From 5c789a8b5766a8c8a425b0e599d05b39a9ccbd03 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 30 2018 04:54:20 +0000 Subject: import ovmf-20180508-3.gitee3198e672e2.el7 --- diff --git a/.gitignore b/.gitignore index 61589a9..84b2a04 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -SOURCES/ovmf-92d07e48907f.tar.xz +SOURCES/openssl-fedora-264133c642cdb6fc916f1d9bba9db4cb4cd4a17c.tar.xz +SOURCES/ovmf-ee3198e672e2.tar.xz diff --git a/.ovmf.metadata b/.ovmf.metadata index 3c14cca..1c31019 100644 --- a/.ovmf.metadata +++ b/.ovmf.metadata @@ -1 +1,2 @@ -b6db0f53d63dd71dae3c6af2696f86ad93b1c450 SOURCES/ovmf-92d07e48907f.tar.xz +885bc596d198c8b1909f2199758e0eec6abe1904 SOURCES/openssl-fedora-264133c642cdb6fc916f1d9bba9db4cb4cd4a17c.tar.xz +ef7bc42e3e6decf2619709fd776481a30f4b4e53 SOURCES/ovmf-ee3198e672e2.tar.xz diff --git a/SOURCES/0002-BuildEnv-override-set-C-noclobber-of-sourcing-env-RH.patch b/SOURCES/0002-BuildEnv-override-set-C-noclobber-of-sourcing-env-RH.patch deleted file mode 100644 index be659b4..0000000 --- a/SOURCES/0002-BuildEnv-override-set-C-noclobber-of-sourcing-env-RH.patch +++ /dev/null @@ -1,45 +0,0 @@ -From e4133f594621fa9e8936348f4d0aa4bbd2976d2f Mon Sep 17 00:00:00 2001 -From: Laszlo Ersek -Date: Sun, 8 Jul 2012 11:55:50 +0200 -Subject: BuildEnv: override "set -C" (noclobber) of sourcing env (RHEL only) - -The BuildEnv utility is sourced (executed by the user's interactive shell) -when the user sets up the build session. Some users like to set -C -(noclobber) for some additional safety in their shells, which trips up -BuildEnv. Update the redirection operator so that it overrides noclobber. - -Notes about the c9e5618 -> b9ffeab rebase: - -- Adapted to new BaseTools feature (= out of tree modules). - -Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: - -- no changes - -Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: - -- no changes - -Signed-off-by: Laszlo Ersek -(cherry picked from commit 7df892b6f1c0dead5b177b3866e127b684cdc001) -(cherry picked from commit 06d17db0523920d95fb18b3629f523dcd63d9499) ---- - BaseTools/BuildEnv | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/BaseTools/BuildEnv b/BaseTools/BuildEnv -index f748811..ff0c511 100755 ---- a/BaseTools/BuildEnv -+++ b/BaseTools/BuildEnv -@@ -90,7 +90,7 @@ StoreCurrentConfiguration() { - # - OUTPUT_FILE=$CONF_PATH/BuildEnv.sh - #echo Storing current configuration into $OUTPUT_FILE -- echo "# Auto-generated by ${BASH_SOURCE[0]}" > $OUTPUT_FILE -+ echo "# Auto-generated by ${BASH_SOURCE[0]}" >| $OUTPUT_FILE - GenerateShellCodeToSetVariable WORKSPACE $OUTPUT_FILE - GenerateShellCodeToSetVariable EDK_TOOLS_PATH $OUTPUT_FILE - GenerateShellCodeToUpdatePath $OUTPUT_FILE --- -1.8.3.1 - diff --git a/SOURCES/0003-advertise-OpenSSL-on-TianoCore-splash-screen-boot-lo.patch b/SOURCES/0003-advertise-OpenSSL-on-TianoCore-splash-screen-boot-lo.patch new file mode 100644 index 0000000..c108842 --- /dev/null +++ b/SOURCES/0003-advertise-OpenSSL-on-TianoCore-splash-screen-boot-lo.patch @@ -0,0 +1,600 @@ +From 0b2d90347cb016cc71c2de62e941a2a4ab0f35a3 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +Date: Wed, 11 Jun 2014 23:33:33 +0200 +Subject: advertise OpenSSL on TianoCore splash screen / boot logo (RHEL only) + +Because we may include the OpenSSL library in our OVMF and AAVMF builds +now, we should advertise it as required by its license. This patch takes +the original TianoCore logo, shifts it up by 20 pixels, and adds the +horizontally centered message + + This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit (http://www.openssl.org/) + +below. + +Logo-OpenSSL.bmp: PC bitmap, Windows 3.x format, 469 x 111 x 24 +Logo.bmp: PC bitmap, Windows 3.x format, 193 x 58 x 8 + +Downstream only because upstream edk2 does not intend to release a +secure-boot-enabled OVMF build. (However the advertising requirement in +the OpenSSL license, +"CryptoPkg/Library/OpensslLib/openssl-1.0.2*/LICENSE", has been discussed +nonetheless, which is why I'm changing the logo.) + +Notes about the 9ece15a -> c9e5618 rebase: +- Logo.bmp is no longer modified in-place; instead a modified copy is + created. That's because AAVMF includes the logo too, but it doesn't + include OpenSSL / Secure Boot, so we need the original copy too. + +Notes about the c9e5618 -> b9ffeab rebase: +- AAVMF gained Secure Boot support, therefore the logo is again modified + in the common location, and no FDF changes are necessary. + +Notes about the d7c0dfa -> 90bb4c5 rebase: + +- squash in the following downstream-only commits (made originally for + ): + + - eef9eb0 restore TianoCore splash logo without OpenSSL advertisment + (RHEL only) + + - 25842f0 OvmfPkg, ArmVirtPkg: show OpenSSL-less logo without Secure + Boot (RH only) + + The reason is that ideas keep changing when and where to include the + Secure Boot feature, so the logo must be controllable directly on the + build command line, from the RPM spec file. See the following + references: + + - https://post-office.corp.redhat.com/mailman/private/virt-devel/2016-March/msg00253.html + - https://post-office.corp.redhat.com/mailman/private/virt-devel/2016-April/msg00118.html + - https://bugzilla.redhat.com/show_bug.cgi?id=1323363 + +- This squashed variant should remain the final version of this patch. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- For more fun, upstream completely changed the way logo bitmaps are + embedded in the firmware binary (see for example commit ab970515d2c6, + "OvmfPkg: Use the new LogoDxe driver", 2016-09-26). Therefore in this + rebase, we reimplement the previous downstream-only commit e775fb20c999, + as described below. + +- Beyond the new bitmap file (which we preserve intact from the last + downstream branch), we introduce: + + - a new IDF (image description file) referencing the new BMP, + + - a new driver INF file, referencing the new BMP and new IDF (same C + source code though), + + - a new UNI (~description) file for the new driver INF file. + +- In the OVMF DSC and FDF files, we select the new driver INF for + inclusion if either SECURE_BOOT_ENABLE or TLS_ENABLE is set, as they + both make use of OpenSSL (although different subsets of it). + +- In the AAVMF DSC and FDF files, we only look at SECURE_BOOT_ENABLE, + because the ArmVirtQemu platform does not support TLS_ENABLE yet. + +- This patch is best displayed with "git show --find-copies-harder". + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- After picking previous downstream-only commit 32192c62e289, carry new + upstream commit e01e9ae28250 ("MdeModulePkg/LogoDxe: Add missing + dependency gEfiHiiImageExProtocolGuid", 2017-03-16) over to + "LogoOpenSSLDxe.inf". + +Notes about the 20171011-92d07e48907f -> 20180508-ee3198e672e2 rebase: + +- Adapted to upstream 25184ec33c36 ("MdeModulePkg/Logo.idf: Remove + incorrect comments.", 2018-02-28) + +Signed-off-by: Laszlo Ersek +(cherry picked from commit 32192c62e289f261f5ce74acee48e5a94561f10b) +(cherry picked from commit 33a710cd613c2ca7d534b8401e2f9f2178af05be) +--- + ArmVirtPkg/ArmVirtQemu.dsc | 4 +++ + ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 4 +++ + ArmVirtPkg/ArmVirtQemuKernel.dsc | 4 +++ + MdeModulePkg/Logo/Logo-OpenSSL.bmp | Bin 0 -> 156342 bytes + MdeModulePkg/Logo/Logo-OpenSSL.idf | 15 +++++++++ + MdeModulePkg/Logo/LogoOpenSSLDxe.inf | 61 +++++++++++++++++++++++++++++++++++ + MdeModulePkg/Logo/LogoOpenSSLDxe.uni | 22 +++++++++++++ + OvmfPkg/OvmfPkgIa32.dsc | 4 +++ + OvmfPkg/OvmfPkgIa32.fdf | 4 +++ + OvmfPkg/OvmfPkgIa32X64.dsc | 4 +++ + OvmfPkg/OvmfPkgIa32X64.fdf | 4 +++ + OvmfPkg/OvmfPkgX64.dsc | 4 +++ + OvmfPkg/OvmfPkgX64.fdf | 4 +++ + 13 files changed, 134 insertions(+) + create mode 100644 MdeModulePkg/Logo/Logo-OpenSSL.bmp + create mode 100644 MdeModulePkg/Logo/Logo-OpenSSL.idf + create mode 100644 MdeModulePkg/Logo/LogoOpenSSLDxe.inf + create mode 100644 MdeModulePkg/Logo/LogoOpenSSLDxe.uni + +diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc +index d74feb7..7331597 100644 +--- a/ArmVirtPkg/ArmVirtQemu.dsc ++++ b/ArmVirtPkg/ArmVirtQemu.dsc +@@ -329,7 +329,11 @@ + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf ++!if $(SECURE_BOOT_ENABLE) == TRUE ++ MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + MdeModulePkg/Logo/LogoDxe.inf ++!endif + MdeModulePkg/Application/UiApp/UiApp.inf { + + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf +diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +index 89f95b2..8941b7f 100644 +--- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc ++++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +@@ -191,7 +191,11 @@ READ_LOCK_STATUS = TRUE + # + # TianoCore logo (splash screen) + # ++!if $(SECURE_BOOT_ENABLE) == TRUE ++ INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + INF MdeModulePkg/Logo/LogoDxe.inf ++!endif + + # + # Ramdisk support +diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc +index 1e823ae..1981aae 100644 +--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc ++++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc +@@ -318,7 +318,11 @@ + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf ++!if $(SECURE_BOOT_ENABLE) == TRUE ++ MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + MdeModulePkg/Logo/LogoDxe.inf ++!endif + MdeModulePkg/Application/UiApp/UiApp.inf { + + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf +diff --git a/MdeModulePkg/Logo/Logo-OpenSSL.bmp b/MdeModulePkg/Logo/Logo-OpenSSL.bmp +new file mode 100644 +index 0000000000000000000000000000000000000000..4af5740232ce484a939a5852604e35711ea88a29 +GIT binary patch +literal 156342 +zcmeI5d(>~$xW~&aw_M64NYZ7LkVerMIgB$pYT%5)88Oa?KguvP +zI4QXdhfYMHh=?MQLQ0BCrP`(4zMRjyzxCbEZ>}}xTJLYa@9y1uKfkf|+RvQxna_OY +zcg^)(&zft#YrS&!|2yzL>&^VO;olbgyJY?K);pa4*I#cF_W4_@5Lmu^`C8SVd%H7l +zd)wQ-|NZYj=s^#f&XKk6aIEP)deoyH_4&_#{_lVP`%O39^p&rC<)truY4^x-xPS12 +zA8_cqMVXTbv=CU+PmfmLR(siwJMQ?$KmPI2kAC#jEw6otV@>bT_rCYN4}IuEk9fo* +z9`Jw%JnwnW`{56N_@4K?r+a)K^O(n6am5v{dey7CMVXTbR1sLyPmgNHR(rvH?sK2t +z{N^`rdefU$rRBBnaIEP)+Is7)?{~lZ`Iv68#THy*os7a;-tv}T|N7VKug`SBI`Auw +z>$~3du0Q?hPm32XzWnmb4?g%{15l_rUji4jU;gr!cieHu#TQ?^!wx%KcinZIMHId8 +zg)jW^kAJ*q(W0AgzWJNq{N|IN{Nz{>pwXu-Zb?o%?X;&ns#NVBjEGTfBy4FKl;%d-}uI8v#o%s?k`p^WRzo0Z5W`_D6$a? +zvU$J(2b_EExet8c17m)1nB4m7UiZ3R{Nfi*BE(uTSy+fksx%IV4gTQ|e{hr?Ww-vE +z=R5~xhBrCvk;!o>!l1&Sj-5fXjcubxvmIcy6SJ0&Z_&>v*L;pTROffdA%`%YZ@cZb +zGtWE|{#~+UiSoP1LngcKx~odp@_mG9&pr2qcDLDP8zy2n62JT1?|jZjwJsve+I;xK +zAAazIAN<_sKKHD%&VqxabIv*Ey!XBD-EhMVIrk1f{P45SKHGJ7*<}|lfG>O5%V_KI +zkAM6}Kl)MV#-$cwyHQ4=NV*F2hx0h2oI=gXkq*en7r*#LxRv|jhdksVSmqi7p`3W) +ziEeb+vSmN}+0U5OqLfQL(CxO{ZYpgwWM>Lj-}=_KUVr`d?|kPwH`!#9``-7y%$@DN +z`|iK}?Qi$mYcFXIDioIOXHAIujbYFz!m^E6AoC4xcmv_gBOm$5sDNA?CUW!x)en5& +z1NWq6{*TsTvak@7jl&TwoN&SkhBV4Et*-cSkBlh=BJ7dh{qA?)Q#kYgpu(Vzd)LOc +z(W5B_Snb5D<LCly@%?cI>&^Fp=BPF>?_bNldT>4z)+u#27YhLpjCu>496=n2` +zq%9Qrwd6<#Fw4C#mkJZQ8rook4H!=ZYf93}YhU|X`v8nwlay>URP*iUKmR$=oUKWC +z#xtIA)m2wX9#kkS7pA(&sNWa{jUsH?hy^C{fbL08dXidnepD`;;WG1r7rY>5##*sr +zEnhmd!x1e*1U}EBY@Jh2J@qF)`H3#H?75jc<&;xgiZG}!QU|p`Y->H5Vt~ai6ep&O +ziu?j?sWp5q^a*LXW3%!1z3+Wi=ps)D$Ti!_YqMY!=;Vzz-e?*niA;_Zd>bsq6mZAOCpR!ye{jO^BwVjDC@{g(AO}9O(dN&p6|Zcf8{rwr>Gm +zcFayIJX>%P5$iSAT%%;8p_*^Ryf$TlM-$gxd##d#3Wa4GsR>cPF$@|-Shf*_BaS%Y +z#V>v_F)6o1Zqy1<*`*SIi=M{JSSwbn7Jr_# +zunqzWPDZ&XvQ9U@R%@gK7-TBov5$RhY(g?)l=U={X(e*v{qKMOJMX+xMU94Pz7=gT +zK$&oWDS9shD0dYK%Z0&iGV0@SZ5T9)uxTR*oS96Nzv30Ih;3ORDn|w6yY9LR^kQbL +z6)V>ArBgc`(K0eOF`Vtnj50aTeC9KGGQs>99pRF|-5VhxgMk|n=?^N5F(Om!2eGa7 +zXo>+=J27kdxL2Spw;Mhe`W)6csCX6^6$<28Bf(=2BeOOO5d}tDyv8E)+)SNE?coo9 +zcnyeX1RW>8{N*n*xx=HXCqD6sMO`e%SeuE?E3dq=(21rbGd`rlvoE(&)GG2xa@ttO +zr6V1nB10!Wy0xh|N-zrvx`?j*?Qefmve6K=YCQscrpy44UjIu+>&u@o@F|&wqYw*9uWNDj@g9zr9B=S}P1vR686+b07cs$M@cQ +zZ)HZA9HQN?fBowS=bd-nQAZucL9U`|p;R#QO1`FiZ(fF4s%Qz?d>Q}#-r%VDGuz30;xx0^0QtBkc5pOzT +zMP`$;+{w6 +zH{5W8a%j}gD#>B0jui_kYBW^q5l}N;zx1Uqap~gzJqA9qIjB&8pjwT6)Nc%fMiIts +zL;~RA-VBcb3QU(O`l6 +zIy(Q$Di$8xzvx9TA}Aw%VZuw#mk2g_!UjJ+^{G$gxsyS(5TPW~N!DpGeTFqynDq~e +zAXJM7`Yc8PcUBaz3W6s~uYBbzZP0>Ek#qa)w{yJVBdQ#G?6LfPl+~gTtB}u)3HMf%xC9#(>mO=IFj^}NHV#Lj +z$@Btox_pQ-IgClIHe-zhH`?@_%%?y7>Aq1LR2XAKO|x%f+vw301FUvp*79+$KwECt +zeC{#^7{VZHYZoc{E-}%mW2voVQLYHuQRNHUA{h)X_hzVlkSY+9jx!LDA1`EGb +zg#`eGHC15}Sv~sHr#__|W)Fy(d7O&p)Q#&m$2fqIefHUh=5WAXA%F>lD`sK7lE(`y +z{J8MK3u%RiPAnaZ%DoLWdPG>wn!IQMnYBB|AAh_u2NjH4VWgHU^m~Va>NbjO!~#{A +zSpxPWk316D`Q5{0$CzeeHqc3g-XmC8h{?gjVK>wY5AiqMbkjm6)bI=vrBw0ib@-RH +z>Vpax9HXOlwXb12*rVAFu-b`P%g4O}G`rpFb1!2Mze6DWl>m3uET-nfk2AvYC~#)Q +z#U5^JZ4wkHy#0}}mC!ZV}nnU^RZ+|=Y +zYqY`)8dJ|u7}r83g1LuKD}xHN?e%Q+dpm0*7JAi`SsW&7f;JaRFUuvrX05PLByDg| +zAllk@-+iSP<-v;UltS$&%oPYmp6Hm>!3=}Bvb><}5SbEG_RcCSXus>u@z*u6a8AYz +z7izBaM8PwE{kCWk0uRUH)jPI0Co(scOxLgqhv<*VAC~SFF?CyEOs~z)>P3# +z!%lISq9!v@kf~Rp)vOg3iexm{mYHq*+~+98SlwjuW6_)6kV?67iuJ#*kP`pX+h-iwYql3 +z-vj~g?13`Eld^&4y-;r^w2{Wh%;l|SjUgq +zSeR08fgx~jjawGs@)w~j^p1arwm`7Cw=h{C-RF%Qyl-TII5XCbb^Mr(g(>wG7y|e1 +zxc%ShrZ`6<0RHgQodrAoh +zSgFbiHWu-)l-PgPQu`y9%`-LB*)t +z0JfJO;vrkhX;mA~d>btkWqVqn>;_z44NA{74Ak~PcLuen4MjgBgk{AzSHT(Yy+ZOeZa@tiM7kUSc0hsS^LlI)1XD +zu-16XJ)ss?51ZxhVqLfPQ4C%L5#O@rx(KctGrRePnv*rlR;al|6OE2EzAq5{Y(Qp|I9?%YE^} +zI*hok1sdfQXioAP9eoWfIwRRSMNyGoOV%t~-$LOM$wo&S-xsi-ZK$PI=rmA`ep0tc +z(oF(eLQ9I+7awKdm9>0KkF$k?%PW5P#p+R}`k1bvHXS&GicEk|{j;C_EWrzcevL-$ +zUK^a+xNTT&bm1PqX8y;4XdIcl2P^Puz~BG=_e@jpx6Zr{$@x)m7i6tg)NnOc8T0KG +zH5A>B=W?T==xX$~`@U03=lt_4MeDKGk_&~#kciGV`a8%E6FwBp_xfZV3#dVMwXaUZ +z2B;E&W>opzX3-i|8gIELz=^Lxh%fXhj5tY^-q)GakaeP;-TXq$$(m&=SdjggY;>gY +zeStAh*K``FM#qZo4}NojNb{Iuj$sypfk>ygGmX}wjO9kx1d;aBfx`z$^%@;M!5Lrf +z+-TJ9wZW;4+lJ*v7h+FwAdY8bDq4Z}&uQj?7ma@66Q6K?6x;4>S +zKTO5P2=S8*6vcPfH{Np3Gm5CmMc8gzP@_&Vq*guth16s=KKiU#cGDILmq<1`()hl> +z7^rJH4OAO`j``+-dZ#@M60IS}YFFFf)W&VY +za-$2er#KLe<3FBAfjbEXm_Akn+3^P3!IK$ly=N;18?Huw#(aAP{le{dE;kyYR_}R) +zK~7|@Gz{JO`}_*6#~(K+ykd}PdUv1FI93}&LI|j0qrZdv;HGB;nx9CoNRT=BEr8-y +zt7}9#n2J+f%pdua4HU&^);zX~Gqy})`@0yYpMHAO+;!Jo?Y0FsCxJJh*WPbbRI%qp +zKFQt>Vbm=t6%*pub_){ +zCA$l<)_b;6)NnQ04>SzuFu1i70ta6~A`DdXC=j +zVqk`4D7>weC&k1#JZWL!jyLuB?XwXz%QkDF +zYqrr5PP5vlI>ta<(`lgE@N@8+3#4^wr`@sI7!sJZ +zwFa<*{1Dw+X))&ZehVNrkKA~Py-jg));`(L`|f%k_;kOEA#2R>F-&>v&SO*N#SDZ6 +zsm0{}`|r=14;04_w9-uBbSZj=1wN7F69NU_jq_;m>nei^@i<1$qui^bsVeoc`^}x+ +zAt9U5S_9ZFKNN>-rH9d?b9*ygx)6j_@o?%-7_>V+olDczYI`!KG(N+W{yf1l#+jPV +zJb^P$W_x?l+g5L8Z}nPcJXou4jWBREe|v>~4Sro^P+?5R3mxu;`Kr^$KK3!bc3Q)B +zp7K{7GJLB2)HbE_`RQDmu2$QVk)=!-$B&ZC6D%X0=~bI2aOTPE +z_%5uv1My(3x-~rK2`X_PQSi){S60inS7?;G_|^RR6>cv1OD?_>7#DK%9=JKrjE8K% +zcXytO^3f +zh{|LlkO+)LU{y}MteXgcz}TUddWk?HP#};Dk_fCK0>y~RWFn9Vj77lb-f>49a@bDW +zvK_w54ib*s{pCdx`+U+ +zL?96;5bzlY?QXxpdau}UJ@!$syxXQ5q73aGyxmqJXzi(}&18)loO{B59Cgxv9?fRK +zGC6E8Cd>;{dpqxp|BbSes6n+?U4Ch?snnTE?z(I7op-|2i*CK8u_gaB`L?96ui-6BS*c0;IaijISoAXhIH_;?CZfvMU{uK+yJwdei7xpya)&%n}p|03g +zVec{f?S)OK87d(k{zVgdCG2(Zi!3fyChT0}-(|~|8H%-D_{5vhUWL{rld#LnSaW +zdl(rV7+DHj1K8kV;$k8`8bucWQk^8VFrw)cWOAsE9fgMChaRR3Q`NWYVa52T-<54&6jk +z&Cv=uR6zkZFhVQH*dZSr$fT4W(VQxhqq!!O$+t`R2|g(6prEYk>W&aoU2^1)_Qi}i57aDByd`it`*14L?zOuC7O`Zb +zMM~LYoFcX8D~-GwJJeDy5l93I1au0qhakki#Jok=YdS`4B>zGjXmW1XHcBB@&gTa6 +zs!05+XpS?VO~e5&U>wSTeIObr16HCJ=3h$T8Xn3K^O7k}fl8n!+7)NPDOiU7AT<=| +zAg0iv6iR|pQJ^_2tB8suu`CO^6X)`P8r~{yrBQUWrxs@M8M7#08Fr>RnN-mpQfr!>mb@vk@wzKEOR +zUl^giiGN`YjEEEA6vzVN5FLCf^F!?L~r8=F3M#awb7i(l9P#3zPvj~*JI}jH6 +zvH&a53YyTC%;Eq!I3V;C|9bv`y0Dc3iAGIIQD!bNZhJgfN!PI&Qb?_NaASq*^_Otm-EAV*Ox +z71_`i=aOjw!h&w#6gGH-O)`5(2Q@emuc)h1sN`V1TtIb}6UZ^3OpwW>AaE8mtNaaDbuBl=~Wik;+1jZuZ^Q{*DihtS9mVXuh#+bL@ +z;@R>q?8C{=X3m9KyurT&nC9FPkxLoM|ZfkdD{z-Jwk38Gqf +zHpah7vXA`BO=$0i5#66E{x$h3ZiRo9qrLf;XpXS1wxOo@H_~pDMZsiV>B`L?96ui-1pi)&}t0pQmuO +zjkyJsVOUMgmwe@7qN10I9 +zJnQFaaaNa1)QE6v^SRD1_?K{4D-+mj;go%g0uR}&)}73yl*wXNFR*9xaw{yTA~}>Q +z^yXO{Nm+}UZVorxR_(zZI&Klm=)3wD;a`iFUw_NQw&>0=^=5RKxw+-`m35JqR3^8{ +zrxeRA9$jrv$M08l~3*$q$_%GvhQ_IVEC`YEO>5ms|O#*GH +zA@<#MSL75e(kPl-$q4fcQ$-RIJm=Eod;Hh(Est8h-d+>i#s@Dy=!E5`oxgl>eR>8$ +zM1krkyE^g?$1Xqq%o*w|ezZlY+Pe6vqHrRKSz1RkS|&+b80r0u9crnU2qXdp0zRW) +z4VIvFX*cGe+#CNEER5O|{0mEpG}#kk+p$8R2n9A4Y0!#FVNzIC)uCM}cn`xyUWQdw +z3l@f;rKYP((H5Gr$(|rLmcp6r6t4$t%^Y9|aV;zhXpXG7(4w#v;g_pi8C^6vkSC$P`*s&}yzMDvEz)yfEm_ +z7UYXRGFxzcmx9L*wbV-l5`h8%pMLP~9LB%3=Wpg;go2x>0+)%o8vF~Zq89m=8Cd=C +zh%$?Ne>j>DUY1daGYOG@d*ffVC6^rkGL@mInS2bQ<2aW&VtOG?S1le_8es(DS&^Xk +zFeC9Su_qJ3Y**b-5;U4*`X`oDb(k?0LCujvDP6ka&x@(cq=c!tmw#h`jB%3jM^Y`y +zNMWHEQJG8x5`nP@_%s{jUojMf0^?{?jOnBWY)-+yFfw#D$iGlCYHW^wp+8SPz>LgA +zxKk3KPLxHL@UNLv{EI2rc`*KUEoNYRognNj+EU-$99$e9+{IXuxV83N3s#LmE}Hr= +zBkX(#u{+O;T5Q5ZDS8!$I`eL$EB>Pi6EtMq{Y3^R){eiiLoM|ZfkdD{z$en+`~y)W +z%9{V}WnN{nM~$enJ^#=f|B6^)w^_x%G{;MG9N{wOK>c$Hz0j310?+`MpPyffka>|0zQid`L~FF3kr@&Y_87uSIrS}iWU{m5(sm_ +zfR~|it^|;>m=rY=;$ZwM{#8isTHt^wHkxpzVUz$GcE%h%7-JSj2s6#sVp|2F;#SzO +z_ebn31?oCbZO6anda6(t)}~_IlT?l}i>Aj8wbV-l5`h8%pTqEPTzaT>uOf~q|a}+cx{*6-y +z&|I9i^&uz(0##TKvO`&G(L4zNOLoIpRVO~J@vqptTM_#z8o4J%4&iUU|F<}$GMNaB +zM!@I%$oLm#G0)ZnY{HE2X?u(F15{Z>{>1_l!5E<AqhNaBmwkID7H=H#8LX<@iYMn@?(6@eye;fR3%8nG=%~X!f%J}H9 +zmWqi$A~1=7&)c~bc<96*r?r1Yi|~}mZnpEk%p}10SYXp?1Oiq4EgX!@GebgS887A^ +zplJoOD0mrz9rH8-I^FqS42oN=Z$b0F3c5wy+~Y%S;x9i>v;Ihd(AE6tx!s~}q+095 +zOig9PT5`Z>N@_#zD%)aez~YZ +z5<7N=$qFe%>YSQ?x$AdKia@Aa{8+&j*FV6U`iXy47lw^b&!j*|>&ruzpwW?n*q^?{ +z-{`THiitoXFo}RqBw{_Njg6ab36h;eKpBSh#I6J<;T_3@y*4{uSQY-oD<}^_giK*r +zE(Z32Kp3w?h?ElWdfvn9e<5ELp{eC-=x`~bme@J2n&9f9Xj--4Xoto`+_4t^U{DA^ +zgdamB9JKZss5qfIuEVafQ{8IFHZ(DOQ1 +zL2xbpxXzOgb_Q=@TibUgI`Lgj(=e> +zMU)Nx~l!_3pH4%7MB!8D7Ym`!#`P^=;NZCbo +zYOx$bt!NLA<3PMHxQa+n1P7P-kAtlc1qjqsh;qTF)Ya?(MW}frTqQq}wQSO~Vq}Qh +z(-f*jPBe}T?|02&p|)mY^jJ&9L?98EM8M}fR1&GSE3cmU2gQ#K{RlEdP#0v4%e#ImMtXlgq`3qxe(=XJ#6JYIXtR@d=>u^LP`e(>mc9&@wKiE +zc&HqAVc`n|ry^h7)I+R9qY#{9VVIYkI8%WpISctWdaR{lB9I77BH$Byb;iFCsAmRr +zzpp*yt4)&zWELCVdj1!(?!C=-j~1rjIaU)fH~SDS;V>JF?Dc?VD+y4lwj$q2yfy#A(Q6|A(gmX6F3%RUOA>-!_~c7> +zMvt{rOau~vNd(NlgYhpEjPjh!KVV9MEl;c1khOQTTV%Qv2e=GKpUn9EA$Mer5cK^a +z0$zgOF7uMf$_Hj(*NETbfXY-NkO+)Mz-Ku8OK1r*D%6!w>``Ws028(CB@lz_AM`0q +zf7)`qfCKTHn1cVw*|W7Di!H#8j2>&Lm&Lm +z3nA`FS~-P8zz9qZs7xgSiNI(Cd=~L6i)U-?&B`ex0!Co;SWCr3AQ6~Ez-LjxzeQ5K +zY~>UZ0V6OupfZ&RBm$!m@L9z4LO1x0ER1aB6cPa=FnX+|Vj_?TOd{a3C{nG6SUEA@ +z$|)oQMqqM4WhxO!1V$s^v#1gOnu4vILLy)UMvt{rOau~vNd$ZrnPj`O5YDl33Wf`WzQnLf`< +zN(2&t(Fph~a{Oz~wUF}&Lm ++// ++// This program and the accompanying materials ++// are licensed and made available under the terms and conditions of the BSD License ++// which accompanies this distribution. The full text of the license may be found at ++// http://opensource.org/licenses/bsd-license.php ++// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++// ++// **/ ++ ++#image IMG_LOGO Logo-OpenSSL.bmp +diff --git a/MdeModulePkg/Logo/LogoOpenSSLDxe.inf b/MdeModulePkg/Logo/LogoOpenSSLDxe.inf +new file mode 100644 +index 0000000..2f79d87 +--- /dev/null ++++ b/MdeModulePkg/Logo/LogoOpenSSLDxe.inf +@@ -0,0 +1,61 @@ ++## @file ++# The default logo bitmap picture shown on setup screen. ++# ++# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
++# ++# This program and the accompanying materials ++# are licensed and made available under the terms and conditions of the BSD License ++# which accompanies this distribution. The full text of the license may be found at ++# http://opensource.org/licenses/bsd-license.php ++# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++# ++# ++## ++ ++[Defines] ++ INF_VERSION = 0x00010005 ++ BASE_NAME = LogoOpenSSLDxe ++ MODULE_UNI_FILE = LogoOpenSSLDxe.uni ++ FILE_GUID = 9CAE7B89-D48D-4D68-BBC4-4C0F1D48CDFF ++ MODULE_TYPE = DXE_DRIVER ++ VERSION_STRING = 1.0 ++ ++ ENTRY_POINT = InitializeLogo ++# ++# This flag specifies whether HII resource section is generated into PE image. ++# ++ UEFI_HII_RESOURCE_SECTION = TRUE ++ ++# ++# The following information is for reference only and not required by the build tools. ++# ++# VALID_ARCHITECTURES = IA32 X64 ++# ++ ++[Sources] ++ Logo-OpenSSL.bmp ++ Logo.c ++ Logo-OpenSSL.idf ++ ++[Packages] ++ MdeModulePkg/MdeModulePkg.dec ++ MdePkg/MdePkg.dec ++ ++[LibraryClasses] ++ UefiBootServicesTableLib ++ UefiDriverEntryPoint ++ DebugLib ++ ++[Protocols] ++ gEfiHiiDatabaseProtocolGuid ## CONSUMES ++ gEfiHiiImageExProtocolGuid ## CONSUMES ++ gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES ++ gEdkiiPlatformLogoProtocolGuid ## PRODUCES ++ ++[Depex] ++ gEfiHiiDatabaseProtocolGuid AND ++ gEfiHiiImageExProtocolGuid ++ ++[UserExtensions.TianoCore."ExtraFiles"] ++ LogoDxeExtra.uni +diff --git a/MdeModulePkg/Logo/LogoOpenSSLDxe.uni b/MdeModulePkg/Logo/LogoOpenSSLDxe.uni +new file mode 100644 +index 0000000..7227ac3 +--- /dev/null ++++ b/MdeModulePkg/Logo/LogoOpenSSLDxe.uni +@@ -0,0 +1,22 @@ ++// /** @file ++// The logo bitmap picture (with OpenSSL advertisment) shown on setup screen. ++// ++// This module provides the logo bitmap picture (with OpenSSL advertisment) ++// shown on setup screen, through EDKII Platform Logo protocol. ++// ++// Copyright (c) 2016, Intel Corporation. All rights reserved.
++// ++// This program and the accompanying materials ++// are licensed and made available under the terms and conditions of the BSD License ++// which accompanies this distribution. The full text of the license may be found at ++// http://opensource.org/licenses/bsd-license.php ++// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, ++// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ++// ++// **/ ++ ++ ++#string STR_MODULE_ABSTRACT #language en-US "Provides the logo bitmap picture (with OpenSSL advertisment) shown on setup screen." ++ ++#string STR_MODULE_DESCRIPTION #language en-US "This module provides the logo bitmap picture (with OpenSSL advertisment) shown on setup screen, through EDKII Platform Logo protocol." ++ +diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc +index 2d6c4c4..a5bb2b0 100644 +--- a/OvmfPkg/OvmfPkgIa32.dsc ++++ b/OvmfPkg/OvmfPkgIa32.dsc +@@ -687,7 +687,11 @@ + NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf + !endif + } ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++ MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + MdeModulePkg/Logo/LogoDxe.inf ++!endif + MdeModulePkg/Application/UiApp/UiApp.inf { + + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf +diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf +index 0427ded..f552bc9 100644 +--- a/OvmfPkg/OvmfPkgIa32.fdf ++++ b/OvmfPkg/OvmfPkgIa32.fdf +@@ -295,7 +295,11 @@ INF ShellPkg/Application/Shell/Shell.inf + INF RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf + !endif + ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + INF MdeModulePkg/Logo/LogoDxe.inf ++!endif + + # + # Network modules +diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc +index 43158c5..be8fee9 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.dsc ++++ b/OvmfPkg/OvmfPkgIa32X64.dsc +@@ -696,7 +696,11 @@ + NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf + !endif + } ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++ MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + MdeModulePkg/Logo/LogoDxe.inf ++!endif + MdeModulePkg/Application/UiApp/UiApp.inf { + + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf +diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf +index 6df47f4..ee77ae1 100644 +--- a/OvmfPkg/OvmfPkgIa32X64.fdf ++++ b/OvmfPkg/OvmfPkgIa32X64.fdf +@@ -296,7 +296,11 @@ INF ShellPkg/Application/Shell/Shell.inf + INF RuleOverride = BINARY USE = X64 EdkShellBinPkg/FullShell/FullShell.inf + !endif + ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + INF MdeModulePkg/Logo/LogoDxe.inf ++!endif + + # + # Network modules +diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc +index d1fdf7c..e224b0e 100644 +--- a/OvmfPkg/OvmfPkgX64.dsc ++++ b/OvmfPkg/OvmfPkgX64.dsc +@@ -694,7 +694,11 @@ + NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf + !endif + } ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++ MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + MdeModulePkg/Logo/LogoDxe.inf ++!endif + MdeModulePkg/Application/UiApp/UiApp.inf { + + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index 2e2a174..505d25d 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -296,7 +296,11 @@ INF ShellPkg/Application/Shell/Shell.inf + INF RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf + !endif + ++!if ($(SECURE_BOOT_ENABLE) == TRUE) || ($(TLS_ENABLE) == TRUE) ++INF MdeModulePkg/Logo/LogoOpenSSLDxe.inf ++!else + INF MdeModulePkg/Logo/LogoDxe.inf ++!endif + + # + # Network modules +-- +1.8.3.1 + diff --git a/SOURCES/0004-OvmfPkg-increase-max-debug-message-length-to-512-RHE.patch b/SOURCES/0004-OvmfPkg-increase-max-debug-message-length-to-512-RHE.patch new file mode 100644 index 0000000..46f35b1 --- /dev/null +++ b/SOURCES/0004-OvmfPkg-increase-max-debug-message-length-to-512-RHE.patch @@ -0,0 +1,48 @@ +From 1df2c822c996ad767f2f45570ab2686458f7604a Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +Date: Thu, 20 Feb 2014 22:54:45 +0100 +Subject: OvmfPkg: increase max debug message length to 512 (RHEL only) + +Upstream prefers short debug messages (sometimes even limited to 80 +characters), but any line length under 512 characters is just unsuitable +for effective debugging. (For example, config strings in HII routing, +logged by the platform driver "OvmfPkg/PlatformDxe" on DEBUG_VERBOSE +level, can be several hundred characters long.) 512 is an empirically good +value. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- no changes + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- no changes + +Notes about the 20171011-92d07e48907f -> 20180508-ee3198e672e2 rebase: + +- no changes + +Signed-off-by: Laszlo Ersek +(cherry picked from commit bfe568d18dba15602604f155982e3b73add63dfb) +(cherry picked from commit 29435a32ec9428720c74c454ce9817662e601fb6) +(cherry picked from commit 58e1d1ebb78bfdaf05f4c6e8abf8d4908dfa038a) +--- + OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c b/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c +index 36cde54..c0c4eae 100644 +--- a/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c ++++ b/OvmfPkg/Library/PlatformDebugLibIoPort/DebugLib.c +@@ -27,7 +27,7 @@ + // + // Define the maximum debug and assert message length that this library supports + // +-#define MAX_DEBUG_MESSAGE_LENGTH 0x100 ++#define MAX_DEBUG_MESSAGE_LENGTH 0x200 + + /** + Prints a debug message to the debug output device if the specified error level is enabled. +-- +1.8.3.1 + diff --git a/SOURCES/0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch b/SOURCES/0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch new file mode 100644 index 0000000..f160b4a --- /dev/null +++ b/SOURCES/0005-OvmfPkg-QemuVideoDxe-enable-debug-messages-in-VbeShi.patch @@ -0,0 +1,554 @@ +From 7046d6040181bb0f76a5ebd680e0dc701c895dba Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +Date: Thu, 12 Jun 2014 00:17:59 +0200 +Subject: OvmfPkg: QemuVideoDxe: enable debug messages in VbeShim (RHEL only) + +The Int10h VBE Shim is capable of emitting short debug messages when the +win2k8r2 UEFI guest uses (emulates) the Video BIOS. In upstream the quiet +version is preferred; for us debug messages are important as a default. + +For this patch, the DEBUG macro is enabled in the assembly file, and then +the header file is regenerated from the assembly, by running +"OvmfPkg/QemuVideoDxe/VbeShim.sh". + +"VbeShim.h" is not auto-generated; it is manually generated. The patch +does not add "VbeShim.h", it just updates both "VbeShim.asm" and (the +manually re-generated) "VbeShim.h" atomically. Doing so helps with local +downstream builds, with bisection, and also keeps redhat/README a bit +simpler. + +Notes about the 20160608b-988715a -> 20170228-c325e41585e3 rebase: + +- no changes + +Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: + +- no changes + +Notes about the 20171011-92d07e48907f -> 20180508-ee3198e672e2 rebase: + +- update commit message as requested in + + +Signed-off-by: Laszlo Ersek +(cherry picked from commit ccda46526bb2e573d9b54f0db75d27e442b4566f) +(cherry picked from commit ed45b26dbeadd63dd8f2edf627290957d8bbb3b2) +(cherry picked from commit 9a8a034ebc082f86fdbb54dc1303a5059508e14c) +--- + OvmfPkg/QemuVideoDxe/VbeShim.asm | 2 +- + OvmfPkg/QemuVideoDxe/VbeShim.h | 481 +++++++++++++++++++++++++-------------- + 2 files changed, 308 insertions(+), 175 deletions(-) + +diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.asm b/OvmfPkg/QemuVideoDxe/VbeShim.asm +index 18fa920..f87ed5c 100644 +--- a/OvmfPkg/QemuVideoDxe/VbeShim.asm ++++ b/OvmfPkg/QemuVideoDxe/VbeShim.asm +@@ -18,7 +18,7 @@ + ;------------------------------------------------------------------------------ + + ; enable this macro for debug messages +-;%define DEBUG ++%define DEBUG + + %macro DebugLog 1 + %ifdef DEBUG +diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.h b/OvmfPkg/QemuVideoDxe/VbeShim.h +index cc9b6e1..325d647 100644 +--- a/OvmfPkg/QemuVideoDxe/VbeShim.h ++++ b/OvmfPkg/QemuVideoDxe/VbeShim.h +@@ -517,185 +517,318 @@ STATIC CONST UINT8 mVbeShim[] = { + /* 000001FE nop */ 0x90, + /* 000001FF nop */ 0x90, + /* 00000200 cmp ax,0x4f00 */ 0x3D, 0x00, 0x4F, +- /* 00000203 jz 0x22d */ 0x74, 0x28, ++ /* 00000203 jz 0x235 */ 0x74, 0x30, + /* 00000205 cmp ax,0x4f01 */ 0x3D, 0x01, 0x4F, +- /* 00000208 jz 0x245 */ 0x74, 0x3B, ++ /* 00000208 jz 0x255 */ 0x74, 0x4B, + /* 0000020A cmp ax,0x4f02 */ 0x3D, 0x02, 0x4F, +- /* 0000020D jz 0x269 */ 0x74, 0x5A, ++ /* 0000020D jz 0x289 */ 0x74, 0x7A, + /* 0000020F cmp ax,0x4f03 */ 0x3D, 0x03, 0x4F, +- /* 00000212 jz word 0x331 */ 0x0F, 0x84, 0x1B, 0x01, ++ /* 00000212 jz word 0x361 */ 0x0F, 0x84, 0x4B, 0x01, + /* 00000216 cmp ax,0x4f10 */ 0x3D, 0x10, 0x4F, +- /* 00000219 jz word 0x336 */ 0x0F, 0x84, 0x19, 0x01, ++ /* 00000219 jz word 0x36e */ 0x0F, 0x84, 0x51, 0x01, + /* 0000021D cmp ax,0x4f15 */ 0x3D, 0x15, 0x4F, +- /* 00000220 jz word 0x338 */ 0x0F, 0x84, 0x14, 0x01, ++ /* 00000220 jz word 0x378 */ 0x0F, 0x84, 0x54, 0x01, + /* 00000224 cmp ah,0x0 */ 0x80, 0xFC, 0x00, +- /* 00000227 jz word 0x33a */ 0x0F, 0x84, 0x0F, 0x01, +- /* 0000022B jmp short 0x22b */ 0xEB, 0xFE, +- /* 0000022D push es */ 0x06, +- /* 0000022E push di */ 0x57, +- /* 0000022F push ds */ 0x1E, +- /* 00000230 push si */ 0x56, +- /* 00000231 push cx */ 0x51, +- /* 00000232 push cs */ 0x0E, +- /* 00000233 pop ds */ 0x1F, +- /* 00000234 mov si,0x0 */ 0xBE, 0x00, 0x00, +- /* 00000237 mov cx,0x100 */ 0xB9, 0x00, 0x01, +- /* 0000023A cld */ 0xFC, +- /* 0000023B rep movsb */ 0xF3, 0xA4, +- /* 0000023D pop cx */ 0x59, +- /* 0000023E pop si */ 0x5E, +- /* 0000023F pop ds */ 0x1F, +- /* 00000240 pop di */ 0x5F, +- /* 00000241 pop es */ 0x07, +- /* 00000242 jmp word 0x34c */ 0xE9, 0x07, 0x01, +- /* 00000245 push es */ 0x06, +- /* 00000246 push di */ 0x57, +- /* 00000247 push ds */ 0x1E, +- /* 00000248 push si */ 0x56, +- /* 00000249 push cx */ 0x51, +- /* 0000024A and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF, +- /* 0000024E cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00, +- /* 00000252 jz 0x256 */ 0x74, 0x02, +- /* 00000254 jmp short 0x22b */ 0xEB, 0xD5, +- /* 00000256 push cs */ 0x0E, +- /* 00000257 pop ds */ 0x1F, +- /* 00000258 mov si,0x100 */ 0xBE, 0x00, 0x01, +- /* 0000025B mov cx,0x100 */ 0xB9, 0x00, 0x01, +- /* 0000025E cld */ 0xFC, +- /* 0000025F rep movsb */ 0xF3, 0xA4, +- /* 00000261 pop cx */ 0x59, +- /* 00000262 pop si */ 0x5E, +- /* 00000263 pop ds */ 0x1F, +- /* 00000264 pop di */ 0x5F, +- /* 00000265 pop es */ 0x07, +- /* 00000266 jmp word 0x34c */ 0xE9, 0xE3, 0x00, +- /* 00000269 push dx */ 0x52, +- /* 0000026A push ax */ 0x50, +- /* 0000026B cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40, +- /* 0000026F jz 0x273 */ 0x74, 0x02, +- /* 00000271 jmp short 0x22b */ 0xEB, 0xB8, +- /* 00000273 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03, +- /* 00000276 mov al,0x20 */ 0xB0, 0x20, +- /* 00000278 out dx,al */ 0xEE, +- /* 00000279 push dx */ 0x52, +- /* 0000027A push ax */ 0x50, +- /* 0000027B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 0000027E mov ax,0x4 */ 0xB8, 0x04, 0x00, +- /* 00000281 out dx,ax */ 0xEF, +- /* 00000282 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 00000285 mov ax,0x0 */ 0xB8, 0x00, 0x00, +- /* 00000288 out dx,ax */ 0xEF, +- /* 00000289 pop ax */ 0x58, +- /* 0000028A pop dx */ 0x5A, +- /* 0000028B push dx */ 0x52, +- /* 0000028C push ax */ 0x50, +- /* 0000028D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 00000290 mov ax,0x5 */ 0xB8, 0x05, 0x00, +- /* 00000293 out dx,ax */ 0xEF, +- /* 00000294 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 00000297 mov ax,0x0 */ 0xB8, 0x00, 0x00, +- /* 0000029A out dx,ax */ 0xEF, +- /* 0000029B pop ax */ 0x58, +- /* 0000029C pop dx */ 0x5A, +- /* 0000029D push dx */ 0x52, +- /* 0000029E push ax */ 0x50, +- /* 0000029F mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002A2 mov ax,0x8 */ 0xB8, 0x08, 0x00, +- /* 000002A5 out dx,ax */ 0xEF, +- /* 000002A6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 000002A9 mov ax,0x0 */ 0xB8, 0x00, 0x00, +- /* 000002AC out dx,ax */ 0xEF, +- /* 000002AD pop ax */ 0x58, +- /* 000002AE pop dx */ 0x5A, +- /* 000002AF push dx */ 0x52, +- /* 000002B0 push ax */ 0x50, +- /* 000002B1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002B4 mov ax,0x9 */ 0xB8, 0x09, 0x00, +- /* 000002B7 out dx,ax */ 0xEF, +- /* 000002B8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 000002BB mov ax,0x0 */ 0xB8, 0x00, 0x00, +- /* 000002BE out dx,ax */ 0xEF, +- /* 000002BF pop ax */ 0x58, +- /* 000002C0 pop dx */ 0x5A, +- /* 000002C1 push dx */ 0x52, +- /* 000002C2 push ax */ 0x50, +- /* 000002C3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002C6 mov ax,0x3 */ 0xB8, 0x03, 0x00, +- /* 000002C9 out dx,ax */ 0xEF, +- /* 000002CA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 000002CD mov ax,0x20 */ 0xB8, 0x20, 0x00, +- /* 000002D0 out dx,ax */ 0xEF, +- /* 000002D1 pop ax */ 0x58, +- /* 000002D2 pop dx */ 0x5A, +- /* 000002D3 push dx */ 0x52, +- /* 000002D4 push ax */ 0x50, +- /* 000002D5 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002D8 mov ax,0x1 */ 0xB8, 0x01, 0x00, +- /* 000002DB out dx,ax */ 0xEF, +- /* 000002DC mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 000002DF mov ax,0x400 */ 0xB8, 0x00, 0x04, +- /* 000002E2 out dx,ax */ 0xEF, +- /* 000002E3 pop ax */ 0x58, +- /* 000002E4 pop dx */ 0x5A, +- /* 000002E5 push dx */ 0x52, +- /* 000002E6 push ax */ 0x50, +- /* 000002E7 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002EA mov ax,0x6 */ 0xB8, 0x06, 0x00, +- /* 000002ED out dx,ax */ 0xEF, +- /* 000002EE mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 000002F1 mov ax,0x400 */ 0xB8, 0x00, 0x04, +- /* 000002F4 out dx,ax */ 0xEF, +- /* 000002F5 pop ax */ 0x58, +- /* 000002F6 pop dx */ 0x5A, +- /* 000002F7 push dx */ 0x52, +- /* 000002F8 push ax */ 0x50, +- /* 000002F9 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 000002FC mov ax,0x2 */ 0xB8, 0x02, 0x00, +- /* 000002FF out dx,ax */ 0xEF, +- /* 00000300 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 00000303 mov ax,0x300 */ 0xB8, 0x00, 0x03, +- /* 00000306 out dx,ax */ 0xEF, +- /* 00000307 pop ax */ 0x58, +- /* 00000308 pop dx */ 0x5A, +- /* 00000309 push dx */ 0x52, +- /* 0000030A push ax */ 0x50, +- /* 0000030B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 0000030E mov ax,0x7 */ 0xB8, 0x07, 0x00, +- /* 00000311 out dx,ax */ 0xEF, +- /* 00000312 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 00000315 mov ax,0x300 */ 0xB8, 0x00, 0x03, +- /* 00000318 out dx,ax */ 0xEF, +- /* 00000319 pop ax */ 0x58, +- /* 0000031A pop dx */ 0x5A, +- /* 0000031B push dx */ 0x52, +- /* 0000031C push ax */ 0x50, +- /* 0000031D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, +- /* 00000320 mov ax,0x4 */ 0xB8, 0x04, 0x00, +- /* 00000323 out dx,ax */ 0xEF, +- /* 00000324 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, +- /* 00000327 mov ax,0x41 */ 0xB8, 0x41, 0x00, +- /* 0000032A out dx,ax */ 0xEF, +- /* 0000032B pop ax */ 0x58, +- /* 0000032C pop dx */ 0x5A, +- /* 0000032D pop ax */ 0x58, +- /* 0000032E pop dx */ 0x5A, +- /* 0000032F jmp short 0x34c */ 0xEB, 0x1B, +- /* 00000331 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40, +- /* 00000334 jmp short 0x34c */ 0xEB, 0x16, +- /* 00000336 jmp short 0x350 */ 0xEB, 0x18, +- /* 00000338 jmp short 0x350 */ 0xEB, 0x16, +- /* 0000033A cmp al,0x3 */ 0x3C, 0x03, +- /* 0000033C jz 0x345 */ 0x74, 0x07, +- /* 0000033E cmp al,0x12 */ 0x3C, 0x12, +- /* 00000340 jz 0x349 */ 0x74, 0x07, +- /* 00000342 jmp word 0x22b */ 0xE9, 0xE6, 0xFE, +- /* 00000345 mov al,0x30 */ 0xB0, 0x30, +- /* 00000347 jmp short 0x34b */ 0xEB, 0x02, +- /* 00000349 mov al,0x20 */ 0xB0, 0x20, +- /* 0000034B iretw */ 0xCF, +- /* 0000034C mov ax,0x4f */ 0xB8, 0x4F, 0x00, +- /* 0000034F iretw */ 0xCF, +- /* 00000350 mov ax,0x14f */ 0xB8, 0x4F, 0x01, +- /* 00000353 iretw */ 0xCF, ++ /* 00000227 jz word 0x382 */ 0x0F, 0x84, 0x57, 0x01, ++ /* 0000022B push si */ 0x56, ++ /* 0000022C mov si,0x3e9 */ 0xBE, 0xE9, 0x03, ++ /* 0000022F call word 0x3c4 */ 0xE8, 0x92, 0x01, ++ /* 00000232 pop si */ 0x5E, ++ /* 00000233 jmp short 0x233 */ 0xEB, 0xFE, ++ /* 00000235 push es */ 0x06, ++ /* 00000236 push di */ 0x57, ++ /* 00000237 push ds */ 0x1E, ++ /* 00000238 push si */ 0x56, ++ /* 00000239 push cx */ 0x51, ++ /* 0000023A push si */ 0x56, ++ /* 0000023B mov si,0x3fb */ 0xBE, 0xFB, 0x03, ++ /* 0000023E call word 0x3c4 */ 0xE8, 0x83, 0x01, ++ /* 00000241 pop si */ 0x5E, ++ /* 00000242 push cs */ 0x0E, ++ /* 00000243 pop ds */ 0x1F, ++ /* 00000244 mov si,0x0 */ 0xBE, 0x00, 0x00, ++ /* 00000247 mov cx,0x100 */ 0xB9, 0x00, 0x01, ++ /* 0000024A cld */ 0xFC, ++ /* 0000024B rep movsb */ 0xF3, 0xA4, ++ /* 0000024D pop cx */ 0x59, ++ /* 0000024E pop si */ 0x5E, ++ /* 0000024F pop ds */ 0x1F, ++ /* 00000250 pop di */ 0x5F, ++ /* 00000251 pop es */ 0x07, ++ /* 00000252 jmp word 0x3ac */ 0xE9, 0x57, 0x01, ++ /* 00000255 push es */ 0x06, ++ /* 00000256 push di */ 0x57, ++ /* 00000257 push ds */ 0x1E, ++ /* 00000258 push si */ 0x56, ++ /* 00000259 push cx */ 0x51, ++ /* 0000025A push si */ 0x56, ++ /* 0000025B mov si,0x404 */ 0xBE, 0x04, 0x04, ++ /* 0000025E call word 0x3c4 */ 0xE8, 0x63, 0x01, ++ /* 00000261 pop si */ 0x5E, ++ /* 00000262 and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF, ++ /* 00000266 cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00, ++ /* 0000026A jz 0x276 */ 0x74, 0x0A, ++ /* 0000026C push si */ 0x56, ++ /* 0000026D mov si,0x432 */ 0xBE, 0x32, 0x04, ++ /* 00000270 call word 0x3c4 */ 0xE8, 0x51, 0x01, ++ /* 00000273 pop si */ 0x5E, ++ /* 00000274 jmp short 0x233 */ 0xEB, 0xBD, ++ /* 00000276 push cs */ 0x0E, ++ /* 00000277 pop ds */ 0x1F, ++ /* 00000278 mov si,0x100 */ 0xBE, 0x00, 0x01, ++ /* 0000027B mov cx,0x100 */ 0xB9, 0x00, 0x01, ++ /* 0000027E cld */ 0xFC, ++ /* 0000027F rep movsb */ 0xF3, 0xA4, ++ /* 00000281 pop cx */ 0x59, ++ /* 00000282 pop si */ 0x5E, ++ /* 00000283 pop ds */ 0x1F, ++ /* 00000284 pop di */ 0x5F, ++ /* 00000285 pop es */ 0x07, ++ /* 00000286 jmp word 0x3ac */ 0xE9, 0x23, 0x01, ++ /* 00000289 push dx */ 0x52, ++ /* 0000028A push ax */ 0x50, ++ /* 0000028B push si */ 0x56, ++ /* 0000028C mov si,0x41a */ 0xBE, 0x1A, 0x04, ++ /* 0000028F call word 0x3c4 */ 0xE8, 0x32, 0x01, ++ /* 00000292 pop si */ 0x5E, ++ /* 00000293 cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40, ++ /* 00000297 jz 0x2a3 */ 0x74, 0x0A, ++ /* 00000299 push si */ 0x56, ++ /* 0000029A mov si,0x432 */ 0xBE, 0x32, 0x04, ++ /* 0000029D call word 0x3c4 */ 0xE8, 0x24, 0x01, ++ /* 000002A0 pop si */ 0x5E, ++ /* 000002A1 jmp short 0x233 */ 0xEB, 0x90, ++ /* 000002A3 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03, ++ /* 000002A6 mov al,0x20 */ 0xB0, 0x20, ++ /* 000002A8 out dx,al */ 0xEE, ++ /* 000002A9 push dx */ 0x52, ++ /* 000002AA push ax */ 0x50, ++ /* 000002AB mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 000002AE mov ax,0x4 */ 0xB8, 0x04, 0x00, ++ /* 000002B1 out dx,ax */ 0xEF, ++ /* 000002B2 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 000002B5 mov ax,0x0 */ 0xB8, 0x00, 0x00, ++ /* 000002B8 out dx,ax */ 0xEF, ++ /* 000002B9 pop ax */ 0x58, ++ /* 000002BA pop dx */ 0x5A, ++ /* 000002BB push dx */ 0x52, ++ /* 000002BC push ax */ 0x50, ++ /* 000002BD mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 000002C0 mov ax,0x5 */ 0xB8, 0x05, 0x00, ++ /* 000002C3 out dx,ax */ 0xEF, ++ /* 000002C4 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 000002C7 mov ax,0x0 */ 0xB8, 0x00, 0x00, ++ /* 000002CA out dx,ax */ 0xEF, ++ /* 000002CB pop ax */ 0x58, ++ /* 000002CC pop dx */ 0x5A, ++ /* 000002CD push dx */ 0x52, ++ /* 000002CE push ax */ 0x50, ++ /* 000002CF mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 000002D2 mov ax,0x8 */ 0xB8, 0x08, 0x00, ++ /* 000002D5 out dx,ax */ 0xEF, ++ /* 000002D6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 000002D9 mov ax,0x0 */ 0xB8, 0x00, 0x00, ++ /* 000002DC out dx,ax */ 0xEF, ++ /* 000002DD pop ax */ 0x58, ++ /* 000002DE pop dx */ 0x5A, ++ /* 000002DF push dx */ 0x52, ++ /* 000002E0 push ax */ 0x50, ++ /* 000002E1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 000002E4 mov ax,0x9 */ 0xB8, 0x09, 0x00, ++ /* 000002E7 out dx,ax */ 0xEF, ++ /* 000002E8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 000002EB mov ax,0x0 */ 0xB8, 0x00, 0x00, ++ /* 000002EE out dx,ax */ 0xEF, ++ /* 000002EF pop ax */ 0x58, ++ /* 000002F0 pop dx */ 0x5A, ++ /* 000002F1 push dx */ 0x52, ++ /* 000002F2 push ax */ 0x50, ++ /* 000002F3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 000002F6 mov ax,0x3 */ 0xB8, 0x03, 0x00, ++ /* 000002F9 out dx,ax */ 0xEF, ++ /* 000002FA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 000002FD mov ax,0x20 */ 0xB8, 0x20, 0x00, ++ /* 00000300 out dx,ax */ 0xEF, ++ /* 00000301 pop ax */ 0x58, ++ /* 00000302 pop dx */ 0x5A, ++ /* 00000303 push dx */ 0x52, ++ /* 00000304 push ax */ 0x50, ++ /* 00000305 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 00000308 mov ax,0x1 */ 0xB8, 0x01, 0x00, ++ /* 0000030B out dx,ax */ 0xEF, ++ /* 0000030C mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 0000030F mov ax,0x400 */ 0xB8, 0x00, 0x04, ++ /* 00000312 out dx,ax */ 0xEF, ++ /* 00000313 pop ax */ 0x58, ++ /* 00000314 pop dx */ 0x5A, ++ /* 00000315 push dx */ 0x52, ++ /* 00000316 push ax */ 0x50, ++ /* 00000317 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 0000031A mov ax,0x6 */ 0xB8, 0x06, 0x00, ++ /* 0000031D out dx,ax */ 0xEF, ++ /* 0000031E mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 00000321 mov ax,0x400 */ 0xB8, 0x00, 0x04, ++ /* 00000324 out dx,ax */ 0xEF, ++ /* 00000325 pop ax */ 0x58, ++ /* 00000326 pop dx */ 0x5A, ++ /* 00000327 push dx */ 0x52, ++ /* 00000328 push ax */ 0x50, ++ /* 00000329 mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 0000032C mov ax,0x2 */ 0xB8, 0x02, 0x00, ++ /* 0000032F out dx,ax */ 0xEF, ++ /* 00000330 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 00000333 mov ax,0x300 */ 0xB8, 0x00, 0x03, ++ /* 00000336 out dx,ax */ 0xEF, ++ /* 00000337 pop ax */ 0x58, ++ /* 00000338 pop dx */ 0x5A, ++ /* 00000339 push dx */ 0x52, ++ /* 0000033A push ax */ 0x50, ++ /* 0000033B mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 0000033E mov ax,0x7 */ 0xB8, 0x07, 0x00, ++ /* 00000341 out dx,ax */ 0xEF, ++ /* 00000342 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 00000345 mov ax,0x300 */ 0xB8, 0x00, 0x03, ++ /* 00000348 out dx,ax */ 0xEF, ++ /* 00000349 pop ax */ 0x58, ++ /* 0000034A pop dx */ 0x5A, ++ /* 0000034B push dx */ 0x52, ++ /* 0000034C push ax */ 0x50, ++ /* 0000034D mov dx,0x1ce */ 0xBA, 0xCE, 0x01, ++ /* 00000350 mov ax,0x4 */ 0xB8, 0x04, 0x00, ++ /* 00000353 out dx,ax */ 0xEF, ++ /* 00000354 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01, ++ /* 00000357 mov ax,0x41 */ 0xB8, 0x41, 0x00, ++ /* 0000035A out dx,ax */ 0xEF, ++ /* 0000035B pop ax */ 0x58, ++ /* 0000035C pop dx */ 0x5A, ++ /* 0000035D pop ax */ 0x58, ++ /* 0000035E pop dx */ 0x5A, ++ /* 0000035F jmp short 0x3ac */ 0xEB, 0x4B, ++ /* 00000361 push si */ 0x56, ++ /* 00000362 mov si,0x411 */ 0xBE, 0x11, 0x04, ++ /* 00000365 call word 0x3c4 */ 0xE8, 0x5C, 0x00, ++ /* 00000368 pop si */ 0x5E, ++ /* 00000369 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40, ++ /* 0000036C jmp short 0x3ac */ 0xEB, 0x3E, ++ /* 0000036E push si */ 0x56, ++ /* 0000036F mov si,0x43f */ 0xBE, 0x3F, 0x04, ++ /* 00000372 call word 0x3c4 */ 0xE8, 0x4F, 0x00, ++ /* 00000375 pop si */ 0x5E, ++ /* 00000376 jmp short 0x3b8 */ 0xEB, 0x40, ++ /* 00000378 push si */ 0x56, ++ /* 00000379 mov si,0x452 */ 0xBE, 0x52, 0x04, ++ /* 0000037C call word 0x3c4 */ 0xE8, 0x45, 0x00, ++ /* 0000037F pop si */ 0x5E, ++ /* 00000380 jmp short 0x3b8 */ 0xEB, 0x36, ++ /* 00000382 push si */ 0x56, ++ /* 00000383 mov si,0x423 */ 0xBE, 0x23, 0x04, ++ /* 00000386 call word 0x3c4 */ 0xE8, 0x3B, 0x00, ++ /* 00000389 pop si */ 0x5E, ++ /* 0000038A cmp al,0x3 */ 0x3C, 0x03, ++ /* 0000038C jz 0x39d */ 0x74, 0x0F, ++ /* 0000038E cmp al,0x12 */ 0x3C, 0x12, ++ /* 00000390 jz 0x3a1 */ 0x74, 0x0F, ++ /* 00000392 push si */ 0x56, ++ /* 00000393 mov si,0x432 */ 0xBE, 0x32, 0x04, ++ /* 00000396 call word 0x3c4 */ 0xE8, 0x2B, 0x00, ++ /* 00000399 pop si */ 0x5E, ++ /* 0000039A jmp word 0x233 */ 0xE9, 0x96, 0xFE, ++ /* 0000039D mov al,0x30 */ 0xB0, 0x30, ++ /* 0000039F jmp short 0x3a3 */ 0xEB, 0x02, ++ /* 000003A1 mov al,0x20 */ 0xB0, 0x20, ++ /* 000003A3 push si */ 0x56, ++ /* 000003A4 mov si,0x3d6 */ 0xBE, 0xD6, 0x03, ++ /* 000003A7 call word 0x3c4 */ 0xE8, 0x1A, 0x00, ++ /* 000003AA pop si */ 0x5E, ++ /* 000003AB iretw */ 0xCF, ++ /* 000003AC push si */ 0x56, ++ /* 000003AD mov si,0x3d6 */ 0xBE, 0xD6, 0x03, ++ /* 000003B0 call word 0x3c4 */ 0xE8, 0x11, 0x00, ++ /* 000003B3 pop si */ 0x5E, ++ /* 000003B4 mov ax,0x4f */ 0xB8, 0x4F, 0x00, ++ /* 000003B7 iretw */ 0xCF, ++ /* 000003B8 push si */ 0x56, ++ /* 000003B9 mov si,0x3dc */ 0xBE, 0xDC, 0x03, ++ /* 000003BC call word 0x3c4 */ 0xE8, 0x05, 0x00, ++ /* 000003BF pop si */ 0x5E, ++ /* 000003C0 mov ax,0x14f */ 0xB8, 0x4F, 0x01, ++ /* 000003C3 iretw */ 0xCF, ++ /* 000003C4 pushaw */ 0x60, ++ /* 000003C5 push ds */ 0x1E, ++ /* 000003C6 push cs */ 0x0E, ++ /* 000003C7 pop ds */ 0x1F, ++ /* 000003C8 mov dx,0x402 */ 0xBA, 0x02, 0x04, ++ /* 000003CB lodsb */ 0xAC, ++ /* 000003CC cmp al,0x0 */ 0x3C, 0x00, ++ /* 000003CE jz 0x3d3 */ 0x74, 0x03, ++ /* 000003D0 out dx,al */ 0xEE, ++ /* 000003D1 jmp short 0x3cb */ 0xEB, 0xF8, ++ /* 000003D3 pop ds */ 0x1F, ++ /* 000003D4 popaw */ 0x61, ++ /* 000003D5 ret */ 0xC3, ++ /* 000003D6 inc bp */ 0x45, ++ /* 000003D7 js 0x442 */ 0x78, 0x69, ++ /* 000003D9 jz 0x3e5 */ 0x74, 0x0A, ++ /* 000003DB add [di+0x6e],dl */ 0x00, 0x55, 0x6E, ++ /* 000003DE jnc 0x455 */ 0x73, 0x75, ++ /* 000003E0 jo 0x452 */ 0x70, 0x70, ++ /* 000003E2 outsw */ 0x6F, ++ /* 000003E3 jc 0x459 */ 0x72, 0x74, ++ /* 000003E5 or al,[fs:bx+si] */ 0x65, 0x64, 0x0A, 0x00, ++ /* 000003E9 push bp */ 0x55, ++ /* 000003EA outsb */ 0x6E, ++ /* 000003EB imul bp,[bp+0x6f],byte +0x77 */ 0x6B, 0x6E, 0x6F, 0x77, ++ /* 000003EF outsb */ 0x6E, ++ /* 000003F0 and [bp+0x75],al */ 0x20, 0x46, 0x75, ++ /* 000003F3 outsb */ 0x6E, ++ /* 000003F4 arpl [si+0x69],si */ 0x63, 0x74, 0x69, ++ /* 000003F7 outsw */ 0x6F, ++ /* 000003F8 outsb */ 0x6E, ++ /* 000003F9 or al,[bx+si] */ 0x0A, 0x00, ++ /* 000003FB inc di */ 0x47, ++ /* 000003FC gs jz 0x448 */ 0x65, 0x74, 0x49, ++ /* 000003FF outsb */ 0x6E, ++ /* 00000400 outsd */ 0x66, 0x6F, ++ /* 00000402 or al,[bx+si] */ 0x0A, 0x00, ++ /* 00000404 inc di */ 0x47, ++ /* 00000405 gs jz 0x455 */ 0x65, 0x74, 0x4D, ++ /* 00000408 outsw */ 0x6F, ++ /* 00000409 gs dec cx */ 0x64, 0x65, 0x49, ++ /* 0000040C outsb */ 0x6E, ++ /* 0000040D outsd */ 0x66, 0x6F, ++ /* 0000040F or al,[bx+si] */ 0x0A, 0x00, ++ /* 00000411 inc di */ 0x47, ++ /* 00000412 gs jz 0x462 */ 0x65, 0x74, 0x4D, ++ /* 00000415 outsw */ 0x6F, ++ /* 00000416 or al,[gs:bx+si] */ 0x64, 0x65, 0x0A, 0x00, ++ /* 0000041A push bx */ 0x53, ++ /* 0000041B gs jz 0x46b */ 0x65, 0x74, 0x4D, ++ /* 0000041E outsw */ 0x6F, ++ /* 0000041F or al,[gs:bx+si] */ 0x64, 0x65, 0x0A, 0x00, ++ /* 00000423 push bx */ 0x53, ++ /* 00000424 gs jz 0x474 */ 0x65, 0x74, 0x4D, ++ /* 00000427 outsw */ 0x6F, ++ /* 00000428 gs dec sp */ 0x64, 0x65, 0x4C, ++ /* 0000042B gs a32 popaw */ 0x65, 0x67, 0x61, ++ /* 0000042E arpl [bx+di+0xa],di */ 0x63, 0x79, 0x0A, ++ /* 00000431 add [di+0x6e],dl */ 0x00, 0x55, 0x6E, ++ /* 00000434 imul bp,[bx+0x77],byte +0x6e */ 0x6B, 0x6F, 0x77, 0x6E, ++ /* 00000438 and [di+0x6f],cl */ 0x20, 0x4D, 0x6F, ++ /* 0000043B or al,[gs:bx+si] */ 0x64, 0x65, 0x0A, 0x00, ++ /* 0000043F inc di */ 0x47, ++ /* 00000440 gs jz 0x493 */ 0x65, 0x74, 0x50, ++ /* 00000443 insw */ 0x6D, ++ /* 00000444 inc bx */ 0x43, ++ /* 00000445 popaw */ 0x61, ++ /* 00000446 jo 0x4a9 */ 0x70, 0x61, ++ /* 00000448 bound bp,[bx+di+0x6c] */ 0x62, 0x69, 0x6C, ++ /* 0000044B imul si,[si+0x69],word 0x7365 */ 0x69, 0x74, 0x69, 0x65, 0x73, ++ /* 00000450 or al,[bx+si] */ 0x0A, 0x00, ++ /* 00000452 push dx */ 0x52, ++ /* 00000453 gs popaw */ 0x65, 0x61, ++ /* 00000455 fs inc bp */ 0x64, 0x45, ++ /* 00000457 fs */ 0x64, ++ /* 00000458 db 0x69 */ 0x69, ++ /* 00000459 or al,[fs:bx+si] */ 0x64, 0x0A, 0x00, + }; + #endif +-- +1.8.3.1 + diff --git a/SOURCES/0005-setup-the-tree-for-the-secure-boot-feature-RHEL-only.patch b/SOURCES/0005-setup-the-tree-for-the-secure-boot-feature-RHEL-only.patch deleted file mode 100644 index ee3bdbd..0000000 --- a/SOURCES/0005-setup-the-tree-for-the-secure-boot-feature-RHEL-only.patch +++ /dev/null @@ -1,703775 +0,0 @@ -From ba83defbb1e975ac4ff61e5b58c7d860bc2de614 Mon Sep 17 00:00:00 2001 -From: Laszlo Ersek -Date: Mon, 12 Sep 2016 20:14:35 +0200 -Subject: setup the tree for the secure boot feature (RHEL only) - -The file "CryptoPkg/Library/OpensslLib/Patch-HOWTO.txt" explains how to -download, embed and patch openssl-1.0.2* in edk2. Performing this step is -necessary for the secure boot feature. - -While it can be easily automated in (S)RPM build scripts, for the exploded -git repo it's best to include openssl in advance -- this way setting up an -interactive build session remains fast and lightweight. The patch follows -the instructions of "CryptoPkg/Library/OpensslLib/Patch-HOWTO.txt" and -captures the result in git. - -*** Notes wrt. the a618eaa -> 3facc08 rebase: - -- upstream updated from openssl-0.9.8w to openssl-0.9.8za in commit - a6908c9, take it into account here. - -*** Notes wrt. the 3facc08 -> 9ece15a rebase: - -- upstream updated from openssl-0.9.8za to openssl-0.9.8zb in commit - f61d69c, take it into account here. - -*** Notes wrt. the 9ece15a -> c9e5618 rebase: - -- upstream updated from openssl-0.9.8zb to openssl-0.9.8zf. - -*** Notes wrt. the c9e5618 -> b9ffeab rebase: - -- upstream updated from openssl-0.9.8zf to openssl-1.0.2d. - -*** Notes wrt. the b9ffeab -> d7c0dfa rebase: - -- upstream updated from openssl-1.0.2d to openssl-1.0.2e. - -*** Notes wrt. the d7c0dfa -> 90bb4c5 rebase: - -- upstream updated from openssl-1.0.2e to openssl-1.0.2g. - -*** Notes wrt. the downstream-only "rhel7master-20160608-988715a" --> - "rhel7master-20160608b-988715a" rebase (note the character "b" after - "20160608"), in reference to - : - -- This rebase does not affect the fork-off point from the upstream git - history; it remains 988715a. - -- This patch replaces the identically titled downstream-only commit - dde83a75b566. The reason is that we can't distribute pristine upstream - OpenSSL tarballs, given that some files in those tarballs are - patent-encumbered. Instead, we do the following, all in this same one - patch (so that OpenSSL embedding remains one atomic patch): - - * Step 1 of "CryptoPkg/Library/OpensslLib/Patch-HOWTO.txt" (i.e., the - downloading of the OpenSSL tarball) is replaced by the following - steps, in a separate directory. The goal is to embed / flatten - Fedora's pre-sanitized OpenSSL tarball from the "openssl" dist-git - tree rather than the upstream tarball: - - fedpkg clone -a openssl - - cd openssl - - fedpkg switch-branch master - - gitk -- sources - - Locate the oldest (chronologically first) dist-git commit that imports - the "hobbled" OpenSSL tarball matching edk2's OpenSSL version - requirement (1.0.2g). In this case, it is dist-git commit - - e7a0ff581f42 minor upstream release 1.0.2g fixing security issues - - Download and verify the matching hobbled 1.0.2g tarball: - - git checkout e7a0ff581f42 - ( - set -e - while read HASH FN; do - wget \ - http://pkgs.fedoraproject.org/repo/pkgs/openssl/$FN/$HASH/$FN - done 20170228-c325e41585e3 rebase: - -- Upstream has moved from 1.0.2g to 1.0.2k (see 14e3b94964ae, - "CryptoPkg/OpensslLib: Upgrade OpenSSL version to 1.0.2k", 2017-02-27, - and other similar commits in the 988715a..c325e41585e3 range), hence - this patch replaces the following downstream-only commits / modified - backports: - - - a1066aaf3ff4 setup the tree for the secure boot feature (RHEL only) - (which flattened 1.0.2g) - - - 180eb313bb44 CryptoPkg/OpensslLib: Upgrade OpenSSL version to 1.0.2h - (which flattened 1.0.2h) - -- The hobbling procedure is the same as above, under the last rebase to - 20160608b-988715a, with the following modifications: - - - Fedora's master branch no longer uses the 1.0.2* stream of OpenSSL (it - has switched to 1.1.0*), thus the hobbled 1.0.2k tarball is taken from - the following commit on the "f25" branch: - - c914702332cf Upload the new version of sources. - - - In addition, the tarball download / verification can either be done - with "fedkpkg sources", or else with wget + "sha512sum -c sources", - because Fedora has switched to SHA512 checksums. - -*** Notes about the 20170228-c325e41585e3 -> 20171011-92d07e48907f rebase: - -- In commit range 2ed235fc296b..113581e6f32d, upstream edk2 received - significant changes for OpenSSL: - - - the currently supported OpenSSL version is 1.1.0e; - - - edk2-side patching of OpenSSL no longer occurs, all edk2-related - patches have been merged into OpenSSL; - - - the new instructions are described in - "CryptoPkg/Library/OpensslLib/OpenSSL-HOWTO.txt" - -- For importing the hobbled OpenSSL tarball from Fedora, the following - steps are necessary. Note that both the "sources" file format and the - pkgs.fedoraproject.org directory structure have changed, accommodating - SHA512 checksums. - - # in a separate directory - fedpkg clone -a openssl - cd openssl - fedpkg switch-branch master - gitk -- sources - - # the commit that added the 1.1.0e hobbled tarball is c676ac32d544, - # subject "update to upstream version 1.1.0e" - git checkout c676ac32d544 - - # fetch the hobbled tarball and verify the checksum - ( - set -e - while read HASH_TYPE FN EQ HASH; do - # remove leading and trailing parens - FN="${FN#(*}" - FN="${FN%*)}" - wget \ - http://pkgs.fedoraproject.org/repo/pkgs/openssl/$FN/sha512/$HASH/$FN - done ---- - .../Library/OpensslLib/openssl/.gitattributes | 3 + - CryptoPkg/Library/OpensslLib/openssl/.gitignore | 178 + - .../OpensslLib/openssl/.travis-create-release.sh | 11 + - CryptoPkg/Library/OpensslLib/openssl/.travis.yml | 152 + - .../Library/OpensslLib/openssl/ACKNOWLEDGEMENTS | 2 + - CryptoPkg/Library/OpensslLib/openssl/AUTHORS | 21 + - CryptoPkg/Library/OpensslLib/openssl/CHANGES | 12454 +++++++++++++++++++ - CryptoPkg/Library/OpensslLib/openssl/CONTRIBUTING | 54 + - .../openssl/Configurations/00-base-templates.conf | 293 + - .../OpensslLib/openssl/Configurations/10-main.conf | 1894 +++ - .../openssl/Configurations/50-djgpp.conf | 15 + - .../openssl/Configurations/50-haiku.conf | 29 + - .../OpensslLib/openssl/Configurations/50-masm.conf | 17 + - .../OpensslLib/openssl/Configurations/90-team.conf | 112 + - .../openssl/Configurations/INTERNALS.Configure | 136 + - .../OpensslLib/openssl/Configurations/README | 655 + - .../openssl/Configurations/README.design | 641 + - .../OpensslLib/openssl/Configurations/common.tmpl | 231 + - .../openssl/Configurations/descrip.mms.tmpl | 767 ++ - .../openssl/Configurations/unix-Makefile.tmpl | 1124 ++ - .../openssl/Configurations/windows-makefile.tmpl | 601 + - CryptoPkg/Library/OpensslLib/openssl/Configure | 2766 ++++ - CryptoPkg/Library/OpensslLib/openssl/FAQ | 2 + - CryptoPkg/Library/OpensslLib/openssl/INSTALL | 951 ++ - CryptoPkg/Library/OpensslLib/openssl/LICENSE | 125 + - .../Library/OpensslLib/openssl/Makefile.shared | 622 + - CryptoPkg/Library/OpensslLib/openssl/NEWS | 852 ++ - CryptoPkg/Library/OpensslLib/openssl/NOTES.DJGPP | 48 + - CryptoPkg/Library/OpensslLib/openssl/NOTES.PERL | 119 + - CryptoPkg/Library/OpensslLib/openssl/NOTES.VMS | 81 + - CryptoPkg/Library/OpensslLib/openssl/NOTES.WIN | 138 + - CryptoPkg/Library/OpensslLib/openssl/README | 94 + - CryptoPkg/Library/OpensslLib/openssl/README.ECC | 61 + - CryptoPkg/Library/OpensslLib/openssl/README.ENGINE | 288 + - CryptoPkg/Library/OpensslLib/openssl/README.FIPS | 1 + - .../Library/OpensslLib/openssl/VMS/VMSify-conf.pl | 41 + - .../Library/OpensslLib/openssl/VMS/engine.opt | 2 + - .../OpensslLib/openssl/VMS/openssl_ivp.com.in | 50 + - .../OpensslLib/openssl/VMS/openssl_shutdown.com.in | 56 + - .../OpensslLib/openssl/VMS/openssl_startup.com.in | 123 + - .../OpensslLib/openssl/VMS/openssl_utils.com.in | 14 + - .../OpensslLib/openssl/VMS/test-includes.com | 28 + - .../OpensslLib/openssl/VMS/translatesyms.pl | 62 + - CryptoPkg/Library/OpensslLib/openssl/apps/CA.pl.in | 196 + - .../Library/OpensslLib/openssl/apps/app_rand.c | 115 + - CryptoPkg/Library/OpensslLib/openssl/apps/apps.c | 2653 ++++ - CryptoPkg/Library/OpensslLib/openssl/apps/apps.h | 569 + - .../Library/OpensslLib/openssl/apps/asn1pars.c | 330 + - .../Library/OpensslLib/openssl/apps/build.info | 22 + - .../Library/OpensslLib/openssl/apps/ca-cert.srl | 1 + - .../Library/OpensslLib/openssl/apps/ca-key.pem | 16 + - .../Library/OpensslLib/openssl/apps/ca-req.pem | 11 + - CryptoPkg/Library/OpensslLib/openssl/apps/ca.c | 2565 ++++ - CryptoPkg/Library/OpensslLib/openssl/apps/cert.pem | 11 + - .../Library/OpensslLib/openssl/apps/ciphers.c | 242 + - .../Library/OpensslLib/openssl/apps/client.pem | 52 + - CryptoPkg/Library/OpensslLib/openssl/apps/cms.c | 1294 ++ - CryptoPkg/Library/OpensslLib/openssl/apps/crl.c | 347 + - CryptoPkg/Library/OpensslLib/openssl/apps/crl2p7.c | 216 + - .../OpensslLib/openssl/apps/ct_log_list.cnf | 34 + - .../OpensslLib/openssl/apps/demoCA/cacert.pem | 14 + - .../OpensslLib/openssl/apps/demoCA/index.txt | 39 + - .../openssl/apps/demoCA/private/cakey.pem | 24 + - .../Library/OpensslLib/openssl/apps/demoCA/serial | 1 + - .../openssl/apps/demoSRP/srp_verifier.txt | 6 + - .../openssl/apps/demoSRP/srp_verifier.txt.attr | 1 + - CryptoPkg/Library/OpensslLib/openssl/apps/dgst.c | 480 + - .../Library/OpensslLib/openssl/apps/dh1024.pem | 10 + - .../Library/OpensslLib/openssl/apps/dh2048.pem | 14 + - .../Library/OpensslLib/openssl/apps/dh4096.pem | 19 + - .../Library/OpensslLib/openssl/apps/dhparam.c | 380 + - .../Library/OpensslLib/openssl/apps/dsa-ca.pem | 47 + - .../Library/OpensslLib/openssl/apps/dsa-pca.pem | 47 + - CryptoPkg/Library/OpensslLib/openssl/apps/dsa.c | 262 + - .../Library/OpensslLib/openssl/apps/dsa1024.pem | 9 + - .../Library/OpensslLib/openssl/apps/dsa512.pem | 6 + - CryptoPkg/Library/OpensslLib/openssl/apps/dsap.pem | 6 + - .../Library/OpensslLib/openssl/apps/dsaparam.c | 313 + - CryptoPkg/Library/OpensslLib/openssl/apps/ec.c | 281 + - .../Library/OpensslLib/openssl/apps/ecparam.c | 465 + - CryptoPkg/Library/OpensslLib/openssl/apps/enc.c | 604 + - CryptoPkg/Library/OpensslLib/openssl/apps/engine.c | 445 + - CryptoPkg/Library/OpensslLib/openssl/apps/errstr.c | 67 + - CryptoPkg/Library/OpensslLib/openssl/apps/gendsa.c | 147 + - .../Library/OpensslLib/openssl/apps/genpkey.c | 314 + - CryptoPkg/Library/OpensslLib/openssl/apps/genrsa.c | 192 + - CryptoPkg/Library/OpensslLib/openssl/apps/nseq.c | 113 + - CryptoPkg/Library/OpensslLib/openssl/apps/ocsp.c | 1290 ++ - .../OpensslLib/openssl/apps/openssl-vms.cnf | 346 + - .../Library/OpensslLib/openssl/apps/openssl.c | 695 ++ - .../Library/OpensslLib/openssl/apps/openssl.cnf | 346 + - CryptoPkg/Library/OpensslLib/openssl/apps/opt.c | 977 ++ - CryptoPkg/Library/OpensslLib/openssl/apps/passwd.c | 512 + - .../Library/OpensslLib/openssl/apps/pca-cert.srl | 1 + - .../Library/OpensslLib/openssl/apps/pca-key.pem | 16 + - .../Library/OpensslLib/openssl/apps/pca-req.pem | 11 + - CryptoPkg/Library/OpensslLib/openssl/apps/pkcs12.c | 935 ++ - CryptoPkg/Library/OpensslLib/openssl/apps/pkcs7.c | 197 + - CryptoPkg/Library/OpensslLib/openssl/apps/pkcs8.c | 353 + - CryptoPkg/Library/OpensslLib/openssl/apps/pkey.c | 190 + - .../Library/OpensslLib/openssl/apps/pkeyparam.c | 104 + - .../Library/OpensslLib/openssl/apps/pkeyutl.c | 489 + - CryptoPkg/Library/OpensslLib/openssl/apps/prime.c | 126 + - .../Library/OpensslLib/openssl/apps/privkey.pem | 16 + - CryptoPkg/Library/OpensslLib/openssl/apps/progs.h | 415 + - CryptoPkg/Library/OpensslLib/openssl/apps/progs.pl | 155 + - CryptoPkg/Library/OpensslLib/openssl/apps/rand.c | 132 + - CryptoPkg/Library/OpensslLib/openssl/apps/rehash.c | 480 + - CryptoPkg/Library/OpensslLib/openssl/apps/req.c | 1508 +++ - CryptoPkg/Library/OpensslLib/openssl/apps/req.pem | 11 + - CryptoPkg/Library/OpensslLib/openssl/apps/rsa.c | 310 + - .../Library/OpensslLib/openssl/apps/rsa8192.pem | 101 + - CryptoPkg/Library/OpensslLib/openssl/apps/rsautl.c | 278 + - .../Library/OpensslLib/openssl/apps/s1024key.pem | 15 + - .../Library/OpensslLib/openssl/apps/s1024req.pem | 11 + - .../Library/OpensslLib/openssl/apps/s512-key.pem | 9 + - .../Library/OpensslLib/openssl/apps/s512-req.pem | 8 + - CryptoPkg/Library/OpensslLib/openssl/apps/s_apps.h | 102 + - CryptoPkg/Library/OpensslLib/openssl/apps/s_cb.c | 1335 ++ - .../Library/OpensslLib/openssl/apps/s_client.c | 2747 ++++ - .../Library/OpensslLib/openssl/apps/s_server.c | 3301 +++++ - .../Library/OpensslLib/openssl/apps/s_socket.c | 201 + - CryptoPkg/Library/OpensslLib/openssl/apps/s_time.c | 422 + - .../Library/OpensslLib/openssl/apps/server.pem | 52 + - .../Library/OpensslLib/openssl/apps/server.srl | 1 + - .../Library/OpensslLib/openssl/apps/server2.pem | 52 + - .../Library/OpensslLib/openssl/apps/sess_id.c | 190 + - CryptoPkg/Library/OpensslLib/openssl/apps/smime.c | 656 + - CryptoPkg/Library/OpensslLib/openssl/apps/speed.c | 3144 +++++ - CryptoPkg/Library/OpensslLib/openssl/apps/spkac.c | 193 + - CryptoPkg/Library/OpensslLib/openssl/apps/srp.c | 609 + - .../Library/OpensslLib/openssl/apps/testCA.pem | 8 + - .../Library/OpensslLib/openssl/apps/testdsa.h | 290 + - .../Library/OpensslLib/openssl/apps/testrsa.h | 1960 +++ - .../Library/OpensslLib/openssl/apps/timeouts.h | 17 + - CryptoPkg/Library/OpensslLib/openssl/apps/ts.c | 995 ++ - CryptoPkg/Library/OpensslLib/openssl/apps/tsget.in | 201 + - CryptoPkg/Library/OpensslLib/openssl/apps/verify.c | 311 + - .../Library/OpensslLib/openssl/apps/version.c | 140 + - .../OpensslLib/openssl/apps/vms_decc_init.c | 214 + - .../OpensslLib/openssl/apps/vms_term_sock.c | 590 + - .../OpensslLib/openssl/apps/vms_term_sock.h | 30 + - .../Library/OpensslLib/openssl/apps/win32_init.c | 307 + - CryptoPkg/Library/OpensslLib/openssl/apps/x509.c | 1101 ++ - CryptoPkg/Library/OpensslLib/openssl/appveyor.yml | 53 + - CryptoPkg/Library/OpensslLib/openssl/build.info | 41 + - CryptoPkg/Library/OpensslLib/openssl/config | 924 ++ - CryptoPkg/Library/OpensslLib/openssl/config.com | 93 + - .../Library/OpensslLib/openssl/crypto/LPdir_nyi.c | 53 + - .../Library/OpensslLib/openssl/crypto/LPdir_unix.c | 131 + - .../Library/OpensslLib/openssl/crypto/LPdir_vms.c | 204 + - .../Library/OpensslLib/openssl/crypto/LPdir_win.c | 211 + - .../OpensslLib/openssl/crypto/LPdir_win32.c | 38 + - .../OpensslLib/openssl/crypto/LPdir_wince.c | 41 + - .../OpensslLib/openssl/crypto/aes/aes_cbc.c | 24 + - .../OpensslLib/openssl/crypto/aes/aes_cfb.c | 43 + - .../OpensslLib/openssl/crypto/aes/aes_core.c | 1367 ++ - .../OpensslLib/openssl/crypto/aes/aes_ecb.c | 26 + - .../OpensslLib/openssl/crypto/aes/aes_ige.c | 281 + - .../OpensslLib/openssl/crypto/aes/aes_locl.h | 42 + - .../OpensslLib/openssl/crypto/aes/aes_misc.c | 21 + - .../OpensslLib/openssl/crypto/aes/aes_ofb.c | 19 + - .../OpensslLib/openssl/crypto/aes/aes_wrap.c | 27 + - .../OpensslLib/openssl/crypto/aes/aes_x86core.c | 1075 ++ - .../OpensslLib/openssl/crypto/aes/asm/aes-586.pl | 3000 +++++ - .../OpensslLib/openssl/crypto/aes/asm/aes-armv4.pl | 1245 ++ - .../openssl/crypto/aes/asm/aes-c64xplus.pl | 1382 ++ - .../OpensslLib/openssl/crypto/aes/asm/aes-ia64.S | 1130 ++ - .../OpensslLib/openssl/crypto/aes/asm/aes-mips.pl | 2131 ++++ - .../openssl/crypto/aes/asm/aes-parisc.pl | 1029 ++ - .../OpensslLib/openssl/crypto/aes/asm/aes-ppc.pl | 1459 +++ - .../OpensslLib/openssl/crypto/aes/asm/aes-s390x.pl | 2235 ++++ - .../openssl/crypto/aes/asm/aes-sparcv9.pl | 1192 ++ - .../openssl/crypto/aes/asm/aes-x86_64.pl | 2820 +++++ - .../openssl/crypto/aes/asm/aesfx-sparcv9.pl | 1270 ++ - .../openssl/crypto/aes/asm/aesni-mb-x86_64.pl | 1402 +++ - .../openssl/crypto/aes/asm/aesni-sha1-x86_64.pl | 2066 +++ - .../openssl/crypto/aes/asm/aesni-sha256-x86_64.pl | 1713 +++ - .../OpensslLib/openssl/crypto/aes/asm/aesni-x86.pl | 3413 +++++ - .../openssl/crypto/aes/asm/aesni-x86_64.pl | 5060 ++++++++ - .../OpensslLib/openssl/crypto/aes/asm/aesp8-ppc.pl | 3805 ++++++ - .../openssl/crypto/aes/asm/aest4-sparcv9.pl | 929 ++ - .../openssl/crypto/aes/asm/aesv8-armx.pl | 1008 ++ - .../openssl/crypto/aes/asm/bsaes-armv7.pl | 2495 ++++ - .../openssl/crypto/aes/asm/bsaes-x86_64.pl | 3111 +++++ - .../openssl/crypto/aes/asm/vpaes-armv8.pl | 1259 ++ - .../OpensslLib/openssl/crypto/aes/asm/vpaes-ppc.pl | 1594 +++ - .../OpensslLib/openssl/crypto/aes/asm/vpaes-x86.pl | 916 ++ - .../openssl/crypto/aes/asm/vpaes-x86_64.pl | 1215 ++ - .../OpensslLib/openssl/crypto/aes/build.info | 57 + - .../OpensslLib/openssl/crypto/alphacpuid.pl | 257 + - .../OpensslLib/openssl/crypto/arm64cpuid.pl | 126 + - .../Library/OpensslLib/openssl/crypto/arm_arch.h | 83 + - .../Library/OpensslLib/openssl/crypto/armcap.c | 193 + - .../OpensslLib/openssl/crypto/armv4cpuid.pl | 296 + - .../OpensslLib/openssl/crypto/asn1/a_bitstr.c | 210 + - .../OpensslLib/openssl/crypto/asn1/a_d2i_fp.c | 235 + - .../OpensslLib/openssl/crypto/asn1/a_digest.c | 66 + - .../Library/OpensslLib/openssl/crypto/asn1/a_dup.c | 68 + - .../OpensslLib/openssl/crypto/asn1/a_gentm.c | 273 + - .../OpensslLib/openssl/crypto/asn1/a_i2d_fp.c | 108 + - .../Library/OpensslLib/openssl/crypto/asn1/a_int.c | 624 + - .../OpensslLib/openssl/crypto/asn1/a_mbstr.c | 395 + - .../OpensslLib/openssl/crypto/asn1/a_object.c | 370 + - .../OpensslLib/openssl/crypto/asn1/a_octet.c | 29 + - .../OpensslLib/openssl/crypto/asn1/a_print.c | 109 + - .../OpensslLib/openssl/crypto/asn1/a_sign.c | 228 + - .../OpensslLib/openssl/crypto/asn1/a_strex.c | 645 + - .../OpensslLib/openssl/crypto/asn1/a_strnid.c | 287 + - .../OpensslLib/openssl/crypto/asn1/a_time.c | 163 + - .../OpensslLib/openssl/crypto/asn1/a_type.c | 134 + - .../OpensslLib/openssl/crypto/asn1/a_utctm.c | 254 + - .../OpensslLib/openssl/crypto/asn1/a_utf8.c | 188 + - .../OpensslLib/openssl/crypto/asn1/a_verify.c | 182 + - .../OpensslLib/openssl/crypto/asn1/ameth_lib.c | 400 + - .../OpensslLib/openssl/crypto/asn1/asn1_err.c | 267 + - .../OpensslLib/openssl/crypto/asn1/asn1_gen.c | 789 ++ - .../OpensslLib/openssl/crypto/asn1/asn1_lib.c | 384 + - .../OpensslLib/openssl/crypto/asn1/asn1_locl.h | 78 + - .../OpensslLib/openssl/crypto/asn1/asn1_par.c | 375 + - .../OpensslLib/openssl/crypto/asn1/asn_mime.c | 980 ++ - .../OpensslLib/openssl/crypto/asn1/asn_moid.c | 105 + - .../OpensslLib/openssl/crypto/asn1/asn_mstbl.c | 114 + - .../OpensslLib/openssl/crypto/asn1/asn_pack.c | 62 + - .../OpensslLib/openssl/crypto/asn1/bio_asn1.c | 437 + - .../OpensslLib/openssl/crypto/asn1/bio_ndef.c | 199 + - .../OpensslLib/openssl/crypto/asn1/build.info | 16 + - .../OpensslLib/openssl/crypto/asn1/charmap.h | 34 + - .../OpensslLib/openssl/crypto/asn1/charmap.pl | 117 + - .../OpensslLib/openssl/crypto/asn1/d2i_pr.c | 125 + - .../OpensslLib/openssl/crypto/asn1/d2i_pu.c | 78 + - .../OpensslLib/openssl/crypto/asn1/evp_asn1.c | 115 + - .../Library/OpensslLib/openssl/crypto/asn1/f_int.c | 167 + - .../OpensslLib/openssl/crypto/asn1/f_string.c | 148 + - .../OpensslLib/openssl/crypto/asn1/i2d_pr.c | 33 + - .../OpensslLib/openssl/crypto/asn1/i2d_pu.c | 38 + - .../OpensslLib/openssl/crypto/asn1/n_pkey.c | 62 + - .../Library/OpensslLib/openssl/crypto/asn1/nsseq.c | 34 + - .../OpensslLib/openssl/crypto/asn1/p5_pbe.c | 96 + - .../OpensslLib/openssl/crypto/asn1/p5_pbev2.c | 221 + - .../OpensslLib/openssl/crypto/asn1/p5_scrypt.c | 283 + - .../OpensslLib/openssl/crypto/asn1/p8_pkey.c | 80 + - .../OpensslLib/openssl/crypto/asn1/t_bitst.c | 56 + - .../OpensslLib/openssl/crypto/asn1/t_pkey.c | 93 + - .../OpensslLib/openssl/crypto/asn1/t_spki.c | 56 + - .../OpensslLib/openssl/crypto/asn1/tasn_dec.c | 1142 ++ - .../OpensslLib/openssl/crypto/asn1/tasn_enc.c | 605 + - .../OpensslLib/openssl/crypto/asn1/tasn_fre.c | 207 + - .../OpensslLib/openssl/crypto/asn1/tasn_new.c | 337 + - .../OpensslLib/openssl/crypto/asn1/tasn_prn.c | 538 + - .../OpensslLib/openssl/crypto/asn1/tasn_scn.c | 65 + - .../OpensslLib/openssl/crypto/asn1/tasn_typ.c | 84 + - .../OpensslLib/openssl/crypto/asn1/tasn_utl.c | 240 + - .../OpensslLib/openssl/crypto/asn1/x_algor.c | 93 + - .../OpensslLib/openssl/crypto/asn1/x_bignum.c | 146 + - .../OpensslLib/openssl/crypto/asn1/x_info.c | 39 + - .../OpensslLib/openssl/crypto/asn1/x_long.c | 146 + - .../OpensslLib/openssl/crypto/asn1/x_pkey.c | 47 + - .../Library/OpensslLib/openssl/crypto/asn1/x_sig.c | 39 + - .../OpensslLib/openssl/crypto/asn1/x_spki.c | 33 + - .../Library/OpensslLib/openssl/crypto/asn1/x_val.c | 20 + - .../openssl/crypto/async/arch/async_null.c | 23 + - .../openssl/crypto/async/arch/async_null.h | 30 + - .../openssl/crypto/async/arch/async_posix.c | 58 + - .../openssl/crypto/async/arch/async_posix.h | 58 + - .../openssl/crypto/async/arch/async_win.c | 55 + - .../openssl/crypto/async/arch/async_win.h | 36 + - .../OpensslLib/openssl/crypto/async/async.c | 433 + - .../OpensslLib/openssl/crypto/async/async_err.c | 51 + - .../OpensslLib/openssl/crypto/async/async_locl.h | 77 + - .../OpensslLib/openssl/crypto/async/async_wait.c | 211 + - .../OpensslLib/openssl/crypto/async/build.info | 4 + - .../OpensslLib/openssl/crypto/bf/asm/bf-586.pl | 149 + - .../Library/OpensslLib/openssl/crypto/bf/bf_cbc.c | 86 + - .../OpensslLib/openssl/crypto/bf/bf_cfb64.c | 74 + - .../Library/OpensslLib/openssl/crypto/bf/bf_ecb.c | 43 + - .../Library/OpensslLib/openssl/crypto/bf/bf_enc.c | 179 + - .../Library/OpensslLib/openssl/crypto/bf/bf_locl.h | 70 + - .../OpensslLib/openssl/crypto/bf/bf_ofb64.c | 61 + - .../Library/OpensslLib/openssl/crypto/bf/bf_pi.h | 530 + - .../Library/OpensslLib/openssl/crypto/bf/bf_skey.c | 67 + - .../OpensslLib/openssl/crypto/bf/build.info | 6 + - .../Library/OpensslLib/openssl/crypto/bio/b_addr.c | 897 ++ - .../Library/OpensslLib/openssl/crypto/bio/b_dump.c | 158 + - .../OpensslLib/openssl/crypto/bio/b_print.c | 944 ++ - .../Library/OpensslLib/openssl/crypto/bio/b_sock.c | 381 + - .../OpensslLib/openssl/crypto/bio/b_sock2.c | 270 + - .../OpensslLib/openssl/crypto/bio/bf_buff.c | 455 + - .../OpensslLib/openssl/crypto/bio/bf_lbuf.c | 319 + - .../OpensslLib/openssl/crypto/bio/bf_nbio.c | 194 + - .../OpensslLib/openssl/crypto/bio/bf_null.c | 140 + - .../Library/OpensslLib/openssl/crypto/bio/bio_cb.c | 99 + - .../OpensslLib/openssl/crypto/bio/bio_err.c | 125 + - .../OpensslLib/openssl/crypto/bio/bio_lcl.h | 188 + - .../OpensslLib/openssl/crypto/bio/bio_lib.c | 600 + - .../OpensslLib/openssl/crypto/bio/bio_meth.c | 145 + - .../OpensslLib/openssl/crypto/bio/bss_acpt.c | 557 + - .../OpensslLib/openssl/crypto/bio/bss_bio.c | 805 ++ - .../OpensslLib/openssl/crypto/bio/bss_conn.c | 545 + - .../OpensslLib/openssl/crypto/bio/bss_dgram.c | 1944 +++ - .../Library/OpensslLib/openssl/crypto/bio/bss_fd.c | 273 + - .../OpensslLib/openssl/crypto/bio/bss_file.c | 419 + - .../OpensslLib/openssl/crypto/bio/bss_log.c | 406 + - .../OpensslLib/openssl/crypto/bio/bss_mem.c | 347 + - .../OpensslLib/openssl/crypto/bio/bss_null.c | 100 + - .../OpensslLib/openssl/crypto/bio/bss_sock.c | 231 + - .../OpensslLib/openssl/crypto/bio/build.info | 8 + - .../OpensslLib/openssl/crypto/blake2/blake2_impl.h | 130 + - .../OpensslLib/openssl/crypto/blake2/blake2_locl.h | 91 + - .../OpensslLib/openssl/crypto/blake2/blake2b.c | 270 + - .../OpensslLib/openssl/crypto/blake2/blake2s.c | 264 + - .../OpensslLib/openssl/crypto/blake2/build.info | 3 + - .../OpensslLib/openssl/crypto/blake2/m_blake2b.c | 59 + - .../OpensslLib/openssl/crypto/blake2/m_blake2s.c | 59 + - .../OpensslLib/openssl/crypto/bn/README.pod | 247 + - .../OpensslLib/openssl/crypto/bn/asm/alpha-mont.pl | 331 + - .../OpensslLib/openssl/crypto/bn/asm/armv4-gf2m.pl | 332 + - .../OpensslLib/openssl/crypto/bn/asm/armv4-mont.pl | 756 ++ - .../OpensslLib/openssl/crypto/bn/asm/armv8-mont.pl | 1510 +++ - .../OpensslLib/openssl/crypto/bn/asm/bn-586.pl | 785 ++ - .../openssl/crypto/bn/asm/bn-c64xplus.asm | 382 + - .../openssl/crypto/bn/asm/c64xplus-gf2m.pl | 160 + - .../OpensslLib/openssl/crypto/bn/asm/co-586.pl | 298 + - .../OpensslLib/openssl/crypto/bn/asm/ia64-mont.pl | 860 ++ - .../OpensslLib/openssl/crypto/bn/asm/ia64.S | 1562 +++ - .../OpensslLib/openssl/crypto/bn/asm/mips-mont.pl | 433 + - .../OpensslLib/openssl/crypto/bn/asm/mips.pl | 2241 ++++ - .../OpensslLib/openssl/crypto/bn/asm/pa-risc2.s | 1624 +++ - .../OpensslLib/openssl/crypto/bn/asm/pa-risc2W.s | 1612 +++ - .../openssl/crypto/bn/asm/parisc-mont.pl | 1002 ++ - .../OpensslLib/openssl/crypto/bn/asm/ppc-mont.pl | 342 + - .../OpensslLib/openssl/crypto/bn/asm/ppc.pl | 2014 +++ - .../OpensslLib/openssl/crypto/bn/asm/ppc64-mont.pl | 1635 +++ - .../OpensslLib/openssl/crypto/bn/asm/rsaz-avx2.pl | 1968 +++ - .../openssl/crypto/bn/asm/rsaz-x86_64.pl | 2358 ++++ - .../OpensslLib/openssl/crypto/bn/asm/s390x-gf2m.pl | 228 + - .../OpensslLib/openssl/crypto/bn/asm/s390x-mont.pl | 284 + - .../OpensslLib/openssl/crypto/bn/asm/s390x.S | 713 ++ - .../openssl/crypto/bn/asm/sparct4-mont.pl | 1232 ++ - .../OpensslLib/openssl/crypto/bn/asm/sparcv8.S | 1458 +++ - .../OpensslLib/openssl/crypto/bn/asm/sparcv8plus.S | 1562 +++ - .../openssl/crypto/bn/asm/sparcv9-gf2m.pl | 200 + - .../openssl/crypto/bn/asm/sparcv9-mont.pl | 616 + - .../openssl/crypto/bn/asm/sparcv9a-mont.pl | 887 ++ - .../OpensslLib/openssl/crypto/bn/asm/via-mont.pl | 254 + - .../OpensslLib/openssl/crypto/bn/asm/vis3-mont.pl | 384 + - .../OpensslLib/openssl/crypto/bn/asm/x86-gf2m.pl | 325 + - .../OpensslLib/openssl/crypto/bn/asm/x86-mont.pl | 629 + - .../OpensslLib/openssl/crypto/bn/asm/x86.pl | 38 + - .../OpensslLib/openssl/crypto/bn/asm/x86_64-gcc.c | 647 + - .../openssl/crypto/bn/asm/x86_64-gf2m.pl | 397 + - .../openssl/crypto/bn/asm/x86_64-mont.pl | 1521 +++ - .../openssl/crypto/bn/asm/x86_64-mont5.pl | 3827 ++++++ - .../Library/OpensslLib/openssl/crypto/bn/bn_add.c | 205 + - .../Library/OpensslLib/openssl/crypto/bn/bn_asm.c | 1039 ++ - .../OpensslLib/openssl/crypto/bn/bn_blind.c | 289 + - .../OpensslLib/openssl/crypto/bn/bn_const.c | 553 + - .../Library/OpensslLib/openssl/crypto/bn/bn_ctx.c | 353 + - .../Library/OpensslLib/openssl/crypto/bn/bn_depr.c | 68 + - .../Library/OpensslLib/openssl/crypto/bn/bn_dh.c | 220 + - .../Library/OpensslLib/openssl/crypto/bn/bn_div.c | 423 + - .../Library/OpensslLib/openssl/crypto/bn/bn_err.c | 107 + - .../Library/OpensslLib/openssl/crypto/bn/bn_exp.c | 1362 ++ - .../Library/OpensslLib/openssl/crypto/bn/bn_exp2.c | 201 + - .../Library/OpensslLib/openssl/crypto/bn/bn_gcd.c | 620 + - .../Library/OpensslLib/openssl/crypto/bn/bn_gf2m.c | 0 - .../OpensslLib/openssl/crypto/bn/bn_intern.c | 210 + - .../Library/OpensslLib/openssl/crypto/bn/bn_kron.c | 140 + - .../Library/OpensslLib/openssl/crypto/bn/bn_lcl.h | 689 + - .../Library/OpensslLib/openssl/crypto/bn/bn_lib.c | 1037 ++ - .../Library/OpensslLib/openssl/crypto/bn/bn_mod.c | 201 + - .../Library/OpensslLib/openssl/crypto/bn/bn_mont.c | 434 + - .../Library/OpensslLib/openssl/crypto/bn/bn_mpi.c | 86 + - .../Library/OpensslLib/openssl/crypto/bn/bn_mul.c | 1045 ++ - .../Library/OpensslLib/openssl/crypto/bn/bn_nist.c | 1239 ++ - .../OpensslLib/openssl/crypto/bn/bn_prime.c | 608 + - .../OpensslLib/openssl/crypto/bn/bn_prime.h | 274 + - .../OpensslLib/openssl/crypto/bn/bn_prime.pl | 46 + - .../OpensslLib/openssl/crypto/bn/bn_print.c | 345 + - .../Library/OpensslLib/openssl/crypto/bn/bn_rand.c | 258 + - .../Library/OpensslLib/openssl/crypto/bn/bn_recp.c | 199 + - .../OpensslLib/openssl/crypto/bn/bn_shift.c | 175 + - .../Library/OpensslLib/openssl/crypto/bn/bn_sqr.c | 235 + - .../Library/OpensslLib/openssl/crypto/bn/bn_sqrt.c | 358 + - .../Library/OpensslLib/openssl/crypto/bn/bn_srp.c | 545 + - .../Library/OpensslLib/openssl/crypto/bn/bn_word.c | 201 + - .../OpensslLib/openssl/crypto/bn/bn_x931p.c | 238 + - .../OpensslLib/openssl/crypto/bn/build.info | 84 + - .../OpensslLib/openssl/crypto/bn/rsaz_exp.c | 352 + - .../OpensslLib/openssl/crypto/bn/rsaz_exp.h | 77 + - .../OpensslLib/openssl/crypto/buffer/buf_err.c | 44 + - .../OpensslLib/openssl/crypto/buffer/buffer.c | 164 + - .../OpensslLib/openssl/crypto/buffer/build.info | 2 + - .../Library/OpensslLib/openssl/crypto/build.info | 37 + - .../OpensslLib/openssl/crypto/c64xpluscpuid.pl | 287 + - .../openssl/crypto/camellia/asm/cmll-x86.pl | 1150 ++ - .../openssl/crypto/camellia/asm/cmll-x86_64.pl | 1088 ++ - .../openssl/crypto/camellia/asm/cmllt4-sparcv9.pl | 939 ++ - .../OpensslLib/openssl/crypto/camellia/build.info | 11 + - .../OpensslLib/openssl/crypto/camellia/camellia.c | 541 + - .../OpensslLib/openssl/crypto/camellia/cmll_cbc.c | 24 + - .../OpensslLib/openssl/crypto/camellia/cmll_cfb.c | 43 + - .../OpensslLib/openssl/crypto/camellia/cmll_ctr.c | 22 + - .../OpensslLib/openssl/crypto/camellia/cmll_ecb.c | 20 + - .../OpensslLib/openssl/crypto/camellia/cmll_locl.h | 43 + - .../OpensslLib/openssl/crypto/camellia/cmll_misc.c | 35 + - .../OpensslLib/openssl/crypto/camellia/cmll_ofb.c | 24 + - .../OpensslLib/openssl/crypto/cast/asm/cast-586.pl | 192 + - .../OpensslLib/openssl/crypto/cast/build.info | 6 + - .../OpensslLib/openssl/crypto/cast/c_cfb64.c | 74 + - .../Library/OpensslLib/openssl/crypto/cast/c_ecb.c | 32 + - .../Library/OpensslLib/openssl/crypto/cast/c_enc.c | 151 + - .../OpensslLib/openssl/crypto/cast/c_ofb64.c | 61 + - .../OpensslLib/openssl/crypto/cast/c_skey.c | 118 + - .../OpensslLib/openssl/crypto/cast/cast_lcl.h | 176 + - .../OpensslLib/openssl/crypto/cast/cast_s.h | 544 + - .../openssl/crypto/chacha/asm/chacha-armv4.pl | 1158 ++ - .../openssl/crypto/chacha/asm/chacha-armv8.pl | 1135 ++ - .../openssl/crypto/chacha/asm/chacha-c64xplus.pl | 926 ++ - .../openssl/crypto/chacha/asm/chacha-ppc.pl | 953 ++ - .../openssl/crypto/chacha/asm/chacha-s390x.pl | 326 + - .../openssl/crypto/chacha/asm/chacha-x86.pl | 1154 ++ - .../openssl/crypto/chacha/asm/chacha-x86_64.pl | 2245 ++++ - .../OpensslLib/openssl/crypto/chacha/build.info | 17 + - .../OpensslLib/openssl/crypto/chacha/chacha_enc.c | 121 + - .../OpensslLib/openssl/crypto/cmac/build.info | 2 + - .../OpensslLib/openssl/crypto/cmac/cm_ameth.c | 51 + - .../OpensslLib/openssl/crypto/cmac/cm_pmeth.c | 161 + - .../Library/OpensslLib/openssl/crypto/cmac/cmac.c | 223 + - .../OpensslLib/openssl/crypto/cms/build.info | 5 + - .../OpensslLib/openssl/crypto/cms/cms_asn1.c | 402 + - .../OpensslLib/openssl/crypto/cms/cms_att.c | 152 + - .../Library/OpensslLib/openssl/crypto/cms/cms_cd.c | 82 + - .../Library/OpensslLib/openssl/crypto/cms/cms_dd.c | 99 + - .../OpensslLib/openssl/crypto/cms/cms_enc.c | 212 + - .../OpensslLib/openssl/crypto/cms/cms_env.c | 902 ++ - .../OpensslLib/openssl/crypto/cms/cms_err.c | 258 + - .../OpensslLib/openssl/crypto/cms/cms_ess.c | 337 + - .../Library/OpensslLib/openssl/crypto/cms/cms_io.c | 88 + - .../OpensslLib/openssl/crypto/cms/cms_kari.c | 411 + - .../OpensslLib/openssl/crypto/cms/cms_lcl.h | 444 + - .../OpensslLib/openssl/crypto/cms/cms_lib.c | 587 + - .../OpensslLib/openssl/crypto/cms/cms_pwri.c | 392 + - .../Library/OpensslLib/openssl/crypto/cms/cms_sd.c | 923 ++ - .../OpensslLib/openssl/crypto/cms/cms_smime.c | 844 ++ - .../OpensslLib/openssl/crypto/comp/build.info | 4 + - .../OpensslLib/openssl/crypto/comp/c_zlib.c | 615 + - .../OpensslLib/openssl/crypto/comp/comp_err.c | 48 + - .../OpensslLib/openssl/crypto/comp/comp_lcl.h | 30 + - .../OpensslLib/openssl/crypto/comp/comp_lib.c | 91 + - .../OpensslLib/openssl/crypto/conf/build.info | 4 + - .../OpensslLib/openssl/crypto/conf/conf_api.c | 214 + - .../OpensslLib/openssl/crypto/conf/conf_def.c | 630 + - .../OpensslLib/openssl/crypto/conf/conf_def.h | 129 + - .../OpensslLib/openssl/crypto/conf/conf_err.c | 79 + - .../OpensslLib/openssl/crypto/conf/conf_lib.c | 365 + - .../OpensslLib/openssl/crypto/conf/conf_mall.c | 29 + - .../OpensslLib/openssl/crypto/conf/conf_mod.c | 549 + - .../OpensslLib/openssl/crypto/conf/conf_sap.c | 60 + - .../OpensslLib/openssl/crypto/conf/keysets.pl | 141 + - .../Library/OpensslLib/openssl/crypto/cpt_err.c | 55 + - .../Library/OpensslLib/openssl/crypto/cryptlib.c | 341 + - .../OpensslLib/openssl/crypto/ct/build.info | 3 + - .../Library/OpensslLib/openssl/crypto/ct/ct_b64.c | 164 + - .../Library/OpensslLib/openssl/crypto/ct/ct_err.c | 87 + - .../Library/OpensslLib/openssl/crypto/ct/ct_locl.h | 216 + - .../Library/OpensslLib/openssl/crypto/ct/ct_log.c | 304 + - .../Library/OpensslLib/openssl/crypto/ct/ct_oct.c | 407 + - .../OpensslLib/openssl/crypto/ct/ct_policy.c | 98 + - .../Library/OpensslLib/openssl/crypto/ct/ct_prn.c | 127 + - .../Library/OpensslLib/openssl/crypto/ct/ct_sct.c | 393 + - .../OpensslLib/openssl/crypto/ct/ct_sct_ctx.c | 263 + - .../Library/OpensslLib/openssl/crypto/ct/ct_vfy.c | 140 + - .../OpensslLib/openssl/crypto/ct/ct_x509v3.c | 60 + - .../Library/OpensslLib/openssl/crypto/cversion.c | 65 + - .../OpensslLib/openssl/crypto/des/asm/crypt586.pl | 217 + - .../OpensslLib/openssl/crypto/des/asm/des-586.pl | 465 + - .../OpensslLib/openssl/crypto/des/asm/des_enc.m4 | 1972 +++ - .../OpensslLib/openssl/crypto/des/asm/desboth.pl | 86 + - .../openssl/crypto/des/asm/dest4-sparcv9.pl | 627 + - .../OpensslLib/openssl/crypto/des/build.info | 17 + - .../OpensslLib/openssl/crypto/des/cbc_cksm.c | 54 + - .../OpensslLib/openssl/crypto/des/cbc_enc.c | 12 + - .../OpensslLib/openssl/crypto/des/cfb64ede.c | 190 + - .../OpensslLib/openssl/crypto/des/cfb64enc.c | 73 + - .../OpensslLib/openssl/crypto/des/cfb_enc.c | 150 + - .../OpensslLib/openssl/crypto/des/des_enc.c | 301 + - .../OpensslLib/openssl/crypto/des/des_locl.h | 217 + - .../OpensslLib/openssl/crypto/des/ecb3_enc.c | 33 + - .../OpensslLib/openssl/crypto/des/ecb_enc.c | 51 + - .../Library/OpensslLib/openssl/crypto/des/fcrypt.c | 149 + - .../OpensslLib/openssl/crypto/des/fcrypt_b.c | 72 + - .../OpensslLib/openssl/crypto/des/ncbc_enc.c | 106 + - .../OpensslLib/openssl/crypto/des/ofb64ede.c | 62 + - .../OpensslLib/openssl/crypto/des/ofb64enc.c | 60 + - .../OpensslLib/openssl/crypto/des/ofb_enc.c | 82 + - .../OpensslLib/openssl/crypto/des/pcbc_enc.c | 66 + - .../OpensslLib/openssl/crypto/des/qud_cksm.c | 77 + - .../OpensslLib/openssl/crypto/des/rand_key.c | 21 + - .../OpensslLib/openssl/crypto/des/rpc_des.h | 76 + - .../OpensslLib/openssl/crypto/des/rpc_enc.c | 30 + - .../OpensslLib/openssl/crypto/des/set_key.c | 389 + - .../Library/OpensslLib/openssl/crypto/des/spr.h | 163 + - .../OpensslLib/openssl/crypto/des/str2key.c | 97 + - .../OpensslLib/openssl/crypto/des/xcbc_enc.c | 103 + - .../OpensslLib/openssl/crypto/dh/build.info | 4 + - .../OpensslLib/openssl/crypto/dh/dh1024.pem | 5 + - .../Library/OpensslLib/openssl/crypto/dh/dh192.pem | 3 + - .../OpensslLib/openssl/crypto/dh/dh2048.pem | 16 + - .../OpensslLib/openssl/crypto/dh/dh4096.pem | 14 + - .../Library/OpensslLib/openssl/crypto/dh/dh512.pem | 4 + - .../OpensslLib/openssl/crypto/dh/dh_ameth.c | 870 ++ - .../Library/OpensslLib/openssl/crypto/dh/dh_asn1.c | 138 + - .../OpensslLib/openssl/crypto/dh/dh_check.c | 183 + - .../Library/OpensslLib/openssl/crypto/dh/dh_depr.c | 46 + - .../Library/OpensslLib/openssl/crypto/dh/dh_err.c | 73 + - .../Library/OpensslLib/openssl/crypto/dh/dh_gen.c | 130 + - .../Library/OpensslLib/openssl/crypto/dh/dh_kdf.c | 150 + - .../Library/OpensslLib/openssl/crypto/dh/dh_key.c | 215 + - .../Library/OpensslLib/openssl/crypto/dh/dh_lib.c | 284 + - .../Library/OpensslLib/openssl/crypto/dh/dh_locl.h | 56 + - .../Library/OpensslLib/openssl/crypto/dh/dh_meth.c | 173 + - .../OpensslLib/openssl/crypto/dh/dh_pmeth.c | 501 + - .../Library/OpensslLib/openssl/crypto/dh/dh_prn.c | 30 + - .../OpensslLib/openssl/crypto/dh/dh_rfc5114.c | 41 + - .../Library/OpensslLib/openssl/crypto/dllmain.c | 60 + - .../OpensslLib/openssl/crypto/dsa/build.info | 5 + - .../OpensslLib/openssl/crypto/dsa/dsa_ameth.c | 567 + - .../OpensslLib/openssl/crypto/dsa/dsa_asn1.c | 155 + - .../OpensslLib/openssl/crypto/dsa/dsa_depr.c | 62 + - .../OpensslLib/openssl/crypto/dsa/dsa_err.c | 76 + - .../OpensslLib/openssl/crypto/dsa/dsa_gen.c | 601 + - .../OpensslLib/openssl/crypto/dsa/dsa_key.c | 77 + - .../OpensslLib/openssl/crypto/dsa/dsa_lib.c | 346 + - .../OpensslLib/openssl/crypto/dsa/dsa_locl.h | 76 + - .../OpensslLib/openssl/crypto/dsa/dsa_meth.c | 224 + - .../OpensslLib/openssl/crypto/dsa/dsa_ossl.c | 338 + - .../OpensslLib/openssl/crypto/dsa/dsa_pmeth.c | 273 + - .../OpensslLib/openssl/crypto/dsa/dsa_prn.c | 69 + - .../OpensslLib/openssl/crypto/dsa/dsa_sign.c | 24 + - .../OpensslLib/openssl/crypto/dsa/dsa_vrf.c | 19 + - .../OpensslLib/openssl/crypto/dso/build.info | 4 + - .../Library/OpensslLib/openssl/crypto/dso/dso_dl.c | 279 + - .../OpensslLib/openssl/crypto/dso/dso_dlfcn.c | 354 + - .../OpensslLib/openssl/crypto/dso/dso_err.c | 93 + - .../OpensslLib/openssl/crypto/dso/dso_lib.c | 349 + - .../OpensslLib/openssl/crypto/dso/dso_locl.h | 106 + - .../OpensslLib/openssl/crypto/dso/dso_openssl.c | 22 + - .../OpensslLib/openssl/crypto/dso/dso_vms.c | 468 + - .../OpensslLib/openssl/crypto/dso/dso_win32.c | 573 + - .../Library/OpensslLib/openssl/crypto/ebcdic.c | 366 + - .../openssl/crypto/ec/asm/ecp_nistz256-armv4.pl | 1865 +++ - .../openssl/crypto/ec/asm/ecp_nistz256-armv8.pl | 1558 +++ - .../openssl/crypto/ec/asm/ecp_nistz256-avx2.pl | 2100 ++++ - .../openssl/crypto/ec/asm/ecp_nistz256-sparcv9.pl | 3061 +++++ - .../openssl/crypto/ec/asm/ecp_nistz256-x86.pl | 1866 +++ - .../openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl | 3087 +++++ - .../OpensslLib/openssl/crypto/ec/build.info | 28 + - .../OpensslLib/openssl/crypto/ec/curve25519.c | 3394 +++++ - .../OpensslLib/openssl/crypto/ec/ec2_mult.c | 0 - .../Library/OpensslLib/openssl/crypto/ec/ec2_oct.c | 0 - .../OpensslLib/openssl/crypto/ec/ec2_smpl.c | 0 - .../OpensslLib/openssl/crypto/ec/ec_ameth.c | 881 ++ - .../Library/OpensslLib/openssl/crypto/ec/ec_asn1.c | 1234 ++ - .../OpensslLib/openssl/crypto/ec/ec_check.c | 72 + - .../OpensslLib/openssl/crypto/ec/ec_curve.c | 0 - .../Library/OpensslLib/openssl/crypto/ec/ec_cvt.c | 95 + - .../Library/OpensslLib/openssl/crypto/ec/ec_err.c | 290 + - .../Library/OpensslLib/openssl/crypto/ec/ec_key.c | 637 + - .../OpensslLib/openssl/crypto/ec/ec_kmeth.c | 317 + - .../Library/OpensslLib/openssl/crypto/ec/ec_lcl.h | 613 + - .../Library/OpensslLib/openssl/crypto/ec/ec_lib.c | 1004 ++ - .../Library/OpensslLib/openssl/crypto/ec/ec_mult.c | 680 + - .../Library/OpensslLib/openssl/crypto/ec/ec_oct.c | 165 + - .../OpensslLib/openssl/crypto/ec/ec_pmeth.c | 463 + - .../OpensslLib/openssl/crypto/ec/ec_print.c | 119 + - .../OpensslLib/openssl/crypto/ec/ecdh_kdf.c | 68 + - .../OpensslLib/openssl/crypto/ec/ecdh_ossl.c | 143 + - .../OpensslLib/openssl/crypto/ec/ecdsa_ossl.c | 462 + - .../OpensslLib/openssl/crypto/ec/ecdsa_sign.c | 52 + - .../OpensslLib/openssl/crypto/ec/ecdsa_vrf.c | 43 + - .../Library/OpensslLib/openssl/crypto/ec/eck_prn.c | 273 + - .../OpensslLib/openssl/crypto/ec/ecp_mont.c | 242 + - .../OpensslLib/openssl/crypto/ec/ecp_nist.c | 167 + - .../OpensslLib/openssl/crypto/ec/ecp_nistp224.c | 1717 +++ - .../OpensslLib/openssl/crypto/ec/ecp_nistp256.c | 2350 ++++ - .../OpensslLib/openssl/crypto/ec/ecp_nistp521.c | 2146 ++++ - .../OpensslLib/openssl/crypto/ec/ecp_nistputil.c | 223 + - .../OpensslLib/openssl/crypto/ec/ecp_nistz256.c | 1559 +++ - .../openssl/crypto/ec/ecp_nistz256_table.c | 9542 ++++++++++++++ - .../Library/OpensslLib/openssl/crypto/ec/ecp_oct.c | 372 + - .../OpensslLib/openssl/crypto/ec/ecp_smpl.c | 1369 ++ - .../OpensslLib/openssl/crypto/ec/ecx_meth.c | 373 + - .../OpensslLib/openssl/crypto/engine/README | 211 + - .../OpensslLib/openssl/crypto/engine/build.info | 8 + - .../OpensslLib/openssl/crypto/engine/eng_all.c | 31 + - .../OpensslLib/openssl/crypto/engine/eng_cnf.c | 192 + - .../openssl/crypto/engine/eng_cryptodev.c | 1754 +++ - .../OpensslLib/openssl/crypto/engine/eng_ctrl.c | 338 + - .../OpensslLib/openssl/crypto/engine/eng_dyn.c | 510 + - .../OpensslLib/openssl/crypto/engine/eng_err.c | 123 + - .../OpensslLib/openssl/crypto/engine/eng_fat.c | 127 + - .../OpensslLib/openssl/crypto/engine/eng_init.c | 108 + - .../OpensslLib/openssl/crypto/engine/eng_int.h | 183 + - .../OpensslLib/openssl/crypto/engine/eng_lib.c | 295 + - .../OpensslLib/openssl/crypto/engine/eng_list.c | 354 + - .../OpensslLib/openssl/crypto/engine/eng_openssl.c | 652 + - .../OpensslLib/openssl/crypto/engine/eng_pkey.c | 140 + - .../OpensslLib/openssl/crypto/engine/eng_rdrand.c | 110 + - .../OpensslLib/openssl/crypto/engine/eng_table.c | 303 + - .../OpensslLib/openssl/crypto/engine/tb_asnmth.c | 207 + - .../OpensslLib/openssl/crypto/engine/tb_cipher.c | 91 + - .../OpensslLib/openssl/crypto/engine/tb_dh.c | 72 + - .../OpensslLib/openssl/crypto/engine/tb_digest.c | 91 + - .../OpensslLib/openssl/crypto/engine/tb_dsa.c | 72 + - .../OpensslLib/openssl/crypto/engine/tb_eckey.c | 72 + - .../OpensslLib/openssl/crypto/engine/tb_pkmeth.c | 114 + - .../OpensslLib/openssl/crypto/engine/tb_rand.c | 72 + - .../OpensslLib/openssl/crypto/engine/tb_rsa.c | 72 + - .../Library/OpensslLib/openssl/crypto/err/README | 44 + - .../OpensslLib/openssl/crypto/err/build.info | 3 + - .../Library/OpensslLib/openssl/crypto/err/err.c | 770 ++ - .../OpensslLib/openssl/crypto/err/err_all.c | 109 + - .../OpensslLib/openssl/crypto/err/err_prn.c | 66 + - .../OpensslLib/openssl/crypto/err/openssl.ec | 100 + - .../OpensslLib/openssl/crypto/evp/bio_b64.c | 542 + - .../OpensslLib/openssl/crypto/evp/bio_enc.c | 449 + - .../Library/OpensslLib/openssl/crypto/evp/bio_md.c | 231 + - .../Library/OpensslLib/openssl/crypto/evp/bio_ok.c | 604 + - .../OpensslLib/openssl/crypto/evp/build.info | 22 + - .../Library/OpensslLib/openssl/crypto/evp/c_allc.c | 220 + - .../Library/OpensslLib/openssl/crypto/evp/c_alld.c | 49 + - .../OpensslLib/openssl/crypto/evp/cmeth_lib.c | 151 + - .../Library/OpensslLib/openssl/crypto/evp/digest.c | 269 + - .../Library/OpensslLib/openssl/crypto/evp/e_aes.c | 2702 ++++ - .../openssl/crypto/evp/e_aes_cbc_hmac_sha1.c | 957 ++ - .../openssl/crypto/evp/e_aes_cbc_hmac_sha256.c | 939 ++ - .../Library/OpensslLib/openssl/crypto/evp/e_bf.c | 38 + - .../OpensslLib/openssl/crypto/evp/e_camellia.c | 364 + - .../Library/OpensslLib/openssl/crypto/evp/e_cast.c | 40 + - .../openssl/crypto/evp/e_chacha20_poly1305.c | 454 + - .../Library/OpensslLib/openssl/crypto/evp/e_des.c | 242 + - .../Library/OpensslLib/openssl/crypto/evp/e_des3.c | 424 + - .../Library/OpensslLib/openssl/crypto/evp/e_idea.c | 70 + - .../Library/OpensslLib/openssl/crypto/evp/e_null.c | 50 + - .../Library/OpensslLib/openssl/crypto/evp/e_old.c | 113 + - .../Library/OpensslLib/openssl/crypto/evp/e_rc2.c | 189 + - .../Library/OpensslLib/openssl/crypto/evp/e_rc4.c | 82 + - .../OpensslLib/openssl/crypto/evp/e_rc4_hmac_md5.c | 262 + - .../Library/OpensslLib/openssl/crypto/evp/e_rc5.c | 74 + - .../Library/OpensslLib/openssl/crypto/evp/e_seed.c | 39 + - .../OpensslLib/openssl/crypto/evp/e_xcbc_d.c | 83 + - .../Library/OpensslLib/openssl/crypto/evp/encode.c | 404 + - .../OpensslLib/openssl/crypto/evp/evp_cnf.c | 65 + - .../OpensslLib/openssl/crypto/evp/evp_enc.c | 641 + - .../OpensslLib/openssl/crypto/evp/evp_err.c | 180 + - .../OpensslLib/openssl/crypto/evp/evp_key.c | 150 + - .../OpensslLib/openssl/crypto/evp/evp_lib.c | 497 + - .../OpensslLib/openssl/crypto/evp/evp_locl.h | 68 + - .../OpensslLib/openssl/crypto/evp/evp_pbe.c | 259 + - .../OpensslLib/openssl/crypto/evp/evp_pkey.c | 150 + - .../Library/OpensslLib/openssl/crypto/evp/m_md2.c | 56 + - .../Library/OpensslLib/openssl/crypto/evp/m_md4.c | 55 + - .../Library/OpensslLib/openssl/crypto/evp/m_md5.c | 55 + - .../OpensslLib/openssl/crypto/evp/m_md5_sha1.c | 142 + - .../Library/OpensslLib/openssl/crypto/evp/m_mdc2.c | 55 + - .../Library/OpensslLib/openssl/crypto/evp/m_null.c | 49 + - .../OpensslLib/openssl/crypto/evp/m_ripemd.c | 55 + - .../Library/OpensslLib/openssl/crypto/evp/m_sha1.c | 233 + - .../OpensslLib/openssl/crypto/evp/m_sigver.c | 169 + - .../Library/OpensslLib/openssl/crypto/evp/m_wp.c | 54 + - .../Library/OpensslLib/openssl/crypto/evp/names.c | 178 + - .../OpensslLib/openssl/crypto/evp/p5_crpt.c | 103 + - .../OpensslLib/openssl/crypto/evp/p5_crpt2.c | 277 + - .../Library/OpensslLib/openssl/crypto/evp/p_dec.c | 36 + - .../Library/OpensslLib/openssl/crypto/evp/p_enc.c | 35 + - .../Library/OpensslLib/openssl/crypto/evp/p_lib.c | 484 + - .../Library/OpensslLib/openssl/crypto/evp/p_open.c | 73 + - .../Library/OpensslLib/openssl/crypto/evp/p_seal.c | 70 + - .../Library/OpensslLib/openssl/crypto/evp/p_sign.c | 61 + - .../OpensslLib/openssl/crypto/evp/p_verify.c | 55 + - .../OpensslLib/openssl/crypto/evp/pmeth_fn.c | 297 + - .../OpensslLib/openssl/crypto/evp/pmeth_gn.c | 169 + - .../OpensslLib/openssl/crypto/evp/pmeth_lib.c | 721 ++ - .../Library/OpensslLib/openssl/crypto/evp/scrypt.c | 248 + - .../Library/OpensslLib/openssl/crypto/ex_data.c | 384 + - .../OpensslLib/openssl/crypto/hmac/build.info | 3 + - .../OpensslLib/openssl/crypto/hmac/hm_ameth.c | 125 + - .../OpensslLib/openssl/crypto/hmac/hm_pmeth.c | 210 + - .../Library/OpensslLib/openssl/crypto/hmac/hmac.c | 240 + - .../OpensslLib/openssl/crypto/hmac/hmac_lcl.h | 33 + - .../Library/OpensslLib/openssl/crypto/ia64cpuid.S | 297 + - .../OpensslLib/openssl/crypto/idea/build.info | 3 + - .../Library/OpensslLib/openssl/crypto/idea/i_cbc.c | 122 + - .../OpensslLib/openssl/crypto/idea/i_cfb64.c | 74 + - .../Library/OpensslLib/openssl/crypto/idea/i_ecb.c | 34 + - .../OpensslLib/openssl/crypto/idea/i_ofb64.c | 61 + - .../OpensslLib/openssl/crypto/idea/i_skey.c | 112 + - .../OpensslLib/openssl/crypto/idea/idea_lcl.h | 103 + - .../openssl/crypto/include/internal/asn1_int.h | 94 + - .../openssl/crypto/include/internal/async.h | 14 + - .../openssl/crypto/include/internal/bn_conf.h.in | 27 + - .../openssl/crypto/include/internal/bn_dh.h | 17 + - .../openssl/crypto/include/internal/bn_int.h | 82 + - .../openssl/crypto/include/internal/bn_srp.h | 9 + - .../openssl/crypto/include/internal/chacha.h | 49 + - .../openssl/crypto/include/internal/cryptlib.h | 81 + - .../openssl/crypto/include/internal/cryptlib_int.h | 31 + - .../openssl/crypto/include/internal/dso_conf.h.in | 15 + - .../openssl/crypto/include/internal/engine.h | 20 + - .../openssl/crypto/include/internal/err_int.h | 17 + - .../openssl/crypto/include/internal/evp_int.h | 389 + - .../openssl/crypto/include/internal/md32_common.h | 383 + - .../openssl/crypto/include/internal/objects.h | 12 + - .../openssl/crypto/include/internal/poly1305.h | 19 + - .../openssl/crypto/include/internal/rand.h | 20 + - .../openssl/crypto/include/internal/x509_int.h | 267 + - CryptoPkg/Library/OpensslLib/openssl/crypto/init.c | 664 + - .../OpensslLib/openssl/crypto/kdf/build.info | 3 + - .../Library/OpensslLib/openssl/crypto/kdf/hkdf.c | 293 + - .../OpensslLib/openssl/crypto/kdf/kdf_err.c | 46 + - .../OpensslLib/openssl/crypto/kdf/tls1_prf.c | 265 + - .../OpensslLib/openssl/crypto/lhash/build.info | 3 + - .../OpensslLib/openssl/crypto/lhash/lh_stats.c | 118 + - .../OpensslLib/openssl/crypto/lhash/lhash.c | 349 + - .../OpensslLib/openssl/crypto/lhash/lhash_lcl.h | 42 + - .../Library/OpensslLib/openssl/crypto/lhash/num.pl | 23 + - .../OpensslLib/openssl/crypto/md2/build.info | 3 + - .../OpensslLib/openssl/crypto/md2/md2_dgst.c | 173 + - .../OpensslLib/openssl/crypto/md2/md2_one.c | 47 + - .../OpensslLib/openssl/crypto/md4/build.info | 3 + - .../OpensslLib/openssl/crypto/md4/md4_dgst.c | 147 + - .../OpensslLib/openssl/crypto/md4/md4_locl.h | 60 + - .../OpensslLib/openssl/crypto/md4/md4_one.c | 47 + - .../OpensslLib/openssl/crypto/md5/asm/md5-586.pl | 318 + - .../OpensslLib/openssl/crypto/md5/asm/md5-ia64.S | 1002 ++ - .../openssl/crypto/md5/asm/md5-sparcv9.pl | 437 + - .../openssl/crypto/md5/asm/md5-x86_64.pl | 380 + - .../OpensslLib/openssl/crypto/md5/build.info | 22 + - .../OpensslLib/openssl/crypto/md5/md5_dgst.c | 164 + - .../OpensslLib/openssl/crypto/md5/md5_locl.h | 80 + - .../OpensslLib/openssl/crypto/md5/md5_one.c | 47 + - .../OpensslLib/openssl/crypto/mdc2/build.info | 3 + - .../OpensslLib/openssl/crypto/mdc2/mdc2_one.c | 27 + - .../OpensslLib/openssl/crypto/mdc2/mdc2dgst.c | 147 + - CryptoPkg/Library/OpensslLib/openssl/crypto/mem.c | 190 + - .../Library/OpensslLib/openssl/crypto/mem_clr.c | 25 + - .../Library/OpensslLib/openssl/crypto/mem_dbg.c | 629 + - .../Library/OpensslLib/openssl/crypto/mem_sec.c | 585 + - .../openssl/crypto/modes/asm/aesni-gcm-x86_64.pl | 1106 ++ - .../openssl/crypto/modes/asm/ghash-alpha.pl | 467 + - .../openssl/crypto/modes/asm/ghash-armv4.pl | 554 + - .../openssl/crypto/modes/asm/ghash-c64xplus.pl | 247 + - .../openssl/crypto/modes/asm/ghash-ia64.pl | 470 + - .../openssl/crypto/modes/asm/ghash-parisc.pl | 738 ++ - .../openssl/crypto/modes/asm/ghash-s390x.pl | 267 + - .../openssl/crypto/modes/asm/ghash-sparcv9.pl | 581 + - .../openssl/crypto/modes/asm/ghash-x86.pl | 1405 +++ - .../openssl/crypto/modes/asm/ghash-x86_64.pl | 1762 +++ - .../openssl/crypto/modes/asm/ghashp8-ppc.pl | 670 + - .../openssl/crypto/modes/asm/ghashv8-armx.pl | 430 + - .../OpensslLib/openssl/crypto/modes/build.info | 27 + - .../OpensslLib/openssl/crypto/modes/cbc128.c | 155 + - .../OpensslLib/openssl/crypto/modes/ccm128.c | 432 + - .../OpensslLib/openssl/crypto/modes/cfb128.c | 198 + - .../OpensslLib/openssl/crypto/modes/ctr128.c | 209 + - .../OpensslLib/openssl/crypto/modes/cts128.c | 523 + - .../OpensslLib/openssl/crypto/modes/gcm128.c | 2302 ++++ - .../OpensslLib/openssl/crypto/modes/modes_lcl.h | 185 + - .../OpensslLib/openssl/crypto/modes/ocb128.c | 568 + - .../OpensslLib/openssl/crypto/modes/ofb128.c | 74 + - .../OpensslLib/openssl/crypto/modes/wrap128.c | 329 + - .../OpensslLib/openssl/crypto/modes/xts128.c | 157 + - .../Library/OpensslLib/openssl/crypto/o_dir.c | 36 + - .../Library/OpensslLib/openssl/crypto/o_fips.c | 34 + - .../Library/OpensslLib/openssl/crypto/o_fopen.c | 103 + - .../Library/OpensslLib/openssl/crypto/o_init.c | 34 + - .../Library/OpensslLib/openssl/crypto/o_str.c | 250 + - .../Library/OpensslLib/openssl/crypto/o_time.c | 360 + - .../OpensslLib/openssl/crypto/objects/README | 44 + - .../OpensslLib/openssl/crypto/objects/build.info | 3 + - .../OpensslLib/openssl/crypto/objects/o_names.c | 370 + - .../OpensslLib/openssl/crypto/objects/obj_dat.c | 728 ++ - .../OpensslLib/openssl/crypto/objects/obj_dat.h | 5101 ++++++++ - .../OpensslLib/openssl/crypto/objects/obj_dat.pl | 227 + - .../OpensslLib/openssl/crypto/objects/obj_err.c | 50 + - .../OpensslLib/openssl/crypto/objects/obj_lcl.h | 14 + - .../OpensslLib/openssl/crypto/objects/obj_lib.c | 66 + - .../OpensslLib/openssl/crypto/objects/obj_mac.num | 1060 ++ - .../OpensslLib/openssl/crypto/objects/obj_xref.c | 165 + - .../OpensslLib/openssl/crypto/objects/obj_xref.h | 118 + - .../OpensslLib/openssl/crypto/objects/obj_xref.txt | 60 + - .../OpensslLib/openssl/crypto/objects/objects.pl | 193 + - .../OpensslLib/openssl/crypto/objects/objects.txt | 1485 +++ - .../OpensslLib/openssl/crypto/objects/objxref.pl | 135 + - .../OpensslLib/openssl/crypto/ocsp/build.info | 4 + - .../OpensslLib/openssl/crypto/ocsp/ocsp_asn.c | 135 + - .../OpensslLib/openssl/crypto/ocsp/ocsp_cl.c | 365 + - .../OpensslLib/openssl/crypto/ocsp/ocsp_err.c | 91 + - .../OpensslLib/openssl/crypto/ocsp/ocsp_ext.c | 472 + - .../OpensslLib/openssl/crypto/ocsp/ocsp_ht.c | 499 + - .../OpensslLib/openssl/crypto/ocsp/ocsp_lcl.h | 216 + - .../OpensslLib/openssl/crypto/ocsp/ocsp_lib.c | 222 + - .../OpensslLib/openssl/crypto/ocsp/ocsp_prn.c | 246 + - .../OpensslLib/openssl/crypto/ocsp/ocsp_srv.c | 277 + - .../OpensslLib/openssl/crypto/ocsp/ocsp_vfy.c | 424 + - .../OpensslLib/openssl/crypto/ocsp/v3_ocsp.c | 264 + - .../Library/OpensslLib/openssl/crypto/pariscid.pl | 263 + - .../OpensslLib/openssl/crypto/pem/build.info | 4 + - .../OpensslLib/openssl/crypto/pem/pem_all.c | 181 + - .../OpensslLib/openssl/crypto/pem/pem_err.c | 115 + - .../OpensslLib/openssl/crypto/pem/pem_info.c | 334 + - .../OpensslLib/openssl/crypto/pem/pem_lib.c | 857 ++ - .../OpensslLib/openssl/crypto/pem/pem_oth.c | 36 + - .../OpensslLib/openssl/crypto/pem/pem_pk8.c | 213 + - .../OpensslLib/openssl/crypto/pem/pem_pkey.c | 243 + - .../OpensslLib/openssl/crypto/pem/pem_sign.c | 50 + - .../OpensslLib/openssl/crypto/pem/pem_x509.c | 18 + - .../OpensslLib/openssl/crypto/pem/pem_xaux.c | 18 + - .../Library/OpensslLib/openssl/crypto/pem/pvkfmt.c | 869 ++ - .../OpensslLib/openssl/crypto/perlasm/README | 124 + - .../OpensslLib/openssl/crypto/perlasm/arm-xlate.pl | 177 + - .../OpensslLib/openssl/crypto/perlasm/cbc.pl | 356 + - .../OpensslLib/openssl/crypto/perlasm/ppc-xlate.pl | 265 + - .../openssl/crypto/perlasm/sparcv9_modes.pl | 1702 +++ - .../openssl/crypto/perlasm/x86_64-xlate.pl | 1185 ++ - .../OpensslLib/openssl/crypto/perlasm/x86asm.pl | 310 + - .../OpensslLib/openssl/crypto/perlasm/x86gas.pl | 265 + - .../OpensslLib/openssl/crypto/perlasm/x86masm.pl | 207 + - .../OpensslLib/openssl/crypto/perlasm/x86nasm.pl | 186 + - .../OpensslLib/openssl/crypto/pkcs12/build.info | 5 + - .../OpensslLib/openssl/crypto/pkcs12/p12_add.c | 164 + - .../OpensslLib/openssl/crypto/pkcs12/p12_asn.c | 76 + - .../OpensslLib/openssl/crypto/pkcs12/p12_attr.c | 103 + - .../OpensslLib/openssl/crypto/pkcs12/p12_crpt.c | 70 + - .../OpensslLib/openssl/crypto/pkcs12/p12_crt.c | 291 + - .../OpensslLib/openssl/crypto/pkcs12/p12_decr.c | 155 + - .../OpensslLib/openssl/crypto/pkcs12/p12_init.c | 43 + - .../OpensslLib/openssl/crypto/pkcs12/p12_key.c | 205 + - .../OpensslLib/openssl/crypto/pkcs12/p12_kiss.c | 245 + - .../OpensslLib/openssl/crypto/pkcs12/p12_lcl.h | 43 + - .../OpensslLib/openssl/crypto/pkcs12/p12_mutl.c | 239 + - .../OpensslLib/openssl/crypto/pkcs12/p12_npas.c | 184 + - .../OpensslLib/openssl/crypto/pkcs12/p12_p8d.c | 23 + - .../OpensslLib/openssl/crypto/pkcs12/p12_p8e.c | 69 + - .../OpensslLib/openssl/crypto/pkcs12/p12_sbag.c | 170 + - .../OpensslLib/openssl/crypto/pkcs12/p12_utl.c | 237 + - .../OpensslLib/openssl/crypto/pkcs12/pk12err.c | 95 + - .../OpensslLib/openssl/crypto/pkcs7/bio_pk7.c | 24 + - .../OpensslLib/openssl/crypto/pkcs7/build.info | 4 + - .../OpensslLib/openssl/crypto/pkcs7/pk7_asn1.c | 201 + - .../OpensslLib/openssl/crypto/pkcs7/pk7_attr.c | 121 + - .../OpensslLib/openssl/crypto/pkcs7/pk7_dgst.c | 15 + - .../OpensslLib/openssl/crypto/pkcs7/pk7_doit.c | 1178 ++ - .../OpensslLib/openssl/crypto/pkcs7/pk7_enc.c | 25 + - .../OpensslLib/openssl/crypto/pkcs7/pk7_lib.c | 589 + - .../OpensslLib/openssl/crypto/pkcs7/pk7_mime.c | 49 + - .../OpensslLib/openssl/crypto/pkcs7/pk7_smime.c | 549 + - .../OpensslLib/openssl/crypto/pkcs7/pkcs7err.c | 131 + - .../openssl/crypto/poly1305/asm/poly1305-armv4.pl | 1252 ++ - .../openssl/crypto/poly1305/asm/poly1305-armv8.pl | 939 ++ - .../crypto/poly1305/asm/poly1305-c64xplus.pl | 331 + - .../openssl/crypto/poly1305/asm/poly1305-mips.pl | 425 + - .../openssl/crypto/poly1305/asm/poly1305-ppc.pl | 644 + - .../openssl/crypto/poly1305/asm/poly1305-ppcfp.pl | 739 ++ - .../openssl/crypto/poly1305/asm/poly1305-s390x.pl | 227 + - .../crypto/poly1305/asm/poly1305-sparcv9.pl | 1120 ++ - .../openssl/crypto/poly1305/asm/poly1305-x86.pl | 1814 +++ - .../openssl/crypto/poly1305/asm/poly1305-x86_64.pl | 2268 ++++ - .../OpensslLib/openssl/crypto/poly1305/build.info | 20 + - .../OpensslLib/openssl/crypto/poly1305/poly1305.c | 1037 ++ - .../openssl/crypto/poly1305/poly1305_ieee754.c | 472 + - .../Library/OpensslLib/openssl/crypto/ppc_arch.h | 26 + - .../Library/OpensslLib/openssl/crypto/ppccap.c | 317 + - .../Library/OpensslLib/openssl/crypto/ppccpuid.pl | 301 + - .../OpensslLib/openssl/crypto/rand/build.info | 4 + - .../OpensslLib/openssl/crypto/rand/md_rand.c | 666 + - .../OpensslLib/openssl/crypto/rand/rand_egd.c | 249 + - .../OpensslLib/openssl/crypto/rand/rand_err.c | 43 + - .../OpensslLib/openssl/crypto/rand/rand_lcl.h | 46 + - .../OpensslLib/openssl/crypto/rand/rand_lib.c | 126 + - .../OpensslLib/openssl/crypto/rand/rand_unix.c | 324 + - .../OpensslLib/openssl/crypto/rand/rand_vms.c | 133 + - .../OpensslLib/openssl/crypto/rand/rand_win.c | 135 + - .../OpensslLib/openssl/crypto/rand/randfile.c | 366 + - .../OpensslLib/openssl/crypto/rc2/build.info | 3 + - .../OpensslLib/openssl/crypto/rc2/rc2_cbc.c | 179 + - .../OpensslLib/openssl/crypto/rc2/rc2_ecb.c | 41 + - .../OpensslLib/openssl/crypto/rc2/rc2_locl.h | 106 + - .../OpensslLib/openssl/crypto/rc2/rc2_skey.c | 98 + - .../OpensslLib/openssl/crypto/rc2/rc2cfb64.c | 74 + - .../OpensslLib/openssl/crypto/rc2/rc2ofb64.c | 61 + - .../Library/OpensslLib/openssl/crypto/rc2/tab.c | 93 + - .../OpensslLib/openssl/crypto/rc4/asm/rc4-586.pl | 428 + - .../openssl/crypto/rc4/asm/rc4-c64xplus.pl | 190 + - .../OpensslLib/openssl/crypto/rc4/asm/rc4-ia64.pl | 767 ++ - .../openssl/crypto/rc4/asm/rc4-md5-x86_64.pl | 645 + - .../openssl/crypto/rc4/asm/rc4-parisc.pl | 321 + - .../OpensslLib/openssl/crypto/rc4/asm/rc4-s390x.pl | 241 + - .../openssl/crypto/rc4/asm/rc4-x86_64.pl | 687 + - .../OpensslLib/openssl/crypto/rc4/build.info | 33 + - .../OpensslLib/openssl/crypto/rc4/rc4_enc.c | 86 + - .../OpensslLib/openssl/crypto/rc4/rc4_locl.h | 16 + - .../OpensslLib/openssl/crypto/rc4/rc4_skey.c | 58 + - .../OpensslLib/openssl/crypto/rc5/asm/rc5-586.pl | 122 + - .../OpensslLib/openssl/crypto/rc5/build.info | 6 + - .../OpensslLib/openssl/crypto/rc5/rc5_ecb.c | 32 + - .../OpensslLib/openssl/crypto/rc5/rc5_enc.c | 160 + - .../OpensslLib/openssl/crypto/rc5/rc5_locl.h | 158 + - .../OpensslLib/openssl/crypto/rc5/rc5_skey.c | 61 + - .../OpensslLib/openssl/crypto/rc5/rc5cfb64.c | 74 + - .../OpensslLib/openssl/crypto/rc5/rc5ofb64.c | 61 + - .../openssl/crypto/ripemd/asm/rmd-586.pl | 603 + - .../OpensslLib/openssl/crypto/ripemd/build.info | 6 + - .../OpensslLib/openssl/crypto/ripemd/rmd_dgst.c | 282 + - .../OpensslLib/openssl/crypto/ripemd/rmd_locl.h | 88 + - .../OpensslLib/openssl/crypto/ripemd/rmd_one.c | 28 + - .../OpensslLib/openssl/crypto/ripemd/rmdconst.h | 350 + - .../OpensslLib/openssl/crypto/rsa/build.info | 6 + - .../OpensslLib/openssl/crypto/rsa/rsa_ameth.c | 866 ++ - .../OpensslLib/openssl/crypto/rsa/rsa_asn1.c | 81 + - .../OpensslLib/openssl/crypto/rsa/rsa_chk.c | 156 + - .../OpensslLib/openssl/crypto/rsa/rsa_crpt.c | 178 + - .../OpensslLib/openssl/crypto/rsa/rsa_depr.c | 61 + - .../OpensslLib/openssl/crypto/rsa/rsa_err.c | 185 + - .../OpensslLib/openssl/crypto/rsa/rsa_gen.c | 199 + - .../OpensslLib/openssl/crypto/rsa/rsa_lib.c | 310 + - .../OpensslLib/openssl/crypto/rsa/rsa_locl.h | 96 + - .../OpensslLib/openssl/crypto/rsa/rsa_meth.c | 273 + - .../OpensslLib/openssl/crypto/rsa/rsa_none.c | 43 + - .../OpensslLib/openssl/crypto/rsa/rsa_null.c | 93 + - .../OpensslLib/openssl/crypto/rsa/rsa_oaep.c | 286 + - .../OpensslLib/openssl/crypto/rsa/rsa_ossl.c | 790 ++ - .../OpensslLib/openssl/crypto/rsa/rsa_pk1.c | 245 + - .../OpensslLib/openssl/crypto/rsa/rsa_pmeth.c | 673 + - .../OpensslLib/openssl/crypto/rsa/rsa_prn.c | 42 + - .../OpensslLib/openssl/crypto/rsa/rsa_pss.c | 244 + - .../OpensslLib/openssl/crypto/rsa/rsa_saos.c | 94 + - .../OpensslLib/openssl/crypto/rsa/rsa_sign.c | 248 + - .../OpensslLib/openssl/crypto/rsa/rsa_ssl.c | 100 + - .../OpensslLib/openssl/crypto/rsa/rsa_x931.c | 116 + - .../OpensslLib/openssl/crypto/rsa/rsa_x931g.c | 195 + - .../Library/OpensslLib/openssl/crypto/s390xcap.c | 50 + - .../Library/OpensslLib/openssl/crypto/s390xcpuid.S | 180 + - .../OpensslLib/openssl/crypto/seed/build.info | 2 + - .../Library/OpensslLib/openssl/crypto/seed/seed.c | 590 + - .../OpensslLib/openssl/crypto/seed/seed_cbc.c | 23 + - .../OpensslLib/openssl/crypto/seed/seed_cfb.c | 20 + - .../OpensslLib/openssl/crypto/seed/seed_ecb.c | 19 + - .../OpensslLib/openssl/crypto/seed/seed_locl.h | 120 + - .../OpensslLib/openssl/crypto/seed/seed_ofb.c | 19 + - .../OpensslLib/openssl/crypto/sha/asm/sha1-586.pl | 1488 +++ - .../openssl/crypto/sha/asm/sha1-alpha.pl | 329 + - .../openssl/crypto/sha/asm/sha1-armv4-large.pl | 742 ++ - .../openssl/crypto/sha/asm/sha1-armv8.pl | 363 + - .../openssl/crypto/sha/asm/sha1-c64xplus.pl | 337 + - .../OpensslLib/openssl/crypto/sha/asm/sha1-ia64.pl | 314 + - .../openssl/crypto/sha/asm/sha1-mb-x86_64.pl | 1582 +++ - .../OpensslLib/openssl/crypto/sha/asm/sha1-mips.pl | 457 + - .../openssl/crypto/sha/asm/sha1-parisc.pl | 267 + - .../OpensslLib/openssl/crypto/sha/asm/sha1-ppc.pl | 351 + - .../openssl/crypto/sha/asm/sha1-s390x.pl | 251 + - .../openssl/crypto/sha/asm/sha1-sparcv9.pl | 434 + - .../openssl/crypto/sha/asm/sha1-sparcv9a.pl | 608 + - .../openssl/crypto/sha/asm/sha1-thumb.pl | 266 + - .../openssl/crypto/sha/asm/sha1-x86_64.pl | 2077 ++++ - .../openssl/crypto/sha/asm/sha256-586.pl | 1293 ++ - .../openssl/crypto/sha/asm/sha256-armv4.pl | 732 ++ - .../openssl/crypto/sha/asm/sha256-c64xplus.pl | 320 + - .../openssl/crypto/sha/asm/sha256-mb-x86_64.pl | 1568 +++ - .../openssl/crypto/sha/asm/sha512-586.pl | 924 ++ - .../openssl/crypto/sha/asm/sha512-armv4.pl | 668 + - .../openssl/crypto/sha/asm/sha512-armv8.pl | 446 + - .../openssl/crypto/sha/asm/sha512-c64xplus.pl | 438 + - .../openssl/crypto/sha/asm/sha512-ia64.pl | 692 ++ - .../openssl/crypto/sha/asm/sha512-mips.pl | 519 + - .../openssl/crypto/sha/asm/sha512-parisc.pl | 800 ++ - .../openssl/crypto/sha/asm/sha512-ppc.pl | 799 ++ - .../openssl/crypto/sha/asm/sha512-s390x.pl | 326 + - .../openssl/crypto/sha/asm/sha512-sparcv9.pl | 857 ++ - .../openssl/crypto/sha/asm/sha512-x86_64.pl | 2407 ++++ - .../openssl/crypto/sha/asm/sha512p8-ppc.pl | 431 + - .../OpensslLib/openssl/crypto/sha/build.info | 69 + - .../OpensslLib/openssl/crypto/sha/sha1_one.c | 28 + - .../OpensslLib/openssl/crypto/sha/sha1dgst.c | 17 + - .../Library/OpensslLib/openssl/crypto/sha/sha256.c | 386 + - .../Library/OpensslLib/openssl/crypto/sha/sha512.c | 678 + - .../OpensslLib/openssl/crypto/sha/sha_locl.h | 424 + - .../Library/OpensslLib/openssl/crypto/sparc_arch.h | 118 + - .../Library/OpensslLib/openssl/crypto/sparccpuid.S | 582 + - .../Library/OpensslLib/openssl/crypto/sparcv9cap.c | 294 + - .../OpensslLib/openssl/crypto/srp/build.info | 2 + - .../OpensslLib/openssl/crypto/srp/srp_lib.c | 0 - .../OpensslLib/openssl/crypto/srp/srp_vfy.c | 0 - .../OpensslLib/openssl/crypto/stack/build.info | 2 + - .../OpensslLib/openssl/crypto/stack/stack.c | 312 + - .../OpensslLib/openssl/crypto/threads_none.c | 124 + - .../OpensslLib/openssl/crypto/threads_pthread.c | 171 + - .../OpensslLib/openssl/crypto/threads_win.c | 136 + - .../OpensslLib/openssl/crypto/ts/build.info | 5 + - .../Library/OpensslLib/openssl/crypto/ts/ts_asn1.c | 259 + - .../Library/OpensslLib/openssl/crypto/ts/ts_conf.c | 468 + - .../Library/OpensslLib/openssl/crypto/ts/ts_err.c | 144 + - .../Library/OpensslLib/openssl/crypto/ts/ts_lcl.h | 183 + - .../Library/OpensslLib/openssl/crypto/ts/ts_lib.c | 93 + - .../OpensslLib/openssl/crypto/ts/ts_req_print.c | 51 + - .../OpensslLib/openssl/crypto/ts/ts_req_utils.c | 183 + - .../OpensslLib/openssl/crypto/ts/ts_rsp_print.c | 195 + - .../OpensslLib/openssl/crypto/ts/ts_rsp_sign.c | 904 ++ - .../OpensslLib/openssl/crypto/ts/ts_rsp_utils.c | 365 + - .../OpensslLib/openssl/crypto/ts/ts_rsp_verify.c | 635 + - .../OpensslLib/openssl/crypto/ts/ts_verify_ctx.c | 146 + - .../OpensslLib/openssl/crypto/txt_db/build.info | 2 + - .../OpensslLib/openssl/crypto/txt_db/txt_db.c | 301 + - .../OpensslLib/openssl/crypto/ui/build.info | 3 + - .../Library/OpensslLib/openssl/crypto/ui/ui_err.c | 72 + - .../Library/OpensslLib/openssl/crypto/ui/ui_lib.c | 826 ++ - .../Library/OpensslLib/openssl/crypto/ui/ui_locl.h | 97 + - .../OpensslLib/openssl/crypto/ui/ui_openssl.c | 700 ++ - .../Library/OpensslLib/openssl/crypto/ui/ui_util.c | 51 + - CryptoPkg/Library/OpensslLib/openssl/crypto/uid.c | 42 + - .../Library/OpensslLib/openssl/crypto/vms_rms.h | 58 + - .../openssl/crypto/whrlpool/asm/wp-mmx.pl | 507 + - .../openssl/crypto/whrlpool/asm/wp-x86_64.pl | 600 + - .../OpensslLib/openssl/crypto/whrlpool/build.info | 7 + - .../OpensslLib/openssl/crypto/whrlpool/wp_block.c | 792 ++ - .../OpensslLib/openssl/crypto/whrlpool/wp_dgst.c | 266 + - .../OpensslLib/openssl/crypto/whrlpool/wp_locl.h | 12 + - .../OpensslLib/openssl/crypto/x509/build.info | 10 + - .../OpensslLib/openssl/crypto/x509/by_dir.c | 388 + - .../OpensslLib/openssl/crypto/x509/by_file.c | 221 + - .../Library/OpensslLib/openssl/crypto/x509/t_crl.c | 89 + - .../Library/OpensslLib/openssl/crypto/x509/t_req.c | 198 + - .../OpensslLib/openssl/crypto/x509/t_x509.c | 376 + - .../OpensslLib/openssl/crypto/x509/x509_att.c | 329 + - .../OpensslLib/openssl/crypto/x509/x509_cmp.c | 459 + - .../OpensslLib/openssl/crypto/x509/x509_d2.c | 57 + - .../OpensslLib/openssl/crypto/x509/x509_def.c | 43 + - .../OpensslLib/openssl/crypto/x509/x509_err.c | 142 + - .../OpensslLib/openssl/crypto/x509/x509_ext.c | 160 + - .../OpensslLib/openssl/crypto/x509/x509_lcl.h | 142 + - .../OpensslLib/openssl/crypto/x509/x509_lu.c | 861 ++ - .../OpensslLib/openssl/crypto/x509/x509_obj.c | 182 + - .../OpensslLib/openssl/crypto/x509/x509_r2x.c | 67 + - .../OpensslLib/openssl/crypto/x509/x509_req.c | 298 + - .../OpensslLib/openssl/crypto/x509/x509_set.c | 159 + - .../OpensslLib/openssl/crypto/x509/x509_trs.c | 298 + - .../OpensslLib/openssl/crypto/x509/x509_txt.c | 177 + - .../OpensslLib/openssl/crypto/x509/x509_v3.c | 234 + - .../OpensslLib/openssl/crypto/x509/x509_vfy.c | 3275 +++++ - .../OpensslLib/openssl/crypto/x509/x509_vpm.c | 617 + - .../OpensslLib/openssl/crypto/x509/x509cset.c | 182 + - .../OpensslLib/openssl/crypto/x509/x509name.c | 358 + - .../OpensslLib/openssl/crypto/x509/x509rset.c | 40 + - .../OpensslLib/openssl/crypto/x509/x509spki.c | 75 + - .../OpensslLib/openssl/crypto/x509/x509type.c | 77 + - .../Library/OpensslLib/openssl/crypto/x509/x_all.c | 526 + - .../OpensslLib/openssl/crypto/x509/x_attrib.c | 55 + - .../Library/OpensslLib/openssl/crypto/x509/x_crl.c | 459 + - .../OpensslLib/openssl/crypto/x509/x_exten.c | 28 + - .../OpensslLib/openssl/crypto/x509/x_name.c | 557 + - .../OpensslLib/openssl/crypto/x509/x_pubkey.c | 374 + - .../Library/OpensslLib/openssl/crypto/x509/x_req.c | 68 + - .../OpensslLib/openssl/crypto/x509/x_x509.c | 224 + - .../OpensslLib/openssl/crypto/x509/x_x509a.c | 169 + - .../OpensslLib/openssl/crypto/x509v3/build.info | 8 + - .../OpensslLib/openssl/crypto/x509v3/ext_dat.h | 24 + - .../OpensslLib/openssl/crypto/x509v3/pcy_cache.c | 216 + - .../OpensslLib/openssl/crypto/x509v3/pcy_data.c | 77 + - .../OpensslLib/openssl/crypto/x509v3/pcy_int.h | 167 + - .../OpensslLib/openssl/crypto/x509v3/pcy_lib.c | 108 + - .../OpensslLib/openssl/crypto/x509v3/pcy_map.c | 81 + - .../OpensslLib/openssl/crypto/x509v3/pcy_node.c | 139 + - .../OpensslLib/openssl/crypto/x509v3/pcy_tree.c | 696 ++ - .../OpensslLib/openssl/crypto/x509v3/tabtest.c | 42 + - .../OpensslLib/openssl/crypto/x509v3/v3_addr.c | 1305 ++ - .../OpensslLib/openssl/crypto/x509v3/v3_akey.c | 160 + - .../OpensslLib/openssl/crypto/x509v3/v3_akeya.c | 23 + - .../OpensslLib/openssl/crypto/x509v3/v3_alt.c | 566 + - .../OpensslLib/openssl/crypto/x509v3/v3_asid.c | 852 ++ - .../OpensslLib/openssl/crypto/x509v3/v3_bcons.c | 84 + - .../OpensslLib/openssl/crypto/x509v3/v3_bitst.c | 93 + - .../OpensslLib/openssl/crypto/x509v3/v3_conf.c | 507 + - .../OpensslLib/openssl/crypto/x509v3/v3_cpols.c | 441 + - .../OpensslLib/openssl/crypto/x509v3/v3_crld.c | 509 + - .../OpensslLib/openssl/crypto/x509v3/v3_enum.c | 53 + - .../OpensslLib/openssl/crypto/x509v3/v3_extku.c | 100 + - .../OpensslLib/openssl/crypto/x509v3/v3_genn.c | 200 + - .../OpensslLib/openssl/crypto/x509v3/v3_ia5.c | 65 + - .../OpensslLib/openssl/crypto/x509v3/v3_info.c | 157 + - .../OpensslLib/openssl/crypto/x509v3/v3_int.c | 43 + - .../OpensslLib/openssl/crypto/x509v3/v3_lib.c | 360 + - .../OpensslLib/openssl/crypto/x509v3/v3_ncons.c | 513 + - .../OpensslLib/openssl/crypto/x509v3/v3_pci.c | 321 + - .../OpensslLib/openssl/crypto/x509v3/v3_pcia.c | 60 + - .../OpensslLib/openssl/crypto/x509v3/v3_pcons.c | 91 + - .../OpensslLib/openssl/crypto/x509v3/v3_pku.c | 65 + - .../OpensslLib/openssl/crypto/x509v3/v3_pmaps.c | 110 + - .../OpensslLib/openssl/crypto/x509v3/v3_prn.c | 210 + - .../OpensslLib/openssl/crypto/x509v3/v3_purp.c | 865 ++ - .../OpensslLib/openssl/crypto/x509v3/v3_skey.c | 106 + - .../OpensslLib/openssl/crypto/x509v3/v3_sxnet.c | 226 + - .../OpensslLib/openssl/crypto/x509v3/v3_tlsf.c | 137 + - .../OpensslLib/openssl/crypto/x509v3/v3_utl.c | 1195 ++ - .../OpensslLib/openssl/crypto/x509v3/v3conf.c | 79 + - .../OpensslLib/openssl/crypto/x509v3/v3err.c | 187 + - .../OpensslLib/openssl/crypto/x509v3/v3prin.c | 50 + - .../OpensslLib/openssl/crypto/x86_64cpuid.pl | 459 + - .../Library/OpensslLib/openssl/crypto/x86cpuid.pl | 561 + - CryptoPkg/Library/OpensslLib/openssl/demos/README | 9 + - .../Library/OpensslLib/openssl/demos/bio/Makefile | 30 + - .../Library/OpensslLib/openssl/demos/bio/README | 7 + - .../OpensslLib/openssl/demos/bio/accept.cnf | 17 + - .../OpensslLib/openssl/demos/bio/client-arg.c | 117 + - .../OpensslLib/openssl/demos/bio/client-conf.c | 126 + - .../Library/OpensslLib/openssl/demos/bio/cmod.cnf | 24 + - .../OpensslLib/openssl/demos/bio/connect.cnf | 9 + - .../OpensslLib/openssl/demos/bio/descrip.mms | 47 + - .../Library/OpensslLib/openssl/demos/bio/intca.pem | 23 + - .../Library/OpensslLib/openssl/demos/bio/root.pem | 22 + - .../Library/OpensslLib/openssl/demos/bio/saccept.c | 122 + - .../OpensslLib/openssl/demos/bio/sconnect.c | 131 + - .../OpensslLib/openssl/demos/bio/server-arg.c | 145 + - .../OpensslLib/openssl/demos/bio/server-cmod.c | 95 + - .../OpensslLib/openssl/demos/bio/server-conf.c | 140 + - .../OpensslLib/openssl/demos/bio/server-ec.pem | 17 + - .../OpensslLib/openssl/demos/bio/server.pem | 77 + - .../OpensslLib/openssl/demos/bio/shared.opt | 2 + - .../OpensslLib/openssl/demos/bio/static.opt | 2 + - .../Library/OpensslLib/openssl/demos/certs/README | 21 + - .../OpensslLib/openssl/demos/certs/apps/apps.cnf | 69 + - .../OpensslLib/openssl/demos/certs/apps/ckey.pem | 27 + - .../OpensslLib/openssl/demos/certs/apps/intkey.pem | 27 + - .../openssl/demos/certs/apps/mkacerts.sh | 45 + - .../openssl/demos/certs/apps/mkxcerts.sh | 29 + - .../openssl/demos/certs/apps/rootkey.pem | 27 + - .../OpensslLib/openssl/demos/certs/apps/skey.pem | 27 + - .../OpensslLib/openssl/demos/certs/apps/skey2.pem | 27 + - .../Library/OpensslLib/openssl/demos/certs/ca.cnf | 86 + - .../OpensslLib/openssl/demos/certs/mkcerts.sh | 96 + - .../OpensslLib/openssl/demos/certs/ocspquery.sh | 21 + - .../OpensslLib/openssl/demos/certs/ocsprun.sh | 14 + - .../OpensslLib/openssl/demos/cms/cacert.pem | 18 + - .../Library/OpensslLib/openssl/demos/cms/cakey.pem | 15 + - .../OpensslLib/openssl/demos/cms/cms_comp.c | 64 + - .../OpensslLib/openssl/demos/cms/cms_ddec.c | 88 + - .../Library/OpensslLib/openssl/demos/cms/cms_dec.c | 78 + - .../OpensslLib/openssl/demos/cms/cms_denc.c | 97 + - .../Library/OpensslLib/openssl/demos/cms/cms_enc.c | 92 + - .../OpensslLib/openssl/demos/cms/cms_sign.c | 88 + - .../OpensslLib/openssl/demos/cms/cms_sign2.c | 98 + - .../OpensslLib/openssl/demos/cms/cms_uncomp.c | 58 + - .../Library/OpensslLib/openssl/demos/cms/cms_ver.c | 85 + - .../Library/OpensslLib/openssl/demos/cms/comp.txt | 22 + - .../Library/OpensslLib/openssl/demos/cms/encr.txt | 3 + - .../Library/OpensslLib/openssl/demos/cms/sign.txt | 3 + - .../OpensslLib/openssl/demos/cms/signer.pem | 32 + - .../OpensslLib/openssl/demos/cms/signer2.pem | 32 + - .../Library/OpensslLib/openssl/demos/evp/aesccm.c | 125 + - .../Library/OpensslLib/openssl/demos/evp/aesgcm.c | 120 + - .../Library/OpensslLib/openssl/demos/pkcs12/README | 3 + - .../OpensslLib/openssl/demos/pkcs12/pkread.c | 68 + - .../OpensslLib/openssl/demos/pkcs12/pkwrite.c | 53 + - .../OpensslLib/openssl/demos/smime/cacert.pem | 18 + - .../OpensslLib/openssl/demos/smime/cakey.pem | 15 + - .../OpensslLib/openssl/demos/smime/encr.txt | 3 + - .../OpensslLib/openssl/demos/smime/sign.txt | 3 + - .../OpensslLib/openssl/demos/smime/signer.pem | 32 + - .../OpensslLib/openssl/demos/smime/signer2.pem | 32 + - .../Library/OpensslLib/openssl/demos/smime/smdec.c | 78 + - .../Library/OpensslLib/openssl/demos/smime/smenc.c | 91 + - .../OpensslLib/openssl/demos/smime/smsign.c | 88 + - .../OpensslLib/openssl/demos/smime/smsign2.c | 96 + - .../Library/OpensslLib/openssl/demos/smime/smver.c | 83 + - .../openssl/doc/CT_POLICY_EVAL_CTX_new.pod | 111 + - .../OpensslLib/openssl/doc/HOWTO/certificates.txt | 110 + - .../Library/OpensslLib/openssl/doc/HOWTO/keys.txt | 72 + - .../openssl/doc/HOWTO/proxy_certificates.txt | 319 + - CryptoPkg/Library/OpensslLib/openssl/doc/README | 20 + - .../OpensslLib/openssl/doc/SCT_validate.pod | 98 + - .../doc/SSL_CTX_set_ct_validation_callback.pod | 142 + - .../Library/OpensslLib/openssl/doc/apps/CA.pl.pod | 214 + - .../OpensslLib/openssl/doc/apps/asn1parse.pod | 208 + - .../Library/OpensslLib/openssl/doc/apps/ca.pod | 719 ++ - .../OpensslLib/openssl/doc/apps/ciphers.pod | 735 ++ - .../Library/OpensslLib/openssl/doc/apps/cms.pod | 737 ++ - .../Library/OpensslLib/openssl/doc/apps/config.pod | 386 + - .../Library/OpensslLib/openssl/doc/apps/crl.pod | 142 + - .../OpensslLib/openssl/doc/apps/crl2pkcs7.pod | 105 + - .../Library/OpensslLib/openssl/doc/apps/dgst.pod | 240 + - .../OpensslLib/openssl/doc/apps/dhparam.pod | 159 + - .../Library/OpensslLib/openssl/doc/apps/dsa.pod | 178 + - .../OpensslLib/openssl/doc/apps/dsaparam.pod | 124 + - .../Library/OpensslLib/openssl/doc/apps/ec.pod | 206 + - .../OpensslLib/openssl/doc/apps/ecparam.pod | 185 + - .../Library/OpensslLib/openssl/doc/apps/enc.pod | 353 + - .../Library/OpensslLib/openssl/doc/apps/engine.pod | 104 + - .../Library/OpensslLib/openssl/doc/apps/errstr.pod | 45 + - .../Library/OpensslLib/openssl/doc/apps/gendsa.pod | 91 + - .../OpensslLib/openssl/doc/apps/genpkey.pod | 277 + - .../Library/OpensslLib/openssl/doc/apps/genrsa.pod | 115 + - .../Library/OpensslLib/openssl/doc/apps/list.pod | 81 + - .../Library/OpensslLib/openssl/doc/apps/nseq.pod | 84 + - .../Library/OpensslLib/openssl/doc/apps/ocsp.pod | 466 + - .../OpensslLib/openssl/doc/apps/openssl.pod | 451 + - .../Library/OpensslLib/openssl/doc/apps/passwd.pod | 96 + - .../Library/OpensslLib/openssl/doc/apps/pkcs12.pod | 378 + - .../Library/OpensslLib/openssl/doc/apps/pkcs7.pod | 119 + - .../Library/OpensslLib/openssl/doc/apps/pkcs8.pod | 301 + - .../Library/OpensslLib/openssl/doc/apps/pkey.pod | 155 + - .../OpensslLib/openssl/doc/apps/pkeyparam.pod | 82 + - .../OpensslLib/openssl/doc/apps/pkeyutl.pod | 292 + - .../Library/OpensslLib/openssl/doc/apps/rand.pod | 69 + - .../Library/OpensslLib/openssl/doc/apps/rehash.pod | 139 + - .../Library/OpensslLib/openssl/doc/apps/req.pod | 658 + - .../Library/OpensslLib/openssl/doc/apps/rsa.pod | 216 + - .../Library/OpensslLib/openssl/doc/apps/rsautl.pod | 204 + - .../OpensslLib/openssl/doc/apps/s_client.pod | 603 + - .../OpensslLib/openssl/doc/apps/s_server.pod | 606 + - .../Library/OpensslLib/openssl/doc/apps/s_time.pod | 194 + - .../OpensslLib/openssl/doc/apps/sess_id.pod | 163 + - .../Library/OpensslLib/openssl/doc/apps/smime.pod | 515 + - .../Library/OpensslLib/openssl/doc/apps/speed.pod | 67 + - .../Library/OpensslLib/openssl/doc/apps/spkac.pod | 147 + - .../Library/OpensslLib/openssl/doc/apps/ts.pod | 650 + - .../Library/OpensslLib/openssl/doc/apps/tsget.pod | 199 + - .../Library/OpensslLib/openssl/doc/apps/verify.pod | 724 ++ - .../OpensslLib/openssl/doc/apps/version.pod | 80 + - .../Library/OpensslLib/openssl/doc/apps/x509.pod | 905 ++ - .../OpensslLib/openssl/doc/apps/x509v3_config.pod | 541 + - .../openssl/doc/crypto/ASN1_INTEGER_get_int64.pod | 132 + - .../openssl/doc/crypto/ASN1_OBJECT_new.pod | 51 + - .../openssl/doc/crypto/ASN1_STRING_length.pod | 93 + - .../openssl/doc/crypto/ASN1_STRING_new.pod | 52 + - .../openssl/doc/crypto/ASN1_STRING_print_ex.pod | 101 + - .../openssl/doc/crypto/ASN1_TIME_set.pod | 138 + - .../openssl/doc/crypto/ASN1_TYPE_get.pod | 100 + - .../openssl/doc/crypto/ASN1_generate_nconf.pod | 270 + - .../openssl/doc/crypto/ASYNC_WAIT_CTX_new.pod | 144 + - .../openssl/doc/crypto/ASYNC_start_job.pod | 330 + - .../OpensslLib/openssl/doc/crypto/BF_encrypt.pod | 117 + - .../OpensslLib/openssl/doc/crypto/BIO_ADDR.pod | 125 + - .../OpensslLib/openssl/doc/crypto/BIO_ADDRINFO.pod | 90 + - .../OpensslLib/openssl/doc/crypto/BIO_connect.pod | 112 + - .../OpensslLib/openssl/doc/crypto/BIO_ctrl.pod | 136 + - .../OpensslLib/openssl/doc/crypto/BIO_f_base64.pod | 91 + - .../OpensslLib/openssl/doc/crypto/BIO_f_buffer.pod | 92 + - .../OpensslLib/openssl/doc/crypto/BIO_f_cipher.pod | 81 + - .../OpensslLib/openssl/doc/crypto/BIO_f_md.pod | 156 + - .../OpensslLib/openssl/doc/crypto/BIO_f_null.pod | 39 + - .../OpensslLib/openssl/doc/crypto/BIO_f_ssl.pod | 298 + - .../openssl/doc/crypto/BIO_find_type.pod | 69 + - .../OpensslLib/openssl/doc/crypto/BIO_get_data.pod | 65 + - .../openssl/doc/crypto/BIO_get_ex_new_index.pod | 64 + - .../OpensslLib/openssl/doc/crypto/BIO_meth_new.pod | 131 + - .../OpensslLib/openssl/doc/crypto/BIO_new.pod | 72 + - .../OpensslLib/openssl/doc/crypto/BIO_new_CMS.pod | 75 + - .../openssl/doc/crypto/BIO_parse_hostserv.pod | 73 + - .../OpensslLib/openssl/doc/crypto/BIO_push.pod | 89 + - .../OpensslLib/openssl/doc/crypto/BIO_read.pod | 77 + - .../OpensslLib/openssl/doc/crypto/BIO_s_accept.pod | 222 + - .../OpensslLib/openssl/doc/crypto/BIO_s_bio.pod | 201 + - .../openssl/doc/crypto/BIO_s_connect.pod | 200 + - .../OpensslLib/openssl/doc/crypto/BIO_s_fd.pod | 98 + - .../OpensslLib/openssl/doc/crypto/BIO_s_file.pod | 159 + - .../OpensslLib/openssl/doc/crypto/BIO_s_mem.pod | 124 + - .../OpensslLib/openssl/doc/crypto/BIO_s_null.pod | 44 + - .../OpensslLib/openssl/doc/crypto/BIO_s_socket.pod | 54 + - .../openssl/doc/crypto/BIO_set_callback.pod | 221 + - .../openssl/doc/crypto/BIO_should_retry.pod | 132 + - .../openssl/doc/crypto/BN_BLINDING_new.pod | 126 + - .../OpensslLib/openssl/doc/crypto/BN_CTX_new.pod | 76 + - .../OpensslLib/openssl/doc/crypto/BN_CTX_start.pod | 57 + - .../OpensslLib/openssl/doc/crypto/BN_add.pod | 127 + - .../OpensslLib/openssl/doc/crypto/BN_add_word.pod | 61 + - .../OpensslLib/openssl/doc/crypto/BN_bn2bin.pod | 116 + - .../OpensslLib/openssl/doc/crypto/BN_cmp.pod | 51 + - .../OpensslLib/openssl/doc/crypto/BN_copy.pod | 69 + - .../openssl/doc/crypto/BN_generate_prime.pod | 194 + - .../openssl/doc/crypto/BN_mod_inverse.pod | 41 + - .../openssl/doc/crypto/BN_mod_mul_montgomery.pod | 90 + - .../openssl/doc/crypto/BN_mod_mul_reciprocal.pod | 76 + - .../OpensslLib/openssl/doc/crypto/BN_new.pod | 62 + - .../OpensslLib/openssl/doc/crypto/BN_num_bytes.pod | 61 + - .../OpensslLib/openssl/doc/crypto/BN_rand.pod | 68 + - .../OpensslLib/openssl/doc/crypto/BN_set_bit.pod | 69 + - .../OpensslLib/openssl/doc/crypto/BN_swap.pod | 28 + - .../OpensslLib/openssl/doc/crypto/BN_zero.pod | 67 + - .../OpensslLib/openssl/doc/crypto/BUF_MEM_new.pod | 77 + - .../openssl/doc/crypto/CMS_add0_cert.pod | 70 + - .../openssl/doc/crypto/CMS_add1_recipient_cert.pod | 66 + - .../openssl/doc/crypto/CMS_add1_signer.pod | 106 + - .../OpensslLib/openssl/doc/crypto/CMS_compress.pod | 81 + - .../OpensslLib/openssl/doc/crypto/CMS_decrypt.pod | 81 + - .../OpensslLib/openssl/doc/crypto/CMS_encrypt.pod | 104 + - .../OpensslLib/openssl/doc/crypto/CMS_final.pod | 46 + - .../openssl/doc/crypto/CMS_get0_RecipientInfos.pod | 130 + - .../openssl/doc/crypto/CMS_get0_SignerInfos.pod | 89 + - .../openssl/doc/crypto/CMS_get0_type.pod | 81 + - .../openssl/doc/crypto/CMS_get1_ReceiptRequest.pod | 72 + - .../OpensslLib/openssl/doc/crypto/CMS_sign.pod | 128 + - .../openssl/doc/crypto/CMS_sign_receipt.pod | 50 + - .../openssl/doc/crypto/CMS_uncompress.pod | 59 + - .../OpensslLib/openssl/doc/crypto/CMS_verify.pod | 131 + - .../openssl/doc/crypto/CMS_verify_receipt.pod | 52 + - .../openssl/doc/crypto/CONF_modules_free.pod | 62 + - .../openssl/doc/crypto/CONF_modules_load_file.pod | 136 + - .../openssl/doc/crypto/CRYPTO_THREAD_run_once.pod | 163 + - .../openssl/doc/crypto/CRYPTO_get_ex_new_index.pod | 161 + - .../doc/crypto/CTLOG_STORE_get0_log_by_id.pod | 49 + - .../openssl/doc/crypto/CTLOG_STORE_new.pod | 79 + - .../OpensslLib/openssl/doc/crypto/CTLOG_new.pod | 72 + - .../openssl/doc/crypto/CT_POLICY_EVAL_CTX_new.pod | 96 + - .../openssl/doc/crypto/DEFINE_STACK_OF.pod | 233 + - .../openssl/doc/crypto/DES_random_key.pod | 310 + - .../openssl/doc/crypto/DH_generate_key.pod | 54 + - .../openssl/doc/crypto/DH_generate_parameters.pod | 134 + - .../OpensslLib/openssl/doc/crypto/DH_get0_pqg.pod | 112 + - .../openssl/doc/crypto/DH_get_1024_160.pod | 74 + - .../OpensslLib/openssl/doc/crypto/DH_meth_new.pod | 156 + - .../OpensslLib/openssl/doc/crypto/DH_new.pod | 46 + - .../openssl/doc/crypto/DH_set_method.pod | 85 + - .../OpensslLib/openssl/doc/crypto/DH_size.pod | 47 + - .../OpensslLib/openssl/doc/crypto/DSA_SIG_new.pod | 58 + - .../OpensslLib/openssl/doc/crypto/DSA_do_sign.pod | 52 + - .../OpensslLib/openssl/doc/crypto/DSA_dup_DH.pod | 41 + - .../openssl/doc/crypto/DSA_generate_key.pod | 39 + - .../openssl/doc/crypto/DSA_generate_parameters.pod | 122 + - .../OpensslLib/openssl/doc/crypto/DSA_get0_pqg.pod | 102 + - .../OpensslLib/openssl/doc/crypto/DSA_meth_new.pod | 193 + - .../OpensslLib/openssl/doc/crypto/DSA_new.pod | 48 + - .../openssl/doc/crypto/DSA_set_method.pod | 85 + - .../OpensslLib/openssl/doc/crypto/DSA_sign.pod | 70 + - .../OpensslLib/openssl/doc/crypto/DSA_size.pod | 44 + - .../openssl/doc/crypto/ECDSA_SIG_new.pod | 207 + - .../openssl/doc/crypto/ECPKParameters_print.pod | 44 + - .../openssl/doc/crypto/EC_GFp_simple_method.pod | 69 + - .../openssl/doc/crypto/EC_GROUP_copy.pod | 206 + - .../OpensslLib/openssl/doc/crypto/EC_GROUP_new.pod | 120 + - .../openssl/doc/crypto/EC_KEY_get_enc_flags.pod | 59 + - .../OpensslLib/openssl/doc/crypto/EC_KEY_new.pod | 183 + - .../OpensslLib/openssl/doc/crypto/EC_POINT_add.pod | 80 + - .../OpensslLib/openssl/doc/crypto/EC_POINT_new.pod | 196 + - .../OpensslLib/openssl/doc/crypto/ENGINE_add.pod | 611 + - .../OpensslLib/openssl/doc/crypto/ERR_GET_LIB.pod | 66 + - .../openssl/doc/crypto/ERR_clear_error.pod | 34 + - .../openssl/doc/crypto/ERR_error_string.pod | 74 + - .../openssl/doc/crypto/ERR_get_error.pod | 79 + - .../openssl/doc/crypto/ERR_load_crypto_strings.pod | 62 + - .../openssl/doc/crypto/ERR_load_strings.pod | 58 + - .../openssl/doc/crypto/ERR_print_errors.pod | 60 + - .../openssl/doc/crypto/ERR_put_error.pod | 76 + - .../openssl/doc/crypto/ERR_remove_state.pod | 53 + - .../OpensslLib/openssl/doc/crypto/ERR_set_mark.pod | 43 + - .../openssl/doc/crypto/EVP_BytesToKey.pod | 78 + - .../doc/crypto/EVP_CIPHER_CTX_get_cipher_data.pod | 51 + - .../openssl/doc/crypto/EVP_CIPHER_meth_new.pod | 238 + - .../openssl/doc/crypto/EVP_DigestInit.pod | 259 + - .../openssl/doc/crypto/EVP_DigestSignInit.pod | 96 + - .../openssl/doc/crypto/EVP_DigestVerifyInit.pod | 91 + - .../openssl/doc/crypto/EVP_EncodeInit.pod | 162 + - .../openssl/doc/crypto/EVP_EncryptInit.pod | 662 + - .../openssl/doc/crypto/EVP_MD_meth_new.pod | 170 + - .../OpensslLib/openssl/doc/crypto/EVP_OpenInit.pod | 70 + - .../openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod | 154 + - .../openssl/doc/crypto/EVP_PKEY_CTX_new.pod | 62 + - .../doc/crypto/EVP_PKEY_CTX_set_hkdf_md.pod | 128 + - .../doc/crypto/EVP_PKEY_CTX_set_tls1_prf_md.pod | 108 + - .../OpensslLib/openssl/doc/crypto/EVP_PKEY_cmp.pod | 73 + - .../openssl/doc/crypto/EVP_PKEY_decrypt.pod | 102 + - .../openssl/doc/crypto/EVP_PKEY_derive.pod | 102 + - .../openssl/doc/crypto/EVP_PKEY_encrypt.pod | 108 + - .../doc/crypto/EVP_PKEY_get_default_digest_nid.pod | 50 + - .../openssl/doc/crypto/EVP_PKEY_keygen.pod | 175 + - .../OpensslLib/openssl/doc/crypto/EVP_PKEY_new.pod | 61 + - .../openssl/doc/crypto/EVP_PKEY_print_private.pod | 62 + - .../openssl/doc/crypto/EVP_PKEY_set1_RSA.pod | 120 + - .../openssl/doc/crypto/EVP_PKEY_sign.pod | 115 + - .../openssl/doc/crypto/EVP_PKEY_verify.pod | 100 + - .../openssl/doc/crypto/EVP_PKEY_verify_recover.pod | 112 + - .../OpensslLib/openssl/doc/crypto/EVP_SealInit.pod | 90 + - .../OpensslLib/openssl/doc/crypto/EVP_SignInit.pod | 110 + - .../openssl/doc/crypto/EVP_VerifyInit.pod | 99 + - .../Library/OpensslLib/openssl/doc/crypto/HMAC.pod | 151 + - .../Library/OpensslLib/openssl/doc/crypto/MD5.pod | 101 + - .../OpensslLib/openssl/doc/crypto/MDC2_Init.pod | 68 + - .../OpensslLib/openssl/doc/crypto/OBJ_nid2obj.pod | 198 + - .../openssl/doc/crypto/OCSP_REQUEST_new.pod | 118 + - .../openssl/doc/crypto/OCSP_cert_to_id.pod | 89 + - .../openssl/doc/crypto/OCSP_request_add1_nonce.pod | 84 + - .../openssl/doc/crypto/OCSP_resp_find_status.pod | 139 + - .../openssl/doc/crypto/OCSP_response_status.pod | 100 + - .../openssl/doc/crypto/OCSP_sendreq_new.pod | 122 + - .../openssl/doc/crypto/OPENSSL_Applink.pod | 31 + - .../openssl/doc/crypto/OPENSSL_LH_COMPFUNC.pod | 239 + - .../openssl/doc/crypto/OPENSSL_LH_stats.pod | 64 + - .../openssl/doc/crypto/OPENSSL_VERSION_NUMBER.pod | 106 + - .../openssl/doc/crypto/OPENSSL_config.pod | 74 + - .../openssl/doc/crypto/OPENSSL_ia32cap.pod | 140 + - .../openssl/doc/crypto/OPENSSL_init_crypto.pod | 245 + - .../openssl/doc/crypto/OPENSSL_instrument_bus.pod | 53 + - .../doc/crypto/OPENSSL_load_builtin_modules.pod | 56 + - .../openssl/doc/crypto/OPENSSL_malloc.pod | 207 + - .../openssl/doc/crypto/OPENSSL_secure_malloc.pod | 123 + - .../doc/crypto/OpenSSL_add_all_algorithms.pod | 90 + - .../OpensslLib/openssl/doc/crypto/PEM_read.pod | 127 + - .../OpensslLib/openssl/doc/crypto/PEM_read_CMS.pod | 97 + - .../openssl/doc/crypto/PEM_read_bio_PrivateKey.pod | 481 + - .../doc/crypto/PEM_write_bio_CMS_stream.pod | 50 + - .../doc/crypto/PEM_write_bio_PKCS7_stream.pod | 49 + - .../openssl/doc/crypto/PKCS12_create.pod | 76 + - .../openssl/doc/crypto/PKCS12_newpass.pod | 103 + - .../OpensslLib/openssl/doc/crypto/PKCS12_parse.pod | 62 + - .../openssl/doc/crypto/PKCS5_PBKDF2_HMAC.pod | 73 + - .../openssl/doc/crypto/PKCS7_decrypt.pod | 57 + - .../openssl/doc/crypto/PKCS7_encrypt.pod | 88 + - .../OpensslLib/openssl/doc/crypto/PKCS7_sign.pod | 124 + - .../openssl/doc/crypto/PKCS7_sign_add_signer.pod | 96 + - .../OpensslLib/openssl/doc/crypto/PKCS7_verify.pod | 128 + - .../OpensslLib/openssl/doc/crypto/RAND_add.pod | 79 + - .../OpensslLib/openssl/doc/crypto/RAND_bytes.pod | 58 + - .../OpensslLib/openssl/doc/crypto/RAND_cleanup.pod | 42 + - .../OpensslLib/openssl/doc/crypto/RAND_egd.pod | 87 + - .../openssl/doc/crypto/RAND_load_file.pod | 79 + - .../openssl/doc/crypto/RAND_set_rand_method.pod | 81 + - .../OpensslLib/openssl/doc/crypto/RC4_set_key.pod | 66 + - .../openssl/doc/crypto/RIPEMD160_Init.pod | 72 + - .../openssl/doc/crypto/RSA_blinding_on.pod | 44 + - .../openssl/doc/crypto/RSA_check_key.pod | 84 + - .../openssl/doc/crypto/RSA_generate_key.pod | 88 + - .../OpensslLib/openssl/doc/crypto/RSA_get0_key.pod | 108 + - .../OpensslLib/openssl/doc/crypto/RSA_meth_new.pod | 235 + - .../OpensslLib/openssl/doc/crypto/RSA_new.pod | 47 + - .../doc/crypto/RSA_padding_add_PKCS1_type_1.pod | 122 + - .../OpensslLib/openssl/doc/crypto/RSA_print.pod | 52 + - .../openssl/doc/crypto/RSA_private_encrypt.pod | 74 + - .../openssl/doc/crypto/RSA_public_encrypt.pod | 88 + - .../openssl/doc/crypto/RSA_set_method.pod | 180 + - .../OpensslLib/openssl/doc/crypto/RSA_sign.pod | 65 + - .../doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod | 63 + - .../OpensslLib/openssl/doc/crypto/RSA_size.pod | 46 + - .../OpensslLib/openssl/doc/crypto/SCT_new.pod | 194 + - .../OpensslLib/openssl/doc/crypto/SCT_print.pod | 52 + - .../OpensslLib/openssl/doc/crypto/SCT_validate.pod | 96 + - .../OpensslLib/openssl/doc/crypto/SHA256_Init.pod | 108 + - .../openssl/doc/crypto/SMIME_read_CMS.pod | 75 + - .../openssl/doc/crypto/SMIME_read_PKCS7.pod | 78 + - .../openssl/doc/crypto/SMIME_write_CMS.pod | 69 + - .../openssl/doc/crypto/SMIME_write_PKCS7.pod | 70 + - .../OpensslLib/openssl/doc/crypto/SSL_set_bio.pod | 108 + - .../OpensslLib/openssl/doc/crypto/UI_new.pod | 186 + - .../openssl/doc/crypto/X509V3_get_d2i.pod | 241 + - .../openssl/doc/crypto/X509_ALGOR_dup.pod | 48 + - .../openssl/doc/crypto/X509_CRL_get0_by_serial.pod | 112 + - .../doc/crypto/X509_EXTENSION_set_object.pod | 96 + - .../openssl/doc/crypto/X509_LOOKUP_hash_dir.pod | 131 + - .../doc/crypto/X509_NAME_ENTRY_get_object.pod | 77 + - .../doc/crypto/X509_NAME_add_entry_by_txt.pod | 123 + - .../openssl/doc/crypto/X509_NAME_get0_der.pod | 40 + - .../doc/crypto/X509_NAME_get_index_by_NID.pod | 123 + - .../openssl/doc/crypto/X509_NAME_print_ex.pod | 112 + - .../openssl/doc/crypto/X509_PUBKEY_new.pod | 120 + - .../openssl/doc/crypto/X509_SIG_get0.pod | 36 + - .../doc/crypto/X509_STORE_CTX_get_error.pod | 338 + - .../openssl/doc/crypto/X509_STORE_CTX_new.pod | 174 + - .../doc/crypto/X509_STORE_CTX_set_verify_cb.pod | 215 + - .../openssl/doc/crypto/X509_STORE_get0_param.pod | 57 + - .../openssl/doc/crypto/X509_STORE_new.pod | 58 + - .../doc/crypto/X509_STORE_set_verify_cb_func.pod | 267 + - .../doc/crypto/X509_VERIFY_PARAM_set_flags.pod | 342 + - .../openssl/doc/crypto/X509_check_ca.pod | 45 + - .../openssl/doc/crypto/X509_check_host.pod | 157 + - .../openssl/doc/crypto/X509_check_issued.pod | 45 + - .../OpensslLib/openssl/doc/crypto/X509_digest.pod | 65 + - .../OpensslLib/openssl/doc/crypto/X509_dup.pod | 303 + - .../openssl/doc/crypto/X509_get0_signature.pod | 97 + - .../openssl/doc/crypto/X509_get0_uids.pod | 57 + - .../doc/crypto/X509_get_extension_flags.pod | 175 + - .../openssl/doc/crypto/X509_get_notBefore.pod | 103 + - .../openssl/doc/crypto/X509_get_pubkey.pod | 87 + - .../openssl/doc/crypto/X509_get_serialNumber.pod | 71 + - .../openssl/doc/crypto/X509_get_subject_name.pod | 86 + - .../openssl/doc/crypto/X509_get_version.pod | 83 + - .../OpensslLib/openssl/doc/crypto/X509_new.pod | 83 + - .../OpensslLib/openssl/doc/crypto/X509_sign.pod | 99 + - .../openssl/doc/crypto/X509_verify_cert.pod | 60 + - .../openssl/doc/crypto/X509v3_get_ext_by_NID.pod | 140 + - .../Library/OpensslLib/openssl/doc/crypto/bio.pod | 90 + - .../OpensslLib/openssl/doc/crypto/crypto.pod | 62 + - .../Library/OpensslLib/openssl/doc/crypto/ct.pod | 55 + - .../OpensslLib/openssl/doc/crypto/d2i_DHparams.pod | 35 + - .../openssl/doc/crypto/d2i_Netscape_RSA.pod | 38 + - .../openssl/doc/crypto/d2i_PKCS8PrivateKey_bio.pod | 61 + - .../openssl/doc/crypto/d2i_PrivateKey.pod | 71 + - .../OpensslLib/openssl/doc/crypto/d2i_X509.pod | 598 + - .../OpensslLib/openssl/doc/crypto/des_modes.pod | 263 + - .../Library/OpensslLib/openssl/doc/crypto/evp.pod | 116 + - .../openssl/doc/crypto/i2d_CMS_bio_stream.pod | 53 + - .../openssl/doc/crypto/i2d_PKCS7_bio_stream.pod | 53 + - .../openssl/doc/crypto/i2d_re_X509_tbs.pod | 79 + - .../OpensslLib/openssl/doc/crypto/o2i_SCT_LIST.pod | 48 + - .../Library/OpensslLib/openssl/doc/crypto/x509.pod | 75 + - .../OpensslLib/openssl/doc/dir-locals.example.el | 15 + - .../OpensslLib/openssl/doc/fingerprints.txt | 27 + - .../OpensslLib/openssl/doc/openssl-c-indent.el | 62 + - .../OpensslLib/openssl/doc/ssl/DTLSv1_listen.pod | 102 + - .../openssl/doc/ssl/OPENSSL_init_ssl.pod | 84 + - .../openssl/doc/ssl/SSL_CIPHER_get_name.pod | 128 + - .../doc/ssl/SSL_COMP_add_compression_method.pod | 116 + - .../openssl/doc/ssl/SSL_CONF_CTX_new.pod | 50 + - .../openssl/doc/ssl/SSL_CONF_CTX_set1_prefix.pod | 58 + - .../openssl/doc/ssl/SSL_CONF_CTX_set_flags.pod | 84 + - .../openssl/doc/ssl/SSL_CONF_CTX_set_ssl_ctx.pod | 56 + - .../OpensslLib/openssl/doc/ssl/SSL_CONF_cmd.pod | 553 + - .../openssl/doc/ssl/SSL_CONF_cmd_argv.pod | 51 + - .../openssl/doc/ssl/SSL_CTX_add1_chain_cert.pod | 158 + - .../doc/ssl/SSL_CTX_add_extra_chain_cert.pod | 80 + - .../openssl/doc/ssl/SSL_CTX_add_session.pod | 82 + - .../OpensslLib/openssl/doc/ssl/SSL_CTX_config.pod | 93 + - .../OpensslLib/openssl/doc/ssl/SSL_CTX_ctrl.pod | 43 + - .../openssl/doc/ssl/SSL_CTX_dane_enable.pod | 382 + - .../openssl/doc/ssl/SSL_CTX_flush_sessions.pod | 56 + - .../OpensslLib/openssl/doc/ssl/SSL_CTX_free.pod | 51 + - .../openssl/doc/ssl/SSL_CTX_get0_param.pod | 64 + - .../openssl/doc/ssl/SSL_CTX_get_verify_mode.pod | 59 + - .../doc/ssl/SSL_CTX_has_client_custom_ext.pod | 37 + - .../doc/ssl/SSL_CTX_load_verify_locations.pod | 161 + - .../OpensslLib/openssl/doc/ssl/SSL_CTX_new.pod | 218 + - .../openssl/doc/ssl/SSL_CTX_sess_number.pod | 85 + - .../doc/ssl/SSL_CTX_sess_set_cache_size.pod | 62 + - .../openssl/doc/ssl/SSL_CTX_sess_set_get_cb.pod | 96 + - .../openssl/doc/ssl/SSL_CTX_sessions.pod | 43 + - .../openssl/doc/ssl/SSL_CTX_set1_curves.pod | 90 + - .../openssl/doc/ssl/SSL_CTX_set1_sigalgs.pod | 113 + - .../doc/ssl/SSL_CTX_set1_verify_cert_store.pod | 100 + - .../openssl/doc/ssl/SSL_CTX_set_alpn_select_cb.pod | 136 + - .../openssl/doc/ssl/SSL_CTX_set_cert_cb.pod | 77 + - .../openssl/doc/ssl/SSL_CTX_set_cert_store.pod | 73 + - .../doc/ssl/SSL_CTX_set_cert_verify_callback.pod | 74 + - .../openssl/doc/ssl/SSL_CTX_set_cipher_list.pod | 74 + - .../openssl/doc/ssl/SSL_CTX_set_client_CA_list.pod | 103 + - .../openssl/doc/ssl/SSL_CTX_set_client_cert_cb.pod | 103 + - .../doc/ssl/SSL_CTX_set_ct_validation_callback.pod | 138 + - .../doc/ssl/SSL_CTX_set_ctlog_list_file.pod | 53 + - .../doc/ssl/SSL_CTX_set_default_passwd_cb.pod | 113 + - .../doc/ssl/SSL_CTX_set_generate_session_id.pod | 139 + - .../openssl/doc/ssl/SSL_CTX_set_info_callback.pod | 162 + - .../openssl/doc/ssl/SSL_CTX_set_max_cert_list.pod | 82 + - .../doc/ssl/SSL_CTX_set_min_proto_version.pod | 60 + - .../openssl/doc/ssl/SSL_CTX_set_mode.pod | 114 + - .../openssl/doc/ssl/SSL_CTX_set_msg_callback.pod | 103 + - .../openssl/doc/ssl/SSL_CTX_set_options.pod | 292 + - .../doc/ssl/SSL_CTX_set_psk_client_callback.pod | 63 + - .../openssl/doc/ssl/SSL_CTX_set_quiet_shutdown.pod | 72 + - .../openssl/doc/ssl/SSL_CTX_set_read_ahead.pod | 60 + - .../openssl/doc/ssl/SSL_CTX_set_security_level.pod | 169 + - .../doc/ssl/SSL_CTX_set_session_cache_mode.pod | 141 + - .../doc/ssl/SSL_CTX_set_session_id_context.pod | 92 + - .../doc/ssl/SSL_CTX_set_split_send_fragment.pod | 132 + - .../openssl/doc/ssl/SSL_CTX_set_ssl_version.pod | 70 + - .../openssl/doc/ssl/SSL_CTX_set_timeout.pod | 68 + - .../doc/ssl/SSL_CTX_set_tlsext_status_cb.pod | 125 + - .../doc/ssl/SSL_CTX_set_tlsext_ticket_key_cb.pod | 198 + - .../doc/ssl/SSL_CTX_set_tmp_dh_callback.pod | 137 + - .../openssl/doc/ssl/SSL_CTX_set_verify.pod | 298 + - .../openssl/doc/ssl/SSL_CTX_use_certificate.pod | 180 + - .../doc/ssl/SSL_CTX_use_psk_identity_hint.pod | 87 + - .../openssl/doc/ssl/SSL_CTX_use_serverinfo.pod | 56 + - .../openssl/doc/ssl/SSL_SESSION_free.pod | 65 + - .../openssl/doc/ssl/SSL_SESSION_get0_cipher.pod | 42 + - .../openssl/doc/ssl/SSL_SESSION_get0_hostname.pod | 37 + - .../doc/ssl/SSL_SESSION_get0_id_context.pod | 41 + - .../doc/ssl/SSL_SESSION_get_protocol_version.pod | 44 + - .../openssl/doc/ssl/SSL_SESSION_get_time.pod | 76 + - .../openssl/doc/ssl/SSL_SESSION_has_ticket.pod | 53 + - .../openssl/doc/ssl/SSL_SESSION_set1_id.pod | 41 + - .../OpensslLib/openssl/doc/ssl/SSL_accept.pod | 82 + - .../openssl/doc/ssl/SSL_alert_type_string.pod | 242 + - .../OpensslLib/openssl/doc/ssl/SSL_check_chain.pod | 94 + - .../OpensslLib/openssl/doc/ssl/SSL_clear.pod | 84 + - .../OpensslLib/openssl/doc/ssl/SSL_connect.pod | 82 + - .../openssl/doc/ssl/SSL_do_handshake.pod | 81 + - .../openssl/doc/ssl/SSL_extension_supported.pod | 145 + - .../OpensslLib/openssl/doc/ssl/SSL_free.pod | 54 + - .../openssl/doc/ssl/SSL_get0_peer_scts.pod | 45 + - .../OpensslLib/openssl/doc/ssl/SSL_get_SSL_CTX.pod | 35 + - .../openssl/doc/ssl/SSL_get_all_async_fds.pod | 88 + - .../OpensslLib/openssl/doc/ssl/SSL_get_ciphers.pod | 84 + - .../openssl/doc/ssl/SSL_get_client_CA_list.pod | 62 + - .../openssl/doc/ssl/SSL_get_client_random.pod | 88 + - .../openssl/doc/ssl/SSL_get_current_cipher.pod | 55 + - .../openssl/doc/ssl/SSL_get_default_timeout.pod | 50 + - .../OpensslLib/openssl/doc/ssl/SSL_get_error.pod | 143 + - .../openssl/doc/ssl/SSL_get_extms_support.pod | 40 + - .../OpensslLib/openssl/doc/ssl/SSL_get_fd.pod | 53 + - .../openssl/doc/ssl/SSL_get_peer_cert_chain.pod | 77 + - .../openssl/doc/ssl/SSL_get_peer_certificate.pod | 64 + - .../openssl/doc/ssl/SSL_get_psk_identity.pod | 44 + - .../OpensslLib/openssl/doc/ssl/SSL_get_rbio.pod | 49 + - .../OpensslLib/openssl/doc/ssl/SSL_get_session.pod | 82 + - .../openssl/doc/ssl/SSL_get_shared_sigalgs.pod | 86 + - .../openssl/doc/ssl/SSL_get_verify_result.pod | 66 + - .../OpensslLib/openssl/doc/ssl/SSL_get_version.pod | 67 + - .../openssl/doc/ssl/SSL_library_init.pod | 57 + - .../openssl/doc/ssl/SSL_load_client_CA_file.pod | 71 + - .../Library/OpensslLib/openssl/doc/ssl/SSL_new.pod | 61 + - .../OpensslLib/openssl/doc/ssl/SSL_pending.pod | 68 + - .../OpensslLib/openssl/doc/ssl/SSL_read.pod | 121 + - .../openssl/doc/ssl/SSL_rstate_string.pod | 68 + - .../openssl/doc/ssl/SSL_session_reused.pod | 54 + - .../OpensslLib/openssl/doc/ssl/SSL_set1_host.pod | 121 + - .../OpensslLib/openssl/doc/ssl/SSL_set_bio.pod | 108 + - .../openssl/doc/ssl/SSL_set_connect_state.pod | 64 + - .../OpensslLib/openssl/doc/ssl/SSL_set_fd.pod | 63 + - .../OpensslLib/openssl/doc/ssl/SSL_set_session.pod | 70 + - .../openssl/doc/ssl/SSL_set_shutdown.pod | 81 + - .../openssl/doc/ssl/SSL_set_verify_result.pod | 47 + - .../OpensslLib/openssl/doc/ssl/SSL_shutdown.pod | 132 + - .../openssl/doc/ssl/SSL_state_string.pod | 54 + - .../OpensslLib/openssl/doc/ssl/SSL_want.pod | 103 + - .../OpensslLib/openssl/doc/ssl/SSL_write.pod | 111 + - .../OpensslLib/openssl/doc/ssl/d2i_SSL_SESSION.pod | 49 + - .../Library/OpensslLib/openssl/doc/ssl/ssl.pod | 833 ++ - CryptoPkg/Library/OpensslLib/openssl/e_os.h | 520 + - .../OpensslLib/openssl/engines/afalg/build.info | 13 + - .../OpensslLib/openssl/engines/afalg/e_afalg.c | 834 ++ - .../OpensslLib/openssl/engines/afalg/e_afalg.ec | 1 + - .../OpensslLib/openssl/engines/afalg/e_afalg.h | 75 + - .../OpensslLib/openssl/engines/afalg/e_afalg_err.c | 111 + - .../OpensslLib/openssl/engines/afalg/e_afalg_err.h | 60 + - .../openssl/engines/asm/e_padlock-x86.pl | 618 + - .../openssl/engines/asm/e_padlock-x86_64.pl | 574 + - .../Library/OpensslLib/openssl/engines/build.info | 32 + - .../Library/OpensslLib/openssl/engines/e_capi.c | 1916 +++ - .../Library/OpensslLib/openssl/engines/e_capi.ec | 1 + - .../OpensslLib/openssl/engines/e_capi_err.c | 143 + - .../OpensslLib/openssl/engines/e_capi_err.h | 88 + - .../Library/OpensslLib/openssl/engines/e_chil.c | 1285 ++ - .../Library/OpensslLib/openssl/engines/e_chil.ec | 1 + - .../OpensslLib/openssl/engines/e_chil_err.c | 111 + - .../OpensslLib/openssl/engines/e_chil_err.h | 64 + - .../Library/OpensslLib/openssl/engines/e_dasync.c | 769 ++ - .../Library/OpensslLib/openssl/engines/e_dasync.ec | 1 + - .../OpensslLib/openssl/engines/e_dasync_err.c | 102 + - .../OpensslLib/openssl/engines/e_dasync_err.h | 52 + - .../OpensslLib/openssl/engines/e_ossltest.c | 568 + - .../OpensslLib/openssl/engines/e_ossltest.ec | 1 + - .../OpensslLib/openssl/engines/e_ossltest_err.c | 89 + - .../OpensslLib/openssl/engines/e_ossltest_err.h | 41 + - .../Library/OpensslLib/openssl/engines/e_padlock.c | 747 ++ - .../OpensslLib/openssl/engines/e_padlock.ec | 1 + - .../OpensslLib/openssl/engines/engine_vector.mar | 24 + - .../openssl/engines/vendor_defns/hwcryptohook.h | 509 + - .../openssl/external/perl/Downloaded.txt | 13 + - .../external/perl/Text-Template-1.46/Artistic | 131 + - .../external/perl/Text-Template-1.46/COPYING | 340 + - .../external/perl/Text-Template-1.46/INSTALL | 31 + - .../external/perl/Text-Template-1.46/MANIFEST | 25 + - .../external/perl/Text-Template-1.46/META.json | 39 + - .../external/perl/Text-Template-1.46/META.yml | 21 + - .../external/perl/Text-Template-1.46/Makefile.PL | 7 + - .../external/perl/Text-Template-1.46/README | 339 + - .../perl/Text-Template-1.46/lib/Text/Template.pm | 1973 +++ - .../lib/Text/Template/Preprocess.pm | 144 + - .../perl/Text-Template-1.46/t/00-version.t | 11 + - .../external/perl/Text-Template-1.46/t/01-basic.t | 266 + - .../external/perl/Text-Template-1.46/t/02-hash.t | 111 + - .../external/perl/Text-Template-1.46/t/03-out.t | 56 + - .../external/perl/Text-Template-1.46/t/04-safe.t | 161 + - .../external/perl/Text-Template-1.46/t/05-safe2.t | 105 + - .../external/perl/Text-Template-1.46/t/06-ofh.t | 39 + - .../external/perl/Text-Template-1.46/t/07-safe3.t | 91 + - .../perl/Text-Template-1.46/t/08-exported.t | 75 + - .../external/perl/Text-Template-1.46/t/09-error.t | 63 + - .../perl/Text-Template-1.46/t/10-delimiters.t | 99 + - .../perl/Text-Template-1.46/t/11-prepend.t | 94 + - .../perl/Text-Template-1.46/t/12-preprocess.t | 52 + - .../external/perl/Text-Template-1.46/t/13-taint.t | 119 + - .../external/perl/Text-Template-1.46/t/14-broken.t | 82 + - .../external/perl/transfer/Text/Template.pm | 20 + - .../Library/OpensslLib/openssl/fuzz/README.md | 66 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/asn1.c | 222 + - .../Library/OpensslLib/openssl/fuzz/asn1parse.c | 33 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/bignum.c | 94 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/bndiv.c | 107 + - .../Library/OpensslLib/openssl/fuzz/build.info | 113 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/cms.c | 36 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/conf.c | 38 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/crl.c | 35 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/ct.c | 40 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/driver.c | 52 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/fuzzer.h | 12 + - .../Library/OpensslLib/openssl/fuzz/helper.py | 52 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/server.c | 250 + - .../Library/OpensslLib/openssl/fuzz/test-corpus.c | 46 + - CryptoPkg/Library/OpensslLib/openssl/fuzz/x509.c | 36 + - .../OpensslLib/openssl/include/internal/bio.h | 26 + - .../OpensslLib/openssl/include/internal/comp.h | 12 + - .../OpensslLib/openssl/include/internal/conf.h | 32 + - .../openssl/include/internal/constant_time_locl.h | 185 + - .../OpensslLib/openssl/include/internal/dane.h | 103 + - .../OpensslLib/openssl/include/internal/dso.h | 239 + - .../OpensslLib/openssl/include/internal/err.h | 15 + - .../OpensslLib/openssl/include/internal/numbers.h | 68 + - .../OpensslLib/openssl/include/internal/o_dir.h | 63 + - .../OpensslLib/openssl/include/internal/o_str.h | 17 + - .../openssl/include/internal/thread_once.h | 45 + - .../include/openssl/__DECC_INCLUDE_EPILOGUE.H | 16 + - .../include/openssl/__DECC_INCLUDE_PROLOGUE.H | 20 + - .../OpensslLib/openssl/include/openssl/aes.h | 92 + - .../OpensslLib/openssl/include/openssl/asn1.h | 1096 ++ - .../OpensslLib/openssl/include/openssl/asn1t.h | 924 ++ - .../OpensslLib/openssl/include/openssl/async.h | 98 + - .../OpensslLib/openssl/include/openssl/bio.h | 854 ++ - .../OpensslLib/openssl/include/openssl/blowfish.h | 61 + - .../OpensslLib/openssl/include/openssl/bn.h | 575 + - .../OpensslLib/openssl/include/openssl/buffer.h | 76 + - .../OpensslLib/openssl/include/openssl/camellia.h | 83 + - .../OpensslLib/openssl/include/openssl/cast.h | 53 + - .../OpensslLib/openssl/include/openssl/cmac.h | 41 + - .../OpensslLib/openssl/include/openssl/cms.h | 512 + - .../OpensslLib/openssl/include/openssl/comp.h | 72 + - .../OpensslLib/openssl/include/openssl/conf.h | 216 + - .../OpensslLib/openssl/include/openssl/conf_api.h | 40 + - .../OpensslLib/openssl/include/openssl/crypto.h | 463 + - .../OpensslLib/openssl/include/openssl/ct.h | 533 + - .../OpensslLib/openssl/include/openssl/des.h | 174 + - .../OpensslLib/openssl/include/openssl/dh.h | 344 + - .../OpensslLib/openssl/include/openssl/dsa.h | 283 + - .../OpensslLib/openssl/include/openssl/dtls1.h | 56 + - .../OpensslLib/openssl/include/openssl/e_os2.h | 311 + - .../OpensslLib/openssl/include/openssl/ebcdic.h | 33 + - .../OpensslLib/openssl/include/openssl/ec.h | 1581 +++ - .../OpensslLib/openssl/include/openssl/ecdh.h | 10 + - .../OpensslLib/openssl/include/openssl/ecdsa.h | 10 + - .../OpensslLib/openssl/include/openssl/engine.h | 840 ++ - .../OpensslLib/openssl/include/openssl/err.h | 259 + - .../OpensslLib/openssl/include/openssl/evp.h | 1590 +++ - .../OpensslLib/openssl/include/openssl/hmac.h | 49 + - .../OpensslLib/openssl/include/openssl/idea.h | 64 + - .../OpensslLib/openssl/include/openssl/kdf.h | 75 + - .../OpensslLib/openssl/include/openssl/lhash.h | 204 + - .../OpensslLib/openssl/include/openssl/md2.h | 44 + - .../OpensslLib/openssl/include/openssl/md4.h | 51 + - .../OpensslLib/openssl/include/openssl/md5.h | 50 + - .../OpensslLib/openssl/include/openssl/mdc2.h | 42 + - .../OpensslLib/openssl/include/openssl/modes.h | 203 + - .../OpensslLib/openssl/include/openssl/obj_mac.h | 4577 +++++++ - .../OpensslLib/openssl/include/openssl/objects.h | 1097 ++ - .../OpensslLib/openssl/include/openssl/ocsp.h | 412 + - .../openssl/include/openssl/opensslconf.h.in | 141 + - .../OpensslLib/openssl/include/openssl/opensslv.h | 105 + - .../OpensslLib/openssl/include/openssl/ossl_typ.h | 190 + - .../OpensslLib/openssl/include/openssl/pem.h | 501 + - .../OpensslLib/openssl/include/openssl/pem2.h | 20 + - .../OpensslLib/openssl/include/openssl/pkcs12.h | 282 + - .../OpensslLib/openssl/include/openssl/pkcs7.h | 404 + - .../OpensslLib/openssl/include/openssl/rand.h | 89 + - .../OpensslLib/openssl/include/openssl/rc2.h | 51 + - .../OpensslLib/openssl/include/openssl/rc4.h | 36 + - .../OpensslLib/openssl/include/openssl/rc5.h | 63 + - .../OpensslLib/openssl/include/openssl/ripemd.h | 47 + - .../OpensslLib/openssl/include/openssl/rsa.h | 590 + - .../OpensslLib/openssl/include/openssl/safestack.h | 164 + - .../OpensslLib/openssl/include/openssl/seed.h | 98 + - .../OpensslLib/openssl/include/openssl/sha.h | 119 + - .../OpensslLib/openssl/include/openssl/srp.h | 131 + - .../OpensslLib/openssl/include/openssl/srtp.h | 50 + - .../OpensslLib/openssl/include/openssl/ssl.h | 2531 ++++ - .../OpensslLib/openssl/include/openssl/ssl2.h | 24 + - .../OpensslLib/openssl/include/openssl/ssl3.h | 310 + - .../OpensslLib/openssl/include/openssl/stack.h | 78 + - .../OpensslLib/openssl/include/openssl/symhacks.h | 52 + - .../OpensslLib/openssl/include/openssl/tls1.h | 972 ++ - .../OpensslLib/openssl/include/openssl/ts.h | 643 + - .../OpensslLib/openssl/include/openssl/txt_db.h | 57 + - .../OpensslLib/openssl/include/openssl/ui.h | 378 + - .../OpensslLib/openssl/include/openssl/whrlpool.h | 48 + - .../OpensslLib/openssl/include/openssl/x509.h | 1123 ++ - .../OpensslLib/openssl/include/openssl/x509_vfy.h | 545 + - .../OpensslLib/openssl/include/openssl/x509v3.h | 1006 ++ - CryptoPkg/Library/OpensslLib/openssl/ms/applink.c | 138 + - CryptoPkg/Library/OpensslLib/openssl/ms/cmp.pl | 53 + - .../Library/OpensslLib/openssl/ms/segrenam.pl | 71 + - CryptoPkg/Library/OpensslLib/openssl/ms/tlhelp32.h | 136 + - .../Library/OpensslLib/openssl/ms/uplink-common.pl | 28 + - .../Library/OpensslLib/openssl/ms/uplink-ia64.pl | 61 + - .../Library/OpensslLib/openssl/ms/uplink-x86.pl | 44 + - .../Library/OpensslLib/openssl/ms/uplink-x86_64.pl | 71 + - CryptoPkg/Library/OpensslLib/openssl/ms/uplink.c | 135 + - CryptoPkg/Library/OpensslLib/openssl/ms/uplink.h | 38 + - .../Library/OpensslLib/openssl/os-dep/haiku.h | 2 + - CryptoPkg/Library/OpensslLib/openssl/ssl/bio_ssl.c | 528 + - .../Library/OpensslLib/openssl/ssl/build.info | 14 + - CryptoPkg/Library/OpensslLib/openssl/ssl/d1_lib.c | 1087 ++ - CryptoPkg/Library/OpensslLib/openssl/ssl/d1_msg.c | 95 + - CryptoPkg/Library/OpensslLib/openssl/ssl/d1_srtp.c | 329 + - CryptoPkg/Library/OpensslLib/openssl/ssl/methods.c | 266 + - .../Library/OpensslLib/openssl/ssl/packet_locl.h | 555 + - CryptoPkg/Library/OpensslLib/openssl/ssl/pqueue.c | 154 + - .../Library/OpensslLib/openssl/ssl/record/README | 74 + - .../OpensslLib/openssl/ssl/record/dtls1_bitmap.c | 78 + - .../OpensslLib/openssl/ssl/record/rec_layer_d1.c | 1224 ++ - .../OpensslLib/openssl/ssl/record/rec_layer_s3.c | 1527 +++ - .../Library/OpensslLib/openssl/ssl/record/record.h | 242 + - .../OpensslLib/openssl/ssl/record/record_locl.h | 116 + - .../OpensslLib/openssl/ssl/record/ssl3_buffer.c | 163 + - .../OpensslLib/openssl/ssl/record/ssl3_record.c | 1634 +++ - CryptoPkg/Library/OpensslLib/openssl/ssl/s3_cbc.c | 529 + - CryptoPkg/Library/OpensslLib/openssl/ssl/s3_enc.c | 585 + - CryptoPkg/Library/OpensslLib/openssl/ssl/s3_lib.c | 4121 ++++++ - CryptoPkg/Library/OpensslLib/openssl/ssl/s3_msg.c | 125 + - .../Library/OpensslLib/openssl/ssl/ssl_asn1.c | 367 + - .../Library/OpensslLib/openssl/ssl/ssl_cert.c | 1090 ++ - .../Library/OpensslLib/openssl/ssl/ssl_ciph.c | 1965 +++ - .../Library/OpensslLib/openssl/ssl/ssl_conf.c | 880 ++ - CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_err.c | 682 + - .../Library/OpensslLib/openssl/ssl/ssl_init.c | 210 + - CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c | 4282 +++++++ - .../Library/OpensslLib/openssl/ssl/ssl_locl.h | 2101 ++++ - .../Library/OpensslLib/openssl/ssl/ssl_mcnf.c | 199 + - CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_rsa.c | 966 ++ - .../Library/OpensslLib/openssl/ssl/ssl_sess.c | 1169 ++ - .../Library/OpensslLib/openssl/ssl/ssl_stat.c | 362 + - CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_txt.c | 217 + - .../Library/OpensslLib/openssl/ssl/ssl_utst.c | 28 + - .../Library/OpensslLib/openssl/ssl/statem/README | 63 + - .../Library/OpensslLib/openssl/ssl/statem/statem.c | 875 ++ - .../Library/OpensslLib/openssl/ssl/statem/statem.h | 123 + - .../OpensslLib/openssl/ssl/statem/statem_clnt.c | 2971 +++++ - .../OpensslLib/openssl/ssl/statem/statem_dtls.c | 1193 ++ - .../OpensslLib/openssl/ssl/statem/statem_lib.c | 1092 ++ - .../OpensslLib/openssl/ssl/statem/statem_locl.h | 124 + - .../OpensslLib/openssl/ssl/statem/statem_srvr.c | 3375 +++++ - CryptoPkg/Library/OpensslLib/openssl/ssl/t1_enc.c | 703 ++ - CryptoPkg/Library/OpensslLib/openssl/ssl/t1_ext.c | 264 + - CryptoPkg/Library/OpensslLib/openssl/ssl/t1_lib.c | 4188 +++++++ - .../Library/OpensslLib/openssl/ssl/t1_reneg.c | 165 + - CryptoPkg/Library/OpensslLib/openssl/ssl/t1_trce.c | 1341 ++ - CryptoPkg/Library/OpensslLib/openssl/ssl/tls_srp.c | 469 + - CryptoPkg/Library/OpensslLib/openssl/test/CAss.cnf | 76 + - .../Library/OpensslLib/openssl/test/CAssdh.cnf | 24 + - .../Library/OpensslLib/openssl/test/CAssdsa.cnf | 23 + - .../Library/OpensslLib/openssl/test/CAssrsa.cnf | 24 + - .../Library/OpensslLib/openssl/test/CAtsa.cnf | 163 + - CryptoPkg/Library/OpensslLib/openssl/test/P1ss.cnf | 37 + - CryptoPkg/Library/OpensslLib/openssl/test/P2ss.cnf | 45 + - CryptoPkg/Library/OpensslLib/openssl/test/README | 107 + - .../OpensslLib/openssl/test/README.ssltest.md | 274 + - .../Library/OpensslLib/openssl/test/Sssdsa.cnf | 27 + - .../Library/OpensslLib/openssl/test/Sssrsa.cnf | 26 + - CryptoPkg/Library/OpensslLib/openssl/test/Uss.cnf | 41 + - .../Library/OpensslLib/openssl/test/aborttest.c | 16 + - .../Library/OpensslLib/openssl/test/afalgtest.c | 133 + - .../Library/OpensslLib/openssl/test/asynciotest.c | 381 + - .../Library/OpensslLib/openssl/test/asynctest.c | 292 + - .../OpensslLib/openssl/test/bad_dtls_test.c | 624 + - CryptoPkg/Library/OpensslLib/openssl/test/bftest.c | 484 + - .../Library/OpensslLib/openssl/test/bio_enc_test.c | 138 + - .../Library/OpensslLib/openssl/test/bioprinttest.c | 225 + - CryptoPkg/Library/OpensslLib/openssl/test/bntest.c | 2094 ++++ - .../Library/OpensslLib/openssl/test/build.info | 317 + - .../Library/OpensslLib/openssl/test/casttest.c | 163 + - .../OpensslLib/openssl/test/certs/alt1-cert.pem | 22 + - .../OpensslLib/openssl/test/certs/alt1-key.pem | 28 + - .../OpensslLib/openssl/test/certs/alt2-cert.pem | 20 + - .../OpensslLib/openssl/test/certs/alt2-key.pem | 28 + - .../OpensslLib/openssl/test/certs/alt3-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/alt3-key.pem | 28 + - .../OpensslLib/openssl/test/certs/bad-pc3-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/bad-pc3-key.pem | 28 + - .../OpensslLib/openssl/test/certs/bad-pc4-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/bad-pc4-key.pem | 28 + - .../OpensslLib/openssl/test/certs/bad-pc6-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/bad-pc6-key.pem | 28 + - .../Library/OpensslLib/openssl/test/certs/bad.key | 27 + - .../Library/OpensslLib/openssl/test/certs/bad.pem | 21 + - .../OpensslLib/openssl/test/certs/badalt1-cert.pem | 20 + - .../OpensslLib/openssl/test/certs/badalt1-key.pem | 28 + - .../openssl/test/certs/badalt10-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/badalt10-key.pem | 28 + - .../OpensslLib/openssl/test/certs/badalt2-cert.pem | 20 + - .../OpensslLib/openssl/test/certs/badalt2-key.pem | 28 + - .../OpensslLib/openssl/test/certs/badalt3-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/badalt3-key.pem | 28 + - .../OpensslLib/openssl/test/certs/badalt4-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/badalt4-key.pem | 28 + - .../OpensslLib/openssl/test/certs/badalt5-cert.pem | 20 + - .../OpensslLib/openssl/test/certs/badalt5-key.pem | 28 + - .../OpensslLib/openssl/test/certs/badalt6-cert.pem | 22 + - .../OpensslLib/openssl/test/certs/badalt6-key.pem | 28 + - .../OpensslLib/openssl/test/certs/badalt7-cert.pem | 23 + - .../OpensslLib/openssl/test/certs/badalt7-key.pem | 28 + - .../OpensslLib/openssl/test/certs/badalt8-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/badalt8-key.pem | 28 + - .../OpensslLib/openssl/test/certs/badalt9-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/badalt9-key.pem | 28 + - .../OpensslLib/openssl/test/certs/ca+anyEKU.pem | 18 + - .../openssl/test/certs/ca+clientAuth.pem | 18 + - .../openssl/test/certs/ca+serverAuth.pem | 18 + - .../OpensslLib/openssl/test/certs/ca-anyEKU.pem | 18 + - .../OpensslLib/openssl/test/certs/ca-cert-768.pem | 15 + - .../OpensslLib/openssl/test/certs/ca-cert-768i.pem | 15 + - .../openssl/test/certs/ca-cert-md5-any.pem | 18 + - .../OpensslLib/openssl/test/certs/ca-cert-md5.pem | 18 + - .../OpensslLib/openssl/test/certs/ca-cert.pem | 18 + - .../OpensslLib/openssl/test/certs/ca-cert2.pem | 18 + - .../openssl/test/certs/ca-clientAuth.pem | 18 + - .../OpensslLib/openssl/test/certs/ca-expired.pem | 18 + - .../OpensslLib/openssl/test/certs/ca-key-768.pem | 13 + - .../OpensslLib/openssl/test/certs/ca-key.pem | 28 + - .../OpensslLib/openssl/test/certs/ca-key2.pem | 28 + - .../OpensslLib/openssl/test/certs/ca-name2.pem | 18 + - .../OpensslLib/openssl/test/certs/ca-nonbc.pem | 18 + - .../OpensslLib/openssl/test/certs/ca-nonca.pem | 19 + - .../OpensslLib/openssl/test/certs/ca-root2.pem | 18 + - .../openssl/test/certs/ca-serverAuth.pem | 18 + - .../OpensslLib/openssl/test/certs/cca+anyEKU.pem | 19 + - .../openssl/test/certs/cca+clientAuth.pem | 19 + - .../openssl/test/certs/cca+serverAuth.pem | 19 + - .../OpensslLib/openssl/test/certs/cca-anyEKU.pem | 19 + - .../OpensslLib/openssl/test/certs/cca-cert.pem | 19 + - .../openssl/test/certs/cca-clientAuth.pem | 19 + - .../openssl/test/certs/cca-serverAuth.pem | 19 + - .../OpensslLib/openssl/test/certs/croot+anyEKU.pem | 19 + - .../openssl/test/certs/croot+clientAuth.pem | 19 + - .../openssl/test/certs/croot+serverAuth.pem | 19 + - .../OpensslLib/openssl/test/certs/croot-anyEKU.pem | 19 + - .../OpensslLib/openssl/test/certs/croot-cert.pem | 19 + - .../openssl/test/certs/croot-clientAuth.pem | 19 + - .../openssl/test/certs/croot-serverAuth.pem | 19 + - .../openssl/test/certs/ee+clientAuth.pem | 20 + - .../openssl/test/certs/ee+serverAuth.pem | 20 + - .../OpensslLib/openssl/test/certs/ee-cert-768.pem | 16 + - .../OpensslLib/openssl/test/certs/ee-cert-768i.pem | 16 + - .../OpensslLib/openssl/test/certs/ee-cert-md5.pem | 19 + - .../OpensslLib/openssl/test/certs/ee-cert.pem | 19 + - .../OpensslLib/openssl/test/certs/ee-cert2.pem | 19 + - .../openssl/test/certs/ee-client-chain.pem | 37 + - .../OpensslLib/openssl/test/certs/ee-client.pem | 19 + - .../openssl/test/certs/ee-clientAuth.pem | 20 + - .../OpensslLib/openssl/test/certs/ee-expired.pem | 19 + - .../OpensslLib/openssl/test/certs/ee-key-768.pem | 13 + - .../OpensslLib/openssl/test/certs/ee-key.pem | 28 + - .../OpensslLib/openssl/test/certs/ee-name2.pem | 19 + - .../openssl/test/certs/ee-serverAuth.pem | 20 + - .../openssl/test/certs/embeddedSCTs1.pem | 20 + - .../openssl/test/certs/embeddedSCTs1.sct | 12 + - .../openssl/test/certs/embeddedSCTs1_issuer.pem | 18 + - .../openssl/test/certs/embeddedSCTs3.pem | 44 + - .../openssl/test/certs/embeddedSCTs3.sct | 36 + - .../openssl/test/certs/embeddedSCTs3_issuer.pem | 35 + - .../OpensslLib/openssl/test/certs/interCA.key | 27 + - .../OpensslLib/openssl/test/certs/interCA.pem | 21 + - .../Library/OpensslLib/openssl/test/certs/leaf.key | 27 + - .../Library/OpensslLib/openssl/test/certs/leaf.pem | 21 + - .../OpensslLib/openssl/test/certs/mkcert.sh | 254 + - .../OpensslLib/openssl/test/certs/nca+anyEKU.pem | 19 + - .../openssl/test/certs/nca+serverAuth.pem | 19 + - .../OpensslLib/openssl/test/certs/ncca-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/ncca-key.pem | 28 + - .../OpensslLib/openssl/test/certs/ncca1-cert.pem | 20 + - .../OpensslLib/openssl/test/certs/ncca1-key.pem | 28 + - .../OpensslLib/openssl/test/certs/ncca2-cert.pem | 20 + - .../OpensslLib/openssl/test/certs/ncca2-key.pem | 28 + - .../OpensslLib/openssl/test/certs/ncca3-cert.pem | 20 + - .../OpensslLib/openssl/test/certs/ncca3-key.pem | 28 + - .../OpensslLib/openssl/test/certs/nroot+anyEKU.pem | 19 + - .../openssl/test/certs/nroot+serverAuth.pem | 19 + - .../OpensslLib/openssl/test/certs/pathlen.pem | 22 + - .../OpensslLib/openssl/test/certs/pc1-cert.pem | 20 + - .../OpensslLib/openssl/test/certs/pc1-key.pem | 28 + - .../OpensslLib/openssl/test/certs/pc2-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/pc2-key.pem | 28 + - .../OpensslLib/openssl/test/certs/pc5-cert.pem | 21 + - .../OpensslLib/openssl/test/certs/pc5-key.pem | 28 + - .../OpensslLib/openssl/test/certs/root+anyEKU.pem | 18 + - .../openssl/test/certs/root+clientAuth.pem | 19 + - .../openssl/test/certs/root+serverAuth.pem | 19 + - .../OpensslLib/openssl/test/certs/root-anyEKU.pem | 18 + - .../openssl/test/certs/root-cert-768.pem | 11 + - .../openssl/test/certs/root-cert-md5.pem | 18 + - .../OpensslLib/openssl/test/certs/root-cert.pem | 18 + - .../OpensslLib/openssl/test/certs/root-cert2.pem | 18 + - .../openssl/test/certs/root-clientAuth.pem | 19 + - .../OpensslLib/openssl/test/certs/root-key-768.pem | 13 + - .../OpensslLib/openssl/test/certs/root-key.pem | 28 + - .../OpensslLib/openssl/test/certs/root-key2.pem | 28 + - .../OpensslLib/openssl/test/certs/root-name2.pem | 18 + - .../OpensslLib/openssl/test/certs/root-nonca.pem | 19 + - .../openssl/test/certs/root-noserver.pem | 19 + - .../openssl/test/certs/root-serverAuth.pem | 19 + - .../openssl/test/certs/root2+clientAuth.pem | 19 + - .../openssl/test/certs/root2+serverAuth.pem | 19 + - .../openssl/test/certs/root2-serverAuth.pem | 19 + - .../OpensslLib/openssl/test/certs/rootCA.key | 27 + - .../OpensslLib/openssl/test/certs/rootCA.pem | 21 + - .../OpensslLib/openssl/test/certs/rootcert.pem | 18 + - .../OpensslLib/openssl/test/certs/rootkey.pem | 28 + - .../OpensslLib/openssl/test/certs/roots.pem | 42 + - .../OpensslLib/openssl/test/certs/sca+anyEKU.pem | 19 + - .../openssl/test/certs/sca+clientAuth.pem | 19 + - .../openssl/test/certs/sca+serverAuth.pem | 19 + - .../OpensslLib/openssl/test/certs/sca-anyEKU.pem | 19 + - .../OpensslLib/openssl/test/certs/sca-cert.pem | 19 + - .../openssl/test/certs/sca-clientAuth.pem | 19 + - .../openssl/test/certs/sca-serverAuth.pem | 19 + - .../openssl/test/certs/server-trusted.pem | 20 + - .../OpensslLib/openssl/test/certs/servercert.pem | 19 + - .../OpensslLib/openssl/test/certs/serverkey.pem | 28 + - .../Library/OpensslLib/openssl/test/certs/setup.sh | 346 + - .../OpensslLib/openssl/test/certs/sroot+anyEKU.pem | 19 + - .../openssl/test/certs/sroot+clientAuth.pem | 19 + - .../openssl/test/certs/sroot+serverAuth.pem | 19 + - .../OpensslLib/openssl/test/certs/sroot-anyEKU.pem | 19 + - .../OpensslLib/openssl/test/certs/sroot-cert.pem | 19 + - .../openssl/test/certs/sroot-clientAuth.pem | 19 + - .../openssl/test/certs/sroot-serverAuth.pem | 19 + - .../openssl/test/certs/subinterCA-ss.pem | 21 + - .../OpensslLib/openssl/test/certs/subinterCA.key | 27 + - .../OpensslLib/openssl/test/certs/subinterCA.pem | 21 + - .../OpensslLib/openssl/test/certs/untrusted.pem | 42 + - .../OpensslLib/openssl/test/certs/wrongcert.pem | 19 + - .../OpensslLib/openssl/test/certs/wrongkey.pem | 28 + - .../OpensslLib/openssl/test/cipherlist_test.c | 199 + - .../OpensslLib/openssl/test/clienthellotest.c | 145 + - .../OpensslLib/openssl/test/cms-examples.pl | 365 + - .../OpensslLib/openssl/test/constant_time_test.c | 268 + - .../Library/OpensslLib/openssl/test/crltest.c | 378 + - .../OpensslLib/openssl/test/ct/log_list.conf | 38 + - .../Library/OpensslLib/openssl/test/ct/tls1.sct | 12 + - .../Library/OpensslLib/openssl/test/ct_test.c | 607 + - .../OpensslLib/openssl/test/d2i-tests/bad-cms.der | Bin 0 -> 24 bytes - .../openssl/test/d2i-tests/bad-int-pad0.der | Bin 0 -> 4 bytes - .../openssl/test/d2i-tests/bad-int-padminus1.der | Bin 0 -> 4 bytes - .../OpensslLib/openssl/test/d2i-tests/bad_bio.der | Bin 0 -> 7 bytes - .../OpensslLib/openssl/test/d2i-tests/bad_cert.der | Bin 0 -> 1007 bytes - .../openssl/test/d2i-tests/bad_generalname.der | Bin 0 -> 60 bytes - .../OpensslLib/openssl/test/d2i-tests/high_tag.der | Bin 0 -> 6 bytes - .../OpensslLib/openssl/test/d2i-tests/int0.der | Bin 0 -> 3 bytes - .../OpensslLib/openssl/test/d2i-tests/int1.der | Bin 0 -> 3 bytes - .../openssl/test/d2i-tests/intminus1.der | Bin 0 -> 3 bytes - .../Library/OpensslLib/openssl/test/d2i_test.c | 222 + - .../Library/OpensslLib/openssl/test/danetest.c | 504 + - .../Library/OpensslLib/openssl/test/danetest.in | 1878 +++ - .../Library/OpensslLib/openssl/test/danetest.pem | 14 + - .../Library/OpensslLib/openssl/test/destest.c | 804 ++ - CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c | 598 + - .../Library/OpensslLib/openssl/test/dsatest.c | 196 + - .../Library/OpensslLib/openssl/test/dtlstest.c | 142 + - .../OpensslLib/openssl/test/dtlsv1listentest.c | 426 + - .../Library/OpensslLib/openssl/test/ecdhtest.c | 612 + - .../OpensslLib/openssl/test/ecdhtest_cavs.h | 1359 ++ - .../Library/OpensslLib/openssl/test/ecdsatest.c | 519 + - CryptoPkg/Library/OpensslLib/openssl/test/ectest.c | 0 - .../Library/OpensslLib/openssl/test/enginetest.c | 204 + - .../OpensslLib/openssl/test/evp_extra_test.c | 409 + - .../Library/OpensslLib/openssl/test/evp_test.c | 2019 +++ - .../Library/OpensslLib/openssl/test/evptests.txt | 3639 ++++++ - .../Library/OpensslLib/openssl/test/exdatatest.c | 104 + - .../Library/OpensslLib/openssl/test/exptest.c | 268 + - .../OpensslLib/openssl/test/generate_buildtest.pl | 34 + - .../OpensslLib/openssl/test/generate_ssl_tests.pl | 141 + - .../Library/OpensslLib/openssl/test/gmdifftest.c | 81 + - .../OpensslLib/openssl/test/handshake_helper.c | 1098 ++ - .../OpensslLib/openssl/test/handshake_helper.h | 59 + - .../OpensslLib/openssl/test/heartbeat_test.c | 378 + - .../Library/OpensslLib/openssl/test/hmactest.c | 312 + - .../Library/OpensslLib/openssl/test/ideatest.c | 178 + - .../Library/OpensslLib/openssl/test/igetest.c | 441 + - .../Library/OpensslLib/openssl/test/md2test.c | 92 + - .../Library/OpensslLib/openssl/test/md4test.c | 87 + - .../Library/OpensslLib/openssl/test/md5test.c | 88 + - .../Library/OpensslLib/openssl/test/mdc2test.c | 99 + - .../Library/OpensslLib/openssl/test/memleaktest.c | 46 + - .../Library/OpensslLib/openssl/test/methtest.c | 57 + - .../OpensslLib/openssl/test/ocsp-tests/D1.ors | 32 + - .../openssl/test/ocsp-tests/D1_Cert_EE.pem | 38 + - .../openssl/test/ocsp-tests/D1_Issuer_ICA.pem | 27 + - .../OpensslLib/openssl/test/ocsp-tests/D2.ors | 32 + - .../openssl/test/ocsp-tests/D2_Cert_ICA.pem | 26 + - .../openssl/test/ocsp-tests/D2_Issuer_Root.pem | 21 + - .../OpensslLib/openssl/test/ocsp-tests/D3.ors | 38 + - .../openssl/test/ocsp-tests/D3_Cert_EE.pem | 31 + - .../openssl/test/ocsp-tests/D3_Issuer_Root.pem | 83 + - .../openssl/test/ocsp-tests/ISDOSC_D1.ors | 32 + - .../openssl/test/ocsp-tests/ISDOSC_D2.ors | 32 + - .../openssl/test/ocsp-tests/ISDOSC_D3.ors | 38 + - .../openssl/test/ocsp-tests/ISIC_D1_Issuer_ICA.pem | 27 + - .../test/ocsp-tests/ISIC_D2_Issuer_Root.pem | 21 + - .../test/ocsp-tests/ISIC_D3_Issuer_Root.pem | 41 + - .../test/ocsp-tests/ISIC_ND1_Issuer_ICA.pem | 29 + - .../test/ocsp-tests/ISIC_ND2_Issuer_Root.pem | 23 + - .../test/ocsp-tests/ISIC_ND3_Issuer_Root.pem | 25 + - .../OpensslLib/openssl/test/ocsp-tests/ISOP_D1.ors | 32 + - .../OpensslLib/openssl/test/ocsp-tests/ISOP_D2.ors | 32 + - .../OpensslLib/openssl/test/ocsp-tests/ISOP_D3.ors | 38 + - .../openssl/test/ocsp-tests/ISOP_ND1.ors | 10 + - .../openssl/test/ocsp-tests/ISOP_ND2.ors | 10 + - .../openssl/test/ocsp-tests/ISOP_ND3.ors | 10 + - .../OpensslLib/openssl/test/ocsp-tests/ND1.ors | 10 + - .../openssl/test/ocsp-tests/ND1_Cert_EE.pem | 36 + - .../openssl/test/ocsp-tests/ND1_Issuer_ICA.pem | 29 + - .../OpensslLib/openssl/test/ocsp-tests/ND2.ors | 10 + - .../openssl/test/ocsp-tests/ND2_Cert_ICA.pem | 29 + - .../openssl/test/ocsp-tests/ND2_Issuer_Root.pem | 23 + - .../OpensslLib/openssl/test/ocsp-tests/ND3.ors | 10 + - .../openssl/test/ocsp-tests/ND3_Cert_EE.pem | 34 + - .../openssl/test/ocsp-tests/ND3_Issuer_Root.pem | 25 + - .../OpensslLib/openssl/test/ocsp-tests/WIKH_D1.ors | 32 + - .../OpensslLib/openssl/test/ocsp-tests/WIKH_D2.ors | 32 + - .../OpensslLib/openssl/test/ocsp-tests/WIKH_D3.ors | 38 + - .../openssl/test/ocsp-tests/WIKH_ND1.ors | 10 + - .../openssl/test/ocsp-tests/WIKH_ND2.ors | 10 + - .../openssl/test/ocsp-tests/WIKH_ND3.ors | 10 + - .../OpensslLib/openssl/test/ocsp-tests/WINH_D1.ors | 32 + - .../OpensslLib/openssl/test/ocsp-tests/WINH_D2.ors | 32 + - .../OpensslLib/openssl/test/ocsp-tests/WINH_D3.ors | 38 + - .../openssl/test/ocsp-tests/WINH_ND1.ors | 10 + - .../openssl/test/ocsp-tests/WINH_ND2.ors | 10 + - .../openssl/test/ocsp-tests/WINH_ND3.ors | 10 + - .../openssl/test/ocsp-tests/WKDOSC_D1.ors | 32 + - .../openssl/test/ocsp-tests/WKDOSC_D2.ors | 32 + - .../openssl/test/ocsp-tests/WKDOSC_D3.ors | 38 + - .../openssl/test/ocsp-tests/WKIC_D1_Issuer_ICA.pem | 27 + - .../test/ocsp-tests/WKIC_D2_Issuer_Root.pem | 21 + - .../test/ocsp-tests/WKIC_D3_Issuer_Root.pem | 41 + - .../test/ocsp-tests/WKIC_ND1_Issuer_ICA.pem | 29 + - .../test/ocsp-tests/WKIC_ND2_Issuer_Root.pem | 23 + - .../test/ocsp-tests/WKIC_ND3_Issuer_Root.pem | 25 + - .../OpensslLib/openssl/test/ocsp-tests/WRID_D1.ors | 32 + - .../OpensslLib/openssl/test/ocsp-tests/WRID_D2.ors | 32 + - .../OpensslLib/openssl/test/ocsp-tests/WRID_D3.ors | 38 + - .../openssl/test/ocsp-tests/WRID_ND1.ors | 10 + - .../openssl/test/ocsp-tests/WRID_ND2.ors | 10 + - .../openssl/test/ocsp-tests/WRID_ND3.ors | 10 + - .../test/ocsp-tests/WSNIC_D1_Issuer_ICA.pem | 27 + - .../test/ocsp-tests/WSNIC_D2_Issuer_Root.pem | 21 + - .../test/ocsp-tests/WSNIC_D3_Issuer_Root.pem | 41 + - .../test/ocsp-tests/WSNIC_ND1_Issuer_ICA.pem | 29 + - .../test/ocsp-tests/WSNIC_ND2_Issuer_Root.pem | 23 + - .../test/ocsp-tests/WSNIC_ND3_Issuer_Root.pem | 25 + - .../OpensslLib/openssl/test/p5_crpt2_test.c | 159 + - .../Library/OpensslLib/openssl/test/packettest.c | 537 + - .../Library/OpensslLib/openssl/test/pbelutest.c | 47 + - .../Library/OpensslLib/openssl/test/pkcs7-1.pem | 15 + - .../Library/OpensslLib/openssl/test/pkcs7.pem | 54 + - .../Library/OpensslLib/openssl/test/pkits-test.pl | 905 ++ - .../Library/OpensslLib/openssl/test/r160test.c | 9 + - .../Library/OpensslLib/openssl/test/randtest.c | 145 + - .../Library/OpensslLib/openssl/test/rc2test.c | 99 + - .../Library/OpensslLib/openssl/test/rc4test.c | 175 + - .../Library/OpensslLib/openssl/test/rc5test.c | 276 + - .../openssl/test/recipes/01-test_abort.t | 16 + - .../openssl/test/recipes/01-test_sanity.t | 12 + - .../openssl/test/recipes/01-test_symbol_presence.t | 116 + - .../openssl/test/recipes/02-test_ordinals.t | 58 + - .../OpensslLib/openssl/test/recipes/03-test_ui.t | 30 + - .../OpensslLib/openssl/test/recipes/05-test_bf.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_cast.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_des.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_hmac.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_idea.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_md2.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_md4.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_md5.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_mdc2.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_rand.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_rc2.t | 11 + - .../OpensslLib/openssl/test/recipes/05-test_rc4.t | 11 + - .../OpensslLib/openssl/test/recipes/05-test_rc5.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_rmd.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_sha1.t | 12 + - .../openssl/test/recipes/05-test_sha256.t | 12 + - .../openssl/test/recipes/05-test_sha512.t | 12 + - .../OpensslLib/openssl/test/recipes/05-test_wp.t | 12 + - .../OpensslLib/openssl/test/recipes/10-test_bn.t | 84 + - .../OpensslLib/openssl/test/recipes/10-test_exp.t | 12 + - .../OpensslLib/openssl/test/recipes/15-test_dh.t | 12 + - .../OpensslLib/openssl/test/recipes/15-test_dsa.t | 40 + - .../OpensslLib/openssl/test/recipes/15-test_ec.t | 38 + - .../OpensslLib/openssl/test/recipes/15-test_ecdh.t | 12 + - .../openssl/test/recipes/15-test_ecdsa.t | 12 + - .../OpensslLib/openssl/test/recipes/15-test_rsa.t | 41 + - .../OpensslLib/openssl/test/recipes/20-test_enc.t | 69 + - .../openssl/test/recipes/20-test_passwd.t | 39 + - .../OpensslLib/openssl/test/recipes/25-test_crl.t | 43 + - .../OpensslLib/openssl/test/recipes/25-test_d2i.t | 93 + - .../openssl/test/recipes/25-test_pkcs7.t | 27 + - .../OpensslLib/openssl/test/recipes/25-test_req.t | 76 + - .../OpensslLib/openssl/test/recipes/25-test_sid.t | 24 + - .../openssl/test/recipes/25-test_verify.t | 330 + - .../OpensslLib/openssl/test/recipes/25-test_x509.t | 34 + - .../openssl/test/recipes/30-test_afalg.t | 23 + - .../openssl/test/recipes/30-test_engine.t | 18 + - .../OpensslLib/openssl/test/recipes/30-test_evp.t | 19 + - .../openssl/test/recipes/30-test_evp_extra.t | 18 + - .../openssl/test/recipes/30-test_pbelu.t | 12 + - .../openssl/test/recipes/40-test_rehash.t | 99 + - .../openssl/test/recipes/70-test_asyncio.t | 21 + - .../openssl/test/recipes/70-test_bad_dtls.t | 20 + - .../openssl/test/recipes/70-test_clienthello.t | 20 + - .../openssl/test/recipes/70-test_packet.t | 12 + - .../openssl/test/recipes/70-test_sslcbcpadding.t | 110 + - .../openssl/test/recipes/70-test_sslcertstatus.t | 66 + - .../openssl/test/recipes/70-test_sslextension.t | 112 + - .../openssl/test/recipes/70-test_sslmessages.t | 147 + - .../openssl/test/recipes/70-test_sslrecords.t | 381 + - .../openssl/test/recipes/70-test_sslsessiontick.t | 268 + - .../openssl/test/recipes/70-test_sslskewith0p.t | 65 + - .../openssl/test/recipes/70-test_sslvertol.t | 67 + - .../openssl/test/recipes/70-test_tlsextms.t | 238 + - .../openssl/test/recipes/70-test_verify_extra.t | 19 + - .../OpensslLib/openssl/test/recipes/80-test_ca.t | 59 + - .../openssl/test/recipes/80-test_cipherlist.t | 26 + - .../OpensslLib/openssl/test/recipes/80-test_cms.t | 502 + - .../OpensslLib/openssl/test/recipes/80-test_ct.t | 17 + - .../OpensslLib/openssl/test/recipes/80-test_dane.t | 24 + - .../OpensslLib/openssl/test/recipes/80-test_dtls.t | 20 + - .../openssl/test/recipes/80-test_dtlsv1listen.t | 12 + - .../OpensslLib/openssl/test/recipes/80-test_ocsp.t | 206 + - .../openssl/test/recipes/80-test_pkcs12.t | 66 + - .../openssl/test/recipes/80-test_ssl_new.t | 131 + - .../openssl/test/recipes/80-test_ssl_old.t | 625 + - .../openssl/test/recipes/80-test_ssl_test_ctx.t | 19 + - .../openssl/test/recipes/80-test_sslcorrupt.t | 20 + - .../OpensslLib/openssl/test/recipes/80-test_tsa.t | 203 + - .../openssl/test/recipes/80-test_x509aux.t | 27 + - .../openssl/test/recipes/90-test_async.t | 12 + - .../openssl/test/recipes/90-test_bio_enc.t | 12 + - .../openssl/test/recipes/90-test_bioprint.t | 12 + - .../openssl/test/recipes/90-test_constant_time.t | 12 + - .../OpensslLib/openssl/test/recipes/90-test_fuzz.t | 40 + - .../openssl/test/recipes/90-test_gmdiff.t | 12 + - .../openssl/test/recipes/90-test_heartbeat.t | 12 + - .../OpensslLib/openssl/test/recipes/90-test_ige.t | 12 + - .../openssl/test/recipes/90-test_memleak.t | 15 + - .../openssl/test/recipes/90-test_p5_crpt2.t | 12 + - .../openssl/test/recipes/90-test_secmem.t | 12 + - .../openssl/test/recipes/90-test_shlibload.t | 36 + - .../OpensslLib/openssl/test/recipes/90-test_srp.t | 12 + - .../openssl/test/recipes/90-test_sslapi.t | 21 + - .../openssl/test/recipes/90-test_threads.t | 12 + - .../openssl/test/recipes/90-test_v3name.t | 12 + - .../Library/OpensslLib/openssl/test/recipes/bc.pl | 113 + - .../OpensslLib/openssl/test/recipes/tconversion.pl | 106 + - .../Library/OpensslLib/openssl/test/rmdtest.c | 92 + - .../Library/OpensslLib/openssl/test/rsa_test.c | 344 + - .../Library/OpensslLib/openssl/test/run_tests.pl | 65 + - .../Library/OpensslLib/openssl/test/sanitytest.c | 67 + - .../Library/OpensslLib/openssl/test/secmemtest.c | 103 + - .../Library/OpensslLib/openssl/test/serverinfo.pem | 16 + - .../Library/OpensslLib/openssl/test/sha1test.c | 111 + - .../Library/OpensslLib/openssl/test/sha256t.c | 177 + - .../Library/OpensslLib/openssl/test/sha512t.c | 199 + - .../Library/OpensslLib/openssl/test/shibboleth.pfx | Bin 0 -> 2519 bytes - .../OpensslLib/openssl/test/shlibloadtest.c | 231 + - .../Library/OpensslLib/openssl/test/smcont.txt | 1 + - .../OpensslLib/openssl/test/smime-certs/ca.cnf | 66 + - .../openssl/test/smime-certs/mksmime-certs.sh | 81 + - .../OpensslLib/openssl/test/smime-certs/smdh.pem | 33 + - .../OpensslLib/openssl/test/smime-certs/smdsa1.pem | 47 + - .../OpensslLib/openssl/test/smime-certs/smdsa2.pem | 47 + - .../OpensslLib/openssl/test/smime-certs/smdsa3.pem | 47 + - .../OpensslLib/openssl/test/smime-certs/smdsap.pem | 9 + - .../OpensslLib/openssl/test/smime-certs/smec1.pem | 22 + - .../OpensslLib/openssl/test/smime-certs/smec2.pem | 23 + - .../OpensslLib/openssl/test/smime-certs/smroot.pem | 49 + - .../OpensslLib/openssl/test/smime-certs/smrsa1.pem | 49 + - .../OpensslLib/openssl/test/smime-certs/smrsa2.pem | 49 + - .../OpensslLib/openssl/test/smime-certs/smrsa3.pem | 49 + - .../Library/OpensslLib/openssl/test/srptest.c | 312 + - .../openssl/test/ssl-tests/01-simple.conf | 78 + - .../openssl/test/ssl-tests/01-simple.conf.in | 42 + - .../test/ssl-tests/02-protocol-version.conf | 9975 +++++++++++++++ - .../test/ssl-tests/02-protocol-version.conf.in | 19 + - .../openssl/test/ssl-tests/03-custom_verify.conf | 238 + - .../test/ssl-tests/03-custom_verify.conf.in | 145 + - .../openssl/test/ssl-tests/04-client_auth.conf | 592 + - .../openssl/test/ssl-tests/04-client_auth.conf.in | 125 + - .../OpensslLib/openssl/test/ssl-tests/05-sni.conf | 203 + - .../openssl/test/ssl-tests/05-sni.conf.in | 112 + - .../openssl/test/ssl-tests/06-sni-ticket.conf | 734 ++ - .../openssl/test/ssl-tests/06-sni-ticket.conf.in | 95 + - .../test/ssl-tests/07-dtls-protocol-version.conf | 1820 +++ - .../ssl-tests/07-dtls-protocol-version.conf.in | 19 + - .../OpensslLib/openssl/test/ssl-tests/08-npn.conf | 794 ++ - .../openssl/test/ssl-tests/08-npn.conf.in | 420 + - .../OpensslLib/openssl/test/ssl-tests/09-alpn.conf | 619 + - .../openssl/test/ssl-tests/09-alpn.conf.in | 324 + - .../openssl/test/ssl-tests/10-resumption.conf | 1336 ++ - .../openssl/test/ssl-tests/10-resumption.conf.in | 19 + - .../openssl/test/ssl-tests/11-dtls_resumption.conf | 612 + - .../test/ssl-tests/11-dtls_resumption.conf.in | 19 + - .../OpensslLib/openssl/test/ssl-tests/12-ct.conf | 135 + - .../openssl/test/ssl-tests/12-ct.conf.in | 80 + - .../openssl/test/ssl-tests/13-fragmentation.conf | 397 + - .../test/ssl-tests/13-fragmentation.conf.in | 181 + - .../openssl/test/ssl-tests/14-curves.conf | 787 ++ - .../openssl/test/ssl-tests/14-curves.conf.in | 44 + - .../openssl/test/ssl-tests/15-certstatus.conf | 62 + - .../openssl/test/ssl-tests/15-certstatus.conf.in | 45 + - .../openssl/test/ssl-tests/16-certstatus.conf | 0 - .../openssl/test/ssl-tests/16-dtls-certstatus.conf | 62 + - .../test/ssl-tests/16-dtls-certstatus.conf.in | 45 + - .../openssl/test/ssl-tests/17-renegotiate.conf | 312 + - .../openssl/test/ssl-tests/17-renegotiate.conf.in | 182 + - .../test/ssl-tests/18-dtls-renegotiate.conf | 276 + - .../test/ssl-tests/18-dtls-renegotiate.conf.in | 170 + - .../openssl/test/ssl-tests/protocol_version.pm | 247 + - .../openssl/test/ssl-tests/ssltests_base.pm | 25 + - .../Library/OpensslLib/openssl/test/ssl_test.c | 359 + - .../Library/OpensslLib/openssl/test/ssl_test.tmpl | 126 + - .../Library/OpensslLib/openssl/test/ssl_test_ctx.c | 661 + - .../Library/OpensslLib/openssl/test/ssl_test_ctx.h | 191 + - .../OpensslLib/openssl/test/ssl_test_ctx_test.c | 338 + - .../OpensslLib/openssl/test/ssl_test_ctx_test.conf | 88 + - .../Library/OpensslLib/openssl/test/sslapitest.c | 1049 ++ - .../OpensslLib/openssl/test/sslcorrupttest.c | 282 + - .../Library/OpensslLib/openssl/test/ssltest_old.c | 3192 +++++ - .../Library/OpensslLib/openssl/test/ssltestlib.c | 682 + - .../Library/OpensslLib/openssl/test/ssltestlib.h | 40 + - CryptoPkg/Library/OpensslLib/openssl/test/test.cnf | 88 + - .../openssl/test/testlib/OpenSSL/Test.pm | 1014 ++ - .../openssl/test/testlib/OpenSSL/Test/Simple.pm | 91 + - .../openssl/test/testlib/OpenSSL/Test/Utils.pm | 239 + - .../Library/OpensslLib/openssl/test/testutil.c | 109 + - .../Library/OpensslLib/openssl/test/testutil.h | 111 + - .../Library/OpensslLib/openssl/test/threadstest.c | 246 + - .../Library/OpensslLib/openssl/test/v3-cert1.pem | 16 + - .../Library/OpensslLib/openssl/test/v3-cert2.pem | 16 + - CryptoPkg/Library/OpensslLib/openssl/test/v3ext.c | 42 + - .../Library/OpensslLib/openssl/test/v3nametest.c | 355 + - .../OpensslLib/openssl/test/verify_extra_test.c | 162 + - .../Library/OpensslLib/openssl/test/wp_test.c | 233 + - .../Library/OpensslLib/openssl/test/x509aux.c | 231 + - .../Library/OpensslLib/openssl/tools/build.info | 7 + - .../Library/OpensslLib/openssl/tools/c_rehash.in | 231 + - .../openssl/util/TLSProxy/ClientHello.pm | 242 + - .../OpensslLib/openssl/util/TLSProxy/Message.pm | 456 + - .../openssl/util/TLSProxy/NewSessionTicket.pm | 81 + - .../OpensslLib/openssl/util/TLSProxy/Proxy.pm | 525 + - .../OpensslLib/openssl/util/TLSProxy/Record.pm | 330 + - .../openssl/util/TLSProxy/ServerHello.pm | 210 + - .../openssl/util/TLSProxy/ServerKeyExchange.pm | 134 + - .../Library/OpensslLib/openssl/util/build.info | 8 + - .../Library/OpensslLib/openssl/util/ck_errf.pl | 70 + - CryptoPkg/Library/OpensslLib/openssl/util/copy.pl | 77 + - .../Library/OpensslLib/openssl/util/dofile.pl | 206 + - .../OpensslLib/openssl/util/find-doc-nits.pl | 196 + - .../OpensslLib/openssl/util/find-undoc-api.pl | 82 + - .../OpensslLib/openssl/util/find-unused-errs | 35 + - .../Library/OpensslLib/openssl/util/fipslink.pl | 115 + - CryptoPkg/Library/OpensslLib/openssl/util/incore | 454 + - .../Library/OpensslLib/openssl/util/indent.pro | 671 + - .../Library/OpensslLib/openssl/util/libcrypto.num | 4216 +++++++ - .../Library/OpensslLib/openssl/util/libssl.num | 407 + - .../Library/OpensslLib/openssl/util/mkbuildinf.pl | 41 + - .../Library/OpensslLib/openssl/util/mkcerts.sh | 220 + - CryptoPkg/Library/OpensslLib/openssl/util/mkdef.pl | 1694 +++ - .../Library/OpensslLib/openssl/util/mkdir-p.pl | 44 + - CryptoPkg/Library/OpensslLib/openssl/util/mkerr.pl | 771 ++ - CryptoPkg/Library/OpensslLib/openssl/util/mkrc.pl | 83 + - .../OpensslLib/openssl/util/openssl-format-source | 175 + - .../Library/OpensslLib/openssl/util/opensslwrap.sh | 26 + - .../openssl/util/perl/OpenSSL/Util/Pod.pm | 158 + - CryptoPkg/Library/OpensslLib/openssl/util/point.sh | 10 + - .../OpensslLib/openssl/util/process_docs.pl | 235 + - .../Library/OpensslLib/openssl/util/selftest.pl | 207 + - .../openssl/util/shareable_image_wrap.c.in | 113 + - .../OpensslLib/openssl/util/shlib_wrap.sh.in | 108 + - .../Library/OpensslLib/openssl/util/su-filter.pl | 264 + - .../OpensslLib/openssl/util/with_fallback.pm | 24 + - 2373 files changed, 684704 insertions(+) - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/.gitattributes - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/.gitignore - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/.travis-create-release.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/.travis.yml - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ACKNOWLEDGEMENTS - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/AUTHORS - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/CHANGES - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/CONTRIBUTING - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/00-base-templates.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/10-main.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/50-djgpp.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/50-haiku.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/50-masm.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/90-team.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/INTERNALS.Configure - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/README.design - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/common.tmpl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/descrip.mms.tmpl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/unix-Makefile.tmpl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Configurations/windows-makefile.tmpl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/Configure - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/FAQ - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/INSTALL - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/LICENSE - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/Makefile.shared - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/NEWS - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/NOTES.DJGPP - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/NOTES.PERL - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/NOTES.VMS - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/NOTES.WIN - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/README.ECC - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/README.ENGINE - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/README.FIPS - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/VMS/VMSify-conf.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/VMS/engine.opt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_ivp.com.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_shutdown.com.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_startup.com.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_utils.com.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/VMS/test-includes.com - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/VMS/translatesyms.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/CA.pl.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/app_rand.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/apps.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/apps.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/asn1pars.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/ca-cert.srl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/ca-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/ca-req.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/ca.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/ciphers.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/client.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/cms.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/crl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/crl2p7.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/ct_log_list.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/cacert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/index.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/private/cakey.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/serial - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/demoSRP/srp_verifier.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/demoSRP/srp_verifier.txt.attr - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dgst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dh1024.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dh2048.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dh4096.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dhparam.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dsa-ca.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dsa-pca.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dsa.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dsa1024.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dsa512.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dsap.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/dsaparam.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/ec.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/ecparam.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/engine.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/errstr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/gendsa.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/genpkey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/genrsa.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/nseq.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/ocsp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/openssl-vms.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/openssl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/openssl.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/opt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/passwd.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/pca-cert.srl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/pca-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/pca-req.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/pkcs12.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/pkcs7.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/pkcs8.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/pkey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/pkeyparam.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/pkeyutl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/prime.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/privkey.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/progs.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/progs.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/rand.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/rehash.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/req.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/req.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/rsa.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/rsa8192.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/rsautl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/s1024key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/s1024req.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/s512-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/s512-req.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/s_apps.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/s_cb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/s_client.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/s_server.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/s_socket.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/s_time.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/server.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/server.srl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/server2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/sess_id.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/smime.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/speed.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/spkac.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/srp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/testCA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/testdsa.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/testrsa.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/timeouts.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/ts.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/tsget.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/verify.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/version.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/vms_decc_init.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/vms_term_sock.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/vms_term_sock.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/win32_init.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/apps/x509.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/appveyor.yml - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/build.info - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/config - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/config.com - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_nyi.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_unix.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_vms.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_win.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_win32.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_wince.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_cbc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_cfb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_core.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ecb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ige.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_misc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ofb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_wrap.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_x86core.c - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-armv4.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-c64xplus.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-ia64.S - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-mips.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-parisc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-ppc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-s390x.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-sparcv9.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesfx-sparcv9.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-mb-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-x86.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-x86_64.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesp8-ppc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aest4-sparcv9.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesv8-armx.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/bsaes-armv7.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/bsaes-x86_64.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-armv8.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-ppc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-x86.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/aes/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/alphacpuid.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/arm64cpuid.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/arm_arch.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/armcap.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/armv4cpuid.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_bitstr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_d2i_fp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_digest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_dup.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_gentm.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_i2d_fp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_int.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_mbstr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_object.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_octet.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_print.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_sign.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_strex.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_strnid.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_time.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_type.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_utctm.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_utf8.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_verify.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/ameth_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_gen.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_par.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_mime.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_moid.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_mstbl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_pack.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_ndef.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/charmap.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/charmap.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/d2i_pr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/d2i_pu.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/evp_asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/f_int.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/f_string.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/i2d_pr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/i2d_pu.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/n_pkey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/nsseq.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_pbe.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_pbev2.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_scrypt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p8_pkey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_bitst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_pkey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_spki.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_dec.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_fre.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_new.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_prn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_scn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_typ.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_utl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_algor.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_bignum.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_info.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_long.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_pkey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_sig.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_spki.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_val.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_null.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_null.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_posix.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_posix.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_win.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_win.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/async.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_wait.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/async/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bf/asm/bf-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_cbc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_cfb64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_ecb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_ofb64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_pi.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_skey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bf/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_addr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_dump.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_print.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_sock.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_sock2.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_buff.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_lbuf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_nbio.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_null.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_cb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_meth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_acpt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_bio.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_conn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_dgram.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_fd.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_file.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_log.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_mem.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_null.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_sock.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bio/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2_impl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2b.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2s.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/m_blake2b.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/m_blake2s.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/README.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/alpha-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv4-gf2m.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv4-mont.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv8-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/bn-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/bn-c64xplus.asm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/c64xplus-gf2m.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/co-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ia64-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ia64.S - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/mips-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/mips.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/pa-risc2.s - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/pa-risc2W.s - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/parisc-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc64-mont.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/rsaz-avx2.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/rsaz-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x-gf2m.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x-mont.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x.S - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparct4-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv8.S - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv8plus.S - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9-gf2m.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9-mont.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9a-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/via-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/vis3-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86-gf2m.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86-mont.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-gcc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-gf2m.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-mont.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-mont5.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_add.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_asm.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_blind.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_const.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_ctx.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_depr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_dh.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_div.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp2.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gcd.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gf2m.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_intern.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_kron.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mod.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mont.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mpi.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mul.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_nist.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_print.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_rand.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_recp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_shift.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqrt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_srp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_word.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_x931p.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsaz_exp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsaz_exp.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/buf_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/buffer.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/c64xpluscpuid.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmll-x86.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmll-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmllt4-sparcv9.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/camellia.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_cbc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_cfb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ctr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ecb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_misc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ofb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cast/asm/cast-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cast/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_cfb64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_ecb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_ofb64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_skey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cast/cast_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cast/cast_s.h - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-armv4.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-armv8.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-c64xplus.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-ppc.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-s390x.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-x86.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/chacha_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cm_ameth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cm_pmeth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cmac.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_att.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_cd.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_dd.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_env.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_ess.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_io.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_kari.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_pwri.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_sd.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_smime.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/comp/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/comp/c_zlib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/conf/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_api.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_def.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_def.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_mall.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_mod.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_sap.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/conf/keysets.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cpt_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cryptlib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_b64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_log.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_oct.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_policy.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_prn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_sct.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_sct_ctx.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_vfy.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_x509v3.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/cversion.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/crypt586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/des-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/des_enc.m4 - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/desboth.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/dest4-sparcv9.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/cbc_cksm.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/cbc_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb64ede.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb64enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/des_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/des_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/ecb3_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/ecb_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/fcrypt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/fcrypt_b.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/ncbc_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb64ede.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb64enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/pcbc_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/qud_cksm.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/rand_key.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/rpc_des.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/rpc_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/set_key.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/spr.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/str2key.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/des/xcbc_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh1024.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh192.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh2048.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh4096.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh512.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_ameth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_depr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_gen.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_kdf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_key.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_meth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_pmeth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_prn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_rfc5114.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dllmain.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_ameth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_depr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_gen.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_key.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_meth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_ossl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_pmeth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_prn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_sign.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_vrf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dso/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_dl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_dlfcn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_openssl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_vms.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_win32.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ebcdic.c - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-armv4.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-armv8.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-avx2.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-sparcv9.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-x86.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/curve25519.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec2_mult.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec2_oct.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec2_smpl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_ameth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_check.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_curve.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_cvt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_key.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_kmeth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_mult.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_oct.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_pmeth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_print.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdh_kdf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdh_ossl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_ossl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_sign.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_vrf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/eck_prn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_mont.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nist.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp224.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp256.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp521.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistputil.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistz256.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistz256_table.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_oct.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_smpl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecx_meth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_all.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_cnf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_cryptodev.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_ctrl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_dyn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_fat.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_init.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_int.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_list.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_openssl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_pkey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_rdrand.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_table.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_asnmth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_cipher.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_dh.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_digest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_dsa.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_eckey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_pkmeth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_rand.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_rsa.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/err/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/err/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/err/err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/err/err_all.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/err/err_prn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.ec - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_b64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_md.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_ok.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/c_allc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/c_alld.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/cmeth_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/digest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_bf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_camellia.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_cast.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_chacha20_poly1305.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_des.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_des3.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_idea.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_null.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_old.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc2.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc4.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc4_hmac_md5.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc5.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_seed.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_xcbc_d.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/encode.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_cnf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_key.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_pbe.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_pkey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md2.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md4.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md5.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md5_sha1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_mdc2.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_null.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_ripemd.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_sha1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_sigver.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_wp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/names.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p5_crpt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p5_crpt2.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_dec.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_open.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_seal.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_sign.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_verify.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_fn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_gn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/evp/scrypt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ex_data.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hm_ameth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hm_pmeth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hmac.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hmac_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ia64cpuid.S - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/idea/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_cbc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_cfb64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_ecb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_ofb64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_skey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/idea/idea_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/asn1_int.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/async.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_conf.h.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_dh.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_int.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_srp.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/chacha.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/cryptlib.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/cryptlib_int.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/dso_conf.h.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/engine.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/err_int.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/evp_int.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/md32_common.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/objects.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/poly1305.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/rand.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/x509_int.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/init.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/hkdf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/kdf_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/tls1_prf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lh_stats.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lhash.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lhash_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/num.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md2/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md2/md2_dgst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md2/md2_one.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md4/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_dgst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_one.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-ia64.S - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-sparcv9.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md5/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_dgst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_one.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/mdc2_one.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/mdc2dgst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/mem.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/mem_clr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/mem_dbg.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/mem_sec.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/aesni-gcm-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-alpha.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-armv4.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-c64xplus.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-ia64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-parisc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-s390x.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-sparcv9.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-x86.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-x86_64.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghashp8-ppc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghashv8-armx.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cbc128.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ccm128.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cfb128.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ctr128.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cts128.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/gcm128.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/modes_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ocb128.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ofb128.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/wrap128.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/modes/xts128.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/o_dir.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/o_fips.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/o_fopen.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/o_init.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/o_str.c - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/o_time.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/o_names.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_mac.num - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objects.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objects.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objxref.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_asn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_cl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_ext.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_ht.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_prn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_srv.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_vfy.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/v3_ocsp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pariscid.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_all.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_info.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_oth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_pk8.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_pkey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_sign.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_x509.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_xaux.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pvkfmt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/README - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/arm-xlate.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/cbc.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/ppc-xlate.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/sparcv9_modes.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86_64-xlate.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86asm.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86gas.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86masm.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86nasm.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_asn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_attr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_crpt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_crt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_decr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_init.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_key.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_kiss.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_p8d.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_p8e.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_sbag.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_utl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/pk12err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/bio_pk7.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_attr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_dgst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_doit.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_smime.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pkcs7err.c - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-armv4.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-armv8.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-c64xplus.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-mips.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppc.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppcfp.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-s390x.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-sparcv9.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-x86.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/poly1305.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/poly1305_ieee754.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ppc_arch.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ppccap.c - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/ppccpuid.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rand/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rand/md_rand.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_egd.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_unix.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_vms.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_win.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rand/randfile.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_cbc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_ecb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_skey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2cfb64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2ofb64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/tab.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-c64xplus.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-ia64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-parisc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-s390x.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_skey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/asm/rc5-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_ecb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_skey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5cfb64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5ofb64.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/asm/rmd-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_dgst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_one.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmdconst.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ameth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_chk.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_crpt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_depr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_gen.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_meth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_none.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_null.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_oaep.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ossl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pk1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pmeth.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_prn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pss.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_saos.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sign.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ssl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_x931.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_x931g.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/s390xcap.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/s390xcpuid.S - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/seed/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_cbc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_cfb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_ecb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_ofb.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-alpha.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-armv4-large.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-armv8.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-c64xplus.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-ia64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-mb-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-mips.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-parisc.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-ppc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-s390x.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-sparcv9.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-sparcv9a.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-thumb.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-armv4.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-c64xplus.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-mb-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-586.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-armv4.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-armv8.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-c64xplus.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-ia64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-mips.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-parisc.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-ppc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-s390x.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-sparcv9.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-x86_64.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512p8-ppc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha1_one.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha1dgst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha256.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha512.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sparc_arch.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sparccpuid.S - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/sparcv9cap.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/srp/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/srp/srp_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/srp/srp_vfy.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/stack/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/stack/stack.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/threads_none.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/threads_pthread.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/threads_win.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_conf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_req_print.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_req_utils.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_print.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_sign.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_utils.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_verify.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_verify_ctx.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/txt_db/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/txt_db/txt_db.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ui/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_openssl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_util.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/uid.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/vms_rms.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/asm/wp-mmx.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/asm/wp-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_block.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_dgst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/by_dir.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/by_file.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_crl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_req.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_x509.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_att.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_cmp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_d2.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_def.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_ext.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_lcl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_lu.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_obj.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_r2x.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_req.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_set.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_trs.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_txt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_v3.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vfy.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vpm.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509cset.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509name.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509rset.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509spki.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509type.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_all.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_attrib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_crl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_exten.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_name.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_pubkey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_req.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_x509.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_x509a.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/ext_dat.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_cache.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_data.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_int.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_map.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/tabtest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_addr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_akey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_akeya.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_alt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_asid.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_bcons.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_bitst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_conf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_cpols.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_crld.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_enum.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_extku.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ia5.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_info.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_int.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ncons.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pci.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pcia.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pcons.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pku.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pmaps.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_prn.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_purp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_skey.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_sxnet.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_tlsf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3conf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3prin.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x86_64cpuid.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/crypto/x86cpuid.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/Makefile - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/accept.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/client-arg.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/client-conf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/cmod.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/connect.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/descrip.mms - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/intca.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/saccept.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/sconnect.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-arg.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-cmod.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-conf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-ec.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/server.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/shared.opt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/bio/static.opt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/apps.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/ckey.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/intkey.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/mkacerts.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/mkxcerts.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/rootkey.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/skey.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/skey2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/ca.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/mkcerts.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/ocspquery.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/certs/ocsprun.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cacert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cakey.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_comp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_ddec.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_dec.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_denc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_sign.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_sign2.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_uncomp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_ver.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/comp.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/encr.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/sign.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/signer.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/cms/signer2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/evp/aesccm.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/evp/aesgcm.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/pkread.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/pkwrite.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/cacert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/cakey.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/encr.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/sign.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/signer.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/signer2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/smdec.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/smenc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/smsign.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/smsign2.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/demos/smime/smver.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/CT_POLICY_EVAL_CTX_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/certificates.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/keys.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/proxy_certificates.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/SCT_validate.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/SSL_CTX_set_ct_validation_callback.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/CA.pl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/asn1parse.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/ca.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/ciphers.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/cms.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/config.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/crl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/crl2pkcs7.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/dgst.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/dhparam.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/dsa.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/dsaparam.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/ec.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/ecparam.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/enc.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/engine.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/errstr.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/gendsa.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/genpkey.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/genrsa.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/list.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/nseq.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/ocsp.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/openssl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/passwd.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/pkcs12.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/pkcs7.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/pkcs8.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/pkey.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/pkeyparam.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/pkeyutl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/rand.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/rehash.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/req.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/rsa.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/rsautl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/s_client.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/s_server.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/s_time.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/sess_id.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/smime.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/speed.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/spkac.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/ts.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/tsget.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/verify.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/version.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/x509.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/apps/x509v3_config.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ASN1_INTEGER_get_int64.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ASN1_OBJECT_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ASN1_STRING_length.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ASN1_STRING_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ASN1_STRING_print_ex.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ASN1_TIME_set.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ASN1_TYPE_get.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ASN1_generate_nconf.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ASYNC_WAIT_CTX_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ASYNC_start_job.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BF_encrypt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_ADDR.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_ADDRINFO.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_connect.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_ctrl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_f_base64.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_f_buffer.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_f_cipher.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_f_md.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_f_null.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_f_ssl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_find_type.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_get_data.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_get_ex_new_index.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_meth_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_new_CMS.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_parse_hostserv.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_push.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_read.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_s_accept.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_s_bio.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_s_connect.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_s_fd.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_s_file.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_s_mem.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_s_null.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_s_socket.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_set_callback.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BIO_should_retry.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_BLINDING_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_CTX_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_CTX_start.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_add.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_add_word.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_bn2bin.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_cmp.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_copy.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_generate_prime.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_mod_inverse.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_mod_mul_montgomery.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_mod_mul_reciprocal.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_num_bytes.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_rand.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_set_bit.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_swap.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BN_zero.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/BUF_MEM_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_add0_cert.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_add1_recipient_cert.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_add1_signer.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_compress.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_decrypt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_encrypt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_final.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_get0_RecipientInfos.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_get0_SignerInfos.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_get0_type.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_get1_ReceiptRequest.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_sign.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_sign_receipt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_uncompress.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_verify.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CMS_verify_receipt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CONF_modules_free.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CONF_modules_load_file.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CRYPTO_THREAD_run_once.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CRYPTO_get_ex_new_index.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CTLOG_STORE_get0_log_by_id.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CTLOG_STORE_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CTLOG_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/CT_POLICY_EVAL_CTX_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DEFINE_STACK_OF.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DES_random_key.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DH_generate_key.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DH_generate_parameters.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DH_get0_pqg.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DH_get_1024_160.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DH_meth_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DH_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DH_set_method.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DH_size.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_SIG_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_do_sign.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_dup_DH.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_generate_key.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_generate_parameters.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_get0_pqg.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_meth_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_set_method.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_sign.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/DSA_size.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ECDSA_SIG_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ECPKParameters_print.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EC_GFp_simple_method.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EC_GROUP_copy.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EC_GROUP_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EC_KEY_get_enc_flags.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EC_KEY_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EC_POINT_add.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EC_POINT_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ENGINE_add.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ERR_GET_LIB.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ERR_clear_error.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ERR_error_string.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ERR_get_error.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ERR_load_crypto_strings.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ERR_load_strings.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ERR_print_errors.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ERR_put_error.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ERR_remove_state.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ERR_set_mark.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_BytesToKey.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_CIPHER_CTX_get_cipher_data.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_CIPHER_meth_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_DigestInit.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_DigestSignInit.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_DigestVerifyInit.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_EncodeInit.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_EncryptInit.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_MD_meth_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_OpenInit.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_CTX_ctrl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_CTX_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_CTX_set_hkdf_md.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_CTX_set_tls1_prf_md.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_cmp.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_decrypt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_derive.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_encrypt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_get_default_digest_nid.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_keygen.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_print_private.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_sign.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_verify.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_PKEY_verify_recover.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_SealInit.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_SignInit.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/EVP_VerifyInit.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/HMAC.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/MD5.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/MDC2_Init.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OBJ_nid2obj.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OCSP_REQUEST_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OCSP_cert_to_id.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OCSP_request_add1_nonce.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OCSP_resp_find_status.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OCSP_response_status.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OCSP_sendreq_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_Applink.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_LH_COMPFUNC.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_LH_stats.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_VERSION_NUMBER.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_config.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_ia32cap.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_init_crypto.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_instrument_bus.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_load_builtin_modules.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_malloc.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OPENSSL_secure_malloc.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/OpenSSL_add_all_algorithms.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PEM_read.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PEM_read_CMS.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PEM_read_bio_PrivateKey.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PEM_write_bio_CMS_stream.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PEM_write_bio_PKCS7_stream.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PKCS12_create.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PKCS12_newpass.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PKCS12_parse.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PKCS5_PBKDF2_HMAC.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PKCS7_decrypt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PKCS7_encrypt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PKCS7_sign.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PKCS7_sign_add_signer.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/PKCS7_verify.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RAND_add.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RAND_bytes.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RAND_cleanup.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RAND_egd.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RAND_load_file.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RAND_set_rand_method.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RC4_set_key.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RIPEMD160_Init.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_blinding_on.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_check_key.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_generate_key.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_get0_key.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_meth_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_padding_add_PKCS1_type_1.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_print.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_private_encrypt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_public_encrypt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_set_method.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_sign.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/RSA_size.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/SCT_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/SCT_print.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/SCT_validate.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/SHA256_Init.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/SMIME_read_CMS.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/SMIME_read_PKCS7.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/SMIME_write_CMS.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/SMIME_write_PKCS7.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/SSL_set_bio.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/UI_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509V3_get_d2i.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_ALGOR_dup.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_CRL_get0_by_serial.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_EXTENSION_set_object.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_LOOKUP_hash_dir.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_NAME_ENTRY_get_object.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_NAME_add_entry_by_txt.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_NAME_get0_der.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_NAME_get_index_by_NID.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_NAME_print_ex.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_PUBKEY_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_SIG_get0.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_STORE_CTX_get_error.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_STORE_CTX_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_STORE_CTX_set_verify_cb.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_STORE_get0_param.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_STORE_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_STORE_set_verify_cb_func.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_VERIFY_PARAM_set_flags.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_check_ca.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_check_host.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_check_issued.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_digest.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_dup.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_get0_signature.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_get0_uids.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_get_extension_flags.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_get_notBefore.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_get_pubkey.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_get_serialNumber.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_get_subject_name.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_get_version.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_sign.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509_verify_cert.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/X509v3_get_ext_by_NID.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/bio.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/crypto.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/ct.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/d2i_DHparams.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/d2i_Netscape_RSA.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/d2i_PKCS8PrivateKey_bio.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/d2i_PrivateKey.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/d2i_X509.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/des_modes.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/evp.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/i2d_CMS_bio_stream.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/i2d_PKCS7_bio_stream.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/i2d_re_X509_tbs.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/o2i_SCT_LIST.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/crypto/x509.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/dir-locals.example.el - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/fingerprints.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/openssl-c-indent.el - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/DTLSv1_listen.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/OPENSSL_init_ssl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CIPHER_get_name.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_COMP_add_compression_method.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CONF_CTX_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CONF_CTX_set1_prefix.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CONF_CTX_set_flags.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CONF_CTX_set_ssl_ctx.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CONF_cmd.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CONF_cmd_argv.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_add1_chain_cert.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_add_extra_chain_cert.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_add_session.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_config.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_ctrl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_dane_enable.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_flush_sessions.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_free.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_get0_param.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_get_verify_mode.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_has_client_custom_ext.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_load_verify_locations.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_sess_number.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_sess_set_cache_size.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_sess_set_get_cb.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_sessions.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set1_curves.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set1_sigalgs.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set1_verify_cert_store.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_alpn_select_cb.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_cert_cb.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_cert_store.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_cert_verify_callback.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_cipher_list.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_client_CA_list.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_client_cert_cb.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_ct_validation_callback.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_ctlog_list_file.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_default_passwd_cb.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_generate_session_id.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_info_callback.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_max_cert_list.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_min_proto_version.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_mode.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_msg_callback.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_options.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_psk_client_callback.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_quiet_shutdown.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_read_ahead.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_security_level.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_session_cache_mode.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_session_id_context.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_split_send_fragment.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_ssl_version.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_timeout.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_tlsext_status_cb.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_tlsext_ticket_key_cb.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_set_verify.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_use_certificate.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_use_psk_identity_hint.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_CTX_use_serverinfo.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_SESSION_free.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_SESSION_get0_cipher.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_SESSION_get0_hostname.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_SESSION_get0_id_context.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_SESSION_get_protocol_version.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_SESSION_get_time.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_SESSION_has_ticket.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_SESSION_set1_id.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_accept.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_alert_type_string.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_check_chain.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_clear.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_connect.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_do_handshake.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_extension_supported.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_free.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get0_peer_scts.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_SSL_CTX.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_all_async_fds.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_ciphers.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_client_CA_list.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_client_random.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_current_cipher.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_default_timeout.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_error.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_extms_support.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_fd.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_peer_cert_chain.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_peer_certificate.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_psk_identity.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_rbio.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_session.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_shared_sigalgs.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_verify_result.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_get_version.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_library_init.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_load_client_CA_file.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_new.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_pending.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_read.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_rstate_string.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_session_reused.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_set1_host.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_set_bio.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_set_connect_state.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_set_fd.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_set_session.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_set_shutdown.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_set_verify_result.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_shutdown.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_state_string.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_want.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/SSL_write.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/d2i_SSL_SESSION.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/doc/ssl/ssl.pod - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/e_os.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/afalg/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/afalg/e_afalg.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/afalg/e_afalg.ec - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/afalg/e_afalg.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/afalg/e_afalg_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/afalg/e_afalg_err.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/asm/e_padlock-x86.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/asm/e_padlock-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_capi.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_capi.ec - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_capi_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_capi_err.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_chil.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_chil.ec - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_chil_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_chil_err.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_dasync.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_dasync.ec - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_dasync_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_dasync_err.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_ossltest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_ossltest.ec - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_ossltest_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_ossltest_err.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_padlock.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/e_padlock.ec - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/engine_vector.mar - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/engines/vendor_defns/hwcryptohook.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Downloaded.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/Artistic - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/COPYING - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/INSTALL - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/MANIFEST - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/META.json - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/META.yml - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/Makefile.PL - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/lib/Text/Template.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/lib/Text/Template/Preprocess.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/00-version.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/01-basic.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/02-hash.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/03-out.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/04-safe.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/05-safe2.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/06-ofh.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/07-safe3.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/08-exported.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/09-error.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/10-delimiters.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/11-prepend.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/12-preprocess.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/13-taint.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/Text-Template-1.46/t/14-broken.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/external/perl/transfer/Text/Template.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/README.md - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/asn1parse.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/bignum.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/bndiv.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/cms.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/conf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/crl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/ct.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/driver.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/fuzzer.h - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/fuzz/helper.py - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/server.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/test-corpus.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/fuzz/x509.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/bio.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/comp.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/conf.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/constant_time_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/dane.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/dso.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/err.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/numbers.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/o_dir.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/o_str.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/internal/thread_once.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/__DECC_INCLUDE_EPILOGUE.H - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/__DECC_INCLUDE_PROLOGUE.H - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/aes.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/asn1.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/asn1t.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/async.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/bio.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/blowfish.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/bn.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/buffer.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/camellia.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/cast.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/cmac.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/cms.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/comp.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/conf.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/conf_api.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/crypto.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ct.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/des.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/dh.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/dsa.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/dtls1.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/e_os2.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ebcdic.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ec.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ecdh.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ecdsa.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/engine.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/err.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/evp.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/hmac.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/idea.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/kdf.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/lhash.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/md2.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/md4.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/md5.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/mdc2.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/modes.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/obj_mac.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/objects.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ocsp.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/opensslconf.h.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/opensslv.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ossl_typ.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/pem.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/pem2.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/pkcs12.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/pkcs7.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/rand.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/rc2.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/rc4.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/rc5.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ripemd.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/rsa.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/safestack.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/seed.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/sha.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/srp.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/srtp.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ssl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ssl2.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ssl3.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/stack.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/symhacks.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/tls1.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ts.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/txt_db.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/ui.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/whrlpool.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/x509.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/x509_vfy.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/include/openssl/x509v3.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ms/applink.c - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/ms/cmp.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/ms/segrenam.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ms/tlhelp32.h - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/ms/uplink-common.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/ms/uplink-ia64.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/ms/uplink-x86.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/ms/uplink-x86_64.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ms/uplink.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ms/uplink.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/os-dep/haiku.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/bio_ssl.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/d1_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/d1_msg.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/d1_srtp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/methods.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/packet_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/pqueue.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/record/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/record/dtls1_bitmap.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/record/rec_layer_d1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/record/rec_layer_s3.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/record/record.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/record/record_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/record/ssl3_buffer.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/record/ssl3_record.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/s3_cbc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/s3_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/s3_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/s3_msg.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_asn1.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_cert.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_ciph.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_conf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_err.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_init.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_mcnf.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_rsa.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_stat.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_txt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_utst.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/statem/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_clnt.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_dtls.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_locl.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/t1_enc.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/t1_ext.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/t1_lib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/t1_reneg.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/t1_trce.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/ssl/tls_srp.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/CAss.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/CAssdh.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/CAssdsa.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/CAssrsa.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/CAtsa.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/P1ss.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/P2ss.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/README - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/README.ssltest.md - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/Sssdsa.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/Sssrsa.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/Uss.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/aborttest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/afalgtest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/asynciotest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/asynctest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/bad_dtls_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/bftest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/bio_enc_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/bioprinttest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/bntest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/casttest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/alt1-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/alt1-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/alt2-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/alt2-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/alt3-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/alt3-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/bad-pc3-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/bad-pc3-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/bad-pc4-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/bad-pc4-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/bad-pc6-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/bad-pc6-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/bad.key - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/bad.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt1-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt1-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt10-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt10-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt2-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt2-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt3-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt3-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt4-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt4-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt5-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt5-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt6-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt6-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt7-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt7-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt8-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt8-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt9-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/badalt9-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca+anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca+clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca+serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-cert-768.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-cert-768i.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-cert-md5-any.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-cert-md5.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-cert2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-expired.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-key-768.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-key2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-name2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-nonbc.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-nonca.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-root2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ca-serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/cca+anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/cca+clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/cca+serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/cca-anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/cca-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/cca-clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/cca-serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/croot+anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/croot+clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/croot+serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/croot-anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/croot-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/croot-clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/croot-serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee+clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee+serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-cert-768.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-cert-768i.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-cert-md5.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-cert2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-client-chain.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-client.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-expired.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-key-768.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-name2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ee-serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/embeddedSCTs1.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/embeddedSCTs1.sct - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/embeddedSCTs1_issuer.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/embeddedSCTs3.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/embeddedSCTs3.sct - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/embeddedSCTs3_issuer.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/interCA.key - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/interCA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/leaf.key - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/leaf.pem - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/certs/mkcert.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/nca+anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/nca+serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ncca-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ncca-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ncca1-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ncca1-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ncca2-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ncca2-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ncca3-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/ncca3-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/nroot+anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/nroot+serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/pathlen.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/pc1-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/pc1-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/pc2-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/pc2-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/pc5-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/pc5-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root+anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root+clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root+serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-cert-768.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-cert-md5.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-cert2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-key-768.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-key.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-key2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-name2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-nonca.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-noserver.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root-serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root2+clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root2+serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/root2-serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/rootCA.key - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/rootCA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/rootcert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/rootkey.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/roots.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sca+anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sca+clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sca+serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sca-anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sca-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sca-clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sca-serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/server-trusted.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/servercert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/serverkey.pem - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/certs/setup.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sroot+anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sroot+clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sroot+serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sroot-anyEKU.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sroot-cert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sroot-clientAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/sroot-serverAuth.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/subinterCA-ss.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/subinterCA.key - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/subinterCA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/untrusted.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/wrongcert.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/certs/wrongkey.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/cipherlist_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/clienthellotest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/cms-examples.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/constant_time_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/crltest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ct/log_list.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ct/tls1.sct - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ct_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i-tests/bad-cms.der - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i-tests/bad-int-pad0.der - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i-tests/bad-int-padminus1.der - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i-tests/bad_bio.der - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i-tests/bad_cert.der - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i-tests/bad_generalname.der - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i-tests/high_tag.der - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i-tests/int0.der - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i-tests/int1.der - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i-tests/intminus1.der - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/d2i_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/danetest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/danetest.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/danetest.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/destest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/dhtest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/dsatest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/dtlstest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/dtlsv1listentest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ecdhtest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ecdhtest_cavs.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ecdsatest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ectest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/enginetest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/evp_extra_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/evp_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/evptests.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/exdatatest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/exptest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/generate_buildtest.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/generate_ssl_tests.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/gmdifftest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/handshake_helper.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/handshake_helper.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/heartbeat_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/hmactest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ideatest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/igetest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/md2test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/md4test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/md5test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/mdc2test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/memleaktest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/methtest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/D1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/D1_Cert_EE.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/D1_Issuer_ICA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/D2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/D2_Cert_ICA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/D2_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/D3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/D3_Cert_EE.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/D3_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISDOSC_D1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISDOSC_D2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISDOSC_D3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISIC_D1_Issuer_ICA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISIC_D2_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISIC_D3_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISIC_ND1_Issuer_ICA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISIC_ND2_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISIC_ND3_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISOP_D1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISOP_D2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISOP_D3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISOP_ND1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISOP_ND2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ISOP_ND3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ND1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ND1_Cert_EE.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ND1_Issuer_ICA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ND2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ND2_Cert_ICA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ND2_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ND3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ND3_Cert_EE.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/ND3_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WIKH_D1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WIKH_D2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WIKH_D3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WIKH_ND1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WIKH_ND2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WIKH_ND3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WINH_D1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WINH_D2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WINH_D3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WINH_ND1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WINH_ND2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WINH_ND3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WKDOSC_D1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WKDOSC_D2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WKDOSC_D3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WKIC_D1_Issuer_ICA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WKIC_D2_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WKIC_D3_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WKIC_ND1_Issuer_ICA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WKIC_ND2_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WKIC_ND3_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WRID_D1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WRID_D2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WRID_D3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WRID_ND1.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WRID_ND2.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WRID_ND3.ors - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WSNIC_D1_Issuer_ICA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WSNIC_D2_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WSNIC_D3_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WSNIC_ND1_Issuer_ICA.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WSNIC_ND2_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ocsp-tests/WSNIC_ND3_Issuer_Root.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/p5_crpt2_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/packettest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/pbelutest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/pkcs7-1.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/pkcs7.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/pkits-test.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/r160test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/randtest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/rc2test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/rc4test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/rc5test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/01-test_abort.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/01-test_sanity.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/01-test_symbol_presence.t - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/recipes/02-test_ordinals.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/03-test_ui.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_bf.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_cast.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_des.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_hmac.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_idea.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_md2.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_md4.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_md5.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_mdc2.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_rand.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_rc2.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_rc4.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_rc5.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_rmd.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_sha1.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_sha256.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_sha512.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/05-test_wp.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/10-test_bn.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/10-test_exp.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/15-test_dh.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/15-test_dsa.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/15-test_ec.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/15-test_ecdh.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/15-test_ecdsa.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/15-test_rsa.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/20-test_enc.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/20-test_passwd.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/25-test_crl.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/25-test_d2i.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/25-test_pkcs7.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/25-test_req.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/25-test_sid.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/25-test_verify.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/25-test_x509.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/30-test_afalg.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/30-test_engine.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/30-test_evp.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/30-test_evp_extra.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/30-test_pbelu.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/40-test_rehash.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_asyncio.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_bad_dtls.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_clienthello.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_packet.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_sslcbcpadding.t - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_sslcertstatus.t - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_sslextension.t - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_sslmessages.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_sslrecords.t - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_sslsessiontick.t - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_sslskewith0p.t - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_sslvertol.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_tlsextms.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/70-test_verify_extra.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_ca.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_cipherlist.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_cms.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_ct.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_dane.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_dtls.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_dtlsv1listen.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_ocsp.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_pkcs12.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_ssl_new.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_ssl_old.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_ssl_test_ctx.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_sslcorrupt.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_tsa.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/80-test_x509aux.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_async.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_bio_enc.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_bioprint.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_constant_time.t - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_fuzz.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_gmdiff.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_heartbeat.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_ige.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_memleak.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_p5_crpt2.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_secmem.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_shlibload.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_srp.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_sslapi.t - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_threads.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/90-test_v3name.t - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/bc.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/recipes/tconversion.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/rmdtest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/rsa_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/run_tests.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/sanitytest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/secmemtest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/serverinfo.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/sha1test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/sha256t.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/sha512t.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/shibboleth.pfx - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/shlibloadtest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smcont.txt - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/ca.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/mksmime-certs.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdh.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa1.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsa3.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smdsap.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smec1.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smec2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smroot.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa1.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/smime-certs/smrsa3.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/srptest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/01-simple.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/01-simple.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/02-protocol-version.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/02-protocol-version.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/03-custom_verify.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/03-custom_verify.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/04-client_auth.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/04-client_auth.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/05-sni.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/05-sni.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/06-sni-ticket.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/06-sni-ticket.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/07-dtls-protocol-version.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/07-dtls-protocol-version.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/08-npn.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/08-npn.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/09-alpn.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/09-alpn.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/10-resumption.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/10-resumption.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/11-dtls_resumption.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/11-dtls_resumption.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/12-ct.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/12-ct.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/13-fragmentation.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/13-fragmentation.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/14-curves.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/14-curves.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/15-certstatus.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/15-certstatus.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/16-certstatus.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/16-dtls-certstatus.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/16-dtls-certstatus.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/17-renegotiate.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/17-renegotiate.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/18-dtls-renegotiate.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/18-dtls-renegotiate.conf.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/protocol_version.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl-tests/ssltests_base.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl_test.tmpl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl_test_ctx.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl_test_ctx.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl_test_ctx_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssl_test_ctx_test.conf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/sslcorrupttest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssltest_old.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssltestlib.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/ssltestlib.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/test.cnf - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/testlib/OpenSSL/Test.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/testlib/OpenSSL/Test/Simple.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/testlib/OpenSSL/Test/Utils.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/testutil.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/testutil.h - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/threadstest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/v3-cert1.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/v3-cert2.pem - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/v3ext.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/v3nametest.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/verify_extra_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/wp_test.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/test/x509aux.c - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/tools/build.info - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/tools/c_rehash.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/TLSProxy/ClientHello.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/TLSProxy/Message.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/TLSProxy/NewSessionTicket.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/TLSProxy/Proxy.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/TLSProxy/Record.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/TLSProxy/ServerHello.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/TLSProxy/ServerKeyExchange.pm - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/build.info - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/ck_errf.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/copy.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/dofile.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/find-doc-nits.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/find-undoc-api.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/find-unused-errs - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/fipslink.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/incore - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/indent.pro - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/libcrypto.num - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/libssl.num - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/mkbuildinf.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/mkcerts.sh - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/mkdef.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/mkdir-p.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/mkerr.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/mkrc.pl - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/openssl-format-source - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/opensslwrap.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/perl/OpenSSL/Util/Pod.pm - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/point.sh - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/process_docs.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/selftest.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/shareable_image_wrap.c.in - create mode 100755 CryptoPkg/Library/OpensslLib/openssl/util/shlib_wrap.sh.in - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/su-filter.pl - create mode 100644 CryptoPkg/Library/OpensslLib/openssl/util/with_fallback.pm - -diff --git a/CryptoPkg/Library/OpensslLib/openssl/.travis-create-release.sh b/CryptoPkg/Library/OpensslLib/openssl/.travis-create-release.sh -new file mode 100644 -index 0000000..311cedd ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/.travis-create-release.sh -@@ -0,0 +1,11 @@ -+#! /bin/sh -+ -+# $1 is expected to be $TRAVIS_OS_NAME -+ -+./Configure dist -+if [ "$1" == osx ]; then -+ make NAME='_srcdist' TARFILE='_srcdist.tar' \ -+ TAR_COMMAND='$(TAR) $(TARFLAGS) -cvf -' tar -+else -+ make TARFILE='_srcdist.tar' NAME='_srcdist' dist -+fi -diff --git a/CryptoPkg/Library/OpensslLib/openssl/.travis.yml b/CryptoPkg/Library/OpensslLib/openssl/.travis.yml -new file mode 100644 -index 0000000..24f62dd ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/.travis.yml -@@ -0,0 +1,152 @@ -+dist: trusty -+sudo: required -+ -+language: c -+cache: ccache -+ -+before_install: -+ - pip install --user cpp-coveralls -+ -+addons: -+ apt: -+ packages: -+ - ccache -+ - clang-3.9 -+ - gcc-5 -+ - binutils-mingw-w64 -+ - gcc-mingw-w64 -+ sources: -+ - llvm-toolchain-trusty-3.9 -+ - ubuntu-toolchain-r-test -+ -+os: -+ - linux -+ - osx -+ -+compiler: -+ - clang -+ - gcc -+ -+env: -+ - CONFIG_OPTS="" DESTDIR="_install" -+ - CONFIG_OPTS="--debug no-shared enable-crypto-mdebug enable-rc5 enable-md2" -+ - CONFIG_OPTS="no-pic --strict-warnings" BUILDONLY="yes" -+ - CONFIG_OPTS="no-engine no-shared --strict-warnings" BUILDONLY="yes" -+ - CONFIG_OPTS="no-stdio --strict-warnings" BUILDONLY="yes" -+ - CONFIG_OPTS="no-ec" BUILDONLY="yes" -+ -+matrix: -+ include: -+ - os: linux -+ compiler: clang-3.9 -+ env: CONFIG_OPTS="--strict-warnings no-deprecated" BUILDONLY="yes" -+ - os: linux -+ compiler: gcc -+ env: CONFIG_OPTS="--debug --coverage no-asm enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-ssl3 enable-ssl3-method enable-weak-ssl-ciphers" COVERALLS="yes" -+ - os: linux -+ compiler: clang-3.9 -+ env: CONFIG_OPTS="enable-asan" -+ - os: linux -+ compiler: clang-3.9 -+ env: CONFIG_OPTS="enable-msan" -+ - os: linux -+ compiler: clang-3.9 -+ env: CONFIG_OPTS="no-asm enable-ubsan enable-rc5 enable-md2 enable-ssl3 enable-ssl3-method -fno-sanitize=alignment" -+ - os: linux -+ compiler: clang-3.9 -+ env: CONFIG_OPTS="no-asm enable-asan enable-rc5 enable-md2" -+ - os: linux -+ compiler: clang-3.9 -+ env: CONFIG_OPTS="no-stdio" -+ - os: linux -+ compiler: gcc-5 -+ env: CONFIG_OPTS="no-asm enable-ubsan enable-rc5 enable-md2 -DPEDANTIC" -+ - os: linux -+ compiler: i686-w64-mingw32-gcc -+ env: CONFIG_OPTS="no-pic" -+ - os: linux -+ compiler: i686-w64-mingw32-gcc -+ env: CONFIG_OPTS="no-stdio" -+ - os: linux -+ compiler: x86_64-w64-mingw32-gcc -+ env: CONFIG_OPTS="no-pic" -+ - os: linux -+ compiler: x86_64-w64-mingw32-gcc -+ env: CONFIG_OPTS="no-stdio" -+ exclude: -+ - os: linux -+ compiler: clang -+ - os: osx -+ compiler: gcc -+ -+before_script: -+ - if [ -n "$DESTDIR" ]; then -+ sh .travis-create-release.sh $TRAVIS_OS_NAME; -+ tar -xvzf _srcdist.tar.gz; -+ mkdir _build; -+ cd _build; -+ srcdir=../_srcdist; -+ top=..; -+ else -+ srcdir=.; -+ top=.; -+ fi -+ - if [ "$CC" == i686-w64-mingw32-gcc ]; then -+ export CROSS_COMPILE=${CC%%gcc}; unset CC; -+ $srcdir/Configure mingw $CONFIG_OPTS -Wno-pedantic-ms-format; -+ elif [ "$CC" == x86_64-w64-mingw32-gcc ]; then -+ export CROSS_COMPILE=${CC%%gcc}; unset CC; -+ $srcdir/Configure mingw64 $CONFIG_OPTS -Wno-pedantic-ms-format; -+ else -+ if which ccache >/dev/null && [ "$CC" != clang-3.9 ]; then -+ CC="ccache $CC"; -+ fi; -+ $srcdir/config -v $CONFIG_OPTS; -+ fi -+ - if [ -z "$BUILDONLY" ]; then -+ if [ -n "$CROSS_COMPILE" ]; then -+ if [ "$TRAVIS_OS_NAME" == "linux" ]; then -+ sudo dpkg --add-architecture i386; -+ sudo apt-get update; -+ sudo apt-get -yq install wine; -+ fi; -+ fi; -+ fi -+ - cd $top -+ -+script: -+ - if [ -z "$BUILDONLY" ]; then -+ make="make -s"; -+ else -+ make="make"; -+ fi -+ - if [ -n "$DESTDIR" ]; then -+ cd _build; -+ top=..; -+ else -+ top=.; -+ fi -+ - $make update -+ - $make -+ - if [ -z "$BUILDONLY" ]; then -+ if [ -n "$CROSS_COMPILE" ]; then -+ export EXE_SHELL="wine" WINEPREFIX=`pwd`; -+ fi; -+ HARNESS_VERBOSE=yes make test; -+ else -+ $make build_tests; -+ fi -+ - if [ -n "$DESTDIR" ]; then -+ mkdir "../$DESTDIR"; -+ $make install install_docs DESTDIR="../$DESTDIR"; -+ fi -+ - cd $top -+ -+after_success: -+ - if [ -n "$COVERALLS" ]; then -+ coveralls -b . --gcov-options '\-lp'; -+ fi; -+ -+notifications: -+ email: -+ secure: "xeGNgWO7aoaDgRvcZubposqMsj36aU8c6F0oHfw+rUqltCQ14IgYCUwzocmR2O+Pa7B3Cx5VjMfBFHbQaajZsfod8vu7g+aGq/zkjwbhsr/SR4dljJjFJXLGZjIalm9KgP6KInmVDuINfCqP+MHIY5lZkNI7DMcyHDhVc5nSKvCXV7xTDNgmstvh8rB/z51WfHDqGqfBtiuK5FDNxmvYK8OFJ5W94Lu9LDlizcxwK3GAj7arOui7Z5w8bQ6p4seUE3IvJL1Zbj0pZHxvNb6Zeb2Pn8QF1qLlN8YmBktD4aiw0ce4wYRiL87uLgcOxZY7SVXtv2XYFIYWapU/FKjCqa6vK93V/H9eZWEIYNMKnN3wXm2beqVdnKek3OeGJ8v0y7MbSfuLfRtBqbTSNYnpU1Zuo4MQAvHvEPuwCAYkYQajOSRplMH5sULFKptuVqNtOMfjL8jHb8AEoL1acYIk43ydxeYrzzas4fqgCDJ52573/u0RNdF1lkQBLkuM365OB8VRqtpnoxcdEIY/qBc/8TzZ24fxyrs5qdHFcxGSgpN2EP6cJMqpvkemnCNSdhxUqfzm22N7a3O8+4LFSBGOnHto/PwdsvF/01yGYL0LoZTnoO1i6x7AMJPBh+eyDU0ZjGhj/msjmqeb9C8vRqQ+1WjHrIS1iqCD0Czib8tUPD4=" -diff --git a/CryptoPkg/Library/OpensslLib/openssl/ACKNOWLEDGEMENTS b/CryptoPkg/Library/OpensslLib/openssl/ACKNOWLEDGEMENTS -new file mode 100644 -index 0000000..d21dccb ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/ACKNOWLEDGEMENTS -@@ -0,0 +1,2 @@ -+Please https://www.openssl.org/community/thanks.html for the current -+acknowledgements. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/AUTHORS b/CryptoPkg/Library/OpensslLib/openssl/AUTHORS -new file mode 100644 -index 0000000..48211a2 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/AUTHORS -@@ -0,0 +1,21 @@ -+ Andy Polyakov -+ Ben Laurie -+ Bodo M�ller -+ Emilia K�sper -+ Eric Young -+ Geoff Thorpe -+ Holger Reif -+ Kurt Roeckx -+ Lutz J�nicke -+ Mark J. Cox -+ Matt Caswell -+ Nils Larsch -+ Paul C. Sutton -+ Ralf S. Engelschall -+ Rich Salz -+ Richard Levitte -+ Stephen Henson -+ Steve Marquess -+ Tim Hudson -+ Ulf M�ller -+ Viktor Dukhovni -diff --git a/CryptoPkg/Library/OpensslLib/openssl/CHANGES b/CryptoPkg/Library/OpensslLib/openssl/CHANGES -new file mode 100644 -index 0000000..cc06923 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/CHANGES -@@ -0,0 +1,12454 @@ -+ -+ OpenSSL CHANGES -+ _______________ -+ -+ Changes between 1.1.0d and 1.1.0e [16 Feb 2017] -+ -+ *) Encrypt-Then-Mac renegotiation crash -+ -+ During a renegotiation handshake if the Encrypt-Then-Mac extension is -+ negotiated where it was not in the original handshake (or vice-versa) then -+ this can cause OpenSSL to crash (dependant on ciphersuite). Both clients -+ and servers are affected. -+ -+ This issue was reported to OpenSSL by Joe Orton (Red Hat). -+ (CVE-2017-3733) -+ [Matt Caswell] -+ -+ Changes between 1.1.0c and 1.1.0d [26 Jan 2017] -+ -+ *) Truncated packet could crash via OOB read -+ -+ If one side of an SSL/TLS path is running on a 32-bit host and a specific -+ cipher is being used, then a truncated packet can cause that host to -+ perform an out-of-bounds read, usually resulting in a crash. -+ -+ This issue was reported to OpenSSL by Robert Święcki of Google. -+ (CVE-2017-3731) -+ [Andy Polyakov] -+ -+ *) Bad (EC)DHE parameters cause a client crash -+ -+ If a malicious server supplies bad parameters for a DHE or ECDHE key -+ exchange then this can result in the client attempting to dereference a -+ NULL pointer leading to a client crash. This could be exploited in a Denial -+ of Service attack. -+ -+ This issue was reported to OpenSSL by Guido Vranken. -+ (CVE-2017-3730) -+ [Matt Caswell] -+ -+ *) BN_mod_exp may produce incorrect results on x86_64 -+ -+ There is a carry propagating bug in the x86_64 Montgomery squaring -+ procedure. No EC algorithms are affected. Analysis suggests that attacks -+ against RSA and DSA as a result of this defect would be very difficult to -+ perform and are not believed likely. Attacks against DH are considered just -+ feasible (although very difficult) because most of the work necessary to -+ deduce information about a private key may be performed offline. The amount -+ of resources required for such an attack would be very significant and -+ likely only accessible to a limited number of attackers. An attacker would -+ additionally need online access to an unpatched system using the target -+ private key in a scenario with persistent DH parameters and a private -+ key that is shared between multiple clients. For example this can occur by -+ default in OpenSSL DHE based SSL/TLS ciphersuites. Note: This issue is very -+ similar to CVE-2015-3193 but must be treated as a separate problem. -+ -+ This issue was reported to OpenSSL by the OSS-Fuzz project. -+ (CVE-2017-3732) -+ [Andy Polyakov] -+ -+ Changes between 1.1.0b and 1.1.0c [10 Nov 2016] -+ -+ *) ChaCha20/Poly1305 heap-buffer-overflow -+ -+ TLS connections using *-CHACHA20-POLY1305 ciphersuites are susceptible to -+ a DoS attack by corrupting larger payloads. This can result in an OpenSSL -+ crash. This issue is not considered to be exploitable beyond a DoS. -+ -+ This issue was reported to OpenSSL by Robert Święcki (Google Security Team) -+ (CVE-2016-7054) -+ [Richard Levitte] -+ -+ *) CMS Null dereference -+ -+ Applications parsing invalid CMS structures can crash with a NULL pointer -+ dereference. This is caused by a bug in the handling of the ASN.1 CHOICE -+ type in OpenSSL 1.1.0 which can result in a NULL value being passed to the -+ structure callback if an attempt is made to free certain invalid encodings. -+ Only CHOICE structures using a callback which do not handle NULL value are -+ affected. -+ -+ This issue was reported to OpenSSL by Tyler Nighswander of ForAllSecure. -+ (CVE-2016-7053) -+ [Stephen Henson] -+ -+ *) Montgomery multiplication may produce incorrect results -+ -+ There is a carry propagating bug in the Broadwell-specific Montgomery -+ multiplication procedure that handles input lengths divisible by, but -+ longer than 256 bits. Analysis suggests that attacks against RSA, DSA -+ and DH private keys are impossible. This is because the subroutine in -+ question is not used in operations with the private key itself and an input -+ of the attacker's direct choice. Otherwise the bug can manifest itself as -+ transient authentication and key negotiation failures or reproducible -+ erroneous outcome of public-key operations with specially crafted input. -+ Among EC algorithms only Brainpool P-512 curves are affected and one -+ presumably can attack ECDH key negotiation. Impact was not analyzed in -+ detail, because pre-requisites for attack are considered unlikely. Namely -+ multiple clients have to choose the curve in question and the server has to -+ share the private key among them, neither of which is default behaviour. -+ Even then only clients that chose the curve will be affected. -+ -+ This issue was publicly reported as transient failures and was not -+ initially recognized as a security issue. Thanks to Richard Morgan for -+ providing reproducible case. -+ (CVE-2016-7055) -+ [Andy Polyakov] -+ -+ *) OpenSSL now fails if it receives an unrecognised record type in TLS1.0 -+ or TLS1.1. Previously this only happened in SSLv3 and TLS1.2. This is to -+ prevent issues where no progress is being made and the peer continually -+ sends unrecognised record types, using up resources processing them. -+ [Matt Caswell] -+ -+ *) Removed automatic addition of RPATH in shared libraries and executables, -+ as this was a remainder from OpenSSL 1.0.x and isn't needed any more. -+ [Richard Levitte] -+ -+ Changes between 1.1.0a and 1.1.0b [26 Sep 2016] -+ -+ *) Fix Use After Free for large message sizes -+ -+ The patch applied to address CVE-2016-6307 resulted in an issue where if a -+ message larger than approx 16k is received then the underlying buffer to -+ store the incoming message is reallocated and moved. Unfortunately a -+ dangling pointer to the old location is left which results in an attempt to -+ write to the previously freed location. This is likely to result in a -+ crash, however it could potentially lead to execution of arbitrary code. -+ -+ This issue only affects OpenSSL 1.1.0a. -+ -+ This issue was reported to OpenSSL by Robert Święcki. -+ (CVE-2016-6309) -+ [Matt Caswell] -+ -+ Changes between 1.1.0 and 1.1.0a [22 Sep 2016] -+ -+ *) OCSP Status Request extension unbounded memory growth -+ -+ A malicious client can send an excessively large OCSP Status Request -+ extension. If that client continually requests renegotiation, sending a -+ large OCSP Status Request extension each time, then there will be unbounded -+ memory growth on the server. This will eventually lead to a Denial Of -+ Service attack through memory exhaustion. Servers with a default -+ configuration are vulnerable even if they do not support OCSP. Builds using -+ the "no-ocsp" build time option are not affected. -+ -+ This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) -+ (CVE-2016-6304) -+ [Matt Caswell] -+ -+ *) SSL_peek() hang on empty record -+ -+ OpenSSL 1.1.0 SSL/TLS will hang during a call to SSL_peek() if the peer -+ sends an empty record. This could be exploited by a malicious peer in a -+ Denial Of Service attack. -+ -+ This issue was reported to OpenSSL by Alex Gaynor. -+ (CVE-2016-6305) -+ [Matt Caswell] -+ -+ *) Excessive allocation of memory in tls_get_message_header() and -+ dtls1_preprocess_fragment() -+ -+ A (D)TLS message includes 3 bytes for its length in the header for the -+ message. This would allow for messages up to 16Mb in length. Messages of -+ this length are excessive and OpenSSL includes a check to ensure that a -+ peer is sending reasonably sized messages in order to avoid too much memory -+ being consumed to service a connection. A flaw in the logic of version -+ 1.1.0 means that memory for the message is allocated too early, prior to -+ the excessive message length check. Due to way memory is allocated in -+ OpenSSL this could mean an attacker could force up to 21Mb to be allocated -+ to service a connection. This could lead to a Denial of Service through -+ memory exhaustion. However, the excessive message length check still takes -+ place, and this would cause the connection to immediately fail. Assuming -+ that the application calls SSL_free() on the failed conneciton in a timely -+ manner then the 21Mb of allocated memory will then be immediately freed -+ again. Therefore the excessive memory allocation will be transitory in -+ nature. This then means that there is only a security impact if: -+ -+ 1) The application does not call SSL_free() in a timely manner in the event -+ that the connection fails -+ or -+ 2) The application is working in a constrained environment where there is -+ very little free memory -+ or -+ 3) The attacker initiates multiple connection attempts such that there are -+ multiple connections in a state where memory has been allocated for the -+ connection; SSL_free() has not yet been called; and there is insufficient -+ memory to service the multiple requests. -+ -+ Except in the instance of (1) above any Denial Of Service is likely to be -+ transitory because as soon as the connection fails the memory is -+ subsequently freed again in the SSL_free() call. However there is an -+ increased risk during this period of application crashes due to the lack of -+ memory - which would then mean a more serious Denial of Service. -+ -+ This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) -+ (CVE-2016-6307 and CVE-2016-6308) -+ [Matt Caswell] -+ -+ *) solaris-x86-cc, i.e. 32-bit configuration with vendor compiler, -+ had to be removed. Primary reason is that vendor assembler can't -+ assemble our modules with -KPIC flag. As result it, assembly -+ support, was not even available as option. But its lack means -+ lack of side-channel resistant code, which is incompatible with -+ security by todays standards. Fortunately gcc is readily available -+ prepackaged option, which we firmly point at... -+ [Andy Polyakov] -+ -+ Changes between 1.0.2h and 1.1.0 [25 Aug 2016] -+ -+ *) Windows command-line tool supports UTF-8 opt-in option for arguments -+ and console input. Setting OPENSSL_WIN32_UTF8 environment variable -+ (to any value) allows Windows user to access PKCS#12 file generated -+ with Windows CryptoAPI and protected with non-ASCII password, as well -+ as files generated under UTF-8 locale on Linux also protected with -+ non-ASCII password. -+ [Andy Polyakov] -+ -+ *) To mitigate the SWEET32 attack (CVE-2016-2183), 3DES cipher suites -+ have been disabled by default and removed from DEFAULT, just like RC4. -+ See the RC4 item below to re-enable both. -+ [Rich Salz] -+ -+ *) The method for finding the storage location for the Windows RAND seed file -+ has changed. First we check %RANDFILE%. If that is not set then we check -+ the directories %HOME%, %USERPROFILE% and %SYSTEMROOT% in that order. If -+ all else fails we fall back to C:\. -+ [Matt Caswell] -+ -+ *) The EVP_EncryptUpdate() function has had its return type changed from void -+ to int. A return of 0 indicates and error while a return of 1 indicates -+ success. -+ [Matt Caswell] -+ -+ *) The flags RSA_FLAG_NO_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME and -+ DH_FLAG_NO_EXP_CONSTTIME which previously provided the ability to switch -+ off the constant time implementation for RSA, DSA and DH have been made -+ no-ops and deprecated. -+ [Matt Caswell] -+ -+ *) Windows RAND implementation was simplified to only get entropy by -+ calling CryptGenRandom(). Various other RAND-related tickets -+ were also closed. -+ [Joseph Wylie Yandle, Rich Salz] -+ -+ *) The stack and lhash API's were renamed to start with OPENSSL_SK_ -+ and OPENSSL_LH_, respectively. The old names are available -+ with API compatibility. They new names are now completely documented. -+ [Rich Salz] -+ -+ *) Unify TYPE_up_ref(obj) methods signature. -+ SSL_CTX_up_ref(), SSL_up_ref(), X509_up_ref(), EVP_PKEY_up_ref(), -+ X509_CRL_up_ref(), X509_OBJECT_up_ref_count() methods are now returning an -+ int (instead of void) like all others TYPE_up_ref() methods. -+ So now these methods also check the return value of CRYPTO_atomic_add(), -+ and the validity of object reference counter. -+ [fdasilvayy@gmail.com] -+ -+ *) With Windows Visual Studio builds, the .pdb files are installed -+ alongside the installed libraries and executables. For a static -+ library installation, ossl_static.pdb is the associate compiler -+ generated .pdb file to be used when linking programs. -+ [Richard Levitte] -+ -+ *) Remove openssl.spec. Packaging files belong with the packagers. -+ [Richard Levitte] -+ -+ *) Automatic Darwin/OSX configuration has had a refresh, it will now -+ recognise x86_64 architectures automatically. You can still decide -+ to build for a different bitness with the environment variable -+ KERNEL_BITS (can be 32 or 64), for example: -+ -+ KERNEL_BITS=32 ./config -+ -+ [Richard Levitte] -+ -+ *) Change default algorithms in pkcs8 utility to use PKCS#5 v2.0, -+ 256 bit AES and HMAC with SHA256. -+ [Steve Henson] -+ -+ *) Remove support for MIPS o32 ABI on IRIX (and IRIX only). -+ [Andy Polyakov] -+ -+ *) Triple-DES ciphers have been moved from HIGH to MEDIUM. -+ [Rich Salz] -+ -+ *) To enable users to have their own config files and build file templates, -+ Configure looks in the directory indicated by the environment variable -+ OPENSSL_LOCAL_CONFIG_DIR as well as the in-source Configurations/ -+ directory. On VMS, OPENSSL_LOCAL_CONFIG_DIR is expected to be a logical -+ name and is used as is. -+ [Richard Levitte] -+ -+ *) The following datatypes were made opaque: X509_OBJECT, X509_STORE_CTX, -+ X509_STORE, X509_LOOKUP, and X509_LOOKUP_METHOD. The unused type -+ X509_CERT_FILE_CTX was removed. -+ [Rich Salz] -+ -+ *) "shared" builds are now the default. To create only static libraries use -+ the "no-shared" Configure option. -+ [Matt Caswell] -+ -+ *) Remove the no-aes, no-hmac, no-rsa, no-sha and no-md5 Configure options. -+ All of these option have not worked for some while and are fundamental -+ algorithms. -+ [Matt Caswell] -+ -+ *) Make various cleanup routines no-ops and mark them as deprecated. Most -+ global cleanup functions are no longer required because they are handled -+ via auto-deinit (see OPENSSL_init_crypto and OPENSSL_init_ssl man pages). -+ Explicitly de-initing can cause problems (e.g. where a library that uses -+ OpenSSL de-inits, but an application is still using it). The affected -+ functions are CONF_modules_free(), ENGINE_cleanup(), OBJ_cleanup(), -+ EVP_cleanup(), BIO_sock_cleanup(), CRYPTO_cleanup_all_ex_data(), -+ RAND_cleanup(), SSL_COMP_free_compression_methods(), ERR_free_strings() and -+ COMP_zlib_cleanup(). -+ [Matt Caswell] -+ -+ *) --strict-warnings no longer enables runtime debugging options -+ such as REF_DEBUG. Instead, debug options are automatically -+ enabled with '--debug' builds. -+ [Andy Polyakov, Emilia Käsper] -+ -+ *) Made DH and DH_METHOD opaque. The structures for managing DH objects -+ have been moved out of the public header files. New functions for managing -+ these have been added. -+ [Matt Caswell] -+ -+ *) Made RSA and RSA_METHOD opaque. The structures for managing RSA -+ objects have been moved out of the public header files. New -+ functions for managing these have been added. -+ [Richard Levitte] -+ -+ *) Made DSA and DSA_METHOD opaque. The structures for managing DSA objects -+ have been moved out of the public header files. New functions for managing -+ these have been added. -+ [Matt Caswell] -+ -+ *) Made BIO and BIO_METHOD opaque. The structures for managing BIOs have been -+ moved out of the public header files. New functions for managing these -+ have been added. -+ [Matt Caswell] -+ -+ *) Removed no-rijndael as a config option. Rijndael is an old name for AES. -+ [Matt Caswell] -+ -+ *) Removed the mk1mf build scripts. -+ [Richard Levitte] -+ -+ *) Headers are now wrapped, if necessary, with OPENSSL_NO_xxx, so -+ it is always safe to #include a header now. -+ [Rich Salz] -+ -+ *) Removed the aged BC-32 config and all its supporting scripts -+ [Richard Levitte] -+ -+ *) Removed support for Ultrix, Netware, and OS/2. -+ [Rich Salz] -+ -+ *) Add support for HKDF. -+ [Alessandro Ghedini] -+ -+ *) Add support for blake2b and blake2s -+ [Bill Cox] -+ -+ *) Added support for "pipelining". Ciphers that have the -+ EVP_CIPH_FLAG_PIPELINE flag set have a capability to process multiple -+ encryptions/decryptions simultaneously. There are currently no built-in -+ ciphers with this property but the expectation is that engines will be able -+ to offer it to significantly improve throughput. Support has been extended -+ into libssl so that multiple records for a single connection can be -+ processed in one go (for >=TLS 1.1). -+ [Matt Caswell] -+ -+ *) Added the AFALG engine. This is an async capable engine which is able to -+ offload work to the Linux kernel. In this initial version it only supports -+ AES128-CBC. The kernel must be version 4.1.0 or greater. -+ [Catriona Lucey] -+ -+ *) OpenSSL now uses a new threading API. It is no longer necessary to -+ set locking callbacks to use OpenSSL in a multi-threaded environment. There -+ are two supported threading models: pthreads and windows threads. It is -+ also possible to configure OpenSSL at compile time for "no-threads". The -+ old threading API should no longer be used. The functions have been -+ replaced with "no-op" compatibility macros. -+ [Alessandro Ghedini, Matt Caswell] -+ -+ *) Modify behavior of ALPN to invoke callback after SNI/servername -+ callback, such that updates to the SSL_CTX affect ALPN. -+ [Todd Short] -+ -+ *) Add SSL_CIPHER queries for authentication and key-exchange. -+ [Todd Short] -+ -+ *) Changes to the DEFAULT cipherlist: -+ - Prefer (EC)DHE handshakes over plain RSA. -+ - Prefer AEAD ciphers over legacy ciphers. -+ - Prefer ECDSA over RSA when both certificates are available. -+ - Prefer TLSv1.2 ciphers/PRF. -+ - Remove DSS, SEED, IDEA, CAMELLIA, and AES-CCM from the -+ default cipherlist. -+ [Emilia Käsper] -+ -+ *) Change the ECC default curve list to be this, in order: x25519, -+ secp256r1, secp521r1, secp384r1. -+ [Rich Salz] -+ -+ *) RC4 based libssl ciphersuites are now classed as "weak" ciphers and are -+ disabled by default. They can be re-enabled using the -+ enable-weak-ssl-ciphers option to Configure. -+ [Matt Caswell] -+ -+ *) If the server has ALPN configured, but supports no protocols that the -+ client advertises, send a fatal "no_application_protocol" alert. -+ This behaviour is SHALL in RFC 7301, though it isn't universally -+ implemented by other servers. -+ [Emilia Käsper] -+ -+ *) Add X25519 support. -+ Add ASN.1 and EVP_PKEY methods for X25519. This includes support -+ for public and private key encoding using the format documented in -+ draft-ietf-curdle-pkix-02. The coresponding EVP_PKEY method supports -+ key generation and key derivation. -+ -+ TLS support complies with draft-ietf-tls-rfc4492bis-08 and uses -+ X25519(29). -+ [Steve Henson] -+ -+ *) Deprecate SRP_VBASE_get_by_user. -+ SRP_VBASE_get_by_user had inconsistent memory management behaviour. -+ In order to fix an unavoidable memory leak (CVE-2016-0798), -+ SRP_VBASE_get_by_user was changed to ignore the "fake user" SRP -+ seed, even if the seed is configured. -+ -+ Users should use SRP_VBASE_get1_by_user instead. Note that in -+ SRP_VBASE_get1_by_user, caller must free the returned value. Note -+ also that even though configuring the SRP seed attempts to hide -+ invalid usernames by continuing the handshake with fake -+ credentials, this behaviour is not constant time and no strong -+ guarantees are made that the handshake is indistinguishable from -+ that of a valid user. -+ [Emilia Käsper] -+ -+ *) Configuration change; it's now possible to build dynamic engines -+ without having to build shared libraries and vice versa. This -+ only applies to the engines in engines/, those in crypto/engine/ -+ will always be built into libcrypto (i.e. "static"). -+ -+ Building dynamic engines is enabled by default; to disable, use -+ the configuration option "disable-dynamic-engine". -+ -+ The only requirements for building dynamic engines are the -+ presence of the DSO module and building with position independent -+ code, so they will also automatically be disabled if configuring -+ with "disable-dso" or "disable-pic". -+ -+ The macros OPENSSL_NO_STATIC_ENGINE and OPENSSL_NO_DYNAMIC_ENGINE -+ are also taken away from openssl/opensslconf.h, as they are -+ irrelevant. -+ [Richard Levitte] -+ -+ *) Configuration change; if there is a known flag to compile -+ position independent code, it will always be applied on the -+ libcrypto and libssl object files, and never on the application -+ object files. This means other libraries that use routines from -+ libcrypto / libssl can be made into shared libraries regardless -+ of how OpenSSL was configured. -+ -+ If this isn't desirable, the configuration options "disable-pic" -+ or "no-pic" can be used to disable the use of PIC. This will -+ also disable building shared libraries and dynamic engines. -+ [Richard Levitte] -+ -+ *) Removed JPAKE code. It was experimental and has no wide use. -+ [Rich Salz] -+ -+ *) The INSTALL_PREFIX Makefile variable has been renamed to -+ DESTDIR. That makes for less confusion on what this variable -+ is for. Also, the configuration option --install_prefix is -+ removed. -+ [Richard Levitte] -+ -+ *) Heartbeat for TLS has been removed and is disabled by default -+ for DTLS; configure with enable-heartbeats. Code that uses the -+ old #define's might need to be updated. -+ [Emilia Käsper, Rich Salz] -+ -+ *) Rename REF_CHECK to REF_DEBUG. -+ [Rich Salz] -+ -+ *) New "unified" build system -+ -+ The "unified" build system is aimed to be a common system for all -+ platforms we support. With it comes new support for VMS. -+ -+ This system builds supports building in a different directory tree -+ than the source tree. It produces one Makefile (for unix family -+ or lookalikes), or one descrip.mms (for VMS). -+ -+ The source of information to make the Makefile / descrip.mms is -+ small files called 'build.info', holding the necessary -+ information for each directory with source to compile, and a -+ template in Configurations, like unix-Makefile.tmpl or -+ descrip.mms.tmpl. -+ -+ With this change, the library names were also renamed on Windows -+ and on VMS. They now have names that are closer to the standard -+ on Unix, and include the major version number, and in certain -+ cases, the architecture they are built for. See "Notes on shared -+ libraries" in INSTALL. -+ -+ We rely heavily on the perl module Text::Template. -+ [Richard Levitte] -+ -+ *) Added support for auto-initialisation and de-initialisation of the library. -+ OpenSSL no longer requires explicit init or deinit routines to be called, -+ except in certain circumstances. See the OPENSSL_init_crypto() and -+ OPENSSL_init_ssl() man pages for further information. -+ [Matt Caswell] -+ -+ *) The arguments to the DTLSv1_listen function have changed. Specifically the -+ "peer" argument is now expected to be a BIO_ADDR object. -+ -+ *) Rewrite of BIO networking library. The BIO library lacked consistent -+ support of IPv6, and adding it required some more extensive -+ modifications. This introduces the BIO_ADDR and BIO_ADDRINFO types, -+ which hold all types of addresses and chains of address information. -+ It also introduces a new API, with functions like BIO_socket, -+ BIO_connect, BIO_listen, BIO_lookup and a rewrite of BIO_accept. -+ The source/sink BIOs BIO_s_connect, BIO_s_accept and BIO_s_datagram -+ have been adapted accordingly. -+ [Richard Levitte] -+ -+ *) RSA_padding_check_PKCS1_type_1 now accepts inputs with and without -+ the leading 0-byte. -+ [Emilia Käsper] -+ -+ *) CRIME protection: disable compression by default, even if OpenSSL is -+ compiled with zlib enabled. Applications can still enable compression -+ by calling SSL_CTX_clear_options(ctx, SSL_OP_NO_COMPRESSION), or by -+ using the SSL_CONF library to configure compression. -+ [Emilia Käsper] -+ -+ *) The signature of the session callback configured with -+ SSL_CTX_sess_set_get_cb was changed. The read-only input buffer -+ was explicitly marked as 'const unsigned char*' instead of -+ 'unsigned char*'. -+ [Emilia Käsper] -+ -+ *) Always DPURIFY. Remove the use of uninitialized memory in the -+ RNG, and other conditional uses of DPURIFY. This makes -DPURIFY a no-op. -+ [Emilia Käsper] -+ -+ *) Removed many obsolete configuration items, including -+ DES_PTR, DES_RISC1, DES_RISC2, DES_INT -+ MD2_CHAR, MD2_INT, MD2_LONG -+ BF_PTR, BF_PTR2 -+ IDEA_SHORT, IDEA_LONG -+ RC2_SHORT, RC2_LONG, RC4_LONG, RC4_CHUNK, RC4_INDEX -+ [Rich Salz, with advice from Andy Polyakov] -+ -+ *) Many BN internals have been moved to an internal header file. -+ [Rich Salz with help from Andy Polyakov] -+ -+ *) Configuration and writing out the results from it has changed. -+ Files such as Makefile include/openssl/opensslconf.h and are now -+ produced through general templates, such as Makefile.in and -+ crypto/opensslconf.h.in and some help from the perl module -+ Text::Template. -+ -+ Also, the center of configuration information is no longer -+ Makefile. Instead, Configure produces a perl module in -+ configdata.pm which holds most of the config data (in the hash -+ table %config), the target data that comes from the target -+ configuration in one of the Configurations/*.conf files (in -+ %target). -+ [Richard Levitte] -+ -+ *) To clarify their intended purposes, the Configure options -+ --prefix and --openssldir change their semantics, and become more -+ straightforward and less interdependent. -+ -+ --prefix shall be used exclusively to give the location INSTALLTOP -+ where programs, scripts, libraries, include files and manuals are -+ going to be installed. The default is now /usr/local. -+ -+ --openssldir shall be used exclusively to give the default -+ location OPENSSLDIR where certificates, private keys, CRLs are -+ managed. This is also where the default openssl.cnf gets -+ installed. -+ If the directory given with this option is a relative path, the -+ values of both the --prefix value and the --openssldir value will -+ be combined to become OPENSSLDIR. -+ The default for --openssldir is INSTALLTOP/ssl. -+ -+ Anyone who uses --openssldir to specify where OpenSSL is to be -+ installed MUST change to use --prefix instead. -+ [Richard Levitte] -+ -+ *) The GOST engine was out of date and therefore it has been removed. An up -+ to date GOST engine is now being maintained in an external repository. -+ See: https://wiki.openssl.org/index.php/Binaries. Libssl still retains -+ support for GOST ciphersuites (these are only activated if a GOST engine -+ is present). -+ [Matt Caswell] -+ -+ *) EGD is no longer supported by default; use enable-egd when -+ configuring. -+ [Ben Kaduk and Rich Salz] -+ -+ *) The distribution now has Makefile.in files, which are used to -+ create Makefile's when Configure is run. *Configure must be run -+ before trying to build now.* -+ [Rich Salz] -+ -+ *) The return value for SSL_CIPHER_description() for error conditions -+ has changed. -+ [Rich Salz] -+ -+ *) Support for RFC6698/RFC7671 DANE TLSA peer authentication. -+ -+ Obtaining and performing DNSSEC validation of TLSA records is -+ the application's responsibility. The application provides -+ the TLSA records of its choice to OpenSSL, and these are then -+ used to authenticate the peer. -+ -+ The TLSA records need not even come from DNS. They can, for -+ example, be used to implement local end-entity certificate or -+ trust-anchor "pinning", where the "pin" data takes the form -+ of TLSA records, which can augment or replace verification -+ based on the usual WebPKI public certification authorities. -+ [Viktor Dukhovni] -+ -+ *) Revert default OPENSSL_NO_DEPRECATED setting. Instead OpenSSL -+ continues to support deprecated interfaces in default builds. -+ However, applications are strongly advised to compile their -+ source files with -DOPENSSL_API_COMPAT=0x10100000L, which hides -+ the declarations of all interfaces deprecated in 0.9.8, 1.0.0 -+ or the 1.1.0 releases. -+ -+ In environments in which all applications have been ported to -+ not use any deprecated interfaces OpenSSL's Configure script -+ should be used with the --api=1.1.0 option to entirely remove -+ support for the deprecated features from the library and -+ unconditionally disable them in the installed headers. -+ Essentially the same effect can be achieved with the "no-deprecated" -+ argument to Configure, except that this will always restrict -+ the build to just the latest API, rather than a fixed API -+ version. -+ -+ As applications are ported to future revisions of the API, -+ they should update their compile-time OPENSSL_API_COMPAT define -+ accordingly, but in most cases should be able to continue to -+ compile with later releases. -+ -+ The OPENSSL_API_COMPAT versions for 1.0.0, and 0.9.8 are -+ 0x10000000L and 0x00908000L, respectively. However those -+ versions did not support the OPENSSL_API_COMPAT feature, and -+ so applications are not typically tested for explicit support -+ of just the undeprecated features of either release. -+ [Viktor Dukhovni] -+ -+ *) Add support for setting the minimum and maximum supported protocol. -+ It can bet set via the SSL_set_min_proto_version() and -+ SSL_set_max_proto_version(), or via the SSL_CONF's MinProtocol and -+ MaxProtcol. It's recommended to use the new APIs to disable -+ protocols instead of disabling individual protocols using -+ SSL_set_options() or SSL_CONF's Protocol. This change also -+ removes support for disabling TLS 1.2 in the OpenSSL TLS -+ client at compile time by defining OPENSSL_NO_TLS1_2_CLIENT. -+ [Kurt Roeckx] -+ -+ *) Support for ChaCha20 and Poly1305 added to libcrypto and libssl. -+ [Andy Polyakov] -+ -+ *) New EC_KEY_METHOD, this replaces the older ECDSA_METHOD and ECDH_METHOD -+ and integrates ECDSA and ECDH functionality into EC. Implementations can -+ now redirect key generation and no longer need to convert to or from -+ ECDSA_SIG format. -+ -+ Note: the ecdsa.h and ecdh.h headers are now no longer needed and just -+ include the ec.h header file instead. -+ [Steve Henson] -+ -+ *) Remove support for all 40 and 56 bit ciphers. This includes all the export -+ ciphers who are no longer supported and drops support the ephemeral RSA key -+ exchange. The LOW ciphers currently doesn't have any ciphers in it. -+ [Kurt Roeckx] -+ -+ *) Made EVP_MD_CTX, EVP_MD, EVP_CIPHER_CTX, EVP_CIPHER and HMAC_CTX -+ opaque. For HMAC_CTX, the following constructors and destructors -+ were added: -+ -+ HMAC_CTX *HMAC_CTX_new(void); -+ void HMAC_CTX_free(HMAC_CTX *ctx); -+ -+ For EVP_MD and EVP_CIPHER, complete APIs to create, fill and -+ destroy such methods has been added. See EVP_MD_meth_new(3) and -+ EVP_CIPHER_meth_new(3) for documentation. -+ -+ Additional changes: -+ 1) EVP_MD_CTX_cleanup(), EVP_CIPHER_CTX_cleanup() and -+ HMAC_CTX_cleanup() were removed. HMAC_CTX_reset() and -+ EVP_MD_CTX_reset() should be called instead to reinitialise -+ an already created structure. -+ 2) For consistency with the majority of our object creators and -+ destructors, EVP_MD_CTX_(create|destroy) were renamed to -+ EVP_MD_CTX_(new|free). The old names are retained as macros -+ for deprecated builds. -+ [Richard Levitte] -+ -+ *) Added ASYNC support. Libcrypto now includes the async sub-library to enable -+ cryptographic operations to be performed asynchronously as long as an -+ asynchronous capable engine is used. See the ASYNC_start_job() man page for -+ further details. Libssl has also had this capability integrated with the -+ introduction of the new mode SSL_MODE_ASYNC and associated error -+ SSL_ERROR_WANT_ASYNC. See the SSL_CTX_set_mode() and SSL_get_error() man -+ pages. This work was developed in partnership with Intel Corp. -+ [Matt Caswell] -+ -+ *) SSL_{CTX_}set_ecdh_auto() has been removed and ECDH is support is -+ always enabled now. If you want to disable the support you should -+ exclude it using the list of supported ciphers. This also means that the -+ "-no_ecdhe" option has been removed from s_server. -+ [Kurt Roeckx] -+ -+ *) SSL_{CTX}_set_tmp_ecdh() which can set 1 EC curve now internally calls -+ SSL_{CTX_}set1_curves() which can set a list. -+ [Kurt Roeckx] -+ -+ *) Remove support for SSL_{CTX_}set_tmp_ecdh_callback(). You should set the -+ curve you want to support using SSL_{CTX_}set1_curves(). -+ [Kurt Roeckx] -+ -+ *) State machine rewrite. The state machine code has been significantly -+ refactored in order to remove much duplication of code and solve issues -+ with the old code (see ssl/statem/README for further details). This change -+ does have some associated API changes. Notably the SSL_state() function -+ has been removed and replaced by SSL_get_state which now returns an -+ "OSSL_HANDSHAKE_STATE" instead of an int. SSL_set_state() has been removed -+ altogether. The previous handshake states defined in ssl.h and ssl3.h have -+ also been removed. -+ [Matt Caswell] -+ -+ *) All instances of the string "ssleay" in the public API were replaced -+ with OpenSSL (case-matching; e.g., OPENSSL_VERSION for #define's) -+ Some error codes related to internal RSA_eay API's were renamed. -+ [Rich Salz] -+ -+ *) The demo files in crypto/threads were moved to demo/threads. -+ [Rich Salz] -+ -+ *) Removed obsolete engines: 4758cca, aep, atalla, cswift, nuron, gmp, -+ sureware and ubsec. -+ [Matt Caswell, Rich Salz] -+ -+ *) New ASN.1 embed macro. -+ -+ New ASN.1 macro ASN1_EMBED. This is the same as ASN1_SIMPLE except the -+ structure is not allocated: it is part of the parent. That is instead of -+ -+ FOO *x; -+ -+ it must be: -+ -+ FOO x; -+ -+ This reduces memory fragmentation and make it impossible to accidentally -+ set a mandatory field to NULL. -+ -+ This currently only works for some fields specifically a SEQUENCE, CHOICE, -+ or ASN1_STRING type which is part of a parent SEQUENCE. Since it is -+ equivalent to ASN1_SIMPLE it cannot be tagged, OPTIONAL, SET OF or -+ SEQUENCE OF. -+ [Steve Henson] -+ -+ *) Remove EVP_CHECK_DES_KEY, a compile-time option that never compiled. -+ [Emilia Käsper] -+ -+ *) Removed DES and RC4 ciphersuites from DEFAULT. Also removed RC2 although -+ in 1.0.2 EXPORT was already removed and the only RC2 ciphersuite is also -+ an EXPORT one. COMPLEMENTOFDEFAULT has been updated accordingly to add -+ DES and RC4 ciphersuites. -+ [Matt Caswell] -+ -+ *) Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs. -+ This changes the decoding behaviour for some invalid messages, -+ though the change is mostly in the more lenient direction, and -+ legacy behaviour is preserved as much as possible. -+ [Emilia Käsper] -+ -+ *) Fix no-stdio build. -+ [ David Woodhouse and also -+ Ivan Nestlerode ] -+ -+ *) New testing framework -+ The testing framework has been largely rewritten and is now using -+ perl and the perl modules Test::Harness and an extended variant of -+ Test::More called OpenSSL::Test to do its work. All test scripts in -+ test/ have been rewritten into test recipes, and all direct calls to -+ executables in test/Makefile have become individual recipes using the -+ simplified testing OpenSSL::Test::Simple. -+ -+ For documentation on our testing modules, do: -+ -+ perldoc test/testlib/OpenSSL/Test/Simple.pm -+ perldoc test/testlib/OpenSSL/Test.pm -+ -+ [Richard Levitte] -+ -+ *) Revamped memory debug; only -DCRYPTO_MDEBUG and -DCRYPTO_MDEBUG_ABORT -+ are used; the latter aborts on memory leaks (usually checked on exit). -+ Some undocumented "set malloc, etc., hooks" functions were removed -+ and others were changed. All are now documented. -+ [Rich Salz] -+ -+ *) In DSA_generate_parameters_ex, if the provided seed is too short, -+ return an error -+ [Rich Salz and Ismo Puustinen ] -+ -+ *) Rewrite PSK to support ECDHE_PSK, DHE_PSK and RSA_PSK. Add ciphersuites -+ from RFC4279, RFC4785, RFC5487, RFC5489. -+ -+ Thanks to Christian J. Dietrich and Giuseppe D'Angelo for the -+ original RSA_PSK patch. -+ [Steve Henson] -+ -+ *) Dropped support for the SSL3_FLAGS_DELAY_CLIENT_FINISHED flag. This SSLeay -+ era flag was never set throughout the codebase (only read). Also removed -+ SSL3_FLAGS_POP_BUFFER which was only used if -+ SSL3_FLAGS_DELAY_CLIENT_FINISHED was also set. -+ [Matt Caswell] -+ -+ *) Changed the default name options in the "ca", "crl", "req" and "x509" -+ to be "oneline" instead of "compat". -+ [Richard Levitte] -+ -+ *) Remove SSL_OP_TLS_BLOCK_PADDING_BUG. This is SSLeay legacy, we're -+ not aware of clients that still exhibit this bug, and the workaround -+ hasn't been working properly for a while. -+ [Emilia Käsper] -+ -+ *) The return type of BIO_number_read() and BIO_number_written() as well as -+ the corresponding num_read and num_write members in the BIO structure has -+ changed from unsigned long to uint64_t. On platforms where an unsigned -+ long is 32 bits (e.g. Windows) these counters could overflow if >4Gb is -+ transferred. -+ [Matt Caswell] -+ -+ *) Given the pervasive nature of TLS extensions it is inadvisable to run -+ OpenSSL without support for them. It also means that maintaining -+ the OPENSSL_NO_TLSEXT option within the code is very invasive (and probably -+ not well tested). Therefore the OPENSSL_NO_TLSEXT option has been removed. -+ [Matt Caswell] -+ -+ *) Removed support for the two export grade static DH ciphersuites -+ EXP-DH-RSA-DES-CBC-SHA and EXP-DH-DSS-DES-CBC-SHA. These two ciphersuites -+ were newly added (along with a number of other static DH ciphersuites) to -+ 1.0.2. However the two export ones have *never* worked since they were -+ introduced. It seems strange in any case to be adding new export -+ ciphersuites, and given "logjam" it also does not seem correct to fix them. -+ [Matt Caswell] -+ -+ *) Version negotiation has been rewritten. In particular SSLv23_method(), -+ SSLv23_client_method() and SSLv23_server_method() have been deprecated, -+ and turned into macros which simply call the new preferred function names -+ TLS_method(), TLS_client_method() and TLS_server_method(). All new code -+ should use the new names instead. Also as part of this change the ssl23.h -+ header file has been removed. -+ [Matt Caswell] -+ -+ *) Support for Kerberos ciphersuites in TLS (RFC2712) has been removed. This -+ code and the associated standard is no longer considered fit-for-purpose. -+ [Matt Caswell] -+ -+ *) RT2547 was closed. When generating a private key, try to make the -+ output file readable only by the owner. This behavior change might -+ be noticeable when interacting with other software. -+ -+ *) Documented all exdata functions. Added CRYPTO_free_ex_index. -+ Added a test. -+ [Rich Salz] -+ -+ *) Added HTTP GET support to the ocsp command. -+ [Rich Salz] -+ -+ *) Changed default digest for the dgst and enc commands from MD5 to -+ sha256 -+ [Rich Salz] -+ -+ *) RAND_pseudo_bytes has been deprecated. Users should use RAND_bytes instead. -+ [Matt Caswell] -+ -+ *) Added support for TLS extended master secret from -+ draft-ietf-tls-session-hash-03.txt. Thanks for Alfredo Pironti for an -+ initial patch which was a great help during development. -+ [Steve Henson] -+ -+ *) All libssl internal structures have been removed from the public header -+ files, and the OPENSSL_NO_SSL_INTERN option has been removed (since it is -+ now redundant). Users should not attempt to access internal structures -+ directly. Instead they should use the provided API functions. -+ [Matt Caswell] -+ -+ *) config has been changed so that by default OPENSSL_NO_DEPRECATED is used. -+ Access to deprecated functions can be re-enabled by running config with -+ "enable-deprecated". In addition applications wishing to use deprecated -+ functions must define OPENSSL_USE_DEPRECATED. Note that this new behaviour -+ will, by default, disable some transitive includes that previously existed -+ in the header files (e.g. ec.h will no longer, by default, include bn.h) -+ [Matt Caswell] -+ -+ *) Added support for OCB mode. OpenSSL has been granted a patent license -+ compatible with the OpenSSL license for use of OCB. Details are available -+ at https://www.openssl.org/source/OCB-patent-grant-OpenSSL.pdf. Support -+ for OCB can be removed by calling config with no-ocb. -+ [Matt Caswell] -+ -+ *) SSLv2 support has been removed. It still supports receiving a SSLv2 -+ compatible client hello. -+ [Kurt Roeckx] -+ -+ *) Increased the minimal RSA keysize from 256 to 512 bits [Rich Salz], -+ done while fixing the error code for the key-too-small case. -+ [Annie Yousar ] -+ -+ *) CA.sh has been removmed; use CA.pl instead. -+ [Rich Salz] -+ -+ *) Removed old DES API. -+ [Rich Salz] -+ -+ *) Remove various unsupported platforms: -+ Sony NEWS4 -+ BEOS and BEOS_R5 -+ NeXT -+ SUNOS -+ MPE/iX -+ Sinix/ReliantUNIX RM400 -+ DGUX -+ NCR -+ Tandem -+ Cray -+ 16-bit platforms such as WIN16 -+ [Rich Salz] -+ -+ *) Clean up OPENSSL_NO_xxx #define's -+ Use setbuf() and remove OPENSSL_NO_SETVBUF_IONBF -+ Rename OPENSSL_SYSNAME_xxx to OPENSSL_SYS_xxx -+ OPENSSL_NO_EC{DH,DSA} merged into OPENSSL_NO_EC -+ OPENSSL_NO_RIPEMD160, OPENSSL_NO_RIPEMD merged into OPENSSL_NO_RMD160 -+ OPENSSL_NO_FP_API merged into OPENSSL_NO_STDIO -+ Remove OPENSSL_NO_BIO OPENSSL_NO_BUFFER OPENSSL_NO_CHAIN_VERIFY -+ OPENSSL_NO_EVP OPENSSL_NO_FIPS_ERR OPENSSL_NO_HASH_COMP -+ OPENSSL_NO_LHASH OPENSSL_NO_OBJECT OPENSSL_NO_SPEED OPENSSL_NO_STACK -+ OPENSSL_NO_X509 OPENSSL_NO_X509_VERIFY -+ Remove MS_STATIC; it's a relic from platforms <32 bits. -+ [Rich Salz] -+ -+ *) Cleaned up dead code -+ Remove all but one '#ifdef undef' which is to be looked at. -+ [Rich Salz] -+ -+ *) Clean up calling of xxx_free routines. -+ Just like free(), fix most of the xxx_free routines to accept -+ NULL. Remove the non-null checks from callers. Save much code. -+ [Rich Salz] -+ -+ *) Add secure heap for storage of private keys (when possible). -+ Add BIO_s_secmem(), CBIGNUM, etc. -+ Contributed by Akamai Technologies under our Corporate CLA. -+ [Rich Salz] -+ -+ *) Experimental support for a new, fast, unbiased prime candidate generator, -+ bn_probable_prime_dh_coprime(). Not currently used by any prime generator. -+ [Felix Laurie von Massenbach ] -+ -+ *) New output format NSS in the sess_id command line tool. This allows -+ exporting the session id and the master key in NSS keylog format. -+ [Martin Kaiser ] -+ -+ *) Harmonize version and its documentation. -f flag is used to display -+ compilation flags. -+ [mancha ] -+ -+ *) Fix eckey_priv_encode so it immediately returns an error upon a failure -+ in i2d_ECPrivateKey. Thanks to Ted Unangst for feedback on this issue. -+ [mancha ] -+ -+ *) Fix some double frees. These are not thought to be exploitable. -+ [mancha ] -+ -+ *) A missing bounds check in the handling of the TLS heartbeat extension -+ can be used to reveal up to 64k of memory to a connected client or -+ server. -+ -+ Thanks for Neel Mehta of Google Security for discovering this bug and to -+ Adam Langley and Bodo Moeller for -+ preparing the fix (CVE-2014-0160) -+ [Adam Langley, Bodo Moeller] -+ -+ *) Fix for the attack described in the paper "Recovering OpenSSL -+ ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack" -+ by Yuval Yarom and Naomi Benger. Details can be obtained from: -+ http://eprint.iacr.org/2014/140 -+ -+ Thanks to Yuval Yarom and Naomi Benger for discovering this -+ flaw and to Yuval Yarom for supplying a fix (CVE-2014-0076) -+ [Yuval Yarom and Naomi Benger] -+ -+ *) Use algorithm specific chains in SSL_CTX_use_certificate_chain_file(): -+ this fixes a limitation in previous versions of OpenSSL. -+ [Steve Henson] -+ -+ *) Experimental encrypt-then-mac support. -+ -+ Experimental support for encrypt then mac from -+ draft-gutmann-tls-encrypt-then-mac-02.txt -+ -+ To enable it set the appropriate extension number (0x42 for the test -+ server) using e.g. -DTLSEXT_TYPE_encrypt_then_mac=0x42 -+ -+ For non-compliant peers (i.e. just about everything) this should have no -+ effect. -+ -+ WARNING: EXPERIMENTAL, SUBJECT TO CHANGE. -+ -+ [Steve Henson] -+ -+ *) Add EVP support for key wrapping algorithms, to avoid problems with -+ existing code the flag EVP_CIPHER_CTX_WRAP_ALLOW has to be set in -+ the EVP_CIPHER_CTX or an error is returned. Add AES and DES3 wrap -+ algorithms and include tests cases. -+ [Steve Henson] -+ -+ *) Extend CMS code to support RSA-PSS signatures and RSA-OAEP for -+ enveloped data. -+ [Steve Henson] -+ -+ *) Extended RSA OAEP support via EVP_PKEY API. Options to specify digest, -+ MGF1 digest and OAEP label. -+ [Steve Henson] -+ -+ *) Make openssl verify return errors. -+ [Chris Palmer and Ben Laurie] -+ -+ *) New function ASN1_TIME_diff to calculate the difference between two -+ ASN1_TIME structures or one structure and the current time. -+ [Steve Henson] -+ -+ *) Update fips_test_suite to support multiple command line options. New -+ test to induce all self test errors in sequence and check expected -+ failures. -+ [Steve Henson] -+ -+ *) Add FIPS_{rsa,dsa,ecdsa}_{sign,verify} functions which digest and -+ sign or verify all in one operation. -+ [Steve Henson] -+ -+ *) Add fips_algvs: a multicall fips utility incorporating all the algorithm -+ test programs and fips_test_suite. Includes functionality to parse -+ the minimal script output of fipsalgest.pl directly. -+ [Steve Henson] -+ -+ *) Add authorisation parameter to FIPS_module_mode_set(). -+ [Steve Henson] -+ -+ *) Add FIPS selftest for ECDH algorithm using P-224 and B-233 curves. -+ [Steve Henson] -+ -+ *) Use separate DRBG fields for internal and external flags. New function -+ FIPS_drbg_health_check() to perform on demand health checking. Add -+ generation tests to fips_test_suite with reduced health check interval to -+ demonstrate periodic health checking. Add "nodh" option to -+ fips_test_suite to skip very slow DH test. -+ [Steve Henson] -+ -+ *) New function FIPS_get_cipherbynid() to lookup FIPS supported ciphers -+ based on NID. -+ [Steve Henson] -+ -+ *) More extensive health check for DRBG checking many more failure modes. -+ New function FIPS_selftest_drbg_all() to handle every possible DRBG -+ combination: call this in fips_test_suite. -+ [Steve Henson] -+ -+ *) Add support for canonical generation of DSA parameter 'g'. See -+ FIPS 186-3 A.2.3. -+ -+ *) Add support for HMAC DRBG from SP800-90. Update DRBG algorithm test and -+ POST to handle HMAC cases. -+ [Steve Henson] -+ -+ *) Add functions FIPS_module_version() and FIPS_module_version_text() -+ to return numerical and string versions of the FIPS module number. -+ [Steve Henson] -+ -+ *) Rename FIPS_mode_set and FIPS_mode to FIPS_module_mode_set and -+ FIPS_module_mode. FIPS_mode and FIPS_mode_set will be implemented -+ outside the validated module in the FIPS capable OpenSSL. -+ [Steve Henson] -+ -+ *) Minor change to DRBG entropy callback semantics. In some cases -+ there is no multiple of the block length between min_len and -+ max_len. Allow the callback to return more than max_len bytes -+ of entropy but discard any extra: it is the callback's responsibility -+ to ensure that the extra data discarded does not impact the -+ requested amount of entropy. -+ [Steve Henson] -+ -+ *) Add PRNG security strength checks to RSA, DSA and ECDSA using -+ information in FIPS186-3, SP800-57 and SP800-131A. -+ [Steve Henson] -+ -+ *) CCM support via EVP. Interface is very similar to GCM case except we -+ must supply all data in one chunk (i.e. no update, final) and the -+ message length must be supplied if AAD is used. Add algorithm test -+ support. -+ [Steve Henson] -+ -+ *) Initial version of POST overhaul. Add POST callback to allow the status -+ of POST to be monitored and/or failures induced. Modify fips_test_suite -+ to use callback. Always run all selftests even if one fails. -+ [Steve Henson] -+ -+ *) XTS support including algorithm test driver in the fips_gcmtest program. -+ Note: this does increase the maximum key length from 32 to 64 bytes but -+ there should be no binary compatibility issues as existing applications -+ will never use XTS mode. -+ [Steve Henson] -+ -+ *) Extensive reorganisation of FIPS PRNG behaviour. Remove all dependencies -+ to OpenSSL RAND code and replace with a tiny FIPS RAND API which also -+ performs algorithm blocking for unapproved PRNG types. Also do not -+ set PRNG type in FIPS_mode_set(): leave this to the application. -+ Add default OpenSSL DRBG handling: sets up FIPS PRNG and seeds with -+ the standard OpenSSL PRNG: set additional data to a date time vector. -+ [Steve Henson] -+ -+ *) Rename old X9.31 PRNG functions of the form FIPS_rand* to FIPS_x931*. -+ This shouldn't present any incompatibility problems because applications -+ shouldn't be using these directly and any that are will need to rethink -+ anyway as the X9.31 PRNG is now deprecated by FIPS 140-2 -+ [Steve Henson] -+ -+ *) Extensive self tests and health checking required by SP800-90 DRBG. -+ Remove strength parameter from FIPS_drbg_instantiate and always -+ instantiate at maximum supported strength. -+ [Steve Henson] -+ -+ *) Add ECDH code to fips module and fips_ecdhvs for primitives only testing. -+ [Steve Henson] -+ -+ *) New algorithm test program fips_dhvs to handle DH primitives only testing. -+ [Steve Henson] -+ -+ *) New function DH_compute_key_padded() to compute a DH key and pad with -+ leading zeroes if needed: this complies with SP800-56A et al. -+ [Steve Henson] -+ -+ *) Initial implementation of SP800-90 DRBGs for Hash and CTR. Not used by -+ anything, incomplete, subject to change and largely untested at present. -+ [Steve Henson] -+ -+ *) Modify fipscanisteronly build option to only build the necessary object -+ files by filtering FIPS_EX_OBJ through a perl script in crypto/Makefile. -+ [Steve Henson] -+ -+ *) Add experimental option FIPSSYMS to give all symbols in -+ fipscanister.o and FIPS or fips prefix. This will avoid -+ conflicts with future versions of OpenSSL. Add perl script -+ util/fipsas.pl to preprocess assembly language source files -+ and rename any affected symbols. -+ [Steve Henson] -+ -+ *) Add selftest checks and algorithm block of non-fips algorithms in -+ FIPS mode. Remove DES2 from selftests. -+ [Steve Henson] -+ -+ *) Add ECDSA code to fips module. Add tiny fips_ecdsa_check to just -+ return internal method without any ENGINE dependencies. Add new -+ tiny fips sign and verify functions. -+ [Steve Henson] -+ -+ *) New build option no-ec2m to disable characteristic 2 code. -+ [Steve Henson] -+ -+ *) New build option "fipscanisteronly". This only builds fipscanister.o -+ and (currently) associated fips utilities. Uses the file Makefile.fips -+ instead of Makefile.org as the prototype. -+ [Steve Henson] -+ -+ *) Add some FIPS mode restrictions to GCM. Add internal IV generator. -+ Update fips_gcmtest to use IV generator. -+ [Steve Henson] -+ -+ *) Initial, experimental EVP support for AES-GCM. AAD can be input by -+ setting output buffer to NULL. The *Final function must be -+ called although it will not retrieve any additional data. The tag -+ can be set or retrieved with a ctrl. The IV length is by default 12 -+ bytes (96 bits) but can be set to an alternative value. If the IV -+ length exceeds the maximum IV length (currently 16 bytes) it cannot be -+ set before the key. -+ [Steve Henson] -+ -+ *) New flag in ciphers: EVP_CIPH_FLAG_CUSTOM_CIPHER. This means the -+ underlying do_cipher function handles all cipher semantics itself -+ including padding and finalisation. This is useful if (for example) -+ an ENGINE cipher handles block padding itself. The behaviour of -+ do_cipher is subtly changed if this flag is set: the return value -+ is the number of characters written to the output buffer (zero is -+ no longer an error code) or a negative error code. Also if the -+ input buffer is NULL and length 0 finalisation should be performed. -+ [Steve Henson] -+ -+ *) If a candidate issuer certificate is already part of the constructed -+ path ignore it: new debug notification X509_V_ERR_PATH_LOOP for this case. -+ [Steve Henson] -+ -+ *) Improve forward-security support: add functions -+ -+ void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx, int (*cb)(SSL *ssl, int is_forward_secure)) -+ void SSL_set_not_resumable_session_callback(SSL *ssl, int (*cb)(SSL *ssl, int is_forward_secure)) -+ -+ for use by SSL/TLS servers; the callback function will be called whenever a -+ new session is created, and gets to decide whether the session may be -+ cached to make it resumable (return 0) or not (return 1). (As by the -+ SSL/TLS protocol specifications, the session_id sent by the server will be -+ empty to indicate that the session is not resumable; also, the server will -+ not generate RFC 4507 (RFC 5077) session tickets.) -+ -+ A simple reasonable callback implementation is to return is_forward_secure. -+ This parameter will be set to 1 or 0 depending on the ciphersuite selected -+ by the SSL/TLS server library, indicating whether it can provide forward -+ security. -+ [Emilia Käsper (Google)] -+ -+ *) New -verify_name option in command line utilities to set verification -+ parameters by name. -+ [Steve Henson] -+ -+ *) Initial CMAC implementation. WARNING: EXPERIMENTAL, API MAY CHANGE. -+ Add CMAC pkey methods. -+ [Steve Henson] -+ -+ *) Experimental renegotiation in s_server -www mode. If the client -+ browses /reneg connection is renegotiated. If /renegcert it is -+ renegotiated requesting a certificate. -+ [Steve Henson] -+ -+ *) Add an "external" session cache for debugging purposes to s_server. This -+ should help trace issues which normally are only apparent in deployed -+ multi-process servers. -+ [Steve Henson] -+ -+ *) Extensive audit of libcrypto with DEBUG_UNUSED. Fix many cases where -+ return value is ignored. NB. The functions RAND_add(), RAND_seed(), -+ BIO_set_cipher() and some obscure PEM functions were changed so they -+ can now return an error. The RAND changes required a change to the -+ RAND_METHOD structure. -+ [Steve Henson] -+ -+ *) New macro __owur for "OpenSSL Warn Unused Result". This makes use of -+ a gcc attribute to warn if the result of a function is ignored. This -+ is enable if DEBUG_UNUSED is set. Add to several functions in evp.h -+ whose return value is often ignored. -+ [Steve Henson] -+ -+ *) New -noct, -requestct, -requirect and -ctlogfile options for s_client. -+ These allow SCTs (signed certificate timestamps) to be requested and -+ validated when establishing a connection. -+ [Rob Percival ] -+ -+ Changes between 1.0.2g and 1.0.2h [3 May 2016] -+ -+ *) Prevent padding oracle in AES-NI CBC MAC check -+ -+ A MITM attacker can use a padding oracle attack to decrypt traffic -+ when the connection uses an AES CBC cipher and the server support -+ AES-NI. -+ -+ This issue was introduced as part of the fix for Lucky 13 padding -+ attack (CVE-2013-0169). The padding check was rewritten to be in -+ constant time by making sure that always the same bytes are read and -+ compared against either the MAC or padding bytes. But it no longer -+ checked that there was enough data to have both the MAC and padding -+ bytes. -+ -+ This issue was reported by Juraj Somorovsky using TLS-Attacker. -+ (CVE-2016-2107) -+ [Kurt Roeckx] -+ -+ *) Fix EVP_EncodeUpdate overflow -+ -+ An overflow can occur in the EVP_EncodeUpdate() function which is used for -+ Base64 encoding of binary data. If an attacker is able to supply very large -+ amounts of input data then a length check can overflow resulting in a heap -+ corruption. -+ -+ Internally to OpenSSL the EVP_EncodeUpdate() function is primarily used by -+ the PEM_write_bio* family of functions. These are mainly used within the -+ OpenSSL command line applications, so any application which processes data -+ from an untrusted source and outputs it as a PEM file should be considered -+ vulnerable to this issue. User applications that call these APIs directly -+ with large amounts of untrusted data may also be vulnerable. -+ -+ This issue was reported by Guido Vranken. -+ (CVE-2016-2105) -+ [Matt Caswell] -+ -+ *) Fix EVP_EncryptUpdate overflow -+ -+ An overflow can occur in the EVP_EncryptUpdate() function. If an attacker -+ is able to supply very large amounts of input data after a previous call to -+ EVP_EncryptUpdate() with a partial block then a length check can overflow -+ resulting in a heap corruption. Following an analysis of all OpenSSL -+ internal usage of the EVP_EncryptUpdate() function all usage is one of two -+ forms. The first form is where the EVP_EncryptUpdate() call is known to be -+ the first called function after an EVP_EncryptInit(), and therefore that -+ specific call must be safe. The second form is where the length passed to -+ EVP_EncryptUpdate() can be seen from the code to be some small value and -+ therefore there is no possibility of an overflow. Since all instances are -+ one of these two forms, it is believed that there can be no overflows in -+ internal code due to this problem. It should be noted that -+ EVP_DecryptUpdate() can call EVP_EncryptUpdate() in certain code paths. -+ Also EVP_CipherUpdate() is a synonym for EVP_EncryptUpdate(). All instances -+ of these calls have also been analysed too and it is believed there are no -+ instances in internal usage where an overflow could occur. -+ -+ This issue was reported by Guido Vranken. -+ (CVE-2016-2106) -+ [Matt Caswell] -+ -+ *) Prevent ASN.1 BIO excessive memory allocation -+ -+ When ASN.1 data is read from a BIO using functions such as d2i_CMS_bio() -+ a short invalid encoding can cause allocation of large amounts of memory -+ potentially consuming excessive resources or exhausting memory. -+ -+ Any application parsing untrusted data through d2i BIO functions is -+ affected. The memory based functions such as d2i_X509() are *not* affected. -+ Since the memory based functions are used by the TLS library, TLS -+ applications are not affected. -+ -+ This issue was reported by Brian Carpenter. -+ (CVE-2016-2109) -+ [Stephen Henson] -+ -+ *) EBCDIC overread -+ -+ ASN1 Strings that are over 1024 bytes can cause an overread in applications -+ using the X509_NAME_oneline() function on EBCDIC systems. This could result -+ in arbitrary stack data being returned in the buffer. -+ -+ This issue was reported by Guido Vranken. -+ (CVE-2016-2176) -+ [Matt Caswell] -+ -+ *) Modify behavior of ALPN to invoke callback after SNI/servername -+ callback, such that updates to the SSL_CTX affect ALPN. -+ [Todd Short] -+ -+ *) Remove LOW from the DEFAULT cipher list. This removes singles DES from the -+ default. -+ [Kurt Roeckx] -+ -+ *) Only remove the SSLv2 methods with the no-ssl2-method option. When the -+ methods are enabled and ssl2 is disabled the methods return NULL. -+ [Kurt Roeckx] -+ -+ Changes between 1.0.2f and 1.0.2g [1 Mar 2016] -+ -+ * Disable weak ciphers in SSLv3 and up in default builds of OpenSSL. -+ Builds that are not configured with "enable-weak-ssl-ciphers" will not -+ provide any "EXPORT" or "LOW" strength ciphers. -+ [Viktor Dukhovni] -+ -+ * Disable SSLv2 default build, default negotiation and weak ciphers. SSLv2 -+ is by default disabled at build-time. Builds that are not configured with -+ "enable-ssl2" will not support SSLv2. Even if "enable-ssl2" is used, -+ users who want to negotiate SSLv2 via the version-flexible SSLv23_method() -+ will need to explicitly call either of: -+ -+ SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv2); -+ or -+ SSL_clear_options(ssl, SSL_OP_NO_SSLv2); -+ -+ as appropriate. Even if either of those is used, or the application -+ explicitly uses the version-specific SSLv2_method() or its client and -+ server variants, SSLv2 ciphers vulnerable to exhaustive search key -+ recovery have been removed. Specifically, the SSLv2 40-bit EXPORT -+ ciphers, and SSLv2 56-bit DES are no longer available. -+ (CVE-2016-0800) -+ [Viktor Dukhovni] -+ -+ *) Fix a double-free in DSA code -+ -+ A double free bug was discovered when OpenSSL parses malformed DSA private -+ keys and could lead to a DoS attack or memory corruption for applications -+ that receive DSA private keys from untrusted sources. This scenario is -+ considered rare. -+ -+ This issue was reported to OpenSSL by Adam Langley(Google/BoringSSL) using -+ libFuzzer. -+ (CVE-2016-0705) -+ [Stephen Henson] -+ -+ *) Disable SRP fake user seed to address a server memory leak. -+ -+ Add a new method SRP_VBASE_get1_by_user that handles the seed properly. -+ -+ SRP_VBASE_get_by_user had inconsistent memory management behaviour. -+ In order to fix an unavoidable memory leak, SRP_VBASE_get_by_user -+ was changed to ignore the "fake user" SRP seed, even if the seed -+ is configured. -+ -+ Users should use SRP_VBASE_get1_by_user instead. Note that in -+ SRP_VBASE_get1_by_user, caller must free the returned value. Note -+ also that even though configuring the SRP seed attempts to hide -+ invalid usernames by continuing the handshake with fake -+ credentials, this behaviour is not constant time and no strong -+ guarantees are made that the handshake is indistinguishable from -+ that of a valid user. -+ (CVE-2016-0798) -+ [Emilia Käsper] -+ -+ *) Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption -+ -+ In the BN_hex2bn function the number of hex digits is calculated using an -+ int value |i|. Later |bn_expand| is called with a value of |i * 4|. For -+ large values of |i| this can result in |bn_expand| not allocating any -+ memory because |i * 4| is negative. This can leave the internal BIGNUM data -+ field as NULL leading to a subsequent NULL ptr deref. For very large values -+ of |i|, the calculation |i * 4| could be a positive value smaller than |i|. -+ In this case memory is allocated to the internal BIGNUM data field, but it -+ is insufficiently sized leading to heap corruption. A similar issue exists -+ in BN_dec2bn. This could have security consequences if BN_hex2bn/BN_dec2bn -+ is ever called by user applications with very large untrusted hex/dec data. -+ This is anticipated to be a rare occurrence. -+ -+ All OpenSSL internal usage of these functions use data that is not expected -+ to be untrusted, e.g. config file data or application command line -+ arguments. If user developed applications generate config file data based -+ on untrusted data then it is possible that this could also lead to security -+ consequences. This is also anticipated to be rare. -+ -+ This issue was reported to OpenSSL by Guido Vranken. -+ (CVE-2016-0797) -+ [Matt Caswell] -+ -+ *) Fix memory issues in BIO_*printf functions -+ -+ The internal |fmtstr| function used in processing a "%s" format string in -+ the BIO_*printf functions could overflow while calculating the length of a -+ string and cause an OOB read when printing very long strings. -+ -+ Additionally the internal |doapr_outch| function can attempt to write to an -+ OOB memory location (at an offset from the NULL pointer) in the event of a -+ memory allocation failure. In 1.0.2 and below this could be caused where -+ the size of a buffer to be allocated is greater than INT_MAX. E.g. this -+ could be in processing a very long "%s" format string. Memory leaks can -+ also occur. -+ -+ The first issue may mask the second issue dependent on compiler behaviour. -+ These problems could enable attacks where large amounts of untrusted data -+ is passed to the BIO_*printf functions. If applications use these functions -+ in this way then they could be vulnerable. OpenSSL itself uses these -+ functions when printing out human-readable dumps of ASN.1 data. Therefore -+ applications that print this data could be vulnerable if the data is from -+ untrusted sources. OpenSSL command line applications could also be -+ vulnerable where they print out ASN.1 data, or if untrusted data is passed -+ as command line arguments. -+ -+ Libssl is not considered directly vulnerable. Additionally certificates etc -+ received via remote connections via libssl are also unlikely to be able to -+ trigger these issues because of message size limits enforced within libssl. -+ -+ This issue was reported to OpenSSL Guido Vranken. -+ (CVE-2016-0799) -+ [Matt Caswell] -+ -+ *) Side channel attack on modular exponentiation -+ -+ A side-channel attack was found which makes use of cache-bank conflicts on -+ the Intel Sandy-Bridge microarchitecture which could lead to the recovery -+ of RSA keys. The ability to exploit this issue is limited as it relies on -+ an attacker who has control of code in a thread running on the same -+ hyper-threaded core as the victim thread which is performing decryptions. -+ -+ This issue was reported to OpenSSL by Yuval Yarom, The University of -+ Adelaide and NICTA, Daniel Genkin, Technion and Tel Aviv University, and -+ Nadia Heninger, University of Pennsylvania with more information at -+ http://cachebleed.info. -+ (CVE-2016-0702) -+ [Andy Polyakov] -+ -+ *) Change the req app to generate a 2048-bit RSA/DSA key by default, -+ if no keysize is specified with default_bits. This fixes an -+ omission in an earlier change that changed all RSA/DSA key generation -+ apps to use 2048 bits by default. -+ [Emilia Käsper] -+ -+ Changes between 1.0.2e and 1.0.2f [28 Jan 2016] -+ *) DH small subgroups -+ -+ Historically OpenSSL only ever generated DH parameters based on "safe" -+ primes. More recently (in version 1.0.2) support was provided for -+ generating X9.42 style parameter files such as those required for RFC 5114 -+ support. The primes used in such files may not be "safe". Where an -+ application is using DH configured with parameters based on primes that are -+ not "safe" then an attacker could use this fact to find a peer's private -+ DH exponent. This attack requires that the attacker complete multiple -+ handshakes in which the peer uses the same private DH exponent. For example -+ this could be used to discover a TLS server's private DH exponent if it's -+ reusing the private DH exponent or it's using a static DH ciphersuite. -+ -+ OpenSSL provides the option SSL_OP_SINGLE_DH_USE for ephemeral DH (DHE) in -+ TLS. It is not on by default. If the option is not set then the server -+ reuses the same private DH exponent for the life of the server process and -+ would be vulnerable to this attack. It is believed that many popular -+ applications do set this option and would therefore not be at risk. -+ -+ The fix for this issue adds an additional check where a "q" parameter is -+ available (as is the case in X9.42 based parameters). This detects the -+ only known attack, and is the only possible defense for static DH -+ ciphersuites. This could have some performance impact. -+ -+ Additionally the SSL_OP_SINGLE_DH_USE option has been switched on by -+ default and cannot be disabled. This could have some performance impact. -+ -+ This issue was reported to OpenSSL by Antonio Sanso (Adobe). -+ (CVE-2016-0701) -+ [Matt Caswell] -+ -+ *) SSLv2 doesn't block disabled ciphers -+ -+ A malicious client can negotiate SSLv2 ciphers that have been disabled on -+ the server and complete SSLv2 handshakes even if all SSLv2 ciphers have -+ been disabled, provided that the SSLv2 protocol was not also disabled via -+ SSL_OP_NO_SSLv2. -+ -+ This issue was reported to OpenSSL on 26th December 2015 by Nimrod Aviram -+ and Sebastian Schinzel. -+ (CVE-2015-3197) -+ [Viktor Dukhovni] -+ -+ Changes between 1.0.2d and 1.0.2e [3 Dec 2015] -+ -+ *) BN_mod_exp may produce incorrect results on x86_64 -+ -+ There is a carry propagating bug in the x86_64 Montgomery squaring -+ procedure. No EC algorithms are affected. Analysis suggests that attacks -+ against RSA and DSA as a result of this defect would be very difficult to -+ perform and are not believed likely. Attacks against DH are considered just -+ feasible (although very difficult) because most of the work necessary to -+ deduce information about a private key may be performed offline. The amount -+ of resources required for such an attack would be very significant and -+ likely only accessible to a limited number of attackers. An attacker would -+ additionally need online access to an unpatched system using the target -+ private key in a scenario with persistent DH parameters and a private -+ key that is shared between multiple clients. For example this can occur by -+ default in OpenSSL DHE based SSL/TLS ciphersuites. -+ -+ This issue was reported to OpenSSL by Hanno Böck. -+ (CVE-2015-3193) -+ [Andy Polyakov] -+ -+ *) Certificate verify crash with missing PSS parameter -+ -+ The signature verification routines will crash with a NULL pointer -+ dereference if presented with an ASN.1 signature using the RSA PSS -+ algorithm and absent mask generation function parameter. Since these -+ routines are used to verify certificate signature algorithms this can be -+ used to crash any certificate verification operation and exploited in a -+ DoS attack. Any application which performs certificate verification is -+ vulnerable including OpenSSL clients and servers which enable client -+ authentication. -+ -+ This issue was reported to OpenSSL by Loïc Jonas Etienne (Qnective AG). -+ (CVE-2015-3194) -+ [Stephen Henson] -+ -+ *) X509_ATTRIBUTE memory leak -+ -+ When presented with a malformed X509_ATTRIBUTE structure OpenSSL will leak -+ memory. This structure is used by the PKCS#7 and CMS routines so any -+ application which reads PKCS#7 or CMS data from untrusted sources is -+ affected. SSL/TLS is not affected. -+ -+ This issue was reported to OpenSSL by Adam Langley (Google/BoringSSL) using -+ libFuzzer. -+ (CVE-2015-3195) -+ [Stephen Henson] -+ -+ *) Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs. -+ This changes the decoding behaviour for some invalid messages, -+ though the change is mostly in the more lenient direction, and -+ legacy behaviour is preserved as much as possible. -+ [Emilia Käsper] -+ -+ *) In DSA_generate_parameters_ex, if the provided seed is too short, -+ return an error -+ [Rich Salz and Ismo Puustinen ] -+ -+ Changes between 1.0.2c and 1.0.2d [9 Jul 2015] -+ -+ *) Alternate chains certificate forgery -+ -+ During certificate verification, OpenSSL will attempt to find an -+ alternative certificate chain if the first attempt to build such a chain -+ fails. An error in the implementation of this logic can mean that an -+ attacker could cause certain checks on untrusted certificates to be -+ bypassed, such as the CA flag, enabling them to use a valid leaf -+ certificate to act as a CA and "issue" an invalid certificate. -+ -+ This issue was reported to OpenSSL by Adam Langley/David Benjamin -+ (Google/BoringSSL). -+ [Matt Caswell] -+ -+ Changes between 1.0.2b and 1.0.2c [12 Jun 2015] -+ -+ *) Fix HMAC ABI incompatibility. The previous version introduced an ABI -+ incompatibility in the handling of HMAC. The previous ABI has now been -+ restored. -+ [Matt Caswell] -+ -+ Changes between 1.0.2a and 1.0.2b [11 Jun 2015] -+ -+ *) Malformed ECParameters causes infinite loop -+ -+ When processing an ECParameters structure OpenSSL enters an infinite loop -+ if the curve specified is over a specially malformed binary polynomial -+ field. -+ -+ This can be used to perform denial of service against any -+ system which processes public keys, certificate requests or -+ certificates. This includes TLS clients and TLS servers with -+ client authentication enabled. -+ -+ This issue was reported to OpenSSL by Joseph Barr-Pixton. -+ (CVE-2015-1788) -+ [Andy Polyakov] -+ -+ *) Exploitable out-of-bounds read in X509_cmp_time -+ -+ X509_cmp_time does not properly check the length of the ASN1_TIME -+ string and can read a few bytes out of bounds. In addition, -+ X509_cmp_time accepts an arbitrary number of fractional seconds in the -+ time string. -+ -+ An attacker can use this to craft malformed certificates and CRLs of -+ various sizes and potentially cause a segmentation fault, resulting in -+ a DoS on applications that verify certificates or CRLs. TLS clients -+ that verify CRLs are affected. TLS clients and servers with client -+ authentication enabled may be affected if they use custom verification -+ callbacks. -+ -+ This issue was reported to OpenSSL by Robert Swiecki (Google), and -+ independently by Hanno Böck. -+ (CVE-2015-1789) -+ [Emilia Käsper] -+ -+ *) PKCS7 crash with missing EnvelopedContent -+ -+ The PKCS#7 parsing code does not handle missing inner EncryptedContent -+ correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs -+ with missing content and trigger a NULL pointer dereference on parsing. -+ -+ Applications that decrypt PKCS#7 data or otherwise parse PKCS#7 -+ structures from untrusted sources are affected. OpenSSL clients and -+ servers are not affected. -+ -+ This issue was reported to OpenSSL by Michal Zalewski (Google). -+ (CVE-2015-1790) -+ [Emilia Käsper] -+ -+ *) CMS verify infinite loop with unknown hash function -+ -+ When verifying a signedData message the CMS code can enter an infinite loop -+ if presented with an unknown hash function OID. This can be used to perform -+ denial of service against any system which verifies signedData messages using -+ the CMS code. -+ This issue was reported to OpenSSL by Johannes Bauer. -+ (CVE-2015-1792) -+ [Stephen Henson] -+ -+ *) Race condition handling NewSessionTicket -+ -+ If a NewSessionTicket is received by a multi-threaded client when attempting to -+ reuse a previous ticket then a race condition can occur potentially leading to -+ a double free of the ticket data. -+ (CVE-2015-1791) -+ [Matt Caswell] -+ -+ *) Only support 256-bit or stronger elliptic curves with the -+ 'ecdh_auto' setting (server) or by default (client). Of supported -+ curves, prefer P-256 (both). -+ [Emilia Kasper] -+ -+ Changes between 1.0.2 and 1.0.2a [19 Mar 2015] -+ -+ *) ClientHello sigalgs DoS fix -+ -+ If a client connects to an OpenSSL 1.0.2 server and renegotiates with an -+ invalid signature algorithms extension a NULL pointer dereference will -+ occur. This can be exploited in a DoS attack against the server. -+ -+ This issue was was reported to OpenSSL by David Ramos of Stanford -+ University. -+ (CVE-2015-0291) -+ [Stephen Henson and Matt Caswell] -+ -+ *) Multiblock corrupted pointer fix -+ -+ OpenSSL 1.0.2 introduced the "multiblock" performance improvement. This -+ feature only applies on 64 bit x86 architecture platforms that support AES -+ NI instructions. A defect in the implementation of "multiblock" can cause -+ OpenSSL's internal write buffer to become incorrectly set to NULL when -+ using non-blocking IO. Typically, when the user application is using a -+ socket BIO for writing, this will only result in a failed connection. -+ However if some other BIO is used then it is likely that a segmentation -+ fault will be triggered, thus enabling a potential DoS attack. -+ -+ This issue was reported to OpenSSL by Daniel Danner and Rainer Mueller. -+ (CVE-2015-0290) -+ [Matt Caswell] -+ -+ *) Segmentation fault in DTLSv1_listen fix -+ -+ The DTLSv1_listen function is intended to be stateless and processes the -+ initial ClientHello from many peers. It is common for user code to loop -+ over the call to DTLSv1_listen until a valid ClientHello is received with -+ an associated cookie. A defect in the implementation of DTLSv1_listen means -+ that state is preserved in the SSL object from one invocation to the next -+ that can lead to a segmentation fault. Errors processing the initial -+ ClientHello can trigger this scenario. An example of such an error could be -+ that a DTLS1.0 only client is attempting to connect to a DTLS1.2 only -+ server. -+ -+ This issue was reported to OpenSSL by Per Allansson. -+ (CVE-2015-0207) -+ [Matt Caswell] -+ -+ *) Segmentation fault in ASN1_TYPE_cmp fix -+ -+ The function ASN1_TYPE_cmp will crash with an invalid read if an attempt is -+ made to compare ASN.1 boolean types. Since ASN1_TYPE_cmp is used to check -+ certificate signature algorithm consistency this can be used to crash any -+ certificate verification operation and exploited in a DoS attack. Any -+ application which performs certificate verification is vulnerable including -+ OpenSSL clients and servers which enable client authentication. -+ (CVE-2015-0286) -+ [Stephen Henson] -+ -+ *) Segmentation fault for invalid PSS parameters fix -+ -+ The signature verification routines will crash with a NULL pointer -+ dereference if presented with an ASN.1 signature using the RSA PSS -+ algorithm and invalid parameters. Since these routines are used to verify -+ certificate signature algorithms this can be used to crash any -+ certificate verification operation and exploited in a DoS attack. Any -+ application which performs certificate verification is vulnerable including -+ OpenSSL clients and servers which enable client authentication. -+ -+ This issue was was reported to OpenSSL by Brian Carpenter. -+ (CVE-2015-0208) -+ [Stephen Henson] -+ -+ *) ASN.1 structure reuse memory corruption fix -+ -+ Reusing a structure in ASN.1 parsing may allow an attacker to cause -+ memory corruption via an invalid write. Such reuse is and has been -+ strongly discouraged and is believed to be rare. -+ -+ Applications that parse structures containing CHOICE or ANY DEFINED BY -+ components may be affected. Certificate parsing (d2i_X509 and related -+ functions) are however not affected. OpenSSL clients and servers are -+ not affected. -+ (CVE-2015-0287) -+ [Stephen Henson] -+ -+ *) PKCS7 NULL pointer dereferences fix -+ -+ The PKCS#7 parsing code does not handle missing outer ContentInfo -+ correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs with -+ missing content and trigger a NULL pointer dereference on parsing. -+ -+ Applications that verify PKCS#7 signatures, decrypt PKCS#7 data or -+ otherwise parse PKCS#7 structures from untrusted sources are -+ affected. OpenSSL clients and servers are not affected. -+ -+ This issue was reported to OpenSSL by Michal Zalewski (Google). -+ (CVE-2015-0289) -+ [Emilia Käsper] -+ -+ *) DoS via reachable assert in SSLv2 servers fix -+ -+ A malicious client can trigger an OPENSSL_assert (i.e., an abort) in -+ servers that both support SSLv2 and enable export cipher suites by sending -+ a specially crafted SSLv2 CLIENT-MASTER-KEY message. -+ -+ This issue was discovered by Sean Burford (Google) and Emilia Käsper -+ (OpenSSL development team). -+ (CVE-2015-0293) -+ [Emilia Käsper] -+ -+ *) Empty CKE with client auth and DHE fix -+ -+ If client auth is used then a server can seg fault in the event of a DHE -+ ciphersuite being selected and a zero length ClientKeyExchange message -+ being sent by the client. This could be exploited in a DoS attack. -+ (CVE-2015-1787) -+ [Matt Caswell] -+ -+ *) Handshake with unseeded PRNG fix -+ -+ Under certain conditions an OpenSSL 1.0.2 client can complete a handshake -+ with an unseeded PRNG. The conditions are: -+ - The client is on a platform where the PRNG has not been seeded -+ automatically, and the user has not seeded manually -+ - A protocol specific client method version has been used (i.e. not -+ SSL_client_methodv23) -+ - A ciphersuite is used that does not require additional random data from -+ the PRNG beyond the initial ClientHello client random (e.g. PSK-RC4-SHA). -+ -+ If the handshake succeeds then the client random that has been used will -+ have been generated from a PRNG with insufficient entropy and therefore the -+ output may be predictable. -+ -+ For example using the following command with an unseeded openssl will -+ succeed on an unpatched platform: -+ -+ openssl s_client -psk 1a2b3c4d -tls1_2 -cipher PSK-RC4-SHA -+ (CVE-2015-0285) -+ [Matt Caswell] -+ -+ *) Use After Free following d2i_ECPrivatekey error fix -+ -+ A malformed EC private key file consumed via the d2i_ECPrivateKey function -+ could cause a use after free condition. This, in turn, could cause a double -+ free in several private key parsing functions (such as d2i_PrivateKey -+ or EVP_PKCS82PKEY) and could lead to a DoS attack or memory corruption -+ for applications that receive EC private keys from untrusted -+ sources. This scenario is considered rare. -+ -+ This issue was discovered by the BoringSSL project and fixed in their -+ commit 517073cd4b. -+ (CVE-2015-0209) -+ [Matt Caswell] -+ -+ *) X509_to_X509_REQ NULL pointer deref fix -+ -+ The function X509_to_X509_REQ will crash with a NULL pointer dereference if -+ the certificate key is invalid. This function is rarely used in practice. -+ -+ This issue was discovered by Brian Carpenter. -+ (CVE-2015-0288) -+ [Stephen Henson] -+ -+ *) Removed the export ciphers from the DEFAULT ciphers -+ [Kurt Roeckx] -+ -+ Changes between 1.0.1l and 1.0.2 [22 Jan 2015] -+ -+ *) Facilitate "universal" ARM builds targeting range of ARM ISAs, e.g. -+ ARMv5 through ARMv8, as opposite to "locking" it to single one. -+ So far those who have to target multiple platforms would compromise -+ and argue that binary targeting say ARMv5 would still execute on -+ ARMv8. "Universal" build resolves this compromise by providing -+ near-optimal performance even on newer platforms. -+ [Andy Polyakov] -+ -+ *) Accelerated NIST P-256 elliptic curve implementation for x86_64 -+ (other platforms pending). -+ [Shay Gueron & Vlad Krasnov (Intel Corp), Andy Polyakov] -+ -+ *) Add support for the SignedCertificateTimestampList certificate and -+ OCSP response extensions from RFC6962. -+ [Rob Stradling] -+ -+ *) Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.) -+ for corner cases. (Certain input points at infinity could lead to -+ bogus results, with non-infinity inputs mapped to infinity too.) -+ [Bodo Moeller] -+ -+ *) Initial support for PowerISA 2.0.7, first implemented in POWER8. -+ This covers AES, SHA256/512 and GHASH. "Initial" means that most -+ common cases are optimized and there still is room for further -+ improvements. Vector Permutation AES for Altivec is also added. -+ [Andy Polyakov] -+ -+ *) Add support for little-endian ppc64 Linux target. -+ [Marcelo Cerri (IBM)] -+ -+ *) Initial support for AMRv8 ISA crypto extensions. This covers AES, -+ SHA1, SHA256 and GHASH. "Initial" means that most common cases -+ are optimized and there still is room for further improvements. -+ Both 32- and 64-bit modes are supported. -+ [Andy Polyakov, Ard Biesheuvel (Linaro)] -+ -+ *) Improved ARMv7 NEON support. -+ [Andy Polyakov] -+ -+ *) Support for SPARC Architecture 2011 crypto extensions, first -+ implemented in SPARC T4. This covers AES, DES, Camellia, SHA1, -+ SHA256/512, MD5, GHASH and modular exponentiation. -+ [Andy Polyakov, David Miller] -+ -+ *) Accelerated modular exponentiation for Intel processors, a.k.a. -+ RSAZ. -+ [Shay Gueron & Vlad Krasnov (Intel Corp)] -+ -+ *) Support for new and upcoming Intel processors, including AVX2, -+ BMI and SHA ISA extensions. This includes additional "stitched" -+ implementations, AESNI-SHA256 and GCM, and multi-buffer support -+ for TLS encrypt. -+ -+ This work was sponsored by Intel Corp. -+ [Andy Polyakov] -+ -+ *) Support for DTLS 1.2. This adds two sets of DTLS methods: DTLS_*_method() -+ supports both DTLS 1.2 and 1.0 and should use whatever version the peer -+ supports and DTLSv1_2_*_method() which supports DTLS 1.2 only. -+ [Steve Henson] -+ -+ *) Use algorithm specific chains in SSL_CTX_use_certificate_chain_file(): -+ this fixes a limitation in previous versions of OpenSSL. -+ [Steve Henson] -+ -+ *) Extended RSA OAEP support via EVP_PKEY API. Options to specify digest, -+ MGF1 digest and OAEP label. -+ [Steve Henson] -+ -+ *) Add EVP support for key wrapping algorithms, to avoid problems with -+ existing code the flag EVP_CIPHER_CTX_WRAP_ALLOW has to be set in -+ the EVP_CIPHER_CTX or an error is returned. Add AES and DES3 wrap -+ algorithms and include tests cases. -+ [Steve Henson] -+ -+ *) Add functions to allocate and set the fields of an ECDSA_METHOD -+ structure. -+ [Douglas E. Engert, Steve Henson] -+ -+ *) New functions OPENSSL_gmtime_diff and ASN1_TIME_diff to find the -+ difference in days and seconds between two tm or ASN1_TIME structures. -+ [Steve Henson] -+ -+ *) Add -rev test option to s_server to just reverse order of characters -+ received by client and send back to server. Also prints an abbreviated -+ summary of the connection parameters. -+ [Steve Henson] -+ -+ *) New option -brief for s_client and s_server to print out a brief summary -+ of connection parameters. -+ [Steve Henson] -+ -+ *) Add callbacks for arbitrary TLS extensions. -+ [Trevor Perrin and Ben Laurie] -+ -+ *) New option -crl_download in several openssl utilities to download CRLs -+ from CRLDP extension in certificates. -+ [Steve Henson] -+ -+ *) New options -CRL and -CRLform for s_client and s_server for CRLs. -+ [Steve Henson] -+ -+ *) New function X509_CRL_diff to generate a delta CRL from the difference -+ of two full CRLs. Add support to "crl" utility. -+ [Steve Henson] -+ -+ *) New functions to set lookup_crls function and to retrieve -+ X509_STORE from X509_STORE_CTX. -+ [Steve Henson] -+ -+ *) Print out deprecated issuer and subject unique ID fields in -+ certificates. -+ [Steve Henson] -+ -+ *) Extend OCSP I/O functions so they can be used for simple general purpose -+ HTTP as well as OCSP. New wrapper function which can be used to download -+ CRLs using the OCSP API. -+ [Steve Henson] -+ -+ *) Delegate command line handling in s_client/s_server to SSL_CONF APIs. -+ [Steve Henson] -+ -+ *) SSL_CONF* functions. These provide a common framework for application -+ configuration using configuration files or command lines. -+ [Steve Henson] -+ -+ *) SSL/TLS tracing code. This parses out SSL/TLS records using the -+ message callback and prints the results. Needs compile time option -+ "enable-ssl-trace". New options to s_client and s_server to enable -+ tracing. -+ [Steve Henson] -+ -+ *) New ctrl and macro to retrieve supported points extensions. -+ Print out extension in s_server and s_client. -+ [Steve Henson] -+ -+ *) New functions to retrieve certificate signature and signature -+ OID NID. -+ [Steve Henson] -+ -+ *) Add functions to retrieve and manipulate the raw cipherlist sent by a -+ client to OpenSSL. -+ [Steve Henson] -+ -+ *) New Suite B modes for TLS code. These use and enforce the requirements -+ of RFC6460: restrict ciphersuites, only permit Suite B algorithms and -+ only use Suite B curves. The Suite B modes can be set by using the -+ strings "SUITEB128", "SUITEB192" or "SUITEB128ONLY" for the cipherstring. -+ [Steve Henson] -+ -+ *) New chain verification flags for Suite B levels of security. Check -+ algorithms are acceptable when flags are set in X509_verify_cert. -+ [Steve Henson] -+ -+ *) Make tls1_check_chain return a set of flags indicating checks passed -+ by a certificate chain. Add additional tests to handle client -+ certificates: checks for matching certificate type and issuer name -+ comparison. -+ [Steve Henson] -+ -+ *) If an attempt is made to use a signature algorithm not in the peer -+ preference list abort the handshake. If client has no suitable -+ signature algorithms in response to a certificate request do not -+ use the certificate. -+ [Steve Henson] -+ -+ *) If server EC tmp key is not in client preference list abort handshake. -+ [Steve Henson] -+ -+ *) Add support for certificate stores in CERT structure. This makes it -+ possible to have different stores per SSL structure or one store in -+ the parent SSL_CTX. Include distinct stores for certificate chain -+ verification and chain building. New ctrl SSL_CTRL_BUILD_CERT_CHAIN -+ to build and store a certificate chain in CERT structure: returning -+ an error if the chain cannot be built: this will allow applications -+ to test if a chain is correctly configured. -+ -+ Note: if the CERT based stores are not set then the parent SSL_CTX -+ store is used to retain compatibility with existing behaviour. -+ -+ [Steve Henson] -+ -+ *) New function ssl_set_client_disabled to set a ciphersuite disabled -+ mask based on the current session, check mask when sending client -+ hello and checking the requested ciphersuite. -+ [Steve Henson] -+ -+ *) New ctrls to retrieve and set certificate types in a certificate -+ request message. Print out received values in s_client. If certificate -+ types is not set with custom values set sensible values based on -+ supported signature algorithms. -+ [Steve Henson] -+ -+ *) Support for distinct client and server supported signature algorithms. -+ [Steve Henson] -+ -+ *) Add certificate callback. If set this is called whenever a certificate -+ is required by client or server. An application can decide which -+ certificate chain to present based on arbitrary criteria: for example -+ supported signature algorithms. Add very simple example to s_server. -+ This fixes many of the problems and restrictions of the existing client -+ certificate callback: for example you can now clear an existing -+ certificate and specify the whole chain. -+ [Steve Henson] -+ -+ *) Add new "valid_flags" field to CERT_PKEY structure which determines what -+ the certificate can be used for (if anything). Set valid_flags field -+ in new tls1_check_chain function. Simplify ssl_set_cert_masks which used -+ to have similar checks in it. -+ -+ Add new "cert_flags" field to CERT structure and include a "strict mode". -+ This enforces some TLS certificate requirements (such as only permitting -+ certificate signature algorithms contained in the supported algorithms -+ extension) which some implementations ignore: this option should be used -+ with caution as it could cause interoperability issues. -+ [Steve Henson] -+ -+ *) Update and tidy signature algorithm extension processing. Work out -+ shared signature algorithms based on preferences and peer algorithms -+ and print them out in s_client and s_server. Abort handshake if no -+ shared signature algorithms. -+ [Steve Henson] -+ -+ *) Add new functions to allow customised supported signature algorithms -+ for SSL and SSL_CTX structures. Add options to s_client and s_server -+ to support them. -+ [Steve Henson] -+ -+ *) New function SSL_certs_clear() to delete all references to certificates -+ from an SSL structure. Before this once a certificate had been added -+ it couldn't be removed. -+ [Steve Henson] -+ -+ *) Integrate hostname, email address and IP address checking with certificate -+ verification. New verify options supporting checking in openssl utility. -+ [Steve Henson] -+ -+ *) Fixes and wildcard matching support to hostname and email checking -+ functions. Add manual page. -+ [Florian Weimer (Red Hat Product Security Team)] -+ -+ *) New functions to check a hostname email or IP address against a -+ certificate. Add options x509 utility to print results of checks against -+ a certificate. -+ [Steve Henson] -+ -+ *) Fix OCSP checking. -+ [Rob Stradling and Ben Laurie] -+ -+ *) Initial experimental support for explicitly trusted non-root CAs. -+ OpenSSL still tries to build a complete chain to a root but if an -+ intermediate CA has a trust setting included that is used. The first -+ setting is used: whether to trust (e.g., -addtrust option to the x509 -+ utility) or reject. -+ [Steve Henson] -+ -+ *) Add -trusted_first option which attempts to find certificates in the -+ trusted store even if an untrusted chain is also supplied. -+ [Steve Henson] -+ -+ *) MIPS assembly pack updates: support for MIPS32r2 and SmartMIPS ASE, -+ platform support for Linux and Android. -+ [Andy Polyakov] -+ -+ *) Support for linux-x32, ILP32 environment in x86_64 framework. -+ [Andy Polyakov] -+ -+ *) Experimental multi-implementation support for FIPS capable OpenSSL. -+ When in FIPS mode the approved implementations are used as normal, -+ when not in FIPS mode the internal unapproved versions are used instead. -+ This means that the FIPS capable OpenSSL isn't forced to use the -+ (often lower performance) FIPS implementations outside FIPS mode. -+ [Steve Henson] -+ -+ *) Transparently support X9.42 DH parameters when calling -+ PEM_read_bio_DHparameters. This means existing applications can handle -+ the new parameter format automatically. -+ [Steve Henson] -+ -+ *) Initial experimental support for X9.42 DH parameter format: mainly -+ to support use of 'q' parameter for RFC5114 parameters. -+ [Steve Henson] -+ -+ *) Add DH parameters from RFC5114 including test data to dhtest. -+ [Steve Henson] -+ -+ *) Support for automatic EC temporary key parameter selection. If enabled -+ the most preferred EC parameters are automatically used instead of -+ hardcoded fixed parameters. Now a server just has to call: -+ SSL_CTX_set_ecdh_auto(ctx, 1) and the server will automatically -+ support ECDH and use the most appropriate parameters. -+ [Steve Henson] -+ -+ *) Enhance and tidy EC curve and point format TLS extension code. Use -+ static structures instead of allocation if default values are used. -+ New ctrls to set curves we wish to support and to retrieve shared curves. -+ Print out shared curves in s_server. New options to s_server and s_client -+ to set list of supported curves. -+ [Steve Henson] -+ -+ *) New ctrls to retrieve supported signature algorithms and -+ supported curve values as an array of NIDs. Extend openssl utility -+ to print out received values. -+ [Steve Henson] -+ -+ *) Add new APIs EC_curve_nist2nid and EC_curve_nid2nist which convert -+ between NIDs and the more common NIST names such as "P-256". Enhance -+ ecparam utility and ECC method to recognise the NIST names for curves. -+ [Steve Henson] -+ -+ *) Enhance SSL/TLS certificate chain handling to support different -+ chains for each certificate instead of one chain in the parent SSL_CTX. -+ [Steve Henson] -+ -+ *) Support for fixed DH ciphersuite client authentication: where both -+ server and client use DH certificates with common parameters. -+ [Steve Henson] -+ -+ *) Support for fixed DH ciphersuites: those requiring DH server -+ certificates. -+ [Steve Henson] -+ -+ *) New function i2d_re_X509_tbs for re-encoding the TBS portion of -+ the certificate. -+ Note: Related 1.0.2-beta specific macros X509_get_cert_info, -+ X509_CINF_set_modified, X509_CINF_get_issuer, X509_CINF_get_extensions and -+ X509_CINF_get_signature were reverted post internal team review. -+ -+ Changes between 1.0.1k and 1.0.1l [15 Jan 2015] -+ -+ *) Build fixes for the Windows and OpenVMS platforms -+ [Matt Caswell and Richard Levitte] -+ -+ Changes between 1.0.1j and 1.0.1k [8 Jan 2015] -+ -+ *) Fix DTLS segmentation fault in dtls1_get_record. A carefully crafted DTLS -+ message can cause a segmentation fault in OpenSSL due to a NULL pointer -+ dereference. This could lead to a Denial Of Service attack. Thanks to -+ Markus Stenberg of Cisco Systems, Inc. for reporting this issue. -+ (CVE-2014-3571) -+ [Steve Henson] -+ -+ *) Fix DTLS memory leak in dtls1_buffer_record. A memory leak can occur in the -+ dtls1_buffer_record function under certain conditions. In particular this -+ could occur if an attacker sent repeated DTLS records with the same -+ sequence number but for the next epoch. The memory leak could be exploited -+ by an attacker in a Denial of Service attack through memory exhaustion. -+ Thanks to Chris Mueller for reporting this issue. -+ (CVE-2015-0206) -+ [Matt Caswell] -+ -+ *) Fix issue where no-ssl3 configuration sets method to NULL. When openssl is -+ built with the no-ssl3 option and a SSL v3 ClientHello is received the ssl -+ method would be set to NULL which could later result in a NULL pointer -+ dereference. Thanks to Frank Schmirler for reporting this issue. -+ (CVE-2014-3569) -+ [Kurt Roeckx] -+ -+ *) Abort handshake if server key exchange message is omitted for ephemeral -+ ECDH ciphersuites. -+ -+ Thanks to Karthikeyan Bhargavan of the PROSECCO team at INRIA for -+ reporting this issue. -+ (CVE-2014-3572) -+ [Steve Henson] -+ -+ *) Remove non-export ephemeral RSA code on client and server. This code -+ violated the TLS standard by allowing the use of temporary RSA keys in -+ non-export ciphersuites and could be used by a server to effectively -+ downgrade the RSA key length used to a value smaller than the server -+ certificate. Thanks for Karthikeyan Bhargavan of the PROSECCO team at -+ INRIA or reporting this issue. -+ (CVE-2015-0204) -+ [Steve Henson] -+ -+ *) Fixed issue where DH client certificates are accepted without verification. -+ An OpenSSL server will accept a DH certificate for client authentication -+ without the certificate verify message. This effectively allows a client to -+ authenticate without the use of a private key. This only affects servers -+ which trust a client certificate authority which issues certificates -+ containing DH keys: these are extremely rare and hardly ever encountered. -+ Thanks for Karthikeyan Bhargavan of the PROSECCO team at INRIA or reporting -+ this issue. -+ (CVE-2015-0205) -+ [Steve Henson] -+ -+ *) Ensure that the session ID context of an SSL is updated when its -+ SSL_CTX is updated via SSL_set_SSL_CTX. -+ -+ The session ID context is typically set from the parent SSL_CTX, -+ and can vary with the CTX. -+ [Adam Langley] -+ -+ *) Fix various certificate fingerprint issues. -+ -+ By using non-DER or invalid encodings outside the signed portion of a -+ certificate the fingerprint can be changed without breaking the signature. -+ Although no details of the signed portion of the certificate can be changed -+ this can cause problems with some applications: e.g. those using the -+ certificate fingerprint for blacklists. -+ -+ 1. Reject signatures with non zero unused bits. -+ -+ If the BIT STRING containing the signature has non zero unused bits reject -+ the signature. All current signature algorithms require zero unused bits. -+ -+ 2. Check certificate algorithm consistency. -+ -+ Check the AlgorithmIdentifier inside TBS matches the one in the -+ certificate signature. NB: this will result in signature failure -+ errors for some broken certificates. -+ -+ Thanks to Konrad Kraszewski from Google for reporting this issue. -+ -+ 3. Check DSA/ECDSA signatures use DER. -+ -+ Re-encode DSA/ECDSA signatures and compare with the original received -+ signature. Return an error if there is a mismatch. -+ -+ This will reject various cases including garbage after signature -+ (thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS -+ program for discovering this case) and use of BER or invalid ASN.1 INTEGERs -+ (negative or with leading zeroes). -+ -+ Further analysis was conducted and fixes were developed by Stephen Henson -+ of the OpenSSL core team. -+ -+ (CVE-2014-8275) -+ [Steve Henson] -+ -+ *) Correct Bignum squaring. Bignum squaring (BN_sqr) may produce incorrect -+ results on some platforms, including x86_64. This bug occurs at random -+ with a very low probability, and is not known to be exploitable in any -+ way, though its exact impact is difficult to determine. Thanks to Pieter -+ Wuille (Blockstream) who reported this issue and also suggested an initial -+ fix. Further analysis was conducted by the OpenSSL development team and -+ Adam Langley of Google. The final fix was developed by Andy Polyakov of -+ the OpenSSL core team. -+ (CVE-2014-3570) -+ [Andy Polyakov] -+ -+ *) Do not resume sessions on the server if the negotiated protocol -+ version does not match the session's version. Resuming with a different -+ version, while not strictly forbidden by the RFC, is of questionable -+ sanity and breaks all known clients. -+ [David Benjamin, Emilia Käsper] -+ -+ *) Tighten handling of the ChangeCipherSpec (CCS) message: reject -+ early CCS messages during renegotiation. (Note that because -+ renegotiation is encrypted, this early CCS was not exploitable.) -+ [Emilia Käsper] -+ -+ *) Tighten client-side session ticket handling during renegotiation: -+ ensure that the client only accepts a session ticket if the server sends -+ the extension anew in the ServerHello. Previously, a TLS client would -+ reuse the old extension state and thus accept a session ticket if one was -+ announced in the initial ServerHello. -+ -+ Similarly, ensure that the client requires a session ticket if one -+ was advertised in the ServerHello. Previously, a TLS client would -+ ignore a missing NewSessionTicket message. -+ [Emilia Käsper] -+ -+ Changes between 1.0.1i and 1.0.1j [15 Oct 2014] -+ -+ *) SRTP Memory Leak. -+ -+ A flaw in the DTLS SRTP extension parsing code allows an attacker, who -+ sends a carefully crafted handshake message, to cause OpenSSL to fail -+ to free up to 64k of memory causing a memory leak. This could be -+ exploited in a Denial Of Service attack. This issue affects OpenSSL -+ 1.0.1 server implementations for both SSL/TLS and DTLS regardless of -+ whether SRTP is used or configured. Implementations of OpenSSL that -+ have been compiled with OPENSSL_NO_SRTP defined are not affected. -+ -+ The fix was developed by the OpenSSL team. -+ (CVE-2014-3513) -+ [OpenSSL team] -+ -+ *) Session Ticket Memory Leak. -+ -+ When an OpenSSL SSL/TLS/DTLS server receives a session ticket the -+ integrity of that ticket is first verified. In the event of a session -+ ticket integrity check failing, OpenSSL will fail to free memory -+ causing a memory leak. By sending a large number of invalid session -+ tickets an attacker could exploit this issue in a Denial Of Service -+ attack. -+ (CVE-2014-3567) -+ [Steve Henson] -+ -+ *) Build option no-ssl3 is incomplete. -+ -+ When OpenSSL is configured with "no-ssl3" as a build option, servers -+ could accept and complete a SSL 3.0 handshake, and clients could be -+ configured to send them. -+ (CVE-2014-3568) -+ [Akamai and the OpenSSL team] -+ -+ *) Add support for TLS_FALLBACK_SCSV. -+ Client applications doing fallback retries should call -+ SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV). -+ (CVE-2014-3566) -+ [Adam Langley, Bodo Moeller] -+ -+ *) Add additional DigestInfo checks. -+ -+ Re-encode DigestInto in DER and check against the original when -+ verifying RSA signature: this will reject any improperly encoded -+ DigestInfo structures. -+ -+ Note: this is a precautionary measure and no attacks are currently known. -+ -+ [Steve Henson] -+ -+ Changes between 1.0.1h and 1.0.1i [6 Aug 2014] -+ -+ *) Fix SRP buffer overrun vulnerability. Invalid parameters passed to the -+ SRP code can be overrun an internal buffer. Add sanity check that -+ g, A, B < N to SRP code. -+ -+ Thanks to Sean Devlin and Watson Ladd of Cryptography Services, NCC -+ Group for discovering this issue. -+ (CVE-2014-3512) -+ [Steve Henson] -+ -+ *) A flaw in the OpenSSL SSL/TLS server code causes the server to negotiate -+ TLS 1.0 instead of higher protocol versions when the ClientHello message -+ is badly fragmented. This allows a man-in-the-middle attacker to force a -+ downgrade to TLS 1.0 even if both the server and the client support a -+ higher protocol version, by modifying the client's TLS records. -+ -+ Thanks to David Benjamin and Adam Langley (Google) for discovering and -+ researching this issue. -+ (CVE-2014-3511) -+ [David Benjamin] -+ -+ *) OpenSSL DTLS clients enabling anonymous (EC)DH ciphersuites are subject -+ to a denial of service attack. A malicious server can crash the client -+ with a null pointer dereference (read) by specifying an anonymous (EC)DH -+ ciphersuite and sending carefully crafted handshake messages. -+ -+ Thanks to Felix Gröbert (Google) for discovering and researching this -+ issue. -+ (CVE-2014-3510) -+ [Emilia Käsper] -+ -+ *) By sending carefully crafted DTLS packets an attacker could cause openssl -+ to leak memory. This can be exploited through a Denial of Service attack. -+ Thanks to Adam Langley for discovering and researching this issue. -+ (CVE-2014-3507) -+ [Adam Langley] -+ -+ *) An attacker can force openssl to consume large amounts of memory whilst -+ processing DTLS handshake messages. This can be exploited through a -+ Denial of Service attack. -+ Thanks to Adam Langley for discovering and researching this issue. -+ (CVE-2014-3506) -+ [Adam Langley] -+ -+ *) An attacker can force an error condition which causes openssl to crash -+ whilst processing DTLS packets due to memory being freed twice. This -+ can be exploited through a Denial of Service attack. -+ Thanks to Adam Langley and Wan-Teh Chang for discovering and researching -+ this issue. -+ (CVE-2014-3505) -+ [Adam Langley] -+ -+ *) If a multithreaded client connects to a malicious server using a resumed -+ session and the server sends an ec point format extension it could write -+ up to 255 bytes to freed memory. -+ -+ Thanks to Gabor Tyukasz (LogMeIn Inc) for discovering and researching this -+ issue. -+ (CVE-2014-3509) -+ [Gabor Tyukasz] -+ -+ *) A malicious server can crash an OpenSSL client with a null pointer -+ dereference (read) by specifying an SRP ciphersuite even though it was not -+ properly negotiated with the client. This can be exploited through a -+ Denial of Service attack. -+ -+ Thanks to Joonas Kuorilehto and Riku Hietamäki (Codenomicon) for -+ discovering and researching this issue. -+ (CVE-2014-5139) -+ [Steve Henson] -+ -+ *) A flaw in OBJ_obj2txt may cause pretty printing functions such as -+ X509_name_oneline, X509_name_print_ex et al. to leak some information -+ from the stack. Applications may be affected if they echo pretty printing -+ output to the attacker. -+ -+ Thanks to Ivan Fratric (Google) for discovering this issue. -+ (CVE-2014-3508) -+ [Emilia Käsper, and Steve Henson] -+ -+ *) Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.) -+ for corner cases. (Certain input points at infinity could lead to -+ bogus results, with non-infinity inputs mapped to infinity too.) -+ [Bodo Moeller] -+ -+ Changes between 1.0.1g and 1.0.1h [5 Jun 2014] -+ -+ *) Fix for SSL/TLS MITM flaw. An attacker using a carefully crafted -+ handshake can force the use of weak keying material in OpenSSL -+ SSL/TLS clients and servers. -+ -+ Thanks to KIKUCHI Masashi (Lepidum Co. Ltd.) for discovering and -+ researching this issue. (CVE-2014-0224) -+ [KIKUCHI Masashi, Steve Henson] -+ -+ *) Fix DTLS recursion flaw. By sending an invalid DTLS handshake to an -+ OpenSSL DTLS client the code can be made to recurse eventually crashing -+ in a DoS attack. -+ -+ Thanks to Imre Rad (Search-Lab Ltd.) for discovering this issue. -+ (CVE-2014-0221) -+ [Imre Rad, Steve Henson] -+ -+ *) Fix DTLS invalid fragment vulnerability. A buffer overrun attack can -+ be triggered by sending invalid DTLS fragments to an OpenSSL DTLS -+ client or server. This is potentially exploitable to run arbitrary -+ code on a vulnerable client or server. -+ -+ Thanks to Jüri Aedla for reporting this issue. (CVE-2014-0195) -+ [Jüri Aedla, Steve Henson] -+ -+ *) Fix bug in TLS code where clients enable anonymous ECDH ciphersuites -+ are subject to a denial of service attack. -+ -+ Thanks to Felix Gröbert and Ivan Fratric at Google for discovering -+ this issue. (CVE-2014-3470) -+ [Felix Gröbert, Ivan Fratric, Steve Henson] -+ -+ *) Harmonize version and its documentation. -f flag is used to display -+ compilation flags. -+ [mancha ] -+ -+ *) Fix eckey_priv_encode so it immediately returns an error upon a failure -+ in i2d_ECPrivateKey. -+ [mancha ] -+ -+ *) Fix some double frees. These are not thought to be exploitable. -+ [mancha ] -+ -+ Changes between 1.0.1f and 1.0.1g [7 Apr 2014] -+ -+ *) A missing bounds check in the handling of the TLS heartbeat extension -+ can be used to reveal up to 64k of memory to a connected client or -+ server. -+ -+ Thanks for Neel Mehta of Google Security for discovering this bug and to -+ Adam Langley and Bodo Moeller for -+ preparing the fix (CVE-2014-0160) -+ [Adam Langley, Bodo Moeller] -+ -+ *) Fix for the attack described in the paper "Recovering OpenSSL -+ ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack" -+ by Yuval Yarom and Naomi Benger. Details can be obtained from: -+ http://eprint.iacr.org/2014/140 -+ -+ Thanks to Yuval Yarom and Naomi Benger for discovering this -+ flaw and to Yuval Yarom for supplying a fix (CVE-2014-0076) -+ [Yuval Yarom and Naomi Benger] -+ -+ *) TLS pad extension: draft-agl-tls-padding-03 -+ -+ Workaround for the "TLS hang bug" (see FAQ and PR#2771): if the -+ TLS client Hello record length value would otherwise be > 255 and -+ less that 512 pad with a dummy extension containing zeroes so it -+ is at least 512 bytes long. -+ -+ [Adam Langley, Steve Henson] -+ -+ Changes between 1.0.1e and 1.0.1f [6 Jan 2014] -+ -+ *) Fix for TLS record tampering bug. A carefully crafted invalid -+ handshake could crash OpenSSL with a NULL pointer exception. -+ Thanks to Anton Johansson for reporting this issues. -+ (CVE-2013-4353) -+ -+ *) Keep original DTLS digest and encryption contexts in retransmission -+ structures so we can use the previous session parameters if they need -+ to be resent. (CVE-2013-6450) -+ [Steve Henson] -+ -+ *) Add option SSL_OP_SAFARI_ECDHE_ECDSA_BUG (part of SSL_OP_ALL) which -+ avoids preferring ECDHE-ECDSA ciphers when the client appears to be -+ Safari on OS X. Safari on OS X 10.8..10.8.3 advertises support for -+ several ECDHE-ECDSA ciphers, but fails to negotiate them. The bug -+ is fixed in OS X 10.8.4, but Apple have ruled out both hot fixing -+ 10.8..10.8.3 and forcing users to upgrade to 10.8.4 or newer. -+ [Rob Stradling, Adam Langley] -+ -+ Changes between 1.0.1d and 1.0.1e [11 Feb 2013] -+ -+ *) Correct fix for CVE-2013-0169. The original didn't work on AES-NI -+ supporting platforms or when small records were transferred. -+ [Andy Polyakov, Steve Henson] -+ -+ Changes between 1.0.1c and 1.0.1d [5 Feb 2013] -+ -+ *) Make the decoding of SSLv3, TLS and DTLS CBC records constant time. -+ -+ This addresses the flaw in CBC record processing discovered by -+ Nadhem Alfardan and Kenny Paterson. Details of this attack can be found -+ at: http://www.isg.rhul.ac.uk/tls/ -+ -+ Thanks go to Nadhem Alfardan and Kenny Paterson of the Information -+ Security Group at Royal Holloway, University of London -+ (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and -+ Emilia Käsper for the initial patch. -+ (CVE-2013-0169) -+ [Emilia Käsper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson] -+ -+ *) Fix flaw in AESNI handling of TLS 1.2 and 1.1 records for CBC mode -+ ciphersuites which can be exploited in a denial of service attack. -+ Thanks go to and to Adam Langley for discovering -+ and detecting this bug and to Wolfgang Ettlinger -+ for independently discovering this issue. -+ (CVE-2012-2686) -+ [Adam Langley] -+ -+ *) Return an error when checking OCSP signatures when key is NULL. -+ This fixes a DoS attack. (CVE-2013-0166) -+ [Steve Henson] -+ -+ *) Make openssl verify return errors. -+ [Chris Palmer and Ben Laurie] -+ -+ *) Call OCSP Stapling callback after ciphersuite has been chosen, so -+ the right response is stapled. Also change SSL_get_certificate() -+ so it returns the certificate actually sent. -+ See http://rt.openssl.org/Ticket/Display.html?id=2836. -+ [Rob Stradling ] -+ -+ *) Fix possible deadlock when decoding public keys. -+ [Steve Henson] -+ -+ *) Don't use TLS 1.0 record version number in initial client hello -+ if renegotiating. -+ [Steve Henson] -+ -+ Changes between 1.0.1b and 1.0.1c [10 May 2012] -+ -+ *) Sanity check record length before skipping explicit IV in TLS -+ 1.2, 1.1 and DTLS to fix DoS attack. -+ -+ Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic -+ fuzzing as a service testing platform. -+ (CVE-2012-2333) -+ [Steve Henson] -+ -+ *) Initialise tkeylen properly when encrypting CMS messages. -+ Thanks to Solar Designer of Openwall for reporting this issue. -+ [Steve Henson] -+ -+ *) In FIPS mode don't try to use composite ciphers as they are not -+ approved. -+ [Steve Henson] -+ -+ Changes between 1.0.1a and 1.0.1b [26 Apr 2012] -+ -+ *) OpenSSL 1.0.0 sets SSL_OP_ALL to 0x80000FFFL and OpenSSL 1.0.1 and -+ 1.0.1a set SSL_OP_NO_TLSv1_1 to 0x00000400L which would unfortunately -+ mean any application compiled against OpenSSL 1.0.0 headers setting -+ SSL_OP_ALL would also set SSL_OP_NO_TLSv1_1, unintentionally disablng -+ TLS 1.1 also. Fix this by changing the value of SSL_OP_NO_TLSv1_1 to -+ 0x10000000L Any application which was previously compiled against -+ OpenSSL 1.0.1 or 1.0.1a headers and which cares about SSL_OP_NO_TLSv1_1 -+ will need to be recompiled as a result. Letting be results in -+ inability to disable specifically TLS 1.1 and in client context, -+ in unlike event, limit maximum offered version to TLS 1.0 [see below]. -+ [Steve Henson] -+ -+ *) In order to ensure interoperabilty SSL_OP_NO_protocolX does not -+ disable just protocol X, but all protocols above X *if* there are -+ protocols *below* X still enabled. In more practical terms it means -+ that if application wants to disable TLS1.0 in favor of TLS1.1 and -+ above, it's not sufficient to pass SSL_OP_NO_TLSv1, one has to pass -+ SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. This applies to -+ client side. -+ [Andy Polyakov] -+ -+ Changes between 1.0.1 and 1.0.1a [19 Apr 2012] -+ -+ *) Check for potentially exploitable overflows in asn1_d2i_read_bio -+ BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer -+ in CRYPTO_realloc_clean. -+ -+ Thanks to Tavis Ormandy, Google Security Team, for discovering this -+ issue and to Adam Langley for fixing it. -+ (CVE-2012-2110) -+ [Adam Langley (Google), Tavis Ormandy, Google Security Team] -+ -+ *) Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections. -+ [Adam Langley] -+ -+ *) Workarounds for some broken servers that "hang" if a client hello -+ record length exceeds 255 bytes. -+ -+ 1. Do not use record version number > TLS 1.0 in initial client -+ hello: some (but not all) hanging servers will now work. -+ 2. If we set OPENSSL_MAX_TLS1_2_CIPHER_LENGTH this will truncate -+ the number of ciphers sent in the client hello. This should be -+ set to an even number, such as 50, for example by passing: -+ -DOPENSSL_MAX_TLS1_2_CIPHER_LENGTH=50 to config or Configure. -+ Most broken servers should now work. -+ 3. If all else fails setting OPENSSL_NO_TLS1_2_CLIENT will disable -+ TLS 1.2 client support entirely. -+ [Steve Henson] -+ -+ *) Fix SEGV in Vector Permutation AES module observed in OpenSSH. -+ [Andy Polyakov] -+ -+ Changes between 1.0.0h and 1.0.1 [14 Mar 2012] -+ -+ *) Add compatibility with old MDC2 signatures which use an ASN1 OCTET -+ STRING form instead of a DigestInfo. -+ [Steve Henson] -+ -+ *) The format used for MDC2 RSA signatures is inconsistent between EVP -+ and the RSA_sign/RSA_verify functions. This was made more apparent when -+ OpenSSL used RSA_sign/RSA_verify for some RSA signatures in particular -+ those which went through EVP_PKEY_METHOD in 1.0.0 and later. Detect -+ the correct format in RSA_verify so both forms transparently work. -+ [Steve Henson] -+ -+ *) Some servers which support TLS 1.0 can choke if we initially indicate -+ support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA -+ encrypted premaster secret. As a workaround use the maximum permitted -+ client version in client hello, this should keep such servers happy -+ and still work with previous versions of OpenSSL. -+ [Steve Henson] -+ -+ *) Add support for TLS/DTLS heartbeats. -+ [Robin Seggelmann ] -+ -+ *) Add support for SCTP. -+ [Robin Seggelmann ] -+ -+ *) Improved PRNG seeding for VOS. -+ [Paul Green ] -+ -+ *) Extensive assembler packs updates, most notably: -+ -+ - x86[_64]: AES-NI, PCLMULQDQ, RDRAND support; -+ - x86[_64]: SSSE3 support (SHA1, vector-permutation AES); -+ - x86_64: bit-sliced AES implementation; -+ - ARM: NEON support, contemporary platforms optimizations; -+ - s390x: z196 support; -+ - *: GHASH and GF(2^m) multiplication implementations; -+ -+ [Andy Polyakov] -+ -+ *) Make TLS-SRP code conformant with RFC 5054 API cleanup -+ (removal of unnecessary code) -+ [Peter Sylvester ] -+ -+ *) Add TLS key material exporter from RFC 5705. -+ [Eric Rescorla] -+ -+ *) Add DTLS-SRTP negotiation from RFC 5764. -+ [Eric Rescorla] -+ -+ *) Add Next Protocol Negotiation, -+ http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-00. Can be -+ disabled with a no-npn flag to config or Configure. Code donated -+ by Google. -+ [Adam Langley and Ben Laurie] -+ -+ *) Add optional 64-bit optimized implementations of elliptic curves NIST-P224, -+ NIST-P256, NIST-P521, with constant-time single point multiplication on -+ typical inputs. Compiler support for the nonstandard type __uint128_t is -+ required to use this (present in gcc 4.4 and later, for 64-bit builds). -+ Code made available under Apache License version 2.0. -+ -+ Specify "enable-ec_nistp_64_gcc_128" on the Configure (or config) command -+ line to include this in your build of OpenSSL, and run "make depend" (or -+ "make update"). This enables the following EC_METHODs: -+ -+ EC_GFp_nistp224_method() -+ EC_GFp_nistp256_method() -+ EC_GFp_nistp521_method() -+ -+ EC_GROUP_new_by_curve_name() will automatically use these (while -+ EC_GROUP_new_curve_GFp() currently prefers the more flexible -+ implementations). -+ [Emilia Käsper, Adam Langley, Bodo Moeller (Google)] -+ -+ *) Use type ossl_ssize_t instad of ssize_t which isn't available on -+ all platforms. Move ssize_t definition from e_os.h to the public -+ header file e_os2.h as it now appears in public header file cms.h -+ [Steve Henson] -+ -+ *) New -sigopt option to the ca, req and x509 utilities. Additional -+ signature parameters can be passed using this option and in -+ particular PSS. -+ [Steve Henson] -+ -+ *) Add RSA PSS signing function. This will generate and set the -+ appropriate AlgorithmIdentifiers for PSS based on those in the -+ corresponding EVP_MD_CTX structure. No application support yet. -+ [Steve Henson] -+ -+ *) Support for companion algorithm specific ASN1 signing routines. -+ New function ASN1_item_sign_ctx() signs a pre-initialised -+ EVP_MD_CTX structure and sets AlgorithmIdentifiers based on -+ the appropriate parameters. -+ [Steve Henson] -+ -+ *) Add new algorithm specific ASN1 verification initialisation function -+ to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1 -+ handling will be the same no matter what EVP_PKEY_METHOD is used. -+ Add a PSS handler to support verification of PSS signatures: checked -+ against a number of sample certificates. -+ [Steve Henson] -+ -+ *) Add signature printing for PSS. Add PSS OIDs. -+ [Steve Henson, Martin Kaiser ] -+ -+ *) Add algorithm specific signature printing. An individual ASN1 method -+ can now print out signatures instead of the standard hex dump. -+ -+ More complex signatures (e.g. PSS) can print out more meaningful -+ information. Include DSA version that prints out the signature -+ parameters r, s. -+ [Steve Henson] -+ -+ *) Password based recipient info support for CMS library: implementing -+ RFC3211. -+ [Steve Henson] -+ -+ *) Split password based encryption into PBES2 and PBKDF2 functions. This -+ neatly separates the code into cipher and PBE sections and is required -+ for some algorithms that split PBES2 into separate pieces (such as -+ password based CMS). -+ [Steve Henson] -+ -+ *) Session-handling fixes: -+ - Fix handling of connections that are resuming with a session ID, -+ but also support Session Tickets. -+ - Fix a bug that suppressed issuing of a new ticket if the client -+ presented a ticket with an expired session. -+ - Try to set the ticket lifetime hint to something reasonable. -+ - Make tickets shorter by excluding irrelevant information. -+ - On the client side, don't ignore renewed tickets. -+ [Adam Langley, Bodo Moeller (Google)] -+ -+ *) Fix PSK session representation. -+ [Bodo Moeller] -+ -+ *) Add RC4-MD5 and AESNI-SHA1 "stitched" implementations. -+ -+ This work was sponsored by Intel. -+ [Andy Polyakov] -+ -+ *) Add GCM support to TLS library. Some custom code is needed to split -+ the IV between the fixed (from PRF) and explicit (from TLS record) -+ portions. This adds all GCM ciphersuites supported by RFC5288 and -+ RFC5289. Generalise some AES* cipherstrings to include GCM and -+ add a special AESGCM string for GCM only. -+ [Steve Henson] -+ -+ *) Expand range of ctrls for AES GCM. Permit setting invocation -+ field on decrypt and retrieval of invocation field only on encrypt. -+ [Steve Henson] -+ -+ *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support. -+ As required by RFC5289 these ciphersuites cannot be used if for -+ versions of TLS earlier than 1.2. -+ [Steve Henson] -+ -+ *) For FIPS capable OpenSSL interpret a NULL default public key method -+ as unset and return the appropriate default but do *not* set the default. -+ This means we can return the appropriate method in applications that -+ switch between FIPS and non-FIPS modes. -+ [Steve Henson] -+ -+ *) Redirect HMAC and CMAC operations to FIPS module in FIPS mode. If an -+ ENGINE is used then we cannot handle that in the FIPS module so we -+ keep original code iff non-FIPS operations are allowed. -+ [Steve Henson] -+ -+ *) Add -attime option to openssl utilities. -+ [Peter Eckersley , Ben Laurie and Steve Henson] -+ -+ *) Redirect DSA and DH operations to FIPS module in FIPS mode. -+ [Steve Henson] -+ -+ *) Redirect ECDSA and ECDH operations to FIPS module in FIPS mode. Also use -+ FIPS EC methods unconditionally for now. -+ [Steve Henson] -+ -+ *) New build option no-ec2m to disable characteristic 2 code. -+ [Steve Henson] -+ -+ *) Backport libcrypto audit of return value checking from 1.1.0-dev; not -+ all cases can be covered as some introduce binary incompatibilities. -+ [Steve Henson] -+ -+ *) Redirect RSA operations to FIPS module including keygen, -+ encrypt, decrypt, sign and verify. Block use of non FIPS RSA methods. -+ [Steve Henson] -+ -+ *) Add similar low level API blocking to ciphers. -+ [Steve Henson] -+ -+ *) Low level digest APIs are not approved in FIPS mode: any attempt -+ to use these will cause a fatal error. Applications that *really* want -+ to use them can use the private_* version instead. -+ [Steve Henson] -+ -+ *) Redirect cipher operations to FIPS module for FIPS builds. -+ [Steve Henson] -+ -+ *) Redirect digest operations to FIPS module for FIPS builds. -+ [Steve Henson] -+ -+ *) Update build system to add "fips" flag which will link in fipscanister.o -+ for static and shared library builds embedding a signature if needed. -+ [Steve Henson] -+ -+ *) Output TLS supported curves in preference order instead of numerical -+ order. This is currently hardcoded for the highest order curves first. -+ This should be configurable so applications can judge speed vs strength. -+ [Steve Henson] -+ -+ *) Add TLS v1.2 server support for client authentication. -+ [Steve Henson] -+ -+ *) Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers -+ and enable MD5. -+ [Steve Henson] -+ -+ *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying -+ FIPS modules versions. -+ [Steve Henson] -+ -+ *) Add TLS v1.2 client side support for client authentication. Keep cache -+ of handshake records longer as we don't know the hash algorithm to use -+ until after the certificate request message is received. -+ [Steve Henson] -+ -+ *) Initial TLS v1.2 client support. Add a default signature algorithms -+ extension including all the algorithms we support. Parse new signature -+ format in client key exchange. Relax some ECC signing restrictions for -+ TLS v1.2 as indicated in RFC5246. -+ [Steve Henson] -+ -+ *) Add server support for TLS v1.2 signature algorithms extension. Switch -+ to new signature format when needed using client digest preference. -+ All server ciphersuites should now work correctly in TLS v1.2. No client -+ support yet and no support for client certificates. -+ [Steve Henson] -+ -+ *) Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch -+ to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based -+ ciphersuites. At present only RSA key exchange ciphersuites work with -+ TLS v1.2. Add new option for TLS v1.2 replacing the old and obsolete -+ SSL_OP_PKCS1_CHECK flags with SSL_OP_NO_TLSv1_2. New TLSv1.2 methods -+ and version checking. -+ [Steve Henson] -+ -+ *) New option OPENSSL_NO_SSL_INTERN. If an application can be compiled -+ with this defined it will not be affected by any changes to ssl internal -+ structures. Add several utility functions to allow openssl application -+ to work with OPENSSL_NO_SSL_INTERN defined. -+ [Steve Henson] -+ -+ *) Add SRP support. -+ [Tom Wu and Ben Laurie] -+ -+ *) Add functions to copy EVP_PKEY_METHOD and retrieve flags and id. -+ [Steve Henson] -+ -+ *) Permit abbreviated handshakes when renegotiating using the function -+ SSL_renegotiate_abbreviated(). -+ [Robin Seggelmann ] -+ -+ *) Add call to ENGINE_register_all_complete() to -+ ENGINE_load_builtin_engines(), so some implementations get used -+ automatically instead of needing explicit application support. -+ [Steve Henson] -+ -+ *) Add support for TLS key exporter as described in RFC5705. -+ [Robin Seggelmann , Steve Henson] -+ -+ *) Initial TLSv1.1 support. Since TLSv1.1 is very similar to TLS v1.0 only -+ a few changes are required: -+ -+ Add SSL_OP_NO_TLSv1_1 flag. -+ Add TLSv1_1 methods. -+ Update version checking logic to handle version 1.1. -+ Add explicit IV handling (ported from DTLS code). -+ Add command line options to s_client/s_server. -+ [Steve Henson] -+ -+ Changes between 1.0.0g and 1.0.0h [12 Mar 2012] -+ -+ *) Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness -+ in CMS and PKCS7 code. When RSA decryption fails use a random key for -+ content decryption and always return the same error. Note: this attack -+ needs on average 2^20 messages so it only affects automated senders. The -+ old behaviour can be re-enabled in the CMS code by setting the -+ CMS_DEBUG_DECRYPT flag: this is useful for debugging and testing where -+ an MMA defence is not necessary. -+ Thanks to Ivan Nestlerode for discovering -+ this issue. (CVE-2012-0884) -+ [Steve Henson] -+ -+ *) Fix CVE-2011-4619: make sure we really are receiving a -+ client hello before rejecting multiple SGC restarts. Thanks to -+ Ivan Nestlerode for discovering this bug. -+ [Steve Henson] -+ -+ Changes between 1.0.0f and 1.0.0g [18 Jan 2012] -+ -+ *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109. -+ Thanks to Antonio Martin, Enterprise Secure Access Research and -+ Development, Cisco Systems, Inc. for discovering this bug and -+ preparing a fix. (CVE-2012-0050) -+ [Antonio Martin] -+ -+ Changes between 1.0.0e and 1.0.0f [4 Jan 2012] -+ -+ *) Nadhem Alfardan and Kenny Paterson have discovered an extension -+ of the Vaudenay padding oracle attack on CBC mode encryption -+ which enables an efficient plaintext recovery attack against -+ the OpenSSL implementation of DTLS. Their attack exploits timing -+ differences arising during decryption processing. A research -+ paper describing this attack can be found at: -+ http://www.isg.rhul.ac.uk/~kp/dtls.pdf -+ Thanks go to Nadhem Alfardan and Kenny Paterson of the Information -+ Security Group at Royal Holloway, University of London -+ (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann -+ and Michael Tuexen -+ for preparing the fix. (CVE-2011-4108) -+ [Robin Seggelmann, Michael Tuexen] -+ -+ *) Clear bytes used for block padding of SSL 3.0 records. -+ (CVE-2011-4576) -+ [Adam Langley (Google)] -+ -+ *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George -+ Kadianakis for discovering this issue and -+ Adam Langley for preparing the fix. (CVE-2011-4619) -+ [Adam Langley (Google)] -+ -+ *) Check parameters are not NULL in GOST ENGINE. (CVE-2012-0027) -+ [Andrey Kulikov ] -+ -+ *) Prevent malformed RFC3779 data triggering an assertion failure. -+ Thanks to Andrew Chi, BBN Technologies, for discovering the flaw -+ and Rob Austein for fixing it. (CVE-2011-4577) -+ [Rob Austein ] -+ -+ *) Improved PRNG seeding for VOS. -+ [Paul Green ] -+ -+ *) Fix ssl_ciph.c set-up race. -+ [Adam Langley (Google)] -+ -+ *) Fix spurious failures in ecdsatest.c. -+ [Emilia Käsper (Google)] -+ -+ *) Fix the BIO_f_buffer() implementation (which was mixing different -+ interpretations of the '..._len' fields). -+ [Adam Langley (Google)] -+ -+ *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than -+ BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent -+ threads won't reuse the same blinding coefficients. -+ -+ This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING -+ lock to call BN_BLINDING_invert_ex, and avoids one use of -+ BN_BLINDING_update for each BN_BLINDING structure (previously, -+ the last update always remained unused). -+ [Emilia Käsper (Google)] -+ -+ *) In ssl3_clear, preserve s3->init_extra along with s3->rbuf. -+ [Bob Buckholz (Google)] -+ -+ Changes between 1.0.0d and 1.0.0e [6 Sep 2011] -+ -+ *) Fix bug where CRLs with nextUpdate in the past are sometimes accepted -+ by initialising X509_STORE_CTX properly. (CVE-2011-3207) -+ [Kaspar Brand ] -+ -+ *) Fix SSL memory handling for (EC)DH ciphersuites, in particular -+ for multi-threaded use of ECDH. (CVE-2011-3210) -+ [Adam Langley (Google)] -+ -+ *) Fix x509_name_ex_d2i memory leak on bad inputs. -+ [Bodo Moeller] -+ -+ *) Remove hard coded ecdsaWithSHA1 signature tests in ssl code and check -+ signature public key algorithm by using OID xref utilities instead. -+ Before this you could only use some ECC ciphersuites with SHA1 only. -+ [Steve Henson] -+ -+ *) Add protection against ECDSA timing attacks as mentioned in the paper -+ by Billy Bob Brumley and Nicola Tuveri, see: -+ -+ http://eprint.iacr.org/2011/232.pdf -+ -+ [Billy Bob Brumley and Nicola Tuveri] -+ -+ Changes between 1.0.0c and 1.0.0d [8 Feb 2011] -+ -+ *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014 -+ [Neel Mehta, Adam Langley, Bodo Moeller (Google)] -+ -+ *) Fix bug in string printing code: if *any* escaping is enabled we must -+ escape the escape character (backslash) or the resulting string is -+ ambiguous. -+ [Steve Henson] -+ -+ Changes between 1.0.0b and 1.0.0c [2 Dec 2010] -+ -+ *) Disable code workaround for ancient and obsolete Netscape browsers -+ and servers: an attacker can use it in a ciphersuite downgrade attack. -+ Thanks to Martin Rex for discovering this bug. CVE-2010-4180 -+ [Steve Henson] -+ -+ *) Fixed J-PAKE implementation error, originally discovered by -+ Sebastien Martini, further info and confirmation from Stefan -+ Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252 -+ [Ben Laurie] -+ -+ Changes between 1.0.0a and 1.0.0b [16 Nov 2010] -+ -+ *) Fix extension code to avoid race conditions which can result in a buffer -+ overrun vulnerability: resumed sessions must not be modified as they can -+ be shared by multiple threads. CVE-2010-3864 -+ [Steve Henson] -+ -+ *) Fix WIN32 build system to correctly link an ENGINE directory into -+ a DLL. -+ [Steve Henson] -+ -+ Changes between 1.0.0 and 1.0.0a [01 Jun 2010] -+ -+ *) Check return value of int_rsa_verify in pkey_rsa_verifyrecover -+ (CVE-2010-1633) -+ [Steve Henson, Peter-Michael Hager ] -+ -+ Changes between 0.9.8n and 1.0.0 [29 Mar 2010] -+ -+ *) Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher -+ context. The operation can be customised via the ctrl mechanism in -+ case ENGINEs want to include additional functionality. -+ [Steve Henson] -+ -+ *) Tolerate yet another broken PKCS#8 key format: private key value negative. -+ [Steve Henson] -+ -+ *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to -+ output hashes compatible with older versions of OpenSSL. -+ [Willy Weisz ] -+ -+ *) Fix compression algorithm handling: if resuming a session use the -+ compression algorithm of the resumed session instead of determining -+ it from client hello again. Don't allow server to change algorithm. -+ [Steve Henson] -+ -+ *) Add load_crls() function to apps tidying load_certs() too. Add option -+ to verify utility to allow additional CRLs to be included. -+ [Steve Henson] -+ -+ *) Update OCSP request code to permit adding custom headers to the request: -+ some responders need this. -+ [Steve Henson] -+ -+ *) The function EVP_PKEY_sign() returns <=0 on error: check return code -+ correctly. -+ [Julia Lawall ] -+ -+ *) Update verify callback code in apps/s_cb.c and apps/verify.c, it -+ needlessly dereferenced structures, used obsolete functions and -+ didn't handle all updated verify codes correctly. -+ [Steve Henson] -+ -+ *) Disable MD2 in the default configuration. -+ [Steve Henson] -+ -+ *) In BIO_pop() and BIO_push() use the ctrl argument (which was NULL) to -+ indicate the initial BIO being pushed or popped. This makes it possible -+ to determine whether the BIO is the one explicitly called or as a result -+ of the ctrl being passed down the chain. Fix BIO_pop() and SSL BIOs so -+ it handles reference counts correctly and doesn't zero out the I/O bio -+ when it is not being explicitly popped. WARNING: applications which -+ included workarounds for the old buggy behaviour will need to be modified -+ or they could free up already freed BIOs. -+ [Steve Henson] -+ -+ *) Extend the uni2asc/asc2uni => OPENSSL_uni2asc/OPENSSL_asc2uni -+ renaming to all platforms (within the 0.9.8 branch, this was -+ done conditionally on Netware platforms to avoid a name clash). -+ [Guenter ] -+ -+ *) Add ECDHE and PSK support to DTLS. -+ [Michael Tuexen ] -+ -+ *) Add CHECKED_STACK_OF macro to safestack.h, otherwise safestack can't -+ be used on C++. -+ [Steve Henson] -+ -+ *) Add "missing" function EVP_MD_flags() (without this the only way to -+ retrieve a digest flags is by accessing the structure directly. Update -+ EVP_MD_do_all*() and EVP_CIPHER_do_all*() to include the name a digest -+ or cipher is registered as in the "from" argument. Print out all -+ registered digests in the dgst usage message instead of manually -+ attempting to work them out. -+ [Steve Henson] -+ -+ *) If no SSLv2 ciphers are used don't use an SSLv2 compatible client hello: -+ this allows the use of compression and extensions. Change default cipher -+ string to remove SSLv2 ciphersuites. This effectively avoids ancient SSLv2 -+ by default unless an application cipher string requests it. -+ [Steve Henson] -+ -+ *) Alter match criteria in PKCS12_parse(). It used to try to use local -+ key ids to find matching certificates and keys but some PKCS#12 files -+ don't follow the (somewhat unwritten) rules and this strategy fails. -+ Now just gather all certificates together and the first private key -+ then look for the first certificate that matches the key. -+ [Steve Henson] -+ -+ *) Support use of registered digest and cipher names for dgst and cipher -+ commands instead of having to add each one as a special case. So now -+ you can do: -+ -+ openssl sha256 foo -+ -+ as well as: -+ -+ openssl dgst -sha256 foo -+ -+ and this works for ENGINE based algorithms too. -+ -+ [Steve Henson] -+ -+ *) Update Gost ENGINE to support parameter files. -+ [Victor B. Wagner ] -+ -+ *) Support GeneralizedTime in ca utility. -+ [Oliver Martin , Steve Henson] -+ -+ *) Enhance the hash format used for certificate directory links. The new -+ form uses the canonical encoding (meaning equivalent names will work -+ even if they aren't identical) and uses SHA1 instead of MD5. This form -+ is incompatible with the older format and as a result c_rehash should -+ be used to rebuild symbolic links. -+ [Steve Henson] -+ -+ *) Make PKCS#8 the default write format for private keys, replacing the -+ traditional format. This form is standardised, more secure and doesn't -+ include an implicit MD5 dependency. -+ [Steve Henson] -+ -+ *) Add a $gcc_devteam_warn option to Configure. The idea is that any code -+ committed to OpenSSL should pass this lot as a minimum. -+ [Steve Henson] -+ -+ *) Add session ticket override functionality for use by EAP-FAST. -+ [Jouni Malinen ] -+ -+ *) Modify HMAC functions to return a value. Since these can be implemented -+ in an ENGINE errors can occur. -+ [Steve Henson] -+ -+ *) Type-checked OBJ_bsearch_ex. -+ [Ben Laurie] -+ -+ *) Type-checked OBJ_bsearch. Also some constification necessitated -+ by type-checking. Still to come: TXT_DB, bsearch(?), -+ OBJ_bsearch_ex, qsort, CRYPTO_EX_DATA, ASN1_VALUE, ASN1_STRING, -+ CONF_VALUE. -+ [Ben Laurie] -+ -+ *) New function OPENSSL_gmtime_adj() to add a specific number of days and -+ seconds to a tm structure directly, instead of going through OS -+ specific date routines. This avoids any issues with OS routines such -+ as the year 2038 bug. New *_adj() functions for ASN1 time structures -+ and X509_time_adj_ex() to cover the extended range. The existing -+ X509_time_adj() is still usable and will no longer have any date issues. -+ [Steve Henson] -+ -+ *) Delta CRL support. New use deltas option which will attempt to locate -+ and search any appropriate delta CRLs available. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) Support for CRLs partitioned by reason code. Reorganise CRL processing -+ code and add additional score elements. Validate alternate CRL paths -+ as part of the CRL checking and indicate a new error "CRL path validation -+ error" in this case. Applications wanting additional details can use -+ the verify callback and check the new "parent" field. If this is not -+ NULL CRL path validation is taking place. Existing applications won't -+ see this because it requires extended CRL support which is off by -+ default. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) Support for freshest CRL extension. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) Initial indirect CRL support. Currently only supported in the CRLs -+ passed directly and not via lookup. Process certificate issuer -+ CRL entry extension and lookup CRL entries by bother issuer name -+ and serial number. Check and process CRL issuer entry in IDP extension. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) Add support for distinct certificate and CRL paths. The CRL issuer -+ certificate is validated separately in this case. Only enabled if -+ an extended CRL support flag is set: this flag will enable additional -+ CRL functionality in future. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) Add support for policy mappings extension. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) Fixes to pathlength constraint, self issued certificate handling, -+ policy processing to align with RFC3280 and PKITS tests. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) Support for name constraints certificate extension. DN, email, DNS -+ and URI types are currently supported. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) To cater for systems that provide a pointer-based thread ID rather -+ than numeric, deprecate the current numeric thread ID mechanism and -+ replace it with a structure and associated callback type. This -+ mechanism allows a numeric "hash" to be extracted from a thread ID in -+ either case, and on platforms where pointers are larger than 'long', -+ mixing is done to help ensure the numeric 'hash' is usable even if it -+ can't be guaranteed unique. The default mechanism is to use "&errno" -+ as a pointer-based thread ID to distinguish between threads. -+ -+ Applications that want to provide their own thread IDs should now use -+ CRYPTO_THREADID_set_callback() to register a callback that will call -+ either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer(). -+ -+ Note that ERR_remove_state() is now deprecated, because it is tied -+ to the assumption that thread IDs are numeric. ERR_remove_state(0) -+ to free the current thread's error state should be replaced by -+ ERR_remove_thread_state(NULL). -+ -+ (This new approach replaces the functions CRYPTO_set_idptr_callback(), -+ CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in -+ OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an -+ application was previously providing a numeric thread callback that -+ was inappropriate for distinguishing threads, then uniqueness might -+ have been obtained with &errno that happened immediately in the -+ intermediate development versions of OpenSSL; this is no longer the -+ case, the numeric thread callback will now override the automatic use -+ of &errno.) -+ [Geoff Thorpe, with help from Bodo Moeller] -+ -+ *) Initial support for different CRL issuing certificates. This covers a -+ simple case where the self issued certificates in the chain exist and -+ the real CRL issuer is higher in the existing chain. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) Removed effectively defunct crypto/store from the build. -+ [Ben Laurie] -+ -+ *) Revamp of STACK to provide stronger type-checking. Still to come: -+ TXT_DB, bsearch(?), OBJ_bsearch, qsort, CRYPTO_EX_DATA, ASN1_VALUE, -+ ASN1_STRING, CONF_VALUE. -+ [Ben Laurie] -+ -+ *) Add a new SSL_MODE_RELEASE_BUFFERS mode flag to release unused buffer -+ RAM on SSL connections. This option can save about 34k per idle SSL. -+ [Nick Mathewson] -+ -+ *) Revamp of LHASH to provide stronger type-checking. Still to come: -+ STACK, TXT_DB, bsearch, qsort. -+ [Ben Laurie] -+ -+ *) Initial support for Cryptographic Message Syntax (aka CMS) based -+ on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility, -+ support for data, signedData, compressedData, digestedData and -+ encryptedData, envelopedData types included. Scripts to check against -+ RFC4134 examples draft and interop and consistency checks of many -+ content types and variants. -+ [Steve Henson] -+ -+ *) Add options to enc utility to support use of zlib compression BIO. -+ [Steve Henson] -+ -+ *) Extend mk1mf to support importing of options and assembly language -+ files from Configure script, currently only included in VC-WIN32. -+ The assembly language rules can now optionally generate the source -+ files from the associated perl scripts. -+ [Steve Henson] -+ -+ *) Implement remaining functionality needed to support GOST ciphersuites. -+ Interop testing has been performed using CryptoPro implementations. -+ [Victor B. Wagner ] -+ -+ *) s390x assembler pack. -+ [Andy Polyakov] -+ -+ *) ARMv4 assembler pack. ARMv4 refers to v4 and later ISA, not CPU -+ "family." -+ [Andy Polyakov] -+ -+ *) Implement Opaque PRF Input TLS extension as specified in -+ draft-rescorla-tls-opaque-prf-input-00.txt. Since this is not an -+ official specification yet and no extension type assignment by -+ IANA exists, this extension (for now) will have to be explicitly -+ enabled when building OpenSSL by providing the extension number -+ to use. For example, specify an option -+ -+ -DTLSEXT_TYPE_opaque_prf_input=0x9527 -+ -+ to the "config" or "Configure" script to enable the extension, -+ assuming extension number 0x9527 (which is a completely arbitrary -+ and unofficial assignment based on the MD5 hash of the Internet -+ Draft). Note that by doing so, you potentially lose -+ interoperability with other TLS implementations since these might -+ be using the same extension number for other purposes. -+ -+ SSL_set_tlsext_opaque_prf_input(ssl, src, len) is used to set the -+ opaque PRF input value to use in the handshake. This will create -+ an interal copy of the length-'len' string at 'src', and will -+ return non-zero for success. -+ -+ To get more control and flexibility, provide a callback function -+ by using -+ -+ SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) -+ SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) -+ -+ where -+ -+ int (*cb)(SSL *, void *peerinput, size_t len, void *arg); -+ void *arg; -+ -+ Callback function 'cb' will be called in handshakes, and is -+ expected to use SSL_set_tlsext_opaque_prf_input() as appropriate. -+ Argument 'arg' is for application purposes (the value as given to -+ SSL_CTX_set_tlsext_opaque_prf_input_callback_arg() will directly -+ be provided to the callback function). The callback function -+ has to return non-zero to report success: usually 1 to use opaque -+ PRF input just if possible, or 2 to enforce use of the opaque PRF -+ input. In the latter case, the library will abort the handshake -+ if opaque PRF input is not successfully negotiated. -+ -+ Arguments 'peerinput' and 'len' given to the callback function -+ will always be NULL and 0 in the case of a client. A server will -+ see the client's opaque PRF input through these variables if -+ available (NULL and 0 otherwise). Note that if the server -+ provides an opaque PRF input, the length must be the same as the -+ length of the client's opaque PRF input. -+ -+ Note that the callback function will only be called when creating -+ a new session (session resumption can resume whatever was -+ previously negotiated), and will not be called in SSL 2.0 -+ handshakes; thus, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) or -+ SSL_set_options(ssl, SSL_OP_NO_SSLv2) is especially recommended -+ for applications that need to enforce opaque PRF input. -+ -+ [Bodo Moeller] -+ -+ *) Update ssl code to support digests other than SHA1+MD5 for handshake -+ MAC. -+ -+ [Victor B. Wagner ] -+ -+ *) Add RFC4507 support to OpenSSL. This includes the corrections in -+ RFC4507bis. The encrypted ticket format is an encrypted encoded -+ SSL_SESSION structure, that way new session features are automatically -+ supported. -+ -+ If a client application caches session in an SSL_SESSION structure -+ support is transparent because tickets are now stored in the encoded -+ SSL_SESSION. -+ -+ The SSL_CTX structure automatically generates keys for ticket -+ protection in servers so again support should be possible -+ with no application modification. -+ -+ If a client or server wishes to disable RFC4507 support then the option -+ SSL_OP_NO_TICKET can be set. -+ -+ Add a TLS extension debugging callback to allow the contents of any client -+ or server extensions to be examined. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) Final changes to avoid use of pointer pointer casts in OpenSSL. -+ OpenSSL should now compile cleanly on gcc 4.2 -+ [Peter Hartley , Steve Henson] -+ -+ *) Update SSL library to use new EVP_PKEY MAC API. Include generic MAC -+ support including streaming MAC support: this is required for GOST -+ ciphersuite support. -+ [Victor B. Wagner , Steve Henson] -+ -+ *) Add option -stream to use PKCS#7 streaming in smime utility. New -+ function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream() -+ to output in BER and PEM format. -+ [Steve Henson] -+ -+ *) Experimental support for use of HMAC via EVP_PKEY interface. This -+ allows HMAC to be handled via the EVP_DigestSign*() interface. The -+ EVP_PKEY "key" in this case is the HMAC key, potentially allowing -+ ENGINE support for HMAC keys which are unextractable. New -mac and -+ -macopt options to dgst utility. -+ [Steve Henson] -+ -+ *) New option -sigopt to dgst utility. Update dgst to use -+ EVP_Digest{Sign,Verify}*. These two changes make it possible to use -+ alternative signing parameters such as X9.31 or PSS in the dgst -+ utility. -+ [Steve Henson] -+ -+ *) Change ssl_cipher_apply_rule(), the internal function that does -+ the work each time a ciphersuite string requests enabling -+ ("foo+bar"), moving ("+foo+bar"), disabling ("-foo+bar", or -+ removing ("!foo+bar") a class of ciphersuites: Now it maintains -+ the order of disabled ciphersuites such that those ciphersuites -+ that most recently went from enabled to disabled not only stay -+ in order with respect to each other, but also have higher priority -+ than other disabled ciphersuites the next time ciphersuites are -+ enabled again. -+ -+ This means that you can now say, e.g., "PSK:-PSK:HIGH" to enable -+ the same ciphersuites as with "HIGH" alone, but in a specific -+ order where the PSK ciphersuites come first (since they are the -+ most recently disabled ciphersuites when "HIGH" is parsed). -+ -+ Also, change ssl_create_cipher_list() (using this new -+ funcionality) such that between otherwise identical -+ cihpersuites, ephemeral ECDH is preferred over ephemeral DH in -+ the default order. -+ [Bodo Moeller] -+ -+ *) Change ssl_create_cipher_list() so that it automatically -+ arranges the ciphersuites in reasonable order before starting -+ to process the rule string. Thus, the definition for "DEFAULT" -+ (SSL_DEFAULT_CIPHER_LIST) now is just "ALL:!aNULL:!eNULL", but -+ remains equivalent to "AES:ALL:!aNULL:!eNULL:+aECDH:+kRSA:+RC4:@STRENGTH". -+ This makes it much easier to arrive at a reasonable default order -+ in applications for which anonymous ciphers are OK (meaning -+ that you can't actually use DEFAULT). -+ [Bodo Moeller; suggested by Victor Duchovni] -+ -+ *) Split the SSL/TLS algorithm mask (as used for ciphersuite string -+ processing) into multiple integers instead of setting -+ "SSL_MKEY_MASK" bits, "SSL_AUTH_MASK" bits, "SSL_ENC_MASK", -+ "SSL_MAC_MASK", and "SSL_SSL_MASK" bits all in a single integer. -+ (These masks as well as the individual bit definitions are hidden -+ away into the non-exported interface ssl/ssl_locl.h, so this -+ change to the definition of the SSL_CIPHER structure shouldn't -+ affect applications.) This give us more bits for each of these -+ categories, so there is no longer a need to coagulate AES128 and -+ AES256 into a single algorithm bit, and to coagulate Camellia128 -+ and Camellia256 into a single algorithm bit, which has led to all -+ kinds of kludges. -+ -+ Thus, among other things, the kludge introduced in 0.9.7m and -+ 0.9.8e for masking out AES256 independently of AES128 or masking -+ out Camellia256 independently of AES256 is not needed here in 0.9.9. -+ -+ With the change, we also introduce new ciphersuite aliases that -+ so far were missing: "AES128", "AES256", "CAMELLIA128", and -+ "CAMELLIA256". -+ [Bodo Moeller] -+ -+ *) Add support for dsa-with-SHA224 and dsa-with-SHA256. -+ Use the leftmost N bytes of the signature input if the input is -+ larger than the prime q (with N being the size in bytes of q). -+ [Nils Larsch] -+ -+ *) Very *very* experimental PKCS#7 streaming encoder support. Nothing uses -+ it yet and it is largely untested. -+ [Steve Henson] -+ -+ *) Add support for the ecdsa-with-SHA224/256/384/512 signature types. -+ [Nils Larsch] -+ -+ *) Initial incomplete changes to avoid need for function casts in OpenSSL -+ some compilers (gcc 4.2 and later) reject their use. Safestack is -+ reimplemented. Update ASN1 to avoid use of legacy functions. -+ [Steve Henson] -+ -+ *) Win32/64 targets are linked with Winsock2. -+ [Andy Polyakov] -+ -+ *) Add an X509_CRL_METHOD structure to allow CRL processing to be redirected -+ to external functions. This can be used to increase CRL handling -+ efficiency especially when CRLs are very large by (for example) storing -+ the CRL revoked certificates in a database. -+ [Steve Henson] -+ -+ *) Overhaul of by_dir code. Add support for dynamic loading of CRLs so -+ new CRLs added to a directory can be used. New command line option -+ -verify_return_error to s_client and s_server. This causes real errors -+ to be returned by the verify callback instead of carrying on no matter -+ what. This reflects the way a "real world" verify callback would behave. -+ [Steve Henson] -+ -+ *) GOST engine, supporting several GOST algorithms and public key formats. -+ Kindly donated by Cryptocom. -+ [Cryptocom] -+ -+ *) Partial support for Issuing Distribution Point CRL extension. CRLs -+ partitioned by DP are handled but no indirect CRL or reason partitioning -+ (yet). Complete overhaul of CRL handling: now the most suitable CRL is -+ selected via a scoring technique which handles IDP and AKID in CRLs. -+ [Steve Henson] -+ -+ *) New X509_STORE_CTX callbacks lookup_crls() and lookup_certs() which -+ will ultimately be used for all verify operations: this will remove the -+ X509_STORE dependency on certificate verification and allow alternative -+ lookup methods. X509_STORE based implementations of these two callbacks. -+ [Steve Henson] -+ -+ *) Allow multiple CRLs to exist in an X509_STORE with matching issuer names. -+ Modify get_crl() to find a valid (unexpired) CRL if possible. -+ [Steve Henson] -+ -+ *) New function X509_CRL_match() to check if two CRLs are identical. Normally -+ this would be called X509_CRL_cmp() but that name is already used by -+ a function that just compares CRL issuer names. Cache several CRL -+ extensions in X509_CRL structure and cache CRLDP in X509. -+ [Steve Henson] -+ -+ *) Store a "canonical" representation of X509_NAME structure (ASN1 Name) -+ this maps equivalent X509_NAME structures into a consistent structure. -+ Name comparison can then be performed rapidly using memcmp(). -+ [Steve Henson] -+ -+ *) Non-blocking OCSP request processing. Add -timeout option to ocsp -+ utility. -+ [Steve Henson] -+ -+ *) Allow digests to supply their own micalg string for S/MIME type using -+ the ctrl EVP_MD_CTRL_MICALG. -+ [Steve Henson] -+ -+ *) During PKCS7 signing pass the PKCS7 SignerInfo structure to the -+ EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN -+ ctrl. It can then customise the structure before and/or after signing -+ if necessary. -+ [Steve Henson] -+ -+ *) New function OBJ_add_sigid() to allow application defined signature OIDs -+ to be added to OpenSSLs internal tables. New function OBJ_sigid_free() -+ to free up any added signature OIDs. -+ [Steve Henson] -+ -+ *) New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(), -+ EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal -+ digest and cipher tables. New options added to openssl utility: -+ list-message-digest-algorithms and list-cipher-algorithms. -+ [Steve Henson] -+ -+ *) Change the array representation of binary polynomials: the list -+ of degrees of non-zero coefficients is now terminated with -1. -+ Previously it was terminated with 0, which was also part of the -+ value; thus, the array representation was not applicable to -+ polynomials where t^0 has coefficient zero. This change makes -+ the array representation useful in a more general context. -+ [Douglas Stebila] -+ -+ *) Various modifications and fixes to SSL/TLS cipher string -+ handling. For ECC, the code now distinguishes between fixed ECDH -+ with RSA certificates on the one hand and with ECDSA certificates -+ on the other hand, since these are separate ciphersuites. The -+ unused code for Fortezza ciphersuites has been removed. -+ -+ For consistency with EDH, ephemeral ECDH is now called "EECDH" -+ (not "ECDHE"). For consistency with the code for DH -+ certificates, use of ECDH certificates is now considered ECDH -+ authentication, not RSA or ECDSA authentication (the latter is -+ merely the CA's signing algorithm and not actively used in the -+ protocol). -+ -+ The temporary ciphersuite alias "ECCdraft" is no longer -+ available, and ECC ciphersuites are no longer excluded from "ALL" -+ and "DEFAULT". The following aliases now exist for RFC 4492 -+ ciphersuites, most of these by analogy with the DH case: -+ -+ kECDHr - ECDH cert, signed with RSA -+ kECDHe - ECDH cert, signed with ECDSA -+ kECDH - ECDH cert (signed with either RSA or ECDSA) -+ kEECDH - ephemeral ECDH -+ ECDH - ECDH cert or ephemeral ECDH -+ -+ aECDH - ECDH cert -+ aECDSA - ECDSA cert -+ ECDSA - ECDSA cert -+ -+ AECDH - anonymous ECDH -+ EECDH - non-anonymous ephemeral ECDH (equivalent to "kEECDH:-AECDH") -+ -+ [Bodo Moeller] -+ -+ *) Add additional S/MIME capabilities for AES and GOST ciphers if supported. -+ Use correct micalg parameters depending on digest(s) in signed message. -+ [Steve Henson] -+ -+ *) Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process -+ an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code. -+ [Steve Henson] -+ -+ *) Initial engine support for EVP_PKEY_METHOD. New functions to permit -+ an engine to register a method. Add ENGINE lookups for methods and -+ functional reference processing. -+ [Steve Henson] -+ -+ *) New functions EVP_Digest{Sign,Verify)*. These are enchance versions of -+ EVP_{Sign,Verify}* which allow an application to customise the signature -+ process. -+ [Steve Henson] -+ -+ *) New -resign option to smime utility. This adds one or more signers -+ to an existing PKCS#7 signedData structure. Also -md option to use an -+ alternative message digest algorithm for signing. -+ [Steve Henson] -+ -+ *) Tidy up PKCS#7 routines and add new functions to make it easier to -+ create PKCS7 structures containing multiple signers. Update smime -+ application to support multiple signers. -+ [Steve Henson] -+ -+ *) New -macalg option to pkcs12 utility to allow setting of an alternative -+ digest MAC. -+ [Steve Henson] -+ -+ *) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC. -+ Reorganize PBE internals to lookup from a static table using NIDs, -+ add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl: -+ EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative -+ PRF which will be automatically used with PBES2. -+ [Steve Henson] -+ -+ *) Replace the algorithm specific calls to generate keys in "req" with the -+ new API. -+ [Steve Henson] -+ -+ *) Update PKCS#7 enveloped data routines to use new API. This is now -+ supported by any public key method supporting the encrypt operation. A -+ ctrl is added to allow the public key algorithm to examine or modify -+ the PKCS#7 RecipientInfo structure if it needs to: for RSA this is -+ a no op. -+ [Steve Henson] -+ -+ *) Add a ctrl to asn1 method to allow a public key algorithm to express -+ a default digest type to use. In most cases this will be SHA1 but some -+ algorithms (such as GOST) need to specify an alternative digest. The -+ return value indicates how strong the preference is 1 means optional and -+ 2 is mandatory (that is it is the only supported type). Modify -+ ASN1_item_sign() to accept a NULL digest argument to indicate it should -+ use the default md. Update openssl utilities to use the default digest -+ type for signing if it is not explicitly indicated. -+ [Steve Henson] -+ -+ *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New -+ EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant -+ signing method from the key type. This effectively removes the link -+ between digests and public key types. -+ [Steve Henson] -+ -+ *) Add an OID cross reference table and utility functions. Its purpose is to -+ translate between signature OIDs such as SHA1WithrsaEncryption and SHA1, -+ rsaEncryption. This will allow some of the algorithm specific hackery -+ needed to use the correct OID to be removed. -+ [Steve Henson] -+ -+ *) Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO -+ structures for PKCS7_sign(). They are now set up by the relevant public -+ key ASN1 method. -+ [Steve Henson] -+ -+ *) Add provisional EC pkey method with support for ECDSA and ECDH. -+ [Steve Henson] -+ -+ *) Add support for key derivation (agreement) in the API, DH method and -+ pkeyutl. -+ [Steve Henson] -+ -+ *) Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support -+ public and private key formats. As a side effect these add additional -+ command line functionality not previously available: DSA signatures can be -+ generated and verified using pkeyutl and DH key support and generation in -+ pkey, genpkey. -+ [Steve Henson] -+ -+ *) BeOS support. -+ [Oliver Tappe ] -+ -+ *) New make target "install_html_docs" installs HTML renditions of the -+ manual pages. -+ [Oliver Tappe ] -+ -+ *) New utility "genpkey" this is analogous to "genrsa" etc except it can -+ generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to -+ support key and parameter generation and add initial key generation -+ functionality for RSA. -+ [Steve Henson] -+ -+ *) Add functions for main EVP_PKEY_method operations. The undocumented -+ functions EVP_PKEY_{encrypt,decrypt} have been renamed to -+ EVP_PKEY_{encrypt,decrypt}_old. -+ [Steve Henson] -+ -+ *) Initial definitions for EVP_PKEY_METHOD. This will be a high level public -+ key API, doesn't do much yet. -+ [Steve Henson] -+ -+ *) New function EVP_PKEY_asn1_get0_info() to retrieve information about -+ public key algorithms. New option to openssl utility: -+ "list-public-key-algorithms" to print out info. -+ [Steve Henson] -+ -+ *) Implement the Supported Elliptic Curves Extension for -+ ECC ciphersuites from draft-ietf-tls-ecc-12.txt. -+ [Douglas Stebila] -+ -+ *) Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or -+ EVP_CIPHER structures to avoid later problems in EVP_cleanup(). -+ [Steve Henson] -+ -+ *) New utilities pkey and pkeyparam. These are similar to algorithm specific -+ utilities such as rsa, dsa, dsaparam etc except they process any key -+ type. -+ [Steve Henson] -+ -+ *) Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New -+ functions EVP_PKEY_print_public(), EVP_PKEY_print_private(), -+ EVP_PKEY_print_param() to print public key data from an EVP_PKEY -+ structure. -+ [Steve Henson] -+ -+ *) Initial support for pluggable public key ASN1. -+ De-spaghettify the public key ASN1 handling. Move public and private -+ key ASN1 handling to a new EVP_PKEY_ASN1_METHOD structure. Relocate -+ algorithm specific handling to a single module within the relevant -+ algorithm directory. Add functions to allow (near) opaque processing -+ of public and private key structures. -+ [Steve Henson] -+ -+ *) Implement the Supported Point Formats Extension for -+ ECC ciphersuites from draft-ietf-tls-ecc-12.txt. -+ [Douglas Stebila] -+ -+ *) Add initial support for RFC 4279 PSK TLS ciphersuites. Add members -+ for the psk identity [hint] and the psk callback functions to the -+ SSL_SESSION, SSL and SSL_CTX structure. -+ -+ New ciphersuites: -+ PSK-RC4-SHA, PSK-3DES-EDE-CBC-SHA, PSK-AES128-CBC-SHA, -+ PSK-AES256-CBC-SHA -+ -+ New functions: -+ SSL_CTX_use_psk_identity_hint -+ SSL_get_psk_identity_hint -+ SSL_get_psk_identity -+ SSL_use_psk_identity_hint -+ -+ [Mika Kousa and Pasi Eronen of Nokia Corporation] -+ -+ *) Add RFC 3161 compliant time stamp request creation, response generation -+ and response verification functionality. -+ [Zoltán Glózik , The OpenTSA Project] -+ -+ *) Add initial support for TLS extensions, specifically for the server_name -+ extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now -+ have new members for a host name. The SSL data structure has an -+ additional member SSL_CTX *initial_ctx so that new sessions can be -+ stored in that context to allow for session resumption, even after the -+ SSL has been switched to a new SSL_CTX in reaction to a client's -+ server_name extension. -+ -+ New functions (subject to change): -+ -+ SSL_get_servername() -+ SSL_get_servername_type() -+ SSL_set_SSL_CTX() -+ -+ New CTRL codes and macros (subject to change): -+ -+ SSL_CTRL_SET_TLSEXT_SERVERNAME_CB -+ - SSL_CTX_set_tlsext_servername_callback() -+ SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG -+ - SSL_CTX_set_tlsext_servername_arg() -+ SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name() -+ -+ openssl s_client has a new '-servername ...' option. -+ -+ openssl s_server has new options '-servername_host ...', '-cert2 ...', -+ '-key2 ...', '-servername_fatal' (subject to change). This allows -+ testing the HostName extension for a specific single host name ('-cert' -+ and '-key' remain fallbacks for handshakes without HostName -+ negotiation). If the unrecognized_name alert has to be sent, this by -+ default is a warning; it becomes fatal with the '-servername_fatal' -+ option. -+ -+ [Peter Sylvester, Remy Allais, Christophe Renou] -+ -+ *) Whirlpool hash implementation is added. -+ [Andy Polyakov] -+ -+ *) BIGNUM code on 64-bit SPARCv9 targets is switched from bn(64,64) to -+ bn(64,32). Because of instruction set limitations it doesn't have -+ any negative impact on performance. This was done mostly in order -+ to make it possible to share assembler modules, such as bn_mul_mont -+ implementations, between 32- and 64-bit builds without hassle. -+ [Andy Polyakov] -+ -+ *) Move code previously exiled into file crypto/ec/ec2_smpt.c -+ to ec2_smpl.c, and no longer require the OPENSSL_EC_BIN_PT_COMP -+ macro. -+ [Bodo Moeller] -+ -+ *) New candidate for BIGNUM assembler implementation, bn_mul_mont, -+ dedicated Montgomery multiplication procedure, is introduced. -+ BN_MONT_CTX is modified to allow bn_mul_mont to reach for higher -+ "64-bit" performance on certain 32-bit targets. -+ [Andy Polyakov] -+ -+ *) New option SSL_OP_NO_COMP to disable use of compression selectively -+ in SSL structures. New SSL ctrl to set maximum send fragment size. -+ Save memory by seeting the I/O buffer sizes dynamically instead of -+ using the maximum available value. -+ [Steve Henson] -+ -+ *) New option -V for 'openssl ciphers'. This prints the ciphersuite code -+ in addition to the text details. -+ [Bodo Moeller] -+ -+ *) Very, very preliminary EXPERIMENTAL support for printing of general -+ ASN1 structures. This currently produces rather ugly output and doesn't -+ handle several customised structures at all. -+ [Steve Henson] -+ -+ *) Integrated support for PVK file format and some related formats such -+ as MS PUBLICKEYBLOB and PRIVATEKEYBLOB. Command line switches to support -+ these in the 'rsa' and 'dsa' utilities. -+ [Steve Henson] -+ -+ *) Support for PKCS#1 RSAPublicKey format on rsa utility command line. -+ [Steve Henson] -+ -+ *) Remove the ancient ASN1_METHOD code. This was only ever used in one -+ place for the (very old) "NETSCAPE" format certificates which are now -+ handled using new ASN1 code equivalents. -+ [Steve Henson] -+ -+ *) Let the TLSv1_method() etc. functions return a 'const' SSL_METHOD -+ pointer and make the SSL_METHOD parameter in SSL_CTX_new, -+ SSL_CTX_set_ssl_version and SSL_set_ssl_method 'const'. -+ [Nils Larsch] -+ -+ *) Modify CRL distribution points extension code to print out previously -+ unsupported fields. Enhance extension setting code to allow setting of -+ all fields. -+ [Steve Henson] -+ -+ *) Add print and set support for Issuing Distribution Point CRL extension. -+ [Steve Henson] -+ -+ *) Change 'Configure' script to enable Camellia by default. -+ [NTT] -+ -+ Changes between 0.9.8m and 0.9.8n [24 Mar 2010] -+ -+ *) When rejecting SSL/TLS records due to an incorrect version number, never -+ update s->server with a new major version number. As of -+ - OpenSSL 0.9.8m if 'short' is a 16-bit type, -+ - OpenSSL 0.9.8f if 'short' is longer than 16 bits, -+ the previous behavior could result in a read attempt at NULL when -+ receiving specific incorrect SSL/TLS records once record payload -+ protection is active. (CVE-2010-0740) -+ [Bodo Moeller, Adam Langley ] -+ -+ *) Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL -+ could be crashed if the relevant tables were not present (e.g. chrooted). -+ [Tomas Hoger ] -+ -+ Changes between 0.9.8l and 0.9.8m [25 Feb 2010] -+ -+ *) Always check bn_wexpend() return values for failure. (CVE-2009-3245) -+ [Martin Olsson, Neel Mehta] -+ -+ *) Fix X509_STORE locking: Every 'objs' access requires a lock (to -+ accommodate for stack sorting, always a write lock!). -+ [Bodo Moeller] -+ -+ *) On some versions of WIN32 Heap32Next is very slow. This can cause -+ excessive delays in the RAND_poll(): over a minute. As a workaround -+ include a time check in the inner Heap32Next loop too. -+ [Steve Henson] -+ -+ *) The code that handled flushing of data in SSL/TLS originally used the -+ BIO_CTRL_INFO ctrl to see if any data was pending first. This caused -+ the problem outlined in PR#1949. The fix suggested there however can -+ trigger problems with buggy BIO_CTRL_WPENDING (e.g. some versions -+ of Apache). So instead simplify the code to flush unconditionally. -+ This should be fine since flushing with no data to flush is a no op. -+ [Steve Henson] -+ -+ *) Handle TLS versions 2.0 and later properly and correctly use the -+ highest version of TLS/SSL supported. Although TLS >= 2.0 is some way -+ off ancient servers have a habit of sticking around for a while... -+ [Steve Henson] -+ -+ *) Modify compression code so it frees up structures without using the -+ ex_data callbacks. This works around a problem where some applications -+ call CRYPTO_cleanup_all_ex_data() before application exit (e.g. when -+ restarting) then use compression (e.g. SSL with compression) later. -+ This results in significant per-connection memory leaks and -+ has caused some security issues including CVE-2008-1678 and -+ CVE-2009-4355. -+ [Steve Henson] -+ -+ *) Constify crypto/cast (i.e., ): a CAST_KEY doesn't -+ change when encrypting or decrypting. -+ [Bodo Moeller] -+ -+ *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to -+ connect and renegotiate with servers which do not support RI. -+ Until RI is more widely deployed this option is enabled by default. -+ [Steve Henson] -+ -+ *) Add "missing" ssl ctrls to clear options and mode. -+ [Steve Henson] -+ -+ *) If client attempts to renegotiate and doesn't support RI respond with -+ a no_renegotiation alert as required by RFC5746. Some renegotiating -+ TLS clients will continue a connection gracefully when they receive -+ the alert. Unfortunately OpenSSL mishandled this alert and would hang -+ waiting for a server hello which it will never receive. Now we treat a -+ received no_renegotiation alert as a fatal error. This is because -+ applications requesting a renegotiation might well expect it to succeed -+ and would have no code in place to handle the server denying it so the -+ only safe thing to do is to terminate the connection. -+ [Steve Henson] -+ -+ *) Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if -+ peer supports secure renegotiation and 0 otherwise. Print out peer -+ renegotiation support in s_client/s_server. -+ [Steve Henson] -+ -+ *) Replace the highly broken and deprecated SPKAC certification method with -+ the updated NID creation version. This should correctly handle UTF8. -+ [Steve Henson] -+ -+ *) Implement RFC5746. Re-enable renegotiation but require the extension -+ as needed. Unfortunately, SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION -+ turns out to be a bad idea. It has been replaced by -+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with -+ SSL_CTX_set_options(). This is really not recommended unless you -+ know what you are doing. -+ [Eric Rescorla , Ben Laurie, Steve Henson] -+ -+ *) Fixes to stateless session resumption handling. Use initial_ctx when -+ issuing and attempting to decrypt tickets in case it has changed during -+ servername handling. Use a non-zero length session ID when attempting -+ stateless session resumption: this makes it possible to determine if -+ a resumption has occurred immediately after receiving server hello -+ (several places in OpenSSL subtly assume this) instead of later in -+ the handshake. -+ [Steve Henson] -+ -+ *) The functions ENGINE_ctrl(), OPENSSL_isservice(), -+ CMS_get1_RecipientRequest() and RAND_bytes() can return <=0 on error -+ fixes for a few places where the return code is not checked -+ correctly. -+ [Julia Lawall ] -+ -+ *) Add --strict-warnings option to Configure script to include devteam -+ warnings in other configurations. -+ [Steve Henson] -+ -+ *) Add support for --libdir option and LIBDIR variable in makefiles. This -+ makes it possible to install openssl libraries in locations which -+ have names other than "lib", for example "/usr/lib64" which some -+ systems need. -+ [Steve Henson, based on patch from Jeremy Utley] -+ -+ *) Don't allow the use of leading 0x80 in OIDs. This is a violation of -+ X690 8.9.12 and can produce some misleading textual output of OIDs. -+ [Steve Henson, reported by Dan Kaminsky] -+ -+ *) Delete MD2 from algorithm tables. This follows the recommendation in -+ several standards that it is not used in new applications due to -+ several cryptographic weaknesses. For binary compatibility reasons -+ the MD2 API is still compiled in by default. -+ [Steve Henson] -+ -+ *) Add compression id to {d2i,i2d}_SSL_SESSION so it is correctly saved -+ and restored. -+ [Steve Henson] -+ -+ *) Rename uni2asc and asc2uni functions to OPENSSL_uni2asc and -+ OPENSSL_asc2uni conditionally on Netware platforms to avoid a name -+ clash. -+ [Guenter ] -+ -+ *) Fix the server certificate chain building code to use X509_verify_cert(), -+ it used to have an ad-hoc builder which was unable to cope with anything -+ other than a simple chain. -+ [David Woodhouse , Steve Henson] -+ -+ *) Don't check self signed certificate signatures in X509_verify_cert() -+ by default (a flag can override this): it just wastes time without -+ adding any security. As a useful side effect self signed root CAs -+ with non-FIPS digests are now usable in FIPS mode. -+ [Steve Henson] -+ -+ *) In dtls1_process_out_of_seq_message() the check if the current message -+ is already buffered was missing. For every new message was memory -+ allocated, allowing an attacker to perform an denial of service attack -+ with sending out of seq handshake messages until there is no memory -+ left. Additionally every future messege was buffered, even if the -+ sequence number made no sense and would be part of another handshake. -+ So only messages with sequence numbers less than 10 in advance will be -+ buffered. (CVE-2009-1378) -+ [Robin Seggelmann, discovered by Daniel Mentz] -+ -+ *) Records are buffered if they arrive with a future epoch to be -+ processed after finishing the corresponding handshake. There is -+ currently no limitation to this buffer allowing an attacker to perform -+ a DOS attack with sending records with future epochs until there is no -+ memory left. This patch adds the pqueue_size() function to determine -+ the size of a buffer and limits the record buffer to 100 entries. -+ (CVE-2009-1377) -+ [Robin Seggelmann, discovered by Daniel Mentz] -+ -+ *) Keep a copy of frag->msg_header.frag_len so it can be used after the -+ parent structure is freed. (CVE-2009-1379) -+ [Daniel Mentz] -+ -+ *) Handle non-blocking I/O properly in SSL_shutdown() call. -+ [Darryl Miles ] -+ -+ *) Add 2.5.4.* OIDs -+ [Ilya O. ] -+ -+ Changes between 0.9.8k and 0.9.8l [5 Nov 2009] -+ -+ *) Disable renegotiation completely - this fixes a severe security -+ problem (CVE-2009-3555) at the cost of breaking all -+ renegotiation. Renegotiation can be re-enabled by setting -+ SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION in s3->flags at -+ run-time. This is really not recommended unless you know what -+ you're doing. -+ [Ben Laurie] -+ -+ Changes between 0.9.8j and 0.9.8k [25 Mar 2009] -+ -+ *) Don't set val to NULL when freeing up structures, it is freed up by -+ underlying code. If sizeof(void *) > sizeof(long) this can result in -+ zeroing past the valid field. (CVE-2009-0789) -+ [Paolo Ganci ] -+ -+ *) Fix bug where return value of CMS_SignerInfo_verify_content() was not -+ checked correctly. This would allow some invalid signed attributes to -+ appear to verify correctly. (CVE-2009-0591) -+ [Ivan Nestlerode ] -+ -+ *) Reject UniversalString and BMPString types with invalid lengths. This -+ prevents a crash in ASN1_STRING_print_ex() which assumes the strings have -+ a legal length. (CVE-2009-0590) -+ [Steve Henson] -+ -+ *) Set S/MIME signing as the default purpose rather than setting it -+ unconditionally. This allows applications to override it at the store -+ level. -+ [Steve Henson] -+ -+ *) Permit restricted recursion of ASN1 strings. This is needed in practice -+ to handle some structures. -+ [Steve Henson] -+ -+ *) Improve efficiency of mem_gets: don't search whole buffer each time -+ for a '\n' -+ [Jeremy Shapiro ] -+ -+ *) New -hex option for openssl rand. -+ [Matthieu Herrb] -+ -+ *) Print out UTF8String and NumericString when parsing ASN1. -+ [Steve Henson] -+ -+ *) Support NumericString type for name components. -+ [Steve Henson] -+ -+ *) Allow CC in the environment to override the automatically chosen -+ compiler. Note that nothing is done to ensure flags work with the -+ chosen compiler. -+ [Ben Laurie] -+ -+ Changes between 0.9.8i and 0.9.8j [07 Jan 2009] -+ -+ *) Properly check EVP_VerifyFinal() and similar return values -+ (CVE-2008-5077). -+ [Ben Laurie, Bodo Moeller, Google Security Team] -+ -+ *) Enable TLS extensions by default. -+ [Ben Laurie] -+ -+ *) Allow the CHIL engine to be loaded, whether the application is -+ multithreaded or not. (This does not release the developer from the -+ obligation to set up the dynamic locking callbacks.) -+ [Sander Temme ] -+ -+ *) Use correct exit code if there is an error in dgst command. -+ [Steve Henson; problem pointed out by Roland Dirlewanger] -+ -+ *) Tweak Configure so that you need to say "experimental-jpake" to enable -+ JPAKE, and need to use -DOPENSSL_EXPERIMENTAL_JPAKE in applications. -+ [Bodo Moeller] -+ -+ *) Add experimental JPAKE support, including demo authentication in -+ s_client and s_server. -+ [Ben Laurie] -+ -+ *) Set the comparison function in v3_addr_canonize(). -+ [Rob Austein ] -+ -+ *) Add support for XMPP STARTTLS in s_client. -+ [Philip Paeps ] -+ -+ *) Change the server-side SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG behavior -+ to ensure that even with this option, only ciphersuites in the -+ server's preference list will be accepted. (Note that the option -+ applies only when resuming a session, so the earlier behavior was -+ just about the algorithm choice for symmetric cryptography.) -+ [Bodo Moeller] -+ -+ Changes between 0.9.8h and 0.9.8i [15 Sep 2008] -+ -+ *) Fix NULL pointer dereference if a DTLS server received -+ ChangeCipherSpec as first record (CVE-2009-1386). -+ [PR #1679] -+ -+ *) Fix a state transition in s3_srvr.c and d1_srvr.c -+ (was using SSL3_ST_CW_CLNT_HELLO_B, should be ..._ST_SW_SRVR_...). -+ [Nagendra Modadugu] -+ -+ *) The fix in 0.9.8c that supposedly got rid of unsafe -+ double-checked locking was incomplete for RSA blinding, -+ addressing just one layer of what turns out to have been -+ doubly unsafe triple-checked locking. -+ -+ So now fix this for real by retiring the MONT_HELPER macro -+ in crypto/rsa/rsa_eay.c. -+ -+ [Bodo Moeller; problem pointed out by Marius Schilder] -+ -+ *) Various precautionary measures: -+ -+ - Avoid size_t integer overflow in HASH_UPDATE (md32_common.h). -+ -+ - Avoid a buffer overflow in d2i_SSL_SESSION() (ssl_asn1.c). -+ (NB: This would require knowledge of the secret session ticket key -+ to exploit, in which case you'd be SOL either way.) -+ -+ - Change bn_nist.c so that it will properly handle input BIGNUMs -+ outside the expected range. -+ -+ - Enforce the 'num' check in BN_div() (bn_div.c) for non-BN_DEBUG -+ builds. -+ -+ [Neel Mehta, Bodo Moeller] -+ -+ *) Allow engines to be "soft loaded" - i.e. optionally don't die if -+ the load fails. Useful for distros. -+ [Ben Laurie and the FreeBSD team] -+ -+ *) Add support for Local Machine Keyset attribute in PKCS#12 files. -+ [Steve Henson] -+ -+ *) Fix BN_GF2m_mod_arr() top-bit cleanup code. -+ [Huang Ying] -+ -+ *) Expand ENGINE to support engine supplied SSL client certificate functions. -+ -+ This work was sponsored by Logica. -+ [Steve Henson] -+ -+ *) Add CryptoAPI ENGINE to support use of RSA and DSA keys held in Windows -+ keystores. Support for SSL/TLS client authentication too. -+ Not compiled unless enable-capieng specified to Configure. -+ -+ This work was sponsored by Logica. -+ [Steve Henson] -+ -+ *) Fix bug in X509_ATTRIBUTE creation: don't set attribute using -+ ASN1_TYPE_set1 if MBSTRING flag set. This bug would crash certain -+ attribute creation routines such as certificate requests and PKCS#12 -+ files. -+ [Steve Henson] -+ -+ Changes between 0.9.8g and 0.9.8h [28 May 2008] -+ -+ *) Fix flaw if 'Server Key exchange message' is omitted from a TLS -+ handshake which could lead to a cilent crash as found using the -+ Codenomicon TLS test suite (CVE-2008-1672) -+ [Steve Henson, Mark Cox] -+ -+ *) Fix double free in TLS server name extensions which could lead to -+ a remote crash found by Codenomicon TLS test suite (CVE-2008-0891) -+ [Joe Orton] -+ -+ *) Clear error queue in SSL_CTX_use_certificate_chain_file() -+ -+ Clear the error queue to ensure that error entries left from -+ older function calls do not interfere with the correct operation. -+ [Lutz Jaenicke, Erik de Castro Lopo] -+ -+ *) Remove root CA certificates of commercial CAs: -+ -+ The OpenSSL project does not recommend any specific CA and does not -+ have any policy with respect to including or excluding any CA. -+ Therefore it does not make any sense to ship an arbitrary selection -+ of root CA certificates with the OpenSSL software. -+ [Lutz Jaenicke] -+ -+ *) RSA OAEP patches to fix two separate invalid memory reads. -+ The first one involves inputs when 'lzero' is greater than -+ 'SHA_DIGEST_LENGTH' (it would read about SHA_DIGEST_LENGTH bytes -+ before the beginning of from). The second one involves inputs where -+ the 'db' section contains nothing but zeroes (there is a one-byte -+ invalid read after the end of 'db'). -+ [Ivan Nestlerode ] -+ -+ *) Partial backport from 0.9.9-dev: -+ -+ Introduce bn_mul_mont (dedicated Montgomery multiplication -+ procedure) as a candidate for BIGNUM assembler implementation. -+ While 0.9.9-dev uses assembler for various architectures, only -+ x86_64 is available by default here in the 0.9.8 branch, and -+ 32-bit x86 is available through a compile-time setting. -+ -+ To try the 32-bit x86 assembler implementation, use Configure -+ option "enable-montasm" (which exists only for this backport). -+ -+ As "enable-montasm" for 32-bit x86 disclaims code stability -+ anyway, in this constellation we activate additional code -+ backported from 0.9.9-dev for further performance improvements, -+ namely BN_from_montgomery_word. (To enable this otherwise, -+ e.g. x86_64, try "-DMONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD".) -+ -+ [Andy Polyakov (backport partially by Bodo Moeller)] -+ -+ *) Add TLS session ticket callback. This allows an application to set -+ TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed -+ values. This is useful for key rollover for example where several key -+ sets may exist with different names. -+ [Steve Henson] -+ -+ *) Reverse ENGINE-internal logic for caching default ENGINE handles. -+ This was broken until now in 0.9.8 releases, such that the only way -+ a registered ENGINE could be used (assuming it initialises -+ successfully on the host) was to explicitly set it as the default -+ for the relevant algorithms. This is in contradiction with 0.9.7 -+ behaviour and the documentation. With this fix, when an ENGINE is -+ registered into a given algorithm's table of implementations, the -+ 'uptodate' flag is reset so that auto-discovery will be used next -+ time a new context for that algorithm attempts to select an -+ implementation. -+ [Ian Lister (tweaked by Geoff Thorpe)] -+ -+ *) Backport of CMS code to OpenSSL 0.9.8. This differs from the 0.9.9 -+ implementation in the following ways: -+ -+ Lack of EVP_PKEY_ASN1_METHOD means algorithm parameters have to be -+ hard coded. -+ -+ Lack of BER streaming support means one pass streaming processing is -+ only supported if data is detached: setting the streaming flag is -+ ignored for embedded content. -+ -+ CMS support is disabled by default and must be explicitly enabled -+ with the enable-cms configuration option. -+ [Steve Henson] -+ -+ *) Update the GMP engine glue to do direct copies between BIGNUM and -+ mpz_t when openssl and GMP use the same limb size. Otherwise the -+ existing "conversion via a text string export" trick is still used. -+ [Paul Sheer ] -+ -+ *) Zlib compression BIO. This is a filter BIO which compressed and -+ uncompresses any data passed through it. -+ [Steve Henson] -+ -+ *) Add AES_wrap_key() and AES_unwrap_key() functions to implement -+ RFC3394 compatible AES key wrapping. -+ [Steve Henson] -+ -+ *) Add utility functions to handle ASN1 structures. ASN1_STRING_set0(): -+ sets string data without copying. X509_ALGOR_set0() and -+ X509_ALGOR_get0(): set and retrieve X509_ALGOR (AlgorithmIdentifier) -+ data. Attribute function X509at_get0_data_by_OBJ(): retrieves data -+ from an X509_ATTRIBUTE structure optionally checking it occurs only -+ once. ASN1_TYPE_set1(): set and ASN1_TYPE structure copying supplied -+ data. -+ [Steve Henson] -+ -+ *) Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set() -+ to get the expected BN_FLG_CONSTTIME behavior. -+ [Bodo Moeller (Google)] -+ -+ *) Netware support: -+ -+ - fixed wrong usage of ioctlsocket() when build for LIBC BSD sockets -+ - fixed do_tests.pl to run the test suite with CLIB builds too (CLIB_OPT) -+ - added some more tests to do_tests.pl -+ - fixed RunningProcess usage so that it works with newer LIBC NDKs too -+ - removed usage of BN_LLONG for CLIB builds to avoid runtime dependency -+ - added new Configure targets netware-clib-bsdsock, netware-clib-gcc, -+ netware-clib-bsdsock-gcc, netware-libc-bsdsock-gcc -+ - various changes to netware.pl to enable gcc-cross builds on Win32 -+ platform -+ - changed crypto/bio/b_sock.c to work with macro functions (CLIB BSD) -+ - various changes to fix missing prototype warnings -+ - fixed x86nasm.pl to create correct asm files for NASM COFF output -+ - added AES, WHIRLPOOL and CPUID assembler code to build files -+ - added missing AES assembler make rules to mk1mf.pl -+ - fixed order of includes in apps/ocsp.c so that e_os.h settings apply -+ [Guenter Knauf ] -+ -+ *) Implement certificate status request TLS extension defined in RFC3546. -+ A client can set the appropriate parameters and receive the encoded -+ OCSP response via a callback. A server can query the supplied parameters -+ and set the encoded OCSP response in the callback. Add simplified examples -+ to s_client and s_server. -+ [Steve Henson] -+ -+ Changes between 0.9.8f and 0.9.8g [19 Oct 2007] -+ -+ *) Fix various bugs: -+ + Binary incompatibility of ssl_ctx_st structure -+ + DTLS interoperation with non-compliant servers -+ + Don't call get_session_cb() without proposed session -+ + Fix ia64 assembler code -+ [Andy Polyakov, Steve Henson] -+ -+ Changes between 0.9.8e and 0.9.8f [11 Oct 2007] -+ -+ *) DTLS Handshake overhaul. There were longstanding issues with -+ OpenSSL DTLS implementation, which were making it impossible for -+ RFC 4347 compliant client to communicate with OpenSSL server. -+ Unfortunately just fixing these incompatibilities would "cut off" -+ pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e -+ server keeps tolerating non RFC compliant syntax. The opposite is -+ not true, 0.9.8f client can not communicate with earlier server. -+ This update even addresses CVE-2007-4995. -+ [Andy Polyakov] -+ -+ *) Changes to avoid need for function casts in OpenSSL: some compilers -+ (gcc 4.2 and later) reject their use. -+ [Kurt Roeckx , Peter Hartley , -+ Steve Henson] -+ -+ *) Add RFC4507 support to OpenSSL. This includes the corrections in -+ RFC4507bis. The encrypted ticket format is an encrypted encoded -+ SSL_SESSION structure, that way new session features are automatically -+ supported. -+ -+ If a client application caches session in an SSL_SESSION structure -+ support is transparent because tickets are now stored in the encoded -+ SSL_SESSION. -+ -+ The SSL_CTX structure automatically generates keys for ticket -+ protection in servers so again support should be possible -+ with no application modification. -+ -+ If a client or server wishes to disable RFC4507 support then the option -+ SSL_OP_NO_TICKET can be set. -+ -+ Add a TLS extension debugging callback to allow the contents of any client -+ or server extensions to be examined. -+ -+ This work was sponsored by Google. -+ [Steve Henson] -+ -+ *) Add initial support for TLS extensions, specifically for the server_name -+ extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now -+ have new members for a host name. The SSL data structure has an -+ additional member SSL_CTX *initial_ctx so that new sessions can be -+ stored in that context to allow for session resumption, even after the -+ SSL has been switched to a new SSL_CTX in reaction to a client's -+ server_name extension. -+ -+ New functions (subject to change): -+ -+ SSL_get_servername() -+ SSL_get_servername_type() -+ SSL_set_SSL_CTX() -+ -+ New CTRL codes and macros (subject to change): -+ -+ SSL_CTRL_SET_TLSEXT_SERVERNAME_CB -+ - SSL_CTX_set_tlsext_servername_callback() -+ SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG -+ - SSL_CTX_set_tlsext_servername_arg() -+ SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name() -+ -+ openssl s_client has a new '-servername ...' option. -+ -+ openssl s_server has new options '-servername_host ...', '-cert2 ...', -+ '-key2 ...', '-servername_fatal' (subject to change). This allows -+ testing the HostName extension for a specific single host name ('-cert' -+ and '-key' remain fallbacks for handshakes without HostName -+ negotiation). If the unrecognized_name alert has to be sent, this by -+ default is a warning; it becomes fatal with the '-servername_fatal' -+ option. -+ -+ [Peter Sylvester, Remy Allais, Christophe Renou, Steve Henson] -+ -+ *) Add AES and SSE2 assembly language support to VC++ build. -+ [Steve Henson] -+ -+ *) Mitigate attack on final subtraction in Montgomery reduction. -+ [Andy Polyakov] -+ -+ *) Fix crypto/ec/ec_mult.c to work properly with scalars of value 0 -+ (which previously caused an internal error). -+ [Bodo Moeller] -+ -+ *) Squeeze another 10% out of IGE mode when in != out. -+ [Ben Laurie] -+ -+ *) AES IGE mode speedup. -+ [Dean Gaudet (Google)] -+ -+ *) Add the Korean symmetric 128-bit cipher SEED (see -+ http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp) and -+ add SEED ciphersuites from RFC 4162: -+ -+ TLS_RSA_WITH_SEED_CBC_SHA = "SEED-SHA" -+ TLS_DHE_DSS_WITH_SEED_CBC_SHA = "DHE-DSS-SEED-SHA" -+ TLS_DHE_RSA_WITH_SEED_CBC_SHA = "DHE-RSA-SEED-SHA" -+ TLS_DH_anon_WITH_SEED_CBC_SHA = "ADH-SEED-SHA" -+ -+ To minimize changes between patchlevels in the OpenSSL 0.9.8 -+ series, SEED remains excluded from compilation unless OpenSSL -+ is configured with 'enable-seed'. -+ [KISA, Bodo Moeller] -+ -+ *) Mitigate branch prediction attacks, which can be practical if a -+ single processor is shared, allowing a spy process to extract -+ information. For detailed background information, see -+ http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron, -+ J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL -+ and Necessary Software Countermeasures"). The core of the change -+ are new versions BN_div_no_branch() and -+ BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(), -+ respectively, which are slower, but avoid the security-relevant -+ conditional branches. These are automatically called by BN_div() -+ and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one -+ of the input BIGNUMs. Also, BN_is_bit_set() has been changed to -+ remove a conditional branch. -+ -+ BN_FLG_CONSTTIME is the new name for the previous -+ BN_FLG_EXP_CONSTTIME flag, since it now affects more than just -+ modular exponentiation. (Since OpenSSL 0.9.7h, setting this flag -+ in the exponent causes BN_mod_exp_mont() to use the alternative -+ implementation in BN_mod_exp_mont_consttime().) The old name -+ remains as a deprecated alias. -+ -+ Similarly, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general -+ RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses -+ constant-time implementations for more than just exponentiation. -+ Here too the old name is kept as a deprecated alias. -+ -+ BN_BLINDING_new() will now use BN_dup() for the modulus so that -+ the BN_BLINDING structure gets an independent copy of the -+ modulus. This means that the previous "BIGNUM *m" argument to -+ BN_BLINDING_new() and to BN_BLINDING_create_param() now -+ essentially becomes "const BIGNUM *m", although we can't actually -+ change this in the header file before 0.9.9. It allows -+ RSA_setup_blinding() to use BN_with_flags() on the modulus to -+ enable BN_FLG_CONSTTIME. -+ -+ [Matthew D Wood (Intel Corp)] -+ -+ *) In the SSL/TLS server implementation, be strict about session ID -+ context matching (which matters if an application uses a single -+ external cache for different purposes). Previously, -+ out-of-context reuse was forbidden only if SSL_VERIFY_PEER was -+ set. This did ensure strict client verification, but meant that, -+ with applications using a single external cache for quite -+ different requirements, clients could circumvent ciphersuite -+ restrictions for a given session ID context by starting a session -+ in a different context. -+ [Bodo Moeller] -+ -+ *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that -+ a ciphersuite string such as "DEFAULT:RSA" cannot enable -+ authentication-only ciphersuites. -+ [Bodo Moeller] -+ -+ *) Update the SSL_get_shared_ciphers() fix CVE-2006-3738 which was -+ not complete and could lead to a possible single byte overflow -+ (CVE-2007-5135) [Ben Laurie] -+ -+ Changes between 0.9.8d and 0.9.8e [23 Feb 2007] -+ -+ *) Since AES128 and AES256 (and similarly Camellia128 and -+ Camellia256) share a single mask bit in the logic of -+ ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a -+ kludge to work properly if AES128 is available and AES256 isn't -+ (or if Camellia128 is available and Camellia256 isn't). -+ [Victor Duchovni] -+ -+ *) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c -+ (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters): -+ When a point or a seed is encoded in a BIT STRING, we need to -+ prevent the removal of trailing zero bits to get the proper DER -+ encoding. (By default, crypto/asn1/a_bitstr.c assumes the case -+ of a NamedBitList, for which trailing 0 bits need to be removed.) -+ [Bodo Moeller] -+ -+ *) Have SSL/TLS server implementation tolerate "mismatched" record -+ protocol version while receiving ClientHello even if the -+ ClientHello is fragmented. (The server can't insist on the -+ particular protocol version it has chosen before the ServerHello -+ message has informed the client about his choice.) -+ [Bodo Moeller] -+ -+ *) Add RFC 3779 support. -+ [Rob Austein for ARIN, Ben Laurie] -+ -+ *) Load error codes if they are not already present instead of using a -+ static variable. This allows them to be cleanly unloaded and reloaded. -+ Improve header file function name parsing. -+ [Steve Henson] -+ -+ *) extend SMTP and IMAP protocol emulation in s_client to use EHLO -+ or CAPABILITY handshake as required by RFCs. -+ [Goetz Babin-Ebell] -+ -+ Changes between 0.9.8c and 0.9.8d [28 Sep 2006] -+ -+ *) Introduce limits to prevent malicious keys being able to -+ cause a denial of service. (CVE-2006-2940) -+ [Steve Henson, Bodo Moeller] -+ -+ *) Fix ASN.1 parsing of certain invalid structures that can result -+ in a denial of service. (CVE-2006-2937) [Steve Henson] -+ -+ *) Fix buffer overflow in SSL_get_shared_ciphers() function. -+ (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team] -+ -+ *) Fix SSL client code which could crash if connecting to a -+ malicious SSLv2 server. (CVE-2006-4343) -+ [Tavis Ormandy and Will Drewry, Google Security Team] -+ -+ *) Since 0.9.8b, ciphersuite strings naming explicit ciphersuites -+ match only those. Before that, "AES256-SHA" would be interpreted -+ as a pattern and match "AES128-SHA" too (since AES128-SHA got -+ the same strength classification in 0.9.7h) as we currently only -+ have a single AES bit in the ciphersuite description bitmap. -+ That change, however, also applied to ciphersuite strings such as -+ "RC4-MD5" that intentionally matched multiple ciphersuites -- -+ namely, SSL 2.0 ciphersuites in addition to the more common ones -+ from SSL 3.0/TLS 1.0. -+ -+ So we change the selection algorithm again: Naming an explicit -+ ciphersuite selects this one ciphersuite, and any other similar -+ ciphersuite (same bitmap) from *other* protocol versions. -+ Thus, "RC4-MD5" again will properly select both the SSL 2.0 -+ ciphersuite and the SSL 3.0/TLS 1.0 ciphersuite. -+ -+ Since SSL 2.0 does not have any ciphersuites for which the -+ 128/256 bit distinction would be relevant, this works for now. -+ The proper fix will be to use different bits for AES128 and -+ AES256, which would have avoided the problems from the beginning; -+ however, bits are scarce, so we can only do this in a new release -+ (not just a patchlevel) when we can change the SSL_CIPHER -+ definition to split the single 'unsigned long mask' bitmap into -+ multiple values to extend the available space. -+ -+ [Bodo Moeller] -+ -+ Changes between 0.9.8b and 0.9.8c [05 Sep 2006] -+ -+ *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher -+ (CVE-2006-4339) [Ben Laurie and Google Security Team] -+ -+ *) Add AES IGE and biIGE modes. -+ [Ben Laurie] -+ -+ *) Change the Unix randomness entropy gathering to use poll() when -+ possible instead of select(), since the latter has some -+ undesirable limitations. -+ [Darryl Miles via Richard Levitte and Bodo Moeller] -+ -+ *) Disable "ECCdraft" ciphersuites more thoroughly. Now special -+ treatment in ssl/ssl_ciph.s makes sure that these ciphersuites -+ cannot be implicitly activated as part of, e.g., the "AES" alias. -+ However, please upgrade to OpenSSL 0.9.9[-dev] for -+ non-experimental use of the ECC ciphersuites to get TLS extension -+ support, which is required for curve and point format negotiation -+ to avoid potential handshake problems. -+ [Bodo Moeller] -+ -+ *) Disable rogue ciphersuites: -+ -+ - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5") -+ - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5") -+ - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5") -+ -+ The latter two were purportedly from -+ draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really -+ appear there. -+ -+ Also deactivate the remaining ciphersuites from -+ draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as -+ unofficial, and the ID has long expired. -+ [Bodo Moeller] -+ -+ *) Fix RSA blinding Heisenbug (problems sometimes occurred on -+ dual-core machines) and other potential thread-safety issues. -+ [Bodo Moeller] -+ -+ *) Add the symmetric cipher Camellia (128-bit, 192-bit, 256-bit key -+ versions), which is now available for royalty-free use -+ (see http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html). -+ Also, add Camellia TLS ciphersuites from RFC 4132. -+ -+ To minimize changes between patchlevels in the OpenSSL 0.9.8 -+ series, Camellia remains excluded from compilation unless OpenSSL -+ is configured with 'enable-camellia'. -+ [NTT] -+ -+ *) Disable the padding bug check when compression is in use. The padding -+ bug check assumes the first packet is of even length, this is not -+ necessarily true if compresssion is enabled and can result in false -+ positives causing handshake failure. The actual bug test is ancient -+ code so it is hoped that implementations will either have fixed it by -+ now or any which still have the bug do not support compression. -+ [Steve Henson] -+ -+ Changes between 0.9.8a and 0.9.8b [04 May 2006] -+ -+ *) When applying a cipher rule check to see if string match is an explicit -+ cipher suite and only match that one cipher suite if it is. -+ [Steve Henson] -+ -+ *) Link in manifests for VC++ if needed. -+ [Austin Ziegler ] -+ -+ *) Update support for ECC-based TLS ciphersuites according to -+ draft-ietf-tls-ecc-12.txt with proposed changes (but without -+ TLS extensions, which are supported starting with the 0.9.9 -+ branch, not in the OpenSSL 0.9.8 branch). -+ [Douglas Stebila] -+ -+ *) New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free() to support -+ opaque EVP_CIPHER_CTX handling. -+ [Steve Henson] -+ -+ *) Fixes and enhancements to zlib compression code. We now only use -+ "zlib1.dll" and use the default __cdecl calling convention on Win32 -+ to conform with the standards mentioned here: -+ http://www.zlib.net/DLL_FAQ.txt -+ Static zlib linking now works on Windows and the new --with-zlib-include -+ --with-zlib-lib options to Configure can be used to supply the location -+ of the headers and library. Gracefully handle case where zlib library -+ can't be loaded. -+ [Steve Henson] -+ -+ *) Several fixes and enhancements to the OID generation code. The old code -+ sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't -+ handle numbers larger than ULONG_MAX, truncated printing and had a -+ non standard OBJ_obj2txt() behaviour. -+ [Steve Henson] -+ -+ *) Add support for building of engines under engine/ as shared libraries -+ under VC++ build system. -+ [Steve Henson] -+ -+ *) Corrected the numerous bugs in the Win32 path splitter in DSO. -+ Hopefully, we will not see any false combination of paths any more. -+ [Richard Levitte] -+ -+ Changes between 0.9.8 and 0.9.8a [11 Oct 2005] -+ -+ *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING -+ (part of SSL_OP_ALL). This option used to disable the -+ countermeasure against man-in-the-middle protocol-version -+ rollback in the SSL 2.0 server implementation, which is a bad -+ idea. (CVE-2005-2969) -+ -+ [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center -+ for Information Security, National Institute of Advanced Industrial -+ Science and Technology [AIST], Japan)] -+ -+ *) Add two function to clear and return the verify parameter flags. -+ [Steve Henson] -+ -+ *) Keep cipherlists sorted in the source instead of sorting them at -+ runtime, thus removing the need for a lock. -+ [Nils Larsch] -+ -+ *) Avoid some small subgroup attacks in Diffie-Hellman. -+ [Nick Mathewson and Ben Laurie] -+ -+ *) Add functions for well-known primes. -+ [Nick Mathewson] -+ -+ *) Extended Windows CE support. -+ [Satoshi Nakamura and Andy Polyakov] -+ -+ *) Initialize SSL_METHOD structures at compile time instead of during -+ runtime, thus removing the need for a lock. -+ [Steve Henson] -+ -+ *) Make PKCS7_decrypt() work even if no certificate is supplied by -+ attempting to decrypt each encrypted key in turn. Add support to -+ smime utility. -+ [Steve Henson] -+ -+ Changes between 0.9.7h and 0.9.8 [05 Jul 2005] -+ -+ [NB: OpenSSL 0.9.7i and later 0.9.7 patch levels were released after -+ OpenSSL 0.9.8.] -+ -+ *) Add libcrypto.pc and libssl.pc for those who feel they need them. -+ [Richard Levitte] -+ -+ *) Change CA.sh and CA.pl so they don't bundle the CSR and the private -+ key into the same file any more. -+ [Richard Levitte] -+ -+ *) Add initial support for Win64, both IA64 and AMD64/x64 flavors. -+ [Andy Polyakov] -+ -+ *) Add -utf8 command line and config file option to 'ca'. -+ [Stefan and Geoff Thorpe] -+ -+ *) Add attribute functions to EVP_PKEY structure. Modify -+ PKCS12_create() to recognize a CSP name attribute and -+ use it. Make -CSP option work again in pkcs12 utility. -+ [Steve Henson] -+ -+ *) Add new functionality to the bn blinding code: -+ - automatic re-creation of the BN_BLINDING parameters after -+ a fixed number of uses (currently 32) -+ - add new function for parameter creation -+ - introduce flags to control the update behaviour of the -+ BN_BLINDING parameters -+ - hide BN_BLINDING structure -+ Add a second BN_BLINDING slot to the RSA structure to improve -+ performance when a single RSA object is shared among several -+ threads. -+ [Nils Larsch] -+ -+ *) Add support for DTLS. -+ [Nagendra Modadugu and Ben Laurie] -+ -+ *) Add support for DER encoded private keys (SSL_FILETYPE_ASN1) -+ to SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file() -+ [Walter Goulet] -+ -+ *) Remove buggy and incomplete DH cert support from -+ ssl/ssl_rsa.c and ssl/s3_both.c -+ [Nils Larsch] -+ -+ *) Use SHA-1 instead of MD5 as the default digest algorithm for -+ the apps/openssl applications. -+ [Nils Larsch] -+ -+ *) Compile clean with "-Wall -Wmissing-prototypes -+ -Wstrict-prototypes -Wmissing-declarations -Werror". Currently -+ DEBUG_SAFESTACK must also be set. -+ [Ben Laurie] -+ -+ *) Change ./Configure so that certain algorithms can be disabled by default. -+ The new counterpiece to "no-xxx" is "enable-xxx". -+ -+ The patented RC5 and MDC2 algorithms will now be disabled unless -+ "enable-rc5" and "enable-mdc2", respectively, are specified. -+ -+ (IDEA remains enabled despite being patented. This is because IDEA -+ is frequently required for interoperability, and there is no license -+ fee for non-commercial use. As before, "no-idea" can be used to -+ avoid this algorithm.) -+ -+ [Bodo Moeller] -+ -+ *) Add processing of proxy certificates (see RFC 3820). This work was -+ sponsored by KTH (The Royal Institute of Technology in Stockholm) and -+ EGEE (Enabling Grids for E-science in Europe). -+ [Richard Levitte] -+ -+ *) RC4 performance overhaul on modern architectures/implementations, such -+ as Intel P4, IA-64 and AMD64. -+ [Andy Polyakov] -+ -+ *) New utility extract-section.pl. This can be used specify an alternative -+ section number in a pod file instead of having to treat each file as -+ a separate case in Makefile. This can be done by adding two lines to the -+ pod file: -+ -+ =for comment openssl_section:XXX -+ -+ The blank line is mandatory. -+ -+ [Steve Henson] -+ -+ *) New arguments -certform, -keyform and -pass for s_client and s_server -+ to allow alternative format key and certificate files and passphrase -+ sources. -+ [Steve Henson] -+ -+ *) New structure X509_VERIFY_PARAM which combines current verify parameters, -+ update associated structures and add various utility functions. -+ -+ Add new policy related verify parameters, include policy checking in -+ standard verify code. Enhance 'smime' application with extra parameters -+ to support policy checking and print out. -+ [Steve Henson] -+ -+ *) Add a new engine to support VIA PadLock ACE extensions in the VIA C3 -+ Nehemiah processors. These extensions support AES encryption in hardware -+ as well as RNG (though RNG support is currently disabled). -+ [Michal Ludvig , with help from Andy Polyakov] -+ -+ *) Deprecate BN_[get|set]_params() functions (they were ignored internally). -+ [Geoff Thorpe] -+ -+ *) New FIPS 180-2 algorithms, SHA-224/-256/-384/-512 are implemented. -+ [Andy Polyakov and a number of other people] -+ -+ *) Improved PowerPC platform support. Most notably BIGNUM assembler -+ implementation contributed by IBM. -+ [Suresh Chari, Peter Waltenberg, Andy Polyakov] -+ -+ *) The new 'RSA_generate_key_ex' function now takes a BIGNUM for the public -+ exponent rather than 'unsigned long'. There is a corresponding change to -+ the new 'rsa_keygen' element of the RSA_METHOD structure. -+ [Jelte Jansen, Geoff Thorpe] -+ -+ *) Functionality for creating the initial serial number file is now -+ moved from CA.pl to the 'ca' utility with a new option -create_serial. -+ -+ (Before OpenSSL 0.9.7e, CA.pl used to initialize the serial -+ number file to 1, which is bound to cause problems. To avoid -+ the problems while respecting compatibility between different 0.9.7 -+ patchlevels, 0.9.7e employed 'openssl x509 -next_serial' in -+ CA.pl for serial number initialization. With the new release 0.9.8, -+ we can fix the problem directly in the 'ca' utility.) -+ [Steve Henson] -+ -+ *) Reduced header interdepencies by declaring more opaque objects in -+ ossl_typ.h. As a consequence, including some headers (eg. engine.h) will -+ give fewer recursive includes, which could break lazy source code - so -+ this change is covered by the OPENSSL_NO_DEPRECATED symbol. As always, -+ developers should define this symbol when building and using openssl to -+ ensure they track the recommended behaviour, interfaces, [etc], but -+ backwards-compatible behaviour prevails when this isn't defined. -+ [Geoff Thorpe] -+ -+ *) New function X509_POLICY_NODE_print() which prints out policy nodes. -+ [Steve Henson] -+ -+ *) Add new EVP function EVP_CIPHER_CTX_rand_key and associated functionality. -+ This will generate a random key of the appropriate length based on the -+ cipher context. The EVP_CIPHER can provide its own random key generation -+ routine to support keys of a specific form. This is used in the des and -+ 3des routines to generate a key of the correct parity. Update S/MIME -+ code to use new functions and hence generate correct parity DES keys. -+ Add EVP_CHECK_DES_KEY #define to return an error if the key is not -+ valid (weak or incorrect parity). -+ [Steve Henson] -+ -+ *) Add a local set of CRLs that can be used by X509_verify_cert() as well -+ as looking them up. This is useful when the verified structure may contain -+ CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs -+ present unless the new PKCS7_NO_CRL flag is asserted. -+ [Steve Henson] -+ -+ *) Extend ASN1 oid configuration module. It now additionally accepts the -+ syntax: -+ -+ shortName = some long name, 1.2.3.4 -+ [Steve Henson] -+ -+ *) Reimplemented the BN_CTX implementation. There is now no more static -+ limitation on the number of variables it can handle nor the depth of the -+ "stack" handling for BN_CTX_start()/BN_CTX_end() pairs. The stack -+ information can now expand as required, and rather than having a single -+ static array of bignums, BN_CTX now uses a linked-list of such arrays -+ allowing it to expand on demand whilst maintaining the usefulness of -+ BN_CTX's "bundling". -+ [Geoff Thorpe] -+ -+ *) Add a missing BN_CTX parameter to the 'rsa_mod_exp' callback in RSA_METHOD -+ to allow all RSA operations to function using a single BN_CTX. -+ [Geoff Thorpe] -+ -+ *) Preliminary support for certificate policy evaluation and checking. This -+ is initially intended to pass the tests outlined in "Conformance Testing -+ of Relying Party Client Certificate Path Processing Logic" v1.07. -+ [Steve Henson] -+ -+ *) bn_dup_expand() has been deprecated, it was introduced in 0.9.7 and -+ remained unused and not that useful. A variety of other little bignum -+ tweaks and fixes have also been made continuing on from the audit (see -+ below). -+ [Geoff Thorpe] -+ -+ *) Constify all or almost all d2i, c2i, s2i and r2i functions, along with -+ associated ASN1, EVP and SSL functions and old ASN1 macros. -+ [Richard Levitte] -+ -+ *) BN_zero() only needs to set 'top' and 'neg' to zero for correct results, -+ and this should never fail. So the return value from the use of -+ BN_set_word() (which can fail due to needless expansion) is now deprecated; -+ if OPENSSL_NO_DEPRECATED is defined, BN_zero() is a void macro. -+ [Geoff Thorpe] -+ -+ *) BN_CTX_get() should return zero-valued bignums, providing the same -+ initialised value as BN_new(). -+ [Geoff Thorpe, suggested by Ulf Möller] -+ -+ *) Support for inhibitAnyPolicy certificate extension. -+ [Steve Henson] -+ -+ *) An audit of the BIGNUM code is underway, for which debugging code is -+ enabled when BN_DEBUG is defined. This makes stricter enforcements on what -+ is considered valid when processing BIGNUMs, and causes execution to -+ assert() when a problem is discovered. If BN_DEBUG_RAND is defined, -+ further steps are taken to deliberately pollute unused data in BIGNUM -+ structures to try and expose faulty code further on. For now, openssl will -+ (in its default mode of operation) continue to tolerate the inconsistent -+ forms that it has tolerated in the past, but authors and packagers should -+ consider trying openssl and their own applications when compiled with -+ these debugging symbols defined. It will help highlight potential bugs in -+ their own code, and will improve the test coverage for OpenSSL itself. At -+ some point, these tighter rules will become openssl's default to improve -+ maintainability, though the assert()s and other overheads will remain only -+ in debugging configurations. See bn.h for more details. -+ [Geoff Thorpe, Nils Larsch, Ulf Möller] -+ -+ *) BN_CTX_init() has been deprecated, as BN_CTX is an opaque structure -+ that can only be obtained through BN_CTX_new() (which implicitly -+ initialises it). The presence of this function only made it possible -+ to overwrite an existing structure (and cause memory leaks). -+ [Geoff Thorpe] -+ -+ *) Because of the callback-based approach for implementing LHASH as a -+ template type, lh_insert() adds opaque objects to hash-tables and -+ lh_doall() or lh_doall_arg() are typically used with a destructor callback -+ to clean up those corresponding objects before destroying the hash table -+ (and losing the object pointers). So some over-zealous constifications in -+ LHASH have been relaxed so that lh_insert() does not take (nor store) the -+ objects as "const" and the lh_doall[_arg] callback wrappers are not -+ prototyped to have "const" restrictions on the object pointers they are -+ given (and so aren't required to cast them away any more). -+ [Geoff Thorpe] -+ -+ *) The tmdiff.h API was so ugly and minimal that our own timing utility -+ (speed) prefers to use its own implementation. The two implementations -+ haven't been consolidated as yet (volunteers?) but the tmdiff API has had -+ its object type properly exposed (MS_TM) instead of casting to/from "char -+ *". This may still change yet if someone realises MS_TM and "ms_time_***" -+ aren't necessarily the greatest nomenclatures - but this is what was used -+ internally to the implementation so I've used that for now. -+ [Geoff Thorpe] -+ -+ *) Ensure that deprecated functions do not get compiled when -+ OPENSSL_NO_DEPRECATED is defined. Some "openssl" subcommands and a few of -+ the self-tests were still using deprecated key-generation functions so -+ these have been updated also. -+ [Geoff Thorpe] -+ -+ *) Reorganise PKCS#7 code to separate the digest location functionality -+ into PKCS7_find_digest(), digest addition into PKCS7_bio_add_digest(). -+ New function PKCS7_set_digest() to set the digest type for PKCS#7 -+ digestedData type. Add additional code to correctly generate the -+ digestedData type and add support for this type in PKCS7 initialization -+ functions. -+ [Steve Henson] -+ -+ *) New function PKCS7_set0_type_other() this initializes a PKCS7 -+ structure of type "other". -+ [Steve Henson] -+ -+ *) Fix prime generation loop in crypto/bn/bn_prime.pl by making -+ sure the loop does correctly stop and breaking ("division by zero") -+ modulus operations are not performed. The (pre-generated) prime -+ table crypto/bn/bn_prime.h was already correct, but it could not be -+ re-generated on some platforms because of the "division by zero" -+ situation in the script. -+ [Ralf S. Engelschall] -+ -+ *) Update support for ECC-based TLS ciphersuites according to -+ draft-ietf-tls-ecc-03.txt: the KDF1 key derivation function with -+ SHA-1 now is only used for "small" curves (where the -+ representation of a field element takes up to 24 bytes); for -+ larger curves, the field element resulting from ECDH is directly -+ used as premaster secret. -+ [Douglas Stebila (Sun Microsystems Laboratories)] -+ -+ *) Add code for kP+lQ timings to crypto/ec/ectest.c, and add SEC2 -+ curve secp160r1 to the tests. -+ [Douglas Stebila (Sun Microsystems Laboratories)] -+ -+ *) Add the possibility to load symbols globally with DSO. -+ [Götz Babin-Ebell via Richard Levitte] -+ -+ *) Add the functions ERR_set_mark() and ERR_pop_to_mark() for better -+ control of the error stack. -+ [Richard Levitte] -+ -+ *) Add support for STORE in ENGINE. -+ [Richard Levitte] -+ -+ *) Add the STORE type. The intention is to provide a common interface -+ to certificate and key stores, be they simple file-based stores, or -+ HSM-type store, or LDAP stores, or... -+ NOTE: The code is currently UNTESTED and isn't really used anywhere. -+ [Richard Levitte] -+ -+ *) Add a generic structure called OPENSSL_ITEM. This can be used to -+ pass a list of arguments to any function as well as provide a way -+ for a function to pass data back to the caller. -+ [Richard Levitte] -+ -+ *) Add the functions BUF_strndup() and BUF_memdup(). BUF_strndup() -+ works like BUF_strdup() but can be used to duplicate a portion of -+ a string. The copy gets NUL-terminated. BUF_memdup() duplicates -+ a memory area. -+ [Richard Levitte] -+ -+ *) Add the function sk_find_ex() which works like sk_find(), but will -+ return an index to an element even if an exact match couldn't be -+ found. The index is guaranteed to point at the element where the -+ searched-for key would be inserted to preserve sorting order. -+ [Richard Levitte] -+ -+ *) Add the function OBJ_bsearch_ex() which works like OBJ_bsearch() but -+ takes an extra flags argument for optional functionality. Currently, -+ the following flags are defined: -+ -+ OBJ_BSEARCH_VALUE_ON_NOMATCH -+ This one gets OBJ_bsearch_ex() to return a pointer to the first -+ element where the comparing function returns a negative or zero -+ number. -+ -+ OBJ_BSEARCH_FIRST_VALUE_ON_MATCH -+ This one gets OBJ_bsearch_ex() to return a pointer to the first -+ element where the comparing function returns zero. This is useful -+ if there are more than one element where the comparing function -+ returns zero. -+ [Richard Levitte] -+ -+ *) Make it possible to create self-signed certificates with 'openssl ca' -+ in such a way that the self-signed certificate becomes part of the -+ CA database and uses the same mechanisms for serial number generation -+ as all other certificate signing. The new flag '-selfsign' enables -+ this functionality. Adapt CA.sh and CA.pl.in. -+ [Richard Levitte] -+ -+ *) Add functionality to check the public key of a certificate request -+ against a given private. This is useful to check that a certificate -+ request can be signed by that key (self-signing). -+ [Richard Levitte] -+ -+ *) Make it possible to have multiple active certificates with the same -+ subject in the CA index file. This is done only if the keyword -+ 'unique_subject' is set to 'no' in the main CA section (default -+ if 'CA_default') of the configuration file. The value is saved -+ with the database itself in a separate index attribute file, -+ named like the index file with '.attr' appended to the name. -+ [Richard Levitte] -+ -+ *) Generate muti valued AVAs using '+' notation in config files for -+ req and dirName. -+ [Steve Henson] -+ -+ *) Support for nameConstraints certificate extension. -+ [Steve Henson] -+ -+ *) Support for policyConstraints certificate extension. -+ [Steve Henson] -+ -+ *) Support for policyMappings certificate extension. -+ [Steve Henson] -+ -+ *) Make sure the default DSA_METHOD implementation only uses its -+ dsa_mod_exp() and/or bn_mod_exp() handlers if they are non-NULL, -+ and change its own handlers to be NULL so as to remove unnecessary -+ indirection. This lets alternative implementations fallback to the -+ default implementation more easily. -+ [Geoff Thorpe] -+ -+ *) Support for directoryName in GeneralName related extensions -+ in config files. -+ [Steve Henson] -+ -+ *) Make it possible to link applications using Makefile.shared. -+ Make that possible even when linking against static libraries! -+ [Richard Levitte] -+ -+ *) Support for single pass processing for S/MIME signing. This now -+ means that S/MIME signing can be done from a pipe, in addition -+ cleartext signing (multipart/signed type) is effectively streaming -+ and the signed data does not need to be all held in memory. -+ -+ This is done with a new flag PKCS7_STREAM. When this flag is set -+ PKCS7_sign() only initializes the PKCS7 structure and the actual signing -+ is done after the data is output (and digests calculated) in -+ SMIME_write_PKCS7(). -+ [Steve Henson] -+ -+ *) Add full support for -rpath/-R, both in shared libraries and -+ applications, at least on the platforms where it's known how -+ to do it. -+ [Richard Levitte] -+ -+ *) In crypto/ec/ec_mult.c, implement fast point multiplication with -+ precomputation, based on wNAF splitting: EC_GROUP_precompute_mult() -+ will now compute a table of multiples of the generator that -+ makes subsequent invocations of EC_POINTs_mul() or EC_POINT_mul() -+ faster (notably in the case of a single point multiplication, -+ scalar * generator). -+ [Nils Larsch, Bodo Moeller] -+ -+ *) IPv6 support for certificate extensions. The various extensions -+ which use the IP:a.b.c.d can now take IPv6 addresses using the -+ formats of RFC1884 2.2 . IPv6 addresses are now also displayed -+ correctly. -+ [Steve Henson] -+ -+ *) Added an ENGINE that implements RSA by performing private key -+ exponentiations with the GMP library. The conversions to and from -+ GMP's mpz_t format aren't optimised nor are any montgomery forms -+ cached, and on x86 it appears OpenSSL's own performance has caught up. -+ However there are likely to be other architectures where GMP could -+ provide a boost. This ENGINE is not built in by default, but it can be -+ specified at Configure time and should be accompanied by the necessary -+ linker additions, eg; -+ ./config -DOPENSSL_USE_GMP -lgmp -+ [Geoff Thorpe] -+ -+ *) "openssl engine" will not display ENGINE/DSO load failure errors when -+ testing availability of engines with "-t" - the old behaviour is -+ produced by increasing the feature's verbosity with "-tt". -+ [Geoff Thorpe] -+ -+ *) ECDSA routines: under certain error conditions uninitialized BN objects -+ could be freed. Solution: make sure initialization is performed early -+ enough. (Reported and fix supplied by Nils Larsch -+ via PR#459) -+ [Lutz Jaenicke] -+ -+ *) Key-generation can now be implemented in RSA_METHOD, DSA_METHOD -+ and DH_METHOD (eg. by ENGINE implementations) to override the normal -+ software implementations. For DSA and DH, parameter generation can -+ also be overridden by providing the appropriate method callbacks. -+ [Geoff Thorpe] -+ -+ *) Change the "progress" mechanism used in key-generation and -+ primality testing to functions that take a new BN_GENCB pointer in -+ place of callback/argument pairs. The new API functions have "_ex" -+ postfixes and the older functions are reimplemented as wrappers for -+ the new ones. The OPENSSL_NO_DEPRECATED symbol can be used to hide -+ declarations of the old functions to help (graceful) attempts to -+ migrate to the new functions. Also, the new key-generation API -+ functions operate on a caller-supplied key-structure and return -+ success/failure rather than returning a key or NULL - this is to -+ help make "keygen" another member function of RSA_METHOD etc. -+ -+ Example for using the new callback interface: -+ -+ int (*my_callback)(int a, int b, BN_GENCB *cb) = ...; -+ void *my_arg = ...; -+ BN_GENCB my_cb; -+ -+ BN_GENCB_set(&my_cb, my_callback, my_arg); -+ -+ return BN_is_prime_ex(some_bignum, BN_prime_checks, NULL, &cb); -+ /* For the meaning of a, b in calls to my_callback(), see the -+ * documentation of the function that calls the callback. -+ * cb will point to my_cb; my_arg can be retrieved as cb->arg. -+ * my_callback should return 1 if it wants BN_is_prime_ex() -+ * to continue, or 0 to stop. -+ */ -+ -+ [Geoff Thorpe] -+ -+ *) Change the ZLIB compression method to be stateful, and make it -+ available to TLS with the number defined in -+ draft-ietf-tls-compression-04.txt. -+ [Richard Levitte] -+ -+ *) Add the ASN.1 structures and functions for CertificatePair, which -+ is defined as follows (according to X.509_4thEditionDraftV6.pdf): -+ -+ CertificatePair ::= SEQUENCE { -+ forward [0] Certificate OPTIONAL, -+ reverse [1] Certificate OPTIONAL, -+ -- at least one of the pair shall be present -- } -+ -+ Also implement the PEM functions to read and write certificate -+ pairs, and defined the PEM tag as "CERTIFICATE PAIR". -+ -+ This needed to be defined, mostly for the sake of the LDAP -+ attribute crossCertificatePair, but may prove useful elsewhere as -+ well. -+ [Richard Levitte] -+ -+ *) Make it possible to inhibit symlinking of shared libraries in -+ Makefile.shared, for Cygwin's sake. -+ [Richard Levitte] -+ -+ *) Extend the BIGNUM API by creating a function -+ void BN_set_negative(BIGNUM *a, int neg); -+ and a macro that behave like -+ int BN_is_negative(const BIGNUM *a); -+ -+ to avoid the need to access 'a->neg' directly in applications. -+ [Nils Larsch] -+ -+ *) Implement fast modular reduction for pseudo-Mersenne primes -+ used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c). -+ EC_GROUP_new_curve_GFp() will now automatically use this -+ if applicable. -+ [Nils Larsch ] -+ -+ *) Add new lock type (CRYPTO_LOCK_BN). -+ [Bodo Moeller] -+ -+ *) Change the ENGINE framework to automatically load engines -+ dynamically from specific directories unless they could be -+ found to already be built in or loaded. Move all the -+ current engines except for the cryptodev one to a new -+ directory engines/. -+ The engines in engines/ are built as shared libraries if -+ the "shared" options was given to ./Configure or ./config. -+ Otherwise, they are inserted in libcrypto.a. -+ /usr/local/ssl/engines is the default directory for dynamic -+ engines, but that can be overridden at configure time through -+ the usual use of --prefix and/or --openssldir, and at run -+ time with the environment variable OPENSSL_ENGINES. -+ [Geoff Thorpe and Richard Levitte] -+ -+ *) Add Makefile.shared, a helper makefile to build shared -+ libraries. Adapt Makefile.org. -+ [Richard Levitte] -+ -+ *) Add version info to Win32 DLLs. -+ [Peter 'Luna' Runestig" ] -+ -+ *) Add new 'medium level' PKCS#12 API. Certificates and keys -+ can be added using this API to created arbitrary PKCS#12 -+ files while avoiding the low level API. -+ -+ New options to PKCS12_create(), key or cert can be NULL and -+ will then be omitted from the output file. The encryption -+ algorithm NIDs can be set to -1 for no encryption, the mac -+ iteration count can be set to 0 to omit the mac. -+ -+ Enhance pkcs12 utility by making the -nokeys and -nocerts -+ options work when creating a PKCS#12 file. New option -nomac -+ to omit the mac, NONE can be set for an encryption algorithm. -+ New code is modified to use the enhanced PKCS12_create() -+ instead of the low level API. -+ [Steve Henson] -+ -+ *) Extend ASN1 encoder to support indefinite length constructed -+ encoding. This can output sequences tags and octet strings in -+ this form. Modify pk7_asn1.c to support indefinite length -+ encoding. This is experimental and needs additional code to -+ be useful, such as an ASN1 bio and some enhanced streaming -+ PKCS#7 code. -+ -+ Extend template encode functionality so that tagging is passed -+ down to the template encoder. -+ [Steve Henson] -+ -+ *) Let 'openssl req' fail if an argument to '-newkey' is not -+ recognized instead of using RSA as a default. -+ [Bodo Moeller] -+ -+ *) Add support for ECC-based ciphersuites from draft-ietf-tls-ecc-01.txt. -+ As these are not official, they are not included in "ALL"; -+ the "ECCdraft" ciphersuite group alias can be used to select them. -+ [Vipul Gupta and Sumit Gupta (Sun Microsystems Laboratories)] -+ -+ *) Add ECDH engine support. -+ [Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)] -+ -+ *) Add ECDH in new directory crypto/ecdh/. -+ [Douglas Stebila (Sun Microsystems Laboratories)] -+ -+ *) Let BN_rand_range() abort with an error after 100 iterations -+ without success (which indicates a broken PRNG). -+ [Bodo Moeller] -+ -+ *) Change BN_mod_sqrt() so that it verifies that the input value -+ is really the square of the return value. (Previously, -+ BN_mod_sqrt would show GIGO behaviour.) -+ [Bodo Moeller] -+ -+ *) Add named elliptic curves over binary fields from X9.62, SECG, -+ and WAP/WTLS; add OIDs that were still missing. -+ -+ [Sheueling Chang Shantz and Douglas Stebila -+ (Sun Microsystems Laboratories)] -+ -+ *) Extend the EC library for elliptic curves over binary fields -+ (new files ec2_smpl.c, ec2_smpt.c, ec2_mult.c in crypto/ec/). -+ New EC_METHOD: -+ -+ EC_GF2m_simple_method -+ -+ New API functions: -+ -+ EC_GROUP_new_curve_GF2m -+ EC_GROUP_set_curve_GF2m -+ EC_GROUP_get_curve_GF2m -+ EC_POINT_set_affine_coordinates_GF2m -+ EC_POINT_get_affine_coordinates_GF2m -+ EC_POINT_set_compressed_coordinates_GF2m -+ -+ Point compression for binary fields is disabled by default for -+ patent reasons (compile with OPENSSL_EC_BIN_PT_COMP defined to -+ enable it). -+ -+ As binary polynomials are represented as BIGNUMs, various members -+ of the EC_GROUP and EC_POINT data structures can be shared -+ between the implementations for prime fields and binary fields; -+ the above ..._GF2m functions (except for EX_GROUP_new_curve_GF2m) -+ are essentially identical to their ..._GFp counterparts. -+ (For simplicity, the '..._GFp' prefix has been dropped from -+ various internal method names.) -+ -+ An internal 'field_div' method (similar to 'field_mul' and -+ 'field_sqr') has been added; this is used only for binary fields. -+ -+ [Sheueling Chang Shantz and Douglas Stebila -+ (Sun Microsystems Laboratories)] -+ -+ *) Optionally dispatch EC_POINT_mul(), EC_POINT_precompute_mult() -+ through methods ('mul', 'precompute_mult'). -+ -+ The generic implementations (now internally called 'ec_wNAF_mul' -+ and 'ec_wNAF_precomputed_mult') remain the default if these -+ methods are undefined. -+ -+ [Sheueling Chang Shantz and Douglas Stebila -+ (Sun Microsystems Laboratories)] -+ -+ *) New function EC_GROUP_get_degree, which is defined through -+ EC_METHOD. For curves over prime fields, this returns the bit -+ length of the modulus. -+ -+ [Sheueling Chang Shantz and Douglas Stebila -+ (Sun Microsystems Laboratories)] -+ -+ *) New functions EC_GROUP_dup, EC_POINT_dup. -+ (These simply call ..._new and ..._copy). -+ -+ [Sheueling Chang Shantz and Douglas Stebila -+ (Sun Microsystems Laboratories)] -+ -+ *) Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c. -+ Polynomials are represented as BIGNUMs (where the sign bit is not -+ used) in the following functions [macros]: -+ -+ BN_GF2m_add -+ BN_GF2m_sub [= BN_GF2m_add] -+ BN_GF2m_mod [wrapper for BN_GF2m_mod_arr] -+ BN_GF2m_mod_mul [wrapper for BN_GF2m_mod_mul_arr] -+ BN_GF2m_mod_sqr [wrapper for BN_GF2m_mod_sqr_arr] -+ BN_GF2m_mod_inv -+ BN_GF2m_mod_exp [wrapper for BN_GF2m_mod_exp_arr] -+ BN_GF2m_mod_sqrt [wrapper for BN_GF2m_mod_sqrt_arr] -+ BN_GF2m_mod_solve_quad [wrapper for BN_GF2m_mod_solve_quad_arr] -+ BN_GF2m_cmp [= BN_ucmp] -+ -+ (Note that only the 'mod' functions are actually for fields GF(2^m). -+ BN_GF2m_add() is misnomer, but this is for the sake of consistency.) -+ -+ For some functions, an the irreducible polynomial defining a -+ field can be given as an 'unsigned int[]' with strictly -+ decreasing elements giving the indices of those bits that are set; -+ i.e., p[] represents the polynomial -+ f(t) = t^p[0] + t^p[1] + ... + t^p[k] -+ where -+ p[0] > p[1] > ... > p[k] = 0. -+ This applies to the following functions: -+ -+ BN_GF2m_mod_arr -+ BN_GF2m_mod_mul_arr -+ BN_GF2m_mod_sqr_arr -+ BN_GF2m_mod_inv_arr [wrapper for BN_GF2m_mod_inv] -+ BN_GF2m_mod_div_arr [wrapper for BN_GF2m_mod_div] -+ BN_GF2m_mod_exp_arr -+ BN_GF2m_mod_sqrt_arr -+ BN_GF2m_mod_solve_quad_arr -+ BN_GF2m_poly2arr -+ BN_GF2m_arr2poly -+ -+ Conversion can be performed by the following functions: -+ -+ BN_GF2m_poly2arr -+ BN_GF2m_arr2poly -+ -+ bntest.c has additional tests for binary polynomial arithmetic. -+ -+ Two implementations for BN_GF2m_mod_div() are available. -+ The default algorithm simply uses BN_GF2m_mod_inv() and -+ BN_GF2m_mod_mul(). The alternative algorithm is compiled in only -+ if OPENSSL_SUN_GF2M_DIV is defined (patent pending; read the -+ copyright notice in crypto/bn/bn_gf2m.c before enabling it). -+ -+ [Sheueling Chang Shantz and Douglas Stebila -+ (Sun Microsystems Laboratories)] -+ -+ *) Add new error code 'ERR_R_DISABLED' that can be used when some -+ functionality is disabled at compile-time. -+ [Douglas Stebila ] -+ -+ *) Change default behaviour of 'openssl asn1parse' so that more -+ information is visible when viewing, e.g., a certificate: -+ -+ Modify asn1_parse2 (crypto/asn1/asn1_par.c) so that in non-'dump' -+ mode the content of non-printable OCTET STRINGs is output in a -+ style similar to INTEGERs, but with '[HEX DUMP]' prepended to -+ avoid the appearance of a printable string. -+ [Nils Larsch ] -+ -+ *) Add 'asn1_flag' and 'asn1_form' member to EC_GROUP with access -+ functions -+ EC_GROUP_set_asn1_flag() -+ EC_GROUP_get_asn1_flag() -+ EC_GROUP_set_point_conversion_form() -+ EC_GROUP_get_point_conversion_form() -+ These control ASN1 encoding details: -+ - Curves (i.e., groups) are encoded explicitly unless asn1_flag -+ has been set to OPENSSL_EC_NAMED_CURVE. -+ - Points are encoded in uncompressed form by default; options for -+ asn1_for are as for point2oct, namely -+ POINT_CONVERSION_COMPRESSED -+ POINT_CONVERSION_UNCOMPRESSED -+ POINT_CONVERSION_HYBRID -+ -+ Also add 'seed' and 'seed_len' members to EC_GROUP with access -+ functions -+ EC_GROUP_set_seed() -+ EC_GROUP_get0_seed() -+ EC_GROUP_get_seed_len() -+ This is used only for ASN1 purposes (so far). -+ [Nils Larsch ] -+ -+ *) Add 'field_type' member to EC_METHOD, which holds the NID -+ of the appropriate field type OID. The new function -+ EC_METHOD_get_field_type() returns this value. -+ [Nils Larsch ] -+ -+ *) Add functions -+ EC_POINT_point2bn() -+ EC_POINT_bn2point() -+ EC_POINT_point2hex() -+ EC_POINT_hex2point() -+ providing useful interfaces to EC_POINT_point2oct() and -+ EC_POINT_oct2point(). -+ [Nils Larsch ] -+ -+ *) Change internals of the EC library so that the functions -+ EC_GROUP_set_generator() -+ EC_GROUP_get_generator() -+ EC_GROUP_get_order() -+ EC_GROUP_get_cofactor() -+ are implemented directly in crypto/ec/ec_lib.c and not dispatched -+ to methods, which would lead to unnecessary code duplication when -+ adding different types of curves. -+ [Nils Larsch with input by Bodo Moeller] -+ -+ *) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM -+ arithmetic, and such that modified wNAFs are generated -+ (which avoid length expansion in many cases). -+ [Bodo Moeller] -+ -+ *) Add a function EC_GROUP_check_discriminant() (defined via -+ EC_METHOD) that verifies that the curve discriminant is non-zero. -+ -+ Add a function EC_GROUP_check() that makes some sanity tests -+ on a EC_GROUP, its generator and order. This includes -+ EC_GROUP_check_discriminant(). -+ [Nils Larsch ] -+ -+ *) Add ECDSA in new directory crypto/ecdsa/. -+ -+ Add applications 'openssl ecparam' and 'openssl ecdsa' -+ (these are based on 'openssl dsaparam' and 'openssl dsa'). -+ -+ ECDSA support is also included in various other files across the -+ library. Most notably, -+ - 'openssl req' now has a '-newkey ecdsa:file' option; -+ - EVP_PKCS82PKEY (crypto/evp/evp_pkey.c) now can handle ECDSA; -+ - X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and -+ d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make -+ them suitable for ECDSA where domain parameters must be -+ extracted before the specific public key; -+ - ECDSA engine support has been added. -+ [Nils Larsch ] -+ -+ *) Include some named elliptic curves, and add OIDs from X9.62, -+ SECG, and WAP/WTLS. Each curve can be obtained from the new -+ function -+ EC_GROUP_new_by_curve_name(), -+ and the list of available named curves can be obtained with -+ EC_get_builtin_curves(). -+ Also add a 'curve_name' member to EC_GROUP objects, which can be -+ accessed via -+ EC_GROUP_set_curve_name() -+ EC_GROUP_get_curve_name() -+ [Nils Larsch ] -+ -+ *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that -+ a ciphersuite string such as "DEFAULT:RSA" cannot enable -+ authentication-only ciphersuites. -+ [Bodo Moeller] -+ -+ *) Since AES128 and AES256 share a single mask bit in the logic of -+ ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a -+ kludge to work properly if AES128 is available and AES256 isn't. -+ [Victor Duchovni] -+ -+ *) Expand security boundary to match 1.1.1 module. -+ [Steve Henson] -+ -+ *) Remove redundant features: hash file source, editing of test vectors -+ modify fipsld to use external fips_premain.c signature. -+ [Steve Henson] -+ -+ *) New perl script mkfipsscr.pl to create shell scripts or batch files to -+ run algorithm test programs. -+ [Steve Henson] -+ -+ *) Make algorithm test programs more tolerant of whitespace. -+ [Steve Henson] -+ -+ *) Have SSL/TLS server implementation tolerate "mismatched" record -+ protocol version while receiving ClientHello even if the -+ ClientHello is fragmented. (The server can't insist on the -+ particular protocol version it has chosen before the ServerHello -+ message has informed the client about his choice.) -+ [Bodo Moeller] -+ -+ *) Load error codes if they are not already present instead of using a -+ static variable. This allows them to be cleanly unloaded and reloaded. -+ [Steve Henson] -+ -+ Changes between 0.9.7k and 0.9.7l [28 Sep 2006] -+ -+ *) Introduce limits to prevent malicious keys being able to -+ cause a denial of service. (CVE-2006-2940) -+ [Steve Henson, Bodo Moeller] -+ -+ *) Fix ASN.1 parsing of certain invalid structures that can result -+ in a denial of service. (CVE-2006-2937) [Steve Henson] -+ -+ *) Fix buffer overflow in SSL_get_shared_ciphers() function. -+ (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team] -+ -+ *) Fix SSL client code which could crash if connecting to a -+ malicious SSLv2 server. (CVE-2006-4343) -+ [Tavis Ormandy and Will Drewry, Google Security Team] -+ -+ *) Change ciphersuite string processing so that an explicit -+ ciphersuite selects this one ciphersuite (so that "AES256-SHA" -+ will no longer include "AES128-SHA"), and any other similar -+ ciphersuite (same bitmap) from *other* protocol versions (so that -+ "RC4-MD5" will still include both the SSL 2.0 ciphersuite and the -+ SSL 3.0/TLS 1.0 ciphersuite). This is a backport combining -+ changes from 0.9.8b and 0.9.8d. -+ [Bodo Moeller] -+ -+ Changes between 0.9.7j and 0.9.7k [05 Sep 2006] -+ -+ *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher -+ (CVE-2006-4339) [Ben Laurie and Google Security Team] -+ -+ *) Change the Unix randomness entropy gathering to use poll() when -+ possible instead of select(), since the latter has some -+ undesirable limitations. -+ [Darryl Miles via Richard Levitte and Bodo Moeller] -+ -+ *) Disable rogue ciphersuites: -+ -+ - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5") -+ - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5") -+ - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5") -+ -+ The latter two were purportedly from -+ draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really -+ appear there. -+ -+ Also deactive the remaining ciphersuites from -+ draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as -+ unofficial, and the ID has long expired. -+ [Bodo Moeller] -+ -+ *) Fix RSA blinding Heisenbug (problems sometimes occurred on -+ dual-core machines) and other potential thread-safety issues. -+ [Bodo Moeller] -+ -+ Changes between 0.9.7i and 0.9.7j [04 May 2006] -+ -+ *) Adapt fipsld and the build system to link against the validated FIPS -+ module in FIPS mode. -+ [Steve Henson] -+ -+ *) Fixes for VC++ 2005 build under Windows. -+ [Steve Henson] -+ -+ *) Add new Windows build target VC-32-GMAKE for VC++. This uses GNU make -+ from a Windows bash shell such as MSYS. It is autodetected from the -+ "config" script when run from a VC++ environment. Modify standard VC++ -+ build to use fipscanister.o from the GNU make build. -+ [Steve Henson] -+ -+ Changes between 0.9.7h and 0.9.7i [14 Oct 2005] -+ -+ *) Wrapped the definition of EVP_MAX_MD_SIZE in a #ifdef OPENSSL_FIPS. -+ The value now differs depending on if you build for FIPS or not. -+ BEWARE! A program linked with a shared FIPSed libcrypto can't be -+ safely run with a non-FIPSed libcrypto, as it may crash because of -+ the difference induced by this change. -+ [Andy Polyakov] -+ -+ Changes between 0.9.7g and 0.9.7h [11 Oct 2005] -+ -+ *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING -+ (part of SSL_OP_ALL). This option used to disable the -+ countermeasure against man-in-the-middle protocol-version -+ rollback in the SSL 2.0 server implementation, which is a bad -+ idea. (CVE-2005-2969) -+ -+ [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center -+ for Information Security, National Institute of Advanced Industrial -+ Science and Technology [AIST], Japan)] -+ -+ *) Minimal support for X9.31 signatures and PSS padding modes. This is -+ mainly for FIPS compliance and not fully integrated at this stage. -+ [Steve Henson] -+ -+ *) For DSA signing, unless DSA_FLAG_NO_EXP_CONSTTIME is set, perform -+ the exponentiation using a fixed-length exponent. (Otherwise, -+ the information leaked through timing could expose the secret key -+ after many signatures; cf. Bleichenbacher's attack on DSA with -+ biased k.) -+ [Bodo Moeller] -+ -+ *) Make a new fixed-window mod_exp implementation the default for -+ RSA, DSA, and DH private-key operations so that the sequence of -+ squares and multiplies and the memory access pattern are -+ independent of the particular secret key. This will mitigate -+ cache-timing and potential related attacks. -+ -+ BN_mod_exp_mont_consttime() is the new exponentiation implementation, -+ and this is automatically used by BN_mod_exp_mont() if the new flag -+ BN_FLG_EXP_CONSTTIME is set for the exponent. RSA, DSA, and DH -+ will use this BN flag for private exponents unless the flag -+ RSA_FLAG_NO_EXP_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME, or -+ DH_FLAG_NO_EXP_CONSTTIME, respectively, is set. -+ -+ [Matthew D Wood (Intel Corp), with some changes by Bodo Moeller] -+ -+ *) Change the client implementation for SSLv23_method() and -+ SSLv23_client_method() so that is uses the SSL 3.0/TLS 1.0 -+ Client Hello message format if the SSL_OP_NO_SSLv2 option is set. -+ (Previously, the SSL 2.0 backwards compatible Client Hello -+ message format would be used even with SSL_OP_NO_SSLv2.) -+ [Bodo Moeller] -+ -+ *) Add support for smime-type MIME parameter in S/MIME messages which some -+ clients need. -+ [Steve Henson] -+ -+ *) New function BN_MONT_CTX_set_locked() to set montgomery parameters in -+ a threadsafe manner. Modify rsa code to use new function and add calls -+ to dsa and dh code (which had race conditions before). -+ [Steve Henson] -+ -+ *) Include the fixed error library code in the C error file definitions -+ instead of fixing them up at runtime. This keeps the error code -+ structures constant. -+ [Steve Henson] -+ -+ Changes between 0.9.7f and 0.9.7g [11 Apr 2005] -+ -+ [NB: OpenSSL 0.9.7h and later 0.9.7 patch levels were released after -+ OpenSSL 0.9.8.] -+ -+ *) Fixes for newer kerberos headers. NB: the casts are needed because -+ the 'length' field is signed on one version and unsigned on another -+ with no (?) obvious way to tell the difference, without these VC++ -+ complains. Also the "definition" of FAR (blank) is no longer included -+ nor is the error ENOMEM. KRB5_PRIVATE has to be set to 1 to pick up -+ some needed definitions. -+ [Steve Henson] -+ -+ *) Undo Cygwin change. -+ [Ulf Möller] -+ -+ *) Added support for proxy certificates according to RFC 3820. -+ Because they may be a security thread to unaware applications, -+ they must be explicitly allowed in run-time. See -+ docs/HOWTO/proxy_certificates.txt for further information. -+ [Richard Levitte] -+ -+ Changes between 0.9.7e and 0.9.7f [22 Mar 2005] -+ -+ *) Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating -+ server and client random values. Previously -+ (SSL_RANDOM_VALUE - sizeof(time_t)) would be used which would result in -+ less random data when sizeof(time_t) > 4 (some 64 bit platforms). -+ -+ This change has negligible security impact because: -+ -+ 1. Server and client random values still have 24 bytes of pseudo random -+ data. -+ -+ 2. Server and client random values are sent in the clear in the initial -+ handshake. -+ -+ 3. The master secret is derived using the premaster secret (48 bytes in -+ size for static RSA ciphersuites) as well as client server and random -+ values. -+ -+ The OpenSSL team would like to thank the UK NISCC for bringing this issue -+ to our attention. -+ -+ [Stephen Henson, reported by UK NISCC] -+ -+ *) Use Windows randomness collection on Cygwin. -+ [Ulf Möller] -+ -+ *) Fix hang in EGD/PRNGD query when communication socket is closed -+ prematurely by EGD/PRNGD. -+ [Darren Tucker via Lutz Jänicke, resolves #1014] -+ -+ *) Prompt for pass phrases when appropriate for PKCS12 input format. -+ [Steve Henson] -+ -+ *) Back-port of selected performance improvements from development -+ branch, as well as improved support for PowerPC platforms. -+ [Andy Polyakov] -+ -+ *) Add lots of checks for memory allocation failure, error codes to indicate -+ failure and freeing up memory if a failure occurs. -+ [Nauticus Networks SSL Team , Steve Henson] -+ -+ *) Add new -passin argument to dgst. -+ [Steve Henson] -+ -+ *) Perform some character comparisons of different types in X509_NAME_cmp: -+ this is needed for some certificates that re-encode DNs into UTF8Strings -+ (in violation of RFC3280) and can't or won't issue name rollover -+ certificates. -+ [Steve Henson] -+ -+ *) Make an explicit check during certificate validation to see that -+ the CA setting in each certificate on the chain is correct. As a -+ side effect always do the following basic checks on extensions, -+ not just when there's an associated purpose to the check: -+ -+ - if there is an unhandled critical extension (unless the user -+ has chosen to ignore this fault) -+ - if the path length has been exceeded (if one is set at all) -+ - that certain extensions fit the associated purpose (if one has -+ been given) -+ [Richard Levitte] -+ -+ Changes between 0.9.7d and 0.9.7e [25 Oct 2004] -+ -+ *) Avoid a race condition when CRLs are checked in a multi threaded -+ environment. This would happen due to the reordering of the revoked -+ entries during signature checking and serial number lookup. Now the -+ encoding is cached and the serial number sort performed under a lock. -+ Add new STACK function sk_is_sorted(). -+ [Steve Henson] -+ -+ *) Add Delta CRL to the extension code. -+ [Steve Henson] -+ -+ *) Various fixes to s3_pkt.c so alerts are sent properly. -+ [David Holmes ] -+ -+ *) Reduce the chances of duplicate issuer name and serial numbers (in -+ violation of RFC3280) using the OpenSSL certificate creation utilities. -+ This is done by creating a random 64 bit value for the initial serial -+ number when a serial number file is created or when a self signed -+ certificate is created using 'openssl req -x509'. The initial serial -+ number file is created using 'openssl x509 -next_serial' in CA.pl -+ rather than being initialized to 1. -+ [Steve Henson] -+ -+ Changes between 0.9.7c and 0.9.7d [17 Mar 2004] -+ -+ *) Fix null-pointer assignment in do_change_cipher_spec() revealed -+ by using the Codenomicon TLS Test Tool (CVE-2004-0079) -+ [Joe Orton, Steve Henson] -+ -+ *) Fix flaw in SSL/TLS handshaking when using Kerberos ciphersuites -+ (CVE-2004-0112) -+ [Joe Orton, Steve Henson] -+ -+ *) Make it possible to have multiple active certificates with the same -+ subject in the CA index file. This is done only if the keyword -+ 'unique_subject' is set to 'no' in the main CA section (default -+ if 'CA_default') of the configuration file. The value is saved -+ with the database itself in a separate index attribute file, -+ named like the index file with '.attr' appended to the name. -+ [Richard Levitte] -+ -+ *) X509 verify fixes. Disable broken certificate workarounds when -+ X509_V_FLAGS_X509_STRICT is set. Check CRL issuer has cRLSign set if -+ keyUsage extension present. Don't accept CRLs with unhandled critical -+ extensions: since verify currently doesn't process CRL extensions this -+ rejects a CRL with *any* critical extensions. Add new verify error codes -+ for these cases. -+ [Steve Henson] -+ -+ *) When creating an OCSP nonce use an OCTET STRING inside the extnValue. -+ A clarification of RFC2560 will require the use of OCTET STRINGs and -+ some implementations cannot handle the current raw format. Since OpenSSL -+ copies and compares OCSP nonces as opaque blobs without any attempt at -+ parsing them this should not create any compatibility issues. -+ [Steve Henson] -+ -+ *) New md flag EVP_MD_CTX_FLAG_REUSE this allows md_data to be reused when -+ calling EVP_MD_CTX_copy_ex() to avoid calling OPENSSL_malloc(). Without -+ this HMAC (and other) operations are several times slower than OpenSSL -+ < 0.9.7. -+ [Steve Henson] -+ -+ *) Print out GeneralizedTime and UTCTime in ASN1_STRING_print_ex(). -+ [Peter Sylvester ] -+ -+ *) Use the correct content when signing type "other". -+ [Steve Henson] -+ -+ Changes between 0.9.7b and 0.9.7c [30 Sep 2003] -+ -+ *) Fix various bugs revealed by running the NISCC test suite: -+ -+ Stop out of bounds reads in the ASN1 code when presented with -+ invalid tags (CVE-2003-0543 and CVE-2003-0544). -+ -+ Free up ASN1_TYPE correctly if ANY type is invalid (CVE-2003-0545). -+ -+ If verify callback ignores invalid public key errors don't try to check -+ certificate signature with the NULL public key. -+ -+ [Steve Henson] -+ -+ *) New -ignore_err option in ocsp application to stop the server -+ exiting on the first error in a request. -+ [Steve Henson] -+ -+ *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate -+ if the server requested one: as stated in TLS 1.0 and SSL 3.0 -+ specifications. -+ [Steve Henson] -+ -+ *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional -+ extra data after the compression methods not only for TLS 1.0 -+ but also for SSL 3.0 (as required by the specification). -+ [Bodo Moeller; problem pointed out by Matthias Loepfe] -+ -+ *) Change X509_certificate_type() to mark the key as exported/exportable -+ when it's 512 *bits* long, not 512 bytes. -+ [Richard Levitte] -+ -+ *) Change AES_cbc_encrypt() so it outputs exact multiple of -+ blocks during encryption. -+ [Richard Levitte] -+ -+ *) Various fixes to base64 BIO and non blocking I/O. On write -+ flushes were not handled properly if the BIO retried. On read -+ data was not being buffered properly and had various logic bugs. -+ This also affects blocking I/O when the data being decoded is a -+ certain size. -+ [Steve Henson] -+ -+ *) Various S/MIME bugfixes and compatibility changes: -+ output correct application/pkcs7 MIME type if -+ PKCS7_NOOLDMIMETYPE is set. Tolerate some broken signatures. -+ Output CR+LF for EOL if PKCS7_CRLFEOL is set (this makes opening -+ of files as .eml work). Correctly handle very long lines in MIME -+ parser. -+ [Steve Henson] -+ -+ Changes between 0.9.7a and 0.9.7b [10 Apr 2003] -+ -+ *) Countermeasure against the Klima-Pokorny-Rosa extension of -+ Bleichbacher's attack on PKCS #1 v1.5 padding: treat -+ a protocol version number mismatch like a decryption error -+ in ssl3_get_client_key_exchange (ssl/s3_srvr.c). -+ [Bodo Moeller] -+ -+ *) Turn on RSA blinding by default in the default implementation -+ to avoid a timing attack. Applications that don't want it can call -+ RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING. -+ They would be ill-advised to do so in most cases. -+ [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller] -+ -+ *) Change RSA blinding code so that it works when the PRNG is not -+ seeded (in this case, the secret RSA exponent is abused as -+ an unpredictable seed -- if it is not unpredictable, there -+ is no point in blinding anyway). Make RSA blinding thread-safe -+ by remembering the creator's thread ID in rsa->blinding and -+ having all other threads use local one-time blinding factors -+ (this requires more computation than sharing rsa->blinding, but -+ avoids excessive locking; and if an RSA object is not shared -+ between threads, blinding will still be very fast). -+ [Bodo Moeller] -+ -+ *) Fixed a typo bug that would cause ENGINE_set_default() to set an -+ ENGINE as defaults for all supported algorithms irrespective of -+ the 'flags' parameter. 'flags' is now honoured, so applications -+ should make sure they are passing it correctly. -+ [Geoff Thorpe] -+ -+ *) Target "mingw" now allows native Windows code to be generated in -+ the Cygwin environment as well as with the MinGW compiler. -+ [Ulf Moeller] -+ -+ Changes between 0.9.7 and 0.9.7a [19 Feb 2003] -+ -+ *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked -+ via timing by performing a MAC computation even if incorrect -+ block cipher padding has been found. This is a countermeasure -+ against active attacks where the attacker has to distinguish -+ between bad padding and a MAC verification error. (CVE-2003-0078) -+ -+ [Bodo Moeller; problem pointed out by Brice Canvel (EPFL), -+ Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and -+ Martin Vuagnoux (EPFL, Ilion)] -+ -+ *) Make the no-err option work as intended. The intention with no-err -+ is not to have the whole error stack handling routines removed from -+ libcrypto, it's only intended to remove all the function name and -+ reason texts, thereby removing some of the footprint that may not -+ be interesting if those errors aren't displayed anyway. -+ -+ NOTE: it's still possible for any application or module to have it's -+ own set of error texts inserted. The routines are there, just not -+ used by default when no-err is given. -+ [Richard Levitte] -+ -+ *) Add support for FreeBSD on IA64. -+ [dirk.meyer@dinoex.sub.org via Richard Levitte, resolves #454] -+ -+ *) Adjust DES_cbc_cksum() so it returns the same value as the MIT -+ Kerberos function mit_des_cbc_cksum(). Before this change, -+ the value returned by DES_cbc_cksum() was like the one from -+ mit_des_cbc_cksum(), except the bytes were swapped. -+ [Kevin Greaney and Richard Levitte] -+ -+ *) Allow an application to disable the automatic SSL chain building. -+ Before this a rather primitive chain build was always performed in -+ ssl3_output_cert_chain(): an application had no way to send the -+ correct chain if the automatic operation produced an incorrect result. -+ -+ Now the chain builder is disabled if either: -+ -+ 1. Extra certificates are added via SSL_CTX_add_extra_chain_cert(). -+ -+ 2. The mode flag SSL_MODE_NO_AUTO_CHAIN is set. -+ -+ The reasoning behind this is that an application would not want the -+ auto chain building to take place if extra chain certificates are -+ present and it might also want a means of sending no additional -+ certificates (for example the chain has two certificates and the -+ root is omitted). -+ [Steve Henson] -+ -+ *) Add the possibility to build without the ENGINE framework. -+ [Steven Reddie via Richard Levitte] -+ -+ *) Under Win32 gmtime() can return NULL: check return value in -+ OPENSSL_gmtime(). Add error code for case where gmtime() fails. -+ [Steve Henson] -+ -+ *) DSA routines: under certain error conditions uninitialized BN objects -+ could be freed. Solution: make sure initialization is performed early -+ enough. (Reported and fix supplied by Ivan D Nestlerode , -+ Nils Larsch via PR#459) -+ [Lutz Jaenicke] -+ -+ *) Another fix for SSLv2 session ID handling: the session ID was incorrectly -+ checked on reconnect on the client side, therefore session resumption -+ could still fail with a "ssl session id is different" error. This -+ behaviour is masked when SSL_OP_ALL is used due to -+ SSL_OP_MICROSOFT_SESS_ID_BUG being set. -+ Behaviour observed by Crispin Flowerday as -+ followup to PR #377. -+ [Lutz Jaenicke] -+ -+ *) IA-32 assembler support enhancements: unified ELF targets, support -+ for SCO/Caldera platforms, fix for Cygwin shared build. -+ [Andy Polyakov] -+ -+ *) Add support for FreeBSD on sparc64. As a consequence, support for -+ FreeBSD on non-x86 processors is separate from x86 processors on -+ the config script, much like the NetBSD support. -+ [Richard Levitte & Kris Kennaway ] -+ -+ Changes between 0.9.6h and 0.9.7 [31 Dec 2002] -+ -+ [NB: OpenSSL 0.9.6i and later 0.9.6 patch levels were released after -+ OpenSSL 0.9.7.] -+ -+ *) Fix session ID handling in SSLv2 client code: the SERVER FINISHED -+ code (06) was taken as the first octet of the session ID and the last -+ octet was ignored consequently. As a result SSLv2 client side session -+ caching could not have worked due to the session ID mismatch between -+ client and server. -+ Behaviour observed by Crispin Flowerday as -+ PR #377. -+ [Lutz Jaenicke] -+ -+ *) Change the declaration of needed Kerberos libraries to use EX_LIBS -+ instead of the special (and badly supported) LIBKRB5. LIBKRB5 is -+ removed entirely. -+ [Richard Levitte] -+ -+ *) The hw_ncipher.c engine requires dynamic locks. Unfortunately, it -+ seems that in spite of existing for more than a year, many application -+ author have done nothing to provide the necessary callbacks, which -+ means that this particular engine will not work properly anywhere. -+ This is a very unfortunate situation which forces us, in the name -+ of usability, to give the hw_ncipher.c a static lock, which is part -+ of libcrypto. -+ NOTE: This is for the 0.9.7 series ONLY. This hack will never -+ appear in 0.9.8 or later. We EXPECT application authors to have -+ dealt properly with this when 0.9.8 is released (unless we actually -+ make such changes in the libcrypto locking code that changes will -+ have to be made anyway). -+ [Richard Levitte] -+ -+ *) In asn1_d2i_read_bio() repeatedly call BIO_read() until all content -+ octets have been read, EOF or an error occurs. Without this change -+ some truncated ASN1 structures will not produce an error. -+ [Steve Henson] -+ -+ *) Disable Heimdal support, since it hasn't been fully implemented. -+ Still give the possibility to force the use of Heimdal, but with -+ warnings and a request that patches get sent to openssl-dev. -+ [Richard Levitte] -+ -+ *) Add the VC-CE target, introduce the WINCE sysname, and add -+ INSTALL.WCE and appropriate conditionals to make it build. -+ [Steven Reddie via Richard Levitte] -+ -+ *) Change the DLL names for Cygwin to cygcrypto-x.y.z.dll and -+ cygssl-x.y.z.dll, where x, y and z are the major, minor and -+ edit numbers of the version. -+ [Corinna Vinschen and Richard Levitte] -+ -+ *) Introduce safe string copy and catenation functions -+ (BUF_strlcpy() and BUF_strlcat()). -+ [Ben Laurie (CHATS) and Richard Levitte] -+ -+ *) Avoid using fixed-size buffers for one-line DNs. -+ [Ben Laurie (CHATS)] -+ -+ *) Add BUF_MEM_grow_clean() to avoid information leakage when -+ resizing buffers containing secrets, and use where appropriate. -+ [Ben Laurie (CHATS)] -+ -+ *) Avoid using fixed size buffers for configuration file location. -+ [Ben Laurie (CHATS)] -+ -+ *) Avoid filename truncation for various CA files. -+ [Ben Laurie (CHATS)] -+ -+ *) Use sizeof in preference to magic numbers. -+ [Ben Laurie (CHATS)] -+ -+ *) Avoid filename truncation in cert requests. -+ [Ben Laurie (CHATS)] -+ -+ *) Add assertions to check for (supposedly impossible) buffer -+ overflows. -+ [Ben Laurie (CHATS)] -+ -+ *) Don't cache truncated DNS entries in the local cache (this could -+ potentially lead to a spoofing attack). -+ [Ben Laurie (CHATS)] -+ -+ *) Fix various buffers to be large enough for hex/decimal -+ representations in a platform independent manner. -+ [Ben Laurie (CHATS)] -+ -+ *) Add CRYPTO_realloc_clean() to avoid information leakage when -+ resizing buffers containing secrets, and use where appropriate. -+ [Ben Laurie (CHATS)] -+ -+ *) Add BIO_indent() to avoid much slightly worrying code to do -+ indents. -+ [Ben Laurie (CHATS)] -+ -+ *) Convert sprintf()/BIO_puts() to BIO_printf(). -+ [Ben Laurie (CHATS)] -+ -+ *) buffer_gets() could terminate with the buffer only half -+ full. Fixed. -+ [Ben Laurie (CHATS)] -+ -+ *) Add assertions to prevent user-supplied crypto functions from -+ overflowing internal buffers by having large block sizes, etc. -+ [Ben Laurie (CHATS)] -+ -+ *) New OPENSSL_assert() macro (similar to assert(), but enabled -+ unconditionally). -+ [Ben Laurie (CHATS)] -+ -+ *) Eliminate unused copy of key in RC4. -+ [Ben Laurie (CHATS)] -+ -+ *) Eliminate unused and incorrectly sized buffers for IV in pem.h. -+ [Ben Laurie (CHATS)] -+ -+ *) Fix off-by-one error in EGD path. -+ [Ben Laurie (CHATS)] -+ -+ *) If RANDFILE path is too long, ignore instead of truncating. -+ [Ben Laurie (CHATS)] -+ -+ *) Eliminate unused and incorrectly sized X.509 structure -+ CBCParameter. -+ [Ben Laurie (CHATS)] -+ -+ *) Eliminate unused and dangerous function knumber(). -+ [Ben Laurie (CHATS)] -+ -+ *) Eliminate unused and dangerous structure, KSSL_ERR. -+ [Ben Laurie (CHATS)] -+ -+ *) Protect against overlong session ID context length in an encoded -+ session object. Since these are local, this does not appear to be -+ exploitable. -+ [Ben Laurie (CHATS)] -+ -+ *) Change from security patch (see 0.9.6e below) that did not affect -+ the 0.9.6 release series: -+ -+ Remote buffer overflow in SSL3 protocol - an attacker could -+ supply an oversized master key in Kerberos-enabled versions. -+ (CVE-2002-0657) -+ [Ben Laurie (CHATS)] -+ -+ *) Change the SSL kerb5 codes to match RFC 2712. -+ [Richard Levitte] -+ -+ *) Make -nameopt work fully for req and add -reqopt switch. -+ [Michael Bell , Steve Henson] -+ -+ *) The "block size" for block ciphers in CFB and OFB mode should be 1. -+ [Steve Henson, reported by Yngve Nysaeter Pettersen ] -+ -+ *) Make sure tests can be performed even if the corresponding algorithms -+ have been removed entirely. This was also the last step to make -+ OpenSSL compilable with DJGPP under all reasonable conditions. -+ [Richard Levitte, Doug Kaufman ] -+ -+ *) Add cipher selection rules COMPLEMENTOFALL and COMPLEMENTOFDEFAULT -+ to allow version independent disabling of normally unselected ciphers, -+ which may be activated as a side-effect of selecting a single cipher. -+ -+ (E.g., cipher list string "RSA" enables ciphersuites that are left -+ out of "ALL" because they do not provide symmetric encryption. -+ "RSA:!COMPLEMEMENTOFALL" avoids these unsafe ciphersuites.) -+ [Lutz Jaenicke, Bodo Moeller] -+ -+ *) Add appropriate support for separate platform-dependent build -+ directories. The recommended way to make a platform-dependent -+ build directory is the following (tested on Linux), maybe with -+ some local tweaks: -+ -+ # Place yourself outside of the OpenSSL source tree. In -+ # this example, the environment variable OPENSSL_SOURCE -+ # is assumed to contain the absolute OpenSSL source directory. -+ mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`" -+ cd objtree/"`uname -s`-`uname -r`-`uname -m`" -+ (cd $OPENSSL_SOURCE; find . -type f) | while read F; do -+ mkdir -p `dirname $F` -+ ln -s $OPENSSL_SOURCE/$F $F -+ done -+ -+ To be absolutely sure not to disturb the source tree, a "make clean" -+ is a good thing. If it isn't successful, don't worry about it, -+ it probably means the source directory is very clean. -+ [Richard Levitte] -+ -+ *) Make sure any ENGINE control commands make local copies of string -+ pointers passed to them whenever necessary. Otherwise it is possible -+ the caller may have overwritten (or deallocated) the original string -+ data when a later ENGINE operation tries to use the stored values. -+ [Götz Babin-Ebell ] -+ -+ *) Improve diagnostics in file reading and command-line digests. -+ [Ben Laurie aided and abetted by Solar Designer ] -+ -+ *) Add AES modes CFB and OFB to the object database. Correct an -+ error in AES-CFB decryption. -+ [Richard Levitte] -+ -+ *) Remove most calls to EVP_CIPHER_CTX_cleanup() in evp_enc.c, this -+ allows existing EVP_CIPHER_CTX structures to be reused after -+ calling EVP_*Final(). This behaviour is used by encryption -+ BIOs and some applications. This has the side effect that -+ applications must explicitly clean up cipher contexts with -+ EVP_CIPHER_CTX_cleanup() or they will leak memory. -+ [Steve Henson] -+ -+ *) Check the values of dna and dnb in bn_mul_recursive before calling -+ bn_mul_comba (a non zero value means the a or b arrays do not contain -+ n2 elements) and fallback to bn_mul_normal if either is not zero. -+ [Steve Henson] -+ -+ *) Fix escaping of non-ASCII characters when using the -subj option -+ of the "openssl req" command line tool. (Robert Joop ) -+ [Lutz Jaenicke] -+ -+ *) Make object definitions compliant to LDAP (RFC2256): SN is the short -+ form for "surname", serialNumber has no short form. -+ Use "mail" as the short name for "rfc822Mailbox" according to RFC2798; -+ therefore remove "mail" short name for "internet 7". -+ The OID for unique identifiers in X509 certificates is -+ x500UniqueIdentifier, not uniqueIdentifier. -+ Some more OID additions. (Michael Bell ) -+ [Lutz Jaenicke] -+ -+ *) Add an "init" command to the ENGINE config module and auto initialize -+ ENGINEs. Without any "init" command the ENGINE will be initialized -+ after all ctrl commands have been executed on it. If init=1 the -+ ENGINE is initailized at that point (ctrls before that point are run -+ on the uninitialized ENGINE and after on the initialized one). If -+ init=0 then the ENGINE will not be iniatialized at all. -+ [Steve Henson] -+ -+ *) Fix the 'app_verify_callback' interface so that the user-defined -+ argument is actually passed to the callback: In the -+ SSL_CTX_set_cert_verify_callback() prototype, the callback -+ declaration has been changed from -+ int (*cb)() -+ into -+ int (*cb)(X509_STORE_CTX *,void *); -+ in ssl_verify_cert_chain (ssl/ssl_cert.c), the call -+ i=s->ctx->app_verify_callback(&ctx) -+ has been changed into -+ i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg). -+ -+ To update applications using SSL_CTX_set_cert_verify_callback(), -+ a dummy argument can be added to their callback functions. -+ [D. K. Smetters ] -+ -+ *) Added the '4758cca' ENGINE to support IBM 4758 cards. -+ [Maurice Gittens , touchups by Geoff Thorpe] -+ -+ *) Add and OPENSSL_LOAD_CONF define which will cause -+ OpenSSL_add_all_algorithms() to load the openssl.cnf config file. -+ This allows older applications to transparently support certain -+ OpenSSL features: such as crypto acceleration and dynamic ENGINE loading. -+ Two new functions OPENSSL_add_all_algorithms_noconf() which will never -+ load the config file and OPENSSL_add_all_algorithms_conf() which will -+ always load it have also been added. -+ [Steve Henson] -+ -+ *) Add the OFB, CFB and CTR (all with 128 bit feedback) to AES. -+ Adjust NIDs and EVP layer. -+ [Stephen Sprunk and Richard Levitte] -+ -+ *) Config modules support in openssl utility. -+ -+ Most commands now load modules from the config file, -+ though in a few (such as version) this isn't done -+ because it couldn't be used for anything. -+ -+ In the case of ca and req the config file used is -+ the same as the utility itself: that is the -config -+ command line option can be used to specify an -+ alternative file. -+ [Steve Henson] -+ -+ *) Move default behaviour from OPENSSL_config(). If appname is NULL -+ use "openssl_conf" if filename is NULL use default openssl config file. -+ [Steve Henson] -+ -+ *) Add an argument to OPENSSL_config() to allow the use of an alternative -+ config section name. Add a new flag to tolerate a missing config file -+ and move code to CONF_modules_load_file(). -+ [Steve Henson] -+ -+ *) Support for crypto accelerator cards from Accelerated Encryption -+ Processing, www.aep.ie. (Use engine 'aep') -+ The support was copied from 0.9.6c [engine] and adapted/corrected -+ to work with the new engine framework. -+ [AEP Inc. and Richard Levitte] -+ -+ *) Support for SureWare crypto accelerator cards from Baltimore -+ Technologies. (Use engine 'sureware') -+ The support was copied from 0.9.6c [engine] and adapted -+ to work with the new engine framework. -+ [Richard Levitte] -+ -+ *) Have the CHIL engine fork-safe (as defined by nCipher) and actually -+ make the newer ENGINE framework commands for the CHIL engine work. -+ [Toomas Kiisk and Richard Levitte] -+ -+ *) Make it possible to produce shared libraries on ReliantUNIX. -+ [Robert Dahlem via Richard Levitte] -+ -+ *) Add the configuration target debug-linux-ppro. -+ Make 'openssl rsa' use the general key loading routines -+ implemented in apps.c, and make those routines able to -+ handle the key format FORMAT_NETSCAPE and the variant -+ FORMAT_IISSGC. -+ [Toomas Kiisk via Richard Levitte] -+ -+ *) Fix a crashbug and a logic bug in hwcrhk_load_pubkey(). -+ [Toomas Kiisk via Richard Levitte] -+ -+ *) Add -keyform to rsautl, and document -engine. -+ [Richard Levitte, inspired by Toomas Kiisk ] -+ -+ *) Change BIO_new_file (crypto/bio/bss_file.c) to use new -+ BIO_R_NO_SUCH_FILE error code rather than the generic -+ ERR_R_SYS_LIB error code if fopen() fails with ENOENT. -+ [Ben Laurie] -+ -+ *) Add new functions -+ ERR_peek_last_error -+ ERR_peek_last_error_line -+ ERR_peek_last_error_line_data. -+ These are similar to -+ ERR_peek_error -+ ERR_peek_error_line -+ ERR_peek_error_line_data, -+ but report on the latest error recorded rather than the first one -+ still in the error queue. -+ [Ben Laurie, Bodo Moeller] -+ -+ *) default_algorithms option in ENGINE config module. This allows things -+ like: -+ default_algorithms = ALL -+ default_algorithms = RSA, DSA, RAND, CIPHERS, DIGESTS -+ [Steve Henson] -+ -+ *) Preliminary ENGINE config module. -+ [Steve Henson] -+ -+ *) New experimental application configuration code. -+ [Steve Henson] -+ -+ *) Change the AES code to follow the same name structure as all other -+ symmetric ciphers, and behave the same way. Move everything to -+ the directory crypto/aes, thereby obsoleting crypto/rijndael. -+ [Stephen Sprunk and Richard Levitte] -+ -+ *) SECURITY: remove unsafe setjmp/signal interaction from ui_openssl.c. -+ [Ben Laurie and Theo de Raadt] -+ -+ *) Add option to output public keys in req command. -+ [Massimiliano Pala madwolf@openca.org] -+ -+ *) Use wNAFs in EC_POINTs_mul() for improved efficiency -+ (up to about 10% better than before for P-192 and P-224). -+ [Bodo Moeller] -+ -+ *) New functions/macros -+ -+ SSL_CTX_set_msg_callback(ctx, cb) -+ SSL_CTX_set_msg_callback_arg(ctx, arg) -+ SSL_set_msg_callback(ssl, cb) -+ SSL_set_msg_callback_arg(ssl, arg) -+ -+ to request calling a callback function -+ -+ void cb(int write_p, int version, int content_type, -+ const void *buf, size_t len, SSL *ssl, void *arg) -+ -+ whenever a protocol message has been completely received -+ (write_p == 0) or sent (write_p == 1). Here 'version' is the -+ protocol version according to which the SSL library interprets -+ the current protocol message (SSL2_VERSION, SSL3_VERSION, or -+ TLS1_VERSION). 'content_type' is 0 in the case of SSL 2.0, or -+ the content type as defined in the SSL 3.0/TLS 1.0 protocol -+ specification (change_cipher_spec(20), alert(21), handshake(22)). -+ 'buf' and 'len' point to the actual message, 'ssl' to the -+ SSL object, and 'arg' is the application-defined value set by -+ SSL[_CTX]_set_msg_callback_arg(). -+ -+ 'openssl s_client' and 'openssl s_server' have new '-msg' options -+ to enable a callback that displays all protocol messages. -+ [Bodo Moeller] -+ -+ *) Change the shared library support so shared libraries are built as -+ soon as the corresponding static library is finished, and thereby get -+ openssl and the test programs linked against the shared library. -+ This still only happens when the keyword "shard" has been given to -+ the configuration scripts. -+ -+ NOTE: shared library support is still an experimental thing, and -+ backward binary compatibility is still not guaranteed. -+ ["Maciej W. Rozycki" and Richard Levitte] -+ -+ *) Add support for Subject Information Access extension. -+ [Peter Sylvester ] -+ -+ *) Make BUF_MEM_grow() behaviour more consistent: Initialise to zero -+ additional bytes when new memory had to be allocated, not just -+ when reusing an existing buffer. -+ [Bodo Moeller] -+ -+ *) New command line and configuration option 'utf8' for the req command. -+ This allows field values to be specified as UTF8 strings. -+ [Steve Henson] -+ -+ *) Add -multi and -mr options to "openssl speed" - giving multiple parallel -+ runs for the former and machine-readable output for the latter. -+ [Ben Laurie] -+ -+ *) Add '-noemailDN' option to 'openssl ca'. This prevents inclusion -+ of the e-mail address in the DN (i.e., it will go into a certificate -+ extension only). The new configuration file option 'email_in_dn = no' -+ has the same effect. -+ [Massimiliano Pala madwolf@openca.org] -+ -+ *) Change all functions with names starting with des_ to be starting -+ with DES_ instead. Add wrappers that are compatible with libdes, -+ but are named _ossl_old_des_*. Finally, add macros that map the -+ des_* symbols to the corresponding _ossl_old_des_* if libdes -+ compatibility is desired. If OpenSSL 0.9.6c compatibility is -+ desired, the des_* symbols will be mapped to DES_*, with one -+ exception. -+ -+ Since we provide two compatibility mappings, the user needs to -+ define the macro OPENSSL_DES_LIBDES_COMPATIBILITY if libdes -+ compatibility is desired. The default (i.e., when that macro -+ isn't defined) is OpenSSL 0.9.6c compatibility. -+ -+ There are also macros that enable and disable the support of old -+ des functions altogether. Those are OPENSSL_ENABLE_OLD_DES_SUPPORT -+ and OPENSSL_DISABLE_OLD_DES_SUPPORT. If none or both of those -+ are defined, the default will apply: to support the old des routines. -+ -+ In either case, one must include openssl/des.h to get the correct -+ definitions. Do not try to just include openssl/des_old.h, that -+ won't work. -+ -+ NOTE: This is a major break of an old API into a new one. Software -+ authors are encouraged to switch to the DES_ style functions. Some -+ time in the future, des_old.h and the libdes compatibility functions -+ will be disable (i.e. OPENSSL_DISABLE_OLD_DES_SUPPORT will be the -+ default), and then completely removed. -+ [Richard Levitte] -+ -+ *) Test for certificates which contain unsupported critical extensions. -+ If such a certificate is found during a verify operation it is -+ rejected by default: this behaviour can be overridden by either -+ handling the new error X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION or -+ by setting the verify flag X509_V_FLAG_IGNORE_CRITICAL. A new function -+ X509_supported_extension() has also been added which returns 1 if a -+ particular extension is supported. -+ [Steve Henson] -+ -+ *) Modify the behaviour of EVP cipher functions in similar way to digests -+ to retain compatibility with existing code. -+ [Steve Henson] -+ -+ *) Modify the behaviour of EVP_DigestInit() and EVP_DigestFinal() to retain -+ compatibility with existing code. In particular the 'ctx' parameter does -+ not have to be to be initialized before the call to EVP_DigestInit() and -+ it is tidied up after a call to EVP_DigestFinal(). New function -+ EVP_DigestFinal_ex() which does not tidy up the ctx. Similarly function -+ EVP_MD_CTX_copy() changed to not require the destination to be -+ initialized valid and new function EVP_MD_CTX_copy_ex() added which -+ requires the destination to be valid. -+ -+ Modify all the OpenSSL digest calls to use EVP_DigestInit_ex(), -+ EVP_DigestFinal_ex() and EVP_MD_CTX_copy_ex(). -+ [Steve Henson] -+ -+ *) Change ssl3_get_message (ssl/s3_both.c) and the functions using it -+ so that complete 'Handshake' protocol structures are kept in memory -+ instead of overwriting 'msg_type' and 'length' with 'body' data. -+ [Bodo Moeller] -+ -+ *) Add an implementation of SSL_add_dir_cert_subjects_to_stack for Win32. -+ [Massimo Santin via Richard Levitte] -+ -+ *) Major restructuring to the underlying ENGINE code. This includes -+ reduction of linker bloat, separation of pure "ENGINE" manipulation -+ (initialisation, etc) from functionality dealing with implementations -+ of specific crypto iterfaces. This change also introduces integrated -+ support for symmetric ciphers and digest implementations - so ENGINEs -+ can now accelerate these by providing EVP_CIPHER and EVP_MD -+ implementations of their own. This is detailed in crypto/engine/README -+ as it couldn't be adequately described here. However, there are a few -+ API changes worth noting - some RSA, DSA, DH, and RAND functions that -+ were changed in the original introduction of ENGINE code have now -+ reverted back - the hooking from this code to ENGINE is now a good -+ deal more passive and at run-time, operations deal directly with -+ RSA_METHODs, DSA_METHODs (etc) as they did before, rather than -+ dereferencing through an ENGINE pointer any more. Also, the ENGINE -+ functions dealing with BN_MOD_EXP[_CRT] handlers have been removed - -+ they were not being used by the framework as there is no concept of a -+ BIGNUM_METHOD and they could not be generalised to the new -+ 'ENGINE_TABLE' mechanism that underlies the new code. Similarly, -+ ENGINE_cpy() has been removed as it cannot be consistently defined in -+ the new code. -+ [Geoff Thorpe] -+ -+ *) Change ASN1_GENERALIZEDTIME_check() to allow fractional seconds. -+ [Steve Henson] -+ -+ *) Change mkdef.pl to sort symbols that get the same entry number, -+ and make sure the automatically generated functions ERR_load_* -+ become part of libeay.num as well. -+ [Richard Levitte] -+ -+ *) New function SSL_renegotiate_pending(). This returns true once -+ renegotiation has been requested (either SSL_renegotiate() call -+ or HelloRequest/ClientHello received from the peer) and becomes -+ false once a handshake has been completed. -+ (For servers, SSL_renegotiate() followed by SSL_do_handshake() -+ sends a HelloRequest, but does not ensure that a handshake takes -+ place. SSL_renegotiate_pending() is useful for checking if the -+ client has followed the request.) -+ [Bodo Moeller] -+ -+ *) New SSL option SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION. -+ By default, clients may request session resumption even during -+ renegotiation (if session ID contexts permit); with this option, -+ session resumption is possible only in the first handshake. -+ -+ SSL_OP_ALL is now 0x00000FFFL instead of 0x000FFFFFL. This makes -+ more bits available for options that should not be part of -+ SSL_OP_ALL (such as SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION). -+ [Bodo Moeller] -+ -+ *) Add some demos for certificate and certificate request creation. -+ [Steve Henson] -+ -+ *) Make maximum certificate chain size accepted from the peer application -+ settable (SSL*_get/set_max_cert_list()), as proposed by -+ "Douglas E. Engert" . -+ [Lutz Jaenicke] -+ -+ *) Add support for shared libraries for Unixware-7 -+ (Boyd Lynn Gerber ). -+ [Lutz Jaenicke] -+ -+ *) Add a "destroy" handler to ENGINEs that allows structural cleanup to -+ be done prior to destruction. Use this to unload error strings from -+ ENGINEs that load their own error strings. NB: This adds two new API -+ functions to "get" and "set" this destroy handler in an ENGINE. -+ [Geoff Thorpe] -+ -+ *) Alter all existing ENGINE implementations (except "openssl" and -+ "openbsd") to dynamically instantiate their own error strings. This -+ makes them more flexible to be built both as statically-linked ENGINEs -+ and self-contained shared-libraries loadable via the "dynamic" ENGINE. -+ Also, add stub code to each that makes building them as self-contained -+ shared-libraries easier (see README.ENGINE). -+ [Geoff Thorpe] -+ -+ *) Add a "dynamic" ENGINE that provides a mechanism for binding ENGINE -+ implementations into applications that are completely implemented in -+ self-contained shared-libraries. The "dynamic" ENGINE exposes control -+ commands that can be used to configure what shared-library to load and -+ to control aspects of the way it is handled. Also, made an update to -+ the README.ENGINE file that brings its information up-to-date and -+ provides some information and instructions on the "dynamic" ENGINE -+ (ie. how to use it, how to build "dynamic"-loadable ENGINEs, etc). -+ [Geoff Thorpe] -+ -+ *) Make it possible to unload ranges of ERR strings with a new -+ "ERR_unload_strings" function. -+ [Geoff Thorpe] -+ -+ *) Add a copy() function to EVP_MD. -+ [Ben Laurie] -+ -+ *) Make EVP_MD routines take a context pointer instead of just the -+ md_data void pointer. -+ [Ben Laurie] -+ -+ *) Add flags to EVP_MD and EVP_MD_CTX. EVP_MD_FLAG_ONESHOT indicates -+ that the digest can only process a single chunk of data -+ (typically because it is provided by a piece of -+ hardware). EVP_MD_CTX_FLAG_ONESHOT indicates that the application -+ is only going to provide a single chunk of data, and hence the -+ framework needn't accumulate the data for oneshot drivers. -+ [Ben Laurie] -+ -+ *) As with "ERR", make it possible to replace the underlying "ex_data" -+ functions. This change also alters the storage and management of global -+ ex_data state - it's now all inside ex_data.c and all "class" code (eg. -+ RSA, BIO, SSL_CTX, etc) no longer stores its own STACKS and per-class -+ index counters. The API functions that use this state have been changed -+ to take a "class_index" rather than pointers to the class's local STACK -+ and counter, and there is now an API function to dynamically create new -+ classes. This centralisation allows us to (a) plug a lot of the -+ thread-safety problems that existed, and (b) makes it possible to clean -+ up all allocated state using "CRYPTO_cleanup_all_ex_data()". W.r.t. (b) -+ such data would previously have always leaked in application code and -+ workarounds were in place to make the memory debugging turn a blind eye -+ to it. Application code that doesn't use this new function will still -+ leak as before, but their memory debugging output will announce it now -+ rather than letting it slide. -+ -+ Besides the addition of CRYPTO_cleanup_all_ex_data(), another API change -+ induced by the "ex_data" overhaul is that X509_STORE_CTX_init() now -+ has a return value to indicate success or failure. -+ [Geoff Thorpe] -+ -+ *) Make it possible to replace the underlying "ERR" functions such that the -+ global state (2 LHASH tables and 2 locks) is only used by the "default" -+ implementation. This change also adds two functions to "get" and "set" -+ the implementation prior to it being automatically set the first time -+ any other ERR function takes place. Ie. an application can call "get", -+ pass the return value to a module it has just loaded, and that module -+ can call its own "set" function using that value. This means the -+ module's "ERR" operations will use (and modify) the error state in the -+ application and not in its own statically linked copy of OpenSSL code. -+ [Geoff Thorpe] -+ -+ *) Give DH, DSA, and RSA types their own "**_up_ref()" function to increment -+ reference counts. This performs normal REF_PRINT/REF_CHECK macros on -+ the operation, and provides a more encapsulated way for external code -+ (crypto/evp/ and ssl/) to do this. Also changed the evp and ssl code -+ to use these functions rather than manually incrementing the counts. -+ -+ Also rename "DSO_up()" function to more descriptive "DSO_up_ref()". -+ [Geoff Thorpe] -+ -+ *) Add EVP test program. -+ [Ben Laurie] -+ -+ *) Add symmetric cipher support to ENGINE. Expect the API to change! -+ [Ben Laurie] -+ -+ *) New CRL functions: X509_CRL_set_version(), X509_CRL_set_issuer_name() -+ X509_CRL_set_lastUpdate(), X509_CRL_set_nextUpdate(), X509_CRL_sort(), -+ X509_REVOKED_set_serialNumber(), and X509_REVOKED_set_revocationDate(). -+ These allow a CRL to be built without having to access X509_CRL fields -+ directly. Modify 'ca' application to use new functions. -+ [Steve Henson] -+ -+ *) Move SSL_OP_TLS_ROLLBACK_BUG out of the SSL_OP_ALL list of recommended -+ bug workarounds. Rollback attack detection is a security feature. -+ The problem will only arise on OpenSSL servers when TLSv1 is not -+ available (sslv3_server_method() or SSL_OP_NO_TLSv1). -+ Software authors not wanting to support TLSv1 will have special reasons -+ for their choice and can explicitly enable this option. -+ [Bodo Moeller, Lutz Jaenicke] -+ -+ *) Rationalise EVP so it can be extended: don't include a union of -+ cipher/digest structures, add init/cleanup functions for EVP_MD_CTX -+ (similar to those existing for EVP_CIPHER_CTX). -+ Usage example: -+ -+ EVP_MD_CTX md; -+ -+ EVP_MD_CTX_init(&md); /* new function call */ -+ EVP_DigestInit(&md, EVP_sha1()); -+ EVP_DigestUpdate(&md, in, len); -+ EVP_DigestFinal(&md, out, NULL); -+ EVP_MD_CTX_cleanup(&md); /* new function call */ -+ -+ [Ben Laurie] -+ -+ *) Make DES key schedule conform to the usual scheme, as well as -+ correcting its structure. This means that calls to DES functions -+ now have to pass a pointer to a des_key_schedule instead of a -+ plain des_key_schedule (which was actually always a pointer -+ anyway): E.g., -+ -+ des_key_schedule ks; -+ -+ des_set_key_checked(..., &ks); -+ des_ncbc_encrypt(..., &ks, ...); -+ -+ (Note that a later change renames 'des_...' into 'DES_...'.) -+ [Ben Laurie] -+ -+ *) Initial reduction of linker bloat: the use of some functions, such as -+ PEM causes large amounts of unused functions to be linked in due to -+ poor organisation. For example pem_all.c contains every PEM function -+ which has a knock on effect of linking in large amounts of (unused) -+ ASN1 code. Grouping together similar functions and splitting unrelated -+ functions prevents this. -+ [Steve Henson] -+ -+ *) Cleanup of EVP macros. -+ [Ben Laurie] -+ -+ *) Change historical references to {NID,SN,LN}_des_ede and ede3 to add the -+ correct _ecb suffix. -+ [Ben Laurie] -+ -+ *) Add initial OCSP responder support to ocsp application. The -+ revocation information is handled using the text based index -+ use by the ca application. The responder can either handle -+ requests generated internally, supplied in files (for example -+ via a CGI script) or using an internal minimal server. -+ [Steve Henson] -+ -+ *) Add configuration choices to get zlib compression for TLS. -+ [Richard Levitte] -+ -+ *) Changes to Kerberos SSL for RFC 2712 compliance: -+ 1. Implemented real KerberosWrapper, instead of just using -+ KRB5 AP_REQ message. [Thanks to Simon Wilkinson ] -+ 2. Implemented optional authenticator field of KerberosWrapper. -+ -+ Added openssl-style ASN.1 macros for Kerberos ticket, ap_req, -+ and authenticator structs; see crypto/krb5/. -+ -+ Generalized Kerberos calls to support multiple Kerberos libraries. -+ [Vern Staats , -+ Jeffrey Altman -+ via Richard Levitte] -+ -+ *) Cause 'openssl speed' to use fully hard-coded DSA keys as it -+ already does with RSA. testdsa.h now has 'priv_key/pub_key' -+ values for each of the key sizes rather than having just -+ parameters (and 'speed' generating keys each time). -+ [Geoff Thorpe] -+ -+ *) Speed up EVP routines. -+ Before: -+encrypt -+type 8 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes -+des-cbc 4408.85k 5560.51k 5778.46k 5862.20k 5825.16k -+des-cbc 4389.55k 5571.17k 5792.23k 5846.91k 5832.11k -+des-cbc 4394.32k 5575.92k 5807.44k 5848.37k 5841.30k -+decrypt -+des-cbc 3482.66k 5069.49k 5496.39k 5614.16k 5639.28k -+des-cbc 3480.74k 5068.76k 5510.34k 5609.87k 5635.52k -+des-cbc 3483.72k 5067.62k 5504.60k 5708.01k 5724.80k -+ After: -+encrypt -+des-cbc 4660.16k 5650.19k 5807.19k 5827.13k 5783.32k -+decrypt -+des-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k -+ [Ben Laurie] -+ -+ *) Added the OS2-EMX target. -+ ["Brian Havard" and Richard Levitte] -+ -+ *) Rewrite apps to use NCONF routines instead of the old CONF. New functions -+ to support NCONF routines in extension code. New function CONF_set_nconf() -+ to allow functions which take an NCONF to also handle the old LHASH -+ structure: this means that the old CONF compatible routines can be -+ retained (in particular wrt extensions) without having to duplicate the -+ code. New function X509V3_add_ext_nconf_sk to add extensions to a stack. -+ [Steve Henson] -+ -+ *) Enhance the general user interface with mechanisms for inner control -+ and with possibilities to have yes/no kind of prompts. -+ [Richard Levitte] -+ -+ *) Change all calls to low level digest routines in the library and -+ applications to use EVP. Add missing calls to HMAC_cleanup() and -+ don't assume HMAC_CTX can be copied using memcpy(). -+ [Verdon Walker , Steve Henson] -+ -+ *) Add the possibility to control engines through control names but with -+ arbitrary arguments instead of just a string. -+ Change the key loaders to take a UI_METHOD instead of a callback -+ function pointer. NOTE: this breaks binary compatibility with earlier -+ versions of OpenSSL [engine]. -+ Adapt the nCipher code for these new conditions and add a card insertion -+ callback. -+ [Richard Levitte] -+ -+ *) Enhance the general user interface with mechanisms to better support -+ dialog box interfaces, application-defined prompts, the possibility -+ to use defaults (for example default passwords from somewhere else) -+ and interrupts/cancellations. -+ [Richard Levitte] -+ -+ *) Tidy up PKCS#12 attribute handling. Add support for the CSP name -+ attribute in PKCS#12 files, add new -CSP option to pkcs12 utility. -+ [Steve Henson] -+ -+ *) Fix a memory leak in 'sk_dup()' in the case reallocation fails. (Also -+ tidy up some unnecessarily weird code in 'sk_new()'). -+ [Geoff, reported by Diego Tartara ] -+ -+ *) Change the key loading routines for ENGINEs to use the same kind -+ callback (pem_password_cb) as all other routines that need this -+ kind of callback. -+ [Richard Levitte] -+ -+ *) Increase ENTROPY_NEEDED to 32 bytes, as Rijndael can operate with -+ 256 bit (=32 byte) keys. Of course seeding with more entropy bytes -+ than this minimum value is recommended. -+ [Lutz Jaenicke] -+ -+ *) New random seeder for OpenVMS, using the system process statistics -+ that are easily reachable. -+ [Richard Levitte] -+ -+ *) Windows apparently can't transparently handle global -+ variables defined in DLLs. Initialisations such as: -+ -+ const ASN1_ITEM *it = &ASN1_INTEGER_it; -+ -+ won't compile. This is used by the any applications that need to -+ declare their own ASN1 modules. This was fixed by adding the option -+ EXPORT_VAR_AS_FN to all Win32 platforms, although this isn't strictly -+ needed for static libraries under Win32. -+ [Steve Henson] -+ -+ *) New functions X509_PURPOSE_set() and X509_TRUST_set() to handle -+ setting of purpose and trust fields. New X509_STORE trust and -+ purpose functions and tidy up setting in other SSL functions. -+ [Steve Henson] -+ -+ *) Add copies of X509_STORE_CTX fields and callbacks to X509_STORE -+ structure. These are inherited by X509_STORE_CTX when it is -+ initialised. This allows various defaults to be set in the -+ X509_STORE structure (such as flags for CRL checking and custom -+ purpose or trust settings) for functions which only use X509_STORE_CTX -+ internally such as S/MIME. -+ -+ Modify X509_STORE_CTX_purpose_inherit() so it only sets purposes and -+ trust settings if they are not set in X509_STORE. This allows X509_STORE -+ purposes and trust (in S/MIME for example) to override any set by default. -+ -+ Add command line options for CRL checking to smime, s_client and s_server -+ applications. -+ [Steve Henson] -+ -+ *) Initial CRL based revocation checking. If the CRL checking flag(s) -+ are set then the CRL is looked up in the X509_STORE structure and -+ its validity and signature checked, then if the certificate is found -+ in the CRL the verify fails with a revoked error. -+ -+ Various new CRL related callbacks added to X509_STORE_CTX structure. -+ -+ Command line options added to 'verify' application to support this. -+ -+ This needs some additional work, such as being able to handle multiple -+ CRLs with different times, extension based lookup (rather than just -+ by subject name) and ultimately more complete V2 CRL extension -+ handling. -+ [Steve Henson] -+ -+ *) Add a general user interface API (crypto/ui/). This is designed -+ to replace things like des_read_password and friends (backward -+ compatibility functions using this new API are provided). -+ The purpose is to remove prompting functions from the DES code -+ section as well as provide for prompting through dialog boxes in -+ a window system and the like. -+ [Richard Levitte] -+ -+ *) Add "ex_data" support to ENGINE so implementations can add state at a -+ per-structure level rather than having to store it globally. -+ [Geoff] -+ -+ *) Make it possible for ENGINE structures to be copied when retrieved by -+ ENGINE_by_id() if the ENGINE specifies a new flag: ENGINE_FLAGS_BY_ID_COPY. -+ This causes the "original" ENGINE structure to act like a template, -+ analogous to the RSA vs. RSA_METHOD type of separation. Because of this -+ operational state can be localised to each ENGINE structure, despite the -+ fact they all share the same "methods". New ENGINE structures returned in -+ this case have no functional references and the return value is the single -+ structural reference. This matches the single structural reference returned -+ by ENGINE_by_id() normally, when it is incremented on the pre-existing -+ ENGINE structure. -+ [Geoff] -+ -+ *) Fix ASN1 decoder when decoding type ANY and V_ASN1_OTHER: since this -+ needs to match any other type at all we need to manually clear the -+ tag cache. -+ [Steve Henson] -+ -+ *) Changes to the "openssl engine" utility to include; -+ - verbosity levels ('-v', '-vv', and '-vvv') that provide information -+ about an ENGINE's available control commands. -+ - executing control commands from command line arguments using the -+ '-pre' and '-post' switches. '-post' is only used if '-t' is -+ specified and the ENGINE is successfully initialised. The syntax for -+ the individual commands are colon-separated, for example; -+ openssl engine chil -pre FORK_CHECK:0 -pre SO_PATH:/lib/test.so -+ [Geoff] -+ -+ *) New dynamic control command support for ENGINEs. ENGINEs can now -+ declare their own commands (numbers), names (strings), descriptions, -+ and input types for run-time discovery by calling applications. A -+ subset of these commands are implicitly classed as "executable" -+ depending on their input type, and only these can be invoked through -+ the new string-based API function ENGINE_ctrl_cmd_string(). (Eg. this -+ can be based on user input, config files, etc). The distinction is -+ that "executable" commands cannot return anything other than a boolean -+ result and can only support numeric or string input, whereas some -+ discoverable commands may only be for direct use through -+ ENGINE_ctrl(), eg. supporting the exchange of binary data, function -+ pointers, or other custom uses. The "executable" commands are to -+ support parameterisations of ENGINE behaviour that can be -+ unambiguously defined by ENGINEs and used consistently across any -+ OpenSSL-based application. Commands have been added to all the -+ existing hardware-supporting ENGINEs, noticeably "SO_PATH" to allow -+ control over shared-library paths without source code alterations. -+ [Geoff] -+ -+ *) Changed all ENGINE implementations to dynamically allocate their -+ ENGINEs rather than declaring them statically. Apart from this being -+ necessary with the removal of the ENGINE_FLAGS_MALLOCED distinction, -+ this also allows the implementations to compile without using the -+ internal engine_int.h header. -+ [Geoff] -+ -+ *) Minor adjustment to "rand" code. RAND_get_rand_method() now returns a -+ 'const' value. Any code that should be able to modify a RAND_METHOD -+ should already have non-const pointers to it (ie. they should only -+ modify their own ones). -+ [Geoff] -+ -+ *) Made a variety of little tweaks to the ENGINE code. -+ - "atalla" and "ubsec" string definitions were moved from header files -+ to C code. "nuron" string definitions were placed in variables -+ rather than hard-coded - allowing parameterisation of these values -+ later on via ctrl() commands. -+ - Removed unused "#if 0"'d code. -+ - Fixed engine list iteration code so it uses ENGINE_free() to release -+ structural references. -+ - Constified the RAND_METHOD element of ENGINE structures. -+ - Constified various get/set functions as appropriate and added -+ missing functions (including a catch-all ENGINE_cpy that duplicates -+ all ENGINE values onto a new ENGINE except reference counts/state). -+ - Removed NULL parameter checks in get/set functions. Setting a method -+ or function to NULL is a way of cancelling out a previously set -+ value. Passing a NULL ENGINE parameter is just plain stupid anyway -+ and doesn't justify the extra error symbols and code. -+ - Deprecate the ENGINE_FLAGS_MALLOCED define and move the area for -+ flags from engine_int.h to engine.h. -+ - Changed prototypes for ENGINE handler functions (init(), finish(), -+ ctrl(), key-load functions, etc) to take an (ENGINE*) parameter. -+ [Geoff] -+ -+ *) Implement binary inversion algorithm for BN_mod_inverse in addition -+ to the algorithm using long division. The binary algorithm can be -+ used only if the modulus is odd. On 32-bit systems, it is faster -+ only for relatively small moduli (roughly 20-30% for 128-bit moduli, -+ roughly 5-15% for 256-bit moduli), so we use it only for moduli -+ up to 450 bits. In 64-bit environments, the binary algorithm -+ appears to be advantageous for much longer moduli; here we use it -+ for moduli up to 2048 bits. -+ [Bodo Moeller] -+ -+ *) Rewrite CHOICE field setting in ASN1_item_ex_d2i(). The old code -+ could not support the combine flag in choice fields. -+ [Steve Henson] -+ -+ *) Add a 'copy_extensions' option to the 'ca' utility. This copies -+ extensions from a certificate request to the certificate. -+ [Steve Henson] -+ -+ *) Allow multiple 'certopt' and 'nameopt' options to be separated -+ by commas. Add 'namopt' and 'certopt' options to the 'ca' config -+ file: this allows the display of the certificate about to be -+ signed to be customised, to allow certain fields to be included -+ or excluded and extension details. The old system didn't display -+ multicharacter strings properly, omitted fields not in the policy -+ and couldn't display additional details such as extensions. -+ [Steve Henson] -+ -+ *) Function EC_POINTs_mul for multiple scalar multiplication -+ of an arbitrary number of elliptic curve points -+ \sum scalars[i]*points[i], -+ optionally including the generator defined for the EC_GROUP: -+ scalar*generator + \sum scalars[i]*points[i]. -+ -+ EC_POINT_mul is a simple wrapper function for the typical case -+ that the point list has just one item (besides the optional -+ generator). -+ [Bodo Moeller] -+ -+ *) First EC_METHODs for curves over GF(p): -+ -+ EC_GFp_simple_method() uses the basic BN_mod_mul and BN_mod_sqr -+ operations and provides various method functions that can also -+ operate with faster implementations of modular arithmetic. -+ -+ EC_GFp_mont_method() reuses most functions that are part of -+ EC_GFp_simple_method, but uses Montgomery arithmetic. -+ -+ [Bodo Moeller; point addition and point doubling -+ implementation directly derived from source code provided by -+ Lenka Fibikova ] -+ -+ *) Framework for elliptic curves (crypto/ec/ec.h, crypto/ec/ec_lcl.h, -+ crypto/ec/ec_lib.c): -+ -+ Curves are EC_GROUP objects (with an optional group generator) -+ based on EC_METHODs that are built into the library. -+ -+ Points are EC_POINT objects based on EC_GROUP objects. -+ -+ Most of the framework would be able to handle curves over arbitrary -+ finite fields, but as there are no obvious types for fields other -+ than GF(p), some functions are limited to that for now. -+ [Bodo Moeller] -+ -+ *) Add the -HTTP option to s_server. It is similar to -WWW, but requires -+ that the file contains a complete HTTP response. -+ [Richard Levitte] -+ -+ *) Add the ec directory to mkdef.pl and mkfiles.pl. In mkdef.pl -+ change the def and num file printf format specifier from "%-40sXXX" -+ to "%-39s XXX". The latter will always guarantee a space after the -+ field while the former will cause them to run together if the field -+ is 40 of more characters long. -+ [Steve Henson] -+ -+ *) Constify the cipher and digest 'method' functions and structures -+ and modify related functions to take constant EVP_MD and EVP_CIPHER -+ pointers. -+ [Steve Henson] -+ -+ *) Hide BN_CTX structure details in bn_lcl.h instead of publishing them -+ in . Also further increase BN_CTX_NUM to 32. -+ [Bodo Moeller] -+ -+ *) Modify EVP_Digest*() routines so they now return values. Although the -+ internal software routines can never fail additional hardware versions -+ might. -+ [Steve Henson] -+ -+ *) Clean up crypto/err/err.h and change some error codes to avoid conflicts: -+ -+ Previously ERR_R_FATAL was too small and coincided with ERR_LIB_PKCS7 -+ (= ERR_R_PKCS7_LIB); it is now 64 instead of 32. -+ -+ ASN1 error codes -+ ERR_R_NESTED_ASN1_ERROR -+ ... -+ ERR_R_MISSING_ASN1_EOS -+ were 4 .. 9, conflicting with -+ ERR_LIB_RSA (= ERR_R_RSA_LIB) -+ ... -+ ERR_LIB_PEM (= ERR_R_PEM_LIB). -+ They are now 58 .. 63 (i.e., just below ERR_R_FATAL). -+ -+ Add new error code 'ERR_R_INTERNAL_ERROR'. -+ [Bodo Moeller] -+ -+ *) Don't overuse locks in crypto/err/err.c: For data retrieval, CRYPTO_r_lock -+ suffices. -+ [Bodo Moeller] -+ -+ *) New option '-subj arg' for 'openssl req' and 'openssl ca'. This -+ sets the subject name for a new request or supersedes the -+ subject name in a given request. Formats that can be parsed are -+ 'CN=Some Name, OU=myOU, C=IT' -+ and -+ 'CN=Some Name/OU=myOU/C=IT'. -+ -+ Add options '-batch' and '-verbose' to 'openssl req'. -+ [Massimiliano Pala ] -+ -+ *) Introduce the possibility to access global variables through -+ functions on platform were that's the best way to handle exporting -+ global variables in shared libraries. To enable this functionality, -+ one must configure with "EXPORT_VAR_AS_FN" or defined the C macro -+ "OPENSSL_EXPORT_VAR_AS_FUNCTION" in crypto/opensslconf.h (the latter -+ is normally done by Configure or something similar). -+ -+ To implement a global variable, use the macro OPENSSL_IMPLEMENT_GLOBAL -+ in the source file (foo.c) like this: -+ -+ OPENSSL_IMPLEMENT_GLOBAL(int,foo)=1; -+ OPENSSL_IMPLEMENT_GLOBAL(double,bar); -+ -+ To declare a global variable, use the macros OPENSSL_DECLARE_GLOBAL -+ and OPENSSL_GLOBAL_REF in the header file (foo.h) like this: -+ -+ OPENSSL_DECLARE_GLOBAL(int,foo); -+ #define foo OPENSSL_GLOBAL_REF(foo) -+ OPENSSL_DECLARE_GLOBAL(double,bar); -+ #define bar OPENSSL_GLOBAL_REF(bar) -+ -+ The #defines are very important, and therefore so is including the -+ header file everywhere where the defined globals are used. -+ -+ The macro OPENSSL_EXPORT_VAR_AS_FUNCTION also affects the definition -+ of ASN.1 items, but that structure is a bit different. -+ -+ The largest change is in util/mkdef.pl which has been enhanced with -+ better and easier to understand logic to choose which symbols should -+ go into the Windows .def files as well as a number of fixes and code -+ cleanup (among others, algorithm keywords are now sorted -+ lexicographically to avoid constant rewrites). -+ [Richard Levitte] -+ -+ *) In BN_div() keep a copy of the sign of 'num' before writing the -+ result to 'rm' because if rm==num the value will be overwritten -+ and produce the wrong result if 'num' is negative: this caused -+ problems with BN_mod() and BN_nnmod(). -+ [Steve Henson] -+ -+ *) Function OCSP_request_verify(). This checks the signature on an -+ OCSP request and verifies the signer certificate. The signer -+ certificate is just checked for a generic purpose and OCSP request -+ trust settings. -+ [Steve Henson] -+ -+ *) Add OCSP_check_validity() function to check the validity of OCSP -+ responses. OCSP responses are prepared in real time and may only -+ be a few seconds old. Simply checking that the current time lies -+ between thisUpdate and nextUpdate max reject otherwise valid responses -+ caused by either OCSP responder or client clock inaccuracy. Instead -+ we allow thisUpdate and nextUpdate to fall within a certain period of -+ the current time. The age of the response can also optionally be -+ checked. Two new options -validity_period and -status_age added to -+ ocsp utility. -+ [Steve Henson] -+ -+ *) If signature or public key algorithm is unrecognized print out its -+ OID rather that just UNKNOWN. -+ [Steve Henson] -+ -+ *) Change OCSP_cert_to_id() to tolerate a NULL subject certificate and -+ OCSP_cert_id_new() a NULL serialNumber. This allows a partial certificate -+ ID to be generated from the issuer certificate alone which can then be -+ passed to OCSP_id_issuer_cmp(). -+ [Steve Henson] -+ -+ *) New compilation option ASN1_ITEM_FUNCTIONS. This causes the new -+ ASN1 modules to export functions returning ASN1_ITEM pointers -+ instead of the ASN1_ITEM structures themselves. This adds several -+ new macros which allow the underlying ASN1 function/structure to -+ be accessed transparently. As a result code should not use ASN1_ITEM -+ references directly (such as &X509_it) but instead use the relevant -+ macros (such as ASN1_ITEM_rptr(X509)). This option is to allow -+ use of the new ASN1 code on platforms where exporting structures -+ is problematical (for example in shared libraries) but exporting -+ functions returning pointers to structures is not. -+ [Steve Henson] -+ -+ *) Add support for overriding the generation of SSL/TLS session IDs. -+ These callbacks can be registered either in an SSL_CTX or per SSL. -+ The purpose of this is to allow applications to control, if they wish, -+ the arbitrary values chosen for use as session IDs, particularly as it -+ can be useful for session caching in multiple-server environments. A -+ command-line switch for testing this (and any client code that wishes -+ to use such a feature) has been added to "s_server". -+ [Geoff Thorpe, Lutz Jaenicke] -+ -+ *) Modify mkdef.pl to recognise and parse preprocessor conditionals -+ of the form '#if defined(...) || defined(...) || ...' and -+ '#if !defined(...) && !defined(...) && ...'. This also avoids -+ the growing number of special cases it was previously handling. -+ [Richard Levitte] -+ -+ *) Make all configuration macros available for application by making -+ sure they are available in opensslconf.h, by giving them names starting -+ with "OPENSSL_" to avoid conflicts with other packages and by making -+ sure e_os2.h will cover all platform-specific cases together with -+ opensslconf.h. -+ Additionally, it is now possible to define configuration/platform- -+ specific names (called "system identities"). In the C code, these -+ are prefixed with "OPENSSL_SYSNAME_". e_os2.h will create another -+ macro with the name beginning with "OPENSSL_SYS_", which is determined -+ from "OPENSSL_SYSNAME_*" or compiler-specific macros depending on -+ what is available. -+ [Richard Levitte] -+ -+ *) New option -set_serial to 'req' and 'x509' this allows the serial -+ number to use to be specified on the command line. Previously self -+ signed certificates were hard coded with serial number 0 and the -+ CA options of 'x509' had to use a serial number in a file which was -+ auto incremented. -+ [Steve Henson] -+ -+ *) New options to 'ca' utility to support V2 CRL entry extensions. -+ Currently CRL reason, invalidity date and hold instruction are -+ supported. Add new CRL extensions to V3 code and some new objects. -+ [Steve Henson] -+ -+ *) New function EVP_CIPHER_CTX_set_padding() this is used to -+ disable standard block padding (aka PKCS#5 padding) in the EVP -+ API, which was previously mandatory. This means that the data is -+ not padded in any way and so the total length much be a multiple -+ of the block size, otherwise an error occurs. -+ [Steve Henson] -+ -+ *) Initial (incomplete) OCSP SSL support. -+ [Steve Henson] -+ -+ *) New function OCSP_parse_url(). This splits up a URL into its host, -+ port and path components: primarily to parse OCSP URLs. New -url -+ option to ocsp utility. -+ [Steve Henson] -+ -+ *) New nonce behavior. The return value of OCSP_check_nonce() now -+ reflects the various checks performed. Applications can decide -+ whether to tolerate certain situations such as an absent nonce -+ in a response when one was present in a request: the ocsp application -+ just prints out a warning. New function OCSP_add1_basic_nonce() -+ this is to allow responders to include a nonce in a response even if -+ the request is nonce-less. -+ [Steve Henson] -+ -+ *) Disable stdin buffering in load_cert (apps/apps.c) so that no certs are -+ skipped when using openssl x509 multiple times on a single input file, -+ e.g. "(openssl x509 -out cert1; openssl x509 -out cert2) ] -+ -+ *) New OCSP verify flag OCSP_TRUSTOTHER. When set the "other" certificates -+ passed by the function are trusted implicitly. If any of them signed the -+ response then it is assumed to be valid and is not verified. -+ [Steve Henson] -+ -+ *) In PKCS7_set_type() initialise content_type in PKCS7_ENC_CONTENT -+ to data. This was previously part of the PKCS7 ASN1 code. This -+ was causing problems with OpenSSL created PKCS#12 and PKCS#7 structures. -+ [Steve Henson, reported by Kenneth R. Robinette -+ ] -+ -+ *) Add CRYPTO_push_info() and CRYPTO_pop_info() calls to new ASN1 -+ routines: without these tracing memory leaks is very painful. -+ Fix leaks in PKCS12 and PKCS7 routines. -+ [Steve Henson] -+ -+ *) Make X509_time_adj() cope with the new behaviour of ASN1_TIME_new(). -+ Previously it initialised the 'type' argument to V_ASN1_UTCTIME which -+ effectively meant GeneralizedTime would never be used. Now it -+ is initialised to -1 but X509_time_adj() now has to check the value -+ and use ASN1_TIME_set() if the value is not V_ASN1_UTCTIME or -+ V_ASN1_GENERALIZEDTIME, without this it always uses GeneralizedTime. -+ [Steve Henson, reported by Kenneth R. Robinette -+ ] -+ -+ *) Fixes to BN_to_ASN1_INTEGER when bn is zero. This would previously -+ result in a zero length in the ASN1_INTEGER structure which was -+ not consistent with the structure when d2i_ASN1_INTEGER() was used -+ and would cause ASN1_INTEGER_cmp() to fail. Enhance s2i_ASN1_INTEGER() -+ to cope with hex and negative integers. Fix bug in i2a_ASN1_INTEGER() -+ where it did not print out a minus for negative ASN1_INTEGER. -+ [Steve Henson] -+ -+ *) Add summary printout to ocsp utility. The various functions which -+ convert status values to strings have been renamed to: -+ OCSP_response_status_str(), OCSP_cert_status_str() and -+ OCSP_crl_reason_str() and are no longer static. New options -+ to verify nonce values and to disable verification. OCSP response -+ printout format cleaned up. -+ [Steve Henson] -+ -+ *) Add additional OCSP certificate checks. These are those specified -+ in RFC2560. This consists of two separate checks: the CA of the -+ certificate being checked must either be the OCSP signer certificate -+ or the issuer of the OCSP signer certificate. In the latter case the -+ OCSP signer certificate must contain the OCSP signing extended key -+ usage. This check is performed by attempting to match the OCSP -+ signer or the OCSP signer CA to the issuerNameHash and issuerKeyHash -+ in the OCSP_CERTID structures of the response. -+ [Steve Henson] -+ -+ *) Initial OCSP certificate verification added to OCSP_basic_verify() -+ and related routines. This uses the standard OpenSSL certificate -+ verify routines to perform initial checks (just CA validity) and -+ to obtain the certificate chain. Then additional checks will be -+ performed on the chain. Currently the root CA is checked to see -+ if it is explicitly trusted for OCSP signing. This is used to set -+ a root CA as a global signing root: that is any certificate that -+ chains to that CA is an acceptable OCSP signing certificate. -+ [Steve Henson] -+ -+ *) New '-extfile ...' option to 'openssl ca' for reading X.509v3 -+ extensions from a separate configuration file. -+ As when reading extensions from the main configuration file, -+ the '-extensions ...' option may be used for specifying the -+ section to use. -+ [Massimiliano Pala ] -+ -+ *) New OCSP utility. Allows OCSP requests to be generated or -+ read. The request can be sent to a responder and the output -+ parsed, outputed or printed in text form. Not complete yet: -+ still needs to check the OCSP response validity. -+ [Steve Henson] -+ -+ *) New subcommands for 'openssl ca': -+ 'openssl ca -status ' prints the status of the cert with -+ the given serial number (according to the index file). -+ 'openssl ca -updatedb' updates the expiry status of certificates -+ in the index file. -+ [Massimiliano Pala ] -+ -+ *) New '-newreq-nodes' command option to CA.pl. This is like -+ '-newreq', but calls 'openssl req' with the '-nodes' option -+ so that the resulting key is not encrypted. -+ [Damien Miller ] -+ -+ *) New configuration for the GNU Hurd. -+ [Jonathan Bartlett via Richard Levitte] -+ -+ *) Initial code to implement OCSP basic response verify. This -+ is currently incomplete. Currently just finds the signer's -+ certificate and verifies the signature on the response. -+ [Steve Henson] -+ -+ *) New SSLeay_version code SSLEAY_DIR to determine the compiled-in -+ value of OPENSSLDIR. This is available via the new '-d' option -+ to 'openssl version', and is also included in 'openssl version -a'. -+ [Bodo Moeller] -+ -+ *) Allowing defining memory allocation callbacks that will be given -+ file name and line number information in additional arguments -+ (a const char* and an int). The basic functionality remains, as -+ well as the original possibility to just replace malloc(), -+ realloc() and free() by functions that do not know about these -+ additional arguments. To register and find out the current -+ settings for extended allocation functions, the following -+ functions are provided: -+ -+ CRYPTO_set_mem_ex_functions -+ CRYPTO_set_locked_mem_ex_functions -+ CRYPTO_get_mem_ex_functions -+ CRYPTO_get_locked_mem_ex_functions -+ -+ These work the same way as CRYPTO_set_mem_functions and friends. -+ CRYPTO_get_[locked_]mem_functions now writes 0 where such an -+ extended allocation function is enabled. -+ Similarly, CRYPTO_get_[locked_]mem_ex_functions writes 0 where -+ a conventional allocation function is enabled. -+ [Richard Levitte, Bodo Moeller] -+ -+ *) Finish off removing the remaining LHASH function pointer casts. -+ There should no longer be any prototype-casting required when using -+ the LHASH abstraction, and any casts that remain are "bugs". See -+ the callback types and macros at the head of lhash.h for details -+ (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example). -+ [Geoff Thorpe] -+ -+ *) Add automatic query of EGD sockets in RAND_poll() for the unix variant. -+ If /dev/[u]random devices are not available or do not return enough -+ entropy, EGD style sockets (served by EGD or PRNGD) will automatically -+ be queried. -+ The locations /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool, and -+ /etc/entropy will be queried once each in this sequence, querying stops -+ when enough entropy was collected without querying more sockets. -+ [Lutz Jaenicke] -+ -+ *) Change the Unix RAND_poll() variant to be able to poll several -+ random devices, as specified by DEVRANDOM, until a sufficient amount -+ of data has been collected. We spend at most 10 ms on each file -+ (select timeout) and read in non-blocking mode. DEVRANDOM now -+ defaults to the list "/dev/urandom", "/dev/random", "/dev/srandom" -+ (previously it was just the string "/dev/urandom"), so on typical -+ platforms the 10 ms delay will never occur. -+ Also separate out the Unix variant to its own file, rand_unix.c. -+ For VMS, there's a currently-empty rand_vms.c. -+ [Richard Levitte] -+ -+ *) Move OCSP client related routines to ocsp_cl.c. These -+ provide utility functions which an application needing -+ to issue a request to an OCSP responder and analyse the -+ response will typically need: as opposed to those which an -+ OCSP responder itself would need which will be added later. -+ -+ OCSP_request_sign() signs an OCSP request with an API similar -+ to PKCS7_sign(). OCSP_response_status() returns status of OCSP -+ response. OCSP_response_get1_basic() extracts basic response -+ from response. OCSP_resp_find_status(): finds and extracts status -+ information from an OCSP_CERTID structure (which will be created -+ when the request structure is built). These are built from lower -+ level functions which work on OCSP_SINGLERESP structures but -+ won't normally be used unless the application wishes to examine -+ extensions in the OCSP response for example. -+ -+ Replace nonce routines with a pair of functions. -+ OCSP_request_add1_nonce() adds a nonce value and optionally -+ generates a random value. OCSP_check_nonce() checks the -+ validity of the nonce in an OCSP response. -+ [Steve Henson] -+ -+ *) Change function OCSP_request_add() to OCSP_request_add0_id(). -+ This doesn't copy the supplied OCSP_CERTID and avoids the -+ need to free up the newly created id. Change return type -+ to OCSP_ONEREQ to return the internal OCSP_ONEREQ structure. -+ This can then be used to add extensions to the request. -+ Deleted OCSP_request_new(), since most of its functionality -+ is now in OCSP_REQUEST_new() (and the case insensitive name -+ clash) apart from the ability to set the request name which -+ will be added elsewhere. -+ [Steve Henson] -+ -+ *) Update OCSP API. Remove obsolete extensions argument from -+ various functions. Extensions are now handled using the new -+ OCSP extension code. New simple OCSP HTTP function which -+ can be used to send requests and parse the response. -+ [Steve Henson] -+ -+ *) Fix the PKCS#7 (S/MIME) code to work with new ASN1. Two new -+ ASN1_ITEM structures help with sign and verify. PKCS7_ATTR_SIGN -+ uses the special reorder version of SET OF to sort the attributes -+ and reorder them to match the encoded order. This resolves a long -+ standing problem: a verify on a PKCS7 structure just after signing -+ it used to fail because the attribute order did not match the -+ encoded order. PKCS7_ATTR_VERIFY does not reorder the attributes: -+ it uses the received order. This is necessary to tolerate some broken -+ software that does not order SET OF. This is handled by encoding -+ as a SEQUENCE OF but using implicit tagging (with UNIVERSAL class) -+ to produce the required SET OF. -+ [Steve Henson] -+ -+ *) Have mk1mf.pl generate the macros OPENSSL_BUILD_SHLIBCRYPTO and -+ OPENSSL_BUILD_SHLIBSSL and use them appropriately in the header -+ files to get correct declarations of the ASN.1 item variables. -+ [Richard Levitte] -+ -+ *) Rewrite of PKCS#12 code to use new ASN1 functionality. Replace many -+ PKCS#12 macros with real functions. Fix two unrelated ASN1 bugs: -+ asn1_check_tlen() would sometimes attempt to use 'ctx' when it was -+ NULL and ASN1_TYPE was not dereferenced properly in asn1_ex_c2i(). -+ New ASN1 macro: DECLARE_ASN1_ITEM() which just declares the relevant -+ ASN1_ITEM and no wrapper functions. -+ [Steve Henson] -+ -+ *) New functions or ASN1_item_d2i_fp() and ASN1_item_d2i_bio(). These -+ replace the old function pointer based I/O routines. Change most of -+ the *_d2i_bio() and *_d2i_fp() functions to use these. -+ [Steve Henson] -+ -+ *) Enhance mkdef.pl to be more accepting about spacing in C preprocessor -+ lines, recognice more "algorithms" that can be deselected, and make -+ it complain about algorithm deselection that isn't recognised. -+ [Richard Levitte] -+ -+ *) New ASN1 functions to handle dup, sign, verify, digest, pack and -+ unpack operations in terms of ASN1_ITEM. Modify existing wrappers -+ to use new functions. Add NO_ASN1_OLD which can be set to remove -+ some old style ASN1 functions: this can be used to determine if old -+ code will still work when these eventually go away. -+ [Steve Henson] -+ -+ *) New extension functions for OCSP structures, these follow the -+ same conventions as certificates and CRLs. -+ [Steve Henson] -+ -+ *) New function X509V3_add1_i2d(). This automatically encodes and -+ adds an extension. Its behaviour can be customised with various -+ flags to append, replace or delete. Various wrappers added for -+ certificates and CRLs. -+ [Steve Henson] -+ -+ *) Fix to avoid calling the underlying ASN1 print routine when -+ an extension cannot be parsed. Correct a typo in the -+ OCSP_SERVICELOC extension. Tidy up print OCSP format. -+ [Steve Henson] -+ -+ *) Make mkdef.pl parse some of the ASN1 macros and add appropriate -+ entries for variables. -+ [Steve Henson] -+ -+ *) Add functionality to apps/openssl.c for detecting locking -+ problems: As the program is single-threaded, all we have -+ to do is register a locking callback using an array for -+ storing which locks are currently held by the program. -+ [Bodo Moeller] -+ -+ *) Use a lock around the call to CRYPTO_get_ex_new_index() in -+ SSL_get_ex_data_X509_STORE_idx(), which is used in -+ ssl_verify_cert_chain() and thus can be called at any time -+ during TLS/SSL handshakes so that thread-safety is essential. -+ Unfortunately, the ex_data design is not at all suited -+ for multi-threaded use, so it probably should be abolished. -+ [Bodo Moeller] -+ -+ *) Added Broadcom "ubsec" ENGINE to OpenSSL. -+ [Broadcom, tweaked and integrated by Geoff Thorpe] -+ -+ *) Move common extension printing code to new function -+ X509V3_print_extensions(). Reorganise OCSP print routines and -+ implement some needed OCSP ASN1 functions. Add OCSP extensions. -+ [Steve Henson] -+ -+ *) New function X509_signature_print() to remove duplication in some -+ print routines. -+ [Steve Henson] -+ -+ *) Add a special meaning when SET OF and SEQUENCE OF flags are both -+ set (this was treated exactly the same as SET OF previously). This -+ is used to reorder the STACK representing the structure to match the -+ encoding. This will be used to get round a problem where a PKCS7 -+ structure which was signed could not be verified because the STACK -+ order did not reflect the encoded order. -+ [Steve Henson] -+ -+ *) Reimplement the OCSP ASN1 module using the new code. -+ [Steve Henson] -+ -+ *) Update the X509V3 code to permit the use of an ASN1_ITEM structure -+ for its ASN1 operations. The old style function pointers still exist -+ for now but they will eventually go away. -+ [Steve Henson] -+ -+ *) Merge in replacement ASN1 code from the ASN1 branch. This almost -+ completely replaces the old ASN1 functionality with a table driven -+ encoder and decoder which interprets an ASN1_ITEM structure describing -+ the ASN1 module. Compatibility with the existing ASN1 API (i2d,d2i) is -+ largely maintained. Almost all of the old asn1_mac.h macro based ASN1 -+ has also been converted to the new form. -+ [Steve Henson] -+ -+ *) Change BN_mod_exp_recp so that negative moduli are tolerated -+ (the sign is ignored). Similarly, ignore the sign in BN_MONT_CTX_set -+ so that BN_mod_exp_mont and BN_mod_exp_mont_word work -+ for negative moduli. -+ [Bodo Moeller] -+ -+ *) Fix BN_uadd and BN_usub: Always return non-negative results instead -+ of not touching the result's sign bit. -+ [Bodo Moeller] -+ -+ *) BN_div bugfix: If the result is 0, the sign (res->neg) must not be -+ set. -+ [Bodo Moeller] -+ -+ *) Changed the LHASH code to use prototypes for callbacks, and created -+ macros to declare and implement thin (optionally static) functions -+ that provide type-safety and avoid function pointer casting for the -+ type-specific callbacks. -+ [Geoff Thorpe] -+ -+ *) Added Kerberos Cipher Suites to be used with TLS, as written in -+ RFC 2712. -+ [Veers Staats , -+ Jeffrey Altman , via Richard Levitte] -+ -+ *) Reformat the FAQ so the different questions and answers can be divided -+ in sections depending on the subject. -+ [Richard Levitte] -+ -+ *) Have the zlib compression code load ZLIB.DLL dynamically under -+ Windows. -+ [Richard Levitte] -+ -+ *) New function BN_mod_sqrt for computing square roots modulo a prime -+ (using the probabilistic Tonelli-Shanks algorithm unless -+ p == 3 (mod 4) or p == 5 (mod 8), which are cases that can -+ be handled deterministically). -+ [Lenka Fibikova , Bodo Moeller] -+ -+ *) Make BN_mod_inverse faster by explicitly handling small quotients -+ in the Euclid loop. (Speed gain about 20% for small moduli [256 or -+ 512 bits], about 30% for larger ones [1024 or 2048 bits].) -+ [Bodo Moeller] -+ -+ *) New function BN_kronecker. -+ [Bodo Moeller] -+ -+ *) Fix BN_gcd so that it works on negative inputs; the result is -+ positive unless both parameters are zero. -+ Previously something reasonably close to an infinite loop was -+ possible because numbers could be growing instead of shrinking -+ in the implementation of Euclid's algorithm. -+ [Bodo Moeller] -+ -+ *) Fix BN_is_word() and BN_is_one() macros to take into account the -+ sign of the number in question. -+ -+ Fix BN_is_word(a,w) to work correctly for w == 0. -+ -+ The old BN_is_word(a,w) macro is now called BN_abs_is_word(a,w) -+ because its test if the absolute value of 'a' equals 'w'. -+ Note that BN_abs_is_word does *not* handle w == 0 reliably; -+ it exists mostly for use in the implementations of BN_is_zero(), -+ BN_is_one(), and BN_is_word(). -+ [Bodo Moeller] -+ -+ *) New function BN_swap. -+ [Bodo Moeller] -+ -+ *) Use BN_nnmod instead of BN_mod in crypto/bn/bn_exp.c so that -+ the exponentiation functions are more likely to produce reasonable -+ results on negative inputs. -+ [Bodo Moeller] -+ -+ *) Change BN_mod_mul so that the result is always non-negative. -+ Previously, it could be negative if one of the factors was negative; -+ I don't think anyone really wanted that behaviour. -+ [Bodo Moeller] -+ -+ *) Move BN_mod_... functions into new file crypto/bn/bn_mod.c -+ (except for exponentiation, which stays in crypto/bn/bn_exp.c, -+ and BN_mod_mul_reciprocal, which stays in crypto/bn/bn_recp.c) -+ and add new functions: -+ -+ BN_nnmod -+ BN_mod_sqr -+ BN_mod_add -+ BN_mod_add_quick -+ BN_mod_sub -+ BN_mod_sub_quick -+ BN_mod_lshift1 -+ BN_mod_lshift1_quick -+ BN_mod_lshift -+ BN_mod_lshift_quick -+ -+ These functions always generate non-negative results. -+ -+ BN_nnmod otherwise is like BN_mod (if BN_mod computes a remainder r -+ such that |m| < r < 0, BN_nnmod will output rem + |m| instead). -+ -+ BN_mod_XXX_quick(r, a, [b,] m) generates the same result as -+ BN_mod_XXX(r, a, [b,] m, ctx), but requires that a [and b] -+ be reduced modulo m. -+ [Lenka Fibikova , Bodo Moeller] -+ -+#if 0 -+ The following entry accidentally appeared in the CHANGES file -+ distributed with OpenSSL 0.9.7. The modifications described in -+ it do *not* apply to OpenSSL 0.9.7. -+ -+ *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there -+ was actually never needed) and in BN_mul(). The removal in BN_mul() -+ required a small change in bn_mul_part_recursive() and the addition -+ of the functions bn_cmp_part_words(), bn_sub_part_words() and -+ bn_add_part_words(), which do the same thing as bn_cmp_words(), -+ bn_sub_words() and bn_add_words() except they take arrays with -+ differing sizes. -+ [Richard Levitte] -+#endif -+ -+ *) In 'openssl passwd', verify passwords read from the terminal -+ unless the '-salt' option is used (which usually means that -+ verification would just waste user's time since the resulting -+ hash is going to be compared with some given password hash) -+ or the new '-noverify' option is used. -+ -+ This is an incompatible change, but it does not affect -+ non-interactive use of 'openssl passwd' (passwords on the command -+ line, '-stdin' option, '-in ...' option) and thus should not -+ cause any problems. -+ [Bodo Moeller] -+ -+ *) Remove all references to RSAref, since there's no more need for it. -+ [Richard Levitte] -+ -+ *) Make DSO load along a path given through an environment variable -+ (SHLIB_PATH) with shl_load(). -+ [Richard Levitte] -+ -+ *) Constify the ENGINE code as a result of BIGNUM constification. -+ Also constify the RSA code and most things related to it. In a -+ few places, most notable in the depth of the ASN.1 code, ugly -+ casts back to non-const were required (to be solved at a later -+ time) -+ [Richard Levitte] -+ -+ *) Make it so the openssl application has all engines loaded by default. -+ [Richard Levitte] -+ -+ *) Constify the BIGNUM routines a little more. -+ [Richard Levitte] -+ -+ *) Add the following functions: -+ -+ ENGINE_load_cswift() -+ ENGINE_load_chil() -+ ENGINE_load_atalla() -+ ENGINE_load_nuron() -+ ENGINE_load_builtin_engines() -+ -+ That way, an application can itself choose if external engines that -+ are built-in in OpenSSL shall ever be used or not. The benefit is -+ that applications won't have to be linked with libdl or other dso -+ libraries unless it's really needed. -+ -+ Changed 'openssl engine' to load all engines on demand. -+ Changed the engine header files to avoid the duplication of some -+ declarations (they differed!). -+ [Richard Levitte] -+ -+ *) 'openssl engine' can now list capabilities. -+ [Richard Levitte] -+ -+ *) Better error reporting in 'openssl engine'. -+ [Richard Levitte] -+ -+ *) Never call load_dh_param(NULL) in s_server. -+ [Bodo Moeller] -+ -+ *) Add engine application. It can currently list engines by name and -+ identity, and test if they are actually available. -+ [Richard Levitte] -+ -+ *) Improve RPM specification file by forcing symbolic linking and making -+ sure the installed documentation is also owned by root.root. -+ [Damien Miller ] -+ -+ *) Give the OpenSSL applications more possibilities to make use of -+ keys (public as well as private) handled by engines. -+ [Richard Levitte] -+ -+ *) Add OCSP code that comes from CertCo. -+ [Richard Levitte] -+ -+ *) Add VMS support for the Rijndael code. -+ [Richard Levitte] -+ -+ *) Added untested support for Nuron crypto accelerator. -+ [Ben Laurie] -+ -+ *) Add support for external cryptographic devices. This code was -+ previously distributed separately as the "engine" branch. -+ [Geoff Thorpe, Richard Levitte] -+ -+ *) Rework the filename-translation in the DSO code. It is now possible to -+ have far greater control over how a "name" is turned into a filename -+ depending on the operating environment and any oddities about the -+ different shared library filenames on each system. -+ [Geoff Thorpe] -+ -+ *) Support threads on FreeBSD-elf in Configure. -+ [Richard Levitte] -+ -+ *) Fix for SHA1 assembly problem with MASM: it produces -+ warnings about corrupt line number information when assembling -+ with debugging information. This is caused by the overlapping -+ of two sections. -+ [Bernd Matthes , Steve Henson] -+ -+ *) NCONF changes. -+ NCONF_get_number() has no error checking at all. As a replacement, -+ NCONF_get_number_e() is defined (_e for "error checking") and is -+ promoted strongly. The old NCONF_get_number is kept around for -+ binary backward compatibility. -+ Make it possible for methods to load from something other than a BIO, -+ by providing a function pointer that is given a name instead of a BIO. -+ For example, this could be used to load configuration data from an -+ LDAP server. -+ [Richard Levitte] -+ -+ *) Fix for non blocking accept BIOs. Added new I/O special reason -+ BIO_RR_ACCEPT to cover this case. Previously use of accept BIOs -+ with non blocking I/O was not possible because no retry code was -+ implemented. Also added new SSL code SSL_WANT_ACCEPT to cover -+ this case. -+ [Steve Henson] -+ -+ *) Added the beginnings of Rijndael support. -+ [Ben Laurie] -+ -+ *) Fix for bug in DirectoryString mask setting. Add support for -+ X509_NAME_print_ex() in 'req' and X509_print_ex() function -+ to allow certificate printing to more controllable, additional -+ 'certopt' option to 'x509' to allow new printing options to be -+ set. -+ [Steve Henson] -+ -+ *) Clean old EAY MD5 hack from e_os.h. -+ [Richard Levitte] -+ -+ Changes between 0.9.6l and 0.9.6m [17 Mar 2004] -+ -+ *) Fix null-pointer assignment in do_change_cipher_spec() revealed -+ by using the Codenomicon TLS Test Tool (CVE-2004-0079) -+ [Joe Orton, Steve Henson] -+ -+ Changes between 0.9.6k and 0.9.6l [04 Nov 2003] -+ -+ *) Fix additional bug revealed by the NISCC test suite: -+ -+ Stop bug triggering large recursion when presented with -+ certain ASN.1 tags (CVE-2003-0851) -+ [Steve Henson] -+ -+ Changes between 0.9.6j and 0.9.6k [30 Sep 2003] -+ -+ *) Fix various bugs revealed by running the NISCC test suite: -+ -+ Stop out of bounds reads in the ASN1 code when presented with -+ invalid tags (CVE-2003-0543 and CVE-2003-0544). -+ -+ If verify callback ignores invalid public key errors don't try to check -+ certificate signature with the NULL public key. -+ -+ [Steve Henson] -+ -+ *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate -+ if the server requested one: as stated in TLS 1.0 and SSL 3.0 -+ specifications. -+ [Steve Henson] -+ -+ *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional -+ extra data after the compression methods not only for TLS 1.0 -+ but also for SSL 3.0 (as required by the specification). -+ [Bodo Moeller; problem pointed out by Matthias Loepfe] -+ -+ *) Change X509_certificate_type() to mark the key as exported/exportable -+ when it's 512 *bits* long, not 512 bytes. -+ [Richard Levitte] -+ -+ Changes between 0.9.6i and 0.9.6j [10 Apr 2003] -+ -+ *) Countermeasure against the Klima-Pokorny-Rosa extension of -+ Bleichbacher's attack on PKCS #1 v1.5 padding: treat -+ a protocol version number mismatch like a decryption error -+ in ssl3_get_client_key_exchange (ssl/s3_srvr.c). -+ [Bodo Moeller] -+ -+ *) Turn on RSA blinding by default in the default implementation -+ to avoid a timing attack. Applications that don't want it can call -+ RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING. -+ They would be ill-advised to do so in most cases. -+ [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller] -+ -+ *) Change RSA blinding code so that it works when the PRNG is not -+ seeded (in this case, the secret RSA exponent is abused as -+ an unpredictable seed -- if it is not unpredictable, there -+ is no point in blinding anyway). Make RSA blinding thread-safe -+ by remembering the creator's thread ID in rsa->blinding and -+ having all other threads use local one-time blinding factors -+ (this requires more computation than sharing rsa->blinding, but -+ avoids excessive locking; and if an RSA object is not shared -+ between threads, blinding will still be very fast). -+ [Bodo Moeller] -+ -+ Changes between 0.9.6h and 0.9.6i [19 Feb 2003] -+ -+ *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked -+ via timing by performing a MAC computation even if incorrrect -+ block cipher padding has been found. This is a countermeasure -+ against active attacks where the attacker has to distinguish -+ between bad padding and a MAC verification error. (CVE-2003-0078) -+ -+ [Bodo Moeller; problem pointed out by Brice Canvel (EPFL), -+ Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and -+ Martin Vuagnoux (EPFL, Ilion)] -+ -+ Changes between 0.9.6g and 0.9.6h [5 Dec 2002] -+ -+ *) New function OPENSSL_cleanse(), which is used to cleanse a section of -+ memory from it's contents. This is done with a counter that will -+ place alternating values in each byte. This can be used to solve -+ two issues: 1) the removal of calls to memset() by highly optimizing -+ compilers, and 2) cleansing with other values than 0, since those can -+ be read through on certain media, for example a swap space on disk. -+ [Geoff Thorpe] -+ -+ *) Bugfix: client side session caching did not work with external caching, -+ because the session->cipher setting was not restored when reloading -+ from the external cache. This problem was masked, when -+ SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG (part of SSL_OP_ALL) was set. -+ (Found by Steve Haslam .) -+ [Lutz Jaenicke] -+ -+ *) Fix client_certificate (ssl/s2_clnt.c): The permissible total -+ length of the REQUEST-CERTIFICATE message is 18 .. 34, not 17 .. 33. -+ [Zeev Lieber ] -+ -+ *) Undo an undocumented change introduced in 0.9.6e which caused -+ repeated calls to OpenSSL_add_all_ciphers() and -+ OpenSSL_add_all_digests() to be ignored, even after calling -+ EVP_cleanup(). -+ [Richard Levitte] -+ -+ *) Change the default configuration reader to deal with last line not -+ being properly terminated. -+ [Richard Levitte] -+ -+ *) Change X509_NAME_cmp() so it applies the special rules on handling -+ DN values that are of type PrintableString, as well as RDNs of type -+ emailAddress where the value has the type ia5String. -+ [stefank@valicert.com via Richard Levitte] -+ -+ *) Add a SSL_SESS_CACHE_NO_INTERNAL_STORE flag to take over half -+ the job SSL_SESS_CACHE_NO_INTERNAL_LOOKUP was inconsistently -+ doing, define a new flag (SSL_SESS_CACHE_NO_INTERNAL) to be -+ the bitwise-OR of the two for use by the majority of applications -+ wanting this behaviour, and update the docs. The documented -+ behaviour and actual behaviour were inconsistent and had been -+ changing anyway, so this is more a bug-fix than a behavioural -+ change. -+ [Geoff Thorpe, diagnosed by Nadav Har'El] -+ -+ *) Don't impose a 16-byte length minimum on session IDs in ssl/s3_clnt.c -+ (the SSL 3.0 and TLS 1.0 specifications allow any length up to 32 bytes). -+ [Bodo Moeller] -+ -+ *) Fix initialization code race conditions in -+ SSLv23_method(), SSLv23_client_method(), SSLv23_server_method(), -+ SSLv2_method(), SSLv2_client_method(), SSLv2_server_method(), -+ SSLv3_method(), SSLv3_client_method(), SSLv3_server_method(), -+ TLSv1_method(), TLSv1_client_method(), TLSv1_server_method(), -+ ssl2_get_cipher_by_char(), -+ ssl3_get_cipher_by_char(). -+ [Patrick McCormick , Bodo Moeller] -+ -+ *) Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after -+ the cached sessions are flushed, as the remove_cb() might use ex_data -+ contents. Bug found by Sam Varshavchik -+ (see [openssl.org #212]). -+ [Geoff Thorpe, Lutz Jaenicke] -+ -+ *) Fix typo in OBJ_txt2obj which incorrectly passed the content -+ length, instead of the encoding length to d2i_ASN1_OBJECT. -+ [Steve Henson] -+ -+ Changes between 0.9.6f and 0.9.6g [9 Aug 2002] -+ -+ *) [In 0.9.6g-engine release:] -+ Fix crypto/engine/vendor_defns/cswift.h for WIN32 (use '_stdcall'). -+ [Lynn Gazis ] -+ -+ Changes between 0.9.6e and 0.9.6f [8 Aug 2002] -+ -+ *) Fix ASN1 checks. Check for overflow by comparing with LONG_MAX -+ and get fix the header length calculation. -+ [Florian Weimer , -+ Alon Kantor (and others), -+ Steve Henson] -+ -+ *) Use proper error handling instead of 'assertions' in buffer -+ overflow checks added in 0.9.6e. This prevents DoS (the -+ assertions could call abort()). -+ [Arne Ansper , Bodo Moeller] -+ -+ Changes between 0.9.6d and 0.9.6e [30 Jul 2002] -+ -+ *) Add various sanity checks to asn1_get_length() to reject -+ the ASN1 length bytes if they exceed sizeof(long), will appear -+ negative or the content length exceeds the length of the -+ supplied buffer. -+ [Steve Henson, Adi Stav , James Yonan ] -+ -+ *) Fix cipher selection routines: ciphers without encryption had no flags -+ for the cipher strength set and where therefore not handled correctly -+ by the selection routines (PR #130). -+ [Lutz Jaenicke] -+ -+ *) Fix EVP_dsa_sha macro. -+ [Nils Larsch] -+ -+ *) New option -+ SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS -+ for disabling the SSL 3.0/TLS 1.0 CBC vulnerability countermeasure -+ that was added in OpenSSL 0.9.6d. -+ -+ As the countermeasure turned out to be incompatible with some -+ broken SSL implementations, the new option is part of SSL_OP_ALL. -+ SSL_OP_ALL is usually employed when compatibility with weird SSL -+ implementations is desired (e.g. '-bugs' option to 's_client' and -+ 's_server'), so the new option is automatically set in many -+ applications. -+ [Bodo Moeller] -+ -+ *) Changes in security patch: -+ -+ Changes marked "(CHATS)" were sponsored by the Defense Advanced -+ Research Projects Agency (DARPA) and Air Force Research Laboratory, -+ Air Force Materiel Command, USAF, under agreement number -+ F30602-01-2-0537. -+ -+ *) Add various sanity checks to asn1_get_length() to reject -+ the ASN1 length bytes if they exceed sizeof(long), will appear -+ negative or the content length exceeds the length of the -+ supplied buffer. (CVE-2002-0659) -+ [Steve Henson, Adi Stav , James Yonan ] -+ -+ *) Assertions for various potential buffer overflows, not known to -+ happen in practice. -+ [Ben Laurie (CHATS)] -+ -+ *) Various temporary buffers to hold ASCII versions of integers were -+ too small for 64 bit platforms. (CVE-2002-0655) -+ [Matthew Byng-Maddick and Ben Laurie (CHATS)> -+ -+ *) Remote buffer overflow in SSL3 protocol - an attacker could -+ supply an oversized session ID to a client. (CVE-2002-0656) -+ [Ben Laurie (CHATS)] -+ -+ *) Remote buffer overflow in SSL2 protocol - an attacker could -+ supply an oversized client master key. (CVE-2002-0656) -+ [Ben Laurie (CHATS)] -+ -+ Changes between 0.9.6c and 0.9.6d [9 May 2002] -+ -+ *) Fix crypto/asn1/a_sign.c so that 'parameters' is omitted (not -+ encoded as NULL) with id-dsa-with-sha1. -+ [Nils Larsch ; problem pointed out by Bodo Moeller] -+ -+ *) Check various X509_...() return values in apps/req.c. -+ [Nils Larsch ] -+ -+ *) Fix BASE64 decode (EVP_DecodeUpdate) for data with CR/LF ended lines: -+ an end-of-file condition would erroneously be flagged, when the CRLF -+ was just at the end of a processed block. The bug was discovered when -+ processing data through a buffering memory BIO handing the data to a -+ BASE64-decoding BIO. Bug fund and patch submitted by Pavel Tsekov -+ and Nedelcho Stanev. -+ [Lutz Jaenicke] -+ -+ *) Implement a countermeasure against a vulnerability recently found -+ in CBC ciphersuites in SSL 3.0/TLS 1.0: Send an empty fragment -+ before application data chunks to avoid the use of known IVs -+ with data potentially chosen by the attacker. -+ [Bodo Moeller] -+ -+ *) Fix length checks in ssl3_get_client_hello(). -+ [Bodo Moeller] -+ -+ *) TLS/SSL library bugfix: use s->s3->in_read_app_data differently -+ to prevent ssl3_read_internal() from incorrectly assuming that -+ ssl3_read_bytes() found application data while handshake -+ processing was enabled when in fact s->s3->in_read_app_data was -+ merely automatically cleared during the initial handshake. -+ [Bodo Moeller; problem pointed out by Arne Ansper ] -+ -+ *) Fix object definitions for Private and Enterprise: they were not -+ recognized in their shortname (=lowercase) representation. Extend -+ obj_dat.pl to issue an error when using undefined keywords instead -+ of silently ignoring the problem (Svenning Sorensen -+ ). -+ [Lutz Jaenicke] -+ -+ *) Fix DH_generate_parameters() so that it works for 'non-standard' -+ generators, i.e. generators other than 2 and 5. (Previously, the -+ code did not properly initialise the 'add' and 'rem' values to -+ BN_generate_prime().) -+ -+ In the new general case, we do not insist that 'generator' is -+ actually a primitive root: This requirement is rather pointless; -+ a generator of the order-q subgroup is just as good, if not -+ better. -+ [Bodo Moeller] -+ -+ *) Map new X509 verification errors to alerts. Discovered and submitted by -+ Tom Wu . -+ [Lutz Jaenicke] -+ -+ *) Fix ssl3_pending() (ssl/s3_lib.c) to prevent SSL_pending() from -+ returning non-zero before the data has been completely received -+ when using non-blocking I/O. -+ [Bodo Moeller; problem pointed out by John Hughes] -+ -+ *) Some of the ciphers missed the strength entry (SSL_LOW etc). -+ [Ben Laurie, Lutz Jaenicke] -+ -+ *) Fix bug in SSL_clear(): bad sessions were not removed (found by -+ Yoram Zahavi ). -+ [Lutz Jaenicke] -+ -+ *) Add information about CygWin 1.3 and on, and preserve proper -+ configuration for the versions before that. -+ [Corinna Vinschen and Richard Levitte] -+ -+ *) Make removal from session cache (SSL_CTX_remove_session()) more robust: -+ check whether we deal with a copy of a session and do not delete from -+ the cache in this case. Problem reported by "Izhar Shoshani Levi" -+ . -+ [Lutz Jaenicke] -+ -+ *) Do not store session data into the internal session cache, if it -+ is never intended to be looked up (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP -+ flag is set). Proposed by Aslam . -+ [Lutz Jaenicke] -+ -+ *) Have ASN1_BIT_STRING_set_bit() really clear a bit when the requested -+ value is 0. -+ [Richard Levitte] -+ -+ *) [In 0.9.6d-engine release:] -+ Fix a crashbug and a logic bug in hwcrhk_load_pubkey(). -+ [Toomas Kiisk via Richard Levitte] -+ -+ *) Add the configuration target linux-s390x. -+ [Neale Ferguson via Richard Levitte] -+ -+ *) The earlier bugfix for the SSL3_ST_SW_HELLO_REQ_C case of -+ ssl3_accept (ssl/s3_srvr.c) incorrectly used a local flag -+ variable as an indication that a ClientHello message has been -+ received. As the flag value will be lost between multiple -+ invocations of ssl3_accept when using non-blocking I/O, the -+ function may not be aware that a handshake has actually taken -+ place, thus preventing a new session from being added to the -+ session cache. -+ -+ To avoid this problem, we now set s->new_session to 2 instead of -+ using a local variable. -+ [Lutz Jaenicke, Bodo Moeller] -+ -+ *) Bugfix: Return -1 from ssl3_get_server_done (ssl3/s3_clnt.c) -+ if the SSL_R_LENGTH_MISMATCH error is detected. -+ [Geoff Thorpe, Bodo Moeller] -+ -+ *) New 'shared_ldflag' column in Configure platform table. -+ [Richard Levitte] -+ -+ *) Fix EVP_CIPHER_mode macro. -+ ["Dan S. Camper" ] -+ -+ *) Fix ssl3_read_bytes (ssl/s3_pkt.c): To ignore messages of unknown -+ type, we must throw them away by setting rr->length to 0. -+ [D P Chang ] -+ -+ Changes between 0.9.6b and 0.9.6c [21 dec 2001] -+ -+ *) Fix BN_rand_range bug pointed out by Dominikus Scherkl -+ . (The previous implementation -+ worked incorrectly for those cases where range = 10..._2 and -+ 3*range is two bits longer than range.) -+ [Bodo Moeller] -+ -+ *) Only add signing time to PKCS7 structures if it is not already -+ present. -+ [Steve Henson] -+ -+ *) Fix crypto/objects/objects.h: "ld-ce" should be "id-ce", -+ OBJ_ld_ce should be OBJ_id_ce. -+ Also some ip-pda OIDs in crypto/objects/objects.txt were -+ incorrect (cf. RFC 3039). -+ [Matt Cooper, Frederic Giudicelli, Bodo Moeller] -+ -+ *) Release CRYPTO_LOCK_DYNLOCK when CRYPTO_destroy_dynlockid() -+ returns early because it has nothing to do. -+ [Andy Schneider ] -+ -+ *) [In 0.9.6c-engine release:] -+ Fix mutex callback return values in crypto/engine/hw_ncipher.c. -+ [Andy Schneider ] -+ -+ *) [In 0.9.6c-engine release:] -+ Add support for Cryptographic Appliance's keyserver technology. -+ (Use engine 'keyclient') -+ [Cryptographic Appliances and Geoff Thorpe] -+ -+ *) Add a configuration entry for OS/390 Unix. The C compiler 'c89' -+ is called via tools/c89.sh because arguments have to be -+ rearranged (all '-L' options must appear before the first object -+ modules). -+ [Richard Shapiro ] -+ -+ *) [In 0.9.6c-engine release:] -+ Add support for Broadcom crypto accelerator cards, backported -+ from 0.9.7. -+ [Broadcom, Nalin Dahyabhai , Mark Cox] -+ -+ *) [In 0.9.6c-engine release:] -+ Add support for SureWare crypto accelerator cards from -+ Baltimore Technologies. (Use engine 'sureware') -+ [Baltimore Technologies and Mark Cox] -+ -+ *) [In 0.9.6c-engine release:] -+ Add support for crypto accelerator cards from Accelerated -+ Encryption Processing, www.aep.ie. (Use engine 'aep') -+ [AEP Inc. and Mark Cox] -+ -+ *) Add a configuration entry for gcc on UnixWare. -+ [Gary Benson ] -+ -+ *) Change ssl/s2_clnt.c and ssl/s2_srvr.c so that received handshake -+ messages are stored in a single piece (fixed-length part and -+ variable-length part combined) and fix various bugs found on the way. -+ [Bodo Moeller] -+ -+ *) Disable caching in BIO_gethostbyname(), directly use gethostbyname() -+ instead. BIO_gethostbyname() does not know what timeouts are -+ appropriate, so entries would stay in cache even when they have -+ become invalid. -+ [Bodo Moeller; problem pointed out by Rich Salz -+ -+ *) Change ssl23_get_client_hello (ssl/s23_srvr.c) behaviour when -+ faced with a pathologically small ClientHello fragment that does -+ not contain client_version: Instead of aborting with an error, -+ simply choose the highest available protocol version (i.e., -+ TLS 1.0 unless it is disabled). In practice, ClientHello -+ messages are never sent like this, but this change gives us -+ strictly correct behaviour at least for TLS. -+ [Bodo Moeller] -+ -+ *) Fix SSL handshake functions and SSL_clear() such that SSL_clear() -+ never resets s->method to s->ctx->method when called from within -+ one of the SSL handshake functions. -+ [Bodo Moeller; problem pointed out by Niko Baric] -+ -+ *) In ssl3_get_client_hello (ssl/s3_srvr.c), generate a fatal alert -+ (sent using the client's version number) if client_version is -+ smaller than the protocol version in use. Also change -+ ssl23_get_client_hello (ssl/s23_srvr.c) to select TLS 1.0 if -+ the client demanded SSL 3.0 but only TLS 1.0 is enabled; then -+ the client will at least see that alert. -+ [Bodo Moeller] -+ -+ *) Fix ssl3_get_message (ssl/s3_both.c) to handle message fragmentation -+ correctly. -+ [Bodo Moeller] -+ -+ *) Avoid infinite loop in ssl3_get_message (ssl/s3_both.c) if a -+ client receives HelloRequest while in a handshake. -+ [Bodo Moeller; bug noticed by Andy Schneider ] -+ -+ *) Bugfix in ssl3_accept (ssl/s3_srvr.c): Case SSL3_ST_SW_HELLO_REQ_C -+ should end in 'break', not 'goto end' which circumvents various -+ cleanups done in state SSL_ST_OK. But session related stuff -+ must be disabled for SSL_ST_OK in the case that we just sent a -+ HelloRequest. -+ -+ Also avoid some overhead by not calling ssl_init_wbio_buffer() -+ before just sending a HelloRequest. -+ [Bodo Moeller, Eric Rescorla ] -+ -+ *) Fix ssl/s3_enc.c, ssl/t1_enc.c and ssl/s3_pkt.c so that we don't -+ reveal whether illegal block cipher padding was found or a MAC -+ verification error occurred. (Neither SSLerr() codes nor alerts -+ are directly visible to potential attackers, but the information -+ may leak via logfiles.) -+ -+ Similar changes are not required for the SSL 2.0 implementation -+ because the number of padding bytes is sent in clear for SSL 2.0, -+ and the extra bytes are just ignored. However ssl/s2_pkt.c -+ failed to verify that the purported number of padding bytes is in -+ the legal range. -+ [Bodo Moeller] -+ -+ *) Add OpenUNIX-8 support including shared libraries -+ (Boyd Lynn Gerber ). -+ [Lutz Jaenicke] -+ -+ *) Improve RSA_padding_check_PKCS1_OAEP() check again to avoid -+ 'wristwatch attack' using huge encoding parameters (cf. -+ James H. Manger's CRYPTO 2001 paper). Note that the -+ RSA_PKCS1_OAEP_PADDING case of RSA_private_decrypt() does not use -+ encoding parameters and hence was not vulnerable. -+ [Bodo Moeller] -+ -+ *) BN_sqr() bug fix. -+ [Ulf Möller, reported by Jim Ellis ] -+ -+ *) Rabin-Miller test analyses assume uniformly distributed witnesses, -+ so use BN_pseudo_rand_range() instead of using BN_pseudo_rand() -+ followed by modular reduction. -+ [Bodo Moeller; pointed out by Adam Young ] -+ -+ *) Add BN_pseudo_rand_range() with obvious functionality: BN_rand_range() -+ equivalent based on BN_pseudo_rand() instead of BN_rand(). -+ [Bodo Moeller] -+ -+ *) s3_srvr.c: allow sending of large client certificate lists (> 16 kB). -+ This function was broken, as the check for a new client hello message -+ to handle SGC did not allow these large messages. -+ (Tracked down by "Douglas E. Engert" .) -+ [Lutz Jaenicke] -+ -+ *) Add alert descriptions for TLSv1 to SSL_alert_desc_string[_long](). -+ [Lutz Jaenicke] -+ -+ *) Fix buggy behaviour of BIO_get_num_renegotiates() and BIO_ctrl() -+ for BIO_C_GET_WRITE_BUF_SIZE ("Stephen Hinton" ). -+ [Lutz Jaenicke] -+ -+ *) Rework the configuration and shared library support for Tru64 Unix. -+ The configuration part makes use of modern compiler features and -+ still retains old compiler behavior for those that run older versions -+ of the OS. The shared library support part includes a variant that -+ uses the RPATH feature, and is available through the special -+ configuration target "alpha-cc-rpath", which will never be selected -+ automatically. -+ [Tim Mooney via Richard Levitte] -+ -+ *) In ssl3_get_key_exchange (ssl/s3_clnt.c), call ssl3_get_message() -+ with the same message size as in ssl3_get_certificate_request(). -+ Otherwise, if no ServerKeyExchange message occurs, CertificateRequest -+ messages might inadvertently be reject as too long. -+ [Petr Lampa ] -+ -+ *) Enhanced support for IA-64 Unix platforms (well, Linux and HP-UX). -+ [Andy Polyakov] -+ -+ *) Modified SSL library such that the verify_callback that has been set -+ specificly for an SSL object with SSL_set_verify() is actually being -+ used. Before the change, a verify_callback set with this function was -+ ignored and the verify_callback() set in the SSL_CTX at the time of -+ the call was used. New function X509_STORE_CTX_set_verify_cb() introduced -+ to allow the necessary settings. -+ [Lutz Jaenicke] -+ -+ *) Initialize static variable in crypto/dsa/dsa_lib.c and crypto/dh/dh_lib.c -+ explicitly to NULL, as at least on Solaris 8 this seems not always to be -+ done automatically (in contradiction to the requirements of the C -+ standard). This made problems when used from OpenSSH. -+ [Lutz Jaenicke] -+ -+ *) In OpenSSL 0.9.6a and 0.9.6b, crypto/dh/dh_key.c ignored -+ dh->length and always used -+ -+ BN_rand_range(priv_key, dh->p). -+ -+ BN_rand_range() is not necessary for Diffie-Hellman, and this -+ specific range makes Diffie-Hellman unnecessarily inefficient if -+ dh->length (recommended exponent length) is much smaller than the -+ length of dh->p. We could use BN_rand_range() if the order of -+ the subgroup was stored in the DH structure, but we only have -+ dh->length. -+ -+ So switch back to -+ -+ BN_rand(priv_key, l, ...) -+ -+ where 'l' is dh->length if this is defined, or BN_num_bits(dh->p)-1 -+ otherwise. -+ [Bodo Moeller] -+ -+ *) In -+ -+ RSA_eay_public_encrypt -+ RSA_eay_private_decrypt -+ RSA_eay_private_encrypt (signing) -+ RSA_eay_public_decrypt (signature verification) -+ -+ (default implementations for RSA_public_encrypt, -+ RSA_private_decrypt, RSA_private_encrypt, RSA_public_decrypt), -+ always reject numbers >= n. -+ [Bodo Moeller] -+ -+ *) In crypto/rand/md_rand.c, use a new short-time lock CRYPTO_LOCK_RAND2 -+ to synchronize access to 'locking_thread'. This is necessary on -+ systems where access to 'locking_thread' (an 'unsigned long' -+ variable) is not atomic. -+ [Bodo Moeller] -+ -+ *) In crypto/rand/md_rand.c, set 'locking_thread' to current thread's ID -+ *before* setting the 'crypto_lock_rand' flag. The previous code had -+ a race condition if 0 is a valid thread ID. -+ [Travis Vitek ] -+ -+ *) Add support for shared libraries under Irix. -+ [Albert Chin-A-Young ] -+ -+ *) Add configuration option to build on Linux on both big-endian and -+ little-endian MIPS. -+ [Ralf Baechle ] -+ -+ *) Add the possibility to create shared libraries on HP-UX. -+ [Richard Levitte] -+ -+ Changes between 0.9.6a and 0.9.6b [9 Jul 2001] -+ -+ *) Change ssleay_rand_bytes (crypto/rand/md_rand.c) -+ to avoid a SSLeay/OpenSSL PRNG weakness pointed out by -+ Markku-Juhani O. Saarinen : -+ PRNG state recovery was possible based on the output of -+ one PRNG request appropriately sized to gain knowledge on -+ 'md' followed by enough consecutive 1-byte PRNG requests -+ to traverse all of 'state'. -+ -+ 1. When updating 'md_local' (the current thread's copy of 'md') -+ during PRNG output generation, hash all of the previous -+ 'md_local' value, not just the half used for PRNG output. -+ -+ 2. Make the number of bytes from 'state' included into the hash -+ independent from the number of PRNG bytes requested. -+ -+ The first measure alone would be sufficient to avoid -+ Markku-Juhani's attack. (Actually it had never occurred -+ to me that the half of 'md_local' used for chaining was the -+ half from which PRNG output bytes were taken -- I had always -+ assumed that the secret half would be used.) The second -+ measure makes sure that additional data from 'state' is never -+ mixed into 'md_local' in small portions; this heuristically -+ further strengthens the PRNG. -+ [Bodo Moeller] -+ -+ *) Fix crypto/bn/asm/mips3.s. -+ [Andy Polyakov] -+ -+ *) When only the key is given to "enc", the IV is undefined. Print out -+ an error message in this case. -+ [Lutz Jaenicke] -+ -+ *) Handle special case when X509_NAME is empty in X509 printing routines. -+ [Steve Henson] -+ -+ *) In dsa_do_verify (crypto/dsa/dsa_ossl.c), verify that r and s are -+ positive and less than q. -+ [Bodo Moeller] -+ -+ *) Don't change *pointer in CRYPTO_add_lock() is add_lock_callback is -+ used: it isn't thread safe and the add_lock_callback should handle -+ that itself. -+ [Paul Rose ] -+ -+ *) Verify that incoming data obeys the block size in -+ ssl3_enc (ssl/s3_enc.c) and tls1_enc (ssl/t1_enc.c). -+ [Bodo Moeller] -+ -+ *) Fix OAEP check. -+ [Ulf Möller, Bodo Möller] -+ -+ *) The countermeasure against Bleichbacher's attack on PKCS #1 v1.5 -+ RSA encryption was accidentally removed in s3_srvr.c in OpenSSL 0.9.5 -+ when fixing the server behaviour for backwards-compatible 'client -+ hello' messages. (Note that the attack is impractical against -+ SSL 3.0 and TLS 1.0 anyway because length and version checking -+ means that the probability of guessing a valid ciphertext is -+ around 2^-40; see section 5 in Bleichenbacher's CRYPTO '98 -+ paper.) -+ -+ Before 0.9.5, the countermeasure (hide the error by generating a -+ random 'decryption result') did not work properly because -+ ERR_clear_error() was missing, meaning that SSL_get_error() would -+ detect the supposedly ignored error. -+ -+ Both problems are now fixed. -+ [Bodo Moeller] -+ -+ *) In crypto/bio/bf_buff.c, increase DEFAULT_BUFFER_SIZE to 4096 -+ (previously it was 1024). -+ [Bodo Moeller] -+ -+ *) Fix for compatibility mode trust settings: ignore trust settings -+ unless some valid trust or reject settings are present. -+ [Steve Henson] -+ -+ *) Fix for blowfish EVP: its a variable length cipher. -+ [Steve Henson] -+ -+ *) Fix various bugs related to DSA S/MIME verification. Handle missing -+ parameters in DSA public key structures and return an error in the -+ DSA routines if parameters are absent. -+ [Steve Henson] -+ -+ *) In versions up to 0.9.6, RAND_file_name() resorted to file ".rnd" -+ in the current directory if neither $RANDFILE nor $HOME was set. -+ RAND_file_name() in 0.9.6a returned NULL in this case. This has -+ caused some confusion to Windows users who haven't defined $HOME. -+ Thus RAND_file_name() is changed again: e_os.h can define a -+ DEFAULT_HOME, which will be used if $HOME is not set. -+ For Windows, we use "C:"; on other platforms, we still require -+ environment variables. -+ -+ *) Move 'if (!initialized) RAND_poll()' into regions protected by -+ CRYPTO_LOCK_RAND. This is not strictly necessary, but avoids -+ having multiple threads call RAND_poll() concurrently. -+ [Bodo Moeller] -+ -+ *) In crypto/rand/md_rand.c, replace 'add_do_not_lock' flag by a -+ combination of a flag and a thread ID variable. -+ Otherwise while one thread is in ssleay_rand_bytes (which sets the -+ flag), *other* threads can enter ssleay_add_bytes without obeying -+ the CRYPTO_LOCK_RAND lock (and may even illegally release the lock -+ that they do not hold after the first thread unsets add_do_not_lock). -+ [Bodo Moeller] -+ -+ *) Change bctest again: '-x' expressions are not available in all -+ versions of 'test'. -+ [Bodo Moeller] -+ -+ Changes between 0.9.6 and 0.9.6a [5 Apr 2001] -+ -+ *) Fix a couple of memory leaks in PKCS7_dataDecode() -+ [Steve Henson, reported by Heyun Zheng ] -+ -+ *) Change Configure and Makefiles to provide EXE_EXT, which will contain -+ the default extension for executables, if any. Also, make the perl -+ scripts that use symlink() to test if it really exists and use "cp" -+ if it doesn't. All this made OpenSSL compilable and installable in -+ CygWin. -+ [Richard Levitte] -+ -+ *) Fix for asn1_GetSequence() for indefinite length constructed data. -+ If SEQUENCE is length is indefinite just set c->slen to the total -+ amount of data available. -+ [Steve Henson, reported by shige@FreeBSD.org] -+ [This change does not apply to 0.9.7.] -+ -+ *) Change bctest to avoid here-documents inside command substitution -+ (workaround for FreeBSD /bin/sh bug). -+ For compatibility with Ultrix, avoid shell functions (introduced -+ in the bctest version that searches along $PATH). -+ [Bodo Moeller] -+ -+ *) Rename 'des_encrypt' to 'des_encrypt1'. This avoids the clashes -+ with des_encrypt() defined on some operating systems, like Solaris -+ and UnixWare. -+ [Richard Levitte] -+ -+ *) Check the result of RSA-CRT (see D. Boneh, R. DeMillo, R. Lipton: -+ On the Importance of Eliminating Errors in Cryptographic -+ Computations, J. Cryptology 14 (2001) 2, 101-119, -+ http://theory.stanford.edu/~dabo/papers/faults.ps.gz). -+ [Ulf Moeller] -+ -+ *) MIPS assembler BIGNUM division bug fix. -+ [Andy Polyakov] -+ -+ *) Disabled incorrect Alpha assembler code. -+ [Richard Levitte] -+ -+ *) Fix PKCS#7 decode routines so they correctly update the length -+ after reading an EOC for the EXPLICIT tag. -+ [Steve Henson] -+ [This change does not apply to 0.9.7.] -+ -+ *) Fix bug in PKCS#12 key generation routines. This was triggered -+ if a 3DES key was generated with a 0 initial byte. Include -+ PKCS12_BROKEN_KEYGEN compilation option to retain the old -+ (but broken) behaviour. -+ [Steve Henson] -+ -+ *) Enhance bctest to search for a working bc along $PATH and print -+ it when found. -+ [Tim Rice via Richard Levitte] -+ -+ *) Fix memory leaks in err.c: free err_data string if necessary; -+ don't write to the wrong index in ERR_set_error_data. -+ [Bodo Moeller] -+ -+ *) Implement ssl23_peek (analogous to ssl23_read), which previously -+ did not exist. -+ [Bodo Moeller] -+ -+ *) Replace rdtsc with _emit statements for VC++ version 5. -+ [Jeremy Cooper ] -+ -+ *) Make it possible to reuse SSLv2 sessions. -+ [Richard Levitte] -+ -+ *) In copy_email() check for >= 0 as a return value for -+ X509_NAME_get_index_by_NID() since 0 is a valid index. -+ [Steve Henson reported by Massimiliano Pala ] -+ -+ *) Avoid coredump with unsupported or invalid public keys by checking if -+ X509_get_pubkey() fails in PKCS7_verify(). Fix memory leak when -+ PKCS7_verify() fails with non detached data. -+ [Steve Henson] -+ -+ *) Don't use getenv in library functions when run as setuid/setgid. -+ New function OPENSSL_issetugid(). -+ [Ulf Moeller] -+ -+ *) Avoid false positives in memory leak detection code (crypto/mem_dbg.c) -+ due to incorrect handling of multi-threading: -+ -+ 1. Fix timing glitch in the MemCheck_off() portion of CRYPTO_mem_ctrl(). -+ -+ 2. Fix logical glitch in is_MemCheck_on() aka CRYPTO_is_mem_check_on(). -+ -+ 3. Count how many times MemCheck_off() has been called so that -+ nested use can be treated correctly. This also avoids -+ inband-signalling in the previous code (which relied on the -+ assumption that thread ID 0 is impossible). -+ [Bodo Moeller] -+ -+ *) Add "-rand" option also to s_client and s_server. -+ [Lutz Jaenicke] -+ -+ *) Fix CPU detection on Irix 6.x. -+ [Kurt Hockenbury and -+ "Bruce W. Forsberg" ] -+ -+ *) Fix X509_NAME bug which produced incorrect encoding if X509_NAME -+ was empty. -+ [Steve Henson] -+ [This change does not apply to 0.9.7.] -+ -+ *) Use the cached encoding of an X509_NAME structure rather than -+ copying it. This is apparently the reason for the libsafe "errors" -+ but the code is actually correct. -+ [Steve Henson] -+ -+ *) Add new function BN_rand_range(), and fix DSA_sign_setup() to prevent -+ Bleichenbacher's DSA attack. -+ Extend BN_[pseudo_]rand: As before, top=1 forces the highest two bits -+ to be set and top=0 forces the highest bit to be set; top=-1 is new -+ and leaves the highest bit random. -+ [Ulf Moeller, Bodo Moeller] -+ -+ *) In the NCONF_...-based implementations for CONF_... queries -+ (crypto/conf/conf_lib.c), if the input LHASH is NULL, avoid using -+ a temporary CONF structure with the data component set to NULL -+ (which gives segmentation faults in lh_retrieve). -+ Instead, use NULL for the CONF pointer in CONF_get_string and -+ CONF_get_number (which may use environment variables) and directly -+ return NULL from CONF_get_section. -+ [Bodo Moeller] -+ -+ *) Fix potential buffer overrun for EBCDIC. -+ [Ulf Moeller] -+ -+ *) Tolerate nonRepudiation as being valid for S/MIME signing and certSign -+ keyUsage if basicConstraints absent for a CA. -+ [Steve Henson] -+ -+ *) Make SMIME_write_PKCS7() write mail header values with a format that -+ is more generally accepted (no spaces before the semicolon), since -+ some programs can't parse those values properly otherwise. Also make -+ sure BIO's that break lines after each write do not create invalid -+ headers. -+ [Richard Levitte] -+ -+ *) Make the CRL encoding routines work with empty SEQUENCE OF. The -+ macros previously used would not encode an empty SEQUENCE OF -+ and break the signature. -+ [Steve Henson] -+ [This change does not apply to 0.9.7.] -+ -+ *) Zero the premaster secret after deriving the master secret in -+ DH ciphersuites. -+ [Steve Henson] -+ -+ *) Add some EVP_add_digest_alias registrations (as found in -+ OpenSSL_add_all_digests()) to SSL_library_init() -+ aka OpenSSL_add_ssl_algorithms(). This provides improved -+ compatibility with peers using X.509 certificates -+ with unconventional AlgorithmIdentifier OIDs. -+ [Bodo Moeller] -+ -+ *) Fix for Irix with NO_ASM. -+ ["Bruce W. Forsberg" ] -+ -+ *) ./config script fixes. -+ [Ulf Moeller, Richard Levitte] -+ -+ *) Fix 'openssl passwd -1'. -+ [Bodo Moeller] -+ -+ *) Change PKCS12_key_gen_asc() so it can cope with non null -+ terminated strings whose length is passed in the passlen -+ parameter, for example from PEM callbacks. This was done -+ by adding an extra length parameter to asc2uni(). -+ [Steve Henson, reported by ] -+ -+ *) Fix C code generated by 'openssl dsaparam -C': If a BN_bin2bn -+ call failed, free the DSA structure. -+ [Bodo Moeller] -+ -+ *) Fix to uni2asc() to cope with zero length Unicode strings. -+ These are present in some PKCS#12 files. -+ [Steve Henson] -+ -+ *) Increase s2->wbuf allocation by one byte in ssl2_new (ssl/s2_lib.c). -+ Otherwise do_ssl_write (ssl/s2_pkt.c) will write beyond buffer limits -+ when writing a 32767 byte record. -+ [Bodo Moeller; problem reported by Eric Day ] -+ -+ *) In RSA_eay_public_{en,ed}crypt and RSA_eay_mod_exp (rsa_eay.c), -+ obtain lock CRYPTO_LOCK_RSA before setting rsa->_method_mod_{n,p,q}. -+ -+ (RSA objects have a reference count access to which is protected -+ by CRYPTO_LOCK_RSA [see rsa_lib.c, s3_srvr.c, ssl_cert.c, ssl_rsa.c], -+ so they are meant to be shared between threads.) -+ [Bodo Moeller, Geoff Thorpe; original patch submitted by -+ "Reddie, Steven" ] -+ -+ *) Fix a deadlock in CRYPTO_mem_leaks(). -+ [Bodo Moeller] -+ -+ *) Use better test patterns in bntest. -+ [Ulf Möller] -+ -+ *) rand_win.c fix for Borland C. -+ [Ulf Möller] -+ -+ *) BN_rshift bugfix for n == 0. -+ [Bodo Moeller] -+ -+ *) Add a 'bctest' script that checks for some known 'bc' bugs -+ so that 'make test' does not abort just because 'bc' is broken. -+ [Bodo Moeller] -+ -+ *) Store verify_result within SSL_SESSION also for client side to -+ avoid potential security hole. (Re-used sessions on the client side -+ always resulted in verify_result==X509_V_OK, not using the original -+ result of the server certificate verification.) -+ [Lutz Jaenicke] -+ -+ *) Fix ssl3_pending: If the record in s->s3->rrec is not of type -+ SSL3_RT_APPLICATION_DATA, return 0. -+ Similarly, change ssl2_pending to return 0 if SSL_in_init(s) is true. -+ [Bodo Moeller] -+ -+ *) Fix SSL_peek: -+ Both ssl2_peek and ssl3_peek, which were totally broken in earlier -+ releases, have been re-implemented by renaming the previous -+ implementations of ssl2_read and ssl3_read to ssl2_read_internal -+ and ssl3_read_internal, respectively, and adding 'peek' parameters -+ to them. The new ssl[23]_{read,peek} functions are calls to -+ ssl[23]_read_internal with the 'peek' flag set appropriately. -+ A 'peek' parameter has also been added to ssl3_read_bytes, which -+ does the actual work for ssl3_read_internal. -+ [Bodo Moeller] -+ -+ *) Initialise "ex_data" member of RSA/DSA/DH structures prior to calling -+ the method-specific "init()" handler. Also clean up ex_data after -+ calling the method-specific "finish()" handler. Previously, this was -+ happening the other way round. -+ [Geoff Thorpe] -+ -+ *) Increase BN_CTX_NUM (the number of BIGNUMs in a BN_CTX) to 16. -+ The previous value, 12, was not always sufficient for BN_mod_exp(). -+ [Bodo Moeller] -+ -+ *) Make sure that shared libraries get the internal name engine with -+ the full version number and not just 0. This should mark the -+ shared libraries as not backward compatible. Of course, this should -+ be changed again when we can guarantee backward binary compatibility. -+ [Richard Levitte] -+ -+ *) Fix typo in get_cert_by_subject() in by_dir.c -+ [Jean-Marc Desperrier ] -+ -+ *) Rework the system to generate shared libraries: -+ -+ - Make note of the expected extension for the shared libraries and -+ if there is a need for symbolic links from for example libcrypto.so.0 -+ to libcrypto.so.0.9.7. There is extended info in Configure for -+ that. -+ -+ - Make as few rebuilds of the shared libraries as possible. -+ -+ - Still avoid linking the OpenSSL programs with the shared libraries. -+ -+ - When installing, install the shared libraries separately from the -+ static ones. -+ [Richard Levitte] -+ -+ *) Fix SSL_CTX_set_read_ahead macro to actually use its argument. -+ -+ Copy SSL_CTX's read_ahead flag to SSL object directly in SSL_new -+ and not in SSL_clear because the latter is also used by the -+ accept/connect functions; previously, the settings made by -+ SSL_set_read_ahead would be lost during the handshake. -+ [Bodo Moeller; problems reported by Anders Gertz ] -+ -+ *) Correct util/mkdef.pl to be selective about disabled algorithms. -+ Previously, it would create entries for disabled algorithms no -+ matter what. -+ [Richard Levitte] -+ -+ *) Added several new manual pages for SSL_* function. -+ [Lutz Jaenicke] -+ -+ Changes between 0.9.5a and 0.9.6 [24 Sep 2000] -+ -+ *) In ssl23_get_client_hello, generate an error message when faced -+ with an initial SSL 3.0/TLS record that is too small to contain the -+ first two bytes of the ClientHello message, i.e. client_version. -+ (Note that this is a pathologic case that probably has never happened -+ in real life.) The previous approach was to use the version number -+ from the record header as a substitute; but our protocol choice -+ should not depend on that one because it is not authenticated -+ by the Finished messages. -+ [Bodo Moeller] -+ -+ *) More robust randomness gathering functions for Windows. -+ [Jeffrey Altman ] -+ -+ *) For compatibility reasons if the flag X509_V_FLAG_ISSUER_CHECK is -+ not set then we don't setup the error code for issuer check errors -+ to avoid possibly overwriting other errors which the callback does -+ handle. If an application does set the flag then we assume it knows -+ what it is doing and can handle the new informational codes -+ appropriately. -+ [Steve Henson] -+ -+ *) Fix for a nasty bug in ASN1_TYPE handling. ASN1_TYPE is used for -+ a general "ANY" type, as such it should be able to decode anything -+ including tagged types. However it didn't check the class so it would -+ wrongly interpret tagged types in the same way as their universal -+ counterpart and unknown types were just rejected. Changed so that the -+ tagged and unknown types are handled in the same way as a SEQUENCE: -+ that is the encoding is stored intact. There is also a new type -+ "V_ASN1_OTHER" which is used when the class is not universal, in this -+ case we have no idea what the actual type is so we just lump them all -+ together. -+ [Steve Henson] -+ -+ *) On VMS, stdout may very well lead to a file that is written to -+ in a record-oriented fashion. That means that every write() will -+ write a separate record, which will be read separately by the -+ programs trying to read from it. This can be very confusing. -+ -+ The solution is to put a BIO filter in the way that will buffer -+ text until a linefeed is reached, and then write everything a -+ line at a time, so every record written will be an actual line, -+ not chunks of lines and not (usually doesn't happen, but I've -+ seen it once) several lines in one record. BIO_f_linebuffer() is -+ the answer. -+ -+ Currently, it's a VMS-only method, because that's where it has -+ been tested well enough. -+ [Richard Levitte] -+ -+ *) Remove 'optimized' squaring variant in BN_mod_mul_montgomery, -+ it can return incorrect results. -+ (Note: The buggy variant was not enabled in OpenSSL 0.9.5a, -+ but it was in 0.9.6-beta[12].) -+ [Bodo Moeller] -+ -+ *) Disable the check for content being present when verifying detached -+ signatures in pk7_smime.c. Some versions of Netscape (wrongly) -+ include zero length content when signing messages. -+ [Steve Henson] -+ -+ *) New BIO_shutdown_wr macro, which invokes the BIO_C_SHUTDOWN_WR -+ BIO_ctrl (for BIO pairs). -+ [Bodo Möller] -+ -+ *) Add DSO method for VMS. -+ [Richard Levitte] -+ -+ *) Bug fix: Montgomery multiplication could produce results with the -+ wrong sign. -+ [Ulf Möller] -+ -+ *) Add RPM specification openssl.spec and modify it to build three -+ packages. The default package contains applications, application -+ documentation and run-time libraries. The devel package contains -+ include files, static libraries and function documentation. The -+ doc package contains the contents of the doc directory. The original -+ openssl.spec was provided by Damien Miller . -+ [Richard Levitte] -+ -+ *) Add a large number of documentation files for many SSL routines. -+ [Lutz Jaenicke ] -+ -+ *) Add a configuration entry for Sony News 4. -+ [NAKAJI Hiroyuki ] -+ -+ *) Don't set the two most significant bits to one when generating a -+ random number < q in the DSA library. -+ [Ulf Möller] -+ -+ *) New SSL API mode 'SSL_MODE_AUTO_RETRY'. This disables the default -+ behaviour that SSL_read may result in SSL_ERROR_WANT_READ (even if -+ the underlying transport is blocking) if a handshake took place. -+ (The default behaviour is needed by applications such as s_client -+ and s_server that use select() to determine when to use SSL_read; -+ but for applications that know in advance when to expect data, it -+ just makes things more complicated.) -+ [Bodo Moeller] -+ -+ *) Add RAND_egd_bytes(), which gives control over the number of bytes read -+ from EGD. -+ [Ben Laurie] -+ -+ *) Add a few more EBCDIC conditionals that make `req' and `x509' -+ work better on such systems. -+ [Martin Kraemer ] -+ -+ *) Add two demo programs for PKCS12_parse() and PKCS12_create(). -+ Update PKCS12_parse() so it copies the friendlyName and the -+ keyid to the certificates aux info. -+ [Steve Henson] -+ -+ *) Fix bug in PKCS7_verify() which caused an infinite loop -+ if there was more than one signature. -+ [Sven Uszpelkat ] -+ -+ *) Major change in util/mkdef.pl to include extra information -+ about each symbol, as well as presenting variables as well -+ as functions. This change means that there's n more need -+ to rebuild the .num files when some algorithms are excluded. -+ [Richard Levitte] -+ -+ *) Allow the verify time to be set by an application, -+ rather than always using the current time. -+ [Steve Henson] -+ -+ *) Phase 2 verify code reorganisation. The certificate -+ verify code now looks up an issuer certificate by a -+ number of criteria: subject name, authority key id -+ and key usage. It also verifies self signed certificates -+ by the same criteria. The main comparison function is -+ X509_check_issued() which performs these checks. -+ -+ Lot of changes were necessary in order to support this -+ without completely rewriting the lookup code. -+ -+ Authority and subject key identifier are now cached. -+ -+ The LHASH 'certs' is X509_STORE has now been replaced -+ by a STACK_OF(X509_OBJECT). This is mainly because an -+ LHASH can't store or retrieve multiple objects with -+ the same hash value. -+ -+ As a result various functions (which were all internal -+ use only) have changed to handle the new X509_STORE -+ structure. This will break anything that messed round -+ with X509_STORE internally. -+ -+ The functions X509_STORE_add_cert() now checks for an -+ exact match, rather than just subject name. -+ -+ The X509_STORE API doesn't directly support the retrieval -+ of multiple certificates matching a given criteria, however -+ this can be worked round by performing a lookup first -+ (which will fill the cache with candidate certificates) -+ and then examining the cache for matches. This is probably -+ the best we can do without throwing out X509_LOOKUP -+ entirely (maybe later...). -+ -+ The X509_VERIFY_CTX structure has been enhanced considerably. -+ -+ All certificate lookup operations now go via a get_issuer() -+ callback. Although this currently uses an X509_STORE it -+ can be replaced by custom lookups. This is a simple way -+ to bypass the X509_STORE hackery necessary to make this -+ work and makes it possible to use more efficient techniques -+ in future. A very simple version which uses a simple -+ STACK for its trusted certificate store is also provided -+ using X509_STORE_CTX_trusted_stack(). -+ -+ The verify_cb() and verify() callbacks now have equivalents -+ in the X509_STORE_CTX structure. -+ -+ X509_STORE_CTX also has a 'flags' field which can be used -+ to customise the verify behaviour. -+ [Steve Henson] -+ -+ *) Add new PKCS#7 signing option PKCS7_NOSMIMECAP which -+ excludes S/MIME capabilities. -+ [Steve Henson] -+ -+ *) When a certificate request is read in keep a copy of the -+ original encoding of the signed data and use it when outputting -+ again. Signatures then use the original encoding rather than -+ a decoded, encoded version which may cause problems if the -+ request is improperly encoded. -+ [Steve Henson] -+ -+ *) For consistency with other BIO_puts implementations, call -+ buffer_write(b, ...) directly in buffer_puts instead of calling -+ BIO_write(b, ...). -+ -+ In BIO_puts, increment b->num_write as in BIO_write. -+ [Peter.Sylvester@EdelWeb.fr] -+ -+ *) Fix BN_mul_word for the case where the word is 0. (We have to use -+ BN_zero, we may not return a BIGNUM with an array consisting of -+ words set to zero.) -+ [Bodo Moeller] -+ -+ *) Avoid calling abort() from within the library when problems are -+ detected, except if preprocessor symbols have been defined -+ (such as REF_CHECK, BN_DEBUG etc.). -+ [Bodo Moeller] -+ -+ *) New openssl application 'rsautl'. This utility can be -+ used for low level RSA operations. DER public key -+ BIO/fp routines also added. -+ [Steve Henson] -+ -+ *) New Configure entry and patches for compiling on QNX 4. -+ [Andreas Schneider ] -+ -+ *) A demo state-machine implementation was sponsored by -+ Nuron (http://www.nuron.com/) and is now available in -+ demos/state_machine. -+ [Ben Laurie] -+ -+ *) New options added to the 'dgst' utility for signature -+ generation and verification. -+ [Steve Henson] -+ -+ *) Unrecognized PKCS#7 content types are now handled via a -+ catch all ASN1_TYPE structure. This allows unsupported -+ types to be stored as a "blob" and an application can -+ encode and decode it manually. -+ [Steve Henson] -+ -+ *) Fix various signed/unsigned issues to make a_strex.c -+ compile under VC++. -+ [Oscar Jacobsson ] -+ -+ *) ASN1 fixes. i2d_ASN1_OBJECT was not returning the correct -+ length if passed a buffer. ASN1_INTEGER_to_BN failed -+ if passed a NULL BN and its argument was negative. -+ [Steve Henson, pointed out by Sven Heiberg ] -+ -+ *) Modification to PKCS#7 encoding routines to output definite -+ length encoding. Since currently the whole structures are in -+ memory there's not real point in using indefinite length -+ constructed encoding. However if OpenSSL is compiled with -+ the flag PKCS7_INDEFINITE_ENCODING the old form is used. -+ [Steve Henson] -+ -+ *) Added BIO_vprintf() and BIO_vsnprintf(). -+ [Richard Levitte] -+ -+ *) Added more prefixes to parse for in the the strings written -+ through a logging bio, to cover all the levels that are available -+ through syslog. The prefixes are now: -+ -+ PANIC, EMERG, EMR => LOG_EMERG -+ ALERT, ALR => LOG_ALERT -+ CRIT, CRI => LOG_CRIT -+ ERROR, ERR => LOG_ERR -+ WARNING, WARN, WAR => LOG_WARNING -+ NOTICE, NOTE, NOT => LOG_NOTICE -+ INFO, INF => LOG_INFO -+ DEBUG, DBG => LOG_DEBUG -+ -+ and as before, if none of those prefixes are present at the -+ beginning of the string, LOG_ERR is chosen. -+ -+ On Win32, the LOG_* levels are mapped according to this: -+ -+ LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR => EVENTLOG_ERROR_TYPE -+ LOG_WARNING => EVENTLOG_WARNING_TYPE -+ LOG_NOTICE, LOG_INFO, LOG_DEBUG => EVENTLOG_INFORMATION_TYPE -+ -+ [Richard Levitte] -+ -+ *) Made it possible to reconfigure with just the configuration -+ argument "reconf" or "reconfigure". The command line arguments -+ are stored in Makefile.ssl in the variable CONFIGURE_ARGS, -+ and are retrieved from there when reconfiguring. -+ [Richard Levitte] -+ -+ *) MD4 implemented. -+ [Assar Westerlund , Richard Levitte] -+ -+ *) Add the arguments -CAfile and -CApath to the pkcs12 utility. -+ [Richard Levitte] -+ -+ *) The obj_dat.pl script was messing up the sorting of object -+ names. The reason was that it compared the quoted version -+ of strings as a result "OCSP" > "OCSP Signing" because -+ " > SPACE. Changed script to store unquoted versions of -+ names and add quotes on output. It was also omitting some -+ names from the lookup table if they were given a default -+ value (that is if SN is missing it is given the same -+ value as LN and vice versa), these are now added on the -+ grounds that if an object has a name we should be able to -+ look it up. Finally added warning output when duplicate -+ short or long names are found. -+ [Steve Henson] -+ -+ *) Changes needed for Tandem NSK. -+ [Scott Uroff ] -+ -+ *) Fix SSL 2.0 rollback checking: Due to an off-by-one error in -+ RSA_padding_check_SSLv23(), special padding was never detected -+ and thus the SSL 3.0/TLS 1.0 countermeasure against protocol -+ version rollback attacks was not effective. -+ -+ In s23_clnt.c, don't use special rollback-attack detection padding -+ (RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the -+ client; similarly, in s23_srvr.c, don't do the rollback check if -+ SSL 2.0 is the only protocol enabled in the server. -+ [Bodo Moeller] -+ -+ *) Make it possible to get hexdumps of unprintable data with 'openssl -+ asn1parse'. By implication, the functions ASN1_parse_dump() and -+ BIO_dump_indent() are added. -+ [Richard Levitte] -+ -+ *) New functions ASN1_STRING_print_ex() and X509_NAME_print_ex() -+ these print out strings and name structures based on various -+ flags including RFC2253 support and proper handling of -+ multibyte characters. Added options to the 'x509' utility -+ to allow the various flags to be set. -+ [Steve Henson] -+ -+ *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME. -+ Also change the functions X509_cmp_current_time() and -+ X509_gmtime_adj() work with an ASN1_TIME structure, -+ this will enable certificates using GeneralizedTime in validity -+ dates to be checked. -+ [Steve Henson] -+ -+ *) Make the NEG_PUBKEY_BUG code (which tolerates invalid -+ negative public key encodings) on by default, -+ NO_NEG_PUBKEY_BUG can be set to disable it. -+ [Steve Henson] -+ -+ *) New function c2i_ASN1_OBJECT() which acts on ASN1_OBJECT -+ content octets. An i2c_ASN1_OBJECT is unnecessary because -+ the encoding can be trivially obtained from the structure. -+ [Steve Henson] -+ -+ *) crypto/err.c locking bugfix: Use write locks (CRYPTO_w_[un]lock), -+ not read locks (CRYPTO_r_[un]lock). -+ [Bodo Moeller] -+ -+ *) A first attempt at creating official support for shared -+ libraries through configuration. I've kept it so the -+ default is static libraries only, and the OpenSSL programs -+ are always statically linked for now, but there are -+ preparations for dynamic linking in place. -+ This has been tested on Linux and Tru64. -+ [Richard Levitte] -+ -+ *) Randomness polling function for Win9x, as described in: -+ Peter Gutmann, Software Generation of Practically Strong -+ Random Numbers. -+ [Ulf Möller] -+ -+ *) Fix so PRNG is seeded in req if using an already existing -+ DSA key. -+ [Steve Henson] -+ -+ *) New options to smime application. -inform and -outform -+ allow alternative formats for the S/MIME message including -+ PEM and DER. The -content option allows the content to be -+ specified separately. This should allow things like Netscape -+ form signing output easier to verify. -+ [Steve Henson] -+ -+ *) Fix the ASN1 encoding of tags using the 'long form'. -+ [Steve Henson] -+ -+ *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT -+ STRING types. These convert content octets to and from the -+ underlying type. The actual tag and length octets are -+ already assumed to have been read in and checked. These -+ are needed because all other string types have virtually -+ identical handling apart from the tag. By having versions -+ of the ASN1 functions that just operate on content octets -+ IMPLICIT tagging can be handled properly. It also allows -+ the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED -+ and ASN1_INTEGER are identical apart from the tag. -+ [Steve Henson] -+ -+ *) Change the handling of OID objects as follows: -+ -+ - New object identifiers are inserted in objects.txt, following -+ the syntax given in objects.README. -+ - objects.pl is used to process obj_mac.num and create a new -+ obj_mac.h. -+ - obj_dat.pl is used to create a new obj_dat.h, using the data in -+ obj_mac.h. -+ -+ This is currently kind of a hack, and the perl code in objects.pl -+ isn't very elegant, but it works as I intended. The simplest way -+ to check that it worked correctly is to look in obj_dat.h and -+ check the array nid_objs and make sure the objects haven't moved -+ around (this is important!). Additions are OK, as well as -+ consistent name changes. -+ [Richard Levitte] -+ -+ *) Add BSD-style MD5-based passwords to 'openssl passwd' (option '-1'). -+ [Bodo Moeller] -+ -+ *) Addition of the command line parameter '-rand file' to 'openssl req'. -+ The given file adds to whatever has already been seeded into the -+ random pool through the RANDFILE configuration file option or -+ environment variable, or the default random state file. -+ [Richard Levitte] -+ -+ *) mkstack.pl now sorts each macro group into lexical order. -+ Previously the output order depended on the order the files -+ appeared in the directory, resulting in needless rewriting -+ of safestack.h . -+ [Steve Henson] -+ -+ *) Patches to make OpenSSL compile under Win32 again. Mostly -+ work arounds for the VC++ problem that it treats func() as -+ func(void). Also stripped out the parts of mkdef.pl that -+ added extra typesafe functions: these no longer exist. -+ [Steve Henson] -+ -+ *) Reorganisation of the stack code. The macros are now all -+ collected in safestack.h . Each macro is defined in terms of -+ a "stack macro" of the form SKM_(type, a, b). The -+ DEBUG_SAFESTACK is now handled in terms of function casts, -+ this has the advantage of retaining type safety without the -+ use of additional functions. If DEBUG_SAFESTACK is not defined -+ then the non typesafe macros are used instead. Also modified the -+ mkstack.pl script to handle the new form. Needs testing to see -+ if which (if any) compilers it chokes and maybe make DEBUG_SAFESTACK -+ the default if no major problems. Similar behaviour for ASN1_SET_OF -+ and PKCS12_STACK_OF. -+ [Steve Henson] -+ -+ *) When some versions of IIS use the 'NET' form of private key the -+ key derivation algorithm is different. Normally MD5(password) is -+ used as a 128 bit RC4 key. In the modified case -+ MD5(MD5(password) + "SGCKEYSALT") is used instead. Added some -+ new functions i2d_RSA_NET(), d2i_RSA_NET() etc which are the same -+ as the old Netscape_RSA functions except they have an additional -+ 'sgckey' parameter which uses the modified algorithm. Also added -+ an -sgckey command line option to the rsa utility. Thanks to -+ Adrian Peck for posting details of the modified -+ algorithm to openssl-dev. -+ [Steve Henson] -+ -+ *) The evp_local.h macros were using 'c.##kname' which resulted in -+ invalid expansion on some systems (SCO 5.0.5 for example). -+ Corrected to 'c.kname'. -+ [Phillip Porch ] -+ -+ *) New X509_get1_email() and X509_REQ_get1_email() functions that return -+ a STACK of email addresses from a certificate or request, these look -+ in the subject name and the subject alternative name extensions and -+ omit any duplicate addresses. -+ [Steve Henson] -+ -+ *) Re-implement BN_mod_exp2_mont using independent (and larger) windows. -+ This makes DSA verification about 2 % faster. -+ [Bodo Moeller] -+ -+ *) Increase maximum window size in BN_mod_exp_... to 6 bits instead of 5 -+ (meaning that now 2^5 values will be precomputed, which is only 4 KB -+ plus overhead for 1024 bit moduli). -+ This makes exponentiations about 0.5 % faster for 1024 bit -+ exponents (as measured by "openssl speed rsa2048"). -+ [Bodo Moeller] -+ -+ *) Rename memory handling macros to avoid conflicts with other -+ software: -+ Malloc => OPENSSL_malloc -+ Malloc_locked => OPENSSL_malloc_locked -+ Realloc => OPENSSL_realloc -+ Free => OPENSSL_free -+ [Richard Levitte] -+ -+ *) New function BN_mod_exp_mont_word for small bases (roughly 15% -+ faster than BN_mod_exp_mont, i.e. 7% for a full DH exchange). -+ [Bodo Moeller] -+ -+ *) CygWin32 support. -+ [John Jarvie ] -+ -+ *) The type-safe stack code has been rejigged. It is now only compiled -+ in when OpenSSL is configured with the DEBUG_SAFESTACK option and -+ by default all type-specific stack functions are "#define"d back to -+ standard stack functions. This results in more streamlined output -+ but retains the type-safety checking possibilities of the original -+ approach. -+ [Geoff Thorpe] -+ -+ *) The STACK code has been cleaned up, and certain type declarations -+ that didn't make a lot of sense have been brought in line. This has -+ also involved a cleanup of sorts in safestack.h to more correctly -+ map type-safe stack functions onto their plain stack counterparts. -+ This work has also resulted in a variety of "const"ifications of -+ lots of the code, especially "_cmp" operations which should normally -+ be prototyped with "const" parameters anyway. -+ [Geoff Thorpe] -+ -+ *) When generating bytes for the first time in md_rand.c, 'stir the pool' -+ by seeding with STATE_SIZE dummy bytes (with zero entropy count). -+ (The PRNG state consists of two parts, the large pool 'state' and 'md', -+ where all of 'md' is used each time the PRNG is used, but 'state' -+ is used only indexed by a cyclic counter. As entropy may not be -+ well distributed from the beginning, 'md' is important as a -+ chaining variable. However, the output function chains only half -+ of 'md', i.e. 80 bits. ssleay_rand_add, on the other hand, chains -+ all of 'md', and seeding with STATE_SIZE dummy bytes will result -+ in all of 'state' being rewritten, with the new values depending -+ on virtually all of 'md'. This overcomes the 80 bit limitation.) -+ [Bodo Moeller] -+ -+ *) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when -+ the handshake is continued after ssl_verify_cert_chain(); -+ otherwise, if SSL_VERIFY_NONE is set, remaining error codes -+ can lead to 'unexplainable' connection aborts later. -+ [Bodo Moeller; problem tracked down by Lutz Jaenicke] -+ -+ *) Major EVP API cipher revision. -+ Add hooks for extra EVP features. This allows various cipher -+ parameters to be set in the EVP interface. Support added for variable -+ key length ciphers via the EVP_CIPHER_CTX_set_key_length() function and -+ setting of RC2 and RC5 parameters. -+ -+ Modify EVP_OpenInit() and EVP_SealInit() to cope with variable key length -+ ciphers. -+ -+ Remove lots of duplicated code from the EVP library. For example *every* -+ cipher init() function handles the 'iv' in the same way according to the -+ cipher mode. They also all do nothing if the 'key' parameter is NULL and -+ for CFB and OFB modes they zero ctx->num. -+ -+ New functionality allows removal of S/MIME code RC2 hack. -+ -+ Most of the routines have the same form and so can be declared in terms -+ of macros. -+ -+ By shifting this to the top level EVP_CipherInit() it can be removed from -+ all individual ciphers. If the cipher wants to handle IVs or keys -+ differently it can set the EVP_CIPH_CUSTOM_IV or EVP_CIPH_ALWAYS_CALL_INIT -+ flags. -+ -+ Change lots of functions like EVP_EncryptUpdate() to now return a -+ value: although software versions of the algorithms cannot fail -+ any installed hardware versions can. -+ [Steve Henson] -+ -+ *) Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if -+ this option is set, tolerate broken clients that send the negotiated -+ protocol version number instead of the requested protocol version -+ number. -+ [Bodo Moeller] -+ -+ *) Call dh_tmp_cb (set by ..._TMP_DH_CB) with correct 'is_export' flag; -+ i.e. non-zero for export ciphersuites, zero otherwise. -+ Previous versions had this flag inverted, inconsistent with -+ rsa_tmp_cb (..._TMP_RSA_CB). -+ [Bodo Moeller; problem reported by Amit Chopra] -+ -+ *) Add missing DSA library text string. Work around for some IIS -+ key files with invalid SEQUENCE encoding. -+ [Steve Henson] -+ -+ *) Add a document (doc/standards.txt) that list all kinds of standards -+ and so on that are implemented in OpenSSL. -+ [Richard Levitte] -+ -+ *) Enhance c_rehash script. Old version would mishandle certificates -+ with the same subject name hash and wouldn't handle CRLs at all. -+ Added -fingerprint option to crl utility, to support new c_rehash -+ features. -+ [Steve Henson] -+ -+ *) Eliminate non-ANSI declarations in crypto.h and stack.h. -+ [Ulf Möller] -+ -+ *) Fix for SSL server purpose checking. Server checking was -+ rejecting certificates which had extended key usage present -+ but no ssl client purpose. -+ [Steve Henson, reported by Rene Grosser ] -+ -+ *) Make PKCS#12 code work with no password. The PKCS#12 spec -+ is a little unclear about how a blank password is handled. -+ Since the password in encoded as a BMPString with terminating -+ double NULL a zero length password would end up as just the -+ double NULL. However no password at all is different and is -+ handled differently in the PKCS#12 key generation code. NS -+ treats a blank password as zero length. MSIE treats it as no -+ password on export: but it will try both on import. We now do -+ the same: PKCS12_parse() tries zero length and no password if -+ the password is set to "" or NULL (NULL is now a valid password: -+ it wasn't before) as does the pkcs12 application. -+ [Steve Henson] -+ -+ *) Bugfixes in apps/x509.c: Avoid a memory leak; and don't use -+ perror when PEM_read_bio_X509_REQ fails, the error message must -+ be obtained from the error queue. -+ [Bodo Moeller] -+ -+ *) Avoid 'thread_hash' memory leak in crypto/err/err.c by freeing -+ it in ERR_remove_state if appropriate, and change ERR_get_state -+ accordingly to avoid race conditions (this is necessary because -+ thread_hash is no longer constant once set). -+ [Bodo Moeller] -+ -+ *) Bugfix for linux-elf makefile.one. -+ [Ulf Möller] -+ -+ *) RSA_get_default_method() will now cause a default -+ RSA_METHOD to be chosen if one doesn't exist already. -+ Previously this was only set during a call to RSA_new() -+ or RSA_new_method(NULL) meaning it was possible for -+ RSA_get_default_method() to return NULL. -+ [Geoff Thorpe] -+ -+ *) Added native name translation to the existing DSO code -+ that will convert (if the flag to do so is set) filenames -+ that are sufficiently small and have no path information -+ into a canonical native form. Eg. "blah" converted to -+ "libblah.so" or "blah.dll" etc. -+ [Geoff Thorpe] -+ -+ *) New function ERR_error_string_n(e, buf, len) which is like -+ ERR_error_string(e, buf), but writes at most 'len' bytes -+ including the 0 terminator. For ERR_error_string_n, 'buf' -+ may not be NULL. -+ [Damien Miller , Bodo Moeller] -+ -+ *) CONF library reworked to become more general. A new CONF -+ configuration file reader "class" is implemented as well as a -+ new functions (NCONF_*, for "New CONF") to handle it. The now -+ old CONF_* functions are still there, but are reimplemented to -+ work in terms of the new functions. Also, a set of functions -+ to handle the internal storage of the configuration data is -+ provided to make it easier to write new configuration file -+ reader "classes" (I can definitely see something reading a -+ configuration file in XML format, for example), called _CONF_*, -+ or "the configuration storage API"... -+ -+ The new configuration file reading functions are: -+ -+ NCONF_new, NCONF_free, NCONF_load, NCONF_load_fp, NCONF_load_bio, -+ NCONF_get_section, NCONF_get_string, NCONF_get_numbre -+ -+ NCONF_default, NCONF_WIN32 -+ -+ NCONF_dump_fp, NCONF_dump_bio -+ -+ NCONF_default and NCONF_WIN32 are method (or "class") choosers, -+ NCONF_new creates a new CONF object. This works in the same way -+ as other interfaces in OpenSSL, like the BIO interface. -+ NCONF_dump_* dump the internal storage of the configuration file, -+ which is useful for debugging. All other functions take the same -+ arguments as the old CONF_* functions wth the exception of the -+ first that must be a `CONF *' instead of a `LHASH *'. -+ -+ To make it easer to use the new classes with the old CONF_* functions, -+ the function CONF_set_default_method is provided. -+ [Richard Levitte] -+ -+ *) Add '-tls1' option to 'openssl ciphers', which was already -+ mentioned in the documentation but had not been implemented. -+ (This option is not yet really useful because even the additional -+ experimental TLS 1.0 ciphers are currently treated as SSL 3.0 ciphers.) -+ [Bodo Moeller] -+ -+ *) Initial DSO code added into libcrypto for letting OpenSSL (and -+ OpenSSL-based applications) load shared libraries and bind to -+ them in a portable way. -+ [Geoff Thorpe, with contributions from Richard Levitte] -+ -+ Changes between 0.9.5 and 0.9.5a [1 Apr 2000] -+ -+ *) Make sure _lrotl and _lrotr are only used with MSVC. -+ -+ *) Use lock CRYPTO_LOCK_RAND correctly in ssleay_rand_status -+ (the default implementation of RAND_status). -+ -+ *) Rename openssl x509 option '-crlext', which was added in 0.9.5, -+ to '-clrext' (= clear extensions), as intended and documented. -+ [Bodo Moeller; inconsistency pointed out by Michael Attili -+ ] -+ -+ *) Fix for HMAC. It wasn't zeroing the rest of the block if the key length -+ was larger than the MD block size. -+ [Steve Henson, pointed out by Yost William ] -+ -+ *) Modernise PKCS12_parse() so it uses STACK_OF(X509) for its ca argument -+ fix a leak when the ca argument was passed as NULL. Stop X509_PUBKEY_set() -+ using the passed key: if the passed key was a private key the result -+ of X509_print(), for example, would be to print out all the private key -+ components. -+ [Steve Henson] -+ -+ *) des_quad_cksum() byte order bug fix. -+ [Ulf Möller, using the problem description in krb4-0.9.7, where -+ the solution is attributed to Derrick J Brashear ] -+ -+ *) Fix so V_ASN1_APP_CHOOSE works again: however its use is strongly -+ discouraged. -+ [Steve Henson, pointed out by Brian Korver ] -+ -+ *) For easily testing in shell scripts whether some command -+ 'openssl XXX' exists, the new pseudo-command 'openssl no-XXX' -+ returns with exit code 0 iff no command of the given name is available. -+ 'no-XXX' is printed in this case, 'XXX' otherwise. In both cases, -+ the output goes to stdout and nothing is printed to stderr. -+ Additional arguments are always ignored. -+ -+ Since for each cipher there is a command of the same name, -+ the 'no-cipher' compilation switches can be tested this way. -+ -+ ('openssl no-XXX' is not able to detect pseudo-commands such -+ as 'quit', 'list-XXX-commands', or 'no-XXX' itself.) -+ [Bodo Moeller] -+ -+ *) Update test suite so that 'make test' succeeds in 'no-rsa' configuration. -+ [Bodo Moeller] -+ -+ *) For SSL_[CTX_]set_tmp_dh, don't create a DH key if SSL_OP_SINGLE_DH_USE -+ is set; it will be thrown away anyway because each handshake creates -+ its own key. -+ ssl_cert_dup, which is used by SSL_new, now copies DH keys in addition -+ to parameters -- in previous versions (since OpenSSL 0.9.3) the -+ 'default key' from SSL_CTX_set_tmp_dh would always be lost, meaning -+ you effectivly got SSL_OP_SINGLE_DH_USE when using this macro. -+ [Bodo Moeller] -+ -+ *) New s_client option -ign_eof: EOF at stdin is ignored, and -+ 'Q' and 'R' lose their special meanings (quit/renegotiate). -+ This is part of what -quiet does; unlike -quiet, -ign_eof -+ does not suppress any output. -+ [Richard Levitte] -+ -+ *) Add compatibility options to the purpose and trust code. The -+ purpose X509_PURPOSE_ANY is "any purpose" which automatically -+ accepts a certificate or CA, this was the previous behaviour, -+ with all the associated security issues. -+ -+ X509_TRUST_COMPAT is the old trust behaviour: only and -+ automatically trust self signed roots in certificate store. A -+ new trust setting X509_TRUST_DEFAULT is used to specify that -+ a purpose has no associated trust setting and it should instead -+ use the value in the default purpose. -+ [Steve Henson] -+ -+ *) Fix the PKCS#8 DSA private key code so it decodes keys again -+ and fix a memory leak. -+ [Steve Henson] -+ -+ *) In util/mkerr.pl (which implements 'make errors'), preserve -+ reason strings from the previous version of the .c file, as -+ the default to have only downcase letters (and digits) in -+ automatically generated reasons codes is not always appropriate. -+ [Bodo Moeller] -+ -+ *) In ERR_load_ERR_strings(), build an ERR_LIB_SYS error reason table -+ using strerror. Previously, ERR_reason_error_string() returned -+ library names as reason strings for SYSerr; but SYSerr is a special -+ case where small numbers are errno values, not library numbers. -+ [Bodo Moeller] -+ -+ *) Add '-dsaparam' option to 'openssl dhparam' application. This -+ converts DSA parameters into DH parameters. (When creating parameters, -+ DSA_generate_parameters is used.) -+ [Bodo Moeller] -+ -+ *) Include 'length' (recommended exponent length) in C code generated -+ by 'openssl dhparam -C'. -+ [Bodo Moeller] -+ -+ *) The second argument to set_label in perlasm was already being used -+ so couldn't be used as a "file scope" flag. Moved to third argument -+ which was free. -+ [Steve Henson] -+ -+ *) In PEM_ASN1_write_bio and some other functions, use RAND_pseudo_bytes -+ instead of RAND_bytes for encryption IVs and salts. -+ [Bodo Moeller] -+ -+ *) Include RAND_status() into RAND_METHOD instead of implementing -+ it only for md_rand.c Otherwise replacing the PRNG by calling -+ RAND_set_rand_method would be impossible. -+ [Bodo Moeller] -+ -+ *) Don't let DSA_generate_key() enter an infinite loop if the random -+ number generation fails. -+ [Bodo Moeller] -+ -+ *) New 'rand' application for creating pseudo-random output. -+ [Bodo Moeller] -+ -+ *) Added configuration support for Linux/IA64 -+ [Rolf Haberrecker ] -+ -+ *) Assembler module support for Mingw32. -+ [Ulf Möller] -+ -+ *) Shared library support for HPUX (in shlib/). -+ [Lutz Jaenicke and Anonymous] -+ -+ *) Shared library support for Solaris gcc. -+ [Lutz Behnke ] -+ -+ Changes between 0.9.4 and 0.9.5 [28 Feb 2000] -+ -+ *) PKCS7_encrypt() was adding text MIME headers twice because they -+ were added manually and by SMIME_crlf_copy(). -+ [Steve Henson] -+ -+ *) In bntest.c don't call BN_rand with zero bits argument. -+ [Steve Henson, pointed out by Andrew W. Gray ] -+ -+ *) BN_mul bugfix: In bn_mul_part_recursion() only the a>a[n] && b>b[n] -+ case was implemented. This caused BN_div_recp() to fail occasionally. -+ [Ulf Möller] -+ -+ *) Add an optional second argument to the set_label() in the perl -+ assembly language builder. If this argument exists and is set -+ to 1 it signals that the assembler should use a symbol whose -+ scope is the entire file, not just the current function. This -+ is needed with MASM which uses the format label:: for this scope. -+ [Steve Henson, pointed out by Peter Runestig ] -+ -+ *) Change the ASN1 types so they are typedefs by default. Before -+ almost all types were #define'd to ASN1_STRING which was causing -+ STACK_OF() problems: you couldn't declare STACK_OF(ASN1_UTF8STRING) -+ for example. -+ [Steve Henson] -+ -+ *) Change names of new functions to the new get1/get0 naming -+ convention: After 'get1', the caller owns a reference count -+ and has to call ..._free; 'get0' returns a pointer to some -+ data structure without incrementing reference counters. -+ (Some of the existing 'get' functions increment a reference -+ counter, some don't.) -+ Similarly, 'set1' and 'add1' functions increase reference -+ counters or duplicate objects. -+ [Steve Henson] -+ -+ *) Allow for the possibility of temp RSA key generation failure: -+ the code used to assume it always worked and crashed on failure. -+ [Steve Henson] -+ -+ *) Fix potential buffer overrun problem in BIO_printf(). -+ [Ulf Möller, using public domain code by Patrick Powell; problem -+ pointed out by David Sacerdote ] -+ -+ *) Support EGD . New functions -+ RAND_egd() and RAND_status(). In the command line application, -+ the EGD socket can be specified like a seed file using RANDFILE -+ or -rand. -+ [Ulf Möller] -+ -+ *) Allow the string CERTIFICATE to be tolerated in PKCS#7 structures. -+ Some CAs (e.g. Verisign) distribute certificates in this form. -+ [Steve Henson] -+ -+ *) Remove the SSL_ALLOW_ADH compile option and set the default cipher -+ list to exclude them. This means that no special compilation option -+ is needed to use anonymous DH: it just needs to be included in the -+ cipher list. -+ [Steve Henson] -+ -+ *) Change the EVP_MD_CTX_type macro so its meaning consistent with -+ EVP_MD_type. The old functionality is available in a new macro called -+ EVP_MD_md(). Change code that uses it and update docs. -+ [Steve Henson] -+ -+ *) ..._ctrl functions now have corresponding ..._callback_ctrl functions -+ where the 'void *' argument is replaced by a function pointer argument. -+ Previously 'void *' was abused to point to functions, which works on -+ many platforms, but is not correct. As these functions are usually -+ called by macros defined in OpenSSL header files, most source code -+ should work without changes. -+ [Richard Levitte] -+ -+ *) (which is created by Configure) now contains -+ sections with information on -D... compiler switches used for -+ compiling the library so that applications can see them. To enable -+ one of these sections, a pre-processor symbol OPENSSL_..._DEFINES -+ must be defined. E.g., -+ #define OPENSSL_ALGORITHM_DEFINES -+ #include -+ defines all pertinent NO_ symbols, such as NO_IDEA, NO_RSA, etc. -+ [Richard Levitte, Ulf and Bodo Möller] -+ -+ *) Bugfix: Tolerate fragmentation and interleaving in the SSL 3/TLS -+ record layer. -+ [Bodo Moeller] -+ -+ *) Change the 'other' type in certificate aux info to a STACK_OF -+ X509_ALGOR. Although not an AlgorithmIdentifier as such it has -+ the required ASN1 format: arbitrary types determined by an OID. -+ [Steve Henson] -+ -+ *) Add some PEM_write_X509_REQ_NEW() functions and a command line -+ argument to 'req'. This is not because the function is newer or -+ better than others it just uses the work 'NEW' in the certificate -+ request header lines. Some software needs this. -+ [Steve Henson] -+ -+ *) Reorganise password command line arguments: now passwords can be -+ obtained from various sources. Delete the PEM_cb function and make -+ it the default behaviour: i.e. if the callback is NULL and the -+ usrdata argument is not NULL interpret it as a null terminated pass -+ phrase. If usrdata and the callback are NULL then the pass phrase -+ is prompted for as usual. -+ [Steve Henson] -+ -+ *) Add support for the Compaq Atalla crypto accelerator. If it is installed, -+ the support is automatically enabled. The resulting binaries will -+ autodetect the card and use it if present. -+ [Ben Laurie and Compaq Inc.] -+ -+ *) Work around for Netscape hang bug. This sends certificate request -+ and server done in one record. Since this is perfectly legal in the -+ SSL/TLS protocol it isn't a "bug" option and is on by default. See -+ the bugs/SSLv3 entry for more info. -+ [Steve Henson] -+ -+ *) HP-UX tune-up: new unified configs, HP C compiler bug workaround. -+ [Andy Polyakov] -+ -+ *) Add -rand argument to smime and pkcs12 applications and read/write -+ of seed file. -+ [Steve Henson] -+ -+ *) New 'passwd' tool for crypt(3) and apr1 password hashes. -+ [Bodo Moeller] -+ -+ *) Add command line password options to the remaining applications. -+ [Steve Henson] -+ -+ *) Bug fix for BN_div_recp() for numerators with an even number of -+ bits. -+ [Ulf Möller] -+ -+ *) More tests in bntest.c, and changed test_bn output. -+ [Ulf Möller] -+ -+ *) ./config recognizes MacOS X now. -+ [Andy Polyakov] -+ -+ *) Bug fix for BN_div() when the first words of num and divsor are -+ equal (it gave wrong results if (rem=(n1-q*d0)&BN_MASK2) < d0). -+ [Ulf Möller] -+ -+ *) Add support for various broken PKCS#8 formats, and command line -+ options to produce them. -+ [Steve Henson] -+ -+ *) New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to -+ get temporary BIGNUMs from a BN_CTX. -+ [Ulf Möller] -+ -+ *) Correct return values in BN_mod_exp_mont() and BN_mod_exp2_mont() -+ for p == 0. -+ [Ulf Möller] -+ -+ *) Change the SSLeay_add_all_*() functions to OpenSSL_add_all_*() and -+ include a #define from the old name to the new. The original intent -+ was that statically linked binaries could for example just call -+ SSLeay_add_all_ciphers() to just add ciphers to the table and not -+ link with digests. This never worked because SSLeay_add_all_digests() -+ and SSLeay_add_all_ciphers() were in the same source file so calling -+ one would link with the other. They are now in separate source files. -+ [Steve Henson] -+ -+ *) Add a new -notext option to 'ca' and a -pubkey option to 'spkac'. -+ [Steve Henson] -+ -+ *) Use a less unusual form of the Miller-Rabin primality test (it used -+ a binary algorithm for exponentiation integrated into the Miller-Rabin -+ loop, our standard modexp algorithms are faster). -+ [Bodo Moeller] -+ -+ *) Support for the EBCDIC character set completed. -+ [Martin Kraemer ] -+ -+ *) Source code cleanups: use const where appropriate, eliminate casts, -+ use void * instead of char * in lhash. -+ [Ulf Möller] -+ -+ *) Bugfix: ssl3_send_server_key_exchange was not restartable -+ (the state was not changed to SSL3_ST_SW_KEY_EXCH_B, and because of -+ this the server could overwrite ephemeral keys that the client -+ has already seen). -+ [Bodo Moeller] -+ -+ *) Turn DSA_is_prime into a macro that calls BN_is_prime, -+ using 50 iterations of the Rabin-Miller test. -+ -+ DSA_generate_parameters now uses BN_is_prime_fasttest (with 50 -+ iterations of the Rabin-Miller test as required by the appendix -+ to FIPS PUB 186[-1]) instead of DSA_is_prime. -+ As BN_is_prime_fasttest includes trial division, DSA parameter -+ generation becomes much faster. -+ -+ This implies a change for the callback functions in DSA_is_prime -+ and DSA_generate_parameters: The callback function is called once -+ for each positive witness in the Rabin-Miller test, not just -+ occasionally in the inner loop; and the parameters to the -+ callback function now provide an iteration count for the outer -+ loop rather than for the current invocation of the inner loop. -+ DSA_generate_parameters additionally can call the callback -+ function with an 'iteration count' of -1, meaning that a -+ candidate has passed the trial division test (when q is generated -+ from an application-provided seed, trial division is skipped). -+ [Bodo Moeller] -+ -+ *) New function BN_is_prime_fasttest that optionally does trial -+ division before starting the Rabin-Miller test and has -+ an additional BN_CTX * argument (whereas BN_is_prime always -+ has to allocate at least one BN_CTX). -+ 'callback(1, -1, cb_arg)' is called when a number has passed the -+ trial division stage. -+ [Bodo Moeller] -+ -+ *) Fix for bug in CRL encoding. The validity dates weren't being handled -+ as ASN1_TIME. -+ [Steve Henson] -+ -+ *) New -pkcs12 option to CA.pl script to write out a PKCS#12 file. -+ [Steve Henson] -+ -+ *) New function BN_pseudo_rand(). -+ [Ulf Möller] -+ -+ *) Clean up BN_mod_mul_montgomery(): replace the broken (and unreadable) -+ bignum version of BN_from_montgomery() with the working code from -+ SSLeay 0.9.0 (the word based version is faster anyway), and clean up -+ the comments. -+ [Ulf Möller] -+ -+ *) Avoid a race condition in s2_clnt.c (function get_server_hello) that -+ made it impossible to use the same SSL_SESSION data structure in -+ SSL2 clients in multiple threads. -+ [Bodo Moeller] -+ -+ *) The return value of RAND_load_file() no longer counts bytes obtained -+ by stat(). RAND_load_file(..., -1) is new and uses the complete file -+ to seed the PRNG (previously an explicit byte count was required). -+ [Ulf Möller, Bodo Möller] -+ -+ *) Clean up CRYPTO_EX_DATA functions, some of these didn't have prototypes -+ used (char *) instead of (void *) and had casts all over the place. -+ [Steve Henson] -+ -+ *) Make BN_generate_prime() return NULL on error if ret!=NULL. -+ [Ulf Möller] -+ -+ *) Retain source code compatibility for BN_prime_checks macro: -+ BN_is_prime(..., BN_prime_checks, ...) now uses -+ BN_prime_checks_for_size to determine the appropriate number of -+ Rabin-Miller iterations. -+ [Ulf Möller] -+ -+ *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to -+ DH_CHECK_P_NOT_SAFE_PRIME. -+ (Check if this is true? OpenPGP calls them "strong".) -+ [Ulf Möller] -+ -+ *) Merge the functionality of "dh" and "gendh" programs into a new program -+ "dhparam". The old programs are retained for now but will handle DH keys -+ (instead of parameters) in future. -+ [Steve Henson] -+ -+ *) Make the ciphers, s_server and s_client programs check the return values -+ when a new cipher list is set. -+ [Steve Henson] -+ -+ *) Enhance the SSL/TLS cipher mechanism to correctly handle the TLS 56bit -+ ciphers. Before when the 56bit ciphers were enabled the sorting was -+ wrong. -+ -+ The syntax for the cipher sorting has been extended to support sorting by -+ cipher-strength (using the strength_bits hard coded in the tables). -+ The new command is "@STRENGTH" (see also doc/apps/ciphers.pod). -+ -+ Fix a bug in the cipher-command parser: when supplying a cipher command -+ string with an "undefined" symbol (neither command nor alphanumeric -+ [A-Za-z0-9], ssl_set_cipher_list used to hang in an endless loop. Now -+ an error is flagged. -+ -+ Due to the strength-sorting extension, the code of the -+ ssl_create_cipher_list() function was completely rearranged. I hope that -+ the readability was also increased :-) -+ [Lutz Jaenicke ] -+ -+ *) Minor change to 'x509' utility. The -CAcreateserial option now uses 1 -+ for the first serial number and places 2 in the serial number file. This -+ avoids problems when the root CA is created with serial number zero and -+ the first user certificate has the same issuer name and serial number -+ as the root CA. -+ [Steve Henson] -+ -+ *) Fixes to X509_ATTRIBUTE utilities, change the 'req' program so it uses -+ the new code. Add documentation for this stuff. -+ [Steve Henson] -+ -+ *) Changes to X509_ATTRIBUTE utilities. These have been renamed from -+ X509_*() to X509at_*() on the grounds that they don't handle X509 -+ structures and behave in an analogous way to the X509v3 functions: -+ they shouldn't be called directly but wrapper functions should be used -+ instead. -+ -+ So we also now have some wrapper functions that call the X509at functions -+ when passed certificate requests. (TO DO: similar things can be done with -+ PKCS#7 signed and unsigned attributes, PKCS#12 attributes and a few other -+ things. Some of these need some d2i or i2d and print functionality -+ because they handle more complex structures.) -+ [Steve Henson] -+ -+ *) Add missing #ifndefs that caused missing symbols when building libssl -+ as a shared library without RSA. Use #ifndef NO_SSL2 instead of -+ NO_RSA in ssl/s2*.c. -+ [Kris Kennaway , modified by Ulf Möller] -+ -+ *) Precautions against using the PRNG uninitialized: RAND_bytes() now -+ has a return value which indicates the quality of the random data -+ (1 = ok, 0 = not seeded). Also an error is recorded on the thread's -+ error queue. New function RAND_pseudo_bytes() generates output that is -+ guaranteed to be unique but not unpredictable. RAND_add is like -+ RAND_seed, but takes an extra argument for an entropy estimate -+ (RAND_seed always assumes full entropy). -+ [Ulf Möller] -+ -+ *) Do more iterations of Rabin-Miller probable prime test (specifically, -+ 3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes -+ instead of only 2 for all lengths; see BN_prime_checks_for_size definition -+ in crypto/bn/bn_prime.c for the complete table). This guarantees a -+ false-positive rate of at most 2^-80 for random input. -+ [Bodo Moeller] -+ -+ *) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs. -+ [Bodo Moeller] -+ -+ *) New function X509_CTX_rget_chain() (renamed to X509_CTX_get1_chain -+ in the 0.9.5 release), this returns the chain -+ from an X509_CTX structure with a dup of the stack and all -+ the X509 reference counts upped: so the stack will exist -+ after X509_CTX_cleanup() has been called. Modify pkcs12.c -+ to use this. -+ -+ Also make SSL_SESSION_print() print out the verify return -+ code. -+ [Steve Henson] -+ -+ *) Add manpage for the pkcs12 command. Also change the default -+ behaviour so MAC iteration counts are used unless the new -+ -nomaciter option is used. This improves file security and -+ only older versions of MSIE (4.0 for example) need it. -+ [Steve Henson] -+ -+ *) Honor the no-xxx Configure options when creating .DEF files. -+ [Ulf Möller] -+ -+ *) Add PKCS#10 attributes to field table: challengePassword, -+ unstructuredName and unstructuredAddress. These are taken from -+ draft PKCS#9 v2.0 but are compatible with v1.2 provided no -+ international characters are used. -+ -+ More changes to X509_ATTRIBUTE code: allow the setting of types -+ based on strings. Remove the 'loc' parameter when adding -+ attributes because these will be a SET OF encoding which is sorted -+ in ASN1 order. -+ [Steve Henson] -+ -+ *) Initial changes to the 'req' utility to allow request generation -+ automation. This will allow an application to just generate a template -+ file containing all the field values and have req construct the -+ request. -+ -+ Initial support for X509_ATTRIBUTE handling. Stacks of these are -+ used all over the place including certificate requests and PKCS#7 -+ structures. They are currently handled manually where necessary with -+ some primitive wrappers for PKCS#7. The new functions behave in a -+ manner analogous to the X509 extension functions: they allow -+ attributes to be looked up by NID and added. -+ -+ Later something similar to the X509V3 code would be desirable to -+ automatically handle the encoding, decoding and printing of the -+ more complex types. The string types like challengePassword can -+ be handled by the string table functions. -+ -+ Also modified the multi byte string table handling. Now there is -+ a 'global mask' which masks out certain types. The table itself -+ can use the flag STABLE_NO_MASK to ignore the mask setting: this -+ is useful when for example there is only one permissible type -+ (as in countryName) and using the mask might result in no valid -+ types at all. -+ [Steve Henson] -+ -+ *) Clean up 'Finished' handling, and add functions SSL_get_finished and -+ SSL_get_peer_finished to allow applications to obtain the latest -+ Finished messages sent to the peer or expected from the peer, -+ respectively. (SSL_get_peer_finished is usually the Finished message -+ actually received from the peer, otherwise the protocol will be aborted.) -+ -+ As the Finished message are message digests of the complete handshake -+ (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can -+ be used for external authentication procedures when the authentication -+ provided by SSL/TLS is not desired or is not enough. -+ [Bodo Moeller] -+ -+ *) Enhanced support for Alpha Linux is added. Now ./config checks if -+ the host supports BWX extension and if Compaq C is present on the -+ $PATH. Just exploiting of the BWX extension results in 20-30% -+ performance kick for some algorithms, e.g. DES and RC4 to mention -+ a couple. Compaq C in turn generates ~20% faster code for MD5 and -+ SHA1. -+ [Andy Polyakov] -+ -+ *) Add support for MS "fast SGC". This is arguably a violation of the -+ SSL3/TLS protocol. Netscape SGC does two handshakes: the first with -+ weak crypto and after checking the certificate is SGC a second one -+ with strong crypto. MS SGC stops the first handshake after receiving -+ the server certificate message and sends a second client hello. Since -+ a server will typically do all the time consuming operations before -+ expecting any further messages from the client (server key exchange -+ is the most expensive) there is little difference between the two. -+ -+ To get OpenSSL to support MS SGC we have to permit a second client -+ hello message after we have sent server done. In addition we have to -+ reset the MAC if we do get this second client hello. -+ [Steve Henson] -+ -+ *) Add a function 'd2i_AutoPrivateKey()' this will automatically decide -+ if a DER encoded private key is RSA or DSA traditional format. Changed -+ d2i_PrivateKey_bio() to use it. This is only needed for the "traditional" -+ format DER encoded private key. Newer code should use PKCS#8 format which -+ has the key type encoded in the ASN1 structure. Added DER private key -+ support to pkcs8 application. -+ [Steve Henson] -+ -+ *) SSL 3/TLS 1 servers now don't request certificates when an anonymous -+ ciphersuites has been selected (as required by the SSL 3/TLS 1 -+ specifications). Exception: When SSL_VERIFY_FAIL_IF_NO_PEER_CERT -+ is set, we interpret this as a request to violate the specification -+ (the worst that can happen is a handshake failure, and 'correct' -+ behaviour would result in a handshake failure anyway). -+ [Bodo Moeller] -+ -+ *) In SSL_CTX_add_session, take into account that there might be multiple -+ SSL_SESSION structures with the same session ID (e.g. when two threads -+ concurrently obtain them from an external cache). -+ The internal cache can handle only one SSL_SESSION with a given ID, -+ so if there's a conflict, we now throw out the old one to achieve -+ consistency. -+ [Bodo Moeller] -+ -+ *) Add OIDs for idea and blowfish in CBC mode. This will allow both -+ to be used in PKCS#5 v2.0 and S/MIME. Also add checking to -+ some routines that use cipher OIDs: some ciphers do not have OIDs -+ defined and so they cannot be used for S/MIME and PKCS#5 v2.0 for -+ example. -+ [Steve Henson] -+ -+ *) Simplify the trust setting structure and code. Now we just have -+ two sequences of OIDs for trusted and rejected settings. These will -+ typically have values the same as the extended key usage extension -+ and any application specific purposes. -+ -+ The trust checking code now has a default behaviour: it will just -+ check for an object with the same NID as the passed id. Functions can -+ be provided to override either the default behaviour or the behaviour -+ for a given id. SSL client, server and email already have functions -+ in place for compatibility: they check the NID and also return "trusted" -+ if the certificate is self signed. -+ [Steve Henson] -+ -+ *) Add d2i,i2d bio/fp functions for PrivateKey: these convert the -+ traditional format into an EVP_PKEY structure. -+ [Steve Henson] -+ -+ *) Add a password callback function PEM_cb() which either prompts for -+ a password if usr_data is NULL or otherwise assumes it is a null -+ terminated password. Allow passwords to be passed on command line -+ environment or config files in a few more utilities. -+ [Steve Henson] -+ -+ *) Add a bunch of DER and PEM functions to handle PKCS#8 format private -+ keys. Add some short names for PKCS#8 PBE algorithms and allow them -+ to be specified on the command line for the pkcs8 and pkcs12 utilities. -+ Update documentation. -+ [Steve Henson] -+ -+ *) Support for ASN1 "NULL" type. This could be handled before by using -+ ASN1_TYPE but there wasn't any function that would try to read a NULL -+ and produce an error if it couldn't. For compatibility we also have -+ ASN1_NULL_new() and ASN1_NULL_free() functions but these are faked and -+ don't allocate anything because they don't need to. -+ [Steve Henson] -+ -+ *) Initial support for MacOS is now provided. Examine INSTALL.MacOS -+ for details. -+ [Andy Polyakov, Roy Woods ] -+ -+ *) Rebuild of the memory allocation routines used by OpenSSL code and -+ possibly others as well. The purpose is to make an interface that -+ provide hooks so anyone can build a separate set of allocation and -+ deallocation routines to be used by OpenSSL, for example memory -+ pool implementations, or something else, which was previously hard -+ since Malloc(), Realloc() and Free() were defined as macros having -+ the values malloc, realloc and free, respectively (except for Win32 -+ compilations). The same is provided for memory debugging code. -+ OpenSSL already comes with functionality to find memory leaks, but -+ this gives people a chance to debug other memory problems. -+ -+ With these changes, a new set of functions and macros have appeared: -+ -+ CRYPTO_set_mem_debug_functions() [F] -+ CRYPTO_get_mem_debug_functions() [F] -+ CRYPTO_dbg_set_options() [F] -+ CRYPTO_dbg_get_options() [F] -+ CRYPTO_malloc_debug_init() [M] -+ -+ The memory debug functions are NULL by default, unless the library -+ is compiled with CRYPTO_MDEBUG or friends is defined. If someone -+ wants to debug memory anyway, CRYPTO_malloc_debug_init() (which -+ gives the standard debugging functions that come with OpenSSL) or -+ CRYPTO_set_mem_debug_functions() (tells OpenSSL to use functions -+ provided by the library user) must be used. When the standard -+ debugging functions are used, CRYPTO_dbg_set_options can be used to -+ request additional information: -+ CRYPTO_dbg_set_options(V_CYRPTO_MDEBUG_xxx) corresponds to setting -+ the CRYPTO_MDEBUG_xxx macro when compiling the library. -+ -+ Also, things like CRYPTO_set_mem_functions will always give the -+ expected result (the new set of functions is used for allocation -+ and deallocation) at all times, regardless of platform and compiler -+ options. -+ -+ To finish it up, some functions that were never use in any other -+ way than through macros have a new API and new semantic: -+ -+ CRYPTO_dbg_malloc() -+ CRYPTO_dbg_realloc() -+ CRYPTO_dbg_free() -+ -+ All macros of value have retained their old syntax. -+ [Richard Levitte and Bodo Moeller] -+ -+ *) Some S/MIME fixes. The OID for SMIMECapabilities was wrong, the -+ ordering of SMIMECapabilities wasn't in "strength order" and there -+ was a missing NULL in the AlgorithmIdentifier for the SHA1 signature -+ algorithm. -+ [Steve Henson] -+ -+ *) Some ASN1 types with illegal zero length encoding (INTEGER, -+ ENUMERATED and OBJECT IDENTIFIER) choked the ASN1 routines. -+ [Frans Heymans , modified by Steve Henson] -+ -+ *) Merge in my S/MIME library for OpenSSL. This provides a simple -+ S/MIME API on top of the PKCS#7 code, a MIME parser (with enough -+ functionality to handle multipart/signed properly) and a utility -+ called 'smime' to call all this stuff. This is based on code I -+ originally wrote for Celo who have kindly allowed it to be -+ included in OpenSSL. -+ [Steve Henson] -+ -+ *) Add variants des_set_key_checked and des_set_key_unchecked of -+ des_set_key (aka des_key_sched). Global variable des_check_key -+ decides which of these is called by des_set_key; this way -+ des_check_key behaves as it always did, but applications and -+ the library itself, which was buggy for des_check_key == 1, -+ have a cleaner way to pick the version they need. -+ [Bodo Moeller] -+ -+ *) New function PKCS12_newpass() which changes the password of a -+ PKCS12 structure. -+ [Steve Henson] -+ -+ *) Modify X509_TRUST and X509_PURPOSE so it also uses a static and -+ dynamic mix. In both cases the ids can be used as an index into the -+ table. Also modified the X509_TRUST_add() and X509_PURPOSE_add() -+ functions so they accept a list of the field values and the -+ application doesn't need to directly manipulate the X509_TRUST -+ structure. -+ [Steve Henson] -+ -+ *) Modify the ASN1_STRING_TABLE stuff so it also uses bsearch and doesn't -+ need initialising. -+ [Steve Henson] -+ -+ *) Modify the way the V3 extension code looks up extensions. This now -+ works in a similar way to the object code: we have some "standard" -+ extensions in a static table which is searched with OBJ_bsearch() -+ and the application can add dynamic ones if needed. The file -+ crypto/x509v3/ext_dat.h now has the info: this file needs to be -+ updated whenever a new extension is added to the core code and kept -+ in ext_nid order. There is a simple program 'tabtest.c' which checks -+ this. New extensions are not added too often so this file can readily -+ be maintained manually. -+ -+ There are two big advantages in doing things this way. The extensions -+ can be looked up immediately and no longer need to be "added" using -+ X509V3_add_standard_extensions(): this function now does nothing. -+ [Side note: I get *lots* of email saying the extension code doesn't -+ work because people forget to call this function] -+ Also no dynamic allocation is done unless new extensions are added: -+ so if we don't add custom extensions there is no need to call -+ X509V3_EXT_cleanup(). -+ [Steve Henson] -+ -+ *) Modify enc utility's salting as follows: make salting the default. Add a -+ magic header, so unsalted files fail gracefully instead of just decrypting -+ to garbage. This is because not salting is a big security hole, so people -+ should be discouraged from doing it. -+ [Ben Laurie] -+ -+ *) Fixes and enhancements to the 'x509' utility. It allowed a message -+ digest to be passed on the command line but it only used this -+ parameter when signing a certificate. Modified so all relevant -+ operations are affected by the digest parameter including the -+ -fingerprint and -x509toreq options. Also -x509toreq choked if a -+ DSA key was used because it didn't fix the digest. -+ [Steve Henson] -+ -+ *) Initial certificate chain verify code. Currently tests the untrusted -+ certificates for consistency with the verify purpose (which is set -+ when the X509_STORE_CTX structure is set up) and checks the pathlength. -+ -+ There is a NO_CHAIN_VERIFY compilation option to keep the old behaviour: -+ this is because it will reject chains with invalid extensions whereas -+ every previous version of OpenSSL and SSLeay made no checks at all. -+ -+ Trust code: checks the root CA for the relevant trust settings. Trust -+ settings have an initial value consistent with the verify purpose: e.g. -+ if the verify purpose is for SSL client use it expects the CA to be -+ trusted for SSL client use. However the default value can be changed to -+ permit custom trust settings: one example of this would be to only trust -+ certificates from a specific "secure" set of CAs. -+ -+ Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions -+ which should be used for version portability: especially since the -+ verify structure is likely to change more often now. -+ -+ SSL integration. Add purpose and trust to SSL_CTX and SSL and functions -+ to set them. If not set then assume SSL clients will verify SSL servers -+ and vice versa. -+ -+ Two new options to the verify program: -untrusted allows a set of -+ untrusted certificates to be passed in and -purpose which sets the -+ intended purpose of the certificate. If a purpose is set then the -+ new chain verify code is used to check extension consistency. -+ [Steve Henson] -+ -+ *) Support for the authority information access extension. -+ [Steve Henson] -+ -+ *) Modify RSA and DSA PEM read routines to transparently handle -+ PKCS#8 format private keys. New *_PUBKEY_* functions that handle -+ public keys in a format compatible with certificate -+ SubjectPublicKeyInfo structures. Unfortunately there were already -+ functions called *_PublicKey_* which used various odd formats so -+ these are retained for compatibility: however the DSA variants were -+ never in a public release so they have been deleted. Changed dsa/rsa -+ utilities to handle the new format: note no releases ever handled public -+ keys so we should be OK. -+ -+ The primary motivation for this change is to avoid the same fiasco -+ that dogs private keys: there are several incompatible private key -+ formats some of which are standard and some OpenSSL specific and -+ require various evil hacks to allow partial transparent handling and -+ even then it doesn't work with DER formats. Given the option anything -+ other than PKCS#8 should be dumped: but the other formats have to -+ stay in the name of compatibility. -+ -+ With public keys and the benefit of hindsight one standard format -+ is used which works with EVP_PKEY, RSA or DSA structures: though -+ it clearly returns an error if you try to read the wrong kind of key. -+ -+ Added a -pubkey option to the 'x509' utility to output the public key. -+ Also rename the EVP_PKEY_get_*() to EVP_PKEY_rget_*() -+ (renamed to EVP_PKEY_get1_*() in the OpenSSL 0.9.5 release) and add -+ EVP_PKEY_rset_*() functions (renamed to EVP_PKEY_set1_*()) -+ that do the same as the EVP_PKEY_assign_*() except they up the -+ reference count of the added key (they don't "swallow" the -+ supplied key). -+ [Steve Henson] -+ -+ *) Fixes to crypto/x509/by_file.c the code to read in certificates and -+ CRLs would fail if the file contained no certificates or no CRLs: -+ added a new function to read in both types and return the number -+ read: this means that if none are read it will be an error. The -+ DER versions of the certificate and CRL reader would always fail -+ because it isn't possible to mix certificates and CRLs in DER format -+ without choking one or the other routine. Changed this to just read -+ a certificate: this is the best we can do. Also modified the code -+ in apps/verify.c to take notice of return codes: it was previously -+ attempting to read in certificates from NULL pointers and ignoring -+ any errors: this is one reason why the cert and CRL reader seemed -+ to work. It doesn't check return codes from the default certificate -+ routines: these may well fail if the certificates aren't installed. -+ [Steve Henson] -+ -+ *) Code to support otherName option in GeneralName. -+ [Steve Henson] -+ -+ *) First update to verify code. Change the verify utility -+ so it warns if it is passed a self signed certificate: -+ for consistency with the normal behaviour. X509_verify -+ has been modified to it will now verify a self signed -+ certificate if *exactly* the same certificate appears -+ in the store: it was previously impossible to trust a -+ single self signed certificate. This means that: -+ openssl verify ss.pem -+ now gives a warning about a self signed certificate but -+ openssl verify -CAfile ss.pem ss.pem -+ is OK. -+ [Steve Henson] -+ -+ *) For servers, store verify_result in SSL_SESSION data structure -+ (and add it to external session representation). -+ This is needed when client certificate verifications fails, -+ but an application-provided verification callback (set by -+ SSL_CTX_set_cert_verify_callback) allows accepting the session -+ anyway (i.e. leaves x509_store_ctx->error != X509_V_OK -+ but returns 1): When the session is reused, we have to set -+ ssl->verify_result to the appropriate error code to avoid -+ security holes. -+ [Bodo Moeller, problem pointed out by Lutz Jaenicke] -+ -+ *) Fix a bug in the new PKCS#7 code: it didn't consider the -+ case in PKCS7_dataInit() where the signed PKCS7 structure -+ didn't contain any existing data because it was being created. -+ [Po-Cheng Chen , slightly modified by Steve Henson] -+ -+ *) Add a salt to the key derivation routines in enc.c. This -+ forms the first 8 bytes of the encrypted file. Also add a -+ -S option to allow a salt to be input on the command line. -+ [Steve Henson] -+ -+ *) New function X509_cmp(). Oddly enough there wasn't a function -+ to compare two certificates. We do this by working out the SHA1 -+ hash and comparing that. X509_cmp() will be needed by the trust -+ code. -+ [Steve Henson] -+ -+ *) SSL_get1_session() is like SSL_get_session(), but increments -+ the reference count in the SSL_SESSION returned. -+ [Geoff Thorpe ] -+ -+ *) Fix for 'req': it was adding a null to request attributes. -+ Also change the X509_LOOKUP and X509_INFO code to handle -+ certificate auxiliary information. -+ [Steve Henson] -+ -+ *) Add support for 40 and 64 bit RC2 and RC4 algorithms: document -+ the 'enc' command. -+ [Steve Henson] -+ -+ *) Add the possibility to add extra information to the memory leak -+ detecting output, to form tracebacks, showing from where each -+ allocation was originated: CRYPTO_push_info("constant string") adds -+ the string plus current file name and line number to a per-thread -+ stack, CRYPTO_pop_info() does the obvious, CRYPTO_remove_all_info() -+ is like calling CYRPTO_pop_info() until the stack is empty. -+ Also updated memory leak detection code to be multi-thread-safe. -+ [Richard Levitte] -+ -+ *) Add options -text and -noout to pkcs7 utility and delete the -+ encryption options which never did anything. Update docs. -+ [Steve Henson] -+ -+ *) Add options to some of the utilities to allow the pass phrase -+ to be included on either the command line (not recommended on -+ OSes like Unix) or read from the environment. Update the -+ manpages and fix a few bugs. -+ [Steve Henson] -+ -+ *) Add a few manpages for some of the openssl commands. -+ [Steve Henson] -+ -+ *) Fix the -revoke option in ca. It was freeing up memory twice, -+ leaking and not finding already revoked certificates. -+ [Steve Henson] -+ -+ *) Extensive changes to support certificate auxiliary information. -+ This involves the use of X509_CERT_AUX structure and X509_AUX -+ functions. An X509_AUX function such as PEM_read_X509_AUX() -+ can still read in a certificate file in the usual way but it -+ will also read in any additional "auxiliary information". By -+ doing things this way a fair degree of compatibility can be -+ retained: existing certificates can have this information added -+ using the new 'x509' options. -+ -+ Current auxiliary information includes an "alias" and some trust -+ settings. The trust settings will ultimately be used in enhanced -+ certificate chain verification routines: currently a certificate -+ can only be trusted if it is self signed and then it is trusted -+ for all purposes. -+ [Steve Henson] -+ -+ *) Fix assembler for Alpha (tested only on DEC OSF not Linux or *BSD). -+ The problem was that one of the replacement routines had not been working -+ since SSLeay releases. For now the offending routine has been replaced -+ with non-optimised assembler. Even so, this now gives around 95% -+ performance improvement for 1024 bit RSA signs. -+ [Mark Cox] -+ -+ *) Hack to fix PKCS#7 decryption when used with some unorthodox RC2 -+ handling. Most clients have the effective key size in bits equal to -+ the key length in bits: so a 40 bit RC2 key uses a 40 bit (5 byte) key. -+ A few however don't do this and instead use the size of the decrypted key -+ to determine the RC2 key length and the AlgorithmIdentifier to determine -+ the effective key length. In this case the effective key length can still -+ be 40 bits but the key length can be 168 bits for example. This is fixed -+ by manually forcing an RC2 key into the EVP_PKEY structure because the -+ EVP code can't currently handle unusual RC2 key sizes: it always assumes -+ the key length and effective key length are equal. -+ [Steve Henson] -+ -+ *) Add a bunch of functions that should simplify the creation of -+ X509_NAME structures. Now you should be able to do: -+ X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, "Steve", -1, -1, 0); -+ and have it automatically work out the correct field type and fill in -+ the structures. The more adventurous can try: -+ X509_NAME_add_entry_by_txt(nm, field, MBSTRING_UTF8, str, -1, -1, 0); -+ and it will (hopefully) work out the correct multibyte encoding. -+ [Steve Henson] -+ -+ *) Change the 'req' utility to use the new field handling and multibyte -+ copy routines. Before the DN field creation was handled in an ad hoc -+ way in req, ca, and x509 which was rather broken and didn't support -+ BMPStrings or UTF8Strings. Since some software doesn't implement -+ BMPStrings or UTF8Strings yet, they can be enabled using the config file -+ using the dirstring_type option. See the new comment in the default -+ openssl.cnf for more info. -+ [Steve Henson] -+ -+ *) Make crypto/rand/md_rand.c more robust: -+ - Assure unique random numbers after fork(). -+ - Make sure that concurrent threads access the global counter and -+ md serializably so that we never lose entropy in them -+ or use exactly the same state in multiple threads. -+ Access to the large state is not always serializable because -+ the additional locking could be a performance killer, and -+ md should be large enough anyway. -+ [Bodo Moeller] -+ -+ *) New file apps/app_rand.c with commonly needed functionality -+ for handling the random seed file. -+ -+ Use the random seed file in some applications that previously did not: -+ ca, -+ dsaparam -genkey (which also ignored its '-rand' option), -+ s_client, -+ s_server, -+ x509 (when signing). -+ Except on systems with /dev/urandom, it is crucial to have a random -+ seed file at least for key creation, DSA signing, and for DH exchanges; -+ for RSA signatures we could do without one. -+ -+ gendh and gendsa (unlike genrsa) used to read only the first byte -+ of each file listed in the '-rand' option. The function as previously -+ found in genrsa is now in app_rand.c and is used by all programs -+ that support '-rand'. -+ [Bodo Moeller] -+ -+ *) In RAND_write_file, use mode 0600 for creating files; -+ don't just chmod when it may be too late. -+ [Bodo Moeller] -+ -+ *) Report an error from X509_STORE_load_locations -+ when X509_LOOKUP_load_file or X509_LOOKUP_add_dir failed. -+ [Bill Perry] -+ -+ *) New function ASN1_mbstring_copy() this copies a string in either -+ ASCII, Unicode, Universal (4 bytes per character) or UTF8 format -+ into an ASN1_STRING type. A mask of permissible types is passed -+ and it chooses the "minimal" type to use or an error if not type -+ is suitable. -+ [Steve Henson] -+ -+ *) Add function equivalents to the various macros in asn1.h. The old -+ macros are retained with an M_ prefix. Code inside the library can -+ use the M_ macros. External code (including the openssl utility) -+ should *NOT* in order to be "shared library friendly". -+ [Steve Henson] -+ -+ *) Add various functions that can check a certificate's extensions -+ to see if it usable for various purposes such as SSL client, -+ server or S/MIME and CAs of these types. This is currently -+ VERY EXPERIMENTAL but will ultimately be used for certificate chain -+ verification. Also added a -purpose flag to x509 utility to -+ print out all the purposes. -+ [Steve Henson] -+ -+ *) Add a CRYPTO_EX_DATA to X509 certificate structure and associated -+ functions. -+ [Steve Henson] -+ -+ *) New X509V3_{X509,CRL,REVOKED}_get_d2i() functions. These will search -+ for, obtain and decode and extension and obtain its critical flag. -+ This allows all the necessary extension code to be handled in a -+ single function call. -+ [Steve Henson] -+ -+ *) RC4 tune-up featuring 30-40% performance improvement on most RISC -+ platforms. See crypto/rc4/rc4_enc.c for further details. -+ [Andy Polyakov] -+ -+ *) New -noout option to asn1parse. This causes no output to be produced -+ its main use is when combined with -strparse and -out to extract data -+ from a file (which may not be in ASN.1 format). -+ [Steve Henson] -+ -+ *) Fix for pkcs12 program. It was hashing an invalid certificate pointer -+ when producing the local key id. -+ [Richard Levitte ] -+ -+ *) New option -dhparam in s_server. This allows a DH parameter file to be -+ stated explicitly. If it is not stated then it tries the first server -+ certificate file. The previous behaviour hard coded the filename -+ "server.pem". -+ [Steve Henson] -+ -+ *) Add -pubin and -pubout options to the rsa and dsa commands. These allow -+ a public key to be input or output. For example: -+ openssl rsa -in key.pem -pubout -out pubkey.pem -+ Also added necessary DSA public key functions to handle this. -+ [Steve Henson] -+ -+ *) Fix so PKCS7_dataVerify() doesn't crash if no certificates are contained -+ in the message. This was handled by allowing -+ X509_find_by_issuer_and_serial() to tolerate a NULL passed to it. -+ [Steve Henson, reported by Sampo Kellomaki ] -+ -+ *) Fix for bug in d2i_ASN1_bytes(): other ASN1 functions add an extra null -+ to the end of the strings whereas this didn't. This would cause problems -+ if strings read with d2i_ASN1_bytes() were later modified. -+ [Steve Henson, reported by Arne Ansper ] -+ -+ *) Fix for base64 decode bug. When a base64 bio reads only one line of -+ data and it contains EOF it will end up returning an error. This is -+ caused by input 46 bytes long. The cause is due to the way base64 -+ BIOs find the start of base64 encoded data. They do this by trying a -+ trial decode on each line until they find one that works. When they -+ do a flag is set and it starts again knowing it can pass all the -+ data directly through the decoder. Unfortunately it doesn't reset -+ the context it uses. This means that if EOF is reached an attempt -+ is made to pass two EOFs through the context and this causes the -+ resulting error. This can also cause other problems as well. As is -+ usual with these problems it takes *ages* to find and the fix is -+ trivial: move one line. -+ [Steve Henson, reported by ian@uns.ns.ac.yu (Ivan Nejgebauer) ] -+ -+ *) Ugly workaround to get s_client and s_server working under Windows. The -+ old code wouldn't work because it needed to select() on sockets and the -+ tty (for keypresses and to see if data could be written). Win32 only -+ supports select() on sockets so we select() with a 1s timeout on the -+ sockets and then see if any characters are waiting to be read, if none -+ are present then we retry, we also assume we can always write data to -+ the tty. This isn't nice because the code then blocks until we've -+ received a complete line of data and it is effectively polling the -+ keyboard at 1s intervals: however it's quite a bit better than not -+ working at all :-) A dedicated Windows application might handle this -+ with an event loop for example. -+ [Steve Henson] -+ -+ *) Enhance RSA_METHOD structure. Now there are two extra methods, rsa_sign -+ and rsa_verify. When the RSA_FLAGS_SIGN_VER option is set these functions -+ will be called when RSA_sign() and RSA_verify() are used. This is useful -+ if rsa_pub_dec() and rsa_priv_enc() equivalents are not available. -+ For this to work properly RSA_public_decrypt() and RSA_private_encrypt() -+ should *not* be used: RSA_sign() and RSA_verify() must be used instead. -+ This necessitated the support of an extra signature type NID_md5_sha1 -+ for SSL signatures and modifications to the SSL library to use it instead -+ of calling RSA_public_decrypt() and RSA_private_encrypt(). -+ [Steve Henson] -+ -+ *) Add new -verify -CAfile and -CApath options to the crl program, these -+ will lookup a CRL issuers certificate and verify the signature in a -+ similar way to the verify program. Tidy up the crl program so it -+ no longer accesses structures directly. Make the ASN1 CRL parsing a bit -+ less strict. It will now permit CRL extensions even if it is not -+ a V2 CRL: this will allow it to tolerate some broken CRLs. -+ [Steve Henson] -+ -+ *) Initialize all non-automatic variables each time one of the openssl -+ sub-programs is started (this is necessary as they may be started -+ multiple times from the "OpenSSL>" prompt). -+ [Lennart Bang, Bodo Moeller] -+ -+ *) Preliminary compilation option RSA_NULL which disables RSA crypto without -+ removing all other RSA functionality (this is what NO_RSA does). This -+ is so (for example) those in the US can disable those operations covered -+ by the RSA patent while allowing storage and parsing of RSA keys and RSA -+ key generation. -+ [Steve Henson] -+ -+ *) Non-copying interface to BIO pairs. -+ (still largely untested) -+ [Bodo Moeller] -+ -+ *) New function ANS1_tag2str() to convert an ASN1 tag to a descriptive -+ ASCII string. This was handled independently in various places before. -+ [Steve Henson] -+ -+ *) New functions UTF8_getc() and UTF8_putc() that parse and generate -+ UTF8 strings a character at a time. -+ [Steve Henson] -+ -+ *) Use client_version from client hello to select the protocol -+ (s23_srvr.c) and for RSA client key exchange verification -+ (s3_srvr.c), as required by the SSL 3.0/TLS 1.0 specifications. -+ [Bodo Moeller] -+ -+ *) Add various utility functions to handle SPKACs, these were previously -+ handled by poking round in the structure internals. Added new function -+ NETSCAPE_SPKI_print() to print out SPKAC and a new utility 'spkac' to -+ print, verify and generate SPKACs. Based on an original idea from -+ Massimiliano Pala but extensively modified. -+ [Steve Henson] -+ -+ *) RIPEMD160 is operational on all platforms and is back in 'make test'. -+ [Andy Polyakov] -+ -+ *) Allow the config file extension section to be overwritten on the -+ command line. Based on an original idea from Massimiliano Pala -+ . The new option is called -extensions -+ and can be applied to ca, req and x509. Also -reqexts to override -+ the request extensions in req and -crlexts to override the crl extensions -+ in ca. -+ [Steve Henson] -+ -+ *) Add new feature to the SPKAC handling in ca. Now you can include -+ the same field multiple times by preceding it by "XXXX." for example: -+ 1.OU="Unit name 1" -+ 2.OU="Unit name 2" -+ this is the same syntax as used in the req config file. -+ [Steve Henson] -+ -+ *) Allow certificate extensions to be added to certificate requests. These -+ are specified in a 'req_extensions' option of the req section of the -+ config file. They can be printed out with the -text option to req but -+ are otherwise ignored at present. -+ [Steve Henson] -+ -+ *) Fix a horrible bug in enc_read() in crypto/evp/bio_enc.c: if the first -+ data read consists of only the final block it would not decrypted because -+ EVP_CipherUpdate() would correctly report zero bytes had been decrypted. -+ A misplaced 'break' also meant the decrypted final block might not be -+ copied until the next read. -+ [Steve Henson] -+ -+ *) Initial support for DH_METHOD. Again based on RSA_METHOD. Also added -+ a few extra parameters to the DH structure: these will be useful if -+ for example we want the value of 'q' or implement X9.42 DH. -+ [Steve Henson] -+ -+ *) Initial support for DSA_METHOD. This is based on the RSA_METHOD and -+ provides hooks that allow the default DSA functions or functions on a -+ "per key" basis to be replaced. This allows hardware acceleration and -+ hardware key storage to be handled without major modification to the -+ library. Also added low level modexp hooks and CRYPTO_EX structure and -+ associated functions. -+ [Steve Henson] -+ -+ *) Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO -+ as "read only": it can't be written to and the buffer it points to will -+ not be freed. Reading from a read only BIO is much more efficient than -+ a normal memory BIO. This was added because there are several times when -+ an area of memory needs to be read from a BIO. The previous method was -+ to create a memory BIO and write the data to it, this results in two -+ copies of the data and an O(n^2) reading algorithm. There is a new -+ function BIO_new_mem_buf() which creates a read only memory BIO from -+ an area of memory. Also modified the PKCS#7 routines to use read only -+ memory BIOs. -+ [Steve Henson] -+ -+ *) Bugfix: ssl23_get_client_hello did not work properly when called in -+ state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of -+ a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read, -+ but a retry condition occurred while trying to read the rest. -+ [Bodo Moeller] -+ -+ *) The PKCS7_ENC_CONTENT_new() function was setting the content type as -+ NID_pkcs7_encrypted by default: this was wrong since this should almost -+ always be NID_pkcs7_data. Also modified the PKCS7_set_type() to handle -+ the encrypted data type: this is a more sensible place to put it and it -+ allows the PKCS#12 code to be tidied up that duplicated this -+ functionality. -+ [Steve Henson] -+ -+ *) Changed obj_dat.pl script so it takes its input and output files on -+ the command line. This should avoid shell escape redirection problems -+ under Win32. -+ [Steve Henson] -+ -+ *) Initial support for certificate extension requests, these are included -+ in things like Xenroll certificate requests. Included functions to allow -+ extensions to be obtained and added. -+ [Steve Henson] -+ -+ *) -crlf option to s_client and s_server for sending newlines as -+ CRLF (as required by many protocols). -+ [Bodo Moeller] -+ -+ Changes between 0.9.3a and 0.9.4 [09 Aug 1999] -+ -+ *) Install libRSAglue.a when OpenSSL is built with RSAref. -+ [Ralf S. Engelschall] -+ -+ *) A few more ``#ifndef NO_FP_API / #endif'' pairs for consistency. -+ [Andrija Antonijevic ] -+ -+ *) Fix -startdate and -enddate (which was missing) arguments to 'ca' -+ program. -+ [Steve Henson] -+ -+ *) New function DSA_dup_DH, which duplicates DSA parameters/keys as -+ DH parameters/keys (q is lost during that conversion, but the resulting -+ DH parameters contain its length). -+ -+ For 1024-bit p, DSA_generate_parameters followed by DSA_dup_DH is -+ much faster than DH_generate_parameters (which creates parameters -+ where p = 2*q + 1), and also the smaller q makes DH computations -+ much more efficient (160-bit exponentiation instead of 1024-bit -+ exponentiation); so this provides a convenient way to support DHE -+ ciphersuites in SSL/TLS servers (see ssl/ssltest.c). It is of -+ utter importance to use -+ SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); -+ or -+ SSL_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); -+ when such DH parameters are used, because otherwise small subgroup -+ attacks may become possible! -+ [Bodo Moeller] -+ -+ *) Avoid memory leak in i2d_DHparams. -+ [Bodo Moeller] -+ -+ *) Allow the -k option to be used more than once in the enc program: -+ this allows the same encrypted message to be read by multiple recipients. -+ [Steve Henson] -+ -+ *) New function OBJ_obj2txt(buf, buf_len, a, no_name), this converts -+ an ASN1_OBJECT to a text string. If the "no_name" parameter is set then -+ it will always use the numerical form of the OID, even if it has a short -+ or long name. -+ [Steve Henson] -+ -+ *) Added an extra RSA flag: RSA_FLAG_EXT_PKEY. Previously the rsa_mod_exp -+ method only got called if p,q,dmp1,dmq1,iqmp components were present, -+ otherwise bn_mod_exp was called. In the case of hardware keys for example -+ no private key components need be present and it might store extra data -+ in the RSA structure, which cannot be accessed from bn_mod_exp. -+ By setting RSA_FLAG_EXT_PKEY rsa_mod_exp will always be called for -+ private key operations. -+ [Steve Henson] -+ -+ *) Added support for SPARC Linux. -+ [Andy Polyakov] -+ -+ *) pem_password_cb function type incompatibly changed from -+ typedef int pem_password_cb(char *buf, int size, int rwflag); -+ to -+ ....(char *buf, int size, int rwflag, void *userdata); -+ so that applications can pass data to their callbacks: -+ The PEM[_ASN1]_{read,write}... functions and macros now take an -+ additional void * argument, which is just handed through whenever -+ the password callback is called. -+ [Damien Miller ; tiny changes by Bodo Moeller] -+ -+ New function SSL_CTX_set_default_passwd_cb_userdata. -+ -+ Compatibility note: As many C implementations push function arguments -+ onto the stack in reverse order, the new library version is likely to -+ interoperate with programs that have been compiled with the old -+ pem_password_cb definition (PEM_whatever takes some data that -+ happens to be on the stack as its last argument, and the callback -+ just ignores this garbage); but there is no guarantee whatsoever that -+ this will work. -+ -+ *) The -DPLATFORM="\"$(PLATFORM)\"" definition and the similar -DCFLAGS=... -+ (both in crypto/Makefile.ssl for use by crypto/cversion.c) caused -+ problems not only on Windows, but also on some Unix platforms. -+ To avoid problematic command lines, these definitions are now in an -+ auto-generated file crypto/buildinf.h (created by crypto/Makefile.ssl -+ for standard "make" builds, by util/mk1mf.pl for "mk1mf" builds). -+ [Bodo Moeller] -+ -+ *) MIPS III/IV assembler module is reimplemented. -+ [Andy Polyakov] -+ -+ *) More DES library cleanups: remove references to srand/rand and -+ delete an unused file. -+ [Ulf Möller] -+ -+ *) Add support for the the free Netwide assembler (NASM) under Win32, -+ since not many people have MASM (ml) and it can be hard to obtain. -+ This is currently experimental but it seems to work OK and pass all -+ the tests. Check out INSTALL.W32 for info. -+ [Steve Henson] -+ -+ *) Fix memory leaks in s3_clnt.c: All non-anonymous SSL3/TLS1 connections -+ without temporary keys kept an extra copy of the server key, -+ and connections with temporary keys did not free everything in case -+ of an error. -+ [Bodo Moeller] -+ -+ *) New function RSA_check_key and new openssl rsa option -check -+ for verifying the consistency of RSA keys. -+ [Ulf Moeller, Bodo Moeller] -+ -+ *) Various changes to make Win32 compile work: -+ 1. Casts to avoid "loss of data" warnings in p5_crpt2.c -+ 2. Change unsigned int to int in b_dump.c to avoid "signed/unsigned -+ comparison" warnings. -+ 3. Add sk__sort to DEF file generator and do make update. -+ [Steve Henson] -+ -+ *) Add a debugging option to PKCS#5 v2 key generation function: when -+ you #define DEBUG_PKCS5V2 passwords, salts, iteration counts and -+ derived keys are printed to stderr. -+ [Steve Henson] -+ -+ *) Copy the flags in ASN1_STRING_dup(). -+ [Roman E. Pavlov ] -+ -+ *) The x509 application mishandled signing requests containing DSA -+ keys when the signing key was also DSA and the parameters didn't match. -+ -+ It was supposed to omit the parameters when they matched the signing key: -+ the verifying software was then supposed to automatically use the CA's -+ parameters if they were absent from the end user certificate. -+ -+ Omitting parameters is no longer recommended. The test was also -+ the wrong way round! This was probably due to unusual behaviour in -+ EVP_cmp_parameters() which returns 1 if the parameters match. -+ This meant that parameters were omitted when they *didn't* match and -+ the certificate was useless. Certificates signed with 'ca' didn't have -+ this bug. -+ [Steve Henson, reported by Doug Erickson ] -+ -+ *) Memory leak checking (-DCRYPTO_MDEBUG) had some problems. -+ The interface is as follows: -+ Applications can use -+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) aka MemCheck_start(), -+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) aka MemCheck_stop(); -+ "off" is now the default. -+ The library internally uses -+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) aka MemCheck_off(), -+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) aka MemCheck_on() -+ to disable memory-checking temporarily. -+ -+ Some inconsistent states that previously were possible (and were -+ even the default) are now avoided. -+ -+ -DCRYPTO_MDEBUG_TIME is new and additionally stores the current time -+ with each memory chunk allocated; this is occasionally more helpful -+ than just having a counter. -+ -+ -DCRYPTO_MDEBUG_THREAD is also new and adds the thread ID. -+ -+ -DCRYPTO_MDEBUG_ALL enables all of the above, plus any future -+ extensions. -+ [Bodo Moeller] -+ -+ *) Introduce "mode" for SSL structures (with defaults in SSL_CTX), -+ which largely parallels "options", but is for changing API behaviour, -+ whereas "options" are about protocol behaviour. -+ Initial "mode" flags are: -+ -+ SSL_MODE_ENABLE_PARTIAL_WRITE Allow SSL_write to report success when -+ a single record has been written. -+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER Don't insist that SSL_write -+ retries use the same buffer location. -+ (But all of the contents must be -+ copied!) -+ [Bodo Moeller] -+ -+ *) Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options -+ worked. -+ -+ *) Fix problems with no-hmac etc. -+ [Ulf Möller, pointed out by Brian Wellington ] -+ -+ *) New functions RSA_get_default_method(), RSA_set_method() and -+ RSA_get_method(). These allows replacement of RSA_METHODs without having -+ to mess around with the internals of an RSA structure. -+ [Steve Henson] -+ -+ *) Fix memory leaks in DSA_do_sign and DSA_is_prime. -+ Also really enable memory leak checks in openssl.c and in some -+ test programs. -+ [Chad C. Mulligan, Bodo Moeller] -+ -+ *) Fix a bug in d2i_ASN1_INTEGER() and i2d_ASN1_INTEGER() which can mess -+ up the length of negative integers. This has now been simplified to just -+ store the length when it is first determined and use it later, rather -+ than trying to keep track of where data is copied and updating it to -+ point to the end. -+ [Steve Henson, reported by Brien Wheeler -+ ] -+ -+ *) Add a new function PKCS7_signatureVerify. This allows the verification -+ of a PKCS#7 signature but with the signing certificate passed to the -+ function itself. This contrasts with PKCS7_dataVerify which assumes the -+ certificate is present in the PKCS#7 structure. This isn't always the -+ case: certificates can be omitted from a PKCS#7 structure and be -+ distributed by "out of band" means (such as a certificate database). -+ [Steve Henson] -+ -+ *) Complete the PEM_* macros with DECLARE_PEM versions to replace the -+ function prototypes in pem.h, also change util/mkdef.pl to add the -+ necessary function names. -+ [Steve Henson] -+ -+ *) mk1mf.pl (used by Windows builds) did not properly read the -+ options set by Configure in the top level Makefile, and Configure -+ was not even able to write more than one option correctly. -+ Fixed, now "no-idea no-rc5 -DCRYPTO_MDEBUG" etc. works as intended. -+ [Bodo Moeller] -+ -+ *) New functions CONF_load_bio() and CONF_load_fp() to allow a config -+ file to be loaded from a BIO or FILE pointer. The BIO version will -+ for example allow memory BIOs to contain config info. -+ [Steve Henson] -+ -+ *) New function "CRYPTO_num_locks" that returns CRYPTO_NUM_LOCKS. -+ Whoever hopes to achieve shared-library compatibility across versions -+ must use this, not the compile-time macro. -+ (Exercise 0.9.4: Which is the minimum library version required by -+ such programs?) -+ Note: All this applies only to multi-threaded programs, others don't -+ need locks. -+ [Bodo Moeller] -+ -+ *) Add missing case to s3_clnt.c state machine -- one of the new SSL tests -+ through a BIO pair triggered the default case, i.e. -+ SSLerr(...,SSL_R_UNKNOWN_STATE). -+ [Bodo Moeller] -+ -+ *) New "BIO pair" concept (crypto/bio/bss_bio.c) so that applications -+ can use the SSL library even if none of the specific BIOs is -+ appropriate. -+ [Bodo Moeller] -+ -+ *) Fix a bug in i2d_DSAPublicKey() which meant it returned the wrong value -+ for the encoded length. -+ [Jeon KyoungHo ] -+ -+ *) Add initial documentation of the X509V3 functions. -+ [Steve Henson] -+ -+ *) Add a new pair of functions PEM_write_PKCS8PrivateKey() and -+ PEM_write_bio_PKCS8PrivateKey() that are equivalent to -+ PEM_write_PrivateKey() and PEM_write_bio_PrivateKey() but use the more -+ secure PKCS#8 private key format with a high iteration count. -+ [Steve Henson] -+ -+ *) Fix determination of Perl interpreter: A perl or perl5 -+ _directory_ in $PATH was also accepted as the interpreter. -+ [Ralf S. Engelschall] -+ -+ *) Fix demos/sign/sign.c: well there wasn't anything strictly speaking -+ wrong with it but it was very old and did things like calling -+ PEM_ASN1_read() directly and used MD5 for the hash not to mention some -+ unusual formatting. -+ [Steve Henson] -+ -+ *) Fix demos/selfsign.c: it used obsolete and deleted functions, changed -+ to use the new extension code. -+ [Steve Henson] -+ -+ *) Implement the PEM_read/PEM_write functions in crypto/pem/pem_all.c -+ with macros. This should make it easier to change their form, add extra -+ arguments etc. Fix a few PEM prototypes which didn't have cipher as a -+ constant. -+ [Steve Henson] -+ -+ *) Add to configuration table a new entry that can specify an alternative -+ name for unistd.h (for pre-POSIX systems); we need this for NeXTstep, -+ according to Mark Crispin . -+ [Bodo Moeller] -+ -+#if 0 -+ *) DES CBC did not update the IV. Weird. -+ [Ben Laurie] -+#else -+ des_cbc_encrypt does not update the IV, but des_ncbc_encrypt does. -+ Changing the behaviour of the former might break existing programs -- -+ where IV updating is needed, des_ncbc_encrypt can be used. -+#endif -+ -+ *) When bntest is run from "make test" it drives bc to check its -+ calculations, as well as internally checking them. If an internal check -+ fails, it needs to cause bc to give a non-zero result or make test carries -+ on without noticing the failure. Fixed. -+ [Ben Laurie] -+ -+ *) DES library cleanups. -+ [Ulf Möller] -+ -+ *) Add support for PKCS#5 v2.0 PBE algorithms. This will permit PKCS#8 to be -+ used with any cipher unlike PKCS#5 v1.5 which can at most handle 64 bit -+ ciphers. NOTE: although the key derivation function has been verified -+ against some published test vectors it has not been extensively tested -+ yet. Added a -v2 "cipher" option to pkcs8 application to allow the use -+ of v2.0. -+ [Steve Henson] -+ -+ *) Instead of "mkdir -p", which is not fully portable, use new -+ Perl script "util/mkdir-p.pl". -+ [Bodo Moeller] -+ -+ *) Rewrite the way password based encryption (PBE) is handled. It used to -+ assume that the ASN1 AlgorithmIdentifier parameter was a PBEParameter -+ structure. This was true for the PKCS#5 v1.5 and PKCS#12 PBE algorithms -+ but doesn't apply to PKCS#5 v2.0 where it can be something else. Now -+ the 'parameter' field of the AlgorithmIdentifier is passed to the -+ underlying key generation function so it must do its own ASN1 parsing. -+ This has also changed the EVP_PBE_CipherInit() function which now has a -+ 'parameter' argument instead of literal salt and iteration count values -+ and the function EVP_PBE_ALGOR_CipherInit() has been deleted. -+ [Steve Henson] -+ -+ *) Support for PKCS#5 v1.5 compatible password based encryption algorithms -+ and PKCS#8 functionality. New 'pkcs8' application linked to openssl. -+ Needed to change the PEM_STRING_EVP_PKEY value which was just "PRIVATE -+ KEY" because this clashed with PKCS#8 unencrypted string. Since this -+ value was just used as a "magic string" and not used directly its -+ value doesn't matter. -+ [Steve Henson] -+ -+ *) Introduce some semblance of const correctness to BN. Shame C doesn't -+ support mutable. -+ [Ben Laurie] -+ -+ *) "linux-sparc64" configuration (ultrapenguin). -+ [Ray Miller ] -+ "linux-sparc" configuration. -+ [Christian Forster ] -+ -+ *) config now generates no-xxx options for missing ciphers. -+ [Ulf Möller] -+ -+ *) Support the EBCDIC character set (work in progress). -+ File ebcdic.c not yet included because it has a different license. -+ [Martin Kraemer ] -+ -+ *) Support BS2000/OSD-POSIX. -+ [Martin Kraemer ] -+ -+ *) Make callbacks for key generation use void * instead of char *. -+ [Ben Laurie] -+ -+ *) Make S/MIME samples compile (not yet tested). -+ [Ben Laurie] -+ -+ *) Additional typesafe stacks. -+ [Ben Laurie] -+ -+ *) New configuration variants "bsdi-elf-gcc" (BSD/OS 4.x). -+ [Bodo Moeller] -+ -+ -+ Changes between 0.9.3 and 0.9.3a [29 May 1999] -+ -+ *) New configuration variant "sco5-gcc". -+ -+ *) Updated some demos. -+ [Sean O Riordain, Wade Scholine] -+ -+ *) Add missing BIO_free at exit of pkcs12 application. -+ [Wu Zhigang] -+ -+ *) Fix memory leak in conf.c. -+ [Steve Henson] -+ -+ *) Updates for Win32 to assembler version of MD5. -+ [Steve Henson] -+ -+ *) Set #! path to perl in apps/der_chop to where we found it -+ instead of using a fixed path. -+ [Bodo Moeller] -+ -+ *) SHA library changes for irix64-mips4-cc. -+ [Andy Polyakov] -+ -+ *) Improvements for VMS support. -+ [Richard Levitte] -+ -+ -+ Changes between 0.9.2b and 0.9.3 [24 May 1999] -+ -+ *) Bignum library bug fix. IRIX 6 passes "make test" now! -+ This also avoids the problems with SC4.2 and unpatched SC5. -+ [Andy Polyakov ] -+ -+ *) New functions sk_num, sk_value and sk_set to replace the previous macros. -+ These are required because of the typesafe stack would otherwise break -+ existing code. If old code used a structure member which used to be STACK -+ and is now STACK_OF (for example cert in a PKCS7_SIGNED structure) with -+ sk_num or sk_value it would produce an error because the num, data members -+ are not present in STACK_OF. Now it just produces a warning. sk_set -+ replaces the old method of assigning a value to sk_value -+ (e.g. sk_value(x, i) = y) which the library used in a few cases. Any code -+ that does this will no longer work (and should use sk_set instead) but -+ this could be regarded as a "questionable" behaviour anyway. -+ [Steve Henson] -+ -+ *) Fix most of the other PKCS#7 bugs. The "experimental" code can now -+ correctly handle encrypted S/MIME data. -+ [Steve Henson] -+ -+ *) Change type of various DES function arguments from des_cblock -+ (which means, in function argument declarations, pointer to char) -+ to des_cblock * (meaning pointer to array with 8 char elements), -+ which allows the compiler to do more typechecking; it was like -+ that back in SSLeay, but with lots of ugly casts. -+ -+ Introduce new type const_des_cblock. -+ [Bodo Moeller] -+ -+ *) Reorganise the PKCS#7 library and get rid of some of the more obvious -+ problems: find RecipientInfo structure that matches recipient certificate -+ and initialise the ASN1 structures properly based on passed cipher. -+ [Steve Henson] -+ -+ *) Belatedly make the BN tests actually check the results. -+ [Ben Laurie] -+ -+ *) Fix the encoding and decoding of negative ASN1 INTEGERS and conversion -+ to and from BNs: it was completely broken. New compilation option -+ NEG_PUBKEY_BUG to allow for some broken certificates that encode public -+ key elements as negative integers. -+ [Steve Henson] -+ -+ *) Reorganize and speed up MD5. -+ [Andy Polyakov ] -+ -+ *) VMS support. -+ [Richard Levitte ] -+ -+ *) New option -out to asn1parse to allow the parsed structure to be -+ output to a file. This is most useful when combined with the -strparse -+ option to examine the output of things like OCTET STRINGS. -+ [Steve Henson] -+ -+ *) Make SSL library a little more fool-proof by not requiring any longer -+ that SSL_set_{accept,connect}_state be called before -+ SSL_{accept,connect} may be used (SSL_set_..._state is omitted -+ in many applications because usually everything *appeared* to work as -+ intended anyway -- now it really works as intended). -+ [Bodo Moeller] -+ -+ *) Move openssl.cnf out of lib/. -+ [Ulf Möller] -+ -+ *) Fix various things to let OpenSSL even pass ``egcc -pipe -O2 -Wall -+ -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes -+ -Wmissing-declarations -Wnested-externs -Winline'' with EGCS 1.1.2+ -+ [Ralf S. Engelschall] -+ -+ *) Various fixes to the EVP and PKCS#7 code. It may now be able to -+ handle PKCS#7 enveloped data properly. -+ [Sebastian Akerman , modified by Steve] -+ -+ *) Create a duplicate of the SSL_CTX's CERT in SSL_new instead of -+ copying pointers. The cert_st handling is changed by this in -+ various ways (and thus what used to be known as ctx->default_cert -+ is now called ctx->cert, since we don't resort to s->ctx->[default_]cert -+ any longer when s->cert does not give us what we need). -+ ssl_cert_instantiate becomes obsolete by this change. -+ As soon as we've got the new code right (possibly it already is?), -+ we have solved a couple of bugs of the earlier code where s->cert -+ was used as if it could not have been shared with other SSL structures. -+ -+ Note that using the SSL API in certain dirty ways now will result -+ in different behaviour than observed with earlier library versions: -+ Changing settings for an SSL_CTX *ctx after having done s = SSL_new(ctx) -+ does not influence s as it used to. -+ -+ In order to clean up things more thoroughly, inside SSL_SESSION -+ we don't use CERT any longer, but a new structure SESS_CERT -+ that holds per-session data (if available); currently, this is -+ the peer's certificate chain and, for clients, the server's certificate -+ and temporary key. CERT holds only those values that can have -+ meaningful defaults in an SSL_CTX. -+ [Bodo Moeller] -+ -+ *) New function X509V3_EXT_i2d() to create an X509_EXTENSION structure -+ from the internal representation. Various PKCS#7 fixes: remove some -+ evil casts and set the enc_dig_alg field properly based on the signing -+ key type. -+ [Steve Henson] -+ -+ *) Allow PKCS#12 password to be set from the command line or the -+ environment. Let 'ca' get its config file name from the environment -+ variables "OPENSSL_CONF" or "SSLEAY_CONF" (for consistency with 'req' -+ and 'x509'). -+ [Steve Henson] -+ -+ *) Allow certificate policies extension to use an IA5STRING for the -+ organization field. This is contrary to the PKIX definition but -+ VeriSign uses it and IE5 only recognises this form. Document 'x509' -+ extension option. -+ [Steve Henson] -+ -+ *) Add PEDANTIC compiler flag to allow compilation with gcc -pedantic, -+ without disallowing inline assembler and the like for non-pedantic builds. -+ [Ben Laurie] -+ -+ *) Support Borland C++ builder. -+ [Janez Jere , modified by Ulf Möller] -+ -+ *) Support Mingw32. -+ [Ulf Möller] -+ -+ *) SHA-1 cleanups and performance enhancements. -+ [Andy Polyakov ] -+ -+ *) Sparc v8plus assembler for the bignum library. -+ [Andy Polyakov ] -+ -+ *) Accept any -xxx and +xxx compiler options in Configure. -+ [Ulf Möller] -+ -+ *) Update HPUX configuration. -+ [Anonymous] -+ -+ *) Add missing sk__unshift() function to safestack.h -+ [Ralf S. Engelschall] -+ -+ *) New function SSL_CTX_use_certificate_chain_file that sets the -+ "extra_cert"s in addition to the certificate. (This makes sense -+ only for "PEM" format files, as chains as a whole are not -+ DER-encoded.) -+ [Bodo Moeller] -+ -+ *) Support verify_depth from the SSL API. -+ x509_vfy.c had what can be considered an off-by-one-error: -+ Its depth (which was not part of the external interface) -+ was actually counting the number of certificates in a chain; -+ now it really counts the depth. -+ [Bodo Moeller] -+ -+ *) Bugfix in crypto/x509/x509_cmp.c: The SSLerr macro was used -+ instead of X509err, which often resulted in confusing error -+ messages since the error codes are not globally unique -+ (e.g. an alleged error in ssl3_accept when a certificate -+ didn't match the private key). -+ -+ *) New function SSL_CTX_set_session_id_context that allows to set a default -+ value (so that you don't need SSL_set_session_id_context for each -+ connection using the SSL_CTX). -+ [Bodo Moeller] -+ -+ *) OAEP decoding bug fix. -+ [Ulf Möller] -+ -+ *) Support INSTALL_PREFIX for package builders, as proposed by -+ David Harris. -+ [Bodo Moeller] -+ -+ *) New Configure options "threads" and "no-threads". For systems -+ where the proper compiler options are known (currently Solaris -+ and Linux), "threads" is the default. -+ [Bodo Moeller] -+ -+ *) New script util/mklink.pl as a faster substitute for util/mklink.sh. -+ [Bodo Moeller] -+ -+ *) Install various scripts to $(OPENSSLDIR)/misc, not to -+ $(INSTALLTOP)/bin -- they shouldn't clutter directories -+ such as /usr/local/bin. -+ [Bodo Moeller] -+ -+ *) "make linux-shared" to build shared libraries. -+ [Niels Poppe ] -+ -+ *) New Configure option no- (rsa, idea, rc5, ...). -+ [Ulf Möller] -+ -+ *) Add the PKCS#12 API documentation to openssl.txt. Preliminary support for -+ extension adding in x509 utility. -+ [Steve Henson] -+ -+ *) Remove NOPROTO sections and error code comments. -+ [Ulf Möller] -+ -+ *) Partial rewrite of the DEF file generator to now parse the ANSI -+ prototypes. -+ [Steve Henson] -+ -+ *) New Configure options --prefix=DIR and --openssldir=DIR. -+ [Ulf Möller] -+ -+ *) Complete rewrite of the error code script(s). It is all now handled -+ by one script at the top level which handles error code gathering, -+ header rewriting and C source file generation. It should be much better -+ than the old method: it now uses a modified version of Ulf's parser to -+ read the ANSI prototypes in all header files (thus the old K&R definitions -+ aren't needed for error creation any more) and do a better job of -+ translating function codes into names. The old 'ASN1 error code imbedded -+ in a comment' is no longer necessary and it doesn't use .err files which -+ have now been deleted. Also the error code call doesn't have to appear all -+ on one line (which resulted in some large lines...). -+ [Steve Henson] -+ -+ *) Change #include filenames from to . -+ [Bodo Moeller] -+ -+ *) Change behaviour of ssl2_read when facing length-0 packets: Don't return -+ 0 (which usually indicates a closed connection), but continue reading. -+ [Bodo Moeller] -+ -+ *) Fix some race conditions. -+ [Bodo Moeller] -+ -+ *) Add support for CRL distribution points extension. Add Certificate -+ Policies and CRL distribution points documentation. -+ [Steve Henson] -+ -+ *) Move the autogenerated header file parts to crypto/opensslconf.h. -+ [Ulf Möller] -+ -+ *) Fix new 56-bit DES export ciphersuites: they were using 7 bytes instead of -+ 8 of keying material. Merlin has also confirmed interop with this fix -+ between OpenSSL and Baltimore C/SSL 2.0 and J/SSL 2.0. -+ [Merlin Hughes ] -+ -+ *) Fix lots of warnings. -+ [Richard Levitte ] -+ -+ *) In add_cert_dir() in crypto/x509/by_dir.c, break out of the loop if -+ the directory spec didn't end with a LIST_SEPARATOR_CHAR. -+ [Richard Levitte ] -+ -+ *) Fix problems with sizeof(long) == 8. -+ [Andy Polyakov ] -+ -+ *) Change functions to ANSI C. -+ [Ulf Möller] -+ -+ *) Fix typos in error codes. -+ [Martin Kraemer , Ulf Möller] -+ -+ *) Remove defunct assembler files from Configure. -+ [Ulf Möller] -+ -+ *) SPARC v8 assembler BIGNUM implementation. -+ [Andy Polyakov ] -+ -+ *) Support for Certificate Policies extension: both print and set. -+ Various additions to support the r2i method this uses. -+ [Steve Henson] -+ -+ *) A lot of constification, and fix a bug in X509_NAME_oneline() that could -+ return a const string when you are expecting an allocated buffer. -+ [Ben Laurie] -+ -+ *) Add support for ASN1 types UTF8String and VISIBLESTRING, also the CHOICE -+ types DirectoryString and DisplayText. -+ [Steve Henson] -+ -+ *) Add code to allow r2i extensions to access the configuration database, -+ add an LHASH database driver and add several ctx helper functions. -+ [Steve Henson] -+ -+ *) Fix an evil bug in bn_expand2() which caused various BN functions to -+ fail when they extended the size of a BIGNUM. -+ [Steve Henson] -+ -+ *) Various utility functions to handle SXNet extension. Modify mkdef.pl to -+ support typesafe stack. -+ [Steve Henson] -+ -+ *) Fix typo in SSL_[gs]et_options(). -+ [Nils Frostberg ] -+ -+ *) Delete various functions and files that belonged to the (now obsolete) -+ old X509V3 handling code. -+ [Steve Henson] -+ -+ *) New Configure option "rsaref". -+ [Ulf Möller] -+ -+ *) Don't auto-generate pem.h. -+ [Bodo Moeller] -+ -+ *) Introduce type-safe ASN.1 SETs. -+ [Ben Laurie] -+ -+ *) Convert various additional casted stacks to type-safe STACK_OF() variants. -+ [Ben Laurie, Ralf S. Engelschall, Steve Henson] -+ -+ *) Introduce type-safe STACKs. This will almost certainly break lots of code -+ that links with OpenSSL (well at least cause lots of warnings), but fear -+ not: the conversion is trivial, and it eliminates loads of evil casts. A -+ few STACKed things have been converted already. Feel free to convert more. -+ In the fullness of time, I'll do away with the STACK type altogether. -+ [Ben Laurie] -+ -+ *) Add `openssl ca -revoke ' facility which revokes a certificate -+ specified in by updating the entry in the index.txt file. -+ This way one no longer has to edit the index.txt file manually for -+ revoking a certificate. The -revoke option does the gory details now. -+ [Massimiliano Pala , Ralf S. Engelschall] -+ -+ *) Fix `openssl crl -noout -text' combination where `-noout' killed the -+ `-text' option at all and this way the `-noout -text' combination was -+ inconsistent in `openssl crl' with the friends in `openssl x509|rsa|dsa'. -+ [Ralf S. Engelschall] -+ -+ *) Make sure a corresponding plain text error message exists for the -+ X509_V_ERR_CERT_REVOKED/23 error number which can occur when a -+ verify callback function determined that a certificate was revoked. -+ [Ralf S. Engelschall] -+ -+ *) Bugfix: In test/testenc, don't test "openssl " for -+ ciphers that were excluded, e.g. by -DNO_IDEA. Also, test -+ all available cipers including rc5, which was forgotten until now. -+ In order to let the testing shell script know which algorithms -+ are available, a new (up to now undocumented) command -+ "openssl list-cipher-commands" is used. -+ [Bodo Moeller] -+ -+ *) Bugfix: s_client occasionally would sleep in select() when -+ it should have checked SSL_pending() first. -+ [Bodo Moeller] -+ -+ *) New functions DSA_do_sign and DSA_do_verify to provide access to -+ the raw DSA values prior to ASN.1 encoding. -+ [Ulf Möller] -+ -+ *) Tweaks to Configure -+ [Niels Poppe ] -+ -+ *) Add support for PKCS#5 v2.0 ASN1 PBES2 structures. No other support, -+ yet... -+ [Steve Henson] -+ -+ *) New variables $(RANLIB) and $(PERL) in the Makefiles. -+ [Ulf Möller] -+ -+ *) New config option to avoid instructions that are illegal on the 80386. -+ The default code is faster, but requires at least a 486. -+ [Ulf Möller] -+ -+ *) Got rid of old SSL2_CLIENT_VERSION (inconsistently used) and -+ SSL2_SERVER_VERSION (not used at all) macros, which are now the -+ same as SSL2_VERSION anyway. -+ [Bodo Moeller] -+ -+ *) New "-showcerts" option for s_client. -+ [Bodo Moeller] -+ -+ *) Still more PKCS#12 integration. Add pkcs12 application to openssl -+ application. Various cleanups and fixes. -+ [Steve Henson] -+ -+ *) More PKCS#12 integration. Add new pkcs12 directory with Makefile.ssl and -+ modify error routines to work internally. Add error codes and PBE init -+ to library startup routines. -+ [Steve Henson] -+ -+ *) Further PKCS#12 integration. Added password based encryption, PKCS#8 and -+ packing functions to asn1 and evp. Changed function names and error -+ codes along the way. -+ [Steve Henson] -+ -+ *) PKCS12 integration: and so it begins... First of several patches to -+ slowly integrate PKCS#12 functionality into OpenSSL. Add PKCS#12 -+ objects to objects.h -+ [Steve Henson] -+ -+ *) Add a new 'indent' option to some X509V3 extension code. Initial ASN1 -+ and display support for Thawte strong extranet extension. -+ [Steve Henson] -+ -+ *) Add LinuxPPC support. -+ [Jeff Dubrule ] -+ -+ *) Get rid of redundant BN file bn_mulw.c, and rename bn_div64 to -+ bn_div_words in alpha.s. -+ [Hannes Reinecke and Ben Laurie] -+ -+ *) Make sure the RSA OAEP test is skipped under -DRSAref because -+ OAEP isn't supported when OpenSSL is built with RSAref. -+ [Ulf Moeller ] -+ -+ *) Move definitions of IS_SET/IS_SEQUENCE inside crypto/asn1/asn1.h -+ so they no longer are missing under -DNOPROTO. -+ [Soren S. Jorvang ] -+ -+ -+ Changes between 0.9.1c and 0.9.2b [22 Mar 1999] -+ -+ *) Make SSL_get_peer_cert_chain() work in servers. Unfortunately, it still -+ doesn't work when the session is reused. Coming soon! -+ [Ben Laurie] -+ -+ *) Fix a security hole, that allows sessions to be reused in the wrong -+ context thus bypassing client cert protection! All software that uses -+ client certs and session caches in multiple contexts NEEDS PATCHING to -+ allow session reuse! A fuller solution is in the works. -+ [Ben Laurie, problem pointed out by Holger Reif, Bodo Moeller (and ???)] -+ -+ *) Some more source tree cleanups (removed obsolete files -+ crypto/bf/asm/bf586.pl, test/test.txt and crypto/sha/asm/f.s; changed -+ permission on "config" script to be executable) and a fix for the INSTALL -+ document. -+ [Ulf Moeller ] -+ -+ *) Remove some legacy and erroneous uses of malloc, free instead of -+ Malloc, Free. -+ [Lennart Bang , with minor changes by Steve] -+ -+ *) Make rsa_oaep_test return non-zero on error. -+ [Ulf Moeller ] -+ -+ *) Add support for native Solaris shared libraries. Configure -+ solaris-sparc-sc4-pic, make, then run shlib/solaris-sc4.sh. It'd be nice -+ if someone would make that last step automatic. -+ [Matthias Loepfe ] -+ -+ *) ctx_size was not built with the right compiler during "make links". Fixed. -+ [Ben Laurie] -+ -+ *) Change the meaning of 'ALL' in the cipher list. It now means "everything -+ except NULL ciphers". This means the default cipher list will no longer -+ enable NULL ciphers. They need to be specifically enabled e.g. with -+ the string "DEFAULT:eNULL". -+ [Steve Henson] -+ -+ *) Fix to RSA private encryption routines: if p < q then it would -+ occasionally produce an invalid result. This will only happen with -+ externally generated keys because OpenSSL (and SSLeay) ensure p > q. -+ [Steve Henson] -+ -+ *) Be less restrictive and allow also `perl util/perlpath.pl -+ /path/to/bin/perl' in addition to `perl util/perlpath.pl /path/to/bin', -+ because this way one can also use an interpreter named `perl5' (which is -+ usually the name of Perl 5.xxx on platforms where an Perl 4.x is still -+ installed as `perl'). -+ [Matthias Loepfe ] -+ -+ *) Let util/clean-depend.pl work also with older Perl 5.00x versions. -+ [Matthias Loepfe ] -+ -+ *) Fix Makefile.org so CC,CFLAG etc are passed to 'make links' add -+ advapi32.lib to Win32 build and change the pem test comparison -+ to fc.exe (thanks to Ulrich Kroener for the -+ suggestion). Fix misplaced ASNI prototypes and declarations in evp.h -+ and crypto/des/ede_cbcm_enc.c. -+ [Steve Henson] -+ -+ *) DES quad checksum was broken on big-endian architectures. Fixed. -+ [Ben Laurie] -+ -+ *) Comment out two functions in bio.h that aren't implemented. Fix up the -+ Win32 test batch file so it (might) work again. The Win32 test batch file -+ is horrible: I feel ill.... -+ [Steve Henson] -+ -+ *) Move various #ifdefs around so NO_SYSLOG, NO_DIRENT etc are now selected -+ in e_os.h. Audit of header files to check ANSI and non ANSI -+ sections: 10 functions were absent from non ANSI section and not exported -+ from Windows DLLs. Fixed up libeay.num for new functions. -+ [Steve Henson] -+ -+ *) Make `openssl version' output lines consistent. -+ [Ralf S. Engelschall] -+ -+ *) Fix Win32 symbol export lists for BIO functions: Added -+ BIO_get_ex_new_index, BIO_get_ex_num, BIO_get_ex_data and BIO_set_ex_data -+ to ms/libeay{16,32}.def. -+ [Ralf S. Engelschall] -+ -+ *) Second round of fixing the OpenSSL perl/ stuff. It now at least compiled -+ fine under Unix and passes some trivial tests I've now added. But the -+ whole stuff is horribly incomplete, so a README.1ST with a disclaimer was -+ added to make sure no one expects that this stuff really works in the -+ OpenSSL 0.9.2 release. Additionally I've started to clean the XS sources -+ up and fixed a few little bugs and inconsistencies in OpenSSL.{pm,xs} and -+ openssl_bio.xs. -+ [Ralf S. Engelschall] -+ -+ *) Fix the generation of two part addresses in perl. -+ [Kenji Miyake , integrated by Ben Laurie] -+ -+ *) Add config entry for Linux on MIPS. -+ [John Tobey ] -+ -+ *) Make links whenever Configure is run, unless we are on Windoze. -+ [Ben Laurie] -+ -+ *) Permit extensions to be added to CRLs using crl_section in openssl.cnf. -+ Currently only issuerAltName and AuthorityKeyIdentifier make any sense -+ in CRLs. -+ [Steve Henson] -+ -+ *) Add a useful kludge to allow package maintainers to specify compiler and -+ other platforms details on the command line without having to patch the -+ Configure script everytime: One now can use ``perl Configure -+ :
'', i.e. platform ids are allowed to have details appended -+ to them (separated by colons). This is treated as there would be a static -+ pre-configured entry in Configure's %table under key with value -+
and ``perl Configure '' is called. So, when you want to -+ perform a quick test-compile under FreeBSD 3.1 with pgcc and without -+ assembler stuff you can use ``perl Configure "FreeBSD-elf:pgcc:-O6:::"'' -+ now, which overrides the FreeBSD-elf entry on-the-fly. -+ [Ralf S. Engelschall] -+ -+ *) Disable new TLS1 ciphersuites by default: they aren't official yet. -+ [Ben Laurie] -+ -+ *) Allow DSO flags like -fpic, -fPIC, -KPIC etc. to be specified -+ on the `perl Configure ...' command line. This way one can compile -+ OpenSSL libraries with Position Independent Code (PIC) which is needed -+ for linking it into DSOs. -+ [Ralf S. Engelschall] -+ -+ *) Remarkably, export ciphers were totally broken and no-one had noticed! -+ Fixed. -+ [Ben Laurie] -+ -+ *) Cleaned up the LICENSE document: The official contact for any license -+ questions now is the OpenSSL core team under openssl-core@openssl.org. -+ And add a paragraph about the dual-license situation to make sure people -+ recognize that _BOTH_ the OpenSSL license _AND_ the SSLeay license apply -+ to the OpenSSL toolkit. -+ [Ralf S. Engelschall] -+ -+ *) General source tree makefile cleanups: Made `making xxx in yyy...' -+ display consistent in the source tree and replaced `/bin/rm' by `rm'. -+ Additionally cleaned up the `make links' target: Remove unnecessary -+ semicolons, subsequent redundant removes, inline point.sh into mklink.sh -+ to speed processing and no longer clutter the display with confusing -+ stuff. Instead only the actually done links are displayed. -+ [Ralf S. Engelschall] -+ -+ *) Permit null encryption ciphersuites, used for authentication only. It used -+ to be necessary to set the preprocessor define SSL_ALLOW_ENULL to do this. -+ It is now necessary to set SSL_FORBID_ENULL to prevent the use of null -+ encryption. -+ [Ben Laurie] -+ -+ *) Add a bunch of fixes to the PKCS#7 stuff. It used to sometimes reorder -+ signed attributes when verifying signatures (this would break them), -+ the detached data encoding was wrong and public keys obtained using -+ X509_get_pubkey() weren't freed. -+ [Steve Henson] -+ -+ *) Add text documentation for the BUFFER functions. Also added a work around -+ to a Win95 console bug. This was triggered by the password read stuff: the -+ last character typed gets carried over to the next fread(). If you were -+ generating a new cert request using 'req' for example then the last -+ character of the passphrase would be CR which would then enter the first -+ field as blank. -+ [Steve Henson] -+ -+ *) Added the new `Includes OpenSSL Cryptography Software' button as -+ doc/openssl_button.{gif,html} which is similar in style to the old SSLeay -+ button and can be used by applications based on OpenSSL to show the -+ relationship to the OpenSSL project. -+ [Ralf S. Engelschall] -+ -+ *) Remove confusing variables in function signatures in files -+ ssl/ssl_lib.c and ssl/ssl.h. -+ [Lennart Bong ] -+ -+ *) Don't install bss_file.c under PREFIX/include/ -+ [Lennart Bong ] -+ -+ *) Get the Win32 compile working again. Modify mkdef.pl so it can handle -+ functions that return function pointers and has support for NT specific -+ stuff. Fix mk1mf.pl and VC-32.pl to support NT differences also. Various -+ #ifdef WIN32 and WINNTs sprinkled about the place and some changes from -+ unsigned to signed types: this was killing the Win32 compile. -+ [Steve Henson] -+ -+ *) Add new certificate file to stack functions, -+ SSL_add_dir_cert_subjects_to_stack() and -+ SSL_add_file_cert_subjects_to_stack(). These largely supplant -+ SSL_load_client_CA_file(), and can be used to add multiple certs easily -+ to a stack (usually this is then handed to SSL_CTX_set_client_CA_list()). -+ This means that Apache-SSL and similar packages don't have to mess around -+ to add as many CAs as they want to the preferred list. -+ [Ben Laurie] -+ -+ *) Experiment with doxygen documentation. Currently only partially applied to -+ ssl/ssl_lib.c. -+ See http://www.stack.nl/~dimitri/doxygen/index.html, and run doxygen with -+ openssl.doxy as the configuration file. -+ [Ben Laurie] -+ -+ *) Get rid of remaining C++-style comments which strict C compilers hate. -+ [Ralf S. Engelschall, pointed out by Carlos Amengual] -+ -+ *) Changed BN_RECURSION in bn_mont.c to BN_RECURSION_MONT so it is not -+ compiled in by default: it has problems with large keys. -+ [Steve Henson] -+ -+ *) Add a bunch of SSL_xxx() functions for configuring the temporary RSA and -+ DH private keys and/or callback functions which directly correspond to -+ their SSL_CTX_xxx() counterparts but work on a per-connection basis. This -+ is needed for applications which have to configure certificates on a -+ per-connection basis (e.g. Apache+mod_ssl) instead of a per-context basis -+ (e.g. s_server). -+ For the RSA certificate situation is makes no difference, but -+ for the DSA certificate situation this fixes the "no shared cipher" -+ problem where the OpenSSL cipher selection procedure failed because the -+ temporary keys were not overtaken from the context and the API provided -+ no way to reconfigure them. -+ The new functions now let applications reconfigure the stuff and they -+ are in detail: SSL_need_tmp_RSA, SSL_set_tmp_rsa, SSL_set_tmp_dh, -+ SSL_set_tmp_rsa_callback and SSL_set_tmp_dh_callback. Additionally a new -+ non-public-API function ssl_cert_instantiate() is used as a helper -+ function and also to reduce code redundancy inside ssl_rsa.c. -+ [Ralf S. Engelschall] -+ -+ *) Move s_server -dcert and -dkey options out of the undocumented feature -+ area because they are useful for the DSA situation and should be -+ recognized by the users. -+ [Ralf S. Engelschall] -+ -+ *) Fix the cipher decision scheme for export ciphers: the export bits are -+ *not* within SSL_MKEY_MASK or SSL_AUTH_MASK, they are within -+ SSL_EXP_MASK. So, the original variable has to be used instead of the -+ already masked variable. -+ [Richard Levitte ] -+ -+ *) Fix 'port' variable from `int' to `unsigned int' in crypto/bio/b_sock.c -+ [Richard Levitte ] -+ -+ *) Change type of another md_len variable in pk7_doit.c:PKCS7_dataFinal() -+ from `int' to `unsigned int' because it's a length and initialized by -+ EVP_DigestFinal() which expects an `unsigned int *'. -+ [Richard Levitte ] -+ -+ *) Don't hard-code path to Perl interpreter on shebang line of Configure -+ script. Instead use the usual Shell->Perl transition trick. -+ [Ralf S. Engelschall] -+ -+ *) Make `openssl x509 -noout -modulus' functional also for DSA certificates -+ (in addition to RSA certificates) to match the behaviour of `openssl dsa -+ -noout -modulus' as it's already the case for `openssl rsa -noout -+ -modulus'. For RSA the -modulus is the real "modulus" while for DSA -+ currently the public key is printed (a decision which was already done by -+ `openssl dsa -modulus' in the past) which serves a similar purpose. -+ Additionally the NO_RSA no longer completely removes the whole -modulus -+ option; it now only avoids using the RSA stuff. Same applies to NO_DSA -+ now, too. -+ [Ralf S. Engelschall] -+ -+ *) Add Arne Ansper's reliable BIO - this is an encrypted, block-digested -+ BIO. See the source (crypto/evp/bio_ok.c) for more info. -+ [Arne Ansper ] -+ -+ *) Dump the old yucky req code that tried (and failed) to allow raw OIDs -+ to be added. Now both 'req' and 'ca' can use new objects defined in the -+ config file. -+ [Steve Henson] -+ -+ *) Add cool BIO that does syslog (or event log on NT). -+ [Arne Ansper , integrated by Ben Laurie] -+ -+ *) Add support for new TLS ciphersuites, TLS_RSA_EXPORT56_WITH_RC4_56_MD5, -+ TLS_RSA_EXPORT56_WITH_RC2_CBC_56_MD5 and -+ TLS_RSA_EXPORT56_WITH_DES_CBC_SHA, as specified in "56-bit Export Cipher -+ Suites For TLS", draft-ietf-tls-56-bit-ciphersuites-00.txt. -+ [Ben Laurie] -+ -+ *) Add preliminary config info for new extension code. -+ [Steve Henson] -+ -+ *) Make RSA_NO_PADDING really use no padding. -+ [Ulf Moeller ] -+ -+ *) Generate errors when private/public key check is done. -+ [Ben Laurie] -+ -+ *) Overhaul for 'crl' utility. New function X509_CRL_print. Partial support -+ for some CRL extensions and new objects added. -+ [Steve Henson] -+ -+ *) Really fix the ASN1 IMPLICIT bug this time... Partial support for private -+ key usage extension and fuller support for authority key id. -+ [Steve Henson] -+ -+ *) Add OAEP encryption for the OpenSSL crypto library. OAEP is the improved -+ padding method for RSA, which is recommended for new applications in PKCS -+ #1 v2.0 (RFC 2437, October 1998). -+ OAEP (Optimal Asymmetric Encryption Padding) has better theoretical -+ foundations than the ad-hoc padding used in PKCS #1 v1.5. It is secure -+ against Bleichbacher's attack on RSA. -+ [Ulf Moeller , reformatted, corrected and integrated by -+ Ben Laurie] -+ -+ *) Updates to the new SSL compression code -+ [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] -+ -+ *) Fix so that the version number in the master secret, when passed -+ via RSA, checks that if TLS was proposed, but we roll back to SSLv3 -+ (because the server will not accept higher), that the version number -+ is 0x03,0x01, not 0x03,0x00 -+ [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] -+ -+ *) Run extensive memory leak checks on SSL apps. Fixed *lots* of memory -+ leaks in ssl/ relating to new X509_get_pubkey() behaviour. Also fixes -+ in apps/ and an unrelated leak in crypto/dsa/dsa_vrf.c -+ [Steve Henson] -+ -+ *) Support for RAW extensions where an arbitrary extension can be -+ created by including its DER encoding. See apps/openssl.cnf for -+ an example. -+ [Steve Henson] -+ -+ *) Make sure latest Perl versions don't interpret some generated C array -+ code as Perl array code in the crypto/err/err_genc.pl script. -+ [Lars Weber <3weber@informatik.uni-hamburg.de>] -+ -+ *) Modify ms/do_ms.bat to not generate assembly language makefiles since -+ not many people have the assembler. Various Win32 compilation fixes and -+ update to the INSTALL.W32 file with (hopefully) more accurate Win32 -+ build instructions. -+ [Steve Henson] -+ -+ *) Modify configure script 'Configure' to automatically create crypto/date.h -+ file under Win32 and also build pem.h from pem.org. New script -+ util/mkfiles.pl to create the MINFO file on environments that can't do a -+ 'make files': perl util/mkfiles.pl >MINFO should work. -+ [Steve Henson] -+ -+ *) Major rework of DES function declarations, in the pursuit of correctness -+ and purity. As a result, many evil casts evaporated, and some weirdness, -+ too. You may find this causes warnings in your code. Zapping your evil -+ casts will probably fix them. Mostly. -+ [Ben Laurie] -+ -+ *) Fix for a typo in asn1.h. Bug fix to object creation script -+ obj_dat.pl. It considered a zero in an object definition to mean -+ "end of object": none of the objects in objects.h have any zeros -+ so it wasn't spotted. -+ [Steve Henson, reported by Erwann ABALEA ] -+ -+ *) Add support for Triple DES Cipher Block Chaining with Output Feedback -+ Masking (CBCM). In the absence of test vectors, the best I have been able -+ to do is check that the decrypt undoes the encrypt, so far. Send me test -+ vectors if you have them. -+ [Ben Laurie] -+ -+ *) Correct calculation of key length for export ciphers (too much space was -+ allocated for null ciphers). This has not been tested! -+ [Ben Laurie] -+ -+ *) Modifications to the mkdef.pl for Win32 DEF file creation. The usage -+ message is now correct (it understands "crypto" and "ssl" on its -+ command line). There is also now an "update" option. This will update -+ the util/ssleay.num and util/libeay.num files with any new functions. -+ If you do a: -+ perl util/mkdef.pl crypto ssl update -+ it will update them. -+ [Steve Henson] -+ -+ *) Overhauled the Perl interface (perl/*): -+ - ported BN stuff to OpenSSL's different BN library -+ - made the perl/ source tree CVS-aware -+ - renamed the package from SSLeay to OpenSSL (the files still contain -+ their history because I've copied them in the repository) -+ - removed obsolete files (the test scripts will be replaced -+ by better Test::Harness variants in the future) -+ [Ralf S. Engelschall] -+ -+ *) First cut for a very conservative source tree cleanup: -+ 1. merge various obsolete readme texts into doc/ssleay.txt -+ where we collect the old documents and readme texts. -+ 2. remove the first part of files where I'm already sure that we no -+ longer need them because of three reasons: either they are just temporary -+ files which were left by Eric or they are preserved original files where -+ I've verified that the diff is also available in the CVS via "cvs diff -+ -rSSLeay_0_8_1b" or they were renamed (as it was definitely the case for -+ the crypto/md/ stuff). -+ [Ralf S. Engelschall] -+ -+ *) More extension code. Incomplete support for subject and issuer alt -+ name, issuer and authority key id. Change the i2v function parameters -+ and add an extra 'crl' parameter in the X509V3_CTX structure: guess -+ what that's for :-) Fix to ASN1 macro which messed up -+ IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED. -+ [Steve Henson] -+ -+ *) Preliminary support for ENUMERATED type. This is largely copied from the -+ INTEGER code. -+ [Steve Henson] -+ -+ *) Add new function, EVP_MD_CTX_copy() to replace frequent use of memcpy. -+ [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] -+ -+ *) Make sure `make rehash' target really finds the `openssl' program. -+ [Ralf S. Engelschall, Matthias Loepfe ] -+ -+ *) Squeeze another 7% of speed out of MD5 assembler, at least on a P2. I'd -+ like to hear about it if this slows down other processors. -+ [Ben Laurie] -+ -+ *) Add CygWin32 platform information to Configure script. -+ [Alan Batie ] -+ -+ *) Fixed ms/32all.bat script: `no_asm' -> `no-asm' -+ [Rainer W. Gerling ] -+ -+ *) New program nseq to manipulate netscape certificate sequences -+ [Steve Henson] -+ -+ *) Modify crl2pkcs7 so it supports multiple -certfile arguments. Fix a -+ few typos. -+ [Steve Henson] -+ -+ *) Fixes to BN code. Previously the default was to define BN_RECURSION -+ but the BN code had some problems that would cause failures when -+ doing certificate verification and some other functions. -+ [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] -+ -+ *) Add ASN1 and PEM code to support netscape certificate sequences. -+ [Steve Henson] -+ -+ *) Add ASN1 and PEM code to support netscape certificate sequences. -+ [Steve Henson] -+ -+ *) Add several PKIX and private extended key usage OIDs. -+ [Steve Henson] -+ -+ *) Modify the 'ca' program to handle the new extension code. Modify -+ openssl.cnf for new extension format, add comments. -+ [Steve Henson] -+ -+ *) More X509 V3 changes. Fix typo in v3_bitstr.c. Add support to 'req' -+ and add a sample to openssl.cnf so req -x509 now adds appropriate -+ CA extensions. -+ [Steve Henson] -+ -+ *) Continued X509 V3 changes. Add to other makefiles, integrate with the -+ error code, add initial support to X509_print() and x509 application. -+ [Steve Henson] -+ -+ *) Takes a deep breath and start adding X509 V3 extension support code. Add -+ files in crypto/x509v3. Move original stuff to crypto/x509v3/old. All this -+ stuff is currently isolated and isn't even compiled yet. -+ [Steve Henson] -+ -+ *) Continuing patches for GeneralizedTime. Fix up certificate and CRL -+ ASN1 to use ASN1_TIME and modify print routines to use ASN1_TIME_print. -+ Removed the versions check from X509 routines when loading extensions: -+ this allows certain broken certificates that don't set the version -+ properly to be processed. -+ [Steve Henson] -+ -+ *) Deal with irritating shit to do with dependencies, in YAAHW (Yet Another -+ Ad Hoc Way) - Makefile.ssls now all contain local dependencies, which -+ can still be regenerated with "make depend". -+ [Ben Laurie] -+ -+ *) Spelling mistake in C version of CAST-128. -+ [Ben Laurie, reported by Jeremy Hylton ] -+ -+ *) Changes to the error generation code. The perl script err-code.pl -+ now reads in the old error codes and retains the old numbers, only -+ adding new ones if necessary. It also only changes the .err files if new -+ codes are added. The makefiles have been modified to only insert errors -+ when needed (to avoid needlessly modifying header files). This is done -+ by only inserting errors if the .err file is newer than the auto generated -+ C file. To rebuild all the error codes from scratch (the old behaviour) -+ either modify crypto/Makefile.ssl to pass the -regen flag to err_code.pl -+ or delete all the .err files. -+ [Steve Henson] -+ -+ *) CAST-128 was incorrectly implemented for short keys. The C version has -+ been fixed, but is untested. The assembler versions are also fixed, but -+ new assembler HAS NOT BEEN GENERATED FOR WIN32 - the Makefile needs fixing -+ to regenerate it if needed. -+ [Ben Laurie, reported (with fix for C version) by Jun-ichiro itojun -+ Hagino ] -+ -+ *) File was opened incorrectly in randfile.c. -+ [Ulf Möller ] -+ -+ *) Beginning of support for GeneralizedTime. d2i, i2d, check and print -+ functions. Also ASN1_TIME suite which is a CHOICE of UTCTime or -+ GeneralizedTime. ASN1_TIME is the proper type used in certificates et -+ al: it's just almost always a UTCTime. Note this patch adds new error -+ codes so do a "make errors" if there are problems. -+ [Steve Henson] -+ -+ *) Correct Linux 1 recognition in config. -+ [Ulf Möller ] -+ -+ *) Remove pointless MD5 hash when using DSA keys in ca. -+ [Anonymous ] -+ -+ *) Generate an error if given an empty string as a cert directory. Also -+ generate an error if handed NULL (previously returned 0 to indicate an -+ error, but didn't set one). -+ [Ben Laurie, reported by Anonymous ] -+ -+ *) Add prototypes to SSL methods. Make SSL_write's buffer const, at last. -+ [Ben Laurie] -+ -+ *) Fix the dummy function BN_ref_mod_exp() in rsaref.c to have the correct -+ parameters. This was causing a warning which killed off the Win32 compile. -+ [Steve Henson] -+ -+ *) Remove C++ style comments from crypto/bn/bn_local.h. -+ [Neil Costigan ] -+ -+ *) The function OBJ_txt2nid was broken. It was supposed to return a nid -+ based on a text string, looking up short and long names and finally -+ "dot" format. The "dot" format stuff didn't work. Added new function -+ OBJ_txt2obj to do the same but return an ASN1_OBJECT and rewrote -+ OBJ_txt2nid to use it. OBJ_txt2obj can also return objects even if the -+ OID is not part of the table. -+ [Steve Henson] -+ -+ *) Add prototypes to X509 lookup/verify methods, fixing a bug in -+ X509_LOOKUP_by_alias(). -+ [Ben Laurie] -+ -+ *) Sort openssl functions by name. -+ [Ben Laurie] -+ -+ *) Get the gendsa program working (hopefully) and add it to app list. Remove -+ encryption from sample DSA keys (in case anyone is interested the password -+ was "1234"). -+ [Steve Henson] -+ -+ *) Make _all_ *_free functions accept a NULL pointer. -+ [Frans Heymans ] -+ -+ *) If a DH key is generated in s3_srvr.c, don't blow it by trying to use -+ NULL pointers. -+ [Anonymous ] -+ -+ *) s_server should send the CAfile as acceptable CAs, not its own cert. -+ [Bodo Moeller <3moeller@informatik.uni-hamburg.de>] -+ -+ *) Don't blow it for numeric -newkey arguments to apps/req. -+ [Bodo Moeller <3moeller@informatik.uni-hamburg.de>] -+ -+ *) Temp key "for export" tests were wrong in s3_srvr.c. -+ [Anonymous ] -+ -+ *) Add prototype for temp key callback functions -+ SSL_CTX_set_tmp_{rsa,dh}_callback(). -+ [Ben Laurie] -+ -+ *) Make DH_free() tolerate being passed a NULL pointer (like RSA_free() and -+ DSA_free()). Make X509_PUBKEY_set() check for errors in d2i_PublicKey(). -+ [Steve Henson] -+ -+ *) X509_name_add_entry() freed the wrong thing after an error. -+ [Arne Ansper ] -+ -+ *) rsa_eay.c would attempt to free a NULL context. -+ [Arne Ansper ] -+ -+ *) BIO_s_socket() had a broken should_retry() on Windoze. -+ [Arne Ansper ] -+ -+ *) BIO_f_buffer() didn't pass on BIO_CTRL_FLUSH. -+ [Arne Ansper ] -+ -+ *) Make sure the already existing X509_STORE->depth variable is initialized -+ in X509_STORE_new(), but document the fact that this variable is still -+ unused in the certificate verification process. -+ [Ralf S. Engelschall] -+ -+ *) Fix the various library and apps files to free up pkeys obtained from -+ X509_PUBKEY_get() et al. Also allow x509.c to handle netscape extensions. -+ [Steve Henson] -+ -+ *) Fix reference counting in X509_PUBKEY_get(). This makes -+ demos/maurice/example2.c work, amongst others, probably. -+ [Steve Henson and Ben Laurie] -+ -+ *) First cut of a cleanup for apps/. First the `ssleay' program is now named -+ `openssl' and second, the shortcut symlinks for the `openssl ' -+ are no longer created. This way we have a single and consistent command -+ line interface `openssl ', similar to `cvs '. -+ [Ralf S. Engelschall, Paul Sutton and Ben Laurie] -+ -+ *) ca.c: move test for DSA keys inside #ifndef NO_DSA. Make pubkey -+ BIT STRING wrapper always have zero unused bits. -+ [Steve Henson] -+ -+ *) Add CA.pl, perl version of CA.sh, add extended key usage OID. -+ [Steve Henson] -+ -+ *) Make the top-level INSTALL documentation easier to understand. -+ [Paul Sutton] -+ -+ *) Makefiles updated to exit if an error occurs in a sub-directory -+ make (including if user presses ^C) [Paul Sutton] -+ -+ *) Make Montgomery context stuff explicit in RSA data structure. -+ [Ben Laurie] -+ -+ *) Fix build order of pem and err to allow for generated pem.h. -+ [Ben Laurie] -+ -+ *) Fix renumbering bug in X509_NAME_delete_entry(). -+ [Ben Laurie] -+ -+ *) Enhanced the err-ins.pl script so it makes the error library number -+ global and can add a library name. This is needed for external ASN1 and -+ other error libraries. -+ [Steve Henson] -+ -+ *) Fixed sk_insert which never worked properly. -+ [Steve Henson] -+ -+ *) Fix ASN1 macros so they can handle indefinite length constructed -+ EXPLICIT tags. Some non standard certificates use these: they can now -+ be read in. -+ [Steve Henson] -+ -+ *) Merged the various old/obsolete SSLeay documentation files (doc/xxx.doc) -+ into a single doc/ssleay.txt bundle. This way the information is still -+ preserved but no longer messes up this directory. Now it's new room for -+ the new set of documentation files. -+ [Ralf S. Engelschall] -+ -+ *) SETs were incorrectly DER encoded. This was a major pain, because they -+ shared code with SEQUENCEs, which aren't coded the same. This means that -+ almost everything to do with SETs or SEQUENCEs has either changed name or -+ number of arguments. -+ [Ben Laurie, based on a partial fix by GP Jayan ] -+ -+ *) Fix test data to work with the above. -+ [Ben Laurie] -+ -+ *) Fix the RSA header declarations that hid a bug I fixed in 0.9.0b but -+ was already fixed by Eric for 0.9.1 it seems. -+ [Ben Laurie - pointed out by Ulf Möller ] -+ -+ *) Autodetect FreeBSD3. -+ [Ben Laurie] -+ -+ *) Fix various bugs in Configure. This affects the following platforms: -+ nextstep -+ ncr-scde -+ unixware-2.0 -+ unixware-2.0-pentium -+ sco5-cc. -+ [Ben Laurie] -+ -+ *) Eliminate generated files from CVS. Reorder tests to regenerate files -+ before they are needed. -+ [Ben Laurie] -+ -+ *) Generate Makefile.ssl from Makefile.org (to keep CVS happy). -+ [Ben Laurie] -+ -+ -+ Changes between 0.9.1b and 0.9.1c [23-Dec-1998] -+ -+ *) Added OPENSSL_VERSION_NUMBER to crypto/crypto.h and -+ changed SSLeay to OpenSSL in version strings. -+ [Ralf S. Engelschall] -+ -+ *) Some fixups to the top-level documents. -+ [Paul Sutton] -+ -+ *) Fixed the nasty bug where rsaref.h was not found under compile-time -+ because the symlink to include/ was missing. -+ [Ralf S. Engelschall] -+ -+ *) Incorporated the popular no-RSA/DSA-only patches -+ which allow to compile a RSA-free SSLeay. -+ [Andrew Cooke / Interrader Ldt., Ralf S. Engelschall] -+ -+ *) Fixed nasty rehash problem under `make -f Makefile.ssl links' -+ when "ssleay" is still not found. -+ [Ralf S. Engelschall] -+ -+ *) Added more platforms to Configure: Cray T3E, HPUX 11, -+ [Ralf S. Engelschall, Beckmann ] -+ -+ *) Updated the README file. -+ [Ralf S. Engelschall] -+ -+ *) Added various .cvsignore files in the CVS repository subdirs -+ to make a "cvs update" really silent. -+ [Ralf S. Engelschall] -+ -+ *) Recompiled the error-definition header files and added -+ missing symbols to the Win32 linker tables. -+ [Ralf S. Engelschall] -+ -+ *) Cleaned up the top-level documents; -+ o new files: CHANGES and LICENSE -+ o merged VERSION, HISTORY* and README* files a CHANGES.SSLeay -+ o merged COPYRIGHT into LICENSE -+ o removed obsolete TODO file -+ o renamed MICROSOFT to INSTALL.W32 -+ [Ralf S. Engelschall] -+ -+ *) Removed dummy files from the 0.9.1b source tree: -+ crypto/asn1/x crypto/bio/cd crypto/bio/fg crypto/bio/grep crypto/bio/vi -+ crypto/bn/asm/......add.c crypto/bn/asm/a.out crypto/dsa/f crypto/md5/f -+ crypto/pem/gmon.out crypto/perlasm/f crypto/pkcs7/build crypto/rsa/f -+ crypto/sha/asm/f crypto/threads/f ms/zzz ssl/f ssl/f.mak test/f -+ util/f.mak util/pl/f util/pl/f.mak crypto/bf/bf_locl.old apps/f -+ [Ralf S. Engelschall] -+ -+ *) Added various platform portability fixes. -+ [Mark J. Cox] -+ -+ *) The Genesis of the OpenSSL rpject: -+ We start with the latest (unreleased) SSLeay version 0.9.1b which Eric A. -+ Young and Tim J. Hudson created while they were working for C2Net until -+ summer 1998. -+ [The OpenSSL Project] -+ -+ -+ Changes between 0.9.0b and 0.9.1b [not released] -+ -+ *) Updated a few CA certificates under certs/ -+ [Eric A. Young] -+ -+ *) Changed some BIGNUM api stuff. -+ [Eric A. Young] -+ -+ *) Various platform ports: OpenBSD, Ultrix, IRIX 64bit, NetBSD, -+ DGUX x86, Linux Alpha, etc. -+ [Eric A. Young] -+ -+ *) New COMP library [crypto/comp/] for SSL Record Layer Compression: -+ RLE (dummy implemented) and ZLIB (really implemented when ZLIB is -+ available). -+ [Eric A. Young] -+ -+ *) Add -strparse option to asn1pars program which parses nested -+ binary structures -+ [Dr Stephen Henson ] -+ -+ *) Added "oid_file" to ssleay.cnf for "ca" and "req" programs. -+ [Eric A. Young] -+ -+ *) DSA fix for "ca" program. -+ [Eric A. Young] -+ -+ *) Added "-genkey" option to "dsaparam" program. -+ [Eric A. Young] -+ -+ *) Added RIPE MD160 (rmd160) message digest. -+ [Eric A. Young] -+ -+ *) Added -a (all) option to "ssleay version" command. -+ [Eric A. Young] -+ -+ *) Added PLATFORM define which is the id given to Configure. -+ [Eric A. Young] -+ -+ *) Added MemCheck_XXXX functions to crypto/mem.c for memory checking. -+ [Eric A. Young] -+ -+ *) Extended the ASN.1 parser routines. -+ [Eric A. Young] -+ -+ *) Extended BIO routines to support REUSEADDR, seek, tell, etc. -+ [Eric A. Young] -+ -+ *) Added a BN_CTX to the BN library. -+ [Eric A. Young] -+ -+ *) Fixed the weak key values in DES library -+ [Eric A. Young] -+ -+ *) Changed API in EVP library for cipher aliases. -+ [Eric A. Young] -+ -+ *) Added support for RC2/64bit cipher. -+ [Eric A. Young] -+ -+ *) Converted the lhash library to the crypto/mem.c functions. -+ [Eric A. Young] -+ -+ *) Added more recognized ASN.1 object ids. -+ [Eric A. Young] -+ -+ *) Added more RSA padding checks for SSL/TLS. -+ [Eric A. Young] -+ -+ *) Added BIO proxy/filter functionality. -+ [Eric A. Young] -+ -+ *) Added extra_certs to SSL_CTX which can be used -+ send extra CA certificates to the client in the CA cert chain sending -+ process. It can be configured with SSL_CTX_add_extra_chain_cert(). -+ [Eric A. Young] -+ -+ *) Now Fortezza is denied in the authentication phase because -+ this is key exchange mechanism is not supported by SSLeay at all. -+ [Eric A. Young] -+ -+ *) Additional PKCS1 checks. -+ [Eric A. Young] -+ -+ *) Support the string "TLSv1" for all TLS v1 ciphers. -+ [Eric A. Young] -+ -+ *) Added function SSL_get_ex_data_X509_STORE_CTX_idx() which gives the -+ ex_data index of the SSL context in the X509_STORE_CTX ex_data. -+ [Eric A. Young] -+ -+ *) Fixed a few memory leaks. -+ [Eric A. Young] -+ -+ *) Fixed various code and comment typos. -+ [Eric A. Young] -+ -+ *) A minor bug in ssl/s3_clnt.c where there would always be 4 0 -+ bytes sent in the client random. -+ [Edward Bishop ] -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/CONTRIBUTING b/CryptoPkg/Library/OpensslLib/openssl/CONTRIBUTING -new file mode 100644 -index 0000000..1eebaf3 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/CONTRIBUTING -@@ -0,0 +1,54 @@ -+HOW TO CONTRIBUTE PATCHES TO OpenSSL -+------------------------------------ -+ -+(Please visit https://www.openssl.org/community/getting-started.html for -+other ideas about how to contribute.) -+ -+Development is coordinated on the openssl-dev mailing list (see the -+above link or https://mta.openssl.org for information on subscribing). -+If you are unsure as to whether a feature will be useful for the general -+OpenSSL community you might want to discuss it on the openssl-dev mailing -+list first. Someone may be already working on the same thing or there -+may be a good reason as to why that feature isn't implemented. -+ -+To submit a patch, make a pull request on GitHub. If you think the patch -+could use feedback from the community, please start a thread on openssl-dev -+to discuss it. -+ -+Having addressed the following items before the PR will help make the -+acceptance and review process faster: -+ -+ 1. Anything other than trivial contributions will require a contributor -+ licensing agreement, giving us permission to use your code. See -+ https://www.openssl.org/policies/cla.html for details. -+ -+ 2. All source files should start with the following text (with -+ appropriate comment characters at the start of each line and the -+ year(s) updated): -+ -+ Copyright 20xx-20yy The OpenSSL Project Authors. All Rights Reserved. -+ -+ Licensed under the OpenSSL license (the "License"). You may not use -+ this file except in compliance with the License. You can obtain a copy -+ in the file LICENSE in the source distribution or at -+ https://www.openssl.org/source/license.html -+ -+ 3. Patches should be as current as possible; expect to have to rebase -+ often. We do not accept merge commits; You will be asked to remove -+ them before a patch is considered acceptable. -+ -+ 4. Patches should follow our coding style (see -+ https://www.openssl.org/policies/codingstyle.html) and compile without -+ warnings. Where gcc or clang is available you should use the -+ --strict-warnings Configure option. OpenSSL compiles on many varied -+ platforms: try to ensure you only use portable features. -+ Clean builds via Travis and AppVeyor are expected, and done whenever -+ a PR is created or updated. -+ -+ 5. When at all possible, patches should include tests. These can -+ either be added to an existing test, or completely new. Please see -+ test/README for information on the test framework. -+ -+ 6. New features or changed functionality must include -+ documentation. Please look at the "pod" files in doc/apps, doc/crypto -+ and doc/ssl for examples of our style. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/00-base-templates.conf b/CryptoPkg/Library/OpensslLib/openssl/Configurations/00-base-templates.conf -new file mode 100644 -index 0000000..3455b3a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/00-base-templates.conf -@@ -0,0 +1,293 @@ -+# -*- Mode: perl -*- -+%targets=( -+ DEFAULTS => { -+ template => 1, -+ -+ cflags => "", -+ defines => [], -+ thread_scheme => "(unknown)", # Assume we don't know -+ thread_defines => [], -+ -+ apps_aux_src => "", -+ cpuid_asm_src => "mem_clr.c", -+ uplink_aux_src => "", -+ bn_asm_src => "bn_asm.c", -+ ec_asm_src => "", -+ des_asm_src => "des_enc.c fcrypt_b.c", -+ aes_asm_src => "aes_core.c aes_cbc.c", -+ bf_asm_src => "bf_enc.c", -+ md5_asm_src => "", -+ cast_asm_src => "c_enc.c", -+ rc4_asm_src => "rc4_enc.c rc4_skey.c", -+ rmd160_asm_src => "", -+ rc5_asm_src => "rc5_enc.c", -+ wp_asm_src => "wp_block.c", -+ cmll_asm_src => "camellia.c cmll_misc.c cmll_cbc.c", -+ modes_asm_src => "", -+ padlock_asm_src => "", -+ chacha_asm_src => "chacha_enc.c", -+ poly1305_asm_src => "", -+ -+ unistd => "", -+ shared_target => "", -+ shared_cflag => "", -+ shared_defines => [], -+ shared_ldflag => "", -+ shared_rcflag => "", -+ shared_extension => "", -+ -+ build_scheme => [ "unified", "unix" ], -+ build_file => "Makefile", -+ }, -+ -+ BASE_common => { -+ template => 1, -+ defines => -+ sub { -+ my @defs = (); -+ push @defs, "ZLIB" unless $disabled{zlib}; -+ push @defs, "ZLIB_SHARED" unless $disabled{"zlib-dynamic"}; -+ return [ @defs ]; -+ }, -+ }, -+ -+ BASE_unix => { -+ inherit_from => [ "BASE_common" ], -+ template => 1, -+ -+ ex_libs => -+ sub { -+ unless ($disabled{zlib}) { -+ if (defined($disabled{"zlib-dynamic"})) { -+ if (defined($withargs{zlib_lib})) { -+ return "-L".$withargs{zlib_lib}." -lz"; -+ } else { -+ return "-lz"; -+ } -+ } -+ } -+ return (); }, -+ -+ build_scheme => [ "unified", "unix" ], -+ build_file => "Makefile", -+ }, -+ -+ BASE_Windows => { -+ inherit_from => [ "BASE_common" ], -+ template => 1, -+ -+ ex_libs => -+ sub { -+ unless ($disabled{zlib}) { -+ if (defined($disabled{"zlib-dynamic"})) { -+ return $withargs{zlib_lib} // "ZLIB1"; -+ } -+ } -+ return (); -+ }, -+ -+ ld => "link", -+ lflags => "/nologo", -+ loutflag => "/out:", -+ ar => "lib", -+ arflags => "/nologo", -+ aroutflag => "/out:", -+ rc => "rc", -+ rcoutflag => "/fo", -+ mt => "mt", -+ mtflags => "-nologo", -+ mtinflag => "-manifest ", -+ mtoutflag => "-outputresource:", -+ -+ build_file => "makefile", -+ build_scheme => [ "unified", "windows" ], -+ }, -+ -+ BASE_VMS => { -+ inherit_from => [ "BASE_common" ], -+ template => 1, -+ -+ build_file => "descrip.mms", -+ build_scheme => [ "unified", "VMS" ], -+ }, -+ -+ uplink_common => { -+ template => 1, -+ apps_aux_src => add("../ms/applink.c"), -+ uplink_aux_src => add("../ms/uplink.c"), -+ defines => add("OPENSSL_USE_APPLINK"), -+ }, -+ x86_uplink => { -+ inherit_from => [ "uplink_common" ], -+ template => 1, -+ uplink_aux_src => add("uplink-x86.s"), -+ }, -+ x86_64_uplink => { -+ inherit_from => [ "uplink_common" ], -+ template => 1, -+ uplink_aux_src => add("uplink-x86_64.s"), -+ }, -+ ia64_uplink => { -+ inherit_from => [ "uplink_common" ], -+ template => 1, -+ uplink_aux_src => add("uplink-ia64.s"), -+ }, -+ -+ x86_asm => { -+ template => 1, -+ cpuid_asm_src => "x86cpuid.s", -+ bn_asm_src => "bn-586.s co-586.s x86-mont.s x86-gf2m.s", -+ ec_asm_src => "ecp_nistz256.c ecp_nistz256-x86.s", -+ des_asm_src => "des-586.s crypt586.s", -+ aes_asm_src => "aes-586.s vpaes-x86.s aesni-x86.s", -+ bf_asm_src => "bf-586.s", -+ md5_asm_src => "md5-586.s", -+ cast_asm_src => "cast-586.s", -+ sha1_asm_src => "sha1-586.s sha256-586.s sha512-586.s", -+ rc4_asm_src => "rc4-586.s", -+ rmd160_asm_src => "rmd-586.s", -+ rc5_asm_src => "rc5-586.s", -+ wp_asm_src => "wp_block.c wp-mmx.s", -+ cmll_asm_src => "cmll-x86.s", -+ modes_asm_src => "ghash-x86.s", -+ padlock_asm_src => "e_padlock-x86.s", -+ chacha_asm_src => "chacha-x86.s", -+ poly1305_asm_src=> "poly1305-x86.s", -+ }, -+ x86_elf_asm => { -+ template => 1, -+ inherit_from => [ "x86_asm" ], -+ perlasm_scheme => "elf" -+ }, -+ x86_64_asm => { -+ template => 1, -+ cpuid_asm_src => "x86_64cpuid.s", -+ bn_asm_src => "asm/x86_64-gcc.c x86_64-mont.s x86_64-mont5.s x86_64-gf2m.s rsaz_exp.c rsaz-x86_64.s rsaz-avx2.s", -+ ec_asm_src => "ecp_nistz256.c ecp_nistz256-x86_64.s", -+ aes_asm_src => "aes-x86_64.s vpaes-x86_64.s bsaes-x86_64.s aesni-x86_64.s aesni-sha1-x86_64.s aesni-sha256-x86_64.s aesni-mb-x86_64.s", -+ md5_asm_src => "md5-x86_64.s", -+ sha1_asm_src => "sha1-x86_64.s sha256-x86_64.s sha512-x86_64.s sha1-mb-x86_64.s sha256-mb-x86_64.s", -+ rc4_asm_src => "rc4-x86_64.s rc4-md5-x86_64.s", -+ wp_asm_src => "wp-x86_64.s", -+ cmll_asm_src => "cmll-x86_64.s cmll_misc.c", -+ modes_asm_src => "ghash-x86_64.s aesni-gcm-x86_64.s", -+ padlock_asm_src => "e_padlock-x86_64.s", -+ chacha_asm_src => "chacha-x86_64.s", -+ poly1305_asm_src=> "poly1305-x86_64.s", -+ }, -+ ia64_asm => { -+ template => 1, -+ cpuid_asm_src => "ia64cpuid.s", -+ bn_asm_src => "bn-ia64.s ia64-mont.s", -+ aes_asm_src => "aes_core.c aes_cbc.c aes-ia64.s", -+ md5_asm_src => "md5-ia64.s", -+ sha1_asm_src => "sha1-ia64.s sha256-ia64.s sha512-ia64.s", -+ rc4_asm_src => "rc4-ia64.s rc4_skey.c", -+ modes_asm_src => "ghash-ia64.s", -+ perlasm_scheme => "void" -+ }, -+ sparcv9_asm => { -+ template => 1, -+ cpuid_asm_src => "sparcv9cap.c sparccpuid.S", -+ bn_asm_src => "asm/sparcv8plus.S sparcv9-mont.S sparcv9a-mont.S vis3-mont.S sparct4-mont.S sparcv9-gf2m.S", -+ ec_asm_src => "ecp_nistz256.c ecp_nistz256-sparcv9.S", -+ des_asm_src => "des_enc-sparc.S fcrypt_b.c dest4-sparcv9.S", -+ aes_asm_src => "aes_core.c aes_cbc.c aes-sparcv9.S aest4-sparcv9.S aesfx-sparcv9.S", -+ md5_asm_src => "md5-sparcv9.S", -+ sha1_asm_src => "sha1-sparcv9.S sha256-sparcv9.S sha512-sparcv9.S", -+ cmll_asm_src => "camellia.c cmll_misc.c cmll_cbc.c cmllt4-sparcv9.S", -+ modes_asm_src => "ghash-sparcv9.S", -+ poly1305_asm_src=> "poly1305-sparcv9.S", -+ perlasm_scheme => "void" -+ }, -+ sparcv8_asm => { -+ template => 1, -+ cpuid_asm_src => "", -+ bn_asm_src => "asm/sparcv8.S", -+ des_asm_src => "des_enc-sparc.S fcrypt_b.c", -+ perlasm_scheme => "void" -+ }, -+ alpha_asm => { -+ template => 1, -+ cpuid_asm_src => "alphacpuid.s", -+ bn_asm_src => "bn_asm.c alpha-mont.S", -+ sha1_asm_src => "sha1-alpha.S", -+ modes_asm_src => "ghash-alpha.S", -+ perlasm_scheme => "void" -+ }, -+ mips32_asm => { -+ template => 1, -+ bn_asm_src => "bn-mips.s mips-mont.s", -+ aes_asm_src => "aes_cbc.c aes-mips.S", -+ sha1_asm_src => "sha1-mips.S sha256-mips.S", -+ }, -+ mips64_asm => { -+ inherit_from => [ "mips32_asm" ], -+ template => 1, -+ sha1_asm_src => add("sha512-mips.S"), -+ poly1305_asm_src=> "poly1305-mips.S", -+ }, -+ s390x_asm => { -+ template => 1, -+ cpuid_asm_src => "s390xcap.c s390xcpuid.S", -+ bn_asm_src => "asm/s390x.S s390x-mont.S s390x-gf2m.s", -+ aes_asm_src => "aes-s390x.S aes-ctr.fake aes-xts.fake", -+ sha1_asm_src => "sha1-s390x.S sha256-s390x.S sha512-s390x.S", -+ rc4_asm_src => "rc4-s390x.s", -+ modes_asm_src => "ghash-s390x.S", -+ chacha_asm_src => "chacha-s390x.S", -+ poly1305_asm_src=> "poly1305-s390x.S", -+ }, -+ armv4_asm => { -+ template => 1, -+ cpuid_asm_src => "armcap.c armv4cpuid.S", -+ bn_asm_src => "bn_asm.c armv4-mont.S armv4-gf2m.S", -+ ec_asm_src => "ecp_nistz256.c ecp_nistz256-armv4.S", -+ aes_asm_src => "aes_cbc.c aes-armv4.S bsaes-armv7.S aesv8-armx.S", -+ sha1_asm_src => "sha1-armv4-large.S sha256-armv4.S sha512-armv4.S", -+ modes_asm_src => "ghash-armv4.S ghashv8-armx.S", -+ chacha_asm_src => "chacha-armv4.S", -+ poly1305_asm_src=> "poly1305-armv4.S", -+ perlasm_scheme => "void" -+ }, -+ aarch64_asm => { -+ template => 1, -+ cpuid_asm_src => "armcap.c arm64cpuid.S", -+ ec_asm_src => "ecp_nistz256.c ecp_nistz256-armv8.S", -+ bn_asm_src => "bn_asm.c armv8-mont.S", -+ aes_asm_src => "aes_core.c aes_cbc.c aesv8-armx.S vpaes-armv8.S", -+ sha1_asm_src => "sha1-armv8.S sha256-armv8.S sha512-armv8.S", -+ modes_asm_src => "ghashv8-armx.S", -+ chacha_asm_src => "chacha-armv8.S", -+ poly1305_asm_src=> "poly1305-armv8.S", -+ }, -+ parisc11_asm => { -+ template => 1, -+ cpuid_asm_src => "pariscid.s", -+ bn_asm_src => "bn_asm.c parisc-mont.s", -+ aes_asm_src => "aes_core.c aes_cbc.c aes-parisc.s", -+ sha1_asm_src => "sha1-parisc.s sha256-parisc.s sha512-parisc.s", -+ rc4_asm_src => "rc4-parisc.s", -+ modes_asm_src => "ghash-parisc.s", -+ perlasm_scheme => "32" -+ }, -+ parisc20_64_asm => { -+ template => 1, -+ inherit_from => [ "parisc11_asm" ], -+ perlasm_scheme => "64", -+ }, -+ ppc64_asm => { -+ template => 1, -+ cpuid_asm_src => "ppccpuid.s ppccap.c", -+ bn_asm_src => "bn-ppc.s ppc-mont.s ppc64-mont.s", -+ aes_asm_src => "aes_core.c aes_cbc.c aes-ppc.s vpaes-ppc.s aesp8-ppc.s", -+ sha1_asm_src => "sha1-ppc.s sha256-ppc.s sha512-ppc.s sha256p8-ppc.s sha512p8-ppc.s", -+ modes_asm_src => "ghashp8-ppc.s", -+ chacha_asm_src => "chacha-ppc.s", -+ poly1305_asm_src=> "poly1305-ppc.s poly1305-ppcfp.s", -+ }, -+ ppc32_asm => { -+ inherit_from => [ "ppc64_asm" ], -+ template => 1 -+ }, -+); -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/10-main.conf b/CryptoPkg/Library/OpensslLib/openssl/Configurations/10-main.conf -new file mode 100644 -index 0000000..985220f ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/10-main.conf -@@ -0,0 +1,1894 @@ -+## -*- mode: perl; -*- -+## Standard openssl configuration targets. -+ -+# Helper functions for the Windows configs -+my $vc_win64a_info = {}; -+sub vc_win64a_info { -+ unless (%$vc_win64a_info) { -+ if (`nasm -v 2>NUL` =~ /NASM version ([0-9]+\.[0-9]+)/ && $1 >= 2.0) { -+ $vc_win64a_info = { as => "nasm", -+ asflags => "-f win64 -DNEAR -Ox -g", -+ asoutflag => "-o" }; -+ } elsif ($disabled{asm}) { -+ $vc_win64a_info = { as => "ml64", -+ asflags => "/c /Cp /Cx /Zi", -+ asoutflag => "/Fo" }; -+ } else { -+ $die->("NASM not found - please read INSTALL and NOTES.WIN for further details\n"); -+ $vc_win64a_info = { as => "{unknown}", -+ asflags => "", -+ asoutflag => "" }; -+ } -+ } -+ return $vc_win64a_info; -+} -+ -+my $vc_win32_info = {}; -+sub vc_win32_info { -+ unless (%$vc_win32_info) { -+ my $ver=`nasm -v 2>NUL`; -+ my $vew=`nasmw -v 2>NUL`; -+ if ($ver ne "" || $vew ne "") { -+ $vc_win32_info = { as => $ver ge $vew ? "nasm" : "nasmw", -+ asflags => "-f win32", -+ asoutflag => "-o", -+ perlasm_scheme => "win32n" }; -+ } elsif ($disabled{asm}) { -+ $vc_win32_info = { as => "ml", -+ asflags => "/nologo /Cp /coff /c /Cx /Zi", -+ asoutflag => "/Fo", -+ perlasm_scheme => "win32" }; -+ } else { -+ $die->("NASM not found - please read INSTALL and NOTES.WIN for further details\n"); -+ $vc_win32_info = { as => "{unknown}", -+ asflags => "", -+ asoutflag => "", -+ perlasm_scheme => "win32" }; -+ } -+ } -+ return $vc_win32_info; -+} -+ -+my $vc_wince_info = {}; -+sub vc_wince_info { -+ unless (%$vc_wince_info) { -+ # sanity check -+ $die->('%OSVERSION% is not defined') if (!defined($ENV{'OSVERSION'})); -+ $die->('%PLATFORM% is not defined') if (!defined($ENV{'PLATFORM'})); -+ $die->('%TARGETCPU% is not defined') if (!defined($ENV{'TARGETCPU'})); -+ -+ # -+ # Idea behind this is to mimic flags set by eVC++ IDE... -+ # -+ my $wcevers = $ENV{'OSVERSION'}; # WCENNN -+ my $wcevernum; -+ my $wceverdotnum; -+ if ($wcevers =~ /^WCE([1-9])([0-9]{2})$/) { -+ $wcevernum = "$1$2"; -+ $wceverdotnum = "$1.$2"; -+ } else { -+ $die->('%OSVERSION% value is insane'); -+ $wcevernum = "{unknown}"; -+ $wceverdotnum = "{unknown}"; -+ } -+ my $wcecdefs = "-D_WIN32_WCE=$wcevernum -DUNDER_CE=$wcevernum"; # -D_WIN32_WCE=NNN -+ my $wcelflag = "/subsystem:windowsce,$wceverdotnum"; # ...,N.NN -+ -+ my $wceplatf = $ENV{'PLATFORM'}; -+ -+ $wceplatf =~ tr/a-z0-9 /A-Z0-9_/; -+ $wcecdefs .= " -DWCE_PLATFORM_$wceplatf"; -+ -+ my $wcetgt = $ENV{'TARGETCPU'}; # just shorter name... -+ SWITCH: for($wcetgt) { -+ /^X86/ && do { $wcecdefs.=" -Dx86 -D_X86_ -D_i386_ -Di_386_"; -+ $wcelflag.=" /machine:X86"; last; }; -+ /^ARMV4[IT]/ && do { $wcecdefs.=" -DARM -D_ARM_ -D$wcetgt"; -+ $wcecdefs.=" -DTHUMB -D_THUMB_" if($wcetgt=~/T$/); -+ $wcecdefs.=" -QRarch4T -QRinterwork-return"; -+ $wcelflag.=" /machine:THUMB"; last; }; -+ /^ARM/ && do { $wcecdefs.=" -DARM -D_ARM_ -D$wcetgt"; -+ $wcelflag.=" /machine:ARM"; last; }; -+ /^MIPSIV/ && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt"; -+ $wcecdefs.=" -D_MIPS64 -QMmips4 -QMn32"; -+ $wcelflag.=" /machine:MIPSFPU"; last; }; -+ /^MIPS16/ && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt"; -+ $wcecdefs.=" -DMIPSII -QMmips16"; -+ $wcelflag.=" /machine:MIPS16"; last; }; -+ /^MIPSII/ && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt"; -+ $wcecdefs.=" -QMmips2"; -+ $wcelflag.=" /machine:MIPS"; last; }; -+ /^R4[0-9]{3}/ && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000"; -+ $wcelflag.=" /machine:MIPS"; last; }; -+ /^SH[0-9]/ && do { $wcecdefs.=" -D$wcetgt -D_${wcetgt}_ -DSHx"; -+ $wcecdefs.=" -Qsh4" if ($wcetgt =~ /^SH4/); -+ $wcelflag.=" /machine:$wcetgt"; last; }; -+ { $wcecdefs.=" -D$wcetgt -D_${wcetgt}_"; -+ $wcelflag.=" /machine:$wcetgt"; last; }; -+ } -+ -+ $vc_wince_info = { cflags => $wcecdefs, -+ lflags => $wcelflag }; -+ } -+ return $vc_wince_info; -+} -+ -+# Helper functions for the VMS configs -+my $vms_info = {}; -+sub vms_info { -+ unless (%$vms_info) { -+ my $pointer_size = shift; -+ my $pointer_size_str = $pointer_size == 0 ? "" : "$pointer_size"; -+ -+ $vms_info->{disable_warns} = [ ]; -+ $vms_info->{pointer_size} = $pointer_size_str; -+ if ($pointer_size == 64) { -+ `PIPE CC /NOCROSS_REFERENCE /NOLIST /NOOBJECT /WARNINGS = DISABLE = ( MAYLOSEDATA3, EMPTYFILE ) NL: 2> NL:`; -+ if ($? == 0) { -+ push @{$vms_info->{disable_warns}}, "MAYLOSEDATA3"; -+ } -+ } -+ -+ unless ($disabled{zlib}) { -+ my $default_zlib = 'GNV$LIBZSHR' . $pointer_size_str; -+ if (defined($disabled{"zlib-dynamic"})) { -+ $vms_info->{zlib} = $withargs{zlib_lib} || "$default_zlib/SHARE"; -+ } else { -+ $vms_info->{def_zlib} = $withargs{zlib_lib} || $default_zlib; -+ # In case the --with-zlib-lib value contains something like -+ # /SHARE or /LIB or so at the end, remove it. -+ $vms_info->{def_zlib} =~ s|/.*$||g; -+ } -+ } -+ } -+ return $vms_info; -+} -+ -+%targets = ( -+ -+#### Basic configs that should work on any 32-bit box -+ "gcc" => { -+ cc => "gcc", -+ cflags => picker(debug => "-O0 -g", -+ release => "-O3"), -+ thread_scheme => "(unknown)", -+ bn_ops => "BN_LLONG", -+ }, -+ "cc" => { -+ cc => "cc", -+ cflags => "-O", -+ thread_scheme => "(unknown)", -+ }, -+ -+#### VOS Configurations -+ "vos-gcc" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "gcc", -+ cflags => picker(default => "-Wall -DOPENSSL_SYS_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN", -+ debug => "-O0 -g", -+ release => "-O3"), -+ thread_scheme => "(unknown)", -+ sys_id => "VOS", -+ lflags => "-Wl,-map", -+ bn_ops => "BN_LLONG", -+ shared_extension => ".so", -+ }, -+ -+#### Solaris configurations -+ "solaris-common" => { -+ inherit_from => [ "BASE_unix" ], -+ template => 1, -+ cflags => "-DFILIO_H", -+ ex_libs => add("-lresolv -lsocket -lnsl -ldl"), -+ dso_scheme => "dlfcn", -+ thread_scheme => "pthreads", -+ shared_target => "solaris-shared", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+#### Solaris x86 with GNU C setups -+ "solaris-x86-gcc" => { -+ # NB. GNU C has to be configured to use GNU assembler, and not -+ # /usr/ccs/bin/as. Failure to comply will result in compile -+ # failures [at least] in 32-bit build. -+ # [Above statement is in direct contradition with one below. -+ # Latter is kept, because it's formally inappropriate to -+ # modify compile flags in letter release.] -+ # -DOPENSSL_NO_INLINE_ASM switches off inline assembler. We have -+ # to do it here because whenever GNU C instantiates an assembler -+ # template it surrounds it with #APP #NO_APP comment pair which -+ # (at least Solaris 7_x86) /usr/ccs/bin/as fails to assemble -+ # with "Illegal mnemonic" error message. -+ inherit_from => [ "solaris-common", asm("x86_elf_asm") ], -+ cc => "gcc", -+ cflags => add_before(picker(default => "-Wall -DL_ENDIAN -DOPENSSL_NO_INLINE_ASM", -+ debug => "-O0 -g", -+ release => "-O3 -fomit-frame-pointer"), -+ threads("-pthread")), -+ bn_ops => "BN_LLONG", -+ shared_cflag => "-fPIC", -+ shared_ldflag => "-shared -static-libgcc", -+ }, -+ "solaris64-x86_64-gcc" => { -+ # -shared -static-libgcc might appear controversial, but modules -+ # taken from static libgcc do not have relocations and linking -+ # them into our shared objects doesn't have any negative side -+ # effects. On the contrary, doing so makes it possible to use -+ # gcc shared build with Sun C. Given that gcc generates faster -+ # code [thanks to inline assembler], I would actually recommend -+ # to consider using gcc shared build even with vendor compiler:-) -+ # -+ inherit_from => [ "solaris-common", asm("x86_64_asm") ], -+ cc => "gcc", -+ cflags => add_before(picker(default => "-m64 -Wall -DL_ENDIAN", -+ debug => "-O0 -g", -+ release => "-O3"), -+ threads("-pthread")), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ perlasm_scheme => "elf", -+ shared_cflag => "-fPIC", -+ shared_ldflag => "-m64 -shared -static-libgcc", -+ multilib => "/64", -+ }, -+ -+#### Solaris x86 with Sun C setups -+ # There used to be solaris-x86-cc target, but it was removed, -+ # primarily because vendor assembler can't assemble our modules -+ # with -KPIC flag. As result it, assembly support, was not even -+ # available as option. But its lack means lack of side-channel -+ # resistant code, which is incompatible with security by todays -+ # standards. Fortunately gcc is readily available prepackaged -+ # option, which we can firmly point at... -+ # -+ # On related note, solaris64-x86_64-cc target won't compile code -+ # paths utilizing AVX and post-Haswell instruction extensions. -+ # Consider switching to solaris64-x86_64-gcc even here... -+ # -+ "solaris64-x86_64-cc" => { -+ inherit_from => [ "solaris-common", asm("x86_64_asm") ], -+ cc => "cc", -+ cflags => add_before(picker(default => "-xarch=generic64 -xstrconst -Xa -DL_ENDIAN", -+ debug => "-g", -+ release => "-xO5 -xdepend -xbuiltin"), -+ threads("-D_REENTRANT")), -+ thread_scheme => "pthreads", -+ lflags => add("-xarch=generic64",threads("-mt")), -+ ex_libs => add(threads("-lpthread")), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ perlasm_scheme => "elf", -+ shared_cflag => "-KPIC", -+ shared_ldflag => "-xarch=generic64 -G -dy -z text", -+ multilib => "/64", -+ }, -+ -+#### SPARC Solaris with GNU C setups -+ "solaris-sparcv7-gcc" => { -+ inherit_from => [ "solaris-common" ], -+ cc => "gcc", -+ cflags => add_before(picker(default => "-Wall -DB_ENDIAN -DBN_DIV2W", -+ debug => "-O0 -g", -+ release => "-O3"), -+ threads("-pthread")), -+ bn_ops => "BN_LLONG RC4_CHAR", -+ shared_cflag => "-fPIC", -+ shared_ldflag => "-shared", -+ }, -+ "solaris-sparcv8-gcc" => { -+ inherit_from => [ "solaris-sparcv7-gcc", asm("sparcv8_asm") ], -+ cflags => add_before("-mcpu=v8"), -+ }, -+ "solaris-sparcv9-gcc" => { -+ # -m32 should be safe to add as long as driver recognizes -+ # -mcpu=ultrasparc -+ inherit_from => [ "solaris-sparcv7-gcc", asm("sparcv9_asm") ], -+ cflags => add_before("-m32 -mcpu=ultrasparc"), -+ }, -+ "solaris64-sparcv9-gcc" => { -+ inherit_from => [ "solaris-sparcv9-gcc" ], -+ cflags => sub { my $f=join(" ",@_); $f =~ s/\-m32/-m64/; $f; }, -+ bn_ops => "BN_LLONG RC4_CHAR", -+ shared_ldflag => "-m64 -shared", -+ multilib => "/64", -+ }, -+ -+#### SPARC Solaris with Sun C setups -+# SC4.0 doesn't pass 'make test', upgrade to SC5.0 or SC4.2. -+# SC4.2 is ok, better than gcc even on bn as long as you tell it -xarch=v8 -+# SC5.0 note: Compiler common patch 107357-01 or later is required! -+ "solaris-sparcv7-cc" => { -+ inherit_from => [ "solaris-common" ], -+ cc => "cc", -+ cflags => add_before(picker(default => "-xstrconst -Xa -DB_ENDIAN -DBN_DIV2W", -+ debug => "-g", -+ release => "-xO5 -xdepend"), -+ threads("-D_REENTRANT")), -+ lflags => add(threads("-mt")), -+ ex_libs => add(threads("-lpthread")), -+ bn_ops => "BN_LLONG RC4_CHAR", -+ shared_cflag => "-KPIC", -+ shared_ldflag => "-G -dy -z text", -+ }, -+#### -+ "solaris-sparcv8-cc" => { -+ inherit_from => [ "solaris-sparcv7-cc", asm("sparcv8_asm") ], -+ cflags => add_before("-xarch=v8"), -+ }, -+ "solaris-sparcv9-cc" => { -+ inherit_from => [ "solaris-sparcv7-cc", asm("sparcv9_asm") ], -+ cflags => add_before("-xarch=v8plus"), -+ }, -+ "solaris64-sparcv9-cc" => { -+ inherit_from => [ "solaris-sparcv7-cc", asm("sparcv9_asm") ], -+ cflags => add_before("-xarch=v9"), -+ lflags => add_before("-xarch=v9"), -+ bn_ops => "BN_LLONG RC4_CHAR", -+ shared_ldflag => "-xarch=v9 -G -dy -z text", -+ multilib => "/64", -+ }, -+ -+#### IRIX 6.x configs -+# Only N32 and N64 ABIs are supported. -+ "irix-mips3-gcc" => { -+ inherit_from => [ "BASE_unix", asm("mips64_asm") ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-mabi=n32 -DB_ENDIAN -DBN_DIV3W", -+ debug => "-g -O0", -+ release => "-O3"), -+ threads("-D_SGI_MP_SOURCE")), -+ ex_libs => add(threads("-lpthread")), -+ bn_ops => "RC4_CHAR SIXTY_FOUR_BIT", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "n32", -+ dso_scheme => "dlfcn", -+ shared_target => "irix-shared", -+ shared_ldflag => "-mabi=n32", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "32", -+ }, -+ "irix-mips3-cc" => { -+ inherit_from => [ "BASE_unix", asm("mips64_asm") ], -+ cc => "cc", -+ cflags => combine(picker(default => "-n32 -mips3 -use_readonly_const -G0 -rdata_shared -DB_ENDIAN -DBN_DIV3W", -+ debug => "-g -O0", -+ release => "-O2"), -+ threads("-D_SGI_MP_SOURCE")), -+ ex_libs => add(threads("-lpthread")), -+ bn_ops => "RC4_CHAR SIXTY_FOUR_BIT", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "n32", -+ dso_scheme => "dlfcn", -+ shared_target => "irix-shared", -+ shared_ldflag => "-n32", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "32", -+ }, -+ # N64 ABI builds. -+ "irix64-mips4-gcc" => { -+ inherit_from => [ "BASE_unix", asm("mips64_asm") ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-mabi=64 -mips4 -DB_ENDIAN -DBN_DIV3W", -+ debug => "-g -O0", -+ release => "-O3"), -+ threads("-D_SGI_MP_SOURCE")), -+ ex_libs => add(threads("-lpthread")), -+ bn_ops => "RC4_CHAR SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "64", -+ dso_scheme => "dlfcn", -+ shared_target => "irix-shared", -+ shared_ldflag => "-mabi=64", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "64", -+ }, -+ "irix64-mips4-cc" => { -+ inherit_from => [ "BASE_unix", asm("mips64_asm") ], -+ cc => "cc", -+ cflags => combine(picker(default => "-64 -mips4 -use_readonly_const -G0 -rdata_shared -DB_ENDIAN -DBN_DIV3W", -+ debug => "-g -O0", -+ release => "-O2"), -+ threads("-D_SGI_MP_SOURCE")), -+ ex_libs => add(threads("-lpthread")), -+ bn_ops => "RC4_CHAR SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "64", -+ dso_scheme => "dlfcn", -+ shared_target => "irix-shared", -+ shared_ldflag => "-64", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "64", -+ }, -+ -+#### Unified HP-UX ANSI C configs. -+# Special notes: -+# - Originally we were optimizing at +O4 level. It should be noted -+# that the only difference between +O3 and +O4 is global inter- -+# procedural analysis. As it has to be performed during the link -+# stage the compiler leaves behind certain pseudo-code in lib*.a -+# which might be release or even patch level specific. Generating -+# the machine code for and analyzing the *whole* program appears -+# to be *extremely* memory demanding while the performance gain is -+# actually questionable. The situation is intensified by the default -+# HP-UX data set size limit (infamous 'maxdsiz' tunable) of 64MB -+# which is way too low for +O4. In other words, doesn't +O3 make -+# more sense? -+# - Keep in mind that the HP compiler by default generates code -+# suitable for execution on the host you're currently compiling at. -+# If the toolkit is meant to be used on various PA-RISC processors -+# consider './Configure hpux-parisc-[g]cc +DAportable'. -+# - -DMD32_XARRAY triggers workaround for compiler bug we ran into in -+# 32-bit message digests. (For the moment of this writing) HP C -+# doesn't seem to "digest" too many local variables (they make "him" -+# chew forever:-). For more details look-up MD32_XARRAY comment in -+# crypto/sha/sha_lcl.h. -+# - originally there were 32-bit hpux-parisc2-* targets. They were -+# scrapped, because a) they were not interchangeable with other 32-bit -+# targets; b) performance-critical 32-bit assembly modules implement -+# even PA-RISC 2.0-specific code paths, which are chosen at run-time, -+# thus adequate performance is provided even with PA-RISC 1.1 build. -+# -+ "hpux-parisc-gcc" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-DB_ENDIAN -DBN_DIV2W", -+ debug => "-O0 -g", -+ release => "-O3"), -+ threads("-pthread")), -+ ex_libs => add("-Wl,+s -ldld"), -+ bn_ops => "BN_LLONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "dl", -+ shared_target => "hpux-shared", -+ shared_cflag => "-fPIC", -+ shared_ldflag => "-shared", -+ shared_extension => ".sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ "hpux-parisc1_1-gcc" => { -+ inherit_from => [ "hpux-parisc-gcc", asm("parisc11_asm") ], -+ multilib => "/pa1.1", -+ }, -+ "hpux64-parisc2-gcc" => { -+ inherit_from => [ "BASE_unix", asm("parisc20_64_asm") ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-DB_ENDIAN", -+ debug => "-O0 -g", -+ release => "-O3"), -+ threads("-D_REENTRANT")), -+ ex_libs => add("-ldl"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "hpux-shared", -+ shared_cflag => "-fpic", -+ shared_ldflag => "-shared", -+ shared_extension => ".sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "/pa20_64", -+ }, -+ -+ # More attempts at unified 10.X and 11.X targets for HP C compiler. -+ # -+ # Chris Ruemmler -+ # Kevin Steves -+ "hpux-parisc-cc" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "cc", -+ cflags => combine(picker(default => "+Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY", -+ debug => "+O0 +d -g", -+ release => "+O3"), -+ threads("-D_REENTRANT")), -+ ex_libs => add("-Wl,+s -ldld",threads("-lpthread")), -+ bn_ops => "RC4_CHAR", -+ thread_scheme => "pthreads", -+ dso_scheme => "dl", -+ shared_target => "hpux-shared", -+ shared_cflag => "+Z", -+ shared_ldflag => "-b", -+ shared_extension => ".sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ "hpux-parisc1_1-cc" => { -+ inherit_from => [ "hpux-parisc-cc", asm("parisc11_asm") ], -+ cflags => add_before("+DA1.1"), -+ multilib => "/pa1.1", -+ }, -+ "hpux64-parisc2-cc" => { -+ inherit_from => [ "BASE_unix", asm("parisc20_64_asm") ], -+ cc => "cc", -+ cflags => combine(picker(default => "+DD64 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY", -+ debug => "+O0 +d -g", -+ release => "+O3"), -+ threads("-D_REENTRANT")), -+ ex_libs => add("-ldl",threads("-lpthread")), -+ bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "hpux-shared", -+ shared_cflag => "+Z", -+ shared_ldflag => "+DD64 -b", -+ shared_extension => ".sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "/pa20_64", -+ }, -+ -+ # HP/UX IA-64 targets -+ "hpux-ia64-cc" => { -+ inherit_from => [ "BASE_unix", asm("ia64_asm") ], -+ cc => "cc", -+ cflags => combine(picker(default => "-Ae +DD32 +Olit=all -z -DB_ENDIAN", -+ debug => "+O0 +d -g", -+ release => "+O2"), -+ threads("-D_REENTRANT")), -+ ex_libs => add("-ldl",threads("-lpthread")), -+ bn_ops => "SIXTY_FOUR_BIT", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "hpux-shared", -+ shared_cflag => "+Z", -+ shared_ldflag => "+DD32 -b", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "/hpux32", -+ }, -+ # Frank Geurts has patiently assisted -+ # with debugging of the following config. -+ "hpux64-ia64-cc" => { -+ inherit_from => [ "BASE_unix", asm("ia64_asm") ], -+ cc => "cc", -+ cflags => combine(picker(default => "-Ae +DD64 +Olit=all -z -DB_ENDIAN", -+ debug => "+O0 +d -g", -+ release => "+O3"), -+ threads("-D_REENTRANT")), -+ ex_libs => add("-ldl", threads("-lpthread")), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "hpux-shared", -+ shared_cflag => "+Z", -+ shared_ldflag => "+DD64 -b", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "/hpux64", -+ }, -+ # GCC builds... -+ "hpux-ia64-gcc" => { -+ inherit_from => [ "BASE_unix", asm("ia64_asm") ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-DB_ENDIAN", -+ debug => "-O0 -g", -+ release => "-O3"), -+ threads("-pthread")), -+ ex_libs => add("-ldl"), -+ bn_ops => "SIXTY_FOUR_BIT", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "hpux-shared", -+ shared_cflag => "-fpic", -+ shared_ldflag => "-shared", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "/hpux32", -+ }, -+ "hpux64-ia64-gcc" => { -+ inherit_from => [ "BASE_unix", asm("ia64_asm") ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-mlp64 -DB_ENDIAN", -+ debug => "-O0 -g", -+ release => "-O3"), -+ threads("-pthread")), -+ ex_libs => add("-ldl"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "hpux-shared", -+ shared_cflag => "-fpic", -+ shared_ldflag => "-mlp64 -shared", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "/hpux64", -+ }, -+ -+#### HP MPE/iX http://jazz.external.hp.com/src/openssl/ -+ "MPE/iX-gcc" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "gcc", -+ cflags => "-D_ENDIAN -DBN_DIV2W -O3 -D_POSIX_SOURCE -D_SOCKET_SOURCE -I/SYSLOG/PUB", -+ sys_id => "MPE", -+ ex_libs => add("-L/SYSLOG/PUB -lsyslog -lsocket -lcurses"), -+ thread_scheme => "(unknown)", -+ bn_ops => "BN_LLONG", -+ }, -+ -+#### DEC Alpha Tru64 targets. Tru64 is marketing name for OSF/1 version 4 -+#### and forward. In reality 'uname -s' still returns "OSF1". Originally -+#### there were even osf1-* configs targeting prior versions provided, -+#### but not anymore... -+ "tru64-alpha-gcc" => { -+ inherit_from => [ "BASE_unix", asm("alpha_asm") ], -+ cc => "gcc", -+ cflags => combine("-std=c9x -D_XOPEN_SOURCE=500 -D_OSF_SOURCE -O3", -+ threads("-pthread")), -+ ex_libs => "-lrt", # for mlock(2) -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "alpha-osf1-shared", -+ shared_extension => ".so", -+ }, -+ "tru64-alpha-cc" => { -+ inherit_from => [ "BASE_unix", asm("alpha_asm") ], -+ cc => "cc", -+ cflags => combine("-std1 -D_XOPEN_SOURCE=500 -D_OSF_SOURCE -tune host -fast -readonly_strings", -+ threads("-pthread")), -+ ex_libs => "-lrt", # for mlock(2) -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "alpha-osf1-shared", -+ shared_ldflag => "-msym", -+ shared_extension => ".so", -+ }, -+ -+#### -+#### Variety of LINUX:-) -+#### -+# *-generic* is endian-neutral target, but ./config is free to -+# throw in -D[BL]_ENDIAN, whichever appropriate... -+ "linux-generic32" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-Wall", -+ debug => "-O0 -g", -+ release => "-O3"), -+ threads("-pthread")), -+ ex_libs => add("-ldl"), -+ bn_ops => "BN_LLONG RC4_CHAR", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "linux-shared", -+ shared_cflag => "-fPIC -DOPENSSL_USE_NODELETE", -+ shared_ldflag => "-Wl,-znodelete", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ "linux-generic64" => { -+ inherit_from => [ "linux-generic32" ], -+ bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR", -+ }, -+ -+ "linux-ppc" => { -+ inherit_from => [ "linux-generic32", asm("ppc32_asm") ], -+ perlasm_scheme => "linux32", -+ }, -+ "linux-ppc64" => { -+ inherit_from => [ "linux-generic64", asm("ppc64_asm") ], -+ cflags => add("-m64 -DB_ENDIAN"), -+ perlasm_scheme => "linux64", -+ shared_ldflag => add("-m64"), -+ multilib => "64", -+ }, -+ "linux-ppc64le" => { -+ inherit_from => [ "linux-generic64", asm("ppc64_asm") ], -+ cflags => add("-m64 -DL_ENDIAN"), -+ perlasm_scheme => "linux64le", -+ shared_ldflag => add("-m64"), -+ }, -+ -+ "linux-armv4" => { -+ ################################################################ -+ # Note that -march is not among compiler options in linux-armv4 -+ # target description. Not specifying one is intentional to give -+ # you choice to: -+ # -+ # a) rely on your compiler default by not specifying one; -+ # b) specify your target platform explicitly for optimal -+ # performance, e.g. -march=armv6 or -march=armv7-a; -+ # c) build "universal" binary that targets *range* of platforms -+ # by specifying minimum and maximum supported architecture; -+ # -+ # As for c) option. It actually makes no sense to specify -+ # maximum to be less than ARMv7, because it's the least -+ # requirement for run-time switch between platform-specific -+ # code paths. And without run-time switch performance would be -+ # equivalent to one for minimum. Secondly, there are some -+ # natural limitations that you'd have to accept and respect. -+ # Most notably you can *not* build "universal" binary for -+ # big-endian platform. This is because ARMv7 processor always -+ # picks instructions in little-endian order. Another similar -+ # limitation is that -mthumb can't "cross" -march=armv6t2 -+ # boundary, because that's where it became Thumb-2. Well, this -+ # limitation is a bit artificial, because it's not really -+ # impossible, but it's deemed too tricky to support. And of -+ # course you have to be sure that your binutils are actually -+ # up to the task of handling maximum target platform. With all -+ # this in mind here is an example of how to configure -+ # "universal" build: -+ # -+ # ./Configure linux-armv4 -march=armv6 -D__ARM_MAX_ARCH__=8 -+ # -+ inherit_from => [ "linux-generic32", asm("armv4_asm") ], -+ perlasm_scheme => "linux32", -+ }, -+ "linux-aarch64" => { -+ inherit_from => [ "linux-generic64", asm("aarch64_asm") ], -+ perlasm_scheme => "linux64", -+ }, -+ "linux-arm64ilp32" => { # https://wiki.linaro.org/Platform/arm64-ilp32 -+ inherit_from => [ "linux-generic32", asm("aarch64_asm") ], -+ cflags => add("-mabi=ilp32"), -+ bn_ops => "SIXTY_FOUR_BIT RC4_CHAR", -+ perlasm_scheme => "linux64", -+ shared_ldflag => add("-mabi=ilp32"), -+ }, -+ -+ "linux-mips32" => { -+ # Configure script adds minimally required -march for assembly -+ # support, if no -march was specified at command line. -+ inherit_from => [ "linux-generic32", asm("mips32_asm") ], -+ cflags => add("-mabi=32 -DBN_DIV3W"), -+ perlasm_scheme => "o32", -+ shared_ldflag => add("-mabi=32"), -+ }, -+ # mips32 and mips64 below refer to contemporary MIPS Architecture -+ # specifications, MIPS32 and MIPS64, rather than to kernel bitness. -+ "linux-mips64" => { -+ inherit_from => [ "linux-generic32", asm("mips64_asm") ], -+ cflags => add("-mabi=n32 -DBN_DIV3W"), -+ bn_ops => "SIXTY_FOUR_BIT RC4_CHAR", -+ perlasm_scheme => "n32", -+ shared_ldflag => add("-mabi=n32"), -+ multilib => "32", -+ }, -+ "linux64-mips64" => { -+ inherit_from => [ "linux-generic64", asm("mips64_asm") ], -+ cflags => add("-mabi=64 -DBN_DIV3W"), -+ perlasm_scheme => "64", -+ shared_ldflag => add("-mabi=64"), -+ multilib => "64", -+ }, -+ -+ #### IA-32 targets... -+ #### These two targets are a bit aged and are to be used on older Linux -+ #### machines where gcc doesn't understand -m32 and -m64 -+ "linux-elf" => { -+ inherit_from => [ "linux-generic32", asm("x86_elf_asm") ], -+ cflags => add(picker(default => "-DL_ENDIAN", -+ release => "-fomit-frame-pointer")), -+ bn_ops => "BN_LLONG", -+ }, -+ "linux-aout" => { -+ inherit_from => [ "BASE_unix", asm("x86_asm") ], -+ cc => "gcc", -+ cflags => add(picker(default => "-DL_ENDIAN -Wall", -+ debug => "-O0 -g", -+ release => "-O3 -fomit-frame-pointer")), -+ bn_ops => "BN_LLONG", -+ thread_scheme => "(unknown)", -+ perlasm_scheme => "a.out", -+ }, -+ -+ #### X86 / X86_64 targets -+ "linux-x86" => { -+ inherit_from => [ "linux-generic32", asm("x86_asm") ], -+ cflags => add(picker(default => "-m32 -DL_ENDIAN", -+ release => "-fomit-frame-pointer")), -+ bn_ops => "BN_LLONG", -+ perlasm_scheme => "elf", -+ shared_ldflag => add("-m32"), -+ }, -+ "linux-x86-clang" => { -+ inherit_from => [ "linux-x86" ], -+ cc => "clang", -+ cxx => "clang++", -+ cflags => add("-Wextra -Qunused-arguments"), -+ }, -+ "linux-x86_64" => { -+ inherit_from => [ "linux-generic64", asm("x86_64_asm") ], -+ cflags => add("-m64 -DL_ENDIAN"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ perlasm_scheme => "elf", -+ shared_ldflag => add("-m64"), -+ multilib => "64", -+ }, -+ "linux-x86_64-clang" => { -+ inherit_from => [ "linux-x86_64" ], -+ cc => "clang", -+ cflags => add("-Wextra -Qunused-arguments"), -+ }, -+ "linux-x32" => { -+ inherit_from => [ "linux-generic32", asm("x86_64_asm") ], -+ cflags => add("-mx32 -DL_ENDIAN"), -+ bn_ops => "SIXTY_FOUR_BIT", -+ perlasm_scheme => "elf32", -+ shared_ldflag => add("-mx32"), -+ multilib => "x32", -+ }, -+ -+ "linux-ia64" => { -+ inherit_from => [ "linux-generic64", asm("ia64_asm") ], -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ }, -+ -+ "linux64-s390x" => { -+ inherit_from => [ "linux-generic64", asm("s390x_asm") ], -+ cflags => add("-m64 -DB_ENDIAN"), -+ perlasm_scheme => "64", -+ shared_ldflag => add("-m64"), -+ multilib => "64", -+ }, -+ "linux32-s390x" => { -+ #### So called "highgprs" target for z/Architecture CPUs -+ # "Highgprs" is kernel feature first implemented in Linux -+ # 2.6.32, see /proc/cpuinfo. The idea is to preserve most -+ # significant bits of general purpose registers not only -+ # upon 32-bit process context switch, but even on -+ # asynchronous signal delivery to such process. This makes -+ # it possible to deploy 64-bit instructions even in legacy -+ # application context and achieve better [or should we say -+ # adequate] performance. The build is binary compatible with -+ # linux-generic32, and the idea is to be able to install the -+ # resulting libcrypto.so alongside generic one, e.g. as -+ # /lib/highgprs/libcrypto.so.x.y, for ldconfig and run-time -+ # linker to autodiscover. Unfortunately it doesn't work just -+ # yet, because of couple of bugs in glibc -+ # sysdeps/s390/dl-procinfo.c affecting ldconfig and ld.so.1... -+ # -+ inherit_from => [ "linux-generic32", asm("s390x_asm") ], -+ cflags => add("-m31 -Wa,-mzarch -DB_ENDIAN"), -+ bn_asm_src => sub { my $r=join(" ",@_); $r=~s|asm/s390x\.S|bn_asm.c|; $r; }, -+ perlasm_scheme => "31", -+ shared_ldflag => add("-m31"), -+ multilib => "/highgprs", -+ }, -+ -+ #### SPARC Linux setups -+ # Ray Miller has -+ # patiently assisted with debugging of following two configs. -+ "linux-sparcv8" => { -+ inherit_from => [ "linux-generic32", asm("sparcv8_asm") ], -+ cflags => add("-mcpu=v8 -DB_ENDIAN -DBN_DIV2W"), -+ }, -+ "linux-sparcv9" => { -+ # it's a real mess with -mcpu=ultrasparc option under Linux, -+ # but -Wa,-Av8plus should do the trick no matter what. -+ inherit_from => [ "linux-generic32", asm("sparcv9_asm") ], -+ cflags => add("-m32 -mcpu=ultrasparc -Wa,-Av8plus -DB_ENDIAN -DBN_DIV2W"), -+ shared_ldflag => add("-m32"), -+ }, -+ "linux64-sparcv9" => { -+ # GCC 3.1 is a requirement -+ inherit_from => [ "linux-generic64", asm("sparcv9_asm") ], -+ cflags => add("-m64 -mcpu=ultrasparc -DB_ENDIAN"), -+ bn_ops => "BN_LLONG RC4_CHAR", -+ shared_ldflag => add("-m64"), -+ multilib => "64", -+ }, -+ -+ "linux-alpha-gcc" => { -+ inherit_from => [ "linux-generic64", asm("alpha_asm") ], -+ cflags => add("-DL_ENDIAN"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ }, -+ "linux-c64xplus" => { -+ inherit_from => [ "BASE_unix" ], -+ # TI_CGT_C6000_7.3.x is a requirement -+ cc => "cl6x", -+ cflags => combine("--linux -ea=.s -eo=.o -mv6400+ -o2 -ox -ms -pden -DOPENSSL_SMALL_FOOTPRINT", -+ threads("-D_REENTRANT")), -+ bn_ops => "BN_LLONG", -+ cpuid_asm_src => "c64xpluscpuid.s", -+ bn_asm_src => "asm/bn-c64xplus.asm c64xplus-gf2m.s", -+ aes_asm_src => "aes-c64xplus.s aes_cbc.c aes-ctr.fake", -+ sha1_asm_src => "sha1-c64xplus.s sha256-c64xplus.s sha512-c64xplus.s", -+ rc4_asm_src => "rc4-c64xplus.s", -+ modes_asm_src => "ghash-c64xplus.s", -+ chacha_asm_src => "chacha-c64xplus.s", -+ poly1305_asm_src => "poly1305-c64xplus.s", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "void", -+ dso_scheme => "dlfcn", -+ shared_target => "linux-shared", -+ shared_cflag => "--pic", -+ shared_ldflag => add("-z --sysv --shared"), -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ ranlib => "true", -+ }, -+ -+#### Android: linux-* but without pointers to headers and libs. -+ # -+ # It takes pair of prior-set environment variables to make it work: -+ # -+ # CROSS_SYSROOT=/some/where/android-ndk-/platforms/android-/arch- -+ # CROSS_COMPILE= -+ # -+ # As well as PATH adjusted to cover ${CROSS_COMPILE}gcc and company. -+ # For example to compile for ICS and ARM with NDK 10d, you'd: -+ # -+ # ANDROID_NDK=/some/where/android-ndk-10d -+ # CROSS_SYSROOT=$ANDROID_NDK/platforms/android-14/arch-arm -+ # CROSS_COMPILE=arm-linux-adroideabi- -+ # PATH=$ANDROID_NDK/toolchains/arm-linux-androideabi-4.8/prebuild/linux-x86_64/bin -+ # -+ "android" => { -+ inherit_from => [ "linux-generic32" ], -+ # Special note about unconditional -fPIC and -pie. The underlying -+ # reason is that Lollipop refuses to run non-PIE. But what about -+ # older systems and NDKs? -fPIC was never problem, so the only -+ # concern is -pie. Older toolchains, e.g. r4, appear to handle it -+ # and binaries turn mostly functional. "Mostly" means that oldest -+ # Androids, such as Froyo, fail to handle executable, but newer -+ # systems are perfectly capable of executing binaries targeting -+ # Froyo. Keep in mind that in the nutshell Android builds are -+ # about JNI, i.e. shared libraries, not applications. -+ cflags => add(picker(default => "-mandroid -fPIC --sysroot=\$(CROSS_SYSROOT) -Wa,--noexecstack")), -+ bin_cflags => "-pie", -+ }, -+ "android-x86" => { -+ inherit_from => [ "android", asm("x86_asm") ], -+ cflags => add(picker(release => "-fomit-frame-pointer")), -+ bn_ops => "BN_LLONG", -+ perlasm_scheme => "android", -+ }, -+ ################################################################ -+ # Contemporary Android applications can provide multiple JNI -+ # providers in .apk, targeting multiple architectures. Among -+ # them there is "place" for two ARM flavours: generic eabi and -+ # armv7-a/hard-float. However, it should be noted that OpenSSL's -+ # ability to engage NEON is not constrained by ABI choice, nor -+ # is your ability to call OpenSSL from your application code -+ # compiled with floating-point ABI other than default 'soft'. -+ # [Latter thanks to __attribute__((pcs("aapcs"))) declaration.] -+ # This means that choice of ARM libraries you provide in .apk -+ # is driven by application needs. For example if application -+ # itself benefits from NEON or is floating-point intensive, then -+ # it might be appropriate to provide both libraries. Otherwise -+ # just generic eabi would do. But in latter case it would be -+ # appropriate to -+ # -+ # ./Configure android-armeabi -D__ARM_MAX_ARCH__=8 -+ # -+ # in order to build "universal" binary and allow OpenSSL take -+ # advantage of NEON when it's available. -+ # -+ "android-armeabi" => { -+ inherit_from => [ "android", asm("armv4_asm") ], -+ }, -+ "android-mips" => { -+ inherit_from => [ "android", asm("mips32_asm") ], -+ perlasm_scheme => "o32", -+ }, -+ -+ "android64" => { -+ inherit_from => [ "linux-generic64" ], -+ cflags => add(picker(default => "-mandroid -fPIC --sysroot=\$(CROSS_SYSROOT) -Wa,--noexecstack")), -+ bin_cflags => "-pie", -+ }, -+ "android64-aarch64" => { -+ inherit_from => [ "android64", asm("aarch64_asm") ], -+ perlasm_scheme => "linux64", -+ }, -+ -+#### *BSD -+ "BSD-generic32" => { -+ # As for thread cflag. Idea is to maintain "collective" set of -+ # flags, which would cover all BSD flavors. -pthread applies -+ # to them all, but is treated differently. OpenBSD expands is -+ # as -D_POSIX_THREAD -lc_r, which is sufficient. FreeBSD 4.x -+ # expands it as -lc_r, which has to be accompanied by explicit -+ # -D_THREAD_SAFE and sometimes -D_REENTRANT. FreeBSD 5.x -+ # expands it as -lc_r, which seems to be sufficient? -+ inherit_from => [ "BASE_unix" ], -+ cc => "cc", -+ cflags => combine(picker(default => "-Wall", -+ debug => "-O0 -g", -+ release => "-O3"), -+ threads("-pthread -D_THREAD_SAFE -D_REENTRANT")), -+ bn_ops => "BN_LLONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "bsd-gcc-shared", -+ shared_cflag => "-fPIC", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ "BSD-generic64" => { -+ inherit_from => [ "BSD-generic32" ], -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ }, -+ -+ "BSD-x86" => { -+ inherit_from => [ "BSD-generic32", asm("x86_asm") ], -+ cflags => add(picker(default => "-DL_ENDIAN", -+ release => "-fomit-frame-pointer")), -+ bn_ops => "BN_LLONG", -+ shared_target => "bsd-shared", -+ perlasm_scheme => "a.out", -+ }, -+ "BSD-x86-elf" => { -+ inherit_from => [ "BSD-x86" ], -+ perlasm_scheme => "elf", -+ }, -+ -+ "BSD-sparcv8" => { -+ inherit_from => [ "BSD-generic32", asm("sparcv8_asm") ], -+ cflags => add("-mcpu=v8 -DB_ENDIAN"), -+ }, -+ "BSD-sparc64" => { -+ # -DMD32_REG_T=int doesn't actually belong in sparc64 target, it -+ # simply *happens* to work around a compiler bug in gcc 3.3.3, -+ # triggered by RIPEMD160 code. -+ inherit_from => [ "BSD-generic64", asm("sparcv9_asm") ], -+ cflags => add("-DB_ENDIAN -DMD32_REG_T=int"), -+ bn_ops => "BN_LLONG", -+ }, -+ -+ "BSD-ia64" => { -+ inherit_from => [ "BSD-generic64", asm("ia64_asm") ], -+ cflags => add_before("-DL_ENDIAN"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ }, -+ -+ "BSD-x86_64" => { -+ inherit_from => [ "BSD-generic64", asm("x86_64_asm") ], -+ cflags => add_before("-DL_ENDIAN"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ perlasm_scheme => "elf", -+ }, -+ -+ "bsdi-elf-gcc" => { -+ inherit_from => [ "BASE_unix", asm("x86_elf_asm") ], -+ cc => "gcc", -+ cflags => "-DPERL5 -DL_ENDIAN -fomit-frame-pointer -O3 -Wall", -+ ex_libs => add("-ldl"), -+ bn_ops => "BN_LLONG", -+ thread_scheme => "(unknown)", -+ dso_scheme => "dlfcn", -+ shared_target => "bsd-gcc-shared", -+ shared_cflag => "-fPIC", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ -+ "nextstep" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "cc", -+ cflags => "-O -Wall", -+ unistd => "", -+ bn_ops => "BN_LLONG", -+ thread_scheme => "(unknown)", -+ }, -+ "nextstep3.3" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "cc", -+ cflags => "-O3 -Wall", -+ unistd => "", -+ bn_ops => "BN_LLONG", -+ thread_scheme => "(unknown)", -+ }, -+ -+# QNX -+ "qnx4" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "cc", -+ cflags => "-DL_ENDIAN -DTERMIO", -+ thread_scheme => "(unknown)", -+ }, -+ "QNX6" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "gcc", -+ ex_libs => add("-lsocket"), -+ dso_scheme => "dlfcn", -+ shared_target => "bsd-gcc-shared", -+ shared_cflag => "-fPIC", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ "QNX6-i386" => { -+ inherit_from => [ "BASE_unix", asm("x86_elf_asm") ], -+ cc => "gcc", -+ cflags => "-DL_ENDIAN -O2 -Wall", -+ ex_libs => add("-lsocket"), -+ dso_scheme => "dlfcn", -+ shared_target => "bsd-gcc-shared", -+ shared_cflag => "-fPIC", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ -+#### SCO/Caldera targets. -+# -+# Originally we had like unixware-*, unixware-*-pentium, unixware-*-p6, etc. -+# Now we only have blended unixware-* as it's the only one used by ./config. -+# If you want to optimize for particular microarchitecture, bypass ./config -+# and './Configure unixware-7 -Kpentium_pro' or whatever appropriate. -+# Note that not all targets include assembler support. Mostly because of -+# lack of motivation to support out-of-date platforms with out-of-date -+# compiler drivers and assemblers. Tim Rice has -+# patiently assisted to debug most of it. -+# -+# UnixWare 2.0x fails destest with -O. -+ "unixware-2.0" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "cc", -+ cflags => combine("-DFILIO_H -DNO_STRINGS_H", -+ threads("-Kthread")), -+ ex_libs => add("-lsocket -lnsl -lresolv -lx"), -+ thread_scheme => "uithreads", -+ }, -+ "unixware-2.1" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "cc", -+ cflags => combine("-O -DFILIO_H", -+ threads("-Kthread")), -+ ex_libs => add("-lsocket -lnsl -lresolv -lx"), -+ thread_scheme => "uithreads", -+ }, -+ "unixware-7" => { -+ inherit_from => [ "BASE_unix", asm("x86_elf_asm") ], -+ cc => "cc", -+ cflags => combine("-O -DFILIO_H -Kalloca", -+ threads("-Kthread")), -+ ex_libs => add("-lsocket -lnsl"), -+ thread_scheme => "uithreads", -+ bn_ops => "BN_LLONG", -+ perlasm_scheme => "elf-1", -+ dso_scheme => "dlfcn", -+ shared_target => "svr5-shared", -+ shared_cflag => "-Kpic", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ "unixware-7-gcc" => { -+ inherit_from => [ "BASE_unix", asm("x86_elf_asm") ], -+ cc => "gcc", -+ cflags => combine("-DL_ENDIAN -DFILIO_H -O3 -fomit-frame-pointer -Wall", -+ threads("-D_REENTRANT")), -+ ex_libs => add("-lsocket -lnsl"), -+ bn_ops => "BN_LLONG", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "elf-1", -+ dso_scheme => "dlfcn", -+ shared_target => "gnu-shared", -+ shared_cflag => "-fPIC", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+# SCO 5 - Ben Laurie says the -O breaks the SCO cc. -+ "sco5-cc" => { -+ inherit_from => [ "BASE_unix", asm("x86_elf_asm") ], -+ cc => "cc", -+ cflags => "-belf", -+ ex_libs => add("-lsocket -lnsl"), -+ thread_scheme => "(unknown)", -+ perlasm_scheme => "elf-1", -+ dso_scheme => "dlfcn", -+ shared_target => "svr3-shared", -+ shared_cflag => "-Kpic", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ "sco5-gcc" => { -+ inherit_from => [ "BASE_unix", asm("x86_elf_asm") ], -+ cc => "gcc", -+ cflags => "-O3 -fomit-frame-pointer", -+ ex_libs => add("-lsocket -lnsl"), -+ bn_ops => "BN_LLONG", -+ thread_scheme => "(unknown)", -+ perlasm_scheme => "elf-1", -+ dso_scheme => "dlfcn", -+ shared_target => "svr3-shared", -+ shared_cflag => "-fPIC", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ -+#### IBM's AIX. -+ # Below targets assume AIX >=5. Caveat lector. If you are accustomed -+ # to control compilation "bitness" by setting $OBJECT_MODE environment -+ # variable, then you should know that in OpenSSL case it's considered -+ # only in ./config. Once configured, build procedure remains "deaf" to -+ # current value of $OBJECT_MODE. -+ "aix-gcc" => { -+ inherit_from => [ "BASE_unix", asm("ppc32_asm") ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-DB_ENDIAN", -+ debug => "-O0 -g", -+ release => "-O"), -+ threads("-pthread")), -+ sys_id => "AIX", -+ bn_ops => "BN_LLONG RC4_CHAR", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "aix32", -+ dso_scheme => "dlfcn", -+ shared_target => "aix-shared", -+ shared_ldflag => "-shared -static-libgcc -Wl,-G", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ arflags => "-X32", -+ }, -+ "aix64-gcc" => { -+ inherit_from => [ "BASE_unix", asm("ppc64_asm") ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-maix64 -DB_ENDIAN", -+ debug => "-O0 -g", -+ release => "-O"), -+ threads("-pthread")), -+ sys_id => "AIX", -+ bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "aix64", -+ dso_scheme => "dlfcn", -+ shared_target => "aix-shared", -+ shared_ldflag => "-maix64 -shared -static-libgcc -Wl,-G", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ arflags => "-X64", -+ }, -+ "aix-cc" => { -+ inherit_from => [ "BASE_unix", asm("ppc32_asm") ], -+ cc => "cc", -+ cflags => combine(picker(default => "-q32 -DB_ENDIAN -qmaxmem=16384 -qro -qroconst", -+ debug => "-O0 -g", -+ release => "-O"), -+ threads("-qthreaded -D_THREAD_SAFE")), -+ sys_id => "AIX", -+ bn_ops => "BN_LLONG RC4_CHAR", -+ thread_scheme => "pthreads", -+ ex_libs => threads("-lpthreads"), -+ perlasm_scheme => "aix32", -+ dso_scheme => "dlfcn", -+ shared_target => "aix-shared", -+ shared_ldflag => "-q32 -G", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ arflags => "-X 32", -+ }, -+ "aix64-cc" => { -+ inherit_from => [ "BASE_unix", asm("ppc64_asm") ], -+ cc => "cc", -+ cflags => combine(picker(default => "-q64 -DB_ENDIAN -qmaxmem=16384 -qro -qroconst", -+ debug => "-O0 -g", -+ release => "-O"), -+ threads("-qthreaded -D_THREAD_SAFE")), -+ sys_id => "AIX", -+ bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR", -+ thread_scheme => "pthreads", -+ ex_libs => threads("-lpthreads"), -+ perlasm_scheme => "aix64", -+ dso_scheme => "dlfcn", -+ shared_target => "aix-shared", -+ shared_ldflag => "-q64 -G", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ arflags => "-X 64", -+ }, -+ -+# SIEMENS BS2000/OSD: an EBCDIC-based mainframe -+ "BS2000-OSD" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "c89", -+ cflags => "-O -XLLML -XLLMK -XL -DB_ENDIAN -DCHARSET_EBCDIC", -+ ex_libs => add("-lsocket -lnsl"), -+ bn_ops => "THIRTY_TWO_BIT RC4_CHAR", -+ thread_scheme => "(unknown)", -+ }, -+ -+# OS/390 Unix an EBCDIC-based Unix system on IBM mainframe -+# You need to compile using the c89.sh wrapper in the tools directory, because the -+# IBM compiler does not like the -L switch after any object modules. -+# -+ "OS390-Unix" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "c89.sh", -+ cflags => "-O -DB_ENDIAN -DCHARSET_EBCDIC -DNO_SYS_PARAM_H -D_ALL_SOURCE", -+ bn_ops => "THIRTY_TWO_BIT RC4_CHAR", -+ thread_scheme => "(unknown)", -+ }, -+ -+#### Visual C targets -+# -+# Win64 targets, WIN64I denotes IA-64 and WIN64A - AMD64 -+# -+# Note about -wd4090, disable warning C4090. This warning returns false -+# positives in some situations. Disabling it altogether masks both -+# legitimate and false cases, but as we compile on multiple platforms, -+# we rely on other compilers to catch legitimate cases. -+# -+# Also note that we force threads no matter what. Configuring "no-threads" -+# is ignored. -+ "VC-common" => { -+ inherit_from => [ "BASE_Windows" ], -+ template => 1, -+ cc => "cl", -+ cflags => "-W3 -wd4090 -Gs0 -GF -Gy -nologo -DOPENSSL_SYS_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE", -+ defines => add(sub { my @defs = (); -+ unless ($disabled{"zlib-dynamic"}) { -+ my $zlib = -+ $withargs{zlib_lib} // "ZLIB1"; -+ push @defs, -+ quotify("perl", -+ 'LIBZ="' . $zlib . '"'); -+ } -+ return [ @defs ]; -+ }), -+ coutflag => "/Fo", -+ lib_cflags => add("/Zi /Fdossl_static"), -+ dso_cflags => "/Zi /Fddso", -+ bin_cflags => "/Zi /Fdapp", -+ lflags => add("/debug"), -+ shared_ldflag => "/dll", -+ shared_target => "win-shared", # meaningless except it gives Configure a hint -+ thread_scheme => "winthreads", -+ dso_scheme => "win32", -+ apps_aux_src => add("win32_init.c"), -+ }, -+ "VC-noCE-common" => { -+ inherit_from => [ "VC-common" ], -+ template => 1, -+ cflags => add(picker(default => "-DUNICODE -D_UNICODE", -+ debug => -+ sub { -+ ($disabled{shared} ? "" : "/MDd") -+ ." /Od -DDEBUG -D_DEBUG"; -+ }, -+ release => -+ sub { -+ ($disabled{shared} ? "" : "/MD") -+ ." /O2"; -+ })), -+ lib_cflags => add(sub { $disabled{shared} ? "/MT /Zl" : () }), -+ # Following might/should appears controversial, i.e. defining -+ # /MDd without evaluating $disabled{shared}. It works in -+ # non-shared build because static library is compiled with /Zl -+ # and bares no reference to specific RTL. And it works in -+ # shared build because multiple /MDd options are not prohibited. -+ # But why /MDd in static build? Well, basically this is just a -+ # reference point, which allows to catch eventual errors that -+ # would prevent those who want to wrap OpenSSL into own .DLL. -+ # Why not /MD in release build then? Well, some are likely to -+ # prefer [non-debug] openssl.exe to be free from Micorosoft RTL -+ # redistributable. -+ bin_cflags => add(picker(debug => "/MDd", -+ release => sub { $disabled{shared} ? "/MT" : () }, -+ )), -+ bin_lflags => add("/subsystem:console /opt:ref"), -+ ex_libs => add(sub { -+ my @ex_libs = (); -+ push @ex_libs, 'ws2_32.lib' unless $disabled{sock}; -+ push @ex_libs, 'gdi32.lib advapi32.lib crypt32.lib user32.lib'; -+ return join(" ", @ex_libs); -+ }), -+ }, -+ "VC-WIN64-common" => { -+ inherit_from => [ "VC-noCE-common" ], -+ template => 1, -+ ex_libs => add(sub { -+ my @ex_libs = (); -+ push @ex_libs, 'bufferoverflowu.lib' if (`cl 2>&1` =~ /14\.00\.4[0-9]{4}\./); -+ return join(" ", @_, @ex_libs); -+ }), -+ bn_ops => "SIXTY_FOUR_BIT EXPORT_VAR_AS_FN", -+ build_scheme => add("VC-W64", { separator => undef }), -+ }, -+ "VC-WIN64I" => { -+ inherit_from => [ "VC-WIN64-common", asm("ia64_asm"), -+ sub { $disabled{shared} ? () : "ia64_uplink" } ], -+ as => "ias", -+ asflags => "-d debug", -+ asoutflag => "-o", -+ sys_id => "WIN64I", -+ bn_asm_src => sub { return undef unless @_; -+ my $r=join(" ",@_); $r=~s|bn-ia64.s|bn_asm.c|; $r; }, -+ perlasm_scheme => "ias", -+ multilib => "-ia64", -+ }, -+ "VC-WIN64A" => { -+ inherit_from => [ "VC-WIN64-common", asm("x86_64_asm"), -+ sub { $disabled{shared} ? () : "x86_64_uplink" } ], -+ as => sub { vc_win64a_info()->{as} }, -+ asflags => sub { vc_win64a_info()->{asflags} }, -+ asoutflag => sub { vc_win64a_info()->{asoutflag} }, -+ sys_id => "WIN64A", -+ bn_asm_src => sub { return undef unless @_; -+ my $r=join(" ",@_); $r=~s|asm/x86_64-gcc|bn_asm|; $r; }, -+ perlasm_scheme => "auto", -+ multilib => "-x64", -+ }, -+ "VC-WIN32" => { -+ # x86 Win32 target defaults to ANSI API, if you want UNICODE, -+ # configure with 'perl Configure VC-WIN32 -DUNICODE -D_UNICODE' -+ inherit_from => [ "VC-noCE-common", asm("x86_asm"), -+ sub { $disabled{shared} ? () : "uplink_common" } ], -+ as => sub { vc_win32_info()->{as} }, -+ asflags => sub { vc_win32_info()->{asflags} }, -+ asoutflag => sub { vc_win32_info()->{asoutflag} }, -+ ex_libs => add(sub { -+ my @ex_libs = (); -+ # WIN32 UNICODE build gets linked with unicows.lib for -+ # backward compatibility with Win9x. -+ push @ex_libs, 'unicows.lib' -+ if (grep { $_ eq "UNICODE" } @user_defines); -+ return join(" ", @ex_libs, @_); -+ }), -+ sys_id => "WIN32", -+ bn_ops => "BN_LLONG EXPORT_VAR_AS_FN", -+ perlasm_scheme => sub { vc_win32_info()->{perlasm_scheme} }, -+ build_scheme => add("VC-W32", { separator => undef }), -+ }, -+ "VC-CE" => { -+ inherit_from => [ "VC-common" ], -+ as => "ml", -+ asflags => "/nologo /Cp /coff /c /Cx /Zi", -+ asoutflag => "/Fo", -+ cc => "cl", -+ cflags => -+ picker(default => -+ combine('/W3 /WX /GF /Gy /nologo -DUNICODE -D_UNICODE -DOPENSSL_SYS_WINCE -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DDSO_WIN32 -DNO_CHMOD -DOPENSSL_SMALL_FOOTPRINT', -+ sub { vc_wince_info()->{cflags}; }, -+ sub { defined($ENV{'WCECOMPAT'}) -+ ? '-I$(WCECOMPAT)/include' : (); }, -+ sub { defined($ENV{'PORTSDK_LIBPATH'}) -+ ? '-I$(PORTSDK_LIBPATH)/../../include' : (); }, -+ sub { `cl 2>&1` =~ /Version ([0-9]+)\./ && $1>=14 -+ ? ($disabled{shared} ? " /MT" : " /MD") -+ : " /MC"; }), -+ debug => "/Od -DDEBUG -D_DEBUG", -+ release => "/O1i"), -+ lflags => combine("/nologo /opt:ref", -+ sub { vc_wince_info()->{lflags}; }, -+ sub { defined($ENV{PORTSDK_LIBPATH}) -+ ? "/entry:mainCRTstartup" : (); }), -+ sys_id => "WINCE", -+ bn_ops => "BN_LLONG EXPORT_VAR_AS_FN", -+ ex_libs => add(sub { -+ my @ex_libs = (); -+ push @ex_libs, 'ws2.lib' unless $disabled{sock}; -+ push @ex_libs, 'crypt32.lib'; -+ if (defined($ENV{WCECOMPAT})) { -+ my $x = '$(WCECOMPAT)/lib'; -+ if (-f "$x/$ENV{TARGETCPU}/wcecompatex.lib") { -+ $x .= '/$(TARGETCPU)/wcecompatex.lib'; -+ } else { -+ $x .= '/wcecompatex.lib'; -+ } -+ push @ex_libs, $x; -+ } -+ push @ex_libs, '$(PORTSDK_LIBPATH)/portlib.lib' -+ if (defined($ENV{'PORTSDK_LIBPATH'})); -+ push @ex_libs, ' /nodefaultlib coredll.lib corelibc.lib' -+ if ($ENV{'TARGETCPU'} eq "X86"); -+ return @ex_libs; -+ }), -+ build_scheme => add("VC-WCE", { separator => undef }), -+ }, -+ -+#### MinGW -+ "mingw" => { -+ inherit_from => [ "BASE_unix", asm("x86_asm"), -+ sub { $disabled{shared} ? () : "x86_uplink" } ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-DL_ENDIAN -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE -m32 -Wall", -+ debug => "-g -O0", -+ release => "-O3 -fomit-frame-pointer"), -+ threads("-D_MT")), -+ sys_id => "MINGW32", -+ ex_libs => add("-lws2_32 -lgdi32 -lcrypt32"), -+ bn_ops => "BN_LLONG EXPORT_VAR_AS_FN", -+ thread_scheme => "winthreads", -+ perlasm_scheme => "coff", -+ dso_scheme => "win32", -+ shared_target => "mingw-shared", -+ shared_cflag => add("-D_WINDLL"), -+ shared_ldflag => "-static-libgcc", -+ shared_rcflag => "--target=pe-i386", -+ shared_extension => ".dll", -+ multilib => "", -+ apps_aux_src => add("win32_init.c"), -+ }, -+ "mingw64" => { -+ # As for OPENSSL_USE_APPLINK. Applink makes it possible to use -+ # .dll compiled with one compiler with application compiled with -+ # another compiler. It's possible to engage Applink support in -+ # mingw64 build, but it's not done, because till mingw64 -+ # supports structured exception handling, one can't seriously -+ # consider its binaries for using with non-mingw64 run-time -+ # environment. And as mingw64 is always consistent with itself, -+ # Applink is never engaged and can as well be omitted. -+ inherit_from => [ "BASE_unix", asm("x86_64_asm") ], -+ cc => "gcc", -+ cflags => combine(picker(default => "-DL_ENDIAN -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE -m64 -Wall", -+ debug => "-g -O0", -+ release => "-O3"), -+ threads("-D_MT")), -+ sys_id => "MINGW64", -+ ex_libs => add("-lws2_32 -lgdi32 -lcrypt32"), -+ bn_ops => "SIXTY_FOUR_BIT EXPORT_VAR_AS_FN", -+ thread_scheme => "winthreads", -+ perlasm_scheme => "mingw64", -+ dso_scheme => "win32", -+ shared_target => "mingw-shared", -+ shared_cflag => add("-D_WINDLL"), -+ shared_ldflag => "-static-libgcc", -+ shared_rcflag => "--target=pe-x86-64", -+ shared_extension => ".dll", -+ multilib => "64", -+ apps_aux_src => add("win32_init.c"), -+ }, -+ -+#### UEFI -+ "UEFI" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "cc", -+ cflags => "-DL_ENDIAN -O", -+ sys_id => "UEFI", -+ }, -+ -+#### UWIN -+ "UWIN" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "cc", -+ cflags => "-DTERMIOS -DL_ENDIAN -O -Wall", -+ sys_id => "UWIN", -+ bn_ops => "BN_LLONG", -+ dso_scheme => "win32", -+ }, -+ -+#### Cygwin -+ "Cygwin-x86" => { -+ inherit_from => [ "BASE_unix", asm("x86_asm") ], -+ cc => "gcc", -+ cflags => picker(default => "-DTERMIOS -DL_ENDIAN -Wall", -+ debug => "-g -O0", -+ release => "-O3 -fomit-frame-pointer"), -+ sys_id => "CYGWIN", -+ bn_ops => "BN_LLONG", -+ thread_scheme => "pthread", -+ perlasm_scheme => "coff", -+ dso_scheme => "dlfcn", -+ shared_target => "cygwin-shared", -+ shared_cflag => "-D_WINDLL", -+ shared_ldflag => "-shared", -+ shared_extension => ".dll", -+ }, -+ "Cygwin-x86_64" => { -+ inherit_from => [ "BASE_unix", asm("x86_64_asm") ], -+ cc => "gcc", -+ cflags => picker(default => "-DTERMIOS -DL_ENDIAN -Wall", -+ debug => "-g -O0", -+ release => "-O3"), -+ sys_id => "CYGWIN", -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthread", -+ perlasm_scheme => "mingw64", -+ dso_scheme => "dlfcn", -+ shared_target => "cygwin-shared", -+ shared_cflag => "-D_WINDLL", -+ shared_ldflag => "-shared", -+ shared_extension => ".dll", -+ }, -+ # Backward compatibility for those using this target -+ "Cygwin" => { -+ inherit_from => [ "Cygwin-x86" ] -+ }, -+ # In case someone constructs the Cygwin target name themself -+ "Cygwin-i386" => { -+ inherit_from => [ "Cygwin-x86" ] -+ }, -+ "Cygwin-i486" => { -+ inherit_from => [ "Cygwin-x86" ] -+ }, -+ "Cygwin-i586" => { -+ inherit_from => [ "Cygwin-x86" ] -+ }, -+ "Cygwin-i686" => { -+ inherit_from => [ "Cygwin-x86" ] -+ }, -+ -+##### MacOS X (a.k.a. Darwin) setup -+ "darwin-common" => { -+ inherit_from => [ "BASE_unix" ], -+ template => 1, -+ cc => "cc", -+ cflags => combine(picker(default => "", -+ debug => "-g -O0", -+ release => "-O3"), -+ threads("-D_REENTRANT")), -+ sys_id => "MACOSX", -+ plib_lflags => "-Wl,-search_paths_first", -+ bn_ops => "BN_LLONG RC4_CHAR", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "osx32", -+ dso_scheme => "dlfcn", -+ ranlib => "ranlib -c", -+ shared_target => "darwin-shared", -+ shared_cflag => "-fPIC", -+ shared_ldflag => "-dynamiclib", -+ shared_extension => ".\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", -+ }, -+ # Option "freeze" such as -std=gnu9x can't negatively interfere -+ # with future defaults for below two targets, because MacOS X -+ # for PPC has no future, it was discontinued by vendor in 2009. -+ "darwin-ppc-cc" => { -+ inherit_from => [ "darwin-common", asm("ppc32_asm") ], -+ cflags => add("-arch ppc -std=gnu9x -DB_ENDIAN -Wa,-force_cpusubtype_ALL"), -+ perlasm_scheme => "osx32", -+ shared_ldflag => "-arch ppc -dynamiclib", -+ }, -+ "darwin64-ppc-cc" => { -+ inherit_from => [ "darwin-common", asm("ppc64_asm") ], -+ cflags => add("-arch ppc64 -std=gnu9x -DB_ENDIAN"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR", -+ perlasm_scheme => "osx64", -+ shared_ldflag => "-arch ppc64 -dynamiclib", -+ }, -+ "darwin-i386-cc" => { -+ inherit_from => [ "darwin-common", asm("x86_asm") ], -+ cflags => add(picker(default => "-arch i386 -DL_ENDIAN", -+ release => "-fomit-frame-pointer")), -+ bn_ops => "BN_LLONG RC4_INT", -+ perlasm_scheme => "macosx", -+ shared_ldflag => "-arch i386 -dynamiclib", -+ }, -+ "darwin64-x86_64-cc" => { -+ inherit_from => [ "darwin-common", asm("x86_64_asm") ], -+ cflags => add("-arch x86_64 -DL_ENDIAN -Wall"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ perlasm_scheme => "macosx", -+ shared_ldflag => "-arch x86_64 -dynamiclib", -+ }, -+ -+#### iPhoneOS/iOS -+# -+# It takes three prior-set environment variables to make it work: -+# -+# CROSS_COMPILE=/where/toolchain/is/usr/bin/ [note ending slash] -+# CROSS_TOP=/where/SDKs/are -+# CROSS_SDK=iPhoneOSx.y.sdk -+# -+# Exact paths vary with Xcode releases, but for couple of last ones -+# they would look like this: -+# -+# CROSS_COMPILE=`xcode-select --print-path`/Toolchains/XcodeDefault.xctoolchain/usr/bin/ -+# CROSS_TOP=`xcode-select --print-path`/Platforms/iPhoneOS.platform/Developer -+# CROSS_SDK=iPhoneOS.sdk -+# -+ "iphoneos-cross" => { -+ inherit_from => [ "darwin-common" ], -+ cflags => add("-isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common"), -+ sys_id => "iOS", -+ }, -+ "ios-cross" => { -+ inherit_from => [ "darwin-common", asm("armv4_asm") ], -+ # It should be possible to go below iOS 6 and even add -arch armv6, -+ # thus targeting iPhone pre-3GS, but it's assumed to be irrelevant -+ # at this point. -+ cflags => add("-arch armv7 -mios-version-min=6.0.0 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common"), -+ sys_id => "iOS", -+ perlasm_scheme => "ios32", -+ }, -+ "ios64-cross" => { -+ inherit_from => [ "darwin-common", asm("aarch64_asm") ], -+ cflags => add("-arch arm64 -mios-version-min=7.0.0 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common"), -+ sys_id => "iOS", -+ bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR", -+ perlasm_scheme => "ios64", -+ }, -+ -+##### GNU Hurd -+ "hurd-x86" => { -+ inherit_from => [ "BASE_unix" ], -+ inherit_from => [ asm("x86_elf_asm") ], -+ cc => "gcc", -+ cflags => combine("-DL_ENDIAN -O3 -fomit-frame-pointer -Wall", -+ threads("-pthread")), -+ ex_libs => add("-ldl"), -+ bn_ops => "BN_LLONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "linux-shared", -+ shared_cflag => "-fPIC", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ -+##### VxWorks for various targets -+ "vxworks-ppc60x" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "ccppc", -+ cflags => "-D_REENTRANT -mrtp -mhard-float -mstrict-align -fno-implicit-fp -DPPC32_fp60x -O2 -fstrength-reduce -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip", -+ sys_id => "VXWORKS", -+ ex_libs => add("-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/common"), -+ }, -+ "vxworks-ppcgen" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "ccppc", -+ cflags => "-D_REENTRANT -mrtp -msoft-float -mstrict-align -O1 -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip", -+ sys_id => "VXWORKS", -+ ex_libs => add("-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/sfcommon"), -+ }, -+ "vxworks-ppc405" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "ccppc", -+ cflags => "-g -msoft-float -mlongcall -DCPU=PPC405 -I\$(WIND_BASE)/target/h", -+ sys_id => "VXWORKS", -+ lflags => "-r", -+ }, -+ "vxworks-ppc750" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "ccppc", -+ cflags => "-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h \$(DEBUG_FLAG)", -+ sys_id => "VXWORKS", -+ lflags => "-r", -+ }, -+ "vxworks-ppc750-debug" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "ccppc", -+ cflags => "-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h -DPEDANTIC -DDEBUG -g", -+ sys_id => "VXWORKS", -+ lflags => "-r", -+ }, -+ "vxworks-ppc860" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "ccppc", -+ cflags => "-nostdinc -msoft-float -DCPU=PPC860 -DNO_STRINGS_H -I\$(WIND_BASE)/target/h", -+ sys_id => "VXWORKS", -+ lflags => "-r", -+ }, -+ "vxworks-simlinux" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "ccpentium", -+ cflags => "-B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DL_ENDIAN -DCPU=SIMLINUX -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/h -I\$(WIND_BASE)/target/h/wrn/coreip -DOPENSSL_NO_HW_PADLOCK", -+ sys_id => "VXWORKS", -+ lflags => "-r", -+ ranlib => "ranlibpentium", -+ }, -+ "vxworks-mips" => { -+ inherit_from => [ "BASE_unix", asm("mips32_asm") ], -+ cc => "ccmips", -+ cflags => combine("-mrtp -mips2 -O -G 0 -B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DCPU=MIPS32 -msoft-float -mno-branch-likely -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/h/wrn/coreip", -+ threads("-D_REENTRANT")), -+ sys_id => "VXWORKS", -+ ex_libs => add("-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/mips/MIPSI32/sfcommon"), -+ thread_scheme => "pthreads", -+ perlasm_scheme => "o32", -+ ranlib => "ranlibmips", -+ }, -+ -+#### uClinux -+ "uClinux-dist" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "$ENV{'CC'}", -+ cflags => combine("\$(CFLAGS)", -+ threads("-D_REENTRANT")), -+ plib_lflags => "\$(LDFLAGS)", -+ ex_libs => add("\$(LDLIBS)"), -+ bn_ops => "BN_LLONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "$ENV{'LIBSSL_dlfcn'}", -+ shared_target => "linux-shared", -+ shared_cflag => "-fPIC", -+ shared_ldflag => "-shared", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ ranlib => "$ENV{'RANLIB'}", -+ }, -+ "uClinux-dist64" => { -+ inherit_from => [ "BASE_unix" ], -+ cc => "$ENV{'CC'}", -+ cflags => combine("\$(CFLAGS)", -+ threads("-D_REENTRANT")), -+ plib_lflags => "\$(LDFLAGS)", -+ ex_libs => add("\$(LDLIBS)"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "$ENV{'LIBSSL_dlfcn'}", -+ shared_target => "linux-shared", -+ shared_cflag => "-fPIC", -+ shared_ldflag => "-shared", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ ranlib => "$ENV{'RANLIB'}", -+ }, -+ -+ ##### VMS -+ "vms-generic" => { -+ inherit_from => [ "BASE_VMS" ], -+ template => 1, -+ cc => "CC/DECC", -+ cflags => picker(default => "/STANDARD=(ISOC94,RELAXED)/NOLIST/PREFIX=ALL", -+ debug => "/NOOPTIMIZE/DEBUG", -+ release => "/OPTIMIZE/NODEBUG"), -+ defines => add("OPENSSL_USE_NODELETE"), -+ lflags => picker(default => "/MAP", -+ debug => "/DEBUG/TRACEBACK", -+ release => "/NODEBUG/NOTRACEBACK"), -+ lib_cflags => add("/NAMES=(AS_IS,SHORTENED)/EXTERN_MODEL=STRICT_REFDEF"), -+ dso_cflags => add("/NAMES=(AS_IS,SHORTENED)"), -+ shared_target => "vms-shared", -+ dso_scheme => "vms", -+ thread_scheme => "pthreads", -+ -+ apps_aux_src => "vms_decc_init.c vms_term_sock.c", -+ }, -+ -+ "vms-alpha" => { -+ inherit_from => [ "vms-generic" ], -+ cflags => add(sub { my @warnings = -+ @{vms_info(0)->{disable_warns}}; -+ @warnings -+ ? "/WARNINGS=DISABLE=(".join(",",@warnings).")" : (); }), -+ defines => -+ add(sub { -+ return vms_info(0)->{def_zlib} -+ ? "LIBZ=\"\"\"".vms_info(0)->{def_zlib}."\"\"\"" : (); -+ }), -+ ex_libs => add(sub { return vms_info(0)->{zlib} || (); }), -+ pointer_size => sub { return vms_info(0)->{pointer_size} }, -+ #as => "???", -+ #debug_aflags => "/NOOPTIMIZE/DEBUG", -+ #release_aflags => "/OPTIMIZE/NODEBUG", -+ bn_opts => "SIXTY_FOUR_BIT RC4_INT", -+ }, -+ "vms-alpha-p32" => { -+ inherit_from => [ "vms-generic" ], -+ cflags => -+ add("/POINTER_SIZE=32", -+ sub { my @warnings = -+ @{vms_info(32)->{disable_warns}}; -+ @warnings -+ ? "/WARNINGS=DISABLE=(".join(",",@warnings).")" : (); -+ } ), -+ defines => -+ add(sub { -+ return vms_info(32)->{def_zlib} -+ ? "LIBZ=\"\"\"".vms_info(32)->{def_zlib}."\"\"\"" : (); -+ }), -+ ex_libs => add(sub { return vms_info(32)->{zlib} || (); }), -+ pointer_size => sub { return vms_info(32)->{pointer_size} }, -+ }, -+ "vms-alpha-p64" => { -+ inherit_from => [ "vms-generic" ], -+ cflags => -+ add("/POINTER_SIZE=64=ARGV", -+ sub { my @warnings = -+ @{vms_info(64)->{disable_warns}}; -+ @warnings -+ ? "/WARNINGS=DISABLE=(".join(",",@warnings).")" : (); -+ } ), -+ defines => -+ add(sub { -+ return vms_info(64)->{def_zlib} -+ ? "LIBZ=\"\"\"".vms_info(64)->{def_zlib}."\"\"\"" : (); -+ }), -+ ex_libs => add(sub { return vms_info(64)->{zlib} || (); }), -+ pointer_size => sub { return vms_info(64)->{pointer_size} }, -+ }, -+ "vms-ia64" => { -+ inherit_from => [ "vms-generic" ], -+ cflags => add(sub { my @warnings = -+ @{vms_info(0)->{disable_warns}}; -+ @warnings -+ ? "/WARNINGS=DISABLE=(".join(",",@warnings).")" : (); }), -+ defines => -+ add(sub { -+ return vms_info(0)->{def_zlib} -+ ? "LIBZ=\"\"\"".vms_info(0)->{def_zlib}."\"\"\"" : (); -+ }), -+ ex_libs => add(sub { return vms_info(0)->{zlib} || (); }), -+ pointer_size => sub { return vms_info(0)->{pointer_size} }, -+ #as => "I4S", -+ #debug_aflags => "/NOOPTIMIZE/DEBUG", -+ #release_aflags => "/OPTIMIZE/NODEBUG", -+ bn_opts => "SIXTY_FOUR_BIT RC4_INT", -+ }, -+ "vms-ia64-p32" => { -+ inherit_from => [ "vms-generic" ], -+ cflags => -+ add("/POINTER_SIZE=32", -+ sub { my @warnings = -+ @{vms_info(32)->{disable_warns}}; -+ @warnings -+ ? "/WARNINGS=DISABLE=(".join(",",@warnings).")" : (); -+ } ), -+ defines => -+ add(sub { -+ return vms_info(32)->{def_zlib} -+ ? "LIBZ=\"\"\"".vms_info(32)->{def_zlib}."\"\"\"" : (); -+ }), -+ ex_libs => add(sub { return vms_info(32)->{zlib} || (); }), -+ pointer_size => sub { return vms_info(32)->{pointer_size} }, -+ }, -+ "vms-ia64-p64" => { -+ inherit_from => [ "vms-generic" ], -+ cflags => -+ add("/POINTER_SIZE=64=ARGV", -+ sub { my @warnings = -+ @{vms_info(64)->{disable_warns}}; -+ @warnings -+ ? "/WARNINGS=DISABLE=(".join(",",@warnings).")" : (); -+ } ), -+ defines => -+ add(sub { -+ return vms_info(64)->{def_zlib} -+ ? "LIBZ=\"\"\"".vms_info(64)->{def_zlib}."\"\"\"" : (); -+ }), -+ ex_libs => add(sub { return vms_info(64)->{zlib} || (); }), -+ pointer_size => sub { return vms_info(64)->{pointer_size} }, -+ }, -+ -+); -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/50-djgpp.conf b/CryptoPkg/Library/OpensslLib/openssl/Configurations/50-djgpp.conf -new file mode 100644 -index 0000000..f532bd1 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/50-djgpp.conf -@@ -0,0 +1,15 @@ -+# We can't make any commitment to support the DJGPP platform, -+# and rely entirely on the OpenSSL community to help is fine -+# tune and test. -+ -+%targets = ( -+ "DJGPP" => { -+ inherit_from => [ asm("x86_asm") ], -+ cc => "gcc", -+ cflags => "-I/dev/env/WATT_ROOT/inc -DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O2 -Wall", -+ sys_id => "MSDOS", -+ ex_libs => add("-L/dev/env/WATT_ROOT/lib -lwatt"), -+ bn_ops => "BN_LLONG", -+ perlasm_scheme => "a.out", -+ }, -+); -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/50-haiku.conf b/CryptoPkg/Library/OpensslLib/openssl/Configurations/50-haiku.conf -new file mode 100644 -index 0000000..f114666 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/50-haiku.conf -@@ -0,0 +1,29 @@ -+%targets = ( -+ "haiku-common" => { -+ template => 1, -+ cc => "cc", -+ cflags => add_before(picker(default => "-DL_ENDIAN -Wall -include \$(SRCDIR)/os-dep/haiku.h", -+ debug => "-g -O0", -+ release => "-O2"), -+ threads("-D_REENTRANT")), -+ sys_id => "HAIKU", -+ ex_libs => "-lnetwork", -+ perlasm_scheme => "elf", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ shared_target => "gnu-shared", -+ shared_cflag => "-fPIC", -+ shared_ldflag => "-shared", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ "haiku-x86" => { -+ inherit_from => [ "haiku-common", asm("x86_elf_asm") ], -+ cflags => add(picker(release => "-fomit-frame-pointer")), -+ bn_ops => "BN_LLONG", -+ }, -+ "haiku-x86_64" => { -+ inherit_from => [ "haiku-common" ], -+ cflags => add("-m64"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ }, -+); -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/50-masm.conf b/CryptoPkg/Library/OpensslLib/openssl/Configurations/50-masm.conf -new file mode 100644 -index 0000000..60a5507 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/50-masm.conf -@@ -0,0 +1,17 @@ -+# We can't make commitment to supporting Microsoft assembler, -+# because it would mean supporting all masm versions. This in -+# in turn is because masm is not really an interchangeable option, -+# while users tend to have reasons to stick with specific Visual -+# Studio versions. It's usually lesser hassle to make it work -+# with latest assembler, but tweaking for older versions had -+# proven to be daunting task. This is experimental target, for -+# production builds stick with [up-to-date version of] nasm. -+ -+%targets = ( -+ "VC-WIN64A-masm" => { -+ inherit_from => [ "VC-WIN64A" ], -+ as => "ml64", -+ asflags => "/c /Cp /Cx /Zi", -+ asoutflag => "/Fo", -+ }, -+); -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/90-team.conf b/CryptoPkg/Library/OpensslLib/openssl/Configurations/90-team.conf -new file mode 100644 -index 0000000..0a83c22 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/90-team.conf -@@ -0,0 +1,112 @@ -+## -*- mode: perl; -*- -+## Build configuration targets for openssl-team members -+ -+%targets = ( -+ "purify" => { -+ cc => "purify gcc", -+ cflags => "-g -Wall", -+ thread_scheme => "(unknown)", -+ ex_libs => add(" ","-lsocket -lnsl"), -+ }, -+ "debug" => { -+ cc => "gcc", -+ cflags => "-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DOPENSSL_NO_ASM -ggdb -g2 -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror", -+ thread_scheme => "(unknown)", -+ }, -+ "debug-erbridge" => { -+ inherit_from => [ "x86_64_asm" ], -+ cc => "gcc", -+ cflags => combine("$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -m64 -DL_ENDIAN -DTERMIO -g", -+ threads("-D_REENTRANT")), -+ ex_libs => add(" ","-ldl"), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "elf", -+ dso_scheme => "dlfcn", -+ shared_target => "linux-shared", -+ shared_cflag => "-fPIC", -+ shared_ldflag => "-m64", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ multilib => "64", -+ }, -+ "debug-linux-pentium" => { -+ inherit_from => [ "x86_elf_asm" ], -+ cc => "gcc", -+ cflags => combine("-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DL_ENDIAN -g -mcpu=pentium -Wall", -+ threads("-D_REENTRANT")), -+ ex_libs => add(" ","-ldl"), -+ bn_ops => "BN_LLONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ }, -+ "debug-linux-ppro" => { -+ inherit_from => [ "x86_elf_asm" ], -+ cc => "gcc", -+ cflags => combine("-DBN_DEBUG -DREF_DEBUG -DCONF_DEBUG -DBN_CTX_DEBUG -DL_ENDIAN -g -mcpu=pentiumpro -Wall", -+ threads("-D_REENTRANT")), -+ ex_libs => add(" ","-ldl"), -+ bn_ops => "BN_LLONG", -+ thread_scheme => "pthreads", -+ dso_scheme => "dlfcn", -+ }, -+ "debug-linux-ia32-aes" => { -+ cc => "gcc", -+ cflags => combine("-DL_ENDIAN -O3 -fomit-frame-pointer -Wall", -+ threads("-D_REENTRANT")), -+ ex_libs => add(" ","-ldl"), -+ bn_ops => "BN_LLONG", -+ cpuid_asm_src => "x86cpuid.s", -+ bn_asm_src => "bn-586.s co-586.s x86-mont.s", -+ des_asm_src => "des-586.s crypt586.s", -+ aes_asm_src => "aes_x86core.s aes_cbc.s aesni-x86.s", -+ bf_asm_src => "bf-586.s", -+ md5_asm_src => "md5-586.s", -+ sha1_asm_src => "sha1-586.s sha256-586.s sha512-586.s", -+ cast_asm_src => "cast-586.s", -+ rc4_asm_src => "rc4-586.s", -+ rmd160_asm_src => "rmd-586.s", -+ rc5_asm_src => "rc5-586.s", -+ wp_asm_src => "wp_block.s wp-mmx.s", -+ modes_asm_src => "ghash-x86.s", -+ padlock_asm_src => "e_padlock-x86.s", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "elf", -+ dso_scheme => "dlfcn", -+ shared_target => "linux-shared", -+ shared_cflag => "-fPIC", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ "dist" => { -+ cc => "cc", -+ cflags => "-O", -+ thread_scheme => "(unknown)", -+ }, -+ "debug-test-64-clang" => { -+ inherit_from => [ "x86_64_asm" ], -+ cc => "clang", -+ cflags => combine("$gcc_devteam_warn -Wno-error=overlength-strings -Wno-error=extended-offsetof -Wno-error=language-extension-token -Wno-error=unused-const-variable -Wstrict-overflow -Qunused-arguments -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe", -+ threads("${BSDthreads}")), -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "elf", -+ dso_scheme => "dlfcn", -+ shared_target => "bsd-gcc-shared", -+ shared_cflag => "-fPIC", -+ shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+ }, -+ "darwin64-debug-test-64-clang" => { -+ inherit_from => [ "x86_64_asm" ], -+ cc => "clang", -+ cflags => combine("-arch x86_64 -DL_ENDIAN $gcc_devteam_warn -Wno-error=overlength-strings -Wno-error=extended-offsetof -Wno-error=language-extension-token -Wno-error=unused-const-variable -Wstrict-overflow -Qunused-arguments -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe", -+ threads("${BSDthreads}")), -+ sys_id => "MACOSX", -+ bn_ops => "SIXTY_FOUR_BIT_LONG", -+ thread_scheme => "pthreads", -+ perlasm_scheme => "macosx", -+ dso_scheme => "dlfcn", -+ shared_target => "darwin-shared", -+ shared_cflag => "-fPIC -fno-common", -+ shared_ldflag => "-arch x86_64 -dynamiclib", -+ shared_extension => ".\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", -+ }, -+); -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/INTERNALS.Configure b/CryptoPkg/Library/OpensslLib/openssl/Configurations/INTERNALS.Configure -new file mode 100644 -index 0000000..b28305d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/INTERNALS.Configure -@@ -0,0 +1,136 @@ -+Configure Internals -+=================== -+ -+[ note: this file uses markdown for formatting ] -+ -+Intro -+----- -+ -+This is a collection of notes that are hopefully of interest to those -+who decide to dive into Configure and what it does. This is a living -+document and anyone is encouraged to add to it and submit changes. -+There's no claim for this document to be complete at any time, but it -+will hopefully reach such a point in time. -+ -+ -+---------------------------------------------------------------------- -+ -+Parsing build.info files, processing conditions -+----------------------------------------------- -+ -+Processing conditions in build.info files is done with the help of a -+condition stack that tell if a build.info should be processed or if it -+should just be skipped over. The possible states of the stack top are -+expressed in the following comment from Configure: -+ -+ # The top item of this stack has the following values -+ # -2 positive already run and we found ELSE (following ELSIF should fail) -+ # -1 positive already run (skip until ENDIF) -+ # 0 negatives so far (if we're at a condition, check it) -+ # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF) -+ # 2 positive ELSE (following ELSIF should fail) -+ -+Ground rule is that non-condition lines are skipped over if the -+stack top is > 0. Condition lines (IF, ELSIF, ELSE and ENDIF -+statements) need to be processed either way to keep track of the skip -+stack states, so they are a little more intricate. -+ -+Instead of trying to describe in words, here are some example of what -+the skip stack should look like after each line is processed: -+ -+Example 1: -+ -+| IF[1] | 1 | | -+| ... whatever ... | | this line is processed | -+| IF[1] | 1 1 | | -+| ... whatever ... | | this line is processed | -+| ELSIF[1] | 1 -1 | | -+| ... whatever ... | | this line is skipped over | -+| ELSE | 1 -2 | | -+| ... whatever ... | | this line is skipped over | -+| ENDIF | 1 | | -+| ... whatever ... | | this line is processed | -+| ELSIF[1] | -1 | | -+| ... whatever ... | | this line is skipped over | -+| IF[1] | -1 -1 | | -+| ... whatever ... | | this line is skipped over | -+| ELSIF[1] | -1 -1 | | -+| ... whatever ... | | this line is skipped over | -+| ELSE | -1 -2 | | -+| ... whatever ... | | this line is skipped over | -+| ENDIF | -1 | | -+| ... whatever ... | | this line is skipped over | -+| ENDIF | | | -+ -+Example 2: -+ -+| IF[0] | 0 | | -+| ... whatever ... | | this line is skipped over | -+| IF[1] | 0 -1 | | -+| ... whatever ... | | this line is skipped over | -+| ELSIF[1] | 0 -1 | | -+| ... whatever ... | | this line is skipped over | -+| ELSE | 0 -2 | | -+| ... whatever ... | | this line is skipped over | -+| ENDIF | 0 | | -+| ... whatever ... | | this line is skipped over | -+| ELSIF[1] | 1 | | -+| ... whatever ... | | this line is processed | -+| IF[1] | 1 1 | | -+| ... whatever ... | | this line is processed | -+| ELSIF[1] | 1 -1 | | -+| ... whatever ... | | this line is skipped over | -+| ELSE | 1 -2 | | -+| ... whatever ... | | this line is skipped over | -+| ENDIF | 1 | | -+| ... whatever ... | | this line is processed | -+| ENDIF | | | -+ -+Example 3: -+ -+| IF[0] | 0 | | -+| ... whatever ... | | this line is skipped over | -+| IF[0] | 0 -1 | | -+| ... whatever ... | | this line is skipped over | -+| ELSIF[1] | 0 -1 | | -+| ... whatever ... | | this line is skipped over | -+| ELSE | 0 -2 | | -+| ... whatever ... | | this line is skipped over | -+| ENDIF | 0 | | -+| ... whatever ... | | this line is skipped over | -+| ELSIF[1] | 1 | | -+| ... whatever ... | | this line is processed | -+| IF[0] | 1 0 | | -+| ... whatever ... | | this line is skipped over | -+| ELSIF[1] | 1 1 | | -+| ... whatever ... | | this line is processed | -+| ELSE | 1 -2 | | -+| ... whatever ... | | this line is skipped over | -+| ENDIF | 1 | | -+| ... whatever ... | | this line is processed | -+| ENDIF | | | -+ -+Example 4: -+ -+| IF[0] | 0 | | -+| ... whatever ... | | this line is skipped over | -+| IF[0] | 0 -1 | | -+| ... whatever ... | | this line is skipped over | -+| ELSIF[0] | 0 -1 | | -+| ... whatever ... | | this line is skipped over | -+| ELSE | 0 -2 | | -+| ... whatever ... | | this line is skipped over | -+| ENDIF | 0 | | -+| ... whatever ... | | this line is skipped over | -+| ELSIF[1] | 1 | | -+| ... whatever ... | | this line is processed | -+| IF[0] | 1 0 | | -+| ... whatever ... | | this line is skipped over | -+| ELSIF[0] | 1 0 | | -+| ... whatever ... | | this line is skipped over | -+| ELSE | 1 2 | | -+| ... whatever ... | | this line is processed | -+| ENDIF | 1 | | -+| ... whatever ... | | this line is processed | -+| ENDIF | | | -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/README b/CryptoPkg/Library/OpensslLib/openssl/Configurations/README -new file mode 100644 -index 0000000..da64e8c ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/README -@@ -0,0 +1,655 @@ -+Configurations of OpenSSL target platforms -+========================================== -+ -+Target configurations are a collection of facts that we know about -+different platforms and their capabilities. We organise them in a -+hash table, where each entry represent a specific target. -+ -+In each table entry, the following keys are significant: -+ -+ inherit_from => Other targets to inherit values from. -+ Explained further below. [1] -+ template => Set to 1 if this isn't really a platform -+ target. Instead, this target is a template -+ upon which other targets can be built. -+ Explained further below. [1] -+ -+ sys_id => System identity for systems where that -+ is difficult to determine automatically. -+ -+ cc => The compiler command, usually one of "cc", -+ "gcc" or "clang". This command is normally -+ also used to link object files and -+ libraries into the final program. -+ cflags => Flags that are used at all times when -+ compiling. -+ defines => As an alternative, macro definitions may be -+ present here instead of in `cflags'. If -+ given here, they MUST be as an array of the -+ string such as "MACRO=value", or just -+ "MACRO" for definitions without value. -+ shared_cflag => Extra compilation flags used when -+ compiling for shared libraries, typically -+ something like "-fPIC". -+ -+ (linking is a complex thing, see [3] below) -+ ld => Linker command, usually not defined -+ (meaning the compiler command is used -+ instead). -+ (NOTE: this is here for future use, it's -+ not implemented yet) -+ lflags => Flags that are used when linking apps. -+ shared_ldflag => Flags that are used when linking shared -+ or dynamic libraries. -+ plib_lflags => Extra linking flags to appear just before -+ the libraries on the command line. -+ ex_libs => Extra libraries that are needed when -+ linking. -+ -+ ar => The library archive command, the default is -+ "ar". -+ (NOTE: this is here for future use, it's -+ not implemented yet) -+ arflags => Flags to be used with the library archive -+ command. -+ -+ ranlib => The library archive indexing command, the -+ default is 'ranlib' it it exists. -+ -+ unistd => An alternative header to the typical -+ ''. This is very rarely needed. -+ -+ shared_extension => File name extension used for shared -+ libraries. -+ obj_extension => File name extension used for object files. -+ On unix, this defaults to ".o" (NOTE: this -+ is here for future use, it's not -+ implemented yet) -+ exe_extension => File name extension used for executable -+ files. On unix, this defaults to "" (NOTE: -+ this is here for future use, it's not -+ implemented yet) -+ -+ thread_scheme => The type of threads is used on the -+ configured platform. Currently known -+ values are "(unknown)", "pthreads", -+ "uithreads" (a.k.a solaris threads) and -+ "winthreads". Except for "(unknown)", the -+ actual value is currently ignored but may -+ be used in the future. See further notes -+ below [2]. -+ dso_scheme => The type of dynamic shared objects to build -+ for. This mostly comes into play with -+ engines, but can be used for other purposes -+ as well. Valid values are "DLFCN" -+ (dlopen() et al), "DLFCN_NO_H" (for systems -+ that use dlopen() et al but do not have -+ fcntl.h), "DL" (shl_load() et al), "WIN32" -+ and "VMS". -+ perlasm_scheme => The perlasm method used to created the -+ assembler files used when compiling with -+ assembler implementations. -+ shared_target => The shared library building method used. -+ This is a target found in Makefile.shared. -+ build_scheme => The scheme used to build up a Makefile. -+ In its simplest form, the value is a string -+ with the name of the build scheme. -+ The value may also take the form of a list -+ of strings, if the build_scheme is to have -+ some options. In this case, the first -+ string in the list is the name of the build -+ scheme. -+ Currently recognised build scheme is "unified". -+ For the "unified" build scheme, this item -+ *must* be an array with the first being the -+ word "unified" and the second being a word -+ to identify the platform family. -+ -+ multilib => On systems that support having multiple -+ implementations of a library (typically a -+ 32-bit and a 64-bit variant), this is used -+ to have the different variants in different -+ directories. -+ -+ bn_ops => Building options (was just bignum options -+ in the earlier history of this option, -+ hence the name). This a string of words -+ that describe properties on the designated -+ target platform, such as the type of -+ integers used to build up the bitnum, -+ different ways to implement certain ciphers -+ and so on. To fully comprehend the -+ meaning, the best is to read the affected -+ source. -+ The valid words are: -+ -+ BN_LLONG use 'unsigned long long' in -+ some bignum calculations. -+ This has no value when -+ SIXTY_FOUR_BIT or -+ SIXTY_FOUR_BIT_LONG is given. -+ RC4_CHAR makes the basic RC4 unit of -+ calculation an unsigned char. -+ SIXTY_FOUR_BIT processor registers -+ are 64 bits, long is -+ 32 bits, long long is -+ 64 bits. -+ SIXTY_FOUR_BIT_LONG processor registers -+ are 64 bits, long is -+ 64 bits. -+ THIRTY_TWO_BIT processor registers -+ are 32 bits. -+ EXPORT_VAR_AS_FN for shared libraries, -+ export vars as -+ accessor functions. -+ -+ apps_extra_src => Extra source to build apps/openssl, as -+ needed by the target. -+ cpuid_asm_src => assembler implementation of cpuid code as -+ well as OPENSSL_cleanse(). -+ Default to mem_clr.c -+ bn_asm_src => Assembler implementation of core bignum -+ functions. -+ Defaults to bn_asm.c -+ ec_asm_src => Assembler implementation of core EC -+ functions. -+ des_asm_src => Assembler implementation of core DES -+ encryption functions. -+ Defaults to 'des_enc.c fcrypt_b.c' -+ aes_asm_src => Assembler implementation of core AES -+ functions. -+ Defaults to 'aes_core.c aes_cbc.c' -+ bf_asm_src => Assembler implementation of core BlowFish -+ functions. -+ Defaults to 'bf_enc.c' -+ md5_asm_src => Assembler implementation of core MD5 -+ functions. -+ sha1_asm_src => Assembler implementation of core SHA1, -+ functions, and also possibly SHA256 and -+ SHA512 ones. -+ cast_asm_src => Assembler implementation of core CAST -+ functions. -+ Defaults to 'c_enc.c' -+ rc4_asm_src => Assembler implementation of core RC4 -+ functions. -+ Defaults to 'rc4_enc.c rc4_skey.c' -+ rmd160_asm_src => Assembler implementation of core RMD160 -+ functions. -+ rc5_asm_src => Assembler implementation of core RC5 -+ functions. -+ Defaults to 'rc5_enc.c' -+ wp_asm_src => Assembler implementation of core WHIRLPOOL -+ functions. -+ cmll_asm_src => Assembler implementation of core CAMELLIA -+ functions. -+ Defaults to 'camellia.c cmll_misc.c cmll_cbc.c' -+ modes_asm_src => Assembler implementation of cipher modes, -+ currently the functions gcm_gmult_4bit and -+ gcm_ghash_4bit. -+ padlock_asm_src => Assembler implementation of core parts of -+ the padlock engine. This is mandatory on -+ any platform where the padlock engine might -+ actually be built. -+ -+ -+[1] as part of the target configuration, one can have a key called -+ 'inherit_from' that indicate what other configurations to inherit -+ data from. These are resolved recursively. -+ -+ Inheritance works as a set of default values that can be overridden -+ by corresponding key values in the inheriting configuration. -+ -+ Note 1: any configuration table can be used as a template. -+ Note 2: pure templates have the attribute 'template => 1' and -+ cannot be used as build targets. -+ -+ If several configurations are given in the 'inherit_from' array, -+ the values of same attribute are concatenated with space -+ separation. With this, it's possible to have several smaller -+ templates for different configuration aspects that can be combined -+ into a complete configuration. -+ -+ instead of a scalar value or an array, a value can be a code block -+ of the form 'sub { /* your code here */ }'. This code block will -+ be called with the list of inherited values for that key as -+ arguments. In fact, the concatenation of strings is really done -+ by using 'sub { join(" ",@_) }' on the list of inherited values. -+ -+ An example: -+ -+ "foo" => { -+ template => 1, -+ haha => "ha ha", -+ hoho => "ho", -+ ignored => "This should not appear in the end result", -+ }, -+ "bar" => { -+ template => 1, -+ haha => "ah", -+ hoho => "haho", -+ hehe => "hehe" -+ }, -+ "laughter" => { -+ inherit_from => [ "foo", "bar" ], -+ hehe => sub { join(" ",(@_,"!!!")) }, -+ ignored => "", -+ } -+ -+ The entry for "laughter" will become as follows after processing: -+ -+ "laughter" => { -+ haha => "ha ha ah", -+ hoho => "ho haho", -+ hehe => "hehe !!!", -+ ignored => "" -+ } -+ -+[2] OpenSSL is built with threading capabilities unless the user -+ specifies 'no-threads'. The value of the key 'thread_scheme' may -+ be "(unknown)", in which case the user MUST give some compilation -+ flags to Configure. -+ -+[3] OpenSSL has three types of things to link from object files or -+ static libraries: -+ -+ - shared libraries; that would be libcrypto and libssl. -+ - shared objects (sometimes called dynamic libraries); that would -+ be the engines. -+ - applications; those are apps/openssl and all the test apps. -+ -+ Very roughly speaking, linking is done like this (words in braces -+ represent the configuration settings documented at the beginning -+ of this file): -+ -+ shared libraries: -+ {ld} $(CFLAGS) {shared_ldflag} -shared -o libfoo.so \ -+ -Wl,--whole-archive libfoo.a -Wl,--no-whole-archive \ -+ {plib_lflags} -lcrypto {ex_libs} -+ -+ shared objects: -+ {ld} $(CFLAGS) {shared_ldflag} -shared -o libeng.so \ -+ blah1.o blah2.o {plib_lflags} -lcrypto {ex_libs} -+ -+ applications: -+ {ld} $(CFLAGS) {lflags} -o app \ -+ app1.o utils.o {plib_lflags} -lssl -lcrypto {ex_libs} -+ -+ -+Historically, the target configurations came in form of a string with -+values separated by colons. This use is deprecated. The string form -+looked like this: -+ -+ "target" => "{cc}:{cflags}:{unistd}:{thread_cflag}:{sys_id}:{lflags}:{bn_ops}:{cpuid_obj}:{bn_obj}:{ec_obj}:{des_obj}:{aes_obj}:{bf_obj}:{md5_obj}:{sha1_obj}:{cast_obj}:{rc4_obj}:{rmd160_obj}:{rc5_obj}:{wp_obj}:{cmll_obj}:{modes_obj}:{padlock_obj}:{perlasm_scheme}:{dso_scheme}:{shared_target}:{shared_cflag}:{shared_ldflag}:{shared_extension}:{ranlib}:{arflags}:{multilib}" -+ -+ -+Build info files -+================ -+ -+The build.info files that are spread over the source tree contain the -+minimum information needed to build and distribute OpenSSL. It uses a -+simple and yet fairly powerful language to determine what needs to be -+built, from what sources, and other relationships between files. -+ -+For every build.info file, all file references are relative to the -+directory of the build.info file for source files, and the -+corresponding build directory for built files if the build tree -+differs from the source tree. -+ -+When processed, every line is processed with the perl module -+Text::Template, using the delimiters "{-" and "-}". The hashes -+%config and %target are passed to the perl fragments, along with -+$sourcedir and $builddir, which are the locations of the source -+directory for the current build.info file and the corresponding build -+directory, all relative to the top of the build tree. -+ -+To begin with, things to be built are declared by setting specific -+variables: -+ -+ PROGRAMS=foo bar -+ LIBS=libsomething -+ ENGINES=libeng -+ SCRIPTS=myhack -+ EXTRA=file1 file2 -+ -+Note that the files mentioned for PROGRAMS, LIBS and ENGINES *must* be -+without extensions. The build file templates will figure them out. -+ -+For each thing to be built, it is then possible to say what sources -+they are built from: -+ -+ PROGRAMS=foo bar -+ SOURCE[foo]=foo.c common.c -+ SOURCE[bar]=bar.c extra.c common.c -+ -+It's also possible to tell some other dependencies: -+ -+ DEPEND[foo]=libsomething -+ DEPEND[libbar]=libsomethingelse -+ -+(it could be argued that 'libsomething' and 'libsomethingelse' are -+source as well. However, the files given through SOURCE are expected -+to be located in the source tree while files given through DEPEND are -+expected to be located in the build tree) -+ -+For some libraries, we maintain files with public symbols and their -+slot in a transfer vector (important on some platforms). It can be -+declared like this: -+ -+ ORDINALS[libcrypto]=crypto -+ -+The value is not the name of the file in question, but rather the -+argument to util/mkdef.pl that indicates which file to use. -+ -+One some platforms, shared libraries come with a name that's different -+from their static counterpart. That's declared as follows: -+ -+ SHARED_NAME[libfoo]=cygfoo-{- $config{shlibver} -} -+ -+The example is from Cygwin, which has a required naming convention. -+ -+Sometimes, it makes sense to rename an output file, for example a -+library: -+ -+ RENAME[libfoo]=libbar -+ -+That lines has "libfoo" get renamed to "libbar". While it makes no -+sense at all to just have a rename like that (why not just use -+"libbar" everywhere?), it does make sense when it can be used -+conditionally. See a little further below for an example. -+ -+In some cases, it's desirable to include some source files in the -+shared form of a library only: -+ -+ SHARED_SOURCE[libfoo]=dllmain.c -+ -+For any file to be built, it's also possible to tell what extra -+include paths the build of their source files should use: -+ -+ INCLUDE[foo]=include -+ -+In some cases, one might want to generate some source files from -+others, that's done as follows: -+ -+ GENERATE[foo.s]=asm/something.pl $(CFLAGS) -+ GENERATE[bar.s]=asm/bar.S -+ -+The value of each GENERATE line is a command line or part of it. -+Configure places no rules on the command line, except the the first -+item muct be the generator file. It is, however, entirely up to the -+build file template to define exactly how those command lines should -+be handled, how the output is captured and so on. -+ -+Sometimes, the generator file itself depends on other files, for -+example if it is a perl script that depends on other perl modules. -+This can be expressed using DEPEND like this: -+ -+ DEPEND[asm/something.pl]=../perlasm/Foo.pm -+ -+There may also be cases where the exact file isn't easily specified, -+but an inclusion directory still needs to be specified. INCLUDE can -+be used in that case: -+ -+ INCLUDE[asm/something.pl]=../perlasm -+ -+NOTE: GENERATE lines are limited to one command only per GENERATE. -+ -+As a last resort, it's possible to have raw build file lines, between -+BEGINRAW and ENDRAW lines as follows: -+ -+ BEGINRAW[Makefile(unix)] -+ haha.h: {- $builddir -}/Makefile -+ echo "/* haha */" > haha.h -+ ENDRAW[Makefile(unix)] -+ -+The word within square brackets is the build_file configuration item -+or the build_file configuration item followed by the second word in the -+build_scheme configuration item for the configured target within -+parenthesis as shown above. For example, with the following relevant -+configuration items: -+ -+ build_file => "build.ninja" -+ build_scheme => [ "unified", "unix" ] -+ -+... these lines will be considered: -+ -+ BEGINRAW[build.ninja] -+ build haha.h: echo "/* haha */" > haha.h -+ ENDRAW[build.ninja] -+ -+ BEGINRAW[build.ninja(unix)] -+ build hoho.h: echo "/* hoho */" > hoho.h -+ ENDRAW[build.ninja(unix)] -+ -+Should it be needed because the recipes within a RAW section might -+clash with those generated by Configure, it's possible to tell it -+not to generate them with the use of OVERRIDES, for example: -+ -+ SOURCE[libfoo]=foo.c bar.c -+ -+ OVERRIDES=bar.o -+ BEGINRAW[Makefile(unix)] -+ bar.o: bar.c -+ $(CC) $(CFLAGS) -DSPECIAL -c -o $@ $< -+ ENDRAW[Makefile(unix)] -+ -+See the documentation further up for more information on configuration -+items. -+ -+Finally, you can have some simple conditional use of the build.info -+information, looking like this: -+ -+ IF[1] -+ something -+ ELSIF[2] -+ something other -+ ELSE -+ something else -+ ENDIF -+ -+The expression in square brackets is interpreted as a string in perl, -+and will be seen as true if perl thinks it is, otherwise false. For -+example, the above would have "something" used, since 1 is true. -+ -+Together with the use of Text::Template, this can be used as -+conditions based on something in the passed variables, for example: -+ -+ IF[{- $disabled{shared} -}] -+ LIBS=libcrypto -+ SOURCE[libcrypto]=... -+ ELSE -+ LIBS=libfoo -+ SOURCE[libfoo]=... -+ ENDIF -+ -+or: -+ -+ # VMS has a cultural standard where all libraries are prefixed. -+ # For OpenSSL, the choice is 'ossl_' -+ IF[{- $config{target} =~ /^vms/ -}] -+ RENAME[libcrypto]=ossl_libcrypto -+ RENAME[libssl]=ossl_libssl -+ ENDIF -+ -+ -+Build-file programming with the "unified" build system -+====================================================== -+ -+"Build files" are called "Makefile" on Unix-like operating systems, -+"descrip.mms" for MMS on VMS, "makefile" for nmake on Windows, etc. -+ -+To use the "unified" build system, the target configuration needs to -+set the three items 'build_scheme', 'build_file' and 'build_command'. -+In the rest of this section, we will assume that 'build_scheme' is set -+to "unified" (see the configurations documentation above for the -+details). -+ -+For any name given by 'build_file', the "unified" system expects a -+template file in Configurations/ named like the build file, with -+".tmpl" appended, or in case of possible ambiguity, a combination of -+the second 'build_scheme' list item and the 'build_file' name. For -+example, if 'build_file' is set to "Makefile", the template could be -+Configurations/Makefile.tmpl or Configurations/unix-Makefile.tmpl. -+In case both Configurations/unix-Makefile.tmpl and -+Configurations/Makefile.tmpl are present, the former takes -+precedence. -+ -+The build-file template is processed with the perl module -+Text::Template, using "{-" and "-}" as delimiters that enclose the -+perl code fragments that generate configuration-dependent content. -+Those perl fragments have access to all the hash variables from -+configdata.pem. -+ -+The build-file template is expected to define at least the following -+perl functions in a perl code fragment enclosed with "{-" and "-}". -+They are all expected to return a string with the lines they produce. -+ -+ generatesrc - function that produces build file lines to generate -+ a source file from some input. -+ -+ It's called like this: -+ -+ generatesrc(src => "PATH/TO/tobegenerated", -+ generator => [ "generatingfile", ... ] -+ generator_incs => [ "INCL/PATH", ... ] -+ generator_deps => [ "dep1", ... ] -+ generator => [ "generatingfile", ... ] -+ incs => [ "INCL/PATH", ... ], -+ deps => [ "dep1", ... ], -+ intent => one of "libs", "dso", "bin" ); -+ -+ 'src' has the name of the file to be generated. -+ 'generator' is the command or part of command to -+ generate the file, of which the first item is -+ expected to be the file to generate from. -+ generatesrc() is expected to analyse and figure out -+ exactly how to apply that file and how to capture -+ the result. 'generator_incs' and 'generator_deps' -+ are include directories and files that the generator -+ file itself depends on. 'incs' and 'deps' are -+ include directories and files that are used if $(CC) -+ is used as an intermediary step when generating the -+ end product (the file indicated by 'src'). 'intent' -+ indicates what the generated file is going to be -+ used for. -+ -+ src2obj - function that produces build file lines to build an -+ object file from source files and associated data. -+ -+ It's called like this: -+ -+ src2obj(obj => "PATH/TO/objectfile", -+ srcs => [ "PATH/TO/sourcefile", ... ], -+ deps => [ "dep1", ... ], -+ incs => [ "INCL/PATH", ... ] -+ intent => one of "lib", "dso", "bin" ); -+ -+ 'obj' has the intended object file *without* -+ extension, src2obj() is expected to add that. -+ 'srcs' has the list of source files to build the -+ object file, with the first item being the source -+ file that directly corresponds to the object file. -+ 'deps' is a list of explicit dependencies. 'incs' -+ is a list of include file directories. Finally, -+ 'intent' indicates what this object file is going -+ to be used for. -+ -+ obj2lib - function that produces build file lines to build a -+ static library file ("libfoo.a" in Unix terms) from -+ object files. -+ -+ called like this: -+ -+ obj2lib(lib => "PATH/TO/libfile", -+ objs => [ "PATH/TO/objectfile", ... ]); -+ -+ 'lib' has the intended library file name *without* -+ extension, obj2lib is expected to add that. 'objs' -+ has the list of object files (also *without* -+ extension) to build this library. -+ -+ libobj2shlib - function that produces build file lines to build a -+ shareable object library file ("libfoo.so" in Unix -+ terms) from the corresponding static library file -+ or object files. -+ -+ called like this: -+ -+ libobj2shlib(shlib => "PATH/TO/shlibfile", -+ lib => "PATH/TO/libfile", -+ objs => [ "PATH/TO/objectfile", ... ], -+ deps => [ "PATH/TO/otherlibfile", ... ], -+ ordinals => [ "word", "/PATH/TO/ordfile" ]); -+ -+ 'lib' has the intended library file name *without* -+ extension, libobj2shlib is expected to add that. -+ 'shlib' has the corresponding shared library name -+ *without* extension. 'deps' has the list of other -+ libraries (also *without* extension) this library -+ needs to be linked with. 'objs' has the list of -+ object files (also *without* extension) to build -+ this library. 'ordinals' MAY be present, and when -+ it is, its value is an array where the word is -+ "crypto" or "ssl" and the file is one of the ordinal -+ files util/libeay.num or util/ssleay.num in the -+ source directory. -+ -+ This function has a choice; it can use the -+ corresponding static library as input to make the -+ shared library, or the list of object files. -+ -+ obj2dso - function that produces build file lines to build a -+ dynamic shared object file from object files. -+ -+ called like this: -+ -+ obj2dso(lib => "PATH/TO/libfile", -+ objs => [ "PATH/TO/objectfile", ... ], -+ deps => [ "PATH/TO/otherlibfile", -+ ... ]); -+ -+ This is almost the same as libobj2shlib, but the -+ intent is to build a shareable library that can be -+ loaded in runtime (a "plugin"...). The differences -+ are subtle, one of the most visible ones is that the -+ resulting shareable library is produced from object -+ files only. -+ -+ obj2bin - function that produces build file lines to build an -+ executable file from object files. -+ -+ called like this: -+ -+ obj2bin(bin => "PATH/TO/binfile", -+ objs => [ "PATH/TO/objectfile", ... ], -+ deps => [ "PATH/TO/libfile", ... ]); -+ -+ 'bin' has the intended executable file name -+ *without* extension, obj2bin is expected to add -+ that. 'objs' has the list of object files (also -+ *without* extension) to build this library. 'deps' -+ has the list of library files (also *without* -+ extension) that the programs needs to be linked -+ with. -+ -+ in2script - function that produces build file lines to build a -+ script file from some input. -+ -+ called like this: -+ -+ in2script(script => "PATH/TO/scriptfile", -+ sources => [ "PATH/TO/infile", ... ]); -+ -+ 'script' has the intended script file name. -+ 'sources' has the list of source files to build the -+ resulting script from. -+ -+In all cases, file file paths are relative to the build tree top, and -+the build file actions run with the build tree top as current working -+directory. -+ -+Make sure to end the section with these functions with a string that -+you thing is appropriate for the resulting build file. If nothing -+else, end it like this: -+ -+ ""; # Make sure no lingering values end up in the Makefile -+ -} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/README.design b/CryptoPkg/Library/OpensslLib/openssl/Configurations/README.design -new file mode 100644 -index 0000000..bea9790 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/README.design -@@ -0,0 +1,641 @@ -+Design document for the unified scheme data -+=========================================== -+ -+How are things connected? -+------------------------- -+ -+The unified scheme takes all its data from the build.info files seen -+throughout the source tree. These files hold the minimum information -+needed to build end product files from diverse sources. See the -+section on build.info files below. -+ -+From the information in build.info files, Configure builds up an -+information database as a hash table called %unified_info, which is -+stored in configdata.pm, found at the top of the build tree (which may -+or may not be the same as the source tree). -+ -+Configurations/common.tmpl uses the data from %unified_info to -+generate the rules for building end product files as well as -+intermediary files with the help of a few functions found in the -+build-file templates. See the section on build-file templates further -+down for more information. -+ -+build.info files -+---------------- -+ -+As mentioned earlier, build.info files are meant to hold the minimum -+information needed to build output files, and therefore only (with a -+few possible exceptions [1]) have information about end products (such -+as scripts, library files and programs) and source files (such as C -+files, C header files, assembler files, etc). Intermediate files such -+as object files are rarely directly referred to in build.info files (and -+when they are, it's always with the file name extension .o), they are -+inferred by Configure. By the same rule of minimalism, end product -+file name extensions (such as .so, .a, .exe, etc) are never mentioned -+in build.info. Their file name extensions will be inferred by the -+build-file templates, adapted for the platform they are meant for (see -+sections on %unified_info and build-file templates further down). -+ -+The variables PROGRAMS, LIBS, ENGINES and SCRIPTS are used to declare -+end products. There are variants for them with '_NO_INST' as suffix -+(PROGRAM_NO_INST etc) to specify end products that shouldn't get -+installed. -+ -+The variables SOURCE, DEPEND, INCLUDE and ORDINALS are indexed by a -+produced file, and their values are the source used to produce that -+particular produced file, extra dependencies, include directories -+needed, and ordinal files (explained further below. -+ -+All their values in all the build.info throughout the source tree are -+collected together and form a set of programs, libraries, engines and -+scripts to be produced, source files, dependencies, etc etc etc. -+ -+Let's have a pretend example, a very limited contraption of OpenSSL, -+composed of the program 'apps/openssl', the libraries 'libssl' and -+'libcrypto', an engine 'engines/ossltest' and their sources and -+dependencies. -+ -+ # build.info -+ LIBS=libcrypto libssl -+ ORDINALS[libcrypto]=crypto -+ ORDINALS[libssl]=ssl -+ INCLUDE[libcrypto]=include -+ INCLUDE[libssl]=include -+ DEPEND[libssl]=libcrypto -+ -+This is the top directory build.info file, and it tells us that two -+libraries are to be built, there are some ordinals to be used to -+declare what symbols in those libraries are seen as public, the -+include directory 'include/' shall be used throughout when building -+anything that will end up in each library, and that the library -+'libssl' depend on the library 'libcrypto' to function properly. -+ -+ # apps/build.info -+ PROGRAMS=openssl -+ SOURCE[openssl]=openssl.c -+ INCLUDE[openssl]=.. ../include -+ DEPEND[openssl]=../libssl -+ -+This is the build.info file in 'apps/', one may notice that all file -+paths mentioned are relative to the directory the build.info file is -+located in. This one tells us that there's a program to be built -+called 'apps/openssl' (the file name extension will depend on the -+platform and is therefore not mentioned in the build.info file). It's -+built from one source file, 'apps/openssl.c', and building it requires -+the use of '.' and 'include' include directories (both are declared -+from the point of view of the 'apps/' directory), and that the program -+depends on the library 'libssl' to function properly. -+ -+ # crypto/build.info -+ LIBS=../libcrypto -+ SOURCE[../libcrypto]=aes.c evp.c cversion.c -+ DEPEND[cversion.o]=buildinf.h -+ -+ GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(CFLAGS)" "$(PLATFORM)" -+ DEPEND[buildinf.h]=../Makefile -+ DEPEND[../util/mkbuildinf.pl]=../util/Foo.pm -+ -+This is the build.info file in 'crypto', and it tells us a little more -+about what's needed to produce 'libcrypto'. LIBS is used again to -+declare that 'libcrypto' is to be produced. This declaration is -+really unnecessary as it's already mentioned in the top build.info -+file, but can make the info file easier to understand. This is to -+show that duplicate information isn't an issue. -+ -+This build.info file informs us that 'libcrypto' is built from a few -+source files, 'crypto/aes.c', 'crypto/evp.c' and 'crypto/cversion.c'. -+It also shows us that building the object file inferred from -+'crypto/cversion.c' depends on 'crypto/buildinf.h'. Finally, it -+also shows the possibility to declare how some files are generated -+using some script, in this case a perl script, and how such scripts -+can be declared to depend on other files, in this case a perl module. -+ -+Two things are worth an extra note: -+ -+'DEPEND[cversion.o]' mentions an object file. DEPEND indexes is the -+only location where it's valid to mention them -+ -+Lines in 'BEGINRAW'..'ENDRAW' sections must always mention files as -+seen from the top directory, no exception. -+ -+ # ssl/build.info -+ LIBS=../libssl -+ SOURCE[../libssl]=tls.c -+ -+This is the build.info file in 'ssl/', and it tells us that the -+library 'libssl' is built from the source file 'ssl/tls.c'. -+ -+ # engines/build.info -+ ENGINES=dasync -+ SOURCE[dasync]=e_dasync.c -+ DEPEND[dasync]=../libcrypto -+ INCLUDE[dasync]=../include -+ -+ ENGINES_NO_INST=ossltest -+ SOURCE[ossltest]=e_ossltest.c -+ DEPEND[ossltest]=../libcrypto -+ INCLUDE[ossltest]=../include -+ -+This is the build.info file in 'engines/', telling us that two engines -+called 'engines/dasync' and 'engines/ossltest' shall be built, that -+dasync's source is 'engines/e_dasync.c' and ossltest's source is -+'engines/e_ossltest.c' and that the include directory 'include/' may -+be used when building anything that will be part of these engines. -+Also, both engines depend on the library 'libcrypto' to function -+properly. Finally, only dasync is being installed, as ossltest is -+only for internal testing. -+ -+When Configure digests these build.info files, the accumulated -+information comes down to this: -+ -+ LIBS=libcrypto libssl -+ ORDINALS[libcrypto]=crypto -+ SOURCE[libcrypto]=crypto/aes.c crypto/evp.c crypto/cversion.c -+ DEPEND[crypto/cversion.o]=crypto/buildinf.h -+ INCLUDE[libcrypto]=include -+ ORDINALS[libssl]=ssl -+ SOURCE[libssl]=ssl/tls.c -+ INCLUDE[libssl]=include -+ DEPEND[libssl]=libcrypto -+ -+ PROGRAMS=apps/openssl -+ SOURCE[apps/openssl]=apps/openssl.c -+ INCLUDE[apps/openssl]=. include -+ DEPEND[apps/openssl]=libssl -+ -+ ENGINES=engines/dasync -+ SOURCE[engines/dasync]=engines/e_dasync.c -+ DEPEND[engines/dasync]=libcrypto -+ INCLUDE[engines/dasync]=include -+ -+ ENGINES_NO_INST=engines/ossltest -+ SOURCE[engines/ossltest]=engines/e_ossltest.c -+ DEPEND[engines/ossltest]=libcrypto -+ INCLUDE[engines/ossltest]=include -+ -+ GENERATE[crypto/buildinf.h]=util/mkbuildinf.pl "$(CC) $(CFLAGS)" "$(PLATFORM)" -+ DEPEND[crypto/buildinf.h]=Makefile -+ DEPEND[util/mkbuildinf.pl]=util/Foo.pm -+ -+ -+A few notes worth mentioning: -+ -+LIBS may be used to declare routine libraries only. -+ -+PROGRAMS may be used to declare programs only. -+ -+ENGINES may be used to declare engines only. -+ -+The indexes for SOURCE and ORDINALS must only be end product files, -+such as libraries, programs or engines. The values of SOURCE -+variables must only be source files (possibly generated) -+ -+INCLUDE and DEPEND shows a relationship between different files -+(usually produced files) or between files and directories, such as a -+program depending on a library, or between an object file and some -+extra source file. -+ -+When Configure processes the build.info files, it will take it as -+truth without question, and will therefore perform very few checks. -+If the build tree is separate from the source tree, it will assume -+that all built files and up in the build directory and that all source -+files are to be found in the source tree, if they can be found there. -+Configure will assume that source files that can't be found in the -+source tree (such as 'crypto/bildinf.h' in the example above) are -+generated and will be found in the build tree. -+ -+ -+The %unified_info database -+-------------------------- -+ -+The information in all the build.info get digested by Configure and -+collected into the %unified_info database, divided into the following -+indexes: -+ -+ depends => a hash table containing 'file' => [ 'dependency' ... ] -+ pairs. These are directly inferred from the DEPEND -+ variables in build.info files. -+ -+ engines => a list of engines. These are directly inferred from -+ the ENGINES variable in build.info files. -+ -+ generate => a hash table containing 'file' => [ 'generator' ... ] -+ pairs. These are directly inferred from the GENERATE -+ variables in build.info files. -+ -+ includes => a hash table containing 'file' => [ 'include' ... ] -+ pairs. These are directly inferred from the INCLUDE -+ variables in build.info files. -+ -+ install => a hash table containing 'type' => [ 'file' ... ] pairs. -+ The types are 'programs', 'libraries', 'engines' and -+ 'scripts', and the array of files list the files of -+ that type that should be installed. -+ -+ libraries => a list of libraries. These are directly inferred from -+ the LIBS variable in build.info files. -+ -+ ordinals => a hash table containing 'file' => [ 'word', 'ordfile' ] -+ pairs. 'file' and 'word' are directly inferred from -+ the ORDINALS variables in build.info files, while the -+ file 'ofile' comes from internal knowledge in -+ Configure. -+ -+ programs => a list of programs. These are directly inferred from -+ the PROGRAMS variable in build.info files. -+ -+ rawlines => a list of build-file lines. These are a direct copy of -+ the BEGINRAW..ENDRAW lines in build.info files. Note: -+ only the BEGINRAW..ENDRAW section for the current -+ platform are copied, the rest are ignored. -+ -+ scripts => a list of scripts. There are directly inferred from -+ the SCRIPTS variable in build.info files. -+ -+ sources => a hash table containing 'file' => [ 'sourcefile' ... ] -+ pairs. These are indirectly inferred from the SOURCE -+ variables in build.info files. Object files are -+ mentioned in this hash table, with source files from -+ SOURCE variables, and AS source files for programs and -+ libraries. -+ -+ shared_sources => -+ a hash table just like 'sources', but only as source -+ files (object files) for building shared libraries. -+ -+As an example, here is how the build.info files example from the -+section above would be digested into a %unified_info table: -+ -+ our %unified_info = ( -+ "depends" => -+ { -+ "apps/openssl" => -+ [ -+ "libssl", -+ ], -+ "crypto/buildinf.h" => -+ [ -+ "Makefile", -+ ], -+ "crypto/cversion.o" => -+ [ -+ "crypto/buildinf.h", -+ ], -+ "engines/ossltest" => -+ [ -+ "libcrypto", -+ ], -+ "libssl" => -+ [ -+ "libcrypto", -+ ], -+ "util/mkbuildinf.pl" => -+ [ -+ "util/Foo.pm", -+ ], -+ }, -+ "engines" => -+ [ -+ "engines/dasync", -+ "engines/ossltest", -+ ], -+ "generate" => -+ { -+ "crypto/buildinf.h" => -+ [ -+ "util/mkbuildinf.pl", -+ "\"\$(CC)", -+ "\$(CFLAGS)\"", -+ "\"$(PLATFORM)\"", -+ ], -+ }, -+ "includes" => -+ { -+ "apps/openssl" => -+ [ -+ ".", -+ "include", -+ ], -+ "engines/ossltest" => -+ [ -+ "include" -+ ], -+ "libcrypto" => -+ [ -+ "include", -+ ], -+ "libssl" => -+ [ -+ "include", -+ ], -+ "util/mkbuildinf.pl" => -+ [ -+ "util", -+ ], -+ } -+ "install" => -+ { -+ "engines" => -+ [ -+ "engines/dasync", -+ ], -+ "libraries" => -+ [ -+ "libcrypto", -+ "libssl", -+ ], -+ "programs" => -+ [ -+ "apps/openssl", -+ ], -+ }, -+ "libraries" => -+ [ -+ "libcrypto", -+ "libssl", -+ ], -+ "ordinals" => -+ { -+ "libcrypto" => -+ [ -+ "crypto", -+ "util/libcrypto.num", -+ ], -+ "libssl" => -+ [ -+ "ssl", -+ "util/libssl.num", -+ ], -+ }, -+ "programs" => -+ [ -+ "apps/openssl", -+ ], -+ "rawlines" => -+ [ -+ ], -+ "sources" => -+ { -+ "apps/openssl" => -+ [ -+ "apps/openssl.o", -+ ], -+ "apps/openssl.o" => -+ [ -+ "apps/openssl.c", -+ ], -+ "crypto/aes.o" => -+ [ -+ "crypto/aes.c", -+ ], -+ "crypto/cversion.o" => -+ [ -+ "crypto/cversion.c", -+ ], -+ "crypto/evp.o" => -+ [ -+ "crypto/evp.c", -+ ], -+ "engines/e_ossltest.o" => -+ [ -+ "engines/e_ossltest.c", -+ ], -+ "engines/ossltest" => -+ [ -+ "engines/e_ossltest.o", -+ ], -+ "libcrypto" => -+ [ -+ "crypto/aes.c", -+ "crypto/cversion.c", -+ "crypto/evp.c", -+ ], -+ "libssl" => -+ [ -+ "ssl/tls.c", -+ ], -+ "ssl/tls.o" => -+ [ -+ "ssl/tls.c", -+ ], -+ }, -+ ); -+ -+As can be seen, everything in %unified_info is fairly simple suggest -+of information. Still, it tells us that to build all programs, we -+must build 'apps/openssl', and to build the latter, we will need to -+build all its sources ('apps/openssl.o' in this case) and all the -+other things it depends on (such as 'libssl'). All those dependencies -+need to be built as well, using the same logic, so to build 'libssl', -+we need to build 'ssl/tls.o' as well as 'libcrypto', and to build the -+latter... -+ -+ -+Build-file templates -+-------------------- -+ -+Build-file templates are essentially build-files (such as Makefile on -+Unix) with perl code fragments mixed in. Those perl code fragment -+will generate all the configuration dependent data, including all the -+rules needed to build end product files and intermediary files alike. -+At a minimum, there must be a perl code fragment that defines a set of -+functions that are used to generates specific build-file rules, to -+build static libraries from object files, to build shared libraries -+from static libraries, to programs from object files and libraries, -+etc. -+ -+ generatesrc - function that produces build file lines to generate -+ a source file from some input. -+ -+ It's called like this: -+ -+ generatesrc(src => "PATH/TO/tobegenerated", -+ generator => [ "generatingfile", ... ] -+ generator_incs => [ "INCL/PATH", ... ] -+ generator_deps => [ "dep1", ... ] -+ incs => [ "INCL/PATH", ... ], -+ deps => [ "dep1", ... ], -+ intent => one of "libs", "dso", "bin" ); -+ -+ 'src' has the name of the file to be generated. -+ 'generator' is the command or part of command to -+ generate the file, of which the first item is -+ expected to be the file to generate from. -+ generatesrc() is expected to analyse and figure out -+ exactly how to apply that file and how to capture -+ the result. 'generator_incs' and 'generator_deps' -+ are include directories and files that the generator -+ file itself depends on. 'incs' and 'deps' are -+ include directories and files that are used if $(CC) -+ is used as an intermediary step when generating the -+ end product (the file indicated by 'src'). 'intent' -+ indicates what the generated file is going to be -+ used for. -+ -+ src2obj - function that produces build file lines to build an -+ object file from source files and associated data. -+ -+ It's called like this: -+ -+ src2obj(obj => "PATH/TO/objectfile", -+ srcs => [ "PATH/TO/sourcefile", ... ], -+ deps => [ "dep1", ... ], -+ incs => [ "INCL/PATH", ... ] -+ intent => one of "lib", "dso", "bin" ); -+ -+ 'obj' has the intended object file *without* -+ extension, src2obj() is expected to add that. -+ 'srcs' has the list of source files to build the -+ object file, with the first item being the source -+ file that directly corresponds to the object file. -+ 'deps' is a list of explicit dependencies. 'incs' -+ is a list of include file directories. Finally, -+ 'intent' indicates what this object file is going -+ to be used for. -+ -+ obj2lib - function that produces build file lines to build a -+ static library file ("libfoo.a" in Unix terms) from -+ object files. -+ -+ called like this: -+ -+ obj2lib(lib => "PATH/TO/libfile", -+ objs => [ "PATH/TO/objectfile", ... ]); -+ -+ 'lib' has the intended library file name *without* -+ extension, obj2lib is expected to add that. 'objs' -+ has the list of object files (also *without* -+ extension) to build this library. -+ -+ libobj2shlib - function that produces build file lines to build a -+ shareable object library file ("libfoo.so" in Unix -+ terms) from the corresponding static library file -+ or object files. -+ -+ called like this: -+ -+ libobj2shlib(shlib => "PATH/TO/shlibfile", -+ lib => "PATH/TO/libfile", -+ objs => [ "PATH/TO/objectfile", ... ], -+ deps => [ "PATH/TO/otherlibfile", ... ], -+ ordinals => [ "word", "/PATH/TO/ordfile" ]); -+ -+ 'lib' has the intended library file name *without* -+ extension, libobj2shlib is expected to add that. -+ 'shlib' has the corresponding shared library name -+ *without* extension. 'deps' has the list of other -+ libraries (also *without* extension) this library -+ needs to be linked with. 'objs' has the list of -+ object files (also *without* extension) to build -+ this library. 'ordinals' MAY be present, and when -+ it is, its value is an array where the word is -+ "crypto" or "ssl" and the file is one of the ordinal -+ files util/libcrypto.num or util/libssl.num in the -+ source directory. -+ -+ This function has a choice; it can use the -+ corresponding static library as input to make the -+ shared library, or the list of object files. -+ -+ obj2dynlib - function that produces build file lines to build a -+ dynamically loadable library file ("libfoo.so" on -+ Unix) from object files. -+ -+ called like this: -+ -+ obj2dynlib(lib => "PATH/TO/libfile", -+ objs => [ "PATH/TO/objectfile", ... ], -+ deps => [ "PATH/TO/otherlibfile", -+ ... ]); -+ -+ This is almost the same as libobj2shlib, but the -+ intent is to build a shareable library that can be -+ loaded in runtime (a "plugin"...). The differences -+ are subtle, one of the most visible ones is that the -+ resulting shareable library is produced from object -+ files only. -+ -+ obj2bin - function that produces build file lines to build an -+ executable file from object files. -+ -+ called like this: -+ -+ obj2bin(bin => "PATH/TO/binfile", -+ objs => [ "PATH/TO/objectfile", ... ], -+ deps => [ "PATH/TO/libfile", ... ]); -+ -+ 'bin' has the intended executable file name -+ *without* extension, obj2bin is expected to add -+ that. 'objs' has the list of object files (also -+ *without* extension) to build this library. 'deps' -+ has the list of library files (also *without* -+ extension) that the programs needs to be linked -+ with. -+ -+ in2script - function that produces build file lines to build a -+ script file from some input. -+ -+ called like this: -+ -+ in2script(script => "PATH/TO/scriptfile", -+ sources => [ "PATH/TO/infile", ... ]); -+ -+ 'script' has the intended script file name. -+ 'sources' has the list of source files to build the -+ resulting script from. -+ -+Along with the build-file templates is the driving engine -+Configurations/common.tmpl, which looks through all the information in -+%unified_info and generates all the rulesets to build libraries, -+programs and all intermediate files, using the rule generating -+functions defined in the build-file template. -+ -+As an example with the smaller build.info set we've seen as an -+example, producing the rules to build 'libcrypto' would result in the -+following calls: -+ -+ # Note: libobj2shlib will only be called if shared libraries are -+ # to be produced. -+ # Note 2: libobj2shlib gets both the name of the static library -+ # and the names of all the object files that go into it. It's up -+ # to the implementation to decide which to use as input. -+ # Note 3: common.tmpl peals off the ".o" extension from all object -+ # files, as the platform at hand may have a different one. -+ libobj2shlib(shlib => "libcrypto", -+ lib => "libcrypto", -+ objs => [ "crypto/aes", "crypto/evp", "crypto/cversion" ], -+ deps => [ ] -+ ordinals => [ "crypto", "util/libcrypto.num" ]); -+ -+ obj2lib(lib => "libcrypto" -+ objs => [ "crypto/aes", "crypto/evp", "crypto/cversion" ]); -+ -+ src2obj(obj => "crypto/aes" -+ srcs => [ "crypto/aes.c" ], -+ deps => [ ], -+ incs => [ "include" ], -+ intent => "lib"); -+ -+ src2obj(obj => "crypto/evp" -+ srcs => [ "crypto/evp.c" ], -+ deps => [ ], -+ incs => [ "include" ], -+ intent => "lib"); -+ -+ src2obj(obj => "crypto/cversion" -+ srcs => [ "crypto/cversion.c" ], -+ deps => [ "crypto/buildinf.h" ], -+ incs => [ "include" ], -+ intent => "lib"); -+ -+ generatesrc(src => "crypto/buildinf.h", -+ generator => [ "util/mkbuildinf.pl", "\"$(CC)", -+ "$(CFLAGS)\"", "\"$(PLATFORM)\"" ], -+ generator_incs => [ "util" ], -+ generator_deps => [ "util/Foo.pm" ], -+ incs => [ ], -+ deps => [ ], -+ intent => "lib"); -+ -+The returned strings from all those calls are then concatenated -+together and written to the resulting build-file. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/common.tmpl b/CryptoPkg/Library/OpensslLib/openssl/Configurations/common.tmpl -new file mode 100644 -index 0000000..9d7fbf2 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/common.tmpl -@@ -0,0 +1,231 @@ -+{- # -*- Mode: perl -*- -+ -+ use File::Basename; -+ -+ # A cache of objects for which a recipe has already been generated -+ my %cache; -+ -+ # resolvedepends and reducedepends work in tandem to make sure -+ # there are no duplicate dependencies and that they are in the -+ # right order. This is especially used to sort the list of -+ # libraries that a build depends on. -+ sub resolvedepends { -+ my $thing = shift; -+ my @listsofar = @_; # to check if we're looping -+ my @list = @{$unified_info{depends}->{$thing}}; -+ my @newlist = (); -+ if (scalar @list) { -+ foreach my $item (@list) { -+ # It's time to break off when the dependency list starts looping -+ next if grep { $_ eq $item } @listsofar; -+ push @newlist, $item, resolvedepends($item, @listsofar, $item); -+ } -+ } -+ @newlist; -+ } -+ sub reducedepends { -+ my @list = @_; -+ my @newlist = (); -+ while (@list) { -+ my $item = shift @list; -+ push @newlist, $item -+ unless grep { $item eq $_ } @list; -+ } -+ @newlist; -+ } -+ -+ # dogenerate is responsible for producing all the recipes that build -+ # generated source files. It recurses in case a dependency is also a -+ # generated source file. -+ sub dogenerate { -+ my $src = shift; -+ return "" if $cache{$src}; -+ my $obj = shift; -+ my $bin = shift; -+ my %opts = @_; -+ if ($unified_info{generate}->{$src}) { -+ die "$src is generated by Configure, should not appear in build file\n" -+ if ref $unified_info{generate}->{$src} eq ""; -+ my $script = $unified_info{generate}->{$src}->[0]; -+ $OUT .= generatesrc(src => $src, -+ generator => $unified_info{generate}->{$src}, -+ generator_incs => $unified_info{includes}->{$script}, -+ generator_deps => $unified_info{depends}->{$script}, -+ deps => $unified_info{depends}->{$src}, -+ incs => [ @{$unified_info{includes}->{$bin}}, -+ @{$unified_info{includes}->{$obj}} ], -+ %opts); -+ foreach (@{$unified_info{depends}->{$src}}) { -+ dogenerate($_, $obj, $bin, %opts); -+ } -+ } -+ $cache{$src} = 1; -+ } -+ -+ # doobj is responsible for producing all the recipes that build -+ # object files as well as dependency files. -+ sub doobj { -+ my $obj = shift; -+ return "" if $cache{$obj}; -+ (my $obj_no_o = $obj) =~ s|\.o$||; -+ my $bin = shift; -+ my %opts = @_; -+ if (@{$unified_info{sources}->{$obj}}) { -+ $OUT .= src2obj(obj => $obj_no_o, -+ srcs => $unified_info{sources}->{$obj}, -+ deps => $unified_info{depends}->{$obj}, -+ incs => [ @{$unified_info{includes}->{$bin}}, -+ @{$unified_info{includes}->{$obj}} ], -+ %opts); -+ foreach ((@{$unified_info{sources}->{$obj}}, -+ @{$unified_info{depends}->{$obj}})) { -+ dogenerate($_, $obj, $bin, %opts); -+ } -+ } -+ $cache{$obj} = 1; -+ } -+ -+ # dolib is responsible for building libraries. It will call -+ # libobj2shlib is shared libraries are produced, and obj2lib in all -+ # cases. It also makes sure all object files for the library are -+ # built. -+ sub dolib { -+ my $lib = shift; -+ return "" if $cache{$lib}; -+ unless ($disabled{shared}) { -+ my %ordinals = -+ $unified_info{ordinals}->{$lib} -+ ? (ordinals => $unified_info{ordinals}->{$lib}) : (); -+ $OUT .= libobj2shlib(shlib => $unified_info{sharednames}->{$lib}, -+ lib => $lib, -+ objs => [ map { (my $x = $_) =~ s|\.o$||; $x } -+ (@{$unified_info{sources}->{$lib}}, -+ @{$unified_info{shared_sources}->{$lib}}) ], -+ deps => [ reducedepends(resolvedepends($lib)) ], -+ %ordinals); -+ foreach (@{$unified_info{shared_sources}->{$lib}}) { -+ doobj($_, $lib, intent => "lib"); -+ } -+ } -+ $OUT .= obj2lib(lib => $lib, -+ objs => [ map { (my $x = $_) =~ s|\.o$||; $x } -+ @{$unified_info{sources}->{$lib}} ]); -+ foreach (@{$unified_info{sources}->{$lib}}) { -+ doobj($_, $lib, intent => "lib"); -+ } -+ $cache{$lib} = 1; -+ } -+ -+ # doengine is responsible for building engines. It will call -+ # obj2dso, and also makes sure all object files for the library -+ # are built. -+ sub doengine { -+ my $lib = shift; -+ return "" if $cache{$lib}; -+ $OUT .= obj2dso(lib => $lib, -+ objs => [ map { (my $x = $_) =~ s|\.o$||; $x } -+ (@{$unified_info{sources}->{$lib}}, -+ @{$unified_info{shared_sources}->{$lib}}) ], -+ deps => [ resolvedepends($lib) ]); -+ foreach ((@{$unified_info{sources}->{$lib}}, -+ @{$unified_info{shared_sources}->{$lib}})) { -+ doobj($_, $lib, intent => "dso"); -+ } -+ $cache{$lib} = 1; -+ } -+ -+ # dobin is responsible for building programs. It will call obj2bin, -+ # and also makes sure all object files for the library are built. -+ sub dobin { -+ my $bin = shift; -+ return "" if $cache{$bin}; -+ my $deps = [ reducedepends(resolvedepends($bin)) ]; -+ $OUT .= obj2bin(bin => $bin, -+ objs => [ map { (my $x = $_) =~ s|\.o$||; $x } -+ @{$unified_info{sources}->{$bin}} ], -+ deps => $deps); -+ foreach (@{$unified_info{sources}->{$bin}}) { -+ doobj($_, $bin, intent => "bin"); -+ } -+ $cache{$bin} = 1; -+ } -+ -+ # dobin is responsible for building scripts from templates. It will -+ # call in2script. -+ sub doscript { -+ my $script = shift; -+ return "" if $cache{$script}; -+ $OUT .= in2script(script => $script, -+ sources => $unified_info{sources}->{$script}); -+ $cache{$script} = 1; -+ } -+ -+ sub dodir { -+ my $dir = shift; -+ return "" if !exists(&generatedir) or $cache{$dir}; -+ $OUT .= generatedir(dir => $dir, -+ deps => $unified_info{dirinfo}->{$dir}->{deps}, -+ %{$unified_info{dirinfo}->{$_}->{products}}); -+ $cache{$dir} = 1; -+ } -+ -+ # Start with populating the cache with all the overrides -+ %cache = map { $_ => 1 } @{$unified_info{overrides}}; -+ -+ # For convenience collect information regarding directories where -+ # files are generated, those generated files and the end product -+ # they end up in where applicable. Then, add build rules for those -+ # directories -+ if (exists &generatedir) { -+ my %loopinfo = ( "dso" => [ @{$unified_info{engines}} ], -+ "lib" => [ @{$unified_info{libraries}} ], -+ "bin" => [ @{$unified_info{programs}} ], -+ "script" => [ @{$unified_info{scripts}} ] ); -+ foreach my $type (keys %loopinfo) { -+ foreach my $product (@{$loopinfo{$type}}) { -+ my %dirs = (); -+ my $pd = dirname($product); -+ -+ # We already have a "test" target, and the current directory -+ # is just silly to make a target for -+ $dirs{$pd} = 1 unless $pd eq "test" || $pd eq "."; -+ -+ foreach (@{$unified_info{sources}->{$product}}) { -+ my $d = dirname($_); -+ -+ # We don't want to create targets for source directories -+ # when building out of source -+ next if ($config{sourcedir} ne $config{builddir} -+ && $d =~ m|^\Q$config{sourcedir}\E|); -+ # We already have a "test" target, and the current directory -+ # is just silly to make a target for -+ next if $d eq "test" || $d eq "."; -+ -+ $dirs{$d} = 1; -+ push @{$unified_info{dirinfo}->{$d}->{deps}}, $_ -+ if $d ne $pd; -+ } -+ foreach (keys %dirs) { -+ push @{$unified_info{dirinfo}->{$_}->{products}->{$type}}, -+ $product; -+ } -+ } -+ } -+ } -+ -+ # Build mandatory generated headers -+ foreach (@{$unified_info{depends}->{""}}) { dogenerate($_); } -+ -+ # Build all known libraries, engines, programs and scripts. -+ # Everything else will be handled as a consequence. -+ foreach (@{$unified_info{libraries}}) { dolib($_); } -+ foreach (@{$unified_info{engines}}) { doengine($_); } -+ foreach (@{$unified_info{programs}}) { dobin($_); } -+ foreach (@{$unified_info{scripts}}) { doscript($_); } -+ -+ foreach (sort keys %{$unified_info{dirinfo}}) { dodir($_); } -+ -+ # Finally, should there be any applicable BEGINRAW/ENDRAW sections, -+ # they are added here. -+ $OUT .= $_."\n" foreach @{$unified_info{rawlines}}; -+-} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/descrip.mms.tmpl b/CryptoPkg/Library/OpensslLib/openssl/Configurations/descrip.mms.tmpl -new file mode 100644 -index 0000000..da57049 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/descrip.mms.tmpl -@@ -0,0 +1,767 @@ -+## descrip.mms to build OpenSSL on OpenVMS -+## -+## {- join("\n## ", @autowarntext) -} -+{- -+ use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/; -+ -+ # Our prefix, claimed when speaking with the VSI folks Tuesday -+ # January 26th 2016 -+ our $osslprefix = 'OSSL$'; -+ (our $osslprefix_q = $osslprefix) =~ s/\$/\\\$/; -+ -+ our $sover = sprintf "%02d%02d", $config{shlib_major}, $config{shlib_minor}; -+ our $osslver = sprintf "%02d%02d", split(/\./, $config{version}); -+ -+ our $sourcedir = $config{sourcedir}; -+ our $builddir = $config{builddir}; -+ sub sourcefile { -+ catfile($sourcedir, @_); -+ } -+ sub buildfile { -+ catfile($builddir, @_); -+ } -+ sub sourcedir { -+ catdir($sourcedir, @_); -+ } -+ sub builddir { -+ catdir($builddir, @_); -+ } -+ sub tree { -+ (my $x = shift) =~ s|\]$|...]|; -+ $x -+ } -+ sub move { -+ my $f = catdir(@_); -+ my $b = abs2rel(rel2abs("."),rel2abs($f)); -+ $sourcedir = catdir($b,$sourcedir) -+ if !file_name_is_absolute($sourcedir); -+ $builddir = catdir($b,$builddir) -+ if !file_name_is_absolute($builddir); -+ ""; -+ } -+ -+ # Because we need to make two computations of these data, -+ # we store them in arrays for reuse -+ our @shlibs = map { $unified_info{sharednames}->{$_} || () } @{$unified_info{libraries}}; -+ our @install_shlibs = map { $unified_info{sharednames}->{$_} || () } @{$unified_info{install}->{libraries}}; -+ our @generated = ( ( map { (my $x = $_) =~ s|\.S$|\.s|; $x } -+ grep { defined $unified_info{generate}->{$_} } -+ map { @{$unified_info{sources}->{$_}} } -+ grep { /\.o$/ } keys %{$unified_info{sources}} ), -+ ( grep { /\.h$/ } keys %{$unified_info{generate}} ) ); -+ -+ # This is a horrible hack, but is needed because recursive inclusion of files -+ # in different directories does not work well with HP C. -+ my $sd = sourcedir("crypto", "async", "arch"); -+ foreach (grep /\[\.crypto\.async\.arch\].*\.o$/, keys %{$unified_info{sources}}) { -+ (my $x = $_) =~ s|\.o$|.OBJ|; -+ $unified_info{before}->{$x} -+ = qq(arch_include = F\$PARSE("$sd","A.;",,,"SYNTAX_ONLY") - "A.;" -+ define arch 'arch_include'); -+ $unified_info{after}->{$x} -+ = qq(deassign arch); -+ } -+ my $sd1 = sourcedir("ssl","record"); -+ my $sd2 = sourcedir("ssl","statem"); -+ $unified_info{before}->{"[.test]heartbeat_test.OBJ"} -+ = $unified_info{before}->{"[.test]ssltest_old.OBJ"} -+ = qq(record_include = F\$PARSE("$sd1","A.;",,,"SYNTAX_ONLY") - "A.;" -+ define record 'record_include' -+ statem_include = F\$PARSE("$sd2","A.;",,,"SYNTAX_ONLY") - "A.;" -+ define statem 'statem_include'); -+ $unified_info{after}->{"[.test]heartbeat_test.OBJ"} -+ = $unified_info{after}->{"[.test]ssltest.OBJ"} -+ = qq(deassign statem -+ deassign record); -+ foreach (grep /^\[\.ssl\.(?:record|statem)\].*\.o$/, keys %{$unified_info{sources}}) { -+ (my $x = $_) =~ s|\.o$|.OBJ|; -+ $unified_info{before}->{$x} -+ = qq(record_include = F\$PARSE("$sd1","A.;",,,"SYNTAX_ONLY") - "A.;" -+ define record 'record_include' -+ statem_include = F\$PARSE("$sd2","A.;",,,"SYNTAX_ONLY") - "A.;" -+ define statem 'statem_include'); -+ $unified_info{after}->{$x} -+ = qq(deassign statem -+ deassign record); -+ } -+ #use Data::Dumper; -+ #print STDERR "DEBUG: before:\n", Dumper($unified_info{before}); -+ #print STDERR "DEBUG: after:\n", Dumper($unified_info{after}); -+ ""; -+-} -+PLATFORM={- $config{target} -} -+OPTIONS={- $config{options} -} -+CONFIGURE_ARGS=({- join(", ",quotify_l(@{$config{perlargv}})) -}) -+SRCDIR={- $config{sourcedir} -} -+BLDDIR={- $config{builddir} -} -+ -+# Allow both V and VERBOSE to indicate verbosity. This only applies -+# to testing. -+VERBOSE=$(V) -+ -+VERSION={- $config{version} -} -+MAJOR={- $config{major} -} -+MINOR={- $config{minor} -} -+SHLIB_VERSION_NUMBER={- $config{shlib_version_number} -} -+SHLIB_VERSION_HISTORY={- $config{shlib_version_history} -} -+SHLIB_MAJOR={- $config{shlib_major} -} -+SHLIB_MINOR={- $config{shlib_minor} -} -+SHLIB_TARGET={- $target{shared_target} -} -+ -+EXE_EXT=.EXE -+LIB_EXT=.OLB -+SHLIB_EXT=.EXE -+OBJ_EXT=.OBJ -+DEP_EXT=.D -+ -+LIBS={- join(", ", map { "-\n\t".$_.".OLB" } @{$unified_info{libraries}}) -} -+SHLIBS={- join(", ", map { "-\n\t".$_.".EXE" } @shlibs) -} -+ENGINES={- join(", ", map { "-\n\t".$_.".EXE" } @{$unified_info{engines}}) -} -+PROGRAMS={- join(", ", map { "-\n\t".$_.".EXE" } @{$unified_info{programs}}) -} -+SCRIPTS={- join(", ", map { "-\n\t".$_ } @{$unified_info{scripts}}) -} -+{- output_off() if $disabled{makedepend}; "" -} -+DEPS={- our @deps = map { (my $x = $_) =~ s|\.o$|\$(DEP_EXT)|; $x; } -+ grep { $unified_info{sources}->{$_}->[0] =~ /\.c$/ } -+ keys %{$unified_info{sources}}; -+ join(", ", map { "-\n\t".$_ } @deps); -} -+{- output_on() if $disabled{makedepend}; "" -} -+GENERATED_MANDATORY={- join(", ", map { "-\n\t".$_ } @{$unified_info{depends}->{""}} ) -} -+GENERATED={- join(", ", map { "-\n\t".$_ } @generated) -} -+ -+INSTALL_LIBS={- join(", ", map { "-\n\t".$_.".OLB" } @{$unified_info{install}->{libraries}}) -} -+INSTALL_SHLIBS={- join(", ", map { "-\n\t".$_.".EXE" } @install_shlibs) -} -+INSTALL_ENGINES={- join(", ", map { "-\n\t".$_.".EXE" } @{$unified_info{install}->{engines}}) -} -+INSTALL_PROGRAMS={- join(", ", map { "-\n\t".$_.".EXE" } @{$unified_info{install}->{programs}}) -} -+{- output_off() if $disabled{apps}; "" -} -+BIN_SCRIPTS=[.tools]c_rehash.pl -+MISC_SCRIPTS=[.apps]CA.pl, [.apps]tsget.pl -+{- output_on() if $disabled{apps}; "" -} -+ -+# DESTDIR is for package builders so that they can configure for, say, -+# SYS$COMMON:[OPENSSL] and yet have everything installed in STAGING:[USER]. -+# In that case, configure with --prefix=SYS$COMMON:[OPENSSL] and then run -+# MMS with /MACROS=(DESTDIR=STAGING:[USER]). The result will end up in -+# STAGING:[USER.OPENSSL]. -+# Normally it is left empty. -+DESTDIR= -+ -+# Do not edit this manually. Use Configure --prefix=DIR to change this! -+INSTALLTOP={- our $installtop = -+ catdir($config{prefix}) || "SYS\$COMMON:[OPENSSL]"; -+ $installtop -} -+SYSTARTUP={- catdir($installtop, '[.SYS$STARTUP]'); -} -+# This is the standard central area to store certificates, private keys... -+OPENSSLDIR={- catdir($config{openssldir}) or -+ $config{prefix} ? catdir($config{prefix},"COMMON") -+ : "SYS\$COMMON:[OPENSSL-COMMON]" -} -+# The same, but for C -+OPENSSLDIR_C={- $osslprefix -}DATAROOT:[000000] -+# Where installed engines reside, for C -+ENGINESDIR_C={- $osslprefix -}ENGINES{- $sover.$target{pointer_size} -}: -+ -+CC= {- $target{cc} -} -+CFLAGS= /DEFINE=({- join(",", @{$target{defines}}, @{$config{defines}},"OPENSSLDIR=\"\"\"\$(OPENSSLDIR_C)\"\"\"","ENGINESDIR=\"\"\"\$(ENGINESDIR_C)\"\"\"") -}) {- $target{cflags} -} {- $config{cflags} -} -+CFLAGS_Q=$(CFLAGS) -+DEPFLAG= /DEFINE=({- join(",", @{$config{depdefines}}) -}) -+LDFLAGS= {- $target{lflags} -} -+EX_LIBS= {- $target{ex_libs} ? ",".$target{ex_libs} : "" -}{- $config{ex_libs} ? ",".$config{ex_libs} : "" -} -+LIB_CFLAGS={- $target{lib_cflags} || "" -} -+DSO_CFLAGS={- $target{dso_cflags} || "" -} -+BIN_CFLAGS={- $target{bin_cflags} || "" -} -+ -+PERL={- $config{perl} -} -+ -+# We let the C compiler driver to take care of .s files. This is done in -+# order to be excused from maintaining a separate set of architecture -+# dependent assembler flags. E.g. if you throw -mcpu=ultrasparc at SPARC -+# gcc, then the driver will automatically translate it to -xarch=v8plus -+# and pass it down to assembler. -+AS={- $target{as} -} -+ASFLAG={- $target{asflags} -} -+ -+# .FIRST and .LAST are special targets with MMS and MMK. -+# The defines in there are for C. includes that look like -+# this: -+# -+# #include -+# #include "internal/bar.h" -+# -+# will use the logical names to find the files. Expecting -+# DECompHP C to find files in subdirectories of whatever was -+# given with /INCLUDE is a fantasy, unfortunately. -+NODEBUG=@ -+.FIRST : -+ $(NODEBUG) openssl_inc1 = F$PARSE("[.include.openssl]","A.;",,,"syntax_only") - "A.;" -+ $(NODEBUG) openssl_inc2 = F$PARSE("{- catdir($config{sourcedir},"[.include.openssl]") -}","A.;",,,"SYNTAX_ONLY") - "A.;" -+ $(NODEBUG) internal_inc1 = F$PARSE("[.crypto.include.internal]","A.;",,,"SYNTAX_ONLY") - "A.;" -+ $(NODEBUG) internal_inc2 = F$PARSE("{- catdir($config{sourcedir},"[.include.internal]") -}","A.;",,,"SYNTAX_ONLY") - "A.;" -+ $(NODEBUG) internal_inc3 = F$PARSE("{- catdir($config{sourcedir},"[.crypto.include.internal]") -}","A.;",,,"SYNTAX_ONLY") - "A.;" -+ $(NODEBUG) DEFINE openssl 'openssl_inc1','openssl_inc2' -+ $(NODEBUG) DEFINE internal 'internal_inc1','internal_inc2','internal_inc3' -+ $(NODEBUG) staging_dir = "$(DESTDIR)" -+ $(NODEBUG) staging_instdir = "" -+ $(NODEBUG) staging_datadir = "" -+ $(NODEBUG) IF staging_dir .NES. "" THEN - -+ staging_instdir = F$PARSE("A.;",staging_dir,"[]",,"SYNTAX_ONLY") -+ $(NODEBUG) IF staging_instdir - "]A.;" .NES. staging_instdir THEN - -+ staging_instdir = staging_instdir - "]A.;" + ".OPENSSL-INSTALL]" -+ $(NODEBUG) IF staging_instdir - "A.;" .NES. staging_instdir THEN - -+ staging_instdir = staging_instdir - "A.;" + "[OPENSSL-INSTALL]" -+ $(NODEBUG) IF staging_dir .NES. "" THEN - -+ staging_datadir = F$PARSE("A.;",staging_dir,"[]",,"SYNTAX_ONLY") -+ $(NODEBUG) IF staging_datadir - "]A.;" .NES. staging_datadir THEN - -+ staging_datadir = staging_datadir - "]A.;" + ".OPENSSL-COMMON]" -+ $(NODEBUG) IF staging_datadir - "A.;" .NES. staging_datadir THEN - -+ staging_datadir = staging_datadir - "A.;" + "[OPENSSL-COMMON]" -+ $(NODEBUG) ! -+ $(NODEBUG) ! Installation logical names -+ $(NODEBUG) ! -+ $(NODEBUG) installtop = F$PARSE(staging_instdir,"$(INSTALLTOP)","[]A.;",,"SYNTAX_ONLY,NO_CONCEAL") - ".][000000" - "[000000." - "][" - "]A.;" + ".]" -+ $(NODEBUG) datatop = F$PARSE(staging_datadir,"$(OPENSSLDIR)","[]A.;",,"SYNTAX_ONLY,NO_CONCEAL") - ".][000000" - "[000000." - "][" - "]A.;" + ".]" -+ $(NODEBUG) DEFINE ossl_installroot 'installtop' -+ $(NODEBUG) DEFINE ossl_dataroot 'datatop' -+ $(NODEBUG) ! -+ $(NODEBUG) ! Figure out the architecture -+ $(NODEBUG) ! -+ $(NODEBUG) arch = f$edit( f$getsyi( "arch_name"), "upcase") -+ $(NODEBUG) ! -+ $(NODEBUG) ! Set up logical names for the libraries, so LINK and -+ $(NODEBUG) ! running programs can use them. -+ $(NODEBUG) ! -+ $(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEFINE ".uc($_)." 'F\$ENV(\"DEFAULT\")'".uc($_)."\$(SHLIB_EXT)" } map { $unified_info{sharednames}->{$_} || () } @{$unified_info{libraries}}) || "!" -} -+ -+.LAST : -+ $(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEASSIGN ".uc($_) } map { $unified_info{sharednames}->{$_} || () } @{$unified_info{libraries}}) || "!" -} -+ $(NODEBUG) DEASSIGN ossl_dataroot -+ $(NODEBUG) DEASSIGN ossl_installroot -+ $(NODEBUG) DEASSIGN internal -+ $(NODEBUG) DEASSIGN openssl -+.DEFAULT : -+ @ ! MMS cannot handle no actions... -+ -+# The main targets ################################################### -+ -+all : build_generated, - -+ build_libs_nodep, build_engines_nodep, build_programs_nodep, - -+ depend -+ -+build_libs : build_generated, build_libs_nodep, depend -+build_libs_nodep : $(LIBS), $(SHLIBS) -+build_engines : build_generated, build_engines_nodep, depend -+build_engines_nodep : $(ENGINES) -+build_programs : build_generated, build_programs_nodep, depend -+build_programs_nodep : $(PROGRAMS), $(SCRIPTS) -+ -+build_generated : $(GENERATED_MANDATORY) -+ -+# Kept around for backward compatibility -+build_apps build_tests : build_programs -+ -+test tests : build_generated, build_programs_nodep, build_engines_nodep, - -+ depend -+ @ ! {- output_off() if $disabled{tests}; "" -} -+ SET DEFAULT [.test]{- move("test") -} -+ DEFINE SRCTOP {- sourcedir() -} -+ DEFINE BLDTOP {- builddir() -} -+ DEFINE OPENSSL_ENGINES {- builddir("engines") -} -+ DEFINE OPENSSL_DEBUG_MEMORY "on" -+ IF "$(VERBOSE)" .NES. "" THEN DEFINE VERBOSE "$(VERBOSE)" -+ $(PERL) {- sourcefile("test", "run_tests.pl") -} $(TESTS) -+ DEASSIGN OPENSSL_DEBUG_MEMORY -+ DEASSIGN OPENSSL_ENGINES -+ DEASSIGN BLDTOP -+ DEASSIGN SRCTOP -+ SET DEFAULT [-]{- move("..") -} -+ @ ! {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -} -+ @ WRITE SYS$OUTPUT "Tests are not supported with your chosen Configure options" -+ @ ! {- output_on() if !$disabled{tests}; "" -} -+ -+list-tests : -+ @ ! {- output_off() if $disabled{tests}; "" -} -+ @ DEFINE SRCTOP {- sourcedir() -} -+ @ $(PERL) {- sourcefile("test", "run_tests.pl") -} list -+ @ DEASSIGN SRCTOP -+ @ ! {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -} -+ @ WRITE SYS$OUTPUT "Tests are not supported with your chosen Configure options" -+ @ ! {- output_on() if !$disabled{tests}; "" -} -+ -+install : install_sw install_ssldirs install_docs -+ @ WRITE SYS$OUTPUT "" -+ @ WRITE SYS$OUTPUT "######################################################################" -+ @ WRITE SYS$OUTPUT "" -+ @ IF "$(DESTDIR)" .EQS. "" THEN - -+ PIPE ( WRITE SYS$OUTPUT "Installation complete" ; - -+ WRITE SYS$OUTPUT "" ; - -+ WRITE SYS$OUTPUT "Run @$(SYSTARTUP)openssl_startup{- $osslver -} to set up logical names" ; - -+ WRITE SYS$OUTPUT "then run @$(SYSTARTUP)openssl_utils{- $osslver -} to define commands" ; - -+ WRITE SYS$OUTPUT "" ) -+ @ IF "$(DESTDIR)" .NES. "" THEN - -+ PIPE ( WRITE SYS$OUTPUT "Staging installation complete" ; - -+ WRITE SYS$OUTPUT "" ; - -+ WRITE SYS$OUTPUT "Finish or package in such a way that the contents of the directory tree" ; - -+ WRITE SYS$OUTPUT staging_instdir ; - -+ WRITE SYS$OUTPUT "ends up in $(INSTALLTOP)," ; - -+ WRITE SYS$OUTPUT "and that the contents of the contents of the directory tree" ; - -+ WRITE SYS$OUTPUT staging_datadir ; - -+ WRITE SYS$OUTPUT "ends up in $(OPENSSLDIR)" ; - -+ WRITE SYS$OUTPUT "" ; - -+ WRITE SYS$OUTPUT "When in its final destination," ; - -+ WRITE SYS$OUTPUT "Run @$(SYSTARTUP)openssl_startup{- $osslver -} to set up logical names" ; - -+ WRITE SYS$OUTPUT "then run @$(SYSTARTUP)openssl_utils{- $osslver -} to define commands" ; - -+ WRITE SYS$OUTPUT "" ) -+ -+check_install : -+ spawn/nolog @ossl_installroot:[SYSTEST]openssl_ivp{- $osslver -}.com -+ -+uninstall : uninstall_docs uninstall_sw -+ -+# Because VMS wants the generation number (or *) to delete files, we can't -+# use $(LIBS), $(PROGRAMS), $(GENERATED) and $(ENGINES)directly. -+libclean : -+ {- join("\n\t", map { "- DELETE $_.OLB;*" } @{$unified_info{libraries}}) || "@ !" -} -+ {- join("\n\t", map { "- DELETE $_.EXE;*,$_.MAP;*,$_.OPT;*" } @shlibs) || "@ !" -} -+ -+clean : libclean -+ {- join("\n\t", map { "- DELETE $_.EXE;*,$_.OPT;*" } @{$unified_info{programs}}) || "@ !" -} -+ {- join("\n\t", map { "- DELETE $_.EXE;*,$_.OPT;*" } @{$unified_info{engines}}) || "@ !" -} -+ {- join("\n\t", map { "- DELETE $_;*" } @{$unified_info{scripts}}) || "@ !" -} -+ {- join("\n\t", map { "- DELETE $_;*" } @generated) || "@ !" -} -+ - DELETE [...]*.MAP;* -+ - DELETE [...]*.D;* -+ - DELETE [...]*.OBJ;*,*.LIS;* -+ - DELETE []CXX$DEMANGLER_DB.;* -+ - DELETE [.VMS]openssl_startup.com;* -+ - DELETE [.VMS]openssl_shutdown.com;* -+ - DELETE []vmsconfig.pm;* -+ -+distclean : clean -+ - DELETE configdata.pm;* -+ - DELETE descrip.mms;* -+ -+depend : descrip.mms -+descrip.mms : FORCE -+ @ ! {- output_off() if $disabled{makedepend}; "" -} -+ @ $(PERL) -pe "if (/^# DO NOT DELETE.*/) { exit(0); }" - -+ < descrip.mms > descrip.mms-new -+ @ OPEN/APPEND DESCRIP descrip.mms-new -+ @ WRITE DESCRIP "# DO NOT DELETE THIS LINE -- make depend depends on it." -+ {- join("\n\t", map { "\@ IF F\$SEARCH(\"$_\") .NES. \"\" THEN TYPE $_ /OUTPUT=DESCRIP:" } @deps); -} -+ @ CLOSE DESCRIP -+ @ PIPE ( $(PERL) -e "use File::Compare qw/compare_text/; my $x = compare_text(""descrip.mms"",""descrip.mms-new""); exit(0x10000000 + ($x == 0));" || - -+ RENAME descrip.mms-new descrip.mms ) -+ @ IF F$SEARCH("descrip.mms-new") .NES. "" THEN DELETE descrip.mms-new;* -+ -@ SPAWN/OUTPUT=NLA0: PURGE/NOLOG descrip.mms -+ @ ! {- output_on() if $disabled{makedepend}; "" -} -+ -+# Install helper targets ############################################# -+ -+install_sw : all install_shared _install_dev_ns - -+ install_engines _install_runtime_ns - -+ install_startup install_ivp -+ -+uninstall_sw : uninstall_shared _uninstall_dev_ns - -+ uninstall_engines _uninstall_runtime_ns - -+ uninstall_startup uninstall_ivp -+ -+install_docs : install_html_docs -+ -+uninstall_docs : uninstall_html_docs -+ -+install_ssldirs : check_INSTALLTOP -+ - CREATE/DIR/PROT=(S:RWED,O:RWE,G:RE,W:RE) OSSL_DATAROOT:[000000] -+ IF F$SEARCH("OSSL_DATAROOT:[000000]CERTS.DIR;1") .EQS. "" THEN - -+ CREATE/DIR/PROT=(S:RWED,O:RWE,G:RE,W:RE) OSSL_DATAROOT:[CERTS] -+ IF F$SEARCH("OSSL_DATAROOT:[000000]PRIVATE.DIR;1") .EQS. "" THEN - -+ CREATE/DIR/PROT=(S:RWED,O:RWE,G,W) OSSL_DATAROOT:[PRIVATE] -+ IF F$SEARCH("OSSL_DATAROOT:[000000]MISC.DIR;1") .EQS. "" THEN - -+ CREATE/DIR/PROT=(S:RWED,O:RWE,G,W) OSSL_DATAROOT:[MISC] -+ COPY/PROT=W:RE $(MISC_SCRIPTS) OSSL_DATAROOT:[MISC] -+ @ ! Install configuration file -+ COPY/PROT=W:R {- sourcefile("apps", "openssl-vms.cnf") -} - -+ ossl_dataroot:[000000]openssl.cnf-dist -+ IF F$SEARCH("OSSL_DATAROOT:[000000]openssl.cnf") .EQS. "" THEN - -+ COPY/PROT=W:R {- sourcefile("apps", "openssl-vms.cnf") -} - -+ ossl_dataroot:[000000]openssl.cnf -+ -+install_shared : check_INSTALLTOP -+ @ {- output_off() if $disabled{shared}; "" -} ! -+ @ WRITE SYS$OUTPUT "*** Installing shareable images" -+ @ ! Install shared (runtime) libraries -+ - CREATE/DIR ossl_installroot:[LIB.'arch'] -+ {- join("\n ", -+ map { "COPY/PROT=W:R $_.EXE ossl_installroot:[LIB.'arch']" } -+ @install_shlibs) -} -+ @ {- output_on() if $disabled{shared}; "" -} ! -+ -+_install_dev_ns : check_INSTALLTOP -+ @ WRITE SYS$OUTPUT "*** Installing development files" -+ @ ! Install header files -+ - CREATE/DIR ossl_installroot:[include.openssl] -+ COPY/PROT=W:R openssl:*.h ossl_installroot:[include.openssl] -+ @ ! Install static (development) libraries -+ - CREATE/DIR ossl_installroot:[LIB.'arch'] -+ {- join("\n ", -+ map { "COPY/PROT=W:R $_.OLB ossl_installroot:[LIB.'arch']" } -+ @{$unified_info{install}->{libraries}}) -} -+ -+install_dev : install_shared _install_dev_ns -+ -+_install_runtime_ns : check_INSTALLTOP -+ @ ! Install the main program -+ - CREATE/DIR ossl_installroot:[EXE.'arch'] -+ COPY/PROT=W:RE [.APPS]openssl.EXE - -+ ossl_installroot:[EXE.'arch']openssl{- $osslver -}.EXE -+ @ ! Install scripts -+ COPY/PROT=W:RE $(BIN_SCRIPTS) ossl_installroot:[EXE] -+ @ ! {- output_on() if $disabled{apps}; "" -} -+ -+install_runtime : install_shared _install_runtime_ns -+ -+install_engines : check_INSTALLTOP -+ @ {- output_off() unless scalar @{$unified_info{engines}}; "" -} ! -+ @ WRITE SYS$OUTPUT "*** Installing engines" -+ - CREATE/DIR ossl_installroot:[ENGINES{- $sover.$target{pointer_size} -}.'arch'] -+ {- join("\n ", -+ map { "COPY/PROT=W:RE $_.EXE ossl_installroot:[ENGINES$sover$target{pointer_size}.'arch']" } -+ @{$unified_info{install}->{engines}}) -} -+ @ {- output_on() unless scalar @{$unified_info{engines}}; "" -} ! -+ -+install_startup : [.VMS]openssl_startup.com [.VMS]openssl_shutdown.com - -+ [.VMS]openssl_utils.com, check_INSTALLTOP -+ - CREATE/DIR ossl_installroot:[SYS$STARTUP] -+ COPY/PROT=W:RE [.VMS]openssl_startup.com - -+ ossl_installroot:[SYS$STARTUP]openssl_startup{- $osslver -}.com -+ COPY/PROT=W:RE [.VMS]openssl_shutdown.com - -+ ossl_installroot:[SYS$STARTUP]openssl_shutdown{- $osslver -}.com -+ COPY/PROT=W:RE [.VMS]openssl_utils.com - -+ ossl_installroot:[SYS$STARTUP]openssl_utils{- $osslver -}.com -+ -+install_ivp : [.VMS]openssl_ivp.com check_INSTALLTOP -+ - CREATE/DIR ossl_installroot:[SYSTEST] -+ COPY/PROT=W:RE [.VMS]openssl_ivp.com - -+ ossl_installroot:[SYSTEST]openssl_ivp{- $osslver -}.com -+ -+[.VMS]openssl_startup.com : vmsconfig.pm {- sourcefile("VMS", "openssl_startup.com.in") -} -+ - CREATE/DIR [.VMS] -+ $(PERL) "-I." "-Mvmsconfig" {- sourcefile("util", "dofile.pl") -} - -+ {- sourcefile("VMS", "openssl_startup.com.in") -} - -+ > [.VMS]openssl_startup.com -+ -+[.VMS]openssl_utils.com : vmsconfig.pm {- sourcefile("VMS", "openssl_utils.com.in") -} -+ - CREATE/DIR [.VMS] -+ $(PERL) "-I." "-Mvmsconfig" {- sourcefile("util", "dofile.pl") -} - -+ {- sourcefile("VMS", "openssl_utils.com.in") -} - -+ > [.VMS]openssl_utils.com -+ -+[.VMS]openssl_shutdown.com : vmsconfig.pm {- sourcefile("VMS", "openssl_shutdown.com.in") -} -+ - CREATE/DIR [.VMS] -+ $(PERL) "-I." "-Mvmsconfig" {- sourcefile("util", "dofile.pl") -} - -+ {- sourcefile("VMS", "openssl_shutdown.com.in") -} - -+ > [.VMS]openssl_shutdown.com -+ -+[.VMS]openssl_ivp.com : vmsconfig.pm {- sourcefile("VMS", "openssl_ivp.com.in") -} -+ - CREATE/DIR [.VMS] -+ $(PERL) "-I." "-Mvmsconfig" {- sourcefile("util", "dofile.pl") -} - -+ {- sourcefile("VMS", "openssl_ivp.com.in") -} - -+ > [.VMS]openssl_ivp.com -+ -+vmsconfig.pm : configdata.pm -+ OPEN/WRITE/SHARE=READ CONFIG []vmsconfig.pm -+ WRITE CONFIG "package vmsconfig;" -+ WRITE CONFIG "use strict; use warnings;" -+ WRITE CONFIG "use Exporter;" -+ WRITE CONFIG "our @ISA = qw(Exporter);" -+ WRITE CONFIG "our @EXPORT = qw(%config %target %withargs %unified_info %disabled);" -+ WRITE CONFIG "our %config = (" -+ WRITE CONFIG " target => '","{- $config{target} -}","'," -+ WRITE CONFIG " version => '","{- $config{version} -}","'," -+ WRITE CONFIG " shlib_major => '","{- $config{shlib_major} -}","'," -+ WRITE CONFIG " shlib_minor => '","{- $config{shlib_minor} -}","'," -+ WRITE CONFIG " no_shared => '","{- $disabled{shared} -}","'," -+ WRITE CONFIG " INSTALLTOP => '$(INSTALLTOP)'," -+ WRITE CONFIG " OPENSSLDIR => '$(OPENSSLDIR)'," -+ WRITE CONFIG " pointer_size => '","{- $target{pointer_size} -}","'," -+ WRITE CONFIG ");" -+ WRITE CONFIG "our %target = ();" -+ WRITE CONFIG "our %disabled = ();" -+ WRITE CONFIG "our %withargs = ();" -+ WRITE CONFIG "our %unified_info = ();" -+ WRITE CONFIG "1;" -+ CLOSE CONFIG -+ -+install_html_docs : check_INSTALLTOP -+ sourcedir = F$PARSE("{- $sourcedir -}A.;","[]") - "]A.;" + ".DOC]" -+ $(PERL) {- sourcefile("util", "process_docs.pl") -} - -+ --sourcedir='sourcedir' --destdir=ossl_installroot:[HTML] - -+ --type=html -+ -+check_INSTALLTOP : -+ @ IF "$(INSTALLTOP)" .EQS. "" THEN - -+ WRITE SYS$ERROR "INSTALLTOP should not be empty" -+ @ IF "$(INSTALLTOP)" .EQS. "" THEN - -+ EXIT %x10000002 -+ -+# Helper targets ##################################################### -+ -+# Developer targets ################################################## -+ -+debug_logicals : -+ SH LOGICAL/PROC openssl,internal,ossl_installroot,ossl_dataroot -+ -+# Building targets ################################################### -+ -+configdata.pm : $(SRCDIR)Configure $(SRCDIR)config.com {- join(" ", @{$config{build_file_templates}}, @{$config{build_infos}}, @{$config{conf_files}}) -} -+ @ WRITE SYS$OUTPUT "Reconfiguring..." -+ perl $(SRCDIR)Configure reconf -+ @ WRITE SYS$OUTPUT "*************************************************" -+ @ WRITE SYS$OUTPUT "*** ***" -+ @ WRITE SYS$OUTPUT "*** Please run the same mms command again ***" -+ @ WRITE SYS$OUTPUT "*** ***" -+ @ WRITE SYS$OUTPUT "*************************************************" -+ @ PIPE ( EXIT %X10000000 ) -+ -+{- -+ use File::Basename; -+ use File::Spec::Functions qw/abs2rel rel2abs catfile catdir/; -+ -+ sub generatesrc { -+ my %args = @_; -+ my $generator = join(" ", @{$args{generator}}); -+ my $generator_incs = join("", map { ' "-I'.$_.'"' } @{$args{generator_incs}}); -+ my $deps = join(", -\n\t\t", @{$args{generator_deps}}, @{$args{deps}}); -+ -+ if ($args{src} !~ /\.[sS]$/) { -+ if ($args{generator}->[0] =~ m|^.*\.in$|) { -+ my $dofile = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "util", "dofile.pl")), -+ rel2abs($config{builddir})); -+ return <<"EOF"; -+$args{src} : $args{generator}->[0] $deps -+ \$(PERL) "-I\$(BLDDIR)" "-Mconfigdata" $dofile \\ -+ "-o$target{build_file}" $generator > \$@ -+EOF -+ } else { -+ return <<"EOF"; -+$args{src} : $args{generator}->[0] $deps -+ \$(PERL)$generator_incs $generator > \$@ -+EOF -+ } -+ } else { -+ die "No method to generate assembler source present.\n"; -+ } -+ } -+ -+ sub src2obj { -+ my %args = @_; -+ my $obj = $args{obj}; -+ my $deps = join(", -\n\t\t", @{$args{srcs}}, @{$args{deps}}); -+ -+ # Because VMS C isn't very good at combining a /INCLUDE path with -+ # #includes having a relative directory (like '#include "../foo.h"), -+ # the best choice is to move to the first source file's intended -+ # directory before compiling, and make sure to write the object file -+ # in the correct position (important when the object tree is other -+ # than the source tree). -+ my $forward = dirname($args{srcs}->[0]); -+ my $backward = abs2rel(rel2abs("."), rel2abs($forward)); -+ my $objd = abs2rel(rel2abs(dirname($obj)), rel2abs($forward)); -+ my $objn = basename($obj); -+ my $srcs = -+ join(", ", -+ map { abs2rel(rel2abs($_), rel2abs($forward)) } @{$args{srcs}}); -+ my $ecflags = { lib => '$(LIB_CFLAGS)', -+ dso => '$(DSO_CFLAGS)', -+ bin => '$(BIN_CFLAGS)' } -> {$args{intent}}; -+ my $incs_on = "\@ !"; -+ my $incs_off = "\@ !"; -+ my $incs = ""; -+ my @incs = (); -+ push @incs, @{$args{incs}} if @{$args{incs}}; -+ unless ($disabled{zlib}) { -+ # GNV$ZLIB_INCLUDE is the standard logical name for later zlib -+ # incarnations. -+ push @incs, ($withargs{zlib_include} || 'GNV$ZLIB_INCLUDE:'); -+ } -+ if (@incs) { -+ $incs_on = -+ "DEFINE tmp_includes " -+ .join(",-\n\t\t\t", map { -+ file_name_is_absolute($_) -+ ? $_ : catdir($backward,$_) -+ } @incs); -+ $incs_off = "DEASSIGN tmp_includes"; -+ $incs = " /INCLUDE=(tmp_includes:)"; -+ } -+ my $before = $unified_info{before}->{$obj.".OBJ"} || "\@ !"; -+ my $after = $unified_info{after}->{$obj.".OBJ"} || "\@ !"; -+ my $depbuild = $disabled{makedepend} ? "" -+ : " /MMS=(FILE=${objd}${objn}.tmp-D,TARGET=$obj.OBJ)"; -+ -+ return <<"EOF"; -+$obj.OBJ : $deps -+ ${before} -+ SET DEFAULT $forward -+ $incs_on -+ \$(CC) \$(CFLAGS)${ecflags}${incs}${depbuild} /OBJECT=${objd}${objn}.OBJ /REPOSITORY=$backward $srcs -+ $incs_off -+ SET DEFAULT $backward -+ ${after} -+ \@ PIPE ( \$(PERL) -e "use File::Compare qw/compare_text/; my \$x = compare_text(""$obj.D"",""$obj.tmp-D""); exit(0x10000000 + (\$x == 0));" || - -+ RENAME $obj.tmp-D $obj.d ) -+ \@ IF F\$SEARCH("$obj.tmp-D") .NES. "" THEN DELETE $obj.tmp-D;* -+ - PURGE $obj.OBJ -+EOF -+ } -+ sub libobj2shlib { -+ my %args = @_; -+ my $lib = $args{lib}; -+ my $shlib = $args{shlib}; -+ my $libd = dirname($lib); -+ my $libn = basename($lib); -+ (my $mkdef_key = $libn) =~ s/^${osslprefix_q}lib([^0-9]*)\d*/$1/i; -+ my @deps = map { -+ $disabled{shared} ? $_.".OLB" -+ : $unified_info{sharednames}->{$_}.".EXE"; } @{$args{deps}}; -+ my $deps = join(", -\n\t\t", @deps); -+ my $shlib_target = $disabled{shared} ? "" : $target{shared_target}; -+ my $ordinalsfile = defined($args{ordinals}) ? $args{ordinals}->[1] : ""; -+ my $engine_opt = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "VMS", "engine.opt")), -+ rel2abs($config{builddir})); -+ my $mkdef_pl = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "util", "mkdef.pl")), -+ rel2abs($config{builddir})); -+ my $translatesyms_pl = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "VMS", "translatesyms.pl")), -+ rel2abs($config{builddir})); -+ # The "[]" hack is because in .OPT files, each line inherits the -+ # previous line's file spec as default, so if no directory spec -+ # is present in the current line and the previous line has one that -+ # doesn't apply, you're in for a surprise. -+ my $write_opt = -+ join("\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_; -+ $x =~ s|(\.EXE)|$1/SHARE|; -+ $x =~ s|(\.OLB)|$1/LIB|; -+ "WRITE OPT_FILE \"$x\"" } @deps) -+ || "\@ !"; -+ return <<"EOF"; -+$shlib.EXE : $lib.OLB $deps $ordinalsfile -+ \$(PERL) $mkdef_pl "$mkdef_key" "VMS" > $shlib.SYMVEC-tmp -+ \$(PERL) $translatesyms_pl \$(BLDDIR)CXX\$DEMANGLER_DB. < $shlib.SYMVEC-tmp > $shlib.SYMVEC -+ DELETE $shlib.SYMVEC-tmp;* -+ OPEN/WRITE/SHARE=READ OPT_FILE $shlib.OPT -+ WRITE OPT_FILE "IDENTIFICATION=""V$config{version}""" -+ TYPE $shlib.SYMVEC /OUTPUT=OPT_FILE: -+ WRITE OPT_FILE "$lib.OLB/LIBRARY" -+ $write_opt -+ CLOSE OPT_FILE -+ LINK /MAP=$shlib.MAP /FULL/SHARE=$shlib.EXE $shlib.OPT/OPT \$(EX_LIBS) -+ DELETE $shlib.SYMVEC;* -+ PURGE $shlib.EXE,$shlib.OPT,$shlib.MAP -+EOF -+ } -+ sub obj2dso { -+ my %args = @_; -+ my $lib = $args{lib}; -+ my $libd = dirname($lib); -+ my $libn = basename($lib); -+ (my $libn_nolib = $libn) =~ s/^lib//; -+ my @objs = map { "$_.OBJ" } @{$args{objs}}; -+ my @deps = map { -+ $disabled{shared} ? $_.".OLB" -+ : $unified_info{sharednames}->{$_}.".EXE"; } @{$args{deps}}; -+ my $deps = join(", -\n\t\t", @objs, @deps); -+ my $shlib_target = $disabled{shared} ? "" : $target{shared_target}; -+ my $engine_opt = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "VMS", "engine.opt")), -+ rel2abs($config{builddir})); -+ # The "[]" hack is because in .OPT files, each line inherits the -+ # previous line's file spec as default, so if no directory spec -+ # is present in the current line and the previous line has one that -+ # doesn't apply, you're in for a surprise. -+ my $write_opt1 = -+ join(",-\"\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_; -+ "WRITE OPT_FILE \"$x" } @objs). -+ "\""; -+ my $write_opt2 = -+ join("\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_; -+ $x =~ s|(\.EXE)|$1/SHARE|; -+ $x =~ s|(\.OLB)|$1/LIB|; -+ "WRITE OPT_FILE \"$x\"" } @deps) -+ || "\@ !"; -+ return <<"EOF"; -+$lib.EXE : $deps -+ OPEN/WRITE/SHARE=READ OPT_FILE $lib.OPT -+ TYPE $engine_opt /OUTPUT=OPT_FILE: -+ $write_opt1 -+ $write_opt2 -+ CLOSE OPT_FILE -+ LINK /MAP=$lib.MAP /FULL/SHARE=$lib.EXE $lib.OPT/OPT \$(EX_LIBS) -+ - PURGE $lib.EXE,$lib.OPT,$lib.MAP -+EOF -+ } -+ sub obj2lib { -+ my %args = @_; -+ my $lib = $args{lib}; -+ my $objs = join(", -\n\t\t", map { $_.".OBJ" } (@{$args{objs}})); -+ my $fill_lib = join("\n\t", (map { "LIBRARY/REPLACE $lib.OLB $_.OBJ" } -+ @{$args{objs}})); -+ return <<"EOF"; -+$lib.OLB : $objs -+ LIBRARY/CREATE/OBJECT $lib.OLB -+ $fill_lib -+ - PURGE $lib.OLB -+EOF -+ } -+ sub obj2bin { -+ my %args = @_; -+ my $bin = $args{bin}; -+ my $bind = dirname($bin); -+ my $binn = basename($bin); -+ my @objs = map { "$_.OBJ" } @{$args{objs}}; -+ my @deps = map { -+ $disabled{shared} ? $_.".OLB" -+ : $unified_info{sharednames}->{$_}.".EXE"; } @{$args{deps}}; -+ my $deps = join(", -\n\t\t", @objs, @deps); -+ # The "[]" hack is because in .OPT files, each line inherits the -+ # previous line's file spec as default, so if no directory spec -+ # is present in the current line and the previous line has one that -+ # doesn't apply, you're in for a surprise. -+ my $write_opt1 = -+ join(",-\"\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_; -+ "WRITE OPT_FILE \"$x" } @objs). -+ "\""; -+ my $write_opt2 = -+ join("\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_; -+ $x =~ s|(\.EXE)|$1/SHARE|; -+ $x =~ s|(\.OLB)|$1/LIB|; -+ "WRITE OPT_FILE \"$x\"" } @deps) -+ || "\@ !"; -+ return <<"EOF"; -+$bin.EXE : $deps -+ OPEN/WRITE/SHARE=READ OPT_FILE $bin.OPT -+ $write_opt1 -+ $write_opt2 -+ CLOSE OPT_FILE -+ LINK/EXEC=$bin.EXE \$(LDFLAGS) $bin.OPT/OPT \$(EX_LIBS) -+ - PURGE $bin.EXE,$bin.OPT -+EOF -+ } -+ sub in2script { -+ my %args = @_; -+ my $script = $args{script}; -+ return "" if grep { $_ eq $script } @{$args{sources}}; # No overwrite! -+ my $sources = join(" ", @{$args{sources}}); -+ my $dofile = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "util", "dofile.pl")), -+ rel2abs($config{builddir})); -+ return <<"EOF"; -+$script : $sources -+ \$(PERL) "-I\$(BLDDIR)" "-Mconfigdata" $dofile - -+ "-o$target{build_file}" $sources > $script -+ SET FILE/PROT=(S:RWED,O:RWED,G:RE,W:RE) $script -+ PURGE $script -+EOF -+ } -+ "" # Important! This becomes part of the template result. -+-} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/unix-Makefile.tmpl b/CryptoPkg/Library/OpensslLib/openssl/Configurations/unix-Makefile.tmpl -new file mode 100644 -index 0000000..c029817 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/unix-Makefile.tmpl -@@ -0,0 +1,1124 @@ -+## -+## Makefile for OpenSSL -+## -+## {- join("\n## ", @autowarntext) -} -+{- -+ our $objext = $target{obj_extension} || ".o"; -+ our $depext = $target{dep_extension} || ".d"; -+ our $exeext = $target{exe_extension} || ""; -+ our $libext = $target{lib_extension} || ".a"; -+ our $shlibext = $target{shared_extension} || ".so"; -+ our $shlibextsimple = $target{shared_extension_simple} || ".so"; -+ our $shlibextimport = $target{shared_import_extension} || ""; -+ our $dsoext = $target{dso_extension} || ".so"; -+ -+ sub windowsdll { $config{target} =~ /^(?:Cygwin|mingw)/ } -+ -+ our $sover = $config{target} =~ /^mingw/ -+ ? $config{shlib_major}."_".$config{shlib_minor} -+ : $config{shlib_major}.".".$config{shlib_minor}; -+ -+ # shlib and shlib_simple both take a static library name and figure -+ # out what the shlib name should be. -+ # -+ # When OpenSSL is configured "no-shared", these functions will just -+ # return empty lists, making them suitable to join(). -+ # -+ # With Windows DLL producers, shlib($libname) will return the shared -+ # library name (which usually is different from the static library -+ # name) with the default shared extension appended to it, while -+ # shlib_simple($libname) will return the static library name with -+ # the shared extension followed by ".a" appended to it. The former -+ # result is used as the runtime shared library while the latter is -+ # used as the DLL import library. -+ # -+ # On all Unix systems, shlib($libname) will return the library name -+ # with the default shared extension, while shlib_simple($libname) -+ # will return the name from shlib($libname) with any SO version number -+ # removed. On some systems, they may therefore return the exact same -+ # string. -+ sub shlib { -+ return () if $disabled{shared}; -+ my $lib = shift; -+ return $unified_info{sharednames}->{$lib} . $shlibext; -+ } -+ sub shlib_simple { -+ return () if $disabled{shared}; -+ -+ my $lib = shift; -+ if (windowsdll()) { -+ return $lib . $shlibextimport; -+ } -+ return $lib . $shlibextsimple; -+ } -+ -+ # dso is a complement to shlib / shlib_simple that returns the -+ # given libname with the simple shared extension (possible SO version -+ # removed). This differs from shlib_simple() by being unconditional. -+ sub dso { -+ my $engine = shift; -+ -+ return $engine . $dsoext; -+ } -+ # This makes sure things get built in the order they need -+ # to. You're welcome. -+ sub dependmagic { -+ my $target = shift; -+ -+ return "$target: build_generated\n\t\$(MAKE) depend && \$(MAKE) _$target\n_$target"; -+ } -+ ''; -+-} -+PLATFORM={- $config{target} -} -+OPTIONS={- $config{options} -} -+CONFIGURE_ARGS=({- join(", ",quotify_l(@{$config{perlargv}})) -}) -+SRCDIR={- $config{sourcedir} -} -+BLDDIR={- $config{builddir} -} -+ -+VERSION={- $config{version} -} -+MAJOR={- $config{major} -} -+MINOR={- $config{minor} -} -+SHLIB_VERSION_NUMBER={- $config{shlib_version_number} -} -+SHLIB_VERSION_HISTORY={- $config{shlib_version_history} -} -+SHLIB_MAJOR={- $config{shlib_major} -} -+SHLIB_MINOR={- $config{shlib_minor} -} -+SHLIB_TARGET={- $target{shared_target} -} -+ -+LIBS={- join(" ", map { $_.$libext } @{$unified_info{libraries}}) -} -+SHLIBS={- join(" ", map { shlib($_) } @{$unified_info{libraries}}) -} -+SHLIB_INFO={- join(" ", map { "\"".shlib($_).";".shlib_simple($_)."\"" } @{$unified_info{libraries}}) -} -+ENGINES={- join(" ", map { dso($_) } @{$unified_info{engines}}) -} -+PROGRAMS={- join(" ", map { $_.$exeext } @{$unified_info{programs}}) -} -+SCRIPTS={- join(" ", @{$unified_info{scripts}}) -} -+{- output_off() if $disabled{makedepend}; "" -} -+DEPS={- join(" ", map { (my $x = $_) =~ s|\.o$|$depext|; $x; } -+ grep { $unified_info{sources}->{$_}->[0] =~ /\.c$/ } -+ keys %{$unified_info{sources}}); -} -+{- output_on() if $disabled{makedepend}; "" -} -+GENERATED_MANDATORY={- join(" ", @{$unified_info{depends}->{""}} ) -} -+GENERATED={- join(" ", -+ ( map { (my $x = $_) =~ s|\.S$|\.s|; $x } -+ grep { defined $unified_info{generate}->{$_} } -+ map { @{$unified_info{sources}->{$_}} } -+ grep { /\.o$/ } keys %{$unified_info{sources}} ), -+ ( grep { /\.h$/ } keys %{$unified_info{generate}} )) -} -+ -+INSTALL_LIBS={- join(" ", map { $_.$libext } @{$unified_info{install}->{libraries}}) -} -+INSTALL_SHLIBS={- join(" ", map { shlib($_) } @{$unified_info{install}->{libraries}}) -} -+INSTALL_SHLIB_INFO={- join(" ", map { "\"".shlib($_).";".shlib_simple($_)."\"" } @{$unified_info{install}->{libraries}}) -} -+INSTALL_ENGINES={- join(" ", map { dso($_) } @{$unified_info{install}->{engines}}) -} -+INSTALL_PROGRAMS={- join(" ", map { $_.$exeext } @{$unified_info{install}->{programs}}) -} -+{- output_off() if $disabled{apps}; "" -} -+BIN_SCRIPTS=$(BLDDIR)/tools/c_rehash -+MISC_SCRIPTS=$(BLDDIR)/apps/CA.pl $(BLDDIR)/apps/tsget -+{- output_on() if $disabled{apps}; "" -} -+ -+# DESTDIR is for package builders so that they can configure for, say, -+# /usr/ and yet have everything installed to /tmp/somedir/usr/. -+# Normally it is left empty. -+DESTDIR= -+ -+# Do not edit these manually. Use Configure with --prefix or --openssldir -+# to change this! Short explanation in the top comment in Configure -+INSTALLTOP={- # $prefix is used in the OPENSSLDIR perl snippet -+ # -+ our $prefix = $config{prefix} || "/usr/local"; -+ $prefix -} -+OPENSSLDIR={- # -+ # The logic here is that if no --openssldir was given, -+ # OPENSSLDIR will get the value from $prefix plus "/ssl". -+ # If --openssldir was given and the value is an absolute -+ # path, OPENSSLDIR will get its value without change. -+ # If the value from --openssldir is a relative path, -+ # OPENSSLDIR will get $prefix with the --openssldir -+ # value appended as a subdirectory. -+ # -+ use File::Spec::Functions; -+ our $openssldir = -+ $config{openssldir} ? -+ (file_name_is_absolute($config{openssldir}) ? -+ $config{openssldir} -+ : catdir($prefix, $config{openssldir})) -+ : catdir($prefix, "ssl"); -+ $openssldir -} -+LIBDIR={- # -+ # if $prefix/lib$target{multilib} is not an existing -+ # directory, then assume that it's not searched by linker -+ # automatically, in which case adding $target{multilib} suffix -+ # causes more grief than we're ready to tolerate, so don't... -+ our $multilib = -+ -d "$prefix/lib$target{multilib}" ? $target{multilib} : ""; -+ our $libdir = $config{libdir} || "lib$multilib"; -+ $libdir -} -+ENGINESDIR={- use File::Spec::Functions; -+ catdir($prefix,$libdir,"engines-$sover") -} -+ -+# Convenience variable for those who want to set the rpath in shared -+# libraries and applications -+LIBRPATH=$(INSTALLTOP)/$(LIBDIR) -+ -+MANDIR=$(INSTALLTOP)/share/man -+DOCDIR=$(INSTALLTOP)/share/doc/$(BASENAME) -+HTMLDIR=$(DOCDIR)/html -+ -+# MANSUFFIX is for the benefit of anyone who may want to have a suffix -+# appended after the manpage file section number. "ssl" is popular, -+# resulting in files such as config.5ssl rather than config.5. -+MANSUFFIX= -+HTMLSUFFIX=html -+ -+ -+ -+CROSS_COMPILE= {- $config{cross_compile_prefix} -} -+CC= $(CROSS_COMPILE){- $target{cc} -} -+CFLAGS={- our $cflags2 = join(" ",(map { "-D".$_} @{$target{defines}}, @{$config{defines}}),"-DOPENSSLDIR=\"\\\"\$(OPENSSLDIR)\\\"\"","-DENGINESDIR=\"\\\"\$(ENGINESDIR)\\\"\"") -} {- $target{cflags} -} {- $config{cflags} -} -+CFLAGS_Q={- $cflags2 =~ s|([\\"])|\\$1|g; $cflags2 -} {- $config{cflags} -} -+LDFLAGS= {- $target{lflags} -} -+PLIB_LDFLAGS= {- $target{plib_lflags} -} -+EX_LIBS= {- $target{ex_libs} -} {- $config{ex_libs} -} -+LIB_CFLAGS={- $target{shared_cflag} || "" -} -+LIB_LDFLAGS={- $target{shared_ldflag}." ".$config{shared_ldflag} -} -+DSO_CFLAGS={- $target{shared_cflag} || "" -} -+DSO_LDFLAGS=$(LIB_LDFLAGS) -+BIN_CFLAGS={- $target{bin_cflags} -} -+ -+PERL={- $config{perl} -} -+ -+ARFLAGS= {- $target{arflags} -} -+AR=$(CROSS_COMPILE){- $target{ar} || "ar" -} $(ARFLAGS) r -+RANLIB= {- $target{ranlib} -} -+NM= $(CROSS_COMPILE){- $target{nm} || "nm" -} -+RCFLAGS={- $target{shared_rcflag} -} -+RC= $(CROSS_COMPILE){- $target{rc} || "windres" -} -+RM= rm -f -+RMDIR= rmdir -+TAR= {- $target{tar} || "tar" -} -+TARFLAGS= {- $target{tarflags} -} -+MAKEDEPEND={- $config{makedepprog} -} -+ -+BASENAME= openssl -+NAME= $(BASENAME)-$(VERSION) -+TARFILE= ../$(NAME).tar -+ -+# We let the C compiler driver to take care of .s files. This is done in -+# order to be excused from maintaining a separate set of architecture -+# dependent assembler flags. E.g. if you throw -mcpu=ultrasparc at SPARC -+# gcc, then the driver will automatically translate it to -xarch=v8plus -+# and pass it down to assembler. -+AS=$(CC) -c -+ASFLAG=$(CFLAGS) -+PERLASM_SCHEME= {- $target{perlasm_scheme} -} -+ -+# For x86 assembler: Set PROCESSOR to 386 if you want to support -+# the 80386. -+PROCESSOR= {- $config{processor} -} -+ -+# We want error [and other] messages in English. Trouble is that make(1) -+# doesn't pass macros down as environment variables unless there already -+# was corresponding variable originally set. In other words we can only -+# reassign environment variables, but not set new ones, not in portable -+# manner that is. That's why we reassign several, just to be sure... -+LC_ALL=C -+LC_MESSAGES=C -+LANG=C -+ -+# The main targets ################################################### -+ -+{- dependmagic('all'); -}: build_libs_nodep build_engines_nodep build_programs_nodep link-utils -+{- dependmagic('build_libs'); -}: build_libs_nodep -+{- dependmagic('build_engines'); -}: build_engines_nodep -+{- dependmagic('build_programs'); -}: build_programs_nodep -+ -+build_generated: $(GENERATED_MANDATORY) -+build_libs_nodep: libcrypto.pc libssl.pc openssl.pc -+build_engines_nodep: $(ENGINES) -+build_programs_nodep: $(PROGRAMS) $(SCRIPTS) -+ -+# Kept around for backward compatibility -+build_apps build_tests: build_programs -+ -+test: tests -+{- dependmagic('tests'); -}: build_programs_nodep build_engines_nodep link-utils -+ @ : {- output_off() if $disabled{tests}; "" -} -+ ( cd test; \ -+ SRCTOP=../$(SRCDIR) \ -+ BLDTOP=../$(BLDDIR) \ -+ PERL="$(PERL)" \ -+ EXE_EXT={- $exeext -} \ -+ OPENSSL_ENGINES=../$(BLDDIR)/engines \ -+ OPENSSL_DEBUG_MEMORY=on \ -+ $(PERL) ../$(SRCDIR)/test/run_tests.pl $(TESTS) ) -+ @ : {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -} -+ @echo "Tests are not supported with your chosen Configure options" -+ @ : {- output_on() if !$disabled{tests}; "" -} -+ -+list-tests: -+ @ : {- output_off() if $disabled{tests}; "" -} -+ @SRCTOP="$(SRCDIR)" \ -+ $(PERL) $(SRCDIR)/test/run_tests.pl list -+ @ : {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -} -+ @echo "Tests are not supported with your chosen Configure options" -+ @ : {- output_on() if !$disabled{tests}; "" -} -+ -+install: install_sw install_ssldirs install_docs -+ -+uninstall: uninstall_docs uninstall_sw -+ -+libclean: -+ @set -e; for s in $(SHLIB_INFO); do \ -+ s1=`echo "$$s" | cut -f1 -d";"`; \ -+ s2=`echo "$$s" | cut -f2 -d";"`; \ -+ echo $(RM) $$s1; \ -+ $(RM) $$s1; \ -+ if [ "$$s1" != "$$s2" ]; then \ -+ echo $(RM) $$s2; \ -+ $(RM) $$s2; \ -+ fi; \ -+ done -+ $(RM) $(LIBS) -+ $(RM) *.map -+ -+clean: libclean -+ $(RM) $(PROGRAMS) $(TESTPROGS) $(ENGINES) $(SCRIPTS) -+ $(RM) $(GENERATED) -+ -$(RM) `find . -name '*{- $depext -}' -a \! -path "./.git/*"` -+ -$(RM) `find . -name '*{- $objext -}' -a \! -path "./.git/*"` -+ $(RM) core -+ $(RM) tags TAGS -+ $(RM) test/.rnd -+ $(RM) openssl.pc libcrypto.pc libssl.pc -+ -$(RM) `find . -type l -a \! -path "./.git/*"` -+ $(RM) $(TARFILE) -+ -+distclean: clean -+ $(RM) configdata.pm -+ $(RM) Makefile -+ -+# We check if any depfile is newer than Makefile and decide to -+# concatenate only if that is true. -+depend: -+ @: {- output_off() if $disabled{makedepend}; "" -} -+ @if egrep "^# DO NOT DELETE THIS LINE" Makefile >/dev/null && [ -z "`find $(DEPS) -newer Makefile 2>/dev/null; exit 0`" ]; then :; else \ -+ ( $(PERL) -pe 'exit 0 if /^# DO NOT DELETE THIS LINE.*/' < Makefile; \ -+ echo '# DO NOT DELETE THIS LINE -- make depend depends on it.'; \ -+ echo; \ -+ for f in $(DEPS); do \ -+ if [ -f $$f ]; then cat $$f; fi; \ -+ done ) > Makefile.new; \ -+ if cmp Makefile.new Makefile >/dev/null 2>&1; then \ -+ rm -f Makefile.new; \ -+ else \ -+ mv -f Makefile.new Makefile; \ -+ fi; \ -+ fi -+ @: {- output_on() if $disabled{makedepend}; "" -} -+ -+# Install helper targets ############################################# -+ -+install_sw: all install_dev install_engines install_runtime -+ -+uninstall_sw: uninstall_runtime uninstall_engines uninstall_dev -+ -+install_docs: install_man_docs install_html_docs -+ -+uninstall_docs: uninstall_man_docs uninstall_html_docs -+ $(RM) -r -v $(DESTDIR)$(DOCDIR) -+ -+install_ssldirs: -+ @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(OPENSSLDIR)/certs -+ @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(OPENSSLDIR)/private -+ @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(OPENSSLDIR)/misc -+ @set -e; for x in dummy $(MISC_SCRIPTS); do \ -+ if [ "$$x" = "dummy" ]; then continue; fi; \ -+ fn=`basename $$x`; \ -+ echo "install $$x -> $(DESTDIR)$(OPENSSLDIR)/misc/$$fn"; \ -+ cp $$x $(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new; \ -+ chmod 755 $(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new; \ -+ mv -f $(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new \ -+ $(DESTDIR)$(OPENSSLDIR)/misc/$$fn; \ -+ done -+ @echo "install $(SRCDIR)/apps/openssl.cnf -> $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.dist" -+ @cp $(SRCDIR)/apps/openssl.cnf $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new -+ @chmod 644 $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new -+ @mv -f $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.dist -+ @if ! [ -f "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf" ]; then \ -+ echo "install $(SRCDIR)/apps/openssl.cnf -> $(DESTDIR)$(OPENSSLDIR)/openssl.cnf"; \ -+ cp $(SRCDIR)/apps/openssl.cnf $(DESTDIR)$(OPENSSLDIR)/openssl.cnf; \ -+ chmod 644 $(DESTDIR)$(OPENSSLDIR)/openssl.cnf; \ -+ fi -+ -+install_dev: -+ @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) -+ @echo "*** Installing development files" -+ @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/include/openssl -+ @ : {- output_off() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$target{defines}}; "" -} -+ @echo "install $(SRCDIR)/ms/applink.c -> $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c" -+ @cp $(SRCDIR)/ms/applink.c $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c -+ @chmod 644 $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c -+ @ : {- output_on() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$target{defines}}; "" -} -+ @set -e; for i in $(SRCDIR)/include/openssl/*.h \ -+ $(BLDDIR)/include/openssl/*.h; do \ -+ fn=`basename $$i`; \ -+ echo "install $$i -> $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn"; \ -+ cp $$i $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn; \ -+ chmod 644 $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn; \ -+ done -+ @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/$(LIBDIR) -+ @set -e; for l in $(INSTALL_LIBS); do \ -+ fn=`basename $$l`; \ -+ echo "install $$l -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn"; \ -+ cp $$l $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new; \ -+ $(RANLIB) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new; \ -+ chmod 644 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new; \ -+ mv -f $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new \ -+ $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn; \ -+ done -+ @ : {- output_off() if $disabled{shared}; "" -} -+ @set -e; for s in $(INSTALL_SHLIB_INFO); do \ -+ s1=`echo "$$s" | cut -f1 -d";"`; \ -+ s2=`echo "$$s" | cut -f2 -d";"`; \ -+ fn1=`basename $$s1`; \ -+ fn2=`basename $$s2`; \ -+ : {- output_off() if windowsdll(); "" -}; \ -+ echo "install $$s1 -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn1"; \ -+ cp $$s1 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn1.new; \ -+ chmod 755 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn1.new; \ -+ mv -f $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn1.new \ -+ $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn1; \ -+ if [ "$$fn1" != "$$fn2" ]; then \ -+ echo "link $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2 -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn1"; \ -+ ln -sf $$fn1 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2; \ -+ fi; \ -+ : {- output_on() if windowsdll(); "" -}{- output_off() unless windowsdll(); "" -}; \ -+ echo "install $$s2 -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2"; \ -+ cp $$s2 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2.new; \ -+ chmod 755 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2.new; \ -+ mv -f $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2.new \ -+ $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2; \ -+ : {- output_on() unless windowsdll(); "" -}; \ -+ done -+ @ : {- output_on() if $disabled{shared}; "" -} -+ @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig -+ @echo "install libcrypto.pc -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc" -+ @cp libcrypto.pc $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig -+ @chmod 644 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc -+ @echo "install libssl.pc -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc" -+ @cp libssl.pc $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig -+ @chmod 644 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc -+ @echo "install openssl.pc -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc" -+ @cp openssl.pc $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig -+ @chmod 644 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc -+ -+uninstall_dev: -+ @echo "*** Uninstalling development files" -+ @ : {- output_off() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$target{defines}}; "" -} -+ @echo "$(RM) $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c" -+ @$(RM) $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c -+ @ : {- output_on() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$target{defines}}; "" -} -+ @set -e; for i in $(SRCDIR)/include/openssl/*.h \ -+ $(BLDDIR)/include/openssl/*.h; do \ -+ fn=`basename $$i`; \ -+ echo "$(RM) $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn"; \ -+ $(RM) $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn; \ -+ done -+ -$(RMDIR) $(DESTDIR)$(INSTALLTOP)/include/openssl -+ -$(RMDIR) $(DESTDIR)$(INSTALLTOP)/include -+ @set -e; for l in $(INSTALL_LIBS); do \ -+ fn=`basename $$l`; \ -+ echo "$(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn"; \ -+ $(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn; \ -+ done -+ @ : {- output_off() if $disabled{shared}; "" -} -+ @set -e; for s in $(INSTALL_SHLIB_INFO); do \ -+ s1=`echo "$$s" | cut -f1 -d";"`; \ -+ s2=`echo "$$s" | cut -f2 -d";"`; \ -+ fn1=`basename $$s1`; \ -+ fn2=`basename $$s2`; \ -+ : {- output_off() if windowsdll(); "" -}; \ -+ echo "$(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn1"; \ -+ $(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn1; \ -+ if [ "$$fn1" != "$$fn2" ]; then \ -+ echo "$(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2"; \ -+ $(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2; \ -+ fi; \ -+ : {- output_on() if windowsdll(); "" -}{- output_off() unless windowsdll(); "" -}; \ -+ echo "$(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2"; \ -+ $(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn2; \ -+ : {- output_on() unless windowsdll(); "" -}; \ -+ done -+ @ : {- output_on() if $disabled{shared}; "" -} -+ $(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc -+ $(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc -+ $(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc -+ -$(RMDIR) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig -+ -$(RMDIR) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR) -+ -+install_engines: -+ @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) -+ @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(ENGINESDIR)/ -+ @echo "*** Installing engines" -+ @set -e; for e in dummy $(INSTALL_ENGINES); do \ -+ if [ "$$e" = "dummy" ]; then continue; fi; \ -+ fn=`basename $$e`; \ -+ echo "install $$e -> $(DESTDIR)$(ENGINESDIR)/$$fn"; \ -+ cp $$e $(DESTDIR)$(ENGINESDIR)/$$fn.new; \ -+ chmod 755 $(DESTDIR)$(ENGINESDIR)/$$fn.new; \ -+ mv -f $(DESTDIR)$(ENGINESDIR)/$$fn.new \ -+ $(DESTDIR)$(ENGINESDIR)/$$fn; \ -+ done -+ -+uninstall_engines: -+ @echo "*** Uninstalling engines" -+ @set -e; for e in dummy $(INSTALL_ENGINES); do \ -+ if [ "$$e" = "dummy" ]; then continue; fi; \ -+ fn=`basename $$e`; \ -+ if [ "$$fn" = '{- dso("ossltest") -}' ]; then \ -+ continue; \ -+ fi; \ -+ echo "$(RM) $(DESTDIR)$(ENGINESDIR)/$$fn"; \ -+ $(RM) $(DESTDIR)$(ENGINESDIR)/$$fn; \ -+ done -+ -$(RMDIR) $(DESTDIR)$(ENGINESDIR) -+ -+install_runtime: -+ @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) -+ @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/bin -+ @ : {- output_off() if windowsdll(); "" -} -+ @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/$(LIBDIR) -+ @ : {- output_on() if windowsdll(); "" -} -+ @echo "*** Installing runtime files" -+ @set -e; for s in dummy $(INSTALL_SHLIBS); do \ -+ if [ "$$s" = "dummy" ]; then continue; fi; \ -+ fn=`basename $$s`; \ -+ : {- output_off() unless windowsdll(); "" -}; \ -+ echo "install $$s -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \ -+ cp $$s $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \ -+ chmod 644 $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \ -+ mv -f $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new \ -+ $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \ -+ : {- output_on() unless windowsdll(); "" -}{- output_off() if windowsdll(); "" -}; \ -+ echo "install $$s -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn"; \ -+ cp $$s $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new; \ -+ chmod 755 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new; \ -+ mv -f $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new \ -+ $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn; \ -+ : {- output_on() if windowsdll(); "" -}; \ -+ done -+ @set -e; for x in dummy $(INSTALL_PROGRAMS); do \ -+ if [ "$$x" = "dummy" ]; then continue; fi; \ -+ fn=`basename $$x`; \ -+ echo "install $$x -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \ -+ cp $$x $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \ -+ chmod 755 $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \ -+ mv -f $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new \ -+ $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \ -+ done -+ @set -e; for x in dummy $(BIN_SCRIPTS); do \ -+ if [ "$$x" = "dummy" ]; then continue; fi; \ -+ fn=`basename $$x`; \ -+ echo "install $$x -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \ -+ cp $$x $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \ -+ chmod 755 $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \ -+ mv -f $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new \ -+ $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \ -+ done -+ -+uninstall_runtime: -+ @echo "*** Uninstalling runtime files" -+ @set -e; for x in dummy $(INSTALL_PROGRAMS); \ -+ do \ -+ if [ "$$x" = "dummy" ]; then continue; fi; \ -+ fn=`basename $$x`; \ -+ echo "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \ -+ $(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \ -+ done; -+ @set -e; for x in dummy $(BIN_SCRIPTS); \ -+ do \ -+ if [ "$$x" = "dummy" ]; then continue; fi; \ -+ fn=`basename $$x`; \ -+ echo "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \ -+ $(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \ -+ done -+ @ : {- output_off() unless windowsdll(); "" -} -+ @set -e; for s in dummy $(INSTALL_SHLIBS); do \ -+ if [ "$$s" = "dummy" ]; then continue; fi; \ -+ fn=`basename $$s`; \ -+ echo "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \ -+ $(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \ -+ done -+ @ : {- output_on() unless windowsdll(); "" -} -+ -$(RMDIR) $(DESTDIR)$(INSTALLTOP)/bin -+ -+# A method to extract all names from a .pod file -+# The first sed extracts everything between "=head1 NAME" and the next =head1 -+# The perl command joins all the lines into one -+# The second sed removes the description and turns all commas into spaces -+# Voilà, you have a space separated list of names! -+EXTRACT_NAMES=sed -e '1,/^=head1 *NAME *$$/d;/^=head1/,$$d' | \ -+ $(PERL) -p -0 -e 's/\n/ /g; END {print "\n"}' | \ -+ sed -e 's/ - .*$$//;s/,/ /g' -+PROCESS_PODS=\ -+ set -e; \ -+ here=`cd $(SRCDIR); pwd`; \ -+ point=$$here/util/point.sh; \ -+ for ds in apps:1 crypto:3 ssl:3; do \ -+ defdir=`echo $$ds | cut -f1 -d:`; \ -+ defsec=`echo $$ds | cut -f2 -d:`; \ -+ for p in $(SRCDIR)/doc/$$defdir/*.pod; do \ -+ SEC=`sed -ne 's/^=for *comment *openssl_manual_section: *\([0-9]\) *$$/\1/p' $$p`; \ -+ [ -z "$$SEC" ] && SEC=$$defsec; \ -+ fn=`basename $$p .pod`; \ -+ Name=$$fn; \ -+ NAME=`echo $$fn | tr '[a-z]' '[A-Z]'`; \ -+ suf=`eval "echo $$OUTSUFFIX"`; \ -+ top=`eval "echo $$OUTTOP"`; \ -+ $(PERL) $(SRCDIR)/util/mkdir-p.pl $$top/man$$SEC; \ -+ echo "install $$p -> $$top/man$$SEC/$$fn$$suf"; \ -+ cat $$p | eval "$$GENERATE" \ -+ > $$top/man$$SEC/$$fn$$suf; \ -+ names=`cat $$p | $(EXTRACT_NAMES)`; \ -+ ( cd $$top/man$$SEC; \ -+ for n in $$names; do \ -+ comp_n="$$n"; \ -+ comp_fn="$$fn"; \ -+ case "$(PLATFORM)" in DJGPP|Cygwin*|mingw*|darwin*-*-cc) \ -+ comp_n=`echo "$$n" | tr '[A-Z]' '[a-z]'`; \ -+ comp_fn=`echo "$$fn" | tr '[A-Z]' '[a-z]'`; \ -+ ;; \ -+ esac; \ -+ if [ "$$comp_n" != "$$comp_fn" ]; then \ -+ echo "link $$top/man$$SEC/$$n$$suf -> $$top/man$$SEC/$$fn$$suf"; \ -+ PLATFORM=$(PLATFORM) $$point $$fn$$suf $$n$$suf; \ -+ fi; \ -+ done ); \ -+ done; \ -+ done -+UNINSTALL_DOCS=\ -+ set -e; \ -+ here=`cd $(SRCDIR); pwd`; \ -+ for ds in apps:1 crypto:3 ssl:3; do \ -+ defdir=`echo $$ds | cut -f1 -d:`; \ -+ defsec=`echo $$ds | cut -f2 -d:`; \ -+ for p in $(SRCDIR)/doc/$$defdir/*.pod; do \ -+ SEC=`sed -ne 's/^=for *comment *openssl_manual_section: *\([0-9]\) *$$/\1/p' $$p`; \ -+ [ -z "$$SEC" ] && SEC=$$defsec; \ -+ fn=`basename $$p .pod`; \ -+ suf=`eval "echo $$OUTSUFFIX"`; \ -+ top=`eval "echo $$OUTTOP"`; \ -+ echo "$(RM) $$top/man$$SEC/$$fn$$suf"; \ -+ $(RM) $$top/man$$SEC/$$fn$$suf; \ -+ names=`cat $$p | $(EXTRACT_NAMES)`; \ -+ for n in $$names; do \ -+ comp_n="$$n"; \ -+ comp_fn="$$fn"; \ -+ case "$(PLATFORM)" in DJGPP|Cygwin*|mingw*|darwin*-*-cc) \ -+ comp_n=`echo "$$n" | tr '[A-Z]' '[a-z]'`; \ -+ comp_fn=`echo "$$fn" | tr '[A-Z]' '[a-z]'`; \ -+ ;; \ -+ esac; \ -+ if [ "$$comp_n" != "$$comp_fn" ]; then \ -+ echo "$(RM) $$top/man$$SEC/$$n$$suf"; \ -+ $(RM) $$top/man$$SEC/$$n$$suf; \ -+ fi; \ -+ done; \ -+ ( $(RMDIR) $$top/man$$SEC 2>/dev/null || exit 0 ); \ -+ done; \ -+ done -+ -+install_man_docs: -+ @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) -+ @echo "*** Installing manpages" -+ @\ -+ OUTSUFFIX='.$${SEC}$(MANSUFFIX)'; \ -+ OUTTOP="$(DESTDIR)$(MANDIR)"; \ -+ GENERATE='pod2man --name=$$NAME --section=$$SEC --center=OpenSSL --release=$(VERSION)'; \ -+ $(PROCESS_PODS) -+ -+uninstall_man_docs: -+ @echo "*** Uninstalling manpages" -+ @\ -+ OUTSUFFIX='.$${SEC}$(MANSUFFIX)'; \ -+ OUTTOP="$(DESTDIR)$(MANDIR)"; \ -+ $(UNINSTALL_DOCS) -+ -+install_html_docs: -+ @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) -+ @echo "*** Installing HTML manpages" -+ @\ -+ OUTSUFFIX='.$(HTMLSUFFIX)'; \ -+ OUTTOP="$(DESTDIR)$(HTMLDIR)"; \ -+ GENERATE="pod2html --podroot=$(SRCDIR)/doc --htmldir=.. \ -+ --podpath=apps:crypto:ssl --title=\$$Name \ -+ | perl -pe 's|href=\"http://man.he.net/man|href=\"../man|g; s|href=\"(.*/man.*)(?|href=\"\$$1.html\">|g;'"; \ -+ $(PROCESS_PODS) -+ -+uninstall_html_docs: -+ @echo "*** Uninstalling manpages" -+ @\ -+ OUTSUFFIX='.$(HTMLSUFFIX)'; \ -+ OUTTOP="$(DESTDIR)$(HTMLDIR)"; \ -+ $(UNINSTALL_DOCS) -+ -+ -+# Developer targets (note: these are only available on Unix) ######### -+ -+update: generate errors ordinals -+ -+generate: generate_apps generate_crypto_bn generate_crypto_objects \ -+ generate_crypto_conf generate_crypto_asn1 -+ -+# Test coverage is a good idea for the future -+#coverage: $(PROGRAMS) $(TESTPROGRAMS) -+# ... -+ -+lint: -+ lint -DLINT $(INCLUDES) $(SRCS) -+ -+{- # because the program apps/openssl has object files as sources, and -+ # they then have the corresponding C files as source, we need to chain -+ # the lookups in %unified_info -+ my $apps_openssl = catfile("apps","openssl"); -+ our @openssl_source = map { @{$unified_info{sources}->{$_}} } -+ @{$unified_info{sources}->{$apps_openssl}}; -+ ""; -} -+generate_apps: -+ ( cd $(SRCDIR); $(PERL) VMS/VMSify-conf.pl \ -+ < apps/openssl.cnf > apps/openssl-vms.cnf ) -+ ( b=`pwd`; cd $(SRCDIR); $(PERL) -I$$b apps/progs.pl \ -+ {- join(" ", @openssl_source) -} \ -+ > apps/progs.h ) -+ -+generate_crypto_bn: -+ ( cd $(SRCDIR); $(PERL) crypto/bn/bn_prime.pl > crypto/bn/bn_prime.h ) -+ -+generate_crypto_objects: -+ ( cd $(SRCDIR); $(PERL) crypto/objects/objects.pl \ -+ crypto/objects/objects.txt \ -+ crypto/objects/obj_mac.num \ -+ include/openssl/obj_mac.h ) -+ ( cd $(SRCDIR); $(PERL) crypto/objects/obj_dat.pl \ -+ include/openssl/obj_mac.h \ -+ crypto/objects/obj_dat.h ) -+ ( cd $(SRCDIR); $(PERL) crypto/objects/objxref.pl \ -+ crypto/objects/obj_mac.num \ -+ crypto/objects/obj_xref.txt \ -+ > crypto/objects/obj_xref.h ) -+ -+generate_crypto_conf: -+ ( cd $(SRCDIR); $(PERL) crypto/conf/keysets.pl \ -+ > crypto/conf/conf_def.h ) -+ -+generate_crypto_asn1: -+ ( cd $(SRCDIR); $(PERL) crypto/asn1/charmap.pl \ -+ > crypto/asn1/charmap.h ) -+ -+errors: -+ ( cd $(SRCDIR); $(PERL) util/ck_errf.pl -strict */*.c */*/*.c ) -+ ( cd $(SRCDIR); $(PERL) util/mkerr.pl -recurse -write ) -+ ( cd $(SRCDIR)/engines; \ -+ for e in *.ec; do \ -+ $(PERL) ../util/mkerr.pl -conf $$e \ -+ -nostatic -staticloader -write *.c; \ -+ done ) -+ -+ordinals: -+ ( b=`pwd`; cd $(SRCDIR); $(PERL) -I$$b util/mkdef.pl crypto update ) -+ ( b=`pwd`; cd $(SRCDIR); $(PERL) -I$$b util/mkdef.pl ssl update ) -+ -+test_ordinals: -+ ( cd test; \ -+ SRCTOP=../$(SRCDIR) \ -+ BLDTOP=../$(BLDDIR) \ -+ $(PERL) ../$(SRCDIR)/test/run_tests.pl test_ordinals ) -+ -+tags TAGS: FORCE -+ rm -f TAGS tags -+ -ctags -R . -+ -etags `find . -name '*.[ch]' -o -name '*.pm'` -+ -+# Release targets (note: only available on Unix) ##################### -+ -+TAR_COMMAND=$(TAR) $(TARFLAGS) --owner 0 --group 0 -cvf - -+PREPARE_CMD=: -+tar: -+ TMPDIR=/var/tmp/openssl-copy.$$$$; \ -+ DISTDIR=$(NAME); \ -+ mkdir -p $$TMPDIR/$$DISTDIR; \ -+ (cd $(SRCDIR); \ -+ git ls-tree -r --name-only --full-tree HEAD \ -+ | grep -v '^fuzz/corpora' \ -+ | while read F; do \ -+ mkdir -p $$TMPDIR/$$DISTDIR/`dirname $$F`; \ -+ cp $$F $$TMPDIR/$$DISTDIR/$$F; \ -+ done); \ -+ (cd $$TMPDIR; \ -+ $(PREPARE_CMD); \ -+ find $$TMPDIR/$$DISTDIR -type d -print | xargs chmod 755; \ -+ find $$TMPDIR/$$DISTDIR -type f -print | xargs chmod a+r; \ -+ find $$TMPDIR/$$DISTDIR -type f -perm -0100 -print | xargs chmod a+x; \ -+ $(TAR_COMMAND) $$DISTDIR) \ -+ | (cd $(SRCDIR); gzip --best > $(TARFILE).gz); \ -+ rm -rf $$TMPDIR -+ cd $(SRCDIR); ls -l $(TARFILE).gz -+ -+dist: -+ @$(MAKE) PREPARE_CMD='$(PERL) ./Configure dist' tar -+ -+# Helper targets ##################################################### -+ -+link-utils: $(BLDDIR)/util/opensslwrap.sh -+ -+$(BLDDIR)/util/opensslwrap.sh: configdata.pm -+ @if [ "$(SRCDIR)" != "$(BLDDIR)" ]; then \ -+ mkdir -p "$(BLDDIR)/util"; \ -+ ln -sf "../$(SRCDIR)/util/opensslwrap.sh" "$(BLDDIR)/util"; \ -+ fi -+ -+FORCE: -+ -+# Building targets ################################################### -+ -+libcrypto.pc libssl.pc openssl.pc: configdata.pm $(LIBS) {- join(" ",map { shlib_simple($_) } @{$unified_info{libraries}}) -} -+libcrypto.pc: -+ @ ( echo 'prefix=$(INSTALLTOP)'; \ -+ echo 'exec_prefix=$${prefix}'; \ -+ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \ -+ echo 'includedir=$${prefix}/include'; \ -+ echo 'enginesdir=$${libdir}/engines-{- $sover -}'; \ -+ echo ''; \ -+ echo 'Name: OpenSSL-libcrypto'; \ -+ echo 'Description: OpenSSL cryptography library'; \ -+ echo 'Version: '$(VERSION); \ -+ echo 'Libs: -L$${libdir} -lcrypto'; \ -+ echo 'Libs.private: $(EX_LIBS)'; \ -+ echo 'Cflags: -I$${includedir}' ) > libcrypto.pc -+ -+libssl.pc: -+ @ ( echo 'prefix=$(INSTALLTOP)'; \ -+ echo 'exec_prefix=$${prefix}'; \ -+ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \ -+ echo 'includedir=$${prefix}/include'; \ -+ echo ''; \ -+ echo 'Name: OpenSSL-libssl'; \ -+ echo 'Description: Secure Sockets Layer and cryptography libraries'; \ -+ echo 'Version: '$(VERSION); \ -+ echo 'Requires.private: libcrypto'; \ -+ echo 'Libs: -L$${libdir} -lssl'; \ -+ echo 'Libs.private: $(EX_LIBS)'; \ -+ echo 'Cflags: -I$${includedir}' ) > libssl.pc -+ -+openssl.pc: -+ @ ( echo 'prefix=$(INSTALLTOP)'; \ -+ echo 'exec_prefix=$${prefix}'; \ -+ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \ -+ echo 'includedir=$${prefix}/include'; \ -+ echo ''; \ -+ echo 'Name: OpenSSL'; \ -+ echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \ -+ echo 'Version: '$(VERSION); \ -+ echo 'Requires: libssl libcrypto' ) > openssl.pc -+ -+configdata.pm: $(SRCDIR)/Configure $(SRCDIR)/config {- join(" ", @{$config{build_file_templates}}, @{$config{build_infos}}, @{$config{conf_files}}) -} -+ @echo "Detected changed: $?" -+ @echo "Reconfiguring..." -+ $(PERL) $(SRCDIR)/Configure reconf -+ @echo "**************************************************" -+ @echo "*** ***" -+ @echo "*** Please run the same make command again ***" -+ @echo "*** ***" -+ @echo "**************************************************" -+ @false -+ -+{- -+ use File::Basename; -+ use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/; -+ -+ # Helper function to figure out dependencies on libraries -+ # It takes a list of library names and outputs a list of dependencies -+ sub compute_lib_depends { -+ if ($disabled{shared}) { -+ return map { $_.$libext } @_; -+ } -+ -+ # Depending on shared libraries: -+ # On Windows POSIX layers, we depend on {libname}.dll.a -+ # On Unix platforms, we depend on {shlibname}.so -+ return map { shlib_simple($_) } @_; -+ } -+ -+ sub generatesrc { -+ my %args = @_; -+ my $generator = join(" ", @{$args{generator}}); -+ my $generator_incs = join("", map { " -I".$_ } @{$args{generator_incs}}); -+ my $incs = join("", map { " -I".$_ } @{$args{incs}}); -+ my $deps = join(" ", @{$args{generator_deps}}, @{$args{deps}}); -+ -+ if ($args{src} !~ /\.[sS]$/) { -+ if ($args{generator}->[0] =~ m|^.*\.in$|) { -+ my $dofile = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "util", "dofile.pl")), -+ rel2abs($config{builddir})); -+ return <<"EOF"; -+$args{src}: $args{generator}->[0] $deps -+ \$(PERL) "-I\$(BLDDIR)" -Mconfigdata "$dofile" \\ -+ "-o$target{build_file}" $generator > \$@ -+EOF -+ } else { -+ return <<"EOF"; -+$args{src}: $args{generator}->[0] $deps -+ \$(PERL)$generator_incs $generator > \$@ -+EOF -+ } -+ } else { -+ if ($args{generator}->[0] =~ /\.pl$/) { -+ $generator = 'CC="$(CC)" $(PERL)'.$generator_incs.' '.$generator; -+ } elsif ($args{generator}->[0] =~ /\.m4$/) { -+ $generator = 'm4 -B 8192'.$generator_incs.' '.$generator.' >' -+ } elsif ($args{generator}->[0] =~ /\.S$/) { -+ $generator = undef; -+ } else { -+ die "Generator type for $args{src} unknown: $generator\n"; -+ } -+ -+ if (defined($generator)) { -+ # If the target is named foo.S in build.info, we want to -+ # end up generating foo.s in two steps. -+ if ($args{src} =~ /\.S$/) { -+ (my $target = $args{src}) =~ s|\.S$|.s|; -+ return <<"EOF"; -+$target: $args{generator}->[0] $deps -+ ( trap "rm -f \$@.*" INT 0; \\ -+ $generator \$@.S; \\ -+ \$(CC) $incs \$(CFLAGS) -E \$@.S | \\ -+ \$(PERL) -ne '/^#(line)?\\s*[0-9]+/ or print' > \$@.i && \\ -+ mv -f \$@.i \$@ ) -+EOF -+ } -+ # Otherwise.... -+ return <<"EOF"; -+$args{src}: $args{generator}->[0] $deps -+ $generator \$@ -+EOF -+ } -+ return <<"EOF"; -+$args{src}: $args{generator}->[0] $deps -+ \$(CC) $incs \$(CFLAGS) -E \$< | \\ -+ \$(PERL) -ne '/^#(line)?\\s*[0-9]+/ or print' > \$@ -+EOF -+ } -+ } -+ -+ # Should one wonder about the end of the Perl snippet, it's because this -+ # second regexp eats up line endings as well, if the removed path is the -+ # last in the line. We may therefore need to put back a line ending. -+ sub src2obj { -+ my %args = @_; -+ my $obj = $args{obj}; -+ my @srcs = map { if ($unified_info{generate}->{$_}) { -+ (my $x = $_) =~ s/\.S$/.s/; $x -+ } else { -+ $_ -+ } -+ } ( @{$args{srcs}} ); -+ my $srcs = join(" ", @srcs); -+ my $deps = join(" ", @srcs, @{$args{deps}}); -+ my $incs = join("", map { " -I".$_ } @{$args{incs}}); -+ unless ($disabled{zlib}) { -+ if ($withargs{zlib_include}) { -+ $incs .= " -I".$withargs{zlib_include}; -+ } -+ } -+ my $ecflags = { lib => '$(LIB_CFLAGS)', -+ dso => '$(DSO_CFLAGS)', -+ bin => '$(BIN_CFLAGS)' } -> {$args{intent}}; -+ my $makedepprog = $config{makedepprog}; -+ my $recipe = <<"EOF"; -+$obj$objext: $deps -+EOF -+ if (!$disabled{makedepend} && $makedepprog !~ /\/makedepend/) { -+ $recipe .= <<"EOF"; -+ \$(CC) $incs \$(CFLAGS) $ecflags -MMD -MF $obj$depext.tmp -MT \$\@ -c -o \$\@ $srcs -+ \@touch $obj$depext.tmp -+ \@if cmp $obj$depext.tmp $obj$depext > /dev/null 2> /dev/null; then \\ -+ rm -f $obj$depext.tmp; \\ -+ else \\ -+ mv $obj$depext.tmp $obj$depext; \\ -+ fi -+EOF -+ } else { -+ $recipe .= <<"EOF"; -+ \$(CC) $incs \$(CFLAGS) $ecflags -c -o \$\@ $srcs -+EOF -+ if (!$disabled{makedepend} && $makedepprog =~ /\/makedepend/) { -+ $recipe .= <<"EOF"; -+ -\$(MAKEDEPEND) -f- -o"|\$\@" -- $incs \$(CFLAGS) $ecflags -- $srcs \\ -+ >$obj$depext.tmp 2>/dev/null -+ -\$(PERL) -i -pe 's/^.*\\|//; s/ \\/(\\\\.|[^ ])*//; \$\$_ = undef if (/: *\$\$/ || /^(#.*| *)\$\$/); \$\$_.="\\n" unless !defined(\$\$_) or /\\R\$\$/g;' $obj$depext.tmp -+ \@if cmp $obj$depext.tmp $obj$depext > /dev/null 2> /dev/null; then \\ -+ rm -f $obj$depext.tmp; \\ -+ else \\ -+ mv $obj$depext.tmp $obj$depext; \\ -+ fi -+EOF -+ } -+ } -+ return $recipe; -+ } -+ # On Unix, we build shlibs from static libs, so we're ignoring the -+ # object file array. We *know* this routine is only called when we've -+ # configure 'shared'. -+ sub libobj2shlib { -+ my %args = @_; -+ my $lib = $args{lib}; -+ my $shlib = $args{shlib}; -+ my $libd = dirname($lib); -+ my $libn = basename($lib); -+ (my $libname = $libn) =~ s/^lib//; -+ my $linklibs = join("", map { my $d = dirname($_); -+ my $f = basename($_); -+ (my $l = $f) =~ s/^lib//; -+ " -L$d -l$l" } @{$args{deps}}); -+ my $deps = join(" ",compute_lib_depends(@{$args{deps}})); -+ my $shlib_target = $target{shared_target}; -+ my $ordinalsfile = defined($args{ordinals}) ? $args{ordinals}->[1] : ""; -+ my $target = shlib_simple($lib); -+ return <<"EOF" -+# With a build on a Windows POSIX layer (Cygwin or Mingw), we know for a fact -+# that two files get produced, {shlibname}.dll and {libname}.dll.a. -+# With all other Unix platforms, we often build a shared library with the -+# SO version built into the file name and a symlink without the SO version -+# It's not necessary to have both as targets. The choice falls on the -+# simplest, {libname}$shlibextimport for Windows POSIX layers and -+# {libname}$shlibextsimple for the Unix platforms. -+$target: $lib$libext $deps $ordinalsfile -+ \$(MAKE) -f \$(SRCDIR)/Makefile.shared -e \\ -+ PLATFORM=\$(PLATFORM) \\ -+ PERL="\$(PERL)" SRCDIR='\$(SRCDIR)' DSTDIR="$libd" \\ -+ INSTALLTOP='\$(INSTALLTOP)' LIBDIR='\$(LIBDIR)' \\ -+ LIBDEPS='\$(PLIB_LDFLAGS) '"$linklibs"' \$(EX_LIBS)' \\ -+ LIBNAME=$libname LIBVERSION=\$(SHLIB_MAJOR).\$(SHLIB_MINOR) \\ -+ LIBCOMPATVERSIONS=';\$(SHLIB_VERSION_HISTORY)' \\ -+ CC='\$(CC)' CFLAGS='\$(CFLAGS) \$(LIB_CFLAGS)' \\ -+ LDFLAGS='\$(LDFLAGS)' \\ -+ SHARED_LDFLAGS='\$(LIB_LDFLAGS)' SHLIB_EXT=$shlibext \\ -+ RC='\$(RC)' SHARED_RCFLAGS='\$(RCFLAGS)' \\ -+ link_shlib.$shlib_target -+EOF -+ . (windowsdll() ? <<"EOF" : ""); -+ rm -f apps/$shlib$shlibext -+ rm -f test/$shlib$shlibext -+ cp -p $shlib$shlibext apps/ -+ cp -p $shlib$shlibext test/ -+EOF -+ } -+ sub obj2dso { -+ my %args = @_; -+ my $lib = $args{lib}; -+ my $libd = dirname($lib); -+ my $libn = basename($lib); -+ (my $libname = $libn) =~ s/^lib//; -+ my $shlibdeps = join("", map { my $d = dirname($_); -+ my $f = basename($_); -+ (my $l = $f) =~ s/^lib//; -+ " -L$d -l$l" } @{$args{deps}}); -+ my $deps = join(" ",compute_lib_depends(@{$args{deps}})); -+ my $shlib_target = $target{shared_target}; -+ my $objs = join(" ", map { $_.$objext } @{$args{objs}}); -+ my $target = dso($lib); -+ return <<"EOF"; -+$target: $objs $deps -+ \$(MAKE) -f \$(SRCDIR)/Makefile.shared -e \\ -+ PLATFORM=\$(PLATFORM) \\ -+ PERL="\$(PERL)" SRCDIR='\$(SRCDIR)' DSTDIR="$libd" \\ -+ LIBDEPS='\$(PLIB_LDFLAGS) '"$shlibdeps"' \$(EX_LIBS)' \\ -+ LIBNAME=$libname LDFLAGS='\$(LDFLAGS)' \\ -+ CC='\$(CC)' CFLAGS='\$(CFLAGS) \$(DSO_CFLAGS)' \\ -+ SHARED_LDFLAGS='\$(DSO_LDFLAGS)' \\ -+ SHLIB_EXT=$dsoext \\ -+ LIBEXTRAS="$objs" \\ -+ link_dso.$shlib_target -+EOF -+ } -+ sub obj2lib { -+ my %args = @_; -+ my $lib = $args{lib}; -+ my $objs = join(" ", map { $_.$objext } @{$args{objs}}); -+ return <<"EOF"; -+$lib$libext: $objs -+ \$(AR) \$\@ \$\? -+ \$(RANLIB) \$\@ || echo Never mind. -+EOF -+ } -+ sub obj2bin { -+ my %args = @_; -+ my $bin = $args{bin}; -+ my $bind = dirname($bin); -+ my $binn = basename($bin); -+ my $objs = join(" ", map { $_.$objext } @{$args{objs}}); -+ my $deps = join(" ",compute_lib_depends(@{$args{deps}})); -+ my $linklibs = join("", map { my $d = dirname($_); -+ my $f = basename($_); -+ $d = "." if $d eq $f; -+ (my $l = $f) =~ s/^lib//; -+ " -L$d -l$l" } @{$args{deps}}); -+ my $shlib_target = $disabled{shared} ? "" : $target{shared_target}; -+ return <<"EOF"; -+$bin$exeext: $objs $deps -+ \$(RM) $bin$exeext -+ \$(MAKE) -f \$(SRCDIR)/Makefile.shared -e \\ -+ PERL="\$(PERL)" SRCDIR=\$(SRCDIR) \\ -+ APPNAME=$bin$exeext OBJECTS="$objs" \\ -+ LIBDEPS='\$(PLIB_LDFLAGS) '"$linklibs"' \$(EX_LIBS)' \\ -+ CC='\$(CC)' CFLAGS='\$(CFLAGS) \$(BIN_CFLAGS)' \\ -+ LDFLAGS='\$(LDFLAGS)' \\ -+ link_app.$shlib_target -+EOF -+ } -+ sub in2script { -+ my %args = @_; -+ my $script = $args{script}; -+ my $sources = join(" ", @{$args{sources}}); -+ my $dofile = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "util", "dofile.pl")), -+ rel2abs($config{builddir})); -+ return <<"EOF"; -+$script: $sources -+ \$(PERL) "-I\$(BLDDIR)" -Mconfigdata "$dofile" \\ -+ "-o$target{build_file}" $sources > "$script" -+ chmod a+x $script -+EOF -+ } -+ sub generatedir { -+ my %args = @_; -+ my $dir = $args{dir}; -+ my @deps = map { s|\.o$|$objext|; $_ } @{$args{deps}}; -+ my @actions = (); -+ my %extinfo = ( dso => $dsoext, -+ lib => $libext, -+ bin => $exeext ); -+ -+ foreach my $type (("dso", "lib", "bin", "script")) { -+ next unless defined($unified_info{dirinfo}->{$dir}->{products}->{$type}); -+ # For lib object files, we could update the library. However, it -+ # was decided that it's enough to build the directory local object -+ # files, so we don't need to add any actions, and the dependencies -+ # are already taken care of. -+ if ($type ne "lib") { -+ foreach my $prod (@{$unified_info{dirinfo}->{$dir}->{products}->{$type}}) { -+ if (dirname($prod) eq $dir) { -+ push @deps, $prod.$extinfo{$type}; -+ } else { -+ push @actions, "\t@ : No support to produce $type ".join(", ", @{$unified_info{dirinfo}->{$dir}->{products}->{$type}}); -+ } -+ } -+ } -+ } -+ -+ my $deps = join(" ", @deps); -+ my $actions = join("\n", "", @actions); -+ return <<"EOF"; -+$args{dir} $args{dir}/: $deps$actions -+EOF -+ } -+ "" # Important! This becomes part of the template result. -+-} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configurations/windows-makefile.tmpl b/CryptoPkg/Library/OpensslLib/openssl/Configurations/windows-makefile.tmpl -new file mode 100644 -index 0000000..1d7e666 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configurations/windows-makefile.tmpl -@@ -0,0 +1,601 @@ -+## -+## Makefile for OpenSSL -+## -+## {- join("\n## ", @autowarntext) -} -+{- -+ our $objext = $target{obj_extension} || ".obj"; -+ our $depext = $target{dep_extension} || ".d"; -+ our $exeext = $target{exe_extension} || ".exe"; -+ our $libext = $target{lib_extension} || ".lib"; -+ our $shlibext = $target{shared_extension} || ".dll"; -+ our $shlibextimport = $target{shared_import_extension} || ".lib"; -+ our $dsoext = $target{dso_extension} || ".dll"; -+ -+ our $sover = $config{shlib_major}."_".$config{shlib_minor}; -+ -+ my $win_installenv = -+ $target{build_scheme}->[2] eq "VC-W32" ? -+ "ProgramFiles(x86)" : "ProgramW6432"; -+ my $win_commonenv = -+ $target{build_scheme}->[2] eq "VC-W32" -+ ? "CommonProgramFiles(x86)" : "CommonProgramW6432"; -+ our $win_installroot = -+ defined($ENV{$win_installenv}) -+ ? $win_installenv : 'ProgramFiles'; -+ our $win_commonroot = -+ defined($ENV{$win_commonenv}) -+ ? $win_commonenv : 'CommonProgramFiles'; -+ -+ # expand variables early -+ $win_installroot = $ENV{$win_installroot}; -+ $win_commonroot = $ENV{$win_commonroot}; -+ -+ sub shlib { -+ return () if $disabled{shared}; -+ my $lib = shift; -+ return $unified_info{sharednames}->{$lib} . $shlibext; -+ } -+ -+ sub shlib_import { -+ return () if $disabled{shared}; -+ my $lib = shift; -+ return $lib . $shlibextimport; -+ } -+ -+ sub dso { -+ my $dso = shift; -+ -+ return $dso . $dsoext; -+ } -+ ''; -+-} -+ -+PLATFORM={- $config{target} -} -+SRCDIR={- $config{sourcedir} -} -+BLDDIR={- $config{builddir} -} -+ -+VERSION={- $config{version} -} -+MAJOR={- $config{major} -} -+MINOR={- $config{minor} -} -+ -+SHLIB_VERSION_NUMBER={- $config{shlib_version_number} -} -+ -+LIBS={- join(" ", map { $_.$libext } @{$unified_info{libraries}}) -} -+SHLIBS={- join(" ", map { shlib($_) } @{$unified_info{libraries}}) -} -+SHLIBPDBS={- join(" ", map { local $shlibext = ".pdb"; shlib($_) } @{$unified_info{libraries}}) -} -+ENGINES={- join(" ", map { dso($_) } @{$unified_info{engines}}) -} -+ENGINEPDBS={- join(" ", map { local $dsoext = ".pdb"; dso($_) } @{$unified_info{engines}}) -} -+PROGRAMS={- join(" ", map { $_.$exeext } @{$unified_info{programs}}) -} -+PROGRAMPDBS={- join(" ", map { $_.".pdb" } @{$unified_info{programs}}) -} -+SCRIPTS={- join(" ", @{$unified_info{scripts}}) -} -+{- output_off() if $disabled{makedepend}; "" -} -+DEPS={- join(" ", map { (my $x = $_) =~ s|\.o$|$depext|; $x; } -+ grep { $unified_info{sources}->{$_}->[0] =~ /\.c$/ } -+ keys %{$unified_info{sources}}); -} -+{- output_on() if $disabled{makedepend}; "" -} -+GENERATED_MANDATORY={- join(" ", @{$unified_info{depends}->{""}} ) -} -+GENERATED={- join(" ", -+ ( map { (my $x = $_) =~ s|\.[sS]$|\.asm|; $x } -+ grep { defined $unified_info{generate}->{$_} } -+ map { @{$unified_info{sources}->{$_}} } -+ grep { /\.o$/ } keys %{$unified_info{sources}} ), -+ ( grep { /\.h$/ } keys %{$unified_info{generate}} )) -} -+ -+INSTALL_LIBS={- join(" ", map { $_.$libext } @{$unified_info{install}->{libraries}}) -} -+INSTALL_SHLIBS={- join(" ", map { shlib($_) } @{$unified_info{install}->{libraries}}) -} -+INSTALL_SHLIBPDBS={- join(" ", map { local $shlibext = ".pdb"; shlib($_) } @{$unified_info{install}->{libraries}}) -} -+INSTALL_ENGINES={- join(" ", map { dso($_) } @{$unified_info{install}->{engines}}) -} -+INSTALL_ENGINEPDBS={- join(" ", map { local $dsoext = ".pdb"; dso($_) } @{$unified_info{install}->{engines}}) -} -+INSTALL_PROGRAMS={- join(" ", map { $_.$exeext } grep { !m|^test\\| } @{$unified_info{install}->{programs}}) -} -+INSTALL_PROGRAMPDBS={- join(" ", map { $_.".pdb" } grep { !m|^test\\| } @{$unified_info{install}->{programs}}) -} -+{- output_off() if $disabled{apps}; "" -} -+BIN_SCRIPTS=$(BLDDIR)\tools\c_rehash.pl -+MISC_SCRIPTS=$(BLDDIR)\apps\CA.pl $(BLDDIR)\apps\tsget.pl -+{- output_on() if $disabled{apps}; "" -} -+ -+# Do not edit these manually. Use Configure with --prefix or --openssldir -+# to change this! Short explanation in the top comment in Configure -+INSTALLTOP_dev={- # $prefix is used in the OPENSSLDIR perl snippet -+ # -+ use File::Spec::Functions qw(:DEFAULT splitpath); -+ our $prefix = $config{prefix} || "$win_installroot\\OpenSSL"; -+ our ($prefix_dev, $prefix_dir, $prefix_file) = -+ splitpath($prefix, 1); -+ $prefix_dev -} -+INSTALLTOP_dir={- $prefix_dir -} -+OPENSSLDIR_dev={- # -+ # The logic here is that if no --openssldir was given, -+ # OPENSSLDIR will get the value from $prefix plus "/ssl". -+ # If --openssldir was given and the value is an absolute -+ # path, OPENSSLDIR will get its value without change. -+ # If the value from --openssldir is a relative path, -+ # OPENSSLDIR will get $prefix with the --openssldir -+ # value appended as a subdirectory. -+ # -+ use File::Spec::Functions qw(:DEFAULT splitpath); -+ our $openssldir = -+ $config{openssldir} ? -+ (file_name_is_absolute($config{openssldir}) ? -+ $config{openssldir} -+ : catdir($prefix, $config{openssldir})) -+ : "$win_commonroot\\SSL"; -+ our ($openssldir_dev, $openssldir_dir, $openssldir_file) = -+ splitpath($openssldir, 1); -+ $openssldir_dev -} -+OPENSSLDIR_dir={- $openssldir_dir -} -+LIBDIR={- our $libdir = $config{libdir} || "lib"; -+ $libdir -} -+ENGINESDIR_dev={- use File::Spec::Functions qw(:DEFAULT splitpath); -+ our $enginesdir = catdir($prefix,$libdir,"engines-$sover"); -+ our ($enginesdir_dev, $enginesdir_dir, $enginesdir_file) = -+ splitpath($enginesdir, 1); -+ $enginesdir_dev -} -+ENGINESDIR_dir={- $enginesdir_dir -} -+!IF "$(DESTDIR)" != "" -+INSTALLTOP=$(DESTDIR)$(INSTALLTOP_dir) -+OPENSSLDIR=$(DESTDIR)$(OPENSSLDIR_dir) -+ENGINESDIR=$(DESTDIR)$(ENGINESDIR_dir) -+!ELSE -+INSTALLTOP=$(INSTALLTOP_dev)$(INSTALLTOP_dir) -+OPENSSLDIR=$(OPENSSLDIR_dev)$(OPENSSLDIR_dir) -+ENGINESDIR=$(ENGINESDIR_dev)$(ENGINESDIR_dir) -+!ENDIF -+ -+CC={- $target{cc} -} -+CFLAGS={- join(" ",(map { "-D".$_} @{$target{defines}}, @{$config{defines}})) -} {- join(" ", quotify_l("-DENGINESDIR=\"$enginesdir\"", "-DOPENSSLDIR=\"$openssldir\"")) -} {- $target{cflags} -} {- $config{cflags} -} -+COUTFLAG={- $target{coutflag} || "/Fo" -}$(OSSL_EMPTY) -+RC={- $target{rc} || "rc" -} -+RCOUTFLAG={- $target{rcoutflag} || "/fo" -}$(OSSL_EMPTY) -+LD={- $target{ld} || "link" -} -+LDFLAGS={- $target{lflags} -} -+LDOUTFLAG={- $target{loutflag} || "/out:" -}$(OSSL_EMPTY) -+EX_LIBS={- $target{ex_libs} -} -+LIB_CFLAGS={- join(" ", $target{lib_cflags}, $target{shared_cflag}) || "" -} -+LIB_LDFLAGS={- $target{shared_ldflag} || "" -} -+DSO_CFLAGS={- join(" ", $target{dso_cflags}, $target{shared_cflag}) || "" -} -+DSO_LDFLAGS={- join(" ", $target{dso_lflags}, $target{shared_ldflag}) || "" -} -+BIN_CFLAGS={- $target{bin_cflags} -} -+BIN_LDFLAGS={- $target{bin_lflags} -} -+ -+PERL={- $config{perl} -} -+ -+AR={- $target{ar} -} -+ARFLAGS= {- $target{arflags} -} -+AROUTFLAG={- $target{aroutflag} || "/out:" -}$(OSSL_EMPTY) -+ -+MT={- $target{mt} -} -+MTFLAGS= {- $target{mtflags} -} -+MTINFLAG={- $target{mtinflag} || "-manifest " -}$(OSSL_EMPTY) -+MTOUTFLAG={- $target{mtoutflag} || "-outputresource:" -}$(OSSL_EMPTY) -+ -+AS={- $target{as} -} -+ASFLAGS={- $target{asflags} -} -+ASOUTFLAG={- $target{asoutflag} -}$(OSSL_EMPTY) -+PERLASM_SCHEME= {- $target{perlasm_scheme} -} -+ -+PROCESSOR= {- $config{processor} -} -+ -+# The main targets ################################################### -+ -+all: build_generated \ -+ build_libs_nodep build_engines_nodep build_programs_nodep depend -+ -+build_libs: build_generated build_libs_nodep depend -+build_libs_nodep: $(LIBS) {- join(" ",map { shlib_import($_) } @{$unified_info{libraries}}) -} -+build_engines: build_generated build_engines_nodep depend -+build_engines_nodep: $(ENGINES) -+build_programs: build_generated build_programs_nodep depend -+build_programs_nodep: $(PROGRAMS) $(SCRIPTS) -+ -+build_generated: $(GENERATED_MANDATORY) -+ -+# Kept around for backward compatibility -+build_apps build_tests: build_programs -+ -+test: tests -+tests: build_generated build_programs_nodep build_engines_nodep depend -+ @rem {- output_off() if $disabled{tests}; "" -} -+ set SRCTOP=$(SRCDIR) -+ set BLDTOP=$(BLDDIR) -+ set PERL=$(PERL) -+ set OPENSSL_DEBUG_MEMORY=on -+ "$(PERL)" "$(SRCDIR)\test\run_tests.pl" $(TESTS) -+ @rem {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -} -+ @echo "Tests are not supported with your chosen Configure options" -+ @rem {- output_on() if !$disabled{tests}; "" -} -+ -+list-tests: -+ @rem {- output_off() if $disabled{tests}; "" -} -+ @set SRCTOP=$(SRCDIR) -+ @"$(PERL)" "$(SRCDIR)\test\run_tests.pl" list -+ @rem {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -} -+ @echo "Tests are not supported with your chosen Configure options" -+ @rem {- output_on() if !$disabled{tests}; "" -} -+ -+install: install_sw install_ssldirs install_docs -+ -+uninstall: uninstall_docs uninstall_sw -+ -+libclean: -+ "$(PERL)" -e "map { m/(.*)\.dll$$/; unlink glob """$$1.*"""; } @ARGV" $(SHLIBS) -+ "$(PERL)" -e "map { m/(.*)\.dll$$/; unlink glob """apps/$$1.*"""; } @ARGV" $(SHLIBS) -+ "$(PERL)" -e "map { m/(.*)\.dll$$/; unlink glob """test/$$1.*"""; } @ARGV" $(SHLIBS) -+ -del /Q /F $(LIBS) -+ -del /Q ossl_static.pdb -+ -+clean: libclean -+ -del /Q /F $(PROGRAMS) $(ENGINES) $(SCRIPTS) -+ -del /Q /F $(GENERATED) -+ -del /Q /S /F *.d -+ -del /Q /S /F *.obj -+ -del /Q /S /F *.pdb -+ -del /Q /S /F *.exp -+ -del /Q /S /F engines\*.ilk -+ -del /Q /S /F engines\*.lib -+ -del /Q /S /F apps\*.lib -+ -del /Q /S /F engines\*.manifest -+ -del /Q /S /F apps\*.manifest -+ -del /Q /S /F test\*.manifest -+ -+distclean: clean -+ -del /Q /F configdata.pm -+ -del /Q /F makefile -+ -+depend: -+ -+# Install helper targets ############################################# -+ -+install_sw: all install_dev install_engines install_runtime -+ -+uninstall_sw: uninstall_runtime uninstall_engines uninstall_dev -+ -+install_docs: install_html_docs -+ -+uninstall_docs: uninstall_html_docs -+ -+install_ssldirs: -+ @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(OPENSSLDIR)\certs" -+ @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(OPENSSLDIR)\private" -+ @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(OPENSSLDIR)\misc" -+ @"$(PERL)" "$(SRCDIR)\util\copy.pl" "$(SRCDIR)\apps\openssl.cnf" \ -+ "$(OPENSSLDIR)\openssl.cnf.dist" -+ @IF NOT EXIST "$(OPENSSLDIR)\openssl.cnf" \ -+ "$(PERL)" "$(SRCDIR)\util\copy.pl" "$(SRCDIR)\apps\openssl.cnf" \ -+ "$(OPENSSLDIR)\openssl.cnf" -+ @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(MISC_SCRIPTS) \ -+ "$(OPENSSLDIR)\misc" -+ -+install_dev: -+ @if "$(INSTALLTOP)"=="" ( echo INSTALLTOP should not be empty & exit 1 ) -+ @echo *** Installing development files -+ @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\include\openssl" -+ @rem {- output_off() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$target{defines}}; "" -} -+ @"$(PERL)" "$(SRCDIR)\util\copy.pl" "$(SRCDIR)\ms\applink.c" \ -+ "$(INSTALLTOP)\include\openssl" -+ @rem {- output_on() unless grep { $_ eq "OPENSSL_USE_APPLINK" } @{$target{defines}}; "" -} -+ @"$(PERL)" "$(SRCDIR)\util\copy.pl" "$(SRCDIR)\include\openssl\*.h" \ -+ "$(INSTALLTOP)\include\openssl" -+ @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(BLDDIR)\include\openssl\*.h \ -+ "$(INSTALLTOP)\include\openssl" -+ @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\$(LIBDIR)" -+ @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_LIBS) \ -+ "$(INSTALLTOP)\$(LIBDIR)" -+ @if "$(SHLIBS)"=="" \ -+ "$(PERL)" "$(SRCDIR)\util\copy.pl" ossl_static.pdb \ -+ "$(INSTALLTOP)\$(LIBDIR)" -+ -+uninstall_dev: -+ -+install_engines: -+ @if "$(INSTALLTOP)"=="" ( echo INSTALLTOP should not be empty & exit 1 ) -+ @echo *** Installing engines -+ @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(ENGINESDIR)" -+ @if not "$(ENGINES)"=="" \ -+ "$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_ENGINES) "$(ENGINESDIR)" -+ @if not "$(ENGINES)"=="" \ -+ "$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_ENGINEPDBS) "$(ENGINESDIR)" -+ -+uninstall_engines: -+ -+install_runtime: -+ @if "$(INSTALLTOP)"=="" ( echo INSTALLTOP should not be empty & exit 1 ) -+ @echo *** Installing runtime files -+ @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\bin" -+ @if not "$(SHLIBS)"=="" \ -+ "$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_SHLIBS) "$(INSTALLTOP)\bin" -+ @if not "$(SHLIBS)"=="" \ -+ "$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_SHLIBPDBS) \ -+ "$(INSTALLTOP)\bin" -+ @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_PROGRAMS) \ -+ "$(INSTALLTOP)\bin" -+ @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_PROGRAMPDBS) \ -+ "$(INSTALLTOP)\bin" -+ @"$(PERL)" "$(SRCDIR)\util\copy.pl" $(BIN_SCRIPTS) \ -+ "$(INSTALLTOP)\bin" -+ -+uninstall_runtime: -+ -+install_html_docs: -+ "$(PERL)" "$(SRCDIR)\util\process_docs.pl" \ -+ "--destdir=$(INSTALLTOP)\html" --type=html -+ -+uninstall_html_docs: -+ -+# Building targets ################################################### -+ -+configdata.pm: "$(SRCDIR)\Configure" {- join(" ", map { '"'.$_.'"' } @{$config{build_file_templates}}, @{$config{build_infos}}, @{$config{conf_files}}) -} -+ @echo "Detected changed: $?" -+ @echo "Reconfiguring..." -+ "$(PERL)" "$(SRCDIR)\Configure" reconf -+ @echo "**************************************************" -+ @echo "*** ***" -+ @echo "*** Please run the same make command again ***" -+ @echo "*** ***" -+ @echo "**************************************************" -+ @exit 1 -+ -+{- -+ use File::Basename; -+ use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/; -+ -+ # Helper function to figure out dependencies on libraries -+ # It takes a list of library names and outputs a list of dependencies -+ sub compute_lib_depends { -+ if ($disabled{shared}) { -+ return map { $_.$libext } @_; -+ } -+ return map { shlib_import($_) } @_; -+ } -+ -+ sub generatesrc { -+ my %args = @_; -+ (my $target = $args{src}) =~ s/\.[sS]$/.asm/; -+ my $generator = '"'.join('" "', @{$args{generator}}).'"'; -+ my $generator_incs = join("", map { " -I \"$_\"" } @{$args{generator_incs}}); -+ my $incs = join("", map { " /I \"$_\"" } @{$args{incs}}); -+ my $deps = @{$args{deps}} ? -+ '"'.join('" "', @{$args{generator_deps}}, @{$args{deps}}).'"' : ''; -+ -+ if ($target !~ /\.asm$/) { -+ if ($args{generator}->[0] =~ m|^.*\.in$|) { -+ my $dofile = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "util", "dofile.pl")), -+ rel2abs($config{builddir})); -+ return <<"EOF"; -+$target: "$args{generator}->[0]" $deps -+ "\$(PERL)" "-I\$(BLDDIR)" -Mconfigdata "$dofile" \\ -+ "-o$target{build_file}" $generator > \$@ -+EOF -+ } else { -+ return <<"EOF"; -+$target: "$args{generator}->[0]" $deps -+ "\$(PERL)"$generator_incs $generator > \$@ -+EOF -+ } -+ } else { -+ if ($args{generator}->[0] =~ /\.pl$/) { -+ $generator = '"$(PERL)"'.$generator_incs.' '.$generator; -+ } elsif ($args{generator}->[0] =~ /\.S$/) { -+ $generator = undef; -+ } else { -+ die "Generator type for $src unknown: $generator\n"; -+ } -+ -+ if (defined($generator)) { -+ # If the target is named foo.S in build.info, we want to -+ # end up generating foo.s in two steps. -+ if ($args{src} =~ /\.S$/) { -+ return <<"EOF"; -+$target: "$args{generator}->[0]" $deps -+ set ASM=\$(AS) -+ $generator \$@.S -+ \$(CC) $incs \$(CFLAGS) /EP /C \$@.S > \$@.i && move /Y \$@.i \$@ -+ del /Q \$@.S -+EOF -+ } -+ # Otherwise.... -+ return <<"EOF"; -+$target: "$args{generator}->[0]" $deps -+ set ASM=\$(AS) -+ $generator \$@ -+EOF -+ } -+ return <<"EOF"; -+$target: "$args{generator}->[0]" $deps -+ \$(CC) $incs \$(CFLAGS) /EP /C "$args{generator}->[0]" > \$@.i && move /Y \$@.i \$@ -+EOF -+ } -+ } -+ -+ sub src2obj { -+ my %args = @_; -+ my $obj = $args{obj}; -+ my @srcs = map { (my $x = $_) =~ s/\.s$/.asm/; $x -+ } ( @{$args{srcs}} ); -+ my $srcs = '"'.join('" "', @srcs).'"'; -+ my $deps = '"'.join('" "', @srcs, @{$args{deps}}).'"'; -+ my $incs = join("", map { ' /I "'.$_.'"' } @{$args{incs}}); -+ unless ($disabled{zlib}) { -+ if ($withargs{zlib_include}) { -+ $incs .= ' /I "'.$withargs{zlib_include}.'"'; -+ } -+ } -+ my $ecflags = { lib => '$(LIB_CFLAGS)', -+ dso => '$(DSO_CFLAGS)', -+ bin => '$(BIN_CFLAGS)' } -> {$args{intent}}; -+ my $makedepprog = $config{makedepprog}; -+ if ($srcs[0] =~ /\.asm$/) { -+ return <<"EOF"; -+$obj$objext: $deps -+ \$(AS) \$(ASFLAGS) \$(ASOUTFLAG)\$\@ $srcs -+EOF -+ } -+ return <<"EOF" if (!$disabled{makedepend}); -+$obj$depext: $deps -+ \$(CC) \$(CFLAGS) $ecflags$inc /Zs /showIncludes $srcs 2>&1 | \\ -+ "\$(PERL)" -n << > $obj$depext -+chomp; -+s/^Note: including file: *//; -+\$\$collect{\$\$_} = 1; -+END { print '$obj$objext: ',join(" ", sort keys \%collect),"\\n" } -+<< -+$obj$objext: $obj$depext -+ \$(CC) $incs \$(CFLAGS) $ecflags -c \$(COUTFLAG)\$\@ @<< -+$srcs -+<< -+EOF -+ return <<"EOF" if ($disabled{makedepend}); -+$obj$objext: $deps -+ \$(CC) $incs \$(CFLAGS) $ecflags -c \$(COUTFLAG)\$\@ $srcs -+EOF -+ } -+ -+ # On Unix, we build shlibs from static libs, so we're ignoring the -+ # object file array. We *know* this routine is only called when we've -+ # configure 'shared'. -+ sub libobj2shlib { -+ my %args = @_; -+ my $lib = $args{lib}; -+ my $shlib = $args{shlib}; -+ (my $mkdef_key = $lib) =~ s/^lib//i; -+ my $objs = join("\n", map { $_.$objext } @{$args{objs}}); -+ my $linklibs = join("", -+ map { "\n$_" } compute_lib_depends(@{$args{deps}})); -+ my $deps = join(" ", -+ (map { $_.$objext } @{$args{objs}}), -+ compute_lib_depends(@{$args{deps}})); -+ my $ordinalsfile = defined($args{ordinals}) ? $args{ordinals}->[1] : ""; -+ my $mkdef_pl = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "util", "mkdef.pl")), -+ rel2abs($config{builddir})); -+ my $mkrc_pl = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "util", "mkrc.pl")), -+ rel2abs($config{builddir})); -+ my $target = shlib_import($lib); -+ return <<"EOF" -+$target: $deps "$ordinalsfile" "$mkdef_pl" -+ "\$(PERL)" "$mkdef_pl" "$mkdef_key" 32 > $shlib.def -+ "\$(PERL)" -i.tmp -pe "s|^LIBRARY\\s+${mkdef_key}32|LIBRARY $shlib|;" $shlib.def -+ DEL $shlib.def.tmp -+ "\$(PERL)" "$mkrc_pl" $shlib$shlibext > $shlib.rc -+ \$(RC) \$(RCOUTFLAG)$shlib.res $shlib.rc -+ IF EXIST $shlib$shlibext.manifest DEL /F /Q $shlib$shlibext.manifest -+ \$(LD) \$(LDFLAGS) \$(LIB_LDFLAGS) \\ -+ /implib:\$@ \$(LDOUTFLAG)$shlib$shlibext /def:$shlib.def @<< || (DEL /Q \$(\@B).* $shlib.* && EXIT 1) -+$objs $shlib.res$linklibs \$(EX_LIBS) -+<< -+ IF EXIST $shlib$shlibext.manifest \\ -+ \$(MT) \$(MTFLAGS) \$(MTINFLAG)$shlib$shlibext.manifest \$(MTOUTFLAG)$shlib$shlibext -+ IF EXIST apps\\$shlib$shlibext DEL /Q /F apps\\$shlib$shlibext -+ IF EXIST test\\$shlib$shlibext DEL /Q /F test\\$shlib$shlibext -+ COPY $shlib$shlibext apps -+ COPY $shlib$shlibext test -+EOF -+ } -+ sub obj2dso { -+ my %args = @_; -+ my $dso = $args{lib}; -+ my $dso_n = basename($dso); -+ my $objs = join("\n", map { $_.$objext } @{$args{objs}}); -+ my $linklibs = join("", -+ map { "\n$_" } compute_lib_depends(@{$args{deps}})); -+ my $deps = join(" ", -+ (map { $_.$objext } @{$args{objs}}), -+ compute_lib_depends(@{$args{deps}})); -+ return <<"EOF"; -+$dso$dsoext: $deps -+ IF EXIST $dso$dsoext.manifest DEL /F /Q $dso$dsoext.manifest -+ \$(LD) \$(LDFLAGS) \$(DSO_LDFLAGS) \$(LDOUTFLAG)$dso$dsoext /def:<< @<< -+LIBRARY $dso_n -+EXPORTS -+ bind_engine @1 -+ v_check @2 -+<< -+$objs$linklibs \$(EX_LIBS) -+<< -+ IF EXIST $dso$dsoext.manifest \\ -+ \$(MT) \$(MTFLAGS) \$(MTINFLAG)$dso$dsoext.manifest \$(MTOUTFLAG)$dso$dsoext -+EOF -+ } -+ sub obj2lib { -+ # Because static libs and import libs are both named the same in native -+ # Windows, we can't have both. We skip the static lib in that case, -+ # as the shared libs are what we use anyway. -+ return "" unless $disabled{"shared"}; -+ -+ my %args = @_; -+ my $lib = $args{lib}; -+ my $objs = join("\n", map { $_.$objext } @{$args{objs}}); -+ my $deps = join(" ", map { $_.$objext } @{$args{objs}}); -+ return <<"EOF"; -+$lib$libext: $deps -+ \$(AR) \$(ARFLAGS) \$(AROUTFLAG)$lib$libext @<< -+\$** -+<< -+EOF -+ } -+ sub obj2bin { -+ my %args = @_; -+ my $bin = $args{bin}; -+ my $objs = join("\n", map { $_.$objext } @{$args{objs}}); -+ my $linklibs = join("", -+ map { "\n$_" } compute_lib_depends(@{$args{deps}})); -+ my $deps = join(" ", -+ (map { $_.$objext } @{$args{objs}}), -+ compute_lib_depends(@{$args{deps}})); -+ return <<"EOF"; -+$bin$exeext: $deps -+ IF EXIST $bin$exeext.manifest DEL /F /Q $bin$exeext.manifest -+ \$(LD) \$(LDFLAGS) \$(BIN_LDFLAGS) \$(LDOUTFLAG)$bin$exeext @<< -+$objs setargv.obj$linklibs \$(EX_LIBS) -+<< -+ IF EXIST $bin$exeext.manifest \\ -+ \$(MT) \$(MTFLAGS) \$(MTINFLAG)$bin$exeext.manifest \$(MTOUTFLAG)$bin$exeext -+EOF -+ } -+ sub in2script { -+ my %args = @_; -+ my $script = $args{script}; -+ my $sources = '"'.join('" "', @{$args{sources}}).'"'; -+ my $dofile = abs2rel(rel2abs(catfile($config{sourcedir}, -+ "util", "dofile.pl")), -+ rel2abs($config{builddir})); -+ return <<"EOF"; -+$script: $sources -+ "\$(PERL)" "-I\$(BLDDIR)" -Mconfigdata "$dofile" \\ -+ "-o$target{build_file}" $sources > "$script" -+EOF -+ } -+ sub generatedir { -+ my %args = @_; -+ my $dir = $args{dir}; -+ my @deps = map { s|\.o$|$objext|; $_ } @{$args{deps}}; -+ my @actions = (); -+ my %extinfo = ( dso => $dsoext, -+ lib => $libext, -+ bin => $exeext ); -+ -+ foreach my $type (("dso", "lib", "bin", "script")) { -+ next unless defined($unified_info{dirinfo}->{$dir}->{products}->{$type}); -+ # For lib object files, we could update the library. However, -+ # LIB on Windows doesn't work that way, so we won't create any -+ # actions for it, and the dependencies are already taken care of. -+ if ($type ne "lib") { -+ foreach my $prod (@{$unified_info{dirinfo}->{$dir}->{products}->{$type}}) { -+ if (dirname($prod) eq $dir) { -+ push @deps, $prod.$extinfo{$type}; -+ } else { -+ push @actions, "\t@rem No support to produce $type ".join(", ", @{$unified_info{dirinfo}->{$dir}->{products}->{$type}}); -+ } -+ } -+ } -+ } -+ -+ my $deps = join(" ", @deps); -+ my $actions = join("\n", "", @actions); -+ return <<"EOF"; -+$args{dir} $args{dir}\\ : $deps$actions -+EOF -+ } -+ "" # Important! This becomes part of the template result. -+-} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Configure b/CryptoPkg/Library/OpensslLib/openssl/Configure -new file mode 100755 -index 0000000..aee7cc3 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Configure -@@ -0,0 +1,2766 @@ -+#! /usr/bin/env perl -+# -*- mode: perl; -*- -+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. -+# -+# Licensed under the OpenSSL license (the "License"). You may not use -+# this file except in compliance with the License. You can obtain a copy -+# in the file LICENSE in the source distribution or at -+# https://www.openssl.org/source/license.html -+ -+## Configure -- OpenSSL source tree configuration script -+ -+require 5.10.0; -+use strict; -+use File::Basename; -+use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/; -+use File::Path qw/mkpath/; -+use if $^O ne "VMS", 'File::Glob' => qw/glob/; -+ -+# see INSTALL for instructions. -+ -+my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n"; -+ -+# Options: -+# -+# --config add the given configuration file, which will be read after -+# any "Configurations*" files that are found in the same -+# directory as this script. -+# --prefix prefix for the OpenSSL installation, which includes the -+# directories bin, lib, include, share/man, share/doc/openssl -+# This becomes the value of INSTALLTOP in Makefile -+# (Default: /usr/local) -+# --openssldir OpenSSL data area, such as openssl.cnf, certificates and keys. -+# If it's a relative directory, it will be added on the directory -+# given with --prefix. -+# This becomes the value of OPENSSLDIR in Makefile and in C. -+# (Default: PREFIX/ssl) -+# -+# --cross-compile-prefix Add specified prefix to binutils components. -+# -+# --api One of 0.9.8, 1.0.0 or 1.1.0. Do not compile support for -+# interfaces deprecated as of the specified OpenSSL version. -+# -+# no-hw-xxx do not compile support for specific crypto hardware. -+# Generic OpenSSL-style methods relating to this support -+# are always compiled but return NULL if the hardware -+# support isn't compiled. -+# no-hw do not compile support for any crypto hardware. -+# [no-]threads [don't] try to create a library that is suitable for -+# multithreaded applications (default is "threads" if we -+# know how to do it) -+# [no-]shared [don't] try to create shared libraries when supported. -+# [no-]pic [don't] try to build position independent code when supported. -+# If disabled, it also disables shared and dynamic-engine. -+# no-asm do not use assembler -+# no-dso do not compile in any native shared-library methods. This -+# will ensure that all methods just return NULL. -+# no-egd do not compile support for the entropy-gathering daemon APIs -+# [no-]zlib [don't] compile support for zlib compression. -+# zlib-dynamic Like "zlib", but the zlib library is expected to be a shared -+# library and will be loaded in run-time by the OpenSSL library. -+# sctp include SCTP support -+# enable-weak-ssl-ciphers -+# Enable weak ciphers that are disabled by default. This currently -+# only includes RC4 based ciphers. -+# 386 generate 80386 code in assembly modules -+# no-sse2 disables IA-32 SSE2 code in assembly modules, the above -+# mentioned '386' option implies this one -+# no- build without specified algorithm (rsa, idea, rc5, ...) -+# - + compiler options are passed through -+# -static while -static is also a pass-through compiler option (and -+# as such is limited to environments where it's actually -+# meaningful), it triggers a number configuration options, -+# namely no-dso, no-pic, no-shared and no-threads. It is -+# argued that the only reason to produce statically linked -+# binaries (and in context it means executables linked with -+# -static flag, and not just executables linked with static -+# libcrypto.a) is to eliminate dependency on specific run-time, -+# a.k.a. libc version. The mentioned config options are meant -+# to achieve just that. Unfortunately on Linux it's impossible -+# to eliminate the dependency completely for openssl executable -+# because of getaddrinfo and gethostbyname calls, which can -+# invoke dynamically loadable library facility anyway to meet -+# the lookup requests. For this reason on Linux statically -+# linked openssl executable has rather debugging value than -+# production quality. -+# -+# DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items -+# provided to stack calls. Generates unique stack functions for -+# each possible stack type. -+# BN_LLONG use the type 'long long' in crypto/bn/bn.h -+# RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h -+# Following are set automatically by this script -+# -+# MD5_ASM use some extra md5 assembler, -+# SHA1_ASM use some extra sha1 assembler, must define L_ENDIAN for x86 -+# RMD160_ASM use some extra ripemd160 assembler, -+# SHA256_ASM sha256_block is implemented in assembler -+# SHA512_ASM sha512_block is implemented in assembler -+# AES_ASM AES_[en|de]crypt is implemented in assembler -+ -+# Minimum warning options... any contributions to OpenSSL should at least get -+# past these. -+ -+# DEBUG_UNUSED enables __owur (warn unused result) checks. -+my $gcc_devteam_warn = "-DDEBUG_UNUSED" -+ # -DPEDANTIC complements -pedantic and is meant to mask code that -+ # is not strictly standard-compliant and/or implementation-specific, -+ # e.g. inline assembly, disregards to alignment requirements, such -+ # that -pedantic would complain about. Incidentally -DPEDANTIC has -+ # to be used even in sanitized builds, because sanitizer too is -+ # supposed to and does take notice of non-standard behaviour. Then -+ # -pedantic with pre-C9x compiler would also complain about 'long -+ # long' not being supported. As 64-bit algorithms are common now, -+ # it grew impossible to resolve this without sizeable additional -+ # code, so we just tell compiler to be pedantic about everything -+ # but 'long long' type. -+ . " -DPEDANTIC -pedantic -Wno-long-long" -+ . " -Wall" -+ . " -Wsign-compare" -+ . " -Wmissing-prototypes" -+ . " -Wshadow" -+ . " -Wformat" -+ . " -Wtype-limits" -+ . " -Werror" -+ ; -+ -+# These are used in addition to $gcc_devteam_warn when the compiler is clang. -+# TODO(openssl-team): fix problems and investigate if (at least) the -+# following warnings can also be enabled: -+# -Wswitch-enum -+# -Wcast-align -+# -Wunreachable-code -+# -Wlanguage-extension-token -- no, we use asm() -+# -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc -+# -Wextended-offsetof -- no, needed in CMS ASN1 code -+my $clang_devteam_warn = "" -+ . " -Qunused-arguments" -+ . " -Wextra" -+ . " -Wno-unused-parameter" -+ . " -Wno-missing-field-initializers" -+ . " -Wno-language-extension-token" -+ . " -Wno-extended-offsetof" -+ . " -Wconditional-uninitialized" -+ . " -Wincompatible-pointer-types-discards-qualifiers" -+ . " -Wmissing-variable-declarations" -+ ; -+ -+# This adds backtrace information to the memory leak info. Is only used -+# when crypto-mdebug-backtrace is enabled. -+my $memleak_devteam_backtrace = "-rdynamic"; -+ -+my $strict_warnings = 0; -+ -+# As for $BSDthreads. Idea is to maintain "collective" set of flags, -+# which would cover all BSD flavors. -pthread applies to them all, -+# but is treated differently. OpenBSD expands is as -D_POSIX_THREAD -+# -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r, -+# which has to be accompanied by explicit -D_THREAD_SAFE and -+# sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which -+# seems to be sufficient? -+our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT"; -+ -+# -+# API compatibility name to version number mapping. -+# -+my $maxapi = "1.1.0"; # API for "no-deprecated" builds -+my $apitable = { -+ "1.1.0" => "0x10100000L", -+ "1.0.0" => "0x10000000L", -+ "0.9.8" => "0x00908000L", -+}; -+ -+our %table = (); -+our %config = (); -+our %withargs = (); -+ -+# Forward declarations ############################################### -+ -+# read_config(filename) -+# -+# Reads a configuration file and populates %table with the contents -+# (which the configuration file places in %targets). -+sub read_config; -+ -+# resolve_config(target) -+# -+# Resolves all the late evaluations, inheritances and so on for the -+# chosen target and any target it inherits from. -+sub resolve_config; -+ -+ -+# Information collection ############################################# -+ -+# Unified build supports separate build dir -+my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax -+my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax -+my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl")); -+ -+my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR'; -+ -+$config{sourcedir} = abs2rel($srcdir); -+$config{builddir} = abs2rel($blddir); -+ -+# Collect reconfiguration information if needed -+my @argvcopy=@ARGV; -+ -+if (grep /^reconf(igure)?$/, @argvcopy) { -+ if (-f "./configdata.pm") { -+ my $file = "./configdata.pm"; -+ unless (my $return = do $file) { -+ die "couldn't parse $file: $@" if $@; -+ die "couldn't do $file: $!" unless defined $return; -+ die "couldn't run $file" unless $return; -+ } -+ -+ @argvcopy = defined($configdata::config{perlargv}) ? -+ @{$configdata::config{perlargv}} : (); -+ die "Incorrect data to reconfigure, please do a normal configuration\n" -+ if (grep(/^reconf/,@argvcopy)); -+ $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix} -+ if defined($configdata::config{cross_compile_prefix}); -+ $ENV{CC} = $configdata::config{cc} -+ if defined($configdata::config{cc}); -+ $ENV{BUILDFILE} = $configdata::config{build_file} -+ if defined($configdata::config{build_file}); -+ $ENV{$local_config_envname} = $configdata::config{local_config_dir} -+ if defined($configdata::config{local_config_dir}); -+ -+ print "Reconfiguring with: ", join(" ",@argvcopy), "\n"; -+ print " CROSS_COMPILE = ",$ENV{CROSS_COMPILE},"\n" -+ if $ENV{CROSS_COMPILE}; -+ print " CC = ",$ENV{CC},"\n" if $ENV{CC}; -+ print " BUILDFILE = ",$ENV{BUILDFILE},"\n" if $ENV{BUILDFILE}; -+ print " $local_config_envname = ",$ENV{$local_config_envname},"\n" -+ if $ENV{$local_config_envname}; -+ } else { -+ die "Insufficient data to reconfigure, please do a normal configuration\n"; -+ } -+} -+ -+$config{perlargv} = [ @argvcopy ]; -+ -+# Collect version numbers -+$config{version} = "unknown"; -+$config{version_num} = "unknown"; -+$config{shlib_version_number} = "unknown"; -+$config{shlib_version_history} = "unknown"; -+ -+collect_information( -+ collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')), -+ qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; }, -+ qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/ => sub { $config{version_num}=$1 }, -+ qr/SHLIB_VERSION_NUMBER *"([^"]+)"/ => sub { $config{shlib_version_number}=$1 }, -+ qr/SHLIB_VERSION_HISTORY *"([^"]*)"/ => sub { $config{shlib_version_history}=$1 } -+ ); -+if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; } -+ -+($config{major}, $config{minor}) -+ = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/); -+($config{shlib_major}, $config{shlib_minor}) -+ = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/); -+die "erroneous version information in opensslv.h: ", -+ "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n" -+ if ($config{major} eq "" || $config{minor} eq "" -+ || $config{shlib_major} eq "" || $config{shlib_minor} eq ""); -+ -+# Collect target configurations -+ -+my $pattern = catfile(dirname($0), "Configurations", "*.conf"); -+foreach (sort glob($pattern)) { -+ &read_config($_); -+} -+ -+if (defined $ENV{$local_config_envname}) { -+ if ($^O eq 'VMS') { -+ # VMS environment variables are logical names, -+ # which can be used as is -+ $pattern = $local_config_envname . ':' . '*.conf'; -+ } else { -+ $pattern = catfile($ENV{$local_config_envname}, '*.conf'); -+ } -+ -+ foreach (sort glob($pattern)) { -+ &read_config($_); -+ } -+} -+ -+ -+print "Configuring OpenSSL version $config{version} ($config{version_num})\n"; -+ -+$config{prefix}=""; -+$config{openssldir}=""; -+$config{processor}=""; -+$config{libdir}=""; -+$config{cross_compile_prefix}=""; -+$config{fipslibdir}="/usr/local/ssl/fips-2.0/lib/"; -+my $nofipscanistercheck=0; -+$config{baseaddr}="0xFB00000"; -+my $auto_threads=1; # enable threads automatically? true by default -+my $default_ranlib; -+$config{fips}=0; -+ -+# Top level directories to build -+$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ]; -+# crypto/ subdirectories to build -+$config{sdirs} = [ -+ "objects", -+ "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", -+ "des", "aes", "rc2", "rc4", "rc5", "idea", "bf", "cast", "camellia", "seed", "chacha", "modes", -+ "bn", "ec", "rsa", "dsa", "dh", "dso", "engine", -+ "buffer", "bio", "stack", "lhash", "rand", "err", -+ "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui", -+ "cms", "ts", "srp", "cmac", "ct", "async", "kdf" -+ ]; -+ -+# Known TLS and DTLS protocols -+my @tls = qw(ssl3 tls1 tls1_1 tls1_2); -+my @dtls = qw(dtls1 dtls1_2); -+ -+# Explicitly known options that are possible to disable. They can -+# be regexps, and will be used like this: /^no-${option}$/ -+# For developers: keep it sorted alphabetically -+ -+my @disablables = ( -+ "afalgeng", -+ "asan", -+ "asm", -+ "async", -+ "autoalginit", -+ "autoerrinit", -+ "bf", -+ "blake2", -+ "camellia", -+ "capieng", -+ "cast", -+ "chacha", -+ "cmac", -+ "cms", -+ "comp", -+ "crypto-mdebug", -+ "crypto-mdebug-backtrace", -+ "ct", -+ "deprecated", -+ "des", -+ "dgram", -+ "dh", -+ "dsa", -+ "dso", -+ "dtls", -+ "dynamic-engine", -+ "ec", -+ "ec2m", -+ "ecdh", -+ "ecdsa", -+ "ec_nistp_64_gcc_128", -+ "egd", -+ "engine", -+ "err", -+ "filenames", -+ "fuzz-libfuzzer", -+ "fuzz-afl", -+ "gost", -+ "heartbeats", -+ "hw(-.+)?", -+ "idea", -+ "makedepend", -+ "md2", -+ "md4", -+ "mdc2", -+ "msan", -+ "multiblock", -+ "nextprotoneg", -+ "ocb", -+ "ocsp", -+ "pic", -+ "poly1305", -+ "posix-io", -+ "psk", -+ "rc2", -+ "rc4", -+ "rc5", -+ "rdrand", -+ "rfc3779", -+ "rmd160", -+ "scrypt", -+ "sctp", -+ "seed", -+ "shared", -+ "sock", -+ "srp", -+ "srtp", -+ "sse2", -+ "ssl", -+ "ssl-trace", -+ "static-engine", -+ "stdio", -+ "threads", -+ "tls", -+ "ts", -+ "ubsan", -+ "ui", -+ "unit-test", -+ "whirlpool", -+ "weak-ssl-ciphers", -+ "zlib", -+ "zlib-dynamic", -+ ); -+foreach my $proto ((@tls, @dtls)) -+ { -+ push(@disablables, $proto); -+ push(@disablables, "$proto-method"); -+ } -+ -+my %deprecated_disablables = ( -+ "ssl2" => undef, -+ "buf-freelists" => undef, -+ "ripemd" => "rmd160" -+ ); -+ -+# All of the following is disabled by default (RC5 was enabled before 0.9.8): -+ -+our %disabled = ( # "what" => "comment" -+ "asan" => "default", -+ "crypto-mdebug" => "default", -+ "crypto-mdebug-backtrace" => "default", -+ "ec_nistp_64_gcc_128" => "default", -+ "egd" => "default", -+ "fuzz-libfuzzer" => "default", -+ "fuzz-afl" => "default", -+ "heartbeats" => "default", -+ "md2" => "default", -+ "msan" => "default", -+ "rc5" => "default", -+ "sctp" => "default", -+ "ssl-trace" => "default", -+ "ssl3" => "default", -+ "ssl3-method" => "default", -+ "ubsan" => "default", -+ "unit-test" => "default", -+ "weak-ssl-ciphers" => "default", -+ "zlib" => "default", -+ "zlib-dynamic" => "default", -+ ); -+ -+# Note: => pair form used for aesthetics, not to truly make a hash table -+my @disable_cascades = ( -+ # "what" => [ "cascade", ... ] -+ sub { $config{processor} eq "386" } -+ => [ "sse2" ], -+ "ssl" => [ "ssl3" ], -+ "ssl3-method" => [ "ssl3" ], -+ "zlib" => [ "zlib-dynamic" ], -+ "des" => [ "mdc2" ], -+ "ec" => [ "ecdsa", "ecdh" ], -+ -+ "dgram" => [ "dtls", "sctp" ], -+ "sock" => [ "dgram" ], -+ "dtls" => [ @dtls ], -+ -+ # SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA -+ "md5" => [ "ssl", "tls1", "tls1_1", "dtls1" ], -+ "sha" => [ "ssl", "tls1", "tls1_1", "dtls1" ], -+ -+ # Additionally, SSL 3.0 requires either RSA or DSA+DH -+ sub { $disabled{rsa} -+ && ($disabled{dsa} || $disabled{dh}); } -+ => [ "ssl" ], -+ -+ # (D)TLS 1.0 and TLS 1.1 also require either RSA or DSA+DH -+ # or ECDSA + ECDH. (D)TLS 1.2 has this requirement as well. -+ # (XXX: We don't support PSK-only builds). -+ sub { $disabled{rsa} -+ && ($disabled{dsa} || $disabled{dh}) -+ && ($disabled{ecdsa} || $disabled{ecdh}); } -+ => [ "tls1", "tls1_1", "tls1_2", -+ "dtls1", "dtls1_2" ], -+ -+ "tls" => [ @tls ], -+ -+ # SRP and HEARTBEATS require TLSEXT -+ "tlsext" => [ "srp", "heartbeats" ], -+ -+ "crypto-mdebug" => [ "crypto-mdebug-backtrace" ], -+ -+ # Without DSO, we can't load dynamic engines, so don't build them dynamic -+ "dso" => [ "dynamic-engine" ], -+ -+ # Without position independent code, there can be no shared libraries or DSOs -+ "pic" => [ "shared" ], -+ "shared" => [ "dynamic-engine" ], -+ "engine" => [ "afalgeng" ], -+ -+ # no-autoalginit is only useful when building non-shared -+ "autoalginit" => [ "shared", "apps" ], -+ -+ "stdio" => [ "apps", "capieng" ], -+ "apps" => [ "tests" ], -+ "comp" => [ "zlib" ], -+ sub { !$disabled{"unit-test"} } => [ "heartbeats" ], -+ -+ sub { !$disabled{"msan"} } => [ "asm" ], -+ ); -+ -+# Avoid protocol support holes. Also disable all versions below N, if version -+# N is disabled while N+1 is enabled. -+# -+my @list = (reverse @tls); -+while ((my $first, my $second) = (shift @list, shift @list)) { -+ last unless @list; -+ push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} } -+ => [ @list ] ); -+ unshift @list, $second; -+} -+my @list = (reverse @dtls); -+while ((my $first, my $second) = (shift @list, shift @list)) { -+ last unless @list; -+ push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} } -+ => [ @list ] ); -+ unshift @list, $second; -+} -+ -+# Explicit "no-..." options will be collected in %disabled along with the defaults. -+# To remove something from %disabled, use "enable-foo". -+# For symmetry, "disable-foo" is a synonym for "no-foo". -+ -+my $no_sse2=0; -+ -+&usage if ($#ARGV < 0); -+ -+my $user_cflags=""; -+my @user_defines=(); -+$config{openssl_api_defines}=[]; -+$config{openssl_algorithm_defines}=[]; -+$config{openssl_thread_defines}=[]; -+$config{openssl_sys_defines}=[]; -+$config{openssl_other_defines}=[]; -+my $libs=""; -+my $target=""; -+$config{options}=""; -+$config{build_type} = "release"; -+ -+my %unsupported_options = (); -+my %deprecated_options = (); -+while (@argvcopy) -+ { -+ $_ = shift @argvcopy; -+ # VMS is a case insensitive environment, and depending on settings -+ # out of our control, we may receive options uppercased. Let's -+ # downcase at least the part before any equal sign. -+ if ($^O eq "VMS") -+ { -+ s/^([^=]*)/lc($1)/e; -+ } -+ s /^-no-/no-/; # some people just can't read the instructions -+ -+ # rewrite some options in "enable-..." form -+ s /^-?-?shared$/enable-shared/; -+ s /^sctp$/enable-sctp/; -+ s /^threads$/enable-threads/; -+ s /^zlib$/enable-zlib/; -+ s /^zlib-dynamic$/enable-zlib-dynamic/; -+ -+ if (/^(no|disable|enable)-(.+)$/) -+ { -+ my $word = $2; -+ if (!exists $deprecated_disablables{$word} -+ && !grep { $word =~ /^${_}$/ } @disablables) -+ { -+ $unsupported_options{$_} = 1; -+ next; -+ } -+ } -+ if (/^no-(.+)$/ || /^disable-(.+)$/) -+ { -+ foreach my $proto ((@tls, @dtls)) -+ { -+ if ($1 eq "$proto-method") -+ { -+ $disabled{"$proto"} = "option($proto-method)"; -+ last; -+ } -+ } -+ if ($1 eq "dtls") -+ { -+ foreach my $proto (@dtls) -+ { -+ $disabled{$proto} = "option(dtls)"; -+ } -+ $disabled{"dtls"} = "option(dtls)"; -+ } -+ elsif ($1 eq "ssl") -+ { -+ # Last one of its kind -+ $disabled{"ssl3"} = "option(ssl)"; -+ } -+ elsif ($1 eq "tls") -+ { -+ # XXX: Tests will fail if all SSL/TLS -+ # protocols are disabled. -+ foreach my $proto (@tls) -+ { -+ $disabled{$proto} = "option(tls)"; -+ } -+ } -+ elsif ($1 eq "static-engine") -+ { -+ delete $disabled{"dynamic-engine"}; -+ } -+ elsif ($1 eq "dynamic-engine") -+ { -+ $disabled{"dynamic-engine"} = "option"; -+ } -+ elsif (exists $deprecated_disablables{$1}) -+ { -+ $deprecated_options{$_} = 1; -+ if (defined $deprecated_disablables{$1}) -+ { -+ $disabled{$deprecated_disablables{$1}} = "option"; -+ } -+ } -+ else -+ { -+ $disabled{$1} = "option"; -+ } -+ # No longer an automatic choice -+ $auto_threads = 0 if ($1 eq "threads"); -+ } -+ elsif (/^enable-(.+)$/) -+ { -+ if ($1 eq "static-engine") -+ { -+ $disabled{"dynamic-engine"} = "option"; -+ } -+ elsif ($1 eq "dynamic-engine") -+ { -+ delete $disabled{"dynamic-engine"}; -+ } -+ elsif ($1 eq "zlib-dynamic") -+ { -+ delete $disabled{"zlib"}; -+ } -+ my $algo = $1; -+ delete $disabled{$algo}; -+ -+ # No longer an automatic choice -+ $auto_threads = 0 if ($1 eq "threads"); -+ } -+ elsif (/^--strict-warnings$/) -+ { -+ $strict_warnings = 1; -+ } -+ elsif (/^--debug$/) -+ { -+ $config{build_type} = "debug"; -+ } -+ elsif (/^--release$/) -+ { -+ $config{build_type} = "release"; -+ } -+ elsif (/^386$/) -+ { $config{processor}=386; } -+ elsif (/^fips$/) -+ { -+ $config{fips}=1; -+ } -+ elsif (/^rsaref$/) -+ { -+ # No RSAref support any more since it's not needed. -+ # The check for the option is there so scripts aren't -+ # broken -+ } -+ elsif (/^nofipscanistercheck$/) -+ { -+ $config{fips} = 1; -+ $nofipscanistercheck = 1; -+ } -+ elsif (/^[-+]/) -+ { -+ if (/^--prefix=(.*)$/) -+ { -+ $config{prefix}=$1; -+ die "Directory given with --prefix MUST be absolute\n" -+ unless file_name_is_absolute($config{prefix}); -+ } -+ elsif (/^--api=(.*)$/) -+ { -+ $config{api}=$1; -+ } -+ elsif (/^--libdir=(.*)$/) -+ { -+ $config{libdir}=$1; -+ } -+ elsif (/^--openssldir=(.*)$/) -+ { -+ $config{openssldir}=$1; -+ } -+ elsif (/^--with-zlib-lib=(.*)$/) -+ { -+ $withargs{zlib_lib}=$1; -+ } -+ elsif (/^--with-zlib-include=(.*)$/) -+ { -+ $withargs{zlib_include}=$1; -+ } -+ elsif (/^--with-fuzzer-lib=(.*)$/) -+ { -+ $withargs{fuzzer_lib}=$1; -+ } -+ elsif (/^--with-fuzzer-include=(.*)$/) -+ { -+ $withargs{fuzzer_include}=$1; -+ } -+ elsif (/^--with-fipslibdir=(.*)$/) -+ { -+ $config{fipslibdir}="$1/"; -+ } -+ elsif (/^--with-baseaddr=(.*)$/) -+ { -+ $config{baseaddr}="$1"; -+ } -+ elsif (/^--cross-compile-prefix=(.*)$/) -+ { -+ $config{cross_compile_prefix}=$1; -+ } -+ elsif (/^--config=(.*)$/) -+ { -+ read_config $1; -+ } -+ elsif (/^-[lL](.*)$/ or /^-Wl,/) -+ { -+ $libs.=$_." "; -+ } -+ elsif (/^-rpath$/ or /^-R$/) -+ # -rpath is the OSF1 rpath flag -+ # -R is the old Solaris rpath flag -+ { -+ my $rpath = shift(@argvcopy) || ""; -+ $rpath .= " " if $rpath ne ""; -+ $libs.=$_." ".$rpath; -+ } -+ elsif (/^-static$/) -+ { -+ $libs.=$_." "; -+ $disabled{"dso"} = "forced"; -+ $disabled{"pic"} = "forced"; -+ $disabled{"shared"} = "forced"; -+ $disabled{"threads"} = "forced"; -+ } -+ elsif (/^-D(.*)$/) -+ { -+ push @user_defines, $1; -+ } -+ else # common if (/^[-+]/), just pass down... -+ { -+ $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei; -+ $user_cflags.=" ".$_; -+ } -+ } -+ else -+ { -+ die "target already defined - $target (offending arg: $_)\n" if ($target ne ""); -+ $target=$_; -+ } -+ unless ($_ eq $target || /^no-/ || /^disable-/) -+ { -+ # "no-..." follows later after implied disactivations -+ # have been derived. (Don't take this too seriously, -+ # we really only write OPTIONS to the Makefile out of -+ # nostalgia.) -+ -+ if ($config{options} eq "") -+ { $config{options} = $_; } -+ else -+ { $config{options} .= " ".$_; } -+ } -+ -+ if (defined($config{api}) && !exists $apitable->{$config{api}}) { -+ die "***** Unsupported api compatibility level: $config{api}\n", -+ } -+ -+ if (keys %deprecated_options) -+ { -+ warn "***** Deprecated options: ", -+ join(", ", keys %deprecated_options), "\n"; -+ } -+ if (keys %unsupported_options) -+ { -+ die "***** Unsupported options: ", -+ join(", ", keys %unsupported_options), "\n"; -+ } -+ } -+ -+if ($libs =~ /(^|\s)-Wl,-rpath,/ -+ && !$disabled{shared} -+ && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) { -+ die "***** Cannot simultaneously use -rpath, shared libraries, and\n", -+ "***** any of asan, msan or ubsan\n"; -+} -+ -+if ($config{fips}) -+ { -+ delete $disabled{"shared"} if ($disabled{"shared"} =~ /^default/); -+ } -+else -+ { -+ @{$config{dirs}} = grep !/^fips$/, @{$config{dirs}}; -+ } -+ -+my @tocheckfor = (keys %disabled); -+while (@tocheckfor) { -+ my %new_tocheckfor = (); -+ my @cascade_copy = (@disable_cascades); -+ while (@cascade_copy) { -+ my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy); -+ if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) { -+ foreach(grep { !defined($disabled{$_}) } @$descendents) { -+ $new_tocheckfor{$_} = 1; $disabled{$_} = "forced"; -+ } -+ } -+ } -+ @tocheckfor = (keys %new_tocheckfor); -+} -+ -+our $die = sub { die @_; }; -+if ($target eq "TABLE") { -+ local $die = sub { warn @_; }; -+ foreach (sort keys %table) { -+ print_table_entry($_, "TABLE"); -+ } -+ exit 0; -+} -+ -+if ($target eq "LIST") { -+ foreach (sort keys %table) { -+ print $_,"\n" unless $table{$_}->{template}; -+ } -+ exit 0; -+} -+ -+if ($target eq "HASH") { -+ local $die = sub { warn @_; }; -+ print "%table = (\n"; -+ foreach (sort keys %table) { -+ print_table_entry($_, "HASH"); -+ } -+ exit 0; -+} -+ -+# Backward compatibility? -+if ($target =~ m/^CygWin32(-.*)$/) { -+ $target = "Cygwin".$1; -+} -+ -+foreach (sort (keys %disabled)) -+ { -+ $config{options} .= " no-$_"; -+ -+ printf " no-%-12s %-10s", $_, "[$disabled{$_}]"; -+ -+ if (/^dso$/) -+ { } -+ elsif (/^threads$/) -+ { } -+ elsif (/^shared$/) -+ { } -+ elsif (/^pic$/) -+ { } -+ elsif (/^zlib$/) -+ { } -+ elsif (/^dynamic-engine$/) -+ { } -+ elsif (/^makedepend$/) -+ { } -+ elsif (/^zlib-dynamic$/) -+ { } -+ elsif (/^sse2$/) -+ { $no_sse2 = 1; } -+ elsif (/^engine$/) -+ { -+ @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}}; -+ @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}}; -+ push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE"; -+ print " OPENSSL_NO_ENGINE (skip engines)"; -+ } -+ else -+ { -+ my ($WHAT, $what); -+ -+ ($WHAT = $what = $_) =~ tr/[\-a-z]/[_A-Z]/; -+ -+ # Fix up C macro end names -+ $WHAT = "RMD160" if $what eq "ripemd"; -+ -+ # fix-up crypto/directory name(s) -+ $what = "ripemd" if $what eq "rmd160"; -+ $what = "whrlpool" if $what eq "whirlpool"; -+ -+ if ($what ne "async" && $what ne "err" -+ && grep { $_ eq $what } @{$config{sdirs}}) -+ { -+ push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$WHAT"; -+ @{$config{sdirs}} = grep { $_ ne $what} @{$config{sdirs}}; -+ -+ print " OPENSSL_NO_$WHAT (skip dir)"; -+ } -+ else -+ { -+ push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT"; -+ print " OPENSSL_NO_$WHAT"; -+ -+ if (/^err$/) { push @user_defines, "OPENSSL_NO_ERR"; } -+ } -+ } -+ -+ print "\n"; -+ } -+ -+print "Configuring for $target\n"; -+ -+# Support for legacy targets having a name starting with 'debug-' -+my ($d, $t) = $target =~ m/^(debug-)?(.*)$/; -+if ($d) { -+ $config{build_type} = "debug"; -+ -+ # If we do not find debug-foo in the table, the target is set to foo. -+ if (!$table{$target}) { -+ $target = $t; -+ } -+} -+$config{target} = $target; -+my %target = resolve_config($target); -+ -+&usage if (!%target || $target{template}); -+ -+my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}}); -+$config{conf_files} = [ sort keys %conf_files ]; -+%target = ( %{$table{DEFAULTS}}, %target ); -+ -+$target{exe_extension}=""; -+$target{exe_extension}=".exe" if ($config{target} eq "DJGPP" -+ || $config{target} =~ /^(?:Cygwin|mingw)/); -+$target{exe_extension}=".pm" if ($config{target} =~ /vos/); -+ -+($target{shared_extension_simple}=$target{shared_extension}) -+ =~ s|\.\$\(SHLIB_MAJOR\)\.\$\(SHLIB_MINOR\)||; -+$target{dso_extension}=$target{shared_extension_simple}; -+($target{shared_import_extension}=$target{shared_extension_simple}.".a") -+ if ($config{target} =~ /^(?:Cygwin|mingw)/); -+ -+ -+$config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'} -+ if $config{cross_compile_prefix} eq ""; -+ -+# Allow overriding the names of some tools. USE WITH CARE -+# Note: only Unix cares about HASHBANGPERL... that explains -+# the default string. -+$config{perl} = $ENV{'PERL'} || ($^O ne "VMS" ? $^X : "perl"); -+$config{hashbangperl} = -+ $ENV{'HASHBANGPERL'} || $ENV{'PERL'} || "/usr/bin/env perl"; -+$target{cc} = $ENV{'CC'} || $target{cc} || "cc"; -+$target{ranlib} = $ENV{'RANLIB'} || $target{ranlib} || -+ (which("$config{cross_compile_prefix}ranlib") ? -+ "\$(CROSS_COMPILE)ranlib" : "true"); -+$target{ar} = $ENV{'AR'} || $target{ar} || "ar"; -+$target{nm} = $ENV{'NM'} || $target{nm} || "nm"; -+$target{rc} = -+ $ENV{'RC'} || $ENV{'WINDRES'} || $target{rc} || "windres"; -+ -+# Allow overriding the build file name -+$target{build_file} = $ENV{BUILDFILE} || $target{build_file} || "Makefile"; -+ -+# Cache information necessary for reconfiguration -+$config{cc} = $target{cc}; -+$config{build_file} = $target{build_file}; -+ -+# For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_ -+# or release_ attributes. -+# Do it in such a way that no spurious space is appended (hence the grep). -+$config{defines} = []; -+$config{cflags} = ""; -+$config{ex_libs} = ""; -+$config{shared_ldflag} = ""; -+ -+# Make sure build_scheme is consistent. -+$target{build_scheme} = [ $target{build_scheme} ] -+ if ref($target{build_scheme}) ne "ARRAY"; -+ -+my ($builder, $builder_platform, @builder_opts) = -+ @{$target{build_scheme}}; -+ -+push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release"; -+ -+if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m) -+ { -+ $config{cflags} .= " -mno-cygwin"; -+ $config{shared_ldflag} .= " -mno-cygwin"; -+ } -+ -+if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) { -+ # minimally required architecture flags for assembly modules -+ $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/); -+ $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/); -+} -+ -+my $no_shared_warn=0; -+my $no_user_cflags=0; -+my $no_user_defines=0; -+ -+# The DSO code currently always implements all functions so that no -+# applications will have to worry about that from a compilation point -+# of view. However, the "method"s may return zero unless that platform -+# has support compiled in for them. Currently each method is enabled -+# by a define "DSO_" ... we translate the "dso_scheme" config -+# string entry into using the following logic; -+if (!$disabled{dso} && $target{dso_scheme} ne "") -+ { -+ $target{dso_scheme} =~ tr/[a-z]/[A-Z]/; -+ if ($target{dso_scheme} eq "DLFCN") -+ { -+ unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H"; -+ } -+ elsif ($target{dso_scheme} eq "DLFCN_NO_H") -+ { -+ unshift @{$config{defines}}, "DSO_DLFCN"; -+ } -+ else -+ { -+ unshift @{$config{defines}}, "DSO_$target{dso_scheme}"; -+ } -+ } -+ -+$config{ex_libs}="$libs$config{ex_libs}" if ($libs ne ""); -+ -+if ($disabled{asm}) -+ { -+ if ($config{fips}) -+ { -+ @{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}}; -+ @{$target{defines}} = grep !/^[BL]_ENDIAN$/, @{$target{defines}}; -+ } -+ } -+ -+# If threads aren't disabled, check how possible they are -+unless ($disabled{threads}) { -+ if ($auto_threads) { -+ # Enabled by default, disable it forcibly if unavailable -+ if ($target{thread_scheme} eq "(unknown)") { -+ $disabled{threads} = "unavailable"; -+ } -+ } else { -+ # The user chose to enable threads explicitly, let's see -+ # if there's a chance that's possible -+ if ($target{thread_scheme} eq "(unknown)") { -+ # If the user asked for "threads" and we don't have internal -+ # knowledge how to do it, [s]he is expected to provide any -+ # system-dependent compiler options that are necessary. We -+ # can't truly check that the given options are correct, but -+ # we expect the user to know what [s]He is doing. -+ if ($no_user_cflags && $no_user_defines) { -+ die "You asked for multi-threading support, but didn't\n" -+ ,"provide any system-specific compiler options\n"; -+ } -+ } -+ } -+} -+ -+# If threads still aren't disabled, add a C macro to ensure the source -+# code knows about it. Any other flag is taken care of by the configs. -+unless($disabled{threads}) { -+ foreach (("defines", "openssl_thread_defines")) { -+ push @{$config{$_}}, "OPENSSL_THREADS"; -+ } -+} -+ -+# With "deprecated" disable all deprecated features. -+if (defined($disabled{"deprecated"})) { -+ $config{api} = $maxapi; -+} -+ -+if ($target{shared_target} eq "") -+ { -+ $no_shared_warn = 1 -+ if ((!$disabled{shared} || !$disabled{"dynamic-engine"}) -+ && !$config{fips}); -+ $disabled{shared} = "no-shared-target"; -+ $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} = -+ "no-shared-target"; -+ } -+ -+if ($disabled{"dynamic-engine"}) { -+ push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE"; -+ $config{dynamic_engines} = 0; -+} else { -+ push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE"; -+ $config{dynamic_engines} = 1; -+} -+ -+unless ($disabled{"fuzz-libfuzzer"}) { -+ $config{cflags} .= "-fsanitize-coverage=edge,indirect-calls "; -+} -+ -+unless ($disabled{asan}) { -+ $config{cflags} .= "-fsanitize=address "; -+} -+ -+unless ($disabled{ubsan}) { -+ # -DPEDANTIC or -fnosanitize=alignment may also be required on some -+ # platforms. -+ $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all "; -+} -+ -+unless ($disabled{msan}) { -+ $config{cflags} .= "-fsanitize=memory "; -+} -+ -+unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"} -+ && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) { -+ $config{cflags} .= "-fno-omit-frame-pointer -g "; -+} -+# -+# Platform fix-ups -+# -+ -+# This saves the build files from having to check -+if ($disabled{pic}) -+ { -+ $target{shared_cflag} = $target{shared_ldflag} = -+ $target{shared_rcflag} = ""; -+ } -+else -+ { -+ push @{$config{defines}}, "OPENSSL_PIC"; -+ } -+ -+if ($target{sys_id} ne "") -+ { -+ push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}"; -+ } -+ -+unless ($disabled{asm}) { -+ $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386"); -+ $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m})); -+ -+ # bn-586 is the only one implementing bn_*_part_words -+ push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/); -+ push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/); -+ -+ push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/); -+ push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/); -+ push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/); -+ -+ if ($config{fips}) { -+ push @{$config{openssl_other_defines}}, "OPENSSL_FIPS"; -+ } -+ -+ if ($target{sha1_asm_src}) { -+ push @{$config{defines}}, "SHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/); -+ push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/); -+ push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/); -+ } -+ if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) { -+ push @{$config{defines}}, "RC4_ASM"; -+ } -+ if ($target{md5_asm_src}) { -+ push @{$config{defines}}, "MD5_ASM"; -+ } -+ $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC -+ if ($target{rmd160_asm_src}) { -+ push @{$config{defines}}, "RMD160_ASM"; -+ } -+ if ($target{aes_asm_src}) { -+ push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);; -+ # aes-ctr.fake is not a real file, only indication that assembler -+ # module implements AES_ctr32_encrypt... -+ push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//); -+ # aes-xts.fake indicates presence of AES_xts_[en|de]crypt... -+ push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//); -+ $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2); -+ push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/); -+ push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/); -+ } -+ if ($target{wp_asm_src} =~ /mmx/) { -+ if ($config{processor} eq "386") { -+ $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src}; -+ } elsif (!$disabled{"whirlpool"}) { -+ push @{$config{defines}}, "WHIRLPOOL_ASM"; -+ } -+ } -+ if ($target{modes_asm_src} =~ /ghash-/) { -+ push @{$config{defines}}, "GHASH_ASM"; -+ } -+ if ($target{ec_asm_src} =~ /ecp_nistz256/) { -+ push @{$config{defines}}, "ECP_NISTZ256_ASM"; -+ } -+ if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) { -+ push @{$config{defines}}, "PADLOCK_ASM"; -+ } -+ if ($target{poly1305_asm_src} ne "") { -+ push @{$config{defines}}, "POLY1305_ASM"; -+ } -+} -+ -+my $ecc = $target{cc}; -+if ($^O ne "VMS" && !$disabled{makedepend}) { -+ # Is the compiler gcc or clang? $ecc is used below to see if -+ # error-checking can be turned on. -+ my $ccpcc = "$config{cross_compile_prefix}$target{cc}"; -+ open(PIPE, "$ccpcc --version 2>&1 |"); -+ my $lines = 2; -+ while ( ) { -+ # Find the version number and save the major. -+ m|(?:.*)\b(\d+)\.\d+\.\d+\b(?:.*)|; -+ my $compiler_major = $1; -+ # We know that GNU C version 3 and up as well as all clang -+ # versions support dependency generation -+ $config{makedepprog} = $ccpcc -+ if (/clang/ || (/gcc/ && $compiler_major >= 3)); -+ $ecc = "clang" if /clang/; -+ $ecc = "gcc" if /gcc/; -+ last if ($config{makedepprog} || !$lines--); -+ } -+ close(PIPE); -+ -+ $config{makedepprog} = which('makedepend') unless $config{makedepprog}; -+ $disabled{makedepend} = "unavailable" unless $config{makedepprog}; -+} -+ -+ -+ -+# Deal with bn_ops ################################################### -+ -+$config{bn_ll} =0; -+$config{export_var_as_fn} =0; -+my $def_int="unsigned int"; -+$config{rc4_int} =$def_int; -+($config{b64l},$config{b64},$config{b32})=(0,0,1); -+ -+my $count = 0; -+foreach (sort split(/\s+/,$target{bn_ops})) { -+ $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/; -+ $config{export_var_as_fn}=1 if $_ eq 'EXPORT_VAR_AS_FN'; -+ $config{bn_ll}=1 if $_ eq 'BN_LLONG'; -+ $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR'; -+ ($config{b64l},$config{b64},$config{b32}) -+ =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT'; -+ ($config{b64l},$config{b64},$config{b32}) -+ =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG'; -+ ($config{b64l},$config{b64},$config{b32}) -+ =(0,0,1) if $_ eq 'THIRTY_TWO_BIT'; -+} -+die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n" -+ if $count > 1; -+ -+ -+# Hack cflags for better warnings (dev option) ####################### -+ -+# "Stringify" the C flags string. This permits it to be made part of a string -+# and works as well on command lines. -+$config{cflags} =~ s/([\\\"])/\\$1/g; -+ -+if (defined($config{api})) { -+ $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ]; -+ my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}}); -+ push @{$config{defines}}, $apiflag; -+} -+ -+if ($strict_warnings) -+ { -+ my $wopt; -+ die "ERROR --strict-warnings requires gcc or clang" -+ unless $ecc eq 'gcc' || $ecc eq 'clang'; -+ foreach $wopt (split /\s+/, $gcc_devteam_warn) -+ { -+ $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/) -+ } -+ if ($ecc eq "clang") -+ { -+ foreach $wopt (split /\s+/, $clang_devteam_warn) -+ { -+ $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/) -+ } -+ } -+ } -+ -+unless ($disabled{"crypto-mdebug-backtrace"}) -+ { -+ foreach my $wopt (split /\s+/, $memleak_devteam_backtrace) -+ { -+ $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/) -+ } -+ if ($target =~ /^BSD-/) -+ { -+ $config{ex_libs} .= " -lexecinfo"; -+ } -+ } -+ -+if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; } -+else { $no_user_cflags=1; } -+if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; } -+else { $no_user_defines=1; } -+ -+# ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON -+ -+unless ($disabled{afalgeng}) { -+ $config{afalgeng}=""; -+ if ($target =~ m/^linux/) { -+ my $minver = 4*10000 + 1*100 + 0; -+ if ($config{cross_compile_prefix} eq "") { -+ my $verstr = `uname -r`; -+ my ($ma, $mi1, $mi2) = split("\\.", $verstr); -+ ($mi2) = $mi2 =~ /(\d+)/; -+ my $ver = $ma*10000 + $mi1*100 + $mi2; -+ if ($ver < $minver) { -+ $disabled{afalgeng} = "too-old-kernel"; -+ } else { -+ push @{$config{engdirs}}, "afalg"; -+ } -+ } else { -+ $disabled{afalgeng} = "cross-compiling"; -+ } -+ } else { -+ $disabled{afalgeng} = "not-linux"; -+ } -+} -+ -+push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng}); -+ -+# If we use the unified build, collect information from build.info files -+my %unified_info = (); -+ -+my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO}); -+if ($builder eq "unified") { -+ use lib catdir(dirname(__FILE__),"util"); -+ use with_fallback qw(Text::Template); -+ -+ sub cleandir { -+ my $base = shift; -+ my $dir = shift; -+ my $relativeto = shift || "."; -+ -+ $dir = catdir($base,$dir) unless isabsolute($dir); -+ -+ # Make sure the directories we're building in exists -+ mkpath($dir); -+ -+ my $res = abs2rel(absolutedir($dir), rel2abs($relativeto)); -+ #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n"; -+ return $res; -+ } -+ -+ sub cleanfile { -+ my $base = shift; -+ my $file = shift; -+ my $relativeto = shift || "."; -+ -+ $file = catfile($base,$file) unless isabsolute($file); -+ -+ my $d = dirname($file); -+ my $f = basename($file); -+ -+ # Make sure the directories we're building in exists -+ mkpath($d); -+ -+ my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto)); -+ #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n"; -+ return $res; -+ } -+ -+ # Store the name of the template file we will build the build file from -+ # in %config. This may be useful for the build file itself. -+ my @build_file_template_names = -+ ( $builder_platform."-".$target{build_file}.".tmpl", -+ $target{build_file}.".tmpl" ); -+ my @build_file_templates = (); -+ -+ # First, look in the user provided directory, if given -+ if (defined $ENV{$local_config_envname}) { -+ @build_file_templates = -+ map { -+ if ($^O eq 'VMS') { -+ # VMS environment variables are logical names, -+ # which can be used as is -+ $local_config_envname . ':' . $_; -+ } else { -+ catfile($ENV{$local_config_envname}, $_); -+ } -+ } -+ @build_file_template_names; -+ } -+ # Then, look in our standard directory -+ push @build_file_templates, -+ ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) } -+ @build_file_template_names ); -+ -+ my $build_file_template; -+ for $_ (@build_file_templates) { -+ $build_file_template = $_; -+ last if -f $build_file_template; -+ -+ $build_file_template = undef; -+ } -+ if (!defined $build_file_template) { -+ die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n"; -+ } -+ $config{build_file_templates} -+ = [ $build_file_template, -+ cleanfile($srcdir, catfile("Configurations", "common.tmpl"), -+ $blddir) ]; -+ -+ my @build_infos = ( [ ".", "build.info" ] ); -+ foreach (@{$config{dirs}}) { -+ push @build_infos, [ $_, "build.info" ] -+ if (-f catfile($srcdir, $_, "build.info")); -+ } -+ foreach (@{$config{sdirs}}) { -+ push @build_infos, [ catdir("crypto", $_), "build.info" ] -+ if (-f catfile($srcdir, "crypto", $_, "build.info")); -+ } -+ foreach (@{$config{engdirs}}) { -+ push @build_infos, [ catdir("engines", $_), "build.info" ] -+ if (-f catfile($srcdir, "engines", $_, "build.info")); -+ } -+ -+ $config{build_infos} = [ ]; -+ -+ foreach (@build_infos) { -+ my $sourced = catdir($srcdir, $_->[0]); -+ my $buildd = catdir($blddir, $_->[0]); -+ -+ mkpath($buildd); -+ -+ my $f = $_->[1]; -+ # The basic things we're trying to build -+ my @programs = (); -+ my @programs_install = (); -+ my @libraries = (); -+ my @libraries_install = (); -+ my @engines = (); -+ my @engines_install = (); -+ my @scripts = (); -+ my @scripts_install = (); -+ my @extra = (); -+ my @overrides = (); -+ my @intermediates = (); -+ my @rawlines = (); -+ -+ my %ordinals = (); -+ my %sources = (); -+ my %shared_sources = (); -+ my %includes = (); -+ my %depends = (); -+ my %renames = (); -+ my %sharednames = (); -+ my %generate = (); -+ -+ push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f); -+ my $template = Text::Template->new(TYPE => 'FILE', -+ SOURCE => catfile($sourced, $f)); -+ die "Something went wrong with $sourced/$f: $!\n" unless $template; -+ my @text = -+ split /^/m, -+ $template->fill_in(HASH => { config => \%config, -+ target => \%target, -+ disabled => \%disabled, -+ withargs => \%withargs, -+ builddir => abs2rel($buildd, $blddir), -+ sourcedir => abs2rel($sourced, $blddir), -+ buildtop => abs2rel($blddir, $blddir), -+ sourcetop => abs2rel($srcdir, $blddir) }, -+ DELIMITERS => [ "{-", "-}" ]); -+ -+ # The top item of this stack has the following values -+ # -2 positive already run and we found ELSE (following ELSIF should fail) -+ # -1 positive already run (skip until ENDIF) -+ # 0 negatives so far (if we're at a condition, check it) -+ # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF) -+ # 2 positive ELSE (following ELSIF should fail) -+ my @skip = (); -+ collect_information( -+ collect_from_array([ @text ], -+ qr/\\$/ => sub { my $l1 = shift; my $l2 = shift; -+ $l1 =~ s/\\$//; $l1.$l2 }), -+ # Info we're looking for -+ qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/ -+ => sub { -+ if (! @skip || $skip[$#skip] > 0) { -+ push @skip, !! $1; -+ } else { -+ push @skip, -1; -+ } -+ }, -+ qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/ -+ => sub { die "ELSIF out of scope" if ! @skip; -+ die "ELSIF following ELSE" if abs($skip[$#skip]) == 2; -+ $skip[$#skip] = -1 if $skip[$#skip] != 0; -+ $skip[$#skip] = !! $1 -+ if $skip[$#skip] == 0; }, -+ qr/^\s*ELSE\s*$/ -+ => sub { die "ELSE out of scope" if ! @skip; -+ $skip[$#skip] = -2 if $skip[$#skip] != 0; -+ $skip[$#skip] = 2 if $skip[$#skip] == 0; }, -+ qr/^\s*ENDIF\s*$/ -+ => sub { die "ENDIF out of scope" if ! @skip; -+ pop @skip; }, -+ qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/ -+ => sub { -+ if (!@skip || $skip[$#skip] > 0) { -+ my $install = $1; -+ my @x = tokenize($2); -+ push @programs, @x; -+ push @programs_install, @x unless $install; -+ } -+ }, -+ qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/ -+ => sub { -+ if (!@skip || $skip[$#skip] > 0) { -+ my $install = $1; -+ my @x = tokenize($2); -+ push @libraries, @x; -+ push @libraries_install, @x unless $install; -+ } -+ }, -+ qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/ -+ => sub { -+ if (!@skip || $skip[$#skip] > 0) { -+ my $install = $1; -+ my @x = tokenize($2); -+ push @engines, @x; -+ push @engines_install, @x unless $install; -+ } -+ }, -+ qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/ -+ => sub { -+ if (!@skip || $skip[$#skip] > 0) { -+ my $install = $1; -+ my @x = tokenize($2); -+ push @scripts, @x; -+ push @scripts_install, @x unless $install; -+ } -+ }, -+ qr/^\s*EXTRA\s*=\s*(.*)\s*$/ -+ => sub { push @extra, tokenize($1) -+ if !@skip || $skip[$#skip] > 0 }, -+ qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/ -+ => sub { push @overrides, tokenize($1) -+ if !@skip || $skip[$#skip] > 0 }, -+ -+ qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/, -+ => sub { push @{$ordinals{$1}}, tokenize($2) -+ if !@skip || $skip[$#skip] > 0 }, -+ qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ -+ => sub { push @{$sources{$1}}, tokenize($2) -+ if !@skip || $skip[$#skip] > 0 }, -+ qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ -+ => sub { push @{$shared_sources{$1}}, tokenize($2) -+ if !@skip || $skip[$#skip] > 0 }, -+ qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ -+ => sub { push @{$includes{$1}}, tokenize($2) -+ if !@skip || $skip[$#skip] > 0 }, -+ qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/ -+ => sub { push @{$depends{$1}}, tokenize($2) -+ if !@skip || $skip[$#skip] > 0 }, -+ qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ -+ => sub { push @{$generate{$1}}, $2 -+ if !@skip || $skip[$#skip] > 0 }, -+ qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ -+ => sub { push @{$renames{$1}}, tokenize($2) -+ if !@skip || $skip[$#skip] > 0 }, -+ qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ -+ => sub { push @{$sharednames{$1}}, tokenize($2) -+ if !@skip || $skip[$#skip] > 0 }, -+ qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/ -+ => sub { -+ my $lineiterator = shift; -+ my $target_kind = $1; -+ while (defined $lineiterator->()) { -+ s|\R$||; -+ if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) { -+ die "ENDRAW doesn't match BEGINRAW" -+ if $1 ne $target_kind; -+ last; -+ } -+ next if @skip && $skip[$#skip] <= 0; -+ push @rawlines, $_ -+ if ($target_kind eq $target{build_file} -+ || $target_kind eq $target{build_file}."(".$builder_platform.")"); -+ } -+ }, -+ qr/^(?:#.*|\s*)$/ => sub { }, -+ "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }, -+ "BEFORE" => sub { -+ if ($buildinfo_debug) { -+ print STDERR "DEBUG: Parsing ",join(" ", @_),"\n"; -+ print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n"; -+ } -+ }, -+ "AFTER" => sub { -+ if ($buildinfo_debug) { -+ print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n"; -+ } -+ }, -+ ); -+ die "runaway IF?" if (@skip); -+ -+ foreach (keys %renames) { -+ die "$_ renamed to more than one thing: " -+ ,join(" ", @{$renames{$_}}),"\n" -+ if scalar @{$renames{$_}} > 1; -+ my $dest = cleanfile($buildd, $_, $blddir); -+ my $to = cleanfile($buildd, $renames{$_}->[0], $blddir); -+ die "$dest renamed to more than one thing: " -+ ,$unified_info{rename}->{$dest}, $to -+ unless !defined($unified_info{rename}->{$dest}) -+ or $unified_info{rename}->{$dest} eq $to; -+ $unified_info{rename}->{$dest} = $to; -+ } -+ -+ foreach (@programs) { -+ my $program = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$program}) { -+ $program = $unified_info{rename}->{$program}; -+ } -+ $unified_info{programs}->{$program} = 1; -+ } -+ -+ foreach (@programs_install) { -+ my $program = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$program}) { -+ $program = $unified_info{rename}->{$program}; -+ } -+ $unified_info{install}->{programs}->{$program} = 1; -+ } -+ -+ foreach (@libraries) { -+ my $library = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$library}) { -+ $library = $unified_info{rename}->{$library}; -+ } -+ $unified_info{libraries}->{$library} = 1; -+ } -+ -+ foreach (@libraries_install) { -+ my $library = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$library}) { -+ $library = $unified_info{rename}->{$library}; -+ } -+ $unified_info{install}->{libraries}->{$library} = 1; -+ } -+ -+ die <<"EOF" if scalar @engines and !$config{dynamic_engines}; -+ENGINES can only be used if configured with 'dynamic-engine'. -+This is usually a fault in a build.info file. -+EOF -+ foreach (@engines) { -+ my $library = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$library}) { -+ $library = $unified_info{rename}->{$library}; -+ } -+ $unified_info{engines}->{$library} = 1; -+ } -+ -+ foreach (@engines_install) { -+ my $library = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$library}) { -+ $library = $unified_info{rename}->{$library}; -+ } -+ $unified_info{install}->{engines}->{$library} = 1; -+ } -+ -+ foreach (@scripts) { -+ my $script = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$script}) { -+ $script = $unified_info{rename}->{$script}; -+ } -+ $unified_info{scripts}->{$script} = 1; -+ } -+ -+ foreach (@scripts_install) { -+ my $script = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$script}) { -+ $script = $unified_info{rename}->{$script}; -+ } -+ $unified_info{install}->{scripts}->{$script} = 1; -+ } -+ -+ foreach (@extra) { -+ my $extra = cleanfile($buildd, $_, $blddir); -+ $unified_info{extra}->{$extra} = 1; -+ } -+ -+ foreach (@overrides) { -+ my $override = cleanfile($buildd, $_, $blddir); -+ $unified_info{overrides}->{$override} = 1; -+ } -+ -+ push @{$unified_info{rawlines}}, @rawlines; -+ -+ unless ($disabled{shared}) { -+ # Check sharednames. -+ foreach (keys %sharednames) { -+ my $dest = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$dest}) { -+ $dest = $unified_info{rename}->{$dest}; -+ } -+ die "shared_name for $dest with multiple values: " -+ ,join(" ", @{$sharednames{$_}}),"\n" -+ if scalar @{$sharednames{$_}} > 1; -+ my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir); -+ die "shared_name found for a library $dest that isn't defined\n" -+ unless $unified_info{libraries}->{$dest}; -+ die "shared_name for $dest with multiple values: " -+ ,$unified_info{sharednames}->{$dest}, ", ", $to -+ unless !defined($unified_info{sharednames}->{$dest}) -+ or $unified_info{sharednames}->{$dest} eq $to; -+ $unified_info{sharednames}->{$dest} = $to; -+ } -+ -+ # Additionally, we set up sharednames for libraries that don't -+ # have any, as themselves. -+ foreach (keys %{$unified_info{libraries}}) { -+ if (!defined $unified_info{sharednames}->{$_}) { -+ $unified_info{sharednames}->{$_} = $_ -+ } -+ } -+ } -+ -+ foreach (keys %ordinals) { -+ my $dest = $_; -+ my $ddest = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$ddest}) { -+ $ddest = $unified_info{rename}->{$ddest}; -+ } -+ foreach (@{$ordinals{$dest}}) { -+ my %known_ordinals = -+ ( -+ crypto => -+ cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir), -+ ssl => -+ cleanfile($sourced, catfile("util", "libssl.num"), $blddir) -+ ); -+ my $o = $known_ordinals{$_}; -+ die "Ordinals for $ddest defined more than once\n" -+ if $unified_info{ordinals}->{$ddest}; -+ $unified_info{ordinals}->{$ddest} = [ $_, $o ]; -+ } -+ } -+ -+ foreach (keys %sources) { -+ my $dest = $_; -+ my $ddest = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$ddest}) { -+ $ddest = $unified_info{rename}->{$ddest}; -+ } -+ foreach (@{$sources{$dest}}) { -+ my $s = cleanfile($sourced, $_, $blddir); -+ -+ # If it isn't in the source tree, we assume it's generated -+ # in the build tree -+ if (! -f $s) { -+ $s = cleanfile($buildd, $_, $blddir); -+ } -+ # We recognise C and asm files -+ if ($s =~ /\.[csS]\b$/) { -+ (my $o = $_) =~ s/\.[csS]\b$/.o/; -+ $o = cleanfile($buildd, $o, $blddir); -+ $unified_info{sources}->{$ddest}->{$o} = 1; -+ $unified_info{sources}->{$o}->{$s} = 1; -+ } else { -+ $unified_info{sources}->{$ddest}->{$s} = 1; -+ } -+ } -+ } -+ -+ foreach (keys %shared_sources) { -+ my $dest = $_; -+ my $ddest = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$ddest}) { -+ $ddest = $unified_info{rename}->{$ddest}; -+ } -+ foreach (@{$shared_sources{$dest}}) { -+ my $s = cleanfile($sourced, $_, $blddir); -+ -+ # If it isn't in the source tree, we assume it's generated -+ # in the build tree -+ if (! -f $s) { -+ $s = cleanfile($buildd, $_, $blddir); -+ } -+ # We recognise C and asm files -+ if ($s =~ /\.[csS]\b$/) { -+ (my $o = $_) =~ s/\.[csS]\b$/.o/; -+ $o = cleanfile($buildd, $o, $blddir); -+ $unified_info{shared_sources}->{$ddest}->{$o} = 1; -+ $unified_info{sources}->{$o}->{$s} = 1; -+ } else { -+ die "unrecognised source file type for shared library: $s\n"; -+ } -+ } -+ } -+ -+ foreach (keys %generate) { -+ my $dest = $_; -+ my $ddest = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$ddest}) { -+ $ddest = $unified_info{rename}->{$ddest}; -+ } -+ die "more than one generator for $dest: " -+ ,join(" ", @{$generate{$_}}),"\n" -+ if scalar @{$generate{$_}} > 1; -+ my @generator = split /\s+/, $generate{$dest}->[0]; -+ $generator[0] = cleanfile($sourced, $generator[0], $blddir), -+ $unified_info{generate}->{$ddest} = [ @generator ]; -+ } -+ -+ foreach (keys %depends) { -+ my $dest = $_; -+ my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir); -+ -+ # If the destination doesn't exist in source, it can only be -+ # a generated file in the build tree. -+ if ($ddest ne "" && ! -f $ddest) { -+ $ddest = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$ddest}) { -+ $ddest = $unified_info{rename}->{$ddest}; -+ } -+ } -+ foreach (@{$depends{$dest}}) { -+ my $d = cleanfile($sourced, $_, $blddir); -+ -+ # If we know it's generated, or assume it is because we can't -+ # find it in the source tree, we set file we depend on to be -+ # in the build tree rather than the source tree, and assume -+ # and that there are lines to build it in a BEGINRAW..ENDRAW -+ # section or in the Makefile template. -+ if (! -f $d -+ || (grep { $d eq $_ } -+ map { cleanfile($srcdir, $_, $blddir) } -+ grep { /\.h$/ } keys %{$unified_info{generate}})) { -+ $d = cleanfile($buildd, $_, $blddir); -+ } -+ # Take note if the file to depend on is being renamed -+ if ($unified_info{rename}->{$d}) { -+ $d = $unified_info{rename}->{$d}; -+ } -+ $unified_info{depends}->{$ddest}->{$d} = 1; -+ # If we depend on a header file or a perl module, let's make -+ # sure it can get included -+ if ($dest ne "" && $d =~ /\.(h|pm)$/) { -+ my $i = dirname($d); -+ push @{$unified_info{includes}->{$ddest}->{source}}, $i -+ unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}->{source}}; -+ } -+ } -+ } -+ -+ foreach (keys %includes) { -+ my $dest = $_; -+ my $ddest = cleanfile($sourced, $_, $blddir); -+ -+ # If the destination doesn't exist in source, it can only be -+ # a generated file in the build tree. -+ if (! -f $ddest) { -+ $ddest = cleanfile($buildd, $_, $blddir); -+ if ($unified_info{rename}->{$ddest}) { -+ $ddest = $unified_info{rename}->{$ddest}; -+ } -+ } -+ foreach (@{$includes{$dest}}) { -+ my $is = cleandir($sourced, $_, $blddir); -+ my $ib = cleandir($buildd, $_, $blddir); -+ push @{$unified_info{includes}->{$ddest}->{source}}, $is -+ unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}}; -+ push @{$unified_info{includes}->{$ddest}->{build}}, $ib -+ unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}}; -+ } -+ } -+ } -+ -+ ### Make unified_info a bit more efficient -+ # One level structures -+ foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) { -+ $unified_info{$_} = [ sort keys %{$unified_info{$_}} ]; -+ } -+ # Two level structures -+ foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) { -+ foreach my $l2 (sort keys %{$unified_info{$l1}}) { -+ $unified_info{$l1}->{$l2} = -+ [ sort keys %{$unified_info{$l1}->{$l2}} ]; -+ } -+ } -+ # Includes -+ foreach my $dest (sort keys %{$unified_info{includes}}) { -+ if (defined($unified_info{includes}->{$dest}->{build})) { -+ my @source_includes = -+ ( @{$unified_info{includes}->{$dest}->{source}} ); -+ $unified_info{includes}->{$dest} = -+ [ @{$unified_info{includes}->{$dest}->{build}} ]; -+ foreach my $inc (@source_includes) { -+ push @{$unified_info{includes}->{$dest}}, $inc -+ unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}}; -+ } -+ } else { -+ $unified_info{includes}->{$dest} = -+ [ @{$unified_info{includes}->{$dest}->{source}} ]; -+ } -+ } -+} -+ -+# For the schemes that need it, we provide the old *_obj configs -+# from the *_asm_obj ones -+foreach (grep /_(asm|aux)_src$/, keys %target) { -+ my $src = $_; -+ (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/; -+ ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g; -+} -+ -+# Write down our configuration where it fits ######################### -+ -+open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n"; -+print OUT <<"EOF"; -+package configdata; -+ -+use strict; -+use warnings; -+ -+use Exporter; -+#use vars qw(\@ISA \@EXPORT); -+our \@ISA = qw(Exporter); -+our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables); -+ -+EOF -+print OUT "our %config = (\n"; -+foreach (sort keys %config) { -+ if (ref($config{$_}) eq "ARRAY") { -+ print OUT " ", $_, " => [ ", join(", ", -+ map { quotify("perl", $_) } -+ @{$config{$_}}), " ],\n"; -+ } else { -+ print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n" -+ } -+} -+print OUT <<"EOF"; -+); -+ -+EOF -+print OUT "our %target = (\n"; -+foreach (sort keys %target) { -+ if (ref($target{$_}) eq "ARRAY") { -+ print OUT " ", $_, " => [ ", join(", ", -+ map { quotify("perl", $_) } -+ @{$target{$_}}), " ],\n"; -+ } else { -+ print OUT " ", $_, " => ", quotify("perl", $target{$_}), ",\n" -+ } -+} -+print OUT <<"EOF"; -+); -+ -+EOF -+print OUT "our \%available_protocols = (\n"; -+print OUT " tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n"; -+print OUT " dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n"; -+print OUT <<"EOF"; -+); -+ -+EOF -+print OUT "our \@disablables = (\n"; -+foreach (@disablables) { -+ print OUT " ", quotify("perl", $_), ",\n"; -+} -+print OUT <<"EOF"; -+); -+ -+EOF -+print OUT "our \%disabled = (\n"; -+foreach (sort keys %disabled) { -+ print OUT " ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n"; -+} -+print OUT <<"EOF"; -+); -+ -+EOF -+print OUT "our %withargs = (\n"; -+foreach (sort keys %withargs) { -+ if (ref($withargs{$_}) eq "ARRAY") { -+ print OUT " ", $_, " => [ ", join(", ", -+ map { quotify("perl", $_) } -+ @{$withargs{$_}}), " ],\n"; -+ } else { -+ print OUT " ", $_, " => ", quotify("perl", $withargs{$_}), ",\n" -+ } -+} -+print OUT <<"EOF"; -+); -+ -+EOF -+if ($builder eq "unified") { -+ my $recurse; -+ $recurse = sub { -+ my $indent = shift; -+ foreach (@_) { -+ if (ref $_ eq "ARRAY") { -+ print OUT " "x$indent, "[\n"; -+ foreach (@$_) { -+ $recurse->($indent + 4, $_); -+ } -+ print OUT " "x$indent, "],\n"; -+ } elsif (ref $_ eq "HASH") { -+ my %h = %$_; -+ print OUT " "x$indent, "{\n"; -+ foreach (sort keys %h) { -+ if (ref $h{$_} eq "") { -+ print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n"; -+ } else { -+ print OUT " "x($indent + 4), quotify("perl", $_), " =>\n"; -+ $recurse->($indent + 8, $h{$_}); -+ } -+ } -+ print OUT " "x$indent, "},\n"; -+ } else { -+ print OUT " "x$indent, quotify("perl", $_), ",\n"; -+ } -+ } -+ }; -+ print OUT "our %unified_info = (\n"; -+ foreach (sort keys %unified_info) { -+ if (ref $unified_info{$_} eq "") { -+ print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n"; -+ } else { -+ print OUT " "x4, quotify("perl", $_), " =>\n"; -+ $recurse->(8, $unified_info{$_}); -+ } -+ } -+ print OUT <<"EOF"; -+); -+ -+EOF -+} -+print OUT "1;\n"; -+close(OUT); -+ -+ -+print "CC =$config{cross_compile_prefix}$target{cc}\n"; -+print "CFLAG =$target{cflags} $config{cflags}\n"; -+print "SHARED_CFLAG =$target{shared_cflag}\n"; -+print "DEFINES =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n"; -+print "LFLAG =$target{lflags}\n"; -+print "PLIB_LFLAG =$target{plib_lflags}\n"; -+print "EX_LIBS =$target{ex_libs} $config{ex_libs}\n"; -+print "APPS_OBJ =$target{apps_obj}\n"; -+print "CPUID_OBJ =$target{cpuid_obj}\n"; -+print "UPLINK_OBJ =$target{uplink_obj}\n"; -+print "BN_ASM =$target{bn_obj}\n"; -+print "EC_ASM =$target{ec_obj}\n"; -+print "DES_ENC =$target{des_obj}\n"; -+print "AES_ENC =$target{aes_obj}\n"; -+print "BF_ENC =$target{bf_obj}\n"; -+print "CAST_ENC =$target{cast_obj}\n"; -+print "RC4_ENC =$target{rc4_obj}\n"; -+print "RC5_ENC =$target{rc5_obj}\n"; -+print "MD5_OBJ_ASM =$target{md5_obj}\n"; -+print "SHA1_OBJ_ASM =$target{sha1_obj}\n"; -+print "RMD160_OBJ_ASM=$target{rmd160_obj}\n"; -+print "CMLL_ENC =$target{cmll_obj}\n"; -+print "MODES_OBJ =$target{modes_obj}\n"; -+print "PADLOCK_OBJ =$target{padlock_obj}\n"; -+print "CHACHA_ENC =$target{chacha_obj}\n"; -+print "POLY1305_OBJ =$target{poly1305_obj}\n"; -+print "BLAKE2_OBJ =$target{blake2_obj}\n"; -+print "PROCESSOR =$config{processor}\n"; -+print "RANLIB =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ? -+ "$config{cross_compile_prefix}ranlib" : -+ "$target{ranlib}", "\n"; -+print "ARFLAGS =$target{arflags}\n"; -+print "PERL =$config{perl}\n"; -+print "\n"; -+print "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l}; -+print "SIXTY_FOUR_BIT mode\n" if $config{b64}; -+print "THIRTY_TWO_BIT mode\n" if $config{b32}; -+print "BN_LLONG mode\n" if $config{bn_ll}; -+print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} ne $def_int; -+ -+my %builders = ( -+ unified => sub { -+ run_dofile(catfile($blddir, $target{build_file}), -+ @{$config{build_file_templates}}); -+ }, -+ ); -+ -+$builders{$builder}->($builder_platform, @builder_opts); -+ -+print <<"EOF"; -+ -+Configured for $target. -+EOF -+ -+print <<"EOF" if ($disabled{threads} eq "unavailable"); -+ -+The library could not be configured for supporting multi-threaded -+applications as the compiler options required on this system are not known. -+See file INSTALL for details if you need multi-threading. -+EOF -+ -+print <<"EOF" if ($no_shared_warn); -+ -+The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this -+platform, so we will pretend you gave the option 'no-pic', which also disables -+'shared' and 'dynamic-engine'. If you know how to implement shared libraries -+or position independent code, please let us know (but please first make sure -+you have tried with a current version of OpenSSL). -+EOF -+ -+print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir); -+ -+WARNING: there are indications that another build was made in the source -+directory. This build may have picked up artifacts from that build, the -+safest course of action is to clean the source directory and redo this -+configuration. -+EOF -+ -+exit(0); -+ -+###################################################################### -+# -+# Helpers and utility functions -+# -+ -+# Configuration file reading ######################################### -+ -+# Note: All of the helper functions are for lazy evaluation. They all -+# return a CODE ref, which will return the intended value when evaluated. -+# Thus, whenever there's mention of a returned value, it's about that -+# intended value. -+ -+# Helper function to implement conditional inheritance depending on the -+# value of $disabled{asm}. Used in inherit_from values as follows: -+# -+# inherit_from => [ "template", asm("asm_tmpl") ] -+# -+sub asm { -+ my @x = @_; -+ sub { -+ $disabled{asm} ? () : @x; -+ } -+} -+ -+# Helper function to implement conditional value variants, with a default -+# plus additional values based on the value of $config{build_type}. -+# Arguments are given in hash table form: -+# -+# picker(default => "Basic string: ", -+# debug => "debug", -+# release => "release") -+# -+# When configuring with --debug, the resulting string will be -+# "Basic string: debug", and when not, it will be "Basic string: release" -+# -+# This can be used to create variants of sets of flags according to the -+# build type: -+# -+# cflags => picker(default => "-Wall", -+# debug => "-g -O0", -+# release => "-O3") -+# -+sub picker { -+ my %opts = @_; -+ return sub { add($opts{default} || (), -+ $opts{$config{build_type}} || ())->(); } -+} -+ -+# Helper function to combine several values of different types into one. -+# This is useful if you want to combine a string with the result of a -+# lazy function, such as: -+# -+# cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" }) -+# -+sub combine { -+ my @stuff = @_; -+ return sub { add(@stuff)->(); } -+} -+ -+# Helper function to implement conditional values depending on the value -+# of $disabled{threads}. Can be used as follows: -+# -+# cflags => combine("-Wall", threads("-pthread")) -+# -+sub threads { -+ my @flags = @_; -+ return sub { add($disabled{threads} ? () : @flags)->(); } -+} -+ -+ -+ -+our $add_called = 0; -+# Helper function to implement adding values to already existing configuration -+# values. It handles elements that are ARRAYs, CODEs and scalars -+sub _add { -+ my $separator = shift; -+ -+ # If there's any ARRAY in the collection of values OR the separator -+ # is undef, we will return an ARRAY of combined values, otherwise a -+ # string of joined values with $separator as the separator. -+ my $found_array = !defined($separator); -+ -+ my @values = -+ map { -+ my $res = $_; -+ while (ref($res) eq "CODE") { -+ $res = $res->(); -+ } -+ if (defined($res)) { -+ if (ref($res) eq "ARRAY") { -+ $found_array = 1; -+ @$res; -+ } else { -+ $res; -+ } -+ } else { -+ (); -+ } -+ } (@_); -+ -+ $add_called = 1; -+ -+ if ($found_array) { -+ [ @values ]; -+ } else { -+ join($separator, grep { defined($_) && $_ ne "" } @values); -+ } -+} -+sub add_before { -+ my $separator = " "; -+ if (ref($_[$#_]) eq "HASH") { -+ my $opts = pop; -+ $separator = $opts->{separator}; -+ } -+ my @x = @_; -+ sub { _add($separator, @x, @_) }; -+} -+sub add { -+ my $separator = " "; -+ if (ref($_[$#_]) eq "HASH") { -+ my $opts = pop; -+ $separator = $opts->{separator}; -+ } -+ my @x = @_; -+ sub { _add($separator, @_, @x) }; -+} -+ -+# configuration reader, evaluates the input file as a perl script and expects -+# it to fill %targets with target configurations. Those are then added to -+# %table. -+sub read_config { -+ my $fname = shift; -+ open(CONFFILE, "< $fname") -+ or die "Can't open configuration file '$fname'!\n"; -+ my $x = $/; -+ undef $/; -+ my $content = ; -+ $/ = $x; -+ close(CONFFILE); -+ my %targets = (); -+ { -+ # Protect certain tables from tampering -+ local %table = %::table; -+ -+ eval $content; -+ warn $@ if $@; -+ } -+ -+ # For each target, check that it's configured with a hash table. -+ foreach (keys %targets) { -+ if (ref($targets{$_}) ne "HASH") { -+ if (ref($targets{$_}) eq "") { -+ warn "Deprecated target configuration for $_, ignoring...\n"; -+ } else { -+ warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n"; -+ } -+ delete $targets{$_}; -+ } else { -+ $targets{$_}->{_conf_fname_int} = add([ $fname ]); -+ } -+ } -+ -+ %table = (%table, %targets); -+ -+} -+ -+# configuration resolver. Will only resolve all the lazy evaluation -+# codeblocks for the chosen target and all those it inherits from, -+# recursively -+sub resolve_config { -+ my $target = shift; -+ my @breadcrumbs = @_; -+ -+# my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS}); -+ -+ if (grep { $_ eq $target } @breadcrumbs) { -+ die "inherit_from loop! target backtrace:\n " -+ ,$target,"\n ",join("\n ", @breadcrumbs),"\n"; -+ } -+ -+ if (!defined($table{$target})) { -+ warn "Warning! target $target doesn't exist!\n"; -+ return (); -+ } -+ # Recurse through all inheritances. They will be resolved on the -+ # fly, so when this operation is done, they will all just be a -+ # bunch of attributes with string values. -+ # What we get here, though, are keys with references to lists of -+ # the combined values of them all. We will deal with lists after -+ # this stage is done. -+ my %combined_inheritance = (); -+ if ($table{$target}->{inherit_from}) { -+ my @inherit_from = -+ map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}}; -+ foreach (@inherit_from) { -+ my %inherited_config = resolve_config($_, $target, @breadcrumbs); -+ -+ # 'template' is a marker that's considered private to -+ # the config that had it. -+ delete $inherited_config{template}; -+ -+ foreach (keys %inherited_config) { -+ if (!$combined_inheritance{$_}) { -+ $combined_inheritance{$_} = []; -+ } -+ push @{$combined_inheritance{$_}}, $inherited_config{$_}; -+ } -+ } -+ } -+ -+ # We won't need inherit_from in this target any more, since we've -+ # resolved all the inheritances that lead to this -+ delete $table{$target}->{inherit_from}; -+ -+ # Now is the time to deal with those lists. Here's the place to -+ # decide what shall be done with those lists, all based on the -+ # values of the target we're currently dealing with. -+ # - If a value is a coderef, it will be executed with the list of -+ # inherited values as arguments. -+ # - If the corresponding key doesn't have a value at all or is the -+ # empty string, the inherited value list will be run through the -+ # default combiner (below), and the result becomes this target's -+ # value. -+ # - Otherwise, this target's value is assumed to be a string that -+ # will simply override the inherited list of values. -+ my $default_combiner = add(); -+ -+ my %all_keys = -+ map { $_ => 1 } (keys %combined_inheritance, -+ keys %{$table{$target}}); -+ -+ sub process_values { -+ my $object = shift; -+ my $inherited = shift; # Always a [ list ] -+ my $target = shift; -+ my $entry = shift; -+ -+ $add_called = 0; -+ -+ while(ref($object) eq "CODE") { -+ $object = $object->(@$inherited); -+ } -+ if (!defined($object)) { -+ return (); -+ } -+ elsif (ref($object) eq "ARRAY") { -+ local $add_called; # To make sure recursive calls don't affect it -+ return [ map { process_values($_, $inherited, $target, $entry) } -+ @$object ]; -+ } elsif (ref($object) eq "") { -+ return $object; -+ } else { -+ die "cannot handle reference type ",ref($object) -+ ," found in target ",$target," -> ",$entry,"\n"; -+ } -+ } -+ -+ foreach (sort keys %all_keys) { -+ my $previous = $combined_inheritance{$_}; -+ -+ # Current target doesn't have a value for the current key? -+ # Assign it the default combiner, the rest of this loop body -+ # will handle it just like any other coderef. -+ if (!exists $table{$target}->{$_}) { -+ $table{$target}->{$_} = $default_combiner; -+ } -+ -+ $table{$target}->{$_} = process_values($table{$target}->{$_}, -+ $combined_inheritance{$_}, -+ $target, $_); -+ unless(defined($table{$target}->{$_})) { -+ delete $table{$target}->{$_}; -+ } -+# if ($extra_checks && -+# $previous && !($add_called || $previous ~~ $table{$target}->{$_})) { -+# warn "$_ got replaced in $target\n"; -+# } -+ } -+ -+ # Finally done, return the result. -+ return %{$table{$target}}; -+} -+ -+sub usage -+ { -+ print STDERR $usage; -+ print STDERR "\npick os/compiler from:\n"; -+ my $j=0; -+ my $i; -+ my $k=0; -+ foreach $i (sort keys %table) -+ { -+ next if $table{$i}->{template}; -+ next if $i =~ /^debug/; -+ $k += length($i) + 1; -+ if ($k > 78) -+ { -+ print STDERR "\n"; -+ $k=length($i); -+ } -+ print STDERR $i . " "; -+ } -+ foreach $i (sort keys %table) -+ { -+ next if $table{$i}->{template}; -+ next if $i !~ /^debug/; -+ $k += length($i) + 1; -+ if ($k > 78) -+ { -+ print STDERR "\n"; -+ $k=length($i); -+ } -+ print STDERR $i . " "; -+ } -+ print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n"; -+ exit(1); -+ } -+ -+sub run_dofile -+{ -+ my $out = shift; -+ my @templates = @_; -+ -+ unlink $out || warn "Can't remove $out, $!" -+ if -f $out; -+ foreach (@templates) { -+ die "Can't open $_, $!" unless -f $_; -+ } -+ my $perlcmd = (quotify("maybeshell", $config{perl}))[0]; -+ my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\""; -+ #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n"; -+ system($cmd); -+ exit 1 if $? != 0; -+ rename("$out.new", $out) || die "Can't rename $out.new, $!"; -+} -+ -+sub which -+{ -+ my ($name)=@_; -+ -+ if (eval { require IPC::Cmd; 1; }) { -+ IPC::Cmd->import(); -+ return scalar IPC::Cmd::can_run($name); -+ } else { -+ # if there is $directories component in splitpath, -+ # then it's not something to test with $PATH... -+ return $name if (File::Spec->splitpath($name))[1]; -+ -+ foreach (File::Spec->path()) { -+ my $fullpath = catfile($_, "$name$target{exe_extension}"); -+ if (-f $fullpath and -x $fullpath) { -+ return $fullpath; -+ } -+ } -+ } -+} -+ -+# Configuration printer ############################################## -+ -+sub print_table_entry -+{ -+ my $target = shift; -+ my %target = resolve_config($target); -+ my $type = shift; -+ -+ # Don't print the templates -+ return if $target{template}; -+ -+ my @sequence = ( -+ "sys_id", -+ "cc", -+ "cflags", -+ "defines", -+ "unistd", -+ "ld", -+ "lflags", -+ "loutflag", -+ "plib_lflags", -+ "ex_libs", -+ "bn_ops", -+ "apps_aux_src", -+ "cpuid_asm_src", -+ "uplink_aux_src", -+ "bn_asm_src", -+ "ec_asm_src", -+ "des_asm_src", -+ "aes_asm_src", -+ "bf_asm_src", -+ "md5_asm_src", -+ "cast_asm_src", -+ "sha1_asm_src", -+ "rc4_asm_src", -+ "rmd160_asm_src", -+ "rc5_asm_src", -+ "wp_asm_src", -+ "cmll_asm_src", -+ "modes_asm_src", -+ "padlock_asm_src", -+ "chacha_asm_src", -+ "poly1035_asm_src", -+ "thread_scheme", -+ "perlasm_scheme", -+ "dso_scheme", -+ "shared_target", -+ "shared_cflag", -+ "shared_defines", -+ "shared_ldflag", -+ "shared_rcflag", -+ "shared_extension", -+ "dso_extension", -+ "obj_extension", -+ "exe_extension", -+ "ranlib", -+ "ar", -+ "arflags", -+ "aroutflag", -+ "rc", -+ "rcflags", -+ "rcoutflag", -+ "mt", -+ "mtflags", -+ "mtinflag", -+ "mtoutflag", -+ "multilib", -+ "build_scheme", -+ ); -+ -+ if ($type eq "TABLE") { -+ print "\n"; -+ print "*** $target\n"; -+ foreach (@sequence) { -+ if (ref($target{$_}) eq "ARRAY") { -+ printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}}); -+ } else { -+ printf "\$%-12s = %s\n", $_, $target{$_}; -+ } -+ } -+ } elsif ($type eq "HASH") { -+ my $largest = -+ length((sort { length($a) <=> length($b) } @sequence)[-1]); -+ print " '$target' => {\n"; -+ foreach (@sequence) { -+ if ($target{$_}) { -+ if (ref($target{$_}) eq "ARRAY") { -+ print " '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n"; -+ } else { -+ print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n"; -+ } -+ } -+ } -+ print " },\n"; -+ } -+} -+ -+# Utility routines ################################################### -+ -+# On VMS, if the given file is a logical name, File::Spec::Functions -+# will consider it an absolute path. There are cases when we want a -+# purely syntactic check without checking the environment. -+sub isabsolute { -+ my $file = shift; -+ -+ # On non-platforms, we just use file_name_is_absolute(). -+ return file_name_is_absolute($file) unless $^O eq "VMS"; -+ -+ # If the file spec includes a device or a directpry spec, -+ # file_name_is_absolute() is perfectly safe. -+ return file_name_is_absolute($file) if $file =~ m|[:\[]|; -+ -+ # Here, we know the given file spec isn't absolute -+ return 0; -+} -+ -+# Makes a directory absolute and cleans out /../ in paths like foo/../bar -+# On some platforms, this uses rel2abs(), while on others, realpath() is used. -+# realpath() requires that at least all path components except the last is an -+# existing directory. On VMS, the last component of the directory spec must -+# exist. -+sub absolutedir { -+ my $dir = shift; -+ -+ # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which -+ # will return the volume name for the device, no matter what. Also, -+ # it will return an incorrect directory spec if the argument is a -+ # directory that doesn't exist. -+ if ($^O eq "VMS") { -+ return rel2abs($dir); -+ } -+ -+ # We use realpath() on Unix, since no other will properly clean out -+ # a directory spec. -+ use Cwd qw/realpath/; -+ -+ return realpath($dir); -+} -+ -+sub quotify { -+ my %processors = ( -+ perl => sub { my $x = shift; -+ $x =~ s/([\\\$\@"])/\\$1/g; -+ return '"'.$x.'"'; }, -+ maybeshell => sub { my $x = shift; -+ (my $y = $x) =~ s/([\\\"])/\\$1/g; -+ if ($x ne $y || $x =~ m|\s|) { -+ return '"'.$y.'"'; -+ } else { -+ return $x; -+ } -+ }, -+ ); -+ my $for = shift; -+ my $processor = -+ defined($processors{$for}) ? $processors{$for} : sub { shift; }; -+ -+ return map { $processor->($_); } @_; -+} -+ -+# collect_from_file($filename, $line_concat_cond_re, $line_concat) -+# $filename is a file name to read from -+# $line_concat_cond_re is a regexp detecting a line continuation ending -+# $line_concat is a CODEref that takes care of concatenating two lines -+sub collect_from_file { -+ my $filename = shift; -+ my $line_concat_cond_re = shift; -+ my $line_concat = shift; -+ -+ open my $fh, $filename || die "unable to read $filename: $!\n"; -+ return sub { -+ my $saved_line = ""; -+ $_ = ""; -+ while (<$fh>) { -+ s|\R$||; -+ if (defined $line_concat) { -+ $_ = $line_concat->($saved_line, $_); -+ $saved_line = ""; -+ } -+ if (defined $line_concat_cond_re && /$line_concat_cond_re/) { -+ $saved_line = $_; -+ next; -+ } -+ return $_; -+ } -+ die "$filename ending with continuation line\n" if $_; -+ close $fh; -+ return undef; -+ } -+} -+ -+# collect_from_array($array, $line_concat_cond_re, $line_concat) -+# $array is an ARRAYref of lines -+# $line_concat_cond_re is a regexp detecting a line continuation ending -+# $line_concat is a CODEref that takes care of concatenating two lines -+sub collect_from_array { -+ my $array = shift; -+ my $line_concat_cond_re = shift; -+ my $line_concat = shift; -+ my @array = (@$array); -+ -+ return sub { -+ my $saved_line = ""; -+ $_ = ""; -+ while (defined($_ = shift @array)) { -+ s|\R$||; -+ if (defined $line_concat) { -+ $_ = $line_concat->($saved_line, $_); -+ $saved_line = ""; -+ } -+ if (defined $line_concat_cond_re && /$line_concat_cond_re/) { -+ $saved_line = $_; -+ next; -+ } -+ return $_; -+ } -+ die "input text ending with continuation line\n" if $_; -+ return undef; -+ } -+} -+ -+# collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...) -+# $lineiterator is a CODEref that delivers one line at a time. -+# All following arguments are regex/CODEref pairs, where the regexp detects a -+# line and the CODEref does something with the result of the regexp. -+sub collect_information { -+ my $lineiterator = shift; -+ my %collectors = @_; -+ -+ while(defined($_ = $lineiterator->())) { -+ s|\R$||; -+ my $found = 0; -+ if ($collectors{"BEFORE"}) { -+ $collectors{"BEFORE"}->($_); -+ } -+ foreach my $re (keys %collectors) { -+ if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) { -+ $collectors{$re}->($lineiterator); -+ $found = 1; -+ }; -+ } -+ if ($collectors{"OTHERWISE"}) { -+ $collectors{"OTHERWISE"}->($lineiterator, $_) -+ unless $found || !defined $collectors{"OTHERWISE"}; -+ } -+ if ($collectors{"AFTER"}) { -+ $collectors{"AFTER"}->($_); -+ } -+ } -+} -+ -+# tokenize($line) -+# $line is a line of text to split up into tokens -+# returns a list of tokens -+# -+# Tokens are divided by spaces. If the tokens include spaces, they -+# have to be quoted with single or double quotes. Double quotes -+# inside a double quoted token must be escaped. Escaping is done -+# with backslash. -+# Basically, the same quoting rules apply for " and ' as in any -+# Unix shell. -+sub tokenize { -+ my $line = my $debug_line = shift; -+ my @result = (); -+ -+ while ($line =~ s|^\s+||, $line ne "") { -+ my $token = ""; -+ while ($line ne "" && $line !~ m|^\s|) { -+ if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) { -+ $token .= $1; -+ $line = $'; -+ } elsif ($line =~ m/^'([^']*)'/) { -+ $token .= $1; -+ $line = $'; -+ } elsif ($line =~ m/^(\S+)/) { -+ $token .= $1; -+ $line = $'; -+ } -+ } -+ push @result, $token; -+ } -+ -+ if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) { -+ print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n"; -+ print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n"; -+ } -+ return @result; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/FAQ b/CryptoPkg/Library/OpensslLib/openssl/FAQ -new file mode 100644 -index 0000000..22c5cf7 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/FAQ -@@ -0,0 +1,2 @@ -+The FAQ is now maintained on the web: -+ https://www.openssl.org/docs/faq.html -diff --git a/CryptoPkg/Library/OpensslLib/openssl/INSTALL b/CryptoPkg/Library/OpensslLib/openssl/INSTALL -new file mode 100644 -index 0000000..61b13c4 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/INSTALL -@@ -0,0 +1,951 @@ -+ -+ OPENSSL INSTALLATION -+ -------------------- -+ -+ This document describes installation on all supported operating -+ systems (the Linux/Unix family, OpenVMS and Windows) -+ -+ To install OpenSSL, you will need: -+ -+ * A make implementation -+ * Perl 5 with core modules (please read NOTES.PERL) -+ * The perl module Text::Template (please read NOTES.PERL) -+ * an ANSI C compiler -+ * a development environment in the form of development libraries and C -+ header files -+ * a supported operating system -+ -+ For additional platform specific requirements, solutions to specific -+ issues and other details, please read one of these: -+ -+ * NOTES.VMS (OpenVMS) -+ * NOTES.WIN (any supported Windows) -+ * NOTES.DJGPP (DOS platform with DJGPP) -+ -+ Notational conventions in this document -+ --------------------------------------- -+ -+ Throughout this document, we use the following conventions in command -+ examples: -+ -+ $ command Any line starting with a dollar sign -+ ($) is a command line. -+ -+ { word1 | word2 | word3 } This denotes a mandatory choice, to be -+ replaced with one of the given words. -+ A simple example would be this: -+ -+ $ echo { FOO | BAR | COOKIE } -+ -+ which is to be understood as one of -+ these: -+ -+ $ echo FOO -+ - or - -+ $ echo BAR -+ - or - -+ $ echo COOKIE -+ -+ [ word1 | word2 | word3 ] Similar to { word1 | word2 | word3 } -+ except it's optional to give any of -+ those. In addition to the examples -+ above, this would also be valid: -+ -+ $ echo -+ -+ {{ target }} This denotes a mandatory word or -+ sequence of words of some sort. A -+ simple example would be this: -+ -+ $ type {{ filename }} -+ -+ which is to be understood to use the -+ command 'type' on some file name -+ determined by the user. -+ -+ [[ options ]] Similar to {{ target }}, but is -+ optional. -+ -+ Note that the notation assumes spaces around {, }, [, ], {{, }} and -+ [[, ]]. This is to differentiate from OpenVMS directory -+ specifications, which also use [ and ], but without spaces. -+ -+ Quick Start -+ ----------- -+ -+ If you want to just get on with it, do: -+ -+ on Unix: -+ -+ $ ./config -+ $ make -+ $ make test -+ $ make install -+ -+ on OpenVMS: -+ -+ $ @config -+ $ mms -+ $ mms test -+ $ mms install -+ -+ on Windows (only pick one of the targets for configuration): -+ -+ $ perl Configure { VC-WIN32 | VC-WIN64A | VC-WIN64I | VC-CE } -+ $ nmake -+ $ nmake test -+ $ nmake install -+ -+ If any of these steps fails, see section Installation in Detail below. -+ -+ This will build and install OpenSSL in the default location, which is: -+ -+ Unix: normal installation directories under /usr/local -+ OpenVMS: SYS$COMMON:[OPENSSL-'version'...], where 'version' is the -+ OpenSSL version number with underscores instead of periods. -+ Windows: C:\Program Files\OpenSSL or C:\Program Files (x86)\OpenSSL -+ -+ If you want to install it anywhere else, run config like this: -+ -+ On Unix: -+ -+ $ ./config --prefix=/opt/openssl --openssldir=/usr/local/ssl -+ -+ On OpenVMS: -+ -+ $ @config --prefix=PROGRAM:[INSTALLS] --openssldir=SYS$MANAGER:[OPENSSL] -+ -+ -+ Configuration Options -+ --------------------- -+ -+ There are several options to ./config (or ./Configure) to customize -+ the build (note that for Windows, the defaults for --prefix and -+ --openssldir depend in what configuration is used and what Windows -+ implementation OpenSSL is built on. More notes on this in NOTES.WIN): -+ -+ --api=x.y.z -+ Don't build with support for deprecated APIs below the -+ specified version number. For example "--api=1.1.0" will -+ remove support for all APIS that were deprecated in OpenSSL -+ version 1.1.0 or below. -+ -+ --cross-compile-prefix=PREFIX -+ The PREFIX to include in front of commands for your -+ toolchain. It's likely to have to end with dash, e.g. -+ a-b-c- would invoke GNU compiler as a-b-c-gcc, etc. -+ Unfortunately cross-compiling is too case-specific to -+ put together one-size-fits-all instructions. You might -+ have to pass more flags or set up environment variables -+ to actually make it work. Android and iOS cases are -+ discussed in corresponding Configurations/10-main.cf -+ sections. But there are cases when this option alone is -+ sufficient. For example to build the mingw64 target on -+ Linux "--cross-compile-prefix=x86_64-w64-mingw32-" -+ works. Naturally provided that mingw packages are -+ installed. Today Debian and Ubuntu users have option to -+ install a number of prepackaged cross-compilers along -+ with corresponding run-time and development packages for -+ "alien" hardware. To give another example -+ "--cross-compile-prefix=mipsel-linux-gnu-" suffices -+ in such case. Needless to mention that you have to -+ invoke ./Configure, not ./config, and pass your target -+ name explicitly. -+ -+ --debug -+ Build OpenSSL with debugging symbols. -+ -+ --libdir=DIR -+ The name of the directory under the top of the installation -+ directory tree (see the --prefix option) where libraries will -+ be installed. By default this is "lib". Note that on Windows -+ only ".lib" files will be stored in this location. dll files -+ will always be installed to the "bin" directory. -+ -+ --openssldir=DIR -+ Directory for OpenSSL configuration files, and also the -+ default certificate and key store. Defaults are: -+ -+ Unix: /usr/local/ssl -+ Windows: C:\Program Files\Common Files\SSL -+ or C:\Program Files (x86)\Common Files\SSL -+ OpenVMS: SYS$COMMON:[OPENSSL-COMMON] -+ -+ --prefix=DIR -+ The top of the installation directory tree. Defaults are: -+ -+ Unix: /usr/local -+ Windows: C:\Program Files\OpenSSL -+ or C:\Program Files (x86)\OpenSSL -+ OpenVMS: SYS$COMMON:[OPENSSL-'version'] -+ -+ --release -+ Build OpenSSL without debugging symbols. This is the default. -+ -+ --strict-warnings -+ This is a developer flag that switches on various compiler -+ options recommended for OpenSSL development. It only works -+ when using gcc or clang as the compiler. If you are -+ developing a patch for OpenSSL then it is recommended that -+ you use this option where possible. -+ -+ --with-zlib-include=DIR -+ The directory for the location of the zlib include file. This -+ option is only necessary if enable-zlib (see below) is used -+ and the include file is not already on the system include -+ path. -+ -+ --with-zlib-lib=LIB -+ On Unix: this is the directory containing the zlib library. -+ If not provided the system library path will be used. -+ On Windows: this is the filename of the zlib library (with or -+ without a path). This flag must be provided if the -+ zlib-dynamic option is not also used. If zlib-dynamic is used -+ then this flag is optional and a default value ("ZLIB1") is -+ used if not provided. -+ On VMS: this is the filename of the zlib library (with or -+ without a path). This flag is optional and if not provided -+ then "GNV$LIBZSHR", "GNV$LIBZSHR32" or "GNV$LIBZSHR64" is -+ used by default depending on the pointer size chosen. -+ -+ no-afalgeng -+ Don't build the AFALG engine. This option will be forced if -+ on a platform that does not support AFALG. -+ -+ enable-asan -+ Build with the Address sanitiser. This is a developer option -+ only. It may not work on all platforms and should never be -+ used in production environments. It will only work when used -+ with gcc or clang and should be used in conjunction with the -+ no-shared option. -+ -+ no-asm -+ Do not use assembler code. On some platforms a small amount -+ of assembler code may still be used. -+ -+ no-async -+ Do not build support for async operations. -+ -+ no-autoalginit -+ Don't automatically load all supported ciphers and digests. -+ Typically OpenSSL will make available all of its supported -+ ciphers and digests. For a statically linked application this -+ may be undesirable if small executable size is an objective. -+ This only affects libcrypto. Ciphers and digests will have to -+ be loaded manually using EVP_add_cipher() and -+ EVP_add_digest() if this option is used. This option will -+ force a non-shared build. -+ -+ no-autoerrinit -+ Don't automatically load all libcrypto/libssl error strings. -+ Typically OpenSSL will automatically load human readable -+ error strings. For a statically linked application this may -+ be undesirable if small executable size is an objective. -+ -+ -+ no-capieng -+ Don't build the CAPI engine. This option will be forced if -+ on a platform that does not support CAPI. -+ -+ no-cms -+ Don't build support for CMS features -+ -+ no-comp -+ Don't build support for SSL/TLS compression. If this option -+ is left enabled (the default), then compression will only -+ work if the zlib or zlib-dynamic options are also chosen. -+ -+ enable-crypto-mdebug -+ Build support for debugging memory allocated via -+ OPENSSL_malloc() or OPENSSL_zalloc(). -+ -+ enable-crypto-mdebug-backtrace -+ As for crypto-mdebug, but additionally provide backtrace -+ information for allocated memory. -+ TO BE USED WITH CARE: this uses GNU C functionality, and -+ is therefore not usable for non-GNU config targets. If -+ your build complains about the use of '-rdynamic' or the -+ lack of header file execinfo.h, this option is not for you. -+ ALSO NOTE that even though execinfo.h is available on your -+ system (through Gnulib), the functions might just be stubs -+ that do nothing. -+ -+ no-ct -+ Don't build support for Certificate Transparency. -+ -+ no-deprecated -+ Don't build with support for any deprecated APIs. This is the -+ same as using "--api" and supplying the latest version -+ number. -+ -+ no-dgram -+ Don't build support for datagram based BIOs. Selecting this -+ option will also force the disabling of DTLS. -+ -+ no-dso -+ Don't build support for loading Dynamic Shared Objects. -+ -+ no-dynamic-engine -+ Don't build the dynamically loaded engines. This only has an -+ effect in a "shared" build -+ -+ no-ec -+ Don't build support for Elliptic Curves. -+ -+ no-ec2m -+ Don't build support for binary Elliptic Curves -+ -+ enable-ec_nistp_64_gcc_128 -+ Enable support for optimised implementations of some commonly -+ used NIST elliptic curves. This is only supported on some -+ platforms. -+ -+ enable-egd -+ Build support for gathering entropy from EGD (Entropy -+ Gathering Daemon). -+ -+ no-engine -+ Don't build support for loading engines. -+ -+ no-err -+ Don't compile in any error strings. -+ -+ no-filenames -+ Don't compile in filename and line number information (e.g. -+ for errors and memory allocation). -+ -+ enable-fuzz-libfuzzer, enable-fuzz-afl -+ Build with support for fuzzing using either libfuzzer or AFL. -+ These are developer options only. They may not work on all -+ platforms and should never be used in production environments. -+ See the file fuzz/README.md for further details. -+ -+ no-gost -+ Don't build support for GOST based ciphersuites. Note that -+ if this feature is enabled then GOST ciphersuites are only -+ available if the GOST algorithms are also available through -+ loading an externally supplied engine. -+ -+ enable-heartbeats -+ Build support for DTLS heartbeats. -+ -+ no-hw-padlock -+ Don't build the padlock engine. -+ -+ no-makedepend -+ Don't generate dependencies. -+ -+ no-multiblock -+ Don't build support for writing multiple records in one -+ go in libssl (Note: this is a different capability to the -+ pipelining functionality). -+ -+ no-nextprotoneg -+ Don't build support for the NPN TLS extension. -+ -+ no-ocsp -+ Don't build support for OCSP. -+ -+ no-pic -+ Don't build with support for Position Independent Code. -+ -+ no-posix-io -+ Don't use POSIX IO capabilities. -+ -+ no-psk -+ Don't build support for Pre-Shared Key based ciphersuites. -+ -+ no-rdrand -+ Don't use hardware RDRAND capabilities. -+ -+ no-rfc3779 -+ Don't build support for RFC3779 ("X.509 Extensions for IP -+ Addresses and AS Identifiers") -+ -+ sctp -+ Build support for SCTP -+ -+ no-shared -+ Do not create shared libraries, only static ones. See "Note -+ on shared libraries" below. -+ -+ no-sock -+ Don't build support for socket BIOs -+ -+ no-srp -+ Don't build support for SRP or SRP based ciphersuites. -+ -+ no-srtp -+ Don't build SRTP support -+ -+ no-sse2 -+ Exclude SSE2 code paths from 32-bit x86 assembly modules. -+ Normally SSE2 extension is detected at run-time, but the -+ decision whether or not the machine code will be executed -+ is taken solely on CPU capability vector. This means that -+ if you happen to run OS kernel which does not support SSE2 -+ extension on Intel P4 processor, then your application -+ might be exposed to "illegal instruction" exception. -+ There might be a way to enable support in kernel, e.g. -+ FreeBSD kernel can be compiled with CPU_ENABLE_SSE, and -+ there is a way to disengage SSE2 code paths upon application -+ start-up, but if you aim for wider "audience" running -+ such kernel, consider no-sse2. Both the 386 and -+ no-asm options imply no-sse2. -+ -+ enable-ssl-trace -+ Build with the SSL Trace capabilities (adds the "-trace" -+ option to s_client and s_server). -+ -+ no-static-engine -+ Don't build the statically linked engines. This only -+ has an impact when not built "shared". -+ -+ no-stdio -+ Don't use any C "stdio" features. Only libcrypto and libssl -+ can be built in this way. Using this option will suppress -+ building the command line applications. Additionally since -+ the OpenSSL tests also use the command line applications the -+ tests will also be skipped. -+ -+ no-threads -+ Don't try to build with support for multi-threaded -+ applications. -+ -+ threads -+ Build with support for multi-threaded applications. Most -+ platforms will enable this by default. However if on a -+ platform where this is not the case then this will usually -+ require additional system-dependent options! See "Note on -+ multi-threading" below. -+ -+ no-ts -+ Don't build Time Stamping Authority support. -+ -+ enable-ubsan -+ Build with the Undefined Behaviour sanitiser. This is a -+ developer option only. It may not work on all platforms and -+ should never be used in production environments. It will only -+ work when used with gcc or clang and should be used in -+ conjunction with the "-DPEDANTIC" option (or the -+ --strict-warnings option). -+ -+ no-ui -+ Don't build with the "UI" capability (i.e. the set of -+ features enabling text based prompts). -+ -+ enable-unit-test -+ Enable additional unit test APIs. This should not typically -+ be used in production deployments. -+ -+ enable-weak-ssl-ciphers -+ Build support for SSL/TLS ciphers that are considered "weak" -+ (e.g. RC4 based ciphersuites). -+ -+ zlib -+ Build with support for zlib compression/decompression. -+ -+ zlib-dynamic -+ Like "zlib", but has OpenSSL load the zlib library -+ dynamically when needed. This is only supported on systems -+ where loading of shared libraries is supported. -+ -+ 386 -+ In 32-bit x86 builds, when generating assembly modules, -+ use the 80386 instruction set only (the default x86 code -+ is more efficient, but requires at least a 486). Note: -+ This doesn't affect code generated by compiler, you're -+ likely to complement configuration command line with -+ suitable compiler-specific option. -+ -+ no- -+ Don't build support for negotiating the specified SSL/TLS -+ protocol (one of ssl, ssl3, tls, tls1, tls1_1, tls1_2, dtls, -+ dtls1 or dtls1_2). If "no-tls" is selected then all of tls1, -+ tls1_1 and tls1_2 are disabled. Similarly "no-dtls" will -+ disable dtls1 and dtls1_2. The "no-ssl" option is synonymous -+ with "no-ssl3". Note this only affects version negotiation. -+ OpenSSL will still provide the methods for applications to -+ explicitly select the individual protocol versions. -+ -+ no--method -+ As for no- but in addition do not build the methods for -+ applications to explicitly select individual protocol -+ versions. -+ -+ enable- -+ Build with support for the specified algorithm, where -+ is one of: md2 or rc5. -+ -+ no- -+ Build without support for the specified algorithm, where -+ is one of: bf, blake2, camellia, cast, chacha, cmac, -+ des, dh, dsa, ecdh, ecdsa, idea, md4, mdc2, ocb, poly1305, -+ rc2, rc4, rmd160, scrypt, seed or whirlpool. The "ripemd" -+ algorithm is deprecated and if used is synonymous with rmd160. -+ -+ -Dxxx, -lxxx, -Lxxx, -fxxx, -mXXX, -Kxxx -+ These system specific options will be passed through to the -+ compiler to allow you to define preprocessor symbols, specify -+ additional libraries, library directories or other compiler -+ options. It might be worth noting that some compilers -+ generate code specifically for processor the compiler -+ currently executes on. This is not necessarily what you might -+ have in mind, since it might be unsuitable for execution on -+ other, typically older, processor. Consult your compiler -+ documentation. -+ -+ -+ Installation in Detail -+ ---------------------- -+ -+ 1a. Configure OpenSSL for your operation system automatically: -+ -+ NOTE: This is not available on Windows. -+ -+ $ ./config [[ options ]] # Unix -+ -+ or -+ -+ $ @config [[ options ]] ! OpenVMS -+ -+ For the remainder of this text, the Unix form will be used in all -+ examples, please use the appropriate form for your platform. -+ -+ This guesses at your operating system (and compiler, if necessary) and -+ configures OpenSSL based on this guess. Run ./config -t to see -+ if it guessed correctly. If you want to use a different compiler, you -+ are cross-compiling for another platform, or the ./config guess was -+ wrong for other reasons, go to step 1b. Otherwise go to step 2. -+ -+ On some systems, you can include debugging information as follows: -+ -+ $ ./config -d [[ options ]] -+ -+ 1b. Configure OpenSSL for your operating system manually -+ -+ OpenSSL knows about a range of different operating system, hardware and -+ compiler combinations. To see the ones it knows about, run -+ -+ $ ./Configure # Unix -+ -+ or -+ -+ $ perl Configure # All other platforms -+ -+ For the remainder of this text, the Unix form will be used in all -+ examples, please use the appropriate form for your platform. -+ -+ Pick a suitable name from the list that matches your system. For most -+ operating systems there is a choice between using "cc" or "gcc". When -+ you have identified your system (and if necessary compiler) use this name -+ as the argument to Configure. For example, a "linux-elf" user would -+ run: -+ -+ $ ./Configure linux-elf [[ options ]] -+ -+ If your system isn't listed, you will have to create a configuration -+ file named Configurations/{{ something }}.conf and add the correct -+ configuration for your system. See the available configs as examples -+ and read Configurations/README and Configurations/README.design for -+ more information. -+ -+ The generic configurations "cc" or "gcc" should usually work on 32 bit -+ Unix-like systems. -+ -+ Configure creates a build file ("Makefile" on Unix, "makefile" on Windows -+ and "descrip.mms" on OpenVMS) from a suitable template in Configurations, -+ and defines various macros in include/openssl/opensslconf.h (generated from -+ include/openssl/opensslconf.h.in). -+ -+ 1c. Configure OpenSSL for building outside of the source tree. -+ -+ OpenSSL can be configured to build in a build directory separate from -+ the directory with the source code. It's done by placing yourself in -+ some other directory and invoking the configuration commands from -+ there. -+ -+ Unix example: -+ -+ $ mkdir /var/tmp/openssl-build -+ $ cd /var/tmp/openssl-build -+ $ /PATH/TO/OPENSSL/SOURCE/config [[ options ]] -+ -+ or -+ -+ $ /PATH/TO/OPENSSL/SOURCE/Configure {{ target }} [[ options ]] -+ -+ OpenVMS example: -+ -+ $ set default sys$login: -+ $ create/dir [.tmp.openssl-build] -+ $ set default [.tmp.openssl-build] -+ $ @[PATH.TO.OPENSSL.SOURCE]config [[ options ]] -+ -+ or -+ -+ $ @[PATH.TO.OPENSSL.SOURCE]Configure {{ target }} [[ options ]] -+ -+ Windows example: -+ -+ $ C: -+ $ mkdir \temp-openssl -+ $ cd \temp-openssl -+ $ perl d:\PATH\TO\OPENSSL\SOURCE\Configure {{ target }} [[ options ]] -+ -+ Paths can be relative just as well as absolute. Configure will -+ do its best to translate them to relative paths whenever possible. -+ -+ 2. Build OpenSSL by running: -+ -+ $ make # Unix -+ $ mms ! (or mmk) OpenVMS -+ $ nmake # Windows -+ -+ This will build the OpenSSL libraries (libcrypto.a and libssl.a on -+ Unix, corresponding on other platforms) and the OpenSSL binary -+ ("openssl"). The libraries will be built in the top-level directory, -+ and the binary will be in the "apps" subdirectory. -+ -+ If the build fails, look at the output. There may be reasons -+ for the failure that aren't problems in OpenSSL itself (like -+ missing standard headers). If you are having problems you can -+ get help by sending an email to the openssl-users email list (see -+ https://www.openssl.org/community/mailinglists.html for details). If -+ it is a bug with OpenSSL itself, please open an issue on GitHub, at -+ https://github.com/openssl/openssl/issues. Please review the existing -+ ones first; maybe the bug was already reported or has already been -+ fixed. -+ -+ (If you encounter assembler error messages, try the "no-asm" -+ configuration option as an immediate fix.) -+ -+ Compiling parts of OpenSSL with gcc and others with the system -+ compiler will result in unresolved symbols on some systems. -+ -+ 3. After a successful build, the libraries should be tested. Run: -+ -+ $ make test # Unix -+ $ mms test ! OpenVMS -+ $ nmake test # Windows -+ -+ NOTE: you MUST run the tests from an unprivileged account (or -+ disable your privileges temporarily if your platform allows it). -+ -+ If some tests fail, look at the output. There may be reasons for -+ the failure that isn't a problem in OpenSSL itself (like a -+ malfunction with Perl). You may want increased verbosity, that -+ can be accomplished like this: -+ -+ $ make VERBOSE=1 test # Unix -+ -+ $ mms /macro=(VERBOSE=1) test ! OpenVMS -+ -+ $ nmake VERBOSE=1 test # Windows -+ -+ If you want to run just one or a few specific tests, you can use -+ the make variable TESTS to specify them, like this: -+ -+ $ make TESTS='test_rsa test_dsa' test # Unix -+ $ mms/macro="TESTS=test_rsa test_dsa" test ! OpenVMS -+ $ nmake TESTS='test_rsa test_dsa' test # Windows -+ -+ And of course, you can combine (Unix example shown): -+ -+ $ make VERBOSE=1 TESTS='test_rsa test_dsa' test -+ -+ You can find the list of available tests like this: -+ -+ $ make list-tests # Unix -+ $ mms list-tests ! OpenVMS -+ $ nmake list-tests # Windows -+ -+ Have a look at the manual for the perl module Test::Harness to -+ see what other HARNESS_* variables there are. -+ -+ If you find a problem with OpenSSL itself, try removing any -+ compiler optimization flags from the CFLAGS line in Makefile and -+ run "make clean; make" or corresponding. -+ -+ Please send bug reports to . -+ -+ 4. If everything tests ok, install OpenSSL with -+ -+ $ make install # Unix -+ $ mms install ! OpenVMS -+ $ nmake install # Windows -+ -+ This will install all the software components in this directory -+ tree under PREFIX (the directory given with --prefix or its -+ default): -+ -+ Unix: -+ -+ bin/ Contains the openssl binary and a few other -+ utility scripts. -+ include/openssl -+ Contains the header files needed if you want -+ to build your own programs that use libcrypto -+ or libssl. -+ lib Contains the OpenSSL library files. -+ lib/engines Contains the OpenSSL dynamically loadable engines. -+ -+ share/man/man1 Contains the OpenSSL command line man-pages. -+ share/man/man3 Contains the OpenSSL library calls man-pages. -+ share/man/man5 Contains the OpenSSL configuration format man-pages. -+ share/man/man7 Contains the OpenSSL other misc man-pages. -+ -+ share/doc/openssl/html/man1 -+ share/doc/openssl/html/man3 -+ share/doc/openssl/html/man5 -+ share/doc/openssl/html/man7 -+ Contains the HTML rendition of the man-pages. -+ -+ OpenVMS ('arch' is replaced with the architecture name, "Alpha" -+ or "ia64", 'sover' is replaced with the shared library version -+ (0101 for 1.1), and 'pz' is replaced with the pointer size -+ OpenSSL was built with): -+ -+ [.EXE.'arch'] Contains the openssl binary. -+ [.EXE] Contains a few utility scripts. -+ [.include.openssl] -+ Contains the header files needed if you want -+ to build your own programs that use libcrypto -+ or libssl. -+ [.LIB.'arch'] Contains the OpenSSL library files. -+ [.ENGINES'sover''pz'.'arch'] -+ Contains the OpenSSL dynamically loadable engines. -+ [.SYS$STARTUP] Contains startup, login and shutdown scripts. -+ These define appropriate logical names and -+ command symbols. -+ [.SYSTEST] Contains the installation verification procedure. -+ [.HTML] Contains the HTML rendition of the manual pages. -+ -+ -+ Additionally, install will add the following directories under -+ OPENSSLDIR (the directory given with --openssldir or its default) -+ for you convenience: -+ -+ certs Initially empty, this is the default location -+ for certificate files. -+ private Initially empty, this is the default location -+ for private key files. -+ misc Various scripts. -+ -+ Package builders who want to configure the library for standard -+ locations, but have the package installed somewhere else so that -+ it can easily be packaged, can use -+ -+ $ make DESTDIR=/tmp/package-root install # Unix -+ $ mms/macro="DESTDIR=TMP:[PACKAGE-ROOT]" install ! OpenVMS -+ -+ The specified destination directory will be prepended to all -+ installation target paths. -+ -+ Compatibility issues with previous OpenSSL versions: -+ -+ * COMPILING existing applications -+ -+ OpenSSL 1.1.0 hides a number of structures that were previously -+ open. This includes all internal libssl structures and a number -+ of EVP types. Accessor functions have been added to allow -+ controlled access to the structures' data. -+ -+ This means that some software needs to be rewritten to adapt to -+ the new ways of doing things. This often amounts to allocating -+ an instance of a structure explicitly where you could previously -+ allocate them on the stack as automatic variables, and using the -+ provided accessor functions where you would previously access a -+ structure's field directly. -+ -+ Some APIs have changed as well. However, older APIs have been -+ preserved when possible. -+ -+ Environment Variables -+ --------------------- -+ -+ A number of environment variables can be used to provide additional control -+ over the build process. Typically these should be defined prior to running -+ config or Configure. Not all environment variables are relevant to all -+ platforms. -+ -+ AR -+ The name of the ar executable to use. -+ -+ BUILDFILE -+ Use a different build file name than the platform default -+ ("Makefile" on Unixly platforms, "makefile" on native Windows, -+ "descrip.mms" on OpenVMS). This requires that there is a -+ corresponding build file template. See Configurations/README -+ for further information. -+ -+ CC -+ The compiler to use. Configure will attempt to pick a default -+ compiler for your platform but this choice can be overridden -+ using this variable. Set it to the compiler executable you wish -+ to use, e.g. "gcc" or "clang". -+ -+ CROSS_COMPILE -+ This environment variable has the same meaning as for the -+ "--cross-compile-prefix" Configure flag described above. If both -+ are set then the Configure flag takes precedence. -+ -+ NM -+ The name of the nm executable to use. -+ -+ OPENSSL_LOCAL_CONFIG_DIR -+ OpenSSL comes with a database of information about how it -+ should be built on different platforms as well as build file -+ templates for those platforms. The database is comprised of -+ ".conf" files in the Configurations directory. The build -+ file templates reside there as well as ".tmpl" files. See the -+ file Configurations/README for further information about the -+ format of ".conf" files as well as information on the ".tmpl" -+ files. -+ In addition to the standard ".conf" and ".tmpl" files, it is -+ possible to create your own ".conf" and ".tmpl" files and store -+ them locally, outside the OpenSSL source tree. This environment -+ variable can be set to the directory where these files are held -+ and will have Configure to consider them in addition to the -+ standard ones. -+ -+ PERL -+ The name of the Perl executable to use when building OpenSSL. -+ -+ HASHBANGPERL -+ The command string for the Perl executable to insert in the -+ #! line of perl scripts that will be publically installed. -+ Default: /usr/bin/env perl -+ Note: the value of this variable is added to the same scripts -+ on all platforms, but it's only relevant on Unix-like platforms. -+ -+ RC -+ The name of the rc executable to use. The default will be as -+ defined for the target platform in the ".conf" file. If not -+ defined then "windres" will be used. The WINDRES environment -+ variable is synonymous to this. If both are defined then RC -+ takes precedence. -+ -+ RANLIB -+ The name of the ranlib executable to use. -+ -+ WINDRES -+ See RC. -+ -+ Makefile targets -+ ---------------- -+ -+ The Configure script generates a Makefile in a format relevant to the specific -+ platform. The Makefiles provide a number of targets that can be used. Not all -+ targets may be available on all platforms. Only the most common targets are -+ described here. Examine the Makefiles themselves for the full list. -+ -+ all -+ The default target to build all the software components. -+ -+ clean -+ Remove all build artefacts and return the directory to a "clean" -+ state. -+ -+ depend -+ Rebuild the dependencies in the Makefiles. This is a legacy -+ option that no longer needs to be used in OpenSSL 1.1.0. -+ -+ install -+ Install all OpenSSL components. -+ -+ install_sw -+ Only install the OpenSSL software components. -+ -+ install_docs -+ Only install the OpenSSL documentation components. -+ -+ install_man_docs -+ Only install the OpenSSL man pages (Unix only). -+ -+ install_html_docs -+ Only install the OpenSSL html documentation. -+ -+ list-tests -+ Prints a list of all the self test names. -+ -+ test -+ Build and run the OpenSSL self tests. -+ -+ uninstall -+ Uninstall all OpenSSL components. -+ -+ update -+ This is a developer option. If you are developing a patch for -+ OpenSSL you may need to use this if you want to update -+ automatically generated files; add new error codes or add new -+ (or change the visibility of) public API functions. (Unix only). -+ -+ Note on multi-threading -+ ----------------------- -+ -+ For some systems, the OpenSSL Configure script knows what compiler options -+ are needed to generate a library that is suitable for multi-threaded -+ applications. On these systems, support for multi-threading is enabled -+ by default; use the "no-threads" option to disable (this should never be -+ necessary). -+ -+ On other systems, to enable support for multi-threading, you will have -+ to specify at least two options: "threads", and a system-dependent option. -+ (The latter is "-D_REENTRANT" on various systems.) The default in this -+ case, obviously, is not to include support for multi-threading (but -+ you can still use "no-threads" to suppress an annoying warning message -+ from the Configure script.) -+ -+ OpenSSL provides built-in support for two threading models: pthreads (found on -+ most UNIX/Linux systems), and Windows threads. No other threading models are -+ supported. If your platform does not provide pthreads or Windows threads then -+ you should Configure with the "no-threads" option. -+ -+ Notes on shared libraries -+ ------------------------- -+ -+ For most systems the OpenSSL Configure script knows what is needed to -+ build shared libraries for libcrypto and libssl. On these systems -+ the shared libraries will be created by default. This can be suppressed and -+ only static libraries created by using the "no-shared" option. On systems -+ where OpenSSL does not know how to build shared libraries the "no-shared" -+ option will be forced and only static libraries will be created. -+ -+ Shared libraries are named a little differently on different platforms. -+ One way or another, they all have the major OpenSSL version number as -+ part of the file name, i.e. for OpenSSL 1.1.x, 1.1 is somehow part of -+ the name. -+ -+ On most POSIXly platforms, shared libraries are named libcrypto.so.1.1 -+ and libssl.so.1.1. -+ -+ on Cygwin, shared libraries are named cygcrypto-1.1.dll and cygssl-1.1.dll -+ with import libraries libcrypto.dll.a and libssl.dll.a. -+ -+ On Windows build with MSVC or using MingW, shared libraries are named -+ libcrypto-1_1.dll and libssl-1_1.dll for 32-bit Windows, libcrypto-1_1-x64.dll -+ and libssl-1_1-x64.dll for 64-bit x86_64 Windows, and libcrypto-1_1-ia64.dll -+ and libssl-1_1-ia64.dll for IA64 Windows. With MSVC, the import libraries -+ are named libcrypto.lib and libssl.lib, while with MingW, they are named -+ libcrypto.dll.a and libssl.dll.a. -+ -+ On VMS, shareable images (VMS speak for shared libraries) are named -+ ossl$libcrypto0101_shr.exe and ossl$libssl0101_shr.exe. However, when -+ OpenSSL is specifically built for 32-bit pointers, the shareable images -+ are named ossl$libcrypto0101_shr32.exe and ossl$libssl0101_shr32.exe -+ instead, and when built for 64-bit pointers, they are named -+ ossl$libcrypto0101_shr64.exe and ossl$libssl0101_shr64.exe. -+ -+ Note on random number generation -+ -------------------------------- -+ -+ Availability of cryptographically secure random numbers is required for -+ secret key generation. OpenSSL provides several options to seed the -+ internal PRNG. If not properly seeded, the internal PRNG will refuse -+ to deliver random bytes and a "PRNG not seeded error" will occur. -+ On systems without /dev/urandom (or similar) device, it may be necessary -+ to install additional support software to obtain a random seed. -+ Please check out the manual pages for RAND_add(), RAND_bytes(), RAND_egd(), -+ and the FAQ for more information. -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/LICENSE b/CryptoPkg/Library/OpensslLib/openssl/LICENSE -new file mode 100644 -index 0000000..c6cc098 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/LICENSE -@@ -0,0 +1,125 @@ -+ -+ LICENSE ISSUES -+ ============== -+ -+ The OpenSSL toolkit stays under a dual license, i.e. both the conditions of -+ the OpenSSL License and the original SSLeay license apply to the toolkit. -+ See below for the actual license texts. -+ -+ OpenSSL License -+ --------------- -+ -+/* ==================================================================== -+ * Copyright (c) 1998-2016 The OpenSSL Project. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * 3. All advertising materials mentioning features or use of this -+ * software must display the following acknowledgment: -+ * "This product includes software developed by the OpenSSL Project -+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" -+ * -+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to -+ * endorse or promote products derived from this software without -+ * prior written permission. For written permission, please contact -+ * openssl-core@openssl.org. -+ * -+ * 5. Products derived from this software may not be called "OpenSSL" -+ * nor may "OpenSSL" appear in their names without prior written -+ * permission of the OpenSSL Project. -+ * -+ * 6. Redistributions of any form whatsoever must retain the following -+ * acknowledgment: -+ * "This product includes software developed by the OpenSSL Project -+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY -+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR -+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -+ * OF THE POSSIBILITY OF SUCH DAMAGE. -+ * ==================================================================== -+ * -+ * This product includes cryptographic software written by Eric Young -+ * (eay@cryptsoft.com). This product includes software written by Tim -+ * Hudson (tjh@cryptsoft.com). -+ * -+ */ -+ -+ Original SSLeay License -+ ----------------------- -+ -+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -+ * All rights reserved. -+ * -+ * This package is an SSL implementation written -+ * by Eric Young (eay@cryptsoft.com). -+ * The implementation was written so as to conform with Netscapes SSL. -+ * -+ * This library is free for commercial and non-commercial use as long as -+ * the following conditions are aheared to. The following conditions -+ * apply to all code found in this distribution, be it the RC4, RSA, -+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation -+ * included with this distribution is covered by the same copyright terms -+ * except that the holder is Tim Hudson (tjh@cryptsoft.com). -+ * -+ * Copyright remains Eric Young's, and as such any Copyright notices in -+ * the code are not to be removed. -+ * If this package is used in a product, Eric Young should be given attribution -+ * as the author of the parts of the library used. -+ * This can be in the form of a textual message at program startup or -+ * in documentation (online or textual) provided with the package. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. All advertising materials mentioning features or use of this software -+ * must display the following acknowledgement: -+ * "This product includes cryptographic software written by -+ * Eric Young (eay@cryptsoft.com)" -+ * The word 'cryptographic' can be left out if the rouines from the library -+ * being used are not cryptographic related :-). -+ * 4. If you include any Windows specific code (or a derivative thereof) from -+ * the apps directory (application code) you must include an acknowledgement: -+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" -+ * -+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * The licence and distribution terms for any publically available version or -+ * derivative of this code cannot be changed. i.e. this code cannot simply be -+ * copied and put under another distribution licence -+ * [including the GNU Public Licence.] -+ */ -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/Makefile.shared b/CryptoPkg/Library/OpensslLib/openssl/Makefile.shared -new file mode 100644 -index 0000000..098e1ec ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/Makefile.shared -@@ -0,0 +1,622 @@ -+# -+# Helper makefile to link shared libraries in a portable way. -+# This is much simpler than libtool, and hopefully not too error-prone. -+# -+# The following variables need to be set on the command line to build -+# properly -+ -+# CC contains the current compiler. This one MUST be defined -+CC=cc -+CFLAGS=$(CFLAG) -+# LDFLAGS contains flags to be used when temporary object files (when building -+# shared libraries) are created, or when an application is linked. -+# SHARED_LDFLAGS contains flags to be used when the shared library is created. -+LDFLAGS=$(LDFLAG) -+SHARED_LDFLAGS=$(SHARED_LDFLAG) -+ -+RC=windres -+# SHARED_RCFLAGS are flags used with windres, i.e. when build for Cygwin -+# or Mingw. -+SHARED_RCFLAGS=$(SHARED_RCFLAG) -+ -+NM=nm -+ -+# LIBNAME contains just the name of the library, without prefix ("lib" -+# on Unix, "cyg" for certain forms under Cygwin...) or suffix (.a, .so, -+# .dll, ...). This one MUST have a value when using this makefile to -+# build shared libraries. -+# For example, to build libfoo.so, you need to do the following: -+#LIBNAME=foo -+LIBNAME= -+ -+# APPNAME contains just the name of the application, without suffix ("" -+# on Unix, ".exe" on Windows, ...). This one MUST have a value when using -+# this makefile to build applications. -+# For example, to build foo, you need to do the following: -+#APPNAME=foo -+APPNAME= -+ -+# DSTDIR is the directory where the built file should end up in. -+DSTDIR=. -+ -+# SRCDIR is the top directory of the source tree. -+SRCDIR=. -+ -+# OBJECTS contains all the object files to link together into the application. -+# This must contain at least one object file. -+#OBJECTS=foo.o -+OBJECTS= -+ -+# LIBEXTRAS contains extra modules to link together with the library. -+# For example, if a second library, say libbar.a needs to be linked into -+# libfoo.so, you need to do the following: -+#LIBEXTRAS=libbar.a -+# Note that this MUST be used when using the link_dso targets, to hold the -+# names of all object files that go into the target shared object. -+LIBEXTRAS= -+ -+# LIBVERSION contains the current version of the library. -+# For example, to build libfoo.so.1.2, you need to do the following: -+#LIBVERSION=1.2 -+LIBVERSION= -+ -+# LIBCOMPATVERSIONS contains the compatibility versions (a list) of -+# the library. They MUST be in decreasing order. -+# For example, if libfoo.so.1.2.1 is backward compatible with libfoo.so.1.2 -+# and libfoo.so.1, you need to do the following: -+#LIBCOMPATVERSIONS=1.2 1 -+# Note that on systems that use sonames, the last number will appear as -+# part of it. -+# It's also possible, for systems that support it (Tru64, for example), -+# to add extra compatibility info with more precision, by adding a second -+# list of versions, separated from the first with a semicolon, like this: -+#LIBCOMPATVERSIONS=1.2 1;1.2.0 1.1.2 1.1.1 1.1.0 1.0.0 -+LIBCOMPATVERSIONS= -+ -+# LIBDEPS contains all the flags necessary to cover all necessary -+# dependencies to other libraries. -+LIBDEPS= -+ -+#------------------------------------------------------------------------------ -+# The rest is private to this makefile. -+ -+SET_X=: -+#SET_X=set -x -+ -+top: -+ echo "Trying to use this makefile interactively? Don't." -+ -+CALC_VERSIONS= \ -+ SHLIB_COMPAT=; SHLIB_SOVER=; \ -+ if [ -n "$(LIBVERSION)$(LIBCOMPATVERSIONS)" ]; then \ -+ prev=""; \ -+ for v in `echo "$(LIBVERSION) $(LIBCOMPATVERSIONS)" | cut -d';' -f1`; do \ -+ SHLIB_SOVER_NODOT=$$v; \ -+ SHLIB_SOVER=.$$v; \ -+ if [ -n "$$prev" ]; then \ -+ SHLIB_COMPAT="$$SHLIB_COMPAT .$$prev"; \ -+ fi; \ -+ prev=$$v; \ -+ done; \ -+ fi -+ -+LINK_APP= \ -+ ( $(SET_X); \ -+ LIBDEPS="$${LIBDEPS:-$(LIBDEPS)}"; \ -+ LDCMD="$${LDCMD:-$(CC)}"; LDFLAGS="$${LDFLAGS:-$(CFLAGS) $(LDFLAGS)}"; \ -+ LIBPATH=`for x in $$LIBDEPS; do echo $$x; done | sed -e 's/^ *-L//;t' -e d | uniq`; \ -+ LIBPATH=`echo $$LIBPATH | sed -e 's/ /:/g'`; \ -+ echo LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \ -+ $${LDCMD} $${LDFLAGS} -o $${APPNAME:=$(APPNAME)} $(OBJECTS) $${LIBDEPS}; \ -+ LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \ -+ $${LDCMD} $${LDFLAGS} -o $${APPNAME:=$(APPNAME)} $(OBJECTS) $${LIBDEPS} ) -+ -+LINK_SO= \ -+ ( $(SET_X); \ -+ LIBDEPS="$${LIBDEPS:-$(LIBDEPS)}"; \ -+ SHAREDCMD="$${SHAREDCMD:-$(CC)}"; \ -+ SHAREDFLAGS="$${SHAREDFLAGS:-$(CFLAGS) $(SHARED_LDFLAGS)}"; \ -+ LIBPATH=`for x in $$LIBDEPS; do echo $$x; done | sed -e 's/^ *-L//;t' -e d | uniq`; \ -+ LIBPATH=`echo $$LIBPATH | sed -e 's/ /:/g'`; \ -+ echo LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \ -+ $${SHAREDCMD} $${SHAREDFLAGS} \ -+ -o $(DSTDIR)/$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX \ -+ $$ALLSYMSFLAGS $$SHOBJECTS $$NOALLSYMSFLAGS $$LIBDEPS; \ -+ LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \ -+ $${SHAREDCMD} $${SHAREDFLAGS} \ -+ -o $(DSTDIR)/$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX \ -+ $$ALLSYMSFLAGS $$SHOBJECTS $$NOALLSYMSFLAGS $$LIBDEPS \ -+ ) && $(SYMLINK_SO) -+ -+SYMLINK_SO= \ -+ if [ -n "$$INHIBIT_SYMLINKS" ]; then :; else \ -+ prev=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; \ -+ if [ -n "$$SHLIB_COMPAT" ]; then \ -+ for x in $$SHLIB_COMPAT; do \ -+ ( $(SET_X); rm -f $(DSTDIR)/$$SHLIB$$x$$SHLIB_SUFFIX; \ -+ ln -s $$prev $(DSTDIR)/$$SHLIB$$x$$SHLIB_SUFFIX ); \ -+ prev=$$SHLIB$$x$$SHLIB_SUFFIX; \ -+ done; \ -+ fi; \ -+ if [ -n "$$SHLIB_SOVER" ]; then \ -+ ( $(SET_X); rm -f $(DSTDIR)/$$SHLIB$$SHLIB_SUFFIX; \ -+ ln -s $$prev $(DSTDIR)/$$SHLIB$$SHLIB_SUFFIX ); \ -+ fi; \ -+ fi -+ -+LINK_SO_SHLIB= SHOBJECTS="$(DSTDIR)/lib$(LIBNAME).a $(LIBEXTRAS)"; $(LINK_SO) -+LINK_SO_DSO= INHIBIT_SYMLINKS=yes; SHOBJECTS="$(LIBEXTRAS)"; $(LINK_SO) -+ -+LINK_SO_SHLIB_VIA_O= \ -+ SHOBJECTS=$(DSTDIR)/lib$(LIBNAME).o; \ -+ ALL=$$ALLSYMSFLAGS; ALLSYMSFLAGS=; NOALLSYMSFLAGS=; \ -+ ( echo ld $(LDFLAGS) -r -o $$SHOBJECTS $$ALL lib$(LIBNAME).a $(LIBEXTRAS); \ -+ ld $(LDFLAGS) -r -o $$SHOBJECTS $$ALL $(DSTDIR)/lib$(LIBNAME).a $(LIBEXTRAS) ); \ -+ $(LINK_SO) && ( echo rm -f $$SHOBJECTS; rm -f $$SHOBJECTS ) -+ -+LINK_SO_SHLIB_UNPACKED= \ -+ UNPACKDIR=link_tmp.$$$$; rm -rf $$UNPACKDIR; mkdir $$UNPACKDIR; \ -+ (cd $$UNPACKDIR; ar x ../$(DSTDIR)/lib$(LIBNAME).a) && \ -+ ([ -z "$(LIBEXTRAS)" ] || cp $(LIBEXTRAS) $$UNPACKDIR) && \ -+ SHOBJECTS=$$UNPACKDIR/*.o; \ -+ $(LINK_SO) && rm -rf $$UNPACKDIR -+ -+DETECT_GNU_LD=($(CC) -Wl,-V /dev/null 2>&1 | grep '^GNU ld' )>/dev/null -+ -+DO_GNU_SO_COMMON=\ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX" -+DO_GNU_DSO=\ -+ SHLIB=$(LIBNAME).so; \ -+ SHLIB_SOVER=; \ -+ SHLIB_SUFFIX=; \ -+ $(DO_GNU_SO_COMMON) -+DO_GNU_SO=\ -+ $(CALC_VERSIONS); \ -+ SHLIB=lib$(LIBNAME).so; \ -+ ALLSYMSFLAGS='-Wl,--whole-archive'; \ -+ NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \ -+ $(DO_GNU_SO_COMMON) -+DO_GNU_APP=LDFLAGS="$(CFLAGS) $(LDFLAGS)" -+ -+#This is rather special. It's a special target with which one can link -+#applications without bothering with any features that have anything to -+#do with shared libraries, for example when linking against static -+#libraries. It's mostly here to avoid a lot of conditionals everywhere -+#else... -+link_app.: -+ $(LINK_APP) -+ -+link_dso.gnu: -+ @ $(DO_GNU_DSO); $(LINK_SO_DSO) -+link_shlib.gnu: -+ @ $(DO_GNU_SO); $(LINK_SO_SHLIB) -+link_app.gnu: -+ @ $(DO_GNU_APP); $(LINK_APP) -+ -+link_shlib.linux-shared: -+ @$(PERL) $(SRCDIR)/util/mkdef.pl $(LIBNAME) linux >$(LIBNAME).map; \ -+ $(DO_GNU_SO); \ -+ ALLSYMSFLAGS='-Wl,--whole-archive,--version-script=$(LIBNAME).map'; \ -+ $(LINK_SO_SHLIB) -+ -+link_dso.bsd: -+ @if $(DETECT_GNU_LD); then $(DO_GNU_DSO); else \ -+ SHLIB=$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ LIBDEPS=" "; \ -+ ALLSYMSFLAGS=; \ -+ NOALLSYMSFLAGS=; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -nostdlib"; \ -+ fi; $(LINK_SO_DSO) -+link_shlib.bsd: -+ @if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \ -+ $(CALC_VERSIONS); \ -+ SHLIB=lib$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ LIBDEPS=" "; \ -+ ALLSYMSFLAGS="-Wl,-Bforcearchive"; \ -+ NOALLSYMSFLAGS=; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -nostdlib"; \ -+ fi; $(LINK_SO_SHLIB) -+link_app.bsd: -+ @if $(DETECT_GNU_LD); then $(DO_GNU_APP); else \ -+ LDFLAGS="$(CFLAGS) $(LDFLAGS)"; \ -+ fi; $(LINK_APP) -+ -+# For Darwin AKA Mac OS/X (dyld) -+# Originally link_dso.darwin produced .so, because it was hard-coded -+# in dso_dlfcn module. At later point dso_dlfcn switched to .dylib -+# extension in order to allow for run-time linking with vendor- -+# supplied shared libraries such as libz, so that link_dso.darwin had -+# to be harmonized with it. This caused minor controversy, because -+# it was believed that dlopen can't be used to dynamically load -+# .dylib-s, only so called bundle modules (ones linked with -bundle -+# flag). The belief seems to be originating from pre-10.4 release, -+# where dlfcn functionality was emulated by dlcompat add-on. In -+# 10.4 dlopen was rewritten as native part of dyld and is documented -+# to be capable of loading both dynamic libraries and bundles. In -+# order to provide compatibility with pre-10.4 dlopen, modules are -+# linked with -bundle flag, which makes .dylib extension misleading. -+# It works, because dlopen is [and always was] extension-agnostic. -+# Alternative to this heuristic approach is to develop specific -+# MacOS X dso module relying on whichever "native" dyld interface. -+link_dso.darwin: -+ @ SHLIB=$(LIBNAME); \ -+ SHLIB_SUFFIX=.dylib; \ -+ ALLSYMSFLAGS=''; \ -+ NOALLSYMSFLAGS=''; \ -+ SHAREDFLAGS="$(CFLAGS) `echo $(SHARED_LDFLAGS) | sed s/dynamiclib/bundle/`"; \ -+ $(LINK_SO_DSO) -+link_shlib.darwin: -+ @ $(CALC_VERSIONS); \ -+ SHLIB=lib$(LIBNAME); \ -+ SHLIB_SUFFIX=.dylib; \ -+ ALLSYMSFLAGS='-all_load'; \ -+ NOALLSYMSFLAGS=''; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS)"; \ -+ if [ -n "$(LIBVERSION)" ]; then \ -+ SHAREDFLAGS="$$SHAREDFLAGS -current_version $(LIBVERSION)"; \ -+ fi; \ -+ if [ -n "$$SHLIB_SOVER_NODOT" ]; then \ -+ SHAREDFLAGS="$$SHAREDFLAGS -compatibility_version $$SHLIB_SOVER_NODOT"; \ -+ fi; \ -+ SHAREDFLAGS="$$SHAREDFLAGS -install_name $(INSTALLTOP)/$(LIBDIR)/$$SHLIB$(SHLIB_EXT)"; \ -+ $(LINK_SO_SHLIB) -+link_app.darwin: # is there run-path on darwin? -+ $(LINK_APP) -+ -+link_dso.cygwin: -+ @SHLIB=$(LIBNAME); \ -+ SHLIB_SUFFIX=.dll; \ -+ ALLSYMSFLAGS=''; \ -+ NOALLSYMSFLAGS=''; \ -+ base=-Wl,--enable-auto-image-base; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared $$base -Wl,-Bsymbolic"; \ -+ $(LINK_SO_DSO) -+link_shlib.cygwin: -+ @ $(CALC_VERSIONS); \ -+ INHIBIT_SYMLINKS=yes; \ -+ SHLIB=cyg$(LIBNAME); SHLIB_SOVER=-$(LIBVERSION); SHLIB_SUFFIX=.dll; \ -+ dll_name=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; \ -+ echo "$(PERL) $(SRCDIR)/util/mkrc.pl $$dll_name |" \ -+ "$(RC) $(SHARED_RCFLAGS) -o rc.o"; \ -+ $(PERL) $(SRCDIR)/util/mkrc.pl $$dll_name | \ -+ $(RC) $(SHARED_RCFLAGS) -o rc.o; \ -+ ALLSYMSFLAGS='-Wl,--whole-archive'; \ -+ NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,--enable-auto-image-base -Wl,-Bsymbolic -Wl,--out-implib,lib$(LIBNAME).dll.a rc.o"; \ -+ $(LINK_SO_SHLIB) || exit 1; \ -+ rm rc.o -+link_app.cygwin: -+ $(LINK_APP) -+ -+# link_dso.mingw-shared and link_app.mingw-shared are mapped to the -+# corresponding cygwin targets, as they do the exact same thing. -+link_shlib.mingw: -+ @ $(CALC_VERSIONS); \ -+ INHIBIT_SYMLINKS=yes; \ -+ arch=; \ -+ if expr $(PLATFORM) : mingw64 > /dev/null; then arch=-x64; fi; \ -+ sover=`echo $(LIBVERSION) | sed -e 's/\./_/g'` ; \ -+ SHLIB=lib$(LIBNAME); \ -+ SHLIB_SOVER=-$$sover$$arch; \ -+ SHLIB_SUFFIX=.dll; \ -+ dll_name=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; \ -+ base=; [ $(LIBNAME) = "crypto" -a -n "$(FIPSCANLIB)" ] && base=-Wl,--image-base,0x63000000; \ -+ $(PERL) $(SRCDIR)/util/mkdef.pl 32 $(LIBNAME) \ -+ | sed -e 's|^\(LIBRARY *\)$(LIBNAME)32|\1'"$$dll_name"'|' \ -+ > $(LIBNAME).def; \ -+ echo "$(PERL) $(SRCDIR)/util/mkrc.pl $$dll_name |" \ -+ "$(RC) $(SHARED_RCFLAGS) -o rc.o"; \ -+ $(PERL) $(SRCDIR)/util/mkrc.pl $$dll_name | \ -+ $(RC) $(SHARED_RCFLAGS) -o rc.o; \ -+ ALLSYMSFLAGS='-Wl,--whole-archive'; \ -+ NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared $$base -Wl,-Bsymbolic -Wl,--out-implib,lib$(LIBNAME).dll.a $(LIBNAME).def rc.o"; \ -+ $(LINK_SO_SHLIB) || exit 1; \ -+ rm $(LIBNAME).def rc.o -+ -+link_dso.alpha-osf1: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_DSO); \ -+ else \ -+ SHLIB=$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS=''; \ -+ NOALLSYMSFLAGS=''; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-B,symbolic"; \ -+ fi; \ -+ $(LINK_SO_DSO) -+link_shlib.alpha-osf1: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_SO); \ -+ else \ -+ SHLIB=lib$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \ -+ if [ -n "$$SHLIB_HIST" ]; then \ -+ SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \ -+ else \ -+ SHLIB_HIST="$(LIBVERSION)"; \ -+ fi; \ -+ SHLIB_SOVER=; \ -+ ALLSYMSFLAGS='-all'; \ -+ NOALLSYMSFLAGS='-none'; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-B,symbolic"; \ -+ if [ -n "$$SHLIB_HIST" ]; then \ -+ SHAREDFLAGS="$$SHAREDFLAGS -set_version $$SHLIB_HIST"; \ -+ fi; \ -+ fi; \ -+ $(LINK_SO_SHLIB) -+link_app.alpha-osf1: -+ @if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_APP); \ -+ else \ -+ LDFLAGS="$(CFLAGS) $(LDFLAGS)"; \ -+ fi; \ -+ $(LINK_APP) -+ -+link_dso.solaris: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_DSO); \ -+ else \ -+ $(CALC_VERSIONS); \ -+ SHLIB=$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS=""; \ -+ NOALLSYMSFLAGS=""; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \ -+ fi; \ -+ $(LINK_SO_DSO) -+link_shlib.solaris: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_SO); \ -+ else \ -+ $(CALC_VERSIONS); \ -+ SHLIB=lib$(LIBNAME).so; \ -+ SHLIB_SUFFIX=;\ -+ $(PERL) $(SRCDIR)/util/mkdef.pl $(LIBNAME) linux >$(LIBNAME).map; \ -+ ALLSYMSFLAGS="-Wl,-z,allextract,-M,$(LIBNAME).map"; \ -+ NOALLSYMSFLAGS="-Wl,-z,defaultextract"; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \ -+ fi; \ -+ $(LINK_SO_SHLIB) -+link_app.solaris: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_APP); \ -+ else \ -+ LDFLAGS="$(CFLAGS) $(LDFLAGS)"; \ -+ fi; \ -+ $(LINK_APP) -+ -+# OpenServer 5 native compilers used -+link_dso.svr3: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_DSO); \ -+ else \ -+ $(CALC_VERSIONS); \ -+ SHLIB=$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS=''; \ -+ NOALLSYMSFLAGS=''; \ -+ SHAREDFLAGS="$(CFLAGS) -G -h $$SHLIB$$SHLIB_SUFFIX"; \ -+ fi; \ -+ $(LINK_SO_DSO) -+link_shlib.svr3: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_SO); \ -+ else \ -+ $(CALC_VERSIONS); \ -+ SHLIB=lib$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS=''; \ -+ NOALLSYMSFLAGS=''; \ -+ SHAREDFLAGS="$(CFLAGS) -G -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \ -+ fi; \ -+ $(LINK_SO_SHLIB_UNPACKED) -+link_app.svr3: -+ @$(DETECT_GNU_LD) && $(DO_GNU_APP); \ -+ $(LINK_APP) -+ -+# UnixWare 7 and OpenUNIX 8 native compilers used -+link_dso.svr5: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_DSO); \ -+ else \ -+ SHARE_FLAG='-G'; \ -+ ($(CC) -v 2>&1 | grep gcc) > /dev/null && SHARE_FLAG='-shared'; \ -+ SHLIB=$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS=''; \ -+ NOALLSYMSFLAGS=''; \ -+ SHAREDFLAGS="$(CFLAGS) $${SHARE_FLAG} -h $$SHLIB$$SHLIB_SUFFIX"; \ -+ fi; \ -+ $(LINK_SO_DSO) -+link_shlib.svr5: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_SO); \ -+ else \ -+ $(CALC_VERSIONS); \ -+ SHARE_FLAG='-G'; \ -+ ($(CC) -v 2>&1 | grep gcc) > /dev/null && SHARE_FLAG='-shared'; \ -+ SHLIB=lib$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS=''; \ -+ NOALLSYMSFLAGS=''; \ -+ SHAREDFLAGS="$(CFLAGS) $${SHARE_FLAG} -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX"; \ -+ fi; \ -+ $(LINK_SO_SHLIB_UNPACKED) -+link_app.svr5: -+ @$(DETECT_GNU_LD) && $(DO_GNU_APP); \ -+ $(LINK_APP) -+ -+link_dso.irix: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_DSO); \ -+ else \ -+ SHLIB=$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS=""; \ -+ NOALLSYMSFLAGS=""; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-soname,$$SHLIB$$SHLIB_SUFFIX,-B,symbolic"; \ -+ fi; \ -+ $(LINK_SO_DSO) -+link_shlib.irix: -+ @ if $(DETECT_GNU_LD); then \ -+ $(DO_GNU_SO); \ -+ else \ -+ $(CALC_VERSIONS); \ -+ SHLIB=lib$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ MINUSWL=""; \ -+ ($(CC) -v 2>&1 | grep gcc) > /dev/null && MINUSWL="-Wl,"; \ -+ ALLSYMSFLAGS="$${MINUSWL}-all"; \ -+ NOALLSYMSFLAGS="$${MINUSWL}-none"; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-soname,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX,-B,symbolic"; \ -+ fi; \ -+ $(LINK_SO_SHLIB) -+link_app.irix: -+ @LDFLAGS="$(CFLAGS) $(LDFLAGS)"; \ -+ $(LINK_APP) -+ -+# 32-bit PA-RISC HP-UX embeds the -L pathname of libs we link with, so -+# we compensate for it with +cdp ../: and +cdp ./:. Yes, these rewrite -+# rules imply that we can only link one level down in catalog structure, -+# but that's what takes place for the moment of this writing. +cdp option -+# was introduced in HP-UX 11.x and applies in 32-bit PA-RISC link -+# editor context only [it's simply ignored in other cases, which are all -+# ELFs by the way]. -+# -+link_dso.hpux: -+ @if $(DETECT_GNU_LD); then $(DO_GNU_DSO); else \ -+ SHLIB=$(LIBNAME).sl; \ -+ expr "$(CFLAGS)" : '.*DSO_DLFCN' > /dev/null && SHLIB=$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS=''; \ -+ NOALLSYMSFLAGS=''; \ -+ expr $(PLATFORM) : 'hpux64' > /dev/null && ALLSYMSFLAGS='-Wl,+forceload'; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-B,symbolic,+vnocompatwarnings,-z,+s,+h,$$SHLIB$$SHLIB_SUFFIX,+cdp,../:,+cdp,./:"; \ -+ fi; \ -+ rm -f $(DSTDIR)/$$SHLIB$$SHLIB_SUFFIX || :; \ -+ $(LINK_SO_DSO) && chmod a=rx $(DSTDIR)/$$SHLIB$$SHLIB_SUFFIX -+link_shlib.hpux: -+ @if $(DETECT_GNU_LD); then $(DO_GNU_SO); else \ -+ $(CALC_VERSIONS); \ -+ SHLIB=lib$(LIBNAME).sl; \ -+ expr $(PLATFORM) : '.*ia64' > /dev/null && SHLIB=lib$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS='-Wl,-Fl'; \ -+ NOALLSYMSFLAGS=''; \ -+ expr $(PLATFORM) : 'hpux64' > /dev/null && ALLSYMSFLAGS='-Wl,+forceload'; \ -+ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-B,symbolic,+vnocompatwarnings,-z,+s,+h,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX,+cdp,../:,+cdp,./:"; \ -+ fi; \ -+ rm -f $(DSTDIR)/$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX || :; \ -+ $(LINK_SO_SHLIB) && chmod a=rx $(DSTDIR)/$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -+link_app.hpux: -+ @if $(DETECT_GNU_LD); then $(DO_GNU_APP); else \ -+ LDFLAGS="$(CFLAGS) $(LDFLAGS) -Wl,+s,+cdp,../:,+cdp,./:"; \ -+ fi; \ -+ $(LINK_APP) -+ -+link_dso.aix: -+ @OBJECT_MODE=`expr "x$(SHARED_LDFLAGS)" : 'x\-[a-z]*\(64\)'` || :; \ -+ OBJECT_MODE=$${OBJECT_MODE:-32}; export OBJECT_MODE; \ -+ SHLIB=$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS=''; \ -+ NOALLSYMSFLAGS=''; \ -+ SHAREDFLAGS='$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-bexpall,-bnolibpath,-bM:SRE'; \ -+ rm -f $(DSTDIR)/$$SHLIB$$SHLIB_SOVER 2>&1 > /dev/null ; \ -+ $(LINK_SO_DSO); -+link_shlib.aix: -+ @ $(CALC_VERSIONS); \ -+ OBJECT_MODE=`expr "x$(SHARED_LDFLAGS)" : 'x\-[a-z]*\(64\)'` || : ; \ -+ OBJECT_MODE=$${OBJECT_MODE:-32}; export OBJECT_MODE; \ -+ SHLIB=lib$(LIBNAME).so; \ -+ SHLIB_SUFFIX=; \ -+ ALLSYMSFLAGS='-bnogc'; \ -+ NOALLSYMSFLAGS=''; \ -+ SHAREDFLAGS='$(CFLAGS) $(SHARED_LDFLAGS) -Wl,-bexpall,-bnolibpath,-bM:SRE'; \ -+ rm -f $(DSTDIR)/$$SHLIB$$SHLIB_SOVER 2>&1 > /dev/null ; \ -+ $(LINK_SO_SHLIB_VIA_O) -+link_app.aix: -+ LDFLAGS="$(CFLAGS) -Wl,-bsvr4 $(LDFLAGS)"; \ -+ $(LINK_APP) -+ -+ -+# Targets to build symbolic links when needed -+symlink.gnu symlink.solaris symlink.svr3 symlink.svr5 symlink.irix \ -+symlink.aix: -+ @ $(CALC_VERSIONS); \ -+ SHLIB=lib$(LIBNAME).so; \ -+ $(SYMLINK_SO) -+symlink.darwin: -+ @ $(CALC_VERSIONS); \ -+ SHLIB=lib$(LIBNAME); \ -+ SHLIB_SUFFIX=.dylib; \ -+ $(SYMLINK_SO) -+symlink.hpux: -+ @ $(CALC_VERSIONS); \ -+ SHLIB=lib$(LIBNAME).sl; \ -+ expr $(PLATFORM) : '.*ia64' > /dev/null && SHLIB=lib$(LIBNAME).so; \ -+ $(SYMLINK_SO) -+# The following lines means those specific architectures do no symlinks -+symlink.cygwin symlink.alpha-osf1 symlink.tru64 symlink.tru64-rpath: -+ -+# Compatibility targets -+link_dso.bsd-gcc-shared link_dso.linux-shared link_dso.gnu-shared: link_dso.gnu -+link_shlib.bsd-gcc-shared: link_shlib.linux-shared -+link_shlib.gnu-shared: link_shlib.gnu -+link_app.bsd-gcc-shared link_app.linux-shared link_app.gnu-shared: link_app.gnu -+symlink.bsd-gcc-shared symlink.bsd-shared symlink.linux-shared symlink.gnu-shared: symlink.gnu -+link_dso.bsd-shared: link_dso.bsd -+link_shlib.bsd-shared: link_shlib.bsd -+link_app.bsd-shared: link_app.bsd -+link_dso.darwin-shared: link_dso.darwin -+link_shlib.darwin-shared: link_shlib.darwin -+link_app.darwin-shared: link_app.darwin -+symlink.darwin-shared: symlink.darwin -+link_dso.cygwin-shared: link_dso.cygwin -+link_shlib.cygwin-shared: link_shlib.cygwin -+link_app.cygwin-shared: link_app.cygwin -+symlink.cygwin-shared: symlink.cygwin -+link_dso.mingw-shared: link_dso.cygwin -+link_shlib.mingw-shared: link_shlib.mingw -+link_app.mingw-shared: link_app.cygwin -+symlink.mingw-shared: symlink.cygwin -+link_dso.alpha-osf1-shared: link_dso.alpha-osf1 -+link_shlib.alpha-osf1-shared: link_shlib.alpha-osf1 -+link_app.alpha-osf1-shared: link_app.alpha-osf1 -+symlink.alpha-osf1-shared: symlink.alpha-osf1 -+link_dso.tru64-shared: link_dso.tru64 -+link_shlib.tru64-shared: link_shlib.tru64 -+link_app.tru64-shared: link_app.tru64 -+symlink.tru64-shared: symlink.tru64 -+link_dso.tru64-shared-rpath: link_dso.tru64-rpath -+link_shlib.tru64-shared-rpath: link_shlib.tru64-rpath -+link_app.tru64-shared-rpath: link_app.tru64-rpath -+symlink.tru64-shared-rpath: symlink.tru64-rpath -+link_dso.solaris-shared: link_dso.solaris -+link_shlib.solaris-shared: link_shlib.solaris -+link_app.solaris-shared: link_app.solaris -+symlink.solaris-shared: symlink.solaris -+link_dso.svr3-shared: link_dso.svr3 -+link_shlib.svr3-shared: link_shlib.svr3 -+link_app.svr3-shared: link_app.svr3 -+symlink.svr3-shared: symlink.svr3 -+link_dso.svr5-shared: link_dso.svr5 -+link_shlib.svr5-shared: link_shlib.svr5 -+link_app.svr5-shared: link_app.svr5 -+symlink.svr5-shared: symlink.svr5 -+link_dso.irix-shared: link_dso.irix -+link_shlib.irix-shared: link_shlib.irix -+link_app.irix-shared: link_app.irix -+symlink.irix-shared: symlink.irix -+link_dso.hpux-shared: link_dso.hpux -+link_shlib.hpux-shared: link_shlib.hpux -+link_app.hpux-shared: link_app.hpux -+symlink.hpux-shared: symlink.hpux -+link_dso.aix-shared: link_dso.aix -+link_shlib.aix-shared: link_shlib.aix -+link_app.aix-shared: link_app.aix -+symlink.aix-shared: symlink.aix -diff --git a/CryptoPkg/Library/OpensslLib/openssl/NEWS b/CryptoPkg/Library/OpensslLib/openssl/NEWS -new file mode 100644 -index 0000000..f331ec4 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/NEWS -@@ -0,0 +1,852 @@ -+ -+ NEWS -+ ==== -+ -+ This file gives a brief overview of the major changes between each OpenSSL -+ release. For more details please read the CHANGES file. -+ -+ Major changes between OpenSSL 1.1.0d and OpenSSL 1.1.0e [16 Feb 2017] -+ -+ o Encrypt-Then-Mac renegotiation crash (CVE-2017-3733) -+ -+ Major changes between OpenSSL 1.1.0c and OpenSSL 1.1.0d [26 Jan 2017] -+ -+ o Truncated packet could crash via OOB read (CVE-2017-3731) -+ o Bad (EC)DHE parameters cause a client crash (CVE-2017-3730) -+ o BN_mod_exp may produce incorrect results on x86_64 (CVE-2017-3732) -+ -+ Major changes between OpenSSL 1.1.0b and OpenSSL 1.1.0c [10 Nov 2016] -+ -+ o ChaCha20/Poly1305 heap-buffer-overflow (CVE-2016-7054) -+ o CMS Null dereference (CVE-2016-7053) -+ o Montgomery multiplication may produce incorrect results (CVE-2016-7055) -+ -+ Major changes between OpenSSL 1.1.0a and OpenSSL 1.1.0b [26 Sep 2016] -+ -+ o Fix Use After Free for large message sizes (CVE-2016-6309) -+ -+ Major changes between OpenSSL 1.1.0 and OpenSSL 1.1.0a [22 Sep 2016] -+ -+ o OCSP Status Request extension unbounded memory growth (CVE-2016-6304) -+ o SSL_peek() hang on empty record (CVE-2016-6305) -+ o Excessive allocation of memory in tls_get_message_header() -+ (CVE-2016-6307) -+ o Excessive allocation of memory in dtls1_preprocess_fragment() -+ (CVE-2016-6308) -+ -+ Major changes between OpenSSL 1.0.2h and OpenSSL 1.1.0 [25 Aug 2016] -+ -+ o Copyright text was shrunk to a boilerplate that points to the license -+ o "shared" builds are now the default when possible -+ o Added support for "pipelining" -+ o Added the AFALG engine -+ o New threading API implemented -+ o Support for ChaCha20 and Poly1305 added to libcrypto and libssl -+ o Support for extended master secret -+ o CCM ciphersuites -+ o Reworked test suite, now based on perl, Test::Harness and Test::More -+ o *Most* libcrypto and libssl public structures were made opaque, -+ including: -+ BIGNUM and associated types, EC_KEY and EC_KEY_METHOD, -+ DH and DH_METHOD, DSA and DSA_METHOD, RSA and RSA_METHOD, -+ BIO and BIO_METHOD, EVP_MD_CTX, EVP_MD, EVP_CIPHER_CTX, -+ EVP_CIPHER, EVP_PKEY and associated types, HMAC_CTX, -+ X509, X509_CRL, X509_OBJECT, X509_STORE_CTX, X509_STORE, -+ X509_LOOKUP, X509_LOOKUP_METHOD -+ o libssl internal structures made opaque -+ o SSLv2 support removed -+ o Kerberos ciphersuite support removed -+ o RC4 removed from DEFAULT ciphersuites in libssl -+ o 40 and 56 bit cipher support removed from libssl -+ o All public header files moved to include/openssl, no more symlinking -+ o SSL/TLS state machine, version negotiation and record layer rewritten -+ o EC revision: now operations use new EC_KEY_METHOD. -+ o Support for OCB mode added to libcrypto -+ o Support for asynchronous crypto operations added to libcrypto and libssl -+ o Deprecated interfaces can now be disabled at build time either -+ relative to the latest release via the "no-deprecated" Configure -+ argument, or via the "--api=1.1.0|1.0.0|0.9.8" option. -+ o Application software can be compiled with -DOPENSSL_API_COMPAT=version -+ to ensure that features deprecated in that version are not exposed. -+ o Support for RFC6698/RFC7671 DANE TLSA peer authentication -+ o Change of Configure to use --prefix as the main installation -+ directory location rather than --openssldir. The latter becomes -+ the directory for certs, private key and openssl.cnf exclusively. -+ o Reworked BIO networking library, with full support for IPv6. -+ o New "unified" build system -+ o New security levels -+ o Support for scrypt algorithm -+ o Support for X25519 -+ o Extended SSL_CONF support using configuration files -+ o KDF algorithm support. Implement TLS PRF as a KDF. -+ o Support for Certificate Transparency -+ o HKDF support. -+ -+ Major changes between OpenSSL 1.0.2g and OpenSSL 1.0.2h [3 May 2016] -+ -+ o Prevent padding oracle in AES-NI CBC MAC check (CVE-2016-2107) -+ o Fix EVP_EncodeUpdate overflow (CVE-2016-2105) -+ o Fix EVP_EncryptUpdate overflow (CVE-2016-2106) -+ o Prevent ASN.1 BIO excessive memory allocation (CVE-2016-2109) -+ o EBCDIC overread (CVE-2016-2176) -+ o Modify behavior of ALPN to invoke callback after SNI/servername -+ callback, such that updates to the SSL_CTX affect ALPN. -+ o Remove LOW from the DEFAULT cipher list. This removes singles DES from -+ the default. -+ o Only remove the SSLv2 methods with the no-ssl2-method option. -+ -+ Major changes between OpenSSL 1.0.2f and OpenSSL 1.0.2g [1 Mar 2016] -+ -+ o Disable weak ciphers in SSLv3 and up in default builds of OpenSSL. -+ o Disable SSLv2 default build, default negotiation and weak ciphers -+ (CVE-2016-0800) -+ o Fix a double-free in DSA code (CVE-2016-0705) -+ o Disable SRP fake user seed to address a server memory leak -+ (CVE-2016-0798) -+ o Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption -+ (CVE-2016-0797) -+ o Fix memory issues in BIO_*printf functions (CVE-2016-0799) -+ o Fix side channel attack on modular exponentiation (CVE-2016-0702) -+ -+ Major changes between OpenSSL 1.0.2e and OpenSSL 1.0.2f [28 Jan 2016] -+ -+ o DH small subgroups (CVE-2016-0701) -+ o SSLv2 doesn't block disabled ciphers (CVE-2015-3197) -+ -+ Major changes between OpenSSL 1.0.2d and OpenSSL 1.0.2e [3 Dec 2015] -+ -+ o BN_mod_exp may produce incorrect results on x86_64 (CVE-2015-3193) -+ o Certificate verify crash with missing PSS parameter (CVE-2015-3194) -+ o X509_ATTRIBUTE memory leak (CVE-2015-3195) -+ o Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs -+ o In DSA_generate_parameters_ex, if the provided seed is too short, -+ return an error -+ -+ Major changes between OpenSSL 1.0.2c and OpenSSL 1.0.2d [9 Jul 2015] -+ -+ o Alternate chains certificate forgery (CVE-2015-1793) -+ o Race condition handling PSK identify hint (CVE-2015-3196) -+ -+ Major changes between OpenSSL 1.0.2b and OpenSSL 1.0.2c [12 Jun 2015] -+ -+ o Fix HMAC ABI incompatibility -+ -+ Major changes between OpenSSL 1.0.2a and OpenSSL 1.0.2b [11 Jun 2015] -+ -+ o Malformed ECParameters causes infinite loop (CVE-2015-1788) -+ o Exploitable out-of-bounds read in X509_cmp_time (CVE-2015-1789) -+ o PKCS7 crash with missing EnvelopedContent (CVE-2015-1790) -+ o CMS verify infinite loop with unknown hash function (CVE-2015-1792) -+ o Race condition handling NewSessionTicket (CVE-2015-1791) -+ -+ Major changes between OpenSSL 1.0.2 and OpenSSL 1.0.2a [19 Mar 2015] -+ -+ o OpenSSL 1.0.2 ClientHello sigalgs DoS fix (CVE-2015-0291) -+ o Multiblock corrupted pointer fix (CVE-2015-0290) -+ o Segmentation fault in DTLSv1_listen fix (CVE-2015-0207) -+ o Segmentation fault in ASN1_TYPE_cmp fix (CVE-2015-0286) -+ o Segmentation fault for invalid PSS parameters fix (CVE-2015-0208) -+ o ASN.1 structure reuse memory corruption fix (CVE-2015-0287) -+ o PKCS7 NULL pointer dereferences fix (CVE-2015-0289) -+ o DoS via reachable assert in SSLv2 servers fix (CVE-2015-0293) -+ o Empty CKE with client auth and DHE fix (CVE-2015-1787) -+ o Handshake with unseeded PRNG fix (CVE-2015-0285) -+ o Use After Free following d2i_ECPrivatekey error fix (CVE-2015-0209) -+ o X509_to_X509_REQ NULL pointer deref fix (CVE-2015-0288) -+ o Removed the export ciphers from the DEFAULT ciphers -+ -+ Major changes between OpenSSL 1.0.1l and OpenSSL 1.0.2 [22 Jan 2015]: -+ -+ o Suite B support for TLS 1.2 and DTLS 1.2 -+ o Support for DTLS 1.2 -+ o TLS automatic EC curve selection. -+ o API to set TLS supported signature algorithms and curves -+ o SSL_CONF configuration API. -+ o TLS Brainpool support. -+ o ALPN support. -+ o CMS support for RSA-PSS, RSA-OAEP, ECDH and X9.42 DH. -+ -+ Major changes between OpenSSL 1.0.1k and OpenSSL 1.0.1l [15 Jan 2015] -+ -+ o Build fixes for the Windows and OpenVMS platforms -+ -+ Major changes between OpenSSL 1.0.1j and OpenSSL 1.0.1k [8 Jan 2015] -+ -+ o Fix for CVE-2014-3571 -+ o Fix for CVE-2015-0206 -+ o Fix for CVE-2014-3569 -+ o Fix for CVE-2014-3572 -+ o Fix for CVE-2015-0204 -+ o Fix for CVE-2015-0205 -+ o Fix for CVE-2014-8275 -+ o Fix for CVE-2014-3570 -+ -+ Major changes between OpenSSL 1.0.1i and OpenSSL 1.0.1j [15 Oct 2014] -+ -+ o Fix for CVE-2014-3513 -+ o Fix for CVE-2014-3567 -+ o Mitigation for CVE-2014-3566 (SSL protocol vulnerability) -+ o Fix for CVE-2014-3568 -+ -+ Major changes between OpenSSL 1.0.1h and OpenSSL 1.0.1i [6 Aug 2014] -+ -+ o Fix for CVE-2014-3512 -+ o Fix for CVE-2014-3511 -+ o Fix for CVE-2014-3510 -+ o Fix for CVE-2014-3507 -+ o Fix for CVE-2014-3506 -+ o Fix for CVE-2014-3505 -+ o Fix for CVE-2014-3509 -+ o Fix for CVE-2014-5139 -+ o Fix for CVE-2014-3508 -+ -+ Major changes between OpenSSL 1.0.1g and OpenSSL 1.0.1h [5 Jun 2014] -+ -+ o Fix for CVE-2014-0224 -+ o Fix for CVE-2014-0221 -+ o Fix for CVE-2014-0198 -+ o Fix for CVE-2014-0195 -+ o Fix for CVE-2014-3470 -+ o Fix for CVE-2010-5298 -+ -+ Major changes between OpenSSL 1.0.1f and OpenSSL 1.0.1g [7 Apr 2014] -+ -+ o Fix for CVE-2014-0160 -+ o Add TLS padding extension workaround for broken servers. -+ o Fix for CVE-2014-0076 -+ -+ Major changes between OpenSSL 1.0.1e and OpenSSL 1.0.1f [6 Jan 2014] -+ -+ o Don't include gmt_unix_time in TLS server and client random values -+ o Fix for TLS record tampering bug CVE-2013-4353 -+ o Fix for TLS version checking bug CVE-2013-6449 -+ o Fix for DTLS retransmission bug CVE-2013-6450 -+ -+ Major changes between OpenSSL 1.0.1d and OpenSSL 1.0.1e [11 Feb 2013]: -+ -+ o Corrected fix for CVE-2013-0169 -+ -+ Major changes between OpenSSL 1.0.1c and OpenSSL 1.0.1d [4 Feb 2013]: -+ -+ o Fix renegotiation in TLS 1.1, 1.2 by using the correct TLS version. -+ o Include the fips configuration module. -+ o Fix OCSP bad key DoS attack CVE-2013-0166 -+ o Fix for SSL/TLS/DTLS CBC plaintext recovery attack CVE-2013-0169 -+ o Fix for TLS AESNI record handling flaw CVE-2012-2686 -+ -+ Major changes between OpenSSL 1.0.1b and OpenSSL 1.0.1c [10 May 2012]: -+ -+ o Fix TLS/DTLS record length checking bug CVE-2012-2333 -+ o Don't attempt to use non-FIPS composite ciphers in FIPS mode. -+ -+ Major changes between OpenSSL 1.0.1a and OpenSSL 1.0.1b [26 Apr 2012]: -+ -+ o Fix compilation error on non-x86 platforms. -+ o Make FIPS capable OpenSSL ciphers work in non-FIPS mode. -+ o Fix SSL_OP_NO_TLSv1_1 clash with SSL_OP_ALL in OpenSSL 1.0.0 -+ -+ Major changes between OpenSSL 1.0.1 and OpenSSL 1.0.1a [19 Apr 2012]: -+ -+ o Fix for ASN1 overflow bug CVE-2012-2110 -+ o Workarounds for some servers that hang on long client hellos. -+ o Fix SEGV in AES code. -+ -+ Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.1 [14 Mar 2012]: -+ -+ o TLS/DTLS heartbeat support. -+ o SCTP support. -+ o RFC 5705 TLS key material exporter. -+ o RFC 5764 DTLS-SRTP negotiation. -+ o Next Protocol Negotiation. -+ o PSS signatures in certificates, requests and CRLs. -+ o Support for password based recipient info for CMS. -+ o Support TLS v1.2 and TLS v1.1. -+ o Preliminary FIPS capability for unvalidated 2.0 FIPS module. -+ o SRP support. -+ -+ Major changes between OpenSSL 1.0.0g and OpenSSL 1.0.0h [12 Mar 2012]: -+ -+ o Fix for CMS/PKCS#7 MMA CVE-2012-0884 -+ o Corrected fix for CVE-2011-4619 -+ o Various DTLS fixes. -+ -+ Major changes between OpenSSL 1.0.0f and OpenSSL 1.0.0g [18 Jan 2012]: -+ -+ o Fix for DTLS DoS issue CVE-2012-0050 -+ -+ Major changes between OpenSSL 1.0.0e and OpenSSL 1.0.0f [4 Jan 2012]: -+ -+ o Fix for DTLS plaintext recovery attack CVE-2011-4108 -+ o Clear block padding bytes of SSL 3.0 records CVE-2011-4576 -+ o Only allow one SGC handshake restart for SSL/TLS CVE-2011-4619 -+ o Check parameters are not NULL in GOST ENGINE CVE-2012-0027 -+ o Check for malformed RFC3779 data CVE-2011-4577 -+ -+ Major changes between OpenSSL 1.0.0d and OpenSSL 1.0.0e [6 Sep 2011]: -+ -+ o Fix for CRL vulnerability issue CVE-2011-3207 -+ o Fix for ECDH crashes CVE-2011-3210 -+ o Protection against EC timing attacks. -+ o Support ECDH ciphersuites for certificates using SHA2 algorithms. -+ o Various DTLS fixes. -+ -+ Major changes between OpenSSL 1.0.0c and OpenSSL 1.0.0d [8 Feb 2011]: -+ -+ o Fix for security issue CVE-2011-0014 -+ -+ Major changes between OpenSSL 1.0.0b and OpenSSL 1.0.0c [2 Dec 2010]: -+ -+ o Fix for security issue CVE-2010-4180 -+ o Fix for CVE-2010-4252 -+ o Fix mishandling of absent EC point format extension. -+ o Fix various platform compilation issues. -+ o Corrected fix for security issue CVE-2010-3864. -+ -+ Major changes between OpenSSL 1.0.0a and OpenSSL 1.0.0b [16 Nov 2010]: -+ -+ o Fix for security issue CVE-2010-3864. -+ o Fix for CVE-2010-2939 -+ o Fix WIN32 build system for GOST ENGINE. -+ -+ Major changes between OpenSSL 1.0.0 and OpenSSL 1.0.0a [1 Jun 2010]: -+ -+ o Fix for security issue CVE-2010-1633. -+ o GOST MAC and CFB fixes. -+ -+ Major changes between OpenSSL 0.9.8n and OpenSSL 1.0.0 [29 Mar 2010]: -+ -+ o RFC3280 path validation: sufficient to process PKITS tests. -+ o Integrated support for PVK files and keyblobs. -+ o Change default private key format to PKCS#8. -+ o CMS support: able to process all examples in RFC4134 -+ o Streaming ASN1 encode support for PKCS#7 and CMS. -+ o Multiple signer and signer add support for PKCS#7 and CMS. -+ o ASN1 printing support. -+ o Whirlpool hash algorithm added. -+ o RFC3161 time stamp support. -+ o New generalised public key API supporting ENGINE based algorithms. -+ o New generalised public key API utilities. -+ o New ENGINE supporting GOST algorithms. -+ o SSL/TLS GOST ciphersuite support. -+ o PKCS#7 and CMS GOST support. -+ o RFC4279 PSK ciphersuite support. -+ o Supported points format extension for ECC ciphersuites. -+ o ecdsa-with-SHA224/256/384/512 signature types. -+ o dsa-with-SHA224 and dsa-with-SHA256 signature types. -+ o Opaque PRF Input TLS extension support. -+ o Updated time routines to avoid OS limitations. -+ -+ Major changes between OpenSSL 0.9.8m and OpenSSL 0.9.8n [24 Mar 2010]: -+ -+ o CFB cipher definition fixes. -+ o Fix security issues CVE-2010-0740 and CVE-2010-0433. -+ -+ Major changes between OpenSSL 0.9.8l and OpenSSL 0.9.8m [25 Feb 2010]: -+ -+ o Cipher definition fixes. -+ o Workaround for slow RAND_poll() on some WIN32 versions. -+ o Remove MD2 from algorithm tables. -+ o SPKAC handling fixes. -+ o Support for RFC5746 TLS renegotiation extension. -+ o Compression memory leak fixed. -+ o Compression session resumption fixed. -+ o Ticket and SNI coexistence fixes. -+ o Many fixes to DTLS handling. -+ -+ Major changes between OpenSSL 0.9.8k and OpenSSL 0.9.8l [5 Nov 2009]: -+ -+ o Temporary work around for CVE-2009-3555: disable renegotiation. -+ -+ Major changes between OpenSSL 0.9.8j and OpenSSL 0.9.8k [25 Mar 2009]: -+ -+ o Fix various build issues. -+ o Fix security issues (CVE-2009-0590, CVE-2009-0591, CVE-2009-0789) -+ -+ Major changes between OpenSSL 0.9.8i and OpenSSL 0.9.8j [7 Jan 2009]: -+ -+ o Fix security issue (CVE-2008-5077) -+ o Merge FIPS 140-2 branch code. -+ -+ Major changes between OpenSSL 0.9.8g and OpenSSL 0.9.8h [28 May 2008]: -+ -+ o CryptoAPI ENGINE support. -+ o Various precautionary measures. -+ o Fix for bugs affecting certificate request creation. -+ o Support for local machine keyset attribute in PKCS#12 files. -+ -+ Major changes between OpenSSL 0.9.8f and OpenSSL 0.9.8g [19 Oct 2007]: -+ -+ o Backport of CMS functionality to 0.9.8. -+ o Fixes for bugs introduced with 0.9.8f. -+ -+ Major changes between OpenSSL 0.9.8e and OpenSSL 0.9.8f [11 Oct 2007]: -+ -+ o Add gcc 4.2 support. -+ o Add support for AES and SSE2 assembly language optimization -+ for VC++ build. -+ o Support for RFC4507bis and server name extensions if explicitly -+ selected at compile time. -+ o DTLS improvements. -+ o RFC4507bis support. -+ o TLS Extensions support. -+ -+ Major changes between OpenSSL 0.9.8d and OpenSSL 0.9.8e [23 Feb 2007]: -+ -+ o Various ciphersuite selection fixes. -+ o RFC3779 support. -+ -+ Major changes between OpenSSL 0.9.8c and OpenSSL 0.9.8d [28 Sep 2006]: -+ -+ o Introduce limits to prevent malicious key DoS (CVE-2006-2940) -+ o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343) -+ o Changes to ciphersuite selection algorithm -+ -+ Major changes between OpenSSL 0.9.8b and OpenSSL 0.9.8c [5 Sep 2006]: -+ -+ o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339 -+ o New cipher Camellia -+ -+ Major changes between OpenSSL 0.9.8a and OpenSSL 0.9.8b [4 May 2006]: -+ -+ o Cipher string fixes. -+ o Fixes for VC++ 2005. -+ o Updated ECC cipher suite support. -+ o New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free(). -+ o Zlib compression usage fixes. -+ o Built in dynamic engine compilation support on Win32. -+ o Fixes auto dynamic engine loading in Win32. -+ -+ Major changes between OpenSSL 0.9.8 and OpenSSL 0.9.8a [11 Oct 2005]: -+ -+ o Fix potential SSL 2.0 rollback, CVE-2005-2969 -+ o Extended Windows CE support -+ -+ Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.8 [5 Jul 2005]: -+ -+ o Major work on the BIGNUM library for higher efficiency and to -+ make operations more streamlined and less contradictory. This -+ is the result of a major audit of the BIGNUM library. -+ o Addition of BIGNUM functions for fields GF(2^m) and NIST -+ curves, to support the Elliptic Crypto functions. -+ o Major work on Elliptic Crypto; ECDH and ECDSA added, including -+ the use through EVP, X509 and ENGINE. -+ o New ASN.1 mini-compiler that's usable through the OpenSSL -+ configuration file. -+ o Added support for ASN.1 indefinite length constructed encoding. -+ o New PKCS#12 'medium level' API to manipulate PKCS#12 files. -+ o Complete rework of shared library construction and linking -+ programs with shared or static libraries, through a separate -+ Makefile.shared. -+ o Rework of the passing of parameters from one Makefile to another. -+ o Changed ENGINE framework to load dynamic engine modules -+ automatically from specifically given directories. -+ o New structure and ASN.1 functions for CertificatePair. -+ o Changed the ZLIB compression method to be stateful. -+ o Changed the key-generation and primality testing "progress" -+ mechanism to take a structure that contains the ticker -+ function and an argument. -+ o New engine module: GMP (performs private key exponentiation). -+ o New engine module: VIA PadLOck ACE extension in VIA C3 -+ Nehemiah processors. -+ o Added support for IPv6 addresses in certificate extensions. -+ See RFC 1884, section 2.2. -+ o Added support for certificate policy mappings, policy -+ constraints and name constraints. -+ o Added support for multi-valued AVAs in the OpenSSL -+ configuration file. -+ o Added support for multiple certificates with the same subject -+ in the 'openssl ca' index file. -+ o Make it possible to create self-signed certificates using -+ 'openssl ca -selfsign'. -+ o Make it possible to generate a serial number file with -+ 'openssl ca -create_serial'. -+ o New binary search functions with extended functionality. -+ o New BUF functions. -+ o New STORE structure and library to provide an interface to all -+ sorts of data repositories. Supports storage of public and -+ private keys, certificates, CRLs, numbers and arbitrary blobs. -+ This library is unfortunately unfinished and unused within -+ OpenSSL. -+ o New control functions for the error stack. -+ o Changed the PKCS#7 library to support one-pass S/MIME -+ processing. -+ o Added the possibility to compile without old deprecated -+ functionality with the OPENSSL_NO_DEPRECATED macro or the -+ 'no-deprecated' argument to the config and Configure scripts. -+ o Constification of all ASN.1 conversion functions, and other -+ affected functions. -+ o Improved platform support for PowerPC. -+ o New FIPS 180-2 algorithms (SHA-224, -256, -384 and -512). -+ o New X509_VERIFY_PARAM structure to support parametrisation -+ of X.509 path validation. -+ o Major overhaul of RC4 performance on Intel P4, IA-64 and -+ AMD64. -+ o Changed the Configure script to have some algorithms disabled -+ by default. Those can be explicitly enabled with the new -+ argument form 'enable-xxx'. -+ o Change the default digest in 'openssl' commands from MD5 to -+ SHA-1. -+ o Added support for DTLS. -+ o New BIGNUM blinding. -+ o Added support for the RSA-PSS encryption scheme -+ o Added support for the RSA X.931 padding. -+ o Added support for BSD sockets on NetWare. -+ o Added support for files larger than 2GB. -+ o Added initial support for Win64. -+ o Added alternate pkg-config files. -+ -+ Major changes between OpenSSL 0.9.7l and OpenSSL 0.9.7m [23 Feb 2007]: -+ -+ o FIPS 1.1.1 module linking. -+ o Various ciphersuite selection fixes. -+ -+ Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l [28 Sep 2006]: -+ -+ o Introduce limits to prevent malicious key DoS (CVE-2006-2940) -+ o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343) -+ -+ Major changes between OpenSSL 0.9.7j and OpenSSL 0.9.7k [5 Sep 2006]: -+ -+ o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339 -+ -+ Major changes between OpenSSL 0.9.7i and OpenSSL 0.9.7j [4 May 2006]: -+ -+ o Visual C++ 2005 fixes. -+ o Update Windows build system for FIPS. -+ -+ Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i [14 Oct 2005]: -+ -+ o Give EVP_MAX_MD_SIZE it's old value, except for a FIPS build. -+ -+ Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.7h [11 Oct 2005]: -+ -+ o Fix SSL 2.0 Rollback, CVE-2005-2969 -+ o Allow use of fixed-length exponent on DSA signing -+ o Default fixed-window RSA, DSA, DH private-key operations -+ -+ Major changes between OpenSSL 0.9.7f and OpenSSL 0.9.7g [11 Apr 2005]: -+ -+ o More compilation issues fixed. -+ o Adaptation to more modern Kerberos API. -+ o Enhanced or corrected configuration for Solaris64, Mingw and Cygwin. -+ o Enhanced x86_64 assembler BIGNUM module. -+ o More constification. -+ o Added processing of proxy certificates (RFC 3820). -+ -+ Major changes between OpenSSL 0.9.7e and OpenSSL 0.9.7f [22 Mar 2005]: -+ -+ o Several compilation issues fixed. -+ o Many memory allocation failure checks added. -+ o Improved comparison of X509 Name type. -+ o Mandatory basic checks on certificates. -+ o Performance improvements. -+ -+ Major changes between OpenSSL 0.9.7d and OpenSSL 0.9.7e [25 Oct 2004]: -+ -+ o Fix race condition in CRL checking code. -+ o Fixes to PKCS#7 (S/MIME) code. -+ -+ Major changes between OpenSSL 0.9.7c and OpenSSL 0.9.7d [17 Mar 2004]: -+ -+ o Security: Fix Kerberos ciphersuite SSL/TLS handshaking bug -+ o Security: Fix null-pointer assignment in do_change_cipher_spec() -+ o Allow multiple active certificates with same subject in CA index -+ o Multiple X509 verification fixes -+ o Speed up HMAC and other operations -+ -+ Major changes between OpenSSL 0.9.7b and OpenSSL 0.9.7c [30 Sep 2003]: -+ -+ o Security: fix various ASN1 parsing bugs. -+ o New -ignore_err option to OCSP utility. -+ o Various interop and bug fixes in S/MIME code. -+ o SSL/TLS protocol fix for unrequested client certificates. -+ -+ Major changes between OpenSSL 0.9.7a and OpenSSL 0.9.7b [10 Apr 2003]: -+ -+ o Security: counter the Klima-Pokorny-Rosa extension of -+ Bleichbacher's attack -+ o Security: make RSA blinding default. -+ o Configuration: Irix fixes, AIX fixes, better mingw support. -+ o Support for new platforms: linux-ia64-ecc. -+ o Build: shared library support fixes. -+ o ASN.1: treat domainComponent correctly. -+ o Documentation: fixes and additions. -+ -+ Major changes between OpenSSL 0.9.7 and OpenSSL 0.9.7a [19 Feb 2003]: -+ -+ o Security: Important security related bugfixes. -+ o Enhanced compatibility with MIT Kerberos. -+ o Can be built without the ENGINE framework. -+ o IA32 assembler enhancements. -+ o Support for new platforms: FreeBSD/IA64 and FreeBSD/Sparc64. -+ o Configuration: the no-err option now works properly. -+ o SSL/TLS: now handles manual certificate chain building. -+ o SSL/TLS: certain session ID malfunctions corrected. -+ -+ Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.7 [30 Dec 2002]: -+ -+ o New library section OCSP. -+ o Complete rewrite of ASN1 code. -+ o CRL checking in verify code and openssl utility. -+ o Extension copying in 'ca' utility. -+ o Flexible display options in 'ca' utility. -+ o Provisional support for international characters with UTF8. -+ o Support for external crypto devices ('engine') is no longer -+ a separate distribution. -+ o New elliptic curve library section. -+ o New AES (Rijndael) library section. -+ o Support for new platforms: Windows CE, Tandem OSS, A/UX, AIX 64-bit, -+ Linux x86_64, Linux 64-bit on Sparc v9 -+ o Extended support for some platforms: VxWorks -+ o Enhanced support for shared libraries. -+ o Now only builds PIC code when shared library support is requested. -+ o Support for pkg-config. -+ o Lots of new manuals. -+ o Makes symbolic links to or copies of manuals to cover all described -+ functions. -+ o Change DES API to clean up the namespace (some applications link also -+ against libdes providing similar functions having the same name). -+ Provide macros for backward compatibility (will be removed in the -+ future). -+ o Unify handling of cryptographic algorithms (software and engine) -+ to be available via EVP routines for asymmetric and symmetric ciphers. -+ o NCONF: new configuration handling routines. -+ o Change API to use more 'const' modifiers to improve error checking -+ and help optimizers. -+ o Finally remove references to RSAref. -+ o Reworked parts of the BIGNUM code. -+ o Support for new engines: Broadcom ubsec, Accelerated Encryption -+ Processing, IBM 4758. -+ o A few new engines added in the demos area. -+ o Extended and corrected OID (object identifier) table. -+ o PRNG: query at more locations for a random device, automatic query for -+ EGD style random sources at several locations. -+ o SSL/TLS: allow optional cipher choice according to server's preference. -+ o SSL/TLS: allow server to explicitly set new session ids. -+ o SSL/TLS: support Kerberos cipher suites (RFC2712). -+ Only supports MIT Kerberos for now. -+ o SSL/TLS: allow more precise control of renegotiations and sessions. -+ o SSL/TLS: add callback to retrieve SSL/TLS messages. -+ o SSL/TLS: support AES cipher suites (RFC3268). -+ -+ Major changes between OpenSSL 0.9.6j and OpenSSL 0.9.6k [30 Sep 2003]: -+ -+ o Security: fix various ASN1 parsing bugs. -+ o SSL/TLS protocol fix for unrequested client certificates. -+ -+ Major changes between OpenSSL 0.9.6i and OpenSSL 0.9.6j [10 Apr 2003]: -+ -+ o Security: counter the Klima-Pokorny-Rosa extension of -+ Bleichbacher's attack -+ o Security: make RSA blinding default. -+ o Build: shared library support fixes. -+ -+ Major changes between OpenSSL 0.9.6h and OpenSSL 0.9.6i [19 Feb 2003]: -+ -+ o Important security related bugfixes. -+ -+ Major changes between OpenSSL 0.9.6g and OpenSSL 0.9.6h [5 Dec 2002]: -+ -+ o New configuration targets for Tandem OSS and A/UX. -+ o New OIDs for Microsoft attributes. -+ o Better handling of SSL session caching. -+ o Better comparison of distinguished names. -+ o Better handling of shared libraries in a mixed GNU/non-GNU environment. -+ o Support assembler code with Borland C. -+ o Fixes for length problems. -+ o Fixes for uninitialised variables. -+ o Fixes for memory leaks, some unusual crashes and some race conditions. -+ o Fixes for smaller building problems. -+ o Updates of manuals, FAQ and other instructive documents. -+ -+ Major changes between OpenSSL 0.9.6f and OpenSSL 0.9.6g [9 Aug 2002]: -+ -+ o Important building fixes on Unix. -+ -+ Major changes between OpenSSL 0.9.6e and OpenSSL 0.9.6f [8 Aug 2002]: -+ -+ o Various important bugfixes. -+ -+ Major changes between OpenSSL 0.9.6d and OpenSSL 0.9.6e [30 Jul 2002]: -+ -+ o Important security related bugfixes. -+ o Various SSL/TLS library bugfixes. -+ -+ Major changes between OpenSSL 0.9.6c and OpenSSL 0.9.6d [9 May 2002]: -+ -+ o Various SSL/TLS library bugfixes. -+ o Fix DH parameter generation for 'non-standard' generators. -+ -+ Major changes between OpenSSL 0.9.6b and OpenSSL 0.9.6c [21 Dec 2001]: -+ -+ o Various SSL/TLS library bugfixes. -+ o BIGNUM library fixes. -+ o RSA OAEP and random number generation fixes. -+ o Object identifiers corrected and added. -+ o Add assembler BN routines for IA64. -+ o Add support for OS/390 Unix, UnixWare with gcc, OpenUNIX 8, -+ MIPS Linux; shared library support for Irix, HP-UX. -+ o Add crypto accelerator support for AEP, Baltimore SureWare, -+ Broadcom and Cryptographic Appliance's keyserver -+ [in 0.9.6c-engine release]. -+ -+ Major changes between OpenSSL 0.9.6a and OpenSSL 0.9.6b [9 Jul 2001]: -+ -+ o Security fix: PRNG improvements. -+ o Security fix: RSA OAEP check. -+ o Security fix: Reinsert and fix countermeasure to Bleichbacher's -+ attack. -+ o MIPS bug fix in BIGNUM. -+ o Bug fix in "openssl enc". -+ o Bug fix in X.509 printing routine. -+ o Bug fix in DSA verification routine and DSA S/MIME verification. -+ o Bug fix to make PRNG thread-safe. -+ o Bug fix in RAND_file_name(). -+ o Bug fix in compatibility mode trust settings. -+ o Bug fix in blowfish EVP. -+ o Increase default size for BIO buffering filter. -+ o Compatibility fixes in some scripts. -+ -+ Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.6a [5 Apr 2001]: -+ -+ o Security fix: change behavior of OpenSSL to avoid using -+ environment variables when running as root. -+ o Security fix: check the result of RSA-CRT to reduce the -+ possibility of deducing the private key from an incorrectly -+ calculated signature. -+ o Security fix: prevent Bleichenbacher's DSA attack. -+ o Security fix: Zero the premaster secret after deriving the -+ master secret in DH ciphersuites. -+ o Reimplement SSL_peek(), which had various problems. -+ o Compatibility fix: the function des_encrypt() renamed to -+ des_encrypt1() to avoid clashes with some Unixen libc. -+ o Bug fixes for Win32, HP/UX and Irix. -+ o Bug fixes in BIGNUM, SSL, PKCS#7, PKCS#12, X.509, CONF and -+ memory checking routines. -+ o Bug fixes for RSA operations in threaded environments. -+ o Bug fixes in misc. openssl applications. -+ o Remove a few potential memory leaks. -+ o Add tighter checks of BIGNUM routines. -+ o Shared library support has been reworked for generality. -+ o More documentation. -+ o New function BN_rand_range(). -+ o Add "-rand" option to openssl s_client and s_server. -+ -+ Major changes between OpenSSL 0.9.5a and OpenSSL 0.9.6 [10 Oct 2000]: -+ -+ o Some documentation for BIO and SSL libraries. -+ o Enhanced chain verification using key identifiers. -+ o New sign and verify options to 'dgst' application. -+ o Support for DER and PEM encoded messages in 'smime' application. -+ o New 'rsautl' application, low level RSA utility. -+ o MD4 now included. -+ o Bugfix for SSL rollback padding check. -+ o Support for external crypto devices [1]. -+ o Enhanced EVP interface. -+ -+ [1] The support for external crypto devices is currently a separate -+ distribution. See the file README.ENGINE. -+ -+ Major changes between OpenSSL 0.9.5 and OpenSSL 0.9.5a [1 Apr 2000]: -+ -+ o Bug fixes for Win32, SuSE Linux, NeXTSTEP and FreeBSD 2.2.8 -+ o Shared library support for HPUX and Solaris-gcc -+ o Support of Linux/IA64 -+ o Assembler support for Mingw32 -+ o New 'rand' application -+ o New way to check for existence of algorithms from scripts -+ -+ Major changes between OpenSSL 0.9.4 and OpenSSL 0.9.5 [25 May 2000]: -+ -+ o S/MIME support in new 'smime' command -+ o Documentation for the OpenSSL command line application -+ o Automation of 'req' application -+ o Fixes to make s_client, s_server work under Windows -+ o Support for multiple fieldnames in SPKACs -+ o New SPKAC command line utilty and associated library functions -+ o Options to allow passwords to be obtained from various sources -+ o New public key PEM format and options to handle it -+ o Many other fixes and enhancements to command line utilities -+ o Usable certificate chain verification -+ o Certificate purpose checking -+ o Certificate trust settings -+ o Support of authority information access extension -+ o Extensions in certificate requests -+ o Simplified X509 name and attribute routines -+ o Initial (incomplete) support for international character sets -+ o New DH_METHOD, DSA_METHOD and enhanced RSA_METHOD -+ o Read only memory BIOs and simplified creation function -+ o TLS/SSL protocol bugfixes: Accept TLS 'client hello' in SSL 3.0 -+ record; allow fragmentation and interleaving of handshake and other -+ data -+ o TLS/SSL code now "tolerates" MS SGC -+ o Work around for Netscape client certificate hang bug -+ o RSA_NULL option that removes RSA patent code but keeps other -+ RSA functionality -+ o Memory leak detection now allows applications to add extra information -+ via a per-thread stack -+ o PRNG robustness improved -+ o EGD support -+ o BIGNUM library bug fixes -+ o Faster DSA parameter generation -+ o Enhanced support for Alpha Linux -+ o Experimental MacOS support -+ -+ Major changes between OpenSSL 0.9.3 and OpenSSL 0.9.4 [9 Aug 1999]: -+ -+ o Transparent support for PKCS#8 format private keys: these are used -+ by several software packages and are more secure than the standard -+ form -+ o PKCS#5 v2.0 implementation -+ o Password callbacks have a new void * argument for application data -+ o Avoid various memory leaks -+ o New pipe-like BIO that allows using the SSL library when actual I/O -+ must be handled by the application (BIO pair) -+ -+ Major changes between OpenSSL 0.9.2b and OpenSSL 0.9.3 [24 May 1999]: -+ o Lots of enhancements and cleanups to the Configuration mechanism -+ o RSA OEAP related fixes -+ o Added `openssl ca -revoke' option for revoking a certificate -+ o Source cleanups: const correctness, type-safe stacks and ASN.1 SETs -+ o Source tree cleanups: removed lots of obsolete files -+ o Thawte SXNet, certificate policies and CRL distribution points -+ extension support -+ o Preliminary (experimental) S/MIME support -+ o Support for ASN.1 UTF8String and VisibleString -+ o Full integration of PKCS#12 code -+ o Sparc assembler bignum implementation, optimized hash functions -+ o Option to disable selected ciphers -+ -+ Major changes between OpenSSL 0.9.1c and OpenSSL 0.9.2b [22 Mar 1999]: -+ o Fixed a security hole related to session resumption -+ o Fixed RSA encryption routines for the p < q case -+ o "ALL" in cipher lists now means "everything except NULL ciphers" -+ o Support for Triple-DES CBCM cipher -+ o Support of Optimal Asymmetric Encryption Padding (OAEP) for RSA -+ o First support for new TLSv1 ciphers -+ o Added a few new BIOs (syslog BIO, reliable BIO) -+ o Extended support for DSA certificate/keys. -+ o Extended support for Certificate Signing Requests (CSR) -+ o Initial support for X.509v3 extensions -+ o Extended support for compression inside the SSL record layer -+ o Overhauled Win32 builds -+ o Cleanups and fixes to the Big Number (BN) library -+ o Support for ASN.1 GeneralizedTime -+ o Splitted ASN.1 SETs from SEQUENCEs -+ o ASN1 and PEM support for Netscape Certificate Sequences -+ o Overhauled Perl interface -+ o Lots of source tree cleanups. -+ o Lots of memory leak fixes. -+ o Lots of bug fixes. -+ -+ Major changes between SSLeay 0.9.0b and OpenSSL 0.9.1c [23 Dec 1998]: -+ o Integration of the popular NO_RSA/NO_DSA patches -+ o Initial support for compression inside the SSL record layer -+ o Added BIO proxy and filtering functionality -+ o Extended Big Number (BN) library -+ o Added RIPE MD160 message digest -+ o Addeed support for RC2/64bit cipher -+ o Extended ASN.1 parser routines -+ o Adjustations of the source tree for CVS -+ o Support for various new platforms -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/NOTES.DJGPP b/CryptoPkg/Library/OpensslLib/openssl/NOTES.DJGPP -new file mode 100644 -index 0000000..bbe63dc ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/NOTES.DJGPP -@@ -0,0 +1,48 @@ -+ -+ -+ INSTALLATION ON THE DOS PLATFORM WITH DJGPP -+ ------------------------------------------- -+ -+ OpenSSL has been ported to DJGPP, a Unix look-alike 32-bit run-time -+ environment for 16-bit DOS, but only with long filename support. -+ If you wish to compile on native DOS with 8+3 filenames, you will -+ have to tweak the installation yourself, including renaming files -+ with illegal or duplicate names. -+ -+ You should have a full DJGPP environment installed, including the -+ latest versions of DJGPP, GCC, BINUTILS, BASH, etc. This package -+ requires that PERL and the PERL module Text::Template also be -+ installed (see NOTES.PERL). -+ -+ All of these can be obtained from the usual DJGPP mirror sites or -+ directly at "http://www.delorie.com/pub/djgpp". For help on which -+ files to download, see the DJGPP "ZIP PICKER" page at -+ "http://www.delorie.com/djgpp/zip-picker.html". You also need to have -+ the WATT-32 networking package installed before you try to compile -+ OpenSSL. This can be obtained from "http://www.watt-32.net/". -+ The Makefile assumes that the WATT-32 code is in the directory -+ specified by the environment variable WATT_ROOT. If you have watt-32 -+ in directory "watt32" under your main DJGPP directory, specify -+ WATT_ROOT="/dev/env/DJDIR/watt32". -+ -+ To compile OpenSSL, start your BASH shell, then configure for DJGPP by -+ running "./Configure" with appropriate arguments: -+ -+ ./Configure no-threads --prefix=/dev/env/DJDIR DJGPP -+ -+ And finally fire up "make". You may run out of DPMI selectors when -+ running in a DOS box under Windows. If so, just close the BASH -+ shell, go back to Windows, and restart BASH. Then run "make" again. -+ -+ RUN-TIME CAVEAT LECTOR -+ -------------- -+ -+ Quoting FAQ: -+ -+ "Cryptographic software needs a source of unpredictable data to work -+ correctly. Many open source operating systems provide a "randomness -+ device" (/dev/urandom or /dev/random) that serves this purpose." -+ -+ As of version 0.9.7f DJGPP port checks upon /dev/urandom$ for a 3rd -+ party "randomness" DOS driver. One such driver, NOISE.SYS, can be -+ obtained from "http://www.rahul.net/dkaufman/index.html". -diff --git a/CryptoPkg/Library/OpensslLib/openssl/NOTES.PERL b/CryptoPkg/Library/OpensslLib/openssl/NOTES.PERL -new file mode 100644 -index 0000000..46d585a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/NOTES.PERL -@@ -0,0 +1,119 @@ -+ TOC -+ === -+ -+ - Notes on Perl -+ - Notes on Perl on Windows -+ - Notes on Perl modules we use -+ - Notes on installing a perl module -+ -+ Notes on Perl -+ ------------- -+ -+ For our scripts, we rely quite a bit on Perl, and increasingly on -+ some core Perl modules. These Perl modules are part of the Perl -+ source, so if you build Perl on your own, you should be set. -+ -+ However, if you install Perl as binary packages, the outcome might -+ differ, and you may have to check that you do get the core modules -+ installed properly. We do not claim to know them all, but experience -+ has told us the following: -+ -+ - on Linux distributions based on Debian, the package 'perl' will -+ install the core Perl modules as well, so you will be fine. -+ - on Linux distributions based on RPMs, you will need to install -+ 'perl-core' rather than just 'perl'. -+ -+ You MUST have at least Perl version 5.10.0 installed. This minimum -+ requirement is due to our use of regexp backslash sequence \R among -+ other features that didn't exist in core Perl before that version. -+ -+ Notes on Perl on Windows -+ ------------------------ -+ -+ There are a number of build targets that can be viewed as "Windows". -+ Indeed, there are VC-* configs targeting VisualStudio C, as well as -+ MinGW and Cygwin. The key recommendation is to use "matching" Perl, -+ one that matches build environment. For example, if you will build -+ on Cygwin be sure to use the Cygwin package manager to install Perl. -+ For MSYS builds use the MSYS provided Perl. For VC-* builds we -+ recommend ActiveState Perl, available from -+ http://www.activestate.com/ActivePerl. -+ -+ Notes on Perl on VMS -+ -------------------- -+ -+ You will need to install Perl separately. One way to do so is to -+ download the source from http://perl.org/, unpacking it, reading -+ README.vms and follow the instructions. Another way is to download a -+ .PCSI file from http://www.vmsperl.com/ and install it using the -+ POLYCENTER install tool. -+ -+ Notes on Perl modules we use -+ ---------------------------- -+ -+ We make increasing use of Perl modules, and do our best to limit -+ ourselves to core Perl modules to keep the requirements down. There -+ are just a few exceptions: -+ -+ Test::More We require the minimum version to be 0.96, which -+ appeared in Perl 5.13.4, because that version was -+ the first to have all the features we're using. -+ This module is required for testing only! If you -+ don't plan on running the tests, you don't need to -+ bother with this one. -+ -+ Text::Template This module is not part of the core Perl modules. -+ As a matter of fact, the core Perl modules do not -+ include any templating module to date. -+ This module is absolutely needed, configuration -+ depends on it. -+ -+ To avoid unnecessary initial hurdles, we have bundled a copy of the -+ following modules in our source. They will work as fallbacks if -+ these modules aren't already installed on the system. -+ -+ Text::Template -+ -+ Notes on installing a perl module -+ --------------------------------- -+ -+ There are a number of ways to install a perl module. In all -+ descriptions below, Text::Template will server as an example. -+ -+ 1. for Linux users, the easiest is to install with the use of your -+ favorite package manager. Usually, all you need to do is search -+ for the module name and to install the package that comes up. -+ -+ On Debian based Linux distributions, it would go like this: -+ -+ $ apt-cache search Text::Template -+ ... -+ libtext-template-perl - perl module to process text templates -+ $ sudo apt-get install libtext-template-perl -+ -+ Perl modules in Debian based distributions use package names like -+ the name of the module in question, with "lib" prepended and -+ "-perl" appended. -+ -+ 2. Install using CPAN. This is very easy, but usually requires root -+ access: -+ -+ $ cpan -i Text::Template -+ -+ Note that this runs all the tests that the module to be installed -+ comes with. This is usually a smooth operation, but there are -+ platforms where a failure is indicated even though the actual tests -+ were successful. Should that happen, you can force an -+ installation regardless (that should be safe since you've already -+ seen the tests succeed!): -+ -+ $ cpan -f -i Text::Template -+ -+ Note: on VMS, you must quote any argument that contains upper case -+ characters, so the lines above would be: -+ -+ $ cpan -i "Text::Template" -+ -+ and: -+ -+ $ cpan -f -i "Text::Template" -diff --git a/CryptoPkg/Library/OpensslLib/openssl/NOTES.VMS b/CryptoPkg/Library/OpensslLib/openssl/NOTES.VMS -new file mode 100644 -index 0000000..3e9a57e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/NOTES.VMS -@@ -0,0 +1,81 @@ -+ -+ NOTES FOR THE OPENVMS PLATFORM -+ ============================== -+ -+ Requirement details -+ ------------------- -+ -+ In addition to the requirements and instructions listed in INSTALL, -+ this are required as well: -+ -+ * At least ODS-5 disk organization for source and build. -+ Installation can be done on any existing disk organization. -+ -+ -+ About ANSI C compiler -+ --------------------- -+ -+ An ANSI C compiled is needed among other things. This means that -+ VAX C is not and will not be supported. -+ -+ We have only tested with DEC C (a.k.a HP VMS C / VSI C) and require -+ version 7.1 or later. Compiling with a different ANSI C compiler may -+ require some work. -+ -+ Please avoid using C RTL feature logical names DECC$* when building -+ and testing OpenSSL. Most of all, they can be disruptive when -+ running the tests, as they affect the Perl interpreter. -+ -+ -+ About ODS-5 directory names and Perl -+ ------------------------------------ -+ -+ It seems that the perl function canonpath() in the File::Spec module -+ doesn't treat file specifications where the last directory name -+ contains periods very well. Unfortunately, some versions of VMS tar -+ will keep the periods in the OpenSSL source directory instead of -+ converting them to underscore, thereby leaving your source in -+ something like [.openssl-1^.1^.0]. This will lead to issues when -+ configuring and building OpenSSL. -+ -+ We have no replacement for Perl's canonpath(), so the best workaround -+ for now is to rename the OpenSSL source directory, as follows (please -+ adjust for the actual source directory name you have): -+ -+ $ rename openssl-1^.1^.0.DIR openssl-1_1_0.DIR -+ -+ -+ About MMS and DCL -+ ----------------- -+ -+ MMS has certain limitations when it comes to line length, and DCL has -+ certain limitations when it comes to total command length. We do -+ what we can to mitigate, but there is the possibility that it's not -+ enough. Should you run into issues, a very simple solution is to set -+ yourself up a few logical names for the directory trees you're going -+ to use. -+ -+ -+ Checking the distribution -+ ------------------------- -+ -+ There have been reports of places where the distribution didn't quite -+ get through, for example if you've copied the tree from a NFS-mounted -+ Unix mount point. -+ -+ The easiest way to check if everything got through as it should is to -+ check for one of the following files: -+ -+ [.crypto]opensslconf^.h.in -+ -+ The best way to get a correct distribution is to download the gzipped -+ tar file from ftp://ftp.openssl.org/source/, use GZIP -d to uncompress -+ it and VMSTAR to unpack the resulting tar file. -+ -+ Gzip and VMSTAR are available here: -+ -+ http://antinode.info/dec/index.html#Software -+ -+ Should you need it, you can find UnZip for VMS here: -+ -+ http://www.info-zip.org/UnZip.html -diff --git a/CryptoPkg/Library/OpensslLib/openssl/NOTES.WIN b/CryptoPkg/Library/OpensslLib/openssl/NOTES.WIN -new file mode 100644 -index 0000000..2a3c1e1 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/NOTES.WIN -@@ -0,0 +1,138 @@ -+ -+ NOTES FOR THE WINDOWS PLATFORMS -+ =============================== -+ -+ Requirement details for native (Visual C++) builds -+ -------------------------------------------------- -+ -+ In addition to the requirements and instructions listed in INSTALL, -+ this are required as well: -+ -+ - You need Perl. We recommend ActiveState Perl, available from -+ https://www.activestate.com/ActivePerl. -+ You also need the perl module Text::Template, available on CPAN. -+ Please read NOTES.PERL for more information. -+ -+ - You need a C compiler. OpenSSL has been tested to build with these: -+ -+ * Visual C++ -+ -+ - Netwide Assembler, a.k.a. NASM, available from http://www.nasm.us, -+ is required if you intend to utilize assembler modules. Note that NASM -+ is the only supported assembler. The Microsoft provided assembler is NOT -+ supported. -+ -+ -+ Visual C++ (native Windows) -+ --------------------------- -+ -+ Installation directories -+ -+ The default installation directories are derived from environment -+ variables. -+ -+ For VC-WIN32, the following defaults are use: -+ -+ PREFIX: %ProgramFiles(86)%\OpenSSL -+ OPENSSLDIR: %CommonProgramFiles(86)%\SSL -+ -+ For VC-WIN64, the following defaults are use: -+ -+ PREFIX: %ProgramW6432%\OpenSSL -+ OPENSSLDIR: %CommonProgramW6432%\SSL -+ -+ Should those environment variables not exist (on a pure Win32 -+ installation for examples), these fallbacks are used: -+ -+ PREFIX: %ProgramFiles%\OpenSSL -+ OPENSSLDIR: %CommonProgramFiles%\SSL -+ -+ ALSO NOTE that those directories are usually write protected, even if -+ your account is in the Administrators group. To work around that, -+ start the command prompt by right-clicking on it and choosing "Run as -+ Administrator" before running 'nmake install'. The other solution -+ is, of course, to choose a different set of directories by using -+ --prefix and --openssldir when configuring. -+ -+ GNU C (Cygwin) -+ -------------- -+ -+ Cygwin implements a Posix/Unix runtime system (cygwin1.dll) on top of the -+ Windows subsystem and provides a bash shell and GNU tools environment. -+ Consequently, a make of OpenSSL with Cygwin is virtually identical to the -+ Unix procedure. -+ -+ To build OpenSSL using Cygwin, you need to: -+ -+ * Install Cygwin (see https://cygwin.com/) -+ -+ * Install Cygwin Perl and ensure it is in the path. Recall that -+ as least 5.10.0 is required. -+ -+ * Run the Cygwin bash shell -+ -+ Apart from that, follow the Unix instructions in INSTALL. -+ -+ NOTE: "make test" and normal file operations may fail in directories -+ mounted as text (i.e. mount -t c:\somewhere /home) due to Cygwin -+ stripping of carriage returns. To avoid this ensure that a binary -+ mount is used, e.g. mount -b c:\somewhere /home. -+ -+ It is also possible to create "conventional" Windows binaries that use -+ the Microsoft C runtime system (msvcrt.dll or crtdll.dll) using MinGW -+ development add-on for Cygwin. MinGW is supported even as a standalone -+ setup as described in the following section. In the context you should -+ recognize that binaries targeting Cygwin itself are not interchangeable -+ with "conventional" Windows binaries you generate with/for MinGW. -+ -+ -+ GNU C (MinGW/MSYS) -+ ------------------ -+ -+ * Compiler and shell environment installation: -+ -+ MinGW and MSYS are available from http://www.mingw.org/, both are -+ required. Run the installers and do whatever magic they say it takes -+ to start MSYS bash shell with GNU tools and matching Perl on its PATH. -+ "Matching Perl" refers to chosen "shell environment", i.e. if built -+ under MSYS, then Perl compiled for MSYS must be used. -+ -+ Alternatively, one can use MSYS2 from https://msys2.github.io/, -+ which includes MingW (32-bit and 64-bit). -+ -+ * It is also possible to cross-compile it on Linux by configuring -+ with './Configure --cross-compile-prefix=i386-mingw32- mingw ...'. -+ Other possible cross compile prefixes include x86_64-w64-mingw32- -+ and i686-w64-mingw32-. -+ -+ -+ Linking your application -+ ------------------------ -+ -+ This section applies to non-Cygwin builds. -+ -+ If you link with static OpenSSL libraries then you're expected to -+ additionally link your application with WS2_32.LIB, GDI32.LIB, -+ ADVAPI32.LIB, CRYPT32.LIB and USER32.LIB. Those developing -+ non-interactive service applications might feel concerned about -+ linking with GDI32.LIB and USER32.LIB, as they are justly associated -+ with interactive desktop, which is not available to service -+ processes. The toolkit is designed to detect in which context it's -+ currently executed, GUI, console app or service, and act accordingly, -+ namely whether or not to actually make GUI calls. Additionally those -+ who wish to /DELAYLOAD:GDI32.DLL and /DELAYLOAD:USER32.DLL and -+ actually keep them off service process should consider implementing -+ and exporting from .exe image in question own _OPENSSL_isservice not -+ relying on USER32.DLL. E.g., on Windows Vista and later you could: -+ -+ __declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void) -+ { DWORD sess; -+ if (ProcessIdToSessionId(GetCurrentProcessId(),&sess)) -+ return sess==0; -+ return FALSE; -+ } -+ -+ If you link with OpenSSL .DLLs, then you're expected to include into -+ your application code small "shim" snippet, which provides glue between -+ OpenSSL BIO layer and your compiler run-time. See the OPENSSL_Applink -+ manual page for further details. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/README b/CryptoPkg/Library/OpensslLib/openssl/README -new file mode 100644 -index 0000000..29979ab ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/README -@@ -0,0 +1,94 @@ -+ -+ OpenSSL 1.1.0e 16 Feb 2017 -+ -+ Copyright (c) 1998-2016 The OpenSSL Project -+ Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson -+ All rights reserved. -+ -+ DESCRIPTION -+ ----------- -+ -+ The OpenSSL Project is a collaborative effort to develop a robust, -+ commercial-grade, fully featured, and Open Source toolkit implementing the -+ Transport Layer Security (TLS) protocols (including SSLv3) as well as a -+ full-strength general purpose cryptographic library. -+ -+ OpenSSL is descended from the SSLeay library developed by Eric A. Young -+ and Tim J. Hudson. The OpenSSL toolkit is licensed under a dual-license (the -+ OpenSSL license plus the SSLeay license), which means that you are free to -+ get and use it for commercial and non-commercial purposes as long as you -+ fulfill the conditions of both licenses. -+ -+ OVERVIEW -+ -------- -+ -+ The OpenSSL toolkit includes: -+ -+ libssl (with platform specific naming): -+ Provides the client and server-side implementations for SSLv3 and TLS. -+ -+ libcrypto (with platform specific naming): -+ Provides general cryptographic and X.509 support needed by SSL/TLS but -+ not logically part of it. -+ -+ openssl: -+ A command line tool that can be used for: -+ Creation of key parameters -+ Creation of X.509 certificates, CSRs and CRLs -+ Calculation of message digests -+ Encryption and decryption -+ SSL/TLS client and server tests -+ Handling of S/MIME signed or encrypted mail -+ And more... -+ -+ INSTALLATION -+ ------------ -+ -+ See the appropriate file: -+ INSTALL Linux, Unix, Windows, OpenVMS, ... -+ NOTES.* INSTALL addendums for different platforms -+ -+ SUPPORT -+ ------- -+ -+ See the OpenSSL website www.openssl.org for details on how to obtain -+ commercial technical support. Free community support is available through the -+ openssl-users email list (see -+ https://www.openssl.org/community/mailinglists.html for further details). -+ -+ If you have any problems with OpenSSL then please take the following steps -+ first: -+ -+ - Download the latest version from the repository -+ to see if the problem has already been addressed -+ - Configure with no-asm -+ - Remove compiler optimisation flags -+ -+ If you wish to report a bug then please include the following information -+ and create an issue on GitHub: -+ -+ - OpenSSL version: output of 'openssl version -a' -+ - Any "Configure" options that you selected during compilation of the -+ library if applicable (see INSTALL) -+ - OS Name, Version, Hardware platform -+ - Compiler Details (name, version) -+ - Application Details (name, version) -+ - Problem Description (steps that will reproduce the problem, if known) -+ - Stack Traceback (if the application dumps core) -+ -+ Just because something doesn't work the way you expect does not mean it -+ is necessarily a bug in OpenSSL. Use the openssl-users email list for this type -+ of query. -+ -+ HOW TO CONTRIBUTE TO OpenSSL -+ ---------------------------- -+ -+ See CONTRIBUTING -+ -+ LEGALITIES -+ ---------- -+ -+ A number of nations restrict the use or export of cryptography. If you -+ are potentially subject to such restrictions you should seek competent -+ professional legal advice before attempting to develop or distribute -+ cryptographic code. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/README.ECC b/CryptoPkg/Library/OpensslLib/openssl/README.ECC -new file mode 100644 -index 0000000..fa3cad7 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/README.ECC -@@ -0,0 +1,61 @@ -+NOTE: The OpenSSL Software Foundation has executed a sublicense agreement -+entitled "Elliptic Curve Cryptography Patent License Agreement" with the -+National Security Agency/ Central Security Service Commercial Solutions -+Center (NCSC) dated 2010-11-04. That agreement permits implementation and -+distribution of software containing features covered by any or all of the -+following patents: -+ -+1.) U.S. Pat. No. 5,761,305 entitled "Key Agreement and Transport Protocol -+ with Implicit Signatures" issued on June 2, 1998; -+2.) Can. Pat. Appl. Ser. No. 2176972 entitled "Key Agreement and Transport -+ Protocol with Implicit Signature and Reduced Bandwidth" filed on May -+ 16, 1996; -+3.) U.S. Pat. No. 5,889,865 entitled "Key Agreement and Transport Protocol -+ with Implicit Signatures" issued on March 30, 1999; -+4.) U.S. Pat. No. 5,896,455 entitled "Key Agreement and Transport Protocol -+ with Implicit Signatures" issued on April 20, 1999; -+5.) U.S. Pat. No. 5,933,504 entitled "Strengthened Public Key Protocol" -+ issued on August 3, 1999; -+6.) Can. Pat. Appl. Ser. No. 2176866 entitled "Strengthened Public Key -+ Protocol" filed on May 17, 1996; -+7.) E.P. Pat. Appl. Ser. No. 96201322.3 entitled "Strengthened Public Key -+ Protocol" filed on May 17, 1996; -+8.) U.S. Pat. No. 5,999,626 entitled "Digital Signatures on a Smartcard" -+ issued on December 7, 1999; -+9.) Can. Pat. Appl. Ser. No. 2202566 entitled "Digital Signatures on a -+ Smartcard" filed on April 14, 1997; -+10.) E.P. Pat. Appl. No. 97106114.8 entitled "Digital Signatures on a -+ Smartcard" filed on April 15, 1997; -+11.) U.S Pat. No. 6,122,736 entitled "Key Agreement and Transport Protocol -+ with Implicit Signatures" issued on September 19, 2000; -+12.) Can. Pat. Appl. Ser. No. 2174261 entitled "Key Agreement and Transport -+ Protocol with Implicit Signatures" filed on April 16, 1996; -+13.) E.P. Pat. Appl. Ser. No. 96105920.1 entitled "Key Agreement and -+ Transport Protocol with Implicit Signatures" filed on April 16, 1996; -+14.) U.S. Pat. No. 6,141,420 entitled "Elliptic Curve Encryption Systems" -+ issued on October 31, 2000; -+15.) Can. Pat. Appl. Ser. No. 2155038 entitled "Elliptic Curve Encryption -+ Systems" filed on July 31, 1995; -+16.) E.P. Pat. Appl. Ser. No. 95926348.4 entitled "Elliptic Curve Encryption -+ Systems" filed on July 31, 1995; -+17.) U.S. Pat. No. 6,336,188 entitled "Authenticated Key Agreement" issued -+ on January 1, 2002; -+18.) U.S. Pat. No. 6,487,661 entitled "Key Agreement and Transport Protocol" -+ issued on November 26, 2002; -+19.) Can. Pat. Appl. Ser. No. 2174260 entitled "Key Agreement and Transport -+ Protocol" filed on April 16, 1996; -+20.) E.P. Pat. Appl. Ser. No. 96105921.9 entitled "Key Agreement and -+ Transport Protocol" filed on April 21, 1996; -+21.) U.S. Pat. No. 6,563,928 entitled "Strengthened Public Key Protocol" -+ issued on May 13, 2003; -+22.) U.S. Pat. No. 6,618,483 entitled "Elliptic Curve Encryption Systems" -+ issued September 9, 2003; -+23.) U.S. Pat. Appl. Ser. No. 09/434,247 entitled "Digital Signatures on a -+ Smartcard" filed on November 5, 1999; -+24.) U.S. Pat. Appl. Ser. No. 09/558,256 entitled "Key Agreement and -+ Transport Protocol with Implicit Signatures" filed on April 25, 2000; -+25.) U.S. Pat. Appl. Ser. No. 09/942,492 entitled "Digital Signatures on a -+ Smartcard" filed on August 29, 2001 and published on July 18, 2002; and, -+26.) U.S. Pat. Appl. Ser. No. 10/185,735 entitled "Strengthened Public Key -+ Protocol" filed on July 1, 2000. -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/README.ENGINE b/CryptoPkg/Library/OpensslLib/openssl/README.ENGINE -new file mode 100644 -index 0000000..530a4ed ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/README.ENGINE -@@ -0,0 +1,288 @@ -+ ENGINE -+ ====== -+ -+ With OpenSSL 0.9.6, a new component was added to support alternative -+ cryptography implementations, most commonly for interfacing with external -+ crypto devices (eg. accelerator cards). This component is called ENGINE, -+ and its presence in OpenSSL 0.9.6 (and subsequent bug-fix releases) -+ caused a little confusion as 0.9.6** releases were rolled in two -+ versions, a "standard" and an "engine" version. In development for 0.9.7, -+ the ENGINE code has been merged into the main branch and will be present -+ in the standard releases from 0.9.7 forwards. -+ -+ There are currently built-in ENGINE implementations for the following -+ crypto devices: -+ -+ o Cryptodev -+ o Microsoft CryptoAPI -+ o VIA Padlock -+ o nCipher CHIL -+ -+ In addition, dynamic binding to external ENGINE implementations is now -+ provided by a special ENGINE called "dynamic". See the "DYNAMIC ENGINE" -+ section below for details. -+ -+ At this stage, a number of things are still needed and are being worked on: -+ -+ 1 Integration of EVP support. -+ 2 Configuration support. -+ 3 Documentation! -+ -+1 With respect to EVP, this relates to support for ciphers and digests in -+ the ENGINE model so that alternative implementations of existing -+ algorithms/modes (or previously unimplemented ones) can be provided by -+ ENGINE implementations. -+ -+2 Configuration support currently exists in the ENGINE API itself, in the -+ form of "control commands". These allow an application to expose to the -+ user/admin the set of commands and parameter types a given ENGINE -+ implementation supports, and for an application to directly feed string -+ based input to those ENGINEs, in the form of name-value pairs. This is an -+ extensible way for ENGINEs to define their own "configuration" mechanisms -+ that are specific to a given ENGINE (eg. for a particular hardware -+ device) but that should be consistent across *all* OpenSSL-based -+ applications when they use that ENGINE. Work is in progress (or at least -+ in planning) for supporting these control commands from the CONF (or -+ NCONF) code so that applications using OpenSSL's existing configuration -+ file format can have ENGINE settings specified in much the same way. -+ Presently however, applications must use the ENGINE API itself to provide -+ such functionality. To see first hand the types of commands available -+ with the various compiled-in ENGINEs (see further down for dynamic -+ ENGINEs), use the "engine" openssl utility with full verbosity, ie; -+ openssl engine -vvvv -+ -+3 Documentation? Volunteers welcome! The source code is reasonably well -+ self-documenting, but some summaries and usage instructions are needed - -+ moreover, they are needed in the same POD format the existing OpenSSL -+ documentation is provided in. Any complete or incomplete contributions -+ would help make this happen. -+ -+ STABILITY & BUG-REPORTS -+ ======================= -+ -+ What already exists is fairly stable as far as it has been tested, but -+ the test base has been a bit small most of the time. For the most part, -+ the vendors of the devices these ENGINEs support have contributed to the -+ development and/or testing of the implementations, and *usually* (with no -+ guarantees) have experience in using the ENGINE support to drive their -+ devices from common OpenSSL-based applications. Bugs and/or inexplicable -+ behaviour in using a specific ENGINE implementation should be sent to the -+ author of that implementation (if it is mentioned in the corresponding C -+ file), and in the case of implementations for commercial hardware -+ devices, also through whatever vendor support channels are available. If -+ none of this is possible, or the problem seems to be something about the -+ ENGINE API itself (ie. not necessarily specific to a particular ENGINE -+ implementation) then you should mail complete details to the relevant -+ OpenSSL mailing list. For a definition of "complete details", refer to -+ the OpenSSL "README" file. As for which list to send it to; -+ -+ openssl-users: if you are *using* the ENGINE abstraction, either in an -+ pre-compiled application or in your own application code. -+ -+ openssl-dev: if you are discussing problems with OpenSSL source code. -+ -+ USAGE -+ ===== -+ -+ The default "openssl" ENGINE is always chosen when performing crypto -+ operations unless you specify otherwise. You must actively tell the -+ openssl utility commands to use anything else through a new command line -+ switch called "-engine". Also, if you want to use the ENGINE support in -+ your own code to do something similar, you must likewise explicitly -+ select the ENGINE implementation you want. -+ -+ Depending on the type of hardware, system, and configuration, "settings" -+ may need to be applied to an ENGINE for it to function as expected/hoped. -+ The recommended way of doing this is for the application to support -+ ENGINE "control commands" so that each ENGINE implementation can provide -+ whatever configuration primitives it might require and the application -+ can allow the user/admin (and thus the hardware vendor's support desk -+ also) to provide any such input directly to the ENGINE implementation. -+ This way, applications do not need to know anything specific to any -+ device, they only need to provide the means to carry such user/admin -+ input through to the ENGINE in question. Ie. this connects *you* (and -+ your helpdesk) to the specific ENGINE implementation (and device), and -+ allows application authors to not get buried in hassle supporting -+ arbitrary devices they know (and care) nothing about. -+ -+ A new "openssl" utility, "openssl engine", has been added in that allows -+ for testing and examination of ENGINE implementations. Basic usage -+ instructions are available by specifying the "-?" command line switch. -+ -+ DYNAMIC ENGINES -+ =============== -+ -+ The new "dynamic" ENGINE provides a low-overhead way to support ENGINE -+ implementations that aren't pre-compiled and linked into OpenSSL-based -+ applications. This could be because existing compiled-in implementations -+ have known problems and you wish to use a newer version with an existing -+ application. It could equally be because the application (or OpenSSL -+ library) you are using simply doesn't have support for the ENGINE you -+ wish to use, and the ENGINE provider (eg. hardware vendor) is providing -+ you with a self-contained implementation in the form of a shared-library. -+ The other use-case for "dynamic" is with applications that wish to -+ maintain the smallest foot-print possible and so do not link in various -+ ENGINE implementations from OpenSSL, but instead leaves you to provide -+ them, if you want them, in the form of "dynamic"-loadable -+ shared-libraries. It should be possible for hardware vendors to provide -+ their own shared-libraries to support arbitrary hardware to work with -+ applications based on OpenSSL 0.9.7 or later. If you're using an -+ application based on 0.9.7 (or later) and the support you desire is only -+ announced for versions later than the one you need, ask the vendor to -+ backport their ENGINE to the version you need. -+ -+ How does "dynamic" work? -+ ------------------------ -+ The dynamic ENGINE has a special flag in its implementation such that -+ every time application code asks for the 'dynamic' ENGINE, it in fact -+ gets its own copy of it. As such, multi-threaded code (or code that -+ multiplexes multiple uses of 'dynamic' in a single application in any -+ way at all) does not get confused by 'dynamic' being used to do many -+ independent things. Other ENGINEs typically don't do this so there is -+ only ever 1 ENGINE structure of its type (and reference counts are used -+ to keep order). The dynamic ENGINE itself provides absolutely no -+ cryptographic functionality, and any attempt to "initialise" the ENGINE -+ automatically fails. All it does provide are a few "control commands" -+ that can be used to control how it will load an external ENGINE -+ implementation from a shared-library. To see these control commands, -+ use the command-line; -+ -+ openssl engine -vvvv dynamic -+ -+ The "SO_PATH" control command should be used to identify the -+ shared-library that contains the ENGINE implementation, and "NO_VCHECK" -+ might possibly be useful if there is a minor version conflict and you -+ (or a vendor helpdesk) is convinced you can safely ignore it. -+ "ID" is probably only needed if a shared-library implements -+ multiple ENGINEs, but if you know the engine id you expect to be using, -+ it doesn't hurt to specify it (and this provides a sanity check if -+ nothing else). "LIST_ADD" is only required if you actually wish the -+ loaded ENGINE to be discoverable by application code later on using the -+ ENGINE's "id". For most applications, this isn't necessary - but some -+ application authors may have nifty reasons for using it. The "LOAD" -+ command is the only one that takes no parameters and is the command -+ that uses the settings from any previous commands to actually *load* -+ the shared-library ENGINE implementation. If this command succeeds, the -+ (copy of the) 'dynamic' ENGINE will magically morph into the ENGINE -+ that has been loaded from the shared-library. As such, any control -+ commands supported by the loaded ENGINE could then be executed as per -+ normal. Eg. if ENGINE "foo" is implemented in the shared-library -+ "libfoo.so" and it supports some special control command "CMD_FOO", the -+ following code would load and use it (NB: obviously this code has no -+ error checking); -+ -+ ENGINE *e = ENGINE_by_id("dynamic"); -+ ENGINE_ctrl_cmd_string(e, "SO_PATH", "/lib/libfoo.so", 0); -+ ENGINE_ctrl_cmd_string(e, "ID", "foo", 0); -+ ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0); -+ ENGINE_ctrl_cmd_string(e, "CMD_FOO", "some input data", 0); -+ -+ For testing, the "openssl engine" utility can be useful for this sort -+ of thing. For example the above code excerpt would achieve much the -+ same result as; -+ -+ openssl engine dynamic \ -+ -pre SO_PATH:/lib/libfoo.so \ -+ -pre ID:foo \ -+ -pre LOAD \ -+ -pre "CMD_FOO:some input data" -+ -+ Or to simply see the list of commands supported by the "foo" ENGINE; -+ -+ openssl engine -vvvv dynamic \ -+ -pre SO_PATH:/lib/libfoo.so \ -+ -pre ID:foo \ -+ -pre LOAD -+ -+ Applications that support the ENGINE API and more specifically, the -+ "control commands" mechanism, will provide some way for you to pass -+ such commands through to ENGINEs. As such, you would select "dynamic" -+ as the ENGINE to use, and the parameters/commands you pass would -+ control the *actual* ENGINE used. Each command is actually a name-value -+ pair and the value can sometimes be omitted (eg. the "LOAD" command). -+ Whilst the syntax demonstrated in "openssl engine" uses a colon to -+ separate the command name from the value, applications may provide -+ their own syntax for making that separation (eg. a win32 registry -+ key-value pair may be used by some applications). The reason for the -+ "-pre" syntax in the "openssl engine" utility is that some commands -+ might be issued to an ENGINE *after* it has been initialised for use. -+ Eg. if an ENGINE implementation requires a smart-card to be inserted -+ during initialisation (or a PIN to be typed, or whatever), there may be -+ a control command you can issue afterwards to "forget" the smart-card -+ so that additional initialisation is no longer possible. In -+ applications such as web-servers, where potentially volatile code may -+ run on the same host system, this may provide some arguable security -+ value. In such a case, the command would be passed to the ENGINE after -+ it has been initialised for use, and so the "-post" switch would be -+ used instead. Applications may provide a different syntax for -+ supporting this distinction, and some may simply not provide it at all -+ ("-pre" is almost always what you're after, in reality). -+ -+ How do I build a "dynamic" ENGINE? -+ ---------------------------------- -+ This question is trickier - currently OpenSSL bundles various ENGINE -+ implementations that are statically built in, and any application that -+ calls the "ENGINE_load_builtin_engines()" function will automatically -+ have all such ENGINEs available (and occupying memory). Applications -+ that don't call that function have no ENGINEs available like that and -+ would have to use "dynamic" to load any such ENGINE - but on the other -+ hand such applications would only have the memory footprint of any -+ ENGINEs explicitly loaded using user/admin provided control commands. -+ The main advantage of not statically linking ENGINEs and only using -+ "dynamic" for hardware support is that any installation using no -+ "external" ENGINE suffers no unnecessary memory footprint from unused -+ ENGINEs. Likewise, installations that do require an ENGINE incur the -+ overheads from only *that* ENGINE once it has been loaded. -+ -+ Sounds good? Maybe, but currently building an ENGINE implementation as -+ a shared-library that can be loaded by "dynamic" isn't automated in -+ OpenSSL's build process. It can be done manually quite easily however. -+ Such a shared-library can either be built with any OpenSSL code it -+ needs statically linked in, or it can link dynamically against OpenSSL -+ if OpenSSL itself is built as a shared library. The instructions are -+ the same in each case, but in the former (statically linked any -+ dependencies on OpenSSL) you must ensure OpenSSL is built with -+ position-independent code ("PIC"). The default OpenSSL compilation may -+ already specify the relevant flags to do this, but you should consult -+ with your compiler documentation if you are in any doubt. -+ -+ This example will show building the "atalla" ENGINE in the -+ crypto/engine/ directory as a shared-library for use via the "dynamic" -+ ENGINE. -+ 1) "cd" to the crypto/engine/ directory of a pre-compiled OpenSSL -+ source tree. -+ 2) Recompile at least one source file so you can see all the compiler -+ flags (and syntax) being used to build normally. Eg; -+ touch hw_atalla.c ; make -+ will rebuild "hw_atalla.o" using all such flags. -+ 3) Manually enter the same compilation line to compile the -+ "hw_atalla.c" file but with the following two changes; -+ (a) add "-DENGINE_DYNAMIC_SUPPORT" to the command line switches, -+ (b) change the output file from "hw_atalla.o" to something new, -+ eg. "tmp_atalla.o" -+ 4) Link "tmp_atalla.o" into a shared-library using the top-level -+ OpenSSL libraries to resolve any dependencies. The syntax for doing -+ this depends heavily on your system/compiler and is a nightmare -+ known well to anyone who has worked with shared-library portability -+ before. 'gcc' on Linux, for example, would use the following syntax; -+ gcc -shared -o dyn_atalla.so tmp_atalla.o -L../.. -lcrypto -+ 5) Test your shared library using "openssl engine" as explained in the -+ previous section. Eg. from the top-level directory, you might try; -+ apps/openssl engine -vvvv dynamic \ -+ -pre SO_PATH:./crypto/engine/dyn_atalla.so -pre LOAD -+ If the shared-library loads successfully, you will see both "-pre" -+ commands marked as "SUCCESS" and the list of control commands -+ displayed (because of "-vvvv") will be the control commands for the -+ *atalla* ENGINE (ie. *not* the 'dynamic' ENGINE). You can also add -+ the "-t" switch to the utility if you want it to try and initialise -+ the atalla ENGINE for use to test any possible hardware/driver -+ issues. -+ -+ PROBLEMS -+ ======== -+ -+ It seems like the ENGINE part doesn't work too well with CryptoSwift on Win32. -+ A quick test done right before the release showed that trying "openssl speed -+ -engine cswift" generated errors. If the DSO gets enabled, an attempt is made -+ to write at memory address 0x00000002. -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/README.FIPS b/CryptoPkg/Library/OpensslLib/openssl/README.FIPS -new file mode 100644 -index 0000000..8593486 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/README.FIPS -@@ -0,0 +1 @@ -+This release does not support a FIPS 140-2 validated module. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/VMS/VMSify-conf.pl b/CryptoPkg/Library/OpensslLib/openssl/VMS/VMSify-conf.pl -new file mode 100644 -index 0000000..21eff11 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/VMS/VMSify-conf.pl -@@ -0,0 +1,41 @@ -+#! /usr/bin/env perl -+# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+# -+# Licensed under the OpenSSL license (the "License"). You may not use -+# this file except in compliance with the License. You can obtain a copy -+# in the file LICENSE in the source distribution or at -+# https://www.openssl.org/source/license.html -+ -+ -+use strict; -+use warnings; -+ -+my @directory_vars = ( "dir", "certs", "crl_dir", "new_certs_dir" ); -+my @file_vars = ( "database", "certificate", "serial", "crlnumber", -+ "crl", "private_key", "RANDFILE" ); -+while() { -+ s|\R$||; -+ foreach my $d (@directory_vars) { -+ if (/^(\s*\#?\s*${d}\s*=\s*)\.\/([^\s\#]*)([\s\#].*)$/) { -+ $_ = "$1sys\\\$disk:\[.$2$3"; -+ } elsif (/^(\s*\#?\s*${d}\s*=\s*)(\w[^\s\#]*)([\s\#].*)$/) { -+ $_ = "$1sys\\\$disk:\[.$2$3"; -+ } -+ s/^(\s*\#?\s*${d}\s*=\s*\$\w+)\/([^\s\#]*)([\s\#].*)$/$1.$2\]$3/; -+ while(/^(\s*\#?\s*${d}\s*=\s*(\$\w+\.|sys\\\$disk:\[\.)[\w\.]+)\/([^\]]*)\](.*)$/) { -+ $_ = "$1.$3]$4"; -+ } -+ } -+ foreach my $f (@file_vars) { -+ s/^(\s*\#?\s*${f}\s*=\s*)\.\/(.*)$/$1sys\\\$disk:\[\/$2/; -+ while(/^(\s*\#?\s*${f}\s*=\s*(\$\w+|sys\\\$disk:\[)[^\/]*)\/(\w+\/[^\s\#]*)([\s\#].*)$/) { -+ $_ = "$1.$3$4"; -+ } -+ if (/^(\s*\#?\s*${f}\s*=\s*(\$\w+|sys\\\$disk:\[)[^\/]*)\/(\w+)([\s\#].*)$/) { -+ $_ = "$1]$3.$4"; -+ } elsif (/^(\s*\#?\s*${f}\s*=\s*(\$\w+|sys\\\$disk:\[)[^\/]*)\/([^\s\#]*)([\s\#].*)$/) { -+ $_ = "$1]$3$4"; -+ } -+ } -+ print $_,"\n"; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/VMS/engine.opt b/CryptoPkg/Library/OpensslLib/openssl/VMS/engine.opt -new file mode 100644 -index 0000000..1c73c80 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/VMS/engine.opt -@@ -0,0 +1,2 @@ -+CASE_SENSITIVE=YES -+SYMBOL_VECTOR=(bind_engine=PROCEDURE,v_check=PROCEDURE) -diff --git a/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_ivp.com.in b/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_ivp.com.in -new file mode 100644 -index 0000000..825a699 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_ivp.com.in -@@ -0,0 +1,50 @@ -+$ ! OpenSSL Internal Verification Procedure -+$ ! -+$ ! This script checks the consistency of a OpenSSL installation -+$ ! It had better be spawned, as it creates process logicals -+$ -+$ ! Generated information -+$ INSTALLTOP := {- $config{INSTALLTOP} -} -+$ OPENSSLDIR := {- $config{OPENSSLDIR} -} -+$ -+$ ! Make sure that INSTALLTOP and OPENSSLDIR become something one -+$ ! can use to call the startup procedure -+$ INSTALLTOP_ = F$PARSE("A.;",INSTALLTOP,,,"NO_CONCEAL") - -+ - ".][000000" - "[000000." - "][" - "]A.;" + "." -+$ OPENSSLDIR_ = F$PARSE("A.;",OPENSSLDIR,,,"NO_CONCEAL") - -+ - ".][000000" - "[000000." - "][" - "]A.;" + "." -+$ -+$ v := {- sprintf "%02d%02d", split(/\./, $config{version}) -} -+$ pz := {- $config{pointer_size} -} -+$ -+$ @'INSTALLTOP_'SYS$STARTUP]openssl_startup'v' -+$ @'INSTALLTOP_'SYS$STARTUP]openssl_utils'v' -+$ -+$ IF F$SEARCH("OSSL$LIBCRYPTO''pz'") .EQS. "" - -+ .OR. F$SEARCH("OSSL$LIBSSL''pz'") .EQS. "" {- output_off() if $config{no_shared}; "" -}- -+ .OR. F$SEARCH("OSSL$LIBCRYPTO_SHR''pz'") .EQS. "" - -+ .OR. F$SEARCH("OSSL$LIBSSL_SHR''pz'") .EQS. "" {- output_on() if $config{no_shared}; "" -}- -+ .OR. F$SEARCH("OSSL$INCLUDE:[OPENSSL]crypto.h") .EQS. "" - -+ .OR. F$SEARCH("OPENSSL:crypto.h") .EQS. "" - -+ .OR. F$SEARCH("OSSL$EXE:OPENSSL''v'.EXE") .EQS. "" -+$ THEN -+$ WRITE SYS$ERROR "Installation inconsistent" -+$ EXIT %x00018292 ! RMS$_FNF, file not found -+$ ENDIF -+$ -+$ ON ERROR THEN GOTO error -+$ -+$ ! If something else is wrong with the installation, we're likely -+$ ! to get an image activation error here -+$ openssl version -a -+$ -+$ ! FUTURE ENHANCEMENT: Verify that engines are where they should be. -+$ ! openssl engine -c -t checker -+$ -+$ WRITE SYS$ERROR "OpenSSL IVP passed" -+$ EXIT %x10000001 -+$ -+$ error: -+$ save_status = $STATUS -+$ WRITE SYS$ERROR "OpenSSL IVP failed" -+$ EXIT 'save_status' -diff --git a/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_shutdown.com.in b/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_shutdown.com.in -new file mode 100644 -index 0000000..f0df1c1 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_shutdown.com.in -@@ -0,0 +1,56 @@ -+$ ! OpenSSL shutdown script -+$ ! -+$ ! This script deassigns the logical names used by the installation -+$ ! of OpenSSL. It can do so at any level, defined by P1. -+$ ! -+$ ! P1 Qualifier(s) for DEASSIGN. -+$ ! Default: /PROCESS -+$ ! -+$ ! P2 If the value is "NOALIASES", no alias logical names are -+$ ! deassigned. -+$ -+$ status = %x10000001 ! Generic success -+$ -+$ ! In case there's a problem -+$ ON CONTROL_Y THEN GOTO bailout -+$ ON ERROR THEN GOTO bailout -+$ -+$ ! Find the architecture -+$ IF F$GETSYI("CPU") .LT. 128 -+$ THEN -+$ arch := VAX -+$ ELSE -+$ arch := F$EDIT(F$GETSYI("ARCH_NAME"),"UPCASE") -+$ IF arch .EQS. "" THEN GOTO unknown_arch -+$ ENDIF -+$ -+$ ! Abbrevs -+$ DEAS := DEASSIGN /NOLOG 'P1' -+$ sv := {- sprintf "%02d%02d", $config{shlib_major}, $config{shlib_minor} -} -+$ pz := {- $config{pointer_size} -} -+$ -+$ DEAS OSSL$DATAROOT -+$ DEAS OSSL$INSTROOT -+$ DEAS OSSL$INCLUDE -+$ DEAS OSSL$LIB -+$ DEAS OSSL$SHARE -+$ DEAS OSSL$ENGINES'sv' -+$ DEAS OSSL$EXE -+$ DEAS OSSL$LIBCRYPTO'pz' -+$ DEAS OSSL$LIBSSL'pz' -+${- output_off() if $config{no_shared}; "" -} -+$ DEAS OSSL$LIBCRYPTO'sv'_SHR'pz' -+$ DEAS OSSL$LIBSSL'sv'_SHR'pz' -+${- output_on() if $config{no_shared}; "" -} -+$ DEAS OPENSSL -+$ -+$ IF P2 .NES. "NOALIASES" -+$ THEN -+$ DEAS OSSL$ENGINES -+${- output_off() if $config{no_shared}; "" -} -+$ DEAS OSSL$LIBCRYPTO_SHR'pz' -+$ DEAS OSSL$LIBSSL_SHR'pz' -+${- output_on() if $config{no_shared}; "" -} -+$ ENDIF -+$ -+$ EXIT 'status' -diff --git a/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_startup.com.in b/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_startup.com.in -new file mode 100644 -index 0000000..9c8c09a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_startup.com.in -@@ -0,0 +1,123 @@ -+$ ! OpenSSL startup script -+$ ! -+$ ! This script defines the logical names used by the installation -+$ ! of OpenSSL. It can provide those logical names at any level, -+$ ! defined by P1. -+$ ! -+$ ! The logical names created are: -+$ ! -+$ ! OSSL$INSTROOT Installation root -+$ ! OSSL$DATAROOT Data root (common directory -+$ ! for certs etc) -+$ ! OSSL$INCLUDE Include directory root -+$ ! OSSL$LIB Where the static library files -+$ ! are located -+$ ! OSSL$SHARE Where the shareable image files -+$ ! are located -+$ ! OSSL$EXE Where the executables are located -+$ ! OSSL$ENGINESnnn Where the shareable images are located -+$ ! OSSL$LIBCRYPTO The static crypto library -+$ ! OSSL$LIBSSL The static ssl library -+$ ! OSSL$LIBCRYPTOnnn_SHR The shareable crypto image -+$ ! OSSL$LIBSSLnnn_SHR The shareable ssl image -+$ ! OPENSSL is OSSL$INCLUDE:[OPENSSL] -+$ ! -+$ ! In all these, nnn is the OpenSSL version number. This allows -+$ ! several OpenSSL versions to be installed simultaneously, which -+$ ! matters for applications that are linked to the shareable images -+$ ! or that depend on engines. -+$ ! -+$ ! In addition, unless P2 is "NOALIASES", these logical names are -+$ ! created: -+$ ! -+$ ! OSSL$ENGINES Alias for OSSL$ENGINESnnn -+$ ! OSSL$LIBCRYPTO_SHR Alias for OSSL$LIBCRYPTOnnn_SHR -+$ ! OSSL$LIBSSL_SHR Alias for OSSL$LIBSSLnnn_SHR -+$ ! -+$ ! P1 Qualifier(s) for DEFINE. "/SYSTEM" would be typical when -+$ ! calling this script from SYS$STARTUP:SYSTARTUP_VMS.COM, -+$ ! while "/PROCESS" would be typical for a personal install. -+$ ! Default: /PROCESS -+$ ! -+$ ! P2 If the value is "NOALIASES", no alias logical names are -+$ ! created. -+$ -+$ status = %x10000001 ! Generic success -+$ -+$ ! In case there's a problem -+$ ON CONTROL_Y THEN GOTO bailout -+$ ON ERROR THEN GOTO bailout -+$ -+$ ! Find the architecture -+$ IF F$GETSYI("CPU") .LT. 128 -+$ THEN -+$ arch := VAX -+$ ELSE -+$ arch = F$EDIT(F$GETSYI("ARCH_NAME"),"UPCASE") -+$ IF arch .EQS. "" THEN GOTO unknown_arch -+$ ENDIF -+$ -+$ ! Generated information -+$ INSTALLTOP := {- $config{INSTALLTOP} -} -+$ OPENSSLDIR := {- $config{OPENSSLDIR} -} -+$ -+$ ! Make sure that INSTALLTOP and OPENSSLDIR become something one -+$ ! can build concealed logical names on -+$ INSTALLTOP_ = F$PARSE("A.;",INSTALLTOP,,,"NO_CONCEAL") - -+ - ".][000000" - "[000000." - "][" - "]A.;" + "." -+$ OPENSSLDIR_ = F$PARSE("A.;",OPENSSLDIR,,,"NO_CONCEAL") - -+ - ".][000000" - "[000000." - "][" - "]A.;" + "." -+$ -+$ DEFINE /TRANSLATION=CONCEALED /NOLOG WRK_INSTALLTOP 'INSTALLTOP_'] -+$ DEFINE /TRANSLATION=CONCEALED /NOLOG WRK_OPENSSLDIR 'OPENSSLDIR_'] -+$ -+$ ! Check that things are in place, and specifically, the stuff -+$ ! belonging to this architecture -+$ IF F$SEARCH("WRK_INSTALLTOP:[000000]INCLUDE.DIR;1") .EQS. "" - -+ .OR. F$SEARCH("WRK_INSTALLTOP:[000000]LIB.DIR;1") .EQS. "" - -+ .OR. F$SEARCH("WRK_INSTALLTOP:[000000]EXE.DIR;1") .EQS. "" - -+ .OR. F$SEARCH("WRK_INSTALLTOP:[LIB]''arch'.DIR;1") .EQS. "" - -+ .OR. F$SEARCH("WRK_INSTALLTOP:[EXE]''arch'.DIR;1") .EQS. "" - -+ .OR. F$SEARCH("WRK_OPENSSLDIR:[000000]openssl.cnf") .EQS. "" -+$ THEN -+$ WRITE SYS$ERROR "''INSTALLTOP' doesn't look like an OpenSSL installation for ''arch'" -+$ status = %x00018292 ! RMS$_FNF, file not found -+$ GOTO bailout -+$ ENDIF -+$ -+$ ! Abbrevs -+$ DEFT := DEFINE /TRANSLATION=CONCEALED /NOLOG 'P1' -+$ DEF := DEFINE /NOLOG 'P1' -+$ sv := {- sprintf "%02d%02d", $config{shlib_major}, $config{shlib_minor} -} -+$ pz := {- $config{pointer_size} -} -+$ -+$ DEFT OSSL$DATAROOT 'OPENSSLDIR_'] -+$ DEFT OSSL$INSTROOT 'INSTALLTOP_'] -+$ DEFT OSSL$INCLUDE 'INSTALLTOP_'INCLUDE.] -+$ DEF OSSL$LIB OSSL$INSTROOT:[LIB.'arch'] -+$ DEF OSSL$SHARE OSSL$INSTROOT:[LIB.'arch'] -+$ DEF OSSL$ENGINES'sv''pz' OSSL$INSTROOT:[ENGINES'sv''pz'.'arch'] -+$ DEF OSSL$EXE OSSL$INSTROOT:[EXE.'arch'],- -+ OSSL$INSTROOT:[EXE] -+$ DEF OSSL$LIBCRYPTO'pz' OSSL$LIB:OSSL$LIBCRYPTO'pz'.OLB -+$ DEF OSSL$LIBSSL'pz' OSSL$LIB:OSSL$LIBSSL'pz'.OLB -+${- output_off() if $config{no_shared}; "" -} -+$ DEF OSSL$LIBCRYPTO'sv'_SHR'pz' OSSL$SHARE:OSSL$LIBCRYPTO'sv'_SHR'pz'.EXE -+$ DEF OSSL$LIBSSL'sv'_SHR'pz' OSSL$SHARE:OSSL$LIBSSL'sv'_SHR'pz'.EXE -+${- output_on() if $config{no_shared}; "" -} -+$ DEF OPENSSL OSSL$INCLUDE:[OPENSSL] -+$ -+$ IF P2 .NES. "NOALIASES" -+$ THEN -+$ DEF OSSL$ENGINES'pz' OSSL$ENGINES'sv''pz' -+${- output_off() if $config{no_shared}; "" -} -+$ DEF OSSL$LIBCRYPTO_SHR'pz' OSSL$LIBCRYPTO'sv'_SHR'pz' -+$ DEF OSSL$LIBSSL_SHR'pz' OSSL$LIBSSL'sv'_SHR'pz' -+${- output_on() if $config{no_shared}; "" -} -+$ ENDIF -+$ -+$ bailout: -+$ DEASSIGN WRK_INSTALLTOP -+$ DEASSIGN WRK_OPENSSLDIR -+$ -+$ EXIT 'status' -diff --git a/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_utils.com.in b/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_utils.com.in -new file mode 100644 -index 0000000..edd733d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/VMS/openssl_utils.com.in -@@ -0,0 +1,14 @@ -+$ ! OpenSSL utilities -+$ ! -+$ -+$ v := {- sprintf "%02d%02d", split(/\./, $config{version}) -} -+$ -+$ OPENSSL'v' :== $OSSL$EXE:OPENSSL'v' -+$ OPENSSL :== $OSSL$EXE:OPENSSL'v' -+$ -+$ IF F$TYPE(PERL) .EQS. "STRING" -+$ THEN -+$ C_REHASH :== 'PERL' OSSL$EXE:c_rehash.pl -+$ ELSE -+$ WRITE SYS$ERROR "NOTE: no perl => no C_REHASH" -+$ ENDIF -diff --git a/CryptoPkg/Library/OpensslLib/openssl/VMS/test-includes.com b/CryptoPkg/Library/OpensslLib/openssl/VMS/test-includes.com -new file mode 100644 -index 0000000..c1d7ccd ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/VMS/test-includes.com -@@ -0,0 +1,28 @@ -+$! Quick script to check how well including individual header files works -+$! on VMS, even when the VMS macro isn't defined. -+$ -+$ sav_def = f$env("DEFAULT") -+$ here = f$parse("A.;0",f$ENV("PROCEDURE")) - "A.;0" -+$ set default 'here' -+$ set default [-.include.openssl] -+$ define openssl 'f$env("DEFAULT")' -+$ set default [--] -+$ -+$ loop: -+$ f = f$search("openssl:*.h") -+$ if f .eqs. "" then goto loop_end -+$ write sys$output "Checking ",f -+$ open/write foo foo.c -+$ write foo "#undef VMS" -+$ write foo "#include " -+$ write foo "#include " -+$ write foo "main()" -+$ write foo "{printf(""foo\n"");}" -+$ close foo -+$ cc/STANDARD=ANSI89/NOLIST/PREFIX=ALL foo.c -+$ delete foo.c; -+$ goto loop -+$ loop_end: -+$ set default 'save_def' -+$ exit -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/VMS/translatesyms.pl b/CryptoPkg/Library/OpensslLib/openssl/VMS/translatesyms.pl -new file mode 100644 -index 0000000..f61d954 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/VMS/translatesyms.pl -@@ -0,0 +1,62 @@ -+#! /usr/bin/env perl -+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. -+# -+# Licensed under the OpenSSL license (the "License"). You may not use -+# this file except in compliance with the License. You can obtain a copy -+# in the file LICENSE in the source distribution or at -+# https://www.openssl.org/source/license.html -+ -+ -+# This script will translate any SYMBOL_VECTOR item that has a translation -+# in CXX$DEMANGLER_DB. The latter is generated by and CC/DECC command that -+# uses the qualifier /REPOSITORY with the build directory as value. When -+# /NAMES=SHORTENED has been used, this file will hold the translations from -+# the original symbols to the shortened variants. -+# -+# CXX$DEMAGLER_DB. is an ISAM file, but with the magic of RMS, it can be -+# read as a text file, with each record as one line. -+# -+# The lines will have the following syntax for any symbol found that's longer -+# than 31 characters: -+# -+# LONG_symbol_34567890123{cksum}$LONG_symbol_34567890123_more_than_31_chars -+# -+# $ is present at the end of the shortened symbol name, and is preceded by a -+# 7 character checksum. The $ makes it easy to separate the shortened name -+# from the original one. -+ -+use strict; -+use warnings; -+ -+usage() if scalar @ARGV < 1; -+ -+my %translations = (); -+ -+open DEMANGLER_DATA, $ARGV[0] -+ or die "Couldn't open $ARGV[0]: $!\n"; -+while() { -+ s|\R$||; -+ (my $translated, my $original) = split /\$/; -+ $translations{$original} = $translated.'$'; -+} -+close DEMANGLER_DATA; -+ -+$| = 1; # Autoflush -+while() { -+ s@ -+ ((?:[A-Za-z0-9_]+)\/)?([A-Za-z0-9_]+)=(PROCEDURE|DATA) -+ @ -+ if (defined($translations{$2})) { -+ my $trans = $translations{$2}; -+ my $trans_uc = uc $trans; -+ if (defined($1) && $trans ne $trans_uc) { -+ "$trans_uc/$trans=$3" -+ } else { -+ "$trans=$3" -+ } -+ } else { -+ $& -+ } -+ @gxe; -+ print $_; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/CA.pl.in b/CryptoPkg/Library/OpensslLib/openssl/apps/CA.pl.in -new file mode 100644 -index 0000000..3187e47 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/CA.pl.in -@@ -0,0 +1,196 @@ -+#!{- $config{hashbangperl} -} -+# Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. -+# -+# Licensed under the OpenSSL license (the "License"). You may not use -+# this file except in compliance with the License. You can obtain a copy -+# in the file LICENSE in the source distribution or at -+# https://www.openssl.org/source/license.html -+ -+# -+# Wrapper around the ca to make it easier to use -+# -+# {- join("\n# ", @autowarntext) -} -+ -+use strict; -+use warnings; -+ -+my $openssl = "openssl"; -+if(defined $ENV{'OPENSSL'}) { -+ $openssl = $ENV{'OPENSSL'}; -+} else { -+ $ENV{'OPENSSL'} = $openssl; -+} -+ -+my $verbose = 1; -+ -+my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} || ""; -+my $DAYS = "-days 365"; -+my $CADAYS = "-days 1095"; # 3 years -+my $REQ = "$openssl req $OPENSSL_CONFIG"; -+my $CA = "$openssl ca $OPENSSL_CONFIG"; -+my $VERIFY = "$openssl verify"; -+my $X509 = "$openssl x509"; -+my $PKCS12 = "$openssl pkcs12"; -+ -+# default openssl.cnf file has setup as per the following -+my $CATOP = "./demoCA"; -+my $CAKEY = "cakey.pem"; -+my $CAREQ = "careq.pem"; -+my $CACERT = "cacert.pem"; -+my $CACRL = "crl.pem"; -+my $DIRMODE = 0777; -+ -+my $NEWKEY = "newkey.pem"; -+my $NEWREQ = "newreq.pem"; -+my $NEWCERT = "newcert.pem"; -+my $NEWP12 = "newcert.p12"; -+my $RET = 0; -+my $WHAT = shift @ARGV || ""; -+my $FILE; -+ -+# See if reason for a CRL entry is valid; exit if not. -+sub crl_reason_ok -+{ -+ my $r = shift; -+ -+ if ($r eq 'unspecified' || $r eq 'keyCompromise' -+ || $r eq 'CACompromise' || $r eq 'affiliationChanged' -+ || $r eq 'superseded' || $r eq 'cessationOfOperation' -+ || $r eq 'certificateHold' || $r eq 'removeFromCRL') { -+ return 1; -+ } -+ print STDERR "Invalid CRL reason; must be one of:\n"; -+ print STDERR " unspecified, keyCompromise, CACompromise,\n"; -+ print STDERR " affiliationChanged, superseded, cessationOfOperation\n"; -+ print STDERR " certificateHold, removeFromCRL"; -+ exit 1; -+} -+ -+# Copy a PEM-format file; return like exit status (zero means ok) -+sub copy_pemfile -+{ -+ my ($infile, $outfile, $bound) = @_; -+ my $found = 0; -+ -+ open IN, $infile || die "Cannot open $infile, $!"; -+ open OUT, ">$outfile" || die "Cannot write to $outfile, $!"; -+ while () { -+ $found = 1 if /^-----BEGIN.*$bound/; -+ print OUT $_ if $found; -+ $found = 2, last if /^-----END.*$bound/; -+ } -+ close IN; -+ close OUT; -+ return $found == 2 ? 0 : 1; -+} -+ -+# Wrapper around system; useful for debugging. Returns just the exit status -+sub run -+{ -+ my $cmd = shift; -+ print "====\n$cmd\n" if $verbose; -+ my $status = system($cmd); -+ print "==> $status\n====\n" if $verbose; -+ return $status >> 8; -+} -+ -+ -+if ( $WHAT =~ /^(-\?|-h|-help)$/ ) { -+ print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-signcert|-verify\n"; -+ print STDERR " CA -pkcs12 [certname]\n"; -+ print STDERR " CA -crl|-revoke cert-filename [reason]\n"; -+ exit 0; -+} -+if ($WHAT eq '-newcert' ) { -+ # create a certificate -+ $RET = run("$REQ -new -x509 -keyout $NEWKEY -out $NEWCERT $DAYS"); -+ print "Cert is in $NEWCERT, private key is in $NEWKEY\n" if $RET == 0; -+} elsif ($WHAT eq '-newreq' ) { -+ # create a certificate request -+ $RET = run("$REQ -new -keyout $NEWKEY -out $NEWREQ $DAYS"); -+ print "Request is in $NEWREQ, private key is in $NEWKEY\n" if $RET == 0; -+} elsif ($WHAT eq '-newreq-nodes' ) { -+ # create a certificate request -+ $RET = run("$REQ -new -nodes -keyout $NEWKEY -out $NEWREQ $DAYS"); -+ print "Request is in $NEWREQ, private key is in $NEWKEY\n" if $RET == 0; -+} elsif ($WHAT eq '-newca' ) { -+ # create the directory hierarchy -+ mkdir ${CATOP}, $DIRMODE; -+ mkdir "${CATOP}/certs", $DIRMODE; -+ mkdir "${CATOP}/crl", $DIRMODE ; -+ mkdir "${CATOP}/newcerts", $DIRMODE; -+ mkdir "${CATOP}/private", $DIRMODE; -+ open OUT, ">${CATOP}/index.txt"; -+ close OUT; -+ open OUT, ">${CATOP}/crlnumber"; -+ print OUT "01\n"; -+ close OUT; -+ # ask user for existing CA certificate -+ print "CA certificate filename (or enter to create)\n"; -+ $FILE = "" unless defined($FILE = ); -+ $FILE =~ s{\R$}{}; -+ if ($FILE ne "") { -+ copy_pemfile($FILE,"${CATOP}/private/$CAKEY", "PRIVATE"); -+ copy_pemfile($FILE,"${CATOP}/$CACERT", "CERTIFICATE"); -+ } else { -+ print "Making CA certificate ...\n"; -+ $RET = run("$REQ -new -keyout" -+ . " ${CATOP}/private/$CAKEY" -+ . " -out ${CATOP}/$CAREQ"); -+ $RET = run("$CA -create_serial" -+ . " -out ${CATOP}/$CACERT $CADAYS -batch" -+ . " -keyfile ${CATOP}/private/$CAKEY -selfsign" -+ . " -extensions v3_ca" -+ . " -infiles ${CATOP}/$CAREQ") if $RET == 0; -+ print "CA certificate is in ${CATOP}/$CACERT\n" if $RET == 0; -+ } -+} elsif ($WHAT eq '-pkcs12' ) { -+ my $cname = $ARGV[1]; -+ $cname = "My Certificate" unless defined $cname; -+ $RET = run("$PKCS12 -in $NEWCERT -inkey $NEWKEY" -+ . " -certfile ${CATOP}/$CACERT" -+ . " -out $NEWP12" -+ . " -export -name \"$cname\""); -+ print "PKCS #12 file is in $NEWP12\n" if $RET == 0; -+} elsif ($WHAT eq '-xsign' ) { -+ $RET = run("$CA -policy policy_anything -infiles $NEWREQ"); -+} elsif ($WHAT eq '-sign' ) { -+ $RET = run("$CA -policy policy_anything -out $NEWCERT -infiles $NEWREQ"); -+ print "Signed certificate is in $NEWCERT\n" if $RET == 0; -+} elsif ($WHAT eq '-signCA' ) { -+ $RET = run("$CA -policy policy_anything -out $NEWCERT" -+ . " -extensions v3_ca -infiles $NEWREQ"); -+ print "Signed CA certificate is in $NEWCERT\n" if $RET == 0; -+} elsif ($WHAT eq '-signcert' ) { -+ $RET = run("$X509 -x509toreq -in $NEWREQ -signkey $NEWREQ" -+ . " -out tmp.pem"); -+ $RET = run("$CA -policy policy_anything -out $NEWCERT" -+ . " -infiles tmp.pem") if $RET == 0; -+ print "Signed certificate is in $NEWCERT\n" if $RET == 0; -+} elsif ($WHAT eq '-verify' ) { -+ my @files = @ARGV ? @ARGV : ( $NEWCERT ); -+ my $file; -+ foreach $file (@files) { -+ my $status = run("$VERIFY \"-CAfile\" ${CATOP}/$CACERT $file"); -+ $RET = $status if $status != 0; -+ } -+} elsif ($WHAT eq '-crl' ) { -+ $RET = run("$CA -gencrl -out ${CATOP}/crl/$CACRL"); -+ print "Generated CRL is in ${CATOP}/crl/$CACRL\n" if $RET == 0; -+} elsif ($WHAT eq '-revoke' ) { -+ my $cname = $ARGV[1]; -+ if (!defined $cname) { -+ print "Certificate filename is required; reason optional.\n"; -+ exit 1; -+ } -+ my $reason = $ARGV[2]; -+ $reason = " -crl_reason $reason" -+ if defined $reason && crl_reason_ok($reason); -+ $RET = run("$CA -revoke \"$cname\"" . $reason); -+} else { -+ print STDERR "Unknown arg \"$WHAT\"\n"; -+ print STDERR "Use -help for help.\n"; -+ exit 1; -+} -+ -+exit $RET; -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/app_rand.c b/CryptoPkg/Library/OpensslLib/openssl/apps/app_rand.c -new file mode 100644 -index 0000000..0d44af9 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/app_rand.c -@@ -0,0 +1,115 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "apps.h" -+#include -+#include -+ -+static int seeded = 0; -+static int egdsocket = 0; -+ -+int app_RAND_load_file(const char *file, int dont_warn) -+{ -+ int consider_randfile = (file == NULL); -+ char buffer[200]; -+ -+ if (file == NULL) -+ file = RAND_file_name(buffer, sizeof buffer); -+#ifndef OPENSSL_NO_EGD -+ else if (RAND_egd(file) > 0) { -+ /* -+ * we try if the given filename is an EGD socket. if it is, we don't -+ * write anything back to the file. -+ */ -+ egdsocket = 1; -+ return 1; -+ } -+#endif -+ if (file == NULL || !RAND_load_file(file, -1)) { -+ if (RAND_status() == 0) { -+ if (!dont_warn) { -+ BIO_printf(bio_err, "unable to load 'random state'\n"); -+ BIO_printf(bio_err, -+ "This means that the random number generator has not been seeded\n"); -+ BIO_printf(bio_err, "with much random data.\n"); -+ if (consider_randfile) { /* explanation does not apply when a -+ * file is explicitly named */ -+ BIO_printf(bio_err, -+ "Consider setting the RANDFILE environment variable to point at a file that\n"); -+ BIO_printf(bio_err, -+ "'random' data can be kept in (the file will be overwritten).\n"); -+ } -+ } -+ return 0; -+ } -+ } -+ seeded = 1; -+ return 1; -+} -+ -+long app_RAND_load_files(char *name) -+{ -+ char *p, *n; -+ int last; -+ long tot = 0; -+#ifndef OPENSSL_NO_EGD -+ int egd; -+#endif -+ -+ for (;;) { -+ last = 0; -+ for (p = name; ((*p != '\0') && (*p != LIST_SEPARATOR_CHAR)); p++) ; -+ if (*p == '\0') -+ last = 1; -+ *p = '\0'; -+ n = name; -+ name = p + 1; -+ if (*n == '\0') -+ break; -+ -+#ifndef OPENSSL_NO_EGD -+ egd = RAND_egd(n); -+ if (egd > 0) -+ tot += egd; -+ else -+#endif -+ tot += RAND_load_file(n, -1); -+ if (last) -+ break; -+ } -+ if (tot > 512) -+ app_RAND_allow_write_file(); -+ return (tot); -+} -+ -+int app_RAND_write_file(const char *file) -+{ -+ char buffer[200]; -+ -+ if (egdsocket || !seeded) -+ /* -+ * If we did not manage to read the seed file, we should not write a -+ * low-entropy seed file back -- it would suppress a crucial warning -+ * the next time we want to use it. -+ */ -+ return 0; -+ -+ if (file == NULL) -+ file = RAND_file_name(buffer, sizeof buffer); -+ if (file == NULL || !RAND_write_file(file)) { -+ BIO_printf(bio_err, "unable to write 'random state'\n"); -+ return 0; -+ } -+ return 1; -+} -+ -+void app_RAND_allow_write_file(void) -+{ -+ seeded = 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/apps.c b/CryptoPkg/Library/OpensslLib/openssl/apps/apps.c -new file mode 100644 -index 0000000..cbf4e90 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/apps.c -@@ -0,0 +1,2653 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) -+/* -+ * On VMS, you need to define this to get the declaration of fileno(). The -+ * value 2 is to make sure no function defined in POSIX-2 is left undefined. -+ */ -+# define _POSIX_C_SOURCE 2 -+#endif -+ -+#include -+#include -+#include -+#ifndef NO_SYS_TYPES_H -+# include -+#endif -+#ifndef OPENSSL_NO_POSIX_IO -+# include -+# include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef OPENSSL_NO_ENGINE -+# include -+#endif -+#ifndef OPENSSL_NO_RSA -+# include -+#endif -+#include -+#include -+#include "s_apps.h" -+#include "apps.h" -+ -+#ifdef _WIN32 -+static int WIN32_rename(const char *from, const char *to); -+# define rename(from,to) WIN32_rename((from),(to)) -+#endif -+ -+typedef struct { -+ const char *name; -+ unsigned long flag; -+ unsigned long mask; -+} NAME_EX_TBL; -+ -+#if !defined(OPENSSL_NO_UI) || !defined(OPENSSL_NO_ENGINE) -+static UI_METHOD *ui_method = NULL; -+#endif -+ -+static int set_table_opts(unsigned long *flags, const char *arg, -+ const NAME_EX_TBL * in_tbl); -+static int set_multi_opts(unsigned long *flags, const char *arg, -+ const NAME_EX_TBL * in_tbl); -+ -+int app_init(long mesgwin); -+ -+int chopup_args(ARGS *arg, char *buf) -+{ -+ int quoted; -+ char c = '\0', *p = NULL; -+ -+ arg->argc = 0; -+ if (arg->size == 0) { -+ arg->size = 20; -+ arg->argv = app_malloc(sizeof(*arg->argv) * arg->size, "argv space"); -+ } -+ -+ for (p = buf;;) { -+ /* Skip whitespace. */ -+ while (*p && isspace(_UC(*p))) -+ p++; -+ if (!*p) -+ break; -+ -+ /* The start of something good :-) */ -+ if (arg->argc >= arg->size) { -+ char **tmp; -+ arg->size += 20; -+ tmp = OPENSSL_realloc(arg->argv, sizeof(*arg->argv) * arg->size); -+ if (tmp == NULL) -+ return 0; -+ arg->argv = tmp; -+ } -+ quoted = *p == '\'' || *p == '"'; -+ if (quoted) -+ c = *p++; -+ arg->argv[arg->argc++] = p; -+ -+ /* now look for the end of this */ -+ if (quoted) { -+ while (*p && *p != c) -+ p++; -+ *p++ = '\0'; -+ } else { -+ while (*p && !isspace(_UC(*p))) -+ p++; -+ if (*p) -+ *p++ = '\0'; -+ } -+ } -+ arg->argv[arg->argc] = NULL; -+ return (1); -+} -+ -+#ifndef APP_INIT -+int app_init(long mesgwin) -+{ -+ return (1); -+} -+#endif -+ -+int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile, -+ const char *CApath, int noCAfile, int noCApath) -+{ -+ if (CAfile == NULL && CApath == NULL) { -+ if (!noCAfile && SSL_CTX_set_default_verify_file(ctx) <= 0) -+ return 0; -+ if (!noCApath && SSL_CTX_set_default_verify_dir(ctx) <= 0) -+ return 0; -+ -+ return 1; -+ } -+ return SSL_CTX_load_verify_locations(ctx, CAfile, CApath); -+} -+ -+#ifndef OPENSSL_NO_CT -+ -+int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path) -+{ -+ if (path == NULL) { -+ return SSL_CTX_set_default_ctlog_list_file(ctx); -+ } -+ -+ return SSL_CTX_set_ctlog_list_file(ctx, path); -+} -+ -+#endif -+ -+int dump_cert_text(BIO *out, X509 *x) -+{ -+ char *p; -+ -+ p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0); -+ BIO_puts(out, "subject="); -+ BIO_puts(out, p); -+ OPENSSL_free(p); -+ -+ p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0); -+ BIO_puts(out, "\nissuer="); -+ BIO_puts(out, p); -+ BIO_puts(out, "\n"); -+ OPENSSL_free(p); -+ -+ return 0; -+} -+ -+#ifndef OPENSSL_NO_UI -+static int ui_open(UI *ui) -+{ -+ return UI_method_get_opener(UI_OpenSSL())(ui); -+} -+ -+static int ui_read(UI *ui, UI_STRING *uis) -+{ -+ if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD -+ && UI_get0_user_data(ui)) { -+ switch (UI_get_string_type(uis)) { -+ case UIT_PROMPT: -+ case UIT_VERIFY: -+ { -+ const char *password = -+ ((PW_CB_DATA *)UI_get0_user_data(ui))->password; -+ if (password && password[0] != '\0') { -+ UI_set_result(ui, uis, password); -+ return 1; -+ } -+ } -+ default: -+ break; -+ } -+ } -+ return UI_method_get_reader(UI_OpenSSL())(ui, uis); -+} -+ -+static int ui_write(UI *ui, UI_STRING *uis) -+{ -+ if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD -+ && UI_get0_user_data(ui)) { -+ switch (UI_get_string_type(uis)) { -+ case UIT_PROMPT: -+ case UIT_VERIFY: -+ { -+ const char *password = -+ ((PW_CB_DATA *)UI_get0_user_data(ui))->password; -+ if (password && password[0] != '\0') -+ return 1; -+ } -+ default: -+ break; -+ } -+ } -+ return UI_method_get_writer(UI_OpenSSL())(ui, uis); -+} -+ -+static int ui_close(UI *ui) -+{ -+ return UI_method_get_closer(UI_OpenSSL())(ui); -+} -+ -+int setup_ui_method(void) -+{ -+ ui_method = UI_create_method("OpenSSL application user interface"); -+ UI_method_set_opener(ui_method, ui_open); -+ UI_method_set_reader(ui_method, ui_read); -+ UI_method_set_writer(ui_method, ui_write); -+ UI_method_set_closer(ui_method, ui_close); -+ return 0; -+} -+ -+void destroy_ui_method(void) -+{ -+ if (ui_method) { -+ UI_destroy_method(ui_method); -+ ui_method = NULL; -+ } -+} -+#endif -+ -+int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp) -+{ -+ int res = 0; -+#ifndef OPENSSL_NO_UI -+ UI *ui = NULL; -+#endif -+ PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp; -+ -+#ifdef OPENSSL_NO_UI -+ if (cb_data != NULL && cb_data->password != NULL) { -+ res = strlen(cb_data->password); -+ if (res > bufsiz) -+ res = bufsiz; -+ memcpy(buf, cb_data->password, res); -+ } -+#else -+ ui = UI_new_method(ui_method); -+ if (ui) { -+ int ok = 0; -+ char *buff = NULL; -+ int ui_flags = 0; -+ const char *prompt_info = NULL; -+ char *prompt; -+ -+ if (cb_data != NULL && cb_data->prompt_info != NULL) -+ prompt_info = cb_data->prompt_info; -+ prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); -+ if (!prompt) { -+ BIO_printf(bio_err, "Out of memory\n"); -+ UI_free(ui); -+ return 0; -+ } -+ -+ ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD; -+ UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); -+ -+ /* We know that there is no previous user data to return to us */ -+ (void)UI_add_user_data(ui, cb_data); -+ -+ if (ok >= 0) -+ ok = UI_add_input_string(ui, prompt, ui_flags, buf, -+ PW_MIN_LENGTH, bufsiz - 1); -+ if (ok >= 0 && verify) { -+ buff = app_malloc(bufsiz, "password buffer"); -+ ok = UI_add_verify_string(ui, prompt, ui_flags, buff, -+ PW_MIN_LENGTH, bufsiz - 1, buf); -+ } -+ if (ok >= 0) -+ do { -+ ok = UI_process(ui); -+ } -+ while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); -+ -+ OPENSSL_clear_free(buff, (unsigned int)bufsiz); -+ -+ if (ok >= 0) -+ res = strlen(buf); -+ if (ok == -1) { -+ BIO_printf(bio_err, "User interface error\n"); -+ ERR_print_errors(bio_err); -+ OPENSSL_cleanse(buf, (unsigned int)bufsiz); -+ res = 0; -+ } -+ if (ok == -2) { -+ BIO_printf(bio_err, "aborted!\n"); -+ OPENSSL_cleanse(buf, (unsigned int)bufsiz); -+ res = 0; -+ } -+ UI_free(ui); -+ OPENSSL_free(prompt); -+ } -+#endif -+ return res; -+} -+ -+static char *app_get_pass(const char *arg, int keepbio); -+ -+int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2) -+{ -+ int same; -+ if (!arg2 || !arg1 || strcmp(arg1, arg2)) -+ same = 0; -+ else -+ same = 1; -+ if (arg1) { -+ *pass1 = app_get_pass(arg1, same); -+ if (!*pass1) -+ return 0; -+ } else if (pass1) -+ *pass1 = NULL; -+ if (arg2) { -+ *pass2 = app_get_pass(arg2, same ? 2 : 0); -+ if (!*pass2) -+ return 0; -+ } else if (pass2) -+ *pass2 = NULL; -+ return 1; -+} -+ -+static char *app_get_pass(const char *arg, int keepbio) -+{ -+ char *tmp, tpass[APP_PASS_LEN]; -+ static BIO *pwdbio = NULL; -+ int i; -+ -+ if (strncmp(arg, "pass:", 5) == 0) -+ return OPENSSL_strdup(arg + 5); -+ if (strncmp(arg, "env:", 4) == 0) { -+ tmp = getenv(arg + 4); -+ if (!tmp) { -+ BIO_printf(bio_err, "Can't read environment variable %s\n", arg + 4); -+ return NULL; -+ } -+ return OPENSSL_strdup(tmp); -+ } -+ if (!keepbio || !pwdbio) { -+ if (strncmp(arg, "file:", 5) == 0) { -+ pwdbio = BIO_new_file(arg + 5, "r"); -+ if (!pwdbio) { -+ BIO_printf(bio_err, "Can't open file %s\n", arg + 5); -+ return NULL; -+ } -+#if !defined(_WIN32) -+ /* -+ * Under _WIN32, which covers even Win64 and CE, file -+ * descriptors referenced by BIO_s_fd are not inherited -+ * by child process and therefore below is not an option. -+ * It could have been an option if bss_fd.c was operating -+ * on real Windows descriptors, such as those obtained -+ * with CreateFile. -+ */ -+ } else if (strncmp(arg, "fd:", 3) == 0) { -+ BIO *btmp; -+ i = atoi(arg + 3); -+ if (i >= 0) -+ pwdbio = BIO_new_fd(i, BIO_NOCLOSE); -+ if ((i < 0) || !pwdbio) { -+ BIO_printf(bio_err, "Can't access file descriptor %s\n", arg + 3); -+ return NULL; -+ } -+ /* -+ * Can't do BIO_gets on an fd BIO so add a buffering BIO -+ */ -+ btmp = BIO_new(BIO_f_buffer()); -+ pwdbio = BIO_push(btmp, pwdbio); -+#endif -+ } else if (strcmp(arg, "stdin") == 0) { -+ pwdbio = dup_bio_in(FORMAT_TEXT); -+ if (!pwdbio) { -+ BIO_printf(bio_err, "Can't open BIO for stdin\n"); -+ return NULL; -+ } -+ } else { -+ BIO_printf(bio_err, "Invalid password argument \"%s\"\n", arg); -+ return NULL; -+ } -+ } -+ i = BIO_gets(pwdbio, tpass, APP_PASS_LEN); -+ if (keepbio != 1) { -+ BIO_free_all(pwdbio); -+ pwdbio = NULL; -+ } -+ if (i <= 0) { -+ BIO_printf(bio_err, "Error reading password from BIO\n"); -+ return NULL; -+ } -+ tmp = strchr(tpass, '\n'); -+ if (tmp) -+ *tmp = 0; -+ return OPENSSL_strdup(tpass); -+} -+ -+static CONF *app_load_config_(BIO *in, const char *filename) -+{ -+ long errorline = -1; -+ CONF *conf; -+ int i; -+ -+ conf = NCONF_new(NULL); -+ i = NCONF_load_bio(conf, in, &errorline); -+ if (i > 0) -+ return conf; -+ -+ if (errorline <= 0) -+ BIO_printf(bio_err, "%s: Can't load config file \"%s\"\n", -+ opt_getprog(), filename); -+ else -+ BIO_printf(bio_err, "%s: Error on line %ld of config file \"%s\"\n", -+ opt_getprog(), errorline, filename); -+ NCONF_free(conf); -+ return NULL; -+} -+CONF *app_load_config(const char *filename) -+{ -+ BIO *in; -+ CONF *conf; -+ -+ in = bio_open_default(filename, 'r', FORMAT_TEXT); -+ if (in == NULL) -+ return NULL; -+ -+ conf = app_load_config_(in, filename); -+ BIO_free(in); -+ return conf; -+} -+CONF *app_load_config_quiet(const char *filename) -+{ -+ BIO *in; -+ CONF *conf; -+ -+ in = bio_open_default_quiet(filename, 'r', FORMAT_TEXT); -+ if (in == NULL) -+ return NULL; -+ -+ conf = app_load_config_(in, filename); -+ BIO_free(in); -+ return conf; -+} -+ -+int app_load_modules(const CONF *config) -+{ -+ CONF *to_free = NULL; -+ -+ if (config == NULL) -+ config = to_free = app_load_config_quiet(default_config_file); -+ if (config == NULL) -+ return 1; -+ -+ if (CONF_modules_load(config, NULL, 0) <= 0) { -+ BIO_printf(bio_err, "Error configuring OpenSSL modules\n"); -+ ERR_print_errors(bio_err); -+ NCONF_free(to_free); -+ return 0; -+ } -+ NCONF_free(to_free); -+ return 1; -+} -+ -+int add_oid_section(CONF *conf) -+{ -+ char *p; -+ STACK_OF(CONF_VALUE) *sktmp; -+ CONF_VALUE *cnf; -+ int i; -+ -+ if ((p = NCONF_get_string(conf, NULL, "oid_section")) == NULL) { -+ ERR_clear_error(); -+ return 1; -+ } -+ if ((sktmp = NCONF_get_section(conf, p)) == NULL) { -+ BIO_printf(bio_err, "problem loading oid section %s\n", p); -+ return 0; -+ } -+ for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { -+ cnf = sk_CONF_VALUE_value(sktmp, i); -+ if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) { -+ BIO_printf(bio_err, "problem creating object %s=%s\n", -+ cnf->name, cnf->value); -+ return 0; -+ } -+ } -+ return 1; -+} -+ -+static int load_pkcs12(BIO *in, const char *desc, -+ pem_password_cb *pem_cb, void *cb_data, -+ EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) -+{ -+ const char *pass; -+ char tpass[PEM_BUFSIZE]; -+ int len, ret = 0; -+ PKCS12 *p12; -+ p12 = d2i_PKCS12_bio(in, NULL); -+ if (p12 == NULL) { -+ BIO_printf(bio_err, "Error loading PKCS12 file for %s\n", desc); -+ goto die; -+ } -+ /* See if an empty password will do */ -+ if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) -+ pass = ""; -+ else { -+ if (!pem_cb) -+ pem_cb = (pem_password_cb *)password_callback; -+ len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data); -+ if (len < 0) { -+ BIO_printf(bio_err, "Passphrase callback error for %s\n", desc); -+ goto die; -+ } -+ if (len < PEM_BUFSIZE) -+ tpass[len] = 0; -+ if (!PKCS12_verify_mac(p12, tpass, len)) { -+ BIO_printf(bio_err, -+ "Mac verify error (wrong password?) in PKCS12 file for %s\n", -+ desc); -+ goto die; -+ } -+ pass = tpass; -+ } -+ ret = PKCS12_parse(p12, pass, pkey, cert, ca); -+ die: -+ PKCS12_free(p12); -+ return ret; -+} -+ -+#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK) -+static int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl) -+{ -+ char *host = NULL, *port = NULL, *path = NULL; -+ BIO *bio = NULL; -+ OCSP_REQ_CTX *rctx = NULL; -+ int use_ssl, rv = 0; -+ if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl)) -+ goto err; -+ if (use_ssl) { -+ BIO_puts(bio_err, "https not supported\n"); -+ goto err; -+ } -+ bio = BIO_new_connect(host); -+ if (!bio || !BIO_set_conn_port(bio, port)) -+ goto err; -+ rctx = OCSP_REQ_CTX_new(bio, 1024); -+ if (rctx == NULL) -+ goto err; -+ if (!OCSP_REQ_CTX_http(rctx, "GET", path)) -+ goto err; -+ if (!OCSP_REQ_CTX_add1_header(rctx, "Host", host)) -+ goto err; -+ if (pcert) { -+ do { -+ rv = X509_http_nbio(rctx, pcert); -+ } while (rv == -1); -+ } else { -+ do { -+ rv = X509_CRL_http_nbio(rctx, pcrl); -+ } while (rv == -1); -+ } -+ -+ err: -+ OPENSSL_free(host); -+ OPENSSL_free(path); -+ OPENSSL_free(port); -+ if (bio) -+ BIO_free_all(bio); -+ OCSP_REQ_CTX_free(rctx); -+ if (rv != 1) { -+ BIO_printf(bio_err, "Error loading %s from %s\n", -+ pcert ? "certificate" : "CRL", url); -+ ERR_print_errors(bio_err); -+ } -+ return rv; -+} -+#endif -+ -+X509 *load_cert(const char *file, int format, const char *cert_descrip) -+{ -+ X509 *x = NULL; -+ BIO *cert; -+ -+ if (format == FORMAT_HTTP) { -+#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK) -+ load_cert_crl_http(file, &x, NULL); -+#endif -+ return x; -+ } -+ -+ if (file == NULL) { -+ unbuffer(stdin); -+ cert = dup_bio_in(format); -+ } else -+ cert = bio_open_default(file, 'r', format); -+ if (cert == NULL) -+ goto end; -+ -+ if (format == FORMAT_ASN1) -+ x = d2i_X509_bio(cert, NULL); -+ else if (format == FORMAT_PEM) -+ x = PEM_read_bio_X509_AUX(cert, NULL, -+ (pem_password_cb *)password_callback, NULL); -+ else if (format == FORMAT_PKCS12) { -+ if (!load_pkcs12(cert, cert_descrip, NULL, NULL, NULL, &x, NULL)) -+ goto end; -+ } else { -+ BIO_printf(bio_err, "bad input format specified for %s\n", cert_descrip); -+ goto end; -+ } -+ end: -+ if (x == NULL) { -+ BIO_printf(bio_err, "unable to load certificate\n"); -+ ERR_print_errors(bio_err); -+ } -+ BIO_free(cert); -+ return (x); -+} -+ -+X509_CRL *load_crl(const char *infile, int format) -+{ -+ X509_CRL *x = NULL; -+ BIO *in = NULL; -+ -+ if (format == FORMAT_HTTP) { -+#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK) -+ load_cert_crl_http(infile, NULL, &x); -+#endif -+ return x; -+ } -+ -+ in = bio_open_default(infile, 'r', format); -+ if (in == NULL) -+ goto end; -+ if (format == FORMAT_ASN1) -+ x = d2i_X509_CRL_bio(in, NULL); -+ else if (format == FORMAT_PEM) -+ x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); -+ else { -+ BIO_printf(bio_err, "bad input format specified for input crl\n"); -+ goto end; -+ } -+ if (x == NULL) { -+ BIO_printf(bio_err, "unable to load CRL\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ end: -+ BIO_free(in); -+ return (x); -+} -+ -+EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, -+ const char *pass, ENGINE *e, const char *key_descrip) -+{ -+ BIO *key = NULL; -+ EVP_PKEY *pkey = NULL; -+ PW_CB_DATA cb_data; -+ -+ cb_data.password = pass; -+ cb_data.prompt_info = file; -+ -+ if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) { -+ BIO_printf(bio_err, "no keyfile specified\n"); -+ goto end; -+ } -+ if (format == FORMAT_ENGINE) { -+ if (e == NULL) -+ BIO_printf(bio_err, "no engine specified\n"); -+ else { -+#ifndef OPENSSL_NO_ENGINE -+ if (ENGINE_init(e)) { -+ pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data); -+ ENGINE_finish(e); -+ } -+ if (pkey == NULL) { -+ BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip); -+ ERR_print_errors(bio_err); -+ } -+#else -+ BIO_printf(bio_err, "engines not supported\n"); -+#endif -+ } -+ goto end; -+ } -+ if (file == NULL && maybe_stdin) { -+ unbuffer(stdin); -+ key = dup_bio_in(format); -+ } else -+ key = bio_open_default(file, 'r', format); -+ if (key == NULL) -+ goto end; -+ if (format == FORMAT_ASN1) { -+ pkey = d2i_PrivateKey_bio(key, NULL); -+ } else if (format == FORMAT_PEM) { -+ pkey = PEM_read_bio_PrivateKey(key, NULL, -+ (pem_password_cb *)password_callback, -+ &cb_data); -+ } -+ else if (format == FORMAT_PKCS12) { -+ if (!load_pkcs12(key, key_descrip, -+ (pem_password_cb *)password_callback, &cb_data, -+ &pkey, NULL, NULL)) -+ goto end; -+ } -+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4) -+ else if (format == FORMAT_MSBLOB) -+ pkey = b2i_PrivateKey_bio(key); -+ else if (format == FORMAT_PVK) -+ pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback, -+ &cb_data); -+#endif -+ else { -+ BIO_printf(bio_err, "bad input format specified for key file\n"); -+ goto end; -+ } -+ end: -+ BIO_free(key); -+ if (pkey == NULL) { -+ BIO_printf(bio_err, "unable to load %s\n", key_descrip); -+ ERR_print_errors(bio_err); -+ } -+ return (pkey); -+} -+ -+EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, -+ const char *pass, ENGINE *e, const char *key_descrip) -+{ -+ BIO *key = NULL; -+ EVP_PKEY *pkey = NULL; -+ PW_CB_DATA cb_data; -+ -+ cb_data.password = pass; -+ cb_data.prompt_info = file; -+ -+ if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) { -+ BIO_printf(bio_err, "no keyfile specified\n"); -+ goto end; -+ } -+ if (format == FORMAT_ENGINE) { -+ if (e == NULL) -+ BIO_printf(bio_err, "no engine specified\n"); -+ else { -+#ifndef OPENSSL_NO_ENGINE -+ pkey = ENGINE_load_public_key(e, file, ui_method, &cb_data); -+ if (pkey == NULL) { -+ BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip); -+ ERR_print_errors(bio_err); -+ } -+#else -+ BIO_printf(bio_err, "engines not supported\n"); -+#endif -+ } -+ goto end; -+ } -+ if (file == NULL && maybe_stdin) { -+ unbuffer(stdin); -+ key = dup_bio_in(format); -+ } else -+ key = bio_open_default(file, 'r', format); -+ if (key == NULL) -+ goto end; -+ if (format == FORMAT_ASN1) { -+ pkey = d2i_PUBKEY_bio(key, NULL); -+ } -+ else if (format == FORMAT_ASN1RSA) { -+#ifndef OPENSSL_NO_RSA -+ RSA *rsa; -+ rsa = d2i_RSAPublicKey_bio(key, NULL); -+ if (rsa) { -+ pkey = EVP_PKEY_new(); -+ if (pkey != NULL) -+ EVP_PKEY_set1_RSA(pkey, rsa); -+ RSA_free(rsa); -+ } else -+#else -+ BIO_printf(bio_err, "RSA keys not supported\n"); -+#endif -+ pkey = NULL; -+ } else if (format == FORMAT_PEMRSA) { -+#ifndef OPENSSL_NO_RSA -+ RSA *rsa; -+ rsa = PEM_read_bio_RSAPublicKey(key, NULL, -+ (pem_password_cb *)password_callback, -+ &cb_data); -+ if (rsa != NULL) { -+ pkey = EVP_PKEY_new(); -+ if (pkey != NULL) -+ EVP_PKEY_set1_RSA(pkey, rsa); -+ RSA_free(rsa); -+ } else -+#else -+ BIO_printf(bio_err, "RSA keys not supported\n"); -+#endif -+ pkey = NULL; -+ } -+ else if (format == FORMAT_PEM) { -+ pkey = PEM_read_bio_PUBKEY(key, NULL, -+ (pem_password_cb *)password_callback, -+ &cb_data); -+ } -+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) -+ else if (format == FORMAT_MSBLOB) -+ pkey = b2i_PublicKey_bio(key); -+#endif -+ end: -+ BIO_free(key); -+ if (pkey == NULL) -+ BIO_printf(bio_err, "unable to load %s\n", key_descrip); -+ return (pkey); -+} -+ -+static int load_certs_crls(const char *file, int format, -+ const char *pass, const char *desc, -+ STACK_OF(X509) **pcerts, -+ STACK_OF(X509_CRL) **pcrls) -+{ -+ int i; -+ BIO *bio; -+ STACK_OF(X509_INFO) *xis = NULL; -+ X509_INFO *xi; -+ PW_CB_DATA cb_data; -+ int rv = 0; -+ -+ cb_data.password = pass; -+ cb_data.prompt_info = file; -+ -+ if (format != FORMAT_PEM) { -+ BIO_printf(bio_err, "bad input format specified for %s\n", desc); -+ return 0; -+ } -+ -+ bio = bio_open_default(file, 'r', FORMAT_PEM); -+ if (bio == NULL) -+ return 0; -+ -+ xis = PEM_X509_INFO_read_bio(bio, NULL, -+ (pem_password_cb *)password_callback, -+ &cb_data); -+ -+ BIO_free(bio); -+ -+ if (pcerts && *pcerts == NULL) { -+ *pcerts = sk_X509_new_null(); -+ if (!*pcerts) -+ goto end; -+ } -+ -+ if (pcrls && *pcrls == NULL) { -+ *pcrls = sk_X509_CRL_new_null(); -+ if (!*pcrls) -+ goto end; -+ } -+ -+ for (i = 0; i < sk_X509_INFO_num(xis); i++) { -+ xi = sk_X509_INFO_value(xis, i); -+ if (xi->x509 && pcerts) { -+ if (!sk_X509_push(*pcerts, xi->x509)) -+ goto end; -+ xi->x509 = NULL; -+ } -+ if (xi->crl && pcrls) { -+ if (!sk_X509_CRL_push(*pcrls, xi->crl)) -+ goto end; -+ xi->crl = NULL; -+ } -+ } -+ -+ if (pcerts && sk_X509_num(*pcerts) > 0) -+ rv = 1; -+ -+ if (pcrls && sk_X509_CRL_num(*pcrls) > 0) -+ rv = 1; -+ -+ end: -+ -+ sk_X509_INFO_pop_free(xis, X509_INFO_free); -+ -+ if (rv == 0) { -+ if (pcerts) { -+ sk_X509_pop_free(*pcerts, X509_free); -+ *pcerts = NULL; -+ } -+ if (pcrls) { -+ sk_X509_CRL_pop_free(*pcrls, X509_CRL_free); -+ *pcrls = NULL; -+ } -+ BIO_printf(bio_err, "unable to load %s\n", -+ pcerts ? "certificates" : "CRLs"); -+ ERR_print_errors(bio_err); -+ } -+ return rv; -+} -+ -+void* app_malloc(int sz, const char *what) -+{ -+ void *vp = OPENSSL_malloc(sz); -+ -+ if (vp == NULL) { -+ BIO_printf(bio_err, "%s: Could not allocate %d bytes for %s\n", -+ opt_getprog(), sz, what); -+ ERR_print_errors(bio_err); -+ exit(1); -+ } -+ return vp; -+} -+ -+/* -+ * Initialize or extend, if *certs != NULL, a certificate stack. -+ */ -+int load_certs(const char *file, STACK_OF(X509) **certs, int format, -+ const char *pass, const char *desc) -+{ -+ return load_certs_crls(file, format, pass, desc, certs, NULL); -+} -+ -+/* -+ * Initialize or extend, if *crls != NULL, a certificate stack. -+ */ -+int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format, -+ const char *pass, const char *desc) -+{ -+ return load_certs_crls(file, format, pass, desc, NULL, crls); -+} -+ -+#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) -+/* Return error for unknown extensions */ -+#define X509V3_EXT_DEFAULT 0 -+/* Print error for unknown extensions */ -+#define X509V3_EXT_ERROR_UNKNOWN (1L << 16) -+/* ASN1 parse unknown extensions */ -+#define X509V3_EXT_PARSE_UNKNOWN (2L << 16) -+/* BIO_dump unknown extensions */ -+#define X509V3_EXT_DUMP_UNKNOWN (3L << 16) -+ -+#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \ -+ X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION) -+ -+int set_cert_ex(unsigned long *flags, const char *arg) -+{ -+ static const NAME_EX_TBL cert_tbl[] = { -+ {"compatible", X509_FLAG_COMPAT, 0xffffffffl}, -+ {"ca_default", X509_FLAG_CA, 0xffffffffl}, -+ {"no_header", X509_FLAG_NO_HEADER, 0}, -+ {"no_version", X509_FLAG_NO_VERSION, 0}, -+ {"no_serial", X509_FLAG_NO_SERIAL, 0}, -+ {"no_signame", X509_FLAG_NO_SIGNAME, 0}, -+ {"no_validity", X509_FLAG_NO_VALIDITY, 0}, -+ {"no_subject", X509_FLAG_NO_SUBJECT, 0}, -+ {"no_issuer", X509_FLAG_NO_ISSUER, 0}, -+ {"no_pubkey", X509_FLAG_NO_PUBKEY, 0}, -+ {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0}, -+ {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0}, -+ {"no_aux", X509_FLAG_NO_AUX, 0}, -+ {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0}, -+ {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK}, -+ {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, -+ {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, -+ {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK}, -+ {NULL, 0, 0} -+ }; -+ return set_multi_opts(flags, arg, cert_tbl); -+} -+ -+int set_name_ex(unsigned long *flags, const char *arg) -+{ -+ static const NAME_EX_TBL ex_tbl[] = { -+ {"esc_2253", ASN1_STRFLGS_ESC_2253, 0}, -+ {"esc_2254", ASN1_STRFLGS_ESC_2254, 0}, -+ {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0}, -+ {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0}, -+ {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0}, -+ {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0}, -+ {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0}, -+ {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0}, -+ {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0}, -+ {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0}, -+ {"dump_der", ASN1_STRFLGS_DUMP_DER, 0}, -+ {"compat", XN_FLAG_COMPAT, 0xffffffffL}, -+ {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK}, -+ {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK}, -+ {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK}, -+ {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK}, -+ {"dn_rev", XN_FLAG_DN_REV, 0}, -+ {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK}, -+ {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK}, -+ {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK}, -+ {"align", XN_FLAG_FN_ALIGN, 0}, -+ {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK}, -+ {"space_eq", XN_FLAG_SPC_EQ, 0}, -+ {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0}, -+ {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL}, -+ {"oneline", XN_FLAG_ONELINE, 0xffffffffL}, -+ {"multiline", XN_FLAG_MULTILINE, 0xffffffffL}, -+ {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL}, -+ {NULL, 0, 0} -+ }; -+ if (set_multi_opts(flags, arg, ex_tbl) == 0) -+ return 0; -+ if ((*flags & XN_FLAG_SEP_MASK) == 0) -+ *flags |= XN_FLAG_SEP_CPLUS_SPC; -+ return 1; -+} -+ -+int set_ext_copy(int *copy_type, const char *arg) -+{ -+ if (strcasecmp(arg, "none") == 0) -+ *copy_type = EXT_COPY_NONE; -+ else if (strcasecmp(arg, "copy") == 0) -+ *copy_type = EXT_COPY_ADD; -+ else if (strcasecmp(arg, "copyall") == 0) -+ *copy_type = EXT_COPY_ALL; -+ else -+ return 0; -+ return 1; -+} -+ -+int copy_extensions(X509 *x, X509_REQ *req, int copy_type) -+{ -+ STACK_OF(X509_EXTENSION) *exts = NULL; -+ X509_EXTENSION *ext, *tmpext; -+ ASN1_OBJECT *obj; -+ int i, idx, ret = 0; -+ if (!x || !req || (copy_type == EXT_COPY_NONE)) -+ return 1; -+ exts = X509_REQ_get_extensions(req); -+ -+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { -+ ext = sk_X509_EXTENSION_value(exts, i); -+ obj = X509_EXTENSION_get_object(ext); -+ idx = X509_get_ext_by_OBJ(x, obj, -1); -+ /* Does extension exist? */ -+ if (idx != -1) { -+ /* If normal copy don't override existing extension */ -+ if (copy_type == EXT_COPY_ADD) -+ continue; -+ /* Delete all extensions of same type */ -+ do { -+ tmpext = X509_get_ext(x, idx); -+ X509_delete_ext(x, idx); -+ X509_EXTENSION_free(tmpext); -+ idx = X509_get_ext_by_OBJ(x, obj, -1); -+ } while (idx != -1); -+ } -+ if (!X509_add_ext(x, ext, -1)) -+ goto end; -+ } -+ -+ ret = 1; -+ -+ end: -+ -+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); -+ -+ return ret; -+} -+ -+static int set_multi_opts(unsigned long *flags, const char *arg, -+ const NAME_EX_TBL * in_tbl) -+{ -+ STACK_OF(CONF_VALUE) *vals; -+ CONF_VALUE *val; -+ int i, ret = 1; -+ if (!arg) -+ return 0; -+ vals = X509V3_parse_list(arg); -+ for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { -+ val = sk_CONF_VALUE_value(vals, i); -+ if (!set_table_opts(flags, val->name, in_tbl)) -+ ret = 0; -+ } -+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); -+ return ret; -+} -+ -+static int set_table_opts(unsigned long *flags, const char *arg, -+ const NAME_EX_TBL * in_tbl) -+{ -+ char c; -+ const NAME_EX_TBL *ptbl; -+ c = arg[0]; -+ -+ if (c == '-') { -+ c = 0; -+ arg++; -+ } else if (c == '+') { -+ c = 1; -+ arg++; -+ } else -+ c = 1; -+ -+ for (ptbl = in_tbl; ptbl->name; ptbl++) { -+ if (strcasecmp(arg, ptbl->name) == 0) { -+ *flags &= ~ptbl->mask; -+ if (c) -+ *flags |= ptbl->flag; -+ else -+ *flags &= ~ptbl->flag; -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+void print_name(BIO *out, const char *title, X509_NAME *nm, -+ unsigned long lflags) -+{ -+ char *buf; -+ char mline = 0; -+ int indent = 0; -+ -+ if (title) -+ BIO_puts(out, title); -+ if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { -+ mline = 1; -+ indent = 4; -+ } -+ if (lflags == XN_FLAG_COMPAT) { -+ buf = X509_NAME_oneline(nm, 0, 0); -+ BIO_puts(out, buf); -+ BIO_puts(out, "\n"); -+ OPENSSL_free(buf); -+ } else { -+ if (mline) -+ BIO_puts(out, "\n"); -+ X509_NAME_print_ex(out, nm, indent, lflags); -+ BIO_puts(out, "\n"); -+ } -+} -+ -+void print_bignum_var(BIO *out, const BIGNUM *in, const char *var, -+ int len, unsigned char *buffer) -+{ -+ BIO_printf(out, " static unsigned char %s_%d[] = {", var, len); -+ if (BN_is_zero(in)) -+ BIO_printf(out, "\n\t0x00"); -+ else { -+ int i, l; -+ -+ l = BN_bn2bin(in, buffer); -+ for (i = 0; i < l; i++) { -+ if ((i % 10) == 0) -+ BIO_printf(out, "\n\t"); -+ if (i < l - 1) -+ BIO_printf(out, "0x%02X, ", buffer[i]); -+ else -+ BIO_printf(out, "0x%02X", buffer[i]); -+ } -+ } -+ BIO_printf(out, "\n };\n"); -+} -+void print_array(BIO *out, const char* title, int len, const unsigned char* d) -+{ -+ int i; -+ -+ BIO_printf(out, "unsigned char %s[%d] = {", title, len); -+ for (i = 0; i < len; i++) { -+ if ((i % 10) == 0) -+ BIO_printf(out, "\n "); -+ if (i < len - 1) -+ BIO_printf(out, "0x%02X, ", d[i]); -+ else -+ BIO_printf(out, "0x%02X", d[i]); -+ } -+ BIO_printf(out, "\n};\n"); -+} -+ -+X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, int noCApath) -+{ -+ X509_STORE *store = X509_STORE_new(); -+ X509_LOOKUP *lookup; -+ -+ if (store == NULL) -+ goto end; -+ -+ if (CAfile != NULL || !noCAfile) { -+ lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); -+ if (lookup == NULL) -+ goto end; -+ if (CAfile) { -+ if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) { -+ BIO_printf(bio_err, "Error loading file %s\n", CAfile); -+ goto end; -+ } -+ } else -+ X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); -+ } -+ -+ if (CApath != NULL || !noCApath) { -+ lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); -+ if (lookup == NULL) -+ goto end; -+ if (CApath) { -+ if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) { -+ BIO_printf(bio_err, "Error loading directory %s\n", CApath); -+ goto end; -+ } -+ } else -+ X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); -+ } -+ -+ ERR_clear_error(); -+ return store; -+ end: -+ X509_STORE_free(store); -+ return NULL; -+} -+ -+#ifndef OPENSSL_NO_ENGINE -+/* Try to load an engine in a shareable library */ -+static ENGINE *try_load_engine(const char *engine) -+{ -+ ENGINE *e = ENGINE_by_id("dynamic"); -+ if (e) { -+ if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) -+ || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) { -+ ENGINE_free(e); -+ e = NULL; -+ } -+ } -+ return e; -+} -+#endif -+ -+ENGINE *setup_engine(const char *engine, int debug) -+{ -+ ENGINE *e = NULL; -+ -+#ifndef OPENSSL_NO_ENGINE -+ if (engine) { -+ if (strcmp(engine, "auto") == 0) { -+ BIO_printf(bio_err, "enabling auto ENGINE support\n"); -+ ENGINE_register_all_complete(); -+ return NULL; -+ } -+ if ((e = ENGINE_by_id(engine)) == NULL -+ && (e = try_load_engine(engine)) == NULL) { -+ BIO_printf(bio_err, "invalid engine \"%s\"\n", engine); -+ ERR_print_errors(bio_err); -+ return NULL; -+ } -+ if (debug) { -+ ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0); -+ } -+ ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1); -+ if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { -+ BIO_printf(bio_err, "can't use that engine\n"); -+ ERR_print_errors(bio_err); -+ ENGINE_free(e); -+ return NULL; -+ } -+ -+ BIO_printf(bio_err, "engine \"%s\" set.\n", ENGINE_get_id(e)); -+ } -+#endif -+ return e; -+} -+ -+void release_engine(ENGINE *e) -+{ -+#ifndef OPENSSL_NO_ENGINE -+ if (e != NULL) -+ /* Free our "structural" reference. */ -+ ENGINE_free(e); -+#endif -+} -+ -+static unsigned long index_serial_hash(const OPENSSL_CSTRING *a) -+{ -+ const char *n; -+ -+ n = a[DB_serial]; -+ while (*n == '0') -+ n++; -+ return OPENSSL_LH_strhash(n); -+} -+ -+static int index_serial_cmp(const OPENSSL_CSTRING *a, -+ const OPENSSL_CSTRING *b) -+{ -+ const char *aa, *bb; -+ -+ for (aa = a[DB_serial]; *aa == '0'; aa++) ; -+ for (bb = b[DB_serial]; *bb == '0'; bb++) ; -+ return (strcmp(aa, bb)); -+} -+ -+static int index_name_qual(char **a) -+{ -+ return (a[0][0] == 'V'); -+} -+ -+static unsigned long index_name_hash(const OPENSSL_CSTRING *a) -+{ -+ return OPENSSL_LH_strhash(a[DB_name]); -+} -+ -+int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b) -+{ -+ return (strcmp(a[DB_name], b[DB_name])); -+} -+ -+static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING) -+static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING) -+static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING) -+static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING) -+#undef BSIZE -+#define BSIZE 256 -+BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai) -+{ -+ BIO *in = NULL; -+ BIGNUM *ret = NULL; -+ char buf[1024]; -+ ASN1_INTEGER *ai = NULL; -+ -+ ai = ASN1_INTEGER_new(); -+ if (ai == NULL) -+ goto err; -+ -+ in = BIO_new_file(serialfile, "r"); -+ if (in == NULL) { -+ if (!create) { -+ perror(serialfile); -+ goto err; -+ } -+ ERR_clear_error(); -+ ret = BN_new(); -+ if (ret == NULL || !rand_serial(ret, ai)) -+ BIO_printf(bio_err, "Out of memory\n"); -+ } else { -+ if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) { -+ BIO_printf(bio_err, "unable to load number from %s\n", -+ serialfile); -+ goto err; -+ } -+ ret = ASN1_INTEGER_to_BN(ai, NULL); -+ if (ret == NULL) { -+ BIO_printf(bio_err, -+ "error converting number from bin to BIGNUM\n"); -+ goto err; -+ } -+ } -+ -+ if (ret && retai) { -+ *retai = ai; -+ ai = NULL; -+ } -+ err: -+ BIO_free(in); -+ ASN1_INTEGER_free(ai); -+ return (ret); -+} -+ -+int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial, -+ ASN1_INTEGER **retai) -+{ -+ char buf[1][BSIZE]; -+ BIO *out = NULL; -+ int ret = 0; -+ ASN1_INTEGER *ai = NULL; -+ int j; -+ -+ if (suffix == NULL) -+ j = strlen(serialfile); -+ else -+ j = strlen(serialfile) + strlen(suffix) + 1; -+ if (j >= BSIZE) { -+ BIO_printf(bio_err, "file name too long\n"); -+ goto err; -+ } -+ -+ if (suffix == NULL) -+ OPENSSL_strlcpy(buf[0], serialfile, BSIZE); -+ else { -+#ifndef OPENSSL_SYS_VMS -+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix); -+#else -+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix); -+#endif -+ } -+ out = BIO_new_file(buf[0], "w"); -+ if (out == NULL) { -+ ERR_print_errors(bio_err); -+ goto err; -+ } -+ -+ if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) { -+ BIO_printf(bio_err, "error converting serial to ASN.1 format\n"); -+ goto err; -+ } -+ i2a_ASN1_INTEGER(out, ai); -+ BIO_puts(out, "\n"); -+ ret = 1; -+ if (retai) { -+ *retai = ai; -+ ai = NULL; -+ } -+ err: -+ BIO_free_all(out); -+ ASN1_INTEGER_free(ai); -+ return (ret); -+} -+ -+int rotate_serial(const char *serialfile, const char *new_suffix, -+ const char *old_suffix) -+{ -+ char buf[2][BSIZE]; -+ int i, j; -+ -+ i = strlen(serialfile) + strlen(old_suffix); -+ j = strlen(serialfile) + strlen(new_suffix); -+ if (i > j) -+ j = i; -+ if (j + 1 >= BSIZE) { -+ BIO_printf(bio_err, "file name too long\n"); -+ goto err; -+ } -+#ifndef OPENSSL_SYS_VMS -+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, new_suffix); -+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", serialfile, old_suffix); -+#else -+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, new_suffix); -+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", serialfile, old_suffix); -+#endif -+ if (rename(serialfile, buf[1]) < 0 && errno != ENOENT -+#ifdef ENOTDIR -+ && errno != ENOTDIR -+#endif -+ ) { -+ BIO_printf(bio_err, -+ "unable to rename %s to %s\n", serialfile, buf[1]); -+ perror("reason"); -+ goto err; -+ } -+ if (rename(buf[0], serialfile) < 0) { -+ BIO_printf(bio_err, -+ "unable to rename %s to %s\n", buf[0], serialfile); -+ perror("reason"); -+ rename(buf[1], serialfile); -+ goto err; -+ } -+ return 1; -+ err: -+ return 0; -+} -+ -+int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) -+{ -+ BIGNUM *btmp; -+ int ret = 0; -+ -+ if (b) -+ btmp = b; -+ else -+ btmp = BN_new(); -+ -+ if (btmp == NULL) -+ return 0; -+ -+ if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) -+ goto error; -+ if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) -+ goto error; -+ -+ ret = 1; -+ -+ error: -+ -+ if (btmp != b) -+ BN_free(btmp); -+ -+ return ret; -+} -+ -+CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr) -+{ -+ CA_DB *retdb = NULL; -+ TXT_DB *tmpdb = NULL; -+ BIO *in; -+ CONF *dbattr_conf = NULL; -+ char buf[BSIZE]; -+ -+ in = BIO_new_file(dbfile, "r"); -+ if (in == NULL) { -+ ERR_print_errors(bio_err); -+ goto err; -+ } -+ if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) -+ goto err; -+ -+#ifndef OPENSSL_SYS_VMS -+ BIO_snprintf(buf, sizeof buf, "%s.attr", dbfile); -+#else -+ BIO_snprintf(buf, sizeof buf, "%s-attr", dbfile); -+#endif -+ dbattr_conf = app_load_config(buf); -+ -+ retdb = app_malloc(sizeof(*retdb), "new DB"); -+ retdb->db = tmpdb; -+ tmpdb = NULL; -+ if (db_attr) -+ retdb->attributes = *db_attr; -+ else { -+ retdb->attributes.unique_subject = 1; -+ } -+ -+ if (dbattr_conf) { -+ char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject"); -+ if (p) { -+ retdb->attributes.unique_subject = parse_yesno(p, 1); -+ } -+ } -+ -+ err: -+ NCONF_free(dbattr_conf); -+ TXT_DB_free(tmpdb); -+ BIO_free_all(in); -+ return retdb; -+} -+ -+int index_index(CA_DB *db) -+{ -+ if (!TXT_DB_create_index(db->db, DB_serial, NULL, -+ LHASH_HASH_FN(index_serial), -+ LHASH_COMP_FN(index_serial))) { -+ BIO_printf(bio_err, -+ "error creating serial number index:(%ld,%ld,%ld)\n", -+ db->db->error, db->db->arg1, db->db->arg2); -+ return 0; -+ } -+ -+ if (db->attributes.unique_subject -+ && !TXT_DB_create_index(db->db, DB_name, index_name_qual, -+ LHASH_HASH_FN(index_name), -+ LHASH_COMP_FN(index_name))) { -+ BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n", -+ db->db->error, db->db->arg1, db->db->arg2); -+ return 0; -+ } -+ return 1; -+} -+ -+int save_index(const char *dbfile, const char *suffix, CA_DB *db) -+{ -+ char buf[3][BSIZE]; -+ BIO *out; -+ int j; -+ -+ j = strlen(dbfile) + strlen(suffix); -+ if (j + 6 >= BSIZE) { -+ BIO_printf(bio_err, "file name too long\n"); -+ goto err; -+ } -+#ifndef OPENSSL_SYS_VMS -+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile); -+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix); -+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix); -+#else -+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile); -+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix); -+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix); -+#endif -+ out = BIO_new_file(buf[0], "w"); -+ if (out == NULL) { -+ perror(dbfile); -+ BIO_printf(bio_err, "unable to open '%s'\n", dbfile); -+ goto err; -+ } -+ j = TXT_DB_write(out, db->db); -+ BIO_free(out); -+ if (j <= 0) -+ goto err; -+ -+ out = BIO_new_file(buf[1], "w"); -+ if (out == NULL) { -+ perror(buf[2]); -+ BIO_printf(bio_err, "unable to open '%s'\n", buf[2]); -+ goto err; -+ } -+ BIO_printf(out, "unique_subject = %s\n", -+ db->attributes.unique_subject ? "yes" : "no"); -+ BIO_free(out); -+ -+ return 1; -+ err: -+ return 0; -+} -+ -+int rotate_index(const char *dbfile, const char *new_suffix, -+ const char *old_suffix) -+{ -+ char buf[5][BSIZE]; -+ int i, j; -+ -+ i = strlen(dbfile) + strlen(old_suffix); -+ j = strlen(dbfile) + strlen(new_suffix); -+ if (i > j) -+ j = i; -+ if (j + 6 >= BSIZE) { -+ BIO_printf(bio_err, "file name too long\n"); -+ goto err; -+ } -+#ifndef OPENSSL_SYS_VMS -+ j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile); -+ j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", dbfile, old_suffix); -+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", dbfile, new_suffix); -+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", dbfile, old_suffix); -+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, new_suffix); -+#else -+ j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile); -+ j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", dbfile, old_suffix); -+ j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", dbfile, new_suffix); -+ j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", dbfile, old_suffix); -+ j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, new_suffix); -+#endif -+ if (rename(dbfile, buf[1]) < 0 && errno != ENOENT -+#ifdef ENOTDIR -+ && errno != ENOTDIR -+#endif -+ ) { -+ BIO_printf(bio_err, "unable to rename %s to %s\n", dbfile, buf[1]); -+ perror("reason"); -+ goto err; -+ } -+ if (rename(buf[0], dbfile) < 0) { -+ BIO_printf(bio_err, "unable to rename %s to %s\n", buf[0], dbfile); -+ perror("reason"); -+ rename(buf[1], dbfile); -+ goto err; -+ } -+ if (rename(buf[4], buf[3]) < 0 && errno != ENOENT -+#ifdef ENOTDIR -+ && errno != ENOTDIR -+#endif -+ ) { -+ BIO_printf(bio_err, "unable to rename %s to %s\n", buf[4], buf[3]); -+ perror("reason"); -+ rename(dbfile, buf[0]); -+ rename(buf[1], dbfile); -+ goto err; -+ } -+ if (rename(buf[2], buf[4]) < 0) { -+ BIO_printf(bio_err, "unable to rename %s to %s\n", buf[2], buf[4]); -+ perror("reason"); -+ rename(buf[3], buf[4]); -+ rename(dbfile, buf[0]); -+ rename(buf[1], dbfile); -+ goto err; -+ } -+ return 1; -+ err: -+ return 0; -+} -+ -+void free_index(CA_DB *db) -+{ -+ if (db) { -+ TXT_DB_free(db->db); -+ OPENSSL_free(db); -+ } -+} -+ -+int parse_yesno(const char *str, int def) -+{ -+ if (str) { -+ switch (*str) { -+ case 'f': /* false */ -+ case 'F': /* FALSE */ -+ case 'n': /* no */ -+ case 'N': /* NO */ -+ case '0': /* 0 */ -+ return 0; -+ case 't': /* true */ -+ case 'T': /* TRUE */ -+ case 'y': /* yes */ -+ case 'Y': /* YES */ -+ case '1': /* 1 */ -+ return 1; -+ } -+ } -+ return def; -+} -+ -+/* -+ * name is expected to be in the format /type0=value0/type1=value1/type2=... -+ * where characters may be escaped by \ -+ */ -+X509_NAME *parse_name(const char *cp, long chtype, int canmulti) -+{ -+ int nextismulti = 0; -+ char *work; -+ X509_NAME *n; -+ -+ if (*cp++ != '/') -+ return NULL; -+ -+ n = X509_NAME_new(); -+ if (n == NULL) -+ return NULL; -+ work = OPENSSL_strdup(cp); -+ if (work == NULL) -+ goto err; -+ -+ while (*cp) { -+ char *bp = work; -+ char *typestr = bp; -+ unsigned char *valstr; -+ int nid; -+ int ismulti = nextismulti; -+ nextismulti = 0; -+ -+ /* Collect the type */ -+ while (*cp && *cp != '=') -+ *bp++ = *cp++; -+ if (*cp == '\0') { -+ BIO_printf(bio_err, -+ "%s: Hit end of string before finding the equals.\n", -+ opt_getprog()); -+ goto err; -+ } -+ *bp++ = '\0'; -+ ++cp; -+ -+ /* Collect the value. */ -+ valstr = (unsigned char *)bp; -+ for (; *cp && *cp != '/'; *bp++ = *cp++) { -+ if (canmulti && *cp == '+') { -+ nextismulti = 1; -+ break; -+ } -+ if (*cp == '\\' && *++cp == '\0') { -+ BIO_printf(bio_err, -+ "%s: escape character at end of string\n", -+ opt_getprog()); -+ goto err; -+ } -+ } -+ *bp++ = '\0'; -+ -+ /* If not at EOS (must be + or /), move forward. */ -+ if (*cp) -+ ++cp; -+ -+ /* Parse */ -+ nid = OBJ_txt2nid(typestr); -+ if (nid == NID_undef) { -+ BIO_printf(bio_err, "%s: Skipping unknown attribute \"%s\"\n", -+ opt_getprog(), typestr); -+ continue; -+ } -+ if (!X509_NAME_add_entry_by_NID(n, nid, chtype, -+ valstr, strlen((char *)valstr), -+ -1, ismulti ? -1 : 0)) -+ goto err; -+ } -+ -+ OPENSSL_free(work); -+ return n; -+ -+ err: -+ X509_NAME_free(n); -+ OPENSSL_free(work); -+ return NULL; -+} -+ -+/* -+ * Read whole contents of a BIO into an allocated memory buffer and return -+ * it. -+ */ -+ -+int bio_to_mem(unsigned char **out, int maxlen, BIO *in) -+{ -+ BIO *mem; -+ int len, ret; -+ unsigned char tbuf[1024]; -+ -+ mem = BIO_new(BIO_s_mem()); -+ if (mem == NULL) -+ return -1; -+ for (;;) { -+ if ((maxlen != -1) && maxlen < 1024) -+ len = maxlen; -+ else -+ len = 1024; -+ len = BIO_read(in, tbuf, len); -+ if (len < 0) { -+ BIO_free(mem); -+ return -1; -+ } -+ if (len == 0) -+ break; -+ if (BIO_write(mem, tbuf, len) != len) { -+ BIO_free(mem); -+ return -1; -+ } -+ maxlen -= len; -+ -+ if (maxlen == 0) -+ break; -+ } -+ ret = BIO_get_mem_data(mem, (char **)out); -+ BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY); -+ BIO_free(mem); -+ return ret; -+} -+ -+int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value) -+{ -+ int rv; -+ char *stmp, *vtmp = NULL; -+ stmp = OPENSSL_strdup(value); -+ if (!stmp) -+ return -1; -+ vtmp = strchr(stmp, ':'); -+ if (vtmp) { -+ *vtmp = 0; -+ vtmp++; -+ } -+ rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp); -+ OPENSSL_free(stmp); -+ return rv; -+} -+ -+static void nodes_print(const char *name, STACK_OF(X509_POLICY_NODE) *nodes) -+{ -+ X509_POLICY_NODE *node; -+ int i; -+ -+ BIO_printf(bio_err, "%s Policies:", name); -+ if (nodes) { -+ BIO_puts(bio_err, "\n"); -+ for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) { -+ node = sk_X509_POLICY_NODE_value(nodes, i); -+ X509_POLICY_NODE_print(bio_err, node, 2); -+ } -+ } else -+ BIO_puts(bio_err, " \n"); -+} -+ -+void policies_print(X509_STORE_CTX *ctx) -+{ -+ X509_POLICY_TREE *tree; -+ int explicit_policy; -+ tree = X509_STORE_CTX_get0_policy_tree(ctx); -+ explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx); -+ -+ BIO_printf(bio_err, "Require explicit Policy: %s\n", -+ explicit_policy ? "True" : "False"); -+ -+ nodes_print("Authority", X509_policy_tree_get0_policies(tree)); -+ nodes_print("User", X509_policy_tree_get0_user_policies(tree)); -+} -+ -+/*- -+ * next_protos_parse parses a comma separated list of strings into a string -+ * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. -+ * outlen: (output) set to the length of the resulting buffer on success. -+ * err: (maybe NULL) on failure, an error message line is written to this BIO. -+ * in: a NUL terminated string like "abc,def,ghi" -+ * -+ * returns: a malloc'd buffer or NULL on failure. -+ */ -+unsigned char *next_protos_parse(size_t *outlen, const char *in) -+{ -+ size_t len; -+ unsigned char *out; -+ size_t i, start = 0; -+ -+ len = strlen(in); -+ if (len >= 65535) -+ return NULL; -+ -+ out = app_malloc(strlen(in) + 1, "NPN buffer"); -+ for (i = 0; i <= len; ++i) { -+ if (i == len || in[i] == ',') { -+ if (i - start > 255) { -+ OPENSSL_free(out); -+ return NULL; -+ } -+ out[start] = i - start; -+ start = i + 1; -+ } else -+ out[i + 1] = in[i]; -+ } -+ -+ *outlen = len + 1; -+ return out; -+} -+ -+void print_cert_checks(BIO *bio, X509 *x, -+ const char *checkhost, -+ const char *checkemail, const char *checkip) -+{ -+ if (x == NULL) -+ return; -+ if (checkhost) { -+ BIO_printf(bio, "Hostname %s does%s match certificate\n", -+ checkhost, -+ X509_check_host(x, checkhost, 0, 0, NULL) == 1 -+ ? "" : " NOT"); -+ } -+ -+ if (checkemail) { -+ BIO_printf(bio, "Email %s does%s match certificate\n", -+ checkemail, X509_check_email(x, checkemail, 0, 0) -+ ? "" : " NOT"); -+ } -+ -+ if (checkip) { -+ BIO_printf(bio, "IP %s does%s match certificate\n", -+ checkip, X509_check_ip_asc(x, checkip, 0) ? "" : " NOT"); -+ } -+} -+ -+/* Get first http URL from a DIST_POINT structure */ -+ -+static const char *get_dp_url(DIST_POINT *dp) -+{ -+ GENERAL_NAMES *gens; -+ GENERAL_NAME *gen; -+ int i, gtype; -+ ASN1_STRING *uri; -+ if (!dp->distpoint || dp->distpoint->type != 0) -+ return NULL; -+ gens = dp->distpoint->name.fullname; -+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { -+ gen = sk_GENERAL_NAME_value(gens, i); -+ uri = GENERAL_NAME_get0_value(gen, >ype); -+ if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) { -+ const char *uptr = (const char *)ASN1_STRING_get0_data(uri); -+ if (strncmp(uptr, "http://", 7) == 0) -+ return uptr; -+ } -+ } -+ return NULL; -+} -+ -+/* -+ * Look through a CRLDP structure and attempt to find an http URL to -+ * downloads a CRL from. -+ */ -+ -+static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp) -+{ -+ int i; -+ const char *urlptr = NULL; -+ for (i = 0; i < sk_DIST_POINT_num(crldp); i++) { -+ DIST_POINT *dp = sk_DIST_POINT_value(crldp, i); -+ urlptr = get_dp_url(dp); -+ if (urlptr) -+ return load_crl(urlptr, FORMAT_HTTP); -+ } -+ return NULL; -+} -+ -+/* -+ * Example of downloading CRLs from CRLDP: not usable for real world as it -+ * always downloads, doesn't support non-blocking I/O and doesn't cache -+ * anything. -+ */ -+ -+static STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm) -+{ -+ X509 *x; -+ STACK_OF(X509_CRL) *crls = NULL; -+ X509_CRL *crl; -+ STACK_OF(DIST_POINT) *crldp; -+ -+ crls = sk_X509_CRL_new_null(); -+ if (!crls) -+ return NULL; -+ x = X509_STORE_CTX_get_current_cert(ctx); -+ crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); -+ crl = load_crl_crldp(crldp); -+ sk_DIST_POINT_pop_free(crldp, DIST_POINT_free); -+ if (!crl) { -+ sk_X509_CRL_free(crls); -+ return NULL; -+ } -+ sk_X509_CRL_push(crls, crl); -+ /* Try to download delta CRL */ -+ crldp = X509_get_ext_d2i(x, NID_freshest_crl, NULL, NULL); -+ crl = load_crl_crldp(crldp); -+ sk_DIST_POINT_pop_free(crldp, DIST_POINT_free); -+ if (crl) -+ sk_X509_CRL_push(crls, crl); -+ return crls; -+} -+ -+void store_setup_crl_download(X509_STORE *st) -+{ -+ X509_STORE_set_lookup_crls_cb(st, crls_http_cb); -+} -+ -+/* -+ * Platform-specific sections -+ */ -+#if defined(_WIN32) -+# ifdef fileno -+# undef fileno -+# define fileno(a) (int)_fileno(a) -+# endif -+ -+# include -+# include -+ -+static int WIN32_rename(const char *from, const char *to) -+{ -+ TCHAR *tfrom = NULL, *tto; -+ DWORD err; -+ int ret = 0; -+ -+ if (sizeof(TCHAR) == 1) { -+ tfrom = (TCHAR *)from; -+ tto = (TCHAR *)to; -+ } else { /* UNICODE path */ -+ -+ size_t i, flen = strlen(from) + 1, tlen = strlen(to) + 1; -+ tfrom = malloc(sizeof(*tfrom) * (flen + tlen)); -+ if (tfrom == NULL) -+ goto err; -+ tto = tfrom + flen; -+# if !defined(_WIN32_WCE) || _WIN32_WCE>=101 -+ if (!MultiByteToWideChar(CP_ACP, 0, from, flen, (WCHAR *)tfrom, flen)) -+# endif -+ for (i = 0; i < flen; i++) -+ tfrom[i] = (TCHAR)from[i]; -+# if !defined(_WIN32_WCE) || _WIN32_WCE>=101 -+ if (!MultiByteToWideChar(CP_ACP, 0, to, tlen, (WCHAR *)tto, tlen)) -+# endif -+ for (i = 0; i < tlen; i++) -+ tto[i] = (TCHAR)to[i]; -+ } -+ -+ if (MoveFile(tfrom, tto)) -+ goto ok; -+ err = GetLastError(); -+ if (err == ERROR_ALREADY_EXISTS || err == ERROR_FILE_EXISTS) { -+ if (DeleteFile(tto) && MoveFile(tfrom, tto)) -+ goto ok; -+ err = GetLastError(); -+ } -+ if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) -+ errno = ENOENT; -+ else if (err == ERROR_ACCESS_DENIED) -+ errno = EACCES; -+ else -+ errno = EINVAL; /* we could map more codes... */ -+ err: -+ ret = -1; -+ ok: -+ if (tfrom != NULL && tfrom != (TCHAR *)from) -+ free(tfrom); -+ return ret; -+} -+#endif -+ -+/* app_tminterval section */ -+#if defined(_WIN32) -+double app_tminterval(int stop, int usertime) -+{ -+ FILETIME now; -+ double ret = 0; -+ static ULARGE_INTEGER tmstart; -+ static int warning = 1; -+# ifdef _WIN32_WINNT -+ static HANDLE proc = NULL; -+ -+ if (proc == NULL) { -+ if (check_winnt()) -+ proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, -+ GetCurrentProcessId()); -+ if (proc == NULL) -+ proc = (HANDLE) - 1; -+ } -+ -+ if (usertime && proc != (HANDLE) - 1) { -+ FILETIME junk; -+ GetProcessTimes(proc, &junk, &junk, &junk, &now); -+ } else -+# endif -+ { -+ SYSTEMTIME systime; -+ -+ if (usertime && warning) { -+ BIO_printf(bio_err, "To get meaningful results, run " -+ "this program on idle system.\n"); -+ warning = 0; -+ } -+ GetSystemTime(&systime); -+ SystemTimeToFileTime(&systime, &now); -+ } -+ -+ if (stop == TM_START) { -+ tmstart.u.LowPart = now.dwLowDateTime; -+ tmstart.u.HighPart = now.dwHighDateTime; -+ } else { -+ ULARGE_INTEGER tmstop; -+ -+ tmstop.u.LowPart = now.dwLowDateTime; -+ tmstop.u.HighPart = now.dwHighDateTime; -+ -+ ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7; -+ } -+ -+ return (ret); -+} -+#elif defined(OPENSSL_SYSTEM_VXWORKS) -+# include -+ -+double app_tminterval(int stop, int usertime) -+{ -+ double ret = 0; -+# ifdef CLOCK_REALTIME -+ static struct timespec tmstart; -+ struct timespec now; -+# else -+ static unsigned long tmstart; -+ unsigned long now; -+# endif -+ static int warning = 1; -+ -+ if (usertime && warning) { -+ BIO_printf(bio_err, "To get meaningful results, run " -+ "this program on idle system.\n"); -+ warning = 0; -+ } -+# ifdef CLOCK_REALTIME -+ clock_gettime(CLOCK_REALTIME, &now); -+ if (stop == TM_START) -+ tmstart = now; -+ else -+ ret = ((now.tv_sec + now.tv_nsec * 1e-9) -+ - (tmstart.tv_sec + tmstart.tv_nsec * 1e-9)); -+# else -+ now = tickGet(); -+ if (stop == TM_START) -+ tmstart = now; -+ else -+ ret = (now - tmstart) / (double)sysClkRateGet(); -+# endif -+ return (ret); -+} -+ -+#elif defined(OPENSSL_SYSTEM_VMS) -+# include -+# include -+ -+double app_tminterval(int stop, int usertime) -+{ -+ static clock_t tmstart; -+ double ret = 0; -+ clock_t now; -+# ifdef __TMS -+ struct tms rus; -+ -+ now = times(&rus); -+ if (usertime) -+ now = rus.tms_utime; -+# else -+ if (usertime) -+ now = clock(); /* sum of user and kernel times */ -+ else { -+ struct timeval tv; -+ gettimeofday(&tv, NULL); -+ now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK + -+ (unsigned long long)tv.tv_usec * (1000000 / CLK_TCK) -+ ); -+ } -+# endif -+ if (stop == TM_START) -+ tmstart = now; -+ else -+ ret = (now - tmstart) / (double)(CLK_TCK); -+ -+ return (ret); -+} -+ -+#elif defined(_SC_CLK_TCK) /* by means of unistd.h */ -+# include -+ -+double app_tminterval(int stop, int usertime) -+{ -+ double ret = 0; -+ struct tms rus; -+ clock_t now = times(&rus); -+ static clock_t tmstart; -+ -+ if (usertime) -+ now = rus.tms_utime; -+ -+ if (stop == TM_START) -+ tmstart = now; -+ else { -+ long int tck = sysconf(_SC_CLK_TCK); -+ ret = (now - tmstart) / (double)tck; -+ } -+ -+ return (ret); -+} -+ -+#else -+# include -+# include -+ -+double app_tminterval(int stop, int usertime) -+{ -+ double ret = 0; -+ struct rusage rus; -+ struct timeval now; -+ static struct timeval tmstart; -+ -+ if (usertime) -+ getrusage(RUSAGE_SELF, &rus), now = rus.ru_utime; -+ else -+ gettimeofday(&now, NULL); -+ -+ if (stop == TM_START) -+ tmstart = now; -+ else -+ ret = ((now.tv_sec + now.tv_usec * 1e-6) -+ - (tmstart.tv_sec + tmstart.tv_usec * 1e-6)); -+ -+ return ret; -+} -+#endif -+ -+int app_access(const char* name, int flag) -+{ -+#ifdef _WIN32 -+ return _access(name, flag); -+#else -+ return access(name, flag); -+#endif -+} -+ -+/* app_isdir section */ -+#ifdef _WIN32 -+int app_isdir(const char *name) -+{ -+ HANDLE hList; -+ WIN32_FIND_DATA FileData; -+# if defined(UNICODE) || defined(_UNICODE) -+ size_t i, len_0 = strlen(name) + 1; -+ -+ if (len_0 > OSSL_NELEM(FileData.cFileName)) -+ return -1; -+ -+# if !defined(_WIN32_WCE) || _WIN32_WCE>=101 -+ if (!MultiByteToWideChar -+ (CP_ACP, 0, name, len_0, FileData.cFileName, len_0)) -+# endif -+ for (i = 0; i < len_0; i++) -+ FileData.cFileName[i] = (WCHAR)name[i]; -+ -+ hList = FindFirstFile(FileData.cFileName, &FileData); -+# else -+ hList = FindFirstFile(name, &FileData); -+# endif -+ if (hList == INVALID_HANDLE_VALUE) -+ return -1; -+ FindClose(hList); -+ return ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); -+} -+#else -+# include -+# ifndef S_ISDIR -+# if defined(_S_IFMT) && defined(_S_IFDIR) -+# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR) -+# else -+# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) -+# endif -+# endif -+ -+int app_isdir(const char *name) -+{ -+# if defined(S_ISDIR) -+ struct stat st; -+ -+ if (stat(name, &st) == 0) -+ return S_ISDIR(st.st_mode); -+ else -+ return -1; -+# else -+ return -1; -+# endif -+} -+#endif -+ -+/* raw_read|write section */ -+#if defined(__VMS) -+# include "vms_term_sock.h" -+static int stdin_sock = -1; -+ -+static void close_stdin_sock(void) -+{ -+ TerminalSocket (TERM_SOCK_DELETE, &stdin_sock); -+} -+ -+int fileno_stdin(void) -+{ -+ if (stdin_sock == -1) { -+ TerminalSocket(TERM_SOCK_CREATE, &stdin_sock); -+ atexit(close_stdin_sock); -+ } -+ -+ return stdin_sock; -+} -+#else -+int fileno_stdin(void) -+{ -+ return fileno(stdin); -+} -+#endif -+ -+int fileno_stdout(void) -+{ -+ return fileno(stdout); -+} -+ -+#if defined(_WIN32) && defined(STD_INPUT_HANDLE) -+int raw_read_stdin(void *buf, int siz) -+{ -+ DWORD n; -+ if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL)) -+ return (n); -+ else -+ return (-1); -+} -+#elif defined(__VMS) -+#include -+ -+int raw_read_stdin(void *buf, int siz) -+{ -+ return recv(fileno_stdin(), buf, siz, 0); -+} -+#else -+int raw_read_stdin(void *buf, int siz) -+{ -+ return read(fileno_stdin(), buf, siz); -+} -+#endif -+ -+#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE) -+int raw_write_stdout(const void *buf, int siz) -+{ -+ DWORD n; -+ if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL)) -+ return (n); -+ else -+ return (-1); -+} -+#else -+int raw_write_stdout(const void *buf, int siz) -+{ -+ return write(fileno_stdout(), buf, siz); -+} -+#endif -+ -+/* -+ * Centralized handling if input and output files with format specification -+ * The format is meant to show what the input and output is supposed to be, -+ * and is therefore a show of intent more than anything else. However, it -+ * does impact behavior on some platform, such as differentiating between -+ * text and binary input/output on non-Unix platforms -+ */ -+static int istext(int format) -+{ -+ return (format & B_FORMAT_TEXT) == B_FORMAT_TEXT; -+} -+ -+BIO *dup_bio_in(int format) -+{ -+ return BIO_new_fp(stdin, -+ BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); -+} -+ -+BIO *dup_bio_out(int format) -+{ -+ BIO *b = BIO_new_fp(stdout, -+ BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); -+#ifdef OPENSSL_SYS_VMS -+ if (istext(format)) -+ b = BIO_push(BIO_new(BIO_f_linebuffer()), b); -+#endif -+ return b; -+} -+ -+BIO *dup_bio_err(int format) -+{ -+ BIO *b = BIO_new_fp(stderr, -+ BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0)); -+#ifdef OPENSSL_SYS_VMS -+ if (istext(format)) -+ b = BIO_push(BIO_new(BIO_f_linebuffer()), b); -+#endif -+ return b; -+} -+ -+void unbuffer(FILE *fp) -+{ -+/* -+ * On VMS, setbuf() will only take 32-bit pointers, and a compilation -+ * with /POINTER_SIZE=64 will give off a MAYLOSEDATA2 warning here. -+ * However, we trust that the C RTL will never give us a FILE pointer -+ * above the first 4 GB of memory, so we simply turn off the warning -+ * temporarily. -+ */ -+#if defined(OPENSSL_SYS_VMS) && defined(__DECC) -+# pragma environment save -+# pragma message disable maylosedata2 -+#endif -+ setbuf(fp, NULL); -+#if defined(OPENSSL_SYS_VMS) && defined(__DECC) -+# pragma environment restore -+#endif -+} -+ -+static const char *modestr(char mode, int format) -+{ -+ OPENSSL_assert(mode == 'a' || mode == 'r' || mode == 'w'); -+ -+ switch (mode) { -+ case 'a': -+ return istext(format) ? "a" : "ab"; -+ case 'r': -+ return istext(format) ? "r" : "rb"; -+ case 'w': -+ return istext(format) ? "w" : "wb"; -+ } -+ /* The assert above should make sure we never reach this point */ -+ return NULL; -+} -+ -+static const char *modeverb(char mode) -+{ -+ switch (mode) { -+ case 'a': -+ return "appending"; -+ case 'r': -+ return "reading"; -+ case 'w': -+ return "writing"; -+ } -+ return "(doing something)"; -+} -+ -+/* -+ * Open a file for writing, owner-read-only. -+ */ -+BIO *bio_open_owner(const char *filename, int format, int private) -+{ -+ FILE *fp = NULL; -+ BIO *b = NULL; -+ int fd = -1, bflags, mode, textmode; -+ -+ if (!private || filename == NULL || strcmp(filename, "-") == 0) -+ return bio_open_default(filename, 'w', format); -+ -+ mode = O_WRONLY; -+#ifdef O_CREAT -+ mode |= O_CREAT; -+#endif -+#ifdef O_TRUNC -+ mode |= O_TRUNC; -+#endif -+ textmode = istext(format); -+ if (!textmode) { -+#ifdef O_BINARY -+ mode |= O_BINARY; -+#elif defined(_O_BINARY) -+ mode |= _O_BINARY; -+#endif -+ } -+ -+#ifdef OPENSSL_SYS_VMS -+ /* VMS doesn't have O_BINARY, it just doesn't make sense. But, -+ * it still needs to know that we're going binary, or fdopen() -+ * will fail with "invalid argument"... so we tell VMS what the -+ * context is. -+ */ -+ if (!textmode) -+ fd = open(filename, mode, 0600, "ctx=bin"); -+ else -+#endif -+ fd = open(filename, mode, 0600); -+ if (fd < 0) -+ goto err; -+ fp = fdopen(fd, modestr('w', format)); -+ if (fp == NULL) -+ goto err; -+ bflags = BIO_CLOSE; -+ if (textmode) -+ bflags |= BIO_FP_TEXT; -+ b = BIO_new_fp(fp, bflags); -+ if (b) -+ return b; -+ -+ err: -+ BIO_printf(bio_err, "%s: Can't open \"%s\" for writing, %s\n", -+ opt_getprog(), filename, strerror(errno)); -+ ERR_print_errors(bio_err); -+ /* If we have fp, then fdopen took over fd, so don't close both. */ -+ if (fp) -+ fclose(fp); -+ else if (fd >= 0) -+ close(fd); -+ return NULL; -+} -+ -+static BIO *bio_open_default_(const char *filename, char mode, int format, -+ int quiet) -+{ -+ BIO *ret; -+ -+ if (filename == NULL || strcmp(filename, "-") == 0) { -+ ret = mode == 'r' ? dup_bio_in(format) : dup_bio_out(format); -+ if (quiet) { -+ ERR_clear_error(); -+ return ret; -+ } -+ if (ret != NULL) -+ return ret; -+ BIO_printf(bio_err, -+ "Can't open %s, %s\n", -+ mode == 'r' ? "stdin" : "stdout", strerror(errno)); -+ } else { -+ ret = BIO_new_file(filename, modestr(mode, format)); -+ if (quiet) { -+ ERR_clear_error(); -+ return ret; -+ } -+ if (ret != NULL) -+ return ret; -+ BIO_printf(bio_err, -+ "Can't open %s for %s, %s\n", -+ filename, modeverb(mode), strerror(errno)); -+ } -+ ERR_print_errors(bio_err); -+ return NULL; -+} -+ -+BIO *bio_open_default(const char *filename, char mode, int format) -+{ -+ return bio_open_default_(filename, mode, format, 0); -+} -+ -+BIO *bio_open_default_quiet(const char *filename, char mode, int format) -+{ -+ return bio_open_default_(filename, mode, format, 1); -+} -+ -+void wait_for_async(SSL *s) -+{ -+ /* On Windows select only works for sockets, so we simply don't wait */ -+#ifndef OPENSSL_SYS_WINDOWS -+ int width = 0; -+ fd_set asyncfds; -+ OSSL_ASYNC_FD *fds; -+ size_t numfds; -+ -+ if (!SSL_get_all_async_fds(s, NULL, &numfds)) -+ return; -+ if (numfds == 0) -+ return; -+ fds = app_malloc(sizeof(OSSL_ASYNC_FD) * numfds, "allocate async fds"); -+ if (!SSL_get_all_async_fds(s, fds, &numfds)) { -+ OPENSSL_free(fds); -+ } -+ -+ FD_ZERO(&asyncfds); -+ while (numfds > 0) { -+ if (width <= (int)*fds) -+ width = (int)*fds + 1; -+ openssl_fdset((int)*fds, &asyncfds); -+ numfds--; -+ fds++; -+ } -+ select(width, (void *)&asyncfds, NULL, NULL, NULL); -+#endif -+} -+ -+/* if OPENSSL_SYS_WINDOWS is defined then so is OPENSSL_SYS_MSDOS */ -+#if defined(OPENSSL_SYS_MSDOS) -+int has_stdin_waiting(void) -+{ -+# if defined(OPENSSL_SYS_WINDOWS) -+ HANDLE inhand = GetStdHandle(STD_INPUT_HANDLE); -+ DWORD events = 0; -+ INPUT_RECORD inputrec; -+ DWORD insize = 1; -+ BOOL peeked; -+ -+ if (inhand == INVALID_HANDLE_VALUE) { -+ return 0; -+ } -+ -+ peeked = PeekConsoleInput(inhand, &inputrec, insize, &events); -+ if (!peeked) { -+ /* Probably redirected input? _kbhit() does not work in this case */ -+ if (!feof(stdin)) { -+ return 1; -+ } -+ return 0; -+ } -+# endif -+ return _kbhit(); -+} -+#endif -+ -+/* Corrupt a signature by modifying final byte */ -+void corrupt_signature(const ASN1_STRING *signature) -+{ -+ unsigned char *s = signature->data; -+ s[signature->length - 1] ^= 0x1; -+} -+ -+int set_cert_times(X509 *x, const char *startdate, const char *enddate, -+ int days) -+{ -+ if (startdate == NULL || strcmp(startdate, "today") == 0) { -+ if (X509_gmtime_adj(X509_getm_notBefore(x), 0) == NULL) -+ return 0; -+ } else { -+ if (!ASN1_TIME_set_string(X509_getm_notBefore(x), startdate)) -+ return 0; -+ } -+ if (enddate == NULL) { -+ if (X509_time_adj_ex(X509_getm_notAfter(x), days, 0, NULL) -+ == NULL) -+ return 0; -+ } else if (!ASN1_TIME_set_string(X509_getm_notAfter(x), enddate)) { -+ return 0; -+ } -+ return 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/apps.h b/CryptoPkg/Library/OpensslLib/openssl/apps/apps.h -new file mode 100644 -index 0000000..926a6d6 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/apps.h -@@ -0,0 +1,569 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#ifndef HEADER_APPS_H -+# define HEADER_APPS_H -+ -+# include "e_os.h" -+# if defined(__unix) || defined(__unix__) -+# include /* struct timeval for DTLS */ -+# endif -+# include -+ -+# include -+# include -+# include -+# include -+# include -+# include -+# include -+# include -+# include -+# include -+ -+# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINCE) -+# define openssl_fdset(a,b) FD_SET((unsigned int)a, b) -+# else -+# define openssl_fdset(a,b) FD_SET(a, b) -+# endif -+ -+/* -+ * quick macro when you need to pass an unsigned char instead of a char. -+ * this is true for some implementations of the is*() functions, for -+ * example. -+ */ -+#define _UC(c) ((unsigned char)(c)) -+ -+int app_RAND_load_file(const char *file, int dont_warn); -+int app_RAND_write_file(const char *file); -+/* -+ * When `file' is NULL, use defaults. `bio_e' is for error messages. -+ */ -+void app_RAND_allow_write_file(void); -+long app_RAND_load_files(char *file); /* `file' is a list of files to read, -+ * separated by LIST_SEPARATOR_CHAR -+ * (see e_os.h). The string is -+ * destroyed! */ -+ -+extern char *default_config_file; -+extern BIO *bio_in; -+extern BIO *bio_out; -+extern BIO *bio_err; -+BIO *dup_bio_in(int format); -+BIO *dup_bio_out(int format); -+BIO *dup_bio_err(int format); -+BIO *bio_open_owner(const char *filename, int format, int private); -+BIO *bio_open_default(const char *filename, char mode, int format); -+BIO *bio_open_default_quiet(const char *filename, char mode, int format); -+CONF *app_load_config(const char *filename); -+CONF *app_load_config_quiet(const char *filename); -+int app_load_modules(const CONF *config); -+void unbuffer(FILE *fp); -+void wait_for_async(SSL *s); -+# if defined(OPENSSL_SYS_MSDOS) -+int has_stdin_waiting(void); -+# endif -+ -+void corrupt_signature(const ASN1_STRING *signature); -+int set_cert_times(X509 *x, const char *startdate, const char *enddate, -+ int days); -+ -+/* -+ * Common verification options. -+ */ -+# define OPT_V_ENUM \ -+ OPT_V__FIRST=2000, \ -+ OPT_V_POLICY, OPT_V_PURPOSE, OPT_V_VERIFY_NAME, OPT_V_VERIFY_DEPTH, \ -+ OPT_V_ATTIME, OPT_V_VERIFY_HOSTNAME, OPT_V_VERIFY_EMAIL, \ -+ OPT_V_VERIFY_IP, OPT_V_IGNORE_CRITICAL, OPT_V_ISSUER_CHECKS, \ -+ OPT_V_CRL_CHECK, OPT_V_CRL_CHECK_ALL, OPT_V_POLICY_CHECK, \ -+ OPT_V_EXPLICIT_POLICY, OPT_V_INHIBIT_ANY, OPT_V_INHIBIT_MAP, \ -+ OPT_V_X509_STRICT, OPT_V_EXTENDED_CRL, OPT_V_USE_DELTAS, \ -+ OPT_V_POLICY_PRINT, OPT_V_CHECK_SS_SIG, OPT_V_TRUSTED_FIRST, \ -+ OPT_V_SUITEB_128_ONLY, OPT_V_SUITEB_128, OPT_V_SUITEB_192, \ -+ OPT_V_PARTIAL_CHAIN, OPT_V_NO_ALT_CHAINS, OPT_V_NO_CHECK_TIME, \ -+ OPT_V_VERIFY_AUTH_LEVEL, OPT_V_ALLOW_PROXY_CERTS, \ -+ OPT_V__LAST -+ -+# define OPT_V_OPTIONS \ -+ { "policy", OPT_V_POLICY, 's', "adds policy to the acceptable policy set"}, \ -+ { "purpose", OPT_V_PURPOSE, 's', \ -+ "certificate chain purpose"}, \ -+ { "verify_name", OPT_V_VERIFY_NAME, 's', "verification policy name"}, \ -+ { "verify_depth", OPT_V_VERIFY_DEPTH, 'n', \ -+ "chain depth limit" }, \ -+ { "auth_level", OPT_V_VERIFY_AUTH_LEVEL, 'n', \ -+ "chain authentication security level" }, \ -+ { "attime", OPT_V_ATTIME, 'M', "verification epoch time" }, \ -+ { "verify_hostname", OPT_V_VERIFY_HOSTNAME, 's', \ -+ "expected peer hostname" }, \ -+ { "verify_email", OPT_V_VERIFY_EMAIL, 's', \ -+ "expected peer email" }, \ -+ { "verify_ip", OPT_V_VERIFY_IP, 's', \ -+ "expected peer IP address" }, \ -+ { "ignore_critical", OPT_V_IGNORE_CRITICAL, '-', \ -+ "permit unhandled critical extensions"}, \ -+ { "issuer_checks", OPT_V_ISSUER_CHECKS, '-', "(deprecated)"}, \ -+ { "crl_check", OPT_V_CRL_CHECK, '-', "check leaf certificate revocation" }, \ -+ { "crl_check_all", OPT_V_CRL_CHECK_ALL, '-', "check full chain revocation" }, \ -+ { "policy_check", OPT_V_POLICY_CHECK, '-', "perform rfc5280 policy checks"}, \ -+ { "explicit_policy", OPT_V_EXPLICIT_POLICY, '-', \ -+ "set policy variable require-explicit-policy"}, \ -+ { "inhibit_any", OPT_V_INHIBIT_ANY, '-', \ -+ "set policy variable inhibit-any-policy"}, \ -+ { "inhibit_map", OPT_V_INHIBIT_MAP, '-', \ -+ "set policy variable inhibit-policy-mapping"}, \ -+ { "x509_strict", OPT_V_X509_STRICT, '-', \ -+ "disable certificate compatibility work-arounds"}, \ -+ { "extended_crl", OPT_V_EXTENDED_CRL, '-', \ -+ "enable extended CRL features"}, \ -+ { "use_deltas", OPT_V_USE_DELTAS, '-', \ -+ "use delta CRLs"}, \ -+ { "policy_print", OPT_V_POLICY_PRINT, '-', \ -+ "print policy processing diagnostics"}, \ -+ { "check_ss_sig", OPT_V_CHECK_SS_SIG, '-', \ -+ "check root CA self-signatures"}, \ -+ { "trusted_first", OPT_V_TRUSTED_FIRST, '-', \ -+ "search trust store first (default)" }, \ -+ { "suiteB_128_only", OPT_V_SUITEB_128_ONLY, '-', "Suite B 128-bit-only mode"}, \ -+ { "suiteB_128", OPT_V_SUITEB_128, '-', \ -+ "Suite B 128-bit mode allowing 192-bit algorithms"}, \ -+ { "suiteB_192", OPT_V_SUITEB_192, '-', "Suite B 192-bit-only mode" }, \ -+ { "partial_chain", OPT_V_PARTIAL_CHAIN, '-', \ -+ "accept chains anchored by intermediate trust-store CAs"}, \ -+ { "no_alt_chains", OPT_V_NO_ALT_CHAINS, '-', "(deprecated)" }, \ -+ { "no_check_time", OPT_V_NO_CHECK_TIME, '-', "ignore certificate validity time" }, \ -+ { "allow_proxy_certs", OPT_V_ALLOW_PROXY_CERTS, '-', "allow the use of proxy certificates" } -+ -+# define OPT_V_CASES \ -+ OPT_V__FIRST: case OPT_V__LAST: break; \ -+ case OPT_V_POLICY: \ -+ case OPT_V_PURPOSE: \ -+ case OPT_V_VERIFY_NAME: \ -+ case OPT_V_VERIFY_DEPTH: \ -+ case OPT_V_VERIFY_AUTH_LEVEL: \ -+ case OPT_V_ATTIME: \ -+ case OPT_V_VERIFY_HOSTNAME: \ -+ case OPT_V_VERIFY_EMAIL: \ -+ case OPT_V_VERIFY_IP: \ -+ case OPT_V_IGNORE_CRITICAL: \ -+ case OPT_V_ISSUER_CHECKS: \ -+ case OPT_V_CRL_CHECK: \ -+ case OPT_V_CRL_CHECK_ALL: \ -+ case OPT_V_POLICY_CHECK: \ -+ case OPT_V_EXPLICIT_POLICY: \ -+ case OPT_V_INHIBIT_ANY: \ -+ case OPT_V_INHIBIT_MAP: \ -+ case OPT_V_X509_STRICT: \ -+ case OPT_V_EXTENDED_CRL: \ -+ case OPT_V_USE_DELTAS: \ -+ case OPT_V_POLICY_PRINT: \ -+ case OPT_V_CHECK_SS_SIG: \ -+ case OPT_V_TRUSTED_FIRST: \ -+ case OPT_V_SUITEB_128_ONLY: \ -+ case OPT_V_SUITEB_128: \ -+ case OPT_V_SUITEB_192: \ -+ case OPT_V_PARTIAL_CHAIN: \ -+ case OPT_V_NO_ALT_CHAINS: \ -+ case OPT_V_NO_CHECK_TIME: \ -+ case OPT_V_ALLOW_PROXY_CERTS -+ -+/* -+ * Common "extended"? options. -+ */ -+# define OPT_X_ENUM \ -+ OPT_X__FIRST=1000, \ -+ OPT_X_KEY, OPT_X_CERT, OPT_X_CHAIN, OPT_X_CHAIN_BUILD, \ -+ OPT_X_CERTFORM, OPT_X_KEYFORM, \ -+ OPT_X__LAST -+ -+# define OPT_X_OPTIONS \ -+ { "xkey", OPT_X_KEY, '<', "key for Extended certificates"}, \ -+ { "xcert", OPT_X_CERT, '<', "cert for Extended certificates"}, \ -+ { "xchain", OPT_X_CHAIN, '<', "chain for Extended certificates"}, \ -+ { "xchain_build", OPT_X_CHAIN_BUILD, '-', \ -+ "build certificate chain for the extended certificates"}, \ -+ { "xcertform", OPT_X_CERTFORM, 'F', \ -+ "format of Extended certificate (PEM or DER) PEM default " }, \ -+ { "xkeyform", OPT_X_KEYFORM, 'F', \ -+ "format of Extended certificate's key (PEM or DER) PEM default"} -+ -+# define OPT_X_CASES \ -+ OPT_X__FIRST: case OPT_X__LAST: break; \ -+ case OPT_X_KEY: \ -+ case OPT_X_CERT: \ -+ case OPT_X_CHAIN: \ -+ case OPT_X_CHAIN_BUILD: \ -+ case OPT_X_CERTFORM: \ -+ case OPT_X_KEYFORM -+ -+/* -+ * Common SSL options. -+ * Any changes here must be coordinated with ../ssl/ssl_conf.c -+ */ -+# define OPT_S_ENUM \ -+ OPT_S__FIRST=3000, \ -+ OPT_S_NOSSL3, OPT_S_NOTLS1, OPT_S_NOTLS1_1, OPT_S_NOTLS1_2, \ -+ OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \ -+ OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_LEGACYCONN, \ -+ OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_STRICT, OPT_S_SIGALGS, \ -+ OPT_S_CLIENTSIGALGS, OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, \ -+ OPT_S_DHPARAM, OPT_S_DEBUGBROKE, OPT_S_COMP, \ -+ OPT_S__LAST -+ -+# define OPT_S_OPTIONS \ -+ {"no_ssl3", OPT_S_NOSSL3, '-',"Just disable SSLv3" }, \ -+ {"no_tls1", OPT_S_NOTLS1, '-', "Just disable TLSv1"}, \ -+ {"no_tls1_1", OPT_S_NOTLS1_1, '-', "Just disable TLSv1.1" }, \ -+ {"no_tls1_2", OPT_S_NOTLS1_2, '-', "Just disable TLSv1.2"}, \ -+ {"bugs", OPT_S_BUGS, '-', "Turn on SSL bug compatibility"}, \ -+ {"no_comp", OPT_S_NO_COMP, '-', "Disable SSL/TLS compression (default)" }, \ -+ {"comp", OPT_S_COMP, '-', "Use SSL/TLS-level compression" }, \ -+ {"no_ticket", OPT_S_NOTICKET, '-', \ -+ "Disable use of TLS session tickets"}, \ -+ {"serverpref", OPT_S_SERVERPREF, '-', "Use server's cipher preferences"}, \ -+ {"legacy_renegotiation", OPT_S_LEGACYRENEG, '-', \ -+ "Enable use of legacy renegotiation (dangerous)"}, \ -+ {"legacy_server_connect", OPT_S_LEGACYCONN, '-', \ -+ "Allow initial connection to servers that don't support RI"}, \ -+ {"no_resumption_on_reneg", OPT_S_ONRESUMP, '-', \ -+ "Disallow session resumption on renegotiation"}, \ -+ {"no_legacy_server_connect", OPT_S_NOLEGACYCONN, '-', \ -+ "Disallow initial connection to servers that don't support RI"}, \ -+ {"strict", OPT_S_STRICT, '-', \ -+ "Enforce strict certificate checks as per TLS standard"}, \ -+ {"sigalgs", OPT_S_SIGALGS, 's', \ -+ "Signature algorithms to support (colon-separated list)" }, \ -+ {"client_sigalgs", OPT_S_CLIENTSIGALGS, 's', \ -+ "Signature algorithms to support for client certificate" \ -+ " authentication (colon-separated list)" }, \ -+ {"curves", OPT_S_CURVES, 's', \ -+ "Elliptic curves to advertise (colon-separated list)" }, \ -+ {"named_curve", OPT_S_NAMEDCURVE, 's', \ -+ "Elliptic curve used for ECDHE (server-side only)" }, \ -+ {"cipher", OPT_S_CIPHER, 's', "Specify cipher list to be used"}, \ -+ {"dhparam", OPT_S_DHPARAM, '<', \ -+ "DH parameter file to use, in cert file if not specified"}, \ -+ {"debug_broken_protocol", OPT_S_DEBUGBROKE, '-', \ -+ "Perform all sorts of protocol violations for testing purposes"} -+ -+# define OPT_S_CASES \ -+ OPT_S__FIRST: case OPT_S__LAST: break; \ -+ case OPT_S_NOSSL3: \ -+ case OPT_S_NOTLS1: \ -+ case OPT_S_NOTLS1_1: \ -+ case OPT_S_NOTLS1_2: \ -+ case OPT_S_BUGS: \ -+ case OPT_S_NO_COMP: \ -+ case OPT_S_COMP: \ -+ case OPT_S_NOTICKET: \ -+ case OPT_S_SERVERPREF: \ -+ case OPT_S_LEGACYRENEG: \ -+ case OPT_S_LEGACYCONN: \ -+ case OPT_S_ONRESUMP: \ -+ case OPT_S_NOLEGACYCONN: \ -+ case OPT_S_STRICT: \ -+ case OPT_S_SIGALGS: \ -+ case OPT_S_CLIENTSIGALGS: \ -+ case OPT_S_CURVES: \ -+ case OPT_S_NAMEDCURVE: \ -+ case OPT_S_CIPHER: \ -+ case OPT_S_DHPARAM: \ -+ case OPT_S_DEBUGBROKE -+ -+#define IS_NO_PROT_FLAG(o) \ -+ (o == OPT_S_NOSSL3 || o == OPT_S_NOTLS1 || o == OPT_S_NOTLS1_1 \ -+ || o == OPT_S_NOTLS1_2) -+ -+/* -+ * Option parsing. -+ */ -+extern const char OPT_HELP_STR[]; -+extern const char OPT_MORE_STR[]; -+typedef struct options_st { -+ const char *name; -+ int retval; -+ /* -+ * value type: - no value (also the value zero), n number, p positive -+ * number, u unsigned, l long, s string, < input file, > output file, -+ * f any format, F der/pem format , E der/pem/engine format identifier. -+ * l, n and u include zero; p does not. -+ */ -+ int valtype; -+ const char *helpstr; -+} OPTIONS; -+ -+/* -+ * A string/int pairing; widely use for option value lookup, hence the -+ * name OPT_PAIR. But that name is misleading in s_cb.c, so we also use -+ * the "generic" name STRINT_PAIR. -+ */ -+typedef struct string_int_pair_st { -+ const char *name; -+ int retval; -+} OPT_PAIR, STRINT_PAIR; -+ -+/* Flags to pass into opt_format; see FORMAT_xxx, below. */ -+# define OPT_FMT_PEMDER (1L << 1) -+# define OPT_FMT_PKCS12 (1L << 2) -+# define OPT_FMT_SMIME (1L << 3) -+# define OPT_FMT_ENGINE (1L << 4) -+# define OPT_FMT_MSBLOB (1L << 5) -+# define OPT_FMT_NETSCAPE (1L << 6) -+# define OPT_FMT_NSS (1L << 7) -+# define OPT_FMT_TEXT (1L << 8) -+# define OPT_FMT_HTTP (1L << 9) -+# define OPT_FMT_PVK (1L << 10) -+# define OPT_FMT_PDE (OPT_FMT_PEMDER | OPT_FMT_ENGINE) -+# define OPT_FMT_PDS (OPT_FMT_PEMDER | OPT_FMT_SMIME) -+# define OPT_FMT_ANY ( \ -+ OPT_FMT_PEMDER | OPT_FMT_PKCS12 | OPT_FMT_SMIME | \ -+ OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NETSCAPE | \ -+ OPT_FMT_NSS | OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK) -+ -+char *opt_progname(const char *argv0); -+char *opt_getprog(void); -+char *opt_init(int ac, char **av, const OPTIONS * o); -+int opt_next(void); -+int opt_format(const char *s, unsigned long flags, int *result); -+int opt_int(const char *arg, int *result); -+int opt_ulong(const char *arg, unsigned long *result); -+int opt_long(const char *arg, long *result); -+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ -+ defined(INTMAX_MAX) && defined(UINTMAX_MAX) -+int opt_imax(const char *arg, intmax_t *result); -+int opt_umax(const char *arg, uintmax_t *result); -+#else -+# define opt_imax opt_long -+# define opt_umax opt_ulong -+# define intmax_t long -+# define uintmax_t unsigned long -+#endif -+int opt_pair(const char *arg, const OPT_PAIR * pairs, int *result); -+int opt_cipher(const char *name, const EVP_CIPHER **cipherp); -+int opt_md(const char *name, const EVP_MD **mdp); -+char *opt_arg(void); -+char *opt_flag(void); -+char *opt_unknown(void); -+char *opt_reset(void); -+char **opt_rest(void); -+int opt_num_rest(void); -+int opt_verify(int i, X509_VERIFY_PARAM *vpm); -+void opt_help(const OPTIONS * list); -+int opt_format_error(const char *s, unsigned long flags); -+ -+typedef struct args_st { -+ int size; -+ int argc; -+ char **argv; -+} ARGS; -+ -+/* -+ * VMS C only for now, implemented in vms_decc_init.c -+ * If other C compilers forget to terminate argv with NULL, this function -+ * can be re-used. -+ */ -+char **copy_argv(int *argc, char *argv[]); -+/* -+ * Win32-specific argv initialization that splits OS-supplied UNICODE -+ * command line string to array of UTF8-encoded strings. -+ */ -+void win32_utf8argv(int *argc, char **argv[]); -+ -+ -+# define PW_MIN_LENGTH 4 -+typedef struct pw_cb_data { -+ const void *password; -+ const char *prompt_info; -+} PW_CB_DATA; -+ -+int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data); -+ -+int setup_ui_method(void); -+void destroy_ui_method(void); -+ -+int chopup_args(ARGS *arg, char *buf); -+# ifdef HEADER_X509_H -+int dump_cert_text(BIO *out, X509 *x); -+void print_name(BIO *out, const char *title, X509_NAME *nm, -+ unsigned long lflags); -+# endif -+void print_bignum_var(BIO *, const BIGNUM *, const char*, -+ int, unsigned char *); -+void print_array(BIO *, const char *, int, const unsigned char *); -+int set_cert_ex(unsigned long *flags, const char *arg); -+int set_name_ex(unsigned long *flags, const char *arg); -+int set_ext_copy(int *copy_type, const char *arg); -+int copy_extensions(X509 *x, X509_REQ *req, int copy_type); -+int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2); -+int add_oid_section(CONF *conf); -+X509 *load_cert(const char *file, int format, const char *cert_descrip); -+X509_CRL *load_crl(const char *infile, int format); -+EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, -+ const char *pass, ENGINE *e, const char *key_descrip); -+EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, -+ const char *pass, ENGINE *e, const char *key_descrip); -+int load_certs(const char *file, STACK_OF(X509) **certs, int format, -+ const char *pass, const char *cert_descrip); -+int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format, -+ const char *pass, const char *cert_descrip); -+X509_STORE *setup_verify(const char *CAfile, const char *CApath, -+ int noCAfile, int noCApath); -+__owur int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile, -+ const char *CApath, int noCAfile, -+ int noCApath); -+ -+#ifndef OPENSSL_NO_CT -+ -+/* -+ * Sets the file to load the Certificate Transparency log list from. -+ * If path is NULL, loads from the default file path. -+ * Returns 1 on success, 0 otherwise. -+ */ -+__owur int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path); -+ -+#endif -+ -+ENGINE *setup_engine(const char *engine, int debug); -+void release_engine(ENGINE *e); -+ -+# ifndef OPENSSL_NO_OCSP -+OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, -+ const char *host, const char *path, -+ const char *port, int use_ssl, -+ STACK_OF(CONF_VALUE) *headers, -+ int req_timeout); -+# endif -+ -+/* Functions defined in ca.c and also used in ocsp.c */ -+int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, -+ ASN1_GENERALIZEDTIME **pinvtm, const char *str); -+ -+# define DB_type 0 -+# define DB_exp_date 1 -+# define DB_rev_date 2 -+# define DB_serial 3 /* index - unique */ -+# define DB_file 4 -+# define DB_name 5 /* index - unique when active and not -+ * disabled */ -+# define DB_NUMBER 6 -+ -+# define DB_TYPE_REV 'R' -+# define DB_TYPE_EXP 'E' -+# define DB_TYPE_VAL 'V' -+ -+typedef struct db_attr_st { -+ int unique_subject; -+} DB_ATTR; -+typedef struct ca_db_st { -+ DB_ATTR attributes; -+ TXT_DB *db; -+} CA_DB; -+ -+void* app_malloc(int sz, const char *what); -+BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai); -+int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial, -+ ASN1_INTEGER **retai); -+int rotate_serial(const char *serialfile, const char *new_suffix, -+ const char *old_suffix); -+int rand_serial(BIGNUM *b, ASN1_INTEGER *ai); -+CA_DB *load_index(const char *dbfile, DB_ATTR *dbattr); -+int index_index(CA_DB *db); -+int save_index(const char *dbfile, const char *suffix, CA_DB *db); -+int rotate_index(const char *dbfile, const char *new_suffix, -+ const char *old_suffix); -+void free_index(CA_DB *db); -+# define index_name_cmp_noconst(a, b) \ -+ index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \ -+ (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b)) -+int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b); -+int parse_yesno(const char *str, int def); -+ -+X509_NAME *parse_name(const char *str, long chtype, int multirdn); -+int args_verify(char ***pargs, int *pargc, -+ int *badarg, X509_VERIFY_PARAM **pm); -+void policies_print(X509_STORE_CTX *ctx); -+int bio_to_mem(unsigned char **out, int maxlen, BIO *in); -+int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value); -+int init_gen_str(EVP_PKEY_CTX **pctx, -+ const char *algname, ENGINE *e, int do_param); -+int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, -+ STACK_OF(OPENSSL_STRING) *sigopts); -+int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, -+ STACK_OF(OPENSSL_STRING) *sigopts); -+int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, -+ STACK_OF(OPENSSL_STRING) *sigopts); -+# ifndef OPENSSL_NO_PSK -+extern char *psk_key; -+# endif -+ -+unsigned char *next_protos_parse(size_t *outlen, const char *in); -+ -+void print_cert_checks(BIO *bio, X509 *x, -+ const char *checkhost, -+ const char *checkemail, const char *checkip); -+ -+void store_setup_crl_download(X509_STORE *st); -+ -+/* See OPT_FMT_xxx, above. */ -+/* On some platforms, it's important to distinguish between text and binary -+ * files. On some, there might even be specific file formats for different -+ * contents. The FORMAT_xxx macros are meant to express an intent with the -+ * file being read or created. -+ */ -+# define B_FORMAT_TEXT 0x8000 -+# define FORMAT_UNDEF 0 -+# define FORMAT_TEXT (1 | B_FORMAT_TEXT) /* Generic text */ -+# define FORMAT_BINARY 2 /* Generic binary */ -+# define FORMAT_BASE64 (3 | B_FORMAT_TEXT) /* Base64 */ -+# define FORMAT_ASN1 4 /* ASN.1/DER */ -+# define FORMAT_PEM (5 | B_FORMAT_TEXT) -+# define FORMAT_PKCS12 6 -+# define FORMAT_SMIME (7 | B_FORMAT_TEXT) -+# define FORMAT_ENGINE 8 /* Not really a file format */ -+# define FORMAT_PEMRSA (9 | B_FORMAT_TEXT) /* PEM RSAPubicKey format */ -+# define FORMAT_ASN1RSA 10 /* DER RSAPubicKey format */ -+# define FORMAT_MSBLOB 11 /* MS Key blob format */ -+# define FORMAT_PVK 12 /* MS PVK file format */ -+# define FORMAT_HTTP 13 /* Download using HTTP */ -+# define FORMAT_NSS 14 /* NSS keylog format */ -+ -+# define EXT_COPY_NONE 0 -+# define EXT_COPY_ADD 1 -+# define EXT_COPY_ALL 2 -+ -+# define NETSCAPE_CERT_HDR "certificate" -+ -+# define APP_PASS_LEN 1024 -+ -+# define SERIAL_RAND_BITS 64 -+ -+int app_isdir(const char *); -+int app_access(const char *, int flag); -+int fileno_stdin(void); -+int fileno_stdout(void); -+int raw_read_stdin(void *, int); -+int raw_write_stdout(const void *, int); -+ -+# define TM_START 0 -+# define TM_STOP 1 -+double app_tminterval(int stop, int usertime); -+ -+typedef struct verify_options_st { -+ int depth; -+ int quiet; -+ int error; -+ int return_error; -+} VERIFY_CB_ARGS; -+ -+extern VERIFY_CB_ARGS verify_args; -+ -+# include "progs.h" -+ -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/asn1pars.c b/CryptoPkg/Library/OpensslLib/openssl/apps/asn1pars.c -new file mode 100644 -index 0000000..1ac261c ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/asn1pars.c -@@ -0,0 +1,330 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * A nice addition from Dr Stephen Henson to add the -+ * -strparse option which parses nested binary structures -+ */ -+ -+#include -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_IN, OPT_OUT, OPT_INDENT, OPT_NOOUT, -+ OPT_OID, OPT_OFFSET, OPT_LENGTH, OPT_DUMP, OPT_DLIMIT, -+ OPT_STRPARSE, OPT_GENSTR, OPT_GENCONF, OPT_STRICTPEM -+} OPTION_CHOICE; -+ -+OPTIONS asn1parse_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'F', "input format - one of DER PEM"}, -+ {"in", OPT_IN, '<', "input file"}, -+ {"out", OPT_OUT, '>', "output file (output format is always DER)"}, -+ {"i", OPT_INDENT, 0, "indents the output"}, -+ {"noout", OPT_NOOUT, 0, "do not produce any output"}, -+ {"offset", OPT_OFFSET, 'p', "offset into file"}, -+ {"length", OPT_LENGTH, 'p', "length of section in file"}, -+ {"oid", OPT_OID, '<', "file of extra oid definitions"}, -+ {"dump", OPT_DUMP, 0, "unknown data in hex form"}, -+ {"dlimit", OPT_DLIMIT, 'p', -+ "dump the first arg bytes of unknown data in hex form"}, -+ {"strparse", OPT_STRPARSE, 's', -+ "offset; a series of these can be used to 'dig'"}, -+ {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"}, -+ {"genstr", OPT_GENSTR, 's', "string to generate ASN1 structure from"}, -+ {"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"}, -+ {OPT_MORE_STR, 0, 0, "(-inform will be ignored)"}, -+ {"strictpem", OPT_STRICTPEM, 0, -+ "do not attempt base64 decode outside PEM markers"}, -+ {NULL} -+}; -+ -+static int do_generate(char *genstr, const char *genconf, BUF_MEM *buf); -+ -+int asn1parse_main(int argc, char **argv) -+{ -+ ASN1_TYPE *at = NULL; -+ BIO *in = NULL, *b64 = NULL, *derout = NULL; -+ BUF_MEM *buf = NULL; -+ STACK_OF(OPENSSL_STRING) *osk = NULL; -+ char *genstr = NULL, *genconf = NULL; -+ char *infile = NULL, *oidfile = NULL, *derfile = NULL; -+ unsigned char *str = NULL; -+ char *name = NULL, *header = NULL, *prog; -+ const unsigned char *ctmpbuf; -+ int indent = 0, noout = 0, dump = 0, strictpem = 0, informat = FORMAT_PEM; -+ int offset = 0, ret = 1, i, j; -+ long num, tmplen; -+ unsigned char *tmpbuf; -+ unsigned int length = 0; -+ OPTION_CHOICE o; -+ -+ prog = opt_init(argc, argv, asn1parse_options); -+ -+ if ((osk = sk_OPENSSL_STRING_new_null()) == NULL) { -+ BIO_printf(bio_err, "%s: Memory allocation failure\n", prog); -+ goto end; -+ } -+ -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(asn1parse_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ derfile = opt_arg(); -+ break; -+ case OPT_INDENT: -+ indent = 1; -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ case OPT_OID: -+ oidfile = opt_arg(); -+ break; -+ case OPT_OFFSET: -+ offset = strtol(opt_arg(), NULL, 0); -+ break; -+ case OPT_LENGTH: -+ length = atoi(opt_arg()); -+ break; -+ case OPT_DUMP: -+ dump = -1; -+ break; -+ case OPT_DLIMIT: -+ dump = atoi(opt_arg()); -+ break; -+ case OPT_STRPARSE: -+ sk_OPENSSL_STRING_push(osk, opt_arg()); -+ break; -+ case OPT_GENSTR: -+ genstr = opt_arg(); -+ break; -+ case OPT_GENCONF: -+ genconf = opt_arg(); -+ break; -+ case OPT_STRICTPEM: -+ strictpem = 1; -+ informat = FORMAT_PEM; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ if (oidfile != NULL) { -+ in = bio_open_default(oidfile, 'r', FORMAT_TEXT); -+ if (in == NULL) -+ goto end; -+ OBJ_create_objects(in); -+ BIO_free(in); -+ } -+ -+ if ((in = bio_open_default(infile, 'r', informat)) == NULL) -+ goto end; -+ -+ if (derfile && (derout = bio_open_default(derfile, 'w', FORMAT_ASN1)) == NULL) -+ goto end; -+ -+ if (strictpem) { -+ if (PEM_read_bio(in, &name, &header, &str, &num) != -+ 1) { -+ BIO_printf(bio_err, "Error reading PEM file\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } else { -+ -+ if ((buf = BUF_MEM_new()) == NULL) -+ goto end; -+ if (!BUF_MEM_grow(buf, BUFSIZ * 8)) -+ goto end; /* Pre-allocate :-) */ -+ -+ if (genstr || genconf) { -+ num = do_generate(genstr, genconf, buf); -+ if (num < 0) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ else { -+ -+ if (informat == FORMAT_PEM) { -+ BIO *tmp; -+ -+ if ((b64 = BIO_new(BIO_f_base64())) == NULL) -+ goto end; -+ BIO_push(b64, in); -+ tmp = in; -+ in = b64; -+ b64 = tmp; -+ } -+ -+ num = 0; -+ for (;;) { -+ if (!BUF_MEM_grow(buf, (int)num + BUFSIZ)) -+ goto end; -+ i = BIO_read(in, &(buf->data[num]), BUFSIZ); -+ if (i <= 0) -+ break; -+ num += i; -+ } -+ } -+ str = (unsigned char *)buf->data; -+ -+ } -+ -+ /* If any structs to parse go through in sequence */ -+ -+ if (sk_OPENSSL_STRING_num(osk)) { -+ tmpbuf = str; -+ tmplen = num; -+ for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) { -+ ASN1_TYPE *atmp; -+ int typ; -+ j = atoi(sk_OPENSSL_STRING_value(osk, i)); -+ if (j == 0) { -+ BIO_printf(bio_err, "'%s' is an invalid number\n", -+ sk_OPENSSL_STRING_value(osk, i)); -+ continue; -+ } -+ tmpbuf += j; -+ tmplen -= j; -+ atmp = at; -+ ctmpbuf = tmpbuf; -+ at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen); -+ ASN1_TYPE_free(atmp); -+ if (!at) { -+ BIO_printf(bio_err, "Error parsing structure\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ typ = ASN1_TYPE_get(at); -+ if ((typ == V_ASN1_OBJECT) -+ || (typ == V_ASN1_BOOLEAN) -+ || (typ == V_ASN1_NULL)) { -+ BIO_printf(bio_err, "Can't parse %s type\n", ASN1_tag2str(typ)); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ /* hmm... this is a little evil but it works */ -+ tmpbuf = at->value.asn1_string->data; -+ tmplen = at->value.asn1_string->length; -+ } -+ str = tmpbuf; -+ num = tmplen; -+ } -+ -+ if (offset >= num) { -+ BIO_printf(bio_err, "Error: offset too large\n"); -+ goto end; -+ } -+ -+ num -= offset; -+ -+ if ((length == 0) || ((long)length > num)) -+ length = (unsigned int)num; -+ if (derout) { -+ if (BIO_write(derout, str + offset, length) != (int)length) { -+ BIO_printf(bio_err, "Error writing output\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ if (!noout && -+ !ASN1_parse_dump(bio_out, &(str[offset]), length, -+ indent, dump)) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ ret = 0; -+ end: -+ BIO_free(derout); -+ BIO_free(in); -+ BIO_free(b64); -+ if (ret != 0) -+ ERR_print_errors(bio_err); -+ BUF_MEM_free(buf); -+ OPENSSL_free(name); -+ OPENSSL_free(header); -+ if (strictpem) -+ OPENSSL_free(str); -+ ASN1_TYPE_free(at); -+ sk_OPENSSL_STRING_free(osk); -+ return (ret); -+} -+ -+static int do_generate(char *genstr, const char *genconf, BUF_MEM *buf) -+{ -+ CONF *cnf = NULL; -+ int len; -+ unsigned char *p; -+ ASN1_TYPE *atyp = NULL; -+ -+ if (genconf) { -+ if ((cnf = app_load_config(genconf)) == NULL) -+ goto err; -+ if (!genstr) -+ genstr = NCONF_get_string(cnf, "default", "asn1"); -+ if (!genstr) { -+ BIO_printf(bio_err, "Can't find 'asn1' in '%s'\n", genconf); -+ goto err; -+ } -+ } -+ -+ atyp = ASN1_generate_nconf(genstr, cnf); -+ NCONF_free(cnf); -+ cnf = NULL; -+ -+ if (!atyp) -+ return -1; -+ -+ len = i2d_ASN1_TYPE(atyp, NULL); -+ -+ if (len <= 0) -+ goto err; -+ -+ if (!BUF_MEM_grow(buf, len)) -+ goto err; -+ -+ p = (unsigned char *)buf->data; -+ -+ i2d_ASN1_TYPE(atyp, &p); -+ -+ ASN1_TYPE_free(atyp); -+ return len; -+ -+ err: -+ NCONF_free(cnf); -+ ASN1_TYPE_free(atyp); -+ return -1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/build.info b/CryptoPkg/Library/OpensslLib/openssl/apps/build.info -new file mode 100644 -index 0000000..ae64861 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/build.info -@@ -0,0 +1,22 @@ -+{- our $tsget_name = $config{target} =~ /^(VC|vms)-/ ? "tsget.pl" : "tsget"; -+ "" -} -+IF[{- !$disabled{apps} -}] -+ PROGRAMS=openssl -+ SOURCE[openssl]=\ -+ openssl.c \ -+ asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c \ -+ dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c \ -+ genpkey.c genrsa.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c pkcs8.c \ -+ pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c rsautl.c \ -+ s_client.c s_server.c s_time.c sess_id.c smime.c speed.c spkac.c \ -+ srp.c ts.c verify.c version.c x509.c rehash.c \ -+ apps.c opt.c s_cb.c s_socket.c \ -+ app_rand.c \ -+ {- $target{apps_aux_src} -} -+ INCLUDE[openssl]=.. ../include -+ DEPEND[openssl]=../libssl -+ -+ SCRIPTS=CA.pl {- $tsget_name -} -+ SOURCE[CA.pl]=CA.pl.in -+ SOURCE[{- $tsget_name -}]=tsget.in -+ENDIF -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/ca-cert.srl b/CryptoPkg/Library/OpensslLib/openssl/apps/ca-cert.srl -new file mode 100644 -index 0000000..2c7456e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/ca-cert.srl -@@ -0,0 +1 @@ -+07 -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/ca-key.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/ca-key.pem -new file mode 100644 -index 0000000..4e74249 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/ca-key.pem -@@ -0,0 +1,16 @@ -+-----BEGIN PRIVATE KEY----- -+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAL4tQNyKy4U2zX6l -+IZvORB1edmwMwIgSB4cgoFECrG5pixzYxKauZkAwKG9/+L4DB8qXRjfXWcvafcOU -+DlYpRROykJ7wGkiqmqbZyrxY8DWjk5ZZQXiSuhYOAJB+Fyfb11JZV6+CvBQX/1g+ -+vhJr39Gmp6oAesoYrj90ecozClmnAgMBAAECgYA3j6sSg+5f9hnldUMzbPjTh8Sb -+XsJlPrc6UFrmMBzGiUleXSpe9Dbla+x0XvQCN4pwMvAN4nnWp/f0Su5BV/9Y93nb -+im5ijGNrfN9i6QrnqGCr+MMute+4E8HR2pCScX0mBLDDf40SmDvMzCaxtd21keyr -+9DqHgInQZNEi6NKlkQJBAPCbUTFg6iQ6VTCQ8CsEf5q2xHhuTK23fJ999lvWVxN7 -+QsvWb9RP9Ng34HVtvB7Pl6P7FyHLQYiDJhhvYR0L0+kCQQDKV/09Kt6Wjf5Omp1I -+wd3A+tFnipdqnPw+qNHGjevv0hYiEIWQOYbx00zXgaX+WN/pzV9eeNN2XAxlNJ++ -+dxcPAkBrzeuPKFFAcjKBVC+H1rgl5gYZv7Hzk+buv02G0H6rZ+sB0c7BXiHiTwbv -+Fn/XfkP/YR14Ms3mEH0dLaphjU8hAkEAh3Ar/rRiN04mCcEuRFQXtaNtZSv8PA2G -+Pf7MI2Y9pdHupLCAZlBLRjTUO2/5hu1AO4QPMPIZQSFN3rRBtMCL+wJAMp/m2hvI -+TmtbMp/IrKGfma09e3yFiCmoNn7cHLJ7jLvXcacV2XNzpr9YHfBxiZo0g9FqZKvv -+PZoQ5B2XJ7bhTQ== -+-----END PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/ca-req.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/ca-req.pem -new file mode 100644 -index 0000000..84c6dbb ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/ca-req.pem -@@ -0,0 +1,11 @@ -+-----BEGIN CERTIFICATE REQUEST----- -+MIIBmzCCAQQCAQAwWzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClF1ZWVuc2xhbmQx -+GjAYBgNVBAoMEUNyeXB0U29mdCBQdHkgTHRkMRswGQYDVQQDDBJUZXN0IENBICgx -+MDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL4tQNyKy4U2zX6l -+IZvORB1edmwMwIgSB4cgoFECrG5pixzYxKauZkAwKG9/+L4DB8qXRjfXWcvafcOU -+DlYpRROykJ7wGkiqmqbZyrxY8DWjk5ZZQXiSuhYOAJB+Fyfb11JZV6+CvBQX/1g+ -+vhJr39Gmp6oAesoYrj90ecozClmnAgMBAAGgADANBgkqhkiG9w0BAQsFAAOBgQCo -+2jE7J1SNV7kyRm9m8CoPw8xYsuVcVFxPheBymYp8BlO0/rSdYygRjobpYnLVRUPZ -+pV792wzT1Rp4sXfZWO10lkFY4yi0pH2cdK2RX7qedibV1Xu9vt/yYANFBKVpA4dy -+PRyTQwi3In1N8hdfddpYR8f5MIUYRe5poFMIJcf8JA== -+-----END CERTIFICATE REQUEST----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/ca.c b/CryptoPkg/Library/OpensslLib/openssl/apps/ca.c -new file mode 100644 -index 0000000..1fb7b08 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/ca.c -@@ -0,0 +1,2565 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* The PPKI stuff has been donated by Jeff Barber */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef W_OK -+# ifdef OPENSSL_SYS_VMS -+# if defined(__DECC) -+# include -+# else -+# include -+# endif -+# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) -+# include -+# endif -+#endif -+ -+#include "apps.h" -+ -+#ifndef W_OK -+# define F_OK 0 -+# define X_OK 1 -+# define W_OK 2 -+# define R_OK 4 -+#endif -+ -+#undef BSIZE -+#define BSIZE 256 -+ -+#define BASE_SECTION "ca" -+ -+#define ENV_DEFAULT_CA "default_ca" -+ -+#define STRING_MASK "string_mask" -+#define UTF8_IN "utf8" -+ -+#define ENV_NEW_CERTS_DIR "new_certs_dir" -+#define ENV_CERTIFICATE "certificate" -+#define ENV_SERIAL "serial" -+#define ENV_CRLNUMBER "crlnumber" -+#define ENV_PRIVATE_KEY "private_key" -+#define ENV_DEFAULT_DAYS "default_days" -+#define ENV_DEFAULT_STARTDATE "default_startdate" -+#define ENV_DEFAULT_ENDDATE "default_enddate" -+#define ENV_DEFAULT_CRL_DAYS "default_crl_days" -+#define ENV_DEFAULT_CRL_HOURS "default_crl_hours" -+#define ENV_DEFAULT_MD "default_md" -+#define ENV_DEFAULT_EMAIL_DN "email_in_dn" -+#define ENV_PRESERVE "preserve" -+#define ENV_POLICY "policy" -+#define ENV_EXTENSIONS "x509_extensions" -+#define ENV_CRLEXT "crl_extensions" -+#define ENV_MSIE_HACK "msie_hack" -+#define ENV_NAMEOPT "name_opt" -+#define ENV_CERTOPT "cert_opt" -+#define ENV_EXTCOPY "copy_extensions" -+#define ENV_UNIQUE_SUBJECT "unique_subject" -+ -+#define ENV_DATABASE "database" -+ -+/* Additional revocation information types */ -+ -+#define REV_NONE 0 /* No additional information */ -+#define REV_CRL_REASON 1 /* Value is CRL reason code */ -+#define REV_HOLD 2 /* Value is hold instruction */ -+#define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */ -+#define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */ -+ -+static char *lookup_conf(const CONF *conf, const char *group, const char *tag); -+ -+static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, -+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, -+ BIGNUM *serial, const char *subj, unsigned long chtype, -+ int multirdn, int email_dn, const char *startdate, -+ const char *enddate, -+ long days, int batch, const char *ext_sect, CONF *conf, -+ int verbose, unsigned long certopt, unsigned long nameopt, -+ int default_op, int ext_copy, int selfsign); -+static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, -+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, -+ BIGNUM *serial, const char *subj, unsigned long chtype, -+ int multirdn, int email_dn, const char *startdate, -+ const char *enddate, long days, int batch, const char *ext_sect, -+ CONF *conf, int verbose, unsigned long certopt, -+ unsigned long nameopt, int default_op, int ext_copy); -+static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, -+ X509 *x509, const EVP_MD *dgst, -+ STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, -+ BIGNUM *serial, const char *subj, unsigned long chtype, -+ int multirdn, int email_dn, const char *startdate, -+ const char *enddate, long days, const char *ext_sect, CONF *conf, -+ int verbose, unsigned long certopt, -+ unsigned long nameopt, int default_op, int ext_copy); -+static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext); -+static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, -+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, -+ const char *subj, unsigned long chtype, int multirdn, -+ int email_dn, const char *startdate, const char *enddate, long days, -+ int batch, int verbose, X509_REQ *req, const char *ext_sect, -+ CONF *conf, unsigned long certopt, unsigned long nameopt, -+ int default_op, int ext_copy, int selfsign); -+static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval); -+static int get_certificate_status(const char *ser_status, CA_DB *db); -+static int do_updatedb(CA_DB *db); -+static int check_time_format(const char *str); -+char *make_revocation_str(int rev_type, char *rev_arg); -+int make_revoked(X509_REVOKED *rev, const char *str); -+static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str); -+ -+static CONF *extconf = NULL; -+static int preserve = 0; -+static int msie_hack = 0; -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_ENGINE, OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SUBJ, OPT_UTF8, -+ OPT_CREATE_SERIAL, OPT_MULTIVALUE_RDN, OPT_STARTDATE, OPT_ENDDATE, -+ OPT_DAYS, OPT_MD, OPT_POLICY, OPT_KEYFILE, OPT_KEYFORM, OPT_PASSIN, -+ OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR, -+ OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN, -+ OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, -+ OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID, -+ OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS, -+ OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, -+ OPT_CRL_CA_COMPROMISE -+} OPTION_CHOICE; -+ -+OPTIONS ca_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"verbose", OPT_VERBOSE, '-', "Verbose output during processing"}, -+ {"config", OPT_CONFIG, 's', "A config file"}, -+ {"name", OPT_NAME, 's', "The particular CA definition to use"}, -+ {"subj", OPT_SUBJ, 's', "Use arg instead of request's subject"}, -+ {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"}, -+ {"create_serial", OPT_CREATE_SERIAL, '-', -+ "If reading serial fails, create a new random serial"}, -+ {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-', -+ "Enable support for multivalued RDNs"}, -+ {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"}, -+ {"enddate", OPT_ENDDATE, 's', -+ "YYMMDDHHMMSSZ cert notAfter (overrides -days)"}, -+ {"days", OPT_DAYS, 'p', "Number of days to certify the cert for"}, -+ {"md", OPT_MD, 's', "md to use; one of md2, md5, sha or sha1"}, -+ {"policy", OPT_POLICY, 's', "The CA 'policy' to support"}, -+ {"keyfile", OPT_KEYFILE, 's', "Private key"}, -+ {"keyform", OPT_KEYFORM, 'f', "Private key file format (PEM or ENGINE)"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+ {"key", OPT_KEY, 's', "Key to decode the private key if it is encrypted"}, -+ {"cert", OPT_CERT, '<', "The CA cert"}, -+ {"selfsign", OPT_SELFSIGN, '-', -+ "Sign a cert with the key associated with it"}, -+ {"in", OPT_IN, '<', "The input PEM encoded cert request(s)"}, -+ {"out", OPT_OUT, '>', "Where to put the output file(s)"}, -+ {"outdir", OPT_OUTDIR, '/', "Where to put output cert"}, -+ {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, -+ {"notext", OPT_NOTEXT, '-', "Do not print the generated certificate"}, -+ {"batch", OPT_BATCH, '-', "Don't ask questions"}, -+ {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"}, -+ {"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"}, -+ {"gencrl", OPT_GENCRL, '-', "Generate a new CRL"}, -+ {"msie_hack", OPT_MSIE_HACK, '-', -+ "msie modifications to handle all those universal strings"}, -+ {"crldays", OPT_CRLDAYS, 'p', "Days until the next CRL is due"}, -+ {"crlhours", OPT_CRLHOURS, 'p', "Hours until the next CRL is due"}, -+ {"crlsec", OPT_CRLSEC, 'p', "Seconds until the next CRL is due"}, -+ {"infiles", OPT_INFILES, '-', "The last argument, requests to process"}, -+ {"ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign"}, -+ {"spkac", OPT_SPKAC, '<', -+ "File contains DN and signed public key and challenge"}, -+ {"revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)"}, -+ {"valid", OPT_VALID, 's', -+ "Add a Valid(not-revoked) DB entry about a cert (given in file)"}, -+ {"extensions", OPT_EXTENSIONS, 's', -+ "Extension section (override value in config file)"}, -+ {"extfile", OPT_EXTFILE, '<', -+ "Configuration file with X509v3 extensions to add"}, -+ {"status", OPT_STATUS, 's', "Shows cert status given the serial number"}, -+ {"updatedb", OPT_UPDATEDB, '-', "Updates db for expired cert"}, -+ {"crlexts", OPT_CRLEXTS, 's', -+ "CRL extension section (override value in config file)"}, -+ {"crl_reason", OPT_CRL_REASON, 's', "revocation reason"}, -+ {"crl_hold", OPT_CRL_HOLD, 's', -+ "the hold instruction, an OID. Sets revocation reason to certificateHold"}, -+ {"crl_compromise", OPT_CRL_COMPROMISE, 's', -+ "sets compromise time to val and the revocation reason to keyCompromise"}, -+ {"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's', -+ "sets compromise time to val and the revocation reason to CACompromise"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+#endif -+ {NULL} -+}; -+ -+int ca_main(int argc, char **argv) -+{ -+ CONF *conf = NULL; -+ ENGINE *e = NULL; -+ BIGNUM *crlnumber = NULL, *serial = NULL; -+ EVP_PKEY *pkey = NULL; -+ BIO *in = NULL, *out = NULL, *Sout = NULL; -+ ASN1_INTEGER *tmpser; -+ ASN1_TIME *tmptm; -+ CA_DB *db = NULL; -+ DB_ATTR db_attr; -+ STACK_OF(CONF_VALUE) *attribs = NULL; -+ STACK_OF(OPENSSL_STRING) *sigopts = NULL; -+ STACK_OF(X509) *cert_sk = NULL; -+ X509_CRL *crl = NULL; -+ const EVP_MD *dgst = NULL; -+ char *configfile = default_config_file, *section = NULL; -+ char *md = NULL, *policy = NULL, *keyfile = NULL; -+ char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL, *key = NULL; -+ const char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL; -+ const char *extensions = NULL, *extfile = NULL, *passinarg = NULL; -+ char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL; -+ const char *serialfile = NULL, *subj = NULL; -+ char *prog, *startdate = NULL, *enddate = NULL; -+ char *dbfile = NULL, *f, *randfile = NULL; -+ char buf[3][BSIZE]; -+ char *const *pp; -+ const char *p; -+ int create_ser = 0, free_key = 0, total = 0, total_done = 0; -+ int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE; -+ int keyformat = FORMAT_PEM, multirdn = 0, notext = 0, output_der = 0; -+ int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0; -+ int i, j, rev_type = REV_NONE, selfsign = 0; -+ long crldays = 0, crlhours = 0, crlsec = 0, days = 0; -+ unsigned long chtype = MBSTRING_ASC, nameopt = 0, certopt = 0; -+ X509 *x509 = NULL, *x509p = NULL, *x = NULL; -+ X509_REVOKED *r = NULL; -+ OPTION_CHOICE o; -+ -+ prog = opt_init(argc, argv, ca_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(ca_options); -+ ret = 0; -+ goto end; -+ case OPT_IN: -+ req = 1; -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_VERBOSE: -+ verbose = 1; -+ break; -+ case OPT_CONFIG: -+ configfile = opt_arg(); -+ break; -+ case OPT_NAME: -+ section = opt_arg(); -+ break; -+ case OPT_SUBJ: -+ subj = opt_arg(); -+ /* preserve=1; */ -+ break; -+ case OPT_UTF8: -+ chtype = MBSTRING_UTF8; -+ break; -+ case OPT_CREATE_SERIAL: -+ create_ser = 1; -+ break; -+ case OPT_MULTIVALUE_RDN: -+ multirdn = 1; -+ break; -+ case OPT_STARTDATE: -+ startdate = opt_arg(); -+ break; -+ case OPT_ENDDATE: -+ enddate = opt_arg(); -+ break; -+ case OPT_DAYS: -+ days = atoi(opt_arg()); -+ break; -+ case OPT_MD: -+ md = opt_arg(); -+ break; -+ case OPT_POLICY: -+ policy = opt_arg(); -+ break; -+ case OPT_KEYFILE: -+ keyfile = opt_arg(); -+ break; -+ case OPT_KEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat)) -+ goto opthelp; -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ case OPT_KEY: -+ key = opt_arg(); -+ break; -+ case OPT_CERT: -+ certfile = opt_arg(); -+ break; -+ case OPT_SELFSIGN: -+ selfsign = 1; -+ break; -+ case OPT_OUTDIR: -+ outdir = opt_arg(); -+ break; -+ case OPT_SIGOPT: -+ if (sigopts == NULL) -+ sigopts = sk_OPENSSL_STRING_new_null(); -+ if (sigopts == NULL -+ || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) -+ goto end; -+ break; -+ case OPT_NOTEXT: -+ notext = 1; -+ break; -+ case OPT_BATCH: -+ batch = 1; -+ break; -+ case OPT_PRESERVEDN: -+ preserve = 1; -+ break; -+ case OPT_NOEMAILDN: -+ email_dn = 0; -+ break; -+ case OPT_GENCRL: -+ gencrl = 1; -+ break; -+ case OPT_MSIE_HACK: -+ msie_hack = 1; -+ break; -+ case OPT_CRLDAYS: -+ crldays = atol(opt_arg()); -+ break; -+ case OPT_CRLHOURS: -+ crlhours = atol(opt_arg()); -+ break; -+ case OPT_CRLSEC: -+ crlsec = atol(opt_arg()); -+ break; -+ case OPT_INFILES: -+ req = 1; -+ goto end_of_options; -+ case OPT_SS_CERT: -+ ss_cert_file = opt_arg(); -+ req = 1; -+ break; -+ case OPT_SPKAC: -+ spkac_file = opt_arg(); -+ req = 1; -+ break; -+ case OPT_REVOKE: -+ infile = opt_arg(); -+ dorevoke = 1; -+ break; -+ case OPT_VALID: -+ infile = opt_arg(); -+ dorevoke = 2; -+ break; -+ case OPT_EXTENSIONS: -+ extensions = opt_arg(); -+ break; -+ case OPT_EXTFILE: -+ extfile = opt_arg(); -+ break; -+ case OPT_STATUS: -+ ser_status = opt_arg(); -+ break; -+ case OPT_UPDATEDB: -+ doupdatedb = 1; -+ break; -+ case OPT_CRLEXTS: -+ crl_ext = opt_arg(); -+ break; -+ case OPT_CRL_REASON: -+ rev_arg = opt_arg(); -+ rev_type = REV_CRL_REASON; -+ break; -+ case OPT_CRL_HOLD: -+ rev_arg = opt_arg(); -+ rev_type = REV_HOLD; -+ break; -+ case OPT_CRL_COMPROMISE: -+ rev_arg = opt_arg(); -+ rev_type = REV_KEY_COMPROMISE; -+ break; -+ case OPT_CRL_CA_COMPROMISE: -+ rev_arg = opt_arg(); -+ rev_type = REV_CA_COMPROMISE; -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ } -+ } -+end_of_options: -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ -+ BIO_printf(bio_err, "Using configuration from %s\n", configfile); -+ -+ if ((conf = app_load_config(configfile)) == NULL) -+ goto end; -+ if (configfile != default_config_file && !app_load_modules(conf)) -+ goto end; -+ -+ /* Lets get the config section we are using */ -+ if (section == NULL -+ && (section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_CA)) == NULL) -+ goto end; -+ -+ if (conf != NULL) { -+ p = NCONF_get_string(conf, NULL, "oid_file"); -+ if (p == NULL) -+ ERR_clear_error(); -+ if (p != NULL) { -+ BIO *oid_bio; -+ -+ oid_bio = BIO_new_file(p, "r"); -+ if (oid_bio == NULL) { -+ /*- -+ BIO_printf(bio_err,"problems opening %s for extra oid's\n",p); -+ ERR_print_errors(bio_err); -+ */ -+ ERR_clear_error(); -+ } else { -+ OBJ_create_objects(oid_bio); -+ BIO_free(oid_bio); -+ } -+ } -+ if (!add_oid_section(conf)) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE"); -+ if (randfile == NULL) -+ ERR_clear_error(); -+ app_RAND_load_file(randfile, 0); -+ -+ f = NCONF_get_string(conf, section, STRING_MASK); -+ if (!f) -+ ERR_clear_error(); -+ -+ if (f && !ASN1_STRING_set_default_mask_asc(f)) { -+ BIO_printf(bio_err, "Invalid global string mask setting %s\n", f); -+ goto end; -+ } -+ -+ if (chtype != MBSTRING_UTF8) { -+ f = NCONF_get_string(conf, section, UTF8_IN); -+ if (!f) -+ ERR_clear_error(); -+ else if (strcmp(f, "yes") == 0) -+ chtype = MBSTRING_UTF8; -+ } -+ -+ db_attr.unique_subject = 1; -+ p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT); -+ if (p) { -+ db_attr.unique_subject = parse_yesno(p, 1); -+ } else -+ ERR_clear_error(); -+ -+ /*****************************************************************/ -+ /* report status of cert with serial number given on command line */ -+ if (ser_status) { -+ dbfile = lookup_conf(conf, section, ENV_DATABASE); -+ if (dbfile == NULL) -+ goto end; -+ -+ db = load_index(dbfile, &db_attr); -+ if (db == NULL) -+ goto end; -+ -+ if (!index_index(db)) -+ goto end; -+ -+ if (get_certificate_status(ser_status, db) != 1) -+ BIO_printf(bio_err, "Error verifying serial %s!\n", ser_status); -+ goto end; -+ } -+ -+ /*****************************************************************/ -+ /* we definitely need a private key, so let's get it */ -+ -+ if (keyfile == NULL -+ && (keyfile = lookup_conf(conf, section, ENV_PRIVATE_KEY)) == NULL) -+ goto end; -+ -+ if (!key) { -+ free_key = 1; -+ if (!app_passwd(passinarg, NULL, &key, NULL)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ } -+ pkey = load_key(keyfile, keyformat, 0, key, e, "CA private key"); -+ if (key) -+ OPENSSL_cleanse(key, strlen(key)); -+ if (pkey == NULL) { -+ /* load_key() has already printed an appropriate message */ -+ goto end; -+ } -+ -+ /*****************************************************************/ -+ /* we need a certificate */ -+ if (!selfsign || spkac_file || ss_cert_file || gencrl) { -+ if (certfile == NULL -+ && (certfile = lookup_conf(conf, section, ENV_CERTIFICATE)) == NULL) -+ goto end; -+ -+ x509 = load_cert(certfile, FORMAT_PEM, "CA certificate"); -+ if (x509 == NULL) -+ goto end; -+ -+ if (!X509_check_private_key(x509, pkey)) { -+ BIO_printf(bio_err, -+ "CA certificate and CA private key do not match\n"); -+ goto end; -+ } -+ } -+ if (!selfsign) -+ x509p = x509; -+ -+ f = NCONF_get_string(conf, BASE_SECTION, ENV_PRESERVE); -+ if (f == NULL) -+ ERR_clear_error(); -+ if ((f != NULL) && ((*f == 'y') || (*f == 'Y'))) -+ preserve = 1; -+ f = NCONF_get_string(conf, BASE_SECTION, ENV_MSIE_HACK); -+ if (f == NULL) -+ ERR_clear_error(); -+ if ((f != NULL) && ((*f == 'y') || (*f == 'Y'))) -+ msie_hack = 1; -+ -+ f = NCONF_get_string(conf, section, ENV_NAMEOPT); -+ -+ if (f) { -+ if (!set_name_ex(&nameopt, f)) { -+ BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f); -+ goto end; -+ } -+ default_op = 0; -+ } else { -+ nameopt = XN_FLAG_ONELINE; -+ ERR_clear_error(); -+ } -+ -+ f = NCONF_get_string(conf, section, ENV_CERTOPT); -+ -+ if (f) { -+ if (!set_cert_ex(&certopt, f)) { -+ BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f); -+ goto end; -+ } -+ default_op = 0; -+ } else -+ ERR_clear_error(); -+ -+ f = NCONF_get_string(conf, section, ENV_EXTCOPY); -+ -+ if (f) { -+ if (!set_ext_copy(&ext_copy, f)) { -+ BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f); -+ goto end; -+ } -+ } else -+ ERR_clear_error(); -+ -+ /*****************************************************************/ -+ /* lookup where to write new certificates */ -+ if ((outdir == NULL) && (req)) { -+ -+ outdir = NCONF_get_string(conf, section, ENV_NEW_CERTS_DIR); -+ if (outdir == NULL) { -+ BIO_printf(bio_err, -+ "there needs to be defined a directory for new certificate to be placed in\n"); -+ goto end; -+ } -+#ifndef OPENSSL_SYS_VMS -+ /* -+ * outdir is a directory spec, but access() for VMS demands a -+ * filename. We could use the DEC C routine to convert the -+ * directory syntax to Unixly, and give that to app_isdir, -+ * but for now the fopen will catch the error if it's not a -+ * directory -+ */ -+ if (app_isdir(outdir) <= 0) { -+ BIO_printf(bio_err, "%s: %s is not a directory\n", prog, outdir); -+ perror(outdir); -+ goto end; -+ } -+#endif -+ } -+ -+ /*****************************************************************/ -+ /* we need to load the database file */ -+ dbfile = lookup_conf(conf, section, ENV_DATABASE); -+ if (dbfile == NULL) -+ goto end; -+ -+ db = load_index(dbfile, &db_attr); -+ if (db == NULL) -+ goto end; -+ -+ /* Lets check some fields */ -+ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { -+ pp = sk_OPENSSL_PSTRING_value(db->db->data, i); -+ if ((pp[DB_type][0] != DB_TYPE_REV) && (pp[DB_rev_date][0] != '\0')) { -+ BIO_printf(bio_err, -+ "entry %d: not revoked yet, but has a revocation date\n", -+ i + 1); -+ goto end; -+ } -+ if ((pp[DB_type][0] == DB_TYPE_REV) && -+ !make_revoked(NULL, pp[DB_rev_date])) { -+ BIO_printf(bio_err, " in entry %d\n", i + 1); -+ goto end; -+ } -+ if (!check_time_format((char *)pp[DB_exp_date])) { -+ BIO_printf(bio_err, "entry %d: invalid expiry date\n", i + 1); -+ goto end; -+ } -+ p = pp[DB_serial]; -+ j = strlen(p); -+ if (*p == '-') { -+ p++; -+ j--; -+ } -+ if ((j & 1) || (j < 2)) { -+ BIO_printf(bio_err, "entry %d: bad serial number length (%d)\n", -+ i + 1, j); -+ goto end; -+ } -+ for ( ; *p; p++) { -+ if (!isxdigit(_UC(*p))) { -+ BIO_printf(bio_err, -+ "entry %d: bad char 0%o '%c' in serial number\n", -+ i + 1, *p, *p); -+ goto end; -+ } -+ } -+ } -+ if (verbose) { -+ TXT_DB_write(bio_out, db->db); -+ BIO_printf(bio_err, "%d entries loaded from the database\n", -+ sk_OPENSSL_PSTRING_num(db->db->data)); -+ BIO_printf(bio_err, "generating index\n"); -+ } -+ -+ if (!index_index(db)) -+ goto end; -+ -+ /*****************************************************************/ -+ /* Update the db file for expired certificates */ -+ if (doupdatedb) { -+ if (verbose) -+ BIO_printf(bio_err, "Updating %s ...\n", dbfile); -+ -+ i = do_updatedb(db); -+ if (i == -1) { -+ BIO_printf(bio_err, "Malloc failure\n"); -+ goto end; -+ } else if (i == 0) { -+ if (verbose) -+ BIO_printf(bio_err, "No entries found to mark expired\n"); -+ } else { -+ if (!save_index(dbfile, "new", db)) -+ goto end; -+ -+ if (!rotate_index(dbfile, "new", "old")) -+ goto end; -+ -+ if (verbose) -+ BIO_printf(bio_err, -+ "Done. %d entries marked as expired\n", i); -+ } -+ } -+ -+ /*****************************************************************/ -+ /* Read extensions config file */ -+ if (extfile) { -+ if ((extconf = app_load_config(extfile)) == NULL) { -+ ret = 1; -+ goto end; -+ } -+ -+ if (verbose) -+ BIO_printf(bio_err, "Successfully loaded extensions file %s\n", -+ extfile); -+ -+ /* We can have sections in the ext file */ -+ if (extensions == NULL) { -+ extensions = NCONF_get_string(extconf, "default", "extensions"); -+ if (extensions == NULL) -+ extensions = "default"; -+ } -+ } -+ -+ /*****************************************************************/ -+ if (req || gencrl) { -+ /* FIXME: Is it really always text? */ -+ Sout = bio_open_default(outfile, 'w', FORMAT_TEXT); -+ if (Sout == NULL) -+ goto end; -+ } -+ -+ if (md == NULL -+ && (md = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL) -+ goto end; -+ -+ if (strcmp(md, "default") == 0) { -+ int def_nid; -+ if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) { -+ BIO_puts(bio_err, "no default digest\n"); -+ goto end; -+ } -+ md = (char *)OBJ_nid2sn(def_nid); -+ } -+ -+ if (!opt_md(md, &dgst)) { -+ goto end; -+ } -+ -+ if (req) { -+ if (email_dn == 1) { -+ char *tmp_email_dn = NULL; -+ -+ tmp_email_dn = NCONF_get_string(conf, section, ENV_DEFAULT_EMAIL_DN); -+ if (tmp_email_dn != NULL && strcmp(tmp_email_dn, "no") == 0) -+ email_dn = 0; -+ } -+ if (verbose) -+ BIO_printf(bio_err, "message digest is %s\n", -+ OBJ_nid2ln(EVP_MD_type(dgst))); -+ if (policy == NULL -+ && (policy = lookup_conf(conf, section, ENV_POLICY)) == NULL) -+ goto end; -+ -+ if (verbose) -+ BIO_printf(bio_err, "policy is %s\n", policy); -+ -+ serialfile = lookup_conf(conf, section, ENV_SERIAL); -+ if (serialfile == NULL) -+ goto end; -+ -+ if (!extconf) { -+ /* -+ * no '-extfile' option, so we look for extensions in the main -+ * configuration file -+ */ -+ if (!extensions) { -+ extensions = NCONF_get_string(conf, section, ENV_EXTENSIONS); -+ if (!extensions) -+ ERR_clear_error(); -+ } -+ if (extensions) { -+ /* Check syntax of file */ -+ X509V3_CTX ctx; -+ X509V3_set_ctx_test(&ctx); -+ X509V3_set_nconf(&ctx, conf); -+ if (!X509V3_EXT_add_nconf(conf, &ctx, extensions, NULL)) { -+ BIO_printf(bio_err, -+ "Error Loading extension section %s\n", -+ extensions); -+ ret = 1; -+ goto end; -+ } -+ } -+ } -+ -+ if (startdate == NULL) { -+ startdate = NCONF_get_string(conf, section, -+ ENV_DEFAULT_STARTDATE); -+ if (startdate == NULL) -+ ERR_clear_error(); -+ } -+ if (startdate && !ASN1_TIME_set_string(NULL, startdate)) { -+ BIO_printf(bio_err, -+ "start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); -+ goto end; -+ } -+ if (startdate == NULL) -+ startdate = "today"; -+ -+ if (enddate == NULL) { -+ enddate = NCONF_get_string(conf, section, ENV_DEFAULT_ENDDATE); -+ if (enddate == NULL) -+ ERR_clear_error(); -+ } -+ if (enddate && !ASN1_TIME_set_string(NULL, enddate)) { -+ BIO_printf(bio_err, -+ "end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n"); -+ goto end; -+ } -+ -+ if (days == 0) { -+ if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days)) -+ days = 0; -+ } -+ if (!enddate && (days == 0)) { -+ BIO_printf(bio_err, -+ "cannot lookup how many days to certify for\n"); -+ goto end; -+ } -+ -+ if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) { -+ BIO_printf(bio_err, "error while loading serial number\n"); -+ goto end; -+ } -+ if (verbose) { -+ if (BN_is_zero(serial)) -+ BIO_printf(bio_err, "next serial number is 00\n"); -+ else { -+ if ((f = BN_bn2hex(serial)) == NULL) -+ goto end; -+ BIO_printf(bio_err, "next serial number is %s\n", f); -+ OPENSSL_free(f); -+ } -+ } -+ -+ if ((attribs = NCONF_get_section(conf, policy)) == NULL) { -+ BIO_printf(bio_err, "unable to find 'section' for %s\n", policy); -+ goto end; -+ } -+ -+ if ((cert_sk = sk_X509_new_null()) == NULL) { -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ if (spkac_file != NULL) { -+ total++; -+ j = certify_spkac(&x, spkac_file, pkey, x509, dgst, sigopts, -+ attribs, db, serial, subj, chtype, multirdn, -+ email_dn, startdate, enddate, days, extensions, -+ conf, verbose, certopt, nameopt, default_op, -+ ext_copy); -+ if (j < 0) -+ goto end; -+ if (j > 0) { -+ total_done++; -+ BIO_printf(bio_err, "\n"); -+ if (!BN_add_word(serial, 1)) -+ goto end; -+ if (!sk_X509_push(cert_sk, x)) { -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ if (outfile) { -+ output_der = 1; -+ batch = 1; -+ } -+ } -+ } -+ if (ss_cert_file != NULL) { -+ total++; -+ j = certify_cert(&x, ss_cert_file, pkey, x509, dgst, sigopts, -+ attribs, -+ db, serial, subj, chtype, multirdn, email_dn, -+ startdate, enddate, days, batch, extensions, -+ conf, verbose, certopt, nameopt, default_op, -+ ext_copy); -+ if (j < 0) -+ goto end; -+ if (j > 0) { -+ total_done++; -+ BIO_printf(bio_err, "\n"); -+ if (!BN_add_word(serial, 1)) -+ goto end; -+ if (!sk_X509_push(cert_sk, x)) { -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ } -+ } -+ if (infile != NULL) { -+ total++; -+ j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db, -+ serial, subj, chtype, multirdn, email_dn, startdate, -+ enddate, days, batch, extensions, conf, verbose, -+ certopt, nameopt, default_op, ext_copy, selfsign); -+ if (j < 0) -+ goto end; -+ if (j > 0) { -+ total_done++; -+ BIO_printf(bio_err, "\n"); -+ if (!BN_add_word(serial, 1)) -+ goto end; -+ if (!sk_X509_push(cert_sk, x)) { -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ } -+ } -+ for (i = 0; i < argc; i++) { -+ total++; -+ j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db, -+ serial, subj, chtype, multirdn, email_dn, startdate, -+ enddate, days, batch, extensions, conf, verbose, -+ certopt, nameopt, default_op, ext_copy, selfsign); -+ if (j < 0) -+ goto end; -+ if (j > 0) { -+ total_done++; -+ BIO_printf(bio_err, "\n"); -+ if (!BN_add_word(serial, 1)) -+ goto end; -+ if (!sk_X509_push(cert_sk, x)) { -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ } -+ } -+ /* -+ * we have a stack of newly certified certificates and a data base -+ * and serial number that need updating -+ */ -+ -+ if (sk_X509_num(cert_sk) > 0) { -+ if (!batch) { -+ BIO_printf(bio_err, -+ "\n%d out of %d certificate requests certified, commit? [y/n]", -+ total_done, total); -+ (void)BIO_flush(bio_err); -+ buf[0][0] = '\0'; -+ if (!fgets(buf[0], 10, stdin)) { -+ BIO_printf(bio_err, -+ "CERTIFICATION CANCELED: I/O error\n"); -+ ret = 0; -+ goto end; -+ } -+ if ((buf[0][0] != 'y') && (buf[0][0] != 'Y')) { -+ BIO_printf(bio_err, "CERTIFICATION CANCELED\n"); -+ ret = 0; -+ goto end; -+ } -+ } -+ -+ BIO_printf(bio_err, "Write out database with %d new entries\n", -+ sk_X509_num(cert_sk)); -+ -+ if (!save_serial(serialfile, "new", serial, NULL)) -+ goto end; -+ -+ if (!save_index(dbfile, "new", db)) -+ goto end; -+ } -+ -+ if (verbose) -+ BIO_printf(bio_err, "writing new certificates\n"); -+ for (i = 0; i < sk_X509_num(cert_sk); i++) { -+ BIO *Cout = NULL; -+ X509 *xi = sk_X509_value(cert_sk, i); -+ ASN1_INTEGER *serialNumber = X509_get_serialNumber(xi); -+ int k; -+ char *n; -+ -+ j = ASN1_STRING_length(serialNumber); -+ p = (const char *)ASN1_STRING_get0_data(serialNumber); -+ -+ if (strlen(outdir) >= (size_t)(j ? BSIZE - j * 2 - 6 : BSIZE - 8)) { -+ BIO_printf(bio_err, "certificate file name too long\n"); -+ goto end; -+ } -+ -+ strcpy(buf[2], outdir); -+ -+#ifndef OPENSSL_SYS_VMS -+ OPENSSL_strlcat(buf[2], "/", sizeof(buf[2])); -+#endif -+ -+ n = (char *)&(buf[2][strlen(buf[2])]); -+ if (j > 0) { -+ for (k = 0; k < j; k++) { -+ if (n >= &(buf[2][sizeof(buf[2])])) -+ break; -+ BIO_snprintf(n, -+ &buf[2][0] + sizeof(buf[2]) - n, -+ "%02X", (unsigned char)*(p++)); -+ n += 2; -+ } -+ } else { -+ *(n++) = '0'; -+ *(n++) = '0'; -+ } -+ *(n++) = '.'; -+ *(n++) = 'p'; -+ *(n++) = 'e'; -+ *(n++) = 'm'; -+ *n = '\0'; -+ if (verbose) -+ BIO_printf(bio_err, "writing %s\n", buf[2]); -+ -+ Cout = BIO_new_file(buf[2], "w"); -+ if (Cout == NULL) { -+ perror(buf[2]); -+ goto end; -+ } -+ write_new_certificate(Cout, xi, 0, notext); -+ write_new_certificate(Sout, xi, output_der, notext); -+ BIO_free_all(Cout); -+ } -+ -+ if (sk_X509_num(cert_sk)) { -+ /* Rename the database and the serial file */ -+ if (!rotate_serial(serialfile, "new", "old")) -+ goto end; -+ -+ if (!rotate_index(dbfile, "new", "old")) -+ goto end; -+ -+ BIO_printf(bio_err, "Data Base Updated\n"); -+ } -+ } -+ -+ /*****************************************************************/ -+ if (gencrl) { -+ int crl_v2 = 0; -+ if (!crl_ext) { -+ crl_ext = NCONF_get_string(conf, section, ENV_CRLEXT); -+ if (!crl_ext) -+ ERR_clear_error(); -+ } -+ if (crl_ext) { -+ /* Check syntax of file */ -+ X509V3_CTX ctx; -+ X509V3_set_ctx_test(&ctx); -+ X509V3_set_nconf(&ctx, conf); -+ if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) { -+ BIO_printf(bio_err, -+ "Error Loading CRL extension section %s\n", -+ crl_ext); -+ ret = 1; -+ goto end; -+ } -+ } -+ -+ if ((crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER)) -+ != NULL) -+ if ((crlnumber = load_serial(crlnumberfile, 0, NULL)) == NULL) { -+ BIO_printf(bio_err, "error while loading CRL number\n"); -+ goto end; -+ } -+ -+ if (!crldays && !crlhours && !crlsec) { -+ if (!NCONF_get_number(conf, section, -+ ENV_DEFAULT_CRL_DAYS, &crldays)) -+ crldays = 0; -+ if (!NCONF_get_number(conf, section, -+ ENV_DEFAULT_CRL_HOURS, &crlhours)) -+ crlhours = 0; -+ ERR_clear_error(); -+ } -+ if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) { -+ BIO_printf(bio_err, -+ "cannot lookup how long until the next CRL is issued\n"); -+ goto end; -+ } -+ -+ if (verbose) -+ BIO_printf(bio_err, "making CRL\n"); -+ if ((crl = X509_CRL_new()) == NULL) -+ goto end; -+ if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) -+ goto end; -+ -+ tmptm = ASN1_TIME_new(); -+ if (tmptm == NULL) -+ goto end; -+ X509_gmtime_adj(tmptm, 0); -+ X509_CRL_set1_lastUpdate(crl, tmptm); -+ if (!X509_time_adj_ex(tmptm, crldays, crlhours * 60 * 60 + crlsec, -+ NULL)) { -+ BIO_puts(bio_err, "error setting CRL nextUpdate\n"); -+ goto end; -+ } -+ X509_CRL_set1_nextUpdate(crl, tmptm); -+ -+ ASN1_TIME_free(tmptm); -+ -+ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { -+ pp = sk_OPENSSL_PSTRING_value(db->db->data, i); -+ if (pp[DB_type][0] == DB_TYPE_REV) { -+ if ((r = X509_REVOKED_new()) == NULL) -+ goto end; -+ j = make_revoked(r, pp[DB_rev_date]); -+ if (!j) -+ goto end; -+ if (j == 2) -+ crl_v2 = 1; -+ if (!BN_hex2bn(&serial, pp[DB_serial])) -+ goto end; -+ tmpser = BN_to_ASN1_INTEGER(serial, NULL); -+ BN_free(serial); -+ serial = NULL; -+ if (!tmpser) -+ goto end; -+ X509_REVOKED_set_serialNumber(r, tmpser); -+ ASN1_INTEGER_free(tmpser); -+ X509_CRL_add0_revoked(crl, r); -+ } -+ } -+ -+ /* -+ * sort the data so it will be written in serial number order -+ */ -+ X509_CRL_sort(crl); -+ -+ /* we now have a CRL */ -+ if (verbose) -+ BIO_printf(bio_err, "signing CRL\n"); -+ -+ /* Add any extensions asked for */ -+ -+ if (crl_ext || crlnumberfile != NULL) { -+ X509V3_CTX crlctx; -+ X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0); -+ X509V3_set_nconf(&crlctx, conf); -+ -+ if (crl_ext) -+ if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl)) -+ goto end; -+ if (crlnumberfile != NULL) { -+ tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL); -+ if (!tmpser) -+ goto end; -+ X509_CRL_add1_ext_i2d(crl, NID_crl_number, tmpser, 0, 0); -+ ASN1_INTEGER_free(tmpser); -+ crl_v2 = 1; -+ if (!BN_add_word(crlnumber, 1)) -+ goto end; -+ } -+ } -+ if (crl_ext || crl_v2) { -+ if (!X509_CRL_set_version(crl, 1)) -+ goto end; /* version 2 CRL */ -+ } -+ -+ /* we have a CRL number that need updating */ -+ if (crlnumberfile != NULL) -+ if (!save_serial(crlnumberfile, "new", crlnumber, NULL)) -+ goto end; -+ -+ BN_free(crlnumber); -+ crlnumber = NULL; -+ -+ if (!do_X509_CRL_sign(crl, pkey, dgst, sigopts)) -+ goto end; -+ -+ PEM_write_bio_X509_CRL(Sout, crl); -+ -+ if (crlnumberfile != NULL) /* Rename the crlnumber file */ -+ if (!rotate_serial(crlnumberfile, "new", "old")) -+ goto end; -+ -+ } -+ /*****************************************************************/ -+ if (dorevoke) { -+ if (infile == NULL) { -+ BIO_printf(bio_err, "no input files\n"); -+ goto end; -+ } else { -+ X509 *revcert; -+ revcert = load_cert(infile, FORMAT_PEM, infile); -+ if (revcert == NULL) -+ goto end; -+ if (dorevoke == 2) -+ rev_type = -1; -+ j = do_revoke(revcert, db, rev_type, rev_arg); -+ if (j <= 0) -+ goto end; -+ X509_free(revcert); -+ -+ if (!save_index(dbfile, "new", db)) -+ goto end; -+ -+ if (!rotate_index(dbfile, "new", "old")) -+ goto end; -+ -+ BIO_printf(bio_err, "Data Base Updated\n"); -+ } -+ } -+ /*****************************************************************/ -+ ret = 0; -+ end: -+ BIO_free_all(Sout); -+ BIO_free_all(out); -+ BIO_free_all(in); -+ sk_X509_pop_free(cert_sk, X509_free); -+ -+ if (ret) -+ ERR_print_errors(bio_err); -+ app_RAND_write_file(randfile); -+ if (free_key) -+ OPENSSL_free(key); -+ BN_free(serial); -+ BN_free(crlnumber); -+ free_index(db); -+ sk_OPENSSL_STRING_free(sigopts); -+ EVP_PKEY_free(pkey); -+ X509_free(x509); -+ X509_CRL_free(crl); -+ NCONF_free(conf); -+ NCONF_free(extconf); -+ release_engine(e); -+ return (ret); -+} -+ -+static char *lookup_conf(const CONF *conf, const char *section, const char *tag) -+{ -+ char *entry = NCONF_get_string(conf, section, tag); -+ if (entry == NULL) -+ BIO_printf(bio_err, "variable lookup failed for %s::%s\n", section, tag); -+ return entry; -+} -+ -+static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, -+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, -+ BIGNUM *serial, const char *subj, unsigned long chtype, -+ int multirdn, int email_dn, const char *startdate, -+ const char *enddate, -+ long days, int batch, const char *ext_sect, CONF *lconf, -+ int verbose, unsigned long certopt, unsigned long nameopt, -+ int default_op, int ext_copy, int selfsign) -+{ -+ X509_REQ *req = NULL; -+ BIO *in = NULL; -+ EVP_PKEY *pktmp = NULL; -+ int ok = -1, i; -+ -+ in = BIO_new_file(infile, "r"); -+ if (in == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if ((req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL)) == NULL) { -+ BIO_printf(bio_err, "Error reading certificate request in %s\n", -+ infile); -+ goto end; -+ } -+ if (verbose) -+ X509_REQ_print(bio_err, req); -+ -+ BIO_printf(bio_err, "Check that the request matches the signature\n"); -+ -+ if (selfsign && !X509_REQ_check_private_key(req, pkey)) { -+ BIO_printf(bio_err, -+ "Certificate request and CA private key do not match\n"); -+ ok = 0; -+ goto end; -+ } -+ if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) { -+ BIO_printf(bio_err, "error unpacking public key\n"); -+ goto end; -+ } -+ i = X509_REQ_verify(req, pktmp); -+ pktmp = NULL; -+ if (i < 0) { -+ ok = 0; -+ BIO_printf(bio_err, "Signature verification problems....\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (i == 0) { -+ ok = 0; -+ BIO_printf(bio_err, -+ "Signature did not match the certificate request\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } else -+ BIO_printf(bio_err, "Signature ok\n"); -+ -+ ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, -+ chtype, multirdn, email_dn, startdate, enddate, days, batch, -+ verbose, req, ext_sect, lconf, certopt, nameopt, default_op, -+ ext_copy, selfsign); -+ -+ end: -+ X509_REQ_free(req); -+ BIO_free(in); -+ return (ok); -+} -+ -+static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, -+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, -+ BIGNUM *serial, const char *subj, unsigned long chtype, -+ int multirdn, int email_dn, const char *startdate, -+ const char *enddate, long days, int batch, const char *ext_sect, -+ CONF *lconf, int verbose, unsigned long certopt, -+ unsigned long nameopt, int default_op, int ext_copy) -+{ -+ X509 *req = NULL; -+ X509_REQ *rreq = NULL; -+ EVP_PKEY *pktmp = NULL; -+ int ok = -1, i; -+ -+ if ((req = load_cert(infile, FORMAT_PEM, infile)) == NULL) -+ goto end; -+ if (verbose) -+ X509_print(bio_err, req); -+ -+ BIO_printf(bio_err, "Check that the request matches the signature\n"); -+ -+ if ((pktmp = X509_get0_pubkey(req)) == NULL) { -+ BIO_printf(bio_err, "error unpacking public key\n"); -+ goto end; -+ } -+ i = X509_verify(req, pktmp); -+ if (i < 0) { -+ ok = 0; -+ BIO_printf(bio_err, "Signature verification problems....\n"); -+ goto end; -+ } -+ if (i == 0) { -+ ok = 0; -+ BIO_printf(bio_err, "Signature did not match the certificate\n"); -+ goto end; -+ } else -+ BIO_printf(bio_err, "Signature ok\n"); -+ -+ if ((rreq = X509_to_X509_REQ(req, NULL, NULL)) == NULL) -+ goto end; -+ -+ ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, -+ chtype, multirdn, email_dn, startdate, enddate, days, batch, -+ verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op, -+ ext_copy, 0); -+ -+ end: -+ X509_REQ_free(rreq); -+ X509_free(req); -+ return (ok); -+} -+ -+static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, -+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, -+ const char *subj, unsigned long chtype, int multirdn, -+ int email_dn, const char *startdate, const char *enddate, long days, -+ int batch, int verbose, X509_REQ *req, const char *ext_sect, -+ CONF *lconf, unsigned long certopt, unsigned long nameopt, -+ int default_op, int ext_copy, int selfsign) -+{ -+ X509_NAME *name = NULL, *CAname = NULL, *subject = NULL, *dn_subject = -+ NULL; -+ const ASN1_TIME *tm; -+ ASN1_STRING *str, *str2; -+ ASN1_OBJECT *obj; -+ X509 *ret = NULL; -+ X509_NAME_ENTRY *ne; -+ X509_NAME_ENTRY *tne, *push; -+ EVP_PKEY *pktmp; -+ int ok = -1, i, j, last, nid; -+ const char *p; -+ CONF_VALUE *cv; -+ OPENSSL_STRING row[DB_NUMBER]; -+ OPENSSL_STRING *irow = NULL; -+ OPENSSL_STRING *rrow = NULL; -+ char buf[25]; -+ -+ for (i = 0; i < DB_NUMBER; i++) -+ row[i] = NULL; -+ -+ if (subj) { -+ X509_NAME *n = parse_name(subj, chtype, multirdn); -+ -+ if (!n) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ X509_REQ_set_subject_name(req, n); -+ X509_NAME_free(n); -+ } -+ -+ if (default_op) -+ BIO_printf(bio_err, -+ "The Subject's Distinguished Name is as follows\n"); -+ -+ name = X509_REQ_get_subject_name(req); -+ for (i = 0; i < X509_NAME_entry_count(name); i++) { -+ ne = X509_NAME_get_entry(name, i); -+ str = X509_NAME_ENTRY_get_data(ne); -+ obj = X509_NAME_ENTRY_get_object(ne); -+ -+ if (msie_hack) { -+ /* assume all type should be strings */ -+ nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne)); -+ -+ if (str->type == V_ASN1_UNIVERSALSTRING) -+ ASN1_UNIVERSALSTRING_to_string(str); -+ -+ if ((str->type == V_ASN1_IA5STRING) && -+ (nid != NID_pkcs9_emailAddress)) -+ str->type = V_ASN1_T61STRING; -+ -+ if ((nid == NID_pkcs9_emailAddress) && -+ (str->type == V_ASN1_PRINTABLESTRING)) -+ str->type = V_ASN1_IA5STRING; -+ } -+ -+ /* If no EMAIL is wanted in the subject */ -+ if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn)) -+ continue; -+ -+ /* check some things */ -+ if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && -+ (str->type != V_ASN1_IA5STRING)) { -+ BIO_printf(bio_err, -+ "\nemailAddress type needs to be of type IA5STRING\n"); -+ goto end; -+ } -+ if ((str->type != V_ASN1_BMPSTRING) -+ && (str->type != V_ASN1_UTF8STRING)) { -+ j = ASN1_PRINTABLE_type(str->data, str->length); -+ if (((j == V_ASN1_T61STRING) && -+ (str->type != V_ASN1_T61STRING)) || -+ ((j == V_ASN1_IA5STRING) && -+ (str->type == V_ASN1_PRINTABLESTRING))) { -+ BIO_printf(bio_err, -+ "\nThe string contains characters that are illegal for the ASN.1 type\n"); -+ goto end; -+ } -+ } -+ -+ if (default_op) -+ old_entry_print(obj, str); -+ } -+ -+ /* Ok, now we check the 'policy' stuff. */ -+ if ((subject = X509_NAME_new()) == NULL) { -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ -+ /* take a copy of the issuer name before we mess with it. */ -+ if (selfsign) -+ CAname = X509_NAME_dup(name); -+ else -+ CAname = X509_NAME_dup(X509_get_subject_name(x509)); -+ if (CAname == NULL) -+ goto end; -+ str = str2 = NULL; -+ -+ for (i = 0; i < sk_CONF_VALUE_num(policy); i++) { -+ cv = sk_CONF_VALUE_value(policy, i); /* get the object id */ -+ if ((j = OBJ_txt2nid(cv->name)) == NID_undef) { -+ BIO_printf(bio_err, -+ "%s:unknown object type in 'policy' configuration\n", -+ cv->name); -+ goto end; -+ } -+ obj = OBJ_nid2obj(j); -+ -+ last = -1; -+ for (;;) { -+ /* lookup the object in the supplied name list */ -+ j = X509_NAME_get_index_by_OBJ(name, obj, last); -+ if (j < 0) { -+ if (last != -1) -+ break; -+ tne = NULL; -+ } else { -+ tne = X509_NAME_get_entry(name, j); -+ } -+ last = j; -+ -+ /* depending on the 'policy', decide what to do. */ -+ push = NULL; -+ if (strcmp(cv->value, "optional") == 0) { -+ if (tne != NULL) -+ push = tne; -+ } else if (strcmp(cv->value, "supplied") == 0) { -+ if (tne == NULL) { -+ BIO_printf(bio_err, -+ "The %s field needed to be supplied and was missing\n", -+ cv->name); -+ goto end; -+ } else -+ push = tne; -+ } else if (strcmp(cv->value, "match") == 0) { -+ int last2; -+ -+ if (tne == NULL) { -+ BIO_printf(bio_err, -+ "The mandatory %s field was missing\n", -+ cv->name); -+ goto end; -+ } -+ -+ last2 = -1; -+ -+ again2: -+ j = X509_NAME_get_index_by_OBJ(CAname, obj, last2); -+ if ((j < 0) && (last2 == -1)) { -+ BIO_printf(bio_err, -+ "The %s field does not exist in the CA certificate,\n" -+ "the 'policy' is misconfigured\n", -+ cv->name); -+ goto end; -+ } -+ if (j >= 0) { -+ push = X509_NAME_get_entry(CAname, j); -+ str = X509_NAME_ENTRY_get_data(tne); -+ str2 = X509_NAME_ENTRY_get_data(push); -+ last2 = j; -+ if (ASN1_STRING_cmp(str, str2) != 0) -+ goto again2; -+ } -+ if (j < 0) { -+ BIO_printf(bio_err, -+ "The %s field is different between\n" -+ "CA certificate (%s) and the request (%s)\n", -+ cv->name, -+ ((str2 == NULL) ? "NULL" : (char *)str2->data), -+ ((str == NULL) ? "NULL" : (char *)str->data)); -+ goto end; -+ } -+ } else { -+ BIO_printf(bio_err, -+ "%s:invalid type in 'policy' configuration\n", -+ cv->value); -+ goto end; -+ } -+ -+ if (push != NULL) { -+ if (!X509_NAME_add_entry(subject, push, -1, 0)) { -+ X509_NAME_ENTRY_free(push); -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ } -+ if (j < 0) -+ break; -+ } -+ } -+ -+ if (preserve) { -+ X509_NAME_free(subject); -+ /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */ -+ subject = X509_NAME_dup(name); -+ if (subject == NULL) -+ goto end; -+ } -+ -+ if (verbose) -+ BIO_printf(bio_err, -+ "The subject name appears to be ok, checking data base for clashes\n"); -+ -+ /* Build the correct Subject if no e-mail is wanted in the subject */ -+ /* -+ * and add it later on because of the method extensions are added -+ * (altName) -+ */ -+ -+ if (email_dn) -+ dn_subject = subject; -+ else { -+ X509_NAME_ENTRY *tmpne; -+ /* -+ * Its best to dup the subject DN and then delete any email addresses -+ * because this retains its structure. -+ */ -+ if ((dn_subject = X509_NAME_dup(subject)) == NULL) { -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ while ((i = X509_NAME_get_index_by_NID(dn_subject, -+ NID_pkcs9_emailAddress, -+ -1)) >= 0) { -+ tmpne = X509_NAME_get_entry(dn_subject, i); -+ X509_NAME_delete_entry(dn_subject, i); -+ X509_NAME_ENTRY_free(tmpne); -+ } -+ } -+ -+ if (BN_is_zero(serial)) -+ row[DB_serial] = OPENSSL_strdup("00"); -+ else -+ row[DB_serial] = BN_bn2hex(serial); -+ if (row[DB_serial] == NULL) { -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ -+ if (db->attributes.unique_subject) { -+ OPENSSL_STRING *crow = row; -+ -+ rrow = TXT_DB_get_by_index(db->db, DB_name, crow); -+ if (rrow != NULL) { -+ BIO_printf(bio_err, -+ "ERROR:There is already a certificate for %s\n", -+ row[DB_name]); -+ } -+ } -+ if (rrow == NULL) { -+ rrow = TXT_DB_get_by_index(db->db, DB_serial, row); -+ if (rrow != NULL) { -+ BIO_printf(bio_err, -+ "ERROR:Serial number %s has already been issued,\n", -+ row[DB_serial]); -+ BIO_printf(bio_err, -+ " check the database/serial_file for corruption\n"); -+ } -+ } -+ -+ if (rrow != NULL) { -+ BIO_printf(bio_err, "The matching entry has the following details\n"); -+ if (rrow[DB_type][0] == 'E') -+ p = "Expired"; -+ else if (rrow[DB_type][0] == 'R') -+ p = "Revoked"; -+ else if (rrow[DB_type][0] == 'V') -+ p = "Valid"; -+ else -+ p = "\ninvalid type, Data base error\n"; -+ BIO_printf(bio_err, "Type :%s\n", p);; -+ if (rrow[DB_type][0] == 'R') { -+ p = rrow[DB_exp_date]; -+ if (p == NULL) -+ p = "undef"; -+ BIO_printf(bio_err, "Was revoked on:%s\n", p); -+ } -+ p = rrow[DB_exp_date]; -+ if (p == NULL) -+ p = "undef"; -+ BIO_printf(bio_err, "Expires on :%s\n", p); -+ p = rrow[DB_serial]; -+ if (p == NULL) -+ p = "undef"; -+ BIO_printf(bio_err, "Serial Number :%s\n", p); -+ p = rrow[DB_file]; -+ if (p == NULL) -+ p = "undef"; -+ BIO_printf(bio_err, "File name :%s\n", p); -+ p = rrow[DB_name]; -+ if (p == NULL) -+ p = "undef"; -+ BIO_printf(bio_err, "Subject Name :%s\n", p); -+ ok = -1; /* This is now a 'bad' error. */ -+ goto end; -+ } -+ -+ /* We are now totally happy, lets make and sign the certificate */ -+ if (verbose) -+ BIO_printf(bio_err, -+ "Everything appears to be ok, creating and signing the certificate\n"); -+ -+ if ((ret = X509_new()) == NULL) -+ goto end; -+ -+#ifdef X509_V3 -+ /* Make it an X509 v3 certificate. */ -+ if (!X509_set_version(ret, 2)) -+ goto end; -+#endif -+ -+ if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL) -+ goto end; -+ if (selfsign) { -+ if (!X509_set_issuer_name(ret, subject)) -+ goto end; -+ } else { -+ if (!X509_set_issuer_name(ret, X509_get_subject_name(x509))) -+ goto end; -+ } -+ -+ if (!set_cert_times(ret, startdate, enddate, days)) -+ goto end; -+ -+ if (enddate != NULL) { -+ int tdays; -+ ASN1_TIME_diff(&tdays, NULL, NULL, X509_get0_notAfter(ret)); -+ days = tdays; -+ } -+ -+ if (!X509_set_subject_name(ret, subject)) -+ goto end; -+ -+ pktmp = X509_REQ_get0_pubkey(req); -+ i = X509_set_pubkey(ret, pktmp); -+ if (!i) -+ goto end; -+ -+ /* Lets add the extensions, if there are any */ -+ if (ext_sect) { -+ X509V3_CTX ctx; -+ X509_set_version(ret, 2); -+ -+ /* Initialize the context structure */ -+ if (selfsign) -+ X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0); -+ else -+ X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0); -+ -+ if (extconf) { -+ if (verbose) -+ BIO_printf(bio_err, "Extra configuration file found\n"); -+ -+ /* Use the extconf configuration db LHASH */ -+ X509V3_set_nconf(&ctx, extconf); -+ -+ /* Test the structure (needed?) */ -+ /* X509V3_set_ctx_test(&ctx); */ -+ -+ /* Adds exts contained in the configuration file */ -+ if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect, ret)) { -+ BIO_printf(bio_err, -+ "ERROR: adding extensions in section %s\n", -+ ext_sect); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (verbose) -+ BIO_printf(bio_err, -+ "Successfully added extensions from file.\n"); -+ } else if (ext_sect) { -+ /* We found extensions to be set from config file */ -+ X509V3_set_nconf(&ctx, lconf); -+ -+ if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) { -+ BIO_printf(bio_err, -+ "ERROR: adding extensions in section %s\n", -+ ext_sect); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (verbose) -+ BIO_printf(bio_err, -+ "Successfully added extensions from config\n"); -+ } -+ } -+ -+ /* Copy extensions from request (if any) */ -+ -+ if (!copy_extensions(ret, req, ext_copy)) { -+ BIO_printf(bio_err, "ERROR: adding extensions from request\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ /* Set the right value for the noemailDN option */ -+ if (email_dn == 0) { -+ if (!X509_set_subject_name(ret, dn_subject)) -+ goto end; -+ } -+ -+ if (!default_op) { -+ BIO_printf(bio_err, "Certificate Details:\n"); -+ /* -+ * Never print signature details because signature not present -+ */ -+ certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME; -+ X509_print_ex(bio_err, ret, nameopt, certopt); -+ } -+ -+ BIO_printf(bio_err, "Certificate is to be certified until "); -+ ASN1_TIME_print(bio_err, X509_get0_notAfter(ret)); -+ if (days) -+ BIO_printf(bio_err, " (%ld days)", days); -+ BIO_printf(bio_err, "\n"); -+ -+ if (!batch) { -+ -+ BIO_printf(bio_err, "Sign the certificate? [y/n]:"); -+ (void)BIO_flush(bio_err); -+ buf[0] = '\0'; -+ if (!fgets(buf, sizeof(buf) - 1, stdin)) { -+ BIO_printf(bio_err, -+ "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n"); -+ ok = 0; -+ goto end; -+ } -+ if (!((buf[0] == 'y') || (buf[0] == 'Y'))) { -+ BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED\n"); -+ ok = 0; -+ goto end; -+ } -+ } -+ -+ pktmp = X509_get0_pubkey(ret); -+ if (EVP_PKEY_missing_parameters(pktmp) && -+ !EVP_PKEY_missing_parameters(pkey)) -+ EVP_PKEY_copy_parameters(pktmp, pkey); -+ -+ if (!do_X509_sign(ret, pkey, dgst, sigopts)) -+ goto end; -+ -+ /* We now just add it to the database */ -+ row[DB_type] = OPENSSL_strdup("V"); -+ tm = X509_get0_notAfter(ret); -+ row[DB_exp_date] = app_malloc(tm->length + 1, "row expdate"); -+ memcpy(row[DB_exp_date], tm->data, tm->length); -+ row[DB_exp_date][tm->length] = '\0'; -+ row[DB_rev_date] = NULL; -+ row[DB_file] = OPENSSL_strdup("unknown"); -+ row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0); -+ -+ if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || -+ (row[DB_file] == NULL) || (row[DB_name] == NULL)) { -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ -+ irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row space"); -+ for (i = 0; i < DB_NUMBER; i++) { -+ irow[i] = row[i]; -+ row[i] = NULL; -+ } -+ irow[DB_NUMBER] = NULL; -+ -+ if (!TXT_DB_insert(db->db, irow)) { -+ BIO_printf(bio_err, "failed to update database\n"); -+ BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error); -+ goto end; -+ } -+ ok = 1; -+ end: -+ for (i = 0; i < DB_NUMBER; i++) -+ OPENSSL_free(row[i]); -+ -+ X509_NAME_free(CAname); -+ X509_NAME_free(subject); -+ if (dn_subject != subject) -+ X509_NAME_free(dn_subject); -+ if (ok <= 0) -+ X509_free(ret); -+ else -+ *xret = ret; -+ return (ok); -+} -+ -+static void write_new_certificate(BIO *bp, X509 *x, int output_der, -+ int notext) -+{ -+ -+ if (output_der) { -+ (void)i2d_X509_bio(bp, x); -+ return; -+ } -+ if (!notext) -+ X509_print(bp, x); -+ PEM_write_bio_X509(bp, x); -+} -+ -+static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, -+ X509 *x509, const EVP_MD *dgst, -+ STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, -+ BIGNUM *serial, const char *subj, unsigned long chtype, -+ int multirdn, int email_dn, const char *startdate, -+ const char *enddate, long days, const char *ext_sect, -+ CONF *lconf, int verbose, unsigned long certopt, -+ unsigned long nameopt, int default_op, int ext_copy) -+{ -+ STACK_OF(CONF_VALUE) *sk = NULL; -+ LHASH_OF(CONF_VALUE) *parms = NULL; -+ X509_REQ *req = NULL; -+ CONF_VALUE *cv = NULL; -+ NETSCAPE_SPKI *spki = NULL; -+ char *type, *buf; -+ EVP_PKEY *pktmp = NULL; -+ X509_NAME *n = NULL; -+ X509_NAME_ENTRY *ne = NULL; -+ int ok = -1, i, j; -+ long errline; -+ int nid; -+ -+ /* -+ * Load input file into a hash table. (This is just an easy -+ * way to read and parse the file, then put it into a convenient -+ * STACK format). -+ */ -+ parms = CONF_load(NULL, infile, &errline); -+ if (parms == NULL) { -+ BIO_printf(bio_err, "error on line %ld of %s\n", errline, infile); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ sk = CONF_get_section(parms, "default"); -+ if (sk_CONF_VALUE_num(sk) == 0) { -+ BIO_printf(bio_err, "no name/value pairs found in %s\n", infile); -+ goto end; -+ } -+ -+ /* -+ * Now create a dummy X509 request structure. We don't actually -+ * have an X509 request, but we have many of the components -+ * (a public key, various DN components). The idea is that we -+ * put these components into the right X509 request structure -+ * and we can use the same code as if you had a real X509 request. -+ */ -+ req = X509_REQ_new(); -+ if (req == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ /* -+ * Build up the subject name set. -+ */ -+ n = X509_REQ_get_subject_name(req); -+ -+ for (i = 0;; i++) { -+ if (sk_CONF_VALUE_num(sk) <= i) -+ break; -+ -+ cv = sk_CONF_VALUE_value(sk, i); -+ type = cv->name; -+ /* -+ * Skip past any leading X. X: X, etc to allow for multiple instances -+ */ -+ for (buf = cv->name; *buf; buf++) -+ if ((*buf == ':') || (*buf == ',') || (*buf == '.')) { -+ buf++; -+ if (*buf) -+ type = buf; -+ break; -+ } -+ -+ buf = cv->value; -+ if ((nid = OBJ_txt2nid(type)) == NID_undef) { -+ if (strcmp(type, "SPKAC") == 0) { -+ spki = NETSCAPE_SPKI_b64_decode(cv->value, -1); -+ if (spki == NULL) { -+ BIO_printf(bio_err, -+ "unable to load Netscape SPKAC structure\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ continue; -+ } -+ -+ if (!X509_NAME_add_entry_by_NID(n, nid, chtype, -+ (unsigned char *)buf, -1, -1, 0)) -+ goto end; -+ } -+ if (spki == NULL) { -+ BIO_printf(bio_err, "Netscape SPKAC structure not found in %s\n", -+ infile); -+ goto end; -+ } -+ -+ /* -+ * Now extract the key from the SPKI structure. -+ */ -+ -+ BIO_printf(bio_err, -+ "Check that the SPKAC request matches the signature\n"); -+ -+ if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) { -+ BIO_printf(bio_err, "error unpacking SPKAC public key\n"); -+ goto end; -+ } -+ -+ j = NETSCAPE_SPKI_verify(spki, pktmp); -+ if (j <= 0) { -+ EVP_PKEY_free(pktmp); -+ BIO_printf(bio_err, -+ "signature verification failed on SPKAC public key\n"); -+ goto end; -+ } -+ BIO_printf(bio_err, "Signature ok\n"); -+ -+ X509_REQ_set_pubkey(req, pktmp); -+ EVP_PKEY_free(pktmp); -+ ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, -+ chtype, multirdn, email_dn, startdate, enddate, days, 1, -+ verbose, req, ext_sect, lconf, certopt, nameopt, default_op, -+ ext_copy, 0); -+ end: -+ X509_REQ_free(req); -+ CONF_free(parms); -+ NETSCAPE_SPKI_free(spki); -+ X509_NAME_ENTRY_free(ne); -+ -+ return (ok); -+} -+ -+static int check_time_format(const char *str) -+{ -+ return ASN1_TIME_set_string(NULL, str); -+} -+ -+static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) -+{ -+ const ASN1_TIME *tm = NULL; -+ char *row[DB_NUMBER], **rrow, **irow; -+ char *rev_str = NULL; -+ BIGNUM *bn = NULL; -+ int ok = -1, i; -+ -+ for (i = 0; i < DB_NUMBER; i++) -+ row[i] = NULL; -+ row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0); -+ bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509), NULL); -+ if (!bn) -+ goto end; -+ if (BN_is_zero(bn)) -+ row[DB_serial] = OPENSSL_strdup("00"); -+ else -+ row[DB_serial] = BN_bn2hex(bn); -+ BN_free(bn); -+ if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) { -+ BIO_printf(bio_err, "Memory allocation failure\n"); -+ goto end; -+ } -+ /* -+ * We have to lookup by serial number because name lookup skips revoked -+ * certs -+ */ -+ rrow = TXT_DB_get_by_index(db->db, DB_serial, row); -+ if (rrow == NULL) { -+ BIO_printf(bio_err, -+ "Adding Entry with serial number %s to DB for %s\n", -+ row[DB_serial], row[DB_name]); -+ -+ /* We now just add it to the database */ -+ row[DB_type] = OPENSSL_strdup("V"); -+ tm = X509_get0_notAfter(x509); -+ row[DB_exp_date] = app_malloc(tm->length + 1, "row exp_data"); -+ memcpy(row[DB_exp_date], tm->data, tm->length); -+ row[DB_exp_date][tm->length] = '\0'; -+ row[DB_rev_date] = NULL; -+ row[DB_file] = OPENSSL_strdup("unknown"); -+ -+ irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row ptr"); -+ for (i = 0; i < DB_NUMBER; i++) { -+ irow[i] = row[i]; -+ row[i] = NULL; -+ } -+ irow[DB_NUMBER] = NULL; -+ -+ if (!TXT_DB_insert(db->db, irow)) { -+ BIO_printf(bio_err, "failed to update database\n"); -+ BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error); -+ goto end; -+ } -+ -+ /* Revoke Certificate */ -+ if (type == -1) -+ ok = 1; -+ else -+ ok = do_revoke(x509, db, type, value); -+ -+ goto end; -+ -+ } else if (index_name_cmp_noconst(row, rrow)) { -+ BIO_printf(bio_err, "ERROR:name does not match %s\n", row[DB_name]); -+ goto end; -+ } else if (type == -1) { -+ BIO_printf(bio_err, "ERROR:Already present, serial number %s\n", -+ row[DB_serial]); -+ goto end; -+ } else if (rrow[DB_type][0] == 'R') { -+ BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n", -+ row[DB_serial]); -+ goto end; -+ } else { -+ BIO_printf(bio_err, "Revoking Certificate %s.\n", rrow[DB_serial]); -+ rev_str = make_revocation_str(type, value); -+ if (!rev_str) { -+ BIO_printf(bio_err, "Error in revocation arguments\n"); -+ goto end; -+ } -+ rrow[DB_type][0] = 'R'; -+ rrow[DB_type][1] = '\0'; -+ rrow[DB_rev_date] = rev_str; -+ } -+ ok = 1; -+ end: -+ for (i = 0; i < DB_NUMBER; i++) { -+ OPENSSL_free(row[i]); -+ } -+ return (ok); -+} -+ -+static int get_certificate_status(const char *serial, CA_DB *db) -+{ -+ char *row[DB_NUMBER], **rrow; -+ int ok = -1, i; -+ size_t serial_len = strlen(serial); -+ -+ /* Free Resources */ -+ for (i = 0; i < DB_NUMBER; i++) -+ row[i] = NULL; -+ -+ /* Malloc needed char spaces */ -+ row[DB_serial] = app_malloc(serial_len + 2, "row serial#"); -+ -+ if (serial_len % 2) { -+ /* -+ * Set the first char to 0 -+ */ ; -+ row[DB_serial][0] = '0'; -+ -+ /* Copy String from serial to row[DB_serial] */ -+ memcpy(row[DB_serial] + 1, serial, serial_len); -+ row[DB_serial][serial_len + 1] = '\0'; -+ } else { -+ /* Copy String from serial to row[DB_serial] */ -+ memcpy(row[DB_serial], serial, serial_len); -+ row[DB_serial][serial_len] = '\0'; -+ } -+ -+ /* Make it Upper Case */ -+ for (i = 0; row[DB_serial][i] != '\0'; i++) -+ row[DB_serial][i] = toupper((unsigned char)row[DB_serial][i]); -+ -+ ok = 1; -+ -+ /* Search for the certificate */ -+ rrow = TXT_DB_get_by_index(db->db, DB_serial, row); -+ if (rrow == NULL) { -+ BIO_printf(bio_err, "Serial %s not present in db.\n", row[DB_serial]); -+ ok = -1; -+ goto end; -+ } else if (rrow[DB_type][0] == 'V') { -+ BIO_printf(bio_err, "%s=Valid (%c)\n", -+ row[DB_serial], rrow[DB_type][0]); -+ goto end; -+ } else if (rrow[DB_type][0] == 'R') { -+ BIO_printf(bio_err, "%s=Revoked (%c)\n", -+ row[DB_serial], rrow[DB_type][0]); -+ goto end; -+ } else if (rrow[DB_type][0] == 'E') { -+ BIO_printf(bio_err, "%s=Expired (%c)\n", -+ row[DB_serial], rrow[DB_type][0]); -+ goto end; -+ } else if (rrow[DB_type][0] == 'S') { -+ BIO_printf(bio_err, "%s=Suspended (%c)\n", -+ row[DB_serial], rrow[DB_type][0]); -+ goto end; -+ } else { -+ BIO_printf(bio_err, "%s=Unknown (%c).\n", -+ row[DB_serial], rrow[DB_type][0]); -+ ok = -1; -+ } -+ end: -+ for (i = 0; i < DB_NUMBER; i++) { -+ OPENSSL_free(row[i]); -+ } -+ return (ok); -+} -+ -+static int do_updatedb(CA_DB *db) -+{ -+ ASN1_UTCTIME *a_tm = NULL; -+ int i, cnt = 0; -+ int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */ -+ char **rrow, *a_tm_s; -+ -+ a_tm = ASN1_UTCTIME_new(); -+ if (a_tm == NULL) -+ return -1; -+ -+ /* get actual time and make a string */ -+ a_tm = X509_gmtime_adj(a_tm, 0); -+ a_tm_s = app_malloc(a_tm->length + 1, "time string"); -+ -+ memcpy(a_tm_s, a_tm->data, a_tm->length); -+ a_tm_s[a_tm->length] = '\0'; -+ -+ if (strncmp(a_tm_s, "49", 2) <= 0) -+ a_y2k = 1; -+ else -+ a_y2k = 0; -+ -+ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { -+ rrow = sk_OPENSSL_PSTRING_value(db->db->data, i); -+ -+ if (rrow[DB_type][0] == 'V') { -+ /* ignore entries that are not valid */ -+ if (strncmp(rrow[DB_exp_date], "49", 2) <= 0) -+ db_y2k = 1; -+ else -+ db_y2k = 0; -+ -+ if (db_y2k == a_y2k) { -+ /* all on the same y2k side */ -+ if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0) { -+ rrow[DB_type][0] = 'E'; -+ rrow[DB_type][1] = '\0'; -+ cnt++; -+ -+ BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]); -+ } -+ } else if (db_y2k < a_y2k) { -+ rrow[DB_type][0] = 'E'; -+ rrow[DB_type][1] = '\0'; -+ cnt++; -+ -+ BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]); -+ } -+ -+ } -+ } -+ -+ ASN1_UTCTIME_free(a_tm); -+ OPENSSL_free(a_tm_s); -+ return (cnt); -+} -+ -+static const char *crl_reasons[] = { -+ /* CRL reason strings */ -+ "unspecified", -+ "keyCompromise", -+ "CACompromise", -+ "affiliationChanged", -+ "superseded", -+ "cessationOfOperation", -+ "certificateHold", -+ "removeFromCRL", -+ /* Additional pseudo reasons */ -+ "holdInstruction", -+ "keyTime", -+ "CAkeyTime" -+}; -+ -+#define NUM_REASONS OSSL_NELEM(crl_reasons) -+ -+/* -+ * Given revocation information convert to a DB string. The format of the -+ * string is: revtime[,reason,extra]. Where 'revtime' is the revocation time -+ * (the current time). 'reason' is the optional CRL reason and 'extra' is any -+ * additional argument -+ */ -+ -+char *make_revocation_str(int rev_type, char *rev_arg) -+{ -+ char *str; -+ const char *other = NULL; -+ const char *reason = NULL; -+ ASN1_OBJECT *otmp; -+ ASN1_UTCTIME *revtm = NULL; -+ int i; -+ switch (rev_type) { -+ case REV_NONE: -+ break; -+ -+ case REV_CRL_REASON: -+ for (i = 0; i < 8; i++) { -+ if (strcasecmp(rev_arg, crl_reasons[i]) == 0) { -+ reason = crl_reasons[i]; -+ break; -+ } -+ } -+ if (reason == NULL) { -+ BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg); -+ return NULL; -+ } -+ break; -+ -+ case REV_HOLD: -+ /* Argument is an OID */ -+ -+ otmp = OBJ_txt2obj(rev_arg, 0); -+ ASN1_OBJECT_free(otmp); -+ -+ if (otmp == NULL) { -+ BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg); -+ return NULL; -+ } -+ -+ reason = "holdInstruction"; -+ other = rev_arg; -+ break; -+ -+ case REV_KEY_COMPROMISE: -+ case REV_CA_COMPROMISE: -+ -+ /* Argument is the key compromise time */ -+ if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) { -+ BIO_printf(bio_err, -+ "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n", -+ rev_arg); -+ return NULL; -+ } -+ other = rev_arg; -+ if (rev_type == REV_KEY_COMPROMISE) -+ reason = "keyTime"; -+ else -+ reason = "CAkeyTime"; -+ -+ break; -+ -+ } -+ -+ revtm = X509_gmtime_adj(NULL, 0); -+ -+ if (!revtm) -+ return NULL; -+ -+ i = revtm->length + 1; -+ -+ if (reason) -+ i += strlen(reason) + 1; -+ if (other) -+ i += strlen(other) + 1; -+ -+ str = app_malloc(i, "revocation reason"); -+ OPENSSL_strlcpy(str, (char *)revtm->data, i); -+ if (reason) { -+ OPENSSL_strlcat(str, ",", i); -+ OPENSSL_strlcat(str, reason, i); -+ } -+ if (other) { -+ OPENSSL_strlcat(str, ",", i); -+ OPENSSL_strlcat(str, other, i); -+ } -+ ASN1_UTCTIME_free(revtm); -+ return str; -+} -+ -+/*- -+ * Convert revocation field to X509_REVOKED entry -+ * return code: -+ * 0 error -+ * 1 OK -+ * 2 OK and some extensions added (i.e. V2 CRL) -+ */ -+ -+int make_revoked(X509_REVOKED *rev, const char *str) -+{ -+ char *tmp = NULL; -+ int reason_code = -1; -+ int i, ret = 0; -+ ASN1_OBJECT *hold = NULL; -+ ASN1_GENERALIZEDTIME *comp_time = NULL; -+ ASN1_ENUMERATED *rtmp = NULL; -+ -+ ASN1_TIME *revDate = NULL; -+ -+ i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str); -+ -+ if (i == 0) -+ goto end; -+ -+ if (rev && !X509_REVOKED_set_revocationDate(rev, revDate)) -+ goto end; -+ -+ if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) { -+ rtmp = ASN1_ENUMERATED_new(); -+ if (rtmp == NULL || !ASN1_ENUMERATED_set(rtmp, reason_code)) -+ goto end; -+ if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0)) -+ goto end; -+ } -+ -+ if (rev && comp_time) { -+ if (!X509_REVOKED_add1_ext_i2d -+ (rev, NID_invalidity_date, comp_time, 0, 0)) -+ goto end; -+ } -+ if (rev && hold) { -+ if (!X509_REVOKED_add1_ext_i2d -+ (rev, NID_hold_instruction_code, hold, 0, 0)) -+ goto end; -+ } -+ -+ if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS) -+ ret = 2; -+ else -+ ret = 1; -+ -+ end: -+ -+ OPENSSL_free(tmp); -+ ASN1_OBJECT_free(hold); -+ ASN1_GENERALIZEDTIME_free(comp_time); -+ ASN1_ENUMERATED_free(rtmp); -+ ASN1_TIME_free(revDate); -+ -+ return ret; -+} -+ -+static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str) -+{ -+ char buf[25], *pbuf; -+ const char *p; -+ int j; -+ -+ j = i2a_ASN1_OBJECT(bio_err, obj); -+ pbuf = buf; -+ for (j = 22 - j; j > 0; j--) -+ *(pbuf++) = ' '; -+ *(pbuf++) = ':'; -+ *(pbuf++) = '\0'; -+ BIO_puts(bio_err, buf); -+ -+ if (str->type == V_ASN1_PRINTABLESTRING) -+ BIO_printf(bio_err, "PRINTABLE:'"); -+ else if (str->type == V_ASN1_T61STRING) -+ BIO_printf(bio_err, "T61STRING:'"); -+ else if (str->type == V_ASN1_IA5STRING) -+ BIO_printf(bio_err, "IA5STRING:'"); -+ else if (str->type == V_ASN1_UNIVERSALSTRING) -+ BIO_printf(bio_err, "UNIVERSALSTRING:'"); -+ else -+ BIO_printf(bio_err, "ASN.1 %2d:'", str->type); -+ -+ p = (const char *)str->data; -+ for (j = str->length; j > 0; j--) { -+ if ((*p >= ' ') && (*p <= '~')) -+ BIO_printf(bio_err, "%c", *p); -+ else if (*p & 0x80) -+ BIO_printf(bio_err, "\\0x%02X", *p); -+ else if ((unsigned char)*p == 0xf7) -+ BIO_printf(bio_err, "^?"); -+ else -+ BIO_printf(bio_err, "^%c", *p + '@'); -+ p++; -+ } -+ BIO_printf(bio_err, "'\n"); -+ return 1; -+} -+ -+int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, -+ ASN1_GENERALIZEDTIME **pinvtm, const char *str) -+{ -+ char *tmp; -+ char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p; -+ int reason_code = -1; -+ int ret = 0; -+ unsigned int i; -+ ASN1_OBJECT *hold = NULL; -+ ASN1_GENERALIZEDTIME *comp_time = NULL; -+ -+ tmp = OPENSSL_strdup(str); -+ if (!tmp) { -+ BIO_printf(bio_err, "memory allocation failure\n"); -+ goto end; -+ } -+ -+ p = strchr(tmp, ','); -+ -+ rtime_str = tmp; -+ -+ if (p) { -+ *p = '\0'; -+ p++; -+ reason_str = p; -+ p = strchr(p, ','); -+ if (p) { -+ *p = '\0'; -+ arg_str = p + 1; -+ } -+ } -+ -+ if (prevtm) { -+ *prevtm = ASN1_UTCTIME_new(); -+ if (*prevtm == NULL) { -+ BIO_printf(bio_err, "memory allocation failure\n"); -+ goto end; -+ } -+ if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) { -+ BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str); -+ goto end; -+ } -+ } -+ if (reason_str) { -+ for (i = 0; i < NUM_REASONS; i++) { -+ if (strcasecmp(reason_str, crl_reasons[i]) == 0) { -+ reason_code = i; -+ break; -+ } -+ } -+ if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) { -+ BIO_printf(bio_err, "invalid reason code %s\n", reason_str); -+ goto end; -+ } -+ -+ if (reason_code == 7) -+ reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL; -+ else if (reason_code == 8) { /* Hold instruction */ -+ if (!arg_str) { -+ BIO_printf(bio_err, "missing hold instruction\n"); -+ goto end; -+ } -+ reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD; -+ hold = OBJ_txt2obj(arg_str, 0); -+ -+ if (!hold) { -+ BIO_printf(bio_err, "invalid object identifier %s\n", -+ arg_str); -+ goto end; -+ } -+ if (phold) -+ *phold = hold; -+ else -+ ASN1_OBJECT_free(hold); -+ } else if ((reason_code == 9) || (reason_code == 10)) { -+ if (!arg_str) { -+ BIO_printf(bio_err, "missing compromised time\n"); -+ goto end; -+ } -+ comp_time = ASN1_GENERALIZEDTIME_new(); -+ if (comp_time == NULL) { -+ BIO_printf(bio_err, "memory allocation failure\n"); -+ goto end; -+ } -+ if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str)) { -+ BIO_printf(bio_err, "invalid compromised time %s\n", arg_str); -+ goto end; -+ } -+ if (reason_code == 9) -+ reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE; -+ else -+ reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE; -+ } -+ } -+ -+ if (preason) -+ *preason = reason_code; -+ if (pinvtm) { -+ *pinvtm = comp_time; -+ comp_time = NULL; -+ } -+ -+ ret = 1; -+ -+ end: -+ -+ OPENSSL_free(tmp); -+ ASN1_GENERALIZEDTIME_free(comp_time); -+ -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/cert.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/cert.pem -new file mode 100644 -index 0000000..de4a77a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/cert.pem -@@ -0,0 +1,11 @@ -+-----BEGIN CERTIFICATE----- -+MIIBoDCCAUoCAQAwDQYJKoZIhvcNAQEEBQAwYzELMAkGA1UEBhMCQVUxEzARBgNV -+BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSMwIQYD -+VQQDExpTZXJ2ZXIgdGVzdCBjZXJ0ICg1MTIgYml0KTAeFw05NzA5MDkwMzQxMjZa -+Fw05NzEwMDkwMzQxMjZaMF4xCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -+YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFzAVBgNVBAMT -+DkVyaWMgdGhlIFlvdW5nMFEwCQYFKw4DAgwFAANEAAJBALVEqPODnpI4rShlY8S7 -+tB713JNvabvn6Gned7zylwLLiXQAo/PAT6mfdWPTyCX9RlId/Aroh1ou893BA32Q -+sggwDQYJKoZIhvcNAQEEBQADQQCU5SSgapJSdRXJoX+CpCvFy+JVh9HpSjCpSNKO -+19raHv98hKAUJuP9HyM+SUsffO6mAIgitUaqW8/wDMePhEC3 -+-----END CERTIFICATE----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/ciphers.c b/CryptoPkg/Library/OpensslLib/openssl/apps/ciphers.c -new file mode 100644 -index 0000000..c0f43ea ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/ciphers.c -@@ -0,0 +1,242 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include "apps.h" -+#include -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_STDNAME, -+ OPT_SSL3, -+ OPT_TLS1, -+ OPT_TLS1_1, -+ OPT_TLS1_2, -+ OPT_PSK, -+ OPT_SRP, -+ OPT_V, OPT_UPPER_V, OPT_S -+} OPTION_CHOICE; -+ -+OPTIONS ciphers_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"}, -+ {"V", OPT_UPPER_V, '-', "Even more verbose"}, -+ {"s", OPT_S, '-', "Only supported ciphers"}, -+#ifndef OPENSSL_NO_SSL3 -+ {"ssl3", OPT_SSL3, '-', "SSL3 mode"}, -+#endif -+#ifndef OPENSSL_NO_TLS1 -+ {"tls1", OPT_TLS1, '-', "TLS1 mode"}, -+#endif -+#ifndef OPENSSL_NO_TLS1_1 -+ {"tls1_1", OPT_TLS1_1, '-', "TLS1.1 mode"}, -+#endif -+#ifndef OPENSSL_NO_TLS1_2 -+ {"tls1_2", OPT_TLS1_2, '-', "TLS1.2 mode"}, -+#endif -+#ifndef OPENSSL_NO_SSL_TRACE -+ {"stdname", OPT_STDNAME, '-', "Show standard cipher names"}, -+#endif -+#ifndef OPENSSL_NO_PSK -+ {"psk", OPT_PSK, '-', "include ciphersuites requiring PSK"}, -+#endif -+#ifndef OPENSSL_NO_SRP -+ {"srp", OPT_SRP, '-', "include ciphersuites requiring SRP"}, -+#endif -+ {NULL} -+}; -+ -+#ifndef OPENSSL_NO_PSK -+static unsigned int dummy_psk(SSL *ssl, const char *hint, char *identity, -+ unsigned int max_identity_len, -+ unsigned char *psk, -+ unsigned int max_psk_len) -+{ -+ return 0; -+} -+#endif -+#ifndef OPENSSL_NO_SRP -+static char *dummy_srp(SSL *ssl, void *arg) -+{ -+ return ""; -+} -+#endif -+ -+int ciphers_main(int argc, char **argv) -+{ -+ SSL_CTX *ctx = NULL; -+ SSL *ssl = NULL; -+ STACK_OF(SSL_CIPHER) *sk = NULL; -+ const SSL_METHOD *meth = TLS_server_method(); -+ int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0; -+#ifndef OPENSSL_NO_SSL_TRACE -+ int stdname = 0; -+#endif -+#ifndef OPENSSL_NO_PSK -+ int psk = 0; -+#endif -+#ifndef OPENSSL_NO_SRP -+ int srp = 0; -+#endif -+ const char *p; -+ char *ciphers = NULL, *prog; -+ char buf[512]; -+ OPTION_CHOICE o; -+ int min_version = 0, max_version = 0; -+ -+ prog = opt_init(argc, argv, ciphers_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(ciphers_options); -+ ret = 0; -+ goto end; -+ case OPT_V: -+ verbose = 1; -+ break; -+ case OPT_UPPER_V: -+ verbose = Verbose = 1; -+ break; -+ case OPT_S: -+ use_supported = 1; -+ break; -+ case OPT_STDNAME: -+#ifndef OPENSSL_NO_SSL_TRACE -+ stdname = verbose = 1; -+#endif -+ break; -+ case OPT_SSL3: -+ min_version = SSL3_VERSION; -+ max_version = SSL3_VERSION; -+ break; -+ case OPT_TLS1: -+ min_version = TLS1_VERSION; -+ max_version = TLS1_VERSION; -+ break; -+ case OPT_TLS1_1: -+ min_version = TLS1_1_VERSION; -+ max_version = TLS1_1_VERSION; -+ break; -+ case OPT_TLS1_2: -+ min_version = TLS1_2_VERSION; -+ max_version = TLS1_2_VERSION; -+ break; -+ case OPT_PSK: -+#ifndef OPENSSL_NO_PSK -+ psk = 1; -+#endif -+ break; -+ case OPT_SRP: -+#ifndef OPENSSL_NO_SRP -+ srp = 1; -+#endif -+ break; -+ } -+ } -+ argv = opt_rest(); -+ argc = opt_num_rest(); -+ -+ if (argc == 1) -+ ciphers = *argv; -+ else if (argc != 0) -+ goto opthelp; -+ -+ ctx = SSL_CTX_new(meth); -+ if (ctx == NULL) -+ goto err; -+ if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0) -+ goto err; -+ if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) -+ goto err; -+ -+#ifndef OPENSSL_NO_PSK -+ if (psk) -+ SSL_CTX_set_psk_client_callback(ctx, dummy_psk); -+#endif -+#ifndef OPENSSL_NO_SRP -+ if (srp) -+ SSL_CTX_set_srp_client_pwd_callback(ctx, dummy_srp); -+#endif -+ if (ciphers != NULL) { -+ if (!SSL_CTX_set_cipher_list(ctx, ciphers)) { -+ BIO_printf(bio_err, "Error in cipher list\n"); -+ goto err; -+ } -+ } -+ ssl = SSL_new(ctx); -+ if (ssl == NULL) -+ goto err; -+ -+ if (use_supported) -+ sk = SSL_get1_supported_ciphers(ssl); -+ else -+ sk = SSL_get_ciphers(ssl); -+ -+ if (!verbose) { -+ for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { -+ const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i); -+ p = SSL_CIPHER_get_name(c); -+ if (p == NULL) -+ break; -+ if (i != 0) -+ BIO_printf(bio_out, ":"); -+ BIO_printf(bio_out, "%s", p); -+ } -+ BIO_printf(bio_out, "\n"); -+ } else { -+ -+ for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { -+ const SSL_CIPHER *c; -+ -+ c = sk_SSL_CIPHER_value(sk, i); -+ -+ if (Verbose) { -+ unsigned long id = SSL_CIPHER_get_id(c); -+ int id0 = (int)(id >> 24); -+ int id1 = (int)((id >> 16) & 0xffL); -+ int id2 = (int)((id >> 8) & 0xffL); -+ int id3 = (int)(id & 0xffL); -+ -+ if ((id & 0xff000000L) == 0x03000000L) -+ BIO_printf(bio_out, " 0x%02X,0x%02X - ", id2, id3); /* SSL3 -+ * cipher */ -+ else -+ BIO_printf(bio_out, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */ -+ } -+#ifndef OPENSSL_NO_SSL_TRACE -+ if (stdname) { -+ const char *nm = SSL_CIPHER_standard_name(c); -+ if (nm == NULL) -+ nm = "UNKNOWN"; -+ BIO_printf(bio_out, "%s - ", nm); -+ } -+#endif -+ BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof buf)); -+ } -+ } -+ -+ ret = 0; -+ goto end; -+ err: -+ ERR_print_errors(bio_err); -+ end: -+ if (use_supported) -+ sk_SSL_CIPHER_free(sk); -+ SSL_CTX_free(ctx); -+ SSL_free(ssl); -+ return (ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/client.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/client.pem -new file mode 100644 -index 0000000..e7a47a7 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/client.pem -@@ -0,0 +1,52 @@ -+subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Client Cert -+issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA -+-----BEGIN CERTIFICATE----- -+MIID5zCCAs+gAwIBAgIJALnu1NlVpZ6yMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV -+BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT -+VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt -+ZWRpYXRlIENBMB4XDTExMTIwODE0MDE0OFoXDTIxMTAxNjE0MDE0OFowZDELMAkG -+A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU -+RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgQ2xpZW50IENlcnQw -+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0ranbHRLcLVqN+0BzcZpY -++yOLqxzDWT1LD9eW1stC4NzXX9/DCtSIVyN7YIHdGLrIPr64IDdXXaMRzgZ2rOKs -+lmHCAiFpO/ja99gGCJRxH0xwQatqAULfJVHeUhs7OEGOZc2nWifjqKvGfNTilP7D -+nwi69ipQFq9oS19FmhwVHk2wg7KZGHI1qDyG04UrfCZMRitvS9+UVhPpIPjuiBi2 -+x3/FZIpL5gXJvvFK6xHY63oq2asyzBATntBgnP4qJFWWcvRx24wF1PnZabxuVoL2 -+bPnQ/KvONDrw3IdqkKhYNTul7jEcu3OlcZIMw+7DiaKJLAzKb/bBF5gm/pwW6As9 -+AgMBAAGjgY8wgYwwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwLAYJYIZI -+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW -+BBSZHKyLoTh7Mb409Zn/mK1ceSDAjDAfBgNVHSMEGDAWgBQ2w2yI55X+sL3szj49 -+hqshgYfa2jANBgkqhkiG9w0BAQUFAAOCAQEAD0mL7PtPYgCEuDyOQSbLpeND5hVS -+curxQdGnrJ6Acrhodb7E9ccATokeb0PLx6HBLQUicxhTZIQ9FbO43YkQcOU6C3BB -+IlwskqmtN6+VmrQzNolHCDzvxNZs9lYL2VbGPGqVRyjZeHpoAlf9cQr8PgDb4d4b -+vUx2KAhHQvV2nkmYvKyXcgnRuHggumF87mkxidriGAEFwH4qfOqetUg64WyxP7P2 -+QLipm04SyQa7ONtIApfVXgHcE42Py4/f4arzCzMjKe3VyhGkS7nsT55X/fWgTaRm -+CQPkO+H94P958WTvQDt77bQ+D3IvYaVvfil8n6HJMOJfFT0LJuSUbpSXJg== -+-----END CERTIFICATE----- -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpQIBAAKCAQEAtK2p2x0S3C1ajftAc3GaWPsji6scw1k9Sw/XltbLQuDc11/f -+wwrUiFcje2CB3Ri6yD6+uCA3V12jEc4GdqzirJZhwgIhaTv42vfYBgiUcR9McEGr -+agFC3yVR3lIbOzhBjmXNp1on46irxnzU4pT+w58IuvYqUBavaEtfRZocFR5NsIOy -+mRhyNag8htOFK3wmTEYrb0vflFYT6SD47ogYtsd/xWSKS+YFyb7xSusR2Ot6Ktmr -+MswQE57QYJz+KiRVlnL0cduMBdT52Wm8blaC9mz50PyrzjQ68NyHapCoWDU7pe4x -+HLtzpXGSDMPuw4miiSwMym/2wReYJv6cFugLPQIDAQABAoIBAAZOyc9MhIwLSU4L -+p4RgQvM4UVVe8/Id+3XTZ8NsXExJbWxXfIhiqGjaIfL8u4vsgRjcl+v1s/jo2/iT -+KMab4o4D8gXD7UavQVDjtjb/ta79WL3SjRl2Uc9YjjMkyq6WmDNQeo2NKDdafCTB -+1uzSJtLNipB8Z53ELPuHJhxX9QMHrMnuha49riQgXZ7buP9iQrHJFhImBjSzbxJx -+L+TI6rkyLSf9Wi0Pd3L27Ob3QWNfNRYNSeTE+08eSRChkur5W0RuXAcuAICdQlCl -+LBvWO/LmmvbzCqiDcgy/TliSb6CGGwgiNG7LJZmlkYNj8laGwalNlYZs3UrVv6NO -+Br2loAECgYEA2kvCvPGj0Dg/6g7WhXDvAkEbcaL1tSeCxBbNH+6HS2UWMWvyTtCn -+/bbD519QIdkvayy1QjEf32GV/UjUVmlULMLBcDy0DGjtL3+XpIhLKWDNxN1v1/ai -+1oz23ZJCOgnk6K4qtFtlRS1XtynjA+rBetvYvLP9SKeFrnpzCgaA2r0CgYEA0+KX -+1ACXDTNH5ySX3kMjSS9xdINf+OOw4CvPHFwbtc9aqk2HePlEsBTz5I/W3rKwXva3 -+NqZ/bRqVVeZB/hHKFywgdUQk2Uc5z/S7Lw70/w1HubNTXGU06Ngb6zOFAo/o/TwZ -+zTP1BMIKSOB6PAZPS3l+aLO4FRIRotfFhgRHOoECgYEAmiZbqt8cJaJDB/5YYDzC -+mp3tSk6gIb936Q6M5VqkMYp9pIKsxhk0N8aDCnTU+kIK6SzWBpr3/d9Ecmqmfyq7 -+5SvWO3KyVf0WWK9KH0abhOm2BKm2HBQvI0DB5u8sUx2/hsvOnjPYDISbZ11t0MtK -+u35Zy89yMYcSsIYJjG/ROCUCgYEAgI2P9G5PNxEP5OtMwOsW84Y3Xat/hPAQFlI+ -+HES+AzbFGWJkeT8zL2nm95tVkFP1sggZ7Kxjz3w7cpx7GX0NkbWSE9O+T51pNASV -+tN1sQ3p5M+/a+cnlqgfEGJVvc7iAcXQPa3LEi5h2yPR49QYXAgG6cifn3dDSpmwn -+SUI7PQECgYEApGCIIpSRPLAEHTGmP87RBL1smurhwmy2s/pghkvUkWehtxg0sGHh -+kuaqDWcskogv+QC0sVdytiLSz8G0DwcEcsHK1Fkyb8A+ayiw6jWJDo2m9+IF4Fww -+1Te6jFPYDESnbhq7+TLGgHGhtwcu5cnb4vSuYXGXKupZGzoLOBbv1Zw= -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/cms.c b/CryptoPkg/Library/OpensslLib/openssl/apps/cms.c -new file mode 100644 -index 0000000..579b227 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/cms.c -@@ -0,0 +1,1294 @@ -+/* -+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* CMS utility function */ -+ -+#include -+#include -+#include "apps.h" -+ -+#ifndef OPENSSL_NO_CMS -+ -+# include -+# include -+# include -+# include -+# include -+# include -+ -+static int save_certs(char *signerfile, STACK_OF(X509) *signers); -+static int cms_cb(int ok, X509_STORE_CTX *ctx); -+static void receipt_request_print(CMS_ContentInfo *cms); -+static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) -+ *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING) -+ *rr_from); -+static int cms_set_pkey_param(EVP_PKEY_CTX *pctx, -+ STACK_OF(OPENSSL_STRING) *param); -+ -+# define SMIME_OP 0x10 -+# define SMIME_IP 0x20 -+# define SMIME_SIGNERS 0x40 -+# define SMIME_ENCRYPT (1 | SMIME_OP) -+# define SMIME_DECRYPT (2 | SMIME_IP) -+# define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS) -+# define SMIME_VERIFY (4 | SMIME_IP) -+# define SMIME_CMSOUT (5 | SMIME_IP | SMIME_OP) -+# define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) -+# define SMIME_DATAOUT (7 | SMIME_IP) -+# define SMIME_DATA_CREATE (8 | SMIME_OP) -+# define SMIME_DIGEST_VERIFY (9 | SMIME_IP) -+# define SMIME_DIGEST_CREATE (10 | SMIME_OP) -+# define SMIME_UNCOMPRESS (11 | SMIME_IP) -+# define SMIME_COMPRESS (12 | SMIME_OP) -+# define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP) -+# define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP) -+# define SMIME_SIGN_RECEIPT (15 | SMIME_IP | SMIME_OP) -+# define SMIME_VERIFY_RECEIPT (16 | SMIME_IP) -+ -+static int verify_err = 0; -+ -+typedef struct cms_key_param_st cms_key_param; -+ -+struct cms_key_param_st { -+ int idx; -+ STACK_OF(OPENSSL_STRING) *param; -+ cms_key_param *next; -+}; -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENCRYPT, -+ OPT_DECRYPT, OPT_SIGN, OPT_SIGN_RECEIPT, OPT_RESIGN, -+ OPT_VERIFY, OPT_VERIFY_RETCODE, OPT_VERIFY_RECEIPT, -+ OPT_CMSOUT, OPT_DATA_OUT, OPT_DATA_CREATE, OPT_DIGEST_VERIFY, -+ OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS, -+ OPT_ED_DECRYPT, OPT_ED_ENCRYPT, OPT_DEBUG_DECRYPT, OPT_TEXT, -+ OPT_ASCIICRLF, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCERTS, -+ OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP, OPT_BINARY, OPT_KEYID, -+ OPT_NOSIGS, OPT_NO_CONTENT_VERIFY, OPT_NO_ATTR_VERIFY, OPT_INDEF, -+ OPT_NOINDEF, OPT_CRLFEOL, OPT_NOOUT, OPT_RR_PRINT, -+ OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE, -+ OPT_CAPATH, OPT_NOCAPATH, OPT_NOCAFILE,OPT_CONTENT, OPT_PRINT, -+ OPT_SECRETKEY, OPT_SECRETKEYID, OPT_PWRI_PASSWORD, OPT_ECONTENT_TYPE, -+ OPT_RAND, OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, -+ OPT_CERTSOUT, OPT_MD, OPT_INKEY, OPT_KEYFORM, OPT_KEYOPT, OPT_RR_FROM, -+ OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP, -+ OPT_3DES_WRAP, OPT_ENGINE, -+ OPT_V_ENUM, -+ OPT_CIPHER -+} OPTION_CHOICE; -+ -+OPTIONS cms_options[] = { -+ {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"}, -+ {OPT_HELP_STR, 1, '-', -+ " cert.pem... recipient certs for encryption\n"}, -+ {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"}, -+ {"outform", OPT_OUTFORM, 'c', -+ "Output format SMIME (default), PEM or DER"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, -+ {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"}, -+ {"sign", OPT_SIGN, '-', "Sign message"}, -+ {"sign_receipt", OPT_SIGN_RECEIPT, '-', "Generate a signed receipt for the message"}, -+ {"resign", OPT_RESIGN, '-', "Resign a signed message"}, -+ {"verify", OPT_VERIFY, '-', "Verify signed message"}, -+ {"verify_retcode", OPT_VERIFY_RETCODE, '-'}, -+ {"verify_receipt", OPT_VERIFY_RECEIPT, '<'}, -+ {"cmsout", OPT_CMSOUT, '-', "Output CMS structure"}, -+ {"data_out", OPT_DATA_OUT, '-'}, -+ {"data_create", OPT_DATA_CREATE, '-'}, -+ {"digest_verify", OPT_DIGEST_VERIFY, '-'}, -+ {"digest_create", OPT_DIGEST_CREATE, '-'}, -+ {"compress", OPT_COMPRESS, '-'}, -+ {"uncompress", OPT_UNCOMPRESS, '-'}, -+ {"EncryptedData_decrypt", OPT_ED_DECRYPT, '-'}, -+ {"EncryptedData_encrypt", OPT_ED_ENCRYPT, '-'}, -+ {"debug_decrypt", OPT_DEBUG_DECRYPT, '-'}, -+ {"text", OPT_TEXT, '-', "Include or delete text MIME headers"}, -+ {"asciicrlf", OPT_ASCIICRLF, '-'}, -+ {"nointern", OPT_NOINTERN, '-', -+ "Don't search certificates in message for signer"}, -+ {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"}, -+ {"nocerts", OPT_NOCERTS, '-', -+ "Don't include signers certificate when signing"}, -+ {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"}, -+ {"nodetach", OPT_NODETACH, '-', "Use opaque signing"}, -+ {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"}, -+ {"binary", OPT_BINARY, '-', "Don't translate message to text"}, -+ {"keyid", OPT_KEYID, '-', "Use subject key identifier"}, -+ {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"}, -+ {"no_content_verify", OPT_NO_CONTENT_VERIFY, '-'}, -+ {"no_attr_verify", OPT_NO_ATTR_VERIFY, '-'}, -+ {"stream", OPT_INDEF, '-', "Enable CMS streaming"}, -+ {"indef", OPT_INDEF, '-', "Same as -stream"}, -+ {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"}, -+ {"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only" }, -+ {"noout", OPT_NOOUT, '-', "For the -cmsout operation do not output the parsed CMS structure"}, -+ {"receipt_request_print", OPT_RR_PRINT, '-', "Print CMS Receipt Request" }, -+ {"receipt_request_all", OPT_RR_ALL, '-'}, -+ {"receipt_request_first", OPT_RR_FIRST, '-'}, -+ {"rctform", OPT_RCTFORM, 'F', "Receipt file format"}, -+ {"certfile", OPT_CERTFILE, '<', "Other certificates file"}, -+ {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, -+ {"CApath", OPT_CAPATH, '/', "trusted certificates directory"}, -+ {"no-CAfile", OPT_NOCAFILE, '-', -+ "Do not load the default certificates file"}, -+ {"no-CApath", OPT_NOCAPATH, '-', -+ "Do not load certificates from the default certificates directory"}, -+ {"content", OPT_CONTENT, '<', -+ "Supply or override content for detached signature"}, -+ {"print", OPT_PRINT, '-', -+ "For the -cmsout operation print out all fields of the CMS structure"}, -+ {"secretkey", OPT_SECRETKEY, 's'}, -+ {"secretkeyid", OPT_SECRETKEYID, 's'}, -+ {"pwri_password", OPT_PWRI_PASSWORD, 's'}, -+ {"econtent_type", OPT_ECONTENT_TYPE, 's'}, -+ {"rand", OPT_RAND, 's', -+ "Load the file(s) into the random number generator"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+ {"to", OPT_TO, 's', "To address"}, -+ {"from", OPT_FROM, 's', "From address"}, -+ {"subject", OPT_SUBJECT, 's', "Subject"}, -+ {"signer", OPT_SIGNER, 's', "Signer certificate file"}, -+ {"recip", OPT_RECIP, '<', "Recipient cert file for decryption"}, -+ {"certsout", OPT_CERTSOUT, '>', "Certificate output file"}, -+ {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"}, -+ {"inkey", OPT_INKEY, 's', -+ "Input private key (if not signer or recipient)"}, -+ {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"}, -+ {"keyopt", OPT_KEYOPT, 's', "Set public key parameters as n:v pairs"}, -+ {"receipt_request_from", OPT_RR_FROM, 's'}, -+ {"receipt_request_to", OPT_RR_TO, 's'}, -+ {"", OPT_CIPHER, '-', "Any supported cipher"}, -+ OPT_V_OPTIONS, -+ {"aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key"}, -+ {"aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key"}, -+ {"aes256-wrap", OPT_AES256_WRAP, '-', "Use AES256 to wrap key"}, -+# ifndef OPENSSL_NO_DES -+ {"des3-wrap", OPT_3DES_WRAP, '-', "Use 3DES-EDE to wrap key"}, -+# endif -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+int cms_main(int argc, char **argv) -+{ -+ ASN1_OBJECT *econtent_type = NULL; -+ BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; -+ CMS_ContentInfo *cms = NULL, *rcms = NULL; -+ CMS_ReceiptRequest *rr = NULL; -+ ENGINE *e = NULL; -+ EVP_PKEY *key = NULL; -+ const EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL; -+ const EVP_MD *sign_md = NULL; -+ STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; -+ STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; -+ STACK_OF(X509) *encerts = NULL, *other = NULL; -+ X509 *cert = NULL, *recip = NULL, *signer = NULL; -+ X509_STORE *store = NULL; -+ X509_VERIFY_PARAM *vpm = NULL; -+ char *certfile = NULL, *keyfile = NULL, *contfile = NULL; -+ const char *CAfile = NULL, *CApath = NULL; -+ char *certsoutfile = NULL; -+ int noCAfile = 0, noCApath = 0; -+ char *infile = NULL, *outfile = NULL, *rctfile = NULL, *inrand = NULL; -+ char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = -+ NULL; -+ char *to = NULL, *from = NULL, *subject = NULL, *prog; -+ cms_key_param *key_first = NULL, *key_param = NULL; -+ int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched = -+ 0; -+ int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; -+ int need_rand = 0, operation = 0, ret = 1, rr_print = 0, rr_allorfirst = -+ -1; -+ int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; -+ size_t secret_keylen = 0, secret_keyidlen = 0; -+ unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; -+ unsigned char *secret_key = NULL, *secret_keyid = NULL; -+ long ltmp; -+ const char *mime_eol = "\n"; -+ OPTION_CHOICE o; -+ -+ if ((vpm = X509_VERIFY_PARAM_new()) == NULL) -+ return 1; -+ -+ prog = opt_init(argc, argv, cms_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(cms_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PDS, &informat)) -+ goto opthelp; -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PDS, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_ENCRYPT: -+ operation = SMIME_ENCRYPT; -+ break; -+ case OPT_DECRYPT: -+ operation = SMIME_DECRYPT; -+ break; -+ case OPT_SIGN: -+ operation = SMIME_SIGN; -+ break; -+ case OPT_SIGN_RECEIPT: -+ operation = SMIME_SIGN_RECEIPT; -+ break; -+ case OPT_RESIGN: -+ operation = SMIME_RESIGN; -+ break; -+ case OPT_VERIFY: -+ operation = SMIME_VERIFY; -+ break; -+ case OPT_VERIFY_RETCODE: -+ verify_retcode = 1; -+ break; -+ case OPT_VERIFY_RECEIPT: -+ operation = SMIME_VERIFY_RECEIPT; -+ rctfile = opt_arg(); -+ break; -+ case OPT_CMSOUT: -+ operation = SMIME_CMSOUT; -+ break; -+ case OPT_DATA_OUT: -+ operation = SMIME_DATAOUT; -+ break; -+ case OPT_DATA_CREATE: -+ operation = SMIME_DATA_CREATE; -+ break; -+ case OPT_DIGEST_VERIFY: -+ operation = SMIME_DIGEST_VERIFY; -+ break; -+ case OPT_DIGEST_CREATE: -+ operation = SMIME_DIGEST_CREATE; -+ break; -+ case OPT_COMPRESS: -+ operation = SMIME_COMPRESS; -+ break; -+ case OPT_UNCOMPRESS: -+ operation = SMIME_UNCOMPRESS; -+ break; -+ case OPT_ED_DECRYPT: -+ operation = SMIME_ENCRYPTED_DECRYPT; -+ break; -+ case OPT_ED_ENCRYPT: -+ operation = SMIME_ENCRYPTED_ENCRYPT; -+ break; -+ case OPT_DEBUG_DECRYPT: -+ flags |= CMS_DEBUG_DECRYPT; -+ break; -+ case OPT_TEXT: -+ flags |= CMS_TEXT; -+ break; -+ case OPT_ASCIICRLF: -+ flags |= CMS_ASCIICRLF; -+ break; -+ case OPT_NOINTERN: -+ flags |= CMS_NOINTERN; -+ break; -+ case OPT_NOVERIFY: -+ flags |= CMS_NO_SIGNER_CERT_VERIFY; -+ break; -+ case OPT_NOCERTS: -+ flags |= CMS_NOCERTS; -+ break; -+ case OPT_NOATTR: -+ flags |= CMS_NOATTR; -+ break; -+ case OPT_NODETACH: -+ flags &= ~CMS_DETACHED; -+ break; -+ case OPT_NOSMIMECAP: -+ flags |= CMS_NOSMIMECAP; -+ break; -+ case OPT_BINARY: -+ flags |= CMS_BINARY; -+ break; -+ case OPT_KEYID: -+ flags |= CMS_USE_KEYID; -+ break; -+ case OPT_NOSIGS: -+ flags |= CMS_NOSIGS; -+ break; -+ case OPT_NO_CONTENT_VERIFY: -+ flags |= CMS_NO_CONTENT_VERIFY; -+ break; -+ case OPT_NO_ATTR_VERIFY: -+ flags |= CMS_NO_ATTR_VERIFY; -+ break; -+ case OPT_INDEF: -+ flags |= CMS_STREAM; -+ break; -+ case OPT_NOINDEF: -+ flags &= ~CMS_STREAM; -+ break; -+ case OPT_CRLFEOL: -+ mime_eol = "\r\n"; -+ flags |= CMS_CRLFEOL; -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ case OPT_RR_PRINT: -+ rr_print = 1; -+ break; -+ case OPT_RR_ALL: -+ rr_allorfirst = 0; -+ break; -+ case OPT_RR_FIRST: -+ rr_allorfirst = 1; -+ break; -+ case OPT_RCTFORM: -+ if (rctformat == FORMAT_SMIME) -+ rcms = SMIME_read_CMS(rctin, NULL); -+ else if (rctformat == FORMAT_PEM) -+ rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); -+ else if (rctformat == FORMAT_ASN1) -+ if (!opt_format(opt_arg(), -+ OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat)) -+ goto opthelp; -+ break; -+ case OPT_CERTFILE: -+ certfile = opt_arg(); -+ break; -+ case OPT_CAFILE: -+ CAfile = opt_arg(); -+ break; -+ case OPT_CAPATH: -+ CApath = opt_arg(); -+ break; -+ case OPT_NOCAFILE: -+ noCAfile = 1; -+ break; -+ case OPT_NOCAPATH: -+ noCApath = 1; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_CONTENT: -+ contfile = opt_arg(); -+ break; -+ case OPT_RR_FROM: -+ if (rr_from == NULL -+ && (rr_from = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ sk_OPENSSL_STRING_push(rr_from, opt_arg()); -+ break; -+ case OPT_RR_TO: -+ if (rr_to == NULL -+ && (rr_to = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ sk_OPENSSL_STRING_push(rr_to, opt_arg()); -+ break; -+ case OPT_PRINT: -+ noout = print = 1; -+ break; -+ case OPT_SECRETKEY: -+ if (secret_key != NULL) { -+ BIO_printf(bio_err, "Invalid key (supplied twice) %s\n", -+ opt_arg()); -+ goto opthelp; -+ } -+ secret_key = OPENSSL_hexstr2buf(opt_arg(), <mp); -+ if (secret_key == NULL) { -+ BIO_printf(bio_err, "Invalid key %s\n", opt_arg()); -+ goto end; -+ } -+ secret_keylen = (size_t)ltmp; -+ break; -+ case OPT_SECRETKEYID: -+ if (secret_keyid != NULL) { -+ BIO_printf(bio_err, "Invalid id (supplied twice) %s\n", -+ opt_arg()); -+ goto opthelp; -+ } -+ secret_keyid = OPENSSL_hexstr2buf(opt_arg(), <mp); -+ if (secret_keyid == NULL) { -+ BIO_printf(bio_err, "Invalid id %s\n", opt_arg()); -+ goto opthelp; -+ } -+ secret_keyidlen = (size_t)ltmp; -+ break; -+ case OPT_PWRI_PASSWORD: -+ pwri_pass = (unsigned char *)opt_arg(); -+ break; -+ case OPT_ECONTENT_TYPE: -+ if (econtent_type != NULL) { -+ BIO_printf(bio_err, "Invalid OID (supplied twice) %s\n", -+ opt_arg()); -+ goto opthelp; -+ } -+ econtent_type = OBJ_txt2obj(opt_arg(), 0); -+ if (econtent_type == NULL) { -+ BIO_printf(bio_err, "Invalid OID %s\n", opt_arg()); -+ goto opthelp; -+ } -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ need_rand = 1; -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ case OPT_TO: -+ to = opt_arg(); -+ break; -+ case OPT_FROM: -+ from = opt_arg(); -+ break; -+ case OPT_SUBJECT: -+ subject = opt_arg(); -+ break; -+ case OPT_CERTSOUT: -+ certsoutfile = opt_arg(); -+ break; -+ case OPT_MD: -+ if (!opt_md(opt_arg(), &sign_md)) -+ goto end; -+ break; -+ case OPT_SIGNER: -+ /* If previous -signer argument add signer to list */ -+ if (signerfile) { -+ if (sksigners == NULL -+ && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ sk_OPENSSL_STRING_push(sksigners, signerfile); -+ if (keyfile == NULL) -+ keyfile = signerfile; -+ if (skkeys == NULL -+ && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ sk_OPENSSL_STRING_push(skkeys, keyfile); -+ keyfile = NULL; -+ } -+ signerfile = opt_arg(); -+ break; -+ case OPT_INKEY: -+ /* If previous -inkey argument add signer to list */ -+ if (keyfile) { -+ if (signerfile == NULL) { -+ BIO_puts(bio_err, "Illegal -inkey without -signer\n"); -+ goto end; -+ } -+ if (sksigners == NULL -+ && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ sk_OPENSSL_STRING_push(sksigners, signerfile); -+ signerfile = NULL; -+ if (skkeys == NULL -+ && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ sk_OPENSSL_STRING_push(skkeys, keyfile); -+ } -+ keyfile = opt_arg(); -+ break; -+ case OPT_KEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) -+ goto opthelp; -+ break; -+ case OPT_RECIP: -+ if (operation == SMIME_ENCRYPT) { -+ if (encerts == NULL && (encerts = sk_X509_new_null()) == NULL) -+ goto end; -+ cert = load_cert(opt_arg(), FORMAT_PEM, -+ "recipient certificate file"); -+ if (cert == NULL) -+ goto end; -+ sk_X509_push(encerts, cert); -+ cert = NULL; -+ } else -+ recipfile = opt_arg(); -+ break; -+ case OPT_CIPHER: -+ if (!opt_cipher(opt_unknown(), &cipher)) -+ goto end; -+ break; -+ case OPT_KEYOPT: -+ keyidx = -1; -+ if (operation == SMIME_ENCRYPT) { -+ if (encerts) -+ keyidx += sk_X509_num(encerts); -+ } else { -+ if (keyfile || signerfile) -+ keyidx++; -+ if (skkeys) -+ keyidx += sk_OPENSSL_STRING_num(skkeys); -+ } -+ if (keyidx < 0) { -+ BIO_printf(bio_err, "No key specified\n"); -+ goto opthelp; -+ } -+ if (key_param == NULL || key_param->idx != keyidx) { -+ cms_key_param *nparam; -+ nparam = app_malloc(sizeof(*nparam), "key param buffer"); -+ nparam->idx = keyidx; -+ if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ nparam->next = NULL; -+ if (key_first == NULL) -+ key_first = nparam; -+ else -+ key_param->next = nparam; -+ key_param = nparam; -+ } -+ sk_OPENSSL_STRING_push(key_param->param, opt_arg()); -+ break; -+ case OPT_V_CASES: -+ if (!opt_verify(o, vpm)) -+ goto end; -+ vpmtouched++; -+ break; -+ case OPT_3DES_WRAP: -+# ifndef OPENSSL_NO_DES -+ wrap_cipher = EVP_des_ede3_wrap(); -+# endif -+ break; -+ case OPT_AES128_WRAP: -+ wrap_cipher = EVP_aes_128_wrap(); -+ break; -+ case OPT_AES192_WRAP: -+ wrap_cipher = EVP_aes_192_wrap(); -+ break; -+ case OPT_AES256_WRAP: -+ wrap_cipher = EVP_aes_256_wrap(); -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ -+ if (((rr_allorfirst != -1) || rr_from) && !rr_to) { -+ BIO_puts(bio_err, "No Signed Receipts Recipients\n"); -+ goto opthelp; -+ } -+ -+ if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) { -+ BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); -+ goto opthelp; -+ } -+ if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { -+ BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); -+ goto opthelp; -+ } -+ -+ if (operation & SMIME_SIGNERS) { -+ if (keyfile && !signerfile) { -+ BIO_puts(bio_err, "Illegal -inkey without -signer\n"); -+ goto opthelp; -+ } -+ /* Check to see if any final signer needs to be appended */ -+ if (signerfile) { -+ if (!sksigners -+ && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ sk_OPENSSL_STRING_push(sksigners, signerfile); -+ if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ if (!keyfile) -+ keyfile = signerfile; -+ sk_OPENSSL_STRING_push(skkeys, keyfile); -+ } -+ if (!sksigners) { -+ BIO_printf(bio_err, "No signer certificate specified\n"); -+ goto opthelp; -+ } -+ signerfile = NULL; -+ keyfile = NULL; -+ need_rand = 1; -+ } -+ -+ else if (operation == SMIME_DECRYPT) { -+ if (!recipfile && !keyfile && !secret_key && !pwri_pass) { -+ BIO_printf(bio_err, -+ "No recipient certificate or key specified\n"); -+ goto opthelp; -+ } -+ } else if (operation == SMIME_ENCRYPT) { -+ if (*argv == NULL && !secret_key && !pwri_pass && !encerts) { -+ BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); -+ goto opthelp; -+ } -+ need_rand = 1; -+ } else if (!operation) -+ goto opthelp; -+ -+ if (!app_passwd(passinarg, NULL, &passin, NULL)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ -+ if (need_rand) { -+ app_RAND_load_file(NULL, (inrand != NULL)); -+ if (inrand != NULL) -+ BIO_printf(bio_err, "%ld semi-random bytes loaded\n", -+ app_RAND_load_files(inrand)); -+ } -+ -+ ret = 2; -+ -+ if (!(operation & SMIME_SIGNERS)) -+ flags &= ~CMS_DETACHED; -+ -+ if (!(operation & SMIME_OP)) { -+ if (flags & CMS_BINARY) -+ outformat = FORMAT_BINARY; -+ } -+ -+ if (!(operation & SMIME_IP)) { -+ if (flags & CMS_BINARY) -+ informat = FORMAT_BINARY; -+ } -+ -+ if (operation == SMIME_ENCRYPT) { -+ if (!cipher) { -+# ifndef OPENSSL_NO_DES -+ cipher = EVP_des_ede3_cbc(); -+# else -+ BIO_printf(bio_err, "No cipher selected\n"); -+ goto end; -+# endif -+ } -+ -+ if (secret_key && !secret_keyid) { -+ BIO_printf(bio_err, "No secret key id\n"); -+ goto end; -+ } -+ -+ if (*argv && !encerts) -+ if ((encerts = sk_X509_new_null()) == NULL) -+ goto end; -+ while (*argv) { -+ if ((cert = load_cert(*argv, FORMAT_PEM, -+ "recipient certificate file")) == NULL) -+ goto end; -+ sk_X509_push(encerts, cert); -+ cert = NULL; -+ argv++; -+ } -+ } -+ -+ if (certfile) { -+ if (!load_certs(certfile, &other, FORMAT_PEM, NULL, -+ "certificate file")) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (recipfile && (operation == SMIME_DECRYPT)) { -+ if ((recip = load_cert(recipfile, FORMAT_PEM, -+ "recipient certificate file")) == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (operation == SMIME_SIGN_RECEIPT) { -+ if ((signer = load_cert(signerfile, FORMAT_PEM, -+ "receipt signer certificate file")) == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (operation == SMIME_DECRYPT) { -+ if (!keyfile) -+ keyfile = recipfile; -+ } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) { -+ if (!keyfile) -+ keyfile = signerfile; -+ } else -+ keyfile = NULL; -+ -+ if (keyfile) { -+ key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); -+ if (!key) -+ goto end; -+ } -+ -+ in = bio_open_default(infile, 'r', informat); -+ if (in == NULL) -+ goto end; -+ -+ if (operation & SMIME_IP) { -+ if (informat == FORMAT_SMIME) -+ cms = SMIME_read_CMS(in, &indata); -+ else if (informat == FORMAT_PEM) -+ cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); -+ else if (informat == FORMAT_ASN1) -+ cms = d2i_CMS_bio(in, NULL); -+ else { -+ BIO_printf(bio_err, "Bad input format for CMS file\n"); -+ goto end; -+ } -+ -+ if (!cms) { -+ BIO_printf(bio_err, "Error reading S/MIME message\n"); -+ goto end; -+ } -+ if (contfile) { -+ BIO_free(indata); -+ if ((indata = BIO_new_file(contfile, "rb")) == NULL) { -+ BIO_printf(bio_err, "Can't read content file %s\n", contfile); -+ goto end; -+ } -+ } -+ if (certsoutfile) { -+ STACK_OF(X509) *allcerts; -+ allcerts = CMS_get1_certs(cms); -+ if (!save_certs(certsoutfile, allcerts)) { -+ BIO_printf(bio_err, -+ "Error writing certs to %s\n", certsoutfile); -+ ret = 5; -+ goto end; -+ } -+ sk_X509_pop_free(allcerts, X509_free); -+ } -+ } -+ -+ if (rctfile) { -+ char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r"; -+ if ((rctin = BIO_new_file(rctfile, rctmode)) == NULL) { -+ BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile); -+ goto end; -+ } -+ -+ if (rctformat == FORMAT_SMIME) -+ rcms = SMIME_read_CMS(rctin, NULL); -+ else if (rctformat == FORMAT_PEM) -+ rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); -+ else if (rctformat == FORMAT_ASN1) -+ rcms = d2i_CMS_bio(rctin, NULL); -+ else { -+ BIO_printf(bio_err, "Bad input format for receipt\n"); -+ goto end; -+ } -+ -+ if (!rcms) { -+ BIO_printf(bio_err, "Error reading receipt\n"); -+ goto end; -+ } -+ } -+ -+ out = bio_open_default(outfile, 'w', outformat); -+ if (out == NULL) -+ goto end; -+ -+ if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) { -+ if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) -+ goto end; -+ X509_STORE_set_verify_cb(store, cms_cb); -+ if (vpmtouched) -+ X509_STORE_set1_param(store, vpm); -+ } -+ -+ ret = 3; -+ -+ if (operation == SMIME_DATA_CREATE) { -+ cms = CMS_data_create(in, flags); -+ } else if (operation == SMIME_DIGEST_CREATE) { -+ cms = CMS_digest_create(in, sign_md, flags); -+ } else if (operation == SMIME_COMPRESS) { -+ cms = CMS_compress(in, -1, flags); -+ } else if (operation == SMIME_ENCRYPT) { -+ int i; -+ flags |= CMS_PARTIAL; -+ cms = CMS_encrypt(NULL, in, cipher, flags); -+ if (!cms) -+ goto end; -+ for (i = 0; i < sk_X509_num(encerts); i++) { -+ CMS_RecipientInfo *ri; -+ cms_key_param *kparam; -+ int tflags = flags; -+ X509 *x = sk_X509_value(encerts, i); -+ for (kparam = key_first; kparam; kparam = kparam->next) { -+ if (kparam->idx == i) { -+ tflags |= CMS_KEY_PARAM; -+ break; -+ } -+ } -+ ri = CMS_add1_recipient_cert(cms, x, tflags); -+ if (!ri) -+ goto end; -+ if (kparam) { -+ EVP_PKEY_CTX *pctx; -+ pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); -+ if (!cms_set_pkey_param(pctx, kparam->param)) -+ goto end; -+ } -+ if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE -+ && wrap_cipher) { -+ EVP_CIPHER_CTX *wctx; -+ wctx = CMS_RecipientInfo_kari_get0_ctx(ri); -+ EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL); -+ } -+ } -+ -+ if (secret_key) { -+ if (!CMS_add0_recipient_key(cms, NID_undef, -+ secret_key, secret_keylen, -+ secret_keyid, secret_keyidlen, -+ NULL, NULL, NULL)) -+ goto end; -+ /* NULL these because call absorbs them */ -+ secret_key = NULL; -+ secret_keyid = NULL; -+ } -+ if (pwri_pass) { -+ pwri_tmp = (unsigned char *)OPENSSL_strdup((char *)pwri_pass); -+ if (!pwri_tmp) -+ goto end; -+ if (!CMS_add0_recipient_password(cms, -+ -1, NID_undef, NID_undef, -+ pwri_tmp, -1, NULL)) -+ goto end; -+ pwri_tmp = NULL; -+ } -+ if (!(flags & CMS_STREAM)) { -+ if (!CMS_final(cms, in, NULL, flags)) -+ goto end; -+ } -+ } else if (operation == SMIME_ENCRYPTED_ENCRYPT) { -+ cms = CMS_EncryptedData_encrypt(in, cipher, -+ secret_key, secret_keylen, flags); -+ -+ } else if (operation == SMIME_SIGN_RECEIPT) { -+ CMS_ContentInfo *srcms = NULL; -+ STACK_OF(CMS_SignerInfo) *sis; -+ CMS_SignerInfo *si; -+ sis = CMS_get0_SignerInfos(cms); -+ if (!sis) -+ goto end; -+ si = sk_CMS_SignerInfo_value(sis, 0); -+ srcms = CMS_sign_receipt(si, signer, key, other, flags); -+ if (!srcms) -+ goto end; -+ CMS_ContentInfo_free(cms); -+ cms = srcms; -+ } else if (operation & SMIME_SIGNERS) { -+ int i; -+ /* -+ * If detached data content we enable streaming if S/MIME output -+ * format. -+ */ -+ if (operation == SMIME_SIGN) { -+ -+ if (flags & CMS_DETACHED) { -+ if (outformat == FORMAT_SMIME) -+ flags |= CMS_STREAM; -+ } -+ flags |= CMS_PARTIAL; -+ cms = CMS_sign(NULL, NULL, other, in, flags); -+ if (!cms) -+ goto end; -+ if (econtent_type) -+ CMS_set1_eContentType(cms, econtent_type); -+ -+ if (rr_to) { -+ rr = make_receipt_request(rr_to, rr_allorfirst, rr_from); -+ if (!rr) { -+ BIO_puts(bio_err, -+ "Signed Receipt Request Creation Error\n"); -+ goto end; -+ } -+ } -+ } else -+ flags |= CMS_REUSE_DIGEST; -+ for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { -+ CMS_SignerInfo *si; -+ cms_key_param *kparam; -+ int tflags = flags; -+ signerfile = sk_OPENSSL_STRING_value(sksigners, i); -+ keyfile = sk_OPENSSL_STRING_value(skkeys, i); -+ -+ signer = load_cert(signerfile, FORMAT_PEM, "signer certificate"); -+ if (!signer) -+ goto end; -+ key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); -+ if (!key) -+ goto end; -+ for (kparam = key_first; kparam; kparam = kparam->next) { -+ if (kparam->idx == i) { -+ tflags |= CMS_KEY_PARAM; -+ break; -+ } -+ } -+ si = CMS_add1_signer(cms, signer, key, sign_md, tflags); -+ if (!si) -+ goto end; -+ if (kparam) { -+ EVP_PKEY_CTX *pctx; -+ pctx = CMS_SignerInfo_get0_pkey_ctx(si); -+ if (!cms_set_pkey_param(pctx, kparam->param)) -+ goto end; -+ } -+ if (rr && !CMS_add1_ReceiptRequest(si, rr)) -+ goto end; -+ X509_free(signer); -+ signer = NULL; -+ EVP_PKEY_free(key); -+ key = NULL; -+ } -+ /* If not streaming or resigning finalize structure */ -+ if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) { -+ if (!CMS_final(cms, in, NULL, flags)) -+ goto end; -+ } -+ } -+ -+ if (!cms) { -+ BIO_printf(bio_err, "Error creating CMS structure\n"); -+ goto end; -+ } -+ -+ ret = 4; -+ if (operation == SMIME_DECRYPT) { -+ if (flags & CMS_DEBUG_DECRYPT) -+ CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags); -+ -+ if (secret_key) { -+ if (!CMS_decrypt_set1_key(cms, -+ secret_key, secret_keylen, -+ secret_keyid, secret_keyidlen)) { -+ BIO_puts(bio_err, "Error decrypting CMS using secret key\n"); -+ goto end; -+ } -+ } -+ -+ if (key) { -+ if (!CMS_decrypt_set1_pkey(cms, key, recip)) { -+ BIO_puts(bio_err, "Error decrypting CMS using private key\n"); -+ goto end; -+ } -+ } -+ -+ if (pwri_pass) { -+ if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) { -+ BIO_puts(bio_err, "Error decrypting CMS using password\n"); -+ goto end; -+ } -+ } -+ -+ if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) { -+ BIO_printf(bio_err, "Error decrypting CMS structure\n"); -+ goto end; -+ } -+ } else if (operation == SMIME_DATAOUT) { -+ if (!CMS_data(cms, out, flags)) -+ goto end; -+ } else if (operation == SMIME_UNCOMPRESS) { -+ if (!CMS_uncompress(cms, indata, out, flags)) -+ goto end; -+ } else if (operation == SMIME_DIGEST_VERIFY) { -+ if (CMS_digest_verify(cms, indata, out, flags) > 0) -+ BIO_printf(bio_err, "Verification successful\n"); -+ else { -+ BIO_printf(bio_err, "Verification failure\n"); -+ goto end; -+ } -+ } else if (operation == SMIME_ENCRYPTED_DECRYPT) { -+ if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen, -+ indata, out, flags)) -+ goto end; -+ } else if (operation == SMIME_VERIFY) { -+ if (CMS_verify(cms, other, store, indata, out, flags) > 0) -+ BIO_printf(bio_err, "Verification successful\n"); -+ else { -+ BIO_printf(bio_err, "Verification failure\n"); -+ if (verify_retcode) -+ ret = verify_err + 32; -+ goto end; -+ } -+ if (signerfile) { -+ STACK_OF(X509) *signers; -+ signers = CMS_get0_signers(cms); -+ if (!save_certs(signerfile, signers)) { -+ BIO_printf(bio_err, -+ "Error writing signers to %s\n", signerfile); -+ ret = 5; -+ goto end; -+ } -+ sk_X509_free(signers); -+ } -+ if (rr_print) -+ receipt_request_print(cms); -+ -+ } else if (operation == SMIME_VERIFY_RECEIPT) { -+ if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) -+ BIO_printf(bio_err, "Verification successful\n"); -+ else { -+ BIO_printf(bio_err, "Verification failure\n"); -+ goto end; -+ } -+ } else { -+ if (noout) { -+ if (print) -+ CMS_ContentInfo_print_ctx(out, cms, 0, NULL); -+ } else if (outformat == FORMAT_SMIME) { -+ if (to) -+ BIO_printf(out, "To: %s%s", to, mime_eol); -+ if (from) -+ BIO_printf(out, "From: %s%s", from, mime_eol); -+ if (subject) -+ BIO_printf(out, "Subject: %s%s", subject, mime_eol); -+ if (operation == SMIME_RESIGN) -+ ret = SMIME_write_CMS(out, cms, indata, flags); -+ else -+ ret = SMIME_write_CMS(out, cms, in, flags); -+ } else if (outformat == FORMAT_PEM) -+ ret = PEM_write_bio_CMS_stream(out, cms, in, flags); -+ else if (outformat == FORMAT_ASN1) -+ ret = i2d_CMS_bio_stream(out, cms, in, flags); -+ else { -+ BIO_printf(bio_err, "Bad output format for CMS file\n"); -+ goto end; -+ } -+ if (ret <= 0) { -+ ret = 6; -+ goto end; -+ } -+ } -+ ret = 0; -+ end: -+ if (ret) -+ ERR_print_errors(bio_err); -+ if (need_rand) -+ app_RAND_write_file(NULL); -+ sk_X509_pop_free(encerts, X509_free); -+ sk_X509_pop_free(other, X509_free); -+ X509_VERIFY_PARAM_free(vpm); -+ sk_OPENSSL_STRING_free(sksigners); -+ sk_OPENSSL_STRING_free(skkeys); -+ OPENSSL_free(secret_key); -+ OPENSSL_free(secret_keyid); -+ OPENSSL_free(pwri_tmp); -+ ASN1_OBJECT_free(econtent_type); -+ CMS_ReceiptRequest_free(rr); -+ sk_OPENSSL_STRING_free(rr_to); -+ sk_OPENSSL_STRING_free(rr_from); -+ for (key_param = key_first; key_param;) { -+ cms_key_param *tparam; -+ sk_OPENSSL_STRING_free(key_param->param); -+ tparam = key_param->next; -+ OPENSSL_free(key_param); -+ key_param = tparam; -+ } -+ X509_STORE_free(store); -+ X509_free(cert); -+ X509_free(recip); -+ X509_free(signer); -+ EVP_PKEY_free(key); -+ CMS_ContentInfo_free(cms); -+ CMS_ContentInfo_free(rcms); -+ release_engine(e); -+ BIO_free(rctin); -+ BIO_free(in); -+ BIO_free(indata); -+ BIO_free_all(out); -+ OPENSSL_free(passin); -+ return (ret); -+} -+ -+static int save_certs(char *signerfile, STACK_OF(X509) *signers) -+{ -+ int i; -+ BIO *tmp; -+ if (!signerfile) -+ return 1; -+ tmp = BIO_new_file(signerfile, "w"); -+ if (!tmp) -+ return 0; -+ for (i = 0; i < sk_X509_num(signers); i++) -+ PEM_write_bio_X509(tmp, sk_X509_value(signers, i)); -+ BIO_free(tmp); -+ return 1; -+} -+ -+/* Minimal callback just to output policy info (if any) */ -+ -+static int cms_cb(int ok, X509_STORE_CTX *ctx) -+{ -+ int error; -+ -+ error = X509_STORE_CTX_get_error(ctx); -+ -+ verify_err = error; -+ -+ if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) -+ && ((error != X509_V_OK) || (ok != 2))) -+ return ok; -+ -+ policies_print(ctx); -+ -+ return ok; -+ -+} -+ -+static void gnames_stack_print(STACK_OF(GENERAL_NAMES) *gns) -+{ -+ STACK_OF(GENERAL_NAME) *gens; -+ GENERAL_NAME *gen; -+ int i, j; -+ -+ for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) { -+ gens = sk_GENERAL_NAMES_value(gns, i); -+ for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) { -+ gen = sk_GENERAL_NAME_value(gens, j); -+ BIO_puts(bio_err, " "); -+ GENERAL_NAME_print(bio_err, gen); -+ BIO_puts(bio_err, "\n"); -+ } -+ } -+ return; -+} -+ -+static void receipt_request_print(CMS_ContentInfo *cms) -+{ -+ STACK_OF(CMS_SignerInfo) *sis; -+ CMS_SignerInfo *si; -+ CMS_ReceiptRequest *rr; -+ int allorfirst; -+ STACK_OF(GENERAL_NAMES) *rto, *rlist; -+ ASN1_STRING *scid; -+ int i, rv; -+ sis = CMS_get0_SignerInfos(cms); -+ for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) { -+ si = sk_CMS_SignerInfo_value(sis, i); -+ rv = CMS_get1_ReceiptRequest(si, &rr); -+ BIO_printf(bio_err, "Signer %d:\n", i + 1); -+ if (rv == 0) -+ BIO_puts(bio_err, " No Receipt Request\n"); -+ else if (rv < 0) { -+ BIO_puts(bio_err, " Receipt Request Parse Error\n"); -+ ERR_print_errors(bio_err); -+ } else { -+ const char *id; -+ int idlen; -+ CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst, -+ &rlist, &rto); -+ BIO_puts(bio_err, " Signed Content ID:\n"); -+ idlen = ASN1_STRING_length(scid); -+ id = (const char *)ASN1_STRING_get0_data(scid); -+ BIO_dump_indent(bio_err, id, idlen, 4); -+ BIO_puts(bio_err, " Receipts From"); -+ if (rlist) { -+ BIO_puts(bio_err, " List:\n"); -+ gnames_stack_print(rlist); -+ } else if (allorfirst == 1) -+ BIO_puts(bio_err, ": First Tier\n"); -+ else if (allorfirst == 0) -+ BIO_puts(bio_err, ": All\n"); -+ else -+ BIO_printf(bio_err, " Unknown (%d)\n", allorfirst); -+ BIO_puts(bio_err, " Receipts To:\n"); -+ gnames_stack_print(rto); -+ } -+ CMS_ReceiptRequest_free(rr); -+ } -+} -+ -+static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns) -+{ -+ int i; -+ STACK_OF(GENERAL_NAMES) *ret; -+ GENERAL_NAMES *gens = NULL; -+ GENERAL_NAME *gen = NULL; -+ ret = sk_GENERAL_NAMES_new_null(); -+ if (!ret) -+ goto err; -+ for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) { -+ char *str = sk_OPENSSL_STRING_value(ns, i); -+ gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0); -+ if (!gen) -+ goto err; -+ gens = GENERAL_NAMES_new(); -+ if (gens == NULL) -+ goto err; -+ if (!sk_GENERAL_NAME_push(gens, gen)) -+ goto err; -+ gen = NULL; -+ if (!sk_GENERAL_NAMES_push(ret, gens)) -+ goto err; -+ gens = NULL; -+ } -+ -+ return ret; -+ -+ err: -+ sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free); -+ GENERAL_NAMES_free(gens); -+ GENERAL_NAME_free(gen); -+ return NULL; -+} -+ -+static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) -+ *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING) -+ *rr_from) -+{ -+ STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL; -+ CMS_ReceiptRequest *rr; -+ rct_to = make_names_stack(rr_to); -+ if (!rct_to) -+ goto err; -+ if (rr_from) { -+ rct_from = make_names_stack(rr_from); -+ if (!rct_from) -+ goto err; -+ } else -+ rct_from = NULL; -+ rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from, -+ rct_to); -+ return rr; -+ err: -+ sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free); -+ return NULL; -+} -+ -+static int cms_set_pkey_param(EVP_PKEY_CTX *pctx, -+ STACK_OF(OPENSSL_STRING) *param) -+{ -+ char *keyopt; -+ int i; -+ if (sk_OPENSSL_STRING_num(param) <= 0) -+ return 1; -+ for (i = 0; i < sk_OPENSSL_STRING_num(param); i++) { -+ keyopt = sk_OPENSSL_STRING_value(param, i); -+ if (pkey_ctrl_string(pctx, keyopt) <= 0) { -+ BIO_printf(bio_err, "parameter error \"%s\"\n", keyopt); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ } -+ return 1; -+} -+ -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/crl.c b/CryptoPkg/Library/OpensslLib/openssl/apps/crl.c -new file mode 100644 -index 0000000..06b6e5b ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/crl.c -@@ -0,0 +1,347 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+#include -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_IN, OPT_OUTFORM, OPT_OUT, OPT_KEYFORM, OPT_KEY, -+ OPT_ISSUER, OPT_LASTUPDATE, OPT_NEXTUPDATE, OPT_FINGERPRINT, -+ OPT_CRLNUMBER, OPT_BADSIG, OPT_GENDELTA, OPT_CAPATH, OPT_CAFILE, -+ OPT_NOCAPATH, OPT_NOCAFILE, OPT_VERIFY, OPT_TEXT, OPT_HASH, OPT_HASH_OLD, -+ OPT_NOOUT, OPT_NAMEOPT, OPT_MD -+} OPTION_CHOICE; -+ -+OPTIONS crl_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'F', "Input format; default PEM"}, -+ {"in", OPT_IN, '<', "Input file - default stdin"}, -+ {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, -+ {"out", OPT_OUT, '>', "output file - default stdout"}, -+ {"keyform", OPT_KEYFORM, 'F', "Private key file format (PEM or ENGINE)"}, -+ {"key", OPT_KEY, '<', "CRL signing Private key to use"}, -+ {"issuer", OPT_ISSUER, '-', "Print issuer DN"}, -+ {"lastupdate", OPT_LASTUPDATE, '-', "Set lastUpdate field"}, -+ {"nextupdate", OPT_NEXTUPDATE, '-', "Set nextUpdate field"}, -+ {"noout", OPT_NOOUT, '-', "No CRL output"}, -+ {"fingerprint", OPT_FINGERPRINT, '-', "Print the crl fingerprint"}, -+ {"crlnumber", OPT_CRLNUMBER, '-', "Print CRL number"}, -+ {"badsig", OPT_BADSIG, '-', "Corrupt last byte of loaded CRL signature (for test)" }, -+ {"gendelta", OPT_GENDELTA, '<', "Other CRL to compare/diff to the Input one"}, -+ {"CApath", OPT_CAPATH, '/', "Verify CRL using certificates in dir"}, -+ {"CAfile", OPT_CAFILE, '<', "Verify CRL using certificates in file name"}, -+ {"no-CAfile", OPT_NOCAFILE, '-', -+ "Do not load the default certificates file"}, -+ {"no-CApath", OPT_NOCAPATH, '-', -+ "Do not load certificates from the default certificates directory"}, -+ {"verify", OPT_VERIFY, '-', "Verify CRL signature"}, -+ {"text", OPT_TEXT, '-', "Print out a text format version"}, -+ {"hash", OPT_HASH, '-', "Print hash value"}, -+ {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, -+ {"", OPT_MD, '-', "Any supported digest"}, -+#ifndef OPENSSL_NO_MD5 -+ {"hash_old", OPT_HASH_OLD, '-', "Print old-style (MD5) hash value"}, -+#endif -+ {NULL} -+}; -+ -+int crl_main(int argc, char **argv) -+{ -+ X509_CRL *x = NULL; -+ BIO *out = NULL; -+ X509_STORE *store = NULL; -+ X509_STORE_CTX *ctx = NULL; -+ X509_LOOKUP *lookup = NULL; -+ X509_OBJECT *xobj = NULL; -+ EVP_PKEY *pkey; -+ const EVP_MD *digest = EVP_sha1(); -+ unsigned long nmflag = 0; -+ char nmflag_set = 0; -+ char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL; -+ const char *CAfile = NULL, *CApath = NULL, *prog; -+ OPTION_CHOICE o; -+ int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = 0; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; -+ int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = 0; -+ int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0; -+ int i; -+#ifndef OPENSSL_NO_MD5 -+ int hash_old = 0; -+#endif -+ -+ prog = opt_init(argc, argv, crl_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(crl_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_KEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) -+ goto opthelp; -+ break; -+ case OPT_KEY: -+ keyfile = opt_arg(); -+ break; -+ case OPT_GENDELTA: -+ crldiff = opt_arg(); -+ break; -+ case OPT_CAPATH: -+ CApath = opt_arg(); -+ do_ver = 1; -+ break; -+ case OPT_CAFILE: -+ CAfile = opt_arg(); -+ do_ver = 1; -+ break; -+ case OPT_NOCAPATH: -+ noCApath = 1; -+ break; -+ case OPT_NOCAFILE: -+ noCAfile = 1; -+ break; -+ case OPT_HASH_OLD: -+#ifndef OPENSSL_NO_MD5 -+ hash_old = ++num; -+#endif -+ break; -+ case OPT_VERIFY: -+ do_ver = 1; -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_HASH: -+ hash = ++num; -+ break; -+ case OPT_ISSUER: -+ issuer = ++num; -+ break; -+ case OPT_LASTUPDATE: -+ lastupdate = ++num; -+ break; -+ case OPT_NEXTUPDATE: -+ nextupdate = ++num; -+ break; -+ case OPT_NOOUT: -+ noout = ++num; -+ break; -+ case OPT_FINGERPRINT: -+ fingerprint = ++num; -+ break; -+ case OPT_CRLNUMBER: -+ crlnumber = ++num; -+ break; -+ case OPT_BADSIG: -+ badsig = 1; -+ break; -+ case OPT_NAMEOPT: -+ nmflag_set = 1; -+ if (!set_name_ex(&nmflag, opt_arg())) -+ goto opthelp; -+ break; -+ case OPT_MD: -+ if (!opt_md(opt_unknown(), &digest)) -+ goto opthelp; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ if (!nmflag_set) -+ nmflag = XN_FLAG_ONELINE; -+ -+ x = load_crl(infile, informat); -+ if (x == NULL) -+ goto end; -+ -+ if (do_ver) { -+ if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) -+ goto end; -+ lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); -+ if (lookup == NULL) -+ goto end; -+ ctx = X509_STORE_CTX_new(); -+ if (ctx == NULL || !X509_STORE_CTX_init(ctx, store, NULL, NULL)) { -+ BIO_printf(bio_err, "Error initialising X509 store\n"); -+ goto end; -+ } -+ -+ xobj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, -+ X509_CRL_get_issuer(x)); -+ if (xobj == NULL) { -+ BIO_printf(bio_err, "Error getting CRL issuer certificate\n"); -+ goto end; -+ } -+ pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj)); -+ X509_OBJECT_free(xobj); -+ if (!pkey) { -+ BIO_printf(bio_err, "Error getting CRL issuer public key\n"); -+ goto end; -+ } -+ i = X509_CRL_verify(x, pkey); -+ EVP_PKEY_free(pkey); -+ if (i < 0) -+ goto end; -+ if (i == 0) -+ BIO_printf(bio_err, "verify failure\n"); -+ else -+ BIO_printf(bio_err, "verify OK\n"); -+ } -+ -+ if (crldiff) { -+ X509_CRL *newcrl, *delta; -+ if (!keyfile) { -+ BIO_puts(bio_err, "Missing CRL signing key\n"); -+ goto end; -+ } -+ newcrl = load_crl(crldiff, informat); -+ if (!newcrl) -+ goto end; -+ pkey = load_key(keyfile, keyformat, 0, NULL, NULL, "CRL signing key"); -+ if (!pkey) { -+ X509_CRL_free(newcrl); -+ goto end; -+ } -+ delta = X509_CRL_diff(x, newcrl, pkey, digest, 0); -+ X509_CRL_free(newcrl); -+ EVP_PKEY_free(pkey); -+ if (delta) { -+ X509_CRL_free(x); -+ x = delta; -+ } else { -+ BIO_puts(bio_err, "Error creating delta CRL\n"); -+ goto end; -+ } -+ } -+ -+ if (badsig) { -+ const ASN1_BIT_STRING *sig; -+ -+ X509_CRL_get0_signature(x, &sig, NULL); -+ corrupt_signature(sig); -+ } -+ -+ if (num) { -+ for (i = 1; i <= num; i++) { -+ if (issuer == i) { -+ print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), -+ nmflag); -+ } -+ if (crlnumber == i) { -+ ASN1_INTEGER *crlnum; -+ crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL); -+ BIO_printf(bio_out, "crlNumber="); -+ if (crlnum) { -+ i2a_ASN1_INTEGER(bio_out, crlnum); -+ ASN1_INTEGER_free(crlnum); -+ } else -+ BIO_puts(bio_out, ""); -+ BIO_printf(bio_out, "\n"); -+ } -+ if (hash == i) { -+ BIO_printf(bio_out, "%08lx\n", -+ X509_NAME_hash(X509_CRL_get_issuer(x))); -+ } -+#ifndef OPENSSL_NO_MD5 -+ if (hash_old == i) { -+ BIO_printf(bio_out, "%08lx\n", -+ X509_NAME_hash_old(X509_CRL_get_issuer(x))); -+ } -+#endif -+ if (lastupdate == i) { -+ BIO_printf(bio_out, "lastUpdate="); -+ ASN1_TIME_print(bio_out, X509_CRL_get0_lastUpdate(x)); -+ BIO_printf(bio_out, "\n"); -+ } -+ if (nextupdate == i) { -+ BIO_printf(bio_out, "nextUpdate="); -+ if (X509_CRL_get0_nextUpdate(x)) -+ ASN1_TIME_print(bio_out, X509_CRL_get0_nextUpdate(x)); -+ else -+ BIO_printf(bio_out, "NONE"); -+ BIO_printf(bio_out, "\n"); -+ } -+ if (fingerprint == i) { -+ int j; -+ unsigned int n; -+ unsigned char md[EVP_MAX_MD_SIZE]; -+ -+ if (!X509_CRL_digest(x, digest, md, &n)) { -+ BIO_printf(bio_err, "out of memory\n"); -+ goto end; -+ } -+ BIO_printf(bio_out, "%s Fingerprint=", -+ OBJ_nid2sn(EVP_MD_type(digest))); -+ for (j = 0; j < (int)n; j++) { -+ BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n) -+ ? '\n' : ':'); -+ } -+ } -+ } -+ } -+ out = bio_open_default(outfile, 'w', outformat); -+ if (out == NULL) -+ goto end; -+ -+ if (text) -+ X509_CRL_print(out, x); -+ -+ if (noout) { -+ ret = 0; -+ goto end; -+ } -+ -+ if (outformat == FORMAT_ASN1) -+ i = (int)i2d_X509_CRL_bio(out, x); -+ else -+ i = PEM_write_bio_X509_CRL(out, x); -+ if (!i) { -+ BIO_printf(bio_err, "unable to write CRL\n"); -+ goto end; -+ } -+ ret = 0; -+ -+ end: -+ if (ret != 0) -+ ERR_print_errors(bio_err); -+ BIO_free_all(out); -+ X509_CRL_free(x); -+ X509_STORE_CTX_free(ctx); -+ X509_STORE_free(store); -+ return (ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/crl2p7.c b/CryptoPkg/Library/OpensslLib/openssl/apps/crl2p7.c -new file mode 100644 -index 0000000..9c5f79f ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/crl2p7.c -@@ -0,0 +1,216 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile); -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOCRL, OPT_CERTFILE -+} OPTION_CHOICE; -+ -+OPTIONS crl2pkcs7_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, -+ {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"nocrl", OPT_NOCRL, '-', "No crl to load, just certs from '-certfile'"}, -+ {"certfile", OPT_CERTFILE, '<', -+ "File of chain of certs to a trusted CA; can be repeated"}, -+ {NULL} -+}; -+ -+int crl2pkcs7_main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ PKCS7 *p7 = NULL; -+ PKCS7_SIGNED *p7s = NULL; -+ STACK_OF(OPENSSL_STRING) *certflst = NULL; -+ STACK_OF(X509) *cert_stack = NULL; -+ STACK_OF(X509_CRL) *crl_stack = NULL; -+ X509_CRL *crl = NULL; -+ char *infile = NULL, *outfile = NULL, *prog, *certfile; -+ int i = 0, informat = FORMAT_PEM, outformat = FORMAT_PEM, ret = 1, nocrl = -+ 0; -+ OPTION_CHOICE o; -+ -+ prog = opt_init(argc, argv, crl2pkcs7_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(crl2pkcs7_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) -+ goto opthelp; -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_NOCRL: -+ nocrl = 1; -+ break; -+ case OPT_CERTFILE: -+ if ((certflst == NULL) -+ && (certflst = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ if (!sk_OPENSSL_STRING_push(certflst, opt_arg())) -+ goto end; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ if (!nocrl) { -+ in = bio_open_default(infile, 'r', informat); -+ if (in == NULL) -+ goto end; -+ -+ if (informat == FORMAT_ASN1) -+ crl = d2i_X509_CRL_bio(in, NULL); -+ else if (informat == FORMAT_PEM) -+ crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); -+ if (crl == NULL) { -+ BIO_printf(bio_err, "unable to load CRL\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if ((p7 = PKCS7_new()) == NULL) -+ goto end; -+ if ((p7s = PKCS7_SIGNED_new()) == NULL) -+ goto end; -+ p7->type = OBJ_nid2obj(NID_pkcs7_signed); -+ p7->d.sign = p7s; -+ p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data); -+ -+ if (!ASN1_INTEGER_set(p7s->version, 1)) -+ goto end; -+ if ((crl_stack = sk_X509_CRL_new_null()) == NULL) -+ goto end; -+ p7s->crl = crl_stack; -+ if (crl != NULL) { -+ sk_X509_CRL_push(crl_stack, crl); -+ crl = NULL; /* now part of p7 for OPENSSL_freeing */ -+ } -+ -+ if ((cert_stack = sk_X509_new_null()) == NULL) -+ goto end; -+ p7s->cert = cert_stack; -+ -+ if (certflst) -+ for (i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) { -+ certfile = sk_OPENSSL_STRING_value(certflst, i); -+ if (add_certs_from_file(cert_stack, certfile) < 0) { -+ BIO_printf(bio_err, "error loading certificates\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ out = bio_open_default(outfile, 'w', outformat); -+ if (out == NULL) -+ goto end; -+ -+ if (outformat == FORMAT_ASN1) -+ i = i2d_PKCS7_bio(out, p7); -+ else if (outformat == FORMAT_PEM) -+ i = PEM_write_bio_PKCS7(out, p7); -+ if (!i) { -+ BIO_printf(bio_err, "unable to write pkcs7 object\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ ret = 0; -+ end: -+ sk_OPENSSL_STRING_free(certflst); -+ BIO_free(in); -+ BIO_free_all(out); -+ PKCS7_free(p7); -+ X509_CRL_free(crl); -+ -+ return (ret); -+} -+ -+/*- -+ *---------------------------------------------------------------------- -+ * int add_certs_from_file -+ * -+ * Read a list of certificates to be checked from a file. -+ * -+ * Results: -+ * number of certs added if successful, -1 if not. -+ *---------------------------------------------------------------------- -+ */ -+static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile) -+{ -+ BIO *in = NULL; -+ int count = 0; -+ int ret = -1; -+ STACK_OF(X509_INFO) *sk = NULL; -+ X509_INFO *xi; -+ -+ in = BIO_new_file(certfile, "r"); -+ if (in == NULL) { -+ BIO_printf(bio_err, "error opening the file, %s\n", certfile); -+ goto end; -+ } -+ -+ /* This loads from a file, a stack of x509/crl/pkey sets */ -+ sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); -+ if (sk == NULL) { -+ BIO_printf(bio_err, "error reading the file, %s\n", certfile); -+ goto end; -+ } -+ -+ /* scan over it and pull out the CRL's */ -+ while (sk_X509_INFO_num(sk)) { -+ xi = sk_X509_INFO_shift(sk); -+ if (xi->x509 != NULL) { -+ sk_X509_push(stack, xi->x509); -+ xi->x509 = NULL; -+ count++; -+ } -+ X509_INFO_free(xi); -+ } -+ -+ ret = count; -+ end: -+ /* never need to OPENSSL_free x */ -+ BIO_free(in); -+ sk_X509_INFO_free(sk); -+ return (ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/ct_log_list.cnf b/CryptoPkg/Library/OpensslLib/openssl/apps/ct_log_list.cnf -new file mode 100644 -index 0000000..2434874 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/ct_log_list.cnf -@@ -0,0 +1,34 @@ -+enabled_logs=pilot,aviator,rocketeer,digicert,certly,izempe,symantec,venafi -+ -+[pilot] -+description = Google Pilot Log -+key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfahLEimAoz2t01p3uMziiLOl/fHTDM0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J5APC2em4JlvR8EEEFMoA== -+ -+[aviator] -+description = Google Aviator log -+key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1/TMabLkDpCjiupacAlP7xNi0I1JYP8bQFAHDG1xhtolSY1l4QgNRzRrvSe8liE+NPWHdjGxfx3JhTsN9x8/6Q== -+ -+[rocketeer] -+description = Google Rocketeer log -+key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIFsYyDzBi7MxCAC/oJBXK7dHjG+1aLCOkHjpoHPqTyghLpzA9BYbqvnV16mAw04vUjyYASVGJCUoI3ctBcJAeg== -+ -+[digicert] -+description = DigiCert Log Server -+key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAkbFvhu7gkAW6MHSrBlpE1n4+HCFRkC5OLAjgqhkTH+/uzSfSl8ois8ZxAD2NgaTZe1M9akhYlrYkes4JECs6A== -+ -+[certly] -+description = Certly.IO log -+key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECyPLhWKYYUgEc+tUXfPQB4wtGS2MNvXrjwFCCnyYJifBtd2Sk7Cu+Js9DNhMTh35FftHaHu6ZrclnNBKwmbbSA== -+ -+[izempe] -+description = Izempe log -+key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJ2Q5DC3cUBj4IQCiDu0s6j51up+TZAkAEcQRF6tczw90rLWXkJMAW7jr9yc92bIKgV8vDXU4lDeZHvYHduDuvg== -+ -+[symantec] -+description = Symantec log -+key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEluqsHEYMG1XcDfy1lCdGV0JwOmkY4r87xNuroPS2bMBTP01CEDPwWJePa75y9CrsHEKqAy8afig1dpkIPSEUhg== -+ -+[venafi] -+description = Venafi log -+key = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAolpIHxdSlTXLo1s6H1OCdpSj/4DyHDc8wLG9wVmLqy1lk9fz4ATVmm+/1iN2Nk8jmctUKK2MFUtlWXZBSpym97M7frGlSaQXUWyA3CqQUEuIJOmlEjKTBEiQAvpfDjCHjlV2Be4qTM6jamkJbiWtgnYPhJL6ONaGTiSPm7Byy57iaz/hbckldSOIoRhYBiMzeNoA0DiRZ9KmfSeXZ1rB8y8X5urSW+iBzf2SaOfzBvDpcoTuAaWx2DPazoOl28fP1hZ+kHUYvxbcMjttjauCFx+JII0dmuZNIwjfeG/GBb9frpSX219k1O4Wi6OEbHEr8at/XQ0y7gTikOxBn/s5wQIDAQAB -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/cacert.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/cacert.pem -new file mode 100644 -index 0000000..affbce3 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/cacert.pem -@@ -0,0 +1,14 @@ -+subject=/C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server -+issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA -+-----BEGIN X509 CERTIFICATE----- -+ -+MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV -+BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz -+MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM -+RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV -+BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3 -+LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb -+/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0 -+DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn -+IMs6ZOZB -+-----END X509 CERTIFICATE----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/index.txt b/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/index.txt -new file mode 100644 -index 0000000..2cdd252 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/index.txt -@@ -0,0 +1,39 @@ -+R 980705233205Z 951009233205Z 01 certs/00000001 /CN=Eric Young -+E 951009233205Z 02 certs/00000002 /CN=Duncan Young -+R 980705233205Z 951201010000Z 03 certs/00000003 /CN=Tim Hudson -+V 980705233205Z 04 certs/00000004 /CN=Eric Young4 -+V 980705233205Z 05 certs/00000004 /CN=Eric Young5 -+V 980705233205Z 06 certs/00000004 /CN=Eric Young6 -+V 980705233205Z 07 certs/00000004 /CN=Eric Young7 -+V 980705233205Z 08 certs/00000004 /CN=Eric Young8 -+V 980705233205Z 09 certs/00000004 /CN=Eric Young9 -+V 980705233205Z 0A certs/00000004 /CN=Eric YoungA -+V 980705233205Z 0B certs/00000004 /CN=Eric YoungB -+V 980705233205Z 0C certs/00000004 /CN=Eric YoungC -+V 980705233205Z 0D certs/00000004 /CN=Eric YoungD -+V 980705233205Z 0E certs/00000004 /CN=Eric YoungE -+V 980705233205Z 0F certs/00000004 /CN=Eric YoungF -+V 980705233205Z 10 certs/00000004 /CN=Eric Young10 -+V 980705233205Z 11 certs/00000004 /CN=Eric Young11 -+V 980705233205Z 12 certs/00000004 /CN=Eric Young12 -+V 980705233205Z 13 certs/00000004 /CN=Eric Young13 -+V 980705233205Z 14 certs/00000004 /CN=Eric Young14 -+V 980705233205Z 15 certs/00000004 /CN=Eric Young15 -+V 980705233205Z 16 certs/00000004 /CN=Eric Young16 -+V 980705233205Z 17 certs/00000004 /CN=Eric Young17 -+V 961206150305Z 010C unknown /C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=MTR/CN=Eric Young/Email=eay@mincom.oz.au -+V 961206153245Z 010D unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=Eric Young/Email=eay@mincom.oz.au -+V 970322074816Z 010E unknown /CN=Eric Young/Email=eay@mincom.oz.au -+V 970322075152Z 010F unknown /CN=Eric Young -+V 970322075906Z 0110 unknown /CN=Eric Youngg -+V 970324092238Z 0111 unknown /C=AU/SP=Queensland/CN=Eric Young -+V 970324221931Z 0112 unknown /CN=Fred -+V 970324224934Z 0113 unknown /C=AU/CN=eay -+V 971001005237Z 0114 unknown /C=AU/SP=QLD/O=Mincom Pty Ltd/OU=MTR/CN=x509v3 test -+V 971001010331Z 0115 unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test again - x509v3 -+V 971001013945Z 0117 unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=x509v3 test -+V 971014225415Z 0118 unknown /C=AU/SP=Queensland/CN=test -+V 971015004448Z 0119 unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test2 -+V 971016035001Z 011A unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test64 -+V 971016080129Z 011B unknown /C=FR/O=ALCATEL/OU=Alcatel Mobile Phones/CN=bourque/Email=bourque@art.alcatel.fr -+V 971016224000Z 011D unknown /L=Bedford/O=Cranfield University/OU=Computer Centre/CN=Peter R Lister/Email=P.Lister@cranfield.ac.uk -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/private/cakey.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/private/cakey.pem -new file mode 100644 -index 0000000..48fb18c ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/private/cakey.pem -@@ -0,0 +1,24 @@ -+issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA -+subject=/C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server -+-----BEGIN X509 CERTIFICATE----- -+ -+MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV -+BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz -+MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM -+RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV -+BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3 -+LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb -+/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0 -+DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn -+IMs6ZOZB -+-----END X509 CERTIFICATE----- -+-----BEGIN RSA PRIVATE KEY----- -+ -+MIIBPAIBAAJBALcsJdxJxa5rQ8UuQcEubZV6OqkDUXhFDyrRWNGI9p+PH9n9pYfe -+Kl0xW+4kZr/AVdv+cMUsOV9an6gI/CEG1U8CAwEAAQJAXJMBZ34ZXHd1vtgL/3hZ -+hexKbVTx/djZO4imXO/dxPGRzG2ylYZpHmG32/T1kaHpZlCHoEPgHoSzmxYXfxjG -+sQIhAPmZ/bQOjmRUHM/VM2X5zrjjM6z18R1P6l3ObFwt9FGdAiEAu943Yh9SqMRw -+tL0xHGxKmM/YJueUw1gB6sLkETN71NsCIQCeT3RhoqXfrpXDoEcEU+gwzjI1bpxq -+agiNTOLfqGoA5QIhAIQFYjgzONxex7FLrsKBm16N2SFl5pXsN9SpRqqL2n63AiEA -+g9VNIQ3xwpw7og3IbONifeku+J9qGMGQJMKwSTwrFtI= -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/serial b/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/serial -new file mode 100644 -index 0000000..69fa0ff ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/demoCA/serial -@@ -0,0 +1 @@ -+011E -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/demoSRP/srp_verifier.txt b/CryptoPkg/Library/OpensslLib/openssl/apps/demoSRP/srp_verifier.txt -new file mode 100644 -index 0000000..ccae629 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/demoSRP/srp_verifier.txt -@@ -0,0 +1,6 @@ -+# This is a file that will be filled by the openssl srp routine. -+# You can initialize the file with additional groups, these are -+# records starting with a I followed by the g and N values and the id. -+# The exact values ... you have to dig this out from the source of srp.c -+# or srp_vfy.c -+# The last value of an I is used as the default group for new users. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/demoSRP/srp_verifier.txt.attr b/CryptoPkg/Library/OpensslLib/openssl/apps/demoSRP/srp_verifier.txt.attr -new file mode 100644 -index 0000000..8f7e63a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/demoSRP/srp_verifier.txt.attr -@@ -0,0 +1 @@ -+unique_subject = yes -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dgst.c b/CryptoPkg/Library/OpensslLib/openssl/apps/dgst.c -new file mode 100644 -index 0000000..08182e2 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dgst.c -@@ -0,0 +1,480 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#undef BUFSIZE -+#define BUFSIZE 1024*8 -+ -+int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, -+ EVP_PKEY *key, unsigned char *sigin, int siglen, -+ const char *sig_name, const char *md_name, -+ const char *file); -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_C, OPT_R, OPT_RAND, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY, -+ OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL, -+ OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT, -+ OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, -+ OPT_DIGEST -+} OPTION_CHOICE; -+ -+OPTIONS dgst_options[] = { -+ {OPT_HELP_STR, 1, '-', "Usage: %s [options] [file...]\n"}, -+ {OPT_HELP_STR, 1, '-', -+ " file... files to digest (default is stdin)\n"}, -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"c", OPT_C, '-', "Print the digest with separating colons"}, -+ {"r", OPT_R, '-', "Print the digest in coreutils format"}, -+ {"rand", OPT_RAND, 's', -+ "Use file(s) containing random data to seed RNG or an EGD sock"}, -+ {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+ {"sign", OPT_SIGN, 's', "Sign digest using private key"}, -+ {"verify", OPT_VERIFY, 's', -+ "Verify a signature using public key"}, -+ {"prverify", OPT_PRVERIFY, 's', -+ "Verify a signature using private key"}, -+ {"signature", OPT_SIGNATURE, '<', "File with signature to verify"}, -+ {"keyform", OPT_KEYFORM, 'f', "Key file format (PEM or ENGINE)"}, -+ {"hex", OPT_HEX, '-', "Print as hex dump"}, -+ {"binary", OPT_BINARY, '-', "Print in binary form"}, -+ {"d", OPT_DEBUG, '-', "Print debug info"}, -+ {"debug", OPT_DEBUG, '-', "Print debug info"}, -+ {"fips-fingerprint", OPT_FIPS_FINGERPRINT, '-', -+ "Compute HMAC with the key used in OpenSSL-FIPS fingerprint"}, -+ {"hmac", OPT_HMAC, 's', "Create hashed MAC with key"}, -+ {"mac", OPT_MAC, 's', "Create MAC (not necessarily HMAC)"}, -+ {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, -+ {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"}, -+ {"", OPT_DIGEST, '-', "Any supported digest"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -+ {"engine_impl", OPT_ENGINE_IMPL, '-', -+ "Also use engine given by -engine for digest operations"}, -+#endif -+ {NULL} -+}; -+ -+int dgst_main(int argc, char **argv) -+{ -+ BIO *in = NULL, *inp, *bmd = NULL, *out = NULL; -+ ENGINE *e = NULL, *impl = NULL; -+ EVP_PKEY *sigkey = NULL; -+ STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; -+ char *hmac_key = NULL; -+ char *mac_name = NULL; -+ char *passinarg = NULL, *passin = NULL; -+ const EVP_MD *md = NULL, *m; -+ const char *outfile = NULL, *keyfile = NULL, *prog = NULL; -+ const char *sigfile = NULL, *randfile = NULL; -+ OPTION_CHOICE o; -+ int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0; -+ int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0; -+ unsigned char *buf = NULL, *sigbuf = NULL; -+ int engine_impl = 0; -+ -+ prog = opt_progname(argv[0]); -+ buf = app_malloc(BUFSIZE, "I/O buffer"); -+ md = EVP_get_digestbyname(prog); -+ -+ prog = opt_init(argc, argv, dgst_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(dgst_options); -+ ret = 0; -+ goto end; -+ case OPT_C: -+ separator = 1; -+ break; -+ case OPT_R: -+ separator = 2; -+ break; -+ case OPT_RAND: -+ randfile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_SIGN: -+ keyfile = opt_arg(); -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ case OPT_VERIFY: -+ keyfile = opt_arg(); -+ want_pub = do_verify = 1; -+ break; -+ case OPT_PRVERIFY: -+ keyfile = opt_arg(); -+ do_verify = 1; -+ break; -+ case OPT_SIGNATURE: -+ sigfile = opt_arg(); -+ break; -+ case OPT_KEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) -+ goto opthelp; -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_ENGINE_IMPL: -+ engine_impl = 1; -+ break; -+ case OPT_HEX: -+ out_bin = 0; -+ break; -+ case OPT_BINARY: -+ out_bin = 1; -+ break; -+ case OPT_DEBUG: -+ debug = 1; -+ break; -+ case OPT_FIPS_FINGERPRINT: -+ hmac_key = "etaonrishdlcupfm"; -+ break; -+ case OPT_HMAC: -+ hmac_key = opt_arg(); -+ break; -+ case OPT_MAC: -+ mac_name = opt_arg(); -+ break; -+ case OPT_SIGOPT: -+ if (!sigopts) -+ sigopts = sk_OPENSSL_STRING_new_null(); -+ if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) -+ goto opthelp; -+ break; -+ case OPT_MACOPT: -+ if (!macopts) -+ macopts = sk_OPENSSL_STRING_new_null(); -+ if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg())) -+ goto opthelp; -+ break; -+ case OPT_DIGEST: -+ if (!opt_md(opt_unknown(), &m)) -+ goto opthelp; -+ md = m; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ if (keyfile != NULL && argc > 1) { -+ BIO_printf(bio_err, "%s: Can only sign or verify one file.\n", prog); -+ goto end; -+ } -+ -+ if (do_verify && !sigfile) { -+ BIO_printf(bio_err, -+ "No signature to verify: use the -signature option\n"); -+ goto end; -+ } -+ if (engine_impl) -+ impl = e; -+ -+ in = BIO_new(BIO_s_file()); -+ bmd = BIO_new(BIO_f_md()); -+ if ((in == NULL) || (bmd == NULL)) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (debug) { -+ BIO_set_callback(in, BIO_debug_callback); -+ /* needed for windows 3.1 */ -+ BIO_set_callback_arg(in, (char *)bio_err); -+ } -+ -+ if (!app_passwd(passinarg, NULL, &passin, NULL)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ -+ if (out_bin == -1) { -+ if (keyfile) -+ out_bin = 1; -+ else -+ out_bin = 0; -+ } -+ -+ if (randfile) -+ app_RAND_load_file(randfile, 0); -+ -+ out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); -+ if (out == NULL) -+ goto end; -+ -+ if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) { -+ BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); -+ goto end; -+ } -+ -+ if (keyfile) { -+ if (want_pub) -+ sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file"); -+ else -+ sigkey = load_key(keyfile, keyform, 0, passin, e, "key file"); -+ if (!sigkey) { -+ /* -+ * load_[pub]key() has already printed an appropriate message -+ */ -+ goto end; -+ } -+ } -+ -+ if (mac_name) { -+ EVP_PKEY_CTX *mac_ctx = NULL; -+ int r = 0; -+ if (!init_gen_str(&mac_ctx, mac_name, impl, 0)) -+ goto mac_end; -+ if (macopts) { -+ char *macopt; -+ for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { -+ macopt = sk_OPENSSL_STRING_value(macopts, i); -+ if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { -+ BIO_printf(bio_err, -+ "MAC parameter error \"%s\"\n", macopt); -+ ERR_print_errors(bio_err); -+ goto mac_end; -+ } -+ } -+ } -+ if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) { -+ BIO_puts(bio_err, "Error generating key\n"); -+ ERR_print_errors(bio_err); -+ goto mac_end; -+ } -+ r = 1; -+ mac_end: -+ EVP_PKEY_CTX_free(mac_ctx); -+ if (r == 0) -+ goto end; -+ } -+ -+ if (hmac_key) { -+ sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl, -+ (unsigned char *)hmac_key, -1); -+ if (!sigkey) -+ goto end; -+ } -+ -+ if (sigkey) { -+ EVP_MD_CTX *mctx = NULL; -+ EVP_PKEY_CTX *pctx = NULL; -+ int r; -+ if (!BIO_get_md_ctx(bmd, &mctx)) { -+ BIO_printf(bio_err, "Error getting context\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (do_verify) -+ r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey); -+ else -+ r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey); -+ if (!r) { -+ BIO_printf(bio_err, "Error setting context\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (sigopts) { -+ char *sigopt; -+ for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { -+ sigopt = sk_OPENSSL_STRING_value(sigopts, i); -+ if (pkey_ctrl_string(pctx, sigopt) <= 0) { -+ BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ } -+ } -+ /* we use md as a filter, reading from 'in' */ -+ else { -+ EVP_MD_CTX *mctx = NULL; -+ if (!BIO_get_md_ctx(bmd, &mctx)) { -+ BIO_printf(bio_err, "Error getting context\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (md == NULL) -+ md = EVP_sha256(); -+ if (!EVP_DigestInit_ex(mctx, md, impl)) { -+ BIO_printf(bio_err, "Error setting digest\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (sigfile && sigkey) { -+ BIO *sigbio = BIO_new_file(sigfile, "rb"); -+ if (!sigbio) { -+ BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ siglen = EVP_PKEY_size(sigkey); -+ sigbuf = app_malloc(siglen, "signature buffer"); -+ siglen = BIO_read(sigbio, sigbuf, siglen); -+ BIO_free(sigbio); -+ if (siglen <= 0) { -+ BIO_printf(bio_err, "Error reading signature file %s\n", sigfile); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ inp = BIO_push(bmd, in); -+ -+ if (md == NULL) { -+ EVP_MD_CTX *tctx; -+ BIO_get_md_ctx(bmd, &tctx); -+ md = EVP_MD_CTX_md(tctx); -+ } -+ -+ if (argc == 0) { -+ BIO_set_fp(in, stdin, BIO_NOCLOSE); -+ ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, -+ siglen, NULL, NULL, "stdin"); -+ } else { -+ const char *md_name = NULL, *sig_name = NULL; -+ if (!out_bin) { -+ if (sigkey) { -+ const EVP_PKEY_ASN1_METHOD *ameth; -+ ameth = EVP_PKEY_get0_asn1(sigkey); -+ if (ameth) -+ EVP_PKEY_asn1_get0_info(NULL, NULL, -+ NULL, NULL, &sig_name, ameth); -+ } -+ if (md) -+ md_name = EVP_MD_name(md); -+ } -+ ret = 0; -+ for (i = 0; i < argc; i++) { -+ int r; -+ if (BIO_read_filename(in, argv[i]) <= 0) { -+ perror(argv[i]); -+ ret++; -+ continue; -+ } else -+ r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, -+ siglen, sig_name, md_name, argv[i]); -+ if (r) -+ ret = r; -+ (void)BIO_reset(bmd); -+ } -+ } -+ end: -+ OPENSSL_clear_free(buf, BUFSIZE); -+ BIO_free(in); -+ OPENSSL_free(passin); -+ BIO_free_all(out); -+ EVP_PKEY_free(sigkey); -+ sk_OPENSSL_STRING_free(sigopts); -+ sk_OPENSSL_STRING_free(macopts); -+ OPENSSL_free(sigbuf); -+ BIO_free(bmd); -+ release_engine(e); -+ return (ret); -+} -+ -+int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, -+ EVP_PKEY *key, unsigned char *sigin, int siglen, -+ const char *sig_name, const char *md_name, -+ const char *file) -+{ -+ size_t len; -+ int i; -+ -+ for (;;) { -+ i = BIO_read(bp, (char *)buf, BUFSIZE); -+ if (i < 0) { -+ BIO_printf(bio_err, "Read Error in %s\n", file); -+ ERR_print_errors(bio_err); -+ return 1; -+ } -+ if (i == 0) -+ break; -+ } -+ if (sigin) { -+ EVP_MD_CTX *ctx; -+ BIO_get_md_ctx(bp, &ctx); -+ i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen); -+ if (i > 0) -+ BIO_printf(out, "Verified OK\n"); -+ else if (i == 0) { -+ BIO_printf(out, "Verification Failure\n"); -+ return 1; -+ } else { -+ BIO_printf(bio_err, "Error Verifying Data\n"); -+ ERR_print_errors(bio_err); -+ return 1; -+ } -+ return 0; -+ } -+ if (key) { -+ EVP_MD_CTX *ctx; -+ BIO_get_md_ctx(bp, &ctx); -+ len = BUFSIZE; -+ if (!EVP_DigestSignFinal(ctx, buf, &len)) { -+ BIO_printf(bio_err, "Error Signing Data\n"); -+ ERR_print_errors(bio_err); -+ return 1; -+ } -+ } else { -+ len = BIO_gets(bp, (char *)buf, BUFSIZE); -+ if ((int)len < 0) { -+ ERR_print_errors(bio_err); -+ return 1; -+ } -+ } -+ -+ if (binout) -+ BIO_write(out, buf, len); -+ else if (sep == 2) { -+ for (i = 0; i < (int)len; i++) -+ BIO_printf(out, "%02x", buf[i]); -+ BIO_printf(out, " *%s\n", file); -+ } else { -+ if (sig_name) { -+ BIO_puts(out, sig_name); -+ if (md_name) -+ BIO_printf(out, "-%s", md_name); -+ BIO_printf(out, "(%s)= ", file); -+ } else if (md_name) -+ BIO_printf(out, "%s(%s)= ", md_name, file); -+ else -+ BIO_printf(out, "(%s)= ", file); -+ for (i = 0; i < (int)len; i++) { -+ if (sep && (i != 0)) -+ BIO_printf(out, ":"); -+ BIO_printf(out, "%02x", buf[i]); -+ } -+ BIO_printf(out, "\n"); -+ } -+ return 0; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dh1024.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/dh1024.pem -new file mode 100644 -index 0000000..f1a5e18 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dh1024.pem -@@ -0,0 +1,10 @@ -+-----BEGIN DH PARAMETERS----- -+MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR -+Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL -+/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC -+-----END DH PARAMETERS----- -+ -+These are the 1024-bit DH parameters from "Internet Key Exchange -+Protocol Version 2 (IKEv2)": https://tools.ietf.org/html/rfc5996 -+ -+See https://tools.ietf.org/html/rfc2412 for how they were generated. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dh2048.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/dh2048.pem -new file mode 100644 -index 0000000..e899f2e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dh2048.pem -@@ -0,0 +1,14 @@ -+-----BEGIN DH PARAMETERS----- -+MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb -+IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft -+awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT -+mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh -+fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq -+5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg== -+-----END DH PARAMETERS----- -+ -+These are the 2048-bit DH parameters from "More Modular Exponential -+(MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)": -+https://tools.ietf.org/html/rfc3526 -+ -+See https://tools.ietf.org/html/rfc2412 for how they were generated. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dh4096.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/dh4096.pem -new file mode 100644 -index 0000000..adada2b ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dh4096.pem -@@ -0,0 +1,19 @@ -+-----BEGIN DH PARAMETERS----- -+MIICCAKCAgEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb -+IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft -+awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT -+mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh -+fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq -+5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM -+fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq -+ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI -+ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O -++S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI -+HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////8CAQI= -+-----END DH PARAMETERS----- -+ -+These are the 4096-bit DH parameters from "More Modular Exponential -+(MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)": -+https://tools.ietf.org/html/rfc3526 -+ -+See https://tools.ietf.org/html/rfc2412 for how they were generated. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dhparam.c b/CryptoPkg/Library/OpensslLib/openssl/apps/dhparam.c -new file mode 100644 -index 0000000..2223e1a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dhparam.c -@@ -0,0 +1,380 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#ifdef OPENSSL_NO_DH -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include -+# include -+# include -+# include -+# include "apps.h" -+# include -+# include -+# include -+# include -+# include -+# include -+ -+# ifndef OPENSSL_NO_DSA -+# include -+# endif -+ -+# define DEFBITS 2048 -+ -+static int dh_cb(int p, int n, BN_GENCB *cb); -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, -+ OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT, -+ OPT_RAND, OPT_DSAPARAM, OPT_C, OPT_2, OPT_5 -+} OPTION_CHOICE; -+ -+OPTIONS dhparam_options[] = { -+ {OPT_HELP_STR, 1, '-', "Usage: %s [flags] [numbits]\n"}, -+ {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"inform", OPT_INFORM, 'F', "Input format, DER or PEM"}, -+ {"outform", OPT_OUTFORM, 'F', "Output format, DER or PEM"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"check", OPT_CHECK, '-', "Check the DH parameters"}, -+ {"text", OPT_TEXT, '-', "Print a text form of the DH parameters"}, -+ {"noout", OPT_NOOUT, '-', "Don't output any DH parameters"}, -+ {"rand", OPT_RAND, 's', -+ "Load the file(s) into the random number generator"}, -+ {"C", OPT_C, '-', "Print C code"}, -+ {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"}, -+ {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"}, -+# ifndef OPENSSL_NO_DSA -+ {"dsaparam", OPT_DSAPARAM, '-', -+ "Read or generate DSA parameters, convert to DH"}, -+# endif -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+int dhparam_main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ DH *dh = NULL; -+ char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL; -+ ENGINE *e = NULL; -+#ifndef OPENSSL_NO_DSA -+ int dsaparam = 0; -+#endif -+ int i, text = 0, C = 0, ret = 1, num = 0, g = 0; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM, check = 0, noout = 0; -+ OPTION_CHOICE o; -+ -+ prog = opt_init(argc, argv, dhparam_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(dhparam_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) -+ goto opthelp; -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_CHECK: -+ check = 1; -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_DSAPARAM: -+#ifndef OPENSSL_NO_DSA -+ dsaparam = 1; -+#endif -+ break; -+ case OPT_C: -+ C = 1; -+ break; -+ case OPT_2: -+ g = 2; -+ break; -+ case OPT_5: -+ g = 5; -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ -+ if (argv[0] && (!opt_int(argv[0], &num) || num <= 0)) -+ goto end; -+ -+ if (g && !num) -+ num = DEFBITS; -+ -+# ifndef OPENSSL_NO_DSA -+ if (dsaparam && g) { -+ BIO_printf(bio_err, -+ "generator may not be chosen for DSA parameters\n"); -+ goto end; -+ } -+# endif -+ /* DH parameters */ -+ if (num && !g) -+ g = 2; -+ -+ if (num) { -+ -+ BN_GENCB *cb; -+ cb = BN_GENCB_new(); -+ if (cb == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ BN_GENCB_set(cb, dh_cb, bio_err); -+ if (!app_RAND_load_file(NULL, 1) && inrand == NULL) { -+ BIO_printf(bio_err, -+ "warning, not much extra random data, consider using the -rand option\n"); -+ } -+ if (inrand != NULL) -+ BIO_printf(bio_err, "%ld semi-random bytes loaded\n", -+ app_RAND_load_files(inrand)); -+ -+# ifndef OPENSSL_NO_DSA -+ if (dsaparam) { -+ DSA *dsa = DSA_new(); -+ -+ BIO_printf(bio_err, -+ "Generating DSA parameters, %d bit long prime\n", num); -+ if (dsa == NULL -+ || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, -+ cb)) { -+ DSA_free(dsa); -+ BN_GENCB_free(cb); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ dh = DSA_dup_DH(dsa); -+ DSA_free(dsa); -+ if (dh == NULL) { -+ BN_GENCB_free(cb); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } else -+# endif -+ { -+ dh = DH_new(); -+ BIO_printf(bio_err, -+ "Generating DH parameters, %d bit long safe prime, generator %d\n", -+ num, g); -+ BIO_printf(bio_err, "This is going to take a long time\n"); -+ if (dh == NULL || !DH_generate_parameters_ex(dh, num, g, cb)) { -+ BN_GENCB_free(cb); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ BN_GENCB_free(cb); -+ app_RAND_write_file(NULL); -+ } else { -+ -+ in = bio_open_default(infile, 'r', informat); -+ if (in == NULL) -+ goto end; -+ -+# ifndef OPENSSL_NO_DSA -+ if (dsaparam) { -+ DSA *dsa; -+ -+ if (informat == FORMAT_ASN1) -+ dsa = d2i_DSAparams_bio(in, NULL); -+ else /* informat == FORMAT_PEM */ -+ dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); -+ -+ if (dsa == NULL) { -+ BIO_printf(bio_err, "unable to load DSA parameters\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ dh = DSA_dup_DH(dsa); -+ DSA_free(dsa); -+ if (dh == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } else -+# endif -+ { -+ if (informat == FORMAT_ASN1) -+ dh = d2i_DHparams_bio(in, NULL); -+ else /* informat == FORMAT_PEM */ -+ dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); -+ -+ if (dh == NULL) { -+ BIO_printf(bio_err, "unable to load DH parameters\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ /* dh != NULL */ -+ } -+ -+ out = bio_open_default(outfile, 'w', outformat); -+ if (out == NULL) -+ goto end; -+ -+ if (text) { -+ DHparams_print(out, dh); -+ } -+ -+ if (check) { -+ if (!DH_check(dh, &i)) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (i & DH_CHECK_P_NOT_PRIME) -+ BIO_printf(bio_err, "WARNING: p value is not prime\n"); -+ if (i & DH_CHECK_P_NOT_SAFE_PRIME) -+ BIO_printf(bio_err, "WARNING: p value is not a safe prime\n"); -+ if (i & DH_CHECK_Q_NOT_PRIME) -+ BIO_printf(bio_err, "WARNING: q value is not a prime\n"); -+ if (i & DH_CHECK_INVALID_Q_VALUE) -+ BIO_printf(bio_err, "WARNING: q value is invalid\n"); -+ if (i & DH_CHECK_INVALID_J_VALUE) -+ BIO_printf(bio_err, "WARNING: j value is invalid\n"); -+ if (i & DH_UNABLE_TO_CHECK_GENERATOR) -+ BIO_printf(bio_err, -+ "WARNING: unable to check the generator value\n"); -+ if (i & DH_NOT_SUITABLE_GENERATOR) -+ BIO_printf(bio_err, "WARNING: the g value is not a generator\n"); -+ if (i == 0) -+ BIO_printf(bio_err, "DH parameters appear to be ok.\n"); -+ if (num != 0 && i != 0) { -+ /* -+ * We have generated parameters but DH_check() indicates they are -+ * invalid! This should never happen! -+ */ -+ BIO_printf(bio_err, "ERROR: Invalid parameters generated\n"); -+ goto end; -+ } -+ } -+ if (C) { -+ unsigned char *data; -+ int len, bits; -+ const BIGNUM *pbn, *gbn; -+ -+ len = DH_size(dh); -+ bits = DH_bits(dh); -+ DH_get0_pqg(dh, &pbn, NULL, &gbn); -+ data = app_malloc(len, "print a BN"); -+ BIO_printf(out, "#ifndef HEADER_DH_H\n" -+ "# include \n" -+ "#endif\n" -+ "\n"); -+ BIO_printf(out, "DH *get_dh%d()\n{\n", bits); -+ print_bignum_var(out, pbn, "dhp", bits, data); -+ print_bignum_var(out, gbn, "dhg", bits, data); -+ BIO_printf(out, " DH *dh = DH_new();\n" -+ " BIGNUM *dhp_bn, *dhg_bn;\n" -+ "\n" -+ " if (dh == NULL)\n" -+ " return NULL;\n"); -+ BIO_printf(out, " dhp_bn = BN_bin2bn(dhp_%d, sizeof (dhp_%d), NULL);\n", -+ bits, bits); -+ BIO_printf(out, " dhg_bn = BN_bin2bn(dhg_%d, sizeof (dhg_%d), NULL);\n", -+ bits, bits); -+ BIO_printf(out, " if (dhp_bn == NULL || dhg_bn == NULL\n" -+ " || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {\n" -+ " DH_free(dh);\n" -+ " BN_free(dhp_bn);\n" -+ " BN_free(dhg_bn);\n" -+ " return NULL;\n" -+ " }\n"); -+ if (DH_get_length(dh) > 0) -+ BIO_printf(out, -+ " if (!DH_set_length(dh, %ld)) {\n" -+ " DH_free(dh);\n" -+ " }\n", DH_get_length(dh)); -+ BIO_printf(out, " return dh;\n}\n"); -+ OPENSSL_free(data); -+ } -+ -+ if (!noout) { -+ const BIGNUM *q; -+ DH_get0_pqg(dh, NULL, &q, NULL); -+ if (outformat == FORMAT_ASN1) -+ i = i2d_DHparams_bio(out, dh); -+ else if (q != NULL) -+ i = PEM_write_bio_DHxparams(out, dh); -+ else -+ i = PEM_write_bio_DHparams(out, dh); -+ if (!i) { -+ BIO_printf(bio_err, "unable to write DH parameters\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ ret = 0; -+ end: -+ BIO_free(in); -+ BIO_free_all(out); -+ DH_free(dh); -+ release_engine(e); -+ return (ret); -+} -+ -+static int dh_cb(int p, int n, BN_GENCB *cb) -+{ -+ char c = '*'; -+ -+ if (p == 0) -+ c = '.'; -+ if (p == 1) -+ c = '+'; -+ if (p == 2) -+ c = '*'; -+ if (p == 3) -+ c = '\n'; -+ BIO_write(BN_GENCB_get_arg(cb), &c, 1); -+ (void)BIO_flush(BN_GENCB_get_arg(cb)); -+ return 1; -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dsa-ca.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/dsa-ca.pem -new file mode 100644 -index 0000000..3ce8dc6 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dsa-ca.pem -@@ -0,0 +1,47 @@ -+-----BEGIN DSA PRIVATE KEY----- -+MIIBugIBAAKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQ -+PnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtel -+u+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcH -+Me36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLso -+hkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbu -+SXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7Y -+Mu0OArgCgYAapll6iqz9XrZFlk2GCVcB+KihxWnH7IuHvSLw9YUrJahcBHmbpvt4 -+94lF4gC5w3WPM+vXJofbusk4GoQEEsQNMDaah4m49uUqAylOVFJJJXuirVJ+o+0T -+tOFDITEAl+YZZariXOD7tdOSOl9RLMPC6+daHKS9e68u3enxhqnDGQIUB78dhW77 -+J6zsFbSEHaQGUmfSeoM= -+-----END DSA PRIVATE KEY----- -+-----BEGIN CERTIFICATE REQUEST----- -+MIICVjCCAhMCAQAwUjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx -+ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDELMAkGA1UEAwwCQ0Ew -+ggG2MIIBKwYHKoZIzjgEATCCAR4CgYEApz9uhb9Bail98J9HGTCQmgkd2mozHsU9 -+hpazFeBTLo/gWYJzkD51MZlHelL7heTZpns4m2iKhJuHxh61foZLU1tZz3FlGYhu -+zmaua4g2++wo3MLXpbvlLDkmS9qacBiVN5UQViP2Fe26BF7eOU/9t0MftaRlb82A -+EeRwlVtQzUkCFQD3BzHt+mwGA9WFihysnGXnUGZlbwKBgE3fTAOmkYr1GW9QRiWZ -+5WhvMONp4eWzXZi7KIZI/N6ZBD9fiAyccyQNIF25Kpo/GJYn5GKHwXt0YlP8YSeo -+epEJnbbxTZxUD1gG7kl0B85VfiPOFvbK3FphAX7JcbVN9tw0KYdo9l4gk7Pb9eQJ -+bEEXlZLrAbVzpWp+2DLtDgK4A4GEAAKBgBqmWXqKrP1etkWWTYYJVwH4qKHFacfs -+i4e9IvD1hSslqFwEeZum+3j3iUXiALnDdY8z69cmh9u6yTgahAQSxA0wNpqHibj2 -+5SoDKU5UUkkle6KtUn6j7RO04UMhMQCX5hllquJc4Pu105I6X1Esw8Lr51ocpL17 -+ry7d6fGGqcMZoAAwCwYJYIZIAWUDBAMCAzAAMC0CFCp7rUwGJNtxK6Aqo6k6US+S -+KP8sAhUAyfSi8Zs3QAvkJoFG0IMRaq8M03I= -+-----END CERTIFICATE REQUEST----- -+-----BEGIN CERTIFICATE----- -+MIIDMDCCAuygAwIBAgIBAjALBglghkgBZQMEAwIwUzELMAkGA1UEBhMCQVUxEzAR -+BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 -+IEx0ZDEMMAoGA1UEAwwDUENBMCAXDTE2MDExMzIxNDE0OVoYDzMwMTUwNTE2MjE0 -+MTQ5WjBSMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UE -+CgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQswCQYDVQQDDAJDQTCCAbYwggEr -+BgcqhkjOOAQBMIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMu -+j+BZgnOQPnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb7 -+7Cjcwtelu+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DN -+SQIVAPcHMe36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh -+5bNdmLsohkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFN -+nFQPWAbuSXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusB -+tXOlan7YMu0OArgDgYQAAoGAGqZZeoqs/V62RZZNhglXAfioocVpx+yLh70i8PWF -+KyWoXAR5m6b7ePeJReIAucN1jzPr1yaH27rJOBqEBBLEDTA2moeJuPblKgMpTlRS -+SSV7oq1SfqPtE7ThQyExAJfmGWWq4lzg+7XTkjpfUSzDwuvnWhykvXuvLt3p8Yap -+wxmjUDBOMB0GA1UdDgQWBBTMZcORcBEVlqO/CD4pf4V6N1NM1zAfBgNVHSMEGDAW -+gBTGjwJ33uvjSa20RNrMKWoGptOLdDAMBgNVHRMEBTADAQH/MAsGCWCGSAFlAwQD -+AgMxADAuAhUA4V6MrHufG8R79E+AtVO02olPxK8CFQDkZyo/TWpavsUBRDJbCeD9 -+jgjIkA== -+-----END CERTIFICATE----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dsa-pca.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/dsa-pca.pem -new file mode 100644 -index 0000000..a51a06e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dsa-pca.pem -@@ -0,0 +1,47 @@ -+-----BEGIN DSA PRIVATE KEY----- -+MIIBvAIBAAKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQ -+PnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtel -+u+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcH -+Me36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLso -+hkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbu -+SXQHzlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7Y -+Mu0OArgCgYEApu25HkB1b4gKMIV7aLGNSIknMzYgrB7o1kQxeDf34dDVRM9OZ8tk -+umz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQlNnKvbtlmMDULpqkZJD0bO7A -+29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgTmvTPT2j9TPjq7RUCFQDNvrBz -+6TicfImU7UFRn9h00j0lJQ== -+-----END DSA PRIVATE KEY----- -+-----BEGIN CERTIFICATE REQUEST----- -+MIICWDCCAhUCAQAwUzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx -+ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAwwDUENB -+MIIBtzCCASsGByqGSM44BAEwggEeAoGBAKc/boW/QWopffCfRxkwkJoJHdpqMx7F -+PYaWsxXgUy6P4FmCc5A+dTGZR3pS+4Xk2aZ7OJtoioSbh8YetX6GS1NbWc9xZRmI -+bs5mrmuINvvsKNzC16W75Sw5JkvamnAYlTeVEFYj9hXtugRe3jlP/bdDH7WkZW/N -+gBHkcJVbUM1JAhUA9wcx7fpsBgPVhYocrJxl51BmZW8CgYBN30wDppGK9RlvUEYl -+meVobzDjaeHls12YuyiGSPzemQQ/X4gMnHMkDSBduSqaPxiWJ+Rih8F7dGJT/GEn -+qHqRCZ228U2cVA9YBu5JdAfOVX4jzhb2ytxaYQF+yXG1TfbcNCmHaPZeIJOz2/Xk -+CWxBF5WS6wG1c6Vqftgy7Q4CuAOBhQACgYEApu25HkB1b4gKMIV7aLGNSIknMzYg -+rB7o1kQxeDf34dDVRM9OZ8tkumz6tl+iUcNe5EoxdsYV1IXSddjOi08LOLsZq7AQ -+lNnKvbtlmMDULpqkZJD0bO7A29nisJfKy1URqABLw5DgfcPh1ZLXtmDfUgJvmjgT -+mvTPT2j9TPjq7RWgADALBglghkgBZQMEAwIDMAAwLQIVAPA6/jxCT1D2HgzE4iZR -+AEup/C7YAhRPLTQvQnAiS5FRrA+8SwBLvDAsaw== -+-----END CERTIFICATE REQUEST----- -+-----BEGIN CERTIFICATE----- -+MIIDMDCCAu6gAwIBAgIBATALBglghkgBZQMEAwIwUzELMAkGA1UEBhMCQVUxEzAR -+BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 -+IEx0ZDEMMAoGA1UEAwwDUENBMCAXDTE2MDExMzIxNDE0OVoYDzMwMTUwNTE2MjE0 -+MTQ5WjBTMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UE -+CgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQwwCgYDVQQDDANQQ0EwggG3MIIB -+KwYHKoZIzjgEATCCAR4CgYEApz9uhb9Bail98J9HGTCQmgkd2mozHsU9hpazFeBT -+Lo/gWYJzkD51MZlHelL7heTZpns4m2iKhJuHxh61foZLU1tZz3FlGYhuzmaua4g2 -+++wo3MLXpbvlLDkmS9qacBiVN5UQViP2Fe26BF7eOU/9t0MftaRlb82AEeRwlVtQ -+zUkCFQD3BzHt+mwGA9WFihysnGXnUGZlbwKBgE3fTAOmkYr1GW9QRiWZ5WhvMONp -+4eWzXZi7KIZI/N6ZBD9fiAyccyQNIF25Kpo/GJYn5GKHwXt0YlP8YSeoepEJnbbx -+TZxUD1gG7kl0B85VfiPOFvbK3FphAX7JcbVN9tw0KYdo9l4gk7Pb9eQJbEEXlZLr -+AbVzpWp+2DLtDgK4A4GFAAKBgQCm7bkeQHVviAowhXtosY1IiSczNiCsHujWRDF4 -+N/fh0NVEz05ny2S6bPq2X6JRw17kSjF2xhXUhdJ12M6LTws4uxmrsBCU2cq9u2WY -+wNQumqRkkPRs7sDb2eKwl8rLVRGoAEvDkOB9w+HVkte2YN9SAm+aOBOa9M9PaP1M -++OrtFaNQME4wHQYDVR0OBBYEFMaPAnfe6+NJrbRE2swpagam04t0MB8GA1UdIwQY -+MBaAFMaPAnfe6+NJrbRE2swpagam04t0MAwGA1UdEwQFMAMBAf8wCwYJYIZIAWUD -+BAMCAy8AMCwCFFhdz4fzQo9BBF20U1CHldYTi/D7AhQydDnDMj21y+U1UhDZJrvh -+lnt88g== -+-----END CERTIFICATE----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dsa.c b/CryptoPkg/Library/OpensslLib/openssl/apps/dsa.c -new file mode 100644 -index 0000000..9c93549 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dsa.c -@@ -0,0 +1,262 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#ifdef OPENSSL_NO_DSA -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include -+# include -+# include -+# include -+# include "apps.h" -+# include -+# include -+# include -+# include -+# include -+# include -+# include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENGINE, -+ /* Do not change the order here; see case statements below */ -+ OPT_PVK_NONE, OPT_PVK_WEAK, OPT_PVK_STRONG, -+ OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_PUBIN, -+ OPT_PUBOUT, OPT_CIPHER, OPT_PASSIN, OPT_PASSOUT -+} OPTION_CHOICE; -+ -+OPTIONS dsa_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'f', "Input format, DER PEM PVK"}, -+ {"outform", OPT_OUTFORM, 'f', "Output format, DER PEM PVK"}, -+ {"in", OPT_IN, 's', "Input key"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"noout", OPT_NOOUT, '-', "Don't print key out"}, -+ {"text", OPT_TEXT, '-', "Print the key in text"}, -+ {"modulus", OPT_MODULUS, '-', "Print the DSA public value"}, -+ {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, -+ {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+ {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, -+ {"", OPT_CIPHER, '-', "Any supported cipher"}, -+# ifndef OPENSSL_NO_RC4 -+ {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"}, -+ {"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"}, -+ {"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"}, -+# endif -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+int dsa_main(int argc, char **argv) -+{ -+ BIO *out = NULL; -+ DSA *dsa = NULL; -+ ENGINE *e = NULL; -+ const EVP_CIPHER *enc = NULL; -+ char *infile = NULL, *outfile = NULL, *prog; -+ char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL; -+ OPTION_CHOICE o; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0; -+ int i, modulus = 0, pubin = 0, pubout = 0, ret = 1; -+# ifndef OPENSSL_NO_RC4 -+ int pvk_encr = 2; -+# endif -+ int private = 0; -+ -+ prog = opt_init(argc, argv, dsa_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ ret = 0; -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(dsa_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ case OPT_PASSOUT: -+ passoutarg = opt_arg(); -+ break; -+ case OPT_PVK_STRONG: /* pvk_encr:= 2 */ -+ case OPT_PVK_WEAK: /* pvk_encr:= 1 */ -+ case OPT_PVK_NONE: /* pvk_encr:= 0 */ -+#ifndef OPENSSL_NO_RC4 -+ pvk_encr = (o - OPT_PVK_NONE); -+#endif -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_MODULUS: -+ modulus = 1; -+ break; -+ case OPT_PUBIN: -+ pubin = 1; -+ break; -+ case OPT_PUBOUT: -+ pubout = 1; -+ break; -+ case OPT_CIPHER: -+ if (!opt_cipher(opt_unknown(), &enc)) -+ goto end; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ private = pubin || pubout ? 0 : 1; -+ if (text && !pubin) -+ private = 1; -+ -+ if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { -+ BIO_printf(bio_err, "Error getting passwords\n"); -+ goto end; -+ } -+ -+ BIO_printf(bio_err, "read DSA key\n"); -+ { -+ EVP_PKEY *pkey; -+ -+ if (pubin) -+ pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key"); -+ else -+ pkey = load_key(infile, informat, 1, passin, e, "Private Key"); -+ -+ if (pkey) { -+ dsa = EVP_PKEY_get1_DSA(pkey); -+ EVP_PKEY_free(pkey); -+ } -+ } -+ if (dsa == NULL) { -+ BIO_printf(bio_err, "unable to load Key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ out = bio_open_owner(outfile, outformat, private); -+ if (out == NULL) -+ goto end; -+ -+ if (text) { -+ assert(pubin || private); -+ if (!DSA_print(out, dsa, 0)) { -+ perror(outfile); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (modulus) { -+ const BIGNUM *pub_key = NULL; -+ DSA_get0_key(dsa, &pub_key, NULL); -+ BIO_printf(out, "Public Key="); -+ BN_print(out, pub_key); -+ BIO_printf(out, "\n"); -+ } -+ -+ if (noout) { -+ ret = 0; -+ goto end; -+ } -+ BIO_printf(bio_err, "writing DSA key\n"); -+ if (outformat == FORMAT_ASN1) { -+ if (pubin || pubout) -+ i = i2d_DSA_PUBKEY_bio(out, dsa); -+ else { -+ assert(private); -+ i = i2d_DSAPrivateKey_bio(out, dsa); -+ } -+ } else if (outformat == FORMAT_PEM) { -+ if (pubin || pubout) -+ i = PEM_write_bio_DSA_PUBKEY(out, dsa); -+ else { -+ assert(private); -+ i = PEM_write_bio_DSAPrivateKey(out, dsa, enc, -+ NULL, 0, NULL, passout); -+ } -+# ifndef OPENSSL_NO_RSA -+ } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { -+ EVP_PKEY *pk; -+ pk = EVP_PKEY_new(); -+ EVP_PKEY_set1_DSA(pk, dsa); -+ if (outformat == FORMAT_PVK) { -+ if (pubin) { -+ BIO_printf(bio_err, "PVK form impossible with public key input\n"); -+ EVP_PKEY_free(pk); -+ goto end; -+ } -+ assert(private); -+# ifdef OPENSSL_NO_RC4 -+ BIO_printf(bio_err, "PVK format not supported\n"); -+ EVP_PKEY_free(pk); -+ goto end; -+# else -+ i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); -+# endif -+ } -+ else if (pubin || pubout) -+ i = i2b_PublicKey_bio(out, pk); -+ else { -+ assert(private); -+ i = i2b_PrivateKey_bio(out, pk); -+ } -+ EVP_PKEY_free(pk); -+# endif -+ } else { -+ BIO_printf(bio_err, "bad output format specified for outfile\n"); -+ goto end; -+ } -+ if (i <= 0) { -+ BIO_printf(bio_err, "unable to write private key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ ret = 0; -+ end: -+ BIO_free_all(out); -+ DSA_free(dsa); -+ release_engine(e); -+ OPENSSL_free(passin); -+ OPENSSL_free(passout); -+ return (ret); -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dsa1024.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/dsa1024.pem -new file mode 100644 -index 0000000..082dec3 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dsa1024.pem -@@ -0,0 +1,9 @@ -+-----BEGIN DSA PARAMETERS----- -+MIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQPnUx -+mUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtelu+Us -+OSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcHMe36 -+bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh5bNdmLsohkj8 -+3pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h6kQmdtvFNnFQPWAbuSXQH -+zlV+I84W9srcWmEBfslxtU323DQph2j2XiCTs9v15AlsQReVkusBtXOlan7YMu0O -+Arg= -+-----END DSA PARAMETERS----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dsa512.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/dsa512.pem -new file mode 100644 -index 0000000..5f86d1a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dsa512.pem -@@ -0,0 +1,6 @@ -+-----BEGIN DSA PARAMETERS----- -+MIGdAkEAnRtpjibb8isRcBmG9hnI+BnyGFOURgbQYlAzSwI8UjADizv5X9EkBk97 -+TLqqQJv9luQ3M7stWtdaEUBmonZ9MQIVAPtT71C0QJIxVoZTeuiLIppJ+3GPAkEA -+gz6I5cWJc847bAFJv7PHnwrqRJHlMKrZvltftxDXibeOdPvPKR7rqCxUUbgQ3qDO -+L8wka5B33qJoplISogOdIA== -+-----END DSA PARAMETERS----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dsap.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/dsap.pem -new file mode 100644 -index 0000000..d4dfdb3 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dsap.pem -@@ -0,0 +1,6 @@ -+-----BEGIN DSA PARAMETERS----- -+MIGcAkEA+ZiKEvZmc9MtnaFZh4NiZ3oZS4J1PHvPrm9MXj5ntVheDPkdmBDTncya -+GAJcMjwsyB/GvLDGd6yGCw/8eF+09wIVAK3VagOxGd/Q4Af5NbxR5FB7CXEjAkA2 -+t/q7HgVLi0KeKvcDG8BRl3wuy7bCvpjgtWiJc/tpvcuzeuAayH89UofjAGueKjXD -+ADiRffvSdhrNw5dkqdql -+-----END DSA PARAMETERS----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/dsaparam.c b/CryptoPkg/Library/OpensslLib/openssl/apps/dsaparam.c -new file mode 100644 -index 0000000..9258803 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/dsaparam.c -@@ -0,0 +1,313 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#ifdef OPENSSL_NO_DSA -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include -+# include -+# include -+# include -+# include "apps.h" -+# include -+# include -+# include -+# include -+# include -+# include -+ -+# ifdef GENCB_TEST -+ -+static int stop_keygen_flag = 0; -+ -+static void timebomb_sigalarm(int foo) -+{ -+ stop_keygen_flag = 1; -+} -+ -+# endif -+ -+static int dsa_cb(int p, int n, BN_GENCB *cb); -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C, -+ OPT_NOOUT, OPT_GENKEY, OPT_RAND, OPT_ENGINE, -+ OPT_TIMEBOMB -+} OPTION_CHOICE; -+ -+OPTIONS dsaparam_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"text", OPT_TEXT, '-', "Print as text"}, -+ {"C", OPT_C, '-', "Output C code"}, -+ {"noout", OPT_NOOUT, '-', "No output"}, -+ {"genkey", OPT_GENKEY, '-', "Generate a DSA key"}, -+ {"rand", OPT_RAND, 's', "Files to use for random number input"}, -+# ifdef GENCB_TEST -+ {"timebomb", OPT_TIMEBOMB, 'p', "Interrupt keygen after 'pnum' seconds"}, -+# endif -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+int dsaparam_main(int argc, char **argv) -+{ -+ ENGINE *e = NULL; -+ DSA *dsa = NULL; -+ BIO *in = NULL, *out = NULL; -+ BN_GENCB *cb = NULL; -+ int numbits = -1, num = 0, genkey = 0, need_rand = 0; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0; -+ int ret = 1, i, text = 0, private = 0; -+# ifdef GENCB_TEST -+ int timebomb = 0; -+# endif -+ char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL; -+ OPTION_CHOICE o; -+ -+ prog = opt_init(argc, argv, dsaparam_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(dsaparam_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_TIMEBOMB: -+# ifdef GENCB_TEST -+ timebomb = atoi(opt_arg()); -+ break; -+# endif -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_C: -+ C = 1; -+ break; -+ case OPT_GENKEY: -+ genkey = need_rand = 1; -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ need_rand = 1; -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ -+ if (argc == 1) { -+ if (!opt_int(argv[0], &num) || num < 0) -+ goto end; -+ /* generate a key */ -+ numbits = num; -+ need_rand = 1; -+ } -+ private = genkey ? 1 : 0; -+ -+ in = bio_open_default(infile, 'r', informat); -+ if (in == NULL) -+ goto end; -+ out = bio_open_owner(outfile, outformat, private); -+ if (out == NULL) -+ goto end; -+ -+ if (need_rand) { -+ app_RAND_load_file(NULL, (inrand != NULL)); -+ if (inrand != NULL) -+ BIO_printf(bio_err, "%ld semi-random bytes loaded\n", -+ app_RAND_load_files(inrand)); -+ } -+ -+ if (numbits > 0) { -+ cb = BN_GENCB_new(); -+ if (cb == NULL) { -+ BIO_printf(bio_err, "Error allocating BN_GENCB object\n"); -+ goto end; -+ } -+ BN_GENCB_set(cb, dsa_cb, bio_err); -+ assert(need_rand); -+ dsa = DSA_new(); -+ if (dsa == NULL) { -+ BIO_printf(bio_err, "Error allocating DSA object\n"); -+ goto end; -+ } -+ BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", -+ num); -+ BIO_printf(bio_err, "This could take some time\n"); -+# ifdef GENCB_TEST -+ if (timebomb > 0) { -+ struct sigaction act; -+ act.sa_handler = timebomb_sigalarm; -+ act.sa_flags = 0; -+ BIO_printf(bio_err, -+ "(though I'll stop it if not done within %d secs)\n", -+ timebomb); -+ if (sigaction(SIGALRM, &act, NULL) != 0) { -+ BIO_printf(bio_err, "Error, couldn't set SIGALRM handler\n"); -+ goto end; -+ } -+ alarm(timebomb); -+ } -+# endif -+ if (!DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, cb)) { -+# ifdef GENCB_TEST -+ if (stop_keygen_flag) { -+ BIO_printf(bio_err, "DSA key generation time-stopped\n"); -+ /* This is an asked-for behaviour! */ -+ ret = 0; -+ goto end; -+ } -+# endif -+ ERR_print_errors(bio_err); -+ BIO_printf(bio_err, "Error, DSA key generation failed\n"); -+ goto end; -+ } -+ } else if (informat == FORMAT_ASN1) -+ dsa = d2i_DSAparams_bio(in, NULL); -+ else -+ dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); -+ if (dsa == NULL) { -+ BIO_printf(bio_err, "unable to load DSA parameters\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (text) { -+ DSAparams_print(out, dsa); -+ } -+ -+ if (C) { -+ const BIGNUM *p = NULL, *q = NULL, *g = NULL; -+ unsigned char *data; -+ int len, bits_p; -+ -+ DSA_get0_pqg(dsa, &p, &q, &g); -+ len = BN_num_bytes(p); -+ bits_p = BN_num_bits(p); -+ -+ data = app_malloc(len + 20, "BN space"); -+ -+ BIO_printf(bio_out, "DSA *get_dsa%d()\n{\n", bits_p); -+ print_bignum_var(bio_out, p, "dsap", len, data); -+ print_bignum_var(bio_out, q, "dsaq", len, data); -+ print_bignum_var(bio_out, g, "dsag", len, data); -+ BIO_printf(bio_out, " DSA *dsa = DSA_new();\n" -+ "\n"); -+ BIO_printf(bio_out, " if (dsa == NULL)\n" -+ " return NULL;\n"); -+ BIO_printf(bio_out, " dsa->p = BN_bin2bn(dsap_%d, sizeof (dsap_%d), NULL);\n", -+ bits_p, bits_p); -+ BIO_printf(bio_out, " dsa->q = BN_bin2bn(dsaq_%d, sizeof (dsaq_%d), NULL);\n", -+ bits_p, bits_p); -+ BIO_printf(bio_out, " dsa->g = BN_bin2bn(dsag_%d, sizeof (dsag_%d), NULL);\n", -+ bits_p, bits_p); -+ BIO_printf(bio_out, " if (!dsa->p || !dsa->q || !dsa->g) {\n" -+ " DSA_free(dsa);\n" -+ " return NULL;\n" -+ " }\n" -+ " return(dsa);\n}\n"); -+ OPENSSL_free(data); -+ } -+ -+ if (!noout) { -+ if (outformat == FORMAT_ASN1) -+ i = i2d_DSAparams_bio(out, dsa); -+ else -+ i = PEM_write_bio_DSAparams(out, dsa); -+ if (!i) { -+ BIO_printf(bio_err, "unable to write DSA parameters\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ if (genkey) { -+ DSA *dsakey; -+ -+ assert(need_rand); -+ if ((dsakey = DSAparams_dup(dsa)) == NULL) -+ goto end; -+ if (!DSA_generate_key(dsakey)) { -+ ERR_print_errors(bio_err); -+ DSA_free(dsakey); -+ goto end; -+ } -+ assert(private); -+ if (outformat == FORMAT_ASN1) -+ i = i2d_DSAPrivateKey_bio(out, dsakey); -+ else -+ i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, -+ NULL); -+ DSA_free(dsakey); -+ } -+ if (need_rand) -+ app_RAND_write_file(NULL); -+ ret = 0; -+ end: -+ BN_GENCB_free(cb); -+ BIO_free(in); -+ BIO_free_all(out); -+ DSA_free(dsa); -+ release_engine(e); -+ return (ret); -+} -+ -+static int dsa_cb(int p, int n, BN_GENCB *cb) -+{ -+ char c = '*'; -+ -+ if (p == 0) -+ c = '.'; -+ if (p == 1) -+ c = '+'; -+ if (p == 2) -+ c = '*'; -+ if (p == 3) -+ c = '\n'; -+ BIO_write(BN_GENCB_get_arg(cb), &c, 1); -+ (void)BIO_flush(BN_GENCB_get_arg(cb)); -+# ifdef GENCB_TEST -+ if (stop_keygen_flag) -+ return 0; -+# endif -+ return 1; -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/ec.c b/CryptoPkg/Library/OpensslLib/openssl/apps/ec.c -new file mode 100644 -index 0000000..2516c03 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/ec.c -@@ -0,0 +1,281 @@ -+/* -+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#ifdef OPENSSL_NO_EC -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include -+# include -+# include -+# include "apps.h" -+# include -+# include -+# include -+# include -+ -+static OPT_PAIR conv_forms[] = { -+ {"compressed", POINT_CONVERSION_COMPRESSED}, -+ {"uncompressed", POINT_CONVERSION_UNCOMPRESSED}, -+ {"hybrid", POINT_CONVERSION_HYBRID}, -+ {NULL} -+}; -+ -+static OPT_PAIR param_enc[] = { -+ {"named_curve", OPENSSL_EC_NAMED_CURVE}, -+ {"explicit", 0}, -+ {NULL} -+}; -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, -+ OPT_NOOUT, OPT_TEXT, OPT_PARAM_OUT, OPT_PUBIN, OPT_PUBOUT, -+ OPT_PASSIN, OPT_PASSOUT, OPT_PARAM_ENC, OPT_CONV_FORM, OPT_CIPHER, -+ OPT_NO_PUBLIC, OPT_CHECK -+} OPTION_CHOICE; -+ -+OPTIONS ec_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"in", OPT_IN, 's', "Input file"}, -+ {"inform", OPT_INFORM, 'f', "Input format - DER or PEM"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, -+ {"noout", OPT_NOOUT, '-', "Don't print key out"}, -+ {"text", OPT_TEXT, '-', "Print the key"}, -+ {"param_out", OPT_PARAM_OUT, '-', "Print the elliptic curve parameters"}, -+ {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, -+ {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, -+ {"no_public", OPT_NO_PUBLIC, '-', "exclude public key from private key"}, -+ {"check", OPT_CHECK, '-', "check key consistency"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+ {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, -+ {"param_enc", OPT_PARAM_ENC, 's', -+ "Specifies the way the ec parameters are encoded"}, -+ {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, -+ {"", OPT_CIPHER, '-', "Any supported cipher"}, -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+int ec_main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ ENGINE *e = NULL; -+ EC_KEY *eckey = NULL; -+ const EC_GROUP *group; -+ const EVP_CIPHER *enc = NULL; -+ point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; -+ char *infile = NULL, *outfile = NULL, *prog; -+ char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL; -+ OPTION_CHOICE o; -+ int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_form = 0, new_asn1_flag = 0; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0; -+ int pubin = 0, pubout = 0, param_out = 0, i, ret = 1, private = 0; -+ int no_public = 0, check = 0; -+ -+ prog = opt_init(argc, argv, ec_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(ec_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_PARAM_OUT: -+ param_out = 1; -+ break; -+ case OPT_PUBIN: -+ pubin = 1; -+ break; -+ case OPT_PUBOUT: -+ pubout = 1; -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ case OPT_PASSOUT: -+ passoutarg = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_CIPHER: -+ if (!opt_cipher(opt_unknown(), &enc)) -+ goto opthelp; -+ break; -+ case OPT_CONV_FORM: -+ if (!opt_pair(opt_arg(), conv_forms, &i)) -+ goto opthelp; -+ new_form = 1; -+ form = i; -+ break; -+ case OPT_PARAM_ENC: -+ if (!opt_pair(opt_arg(), param_enc, &i)) -+ goto opthelp; -+ new_asn1_flag = 1; -+ asn1_flag = i; -+ break; -+ case OPT_NO_PUBLIC: -+ no_public = 1; -+ break; -+ case OPT_CHECK: -+ check = 1; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ private = param_out || pubin || pubout ? 0 : 1; -+ if (text && !pubin) -+ private = 1; -+ -+ if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { -+ BIO_printf(bio_err, "Error getting passwords\n"); -+ goto end; -+ } -+ -+ if (informat != FORMAT_ENGINE) { -+ in = bio_open_default(infile, 'r', informat); -+ if (in == NULL) -+ goto end; -+ } -+ -+ BIO_printf(bio_err, "read EC key\n"); -+ if (informat == FORMAT_ASN1) { -+ if (pubin) -+ eckey = d2i_EC_PUBKEY_bio(in, NULL); -+ else -+ eckey = d2i_ECPrivateKey_bio(in, NULL); -+ } else if (informat == FORMAT_ENGINE) { -+ EVP_PKEY *pkey; -+ if (pubin) -+ pkey = load_pubkey(infile, informat , 1, passin, e, "Public Key"); -+ else -+ pkey = load_key(infile, informat, 1, passin, e, "Private Key"); -+ if (pkey != NULL) { -+ eckey = EVP_PKEY_get1_EC_KEY(pkey); -+ EVP_PKEY_free(pkey); -+ } -+ } else { -+ if (pubin) -+ eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL); -+ else -+ eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, passin); -+ } -+ if (eckey == NULL) { -+ BIO_printf(bio_err, "unable to load Key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ out = bio_open_owner(outfile, outformat, private); -+ if (out == NULL) -+ goto end; -+ -+ group = EC_KEY_get0_group(eckey); -+ -+ if (new_form) -+ EC_KEY_set_conv_form(eckey, form); -+ -+ if (new_asn1_flag) -+ EC_KEY_set_asn1_flag(eckey, asn1_flag); -+ -+ if (no_public) -+ EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY); -+ -+ if (text) { -+ assert(pubin || private); -+ if (!EC_KEY_print(out, eckey, 0)) { -+ perror(outfile); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (check) { -+ if (EC_KEY_check_key(eckey) == 1) { -+ BIO_printf(bio_err, "EC Key valid.\n"); -+ } else { -+ BIO_printf(bio_err, "EC Key Invalid!\n"); -+ ERR_print_errors(bio_err); -+ } -+ } -+ -+ if (noout) { -+ ret = 0; -+ goto end; -+ } -+ -+ BIO_printf(bio_err, "writing EC key\n"); -+ if (outformat == FORMAT_ASN1) { -+ if (param_out) -+ i = i2d_ECPKParameters_bio(out, group); -+ else if (pubin || pubout) -+ i = i2d_EC_PUBKEY_bio(out, eckey); -+ else { -+ assert(private); -+ i = i2d_ECPrivateKey_bio(out, eckey); -+ } -+ } else { -+ if (param_out) -+ i = PEM_write_bio_ECPKParameters(out, group); -+ else if (pubin || pubout) -+ i = PEM_write_bio_EC_PUBKEY(out, eckey); -+ else { -+ assert(private); -+ i = PEM_write_bio_ECPrivateKey(out, eckey, enc, -+ NULL, 0, NULL, passout); -+ } -+ } -+ -+ if (!i) { -+ BIO_printf(bio_err, "unable to write private key\n"); -+ ERR_print_errors(bio_err); -+ } else -+ ret = 0; -+ end: -+ BIO_free(in); -+ BIO_free_all(out); -+ EC_KEY_free(eckey); -+ release_engine(e); -+ OPENSSL_free(passin); -+ OPENSSL_free(passout); -+ return (ret); -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/ecparam.c b/CryptoPkg/Library/OpensslLib/openssl/apps/ecparam.c -new file mode 100644 -index 0000000..891a0ca ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/ecparam.c -@@ -0,0 +1,465 @@ -+/* -+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * -+ * Portions of the attached software ("Contribution") are developed by -+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. -+ * -+ * The Contribution is licensed pursuant to the OpenSSL open source -+ * license provided above. -+ * -+ * The elliptic curve binary polynomial software is originally written by -+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. -+ * -+ */ -+ -+#include -+#ifdef OPENSSL_NO_EC -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include -+# include -+# include -+# include -+# include "apps.h" -+# include -+# include -+# include -+# include -+# include -+# include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C, -+ OPT_CHECK, OPT_LIST_CURVES, OPT_NO_SEED, OPT_NOOUT, OPT_NAME, -+ OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_RAND, OPT_ENGINE -+} OPTION_CHOICE; -+ -+OPTIONS ecparam_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"}, -+ {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, -+ {"in", OPT_IN, '<', "Input file - default stdin"}, -+ {"out", OPT_OUT, '>', "Output file - default stdout"}, -+ {"text", OPT_TEXT, '-', "Print the ec parameters in text form"}, -+ {"C", OPT_C, '-', "Print a 'C' function creating the parameters"}, -+ {"check", OPT_CHECK, '-', "Validate the ec parameters"}, -+ {"list_curves", OPT_LIST_CURVES, '-', -+ "Prints a list of all curve 'short names'"}, -+ {"no_seed", OPT_NO_SEED, '-', -+ "If 'explicit' parameters are chosen do not use the seed"}, -+ {"noout", OPT_NOOUT, '-', "Do not print the ec parameter"}, -+ {"name", OPT_NAME, 's', -+ "Use the ec parameters with specified 'short name'"}, -+ {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "}, -+ {"param_enc", OPT_PARAM_ENC, 's', -+ "Specifies the way the ec parameters are encoded"}, -+ {"genkey", OPT_GENKEY, '-', "Generate ec key"}, -+ {"rand", OPT_RAND, 's', "Files to use for random number input"}, -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+static OPT_PAIR forms[] = { -+ {"compressed", POINT_CONVERSION_COMPRESSED}, -+ {"uncompressed", POINT_CONVERSION_UNCOMPRESSED}, -+ {"hybrid", POINT_CONVERSION_HYBRID}, -+ {NULL} -+}; -+ -+static OPT_PAIR encodings[] = { -+ {"named_curve", OPENSSL_EC_NAMED_CURVE}, -+ {"explicit", 0}, -+ {NULL} -+}; -+ -+int ecparam_main(int argc, char **argv) -+{ -+ ENGINE *e = NULL; -+ BIGNUM *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL; -+ BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL; -+ BIO *in = NULL, *out = NULL; -+ EC_GROUP *group = NULL; -+ point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; -+ char *curve_name = NULL, *inrand = NULL; -+ char *infile = NULL, *outfile = NULL, *prog; -+ unsigned char *buffer = NULL; -+ OPTION_CHOICE o; -+ int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_asn1_flag = 0; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0; -+ int ret = 1, private = 0; -+ int list_curves = 0, no_seed = 0, check = 0, new_form = 0; -+ int text = 0, i, need_rand = 0, genkey = 0; -+ -+ prog = opt_init(argc, argv, ecparam_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(ecparam_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_C: -+ C = 1; -+ break; -+ case OPT_CHECK: -+ check = 1; -+ break; -+ case OPT_LIST_CURVES: -+ list_curves = 1; -+ break; -+ case OPT_NO_SEED: -+ no_seed = 1; -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ case OPT_NAME: -+ curve_name = opt_arg(); -+ break; -+ case OPT_CONV_FORM: -+ if (!opt_pair(opt_arg(), forms, &new_form)) -+ goto opthelp; -+ form = new_form; -+ new_form = 1; -+ break; -+ case OPT_PARAM_ENC: -+ if (!opt_pair(opt_arg(), encodings, &asn1_flag)) -+ goto opthelp; -+ new_asn1_flag = 1; -+ break; -+ case OPT_GENKEY: -+ genkey = need_rand = 1; -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ need_rand = 1; -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ private = genkey ? 1 : 0; -+ -+ in = bio_open_default(infile, 'r', informat); -+ if (in == NULL) -+ goto end; -+ out = bio_open_owner(outfile, outformat, private); -+ if (out == NULL) -+ goto end; -+ -+ if (list_curves) { -+ EC_builtin_curve *curves = NULL; -+ size_t crv_len = EC_get_builtin_curves(NULL, 0); -+ size_t n; -+ -+ curves = app_malloc((int)sizeof(*curves) * crv_len, "list curves"); -+ if (!EC_get_builtin_curves(curves, crv_len)) { -+ OPENSSL_free(curves); -+ goto end; -+ } -+ -+ for (n = 0; n < crv_len; n++) { -+ const char *comment; -+ const char *sname; -+ comment = curves[n].comment; -+ sname = OBJ_nid2sn(curves[n].nid); -+ if (comment == NULL) -+ comment = "CURVE DESCRIPTION NOT AVAILABLE"; -+ if (sname == NULL) -+ sname = ""; -+ -+ BIO_printf(out, " %-10s: ", sname); -+ BIO_printf(out, "%s\n", comment); -+ } -+ -+ OPENSSL_free(curves); -+ ret = 0; -+ goto end; -+ } -+ -+ if (curve_name != NULL) { -+ int nid; -+ -+ /* -+ * workaround for the SECG curve names secp192r1 and secp256r1 (which -+ * are the same as the curves prime192v1 and prime256v1 defined in -+ * X9.62) -+ */ -+ if (strcmp(curve_name, "secp192r1") == 0) { -+ BIO_printf(bio_err, "using curve name prime192v1 " -+ "instead of secp192r1\n"); -+ nid = NID_X9_62_prime192v1; -+ } else if (strcmp(curve_name, "secp256r1") == 0) { -+ BIO_printf(bio_err, "using curve name prime256v1 " -+ "instead of secp256r1\n"); -+ nid = NID_X9_62_prime256v1; -+ } else -+ nid = OBJ_sn2nid(curve_name); -+ -+ if (nid == 0) -+ nid = EC_curve_nist2nid(curve_name); -+ -+ if (nid == 0) { -+ BIO_printf(bio_err, "unknown curve name (%s)\n", curve_name); -+ goto end; -+ } -+ -+ group = EC_GROUP_new_by_curve_name(nid); -+ if (group == NULL) { -+ BIO_printf(bio_err, "unable to create curve (%s)\n", curve_name); -+ goto end; -+ } -+ EC_GROUP_set_asn1_flag(group, asn1_flag); -+ EC_GROUP_set_point_conversion_form(group, form); -+ } else if (informat == FORMAT_ASN1) -+ group = d2i_ECPKParameters_bio(in, NULL); -+ else -+ group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); -+ if (group == NULL) { -+ BIO_printf(bio_err, "unable to load elliptic curve parameters\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (new_form) -+ EC_GROUP_set_point_conversion_form(group, form); -+ -+ if (new_asn1_flag) -+ EC_GROUP_set_asn1_flag(group, asn1_flag); -+ -+ if (no_seed) { -+ EC_GROUP_set_seed(group, NULL, 0); -+ } -+ -+ if (text) { -+ if (!ECPKParameters_print(out, group, 0)) -+ goto end; -+ } -+ -+ if (check) { -+ BIO_printf(bio_err, "checking elliptic curve parameters: "); -+ if (!EC_GROUP_check(group, NULL)) { -+ BIO_printf(bio_err, "failed\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ BIO_printf(bio_err, "ok\n"); -+ -+ } -+ -+ if (C) { -+ size_t buf_len = 0, tmp_len = 0; -+ const EC_POINT *point; -+ int is_prime, len = 0; -+ const EC_METHOD *meth = EC_GROUP_method_of(group); -+ -+ if ((ec_p = BN_new()) == NULL -+ || (ec_a = BN_new()) == NULL -+ || (ec_b = BN_new()) == NULL -+ || (ec_gen = BN_new()) == NULL -+ || (ec_order = BN_new()) == NULL -+ || (ec_cofactor = BN_new()) == NULL) { -+ perror("Can't allocate BN"); -+ goto end; -+ } -+ -+ is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field); -+ if (!is_prime) { -+ BIO_printf(bio_err, "Can only handle X9.62 prime fields\n"); -+ goto end; -+ } -+ -+ if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, ec_b, NULL)) -+ goto end; -+ -+ if ((point = EC_GROUP_get0_generator(group)) == NULL) -+ goto end; -+ if (!EC_POINT_point2bn(group, point, -+ EC_GROUP_get_point_conversion_form(group), -+ ec_gen, NULL)) -+ goto end; -+ if (!EC_GROUP_get_order(group, ec_order, NULL)) -+ goto end; -+ if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL)) -+ goto end; -+ -+ if (!ec_p || !ec_a || !ec_b || !ec_gen || !ec_order || !ec_cofactor) -+ goto end; -+ -+ len = BN_num_bits(ec_order); -+ -+ if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len) -+ buf_len = tmp_len; -+ if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len) -+ buf_len = tmp_len; -+ if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len) -+ buf_len = tmp_len; -+ if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len) -+ buf_len = tmp_len; -+ if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len) -+ buf_len = tmp_len; -+ if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len) -+ buf_len = tmp_len; -+ -+ buffer = app_malloc(buf_len, "BN buffer"); -+ -+ BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n{\n", len); -+ print_bignum_var(out, ec_p, "ec_p", len, buffer); -+ print_bignum_var(out, ec_a, "ec_a", len, buffer); -+ print_bignum_var(out, ec_b, "ec_b", len, buffer); -+ print_bignum_var(out, ec_gen, "ec_gen", len, buffer); -+ print_bignum_var(out, ec_order, "ec_order", len, buffer); -+ print_bignum_var(out, ec_cofactor, "ec_cofactor", len, buffer); -+ BIO_printf(out, " int ok = 0;\n" -+ " EC_GROUP *group = NULL;\n" -+ " EC_POINT *point = NULL;\n" -+ " BIGNUM *tmp_1 = NULL;\n" -+ " BIGNUM *tmp_2 = NULL;\n" -+ " BIGNUM *tmp_3 = NULL;\n" -+ "\n"); -+ -+ BIO_printf(out, " if ((tmp_1 = BN_bin2bn(ec_p_%d, sizeof (ec_p_%d), NULL)) == NULL)\n" -+ " goto err;\n", len, len); -+ BIO_printf(out, " if ((tmp_2 = BN_bin2bn(ec_a_%d, sizeof (ec_a_%d), NULL)) == NULL)\n" -+ " goto err;\n", len, len); -+ BIO_printf(out, " if ((tmp_3 = BN_bin2bn(ec_b_%d, sizeof (ec_b_%d), NULL)) == NULL)\n" -+ " goto err;\n", len, len); -+ BIO_printf(out, " if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)\n" -+ " goto err;\n" -+ "\n"); -+ BIO_printf(out, " /* build generator */\n"); -+ BIO_printf(out, " if ((tmp_1 = BN_bin2bn(ec_gen_%d, sizeof (ec_gen_%d), tmp_1)) == NULL)\n" -+ " goto err;\n", len, len); -+ BIO_printf(out, " point = EC_POINT_bn2point(group, tmp_1, NULL, NULL);\n"); -+ BIO_printf(out, " if (point == NULL)\n" -+ " goto err;\n"); -+ BIO_printf(out, " if ((tmp_2 = BN_bin2bn(ec_order_%d, sizeof (ec_order_%d), tmp_2)) == NULL)\n" -+ " goto err;\n", len, len); -+ BIO_printf(out, " if ((tmp_3 = BN_bin2bn(ec_cofactor_%d, sizeof (ec_cofactor_%d), tmp_3)) == NULL)\n" -+ " goto err;\n", len, len); -+ BIO_printf(out, " if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3))\n" -+ " goto err;\n" -+ "ok = 1;" -+ "\n"); -+ BIO_printf(out, "err:\n" -+ " BN_free(tmp_1);\n" -+ " BN_free(tmp_2);\n" -+ " BN_free(tmp_3);\n" -+ " EC_POINT_free(point);\n" -+ " if (!ok) {\n" -+ " EC_GROUP_free(group);\n" -+ " return NULL;\n" -+ " }\n" -+ " return (group);\n" -+ "}\n"); -+ } -+ -+ if (!noout) { -+ if (outformat == FORMAT_ASN1) -+ i = i2d_ECPKParameters_bio(out, group); -+ else -+ i = PEM_write_bio_ECPKParameters(out, group); -+ if (!i) { -+ BIO_printf(bio_err, "unable to write elliptic " -+ "curve parameters\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (need_rand) { -+ app_RAND_load_file(NULL, (inrand != NULL)); -+ if (inrand != NULL) -+ BIO_printf(bio_err, "%ld semi-random bytes loaded\n", -+ app_RAND_load_files(inrand)); -+ } -+ -+ if (genkey) { -+ EC_KEY *eckey = EC_KEY_new(); -+ -+ if (eckey == NULL) -+ goto end; -+ -+ assert(need_rand); -+ -+ if (EC_KEY_set_group(eckey, group) == 0) { -+ BIO_printf(bio_err, "unable to set group when generating key\n"); -+ EC_KEY_free(eckey); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (!EC_KEY_generate_key(eckey)) { -+ BIO_printf(bio_err, "unable to generate key\n"); -+ EC_KEY_free(eckey); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ assert(private); -+ if (outformat == FORMAT_ASN1) -+ i = i2d_ECPrivateKey_bio(out, eckey); -+ else -+ i = PEM_write_bio_ECPrivateKey(out, eckey, NULL, -+ NULL, 0, NULL, NULL); -+ EC_KEY_free(eckey); -+ } -+ -+ if (need_rand) -+ app_RAND_write_file(NULL); -+ -+ ret = 0; -+ end: -+ BN_free(ec_p); -+ BN_free(ec_a); -+ BN_free(ec_b); -+ BN_free(ec_gen); -+ BN_free(ec_order); -+ BN_free(ec_cofactor); -+ OPENSSL_free(buffer); -+ EC_GROUP_free(group); -+ release_engine(e); -+ BIO_free(in); -+ BIO_free_all(out); -+ return (ret); -+} -+ -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/enc.c b/CryptoPkg/Library/OpensslLib/openssl/apps/enc.c -new file mode 100644 -index 0000000..c66ad93 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/enc.c -@@ -0,0 +1,604 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef OPENSSL_NO_COMP -+# include -+#endif -+#include -+ -+#undef SIZE -+#undef BSIZE -+#define SIZE (512) -+#define BSIZE (8*1024) -+ -+static int set_hex(char *in, unsigned char *out, int size); -+static void show_ciphers(const OBJ_NAME *name, void *bio_); -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_LIST, -+ OPT_E, OPT_IN, OPT_OUT, OPT_PASS, OPT_ENGINE, OPT_D, OPT_P, OPT_V, -+ OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A, -+ OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE, -+ OPT_UPPER_S, OPT_IV, OPT_MD, OPT_CIPHER -+} OPTION_CHOICE; -+ -+OPTIONS enc_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"ciphers", OPT_LIST, '-', "List ciphers"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"pass", OPT_PASS, 's', "Passphrase source"}, -+ {"e", OPT_E, '-', "Encrypt"}, -+ {"d", OPT_D, '-', "Decrypt"}, -+ {"p", OPT_P, '-', "Print the iv/key"}, -+ {"P", OPT_UPPER_P, '-', "Print the iv/key and exit"}, -+ {"v", OPT_V, '-', "Verbose output"}, -+ {"nopad", OPT_NOPAD, '-', "Disable standard block padding"}, -+ {"salt", OPT_SALT, '-', "Use salt in the KDF (default)"}, -+ {"nosalt", OPT_NOSALT, '-', "Do not use salt in the KDF"}, -+ {"debug", OPT_DEBUG, '-', "Print debug info"}, -+ {"a", OPT_A, '-', "Base64 encode/decode, depending on encryption flag"}, -+ {"base64", OPT_A, '-', "Same as option -a"}, -+ {"A", OPT_UPPER_A, '-', -+ "Used with -[base64|a] to specify base64 buffer as a single line"}, -+ {"bufsize", OPT_BUFSIZE, 's', "Buffer size"}, -+ {"k", OPT_K, 's', "Passphrase"}, -+ {"kfile", OPT_KFILE, '<', "Read passphrase from file"}, -+ {"K", OPT_UPPER_K, 's', "Raw key, in hex"}, -+ {"S", OPT_UPPER_S, 's', "Salt, in hex"}, -+ {"iv", OPT_IV, 's', "IV in hex"}, -+ {"md", OPT_MD, 's', "Use specified digest to create a key from the passphrase"}, -+ {"none", OPT_NONE, '-', "Don't encrypt"}, -+ {"", OPT_CIPHER, '-', "Any supported cipher"}, -+#ifdef ZLIB -+ {"z", OPT_Z, '-', "Use zlib as the 'encryption'"}, -+#endif -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+#endif -+ {NULL} -+}; -+ -+int enc_main(int argc, char **argv) -+{ -+ static char buf[128]; -+ static const char magic[] = "Salted__"; -+ ENGINE *e = NULL; -+ BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio = -+ NULL, *wbio = NULL; -+ EVP_CIPHER_CTX *ctx = NULL; -+ const EVP_CIPHER *cipher = NULL, *c; -+ const EVP_MD *dgst = NULL; -+ char *hkey = NULL, *hiv = NULL, *hsalt = NULL, *p; -+ char *infile = NULL, *outfile = NULL, *prog; -+ char *str = NULL, *passarg = NULL, *pass = NULL, *strbuf = NULL; -+ char mbuf[sizeof magic - 1]; -+ OPTION_CHOICE o; -+ int bsize = BSIZE, verbose = 0, debug = 0, olb64 = 0, nosalt = 0; -+ int enc = 1, printkey = 0, i, k; -+ int base64 = 0, informat = FORMAT_BINARY, outformat = FORMAT_BINARY; -+ int ret = 1, inl, nopad = 0; -+ unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; -+ unsigned char *buff = NULL, salt[PKCS5_SALT_LEN]; -+ long n; -+#ifdef ZLIB -+ int do_zlib = 0; -+ BIO *bzl = NULL; -+#endif -+ -+ /* first check the program name */ -+ prog = opt_progname(argv[0]); -+ if (strcmp(prog, "base64") == 0) -+ base64 = 1; -+#ifdef ZLIB -+ else if (strcmp(prog, "zlib") == 0) -+ do_zlib = 1; -+#endif -+ else { -+ cipher = EVP_get_cipherbyname(prog); -+ if (cipher == NULL && strcmp(prog, "enc") != 0) { -+ BIO_printf(bio_err, "%s is not a known cipher\n", prog); -+ goto end; -+ } -+ } -+ -+ prog = opt_init(argc, argv, enc_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(enc_options); -+ ret = 0; -+ goto end; -+ case OPT_LIST: -+ BIO_printf(bio_err, "Supported ciphers:\n"); -+ OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, -+ show_ciphers, bio_err); -+ BIO_printf(bio_err, "\n"); -+ goto end; -+ case OPT_E: -+ enc = 1; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_PASS: -+ passarg = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_D: -+ enc = 0; -+ break; -+ case OPT_P: -+ printkey = 1; -+ break; -+ case OPT_V: -+ verbose = 1; -+ break; -+ case OPT_NOPAD: -+ nopad = 1; -+ break; -+ case OPT_SALT: -+ nosalt = 0; -+ break; -+ case OPT_NOSALT: -+ nosalt = 1; -+ break; -+ case OPT_DEBUG: -+ debug = 1; -+ break; -+ case OPT_UPPER_P: -+ printkey = 2; -+ break; -+ case OPT_UPPER_A: -+ olb64 = 1; -+ break; -+ case OPT_A: -+ base64 = 1; -+ break; -+ case OPT_Z: -+#ifdef ZLIB -+ do_zlib = 1; -+#endif -+ break; -+ case OPT_BUFSIZE: -+ p = opt_arg(); -+ i = (int)strlen(p) - 1; -+ k = i >= 1 && p[i] == 'k'; -+ if (k) -+ p[i] = '\0'; -+ if (!opt_long(opt_arg(), &n) -+ || n < 0 || (k && n >= LONG_MAX / 1024)) -+ goto opthelp; -+ if (k) -+ n *= 1024; -+ bsize = (int)n; -+ break; -+ case OPT_K: -+ str = opt_arg(); -+ break; -+ case OPT_KFILE: -+ in = bio_open_default(opt_arg(), 'r', FORMAT_TEXT); -+ if (in == NULL) -+ goto opthelp; -+ i = BIO_gets(in, buf, sizeof buf); -+ BIO_free(in); -+ in = NULL; -+ if (i <= 0) { -+ BIO_printf(bio_err, -+ "%s Can't read key from %s\n", prog, opt_arg()); -+ goto opthelp; -+ } -+ while (--i > 0 && (buf[i] == '\r' || buf[i] == '\n')) -+ buf[i] = '\0'; -+ if (i <= 0) { -+ BIO_printf(bio_err, "%s: zero length password\n", prog); -+ goto opthelp; -+ } -+ str = buf; -+ break; -+ case OPT_UPPER_K: -+ hkey = opt_arg(); -+ break; -+ case OPT_UPPER_S: -+ hsalt = opt_arg(); -+ break; -+ case OPT_IV: -+ hiv = opt_arg(); -+ break; -+ case OPT_MD: -+ if (!opt_md(opt_arg(), &dgst)) -+ goto opthelp; -+ break; -+ case OPT_CIPHER: -+ if (!opt_cipher(opt_unknown(), &c)) -+ goto opthelp; -+ cipher = c; -+ break; -+ case OPT_NONE: -+ cipher = NULL; -+ break; -+ } -+ } -+ -+ if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { -+ BIO_printf(bio_err, "%s: AEAD ciphers not supported\n", prog); -+ goto end; -+ } -+ -+ if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)) { -+ BIO_printf(bio_err, "%s XTS ciphers not supported\n", prog); -+ goto end; -+ } -+ -+ if (dgst == NULL) -+ dgst = EVP_sha256(); -+ -+ /* It must be large enough for a base64 encoded line */ -+ if (base64 && bsize < 80) -+ bsize = 80; -+ if (verbose) -+ BIO_printf(bio_err, "bufsize=%d\n", bsize); -+ -+#ifdef ZLIB -+ if (!do_zlib) -+#endif -+ if (base64) { -+ if (enc) -+ outformat = FORMAT_BASE64; -+ else -+ informat = FORMAT_BASE64; -+ } -+ -+ strbuf = app_malloc(SIZE, "strbuf"); -+ buff = app_malloc(EVP_ENCODE_LENGTH(bsize), "evp buffer"); -+ -+ if (infile == NULL) { -+ unbuffer(stdin); -+ in = dup_bio_in(informat); -+ } else -+ in = bio_open_default(infile, 'r', informat); -+ if (in == NULL) -+ goto end; -+ -+ if (!str && passarg) { -+ if (!app_passwd(passarg, NULL, &pass, NULL)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ str = pass; -+ } -+ -+ if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) { -+ if (1) { -+#ifndef OPENSSL_NO_UI -+ for (;;) { -+ char prompt[200]; -+ -+ BIO_snprintf(prompt, sizeof prompt, "enter %s %s password:", -+ OBJ_nid2ln(EVP_CIPHER_nid(cipher)), -+ (enc) ? "encryption" : "decryption"); -+ strbuf[0] = '\0'; -+ i = EVP_read_pw_string((char *)strbuf, SIZE, prompt, enc); -+ if (i == 0) { -+ if (strbuf[0] == '\0') { -+ ret = 1; -+ goto end; -+ } -+ str = strbuf; -+ break; -+ } -+ if (i < 0) { -+ BIO_printf(bio_err, "bad password read\n"); -+ goto end; -+ } -+ } -+ } else { -+#endif -+ BIO_printf(bio_err, "password required\n"); -+ goto end; -+ } -+ } -+ -+ out = bio_open_default(outfile, 'w', outformat); -+ if (out == NULL) -+ goto end; -+ -+ if (debug) { -+ BIO_set_callback(in, BIO_debug_callback); -+ BIO_set_callback(out, BIO_debug_callback); -+ BIO_set_callback_arg(in, (char *)bio_err); -+ BIO_set_callback_arg(out, (char *)bio_err); -+ } -+ -+ rbio = in; -+ wbio = out; -+ -+#ifdef ZLIB -+ if (do_zlib) { -+ if ((bzl = BIO_new(BIO_f_zlib())) == NULL) -+ goto end; -+ if (debug) { -+ BIO_set_callback(bzl, BIO_debug_callback); -+ BIO_set_callback_arg(bzl, (char *)bio_err); -+ } -+ if (enc) -+ wbio = BIO_push(bzl, wbio); -+ else -+ rbio = BIO_push(bzl, rbio); -+ } -+#endif -+ -+ if (base64) { -+ if ((b64 = BIO_new(BIO_f_base64())) == NULL) -+ goto end; -+ if (debug) { -+ BIO_set_callback(b64, BIO_debug_callback); -+ BIO_set_callback_arg(b64, (char *)bio_err); -+ } -+ if (olb64) -+ BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); -+ if (enc) -+ wbio = BIO_push(b64, wbio); -+ else -+ rbio = BIO_push(b64, rbio); -+ } -+ -+ if (cipher != NULL) { -+ /* -+ * Note that str is NULL if a key was passed on the command line, so -+ * we get no salt in that case. Is this a bug? -+ */ -+ if (str != NULL) { -+ /* -+ * Salt handling: if encrypting generate a salt and write to -+ * output BIO. If decrypting read salt from input BIO. -+ */ -+ unsigned char *sptr; -+ size_t str_len = strlen(str); -+ -+ if (nosalt) -+ sptr = NULL; -+ else { -+ if (enc) { -+ if (hsalt) { -+ if (!set_hex(hsalt, salt, sizeof salt)) { -+ BIO_printf(bio_err, "invalid hex salt value\n"); -+ goto end; -+ } -+ } else if (RAND_bytes(salt, sizeof salt) <= 0) -+ goto end; -+ /* -+ * If -P option then don't bother writing -+ */ -+ if ((printkey != 2) -+ && (BIO_write(wbio, magic, -+ sizeof magic - 1) != sizeof magic - 1 -+ || BIO_write(wbio, -+ (char *)salt, -+ sizeof salt) != sizeof salt)) { -+ BIO_printf(bio_err, "error writing output file\n"); -+ goto end; -+ } -+ } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf -+ || BIO_read(rbio, -+ (unsigned char *)salt, -+ sizeof salt) != sizeof salt) { -+ BIO_printf(bio_err, "error reading input file\n"); -+ goto end; -+ } else if (memcmp(mbuf, magic, sizeof magic - 1)) { -+ BIO_printf(bio_err, "bad magic number\n"); -+ goto end; -+ } -+ -+ sptr = salt; -+ } -+ -+ if (!EVP_BytesToKey(cipher, dgst, sptr, -+ (unsigned char *)str, -+ str_len, 1, key, iv)) { -+ BIO_printf(bio_err, "EVP_BytesToKey failed\n"); -+ goto end; -+ } -+ /* -+ * zero the complete buffer or the string passed from the command -+ * line bug picked up by Larry J. Hughes Jr. -+ */ -+ if (str == strbuf) -+ OPENSSL_cleanse(str, SIZE); -+ else -+ OPENSSL_cleanse(str, str_len); -+ } -+ if (hiv != NULL) { -+ int siz = EVP_CIPHER_iv_length(cipher); -+ if (siz == 0) { -+ BIO_printf(bio_err, "warning: iv not use by this cipher\n"); -+ } else if (!set_hex(hiv, iv, sizeof iv)) { -+ BIO_printf(bio_err, "invalid hex iv value\n"); -+ goto end; -+ } -+ } -+ if ((hiv == NULL) && (str == NULL) -+ && EVP_CIPHER_iv_length(cipher) != 0) { -+ /* -+ * No IV was explicitly set and no IV was generated during -+ * EVP_BytesToKey. Hence the IV is undefined, making correct -+ * decryption impossible. -+ */ -+ BIO_printf(bio_err, "iv undefined\n"); -+ goto end; -+ } -+ if ((hkey != NULL) && !set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) { -+ BIO_printf(bio_err, "invalid hex key value\n"); -+ goto end; -+ } -+ -+ if ((benc = BIO_new(BIO_f_cipher())) == NULL) -+ goto end; -+ -+ /* -+ * Since we may be changing parameters work on the encryption context -+ * rather than calling BIO_set_cipher(). -+ */ -+ -+ BIO_get_cipher_ctx(benc, &ctx); -+ -+ if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) { -+ BIO_printf(bio_err, "Error setting cipher %s\n", -+ EVP_CIPHER_name(cipher)); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (nopad) -+ EVP_CIPHER_CTX_set_padding(ctx, 0); -+ -+ if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) { -+ BIO_printf(bio_err, "Error setting cipher %s\n", -+ EVP_CIPHER_name(cipher)); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (debug) { -+ BIO_set_callback(benc, BIO_debug_callback); -+ BIO_set_callback_arg(benc, (char *)bio_err); -+ } -+ -+ if (printkey) { -+ if (!nosalt) { -+ printf("salt="); -+ for (i = 0; i < (int)sizeof(salt); i++) -+ printf("%02X", salt[i]); -+ printf("\n"); -+ } -+ if (EVP_CIPHER_key_length(cipher) > 0) { -+ printf("key="); -+ for (i = 0; i < EVP_CIPHER_key_length(cipher); i++) -+ printf("%02X", key[i]); -+ printf("\n"); -+ } -+ if (EVP_CIPHER_iv_length(cipher) > 0) { -+ printf("iv ="); -+ for (i = 0; i < EVP_CIPHER_iv_length(cipher); i++) -+ printf("%02X", iv[i]); -+ printf("\n"); -+ } -+ if (printkey == 2) { -+ ret = 0; -+ goto end; -+ } -+ } -+ } -+ -+ /* Only encrypt/decrypt as we write the file */ -+ if (benc != NULL) -+ wbio = BIO_push(benc, wbio); -+ -+ for (;;) { -+ inl = BIO_read(rbio, (char *)buff, bsize); -+ if (inl <= 0) -+ break; -+ if (BIO_write(wbio, (char *)buff, inl) != inl) { -+ BIO_printf(bio_err, "error writing output file\n"); -+ goto end; -+ } -+ } -+ if (!BIO_flush(wbio)) { -+ BIO_printf(bio_err, "bad decrypt\n"); -+ goto end; -+ } -+ -+ ret = 0; -+ if (verbose) { -+ BIO_printf(bio_err, "bytes read :%8"PRIu64"\n", BIO_number_read(in)); -+ BIO_printf(bio_err, "bytes written:%8"PRIu64"\n", BIO_number_written(out)); -+ } -+ end: -+ ERR_print_errors(bio_err); -+ OPENSSL_free(strbuf); -+ OPENSSL_free(buff); -+ BIO_free(in); -+ BIO_free_all(out); -+ BIO_free(benc); -+ BIO_free(b64); -+#ifdef ZLIB -+ BIO_free(bzl); -+#endif -+ release_engine(e); -+ OPENSSL_free(pass); -+ return (ret); -+} -+ -+static void show_ciphers(const OBJ_NAME *name, void *bio_) -+{ -+ BIO *bio = bio_; -+ static int n; -+ -+ if (!islower((unsigned char)*name->name)) -+ return; -+ -+ BIO_printf(bio, "-%-25s", name->name); -+ if (++n == 3) { -+ BIO_printf(bio, "\n"); -+ n = 0; -+ } else -+ BIO_printf(bio, " "); -+} -+ -+static int set_hex(char *in, unsigned char *out, int size) -+{ -+ int i, n; -+ unsigned char j; -+ -+ n = strlen(in); -+ if (n > (size * 2)) { -+ BIO_printf(bio_err, "hex string is too long\n"); -+ return (0); -+ } -+ memset(out, 0, size); -+ for (i = 0; i < n; i++) { -+ j = (unsigned char)*in; -+ *(in++) = '\0'; -+ if (j == 0) -+ break; -+ if (!isxdigit(j)) { -+ BIO_printf(bio_err, "non-hex digit\n"); -+ return (0); -+ } -+ j = (unsigned char)OPENSSL_hexchar2int(j); -+ if (i & 1) -+ out[i / 2] |= j; -+ else -+ out[i / 2] = (j << 4); -+ } -+ return (1); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/engine.c b/CryptoPkg/Library/OpensslLib/openssl/apps/engine.c -new file mode 100644 -index 0000000..ffd3137 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/engine.c -@@ -0,0 +1,445 @@ -+/* -+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#ifdef OPENSSL_NO_ENGINE -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include "apps.h" -+# include -+# include -+# include -+# include -+# include -+# include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_C, OPT_T, OPT_TT, OPT_PRE, OPT_POST, -+ OPT_V = 100, OPT_VV, OPT_VVV, OPT_VVVV -+} OPTION_CHOICE; -+ -+OPTIONS engine_options[] = { -+ {OPT_HELP_STR, 1, '-', "Usage: %s [options] engine...\n"}, -+ {OPT_HELP_STR, 1, '-', -+ " engine... Engines to load\n"}, -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"v", OPT_V, '-', "List 'control commands' For each specified engine"}, -+ {"vv", OPT_VV, '-', "Also display each command's description"}, -+ {"vvv", OPT_VVV, '-', "Also add the input flags for each command"}, -+ {"vvvv", OPT_VVVV, '-', "Also show internal input flags"}, -+ {"c", OPT_C, '-', "List the capabilities of specified engine"}, -+ {"t", OPT_T, '-', "Check that specified engine is available"}, -+ {"tt", OPT_TT, '-', "Display error trace for unavailable engines"}, -+ {"pre", OPT_PRE, 's', "Run command against the ENGINE before loading it"}, -+ {"post", OPT_POST, 's', "Run command against the ENGINE after loading it"}, -+ {OPT_MORE_STR, OPT_EOF, 1, -+ "Commands are like \"SO_PATH:/lib/libdriver.so\""}, -+ {NULL} -+}; -+ -+static int append_buf(char **buf, int *size, const char *s) -+{ -+ if (*buf == NULL) { -+ *size = 256; -+ *buf = app_malloc(*size, "engine buffer"); -+ **buf = '\0'; -+ } -+ -+ if (strlen(*buf) + strlen(s) >= (unsigned int)*size) { -+ char *tmp; -+ *size += 256; -+ tmp = OPENSSL_realloc(*buf, *size); -+ if (tmp == NULL) { -+ OPENSSL_free(*buf); -+ *buf = NULL; -+ return 0; -+ } -+ *buf = tmp; -+ } -+ -+ if (**buf != '\0') -+ OPENSSL_strlcat(*buf, ", ", *size); -+ OPENSSL_strlcat(*buf, s, *size); -+ -+ return 1; -+} -+ -+static int util_flags(BIO *out, unsigned int flags, const char *indent) -+{ -+ int started = 0, err = 0; -+ /* Indent before displaying input flags */ -+ BIO_printf(out, "%s%s(input flags): ", indent, indent); -+ if (flags == 0) { -+ BIO_printf(out, "\n"); -+ return 1; -+ } -+ /* -+ * If the object is internal, mark it in a way that shows instead of -+ * having it part of all the other flags, even if it really is. -+ */ -+ if (flags & ENGINE_CMD_FLAG_INTERNAL) { -+ BIO_printf(out, "[Internal] "); -+ } -+ -+ if (flags & ENGINE_CMD_FLAG_NUMERIC) { -+ BIO_printf(out, "NUMERIC"); -+ started = 1; -+ } -+ /* -+ * Now we check that no combinations of the mutually exclusive NUMERIC, -+ * STRING, and NO_INPUT flags have been used. Future flags that can be -+ * OR'd together with these would need to added after these to preserve -+ * the testing logic. -+ */ -+ if (flags & ENGINE_CMD_FLAG_STRING) { -+ if (started) { -+ BIO_printf(out, "|"); -+ err = 1; -+ } -+ BIO_printf(out, "STRING"); -+ started = 1; -+ } -+ if (flags & ENGINE_CMD_FLAG_NO_INPUT) { -+ if (started) { -+ BIO_printf(out, "|"); -+ err = 1; -+ } -+ BIO_printf(out, "NO_INPUT"); -+ started = 1; -+ } -+ /* Check for unknown flags */ -+ flags = flags & ~ENGINE_CMD_FLAG_NUMERIC & -+ ~ENGINE_CMD_FLAG_STRING & -+ ~ENGINE_CMD_FLAG_NO_INPUT & ~ENGINE_CMD_FLAG_INTERNAL; -+ if (flags) { -+ if (started) -+ BIO_printf(out, "|"); -+ BIO_printf(out, "<0x%04X>", flags); -+ } -+ if (err) -+ BIO_printf(out, " "); -+ BIO_printf(out, "\n"); -+ return 1; -+} -+ -+static int util_verbose(ENGINE *e, int verbose, BIO *out, const char *indent) -+{ -+ static const int line_wrap = 78; -+ int num; -+ int ret = 0; -+ char *name = NULL; -+ char *desc = NULL; -+ int flags; -+ int xpos = 0; -+ STACK_OF(OPENSSL_STRING) *cmds = NULL; -+ if (!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) || -+ ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE, -+ 0, NULL, NULL)) <= 0)) { -+ return 1; -+ } -+ -+ cmds = sk_OPENSSL_STRING_new_null(); -+ if (!cmds) -+ goto err; -+ -+ do { -+ int len; -+ /* Get the command input flags */ -+ if ((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, -+ NULL, NULL)) < 0) -+ goto err; -+ if (!(flags & ENGINE_CMD_FLAG_INTERNAL) || verbose >= 4) { -+ /* Get the command name */ -+ if ((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_LEN_FROM_CMD, num, -+ NULL, NULL)) <= 0) -+ goto err; -+ name = app_malloc(len + 1, "name buffer"); -+ if (ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_FROM_CMD, num, name, -+ NULL) <= 0) -+ goto err; -+ /* Get the command description */ -+ if ((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_LEN_FROM_CMD, num, -+ NULL, NULL)) < 0) -+ goto err; -+ if (len > 0) { -+ desc = app_malloc(len + 1, "description buffer"); -+ if (ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_FROM_CMD, num, desc, -+ NULL) <= 0) -+ goto err; -+ } -+ /* Now decide on the output */ -+ if (xpos == 0) -+ /* Do an indent */ -+ xpos = BIO_puts(out, indent); -+ else -+ /* Otherwise prepend a ", " */ -+ xpos += BIO_printf(out, ", "); -+ if (verbose == 1) { -+ /* -+ * We're just listing names, comma-delimited -+ */ -+ if ((xpos > (int)strlen(indent)) && -+ (xpos + (int)strlen(name) > line_wrap)) { -+ BIO_printf(out, "\n"); -+ xpos = BIO_puts(out, indent); -+ } -+ xpos += BIO_printf(out, "%s", name); -+ } else { -+ /* We're listing names plus descriptions */ -+ BIO_printf(out, "%s: %s\n", name, -+ (desc == NULL) ? "" : desc); -+ /* ... and sometimes input flags */ -+ if ((verbose >= 3) && !util_flags(out, flags, indent)) -+ goto err; -+ xpos = 0; -+ } -+ } -+ OPENSSL_free(name); -+ name = NULL; -+ OPENSSL_free(desc); -+ desc = NULL; -+ /* Move to the next command */ -+ num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE, num, NULL, NULL); -+ } while (num > 0); -+ if (xpos > 0) -+ BIO_printf(out, "\n"); -+ ret = 1; -+ err: -+ sk_OPENSSL_STRING_free(cmds); -+ OPENSSL_free(name); -+ OPENSSL_free(desc); -+ return ret; -+} -+ -+static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds, -+ BIO *out, const char *indent) -+{ -+ int loop, res, num = sk_OPENSSL_STRING_num(cmds); -+ -+ if (num < 0) { -+ BIO_printf(out, "[Error]: internal stack error\n"); -+ return; -+ } -+ for (loop = 0; loop < num; loop++) { -+ char buf[256]; -+ const char *cmd, *arg; -+ cmd = sk_OPENSSL_STRING_value(cmds, loop); -+ res = 1; /* assume success */ -+ /* Check if this command has no ":arg" */ -+ if ((arg = strstr(cmd, ":")) == NULL) { -+ if (!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0)) -+ res = 0; -+ } else { -+ if ((int)(arg - cmd) > 254) { -+ BIO_printf(out, "[Error]: command name too long\n"); -+ return; -+ } -+ memcpy(buf, cmd, (int)(arg - cmd)); -+ buf[arg - cmd] = '\0'; -+ arg++; /* Move past the ":" */ -+ /* Call the command with the argument */ -+ if (!ENGINE_ctrl_cmd_string(e, buf, arg, 0)) -+ res = 0; -+ } -+ if (res) -+ BIO_printf(out, "[Success]: %s\n", cmd); -+ else { -+ BIO_printf(out, "[Failure]: %s\n", cmd); -+ ERR_print_errors(out); -+ } -+ } -+} -+ -+int engine_main(int argc, char **argv) -+{ -+ int ret = 1, i; -+ int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0; -+ ENGINE *e; -+ STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null(); -+ STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null(); -+ STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null(); -+ BIO *out; -+ const char *indent = " "; -+ OPTION_CHOICE o; -+ char *prog; -+ char *argv1; -+ -+ out = dup_bio_out(FORMAT_TEXT); -+ if (engines == NULL || pre_cmds == NULL || post_cmds == NULL) -+ goto end; -+ -+ /* Remember the original command name, parse/skip any leading engine -+ * names, and then setup to parse the rest of the line as flags. */ -+ prog = argv[0]; -+ while ((argv1 = argv[1]) != NULL && *argv1 != '-') { -+ sk_OPENSSL_CSTRING_push(engines, argv1); -+ argc--; -+ argv++; -+ } -+ argv[0] = prog; -+ opt_init(argc, argv, engine_options); -+ -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(engine_options); -+ ret = 0; -+ goto end; -+ case OPT_VVVV: -+ case OPT_VVV: -+ case OPT_VV: -+ case OPT_V: -+ /* Convert to an integer from one to four. */ -+ i = (int)(o - OPT_V) + 1; -+ if (verbose < i) -+ verbose = i; -+ break; -+ case OPT_C: -+ list_cap = 1; -+ break; -+ case OPT_TT: -+ test_avail_noise++; -+ case OPT_T: -+ test_avail++; -+ break; -+ case OPT_PRE: -+ sk_OPENSSL_STRING_push(pre_cmds, opt_arg()); -+ break; -+ case OPT_POST: -+ sk_OPENSSL_STRING_push(post_cmds, opt_arg()); -+ break; -+ } -+ } -+ -+ /* Allow any trailing parameters as engine names. */ -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ for ( ; *argv; argv++) { -+ if (**argv == '-') { -+ BIO_printf(bio_err, "%s: Cannot mix flags and engine names.\n", -+ prog); -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ } -+ sk_OPENSSL_CSTRING_push(engines, *argv); -+ } -+ -+ if (sk_OPENSSL_CSTRING_num(engines) == 0) { -+ for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) { -+ sk_OPENSSL_CSTRING_push(engines, ENGINE_get_id(e)); -+ } -+ } -+ -+ ret = 0; -+ for (i = 0; i < sk_OPENSSL_CSTRING_num(engines); i++) { -+ const char *id = sk_OPENSSL_CSTRING_value(engines, i); -+ if ((e = ENGINE_by_id(id)) != NULL) { -+ const char *name = ENGINE_get_name(e); -+ /* -+ * Do "id" first, then "name". Easier to auto-parse. -+ */ -+ BIO_printf(out, "(%s) %s\n", id, name); -+ util_do_cmds(e, pre_cmds, out, indent); -+ if (strcmp(ENGINE_get_id(e), id) != 0) { -+ BIO_printf(out, "Loaded: (%s) %s\n", -+ ENGINE_get_id(e), ENGINE_get_name(e)); -+ } -+ if (list_cap) { -+ int cap_size = 256; -+ char *cap_buf = NULL; -+ int k, n; -+ const int *nids; -+ ENGINE_CIPHERS_PTR fn_c; -+ ENGINE_DIGESTS_PTR fn_d; -+ ENGINE_PKEY_METHS_PTR fn_pk; -+ -+ if (ENGINE_get_RSA(e) != NULL -+ && !append_buf(&cap_buf, &cap_size, "RSA")) -+ goto end; -+ if (ENGINE_get_DSA(e) != NULL -+ && !append_buf(&cap_buf, &cap_size, "DSA")) -+ goto end; -+ if (ENGINE_get_DH(e) != NULL -+ && !append_buf(&cap_buf, &cap_size, "DH")) -+ goto end; -+ if (ENGINE_get_RAND(e) != NULL -+ && !append_buf(&cap_buf, &cap_size, "RAND")) -+ goto end; -+ -+ fn_c = ENGINE_get_ciphers(e); -+ if (!fn_c) -+ goto skip_ciphers; -+ n = fn_c(e, NULL, &nids, 0); -+ for (k = 0; k < n; ++k) -+ if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k]))) -+ goto end; -+ -+ skip_ciphers: -+ fn_d = ENGINE_get_digests(e); -+ if (!fn_d) -+ goto skip_digests; -+ n = fn_d(e, NULL, &nids, 0); -+ for (k = 0; k < n; ++k) -+ if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k]))) -+ goto end; -+ -+ skip_digests: -+ fn_pk = ENGINE_get_pkey_meths(e); -+ if (!fn_pk) -+ goto skip_pmeths; -+ n = fn_pk(e, NULL, &nids, 0); -+ for (k = 0; k < n; ++k) -+ if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k]))) -+ goto end; -+ skip_pmeths: -+ if (cap_buf && (*cap_buf != '\0')) -+ BIO_printf(out, " [%s]\n", cap_buf); -+ -+ OPENSSL_free(cap_buf); -+ } -+ if (test_avail) { -+ BIO_printf(out, "%s", indent); -+ if (ENGINE_init(e)) { -+ BIO_printf(out, "[ available ]\n"); -+ util_do_cmds(e, post_cmds, out, indent); -+ ENGINE_finish(e); -+ } else { -+ BIO_printf(out, "[ unavailable ]\n"); -+ if (test_avail_noise) -+ ERR_print_errors_fp(stdout); -+ ERR_clear_error(); -+ } -+ } -+ if ((verbose > 0) && !util_verbose(e, verbose, out, indent)) -+ goto end; -+ ENGINE_free(e); -+ } else { -+ ERR_print_errors(bio_err); -+ /* because exit codes above 127 have special meaning on Unix */ -+ if (++ret > 127) -+ ret = 127; -+ } -+ } -+ -+ end: -+ -+ ERR_print_errors(bio_err); -+ sk_OPENSSL_CSTRING_free(engines); -+ sk_OPENSSL_STRING_free(pre_cmds); -+ sk_OPENSSL_STRING_free(post_cmds); -+ BIO_free_all(out); -+ return (ret); -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/errstr.c b/CryptoPkg/Library/OpensslLib/openssl/apps/errstr.c -new file mode 100644 -index 0000000..5fda799 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/errstr.c -@@ -0,0 +1,67 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP -+} OPTION_CHOICE; -+ -+OPTIONS errstr_options[] = { -+ {OPT_HELP_STR, 1, '-', "Usage: %s [options] errnum...\n"}, -+ {OPT_HELP_STR, 1, '-', " errnum Error number\n"}, -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {NULL} -+}; -+ -+int errstr_main(int argc, char **argv) -+{ -+ OPTION_CHOICE o; -+ char buf[256], *prog; -+ int ret = 1; -+ unsigned long l; -+ -+ prog = opt_init(argc, argv, errstr_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(errstr_options); -+ ret = 0; -+ goto end; -+ } -+ } -+ -+ ret = 0; -+ for (argv = opt_rest(); *argv; argv++) { -+ if (sscanf(*argv, "%lx", &l) == 0) -+ ret++; -+ else { -+ /* We're not really an SSL application so this won't auto-init, but -+ * we're still interested in SSL error strings -+ */ -+ OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS -+ | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); -+ ERR_error_string_n(l, buf, sizeof buf); -+ BIO_printf(bio_out, "%s\n", buf); -+ } -+ } -+ end: -+ return (ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/gendsa.c b/CryptoPkg/Library/OpensslLib/openssl/apps/gendsa.c -new file mode 100644 -index 0000000..bdef022 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/gendsa.c -@@ -0,0 +1,147 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#ifdef OPENSSL_NO_DSA -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include -+# include -+# include -+# include -+# include "apps.h" -+# include -+# include -+# include -+# include -+# include -+# include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_RAND, OPT_CIPHER -+} OPTION_CHOICE; -+ -+OPTIONS gendsa_options[] = { -+ {OPT_HELP_STR, 1, '-', "Usage: %s [args] dsaparam-file\n"}, -+ {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"out", OPT_OUT, '>', "Output the key to the specified file"}, -+ {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, -+ {"rand", OPT_RAND, 's', -+ "Load the file(s) into the random number generator"}, -+ {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+int gendsa_main(int argc, char **argv) -+{ -+ ENGINE *e = NULL; -+ BIO *out = NULL, *in = NULL; -+ DSA *dsa = NULL; -+ const EVP_CIPHER *enc = NULL; -+ char *inrand = NULL, *dsaparams = NULL; -+ char *outfile = NULL, *passoutarg = NULL, *passout = NULL, *prog; -+ OPTION_CHOICE o; -+ int ret = 1, private = 0; -+ const BIGNUM *p = NULL; -+ -+ prog = opt_init(argc, argv, gendsa_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ ret = 0; -+ opt_help(gendsa_options); -+ goto end; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_PASSOUT: -+ passoutarg = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ break; -+ case OPT_CIPHER: -+ if (!opt_cipher(opt_unknown(), &enc)) -+ goto end; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ private = 1; -+ -+ if (argc != 1) -+ goto opthelp; -+ dsaparams = *argv; -+ -+ if (!app_passwd(NULL, passoutarg, NULL, &passout)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ -+ in = bio_open_default(dsaparams, 'r', FORMAT_PEM); -+ if (in == NULL) -+ goto end2; -+ -+ if ((dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) { -+ BIO_printf(bio_err, "unable to load DSA parameter file\n"); -+ goto end; -+ } -+ BIO_free(in); -+ in = NULL; -+ -+ out = bio_open_owner(outfile, FORMAT_PEM, private); -+ if (out == NULL) -+ goto end2; -+ -+ if (!app_RAND_load_file(NULL, 1) && inrand == NULL) { -+ BIO_printf(bio_err, -+ "warning, not much extra random data, consider using the -rand option\n"); -+ } -+ if (inrand != NULL) -+ BIO_printf(bio_err, "%ld semi-random bytes loaded\n", -+ app_RAND_load_files(inrand)); -+ -+ DSA_get0_pqg(dsa, &p, NULL, NULL); -+ BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(p)); -+ if (!DSA_generate_key(dsa)) -+ goto end; -+ -+ app_RAND_write_file(NULL); -+ -+ assert(private); -+ if (!PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout)) -+ goto end; -+ ret = 0; -+ end: -+ if (ret != 0) -+ ERR_print_errors(bio_err); -+ end2: -+ BIO_free(in); -+ BIO_free_all(out); -+ DSA_free(dsa); -+ release_engine(e); -+ OPENSSL_free(passout); -+ return (ret); -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/genpkey.c b/CryptoPkg/Library/OpensslLib/openssl/apps/genpkey.c -new file mode 100644 -index 0000000..9e37977 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/genpkey.c -@@ -0,0 +1,314 @@ -+/* -+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+#ifndef OPENSSL_NO_ENGINE -+# include -+#endif -+ -+static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e); -+static int genpkey_cb(EVP_PKEY_CTX *ctx); -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE, -+ OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER -+} OPTION_CHOICE; -+ -+OPTIONS genpkey_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"}, -+ {"pass", OPT_PASS, 's', "Output file pass phrase source"}, -+ {"paramfile", OPT_PARAMFILE, '<', "Parameters file"}, -+ {"algorithm", OPT_ALGORITHM, 's', "The public key algorithm"}, -+ {"pkeyopt", OPT_PKEYOPT, 's', -+ "Set the public key algorithm option as opt:value"}, -+ {"genparam", OPT_GENPARAM, '-', "Generate parameters, not key"}, -+ {"text", OPT_TEXT, '-', "Print the in text"}, -+ {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+#endif -+ /* This is deliberately last. */ -+ {OPT_HELP_STR, 1, 1, -+ "Order of options may be important! See the documentation.\n"}, -+ {NULL} -+}; -+ -+int genpkey_main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ ENGINE *e = NULL; -+ EVP_PKEY *pkey = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ char *outfile = NULL, *passarg = NULL, *pass = NULL, *prog; -+ const EVP_CIPHER *cipher = NULL; -+ OPTION_CHOICE o; -+ int outformat = FORMAT_PEM, text = 0, ret = 1, rv, do_param = 0; -+ int private = 0; -+ -+ prog = opt_init(argc, argv, genpkey_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ ret = 0; -+ opt_help(genpkey_options); -+ goto end; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_PASS: -+ passarg = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_PARAMFILE: -+ if (do_param == 1) -+ goto opthelp; -+ if (!init_keygen_file(&ctx, opt_arg(), e)) -+ goto end; -+ break; -+ case OPT_ALGORITHM: -+ if (!init_gen_str(&ctx, opt_arg(), e, do_param)) -+ goto end; -+ break; -+ case OPT_PKEYOPT: -+ if (ctx == NULL) { -+ BIO_printf(bio_err, "%s: No keytype specified.\n", prog); -+ goto opthelp; -+ } -+ if (pkey_ctrl_string(ctx, opt_arg()) <= 0) { -+ BIO_printf(bio_err, -+ "%s: Error setting %s parameter:\n", -+ prog, opt_arg()); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ break; -+ case OPT_GENPARAM: -+ if (ctx != NULL) -+ goto opthelp; -+ do_param = 1; -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_CIPHER: -+ if (!opt_cipher(opt_unknown(), &cipher) -+ || do_param == 1) -+ goto opthelp; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ private = do_param ? 0 : 1; -+ -+ if (ctx == NULL) -+ goto opthelp; -+ -+ if (!app_passwd(passarg, NULL, &pass, NULL)) { -+ BIO_puts(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ -+ out = bio_open_owner(outfile, outformat, private); -+ if (out == NULL) -+ goto end; -+ -+ EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); -+ EVP_PKEY_CTX_set_app_data(ctx, bio_err); -+ -+ if (do_param) { -+ if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) { -+ BIO_puts(bio_err, "Error generating parameters\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } else { -+ if (EVP_PKEY_keygen(ctx, &pkey) <= 0) { -+ BIO_puts(bio_err, "Error generating key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (do_param) -+ rv = PEM_write_bio_Parameters(out, pkey); -+ else if (outformat == FORMAT_PEM) { -+ assert(private); -+ rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass); -+ } else if (outformat == FORMAT_ASN1) { -+ assert(private); -+ rv = i2d_PrivateKey_bio(out, pkey); -+ } else { -+ BIO_printf(bio_err, "Bad format specified for key\n"); -+ goto end; -+ } -+ -+ if (rv <= 0) { -+ BIO_puts(bio_err, "Error writing key\n"); -+ ERR_print_errors(bio_err); -+ } -+ -+ if (text) { -+ if (do_param) -+ rv = EVP_PKEY_print_params(out, pkey, 0, NULL); -+ else -+ rv = EVP_PKEY_print_private(out, pkey, 0, NULL); -+ -+ if (rv <= 0) { -+ BIO_puts(bio_err, "Error printing key\n"); -+ ERR_print_errors(bio_err); -+ } -+ } -+ -+ ret = 0; -+ -+ end: -+ EVP_PKEY_free(pkey); -+ EVP_PKEY_CTX_free(ctx); -+ BIO_free_all(out); -+ BIO_free(in); -+ release_engine(e); -+ OPENSSL_free(pass); -+ return ret; -+} -+ -+static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e) -+{ -+ BIO *pbio; -+ EVP_PKEY *pkey = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ if (*pctx) { -+ BIO_puts(bio_err, "Parameters already set!\n"); -+ return 0; -+ } -+ -+ pbio = BIO_new_file(file, "r"); -+ if (!pbio) { -+ BIO_printf(bio_err, "Can't open parameter file %s\n", file); -+ return 0; -+ } -+ -+ pkey = PEM_read_bio_Parameters(pbio, NULL); -+ BIO_free(pbio); -+ -+ if (!pkey) { -+ BIO_printf(bio_err, "Error reading parameter file %s\n", file); -+ return 0; -+ } -+ -+ ctx = EVP_PKEY_CTX_new(pkey, e); -+ if (ctx == NULL) -+ goto err; -+ if (EVP_PKEY_keygen_init(ctx) <= 0) -+ goto err; -+ EVP_PKEY_free(pkey); -+ *pctx = ctx; -+ return 1; -+ -+ err: -+ BIO_puts(bio_err, "Error initializing context\n"); -+ ERR_print_errors(bio_err); -+ EVP_PKEY_CTX_free(ctx); -+ EVP_PKEY_free(pkey); -+ return 0; -+ -+} -+ -+int init_gen_str(EVP_PKEY_CTX **pctx, -+ const char *algname, ENGINE *e, int do_param) -+{ -+ EVP_PKEY_CTX *ctx = NULL; -+ const EVP_PKEY_ASN1_METHOD *ameth; -+ ENGINE *tmpeng = NULL; -+ int pkey_id; -+ -+ if (*pctx) { -+ BIO_puts(bio_err, "Algorithm already set!\n"); -+ return 0; -+ } -+ -+ ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1); -+ -+#ifndef OPENSSL_NO_ENGINE -+ if (!ameth && e) -+ ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1); -+#endif -+ -+ if (!ameth) { -+ BIO_printf(bio_err, "Algorithm %s not found\n", algname); -+ return 0; -+ } -+ -+ ERR_clear_error(); -+ -+ EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); -+#ifndef OPENSSL_NO_ENGINE -+ ENGINE_finish(tmpeng); -+#endif -+ ctx = EVP_PKEY_CTX_new_id(pkey_id, e); -+ -+ if (!ctx) -+ goto err; -+ if (do_param) { -+ if (EVP_PKEY_paramgen_init(ctx) <= 0) -+ goto err; -+ } else { -+ if (EVP_PKEY_keygen_init(ctx) <= 0) -+ goto err; -+ } -+ -+ *pctx = ctx; -+ return 1; -+ -+ err: -+ BIO_printf(bio_err, "Error initializing %s context\n", algname); -+ ERR_print_errors(bio_err); -+ EVP_PKEY_CTX_free(ctx); -+ return 0; -+ -+} -+ -+static int genpkey_cb(EVP_PKEY_CTX *ctx) -+{ -+ char c = '*'; -+ BIO *b = EVP_PKEY_CTX_get_app_data(ctx); -+ int p; -+ p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); -+ if (p == 0) -+ c = '.'; -+ if (p == 1) -+ c = '+'; -+ if (p == 2) -+ c = '*'; -+ if (p == 3) -+ c = '\n'; -+ BIO_write(b, &c, 1); -+ (void)BIO_flush(b); -+ return 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/genrsa.c b/CryptoPkg/Library/OpensslLib/openssl/apps/genrsa.c -new file mode 100644 -index 0000000..1ac66a9 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/genrsa.c -@@ -0,0 +1,192 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#ifdef OPENSSL_NO_RSA -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include -+# include -+# include -+# include -+# include "apps.h" -+# include -+# include -+# include -+# include -+# include -+# include -+# include -+# include -+ -+# define DEFBITS 2048 -+ -+static int genrsa_cb(int p, int n, BN_GENCB *cb); -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_3, OPT_F4, OPT_ENGINE, -+ OPT_OUT, OPT_RAND, OPT_PASSOUT, OPT_CIPHER -+} OPTION_CHOICE; -+ -+OPTIONS genrsa_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"3", OPT_3, '-', "Use 3 for the E value"}, -+ {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, -+ {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, -+ {"out", OPT_OUT, 's', "Output the key to specified file"}, -+ {"rand", OPT_RAND, 's', -+ "Load the file(s) into the random number generator"}, -+ {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, -+ {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+int genrsa_main(int argc, char **argv) -+{ -+ BN_GENCB *cb = BN_GENCB_new(); -+ PW_CB_DATA cb_data; -+ ENGINE *eng = NULL; -+ BIGNUM *bn = BN_new(); -+ BIO *out = NULL; -+ const BIGNUM *e; -+ RSA *rsa = NULL; -+ const EVP_CIPHER *enc = NULL; -+ int ret = 1, num = DEFBITS, private = 0; -+ unsigned long f4 = RSA_F4; -+ char *outfile = NULL, *passoutarg = NULL, *passout = NULL; -+ char *inrand = NULL, *prog, *hexe, *dece; -+ OPTION_CHOICE o; -+ -+ if (bn == NULL || cb == NULL) -+ goto end; -+ -+ BN_GENCB_set(cb, genrsa_cb, bio_err); -+ -+ prog = opt_init(argc, argv, genrsa_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ ret = 0; -+ opt_help(genrsa_options); -+ goto end; -+ case OPT_3: -+ f4 = 3; -+ break; -+ case OPT_F4: -+ f4 = RSA_F4; -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ eng = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ break; -+ case OPT_PASSOUT: -+ passoutarg = opt_arg(); -+ break; -+ case OPT_CIPHER: -+ if (!opt_cipher(opt_unknown(), &enc)) -+ goto end; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ private = 1; -+ -+ if (argv[0] && (!opt_int(argv[0], &num) || num <= 0)) -+ goto end; -+ -+ if (!app_passwd(NULL, passoutarg, NULL, &passout)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ -+ out = bio_open_owner(outfile, FORMAT_PEM, private); -+ if (out == NULL) -+ goto end; -+ -+ if (!app_RAND_load_file(NULL, 1) && inrand == NULL -+ && !RAND_status()) { -+ BIO_printf(bio_err, -+ "warning, not much extra random data, consider using the -rand option\n"); -+ } -+ if (inrand != NULL) -+ BIO_printf(bio_err, "%ld semi-random bytes loaded\n", -+ app_RAND_load_files(inrand)); -+ -+ BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n", -+ num); -+ rsa = eng ? RSA_new_method(eng) : RSA_new(); -+ if (rsa == NULL) -+ goto end; -+ -+ if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, cb)) -+ goto end; -+ -+ app_RAND_write_file(NULL); -+ -+ RSA_get0_key(rsa, NULL, &e, NULL); -+ hexe = BN_bn2hex(e); -+ dece = BN_bn2dec(e); -+ if (hexe && dece) { -+ BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe); -+ } -+ OPENSSL_free(hexe); -+ OPENSSL_free(dece); -+ cb_data.password = passout; -+ cb_data.prompt_info = outfile; -+ assert(private); -+ if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, -+ (pem_password_cb *)password_callback, -+ &cb_data)) -+ goto end; -+ -+ ret = 0; -+ end: -+ BN_free(bn); -+ BN_GENCB_free(cb); -+ RSA_free(rsa); -+ BIO_free_all(out); -+ release_engine(eng); -+ OPENSSL_free(passout); -+ if (ret != 0) -+ ERR_print_errors(bio_err); -+ return (ret); -+} -+ -+static int genrsa_cb(int p, int n, BN_GENCB *cb) -+{ -+ char c = '*'; -+ -+ if (p == 0) -+ c = '.'; -+ if (p == 1) -+ c = '+'; -+ if (p == 2) -+ c = '*'; -+ if (p == 3) -+ c = '\n'; -+ BIO_write(BN_GENCB_get_arg(cb), &c, 1); -+ (void)BIO_flush(BN_GENCB_get_arg(cb)); -+ return 1; -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/nseq.c b/CryptoPkg/Library/OpensslLib/openssl/apps/nseq.c -new file mode 100644 -index 0000000..018d5eb ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/nseq.c -@@ -0,0 +1,113 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "apps.h" -+#include -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_TOSEQ, OPT_IN, OPT_OUT -+} OPTION_CHOICE; -+ -+OPTIONS nseq_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"toseq", OPT_TOSEQ, '-', "Output NS Sequence file"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {NULL} -+}; -+ -+int nseq_main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ X509 *x509 = NULL; -+ NETSCAPE_CERT_SEQUENCE *seq = NULL; -+ OPTION_CHOICE o; -+ int toseq = 0, ret = 1, i; -+ char *infile = NULL, *outfile = NULL, *prog; -+ -+ prog = opt_init(argc, argv, nseq_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ ret = 0; -+ opt_help(nseq_options); -+ goto end; -+ case OPT_TOSEQ: -+ toseq = 1; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ in = bio_open_default(infile, 'r', FORMAT_PEM); -+ if (in == NULL) -+ goto end; -+ out = bio_open_default(outfile, 'w', FORMAT_PEM); -+ if (out == NULL) -+ goto end; -+ -+ if (toseq) { -+ seq = NETSCAPE_CERT_SEQUENCE_new(); -+ if (seq == NULL) -+ goto end; -+ seq->certs = sk_X509_new_null(); -+ if (seq->certs == NULL) -+ goto end; -+ while ((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) -+ sk_X509_push(seq->certs, x509); -+ -+ if (!sk_X509_num(seq->certs)) { -+ BIO_printf(bio_err, "%s: Error reading certs file %s\n", -+ prog, infile); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ PEM_write_bio_NETSCAPE_CERT_SEQUENCE(out, seq); -+ ret = 0; -+ goto end; -+ } -+ -+ seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL); -+ if (seq == NULL) { -+ BIO_printf(bio_err, "%s: Error reading sequence file %s\n", -+ prog, infile); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ for (i = 0; i < sk_X509_num(seq->certs); i++) { -+ x509 = sk_X509_value(seq->certs, i); -+ dump_cert_text(out, x509); -+ PEM_write_bio_X509(out, x509); -+ } -+ ret = 0; -+ end: -+ BIO_free(in); -+ BIO_free_all(out); -+ NETSCAPE_CERT_SEQUENCE_free(seq); -+ -+ return (ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/ocsp.c b/CryptoPkg/Library/OpensslLib/openssl/apps/ocsp.c -new file mode 100644 -index 0000000..41ea970 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/ocsp.c -@@ -0,0 +1,1290 @@ -+/* -+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+ -+#ifdef OPENSSL_NO_OCSP -+NON_EMPTY_TRANSLATION_UNIT -+#else -+# ifdef OPENSSL_SYS_VMS -+# define _XOPEN_SOURCE_EXTENDED/* So fd_set and friends get properly defined -+ * on OpenVMS */ -+# endif -+ -+# define USE_SOCKETS -+ -+# include -+# include -+# include -+# include -+# include -+ -+/* Needs to be included before the openssl headers */ -+# include "apps.h" -+# include -+# include -+# include -+# include -+# include -+# include -+# include -+ -+# if defined(NETWARE_CLIB) -+# ifdef NETWARE_BSDSOCK -+# include -+# include -+# else -+# include -+# endif -+# elif defined(NETWARE_LIBC) -+# ifdef NETWARE_BSDSOCK -+# include -+# else -+# include -+# endif -+# endif -+ -+/* Maximum leeway in validity period: default 5 minutes */ -+# define MAX_VALIDITY_PERIOD (5 * 60) -+ -+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, -+ const EVP_MD *cert_id_md, X509 *issuer, -+ STACK_OF(OCSP_CERTID) *ids); -+static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, -+ const EVP_MD *cert_id_md, X509 *issuer, -+ STACK_OF(OCSP_CERTID) *ids); -+static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, -+ STACK_OF(OPENSSL_STRING) *names, -+ STACK_OF(OCSP_CERTID) *ids, long nsec, -+ long maxage); -+static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, -+ CA_DB *db, X509 *ca, X509 *rcert, -+ EVP_PKEY *rkey, const EVP_MD *md, -+ STACK_OF(X509) *rother, unsigned long flags, -+ int nmin, int ndays, int badsig); -+ -+static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); -+static BIO *init_responder(const char *port); -+static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio); -+static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); -+ -+# ifndef OPENSSL_NO_SOCK -+static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, -+ const char *path, -+ const STACK_OF(CONF_VALUE) *headers, -+ OCSP_REQUEST *req, int req_timeout); -+# endif -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_OUTFILE, OPT_TIMEOUT, OPT_URL, OPT_HOST, OPT_PORT, -+ OPT_IGNORE_ERR, OPT_NOVERIFY, OPT_NONCE, OPT_NO_NONCE, -+ OPT_RESP_NO_CERTS, OPT_RESP_KEY_ID, OPT_NO_CERTS, -+ OPT_NO_SIGNATURE_VERIFY, OPT_NO_CERT_VERIFY, OPT_NO_CHAIN, -+ OPT_NO_CERT_CHECKS, OPT_NO_EXPLICIT, OPT_TRUST_OTHER, -+ OPT_NO_INTERN, OPT_BADSIG, OPT_TEXT, OPT_REQ_TEXT, OPT_RESP_TEXT, -+ OPT_REQIN, OPT_RESPIN, OPT_SIGNER, OPT_VAFILE, OPT_SIGN_OTHER, -+ OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, -+ OPT_VALIDITY_PERIOD, OPT_STATUS_AGE, OPT_SIGNKEY, OPT_REQOUT, -+ OPT_RESPOUT, OPT_PATH, OPT_ISSUER, OPT_CERT, OPT_SERIAL, -+ OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER, -+ OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_HEADER, -+ OPT_V_ENUM, -+ OPT_MD -+} OPTION_CHOICE; -+ -+OPTIONS ocsp_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"out", OPT_OUTFILE, '>', "Output filename"}, -+ {"timeout", OPT_TIMEOUT, 'p', -+ "Connection timeout (in seconds) to the OCSP responder"}, -+ {"url", OPT_URL, 's', "Responder URL"}, -+ {"host", OPT_HOST, 's', "TCP/IP hostname:port to connect to"}, -+ {"port", OPT_PORT, 'p', "Port to run responder on"}, -+ {"ignore_err", OPT_IGNORE_ERR, '-', -+ "Ignore Error response from OCSP responder, and retry "}, -+ {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"}, -+ {"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"}, -+ {"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"}, -+ {"resp_no_certs", OPT_RESP_NO_CERTS, '-', -+ "Don't include any certificates in response"}, -+ {"resp_key_id", OPT_RESP_KEY_ID, '-', -+ "Identify response by signing certificate key ID"}, -+ {"no_certs", OPT_NO_CERTS, '-', -+ "Don't include any certificates in signed request"}, -+ {"no_signature_verify", OPT_NO_SIGNATURE_VERIFY, '-', -+ "Don't check signature on response"}, -+ {"no_cert_verify", OPT_NO_CERT_VERIFY, '-', -+ "Don't check signing certificate"}, -+ {"no_chain", OPT_NO_CHAIN, '-', "Don't chain verify response"}, -+ {"no_cert_checks", OPT_NO_CERT_CHECKS, '-', -+ "Don't do additional checks on signing certificate"}, -+ {"no_explicit", OPT_NO_EXPLICIT, '-', -+ "Do not explicitly check the chain, just verify the root"}, -+ {"trust_other", OPT_TRUST_OTHER, '-', -+ "Don't verify additional certificates"}, -+ {"no_intern", OPT_NO_INTERN, '-', -+ "Don't search certificates contained in response for signer"}, -+ {"badsig", OPT_BADSIG, '-', -+ "Corrupt last byte of loaded OSCP response signature (for test)"}, -+ {"text", OPT_TEXT, '-', "Print text form of request and response"}, -+ {"req_text", OPT_REQ_TEXT, '-', "Print text form of request"}, -+ {"resp_text", OPT_RESP_TEXT, '-', "Print text form of response"}, -+ {"reqin", OPT_REQIN, 's', "File with the DER-encoded request"}, -+ {"respin", OPT_RESPIN, 's', "File with the DER-encoded response"}, -+ {"signer", OPT_SIGNER, '<', "Certificate to sign OCSP request with"}, -+ {"VAfile", OPT_VAFILE, '<', "Validator certificates file"}, -+ {"sign_other", OPT_SIGN_OTHER, '<', -+ "Additional certificates to include in signed request"}, -+ {"verify_other", OPT_VERIFY_OTHER, '<', -+ "Additional certificates to search for signer"}, -+ {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"}, -+ {"CApath", OPT_CAPATH, '<', "Trusted certificates directory"}, -+ {"no-CAfile", OPT_NOCAFILE, '-', -+ "Do not load the default certificates file"}, -+ {"no-CApath", OPT_NOCAPATH, '-', -+ "Do not load certificates from the default certificates directory"}, -+ {"validity_period", OPT_VALIDITY_PERIOD, 'u', -+ "Maximum validity discrepancy in seconds"}, -+ {"status_age", OPT_STATUS_AGE, 'p', "Maximum status age in seconds"}, -+ {"signkey", OPT_SIGNKEY, 's', "Private key to sign OCSP request with"}, -+ {"reqout", OPT_REQOUT, 's', "Output file for the DER-encoded request"}, -+ {"respout", OPT_RESPOUT, 's', "Output file for the DER-encoded response"}, -+ {"path", OPT_PATH, 's', "Path to use in OCSP request"}, -+ {"issuer", OPT_ISSUER, '<', "Issuer certificate"}, -+ {"cert", OPT_CERT, '<', "Certificate to check"}, -+ {"serial", OPT_SERIAL, 's', "Serial number to check"}, -+ {"index", OPT_INDEX, '<', "Certificate status index file"}, -+ {"CA", OPT_CA, '<', "CA certificate"}, -+ {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"}, -+ {"nrequest", OPT_REQUEST, 'p', -+ "Number of requests to accept (default unlimited)"}, -+ {"ndays", OPT_NDAYS, 'p', "Number of days before next update"}, -+ {"rsigner", OPT_RSIGNER, '<', -+ "Responder certificate to sign responses with"}, -+ {"rkey", OPT_RKEY, '<', "Responder key to sign responses with"}, -+ {"rother", OPT_ROTHER, '<', "Other certificates to include in response"}, -+ {"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"}, -+ {"header", OPT_HEADER, 's', "key=value header to add"}, -+ {"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"}, -+ OPT_V_OPTIONS, -+ {NULL} -+}; -+ -+int ocsp_main(int argc, char **argv) -+{ -+ BIO *acbio = NULL, *cbio = NULL, *derbio = NULL, *out = NULL; -+ const EVP_MD *cert_id_md = NULL, *rsign_md = NULL; -+ int trailing_md = 0; -+ CA_DB *rdb = NULL; -+ EVP_PKEY *key = NULL, *rkey = NULL; -+ OCSP_BASICRESP *bs = NULL; -+ OCSP_REQUEST *req = NULL; -+ OCSP_RESPONSE *resp = NULL; -+ STACK_OF(CONF_VALUE) *headers = NULL; -+ STACK_OF(OCSP_CERTID) *ids = NULL; -+ STACK_OF(OPENSSL_STRING) *reqnames = NULL; -+ STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; -+ STACK_OF(X509) *issuers = NULL; -+ X509 *issuer = NULL, *cert = NULL, *rca_cert = NULL; -+ X509 *signer = NULL, *rsigner = NULL; -+ X509_STORE *store = NULL; -+ X509_VERIFY_PARAM *vpm = NULL; -+ const char *CAfile = NULL, *CApath = NULL; -+ char *header, *value; -+ char *host = NULL, *port = NULL, *path = "/", *outfile = NULL; -+ char *rca_filename = NULL, *reqin = NULL, *respin = NULL; -+ char *reqout = NULL, *respout = NULL, *ridx_filename = NULL; -+ char *rsignfile = NULL, *rkeyfile = NULL; -+ char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; -+ char *signfile = NULL, *keyfile = NULL; -+ char *thost = NULL, *tport = NULL, *tpath = NULL; -+ int noCAfile = 0, noCApath = 0; -+ int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1; -+ int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1; -+ int req_text = 0, resp_text = 0, ret = 1; -+#ifndef OPENSSL_NO_SOCK -+ int req_timeout = -1; -+#endif -+ long nsec = MAX_VALIDITY_PERIOD, maxage = -1; -+ unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; -+ OPTION_CHOICE o; -+ char *prog; -+ -+ reqnames = sk_OPENSSL_STRING_new_null(); -+ if (!reqnames) -+ goto end; -+ ids = sk_OCSP_CERTID_new_null(); -+ if (!ids) -+ goto end; -+ if ((vpm = X509_VERIFY_PARAM_new()) == NULL) -+ return 1; -+ -+ prog = opt_init(argc, argv, ocsp_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ ret = 0; -+ opt_help(ocsp_options); -+ goto end; -+ case OPT_OUTFILE: -+ outfile = opt_arg(); -+ break; -+ case OPT_TIMEOUT: -+#ifndef OPENSSL_NO_SOCK -+ req_timeout = atoi(opt_arg()); -+#endif -+ break; -+ case OPT_URL: -+ OPENSSL_free(thost); -+ OPENSSL_free(tport); -+ OPENSSL_free(tpath); -+ thost = tport = tpath = NULL; -+ if (!OCSP_parse_url(opt_arg(), &host, &port, &path, &use_ssl)) { -+ BIO_printf(bio_err, "%s Error parsing URL\n", prog); -+ goto end; -+ } -+ thost = host; -+ tport = port; -+ tpath = path; -+ break; -+ case OPT_HOST: -+ host = opt_arg(); -+ break; -+ case OPT_PORT: -+ port = opt_arg(); -+ break; -+ case OPT_IGNORE_ERR: -+ ignore_err = 1; -+ break; -+ case OPT_NOVERIFY: -+ noverify = 1; -+ break; -+ case OPT_NONCE: -+ add_nonce = 2; -+ break; -+ case OPT_NO_NONCE: -+ add_nonce = 0; -+ break; -+ case OPT_RESP_NO_CERTS: -+ rflags |= OCSP_NOCERTS; -+ break; -+ case OPT_RESP_KEY_ID: -+ rflags |= OCSP_RESPID_KEY; -+ break; -+ case OPT_NO_CERTS: -+ sign_flags |= OCSP_NOCERTS; -+ break; -+ case OPT_NO_SIGNATURE_VERIFY: -+ verify_flags |= OCSP_NOSIGS; -+ break; -+ case OPT_NO_CERT_VERIFY: -+ verify_flags |= OCSP_NOVERIFY; -+ break; -+ case OPT_NO_CHAIN: -+ verify_flags |= OCSP_NOCHAIN; -+ break; -+ case OPT_NO_CERT_CHECKS: -+ verify_flags |= OCSP_NOCHECKS; -+ break; -+ case OPT_NO_EXPLICIT: -+ verify_flags |= OCSP_NOEXPLICIT; -+ break; -+ case OPT_TRUST_OTHER: -+ verify_flags |= OCSP_TRUSTOTHER; -+ break; -+ case OPT_NO_INTERN: -+ verify_flags |= OCSP_NOINTERN; -+ break; -+ case OPT_BADSIG: -+ badsig = 1; -+ break; -+ case OPT_TEXT: -+ req_text = resp_text = 1; -+ break; -+ case OPT_REQ_TEXT: -+ req_text = 1; -+ break; -+ case OPT_RESP_TEXT: -+ resp_text = 1; -+ break; -+ case OPT_REQIN: -+ reqin = opt_arg(); -+ break; -+ case OPT_RESPIN: -+ respin = opt_arg(); -+ break; -+ case OPT_SIGNER: -+ signfile = opt_arg(); -+ break; -+ case OPT_VAFILE: -+ verify_certfile = opt_arg(); -+ verify_flags |= OCSP_TRUSTOTHER; -+ break; -+ case OPT_SIGN_OTHER: -+ sign_certfile = opt_arg(); -+ break; -+ case OPT_VERIFY_OTHER: -+ verify_certfile = opt_arg(); -+ break; -+ case OPT_CAFILE: -+ CAfile = opt_arg(); -+ break; -+ case OPT_CAPATH: -+ CApath = opt_arg(); -+ break; -+ case OPT_NOCAFILE: -+ noCAfile = 1; -+ break; -+ case OPT_NOCAPATH: -+ noCApath = 1; -+ break; -+ case OPT_V_CASES: -+ if (!opt_verify(o, vpm)) -+ goto end; -+ vpmtouched++; -+ break; -+ case OPT_VALIDITY_PERIOD: -+ opt_long(opt_arg(), &nsec); -+ break; -+ case OPT_STATUS_AGE: -+ opt_long(opt_arg(), &maxage); -+ break; -+ case OPT_SIGNKEY: -+ keyfile = opt_arg(); -+ break; -+ case OPT_REQOUT: -+ reqout = opt_arg(); -+ break; -+ case OPT_RESPOUT: -+ respout = opt_arg(); -+ break; -+ case OPT_PATH: -+ path = opt_arg(); -+ break; -+ case OPT_ISSUER: -+ issuer = load_cert(opt_arg(), FORMAT_PEM, "issuer certificate"); -+ if (issuer == NULL) -+ goto end; -+ if (issuers == NULL) { -+ if ((issuers = sk_X509_new_null()) == NULL) -+ goto end; -+ } -+ sk_X509_push(issuers, issuer); -+ break; -+ case OPT_CERT: -+ X509_free(cert); -+ cert = load_cert(opt_arg(), FORMAT_PEM, "certificate"); -+ if (cert == NULL) -+ goto end; -+ if (cert_id_md == NULL) -+ cert_id_md = EVP_sha1(); -+ if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids)) -+ goto end; -+ if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) -+ goto end; -+ trailing_md = 0; -+ break; -+ case OPT_SERIAL: -+ if (cert_id_md == NULL) -+ cert_id_md = EVP_sha1(); -+ if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids)) -+ goto end; -+ if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) -+ goto end; -+ trailing_md = 0; -+ break; -+ case OPT_INDEX: -+ ridx_filename = opt_arg(); -+ break; -+ case OPT_CA: -+ rca_filename = opt_arg(); -+ break; -+ case OPT_NMIN: -+ opt_int(opt_arg(), &nmin); -+ if (ndays == -1) -+ ndays = 0; -+ break; -+ case OPT_REQUEST: -+ opt_int(opt_arg(), &accept_count); -+ break; -+ case OPT_NDAYS: -+ ndays = atoi(opt_arg()); -+ break; -+ case OPT_RSIGNER: -+ rsignfile = opt_arg(); -+ break; -+ case OPT_RKEY: -+ rkeyfile = opt_arg(); -+ break; -+ case OPT_ROTHER: -+ rcertfile = opt_arg(); -+ break; -+ case OPT_RMD: /* Response MessageDigest */ -+ if (!opt_md(opt_arg(), &rsign_md)) -+ goto end; -+ break; -+ case OPT_HEADER: -+ header = opt_arg(); -+ value = strchr(header, '='); -+ if (value == NULL) { -+ BIO_printf(bio_err, "Missing = in header key=value\n"); -+ goto opthelp; -+ } -+ *value++ = '\0'; -+ if (!X509V3_add_value(header, value, &headers)) -+ goto end; -+ break; -+ case OPT_MD: -+ if (trailing_md) { -+ BIO_printf(bio_err, -+ "%s: Digest must be before -cert or -serial\n", -+ prog); -+ goto opthelp; -+ } -+ if (!opt_md(opt_unknown(), &cert_id_md)) -+ goto opthelp; -+ trailing_md = 1; -+ break; -+ } -+ } -+ -+ if (trailing_md) { -+ BIO_printf(bio_err, "%s: Digest must be before -cert or -serial\n", -+ prog); -+ goto opthelp; -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ /* Have we anything to do? */ -+ if (!req && !reqin && !respin && !(port && ridx_filename)) -+ goto opthelp; -+ -+ out = bio_open_default(outfile, 'w', FORMAT_TEXT); -+ if (out == NULL) -+ goto end; -+ -+ if (!req && (add_nonce != 2)) -+ add_nonce = 0; -+ -+ if (!req && reqin) { -+ derbio = bio_open_default(reqin, 'r', FORMAT_ASN1); -+ if (derbio == NULL) -+ goto end; -+ req = d2i_OCSP_REQUEST_bio(derbio, NULL); -+ BIO_free(derbio); -+ if (!req) { -+ BIO_printf(bio_err, "Error reading OCSP request\n"); -+ goto end; -+ } -+ } -+ -+ if (!req && port) { -+ acbio = init_responder(port); -+ if (!acbio) -+ goto end; -+ } -+ -+ if (rsignfile) { -+ if (!rkeyfile) -+ rkeyfile = rsignfile; -+ rsigner = load_cert(rsignfile, FORMAT_PEM, "responder certificate"); -+ if (!rsigner) { -+ BIO_printf(bio_err, "Error loading responder certificate\n"); -+ goto end; -+ } -+ rca_cert = load_cert(rca_filename, FORMAT_PEM, "CA certificate"); -+ if (rcertfile) { -+ if (!load_certs(rcertfile, &rother, FORMAT_PEM, NULL, -+ "responder other certificates")) -+ goto end; -+ } -+ rkey = load_key(rkeyfile, FORMAT_PEM, 0, NULL, NULL, -+ "responder private key"); -+ if (!rkey) -+ goto end; -+ } -+ if (acbio) -+ BIO_printf(bio_err, "Waiting for OCSP client connections...\n"); -+ -+ redo_accept: -+ -+ if (acbio) { -+ if (!do_responder(&req, &cbio, acbio)) -+ goto end; -+ if (!req) { -+ resp = -+ OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, -+ NULL); -+ send_ocsp_response(cbio, resp); -+ goto done_resp; -+ } -+ } -+ -+ if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) { -+ BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); -+ goto end; -+ } -+ -+ if (req && add_nonce) -+ OCSP_request_add1_nonce(req, NULL, -1); -+ -+ if (signfile) { -+ if (!keyfile) -+ keyfile = signfile; -+ signer = load_cert(signfile, FORMAT_PEM, "signer certificate"); -+ if (!signer) { -+ BIO_printf(bio_err, "Error loading signer certificate\n"); -+ goto end; -+ } -+ if (sign_certfile) { -+ if (!load_certs(sign_certfile, &sign_other, FORMAT_PEM, NULL, -+ "signer certificates")) -+ goto end; -+ } -+ key = load_key(keyfile, FORMAT_PEM, 0, NULL, NULL, -+ "signer private key"); -+ if (!key) -+ goto end; -+ -+ if (!OCSP_request_sign -+ (req, signer, key, NULL, sign_other, sign_flags)) { -+ BIO_printf(bio_err, "Error signing OCSP request\n"); -+ goto end; -+ } -+ } -+ -+ if (req_text && req) -+ OCSP_REQUEST_print(out, req, 0); -+ -+ if (reqout) { -+ derbio = bio_open_default(reqout, 'w', FORMAT_ASN1); -+ if (derbio == NULL) -+ goto end; -+ i2d_OCSP_REQUEST_bio(derbio, req); -+ BIO_free(derbio); -+ } -+ -+ if (ridx_filename && (!rkey || !rsigner || !rca_cert)) { -+ BIO_printf(bio_err, -+ "Need a responder certificate, key and CA for this operation!\n"); -+ goto end; -+ } -+ -+ if (ridx_filename && !rdb) { -+ rdb = load_index(ridx_filename, NULL); -+ if (!rdb) -+ goto end; -+ if (!index_index(rdb)) -+ goto end; -+ } -+ -+ if (rdb) { -+ make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, -+ rsign_md, rother, rflags, nmin, ndays, badsig); -+ if (cbio) -+ send_ocsp_response(cbio, resp); -+ } else if (host) { -+# ifndef OPENSSL_NO_SOCK -+ resp = process_responder(req, host, path, -+ port, use_ssl, headers, req_timeout); -+ if (!resp) -+ goto end; -+# else -+ BIO_printf(bio_err, -+ "Error creating connect BIO - sockets not supported.\n"); -+ goto end; -+# endif -+ } else if (respin) { -+ derbio = bio_open_default(respin, 'r', FORMAT_ASN1); -+ if (derbio == NULL) -+ goto end; -+ resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); -+ BIO_free(derbio); -+ if (!resp) { -+ BIO_printf(bio_err, "Error reading OCSP response\n"); -+ goto end; -+ } -+ } else { -+ ret = 0; -+ goto end; -+ } -+ -+ done_resp: -+ -+ if (respout) { -+ derbio = bio_open_default(respout, 'w', FORMAT_ASN1); -+ if (derbio == NULL) -+ goto end; -+ i2d_OCSP_RESPONSE_bio(derbio, resp); -+ BIO_free(derbio); -+ } -+ -+ i = OCSP_response_status(resp); -+ if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { -+ BIO_printf(out, "Responder Error: %s (%d)\n", -+ OCSP_response_status_str(i), i); -+ if (ignore_err) -+ goto redo_accept; -+ ret = 0; -+ goto end; -+ } -+ -+ if (resp_text) -+ OCSP_RESPONSE_print(out, resp, 0); -+ -+ /* If running as responder don't verify our own response */ -+ if (cbio) { -+ /* If not unlimited, see if we took all we should. */ -+ if (accept_count != -1 && --accept_count <= 0) { -+ ret = 0; -+ goto end; -+ } -+ BIO_free_all(cbio); -+ cbio = NULL; -+ OCSP_REQUEST_free(req); -+ req = NULL; -+ OCSP_RESPONSE_free(resp); -+ resp = NULL; -+ goto redo_accept; -+ } -+ if (ridx_filename) { -+ ret = 0; -+ goto end; -+ } -+ -+ if (!store) { -+ store = setup_verify(CAfile, CApath, noCAfile, noCApath); -+ if (!store) -+ goto end; -+ } -+ if (vpmtouched) -+ X509_STORE_set1_param(store, vpm); -+ if (verify_certfile) { -+ if (!load_certs(verify_certfile, &verify_other, FORMAT_PEM, NULL, -+ "validator certificate")) -+ goto end; -+ } -+ -+ bs = OCSP_response_get1_basic(resp); -+ if (!bs) { -+ BIO_printf(bio_err, "Error parsing response\n"); -+ goto end; -+ } -+ -+ ret = 0; -+ -+ if (!noverify) { -+ if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) { -+ if (i == -1) -+ BIO_printf(bio_err, "WARNING: no nonce in response\n"); -+ else { -+ BIO_printf(bio_err, "Nonce Verify error\n"); -+ ret = 1; -+ goto end; -+ } -+ } -+ -+ i = OCSP_basic_verify(bs, verify_other, store, verify_flags); -+ if (i <= 0 && issuers) { -+ i = OCSP_basic_verify(bs, issuers, store, OCSP_TRUSTOTHER); -+ if (i > 0) -+ ERR_clear_error(); -+ } -+ if (i <= 0) { -+ BIO_printf(bio_err, "Response Verify Failure\n"); -+ ERR_print_errors(bio_err); -+ ret = 1; -+ } else -+ BIO_printf(bio_err, "Response verify OK\n"); -+ -+ } -+ -+ print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage); -+ -+ end: -+ ERR_print_errors(bio_err); -+ X509_free(signer); -+ X509_STORE_free(store); -+ X509_VERIFY_PARAM_free(vpm); -+ EVP_PKEY_free(key); -+ EVP_PKEY_free(rkey); -+ X509_free(cert); -+ sk_X509_pop_free(issuers, X509_free); -+ X509_free(rsigner); -+ X509_free(rca_cert); -+ free_index(rdb); -+ BIO_free_all(cbio); -+ BIO_free_all(acbio); -+ BIO_free(out); -+ OCSP_REQUEST_free(req); -+ OCSP_RESPONSE_free(resp); -+ OCSP_BASICRESP_free(bs); -+ sk_OPENSSL_STRING_free(reqnames); -+ sk_OCSP_CERTID_free(ids); -+ sk_X509_pop_free(sign_other, X509_free); -+ sk_X509_pop_free(verify_other, X509_free); -+ sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); -+ OPENSSL_free(thost); -+ OPENSSL_free(tport); -+ OPENSSL_free(tpath); -+ -+ return (ret); -+} -+ -+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, -+ const EVP_MD *cert_id_md, X509 *issuer, -+ STACK_OF(OCSP_CERTID) *ids) -+{ -+ OCSP_CERTID *id; -+ if (!issuer) { -+ BIO_printf(bio_err, "No issuer certificate specified\n"); -+ return 0; -+ } -+ if (*req == NULL) -+ *req = OCSP_REQUEST_new(); -+ if (*req == NULL) -+ goto err; -+ id = OCSP_cert_to_id(cert_id_md, cert, issuer); -+ if (!id || !sk_OCSP_CERTID_push(ids, id)) -+ goto err; -+ if (!OCSP_request_add0_id(*req, id)) -+ goto err; -+ return 1; -+ -+ err: -+ BIO_printf(bio_err, "Error Creating OCSP request\n"); -+ return 0; -+} -+ -+static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, -+ const EVP_MD *cert_id_md, X509 *issuer, -+ STACK_OF(OCSP_CERTID) *ids) -+{ -+ OCSP_CERTID *id; -+ X509_NAME *iname; -+ ASN1_BIT_STRING *ikey; -+ ASN1_INTEGER *sno; -+ if (!issuer) { -+ BIO_printf(bio_err, "No issuer certificate specified\n"); -+ return 0; -+ } -+ if (*req == NULL) -+ *req = OCSP_REQUEST_new(); -+ if (*req == NULL) -+ goto err; -+ iname = X509_get_subject_name(issuer); -+ ikey = X509_get0_pubkey_bitstr(issuer); -+ sno = s2i_ASN1_INTEGER(NULL, serial); -+ if (!sno) { -+ BIO_printf(bio_err, "Error converting serial number %s\n", serial); -+ return 0; -+ } -+ id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno); -+ ASN1_INTEGER_free(sno); -+ if (id == NULL || !sk_OCSP_CERTID_push(ids, id)) -+ goto err; -+ if (!OCSP_request_add0_id(*req, id)) -+ goto err; -+ return 1; -+ -+ err: -+ BIO_printf(bio_err, "Error Creating OCSP request\n"); -+ return 0; -+} -+ -+static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, -+ STACK_OF(OPENSSL_STRING) *names, -+ STACK_OF(OCSP_CERTID) *ids, long nsec, -+ long maxage) -+{ -+ OCSP_CERTID *id; -+ const char *name; -+ int i, status, reason; -+ ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; -+ -+ if (!bs || !req || !sk_OPENSSL_STRING_num(names) -+ || !sk_OCSP_CERTID_num(ids)) -+ return; -+ -+ for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) { -+ id = sk_OCSP_CERTID_value(ids, i); -+ name = sk_OPENSSL_STRING_value(names, i); -+ BIO_printf(out, "%s: ", name); -+ -+ if (!OCSP_resp_find_status(bs, id, &status, &reason, -+ &rev, &thisupd, &nextupd)) { -+ BIO_puts(out, "ERROR: No Status found.\n"); -+ continue; -+ } -+ -+ /* -+ * Check validity: if invalid write to output BIO so we know which -+ * response this refers to. -+ */ -+ if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) { -+ BIO_puts(out, "WARNING: Status times invalid.\n"); -+ ERR_print_errors(out); -+ } -+ BIO_printf(out, "%s\n", OCSP_cert_status_str(status)); -+ -+ BIO_puts(out, "\tThis Update: "); -+ ASN1_GENERALIZEDTIME_print(out, thisupd); -+ BIO_puts(out, "\n"); -+ -+ if (nextupd) { -+ BIO_puts(out, "\tNext Update: "); -+ ASN1_GENERALIZEDTIME_print(out, nextupd); -+ BIO_puts(out, "\n"); -+ } -+ -+ if (status != V_OCSP_CERTSTATUS_REVOKED) -+ continue; -+ -+ if (reason != -1) -+ BIO_printf(out, "\tReason: %s\n", OCSP_crl_reason_str(reason)); -+ -+ BIO_puts(out, "\tRevocation Time: "); -+ ASN1_GENERALIZEDTIME_print(out, rev); -+ BIO_puts(out, "\n"); -+ } -+} -+ -+static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, -+ CA_DB *db, X509 *ca, X509 *rcert, -+ EVP_PKEY *rkey, const EVP_MD *rmd, -+ STACK_OF(X509) *rother, unsigned long flags, -+ int nmin, int ndays, int badsig) -+{ -+ ASN1_TIME *thisupd = NULL, *nextupd = NULL; -+ OCSP_CERTID *cid, *ca_id = NULL; -+ OCSP_BASICRESP *bs = NULL; -+ int i, id_count; -+ -+ id_count = OCSP_request_onereq_count(req); -+ -+ if (id_count <= 0) { -+ *resp = -+ OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); -+ goto end; -+ } -+ -+ bs = OCSP_BASICRESP_new(); -+ thisupd = X509_gmtime_adj(NULL, 0); -+ if (ndays != -1) -+ nextupd = X509_time_adj_ex(NULL, ndays, nmin * 60, NULL); -+ -+ /* Examine each certificate id in the request */ -+ for (i = 0; i < id_count; i++) { -+ OCSP_ONEREQ *one; -+ ASN1_INTEGER *serial; -+ char **inf; -+ ASN1_OBJECT *cert_id_md_oid; -+ const EVP_MD *cert_id_md; -+ one = OCSP_request_onereq_get0(req, i); -+ cid = OCSP_onereq_get0_id(one); -+ -+ OCSP_id_get0_info(NULL, &cert_id_md_oid, NULL, NULL, cid); -+ -+ cert_id_md = EVP_get_digestbyobj(cert_id_md_oid); -+ if (!cert_id_md) { -+ *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, -+ NULL); -+ goto end; -+ } -+ OCSP_CERTID_free(ca_id); -+ ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca); -+ -+ /* Is this request about our CA? */ -+ if (OCSP_id_issuer_cmp(ca_id, cid)) { -+ OCSP_basic_add1_status(bs, cid, -+ V_OCSP_CERTSTATUS_UNKNOWN, -+ 0, NULL, thisupd, nextupd); -+ continue; -+ } -+ OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid); -+ inf = lookup_serial(db, serial); -+ if (!inf) -+ OCSP_basic_add1_status(bs, cid, -+ V_OCSP_CERTSTATUS_UNKNOWN, -+ 0, NULL, thisupd, nextupd); -+ else if (inf[DB_type][0] == DB_TYPE_VAL) -+ OCSP_basic_add1_status(bs, cid, -+ V_OCSP_CERTSTATUS_GOOD, -+ 0, NULL, thisupd, nextupd); -+ else if (inf[DB_type][0] == DB_TYPE_REV) { -+ ASN1_OBJECT *inst = NULL; -+ ASN1_TIME *revtm = NULL; -+ ASN1_GENERALIZEDTIME *invtm = NULL; -+ OCSP_SINGLERESP *single; -+ int reason = -1; -+ unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]); -+ single = OCSP_basic_add1_status(bs, cid, -+ V_OCSP_CERTSTATUS_REVOKED, -+ reason, revtm, thisupd, nextupd); -+ if (invtm) -+ OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date, -+ invtm, 0, 0); -+ else if (inst) -+ OCSP_SINGLERESP_add1_ext_i2d(single, -+ NID_hold_instruction_code, inst, -+ 0, 0); -+ ASN1_OBJECT_free(inst); -+ ASN1_TIME_free(revtm); -+ ASN1_GENERALIZEDTIME_free(invtm); -+ } -+ } -+ -+ OCSP_copy_nonce(bs, req); -+ -+ OCSP_basic_sign(bs, rcert, rkey, rmd, rother, flags); -+ -+ if (badsig) { -+ const ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs); -+ corrupt_signature(sig); -+ } -+ -+ *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs); -+ -+ end: -+ ASN1_TIME_free(thisupd); -+ ASN1_TIME_free(nextupd); -+ OCSP_CERTID_free(ca_id); -+ OCSP_BASICRESP_free(bs); -+} -+ -+static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser) -+{ -+ int i; -+ BIGNUM *bn = NULL; -+ char *itmp, *row[DB_NUMBER], **rrow; -+ for (i = 0; i < DB_NUMBER; i++) -+ row[i] = NULL; -+ bn = ASN1_INTEGER_to_BN(ser, NULL); -+ OPENSSL_assert(bn); /* FIXME: should report an error at this -+ * point and abort */ -+ if (BN_is_zero(bn)) -+ itmp = OPENSSL_strdup("00"); -+ else -+ itmp = BN_bn2hex(bn); -+ row[DB_serial] = itmp; -+ BN_free(bn); -+ rrow = TXT_DB_get_by_index(db->db, DB_serial, row); -+ OPENSSL_free(itmp); -+ return rrow; -+} -+ -+/* Quick and dirty OCSP server: read in and parse input request */ -+ -+static BIO *init_responder(const char *port) -+{ -+# ifdef OPENSSL_NO_SOCK -+ BIO_printf(bio_err, -+ "Error setting up accept BIO - sockets not supported.\n"); -+ return NULL; -+# else -+ BIO *acbio = NULL, *bufbio = NULL; -+ -+ bufbio = BIO_new(BIO_f_buffer()); -+ if (bufbio == NULL) -+ goto err; -+ acbio = BIO_new(BIO_s_accept()); -+ if (acbio == NULL -+ || BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR) < 0 -+ || BIO_set_accept_port(acbio, port) < 0) { -+ BIO_printf(bio_err, "Error setting up accept BIO\n"); -+ ERR_print_errors(bio_err); -+ goto err; -+ } -+ -+ BIO_set_accept_bios(acbio, bufbio); -+ bufbio = NULL; -+ if (BIO_do_accept(acbio) <= 0) { -+ BIO_printf(bio_err, "Error starting accept\n"); -+ ERR_print_errors(bio_err); -+ goto err; -+ } -+ -+ return acbio; -+ -+ err: -+ BIO_free_all(acbio); -+ BIO_free(bufbio); -+ return NULL; -+# endif -+} -+ -+# ifndef OPENSSL_NO_SOCK -+/* -+ * Decode %xx URL-decoding in-place. Ignores mal-formed sequences. -+ */ -+static int urldecode(char *p) -+{ -+ unsigned char *out = (unsigned char *)p; -+ unsigned char *save = out; -+ -+ for (; *p; p++) { -+ if (*p != '%') -+ *out++ = *p; -+ else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) { -+ /* Don't check, can't fail because of ixdigit() call. */ -+ *out++ = (OPENSSL_hexchar2int(p[1]) << 4) -+ | OPENSSL_hexchar2int(p[2]); -+ p += 2; -+ } -+ else -+ return -1; -+ } -+ *out = '\0'; -+ return (int)(out - save); -+} -+# endif -+ -+static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio) -+{ -+# ifdef OPENSSL_NO_SOCK -+ return 0; -+# else -+ int len; -+ OCSP_REQUEST *req = NULL; -+ char inbuf[2048], reqbuf[2048]; -+ char *p, *q; -+ BIO *cbio = NULL, *getbio = NULL, *b64 = NULL; -+ -+ if (BIO_do_accept(acbio) <= 0) { -+ BIO_printf(bio_err, "Error accepting connection\n"); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ -+ cbio = BIO_pop(acbio); -+ *pcbio = cbio; -+ -+ /* Read the request line. */ -+ len = BIO_gets(cbio, reqbuf, sizeof reqbuf); -+ if (len <= 0) -+ return 1; -+ if (strncmp(reqbuf, "GET ", 4) == 0) { -+ /* Expecting GET {sp} /URL {sp} HTTP/1.x */ -+ for (p = reqbuf + 4; *p == ' '; ++p) -+ continue; -+ if (*p != '/') { -+ BIO_printf(bio_err, "Invalid request -- bad URL\n"); -+ return 1; -+ } -+ p++; -+ -+ /* Splice off the HTTP version identifier. */ -+ for (q = p; *q; q++) -+ if (*q == ' ') -+ break; -+ if (strncmp(q, " HTTP/1.", 8) != 0) { -+ BIO_printf(bio_err, "Invalid request -- bad HTTP vesion\n"); -+ return 1; -+ } -+ *q = '\0'; -+ len = urldecode(p); -+ if (len <= 0) { -+ BIO_printf(bio_err, "Invalid request -- bad URL encoding\n"); -+ return 1; -+ } -+ if ((getbio = BIO_new_mem_buf(p, len)) == NULL -+ || (b64 = BIO_new(BIO_f_base64())) == NULL) { -+ BIO_printf(bio_err, "Could not allocate memory\n"); -+ ERR_print_errors(bio_err); -+ return 1; -+ } -+ BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); -+ getbio = BIO_push(b64, getbio); -+ } else if (strncmp(reqbuf, "POST ", 5) != 0) { -+ BIO_printf(bio_err, "Invalid request -- bad HTTP verb\n"); -+ return 1; -+ } -+ -+ /* Read and skip past the headers. */ -+ for (;;) { -+ len = BIO_gets(cbio, inbuf, sizeof inbuf); -+ if (len <= 0) -+ return 1; -+ if ((inbuf[0] == '\r') || (inbuf[0] == '\n')) -+ break; -+ } -+ -+ /* Try to read OCSP request */ -+ if (getbio) { -+ req = d2i_OCSP_REQUEST_bio(getbio, NULL); -+ BIO_free_all(getbio); -+ } else -+ req = d2i_OCSP_REQUEST_bio(cbio, NULL); -+ -+ if (!req) { -+ BIO_printf(bio_err, "Error parsing OCSP request\n"); -+ ERR_print_errors(bio_err); -+ } -+ -+ *preq = req; -+ -+ return 1; -+# endif -+} -+ -+static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) -+{ -+ char http_resp[] = -+ "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n" -+ "Content-Length: %d\r\n\r\n"; -+ if (!cbio) -+ return 0; -+ BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL)); -+ i2d_OCSP_RESPONSE_bio(cbio, resp); -+ (void)BIO_flush(cbio); -+ return 1; -+} -+ -+# ifndef OPENSSL_NO_SOCK -+static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, -+ const char *path, -+ const STACK_OF(CONF_VALUE) *headers, -+ OCSP_REQUEST *req, int req_timeout) -+{ -+ int fd; -+ int rv; -+ int i; -+ int add_host = 1; -+ OCSP_REQ_CTX *ctx = NULL; -+ OCSP_RESPONSE *rsp = NULL; -+ fd_set confds; -+ struct timeval tv; -+ -+ if (req_timeout != -1) -+ BIO_set_nbio(cbio, 1); -+ -+ rv = BIO_do_connect(cbio); -+ -+ if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) { -+ BIO_puts(bio_err, "Error connecting BIO\n"); -+ return NULL; -+ } -+ -+ if (BIO_get_fd(cbio, &fd) < 0) { -+ BIO_puts(bio_err, "Can't get connection fd\n"); -+ goto err; -+ } -+ -+ if (req_timeout != -1 && rv <= 0) { -+ FD_ZERO(&confds); -+ openssl_fdset(fd, &confds); -+ tv.tv_usec = 0; -+ tv.tv_sec = req_timeout; -+ rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); -+ if (rv == 0) { -+ BIO_puts(bio_err, "Timeout on connect\n"); -+ return NULL; -+ } -+ } -+ -+ ctx = OCSP_sendreq_new(cbio, path, NULL, -1); -+ if (ctx == NULL) -+ return NULL; -+ -+ for (i = 0; i < sk_CONF_VALUE_num(headers); i++) { -+ CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i); -+ if (add_host == 1 && strcasecmp("host", hdr->name) == 0) -+ add_host = 0; -+ if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value)) -+ goto err; -+ } -+ -+ if (add_host == 1 && OCSP_REQ_CTX_add1_header(ctx, "Host", host) == 0) -+ goto err; -+ -+ if (!OCSP_REQ_CTX_set1_req(ctx, req)) -+ goto err; -+ -+ for (;;) { -+ rv = OCSP_sendreq_nbio(&rsp, ctx); -+ if (rv != -1) -+ break; -+ if (req_timeout == -1) -+ continue; -+ FD_ZERO(&confds); -+ openssl_fdset(fd, &confds); -+ tv.tv_usec = 0; -+ tv.tv_sec = req_timeout; -+ if (BIO_should_read(cbio)) -+ rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv); -+ else if (BIO_should_write(cbio)) -+ rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); -+ else { -+ BIO_puts(bio_err, "Unexpected retry condition\n"); -+ goto err; -+ } -+ if (rv == 0) { -+ BIO_puts(bio_err, "Timeout on request\n"); -+ break; -+ } -+ if (rv == -1) { -+ BIO_puts(bio_err, "Select error\n"); -+ break; -+ } -+ -+ } -+ err: -+ OCSP_REQ_CTX_free(ctx); -+ -+ return rsp; -+} -+ -+OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, -+ const char *host, const char *path, -+ const char *port, int use_ssl, -+ STACK_OF(CONF_VALUE) *headers, -+ int req_timeout) -+{ -+ BIO *cbio = NULL; -+ SSL_CTX *ctx = NULL; -+ OCSP_RESPONSE *resp = NULL; -+ -+ cbio = BIO_new_connect(host); -+ if (!cbio) { -+ BIO_printf(bio_err, "Error creating connect BIO\n"); -+ goto end; -+ } -+ if (port) -+ BIO_set_conn_port(cbio, port); -+ if (use_ssl == 1) { -+ BIO *sbio; -+ ctx = SSL_CTX_new(TLS_client_method()); -+ if (ctx == NULL) { -+ BIO_printf(bio_err, "Error creating SSL context.\n"); -+ goto end; -+ } -+ SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); -+ sbio = BIO_new_ssl(ctx, 1); -+ cbio = BIO_push(sbio, cbio); -+ } -+ -+ resp = query_responder(cbio, host, path, headers, req, req_timeout); -+ if (!resp) -+ BIO_printf(bio_err, "Error querying OCSP responder\n"); -+ end: -+ BIO_free_all(cbio); -+ SSL_CTX_free(ctx); -+ return resp; -+} -+# endif -+ -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/openssl-vms.cnf b/CryptoPkg/Library/OpensslLib/openssl/apps/openssl-vms.cnf -new file mode 100644 -index 0000000..0092a65 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/openssl-vms.cnf -@@ -0,0 +1,346 @@ -+# -+# OpenSSL example configuration file. -+# This is mostly being used for generation of certificate requests. -+# -+ -+# This definition stops the following lines choking if HOME isn't -+# defined. -+HOME = . -+RANDFILE = $ENV::HOME/.rnd -+ -+# Extra OBJECT IDENTIFIER info: -+#oid_file = $ENV::HOME/.oid -+oid_section = new_oids -+ -+# To use this configuration file with the "-extfile" option of the -+# "openssl x509" utility, name here the section containing the -+# X.509v3 extensions to use: -+# extensions = -+# (Alternatively, use a configuration file that has only -+# X.509v3 extensions in its main [= default] section.) -+ -+[ new_oids ] -+ -+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. -+# Add a simple OID like this: -+# testoid1=1.2.3.4 -+# Or use config file substitution like this: -+# testoid2=${testoid1}.5.6 -+ -+# Policies used by the TSA examples. -+tsa_policy1 = 1.2.3.4.1 -+tsa_policy2 = 1.2.3.4.5.6 -+tsa_policy3 = 1.2.3.4.5.7 -+ -+#################################################################### -+[ ca ] -+default_ca = CA_default # The default ca section -+ -+#################################################################### -+[ CA_default ] -+ -+dir = sys\$disk:[.demoCA # Where everything is kept -+certs = $dir.certs] # Where the issued certs are kept -+crl_dir = $dir.crl] # Where the issued crl are kept -+database = $dir]index.txt # database index file. -+#unique_subject = no # Set to 'no' to allow creation of -+ # several certs with same subject. -+new_certs_dir = $dir.newcerts] # default place for new certs. -+ -+certificate = $dir]cacert.pem # The CA certificate -+serial = $dir]serial. # The current serial number -+crlnumber = $dir]crlnumber. # the current crl number -+ # must be commented out to leave a V1 CRL -+crl = $dir]crl.pem # The current CRL -+private_key = $dir.private]cakey.pem# The private key -+RANDFILE = $dir.private].rand # private random number file -+ -+x509_extensions = usr_cert # The extensions to add to the cert -+ -+# Comment out the following two lines for the "traditional" -+# (and highly broken) format. -+name_opt = ca_default # Subject Name options -+cert_opt = ca_default # Certificate field options -+ -+# Extension copying option: use with caution. -+# copy_extensions = copy -+ -+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -+# so this is commented out by default to leave a V1 CRL. -+# crlnumber must also be commented out to leave a V1 CRL. -+# crl_extensions = crl_ext -+ -+default_days = 365 # how long to certify for -+default_crl_days= 30 # how long before next CRL -+default_md = default # use public key default MD -+preserve = no # keep passed DN ordering -+ -+# A few difference way of specifying how similar the request should look -+# For type CA, the listed attributes must be the same, and the optional -+# and supplied fields are just that :-) -+policy = policy_match -+ -+# For the CA policy -+[ policy_match ] -+countryName = match -+stateOrProvinceName = match -+organizationName = match -+organizationalUnitName = optional -+commonName = supplied -+emailAddress = optional -+ -+# For the 'anything' policy -+# At this point in time, you must list all acceptable 'object' -+# types. -+[ policy_anything ] -+countryName = optional -+stateOrProvinceName = optional -+localityName = optional -+organizationName = optional -+organizationalUnitName = optional -+commonName = supplied -+emailAddress = optional -+ -+#################################################################### -+[ req ] -+default_bits = 2048 -+default_keyfile = privkey.pem -+distinguished_name = req_distinguished_name -+attributes = req_attributes -+x509_extensions = v3_ca # The extensions to add to the self signed cert -+ -+# Passwords for private keys if not present they will be prompted for -+# input_password = secret -+# output_password = secret -+ -+# This sets a mask for permitted string types. There are several options. -+# default: PrintableString, T61String, BMPString. -+# pkix : PrintableString, BMPString (PKIX recommendation before 2004) -+# utf8only: only UTF8Strings (PKIX recommendation after 2004). -+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -+# MASK:XXXX a literal mask value. -+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. -+string_mask = utf8only -+ -+# req_extensions = v3_req # The extensions to add to a certificate request -+ -+[ req_distinguished_name ] -+countryName = Country Name (2 letter code) -+countryName_default = AU -+countryName_min = 2 -+countryName_max = 2 -+ -+stateOrProvinceName = State or Province Name (full name) -+stateOrProvinceName_default = Some-State -+ -+localityName = Locality Name (eg, city) -+ -+0.organizationName = Organization Name (eg, company) -+0.organizationName_default = Internet Widgits Pty Ltd -+ -+# we can do this but it is not needed normally :-) -+#1.organizationName = Second Organization Name (eg, company) -+#1.organizationName_default = World Wide Web Pty Ltd -+ -+organizationalUnitName = Organizational Unit Name (eg, section) -+#organizationalUnitName_default = -+ -+commonName = Common Name (e.g. server FQDN or YOUR name) -+commonName_max = 64 -+ -+emailAddress = Email Address -+emailAddress_max = 64 -+ -+# SET-ex3 = SET extension number 3 -+ -+[ req_attributes ] -+challengePassword = A challenge password -+challengePassword_min = 4 -+challengePassword_max = 20 -+ -+unstructuredName = An optional company name -+ -+[ usr_cert ] -+ -+# These extensions are added when 'ca' signs a request. -+ -+# This goes against PKIX guidelines but some CAs do it and some software -+# requires this to avoid interpreting an end user certificate as a CA. -+ -+basicConstraints=CA:FALSE -+ -+# Here are some examples of the usage of nsCertType. If it is omitted -+# the certificate can be used for anything *except* object signing. -+ -+# This is OK for an SSL server. -+# nsCertType = server -+ -+# For an object signing certificate this would be used. -+# nsCertType = objsign -+ -+# For normal client use this is typical -+# nsCertType = client, email -+ -+# and for everything including object signing: -+# nsCertType = client, email, objsign -+ -+# This is typical in keyUsage for a client certificate. -+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment -+ -+# This will be displayed in Netscape's comment listbox. -+nsComment = "OpenSSL Generated Certificate" -+ -+# PKIX recommendations harmless if included in all certificates. -+subjectKeyIdentifier=hash -+authorityKeyIdentifier=keyid,issuer -+ -+# This stuff is for subjectAltName and issuerAltname. -+# Import the email address. -+# subjectAltName=email:copy -+# An alternative to produce certificates that aren't -+# deprecated according to PKIX. -+# subjectAltName=email:move -+ -+# Copy subject details -+# issuerAltName=issuer:copy -+ -+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -+#nsBaseUrl -+#nsRevocationUrl -+#nsRenewalUrl -+#nsCaPolicyUrl -+#nsSslServerName -+ -+# This is required for TSA certificates. -+# extendedKeyUsage = critical,timeStamping -+ -+[ v3_req ] -+ -+# Extensions to add to a certificate request -+ -+basicConstraints = CA:FALSE -+keyUsage = nonRepudiation, digitalSignature, keyEncipherment -+ -+[ v3_ca ] -+ -+ -+# Extensions for a typical CA -+ -+ -+# PKIX recommendation. -+ -+subjectKeyIdentifier=hash -+ -+authorityKeyIdentifier=keyid:always,issuer -+ -+basicConstraints = critical,CA:true -+ -+# Key usage: this is typical for a CA certificate. However since it will -+# prevent it being used as an test self-signed certificate it is best -+# left out by default. -+# keyUsage = cRLSign, keyCertSign -+ -+# Some might want this also -+# nsCertType = sslCA, emailCA -+ -+# Include email address in subject alt name: another PKIX recommendation -+# subjectAltName=email:copy -+# Copy issuer details -+# issuerAltName=issuer:copy -+ -+# DER hex encoding of an extension: beware experts only! -+# obj=DER:02:03 -+# Where 'obj' is a standard or added object -+# You can even override a supported extension: -+# basicConstraints= critical, DER:30:03:01:01:FF -+ -+[ crl_ext ] -+ -+# CRL extensions. -+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. -+ -+# issuerAltName=issuer:copy -+authorityKeyIdentifier=keyid:always -+ -+[ proxy_cert_ext ] -+# These extensions should be added when creating a proxy certificate -+ -+# This goes against PKIX guidelines but some CAs do it and some software -+# requires this to avoid interpreting an end user certificate as a CA. -+ -+basicConstraints=CA:FALSE -+ -+# Here are some examples of the usage of nsCertType. If it is omitted -+# the certificate can be used for anything *except* object signing. -+ -+# This is OK for an SSL server. -+# nsCertType = server -+ -+# For an object signing certificate this would be used. -+# nsCertType = objsign -+ -+# For normal client use this is typical -+# nsCertType = client, email -+ -+# and for everything including object signing: -+# nsCertType = client, email, objsign -+ -+# This is typical in keyUsage for a client certificate. -+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment -+ -+# This will be displayed in Netscape's comment listbox. -+nsComment = "OpenSSL Generated Certificate" -+ -+# PKIX recommendations harmless if included in all certificates. -+subjectKeyIdentifier=hash -+authorityKeyIdentifier=keyid,issuer -+ -+# This stuff is for subjectAltName and issuerAltname. -+# Import the email address. -+# subjectAltName=email:copy -+# An alternative to produce certificates that aren't -+# deprecated according to PKIX. -+# subjectAltName=email:move -+ -+# Copy subject details -+# issuerAltName=issuer:copy -+ -+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -+#nsBaseUrl -+#nsRevocationUrl -+#nsRenewalUrl -+#nsCaPolicyUrl -+#nsSslServerName -+ -+# This really needs to be in place for it to be a proxy certificate. -+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo -+ -+#################################################################### -+[ tsa ] -+ -+default_tsa = tsa_config1 # the default TSA section -+ -+[ tsa_config1 ] -+ -+# These are used by the TSA reply generation only. -+dir = sys\$disk:[.demoCA # TSA root directory -+serial = $dir]tsaserial. # The current serial number (mandatory) -+crypto_device = builtin # OpenSSL engine to use for signing -+signer_cert = $dir/tsacert.pem # The TSA signing certificate -+ # (optional) -+certs = $dir.cacert.pem] # Certificate chain to include in reply -+ # (optional) -+signer_key = $dir/private/tsakey.pem # The TSA private key (optional) -+signer_digest = sha256 # Signing digest to use. (Optional) -+default_policy = tsa_policy1 # Policy if request did not specify it -+ # (optional) -+other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) -+digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory) -+accuracy = secs:1, millisecs:500, microsecs:100 # (optional) -+clock_precision_digits = 0 # number of digits after dot. (optional) -+ordering = yes # Is ordering defined for timestamps? -+ # (optional, default: no) -+tsa_name = yes # Must the TSA name be included in the reply? -+ # (optional, default: no) -+ess_cert_id_chain = no # Must the ESS cert id chain be included? -+ # (optional, default: no) -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/openssl.c b/CryptoPkg/Library/OpensslLib/openssl/apps/openssl.c -new file mode 100644 -index 0000000..e69e7d9 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/openssl.c -@@ -0,0 +1,695 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef OPENSSL_NO_ENGINE -+# include -+#endif -+#include -+#ifdef OPENSSL_FIPS -+# include -+#endif -+#define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */ -+#include "s_apps.h" -+/* Needed to get the other O_xxx flags. */ -+#ifdef OPENSSL_SYS_VMS -+# include -+#endif -+#define INCLUDE_FUNCTION_TABLE -+#include "apps.h" -+ -+ -+#ifdef OPENSSL_NO_CAMELLIA -+# define FORMAT "%-15s" -+# define COLUMNS 5 -+#else -+# define FORMAT "%-18s" -+# define COLUMNS 4 -+#endif -+ -+/* Special sentinel to exit the program. */ -+#define EXIT_THE_PROGRAM (-1) -+ -+/* -+ * The LHASH callbacks ("hash" & "cmp") have been replaced by functions with -+ * the base prototypes (we cast each variable inside the function to the -+ * required type of "FUNCTION*"). This removes the necessity for -+ * macro-generated wrapper functions. -+ */ -+static LHASH_OF(FUNCTION) *prog_init(void); -+static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]); -+static void list_pkey(void); -+static void list_type(FUNC_TYPE ft); -+static void list_disabled(void); -+char *default_config_file = NULL; -+ -+BIO *bio_in = NULL; -+BIO *bio_out = NULL; -+BIO *bio_err = NULL; -+ -+static int apps_startup() -+{ -+#ifdef SIGPIPE -+ signal(SIGPIPE, SIG_IGN); -+#endif -+ -+ /* Set non-default library initialisation settings */ -+ if (!OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN -+ | OPENSSL_INIT_LOAD_CONFIG, NULL)) -+ return 0; -+ -+#ifndef OPENSSL_NO_UI -+ setup_ui_method(); -+#endif -+ -+ return 1; -+} -+ -+static void apps_shutdown() -+{ -+#ifndef OPENSSL_NO_UI -+ destroy_ui_method(); -+#endif -+} -+ -+static char *make_config_name() -+{ -+ const char *t; -+ size_t len; -+ char *p; -+ -+ if ((t = getenv("OPENSSL_CONF")) != NULL) -+ return OPENSSL_strdup(t); -+ -+ t = X509_get_default_cert_area(); -+ len = strlen(t) + 1 + strlen(OPENSSL_CONF) + 1; -+ p = app_malloc(len, "config filename buffer"); -+ strcpy(p, t); -+#ifndef OPENSSL_SYS_VMS -+ strcat(p, "/"); -+#endif -+ strcat(p, OPENSSL_CONF); -+ -+ return p; -+} -+ -+int main(int argc, char *argv[]) -+{ -+ FUNCTION f, *fp; -+ LHASH_OF(FUNCTION) *prog = NULL; -+ char **copied_argv = NULL; -+ char *p, *pname; -+ char buf[1024]; -+ const char *prompt; -+ ARGS arg; -+ int first, n, i, ret = 0; -+ -+ arg.argv = NULL; -+ arg.size = 0; -+ -+ /* Set up some of the environment. */ -+ default_config_file = make_config_name(); -+ bio_in = dup_bio_in(FORMAT_TEXT); -+ bio_out = dup_bio_out(FORMAT_TEXT); -+ bio_err = dup_bio_err(FORMAT_TEXT); -+ -+#if defined(OPENSSL_SYS_VMS) && defined(__DECC) -+ copied_argv = argv = copy_argv(&argc, argv); -+#elif defined(_WIN32) -+ /* -+ * Replace argv[] with UTF-8 encoded strings. -+ */ -+ win32_utf8argv(&argc, &argv); -+#endif -+ -+ p = getenv("OPENSSL_DEBUG_MEMORY"); -+ if (p != NULL && strcmp(p, "on") == 0) -+ CRYPTO_set_mem_debug(1); -+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); -+ -+ if (getenv("OPENSSL_FIPS")) { -+#ifdef OPENSSL_FIPS -+ if (!FIPS_mode_set(1)) { -+ ERR_print_errors(bio_err); -+ return 1; -+ } -+#else -+ BIO_printf(bio_err, "FIPS mode not supported.\n"); -+ return 1; -+#endif -+ } -+ -+ if (!apps_startup()) -+ goto end; -+ -+ prog = prog_init(); -+ pname = opt_progname(argv[0]); -+ -+ /* first check the program name */ -+ f.name = pname; -+ fp = lh_FUNCTION_retrieve(prog, &f); -+ if (fp != NULL) { -+ argv[0] = pname; -+ ret = fp->func(argc, argv); -+ goto end; -+ } -+ -+ /* If there is stuff on the command line, run with that. */ -+ if (argc != 1) { -+ argc--; -+ argv++; -+ ret = do_cmd(prog, argc, argv); -+ if (ret < 0) -+ ret = 0; -+ goto end; -+ } -+ -+ /* ok, lets enter interactive mode */ -+ for (;;) { -+ ret = 0; -+ /* Read a line, continue reading if line ends with \ */ -+ for (p = buf, n = sizeof buf, i = 0, first = 1; n > 0; first = 0) { -+ prompt = first ? "OpenSSL> " : "> "; -+ p[0] = '\0'; -+#ifndef READLINE -+ fputs(prompt, stdout); -+ fflush(stdout); -+ if (!fgets(p, n, stdin)) -+ goto end; -+ if (p[0] == '\0') -+ goto end; -+ i = strlen(p); -+ if (i <= 1) -+ break; -+ if (p[i - 2] != '\\') -+ break; -+ i -= 2; -+ p += i; -+ n -= i; -+#else -+ { -+ extern char *readline(const char *); -+ extern void add_history(const char *cp); -+ char *text; -+ -+ text = readline(prompt); -+ if (text == NULL) -+ goto end; -+ i = strlen(text); -+ if (i == 0 || i > n) -+ break; -+ if (text[i - 1] != '\\') { -+ p += strlen(strcpy(p, text)); -+ free(text); -+ add_history(buf); -+ break; -+ } -+ -+ text[i - 1] = '\0'; -+ p += strlen(strcpy(p, text)); -+ free(text); -+ n -= i; -+ } -+#endif -+ } -+ -+ if (!chopup_args(&arg, buf)) { -+ BIO_printf(bio_err, "Can't parse (no memory?)\n"); -+ break; -+ } -+ -+ ret = do_cmd(prog, arg.argc, arg.argv); -+ if (ret == EXIT_THE_PROGRAM) { -+ ret = 0; -+ goto end; -+ } -+ if (ret != 0) -+ BIO_printf(bio_err, "error in %s\n", arg.argv[0]); -+ (void)BIO_flush(bio_out); -+ (void)BIO_flush(bio_err); -+ } -+ ret = 1; -+ end: -+ OPENSSL_free(copied_argv); -+ OPENSSL_free(default_config_file); -+ lh_FUNCTION_free(prog); -+ OPENSSL_free(arg.argv); -+ -+ BIO_free(bio_in); -+ BIO_free_all(bio_out); -+ apps_shutdown(); -+#ifndef OPENSSL_NO_CRYPTO_MDEBUG -+ if (CRYPTO_mem_leaks(bio_err) <= 0) -+ ret = 1; -+#endif -+ BIO_free(bio_err); -+ EXIT(ret); -+} -+ -+OPTIONS exit_options[] = { -+ {NULL} -+}; -+ -+static void list_cipher_fn(const EVP_CIPHER *c, -+ const char *from, const char *to, void *arg) -+{ -+ if (c) -+ BIO_printf(arg, "%s\n", EVP_CIPHER_name(c)); -+ else { -+ if (!from) -+ from = ""; -+ if (!to) -+ to = ""; -+ BIO_printf(arg, "%s => %s\n", from, to); -+ } -+} -+ -+static void list_md_fn(const EVP_MD *m, -+ const char *from, const char *to, void *arg) -+{ -+ if (m) -+ BIO_printf(arg, "%s\n", EVP_MD_name(m)); -+ else { -+ if (!from) -+ from = ""; -+ if (!to) -+ to = ""; -+ BIO_printf((BIO *)arg, "%s => %s\n", from, to); -+ } -+} -+ -+/* Unified enum for help and list commands. */ -+typedef enum HELPLIST_CHOICE { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_COMMANDS, OPT_DIGEST_COMMANDS, -+ OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS, -+ OPT_PK_ALGORITHMS, OPT_DISABLED -+} HELPLIST_CHOICE; -+ -+OPTIONS list_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"commands", OPT_COMMANDS, '-', "List of standard commands"}, -+ {"digest-commands", OPT_DIGEST_COMMANDS, '-', -+ "List of message digest commands"}, -+ {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-', -+ "List of message digest algorithms"}, -+ {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"}, -+ {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-', -+ "List of cipher algorithms"}, -+ {"public-key-algorithms", OPT_PK_ALGORITHMS, '-', -+ "List of public key algorithms"}, -+ {"disabled", OPT_DISABLED, '-', -+ "List of disabled features"}, -+ {NULL} -+}; -+ -+int list_main(int argc, char **argv) -+{ -+ char *prog; -+ HELPLIST_CHOICE o; -+ int done = 0; -+ -+ prog = opt_init(argc, argv, list_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: /* Never hit, but suppresses warning */ -+ case OPT_ERR: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ return 1; -+ case OPT_HELP: -+ opt_help(list_options); -+ break; -+ case OPT_COMMANDS: -+ list_type(FT_general); -+ break; -+ case OPT_DIGEST_COMMANDS: -+ list_type(FT_md); -+ break; -+ case OPT_DIGEST_ALGORITHMS: -+ EVP_MD_do_all_sorted(list_md_fn, bio_out); -+ break; -+ case OPT_CIPHER_COMMANDS: -+ list_type(FT_cipher); -+ break; -+ case OPT_CIPHER_ALGORITHMS: -+ EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out); -+ break; -+ case OPT_PK_ALGORITHMS: -+ list_pkey(); -+ break; -+ case OPT_DISABLED: -+ list_disabled(); -+ break; -+ } -+ done = 1; -+ } -+ -+ if (!done) { -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+OPTIONS help_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {NULL} -+}; -+ -+int help_main(int argc, char **argv) -+{ -+ FUNCTION *fp; -+ int i, nl; -+ FUNC_TYPE tp; -+ char *prog; -+ HELPLIST_CHOICE o; -+ -+ prog = opt_init(argc, argv, help_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ default: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ return 1; -+ case OPT_HELP: -+ opt_help(help_options); -+ return 0; -+ } -+ } -+ -+ if (opt_num_rest() != 0) { -+ BIO_printf(bio_err, "Usage: %s\n", prog); -+ return 1; -+ } -+ -+ BIO_printf(bio_err, "\nStandard commands"); -+ i = 0; -+ tp = FT_none; -+ for (fp = functions; fp->name != NULL; fp++) { -+ nl = 0; -+ if (((i++) % COLUMNS) == 0) { -+ BIO_printf(bio_err, "\n"); -+ nl = 1; -+ } -+ if (fp->type != tp) { -+ tp = fp->type; -+ if (!nl) -+ BIO_printf(bio_err, "\n"); -+ if (tp == FT_md) { -+ i = 1; -+ BIO_printf(bio_err, -+ "\nMessage Digest commands (see the `dgst' command for more details)\n"); -+ } else if (tp == FT_cipher) { -+ i = 1; -+ BIO_printf(bio_err, -+ "\nCipher commands (see the `enc' command for more details)\n"); -+ } -+ } -+ BIO_printf(bio_err, FORMAT, fp->name); -+ } -+ BIO_printf(bio_err, "\n\n"); -+ return 0; -+} -+ -+int exit_main(int argc, char **argv) -+{ -+ return EXIT_THE_PROGRAM; -+} -+ -+static void list_type(FUNC_TYPE ft) -+{ -+ FUNCTION *fp; -+ int i = 0; -+ -+ for (fp = functions; fp->name != NULL; fp++) -+ if (fp->type == ft) { -+ if ((i++ % COLUMNS) == 0) -+ BIO_printf(bio_out, "\n"); -+ BIO_printf(bio_out, FORMAT, fp->name); -+ } -+ BIO_printf(bio_out, "\n"); -+} -+ -+static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) -+{ -+ FUNCTION f, *fp; -+ -+ if (argc <= 0 || argv[0] == NULL) -+ return (0); -+ f.name = argv[0]; -+ fp = lh_FUNCTION_retrieve(prog, &f); -+ if (fp == NULL) { -+ if (EVP_get_digestbyname(argv[0])) { -+ f.type = FT_md; -+ f.func = dgst_main; -+ fp = &f; -+ } else if (EVP_get_cipherbyname(argv[0])) { -+ f.type = FT_cipher; -+ f.func = enc_main; -+ fp = &f; -+ } -+ } -+ if (fp != NULL) { -+ return (fp->func(argc, argv)); -+ } -+ if ((strncmp(argv[0], "no-", 3)) == 0) { -+ /* -+ * User is asking if foo is unsupported, by trying to "run" the -+ * no-foo command. Strange. -+ */ -+ f.name = argv[0] + 3; -+ if (lh_FUNCTION_retrieve(prog, &f) == NULL) { -+ BIO_printf(bio_out, "%s\n", argv[0]); -+ return (0); -+ } -+ BIO_printf(bio_out, "%s\n", argv[0] + 3); -+ return 1; -+ } -+ if (strcmp(argv[0], "quit") == 0 || strcmp(argv[0], "q") == 0 || -+ strcmp(argv[0], "exit") == 0 || strcmp(argv[0], "bye") == 0) -+ /* Special value to mean "exit the program. */ -+ return EXIT_THE_PROGRAM; -+ -+ BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", -+ argv[0]); -+ return (1); -+} -+ -+static void list_pkey(void) -+{ -+ int i; -+ -+ for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { -+ const EVP_PKEY_ASN1_METHOD *ameth; -+ int pkey_id, pkey_base_id, pkey_flags; -+ const char *pinfo, *pem_str; -+ ameth = EVP_PKEY_asn1_get0(i); -+ EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags, -+ &pinfo, &pem_str, ameth); -+ if (pkey_flags & ASN1_PKEY_ALIAS) { -+ BIO_printf(bio_out, "Name: %s\n", OBJ_nid2ln(pkey_id)); -+ BIO_printf(bio_out, "\tAlias for: %s\n", -+ OBJ_nid2ln(pkey_base_id)); -+ } else { -+ BIO_printf(bio_out, "Name: %s\n", pinfo); -+ BIO_printf(bio_out, "\tType: %s Algorithm\n", -+ pkey_flags & ASN1_PKEY_DYNAMIC ? -+ "External" : "Builtin"); -+ BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); -+ if (pem_str == NULL) -+ pem_str = "(none)"; -+ BIO_printf(bio_out, "\tPEM string: %s\n", pem_str); -+ } -+ -+ } -+} -+ -+static int function_cmp(const FUNCTION * a, const FUNCTION * b) -+{ -+ return strncmp(a->name, b->name, 8); -+} -+ -+static unsigned long function_hash(const FUNCTION * a) -+{ -+ return OPENSSL_LH_strhash(a->name); -+} -+ -+static int SortFnByName(const void *_f1, const void *_f2) -+{ -+ const FUNCTION *f1 = _f1; -+ const FUNCTION *f2 = _f2; -+ -+ if (f1->type != f2->type) -+ return f1->type - f2->type; -+ return strcmp(f1->name, f2->name); -+} -+ -+static void list_disabled(void) -+{ -+ BIO_puts(bio_out, "Disabled algorithms:\n"); -+#ifdef OPENSSL_NO_BF -+ BIO_puts(bio_out, "BF\n"); -+#endif -+#ifdef OPENSSL_NO_BLAKE2 -+ BIO_puts(bio_out, "BLAKE2\n"); -+#endif -+#ifdef OPENSSL_NO_CAMELLIA -+ BIO_puts(bio_out, "CAMELLIA\n"); -+#endif -+#ifdef OPENSSL_NO_CAST -+ BIO_puts(bio_out, "CAST\n"); -+#endif -+#ifdef OPENSSL_NO_CMAC -+ BIO_puts(bio_out, "CMAC\n"); -+#endif -+#ifdef OPENSSL_NO_CMS -+ BIO_puts(bio_out, "CMS\n"); -+#endif -+#ifdef OPENSSL_NO_COMP -+ BIO_puts(bio_out, "COMP\n"); -+#endif -+#ifdef OPENSSL_NO_DES -+ BIO_puts(bio_out, "DES\n"); -+#endif -+#ifdef OPENSSL_NO_DGRAM -+ BIO_puts(bio_out, "DGRAM\n"); -+#endif -+#ifdef OPENSSL_NO_DH -+ BIO_puts(bio_out, "DH\n"); -+#endif -+#ifdef OPENSSL_NO_DSA -+ BIO_puts(bio_out, "DSA\n"); -+#endif -+#if defined(OPENSSL_NO_DTLS) -+ BIO_puts(bio_out, "DTLS\n"); -+#endif -+#if defined(OPENSSL_NO_DTLS1) -+ BIO_puts(bio_out, "DTLS1\n"); -+#endif -+#if defined(OPENSSL_NO_DTLS1_2) -+ BIO_puts(bio_out, "DTLS1_2\n"); -+#endif -+#ifdef OPENSSL_NO_EC -+ BIO_puts(bio_out, "EC\n"); -+#endif -+#ifdef OPENSSL_NO_EC2M -+ BIO_puts(bio_out, "EC2M\n"); -+#endif -+#ifdef OPENSSL_NO_ENGINE -+ BIO_puts(bio_out, "ENGINE\n"); -+#endif -+#ifdef OPENSSL_NO_GOST -+ BIO_puts(bio_out, "GOST\n"); -+#endif -+#ifdef OPENSSL_NO_HEARTBEATS -+ BIO_puts(bio_out, "HEARTBEATS\n"); -+#endif -+#ifdef OPENSSL_NO_IDEA -+ BIO_puts(bio_out, "IDEA\n"); -+#endif -+#ifdef OPENSSL_NO_MD2 -+ BIO_puts(bio_out, "MD2\n"); -+#endif -+#ifdef OPENSSL_NO_MD4 -+ BIO_puts(bio_out, "MD4\n"); -+#endif -+#ifdef OPENSSL_NO_MD5 -+ BIO_puts(bio_out, "MD5\n"); -+#endif -+#ifdef OPENSSL_NO_MDC2 -+ BIO_puts(bio_out, "MDC2\n"); -+#endif -+#ifdef OPENSSL_NO_OCB -+ BIO_puts(bio_out, "OCB\n"); -+#endif -+#ifdef OPENSSL_NO_OCSP -+ BIO_puts(bio_out, "OCSP\n"); -+#endif -+#ifdef OPENSSL_NO_PSK -+ BIO_puts(bio_out, "PSK\n"); -+#endif -+#ifdef OPENSSL_NO_RC2 -+ BIO_puts(bio_out, "RC2\n"); -+#endif -+#ifdef OPENSSL_NO_RC4 -+ BIO_puts(bio_out, "RC4\n"); -+#endif -+#ifdef OPENSSL_NO_RC5 -+ BIO_puts(bio_out, "RC5\n"); -+#endif -+#ifdef OPENSSL_NO_RMD160 -+ BIO_puts(bio_out, "RMD160\n"); -+#endif -+#ifdef OPENSSL_NO_RSA -+ BIO_puts(bio_out, "RSA\n"); -+#endif -+#ifdef OPENSSL_NO_SCRYPT -+ BIO_puts(bio_out, "SCRYPT\n"); -+#endif -+#ifdef OPENSSL_NO_SCTP -+ BIO_puts(bio_out, "SCTP\n"); -+#endif -+#ifdef OPENSSL_NO_SEED -+ BIO_puts(bio_out, "SEED\n"); -+#endif -+#ifdef OPENSSL_NO_SOCK -+ BIO_puts(bio_out, "SOCK\n"); -+#endif -+#ifdef OPENSSL_NO_SRP -+ BIO_puts(bio_out, "SRP\n"); -+#endif -+#ifdef OPENSSL_NO_SRTP -+ BIO_puts(bio_out, "SRTP\n"); -+#endif -+#ifdef OPENSSL_NO_SSL3 -+ BIO_puts(bio_out, "SSL3\n"); -+#endif -+#ifdef OPENSSL_NO_TLS1 -+ BIO_puts(bio_out, "TLS1\n"); -+#endif -+#ifdef OPENSSL_NO_TLS1_1 -+ BIO_puts(bio_out, "TLS1_1\n"); -+#endif -+#ifdef OPENSSL_NO_TLS1_2 -+ BIO_puts(bio_out, "TLS1_2\n"); -+#endif -+#ifdef OPENSSL_NO_WHIRLPOOL -+ BIO_puts(bio_out, "WHIRLPOOL\n"); -+#endif -+#ifndef ZLIB -+ BIO_puts(bio_out, "ZLIB\n"); -+#endif -+} -+ -+static LHASH_OF(FUNCTION) *prog_init(void) -+{ -+ LHASH_OF(FUNCTION) *ret; -+ FUNCTION *f; -+ size_t i; -+ -+ /* Sort alphabetically within category. For nicer help displays. */ -+ for (i = 0, f = functions; f->name != NULL; ++f, ++i) ; -+ qsort(functions, i, sizeof(*functions), SortFnByName); -+ -+ if ((ret = lh_FUNCTION_new(function_hash, function_cmp)) == NULL) -+ return (NULL); -+ -+ for (f = functions; f->name != NULL; f++) -+ (void)lh_FUNCTION_insert(ret, f); -+ return (ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/openssl.cnf b/CryptoPkg/Library/OpensslLib/openssl/apps/openssl.cnf -new file mode 100644 -index 0000000..b3e7444 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/openssl.cnf -@@ -0,0 +1,346 @@ -+# -+# OpenSSL example configuration file. -+# This is mostly being used for generation of certificate requests. -+# -+ -+# This definition stops the following lines choking if HOME isn't -+# defined. -+HOME = . -+RANDFILE = $ENV::HOME/.rnd -+ -+# Extra OBJECT IDENTIFIER info: -+#oid_file = $ENV::HOME/.oid -+oid_section = new_oids -+ -+# To use this configuration file with the "-extfile" option of the -+# "openssl x509" utility, name here the section containing the -+# X.509v3 extensions to use: -+# extensions = -+# (Alternatively, use a configuration file that has only -+# X.509v3 extensions in its main [= default] section.) -+ -+[ new_oids ] -+ -+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. -+# Add a simple OID like this: -+# testoid1=1.2.3.4 -+# Or use config file substitution like this: -+# testoid2=${testoid1}.5.6 -+ -+# Policies used by the TSA examples. -+tsa_policy1 = 1.2.3.4.1 -+tsa_policy2 = 1.2.3.4.5.6 -+tsa_policy3 = 1.2.3.4.5.7 -+ -+#################################################################### -+[ ca ] -+default_ca = CA_default # The default ca section -+ -+#################################################################### -+[ CA_default ] -+ -+dir = ./demoCA # Where everything is kept -+certs = $dir/certs # Where the issued certs are kept -+crl_dir = $dir/crl # Where the issued crl are kept -+database = $dir/index.txt # database index file. -+#unique_subject = no # Set to 'no' to allow creation of -+ # several certs with same subject. -+new_certs_dir = $dir/newcerts # default place for new certs. -+ -+certificate = $dir/cacert.pem # The CA certificate -+serial = $dir/serial # The current serial number -+crlnumber = $dir/crlnumber # the current crl number -+ # must be commented out to leave a V1 CRL -+crl = $dir/crl.pem # The current CRL -+private_key = $dir/private/cakey.pem# The private key -+RANDFILE = $dir/private/.rand # private random number file -+ -+x509_extensions = usr_cert # The extensions to add to the cert -+ -+# Comment out the following two lines for the "traditional" -+# (and highly broken) format. -+name_opt = ca_default # Subject Name options -+cert_opt = ca_default # Certificate field options -+ -+# Extension copying option: use with caution. -+# copy_extensions = copy -+ -+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -+# so this is commented out by default to leave a V1 CRL. -+# crlnumber must also be commented out to leave a V1 CRL. -+# crl_extensions = crl_ext -+ -+default_days = 365 # how long to certify for -+default_crl_days= 30 # how long before next CRL -+default_md = default # use public key default MD -+preserve = no # keep passed DN ordering -+ -+# A few difference way of specifying how similar the request should look -+# For type CA, the listed attributes must be the same, and the optional -+# and supplied fields are just that :-) -+policy = policy_match -+ -+# For the CA policy -+[ policy_match ] -+countryName = match -+stateOrProvinceName = match -+organizationName = match -+organizationalUnitName = optional -+commonName = supplied -+emailAddress = optional -+ -+# For the 'anything' policy -+# At this point in time, you must list all acceptable 'object' -+# types. -+[ policy_anything ] -+countryName = optional -+stateOrProvinceName = optional -+localityName = optional -+organizationName = optional -+organizationalUnitName = optional -+commonName = supplied -+emailAddress = optional -+ -+#################################################################### -+[ req ] -+default_bits = 2048 -+default_keyfile = privkey.pem -+distinguished_name = req_distinguished_name -+attributes = req_attributes -+x509_extensions = v3_ca # The extensions to add to the self signed cert -+ -+# Passwords for private keys if not present they will be prompted for -+# input_password = secret -+# output_password = secret -+ -+# This sets a mask for permitted string types. There are several options. -+# default: PrintableString, T61String, BMPString. -+# pkix : PrintableString, BMPString (PKIX recommendation before 2004) -+# utf8only: only UTF8Strings (PKIX recommendation after 2004). -+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -+# MASK:XXXX a literal mask value. -+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. -+string_mask = utf8only -+ -+# req_extensions = v3_req # The extensions to add to a certificate request -+ -+[ req_distinguished_name ] -+countryName = Country Name (2 letter code) -+countryName_default = AU -+countryName_min = 2 -+countryName_max = 2 -+ -+stateOrProvinceName = State or Province Name (full name) -+stateOrProvinceName_default = Some-State -+ -+localityName = Locality Name (eg, city) -+ -+0.organizationName = Organization Name (eg, company) -+0.organizationName_default = Internet Widgits Pty Ltd -+ -+# we can do this but it is not needed normally :-) -+#1.organizationName = Second Organization Name (eg, company) -+#1.organizationName_default = World Wide Web Pty Ltd -+ -+organizationalUnitName = Organizational Unit Name (eg, section) -+#organizationalUnitName_default = -+ -+commonName = Common Name (e.g. server FQDN or YOUR name) -+commonName_max = 64 -+ -+emailAddress = Email Address -+emailAddress_max = 64 -+ -+# SET-ex3 = SET extension number 3 -+ -+[ req_attributes ] -+challengePassword = A challenge password -+challengePassword_min = 4 -+challengePassword_max = 20 -+ -+unstructuredName = An optional company name -+ -+[ usr_cert ] -+ -+# These extensions are added when 'ca' signs a request. -+ -+# This goes against PKIX guidelines but some CAs do it and some software -+# requires this to avoid interpreting an end user certificate as a CA. -+ -+basicConstraints=CA:FALSE -+ -+# Here are some examples of the usage of nsCertType. If it is omitted -+# the certificate can be used for anything *except* object signing. -+ -+# This is OK for an SSL server. -+# nsCertType = server -+ -+# For an object signing certificate this would be used. -+# nsCertType = objsign -+ -+# For normal client use this is typical -+# nsCertType = client, email -+ -+# and for everything including object signing: -+# nsCertType = client, email, objsign -+ -+# This is typical in keyUsage for a client certificate. -+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment -+ -+# This will be displayed in Netscape's comment listbox. -+nsComment = "OpenSSL Generated Certificate" -+ -+# PKIX recommendations harmless if included in all certificates. -+subjectKeyIdentifier=hash -+authorityKeyIdentifier=keyid,issuer -+ -+# This stuff is for subjectAltName and issuerAltname. -+# Import the email address. -+# subjectAltName=email:copy -+# An alternative to produce certificates that aren't -+# deprecated according to PKIX. -+# subjectAltName=email:move -+ -+# Copy subject details -+# issuerAltName=issuer:copy -+ -+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -+#nsBaseUrl -+#nsRevocationUrl -+#nsRenewalUrl -+#nsCaPolicyUrl -+#nsSslServerName -+ -+# This is required for TSA certificates. -+# extendedKeyUsage = critical,timeStamping -+ -+[ v3_req ] -+ -+# Extensions to add to a certificate request -+ -+basicConstraints = CA:FALSE -+keyUsage = nonRepudiation, digitalSignature, keyEncipherment -+ -+[ v3_ca ] -+ -+ -+# Extensions for a typical CA -+ -+ -+# PKIX recommendation. -+ -+subjectKeyIdentifier=hash -+ -+authorityKeyIdentifier=keyid:always,issuer -+ -+basicConstraints = critical,CA:true -+ -+# Key usage: this is typical for a CA certificate. However since it will -+# prevent it being used as an test self-signed certificate it is best -+# left out by default. -+# keyUsage = cRLSign, keyCertSign -+ -+# Some might want this also -+# nsCertType = sslCA, emailCA -+ -+# Include email address in subject alt name: another PKIX recommendation -+# subjectAltName=email:copy -+# Copy issuer details -+# issuerAltName=issuer:copy -+ -+# DER hex encoding of an extension: beware experts only! -+# obj=DER:02:03 -+# Where 'obj' is a standard or added object -+# You can even override a supported extension: -+# basicConstraints= critical, DER:30:03:01:01:FF -+ -+[ crl_ext ] -+ -+# CRL extensions. -+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. -+ -+# issuerAltName=issuer:copy -+authorityKeyIdentifier=keyid:always -+ -+[ proxy_cert_ext ] -+# These extensions should be added when creating a proxy certificate -+ -+# This goes against PKIX guidelines but some CAs do it and some software -+# requires this to avoid interpreting an end user certificate as a CA. -+ -+basicConstraints=CA:FALSE -+ -+# Here are some examples of the usage of nsCertType. If it is omitted -+# the certificate can be used for anything *except* object signing. -+ -+# This is OK for an SSL server. -+# nsCertType = server -+ -+# For an object signing certificate this would be used. -+# nsCertType = objsign -+ -+# For normal client use this is typical -+# nsCertType = client, email -+ -+# and for everything including object signing: -+# nsCertType = client, email, objsign -+ -+# This is typical in keyUsage for a client certificate. -+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment -+ -+# This will be displayed in Netscape's comment listbox. -+nsComment = "OpenSSL Generated Certificate" -+ -+# PKIX recommendations harmless if included in all certificates. -+subjectKeyIdentifier=hash -+authorityKeyIdentifier=keyid,issuer -+ -+# This stuff is for subjectAltName and issuerAltname. -+# Import the email address. -+# subjectAltName=email:copy -+# An alternative to produce certificates that aren't -+# deprecated according to PKIX. -+# subjectAltName=email:move -+ -+# Copy subject details -+# issuerAltName=issuer:copy -+ -+#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -+#nsBaseUrl -+#nsRevocationUrl -+#nsRenewalUrl -+#nsCaPolicyUrl -+#nsSslServerName -+ -+# This really needs to be in place for it to be a proxy certificate. -+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo -+ -+#################################################################### -+[ tsa ] -+ -+default_tsa = tsa_config1 # the default TSA section -+ -+[ tsa_config1 ] -+ -+# These are used by the TSA reply generation only. -+dir = ./demoCA # TSA root directory -+serial = $dir/tsaserial # The current serial number (mandatory) -+crypto_device = builtin # OpenSSL engine to use for signing -+signer_cert = $dir/tsacert.pem # The TSA signing certificate -+ # (optional) -+certs = $dir/cacert.pem # Certificate chain to include in reply -+ # (optional) -+signer_key = $dir/private/tsakey.pem # The TSA private key (optional) -+signer_digest = sha256 # Signing digest to use. (Optional) -+default_policy = tsa_policy1 # Policy if request did not specify it -+ # (optional) -+other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) -+digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory) -+accuracy = secs:1, millisecs:500, microsecs:100 # (optional) -+clock_precision_digits = 0 # number of digits after dot. (optional) -+ordering = yes # Is ordering defined for timestamps? -+ # (optional, default: no) -+tsa_name = yes # Must the TSA name be included in the reply? -+ # (optional, default: no) -+ess_cert_id_chain = no # Must the ESS cert id chain be included? -+ # (optional, default: no) -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/opt.c b/CryptoPkg/Library/OpensslLib/openssl/apps/opt.c -new file mode 100644 -index 0000000..f72ac64 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/opt.c -@@ -0,0 +1,977 @@ -+/* -+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* #define COMPILE_STANDALONE_TEST_DRIVER */ -+#include "apps.h" -+#include -+#if !defined(OPENSSL_SYS_MSDOS) -+# include OPENSSL_UNISTD -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_OPT_HELP_WIDTH 30 -+const char OPT_HELP_STR[] = "--"; -+const char OPT_MORE_STR[] = "---"; -+ -+/* Our state */ -+static char **argv; -+static int argc; -+static int opt_index; -+static char *arg; -+static char *flag; -+static char *dunno; -+static const OPTIONS *unknown; -+static const OPTIONS *opts; -+static char prog[40]; -+ -+/* -+ * Return the simple name of the program; removing various platform gunk. -+ */ -+#if defined(OPENSSL_SYS_WIN32) -+char *opt_progname(const char *argv0) -+{ -+ size_t i, n; -+ const char *p; -+ char *q; -+ -+ /* find the last '/', '\' or ':' */ -+ for (p = argv0 + strlen(argv0); --p > argv0;) -+ if (*p == '/' || *p == '\\' || *p == ':') { -+ p++; -+ break; -+ } -+ -+ /* Strip off trailing nonsense. */ -+ n = strlen(p); -+ if (n > 4 && -+ (strcmp(&p[n - 4], ".exe") == 0 || strcmp(&p[n - 4], ".EXE") == 0)) -+ n -= 4; -+ -+ /* Copy over the name, in lowercase. */ -+ if (n > sizeof prog - 1) -+ n = sizeof prog - 1; -+ for (q = prog, i = 0; i < n; i++, p++) -+ *q++ = isupper(*p) ? tolower(*p) : *p; -+ *q = '\0'; -+ return prog; -+} -+ -+#elif defined(OPENSSL_SYS_VMS) -+ -+char *opt_progname(const char *argv0) -+{ -+ const char *p, *q; -+ -+ /* Find last special character sys:[foo.bar]openssl */ -+ for (p = argv0 + strlen(argv0); --p > argv0;) -+ if (*p == ':' || *p == ']' || *p == '>') { -+ p++; -+ break; -+ } -+ -+ q = strrchr(p, '.'); -+ strncpy(prog, p, sizeof prog - 1); -+ prog[sizeof prog - 1] = '\0'; -+ if (q != NULL && q - p < sizeof prog) -+ prog[q - p] = '\0'; -+ return prog; -+} -+ -+#else -+ -+char *opt_progname(const char *argv0) -+{ -+ const char *p; -+ -+ /* Could use strchr, but this is like the ones above. */ -+ for (p = argv0 + strlen(argv0); --p > argv0;) -+ if (*p == '/') { -+ p++; -+ break; -+ } -+ strncpy(prog, p, sizeof prog - 1); -+ prog[sizeof prog - 1] = '\0'; -+ return prog; -+} -+#endif -+ -+char *opt_getprog(void) -+{ -+ return prog; -+} -+ -+/* Set up the arg parsing. */ -+char *opt_init(int ac, char **av, const OPTIONS *o) -+{ -+ /* Store state. */ -+ argc = ac; -+ argv = av; -+ opt_index = 1; -+ opts = o; -+ opt_progname(av[0]); -+ unknown = NULL; -+ -+ for (; o->name; ++o) { -+#ifndef NDEBUG -+ const OPTIONS *next; -+ int duplicated, i; -+#endif -+ -+ if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR) -+ continue; -+#ifndef NDEBUG -+ i = o->valtype; -+ -+ /* Make sure options are legit. */ -+ assert(o->name[0] != '-'); -+ assert(o->retval > 0); -+ switch (i) { -+ case 0: case '-': case '/': case '<': case '>': case 'E': case 'F': -+ case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's': -+ case 'u': case 'c': -+ break; -+ default: -+ assert(0); -+ } -+ -+ /* Make sure there are no duplicates. */ -+ for (next = o + 1; next->name; ++next) { -+ /* -+ * Some compilers inline strcmp and the assert string is too long. -+ */ -+ duplicated = strcmp(o->name, next->name) == 0; -+ assert(!duplicated); -+ } -+#endif -+ if (o->name[0] == '\0') { -+ assert(unknown == NULL); -+ unknown = o; -+ assert(unknown->valtype == 0 || unknown->valtype == '-'); -+ } -+ } -+ return prog; -+} -+ -+static OPT_PAIR formats[] = { -+ {"PEM/DER", OPT_FMT_PEMDER}, -+ {"pkcs12", OPT_FMT_PKCS12}, -+ {"smime", OPT_FMT_SMIME}, -+ {"engine", OPT_FMT_ENGINE}, -+ {"msblob", OPT_FMT_MSBLOB}, -+ {"netscape", OPT_FMT_NETSCAPE}, -+ {"nss", OPT_FMT_NSS}, -+ {"text", OPT_FMT_TEXT}, -+ {"http", OPT_FMT_HTTP}, -+ {"pvk", OPT_FMT_PVK}, -+ {NULL} -+}; -+ -+/* Print an error message about a failed format parse. */ -+int opt_format_error(const char *s, unsigned long flags) -+{ -+ OPT_PAIR *ap; -+ -+ if (flags == OPT_FMT_PEMDER) -+ BIO_printf(bio_err, "%s: Bad format \"%s\"; must be pem or der\n", -+ prog, s); -+ else { -+ BIO_printf(bio_err, "%s: Bad format \"%s\"; must be one of:\n", -+ prog, s); -+ for (ap = formats; ap->name; ap++) -+ if (flags & ap->retval) -+ BIO_printf(bio_err, " %s\n", ap->name); -+ } -+ return 0; -+} -+ -+/* Parse a format string, put it into *result; return 0 on failure, else 1. */ -+int opt_format(const char *s, unsigned long flags, int *result) -+{ -+ switch (*s) { -+ default: -+ return 0; -+ case 'D': -+ case 'd': -+ if ((flags & OPT_FMT_PEMDER) == 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_ASN1; -+ break; -+ case 'T': -+ case 't': -+ if ((flags & OPT_FMT_TEXT) == 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_TEXT; -+ break; -+ case 'N': -+ case 'n': -+ if ((flags & OPT_FMT_NSS) == 0) -+ return opt_format_error(s, flags); -+ if (strcmp(s, "NSS") != 0 && strcmp(s, "nss") != 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_NSS; -+ break; -+ case 'S': -+ case 's': -+ if ((flags & OPT_FMT_SMIME) == 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_SMIME; -+ break; -+ case 'M': -+ case 'm': -+ if ((flags & OPT_FMT_MSBLOB) == 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_MSBLOB; -+ break; -+ case 'E': -+ case 'e': -+ if ((flags & OPT_FMT_ENGINE) == 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_ENGINE; -+ break; -+ case 'H': -+ case 'h': -+ if ((flags & OPT_FMT_HTTP) == 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_HTTP; -+ break; -+ case '1': -+ if ((flags & OPT_FMT_PKCS12) == 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_PKCS12; -+ break; -+ case 'P': -+ case 'p': -+ if (s[1] == '\0' || strcmp(s, "PEM") == 0 || strcmp(s, "pem") == 0) { -+ if ((flags & OPT_FMT_PEMDER) == 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_PEM; -+ } else if (strcmp(s, "PVK") == 0 || strcmp(s, "pvk") == 0) { -+ if ((flags & OPT_FMT_PVK) == 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_PVK; -+ } else if (strcmp(s, "P12") == 0 || strcmp(s, "p12") == 0 -+ || strcmp(s, "PKCS12") == 0 || strcmp(s, "pkcs12") == 0) { -+ if ((flags & OPT_FMT_PKCS12) == 0) -+ return opt_format_error(s, flags); -+ *result = FORMAT_PKCS12; -+ } else -+ return 0; -+ break; -+ } -+ return 1; -+} -+ -+/* Parse a cipher name, put it in *EVP_CIPHER; return 0 on failure, else 1. */ -+int opt_cipher(const char *name, const EVP_CIPHER **cipherp) -+{ -+ *cipherp = EVP_get_cipherbyname(name); -+ if (*cipherp) -+ return 1; -+ BIO_printf(bio_err, "%s: Unknown cipher %s\n", prog, name); -+ return 0; -+} -+ -+/* -+ * Parse message digest name, put it in *EVP_MD; return 0 on failure, else 1. -+ */ -+int opt_md(const char *name, const EVP_MD **mdp) -+{ -+ *mdp = EVP_get_digestbyname(name); -+ if (*mdp) -+ return 1; -+ BIO_printf(bio_err, "%s: Unknown digest %s\n", prog, name); -+ return 0; -+} -+ -+/* Look through a list of name/value pairs. */ -+int opt_pair(const char *name, const OPT_PAIR* pairs, int *result) -+{ -+ const OPT_PAIR *pp; -+ -+ for (pp = pairs; pp->name; pp++) -+ if (strcmp(pp->name, name) == 0) { -+ *result = pp->retval; -+ return 1; -+ } -+ BIO_printf(bio_err, "%s: Value must be one of:\n", prog); -+ for (pp = pairs; pp->name; pp++) -+ BIO_printf(bio_err, "\t%s\n", pp->name); -+ return 0; -+} -+ -+/* Parse an int, put it into *result; return 0 on failure, else 1. */ -+int opt_int(const char *value, int *result) -+{ -+ long l; -+ -+ if (!opt_long(value, &l)) -+ return 0; -+ *result = (int)l; -+ if (*result != l) { -+ BIO_printf(bio_err, "%s: Value \"%s\" outside integer range\n", -+ prog, value); -+ return 0; -+ } -+ return 1; -+} -+ -+/* Parse a long, put it into *result; return 0 on failure, else 1. */ -+int opt_long(const char *value, long *result) -+{ -+ int oerrno = errno; -+ long l; -+ char *endp; -+ -+ errno = 0; -+ l = strtol(value, &endp, 0); -+ if (*endp -+ || endp == value -+ || ((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE) -+ || (l == 0 && errno != 0)) { -+ BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n", -+ prog, value); -+ errno = oerrno; -+ return 0; -+ } -+ *result = l; -+ errno = oerrno; -+ return 1; -+} -+ -+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ -+ defined(INTMAX_MAX) && defined(UINTMAX_MAX) -+ -+/* Parse an intmax_t, put it into *result; return 0 on failure, else 1. */ -+int opt_imax(const char *value, intmax_t *result) -+{ -+ int oerrno = errno; -+ intmax_t m; -+ char *endp; -+ -+ errno = 0; -+ m = strtoimax(value, &endp, 0); -+ if (*endp -+ || endp == value -+ || ((m == INTMAX_MAX || m == INTMAX_MIN) && errno == ERANGE) -+ || (m == 0 && errno != 0)) { -+ BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n", -+ prog, value); -+ errno = oerrno; -+ return 0; -+ } -+ *result = m; -+ errno = oerrno; -+ return 1; -+} -+ -+/* Parse a uintmax_t, put it into *result; return 0 on failure, else 1. */ -+int opt_umax(const char *value, uintmax_t *result) -+{ -+ int oerrno = errno; -+ uintmax_t m; -+ char *endp; -+ -+ errno = 0; -+ m = strtoumax(value, &endp, 0); -+ if (*endp -+ || endp == value -+ || (m == UINTMAX_MAX && errno == ERANGE) -+ || (m == 0 && errno != 0)) { -+ BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n", -+ prog, value); -+ errno = oerrno; -+ return 0; -+ } -+ *result = m; -+ errno = oerrno; -+ return 1; -+} -+#endif -+ -+/* -+ * Parse an unsigned long, put it into *result; return 0 on failure, else 1. -+ */ -+int opt_ulong(const char *value, unsigned long *result) -+{ -+ int oerrno = errno; -+ char *endptr; -+ unsigned long l; -+ -+ errno = 0; -+ l = strtoul(value, &endptr, 0); -+ if (*endptr -+ || endptr == value -+ || ((l == ULONG_MAX) && errno == ERANGE) -+ || (l == 0 && errno != 0)) { -+ BIO_printf(bio_err, "%s: Can't parse \"%s\" as an unsigned number\n", -+ prog, value); -+ errno = oerrno; -+ return 0; -+ } -+ *result = l; -+ errno = oerrno; -+ return 1; -+} -+ -+/* -+ * We pass opt as an int but cast it to "enum range" so that all the -+ * items in the OPT_V_ENUM enumeration are caught; this makes -Wswitch -+ * in gcc do the right thing. -+ */ -+enum range { OPT_V_ENUM }; -+ -+int opt_verify(int opt, X509_VERIFY_PARAM *vpm) -+{ -+ int i; -+ ossl_intmax_t t = 0; -+ ASN1_OBJECT *otmp; -+ X509_PURPOSE *xptmp; -+ const X509_VERIFY_PARAM *vtmp; -+ -+ assert(vpm != NULL); -+ assert(opt > OPT_V__FIRST); -+ assert(opt < OPT_V__LAST); -+ -+ switch ((enum range)opt) { -+ case OPT_V__FIRST: -+ case OPT_V__LAST: -+ return 0; -+ case OPT_V_POLICY: -+ otmp = OBJ_txt2obj(opt_arg(), 0); -+ if (otmp == NULL) { -+ BIO_printf(bio_err, "%s: Invalid Policy %s\n", prog, opt_arg()); -+ return 0; -+ } -+ X509_VERIFY_PARAM_add0_policy(vpm, otmp); -+ break; -+ case OPT_V_PURPOSE: -+ /* purpose name -> purpose index */ -+ i = X509_PURPOSE_get_by_sname(opt_arg()); -+ if (i < 0) { -+ BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg()); -+ return 0; -+ } -+ -+ /* purpose index -> purpose object */ -+ xptmp = X509_PURPOSE_get0(i); -+ -+ /* purpose object -> purpose value */ -+ i = X509_PURPOSE_get_id(xptmp); -+ -+ if (!X509_VERIFY_PARAM_set_purpose(vpm, i)) { -+ BIO_printf(bio_err, -+ "%s: Internal error setting purpose %s\n", -+ prog, opt_arg()); -+ return 0; -+ } -+ break; -+ case OPT_V_VERIFY_NAME: -+ vtmp = X509_VERIFY_PARAM_lookup(opt_arg()); -+ if (vtmp == NULL) { -+ BIO_printf(bio_err, "%s: Invalid verify name %s\n", -+ prog, opt_arg()); -+ return 0; -+ } -+ X509_VERIFY_PARAM_set1(vpm, vtmp); -+ break; -+ case OPT_V_VERIFY_DEPTH: -+ i = atoi(opt_arg()); -+ if (i >= 0) -+ X509_VERIFY_PARAM_set_depth(vpm, i); -+ break; -+ case OPT_V_VERIFY_AUTH_LEVEL: -+ i = atoi(opt_arg()); -+ if (i >= 0) -+ X509_VERIFY_PARAM_set_auth_level(vpm, i); -+ break; -+ case OPT_V_ATTIME: -+ if (!opt_imax(opt_arg(), &t)) -+ return 0; -+ if (t != (time_t)t) { -+ BIO_printf(bio_err, "%s: epoch time out of range %s\n", -+ prog, opt_arg()); -+ return 0; -+ } -+ X509_VERIFY_PARAM_set_time(vpm, (time_t)t); -+ break; -+ case OPT_V_VERIFY_HOSTNAME: -+ if (!X509_VERIFY_PARAM_set1_host(vpm, opt_arg(), 0)) -+ return 0; -+ break; -+ case OPT_V_VERIFY_EMAIL: -+ if (!X509_VERIFY_PARAM_set1_email(vpm, opt_arg(), 0)) -+ return 0; -+ break; -+ case OPT_V_VERIFY_IP: -+ if (!X509_VERIFY_PARAM_set1_ip_asc(vpm, opt_arg())) -+ return 0; -+ break; -+ case OPT_V_IGNORE_CRITICAL: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_IGNORE_CRITICAL); -+ break; -+ case OPT_V_ISSUER_CHECKS: -+ /* NOP, deprecated */ -+ break; -+ case OPT_V_CRL_CHECK: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK); -+ break; -+ case OPT_V_CRL_CHECK_ALL: -+ X509_VERIFY_PARAM_set_flags(vpm, -+ X509_V_FLAG_CRL_CHECK | -+ X509_V_FLAG_CRL_CHECK_ALL); -+ break; -+ case OPT_V_POLICY_CHECK: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_POLICY_CHECK); -+ break; -+ case OPT_V_EXPLICIT_POLICY: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXPLICIT_POLICY); -+ break; -+ case OPT_V_INHIBIT_ANY: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_ANY); -+ break; -+ case OPT_V_INHIBIT_MAP: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_MAP); -+ break; -+ case OPT_V_X509_STRICT: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_X509_STRICT); -+ break; -+ case OPT_V_EXTENDED_CRL: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXTENDED_CRL_SUPPORT); -+ break; -+ case OPT_V_USE_DELTAS: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_DELTAS); -+ break; -+ case OPT_V_POLICY_PRINT: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NOTIFY_POLICY); -+ break; -+ case OPT_V_CHECK_SS_SIG: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CHECK_SS_SIGNATURE); -+ break; -+ case OPT_V_TRUSTED_FIRST: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_TRUSTED_FIRST); -+ break; -+ case OPT_V_SUITEB_128_ONLY: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS_ONLY); -+ break; -+ case OPT_V_SUITEB_128: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS); -+ break; -+ case OPT_V_SUITEB_192: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_192_LOS); -+ break; -+ case OPT_V_PARTIAL_CHAIN: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN); -+ break; -+ case OPT_V_NO_ALT_CHAINS: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_ALT_CHAINS); -+ break; -+ case OPT_V_NO_CHECK_TIME: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_CHECK_TIME); -+ break; -+ case OPT_V_ALLOW_PROXY_CERTS: -+ X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_ALLOW_PROXY_CERTS); -+ break; -+ } -+ return 1; -+ -+} -+ -+/* -+ * Parse the next flag (and value if specified), return 0 if done, -1 on -+ * error, otherwise the flag's retval. -+ */ -+int opt_next(void) -+{ -+ char *p; -+ const OPTIONS *o; -+ int ival; -+ long lval; -+ unsigned long ulval; -+ ossl_intmax_t imval; -+ ossl_uintmax_t umval; -+ -+ /* Look at current arg; at end of the list? */ -+ arg = NULL; -+ p = argv[opt_index]; -+ if (p == NULL) -+ return 0; -+ -+ /* If word doesn't start with a -, we're done. */ -+ if (*p != '-') -+ return 0; -+ -+ /* Hit "--" ? We're done. */ -+ opt_index++; -+ if (strcmp(p, "--") == 0) -+ return 0; -+ -+ /* Allow -nnn and --nnn */ -+ if (*++p == '-') -+ p++; -+ flag = p - 1; -+ -+ /* If we have --flag=foo, snip it off */ -+ if ((arg = strchr(p, '=')) != NULL) -+ *arg++ = '\0'; -+ for (o = opts; o->name; ++o) { -+ /* If not this option, move on to the next one. */ -+ if (strcmp(p, o->name) != 0) -+ continue; -+ -+ /* If it doesn't take a value, make sure none was given. */ -+ if (o->valtype == 0 || o->valtype == '-') { -+ if (arg) { -+ BIO_printf(bio_err, -+ "%s: Option -%s does not take a value\n", prog, p); -+ return -1; -+ } -+ return o->retval; -+ } -+ -+ /* Want a value; get the next param if =foo not used. */ -+ if (arg == NULL) { -+ if (argv[opt_index] == NULL) { -+ BIO_printf(bio_err, -+ "%s: Option -%s needs a value\n", prog, o->name); -+ return -1; -+ } -+ arg = argv[opt_index++]; -+ } -+ -+ /* Syntax-check value. */ -+ switch (o->valtype) { -+ default: -+ case 's': -+ /* Just a string. */ -+ break; -+ case '/': -+ if (app_isdir(arg) >= 0) -+ break; -+ BIO_printf(bio_err, "%s: Not a directory: %s\n", prog, arg); -+ return -1; -+ case '<': -+ /* Input file. */ -+ if (strcmp(arg, "-") == 0 || app_access(arg, R_OK) >= 0) -+ break; -+ BIO_printf(bio_err, -+ "%s: Cannot open input file %s, %s\n", -+ prog, arg, strerror(errno)); -+ return -1; -+ case '>': -+ /* Output file. */ -+ if (strcmp(arg, "-") == 0 || app_access(arg, W_OK) >= 0 || errno == ENOENT) -+ break; -+ BIO_printf(bio_err, -+ "%s: Cannot open output file %s, %s\n", -+ prog, arg, strerror(errno)); -+ return -1; -+ case 'p': -+ case 'n': -+ if (!opt_int(arg, &ival) -+ || (o->valtype == 'p' && ival <= 0)) { -+ BIO_printf(bio_err, -+ "%s: Non-positive number \"%s\" for -%s\n", -+ prog, arg, o->name); -+ return -1; -+ } -+ break; -+ case 'M': -+ if (!opt_imax(arg, &imval)) { -+ BIO_printf(bio_err, -+ "%s: Invalid number \"%s\" for -%s\n", -+ prog, arg, o->name); -+ return -1; -+ } -+ break; -+ case 'U': -+ if (!opt_umax(arg, &umval)) { -+ BIO_printf(bio_err, -+ "%s: Invalid number \"%s\" for -%s\n", -+ prog, arg, o->name); -+ return -1; -+ } -+ break; -+ case 'l': -+ if (!opt_long(arg, &lval)) { -+ BIO_printf(bio_err, -+ "%s: Invalid number \"%s\" for -%s\n", -+ prog, arg, o->name); -+ return -1; -+ } -+ break; -+ case 'u': -+ if (!opt_ulong(arg, &ulval)) { -+ BIO_printf(bio_err, -+ "%s: Invalid number \"%s\" for -%s\n", -+ prog, arg, o->name); -+ return -1; -+ } -+ break; -+ case 'c': -+ case 'E': -+ case 'F': -+ case 'f': -+ if (opt_format(arg, -+ o->valtype == 'c' ? OPT_FMT_PDS : -+ o->valtype == 'E' ? OPT_FMT_PDE : -+ o->valtype == 'F' ? OPT_FMT_PEMDER -+ : OPT_FMT_ANY, &ival)) -+ break; -+ BIO_printf(bio_err, -+ "%s: Invalid format \"%s\" for -%s\n", -+ prog, arg, o->name); -+ return -1; -+ } -+ -+ /* Return the flag value. */ -+ return o->retval; -+ } -+ if (unknown != NULL) { -+ dunno = p; -+ return unknown->retval; -+ } -+ BIO_printf(bio_err, "%s: Option unknown option -%s\n", prog, p); -+ return -1; -+} -+ -+/* Return the most recent flag parameter. */ -+char *opt_arg(void) -+{ -+ return arg; -+} -+ -+/* Return the most recent flag. */ -+char *opt_flag(void) -+{ -+ return flag; -+} -+ -+/* Return the unknown option. */ -+char *opt_unknown(void) -+{ -+ return dunno; -+} -+ -+/* Return the rest of the arguments after parsing flags. */ -+char **opt_rest(void) -+{ -+ return &argv[opt_index]; -+} -+ -+/* How many items in remaining args? */ -+int opt_num_rest(void) -+{ -+ int i = 0; -+ char **pp; -+ -+ for (pp = opt_rest(); *pp; pp++, i++) -+ continue; -+ return i; -+} -+ -+/* Return a string describing the parameter type. */ -+static const char *valtype2param(const OPTIONS *o) -+{ -+ switch (o->valtype) { -+ case 0: -+ case '-': -+ return ""; -+ case 's': -+ return "val"; -+ case '/': -+ return "dir"; -+ case '<': -+ return "infile"; -+ case '>': -+ return "outfile"; -+ case 'p': -+ return "+int"; -+ case 'n': -+ return "int"; -+ case 'l': -+ return "long"; -+ case 'u': -+ return "ulong"; -+ case 'E': -+ return "PEM|DER|ENGINE"; -+ case 'F': -+ return "PEM|DER"; -+ case 'f': -+ return "format"; -+ case 'M': -+ return "intmax"; -+ case 'U': -+ return "uintmax"; -+ } -+ return "parm"; -+} -+ -+void opt_help(const OPTIONS *list) -+{ -+ const OPTIONS *o; -+ int i; -+ int standard_prolog; -+ int width = 5; -+ char start[80 + 1]; -+ char *p; -+ const char *help; -+ -+ /* Starts with its own help message? */ -+ standard_prolog = list[0].name != OPT_HELP_STR; -+ -+ /* Find the widest help. */ -+ for (o = list; o->name; o++) { -+ if (o->name == OPT_MORE_STR) -+ continue; -+ i = 2 + (int)strlen(o->name); -+ if (o->valtype != '-') -+ i += 1 + strlen(valtype2param(o)); -+ if (i < MAX_OPT_HELP_WIDTH && i > width) -+ width = i; -+ assert(i < (int)sizeof start); -+ } -+ -+ if (standard_prolog) -+ BIO_printf(bio_err, "Usage: %s [options]\nValid options are:\n", -+ prog); -+ -+ /* Now let's print. */ -+ for (o = list; o->name; o++) { -+ help = o->helpstr ? o->helpstr : "(No additional info)"; -+ if (o->name == OPT_HELP_STR) { -+ BIO_printf(bio_err, help, prog); -+ continue; -+ } -+ -+ /* Pad out prefix */ -+ memset(start, ' ', sizeof(start) - 1); -+ start[sizeof start - 1] = '\0'; -+ -+ if (o->name == OPT_MORE_STR) { -+ /* Continuation of previous line; pad and print. */ -+ start[width] = '\0'; -+ BIO_printf(bio_err, "%s %s\n", start, help); -+ continue; -+ } -+ -+ /* Build up the "-flag [param]" part. */ -+ p = start; -+ *p++ = ' '; -+ *p++ = '-'; -+ if (o->name[0]) -+ p += strlen(strcpy(p, o->name)); -+ else -+ *p++ = '*'; -+ if (o->valtype != '-') { -+ *p++ = ' '; -+ p += strlen(strcpy(p, valtype2param(o))); -+ } -+ *p = ' '; -+ if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) { -+ *p = '\0'; -+ BIO_printf(bio_err, "%s\n", start); -+ memset(start, ' ', sizeof(start)); -+ } -+ start[width] = '\0'; -+ BIO_printf(bio_err, "%s %s\n", start, help); -+ } -+} -+ -+#ifdef COMPILE_STANDALONE_TEST_DRIVER -+# include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_IN, OPT_INFORM, OPT_OUT, OPT_COUNT, OPT_U, OPT_FLAG, -+ OPT_STR, OPT_NOTUSED -+} OPTION_CHOICE; -+ -+static OPTIONS options[] = { -+ {OPT_HELP_STR, 1, '-', "Usage: %s flags\n"}, -+ {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"in", OPT_IN, '<', "input file"}, -+ {OPT_MORE_STR, 1, '-', "more detail about input"}, -+ {"inform", OPT_INFORM, 'f', "input file format; defaults to pem"}, -+ {"out", OPT_OUT, '>', "output file"}, -+ {"count", OPT_COUNT, 'p', "a counter greater than zero"}, -+ {"u", OPT_U, 'u', "an unsigned number"}, -+ {"flag", OPT_FLAG, 0, "just some flag"}, -+ {"str", OPT_STR, 's', "the magic word"}, -+ {"areallyverylongoption", OPT_HELP, '-', "long way for help"}, -+ {NULL} -+}; -+ -+BIO *bio_err; -+ -+int app_isdir(const char *name) -+{ -+ struct stat sb; -+ -+ return name != NULL && stat(name, &sb) >= 0 && S_ISDIR(sb.st_mode); -+} -+ -+int main(int ac, char **av) -+{ -+ OPTION_CHOICE o; -+ char **rest; -+ char *prog; -+ -+ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); -+ -+ prog = opt_init(ac, av, options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (c) { -+ case OPT_NOTUSED: -+ case OPT_EOF: -+ case OPT_ERR: -+ printf("%s: Usage error; try -help.\n", prog); -+ return 1; -+ case OPT_HELP: -+ opt_help(options); -+ return 0; -+ case OPT_IN: -+ printf("in %s\n", opt_arg()); -+ break; -+ case OPT_INFORM: -+ printf("inform %s\n", opt_arg()); -+ break; -+ case OPT_OUT: -+ printf("out %s\n", opt_arg()); -+ break; -+ case OPT_COUNT: -+ printf("count %s\n", opt_arg()); -+ break; -+ case OPT_U: -+ printf("u %s\n", opt_arg()); -+ break; -+ case OPT_FLAG: -+ printf("flag\n"); -+ break; -+ case OPT_STR: -+ printf("str %s\n", opt_arg()); -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ -+ printf("args = %d\n", argc); -+ if (argc) -+ while (*argv) -+ printf(" %s\n", *argv++); -+ return 0; -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/passwd.c b/CryptoPkg/Library/OpensslLib/openssl/apps/passwd.c -new file mode 100644 -index 0000000..a45245c ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/passwd.c -@@ -0,0 +1,512 @@ -+/* -+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC -+# define NO_MD5CRYPT_1 -+#endif -+ -+#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1) -+ -+# include -+ -+# include "apps.h" -+ -+# include -+# include -+# include -+# include -+# ifndef OPENSSL_NO_DES -+# include -+# endif -+# ifndef NO_MD5CRYPT_1 -+# include -+# endif -+ -+static unsigned const char cov_2char[64] = { -+ /* from crypto/des/fcrypt.c */ -+ 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, -+ 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, -+ 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, -+ 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, -+ 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, -+ 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, -+ 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, -+ 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A -+}; -+ -+static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, -+ char *passwd, BIO *out, int quiet, int table, -+ int reverse, size_t pw_maxlen, int usecrypt, int use1, -+ int useapr1); -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_IN, -+ OPT_NOVERIFY, OPT_QUIET, OPT_TABLE, OPT_REVERSE, OPT_APR1, -+ OPT_1, OPT_CRYPT, OPT_SALT, OPT_STDIN -+} OPTION_CHOICE; -+ -+OPTIONS passwd_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"in", OPT_IN, '<', "Pead passwords from file"}, -+ {"noverify", OPT_NOVERIFY, '-', -+ "Never verify when reading password from terminal"}, -+ {"quiet", OPT_QUIET, '-', "No warnings"}, -+ {"table", OPT_TABLE, '-', "Format output as table"}, -+ {"reverse", OPT_REVERSE, '-', "Switch table columns"}, -+ {"salt", OPT_SALT, 's', "Use provided salt"}, -+ {"stdin", OPT_STDIN, '-', "Read passwords from stdin"}, -+# ifndef NO_MD5CRYPT_1 -+ {"apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant"}, -+ {"1", OPT_1, '-', "MD5-based password algorithm"}, -+# endif -+# ifndef OPENSSL_NO_DES -+ {"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"}, -+# endif -+ {NULL} -+}; -+ -+int passwd_main(int argc, char **argv) -+{ -+ BIO *in = NULL; -+ char *infile = NULL, *salt = NULL, *passwd = NULL, **passwds = NULL; -+ char *salt_malloc = NULL, *passwd_malloc = NULL, *prog; -+ OPTION_CHOICE o; -+ int in_stdin = 0, pw_source_defined = 0; -+#ifndef OPENSSL_NO_UI -+ int in_noverify = 0; -+#endif -+ int passed_salt = 0, quiet = 0, table = 0, reverse = 0; -+ int ret = 1, usecrypt = 0, use1 = 0, useapr1 = 0; -+ size_t passwd_malloc_size = 0, pw_maxlen = 256; -+ -+ prog = opt_init(argc, argv, passwd_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(passwd_options); -+ ret = 0; -+ goto end; -+ case OPT_IN: -+ if (pw_source_defined) -+ goto opthelp; -+ infile = opt_arg(); -+ pw_source_defined = 1; -+ break; -+ case OPT_NOVERIFY: -+#ifndef OPENSSL_NO_UI -+ in_noverify = 1; -+#endif -+ break; -+ case OPT_QUIET: -+ quiet = 1; -+ break; -+ case OPT_TABLE: -+ table = 1; -+ break; -+ case OPT_REVERSE: -+ reverse = 1; -+ break; -+ case OPT_1: -+ use1 = 1; -+ break; -+ case OPT_APR1: -+ useapr1 = 1; -+ break; -+ case OPT_CRYPT: -+ usecrypt = 1; -+ break; -+ case OPT_SALT: -+ passed_salt = 1; -+ salt = opt_arg(); -+ break; -+ case OPT_STDIN: -+ if (pw_source_defined) -+ goto opthelp; -+ in_stdin = 1; -+ pw_source_defined = 1; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ -+ if (*argv) { -+ if (pw_source_defined) -+ goto opthelp; -+ pw_source_defined = 1; -+ passwds = argv; -+ } -+ -+ if (!usecrypt && !use1 && !useapr1) { -+ /* use default */ -+ usecrypt = 1; -+ } -+ if (usecrypt + use1 + useapr1 > 1) { -+ /* conflict */ -+ goto opthelp; -+ } -+ -+# ifdef OPENSSL_NO_DES -+ if (usecrypt) -+ goto opthelp; -+# endif -+# ifdef NO_MD5CRYPT_1 -+ if (use1 || useapr1) -+ goto opthelp; -+# endif -+ -+ if (infile != NULL && in_stdin) { -+ BIO_printf(bio_err, "%s: Can't combine -in and -stdin\n", prog); -+ goto end; -+ } -+ -+ if (infile != NULL || in_stdin) { -+ /* -+ * If in_stdin is true, we know that infile is NULL, and that -+ * bio_open_default() will give us back an alias for stdin. -+ */ -+ in = bio_open_default(infile, 'r', FORMAT_TEXT); -+ if (in == NULL) -+ goto end; -+ } -+ -+ if (usecrypt) -+ pw_maxlen = 8; -+ else if (use1 || useapr1) -+ pw_maxlen = 256; /* arbitrary limit, should be enough for most -+ * passwords */ -+ -+ if (passwds == NULL) { -+ /* no passwords on the command line */ -+ -+ passwd_malloc_size = pw_maxlen + 2; -+ /* longer than necessary so that we can warn about truncation */ -+ passwd = passwd_malloc = -+ app_malloc(passwd_malloc_size, "password buffer"); -+ } -+ -+ if ((in == NULL) && (passwds == NULL)) { -+ if (1) { -+#ifndef OPENSSL_NO_UI -+ /* build a null-terminated list */ -+ static char *passwds_static[2] = { NULL, NULL }; -+ -+ passwds = passwds_static; -+ if (in == NULL) -+ if (EVP_read_pw_string -+ (passwd_malloc, passwd_malloc_size, "Password: ", -+ !(passed_salt || in_noverify)) != 0) -+ goto end; -+ passwds[0] = passwd_malloc; -+ } else { -+#endif -+ BIO_printf(bio_err, "password required\n"); -+ goto end; -+ } -+ } -+ -+ -+ if (in == NULL) { -+ assert(passwds != NULL); -+ assert(*passwds != NULL); -+ -+ do { /* loop over list of passwords */ -+ passwd = *passwds++; -+ if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, bio_out, -+ quiet, table, reverse, pw_maxlen, usecrypt, use1, -+ useapr1)) -+ goto end; -+ } -+ while (*passwds != NULL); -+ } else -+ /* in != NULL */ -+ { -+ int done; -+ -+ assert(passwd != NULL); -+ do { -+ int r = BIO_gets(in, passwd, pw_maxlen + 1); -+ if (r > 0) { -+ char *c = (strchr(passwd, '\n')); -+ if (c != NULL) -+ *c = 0; /* truncate at newline */ -+ else { -+ /* ignore rest of line */ -+ char trash[BUFSIZ]; -+ do -+ r = BIO_gets(in, trash, sizeof trash); -+ while ((r > 0) && (!strchr(trash, '\n'))); -+ } -+ -+ if (!do_passwd -+ (passed_salt, &salt, &salt_malloc, passwd, bio_out, quiet, -+ table, reverse, pw_maxlen, usecrypt, use1, useapr1)) -+ goto end; -+ } -+ done = (r <= 0); -+ } -+ while (!done); -+ } -+ ret = 0; -+ -+ end: -+ ERR_print_errors(bio_err); -+ OPENSSL_free(salt_malloc); -+ OPENSSL_free(passwd_malloc); -+ BIO_free(in); -+ return (ret); -+} -+ -+# ifndef NO_MD5CRYPT_1 -+/* -+ * MD5-based password algorithm (should probably be available as a library -+ * function; then the static buffer would not be acceptable). For magic -+ * string "1", this should be compatible to the MD5-based BSD password -+ * algorithm. For 'magic' string "apr1", this is compatible to the MD5-based -+ * Apache password algorithm. (Apparently, the Apache password algorithm is -+ * identical except that the 'magic' string was changed -- the laziest -+ * application of the NIH principle I've ever encountered.) -+ */ -+static char *md5crypt(const char *passwd, const char *magic, const char *salt) -+{ -+ /* "$apr1$..salt..$.......md5hash..........\0" */ -+ static char out_buf[6 + 9 + 24 + 2]; -+ unsigned char buf[MD5_DIGEST_LENGTH]; -+ char *salt_out; -+ int n; -+ unsigned int i; -+ EVP_MD_CTX *md = NULL, *md2 = NULL; -+ size_t passwd_len, salt_len, magic_len; -+ -+ passwd_len = strlen(passwd); -+ out_buf[0] = '$'; -+ out_buf[1] = 0; -+ magic_len = strlen(magic); -+ -+ if (magic_len > 4) /* assert it's "1" or "apr1" */ -+ return NULL; -+ -+ OPENSSL_strlcat(out_buf, magic, sizeof out_buf); -+ OPENSSL_strlcat(out_buf, "$", sizeof out_buf); -+ OPENSSL_strlcat(out_buf, salt, sizeof out_buf); -+ -+ if (strlen(out_buf) > 6 + 8) /* assert "$apr1$..salt.." */ -+ return NULL; -+ -+ salt_out = out_buf + 2 + magic_len; -+ salt_len = strlen(salt_out); -+ -+ if (salt_len > 8) -+ return NULL; -+ -+ md = EVP_MD_CTX_new(); -+ if (md == NULL -+ || !EVP_DigestInit_ex(md, EVP_md5(), NULL) -+ || !EVP_DigestUpdate(md, passwd, passwd_len) -+ || !EVP_DigestUpdate(md, "$", 1) -+ || !EVP_DigestUpdate(md, magic, magic_len) -+ || !EVP_DigestUpdate(md, "$", 1) -+ || !EVP_DigestUpdate(md, salt_out, salt_len)) -+ goto err; -+ -+ md2 = EVP_MD_CTX_new(); -+ if (md2 == NULL -+ || !EVP_DigestInit_ex(md2, EVP_md5(), NULL) -+ || !EVP_DigestUpdate(md2, passwd, passwd_len) -+ || !EVP_DigestUpdate(md2, salt_out, salt_len) -+ || !EVP_DigestUpdate(md2, passwd, passwd_len) -+ || !EVP_DigestFinal_ex(md2, buf, NULL)) -+ goto err; -+ -+ for (i = passwd_len; i > sizeof buf; i -= sizeof buf) { -+ if (!EVP_DigestUpdate(md, buf, sizeof buf)) -+ goto err; -+ } -+ if (!EVP_DigestUpdate(md, buf, i)) -+ goto err; -+ -+ n = passwd_len; -+ while (n) { -+ if (!EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1)) -+ goto err; -+ n >>= 1; -+ } -+ if (!EVP_DigestFinal_ex(md, buf, NULL)) -+ return NULL; -+ -+ for (i = 0; i < 1000; i++) { -+ if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL)) -+ goto err; -+ if (!EVP_DigestUpdate(md2, -+ (i & 1) ? (unsigned const char *)passwd : buf, -+ (i & 1) ? passwd_len : sizeof buf)) -+ goto err; -+ if (i % 3) { -+ if (!EVP_DigestUpdate(md2, salt_out, salt_len)) -+ goto err; -+ } -+ if (i % 7) { -+ if (!EVP_DigestUpdate(md2, passwd, passwd_len)) -+ goto err; -+ } -+ if (!EVP_DigestUpdate(md2, -+ (i & 1) ? buf : (unsigned const char *)passwd, -+ (i & 1) ? sizeof buf : passwd_len)) -+ goto err; -+ if (!EVP_DigestFinal_ex(md2, buf, NULL)) -+ goto err; -+ } -+ EVP_MD_CTX_free(md2); -+ EVP_MD_CTX_free(md); -+ md2 = NULL; -+ md = NULL; -+ -+ { -+ /* transform buf into output string */ -+ unsigned char buf_perm[sizeof buf]; -+ int dest, source; -+ char *output; -+ -+ /* silly output permutation */ -+ for (dest = 0, source = 0; dest < 14; -+ dest++, source = (source + 6) % 17) -+ buf_perm[dest] = buf[source]; -+ buf_perm[14] = buf[5]; -+ buf_perm[15] = buf[11]; -+# ifndef PEDANTIC /* Unfortunately, this generates a "no -+ * effect" warning */ -+ assert(16 == sizeof buf_perm); -+# endif -+ -+ output = salt_out + salt_len; -+ assert(output == out_buf + strlen(out_buf)); -+ -+ *output++ = '$'; -+ -+ for (i = 0; i < 15; i += 3) { -+ *output++ = cov_2char[buf_perm[i + 2] & 0x3f]; -+ *output++ = cov_2char[((buf_perm[i + 1] & 0xf) << 2) | -+ (buf_perm[i + 2] >> 6)]; -+ *output++ = cov_2char[((buf_perm[i] & 3) << 4) | -+ (buf_perm[i + 1] >> 4)]; -+ *output++ = cov_2char[buf_perm[i] >> 2]; -+ } -+ assert(i == 15); -+ *output++ = cov_2char[buf_perm[i] & 0x3f]; -+ *output++ = cov_2char[buf_perm[i] >> 6]; -+ *output = 0; -+ assert(strlen(out_buf) < sizeof(out_buf)); -+ } -+ -+ return out_buf; -+ -+ err: -+ EVP_MD_CTX_free(md2); -+ EVP_MD_CTX_free(md); -+ return NULL; -+} -+# endif -+ -+static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, -+ char *passwd, BIO *out, int quiet, int table, -+ int reverse, size_t pw_maxlen, int usecrypt, int use1, -+ int useapr1) -+{ -+ char *hash = NULL; -+ -+ assert(salt_p != NULL); -+ assert(salt_malloc_p != NULL); -+ -+ /* first make sure we have a salt */ -+ if (!passed_salt) { -+# ifndef OPENSSL_NO_DES -+ if (usecrypt) { -+ if (*salt_malloc_p == NULL) { -+ *salt_p = *salt_malloc_p = app_malloc(3, "salt buffer"); -+ } -+ if (RAND_bytes((unsigned char *)*salt_p, 2) <= 0) -+ goto end; -+ (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */ -+ (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */ -+ (*salt_p)[2] = 0; -+# ifdef CHARSET_EBCDIC -+ ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert back -+ * to ASCII */ -+# endif -+ } -+# endif /* !OPENSSL_NO_DES */ -+ -+# ifndef NO_MD5CRYPT_1 -+ if (use1 || useapr1) { -+ int i; -+ -+ if (*salt_malloc_p == NULL) { -+ *salt_p = *salt_malloc_p = app_malloc(9, "salt buffer"); -+ } -+ if (RAND_bytes((unsigned char *)*salt_p, 8) <= 0) -+ goto end; -+ -+ for (i = 0; i < 8; i++) -+ (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */ -+ (*salt_p)[8] = 0; -+ } -+# endif /* !NO_MD5CRYPT_1 */ -+ } -+ -+ assert(*salt_p != NULL); -+ -+ /* truncate password if necessary */ -+ if ((strlen(passwd) > pw_maxlen)) { -+ if (!quiet) -+ /* -+ * XXX: really we should know how to print a size_t, not cast it -+ */ -+ BIO_printf(bio_err, -+ "Warning: truncating password to %u characters\n", -+ (unsigned)pw_maxlen); -+ passwd[pw_maxlen] = 0; -+ } -+ assert(strlen(passwd) <= pw_maxlen); -+ -+ /* now compute password hash */ -+# ifndef OPENSSL_NO_DES -+ if (usecrypt) -+ hash = DES_crypt(passwd, *salt_p); -+# endif -+# ifndef NO_MD5CRYPT_1 -+ if (use1 || useapr1) -+ hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p); -+# endif -+ assert(hash != NULL); -+ -+ if (table && !reverse) -+ BIO_printf(out, "%s\t%s\n", passwd, hash); -+ else if (table && reverse) -+ BIO_printf(out, "%s\t%s\n", hash, passwd); -+ else -+ BIO_printf(out, "%s\n", hash); -+ return 1; -+ -+ end: -+ return 0; -+} -+#else -+ -+int passwd_main(int argc, char **argv) -+{ -+ BIO_printf(bio_err, "Program not available.\n"); -+ return (1); -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/pca-cert.srl b/CryptoPkg/Library/OpensslLib/openssl/apps/pca-cert.srl -new file mode 100644 -index 0000000..2c7456e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/pca-cert.srl -@@ -0,0 +1 @@ -+07 -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/pca-key.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/pca-key.pem -new file mode 100644 -index 0000000..c6ad0e9 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/pca-key.pem -@@ -0,0 +1,16 @@ -+-----BEGIN PRIVATE KEY----- -+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALYYjjtpLs/lfkPF -+xAFZ4V3He5mZFbsEakK9bA2fQaryreRwyfhbXbDJHyBV+c4xI5fbmmVd2t/us4k4 -+rMhGsBtL89SqCEHhPJpLFywiQVmJTAjANYrWkZK5uR/++YmZyzuLfPHLButuK6cF -+GKXw3NNToxjYooMf0mad2rPX3cKTAgMBAAECgYBvrJ+Nz/Pli9jjt2V9bqHH4Y7r -+o/avuwVv6Ltbn0+mhy4d6w3yQhYzVSTBr/iDe59YglUt1WFl8/4nKZrNOIzHJlav -+Sw4hd3fYBHxbT+DgZMQ9ikjHECWRdDffrnlTLsSJAcxnpMJBPe3dKCRDMUrqWUvB -+IIKaxyqmXJms5Y/wAQJBAPFL9NMKJcWBftMKXCasxsV0ZGjgqHGZODYjtGFN9jJO -+6AbZrxfCcapTWG4RCC2o/EDEMN8aArEhfdrYY3lhXGsCQQDBMRzFevkD7SYXTw5G -+NA/gJOAsFMYbt7tebcCRsHT7t3ymVfO2QwK7ZF0f/SYvi7cMAPraHvO7s3kFdGTB -+kDx5AkAHBICASsFCdzurA5gef9PgFjx9WFtNwnkCChPK6KuKVwUkfdw7wqnvnDDs -+Mo6cVVfQwmPxeR4u7JxuavCprQ01AkEAp5ZGAh1J9Jj9CQ1AMbAp8WOrvzGKJTM9 -+641Dll4/LLif/d7j2kDJFuvaSMyeGnKVqGkVMq/U+QeYPR4Z5TuM6QJAWK05qFed -+wYgTZyVN0MY53ZOMAIWwjz0cr24TvDfmsZqIvguGL616GKQZKdKDZQyQHg+dCzqJ -+HgIoacuFDKz5CA== -+-----END PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/pca-req.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/pca-req.pem -new file mode 100644 -index 0000000..5a8c5cb ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/pca-req.pem -@@ -0,0 +1,11 @@ -+-----BEGIN CERTIFICATE REQUEST----- -+MIIBnDCCAQUCAQAwXDELMAkGA1UEBhMCQVUxEzARBgNVBAgMClF1ZWVuc2xhbmQx -+GjAYBgNVBAoMEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDDBNUZXN0IFBDQSAo -+MTAyNCBiaXQpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2GI47aS7P5X5D -+xcQBWeFdx3uZmRW7BGpCvWwNn0Gq8q3kcMn4W12wyR8gVfnOMSOX25plXdrf7rOJ -+OKzIRrAbS/PUqghB4TyaSxcsIkFZiUwIwDWK1pGSubkf/vmJmcs7i3zxywbrbiun -+BRil8NzTU6MY2KKDH9Jmndqz193CkwIDAQABoAAwDQYJKoZIhvcNAQELBQADgYEA -+eJdCB0nHnFK0hek4biAxX0GuJXkknuUy46NKEhv3GBwt4gtO29bfkbQTGOsBBKNs -+KptlnkItscOXY+0lSva9K3XlwD9do7k2IZFtXJVayZVw1GcKybIY0l7B6kcSxG7T -+f3CsO+ifdrsJKtyoZNs96lBMrtXyGybt3mgQNdZauQU= -+-----END CERTIFICATE REQUEST----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/pkcs12.c b/CryptoPkg/Library/OpensslLib/openssl/apps/pkcs12.c -new file mode 100644 -index 0000000..0e69c9c ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/pkcs12.c -@@ -0,0 +1,935 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#if defined(OPENSSL_NO_DES) -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include -+# include -+# include -+# include "apps.h" -+# include -+# include -+# include -+# include -+ -+# define NOKEYS 0x1 -+# define NOCERTS 0x2 -+# define INFO 0x4 -+# define CLCERTS 0x8 -+# define CACERTS 0x10 -+ -+static int get_cert_chain(X509 *cert, X509_STORE *store, -+ STACK_OF(X509) **chain); -+int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, -+ const char *pass, int passlen, int options, -+ char *pempass, const EVP_CIPHER *enc); -+int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags, -+ const char *pass, int passlen, int options, -+ char *pempass, const EVP_CIPHER *enc); -+int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bags, -+ const char *pass, int passlen, -+ int options, char *pempass, const EVP_CIPHER *enc); -+int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, -+ const char *name); -+void hex_prin(BIO *out, unsigned char *buf, int len); -+static int alg_print(const X509_ALGOR *alg); -+int cert_load(BIO *in, STACK_OF(X509) *sk); -+static int set_pbe(int *ppbe, const char *str); -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_CIPHER, OPT_NOKEYS, OPT_KEYEX, OPT_KEYSIG, OPT_NOCERTS, OPT_CLCERTS, -+ OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER, -+ OPT_DESCERT, OPT_EXPORT, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, -+ OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE, -+ OPT_RAND, OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME, -+ OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH, -+ OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE -+} OPTION_CHOICE; -+ -+OPTIONS pkcs12_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"nokeys", OPT_NOKEYS, '-', "Don't output private keys"}, -+ {"keyex", OPT_KEYEX, '-', "Set MS key exchange type"}, -+ {"keysig", OPT_KEYSIG, '-', "Set MS key signature type"}, -+ {"nocerts", OPT_NOCERTS, '-', "Don't output certificates"}, -+ {"clcerts", OPT_CLCERTS, '-', "Only output client certificates"}, -+ {"cacerts", OPT_CACERTS, '-', "Only output CA certificates"}, -+ {"noout", OPT_NOOUT, '-', "Don't output anything, just verify"}, -+ {"info", OPT_INFO, '-', "Print info about PKCS#12 structure"}, -+ {"chain", OPT_CHAIN, '-', "Add certificate chain"}, -+ {"twopass", OPT_TWOPASS, '-', "Separate MAC, encryption passwords"}, -+ {"nomacver", OPT_NOMACVER, '-', "Don't verify MAC"}, -+# ifndef OPENSSL_NO_RC2 -+ {"descert", OPT_DESCERT, '-', -+ "Encrypt output with 3DES (default RC2-40)"}, -+ {"certpbe", OPT_CERTPBE, 's', -+ "Certificate PBE algorithm (default RC2-40)"}, -+# else -+ {"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (the default)"}, -+ {"certpbe", OPT_CERTPBE, 's', "Certificate PBE algorithm (default 3DES)"}, -+# endif -+ {"export", OPT_EXPORT, '-', "Output PKCS12 file"}, -+ {"noiter", OPT_NOITER, '-', "Don't use encryption iteration"}, -+ {"maciter", OPT_MACITER, '-', "Use MAC iteration"}, -+ {"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration"}, -+ {"nomac", OPT_NOMAC, '-', "Don't generate MAC"}, -+ {"LMK", OPT_LMK, '-', -+ "Add local machine keyset attribute to private key"}, -+ {"nodes", OPT_NODES, '-', "Don't encrypt private keys"}, -+ {"macalg", OPT_MACALG, 's', -+ "Digest algorithm used in MAC (default SHA1)"}, -+ {"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"}, -+ {"rand", OPT_RAND, 's', -+ "Load the file(s) into the random number generator"}, -+ {"inkey", OPT_INKEY, '<', "Private key if not infile"}, -+ {"certfile", OPT_CERTFILE, '<', "Load certs from file"}, -+ {"name", OPT_NAME, 's', "Use name as friendly name"}, -+ {"CSP", OPT_CSP, 's', "Microsoft CSP name"}, -+ {"caname", OPT_CANAME, 's', -+ "Use name as CA friendly name (can be repeated)"}, -+ {"in", OPT_IN, '<', "Input filename"}, -+ {"out", OPT_OUT, '>', "Output filename"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+ {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, -+ {"password", OPT_PASSWORD, 's', "Set import/export password source"}, -+ {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"}, -+ {"CAfile", OPT_CAFILE, '<', "PEM-format file of CA's"}, -+ {"no-CAfile", OPT_NOCAFILE, '-', -+ "Do not load the default certificates file"}, -+ {"no-CApath", OPT_NOCAPATH, '-', -+ "Do not load certificates from the default certificates directory"}, -+ {"", OPT_CIPHER, '-', "Any supported cipher"}, -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+int pkcs12_main(int argc, char **argv) -+{ -+ char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL; -+ char *name = NULL, *csp_name = NULL; -+ char pass[2048] = "", macpass[2048] = ""; -+ int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0; -+ int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER; -+# ifndef OPENSSL_NO_RC2 -+ int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; -+# else -+ int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; -+# endif -+ int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; -+ int ret = 1, macver = 1, add_lmk = 0, private = 0; -+ int noprompt = 0; -+ char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL; -+ char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL; -+ char *cpass = NULL, *mpass = NULL, *badpass = NULL; -+ const char *CApath = NULL, *CAfile = NULL, *prog; -+ int noCApath = 0, noCAfile = 0; -+ ENGINE *e = NULL; -+ BIO *in = NULL, *out = NULL; -+ PKCS12 *p12 = NULL; -+ STACK_OF(OPENSSL_STRING) *canames = NULL; -+ const EVP_CIPHER *enc = EVP_des_ede3_cbc(); -+ OPTION_CHOICE o; -+ -+ prog = opt_init(argc, argv, pkcs12_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(pkcs12_options); -+ ret = 0; -+ goto end; -+ case OPT_NOKEYS: -+ options |= NOKEYS; -+ break; -+ case OPT_KEYEX: -+ keytype = KEY_EX; -+ break; -+ case OPT_KEYSIG: -+ keytype = KEY_SIG; -+ break; -+ case OPT_NOCERTS: -+ options |= NOCERTS; -+ break; -+ case OPT_CLCERTS: -+ options |= CLCERTS; -+ break; -+ case OPT_CACERTS: -+ options |= CACERTS; -+ break; -+ case OPT_NOOUT: -+ options |= (NOKEYS | NOCERTS); -+ break; -+ case OPT_INFO: -+ options |= INFO; -+ break; -+ case OPT_CHAIN: -+ chain = 1; -+ break; -+ case OPT_TWOPASS: -+ twopass = 1; -+ break; -+ case OPT_NOMACVER: -+ macver = 0; -+ break; -+ case OPT_DESCERT: -+ cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; -+ break; -+ case OPT_EXPORT: -+ export_cert = 1; -+ break; -+ case OPT_CIPHER: -+ if (!opt_cipher(opt_unknown(), &enc)) -+ goto opthelp; -+ break; -+ case OPT_NOITER: -+ iter = 1; -+ break; -+ case OPT_MACITER: -+ maciter = PKCS12_DEFAULT_ITER; -+ break; -+ case OPT_NOMACITER: -+ maciter = 1; -+ break; -+ case OPT_NOMAC: -+ maciter = -1; -+ break; -+ case OPT_MACALG: -+ macalg = opt_arg(); -+ break; -+ case OPT_NODES: -+ enc = NULL; -+ break; -+ case OPT_CERTPBE: -+ if (!set_pbe(&cert_pbe, opt_arg())) -+ goto opthelp; -+ break; -+ case OPT_KEYPBE: -+ if (!set_pbe(&key_pbe, opt_arg())) -+ goto opthelp; -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ break; -+ case OPT_INKEY: -+ keyname = opt_arg(); -+ break; -+ case OPT_CERTFILE: -+ certfile = opt_arg(); -+ break; -+ case OPT_NAME: -+ name = opt_arg(); -+ break; -+ case OPT_LMK: -+ add_lmk = 1; -+ break; -+ case OPT_CSP: -+ csp_name = opt_arg(); -+ break; -+ case OPT_CANAME: -+ if (canames == NULL -+ && (canames = sk_OPENSSL_STRING_new_null()) == NULL) -+ goto end; -+ sk_OPENSSL_STRING_push(canames, opt_arg()); -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ case OPT_PASSOUT: -+ passoutarg = opt_arg(); -+ break; -+ case OPT_PASSWORD: -+ passarg = opt_arg(); -+ break; -+ case OPT_CAPATH: -+ CApath = opt_arg(); -+ break; -+ case OPT_CAFILE: -+ CAfile = opt_arg(); -+ break; -+ case OPT_NOCAPATH: -+ noCApath = 1; -+ break; -+ case OPT_NOCAFILE: -+ noCAfile = 1; -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ private = 1; -+ -+ if (passarg) { -+ if (export_cert) -+ passoutarg = passarg; -+ else -+ passinarg = passarg; -+ } -+ -+ if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { -+ BIO_printf(bio_err, "Error getting passwords\n"); -+ goto end; -+ } -+ -+ if (!cpass) { -+ if (export_cert) -+ cpass = passout; -+ else -+ cpass = passin; -+ } -+ -+ if (cpass) { -+ mpass = cpass; -+ noprompt = 1; -+ } else { -+ cpass = pass; -+ mpass = macpass; -+ } -+ -+ if (export_cert || inrand) { -+ app_RAND_load_file(NULL, (inrand != NULL)); -+ if (inrand != NULL) -+ BIO_printf(bio_err, "%ld semi-random bytes loaded\n", -+ app_RAND_load_files(inrand)); -+ } -+ -+ if (twopass) { -+ if (1) { -+#ifndef OPENSSL_NO_UI -+ if (EVP_read_pw_string -+ (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) { -+ BIO_printf(bio_err, "Can't read Password\n"); -+ goto end; -+ } -+ } else { -+#endif -+ BIO_printf(bio_err, "Unsupported option -twopass\n"); -+ goto end; -+ } -+ } -+ -+ if (export_cert) { -+ EVP_PKEY *key = NULL; -+ X509 *ucert = NULL, *x = NULL; -+ STACK_OF(X509) *certs = NULL; -+ const EVP_MD *macmd = NULL; -+ unsigned char *catmp = NULL; -+ int i; -+ -+ if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) { -+ BIO_printf(bio_err, "Nothing to do!\n"); -+ goto export_end; -+ } -+ -+ if (options & NOCERTS) -+ chain = 0; -+ -+ if (!(options & NOKEYS)) { -+ key = load_key(keyname ? keyname : infile, -+ FORMAT_PEM, 1, passin, e, "private key"); -+ if (!key) -+ goto export_end; -+ } -+ -+ /* Load in all certs in input file */ -+ if (!(options & NOCERTS)) { -+ if (!load_certs(infile, &certs, FORMAT_PEM, NULL, -+ "certificates")) -+ goto export_end; -+ -+ if (key) { -+ /* Look for matching private key */ -+ for (i = 0; i < sk_X509_num(certs); i++) { -+ x = sk_X509_value(certs, i); -+ if (X509_check_private_key(x, key)) { -+ ucert = x; -+ /* Zero keyid and alias */ -+ X509_keyid_set1(ucert, NULL, 0); -+ X509_alias_set1(ucert, NULL, 0); -+ /* Remove from list */ -+ (void)sk_X509_delete(certs, i); -+ break; -+ } -+ } -+ if (!ucert) { -+ BIO_printf(bio_err, -+ "No certificate matches private key\n"); -+ goto export_end; -+ } -+ } -+ -+ } -+ -+ /* Add any more certificates asked for */ -+ if (certfile) { -+ if (!load_certs(certfile, &certs, FORMAT_PEM, NULL, -+ "certificates from certfile")) -+ goto export_end; -+ } -+ -+ /* If chaining get chain from user cert */ -+ if (chain) { -+ int vret; -+ STACK_OF(X509) *chain2; -+ X509_STORE *store; -+ if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) -+ == NULL) -+ goto export_end; -+ -+ vret = get_cert_chain(ucert, store, &chain2); -+ X509_STORE_free(store); -+ -+ if (vret == X509_V_OK) { -+ /* Exclude verified certificate */ -+ for (i = 1; i < sk_X509_num(chain2); i++) -+ sk_X509_push(certs, sk_X509_value(chain2, i)); -+ /* Free first certificate */ -+ X509_free(sk_X509_value(chain2, 0)); -+ sk_X509_free(chain2); -+ } else { -+ if (vret != X509_V_ERR_UNSPECIFIED) -+ BIO_printf(bio_err, "Error %s getting chain.\n", -+ X509_verify_cert_error_string(vret)); -+ else -+ ERR_print_errors(bio_err); -+ goto export_end; -+ } -+ } -+ -+ /* Add any CA names */ -+ -+ for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) { -+ catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i); -+ X509_alias_set1(sk_X509_value(certs, i), catmp, -1); -+ } -+ -+ if (csp_name && key) -+ EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name, -+ MBSTRING_ASC, (unsigned char *)csp_name, -+ -1); -+ -+ if (add_lmk && key) -+ EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1); -+ -+ if (!noprompt) { -+ if (1) { -+#ifndef OPENSSL_NO_UI -+ if (EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", -+ 1)) { -+ BIO_printf(bio_err, "Can't read Password\n"); -+ goto export_end; -+ } -+ } else { -+#endif -+ BIO_printf(bio_err, "Password required\n"); -+ goto export_end; -+ } -+ } -+ -+ if (!twopass) -+ OPENSSL_strlcpy(macpass, pass, sizeof macpass); -+ -+ p12 = PKCS12_create(cpass, name, key, ucert, certs, -+ key_pbe, cert_pbe, iter, -1, keytype); -+ -+ if (!p12) { -+ ERR_print_errors(bio_err); -+ goto export_end; -+ } -+ -+ if (macalg) { -+ if (!opt_md(macalg, &macmd)) -+ goto opthelp; -+ } -+ -+ if (maciter != -1) -+ PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); -+ -+ assert(private); -+ -+ out = bio_open_owner(outfile, FORMAT_PKCS12, private); -+ if (out == NULL) -+ goto end; -+ -+ i2d_PKCS12_bio(out, p12); -+ -+ ret = 0; -+ -+ export_end: -+ -+ EVP_PKEY_free(key); -+ sk_X509_pop_free(certs, X509_free); -+ X509_free(ucert); -+ -+ goto end; -+ -+ } -+ -+ in = bio_open_default(infile, 'r', FORMAT_PKCS12); -+ if (in == NULL) -+ goto end; -+ out = bio_open_owner(outfile, FORMAT_PEM, private); -+ if (out == NULL) -+ goto end; -+ -+ if ((p12 = d2i_PKCS12_bio(in, NULL)) == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (!noprompt) { -+ if (1) { -+#ifndef OPENSSL_NO_UI -+ if (EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", -+ 0)) { -+ BIO_printf(bio_err, "Can't read Password\n"); -+ goto end; -+ } -+ } else { -+#endif -+ BIO_printf(bio_err, "Password required\n"); -+ goto end; -+ } -+ } -+ -+ if (!twopass) -+ OPENSSL_strlcpy(macpass, pass, sizeof macpass); -+ -+ if ((options & INFO) && PKCS12_mac_present(p12)) { -+ const ASN1_INTEGER *tmaciter; -+ const X509_ALGOR *macalgid; -+ const ASN1_OBJECT *macobj; -+ PKCS12_get0_mac(NULL, &macalgid, NULL, &tmaciter, p12); -+ X509_ALGOR_get0(&macobj, NULL, NULL, macalgid); -+ BIO_puts(bio_err, "MAC:"); -+ i2a_ASN1_OBJECT(bio_err, macobj); -+ BIO_printf(bio_err, " Iteration %ld\n", -+ tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L); -+ } -+ if (macver) { -+ /* If we enter empty password try no password first */ -+ if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { -+ /* If mac and crypto pass the same set it to NULL too */ -+ if (!twopass) -+ cpass = NULL; -+ } else if (!PKCS12_verify_mac(p12, mpass, -1)) { -+ /* -+ * May be UTF8 from previous version of OpenSSL: -+ * convert to a UTF8 form which will translate -+ * to the same Unicode password. -+ */ -+ unsigned char *utmp; -+ int utmplen; -+ utmp = OPENSSL_asc2uni(mpass, -1, NULL, &utmplen); -+ if (utmp == NULL) -+ goto end; -+ badpass = OPENSSL_uni2utf8(utmp, utmplen); -+ OPENSSL_free(utmp); -+ if (!PKCS12_verify_mac(p12, badpass, -1)) { -+ BIO_printf(bio_err, "Mac verify error: invalid password?\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } else { -+ BIO_printf(bio_err, "Warning: using broken algorithm\n"); -+ if (!twopass) -+ cpass = badpass; -+ } -+ } -+ } -+ -+ assert(private); -+ if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout, enc)) { -+ BIO_printf(bio_err, "Error outputting keys and certificates\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ ret = 0; -+ end: -+ PKCS12_free(p12); -+ if (export_cert || inrand) -+ app_RAND_write_file(NULL); -+ release_engine(e); -+ BIO_free(in); -+ BIO_free_all(out); -+ sk_OPENSSL_STRING_free(canames); -+ OPENSSL_free(badpass); -+ OPENSSL_free(passin); -+ OPENSSL_free(passout); -+ return (ret); -+} -+ -+int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass, -+ int passlen, int options, char *pempass, -+ const EVP_CIPHER *enc) -+{ -+ STACK_OF(PKCS7) *asafes = NULL; -+ STACK_OF(PKCS12_SAFEBAG) *bags; -+ int i, bagnid; -+ int ret = 0; -+ PKCS7 *p7; -+ -+ if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) -+ return 0; -+ for (i = 0; i < sk_PKCS7_num(asafes); i++) { -+ p7 = sk_PKCS7_value(asafes, i); -+ bagnid = OBJ_obj2nid(p7->type); -+ if (bagnid == NID_pkcs7_data) { -+ bags = PKCS12_unpack_p7data(p7); -+ if (options & INFO) -+ BIO_printf(bio_err, "PKCS7 Data\n"); -+ } else if (bagnid == NID_pkcs7_encrypted) { -+ if (options & INFO) { -+ BIO_printf(bio_err, "PKCS7 Encrypted data: "); -+ alg_print(p7->d.encrypted->enc_data->algorithm); -+ } -+ bags = PKCS12_unpack_p7encdata(p7, pass, passlen); -+ } else -+ continue; -+ if (!bags) -+ goto err; -+ if (!dump_certs_pkeys_bags(out, bags, pass, passlen, -+ options, pempass, enc)) { -+ sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); -+ goto err; -+ } -+ sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); -+ bags = NULL; -+ } -+ ret = 1; -+ -+ err: -+ sk_PKCS7_pop_free(asafes, PKCS7_free); -+ return ret; -+} -+ -+int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags, -+ const char *pass, int passlen, int options, -+ char *pempass, const EVP_CIPHER *enc) -+{ -+ int i; -+ for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { -+ if (!dump_certs_pkeys_bag(out, -+ sk_PKCS12_SAFEBAG_value(bags, i), -+ pass, passlen, options, pempass, enc)) -+ return 0; -+ } -+ return 1; -+} -+ -+int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bag, -+ const char *pass, int passlen, int options, -+ char *pempass, const EVP_CIPHER *enc) -+{ -+ EVP_PKEY *pkey; -+ PKCS8_PRIV_KEY_INFO *p8; -+ const PKCS8_PRIV_KEY_INFO *p8c; -+ X509 *x509; -+ const STACK_OF(X509_ATTRIBUTE) *attrs; -+ int ret = 0; -+ -+ attrs = PKCS12_SAFEBAG_get0_attrs(bag); -+ -+ switch (PKCS12_SAFEBAG_get_nid(bag)) { -+ case NID_keyBag: -+ if (options & INFO) -+ BIO_printf(bio_err, "Key bag\n"); -+ if (options & NOKEYS) -+ return 1; -+ print_attribs(out, attrs, "Bag Attributes"); -+ p8c = PKCS12_SAFEBAG_get0_p8inf(bag); -+ if ((pkey = EVP_PKCS82PKEY(p8c)) == NULL) -+ return 0; -+ print_attribs(out, PKCS8_pkey_get0_attrs(p8c), "Key Attributes"); -+ ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); -+ EVP_PKEY_free(pkey); -+ break; -+ -+ case NID_pkcs8ShroudedKeyBag: -+ if (options & INFO) { -+ const X509_SIG *tp8; -+ const X509_ALGOR *tp8alg; -+ -+ BIO_printf(bio_err, "Shrouded Keybag: "); -+ tp8 = PKCS12_SAFEBAG_get0_pkcs8(bag); -+ X509_SIG_get0(tp8, &tp8alg, NULL); -+ alg_print(tp8alg); -+ } -+ if (options & NOKEYS) -+ return 1; -+ print_attribs(out, attrs, "Bag Attributes"); -+ if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL) -+ return 0; -+ if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) { -+ PKCS8_PRIV_KEY_INFO_free(p8); -+ return 0; -+ } -+ print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes"); -+ PKCS8_PRIV_KEY_INFO_free(p8); -+ ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); -+ EVP_PKEY_free(pkey); -+ break; -+ -+ case NID_certBag: -+ if (options & INFO) -+ BIO_printf(bio_err, "Certificate bag\n"); -+ if (options & NOCERTS) -+ return 1; -+ if (PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID)) { -+ if (options & CACERTS) -+ return 1; -+ } else if (options & CLCERTS) -+ return 1; -+ print_attribs(out, attrs, "Bag Attributes"); -+ if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate) -+ return 1; -+ if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL) -+ return 0; -+ dump_cert_text(out, x509); -+ ret = PEM_write_bio_X509(out, x509); -+ X509_free(x509); -+ break; -+ -+ case NID_safeContentsBag: -+ if (options & INFO) -+ BIO_printf(bio_err, "Safe Contents bag\n"); -+ print_attribs(out, attrs, "Bag Attributes"); -+ return dump_certs_pkeys_bags(out, PKCS12_SAFEBAG_get0_safes(bag), -+ pass, passlen, options, pempass, enc); -+ -+ default: -+ BIO_printf(bio_err, "Warning unsupported bag type: "); -+ i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_type(bag)); -+ BIO_printf(bio_err, "\n"); -+ return 1; -+ } -+ return ret; -+} -+ -+/* Given a single certificate return a verified chain or NULL if error */ -+ -+static int get_cert_chain(X509 *cert, X509_STORE *store, -+ STACK_OF(X509) **chain) -+{ -+ X509_STORE_CTX *store_ctx = NULL; -+ STACK_OF(X509) *chn = NULL; -+ int i = 0; -+ -+ store_ctx = X509_STORE_CTX_new(); -+ if (store_ctx == NULL) { -+ i = X509_V_ERR_UNSPECIFIED; -+ goto end; -+ } -+ if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL)) { -+ i = X509_V_ERR_UNSPECIFIED; -+ goto end; -+ } -+ -+ -+ if (X509_verify_cert(store_ctx) > 0) -+ chn = X509_STORE_CTX_get1_chain(store_ctx); -+ else if ((i = X509_STORE_CTX_get_error(store_ctx)) == 0) -+ i = X509_V_ERR_UNSPECIFIED; -+ -+end: -+ X509_STORE_CTX_free(store_ctx); -+ *chain = chn; -+ return i; -+} -+ -+static int alg_print(const X509_ALGOR *alg) -+{ -+ int pbenid, aparamtype; -+ const ASN1_OBJECT *aoid; -+ const void *aparam; -+ PBEPARAM *pbe = NULL; -+ -+ X509_ALGOR_get0(&aoid, &aparamtype, &aparam, alg); -+ -+ pbenid = OBJ_obj2nid(aoid); -+ -+ BIO_printf(bio_err, "%s", OBJ_nid2ln(pbenid)); -+ -+ /* -+ * If PBE algorithm is PBES2 decode algorithm parameters -+ * for additional details. -+ */ -+ if (pbenid == NID_pbes2) { -+ PBE2PARAM *pbe2 = NULL; -+ int encnid; -+ if (aparamtype == V_ASN1_SEQUENCE) -+ pbe2 = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBE2PARAM)); -+ if (pbe2 == NULL) { -+ BIO_puts(bio_err, ""); -+ goto done; -+ } -+ X509_ALGOR_get0(&aoid, &aparamtype, &aparam, pbe2->keyfunc); -+ pbenid = OBJ_obj2nid(aoid); -+ X509_ALGOR_get0(&aoid, NULL, NULL, pbe2->encryption); -+ encnid = OBJ_obj2nid(aoid); -+ BIO_printf(bio_err, ", %s, %s", OBJ_nid2ln(pbenid), -+ OBJ_nid2sn(encnid)); -+ /* If KDF is PBKDF2 decode parameters */ -+ if (pbenid == NID_id_pbkdf2) { -+ PBKDF2PARAM *kdf = NULL; -+ int prfnid; -+ if (aparamtype == V_ASN1_SEQUENCE) -+ kdf = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBKDF2PARAM)); -+ if (kdf == NULL) { -+ BIO_puts(bio_err, ""); -+ goto done; -+ } -+ -+ if (kdf->prf == NULL) { -+ prfnid = NID_hmacWithSHA1; -+ } else { -+ X509_ALGOR_get0(&aoid, NULL, NULL, kdf->prf); -+ prfnid = OBJ_obj2nid(aoid); -+ } -+ BIO_printf(bio_err, ", Iteration %ld, PRF %s", -+ ASN1_INTEGER_get(kdf->iter), OBJ_nid2sn(prfnid)); -+ PBKDF2PARAM_free(kdf); -+ } -+ PBE2PARAM_free(pbe2); -+ } else { -+ if (aparamtype == V_ASN1_SEQUENCE) -+ pbe = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBEPARAM)); -+ if (pbe == NULL) { -+ BIO_puts(bio_err, ""); -+ goto done; -+ } -+ BIO_printf(bio_err, ", Iteration %ld", ASN1_INTEGER_get(pbe->iter)); -+ PBEPARAM_free(pbe); -+ } -+ done: -+ BIO_puts(bio_err, "\n"); -+ return 1; -+} -+ -+/* Load all certificates from a given file */ -+ -+int cert_load(BIO *in, STACK_OF(X509) *sk) -+{ -+ int ret; -+ X509 *cert; -+ ret = 0; -+ while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) { -+ ret = 1; -+ sk_X509_push(sk, cert); -+ } -+ if (ret) -+ ERR_clear_error(); -+ return ret; -+} -+ -+/* Generalised attribute print: handle PKCS#8 and bag attributes */ -+ -+int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, -+ const char *name) -+{ -+ X509_ATTRIBUTE *attr; -+ ASN1_TYPE *av; -+ char *value; -+ int i, attr_nid; -+ if (!attrlst) { -+ BIO_printf(out, "%s: \n", name); -+ return 1; -+ } -+ if (!sk_X509_ATTRIBUTE_num(attrlst)) { -+ BIO_printf(out, "%s: \n", name); -+ return 1; -+ } -+ BIO_printf(out, "%s\n", name); -+ for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { -+ ASN1_OBJECT *attr_obj; -+ attr = sk_X509_ATTRIBUTE_value(attrlst, i); -+ attr_obj = X509_ATTRIBUTE_get0_object(attr); -+ attr_nid = OBJ_obj2nid(attr_obj); -+ BIO_printf(out, " "); -+ if (attr_nid == NID_undef) { -+ i2a_ASN1_OBJECT(out, attr_obj); -+ BIO_printf(out, ": "); -+ } else -+ BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); -+ -+ if (X509_ATTRIBUTE_count(attr)) { -+ av = X509_ATTRIBUTE_get0_type(attr, 0); -+ switch (av->type) { -+ case V_ASN1_BMPSTRING: -+ value = OPENSSL_uni2asc(av->value.bmpstring->data, -+ av->value.bmpstring->length); -+ BIO_printf(out, "%s\n", value); -+ OPENSSL_free(value); -+ break; -+ -+ case V_ASN1_OCTET_STRING: -+ hex_prin(out, av->value.octet_string->data, -+ av->value.octet_string->length); -+ BIO_printf(out, "\n"); -+ break; -+ -+ case V_ASN1_BIT_STRING: -+ hex_prin(out, av->value.bit_string->data, -+ av->value.bit_string->length); -+ BIO_printf(out, "\n"); -+ break; -+ -+ default: -+ BIO_printf(out, "\n", av->type); -+ break; -+ } -+ } else -+ BIO_printf(out, "\n"); -+ } -+ return 1; -+} -+ -+void hex_prin(BIO *out, unsigned char *buf, int len) -+{ -+ int i; -+ for (i = 0; i < len; i++) -+ BIO_printf(out, "%02X ", buf[i]); -+} -+ -+static int set_pbe(int *ppbe, const char *str) -+{ -+ if (!str) -+ return 0; -+ if (strcmp(str, "NONE") == 0) { -+ *ppbe = -1; -+ return 1; -+ } -+ *ppbe = OBJ_txt2nid(str); -+ if (*ppbe == NID_undef) { -+ BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str); -+ return 0; -+ } -+ return 1; -+} -+ -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/pkcs7.c b/CryptoPkg/Library/OpensslLib/openssl/apps/pkcs7.c -new file mode 100644 -index 0000000..209e30d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/pkcs7.c -@@ -0,0 +1,197 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+#include -+#include -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOOUT, -+ OPT_TEXT, OPT_PRINT, OPT_PRINT_CERTS, OPT_ENGINE -+} OPTION_CHOICE; -+ -+OPTIONS pkcs7_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"noout", OPT_NOOUT, '-', "Don't output encoded data"}, -+ {"text", OPT_TEXT, '-', "Print full details of certificates"}, -+ {"print", OPT_PRINT, '-', "Print out all fields of the PKCS7 structure"}, -+ {"print_certs", OPT_PRINT_CERTS, '-', -+ "Print_certs print any certs or crl in the input"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+#endif -+ {NULL} -+}; -+ -+int pkcs7_main(int argc, char **argv) -+{ -+ ENGINE *e = NULL; -+ PKCS7 *p7 = NULL; -+ BIO *in = NULL, *out = NULL; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM; -+ char *infile = NULL, *outfile = NULL, *prog; -+ int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1; -+ OPTION_CHOICE o; -+ -+ prog = opt_init(argc, argv, pkcs7_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(pkcs7_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) -+ goto opthelp; -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_PRINT: -+ p7_print = 1; -+ break; -+ case OPT_PRINT_CERTS: -+ print_certs = 1; -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ in = bio_open_default(infile, 'r', informat); -+ if (in == NULL) -+ goto end; -+ -+ if (informat == FORMAT_ASN1) -+ p7 = d2i_PKCS7_bio(in, NULL); -+ else -+ p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); -+ if (p7 == NULL) { -+ BIO_printf(bio_err, "unable to load PKCS7 object\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ out = bio_open_default(outfile, 'w', outformat); -+ if (out == NULL) -+ goto end; -+ -+ if (p7_print) -+ PKCS7_print_ctx(out, p7, 0, NULL); -+ -+ if (print_certs) { -+ STACK_OF(X509) *certs = NULL; -+ STACK_OF(X509_CRL) *crls = NULL; -+ -+ i = OBJ_obj2nid(p7->type); -+ switch (i) { -+ case NID_pkcs7_signed: -+ if (p7->d.sign != NULL) { -+ certs = p7->d.sign->cert; -+ crls = p7->d.sign->crl; -+ } -+ break; -+ case NID_pkcs7_signedAndEnveloped: -+ if (p7->d.signed_and_enveloped != NULL) { -+ certs = p7->d.signed_and_enveloped->cert; -+ crls = p7->d.signed_and_enveloped->crl; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ if (certs != NULL) { -+ X509 *x; -+ -+ for (i = 0; i < sk_X509_num(certs); i++) { -+ x = sk_X509_value(certs, i); -+ if (text) -+ X509_print(out, x); -+ else -+ dump_cert_text(out, x); -+ -+ if (!noout) -+ PEM_write_bio_X509(out, x); -+ BIO_puts(out, "\n"); -+ } -+ } -+ if (crls != NULL) { -+ X509_CRL *crl; -+ -+ for (i = 0; i < sk_X509_CRL_num(crls); i++) { -+ crl = sk_X509_CRL_value(crls, i); -+ -+ X509_CRL_print(out, crl); -+ -+ if (!noout) -+ PEM_write_bio_X509_CRL(out, crl); -+ BIO_puts(out, "\n"); -+ } -+ } -+ -+ ret = 0; -+ goto end; -+ } -+ -+ if (!noout) { -+ if (outformat == FORMAT_ASN1) -+ i = i2d_PKCS7_bio(out, p7); -+ else -+ i = PEM_write_bio_PKCS7(out, p7); -+ -+ if (!i) { -+ BIO_printf(bio_err, "unable to write pkcs7 object\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ ret = 0; -+ end: -+ PKCS7_free(p7); -+ release_engine(e); -+ BIO_free(in); -+ BIO_free_all(out); -+ return (ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/pkcs8.c b/CryptoPkg/Library/OpensslLib/openssl/apps/pkcs8.c -new file mode 100644 -index 0000000..93ffdd5 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/pkcs8.c -@@ -0,0 +1,353 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, -+ OPT_TOPK8, OPT_NOITER, OPT_NOCRYPT, -+#ifndef OPENSSL_NO_SCRYPT -+ OPT_SCRYPT, OPT_SCRYPT_N, OPT_SCRYPT_R, OPT_SCRYPT_P, -+#endif -+ OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT, -+ OPT_TRADITIONAL -+} OPTION_CHOICE; -+ -+OPTIONS pkcs8_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'F', "Input format (DER or PEM)"}, -+ {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"topk8", OPT_TOPK8, '-', "Output PKCS8 file"}, -+ {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"}, -+ {"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"}, -+ {"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"}, -+ {"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"}, -+ {"v2prf", OPT_V2PRF, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"}, -+ {"iter", OPT_ITER, 'p', "Specify the iteration count"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+ {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, -+ {"traditional", OPT_TRADITIONAL, '-', "use traditional format private key"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+#endif -+#ifndef OPENSSL_NO_SCRYPT -+ {"scrypt", OPT_SCRYPT, '-', "Use scrypt algorithm"}, -+ {"scrypt_N", OPT_SCRYPT_N, 's', "Set scrypt N parameter"}, -+ {"scrypt_r", OPT_SCRYPT_R, 's', "Set scrypt r parameter"}, -+ {"scrypt_p", OPT_SCRYPT_P, 's', "Set scrypt p parameter"}, -+#endif -+ {NULL} -+}; -+ -+int pkcs8_main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ ENGINE *e = NULL; -+ EVP_PKEY *pkey = NULL; -+ PKCS8_PRIV_KEY_INFO *p8inf = NULL; -+ X509_SIG *p8 = NULL; -+ const EVP_CIPHER *cipher = NULL; -+ char *infile = NULL, *outfile = NULL; -+ char *passinarg = NULL, *passoutarg = NULL, *prog; -+#ifndef OPENSSL_NO_UI -+ char pass[50]; -+#endif -+ char *passin = NULL, *passout = NULL, *p8pass = NULL; -+ OPTION_CHOICE o; -+ int nocrypt = 0, ret = 1, iter = PKCS12_DEFAULT_ITER; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM, topk8 = 0, pbe_nid = -1; -+ int private = 0, traditional = 0; -+#ifndef OPENSSL_NO_SCRYPT -+ long scrypt_N = 0, scrypt_r = 0, scrypt_p = 0; -+#endif -+ -+ prog = opt_init(argc, argv, pkcs8_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(pkcs8_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_TOPK8: -+ topk8 = 1; -+ break; -+ case OPT_NOITER: -+ iter = 1; -+ break; -+ case OPT_NOCRYPT: -+ nocrypt = 1; -+ break; -+ case OPT_TRADITIONAL: -+ traditional = 1; -+ break; -+ case OPT_V2: -+ if (!opt_cipher(opt_arg(), &cipher)) -+ goto opthelp; -+ break; -+ case OPT_V1: -+ pbe_nid = OBJ_txt2nid(opt_arg()); -+ if (pbe_nid == NID_undef) { -+ BIO_printf(bio_err, -+ "%s: Unknown PBE algorithm %s\n", prog, opt_arg()); -+ goto opthelp; -+ } -+ break; -+ case OPT_V2PRF: -+ pbe_nid = OBJ_txt2nid(opt_arg()); -+ if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) { -+ BIO_printf(bio_err, -+ "%s: Unknown PRF algorithm %s\n", prog, opt_arg()); -+ goto opthelp; -+ } -+ if (cipher == NULL) -+ cipher = EVP_aes_256_cbc(); -+ break; -+ case OPT_ITER: -+ if (!opt_int(opt_arg(), &iter)) -+ goto opthelp; -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ case OPT_PASSOUT: -+ passoutarg = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+#ifndef OPENSSL_NO_SCRYPT -+ case OPT_SCRYPT: -+ scrypt_N = 16384; -+ scrypt_r = 8; -+ scrypt_p = 1; -+ if (cipher == NULL) -+ cipher = EVP_aes_256_cbc(); -+ break; -+ case OPT_SCRYPT_N: -+ if (!opt_long(opt_arg(), &scrypt_N) || scrypt_N <= 0) -+ goto opthelp; -+ break; -+ case OPT_SCRYPT_R: -+ if (!opt_long(opt_arg(), &scrypt_r) || scrypt_r <= 0) -+ goto opthelp; -+ break; -+ case OPT_SCRYPT_P: -+ if (!opt_long(opt_arg(), &scrypt_p) || scrypt_p <= 0) -+ goto opthelp; -+ break; -+#endif -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ private = 1; -+ -+ if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { -+ BIO_printf(bio_err, "Error getting passwords\n"); -+ goto end; -+ } -+ -+ if ((pbe_nid == -1) && cipher == NULL) -+ cipher = EVP_aes_256_cbc(); -+ -+ in = bio_open_default(infile, 'r', informat); -+ if (in == NULL) -+ goto end; -+ out = bio_open_owner(outfile, outformat, private); -+ if (out == NULL) -+ goto end; -+ -+ if (topk8) { -+ pkey = load_key(infile, informat, 1, passin, e, "key"); -+ if (!pkey) -+ goto end; -+ if ((p8inf = EVP_PKEY2PKCS8(pkey)) == NULL) { -+ BIO_printf(bio_err, "Error converting key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (nocrypt) { -+ assert(private); -+ if (outformat == FORMAT_PEM) -+ PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); -+ else if (outformat == FORMAT_ASN1) -+ i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf); -+ else { -+ BIO_printf(bio_err, "Bad format specified for key\n"); -+ goto end; -+ } -+ } else { -+ X509_ALGOR *pbe; -+ if (cipher) { -+#ifndef OPENSSL_NO_SCRYPT -+ if (scrypt_N && scrypt_r && scrypt_p) -+ pbe = PKCS5_pbe2_set_scrypt(cipher, NULL, 0, NULL, -+ scrypt_N, scrypt_r, scrypt_p); -+ else -+#endif -+ pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL, -+ pbe_nid); -+ } else { -+ pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, 0); -+ } -+ if (pbe == NULL) { -+ BIO_printf(bio_err, "Error setting PBE algorithm\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (passout) -+ p8pass = passout; -+ else if (1) { -+#ifndef OPENSSL_NO_UI -+ p8pass = pass; -+ if (EVP_read_pw_string -+ (pass, sizeof pass, "Enter Encryption Password:", 1)) { -+ X509_ALGOR_free(pbe); -+ goto end; -+ } -+ } else { -+#endif -+ BIO_printf(bio_err, "Password required\n"); -+ goto end; -+ } -+ app_RAND_load_file(NULL, 0); -+ p8 = PKCS8_set0_pbe(p8pass, strlen(p8pass), p8inf, pbe); -+ if (p8 == NULL) { -+ X509_ALGOR_free(pbe); -+ BIO_printf(bio_err, "Error encrypting key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ app_RAND_write_file(NULL); -+ assert(private); -+ if (outformat == FORMAT_PEM) -+ PEM_write_bio_PKCS8(out, p8); -+ else if (outformat == FORMAT_ASN1) -+ i2d_PKCS8_bio(out, p8); -+ else { -+ BIO_printf(bio_err, "Bad format specified for key\n"); -+ goto end; -+ } -+ } -+ -+ ret = 0; -+ goto end; -+ } -+ -+ if (nocrypt) { -+ if (informat == FORMAT_PEM) -+ p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL, NULL, NULL); -+ else if (informat == FORMAT_ASN1) -+ p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); -+ else { -+ BIO_printf(bio_err, "Bad format specified for key\n"); -+ goto end; -+ } -+ } else { -+ if (informat == FORMAT_PEM) -+ p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); -+ else if (informat == FORMAT_ASN1) -+ p8 = d2i_PKCS8_bio(in, NULL); -+ else { -+ BIO_printf(bio_err, "Bad format specified for key\n"); -+ goto end; -+ } -+ -+ if (!p8) { -+ BIO_printf(bio_err, "Error reading key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (passin) -+ p8pass = passin; -+ else if (1) { -+#ifndef OPENSSL_NO_UI -+ p8pass = pass; -+ if (EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0)) { -+ BIO_printf(bio_err, "Can't read Password\n"); -+ goto end; -+ } -+ } else { -+#endif -+ BIO_printf(bio_err, "Password required\n"); -+ goto end; -+ } -+ p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass)); -+ } -+ -+ if (!p8inf) { -+ BIO_printf(bio_err, "Error decrypting key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if ((pkey = EVP_PKCS82PKEY(p8inf)) == NULL) { -+ BIO_printf(bio_err, "Error converting key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ assert(private); -+ if (outformat == FORMAT_PEM) { -+ if (traditional) -+ PEM_write_bio_PrivateKey_traditional(out, pkey, NULL, NULL, 0, -+ NULL, passout); -+ else -+ PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout); -+ } else if (outformat == FORMAT_ASN1) { -+ i2d_PrivateKey_bio(out, pkey); -+ } else { -+ BIO_printf(bio_err, "Bad format specified for key\n"); -+ goto end; -+ } -+ ret = 0; -+ -+ end: -+ X509_SIG_free(p8); -+ PKCS8_PRIV_KEY_INFO_free(p8inf); -+ EVP_PKEY_free(pkey); -+ release_engine(e); -+ BIO_free_all(out); -+ BIO_free(in); -+ OPENSSL_free(passin); -+ OPENSSL_free(passout); -+ -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/pkey.c b/CryptoPkg/Library/OpensslLib/openssl/apps/pkey.c -new file mode 100644 -index 0000000..ad1a3b1 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/pkey.c -@@ -0,0 +1,190 @@ -+/* -+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE, -+ OPT_IN, OPT_OUT, OPT_PUBIN, OPT_PUBOUT, OPT_TEXT_PUB, -+ OPT_TEXT, OPT_NOOUT, OPT_MD, OPT_TRADITIONAL -+} OPTION_CHOICE; -+ -+OPTIONS pkey_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'f', "Input format (DER or PEM)"}, -+ {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+ {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, -+ {"in", OPT_IN, 's', "Input key"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"pubin", OPT_PUBIN, '-', -+ "Read public key from input (default is private key)"}, -+ {"pubout", OPT_PUBOUT, '-', "Output public key, not private"}, -+ {"text_pub", OPT_TEXT_PUB, '-', "Only output public key components"}, -+ {"text", OPT_TEXT, '-', "Output in plaintext as well"}, -+ {"noout", OPT_NOOUT, '-', "Don't output the key"}, -+ {"", OPT_MD, '-', "Any supported cipher"}, -+ {"traditional", OPT_TRADITIONAL, '-', -+ "Use traditional format for private keys"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+#endif -+ {NULL} -+}; -+ -+int pkey_main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ ENGINE *e = NULL; -+ EVP_PKEY *pkey = NULL; -+ const EVP_CIPHER *cipher = NULL; -+ char *infile = NULL, *outfile = NULL, *passin = NULL, *passout = NULL; -+ char *passinarg = NULL, *passoutarg = NULL, *prog; -+ OPTION_CHOICE o; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM; -+ int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0, ret = 1; -+ int private = 0, traditional = 0; -+ -+ prog = opt_init(argc, argv, pkey_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(pkey_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) -+ goto opthelp; -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ case OPT_PASSOUT: -+ passoutarg = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_PUBIN: -+ pubin = pubout = pubtext = 1; -+ break; -+ case OPT_PUBOUT: -+ pubout = 1; -+ break; -+ case OPT_TEXT_PUB: -+ pubtext = text = 1; -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ case OPT_TRADITIONAL: -+ traditional = 1; -+ break; -+ case OPT_MD: -+ if (!opt_cipher(opt_unknown(), &cipher)) -+ goto opthelp; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ private = !noout && !pubout ? 1 : 0; -+ if (text && !pubtext) -+ private = 1; -+ -+ if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { -+ BIO_printf(bio_err, "Error getting passwords\n"); -+ goto end; -+ } -+ -+ out = bio_open_owner(outfile, outformat, private); -+ if (out == NULL) -+ goto end; -+ -+ if (pubin) -+ pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key"); -+ else -+ pkey = load_key(infile, informat, 1, passin, e, "key"); -+ if (!pkey) -+ goto end; -+ -+ if (!noout) { -+ if (outformat == FORMAT_PEM) { -+ if (pubout) -+ PEM_write_bio_PUBKEY(out, pkey); -+ else { -+ assert(private); -+ if (traditional) -+ PEM_write_bio_PrivateKey_traditional(out, pkey, cipher, -+ NULL, 0, NULL, -+ passout); -+ else -+ PEM_write_bio_PrivateKey(out, pkey, cipher, -+ NULL, 0, NULL, passout); -+ } -+ } else if (outformat == FORMAT_ASN1) { -+ if (pubout) -+ i2d_PUBKEY_bio(out, pkey); -+ else { -+ assert(private); -+ i2d_PrivateKey_bio(out, pkey); -+ } -+ } else { -+ BIO_printf(bio_err, "Bad format specified for key\n"); -+ goto end; -+ } -+ -+ } -+ -+ if (text) { -+ if (pubtext) -+ EVP_PKEY_print_public(out, pkey, 0, NULL); -+ else { -+ assert(private); -+ EVP_PKEY_print_private(out, pkey, 0, NULL); -+ } -+ } -+ -+ ret = 0; -+ -+ end: -+ EVP_PKEY_free(pkey); -+ release_engine(e); -+ BIO_free_all(out); -+ BIO_free(in); -+ OPENSSL_free(passin); -+ OPENSSL_free(passout); -+ -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/pkeyparam.c b/CryptoPkg/Library/OpensslLib/openssl/apps/pkeyparam.c -new file mode 100644 -index 0000000..0a1b2d1 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/pkeyparam.c -@@ -0,0 +1,104 @@ -+/* -+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_IN, OPT_OUT, OPT_TEXT, OPT_NOOUT, OPT_ENGINE -+} OPTION_CHOICE; -+ -+OPTIONS pkeyparam_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"text", OPT_TEXT, '-', "Print parameters as text"}, -+ {"noout", OPT_NOOUT, '-', "Don't output encoded parameters"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+#endif -+ {NULL} -+}; -+ -+int pkeyparam_main(int argc, char **argv) -+{ -+ ENGINE *e = NULL; -+ BIO *in = NULL, *out = NULL; -+ EVP_PKEY *pkey = NULL; -+ int text = 0, noout = 0, ret = 1; -+ OPTION_CHOICE o; -+ char *infile = NULL, *outfile = NULL, *prog; -+ -+ prog = opt_init(argc, argv, pkeyparam_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(pkeyparam_options); -+ ret = 0; -+ goto end; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ in = bio_open_default(infile, 'r', FORMAT_PEM); -+ if (in == NULL) -+ goto end; -+ out = bio_open_default(outfile, 'w', FORMAT_PEM); -+ if (out == NULL) -+ goto end; -+ pkey = PEM_read_bio_Parameters(in, NULL); -+ if (!pkey) { -+ BIO_printf(bio_err, "Error reading parameters\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (!noout) -+ PEM_write_bio_Parameters(out, pkey); -+ -+ if (text) -+ EVP_PKEY_print_params(out, pkey, 0, NULL); -+ -+ ret = 0; -+ -+ end: -+ EVP_PKEY_free(pkey); -+ release_engine(e); -+ BIO_free_all(out); -+ BIO_free(in); -+ -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/pkeyutl.c b/CryptoPkg/Library/OpensslLib/openssl/apps/pkeyutl.c -new file mode 100644 -index 0000000..962a389 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/pkeyutl.c -@@ -0,0 +1,489 @@ -+/* -+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "apps.h" -+#include -+#include -+#include -+#include -+ -+#define KEY_NONE 0 -+#define KEY_PRIVKEY 1 -+#define KEY_PUBKEY 2 -+#define KEY_CERT 3 -+ -+static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, -+ const char *keyfile, int keyform, int key_type, -+ char *passinarg, int pkey_op, ENGINE *e, -+ const int impl); -+ -+static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, -+ ENGINE *e); -+ -+static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, -+ unsigned char *out, size_t *poutlen, -+ const unsigned char *in, size_t inlen); -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_ENGINE, OPT_ENGINE_IMPL, OPT_IN, OPT_OUT, -+ OPT_PUBIN, OPT_CERTIN, OPT_ASN1PARSE, OPT_HEXDUMP, OPT_SIGN, -+ OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT, -+ OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN, -+ OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN -+} OPTION_CHOICE; -+ -+OPTIONS pkeyutl_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"in", OPT_IN, '<', "Input file - default stdin"}, -+ {"out", OPT_OUT, '>', "Output file - default stdout"}, -+ {"pubin", OPT_PUBIN, '-', "Input is a public key"}, -+ {"certin", OPT_CERTIN, '-', "Input is a cert with a public key"}, -+ {"asn1parse", OPT_ASN1PARSE, '-', "asn1parse the output data"}, -+ {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, -+ {"sign", OPT_SIGN, '-', "Sign input data with private key"}, -+ {"verify", OPT_VERIFY, '-', "Verify with public key"}, -+ {"verifyrecover", OPT_VERIFYRECOVER, '-', -+ "Verify with public key, recover original data"}, -+ {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, -+ {"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"}, -+ {"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"}, -+ {"derive", OPT_DERIVE, '-', "Derive shared secret"}, -+ {"kdf", OPT_KDF, 's', "Use KDF algorithm"}, -+ {"kdflen", OPT_KDFLEN, 'p', "KDF algorithm output length"}, -+ {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"}, -+ {"inkey", OPT_INKEY, 's', "Input private key file"}, -+ {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+ {"peerform", OPT_PEERFORM, 'E', "Peer key format - default PEM"}, -+ {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"}, -+ {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+ {"engine_impl", OPT_ENGINE_IMPL, '-', -+ "Also use engine given by -engine for crypto operations"}, -+#endif -+ {NULL} -+}; -+ -+int pkeyutl_main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ ENGINE *e = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL; -+ char hexdump = 0, asn1parse = 0, rev = 0, *prog; -+ unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; -+ OPTION_CHOICE o; -+ int buf_inlen = 0, siglen = -1, keyform = FORMAT_PEM, peerform = -+ FORMAT_PEM; -+ int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; -+ int engine_impl = 0; -+ int ret = 1, rv = -1; -+ size_t buf_outlen; -+ const char *inkey = NULL; -+ const char *peerkey = NULL; -+ const char *kdfalg = NULL; -+ int kdflen = 0; -+ STACK_OF(OPENSSL_STRING) *pkeyopts = NULL; -+ -+ prog = opt_init(argc, argv, pkeyutl_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(pkeyutl_options); -+ ret = 0; -+ goto end; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_SIGFILE: -+ sigfile = opt_arg(); -+ break; -+ case OPT_ENGINE_IMPL: -+ engine_impl = 1; -+ break; -+ case OPT_INKEY: -+ inkey = opt_arg(); -+ break; -+ case OPT_PEERKEY: -+ peerkey = opt_arg(); -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ case OPT_PEERFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PDE, &peerform)) -+ goto opthelp; -+ break; -+ case OPT_KEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyform)) -+ goto opthelp; -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_PUBIN: -+ key_type = KEY_PUBKEY; -+ break; -+ case OPT_CERTIN: -+ key_type = KEY_CERT; -+ break; -+ case OPT_ASN1PARSE: -+ asn1parse = 1; -+ break; -+ case OPT_HEXDUMP: -+ hexdump = 1; -+ break; -+ case OPT_SIGN: -+ pkey_op = EVP_PKEY_OP_SIGN; -+ break; -+ case OPT_VERIFY: -+ pkey_op = EVP_PKEY_OP_VERIFY; -+ break; -+ case OPT_VERIFYRECOVER: -+ pkey_op = EVP_PKEY_OP_VERIFYRECOVER; -+ break; -+ case OPT_ENCRYPT: -+ pkey_op = EVP_PKEY_OP_ENCRYPT; -+ break; -+ case OPT_DECRYPT: -+ pkey_op = EVP_PKEY_OP_DECRYPT; -+ break; -+ case OPT_DERIVE: -+ pkey_op = EVP_PKEY_OP_DERIVE; -+ break; -+ case OPT_KDF: -+ pkey_op = EVP_PKEY_OP_DERIVE; -+ key_type = KEY_NONE; -+ kdfalg = opt_arg(); -+ break; -+ case OPT_KDFLEN: -+ kdflen = atoi(opt_arg()); -+ break; -+ case OPT_REV: -+ rev = 1; -+ break; -+ case OPT_PKEYOPT: -+ if ((pkeyopts == NULL && -+ (pkeyopts = sk_OPENSSL_STRING_new_null()) == NULL) || -+ sk_OPENSSL_STRING_push(pkeyopts, opt_arg()) == 0) { -+ BIO_puts(bio_err, "out of memory\n"); -+ goto end; -+ } -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ if (kdfalg != NULL) { -+ if (kdflen == 0) -+ goto opthelp; -+ } else if ((inkey == NULL) -+ || (peerkey != NULL && pkey_op != EVP_PKEY_OP_DERIVE)) { -+ goto opthelp; -+ } -+ ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type, -+ passinarg, pkey_op, e, engine_impl); -+ if (ctx == NULL) { -+ BIO_printf(bio_err, "%s: Error initializing context\n", prog); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (peerkey != NULL && !setup_peer(ctx, peerform, peerkey, e)) { -+ BIO_printf(bio_err, "%s: Error setting up peer key\n", prog); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (pkeyopts != NULL) { -+ int num = sk_OPENSSL_STRING_num(pkeyopts); -+ int i; -+ -+ for (i = 0; i < num; ++i) { -+ const char *opt = sk_OPENSSL_STRING_value(pkeyopts, i); -+ -+ if (pkey_ctrl_string(ctx, opt) <= 0) { -+ BIO_printf(bio_err, "%s: Can't set parameter:\n", prog); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ } -+ -+ if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) { -+ BIO_printf(bio_err, -+ "%s: Signature file specified for non verify\n", prog); -+ goto end; -+ } -+ -+ if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) { -+ BIO_printf(bio_err, -+ "%s: No signature file specified for verify\n", prog); -+ goto end; -+ } -+ -+/* FIXME: seed PRNG only if needed */ -+ app_RAND_load_file(NULL, 0); -+ -+ if (pkey_op != EVP_PKEY_OP_DERIVE) { -+ in = bio_open_default(infile, 'r', FORMAT_BINARY); -+ if (in == NULL) -+ goto end; -+ } -+ out = bio_open_default(outfile, 'w', FORMAT_BINARY); -+ if (out == NULL) -+ goto end; -+ -+ if (sigfile) { -+ BIO *sigbio = BIO_new_file(sigfile, "rb"); -+ if (!sigbio) { -+ BIO_printf(bio_err, "Can't open signature file %s\n", sigfile); -+ goto end; -+ } -+ siglen = bio_to_mem(&sig, keysize * 10, sigbio); -+ BIO_free(sigbio); -+ if (siglen < 0) { -+ BIO_printf(bio_err, "Error reading signature data\n"); -+ goto end; -+ } -+ } -+ -+ if (in) { -+ /* Read the input data */ -+ buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); -+ if (buf_inlen < 0) { -+ BIO_printf(bio_err, "Error reading input Data\n"); -+ exit(1); -+ } -+ if (rev) { -+ size_t i; -+ unsigned char ctmp; -+ size_t l = (size_t)buf_inlen; -+ for (i = 0; i < l / 2; i++) { -+ ctmp = buf_in[i]; -+ buf_in[i] = buf_in[l - 1 - i]; -+ buf_in[l - 1 - i] = ctmp; -+ } -+ } -+ } -+ -+ if (pkey_op == EVP_PKEY_OP_VERIFY) { -+ rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, -+ buf_in, (size_t)buf_inlen); -+ if (rv == 1) { -+ BIO_puts(out, "Signature Verified Successfully\n"); -+ ret = 0; -+ } else -+ BIO_puts(out, "Signature Verification Failure\n"); -+ goto end; -+ } -+ if (kdflen != 0) { -+ buf_outlen = kdflen; -+ rv = 1; -+ } else { -+ rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, -+ buf_in, (size_t)buf_inlen); -+ } -+ if (rv > 0 && buf_outlen != 0) { -+ buf_out = app_malloc(buf_outlen, "buffer output"); -+ rv = do_keyop(ctx, pkey_op, -+ buf_out, (size_t *)&buf_outlen, -+ buf_in, (size_t)buf_inlen); -+ } -+ if (rv <= 0) { -+ BIO_puts(bio_err, "Public Key operation error\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ ret = 0; -+ -+ if (asn1parse) { -+ if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) -+ ERR_print_errors(bio_err); -+ } else if (hexdump) -+ BIO_dump(out, (char *)buf_out, buf_outlen); -+ else -+ BIO_write(out, buf_out, buf_outlen); -+ -+ end: -+ EVP_PKEY_CTX_free(ctx); -+ release_engine(e); -+ BIO_free(in); -+ BIO_free_all(out); -+ OPENSSL_free(buf_in); -+ OPENSSL_free(buf_out); -+ OPENSSL_free(sig); -+ sk_OPENSSL_STRING_free(pkeyopts); -+ return ret; -+} -+ -+static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, -+ const char *keyfile, int keyform, int key_type, -+ char *passinarg, int pkey_op, ENGINE *e, -+ const int engine_impl) -+{ -+ EVP_PKEY *pkey = NULL; -+ EVP_PKEY_CTX *ctx = NULL; -+ ENGINE *impl = NULL; -+ char *passin = NULL; -+ int rv = -1; -+ X509 *x; -+ if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) -+ || (pkey_op == EVP_PKEY_OP_DERIVE)) -+ && (key_type != KEY_PRIVKEY && kdfalg == NULL)) { -+ BIO_printf(bio_err, "A private key is needed for this operation\n"); -+ goto end; -+ } -+ if (!app_passwd(passinarg, NULL, &passin, NULL)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ switch (key_type) { -+ case KEY_PRIVKEY: -+ pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key"); -+ break; -+ -+ case KEY_PUBKEY: -+ pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "Public Key"); -+ break; -+ -+ case KEY_CERT: -+ x = load_cert(keyfile, keyform, "Certificate"); -+ if (x) { -+ pkey = X509_get_pubkey(x); -+ X509_free(x); -+ } -+ break; -+ -+ case KEY_NONE: -+ break; -+ -+ } -+ -+#ifndef OPENSSL_NO_ENGINE -+ if (engine_impl) -+ impl = e; -+#endif -+ -+ if (kdfalg) { -+ int kdfnid = OBJ_sn2nid(kdfalg); -+ if (kdfnid == NID_undef) -+ goto end; -+ ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); -+ } else { -+ if (pkey == NULL) -+ goto end; -+ *pkeysize = EVP_PKEY_size(pkey); -+ ctx = EVP_PKEY_CTX_new(pkey, impl); -+ EVP_PKEY_free(pkey); -+ } -+ -+ if (ctx == NULL) -+ goto end; -+ -+ switch (pkey_op) { -+ case EVP_PKEY_OP_SIGN: -+ rv = EVP_PKEY_sign_init(ctx); -+ break; -+ -+ case EVP_PKEY_OP_VERIFY: -+ rv = EVP_PKEY_verify_init(ctx); -+ break; -+ -+ case EVP_PKEY_OP_VERIFYRECOVER: -+ rv = EVP_PKEY_verify_recover_init(ctx); -+ break; -+ -+ case EVP_PKEY_OP_ENCRYPT: -+ rv = EVP_PKEY_encrypt_init(ctx); -+ break; -+ -+ case EVP_PKEY_OP_DECRYPT: -+ rv = EVP_PKEY_decrypt_init(ctx); -+ break; -+ -+ case EVP_PKEY_OP_DERIVE: -+ rv = EVP_PKEY_derive_init(ctx); -+ break; -+ } -+ -+ if (rv <= 0) { -+ EVP_PKEY_CTX_free(ctx); -+ ctx = NULL; -+ } -+ -+ end: -+ OPENSSL_free(passin); -+ return ctx; -+ -+} -+ -+static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, -+ ENGINE* e) -+{ -+ EVP_PKEY *peer = NULL; -+ ENGINE* engine = NULL; -+ int ret; -+ -+ if (peerform == FORMAT_ENGINE) -+ engine = e; -+ peer = load_pubkey(file, peerform, 0, NULL, engine, "Peer Key"); -+ if (!peer) { -+ BIO_printf(bio_err, "Error reading peer key %s\n", file); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ -+ ret = EVP_PKEY_derive_set_peer(ctx, peer); -+ -+ EVP_PKEY_free(peer); -+ if (ret <= 0) -+ ERR_print_errors(bio_err); -+ return ret; -+} -+ -+static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, -+ unsigned char *out, size_t *poutlen, -+ const unsigned char *in, size_t inlen) -+{ -+ int rv = 0; -+ switch (pkey_op) { -+ case EVP_PKEY_OP_VERIFYRECOVER: -+ rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen); -+ break; -+ -+ case EVP_PKEY_OP_SIGN: -+ rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen); -+ break; -+ -+ case EVP_PKEY_OP_ENCRYPT: -+ rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen); -+ break; -+ -+ case EVP_PKEY_OP_DECRYPT: -+ rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen); -+ break; -+ -+ case EVP_PKEY_OP_DERIVE: -+ rv = EVP_PKEY_derive(ctx, out, poutlen); -+ break; -+ -+ } -+ return rv; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/prime.c b/CryptoPkg/Library/OpensslLib/openssl/apps/prime.c -new file mode 100644 -index 0000000..b0f5969 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/prime.c -@@ -0,0 +1,126 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+ -+#include "apps.h" -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_HEX, OPT_GENERATE, OPT_BITS, OPT_SAFE, OPT_CHECKS -+} OPTION_CHOICE; -+ -+OPTIONS prime_options[] = { -+ {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"}, -+ {OPT_HELP_STR, 1, '-', -+ " number Number to check for primality\n"}, -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"hex", OPT_HEX, '-', "Hex output"}, -+ {"generate", OPT_GENERATE, '-', "Generate a prime"}, -+ {"bits", OPT_BITS, 'p', "Size of number in bits"}, -+ {"safe", OPT_SAFE, '-', -+ "When used with -generate, generate a safe prime"}, -+ {"checks", OPT_CHECKS, 'p', "Number of checks"}, -+ {NULL} -+}; -+ -+int prime_main(int argc, char **argv) -+{ -+ BIGNUM *bn = NULL; -+ int hex = 0, checks = 20, generate = 0, bits = 0, safe = 0, ret = 1; -+ char *prog; -+ OPTION_CHOICE o; -+ -+ prog = opt_init(argc, argv, prime_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(prime_options); -+ ret = 0; -+ goto end; -+ case OPT_HEX: -+ hex = 1; -+ break; -+ case OPT_GENERATE: -+ generate = 1; -+ break; -+ case OPT_BITS: -+ bits = atoi(opt_arg()); -+ break; -+ case OPT_SAFE: -+ safe = 1; -+ break; -+ case OPT_CHECKS: -+ checks = atoi(opt_arg()); -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ -+ if (argc == 0 && !generate) { -+ BIO_printf(bio_err, "%s: No prime specified\n", prog); -+ goto end; -+ } -+ -+ if (generate) { -+ char *s; -+ -+ if (!bits) { -+ BIO_printf(bio_err, "Specify the number of bits.\n"); -+ goto end; -+ } -+ bn = BN_new(); -+ if (bn == NULL) { -+ BIO_printf(bio_err, "Out of memory.\n"); -+ goto end; -+ } -+ if (!BN_generate_prime_ex(bn, bits, safe, NULL, NULL, NULL)) { -+ BIO_printf(bio_err, "Failed to generate prime.\n"); -+ goto end; -+ } -+ s = hex ? BN_bn2hex(bn) : BN_bn2dec(bn); -+ if (s == NULL) { -+ BIO_printf(bio_err, "Out of memory.\n"); -+ goto end; -+ } -+ BIO_printf(bio_out, "%s\n", s); -+ OPENSSL_free(s); -+ } else { -+ for ( ; *argv; argv++) { -+ int r; -+ -+ if (hex) -+ r = BN_hex2bn(&bn, argv[0]); -+ else -+ r = BN_dec2bn(&bn, argv[0]); -+ -+ if(!r) { -+ BIO_printf(bio_err, "Failed to process value (%s)\n", argv[0]); -+ goto end; -+ } -+ -+ BN_print(bio_out, bn); -+ BIO_printf(bio_out, " (%s) %s prime\n", -+ argv[0], -+ BN_is_prime_ex(bn, checks, NULL, NULL) -+ ? "is" : "is not"); -+ } -+ } -+ -+ ret = 0; -+ end: -+ BN_free(bn); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/privkey.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/privkey.pem -new file mode 100644 -index 0000000..02f3498 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/privkey.pem -@@ -0,0 +1,16 @@ -+-----BEGIN PRIVATE KEY----- -+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMo7DFNMqywUA1O/ -+qvWqCOm6rGrUAcR+dKsSXw6y2qiKO7APDDyotc0b4Mxwqjga98npex2RBIwUoCGJ -+iEmMXo/a8RbXVUZ+ZwcAX7PC+XeXVC5qoajaBBkd2MvYmib/2PqnNrgvhHsUL5dO -+xhC7cRqxLM/g45k3Yyw+nGa+WkTdAgMBAAECgYBMBT5w4dVG0I8foGFnz+9hzWab -+Ee9IKjE5TcKmB93ilXQyjrWO5+zPmbc7ou6aAKk9IaPCTY1kCyzW7pho7Xdt+RFq -+TgVXGZZfqtixO7f2/5oqZAkd00eOn9ZrhBpVMu4yXbbDvhDyFe4/oy0HGDjRUhxa -+Lf6ZlBuTherxm4eFkQJBAPBQwRs9UtqaMAQlagA9pV5UsQjV1WT4IxDURMPfXgCd -+ETNkB6pP0SmxQm5xhv9N2HY1UtoWpug9s0OU5IJB15sCQQDXbfbjiujNbuOxCFNw -+68JZaCFVdNovyOWORkpenQLNEjVkmTCS9OayK09ADEYtsdpUGKeF+2EYBNkFr5px -+CajnAkBMYI4PNz1HBuwt1SpMa0tMoMQnV7bbwVV7usskKbC5pzHZUHhzM6z5gEHp -+0iEisT4Ty7zKXZqsgzefSgoaMAzzAkEAoCIaUhtwXzwdPfvNYnOs3J6doJMimECB -++lbfcyLM8TimvadtRt+KGEg/OYGmLNM2UiqdY+duzdbUpvhYGcwvYwJAQvaoi9z2 -+CkiwSs/PFrLaNlfLJmXRsUBzmiWYoh6+IQJJorEXz7ewI72ee9RBO4s746cgUFwH -+Ri+qO+HhZFUBqQ== -+-----END PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/progs.h b/CryptoPkg/Library/OpensslLib/openssl/apps/progs.h -new file mode 100644 -index 0000000..72d93ba ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/progs.h -@@ -0,0 +1,415 @@ -+/* -+ * WARNING: do not edit! -+ * Generated by apps/progs.pl -+ * -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+typedef enum FUNC_TYPE { -+ FT_none, FT_general, FT_md, FT_cipher, FT_pkey, -+ FT_md_alg, FT_cipher_alg -+} FUNC_TYPE; -+ -+typedef struct function_st { -+ FUNC_TYPE type; -+ const char *name; -+ int (*func)(int argc, char *argv[]); -+ const OPTIONS *help; -+} FUNCTION; -+ -+DEFINE_LHASH_OF(FUNCTION); -+ -+extern int asn1parse_main(int argc, char *argv[]); -+extern int ca_main(int argc, char *argv[]); -+extern int ciphers_main(int argc, char *argv[]); -+extern int cms_main(int argc, char *argv[]); -+extern int crl_main(int argc, char *argv[]); -+extern int crl2pkcs7_main(int argc, char *argv[]); -+extern int dgst_main(int argc, char *argv[]); -+extern int dhparam_main(int argc, char *argv[]); -+extern int dsa_main(int argc, char *argv[]); -+extern int dsaparam_main(int argc, char *argv[]); -+extern int ec_main(int argc, char *argv[]); -+extern int ecparam_main(int argc, char *argv[]); -+extern int enc_main(int argc, char *argv[]); -+extern int engine_main(int argc, char *argv[]); -+extern int errstr_main(int argc, char *argv[]); -+extern int exit_main(int argc, char *argv[]); -+extern int gendsa_main(int argc, char *argv[]); -+extern int genpkey_main(int argc, char *argv[]); -+extern int genrsa_main(int argc, char *argv[]); -+extern int help_main(int argc, char *argv[]); -+extern int list_main(int argc, char *argv[]); -+extern int nseq_main(int argc, char *argv[]); -+extern int ocsp_main(int argc, char *argv[]); -+extern int passwd_main(int argc, char *argv[]); -+extern int pkcs12_main(int argc, char *argv[]); -+extern int pkcs7_main(int argc, char *argv[]); -+extern int pkcs8_main(int argc, char *argv[]); -+extern int pkey_main(int argc, char *argv[]); -+extern int pkeyparam_main(int argc, char *argv[]); -+extern int pkeyutl_main(int argc, char *argv[]); -+extern int prime_main(int argc, char *argv[]); -+extern int rand_main(int argc, char *argv[]); -+extern int rehash_main(int argc, char *argv[]); -+extern int req_main(int argc, char *argv[]); -+extern int rsa_main(int argc, char *argv[]); -+extern int rsautl_main(int argc, char *argv[]); -+extern int s_client_main(int argc, char *argv[]); -+extern int s_server_main(int argc, char *argv[]); -+extern int s_time_main(int argc, char *argv[]); -+extern int sess_id_main(int argc, char *argv[]); -+extern int smime_main(int argc, char *argv[]); -+extern int speed_main(int argc, char *argv[]); -+extern int spkac_main(int argc, char *argv[]); -+extern int srp_main(int argc, char *argv[]); -+extern int ts_main(int argc, char *argv[]); -+extern int verify_main(int argc, char *argv[]); -+extern int version_main(int argc, char *argv[]); -+extern int x509_main(int argc, char *argv[]); -+ -+extern OPTIONS asn1parse_options[]; -+extern OPTIONS ca_options[]; -+extern OPTIONS ciphers_options[]; -+extern OPTIONS cms_options[]; -+extern OPTIONS crl_options[]; -+extern OPTIONS crl2pkcs7_options[]; -+extern OPTIONS dgst_options[]; -+extern OPTIONS dhparam_options[]; -+extern OPTIONS dsa_options[]; -+extern OPTIONS dsaparam_options[]; -+extern OPTIONS ec_options[]; -+extern OPTIONS ecparam_options[]; -+extern OPTIONS enc_options[]; -+extern OPTIONS engine_options[]; -+extern OPTIONS errstr_options[]; -+extern OPTIONS exit_options[]; -+extern OPTIONS gendsa_options[]; -+extern OPTIONS genpkey_options[]; -+extern OPTIONS genrsa_options[]; -+extern OPTIONS help_options[]; -+extern OPTIONS list_options[]; -+extern OPTIONS nseq_options[]; -+extern OPTIONS ocsp_options[]; -+extern OPTIONS passwd_options[]; -+extern OPTIONS pkcs12_options[]; -+extern OPTIONS pkcs7_options[]; -+extern OPTIONS pkcs8_options[]; -+extern OPTIONS pkey_options[]; -+extern OPTIONS pkeyparam_options[]; -+extern OPTIONS pkeyutl_options[]; -+extern OPTIONS prime_options[]; -+extern OPTIONS rand_options[]; -+extern OPTIONS rehash_options[]; -+extern OPTIONS req_options[]; -+extern OPTIONS rsa_options[]; -+extern OPTIONS rsautl_options[]; -+extern OPTIONS s_client_options[]; -+extern OPTIONS s_server_options[]; -+extern OPTIONS s_time_options[]; -+extern OPTIONS sess_id_options[]; -+extern OPTIONS smime_options[]; -+extern OPTIONS speed_options[]; -+extern OPTIONS spkac_options[]; -+extern OPTIONS srp_options[]; -+extern OPTIONS ts_options[]; -+extern OPTIONS verify_options[]; -+extern OPTIONS version_options[]; -+extern OPTIONS x509_options[]; -+ -+#ifdef INCLUDE_FUNCTION_TABLE -+static FUNCTION functions[] = { -+ { FT_general, "asn1parse", asn1parse_main, asn1parse_options }, -+ { FT_general, "ca", ca_main, ca_options }, -+#ifndef OPENSSL_NO_SOCK -+ { FT_general, "ciphers", ciphers_main, ciphers_options }, -+#endif -+#ifndef OPENSSL_NO_CMS -+ { FT_general, "cms", cms_main, cms_options }, -+#endif -+ { FT_general, "crl", crl_main, crl_options }, -+ { FT_general, "crl2pkcs7", crl2pkcs7_main, crl2pkcs7_options }, -+ { FT_general, "dgst", dgst_main, dgst_options }, -+#ifndef OPENSSL_NO_DH -+ { FT_general, "dhparam", dhparam_main, dhparam_options }, -+#endif -+#ifndef OPENSSL_NO_DSA -+ { FT_general, "dsa", dsa_main, dsa_options }, -+#endif -+#ifndef OPENSSL_NO_DSA -+ { FT_general, "dsaparam", dsaparam_main, dsaparam_options }, -+#endif -+#ifndef OPENSSL_NO_EC -+ { FT_general, "ec", ec_main, ec_options }, -+#endif -+#ifndef OPENSSL_NO_EC -+ { FT_general, "ecparam", ecparam_main, ecparam_options }, -+#endif -+ { FT_general, "enc", enc_main, enc_options }, -+#ifndef OPENSSL_NO_ENGINE -+ { FT_general, "engine", engine_main, engine_options }, -+#endif -+ { FT_general, "errstr", errstr_main, errstr_options }, -+ { FT_general, "exit", exit_main, exit_options }, -+#ifndef OPENSSL_NO_DSA -+ { FT_general, "gendsa", gendsa_main, gendsa_options }, -+#endif -+ { FT_general, "genpkey", genpkey_main, genpkey_options }, -+#ifndef OPENSSL_NO_RSA -+ { FT_general, "genrsa", genrsa_main, genrsa_options }, -+#endif -+ { FT_general, "help", help_main, help_options }, -+ { FT_general, "list", list_main, list_options }, -+ { FT_general, "nseq", nseq_main, nseq_options }, -+#ifndef OPENSSL_NO_OCSP -+ { FT_general, "ocsp", ocsp_main, ocsp_options }, -+#endif -+ { FT_general, "passwd", passwd_main, passwd_options }, -+#ifndef OPENSSL_NO_DES -+ { FT_general, "pkcs12", pkcs12_main, pkcs12_options }, -+#endif -+ { FT_general, "pkcs7", pkcs7_main, pkcs7_options }, -+ { FT_general, "pkcs8", pkcs8_main, pkcs8_options }, -+ { FT_general, "pkey", pkey_main, pkey_options }, -+ { FT_general, "pkeyparam", pkeyparam_main, pkeyparam_options }, -+ { FT_general, "pkeyutl", pkeyutl_main, pkeyutl_options }, -+ { FT_general, "prime", prime_main, prime_options }, -+ { FT_general, "rand", rand_main, rand_options }, -+ { FT_general, "rehash", rehash_main, rehash_options }, -+ { FT_general, "req", req_main, req_options }, -+ { FT_general, "rsa", rsa_main, rsa_options }, -+#ifndef OPENSSL_NO_RSA -+ { FT_general, "rsautl", rsautl_main, rsautl_options }, -+#endif -+#ifndef OPENSSL_NO_SOCK -+ { FT_general, "s_client", s_client_main, s_client_options }, -+#endif -+#ifndef OPENSSL_NO_SOCK -+ { FT_general, "s_server", s_server_main, s_server_options }, -+#endif -+#ifndef OPENSSL_NO_SOCK -+ { FT_general, "s_time", s_time_main, s_time_options }, -+#endif -+ { FT_general, "sess_id", sess_id_main, sess_id_options }, -+ { FT_general, "smime", smime_main, smime_options }, -+ { FT_general, "speed", speed_main, speed_options }, -+ { FT_general, "spkac", spkac_main, spkac_options }, -+#ifndef OPENSSL_NO_TS -+ { FT_general, "ts", ts_main, ts_options }, -+#endif -+ { FT_general, "verify", verify_main, verify_options }, -+ { FT_general, "version", version_main, version_options }, -+ { FT_general, "x509", x509_main, x509_options }, -+#ifndef OPENSSL_NO_MD2 -+ { FT_md, "md2", dgst_main}, -+#endif -+#ifndef OPENSSL_NO_MD4 -+ { FT_md, "md4", dgst_main}, -+#endif -+ { FT_md, "md5", dgst_main}, -+#ifndef OPENSSL_NO_GOST -+ { FT_md, "gost", dgst_main}, -+#endif -+ { FT_md, "sha1", dgst_main}, -+ { FT_md, "sha224", dgst_main}, -+ { FT_md, "sha256", dgst_main}, -+ { FT_md, "sha384", dgst_main}, -+ { FT_md, "sha512", dgst_main}, -+#ifndef OPENSSL_NO_MDC2 -+ { FT_md, "mdc2", dgst_main}, -+#endif -+#ifndef OPENSSL_NO_RMD160 -+ { FT_md, "rmd160", dgst_main}, -+#endif -+#ifndef OPENSSL_NO_BLAKE2 -+ { FT_md, "blake2b512", dgst_main}, -+#endif -+#ifndef OPENSSL_NO_BLAKE2 -+ { FT_md, "blake2s256", dgst_main}, -+#endif -+ { FT_cipher, "aes-128-cbc", enc_main, enc_options }, -+ { FT_cipher, "aes-128-ecb", enc_main, enc_options }, -+ { FT_cipher, "aes-192-cbc", enc_main, enc_options }, -+ { FT_cipher, "aes-192-ecb", enc_main, enc_options }, -+ { FT_cipher, "aes-256-cbc", enc_main, enc_options }, -+ { FT_cipher, "aes-256-ecb", enc_main, enc_options }, -+#ifndef OPENSSL_NO_CAMELLIA -+ { FT_cipher, "camellia-128-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAMELLIA -+ { FT_cipher, "camellia-128-ecb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAMELLIA -+ { FT_cipher, "camellia-192-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAMELLIA -+ { FT_cipher, "camellia-192-ecb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAMELLIA -+ { FT_cipher, "camellia-256-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAMELLIA -+ { FT_cipher, "camellia-256-ecb", enc_main, enc_options }, -+#endif -+ { FT_cipher, "base64", enc_main, enc_options }, -+#ifdef ZLIB -+ { FT_cipher, "zlib", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des3", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "desx", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_IDEA -+ { FT_cipher, "idea", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_SEED -+ { FT_cipher, "seed", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC4 -+ { FT_cipher, "rc4", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC4 -+ { FT_cipher, "rc4-40", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC2 -+ { FT_cipher, "rc2", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_BF -+ { FT_cipher, "bf", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAST -+ { FT_cipher, "cast", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC5 -+ { FT_cipher, "rc5", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-ecb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-ede", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-ede3", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-ede-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-ede3-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-cfb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-ede-cfb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-ede3-cfb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-ofb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-ede-ofb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_DES -+ { FT_cipher, "des-ede3-ofb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_IDEA -+ { FT_cipher, "idea-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_IDEA -+ { FT_cipher, "idea-ecb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_IDEA -+ { FT_cipher, "idea-cfb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_IDEA -+ { FT_cipher, "idea-ofb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_SEED -+ { FT_cipher, "seed-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_SEED -+ { FT_cipher, "seed-ecb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_SEED -+ { FT_cipher, "seed-cfb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_SEED -+ { FT_cipher, "seed-ofb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC2 -+ { FT_cipher, "rc2-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC2 -+ { FT_cipher, "rc2-ecb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC2 -+ { FT_cipher, "rc2-cfb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC2 -+ { FT_cipher, "rc2-ofb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC2 -+ { FT_cipher, "rc2-64-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC2 -+ { FT_cipher, "rc2-40-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_BF -+ { FT_cipher, "bf-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_BF -+ { FT_cipher, "bf-ecb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_BF -+ { FT_cipher, "bf-cfb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_BF -+ { FT_cipher, "bf-ofb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAST -+ { FT_cipher, "cast5-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAST -+ { FT_cipher, "cast5-ecb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAST -+ { FT_cipher, "cast5-cfb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAST -+ { FT_cipher, "cast5-ofb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_CAST -+ { FT_cipher, "cast-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC5 -+ { FT_cipher, "rc5-cbc", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC5 -+ { FT_cipher, "rc5-ecb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC5 -+ { FT_cipher, "rc5-cfb", enc_main, enc_options }, -+#endif -+#ifndef OPENSSL_NO_RC5 -+ { FT_cipher, "rc5-ofb", enc_main, enc_options }, -+#endif -+ { 0, NULL, NULL} -+}; -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/progs.pl b/CryptoPkg/Library/OpensslLib/openssl/apps/progs.pl -new file mode 100644 -index 0000000..21baf17 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/progs.pl -@@ -0,0 +1,155 @@ -+#! /usr/bin/env perl -+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+# -+# Licensed under the OpenSSL license (the "License"). You may not use -+# this file except in compliance with the License. You can obtain a copy -+# in the file LICENSE in the source distribution or at -+# https://www.openssl.org/source/license.html -+ -+# Generate progs.h file by looking for command mains in list of C files -+# passed on the command line. -+ -+use strict; -+use warnings; -+use configdata qw/@disablables/; -+ -+my %commands = (); -+my $cmdre = qr/^\s*int\s+([a-z_][a-z0-9_]*)_main\(\s*int\s+argc\s*,/; -+ -+foreach my $filename (@ARGV) { -+ open F, $filename or die "Coudn't open $_: $!\n"; -+ foreach (grep /$cmdre/, ) { -+ my @foo = /$cmdre/; -+ $commands{$1} = 1; -+ } -+ close F; -+} -+ -+@ARGV = sort keys %commands; -+ -+print <<'EOF'; -+/* -+ * WARNING: do not edit! -+ * Generated by apps/progs.pl -+ * -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+typedef enum FUNC_TYPE { -+ FT_none, FT_general, FT_md, FT_cipher, FT_pkey, -+ FT_md_alg, FT_cipher_alg -+} FUNC_TYPE; -+ -+typedef struct function_st { -+ FUNC_TYPE type; -+ const char *name; -+ int (*func)(int argc, char *argv[]); -+ const OPTIONS *help; -+} FUNCTION; -+ -+DEFINE_LHASH_OF(FUNCTION); -+ -+EOF -+ -+foreach (@ARGV) { -+ printf "extern int %s_main(int argc, char *argv[]);\n", $_; -+} -+ -+print "\n"; -+ -+foreach (@ARGV) { -+ printf "extern OPTIONS %s_options[];\n", $_; -+} -+ -+print "\n#ifdef INCLUDE_FUNCTION_TABLE\n"; -+print "static FUNCTION functions[] = {\n"; -+my %cmd_disabler = ( -+ ciphers => "sock", -+ genrsa => "rsa", -+ rsautl => "rsa", -+ gendsa => "dsa", -+ dsaparam => "dsa", -+ gendh => "dh", -+ dhparam => "dh", -+ ecparam => "ec", -+ pkcs12 => "des", -+ ); -+foreach my $cmd (@ARGV) { -+ my $str=" { FT_general, \"$cmd\", ${cmd}_main, ${cmd}_options },\n"; -+ if ($cmd =~ /^s_/) { -+ print "#ifndef OPENSSL_NO_SOCK\n${str}#endif\n"; -+ } elsif (grep { $cmd eq $_ } @disablables) { -+ print "#ifndef OPENSSL_NO_".uc($cmd)."\n${str}#endif\n"; -+ } elsif (my $disabler = $cmd_disabler{$cmd}) { -+ print "#ifndef OPENSSL_NO_".uc($disabler)."\n${str}#endif\n"; -+ } else { -+ print $str; -+ } -+} -+ -+my %md_disabler = ( -+ blake2b512 => "blake2", -+ blake2s256 => "blake2", -+ ); -+foreach my $cmd ( -+ "md2", "md4", "md5", -+ "gost", -+ "sha1", "sha224", "sha256", "sha384", "sha512", -+ "mdc2", "rmd160", "blake2b512", "blake2s256" -+) { -+ my $str = " { FT_md, \"".$cmd."\", dgst_main},\n"; -+ if (grep { $cmd eq $_ } @disablables) { -+ print "#ifndef OPENSSL_NO_".uc($cmd)."\n${str}#endif\n"; -+ } elsif (my $disabler = $md_disabler{$cmd}) { -+ print "#ifndef OPENSSL_NO_".uc($disabler)."\n${str}#endif\n"; -+ } else { -+ print $str; -+ } -+} -+ -+my %cipher_disabler = ( -+ des3 => "des", -+ desx => "des", -+ cast5 => "cast", -+ ); -+foreach my $cmd ( -+ "aes-128-cbc", "aes-128-ecb", -+ "aes-192-cbc", "aes-192-ecb", -+ "aes-256-cbc", "aes-256-ecb", -+ "camellia-128-cbc", "camellia-128-ecb", -+ "camellia-192-cbc", "camellia-192-ecb", -+ "camellia-256-cbc", "camellia-256-ecb", -+ "base64", "zlib", -+ "des", "des3", "desx", "idea", "seed", "rc4", "rc4-40", -+ "rc2", "bf", "cast", "rc5", -+ "des-ecb", "des-ede", "des-ede3", -+ "des-cbc", "des-ede-cbc","des-ede3-cbc", -+ "des-cfb", "des-ede-cfb","des-ede3-cfb", -+ "des-ofb", "des-ede-ofb","des-ede3-ofb", -+ "idea-cbc","idea-ecb", "idea-cfb", "idea-ofb", -+ "seed-cbc","seed-ecb", "seed-cfb", "seed-ofb", -+ "rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc", -+ "bf-cbc", "bf-ecb", "bf-cfb", "bf-ofb", -+ "cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb", -+ "cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb" -+) { -+ my $str=" { FT_cipher, \"$cmd\", enc_main, enc_options },\n"; -+ (my $algo= $cmd) =~ s/-.*//g; -+ if ($cmd eq "zlib") { -+ print "#ifdef ZLIB\n${str}#endif\n"; -+ } elsif (grep { $algo eq $_ } @disablables) { -+ print "#ifndef OPENSSL_NO_".uc($algo)."\n${str}#endif\n"; -+ } elsif (my $disabler = $cipher_disabler{$algo}) { -+ print "#ifndef OPENSSL_NO_".uc($disabler)."\n${str}#endif\n"; -+ } else { -+ print $str; -+ } -+} -+ -+print " { 0, NULL, NULL}\n};\n"; -+print "#endif\n"; -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/rand.c b/CryptoPkg/Library/OpensslLib/openssl/apps/rand.c -new file mode 100644 -index 0000000..e726180 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/rand.c -@@ -0,0 +1,132 @@ -+/* -+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "apps.h" -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_OUT, OPT_ENGINE, OPT_RAND, OPT_BASE64, OPT_HEX -+} OPTION_CHOICE; -+ -+OPTIONS rand_options[] = { -+ {OPT_HELP_STR, 1, '-', "Usage: %s [flags] num\n"}, -+ {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"rand", OPT_RAND, 's', -+ "Load the file(s) into the random number generator"}, -+ {"base64", OPT_BASE64, '-', "Base64 encode output"}, -+ {"hex", OPT_HEX, '-', "Hex encode output"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+#endif -+ {NULL} -+}; -+ -+int rand_main(int argc, char **argv) -+{ -+ ENGINE *e = NULL; -+ BIO *out = NULL; -+ char *inrand = NULL, *outfile = NULL, *prog; -+ OPTION_CHOICE o; -+ int format = FORMAT_BINARY, i, num = -1, r, ret = 1; -+ -+ prog = opt_init(argc, argv, rand_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(rand_options); -+ ret = 0; -+ goto end; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ break; -+ case OPT_BASE64: -+ format = FORMAT_BASE64; -+ break; -+ case OPT_HEX: -+ format = FORMAT_TEXT; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ -+ if (argc != 1 || !opt_int(argv[0], &num) || num < 0) -+ goto opthelp; -+ -+ app_RAND_load_file(NULL, (inrand != NULL)); -+ if (inrand != NULL) -+ BIO_printf(bio_err, "%ld semi-random bytes loaded\n", -+ app_RAND_load_files(inrand)); -+ -+ out = bio_open_default(outfile, 'w', format); -+ if (out == NULL) -+ goto end; -+ -+ if (format == FORMAT_BASE64) { -+ BIO *b64 = BIO_new(BIO_f_base64()); -+ if (b64 == NULL) -+ goto end; -+ out = BIO_push(b64, out); -+ } -+ -+ while (num > 0) { -+ unsigned char buf[4096]; -+ int chunk; -+ -+ chunk = num; -+ if (chunk > (int)sizeof(buf)) -+ chunk = sizeof buf; -+ r = RAND_bytes(buf, chunk); -+ if (r <= 0) -+ goto end; -+ if (format != FORMAT_TEXT) { -+ if (BIO_write(out, buf, chunk) != chunk) -+ goto end; -+ } else { -+ for (i = 0; i < chunk; i++) -+ if (BIO_printf(out, "%02x", buf[i]) != 2) -+ goto end; -+ } -+ num -= chunk; -+ } -+ if (format == FORMAT_TEXT) -+ BIO_puts(out, "\n"); -+ if (BIO_flush(out) <= 0 || !app_RAND_write_file(NULL)) -+ goto end; -+ -+ ret = 0; -+ -+ end: -+ if (ret != 0) -+ ERR_print_errors(bio_err); -+ release_engine(e); -+ BIO_free_all(out); -+ return (ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/rehash.c b/CryptoPkg/Library/OpensslLib/openssl/apps/rehash.c -new file mode 100644 -index 0000000..4e10ded ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/rehash.c -@@ -0,0 +1,480 @@ -+/* -+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * C implementation based on the original Perl and shell versions -+ * -+ * Copyright (c) 2013-2014 Timo Teräs -+ */ -+ -+#include "apps.h" -+ -+#if defined(OPENSSL_SYS_UNIX) || defined(__APPLE__) || \ -+ (defined(__VMS) && defined(__DECC) && __CTRL_VER >= 80300000) -+# include -+# include -+# include -+# include -+# include -+# include -+# include -+ -+# include "internal/o_dir.h" -+# include -+# include -+# include -+ -+ -+# ifndef PATH_MAX -+# define PATH_MAX 4096 -+# endif -+# ifndef NAME_MAX -+# define NAME_MAX 255 -+# endif -+# define MAX_COLLISIONS 256 -+ -+typedef struct hentry_st { -+ struct hentry_st *next; -+ char *filename; -+ unsigned short old_id; -+ unsigned char need_symlink; -+ unsigned char digest[EVP_MAX_MD_SIZE]; -+} HENTRY; -+ -+typedef struct bucket_st { -+ struct bucket_st *next; -+ HENTRY *first_entry, *last_entry; -+ unsigned int hash; -+ unsigned short type; -+ unsigned short num_needed; -+} BUCKET; -+ -+enum Type { -+ /* Keep in sync with |suffixes|, below. */ -+ TYPE_CERT=0, TYPE_CRL=1 -+}; -+ -+enum Hash { -+ HASH_OLD, HASH_NEW, HASH_BOTH -+}; -+ -+ -+static int evpmdsize; -+static const EVP_MD *evpmd; -+static int remove_links = 1; -+static int verbose = 0; -+static BUCKET *hash_table[257]; -+ -+static const char *suffixes[] = { "", "r" }; -+static const char *extensions[] = { "pem", "crt", "cer", "crl" }; -+ -+ -+static void bit_set(unsigned char *set, unsigned int bit) -+{ -+ set[bit >> 3] |= 1 << (bit & 0x7); -+} -+ -+static int bit_isset(unsigned char *set, unsigned int bit) -+{ -+ return set[bit >> 3] & (1 << (bit & 0x7)); -+} -+ -+ -+/* -+ * Process an entry; return number of errors. -+ */ -+static int add_entry(enum Type type, unsigned int hash, const char *filename, -+ const unsigned char *digest, int need_symlink, -+ unsigned short old_id) -+{ -+ static BUCKET nilbucket; -+ static HENTRY nilhentry; -+ BUCKET *bp; -+ HENTRY *ep, *found = NULL; -+ unsigned int ndx = (type + hash) % OSSL_NELEM(hash_table); -+ -+ for (bp = hash_table[ndx]; bp; bp = bp->next) -+ if (bp->type == type && bp->hash == hash) -+ break; -+ if (bp == NULL) { -+ bp = app_malloc(sizeof(*bp), "hash bucket"); -+ *bp = nilbucket; -+ bp->next = hash_table[ndx]; -+ bp->type = type; -+ bp->hash = hash; -+ hash_table[ndx] = bp; -+ } -+ -+ for (ep = bp->first_entry; ep; ep = ep->next) { -+ if (digest && memcmp(digest, ep->digest, evpmdsize) == 0) { -+ BIO_printf(bio_err, -+ "%s: skipping duplicate %s in %s\n", opt_getprog(), -+ type == TYPE_CERT ? "certificate" : "CRL", filename); -+ return 1; -+ } -+ if (strcmp(filename, ep->filename) == 0) { -+ found = ep; -+ if (digest == NULL) -+ break; -+ } -+ } -+ ep = found; -+ if (ep == NULL) { -+ if (bp->num_needed >= MAX_COLLISIONS) { -+ BIO_printf(bio_err, -+ "%s: hash table overflow for %s\n", -+ opt_getprog(), filename); -+ return 1; -+ } -+ ep = app_malloc(sizeof(*ep), "collision bucket"); -+ *ep = nilhentry; -+ ep->old_id = ~0; -+ ep->filename = OPENSSL_strdup(filename); -+ if (bp->last_entry) -+ bp->last_entry->next = ep; -+ if (bp->first_entry == NULL) -+ bp->first_entry = ep; -+ bp->last_entry = ep; -+ } -+ -+ if (old_id < ep->old_id) -+ ep->old_id = old_id; -+ if (need_symlink && !ep->need_symlink) { -+ ep->need_symlink = 1; -+ bp->num_needed++; -+ memcpy(ep->digest, digest, evpmdsize); -+ } -+ return 0; -+} -+ -+/* -+ * Check if a symlink goes to the right spot; return 0 if okay. -+ * This can be -1 if bad filename, or an error count. -+ */ -+static int handle_symlink(const char *filename, const char *fullpath) -+{ -+ unsigned int hash = 0; -+ int i, type, id; -+ unsigned char ch; -+ char linktarget[PATH_MAX], *endptr; -+ ossl_ssize_t n; -+ -+ for (i = 0; i < 8; i++) { -+ ch = filename[i]; -+ if (!isxdigit(ch)) -+ return -1; -+ hash <<= 4; -+ hash += OPENSSL_hexchar2int(ch); -+ } -+ if (filename[i++] != '.') -+ return -1; -+ for (type = OSSL_NELEM(suffixes) - 1; type > 0; type--) { -+ const char *suffix = suffixes[type]; -+ if (strncasecmp(suffix, &filename[i], strlen(suffix)) == 0) -+ break; -+ } -+ i += strlen(suffixes[type]); -+ -+ id = strtoul(&filename[i], &endptr, 10); -+ if (*endptr != '\0') -+ return -1; -+ -+ n = readlink(fullpath, linktarget, sizeof(linktarget)); -+ if (n < 0 || n >= (int)sizeof(linktarget)) -+ return -1; -+ linktarget[n] = 0; -+ -+ return add_entry(type, hash, linktarget, NULL, 0, id); -+} -+ -+/* -+ * process a file, return number of errors. -+ */ -+static int do_file(const char *filename, const char *fullpath, enum Hash h) -+{ -+ STACK_OF (X509_INFO) *inf = NULL; -+ X509_INFO *x; -+ X509_NAME *name = NULL; -+ BIO *b; -+ const char *ext; -+ unsigned char digest[EVP_MAX_MD_SIZE]; -+ int type, errs = 0; -+ size_t i; -+ -+ /* Does it end with a recognized extension? */ -+ if ((ext = strrchr(filename, '.')) == NULL) -+ goto end; -+ for (i = 0; i < OSSL_NELEM(extensions); i++) { -+ if (strcasecmp(extensions[i], ext + 1) == 0) -+ break; -+ } -+ if (i >= OSSL_NELEM(extensions)) -+ goto end; -+ -+ /* Does it have X.509 data in it? */ -+ if ((b = BIO_new_file(fullpath, "r")) == NULL) { -+ BIO_printf(bio_err, "%s: skipping %s, cannot open file\n", -+ opt_getprog(), filename); -+ errs++; -+ goto end; -+ } -+ inf = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL); -+ BIO_free(b); -+ if (inf == NULL) -+ goto end; -+ -+ if (sk_X509_INFO_num(inf) != 1) { -+ BIO_printf(bio_err, -+ "%s: skipping %s," -+ "it does not contain exactly one certificate or CRL\n", -+ opt_getprog(), filename); -+ /* This is not an error. */ -+ goto end; -+ } -+ x = sk_X509_INFO_value(inf, 0); -+ if (x->x509) { -+ type = TYPE_CERT; -+ name = X509_get_subject_name(x->x509); -+ X509_digest(x->x509, evpmd, digest, NULL); -+ } else if (x->crl) { -+ type = TYPE_CRL; -+ name = X509_CRL_get_issuer(x->crl); -+ X509_CRL_digest(x->crl, evpmd, digest, NULL); -+ } else { -+ ++errs; -+ goto end; -+ } -+ if (name) { -+ if ((h == HASH_NEW) || (h == HASH_BOTH)) -+ errs += add_entry(type, X509_NAME_hash(name), filename, digest, 1, ~0); -+ if ((h == HASH_OLD) || (h == HASH_BOTH)) -+ errs += add_entry(type, X509_NAME_hash_old(name), filename, digest, 1, ~0); -+ } -+ -+end: -+ sk_X509_INFO_pop_free(inf, X509_INFO_free); -+ return errs; -+} -+ -+static void str_free(char *s) -+{ -+ OPENSSL_free(s); -+} -+ -+/* -+ * Process a directory; return number of errors found. -+ */ -+static int do_dir(const char *dirname, enum Hash h) -+{ -+ BUCKET *bp, *nextbp; -+ HENTRY *ep, *nextep; -+ OPENSSL_DIR_CTX *d = NULL; -+ struct stat st; -+ unsigned char idmask[MAX_COLLISIONS / 8]; -+ int n, numfiles, nextid, buflen, errs = 0; -+ size_t i; -+ const char *pathsep; -+ const char *filename; -+ char *buf, *copy; -+ STACK_OF(OPENSSL_STRING) *files = NULL; -+ -+ if (app_access(dirname, W_OK) < 0) { -+ BIO_printf(bio_err, "Skipping %s, can't write\n", dirname); -+ return 1; -+ } -+ buflen = strlen(dirname); -+ pathsep = (buflen && dirname[buflen - 1] == '/') ? "" : "/"; -+ buflen += NAME_MAX + 1 + 1; -+ buf = app_malloc(buflen, "filename buffer"); -+ -+ if (verbose) -+ BIO_printf(bio_out, "Doing %s\n", dirname); -+ -+ if ((files = sk_OPENSSL_STRING_new_null()) == NULL) { -+ BIO_printf(bio_err, "Skipping %s, out of memory\n", dirname); -+ exit(1); -+ } -+ while ((filename = OPENSSL_DIR_read(&d, dirname)) != NULL) { -+ if ((copy = strdup(filename)) == NULL -+ || sk_OPENSSL_STRING_push(files, copy) == 0) { -+ BIO_puts(bio_err, "out of memory\n"); -+ exit(1); -+ } -+ } -+ OPENSSL_DIR_end(&d); -+ sk_OPENSSL_STRING_sort(files); -+ -+ numfiles = sk_OPENSSL_STRING_num(files); -+ for (n = 0; n < numfiles; ++n) { -+ filename = sk_OPENSSL_STRING_value(files, n); -+ if (snprintf(buf, buflen, "%s%s%s", -+ dirname, pathsep, filename) >= buflen) -+ continue; -+ if (lstat(buf, &st) < 0) -+ continue; -+ if (S_ISLNK(st.st_mode) && handle_symlink(filename, buf) == 0) -+ continue; -+ errs += do_file(filename, buf, h); -+ } -+ sk_OPENSSL_STRING_pop_free(files, str_free); -+ -+ for (i = 0; i < OSSL_NELEM(hash_table); i++) { -+ for (bp = hash_table[i]; bp; bp = nextbp) { -+ nextbp = bp->next; -+ nextid = 0; -+ memset(idmask, 0, (bp->num_needed + 7) / 8); -+ for (ep = bp->first_entry; ep; ep = ep->next) -+ if (ep->old_id < bp->num_needed) -+ bit_set(idmask, ep->old_id); -+ -+ for (ep = bp->first_entry; ep; ep = nextep) { -+ nextep = ep->next; -+ if (ep->old_id < bp->num_needed) { -+ /* Link exists, and is used as-is */ -+ snprintf(buf, buflen, "%08x.%s%d", bp->hash, -+ suffixes[bp->type], ep->old_id); -+ if (verbose) -+ BIO_printf(bio_out, "link %s -> %s\n", -+ ep->filename, buf); -+ } else if (ep->need_symlink) { -+ /* New link needed (it may replace something) */ -+ while (bit_isset(idmask, nextid)) -+ nextid++; -+ -+ snprintf(buf, buflen, "%s%s%n%08x.%s%d", -+ dirname, pathsep, &n, bp->hash, -+ suffixes[bp->type], nextid); -+ if (verbose) -+ BIO_printf(bio_out, "link %s -> %s\n", -+ ep->filename, &buf[n]); -+ if (unlink(buf) < 0 && errno != ENOENT) { -+ BIO_printf(bio_err, -+ "%s: Can't unlink %s, %s\n", -+ opt_getprog(), buf, strerror(errno)); -+ errs++; -+ } -+ if (symlink(ep->filename, buf) < 0) { -+ BIO_printf(bio_err, -+ "%s: Can't symlink %s, %s\n", -+ opt_getprog(), ep->filename, -+ strerror(errno)); -+ errs++; -+ } -+ bit_set(idmask, nextid); -+ } else if (remove_links) { -+ /* Link to be deleted */ -+ snprintf(buf, buflen, "%s%s%n%08x.%s%d", -+ dirname, pathsep, &n, bp->hash, -+ suffixes[bp->type], ep->old_id); -+ if (verbose) -+ BIO_printf(bio_out, "unlink %s\n", -+ &buf[n]); -+ if (unlink(buf) < 0 && errno != ENOENT) { -+ BIO_printf(bio_err, -+ "%s: Can't unlink %s, %s\n", -+ opt_getprog(), buf, strerror(errno)); -+ errs++; -+ } -+ } -+ OPENSSL_free(ep->filename); -+ OPENSSL_free(ep); -+ } -+ OPENSSL_free(bp); -+ } -+ hash_table[i] = NULL; -+ } -+ -+ OPENSSL_free(buf); -+ return errs; -+} -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_COMPAT, OPT_OLD, OPT_N, OPT_VERBOSE -+} OPTION_CHOICE; -+ -+OPTIONS rehash_options[] = { -+ {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert-directory...]\n"}, -+ {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"h", OPT_HELP, '-', "Display this summary"}, -+ {"compat", OPT_COMPAT, '-', "Create both new- and old-style hash links"}, -+ {"old", OPT_OLD, '-', "Use old-style hash to generate links"}, -+ {"n", OPT_N, '-', "Do not remove existing links"}, -+ {"v", OPT_VERBOSE, '-', "Verbose output"}, -+ {NULL} -+}; -+ -+ -+int rehash_main(int argc, char **argv) -+{ -+ const char *env, *prog; -+ char *e, *m; -+ int errs = 0; -+ OPTION_CHOICE o; -+ enum Hash h = HASH_NEW; -+ -+ prog = opt_init(argc, argv, rehash_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(rehash_options); -+ goto end; -+ case OPT_COMPAT: -+ h = HASH_BOTH; -+ break; -+ case OPT_OLD: -+ h = HASH_OLD; -+ break; -+ case OPT_N: -+ remove_links = 0; -+ break; -+ case OPT_VERBOSE: -+ verbose = 1; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ -+ evpmd = EVP_sha1(); -+ evpmdsize = EVP_MD_size(evpmd); -+ -+ if (*argv) { -+ while (*argv) -+ errs += do_dir(*argv++, h); -+ } else if ((env = getenv("SSL_CERT_DIR")) != NULL) { -+ m = OPENSSL_strdup(env); -+ for (e = strtok(m, ":"); e != NULL; e = strtok(NULL, ":")) -+ errs += do_dir(e, h); -+ OPENSSL_free(m); -+ } else { -+ errs += do_dir("/etc/ssl/certs", h); -+ } -+ -+ end: -+ return errs; -+} -+ -+#else -+OPTIONS rehash_options[] = { -+ {NULL} -+}; -+ -+int rehash_main(int argc, char **argv) -+{ -+ BIO_printf(bio_err, "Not available; use c_rehash script\n"); -+ return (1); -+} -+ -+#endif /* defined(OPENSSL_SYS_UNIX) || defined(__APPLE__) */ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/req.c b/CryptoPkg/Library/OpensslLib/openssl/apps/req.c -new file mode 100644 -index 0000000..e8951ae ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/req.c -@@ -0,0 +1,1508 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include "apps.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef OPENSSL_NO_RSA -+# include -+#endif -+#ifndef OPENSSL_NO_DSA -+# include -+#endif -+ -+#define SECTION "req" -+ -+#define BITS "default_bits" -+#define KEYFILE "default_keyfile" -+#define PROMPT "prompt" -+#define DISTINGUISHED_NAME "distinguished_name" -+#define ATTRIBUTES "attributes" -+#define V3_EXTENSIONS "x509_extensions" -+#define REQ_EXTENSIONS "req_extensions" -+#define STRING_MASK "string_mask" -+#define UTF8_IN "utf8" -+ -+#define DEFAULT_KEY_LENGTH 2048 -+#define MIN_KEY_LENGTH 512 -+ -+static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *dn, int mutlirdn, -+ int attribs, unsigned long chtype); -+static int build_subject(X509_REQ *req, const char *subj, unsigned long chtype, -+ int multirdn); -+static int prompt_info(X509_REQ *req, -+ STACK_OF(CONF_VALUE) *dn_sk, const char *dn_sect, -+ STACK_OF(CONF_VALUE) *attr_sk, const char *attr_sect, -+ int attribs, unsigned long chtype); -+static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk, -+ STACK_OF(CONF_VALUE) *attr, int attribs, -+ unsigned long chtype); -+static int add_attribute_object(X509_REQ *req, char *text, const char *def, -+ char *value, int nid, int n_min, int n_max, -+ unsigned long chtype); -+static int add_DN_object(X509_NAME *n, char *text, const char *def, -+ char *value, int nid, int n_min, int n_max, -+ unsigned long chtype, int mval); -+static int genpkey_cb(EVP_PKEY_CTX *ctx); -+static int req_check_len(int len, int n_min, int n_max); -+static int check_end(const char *str, const char *end); -+static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, -+ int *pkey_type, long *pkeylen, -+ char **palgnam, ENGINE *keygen_engine); -+static CONF *req_conf = NULL; -+static int batch = 0; -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_KEYGEN_ENGINE, OPT_KEY, -+ OPT_PUBKEY, OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT, -+ OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_RAND, OPT_NEWKEY, -+ OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS, -+ OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8, -+ OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509, -+ OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_EXTENSIONS, -+ OPT_REQEXTS, OPT_MD -+} OPTION_CHOICE; -+ -+OPTIONS req_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, -+ {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"key", OPT_KEY, 's', "Private key to use"}, -+ {"keyform", OPT_KEYFORM, 'f', "Key file format"}, -+ {"pubkey", OPT_PUBKEY, '-', "Output public key"}, -+ {"new", OPT_NEW, '-', "New request"}, -+ {"config", OPT_CONFIG, '<', "Request template file"}, -+ {"keyout", OPT_KEYOUT, '>', "File to send the key to"}, -+ {"passin", OPT_PASSIN, 's', "Private key password source"}, -+ {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, -+ {"rand", OPT_RAND, 's', -+ "Load the file(s) into the random number generator"}, -+ {"newkey", OPT_NEWKEY, 's', "Specify as type:bits"}, -+ {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, -+ {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, -+ {"batch", OPT_BATCH, '-', -+ "Do not ask anything during request generation"}, -+ {"newhdr", OPT_NEWHDR, '-', "Output \"NEW\" in the header lines"}, -+ {"modulus", OPT_MODULUS, '-', "RSA modulus"}, -+ {"verify", OPT_VERIFY, '-', "Verify signature on REQ"}, -+ {"nodes", OPT_NODES, '-', "Don't encrypt the output key"}, -+ {"noout", OPT_NOOUT, '-', "Do not output REQ"}, -+ {"verbose", OPT_VERBOSE, '-', "Verbose output"}, -+ {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"}, -+ {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, -+ {"reqopt", OPT_REQOPT, 's', "Various request text options"}, -+ {"text", OPT_TEXT, '-', "Text form of request"}, -+ {"x509", OPT_X509, '-', -+ "Output a x509 structure instead of a cert request"}, -+ {OPT_MORE_STR, 1, 1, "(Required by some CA's)"}, -+ {"subj", OPT_SUBJ, 's', "Set or modify request subject"}, -+ {"subject", OPT_SUBJECT, '-', "Output the request's subject"}, -+ {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-', -+ "Enable support for multivalued RDNs"}, -+ {"days", OPT_DAYS, 'p', "Number of days cert is valid for"}, -+ {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"}, -+ {"extensions", OPT_EXTENSIONS, 's', -+ "Cert extension section (override value in config file)"}, -+ {"reqexts", OPT_REQEXTS, 's', -+ "Request extension section (override value in config file)"}, -+ {"", OPT_MD, '-', "Any supported digest"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+ {"keygen_engine", OPT_KEYGEN_ENGINE, 's', -+ "Specify engine to be used for key generation operations"}, -+#endif -+ {NULL} -+}; -+ -+int req_main(int argc, char **argv) -+{ -+ ASN1_INTEGER *serial = NULL; -+ BIO *in = NULL, *out = NULL; -+ ENGINE *e = NULL, *gen_eng = NULL; -+ EVP_PKEY *pkey = NULL; -+ EVP_PKEY_CTX *genctx = NULL; -+ STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL; -+ X509 *x509ss = NULL; -+ X509_REQ *req = NULL; -+ const EVP_CIPHER *cipher = NULL; -+ const EVP_MD *md_alg = NULL, *digest = NULL; -+ char *extensions = NULL, *infile = NULL; -+ char *outfile = NULL, *keyfile = NULL, *inrand = NULL; -+ char *keyalgstr = NULL, *p, *prog, *passargin = NULL, *passargout = NULL; -+ char *passin = NULL, *passout = NULL; -+ char *nofree_passin = NULL, *nofree_passout = NULL; -+ char *req_exts = NULL, *subj = NULL; -+ char *template = default_config_file, *keyout = NULL; -+ const char *keyalg = NULL; -+ OPTION_CHOICE o; -+ int ret = 1, x509 = 0, days = 30, i = 0, newreq = 0, verbose = 0; -+ int pkey_type = -1, private = 0; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyform = FORMAT_PEM; -+ int modulus = 0, multirdn = 0, verify = 0, noout = 0, text = 0; -+ int nodes = 0, newhdr = 0, subject = 0, pubkey = 0; -+ long newkey = -1; -+ unsigned long chtype = MBSTRING_ASC, nmflag = 0, reqflag = 0; -+ char nmflag_set = 0; -+ -+#ifndef OPENSSL_NO_DES -+ cipher = EVP_des_ede3_cbc(); -+#endif -+ -+ prog = opt_init(argc, argv, req_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(req_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) -+ goto opthelp; -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_KEYGEN_ENGINE: -+#ifndef OPENSSL_NO_ENGINE -+ gen_eng = ENGINE_by_id(opt_arg()); -+ if (gen_eng == NULL) { -+ BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv); -+ goto opthelp; -+ } -+#endif -+ break; -+ case OPT_KEY: -+ keyfile = opt_arg(); -+ break; -+ case OPT_PUBKEY: -+ pubkey = 1; -+ break; -+ case OPT_NEW: -+ newreq = 1; -+ break; -+ case OPT_CONFIG: -+ template = opt_arg(); -+ break; -+ case OPT_KEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_KEYOUT: -+ keyout = opt_arg(); -+ break; -+ case OPT_PASSIN: -+ passargin = opt_arg(); -+ break; -+ case OPT_PASSOUT: -+ passargout = opt_arg(); -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ break; -+ case OPT_NEWKEY: -+ keyalg = opt_arg(); -+ newreq = 1; -+ break; -+ case OPT_PKEYOPT: -+ if (!pkeyopts) -+ pkeyopts = sk_OPENSSL_STRING_new_null(); -+ if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, opt_arg())) -+ goto opthelp; -+ break; -+ case OPT_SIGOPT: -+ if (!sigopts) -+ sigopts = sk_OPENSSL_STRING_new_null(); -+ if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) -+ goto opthelp; -+ break; -+ case OPT_BATCH: -+ batch = 1; -+ break; -+ case OPT_NEWHDR: -+ newhdr = 1; -+ break; -+ case OPT_MODULUS: -+ modulus = 1; -+ break; -+ case OPT_VERIFY: -+ verify = 1; -+ break; -+ case OPT_NODES: -+ nodes = 1; -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ case OPT_VERBOSE: -+ verbose = 1; -+ break; -+ case OPT_UTF8: -+ chtype = MBSTRING_UTF8; -+ break; -+ case OPT_NAMEOPT: -+ nmflag_set = 1; -+ if (!set_name_ex(&nmflag, opt_arg())) -+ goto opthelp; -+ break; -+ case OPT_REQOPT: -+ if (!set_cert_ex(&reqflag, opt_arg())) -+ goto opthelp; -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_X509: -+ x509 = 1; -+ newreq = 1; -+ break; -+ case OPT_DAYS: -+ days = atoi(opt_arg()); -+ break; -+ case OPT_SET_SERIAL: -+ if (serial != NULL) { -+ BIO_printf(bio_err, "Serial number supplied twice\n"); -+ goto opthelp; -+ } -+ serial = s2i_ASN1_INTEGER(NULL, opt_arg()); -+ if (serial == NULL) -+ goto opthelp; -+ break; -+ case OPT_SUBJECT: -+ subject = 1; -+ break; -+ case OPT_SUBJ: -+ subj = opt_arg(); -+ break; -+ case OPT_MULTIVALUE_RDN: -+ multirdn = 1; -+ break; -+ case OPT_EXTENSIONS: -+ extensions = opt_arg(); -+ break; -+ case OPT_REQEXTS: -+ req_exts = opt_arg(); -+ break; -+ case OPT_MD: -+ if (!opt_md(opt_unknown(), &md_alg)) -+ goto opthelp; -+ digest = md_alg; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ if (!nmflag_set) -+ nmflag = XN_FLAG_ONELINE; -+ -+ /* TODO: simplify this as pkey is still always NULL here */ -+ private = newreq && (pkey == NULL) ? 1 : 0; -+ -+ if (!app_passwd(passargin, passargout, &passin, &passout)) { -+ BIO_printf(bio_err, "Error getting passwords\n"); -+ goto end; -+ } -+ -+ if (verbose) -+ BIO_printf(bio_err, "Using configuration from %s\n", template); -+ req_conf = app_load_config(template); -+ if (template != default_config_file && !app_load_modules(req_conf)) -+ goto end; -+ -+ if (req_conf != NULL) { -+ p = NCONF_get_string(req_conf, NULL, "oid_file"); -+ if (p == NULL) -+ ERR_clear_error(); -+ if (p != NULL) { -+ BIO *oid_bio; -+ -+ oid_bio = BIO_new_file(p, "r"); -+ if (oid_bio == NULL) { -+ /*- -+ BIO_printf(bio_err,"problems opening %s for extra oid's\n",p); -+ ERR_print_errors(bio_err); -+ */ -+ } else { -+ OBJ_create_objects(oid_bio); -+ BIO_free(oid_bio); -+ } -+ } -+ } -+ if (!add_oid_section(req_conf)) -+ goto end; -+ -+ if (md_alg == NULL) { -+ p = NCONF_get_string(req_conf, SECTION, "default_md"); -+ if (p == NULL) -+ ERR_clear_error(); -+ else { -+ if (!opt_md(p, &md_alg)) -+ goto opthelp; -+ digest = md_alg; -+ } -+ } -+ -+ if (!extensions) { -+ extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS); -+ if (!extensions) -+ ERR_clear_error(); -+ } -+ if (extensions) { -+ /* Check syntax of file */ -+ X509V3_CTX ctx; -+ X509V3_set_ctx_test(&ctx); -+ X509V3_set_nconf(&ctx, req_conf); -+ if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) { -+ BIO_printf(bio_err, -+ "Error Loading extension section %s\n", extensions); -+ goto end; -+ } -+ } -+ -+ if (passin == NULL) { -+ passin = nofree_passin = -+ NCONF_get_string(req_conf, SECTION, "input_password"); -+ if (passin == NULL) -+ ERR_clear_error(); -+ } -+ -+ if (passout == NULL) { -+ passout = nofree_passout = -+ NCONF_get_string(req_conf, SECTION, "output_password"); -+ if (passout == NULL) -+ ERR_clear_error(); -+ } -+ -+ p = NCONF_get_string(req_conf, SECTION, STRING_MASK); -+ if (!p) -+ ERR_clear_error(); -+ -+ if (p && !ASN1_STRING_set_default_mask_asc(p)) { -+ BIO_printf(bio_err, "Invalid global string mask setting %s\n", p); -+ goto end; -+ } -+ -+ if (chtype != MBSTRING_UTF8) { -+ p = NCONF_get_string(req_conf, SECTION, UTF8_IN); -+ if (!p) -+ ERR_clear_error(); -+ else if (strcmp(p, "yes") == 0) -+ chtype = MBSTRING_UTF8; -+ } -+ -+ if (!req_exts) { -+ req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS); -+ if (!req_exts) -+ ERR_clear_error(); -+ } -+ if (req_exts) { -+ /* Check syntax of file */ -+ X509V3_CTX ctx; -+ X509V3_set_ctx_test(&ctx); -+ X509V3_set_nconf(&ctx, req_conf); -+ if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) { -+ BIO_printf(bio_err, -+ "Error Loading request extension section %s\n", -+ req_exts); -+ goto end; -+ } -+ } -+ -+ if (keyfile != NULL) { -+ pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key"); -+ if (!pkey) { -+ /* load_key() has already printed an appropriate message */ -+ goto end; -+ } else { -+ char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE"); -+ if (randfile == NULL) -+ ERR_clear_error(); -+ app_RAND_load_file(randfile, 0); -+ } -+ } -+ -+ if (newreq && (pkey == NULL)) { -+ char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE"); -+ if (randfile == NULL) -+ ERR_clear_error(); -+ app_RAND_load_file(randfile, 0); -+ if (inrand) -+ app_RAND_load_files(inrand); -+ -+ if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) { -+ newkey = DEFAULT_KEY_LENGTH; -+ } -+ -+ if (keyalg) { -+ genctx = set_keygen_ctx(keyalg, &pkey_type, &newkey, -+ &keyalgstr, gen_eng); -+ if (!genctx) -+ goto end; -+ } -+ -+ if (newkey < MIN_KEY_LENGTH -+ && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) { -+ BIO_printf(bio_err, "private key length is too short,\n"); -+ BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n", -+ MIN_KEY_LENGTH, newkey); -+ goto end; -+ } -+ -+ if (!genctx) { -+ genctx = set_keygen_ctx(NULL, &pkey_type, &newkey, -+ &keyalgstr, gen_eng); -+ if (!genctx) -+ goto end; -+ } -+ -+ if (pkeyopts) { -+ char *genopt; -+ for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) { -+ genopt = sk_OPENSSL_STRING_value(pkeyopts, i); -+ if (pkey_ctrl_string(genctx, genopt) <= 0) { -+ BIO_printf(bio_err, "parameter error \"%s\"\n", genopt); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ } -+ -+ if (pkey_type == EVP_PKEY_EC) { -+ BIO_printf(bio_err, "Generating an EC private key\n"); -+ } else { -+ BIO_printf(bio_err, "Generating a %ld bit %s private key\n", -+ newkey, keyalgstr); -+ } -+ -+ EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); -+ EVP_PKEY_CTX_set_app_data(genctx, bio_err); -+ -+ if (EVP_PKEY_keygen(genctx, &pkey) <= 0) { -+ BIO_puts(bio_err, "Error Generating Key\n"); -+ goto end; -+ } -+ -+ EVP_PKEY_CTX_free(genctx); -+ genctx = NULL; -+ -+ app_RAND_write_file(randfile); -+ -+ if (keyout == NULL) { -+ keyout = NCONF_get_string(req_conf, SECTION, KEYFILE); -+ if (keyout == NULL) -+ ERR_clear_error(); -+ } -+ -+ if (keyout == NULL) -+ BIO_printf(bio_err, "writing new private key to stdout\n"); -+ else -+ BIO_printf(bio_err, "writing new private key to '%s'\n", keyout); -+ out = bio_open_owner(keyout, outformat, private); -+ if (out == NULL) -+ goto end; -+ -+ p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key"); -+ if (p == NULL) { -+ ERR_clear_error(); -+ p = NCONF_get_string(req_conf, SECTION, "encrypt_key"); -+ if (p == NULL) -+ ERR_clear_error(); -+ } -+ if ((p != NULL) && (strcmp(p, "no") == 0)) -+ cipher = NULL; -+ if (nodes) -+ cipher = NULL; -+ -+ i = 0; -+ loop: -+ assert(private); -+ if (!PEM_write_bio_PrivateKey(out, pkey, cipher, -+ NULL, 0, NULL, passout)) { -+ if ((ERR_GET_REASON(ERR_peek_error()) == -+ PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) { -+ ERR_clear_error(); -+ i++; -+ goto loop; -+ } -+ goto end; -+ } -+ BIO_free(out); -+ out = NULL; -+ BIO_printf(bio_err, "-----\n"); -+ } -+ -+ if (!newreq) { -+ in = bio_open_default(infile, 'r', informat); -+ if (in == NULL) -+ goto end; -+ -+ if (informat == FORMAT_ASN1) -+ req = d2i_X509_REQ_bio(in, NULL); -+ else -+ req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); -+ if (req == NULL) { -+ BIO_printf(bio_err, "unable to load X509 request\n"); -+ goto end; -+ } -+ } -+ -+ if (newreq) { -+ if (pkey == NULL) { -+ BIO_printf(bio_err, "you need to specify a private key\n"); -+ goto end; -+ } -+ -+ if (req == NULL) { -+ req = X509_REQ_new(); -+ if (req == NULL) { -+ goto end; -+ } -+ -+ i = make_REQ(req, pkey, subj, multirdn, !x509, chtype); -+ subj = NULL; /* done processing '-subj' option */ -+ if (!i) { -+ BIO_printf(bio_err, "problems making Certificate Request\n"); -+ goto end; -+ } -+ } -+ if (x509) { -+ EVP_PKEY *tmppkey; -+ X509V3_CTX ext_ctx; -+ if ((x509ss = X509_new()) == NULL) -+ goto end; -+ -+ /* Set version to V3 */ -+ if (extensions && !X509_set_version(x509ss, 2)) -+ goto end; -+ if (serial) { -+ if (!X509_set_serialNumber(x509ss, serial)) -+ goto end; -+ } else { -+ if (!rand_serial(NULL, X509_get_serialNumber(x509ss))) -+ goto end; -+ } -+ -+ if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) -+ goto end; -+ if (!set_cert_times(x509ss, NULL, NULL, days)) -+ goto end; -+ if (!X509_set_subject_name -+ (x509ss, X509_REQ_get_subject_name(req))) -+ goto end; -+ tmppkey = X509_REQ_get0_pubkey(req); -+ if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey)) -+ goto end; -+ -+ /* Set up V3 context struct */ -+ -+ X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0); -+ X509V3_set_nconf(&ext_ctx, req_conf); -+ -+ /* Add extensions */ -+ if (extensions && !X509V3_EXT_add_nconf(req_conf, -+ &ext_ctx, extensions, -+ x509ss)) { -+ BIO_printf(bio_err, "Error Loading extension section %s\n", -+ extensions); -+ goto end; -+ } -+ -+ i = do_X509_sign(x509ss, pkey, digest, sigopts); -+ if (!i) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } else { -+ X509V3_CTX ext_ctx; -+ -+ /* Set up V3 context struct */ -+ -+ X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0); -+ X509V3_set_nconf(&ext_ctx, req_conf); -+ -+ /* Add extensions */ -+ if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf, -+ &ext_ctx, req_exts, -+ req)) { -+ BIO_printf(bio_err, "Error Loading extension section %s\n", -+ req_exts); -+ goto end; -+ } -+ i = do_X509_REQ_sign(req, pkey, digest, sigopts); -+ if (!i) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ } -+ -+ if (subj && x509) { -+ BIO_printf(bio_err, "Cannot modify certificate subject\n"); -+ goto end; -+ } -+ -+ if (subj && !x509) { -+ if (verbose) { -+ BIO_printf(bio_err, "Modifying Request's Subject\n"); -+ print_name(bio_err, "old subject=", -+ X509_REQ_get_subject_name(req), nmflag); -+ } -+ -+ if (build_subject(req, subj, chtype, multirdn) == 0) { -+ BIO_printf(bio_err, "ERROR: cannot modify subject\n"); -+ ret = 1; -+ goto end; -+ } -+ -+ if (verbose) { -+ print_name(bio_err, "new subject=", -+ X509_REQ_get_subject_name(req), nmflag); -+ } -+ } -+ -+ if (verify && !x509) { -+ EVP_PKEY *tpubkey = pkey; -+ -+ if (tpubkey == NULL) { -+ tpubkey = X509_REQ_get0_pubkey(req); -+ if (tpubkey == NULL) -+ goto end; -+ } -+ -+ i = X509_REQ_verify(req, tpubkey); -+ -+ if (i < 0) { -+ goto end; -+ } else if (i == 0) { -+ BIO_printf(bio_err, "verify failure\n"); -+ ERR_print_errors(bio_err); -+ } else /* if (i > 0) */ -+ BIO_printf(bio_err, "verify OK\n"); -+ } -+ -+ if (noout && !text && !modulus && !subject && !pubkey) { -+ ret = 0; -+ goto end; -+ } -+ -+ out = bio_open_default(outfile, -+ keyout != NULL && outfile != NULL && -+ strcmp(keyout, outfile) == 0 ? 'a' : 'w', -+ outformat); -+ if (out == NULL) -+ goto end; -+ -+ if (pubkey) { -+ EVP_PKEY *tpubkey = X509_REQ_get0_pubkey(req); -+ -+ if (tpubkey == NULL) { -+ BIO_printf(bio_err, "Error getting public key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ PEM_write_bio_PUBKEY(out, tpubkey); -+ } -+ -+ if (text) { -+ if (x509) -+ X509_print_ex(out, x509ss, nmflag, reqflag); -+ else -+ X509_REQ_print_ex(out, req, nmflag, reqflag); -+ } -+ -+ if (subject) { -+ if (x509) -+ print_name(out, "subject=", X509_get_subject_name(x509ss), -+ nmflag); -+ else -+ print_name(out, "subject=", X509_REQ_get_subject_name(req), -+ nmflag); -+ } -+ -+ if (modulus) { -+ EVP_PKEY *tpubkey; -+ -+ if (x509) -+ tpubkey = X509_get0_pubkey(x509ss); -+ else -+ tpubkey = X509_REQ_get0_pubkey(req); -+ if (tpubkey == NULL) { -+ fprintf(stdout, "Modulus=unavailable\n"); -+ goto end; -+ } -+ fprintf(stdout, "Modulus="); -+#ifndef OPENSSL_NO_RSA -+ if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA) { -+ const BIGNUM *n; -+ RSA_get0_key(EVP_PKEY_get0_RSA(tpubkey), &n, NULL, NULL); -+ BN_print(out, n); -+ } else -+#endif -+ fprintf(stdout, "Wrong Algorithm type"); -+ fprintf(stdout, "\n"); -+ } -+ -+ if (!noout && !x509) { -+ if (outformat == FORMAT_ASN1) -+ i = i2d_X509_REQ_bio(out, req); -+ else if (newhdr) -+ i = PEM_write_bio_X509_REQ_NEW(out, req); -+ else -+ i = PEM_write_bio_X509_REQ(out, req); -+ if (!i) { -+ BIO_printf(bio_err, "unable to write X509 request\n"); -+ goto end; -+ } -+ } -+ if (!noout && x509 && (x509ss != NULL)) { -+ if (outformat == FORMAT_ASN1) -+ i = i2d_X509_bio(out, x509ss); -+ else -+ i = PEM_write_bio_X509(out, x509ss); -+ if (!i) { -+ BIO_printf(bio_err, "unable to write X509 certificate\n"); -+ goto end; -+ } -+ } -+ ret = 0; -+ end: -+ if (ret) { -+ ERR_print_errors(bio_err); -+ } -+ NCONF_free(req_conf); -+ BIO_free(in); -+ BIO_free_all(out); -+ EVP_PKEY_free(pkey); -+ EVP_PKEY_CTX_free(genctx); -+ sk_OPENSSL_STRING_free(pkeyopts); -+ sk_OPENSSL_STRING_free(sigopts); -+#ifndef OPENSSL_NO_ENGINE -+ ENGINE_free(gen_eng); -+#endif -+ OPENSSL_free(keyalgstr); -+ X509_REQ_free(req); -+ X509_free(x509ss); -+ ASN1_INTEGER_free(serial); -+ release_engine(e); -+ if (passin != nofree_passin) -+ OPENSSL_free(passin); -+ if (passout != nofree_passout) -+ OPENSSL_free(passout); -+ return (ret); -+} -+ -+static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn, -+ int attribs, unsigned long chtype) -+{ -+ int ret = 0, i; -+ char no_prompt = 0; -+ STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL; -+ char *tmp, *dn_sect, *attr_sect; -+ -+ tmp = NCONF_get_string(req_conf, SECTION, PROMPT); -+ if (tmp == NULL) -+ ERR_clear_error(); -+ if ((tmp != NULL) && strcmp(tmp, "no") == 0) -+ no_prompt = 1; -+ -+ dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME); -+ if (dn_sect == NULL) { -+ BIO_printf(bio_err, "unable to find '%s' in config\n", -+ DISTINGUISHED_NAME); -+ goto err; -+ } -+ dn_sk = NCONF_get_section(req_conf, dn_sect); -+ if (dn_sk == NULL) { -+ BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect); -+ goto err; -+ } -+ -+ attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES); -+ if (attr_sect == NULL) { -+ ERR_clear_error(); -+ attr_sk = NULL; -+ } else { -+ attr_sk = NCONF_get_section(req_conf, attr_sect); -+ if (attr_sk == NULL) { -+ BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect); -+ goto err; -+ } -+ } -+ -+ /* setup version number */ -+ if (!X509_REQ_set_version(req, 0L)) -+ goto err; /* version 1 */ -+ -+ if (subj) -+ i = build_subject(req, subj, chtype, multirdn); -+ else if (no_prompt) -+ i = auto_info(req, dn_sk, attr_sk, attribs, chtype); -+ else -+ i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, -+ chtype); -+ if (!i) -+ goto err; -+ -+ if (!X509_REQ_set_pubkey(req, pkey)) -+ goto err; -+ -+ ret = 1; -+ err: -+ return (ret); -+} -+ -+/* -+ * subject is expected to be in the format /type0=value0/type1=value1/type2=... -+ * where characters may be escaped by \ -+ */ -+static int build_subject(X509_REQ *req, const char *subject, unsigned long chtype, -+ int multirdn) -+{ -+ X509_NAME *n; -+ -+ if ((n = parse_name(subject, chtype, multirdn)) == NULL) -+ return 0; -+ -+ if (!X509_REQ_set_subject_name(req, n)) { -+ X509_NAME_free(n); -+ return 0; -+ } -+ X509_NAME_free(n); -+ return 1; -+} -+ -+static int prompt_info(X509_REQ *req, -+ STACK_OF(CONF_VALUE) *dn_sk, const char *dn_sect, -+ STACK_OF(CONF_VALUE) *attr_sk, const char *attr_sect, -+ int attribs, unsigned long chtype) -+{ -+ int i; -+ char *p, *q; -+ char buf[100]; -+ int nid, mval; -+ long n_min, n_max; -+ char *type, *value; -+ const char *def; -+ CONF_VALUE *v; -+ X509_NAME *subj; -+ subj = X509_REQ_get_subject_name(req); -+ -+ if (!batch) { -+ BIO_printf(bio_err, -+ "You are about to be asked to enter information that will be incorporated\n"); -+ BIO_printf(bio_err, "into your certificate request.\n"); -+ BIO_printf(bio_err, -+ "What you are about to enter is what is called a Distinguished Name or a DN.\n"); -+ BIO_printf(bio_err, -+ "There are quite a few fields but you can leave some blank\n"); -+ BIO_printf(bio_err, -+ "For some fields there will be a default value,\n"); -+ BIO_printf(bio_err, -+ "If you enter '.', the field will be left blank.\n"); -+ BIO_printf(bio_err, "-----\n"); -+ } -+ -+ if (sk_CONF_VALUE_num(dn_sk)) { -+ i = -1; -+ start:for (;;) { -+ i++; -+ if (sk_CONF_VALUE_num(dn_sk) <= i) -+ break; -+ -+ v = sk_CONF_VALUE_value(dn_sk, i); -+ p = q = NULL; -+ type = v->name; -+ if (!check_end(type, "_min") || !check_end(type, "_max") || -+ !check_end(type, "_default") || !check_end(type, "_value")) -+ continue; -+ /* -+ * Skip past any leading X. X: X, etc to allow for multiple -+ * instances -+ */ -+ for (p = v->name; *p; p++) -+ if ((*p == ':') || (*p == ',') || (*p == '.')) { -+ p++; -+ if (*p) -+ type = p; -+ break; -+ } -+ if (*type == '+') { -+ mval = -1; -+ type++; -+ } else -+ mval = 0; -+ /* If OBJ not recognised ignore it */ -+ if ((nid = OBJ_txt2nid(type)) == NID_undef) -+ goto start; -+ if (BIO_snprintf(buf, sizeof buf, "%s_default", v->name) -+ >= (int)sizeof(buf)) { -+ BIO_printf(bio_err, "Name '%s' too long\n", v->name); -+ return 0; -+ } -+ -+ if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { -+ ERR_clear_error(); -+ def = ""; -+ } -+ -+ BIO_snprintf(buf, sizeof buf, "%s_value", v->name); -+ if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { -+ ERR_clear_error(); -+ value = NULL; -+ } -+ -+ BIO_snprintf(buf, sizeof buf, "%s_min", v->name); -+ if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) { -+ ERR_clear_error(); -+ n_min = -1; -+ } -+ -+ BIO_snprintf(buf, sizeof buf, "%s_max", v->name); -+ if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) { -+ ERR_clear_error(); -+ n_max = -1; -+ } -+ -+ if (!add_DN_object(subj, v->value, def, value, nid, -+ n_min, n_max, chtype, mval)) -+ return 0; -+ } -+ if (X509_NAME_entry_count(subj) == 0) { -+ BIO_printf(bio_err, -+ "error, no objects specified in config file\n"); -+ return 0; -+ } -+ -+ if (attribs) { -+ if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) -+ && (!batch)) { -+ BIO_printf(bio_err, -+ "\nPlease enter the following 'extra' attributes\n"); -+ BIO_printf(bio_err, -+ "to be sent with your certificate request\n"); -+ } -+ -+ i = -1; -+ start2: for (;;) { -+ i++; -+ if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i)) -+ break; -+ -+ v = sk_CONF_VALUE_value(attr_sk, i); -+ type = v->name; -+ if ((nid = OBJ_txt2nid(type)) == NID_undef) -+ goto start2; -+ -+ if (BIO_snprintf(buf, sizeof buf, "%s_default", type) -+ >= (int)sizeof(buf)) { -+ BIO_printf(bio_err, "Name '%s' too long\n", v->name); -+ return 0; -+ } -+ -+ if ((def = NCONF_get_string(req_conf, attr_sect, buf)) -+ == NULL) { -+ ERR_clear_error(); -+ def = ""; -+ } -+ -+ BIO_snprintf(buf, sizeof buf, "%s_value", type); -+ if ((value = NCONF_get_string(req_conf, attr_sect, buf)) -+ == NULL) { -+ ERR_clear_error(); -+ value = NULL; -+ } -+ -+ BIO_snprintf(buf, sizeof buf, "%s_min", type); -+ if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) { -+ ERR_clear_error(); -+ n_min = -1; -+ } -+ -+ BIO_snprintf(buf, sizeof buf, "%s_max", type); -+ if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) { -+ ERR_clear_error(); -+ n_max = -1; -+ } -+ -+ if (!add_attribute_object(req, -+ v->value, def, value, nid, n_min, -+ n_max, chtype)) -+ return 0; -+ } -+ } -+ } else { -+ BIO_printf(bio_err, "No template, please set one up.\n"); -+ return 0; -+ } -+ -+ return 1; -+ -+} -+ -+static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, -+ STACK_OF(CONF_VALUE) *attr_sk, int attribs, -+ unsigned long chtype) -+{ -+ int i, spec_char, plus_char; -+ char *p, *q; -+ char *type; -+ CONF_VALUE *v; -+ X509_NAME *subj; -+ -+ subj = X509_REQ_get_subject_name(req); -+ -+ for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { -+ int mval; -+ v = sk_CONF_VALUE_value(dn_sk, i); -+ p = q = NULL; -+ type = v->name; -+ /* -+ * Skip past any leading X. X: X, etc to allow for multiple instances -+ */ -+ for (p = v->name; *p; p++) { -+#ifndef CHARSET_EBCDIC -+ spec_char = ((*p == ':') || (*p == ',') || (*p == '.')); -+#else -+ spec_char = ((*p == os_toascii[':']) || (*p == os_toascii[',']) -+ || (*p == os_toascii['.'])); -+#endif -+ if (spec_char) { -+ p++; -+ if (*p) -+ type = p; -+ break; -+ } -+ } -+#ifndef CHARSET_EBCDIC -+ plus_char = (*type == '+'); -+#else -+ plus_char = (*type == os_toascii['+']); -+#endif -+ if (plus_char) { -+ type++; -+ mval = -1; -+ } else -+ mval = 0; -+ if (!X509_NAME_add_entry_by_txt(subj, type, chtype, -+ (unsigned char *)v->value, -1, -1, -+ mval)) -+ return 0; -+ -+ } -+ -+ if (!X509_NAME_entry_count(subj)) { -+ BIO_printf(bio_err, "error, no objects specified in config file\n"); -+ return 0; -+ } -+ if (attribs) { -+ for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) { -+ v = sk_CONF_VALUE_value(attr_sk, i); -+ if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype, -+ (unsigned char *)v->value, -1)) -+ return 0; -+ } -+ } -+ return 1; -+} -+ -+static int add_DN_object(X509_NAME *n, char *text, const char *def, -+ char *value, int nid, int n_min, int n_max, -+ unsigned long chtype, int mval) -+{ -+ int i, ret = 0; -+ char buf[1024]; -+ start: -+ if (!batch) -+ BIO_printf(bio_err, "%s [%s]:", text, def); -+ (void)BIO_flush(bio_err); -+ if (value != NULL) { -+ OPENSSL_strlcpy(buf, value, sizeof buf); -+ OPENSSL_strlcat(buf, "\n", sizeof buf); -+ BIO_printf(bio_err, "%s\n", value); -+ } else { -+ buf[0] = '\0'; -+ if (!batch) { -+ if (!fgets(buf, sizeof buf, stdin)) -+ return 0; -+ } else { -+ buf[0] = '\n'; -+ buf[1] = '\0'; -+ } -+ } -+ -+ if (buf[0] == '\0') -+ return (0); -+ else if (buf[0] == '\n') { -+ if ((def == NULL) || (def[0] == '\0')) -+ return (1); -+ OPENSSL_strlcpy(buf, def, sizeof buf); -+ OPENSSL_strlcat(buf, "\n", sizeof buf); -+ } else if ((buf[0] == '.') && (buf[1] == '\n')) -+ return (1); -+ -+ i = strlen(buf); -+ if (buf[i - 1] != '\n') { -+ BIO_printf(bio_err, "weird input :-(\n"); -+ return (0); -+ } -+ buf[--i] = '\0'; -+#ifdef CHARSET_EBCDIC -+ ebcdic2ascii(buf, buf, i); -+#endif -+ if (!req_check_len(i, n_min, n_max)) { -+ if (batch || value) -+ return 0; -+ goto start; -+ } -+ -+ if (!X509_NAME_add_entry_by_NID(n, nid, chtype, -+ (unsigned char *)buf, -1, -1, mval)) -+ goto err; -+ ret = 1; -+ err: -+ return (ret); -+} -+ -+static int add_attribute_object(X509_REQ *req, char *text, const char *def, -+ char *value, int nid, int n_min, -+ int n_max, unsigned long chtype) -+{ -+ int i; -+ static char buf[1024]; -+ -+ start: -+ if (!batch) -+ BIO_printf(bio_err, "%s [%s]:", text, def); -+ (void)BIO_flush(bio_err); -+ if (value != NULL) { -+ OPENSSL_strlcpy(buf, value, sizeof buf); -+ OPENSSL_strlcat(buf, "\n", sizeof buf); -+ BIO_printf(bio_err, "%s\n", value); -+ } else { -+ buf[0] = '\0'; -+ if (!batch) { -+ if (!fgets(buf, sizeof buf, stdin)) -+ return 0; -+ } else { -+ buf[0] = '\n'; -+ buf[1] = '\0'; -+ } -+ } -+ -+ if (buf[0] == '\0') -+ return (0); -+ else if (buf[0] == '\n') { -+ if ((def == NULL) || (def[0] == '\0')) -+ return (1); -+ OPENSSL_strlcpy(buf, def, sizeof buf); -+ OPENSSL_strlcat(buf, "\n", sizeof buf); -+ } else if ((buf[0] == '.') && (buf[1] == '\n')) -+ return (1); -+ -+ i = strlen(buf); -+ if (buf[i - 1] != '\n') { -+ BIO_printf(bio_err, "weird input :-(\n"); -+ return (0); -+ } -+ buf[--i] = '\0'; -+#ifdef CHARSET_EBCDIC -+ ebcdic2ascii(buf, buf, i); -+#endif -+ if (!req_check_len(i, n_min, n_max)) { -+ if (batch || value) -+ return 0; -+ goto start; -+ } -+ -+ if (!X509_REQ_add1_attr_by_NID(req, nid, chtype, -+ (unsigned char *)buf, -1)) { -+ BIO_printf(bio_err, "Error adding attribute\n"); -+ ERR_print_errors(bio_err); -+ goto err; -+ } -+ -+ return (1); -+ err: -+ return (0); -+} -+ -+static int req_check_len(int len, int n_min, int n_max) -+{ -+ if ((n_min > 0) && (len < n_min)) { -+ BIO_printf(bio_err, -+ "string is too short, it needs to be at least %d bytes long\n", -+ n_min); -+ return (0); -+ } -+ if ((n_max >= 0) && (len > n_max)) { -+ BIO_printf(bio_err, -+ "string is too long, it needs to be less than %d bytes long\n", -+ n_max); -+ return (0); -+ } -+ return (1); -+} -+ -+/* Check if the end of a string matches 'end' */ -+static int check_end(const char *str, const char *end) -+{ -+ int elen, slen; -+ const char *tmp; -+ elen = strlen(end); -+ slen = strlen(str); -+ if (elen > slen) -+ return 1; -+ tmp = str + slen - elen; -+ return strcmp(tmp, end); -+} -+ -+static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, -+ int *pkey_type, long *pkeylen, -+ char **palgnam, ENGINE *keygen_engine) -+{ -+ EVP_PKEY_CTX *gctx = NULL; -+ EVP_PKEY *param = NULL; -+ long keylen = -1; -+ BIO *pbio = NULL; -+ const char *paramfile = NULL; -+ -+ if (gstr == NULL) { -+ *pkey_type = EVP_PKEY_RSA; -+ keylen = *pkeylen; -+ } else if (gstr[0] >= '0' && gstr[0] <= '9') { -+ *pkey_type = EVP_PKEY_RSA; -+ keylen = atol(gstr); -+ *pkeylen = keylen; -+ } else if (strncmp(gstr, "param:", 6) == 0) -+ paramfile = gstr + 6; -+ else { -+ const char *p = strchr(gstr, ':'); -+ int len; -+ ENGINE *tmpeng; -+ const EVP_PKEY_ASN1_METHOD *ameth; -+ -+ if (p) -+ len = p - gstr; -+ else -+ len = strlen(gstr); -+ /* -+ * The lookup of a the string will cover all engines so keep a note -+ * of the implementation. -+ */ -+ -+ ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len); -+ -+ if (!ameth) { -+ BIO_printf(bio_err, "Unknown algorithm %.*s\n", len, gstr); -+ return NULL; -+ } -+ -+ EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, ameth); -+#ifndef OPENSSL_NO_ENGINE -+ ENGINE_finish(tmpeng); -+#endif -+ if (*pkey_type == EVP_PKEY_RSA) { -+ if (p) { -+ keylen = atol(p + 1); -+ *pkeylen = keylen; -+ } else -+ keylen = *pkeylen; -+ } else if (p) -+ paramfile = p + 1; -+ } -+ -+ if (paramfile) { -+ pbio = BIO_new_file(paramfile, "r"); -+ if (!pbio) { -+ BIO_printf(bio_err, "Can't open parameter file %s\n", paramfile); -+ return NULL; -+ } -+ param = PEM_read_bio_Parameters(pbio, NULL); -+ -+ if (!param) { -+ X509 *x; -+ (void)BIO_reset(pbio); -+ x = PEM_read_bio_X509(pbio, NULL, NULL, NULL); -+ if (x) { -+ param = X509_get_pubkey(x); -+ X509_free(x); -+ } -+ } -+ -+ BIO_free(pbio); -+ -+ if (!param) { -+ BIO_printf(bio_err, "Error reading parameter file %s\n", paramfile); -+ return NULL; -+ } -+ if (*pkey_type == -1) -+ *pkey_type = EVP_PKEY_id(param); -+ else if (*pkey_type != EVP_PKEY_base_id(param)) { -+ BIO_printf(bio_err, "Key Type does not match parameters\n"); -+ EVP_PKEY_free(param); -+ return NULL; -+ } -+ } -+ -+ if (palgnam) { -+ const EVP_PKEY_ASN1_METHOD *ameth; -+ ENGINE *tmpeng; -+ const char *anam; -+ ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type); -+ if (!ameth) { -+ BIO_puts(bio_err, "Internal error: can't find key algorithm\n"); -+ return NULL; -+ } -+ EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth); -+ *palgnam = OPENSSL_strdup(anam); -+#ifndef OPENSSL_NO_ENGINE -+ ENGINE_finish(tmpeng); -+#endif -+ } -+ -+ if (param) { -+ gctx = EVP_PKEY_CTX_new(param, keygen_engine); -+ *pkeylen = EVP_PKEY_bits(param); -+ EVP_PKEY_free(param); -+ } else -+ gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine); -+ -+ if (gctx == NULL) { -+ BIO_puts(bio_err, "Error allocating keygen context\n"); -+ ERR_print_errors(bio_err); -+ return NULL; -+ } -+ -+ if (EVP_PKEY_keygen_init(gctx) <= 0) { -+ BIO_puts(bio_err, "Error initializing keygen context\n"); -+ ERR_print_errors(bio_err); -+ EVP_PKEY_CTX_free(gctx); -+ return NULL; -+ } -+#ifndef OPENSSL_NO_RSA -+ if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) { -+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) { -+ BIO_puts(bio_err, "Error setting RSA keysize\n"); -+ ERR_print_errors(bio_err); -+ EVP_PKEY_CTX_free(gctx); -+ return NULL; -+ } -+ } -+#endif -+ -+ return gctx; -+} -+ -+static int genpkey_cb(EVP_PKEY_CTX *ctx) -+{ -+ char c = '*'; -+ BIO *b = EVP_PKEY_CTX_get_app_data(ctx); -+ int p; -+ p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); -+ if (p == 0) -+ c = '.'; -+ if (p == 1) -+ c = '+'; -+ if (p == 2) -+ c = '*'; -+ if (p == 3) -+ c = '\n'; -+ BIO_write(b, &c, 1); -+ (void)BIO_flush(b); -+ return 1; -+} -+ -+static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, -+ const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) -+{ -+ EVP_PKEY_CTX *pkctx = NULL; -+ int i; -+ -+ if (ctx == NULL) -+ return 0; -+ if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)) -+ return 0; -+ for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { -+ char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); -+ if (pkey_ctrl_string(pkctx, sigopt) <= 0) { -+ BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ } -+ return 1; -+} -+ -+int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, -+ STACK_OF(OPENSSL_STRING) *sigopts) -+{ -+ int rv; -+ EVP_MD_CTX *mctx = EVP_MD_CTX_new(); -+ -+ rv = do_sign_init(mctx, pkey, md, sigopts); -+ if (rv > 0) -+ rv = X509_sign_ctx(x, mctx); -+ EVP_MD_CTX_free(mctx); -+ return rv > 0 ? 1 : 0; -+} -+ -+int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, -+ STACK_OF(OPENSSL_STRING) *sigopts) -+{ -+ int rv; -+ EVP_MD_CTX *mctx = EVP_MD_CTX_new(); -+ rv = do_sign_init(mctx, pkey, md, sigopts); -+ if (rv > 0) -+ rv = X509_REQ_sign_ctx(x, mctx); -+ EVP_MD_CTX_free(mctx); -+ return rv > 0 ? 1 : 0; -+} -+ -+int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, -+ STACK_OF(OPENSSL_STRING) *sigopts) -+{ -+ int rv; -+ EVP_MD_CTX *mctx = EVP_MD_CTX_new(); -+ rv = do_sign_init(mctx, pkey, md, sigopts); -+ if (rv > 0) -+ rv = X509_CRL_sign_ctx(x, mctx); -+ EVP_MD_CTX_free(mctx); -+ return rv > 0 ? 1 : 0; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/req.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/req.pem -new file mode 100644 -index 0000000..5537df6 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/req.pem -@@ -0,0 +1,11 @@ -+-----BEGIN CERTIFICATE REQUEST----- -+MIIBlzCCAVcCAQAwXjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx -+ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMORXJp -+YyB0aGUgWW91bmcwge8wgaYGBSsOAwIMMIGcAkEA+ZiKEvZmc9MtnaFZh4NiZ3oZ -+S4J1PHvPrm9MXj5ntVheDPkdmBDTncyaGAJcMjwsyB/GvLDGd6yGCw/8eF+09wIV -+AK3VagOxGd/Q4Af5NbxR5FB7CXEjAkA2t/q7HgVLi0KeKvcDG8BRl3wuy7bCvpjg -+tWiJc/tpvcuzeuAayH89UofjAGueKjXDADiRffvSdhrNw5dkqdqlA0QAAkEAtUSo -+84OekjitKGVjxLu0HvXck29pu+foad53vPKXAsuJdACj88BPqZ91Y9PIJf1GUh38 -+CuiHWi7z3cEDfZCyCKAAMAkGBSsOAwIbBQADLwAwLAIUTg8amKVBE9oqC5B75dDQ -+Chy3LdQCFHKodGEj3LjuTzdm/RTe2KZL9Uzf -+-----END CERTIFICATE REQUEST----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/rsa.c b/CryptoPkg/Library/OpensslLib/openssl/apps/rsa.c -new file mode 100644 -index 0000000..35ab727 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/rsa.c -@@ -0,0 +1,310 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#ifdef OPENSSL_NO_RSA -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include -+# include -+# include -+# include -+# include "apps.h" -+# include -+# include -+# include -+# include -+# include -+# include -+# include -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, -+ OPT_PUBIN, OPT_PUBOUT, OPT_PASSOUT, OPT_PASSIN, -+ OPT_RSAPUBKEY_IN, OPT_RSAPUBKEY_OUT, -+ /* Do not change the order here; see case statements below */ -+ OPT_PVK_NONE, OPT_PVK_WEAK, OPT_PVK_STRONG, -+ OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_CHECK, OPT_CIPHER -+} OPTION_CHOICE; -+ -+OPTIONS rsa_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"inform", OPT_INFORM, 'f', "Input format, one of DER NET PEM"}, -+ {"outform", OPT_OUTFORM, 'f', "Output format, one of DER NET PEM PVK"}, -+ {"in", OPT_IN, 's', "Input file"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"}, -+ {"pubout", OPT_PUBOUT, '-', "Output a public key"}, -+ {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+ {"RSAPublicKey_in", OPT_RSAPUBKEY_IN, '-', "Input is an RSAPublicKey"}, -+ {"RSAPublicKey_out", OPT_RSAPUBKEY_OUT, '-', "Output is an RSAPublicKey"}, -+ {"noout", OPT_NOOUT, '-', "Don't print key out"}, -+ {"text", OPT_TEXT, '-', "Print the key in text"}, -+ {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, -+ {"check", OPT_CHECK, '-', "Verify key consistency"}, -+ {"", OPT_CIPHER, '-', "Any supported cipher"}, -+# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) -+ {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"}, -+ {"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"}, -+ {"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"}, -+# endif -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+int rsa_main(int argc, char **argv) -+{ -+ ENGINE *e = NULL; -+ BIO *out = NULL; -+ RSA *rsa = NULL; -+ const EVP_CIPHER *enc = NULL; -+ char *infile = NULL, *outfile = NULL, *prog; -+ char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL; -+ int i, private = 0; -+ int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, check = 0; -+ int noout = 0, modulus = 0, pubin = 0, pubout = 0, ret = 1; -+# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) -+ int pvk_encr = 2; -+# endif -+ OPTION_CHOICE o; -+ -+ prog = opt_init(argc, argv, rsa_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(rsa_options); -+ ret = 0; -+ goto end; -+ case OPT_INFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat)) -+ goto opthelp; -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ case OPT_PASSOUT: -+ passoutarg = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_PUBIN: -+ pubin = 1; -+ break; -+ case OPT_PUBOUT: -+ pubout = 1; -+ break; -+ case OPT_RSAPUBKEY_IN: -+ pubin = 2; -+ break; -+ case OPT_RSAPUBKEY_OUT: -+ pubout = 2; -+ break; -+ case OPT_PVK_STRONG: /* pvk_encr:= 2 */ -+ case OPT_PVK_WEAK: /* pvk_encr:= 1 */ -+ case OPT_PVK_NONE: /* pvk_encr:= 0 */ -+# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) -+ pvk_encr = (o - OPT_PVK_NONE); -+# endif -+ break; -+ case OPT_NOOUT: -+ noout = 1; -+ break; -+ case OPT_TEXT: -+ text = 1; -+ break; -+ case OPT_MODULUS: -+ modulus = 1; -+ break; -+ case OPT_CHECK: -+ check = 1; -+ break; -+ case OPT_CIPHER: -+ if (!opt_cipher(opt_unknown(), &enc)) -+ goto opthelp; -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ private = (text && !pubin) || (!pubout && !noout) ? 1 : 0; -+ -+ if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { -+ BIO_printf(bio_err, "Error getting passwords\n"); -+ goto end; -+ } -+ if (check && pubin) { -+ BIO_printf(bio_err, "Only private keys can be checked\n"); -+ goto end; -+ } -+ -+ { -+ EVP_PKEY *pkey; -+ -+ if (pubin) { -+ int tmpformat = -1; -+ if (pubin == 2) { -+ if (informat == FORMAT_PEM) -+ tmpformat = FORMAT_PEMRSA; -+ else if (informat == FORMAT_ASN1) -+ tmpformat = FORMAT_ASN1RSA; -+ } else -+ tmpformat = informat; -+ -+ pkey = load_pubkey(infile, tmpformat, 1, passin, e, "Public Key"); -+ } else -+ pkey = load_key(infile, informat, 1, passin, e, "Private Key"); -+ -+ if (pkey != NULL) -+ rsa = EVP_PKEY_get1_RSA(pkey); -+ EVP_PKEY_free(pkey); -+ } -+ -+ if (rsa == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ out = bio_open_owner(outfile, outformat, private); -+ if (out == NULL) -+ goto end; -+ -+ if (text) { -+ assert(pubin || private); -+ if (!RSA_print(out, rsa, 0)) { -+ perror(outfile); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (modulus) { -+ const BIGNUM *n; -+ RSA_get0_key(rsa, &n, NULL, NULL); -+ BIO_printf(out, "Modulus="); -+ BN_print(out, n); -+ BIO_printf(out, "\n"); -+ } -+ -+ if (check) { -+ int r = RSA_check_key(rsa); -+ -+ if (r == 1) -+ BIO_printf(out, "RSA key ok\n"); -+ else if (r == 0) { -+ unsigned long err; -+ -+ while ((err = ERR_peek_error()) != 0 && -+ ERR_GET_LIB(err) == ERR_LIB_RSA && -+ ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY && -+ ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) { -+ BIO_printf(out, "RSA key error: %s\n", -+ ERR_reason_error_string(err)); -+ ERR_get_error(); /* remove e from error stack */ -+ } -+ } else if (r == -1) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (noout) { -+ ret = 0; -+ goto end; -+ } -+ BIO_printf(bio_err, "writing RSA key\n"); -+ if (outformat == FORMAT_ASN1) { -+ if (pubout || pubin) { -+ if (pubout == 2) -+ i = i2d_RSAPublicKey_bio(out, rsa); -+ else -+ i = i2d_RSA_PUBKEY_bio(out, rsa); -+ } else { -+ assert(private); -+ i = i2d_RSAPrivateKey_bio(out, rsa); -+ } -+ } -+ else if (outformat == FORMAT_PEM) { -+ if (pubout || pubin) { -+ if (pubout == 2) -+ i = PEM_write_bio_RSAPublicKey(out, rsa); -+ else -+ i = PEM_write_bio_RSA_PUBKEY(out, rsa); -+ } else { -+ assert(private); -+ i = PEM_write_bio_RSAPrivateKey(out, rsa, -+ enc, NULL, 0, NULL, passout); -+ } -+# ifndef OPENSSL_NO_DSA -+ } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { -+ EVP_PKEY *pk; -+ pk = EVP_PKEY_new(); -+ EVP_PKEY_set1_RSA(pk, rsa); -+ if (outformat == FORMAT_PVK) { -+ if (pubin) { -+ BIO_printf(bio_err, "PVK form impossible with public key input\n"); -+ EVP_PKEY_free(pk); -+ goto end; -+ } -+ assert(private); -+# ifdef OPENSSL_NO_RC4 -+ BIO_printf(bio_err, "PVK format not supported\n"); -+ EVP_PKEY_free(pk); -+ goto end; -+# else -+ i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); -+# endif -+ } else if (pubin || pubout) { -+ i = i2b_PublicKey_bio(out, pk); -+ } else { -+ assert(private); -+ i = i2b_PrivateKey_bio(out, pk); -+ } -+ EVP_PKEY_free(pk); -+# endif -+ } else { -+ BIO_printf(bio_err, "bad output format specified for outfile\n"); -+ goto end; -+ } -+ if (i <= 0) { -+ BIO_printf(bio_err, "unable to write key\n"); -+ ERR_print_errors(bio_err); -+ } else -+ ret = 0; -+ end: -+ release_engine(e); -+ BIO_free_all(out); -+ RSA_free(rsa); -+ OPENSSL_free(passin); -+ OPENSSL_free(passout); -+ return (ret); -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/rsa8192.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/rsa8192.pem -new file mode 100644 -index 0000000..946a6e5 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/rsa8192.pem -@@ -0,0 +1,101 @@ -+-----BEGIN RSA PRIVATE KEY----- -+ -+MIISKAIBAAKCBAEAiQ2f1X6Bte1DKD0OoCBKEikzPW+5w3oXk3WwnE97Wxzy6wJZ -+ebbZC3CZKKBnJeBMrysPf+lK+9+fP6Vm8bp1wvbcSIA59BDrX6irFSuM/bdnkbuF -+MFlDjt+uVrxwoyqfPi2IPot1HQg3l5mdyBqcTWvbOnU2L9HZxJfPUCjfzdTMPrMY -+55/A20XL7tlV2opEfwhy3uVlveQBM0DnZ3MUQfrk+lRRNWv7yE4ScbOfER9fjvOm -+yJc3ZbOa3e+AMGGU9OqJ/fyOl0SGYyP2k23omy/idBV4uOs8QWdnAvq8UOzDdua3 -+tuf5Tn17XBurPJ8juwyPBNispkwwn8BjxAZVPhwUIcxFBg339IxJ9cW0WdVy4nNA -+LWo/8Ahlf+kZNnFNGCPFytU9gGMLMhab9w/rLrwa9qNe4L8Fmu1JxONn1WfhMOKE -+aFmycf2olJsYLgUIGYZrjnYu0p/7P3yhTOv8JIhmK+SzmA/I0xiQoF84rpaQzH2d -+PvxICOA9oQSowou0gLuBSZWm6LiXirg1DZCziU46v33ErQlWM1dSyNaUSzihcV59 -+mVD0nmzboXH75lGiyiZlp8cLbozzoCwvk9rYqpUGSBzbAy0ECCpabGpzO2Ug+oDi -+71e5z4WMpeoR4IS8MaOG/GsJnwaXhiB/gNYfK+8pRADVk5StEAZDE2alSuCbDs0z -+d9zYr4/em5T9VZsLetxRE7pm/Es9yELuViz8/Tm0/8MVdmNYc/xZU1t6qYYFdyQ2 -+wlGDTiNPsjR8yXCkmBjKwqnuleu1X6LaZu3VPhEkXGcyFAquQUkSiMv0Yu74qAe0 -+bQ2v+jjZzP6AM9LUo89cW4Kd8SGD96BdNlAVPNMXoBcIOsZBwsOtETBd4KAyvkXE -+Ob17u+PLl4UPnSxm9ypKZunUNFRPxtKUyjySYnvlGL+kTjAXrIrZwKJqIn0uhnfa -+Ck3o7bU6yVMK22ODxy2/Vi3E0P6k5JLwnrF0VIOBqGhts66qo6mWDP8l6MZHARFd -+pU+nofssVmr8tLKmMmjYGMM5GmKIXRNBs0ksTwFnKRs9AmpE5owC8tTSVdTAkGuS -+os7QwLvyvNzq7BGJiVr0Iy3Dhsl1vzR35acNOrCsDl3DcCQONKJ2sVXV4pD3dBah -+mG3sR/jHgjasffJJ35uiGoAua9dbT7HG/+D0z1SHYaVqH8zO4VZSOnGJh/P9rtxx -+cckFDbiag/JMWig2lbnCjebTtp/BcUsK3TNaDOb7vb0LvbAeRJadd1EFu6PSlH3K -+LykSUPm4UedvUU3cWjqkSY5lITFJkVaIYOv/EljYtK7p7kFZFTaEwMAWxgsXU3pQ -+tTzVmq1gZ4vXPwcUq0zK50Frq0F7SQc21ZsunwIDAQABAoIEADuQAkDEpBausJsS -+PgL1RXuzECPJJJCBxTE+2qx0FoY4hJICCWTORHGmU8nGPE3Ht0wBiNDsULw6KXl9 -+psmzYW6D3qRbpdQebky6fu/KZ5H0XTyGpJGomaXELH5hkwo2gdKB805LSXB+m7p0 -+9o96kSdMkpBLVGtf5iZ8W4rY2LsZmlI9f7taQHSLVt/M8HTz1mTnBRU92QO3zZW6 -+xVa+OrWaFl18u3ZeIaSh2X40tBK68cqstXVD0r2OWuXNKobcQeJW8/XABzBShZ0c -+ihL0lzyqiN4uXrLu+Nbr22b+FU2OODy6dGk3U6/69NvI4piMCPlHsfhHOnFjd1ZW -+RIVywyUlCtLNdcn11CchuRro+0J3c2Ba+i9Cl9r3qzT11xFEGF8/XLyUBBCB+uGf -+1dR/xJQhCA7cXWWLXyI/semxcvTaGpImP6kiIl1MAjHjXZTSdvyw4JmfXyYGhSjI -+P0mw3Xn7FXxJ/os9gOfNKz2nZHjr0q4sgWRYO+4vllkeL0GteZrg4oVaVpmZb7LH -+77afhodLylhijlEtV5skfkPujbBLQk6E5Ez3U/huEt2NLg6guADmwxMxfBRliZO4 -+4Ex/td4cuggpEj3FGJV74qRvdvj/MF/uF7IxC/3WapPIsFBFH4zrJsUYt6u3L68I -+/KC/bfioDeUR/8ANw1DNh+UsnPV3GJIwDkIJKdppi2uXPahJyJQQ8Inps53nn8Gg -+GifS+HnOXNgMoKOJnZ9IDGjXpfjIs8dJNrGfDHF0mH30N2WARq2v/a3cNUC+f8Bq -+HSKQ9YrZopktMunsut8u7ZYbTmjIqJpXCaM0CCrSlzSMTDHFSj2tzLk6+qnxeGxB -+ZwIdShbdeK+0ETG91lE1e9RPQs/uXQP9+uCHJV0YpqQcA6pkCLYJfYpoSMu/Bafy -+AgfVZz6l5tyEnV0wCcbopsQShc1k9xtTbYNF1h9AQHknj6zeDW4iZMvmVeh3RovT -+52OA2R8oLyauF+QaG6x2wUjEx13SJlaBarJZ4seZIOJ+a8+oNzKsbgokXc2cyC9p -+5FAZz1OsOb68o93qD1Xvl7bY97fq2q55L7G1XHPPLtZE5lGiLGDtnAuwY8UPrdpr -+7Mv2yIxB7xVGurXyHb5PvusR88XED6HMPfLBG/55ENHTal7G5mRix+IWSBAIkxA5 -+KZ0j8r5Ng4+wELZhqFQai39799bIAyiV6CEz4kyDXlo0kSSexp8o4iz5sPq5vp6h -+cCb7rdRw7uRnbXrHmXahxoB+ibXaurgV/6B2yurrU/UFoxEp2sHp8LXZGfF6ztY1 -+dMhSQAACK2vGy5yNagbkTHLgVaHicG5zavJBqzCE+lbPlCqhOUQPdOIwvjHNjdS/ -+DL3WV/ECggIBAMbW65wPk/i43nSyeZeYwcHtR1SUJqDXavYfBPC0VRhKz+7DVMFw -+Nwnocn6gITABc445W1yl7U3uww+LGuDlSlFnd8WuiXpVYud9/jeNu6Mu4wvNsnWr -+f4f4ua8CcS03GmqmcbROD2Z6by1AblCZ2UL1kv9cUX1FLVjPP1ESAGKoePt3BmZQ -+J1uJfK8HilNT8dcUlj/5CBi2uHxttDhoG0sxXE/SVsG9OD/Pjme0mj7gdzc6Ztd+ -+TALuvpNQR4pRzfo5XWDZBcEYntcEE3PxYJB1+vnZ8509ew5/yLHTbLjFxIcx71zY -+fhH0gM36Sz7mz37r0+E/QkRkc5bVIDC4LDnWmjpAde6QUx0d218ShNx6sJo4kt5c -+Dd7tEVx8nuX8AIZYgwsOb382anLyFRkkmEdK3gRvwQ6SWR36Ez5L7/mHWODpLAX5 -+mVBKSG4/ccFbc633/g0xHw0Nwajir/klckdakuYPlwF0yAxJSKDLhmNctDhRmxjC -+YP+fISkl5oTvFRzJH6HEyNu8M3ybRvmpPIjM5J5JpnB2IYbohYBR+T6/97C1DKrd -+mzL5PjlrWm0c1/d7LlDoP65fOShDMmj2zCiBAHHOM0Alokx+v5LmMd8NJumZIwGJ -+Rt5OpeMOhowz6j1AjYxYgV7PmJL6Ovpfb775od/aLaUbbwHz2uWIvfF7AoICAQCw -+c7NaO7oJVLJClhYw6OCvjT6oqtgNVWaennnDiJgzY9lv5HEgV0MAG0eYuB3hvj+w -+Y1P9DJxP1D+R+cshYrAFg8yU/3kaYVNI0Bl3ygX0eW1b/0HZTdocs+8kM/9PZQDR -+WrKQoU5lHvqRt99dXlD4NWGI2YQtzdZ8iet9QLqnjwRZabgE96mF01qKisMnFcsh -+KjT7ieheU4J15TZj/mdZRNK126d7e3q/rNj73e5EJ9tkYLcolSr4gpknUMJULSEi -+JH1/Qx7C/mTAMRsN5SkOthnGq0djCNWfPv/3JV0H67Uf5krFlnwLebrgfTYoPPdo -+yO7iBUNJzv6Qh22malLp4P8gzACkD7DGlSTnoB5cLwcjmDGg+i9WrUBbOiVTeQfZ -+kOj1o+Tz35ndpq/DDUVlqliB9krcxva+QHeJPH53EGI+YVg1nD+s/vUDZ3mQMGX9 -+DQou2L8uU6RnWNv/BihGcL8QvS4Ty6QyPOUPpD3zc70JQAEcQk9BxQNaELgJX0IN -+22cYn22tYvElew9G41OpDqzBRcfbdJmKXQ2HcroShutYJQRGUpAXHk24fy6JVkIU -+ojF5U6cwextMja1ZIIZgh9eugIRUeIE7319nQNDzuXWjRCcoBLA25P7wnpHWDRpz -+D9ovXCIvdja74lL5psqobV6L5+fbLPkSgXoImKR0LQKCAgAIC9Jk8kxumCyIVGCP -+PeM5Uby9M3GMuKrfYsn0Y5e97+kSJF1dpojTodBgR2KQar6eVrvXt+8uZCcIjfx8 -+dUrYmHNEUJfHl4T1ESgkX1vkcpVFeQFruZDjk7EP3+1sgvpSroGTZkVBRFsTXbQZ -+FuCv0Pgt1TKG+zGmklxhj3TsiRy8MEjWAxBUp++ftZJnZNI4feDGnfEx7tLwVhAg -+6DWSiWDO6hgQpvOLwX5lu+0x9itc1MQsnDO/OqIDnBAJDN5k7cVVkfKlqbVjxgpz -+eqUJs3yAd81f44kDQTCB4ahYocgeIGsrOqd/WoGL1EEPPo/O9wQP7VtlIRt8UwuG -+bS18+a4sBUfAa56xYu/pnPo7YcubsgZfcSIujzFQqMpVTClJRnOnEuJ4J1+PXzRz -+XAO9fs4VJ+CMEmgAyonUz4Xadxulnknlw//sO9VKgM69oFHCDHL/XamAAbqAdwvf -+7R/+uy+Ol7romC0wMhb6SsIZazrvvH2mNtduAKZ638nAP1x/WbQp+6iVG7yJok7w -+82Q7tO7baOePTXh12Rrt4mNPor0HLYxhra4GFgfqkumJ2Mz0esuZAozxJXFOq8ly -+beo9CVtXP5zbT6qNpeNismX6PLICaev8t+1iOZSE56WSLtefuuj/cOVrTMNDz1Rr -+pUkEVV2zjUSjlcScM538A9iL2QKCAgBLbBk0r6T0ihRsK9UucMxhnYEz/Vq+UEu9 -+70Vi1AciqEJv9nh4d3Q3HnH7EHANZxG4Jqzm1DYYVUQa9GfkTFeq88xFv/GW2hUM -+YY8RSfRDrIeXNEOETCe37x2AHw25dRXlZtw+wARPau91y9+Y/FCl18NqCHfcUEin -+ERjsf/eI2bPlODAlR2tZvZ7M60VBdqpN8cmV3zvI3e88z43xLfQlDyr1+v7a5Evy -+lEJnXlSTI2o+vKxtl103vjMSwA1gh63K90gBVsJWXQDZueOzi8mB9UqNRfcMmOEe -+4YHttTXPxeu0x+4cCRfam9zKShsVFgI28vRQ/ijl6qmbQ5gV8wqf18GV1j1L4z0P -+lP6iVynDA4MMrug/w9DqPsHsfK0pwekeETfSj4y0xVXyjWZBfHG2ZBrS6mDTf+RG -+LC4sJgR0hjdILLnUqIX7PzuhieBHRrjBcopwvcryVWRHnI7kslAS0+yHjiWc5oW3 -+x5mtlum4HzelNYuD9cAE/95P6CeSMfp9CyIE/KSX4VvsRm6gQVkoQRKMxnQIFQ3w -+O5gl1l88vhjoo2HxYScgCp70BsDwiUNTqIR3NM+ZBHYFweVf3Gwz5LzHZT2rEZtD -+6VXRP75Q/2wOLnqCO4bK4BUs6sqxcQZmOldruPkPynrY0oPfHHExjxZDvQu4/r80 -+Ls3n0L8yvQKCAgEAnYWS6EikwaQNpJEfiUnOlglgFz4EE1eVkrDbBY4J3oPU+doz -+DrqmsvgpSZIAfd2MUbkN4pOMsMTjbeIYWDnZDa1RoctKs3FhwFPHwAjQpznab4mn -+Bp81FMHM40qyb0NaNuFRwghdXvoQvBBX1p8oEnFzDRvTiuS/vTPTA8KDY8IeRp8R -+oGzKHpfziNwq/URpqj7pwi9odNjGZvR2IwYw9jCLPIqaEbMoSOdI0mg4MoYyqP4q -+nm7d4wqSDwrYxiXZ6f3nYpkhEY1lb0Wbksp1ig8sKSF4nDZRGK1RSfE+6gjBp94H -+X/Wog6Zb6NC9ZpusTiDLvuIUXcyUJvmHiWjSNqiTv8jurlwEsgSwhziEQfqLrtdV -+QI3PRMolBkD1iCk+HFE53r05LMf1bp3r4MS+naaQrLbIrl1kgDNGwVdgS+SCM7Bg -+TwEgE67iOb2iIoUpon/NyP4LesMzvdpsu2JFlfz13PmmQ34mFI7tWvOb3NA5DP3c -+46C6SaWI0TD9B11nJbHGTYN3Si9n0EBgoDJEXUKeh3km9O47dgvkSug4WzhYsvrE -+rMlMLtKfp2w8HlMZpsUlToNCx6CI+tJrohzcs3BAVAbjFAXRKWGijB1rxwyDdHPv -+I+/wJTNaRNPQ1M0SwtEL/zJd21y3KSPn4eL+GP3efhlDSjtlDvZqkdAUsU8= -+-----END RSA PRIVATE KEY----- -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/rsautl.c b/CryptoPkg/Library/OpensslLib/openssl/apps/rsautl.c -new file mode 100644 -index 0000000..d527bf4 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/rsautl.c -@@ -0,0 +1,278 @@ -+/* -+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#ifdef OPENSSL_NO_RSA -+NON_EMPTY_TRANSLATION_UNIT -+#else -+ -+# include "apps.h" -+# include -+# include -+# include -+# include -+ -+# define RSA_SIGN 1 -+# define RSA_VERIFY 2 -+# define RSA_ENCRYPT 3 -+# define RSA_DECRYPT 4 -+ -+# define KEY_PRIVKEY 1 -+# define KEY_PUBKEY 2 -+# define KEY_CERT 3 -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_ENGINE, OPT_IN, OPT_OUT, OPT_ASN1PARSE, OPT_HEXDUMP, -+ OPT_RAW, OPT_OAEP, OPT_SSL, OPT_PKCS, OPT_X931, -+ OPT_SIGN, OPT_VERIFY, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT, -+ OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM -+} OPTION_CHOICE; -+ -+OPTIONS rsautl_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"in", OPT_IN, '<', "Input file"}, -+ {"out", OPT_OUT, '>', "Output file"}, -+ {"inkey", OPT_INKEY, 's', "Input key"}, -+ {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"}, -+ {"pubin", OPT_PUBIN, '-', "Input is an RSA public"}, -+ {"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"}, -+ {"ssl", OPT_SSL, '-', "Use SSL v2 padding"}, -+ {"raw", OPT_RAW, '-', "Use no padding"}, -+ {"pkcs", OPT_PKCS, '-', "Use PKCS#1 v1.5 padding (default)"}, -+ {"oaep", OPT_OAEP, '-', "Use PKCS#1 OAEP"}, -+ {"sign", OPT_SIGN, '-', "Sign with private key"}, -+ {"verify", OPT_VERIFY, '-', "Verify with public key"}, -+ {"asn1parse", OPT_ASN1PARSE, '-', -+ "Run output through asn1parse; useful with -verify"}, -+ {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, -+ {"x931", OPT_X931, '-', "Use ANSI X9.31 padding"}, -+ {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, -+ {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"}, -+ {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"}, -+ {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, -+# ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+# endif -+ {NULL} -+}; -+ -+int rsautl_main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ ENGINE *e = NULL; -+ EVP_PKEY *pkey = NULL; -+ RSA *rsa = NULL; -+ X509 *x; -+ char *infile = NULL, *outfile = NULL, *keyfile = NULL; -+ char *passinarg = NULL, *passin = NULL, *prog; -+ char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; -+ unsigned char *rsa_in = NULL, *rsa_out = NULL, pad = RSA_PKCS1_PADDING; -+ int rsa_inlen, keyformat = FORMAT_PEM, keysize, ret = 1; -+ int rsa_outlen = 0, hexdump = 0, asn1parse = 0, need_priv = 0, rev = 0; -+ OPTION_CHOICE o; -+ -+ prog = opt_init(argc, argv, rsautl_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(rsautl_options); -+ ret = 0; -+ goto end; -+ case OPT_KEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyformat)) -+ goto opthelp; -+ break; -+ case OPT_IN: -+ infile = opt_arg(); -+ break; -+ case OPT_OUT: -+ outfile = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 0); -+ break; -+ case OPT_ASN1PARSE: -+ asn1parse = 1; -+ break; -+ case OPT_HEXDUMP: -+ hexdump = 1; -+ break; -+ case OPT_RAW: -+ pad = RSA_NO_PADDING; -+ break; -+ case OPT_OAEP: -+ pad = RSA_PKCS1_OAEP_PADDING; -+ break; -+ case OPT_SSL: -+ pad = RSA_SSLV23_PADDING; -+ break; -+ case OPT_PKCS: -+ pad = RSA_PKCS1_PADDING; -+ break; -+ case OPT_X931: -+ pad = RSA_X931_PADDING; -+ break; -+ case OPT_SIGN: -+ rsa_mode = RSA_SIGN; -+ need_priv = 1; -+ break; -+ case OPT_VERIFY: -+ rsa_mode = RSA_VERIFY; -+ break; -+ case OPT_REV: -+ rev = 1; -+ break; -+ case OPT_ENCRYPT: -+ rsa_mode = RSA_ENCRYPT; -+ break; -+ case OPT_DECRYPT: -+ rsa_mode = RSA_DECRYPT; -+ need_priv = 1; -+ break; -+ case OPT_PUBIN: -+ key_type = KEY_PUBKEY; -+ break; -+ case OPT_CERTIN: -+ key_type = KEY_CERT; -+ break; -+ case OPT_INKEY: -+ keyfile = opt_arg(); -+ break; -+ case OPT_PASSIN: -+ passinarg = opt_arg(); -+ break; -+ } -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ if (need_priv && (key_type != KEY_PRIVKEY)) { -+ BIO_printf(bio_err, "A private key is needed for this operation\n"); -+ goto end; -+ } -+ -+ if (!app_passwd(passinarg, NULL, &passin, NULL)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ -+/* FIXME: seed PRNG only if needed */ -+ app_RAND_load_file(NULL, 0); -+ -+ switch (key_type) { -+ case KEY_PRIVKEY: -+ pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key"); -+ break; -+ -+ case KEY_PUBKEY: -+ pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "Public Key"); -+ break; -+ -+ case KEY_CERT: -+ x = load_cert(keyfile, keyformat, "Certificate"); -+ if (x) { -+ pkey = X509_get_pubkey(x); -+ X509_free(x); -+ } -+ break; -+ } -+ -+ if (!pkey) { -+ return 1; -+ } -+ -+ rsa = EVP_PKEY_get1_RSA(pkey); -+ EVP_PKEY_free(pkey); -+ -+ if (!rsa) { -+ BIO_printf(bio_err, "Error getting RSA key\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ in = bio_open_default(infile, 'r', FORMAT_BINARY); -+ if (in == NULL) -+ goto end; -+ out = bio_open_default(outfile, 'w', FORMAT_BINARY); -+ if (out == NULL) -+ goto end; -+ -+ keysize = RSA_size(rsa); -+ -+ rsa_in = app_malloc(keysize * 2, "hold rsa key"); -+ rsa_out = app_malloc(keysize, "output rsa key"); -+ -+ /* Read the input data */ -+ rsa_inlen = BIO_read(in, rsa_in, keysize * 2); -+ if (rsa_inlen < 0) { -+ BIO_printf(bio_err, "Error reading input Data\n"); -+ goto end; -+ } -+ if (rev) { -+ int i; -+ unsigned char ctmp; -+ for (i = 0; i < rsa_inlen / 2; i++) { -+ ctmp = rsa_in[i]; -+ rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; -+ rsa_in[rsa_inlen - 1 - i] = ctmp; -+ } -+ } -+ switch (rsa_mode) { -+ -+ case RSA_VERIFY: -+ rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); -+ break; -+ -+ case RSA_SIGN: -+ rsa_outlen = -+ RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); -+ break; -+ -+ case RSA_ENCRYPT: -+ rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); -+ break; -+ -+ case RSA_DECRYPT: -+ rsa_outlen = -+ RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); -+ break; -+ } -+ -+ if (rsa_outlen < 0) { -+ BIO_printf(bio_err, "RSA operation error\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ ret = 0; -+ if (asn1parse) { -+ if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { -+ ERR_print_errors(bio_err); -+ } -+ } else if (hexdump) -+ BIO_dump(out, (char *)rsa_out, rsa_outlen); -+ else -+ BIO_write(out, rsa_out, rsa_outlen); -+ end: -+ RSA_free(rsa); -+ release_engine(e); -+ BIO_free(in); -+ BIO_free_all(out); -+ OPENSSL_free(rsa_in); -+ OPENSSL_free(rsa_out); -+ OPENSSL_free(passin); -+ return ret; -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/s1024key.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/s1024key.pem -new file mode 100644 -index 0000000..19e0403 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/s1024key.pem -@@ -0,0 +1,15 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIICXgIBAAKBgQCzEfU8E+ZGTGtHXV5XhvM2Lg32fXUIjydXb34BGVPX6oN7+aNV -+S9eWayvW/+9/vUb0aCqilJrpFesgItV2T8VhhjOE++XUz46uNpcMU7wHMEAXUufP -+pztpFm8ZEk2tFKvadkSSoN8lb11juvZVkSkPlB65pFhSe4QKSp6J4HrkYwIDAQAB -+AoGBAKy8jvb0Lzby8q11yNLf7+78wCVdYi7ugMHcYA1JVFK8+zb1WfSm44FLQo/0 -+dSChAjgz36TTexeLODPYxleJndjVcOMVzsLJjSM8dLpXsTS4FCeMbhw2s2u+xqKY -+bbPWfk+HOTyJjfnkcC5Nbg44eOmruq0gSmBeUXVM5UntlTnxAkEA7TGCA3h7kx5E -+Bl4zl2pc3gPAGt+dyfk5Po9mGJUUXhF5p2zueGmYWW74TmOWB1kzt4QRdYMzFePq -+zfDNXEa1CwJBAMFErdY0xp0UJ13WwBbUTk8rujqQdHtjw0klhpbuKkjxu2hN0wwM -+6p0D9qxF7JHaghqVRI0fAW/EE0OzdHMR9QkCQQDNR26dMFXKsoPu+vItljj/UEGf -+QG7gERiQ4yxaFBPHgdpGo0kT31eh9x9hQGDkxTe0GNG/YSgCRvm8+C3TMcKXAkBD -+dhGn36wkUFCddMSAM4NSJ1VN8/Z0y5HzCmI8dM3VwGtGMUQlxKxwOl30LEQzdS5M -+0SWojNYXiT2gOBfBwtbhAkEAhafl5QEOIgUz+XazS/IlZ8goNKdDVfYgK3mHHjvv -+nY5G+AuGebdNkXJr4KSWxDcN+C2i47zuj4QXA16MAOandA== -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/s1024req.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/s1024req.pem -new file mode 100644 -index 0000000..bb75e7e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/s1024req.pem -@@ -0,0 +1,11 @@ -+-----BEGIN CERTIFICATE REQUEST----- -+MIIBojCCAQsCAQAwZDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQx -+GjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMSQwIgYDVQQDExtTZXJ2ZXIgdGVz -+dCBjZXJ0ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALMR -+9TwT5kZMa0ddXleG8zYuDfZ9dQiPJ1dvfgEZU9fqg3v5o1VL15ZrK9b/73+9RvRo -+KqKUmukV6yAi1XZPxWGGM4T75dTPjq42lwxTvAcwQBdS58+nO2kWbxkSTa0Uq9p2 -+RJKg3yVvXWO69lWRKQ+UHrmkWFJ7hApKnongeuRjAgMBAAEwDQYJKoZIhvcNAQEE -+BQADgYEAStHlk4pBbwiNeQ2/PKTPPXzITYC8Gn0XMbrU94e/6JIKiO7aArq9Espq -+nrBSvC14dHcNl6NNvnkEKdQ7hAkcACfBbnOXA/oQvMBd4GD78cH3k0jVDoVUEjil -+frLfWlckW6WzpTktt0ZPDdAjJCmKVh0ABHimi7Bo9FC3wIGIe5M= -+-----END CERTIFICATE REQUEST----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/s512-key.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/s512-key.pem -new file mode 100644 -index 0000000..0e3ff2d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/s512-key.pem -@@ -0,0 +1,9 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIBPAIBAAJBAJ+zw4Qnlf8SMVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVD -+TGiXav6ooKXfX3j/7tdkuD8Ey2//Kv7+ue0CAwEAAQJAN6W31vDEP2DjdqhzCDDu -+OA4NACqoiFqyblo7yc2tM4h4xMbC3Yx5UKMN9ZkCtX0gzrz6DyF47bdKcWBzNWCj -+gQIhANEoojVt7hq+SQ6MCN6FTAysGgQf56Q3TYoJMoWvdiXVAiEAw3e3rc+VJpOz -+rHuDo6bgpjUAAXM+v3fcpsfZSNO6V7kCIQCtbVjanpUwvZkMI9by02oUk9taki3b -+PzPfAfNPYAbCJQIhAJXNQDWyqwn/lGmR11cqY2y9nZ1+5w3yHGatLrcDnQHxAiEA -+vnlEGo8K85u+KwIOimM48ZG8oTk7iFdkqLJR1utT3aU= -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/s512-req.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/s512-req.pem -new file mode 100644 -index 0000000..ea314be ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/s512-req.pem -@@ -0,0 +1,8 @@ -+-----BEGIN CERTIFICATE REQUEST----- -+MIIBGzCBxgIBADBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEa -+MBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0 -+IGNlcnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8S -+MVIPFe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8E -+y2//Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAANBAAB+uQi+qwn6qRSHB8EUTvsm -+5TNTHzYDeN39nyIbZNX2s0se3Srn2Bxft5YCwD3moFZ9QoyDHxE0h6qLX5yjD+8= -+-----END CERTIFICATE REQUEST----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/s_apps.h b/CryptoPkg/Library/OpensslLib/openssl/apps/s_apps.h -new file mode 100644 -index 0000000..c47932b ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/s_apps.h -@@ -0,0 +1,102 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+ -+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) -+# include -+#endif -+ -+#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32) -+# define _kbhit kbhit -+#endif -+ -+#if defined(OPENSSL_SYS_VMS) && !defined(FD_SET) -+/* -+ * VAX C does not defined fd_set and friends, but it's actually quite simple -+ */ -+/* These definitions are borrowed from SOCKETSHR. /Richard Levitte */ -+# define MAX_NOFILE 32 -+# define NBBY 8 /* number of bits in a byte */ -+ -+# ifndef FD_SETSIZE -+# define FD_SETSIZE MAX_NOFILE -+# endif /* FD_SETSIZE */ -+ -+/* How many things we'll allow select to use. 0 if unlimited */ -+# define MAXSELFD MAX_NOFILE -+typedef int fd_mask; /* int here! VMS prototypes int, not long */ -+# define NFDBITS (sizeof(fd_mask) * NBBY)/* bits per mask (power of 2!) */ -+# define NFDSHIFT 5 /* Shift based on above */ -+ -+typedef fd_mask fd_set; -+# define FD_SET(n, p) (*(p) |= (1 << ((n) % NFDBITS))) -+# define FD_CLR(n, p) (*(p) &= ~(1 << ((n) % NFDBITS))) -+# define FD_ISSET(n, p) (*(p) & (1 << ((n) % NFDBITS))) -+# define FD_ZERO(p) memset((p), 0, sizeof(*(p))) -+#endif -+ -+#define PORT "4433" -+#define PROTOCOL "tcp" -+ -+typedef int (*do_server_cb)(int s, int stype, unsigned char *context); -+int do_server(int *accept_sock, const char *host, const char *port, -+ int family, int type, -+ do_server_cb cb, -+ unsigned char *context, int naccept); -+#ifdef HEADER_X509_H -+int verify_callback(int ok, X509_STORE_CTX *ctx); -+#endif -+#ifdef HEADER_SSL_H -+int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); -+int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, -+ STACK_OF(X509) *chain, int build_chain); -+int ssl_print_sigalgs(BIO *out, SSL *s); -+int ssl_print_point_formats(BIO *out, SSL *s); -+int ssl_print_curves(BIO *out, SSL *s, int noshared); -+#endif -+int ssl_print_tmp_key(BIO *out, SSL *s); -+int init_client(int *sock, const char *host, const char *port, -+ int family, int type); -+int should_retry(int i); -+ -+long bio_dump_callback(BIO *bio, int cmd, const char *argp, -+ int argi, long argl, long ret); -+ -+#ifdef HEADER_SSL_H -+void apps_ssl_info_callback(const SSL *s, int where, int ret); -+void msg_cb(int write_p, int version, int content_type, const void *buf, -+ size_t len, SSL *ssl, void *arg); -+void tlsext_cb(SSL *s, int client_server, int type, const unsigned char *data, -+ int len, void *arg); -+#endif -+ -+int generate_cookie_callback(SSL *ssl, unsigned char *cookie, -+ unsigned int *cookie_len); -+int verify_cookie_callback(SSL *ssl, const unsigned char *cookie, -+ unsigned int cookie_len); -+ -+typedef struct ssl_excert_st SSL_EXCERT; -+ -+void ssl_ctx_set_excert(SSL_CTX *ctx, SSL_EXCERT *exc); -+void ssl_excert_free(SSL_EXCERT *exc); -+int args_excert(int option, SSL_EXCERT **pexc); -+int load_excert(SSL_EXCERT **pexc); -+void print_verify_detail(SSL *s, BIO *bio); -+void print_ssl_summary(SSL *s); -+#ifdef HEADER_SSL_H -+int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, SSL_CTX *ctx); -+int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, -+ int crl_download); -+int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, -+ const char *vfyCAfile, const char *chCApath, -+ const char *chCAfile, STACK_OF(X509_CRL) *crls, -+ int crl_download); -+void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose); -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/s_cb.c b/CryptoPkg/Library/OpensslLib/openssl/apps/s_cb.c -new file mode 100644 -index 0000000..e0acd51 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/s_cb.c -@@ -0,0 +1,1335 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* callback functions used by s_client, s_server, and s_time */ -+#include -+#include -+#include /* for memcpy() and strcmp() */ -+#define USE_SOCKETS -+#include "apps.h" -+#undef USE_SOCKETS -+#include -+#include -+#include -+#include -+#include -+#ifndef OPENSSL_NO_DH -+# include -+#endif -+#include "s_apps.h" -+ -+#define COOKIE_SECRET_LENGTH 16 -+ -+VERIFY_CB_ARGS verify_args = { 0, 0, X509_V_OK, 0 }; -+ -+#ifndef OPENSSL_NO_SOCK -+static unsigned char cookie_secret[COOKIE_SECRET_LENGTH]; -+static int cookie_initialized = 0; -+#endif -+ -+static const char *lookup(int val, const STRINT_PAIR* list, const char* def) -+{ -+ for ( ; list->name; ++list) -+ if (list->retval == val) -+ return list->name; -+ return def; -+} -+ -+int verify_callback(int ok, X509_STORE_CTX *ctx) -+{ -+ X509 *err_cert; -+ int err, depth; -+ -+ err_cert = X509_STORE_CTX_get_current_cert(ctx); -+ err = X509_STORE_CTX_get_error(ctx); -+ depth = X509_STORE_CTX_get_error_depth(ctx); -+ -+ if (!verify_args.quiet || !ok) { -+ BIO_printf(bio_err, "depth=%d ", depth); -+ if (err_cert) { -+ X509_NAME_print_ex(bio_err, -+ X509_get_subject_name(err_cert), -+ 0, XN_FLAG_ONELINE); -+ BIO_puts(bio_err, "\n"); -+ } else -+ BIO_puts(bio_err, "\n"); -+ } -+ if (!ok) { -+ BIO_printf(bio_err, "verify error:num=%d:%s\n", err, -+ X509_verify_cert_error_string(err)); -+ if (verify_args.depth >= depth) { -+ if (!verify_args.return_error) -+ ok = 1; -+ verify_args.error = err; -+ } else { -+ ok = 0; -+ verify_args.error = X509_V_ERR_CERT_CHAIN_TOO_LONG; -+ } -+ } -+ switch (err) { -+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: -+ BIO_puts(bio_err, "issuer= "); -+ X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), -+ 0, XN_FLAG_ONELINE); -+ BIO_puts(bio_err, "\n"); -+ break; -+ case X509_V_ERR_CERT_NOT_YET_VALID: -+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: -+ BIO_printf(bio_err, "notBefore="); -+ ASN1_TIME_print(bio_err, X509_get0_notBefore(err_cert)); -+ BIO_printf(bio_err, "\n"); -+ break; -+ case X509_V_ERR_CERT_HAS_EXPIRED: -+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: -+ BIO_printf(bio_err, "notAfter="); -+ ASN1_TIME_print(bio_err, X509_get0_notAfter(err_cert)); -+ BIO_printf(bio_err, "\n"); -+ break; -+ case X509_V_ERR_NO_EXPLICIT_POLICY: -+ if (!verify_args.quiet) -+ policies_print(ctx); -+ break; -+ } -+ if (err == X509_V_OK && ok == 2 && !verify_args.quiet) -+ policies_print(ctx); -+ if (ok && !verify_args.quiet) -+ BIO_printf(bio_err, "verify return:%d\n", ok); -+ return (ok); -+} -+ -+int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file) -+{ -+ if (cert_file != NULL) { -+ if (SSL_CTX_use_certificate_file(ctx, cert_file, -+ SSL_FILETYPE_PEM) <= 0) { -+ BIO_printf(bio_err, "unable to get certificate from '%s'\n", -+ cert_file); -+ ERR_print_errors(bio_err); -+ return (0); -+ } -+ if (key_file == NULL) -+ key_file = cert_file; -+ if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) { -+ BIO_printf(bio_err, "unable to get private key from '%s'\n", -+ key_file); -+ ERR_print_errors(bio_err); -+ return (0); -+ } -+ -+ /* -+ * If we are using DSA, we can copy the parameters from the private -+ * key -+ */ -+ -+ /* -+ * Now we know that a key and cert have been set against the SSL -+ * context -+ */ -+ if (!SSL_CTX_check_private_key(ctx)) { -+ BIO_printf(bio_err, -+ "Private key does not match the certificate public key\n"); -+ return (0); -+ } -+ } -+ return (1); -+} -+ -+int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, -+ STACK_OF(X509) *chain, int build_chain) -+{ -+ int chflags = chain ? SSL_BUILD_CHAIN_FLAG_CHECK : 0; -+ if (cert == NULL) -+ return 1; -+ if (SSL_CTX_use_certificate(ctx, cert) <= 0) { -+ BIO_printf(bio_err, "error setting certificate\n"); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ -+ if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) { -+ BIO_printf(bio_err, "error setting private key\n"); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ -+ /* -+ * Now we know that a key and cert have been set against the SSL context -+ */ -+ if (!SSL_CTX_check_private_key(ctx)) { -+ BIO_printf(bio_err, -+ "Private key does not match the certificate public key\n"); -+ return 0; -+ } -+ if (chain && !SSL_CTX_set1_chain(ctx, chain)) { -+ BIO_printf(bio_err, "error setting certificate chain\n"); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ if (build_chain && !SSL_CTX_build_cert_chain(ctx, chflags)) { -+ BIO_printf(bio_err, "error building certificate chain\n"); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ return 1; -+} -+ -+static STRINT_PAIR cert_type_list[] = { -+ {"RSA sign", TLS_CT_RSA_SIGN}, -+ {"DSA sign", TLS_CT_DSS_SIGN}, -+ {"RSA fixed DH", TLS_CT_RSA_FIXED_DH}, -+ {"DSS fixed DH", TLS_CT_DSS_FIXED_DH}, -+ {"ECDSA sign", TLS_CT_ECDSA_SIGN}, -+ {"RSA fixed ECDH", TLS_CT_RSA_FIXED_ECDH}, -+ {"ECDSA fixed ECDH", TLS_CT_ECDSA_FIXED_ECDH}, -+ {"GOST01 Sign", TLS_CT_GOST01_SIGN}, -+ {NULL} -+}; -+ -+static void ssl_print_client_cert_types(BIO *bio, SSL *s) -+{ -+ const unsigned char *p; -+ int i; -+ int cert_type_num = SSL_get0_certificate_types(s, &p); -+ if (!cert_type_num) -+ return; -+ BIO_puts(bio, "Client Certificate Types: "); -+ for (i = 0; i < cert_type_num; i++) { -+ unsigned char cert_type = p[i]; -+ const char *cname = lookup((int)cert_type, cert_type_list, NULL); -+ -+ if (i) -+ BIO_puts(bio, ", "); -+ if (cname) -+ BIO_puts(bio, cname); -+ else -+ BIO_printf(bio, "UNKNOWN (%d),", cert_type); -+ } -+ BIO_puts(bio, "\n"); -+} -+ -+static int do_print_sigalgs(BIO *out, SSL *s, int shared) -+{ -+ int i, nsig, client; -+ client = SSL_is_server(s) ? 0 : 1; -+ if (shared) -+ nsig = SSL_get_shared_sigalgs(s, -1, NULL, NULL, NULL, NULL, NULL); -+ else -+ nsig = SSL_get_sigalgs(s, -1, NULL, NULL, NULL, NULL, NULL); -+ if (nsig == 0) -+ return 1; -+ -+ if (shared) -+ BIO_puts(out, "Shared "); -+ -+ if (client) -+ BIO_puts(out, "Requested "); -+ BIO_puts(out, "Signature Algorithms: "); -+ for (i = 0; i < nsig; i++) { -+ int hash_nid, sign_nid; -+ unsigned char rhash, rsign; -+ const char *sstr = NULL; -+ if (shared) -+ SSL_get_shared_sigalgs(s, i, &sign_nid, &hash_nid, NULL, -+ &rsign, &rhash); -+ else -+ SSL_get_sigalgs(s, i, &sign_nid, &hash_nid, NULL, &rsign, &rhash); -+ if (i) -+ BIO_puts(out, ":"); -+ if (sign_nid == EVP_PKEY_RSA) -+ sstr = "RSA"; -+ else if (sign_nid == EVP_PKEY_DSA) -+ sstr = "DSA"; -+ else if (sign_nid == EVP_PKEY_EC) -+ sstr = "ECDSA"; -+ if (sstr) -+ BIO_printf(out, "%s+", sstr); -+ else -+ BIO_printf(out, "0x%02X+", (int)rsign); -+ if (hash_nid != NID_undef) -+ BIO_printf(out, "%s", OBJ_nid2sn(hash_nid)); -+ else -+ BIO_printf(out, "0x%02X", (int)rhash); -+ } -+ BIO_puts(out, "\n"); -+ return 1; -+} -+ -+int ssl_print_sigalgs(BIO *out, SSL *s) -+{ -+ int mdnid; -+ if (!SSL_is_server(s)) -+ ssl_print_client_cert_types(out, s); -+ do_print_sigalgs(out, s, 0); -+ do_print_sigalgs(out, s, 1); -+ if (SSL_get_peer_signature_nid(s, &mdnid)) -+ BIO_printf(out, "Peer signing digest: %s\n", OBJ_nid2sn(mdnid)); -+ return 1; -+} -+ -+#ifndef OPENSSL_NO_EC -+int ssl_print_point_formats(BIO *out, SSL *s) -+{ -+ int i, nformats; -+ const char *pformats; -+ nformats = SSL_get0_ec_point_formats(s, &pformats); -+ if (nformats <= 0) -+ return 1; -+ BIO_puts(out, "Supported Elliptic Curve Point Formats: "); -+ for (i = 0; i < nformats; i++, pformats++) { -+ if (i) -+ BIO_puts(out, ":"); -+ switch (*pformats) { -+ case TLSEXT_ECPOINTFORMAT_uncompressed: -+ BIO_puts(out, "uncompressed"); -+ break; -+ -+ case TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime: -+ BIO_puts(out, "ansiX962_compressed_prime"); -+ break; -+ -+ case TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2: -+ BIO_puts(out, "ansiX962_compressed_char2"); -+ break; -+ -+ default: -+ BIO_printf(out, "unknown(%d)", (int)*pformats); -+ break; -+ -+ } -+ } -+ BIO_puts(out, "\n"); -+ return 1; -+} -+ -+int ssl_print_curves(BIO *out, SSL *s, int noshared) -+{ -+ int i, ncurves, *curves, nid; -+ const char *cname; -+ -+ ncurves = SSL_get1_curves(s, NULL); -+ if (ncurves <= 0) -+ return 1; -+ curves = app_malloc(ncurves * sizeof(int), "curves to print"); -+ SSL_get1_curves(s, curves); -+ -+ BIO_puts(out, "Supported Elliptic Curves: "); -+ for (i = 0; i < ncurves; i++) { -+ if (i) -+ BIO_puts(out, ":"); -+ nid = curves[i]; -+ /* If unrecognised print out hex version */ -+ if (nid & TLSEXT_nid_unknown) -+ BIO_printf(out, "0x%04X", nid & 0xFFFF); -+ else { -+ /* Use NIST name for curve if it exists */ -+ cname = EC_curve_nid2nist(nid); -+ if (!cname) -+ cname = OBJ_nid2sn(nid); -+ BIO_printf(out, "%s", cname); -+ } -+ } -+ OPENSSL_free(curves); -+ if (noshared) { -+ BIO_puts(out, "\n"); -+ return 1; -+ } -+ BIO_puts(out, "\nShared Elliptic curves: "); -+ ncurves = SSL_get_shared_curve(s, -1); -+ for (i = 0; i < ncurves; i++) { -+ if (i) -+ BIO_puts(out, ":"); -+ nid = SSL_get_shared_curve(s, i); -+ cname = EC_curve_nid2nist(nid); -+ if (!cname) -+ cname = OBJ_nid2sn(nid); -+ BIO_printf(out, "%s", cname); -+ } -+ if (ncurves == 0) -+ BIO_puts(out, "NONE"); -+ BIO_puts(out, "\n"); -+ return 1; -+} -+#endif -+int ssl_print_tmp_key(BIO *out, SSL *s) -+{ -+ EVP_PKEY *key; -+ if (!SSL_get_server_tmp_key(s, &key)) -+ return 1; -+ BIO_puts(out, "Server Temp Key: "); -+ switch (EVP_PKEY_id(key)) { -+ case EVP_PKEY_RSA: -+ BIO_printf(out, "RSA, %d bits\n", EVP_PKEY_bits(key)); -+ break; -+ -+ case EVP_PKEY_DH: -+ BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(key)); -+ break; -+#ifndef OPENSSL_NO_EC -+ case EVP_PKEY_EC: -+ { -+ EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key); -+ int nid; -+ const char *cname; -+ nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); -+ EC_KEY_free(ec); -+ cname = EC_curve_nid2nist(nid); -+ if (!cname) -+ cname = OBJ_nid2sn(nid); -+ BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(key)); -+ } -+ break; -+#endif -+ default: -+ BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_id(key)), -+ EVP_PKEY_bits(key)); -+ } -+ EVP_PKEY_free(key); -+ return 1; -+} -+ -+long bio_dump_callback(BIO *bio, int cmd, const char *argp, -+ int argi, long argl, long ret) -+{ -+ BIO *out; -+ -+ out = (BIO *)BIO_get_callback_arg(bio); -+ if (out == NULL) -+ return (ret); -+ -+ if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) { -+ BIO_printf(out, "read from %p [%p] (%lu bytes => %ld (0x%lX))\n", -+ (void *)bio, (void *)argp, (unsigned long)argi, ret, ret); -+ BIO_dump(out, argp, (int)ret); -+ return (ret); -+ } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) { -+ BIO_printf(out, "write to %p [%p] (%lu bytes => %ld (0x%lX))\n", -+ (void *)bio, (void *)argp, (unsigned long)argi, ret, ret); -+ BIO_dump(out, argp, (int)ret); -+ } -+ return (ret); -+} -+ -+void apps_ssl_info_callback(const SSL *s, int where, int ret) -+{ -+ const char *str; -+ int w; -+ -+ w = where & ~SSL_ST_MASK; -+ -+ if (w & SSL_ST_CONNECT) -+ str = "SSL_connect"; -+ else if (w & SSL_ST_ACCEPT) -+ str = "SSL_accept"; -+ else -+ str = "undefined"; -+ -+ if (where & SSL_CB_LOOP) { -+ BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s)); -+ } else if (where & SSL_CB_ALERT) { -+ str = (where & SSL_CB_READ) ? "read" : "write"; -+ BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n", -+ str, -+ SSL_alert_type_string_long(ret), -+ SSL_alert_desc_string_long(ret)); -+ } else if (where & SSL_CB_EXIT) { -+ if (ret == 0) -+ BIO_printf(bio_err, "%s:failed in %s\n", -+ str, SSL_state_string_long(s)); -+ else if (ret < 0) { -+ BIO_printf(bio_err, "%s:error in %s\n", -+ str, SSL_state_string_long(s)); -+ } -+ } -+} -+ -+static STRINT_PAIR ssl_versions[] = { -+ {"SSL 3.0", SSL3_VERSION}, -+ {"TLS 1.0", TLS1_VERSION}, -+ {"TLS 1.1", TLS1_1_VERSION}, -+ {"TLS 1.2", TLS1_2_VERSION}, -+ {"DTLS 1.0", DTLS1_VERSION}, -+ {"DTLS 1.0 (bad)", DTLS1_BAD_VER}, -+ {NULL} -+}; -+static STRINT_PAIR alert_types[] = { -+ {" close_notify", 0}, -+ {" unexpected_message", 10}, -+ {" bad_record_mac", 20}, -+ {" decryption_failed", 21}, -+ {" record_overflow", 22}, -+ {" decompression_failure", 30}, -+ {" handshake_failure", 40}, -+ {" bad_certificate", 42}, -+ {" unsupported_certificate", 43}, -+ {" certificate_revoked", 44}, -+ {" certificate_expired", 45}, -+ {" certificate_unknown", 46}, -+ {" illegal_parameter", 47}, -+ {" unknown_ca", 48}, -+ {" access_denied", 49}, -+ {" decode_error", 50}, -+ {" decrypt_error", 51}, -+ {" export_restriction", 60}, -+ {" protocol_version", 70}, -+ {" insufficient_security", 71}, -+ {" internal_error", 80}, -+ {" user_canceled", 90}, -+ {" no_renegotiation", 100}, -+ {" unsupported_extension", 110}, -+ {" certificate_unobtainable", 111}, -+ {" unrecognized_name", 112}, -+ {" bad_certificate_status_response", 113}, -+ {" bad_certificate_hash_value", 114}, -+ {" unknown_psk_identity", 115}, -+ {NULL} -+}; -+ -+static STRINT_PAIR handshakes[] = { -+ {", HelloRequest", 0}, -+ {", ClientHello", 1}, -+ {", ServerHello", 2}, -+ {", HelloVerifyRequest", 3}, -+ {", NewSessionTicket", 4}, -+ {", Certificate", 11}, -+ {", ServerKeyExchange", 12}, -+ {", CertificateRequest", 13}, -+ {", ServerHelloDone", 14}, -+ {", CertificateVerify", 15}, -+ {", ClientKeyExchange", 16}, -+ {", Finished", 20}, -+ {", CertificateUrl", 21}, -+ {", CertificateStatus", 22}, -+ {", SupplementalData", 23}, -+ {NULL} -+}; -+ -+void msg_cb(int write_p, int version, int content_type, const void *buf, -+ size_t len, SSL *ssl, void *arg) -+{ -+ BIO *bio = arg; -+ const char *str_write_p = write_p ? ">>>" : "<<<"; -+ const char *str_version = lookup(version, ssl_versions, "???"); -+ const char *str_content_type = "", *str_details1 = "", *str_details2 = ""; -+ const unsigned char* bp = buf; -+ -+ if (version == SSL3_VERSION || -+ version == TLS1_VERSION || -+ version == TLS1_1_VERSION || -+ version == TLS1_2_VERSION || -+ version == DTLS1_VERSION || version == DTLS1_BAD_VER) { -+ switch (content_type) { -+ case 20: -+ str_content_type = "ChangeCipherSpec"; -+ break; -+ case 21: -+ str_content_type = "Alert"; -+ str_details1 = ", ???"; -+ if (len == 2) { -+ switch (bp[0]) { -+ case 1: -+ str_details1 = ", warning"; -+ break; -+ case 2: -+ str_details1 = ", fatal"; -+ break; -+ } -+ str_details2 = lookup((int)bp[1], alert_types, " ???"); -+ } -+ break; -+ case 22: -+ str_content_type = "Handshake"; -+ str_details1 = "???"; -+ if (len > 0) -+ str_details1 = lookup((int)bp[0], handshakes, "???"); -+ break; -+ case 23: -+ str_content_type = "ApplicationData"; -+ break; -+#ifndef OPENSSL_NO_HEARTBEATS -+ case 24: -+ str_details1 = ", Heartbeat"; -+ -+ if (len > 0) { -+ switch (bp[0]) { -+ case 1: -+ str_details1 = ", HeartbeatRequest"; -+ break; -+ case 2: -+ str_details1 = ", HeartbeatResponse"; -+ break; -+ } -+ } -+ break; -+#endif -+ } -+ } -+ -+ BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, -+ str_content_type, (unsigned long)len, str_details1, -+ str_details2); -+ -+ if (len > 0) { -+ size_t num, i; -+ -+ BIO_printf(bio, " "); -+ num = len; -+ for (i = 0; i < num; i++) { -+ if (i % 16 == 0 && i > 0) -+ BIO_printf(bio, "\n "); -+ BIO_printf(bio, " %02x", ((const unsigned char *)buf)[i]); -+ } -+ if (i < len) -+ BIO_printf(bio, " ..."); -+ BIO_printf(bio, "\n"); -+ } -+ (void)BIO_flush(bio); -+} -+ -+static STRINT_PAIR tlsext_types[] = { -+ {"server name", TLSEXT_TYPE_server_name}, -+ {"max fragment length", TLSEXT_TYPE_max_fragment_length}, -+ {"client certificate URL", TLSEXT_TYPE_client_certificate_url}, -+ {"trusted CA keys", TLSEXT_TYPE_trusted_ca_keys}, -+ {"truncated HMAC", TLSEXT_TYPE_truncated_hmac}, -+ {"status request", TLSEXT_TYPE_status_request}, -+ {"user mapping", TLSEXT_TYPE_user_mapping}, -+ {"client authz", TLSEXT_TYPE_client_authz}, -+ {"server authz", TLSEXT_TYPE_server_authz}, -+ {"cert type", TLSEXT_TYPE_cert_type}, -+ {"elliptic curves", TLSEXT_TYPE_elliptic_curves}, -+ {"EC point formats", TLSEXT_TYPE_ec_point_formats}, -+ {"SRP", TLSEXT_TYPE_srp}, -+ {"signature algorithms", TLSEXT_TYPE_signature_algorithms}, -+ {"use SRTP", TLSEXT_TYPE_use_srtp}, -+ {"heartbeat", TLSEXT_TYPE_heartbeat}, -+ {"session ticket", TLSEXT_TYPE_session_ticket}, -+ {"renegotiation info", TLSEXT_TYPE_renegotiate}, -+ {"signed certificate timestamps", TLSEXT_TYPE_signed_certificate_timestamp}, -+ {"TLS padding", TLSEXT_TYPE_padding}, -+#ifdef TLSEXT_TYPE_next_proto_neg -+ {"next protocol", TLSEXT_TYPE_next_proto_neg}, -+#endif -+#ifdef TLSEXT_TYPE_encrypt_then_mac -+ {"encrypt-then-mac", TLSEXT_TYPE_encrypt_then_mac}, -+#endif -+#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation -+ {"application layer protocol negotiation", -+ TLSEXT_TYPE_application_layer_protocol_negotiation}, -+#endif -+#ifdef TLSEXT_TYPE_extended_master_secret -+ {"extended master secret", TLSEXT_TYPE_extended_master_secret}, -+#endif -+ {NULL} -+}; -+ -+void tlsext_cb(SSL *s, int client_server, int type, -+ const unsigned char *data, int len, void *arg) -+{ -+ BIO *bio = arg; -+ const char *extname = lookup(type, tlsext_types, "unknown"); -+ -+ BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n", -+ client_server ? "server" : "client", extname, type, len); -+ BIO_dump(bio, (const char *)data, len); -+ (void)BIO_flush(bio); -+} -+ -+#ifndef OPENSSL_NO_SOCK -+int generate_cookie_callback(SSL *ssl, unsigned char *cookie, -+ unsigned int *cookie_len) -+{ -+ unsigned char *buffer; -+ size_t length; -+ unsigned short port; -+ BIO_ADDR *peer = NULL; -+ -+ /* Initialize a random secret */ -+ if (!cookie_initialized) { -+ if (RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH) <= 0) { -+ BIO_printf(bio_err, "error setting random cookie secret\n"); -+ return 0; -+ } -+ cookie_initialized = 1; -+ } -+ -+ peer = BIO_ADDR_new(); -+ if (peer == NULL) { -+ BIO_printf(bio_err, "memory full\n"); -+ return 0; -+ } -+ -+ /* Read peer information */ -+ (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), peer); -+ -+ /* Create buffer with peer's address and port */ -+ BIO_ADDR_rawaddress(peer, NULL, &length); -+ OPENSSL_assert(length != 0); -+ port = BIO_ADDR_rawport(peer); -+ length += sizeof(port); -+ buffer = app_malloc(length, "cookie generate buffer"); -+ -+ memcpy(buffer, &port, sizeof(port)); -+ BIO_ADDR_rawaddress(peer, buffer + sizeof(port), NULL); -+ -+ /* Calculate HMAC of buffer using the secret */ -+ HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, -+ buffer, length, cookie, cookie_len); -+ -+ OPENSSL_free(buffer); -+ BIO_ADDR_free(peer); -+ -+ return 1; -+} -+ -+int verify_cookie_callback(SSL *ssl, const unsigned char *cookie, -+ unsigned int cookie_len) -+{ -+ unsigned char result[EVP_MAX_MD_SIZE]; -+ unsigned int resultlength; -+ -+ /* Note: we check cookie_initialized because if it's not, -+ * it cannot be valid */ -+ if (cookie_initialized -+ && generate_cookie_callback(ssl, result, &resultlength) -+ && cookie_len == resultlength -+ && memcmp(result, cookie, resultlength) == 0) -+ return 1; -+ -+ return 0; -+} -+#endif -+ -+/* -+ * Example of extended certificate handling. Where the standard support of -+ * one certificate per algorithm is not sufficient an application can decide -+ * which certificate(s) to use at runtime based on whatever criteria it deems -+ * appropriate. -+ */ -+ -+/* Linked list of certificates, keys and chains */ -+struct ssl_excert_st { -+ int certform; -+ const char *certfile; -+ int keyform; -+ const char *keyfile; -+ const char *chainfile; -+ X509 *cert; -+ EVP_PKEY *key; -+ STACK_OF(X509) *chain; -+ int build_chain; -+ struct ssl_excert_st *next, *prev; -+}; -+ -+static STRINT_PAIR chain_flags[] = { -+ {"Overall Validity", CERT_PKEY_VALID}, -+ {"Sign with EE key", CERT_PKEY_SIGN}, -+ {"EE signature", CERT_PKEY_EE_SIGNATURE}, -+ {"CA signature", CERT_PKEY_CA_SIGNATURE}, -+ {"EE key parameters", CERT_PKEY_EE_PARAM}, -+ {"CA key parameters", CERT_PKEY_CA_PARAM}, -+ {"Explicitly sign with EE key", CERT_PKEY_EXPLICIT_SIGN}, -+ {"Issuer Name", CERT_PKEY_ISSUER_NAME}, -+ {"Certificate Type", CERT_PKEY_CERT_TYPE}, -+ {NULL} -+}; -+ -+static void print_chain_flags(SSL *s, int flags) -+{ -+ STRINT_PAIR *pp; -+ -+ for (pp = chain_flags; pp->name; ++pp) -+ BIO_printf(bio_err, "\t%s: %s\n", -+ pp->name, -+ (flags & pp->retval) ? "OK" : "NOT OK"); -+ BIO_printf(bio_err, "\tSuite B: "); -+ if (SSL_set_cert_flags(s, 0) & SSL_CERT_FLAG_SUITEB_128_LOS) -+ BIO_puts(bio_err, flags & CERT_PKEY_SUITEB ? "OK\n" : "NOT OK\n"); -+ else -+ BIO_printf(bio_err, "not tested\n"); -+} -+ -+/* -+ * Very basic selection callback: just use any certificate chain reported as -+ * valid. More sophisticated could prioritise according to local policy. -+ */ -+static int set_cert_cb(SSL *ssl, void *arg) -+{ -+ int i, rv; -+ SSL_EXCERT *exc = arg; -+#ifdef CERT_CB_TEST_RETRY -+ static int retry_cnt; -+ if (retry_cnt < 5) { -+ retry_cnt++; -+ BIO_printf(bio_err, -+ "Certificate callback retry test: count %d\n", -+ retry_cnt); -+ return -1; -+ } -+#endif -+ SSL_certs_clear(ssl); -+ -+ if (!exc) -+ return 1; -+ -+ /* -+ * Go to end of list and traverse backwards since we prepend newer -+ * entries this retains the original order. -+ */ -+ while (exc->next) -+ exc = exc->next; -+ -+ i = 0; -+ -+ while (exc) { -+ i++; -+ rv = SSL_check_chain(ssl, exc->cert, exc->key, exc->chain); -+ BIO_printf(bio_err, "Checking cert chain %d:\nSubject: ", i); -+ X509_NAME_print_ex(bio_err, X509_get_subject_name(exc->cert), 0, -+ XN_FLAG_ONELINE); -+ BIO_puts(bio_err, "\n"); -+ print_chain_flags(ssl, rv); -+ if (rv & CERT_PKEY_VALID) { -+ if (!SSL_use_certificate(ssl, exc->cert) -+ || !SSL_use_PrivateKey(ssl, exc->key)) { -+ return 0; -+ } -+ /* -+ * NB: we wouldn't normally do this as it is not efficient -+ * building chains on each connection better to cache the chain -+ * in advance. -+ */ -+ if (exc->build_chain) { -+ if (!SSL_build_cert_chain(ssl, 0)) -+ return 0; -+ } else if (exc->chain) -+ SSL_set1_chain(ssl, exc->chain); -+ } -+ exc = exc->prev; -+ } -+ return 1; -+} -+ -+void ssl_ctx_set_excert(SSL_CTX *ctx, SSL_EXCERT *exc) -+{ -+ SSL_CTX_set_cert_cb(ctx, set_cert_cb, exc); -+} -+ -+static int ssl_excert_prepend(SSL_EXCERT **pexc) -+{ -+ SSL_EXCERT *exc = app_malloc(sizeof(*exc), "prepend cert"); -+ -+ memset(exc, 0, sizeof(*exc)); -+ -+ exc->next = *pexc; -+ *pexc = exc; -+ -+ if (exc->next) { -+ exc->certform = exc->next->certform; -+ exc->keyform = exc->next->keyform; -+ exc->next->prev = exc; -+ } else { -+ exc->certform = FORMAT_PEM; -+ exc->keyform = FORMAT_PEM; -+ } -+ return 1; -+ -+} -+ -+void ssl_excert_free(SSL_EXCERT *exc) -+{ -+ SSL_EXCERT *curr; -+ -+ if (!exc) -+ return; -+ while (exc) { -+ X509_free(exc->cert); -+ EVP_PKEY_free(exc->key); -+ sk_X509_pop_free(exc->chain, X509_free); -+ curr = exc; -+ exc = exc->next; -+ OPENSSL_free(curr); -+ } -+} -+ -+int load_excert(SSL_EXCERT **pexc) -+{ -+ SSL_EXCERT *exc = *pexc; -+ if (!exc) -+ return 1; -+ /* If nothing in list, free and set to NULL */ -+ if (!exc->certfile && !exc->next) { -+ ssl_excert_free(exc); -+ *pexc = NULL; -+ return 1; -+ } -+ for (; exc; exc = exc->next) { -+ if (!exc->certfile) { -+ BIO_printf(bio_err, "Missing filename\n"); -+ return 0; -+ } -+ exc->cert = load_cert(exc->certfile, exc->certform, -+ "Server Certificate"); -+ if (!exc->cert) -+ return 0; -+ if (exc->keyfile) { -+ exc->key = load_key(exc->keyfile, exc->keyform, -+ 0, NULL, NULL, "Server Key"); -+ } else { -+ exc->key = load_key(exc->certfile, exc->certform, -+ 0, NULL, NULL, "Server Key"); -+ } -+ if (!exc->key) -+ return 0; -+ if (exc->chainfile) { -+ if (!load_certs(exc->chainfile, &exc->chain, FORMAT_PEM, NULL, -+ "Server Chain")) -+ return 0; -+ } -+ } -+ return 1; -+} -+ -+enum range { OPT_X_ENUM }; -+ -+int args_excert(int opt, SSL_EXCERT **pexc) -+{ -+ SSL_EXCERT *exc = *pexc; -+ -+ assert(opt > OPT_X__FIRST); -+ assert(opt < OPT_X__LAST); -+ -+ if (exc == NULL) { -+ if (!ssl_excert_prepend(&exc)) { -+ BIO_printf(bio_err, " %s: Error initialising xcert\n", -+ opt_getprog()); -+ goto err; -+ } -+ *pexc = exc; -+ } -+ -+ switch ((enum range)opt) { -+ case OPT_X__FIRST: -+ case OPT_X__LAST: -+ return 0; -+ case OPT_X_CERT: -+ if (exc->certfile && !ssl_excert_prepend(&exc)) { -+ BIO_printf(bio_err, "%s: Error adding xcert\n", opt_getprog()); -+ goto err; -+ } -+ *pexc = exc; -+ exc->certfile = opt_arg(); -+ break; -+ case OPT_X_KEY: -+ if (exc->keyfile) { -+ BIO_printf(bio_err, "%s: Key already specified\n", opt_getprog()); -+ goto err; -+ } -+ exc->keyfile = opt_arg(); -+ break; -+ case OPT_X_CHAIN: -+ if (exc->chainfile) { -+ BIO_printf(bio_err, "%s: Chain already specified\n", -+ opt_getprog()); -+ goto err; -+ } -+ exc->chainfile = opt_arg(); -+ break; -+ case OPT_X_CHAIN_BUILD: -+ exc->build_chain = 1; -+ break; -+ case OPT_X_CERTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &exc->certform)) -+ return 0; -+ break; -+ case OPT_X_KEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &exc->keyform)) -+ return 0; -+ break; -+ } -+ return 1; -+ -+ err: -+ ERR_print_errors(bio_err); -+ ssl_excert_free(exc); -+ *pexc = NULL; -+ return 0; -+} -+ -+static void print_raw_cipherlist(SSL *s) -+{ -+ const unsigned char *rlist; -+ static const unsigned char scsv_id[] = { 0, 0xFF }; -+ size_t i, rlistlen, num; -+ if (!SSL_is_server(s)) -+ return; -+ num = SSL_get0_raw_cipherlist(s, NULL); -+ OPENSSL_assert(num == 2); -+ rlistlen = SSL_get0_raw_cipherlist(s, &rlist); -+ BIO_puts(bio_err, "Client cipher list: "); -+ for (i = 0; i < rlistlen; i += num, rlist += num) { -+ const SSL_CIPHER *c = SSL_CIPHER_find(s, rlist); -+ if (i) -+ BIO_puts(bio_err, ":"); -+ if (c) -+ BIO_puts(bio_err, SSL_CIPHER_get_name(c)); -+ else if (!memcmp(rlist, scsv_id, num)) -+ BIO_puts(bio_err, "SCSV"); -+ else { -+ size_t j; -+ BIO_puts(bio_err, "0x"); -+ for (j = 0; j < num; j++) -+ BIO_printf(bio_err, "%02X", rlist[j]); -+ } -+ } -+ BIO_puts(bio_err, "\n"); -+} -+ -+/* -+ * Hex encoder for TLSA RRdata, not ':' delimited. -+ */ -+static char *hexencode(const unsigned char *data, size_t len) -+{ -+ static const char *hex = "0123456789abcdef"; -+ char *out; -+ char *cp; -+ size_t outlen = 2 * len + 1; -+ int ilen = (int) outlen; -+ -+ if (outlen < len || ilen < 0 || outlen != (size_t)ilen) { -+ BIO_printf(bio_err, "%s: %" PRIu64 "-byte buffer too large to hexencode\n", -+ opt_getprog(), (uint64_t)len); -+ exit(1); -+ } -+ cp = out = app_malloc(ilen, "TLSA hex data buffer"); -+ -+ while (len-- > 0) { -+ *cp++ = hex[(*data >> 4) & 0x0f]; -+ *cp++ = hex[*data++ & 0x0f]; -+ } -+ *cp = '\0'; -+ return out; -+} -+ -+void print_verify_detail(SSL *s, BIO *bio) -+{ -+ int mdpth; -+ EVP_PKEY *mspki; -+ long verify_err = SSL_get_verify_result(s); -+ -+ if (verify_err == X509_V_OK) { -+ const char *peername = SSL_get0_peername(s); -+ -+ BIO_printf(bio, "Verification: OK\n"); -+ if (peername != NULL) -+ BIO_printf(bio, "Verified peername: %s\n", peername); -+ } else { -+ const char *reason = X509_verify_cert_error_string(verify_err); -+ -+ BIO_printf(bio, "Verification error: %s\n", reason); -+ } -+ -+ if ((mdpth = SSL_get0_dane_authority(s, NULL, &mspki)) >= 0) { -+ uint8_t usage, selector, mtype; -+ const unsigned char *data = NULL; -+ size_t dlen = 0; -+ char *hexdata; -+ -+ mdpth = SSL_get0_dane_tlsa(s, &usage, &selector, &mtype, &data, &dlen); -+ -+ /* -+ * The TLSA data field can be quite long when it is a certificate, -+ * public key or even a SHA2-512 digest. Because the initial octets of -+ * ASN.1 certificates and public keys contain mostly boilerplate OIDs -+ * and lengths, we show the last 12 bytes of the data instead, as these -+ * are more likely to distinguish distinct TLSA records. -+ */ -+#define TLSA_TAIL_SIZE 12 -+ if (dlen > TLSA_TAIL_SIZE) -+ hexdata = hexencode(data + dlen - TLSA_TAIL_SIZE, TLSA_TAIL_SIZE); -+ else -+ hexdata = hexencode(data, dlen); -+ BIO_printf(bio, "DANE TLSA %d %d %d %s%s %s at depth %d\n", -+ usage, selector, mtype, -+ (dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata, -+ (mspki != NULL) ? "signed the certificate" : -+ mdpth ? "matched TA certificate" : "matched EE certificate", -+ mdpth); -+ OPENSSL_free(hexdata); -+ } -+} -+ -+void print_ssl_summary(SSL *s) -+{ -+ const SSL_CIPHER *c; -+ X509 *peer; -+ /* const char *pnam = SSL_is_server(s) ? "client" : "server"; */ -+ -+ BIO_printf(bio_err, "Protocol version: %s\n", SSL_get_version(s)); -+ print_raw_cipherlist(s); -+ c = SSL_get_current_cipher(s); -+ BIO_printf(bio_err, "Ciphersuite: %s\n", SSL_CIPHER_get_name(c)); -+ do_print_sigalgs(bio_err, s, 0); -+ peer = SSL_get_peer_certificate(s); -+ if (peer) { -+ int nid; -+ -+ BIO_puts(bio_err, "Peer certificate: "); -+ X509_NAME_print_ex(bio_err, X509_get_subject_name(peer), -+ 0, XN_FLAG_ONELINE); -+ BIO_puts(bio_err, "\n"); -+ if (SSL_get_peer_signature_nid(s, &nid)) -+ BIO_printf(bio_err, "Hash used: %s\n", OBJ_nid2sn(nid)); -+ print_verify_detail(s, bio_err); -+ } else -+ BIO_puts(bio_err, "No peer certificate\n"); -+ X509_free(peer); -+#ifndef OPENSSL_NO_EC -+ ssl_print_point_formats(bio_err, s); -+ if (SSL_is_server(s)) -+ ssl_print_curves(bio_err, s, 1); -+ else -+ ssl_print_tmp_key(bio_err, s); -+#else -+ if (!SSL_is_server(s)) -+ ssl_print_tmp_key(bio_err, s); -+#endif -+} -+ -+int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, -+ SSL_CTX *ctx) -+{ -+ int i; -+ -+ SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); -+ for (i = 0; i < sk_OPENSSL_STRING_num(str); i += 2) { -+ const char *flag = sk_OPENSSL_STRING_value(str, i); -+ const char *arg = sk_OPENSSL_STRING_value(str, i + 1); -+ if (SSL_CONF_cmd(cctx, flag, arg) <= 0) { -+ if (arg) -+ BIO_printf(bio_err, "Error with command: \"%s %s\"\n", -+ flag, arg); -+ else -+ BIO_printf(bio_err, "Error with command: \"%s\"\n", flag); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ } -+ if (!SSL_CONF_CTX_finish(cctx)) { -+ BIO_puts(bio_err, "Error finishing context\n"); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ return 1; -+} -+ -+static int add_crls_store(X509_STORE *st, STACK_OF(X509_CRL) *crls) -+{ -+ X509_CRL *crl; -+ int i; -+ for (i = 0; i < sk_X509_CRL_num(crls); i++) { -+ crl = sk_X509_CRL_value(crls, i); -+ X509_STORE_add_crl(st, crl); -+ } -+ return 1; -+} -+ -+int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download) -+{ -+ X509_STORE *st; -+ st = SSL_CTX_get_cert_store(ctx); -+ add_crls_store(st, crls); -+ if (crl_download) -+ store_setup_crl_download(st); -+ return 1; -+} -+ -+int ssl_load_stores(SSL_CTX *ctx, -+ const char *vfyCApath, const char *vfyCAfile, -+ const char *chCApath, const char *chCAfile, -+ STACK_OF(X509_CRL) *crls, int crl_download) -+{ -+ X509_STORE *vfy = NULL, *ch = NULL; -+ int rv = 0; -+ if (vfyCApath != NULL || vfyCAfile != NULL) { -+ vfy = X509_STORE_new(); -+ if (vfy == NULL) -+ goto err; -+ if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath)) -+ goto err; -+ add_crls_store(vfy, crls); -+ SSL_CTX_set1_verify_cert_store(ctx, vfy); -+ if (crl_download) -+ store_setup_crl_download(vfy); -+ } -+ if (chCApath != NULL || chCAfile != NULL) { -+ ch = X509_STORE_new(); -+ if (ch == NULL) -+ goto err; -+ if (!X509_STORE_load_locations(ch, chCAfile, chCApath)) -+ goto err; -+ SSL_CTX_set1_chain_cert_store(ctx, ch); -+ } -+ rv = 1; -+ err: -+ X509_STORE_free(vfy); -+ X509_STORE_free(ch); -+ return rv; -+} -+ -+/* Verbose print out of security callback */ -+ -+typedef struct { -+ BIO *out; -+ int verbose; -+ int (*old_cb) (const SSL *s, const SSL_CTX *ctx, int op, int bits, int nid, -+ void *other, void *ex); -+} security_debug_ex; -+ -+static STRINT_PAIR callback_types[] = { -+ {"Supported Ciphersuite", SSL_SECOP_CIPHER_SUPPORTED}, -+ {"Shared Ciphersuite", SSL_SECOP_CIPHER_SHARED}, -+ {"Check Ciphersuite", SSL_SECOP_CIPHER_CHECK}, -+#ifndef OPENSSL_NO_DH -+ {"Temp DH key bits", SSL_SECOP_TMP_DH}, -+#endif -+ {"Supported Curve", SSL_SECOP_CURVE_SUPPORTED}, -+ {"Shared Curve", SSL_SECOP_CURVE_SHARED}, -+ {"Check Curve", SSL_SECOP_CURVE_CHECK}, -+ {"Supported Signature Algorithm digest", SSL_SECOP_SIGALG_SUPPORTED}, -+ {"Shared Signature Algorithm digest", SSL_SECOP_SIGALG_SHARED}, -+ {"Check Signature Algorithm digest", SSL_SECOP_SIGALG_CHECK}, -+ {"Signature Algorithm mask", SSL_SECOP_SIGALG_MASK}, -+ {"Certificate chain EE key", SSL_SECOP_EE_KEY}, -+ {"Certificate chain CA key", SSL_SECOP_CA_KEY}, -+ {"Peer Chain EE key", SSL_SECOP_PEER_EE_KEY}, -+ {"Peer Chain CA key", SSL_SECOP_PEER_CA_KEY}, -+ {"Certificate chain CA digest", SSL_SECOP_CA_MD}, -+ {"Peer chain CA digest", SSL_SECOP_PEER_CA_MD}, -+ {"SSL compression", SSL_SECOP_COMPRESSION}, -+ {"Session ticket", SSL_SECOP_TICKET}, -+ {NULL} -+}; -+ -+static int security_callback_debug(const SSL *s, const SSL_CTX *ctx, -+ int op, int bits, int nid, -+ void *other, void *ex) -+{ -+ security_debug_ex *sdb = ex; -+ int rv, show_bits = 1, cert_md = 0; -+ const char *nm; -+ rv = sdb->old_cb(s, ctx, op, bits, nid, other, ex); -+ if (rv == 1 && sdb->verbose < 2) -+ return 1; -+ BIO_puts(sdb->out, "Security callback: "); -+ -+ nm = lookup(op, callback_types, NULL); -+ switch (op) { -+ case SSL_SECOP_TICKET: -+ case SSL_SECOP_COMPRESSION: -+ show_bits = 0; -+ nm = NULL; -+ break; -+ case SSL_SECOP_VERSION: -+ BIO_printf(sdb->out, "Version=%s", lookup(nid, ssl_versions, "???")); -+ show_bits = 0; -+ nm = NULL; -+ break; -+ case SSL_SECOP_CA_MD: -+ case SSL_SECOP_PEER_CA_MD: -+ cert_md = 1; -+ break; -+ } -+ if (nm) -+ BIO_printf(sdb->out, "%s=", nm); -+ -+ switch (op & SSL_SECOP_OTHER_TYPE) { -+ -+ case SSL_SECOP_OTHER_CIPHER: -+ BIO_puts(sdb->out, SSL_CIPHER_get_name(other)); -+ break; -+ -+#ifndef OPENSSL_NO_EC -+ case SSL_SECOP_OTHER_CURVE: -+ { -+ const char *cname; -+ cname = EC_curve_nid2nist(nid); -+ if (cname == NULL) -+ cname = OBJ_nid2sn(nid); -+ BIO_puts(sdb->out, cname); -+ } -+ break; -+#endif -+#ifndef OPENSSL_NO_DH -+ case SSL_SECOP_OTHER_DH: -+ { -+ DH *dh = other; -+ BIO_printf(sdb->out, "%d", DH_bits(dh)); -+ break; -+ } -+#endif -+ case SSL_SECOP_OTHER_CERT: -+ { -+ if (cert_md) { -+ int sig_nid = X509_get_signature_nid(other); -+ BIO_puts(sdb->out, OBJ_nid2sn(sig_nid)); -+ } else { -+ EVP_PKEY *pkey = X509_get0_pubkey(other); -+ const char *algname = ""; -+ EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, -+ &algname, EVP_PKEY_get0_asn1(pkey)); -+ BIO_printf(sdb->out, "%s, bits=%d", -+ algname, EVP_PKEY_bits(pkey)); -+ } -+ break; -+ } -+ case SSL_SECOP_OTHER_SIGALG: -+ { -+ const unsigned char *salg = other; -+ const char *sname = NULL; -+ switch (salg[1]) { -+ case TLSEXT_signature_anonymous: -+ sname = "anonymous"; -+ break; -+ case TLSEXT_signature_rsa: -+ sname = "RSA"; -+ break; -+ case TLSEXT_signature_dsa: -+ sname = "DSA"; -+ break; -+ case TLSEXT_signature_ecdsa: -+ sname = "ECDSA"; -+ break; -+ } -+ -+ BIO_puts(sdb->out, OBJ_nid2sn(nid)); -+ if (sname) -+ BIO_printf(sdb->out, ", algorithm=%s", sname); -+ else -+ BIO_printf(sdb->out, ", algid=%d", salg[1]); -+ break; -+ } -+ -+ } -+ -+ if (show_bits) -+ BIO_printf(sdb->out, ", security bits=%d", bits); -+ BIO_printf(sdb->out, ": %s\n", rv ? "yes" : "no"); -+ return rv; -+} -+ -+void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose) -+{ -+ static security_debug_ex sdb; -+ -+ sdb.out = bio_err; -+ sdb.verbose = verbose; -+ sdb.old_cb = SSL_CTX_get_security_callback(ctx); -+ SSL_CTX_set_security_callback(ctx, security_callback_debug); -+ SSL_CTX_set0_security_ex_data(ctx, &sdb); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/s_client.c b/CryptoPkg/Library/OpensslLib/openssl/apps/s_client.c -new file mode 100644 -index 0000000..458b9e0 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/s_client.c -@@ -0,0 +1,2747 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* ==================================================================== -+ * Copyright 2005 Nokia. All rights reserved. -+ * -+ * The portions of the attached software ("Contribution") is developed by -+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source -+ * license. -+ * -+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of -+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites -+ * support (see RFC 4279) to OpenSSL. -+ * -+ * No patent licenses or other rights except those expressly stated in -+ * the OpenSSL open source license shall be deemed granted or received -+ * expressly, by implication, estoppel, or otherwise. -+ * -+ * No assurances are provided by Nokia that the Contribution does not -+ * infringe the patent or other intellectual property rights of any third -+ * party or that the license provides you with all the necessary rights -+ * to make use of the Contribution. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN -+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA -+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY -+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR -+ * OTHERWISE. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef OPENSSL_NO_SOCK -+ -+/* -+ * With IPv6, it looks like Digital has mixed up the proper order of -+ * recursive header file inclusion, resulting in the compiler complaining -+ * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is -+ * needed to have fileno() declared correctly... So let's define u_int -+ */ -+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT) -+# define __U_INT -+typedef unsigned int u_int; -+#endif -+ -+#define USE_SOCKETS -+#include "apps.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef OPENSSL_NO_SRP -+# include -+#endif -+#ifndef OPENSSL_NO_CT -+# include -+#endif -+#include "s_apps.h" -+#include "timeouts.h" -+ -+#if defined(__has_feature) -+# if __has_feature(memory_sanitizer) -+# include -+# endif -+#endif -+ -+#undef BUFSIZZ -+#define BUFSIZZ 1024*8 -+#define S_CLIENT_IRC_READ_TIMEOUT 8 -+ -+static char *prog; -+static int c_debug = 0; -+static int c_showcerts = 0; -+static char *keymatexportlabel = NULL; -+static int keymatexportlen = 20; -+static BIO *bio_c_out = NULL; -+static int c_quiet = 0; -+ -+static void print_stuff(BIO *berr, SSL *con, int full); -+#ifndef OPENSSL_NO_OCSP -+static int ocsp_resp_cb(SSL *s, void *arg); -+#endif -+ -+static int saved_errno; -+ -+static void save_errno(void) -+{ -+ saved_errno = errno; -+ errno = 0; -+} -+ -+static int restore_errno(void) -+{ -+ int ret = errno; -+ errno = saved_errno; -+ return ret; -+} -+ -+static void do_ssl_shutdown(SSL *ssl) -+{ -+ int ret; -+ -+ do { -+ /* We only do unidirectional shutdown */ -+ ret = SSL_shutdown(ssl); -+ if (ret < 0) { -+ switch (SSL_get_error(ssl, ret)) { -+ case SSL_ERROR_WANT_READ: -+ case SSL_ERROR_WANT_WRITE: -+ case SSL_ERROR_WANT_ASYNC: -+ case SSL_ERROR_WANT_ASYNC_JOB: -+ /* We just do busy waiting. Nothing clever */ -+ continue; -+ } -+ ret = 0; -+ } -+ } while (ret < 0); -+} -+ -+#ifndef OPENSSL_NO_PSK -+/* Default PSK identity and key */ -+static char *psk_identity = "Client_identity"; -+/* -+ * char *psk_key=NULL; by default PSK is not used -+ */ -+ -+static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity, -+ unsigned int max_identity_len, -+ unsigned char *psk, -+ unsigned int max_psk_len) -+{ -+ int ret; -+ long key_len; -+ unsigned char *key; -+ -+ if (c_debug) -+ BIO_printf(bio_c_out, "psk_client_cb\n"); -+ if (!hint) { -+ /* no ServerKeyExchange message */ -+ if (c_debug) -+ BIO_printf(bio_c_out, -+ "NULL received PSK identity hint, continuing anyway\n"); -+ } else if (c_debug) -+ BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint); -+ -+ /* -+ * lookup PSK identity and PSK key based on the given identity hint here -+ */ -+ ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity); -+ if (ret < 0 || (unsigned int)ret > max_identity_len) -+ goto out_err; -+ if (c_debug) -+ BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity, -+ ret); -+ -+ /* convert the PSK key to binary */ -+ key = OPENSSL_hexstr2buf(psk_key, &key_len); -+ if (key == NULL) { -+ BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n", -+ psk_key); -+ return 0; -+ } -+ if (key_len > max_psk_len) { -+ BIO_printf(bio_err, -+ "psk buffer of callback is too small (%d) for key (%ld)\n", -+ max_psk_len, key_len); -+ OPENSSL_free(key); -+ return 0; -+ } -+ -+ memcpy(psk, key, key_len); -+ OPENSSL_free(key); -+ -+ if (c_debug) -+ BIO_printf(bio_c_out, "created PSK len=%ld\n", key_len); -+ -+ return key_len; -+ out_err: -+ if (c_debug) -+ BIO_printf(bio_err, "Error in PSK client callback\n"); -+ return 0; -+} -+#endif -+ -+/* This is a context that we pass to callbacks */ -+typedef struct tlsextctx_st { -+ BIO *biodebug; -+ int ack; -+} tlsextctx; -+ -+static int ssl_servername_cb(SSL *s, int *ad, void *arg) -+{ -+ tlsextctx *p = (tlsextctx *) arg; -+ const char *hn = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); -+ if (SSL_get_servername_type(s) != -1) -+ p->ack = !SSL_session_reused(s) && hn != NULL; -+ else -+ BIO_printf(bio_err, "Can't use SSL_get_servername\n"); -+ -+ return SSL_TLSEXT_ERR_OK; -+} -+ -+#ifndef OPENSSL_NO_SRP -+ -+/* This is a context that we pass to all callbacks */ -+typedef struct srp_arg_st { -+ char *srppassin; -+ char *srplogin; -+ int msg; /* copy from c_msg */ -+ int debug; /* copy from c_debug */ -+ int amp; /* allow more groups */ -+ int strength; /* minimal size for N */ -+} SRP_ARG; -+ -+# define SRP_NUMBER_ITERATIONS_FOR_PRIME 64 -+ -+static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g) -+{ -+ BN_CTX *bn_ctx = BN_CTX_new(); -+ BIGNUM *p = BN_new(); -+ BIGNUM *r = BN_new(); -+ int ret = -+ g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) && -+ BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) == 1 && -+ p != NULL && BN_rshift1(p, N) && -+ /* p = (N-1)/2 */ -+ BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) == 1 && -+ r != NULL && -+ /* verify g^((N-1)/2) == -1 (mod N) */ -+ BN_mod_exp(r, g, p, N, bn_ctx) && -+ BN_add_word(r, 1) && BN_cmp(r, N) == 0; -+ -+ BN_free(r); -+ BN_free(p); -+ BN_CTX_free(bn_ctx); -+ return ret; -+} -+ -+/*- -+ * This callback is used here for two purposes: -+ * - extended debugging -+ * - making some primality tests for unknown groups -+ * The callback is only called for a non default group. -+ * -+ * An application does not need the call back at all if -+ * only the standard groups are used. In real life situations, -+ * client and server already share well known groups, -+ * thus there is no need to verify them. -+ * Furthermore, in case that a server actually proposes a group that -+ * is not one of those defined in RFC 5054, it is more appropriate -+ * to add the group to a static list and then compare since -+ * primality tests are rather cpu consuming. -+ */ -+ -+static int ssl_srp_verify_param_cb(SSL *s, void *arg) -+{ -+ SRP_ARG *srp_arg = (SRP_ARG *)arg; -+ BIGNUM *N = NULL, *g = NULL; -+ -+ if (((N = SSL_get_srp_N(s)) == NULL) || ((g = SSL_get_srp_g(s)) == NULL)) -+ return 0; -+ if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) { -+ BIO_printf(bio_err, "SRP parameters:\n"); -+ BIO_printf(bio_err, "\tN="); -+ BN_print(bio_err, N); -+ BIO_printf(bio_err, "\n\tg="); -+ BN_print(bio_err, g); -+ BIO_printf(bio_err, "\n"); -+ } -+ -+ if (SRP_check_known_gN_param(g, N)) -+ return 1; -+ -+ if (srp_arg->amp == 1) { -+ if (srp_arg->debug) -+ BIO_printf(bio_err, -+ "SRP param N and g are not known params, going to check deeper.\n"); -+ -+ /* -+ * The srp_moregroups is a real debugging feature. Implementors -+ * should rather add the value to the known ones. The minimal size -+ * has already been tested. -+ */ -+ if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g)) -+ return 1; -+ } -+ BIO_printf(bio_err, "SRP param N and g rejected.\n"); -+ return 0; -+} -+ -+# define PWD_STRLEN 1024 -+ -+static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg) -+{ -+ SRP_ARG *srp_arg = (SRP_ARG *)arg; -+ char *pass = app_malloc(PWD_STRLEN + 1, "SRP password buffer"); -+ PW_CB_DATA cb_tmp; -+ int l; -+ -+ cb_tmp.password = (char *)srp_arg->srppassin; -+ cb_tmp.prompt_info = "SRP user"; -+ if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp)) < 0) { -+ BIO_printf(bio_err, "Can't read Password\n"); -+ OPENSSL_free(pass); -+ return NULL; -+ } -+ *(pass + l) = '\0'; -+ -+ return pass; -+} -+ -+#endif -+ -+static char *srtp_profiles = NULL; -+ -+#ifndef OPENSSL_NO_NEXTPROTONEG -+/* This the context that we pass to next_proto_cb */ -+typedef struct tlsextnextprotoctx_st { -+ unsigned char *data; -+ size_t len; -+ int status; -+} tlsextnextprotoctx; -+ -+static tlsextnextprotoctx next_proto; -+ -+static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, -+ const unsigned char *in, unsigned int inlen, -+ void *arg) -+{ -+ tlsextnextprotoctx *ctx = arg; -+ -+ if (!c_quiet) { -+ /* We can assume that |in| is syntactically valid. */ -+ unsigned i; -+ BIO_printf(bio_c_out, "Protocols advertised by server: "); -+ for (i = 0; i < inlen;) { -+ if (i) -+ BIO_write(bio_c_out, ", ", 2); -+ BIO_write(bio_c_out, &in[i + 1], in[i]); -+ i += in[i] + 1; -+ } -+ BIO_write(bio_c_out, "\n", 1); -+ } -+ -+ ctx->status = -+ SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len); -+ return SSL_TLSEXT_ERR_OK; -+} -+#endif /* ndef OPENSSL_NO_NEXTPROTONEG */ -+ -+static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type, -+ const unsigned char *in, size_t inlen, -+ int *al, void *arg) -+{ -+ char pem_name[100]; -+ unsigned char ext_buf[4 + 65536]; -+ -+ /* Reconstruct the type/len fields prior to extension data */ -+ ext_buf[0] = ext_type >> 8; -+ ext_buf[1] = ext_type & 0xFF; -+ ext_buf[2] = inlen >> 8; -+ ext_buf[3] = inlen & 0xFF; -+ memcpy(ext_buf + 4, in, inlen); -+ -+ BIO_snprintf(pem_name, sizeof(pem_name), "SERVERINFO FOR EXTENSION %d", -+ ext_type); -+ PEM_write_bio(bio_c_out, pem_name, "", ext_buf, 4 + inlen); -+ return 1; -+} -+ -+/* -+ * Hex decoder that tolerates optional whitespace. Returns number of bytes -+ * produced, advances inptr to end of input string. -+ */ -+static ossl_ssize_t hexdecode(const char **inptr, void *result) -+{ -+ unsigned char **out = (unsigned char **)result; -+ const char *in = *inptr; -+ unsigned char *ret = app_malloc(strlen(in) / 2, "hexdecode"); -+ unsigned char *cp = ret; -+ uint8_t byte; -+ int nibble = 0; -+ -+ if (ret == NULL) -+ return -1; -+ -+ for (byte = 0; *in; ++in) { -+ int x; -+ -+ if (isspace(_UC(*in))) -+ continue; -+ x = OPENSSL_hexchar2int(*in); -+ if (x < 0) { -+ OPENSSL_free(ret); -+ return 0; -+ } -+ byte |= (char)x; -+ if ((nibble ^= 1) == 0) { -+ *cp++ = byte; -+ byte = 0; -+ } else { -+ byte <<= 4; -+ } -+ } -+ if (nibble != 0) { -+ OPENSSL_free(ret); -+ return 0; -+ } -+ *inptr = in; -+ -+ return cp - (*out = ret); -+} -+ -+/* -+ * Decode unsigned 0..255, returns 1 on success, <= 0 on failure. Advances -+ * inptr to next field skipping leading whitespace. -+ */ -+static ossl_ssize_t checked_uint8(const char **inptr, void *out) -+{ -+ uint8_t *result = (uint8_t *)out; -+ const char *in = *inptr; -+ char *endp; -+ long v; -+ int e; -+ -+ save_errno(); -+ v = strtol(in, &endp, 10); -+ e = restore_errno(); -+ -+ if (((v == LONG_MIN || v == LONG_MAX) && e == ERANGE) || -+ endp == in || !isspace(_UC(*endp)) || -+ v != (*result = (uint8_t) v)) { -+ return -1; -+ } -+ for (in = endp; isspace(_UC(*in)); ++in) -+ continue; -+ -+ *inptr = in; -+ return 1; -+} -+ -+struct tlsa_field { -+ void *var; -+ const char *name; -+ ossl_ssize_t (*parser)(const char **, void *); -+}; -+ -+static int tlsa_import_rr(SSL *con, const char *rrdata) -+{ -+ /* Not necessary to re-init these values; the "parsers" do that. */ -+ static uint8_t usage; -+ static uint8_t selector; -+ static uint8_t mtype; -+ static unsigned char *data; -+ static struct tlsa_field tlsa_fields[] = { -+ { &usage, "usage", checked_uint8 }, -+ { &selector, "selector", checked_uint8 }, -+ { &mtype, "mtype", checked_uint8 }, -+ { &data, "data", hexdecode }, -+ { NULL, } -+ }; -+ struct tlsa_field *f; -+ int ret; -+ const char *cp = rrdata; -+ ossl_ssize_t len = 0; -+ -+ for (f = tlsa_fields; f->var; ++f) { -+ /* Returns number of bytes produced, advances cp to next field */ -+ if ((len = f->parser(&cp, f->var)) <= 0) { -+ BIO_printf(bio_err, "%s: warning: bad TLSA %s field in: %s\n", -+ prog, f->name, rrdata); -+ return 0; -+ } -+ } -+ /* The data field is last, so len is its length */ -+ ret = SSL_dane_tlsa_add(con, usage, selector, mtype, data, len); -+ OPENSSL_free(data); -+ -+ if (ret == 0) { -+ ERR_print_errors(bio_err); -+ BIO_printf(bio_err, "%s: warning: unusable TLSA rrdata: %s\n", -+ prog, rrdata); -+ return 0; -+ } -+ if (ret < 0) { -+ ERR_print_errors(bio_err); -+ BIO_printf(bio_err, "%s: warning: error loading TLSA rrdata: %s\n", -+ prog, rrdata); -+ return 0; -+ } -+ return ret; -+} -+ -+static int tlsa_import_rrset(SSL *con, STACK_OF(OPENSSL_STRING) *rrset) -+{ -+ int num = sk_OPENSSL_STRING_num(rrset); -+ int count = 0; -+ int i; -+ -+ for (i = 0; i < num; ++i) { -+ char *rrdata = sk_OPENSSL_STRING_value(rrset, i); -+ if (tlsa_import_rr(con, rrdata) > 0) -+ ++count; -+ } -+ return count > 0; -+} -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, -+ OPT_4, OPT_6, OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_UNIX, -+ OPT_XMPPHOST, OPT_VERIFY, -+ OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN, -+ OPT_CERTFORM, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, -+ OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO, -+ OPT_SSL_CLIENT_ENGINE, OPT_RAND, OPT_IGN_EOF, OPT_NO_IGN_EOF, -+ OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_WDEBUG, -+ OPT_MSG, OPT_MSGFILE, OPT_ENGINE, OPT_TRACE, OPT_SECURITY_DEBUG, -+ OPT_SECURITY_DEBUG_VERBOSE, OPT_SHOWCERTS, OPT_NBIO_TEST, OPT_STATE, -+#ifndef OPENSSL_NO_PSK -+ OPT_PSK_IDENTITY, OPT_PSK, -+#endif -+#ifndef OPENSSL_NO_SRP -+ OPT_SRPUSER, OPT_SRPPASS, OPT_SRP_STRENGTH, OPT_SRP_LATEUSER, -+ OPT_SRP_MOREGROUPS, -+#endif -+ OPT_SSL3, OPT_SSL_CONFIG, -+ OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, -+ OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS, -+ OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, -+ OPT_VERIFYCAPATH, -+ OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, -+ OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN, -+ OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME, -+ OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_SMTPHOST, -+ OPT_ASYNC, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF, -+ OPT_V_ENUM, -+ OPT_X_ENUM, -+ OPT_S_ENUM, -+ OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_DANE_TLSA_DOMAIN, -+#ifndef OPENSSL_NO_CT -+ OPT_CT, OPT_NOCT, OPT_CTLOG_FILE, -+#endif -+ OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME -+} OPTION_CHOICE; -+ -+OPTIONS s_client_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"host", OPT_HOST, 's', "Use -connect instead"}, -+ {"port", OPT_PORT, 'p', "Use -connect instead"}, -+ {"connect", OPT_CONNECT, 's', -+ "TCP/IP where to connect (default is :" PORT ")"}, -+ {"proxy", OPT_PROXY, 's', -+ "Connect to via specified proxy to the real server"}, -+#ifdef AF_UNIX -+ {"unix", OPT_UNIX, 's', "Connect over the specified Unix-domain socket"}, -+#endif -+ {"4", OPT_4, '-', "Use IPv4 only"}, -+#ifdef AF_INET6 -+ {"6", OPT_6, '-', "Use IPv6 only"}, -+#endif -+ {"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"}, -+ {"cert", OPT_CERT, '<', "Certificate file to use, PEM format assumed"}, -+ {"certform", OPT_CERTFORM, 'F', -+ "Certificate format (PEM or DER) PEM default"}, -+ {"key", OPT_KEY, 's', "Private key file to use, if not in -cert file"}, -+ {"keyform", OPT_KEYFORM, 'E', "Key format (PEM, DER or engine) PEM default"}, -+ {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, -+ {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, -+ {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, -+ {"no-CAfile", OPT_NOCAFILE, '-', -+ "Do not load the default certificates file"}, -+ {"no-CApath", OPT_NOCAPATH, '-', -+ "Do not load certificates from the default certificates directory"}, -+ {"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"}, -+ {"dane_tlsa_rrdata", OPT_DANE_TLSA_RRDATA, 's', -+ "DANE TLSA rrdata presentation form"}, -+ {"dane_ee_no_namechecks", OPT_DANE_EE_NO_NAME, '-', -+ "Disable name checks when matching DANE-EE(3) TLSA records"}, -+ {"reconnect", OPT_RECONNECT, '-', -+ "Drop and re-make the connection with the same Session-ID"}, -+ {"showcerts", OPT_SHOWCERTS, '-', "Show all certificates in the chain"}, -+ {"debug", OPT_DEBUG, '-', "Extra output"}, -+ {"msg", OPT_MSG, '-', "Show protocol messages"}, -+ {"msgfile", OPT_MSGFILE, '>', -+ "File to send output of -msg or -trace, instead of stdout"}, -+ {"nbio_test", OPT_NBIO_TEST, '-', "More ssl protocol testing"}, -+ {"state", OPT_STATE, '-', "Print the ssl states"}, -+ {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, -+ {"quiet", OPT_QUIET, '-', "No s_client output"}, -+ {"ign_eof", OPT_IGN_EOF, '-', "Ignore input eof (default when -quiet)"}, -+ {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Don't ignore input eof"}, -+ {"starttls", OPT_STARTTLS, 's', -+ "Use the appropriate STARTTLS command before starting TLS"}, -+ {"xmpphost", OPT_XMPPHOST, 's', -+ "Host to use with \"-starttls xmpp[-server]\""}, -+ {"rand", OPT_RAND, 's', -+ "Load the file(s) into the random number generator"}, -+ {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"}, -+ {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"}, -+ {"use_srtp", OPT_USE_SRTP, 's', -+ "Offer SRTP key management with a colon-separated profile list"}, -+ {"keymatexport", OPT_KEYMATEXPORT, 's', -+ "Export keying material using label"}, -+ {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', -+ "Export len bytes of keying material (default 20)"}, -+ {"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"}, -+ {"name", OPT_SMTPHOST, 's', "Hostname to use for \"-starttls smtp\""}, -+ {"CRL", OPT_CRL, '<', "CRL file to use"}, -+ {"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"}, -+ {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, -+ {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', -+ "Close connection on verification error"}, -+ {"verify_quiet", OPT_VERIFY_QUIET, '-', "Restrict verify output to errors"}, -+ {"brief", OPT_BRIEF, '-', -+ "Restrict output to brief summary of connection parameters"}, -+ {"prexit", OPT_PREXIT, '-', -+ "Print session information when the program exits"}, -+ {"security_debug", OPT_SECURITY_DEBUG, '-', -+ "Enable security debug messages"}, -+ {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-', -+ "Output more security debug output"}, -+ {"cert_chain", OPT_CERT_CHAIN, '<', -+ "Certificate chain file (in PEM format)"}, -+ {"chainCApath", OPT_CHAINCAPATH, '/', -+ "Use dir as certificate store path to build CA certificate chain"}, -+ {"verifyCApath", OPT_VERIFYCAPATH, '/', -+ "Use dir as certificate store path to verify CA certificate"}, -+ {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, -+ {"chainCAfile", OPT_CHAINCAFILE, '<', -+ "CA file for certificate chain (PEM format)"}, -+ {"verifyCAfile", OPT_VERIFYCAFILE, '<', -+ "CA file for certificate verification (PEM format)"}, -+ {"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"}, -+ {"servername", OPT_SERVERNAME, 's', -+ "Set TLS extension servername in ClientHello"}, -+ {"tlsextdebug", OPT_TLSEXTDEBUG, '-', -+ "Hex dump of all TLS extensions received"}, -+#ifndef OPENSSL_NO_OCSP -+ {"status", OPT_STATUS, '-', "Request certificate status from server"}, -+#endif -+ {"serverinfo", OPT_SERVERINFO, 's', -+ "types Send empty ClientHello extensions (comma-separated numbers)"}, -+ {"alpn", OPT_ALPN, 's', -+ "Enable ALPN extension, considering named protocols supported (comma-separated list)"}, -+ {"async", OPT_ASYNC, '-', "Support asynchronous operation"}, -+ {"ssl_config", OPT_SSL_CONFIG, 's', "Use specified configuration file"}, -+ {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'n', -+ "Size used to split data for encrypt pipelines"}, -+ {"max_pipelines", OPT_MAX_PIPELINES, 'n', -+ "Maximum number of encrypt/decrypt pipelines to be used"}, -+ {"read_buf", OPT_READ_BUF, 'n', -+ "Default read buffer size to be used for connections"}, -+ OPT_S_OPTIONS, -+ OPT_V_OPTIONS, -+ OPT_X_OPTIONS, -+#ifndef OPENSSL_NO_SSL3 -+ {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, -+#endif -+#ifndef OPENSSL_NO_TLS1 -+ {"tls1", OPT_TLS1, '-', "Just use TLSv1"}, -+#endif -+#ifndef OPENSSL_NO_TLS1_1 -+ {"tls1_1", OPT_TLS1_1, '-', "Just use TLSv1.1"}, -+#endif -+#ifndef OPENSSL_NO_TLS1_2 -+ {"tls1_2", OPT_TLS1_2, '-', "Just use TLSv1.2"}, -+#endif -+#ifndef OPENSSL_NO_DTLS -+ {"dtls", OPT_DTLS, '-', "Use any version of DTLS"}, -+ {"timeout", OPT_TIMEOUT, '-', -+ "Enable send/receive timeout on DTLS connections"}, -+ {"mtu", OPT_MTU, 'p', "Set the link layer MTU"}, -+#endif -+#ifndef OPENSSL_NO_DTLS1 -+ {"dtls1", OPT_DTLS1, '-', "Just use DTLSv1"}, -+#endif -+#ifndef OPENSSL_NO_DTLS1_2 -+ {"dtls1_2", OPT_DTLS1_2, '-', "Just use DTLSv1.2"}, -+#endif -+#ifndef OPENSSL_NO_SSL_TRACE -+ {"trace", OPT_TRACE, '-', "Show trace output of protocol messages"}, -+#endif -+#ifdef WATT32 -+ {"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"}, -+#endif -+ {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, -+#ifndef OPENSSL_NO_PSK -+ {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"}, -+ {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, -+#endif -+#ifndef OPENSSL_NO_SRP -+ {"srpuser", OPT_SRPUSER, 's', "SRP authentication for 'user'"}, -+ {"srppass", OPT_SRPPASS, 's', "Password for 'user'"}, -+ {"srp_lateuser", OPT_SRP_LATEUSER, '-', -+ "SRP username into second ClientHello message"}, -+ {"srp_moregroups", OPT_SRP_MOREGROUPS, '-', -+ "Tolerate other than the known g N values."}, -+ {"srp_strength", OPT_SRP_STRENGTH, 'p', "Minimal length in bits for N"}, -+#endif -+#ifndef OPENSSL_NO_NEXTPROTONEG -+ {"nextprotoneg", OPT_NEXTPROTONEG, 's', -+ "Enable NPN extension, considering named protocols supported (comma-separated list)"}, -+#endif -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+ {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's', -+ "Specify engine to be used for client certificate operations"}, -+#endif -+#ifndef OPENSSL_NO_CT -+ {"ct", OPT_CT, '-', "Request and parse SCTs (also enables OCSP stapling)"}, -+ {"noct", OPT_NOCT, '-', "Do not request or parse SCTs (default)"}, -+ {"ctlogfile", OPT_CTLOG_FILE, '<', "CT log list CONF file"}, -+#endif -+ {NULL, OPT_EOF, 0x00, NULL} -+}; -+ -+typedef enum PROTOCOL_choice { -+ PROTO_OFF, -+ PROTO_SMTP, -+ PROTO_POP3, -+ PROTO_IMAP, -+ PROTO_FTP, -+ PROTO_TELNET, -+ PROTO_XMPP, -+ PROTO_XMPP_SERVER, -+ PROTO_CONNECT, -+ PROTO_IRC -+} PROTOCOL_CHOICE; -+ -+static const OPT_PAIR services[] = { -+ {"smtp", PROTO_SMTP}, -+ {"pop3", PROTO_POP3}, -+ {"imap", PROTO_IMAP}, -+ {"ftp", PROTO_FTP}, -+ {"xmpp", PROTO_XMPP}, -+ {"xmpp-server", PROTO_XMPP_SERVER}, -+ {"telnet", PROTO_TELNET}, -+ {"irc", PROTO_IRC}, -+ {NULL, 0} -+}; -+ -+#define IS_INET_FLAG(o) \ -+ (o == OPT_4 || o == OPT_6 || o == OPT_HOST || o == OPT_PORT || o == OPT_CONNECT) -+#define IS_UNIX_FLAG(o) (o == OPT_UNIX) -+ -+#define IS_PROT_FLAG(o) \ -+ (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ -+ || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2) -+ -+/* Free |*dest| and optionally set it to a copy of |source|. */ -+static void freeandcopy(char **dest, const char *source) -+{ -+ OPENSSL_free(*dest); -+ *dest = NULL; -+ if (source != NULL) -+ *dest = OPENSSL_strdup(source); -+} -+ -+int s_client_main(int argc, char **argv) -+{ -+ BIO *sbio; -+ EVP_PKEY *key = NULL; -+ SSL *con = NULL; -+ SSL_CTX *ctx = NULL; -+ STACK_OF(X509) *chain = NULL; -+ X509 *cert = NULL; -+ X509_VERIFY_PARAM *vpm = NULL; -+ SSL_EXCERT *exc = NULL; -+ SSL_CONF_CTX *cctx = NULL; -+ STACK_OF(OPENSSL_STRING) *ssl_args = NULL; -+ char *dane_tlsa_domain = NULL; -+ STACK_OF(OPENSSL_STRING) *dane_tlsa_rrset = NULL; -+ int dane_ee_no_name = 0; -+ STACK_OF(X509_CRL) *crls = NULL; -+ const SSL_METHOD *meth = TLS_client_method(); -+ const char *CApath = NULL, *CAfile = NULL; -+ char *cbuf = NULL, *sbuf = NULL; -+ char *mbuf = NULL, *proxystr = NULL, *connectstr = NULL; -+ char *cert_file = NULL, *key_file = NULL, *chain_file = NULL; -+ char *chCApath = NULL, *chCAfile = NULL, *host = NULL; -+ char *port = OPENSSL_strdup(PORT); -+ char *inrand = NULL; -+ char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; -+ char *sess_in = NULL, *sess_out = NULL, *crl_file = NULL, *p; -+ char *xmpphost = NULL; -+ const char *ehlo = "mail.example.com"; -+ struct timeval timeout, *timeoutp; -+ fd_set readfds, writefds; -+ int noCApath = 0, noCAfile = 0; -+ int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_PEM; -+ int key_format = FORMAT_PEM, crlf = 0, full_log = 1, mbuf_len = 0; -+ int prexit = 0; -+ int sdebug = 0; -+ int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0; -+ int ret = 1, in_init = 1, i, nbio_test = 0, s = -1, k, width, state = 0; -+ int sbuf_len, sbuf_off, cmdletters = 1; -+ int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM; -+ int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0; -+ int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; -+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) -+ int at_eof = 0; -+#endif -+ int read_buf_len = 0; -+ int fallback_scsv = 0; -+ long randamt = 0; -+ OPTION_CHOICE o; -+#ifndef OPENSSL_NO_DTLS -+ int enable_timeouts = 0; -+ long socket_mtu = 0; -+#endif -+#ifndef OPENSSL_NO_ENGINE -+ ENGINE *ssl_client_engine = NULL; -+#endif -+ ENGINE *e = NULL; -+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) -+ struct timeval tv; -+#endif -+ char *servername = NULL; -+ const char *alpn_in = NULL; -+ tlsextctx tlsextcbp = { NULL, 0 }; -+ const char *ssl_config = NULL; -+#define MAX_SI_TYPES 100 -+ unsigned short serverinfo_types[MAX_SI_TYPES]; -+ int serverinfo_count = 0, start = 0, len; -+#ifndef OPENSSL_NO_NEXTPROTONEG -+ const char *next_proto_neg_in = NULL; -+#endif -+#ifndef OPENSSL_NO_SRP -+ char *srppass = NULL; -+ int srp_lateuser = 0; -+ SRP_ARG srp_arg = { NULL, NULL, 0, 0, 0, 1024 }; -+#endif -+#ifndef OPENSSL_NO_CT -+ char *ctlog_file = NULL; -+ int ct_validation = 0; -+#endif -+ int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0; -+ int async = 0; -+ unsigned int split_send_fragment = 0; -+ unsigned int max_pipelines = 0; -+ enum { use_inet, use_unix, use_unknown } connect_type = use_unknown; -+ int count4or6 = 0; -+ int c_nbio = 0, c_msg = 0, c_ign_eof = 0, c_brief = 0; -+ int c_tlsextdebug = 0; -+#ifndef OPENSSL_NO_OCSP -+ int c_status_req = 0; -+#endif -+ BIO *bio_c_msg = NULL; -+ -+ FD_ZERO(&readfds); -+ FD_ZERO(&writefds); -+/* Known false-positive of MemorySanitizer. */ -+#if defined(__has_feature) -+# if __has_feature(memory_sanitizer) -+ __msan_unpoison(&readfds, sizeof(readfds)); -+ __msan_unpoison(&writefds, sizeof(writefds)); -+# endif -+#endif -+ -+ prog = opt_progname(argv[0]); -+ c_quiet = 0; -+ c_debug = 0; -+ c_showcerts = 0; -+ c_nbio = 0; -+ vpm = X509_VERIFY_PARAM_new(); -+ cctx = SSL_CONF_CTX_new(); -+ -+ if (vpm == NULL || cctx == NULL) { -+ BIO_printf(bio_err, "%s: out of memory\n", prog); -+ goto end; -+ } -+ -+ cbuf = app_malloc(BUFSIZZ, "cbuf"); -+ sbuf = app_malloc(BUFSIZZ, "sbuf"); -+ mbuf = app_malloc(BUFSIZZ, "mbuf"); -+ -+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT | SSL_CONF_FLAG_CMDLINE); -+ -+ prog = opt_init(argc, argv, s_client_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ /* Check for intermixing flags. */ -+ if (connect_type == use_unix && IS_INET_FLAG(o)) { -+ BIO_printf(bio_err, -+ "%s: Intermixed protocol flags (unix and internet domains)\n", -+ prog); -+ goto end; -+ } -+ if (connect_type == use_inet && IS_UNIX_FLAG(o)) { -+ BIO_printf(bio_err, -+ "%s: Intermixed protocol flags (internet and unix domains)\n", -+ prog); -+ goto end; -+ } -+ -+ if (IS_PROT_FLAG(o) && ++prot_opt > 1) { -+ BIO_printf(bio_err, "Cannot supply multiple protocol flags\n"); -+ goto end; -+ } -+ if (IS_NO_PROT_FLAG(o)) -+ no_prot_opt++; -+ if (prot_opt == 1 && no_prot_opt) { -+ BIO_printf(bio_err, -+ "Cannot supply both a protocol flag and '-no_'\n"); -+ goto end; -+ } -+ -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(s_client_options); -+ ret = 0; -+ goto end; -+ case OPT_4: -+ connect_type = use_inet; -+ socket_family = AF_INET; -+ count4or6++; -+ break; -+#ifdef AF_INET6 -+ case OPT_6: -+ connect_type = use_inet; -+ socket_family = AF_INET6; -+ count4or6++; -+ break; -+#endif -+ case OPT_HOST: -+ connect_type = use_inet; -+ freeandcopy(&host, opt_arg()); -+ break; -+ case OPT_PORT: -+ connect_type = use_inet; -+ freeandcopy(&port, opt_arg()); -+ break; -+ case OPT_CONNECT: -+ connect_type = use_inet; -+ freeandcopy(&connectstr, opt_arg()); -+ break; -+ case OPT_PROXY: -+ proxystr = opt_arg(); -+ starttls_proto = PROTO_CONNECT; -+ break; -+#ifdef AF_UNIX -+ case OPT_UNIX: -+ connect_type = use_unix; -+ socket_family = AF_UNIX; -+ freeandcopy(&host, opt_arg()); -+ break; -+#endif -+ case OPT_XMPPHOST: -+ xmpphost = opt_arg(); -+ break; -+ case OPT_SMTPHOST: -+ ehlo = opt_arg(); -+ break; -+ case OPT_VERIFY: -+ verify = SSL_VERIFY_PEER; -+ verify_args.depth = atoi(opt_arg()); -+ if (!c_quiet) -+ BIO_printf(bio_err, "verify depth is %d\n", verify_args.depth); -+ break; -+ case OPT_CERT: -+ cert_file = opt_arg(); -+ break; -+ case OPT_CRL: -+ crl_file = opt_arg(); -+ break; -+ case OPT_CRL_DOWNLOAD: -+ crl_download = 1; -+ break; -+ case OPT_SESS_OUT: -+ sess_out = opt_arg(); -+ break; -+ case OPT_SESS_IN: -+ sess_in = opt_arg(); -+ break; -+ case OPT_CERTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &cert_format)) -+ goto opthelp; -+ break; -+ case OPT_CRLFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format)) -+ goto opthelp; -+ break; -+ case OPT_VERIFY_RET_ERROR: -+ verify_args.return_error = 1; -+ break; -+ case OPT_VERIFY_QUIET: -+ verify_args.quiet = 1; -+ break; -+ case OPT_BRIEF: -+ c_brief = verify_args.quiet = c_quiet = 1; -+ break; -+ case OPT_S_CASES: -+ if (ssl_args == NULL) -+ ssl_args = sk_OPENSSL_STRING_new_null(); -+ if (ssl_args == NULL -+ || !sk_OPENSSL_STRING_push(ssl_args, opt_flag()) -+ || !sk_OPENSSL_STRING_push(ssl_args, opt_arg())) { -+ BIO_printf(bio_err, "%s: Memory allocation failure\n", prog); -+ goto end; -+ } -+ break; -+ case OPT_V_CASES: -+ if (!opt_verify(o, vpm)) -+ goto end; -+ vpmtouched++; -+ break; -+ case OPT_X_CASES: -+ if (!args_excert(o, &exc)) -+ goto end; -+ break; -+ case OPT_PREXIT: -+ prexit = 1; -+ break; -+ case OPT_CRLF: -+ crlf = 1; -+ break; -+ case OPT_QUIET: -+ c_quiet = c_ign_eof = 1; -+ break; -+ case OPT_NBIO: -+ c_nbio = 1; -+ break; -+ case OPT_NOCMDS: -+ cmdletters = 0; -+ break; -+ case OPT_ENGINE: -+ e = setup_engine(opt_arg(), 1); -+ break; -+ case OPT_SSL_CLIENT_ENGINE: -+#ifndef OPENSSL_NO_ENGINE -+ ssl_client_engine = ENGINE_by_id(opt_arg()); -+ if (ssl_client_engine == NULL) { -+ BIO_printf(bio_err, "Error getting client auth engine\n"); -+ goto opthelp; -+ } -+#endif -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ break; -+ case OPT_IGN_EOF: -+ c_ign_eof = 1; -+ break; -+ case OPT_NO_IGN_EOF: -+ c_ign_eof = 0; -+ break; -+ case OPT_DEBUG: -+ c_debug = 1; -+ break; -+ case OPT_TLSEXTDEBUG: -+ c_tlsextdebug = 1; -+ break; -+ case OPT_STATUS: -+#ifndef OPENSSL_NO_OCSP -+ c_status_req = 1; -+#endif -+ break; -+ case OPT_WDEBUG: -+#ifdef WATT32 -+ dbug_init(); -+#endif -+ break; -+ case OPT_MSG: -+ c_msg = 1; -+ break; -+ case OPT_MSGFILE: -+ bio_c_msg = BIO_new_file(opt_arg(), "w"); -+ break; -+ case OPT_TRACE: -+#ifndef OPENSSL_NO_SSL_TRACE -+ c_msg = 2; -+#endif -+ break; -+ case OPT_SECURITY_DEBUG: -+ sdebug = 1; -+ break; -+ case OPT_SECURITY_DEBUG_VERBOSE: -+ sdebug = 2; -+ break; -+ case OPT_SHOWCERTS: -+ c_showcerts = 1; -+ break; -+ case OPT_NBIO_TEST: -+ nbio_test = 1; -+ break; -+ case OPT_STATE: -+ state = 1; -+ break; -+#ifndef OPENSSL_NO_PSK -+ case OPT_PSK_IDENTITY: -+ psk_identity = opt_arg(); -+ break; -+ case OPT_PSK: -+ for (p = psk_key = opt_arg(); *p; p++) { -+ if (isxdigit(_UC(*p))) -+ continue; -+ BIO_printf(bio_err, "Not a hex number '%s'\n", psk_key); -+ goto end; -+ } -+ break; -+#endif -+#ifndef OPENSSL_NO_SRP -+ case OPT_SRPUSER: -+ srp_arg.srplogin = opt_arg(); -+ if (min_version < TLS1_VERSION) -+ min_version = TLS1_VERSION; -+ break; -+ case OPT_SRPPASS: -+ srppass = opt_arg(); -+ if (min_version < TLS1_VERSION) -+ min_version = TLS1_VERSION; -+ break; -+ case OPT_SRP_STRENGTH: -+ srp_arg.strength = atoi(opt_arg()); -+ BIO_printf(bio_err, "SRP minimal length for N is %d\n", -+ srp_arg.strength); -+ if (min_version < TLS1_VERSION) -+ min_version = TLS1_VERSION; -+ break; -+ case OPT_SRP_LATEUSER: -+ srp_lateuser = 1; -+ if (min_version < TLS1_VERSION) -+ min_version = TLS1_VERSION; -+ break; -+ case OPT_SRP_MOREGROUPS: -+ srp_arg.amp = 1; -+ if (min_version < TLS1_VERSION) -+ min_version = TLS1_VERSION; -+ break; -+#endif -+ case OPT_SSL_CONFIG: -+ ssl_config = opt_arg(); -+ break; -+ case OPT_SSL3: -+ min_version = SSL3_VERSION; -+ max_version = SSL3_VERSION; -+ break; -+ case OPT_TLS1_2: -+ min_version = TLS1_2_VERSION; -+ max_version = TLS1_2_VERSION; -+ break; -+ case OPT_TLS1_1: -+ min_version = TLS1_1_VERSION; -+ max_version = TLS1_1_VERSION; -+ break; -+ case OPT_TLS1: -+ min_version = TLS1_VERSION; -+ max_version = TLS1_VERSION; -+ break; -+ case OPT_DTLS: -+#ifndef OPENSSL_NO_DTLS -+ meth = DTLS_client_method(); -+ socket_type = SOCK_DGRAM; -+#endif -+ break; -+ case OPT_DTLS1: -+#ifndef OPENSSL_NO_DTLS1 -+ meth = DTLS_client_method(); -+ min_version = DTLS1_VERSION; -+ max_version = DTLS1_VERSION; -+ socket_type = SOCK_DGRAM; -+#endif -+ break; -+ case OPT_DTLS1_2: -+#ifndef OPENSSL_NO_DTLS1_2 -+ meth = DTLS_client_method(); -+ min_version = DTLS1_2_VERSION; -+ max_version = DTLS1_2_VERSION; -+ socket_type = SOCK_DGRAM; -+#endif -+ break; -+ case OPT_TIMEOUT: -+#ifndef OPENSSL_NO_DTLS -+ enable_timeouts = 1; -+#endif -+ break; -+ case OPT_MTU: -+#ifndef OPENSSL_NO_DTLS -+ socket_mtu = atol(opt_arg()); -+#endif -+ break; -+ case OPT_FALLBACKSCSV: -+ fallback_scsv = 1; -+ break; -+ case OPT_KEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PDE, &key_format)) -+ goto opthelp; -+ break; -+ case OPT_PASS: -+ passarg = opt_arg(); -+ break; -+ case OPT_CERT_CHAIN: -+ chain_file = opt_arg(); -+ break; -+ case OPT_KEY: -+ key_file = opt_arg(); -+ break; -+ case OPT_RECONNECT: -+ reconnect = 5; -+ break; -+ case OPT_CAPATH: -+ CApath = opt_arg(); -+ break; -+ case OPT_NOCAPATH: -+ noCApath = 1; -+ break; -+ case OPT_CHAINCAPATH: -+ chCApath = opt_arg(); -+ break; -+ case OPT_VERIFYCAPATH: -+ vfyCApath = opt_arg(); -+ break; -+ case OPT_BUILD_CHAIN: -+ build_chain = 1; -+ break; -+ case OPT_CAFILE: -+ CAfile = opt_arg(); -+ break; -+ case OPT_NOCAFILE: -+ noCAfile = 1; -+ break; -+#ifndef OPENSSL_NO_CT -+ case OPT_NOCT: -+ ct_validation = 0; -+ break; -+ case OPT_CT: -+ ct_validation = 1; -+ break; -+ case OPT_CTLOG_FILE: -+ ctlog_file = opt_arg(); -+ break; -+#endif -+ case OPT_CHAINCAFILE: -+ chCAfile = opt_arg(); -+ break; -+ case OPT_VERIFYCAFILE: -+ vfyCAfile = opt_arg(); -+ break; -+ case OPT_DANE_TLSA_DOMAIN: -+ dane_tlsa_domain = opt_arg(); -+ break; -+ case OPT_DANE_TLSA_RRDATA: -+ if (dane_tlsa_rrset == NULL) -+ dane_tlsa_rrset = sk_OPENSSL_STRING_new_null(); -+ if (dane_tlsa_rrset == NULL || -+ !sk_OPENSSL_STRING_push(dane_tlsa_rrset, opt_arg())) { -+ BIO_printf(bio_err, "%s: Memory allocation failure\n", prog); -+ goto end; -+ } -+ break; -+ case OPT_DANE_EE_NO_NAME: -+ dane_ee_no_name = 1; -+ break; -+ case OPT_NEXTPROTONEG: -+#ifndef OPENSSL_NO_NEXTPROTONEG -+ next_proto_neg_in = opt_arg(); -+#endif -+ break; -+ case OPT_ALPN: -+ alpn_in = opt_arg(); -+ break; -+ case OPT_SERVERINFO: -+ p = opt_arg(); -+ len = strlen(p); -+ for (start = 0, i = 0; i <= len; ++i) { -+ if (i == len || p[i] == ',') { -+ serverinfo_types[serverinfo_count] = atoi(p + start); -+ if (++serverinfo_count == MAX_SI_TYPES) -+ break; -+ start = i + 1; -+ } -+ } -+ break; -+ case OPT_STARTTLS: -+ if (!opt_pair(opt_arg(), services, &starttls_proto)) -+ goto end; -+ break; -+ case OPT_SERVERNAME: -+ servername = opt_arg(); -+ break; -+ case OPT_USE_SRTP: -+ srtp_profiles = opt_arg(); -+ break; -+ case OPT_KEYMATEXPORT: -+ keymatexportlabel = opt_arg(); -+ break; -+ case OPT_KEYMATEXPORTLEN: -+ keymatexportlen = atoi(opt_arg()); -+ break; -+ case OPT_ASYNC: -+ async = 1; -+ break; -+ case OPT_SPLIT_SEND_FRAG: -+ split_send_fragment = atoi(opt_arg()); -+ if (split_send_fragment == 0) { -+ /* -+ * Not allowed - set to a deliberately bad value so we get an -+ * error message below -+ */ -+ split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH + 1; -+ } -+ break; -+ case OPT_MAX_PIPELINES: -+ max_pipelines = atoi(opt_arg()); -+ break; -+ case OPT_READ_BUF: -+ read_buf_len = atoi(opt_arg()); -+ break; -+ } -+ } -+ if (count4or6 >= 2) { -+ BIO_printf(bio_err, "%s: Can't use both -4 and -6\n", prog); -+ goto opthelp; -+ } -+ argc = opt_num_rest(); -+ if (argc != 0) -+ goto opthelp; -+ -+ if (proxystr) { -+ int res; -+ char *tmp_host = host, *tmp_port = port; -+ if (connectstr == NULL) { -+ BIO_printf(bio_err, "%s: -proxy requires use of -connect\n", prog); -+ goto opthelp; -+ } -+ res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST); -+ if (tmp_host != host) -+ OPENSSL_free(tmp_host); -+ if (tmp_port != port) -+ OPENSSL_free(tmp_port); -+ if (!res) { -+ BIO_printf(bio_err, -+ "%s: -proxy argument malformed or ambiguous\n", prog); -+ goto end; -+ } -+ } else { -+ int res = 1; -+ char *tmp_host = host, *tmp_port = port; -+ if (connectstr != NULL) -+ res = BIO_parse_hostserv(connectstr, &host, &port, -+ BIO_PARSE_PRIO_HOST); -+ if (tmp_host != host) -+ OPENSSL_free(tmp_host); -+ if (tmp_port != port) -+ OPENSSL_free(tmp_port); -+ if (!res) { -+ BIO_printf(bio_err, -+ "%s: -connect argument malformed or ambiguous\n", -+ prog); -+ goto end; -+ } -+ } -+ -+ if (socket_family == AF_UNIX && socket_type != SOCK_STREAM) { -+ BIO_printf(bio_err, -+ "Can't use unix sockets and datagrams together\n"); -+ goto end; -+ } -+ -+ if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) { -+ BIO_printf(bio_err, "Bad split send fragment size\n"); -+ goto end; -+ } -+ -+ if (max_pipelines > SSL_MAX_PIPELINES) { -+ BIO_printf(bio_err, "Bad max pipelines value\n"); -+ goto end; -+ } -+ -+#if !defined(OPENSSL_NO_NEXTPROTONEG) -+ next_proto.status = -1; -+ if (next_proto_neg_in) { -+ next_proto.data = -+ next_protos_parse(&next_proto.len, next_proto_neg_in); -+ if (next_proto.data == NULL) { -+ BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n"); -+ goto end; -+ } -+ } else -+ next_proto.data = NULL; -+#endif -+ -+ if (!app_passwd(passarg, NULL, &pass, NULL)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ -+ if (key_file == NULL) -+ key_file = cert_file; -+ -+ if (key_file) { -+ key = load_key(key_file, key_format, 0, pass, e, -+ "client certificate private key file"); -+ if (key == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (cert_file) { -+ cert = load_cert(cert_file, cert_format, "client certificate file"); -+ if (cert == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (chain_file) { -+ if (!load_certs(chain_file, &chain, FORMAT_PEM, NULL, -+ "client certificate chain")) -+ goto end; -+ } -+ -+ if (crl_file) { -+ X509_CRL *crl; -+ crl = load_crl(crl_file, crl_format); -+ if (crl == NULL) { -+ BIO_puts(bio_err, "Error loading CRL\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ crls = sk_X509_CRL_new_null(); -+ if (crls == NULL || !sk_X509_CRL_push(crls, crl)) { -+ BIO_puts(bio_err, "Error adding CRL\n"); -+ ERR_print_errors(bio_err); -+ X509_CRL_free(crl); -+ goto end; -+ } -+ } -+ -+ if (!load_excert(&exc)) -+ goto end; -+ -+ if (!app_RAND_load_file(NULL, 1) && inrand == NULL -+ && !RAND_status()) { -+ BIO_printf(bio_err, -+ "warning, not much extra random data, consider using the -rand option\n"); -+ } -+ if (inrand != NULL) { -+ randamt = app_RAND_load_files(inrand); -+ BIO_printf(bio_err, "%ld semi-random bytes loaded\n", randamt); -+ } -+ -+ if (bio_c_out == NULL) { -+ if (c_quiet && !c_debug) { -+ bio_c_out = BIO_new(BIO_s_null()); -+ if (c_msg && !bio_c_msg) -+ bio_c_msg = dup_bio_out(FORMAT_TEXT); -+ } else if (bio_c_out == NULL) -+ bio_c_out = dup_bio_out(FORMAT_TEXT); -+ } -+#ifndef OPENSSL_NO_SRP -+ if (!app_passwd(srppass, NULL, &srp_arg.srppassin, NULL)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+#endif -+ -+ ctx = SSL_CTX_new(meth); -+ if (ctx == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (sdebug) -+ ssl_ctx_security_debug(ctx, sdebug); -+ -+ if (ssl_config) { -+ if (SSL_CTX_config(ctx, ssl_config) == 0) { -+ BIO_printf(bio_err, "Error using configuration \"%s\"\n", -+ ssl_config); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0) -+ goto end; -+ if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) -+ goto end; -+ -+ if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) { -+ BIO_printf(bio_err, "Error setting verify params\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (async) { -+ SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC); -+ } -+ if (split_send_fragment > 0) { -+ SSL_CTX_set_split_send_fragment(ctx, split_send_fragment); -+ } -+ if (max_pipelines > 0) { -+ SSL_CTX_set_max_pipelines(ctx, max_pipelines); -+ } -+ -+ if (read_buf_len > 0) { -+ SSL_CTX_set_default_read_buffer_len(ctx, read_buf_len); -+ } -+ -+ if (!config_ctx(cctx, ssl_args, ctx)) -+ goto end; -+ -+ if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, -+ crls, crl_download)) { -+ BIO_printf(bio_err, "Error loading store locations\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+#ifndef OPENSSL_NO_ENGINE -+ if (ssl_client_engine) { -+ if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) { -+ BIO_puts(bio_err, "Error setting client auth engine\n"); -+ ERR_print_errors(bio_err); -+ ENGINE_free(ssl_client_engine); -+ goto end; -+ } -+ ENGINE_free(ssl_client_engine); -+ } -+#endif -+ -+#ifndef OPENSSL_NO_PSK -+ if (psk_key != NULL) { -+ if (c_debug) -+ BIO_printf(bio_c_out, "PSK key given, setting client callback\n"); -+ SSL_CTX_set_psk_client_callback(ctx, psk_client_cb); -+ } -+#endif -+#ifndef OPENSSL_NO_SRTP -+ if (srtp_profiles != NULL) { -+ /* Returns 0 on success! */ -+ if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles) != 0) { -+ BIO_printf(bio_err, "Error setting SRTP profile\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+#endif -+ -+ if (exc) -+ ssl_ctx_set_excert(ctx, exc); -+ -+#if !defined(OPENSSL_NO_NEXTPROTONEG) -+ if (next_proto.data) -+ SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto); -+#endif -+ if (alpn_in) { -+ size_t alpn_len; -+ unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in); -+ -+ if (alpn == NULL) { -+ BIO_printf(bio_err, "Error parsing -alpn argument\n"); -+ goto end; -+ } -+ /* Returns 0 on success! */ -+ if (SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len) != 0) { -+ BIO_printf(bio_err, "Error setting ALPN\n"); -+ goto end; -+ } -+ OPENSSL_free(alpn); -+ } -+ -+ for (i = 0; i < serverinfo_count; i++) { -+ if (!SSL_CTX_add_client_custom_ext(ctx, -+ serverinfo_types[i], -+ NULL, NULL, NULL, -+ serverinfo_cli_parse_cb, NULL)) { -+ BIO_printf(bio_err, -+ "Warning: Unable to add custom extension %u, skipping\n", -+ serverinfo_types[i]); -+ } -+ } -+ -+ if (state) -+ SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); -+ -+#ifndef OPENSSL_NO_CT -+ /* Enable SCT processing, without early connection termination */ -+ if (ct_validation && -+ !SSL_CTX_enable_ct(ctx, SSL_CT_VALIDATION_PERMISSIVE)) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (!ctx_set_ctlog_list_file(ctx, ctlog_file)) { -+ if (ct_validation) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ /* -+ * If CT validation is not enabled, the log list isn't needed so don't -+ * show errors or abort. We try to load it regardless because then we -+ * can show the names of the logs any SCTs came from (SCTs may be seen -+ * even with validation disabled). -+ */ -+ ERR_clear_error(); -+ } -+#endif -+ -+ SSL_CTX_set_verify(ctx, verify, verify_callback); -+ -+ if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ ssl_ctx_add_crls(ctx, crls, crl_download); -+ -+ if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain)) -+ goto end; -+ -+ if (servername != NULL) { -+ tlsextcbp.biodebug = bio_err; -+ SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); -+ SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); -+ } -+# ifndef OPENSSL_NO_SRP -+ if (srp_arg.srplogin) { -+ if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin)) { -+ BIO_printf(bio_err, "Unable to set SRP username\n"); -+ goto end; -+ } -+ srp_arg.msg = c_msg; -+ srp_arg.debug = c_debug; -+ SSL_CTX_set_srp_cb_arg(ctx, &srp_arg); -+ SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb); -+ SSL_CTX_set_srp_strength(ctx, srp_arg.strength); -+ if (c_msg || c_debug || srp_arg.amp == 0) -+ SSL_CTX_set_srp_verify_param_callback(ctx, -+ ssl_srp_verify_param_cb); -+ } -+# endif -+ -+ if (dane_tlsa_domain != NULL) { -+ if (SSL_CTX_dane_enable(ctx) <= 0) { -+ BIO_printf(bio_err, -+ "%s: Error enabling DANE TLSA authentication.\n", -+ prog); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ con = SSL_new(ctx); -+ if (sess_in) { -+ SSL_SESSION *sess; -+ BIO *stmp = BIO_new_file(sess_in, "r"); -+ if (!stmp) { -+ BIO_printf(bio_err, "Can't open session file %s\n", sess_in); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL); -+ BIO_free(stmp); -+ if (!sess) { -+ BIO_printf(bio_err, "Can't open session file %s\n", sess_in); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (!SSL_set_session(con, sess)) { -+ BIO_printf(bio_err, "Can't set session\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ SSL_SESSION_free(sess); -+ } -+ -+ if (fallback_scsv) -+ SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV); -+ -+ if (servername != NULL) { -+ if (!SSL_set_tlsext_host_name(con, servername)) { -+ BIO_printf(bio_err, "Unable to set TLS servername extension.\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (dane_tlsa_domain != NULL) { -+ if (SSL_dane_enable(con, dane_tlsa_domain) <= 0) { -+ BIO_printf(bio_err, "%s: Error enabling DANE TLSA " -+ "authentication.\n", prog); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (dane_tlsa_rrset == NULL) { -+ BIO_printf(bio_err, "%s: DANE TLSA authentication requires at " -+ "least one -dane_tlsa_rrdata option.\n", prog); -+ goto end; -+ } -+ if (tlsa_import_rrset(con, dane_tlsa_rrset) <= 0) { -+ BIO_printf(bio_err, "%s: Failed to import any TLSA " -+ "records.\n", prog); -+ goto end; -+ } -+ if (dane_ee_no_name) -+ SSL_dane_set_flags(con, DANE_FLAG_NO_DANE_EE_NAMECHECKS); -+ } else if (dane_tlsa_rrset != NULL) { -+ BIO_printf(bio_err, "%s: DANE TLSA authentication requires the " -+ "-dane_tlsa_domain option.\n", prog); -+ goto end; -+ } -+ -+ re_start: -+ if (init_client(&s, host, port, socket_family, socket_type) == 0) { -+ BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error()); -+ BIO_closesocket(s); -+ goto end; -+ } -+ BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s); -+ -+ if (c_nbio) { -+ if (!BIO_socket_nbio(s, 1)) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ BIO_printf(bio_c_out, "Turned on non blocking io\n"); -+ } -+#ifndef OPENSSL_NO_DTLS -+ if (socket_type == SOCK_DGRAM) { -+ union BIO_sock_info_u peer_info; -+ -+ sbio = BIO_new_dgram(s, BIO_NOCLOSE); -+ if ((peer_info.addr = BIO_ADDR_new()) == NULL) { -+ BIO_printf(bio_err, "memory allocation failure\n"); -+ BIO_closesocket(s); -+ goto end; -+ } -+ if (!BIO_sock_info(s, BIO_SOCK_INFO_ADDRESS, &peer_info)) { -+ BIO_printf(bio_err, "getsockname:errno=%d\n", -+ get_last_socket_error()); -+ BIO_ADDR_free(peer_info.addr); -+ BIO_closesocket(s); -+ goto end; -+ } -+ -+ (void)BIO_ctrl_set_connected(sbio, peer_info.addr); -+ BIO_ADDR_free(peer_info.addr); -+ peer_info.addr = NULL; -+ -+ if (enable_timeouts) { -+ timeout.tv_sec = 0; -+ timeout.tv_usec = DGRAM_RCV_TIMEOUT; -+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); -+ -+ timeout.tv_sec = 0; -+ timeout.tv_usec = DGRAM_SND_TIMEOUT; -+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); -+ } -+ -+ if (socket_mtu) { -+ if (socket_mtu < DTLS_get_link_min_mtu(con)) { -+ BIO_printf(bio_err, "MTU too small. Must be at least %ld\n", -+ DTLS_get_link_min_mtu(con)); -+ BIO_free(sbio); -+ goto shut; -+ } -+ SSL_set_options(con, SSL_OP_NO_QUERY_MTU); -+ if (!DTLS_set_link_mtu(con, socket_mtu)) { -+ BIO_printf(bio_err, "Failed to set MTU\n"); -+ BIO_free(sbio); -+ goto shut; -+ } -+ } else -+ /* want to do MTU discovery */ -+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); -+ } else -+#endif /* OPENSSL_NO_DTLS */ -+ sbio = BIO_new_socket(s, BIO_NOCLOSE); -+ -+ if (nbio_test) { -+ BIO *test; -+ -+ test = BIO_new(BIO_f_nbio_test()); -+ sbio = BIO_push(test, sbio); -+ } -+ -+ if (c_debug) { -+ BIO_set_callback(sbio, bio_dump_callback); -+ BIO_set_callback_arg(sbio, (char *)bio_c_out); -+ } -+ if (c_msg) { -+#ifndef OPENSSL_NO_SSL_TRACE -+ if (c_msg == 2) -+ SSL_set_msg_callback(con, SSL_trace); -+ else -+#endif -+ SSL_set_msg_callback(con, msg_cb); -+ SSL_set_msg_callback_arg(con, bio_c_msg ? bio_c_msg : bio_c_out); -+ } -+ -+ if (c_tlsextdebug) { -+ SSL_set_tlsext_debug_callback(con, tlsext_cb); -+ SSL_set_tlsext_debug_arg(con, bio_c_out); -+ } -+#ifndef OPENSSL_NO_OCSP -+ if (c_status_req) { -+ SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp); -+ SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb); -+ SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out); -+ } -+#endif -+ -+ SSL_set_bio(con, sbio, sbio); -+ SSL_set_connect_state(con); -+ -+ /* ok, lets connect */ -+ if (fileno_stdin() > SSL_get_fd(con)) -+ width = fileno_stdin() + 1; -+ else -+ width = SSL_get_fd(con) + 1; -+ -+ read_tty = 1; -+ write_tty = 0; -+ tty_on = 0; -+ read_ssl = 1; -+ write_ssl = 1; -+ -+ cbuf_len = 0; -+ cbuf_off = 0; -+ sbuf_len = 0; -+ sbuf_off = 0; -+ -+ switch ((PROTOCOL_CHOICE) starttls_proto) { -+ case PROTO_OFF: -+ break; -+ case PROTO_SMTP: -+ { -+ /* -+ * This is an ugly hack that does a lot of assumptions. We do -+ * have to handle multi-line responses which may come in a single -+ * packet or not. We therefore have to use BIO_gets() which does -+ * need a buffering BIO. So during the initial chitchat we do -+ * push a buffering BIO into the chain that is removed again -+ * later on to not disturb the rest of the s_client operation. -+ */ -+ int foundit = 0; -+ BIO *fbio = BIO_new(BIO_f_buffer()); -+ BIO_push(fbio, sbio); -+ /* wait for multi-line response to end from SMTP */ -+ do { -+ mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); -+ } -+ while (mbuf_len > 3 && mbuf[3] == '-'); -+ BIO_printf(fbio, "EHLO %s\r\n", ehlo); -+ (void)BIO_flush(fbio); -+ /* wait for multi-line response to end EHLO SMTP response */ -+ do { -+ mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); -+ if (strstr(mbuf, "STARTTLS")) -+ foundit = 1; -+ } -+ while (mbuf_len > 3 && mbuf[3] == '-'); -+ (void)BIO_flush(fbio); -+ BIO_pop(fbio); -+ BIO_free(fbio); -+ if (!foundit) -+ BIO_printf(bio_err, -+ "didn't find starttls in server response," -+ " trying anyway...\n"); -+ BIO_printf(sbio, "STARTTLS\r\n"); -+ BIO_read(sbio, sbuf, BUFSIZZ); -+ } -+ break; -+ case PROTO_POP3: -+ { -+ BIO_read(sbio, mbuf, BUFSIZZ); -+ BIO_printf(sbio, "STLS\r\n"); -+ mbuf_len = BIO_read(sbio, sbuf, BUFSIZZ); -+ if (mbuf_len < 0) { -+ BIO_printf(bio_err, "BIO_read failed\n"); -+ goto end; -+ } -+ } -+ break; -+ case PROTO_IMAP: -+ { -+ int foundit = 0; -+ BIO *fbio = BIO_new(BIO_f_buffer()); -+ BIO_push(fbio, sbio); -+ BIO_gets(fbio, mbuf, BUFSIZZ); -+ /* STARTTLS command requires CAPABILITY... */ -+ BIO_printf(fbio, ". CAPABILITY\r\n"); -+ (void)BIO_flush(fbio); -+ /* wait for multi-line CAPABILITY response */ -+ do { -+ mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); -+ if (strstr(mbuf, "STARTTLS")) -+ foundit = 1; -+ } -+ while (mbuf_len > 3 && mbuf[0] != '.'); -+ (void)BIO_flush(fbio); -+ BIO_pop(fbio); -+ BIO_free(fbio); -+ if (!foundit) -+ BIO_printf(bio_err, -+ "didn't find STARTTLS in server response," -+ " trying anyway...\n"); -+ BIO_printf(sbio, ". STARTTLS\r\n"); -+ BIO_read(sbio, sbuf, BUFSIZZ); -+ } -+ break; -+ case PROTO_FTP: -+ { -+ BIO *fbio = BIO_new(BIO_f_buffer()); -+ BIO_push(fbio, sbio); -+ /* wait for multi-line response to end from FTP */ -+ do { -+ mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); -+ } -+ while (mbuf_len > 3 && mbuf[3] == '-'); -+ (void)BIO_flush(fbio); -+ BIO_pop(fbio); -+ BIO_free(fbio); -+ BIO_printf(sbio, "AUTH TLS\r\n"); -+ BIO_read(sbio, sbuf, BUFSIZZ); -+ } -+ break; -+ case PROTO_XMPP: -+ case PROTO_XMPP_SERVER: -+ { -+ int seen = 0; -+ BIO_printf(sbio, "", -+ starttls_proto == PROTO_XMPP ? "client" : "server", -+ xmpphost ? xmpphost : host); -+ seen = BIO_read(sbio, mbuf, BUFSIZZ); -+ mbuf[seen] = 0; -+ while (!strstr -+ (mbuf, ""); -+ seen = BIO_read(sbio, sbuf, BUFSIZZ); -+ sbuf[seen] = 0; -+ if (!strstr(sbuf, " 2); -+ } -+ (void)BIO_flush(fbio); -+ BIO_pop(fbio); -+ BIO_free(fbio); -+ if (foundit != success) { -+ goto shut; -+ } -+ } -+ break; -+ case PROTO_IRC: -+ { -+ int numeric; -+ BIO *fbio = BIO_new(BIO_f_buffer()); -+ -+ BIO_push(fbio, sbio); -+ BIO_printf(fbio, "STARTTLS\r\n"); -+ (void)BIO_flush(fbio); -+ width = SSL_get_fd(con) + 1; -+ -+ do { -+ numeric = 0; -+ -+ FD_ZERO(&readfds); -+ openssl_fdset(SSL_get_fd(con), &readfds); -+ timeout.tv_sec = S_CLIENT_IRC_READ_TIMEOUT; -+ timeout.tv_usec = 0; -+ /* -+ * If the IRCd doesn't respond within -+ * S_CLIENT_IRC_READ_TIMEOUT seconds, assume -+ * it doesn't support STARTTLS. Many IRCds -+ * will not give _any_ sort of response to a -+ * STARTTLS command when it's not supported. -+ */ -+ if (!BIO_get_buffer_num_lines(fbio) -+ && !BIO_pending(fbio) -+ && !BIO_pending(sbio) -+ && select(width, (void *)&readfds, NULL, NULL, -+ &timeout) < 1) { -+ BIO_printf(bio_err, -+ "Timeout waiting for response (%d seconds).\n", -+ S_CLIENT_IRC_READ_TIMEOUT); -+ break; -+ } -+ -+ mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); -+ if (mbuf_len < 1 || sscanf(mbuf, "%*s %d", &numeric) != 1) -+ break; -+ /* :example.net 451 STARTTLS :You have not registered */ -+ /* :example.net 421 STARTTLS :Unknown command */ -+ if ((numeric == 451 || numeric == 421) -+ && strstr(mbuf, "STARTTLS") != NULL) { -+ BIO_printf(bio_err, "STARTTLS not supported: %s", mbuf); -+ break; -+ } -+ if (numeric == 691) { -+ BIO_printf(bio_err, "STARTTLS negotiation failed: "); -+ ERR_print_errors(bio_err); -+ break; -+ } -+ } while (numeric != 670); -+ -+ (void)BIO_flush(fbio); -+ BIO_pop(fbio); -+ BIO_free(fbio); -+ if (numeric != 670) { -+ BIO_printf(bio_err, "Server does not support STARTTLS.\n"); -+ ret = 1; -+ goto shut; -+ } -+ } -+ } -+ -+ for (;;) { -+ FD_ZERO(&readfds); -+ FD_ZERO(&writefds); -+ -+ if ((SSL_version(con) == DTLS1_VERSION) && -+ DTLSv1_get_timeout(con, &timeout)) -+ timeoutp = &timeout; -+ else -+ timeoutp = NULL; -+ -+ if (SSL_in_init(con) && !SSL_total_renegotiations(con)) { -+ in_init = 1; -+ tty_on = 0; -+ } else { -+ tty_on = 1; -+ if (in_init) { -+ in_init = 0; -+ -+ if (servername != NULL && !SSL_session_reused(con)) { -+ BIO_printf(bio_c_out, -+ "Server did %sacknowledge servername extension.\n", -+ tlsextcbp.ack ? "" : "not "); -+ } -+ -+ if (sess_out) { -+ BIO *stmp = BIO_new_file(sess_out, "w"); -+ if (stmp) { -+ PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con)); -+ BIO_free(stmp); -+ } else -+ BIO_printf(bio_err, "Error writing session file %s\n", -+ sess_out); -+ } -+ if (c_brief) { -+ BIO_puts(bio_err, "CONNECTION ESTABLISHED\n"); -+ print_ssl_summary(con); -+ } -+ -+ print_stuff(bio_c_out, con, full_log); -+ if (full_log > 0) -+ full_log--; -+ -+ if (starttls_proto) { -+ BIO_write(bio_err, mbuf, mbuf_len); -+ /* We don't need to know any more */ -+ if (!reconnect) -+ starttls_proto = PROTO_OFF; -+ } -+ -+ if (reconnect) { -+ reconnect--; -+ BIO_printf(bio_c_out, -+ "drop connection and then reconnect\n"); -+ do_ssl_shutdown(con); -+ SSL_set_connect_state(con); -+ BIO_closesocket(SSL_get_fd(con)); -+ goto re_start; -+ } -+ } -+ } -+ -+ ssl_pending = read_ssl && SSL_has_pending(con); -+ -+ if (!ssl_pending) { -+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) -+ if (tty_on) { -+ /* -+ * Note that select() returns when read _would not block_, -+ * and EOF satisfies that. To avoid a CPU-hogging loop, -+ * set the flag so we exit. -+ */ -+ if (read_tty && !at_eof) -+ openssl_fdset(fileno_stdin(), &readfds); -+#if !defined(OPENSSL_SYS_VMS) -+ if (write_tty) -+ openssl_fdset(fileno_stdout(), &writefds); -+#endif -+ } -+ if (read_ssl) -+ openssl_fdset(SSL_get_fd(con), &readfds); -+ if (write_ssl) -+ openssl_fdset(SSL_get_fd(con), &writefds); -+#else -+ if (!tty_on || !write_tty) { -+ if (read_ssl) -+ openssl_fdset(SSL_get_fd(con), &readfds); -+ if (write_ssl) -+ openssl_fdset(SSL_get_fd(con), &writefds); -+ } -+#endif -+ -+ /* -+ * Note: under VMS with SOCKETSHR the second parameter is -+ * currently of type (int *) whereas under other systems it is -+ * (void *) if you don't have a cast it will choke the compiler: -+ * if you do have a cast then you can either go for (int *) or -+ * (void *). -+ */ -+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) -+ /* -+ * Under Windows/DOS we make the assumption that we can always -+ * write to the tty: therefore if we need to write to the tty we -+ * just fall through. Otherwise we timeout the select every -+ * second and see if there are any keypresses. Note: this is a -+ * hack, in a proper Windows application we wouldn't do this. -+ */ -+ i = 0; -+ if (!write_tty) { -+ if (read_tty) { -+ tv.tv_sec = 1; -+ tv.tv_usec = 0; -+ i = select(width, (void *)&readfds, (void *)&writefds, -+ NULL, &tv); -+ if (!i && (!has_stdin_waiting() || !read_tty)) -+ continue; -+ } else -+ i = select(width, (void *)&readfds, (void *)&writefds, -+ NULL, timeoutp); -+ } -+#else -+ i = select(width, (void *)&readfds, (void *)&writefds, -+ NULL, timeoutp); -+#endif -+ if (i < 0) { -+ BIO_printf(bio_err, "bad select %d\n", -+ get_last_socket_error()); -+ goto shut; -+ /* goto end; */ -+ } -+ } -+ -+ if ((SSL_version(con) == DTLS1_VERSION) -+ && DTLSv1_handle_timeout(con) > 0) { -+ BIO_printf(bio_err, "TIMEOUT occurred\n"); -+ } -+ -+ if (!ssl_pending && FD_ISSET(SSL_get_fd(con), &writefds)) { -+ k = SSL_write(con, &(cbuf[cbuf_off]), (unsigned int)cbuf_len); -+ switch (SSL_get_error(con, k)) { -+ case SSL_ERROR_NONE: -+ cbuf_off += k; -+ cbuf_len -= k; -+ if (k <= 0) -+ goto end; -+ /* we have done a write(con,NULL,0); */ -+ if (cbuf_len <= 0) { -+ read_tty = 1; -+ write_ssl = 0; -+ } else { /* if (cbuf_len > 0) */ -+ -+ read_tty = 0; -+ write_ssl = 1; -+ } -+ break; -+ case SSL_ERROR_WANT_WRITE: -+ BIO_printf(bio_c_out, "write W BLOCK\n"); -+ write_ssl = 1; -+ read_tty = 0; -+ break; -+ case SSL_ERROR_WANT_ASYNC: -+ BIO_printf(bio_c_out, "write A BLOCK\n"); -+ wait_for_async(con); -+ write_ssl = 1; -+ read_tty = 0; -+ break; -+ case SSL_ERROR_WANT_READ: -+ BIO_printf(bio_c_out, "write R BLOCK\n"); -+ write_tty = 0; -+ read_ssl = 1; -+ write_ssl = 0; -+ break; -+ case SSL_ERROR_WANT_X509_LOOKUP: -+ BIO_printf(bio_c_out, "write X BLOCK\n"); -+ break; -+ case SSL_ERROR_ZERO_RETURN: -+ if (cbuf_len != 0) { -+ BIO_printf(bio_c_out, "shutdown\n"); -+ ret = 0; -+ goto shut; -+ } else { -+ read_tty = 1; -+ write_ssl = 0; -+ break; -+ } -+ -+ case SSL_ERROR_SYSCALL: -+ if ((k != 0) || (cbuf_len != 0)) { -+ BIO_printf(bio_err, "write:errno=%d\n", -+ get_last_socket_error()); -+ goto shut; -+ } else { -+ read_tty = 1; -+ write_ssl = 0; -+ } -+ break; -+ case SSL_ERROR_WANT_ASYNC_JOB: -+ /* This shouldn't ever happen in s_client - treat as an error */ -+ case SSL_ERROR_SSL: -+ ERR_print_errors(bio_err); -+ goto shut; -+ } -+ } -+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VMS) -+ /* Assume Windows/DOS/BeOS can always write */ -+ else if (!ssl_pending && write_tty) -+#else -+ else if (!ssl_pending && FD_ISSET(fileno_stdout(), &writefds)) -+#endif -+ { -+#ifdef CHARSET_EBCDIC -+ ascii2ebcdic(&(sbuf[sbuf_off]), &(sbuf[sbuf_off]), sbuf_len); -+#endif -+ i = raw_write_stdout(&(sbuf[sbuf_off]), sbuf_len); -+ -+ if (i <= 0) { -+ BIO_printf(bio_c_out, "DONE\n"); -+ ret = 0; -+ goto shut; -+ /* goto end; */ -+ } -+ -+ sbuf_len -= i;; -+ sbuf_off += i; -+ if (sbuf_len <= 0) { -+ read_ssl = 1; -+ write_tty = 0; -+ } -+ } else if (ssl_pending || FD_ISSET(SSL_get_fd(con), &readfds)) { -+#ifdef RENEG -+ { -+ static int iiii; -+ if (++iiii == 52) { -+ SSL_renegotiate(con); -+ iiii = 0; -+ } -+ } -+#endif -+ k = SSL_read(con, sbuf, 1024 /* BUFSIZZ */ ); -+ -+ switch (SSL_get_error(con, k)) { -+ case SSL_ERROR_NONE: -+ if (k <= 0) -+ goto end; -+ sbuf_off = 0; -+ sbuf_len = k; -+ -+ read_ssl = 0; -+ write_tty = 1; -+ break; -+ case SSL_ERROR_WANT_ASYNC: -+ BIO_printf(bio_c_out, "read A BLOCK\n"); -+ wait_for_async(con); -+ write_tty = 0; -+ read_ssl = 1; -+ if ((read_tty == 0) && (write_ssl == 0)) -+ write_ssl = 1; -+ break; -+ case SSL_ERROR_WANT_WRITE: -+ BIO_printf(bio_c_out, "read W BLOCK\n"); -+ write_ssl = 1; -+ read_tty = 0; -+ break; -+ case SSL_ERROR_WANT_READ: -+ BIO_printf(bio_c_out, "read R BLOCK\n"); -+ write_tty = 0; -+ read_ssl = 1; -+ if ((read_tty == 0) && (write_ssl == 0)) -+ write_ssl = 1; -+ break; -+ case SSL_ERROR_WANT_X509_LOOKUP: -+ BIO_printf(bio_c_out, "read X BLOCK\n"); -+ break; -+ case SSL_ERROR_SYSCALL: -+ ret = get_last_socket_error(); -+ if (c_brief) -+ BIO_puts(bio_err, "CONNECTION CLOSED BY SERVER\n"); -+ else -+ BIO_printf(bio_err, "read:errno=%d\n", ret); -+ goto shut; -+ case SSL_ERROR_ZERO_RETURN: -+ BIO_printf(bio_c_out, "closed\n"); -+ ret = 0; -+ goto shut; -+ case SSL_ERROR_WANT_ASYNC_JOB: -+ /* This shouldn't ever happen in s_client. Treat as an error */ -+ case SSL_ERROR_SSL: -+ ERR_print_errors(bio_err); -+ goto shut; -+ /* break; */ -+ } -+ } -+/* OPENSSL_SYS_MSDOS includes OPENSSL_SYS_WINDOWS */ -+#if defined(OPENSSL_SYS_MSDOS) -+ else if (has_stdin_waiting()) -+#else -+ else if (FD_ISSET(fileno_stdin(), &readfds)) -+#endif -+ { -+ if (crlf) { -+ int j, lf_num; -+ -+ i = raw_read_stdin(cbuf, BUFSIZZ / 2); -+ lf_num = 0; -+ /* both loops are skipped when i <= 0 */ -+ for (j = 0; j < i; j++) -+ if (cbuf[j] == '\n') -+ lf_num++; -+ for (j = i - 1; j >= 0; j--) { -+ cbuf[j + lf_num] = cbuf[j]; -+ if (cbuf[j] == '\n') { -+ lf_num--; -+ i++; -+ cbuf[j + lf_num] = '\r'; -+ } -+ } -+ assert(lf_num == 0); -+ } else -+ i = raw_read_stdin(cbuf, BUFSIZZ); -+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) -+ if (i == 0) -+ at_eof = 1; -+#endif -+ -+ if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q' && cmdletters))) { -+ BIO_printf(bio_err, "DONE\n"); -+ ret = 0; -+ goto shut; -+ } -+ -+ if ((!c_ign_eof) && (cbuf[0] == 'R' && cmdletters)) { -+ BIO_printf(bio_err, "RENEGOTIATING\n"); -+ SSL_renegotiate(con); -+ cbuf_len = 0; -+ } -+#ifndef OPENSSL_NO_HEARTBEATS -+ else if ((!c_ign_eof) && (cbuf[0] == 'B' && cmdletters)) { -+ BIO_printf(bio_err, "HEARTBEATING\n"); -+ SSL_heartbeat(con); -+ cbuf_len = 0; -+ } -+#endif -+ else { -+ cbuf_len = i; -+ cbuf_off = 0; -+#ifdef CHARSET_EBCDIC -+ ebcdic2ascii(cbuf, cbuf, i); -+#endif -+ } -+ -+ write_ssl = 1; -+ read_tty = 0; -+ } -+ } -+ -+ ret = 0; -+ shut: -+ if (in_init) -+ print_stuff(bio_c_out, con, full_log); -+ do_ssl_shutdown(con); -+#if defined(OPENSSL_SYS_WINDOWS) -+ /* -+ * Give the socket time to send its last data before we close it. -+ * No amount of setting SO_LINGER etc on the socket seems to persuade -+ * Windows to send the data before closing the socket...but sleeping -+ * for a short time seems to do it (units in ms) -+ * TODO: Find a better way to do this -+ */ -+ Sleep(50); -+#endif -+ BIO_closesocket(SSL_get_fd(con)); -+ end: -+ if (con != NULL) { -+ if (prexit != 0) -+ print_stuff(bio_c_out, con, 1); -+ SSL_free(con); -+ } -+#if !defined(OPENSSL_NO_NEXTPROTONEG) -+ OPENSSL_free(next_proto.data); -+#endif -+ SSL_CTX_free(ctx); -+ X509_free(cert); -+ sk_X509_CRL_pop_free(crls, X509_CRL_free); -+ EVP_PKEY_free(key); -+ sk_X509_pop_free(chain, X509_free); -+ OPENSSL_free(pass); -+#ifndef OPENSSL_NO_SRP -+ OPENSSL_free(srp_arg.srppassin); -+#endif -+ OPENSSL_free(connectstr); -+ OPENSSL_free(host); -+ OPENSSL_free(port); -+ X509_VERIFY_PARAM_free(vpm); -+ ssl_excert_free(exc); -+ sk_OPENSSL_STRING_free(ssl_args); -+ sk_OPENSSL_STRING_free(dane_tlsa_rrset); -+ SSL_CONF_CTX_free(cctx); -+ OPENSSL_clear_free(cbuf, BUFSIZZ); -+ OPENSSL_clear_free(sbuf, BUFSIZZ); -+ OPENSSL_clear_free(mbuf, BUFSIZZ); -+ release_engine(e); -+ BIO_free(bio_c_out); -+ bio_c_out = NULL; -+ BIO_free(bio_c_msg); -+ bio_c_msg = NULL; -+ return (ret); -+} -+ -+static void print_stuff(BIO *bio, SSL *s, int full) -+{ -+ X509 *peer = NULL; -+ char buf[BUFSIZ]; -+ STACK_OF(X509) *sk; -+ STACK_OF(X509_NAME) *sk2; -+ const SSL_CIPHER *c; -+ X509_NAME *xn; -+ int i; -+#ifndef OPENSSL_NO_COMP -+ const COMP_METHOD *comp, *expansion; -+#endif -+ unsigned char *exportedkeymat; -+#ifndef OPENSSL_NO_CT -+ const SSL_CTX *ctx = SSL_get_SSL_CTX(s); -+#endif -+ -+ if (full) { -+ int got_a_chain = 0; -+ -+ sk = SSL_get_peer_cert_chain(s); -+ if (sk != NULL) { -+ got_a_chain = 1; -+ -+ BIO_printf(bio, "---\nCertificate chain\n"); -+ for (i = 0; i < sk_X509_num(sk); i++) { -+ X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, i)), -+ buf, sizeof buf); -+ BIO_printf(bio, "%2d s:%s\n", i, buf); -+ X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, i)), -+ buf, sizeof buf); -+ BIO_printf(bio, " i:%s\n", buf); -+ if (c_showcerts) -+ PEM_write_bio_X509(bio, sk_X509_value(sk, i)); -+ } -+ } -+ -+ BIO_printf(bio, "---\n"); -+ peer = SSL_get_peer_certificate(s); -+ if (peer != NULL) { -+ BIO_printf(bio, "Server certificate\n"); -+ -+ /* Redundant if we showed the whole chain */ -+ if (!(c_showcerts && got_a_chain)) -+ PEM_write_bio_X509(bio, peer); -+ X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf); -+ BIO_printf(bio, "subject=%s\n", buf); -+ X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf); -+ BIO_printf(bio, "issuer=%s\n", buf); -+ } else -+ BIO_printf(bio, "no peer certificate available\n"); -+ -+ sk2 = SSL_get_client_CA_list(s); -+ if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) { -+ BIO_printf(bio, "---\nAcceptable client certificate CA names\n"); -+ for (i = 0; i < sk_X509_NAME_num(sk2); i++) { -+ xn = sk_X509_NAME_value(sk2, i); -+ X509_NAME_oneline(xn, buf, sizeof(buf)); -+ BIO_write(bio, buf, strlen(buf)); -+ BIO_write(bio, "\n", 1); -+ } -+ } else { -+ BIO_printf(bio, "---\nNo client certificate CA names sent\n"); -+ } -+ -+ ssl_print_sigalgs(bio, s); -+ ssl_print_tmp_key(bio, s); -+ -+#ifndef OPENSSL_NO_CT -+ /* -+ * When the SSL session is anonymous, or resumed via an abbreviated -+ * handshake, no SCTs are provided as part of the handshake. While in -+ * a resumed session SCTs may be present in the session's certificate, -+ * no callbacks are invoked to revalidate these, and in any case that -+ * set of SCTs may be incomplete. Thus it makes little sense to -+ * attempt to display SCTs from a resumed session's certificate, and of -+ * course none are associated with an anonymous peer. -+ */ -+ if (peer != NULL && !SSL_session_reused(s) && SSL_ct_is_enabled(s)) { -+ const STACK_OF(SCT) *scts = SSL_get0_peer_scts(s); -+ int sct_count = scts != NULL ? sk_SCT_num(scts) : 0; -+ -+ BIO_printf(bio, "---\nSCTs present (%i)\n", sct_count); -+ if (sct_count > 0) { -+ const CTLOG_STORE *log_store = SSL_CTX_get0_ctlog_store(ctx); -+ -+ BIO_printf(bio, "---\n"); -+ for (i = 0; i < sct_count; ++i) { -+ SCT *sct = sk_SCT_value(scts, i); -+ -+ BIO_printf(bio, "SCT validation status: %s\n", -+ SCT_validation_status_string(sct)); -+ SCT_print(sct, bio, 0, log_store); -+ if (i < sct_count - 1) -+ BIO_printf(bio, "\n---\n"); -+ } -+ BIO_printf(bio, "\n"); -+ } -+ } -+#endif -+ -+ BIO_printf(bio, -+ "---\nSSL handshake has read %" PRIu64 -+ " bytes and written %" PRIu64 " bytes\n", -+ BIO_number_read(SSL_get_rbio(s)), -+ BIO_number_written(SSL_get_wbio(s))); -+ } -+ print_verify_detail(s, bio); -+ BIO_printf(bio, (SSL_session_reused(s) ? "---\nReused, " : "---\nNew, ")); -+ c = SSL_get_current_cipher(s); -+ BIO_printf(bio, "%s, Cipher is %s\n", -+ SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); -+ if (peer != NULL) { -+ EVP_PKEY *pktmp; -+ -+ pktmp = X509_get0_pubkey(peer); -+ BIO_printf(bio, "Server public key is %d bit\n", -+ EVP_PKEY_bits(pktmp)); -+ } -+ BIO_printf(bio, "Secure Renegotiation IS%s supported\n", -+ SSL_get_secure_renegotiation_support(s) ? "" : " NOT"); -+#ifndef OPENSSL_NO_COMP -+ comp = SSL_get_current_compression(s); -+ expansion = SSL_get_current_expansion(s); -+ BIO_printf(bio, "Compression: %s\n", -+ comp ? SSL_COMP_get_name(comp) : "NONE"); -+ BIO_printf(bio, "Expansion: %s\n", -+ expansion ? SSL_COMP_get_name(expansion) : "NONE"); -+#endif -+ -+#ifdef SSL_DEBUG -+ { -+ /* Print out local port of connection: useful for debugging */ -+ int sock; -+ union BIO_sock_info_u info; -+ -+ sock = SSL_get_fd(s); -+ if ((info.addr = BIO_ADDR_new()) != NULL -+ && BIO_sock_info(sock, BIO_SOCK_INFO_ADDRESS, &info)) { -+ BIO_printf(bio_c_out, "LOCAL PORT is %u\n", -+ ntohs(BIO_ADDR_rawport(info.addr))); -+ } -+ BIO_ADDR_free(info.addr); -+ } -+#endif -+ -+#if !defined(OPENSSL_NO_NEXTPROTONEG) -+ if (next_proto.status != -1) { -+ const unsigned char *proto; -+ unsigned int proto_len; -+ SSL_get0_next_proto_negotiated(s, &proto, &proto_len); -+ BIO_printf(bio, "Next protocol: (%d) ", next_proto.status); -+ BIO_write(bio, proto, proto_len); -+ BIO_write(bio, "\n", 1); -+ } -+#endif -+ { -+ const unsigned char *proto; -+ unsigned int proto_len; -+ SSL_get0_alpn_selected(s, &proto, &proto_len); -+ if (proto_len > 0) { -+ BIO_printf(bio, "ALPN protocol: "); -+ BIO_write(bio, proto, proto_len); -+ BIO_write(bio, "\n", 1); -+ } else -+ BIO_printf(bio, "No ALPN negotiated\n"); -+ } -+ -+#ifndef OPENSSL_NO_SRTP -+ { -+ SRTP_PROTECTION_PROFILE *srtp_profile = -+ SSL_get_selected_srtp_profile(s); -+ -+ if (srtp_profile) -+ BIO_printf(bio, "SRTP Extension negotiated, profile=%s\n", -+ srtp_profile->name); -+ } -+#endif -+ -+ SSL_SESSION_print(bio, SSL_get_session(s)); -+ if (SSL_get_session(s) != NULL && keymatexportlabel != NULL) { -+ BIO_printf(bio, "Keying material exporter:\n"); -+ BIO_printf(bio, " Label: '%s'\n", keymatexportlabel); -+ BIO_printf(bio, " Length: %i bytes\n", keymatexportlen); -+ exportedkeymat = app_malloc(keymatexportlen, "export key"); -+ if (!SSL_export_keying_material(s, exportedkeymat, -+ keymatexportlen, -+ keymatexportlabel, -+ strlen(keymatexportlabel), -+ NULL, 0, 0)) { -+ BIO_printf(bio, " Error\n"); -+ } else { -+ BIO_printf(bio, " Keying material: "); -+ for (i = 0; i < keymatexportlen; i++) -+ BIO_printf(bio, "%02X", exportedkeymat[i]); -+ BIO_printf(bio, "\n"); -+ } -+ OPENSSL_free(exportedkeymat); -+ } -+ BIO_printf(bio, "---\n"); -+ X509_free(peer); -+ /* flush, or debugging output gets mixed with http response */ -+ (void)BIO_flush(bio); -+} -+ -+# ifndef OPENSSL_NO_OCSP -+static int ocsp_resp_cb(SSL *s, void *arg) -+{ -+ const unsigned char *p; -+ int len; -+ OCSP_RESPONSE *rsp; -+ len = SSL_get_tlsext_status_ocsp_resp(s, &p); -+ BIO_puts(arg, "OCSP response: "); -+ if (!p) { -+ BIO_puts(arg, "no response sent\n"); -+ return 1; -+ } -+ rsp = d2i_OCSP_RESPONSE(NULL, &p, len); -+ if (!rsp) { -+ BIO_puts(arg, "response parse error\n"); -+ BIO_dump_indent(arg, (char *)p, len, 4); -+ return 0; -+ } -+ BIO_puts(arg, "\n======================================\n"); -+ OCSP_RESPONSE_print(arg, rsp, 0); -+ BIO_puts(arg, "======================================\n"); -+ OCSP_RESPONSE_free(rsp); -+ return 1; -+} -+# endif -+ -+#endif /* OPENSSL_NO_SOCK */ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/s_server.c b/CryptoPkg/Library/OpensslLib/openssl/apps/s_server.c -new file mode 100644 -index 0000000..66405e6 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/s_server.c -@@ -0,0 +1,3301 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* ==================================================================== -+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. -+ * ECC cipher suite support in OpenSSL originally developed by -+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. -+ */ -+/* ==================================================================== -+ * Copyright 2005 Nokia. All rights reserved. -+ * -+ * The portions of the attached software ("Contribution") is developed by -+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source -+ * license. -+ * -+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of -+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites -+ * support (see RFC 4279) to OpenSSL. -+ * -+ * No patent licenses or other rights except those expressly stated in -+ * the OpenSSL open source license shall be deemed granted or received -+ * expressly, by implication, estoppel, or otherwise. -+ * -+ * No assurances are provided by Nokia that the Contribution does not -+ * infringe the patent or other intellectual property rights of any third -+ * party or that the license provides you with all the necessary rights -+ * to make use of the Contribution. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN -+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA -+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY -+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR -+ * OTHERWISE. -+ */ -+ -+#include -+#include -+#include -+#include -+#if defined(_WIN32) -+/* Included before async.h to avoid some warnings */ -+# include -+#endif -+ -+#include -+#include -+#include -+ -+#ifndef OPENSSL_NO_SOCK -+ -+/* -+ * With IPv6, it looks like Digital has mixed up the proper order of -+ * recursive header file inclusion, resulting in the compiler complaining -+ * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is -+ * needed to have fileno() declared correctly... So let's define u_int -+ */ -+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT) -+# define __U_INT -+typedef unsigned int u_int; -+#endif -+ -+#include -+#include -+#define USE_SOCKETS -+#include "apps.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef OPENSSL_NO_DH -+# include -+#endif -+#ifndef OPENSSL_NO_RSA -+# include -+#endif -+#ifndef OPENSSL_NO_SRP -+# include -+#endif -+#include "s_apps.h" -+#include "timeouts.h" -+#ifdef CHARSET_EBCDIC -+#include -+#endif -+ -+static int not_resumable_sess_cb(SSL *s, int is_forward_secure); -+static int sv_body(int s, int stype, unsigned char *context); -+static int www_body(int s, int stype, unsigned char *context); -+static int rev_body(int s, int stype, unsigned char *context); -+static void close_accept_socket(void); -+static int init_ssl_connection(SSL *s); -+static void print_stats(BIO *bp, SSL_CTX *ctx); -+static int generate_session_id(const SSL *ssl, unsigned char *id, -+ unsigned int *id_len); -+static void init_session_cache_ctx(SSL_CTX *sctx); -+static void free_sessions(void); -+#ifndef OPENSSL_NO_DH -+static DH *load_dh_param(const char *dhfile); -+#endif -+ -+/* static int load_CA(SSL_CTX *ctx, char *file);*/ -+ -+static const int bufsize = 16 * 1024; -+static int accept_socket = -1; -+ -+#define TEST_CERT "server.pem" -+#define TEST_CERT2 "server2.pem" -+ -+static int s_nbio = 0; -+static int s_nbio_test = 0; -+static int s_crlf = 0; -+static SSL_CTX *ctx = NULL; -+static SSL_CTX *ctx2 = NULL; -+static int www = 0; -+ -+static BIO *bio_s_out = NULL; -+static BIO *bio_s_msg = NULL; -+static int s_debug = 0; -+static int s_tlsextdebug = 0; -+static int s_msg = 0; -+static int s_quiet = 0; -+static int s_ign_eof = 0; -+static int s_brief = 0; -+ -+static char *keymatexportlabel = NULL; -+static int keymatexportlen = 20; -+ -+static int async = 0; -+ -+static const char *session_id_prefix = NULL; -+ -+#ifndef OPENSSL_NO_DTLS -+static int enable_timeouts = 0; -+static long socket_mtu; -+ -+#endif -+static int dtlslisten = 0; -+ -+#ifndef OPENSSL_NO_PSK -+static char *psk_identity = "Client_identity"; -+char *psk_key = NULL; /* by default PSK is not used */ -+ -+static unsigned int psk_server_cb(SSL *ssl, const char *identity, -+ unsigned char *psk, -+ unsigned int max_psk_len) -+{ -+ long key_len = 0; -+ unsigned char *key; -+ -+ if (s_debug) -+ BIO_printf(bio_s_out, "psk_server_cb\n"); -+ if (!identity) { -+ BIO_printf(bio_err, "Error: client did not send PSK identity\n"); -+ goto out_err; -+ } -+ if (s_debug) -+ BIO_printf(bio_s_out, "identity_len=%d identity=%s\n", -+ (int)strlen(identity), identity); -+ -+ /* here we could lookup the given identity e.g. from a database */ -+ if (strcmp(identity, psk_identity) != 0) { -+ BIO_printf(bio_s_out, "PSK error: client identity not found" -+ " (got '%s' expected '%s')\n", identity, psk_identity); -+ goto out_err; -+ } -+ if (s_debug) -+ BIO_printf(bio_s_out, "PSK client identity found\n"); -+ -+ /* convert the PSK key to binary */ -+ key = OPENSSL_hexstr2buf(psk_key, &key_len); -+ if (key == NULL) { -+ BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n", -+ psk_key); -+ return 0; -+ } -+ if (key_len > (int)max_psk_len) { -+ BIO_printf(bio_err, -+ "psk buffer of callback is too small (%d) for key (%ld)\n", -+ max_psk_len, key_len); -+ OPENSSL_free(key); -+ return 0; -+ } -+ -+ memcpy(psk, key, key_len); -+ OPENSSL_free(key); -+ -+ if (s_debug) -+ BIO_printf(bio_s_out, "fetched PSK len=%ld\n", key_len); -+ return key_len; -+ out_err: -+ if (s_debug) -+ BIO_printf(bio_err, "Error in PSK server callback\n"); -+ (void)BIO_flush(bio_err); -+ (void)BIO_flush(bio_s_out); -+ return 0; -+} -+#endif -+ -+#ifndef OPENSSL_NO_SRP -+/* This is a context that we pass to callbacks */ -+typedef struct srpsrvparm_st { -+ char *login; -+ SRP_VBASE *vb; -+ SRP_user_pwd *user; -+} srpsrvparm; -+ -+/* -+ * This callback pretends to require some asynchronous logic in order to -+ * obtain a verifier. When the callback is called for a new connection we -+ * return with a negative value. This will provoke the accept etc to return -+ * with an LOOKUP_X509. The main logic of the reinvokes the suspended call -+ * (which would normally occur after a worker has finished) and we set the -+ * user parameters. -+ */ -+static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) -+{ -+ srpsrvparm *p = (srpsrvparm *) arg; -+ int ret = SSL3_AL_FATAL; -+ -+ if (p->login == NULL && p->user == NULL) { -+ p->login = SSL_get_srp_username(s); -+ BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login); -+ return (-1); -+ } -+ -+ if (p->user == NULL) { -+ BIO_printf(bio_err, "User %s doesn't exist\n", p->login); -+ goto err; -+ } -+ -+ if (SSL_set_srp_server_param -+ (s, p->user->N, p->user->g, p->user->s, p->user->v, -+ p->user->info) < 0) { -+ *ad = SSL_AD_INTERNAL_ERROR; -+ goto err; -+ } -+ BIO_printf(bio_err, -+ "SRP parameters set: username = \"%s\" info=\"%s\" \n", -+ p->login, p->user->info); -+ ret = SSL_ERROR_NONE; -+ -+ err: -+ SRP_user_pwd_free(p->user); -+ p->user = NULL; -+ p->login = NULL; -+ return ret; -+} -+ -+#endif -+ -+static int local_argc = 0; -+static char **local_argv; -+ -+#ifdef CHARSET_EBCDIC -+static int ebcdic_new(BIO *bi); -+static int ebcdic_free(BIO *a); -+static int ebcdic_read(BIO *b, char *out, int outl); -+static int ebcdic_write(BIO *b, const char *in, int inl); -+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr); -+static int ebcdic_gets(BIO *bp, char *buf, int size); -+static int ebcdic_puts(BIO *bp, const char *str); -+ -+# define BIO_TYPE_EBCDIC_FILTER (18|0x0200) -+static BIO_METHOD *methods_ebcdic = NULL; -+ -+/* This struct is "unwarranted chumminess with the compiler." */ -+typedef struct { -+ size_t alloced; -+ char buff[1]; -+} EBCDIC_OUTBUFF; -+ -+static const BIO_METHOD *BIO_f_ebcdic_filter() -+{ -+ if (methods_ebcdic == NULL) { -+ methods_ebcdic = BIO_meth_new(BIO_TYPE_EBCDIC_FILTER, -+ "EBCDIC/ASCII filter"); -+ if (methods_ebcdic == NULL -+ || !BIO_meth_set_write(methods_ebcdic, ebcdic_write) -+ || !BIO_meth_set_read(methods_ebcdic, ebcdic_read) -+ || !BIO_meth_set_puts(methods_ebcdic, ebcdic_puts) -+ || !BIO_meth_set_gets(methods_ebcdic, ebcdic_gets) -+ || !BIO_meth_set_ctrl(methods_ebcdic, ebcdic_ctrl) -+ || !BIO_meth_set_create(methods_ebcdic, ebcdic_new) -+ || !BIO_meth_set_destroy(methods_ebcdic, ebcdic_free)) -+ return NULL; -+ } -+ return methods_ebcdic; -+} -+ -+static int ebcdic_new(BIO *bi) -+{ -+ EBCDIC_OUTBUFF *wbuf; -+ -+ wbuf = app_malloc(sizeof(*wbuf) + 1024, "ebcdic wbuf"); -+ wbuf->alloced = 1024; -+ wbuf->buff[0] = '\0'; -+ -+ BIO_set_data(bi, wbuf); -+ BIO_set_init(bi, 1); -+ return 1; -+} -+ -+static int ebcdic_free(BIO *a) -+{ -+ EBCDIC_OUTBUFF *wbuf; -+ -+ if (a == NULL) -+ return 0; -+ wbuf = BIO_get_data(a); -+ OPENSSL_free(wbuf); -+ BIO_set_data(a, NULL); -+ BIO_set_init(a, 0); -+ -+ return 1; -+} -+ -+static int ebcdic_read(BIO *b, char *out, int outl) -+{ -+ int ret = 0; -+ BIO *next = BIO_next(b); -+ -+ if (out == NULL || outl == 0) -+ return (0); -+ if (next == NULL) -+ return (0); -+ -+ ret = BIO_read(next, out, outl); -+ if (ret > 0) -+ ascii2ebcdic(out, out, ret); -+ return ret; -+} -+ -+static int ebcdic_write(BIO *b, const char *in, int inl) -+{ -+ EBCDIC_OUTBUFF *wbuf; -+ BIO *next = BIO_next(b); -+ int ret = 0; -+ int num; -+ -+ if ((in == NULL) || (inl <= 0)) -+ return (0); -+ if (next == NULL) -+ return 0; -+ -+ wbuf = (EBCDIC_OUTBUFF *) BIO_get_data(b); -+ -+ if (inl > (num = wbuf->alloced)) { -+ num = num + num; /* double the size */ -+ if (num < inl) -+ num = inl; -+ OPENSSL_free(wbuf); -+ wbuf = app_malloc(sizeof(*wbuf) + num, "grow ebcdic wbuf"); -+ -+ wbuf->alloced = num; -+ wbuf->buff[0] = '\0'; -+ -+ BIO_set_data(b, wbuf); -+ } -+ -+ ebcdic2ascii(wbuf->buff, in, inl); -+ -+ ret = BIO_write(next, wbuf->buff, inl); -+ -+ return (ret); -+} -+ -+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr) -+{ -+ long ret; -+ BIO *next = BIO_next(b); -+ -+ if (next == NULL) -+ return (0); -+ switch (cmd) { -+ case BIO_CTRL_DUP: -+ ret = 0L; -+ break; -+ default: -+ ret = BIO_ctrl(next, cmd, num, ptr); -+ break; -+ } -+ return (ret); -+} -+ -+static int ebcdic_gets(BIO *bp, char *buf, int size) -+{ -+ int i, ret = 0; -+ BIO *next = BIO_next(bp); -+ -+ if (next == NULL) -+ return 0; -+/* return(BIO_gets(bp->next_bio,buf,size));*/ -+ for (i = 0; i < size - 1; ++i) { -+ ret = ebcdic_read(bp, &buf[i], 1); -+ if (ret <= 0) -+ break; -+ else if (buf[i] == '\n') { -+ ++i; -+ break; -+ } -+ } -+ if (i < size) -+ buf[i] = '\0'; -+ return (ret < 0 && i == 0) ? ret : i; -+} -+ -+static int ebcdic_puts(BIO *bp, const char *str) -+{ -+ if (BIO_next(bp) == NULL) -+ return 0; -+ return ebcdic_write(bp, str, strlen(str)); -+} -+#endif -+ -+/* This is a context that we pass to callbacks */ -+typedef struct tlsextctx_st { -+ char *servername; -+ BIO *biodebug; -+ int extension_error; -+} tlsextctx; -+ -+static int ssl_servername_cb(SSL *s, int *ad, void *arg) -+{ -+ tlsextctx *p = (tlsextctx *) arg; -+ const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); -+ if (servername && p->biodebug) -+ BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n", -+ servername); -+ -+ if (!p->servername) -+ return SSL_TLSEXT_ERR_NOACK; -+ -+ if (servername) { -+ if (strcasecmp(servername, p->servername)) -+ return p->extension_error; -+ if (ctx2) { -+ BIO_printf(p->biodebug, "Switching server context.\n"); -+ SSL_set_SSL_CTX(s, ctx2); -+ } -+ } -+ return SSL_TLSEXT_ERR_OK; -+} -+ -+/* Structure passed to cert status callback */ -+ -+typedef struct tlsextstatusctx_st { -+ /* Default responder to use */ -+ char *host, *path, *port; -+ int use_ssl; -+ int timeout; -+ int verbose; -+} tlsextstatusctx; -+ -+static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, 0 }; -+ -+#ifndef OPENSSL_NO_OCSP -+/* -+ * Certificate Status callback. This is called when a client includes a -+ * certificate status request extension. This is a simplified version. It -+ * examines certificates each time and makes one OCSP responder query for -+ * each request. A full version would store details such as the OCSP -+ * certificate IDs and minimise the number of OCSP responses by caching them -+ * until they were considered "expired". -+ */ -+ -+static int cert_status_cb(SSL *s, void *arg) -+{ -+ tlsextstatusctx *srctx = arg; -+ char *host = NULL, *port = NULL, *path = NULL; -+ int use_ssl; -+ unsigned char *rspder = NULL; -+ int rspderlen; -+ STACK_OF(OPENSSL_STRING) *aia = NULL; -+ X509 *x = NULL; -+ X509_STORE_CTX *inctx = NULL; -+ X509_OBJECT *obj; -+ OCSP_REQUEST *req = NULL; -+ OCSP_RESPONSE *resp = NULL; -+ OCSP_CERTID *id = NULL; -+ STACK_OF(X509_EXTENSION) *exts; -+ int ret = SSL_TLSEXT_ERR_NOACK; -+ int i; -+ -+ if (srctx->verbose) -+ BIO_puts(bio_err, "cert_status: callback called\n"); -+ /* Build up OCSP query from server certificate */ -+ x = SSL_get_certificate(s); -+ aia = X509_get1_ocsp(x); -+ if (aia) { -+ if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0), -+ &host, &port, &path, &use_ssl)) { -+ BIO_puts(bio_err, "cert_status: can't parse AIA URL\n"); -+ goto err; -+ } -+ if (srctx->verbose) -+ BIO_printf(bio_err, "cert_status: AIA URL: %s\n", -+ sk_OPENSSL_STRING_value(aia, 0)); -+ } else { -+ if (!srctx->host) { -+ BIO_puts(bio_err, -+ "cert_status: no AIA and no default responder URL\n"); -+ goto done; -+ } -+ host = srctx->host; -+ path = srctx->path; -+ port = srctx->port; -+ use_ssl = srctx->use_ssl; -+ } -+ -+ inctx = X509_STORE_CTX_new(); -+ if (inctx == NULL) -+ goto err; -+ if (!X509_STORE_CTX_init(inctx, -+ SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)), -+ NULL, NULL)) -+ goto err; -+ obj = X509_STORE_CTX_get_obj_by_subject(inctx, X509_LU_X509, -+ X509_get_issuer_name(x)); -+ if (obj == NULL) { -+ BIO_puts(bio_err, "cert_status: Can't retrieve issuer certificate.\n"); -+ goto done; -+ } -+ id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj)); -+ X509_OBJECT_free(obj); -+ if (!id) -+ goto err; -+ req = OCSP_REQUEST_new(); -+ if (req == NULL) -+ goto err; -+ if (!OCSP_request_add0_id(req, id)) -+ goto err; -+ id = NULL; -+ /* Add any extensions to the request */ -+ SSL_get_tlsext_status_exts(s, &exts); -+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { -+ X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); -+ if (!OCSP_REQUEST_add_ext(req, ext, -1)) -+ goto err; -+ } -+ resp = process_responder(req, host, path, port, use_ssl, NULL, -+ srctx->timeout); -+ if (!resp) { -+ BIO_puts(bio_err, "cert_status: error querying responder\n"); -+ goto done; -+ } -+ rspderlen = i2d_OCSP_RESPONSE(resp, &rspder); -+ if (rspderlen <= 0) -+ goto err; -+ SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen); -+ if (srctx->verbose) { -+ BIO_puts(bio_err, "cert_status: ocsp response sent:\n"); -+ OCSP_RESPONSE_print(bio_err, resp, 2); -+ } -+ ret = SSL_TLSEXT_ERR_OK; -+ goto done; -+ -+ err: -+ ret = SSL_TLSEXT_ERR_ALERT_FATAL; -+ done: -+ if (ret != SSL_TLSEXT_ERR_OK) -+ ERR_print_errors(bio_err); -+ if (aia) { -+ OPENSSL_free(host); -+ OPENSSL_free(path); -+ OPENSSL_free(port); -+ X509_email_free(aia); -+ } -+ OCSP_CERTID_free(id); -+ OCSP_REQUEST_free(req); -+ OCSP_RESPONSE_free(resp); -+ X509_STORE_CTX_free(inctx); -+ return ret; -+} -+#endif -+ -+#ifndef OPENSSL_NO_NEXTPROTONEG -+/* This is the context that we pass to next_proto_cb */ -+typedef struct tlsextnextprotoctx_st { -+ unsigned char *data; -+ unsigned int len; -+} tlsextnextprotoctx; -+ -+static int next_proto_cb(SSL *s, const unsigned char **data, -+ unsigned int *len, void *arg) -+{ -+ tlsextnextprotoctx *next_proto = arg; -+ -+ *data = next_proto->data; -+ *len = next_proto->len; -+ -+ return SSL_TLSEXT_ERR_OK; -+} -+#endif /* ndef OPENSSL_NO_NEXTPROTONEG */ -+ -+/* This the context that we pass to alpn_cb */ -+typedef struct tlsextalpnctx_st { -+ unsigned char *data; -+ size_t len; -+} tlsextalpnctx; -+ -+static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, -+ const unsigned char *in, unsigned int inlen, void *arg) -+{ -+ tlsextalpnctx *alpn_ctx = arg; -+ -+ if (!s_quiet) { -+ /* We can assume that |in| is syntactically valid. */ -+ unsigned int i; -+ BIO_printf(bio_s_out, "ALPN protocols advertised by the client: "); -+ for (i = 0; i < inlen;) { -+ if (i) -+ BIO_write(bio_s_out, ", ", 2); -+ BIO_write(bio_s_out, &in[i + 1], in[i]); -+ i += in[i] + 1; -+ } -+ BIO_write(bio_s_out, "\n", 1); -+ } -+ -+ if (SSL_select_next_proto -+ ((unsigned char **)out, outlen, alpn_ctx->data, alpn_ctx->len, in, -+ inlen) != OPENSSL_NPN_NEGOTIATED) { -+ return SSL_TLSEXT_ERR_NOACK; -+ } -+ -+ if (!s_quiet) { -+ BIO_printf(bio_s_out, "ALPN protocols selected: "); -+ BIO_write(bio_s_out, *out, *outlen); -+ BIO_write(bio_s_out, "\n", 1); -+ } -+ -+ return SSL_TLSEXT_ERR_OK; -+} -+ -+static int not_resumable_sess_cb(SSL *s, int is_forward_secure) -+{ -+ /* disable resumption for sessions with forward secure ciphers */ -+ return is_forward_secure; -+} -+ -+#ifndef OPENSSL_NO_SRP -+static srpsrvparm srp_callback_parm; -+#endif -+#ifndef OPENSSL_NO_SRTP -+static char *srtp_profiles = NULL; -+#endif -+ -+typedef enum OPTION_choice { -+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, -+ OPT_4, OPT_6, OPT_ACCEPT, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT, -+ OPT_VERIFY, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL, -+ OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM, -+ OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT, -+ OPT_DKEYFORM, OPT_DPASS, OPT_DKEY, OPT_DCERT_CHAIN, OPT_NOCERT, -+ OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE, -+ OPT_EXT_CACHE, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, -+ OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, -+ OPT_VERIFYCAFILE, OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF, -+ OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE, -+ OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_MSG, OPT_MSGFILE, OPT_TRACE, -+ OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, OPT_CRLF, -+ OPT_QUIET, OPT_BRIEF, OPT_NO_DHE, -+ OPT_NO_RESUME_EPHEMERAL, OPT_PSK_HINT, OPT_PSK, OPT_SRPVFILE, -+ OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC, -+ OPT_SSL_CONFIG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF, -+ OPT_SSL3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, -+ OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, -+ OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL, -+ OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, -+ OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, -+ OPT_S_ENUM, -+ OPT_V_ENUM, -+ OPT_X_ENUM -+} OPTION_CHOICE; -+ -+OPTIONS s_server_options[] = { -+ {"help", OPT_HELP, '-', "Display this summary"}, -+ {"port", OPT_PORT, 'p', -+ "TCP/IP port to listen on for connections (default is " PORT ")"}, -+ {"accept", OPT_ACCEPT, 's', -+ "TCP/IP optional host and port to listen on for connections (default is *:" PORT ")"}, -+#ifdef AF_UNIX -+ {"unix", OPT_UNIX, 's', "Unix domain socket to accept on"}, -+#endif -+ {"4", OPT_4, '-', "Use IPv4 only"}, -+ {"6", OPT_6, '-', "Use IPv6 only"}, -+#ifdef AF_UNIX -+ {"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"}, -+#endif -+ {"context", OPT_CONTEXT, 's', "Set session ID context"}, -+ {"verify", OPT_VERIFY, 'n', "Turn on peer certificate verification"}, -+ {"Verify", OPT_UPPER_V_VERIFY, 'n', -+ "Turn on peer certificate verification, must have a cert"}, -+ {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT}, -+ {"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"}, -+ {"serverinfo", OPT_SERVERINFO, 's', -+ "PEM serverinfo file for certificate"}, -+ {"certform", OPT_CERTFORM, 'F', -+ "Certificate format (PEM or DER) PEM default"}, -+ {"key", OPT_KEY, '<', -+ "Private Key if not in -cert; default is " TEST_CERT}, -+ {"keyform", OPT_KEYFORM, 'f', -+ "Key format (PEM, DER or ENGINE) PEM default"}, -+ {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, -+ {"dcert", OPT_DCERT, '<', -+ "Second certificate file to use (usually for DSA)"}, -+ {"dcertform", OPT_DCERTFORM, 'F', -+ "Second certificate format (PEM or DER) PEM default"}, -+ {"dkey", OPT_DKEY, '<', -+ "Second private key file to use (usually for DSA)"}, -+ {"dkeyform", OPT_DKEYFORM, 'F', -+ "Second key format (PEM, DER or ENGINE) PEM default"}, -+ {"dpass", OPT_DPASS, 's', "Second private key file pass phrase source"}, -+ {"nbio_test", OPT_NBIO_TEST, '-', "Test with the non-blocking test bio"}, -+ {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, -+ {"debug", OPT_DEBUG, '-', "Print more output"}, -+ {"msg", OPT_MSG, '-', "Show protocol messages"}, -+ {"msgfile", OPT_MSGFILE, '>', -+ "File to send output of -msg or -trace, instead of stdout"}, -+ {"state", OPT_STATE, '-', "Print the SSL states"}, -+ {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, -+ {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, -+ {"no-CAfile", OPT_NOCAFILE, '-', -+ "Do not load the default certificates file"}, -+ {"no-CApath", OPT_NOCAPATH, '-', -+ "Do not load certificates from the default certificates directory"}, -+ {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"}, -+ {"quiet", OPT_QUIET, '-', "No server output"}, -+ {"no_resume_ephemeral", OPT_NO_RESUME_EPHEMERAL, '-', -+ "Disable caching and tickets if ephemeral (EC)DH is used"}, -+ {"www", OPT_WWW, '-', "Respond to a 'GET /' with a status page"}, -+ {"WWW", OPT_UPPER_WWW, '-', "Respond to a 'GET with the file ./path"}, -+ {"servername", OPT_SERVERNAME, 's', -+ "Servername for HostName TLS extension"}, -+ {"servername_fatal", OPT_SERVERNAME_FATAL, '-', -+ "mismatch send fatal alert (default warning alert)"}, -+ {"cert2", OPT_CERT2, '<', -+ "Certificate file to use for servername; default is" TEST_CERT2}, -+ {"key2", OPT_KEY2, '<', -+ "-Private Key file to use for servername if not in -cert2"}, -+ {"tlsextdebug", OPT_TLSEXTDEBUG, '-', -+ "Hex dump of all TLS extensions received"}, -+ {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"}, -+ {"id_prefix", OPT_ID_PREFIX, 's', -+ "Generate SSL/TLS session IDs prefixed by arg"}, -+ {"rand", OPT_RAND, 's', -+ "Load the file(s) into the random number generator"}, -+ {"keymatexport", OPT_KEYMATEXPORT, 's', -+ "Export keying material using label"}, -+ {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', -+ "Export len bytes of keying material (default 20)"}, -+ {"CRL", OPT_CRL, '<', "CRL file to use"}, -+ {"crl_download", OPT_CRL_DOWNLOAD, '-', -+ "Download CRL from distribution points"}, -+ {"cert_chain", OPT_CERT_CHAIN, '<', -+ "certificate chain file in PEM format"}, -+ {"dcert_chain", OPT_DCERT_CHAIN, '<', -+ "second certificate chain file in PEM format"}, -+ {"chainCApath", OPT_CHAINCAPATH, '/', -+ "use dir as certificate store path to build CA certificate chain"}, -+ {"verifyCApath", OPT_VERIFYCAPATH, '/', -+ "use dir as certificate store path to verify CA certificate"}, -+ {"no_cache", OPT_NO_CACHE, '-', "Disable session cache"}, -+ {"ext_cache", OPT_EXT_CACHE, '-', -+ "Disable internal cache, setup and use external cache"}, -+ {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, -+ {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', -+ "Close connection on verification error"}, -+ {"verify_quiet", OPT_VERIFY_QUIET, '-', -+ "No verify output except verify errors"}, -+ {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, -+ {"chainCAfile", OPT_CHAINCAFILE, '<', -+ "CA file for certificate chain (PEM format)"}, -+ {"verifyCAfile", OPT_VERIFYCAFILE, '<', -+ "CA file for certificate verification (PEM format)"}, -+ {"ign_eof", OPT_IGN_EOF, '-', "ignore input eof (default when -quiet)"}, -+ {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input eof"}, -+#ifndef OPENSSL_NO_OCSP -+ {"status", OPT_STATUS, '-', "Request certificate status from server"}, -+ {"status_verbose", OPT_STATUS_VERBOSE, '-', -+ "Print more output in certificate status callback"}, -+ {"status_timeout", OPT_STATUS_TIMEOUT, 'n', -+ "Status request responder timeout"}, -+ {"status_url", OPT_STATUS_URL, 's', "Status request fallback URL"}, -+#endif -+#ifndef OPENSSL_NO_SSL_TRACE -+ {"trace", OPT_TRACE, '-', "trace protocol messages"}, -+#endif -+ {"security_debug", OPT_SECURITY_DEBUG, '-', -+ "Print output from SSL/TLS security framework"}, -+ {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-', -+ "Print more output from SSL/TLS security framework"}, -+ {"brief", OPT_BRIEF, '-', -+ "Restrict output to brief summary of connection parameters"}, -+ {"rev", OPT_REV, '-', -+ "act as a simple test server which just sends back with the received text reversed"}, -+ {"async", OPT_ASYNC, '-', "Operate in asynchronous mode"}, -+ {"ssl_config", OPT_SSL_CONFIG, 's', -+ "Configure SSL_CTX using the configuration 'val'"}, -+ {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'n', -+ "Size used to split data for encrypt pipelines"}, -+ {"max_pipelines", OPT_MAX_PIPELINES, 'n', -+ "Maximum number of encrypt/decrypt pipelines to be used"}, -+ {"read_buf", OPT_READ_BUF, 'n', -+ "Default read buffer size to be used for connections"}, -+ OPT_S_OPTIONS, -+ OPT_V_OPTIONS, -+ OPT_X_OPTIONS, -+ {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, -+#ifndef OPENSSL_NO_PSK -+ {"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"}, -+ {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, -+#endif -+#ifndef OPENSSL_NO_SRP -+ {"srpvfile", OPT_SRPVFILE, '<', "The verifier file for SRP"}, -+ {"srpuserseed", OPT_SRPUSERSEED, 's', -+ "A seed string for a default user salt"}, -+#endif -+#ifndef OPENSSL_NO_SSL3 -+ {"ssl3", OPT_SSL3, '-', "Just talk SSLv3"}, -+#endif -+#ifndef OPENSSL_NO_TLS1 -+ {"tls1", OPT_TLS1, '-', "Just talk TLSv1"}, -+#endif -+#ifndef OPENSSL_NO_TLS1_1 -+ {"tls1_1", OPT_TLS1_1, '-', "Just talk TLSv1.1"}, -+#endif -+#ifndef OPENSSL_NO_TLS1_2 -+ {"tls1_2", OPT_TLS1_2, '-', "just talk TLSv1.2"}, -+#endif -+#ifndef OPENSSL_NO_DTLS -+ {"dtls", OPT_DTLS, '-', "Use any DTLS version"}, -+ {"timeout", OPT_TIMEOUT, '-', "Enable timeouts"}, -+ {"mtu", OPT_MTU, 'p', "Set link layer MTU"}, -+ {"listen", OPT_LISTEN, '-', -+ "Listen for a DTLS ClientHello with a cookie and then connect"}, -+#endif -+#ifndef OPENSSL_NO_DTLS1 -+ {"dtls1", OPT_DTLS1, '-', "Just talk DTLSv1"}, -+#endif -+#ifndef OPENSSL_NO_DTLS1_2 -+ {"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"}, -+#endif -+#ifndef OPENSSL_NO_DH -+ {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"}, -+#endif -+#ifndef OPENSSL_NO_NEXTPROTONEG -+ {"nextprotoneg", OPT_NEXTPROTONEG, 's', -+ "Set the advertised protocols for the NPN extension (comma-separated list)"}, -+#endif -+#ifndef OPENSSL_NO_SRTP -+ {"use_srtp", OPT_SRTP_PROFILES, 's', -+ "Offer SRTP key management with a colon-separated profile list"}, -+#endif -+ {"alpn", OPT_ALPN, 's', -+ "Set the advertised protocols for the ALPN extension (comma-separated list)"}, -+#ifndef OPENSSL_NO_ENGINE -+ {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, -+#endif -+ {NULL, OPT_EOF, 0, NULL} -+}; -+ -+#define IS_PROT_FLAG(o) \ -+ (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ -+ || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2) -+ -+int s_server_main(int argc, char *argv[]) -+{ -+ ENGINE *engine = NULL; -+ EVP_PKEY *s_key = NULL, *s_dkey = NULL; -+ SSL_CONF_CTX *cctx = NULL; -+ const SSL_METHOD *meth = TLS_server_method(); -+ SSL_EXCERT *exc = NULL; -+ STACK_OF(OPENSSL_STRING) *ssl_args = NULL; -+ STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL; -+ STACK_OF(X509_CRL) *crls = NULL; -+ X509 *s_cert = NULL, *s_dcert = NULL; -+ X509_VERIFY_PARAM *vpm = NULL; -+ const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL; -+ char *dpassarg = NULL, *dpass = NULL, *inrand = NULL; -+ char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; -+ char *crl_file = NULL, *prog; -+#ifdef AF_UNIX -+ int unlink_unix_path = 0; -+#endif -+ do_server_cb server_cb; -+ int vpmtouched = 0, build_chain = 0, no_cache = 0, ext_cache = 0; -+#ifndef OPENSSL_NO_DH -+ char *dhfile = NULL; -+ int no_dhe = 0; -+#endif -+ int nocert = 0, ret = 1; -+ int noCApath = 0, noCAfile = 0; -+ int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; -+ int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; -+ int rev = 0, naccept = -1, sdebug = 0; -+ int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM; -+ int state = 0, crl_format = FORMAT_PEM, crl_download = 0; -+ char *host = NULL; -+ char *port = BUF_strdup(PORT); -+ unsigned char *context = NULL; -+ OPTION_CHOICE o; -+ EVP_PKEY *s_key2 = NULL; -+ X509 *s_cert2 = NULL; -+ tlsextctx tlsextcbp = { NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING }; -+ const char *ssl_config = NULL; -+ int read_buf_len = 0; -+#ifndef OPENSSL_NO_NEXTPROTONEG -+ const char *next_proto_neg_in = NULL; -+ tlsextnextprotoctx next_proto = { NULL, 0 }; -+#endif -+ const char *alpn_in = NULL; -+ tlsextalpnctx alpn_ctx = { NULL, 0 }; -+#ifndef OPENSSL_NO_PSK -+ /* by default do not send a PSK identity hint */ -+ static char *psk_identity_hint = NULL; -+ char *p; -+#endif -+#ifndef OPENSSL_NO_SRP -+ char *srpuserseed = NULL; -+ char *srp_verifier_file = NULL; -+#endif -+ int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0; -+ int s_server_verify = SSL_VERIFY_NONE; -+ int s_server_session_id_context = 1; /* anything will do */ -+ const char *s_cert_file = TEST_CERT, *s_key_file = NULL, *s_chain_file = NULL; -+ const char *s_cert_file2 = TEST_CERT2, *s_key_file2 = NULL; -+ char *s_dcert_file = NULL, *s_dkey_file = NULL, *s_dchain_file = NULL; -+#ifndef OPENSSL_NO_OCSP -+ int s_tlsextstatus = 0; -+#endif -+ int no_resume_ephemeral = 0; -+ unsigned int split_send_fragment = 0, max_pipelines = 0; -+ const char *s_serverinfo_file = NULL; -+ -+ /* Init of few remaining global variables */ -+ local_argc = argc; -+ local_argv = argv; -+ -+ ctx = ctx2 = NULL; -+ s_nbio = s_nbio_test = 0; -+ www = 0; -+ bio_s_out = NULL; -+ s_debug = 0; -+ s_msg = 0; -+ s_quiet = 0; -+ s_brief = 0; -+ async = 0; -+ -+ cctx = SSL_CONF_CTX_new(); -+ vpm = X509_VERIFY_PARAM_new(); -+ if (cctx == NULL || vpm == NULL) -+ goto end; -+ SSL_CONF_CTX_set_flags(cctx, -+ SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CMDLINE); -+ -+ prog = opt_init(argc, argv, s_server_options); -+ while ((o = opt_next()) != OPT_EOF) { -+ if (IS_PROT_FLAG(o) && ++prot_opt > 1) { -+ BIO_printf(bio_err, "Cannot supply multiple protocol flags\n"); -+ goto end; -+ } -+ if (IS_NO_PROT_FLAG(o)) -+ no_prot_opt++; -+ if (prot_opt == 1 && no_prot_opt) { -+ BIO_printf(bio_err, -+ "Cannot supply both a protocol flag and '-no_'\n"); -+ goto end; -+ } -+ switch (o) { -+ case OPT_EOF: -+ case OPT_ERR: -+ opthelp: -+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); -+ goto end; -+ case OPT_HELP: -+ opt_help(s_server_options); -+ ret = 0; -+ goto end; -+ -+ case OPT_4: -+#ifdef AF_UNIX -+ if (socket_family == AF_UNIX) { -+ OPENSSL_free(host); host = NULL; -+ OPENSSL_free(port); port = NULL; -+ } -+#endif -+ socket_family = AF_INET; -+ break; -+ case OPT_6: -+ if (1) { -+#ifdef AF_INET6 -+#ifdef AF_UNIX -+ if (socket_family == AF_UNIX) { -+ OPENSSL_free(host); host = NULL; -+ OPENSSL_free(port); port = NULL; -+ } -+#endif -+ socket_family = AF_INET6; -+ } else { -+#endif -+ BIO_printf(bio_err, "%s: IPv6 domain sockets unsupported\n", prog); -+ goto end; -+ } -+ break; -+ case OPT_PORT: -+#ifdef AF_UNIX -+ if (socket_family == AF_UNIX) { -+ socket_family = AF_UNSPEC; -+ } -+#endif -+ OPENSSL_free(port); port = NULL; -+ OPENSSL_free(host); host = NULL; -+ if (BIO_parse_hostserv(opt_arg(), NULL, &port, BIO_PARSE_PRIO_SERV) < 1) { -+ BIO_printf(bio_err, -+ "%s: -port argument malformed or ambiguous\n", -+ port); -+ goto end; -+ } -+ break; -+ case OPT_ACCEPT: -+#ifdef AF_UNIX -+ if (socket_family == AF_UNIX) { -+ socket_family = AF_UNSPEC; -+ } -+#endif -+ OPENSSL_free(port); port = NULL; -+ OPENSSL_free(host); host = NULL; -+ if (BIO_parse_hostserv(opt_arg(), &host, &port, BIO_PARSE_PRIO_SERV) < 1) { -+ BIO_printf(bio_err, -+ "%s: -accept argument malformed or ambiguous\n", -+ port); -+ goto end; -+ } -+ break; -+#ifdef AF_UNIX -+ case OPT_UNIX: -+ socket_family = AF_UNIX; -+ OPENSSL_free(host); host = BUF_strdup(opt_arg()); -+ OPENSSL_free(port); port = NULL; -+ break; -+ case OPT_UNLINK: -+ unlink_unix_path = 1; -+ break; -+#endif -+ case OPT_NACCEPT: -+ naccept = atol(opt_arg()); -+ break; -+ case OPT_VERIFY: -+ s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; -+ verify_args.depth = atoi(opt_arg()); -+ if (!s_quiet) -+ BIO_printf(bio_err, "verify depth is %d\n", verify_args.depth); -+ break; -+ case OPT_UPPER_V_VERIFY: -+ s_server_verify = -+ SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | -+ SSL_VERIFY_CLIENT_ONCE; -+ verify_args.depth = atoi(opt_arg()); -+ if (!s_quiet) -+ BIO_printf(bio_err, -+ "verify depth is %d, must return a certificate\n", -+ verify_args.depth); -+ break; -+ case OPT_CONTEXT: -+ context = (unsigned char *)opt_arg(); -+ break; -+ case OPT_CERT: -+ s_cert_file = opt_arg(); -+ break; -+ case OPT_CRL: -+ crl_file = opt_arg(); -+ break; -+ case OPT_CRL_DOWNLOAD: -+ crl_download = 1; -+ break; -+ case OPT_SERVERINFO: -+ s_serverinfo_file = opt_arg(); -+ break; -+ case OPT_CERTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_cert_format)) -+ goto opthelp; -+ break; -+ case OPT_KEY: -+ s_key_file = opt_arg(); -+ break; -+ case OPT_KEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &s_key_format)) -+ goto opthelp; -+ break; -+ case OPT_PASS: -+ passarg = opt_arg(); -+ break; -+ case OPT_CERT_CHAIN: -+ s_chain_file = opt_arg(); -+ break; -+ case OPT_DHPARAM: -+#ifndef OPENSSL_NO_DH -+ dhfile = opt_arg(); -+#endif -+ break; -+ case OPT_DCERTFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dcert_format)) -+ goto opthelp; -+ break; -+ case OPT_DCERT: -+ s_dcert_file = opt_arg(); -+ break; -+ case OPT_DKEYFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dkey_format)) -+ goto opthelp; -+ break; -+ case OPT_DPASS: -+ dpassarg = opt_arg(); -+ break; -+ case OPT_DKEY: -+ s_dkey_file = opt_arg(); -+ break; -+ case OPT_DCERT_CHAIN: -+ s_dchain_file = opt_arg(); -+ break; -+ case OPT_NOCERT: -+ nocert = 1; -+ break; -+ case OPT_CAPATH: -+ CApath = opt_arg(); -+ break; -+ case OPT_NOCAPATH: -+ noCApath = 1; -+ break; -+ case OPT_CHAINCAPATH: -+ chCApath = opt_arg(); -+ break; -+ case OPT_VERIFYCAPATH: -+ vfyCApath = opt_arg(); -+ break; -+ case OPT_NO_CACHE: -+ no_cache = 1; -+ break; -+ case OPT_EXT_CACHE: -+ ext_cache = 1; -+ break; -+ case OPT_CRLFORM: -+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format)) -+ goto opthelp; -+ break; -+ case OPT_S_CASES: -+ if (ssl_args == NULL) -+ ssl_args = sk_OPENSSL_STRING_new_null(); -+ if (ssl_args == NULL -+ || !sk_OPENSSL_STRING_push(ssl_args, opt_flag()) -+ || !sk_OPENSSL_STRING_push(ssl_args, opt_arg())) { -+ BIO_printf(bio_err, "%s: Memory allocation failure\n", prog); -+ goto end; -+ } -+ break; -+ case OPT_V_CASES: -+ if (!opt_verify(o, vpm)) -+ goto end; -+ vpmtouched++; -+ break; -+ case OPT_X_CASES: -+ if (!args_excert(o, &exc)) -+ goto end; -+ break; -+ case OPT_VERIFY_RET_ERROR: -+ verify_args.return_error = 1; -+ break; -+ case OPT_VERIFY_QUIET: -+ verify_args.quiet = 1; -+ break; -+ case OPT_BUILD_CHAIN: -+ build_chain = 1; -+ break; -+ case OPT_CAFILE: -+ CAfile = opt_arg(); -+ break; -+ case OPT_NOCAFILE: -+ noCAfile = 1; -+ break; -+ case OPT_CHAINCAFILE: -+ chCAfile = opt_arg(); -+ break; -+ case OPT_VERIFYCAFILE: -+ vfyCAfile = opt_arg(); -+ break; -+ case OPT_NBIO: -+ s_nbio = 1; -+ break; -+ case OPT_NBIO_TEST: -+ s_nbio = s_nbio_test = 1; -+ break; -+ case OPT_IGN_EOF: -+ s_ign_eof = 1; -+ break; -+ case OPT_NO_IGN_EOF: -+ s_ign_eof = 0; -+ break; -+ case OPT_DEBUG: -+ s_debug = 1; -+ break; -+ case OPT_TLSEXTDEBUG: -+ s_tlsextdebug = 1; -+ break; -+ case OPT_STATUS: -+#ifndef OPENSSL_NO_OCSP -+ s_tlsextstatus = 1; -+#endif -+ break; -+ case OPT_STATUS_VERBOSE: -+#ifndef OPENSSL_NO_OCSP -+ s_tlsextstatus = tlscstatp.verbose = 1; -+#endif -+ break; -+ case OPT_STATUS_TIMEOUT: -+#ifndef OPENSSL_NO_OCSP -+ s_tlsextstatus = 1; -+ tlscstatp.timeout = atoi(opt_arg()); -+#endif -+ break; -+ case OPT_STATUS_URL: -+#ifndef OPENSSL_NO_OCSP -+ s_tlsextstatus = 1; -+ if (!OCSP_parse_url(opt_arg(), -+ &tlscstatp.host, -+ &tlscstatp.port, -+ &tlscstatp.path, &tlscstatp.use_ssl)) { -+ BIO_printf(bio_err, "Error parsing URL\n"); -+ goto end; -+ } -+#endif -+ break; -+ case OPT_MSG: -+ s_msg = 1; -+ break; -+ case OPT_MSGFILE: -+ bio_s_msg = BIO_new_file(opt_arg(), "w"); -+ break; -+ case OPT_TRACE: -+#ifndef OPENSSL_NO_SSL_TRACE -+ s_msg = 2; -+#endif -+ break; -+ case OPT_SECURITY_DEBUG: -+ sdebug = 1; -+ break; -+ case OPT_SECURITY_DEBUG_VERBOSE: -+ sdebug = 2; -+ break; -+ case OPT_STATE: -+ state = 1; -+ break; -+ case OPT_CRLF: -+ s_crlf = 1; -+ break; -+ case OPT_QUIET: -+ s_quiet = 1; -+ break; -+ case OPT_BRIEF: -+ s_quiet = s_brief = verify_args.quiet = 1; -+ break; -+ case OPT_NO_DHE: -+#ifndef OPENSSL_NO_DH -+ no_dhe = 1; -+#endif -+ break; -+ case OPT_NO_RESUME_EPHEMERAL: -+ no_resume_ephemeral = 1; -+ break; -+ case OPT_PSK_HINT: -+#ifndef OPENSSL_NO_PSK -+ psk_identity_hint = opt_arg(); -+#endif -+ break; -+ case OPT_PSK: -+#ifndef OPENSSL_NO_PSK -+ for (p = psk_key = opt_arg(); *p; p++) { -+ if (isxdigit(_UC(*p))) -+ continue; -+ BIO_printf(bio_err, "Not a hex number '%s'\n", *argv); -+ goto end; -+ } -+#endif -+ break; -+ case OPT_SRPVFILE: -+#ifndef OPENSSL_NO_SRP -+ srp_verifier_file = opt_arg(); -+ if (min_version < TLS1_VERSION) -+ min_version = TLS1_VERSION; -+#endif -+ break; -+ case OPT_SRPUSERSEED: -+#ifndef OPENSSL_NO_SRP -+ srpuserseed = opt_arg(); -+ if (min_version < TLS1_VERSION) -+ min_version = TLS1_VERSION; -+#endif -+ break; -+ case OPT_REV: -+ rev = 1; -+ break; -+ case OPT_WWW: -+ www = 1; -+ break; -+ case OPT_UPPER_WWW: -+ www = 2; -+ break; -+ case OPT_HTTP: -+ www = 3; -+ break; -+ case OPT_SSL_CONFIG: -+ ssl_config = opt_arg(); -+ break; -+ case OPT_SSL3: -+ min_version = SSL3_VERSION; -+ max_version = SSL3_VERSION; -+ break; -+ case OPT_TLS1_2: -+ min_version = TLS1_2_VERSION; -+ max_version = TLS1_2_VERSION; -+ break; -+ case OPT_TLS1_1: -+ min_version = TLS1_1_VERSION; -+ max_version = TLS1_1_VERSION; -+ break; -+ case OPT_TLS1: -+ min_version = TLS1_VERSION; -+ max_version = TLS1_VERSION; -+ break; -+ case OPT_DTLS: -+#ifndef OPENSSL_NO_DTLS -+ meth = DTLS_server_method(); -+ socket_type = SOCK_DGRAM; -+#endif -+ break; -+ case OPT_DTLS1: -+#ifndef OPENSSL_NO_DTLS -+ meth = DTLS_server_method(); -+ min_version = DTLS1_VERSION; -+ max_version = DTLS1_VERSION; -+ socket_type = SOCK_DGRAM; -+#endif -+ break; -+ case OPT_DTLS1_2: -+#ifndef OPENSSL_NO_DTLS -+ meth = DTLS_server_method(); -+ min_version = DTLS1_2_VERSION; -+ max_version = DTLS1_2_VERSION; -+ socket_type = SOCK_DGRAM; -+#endif -+ break; -+ case OPT_TIMEOUT: -+#ifndef OPENSSL_NO_DTLS -+ enable_timeouts = 1; -+#endif -+ break; -+ case OPT_MTU: -+#ifndef OPENSSL_NO_DTLS -+ socket_mtu = atol(opt_arg()); -+#endif -+ break; -+ case OPT_LISTEN: -+#ifndef OPENSSL_NO_DTLS -+ dtlslisten = 1; -+#endif -+ break; -+ case OPT_ID_PREFIX: -+ session_id_prefix = opt_arg(); -+ break; -+ case OPT_ENGINE: -+ engine = setup_engine(opt_arg(), 1); -+ break; -+ case OPT_RAND: -+ inrand = opt_arg(); -+ break; -+ case OPT_SERVERNAME: -+ tlsextcbp.servername = opt_arg(); -+ break; -+ case OPT_SERVERNAME_FATAL: -+ tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; -+ break; -+ case OPT_CERT2: -+ s_cert_file2 = opt_arg(); -+ break; -+ case OPT_KEY2: -+ s_key_file2 = opt_arg(); -+ break; -+ case OPT_NEXTPROTONEG: -+# ifndef OPENSSL_NO_NEXTPROTONEG -+ next_proto_neg_in = opt_arg(); -+#endif -+ break; -+ case OPT_ALPN: -+ alpn_in = opt_arg(); -+ break; -+ case OPT_SRTP_PROFILES: -+#ifndef OPENSSL_NO_SRTP -+ srtp_profiles = opt_arg(); -+#endif -+ break; -+ case OPT_KEYMATEXPORT: -+ keymatexportlabel = opt_arg(); -+ break; -+ case OPT_KEYMATEXPORTLEN: -+ keymatexportlen = atoi(opt_arg()); -+ break; -+ case OPT_ASYNC: -+ async = 1; -+ break; -+ case OPT_SPLIT_SEND_FRAG: -+ split_send_fragment = atoi(opt_arg()); -+ if (split_send_fragment == 0) { -+ /* -+ * Not allowed - set to a deliberately bad value so we get an -+ * error message below -+ */ -+ split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH + 1; -+ } -+ break; -+ case OPT_MAX_PIPELINES: -+ max_pipelines = atoi(opt_arg()); -+ break; -+ case OPT_READ_BUF: -+ read_buf_len = atoi(opt_arg()); -+ break; -+ -+ } -+ } -+ argc = opt_num_rest(); -+ argv = opt_rest(); -+ -+#ifndef OPENSSL_NO_DTLS -+ if (www && socket_type == SOCK_DGRAM) { -+ BIO_printf(bio_err, "Can't use -HTTP, -www or -WWW with DTLS\n"); -+ goto end; -+ } -+ -+ if (dtlslisten && socket_type != SOCK_DGRAM) { -+ BIO_printf(bio_err, "Can only use -listen with DTLS\n"); -+ goto end; -+ } -+#endif -+ -+#ifdef AF_UNIX -+ if (socket_family == AF_UNIX && socket_type != SOCK_STREAM) { -+ BIO_printf(bio_err, -+ "Can't use unix sockets and datagrams together\n"); -+ goto end; -+ } -+#endif -+ -+ if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) { -+ BIO_printf(bio_err, "Bad split send fragment size\n"); -+ goto end; -+ } -+ -+ if (max_pipelines > SSL_MAX_PIPELINES) { -+ BIO_printf(bio_err, "Bad max pipelines value\n"); -+ goto end; -+ } -+ -+ if (!app_passwd(passarg, dpassarg, &pass, &dpass)) { -+ BIO_printf(bio_err, "Error getting password\n"); -+ goto end; -+ } -+ -+ if (s_key_file == NULL) -+ s_key_file = s_cert_file; -+ -+ if (s_key_file2 == NULL) -+ s_key_file2 = s_cert_file2; -+ -+ if (!load_excert(&exc)) -+ goto end; -+ -+ if (nocert == 0) { -+ s_key = load_key(s_key_file, s_key_format, 0, pass, engine, -+ "server certificate private key file"); -+ if (!s_key) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ s_cert = load_cert(s_cert_file, s_cert_format, -+ "server certificate file"); -+ -+ if (!s_cert) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (s_chain_file) { -+ if (!load_certs(s_chain_file, &s_chain, FORMAT_PEM, NULL, -+ "server certificate chain")) -+ goto end; -+ } -+ -+ if (tlsextcbp.servername) { -+ s_key2 = load_key(s_key_file2, s_key_format, 0, pass, engine, -+ "second server certificate private key file"); -+ if (!s_key2) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ s_cert2 = load_cert(s_cert_file2, s_cert_format, -+ "second server certificate file"); -+ -+ if (!s_cert2) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ } -+#if !defined(OPENSSL_NO_NEXTPROTONEG) -+ if (next_proto_neg_in) { -+ size_t len; -+ next_proto.data = next_protos_parse(&len, next_proto_neg_in); -+ if (next_proto.data == NULL) -+ goto end; -+ next_proto.len = len; -+ } else { -+ next_proto.data = NULL; -+ } -+#endif -+ alpn_ctx.data = NULL; -+ if (alpn_in) { -+ size_t len; -+ alpn_ctx.data = next_protos_parse(&len, alpn_in); -+ if (alpn_ctx.data == NULL) -+ goto end; -+ alpn_ctx.len = len; -+ } -+ -+ if (crl_file) { -+ X509_CRL *crl; -+ crl = load_crl(crl_file, crl_format); -+ if (!crl) { -+ BIO_puts(bio_err, "Error loading CRL\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ crls = sk_X509_CRL_new_null(); -+ if (!crls || !sk_X509_CRL_push(crls, crl)) { -+ BIO_puts(bio_err, "Error adding CRL\n"); -+ ERR_print_errors(bio_err); -+ X509_CRL_free(crl); -+ goto end; -+ } -+ } -+ -+ if (s_dcert_file) { -+ -+ if (s_dkey_file == NULL) -+ s_dkey_file = s_dcert_file; -+ -+ s_dkey = load_key(s_dkey_file, s_dkey_format, -+ 0, dpass, engine, "second certificate private key file"); -+ if (!s_dkey) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ s_dcert = load_cert(s_dcert_file, s_dcert_format, -+ "second server certificate file"); -+ -+ if (!s_dcert) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (s_dchain_file) { -+ if (!load_certs(s_dchain_file, &s_dchain, FORMAT_PEM, NULL, -+ "second server certificate chain")) -+ goto end; -+ } -+ -+ } -+ -+ if (!app_RAND_load_file(NULL, 1) && inrand == NULL -+ && !RAND_status()) { -+ BIO_printf(bio_err, -+ "warning, not much extra random data, consider using the -rand option\n"); -+ } -+ if (inrand != NULL) -+ BIO_printf(bio_err, "%ld semi-random bytes loaded\n", -+ app_RAND_load_files(inrand)); -+ -+ if (bio_s_out == NULL) { -+ if (s_quiet && !s_debug) { -+ bio_s_out = BIO_new(BIO_s_null()); -+ if (s_msg && !bio_s_msg) -+ bio_s_msg = dup_bio_out(FORMAT_TEXT); -+ } else { -+ if (bio_s_out == NULL) -+ bio_s_out = dup_bio_out(FORMAT_TEXT); -+ } -+ } -+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) -+ if (nocert) -+#endif -+ { -+ s_cert_file = NULL; -+ s_key_file = NULL; -+ s_dcert_file = NULL; -+ s_dkey_file = NULL; -+ s_cert_file2 = NULL; -+ s_key_file2 = NULL; -+ } -+ -+ ctx = SSL_CTX_new(meth); -+ if (ctx == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (sdebug) -+ ssl_ctx_security_debug(ctx, sdebug); -+ if (ssl_config) { -+ if (SSL_CTX_config(ctx, ssl_config) == 0) { -+ BIO_printf(bio_err, "Error using configuration \"%s\"\n", -+ ssl_config); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0) -+ goto end; -+ if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) -+ goto end; -+ -+ if (session_id_prefix) { -+ if (strlen(session_id_prefix) >= 32) -+ BIO_printf(bio_err, -+ "warning: id_prefix is too long, only one new session will be possible\n"); -+ if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) { -+ BIO_printf(bio_err, "error setting 'id_prefix'\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); -+ } -+ SSL_CTX_set_quiet_shutdown(ctx, 1); -+ if (exc) -+ ssl_ctx_set_excert(ctx, exc); -+ -+ if (state) -+ SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); -+ if (no_cache) -+ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); -+ else if (ext_cache) -+ init_session_cache_ctx(ctx); -+ else -+ SSL_CTX_sess_set_cache_size(ctx, 128); -+ -+ if (async) { -+ SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC); -+ } -+ if (split_send_fragment > 0) { -+ SSL_CTX_set_split_send_fragment(ctx, split_send_fragment); -+ } -+ if (max_pipelines > 0) { -+ SSL_CTX_set_max_pipelines(ctx, max_pipelines); -+ } -+ -+ if (read_buf_len > 0) { -+ SSL_CTX_set_default_read_buffer_len(ctx, read_buf_len); -+ } -+#ifndef OPENSSL_NO_SRTP -+ if (srtp_profiles != NULL) { -+ /* Returns 0 on success! */ -+ if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles) != 0) { -+ BIO_printf(bio_err, "Error setting SRTP profile\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+#endif -+ -+ if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) { -+ BIO_printf(bio_err, "Error setting verify params\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ ssl_ctx_add_crls(ctx, crls, 0); -+ if (!config_ctx(cctx, ssl_args, ctx)) -+ goto end; -+ -+ if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, -+ crls, crl_download)) { -+ BIO_printf(bio_err, "Error loading store locations\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (s_cert2) { -+ ctx2 = SSL_CTX_new(meth); -+ if (ctx2 == NULL) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ } -+ -+ if (ctx2) { -+ BIO_printf(bio_s_out, "Setting secondary ctx parameters\n"); -+ -+ if (sdebug) -+ ssl_ctx_security_debug(ctx, sdebug); -+ -+ if (session_id_prefix) { -+ if (strlen(session_id_prefix) >= 32) -+ BIO_printf(bio_err, -+ "warning: id_prefix is too long, only one new session will be possible\n"); -+ if (!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) { -+ BIO_printf(bio_err, "error setting 'id_prefix'\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); -+ } -+ SSL_CTX_set_quiet_shutdown(ctx2, 1); -+ if (exc) -+ ssl_ctx_set_excert(ctx2, exc); -+ -+ if (state) -+ SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback); -+ -+ if (no_cache) -+ SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF); -+ else if (ext_cache) -+ init_session_cache_ctx(ctx2); -+ else -+ SSL_CTX_sess_set_cache_size(ctx2, 128); -+ -+ if (async) -+ SSL_CTX_set_mode(ctx2, SSL_MODE_ASYNC); -+ -+ if (!ctx_set_verify_locations(ctx2, CAfile, CApath, noCAfile, -+ noCApath)) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ if (vpmtouched && !SSL_CTX_set1_param(ctx2, vpm)) { -+ BIO_printf(bio_err, "Error setting verify params\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ ssl_ctx_add_crls(ctx2, crls, 0); -+ if (!config_ctx(cctx, ssl_args, ctx2)) -+ goto end; -+ } -+#ifndef OPENSSL_NO_NEXTPROTONEG -+ if (next_proto.data) -+ SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, -+ &next_proto); -+#endif -+ if (alpn_ctx.data) -+ SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx); -+ -+#ifndef OPENSSL_NO_DH -+ if (!no_dhe) { -+ DH *dh = NULL; -+ -+ if (dhfile) -+ dh = load_dh_param(dhfile); -+ else if (s_cert_file) -+ dh = load_dh_param(s_cert_file); -+ -+ if (dh != NULL) { -+ BIO_printf(bio_s_out, "Setting temp DH parameters\n"); -+ } else { -+ BIO_printf(bio_s_out, "Using default temp DH parameters\n"); -+ } -+ (void)BIO_flush(bio_s_out); -+ -+ if (dh == NULL) -+ SSL_CTX_set_dh_auto(ctx, 1); -+ else if (!SSL_CTX_set_tmp_dh(ctx, dh)) { -+ BIO_puts(bio_err, "Error setting temp DH parameters\n"); -+ ERR_print_errors(bio_err); -+ DH_free(dh); -+ goto end; -+ } -+ -+ if (ctx2) { -+ if (!dhfile) { -+ DH *dh2 = load_dh_param(s_cert_file2); -+ if (dh2 != NULL) { -+ BIO_printf(bio_s_out, "Setting temp DH parameters\n"); -+ (void)BIO_flush(bio_s_out); -+ -+ DH_free(dh); -+ dh = dh2; -+ } -+ } -+ if (dh == NULL) -+ SSL_CTX_set_dh_auto(ctx2, 1); -+ else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) { -+ BIO_puts(bio_err, "Error setting temp DH parameters\n"); -+ ERR_print_errors(bio_err); -+ DH_free(dh); -+ goto end; -+ } -+ } -+ DH_free(dh); -+ } -+#endif -+ -+ if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain)) -+ goto end; -+ -+ if (s_serverinfo_file != NULL -+ && !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file)) { -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2, NULL, build_chain)) -+ goto end; -+ -+ if (s_dcert != NULL) { -+ if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain, build_chain)) -+ goto end; -+ } -+ -+ if (no_resume_ephemeral) { -+ SSL_CTX_set_not_resumable_session_callback(ctx, -+ not_resumable_sess_cb); -+ -+ if (ctx2) -+ SSL_CTX_set_not_resumable_session_callback(ctx2, -+ not_resumable_sess_cb); -+ } -+#ifndef OPENSSL_NO_PSK -+ if (psk_key != NULL) { -+ if (s_debug) -+ BIO_printf(bio_s_out, "PSK key given, setting server callback\n"); -+ SSL_CTX_set_psk_server_callback(ctx, psk_server_cb); -+ } -+ -+ if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) { -+ BIO_printf(bio_err, "error setting PSK identity hint to context\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+#endif -+ -+ SSL_CTX_set_verify(ctx, s_server_verify, verify_callback); -+ if (!SSL_CTX_set_session_id_context(ctx, -+ (void *)&s_server_session_id_context, -+ sizeof s_server_session_id_context)) { -+ BIO_printf(bio_err, "error setting session id context\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ -+ /* Set DTLS cookie generation and verification callbacks */ -+ SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback); -+ SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback); -+ -+ if (ctx2) { -+ SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback); -+ if (!SSL_CTX_set_session_id_context(ctx2, -+ (void *)&s_server_session_id_context, -+ sizeof s_server_session_id_context)) { -+ BIO_printf(bio_err, "error setting session id context\n"); -+ ERR_print_errors(bio_err); -+ goto end; -+ } -+ tlsextcbp.biodebug = bio_s_out; -+ SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb); -+ SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp); -+ SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); -+ SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); -+ } -+ -+#ifndef OPENSSL_NO_SRP -+ if (srp_verifier_file != NULL) { -+ srp_callback_parm.vb = SRP_VBASE_new(srpuserseed); -+ srp_callback_parm.user = NULL; -+ srp_callback_parm.login = NULL; -+ if ((ret = -+ SRP_VBASE_init(srp_callback_parm.vb, -+ srp_verifier_file)) != SRP_NO_ERROR) { -+ BIO_printf(bio_err, -+ "Cannot initialize SRP verifier file \"%s\":ret=%d\n", -+ srp_verifier_file, ret); -+ goto end; -+ } -+ SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback); -+ SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm); -+ SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb); -+ } else -+#endif -+ if (CAfile != NULL) { -+ SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile)); -+ -+ if (ctx2) -+ SSL_CTX_set_client_CA_list(ctx2, SSL_load_client_CA_file(CAfile)); -+ } -+#ifndef OPENSSL_NO_OCSP -+ if (s_tlsextstatus) { -+ SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb); -+ SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp); -+ if (ctx2) { -+ SSL_CTX_set_tlsext_status_cb(ctx2, cert_status_cb); -+ SSL_CTX_set_tlsext_status_arg(ctx2, &tlscstatp); -+ } -+ } -+#endif -+ -+ BIO_printf(bio_s_out, "ACCEPT\n"); -+ (void)BIO_flush(bio_s_out); -+ if (rev) -+ server_cb = rev_body; -+ else if (www) -+ server_cb = www_body; -+ else -+ server_cb = sv_body; -+#ifdef AF_UNIX -+ if (socket_family == AF_UNIX -+ && unlink_unix_path) -+ unlink(host); -+#endif -+ do_server(&accept_socket, host, port, socket_family, socket_type, -+ server_cb, context, naccept); -+ print_stats(bio_s_out, ctx); -+ ret = 0; -+ end: -+ SSL_CTX_free(ctx); -+ X509_free(s_cert); -+ sk_X509_CRL_pop_free(crls, X509_CRL_free); -+ X509_free(s_dcert); -+ EVP_PKEY_free(s_key); -+ EVP_PKEY_free(s_dkey); -+ sk_X509_pop_free(s_chain, X509_free); -+ sk_X509_pop_free(s_dchain, X509_free); -+ OPENSSL_free(pass); -+ OPENSSL_free(dpass); -+ OPENSSL_free(host); -+ OPENSSL_free(port); -+ X509_VERIFY_PARAM_free(vpm); -+ free_sessions(); -+ OPENSSL_free(tlscstatp.host); -+ OPENSSL_free(tlscstatp.port); -+ OPENSSL_free(tlscstatp.path); -+ SSL_CTX_free(ctx2); -+ X509_free(s_cert2); -+ EVP_PKEY_free(s_key2); -+#ifndef OPENSSL_NO_NEXTPROTONEG -+ OPENSSL_free(next_proto.data); -+#endif -+ OPENSSL_free(alpn_ctx.data); -+ ssl_excert_free(exc); -+ sk_OPENSSL_STRING_free(ssl_args); -+ SSL_CONF_CTX_free(cctx); -+ release_engine(engine); -+ BIO_free(bio_s_out); -+ bio_s_out = NULL; -+ BIO_free(bio_s_msg); -+ bio_s_msg = NULL; -+#ifdef CHARSET_EBCDIC -+ BIO_meth_free(methods_ebcdic); -+#endif -+ return (ret); -+} -+ -+static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) -+{ -+ BIO_printf(bio, "%4ld items in the session cache\n", -+ SSL_CTX_sess_number(ssl_ctx)); -+ BIO_printf(bio, "%4ld client connects (SSL_connect())\n", -+ SSL_CTX_sess_connect(ssl_ctx)); -+ BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n", -+ SSL_CTX_sess_connect_renegotiate(ssl_ctx)); -+ BIO_printf(bio, "%4ld client connects that finished\n", -+ SSL_CTX_sess_connect_good(ssl_ctx)); -+ BIO_printf(bio, "%4ld server accepts (SSL_accept())\n", -+ SSL_CTX_sess_accept(ssl_ctx)); -+ BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n", -+ SSL_CTX_sess_accept_renegotiate(ssl_ctx)); -+ BIO_printf(bio, "%4ld server accepts that finished\n", -+ SSL_CTX_sess_accept_good(ssl_ctx)); -+ BIO_printf(bio, "%4ld session cache hits\n", SSL_CTX_sess_hits(ssl_ctx)); -+ BIO_printf(bio, "%4ld session cache misses\n", -+ SSL_CTX_sess_misses(ssl_ctx)); -+ BIO_printf(bio, "%4ld session cache timeouts\n", -+ SSL_CTX_sess_timeouts(ssl_ctx)); -+ BIO_printf(bio, "%4ld callback cache hits\n", -+ SSL_CTX_sess_cb_hits(ssl_ctx)); -+ BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n", -+ SSL_CTX_sess_cache_full(ssl_ctx), -+ SSL_CTX_sess_get_cache_size(ssl_ctx)); -+} -+ -+static int sv_body(int s, int stype, unsigned char *context) -+{ -+ char *buf = NULL; -+ fd_set readfds; -+ int ret = 1, width; -+ int k, i; -+ unsigned long l; -+ SSL *con = NULL; -+ BIO *sbio; -+ struct timeval timeout; -+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) -+ struct timeval tv; -+#else -+ struct timeval *timeoutp; -+#endif -+ -+ buf = app_malloc(bufsize, "server buffer"); -+ if (s_nbio) { -+ if (!BIO_socket_nbio(s, 1)) -+ ERR_print_errors(bio_err); -+ else if (!s_quiet) -+ BIO_printf(bio_err, "Turned on non blocking io\n"); -+ } -+ -+ if (con == NULL) { -+ con = SSL_new(ctx); -+ -+ if (s_tlsextdebug) { -+ SSL_set_tlsext_debug_callback(con, tlsext_cb); -+ SSL_set_tlsext_debug_arg(con, bio_s_out); -+ } -+ -+ if (context -+ && !SSL_set_session_id_context(con, -+ context, strlen((char *)context))) { -+ BIO_printf(bio_err, "Error setting session id context\n"); -+ ret = -1; -+ goto err; -+ } -+ } -+ if (!SSL_clear(con)) { -+ BIO_printf(bio_err, "Error clearing SSL connection\n"); -+ ret = -1; -+ goto err; -+ } -+#ifndef OPENSSL_NO_DTLS -+ if (stype == SOCK_DGRAM) { -+ -+ sbio = BIO_new_dgram(s, BIO_NOCLOSE); -+ -+ if (enable_timeouts) { -+ timeout.tv_sec = 0; -+ timeout.tv_usec = DGRAM_RCV_TIMEOUT; -+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); -+ -+ timeout.tv_sec = 0; -+ timeout.tv_usec = DGRAM_SND_TIMEOUT; -+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); -+ } -+ -+ if (socket_mtu) { -+ if (socket_mtu < DTLS_get_link_min_mtu(con)) { -+ BIO_printf(bio_err, "MTU too small. Must be at least %ld\n", -+ DTLS_get_link_min_mtu(con)); -+ ret = -1; -+ BIO_free(sbio); -+ goto err; -+ } -+ SSL_set_options(con, SSL_OP_NO_QUERY_MTU); -+ if (!DTLS_set_link_mtu(con, socket_mtu)) { -+ BIO_printf(bio_err, "Failed to set MTU\n"); -+ ret = -1; -+ BIO_free(sbio); -+ goto err; -+ } -+ } else -+ /* want to do MTU discovery */ -+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); -+ -+ /* turn on cookie exchange */ -+ SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE); -+ } else -+#endif -+ sbio = BIO_new_socket(s, BIO_NOCLOSE); -+ -+ if (s_nbio_test) { -+ BIO *test; -+ -+ test = BIO_new(BIO_f_nbio_test()); -+ sbio = BIO_push(test, sbio); -+ } -+ -+ SSL_set_bio(con, sbio, sbio); -+ SSL_set_accept_state(con); -+ /* SSL_set_fd(con,s); */ -+ -+ if (s_debug) { -+ BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); -+ BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); -+ } -+ if (s_msg) { -+#ifndef OPENSSL_NO_SSL_TRACE -+ if (s_msg == 2) -+ SSL_set_msg_callback(con, SSL_trace); -+ else -+#endif -+ SSL_set_msg_callback(con, msg_cb); -+ SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out); -+ } -+ -+ if (s_tlsextdebug) { -+ SSL_set_tlsext_debug_callback(con, tlsext_cb); -+ SSL_set_tlsext_debug_arg(con, bio_s_out); -+ } -+ -+ if (fileno_stdin() > s) -+ width = fileno_stdin() + 1; -+ else -+ width = s + 1; -+ for (;;) { -+ int read_from_terminal; -+ int read_from_sslcon; -+ -+ read_from_terminal = 0; -+ read_from_sslcon = SSL_has_pending(con) -+ || (async && SSL_waiting_for_async(con)); -+ -+ if (!read_from_sslcon) { -+ FD_ZERO(&readfds); -+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) -+ openssl_fdset(fileno_stdin(), &readfds); -+#endif -+ openssl_fdset(s, &readfds); -+ /* -+ * Note: under VMS with SOCKETSHR the second parameter is -+ * currently of type (int *) whereas under other systems it is -+ * (void *) if you don't have a cast it will choke the compiler: -+ * if you do have a cast then you can either go for (int *) or -+ * (void *). -+ */ -+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) -+ /* -+ * Under DOS (non-djgpp) and Windows we can't select on stdin: -+ * only on sockets. As a workaround we timeout the select every -+ * second and check for any keypress. In a proper Windows -+ * application we wouldn't do this because it is inefficient. -+ */ -+ tv.tv_sec = 1; -+ tv.tv_usec = 0; -+ i = select(width, (void *)&readfds, NULL, NULL, &tv); -+ if (has_stdin_waiting()) -+ read_from_terminal = 1; -+ if ((i < 0) || (!i && !read_from_terminal)) -+ continue; -+#else -+ if ((SSL_version(con) == DTLS1_VERSION) && -+ DTLSv1_get_timeout(con, &timeout)) -+ timeoutp = &timeout; -+ else -+ timeoutp = NULL; -+ -+ i = select(width, (void *)&readfds, NULL, NULL, timeoutp); -+ -+ if ((SSL_version(con) == DTLS1_VERSION) -+ && DTLSv1_handle_timeout(con) > 0) { -+ BIO_printf(bio_err, "TIMEOUT occurred\n"); -+ } -+ -+ if (i <= 0) -+ continue; -+ if (FD_ISSET(fileno_stdin(), &readfds)) -+ read_from_terminal = 1; -+#endif -+ if (FD_ISSET(s, &readfds)) -+ read_from_sslcon = 1; -+ } -+ if (read_from_terminal) { -+ if (s_crlf) { -+ int j, lf_num; -+ -+ i = raw_read_stdin(buf, bufsize / 2); -+ lf_num = 0; -+ /* both loops are skipped when i <= 0 */ -+ for (j = 0; j < i; j++) -+ if (buf[j] == '\n') -+ lf_num++; -+ for (j = i - 1; j >= 0; j--) { -+ buf[j + lf_num] = buf[j]; -+ if (buf[j] == '\n') { -+ lf_num--; -+ i++; -+ buf[j + lf_num] = '\r'; -+ } -+ } -+ assert(lf_num == 0); -+ } else -+ i = raw_read_stdin(buf, bufsize); -+ -+ if (!s_quiet && !s_brief) { -+ if ((i <= 0) || (buf[0] == 'Q')) { -+ BIO_printf(bio_s_out, "DONE\n"); -+ (void)BIO_flush(bio_s_out); -+ BIO_closesocket(s); -+ close_accept_socket(); -+ ret = -11; -+ goto err; -+ } -+ if ((i <= 0) || (buf[0] == 'q')) { -+ BIO_printf(bio_s_out, "DONE\n"); -+ (void)BIO_flush(bio_s_out); -+ if (SSL_version(con) != DTLS1_VERSION) -+ BIO_closesocket(s); -+ /* -+ * close_accept_socket(); ret= -11; -+ */ -+ goto err; -+ } -+#ifndef OPENSSL_NO_HEARTBEATS -+ if ((buf[0] == 'B') && ((buf[1] == '\n') || (buf[1] == '\r'))) { -+ BIO_printf(bio_err, "HEARTBEATING\n"); -+ SSL_heartbeat(con); -+ i = 0; -+ continue; -+ } -+#endif -+ if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) { -+ SSL_renegotiate(con); -+ i = SSL_do_handshake(con); -+ printf("SSL_do_handshake -> %d\n", i); -+ i = 0; /* 13; */ -+ continue; -+ /* -+ * strcpy(buf,"server side RE-NEGOTIATE\n"); -+ */ -+ } -+ if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) { -+ SSL_set_verify(con, -+ SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, -+ NULL); -+ SSL_renegotiate(con); -+ i = SSL_do_handshake(con); -+ printf("SSL_do_handshake -> %d\n", i); -+ i = 0; /* 13; */ -+ continue; -+ /* -+ * strcpy(buf,"server side RE-NEGOTIATE asking for client -+ * cert\n"); -+ */ -+ } -+ if (buf[0] == 'P') { -+ static const char *str = "Lets print some clear text\n"; -+ BIO_write(SSL_get_wbio(con), str, strlen(str)); -+ } -+ if (buf[0] == 'S') { -+ print_stats(bio_s_out, SSL_get_SSL_CTX(con)); -+ } -+ } -+#ifdef CHARSET_EBCDIC -+ ebcdic2ascii(buf, buf, i); -+#endif -+ l = k = 0; -+ for (;;) { -+ /* should do a select for the write */ -+#ifdef RENEG -+ static count = 0; -+ if (++count == 100) { -+ count = 0; -+ SSL_renegotiate(con); -+ } -+#endif -+ k = SSL_write(con, &(buf[l]), (unsigned int)i); -+#ifndef OPENSSL_NO_SRP -+ while (SSL_get_error(con, k) == SSL_ERROR_WANT_X509_LOOKUP) { -+ BIO_printf(bio_s_out, "LOOKUP renego during write\n"); -+ SRP_user_pwd_free(srp_callback_parm.user); -+ srp_callback_parm.user = -+ SRP_VBASE_get1_by_user(srp_callback_parm.vb, -+ srp_callback_parm.login); -+ if (srp_callback_parm.user) -+ BIO_printf(bio_s_out, "LOOKUP done %s\n", -+ srp_callback_parm.user->info); -+ else -+ BIO_printf(bio_s_out, "LOOKUP not successful\n"); -+ k = SSL_write(con, &(buf[l]), (unsigned int)i); -+ } -+#endif -+ switch (SSL_get_error(con, k)) { -+ case SSL_ERROR_NONE: -+ break; -+ case SSL_ERROR_WANT_ASYNC: -+ BIO_printf(bio_s_out, "Write BLOCK (Async)\n"); -+ (void)BIO_flush(bio_s_out); -+ wait_for_async(con); -+ break; -+ case SSL_ERROR_WANT_WRITE: -+ case SSL_ERROR_WANT_READ: -+ case SSL_ERROR_WANT_X509_LOOKUP: -+ BIO_printf(bio_s_out, "Write BLOCK\n"); -+ (void)BIO_flush(bio_s_out); -+ break; -+ case SSL_ERROR_WANT_ASYNC_JOB: -+ /* -+ * This shouldn't ever happen in s_server. Treat as an error -+ */ -+ case SSL_ERROR_SYSCALL: -+ case SSL_ERROR_SSL: -+ BIO_printf(bio_s_out, "ERROR\n"); -+ (void)BIO_flush(bio_s_out); -+ ERR_print_errors(bio_err); -+ ret = 1; -+ goto err; -+ /* break; */ -+ case SSL_ERROR_ZERO_RETURN: -+ BIO_printf(bio_s_out, "DONE\n"); -+ (void)BIO_flush(bio_s_out); -+ ret = 1; -+ goto err; -+ } -+ if (k > 0) { -+ l += k; -+ i -= k; -+ } -+ if (i <= 0) -+ break; -+ } -+ } -+ if (read_from_sslcon) { -+ /* -+ * init_ssl_connection handles all async events itself so if we're -+ * waiting for async then we shouldn't go back into -+ * init_ssl_connection -+ */ -+ if ((!async || !SSL_waiting_for_async(con)) -+ && !SSL_is_init_finished(con)) { -+ i = init_ssl_connection(con); -+ -+ if (i < 0) { -+ ret = 0; -+ goto err; -+ } else if (i == 0) { -+ ret = 1; -+ goto err; -+ } -+ } else { -+ again: -+ i = SSL_read(con, (char *)buf, bufsize); -+#ifndef OPENSSL_NO_SRP -+ while (SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) { -+ BIO_printf(bio_s_out, "LOOKUP renego during read\n"); -+ SRP_user_pwd_free(srp_callback_parm.user); -+ srp_callback_parm.user = -+ SRP_VBASE_get1_by_user(srp_callback_parm.vb, -+ srp_callback_parm.login); -+ if (srp_callback_parm.user) -+ BIO_printf(bio_s_out, "LOOKUP done %s\n", -+ srp_callback_parm.user->info); -+ else -+ BIO_printf(bio_s_out, "LOOKUP not successful\n"); -+ i = SSL_read(con, (char *)buf, bufsize); -+ } -+#endif -+ switch (SSL_get_error(con, i)) { -+ case SSL_ERROR_NONE: -+#ifdef CHARSET_EBCDIC -+ ascii2ebcdic(buf, buf, i); -+#endif -+ raw_write_stdout(buf, (unsigned int)i); -+ (void)BIO_flush(bio_s_out); -+ if (SSL_has_pending(con)) -+ goto again; -+ break; -+ case SSL_ERROR_WANT_ASYNC: -+ BIO_printf(bio_s_out, "Read BLOCK (Async)\n"); -+ (void)BIO_flush(bio_s_out); -+ wait_for_async(con); -+ break; -+ case SSL_ERROR_WANT_WRITE: -+ case SSL_ERROR_WANT_READ: -+ BIO_printf(bio_s_out, "Read BLOCK\n"); -+ (void)BIO_flush(bio_s_out); -+ break; -+ case SSL_ERROR_WANT_ASYNC_JOB: -+ /* -+ * This shouldn't ever happen in s_server. Treat as an error -+ */ -+ case SSL_ERROR_SYSCALL: -+ case SSL_ERROR_SSL: -+ BIO_printf(bio_s_out, "ERROR\n"); -+ (void)BIO_flush(bio_s_out); -+ ERR_print_errors(bio_err); -+ ret = 1; -+ goto err; -+ case SSL_ERROR_ZERO_RETURN: -+ BIO_printf(bio_s_out, "DONE\n"); -+ (void)BIO_flush(bio_s_out); -+ ret = 1; -+ goto err; -+ } -+ } -+ } -+ } -+ err: -+ if (con != NULL) { -+ BIO_printf(bio_s_out, "shutting down SSL\n"); -+ SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); -+ SSL_free(con); -+ } -+ BIO_printf(bio_s_out, "CONNECTION CLOSED\n"); -+ OPENSSL_clear_free(buf, bufsize); -+ if (ret >= 0) -+ BIO_printf(bio_s_out, "ACCEPT\n"); -+ (void)BIO_flush(bio_s_out); -+ return (ret); -+} -+ -+static void close_accept_socket(void) -+{ -+ BIO_printf(bio_err, "shutdown accept socket\n"); -+ if (accept_socket >= 0) { -+ BIO_closesocket(accept_socket); -+ } -+} -+ -+static int init_ssl_connection(SSL *con) -+{ -+ int i; -+ const char *str; -+ X509 *peer; -+ long verify_err; -+ char buf[BUFSIZ]; -+#if !defined(OPENSSL_NO_NEXTPROTONEG) -+ const unsigned char *next_proto_neg; -+ unsigned next_proto_neg_len; -+#endif -+ unsigned char *exportedkeymat; -+ int retry = 0; -+ -+#ifndef OPENSSL_NO_DTLS -+ if (dtlslisten) { -+ BIO_ADDR *client = NULL; -+ -+ if ((client = BIO_ADDR_new()) == NULL) { -+ BIO_printf(bio_err, "ERROR - memory\n"); -+ return 0; -+ } -+ i = DTLSv1_listen(con, client); -+ if (i > 0) { -+ BIO *wbio; -+ int fd = -1; -+ -+ wbio = SSL_get_wbio(con); -+ if (wbio) { -+ BIO_get_fd(wbio, &fd); -+ } -+ -+ if (!wbio || BIO_connect(fd, client, 0) == 0) { -+ BIO_printf(bio_err, "ERROR - unable to connect\n"); -+ BIO_ADDR_free(client); -+ return 0; -+ } -+ BIO_ADDR_free(client); -+ dtlslisten = 0; -+ i = SSL_accept(con); -+ } else { -+ BIO_ADDR_free(client); -+ } -+ } else -+#endif -+ -+ do { -+ i = SSL_accept(con); -+ -+ if (i <= 0) -+ retry = BIO_sock_should_retry(i); -+#ifdef CERT_CB_TEST_RETRY -+ { -+ while (i <= 0 -+ && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP -+ && SSL_get_state(con) == TLS_ST_SR_CLNT_HELLO) { -+ BIO_printf(bio_err, -+ "LOOKUP from certificate callback during accept\n"); -+ i = SSL_accept(con); -+ if (i <= 0) -+ retry = BIO_sock_should_retry(i); -+ } -+ } -+#endif -+ -+#ifndef OPENSSL_NO_SRP -+ while (i <= 0 -+ && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) { -+ BIO_printf(bio_s_out, "LOOKUP during accept %s\n", -+ srp_callback_parm.login); -+ SRP_user_pwd_free(srp_callback_parm.user); -+ srp_callback_parm.user = -+ SRP_VBASE_get1_by_user(srp_callback_parm.vb, -+ srp_callback_parm.login); -+ if (srp_callback_parm.user) -+ BIO_printf(bio_s_out, "LOOKUP done %s\n", -+ srp_callback_parm.user->info); -+ else -+ BIO_printf(bio_s_out, "LOOKUP not successful\n"); -+ i = SSL_accept(con); -+ if (i <= 0) -+ retry = BIO_sock_should_retry(i); -+ } -+#endif -+ } while (i < 0 && SSL_waiting_for_async(con)); -+ -+ if (i <= 0) { -+ if ((dtlslisten && i == 0) -+ || (!dtlslisten && retry)) { -+ BIO_printf(bio_s_out, "DELAY\n"); -+ return (1); -+ } -+ -+ BIO_printf(bio_err, "ERROR\n"); -+ -+ verify_err = SSL_get_verify_result(con); -+ if (verify_err != X509_V_OK) { -+ BIO_printf(bio_err, "verify error:%s\n", -+ X509_verify_cert_error_string(verify_err)); -+ } -+ /* Always print any error messages */ -+ ERR_print_errors(bio_err); -+ return (0); -+ } -+ -+ if (s_brief) -+ print_ssl_summary(con); -+ -+ PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con)); -+ -+ peer = SSL_get_peer_certificate(con); -+ if (peer != NULL) { -+ BIO_printf(bio_s_out, "Client certificate\n"); -+ PEM_write_bio_X509(bio_s_out, peer); -+ X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf); -+ BIO_printf(bio_s_out, "subject=%s\n", buf); -+ X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf); -+ BIO_printf(bio_s_out, "issuer=%s\n", buf); -+ X509_free(peer); -+ peer = NULL; -+ } -+ -+ if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL) -+ BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf); -+ str = SSL_CIPHER_get_name(SSL_get_current_cipher(con)); -+ ssl_print_sigalgs(bio_s_out, con); -+#ifndef OPENSSL_NO_EC -+ ssl_print_point_formats(bio_s_out, con); -+ ssl_print_curves(bio_s_out, con, 0); -+#endif -+ BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)"); -+ -+#if !defined(OPENSSL_NO_NEXTPROTONEG) -+ SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len); -+ if (next_proto_neg) { -+ BIO_printf(bio_s_out, "NEXTPROTO is "); -+ BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len); -+ BIO_printf(bio_s_out, "\n"); -+ } -+#endif -+#ifndef OPENSSL_NO_SRTP -+ { -+ SRTP_PROTECTION_PROFILE *srtp_profile -+ = SSL_get_selected_srtp_profile(con); -+ -+ if (srtp_profile) -+ BIO_printf(bio_s_out, "SRTP Extension negotiated, profile=%s\n", -+ srtp_profile->name); -+ } -+#endif -+ if (SSL_session_reused(con)) -+ BIO_printf(bio_s_out, "Reused session-id\n"); -+ BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n", -+ SSL_get_secure_renegotiation_support(con) ? "" : " NOT"); -+ if (keymatexportlabel != NULL) { -+ BIO_printf(bio_s_out, "Keying material exporter:\n"); -+ BIO_printf(bio_s_out, " Label: '%s'\n", keymatexportlabel); -+ BIO_printf(bio_s_out, " Length: %i bytes\n", keymatexportlen); -+ exportedkeymat = app_malloc(keymatexportlen, "export key"); -+ if (!SSL_export_keying_material(con, exportedkeymat, -+ keymatexportlen, -+ keymatexportlabel, -+ strlen(keymatexportlabel), -+ NULL, 0, 0)) { -+ BIO_printf(bio_s_out, " Error\n"); -+ } else { -+ BIO_printf(bio_s_out, " Keying material: "); -+ for (i = 0; i < keymatexportlen; i++) -+ BIO_printf(bio_s_out, "%02X", exportedkeymat[i]); -+ BIO_printf(bio_s_out, "\n"); -+ } -+ OPENSSL_free(exportedkeymat); -+ } -+ -+ (void)BIO_flush(bio_s_out); -+ return (1); -+} -+ -+#ifndef OPENSSL_NO_DH -+static DH *load_dh_param(const char *dhfile) -+{ -+ DH *ret = NULL; -+ BIO *bio; -+ -+ if ((bio = BIO_new_file(dhfile, "r")) == NULL) -+ goto err; -+ ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); -+ err: -+ BIO_free(bio); -+ return (ret); -+} -+#endif -+ -+static int www_body(int s, int stype, unsigned char *context) -+{ -+ char *buf = NULL; -+ int ret = 1; -+ int i, j, k, dot; -+ SSL *con; -+ const SSL_CIPHER *c; -+ BIO *io, *ssl_bio, *sbio; -+#ifdef RENEG -+ int total_bytes = 0; -+#endif -+ int width; -+ fd_set readfds; -+ -+ /* Set width for a select call if needed */ -+ width = s + 1; -+ -+ buf = app_malloc(bufsize, "server www buffer"); -+ io = BIO_new(BIO_f_buffer()); -+ ssl_bio = BIO_new(BIO_f_ssl()); -+ if ((io == NULL) || (ssl_bio == NULL)) -+ goto err; -+ -+ if (s_nbio) { -+ if (!BIO_socket_nbio(s, 1)) -+ ERR_print_errors(bio_err); -+ else if (!s_quiet) -+ BIO_printf(bio_err, "Turned on non blocking io\n"); -+ } -+ -+ /* lets make the output buffer a reasonable size */ -+ if (!BIO_set_write_buffer_size(io, bufsize)) -+ goto err; -+ -+ if ((con = SSL_new(ctx)) == NULL) -+ goto err; -+ -+ if (s_tlsextdebug) { -+ SSL_set_tlsext_debug_callback(con, tlsext_cb); -+ SSL_set_tlsext_debug_arg(con, bio_s_out); -+ } -+ -+ if (context -+ && !SSL_set_session_id_context(con, context, -+ strlen((char *)context))) -+ goto err; -+ -+ sbio = BIO_new_socket(s, BIO_NOCLOSE); -+ if (s_nbio_test) { -+ BIO *test; -+ -+ test = BIO_new(BIO_f_nbio_test()); -+ sbio = BIO_push(test, sbio); -+ } -+ SSL_set_bio(con, sbio, sbio); -+ SSL_set_accept_state(con); -+ -+ /* SSL_set_fd(con,s); */ -+ BIO_set_ssl(ssl_bio, con, BIO_CLOSE); -+ BIO_push(io, ssl_bio); -+#ifdef CHARSET_EBCDIC -+ io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io); -+#endif -+ -+ if (s_debug) { -+ BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); -+ BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); -+ } -+ if (s_msg) { -+#ifndef OPENSSL_NO_SSL_TRACE -+ if (s_msg == 2) -+ SSL_set_msg_callback(con, SSL_trace); -+ else -+#endif -+ SSL_set_msg_callback(con, msg_cb); -+ SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out); -+ } -+ -+ for (;;) { -+ i = BIO_gets(io, buf, bufsize - 1); -+ if (i < 0) { /* error */ -+ if (!BIO_should_retry(io) && !SSL_waiting_for_async(con)) { -+ if (!s_quiet) -+ ERR_print_errors(bio_err); -+ goto err; -+ } else { -+ BIO_printf(bio_s_out, "read R BLOCK\n"); -+#ifndef OPENSSL_NO_SRP -+ if (BIO_should_io_special(io) -+ && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) { -+ BIO_printf(bio_s_out, "LOOKUP renego during read\n"); -+ SRP_user_pwd_free(srp_callback_parm.user); -+ srp_callback_parm.user = -+ SRP_VBASE_get1_by_user(srp_callback_parm.vb, -+ srp_callback_parm.login); -+ if (srp_callback_parm.user) -+ BIO_printf(bio_s_out, "LOOKUP done %s\n", -+ srp_callback_parm.user->info); -+ else -+ BIO_printf(bio_s_out, "LOOKUP not successful\n"); -+ continue; -+ } -+#endif -+#if !defined(OPENSSL_SYS_MSDOS) -+ sleep(1); -+#endif -+ continue; -+ } -+ } else if (i == 0) { /* end of input */ -+ ret = 1; -+ goto end; -+ } -+ -+ /* else we have data */ -+ if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) || -+ ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) { -+ char *p; -+ X509 *peer = NULL; -+ STACK_OF(SSL_CIPHER) *sk; -+ static const char *space = " "; -+ -+ if (www == 1 && strncmp("GET /reneg", buf, 10) == 0) { -+ if (strncmp("GET /renegcert", buf, 14) == 0) -+ SSL_set_verify(con, -+ SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, -+ NULL); -+ i = SSL_renegotiate(con); -+ BIO_printf(bio_s_out, "SSL_renegotiate -> %d\n", i); -+ /* Send the HelloRequest */ -+ i = SSL_do_handshake(con); -+ if (i <= 0) { -+ BIO_printf(bio_s_out, "SSL_do_handshake() Retval %d\n", -+ SSL_get_error(con, i)); -+ ERR_print_errors(bio_err); -+ goto err; -+ } -+ /* Wait for a ClientHello to come back */ -+ FD_ZERO(&readfds); -+ openssl_fdset(s, &readfds); -+ i = select(width, (void *)&readfds, NULL, NULL, NULL); -+ if (i <= 0 || !FD_ISSET(s, &readfds)) { -+ BIO_printf(bio_s_out, -+ "Error waiting for client response\n"); -+ ERR_print_errors(bio_err); -+ goto err; -+ } -+ /* -+ * We're not actually expecting any data here and we ignore -+ * any that is sent. This is just to force the handshake that -+ * we're expecting to come from the client. If they haven't -+ * sent one there's not much we can do. -+ */ -+ BIO_gets(io, buf, bufsize - 1); -+ } -+ -+ BIO_puts(io, -+ "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); -+ BIO_puts(io, "\n"); -+ BIO_puts(io, "
\n");
-+            /* BIO_puts(io, OpenSSL_version(OPENSSL_VERSION)); */
-+            BIO_puts(io, "\n");
-+            for (i = 0; i < local_argc; i++) {
-+                const char *myp;
-+                for (myp = local_argv[i]; *myp; myp++)
-+                    switch (*myp) {
-+                    case '<':
-+                        BIO_puts(io, "<");
-+                        break;
-+                    case '>':
-+                        BIO_puts(io, ">");
-+                        break;
-+                    case '&':
-+                        BIO_puts(io, "&");
-+                        break;
-+                    default:
-+                        BIO_write(io, myp, 1);
-+                        break;
-+                    }
-+                BIO_write(io, " ", 1);
-+            }
-+            BIO_puts(io, "\n");
-+
-+            BIO_printf(io,
-+                       "Secure Renegotiation IS%s supported\n",
-+                       SSL_get_secure_renegotiation_support(con) ?
-+                       "" : " NOT");
-+
-+            /*
-+             * The following is evil and should not really be done
-+             */
-+            BIO_printf(io, "Ciphers supported in s_server binary\n");
-+            sk = SSL_get_ciphers(con);
-+            j = sk_SSL_CIPHER_num(sk);
-+            for (i = 0; i < j; i++) {
-+                c = sk_SSL_CIPHER_value(sk, i);
-+                BIO_printf(io, "%-11s:%-25s ",
-+                           SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
-+                if ((((i + 1) % 2) == 0) && (i + 1 != j))
-+                    BIO_puts(io, "\n");
-+            }
-+            BIO_puts(io, "\n");
-+            p = SSL_get_shared_ciphers(con, buf, bufsize);
-+            if (p != NULL) {
-+                BIO_printf(io,
-+                           "---\nCiphers common between both SSL end points:\n");
-+                j = i = 0;
-+                while (*p) {
-+                    if (*p == ':') {
-+                        BIO_write(io, space, 26 - j);
-+                        i++;
-+                        j = 0;
-+                        BIO_write(io, ((i % 3) ? " " : "\n"), 1);
-+                    } else {
-+                        BIO_write(io, p, 1);
-+                        j++;
-+                    }
-+                    p++;
-+                }
-+                BIO_puts(io, "\n");
-+            }
-+            ssl_print_sigalgs(io, con);
-+#ifndef OPENSSL_NO_EC
-+            ssl_print_curves(io, con, 0);
-+#endif
-+            BIO_printf(io, (SSL_session_reused(con)
-+                            ? "---\nReused, " : "---\nNew, "));
-+            c = SSL_get_current_cipher(con);
-+            BIO_printf(io, "%s, Cipher is %s\n",
-+                       SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
-+            SSL_SESSION_print(io, SSL_get_session(con));
-+            BIO_printf(io, "---\n");
-+            print_stats(io, SSL_get_SSL_CTX(con));
-+            BIO_printf(io, "---\n");
-+            peer = SSL_get_peer_certificate(con);
-+            if (peer != NULL) {
-+                BIO_printf(io, "Client certificate\n");
-+                X509_print(io, peer);
-+                PEM_write_bio_X509(io, peer);
-+                X509_free(peer);
-+                peer = NULL;
-+            } else
-+                BIO_puts(io, "no client certificate available\n");
-+            BIO_puts(io, "\r\n\r\n");
-+            break;
-+        } else if ((www == 2 || www == 3)
-+                   && (strncmp("GET /", buf, 5) == 0)) {
-+            BIO *file;
-+            char *p, *e;
-+            static const char *text =
-+                "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
-+
-+            /* skip the '/' */
-+            p = &(buf[5]);
-+
-+            dot = 1;
-+            for (e = p; *e != '\0'; e++) {
-+                if (e[0] == ' ')
-+                    break;
-+
-+                switch (dot) {
-+                case 1:
-+                    dot = (e[0] == '.') ? 2 : 0;
-+                    break;
-+                case 2:
-+                    dot = (e[0] == '.') ? 3 : 0;
-+                    break;
-+                case 3:
-+                    dot = (e[0] == '/') ? -1 : 0;
-+                    break;
-+                }
-+                if (dot == 0)
-+                    dot = (e[0] == '/') ? 1 : 0;
-+            }
-+            dot = (dot == 3) || (dot == -1); /* filename contains ".."
-+                                              * component */
-+
-+            if (*e == '\0') {
-+                BIO_puts(io, text);
-+                BIO_printf(io, "'%s' is an invalid file name\r\n", p);
-+                break;
-+            }
-+            *e = '\0';
-+
-+            if (dot) {
-+                BIO_puts(io, text);
-+                BIO_printf(io, "'%s' contains '..' reference\r\n", p);
-+                break;
-+            }
-+
-+            if (*p == '/') {
-+                BIO_puts(io, text);
-+                BIO_printf(io, "'%s' is an invalid path\r\n", p);
-+                break;
-+            }
-+
-+            /* if a directory, do the index thang */
-+            if (app_isdir(p) > 0) {
-+                BIO_puts(io, text);
-+                BIO_printf(io, "'%s' is a directory\r\n", p);
-+                break;
-+            }
-+
-+            if ((file = BIO_new_file(p, "r")) == NULL) {
-+                BIO_puts(io, text);
-+                BIO_printf(io, "Error opening '%s'\r\n", p);
-+                ERR_print_errors(io);
-+                break;
-+            }
-+
-+            if (!s_quiet)
-+                BIO_printf(bio_err, "FILE:%s\n", p);
-+
-+            if (www == 2) {
-+                i = strlen(p);
-+                if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) ||
-+                    ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) ||
-+                    ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0)))
-+                    BIO_puts(io,
-+                             "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
-+                else
-+                    BIO_puts(io,
-+                             "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
-+            }
-+            /* send the file */
-+            for (;;) {
-+                i = BIO_read(file, buf, bufsize);
-+                if (i <= 0)
-+                    break;
-+
-+#ifdef RENEG
-+                total_bytes += i;
-+                BIO_printf(bio_err, "%d\n", i);
-+                if (total_bytes > 3 * 1024) {
-+                    total_bytes = 0;
-+                    BIO_printf(bio_err, "RENEGOTIATE\n");
-+                    SSL_renegotiate(con);
-+                }
-+#endif
-+
-+                for (j = 0; j < i;) {
-+#ifdef RENEG
-+                    static count = 0;
-+                    if (++count == 13) {
-+                        SSL_renegotiate(con);
-+                    }
-+#endif
-+                    k = BIO_write(io, &(buf[j]), i - j);
-+                    if (k <= 0) {
-+                        if (!BIO_should_retry(io)
-+                            && !SSL_waiting_for_async(con))
-+                            goto write_error;
-+                        else {
-+                            BIO_printf(bio_s_out, "rwrite W BLOCK\n");
-+                        }
-+                    } else {
-+                        j += k;
-+                    }
-+                }
-+            }
-+ write_error:
-+            BIO_free(file);
-+            break;
-+        }
-+    }
-+
-+    for (;;) {
-+        i = (int)BIO_flush(io);
-+        if (i <= 0) {
-+            if (!BIO_should_retry(io))
-+                break;
-+        } else
-+            break;
-+    }
-+ end:
-+    /* make sure we re-use sessions */
-+    SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
-+
-+ err:
-+    if (ret >= 0)
-+        BIO_printf(bio_s_out, "ACCEPT\n");
-+    OPENSSL_free(buf);
-+    BIO_free_all(io);
-+    return (ret);
-+}
-+
-+static int rev_body(int s, int stype, unsigned char *context)
-+{
-+    char *buf = NULL;
-+    int i;
-+    int ret = 1;
-+    SSL *con;
-+    BIO *io, *ssl_bio, *sbio;
-+
-+    buf = app_malloc(bufsize, "server rev buffer");
-+    io = BIO_new(BIO_f_buffer());
-+    ssl_bio = BIO_new(BIO_f_ssl());
-+    if ((io == NULL) || (ssl_bio == NULL))
-+        goto err;
-+
-+    /* lets make the output buffer a reasonable size */
-+    if (!BIO_set_write_buffer_size(io, bufsize))
-+        goto err;
-+
-+    if ((con = SSL_new(ctx)) == NULL)
-+        goto err;
-+
-+    if (s_tlsextdebug) {
-+        SSL_set_tlsext_debug_callback(con, tlsext_cb);
-+        SSL_set_tlsext_debug_arg(con, bio_s_out);
-+    }
-+    if (context
-+        && !SSL_set_session_id_context(con, context,
-+                                       strlen((char *)context))) {
-+        ERR_print_errors(bio_err);
-+        goto err;
-+    }
-+
-+    sbio = BIO_new_socket(s, BIO_NOCLOSE);
-+    SSL_set_bio(con, sbio, sbio);
-+    SSL_set_accept_state(con);
-+
-+    BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
-+    BIO_push(io, ssl_bio);
-+#ifdef CHARSET_EBCDIC
-+    io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io);
-+#endif
-+
-+    if (s_debug) {
-+        BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
-+        BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
-+    }
-+    if (s_msg) {
-+#ifndef OPENSSL_NO_SSL_TRACE
-+        if (s_msg == 2)
-+            SSL_set_msg_callback(con, SSL_trace);
-+        else
-+#endif
-+            SSL_set_msg_callback(con, msg_cb);
-+        SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
-+    }
-+
-+    for (;;) {
-+        i = BIO_do_handshake(io);
-+        if (i > 0)
-+            break;
-+        if (!BIO_should_retry(io)) {
-+            BIO_puts(bio_err, "CONNECTION FAILURE\n");
-+            ERR_print_errors(bio_err);
-+            goto end;
-+        }
-+#ifndef OPENSSL_NO_SRP
-+        if (BIO_should_io_special(io)
-+            && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) {
-+            BIO_printf(bio_s_out, "LOOKUP renego during accept\n");
-+            SRP_user_pwd_free(srp_callback_parm.user);
-+            srp_callback_parm.user =
-+                SRP_VBASE_get1_by_user(srp_callback_parm.vb,
-+                                       srp_callback_parm.login);
-+            if (srp_callback_parm.user)
-+                BIO_printf(bio_s_out, "LOOKUP done %s\n",
-+                           srp_callback_parm.user->info);
-+            else
-+                BIO_printf(bio_s_out, "LOOKUP not successful\n");
-+            continue;
-+        }
-+#endif
-+    }
-+    BIO_printf(bio_err, "CONNECTION ESTABLISHED\n");
-+    print_ssl_summary(con);
-+
-+    for (;;) {
-+        i = BIO_gets(io, buf, bufsize - 1);
-+        if (i < 0) {            /* error */
-+            if (!BIO_should_retry(io)) {
-+                if (!s_quiet)
-+                    ERR_print_errors(bio_err);
-+                goto err;
-+            } else {
-+                BIO_printf(bio_s_out, "read R BLOCK\n");
-+#ifndef OPENSSL_NO_SRP
-+                if (BIO_should_io_special(io)
-+                    && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) {
-+                    BIO_printf(bio_s_out, "LOOKUP renego during read\n");
-+                    SRP_user_pwd_free(srp_callback_parm.user);
-+                    srp_callback_parm.user =
-+                        SRP_VBASE_get1_by_user(srp_callback_parm.vb,
-+                                               srp_callback_parm.login);
-+                    if (srp_callback_parm.user)
-+                        BIO_printf(bio_s_out, "LOOKUP done %s\n",
-+                                   srp_callback_parm.user->info);
-+                    else
-+                        BIO_printf(bio_s_out, "LOOKUP not successful\n");
-+                    continue;
-+                }
-+#endif
-+#if !defined(OPENSSL_SYS_MSDOS)
-+                sleep(1);
-+#endif
-+                continue;
-+            }
-+        } else if (i == 0) {    /* end of input */
-+            ret = 1;
-+            BIO_printf(bio_err, "CONNECTION CLOSED\n");
-+            goto end;
-+        } else {
-+            char *p = buf + i - 1;
-+            while (i && (*p == '\n' || *p == '\r')) {
-+                p--;
-+                i--;
-+            }
-+            if (!s_ign_eof && (i == 5) && (strncmp(buf, "CLOSE", 5) == 0)) {
-+                ret = 1;
-+                BIO_printf(bio_err, "CONNECTION CLOSED\n");
-+                goto end;
-+            }
-+            BUF_reverse((unsigned char *)buf, NULL, i);
-+            buf[i] = '\n';
-+            BIO_write(io, buf, i + 1);
-+            for (;;) {
-+                i = BIO_flush(io);
-+                if (i > 0)
-+                    break;
-+                if (!BIO_should_retry(io))
-+                    goto end;
-+            }
-+        }
-+    }
-+ end:
-+    /* make sure we re-use sessions */
-+    SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
-+
-+ err:
-+
-+    OPENSSL_free(buf);
-+    BIO_free_all(io);
-+    return (ret);
-+}
-+
-+#define MAX_SESSION_ID_ATTEMPTS 10
-+static int generate_session_id(const SSL *ssl, unsigned char *id,
-+                               unsigned int *id_len)
-+{
-+    unsigned int count = 0;
-+    do {
-+        if (RAND_bytes(id, *id_len) <= 0)
-+            return 0;
-+        /*
-+         * Prefix the session_id with the required prefix. NB: If our prefix
-+         * is too long, clip it - but there will be worse effects anyway, eg.
-+         * the server could only possibly create 1 session ID (ie. the
-+         * prefix!) so all future session negotiations will fail due to
-+         * conflicts.
-+         */
-+        memcpy(id, session_id_prefix,
-+               (strlen(session_id_prefix) < *id_len) ?
-+               strlen(session_id_prefix) : *id_len);
-+    }
-+    while (SSL_has_matching_session_id(ssl, id, *id_len) &&
-+           (++count < MAX_SESSION_ID_ATTEMPTS));
-+    if (count >= MAX_SESSION_ID_ATTEMPTS)
-+        return 0;
-+    return 1;
-+}
-+
-+/*
-+ * By default s_server uses an in-memory cache which caches SSL_SESSION
-+ * structures without any serialisation. This hides some bugs which only
-+ * become apparent in deployed servers. By implementing a basic external
-+ * session cache some issues can be debugged using s_server.
-+ */
-+
-+typedef struct simple_ssl_session_st {
-+    unsigned char *id;
-+    unsigned int idlen;
-+    unsigned char *der;
-+    int derlen;
-+    struct simple_ssl_session_st *next;
-+} simple_ssl_session;
-+
-+static simple_ssl_session *first = NULL;
-+
-+static int add_session(SSL *ssl, SSL_SESSION *session)
-+{
-+    simple_ssl_session *sess = app_malloc(sizeof(*sess), "get session");
-+    unsigned char *p;
-+
-+    SSL_SESSION_get_id(session, &sess->idlen);
-+    sess->derlen = i2d_SSL_SESSION(session, NULL);
-+    if (sess->derlen < 0) {
-+        BIO_printf(bio_err, "Error encoding session\n");
-+        OPENSSL_free(sess);
-+        return 0;
-+    }
-+
-+    sess->id = OPENSSL_memdup(SSL_SESSION_get_id(session, NULL), sess->idlen);
-+    sess->der = app_malloc(sess->derlen, "get session buffer");
-+    if (!sess->id) {
-+        BIO_printf(bio_err, "Out of memory adding to external cache\n");
-+        OPENSSL_free(sess->id);
-+        OPENSSL_free(sess->der);
-+        OPENSSL_free(sess);
-+        return 0;
-+    }
-+    p = sess->der;
-+
-+    /* Assume it still works. */
-+    if (i2d_SSL_SESSION(session, &p) != sess->derlen) {
-+        BIO_printf(bio_err, "Unexpected session encoding length\n");
-+        OPENSSL_free(sess->id);
-+        OPENSSL_free(sess->der);
-+        OPENSSL_free(sess);
-+        return 0;
-+    }
-+
-+    sess->next = first;
-+    first = sess;
-+    BIO_printf(bio_err, "New session added to external cache\n");
-+    return 0;
-+}
-+
-+static SSL_SESSION *get_session(SSL *ssl, const unsigned char *id, int idlen,
-+                                int *do_copy)
-+{
-+    simple_ssl_session *sess;
-+    *do_copy = 0;
-+    for (sess = first; sess; sess = sess->next) {
-+        if (idlen == (int)sess->idlen && !memcmp(sess->id, id, idlen)) {
-+            const unsigned char *p = sess->der;
-+            BIO_printf(bio_err, "Lookup session: cache hit\n");
-+            return d2i_SSL_SESSION(NULL, &p, sess->derlen);
-+        }
-+    }
-+    BIO_printf(bio_err, "Lookup session: cache miss\n");
-+    return NULL;
-+}
-+
-+static void del_session(SSL_CTX *sctx, SSL_SESSION *session)
-+{
-+    simple_ssl_session *sess, *prev = NULL;
-+    const unsigned char *id;
-+    unsigned int idlen;
-+    id = SSL_SESSION_get_id(session, &idlen);
-+    for (sess = first; sess; sess = sess->next) {
-+        if (idlen == sess->idlen && !memcmp(sess->id, id, idlen)) {
-+            if (prev)
-+                prev->next = sess->next;
-+            else
-+                first = sess->next;
-+            OPENSSL_free(sess->id);
-+            OPENSSL_free(sess->der);
-+            OPENSSL_free(sess);
-+            return;
-+        }
-+        prev = sess;
-+    }
-+}
-+
-+static void init_session_cache_ctx(SSL_CTX *sctx)
-+{
-+    SSL_CTX_set_session_cache_mode(sctx,
-+                                   SSL_SESS_CACHE_NO_INTERNAL |
-+                                   SSL_SESS_CACHE_SERVER);
-+    SSL_CTX_sess_set_new_cb(sctx, add_session);
-+    SSL_CTX_sess_set_get_cb(sctx, get_session);
-+    SSL_CTX_sess_set_remove_cb(sctx, del_session);
-+}
-+
-+static void free_sessions(void)
-+{
-+    simple_ssl_session *sess, *tsess;
-+    for (sess = first; sess;) {
-+        OPENSSL_free(sess->id);
-+        OPENSSL_free(sess->der);
-+        tsess = sess;
-+        sess = sess->next;
-+        OPENSSL_free(tsess);
-+    }
-+    first = NULL;
-+}
-+
-+#endif                          /* OPENSSL_NO_SOCK */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/s_socket.c b/CryptoPkg/Library/OpensslLib/openssl/apps/s_socket.c
-new file mode 100644
-index 0000000..d16f5ad
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/s_socket.c
-@@ -0,0 +1,201 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* socket-related functions used by s_client and s_server */
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+/*
-+ * With IPv6, it looks like Digital has mixed up the proper order of
-+ * recursive header file inclusion, resulting in the compiler complaining
-+ * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
-+ * needed to have fileno() declared correctly...  So let's define u_int
-+ */
-+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
-+# define __U_INT
-+typedef unsigned int u_int;
-+#endif
-+
-+#ifndef OPENSSL_NO_SOCK
-+
-+# define USE_SOCKETS
-+# include "apps.h"
-+# undef USE_SOCKETS
-+# include "s_apps.h"
-+
-+# include 
-+# include 
-+
-+/*
-+ * init_client - helper routine to set up socket communication
-+ * @sock: pointer to storage of resulting socket.
-+ * @host: the host name or path (for AF_UNIX) to connect to.
-+ * @port: the port to connect to (ignored for AF_UNIX).
-+ * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
-+ *  AF_UNSPEC
-+ * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
-+ *
-+ * This will create a socket and use it to connect to a host:port, or if
-+ * family == AF_UNIX, to the path found in host.
-+ *
-+ * If the host has more than one address, it will try them one by one until
-+ * a successful connection is established.  The resulting socket will be
-+ * found in *sock on success, it will be given INVALID_SOCKET otherwise.
-+ *
-+ * Returns 1 on success, 0 on failure.
-+ */
-+int init_client(int *sock, const char *host, const char *port,
-+                int family, int type)
-+{
-+    BIO_ADDRINFO *res = NULL;
-+    const BIO_ADDRINFO *ai = NULL;
-+    int ret;
-+
-+    if (!BIO_sock_init())
-+        return 0;
-+
-+    ret = BIO_lookup(host, port, BIO_LOOKUP_CLIENT, family, type, &res);
-+    if (ret == 0) {
-+        ERR_print_errors(bio_err);
-+        return 0;
-+    }
-+
-+    ret = 0;
-+    for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
-+        /* Admittedly, these checks are quite paranoid, we should not get
-+         * anything in the BIO_ADDRINFO chain that we haven't
-+         * asked for. */
-+        OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
-+                       && (type == 0 || type == BIO_ADDRINFO_socktype(res)));
-+
-+        *sock = BIO_socket(BIO_ADDRINFO_family(ai), BIO_ADDRINFO_socktype(ai),
-+                           BIO_ADDRINFO_protocol(res), 0);
-+        if (*sock == INVALID_SOCKET) {
-+            /* Maybe the kernel doesn't support the socket family, even if
-+             * BIO_lookup() added it in the returned result...
-+             */
-+            continue;
-+        }
-+        if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai), 0)) {
-+            BIO_closesocket(*sock);
-+            *sock = INVALID_SOCKET;
-+            continue;
-+        }
-+
-+        /* Success, don't try any more addresses */
-+        break;
-+    }
-+
-+    if (*sock == INVALID_SOCKET) {
-+        ERR_print_errors(bio_err);
-+    } else {
-+        /* Remove any stale errors from previous connection attempts */
-+        ERR_clear_error();
-+        ret = 1;
-+    }
-+    BIO_ADDRINFO_free(res);
-+    return ret;
-+}
-+
-+/*
-+ * do_server - helper routine to perform a server operation
-+ * @accept_sock: pointer to storage of resulting socket.
-+ * @host: the host name or path (for AF_UNIX) to connect to.
-+ * @port: the port to connect to (ignored for AF_UNIX).
-+ * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
-+ *  AF_UNSPEC
-+ * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
-+ * @cb: pointer to a function that receives the accepted socket and
-+ *  should perform the communication with the connecting client.
-+ * @context: pointer to memory that's passed verbatim to the cb function.
-+ * @naccept: number of times an incoming connect should be accepted.  If -1,
-+ *  unlimited number.
-+ *
-+ * This will create a socket and use it to listen to a host:port, or if
-+ * family == AF_UNIX, to the path found in host, then start accepting
-+ * incoming connections and run cb on the resulting socket.
-+ *
-+ * 0 on failure, something other on success.
-+ */
-+int do_server(int *accept_sock, const char *host, const char *port,
-+              int family, int type, do_server_cb cb,
-+              unsigned char *context, int naccept)
-+{
-+    int asock = 0;
-+    int sock;
-+    int i;
-+    BIO_ADDRINFO *res = NULL;
-+    int ret = 0;
-+
-+    if (!BIO_sock_init())
-+        return 0;
-+
-+    if (!BIO_lookup(host, port, BIO_LOOKUP_SERVER, family, type, &res)) {
-+        ERR_print_errors(bio_err);
-+        return 0;
-+    }
-+
-+    /* Admittedly, these checks are quite paranoid, we should not get
-+     * anything in the BIO_ADDRINFO chain that we haven't asked for */
-+    OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
-+                   && (type == 0 || type == BIO_ADDRINFO_socktype(res)));
-+
-+    asock = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
-+                       BIO_ADDRINFO_protocol(res), 0);
-+    if (asock == INVALID_SOCKET
-+        || !BIO_listen(asock, BIO_ADDRINFO_address(res), BIO_SOCK_REUSEADDR)) {
-+        BIO_ADDRINFO_free(res);
-+        ERR_print_errors(bio_err);
-+        if (asock != INVALID_SOCKET)
-+            BIO_closesocket(asock);
-+        goto end;
-+    }
-+
-+    BIO_ADDRINFO_free(res);
-+    res = NULL;
-+
-+    if (accept_sock != NULL)
-+        *accept_sock = asock;
-+    for (;;) {
-+        if (type == SOCK_STREAM) {
-+            do {
-+                sock = BIO_accept_ex(asock, NULL, 0);
-+            } while (sock < 0 && BIO_sock_should_retry(ret));
-+            if (sock < 0) {
-+                ERR_print_errors(bio_err);
-+                BIO_closesocket(asock);
-+                break;
-+            }
-+            i = (*cb)(sock, type, context);
-+            BIO_closesocket(sock);
-+        } else {
-+            i = (*cb)(asock, type, context);
-+        }
-+
-+        if (naccept != -1)
-+            naccept--;
-+        if (i < 0 || naccept == 0) {
-+            BIO_closesocket(asock);
-+            ret = i;
-+            break;
-+        }
-+    }
-+ end:
-+# ifdef AF_UNIX
-+    if (family == AF_UNIX)
-+        unlink(host);
-+# endif
-+    return ret;
-+}
-+
-+#endif  /* OPENSSL_NO_SOCK */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/s_time.c b/CryptoPkg/Library/OpensslLib/openssl/apps/s_time.c
-new file mode 100644
-index 0000000..263502c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/s_time.c
-@@ -0,0 +1,422 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#define NO_SHUTDOWN
-+
-+#include 
-+#include 
-+#include 
-+
-+#include 
-+
-+#ifndef OPENSSL_NO_SOCK
-+
-+#define USE_SOCKETS
-+#include "apps.h"
-+#include 
-+#include 
-+#include 
-+#include "s_apps.h"
-+#include 
-+#if !defined(OPENSSL_SYS_MSDOS)
-+# include OPENSSL_UNISTD
-+#endif
-+
-+#undef ioctl
-+#define ioctl ioctlsocket
-+
-+#define SSL_CONNECT_NAME        "localhost:4433"
-+
-+/* no default cert. */
-+/*
-+ * #define TEST_CERT "client.pem"
-+ */
-+
-+#undef min
-+#undef max
-+#define min(a,b) (((a) < (b)) ? (a) : (b))
-+#define max(a,b) (((a) > (b)) ? (a) : (b))
-+
-+#undef SECONDS
-+#define SECONDS 30
-+#define SECONDSSTR "30"
-+
-+static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx);
-+
-+static const char fmt_http_get_cmd[] = "GET %s HTTP/1.0\r\n\r\n";
-+
-+typedef enum OPTION_choice {
-+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-+    OPT_CONNECT, OPT_CIPHER, OPT_CERT, OPT_KEY, OPT_CAPATH,
-+    OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NEW, OPT_REUSE, OPT_BUGS,
-+    OPT_VERIFY, OPT_TIME, OPT_SSL3,
-+    OPT_WWW
-+} OPTION_CHOICE;
-+
-+OPTIONS s_time_options[] = {
-+    {"help", OPT_HELP, '-', "Display this summary"},
-+    {"connect", OPT_CONNECT, 's',
-+     "Where to connect as post:port (default is " SSL_CONNECT_NAME ")"},
-+    {"cipher", OPT_CIPHER, 's', "Cipher to use, see 'openssl ciphers'"},
-+    {"cert", OPT_CERT, '<', "Cert file to use, PEM format assumed"},
-+    {"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"},
-+    {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
-+    {"cafile", OPT_CAFILE, '<', "PEM format file of CA's"},
-+    {"no-CAfile", OPT_NOCAFILE, '-',
-+     "Do not load the default certificates file"},
-+    {"no-CApath", OPT_NOCAPATH, '-',
-+     "Do not load certificates from the default certificates directory"},
-+    {"new", OPT_NEW, '-', "Just time new connections"},
-+    {"reuse", OPT_REUSE, '-', "Just time connection reuse"},
-+    {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"},
-+    {"verify", OPT_VERIFY, 'p',
-+     "Turn on peer certificate verification, set depth"},
-+    {"time", OPT_TIME, 'p', "Seconds to collect data, default " SECONDSSTR},
-+    {"www", OPT_WWW, 's', "Fetch specified page from the site"},
-+#ifndef OPENSSL_NO_SSL3
-+    {"ssl3", OPT_SSL3, '-', "Just use SSLv3"},
-+#endif
-+    {NULL}
-+};
-+
-+#define START   0
-+#define STOP    1
-+
-+static double tm_Time_F(int s)
-+{
-+    return app_tminterval(s, 1);
-+}
-+
-+int s_time_main(int argc, char **argv)
-+{
-+    char buf[1024 * 8];
-+    SSL *scon = NULL;
-+    SSL_CTX *ctx = NULL;
-+    const SSL_METHOD *meth = NULL;
-+    char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *www_path = NULL;
-+    char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog;
-+    double totalTime = 0.0;
-+    int noCApath = 0, noCAfile = 0;
-+    int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = 0;
-+    long bytes_read = 0, finishtime = 0;
-+    OPTION_CHOICE o;
-+    int max_version = 0, ver, buf_len;
-+    size_t buf_size;
-+
-+    meth = TLS_client_method();
-+
-+    prog = opt_init(argc, argv, s_time_options);
-+    while ((o = opt_next()) != OPT_EOF) {
-+        switch (o) {
-+        case OPT_EOF:
-+        case OPT_ERR:
-+ opthelp:
-+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-+            goto end;
-+        case OPT_HELP:
-+            opt_help(s_time_options);
-+            ret = 0;
-+            goto end;
-+        case OPT_CONNECT:
-+            host = opt_arg();
-+            break;
-+        case OPT_REUSE:
-+            perform = 2;
-+            break;
-+        case OPT_NEW:
-+            perform = 1;
-+            break;
-+        case OPT_VERIFY:
-+            if (!opt_int(opt_arg(), &verify_args.depth))
-+                goto opthelp;
-+            BIO_printf(bio_err, "%s: verify depth is %d\n",
-+                       prog, verify_args.depth);
-+            break;
-+        case OPT_CERT:
-+            certfile = opt_arg();
-+            break;
-+        case OPT_KEY:
-+            keyfile = opt_arg();
-+            break;
-+        case OPT_CAPATH:
-+            CApath = opt_arg();
-+            break;
-+        case OPT_CAFILE:
-+            CAfile = opt_arg();
-+            break;
-+        case OPT_NOCAPATH:
-+            noCApath = 1;
-+            break;
-+        case OPT_NOCAFILE:
-+            noCAfile = 1;
-+            break;
-+        case OPT_CIPHER:
-+            cipher = opt_arg();
-+            break;
-+        case OPT_BUGS:
-+            st_bugs = 1;
-+            break;
-+        case OPT_TIME:
-+            if (!opt_int(opt_arg(), &maxtime))
-+                goto opthelp;
-+            break;
-+        case OPT_WWW:
-+            www_path = opt_arg();
-+            buf_size = strlen(www_path) + sizeof(fmt_http_get_cmd) - 2;  /* 2 is for %s */
-+            if (buf_size > sizeof(buf)) {
-+                BIO_printf(bio_err, "%s: -www option is too long\n", prog);
-+                goto end;
-+            }
-+            break;
-+        case OPT_SSL3:
-+            max_version = SSL3_VERSION;
-+            break;
-+        }
-+    }
-+    argc = opt_num_rest();
-+    if (argc != 0)
-+        goto opthelp;
-+
-+    if (cipher == NULL)
-+        cipher = getenv("SSL_CIPHER");
-+    if (cipher == NULL) {
-+        BIO_printf(bio_err, "No CIPHER specified\n");
-+        goto end;
-+    }
-+
-+    if ((ctx = SSL_CTX_new(meth)) == NULL)
-+        goto end;
-+
-+    SSL_CTX_set_quiet_shutdown(ctx, 1);
-+    if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
-+        goto end;
-+
-+    if (st_bugs)
-+        SSL_CTX_set_options(ctx, SSL_OP_ALL);
-+    if (!SSL_CTX_set_cipher_list(ctx, cipher))
-+        goto end;
-+    if (!set_cert_stuff(ctx, certfile, keyfile))
-+        goto end;
-+
-+    if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) {
-+        ERR_print_errors(bio_err);
-+        goto end;
-+    }
-+    if (!(perform & 1))
-+        goto next;
-+    printf("Collecting connection statistics for %d seconds\n", maxtime);
-+
-+    /* Loop and time how long it takes to make connections */
-+
-+    bytes_read = 0;
-+    finishtime = (long)time(NULL) + maxtime;
-+    tm_Time_F(START);
-+    for (;;) {
-+        if (finishtime < (long)time(NULL))
-+            break;
-+
-+        if ((scon = doConnection(NULL, host, ctx)) == NULL)
-+            goto end;
-+
-+        if (www_path != NULL) {
-+            buf_len = BIO_snprintf(buf, sizeof buf,
-+                                   fmt_http_get_cmd, www_path);
-+            if (SSL_write(scon, buf, buf_len) <= 0)
-+                goto end;
-+            while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
-+                bytes_read += i;
-+        }
-+#ifdef NO_SHUTDOWN
-+        SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
-+#else
-+        SSL_shutdown(scon);
-+#endif
-+        BIO_closesocket(SSL_get_fd(scon));
-+
-+        nConn += 1;
-+        if (SSL_session_reused(scon))
-+            ver = 'r';
-+        else {
-+            ver = SSL_version(scon);
-+            if (ver == TLS1_VERSION)
-+                ver = 't';
-+            else if (ver == SSL3_VERSION)
-+                ver = '3';
-+            else
-+                ver = '*';
-+        }
-+        fputc(ver, stdout);
-+        fflush(stdout);
-+
-+        SSL_free(scon);
-+        scon = NULL;
-+    }
-+    totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
-+
-+    i = (int)((long)time(NULL) - finishtime + maxtime);
-+    printf
-+        ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
-+         nConn, totalTime, ((double)nConn / totalTime), bytes_read);
-+    printf
-+        ("%d connections in %ld real seconds, %ld bytes read per connection\n",
-+         nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);
-+
-+    /*
-+     * Now loop and time connections using the same session id over and over
-+     */
-+
-+ next:
-+    if (!(perform & 2))
-+        goto end;
-+    printf("\n\nNow timing with session id reuse.\n");
-+
-+    /* Get an SSL object so we can reuse the session id */
-+    if ((scon = doConnection(NULL, host, ctx)) == NULL) {
-+        BIO_printf(bio_err, "Unable to get connection\n");
-+        goto end;
-+    }
-+
-+    if (www_path != NULL) {
-+        buf_len = BIO_snprintf(buf, sizeof buf,
-+                               fmt_http_get_cmd, www_path);
-+        if (SSL_write(scon, buf, buf_len) <= 0)
-+            goto end;
-+        while (SSL_read(scon, buf, sizeof(buf)) > 0)
-+            continue;
-+    }
-+#ifdef NO_SHUTDOWN
-+    SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
-+#else
-+    SSL_shutdown(scon);
-+#endif
-+    BIO_closesocket(SSL_get_fd(scon));
-+
-+    nConn = 0;
-+    totalTime = 0.0;
-+
-+    finishtime = (long)time(NULL) + maxtime;
-+
-+    printf("starting\n");
-+    bytes_read = 0;
-+    tm_Time_F(START);
-+
-+    for (;;) {
-+        if (finishtime < (long)time(NULL))
-+            break;
-+
-+        if ((doConnection(scon, host, ctx)) == NULL)
-+            goto end;
-+
-+        if (www_path) {
-+            BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n",
-+                         www_path);
-+            if (SSL_write(scon, buf, strlen(buf)) <= 0)
-+                goto end;
-+            while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
-+                bytes_read += i;
-+        }
-+#ifdef NO_SHUTDOWN
-+        SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
-+#else
-+        SSL_shutdown(scon);
-+#endif
-+        BIO_closesocket(SSL_get_fd(scon));
-+
-+        nConn += 1;
-+        if (SSL_session_reused(scon))
-+            ver = 'r';
-+        else {
-+            ver = SSL_version(scon);
-+            if (ver == TLS1_VERSION)
-+                ver = 't';
-+            else if (ver == SSL3_VERSION)
-+                ver = '3';
-+            else
-+                ver = '*';
-+        }
-+        fputc(ver, stdout);
-+        fflush(stdout);
-+    }
-+    totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
-+
-+    printf
-+        ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
-+         nConn, totalTime, ((double)nConn / totalTime), bytes_read);
-+    printf
-+        ("%d connections in %ld real seconds, %ld bytes read per connection\n",
-+         nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);
-+
-+    ret = 0;
-+
-+ end:
-+    SSL_free(scon);
-+    SSL_CTX_free(ctx);
-+    return (ret);
-+}
-+
-+/*-
-+ * doConnection - make a connection
-+ */
-+static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx)
-+{
-+    BIO *conn;
-+    SSL *serverCon;
-+    int width, i;
-+    fd_set readfds;
-+
-+    if ((conn = BIO_new(BIO_s_connect())) == NULL)
-+        return (NULL);
-+
-+    BIO_set_conn_hostname(conn, host);
-+
-+    if (scon == NULL)
-+        serverCon = SSL_new(ctx);
-+    else {
-+        serverCon = scon;
-+        SSL_set_connect_state(serverCon);
-+    }
-+
-+    SSL_set_bio(serverCon, conn, conn);
-+
-+    /* ok, lets connect */
-+    for (;;) {
-+        i = SSL_connect(serverCon);
-+        if (BIO_sock_should_retry(i)) {
-+            BIO_printf(bio_err, "DELAY\n");
-+
-+            i = SSL_get_fd(serverCon);
-+            width = i + 1;
-+            FD_ZERO(&readfds);
-+            openssl_fdset(i, &readfds);
-+            /*
-+             * Note: under VMS with SOCKETSHR the 2nd parameter is currently
-+             * of type (int *) whereas under other systems it is (void *) if
-+             * you don't have a cast it will choke the compiler: if you do
-+             * have a cast then you can either go for (int *) or (void *).
-+             */
-+            select(width, (void *)&readfds, NULL, NULL, NULL);
-+            continue;
-+        }
-+        break;
-+    }
-+    if (i <= 0) {
-+        BIO_printf(bio_err, "ERROR\n");
-+        if (verify_args.error != X509_V_OK)
-+            BIO_printf(bio_err, "verify error:%s\n",
-+                       X509_verify_cert_error_string(verify_args.error));
-+        else
-+            ERR_print_errors(bio_err);
-+        if (scon == NULL)
-+            SSL_free(serverCon);
-+        return NULL;
-+    }
-+
-+    return serverCon;
-+}
-+#endif /* OPENSSL_NO_SOCK */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/server.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/server.pem
-new file mode 100644
-index 0000000..d0fc265
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/server.pem
-@@ -0,0 +1,52 @@
-+subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Server Cert
-+issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA
-+-----BEGIN CERTIFICATE-----
-+MIID5zCCAs+gAwIBAgIJALnu1NlVpZ6zMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
-+BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT
-+VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt
-+ZWRpYXRlIENBMB4XDTExMTIwODE0MDE0OFoXDTIxMTAxNjE0MDE0OFowZDELMAkG
-+A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU
-+RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgU2VydmVyIENlcnQw
-+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDzhPOSNtyyRspmeuUpxfNJ
-+KCLTuf7g3uQ4zu4iHOmRO5TQci+HhVlLZrHF9XqFXcIP0y4pWDbMSGuiorUmzmfi
-+R7bfSdI/+qIQt8KXRH6HNG1t8ou0VSvWId5TS5Dq/er5ODUr9OaaDva7EquHIcMv
-+vPQGuI+OEAcnleVCy9HVEIySrO4P3CNIicnGkwwiAud05yUAq/gPXBC1hTtmlPD7
-+TVcGVSEiJdvzqqlgv02qedGrkki6GY4S7GjZxrrf7Foc2EP+51LJzwLQx3/JfrCU
-+41NEWAsu/Sl0tQabXESN+zJ1pDqoZ3uHMgpQjeGiE0olr+YcsSW/tJmiU9OiAr8R
-+AgMBAAGjgY8wgYwwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwLAYJYIZI
-+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
-+BBSCvM8AABPR9zklmifnr9LvIBturDAfBgNVHSMEGDAWgBQ2w2yI55X+sL3szj49
-+hqshgYfa2jANBgkqhkiG9w0BAQUFAAOCAQEAqb1NV0B0/pbpK9Z4/bNjzPQLTRLK
-+WnSNm/Jh5v0GEUOE/Beg7GNjNrmeNmqxAlpqWz9qoeoFZax+QBpIZYjROU3TS3fp
-+yLsrnlr0CDQ5R7kCCDGa8dkXxemmpZZLbUCpW2Uoy8sAA4JjN9OtsZY7dvUXFgJ7
-+vVNTRnI01ghknbtD+2SxSQd3CWF6QhcRMAzZJ1z1cbbwGDDzfvGFPzJ+Sq+zEPds
-+xoVLLSetCiBc+40ZcDS5dV98h9XD7JMTQfxzA7mNGv73JoZJA6nFgj+ADSlJsY/t
-+JBv+z1iQRueoh9Qeee+ZbRifPouCB8FDx+AltvHTANdAq0t/K3o+pplMVA==
-+-----END CERTIFICATE-----
-+-----BEGIN RSA PRIVATE KEY-----
-+MIIEpAIBAAKCAQEA84TzkjbcskbKZnrlKcXzSSgi07n+4N7kOM7uIhzpkTuU0HIv
-+h4VZS2axxfV6hV3CD9MuKVg2zEhroqK1Js5n4ke230nSP/qiELfCl0R+hzRtbfKL
-+tFUr1iHeU0uQ6v3q+Tg1K/Tmmg72uxKrhyHDL7z0BriPjhAHJ5XlQsvR1RCMkqzu
-+D9wjSInJxpMMIgLndOclAKv4D1wQtYU7ZpTw+01XBlUhIiXb86qpYL9NqnnRq5JI
-+uhmOEuxo2ca63+xaHNhD/udSyc8C0Md/yX6wlONTRFgLLv0pdLUGm1xEjfsydaQ6
-+qGd7hzIKUI3hohNKJa/mHLElv7SZolPTogK/EQIDAQABAoIBAADq9FwNtuE5IRQn
-+zGtO4q7Y5uCzZ8GDNYr9RKp+P2cbuWDbvVAecYq2NV9QoIiWJOAYZKklOvekIju3
-+r0UZLA0PRiIrTg6NrESx3JrjWDK8QNlUO7CPTZ39/K+FrmMkV9lem9yxjJjyC34D
-+AQB+YRTx+l14HppjdxNwHjAVQpIx/uO2F5xAMuk32+3K+pq9CZUtrofe1q4Agj9R
-+5s8mSy9pbRo9kW9wl5xdEotz1LivFOEiqPUJTUq5J5PeMKao3vdK726XI4Z455Nm
-+W2/MA0YV0ug2FYinHcZdvKM6dimH8GLfa3X8xKRfzjGjTiMSwsdjgMa4awY3tEHH
-+674jhAECgYEA/zqMrc0zsbNk83sjgaYIug5kzEpN4ic020rSZsmQxSCerJTgNhmg
-+utKSCt0Re09Jt3LqG48msahX8ycqDsHNvlEGPQSbMu9IYeO3Wr3fAm75GEtFWePY
-+BhM73I7gkRt4s8bUiUepMG/wY45c5tRF23xi8foReHFFe9MDzh8fJFECgYEA9EFX
-+4qAik1pOJGNei9BMwmx0I0gfVEIgu0tzeVqT45vcxbxr7RkTEaDoAG6PlbWP6D9a
-+WQNLp4gsgRM90ZXOJ4up5DsAWDluvaF4/omabMA+MJJ5kGZ0gCj5rbZbKqUws7x8
-+bp+6iBfUPJUbcqNqFmi/08Yt7vrDnMnyMw2A/sECgYEAiiuRMxnuzVm34hQcsbhH
-+6ymVqf7j0PW2qK0F4H1ocT9qhzWFd+RB3kHWrCjnqODQoI6GbGr/4JepHUpre1ex
-+4UEN5oSS3G0ru0rC3U4C59dZ5KwDHFm7ffZ1pr52ljfQDUsrjjIMRtuiwNK2OoRa
-+WSsqiaL+SDzSB+nBmpnAizECgYBdt/y6rerWUx4MhDwwtTnel7JwHyo2MDFS6/5g
-+n8qC2Lj6/fMDRE22w+CA2esp7EJNQJGv+b27iFpbJEDh+/Lf5YzIT4MwVskQ5bYB
-+JFcmRxUVmf4e09D7o705U/DjCgMH09iCsbLmqQ38ONIRSHZaJtMDtNTHD1yi+jF+
-+OT43gQKBgQC/2OHZoko6iRlNOAQ/tMVFNq7fL81GivoQ9F1U0Qr+DH3ZfaH8eIkX
-+xT0ToMPJUzWAn8pZv0snA0um6SIgvkCuxO84OkANCVbttzXImIsL7pFzfcwV/ERK
-+UM6j0ZuSMFOCr/lGPAoOQU0fskidGEHi1/kW+suSr28TqsyYZpwBDQ==
-+-----END RSA PRIVATE KEY-----
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/server.srl b/CryptoPkg/Library/OpensslLib/openssl/apps/server.srl
-new file mode 100644
-index 0000000..8a0f05e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/server.srl
-@@ -0,0 +1 @@
-+01
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/server2.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/server2.pem
-new file mode 100644
-index 0000000..a3927cf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/server2.pem
-@@ -0,0 +1,52 @@
-+subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Server Cert #2
-+issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA
-+-----BEGIN CERTIFICATE-----
-+MIID6jCCAtKgAwIBAgIJALnu1NlVpZ60MA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV
-+BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT
-+VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt
-+ZWRpYXRlIENBMB4XDTExMTIwODE0MDE0OFoXDTIxMTAxNjE0MDE0OFowZzELMAkG
-+A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU
-+RVNUSU5HIFBVUlBPU0VTIE9OTFkxHDAaBgNVBAMME1Rlc3QgU2VydmVyIENlcnQg
-+IzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDrdi7j9yctG+L4EjBy
-+gjPmEqZzOJEQba26MoQGzglU7e5Xf59Rb/hgVQuKAoiZe7/R8rK4zJ4W7iXdXw0L
-+qBpyG8B5aGKeI32w+A9TcBApoXXL2CrYQEQjZwUIpLlYBIi2NkJj3nVkq5dgl1gO
-+ALiQ+W8jg3kzg5Ec9rimp9r93N8wsSL3awsafurmYCvOf7leHaMP1WJ/zDRGUNHG
-+/WtDjXc8ZUG1+6EXU9Jc2Fs+2Omf7fcN0l00AK/wPg8OaNS0rKyGq9JdIT9FRGV1
-+bXe/rx58FaE5CItdwCSYhJvF/O95LWQoxJXye5bCFLmvDTEyVq9FMSCptfsmbXjE
-+ZGsXAgMBAAGjgY8wgYwwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwLAYJ
-+YIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1Ud
-+DgQWBBR52UaWWTKzZGDH/X4mWNcuqeQVazAfBgNVHSMEGDAWgBQ2w2yI55X+sL3s
-+zj49hqshgYfa2jANBgkqhkiG9w0BAQUFAAOCAQEANBW+XYLlHBqVY/31ie+3gRlS
-+LPfy4SIqn0t3RJjagT29MXprblBO2cbMO8VGjkQdKGpmMXjxbht2arOOUXRHX4n/
-+XTyn/QHEf0bcwIITMReO3DZUPAEw8hSjn9xEOM0IRVOCP+mH5fi74QzzQaZVCyYg
-+5VtLKdww/+sc0nCbKl2KWgDluriH0nfVx95qgW3mg9dhXRr0zmf1w2zkBHYpARYL
-+Dew6Z8EE4tS3HJu8/qM6meWzNtrfonQ3eiiMxjZBxzV46jchBwa2z9XYhP6AmpPb
-+oeTSzcQNbWsxaGYzWo46oLDUZmJOwSBawbS31bZNMCoPIY6ukoesCzFSsUKZww==
-+-----END CERTIFICATE-----
-+-----BEGIN RSA PRIVATE KEY-----
-+MIIEowIBAAKCAQEA63Yu4/cnLRvi+BIwcoIz5hKmcziREG2tujKEBs4JVO3uV3+f
-+UW/4YFULigKImXu/0fKyuMyeFu4l3V8NC6gachvAeWhiniN9sPgPU3AQKaF1y9gq
-+2EBEI2cFCKS5WASItjZCY951ZKuXYJdYDgC4kPlvI4N5M4ORHPa4pqfa/dzfMLEi
-+92sLGn7q5mArzn+5Xh2jD9Vif8w0RlDRxv1rQ413PGVBtfuhF1PSXNhbPtjpn+33
-+DdJdNACv8D4PDmjUtKyshqvSXSE/RURldW13v68efBWhOQiLXcAkmISbxfzveS1k
-+KMSV8nuWwhS5rw0xMlavRTEgqbX7Jm14xGRrFwIDAQABAoIBAHLsTPihIfLnYIE5
-+x4GsQQ5zXeBw5ITDM37ktwHnQDC+rIzyUl1aLD1AZRBoKinXd4lOTqLZ4/NHKx4A
-+DYr58mZtWyUmqLOMmQVuHXTZBlp7XtYuXMMNovQwjQlp9LicBeoBU6gQ5PVMtubD
-+F4xGF89Sn0cTHW3iMkqTtQ5KcR1j57OcJO0FEb1vPvk2MXI5ZyAatUYE7YacbEzd
-+rg02uIwx3FqNSkuSI79uz4hMdV5TPtuhxx9nTwj9aLUhXFeZ0mn2PVgVzEnnMoJb
-++znlsZDgzDlJqdaD744YGWh8Z3OEssB35KfzFcdOeO6yH8lmv2Zfznk7pNPT7LTb
-+Lae9VgkCgYEA92p1qnAB3NtJtNcaW53i0S5WJgS1hxWKvUDx3lTB9s8X9fHpqL1a
-+E94fDfWzp/hax6FefUKIvBOukPLQ6bYjTMiFoOHzVirghAIuIUoMI5VtLhwD1hKs
-+Lr7l/dptMgKb1nZHyXoKHRBthsy3K4+udsPi8TzMvYElgEqyQIe/Rk0CgYEA86GL
-+8HC6zLszzKERDPBxrboRmoFvVUCTQDhsfj1M8aR3nQ8V5LkdIJc7Wqm/Ggfk9QRf
-+rJ8M2WUMlU5CNnCn/KCrKzCNZIReze3fV+HnKdbcXGLvgbHPrhnz8yYehUFG+RGq
-+bVyDWRU94T38izy2s5qMYrMJWZEYyXncSPbfcPMCgYAtaXfxcZ+V5xYPQFARMtiX
-+5nZfggvDoJuXgx0h3tK/N2HBfcaSdzbaYLG4gTmZggc/jwnl2dl5E++9oSPhUdIG
-+3ONSFUbxsOsGr9PBvnKd8WZZyUCXAVRjPBzAzF+whzQNWCZy/5htnz9LN7YDI9s0
-+5113Q96cheDZPFydZY0hHQKBgQDVbEhNukM5xCiNcu+f2SaMnLp9EjQ4h5g3IvaP
-+5B16daw/Dw8LzcohWboqIxeAsze0GD/D1ZUJAEd0qBjC3g+a9BjefervCjKOzXng
-+38mEUm+6EwVjJSQcjSmycEs+Sr/kwr/8i5WYvU32+jk4tFgMoC+o6tQe/Uesf68k
-+z/dPVwKBgGbF7Vv1/3SmhlOy+zYyvJ0CrWtKxH9QP6tLIEgEpd8x7YTSuCH94yok
-+kToMXYA3sWNPt22GbRDZ+rcp4c7HkDx6I6vpdP9aQEwJTp0EPy0sgWr2XwYmreIQ
-+NFmkk8Itn9EY2R9VBaP7GLv5kvwxDdLAnmwGmzVtbmaVdxCaBwUk
-+-----END RSA PRIVATE KEY-----
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/sess_id.c b/CryptoPkg/Library/OpensslLib/openssl/apps/sess_id.c
-new file mode 100644
-index 0000000..2b63e69
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/sess_id.c
-@@ -0,0 +1,190 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "apps.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+typedef enum OPTION_choice {
-+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-+    OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT,
-+    OPT_TEXT, OPT_CERT, OPT_NOOUT, OPT_CONTEXT
-+} OPTION_CHOICE;
-+
-+OPTIONS sess_id_options[] = {
-+    {"help", OPT_HELP, '-', "Display this summary"},
-+    {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"},
-+    {"outform", OPT_OUTFORM, 'f',
-+     "Output format - default PEM (PEM, DER or NSS)"},
-+    {"in", OPT_IN, 's', "Input file - default stdin"},
-+    {"out", OPT_OUT, 's', "Output file - default stdout"},
-+    {"text", OPT_TEXT, '-', "Print ssl session id details"},
-+    {"cert", OPT_CERT, '-', "Output certificate "},
-+    {"noout", OPT_NOOUT, '-', "Don't output the encoded session info"},
-+    {"context", OPT_CONTEXT, 's', "Set the session ID context"},
-+    {NULL}
-+};
-+
-+static SSL_SESSION *load_sess_id(char *file, int format);
-+
-+int sess_id_main(int argc, char **argv)
-+{
-+    SSL_SESSION *x = NULL;
-+    X509 *peer = NULL;
-+    BIO *out = NULL;
-+    char *infile = NULL, *outfile = NULL, *context = NULL, *prog;
-+    int informat = FORMAT_PEM, outformat = FORMAT_PEM;
-+    int cert = 0, noout = 0, text = 0, ret = 1, i, num = 0;
-+    OPTION_CHOICE o;
-+
-+    prog = opt_init(argc, argv, sess_id_options);
-+    while ((o = opt_next()) != OPT_EOF) {
-+        switch (o) {
-+        case OPT_EOF:
-+        case OPT_ERR:
-+ opthelp:
-+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-+            goto end;
-+        case OPT_HELP:
-+            opt_help(sess_id_options);
-+            ret = 0;
-+            goto end;
-+        case OPT_INFORM:
-+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
-+                goto opthelp;
-+            break;
-+        case OPT_OUTFORM:
-+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER | OPT_FMT_NSS,
-+                            &outformat))
-+                goto opthelp;
-+            break;
-+        case OPT_IN:
-+            infile = opt_arg();
-+            break;
-+        case OPT_OUT:
-+            outfile = opt_arg();
-+            break;
-+        case OPT_TEXT:
-+            text = ++num;
-+            break;
-+        case OPT_CERT:
-+            cert = ++num;
-+            break;
-+        case OPT_NOOUT:
-+            noout = ++num;
-+            break;
-+        case OPT_CONTEXT:
-+            context = opt_arg();
-+            break;
-+        }
-+    }
-+    argc = opt_num_rest();
-+    if (argc != 0)
-+        goto opthelp;
-+
-+    x = load_sess_id(infile, informat);
-+    if (x == NULL) {
-+        goto end;
-+    }
-+    peer = SSL_SESSION_get0_peer(x);
-+
-+    if (context) {
-+        size_t ctx_len = strlen(context);
-+        if (ctx_len > SSL_MAX_SID_CTX_LENGTH) {
-+            BIO_printf(bio_err, "Context too long\n");
-+            goto end;
-+        }
-+        if (!SSL_SESSION_set1_id_context(x, (unsigned char *)context,
-+                    ctx_len)) {
-+            BIO_printf(bio_err, "Error setting id context\n");
-+            goto end;
-+        }
-+    }
-+
-+    if (!noout || text) {
-+        out = bio_open_default(outfile, 'w', outformat);
-+        if (out == NULL)
-+            goto end;
-+    }
-+
-+    if (text) {
-+        SSL_SESSION_print(out, x);
-+
-+        if (cert) {
-+            if (peer == NULL)
-+                BIO_puts(out, "No certificate present\n");
-+            else
-+                X509_print(out, peer);
-+        }
-+    }
-+
-+    if (!noout && !cert) {
-+        if (outformat == FORMAT_ASN1)
-+            i = i2d_SSL_SESSION_bio(out, x);
-+        else if (outformat == FORMAT_PEM)
-+            i = PEM_write_bio_SSL_SESSION(out, x);
-+        else if (outformat == FORMAT_NSS)
-+            i = SSL_SESSION_print_keylog(out, x);
-+        else {
-+            BIO_printf(bio_err, "bad output format specified for outfile\n");
-+            goto end;
-+        }
-+        if (!i) {
-+            BIO_printf(bio_err, "unable to write SSL_SESSION\n");
-+            goto end;
-+        }
-+    } else if (!noout && (peer != NULL)) { /* just print the certificate */
-+        if (outformat == FORMAT_ASN1)
-+            i = (int)i2d_X509_bio(out, peer);
-+        else if (outformat == FORMAT_PEM)
-+            i = PEM_write_bio_X509(out, peer);
-+        else {
-+            BIO_printf(bio_err, "bad output format specified for outfile\n");
-+            goto end;
-+        }
-+        if (!i) {
-+            BIO_printf(bio_err, "unable to write X509\n");
-+            goto end;
-+        }
-+    }
-+    ret = 0;
-+ end:
-+    BIO_free_all(out);
-+    SSL_SESSION_free(x);
-+    return (ret);
-+}
-+
-+static SSL_SESSION *load_sess_id(char *infile, int format)
-+{
-+    SSL_SESSION *x = NULL;
-+    BIO *in = NULL;
-+
-+    in = bio_open_default(infile, 'r', format);
-+    if (in == NULL)
-+        goto end;
-+    if (format == FORMAT_ASN1)
-+        x = d2i_SSL_SESSION_bio(in, NULL);
-+    else
-+        x = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
-+    if (x == NULL) {
-+        BIO_printf(bio_err, "unable to load SSL_SESSION\n");
-+        ERR_print_errors(bio_err);
-+        goto end;
-+    }
-+
-+ end:
-+    BIO_free(in);
-+    return (x);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/smime.c b/CryptoPkg/Library/OpensslLib/openssl/apps/smime.c
-new file mode 100644
-index 0000000..caa9252
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/smime.c
-@@ -0,0 +1,656 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* S/MIME utility function */
-+
-+#include 
-+#include 
-+#include "apps.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+static int save_certs(char *signerfile, STACK_OF(X509) *signers);
-+static int smime_cb(int ok, X509_STORE_CTX *ctx);
-+
-+#define SMIME_OP        0x10
-+#define SMIME_IP        0x20
-+#define SMIME_SIGNERS   0x40
-+#define SMIME_ENCRYPT   (1 | SMIME_OP)
-+#define SMIME_DECRYPT   (2 | SMIME_IP)
-+#define SMIME_SIGN      (3 | SMIME_OP | SMIME_SIGNERS)
-+#define SMIME_VERIFY    (4 | SMIME_IP)
-+#define SMIME_PK7OUT    (5 | SMIME_IP | SMIME_OP)
-+#define SMIME_RESIGN    (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
-+
-+typedef enum OPTION_choice {
-+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-+    OPT_ENCRYPT, OPT_DECRYPT, OPT_SIGN, OPT_RESIGN, OPT_VERIFY,
-+    OPT_PK7OUT, OPT_TEXT, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCHAIN,
-+    OPT_NOCERTS, OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP,
-+    OPT_BINARY, OPT_NOSIGS, OPT_STREAM, OPT_INDEF, OPT_NOINDEF,
-+    OPT_CRLFEOL, OPT_RAND, OPT_ENGINE, OPT_PASSIN,
-+    OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_MD,
-+    OPT_CIPHER, OPT_INKEY, OPT_KEYFORM, OPT_CERTFILE, OPT_CAFILE,
-+    OPT_V_ENUM,
-+    OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, OPT_IN, OPT_INFORM, OPT_OUT,
-+    OPT_OUTFORM, OPT_CONTENT
-+} OPTION_CHOICE;
-+
-+OPTIONS smime_options[] = {
-+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"},
-+    {OPT_HELP_STR, 1, '-',
-+        "  cert.pem... recipient certs for encryption\n"},
-+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
-+    {"help", OPT_HELP, '-', "Display this summary"},
-+    {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"},
-+    {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"},
-+    {"sign", OPT_SIGN, '-', "Sign message"},
-+    {"verify", OPT_VERIFY, '-', "Verify signed message"},
-+    {"pk7out", OPT_PK7OUT, '-', "Output PKCS#7 structure"},
-+    {"nointern", OPT_NOINTERN, '-',
-+     "Don't search certificates in message for signer"},
-+    {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"},
-+    {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"},
-+    {"nocerts", OPT_NOCERTS, '-',
-+     "Don't include signers certificate when signing"},
-+    {"nodetach", OPT_NODETACH, '-', "Use opaque signing"},
-+    {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"},
-+    {"binary", OPT_BINARY, '-', "Don't translate message to text"},
-+    {"certfile", OPT_CERTFILE, '<', "Other certificates file"},
-+    {"signer", OPT_SIGNER, 's', "Signer certificate file"},
-+    {"recip", OPT_RECIP, '<', "Recipient certificate file for decryption"},
-+    {"in", OPT_IN, '<', "Input file"},
-+    {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"},
-+    {"inkey", OPT_INKEY, '<',
-+     "Input private key (if not signer or recipient)"},
-+    {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"},
-+    {"out", OPT_OUT, '>', "Output file"},
-+    {"outform", OPT_OUTFORM, 'c',
-+     "Output format SMIME (default), PEM or DER"},
-+    {"content", OPT_CONTENT, '<',
-+     "Supply or override content for detached signature"},
-+    {"to", OPT_TO, 's', "To address"},
-+    {"from", OPT_FROM, 's', "From address"},
-+    {"subject", OPT_SUBJECT, 's', "Subject"},
-+    {"text", OPT_TEXT, '-', "Include or delete text MIME headers"},
-+    {"CApath", OPT_CAPATH, '/', "Trusted certificates directory"},
-+    {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"},
-+    {"no-CAfile", OPT_NOCAFILE, '-',
-+     "Do not load the default certificates file"},
-+    {"no-CApath", OPT_NOCAPATH, '-',
-+     "Do not load certificates from the default certificates directory"},
-+    {"resign", OPT_RESIGN, '-', "Resign a signed message"},
-+    {"nochain", OPT_NOCHAIN, '-', 
-+     "set PKCS7_NOCHAIN so certificates contained in the message are not used as untrusted CAs" },
-+    {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"},
-+    {"stream", OPT_STREAM, '-', "Enable CMS streaming" },
-+    {"indef", OPT_INDEF, '-', "Same as -stream" },
-+    {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"},
-+    {"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only"},
-+    {"rand", OPT_RAND, 's',
-+     "Load the file(s) into the random number generator"},
-+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
-+    {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"},
-+    {"", OPT_CIPHER, '-', "Any supported cipher"},
-+    OPT_V_OPTIONS,
-+#ifndef OPENSSL_NO_ENGINE
-+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
-+#endif
-+    {NULL}
-+};
-+
-+int smime_main(int argc, char **argv)
-+{
-+    BIO *in = NULL, *out = NULL, *indata = NULL;
-+    EVP_PKEY *key = NULL;
-+    PKCS7 *p7 = NULL;
-+    STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
-+    STACK_OF(X509) *encerts = NULL, *other = NULL;
-+    X509 *cert = NULL, *recip = NULL, *signer = NULL;
-+    X509_STORE *store = NULL;
-+    X509_VERIFY_PARAM *vpm = NULL;
-+    const EVP_CIPHER *cipher = NULL;
-+    const EVP_MD *sign_md = NULL;
-+    const char *CAfile = NULL, *CApath = NULL, *prog = NULL;
-+    char *certfile = NULL, *keyfile = NULL, *contfile = NULL, *inrand = NULL;
-+    char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile =
-+        NULL;
-+    char *passinarg = NULL, *passin = NULL, *to = NULL, *from =
-+        NULL, *subject = NULL;
-+    OPTION_CHOICE o;
-+    int noCApath = 0, noCAfile = 0;
-+    int flags = PKCS7_DETACHED, operation = 0, ret = 0, need_rand = 0, indef =
-+        0;
-+    int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform =
-+        FORMAT_PEM;
-+    int vpmtouched = 0, rv = 0;
-+    ENGINE *e = NULL;
-+    const char *mime_eol = "\n";
-+
-+    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
-+        return 1;
-+
-+    prog = opt_init(argc, argv, smime_options);
-+    while ((o = opt_next()) != OPT_EOF) {
-+        switch (o) {
-+        case OPT_EOF:
-+        case OPT_ERR:
-+ opthelp:
-+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-+            goto end;
-+        case OPT_HELP:
-+            opt_help(smime_options);
-+            ret = 0;
-+            goto end;
-+        case OPT_INFORM:
-+            if (!opt_format(opt_arg(), OPT_FMT_PDS, &informat))
-+                goto opthelp;
-+            break;
-+        case OPT_IN:
-+            infile = opt_arg();
-+            break;
-+        case OPT_OUTFORM:
-+            if (!opt_format(opt_arg(), OPT_FMT_PDS, &outformat))
-+                goto opthelp;
-+            break;
-+        case OPT_OUT:
-+            outfile = opt_arg();
-+            break;
-+        case OPT_ENCRYPT:
-+            operation = SMIME_ENCRYPT;
-+            break;
-+        case OPT_DECRYPT:
-+            operation = SMIME_DECRYPT;
-+            break;
-+        case OPT_SIGN:
-+            operation = SMIME_SIGN;
-+            break;
-+        case OPT_RESIGN:
-+            operation = SMIME_RESIGN;
-+            break;
-+        case OPT_VERIFY:
-+            operation = SMIME_VERIFY;
-+            break;
-+        case OPT_PK7OUT:
-+            operation = SMIME_PK7OUT;
-+            break;
-+        case OPT_TEXT:
-+            flags |= PKCS7_TEXT;
-+            break;
-+        case OPT_NOINTERN:
-+            flags |= PKCS7_NOINTERN;
-+            break;
-+        case OPT_NOVERIFY:
-+            flags |= PKCS7_NOVERIFY;
-+            break;
-+        case OPT_NOCHAIN:
-+            flags |= PKCS7_NOCHAIN;
-+            break;
-+        case OPT_NOCERTS:
-+            flags |= PKCS7_NOCERTS;
-+            break;
-+        case OPT_NOATTR:
-+            flags |= PKCS7_NOATTR;
-+            break;
-+        case OPT_NODETACH:
-+            flags &= ~PKCS7_DETACHED;
-+            break;
-+        case OPT_NOSMIMECAP:
-+            flags |= PKCS7_NOSMIMECAP;
-+            break;
-+        case OPT_BINARY:
-+            flags |= PKCS7_BINARY;
-+            break;
-+        case OPT_NOSIGS:
-+            flags |= PKCS7_NOSIGS;
-+            break;
-+        case OPT_STREAM:
-+        case OPT_INDEF:
-+            indef = 1;
-+            break;
-+        case OPT_NOINDEF:
-+            indef = 0;
-+            break;
-+        case OPT_CRLFEOL:
-+            flags |= PKCS7_CRLFEOL;
-+            mime_eol = "\r\n";
-+            break;
-+        case OPT_RAND:
-+            inrand = opt_arg();
-+            need_rand = 1;
-+            break;
-+        case OPT_ENGINE:
-+            e = setup_engine(opt_arg(), 0);
-+            break;
-+        case OPT_PASSIN:
-+            passinarg = opt_arg();
-+            break;
-+        case OPT_TO:
-+            to = opt_arg();
-+            break;
-+        case OPT_FROM:
-+            from = opt_arg();
-+            break;
-+        case OPT_SUBJECT:
-+            subject = opt_arg();
-+            break;
-+        case OPT_SIGNER:
-+            /* If previous -signer argument add signer to list */
-+            if (signerfile) {
-+                if (sksigners == NULL
-+                    && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
-+                    goto end;
-+                sk_OPENSSL_STRING_push(sksigners, signerfile);
-+                if (keyfile == NULL)
-+                    keyfile = signerfile;
-+                if (skkeys == NULL
-+                    && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
-+                    goto end;
-+                sk_OPENSSL_STRING_push(skkeys, keyfile);
-+                keyfile = NULL;
-+            }
-+            signerfile = opt_arg();
-+            break;
-+        case OPT_RECIP:
-+            recipfile = opt_arg();
-+            break;
-+        case OPT_MD:
-+            if (!opt_md(opt_arg(), &sign_md))
-+                goto opthelp;
-+            break;
-+        case OPT_CIPHER:
-+            if (!opt_cipher(opt_unknown(), &cipher))
-+                goto opthelp;
-+            break;
-+        case OPT_INKEY:
-+            /* If previous -inkey argument add signer to list */
-+            if (keyfile) {
-+                if (signerfile == NULL) {
-+                    BIO_printf(bio_err,
-+                               "%s: Must have -signer before -inkey\n", prog);
-+                    goto opthelp;
-+                }
-+                if (sksigners == NULL
-+                    && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
-+                    goto end;
-+                sk_OPENSSL_STRING_push(sksigners, signerfile);
-+                signerfile = NULL;
-+                if (skkeys == NULL
-+                    && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
-+                    goto end;
-+                sk_OPENSSL_STRING_push(skkeys, keyfile);
-+            }
-+            keyfile = opt_arg();
-+            break;
-+        case OPT_KEYFORM:
-+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
-+                goto opthelp;
-+            break;
-+        case OPT_CERTFILE:
-+            certfile = opt_arg();
-+            break;
-+        case OPT_CAFILE:
-+            CAfile = opt_arg();
-+            break;
-+        case OPT_CAPATH:
-+            CApath = opt_arg();
-+            break;
-+        case OPT_NOCAFILE:
-+            noCAfile = 1;
-+            break;
-+        case OPT_NOCAPATH:
-+            noCApath = 1;
-+            break;
-+        case OPT_CONTENT:
-+            contfile = opt_arg();
-+            break;
-+        case OPT_V_CASES:
-+            if (!opt_verify(o, vpm))
-+                goto opthelp;
-+            vpmtouched++;
-+            break;
-+        }
-+    }
-+    argc = opt_num_rest();
-+    argv = opt_rest();
-+
-+    if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) {
-+        BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
-+        goto opthelp;
-+    }
-+
-+    if (operation & SMIME_SIGNERS) {
-+        /* Check to see if any final signer needs to be appended */
-+        if (keyfile && !signerfile) {
-+            BIO_puts(bio_err, "Illegal -inkey without -signer\n");
-+            goto opthelp;
-+        }
-+        if (signerfile) {
-+            if (!sksigners
-+                && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
-+                goto end;
-+            sk_OPENSSL_STRING_push(sksigners, signerfile);
-+            if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
-+                goto end;
-+            if (!keyfile)
-+                keyfile = signerfile;
-+            sk_OPENSSL_STRING_push(skkeys, keyfile);
-+        }
-+        if (!sksigners) {
-+            BIO_printf(bio_err, "No signer certificate specified\n");
-+            goto opthelp;
-+        }
-+        signerfile = NULL;
-+        keyfile = NULL;
-+        need_rand = 1;
-+    } else if (operation == SMIME_DECRYPT) {
-+        if (!recipfile && !keyfile) {
-+            BIO_printf(bio_err,
-+                       "No recipient certificate or key specified\n");
-+            goto opthelp;
-+        }
-+    } else if (operation == SMIME_ENCRYPT) {
-+        if (argc == 0) {
-+            BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
-+            goto opthelp;
-+        }
-+        need_rand = 1;
-+    } else if (!operation)
-+        goto opthelp;
-+
-+    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
-+        BIO_printf(bio_err, "Error getting password\n");
-+        goto end;
-+    }
-+
-+    if (need_rand) {
-+        app_RAND_load_file(NULL, (inrand != NULL));
-+        if (inrand != NULL)
-+            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-+                       app_RAND_load_files(inrand));
-+    }
-+
-+    ret = 2;
-+
-+    if (!(operation & SMIME_SIGNERS))
-+        flags &= ~PKCS7_DETACHED;
-+
-+    if (!(operation & SMIME_OP)) {
-+        if (flags & PKCS7_BINARY)
-+            outformat = FORMAT_BINARY;
-+    }
-+
-+    if (!(operation & SMIME_IP)) {
-+        if (flags & PKCS7_BINARY)
-+            informat = FORMAT_BINARY;
-+    }
-+
-+    if (operation == SMIME_ENCRYPT) {
-+        if (!cipher) {
-+#ifndef OPENSSL_NO_DES
-+            cipher = EVP_des_ede3_cbc();
-+#else
-+            BIO_printf(bio_err, "No cipher selected\n");
-+            goto end;
-+#endif
-+        }
-+        encerts = sk_X509_new_null();
-+        if (!encerts)
-+            goto end;
-+        while (*argv) {
-+            cert = load_cert(*argv, FORMAT_PEM,
-+                             "recipient certificate file");
-+            if (cert == NULL)
-+                goto end;
-+            sk_X509_push(encerts, cert);
-+            cert = NULL;
-+            argv++;
-+        }
-+    }
-+
-+    if (certfile) {
-+        if (!load_certs(certfile, &other, FORMAT_PEM, NULL,
-+                        "certificate file")) {
-+            ERR_print_errors(bio_err);
-+            goto end;
-+        }
-+    }
-+
-+    if (recipfile && (operation == SMIME_DECRYPT)) {
-+        if ((recip = load_cert(recipfile, FORMAT_PEM,
-+                               "recipient certificate file")) == NULL) {
-+            ERR_print_errors(bio_err);
-+            goto end;
-+        }
-+    }
-+
-+    if (operation == SMIME_DECRYPT) {
-+        if (!keyfile)
-+            keyfile = recipfile;
-+    } else if (operation == SMIME_SIGN) {
-+        if (!keyfile)
-+            keyfile = signerfile;
-+    } else
-+        keyfile = NULL;
-+
-+    if (keyfile) {
-+        key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
-+        if (!key)
-+            goto end;
-+    }
-+
-+    in = bio_open_default(infile, 'r', informat);
-+    if (in == NULL)
-+        goto end;
-+
-+    if (operation & SMIME_IP) {
-+        if (informat == FORMAT_SMIME)
-+            p7 = SMIME_read_PKCS7(in, &indata);
-+        else if (informat == FORMAT_PEM)
-+            p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
-+        else if (informat == FORMAT_ASN1)
-+            p7 = d2i_PKCS7_bio(in, NULL);
-+        else {
-+            BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
-+            goto end;
-+        }
-+
-+        if (!p7) {
-+            BIO_printf(bio_err, "Error reading S/MIME message\n");
-+            goto end;
-+        }
-+        if (contfile) {
-+            BIO_free(indata);
-+            if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
-+                BIO_printf(bio_err, "Can't read content file %s\n", contfile);
-+                goto end;
-+            }
-+        }
-+    }
-+
-+    out = bio_open_default(outfile, 'w', outformat);
-+    if (out == NULL)
-+        goto end;
-+
-+    if (operation == SMIME_VERIFY) {
-+        if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
-+            goto end;
-+        X509_STORE_set_verify_cb(store, smime_cb);
-+        if (vpmtouched)
-+            X509_STORE_set1_param(store, vpm);
-+    }
-+
-+    ret = 3;
-+
-+    if (operation == SMIME_ENCRYPT) {
-+        if (indef)
-+            flags |= PKCS7_STREAM;
-+        p7 = PKCS7_encrypt(encerts, in, cipher, flags);
-+    } else if (operation & SMIME_SIGNERS) {
-+        int i;
-+        /*
-+         * If detached data content we only enable streaming if S/MIME output
-+         * format.
-+         */
-+        if (operation == SMIME_SIGN) {
-+            if (flags & PKCS7_DETACHED) {
-+                if (outformat == FORMAT_SMIME)
-+                    flags |= PKCS7_STREAM;
-+            } else if (indef)
-+                flags |= PKCS7_STREAM;
-+            flags |= PKCS7_PARTIAL;
-+            p7 = PKCS7_sign(NULL, NULL, other, in, flags);
-+            if (!p7)
-+                goto end;
-+            if (flags & PKCS7_NOCERTS) {
-+                for (i = 0; i < sk_X509_num(other); i++) {
-+                    X509 *x = sk_X509_value(other, i);
-+                    PKCS7_add_certificate(p7, x);
-+                }
-+            }
-+        } else
-+            flags |= PKCS7_REUSE_DIGEST;
-+        for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
-+            signerfile = sk_OPENSSL_STRING_value(sksigners, i);
-+            keyfile = sk_OPENSSL_STRING_value(skkeys, i);
-+            signer = load_cert(signerfile, FORMAT_PEM,
-+                               "signer certificate");
-+            if (!signer)
-+                goto end;
-+            key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
-+            if (!key)
-+                goto end;
-+            if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags))
-+                goto end;
-+            X509_free(signer);
-+            signer = NULL;
-+            EVP_PKEY_free(key);
-+            key = NULL;
-+        }
-+        /* If not streaming or resigning finalize structure */
-+        if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM)) {
-+            if (!PKCS7_final(p7, in, flags))
-+                goto end;
-+        }
-+    }
-+
-+    if (!p7) {
-+        BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
-+        goto end;
-+    }
-+
-+    ret = 4;
-+    if (operation == SMIME_DECRYPT) {
-+        if (!PKCS7_decrypt(p7, key, recip, out, flags)) {
-+            BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
-+            goto end;
-+        }
-+    } else if (operation == SMIME_VERIFY) {
-+        STACK_OF(X509) *signers;
-+        if (PKCS7_verify(p7, other, store, indata, out, flags))
-+            BIO_printf(bio_err, "Verification successful\n");
-+        else {
-+            BIO_printf(bio_err, "Verification failure\n");
-+            goto end;
-+        }
-+        signers = PKCS7_get0_signers(p7, other, flags);
-+        if (!save_certs(signerfile, signers)) {
-+            BIO_printf(bio_err, "Error writing signers to %s\n", signerfile);
-+            ret = 5;
-+            goto end;
-+        }
-+        sk_X509_free(signers);
-+    } else if (operation == SMIME_PK7OUT)
-+        PEM_write_bio_PKCS7(out, p7);
-+    else {
-+        if (to)
-+            BIO_printf(out, "To: %s%s", to, mime_eol);
-+        if (from)
-+            BIO_printf(out, "From: %s%s", from, mime_eol);
-+        if (subject)
-+            BIO_printf(out, "Subject: %s%s", subject, mime_eol);
-+        if (outformat == FORMAT_SMIME) {
-+            if (operation == SMIME_RESIGN)
-+                rv = SMIME_write_PKCS7(out, p7, indata, flags);
-+            else
-+                rv = SMIME_write_PKCS7(out, p7, in, flags);
-+        } else if (outformat == FORMAT_PEM)
-+            rv = PEM_write_bio_PKCS7_stream(out, p7, in, flags);
-+        else if (outformat == FORMAT_ASN1)
-+            rv = i2d_PKCS7_bio_stream(out, p7, in, flags);
-+        else {
-+            BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
-+            goto end;
-+        }
-+        if (rv == 0) {
-+            BIO_printf(bio_err, "Error writing output\n");
-+            ret = 3;
-+            goto end;
-+        }
-+    }
-+    ret = 0;
-+ end:
-+    if (need_rand)
-+        app_RAND_write_file(NULL);
-+    if (ret)
-+        ERR_print_errors(bio_err);
-+    sk_X509_pop_free(encerts, X509_free);
-+    sk_X509_pop_free(other, X509_free);
-+    X509_VERIFY_PARAM_free(vpm);
-+    sk_OPENSSL_STRING_free(sksigners);
-+    sk_OPENSSL_STRING_free(skkeys);
-+    X509_STORE_free(store);
-+    X509_free(cert);
-+    X509_free(recip);
-+    X509_free(signer);
-+    EVP_PKEY_free(key);
-+    PKCS7_free(p7);
-+    release_engine(e);
-+    BIO_free(in);
-+    BIO_free(indata);
-+    BIO_free_all(out);
-+    OPENSSL_free(passin);
-+    return (ret);
-+}
-+
-+static int save_certs(char *signerfile, STACK_OF(X509) *signers)
-+{
-+    int i;
-+    BIO *tmp;
-+    if (!signerfile)
-+        return 1;
-+    tmp = BIO_new_file(signerfile, "w");
-+    if (!tmp)
-+        return 0;
-+    for (i = 0; i < sk_X509_num(signers); i++)
-+        PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
-+    BIO_free(tmp);
-+    return 1;
-+}
-+
-+/* Minimal callback just to output policy info (if any) */
-+
-+static int smime_cb(int ok, X509_STORE_CTX *ctx)
-+{
-+    int error;
-+
-+    error = X509_STORE_CTX_get_error(ctx);
-+
-+    if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
-+        && ((error != X509_V_OK) || (ok != 2)))
-+        return ok;
-+
-+    policies_print(ctx);
-+
-+    return ok;
-+
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/speed.c b/CryptoPkg/Library/OpensslLib/openssl/apps/speed.c
-new file mode 100644
-index 0000000..df22422
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/speed.c
-@@ -0,0 +1,3144 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ *
-+ * Portions of the attached software ("Contribution") are developed by
-+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
-+ *
-+ * The Contribution is licensed pursuant to the OpenSSL open source
-+ * license provided above.
-+ *
-+ * The ECDH and ECDSA speed test software is originally written by
-+ * Sumit Gupta of Sun Microsystems Laboratories.
-+ *
-+ */
-+
-+#undef SECONDS
-+#define SECONDS                 3
-+#define PRIME_SECONDS   10
-+#define RSA_SECONDS             10
-+#define DSA_SECONDS             10
-+#define ECDSA_SECONDS   10
-+#define ECDH_SECONDS    10
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "apps.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#if !defined(OPENSSL_SYS_MSDOS)
-+# include OPENSSL_UNISTD
-+#endif
-+
-+#if defined(_WIN32)
-+# include 
-+#endif
-+
-+#include 
-+#ifndef OPENSSL_NO_DES
-+# include 
-+#endif
-+#include 
-+#ifndef OPENSSL_NO_CAMELLIA
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_MD2
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_MDC2
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_MD4
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_MD5
-+# include 
-+#endif
-+#include 
-+#include 
-+#ifndef OPENSSL_NO_RMD160
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_WHIRLPOOL
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_RC4
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_RC5
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_RC2
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_IDEA
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_SEED
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_BF
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_CAST
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_RSA
-+# include 
-+# include "./testrsa.h"
-+#endif
-+#include 
-+#ifndef OPENSSL_NO_DSA
-+# include 
-+# include "./testdsa.h"
-+#endif
-+#ifndef OPENSSL_NO_EC
-+# include 
-+#endif
-+#include 
-+
-+#ifndef HAVE_FORK
-+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS)
-+#  define HAVE_FORK 0
-+# else
-+#  define HAVE_FORK 1
-+# endif
-+#endif
-+
-+#if HAVE_FORK
-+# undef NO_FORK
-+#else
-+# define NO_FORK
-+#endif
-+
-+#undef BUFSIZE
-+#define BUFSIZE (1024*16+1)
-+#define MAX_MISALIGNMENT 63
-+
-+#define ALGOR_NUM       30
-+#define SIZE_NUM        6
-+#define PRIME_NUM       3
-+#define RSA_NUM         7
-+#define DSA_NUM         3
-+
-+#define EC_NUM          17
-+#define MAX_ECDH_SIZE   256
-+#define MISALIGN        64
-+
-+static volatile int run = 0;
-+
-+static int mr = 0;
-+static int usertime = 1;
-+
-+typedef void *(*kdf_fn) (
-+        const void *in, size_t inlen, void *out, size_t *xoutlen);
-+
-+typedef struct loopargs_st {
-+    ASYNC_JOB *inprogress_job;
-+    ASYNC_WAIT_CTX *wait_ctx;
-+    unsigned char *buf;
-+    unsigned char *buf2;
-+    unsigned char *buf_malloc;
-+    unsigned char *buf2_malloc;
-+    unsigned int siglen;
-+#ifndef OPENSSL_NO_RSA
-+    RSA *rsa_key[RSA_NUM];
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    DSA *dsa_key[DSA_NUM];
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    EC_KEY *ecdsa[EC_NUM];
-+    EC_KEY *ecdh_a[EC_NUM];
-+    EC_KEY *ecdh_b[EC_NUM];
-+    unsigned char *secret_a;
-+    unsigned char *secret_b;
-+    size_t      outlen;
-+    kdf_fn      kdf;
-+#endif
-+    EVP_CIPHER_CTX *ctx;
-+    HMAC_CTX *hctx;
-+    GCM128_CONTEXT *gcm_ctx;
-+} loopargs_t;
-+
-+#ifndef OPENSSL_NO_MD2
-+static int EVP_Digest_MD2_loop(void *args);
-+#endif
-+
-+#ifndef OPENSSL_NO_MDC2
-+static int EVP_Digest_MDC2_loop(void *args);
-+#endif
-+#ifndef OPENSSL_NO_MD4
-+static int EVP_Digest_MD4_loop(void *args);
-+#endif
-+#ifndef OPENSSL_NO_MD5
-+static int MD5_loop(void *args);
-+static int HMAC_loop(void *args);
-+#endif
-+static int SHA1_loop(void *args);
-+static int SHA256_loop(void *args);
-+static int SHA512_loop(void *args);
-+#ifndef OPENSSL_NO_WHIRLPOOL
-+static int WHIRLPOOL_loop(void *args);
-+#endif
-+#ifndef OPENSSL_NO_RMD160
-+static int EVP_Digest_RMD160_loop(void *args);
-+#endif
-+#ifndef OPENSSL_NO_RC4
-+static int RC4_loop(void *args);
-+#endif
-+#ifndef OPENSSL_NO_DES
-+static int DES_ncbc_encrypt_loop(void *args);
-+static int DES_ede3_cbc_encrypt_loop(void *args);
-+#endif
-+static int AES_cbc_128_encrypt_loop(void *args);
-+static int AES_cbc_192_encrypt_loop(void *args);
-+static int AES_ige_128_encrypt_loop(void *args);
-+static int AES_cbc_256_encrypt_loop(void *args);
-+static int AES_ige_192_encrypt_loop(void *args);
-+static int AES_ige_256_encrypt_loop(void *args);
-+static int CRYPTO_gcm128_aad_loop(void *args);
-+static int EVP_Update_loop(void *args);
-+static int EVP_Digest_loop(void *args);
-+#ifndef OPENSSL_NO_RSA
-+static int RSA_sign_loop(void *args);
-+static int RSA_verify_loop(void *args);
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+static int DSA_sign_loop(void *args);
-+static int DSA_verify_loop(void *args);
-+#endif
-+#ifndef OPENSSL_NO_EC
-+static int ECDSA_sign_loop(void *args);
-+static int ECDSA_verify_loop(void *args);
-+static int ECDH_compute_key_loop(void *args);
-+#endif
-+static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_t *loopargs);
-+
-+static double Time_F(int s);
-+static void print_message(const char *s, long num, int length);
-+static void pkey_print_message(const char *str, const char *str2,
-+                               long num, int bits, int sec);
-+static void print_result(int alg, int run_no, int count, double time_used);
-+#ifndef NO_FORK
-+static int do_multi(int multi);
-+#endif
-+
-+static const char *names[ALGOR_NUM] = {
-+    "md2", "mdc2", "md4", "md5", "hmac(md5)", "sha1", "rmd160", "rc4",
-+    "des cbc", "des ede3", "idea cbc", "seed cbc",
-+    "rc2 cbc", "rc5-32/12 cbc", "blowfish cbc", "cast cbc",
-+    "aes-128 cbc", "aes-192 cbc", "aes-256 cbc",
-+    "camellia-128 cbc", "camellia-192 cbc", "camellia-256 cbc",
-+    "evp", "sha256", "sha512", "whirlpool",
-+    "aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash"
-+};
-+
-+static double results[ALGOR_NUM][SIZE_NUM];
-+
-+static const int lengths[SIZE_NUM] = {
-+    16, 64, 256, 1024, 8 * 1024, 16 * 1024
-+};
-+
-+#ifndef OPENSSL_NO_RSA
-+static double rsa_results[RSA_NUM][2];
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+static double dsa_results[DSA_NUM][2];
-+#endif
-+#ifndef OPENSSL_NO_EC
-+static double ecdsa_results[EC_NUM][2];
-+static double ecdh_results[EC_NUM][1];
-+#endif
-+
-+#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
-+static const char rnd_seed[] =
-+    "string to make the random number generator think it has entropy";
-+#endif
-+
-+#ifdef SIGALRM
-+# if defined(__STDC__) || defined(sgi) || defined(_AIX)
-+#  define SIGRETTYPE void
-+# else
-+#  define SIGRETTYPE int
-+# endif
-+
-+static SIGRETTYPE sig_done(int sig);
-+static SIGRETTYPE sig_done(int sig)
-+{
-+    signal(SIGALRM, sig_done);
-+    run = 0;
-+}
-+#endif
-+
-+#define START   0
-+#define STOP    1
-+
-+#if defined(_WIN32)
-+
-+# if !defined(SIGALRM)
-+#  define SIGALRM
-+# endif
-+static unsigned int lapse, schlock;
-+static void alarm_win32(unsigned int secs)
-+{
-+    lapse = secs * 1000;
-+}
-+
-+# define alarm alarm_win32
-+
-+static DWORD WINAPI sleepy(VOID * arg)
-+{
-+    schlock = 1;
-+    Sleep(lapse);
-+    run = 0;
-+    return 0;
-+}
-+
-+static double Time_F(int s)
-+{
-+    double ret;
-+    static HANDLE thr;
-+
-+    if (s == START) {
-+        schlock = 0;
-+        thr = CreateThread(NULL, 4096, sleepy, NULL, 0, NULL);
-+        if (thr == NULL) {
-+            DWORD err = GetLastError();
-+            BIO_printf(bio_err, "unable to CreateThread (%lu)", err);
-+            ExitProcess(err);
-+        }
-+        while (!schlock)
-+            Sleep(0);           /* scheduler spinlock */
-+        ret = app_tminterval(s, usertime);
-+    } else {
-+        ret = app_tminterval(s, usertime);
-+        if (run)
-+            TerminateThread(thr, 0);
-+        CloseHandle(thr);
-+    }
-+
-+    return ret;
-+}
-+#else
-+
-+static double Time_F(int s)
-+{
-+    double ret = app_tminterval(s, usertime);
-+    if (s == STOP)
-+        alarm(0);
-+    return ret;
-+}
-+#endif
-+
-+static void multiblock_speed(const EVP_CIPHER *evp_cipher);
-+
-+static int found(const char *name, const OPT_PAIR *pairs, int *result)
-+{
-+    for (; pairs->name; pairs++)
-+        if (strcmp(name, pairs->name) == 0) {
-+            *result = pairs->retval;
-+            return 1;
-+        }
-+    return 0;
-+}
-+
-+typedef enum OPTION_choice {
-+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-+    OPT_ELAPSED, OPT_EVP, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
-+    OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS
-+} OPTION_CHOICE;
-+
-+OPTIONS speed_options[] = {
-+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] ciphers...\n"},
-+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
-+    {"help", OPT_HELP, '-', "Display this summary"},
-+    {"evp", OPT_EVP, 's', "Use specified EVP cipher"},
-+    {"decrypt", OPT_DECRYPT, '-',
-+     "Time decryption instead of encryption (only EVP)"},
-+    {"mr", OPT_MR, '-', "Produce machine readable output"},
-+    {"mb", OPT_MB, '-',
-+     "Enable (tls1.1) multi-block mode on evp_cipher requested with -evp"},
-+    {"misalign", OPT_MISALIGN, 'n', "Amount to mis-align buffers"},
-+    {"elapsed", OPT_ELAPSED, '-',
-+     "Measure time in real time instead of CPU user time"},
-+#ifndef NO_FORK
-+    {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"},
-+#endif
-+#ifndef OPENSSL_NO_ASYNC
-+    {"async_jobs", OPT_ASYNCJOBS, 'p',
-+     "Enable async mode and start pnum jobs"},
-+#endif
-+#ifndef OPENSSL_NO_ENGINE
-+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
-+#endif
-+    {NULL},
-+};
-+
-+#define D_MD2           0
-+#define D_MDC2          1
-+#define D_MD4           2
-+#define D_MD5           3
-+#define D_HMAC          4
-+#define D_SHA1          5
-+#define D_RMD160        6
-+#define D_RC4           7
-+#define D_CBC_DES       8
-+#define D_EDE3_DES      9
-+#define D_CBC_IDEA      10
-+#define D_CBC_SEED      11
-+#define D_CBC_RC2       12
-+#define D_CBC_RC5       13
-+#define D_CBC_BF        14
-+#define D_CBC_CAST      15
-+#define D_CBC_128_AES   16
-+#define D_CBC_192_AES   17
-+#define D_CBC_256_AES   18
-+#define D_CBC_128_CML   19
-+#define D_CBC_192_CML   20
-+#define D_CBC_256_CML   21
-+#define D_EVP           22
-+#define D_SHA256        23
-+#define D_SHA512        24
-+#define D_WHIRLPOOL     25
-+#define D_IGE_128_AES   26
-+#define D_IGE_192_AES   27
-+#define D_IGE_256_AES   28
-+#define D_GHASH         29
-+static OPT_PAIR doit_choices[] = {
-+#ifndef OPENSSL_NO_MD2
-+    {"md2", D_MD2},
-+#endif
-+#ifndef OPENSSL_NO_MDC2
-+    {"mdc2", D_MDC2},
-+#endif
-+#ifndef OPENSSL_NO_MD4
-+    {"md4", D_MD4},
-+#endif
-+#ifndef OPENSSL_NO_MD5
-+    {"md5", D_MD5},
-+    {"hmac", D_HMAC},
-+#endif
-+    {"sha1", D_SHA1},
-+    {"sha256", D_SHA256},
-+    {"sha512", D_SHA512},
-+#ifndef OPENSSL_NO_WHIRLPOOL
-+    {"whirlpool", D_WHIRLPOOL},
-+#endif
-+#ifndef OPENSSL_NO_RMD160
-+    {"ripemd", D_RMD160},
-+    {"rmd160", D_RMD160},
-+    {"ripemd160", D_RMD160},
-+#endif
-+#ifndef OPENSSL_NO_RC4
-+    {"rc4", D_RC4},
-+#endif
-+#ifndef OPENSSL_NO_DES
-+    {"des-cbc", D_CBC_DES},
-+    {"des-ede3", D_EDE3_DES},
-+#endif
-+    {"aes-128-cbc", D_CBC_128_AES},
-+    {"aes-192-cbc", D_CBC_192_AES},
-+    {"aes-256-cbc", D_CBC_256_AES},
-+    {"aes-128-ige", D_IGE_128_AES},
-+    {"aes-192-ige", D_IGE_192_AES},
-+    {"aes-256-ige", D_IGE_256_AES},
-+#ifndef OPENSSL_NO_RC2
-+    {"rc2-cbc", D_CBC_RC2},
-+    {"rc2", D_CBC_RC2},
-+#endif
-+#ifndef OPENSSL_NO_RC5
-+    {"rc5-cbc", D_CBC_RC5},
-+    {"rc5", D_CBC_RC5},
-+#endif
-+#ifndef OPENSSL_NO_IDEA
-+    {"idea-cbc", D_CBC_IDEA},
-+    {"idea", D_CBC_IDEA},
-+#endif
-+#ifndef OPENSSL_NO_SEED
-+    {"seed-cbc", D_CBC_SEED},
-+    {"seed", D_CBC_SEED},
-+#endif
-+#ifndef OPENSSL_NO_BF
-+    {"bf-cbc", D_CBC_BF},
-+    {"blowfish", D_CBC_BF},
-+    {"bf", D_CBC_BF},
-+#endif
-+#ifndef OPENSSL_NO_CAST
-+    {"cast-cbc", D_CBC_CAST},
-+    {"cast", D_CBC_CAST},
-+    {"cast5", D_CBC_CAST},
-+#endif
-+    {"ghash", D_GHASH},
-+    {NULL}
-+};
-+
-+#ifndef OPENSSL_NO_DSA
-+# define R_DSA_512       0
-+# define R_DSA_1024      1
-+# define R_DSA_2048      2
-+static OPT_PAIR dsa_choices[] = {
-+    {"dsa512", R_DSA_512},
-+    {"dsa1024", R_DSA_1024},
-+    {"dsa2048", R_DSA_2048},
-+    {NULL},
-+};
-+#endif
-+
-+#define R_RSA_512       0
-+#define R_RSA_1024      1
-+#define R_RSA_2048      2
-+#define R_RSA_3072      3
-+#define R_RSA_4096      4
-+#define R_RSA_7680      5
-+#define R_RSA_15360     6
-+static OPT_PAIR rsa_choices[] = {
-+    {"rsa512", R_RSA_512},
-+    {"rsa1024", R_RSA_1024},
-+    {"rsa2048", R_RSA_2048},
-+    {"rsa3072", R_RSA_3072},
-+    {"rsa4096", R_RSA_4096},
-+    {"rsa7680", R_RSA_7680},
-+    {"rsa15360", R_RSA_15360},
-+    {NULL}
-+};
-+
-+#define R_EC_P160    0
-+#define R_EC_P192    1
-+#define R_EC_P224    2
-+#define R_EC_P256    3
-+#define R_EC_P384    4
-+#define R_EC_P521    5
-+#define R_EC_K163    6
-+#define R_EC_K233    7
-+#define R_EC_K283    8
-+#define R_EC_K409    9
-+#define R_EC_K571    10
-+#define R_EC_B163    11
-+#define R_EC_B233    12
-+#define R_EC_B283    13
-+#define R_EC_B409    14
-+#define R_EC_B571    15
-+#define R_EC_X25519  16
-+#ifndef OPENSSL_NO_EC
-+static OPT_PAIR ecdsa_choices[] = {
-+    {"ecdsap160", R_EC_P160},
-+    {"ecdsap192", R_EC_P192},
-+    {"ecdsap224", R_EC_P224},
-+    {"ecdsap256", R_EC_P256},
-+    {"ecdsap384", R_EC_P384},
-+    {"ecdsap521", R_EC_P521},
-+    {"ecdsak163", R_EC_K163},
-+    {"ecdsak233", R_EC_K233},
-+    {"ecdsak283", R_EC_K283},
-+    {"ecdsak409", R_EC_K409},
-+    {"ecdsak571", R_EC_K571},
-+    {"ecdsab163", R_EC_B163},
-+    {"ecdsab233", R_EC_B233},
-+    {"ecdsab283", R_EC_B283},
-+    {"ecdsab409", R_EC_B409},
-+    {"ecdsab571", R_EC_B571},
-+    {NULL}
-+};
-+
-+static OPT_PAIR ecdh_choices[] = {
-+    {"ecdhp160", R_EC_P160},
-+    {"ecdhp192", R_EC_P192},
-+    {"ecdhp224", R_EC_P224},
-+    {"ecdhp256", R_EC_P256},
-+    {"ecdhp384", R_EC_P384},
-+    {"ecdhp521", R_EC_P521},
-+    {"ecdhk163", R_EC_K163},
-+    {"ecdhk233", R_EC_K233},
-+    {"ecdhk283", R_EC_K283},
-+    {"ecdhk409", R_EC_K409},
-+    {"ecdhk571", R_EC_K571},
-+    {"ecdhb163", R_EC_B163},
-+    {"ecdhb233", R_EC_B233},
-+    {"ecdhb283", R_EC_B283},
-+    {"ecdhb409", R_EC_B409},
-+    {"ecdhb571", R_EC_B571},
-+    {"ecdhx25519", R_EC_X25519},
-+    {NULL}
-+};
-+#endif
-+
-+#ifndef SIGALRM
-+# define COND(d) (count < (d))
-+# define COUNT(d) (d)
-+#else
-+# define COND(unused_cond) (run && count<0x7fffffff)
-+# define COUNT(d) (count)
-+#endif                         /* SIGALRM */
-+
-+static int testnum;
-+
-+/* Nb of iterations to do per algorithm and key-size */
-+static long c[ALGOR_NUM][SIZE_NUM];
-+
-+#ifndef OPENSSL_NO_MD2
-+static int EVP_Digest_MD2_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char md2[MD2_DIGEST_LENGTH];
-+    int count;
-+
-+    for (count = 0; COND(c[D_MD2][testnum]); count++) {
-+        if (!EVP_Digest(buf, (size_t)lengths[testnum], md2, NULL, EVP_md2(),
-+                NULL))
-+            return -1;
-+    }
-+    return count;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_MDC2
-+static int EVP_Digest_MDC2_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char mdc2[MDC2_DIGEST_LENGTH];
-+    int count;
-+
-+    for (count = 0; COND(c[D_MDC2][testnum]); count++) {
-+        if (!EVP_Digest(buf, (size_t)lengths[testnum], mdc2, NULL, EVP_mdc2(),
-+                NULL))
-+            return -1;
-+    }
-+    return count;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_MD4
-+static int EVP_Digest_MD4_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char md4[MD4_DIGEST_LENGTH];
-+    int count;
-+
-+    for (count = 0; COND(c[D_MD4][testnum]); count++) {
-+        if (!EVP_Digest(buf, (size_t)lengths[testnum], md4, NULL, EVP_md4(),
-+                NULL))
-+            return -1;
-+    }
-+    return count;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_MD5
-+static int MD5_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char md5[MD5_DIGEST_LENGTH];
-+    int count;
-+    for (count = 0; COND(c[D_MD5][testnum]); count++)
-+        MD5(buf, lengths[testnum], md5);
-+    return count;
-+}
-+
-+static int HMAC_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    HMAC_CTX *hctx = tempargs->hctx;
-+    unsigned char hmac[MD5_DIGEST_LENGTH];
-+    int count;
-+
-+    for (count = 0; COND(c[D_HMAC][testnum]); count++) {
-+        HMAC_Init_ex(hctx, NULL, 0, NULL, NULL);
-+        HMAC_Update(hctx, buf, lengths[testnum]);
-+        HMAC_Final(hctx, hmac, NULL);
-+    }
-+    return count;
-+}
-+#endif
-+
-+static int SHA1_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char sha[SHA_DIGEST_LENGTH];
-+    int count;
-+    for (count = 0; COND(c[D_SHA1][testnum]); count++)
-+        SHA1(buf, lengths[testnum], sha);
-+    return count;
-+}
-+
-+static int SHA256_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char sha256[SHA256_DIGEST_LENGTH];
-+    int count;
-+    for (count = 0; COND(c[D_SHA256][testnum]); count++)
-+        SHA256(buf, lengths[testnum], sha256);
-+    return count;
-+}
-+
-+static int SHA512_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char sha512[SHA512_DIGEST_LENGTH];
-+    int count;
-+    for (count = 0; COND(c[D_SHA512][testnum]); count++)
-+        SHA512(buf, lengths[testnum], sha512);
-+    return count;
-+}
-+
-+#ifndef OPENSSL_NO_WHIRLPOOL
-+static int WHIRLPOOL_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH];
-+    int count;
-+    for (count = 0; COND(c[D_WHIRLPOOL][testnum]); count++)
-+        WHIRLPOOL(buf, lengths[testnum], whirlpool);
-+    return count;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_RMD160
-+static int EVP_Digest_RMD160_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
-+    int count;
-+    for (count = 0; COND(c[D_RMD160][testnum]); count++) {
-+        if (!EVP_Digest(buf, (size_t)lengths[testnum], &(rmd160[0]),
-+                NULL, EVP_ripemd160(), NULL))
-+            return -1;
-+    }
-+    return count;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_RC4
-+static RC4_KEY rc4_ks;
-+static int RC4_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    int count;
-+    for (count = 0; COND(c[D_RC4][testnum]); count++)
-+        RC4(&rc4_ks, (size_t)lengths[testnum], buf, buf);
-+    return count;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_DES
-+static unsigned char DES_iv[8];
-+static DES_key_schedule sch;
-+static DES_key_schedule sch2;
-+static DES_key_schedule sch3;
-+static int DES_ncbc_encrypt_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    int count;
-+    for (count = 0; COND(c[D_CBC_DES][testnum]); count++)
-+        DES_ncbc_encrypt(buf, buf, lengths[testnum], &sch,
-+                &DES_iv, DES_ENCRYPT);
-+    return count;
-+}
-+
-+static int DES_ede3_cbc_encrypt_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    int count;
-+    for (count = 0; COND(c[D_EDE3_DES][testnum]); count++)
-+        DES_ede3_cbc_encrypt(buf, buf, lengths[testnum],
-+                &sch, &sch2, &sch3,
-+                &DES_iv, DES_ENCRYPT);
-+    return count;
-+}
-+#endif
-+
-+#define MAX_BLOCK_SIZE 128
-+
-+static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
-+static AES_KEY aes_ks1, aes_ks2, aes_ks3;
-+static int AES_cbc_128_encrypt_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    int count;
-+    for (count = 0; COND(c[D_CBC_128_AES][testnum]); count++)
-+        AES_cbc_encrypt(buf, buf,
-+                (size_t)lengths[testnum], &aes_ks1,
-+                iv, AES_ENCRYPT);
-+    return count;
-+}
-+
-+static int AES_cbc_192_encrypt_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    int count;
-+    for (count = 0; COND(c[D_CBC_192_AES][testnum]); count++)
-+        AES_cbc_encrypt(buf, buf,
-+                (size_t)lengths[testnum], &aes_ks2,
-+                iv, AES_ENCRYPT);
-+    return count;
-+}
-+
-+static int AES_cbc_256_encrypt_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    int count;
-+    for (count = 0; COND(c[D_CBC_256_AES][testnum]); count++)
-+        AES_cbc_encrypt(buf, buf,
-+                (size_t)lengths[testnum], &aes_ks3,
-+                iv, AES_ENCRYPT);
-+    return count;
-+}
-+
-+static int AES_ige_128_encrypt_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char *buf2 = tempargs->buf2;
-+    int count;
-+    for (count = 0; COND(c[D_IGE_128_AES][testnum]); count++)
-+        AES_ige_encrypt(buf, buf2,
-+                (size_t)lengths[testnum], &aes_ks1,
-+                iv, AES_ENCRYPT);
-+    return count;
-+}
-+
-+static int AES_ige_192_encrypt_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char *buf2 = tempargs->buf2;
-+    int count;
-+    for (count = 0; COND(c[D_IGE_192_AES][testnum]); count++)
-+        AES_ige_encrypt(buf, buf2,
-+                (size_t)lengths[testnum], &aes_ks2,
-+                iv, AES_ENCRYPT);
-+    return count;
-+}
-+
-+static int AES_ige_256_encrypt_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char *buf2 = tempargs->buf2;
-+    int count;
-+    for (count = 0; COND(c[D_IGE_256_AES][testnum]); count++)
-+        AES_ige_encrypt(buf, buf2,
-+                (size_t)lengths[testnum], &aes_ks3,
-+                iv, AES_ENCRYPT);
-+    return count;
-+}
-+
-+static int CRYPTO_gcm128_aad_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    GCM128_CONTEXT *gcm_ctx = tempargs->gcm_ctx;
-+    int count;
-+    for (count = 0; COND(c[D_GHASH][testnum]); count++)
-+        CRYPTO_gcm128_aad(gcm_ctx, buf, lengths[testnum]);
-+    return count;
-+}
-+
-+static long save_count = 0;
-+static int decrypt = 0;
-+static int EVP_Update_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    EVP_CIPHER_CTX *ctx = tempargs->ctx;
-+    int outl, count;
-+#ifndef SIGALRM
-+    int nb_iter = save_count * 4 * lengths[0] / lengths[testnum];
-+#endif
-+    if (decrypt)
-+        for (count = 0; COND(nb_iter); count++)
-+            EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
-+    else
-+        for (count = 0; COND(nb_iter); count++)
-+            EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
-+    if (decrypt)
-+        EVP_DecryptFinal_ex(ctx, buf, &outl);
-+    else
-+        EVP_EncryptFinal_ex(ctx, buf, &outl);
-+    return count;
-+}
-+
-+static const EVP_MD *evp_md = NULL;
-+static int EVP_Digest_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char md[EVP_MAX_MD_SIZE];
-+    int count;
-+#ifndef SIGALRM
-+    int nb_iter = save_count * 4 * lengths[0] / lengths[testnum];
-+#endif
-+
-+    for (count = 0; COND(nb_iter); count++) {
-+        if (!EVP_Digest(buf, lengths[testnum], md, NULL, evp_md, NULL))
-+            return -1;
-+    }
-+    return count;
-+}
-+
-+#ifndef OPENSSL_NO_RSA
-+static long rsa_c[RSA_NUM][2];  /* # RSA iteration test */
-+
-+static int RSA_sign_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char *buf2 = tempargs->buf2;
-+    unsigned int *rsa_num = &tempargs->siglen;
-+    RSA **rsa_key = tempargs->rsa_key;
-+    int ret, count;
-+    for (count = 0; COND(rsa_c[testnum][0]); count++) {
-+        ret = RSA_sign(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[testnum]);
-+        if (ret == 0) {
-+            BIO_printf(bio_err, "RSA sign failure\n");
-+            ERR_print_errors(bio_err);
-+            count = -1;
-+            break;
-+        }
-+    }
-+    return count;
-+}
-+
-+static int RSA_verify_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char *buf2 = tempargs->buf2;
-+    unsigned int rsa_num = tempargs->siglen;
-+    RSA **rsa_key = tempargs->rsa_key;
-+    int ret, count;
-+    for (count = 0; COND(rsa_c[testnum][1]); count++) {
-+        ret = RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[testnum]);
-+        if (ret <= 0) {
-+            BIO_printf(bio_err, "RSA verify failure\n");
-+            ERR_print_errors(bio_err);
-+            count = -1;
-+            break;
-+        }
-+    }
-+    return count;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_DSA
-+static long dsa_c[DSA_NUM][2];
-+static int DSA_sign_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char *buf2 = tempargs->buf2;
-+    DSA **dsa_key = tempargs->dsa_key;
-+    unsigned int *siglen = &tempargs->siglen;
-+    int ret, count;
-+    for (count = 0; COND(dsa_c[testnum][0]); count++) {
-+        ret = DSA_sign(0, buf, 20, buf2, siglen, dsa_key[testnum]);
-+        if (ret == 0) {
-+            BIO_printf(bio_err, "DSA sign failure\n");
-+            ERR_print_errors(bio_err);
-+            count = -1;
-+            break;
-+        }
-+    }
-+    return count;
-+}
-+
-+static int DSA_verify_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    unsigned char *buf2 = tempargs->buf2;
-+    DSA **dsa_key = tempargs->dsa_key;
-+    unsigned int siglen = tempargs->siglen;
-+    int ret, count;
-+    for (count = 0; COND(dsa_c[testnum][1]); count++) {
-+        ret = DSA_verify(0, buf, 20, buf2, siglen, dsa_key[testnum]);
-+        if (ret <= 0) {
-+            BIO_printf(bio_err, "DSA verify failure\n");
-+            ERR_print_errors(bio_err);
-+            count = -1;
-+            break;
-+        }
-+    }
-+    return count;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_EC
-+static long ecdsa_c[EC_NUM][2];
-+static int ECDSA_sign_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    EC_KEY **ecdsa = tempargs->ecdsa;
-+    unsigned char *ecdsasig = tempargs->buf2;
-+    unsigned int *ecdsasiglen = &tempargs->siglen;
-+    int ret, count;
-+    for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
-+        ret = ECDSA_sign(0, buf, 20,
-+                ecdsasig, ecdsasiglen, ecdsa[testnum]);
-+        if (ret == 0) {
-+            BIO_printf(bio_err, "ECDSA sign failure\n");
-+            ERR_print_errors(bio_err);
-+            count = -1;
-+            break;
-+        }
-+    }
-+    return count;
-+}
-+
-+static int ECDSA_verify_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    unsigned char *buf = tempargs->buf;
-+    EC_KEY **ecdsa = tempargs->ecdsa;
-+    unsigned char *ecdsasig = tempargs->buf2;
-+    unsigned int ecdsasiglen = tempargs->siglen;
-+    int ret, count;
-+    for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
-+        ret = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen,
-+                ecdsa[testnum]);
-+        if (ret != 1) {
-+            BIO_printf(bio_err, "ECDSA verify failure\n");
-+            ERR_print_errors(bio_err);
-+            count = -1;
-+            break;
-+        }
-+    }
-+    return count;
-+}
-+
-+/* ******************************************************************** */
-+static long ecdh_c[EC_NUM][1];
-+
-+static int ECDH_compute_key_loop(void *args)
-+{
-+    loopargs_t *tempargs = *(loopargs_t **)args;
-+    EC_KEY **ecdh_a = tempargs->ecdh_a;
-+    EC_KEY **ecdh_b = tempargs->ecdh_b;
-+    unsigned char *secret_a = tempargs->secret_a;
-+    int count;
-+    size_t outlen = tempargs->outlen;
-+    kdf_fn kdf = tempargs->kdf;
-+
-+    for (count = 0; COND(ecdh_c[testnum][0]); count++) {
-+        ECDH_compute_key(secret_a, outlen,
-+                EC_KEY_get0_public_key(ecdh_b[testnum]),
-+                ecdh_a[testnum], kdf);
-+    }
-+    return count;
-+}
-+
-+static const size_t KDF1_SHA1_len = 20;
-+static void *KDF1_SHA1(const void *in, size_t inlen, void *out,
-+                       size_t *outlen)
-+{
-+    if (*outlen < SHA_DIGEST_LENGTH)
-+        return NULL;
-+    *outlen = SHA_DIGEST_LENGTH;
-+    return SHA1(in, inlen, out);
-+}
-+#endif                          /* OPENSSL_NO_EC */
-+
-+static int run_benchmark(int async_jobs,
-+                         int (*loop_function)(void *), loopargs_t *loopargs)
-+{
-+    int job_op_count = 0;
-+    int total_op_count = 0;
-+    int num_inprogress = 0;
-+    int error = 0, i = 0, ret = 0;
-+    OSSL_ASYNC_FD job_fd = 0;
-+    size_t num_job_fds = 0;
-+
-+    run = 1;
-+
-+    if (async_jobs == 0) {
-+        return loop_function((void *)&loopargs);
-+    }
-+
-+    for (i = 0; i < async_jobs && !error; i++) {
-+        loopargs_t *looparg_item = loopargs + i;
-+
-+        /* Copy pointer content (looparg_t item address) into async context */
-+        ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
-+                              &job_op_count, loop_function,
-+                              (void *)&looparg_item, sizeof(looparg_item));
-+        switch (ret) {
-+        case ASYNC_PAUSE:
-+            ++num_inprogress;
-+            break;
-+        case ASYNC_FINISH:
-+            if (job_op_count == -1) {
-+                error = 1;
-+            } else {
-+                total_op_count += job_op_count;
-+            }
-+            break;
-+        case ASYNC_NO_JOBS:
-+        case ASYNC_ERR:
-+            BIO_printf(bio_err, "Failure in the job\n");
-+            ERR_print_errors(bio_err);
-+            error = 1;
-+            break;
-+        }
-+    }
-+
-+    while (num_inprogress > 0) {
-+#if defined(OPENSSL_SYS_WINDOWS)
-+        DWORD avail = 0;
-+#elif defined(OPENSSL_SYS_UNIX)
-+        int select_result = 0;
-+        OSSL_ASYNC_FD max_fd = 0;
-+        fd_set waitfdset;
-+
-+        FD_ZERO(&waitfdset);
-+
-+        for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
-+            if (loopargs[i].inprogress_job == NULL)
-+                continue;
-+
-+            if (!ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, NULL, &num_job_fds)
-+                    || num_job_fds > 1) {
-+                BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
-+                ERR_print_errors(bio_err);
-+                error = 1;
-+                break;
-+            }
-+            ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd, &num_job_fds);
-+            FD_SET(job_fd, &waitfdset);
-+            if (job_fd > max_fd)
-+                max_fd = job_fd;
-+        }
-+
-+        if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
-+            BIO_printf(bio_err,
-+                    "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
-+                    "Decrease the value of async_jobs\n",
-+                    max_fd, FD_SETSIZE);
-+            ERR_print_errors(bio_err);
-+            error = 1;
-+            break;
-+        }
-+
-+        select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
-+        if (select_result == -1 && errno == EINTR)
-+            continue;
-+
-+        if (select_result == -1) {
-+            BIO_printf(bio_err, "Failure in the select\n");
-+            ERR_print_errors(bio_err);
-+            error = 1;
-+            break;
-+        }
-+
-+        if (select_result == 0)
-+            continue;
-+#endif
-+
-+        for (i = 0; i < async_jobs; i++) {
-+            if (loopargs[i].inprogress_job == NULL)
-+                continue;
-+
-+            if (!ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, NULL, &num_job_fds)
-+                    || num_job_fds > 1) {
-+                BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
-+                ERR_print_errors(bio_err);
-+                error = 1;
-+                break;
-+            }
-+            ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd, &num_job_fds);
-+
-+#if defined(OPENSSL_SYS_UNIX)
-+            if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
-+                continue;
-+#elif defined(OPENSSL_SYS_WINDOWS)
-+            if (num_job_fds == 1
-+                && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
-+                && avail > 0)
-+                continue;
-+#endif
-+
-+            ret = ASYNC_start_job(&loopargs[i].inprogress_job, 
-+                    loopargs[i].wait_ctx, &job_op_count, loop_function, 
-+                    (void *)(loopargs + i), sizeof(loopargs_t));
-+            switch (ret) {
-+            case ASYNC_PAUSE:
-+                break;
-+            case ASYNC_FINISH:
-+                if (job_op_count == -1) {
-+                    error = 1;
-+                } else {
-+                    total_op_count += job_op_count;
-+                }
-+                --num_inprogress;
-+                loopargs[i].inprogress_job = NULL;
-+                break;
-+            case ASYNC_NO_JOBS:
-+            case ASYNC_ERR:
-+                --num_inprogress;
-+                loopargs[i].inprogress_job = NULL;
-+                BIO_printf(bio_err, "Failure in the job\n");
-+                ERR_print_errors(bio_err);
-+                error = 1;
-+                break;
-+            }
-+        }
-+    }
-+
-+    return error ? -1 : total_op_count;
-+}
-+
-+int speed_main(int argc, char **argv)
-+{
-+    ENGINE *e = NULL;
-+    loopargs_t *loopargs = NULL;
-+    int async_init = 0;
-+    int loopargs_len = 0;
-+    char *prog;
-+    const char *engine_id = NULL;
-+    const EVP_CIPHER *evp_cipher = NULL;
-+    double d = 0.0;
-+    OPTION_CHOICE o;
-+    int multiblock = 0, pr_header = 0;
-+    int doit[ALGOR_NUM] = { 0 };
-+    int ret = 1, i, k, misalign = 0;
-+    long count = 0;
-+#ifndef NO_FORK
-+    int multi = 0;
-+#endif
-+    int async_jobs = 0;
-+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) \
-+    || !defined(OPENSSL_NO_EC)
-+    long rsa_count = 1;
-+#endif
-+
-+    /* What follows are the buffers and key material. */
-+#ifndef OPENSSL_NO_RC5
-+    RC5_32_KEY rc5_ks;
-+#endif
-+#ifndef OPENSSL_NO_RC2
-+    RC2_KEY rc2_ks;
-+#endif
-+#ifndef OPENSSL_NO_IDEA
-+    IDEA_KEY_SCHEDULE idea_ks;
-+#endif
-+#ifndef OPENSSL_NO_SEED
-+    SEED_KEY_SCHEDULE seed_ks;
-+#endif
-+#ifndef OPENSSL_NO_BF
-+    BF_KEY bf_ks;
-+#endif
-+#ifndef OPENSSL_NO_CAST
-+    CAST_KEY cast_ks;
-+#endif
-+    static const unsigned char key16[16] = {
-+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
-+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12
-+    };
-+    static const unsigned char key24[24] = {
-+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
-+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
-+        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34
-+    };
-+    static const unsigned char key32[32] = {
-+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
-+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
-+        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
-+        0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
-+    };
-+#ifndef OPENSSL_NO_CAMELLIA
-+    static const unsigned char ckey24[24] = {
-+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
-+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
-+        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34
-+    };
-+    static const unsigned char ckey32[32] = {
-+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
-+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
-+        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
-+        0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
-+    };
-+    CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3;
-+#endif
-+#ifndef OPENSSL_NO_DES
-+    static DES_cblock key = {
-+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0
-+    };
-+    static DES_cblock key2 = {
-+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12
-+    };
-+    static DES_cblock key3 = {
-+        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34
-+    };
-+#endif
-+#ifndef OPENSSL_NO_RSA
-+    static const unsigned int rsa_bits[RSA_NUM] = {
-+        512, 1024, 2048, 3072, 4096, 7680, 15360
-+    };
-+    static const unsigned char *rsa_data[RSA_NUM] = {
-+        test512, test1024, test2048, test3072, test4096, test7680, test15360
-+    };
-+    static const int rsa_data_length[RSA_NUM] = {
-+        sizeof(test512), sizeof(test1024),
-+        sizeof(test2048), sizeof(test3072),
-+        sizeof(test4096), sizeof(test7680),
-+        sizeof(test15360)
-+    };
-+    int rsa_doit[RSA_NUM] = { 0 };
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
-+    int dsa_doit[DSA_NUM] = { 0 };
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    /*
-+     * We only test over the following curves as they are representative, To
-+     * add tests over more curves, simply add the curve NID and curve name to
-+     * the following arrays and increase the EC_NUM value accordingly.
-+     */
-+    static const unsigned int test_curves[EC_NUM] = {
-+        /* Prime Curves */
-+        NID_secp160r1, NID_X9_62_prime192v1, NID_secp224r1,
-+        NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1,
-+        /* Binary Curves */
-+        NID_sect163k1, NID_sect233k1, NID_sect283k1,
-+        NID_sect409k1, NID_sect571k1, NID_sect163r2,
-+        NID_sect233r1, NID_sect283r1, NID_sect409r1,
-+        NID_sect571r1,
-+        /* Other */
-+        NID_X25519
-+    };
-+    static const char *test_curves_names[EC_NUM] = {
-+        /* Prime Curves */
-+        "secp160r1", "nistp192", "nistp224",
-+        "nistp256", "nistp384", "nistp521",
-+        /* Binary Curves */
-+        "nistk163", "nistk233", "nistk283",
-+        "nistk409", "nistk571", "nistb163",
-+        "nistb233", "nistb283", "nistb409",
-+        "nistb571",
-+        /* Other */
-+        "X25519"
-+    };
-+    static const int test_curves_bits[EC_NUM] = {
-+        160, 192, 224,
-+        256, 384, 521,
-+        163, 233, 283,
-+        409, 571, 163,
-+        233, 283, 409,
-+        571, 253 /* X25519 */
-+    };
-+
-+    int ecdsa_doit[EC_NUM] = { 0 };
-+    int ecdh_doit[EC_NUM] = { 0 };
-+#endif                          /* ndef OPENSSL_NO_EC */
-+
-+    prog = opt_init(argc, argv, speed_options);
-+    while ((o = opt_next()) != OPT_EOF) {
-+        switch (o) {
-+        case OPT_EOF:
-+        case OPT_ERR:
-+ opterr:
-+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-+            goto end;
-+        case OPT_HELP:
-+            opt_help(speed_options);
-+            ret = 0;
-+            goto end;
-+        case OPT_ELAPSED:
-+            usertime = 0;
-+            break;
-+        case OPT_EVP:
-+            evp_cipher = EVP_get_cipherbyname(opt_arg());
-+            if (evp_cipher == NULL)
-+                evp_md = EVP_get_digestbyname(opt_arg());
-+            if (evp_cipher == NULL && evp_md == NULL) {
-+                BIO_printf(bio_err,
-+                           "%s: %s is an unknown cipher or digest\n",
-+                           prog, opt_arg());
-+                goto end;
-+            }
-+            doit[D_EVP] = 1;
-+            break;
-+        case OPT_DECRYPT:
-+            decrypt = 1;
-+            break;
-+        case OPT_ENGINE:
-+            /*
-+             * In a forked execution, an engine might need to be
-+             * initialised by each child process, not by the parent.
-+             * So store the name here and run setup_engine() later on.
-+             */
-+            engine_id = opt_arg();
-+            break;
-+        case OPT_MULTI:
-+#ifndef NO_FORK
-+            multi = atoi(opt_arg());
-+#endif
-+            break;
-+        case OPT_ASYNCJOBS:
-+#ifndef OPENSSL_NO_ASYNC
-+            async_jobs = atoi(opt_arg());
-+            if (!ASYNC_is_capable()) {
-+                BIO_printf(bio_err,
-+                           "%s: async_jobs specified but async not supported\n",
-+                           prog);
-+                goto opterr;
-+            }
-+#endif
-+            break;
-+        case OPT_MISALIGN:
-+            if (!opt_int(opt_arg(), &misalign))
-+                goto end;
-+            if (misalign > MISALIGN) {
-+                BIO_printf(bio_err,
-+                           "%s: Maximum offset is %d\n", prog, MISALIGN);
-+                goto opterr;
-+            }
-+            break;
-+        case OPT_MR:
-+            mr = 1;
-+            break;
-+        case OPT_MB:
-+            multiblock = 1;
-+#ifdef OPENSSL_NO_MULTIBLOCK
-+            BIO_printf(bio_err,
-+                       "%s: -mb specified but multi-block support is disabled\n",
-+                       prog);
-+            goto end;
-+#endif
-+            break;
-+        }
-+    }
-+    argc = opt_num_rest();
-+    argv = opt_rest();
-+
-+    /* Remaining arguments are algorithms. */
-+    for ( ; *argv; argv++) {
-+        if (found(*argv, doit_choices, &i)) {
-+            doit[i] = 1;
-+            continue;
-+        }
-+#ifndef OPENSSL_NO_DES
-+        if (strcmp(*argv, "des") == 0) {
-+            doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
-+            continue;
-+        }
-+#endif
-+        if (strcmp(*argv, "sha") == 0) {
-+            doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
-+            continue;
-+        }
-+#ifndef OPENSSL_NO_RSA
-+# ifndef RSA_NULL
-+        if (strcmp(*argv, "openssl") == 0) {
-+            RSA_set_default_method(RSA_PKCS1_OpenSSL());
-+            continue;
-+        }
-+# endif
-+        if (strcmp(*argv, "rsa") == 0) {
-+            rsa_doit[R_RSA_512] = rsa_doit[R_RSA_1024] =
-+                rsa_doit[R_RSA_2048] = rsa_doit[R_RSA_3072] =
-+                rsa_doit[R_RSA_4096] = rsa_doit[R_RSA_7680] =
-+                rsa_doit[R_RSA_15360] = 1;
-+            continue;
-+        }
-+        if (found(*argv, rsa_choices, &i)) {
-+            rsa_doit[i] = 1;
-+            continue;
-+        }
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+        if (strcmp(*argv, "dsa") == 0) {
-+            dsa_doit[R_DSA_512] = dsa_doit[R_DSA_1024] =
-+                dsa_doit[R_DSA_2048] = 1;
-+            continue;
-+        }
-+        if (found(*argv, dsa_choices, &i)) {
-+            dsa_doit[i] = 2;
-+            continue;
-+        }
-+#endif
-+        if (strcmp(*argv, "aes") == 0) {
-+            doit[D_CBC_128_AES] = doit[D_CBC_192_AES] =
-+                doit[D_CBC_256_AES] = 1;
-+            continue;
-+        }
-+#ifndef OPENSSL_NO_CAMELLIA
-+        if (strcmp(*argv, "camellia") == 0) {
-+            doit[D_CBC_128_CML] = doit[D_CBC_192_CML] =
-+                doit[D_CBC_256_CML] = 1;
-+            continue;
-+        }
-+#endif
-+#ifndef OPENSSL_NO_EC
-+        if (strcmp(*argv, "ecdsa") == 0) {
-+            for (i = 0; i < EC_NUM; i++)
-+                ecdsa_doit[i] = 1;
-+            continue;
-+        }
-+        if (found(*argv, ecdsa_choices, &i)) {
-+            ecdsa_doit[i] = 2;
-+            continue;
-+        }
-+        if (strcmp(*argv, "ecdh") == 0) {
-+            for (i = 0; i < EC_NUM; i++)
-+                ecdh_doit[i] = 1;
-+            continue;
-+        }
-+        if (found(*argv, ecdh_choices, &i)) {
-+            ecdh_doit[i] = 2;
-+            continue;
-+        }
-+#endif
-+        BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, *argv);
-+        goto end;
-+    }
-+
-+    /* Initialize the job pool if async mode is enabled */
-+    if (async_jobs > 0) {
-+        async_init = ASYNC_init_thread(async_jobs, async_jobs);
-+        if (!async_init) {
-+            BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
-+            goto end;
-+        }
-+    }
-+
-+    loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
-+    loopargs = app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
-+    memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
-+
-+    for (i = 0; i < loopargs_len; i++) {
-+        if (async_jobs > 0) {
-+            loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
-+            if (loopargs[i].wait_ctx == NULL) {
-+                BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
-+                goto end;
-+            }
-+        }
-+
-+        loopargs[i].buf_malloc = app_malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1, "input buffer");
-+        loopargs[i].buf2_malloc = app_malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1, "input buffer");
-+        /* Align the start of buffers on a 64 byte boundary */
-+        loopargs[i].buf = loopargs[i].buf_malloc + misalign;
-+        loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
-+#ifndef OPENSSL_NO_EC
-+        loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
-+        loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
-+#endif
-+    }
-+
-+#ifndef NO_FORK
-+    if (multi && do_multi(multi))
-+        goto show_res;
-+#endif
-+
-+    /* Initialize the engine after the fork */
-+    e = setup_engine(engine_id, 0);
-+
-+    /* No parameters; turn on everything. */
-+    if ((argc == 0) && !doit[D_EVP]) {
-+        for (i = 0; i < ALGOR_NUM; i++)
-+            if (i != D_EVP)
-+                doit[i] = 1;
-+#ifndef OPENSSL_NO_RSA
-+        for (i = 0; i < RSA_NUM; i++)
-+            rsa_doit[i] = 1;
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+        for (i = 0; i < DSA_NUM; i++)
-+            dsa_doit[i] = 1;
-+#endif
-+#ifndef OPENSSL_NO_EC
-+        for (i = 0; i < EC_NUM; i++)
-+            ecdsa_doit[i] = 1;
-+        for (i = 0; i < EC_NUM; i++)
-+            ecdh_doit[i] = 1;
-+#endif
-+    }
-+    for (i = 0; i < ALGOR_NUM; i++)
-+        if (doit[i])
-+            pr_header++;
-+
-+    if (usertime == 0 && !mr)
-+        BIO_printf(bio_err,
-+                   "You have chosen to measure elapsed time "
-+                   "instead of user CPU time.\n");
-+
-+#ifndef OPENSSL_NO_RSA
-+    for (i = 0; i < loopargs_len; i++) {
-+        for (k = 0; k < RSA_NUM; k++) {
-+            const unsigned char *p;
-+
-+            p = rsa_data[k];
-+            loopargs[i].rsa_key[k] = d2i_RSAPrivateKey(NULL, &p, rsa_data_length[k]);
-+            if (loopargs[i].rsa_key[k] == NULL) {
-+                BIO_printf(bio_err, "internal error loading RSA key number %d\n",
-+                        k);
-+                goto end;
-+            }
-+        }
-+    }
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    for (i = 0; i < loopargs_len; i++) {
-+        loopargs[i].dsa_key[0] = get_dsa512();
-+        loopargs[i].dsa_key[1] = get_dsa1024();
-+        loopargs[i].dsa_key[2] = get_dsa2048();
-+    }
-+#endif
-+#ifndef OPENSSL_NO_DES
-+    DES_set_key_unchecked(&key, &sch);
-+    DES_set_key_unchecked(&key2, &sch2);
-+    DES_set_key_unchecked(&key3, &sch3);
-+#endif
-+    AES_set_encrypt_key(key16, 128, &aes_ks1);
-+    AES_set_encrypt_key(key24, 192, &aes_ks2);
-+    AES_set_encrypt_key(key32, 256, &aes_ks3);
-+#ifndef OPENSSL_NO_CAMELLIA
-+    Camellia_set_key(key16, 128, &camellia_ks1);
-+    Camellia_set_key(ckey24, 192, &camellia_ks2);
-+    Camellia_set_key(ckey32, 256, &camellia_ks3);
-+#endif
-+#ifndef OPENSSL_NO_IDEA
-+    IDEA_set_encrypt_key(key16, &idea_ks);
-+#endif
-+#ifndef OPENSSL_NO_SEED
-+    SEED_set_key(key16, &seed_ks);
-+#endif
-+#ifndef OPENSSL_NO_RC4
-+    RC4_set_key(&rc4_ks, 16, key16);
-+#endif
-+#ifndef OPENSSL_NO_RC2
-+    RC2_set_key(&rc2_ks, 16, key16, 128);
-+#endif
-+#ifndef OPENSSL_NO_RC5
-+    RC5_32_set_key(&rc5_ks, 16, key16, 12);
-+#endif
-+#ifndef OPENSSL_NO_BF
-+    BF_set_key(&bf_ks, 16, key16);
-+#endif
-+#ifndef OPENSSL_NO_CAST
-+    CAST_set_key(&cast_ks, 16, key16);
-+#endif
-+#ifndef SIGALRM
-+# ifndef OPENSSL_NO_DES
-+    BIO_printf(bio_err, "First we calculate the approximate speed ...\n");
-+    count = 10;
-+    do {
-+        long it;
-+        count *= 2;
-+        Time_F(START);
-+        for (it = count; it; it--)
-+            DES_ecb_encrypt((DES_cblock *)loopargs[0].buf,
-+                            (DES_cblock *)loopargs[0].buf, &sch, DES_ENCRYPT);
-+        d = Time_F(STOP);
-+    } while (d < 3);
-+    save_count = count;
-+    c[D_MD2][0] = count / 10;
-+    c[D_MDC2][0] = count / 10;
-+    c[D_MD4][0] = count;
-+    c[D_MD5][0] = count;
-+    c[D_HMAC][0] = count;
-+    c[D_SHA1][0] = count;
-+    c[D_RMD160][0] = count;
-+    c[D_RC4][0] = count * 5;
-+    c[D_CBC_DES][0] = count;
-+    c[D_EDE3_DES][0] = count / 3;
-+    c[D_CBC_IDEA][0] = count;
-+    c[D_CBC_SEED][0] = count;
-+    c[D_CBC_RC2][0] = count;
-+    c[D_CBC_RC5][0] = count;
-+    c[D_CBC_BF][0] = count;
-+    c[D_CBC_CAST][0] = count;
-+    c[D_CBC_128_AES][0] = count;
-+    c[D_CBC_192_AES][0] = count;
-+    c[D_CBC_256_AES][0] = count;
-+    c[D_CBC_128_CML][0] = count;
-+    c[D_CBC_192_CML][0] = count;
-+    c[D_CBC_256_CML][0] = count;
-+    c[D_SHA256][0] = count;
-+    c[D_SHA512][0] = count;
-+    c[D_WHIRLPOOL][0] = count;
-+    c[D_IGE_128_AES][0] = count;
-+    c[D_IGE_192_AES][0] = count;
-+    c[D_IGE_256_AES][0] = count;
-+    c[D_GHASH][0] = count;
-+
-+    for (i = 1; i < SIZE_NUM; i++) {
-+        long l0, l1;
-+
-+        l0 = (long)lengths[0];
-+        l1 = (long)lengths[i];
-+
-+        c[D_MD2][i] = c[D_MD2][0] * 4 * l0 / l1;
-+        c[D_MDC2][i] = c[D_MDC2][0] * 4 * l0 / l1;
-+        c[D_MD4][i] = c[D_MD4][0] * 4 * l0 / l1;
-+        c[D_MD5][i] = c[D_MD5][0] * 4 * l0 / l1;
-+        c[D_HMAC][i] = c[D_HMAC][0] * 4 * l0 / l1;
-+        c[D_SHA1][i] = c[D_SHA1][0] * 4 * l0 / l1;
-+        c[D_RMD160][i] = c[D_RMD160][0] * 4 * l0 / l1;
-+        c[D_SHA256][i] = c[D_SHA256][0] * 4 * l0 / l1;
-+        c[D_SHA512][i] = c[D_SHA512][0] * 4 * l0 / l1;
-+        c[D_WHIRLPOOL][i] = c[D_WHIRLPOOL][0] * 4 * l0 / l1;
-+        c[D_GHASH][i] = c[D_GHASH][0] * 4 * l0 / l1;
-+
-+        l0 = (long)lengths[i - 1];
-+
-+        c[D_RC4][i] = c[D_RC4][i - 1] * l0 / l1;
-+        c[D_CBC_DES][i] = c[D_CBC_DES][i - 1] * l0 / l1;
-+        c[D_EDE3_DES][i] = c[D_EDE3_DES][i - 1] * l0 / l1;
-+        c[D_CBC_IDEA][i] = c[D_CBC_IDEA][i - 1] * l0 / l1;
-+        c[D_CBC_SEED][i] = c[D_CBC_SEED][i - 1] * l0 / l1;
-+        c[D_CBC_RC2][i] = c[D_CBC_RC2][i - 1] * l0 / l1;
-+        c[D_CBC_RC5][i] = c[D_CBC_RC5][i - 1] * l0 / l1;
-+        c[D_CBC_BF][i] = c[D_CBC_BF][i - 1] * l0 / l1;
-+        c[D_CBC_CAST][i] = c[D_CBC_CAST][i - 1] * l0 / l1;
-+        c[D_CBC_128_AES][i] = c[D_CBC_128_AES][i - 1] * l0 / l1;
-+        c[D_CBC_192_AES][i] = c[D_CBC_192_AES][i - 1] * l0 / l1;
-+        c[D_CBC_256_AES][i] = c[D_CBC_256_AES][i - 1] * l0 / l1;
-+        c[D_CBC_128_CML][i] = c[D_CBC_128_CML][i - 1] * l0 / l1;
-+        c[D_CBC_192_CML][i] = c[D_CBC_192_CML][i - 1] * l0 / l1;
-+        c[D_CBC_256_CML][i] = c[D_CBC_256_CML][i - 1] * l0 / l1;
-+        c[D_IGE_128_AES][i] = c[D_IGE_128_AES][i - 1] * l0 / l1;
-+        c[D_IGE_192_AES][i] = c[D_IGE_192_AES][i - 1] * l0 / l1;
-+        c[D_IGE_256_AES][i] = c[D_IGE_256_AES][i - 1] * l0 / l1;
-+    }
-+
-+#  ifndef OPENSSL_NO_RSA
-+    rsa_c[R_RSA_512][0] = count / 2000;
-+    rsa_c[R_RSA_512][1] = count / 400;
-+    for (i = 1; i < RSA_NUM; i++) {
-+        rsa_c[i][0] = rsa_c[i - 1][0] / 8;
-+        rsa_c[i][1] = rsa_c[i - 1][1] / 4;
-+        if (rsa_doit[i] <= 1 && rsa_c[i][0] == 0)
-+            rsa_doit[i] = 0;
-+        else {
-+            if (rsa_c[i][0] == 0) {
-+                rsa_c[i][0] = 1;            /* Set minimum iteration Nb to 1. */
-+                rsa_c[i][1] = 20;
-+            }
-+        }
-+    }
-+#  endif
-+
-+#  ifndef OPENSSL_NO_DSA
-+    dsa_c[R_DSA_512][0] = count / 1000;
-+    dsa_c[R_DSA_512][1] = count / 1000 / 2;
-+    for (i = 1; i < DSA_NUM; i++) {
-+        dsa_c[i][0] = dsa_c[i - 1][0] / 4;
-+        dsa_c[i][1] = dsa_c[i - 1][1] / 4;
-+        if (dsa_doit[i] <= 1 && dsa_c[i][0] == 0)
-+            dsa_doit[i] = 0;
-+        else {
-+            if (dsa_c[i][0] == 0) {
-+                dsa_c[i][0] = 1;            /* Set minimum iteration Nb to 1. */
-+                dsa_c[i][1] = 1;
-+            }
-+        }
-+    }
-+#  endif
-+
-+#  ifndef OPENSSL_NO_EC
-+    ecdsa_c[R_EC_P160][0] = count / 1000;
-+    ecdsa_c[R_EC_P160][1] = count / 1000 / 2;
-+    for (i = R_EC_P192; i <= R_EC_P521; i++) {
-+        ecdsa_c[i][0] = ecdsa_c[i - 1][0] / 2;
-+        ecdsa_c[i][1] = ecdsa_c[i - 1][1] / 2;
-+        if (ecdsa_doit[i] <= 1 && ecdsa_c[i][0] == 0)
-+            ecdsa_doit[i] = 0;
-+        else {
-+            if (ecdsa_c[i][0] == 0) {
-+                ecdsa_c[i][0] = 1;
-+                ecdsa_c[i][1] = 1;
-+            }
-+        }
-+    }
-+    ecdsa_c[R_EC_K163][0] = count / 1000;
-+    ecdsa_c[R_EC_K163][1] = count / 1000 / 2;
-+    for (i = R_EC_K233; i <= R_EC_K571; i++) {
-+        ecdsa_c[i][0] = ecdsa_c[i - 1][0] / 2;
-+        ecdsa_c[i][1] = ecdsa_c[i - 1][1] / 2;
-+        if (ecdsa_doit[i] <= 1 && ecdsa_c[i][0] == 0)
-+            ecdsa_doit[i] = 0;
-+        else {
-+            if (ecdsa_c[i][0] == 0) {
-+                ecdsa_c[i][0] = 1;
-+                ecdsa_c[i][1] = 1;
-+            }
-+        }
-+    }
-+    ecdsa_c[R_EC_B163][0] = count / 1000;
-+    ecdsa_c[R_EC_B163][1] = count / 1000 / 2;
-+    for (i = R_EC_B233; i <= R_EC_B571; i++) {
-+        ecdsa_c[i][0] = ecdsa_c[i - 1][0] / 2;
-+        ecdsa_c[i][1] = ecdsa_c[i - 1][1] / 2;
-+        if (ecdsa_doit[i] <= 1 && ecdsa_c[i][0] == 0)
-+            ecdsa_doit[i] = 0;
-+        else {
-+            if (ecdsa_c[i][0] == 0) {
-+                ecdsa_c[i][0] = 1;
-+                ecdsa_c[i][1] = 1;
-+            }
-+        }
-+    }
-+
-+    ecdh_c[R_EC_P160][0] = count / 1000;
-+    for (i = R_EC_P192; i <= R_EC_P521; i++) {
-+        ecdh_c[i][0] = ecdh_c[i - 1][0] / 2;
-+        if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0)
-+            ecdh_doit[i] = 0;
-+        else {
-+            if (ecdh_c[i][0] == 0) {
-+                ecdh_c[i][0] = 1;
-+            }
-+        }
-+    }
-+    ecdh_c[R_EC_K163][0] = count / 1000;
-+    for (i = R_EC_K233; i <= R_EC_K571; i++) {
-+        ecdh_c[i][0] = ecdh_c[i - 1][0] / 2;
-+        if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0)
-+            ecdh_doit[i] = 0;
-+        else {
-+            if (ecdh_c[i][0] == 0) {
-+                ecdh_c[i][0] = 1;
-+            }
-+        }
-+    }
-+    ecdh_c[R_EC_B163][0] = count / 1000;
-+    for (i = R_EC_B233; i <= R_EC_B571; i++) {
-+        ecdh_c[i][0] = ecdh_c[i - 1][0] / 2;
-+        if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0)
-+            ecdh_doit[i] = 0;
-+        else {
-+            if (ecdh_c[i][0] == 0) {
-+                ecdh_c[i][0] = 1;
-+            }
-+        }
-+    }
-+#  endif
-+
-+# else
-+/* not worth fixing */
-+#  error "You cannot disable DES on systems without SIGALRM."
-+# endif                        /* OPENSSL_NO_DES */
-+#else
-+# ifndef _WIN32
-+    signal(SIGALRM, sig_done);
-+# endif
-+#endif                         /* SIGALRM */
-+
-+#ifndef OPENSSL_NO_MD2
-+    if (doit[D_MD2]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_MD2, testnum, count, d);
-+        }
-+    }
-+#endif
-+#ifndef OPENSSL_NO_MDC2
-+    if (doit[D_MDC2]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_MDC2, testnum, count, d);
-+        }
-+    }
-+#endif
-+
-+#ifndef OPENSSL_NO_MD4
-+    if (doit[D_MD4]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_MD4, testnum, count, d);
-+        }
-+    }
-+#endif
-+
-+#ifndef OPENSSL_NO_MD5
-+    if (doit[D_MD5]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, MD5_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_MD5, testnum, count, d);
-+        }
-+    }
-+
-+    if (doit[D_HMAC]) {
-+        static const char hmac_key[] = "This is a key...";
-+        int len = strlen(hmac_key);
-+
-+        for (i = 0; i < loopargs_len; i++) {
-+            loopargs[i].hctx = HMAC_CTX_new();
-+            if (loopargs[i].hctx == NULL) {
-+                BIO_printf(bio_err, "HMAC malloc failure, exiting...");
-+                exit(1);
-+            }
-+
-+            HMAC_Init_ex(loopargs[i].hctx, hmac_key, len, EVP_md5(), NULL);
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, HMAC_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_HMAC, testnum, count, d);
-+        }
-+        for (i = 0; i < loopargs_len; i++) {
-+            HMAC_CTX_free(loopargs[i].hctx);
-+        }
-+    }
-+#endif
-+    if (doit[D_SHA1]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, SHA1_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_SHA1, testnum, count, d);
-+        }
-+    }
-+    if (doit[D_SHA256]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_SHA256], c[D_SHA256][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, SHA256_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_SHA256, testnum, count, d);
-+        }
-+    }
-+    if (doit[D_SHA512]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_SHA512], c[D_SHA512][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, SHA512_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_SHA512, testnum, count, d);
-+        }
-+    }
-+
-+#ifndef OPENSSL_NO_WHIRLPOOL
-+    if (doit[D_WHIRLPOOL]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_WHIRLPOOL, testnum, count, d);
-+        }
-+    }
-+#endif
-+
-+#ifndef OPENSSL_NO_RMD160
-+    if (doit[D_RMD160]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_RMD160], c[D_RMD160][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_RMD160, testnum, count, d);
-+        }
-+    }
-+#endif
-+#ifndef OPENSSL_NO_RC4
-+    if (doit[D_RC4]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_RC4], c[D_RC4][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, RC4_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_RC4, testnum, count, d);
-+        }
-+    }
-+#endif
-+#ifndef OPENSSL_NO_DES
-+    if (doit[D_CBC_DES]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_CBC_DES], c[D_CBC_DES][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, DES_ncbc_encrypt_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_DES, testnum, count, d);
-+        }
-+    }
-+
-+    if (doit[D_EDE3_DES]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, DES_ede3_cbc_encrypt_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_EDE3_DES, testnum, count, d);
-+        }
-+    }
-+#endif
-+
-+    if (doit[D_CBC_128_AES]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_CBC_128_AES], c[D_CBC_128_AES][testnum],
-+                          lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, AES_cbc_128_encrypt_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_128_AES, testnum, count, d);
-+        }
-+    }
-+    if (doit[D_CBC_192_AES]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_CBC_192_AES], c[D_CBC_192_AES][testnum],
-+                          lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, AES_cbc_192_encrypt_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_192_AES, testnum, count, d);
-+        }
-+    }
-+    if (doit[D_CBC_256_AES]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_CBC_256_AES], c[D_CBC_256_AES][testnum],
-+                          lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, AES_cbc_256_encrypt_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_256_AES, testnum, count, d);
-+        }
-+    }
-+
-+    if (doit[D_IGE_128_AES]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_IGE_128_AES], c[D_IGE_128_AES][testnum],
-+                          lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, AES_ige_128_encrypt_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_IGE_128_AES, testnum, count, d);
-+        }
-+    }
-+    if (doit[D_IGE_192_AES]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_IGE_192_AES], c[D_IGE_192_AES][testnum],
-+                          lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, AES_ige_192_encrypt_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_IGE_192_AES, testnum, count, d);
-+        }
-+    }
-+    if (doit[D_IGE_256_AES]) {
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_IGE_256_AES], c[D_IGE_256_AES][testnum],
-+                          lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, AES_ige_256_encrypt_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_IGE_256_AES, testnum, count, d);
-+        }
-+    }
-+    if (doit[D_GHASH]) {
-+        for (i = 0; i < loopargs_len; i++) {
-+            loopargs[i].gcm_ctx = CRYPTO_gcm128_new(&aes_ks1, (block128_f) AES_encrypt);
-+            CRYPTO_gcm128_setiv(loopargs[i].gcm_ctx, (unsigned char *)"0123456789ab", 12);
-+        }
-+
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum]);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, CRYPTO_gcm128_aad_loop, loopargs);
-+            d = Time_F(STOP);
-+            print_result(D_GHASH, testnum, count, d);
-+        }
-+        for (i = 0; i < loopargs_len; i++)
-+            CRYPTO_gcm128_release(loopargs[i].gcm_ctx);
-+    }
-+
-+#ifndef OPENSSL_NO_CAMELLIA
-+    if (doit[D_CBC_128_CML]) {
-+        if (async_jobs > 0) {
-+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
-+                       names[D_CBC_128_CML]);
-+            doit[D_CBC_128_CML] = 0;
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
-+            print_message(names[D_CBC_128_CML], c[D_CBC_128_CML][testnum],
-+                          lengths[testnum]);
-+            Time_F(START);
-+            for (count = 0, run = 1; COND(c[D_CBC_128_CML][testnum]); count++)
-+                Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
-+                                     (size_t)lengths[testnum], &camellia_ks1,
-+                                     iv, CAMELLIA_ENCRYPT);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_128_CML, testnum, count, d);
-+        }
-+    }
-+    if (doit[D_CBC_192_CML]) {
-+        if (async_jobs > 0) {
-+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
-+                       names[D_CBC_192_CML]);
-+            doit[D_CBC_192_CML] = 0;
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
-+            print_message(names[D_CBC_192_CML], c[D_CBC_192_CML][testnum],
-+                          lengths[testnum]);
-+            if (async_jobs > 0) {
-+                BIO_printf(bio_err, "Async mode is not supported, exiting...");
-+                exit(1);
-+            }
-+            Time_F(START);
-+            for (count = 0, run = 1; COND(c[D_CBC_192_CML][testnum]); count++)
-+                Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
-+                                     (size_t)lengths[testnum], &camellia_ks2,
-+                                     iv, CAMELLIA_ENCRYPT);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_192_CML, testnum, count, d);
-+        }
-+    }
-+    if (doit[D_CBC_256_CML]) {
-+        if (async_jobs > 0) {
-+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
-+                       names[D_CBC_256_CML]);
-+            doit[D_CBC_256_CML] = 0;
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
-+            print_message(names[D_CBC_256_CML], c[D_CBC_256_CML][testnum],
-+                          lengths[testnum]);
-+            Time_F(START);
-+            for (count = 0, run = 1; COND(c[D_CBC_256_CML][testnum]); count++)
-+                Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
-+                                     (size_t)lengths[testnum], &camellia_ks3,
-+                                     iv, CAMELLIA_ENCRYPT);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_256_CML, testnum, count, d);
-+        }
-+    }
-+#endif
-+#ifndef OPENSSL_NO_IDEA
-+    if (doit[D_CBC_IDEA]) {
-+        if (async_jobs > 0) {
-+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
-+                       names[D_CBC_IDEA]);
-+            doit[D_CBC_IDEA] = 0;
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
-+            print_message(names[D_CBC_IDEA], c[D_CBC_IDEA][testnum], lengths[testnum]);
-+            Time_F(START);
-+            for (count = 0, run = 1; COND(c[D_CBC_IDEA][testnum]); count++)
-+                IDEA_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
-+                                 (size_t)lengths[testnum], &idea_ks,
-+                                 iv, IDEA_ENCRYPT);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_IDEA, testnum, count, d);
-+        }
-+    }
-+#endif
-+#ifndef OPENSSL_NO_SEED
-+    if (doit[D_CBC_SEED]) {
-+        if (async_jobs > 0) {
-+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
-+                       names[D_CBC_SEED]);
-+            doit[D_CBC_SEED] = 0;
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
-+            print_message(names[D_CBC_SEED], c[D_CBC_SEED][testnum], lengths[testnum]);
-+            Time_F(START);
-+            for (count = 0, run = 1; COND(c[D_CBC_SEED][testnum]); count++)
-+                SEED_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
-+                                 (size_t)lengths[testnum], &seed_ks, iv, 1);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_SEED, testnum, count, d);
-+        }
-+    }
-+#endif
-+#ifndef OPENSSL_NO_RC2
-+    if (doit[D_CBC_RC2]) {
-+        if (async_jobs > 0) {
-+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
-+                       names[D_CBC_RC2]);
-+            doit[D_CBC_RC2] = 0;
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
-+            print_message(names[D_CBC_RC2], c[D_CBC_RC2][testnum], lengths[testnum]);
-+            if (async_jobs > 0) {
-+                BIO_printf(bio_err, "Async mode is not supported, exiting...");
-+                exit(1);
-+            }
-+            Time_F(START);
-+            for (count = 0, run = 1; COND(c[D_CBC_RC2][testnum]); count++)
-+                RC2_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
-+                                (size_t)lengths[testnum], &rc2_ks,
-+                                iv, RC2_ENCRYPT);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_RC2, testnum, count, d);
-+        }
-+    }
-+#endif
-+#ifndef OPENSSL_NO_RC5
-+    if (doit[D_CBC_RC5]) {
-+        if (async_jobs > 0) {
-+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
-+                       names[D_CBC_RC5]);
-+            doit[D_CBC_RC5] = 0;
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
-+            print_message(names[D_CBC_RC5], c[D_CBC_RC5][testnum], lengths[testnum]);
-+            if (async_jobs > 0) {
-+                BIO_printf(bio_err, "Async mode is not supported, exiting...");
-+                exit(1);
-+            }
-+            Time_F(START);
-+            for (count = 0, run = 1; COND(c[D_CBC_RC5][testnum]); count++)
-+                RC5_32_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
-+                                   (size_t)lengths[testnum], &rc5_ks,
-+                                   iv, RC5_ENCRYPT);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_RC5, testnum, count, d);
-+        }
-+    }
-+#endif
-+#ifndef OPENSSL_NO_BF
-+    if (doit[D_CBC_BF]) {
-+        if (async_jobs > 0) {
-+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
-+                       names[D_CBC_BF]);
-+            doit[D_CBC_BF] = 0;
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
-+            print_message(names[D_CBC_BF], c[D_CBC_BF][testnum], lengths[testnum]);
-+            Time_F(START);
-+            for (count = 0, run = 1; COND(c[D_CBC_BF][testnum]); count++)
-+                BF_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
-+                               (size_t)lengths[testnum], &bf_ks,
-+                               iv, BF_ENCRYPT);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_BF, testnum, count, d);
-+        }
-+    }
-+#endif
-+#ifndef OPENSSL_NO_CAST
-+    if (doit[D_CBC_CAST]) {
-+        if (async_jobs > 0) {
-+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
-+                       names[D_CBC_CAST]);
-+            doit[D_CBC_CAST] = 0;
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
-+            print_message(names[D_CBC_CAST], c[D_CBC_CAST][testnum], lengths[testnum]);
-+            Time_F(START);
-+            for (count = 0, run = 1; COND(c[D_CBC_CAST][testnum]); count++)
-+                CAST_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
-+                                 (size_t)lengths[testnum], &cast_ks,
-+                                 iv, CAST_ENCRYPT);
-+            d = Time_F(STOP);
-+            print_result(D_CBC_CAST, testnum, count, d);
-+        }
-+    }
-+#endif
-+
-+    if (doit[D_EVP]) {
-+        if (multiblock && evp_cipher) {
-+            if (!
-+                (EVP_CIPHER_flags(evp_cipher) &
-+                 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
-+                BIO_printf(bio_err, "%s is not multi-block capable\n",
-+                           OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher)));
-+                goto end;
-+            }
-+            if (async_jobs > 0) {
-+                BIO_printf(bio_err, "Async mode is not supported, exiting...");
-+                exit(1);
-+            }
-+            multiblock_speed(evp_cipher);
-+            ret = 0;
-+            goto end;
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            if (evp_cipher) {
-+
-+                names[D_EVP] = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));
-+                /*
-+                 * -O3 -fschedule-insns messes up an optimization here!
-+                 * names[D_EVP] somehow becomes NULL
-+                 */
-+                print_message(names[D_EVP], save_count, lengths[testnum]);
-+
-+                for (k = 0; k < loopargs_len; k++) {
-+                    loopargs[k].ctx = EVP_CIPHER_CTX_new();
-+                    if (decrypt)
-+                        EVP_DecryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, key16, iv);
-+                    else
-+                        EVP_EncryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, key16, iv);
-+                    EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
-+                }
-+
-+                Time_F(START);
-+                count = run_benchmark(async_jobs, EVP_Update_loop, loopargs);
-+                d = Time_F(STOP);
-+                for (k = 0; k < loopargs_len; k++) {
-+                    EVP_CIPHER_CTX_free(loopargs[k].ctx);
-+                }
-+            }
-+            if (evp_md) {
-+                names[D_EVP] = OBJ_nid2ln(EVP_MD_type(evp_md));
-+                print_message(names[D_EVP], save_count, lengths[testnum]);
-+                Time_F(START);
-+                count = run_benchmark(async_jobs, EVP_Digest_loop, loopargs);
-+                d = Time_F(STOP);
-+            }
-+            print_result(D_EVP, testnum, count, d);
-+        }
-+    }
-+
-+    for (i = 0; i < loopargs_len; i++)
-+        RAND_bytes(loopargs[i].buf, 36);
-+
-+#ifndef OPENSSL_NO_RSA
-+    for (testnum = 0; testnum < RSA_NUM; testnum++) {
-+        int st = 0;
-+        if (!rsa_doit[testnum])
-+            continue;
-+        for (i = 0; i < loopargs_len; i++) {
-+            st = RSA_sign(NID_md5_sha1, loopargs[i].buf, 36, loopargs[i].buf2,
-+                          &loopargs[i].siglen, loopargs[i].rsa_key[testnum]);
-+            if (st == 0)
-+                break;
-+        }
-+        if (st == 0) {
-+            BIO_printf(bio_err,
-+                       "RSA sign failure.  No RSA sign will be done.\n");
-+            ERR_print_errors(bio_err);
-+            rsa_count = 1;
-+        } else {
-+            pkey_print_message("private", "rsa",
-+                               rsa_c[testnum][0], rsa_bits[testnum], RSA_SECONDS);
-+            /* RSA_blinding_on(rsa_key[testnum],NULL); */
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
-+            d = Time_F(STOP);
-+            BIO_printf(bio_err,
-+                       mr ? "+R1:%ld:%d:%.2f\n"
-+                       : "%ld %d bit private RSA's in %.2fs\n",
-+                       count, rsa_bits[testnum], d);
-+            rsa_results[testnum][0] = d / (double)count;
-+            rsa_count = count;
-+        }
-+
-+        for (i = 0; i < loopargs_len; i++) {
-+            st = RSA_verify(NID_md5_sha1, loopargs[i].buf, 36, loopargs[i].buf2,
-+                            loopargs[i].siglen, loopargs[i].rsa_key[testnum]);
-+            if (st <= 0)
-+                break;
-+        }
-+        if (st <= 0) {
-+            BIO_printf(bio_err,
-+                       "RSA verify failure.  No RSA verify will be done.\n");
-+            ERR_print_errors(bio_err);
-+            rsa_doit[testnum] = 0;
-+        } else {
-+            pkey_print_message("public", "rsa",
-+                               rsa_c[testnum][1], rsa_bits[testnum], RSA_SECONDS);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
-+            d = Time_F(STOP);
-+            BIO_printf(bio_err,
-+                       mr ? "+R2:%ld:%d:%.2f\n"
-+                       : "%ld %d bit public RSA's in %.2fs\n",
-+                       count, rsa_bits[testnum], d);
-+            rsa_results[testnum][1] = d / (double)count;
-+        }
-+
-+        if (rsa_count <= 1) {
-+            /* if longer than 10s, don't do any more */
-+            for (testnum++; testnum < RSA_NUM; testnum++)
-+                rsa_doit[testnum] = 0;
-+        }
-+    }
-+#endif                          /* OPENSSL_NO_RSA */
-+
-+    for (i = 0; i < loopargs_len; i++)
-+        RAND_bytes(loopargs[i].buf, 36);
-+
-+#ifndef OPENSSL_NO_DSA
-+    if (RAND_status() != 1) {
-+        RAND_seed(rnd_seed, sizeof rnd_seed);
-+    }
-+    for (testnum = 0; testnum < DSA_NUM; testnum++) {
-+        int st = 0;
-+        if (!dsa_doit[testnum])
-+            continue;
-+
-+        /* DSA_generate_key(dsa_key[testnum]); */
-+        /* DSA_sign_setup(dsa_key[testnum],NULL); */
-+        for (i = 0; i < loopargs_len; i++) {
-+            st = DSA_sign(0, loopargs[i].buf, 20, loopargs[i].buf2,
-+                          &loopargs[i].siglen, loopargs[i].dsa_key[testnum]);
-+            if (st == 0)
-+                break;
-+        }
-+        if (st == 0) {
-+            BIO_printf(bio_err,
-+                       "DSA sign failure.  No DSA sign will be done.\n");
-+            ERR_print_errors(bio_err);
-+            rsa_count = 1;
-+        } else {
-+            pkey_print_message("sign", "dsa",
-+                               dsa_c[testnum][0], dsa_bits[testnum], DSA_SECONDS);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
-+            d = Time_F(STOP);
-+            BIO_printf(bio_err,
-+                       mr ? "+R3:%ld:%d:%.2f\n"
-+                       : "%ld %d bit DSA signs in %.2fs\n",
-+                       count, dsa_bits[testnum], d);
-+            dsa_results[testnum][0] = d / (double)count;
-+            rsa_count = count;
-+        }
-+
-+        for (i = 0; i < loopargs_len; i++) {
-+            st = DSA_verify(0, loopargs[i].buf, 20, loopargs[i].buf2,
-+                            loopargs[i].siglen, loopargs[i].dsa_key[testnum]);
-+            if (st <= 0)
-+                break;
-+        }
-+        if (st <= 0) {
-+            BIO_printf(bio_err,
-+                       "DSA verify failure.  No DSA verify will be done.\n");
-+            ERR_print_errors(bio_err);
-+            dsa_doit[testnum] = 0;
-+        } else {
-+            pkey_print_message("verify", "dsa",
-+                               dsa_c[testnum][1], dsa_bits[testnum], DSA_SECONDS);
-+            Time_F(START);
-+            count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
-+            d = Time_F(STOP);
-+            BIO_printf(bio_err,
-+                       mr ? "+R4:%ld:%d:%.2f\n"
-+                       : "%ld %d bit DSA verify in %.2fs\n",
-+                       count, dsa_bits[testnum], d);
-+            dsa_results[testnum][1] = d / (double)count;
-+        }
-+
-+        if (rsa_count <= 1) {
-+            /* if longer than 10s, don't do any more */
-+            for (testnum++; testnum < DSA_NUM; testnum++)
-+                dsa_doit[testnum] = 0;
-+        }
-+    }
-+#endif                          /* OPENSSL_NO_DSA */
-+
-+#ifndef OPENSSL_NO_EC
-+    if (RAND_status() != 1) {
-+        RAND_seed(rnd_seed, sizeof rnd_seed);
-+    }
-+    for (testnum = 0; testnum < EC_NUM; testnum++) {
-+        int st = 1;
-+
-+        if (!ecdsa_doit[testnum])
-+            continue;           /* Ignore Curve */
-+        for (i = 0; i < loopargs_len; i++) {
-+            loopargs[i].ecdsa[testnum] = EC_KEY_new_by_curve_name(test_curves[testnum]);
-+            if (loopargs[i].ecdsa[testnum] == NULL) {
-+                st = 0;
-+                break;
-+            }
-+        }
-+        if (st == 0) {
-+            BIO_printf(bio_err, "ECDSA failure.\n");
-+            ERR_print_errors(bio_err);
-+            rsa_count = 1;
-+        } else {
-+            for (i = 0; i < loopargs_len; i++) {
-+                EC_KEY_precompute_mult(loopargs[i].ecdsa[testnum], NULL);
-+                /* Perform ECDSA signature test */
-+                EC_KEY_generate_key(loopargs[i].ecdsa[testnum]);
-+                st = ECDSA_sign(0, loopargs[i].buf, 20, loopargs[i].buf2,
-+                                &loopargs[i].siglen, loopargs[i].ecdsa[testnum]);
-+                if (st == 0)
-+                    break;
-+            }
-+            if (st == 0) {
-+                BIO_printf(bio_err,
-+                           "ECDSA sign failure.  No ECDSA sign will be done.\n");
-+                ERR_print_errors(bio_err);
-+                rsa_count = 1;
-+            } else {
-+                pkey_print_message("sign", "ecdsa",
-+                                   ecdsa_c[testnum][0],
-+                                   test_curves_bits[testnum], ECDSA_SECONDS);
-+                Time_F(START);
-+                count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
-+                d = Time_F(STOP);
-+
-+                BIO_printf(bio_err,
-+                           mr ? "+R5:%ld:%d:%.2f\n" :
-+                           "%ld %d bit ECDSA signs in %.2fs \n",
-+                           count, test_curves_bits[testnum], d);
-+                ecdsa_results[testnum][0] = d / (double)count;
-+                rsa_count = count;
-+            }
-+
-+            /* Perform ECDSA verification test */
-+            for (i = 0; i < loopargs_len; i++) {
-+                st = ECDSA_verify(0, loopargs[i].buf, 20, loopargs[i].buf2,
-+                                  loopargs[i].siglen, loopargs[i].ecdsa[testnum]);
-+                if (st != 1)
-+                    break;
-+            }
-+            if (st != 1) {
-+                BIO_printf(bio_err,
-+                           "ECDSA verify failure.  No ECDSA verify will be done.\n");
-+                ERR_print_errors(bio_err);
-+                ecdsa_doit[testnum] = 0;
-+            } else {
-+                pkey_print_message("verify", "ecdsa",
-+                                   ecdsa_c[testnum][1],
-+                                   test_curves_bits[testnum], ECDSA_SECONDS);
-+                Time_F(START);
-+                count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
-+                d = Time_F(STOP);
-+                BIO_printf(bio_err,
-+                           mr ? "+R6:%ld:%d:%.2f\n"
-+                           : "%ld %d bit ECDSA verify in %.2fs\n",
-+                           count, test_curves_bits[testnum], d);
-+                ecdsa_results[testnum][1] = d / (double)count;
-+            }
-+
-+            if (rsa_count <= 1) {
-+                /* if longer than 10s, don't do any more */
-+                for (testnum++; testnum < EC_NUM; testnum++)
-+                    ecdsa_doit[testnum] = 0;
-+            }
-+        }
-+    }
-+
-+    if (RAND_status() != 1) {
-+        RAND_seed(rnd_seed, sizeof rnd_seed);
-+    }
-+    for (testnum = 0; testnum < EC_NUM; testnum++) {
-+        int ecdh_checks = 1;
-+
-+        if (!ecdh_doit[testnum])
-+            continue;
-+        for (i = 0; i < loopargs_len; i++) {
-+            loopargs[i].ecdh_a[testnum] = EC_KEY_new_by_curve_name(test_curves[testnum]);
-+            loopargs[i].ecdh_b[testnum] = EC_KEY_new_by_curve_name(test_curves[testnum]);
-+            if (loopargs[i].ecdh_a[testnum] == NULL ||
-+                loopargs[i].ecdh_b[testnum] == NULL) {
-+                ecdh_checks = 0;
-+                break;
-+            }
-+        }
-+        if (ecdh_checks == 0) {
-+            BIO_printf(bio_err, "ECDH failure.\n");
-+            ERR_print_errors(bio_err);
-+            rsa_count = 1;
-+        } else {
-+            for (i = 0; i < loopargs_len; i++) {
-+                /* generate two ECDH key pairs */
-+                if (!EC_KEY_generate_key(loopargs[i].ecdh_a[testnum]) ||
-+                        !EC_KEY_generate_key(loopargs[i].ecdh_b[testnum])) {
-+                    BIO_printf(bio_err, "ECDH key generation failure.\n");
-+                    ERR_print_errors(bio_err);
-+                    ecdh_checks = 0;
-+                    rsa_count = 1;
-+                } else {
-+                    int secret_size_a, secret_size_b;
-+                    /*
-+                     * If field size is not more than 24 octets, then use SHA-1
-+                     * hash of result; otherwise, use result (see section 4.8 of
-+                     * draft-ietf-tls-ecc-03.txt).
-+                     */
-+                    int field_size = EC_GROUP_get_degree(
-+                            EC_KEY_get0_group(loopargs[i].ecdh_a[testnum]));
-+
-+                    if (field_size <= 24 * 8) {                 /* 192 bits */
-+                        loopargs[i].outlen = KDF1_SHA1_len;
-+                        loopargs[i].kdf = KDF1_SHA1;
-+                    } else {
-+                        loopargs[i].outlen = (field_size + 7) / 8;
-+                        loopargs[i].kdf = NULL;
-+                    }
-+                    secret_size_a =
-+                        ECDH_compute_key(loopargs[i].secret_a, loopargs[i].outlen,
-+                                EC_KEY_get0_public_key(loopargs[i].ecdh_b[testnum]),
-+                                loopargs[i].ecdh_a[testnum], loopargs[i].kdf);
-+                    secret_size_b =
-+                        ECDH_compute_key(loopargs[i].secret_b, loopargs[i].outlen,
-+                                EC_KEY_get0_public_key(loopargs[i].ecdh_a[testnum]),
-+                                loopargs[i].ecdh_b[testnum], loopargs[i].kdf);
-+                    if (secret_size_a != secret_size_b)
-+                        ecdh_checks = 0;
-+                    else
-+                        ecdh_checks = 1;
-+
-+                    for (k = 0; k < secret_size_a && ecdh_checks == 1; k++) {
-+                        if (loopargs[i].secret_a[k] != loopargs[i].secret_b[k])
-+                            ecdh_checks = 0;
-+                    }
-+
-+                    if (ecdh_checks == 0) {
-+                        BIO_printf(bio_err, "ECDH computations don't match.\n");
-+                        ERR_print_errors(bio_err);
-+                        rsa_count = 1;
-+                        break;
-+                    }
-+                }
-+            }
-+            if (ecdh_checks != 0) {
-+                pkey_print_message("", "ecdh",
-+                        ecdh_c[testnum][0],
-+                        test_curves_bits[testnum], ECDH_SECONDS);
-+                Time_F(START);
-+                count = run_benchmark(async_jobs, ECDH_compute_key_loop, loopargs);
-+                d = Time_F(STOP);
-+                BIO_printf(bio_err,
-+                        mr ? "+R7:%ld:%d:%.2f\n" :
-+                        "%ld %d-bit ECDH ops in %.2fs\n", count,
-+                        test_curves_bits[testnum], d);
-+                ecdh_results[testnum][0] = d / (double)count;
-+                rsa_count = count;
-+            }
-+        }
-+
-+        if (rsa_count <= 1) {
-+            /* if longer than 10s, don't do any more */
-+            for (testnum++; testnum < EC_NUM; testnum++)
-+                ecdh_doit[testnum] = 0;
-+        }
-+    }
-+#endif                          /* OPENSSL_NO_EC */
-+#ifndef NO_FORK
-+ show_res:
-+#endif
-+    if (!mr) {
-+        printf("%s\n", OpenSSL_version(OPENSSL_VERSION));
-+        printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
-+        printf("options:");
-+        printf("%s ", BN_options());
-+#ifndef OPENSSL_NO_MD2
-+        printf("%s ", MD2_options());
-+#endif
-+#ifndef OPENSSL_NO_RC4
-+        printf("%s ", RC4_options());
-+#endif
-+#ifndef OPENSSL_NO_DES
-+        printf("%s ", DES_options());
-+#endif
-+        printf("%s ", AES_options());
-+#ifndef OPENSSL_NO_IDEA
-+        printf("%s ", IDEA_options());
-+#endif
-+#ifndef OPENSSL_NO_BF
-+        printf("%s ", BF_options());
-+#endif
-+        printf("\n%s\n", OpenSSL_version(OPENSSL_CFLAGS));
-+    }
-+
-+    if (pr_header) {
-+        if (mr)
-+            printf("+H");
-+        else {
-+            printf
-+                ("The 'numbers' are in 1000s of bytes per second processed.\n");
-+            printf("type        ");
-+        }
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++)
-+            printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
-+        printf("\n");
-+    }
-+
-+    for (k = 0; k < ALGOR_NUM; k++) {
-+        if (!doit[k])
-+            continue;
-+        if (mr)
-+            printf("+F:%d:%s", k, names[k]);
-+        else
-+            printf("%-13s", names[k]);
-+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
-+            if (results[k][testnum] > 10000 && !mr)
-+                printf(" %11.2fk", results[k][testnum] / 1e3);
-+            else
-+                printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
-+        }
-+        printf("\n");
-+    }
-+#ifndef OPENSSL_NO_RSA
-+    testnum = 1;
-+    for (k = 0; k < RSA_NUM; k++) {
-+        if (!rsa_doit[k])
-+            continue;
-+        if (testnum && !mr) {
-+            printf("%18ssign    verify    sign/s verify/s\n", " ");
-+            testnum = 0;
-+        }
-+        if (mr)
-+            printf("+F2:%u:%u:%f:%f\n",
-+                   k, rsa_bits[k], rsa_results[k][0], rsa_results[k][1]);
-+        else
-+            printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
-+                   rsa_bits[k], rsa_results[k][0], rsa_results[k][1],
-+                   1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1]);
-+    }
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    testnum = 1;
-+    for (k = 0; k < DSA_NUM; k++) {
-+        if (!dsa_doit[k])
-+            continue;
-+        if (testnum && !mr) {
-+            printf("%18ssign    verify    sign/s verify/s\n", " ");
-+            testnum = 0;
-+        }
-+        if (mr)
-+            printf("+F3:%u:%u:%f:%f\n",
-+                   k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
-+        else
-+            printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
-+                   dsa_bits[k], dsa_results[k][0], dsa_results[k][1],
-+                   1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1]);
-+    }
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    testnum = 1;
-+    for (k = 0; k < EC_NUM; k++) {
-+        if (!ecdsa_doit[k])
-+            continue;
-+        if (testnum && !mr) {
-+            printf("%30ssign    verify    sign/s verify/s\n", " ");
-+            testnum = 0;
-+        }
-+
-+        if (mr)
-+            printf("+F4:%u:%u:%f:%f\n",
-+                   k, test_curves_bits[k],
-+                   ecdsa_results[k][0], ecdsa_results[k][1]);
-+        else
-+            printf("%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
-+                   test_curves_bits[k],
-+                   test_curves_names[k],
-+                   ecdsa_results[k][0], ecdsa_results[k][1],
-+                   1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1]);
-+    }
-+
-+    testnum = 1;
-+    for (k = 0; k < EC_NUM; k++) {
-+        if (!ecdh_doit[k])
-+            continue;
-+        if (testnum && !mr) {
-+            printf("%30sop      op/s\n", " ");
-+            testnum = 0;
-+        }
-+        if (mr)
-+            printf("+F5:%u:%u:%f:%f\n",
-+                   k, test_curves_bits[k],
-+                   ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
-+
-+        else
-+            printf("%4u bit ecdh (%s) %8.4fs %8.1f\n",
-+                   test_curves_bits[k],
-+                   test_curves_names[k],
-+                   ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
-+    }
-+#endif
-+
-+    ret = 0;
-+
-+ end:
-+    ERR_print_errors(bio_err);
-+    for (i = 0; i < loopargs_len; i++) {
-+        OPENSSL_free(loopargs[i].buf_malloc);
-+        OPENSSL_free(loopargs[i].buf2_malloc);
-+
-+#ifndef OPENSSL_NO_RSA
-+        for (k = 0; k < RSA_NUM; k++)
-+            RSA_free(loopargs[i].rsa_key[k]);
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+        for (k = 0; k < DSA_NUM; k++)
-+            DSA_free(loopargs[i].dsa_key[k]);
-+#endif
-+#ifndef OPENSSL_NO_EC
-+        for (k = 0; k < EC_NUM; k++) {
-+            EC_KEY_free(loopargs[i].ecdsa[k]);
-+            EC_KEY_free(loopargs[i].ecdh_a[k]);
-+            EC_KEY_free(loopargs[i].ecdh_b[k]);
-+        }
-+        OPENSSL_free(loopargs[i].secret_a);
-+        OPENSSL_free(loopargs[i].secret_b);
-+#endif
-+    }
-+
-+    if (async_jobs > 0) {
-+        for (i = 0; i < loopargs_len; i++)
-+            ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
-+    }
-+
-+    if (async_init) {
-+        ASYNC_cleanup_thread();
-+    }
-+    OPENSSL_free(loopargs);
-+    release_engine(e);
-+    return (ret);
-+}
-+
-+static void print_message(const char *s, long num, int length)
-+{
-+#ifdef SIGALRM
-+    BIO_printf(bio_err,
-+               mr ? "+DT:%s:%d:%d\n"
-+               : "Doing %s for %ds on %d size blocks: ", s, SECONDS, length);
-+    (void)BIO_flush(bio_err);
-+    alarm(SECONDS);
-+#else
-+    BIO_printf(bio_err,
-+               mr ? "+DN:%s:%ld:%d\n"
-+               : "Doing %s %ld times on %d size blocks: ", s, num, length);
-+    (void)BIO_flush(bio_err);
-+#endif
-+}
-+
-+static void pkey_print_message(const char *str, const char *str2, long num,
-+                               int bits, int tm)
-+{
-+#ifdef SIGALRM
-+    BIO_printf(bio_err,
-+               mr ? "+DTP:%d:%s:%s:%d\n"
-+               : "Doing %d bit %s %s's for %ds: ", bits, str, str2, tm);
-+    (void)BIO_flush(bio_err);
-+    alarm(tm);
-+#else
-+    BIO_printf(bio_err,
-+               mr ? "+DNP:%ld:%d:%s:%s\n"
-+               : "Doing %ld %d bit %s %s's: ", num, bits, str, str2);
-+    (void)BIO_flush(bio_err);
-+#endif
-+}
-+
-+static void print_result(int alg, int run_no, int count, double time_used)
-+{
-+    if (count == -1) {
-+        BIO_puts(bio_err, "EVP error!\n");
-+        exit(1);
-+    }
-+    BIO_printf(bio_err,
-+               mr ? "+R:%d:%s:%f\n"
-+               : "%d %s's in %.2fs\n", count, names[alg], time_used);
-+    results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
-+}
-+
-+#ifndef NO_FORK
-+static char *sstrsep(char **string, const char *delim)
-+{
-+    char isdelim[256];
-+    char *token = *string;
-+
-+    if (**string == 0)
-+        return NULL;
-+
-+    memset(isdelim, 0, sizeof isdelim);
-+    isdelim[0] = 1;
-+
-+    while (*delim) {
-+        isdelim[(unsigned char)(*delim)] = 1;
-+        delim++;
-+    }
-+
-+    while (!isdelim[(unsigned char)(**string)]) {
-+        (*string)++;
-+    }
-+
-+    if (**string) {
-+        **string = 0;
-+        (*string)++;
-+    }
-+
-+    return token;
-+}
-+
-+static int do_multi(int multi)
-+{
-+    int n;
-+    int fd[2];
-+    int *fds;
-+    static char sep[] = ":";
-+
-+    fds = malloc(sizeof(*fds) * multi);
-+    for (n = 0; n < multi; ++n) {
-+        if (pipe(fd) == -1) {
-+            BIO_printf(bio_err, "pipe failure\n");
-+            exit(1);
-+        }
-+        fflush(stdout);
-+        (void)BIO_flush(bio_err);
-+        if (fork()) {
-+            close(fd[1]);
-+            fds[n] = fd[0];
-+        } else {
-+            close(fd[0]);
-+            close(1);
-+            if (dup(fd[1]) == -1) {
-+                BIO_printf(bio_err, "dup failed\n");
-+                exit(1);
-+            }
-+            close(fd[1]);
-+            mr = 1;
-+            usertime = 0;
-+            free(fds);
-+            return 0;
-+        }
-+        printf("Forked child %d\n", n);
-+    }
-+
-+    /* for now, assume the pipe is long enough to take all the output */
-+    for (n = 0; n < multi; ++n) {
-+        FILE *f;
-+        char buf[1024];
-+        char *p;
-+
-+        f = fdopen(fds[n], "r");
-+        while (fgets(buf, sizeof buf, f)) {
-+            p = strchr(buf, '\n');
-+            if (p)
-+                *p = '\0';
-+            if (buf[0] != '+') {
-+                BIO_printf(bio_err, "Don't understand line '%s' from child %d\n",
-+                        buf, n);
-+                continue;
-+            }
-+            printf("Got: %s from %d\n", buf, n);
-+            if (strncmp(buf, "+F:", 3) == 0) {
-+                int alg;
-+                int j;
-+
-+                p = buf + 3;
-+                alg = atoi(sstrsep(&p, sep));
-+                sstrsep(&p, sep);
-+                for (j = 0; j < SIZE_NUM; ++j)
-+                    results[alg][j] += atof(sstrsep(&p, sep));
-+            } else if (strncmp(buf, "+F2:", 4) == 0) {
-+                int k;
-+                double d;
-+
-+                p = buf + 4;
-+                k = atoi(sstrsep(&p, sep));
-+                sstrsep(&p, sep);
-+
-+                d = atof(sstrsep(&p, sep));
-+                if (n)
-+                    rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d);
-+                else
-+                    rsa_results[k][0] = d;
-+
-+                d = atof(sstrsep(&p, sep));
-+                if (n)
-+                    rsa_results[k][1] = 1 / (1 / rsa_results[k][1] + 1 / d);
-+                else
-+                    rsa_results[k][1] = d;
-+            }
-+# ifndef OPENSSL_NO_DSA
-+            else if (strncmp(buf, "+F3:", 4) == 0) {
-+                int k;
-+                double d;
-+
-+                p = buf + 4;
-+                k = atoi(sstrsep(&p, sep));
-+                sstrsep(&p, sep);
-+
-+                d = atof(sstrsep(&p, sep));
-+                if (n)
-+                    dsa_results[k][0] = 1 / (1 / dsa_results[k][0] + 1 / d);
-+                else
-+                    dsa_results[k][0] = d;
-+
-+                d = atof(sstrsep(&p, sep));
-+                if (n)
-+                    dsa_results[k][1] = 1 / (1 / dsa_results[k][1] + 1 / d);
-+                else
-+                    dsa_results[k][1] = d;
-+            }
-+# endif
-+# ifndef OPENSSL_NO_EC
-+            else if (strncmp(buf, "+F4:", 4) == 0) {
-+                int k;
-+                double d;
-+
-+                p = buf + 4;
-+                k = atoi(sstrsep(&p, sep));
-+                sstrsep(&p, sep);
-+
-+                d = atof(sstrsep(&p, sep));
-+                if (n)
-+                    ecdsa_results[k][0] =
-+                        1 / (1 / ecdsa_results[k][0] + 1 / d);
-+                else
-+                    ecdsa_results[k][0] = d;
-+
-+                d = atof(sstrsep(&p, sep));
-+                if (n)
-+                    ecdsa_results[k][1] =
-+                        1 / (1 / ecdsa_results[k][1] + 1 / d);
-+                else
-+                    ecdsa_results[k][1] = d;
-+            } else if (strncmp(buf, "+F5:", 4) == 0) {
-+                int k;
-+                double d;
-+
-+                p = buf + 4;
-+                k = atoi(sstrsep(&p, sep));
-+                sstrsep(&p, sep);
-+
-+                d = atof(sstrsep(&p, sep));
-+                if (n)
-+                    ecdh_results[k][0] = 1 / (1 / ecdh_results[k][0] + 1 / d);
-+                else
-+                    ecdh_results[k][0] = d;
-+
-+            }
-+# endif
-+
-+            else if (strncmp(buf, "+H:", 3) == 0) {
-+                ;
-+            } else
-+                BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf, n);
-+        }
-+
-+        fclose(f);
-+    }
-+    free(fds);
-+    return 1;
-+}
-+#endif
-+
-+static void multiblock_speed(const EVP_CIPHER *evp_cipher)
-+{
-+    static int mblengths[] =
-+        { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
-+    int j, count, num = OSSL_NELEM(mblengths);
-+    const char *alg_name;
-+    unsigned char *inp, *out, no_key[32], no_iv[16];
-+    EVP_CIPHER_CTX *ctx;
-+    double d = 0.0;
-+
-+    inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
-+    out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
-+    ctx = EVP_CIPHER_CTX_new();
-+    EVP_EncryptInit_ex(ctx, evp_cipher, NULL, no_key, no_iv);
-+    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY, sizeof(no_key),
-+                        no_key);
-+    alg_name = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));
-+
-+    for (j = 0; j < num; j++) {
-+        print_message(alg_name, 0, mblengths[j]);
-+        Time_F(START);
-+        for (count = 0, run = 1; run && count < 0x7fffffff; count++) {
-+            unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
-+            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
-+            size_t len = mblengths[j];
-+            int packlen;
-+
-+            memset(aad, 0, 8);  /* avoid uninitialized values */
-+            aad[8] = 23;        /* SSL3_RT_APPLICATION_DATA */
-+            aad[9] = 3;         /* version */
-+            aad[10] = 2;
-+            aad[11] = 0;        /* length */
-+            aad[12] = 0;
-+            mb_param.out = NULL;
-+            mb_param.inp = aad;
-+            mb_param.len = len;
-+            mb_param.interleave = 8;
-+
-+            packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
-+                                          sizeof(mb_param), &mb_param);
-+
-+            if (packlen > 0) {
-+                mb_param.out = out;
-+                mb_param.inp = inp;
-+                mb_param.len = len;
-+                EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
-+                                    sizeof(mb_param), &mb_param);
-+            } else {
-+                int pad;
-+
-+                RAND_bytes(out, 16);
-+                len += 16;
-+                aad[11] = len >> 8;
-+                aad[12] = len;
-+                pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
-+                                          EVP_AEAD_TLS1_AAD_LEN, aad);
-+                EVP_Cipher(ctx, out, inp, len + pad);
-+            }
-+        }
-+        d = Time_F(STOP);
-+        BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
-+                   : "%d %s's in %.2fs\n", count, "evp", d);
-+        results[D_EVP][j] = ((double)count) / d * mblengths[j];
-+    }
-+
-+    if (mr) {
-+        fprintf(stdout, "+H");
-+        for (j = 0; j < num; j++)
-+            fprintf(stdout, ":%d", mblengths[j]);
-+        fprintf(stdout, "\n");
-+        fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
-+        for (j = 0; j < num; j++)
-+            fprintf(stdout, ":%.2f", results[D_EVP][j]);
-+        fprintf(stdout, "\n");
-+    } else {
-+        fprintf(stdout,
-+                "The 'numbers' are in 1000s of bytes per second processed.\n");
-+        fprintf(stdout, "type                    ");
-+        for (j = 0; j < num; j++)
-+            fprintf(stdout, "%7d bytes", mblengths[j]);
-+        fprintf(stdout, "\n");
-+        fprintf(stdout, "%-24s", alg_name);
-+
-+        for (j = 0; j < num; j++) {
-+            if (results[D_EVP][j] > 10000)
-+                fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
-+            else
-+                fprintf(stdout, " %11.2f ", results[D_EVP][j]);
-+        }
-+        fprintf(stdout, "\n");
-+    }
-+
-+    OPENSSL_free(inp);
-+    OPENSSL_free(out);
-+    EVP_CIPHER_CTX_free(ctx);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/spkac.c b/CryptoPkg/Library/OpensslLib/openssl/apps/spkac.c
-new file mode 100644
-index 0000000..90a5bea
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/spkac.c
-@@ -0,0 +1,193 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "apps.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+typedef enum OPTION_choice {
-+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-+    OPT_NOOUT, OPT_PUBKEY, OPT_VERIFY, OPT_IN, OPT_OUT,
-+    OPT_ENGINE, OPT_KEY, OPT_CHALLENGE, OPT_PASSIN, OPT_SPKAC,
-+    OPT_SPKSECT
-+} OPTION_CHOICE;
-+
-+OPTIONS spkac_options[] = {
-+    {"help", OPT_HELP, '-', "Display this summary"},
-+    {"in", OPT_IN, '<', "Input file"},
-+    {"out", OPT_OUT, '>', "Output file"},
-+    {"key", OPT_KEY, '<', "Create SPKAC using private key"},
-+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
-+    {"challenge", OPT_CHALLENGE, 's', "Challenge string"},
-+    {"spkac", OPT_SPKAC, 's', "Alternative SPKAC name"},
-+    {"noout", OPT_NOOUT, '-', "Don't print SPKAC"},
-+    {"pubkey", OPT_PUBKEY, '-', "Output public key"},
-+    {"verify", OPT_VERIFY, '-', "Verify SPKAC signature"},
-+    {"spksect", OPT_SPKSECT, 's',
-+     "Specify the name of an SPKAC-dedicated section of configuration"},
-+#ifndef OPENSSL_NO_ENGINE
-+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
-+#endif
-+    {NULL}
-+};
-+
-+int spkac_main(int argc, char **argv)
-+{
-+    BIO *out = NULL;
-+    CONF *conf = NULL;
-+    ENGINE *e = NULL;
-+    EVP_PKEY *pkey = NULL;
-+    NETSCAPE_SPKI *spki = NULL;
-+    char *challenge = NULL, *keyfile = NULL;
-+    char *infile = NULL, *outfile = NULL, *passinarg = NULL, *passin = NULL;
-+    char *spkstr = NULL, *prog;
-+    const char *spkac = "SPKAC", *spksect = "default";
-+    int i, ret = 1, verify = 0, noout = 0, pubkey = 0;
-+    OPTION_CHOICE o;
-+
-+    prog = opt_init(argc, argv, spkac_options);
-+    while ((o = opt_next()) != OPT_EOF) {
-+        switch (o) {
-+        case OPT_EOF:
-+        case OPT_ERR:
-+ opthelp:
-+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-+            goto end;
-+        case OPT_HELP:
-+            opt_help(spkac_options);
-+            ret = 0;
-+            goto end;
-+        case OPT_IN:
-+            infile = opt_arg();
-+            break;
-+        case OPT_OUT:
-+            outfile = opt_arg();
-+            break;
-+        case OPT_NOOUT:
-+            noout = 1;
-+            break;
-+        case OPT_PUBKEY:
-+            pubkey = 1;
-+            break;
-+        case OPT_VERIFY:
-+            verify = 1;
-+            break;
-+        case OPT_PASSIN:
-+            passinarg = opt_arg();
-+            break;
-+        case OPT_KEY:
-+            keyfile = opt_arg();
-+            break;
-+        case OPT_CHALLENGE:
-+            challenge = opt_arg();
-+            break;
-+        case OPT_SPKAC:
-+            spkac = opt_arg();
-+            break;
-+        case OPT_SPKSECT:
-+            spksect = opt_arg();
-+            break;
-+        case OPT_ENGINE:
-+            e = setup_engine(opt_arg(), 0);
-+            break;
-+        }
-+    }
-+    argc = opt_num_rest();
-+    if (argc != 0)
-+        goto opthelp;
-+
-+    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
-+        BIO_printf(bio_err, "Error getting password\n");
-+        goto end;
-+    }
-+
-+    if (keyfile) {
-+        pkey = load_key(strcmp(keyfile, "-") ? keyfile : NULL,
-+                        FORMAT_PEM, 1, passin, e, "private key");
-+        if (!pkey) {
-+            goto end;
-+        }
-+        spki = NETSCAPE_SPKI_new();
-+        if (challenge)
-+            ASN1_STRING_set(spki->spkac->challenge,
-+                            challenge, (int)strlen(challenge));
-+        NETSCAPE_SPKI_set_pubkey(spki, pkey);
-+        NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
-+        spkstr = NETSCAPE_SPKI_b64_encode(spki);
-+
-+        out = bio_open_default(outfile, 'w', FORMAT_TEXT);
-+        if (out == NULL) {
-+            OPENSSL_free(spkstr);
-+            goto end;
-+        }
-+        BIO_printf(out, "SPKAC=%s\n", spkstr);
-+        OPENSSL_free(spkstr);
-+        ret = 0;
-+        goto end;
-+    }
-+
-+    if ((conf = app_load_config(infile)) == NULL)
-+        goto end;
-+
-+    spkstr = NCONF_get_string(conf, spksect, spkac);
-+
-+    if (spkstr == NULL) {
-+        BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac);
-+        ERR_print_errors(bio_err);
-+        goto end;
-+    }
-+
-+    spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
-+
-+    if (!spki) {
-+        BIO_printf(bio_err, "Error loading SPKAC\n");
-+        ERR_print_errors(bio_err);
-+        goto end;
-+    }
-+
-+    out = bio_open_default(outfile, 'w', FORMAT_TEXT);
-+    if (out == NULL)
-+        goto end;
-+
-+    if (!noout)
-+        NETSCAPE_SPKI_print(out, spki);
-+    pkey = NETSCAPE_SPKI_get_pubkey(spki);
-+    if (verify) {
-+        i = NETSCAPE_SPKI_verify(spki, pkey);
-+        if (i > 0)
-+            BIO_printf(bio_err, "Signature OK\n");
-+        else {
-+            BIO_printf(bio_err, "Signature Failure\n");
-+            ERR_print_errors(bio_err);
-+            goto end;
-+        }
-+    }
-+    if (pubkey)
-+        PEM_write_bio_PUBKEY(out, pkey);
-+
-+    ret = 0;
-+
-+ end:
-+    NCONF_free(conf);
-+    NETSCAPE_SPKI_free(spki);
-+    BIO_free_all(out);
-+    EVP_PKEY_free(pkey);
-+    release_engine(e);
-+    OPENSSL_free(passin);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/srp.c b/CryptoPkg/Library/OpensslLib/openssl/apps/srp.c
-new file mode 100644
-index 0000000..add0100
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/srp.c
-@@ -0,0 +1,609 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#ifdef OPENSSL_NO_SRP
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "apps.h"
-+
-+# define BASE_SECTION    "srp"
-+# define CONFIG_FILE "openssl.cnf"
-+
-+# define ENV_RANDFILE            "RANDFILE"
-+
-+# define ENV_DATABASE            "srpvfile"
-+# define ENV_DEFAULT_SRP         "default_srp"
-+
-+static int get_index(CA_DB *db, char *id, char type)
-+{
-+    char **pp;
-+    int i;
-+    if (id == NULL)
-+        return -1;
-+    if (type == DB_SRP_INDEX)
-+        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
-+            pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
-+            if (pp[DB_srptype][0] == DB_SRP_INDEX
-+                && strcmp(id, pp[DB_srpid]) == 0)
-+                return i;
-+    } else
-+        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
-+            pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
-+
-+            if (pp[DB_srptype][0] != DB_SRP_INDEX
-+                && strcmp(id, pp[DB_srpid]) == 0)
-+                return i;
-+        }
-+
-+    return -1;
-+}
-+
-+static void print_entry(CA_DB *db, int indx, int verbose, char *s)
-+{
-+    if (indx >= 0 && verbose) {
-+        int j;
-+        char **pp = sk_OPENSSL_PSTRING_value(db->db->data, indx);
-+        BIO_printf(bio_err, "%s \"%s\"\n", s, pp[DB_srpid]);
-+        for (j = 0; j < DB_NUMBER; j++) {
-+            BIO_printf(bio_err, "  %d = \"%s\"\n", j, pp[j]);
-+        }
-+    }
-+}
-+
-+static void print_index(CA_DB *db, int indexindex, int verbose)
-+{
-+    print_entry(db, indexindex, verbose, "g N entry");
-+}
-+
-+static void print_user(CA_DB *db, int userindex, int verbose)
-+{
-+    if (verbose > 0) {
-+        char **pp = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
-+
-+        if (pp[DB_srptype][0] != 'I') {
-+            print_entry(db, userindex, verbose, "User entry");
-+            print_entry(db, get_index(db, pp[DB_srpgN], 'I'), verbose,
-+                        "g N entry");
-+        }
-+
-+    }
-+}
-+
-+static int update_index(CA_DB *db, char **row)
-+{
-+    char **irow;
-+    int i;
-+
-+    irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row pointers");
-+    for (i = 0; i < DB_NUMBER; i++) {
-+        irow[i] = row[i];
-+        row[i] = NULL;
-+    }
-+    irow[DB_NUMBER] = NULL;
-+
-+    if (!TXT_DB_insert(db->db, irow)) {
-+        BIO_printf(bio_err, "failed to update srpvfile\n");
-+        BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
-+        OPENSSL_free(irow);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+static char *lookup_conf(const CONF *conf, const char *section, const char *tag)
-+{
-+    char *entry = NCONF_get_string(conf, section, tag);
-+    if (entry == NULL)
-+        BIO_printf(bio_err, "variable lookup failed for %s::%s\n", section, tag);
-+    return entry;
-+}
-+
-+static char *srp_verify_user(const char *user, const char *srp_verifier,
-+                             char *srp_usersalt, const char *g, const char *N,
-+                             const char *passin, int verbose)
-+{
-+    char password[1024];
-+    PW_CB_DATA cb_tmp;
-+    char *verifier = NULL;
-+    char *gNid = NULL;
-+
-+    cb_tmp.prompt_info = user;
-+    cb_tmp.password = passin;
-+
-+    if (password_callback(password, sizeof(password), 0, &cb_tmp) > 0) {
-+        if (verbose)
-+            BIO_printf(bio_err,
-+                       "Validating\n   user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",
-+                       user, srp_verifier, srp_usersalt, g, N);
-+        BIO_printf(bio_err, "Pass %s\n", password);
-+
-+        OPENSSL_assert(srp_usersalt != NULL);
-+        if (!
-+            (gNid =
-+             SRP_create_verifier(user, password, &srp_usersalt, &verifier, N,
-+                                 g))) {
-+            BIO_printf(bio_err, "Internal error validating SRP verifier\n");
-+        } else {
-+            if (strcmp(verifier, srp_verifier))
-+                gNid = NULL;
-+            OPENSSL_free(verifier);
-+        }
-+    }
-+    return gNid;
-+}
-+
-+static char *srp_create_user(char *user, char **srp_verifier,
-+                             char **srp_usersalt, char *g, char *N,
-+                             char *passout, int verbose)
-+{
-+    char password[1024];
-+    PW_CB_DATA cb_tmp;
-+    char *gNid = NULL;
-+    char *salt = NULL;
-+    cb_tmp.prompt_info = user;
-+    cb_tmp.password = passout;
-+
-+    if (password_callback(password, sizeof(password), 1, &cb_tmp) > 0) {
-+        if (verbose)
-+            BIO_printf(bio_err, "Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",
-+                       user, g, N);
-+        if (!
-+            (gNid =
-+             SRP_create_verifier(user, password, &salt, srp_verifier, N,
-+                                 g))) {
-+            BIO_printf(bio_err, "Internal error creating SRP verifier\n");
-+        } else
-+            *srp_usersalt = salt;
-+        if (verbose > 1)
-+            BIO_printf(bio_err, "gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid,
-+                       salt, *srp_verifier);
-+
-+    }
-+    return gNid;
-+}
-+
-+typedef enum OPTION_choice {
-+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-+    OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SRPVFILE, OPT_ADD,
-+    OPT_DELETE, OPT_MODIFY, OPT_LIST, OPT_GN, OPT_USERINFO,
-+    OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE
-+} OPTION_CHOICE;
-+
-+OPTIONS srp_options[] = {
-+    {"help", OPT_HELP, '-', "Display this summary"},
-+    {"verbose", OPT_VERBOSE, '-', "Talk a lot while doing things"},
-+    {"config", OPT_CONFIG, '<', "A config file"},
-+    {"name", OPT_NAME, 's', "The particular srp definition to use"},
-+    {"srpvfile", OPT_SRPVFILE, '<', "The srp verifier file name"},
-+    {"add", OPT_ADD, '-', "Add a user and srp verifier"},
-+    {"modify", OPT_MODIFY, '-',
-+     "Modify the srp verifier of an existing user"},
-+    {"delete", OPT_DELETE, '-', "Delete user from verifier file"},
-+    {"list", OPT_LIST, '-', "List users"},
-+    {"gn", OPT_GN, 's', "Set g and N values to be used for new verifier"},
-+    {"userinfo", OPT_USERINFO, 's', "Additional info to be set for user"},
-+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
-+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
-+# ifndef OPENSSL_NO_ENGINE
-+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
-+# endif
-+    {NULL}
-+};
-+
-+int srp_main(int argc, char **argv)
-+{
-+    ENGINE *e = NULL;
-+    CA_DB *db = NULL;
-+    CONF *conf = NULL;
-+    int gNindex = -1, maxgN = -1, ret = 1, errors = 0, verbose = 0, i;
-+    int doupdatedb = 0, mode = OPT_ERR;
-+    char *user = NULL, *passinarg = NULL, *passoutarg = NULL;
-+    char *passin = NULL, *passout = NULL, *gN = NULL, *userinfo = NULL;
-+    char *randfile = NULL, *section = NULL;
-+    char **gNrow = NULL, *configfile = NULL;
-+    char *srpvfile = NULL, **pp, *prog;
-+    OPTION_CHOICE o;
-+
-+    prog = opt_init(argc, argv, srp_options);
-+    while ((o = opt_next()) != OPT_EOF) {
-+        switch (o) {
-+        case OPT_EOF:
-+        case OPT_ERR:
-+ opthelp:
-+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-+            goto end;
-+        case OPT_HELP:
-+            opt_help(srp_options);
-+            ret = 0;
-+            goto end;
-+        case OPT_VERBOSE:
-+            verbose++;
-+            break;
-+        case OPT_CONFIG:
-+            configfile = opt_arg();
-+            break;
-+        case OPT_NAME:
-+            section = opt_arg();
-+            break;
-+        case OPT_SRPVFILE:
-+            srpvfile = opt_arg();
-+            break;
-+        case OPT_ADD:
-+        case OPT_DELETE:
-+        case OPT_MODIFY:
-+        case OPT_LIST:
-+            if (mode != OPT_ERR) {
-+                BIO_printf(bio_err,
-+                           "%s: Only one of -add/delete-modify/-list\n",
-+                           prog);
-+                goto opthelp;
-+            }
-+            mode = o;
-+            break;
-+        case OPT_GN:
-+            gN = opt_arg();
-+            break;
-+        case OPT_USERINFO:
-+            userinfo = opt_arg();
-+            break;
-+        case OPT_PASSIN:
-+            passinarg = opt_arg();
-+            break;
-+        case OPT_PASSOUT:
-+            passoutarg = opt_arg();
-+            break;
-+        case OPT_ENGINE:
-+            e = setup_engine(opt_arg(), 0);
-+            break;
-+        }
-+    }
-+    argc = opt_num_rest();
-+    argv = opt_rest();
-+
-+    if (srpvfile && configfile) {
-+        BIO_printf(bio_err,
-+                   "-srpvfile and -configfile cannot be specified together.\n");
-+        goto end;
-+    }
-+    if (mode == OPT_ERR) {
-+        BIO_printf(bio_err,
-+                   "Exactly one of the options -add, -delete, -modify -list must be specified.\n");
-+        goto opthelp;
-+    }
-+    if ((mode == OPT_DELETE || mode == OPT_MODIFY || mode == OPT_ADD)
-+        && argc < 1) {
-+        BIO_printf(bio_err,
-+                   "Need at least one user for options -add, -delete, -modify. \n");
-+        goto opthelp;
-+    }
-+    if ((passin || passout) && argc != 1) {
-+        BIO_printf(bio_err,
-+                   "-passin, -passout arguments only valid with one user.\n");
-+        goto opthelp;
-+    }
-+
-+    if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
-+        BIO_printf(bio_err, "Error getting passwords\n");
-+        goto end;
-+    }
-+
-+    if (!srpvfile) {
-+        if (!configfile)
-+            configfile = default_config_file;
-+
-+        if (verbose)
-+            BIO_printf(bio_err, "Using configuration from %s\n",
-+                       configfile);
-+        conf = app_load_config(configfile);
-+        if (conf == NULL)
-+            goto end;
-+        if (configfile != default_config_file && !app_load_modules(conf))
-+            goto end;
-+
-+        /* Lets get the config section we are using */
-+        if (section == NULL) {
-+            if (verbose)
-+                BIO_printf(bio_err,
-+                           "trying to read " ENV_DEFAULT_SRP
-+                           " in " BASE_SECTION "\n");
-+
-+            section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_SRP);
-+            if (section == NULL)
-+                goto end;
-+        }
-+
-+        if (randfile == NULL)
-+            randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
-+
-+        if (verbose)
-+            BIO_printf(bio_err,
-+                       "trying to read " ENV_DATABASE " in section \"%s\"\n",
-+                       section);
-+
-+        srpvfile = lookup_conf(conf, section, ENV_DATABASE);
-+        if (srpvfile == NULL)
-+            goto end;
-+    }
-+    if (randfile == NULL)
-+        ERR_clear_error();
-+    else
-+        app_RAND_load_file(randfile, 0);
-+
-+    if (verbose)
-+        BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n",
-+                   srpvfile);
-+
-+    db = load_index(srpvfile, NULL);
-+    if (db == NULL)
-+        goto end;
-+
-+    /* Lets check some fields */
-+    for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
-+        pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
-+
-+        if (pp[DB_srptype][0] == DB_SRP_INDEX) {
-+            maxgN = i;
-+            if ((gNindex < 0) && (gN != NULL) && strcmp(gN, pp[DB_srpid]) == 0)
-+                gNindex = i;
-+
-+            print_index(db, i, verbose > 1);
-+        }
-+    }
-+
-+    if (verbose)
-+        BIO_printf(bio_err, "Database initialised\n");
-+
-+    if (gNindex >= 0) {
-+        gNrow = sk_OPENSSL_PSTRING_value(db->db->data, gNindex);
-+        print_entry(db, gNindex, verbose > 1, "Default g and N");
-+    } else if (maxgN > 0 && !SRP_get_default_gN(gN)) {
-+        BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN);
-+        goto end;
-+    } else {
-+        if (verbose)
-+            BIO_printf(bio_err, "Database has no g N information.\n");
-+        gNrow = NULL;
-+    }
-+
-+    if (verbose > 1)
-+        BIO_printf(bio_err, "Starting user processing\n");
-+
-+    if (argc > 0)
-+        user = *(argv++);
-+
-+    while (mode == OPT_LIST || user) {
-+        int userindex = -1;
-+
-+        if (user != NULL && verbose > 1)
-+            BIO_printf(bio_err, "Processing user \"%s\"\n", user);
-+        if ((userindex = get_index(db, user, 'U')) >= 0) {
-+            print_user(db, userindex, (verbose > 0) || mode == OPT_LIST);
-+        }
-+
-+        if (mode == OPT_LIST) {
-+            if (user == NULL) {
-+                BIO_printf(bio_err, "List all users\n");
-+
-+                for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
-+                    print_user(db, i, 1);
-+                }
-+            } else if (userindex < 0) {
-+                BIO_printf(bio_err,
-+                           "user \"%s\" does not exist, ignored. t\n", user);
-+                errors++;
-+            }
-+        } else if (mode == OPT_ADD) {
-+            if (userindex >= 0) {
-+                /* reactivation of a new user */
-+                char **row =
-+                    sk_OPENSSL_PSTRING_value(db->db->data, userindex);
-+                BIO_printf(bio_err, "user \"%s\" reactivated.\n", user);
-+                row[DB_srptype][0] = 'V';
-+
-+                doupdatedb = 1;
-+            } else {
-+                char *row[DB_NUMBER];
-+                char *gNid;
-+                row[DB_srpverifier] = NULL;
-+                row[DB_srpsalt] = NULL;
-+                row[DB_srpinfo] = NULL;
-+                if (!
-+                    (gNid =
-+                     srp_create_user(user, &(row[DB_srpverifier]),
-+                                     &(row[DB_srpsalt]),
-+                                     gNrow ? gNrow[DB_srpsalt] : gN,
-+                                     gNrow ? gNrow[DB_srpverifier] : NULL,
-+                                     passout, verbose))) {
-+                    BIO_printf(bio_err,
-+                               "Cannot create srp verifier for user \"%s\", operation abandoned .\n",
-+                               user);
-+                    errors++;
-+                    goto end;
-+                }
-+                row[DB_srpid] = OPENSSL_strdup(user);
-+                row[DB_srptype] = OPENSSL_strdup("v");
-+                row[DB_srpgN] = OPENSSL_strdup(gNid);
-+
-+                if ((row[DB_srpid] == NULL)
-+                    || (row[DB_srpgN] == NULL)
-+                    || (row[DB_srptype] == NULL)
-+                    || (row[DB_srpverifier] == NULL)
-+                    || (row[DB_srpsalt] == NULL)
-+                    || (userinfo
-+                        && ((row[DB_srpinfo] = OPENSSL_strdup(userinfo)) == NULL))
-+                    || !update_index(db, row)) {
-+                    OPENSSL_free(row[DB_srpid]);
-+                    OPENSSL_free(row[DB_srpgN]);
-+                    OPENSSL_free(row[DB_srpinfo]);
-+                    OPENSSL_free(row[DB_srptype]);
-+                    OPENSSL_free(row[DB_srpverifier]);
-+                    OPENSSL_free(row[DB_srpsalt]);
-+                    goto end;
-+                }
-+                doupdatedb = 1;
-+            }
-+        } else if (mode == OPT_MODIFY) {
-+            if (userindex < 0) {
-+                BIO_printf(bio_err,
-+                           "user \"%s\" does not exist, operation ignored.\n",
-+                           user);
-+                errors++;
-+            } else {
-+
-+                char **row =
-+                    sk_OPENSSL_PSTRING_value(db->db->data, userindex);
-+                char type = row[DB_srptype][0];
-+                if (type == 'v') {
-+                    BIO_printf(bio_err,
-+                               "user \"%s\" already updated, operation ignored.\n",
-+                               user);
-+                    errors++;
-+                } else {
-+                    char *gNid;
-+
-+                    if (row[DB_srptype][0] == 'V') {
-+                        int user_gN;
-+                        char **irow = NULL;
-+                        if (verbose)
-+                            BIO_printf(bio_err,
-+                                       "Verifying password for user \"%s\"\n",
-+                                       user);
-+                        if ((user_gN =
-+                             get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0)
-+                            irow =
-+                                sk_OPENSSL_PSTRING_value(db->db->data,
-+                                                         userindex);
-+
-+                        if (!srp_verify_user
-+                            (user, row[DB_srpverifier], row[DB_srpsalt],
-+                             irow ? irow[DB_srpsalt] : row[DB_srpgN],
-+                             irow ? irow[DB_srpverifier] : NULL, passin,
-+                             verbose)) {
-+                            BIO_printf(bio_err,
-+                                       "Invalid password for user \"%s\", operation abandoned.\n",
-+                                       user);
-+                            errors++;
-+                            goto end;
-+                        }
-+                    }
-+                    if (verbose)
-+                        BIO_printf(bio_err, "Password for user \"%s\" ok.\n",
-+                                   user);
-+
-+                    if (!
-+                        (gNid =
-+                         srp_create_user(user, &(row[DB_srpverifier]),
-+                                         &(row[DB_srpsalt]),
-+                                         gNrow ? gNrow[DB_srpsalt] : NULL,
-+                                         gNrow ? gNrow[DB_srpverifier] : NULL,
-+                                         passout, verbose))) {
-+                        BIO_printf(bio_err,
-+                                   "Cannot create srp verifier for user \"%s\", operation abandoned.\n",
-+                                   user);
-+                        errors++;
-+                        goto end;
-+                    }
-+
-+                    row[DB_srptype][0] = 'v';
-+                    row[DB_srpgN] = OPENSSL_strdup(gNid);
-+
-+                    if (row[DB_srpid] == NULL
-+                        || row[DB_srpgN] == NULL
-+                        || row[DB_srptype] == NULL
-+                        || row[DB_srpverifier] == NULL
-+                        || row[DB_srpsalt] == NULL
-+                        || (userinfo
-+                            && ((row[DB_srpinfo] = OPENSSL_strdup(userinfo))
-+                                == NULL)))
-+                        goto end;
-+
-+                    doupdatedb = 1;
-+                }
-+            }
-+        } else if (mode == OPT_DELETE) {
-+            if (userindex < 0) {
-+                BIO_printf(bio_err,
-+                           "user \"%s\" does not exist, operation ignored. t\n",
-+                           user);
-+                errors++;
-+            } else {
-+                char **xpp = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
-+
-+                BIO_printf(bio_err, "user \"%s\" revoked. t\n", user);
-+                xpp[DB_srptype][0] = 'R';
-+                doupdatedb = 1;
-+            }
-+        }
-+        if (--argc > 0)
-+            user = *(argv++);
-+        else {
-+            user = NULL;
-+        }
-+    }
-+
-+    if (verbose)
-+        BIO_printf(bio_err, "User procession done.\n");
-+
-+    if (doupdatedb) {
-+        /* Lets check some fields */
-+        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
-+            pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
-+
-+            if (pp[DB_srptype][0] == 'v') {
-+                pp[DB_srptype][0] = 'V';
-+                print_user(db, i, verbose);
-+            }
-+        }
-+
-+        if (verbose)
-+            BIO_printf(bio_err, "Trying to update srpvfile.\n");
-+        if (!save_index(srpvfile, "new", db))
-+            goto end;
-+
-+        if (verbose)
-+            BIO_printf(bio_err, "Temporary srpvfile created.\n");
-+        if (!rotate_index(srpvfile, "new", "old"))
-+            goto end;
-+
-+        if (verbose)
-+            BIO_printf(bio_err, "srpvfile updated.\n");
-+    }
-+
-+    ret = (errors != 0);
-+ end:
-+    if (errors != 0)
-+        if (verbose)
-+            BIO_printf(bio_err, "User errors %d.\n", errors);
-+
-+    if (verbose)
-+        BIO_printf(bio_err, "SRP terminating with code %d.\n", ret);
-+
-+    OPENSSL_free(passin);
-+    OPENSSL_free(passout);
-+    if (ret)
-+        ERR_print_errors(bio_err);
-+    if (randfile)
-+        app_RAND_write_file(randfile);
-+    NCONF_free(conf);
-+    free_index(db);
-+    release_engine(e);
-+    return (ret);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/testCA.pem b/CryptoPkg/Library/OpensslLib/openssl/apps/testCA.pem
-new file mode 100644
-index 0000000..dcb710a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/testCA.pem
-@@ -0,0 +1,8 @@
-+-----BEGIN CERTIFICATE REQUEST-----
-+MIIBBzCBsgIBADBNMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEX
-+MBUGA1UEChMOTWluY29tIFB0eSBMdGQxEDAOBgNVBAMTB1RFU1QgQ0EwXDANBgkq
-+hkiG9w0BAQEFAANLADBIAkEAzW9brgA8efT2ODB+NrsflJZj3KKqKsm4OrXTRqfL
-+VETj1ws/zCXl42XJAxdWQMCP0liKfc9Ut4xi1qCVI7N07wIDAQABoAAwDQYJKoZI
-+hvcNAQEEBQADQQBjZZ42Det9Uw0AFwJy4ufUEy5Cv74pxBp5SZnljgHY+Az0Hs2S
-+uNkIegr2ITX5azKi9nOkg9ZmsmGG13FIjiC/
-+-----END CERTIFICATE REQUEST-----
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/testdsa.h b/CryptoPkg/Library/OpensslLib/openssl/apps/testdsa.h
-new file mode 100644
-index 0000000..1e4502a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/testdsa.h
-@@ -0,0 +1,290 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* used by speed.c */
-+DSA *get_dsa512(void);
-+DSA *get_dsa1024(void);
-+DSA *get_dsa2048(void);
-+
-+static unsigned char dsa512_priv[] = {
-+    0x65, 0xe5, 0xc7, 0x38, 0x60, 0x24, 0xb5, 0x89, 0xd4, 0x9c, 0xeb, 0x4c,
-+    0x9c, 0x1d, 0x7a, 0x22, 0xbd, 0xd1, 0xc2, 0xd2,
-+};
-+
-+static unsigned char dsa512_pub[] = {
-+    0x00, 0x95, 0xa7, 0x0d, 0xec, 0x93, 0x68, 0xba, 0x5f, 0xf7, 0x5f, 0x07,
-+    0xf2, 0x3b, 0xad, 0x6b, 0x01, 0xdc, 0xbe, 0xec, 0xde, 0x04, 0x7a, 0x3a,
-+    0x27, 0xb3, 0xec, 0x49, 0xfd, 0x08, 0x43, 0x3d, 0x7e, 0xa8, 0x2c, 0x5e,
-+    0x7b, 0xbb, 0xfc, 0xf4, 0x6e, 0xeb, 0x6c, 0xb0, 0x6e, 0xf8, 0x02, 0x12,
-+    0x8c, 0x38, 0x5d, 0x83, 0x56, 0x7d, 0xee, 0x53, 0x05, 0x3e, 0x24, 0x84,
-+    0xbe, 0xba, 0x0a, 0x6b, 0xc8,
-+};
-+
-+static unsigned char dsa512_p[] = {
-+    0x9D, 0x1B, 0x69, 0x8E, 0x26, 0xDB, 0xF2, 0x2B, 0x11, 0x70, 0x19, 0x86,
-+    0xF6, 0x19, 0xC8, 0xF8, 0x19, 0xF2, 0x18, 0x53, 0x94, 0x46, 0x06, 0xD0,
-+    0x62, 0x50, 0x33, 0x4B, 0x02, 0x3C, 0x52, 0x30, 0x03, 0x8B, 0x3B, 0xF9,
-+    0x5F, 0xD1, 0x24, 0x06, 0x4F, 0x7B, 0x4C, 0xBA, 0xAA, 0x40, 0x9B, 0xFD,
-+    0x96, 0xE4, 0x37, 0x33, 0xBB, 0x2D, 0x5A, 0xD7, 0x5A, 0x11, 0x40, 0x66,
-+    0xA2, 0x76, 0x7D, 0x31,
-+};
-+
-+static unsigned char dsa512_q[] = {
-+    0xFB, 0x53, 0xEF, 0x50, 0xB4, 0x40, 0x92, 0x31, 0x56, 0x86, 0x53, 0x7A,
-+    0xE8, 0x8B, 0x22, 0x9A, 0x49, 0xFB, 0x71, 0x8F,
-+};
-+
-+static unsigned char dsa512_g[] = {
-+    0x83, 0x3E, 0x88, 0xE5, 0xC5, 0x89, 0x73, 0xCE, 0x3B, 0x6C, 0x01, 0x49,
-+    0xBF, 0xB3, 0xC7, 0x9F, 0x0A, 0xEA, 0x44, 0x91, 0xE5, 0x30, 0xAA, 0xD9,
-+    0xBE, 0x5B, 0x5F, 0xB7, 0x10, 0xD7, 0x89, 0xB7, 0x8E, 0x74, 0xFB, 0xCF,
-+    0x29, 0x1E, 0xEB, 0xA8, 0x2C, 0x54, 0x51, 0xB8, 0x10, 0xDE, 0xA0, 0xCE,
-+    0x2F, 0xCC, 0x24, 0x6B, 0x90, 0x77, 0xDE, 0xA2, 0x68, 0xA6, 0x52, 0x12,
-+    0xA2, 0x03, 0x9D, 0x20,
-+};
-+
-+DSA *get_dsa512()
-+{
-+    DSA *dsa;
-+    BIGNUM *priv_key, *pub_key, *p, *q, *g;
-+
-+    if ((dsa = DSA_new()) == NULL)
-+        return (NULL);
-+    priv_key = BN_bin2bn(dsa512_priv, sizeof(dsa512_priv), NULL);
-+    pub_key = BN_bin2bn(dsa512_pub, sizeof(dsa512_pub), NULL);
-+    p = BN_bin2bn(dsa512_p, sizeof(dsa512_p), NULL);
-+    q = BN_bin2bn(dsa512_q, sizeof(dsa512_q), NULL);
-+    g = BN_bin2bn(dsa512_g, sizeof(dsa512_g), NULL);
-+    if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
-+            || (g == NULL)) {
-+        goto err;
-+    }
-+    if (!DSA_set0_pqg(dsa, p, q, g))
-+        goto err;
-+    p = q = g = NULL;
-+
-+    if (!DSA_set0_key(dsa, pub_key, priv_key))
-+        goto err;
-+
-+    return dsa;
-+ err:
-+    DSA_free(dsa);
-+    BN_free(priv_key);
-+    BN_free(pub_key);
-+    BN_free(p);
-+    BN_free(q);
-+    BN_free(g);
-+    return NULL;
-+}
-+
-+static unsigned char dsa1024_priv[] = {
-+    0x7d, 0x21, 0xda, 0xbb, 0x62, 0x15, 0x47, 0x36, 0x07, 0x67, 0x12, 0xe8,
-+    0x8c, 0xaa, 0x1c, 0xcd, 0x38, 0x12, 0x61, 0x18,
-+};
-+
-+static unsigned char dsa1024_pub[] = {
-+    0x3c, 0x4e, 0x9c, 0x2a, 0x7f, 0x16, 0xc1, 0x25, 0xeb, 0xac, 0x78, 0x63,
-+    0x90, 0x14, 0x8c, 0x8b, 0xf4, 0x68, 0x43, 0x3c, 0x2d, 0xee, 0x65, 0x50,
-+    0x7d, 0x9c, 0x8f, 0x8c, 0x8a, 0x51, 0xd6, 0x11, 0x2b, 0x99, 0xaf, 0x1e,
-+    0x90, 0x97, 0xb5, 0xd3, 0xa6, 0x20, 0x25, 0xd6, 0xfe, 0x43, 0x02, 0xd5,
-+    0x91, 0x7d, 0xa7, 0x8c, 0xdb, 0xc9, 0x85, 0xa3, 0x36, 0x48, 0xf7, 0x68,
-+    0xaa, 0x60, 0xb1, 0xf7, 0x05, 0x68, 0x3a, 0xa3, 0x3f, 0xd3, 0x19, 0x82,
-+    0xd8, 0x82, 0x7a, 0x77, 0xfb, 0xef, 0xf4, 0x15, 0x0a, 0xeb, 0x06, 0x04,
-+    0x7f, 0x53, 0x07, 0x0c, 0xbc, 0xcb, 0x2d, 0x83, 0xdb, 0x3e, 0xd1, 0x28,
-+    0xa5, 0xa1, 0x31, 0xe0, 0x67, 0xfa, 0x50, 0xde, 0x9b, 0x07, 0x83, 0x7e,
-+    0x2c, 0x0b, 0xc3, 0x13, 0x50, 0x61, 0xe5, 0xad, 0xbd, 0x36, 0xb8, 0x97,
-+    0x4e, 0x40, 0x7d, 0xe8, 0x83, 0x0d, 0xbc, 0x4b
-+};
-+
-+static unsigned char dsa1024_p[] = {
-+    0xA7, 0x3F, 0x6E, 0x85, 0xBF, 0x41, 0x6A, 0x29, 0x7D, 0xF0, 0x9F, 0x47,
-+    0x19, 0x30, 0x90, 0x9A, 0x09, 0x1D, 0xDA, 0x6A, 0x33, 0x1E, 0xC5, 0x3D,
-+    0x86, 0x96, 0xB3, 0x15, 0xE0, 0x53, 0x2E, 0x8F, 0xE0, 0x59, 0x82, 0x73,
-+    0x90, 0x3E, 0x75, 0x31, 0x99, 0x47, 0x7A, 0x52, 0xFB, 0x85, 0xE4, 0xD9,
-+    0xA6, 0x7B, 0x38, 0x9B, 0x68, 0x8A, 0x84, 0x9B, 0x87, 0xC6, 0x1E, 0xB5,
-+    0x7E, 0x86, 0x4B, 0x53, 0x5B, 0x59, 0xCF, 0x71, 0x65, 0x19, 0x88, 0x6E,
-+    0xCE, 0x66, 0xAE, 0x6B, 0x88, 0x36, 0xFB, 0xEC, 0x28, 0xDC, 0xC2, 0xD7,
-+    0xA5, 0xBB, 0xE5, 0x2C, 0x39, 0x26, 0x4B, 0xDA, 0x9A, 0x70, 0x18, 0x95,
-+    0x37, 0x95, 0x10, 0x56, 0x23, 0xF6, 0x15, 0xED, 0xBA, 0x04, 0x5E, 0xDE,
-+    0x39, 0x4F, 0xFD, 0xB7, 0x43, 0x1F, 0xB5, 0xA4, 0x65, 0x6F, 0xCD, 0x80,
-+    0x11, 0xE4, 0x70, 0x95, 0x5B, 0x50, 0xCD, 0x49,
-+};
-+
-+static unsigned char dsa1024_q[] = {
-+    0xF7, 0x07, 0x31, 0xED, 0xFA, 0x6C, 0x06, 0x03, 0xD5, 0x85, 0x8A, 0x1C,
-+    0xAC, 0x9C, 0x65, 0xE7, 0x50, 0x66, 0x65, 0x6F,
-+};
-+
-+static unsigned char dsa1024_g[] = {
-+    0x4D, 0xDF, 0x4C, 0x03, 0xA6, 0x91, 0x8A, 0xF5, 0x19, 0x6F, 0x50, 0x46,
-+    0x25, 0x99, 0xE5, 0x68, 0x6F, 0x30, 0xE3, 0x69, 0xE1, 0xE5, 0xB3, 0x5D,
-+    0x98, 0xBB, 0x28, 0x86, 0x48, 0xFC, 0xDE, 0x99, 0x04, 0x3F, 0x5F, 0x88,
-+    0x0C, 0x9C, 0x73, 0x24, 0x0D, 0x20, 0x5D, 0xB9, 0x2A, 0x9A, 0x3F, 0x18,
-+    0x96, 0x27, 0xE4, 0x62, 0x87, 0xC1, 0x7B, 0x74, 0x62, 0x53, 0xFC, 0x61,
-+    0x27, 0xA8, 0x7A, 0x91, 0x09, 0x9D, 0xB6, 0xF1, 0x4D, 0x9C, 0x54, 0x0F,
-+    0x58, 0x06, 0xEE, 0x49, 0x74, 0x07, 0xCE, 0x55, 0x7E, 0x23, 0xCE, 0x16,
-+    0xF6, 0xCA, 0xDC, 0x5A, 0x61, 0x01, 0x7E, 0xC9, 0x71, 0xB5, 0x4D, 0xF6,
-+    0xDC, 0x34, 0x29, 0x87, 0x68, 0xF6, 0x5E, 0x20, 0x93, 0xB3, 0xDB, 0xF5,
-+    0xE4, 0x09, 0x6C, 0x41, 0x17, 0x95, 0x92, 0xEB, 0x01, 0xB5, 0x73, 0xA5,
-+    0x6A, 0x7E, 0xD8, 0x32, 0xED, 0x0E, 0x02, 0xB8,
-+};
-+
-+DSA *get_dsa1024()
-+{
-+    DSA *dsa;
-+    BIGNUM *priv_key, *pub_key, *p, *q, *g;
-+
-+    if ((dsa = DSA_new()) == NULL)
-+        return (NULL);
-+    priv_key = BN_bin2bn(dsa1024_priv, sizeof(dsa1024_priv), NULL);
-+    pub_key = BN_bin2bn(dsa1024_pub, sizeof(dsa1024_pub), NULL);
-+    p = BN_bin2bn(dsa1024_p, sizeof(dsa1024_p), NULL);
-+    q = BN_bin2bn(dsa1024_q, sizeof(dsa1024_q), NULL);
-+    g = BN_bin2bn(dsa1024_g, sizeof(dsa1024_g), NULL);
-+    if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
-+            || (g == NULL)) {
-+        goto err;
-+    }
-+    if (!DSA_set0_pqg(dsa, p, q, g))
-+        goto err;
-+    p = q = g = NULL;
-+
-+    if (!DSA_set0_key(dsa, pub_key, priv_key))
-+        goto err;
-+
-+    return dsa;
-+ err:
-+    DSA_free(dsa);
-+    BN_free(priv_key);
-+    BN_free(pub_key);
-+    BN_free(p);
-+    BN_free(q);
-+    BN_free(g);
-+    return NULL;
-+}
-+
-+static unsigned char dsa2048_priv[] = {
-+    0x32, 0x67, 0x92, 0xf6, 0xc4, 0xe2, 0xe2, 0xe8, 0xa0, 0x8b, 0x6b, 0x45,
-+    0x0c, 0x8a, 0x76, 0xb0, 0xee, 0xcf, 0x91, 0xa7,
-+};
-+
-+static unsigned char dsa2048_pub[] = {
-+    0x17, 0x8f, 0xa8, 0x11, 0x84, 0x92, 0xec, 0x83, 0x47, 0xc7, 0x6a, 0xb0,
-+    0x92, 0xaf, 0x5a, 0x20, 0x37, 0xa3, 0x64, 0x79, 0xd2, 0xd0, 0x3d, 0xcd,
-+    0xe0, 0x61, 0x88, 0x88, 0x21, 0xcc, 0x74, 0x5d, 0xce, 0x4c, 0x51, 0x47,
-+    0xf0, 0xc5, 0x5c, 0x4c, 0x82, 0x7a, 0xaf, 0x72, 0xad, 0xb9, 0xe0, 0x53,
-+    0xf2, 0x78, 0xb7, 0xf0, 0xb5, 0x48, 0x7f, 0x8a, 0x3a, 0x18, 0xd1, 0x9f,
-+    0x8b, 0x7d, 0xa5, 0x47, 0xb7, 0x95, 0xab, 0x98, 0xf8, 0x7b, 0x74, 0x50,
-+    0x56, 0x8e, 0x57, 0xf0, 0xee, 0xf5, 0xb7, 0xba, 0xab, 0x85, 0x86, 0xf9,
-+    0x2b, 0xef, 0x41, 0x56, 0xa0, 0xa4, 0x9f, 0xb7, 0x38, 0x00, 0x46, 0x0a,
-+    0xa6, 0xf1, 0xfc, 0x1f, 0xd8, 0x4e, 0x85, 0x44, 0x92, 0x43, 0x21, 0x5d,
-+    0x6e, 0xcc, 0xc2, 0xcb, 0x26, 0x31, 0x0d, 0x21, 0xc4, 0xbd, 0x8d, 0x24,
-+    0xbc, 0xd9, 0x18, 0x19, 0xd7, 0xdc, 0xf1, 0xe7, 0x93, 0x50, 0x48, 0x03,
-+    0x2c, 0xae, 0x2e, 0xe7, 0x49, 0x88, 0x5f, 0x93, 0x57, 0x27, 0x99, 0x36,
-+    0xb4, 0x20, 0xab, 0xfc, 0xa7, 0x2b, 0xf2, 0xd9, 0x98, 0xd7, 0xd4, 0x34,
-+    0x9d, 0x96, 0x50, 0x58, 0x9a, 0xea, 0x54, 0xf3, 0xee, 0xf5, 0x63, 0x14,
-+    0xee, 0x85, 0x83, 0x74, 0x76, 0xe1, 0x52, 0x95, 0xc3, 0xf7, 0xeb, 0x04,
-+    0x04, 0x7b, 0xa7, 0x28, 0x1b, 0xcc, 0xea, 0x4a, 0x4e, 0x84, 0xda, 0xd8,
-+    0x9c, 0x79, 0xd8, 0x9b, 0x66, 0x89, 0x2f, 0xcf, 0xac, 0xd7, 0x79, 0xf9,
-+    0xa9, 0xd8, 0x45, 0x13, 0x78, 0xb9, 0x00, 0x14, 0xc9, 0x7e, 0x22, 0x51,
-+    0x86, 0x67, 0xb0, 0x9f, 0x26, 0x11, 0x23, 0xc8, 0x38, 0xd7, 0x70, 0x1d,
-+    0x15, 0x8e, 0x4d, 0x4f, 0x95, 0x97, 0x40, 0xa1, 0xc2, 0x7e, 0x01, 0x18,
-+    0x72, 0xf4, 0x10, 0xe6, 0x8d, 0x52, 0x16, 0x7f, 0xf2, 0xc9, 0xf8, 0x33,
-+    0x8b, 0x33, 0xb7, 0xce,
-+};
-+
-+static unsigned char dsa2048_p[] = {
-+    0xA0, 0x25, 0xFA, 0xAD, 0xF4, 0x8E, 0xB9, 0xE5, 0x99, 0xF3, 0x5D, 0x6F,
-+    0x4F, 0x83, 0x34, 0xE2, 0x7E, 0xCF, 0x6F, 0xBF, 0x30, 0xAF, 0x6F, 0x81,
-+    0xEB, 0xF8, 0xC4, 0x13, 0xD9, 0xA0, 0x5D, 0x8B, 0x5C, 0x8E, 0xDC, 0xC2,
-+    0x1D, 0x0B, 0x41, 0x32, 0xB0, 0x1F, 0xFE, 0xEF, 0x0C, 0xC2, 0xA2, 0x7E,
-+    0x68, 0x5C, 0x28, 0x21, 0xE9, 0xF5, 0xB1, 0x58, 0x12, 0x63, 0x4C, 0x19,
-+    0x4E, 0xFF, 0x02, 0x4B, 0x92, 0xED, 0xD2, 0x07, 0x11, 0x4D, 0x8C, 0x58,
-+    0x16, 0x5C, 0x55, 0x8E, 0xAD, 0xA3, 0x67, 0x7D, 0xB9, 0x86, 0x6E, 0x0B,
-+    0xE6, 0x54, 0x6F, 0x40, 0xAE, 0x0E, 0x67, 0x4C, 0xF9, 0x12, 0x5B, 0x3C,
-+    0x08, 0x7A, 0xF7, 0xFC, 0x67, 0x86, 0x69, 0xE7, 0x0A, 0x94, 0x40, 0xBF,
-+    0x8B, 0x76, 0xFE, 0x26, 0xD1, 0xF2, 0xA1, 0x1A, 0x84, 0xA1, 0x43, 0x56,
-+    0x28, 0xBC, 0x9A, 0x5F, 0xD7, 0x3B, 0x69, 0x89, 0x8A, 0x36, 0x2C, 0x51,
-+    0xDF, 0x12, 0x77, 0x2F, 0x57, 0x7B, 0xA0, 0xAA, 0xDD, 0x7F, 0xA1, 0x62,
-+    0x3B, 0x40, 0x7B, 0x68, 0x1A, 0x8F, 0x0D, 0x38, 0xBB, 0x21, 0x5D, 0x18,
-+    0xFC, 0x0F, 0x46, 0xF7, 0xA3, 0xB0, 0x1D, 0x23, 0xC3, 0xD2, 0xC7, 0x72,
-+    0x51, 0x18, 0xDF, 0x46, 0x95, 0x79, 0xD9, 0xBD, 0xB5, 0x19, 0x02, 0x2C,
-+    0x87, 0xDC, 0xE7, 0x57, 0x82, 0x7E, 0xF1, 0x8B, 0x06, 0x3D, 0x00, 0xA5,
-+    0x7B, 0x6B, 0x26, 0x27, 0x91, 0x0F, 0x6A, 0x77, 0xE4, 0xD5, 0x04, 0xE4,
-+    0x12, 0x2C, 0x42, 0xFF, 0xD2, 0x88, 0xBB, 0xD3, 0x92, 0xA0, 0xF9, 0xC8,
-+    0x51, 0x64, 0x14, 0x5C, 0xD8, 0xF9, 0x6C, 0x47, 0x82, 0xB4, 0x1C, 0x7F,
-+    0x09, 0xB8, 0xF0, 0x25, 0x83, 0x1D, 0x3F, 0x3F, 0x05, 0xB3, 0x21, 0x0A,
-+    0x5D, 0xA7, 0xD8, 0x54, 0xC3, 0x65, 0x7D, 0xC3, 0xB0, 0x1D, 0xBF, 0xAE,
-+    0xF8, 0x68, 0xCF, 0x9B,
-+};
-+
-+static unsigned char dsa2048_q[] = {
-+    0x97, 0xE7, 0x33, 0x4D, 0xD3, 0x94, 0x3E, 0x0B, 0xDB, 0x62, 0x74, 0xC6,
-+    0xA1, 0x08, 0xDD, 0x19, 0xA3, 0x75, 0x17, 0x1B,
-+};
-+
-+static unsigned char dsa2048_g[] = {
-+    0x2C, 0x78, 0x16, 0x59, 0x34, 0x63, 0xF4, 0xF3, 0x92, 0xFC, 0xB5, 0xA5,
-+    0x4F, 0x13, 0xDE, 0x2F, 0x1C, 0xA4, 0x3C, 0xAE, 0xAD, 0x38, 0x3F, 0x7E,
-+    0x90, 0xBF, 0x96, 0xA6, 0xAE, 0x25, 0x90, 0x72, 0xF5, 0x8E, 0x80, 0x0C,
-+    0x39, 0x1C, 0xD9, 0xEC, 0xBA, 0x90, 0x5B, 0x3A, 0xE8, 0x58, 0x6C, 0x9E,
-+    0x30, 0x42, 0x37, 0x02, 0x31, 0x82, 0xBC, 0x6A, 0xDF, 0x6A, 0x09, 0x29,
-+    0xE3, 0xC0, 0x46, 0xD1, 0xCB, 0x85, 0xEC, 0x0C, 0x30, 0x5E, 0xEA, 0xC8,
-+    0x39, 0x8E, 0x22, 0x9F, 0x22, 0x10, 0xD2, 0x34, 0x61, 0x68, 0x37, 0x3D,
-+    0x2E, 0x4A, 0x5B, 0x9A, 0xF5, 0xC1, 0x48, 0xC6, 0xF6, 0xDC, 0x63, 0x1A,
-+    0xD3, 0x96, 0x64, 0xBA, 0x34, 0xC9, 0xD1, 0xA0, 0xD1, 0xAE, 0x6C, 0x2F,
-+    0x48, 0x17, 0x93, 0x14, 0x43, 0xED, 0xF0, 0x21, 0x30, 0x19, 0xC3, 0x1B,
-+    0x5F, 0xDE, 0xA3, 0xF0, 0x70, 0x78, 0x18, 0xE1, 0xA8, 0xE4, 0xEE, 0x2E,
-+    0x00, 0xA5, 0xE4, 0xB3, 0x17, 0xC8, 0x0C, 0x7D, 0x6E, 0x42, 0xDC, 0xB7,
-+    0x46, 0x00, 0x36, 0x4D, 0xD4, 0x46, 0xAA, 0x3D, 0x3C, 0x46, 0x89, 0x40,
-+    0xBF, 0x1D, 0x84, 0x77, 0x0A, 0x75, 0xF3, 0x87, 0x1D, 0x08, 0x4C, 0xA6,
-+    0xD1, 0xA9, 0x1C, 0x1E, 0x12, 0x1E, 0xE1, 0xC7, 0x30, 0x28, 0x76, 0xA5,
-+    0x7F, 0x6C, 0x85, 0x96, 0x2B, 0x6F, 0xDB, 0x80, 0x66, 0x26, 0xAE, 0xF5,
-+    0x93, 0xC7, 0x8E, 0xAE, 0x9A, 0xED, 0xE4, 0xCA, 0x04, 0xEA, 0x3B, 0x72,
-+    0xEF, 0xDC, 0x87, 0xED, 0x0D, 0xA5, 0x4C, 0x4A, 0xDD, 0x71, 0x22, 0x64,
-+    0x59, 0x69, 0x4E, 0x8E, 0xBF, 0x43, 0xDC, 0xAB, 0x8E, 0x66, 0xBB, 0x01,
-+    0xB6, 0xF4, 0xE7, 0xFD, 0xD2, 0xAD, 0x9F, 0x36, 0xC1, 0xA0, 0x29, 0x99,
-+    0xD1, 0x96, 0x70, 0x59, 0x06, 0x78, 0x35, 0xBD, 0x65, 0x55, 0x52, 0x9E,
-+    0xF8, 0xB2, 0xE5, 0x38,
-+};
-+
-+DSA *get_dsa2048()
-+{
-+    DSA *dsa;
-+    BIGNUM *priv_key, *pub_key, *p, *q, *g;
-+
-+    if ((dsa = DSA_new()) == NULL)
-+        return (NULL);
-+    priv_key = BN_bin2bn(dsa2048_priv, sizeof(dsa2048_priv), NULL);
-+    pub_key = BN_bin2bn(dsa2048_pub, sizeof(dsa2048_pub), NULL);
-+    p = BN_bin2bn(dsa2048_p, sizeof(dsa2048_p), NULL);
-+    q = BN_bin2bn(dsa2048_q, sizeof(dsa2048_q), NULL);
-+    g = BN_bin2bn(dsa2048_g, sizeof(dsa2048_g), NULL);
-+    if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
-+            || (g == NULL)) {
-+        goto err;
-+    }
-+    if (!DSA_set0_pqg(dsa, p, q, g))
-+        goto err;
-+    p = q = g = NULL;
-+
-+    if (!DSA_set0_key(dsa, pub_key, priv_key))
-+        goto err;
-+
-+    return dsa;
-+ err:
-+    DSA_free(dsa);
-+    BN_free(priv_key);
-+    BN_free(pub_key);
-+    BN_free(p);
-+    BN_free(q);
-+    BN_free(g);
-+    return NULL;
-+}
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/testrsa.h b/CryptoPkg/Library/OpensslLib/openssl/apps/testrsa.h
-new file mode 100644
-index 0000000..1350ce5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/testrsa.h
-@@ -0,0 +1,1960 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+static unsigned char test512[] = {
-+    0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
-+    0xd6, 0x33, 0xb9, 0xc8, 0xfb, 0x4f, 0x3c, 0x7d, 0xc0, 0x01,
-+    0x86, 0xd0, 0xe7, 0xa0, 0x55, 0xf2, 0x95, 0x93, 0xcc, 0x4f,
-+    0xb7, 0x5b, 0x67, 0x5b, 0x94, 0x68, 0xc9, 0x34, 0x15, 0xde,
-+    0xa5, 0x2e, 0x1c, 0x33, 0xc2, 0x6e, 0xfc, 0x34, 0x5e, 0x71,
-+    0x13, 0xb7, 0xd6, 0xee, 0xd8, 0xa5, 0x65, 0x05, 0x72, 0x87,
-+    0xa8, 0xb0, 0x77, 0xfe, 0x57, 0xf5, 0xfc, 0x5f, 0x55, 0x83,
-+    0x87, 0xdd, 0x57, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
-+    0x41, 0x00, 0xa7, 0xf7, 0x91, 0xc5, 0x0f, 0x84, 0x57, 0xdc,
-+    0x07, 0xf7, 0x6a, 0x7f, 0x60, 0x52, 0xb3, 0x72, 0xf1, 0x66,
-+    0x1f, 0x7d, 0x97, 0x3b, 0x9e, 0xb6, 0x0a, 0x8f, 0x8c, 0xcf,
-+    0x42, 0x23, 0x00, 0x04, 0xd4, 0x28, 0x0e, 0x1c, 0x90, 0xc4,
-+    0x11, 0x25, 0x25, 0xa5, 0x93, 0xa5, 0x2f, 0x70, 0x02, 0xdf,
-+    0x81, 0x9c, 0x49, 0x03, 0xa0, 0xf8, 0x6d, 0x54, 0x2e, 0x26,
-+    0xde, 0xaa, 0x85, 0x59, 0xa8, 0x31, 0x02, 0x21, 0x00, 0xeb,
-+    0x47, 0xd7, 0x3b, 0xf6, 0xc3, 0xdd, 0x5a, 0x46, 0xc5, 0xb9,
-+    0x2b, 0x9a, 0xa0, 0x09, 0x8f, 0xa6, 0xfb, 0xf3, 0x78, 0x7a,
-+    0x33, 0x70, 0x9d, 0x0f, 0x42, 0x6b, 0x13, 0x68, 0x24, 0xd3,
-+    0x15, 0x02, 0x21, 0x00, 0xe9, 0x10, 0xb0, 0xb3, 0x0d, 0xe2,
-+    0x82, 0x68, 0x77, 0x8a, 0x6e, 0x7c, 0xda, 0xbc, 0x3e, 0x53,
-+    0x83, 0xfb, 0xd6, 0x22, 0xe7, 0xb5, 0xae, 0x6e, 0x80, 0xda,
-+    0x00, 0x55, 0x97, 0xc1, 0xd0, 0x65, 0x02, 0x20, 0x4c, 0xf8,
-+    0x73, 0xb1, 0x6a, 0x49, 0x29, 0x61, 0x1f, 0x46, 0x10, 0x0d,
-+    0xf3, 0xc7, 0xe7, 0x58, 0xd7, 0x88, 0x15, 0x5e, 0x94, 0x9b,
-+    0xbf, 0x7b, 0xa2, 0x42, 0x58, 0x45, 0x41, 0x0c, 0xcb, 0x01,
-+    0x02, 0x20, 0x12, 0x11, 0xba, 0x31, 0x57, 0x9d, 0x3d, 0x11,
-+    0x0e, 0x5b, 0x8c, 0x2f, 0x5f, 0xe2, 0x02, 0x4f, 0x05, 0x47,
-+    0x8c, 0x15, 0x8e, 0xb3, 0x56, 0x3f, 0xb8, 0xfb, 0xad, 0xd4,
-+    0xf4, 0xfc, 0x10, 0xc5, 0x02, 0x20, 0x18, 0xa1, 0x29, 0x99,
-+    0x5b, 0xd9, 0xc8, 0xd4, 0xfc, 0x49, 0x7a, 0x2a, 0x21, 0x2c,
-+    0x49, 0xe4, 0x4f, 0xeb, 0xef, 0x51, 0xf1, 0xab, 0x6d, 0xfb,
-+    0x4b, 0x14, 0xe9, 0x4b, 0x52, 0xb5, 0x82, 0x2c,
-+};
-+
-+static unsigned char test1024[] = {
-+    0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81,
-+    0x00, 0xdc, 0x98, 0x43, 0xe8, 0x3d, 0x43, 0x5b, 0xe4, 0x05,
-+    0xcd, 0xd0, 0xa9, 0x3e, 0xcb, 0x83, 0x75, 0xf6, 0xb5, 0xa5,
-+    0x9f, 0x6b, 0xe9, 0x34, 0x41, 0x29, 0x18, 0xfa, 0x6a, 0x55,
-+    0x4d, 0x70, 0xfc, 0xec, 0xae, 0x87, 0x38, 0x0a, 0x20, 0xa9,
-+    0xc0, 0x45, 0x77, 0x6e, 0x57, 0x60, 0x57, 0xf4, 0xed, 0x96,
-+    0x22, 0xcb, 0x8f, 0xe1, 0x33, 0x3a, 0x17, 0x1f, 0xed, 0x37,
-+    0xa5, 0x6f, 0xeb, 0xa6, 0xbc, 0x12, 0x80, 0x1d, 0x53, 0xbd,
-+    0x70, 0xeb, 0x21, 0x76, 0x3e, 0xc9, 0x2f, 0x1a, 0x45, 0x24,
-+    0x82, 0xff, 0xcd, 0x59, 0x32, 0x06, 0x2e, 0x12, 0x3b, 0x23,
-+    0x78, 0xed, 0x12, 0x3d, 0xe0, 0x8d, 0xf9, 0x67, 0x4f, 0x37,
-+    0x4e, 0x47, 0x02, 0x4c, 0x2d, 0xc0, 0x4f, 0x1f, 0xb3, 0x94,
-+    0xe1, 0x41, 0x2e, 0x2d, 0x90, 0x10, 0xfc, 0x82, 0x91, 0x8b,
-+    0x0f, 0x22, 0xd4, 0xf2, 0xfc, 0x2c, 0xab, 0x53, 0x55, 0x02,
-+    0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x2b, 0xcc, 0x3f,
-+    0x8f, 0x58, 0xba, 0x8b, 0x00, 0x16, 0xf6, 0xea, 0x3a, 0xf0,
-+    0x30, 0xd0, 0x05, 0x17, 0xda, 0xb0, 0xeb, 0x9a, 0x2d, 0x4f,
-+    0x26, 0xb0, 0xd6, 0x38, 0xc1, 0xeb, 0xf5, 0xd8, 0x3d, 0x1f,
-+    0x70, 0xf7, 0x7f, 0xf4, 0xe2, 0xcf, 0x51, 0x51, 0x79, 0x88,
-+    0xfa, 0xe8, 0x32, 0x0e, 0x7b, 0x2d, 0x97, 0xf2, 0xfa, 0xba,
-+    0x27, 0xc5, 0x9c, 0xd9, 0xc5, 0xeb, 0x8a, 0x79, 0x52, 0x3c,
-+    0x64, 0x34, 0x7d, 0xc2, 0xcf, 0x28, 0xc7, 0x4e, 0xd5, 0x43,
-+    0x0b, 0xd1, 0xa6, 0xca, 0x6d, 0x03, 0x2d, 0x72, 0x23, 0xbc,
-+    0x6d, 0x05, 0xfa, 0x16, 0x09, 0x2f, 0x2e, 0x5c, 0xb6, 0xee,
-+    0x74, 0xdd, 0xd2, 0x48, 0x8e, 0x36, 0x0c, 0x06, 0x3d, 0x4d,
-+    0xe5, 0x10, 0x82, 0xeb, 0x6a, 0xf3, 0x4b, 0x9f, 0xd6, 0xed,
-+    0x11, 0xb1, 0x6e, 0xec, 0xf4, 0xfe, 0x8e, 0x75, 0x94, 0x20,
-+    0x2f, 0xcb, 0xac, 0x46, 0xf1, 0x02, 0x41, 0x00, 0xf9, 0x8c,
-+    0xa3, 0x85, 0xb1, 0xdd, 0x29, 0xaf, 0x65, 0xc1, 0x33, 0xf3,
-+    0x95, 0xc5, 0x52, 0x68, 0x0b, 0xd4, 0xf1, 0xe5, 0x0e, 0x02,
-+    0x9f, 0x4f, 0xfa, 0x77, 0xdc, 0x46, 0x9e, 0xc7, 0xa6, 0xe4,
-+    0x16, 0x29, 0xda, 0xb0, 0x07, 0xcf, 0x5b, 0xa9, 0x12, 0x8a,
-+    0xdd, 0x63, 0x0a, 0xde, 0x2e, 0x8c, 0x66, 0x8b, 0x8c, 0xdc,
-+    0x19, 0xa3, 0x7e, 0xf4, 0x3b, 0xd0, 0x1a, 0x8c, 0xa4, 0xc2,
-+    0xe1, 0xd3, 0x02, 0x41, 0x00, 0xe2, 0x4c, 0x05, 0xf2, 0x04,
-+    0x86, 0x4e, 0x61, 0x43, 0xdb, 0xb0, 0xb9, 0x96, 0x86, 0x52,
-+    0x2c, 0xca, 0x8d, 0x7b, 0xab, 0x0b, 0x13, 0x0d, 0x7e, 0x38,
-+    0x5b, 0xe2, 0x2e, 0x7b, 0x0e, 0xe7, 0x19, 0x99, 0x38, 0xe7,
-+    0xf2, 0x21, 0xbd, 0x85, 0x85, 0xe3, 0xfd, 0x28, 0x77, 0x20,
-+    0x31, 0x71, 0x2c, 0xd0, 0xff, 0xfb, 0x2e, 0xaf, 0x85, 0xb4,
-+    0x86, 0xca, 0xf3, 0xbb, 0xca, 0xaa, 0x0f, 0x95, 0x37, 0x02,
-+    0x40, 0x0e, 0x41, 0x9a, 0x95, 0xe8, 0xb3, 0x59, 0xce, 0x4b,
-+    0x61, 0xde, 0x35, 0xec, 0x38, 0x79, 0x9c, 0xb8, 0x10, 0x52,
-+    0x41, 0x63, 0xab, 0x82, 0xae, 0x6f, 0x00, 0xa9, 0xf4, 0xde,
-+    0xdd, 0x49, 0x0b, 0x7e, 0xb8, 0xa5, 0x65, 0xa9, 0x0c, 0x8f,
-+    0x8f, 0xf9, 0x1f, 0x35, 0xc6, 0x92, 0xb8, 0x5e, 0xb0, 0x66,
-+    0xab, 0x52, 0x40, 0xc0, 0xb6, 0x36, 0x6a, 0x7d, 0x80, 0x46,
-+    0x04, 0x02, 0xe5, 0x9f, 0x41, 0x02, 0x41, 0x00, 0xc0, 0xad,
-+    0xcc, 0x4e, 0x21, 0xee, 0x1d, 0x24, 0x91, 0xfb, 0xa7, 0x80,
-+    0x8d, 0x9a, 0xb6, 0xb3, 0x2e, 0x8f, 0xc2, 0xe1, 0x82, 0xdf,
-+    0x69, 0x18, 0xb4, 0x71, 0xff, 0xa6, 0x65, 0xde, 0xed, 0x84,
-+    0x8d, 0x42, 0xb7, 0xb3, 0x21, 0x69, 0x56, 0x1c, 0x07, 0x60,
-+    0x51, 0x29, 0x04, 0xff, 0x34, 0x06, 0xdd, 0xb9, 0x67, 0x2c,
-+    0x7c, 0x04, 0x93, 0x0e, 0x46, 0x15, 0xbb, 0x2a, 0xb7, 0x1b,
-+    0xe7, 0x87, 0x02, 0x40, 0x78, 0xda, 0x5d, 0x07, 0x51, 0x0c,
-+    0x16, 0x7a, 0x9f, 0x29, 0x20, 0x84, 0x0d, 0x42, 0xfa, 0xd7,
-+    0x00, 0xd8, 0x77, 0x7e, 0xb0, 0xb0, 0x6b, 0xd6, 0x5b, 0x53,
-+    0xb8, 0x9b, 0x7a, 0xcd, 0xc7, 0x2b, 0xb8, 0x6a, 0x63, 0xa9,
-+    0xfb, 0x6f, 0xa4, 0x72, 0xbf, 0x4c, 0x5d, 0x00, 0x14, 0xba,
-+    0xfa, 0x59, 0x88, 0xed, 0xe4, 0xe0, 0x8c, 0xa2, 0xec, 0x14,
-+    0x7e, 0x2d, 0xe2, 0xf0, 0x46, 0x49, 0x95, 0x45,
-+};
-+
-+static unsigned char test2048[] = {
-+    0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
-+    0x01, 0x00, 0xc0, 0xc0, 0xce, 0x3e, 0x3c, 0x53, 0x67, 0x3f,
-+    0x4f, 0xc5, 0x2f, 0xa4, 0xc2, 0x5a, 0x2f, 0x58, 0xfd, 0x27,
-+    0x52, 0x6a, 0xe8, 0xcf, 0x4a, 0x73, 0x47, 0x8d, 0x25, 0x0f,
-+    0x5f, 0x03, 0x26, 0x78, 0xef, 0xf0, 0x22, 0x12, 0xd3, 0xde,
-+    0x47, 0xb2, 0x1c, 0x0b, 0x38, 0x63, 0x1a, 0x6c, 0x85, 0x7a,
-+    0x80, 0xc6, 0x8f, 0xa0, 0x41, 0xaf, 0x62, 0xc4, 0x67, 0x32,
-+    0x88, 0xf8, 0xa6, 0x9c, 0xf5, 0x23, 0x1d, 0xe4, 0xac, 0x3f,
-+    0x29, 0xf9, 0xec, 0xe1, 0x8b, 0x26, 0x03, 0x2c, 0xb2, 0xab,
-+    0xf3, 0x7d, 0xb5, 0xca, 0x49, 0xc0, 0x8f, 0x1c, 0xdf, 0x33,
-+    0x3a, 0x60, 0xda, 0x3c, 0xb0, 0x16, 0xf8, 0xa9, 0x12, 0x8f,
-+    0x64, 0xac, 0x23, 0x0c, 0x69, 0x64, 0x97, 0x5d, 0x99, 0xd4,
-+    0x09, 0x83, 0x9b, 0x61, 0xd3, 0xac, 0xf0, 0xde, 0xdd, 0x5e,
-+    0x9f, 0x44, 0x94, 0xdb, 0x3a, 0x4d, 0x97, 0xe8, 0x52, 0x29,
-+    0xf7, 0xdb, 0x94, 0x07, 0x45, 0x90, 0x78, 0x1e, 0x31, 0x0b,
-+    0x80, 0xf7, 0x57, 0xad, 0x1c, 0x79, 0xc5, 0xcb, 0x32, 0xb0,
-+    0xce, 0xcd, 0x74, 0xb3, 0xe2, 0x94, 0xc5, 0x78, 0x2f, 0x34,
-+    0x1a, 0x45, 0xf7, 0x8c, 0x52, 0xa5, 0xbc, 0x8d, 0xec, 0xd1,
-+    0x2f, 0x31, 0x3b, 0xf0, 0x49, 0x59, 0x5e, 0x88, 0x9d, 0x15,
-+    0x92, 0x35, 0x32, 0xc1, 0xe7, 0x61, 0xec, 0x50, 0x48, 0x7c,
-+    0xba, 0x05, 0xf9, 0xf8, 0xf8, 0xa7, 0x8c, 0x83, 0xe8, 0x66,
-+    0x5b, 0xeb, 0xfe, 0xd8, 0x4f, 0xdd, 0x6d, 0x36, 0xc0, 0xb2,
-+    0x90, 0x0f, 0xb8, 0x52, 0xf9, 0x04, 0x9b, 0x40, 0x2c, 0x27,
-+    0xd6, 0x36, 0x8e, 0xc2, 0x1b, 0x44, 0xf3, 0x92, 0xd5, 0x15,
-+    0x9e, 0x9a, 0xbc, 0xf3, 0x7d, 0x03, 0xd7, 0x02, 0x14, 0x20,
-+    0xe9, 0x10, 0x92, 0xfd, 0xf9, 0xfc, 0x8f, 0xe5, 0x18, 0xe1,
-+    0x95, 0xcc, 0x9e, 0x60, 0xa6, 0xfa, 0x38, 0x4d, 0x02, 0x03,
-+    0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x00, 0xc3, 0xc3,
-+    0x0d, 0xb4, 0x27, 0x90, 0x8d, 0x4b, 0xbf, 0xb8, 0x84, 0xaa,
-+    0xd0, 0xb8, 0xc7, 0x5d, 0x99, 0xbe, 0x55, 0xf6, 0x3e, 0x7c,
-+    0x49, 0x20, 0xcb, 0x8a, 0x8e, 0x19, 0x0e, 0x66, 0x24, 0xac,
-+    0xaf, 0x03, 0x33, 0x97, 0xeb, 0x95, 0xd5, 0x3b, 0x0f, 0x40,
-+    0x56, 0x04, 0x50, 0xd1, 0xe6, 0xbe, 0x84, 0x0b, 0x25, 0xd3,
-+    0x9c, 0xe2, 0x83, 0x6c, 0xf5, 0x62, 0x5d, 0xba, 0x2b, 0x7d,
-+    0x3d, 0x7a, 0x6c, 0xe1, 0xd2, 0x0e, 0x54, 0x93, 0x80, 0x01,
-+    0x91, 0x51, 0x09, 0xe8, 0x5b, 0x8e, 0x47, 0xbd, 0x64, 0xe4,
-+    0x0e, 0x03, 0x83, 0x55, 0xcf, 0x5a, 0x37, 0xf0, 0x25, 0xb5,
-+    0x7d, 0x21, 0xd7, 0x69, 0xdf, 0x6f, 0xc2, 0xcf, 0x10, 0xc9,
-+    0x8a, 0x40, 0x9f, 0x7a, 0x70, 0xc0, 0xe8, 0xe8, 0xc0, 0xe6,
-+    0x9a, 0x15, 0x0a, 0x8d, 0x4e, 0x46, 0xcb, 0x7a, 0xdb, 0xb3,
-+    0xcb, 0x83, 0x02, 0xc4, 0xf0, 0xab, 0xeb, 0x02, 0x01, 0x0e,
-+    0x23, 0xfc, 0x1d, 0xc4, 0xbd, 0xd4, 0xaa, 0x5d, 0x31, 0x46,
-+    0x99, 0xce, 0x9e, 0xf8, 0x04, 0x75, 0x10, 0x67, 0xc4, 0x53,
-+    0x47, 0x44, 0xfa, 0xc2, 0x25, 0x73, 0x7e, 0xd0, 0x8e, 0x59,
-+    0xd1, 0xb2, 0x5a, 0xf4, 0xc7, 0x18, 0x92, 0x2f, 0x39, 0xab,
-+    0xcd, 0xa3, 0xb5, 0xc2, 0xb9, 0xc7, 0xb9, 0x1b, 0x9f, 0x48,
-+    0xfa, 0x13, 0xc6, 0x98, 0x4d, 0xca, 0x84, 0x9c, 0x06, 0xca,
-+    0xe7, 0x89, 0x01, 0x04, 0xc4, 0x6c, 0xfd, 0x29, 0x59, 0x35,
-+    0xe7, 0xf3, 0xdd, 0xce, 0x64, 0x59, 0xbf, 0x21, 0x13, 0xa9,
-+    0x9f, 0x0e, 0xc5, 0xff, 0xbd, 0x33, 0x00, 0xec, 0xac, 0x6b,
-+    0x11, 0xef, 0x51, 0x5e, 0xad, 0x07, 0x15, 0xde, 0xb8, 0x5f,
-+    0xc6, 0xb9, 0xa3, 0x22, 0x65, 0x46, 0x83, 0x14, 0xdf, 0xd0,
-+    0xf1, 0x44, 0x8a, 0xe1, 0x9c, 0x23, 0x33, 0xb4, 0x97, 0x33,
-+    0xe6, 0x6b, 0x81, 0x02, 0x81, 0x81, 0x00, 0xec, 0x12, 0xa7,
-+    0x59, 0x74, 0x6a, 0xde, 0x3e, 0xad, 0xd8, 0x36, 0x80, 0x50,
-+    0xa2, 0xd5, 0x21, 0x81, 0x07, 0xf1, 0xd0, 0x91, 0xf2, 0x6c,
-+    0x12, 0x2f, 0x9d, 0x1a, 0x26, 0xf8, 0x30, 0x65, 0xdf, 0xe8,
-+    0xc0, 0x9b, 0x6a, 0x30, 0x98, 0x82, 0x87, 0xec, 0xa2, 0x56,
-+    0x87, 0x62, 0x6f, 0xe7, 0x9f, 0xf6, 0x56, 0xe6, 0x71, 0x8f,
-+    0x49, 0x86, 0x93, 0x5a, 0x4d, 0x34, 0x58, 0xfe, 0xd9, 0x04,
-+    0x13, 0xaf, 0x79, 0xb7, 0xad, 0x11, 0xd1, 0x30, 0x9a, 0x14,
-+    0x06, 0xa0, 0xfa, 0xb7, 0x55, 0xdc, 0x6c, 0x5a, 0x4c, 0x2c,
-+    0x59, 0x56, 0xf6, 0xe8, 0x9d, 0xaf, 0x0a, 0x78, 0x99, 0x06,
-+    0x06, 0x9e, 0xe7, 0x9c, 0x51, 0x55, 0x43, 0xfc, 0x3b, 0x6c,
-+    0x0b, 0xbf, 0x2d, 0x41, 0xa7, 0xaf, 0xb7, 0xe0, 0xe8, 0x28,
-+    0x18, 0xb4, 0x13, 0xd1, 0xe6, 0x97, 0xd0, 0x9f, 0x6a, 0x80,
-+    0xca, 0xdd, 0x1a, 0x7e, 0x15, 0x02, 0x81, 0x81, 0x00, 0xd1,
-+    0x06, 0x0c, 0x1f, 0xe3, 0xd0, 0xab, 0xd6, 0xca, 0x7c, 0xbc,
-+    0x7d, 0x13, 0x35, 0xce, 0x27, 0xcd, 0xd8, 0x49, 0x51, 0x63,
-+    0x64, 0x0f, 0xca, 0x06, 0x12, 0xfc, 0x07, 0x3e, 0xaf, 0x61,
-+    0x6d, 0xe2, 0x53, 0x39, 0x27, 0xae, 0xc3, 0x11, 0x9e, 0x94,
-+    0x01, 0x4f, 0xe3, 0xf3, 0x67, 0xf9, 0x77, 0xf9, 0xe7, 0x95,
-+    0x3a, 0x6f, 0xe2, 0x20, 0x73, 0x3e, 0xa4, 0x7a, 0x28, 0xd4,
-+    0x61, 0x97, 0xf6, 0x17, 0xa0, 0x23, 0x10, 0x2b, 0xce, 0x84,
-+    0x57, 0x7e, 0x25, 0x1f, 0xf4, 0xa8, 0x54, 0xd2, 0x65, 0x94,
-+    0xcc, 0x95, 0x0a, 0xab, 0x30, 0xc1, 0x59, 0x1f, 0x61, 0x8e,
-+    0xb9, 0x6b, 0xd7, 0x4e, 0xb9, 0x83, 0x43, 0x79, 0x85, 0x11,
-+    0xbc, 0x0f, 0xae, 0x25, 0x20, 0x05, 0xbc, 0xd2, 0x48, 0xa1,
-+    0x68, 0x09, 0x84, 0xf6, 0x12, 0x9a, 0x66, 0xb9, 0x2b, 0xbb,
-+    0x76, 0x03, 0x17, 0x46, 0x4e, 0x97, 0x59, 0x02, 0x81, 0x80,
-+    0x09, 0x4c, 0xfa, 0xd6, 0xe5, 0x65, 0x48, 0x78, 0x43, 0xb5,
-+    0x1f, 0x00, 0x93, 0x2c, 0xb7, 0x24, 0xe8, 0xc6, 0x7d, 0x5a,
-+    0x70, 0x45, 0x92, 0xc8, 0x6c, 0xa3, 0xcd, 0xe1, 0xf7, 0x29,
-+    0x40, 0xfa, 0x3f, 0x5b, 0x47, 0x44, 0x39, 0xc1, 0xe8, 0x72,
-+    0x9e, 0x7a, 0x0e, 0xda, 0xaa, 0xa0, 0x2a, 0x09, 0xfd, 0x54,
-+    0x93, 0x23, 0xaa, 0x37, 0x85, 0x5b, 0xcc, 0xd4, 0xf9, 0xd8,
-+    0xff, 0xc1, 0x61, 0x0d, 0xbd, 0x7e, 0x18, 0x24, 0x73, 0x6d,
-+    0x40, 0x72, 0xf1, 0x93, 0x09, 0x48, 0x97, 0x6c, 0x84, 0x90,
-+    0xa8, 0x46, 0x14, 0x01, 0x39, 0x11, 0xe5, 0x3c, 0x41, 0x27,
-+    0x32, 0x75, 0x24, 0xed, 0xa1, 0xd9, 0x12, 0x29, 0x8a, 0x28,
-+    0x71, 0x89, 0x8d, 0xca, 0x30, 0xb0, 0x01, 0xc4, 0x2f, 0x82,
-+    0x19, 0x14, 0x4c, 0x70, 0x1c, 0xb8, 0x23, 0x2e, 0xe8, 0x90,
-+    0x49, 0x97, 0x92, 0x97, 0x6b, 0x7a, 0x9d, 0xb9, 0x02, 0x81,
-+    0x80, 0x0f, 0x0e, 0xa1, 0x76, 0xf6, 0xa1, 0x44, 0x8f, 0xaf,
-+    0x7c, 0x76, 0xd3, 0x87, 0xbb, 0xbb, 0x83, 0x10, 0x88, 0x01,
-+    0x18, 0x14, 0xd1, 0xd3, 0x75, 0x59, 0x24, 0xaa, 0xf5, 0x16,
-+    0xa5, 0xe9, 0x9d, 0xd1, 0xcc, 0xee, 0xf4, 0x15, 0xd9, 0xc5,
-+    0x7e, 0x27, 0xe9, 0x44, 0x49, 0x06, 0x72, 0xb9, 0xfc, 0xd3,
-+    0x8a, 0xc4, 0x2c, 0x36, 0x7d, 0x12, 0x9b, 0x5a, 0xaa, 0xdc,
-+    0x85, 0xee, 0x6e, 0xad, 0x54, 0xb3, 0xf4, 0xfc, 0x31, 0xa1,
-+    0x06, 0x3a, 0x70, 0x57, 0x0c, 0xf3, 0x95, 0x5b, 0x3e, 0xe8,
-+    0xfd, 0x1a, 0x4f, 0xf6, 0x78, 0x93, 0x46, 0x6a, 0xd7, 0x31,
-+    0xb4, 0x84, 0x64, 0x85, 0x09, 0x38, 0x89, 0x92, 0x94, 0x1c,
-+    0xbf, 0xe2, 0x3c, 0x2a, 0xe0, 0xff, 0x99, 0xa3, 0xf0, 0x2b,
-+    0x31, 0xc2, 0x36, 0xcd, 0x60, 0xbf, 0x9d, 0x2d, 0x74, 0x32,
-+    0xe8, 0x9c, 0x93, 0x6e, 0xbb, 0x91, 0x7b, 0xfd, 0xd9, 0x02,
-+    0x81, 0x81, 0x00, 0xa2, 0x71, 0x25, 0x38, 0xeb, 0x2a, 0xe9,
-+    0x37, 0xcd, 0xfe, 0x44, 0xce, 0x90, 0x3f, 0x52, 0x87, 0x84,
-+    0x52, 0x1b, 0xae, 0x8d, 0x22, 0x94, 0xce, 0x38, 0xe6, 0x04,
-+    0x88, 0x76, 0x85, 0x9a, 0xd3, 0x14, 0x09, 0xe5, 0x69, 0x9a,
-+    0xff, 0x58, 0x92, 0x02, 0x6a, 0x7d, 0x7c, 0x1e, 0x2c, 0xfd,
-+    0xa8, 0xca, 0x32, 0x14, 0x4f, 0x0d, 0x84, 0x0d, 0x37, 0x43,
-+    0xbf, 0xe4, 0x5d, 0x12, 0xc8, 0x24, 0x91, 0x27, 0x8d, 0x46,
-+    0xd9, 0x54, 0x53, 0xe7, 0x62, 0x71, 0xa8, 0x2b, 0x71, 0x41,
-+    0x8d, 0x75, 0xf8, 0x3a, 0xa0, 0x61, 0x29, 0x46, 0xa6, 0xe5,
-+    0x82, 0xfa, 0x3a, 0xd9, 0x08, 0xfa, 0xfc, 0x63, 0xfd, 0x6b,
-+    0x30, 0xbc, 0xf4, 0x4e, 0x9e, 0x8c, 0x25, 0x0c, 0xb6, 0x55,
-+    0xe7, 0x3c, 0xd4, 0x4e, 0x0b, 0xfd, 0x8b, 0xc3, 0x0e, 0x1d,
-+    0x9c, 0x44, 0x57, 0x8f, 0x1f, 0x86, 0xf7, 0xd5, 0x1b, 0xe4,
-+    0x95,
-+};
-+
-+static unsigned char test3072[] = {
-+    0x30, 0x82, 0x06, 0xe3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
-+    0x81, 0x00, 0xbc, 0x3b, 0x23, 0xc0, 0x33, 0xa7, 0x8b, 0xaa,
-+    0xca, 0xa3, 0x8c, 0x94, 0xf2, 0x4c, 0x52, 0x08, 0x85, 0x80,
-+    0xfc, 0x36, 0x15, 0xfa, 0x03, 0x06, 0xb6, 0xd6, 0x3f, 0x60,
-+    0x8a, 0x89, 0x0d, 0xba, 0x1a, 0x51, 0x0b, 0x12, 0xea, 0x71,
-+    0x77, 0xf6, 0x3a, 0x30, 0x21, 0x3d, 0x24, 0xf8, 0x2e, 0xd0,
-+    0x17, 0x3a, 0x85, 0x94, 0x25, 0x42, 0x89, 0xff, 0x6a, 0x68,
-+    0xdf, 0x1f, 0x86, 0xae, 0xa5, 0xbb, 0x9a, 0x79, 0xf6, 0x69,
-+    0x94, 0xfe, 0xde, 0xfe, 0xce, 0x1b, 0x2e, 0xae, 0x1d, 0x91,
-+    0xcb, 0xb9, 0xf1, 0x2d, 0xd8, 0x00, 0x82, 0x51, 0x8e, 0xf9,
-+    0xfd, 0xac, 0xf1, 0x0e, 0x7f, 0xb7, 0x95, 0x85, 0x35, 0xf9,
-+    0xcb, 0xbe, 0x5f, 0xd3, 0x58, 0xe3, 0xa1, 0x54, 0x9e, 0x30,
-+    0xb1, 0x8d, 0x01, 0x97, 0x82, 0x06, 0x8e, 0x77, 0xfb, 0xce,
-+    0x50, 0x2f, 0xbf, 0xf1, 0xff, 0x57, 0x0a, 0x42, 0x03, 0xfd,
-+    0x0e, 0xba, 0x1e, 0xca, 0x85, 0xc1, 0x9b, 0xa5, 0x9d, 0x09,
-+    0x0e, 0xe9, 0xbb, 0xc5, 0x73, 0x47, 0x0d, 0x39, 0x3c, 0x64,
-+    0x06, 0x9a, 0x79, 0x3f, 0x50, 0x87, 0x9c, 0x18, 0x2d, 0x62,
-+    0x01, 0xfc, 0xed, 0xc1, 0x58, 0x28, 0x21, 0x94, 0x1e, 0xf9,
-+    0x2d, 0x96, 0x4f, 0xd0, 0xbc, 0xf1, 0xe0, 0x8a, 0xfa, 0x4d,
-+    0xb6, 0x78, 0x4a, 0xde, 0x17, 0x59, 0xb0, 0x22, 0xa0, 0x9a,
-+    0xd3, 0x70, 0xb6, 0xc2, 0xbe, 0xbc, 0x96, 0xca, 0x41, 0x5f,
-+    0x58, 0x4e, 0xce, 0xef, 0x64, 0x45, 0xdd, 0x3f, 0x81, 0x92,
-+    0xcc, 0x40, 0x79, 0xfc, 0x19, 0xe2, 0xbc, 0x77, 0x2f, 0x43,
-+    0xfb, 0x8e, 0xad, 0x82, 0x4a, 0x0b, 0xb1, 0xbc, 0x09, 0x8a,
-+    0x80, 0xc3, 0x0f, 0xef, 0xd2, 0x06, 0xd3, 0x4b, 0x0c, 0x7f,
-+    0xae, 0x60, 0x3f, 0x2e, 0x52, 0xb4, 0xe4, 0xc2, 0x5c, 0xa6,
-+    0x71, 0xc0, 0x13, 0x9c, 0xca, 0xa6, 0x0d, 0x13, 0xd7, 0xb7,
-+    0x14, 0x94, 0x3f, 0x0d, 0x8b, 0x06, 0x70, 0x2f, 0x15, 0x82,
-+    0x8d, 0x47, 0x45, 0xa6, 0x00, 0x8a, 0x14, 0x91, 0xde, 0x2f,
-+    0x50, 0x17, 0xe3, 0x1d, 0x34, 0x29, 0x8c, 0xe4, 0x57, 0x74,
-+    0x2a, 0x3a, 0x82, 0x65, 0x26, 0xf7, 0x8d, 0xcc, 0x1b, 0x8f,
-+    0xaf, 0xe5, 0x85, 0xe5, 0xbe, 0x85, 0xd6, 0xb7, 0x04, 0xe8,
-+    0xf5, 0xd4, 0x74, 0xe2, 0x54, 0x14, 0xdd, 0x58, 0xcf, 0x1f,
-+    0x11, 0x8a, 0x9f, 0x82, 0xa2, 0x01, 0xf9, 0xc2, 0xdf, 0x7b,
-+    0x84, 0xb1, 0xd8, 0x5b, 0x70, 0xbb, 0x24, 0xe7, 0xd0, 0x2a,
-+    0x75, 0x3d, 0x55, 0xac, 0x45, 0xe9, 0xab, 0xc6, 0x84, 0x8a,
-+    0xe7, 0x6d, 0x26, 0x12, 0x89, 0xb5, 0x67, 0xe8, 0x46, 0x9d,
-+    0x46, 0x1a, 0xfa, 0x2d, 0xc0, 0x5b, 0x60, 0x46, 0x8b, 0xb7,
-+    0x32, 0x03, 0xff, 0x75, 0xee, 0x9f, 0x3c, 0xdd, 0xb6, 0x35,
-+    0x4e, 0x82, 0xbd, 0x99, 0x73, 0x51, 0x02, 0x03, 0x01, 0x00,
-+    0x01, 0x02, 0x82, 0x01, 0x80, 0x42, 0xee, 0xa4, 0x9f, 0xcb,
-+    0xbe, 0x60, 0x23, 0xb3, 0x3a, 0xc4, 0xda, 0x91, 0xee, 0x21,
-+    0x9d, 0x76, 0x1b, 0x8f, 0x93, 0x8b, 0xed, 0x02, 0xf6, 0x78,
-+    0x3d, 0x66, 0xfb, 0xe5, 0x47, 0x26, 0xe2, 0x6e, 0x49, 0x33,
-+    0x2e, 0xde, 0xbe, 0xca, 0x71, 0x7b, 0xef, 0x71, 0x62, 0x54,
-+    0xab, 0x0b, 0xba, 0x63, 0x08, 0x24, 0x47, 0xb1, 0x98, 0x1f,
-+    0x89, 0xfb, 0x44, 0x9f, 0x52, 0x8e, 0x89, 0xbb, 0xd5, 0x21,
-+    0xf1, 0x0c, 0x76, 0x2e, 0xcd, 0x12, 0x6e, 0x78, 0xcb, 0xa1,
-+    0xa5, 0xb8, 0x4e, 0x07, 0xab, 0x6e, 0xdf, 0x66, 0x57, 0x87,
-+    0xff, 0x88, 0x5f, 0xcc, 0x9c, 0x9a, 0x7b, 0x15, 0x5f, 0x2a,
-+    0x83, 0xdb, 0xd5, 0x9f, 0x65, 0x6a, 0x9d, 0xb4, 0x95, 0xfc,
-+    0xe0, 0x22, 0x00, 0x1e, 0xa2, 0x8d, 0x56, 0x5a, 0x9e, 0x0a,
-+    0x3b, 0x10, 0x07, 0x24, 0xec, 0x55, 0xcc, 0xaf, 0x87, 0x3b,
-+    0xd6, 0x8d, 0xa4, 0x86, 0x80, 0x18, 0x42, 0xdb, 0x9d, 0x24,
-+    0xc3, 0x97, 0x3b, 0x89, 0x5a, 0x03, 0xb3, 0x0a, 0x72, 0xd1,
-+    0x78, 0xf0, 0xc8, 0x80, 0xb0, 0x9d, 0x3c, 0xae, 0x5e, 0x0a,
-+    0x5b, 0x6e, 0x87, 0xd3, 0x3d, 0x25, 0x2e, 0x03, 0x33, 0x01,
-+    0xfd, 0xb1, 0xa5, 0xd9, 0x58, 0x01, 0xb9, 0xaf, 0xf6, 0x32,
-+    0x6a, 0x38, 0xe7, 0x39, 0x63, 0x3c, 0xfc, 0x0c, 0x41, 0x90,
-+    0x28, 0x40, 0x03, 0xcd, 0xfb, 0xde, 0x80, 0x74, 0x21, 0xaa,
-+    0xae, 0x58, 0xe9, 0x97, 0x18, 0x85, 0x58, 0x3d, 0x2b, 0xd6,
-+    0x61, 0xf6, 0xe8, 0xbc, 0x6d, 0x2a, 0xf3, 0xb8, 0xea, 0x8c,
-+    0x64, 0x44, 0xc6, 0xd3, 0x9f, 0x00, 0x7b, 0xb2, 0x52, 0x18,
-+    0x11, 0x04, 0x96, 0xb7, 0x05, 0xbb, 0xc2, 0x38, 0x5b, 0xa7,
-+    0x0a, 0x84, 0xb6, 0x4f, 0x02, 0x63, 0xa4, 0x57, 0x00, 0xe3,
-+    0xde, 0xe4, 0xf2, 0xb3, 0x55, 0xd9, 0x00, 0xa9, 0xd2, 0x5c,
-+    0x69, 0x9f, 0xe5, 0x80, 0x4f, 0x23, 0x7c, 0xd9, 0xa7, 0x77,
-+    0x4a, 0xbb, 0x09, 0x6d, 0x45, 0x02, 0xcf, 0x32, 0x90, 0xfd,
-+    0x10, 0xb6, 0xb3, 0x93, 0xd9, 0x3b, 0x1d, 0x57, 0x66, 0xb5,
-+    0xb3, 0xb1, 0x6e, 0x53, 0x5f, 0x04, 0x60, 0x29, 0xcd, 0xe8,
-+    0xb8, 0xab, 0x62, 0x82, 0x33, 0x40, 0xc7, 0xf8, 0x64, 0x60,
-+    0x0e, 0xab, 0x06, 0x3e, 0xa0, 0xa3, 0x62, 0x11, 0x3f, 0x67,
-+    0x5d, 0x24, 0x9e, 0x60, 0x29, 0xdc, 0x4c, 0xd5, 0x13, 0xee,
-+    0x3d, 0xb7, 0x84, 0x93, 0x27, 0xb5, 0x6a, 0xf9, 0xf0, 0xdd,
-+    0x50, 0xac, 0x46, 0x3c, 0xe6, 0xd5, 0xec, 0xf7, 0xb7, 0x9f,
-+    0x23, 0x39, 0x9c, 0x88, 0x8c, 0x5a, 0x62, 0x3f, 0x8d, 0x4a,
-+    0xd7, 0xeb, 0x5e, 0x1e, 0x49, 0xf8, 0xa9, 0x53, 0x11, 0x75,
-+    0xd0, 0x43, 0x1e, 0xc7, 0x29, 0x22, 0x80, 0x1f, 0xc5, 0x83,
-+    0x8d, 0x20, 0x04, 0x87, 0x7f, 0x57, 0x8c, 0xf5, 0xa1, 0x02,
-+    0x81, 0xc1, 0x00, 0xf7, 0xaa, 0xf5, 0xa5, 0x00, 0xdb, 0xd6,
-+    0x11, 0xfc, 0x07, 0x6d, 0x22, 0x24, 0x2b, 0x4b, 0xc5, 0x67,
-+    0x0f, 0x37, 0xa5, 0xdb, 0x8f, 0x38, 0xe2, 0x05, 0x43, 0x9a,
-+    0x44, 0x05, 0x3f, 0xa9, 0xac, 0x4c, 0x98, 0x3c, 0x72, 0x38,
-+    0xc3, 0x89, 0x33, 0x58, 0x73, 0x51, 0xcc, 0x5d, 0x2f, 0x8f,
-+    0x6d, 0x3f, 0xa1, 0x22, 0x9e, 0xfb, 0x9a, 0xb4, 0xb8, 0x79,
-+    0x95, 0xaf, 0x83, 0xcf, 0x5a, 0xb7, 0x14, 0x14, 0x0c, 0x51,
-+    0x8a, 0x11, 0xe6, 0xd6, 0x21, 0x1e, 0x17, 0x13, 0xd3, 0x69,
-+    0x7a, 0x3a, 0xd5, 0xaf, 0x3f, 0xb8, 0x25, 0x01, 0xcb, 0x2b,
-+    0xe6, 0xfc, 0x03, 0xd8, 0xd4, 0xf7, 0x20, 0xe0, 0x21, 0xef,
-+    0x1a, 0xca, 0x61, 0xeb, 0x8e, 0x96, 0x45, 0x8e, 0x5c, 0xe6,
-+    0x81, 0x0b, 0x2d, 0x05, 0x32, 0xf9, 0x41, 0x62, 0xb4, 0x33,
-+    0x98, 0x10, 0x3a, 0xcd, 0xf0, 0x7a, 0x8b, 0x1a, 0x48, 0xd7,
-+    0x3b, 0x01, 0xf5, 0x18, 0x65, 0x8f, 0x3c, 0xc2, 0x31, 0x3b,
-+    0xd3, 0xa7, 0x17, 0x5f, 0x7c, 0x0c, 0xe7, 0x25, 0x18, 0x5a,
-+    0x08, 0xe1, 0x09, 0x89, 0x13, 0xa7, 0xc5, 0x12, 0xab, 0x88,
-+    0x30, 0xcd, 0x06, 0xf9, 0xba, 0x6f, 0xca, 0x9c, 0x8a, 0xda,
-+    0x3e, 0x53, 0x90, 0xd7, 0x16, 0x2e, 0xfc, 0xbc, 0xad, 0xd6,
-+    0x3d, 0xc0, 0x66, 0x4c, 0x02, 0x3d, 0x31, 0xfd, 0x6c, 0xdb,
-+    0x1c, 0xdf, 0x96, 0x33, 0x23, 0x02, 0x81, 0xc1, 0x00, 0xc2,
-+    0x90, 0x47, 0xc4, 0xfb, 0x59, 0xf0, 0xc5, 0x14, 0x75, 0x29,
-+    0xfa, 0x77, 0xa1, 0x8d, 0xd4, 0x90, 0xa1, 0x0d, 0x3f, 0x16,
-+    0x88, 0xe3, 0x4c, 0x8f, 0x8f, 0x18, 0x8c, 0x9c, 0x8a, 0xd5,
-+    0xa7, 0x41, 0x99, 0xf3, 0x80, 0x8e, 0xb1, 0xb8, 0x63, 0xd8,
-+    0x3f, 0x95, 0xd0, 0xd0, 0x2b, 0xf5, 0xe6, 0x93, 0xe8, 0xfe,
-+    0xd0, 0x73, 0xd5, 0xbd, 0xb4, 0xee, 0x51, 0x19, 0x6a, 0x10,
-+    0xca, 0xc8, 0xba, 0xa4, 0x4d, 0x84, 0x54, 0x38, 0x17, 0xb5,
-+    0xd0, 0xa8, 0x75, 0x22, 0xc5, 0x1b, 0x61, 0xa6, 0x51, 0x88,
-+    0x63, 0xf0, 0x4f, 0xd1, 0x88, 0xd9, 0x16, 0x49, 0x30, 0xe1,
-+    0xa8, 0x47, 0xc9, 0x30, 0x1d, 0x5c, 0x75, 0xd8, 0x89, 0xb6,
-+    0x1d, 0x45, 0xd8, 0x0f, 0x94, 0x89, 0xb3, 0xe4, 0x51, 0xfa,
-+    0x21, 0xff, 0x6f, 0xb6, 0x30, 0x6f, 0x33, 0x24, 0xbc, 0x09,
-+    0x98, 0xe9, 0x20, 0x02, 0x0b, 0xde, 0xff, 0xc5, 0x06, 0xb6,
-+    0x28, 0xa3, 0xa1, 0x07, 0xe8, 0xe1, 0xd2, 0xc2, 0xf1, 0xd1,
-+    0x23, 0x6b, 0x4c, 0x3a, 0xae, 0x85, 0xec, 0xf9, 0xff, 0xa7,
-+    0x9b, 0x25, 0xb8, 0x95, 0x1d, 0xa8, 0x14, 0x81, 0x4f, 0x79,
-+    0x4f, 0xd6, 0x39, 0x5d, 0xe6, 0x5f, 0xd2, 0x34, 0x54, 0x8b,
-+    0x1e, 0x40, 0x4c, 0x15, 0x5a, 0x45, 0xce, 0x0c, 0xb0, 0xdf,
-+    0xa1, 0x17, 0xb8, 0xb0, 0x6a, 0x82, 0xa5, 0x97, 0x92, 0x70,
-+    0xfb, 0x02, 0x81, 0xc0, 0x77, 0x46, 0x44, 0x2b, 0x04, 0xf0,
-+    0xda, 0x75, 0xaa, 0xd4, 0xc0, 0xc0, 0x32, 0x7f, 0x0f, 0x6c,
-+    0xb0, 0x27, 0x69, 0xfb, 0x5c, 0x73, 0xeb, 0x47, 0x1e, 0x95,
-+    0xe2, 0x13, 0x64, 0x1b, 0xb6, 0xd1, 0x1d, 0xca, 0x2b, 0x42,
-+    0x2f, 0x08, 0x2c, 0x69, 0x27, 0xed, 0xd1, 0xb5, 0x04, 0x23,
-+    0xc5, 0x85, 0x2d, 0xa1, 0xa2, 0x94, 0xc2, 0x43, 0x4d, 0x49,
-+    0x92, 0x74, 0x7e, 0x24, 0x92, 0x95, 0xf3, 0x99, 0x9d, 0xd6,
-+    0x18, 0xe6, 0xcf, 0x9c, 0x45, 0xff, 0x89, 0x08, 0x40, 0x2a,
-+    0x0e, 0xa0, 0x28, 0xf9, 0x83, 0xfe, 0xc1, 0xe6, 0x40, 0xa8,
-+    0xe2, 0x29, 0xc9, 0xb0, 0xe8, 0x9a, 0x17, 0xb2, 0x23, 0x7e,
-+    0xf4, 0x32, 0x08, 0xc9, 0x83, 0xb2, 0x15, 0xb8, 0xc5, 0xc9,
-+    0x03, 0xd1, 0x9d, 0xda, 0x3e, 0xa8, 0xbf, 0xd5, 0xb7, 0x7d,
-+    0x65, 0x63, 0x94, 0x5d, 0x5d, 0x94, 0xb4, 0xcf, 0x8d, 0x07,
-+    0x0b, 0x70, 0x85, 0x8e, 0xce, 0x03, 0x0b, 0x2a, 0x8d, 0xb3,
-+    0x3c, 0x46, 0xc0, 0x2f, 0xc7, 0x72, 0x6c, 0x9c, 0x5d, 0x07,
-+    0x0f, 0x45, 0x3b, 0x6b, 0x66, 0x32, 0xab, 0x17, 0x83, 0xd8,
-+    0x4c, 0x2c, 0x84, 0x71, 0x19, 0x8f, 0xaa, 0x0a, 0xff, 0xbc,
-+    0xf7, 0x42, 0x10, 0xe8, 0xae, 0x4d, 0x26, 0xaf, 0xdd, 0x06,
-+    0x33, 0x29, 0x66, 0x21, 0x5d, 0xf5, 0xae, 0x17, 0x07, 0x1f,
-+    0x87, 0x9e, 0xae, 0x27, 0x1d, 0xd5, 0x02, 0x81, 0xc0, 0x56,
-+    0x17, 0x4f, 0x9a, 0x8a, 0xf9, 0xde, 0x3e, 0xe6, 0x71, 0x7d,
-+    0x94, 0xb5, 0xb0, 0xc7, 0xb8, 0x62, 0x12, 0xd1, 0x70, 0xb4,
-+    0x00, 0xf8, 0x4a, 0xdd, 0x4f, 0x1d, 0x36, 0xc2, 0xe1, 0xef,
-+    0xee, 0x25, 0x6a, 0x00, 0xc4, 0x46, 0xdf, 0xbe, 0xce, 0x77,
-+    0x56, 0x93, 0x6d, 0x25, 0x5f, 0xfe, 0x5b, 0xfb, 0xe0, 0xe2,
-+    0x37, 0xcc, 0xb9, 0xac, 0x4a, 0xce, 0x15, 0x16, 0xa0, 0xc7,
-+    0x33, 0x63, 0xa4, 0xaa, 0xa5, 0x1e, 0x43, 0xc1, 0xda, 0x43,
-+    0xfa, 0x43, 0x40, 0x29, 0x95, 0x7c, 0x2b, 0x36, 0x53, 0xe7,
-+    0x7d, 0x09, 0x4d, 0xd8, 0x52, 0xac, 0x74, 0x5f, 0x08, 0x81,
-+    0x21, 0x5c, 0x3a, 0x5a, 0xce, 0xf3, 0x25, 0xb6, 0x1e, 0x21,
-+    0x76, 0x4c, 0x7c, 0x71, 0x50, 0x71, 0xaa, 0x27, 0x02, 0x5b,
-+    0x23, 0x06, 0x0b, 0x21, 0x5b, 0xc7, 0x28, 0xa3, 0x3d, 0x8d,
-+    0x25, 0x9b, 0x2a, 0x2d, 0x9d, 0xa1, 0x1c, 0x1d, 0xcb, 0x7d,
-+    0x78, 0xf8, 0x06, 0x7e, 0x20, 0x7f, 0x24, 0x2a, 0x5c, 0xa4,
-+    0x04, 0xff, 0x2a, 0x68, 0xe0, 0xe6, 0xa3, 0xd8, 0x6f, 0x56,
-+    0x73, 0xa1, 0x3a, 0x4e, 0xc9, 0x23, 0xa1, 0x87, 0x22, 0x6a,
-+    0x74, 0x78, 0x3f, 0x44, 0x1c, 0x77, 0x13, 0xe5, 0x51, 0xef,
-+    0x89, 0x00, 0x3c, 0x6a, 0x4a, 0x5a, 0x8e, 0xf5, 0x30, 0xa2,
-+    0x93, 0x7e, 0x92, 0x9b, 0x85, 0x55, 0xaf, 0xfe, 0x24, 0xaf,
-+    0x57, 0x02, 0x81, 0xc1, 0x00, 0xa4, 0xc2, 0x6a, 0x59, 0x45,
-+    0xea, 0x71, 0x7d, 0x4c, 0xaf, 0xaf, 0xd6, 0x55, 0x97, 0x73,
-+    0xc5, 0xa1, 0x3c, 0xf6, 0x59, 0x23, 0xb6, 0x1f, 0x5e, 0x9c,
-+    0x96, 0x0f, 0x97, 0x66, 0x82, 0x91, 0x48, 0x36, 0x70, 0x02,
-+    0x67, 0xde, 0x34, 0xa6, 0x95, 0x7b, 0x51, 0x43, 0x66, 0xa4,
-+    0x16, 0x45, 0x59, 0x12, 0xdb, 0x35, 0x19, 0x4b, 0xbf, 0x1d,
-+    0xab, 0xf3, 0x3f, 0xb4, 0xb4, 0x6f, 0x66, 0xb0, 0x67, 0xc6,
-+    0x77, 0x2c, 0x46, 0xa8, 0x03, 0x64, 0x9a, 0x13, 0x9d, 0x40,
-+    0x22, 0x56, 0x76, 0x1a, 0x7c, 0x1e, 0xe2, 0xda, 0x7f, 0x09,
-+    0xcf, 0x10, 0xe3, 0xf2, 0xf4, 0x2a, 0x3b, 0x46, 0xc7, 0x61,
-+    0x9b, 0xef, 0x4a, 0x18, 0x60, 0x8c, 0x32, 0x71, 0xb9, 0xdd,
-+    0xac, 0xa0, 0xc6, 0x8d, 0x3f, 0xab, 0xc3, 0x21, 0x2c, 0xeb,
-+    0x91, 0x8f, 0xc7, 0x43, 0x0d, 0x0c, 0x67, 0x9e, 0xab, 0xe6,
-+    0x8d, 0xb6, 0x2d, 0x41, 0xca, 0x43, 0xd8, 0xcb, 0x30, 0xfb,
-+    0x3b, 0x40, 0x0d, 0x10, 0x9b, 0xb1, 0x55, 0x93, 0x73, 0x8b,
-+    0x60, 0xef, 0xc0, 0xee, 0xc0, 0xa6, 0x7a, 0x79, 0x90, 0xfd,
-+    0x4c, 0x25, 0xd4, 0x4f, 0x67, 0xbe, 0xf7, 0x86, 0x3c, 0x5d,
-+    0x2b, 0x7d, 0x97, 0x3d, 0xa2, 0x91, 0xa5, 0x06, 0x69, 0xf6,
-+    0x7a, 0xb8, 0x77, 0xe6, 0x70, 0xa9, 0xd8, 0x86, 0x4b, 0xa6,
-+    0xcf, 0x67, 0x1d, 0x33, 0xcf, 0xfe, 0x3e
-+};
-+
-+static unsigned char test4096[] = {
-+    0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02,
-+    0x01, 0x00, 0xc0, 0x71, 0xac, 0x1a, 0x13, 0x88, 0x82, 0x43,
-+    0x3b, 0x51, 0x57, 0x71, 0x8d, 0xb6, 0x2b, 0x82, 0x65, 0x21,
-+    0x53, 0x5f, 0x28, 0x29, 0x4f, 0x8d, 0x7c, 0x8a, 0xb9, 0x44,
-+    0xb3, 0x28, 0x41, 0x4f, 0xd3, 0xfa, 0x6a, 0xf8, 0xb9, 0x28,
-+    0x50, 0x39, 0x67, 0x53, 0x2c, 0x3c, 0xd7, 0xcb, 0x96, 0x41,
-+    0x40, 0x32, 0xbb, 0xeb, 0x70, 0xae, 0x1f, 0xb0, 0x65, 0xf7,
-+    0x3a, 0xd9, 0x22, 0xfd, 0x10, 0xae, 0xbd, 0x02, 0xe2, 0xdd,
-+    0xf3, 0xc2, 0x79, 0x3c, 0xc6, 0xfc, 0x75, 0xbb, 0xaf, 0x4e,
-+    0x3a, 0x36, 0xc2, 0x4f, 0xea, 0x25, 0xdf, 0x13, 0x16, 0x4b,
-+    0x20, 0xfe, 0x4b, 0x69, 0x16, 0xc4, 0x7f, 0x1a, 0x43, 0xa6,
-+    0x17, 0x1b, 0xb9, 0x0a, 0xf3, 0x09, 0x86, 0x28, 0x89, 0xcf,
-+    0x2c, 0xd0, 0xd4, 0x81, 0xaf, 0xc6, 0x6d, 0xe6, 0x21, 0x8d,
-+    0xee, 0xef, 0xea, 0xdc, 0xb7, 0xc6, 0x3b, 0x63, 0x9f, 0x0e,
-+    0xad, 0x89, 0x78, 0x23, 0x18, 0xbf, 0x70, 0x7e, 0x84, 0xe0,
-+    0x37, 0xec, 0xdb, 0x8e, 0x9c, 0x3e, 0x6a, 0x19, 0xcc, 0x99,
-+    0x72, 0xe6, 0xb5, 0x7d, 0x6d, 0xfa, 0xe5, 0xd3, 0xe4, 0x90,
-+    0xb5, 0xb2, 0xb2, 0x12, 0x70, 0x4e, 0xca, 0xf8, 0x10, 0xf8,
-+    0xa3, 0x14, 0xc2, 0x48, 0x19, 0xeb, 0x60, 0x99, 0xbb, 0x2a,
-+    0x1f, 0xb1, 0x7a, 0xb1, 0x3d, 0x24, 0xfb, 0xa0, 0x29, 0xda,
-+    0xbd, 0x1b, 0xd7, 0xa4, 0xbf, 0xef, 0x60, 0x2d, 0x22, 0xca,
-+    0x65, 0x98, 0xf1, 0xc4, 0xe1, 0xc9, 0x02, 0x6b, 0x16, 0x28,
-+    0x2f, 0xa1, 0xaa, 0x79, 0x00, 0xda, 0xdc, 0x7c, 0x43, 0xf7,
-+    0x42, 0x3c, 0xa0, 0xef, 0x68, 0xf7, 0xdf, 0xb9, 0x69, 0xfb,
-+    0x8e, 0x01, 0xed, 0x01, 0x42, 0xb5, 0x4e, 0x57, 0xa6, 0x26,
-+    0xb8, 0xd0, 0x7b, 0x56, 0x6d, 0x03, 0xc6, 0x40, 0x8c, 0x8c,
-+    0x2a, 0x55, 0xd7, 0x9c, 0x35, 0x00, 0x94, 0x93, 0xec, 0x03,
-+    0xeb, 0x22, 0xef, 0x77, 0xbb, 0x79, 0x13, 0x3f, 0x15, 0xa1,
-+    0x8f, 0xca, 0xdf, 0xfd, 0xd3, 0xb8, 0xe1, 0xd4, 0xcc, 0x09,
-+    0x3f, 0x3c, 0x2c, 0xdb, 0xd1, 0x49, 0x7f, 0x38, 0x07, 0x83,
-+    0x6d, 0xeb, 0x08, 0x66, 0xe9, 0x06, 0x44, 0x12, 0xac, 0x95,
-+    0x22, 0x90, 0x23, 0x67, 0xd4, 0x08, 0xcc, 0xf4, 0xb7, 0xdc,
-+    0xcc, 0x87, 0xd4, 0xac, 0x69, 0x35, 0x4c, 0xb5, 0x39, 0x36,
-+    0xcd, 0xa4, 0xd2, 0x95, 0xca, 0x0d, 0xc5, 0xda, 0xc2, 0xc5,
-+    0x22, 0x32, 0x28, 0x08, 0xe3, 0xd2, 0x8b, 0x38, 0x30, 0xdc,
-+    0x8c, 0x75, 0x4f, 0x6a, 0xec, 0x7a, 0xac, 0x16, 0x3e, 0xa8,
-+    0xd4, 0x6a, 0x45, 0xe1, 0xa8, 0x4f, 0x2e, 0x80, 0x34, 0xaa,
-+    0x54, 0x1b, 0x02, 0x95, 0x7d, 0x8a, 0x6d, 0xcc, 0x79, 0xca,
-+    0xf2, 0xa4, 0x2e, 0x8d, 0xfb, 0xfe, 0x15, 0x51, 0x10, 0x0e,
-+    0x4d, 0x88, 0xb1, 0xc7, 0xf4, 0x79, 0xdb, 0xf0, 0xb4, 0x56,
-+    0x44, 0x37, 0xca, 0x5a, 0xc1, 0x8c, 0x48, 0xac, 0xae, 0x48,
-+    0x80, 0x83, 0x01, 0x3f, 0xde, 0xd9, 0xd3, 0x2c, 0x51, 0x46,
-+    0xb1, 0x41, 0xb6, 0xc6, 0x91, 0x72, 0xf9, 0x83, 0x55, 0x1b,
-+    0x8c, 0xba, 0xf3, 0x73, 0xe5, 0x2c, 0x74, 0x50, 0x3a, 0xbe,
-+    0xc5, 0x2f, 0xa7, 0xb2, 0x6d, 0x8c, 0x9e, 0x13, 0x77, 0xa3,
-+    0x13, 0xcd, 0x6d, 0x8c, 0x45, 0xe1, 0xfc, 0x0b, 0xb7, 0x69,
-+    0xe9, 0x27, 0xbc, 0x65, 0xc3, 0xfa, 0x9b, 0xd0, 0xef, 0xfe,
-+    0xe8, 0x1f, 0xb3, 0x5e, 0x34, 0xf4, 0x8c, 0xea, 0xfc, 0xd3,
-+    0x81, 0xbf, 0x3d, 0x30, 0xb2, 0xb4, 0x01, 0xe8, 0x43, 0x0f,
-+    0xba, 0x02, 0x23, 0x42, 0x76, 0x82, 0x31, 0x73, 0x91, 0xed,
-+    0x07, 0x46, 0x61, 0x0d, 0x39, 0x83, 0x40, 0xce, 0x7a, 0xd4,
-+    0xdb, 0x80, 0x2c, 0x1f, 0x0d, 0xd1, 0x34, 0xd4, 0x92, 0xe3,
-+    0xd4, 0xf1, 0xc2, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
-+    0x82, 0x02, 0x01, 0x00, 0x97, 0x6c, 0xda, 0x6e, 0xea, 0x4f,
-+    0xcf, 0xaf, 0xf7, 0x4c, 0xd9, 0xf1, 0x90, 0x00, 0x77, 0xdb,
-+    0xf2, 0x97, 0x76, 0x72, 0xb9, 0xb7, 0x47, 0xd1, 0x9c, 0xdd,
-+    0xcb, 0x4a, 0x33, 0x6e, 0xc9, 0x75, 0x76, 0xe6, 0xe4, 0xa5,
-+    0x31, 0x8c, 0x77, 0x13, 0xb4, 0x29, 0xcd, 0xf5, 0x52, 0x17,
-+    0xef, 0xf3, 0x08, 0x00, 0xe3, 0xbd, 0x2e, 0xbc, 0xd4, 0x52,
-+    0x88, 0xe9, 0x30, 0x75, 0x0b, 0x02, 0xf5, 0xcd, 0x89, 0x0c,
-+    0x6c, 0x57, 0x19, 0x27, 0x3d, 0x1e, 0x85, 0xb4, 0xc1, 0x2f,
-+    0x1d, 0x92, 0x00, 0x5c, 0x76, 0x29, 0x4b, 0xa4, 0xe1, 0x12,
-+    0xb3, 0xc8, 0x09, 0xfe, 0x0e, 0x78, 0x72, 0x61, 0xcb, 0x61,
-+    0x6f, 0x39, 0x91, 0x95, 0x4e, 0xd5, 0x3e, 0xc7, 0x8f, 0xb8,
-+    0xf6, 0x36, 0xfe, 0x9c, 0x93, 0x9a, 0x38, 0x25, 0x7a, 0xf4,
-+    0x4a, 0x12, 0xd4, 0xa0, 0x13, 0xbd, 0xf9, 0x1d, 0x12, 0x3e,
-+    0x21, 0x39, 0xfb, 0x72, 0xe0, 0x05, 0x3d, 0xc3, 0xe5, 0x50,
-+    0xa8, 0x5d, 0x85, 0xa3, 0xea, 0x5f, 0x1c, 0xb2, 0x3f, 0xea,
-+    0x6d, 0x03, 0x91, 0x55, 0xd8, 0x19, 0x0a, 0x21, 0x12, 0x16,
-+    0xd9, 0x12, 0xc4, 0xe6, 0x07, 0x18, 0x5b, 0x26, 0xa4, 0xae,
-+    0xed, 0x2b, 0xb7, 0xa6, 0xed, 0xf8, 0xad, 0xec, 0x77, 0xe6,
-+    0x7f, 0x4f, 0x76, 0x00, 0xc0, 0xfa, 0x15, 0x92, 0xb4, 0x2c,
-+    0x22, 0xc2, 0xeb, 0x6a, 0xad, 0x14, 0x05, 0xb2, 0xe5, 0x8a,
-+    0x9e, 0x85, 0x83, 0xcc, 0x04, 0xf1, 0x56, 0x78, 0x44, 0x5e,
-+    0xde, 0xe0, 0x60, 0x1a, 0x65, 0x79, 0x31, 0x23, 0x05, 0xbb,
-+    0x01, 0xff, 0xdd, 0x2e, 0xb7, 0xb3, 0xaa, 0x74, 0xe0, 0xa5,
-+    0x94, 0xaf, 0x4b, 0xde, 0x58, 0x0f, 0x55, 0xde, 0x33, 0xf6,
-+    0xe3, 0xd6, 0x34, 0x36, 0x57, 0xd6, 0x79, 0x91, 0x2e, 0xbe,
-+    0x3b, 0xd9, 0x4e, 0xb6, 0x9d, 0x21, 0x5c, 0xd3, 0x48, 0x14,
-+    0x7f, 0x4a, 0xc4, 0x60, 0xa9, 0x29, 0xf8, 0x53, 0x7f, 0x88,
-+    0x11, 0x2d, 0xb5, 0xc5, 0x2d, 0x6f, 0xee, 0x85, 0x0b, 0xf7,
-+    0x8d, 0x9a, 0xbe, 0xb0, 0x42, 0xf2, 0x2e, 0x71, 0xaf, 0x19,
-+    0x31, 0x6d, 0xec, 0xcd, 0x6f, 0x2b, 0x23, 0xdf, 0xb4, 0x40,
-+    0xaf, 0x2c, 0x0a, 0xc3, 0x1b, 0x7d, 0x7d, 0x03, 0x1d, 0x4b,
-+    0xf3, 0xb5, 0xe0, 0x85, 0xd8, 0xdf, 0x91, 0x6b, 0x0a, 0x69,
-+    0xf7, 0xf2, 0x69, 0x66, 0x5b, 0xf1, 0xcf, 0x46, 0x7d, 0xe9,
-+    0x70, 0xfa, 0x6d, 0x7e, 0x75, 0x4e, 0xa9, 0x77, 0xe6, 0x8c,
-+    0x02, 0xf7, 0x14, 0x4d, 0xa5, 0x41, 0x8f, 0x3f, 0xc1, 0x62,
-+    0x1e, 0x71, 0x5e, 0x38, 0xb4, 0xd6, 0xe6, 0xe1, 0x4b, 0xc2,
-+    0x2c, 0x30, 0x83, 0x81, 0x6f, 0x49, 0x2e, 0x96, 0xe6, 0xc9,
-+    0x9a, 0xf7, 0x5d, 0x09, 0xa0, 0x55, 0x02, 0xa5, 0x3a, 0x25,
-+    0x23, 0xd0, 0x92, 0xc3, 0xa3, 0xe3, 0x0e, 0x12, 0x2f, 0x4d,
-+    0xef, 0xf3, 0x55, 0x5a, 0xbe, 0xe6, 0x19, 0x86, 0x31, 0xab,
-+    0x75, 0x9a, 0xd3, 0xf0, 0x2c, 0xc5, 0x41, 0x92, 0xd9, 0x1f,
-+    0x5f, 0x11, 0x8c, 0x75, 0x1c, 0x63, 0xd0, 0x02, 0x80, 0x2c,
-+    0x68, 0xcb, 0x93, 0xfb, 0x51, 0x73, 0x49, 0xb4, 0x60, 0xda,
-+    0xe2, 0x26, 0xaf, 0xa9, 0x46, 0x12, 0xb8, 0xec, 0x50, 0xdd,
-+    0x12, 0x06, 0x5f, 0xce, 0x59, 0xe6, 0xf6, 0x1c, 0xe0, 0x54,
-+    0x10, 0xad, 0xf6, 0xcd, 0x98, 0xcc, 0x0f, 0xfb, 0xcb, 0x41,
-+    0x14, 0x9d, 0xed, 0xe4, 0xb4, 0x74, 0x5f, 0x09, 0x60, 0xc7,
-+    0x12, 0xf6, 0x7b, 0x3c, 0x8f, 0xa7, 0x20, 0xbc, 0xe4, 0xb1,
-+    0xef, 0xeb, 0xa4, 0x93, 0xc5, 0x06, 0xca, 0x9a, 0x27, 0x9d,
-+    0x87, 0xf3, 0xde, 0xca, 0xe5, 0xe7, 0xf6, 0x1c, 0x01, 0x65,
-+    0x5b, 0xfb, 0x19, 0x79, 0x6e, 0x08, 0x26, 0xc5, 0xc8, 0x28,
-+    0x0e, 0xb6, 0x3b, 0x07, 0x08, 0xc1, 0x02, 0x82, 0x01, 0x01,
-+    0x00, 0xe8, 0x1c, 0x73, 0xa6, 0xb8, 0xe0, 0x0e, 0x6d, 0x8d,
-+    0x1b, 0xb9, 0x53, 0xed, 0x58, 0x94, 0xe6, 0x1d, 0x60, 0x14,
-+    0x5c, 0x76, 0x43, 0xc4, 0x58, 0x19, 0xc4, 0x24, 0xe8, 0xbc,
-+    0x1b, 0x3b, 0x0b, 0x13, 0x24, 0x45, 0x54, 0x0e, 0xcc, 0x37,
-+    0xf0, 0xe0, 0x63, 0x7d, 0xc3, 0xf7, 0xfb, 0x81, 0x74, 0x81,
-+    0xc4, 0x0f, 0x1a, 0x21, 0x48, 0xaf, 0xce, 0xc1, 0xc4, 0x94,
-+    0x18, 0x06, 0x44, 0x8d, 0xd3, 0xd2, 0x22, 0x2d, 0x2d, 0x3e,
-+    0x5a, 0x31, 0xdc, 0x95, 0x8e, 0xf4, 0x41, 0xfc, 0x58, 0xc9,
-+    0x40, 0x92, 0x17, 0x5f, 0xe3, 0xda, 0xac, 0x9e, 0x3f, 0x1c,
-+    0x2a, 0x6b, 0x58, 0x5f, 0x48, 0x78, 0x20, 0xb1, 0xaf, 0x24,
-+    0x9b, 0x3c, 0x20, 0x8b, 0x93, 0x25, 0x9e, 0xe6, 0x6b, 0xbc,
-+    0x13, 0x42, 0x14, 0x6c, 0x36, 0x31, 0xff, 0x7a, 0xd1, 0xc1,
-+    0x1a, 0x26, 0x14, 0x7f, 0xa9, 0x76, 0xa7, 0x0c, 0xf8, 0xcc,
-+    0xed, 0x07, 0x6a, 0xd2, 0xdf, 0x62, 0xee, 0x0a, 0x7c, 0x84,
-+    0xcb, 0x49, 0x90, 0xb2, 0x03, 0x0d, 0xa2, 0x82, 0x06, 0x77,
-+    0xf1, 0xcd, 0x67, 0xf2, 0x47, 0x21, 0x02, 0x3f, 0x43, 0x21,
-+    0xf0, 0x46, 0x30, 0x62, 0x51, 0x72, 0xb1, 0xe7, 0x48, 0xc6,
-+    0x67, 0x12, 0xcd, 0x9e, 0xd6, 0x15, 0xe5, 0x21, 0xed, 0xfa,
-+    0x8f, 0x30, 0xa6, 0x41, 0xfe, 0xb6, 0xfa, 0x8f, 0x34, 0x14,
-+    0x19, 0xe8, 0x11, 0xf7, 0xa5, 0x77, 0x3e, 0xb7, 0xf9, 0x39,
-+    0x07, 0x8c, 0x67, 0x2a, 0xab, 0x7b, 0x08, 0xf8, 0xb0, 0x06,
-+    0xa8, 0xea, 0x2f, 0x8f, 0xfa, 0xcc, 0xcc, 0x40, 0xce, 0xf3,
-+    0x70, 0x4f, 0x3f, 0x7f, 0xe2, 0x0c, 0xea, 0x76, 0x4a, 0x35,
-+    0x4e, 0x47, 0xad, 0x2b, 0xa7, 0x97, 0x5d, 0x74, 0x43, 0x97,
-+    0x90, 0xd2, 0xfb, 0xd9, 0xf9, 0x96, 0x01, 0x33, 0x05, 0xed,
-+    0x7b, 0x03, 0x05, 0xad, 0xf8, 0x49, 0x03, 0x02, 0x82, 0x01,
-+    0x01, 0x00, 0xd4, 0x40, 0x17, 0x66, 0x10, 0x92, 0x95, 0xc8,
-+    0xec, 0x62, 0xa9, 0x7a, 0xcb, 0x93, 0x8e, 0xe6, 0x53, 0xd4,
-+    0x80, 0x48, 0x27, 0x4b, 0x41, 0xce, 0x61, 0xdf, 0xbf, 0x94,
-+    0xa4, 0x3d, 0x71, 0x03, 0x0b, 0xed, 0x25, 0x71, 0x98, 0xa4,
-+    0xd6, 0xd5, 0x4a, 0x57, 0xf5, 0x6c, 0x1b, 0xda, 0x21, 0x7d,
-+    0x35, 0x45, 0xb3, 0xf3, 0x6a, 0xd9, 0xd3, 0x43, 0xe8, 0x5c,
-+    0x54, 0x1c, 0x83, 0x1b, 0xb4, 0x5f, 0xf2, 0x97, 0x24, 0x2e,
-+    0xdc, 0x40, 0xde, 0x92, 0x23, 0x59, 0x8e, 0xbc, 0xd2, 0xa1,
-+    0xf2, 0xe0, 0x4c, 0xdd, 0x0b, 0xd1, 0xe7, 0xae, 0x65, 0xbc,
-+    0xb5, 0xf5, 0x5b, 0x98, 0xe9, 0xd7, 0xc2, 0xb7, 0x0e, 0x55,
-+    0x71, 0x0e, 0x3c, 0x0a, 0x24, 0x6b, 0xa6, 0xe6, 0x14, 0x61,
-+    0x11, 0xfd, 0x33, 0x42, 0x99, 0x2b, 0x84, 0x77, 0x74, 0x92,
-+    0x91, 0xf5, 0x79, 0x79, 0xcf, 0xad, 0x8e, 0x04, 0xef, 0x80,
-+    0x1e, 0x57, 0xf4, 0x14, 0xf5, 0x35, 0x09, 0x74, 0xb2, 0x13,
-+    0x71, 0x58, 0x6b, 0xea, 0x32, 0x5d, 0xf3, 0xd3, 0x76, 0x48,
-+    0x39, 0x10, 0x23, 0x84, 0x9d, 0xbe, 0x92, 0x77, 0x4a, 0xed,
-+    0x70, 0x3e, 0x1a, 0xa2, 0x6c, 0xb3, 0x81, 0x00, 0xc3, 0xc9,
-+    0xe4, 0x52, 0xc8, 0x24, 0x88, 0x0c, 0x41, 0xad, 0x87, 0x5a,
-+    0xea, 0xa3, 0x7a, 0x85, 0x1c, 0x5e, 0x31, 0x7f, 0xc3, 0x35,
-+    0xc6, 0xfa, 0x10, 0xc8, 0x75, 0x10, 0xc4, 0x96, 0x99, 0xe7,
-+    0xfe, 0x01, 0xb4, 0x74, 0xdb, 0xb4, 0x11, 0xc3, 0xc8, 0x8c,
-+    0xf6, 0xf7, 0x3b, 0x66, 0x50, 0xfc, 0xdb, 0xeb, 0xca, 0x47,
-+    0x85, 0x89, 0xe1, 0x65, 0xd9, 0x62, 0x34, 0x3c, 0x70, 0xd8,
-+    0x2e, 0xb4, 0x2f, 0x65, 0x3c, 0x4a, 0xa6, 0x2a, 0xe7, 0xc7,
-+    0xd8, 0x41, 0x8f, 0x8a, 0x43, 0xbf, 0x42, 0xf2, 0x4d, 0xbc,
-+    0xfc, 0x9e, 0x27, 0x95, 0xfb, 0x75, 0xff, 0xab, 0x02, 0x82,
-+    0x01, 0x00, 0x41, 0x2f, 0x44, 0x57, 0x6d, 0x12, 0x17, 0x5b,
-+    0x32, 0xc6, 0xb7, 0x6c, 0x57, 0x7a, 0x8a, 0x0e, 0x79, 0xef,
-+    0x72, 0xa8, 0x68, 0xda, 0x2d, 0x38, 0xe4, 0xbb, 0x8d, 0xf6,
-+    0x02, 0x65, 0xcf, 0x56, 0x13, 0xe1, 0x1a, 0xcb, 0x39, 0x80,
-+    0xa6, 0xb1, 0x32, 0x03, 0x1e, 0xdd, 0xbb, 0x35, 0xd9, 0xac,
-+    0x43, 0x89, 0x31, 0x08, 0x90, 0x92, 0x5e, 0x35, 0x3d, 0x7b,
-+    0x9c, 0x6f, 0x86, 0xcb, 0x17, 0xdd, 0x85, 0xe4, 0xed, 0x35,
-+    0x08, 0x8e, 0xc1, 0xf4, 0x05, 0xd8, 0x68, 0xc6, 0x63, 0x3c,
-+    0xf7, 0xff, 0xf7, 0x47, 0x33, 0x39, 0xc5, 0x3e, 0xb7, 0x0e,
-+    0x58, 0x35, 0x9d, 0x81, 0xea, 0xf8, 0x6a, 0x2c, 0x1c, 0x5a,
-+    0x68, 0x78, 0x64, 0x11, 0x6b, 0xc1, 0x3e, 0x4e, 0x7a, 0xbd,
-+    0x84, 0xcb, 0x0f, 0xc2, 0xb6, 0x85, 0x1d, 0xd3, 0x76, 0xc5,
-+    0x93, 0x6a, 0x69, 0x89, 0x56, 0x34, 0xdc, 0x4a, 0x9b, 0xbc,
-+    0xff, 0xa8, 0x0d, 0x6e, 0x35, 0x9c, 0x60, 0xa7, 0x23, 0x30,
-+    0xc7, 0x06, 0x64, 0x39, 0x8b, 0x94, 0x89, 0xee, 0xba, 0x7f,
-+    0x60, 0x8d, 0xfa, 0xb6, 0x97, 0x76, 0xdc, 0x51, 0x4a, 0x3c,
-+    0xeb, 0x3a, 0x14, 0x2c, 0x20, 0x60, 0x69, 0x4a, 0x86, 0xfe,
-+    0x8c, 0x21, 0x84, 0x49, 0x54, 0xb3, 0x20, 0xe1, 0x01, 0x7f,
-+    0x58, 0xdf, 0x7f, 0xb5, 0x21, 0x51, 0x8c, 0x47, 0x9f, 0x91,
-+    0xeb, 0x97, 0x3e, 0xf2, 0x54, 0xcf, 0x16, 0x46, 0xf9, 0xd9,
-+    0xb6, 0xe7, 0x64, 0xc9, 0xd0, 0x54, 0xea, 0x2f, 0xa1, 0xcf,
-+    0xa5, 0x7f, 0x28, 0x8d, 0x84, 0xec, 0xd5, 0x39, 0x03, 0x76,
-+    0x5b, 0x2d, 0x8e, 0x43, 0xf2, 0x01, 0x24, 0xc9, 0x6f, 0xc0,
-+    0xf5, 0x69, 0x6f, 0x7d, 0xb5, 0x85, 0xd2, 0x5f, 0x7f, 0x78,
-+    0x40, 0x07, 0x7f, 0x09, 0x15, 0xb5, 0x1f, 0x28, 0x65, 0x10,
-+    0xe4, 0x19, 0xa8, 0xc6, 0x9e, 0x8d, 0xdc, 0xcb, 0x02, 0x82,
-+    0x01, 0x00, 0x13, 0x01, 0xee, 0x56, 0x80, 0x93, 0x70, 0x00,
-+    0x7f, 0x52, 0xd2, 0x94, 0xa1, 0x98, 0x84, 0x4a, 0x92, 0x25,
-+    0x4c, 0x9b, 0xa9, 0x91, 0x2e, 0xc2, 0x79, 0xb7, 0x5c, 0xe3,
-+    0xc5, 0xd5, 0x8e, 0xc2, 0x54, 0x16, 0x17, 0xad, 0x55, 0x9b,
-+    0x25, 0x76, 0x12, 0x63, 0x50, 0x22, 0x2f, 0x58, 0x58, 0x79,
-+    0x6b, 0x04, 0xe3, 0xf9, 0x9f, 0x8f, 0x04, 0x41, 0x67, 0x94,
-+    0xa5, 0x1f, 0xac, 0x8a, 0x15, 0x9c, 0x26, 0x10, 0x6c, 0xf8,
-+    0x19, 0x57, 0x61, 0xd7, 0x3a, 0x7d, 0x31, 0xb0, 0x2d, 0x38,
-+    0xbd, 0x94, 0x62, 0xad, 0xc4, 0xfa, 0x36, 0x42, 0x42, 0xf0,
-+    0x24, 0x67, 0x65, 0x9d, 0x8b, 0x0b, 0x7c, 0x6f, 0x82, 0x44,
-+    0x1a, 0x8c, 0xc8, 0xc9, 0xab, 0xbb, 0x4c, 0x45, 0xfc, 0x7b,
-+    0x38, 0xee, 0x30, 0xe1, 0xfc, 0xef, 0x8d, 0xbc, 0x58, 0xdf,
-+    0x2b, 0x5d, 0x0d, 0x54, 0xe0, 0x49, 0x4d, 0x97, 0x99, 0x8f,
-+    0x22, 0xa8, 0x83, 0xbe, 0x40, 0xbb, 0x50, 0x2e, 0x78, 0x28,
-+    0x0f, 0x95, 0x78, 0x8c, 0x8f, 0x98, 0x24, 0x56, 0xc2, 0x97,
-+    0xf3, 0x2c, 0x43, 0xd2, 0x03, 0x82, 0x66, 0x81, 0x72, 0x5f,
-+    0x53, 0x16, 0xec, 0xb1, 0xb1, 0x04, 0x5e, 0x40, 0x20, 0x48,
-+    0x7b, 0x3f, 0x02, 0x97, 0x6a, 0xeb, 0x96, 0x12, 0x21, 0x35,
-+    0xfe, 0x1f, 0x47, 0xc0, 0x95, 0xea, 0xc5, 0x8a, 0x08, 0x84,
-+    0x4f, 0x5e, 0x63, 0x94, 0x60, 0x0f, 0x71, 0x5b, 0x7f, 0x4a,
-+    0xec, 0x4f, 0x60, 0xc6, 0xba, 0x4a, 0x24, 0xf1, 0x20, 0x8b,
-+    0xa7, 0x2e, 0x3a, 0xce, 0x8d, 0xe0, 0x27, 0x1d, 0xb5, 0x8e,
-+    0xb4, 0x21, 0xc5, 0xe2, 0xa6, 0x16, 0x0a, 0x51, 0x83, 0x55,
-+    0x88, 0xd1, 0x30, 0x11, 0x63, 0xd5, 0xd7, 0x8d, 0xae, 0x16,
-+    0x12, 0x82, 0xc4, 0x85, 0x00, 0x4e, 0x27, 0x83, 0xa5, 0x7c,
-+    0x90, 0x2e, 0xe5, 0xa2, 0xa3, 0xd3, 0x4c, 0x63, 0x02, 0x82,
-+    0x01, 0x01, 0x00, 0x86, 0x08, 0x98, 0x98, 0xa5, 0x00, 0x05,
-+    0x39, 0x77, 0xd9, 0x66, 0xb3, 0xcf, 0xca, 0xa0, 0x71, 0xb3,
-+    0x50, 0xce, 0x3d, 0xb1, 0x93, 0x95, 0x35, 0xc4, 0xd4, 0x2e,
-+    0x90, 0xdf, 0x0f, 0xfc, 0x60, 0xc1, 0x94, 0x68, 0x61, 0x43,
-+    0xca, 0x9a, 0x23, 0x4a, 0x1e, 0x45, 0x72, 0x99, 0xb5, 0x1e,
-+    0x61, 0x8d, 0x77, 0x0f, 0xa0, 0xbb, 0xd7, 0x77, 0xb4, 0x2a,
-+    0x15, 0x11, 0x88, 0x2d, 0xb3, 0x56, 0x61, 0x5e, 0x6a, 0xed,
-+    0xa4, 0x46, 0x4a, 0x3f, 0x50, 0x11, 0xd6, 0xba, 0xb6, 0xd7,
-+    0x95, 0x65, 0x53, 0xc3, 0xa1, 0x8f, 0xe0, 0xa3, 0xf5, 0x1c,
-+    0xfd, 0xaf, 0x6e, 0x43, 0xd7, 0x17, 0xa7, 0xd3, 0x81, 0x1b,
-+    0xa4, 0xdf, 0xe0, 0x97, 0x8a, 0x46, 0x03, 0xd3, 0x46, 0x0e,
-+    0x83, 0x48, 0x4e, 0xd2, 0x02, 0xcb, 0xc0, 0xad, 0x79, 0x95,
-+    0x8c, 0x96, 0xba, 0x40, 0x34, 0x11, 0x71, 0x5e, 0xe9, 0x11,
-+    0xf9, 0xc5, 0x4a, 0x5e, 0x91, 0x9d, 0xf5, 0x92, 0x4f, 0xeb,
-+    0xc6, 0x70, 0x02, 0x2d, 0x3d, 0x04, 0xaa, 0xe9, 0x3a, 0x8e,
-+    0xd5, 0xa8, 0xad, 0xf7, 0xce, 0x0d, 0x16, 0xb2, 0xec, 0x0a,
-+    0x9c, 0xf5, 0x94, 0x39, 0xb9, 0x8a, 0xfc, 0x1e, 0xf9, 0xcc,
-+    0xf2, 0x5f, 0x21, 0x31, 0x74, 0x72, 0x6b, 0x64, 0xae, 0x35,
-+    0x61, 0x8d, 0x0d, 0xcb, 0xe7, 0xda, 0x39, 0xca, 0xf3, 0x21,
-+    0x66, 0x0b, 0x95, 0xd7, 0x0a, 0x7c, 0xca, 0xa1, 0xa9, 0x5a,
-+    0xe8, 0xac, 0xe0, 0x71, 0x54, 0xaf, 0x28, 0xcf, 0xd5, 0x70,
-+    0x89, 0xe0, 0xf3, 0x9e, 0x43, 0x6c, 0x8d, 0x7b, 0x99, 0x01,
-+    0x68, 0x4d, 0xa1, 0x45, 0x46, 0x0c, 0x43, 0xbc, 0xcc, 0x2c,
-+    0xdd, 0xc5, 0x46, 0xc8, 0x4e, 0x0e, 0xbe, 0xed, 0xb9, 0x26,
-+    0xab, 0x2e, 0xdb, 0xeb, 0x8f, 0xff, 0xdb, 0xb0, 0xc6, 0x55,
-+    0xaf, 0xf8, 0x2a, 0x91, 0x9d, 0x50, 0x44, 0x21, 0x17,
-+};
-+
-+static unsigned char test7680[] = {
-+    0x30, 0x82, 0x11, 0x09, 0x02, 0x01, 0x00, 0x02, 0x82, 0x03,
-+    0xc1, 0x00, 0xe3, 0x27, 0x46, 0x99, 0xb5, 0x17, 0xab, 0xfa,
-+    0x65, 0x05, 0x7a, 0x06, 0x81, 0x14, 0xce, 0x43, 0x21, 0x49,
-+    0x0f, 0x08, 0xf1, 0x70, 0xb4, 0xc1, 0x10, 0xd1, 0x87, 0xf8,
-+    0x29, 0x91, 0x36, 0x66, 0x2d, 0xbe, 0x7b, 0x1d, 0xa2, 0x0b,
-+    0x20, 0x38, 0xd9, 0x8e, 0x78, 0x27, 0xcf, 0xb5, 0x45, 0x58,
-+    0x3d, 0xf4, 0xda, 0xf0, 0xdc, 0x21, 0x17, 0x52, 0xcd, 0x68,
-+    0xe2, 0x81, 0xac, 0x88, 0x61, 0x10, 0xbc, 0xb0, 0x7f, 0xe4,
-+    0xf3, 0x78, 0xb7, 0x28, 0x6c, 0x5f, 0x5c, 0xc2, 0x8d, 0x3d,
-+    0xb0, 0x87, 0x41, 0x15, 0x2e, 0x09, 0x5f, 0xea, 0x06, 0x7f,
-+    0xe9, 0x35, 0x18, 0x90, 0x50, 0xad, 0xf6, 0xb9, 0xfd, 0x33,
-+    0x02, 0x1a, 0x99, 0x9e, 0xa5, 0x7d, 0x2c, 0x3b, 0x24, 0xe7,
-+    0x31, 0x35, 0x73, 0x9a, 0xb0, 0xfe, 0x03, 0xfc, 0xc6, 0x98,
-+    0x78, 0xd9, 0x66, 0x95, 0xa5, 0x12, 0xbc, 0x1e, 0x82, 0xbc,
-+    0xf1, 0xc5, 0x31, 0xcd, 0xa6, 0xb1, 0x0c, 0x02, 0xbf, 0x7f,
-+    0xb7, 0xaf, 0x5f, 0xd6, 0xed, 0xf7, 0xc1, 0x59, 0x86, 0x3a,
-+    0x35, 0x95, 0x54, 0x21, 0x8d, 0x6a, 0xb3, 0xd1, 0x2b, 0x71,
-+    0xf5, 0xf1, 0x66, 0x00, 0xb1, 0x88, 0xee, 0x3b, 0xa4, 0x41,
-+    0x52, 0x1a, 0xf5, 0x0e, 0x32, 0xb6, 0xbf, 0x52, 0xab, 0x51,
-+    0x55, 0x91, 0x32, 0x4f, 0xaf, 0x91, 0xac, 0xf7, 0xff, 0x8e,
-+    0x3b, 0x2b, 0x61, 0xe9, 0x6d, 0x1d, 0x68, 0x80, 0x90, 0x79,
-+    0x34, 0x96, 0xca, 0x49, 0x43, 0x7c, 0x89, 0x4e, 0x5e, 0x31,
-+    0xb5, 0xce, 0x01, 0x9b, 0x09, 0xaf, 0x92, 0x06, 0x24, 0xe7,
-+    0x22, 0x35, 0xcc, 0xa2, 0x0b, 0xfb, 0x5b, 0x87, 0x65, 0x71,
-+    0xff, 0x64, 0x3e, 0xf9, 0xe8, 0x33, 0xa0, 0xc3, 0x4e, 0xb2,
-+    0x41, 0x98, 0x54, 0xeb, 0x13, 0x99, 0xfb, 0x32, 0x78, 0x7e,
-+    0xda, 0x4f, 0xd3, 0x46, 0x6a, 0xb5, 0x78, 0x81, 0x3f, 0x04,
-+    0x13, 0x5f, 0x67, 0xaf, 0x88, 0xa5, 0x9e, 0x0d, 0xc5, 0xf3,
-+    0xe7, 0x4c, 0x51, 0xf5, 0x51, 0x4a, 0xa4, 0x58, 0x64, 0xd9,
-+    0xa2, 0x32, 0x54, 0x36, 0xce, 0x38, 0xd8, 0xc2, 0x0e, 0x0d,
-+    0x60, 0x8e, 0x32, 0x7f, 0x90, 0x8a, 0xbc, 0x88, 0xbe, 0x6a,
-+    0xc0, 0x47, 0x0f, 0x02, 0x41, 0xff, 0x3b, 0x7e, 0xc5, 0xa6,
-+    0x33, 0x1d, 0x19, 0xd1, 0xd5, 0x67, 0x6c, 0xbf, 0x16, 0xb0,
-+    0x7e, 0x80, 0x10, 0xbf, 0x7f, 0xdd, 0xd0, 0xf4, 0xc3, 0x94,
-+    0x2c, 0x9a, 0x2c, 0xda, 0x69, 0x4e, 0xd6, 0x7b, 0x40, 0x4d,
-+    0x2a, 0x27, 0xcb, 0x5a, 0xe5, 0x2d, 0x3f, 0x7d, 0x51, 0x9d,
-+    0x9f, 0x70, 0xde, 0x50, 0xb1, 0xd3, 0xd2, 0x38, 0x4d, 0x1c,
-+    0xca, 0xc2, 0x1e, 0x80, 0xd0, 0x36, 0x82, 0x04, 0xe6, 0x17,
-+    0x79, 0x9f, 0x2e, 0xc9, 0xed, 0x2b, 0xd5, 0x1b, 0xfa, 0x7d,
-+    0x1a, 0x80, 0xb5, 0x0e, 0x2f, 0x05, 0xbe, 0x4a, 0x1b, 0xfe,
-+    0x0a, 0xad, 0x01, 0xde, 0x91, 0xc8, 0xf9, 0x81, 0xbe, 0xc7,
-+    0xaf, 0xe7, 0x87, 0xed, 0x9d, 0xb8, 0x6c, 0xad, 0x65, 0xed,
-+    0x5e, 0xd3, 0x67, 0x8c, 0x62, 0x3a, 0xe7, 0xfd, 0x67, 0xe0,
-+    0xbb, 0x57, 0xaf, 0x56, 0xeb, 0x4a, 0x58, 0x6e, 0xad, 0xf2,
-+    0xbe, 0xc3, 0x70, 0x29, 0xf8, 0xeb, 0x68, 0x45, 0xa0, 0xbd,
-+    0xcd, 0xa5, 0xb4, 0xd9, 0x01, 0xb7, 0x44, 0xeb, 0x97, 0xf3,
-+    0x0c, 0x56, 0xe4, 0x26, 0xd0, 0xa5, 0xb1, 0xa3, 0x49, 0x6e,
-+    0x88, 0xf2, 0x22, 0xe2, 0x7b, 0x58, 0x3a, 0xd9, 0x52, 0xa4,
-+    0xb1, 0x4c, 0x5c, 0x7c, 0xf0, 0x88, 0x7b, 0x9f, 0x06, 0xe9,
-+    0x32, 0x4e, 0xf2, 0x64, 0x83, 0x8b, 0xa2, 0xea, 0x1d, 0x25,
-+    0xf1, 0x8d, 0x16, 0x8b, 0xe0, 0xab, 0xd2, 0xe9, 0xe4, 0x6b,
-+    0x7d, 0x76, 0x98, 0x22, 0x53, 0x31, 0x6b, 0xcc, 0xf1, 0xe5,
-+    0x1d, 0xd7, 0xa5, 0xb0, 0xea, 0x6b, 0x38, 0x14, 0x0c, 0x06,
-+    0x10, 0x27, 0xd8, 0x33, 0xf3, 0x9a, 0xae, 0x94, 0xdd, 0x0b,
-+    0xb4, 0x6d, 0xe5, 0x91, 0xdd, 0xf1, 0x0f, 0x27, 0xa4, 0x94,
-+    0x55, 0xf0, 0xde, 0x07, 0x29, 0xe6, 0x3f, 0x26, 0x19, 0xa1,
-+    0xdd, 0xd1, 0x06, 0x99, 0xda, 0x54, 0x23, 0x3c, 0xf5, 0x5c,
-+    0x2e, 0x96, 0xa9, 0x21, 0x23, 0x25, 0x2e, 0x6f, 0xf1, 0xf9,
-+    0x11, 0x54, 0xe5, 0x7b, 0xb9, 0x1f, 0x11, 0xe2, 0x9e, 0x6b,
-+    0x61, 0x8b, 0xa3, 0x8b, 0xc1, 0x20, 0x9b, 0xfb, 0x51, 0xef,
-+    0xbb, 0xb9, 0xf6, 0xaf, 0x66, 0xb3, 0x2c, 0x25, 0xef, 0x76,
-+    0xcb, 0xbf, 0x7a, 0x93, 0x2f, 0xe1, 0x17, 0x56, 0xc1, 0x00,
-+    0x33, 0xb5, 0xd9, 0x91, 0x05, 0x31, 0xcc, 0x72, 0xcd, 0x4a,
-+    0x93, 0x9a, 0xe3, 0x21, 0x42, 0x9e, 0xb8, 0x4e, 0x6c, 0x27,
-+    0x93, 0xf0, 0x7f, 0x22, 0xdb, 0xe5, 0xb3, 0xa3, 0xf7, 0xe7,
-+    0x80, 0xbb, 0x91, 0xca, 0xf7, 0xe8, 0x52, 0xb8, 0x11, 0x64,
-+    0x66, 0x25, 0x94, 0xf8, 0x6f, 0x0b, 0x3b, 0xb7, 0xff, 0x80,
-+    0x9e, 0x36, 0xe9, 0x88, 0x2e, 0xab, 0x05, 0xbf, 0x99, 0x9f,
-+    0x2b, 0x4f, 0xc6, 0xb1, 0x13, 0x5b, 0x06, 0xff, 0x0a, 0x7b,
-+    0xbc, 0x7f, 0x07, 0xa0, 0x35, 0xc2, 0x2d, 0x44, 0x3e, 0xad,
-+    0x44, 0xcb, 0x47, 0x18, 0x26, 0x71, 0x7b, 0x17, 0xc9, 0x6d,
-+    0xb5, 0x4b, 0xcf, 0xdf, 0x14, 0x2c, 0x6c, 0xdf, 0x21, 0xce,
-+    0x93, 0x49, 0x34, 0x69, 0x49, 0xfd, 0x3e, 0x71, 0x5b, 0xfa,
-+    0x07, 0xc5, 0x7e, 0x5e, 0x54, 0x1a, 0x3c, 0xa6, 0x29, 0xb5,
-+    0xbf, 0x0d, 0xf1, 0xc6, 0xa4, 0x61, 0xd6, 0x17, 0x1d, 0xf0,
-+    0xa2, 0x78, 0x8f, 0xbc, 0x7e, 0x0c, 0xb4, 0xf0, 0x1e, 0x05,
-+    0xea, 0xb5, 0xad, 0x68, 0x95, 0x0b, 0x27, 0xb4, 0x29, 0x7c,
-+    0x70, 0x2a, 0x9a, 0x0a, 0x39, 0xd4, 0x76, 0xb7, 0x72, 0x30,
-+    0x5e, 0xae, 0x9c, 0x4a, 0x55, 0xc7, 0x46, 0xd7, 0x5f, 0xbe,
-+    0x10, 0x61, 0x25, 0x18, 0x7a, 0x9f, 0xd3, 0x05, 0x3d, 0x6f,
-+    0x9a, 0x1e, 0xec, 0x2b, 0x03, 0xe0, 0x49, 0x6a, 0x9c, 0xd6,
-+    0xdb, 0xc2, 0xa1, 0xe1, 0x0a, 0xbb, 0x31, 0x42, 0xc8, 0x43,
-+    0x4e, 0x7c, 0xa9, 0x7c, 0x60, 0xea, 0xbe, 0xf1, 0x8b, 0xe8,
-+    0xb2, 0x90, 0x83, 0x14, 0x21, 0xe4, 0xb3, 0x0d, 0x7c, 0x63,
-+    0x3c, 0x98, 0x55, 0xc6, 0x44, 0xa6, 0xa8, 0x1e, 0x42, 0xb7,
-+    0x89, 0xa8, 0xbd, 0xb8, 0x34, 0x3d, 0x09, 0x80, 0x99, 0x73,
-+    0x9f, 0xaf, 0x17, 0x56, 0xf2, 0x73, 0x3e, 0x1e, 0x6e, 0xe9,
-+    0x18, 0xa0, 0x5b, 0x69, 0xce, 0xfd, 0x3d, 0x77, 0x81, 0x95,
-+    0x3b, 0xf1, 0xde, 0x26, 0xe9, 0x27, 0xef, 0x92, 0x2a, 0x97,
-+    0xdc, 0x95, 0xa5, 0xa3, 0xb0, 0xfb, 0x96, 0x89, 0x4f, 0xe6,
-+    0xc1, 0x42, 0x0b, 0xfd, 0xb4, 0x6d, 0x0a, 0x9f, 0x9b, 0x31,
-+    0xd8, 0x21, 0x38, 0x8a, 0xee, 0xb6, 0x5c, 0x12, 0xa8, 0xb4,
-+    0x07, 0x79, 0x41, 0xa7, 0x7f, 0x13, 0x74, 0xad, 0x0b, 0xee,
-+    0x28, 0x52, 0xac, 0x2f, 0x4d, 0x30, 0x1c, 0xc5, 0xa6, 0xa5,
-+    0x61, 0x42, 0xbd, 0xe1, 0x4f, 0xd3, 0xec, 0x66, 0xf2, 0x63,
-+    0xf4, 0x93, 0xdb, 0x35, 0x2d, 0x3b, 0x71, 0x25, 0x09, 0xde,
-+    0xda, 0x46, 0xda, 0xe2, 0xa7, 0xa3, 0xdf, 0xcd, 0xbf, 0x58,
-+    0x05, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x03,
-+    0xc0, 0x5f, 0xd5, 0x15, 0x1b, 0x09, 0xe4, 0xa7, 0xc0, 0xa6,
-+    0xd8, 0x0d, 0xa8, 0x2a, 0xd3, 0x1d, 0x46, 0x03, 0x07, 0xf0,
-+    0x98, 0xe4, 0x4b, 0x99, 0x66, 0x8e, 0x72, 0xe7, 0xbb, 0x51,
-+    0xc6, 0x1a, 0xbe, 0x36, 0xf4, 0x52, 0xba, 0xa8, 0xbf, 0xaa,
-+    0xe3, 0x71, 0x1d, 0x83, 0x21, 0xc0, 0xa6, 0x88, 0x4f, 0xf7,
-+    0x2b, 0x93, 0x26, 0xe4, 0xa7, 0xed, 0x50, 0x18, 0xaa, 0xf4,
-+    0x4c, 0xa2, 0xfe, 0x92, 0x7c, 0xde, 0x2e, 0x54, 0x76, 0xc2,
-+    0x25, 0x1e, 0x98, 0xa6, 0x48, 0x01, 0x39, 0x6f, 0x1f, 0x24,
-+    0x97, 0x9b, 0x64, 0x95, 0x1c, 0x8d, 0x63, 0x8d, 0x44, 0x6f,
-+    0x9d, 0xdf, 0xf4, 0x1a, 0xa5, 0x9a, 0x1e, 0xd3, 0x6c, 0xae,
-+    0xa9, 0x8c, 0x3f, 0xfb, 0x2f, 0x78, 0xf6, 0xa6, 0xd6, 0x06,
-+    0xd3, 0xb7, 0x26, 0xff, 0x1e, 0xdb, 0x8d, 0xcc, 0x37, 0x4d,
-+    0x5c, 0xe2, 0xc3, 0xa5, 0x75, 0xe6, 0xf9, 0xb4, 0x4c, 0x84,
-+    0x6f, 0x9e, 0x58, 0x55, 0xc8, 0x01, 0xfa, 0x32, 0xd2, 0x6e,
-+    0x2b, 0x45, 0xf2, 0xc6, 0x48, 0xad, 0x40, 0xd8, 0xb9, 0x3c,
-+    0x1b, 0xf8, 0xf7, 0x82, 0xd3, 0x0e, 0x73, 0xe3, 0xb1, 0x5b,
-+    0x82, 0x71, 0x77, 0x3f, 0x6f, 0x36, 0x9a, 0xe0, 0xec, 0x51,
-+    0xf8, 0x5f, 0x84, 0x92, 0xee, 0xb8, 0x7e, 0xe7, 0x1a, 0x14,
-+    0x50, 0x82, 0x7a, 0x4d, 0xe6, 0xd6, 0xa3, 0x76, 0x24, 0x8a,
-+    0x5f, 0xfe, 0x19, 0xdd, 0xd7, 0xf7, 0x5b, 0xae, 0x18, 0x04,
-+    0x90, 0xcd, 0x5c, 0xe5, 0x64, 0xe8, 0x04, 0xb1, 0x06, 0xa5,
-+    0xdd, 0xf8, 0x9d, 0x71, 0x13, 0xaa, 0x36, 0x7f, 0x61, 0x27,
-+    0xf4, 0xac, 0x95, 0x7d, 0x1a, 0x99, 0x7d, 0xe0, 0xd5, 0x9c,
-+    0x5a, 0xad, 0x9a, 0xff, 0x54, 0xb0, 0xb1, 0x55, 0x45, 0x2d,
-+    0x19, 0x58, 0x52, 0x28, 0xdd, 0xe0, 0xb5, 0x65, 0x52, 0x97,
-+    0x45, 0xf0, 0x2b, 0x98, 0x1f, 0x61, 0x6c, 0x9d, 0xaa, 0x59,
-+    0x85, 0xf9, 0x97, 0x7b, 0xbd, 0xeb, 0x95, 0x81, 0xfb, 0x29,
-+    0x8c, 0xf0, 0x52, 0xdf, 0xed, 0xee, 0xb2, 0x00, 0x32, 0x35,
-+    0x14, 0xa8, 0xa4, 0xca, 0x91, 0xff, 0x18, 0xb7, 0x96, 0xfb,
-+    0x32, 0x62, 0xa9, 0xa0, 0xd0, 0x77, 0x43, 0xf5, 0x99, 0xd1,
-+    0xee, 0xe8, 0xad, 0x1a, 0x2c, 0xd4, 0xeb, 0xe1, 0xf5, 0x01,
-+    0x41, 0x78, 0xc0, 0x27, 0x19, 0x50, 0x2e, 0xba, 0x22, 0xd1,
-+    0xeb, 0xb3, 0xa5, 0x27, 0x0b, 0xec, 0xf9, 0x26, 0x7e, 0x1f,
-+    0xe7, 0x17, 0x9f, 0x39, 0xa8, 0x72, 0x22, 0x63, 0x79, 0x6a,
-+    0x9c, 0x89, 0x55, 0x9a, 0xb4, 0x61, 0x41, 0xbc, 0xaa, 0x14,
-+    0x37, 0x29, 0x03, 0xc0, 0x52, 0x4e, 0x31, 0x44, 0x8f, 0x2e,
-+    0x17, 0x81, 0x88, 0xf4, 0xce, 0xda, 0x41, 0xb8, 0xd5, 0x14,
-+    0x91, 0x8c, 0xca, 0xd2, 0x0d, 0x99, 0x06, 0x09, 0xc2, 0xb7,
-+    0xe8, 0xae, 0xfa, 0x01, 0xea, 0x99, 0x62, 0x68, 0xb6, 0xdf,
-+    0xc8, 0x27, 0xae, 0xbf, 0xb0, 0x9b, 0x5b, 0x1a, 0xa2, 0xe2,
-+    0x5a, 0x7a, 0xe5, 0x4b, 0x92, 0x1f, 0xff, 0x73, 0xae, 0x16,
-+    0x40, 0x78, 0x42, 0x28, 0xbb, 0x13, 0x5e, 0xbc, 0x71, 0x7a,
-+    0x78, 0x3e, 0xd8, 0x1b, 0xc2, 0x2c, 0xd6, 0xdc, 0xfa, 0x39,
-+    0x72, 0xf8, 0xa2, 0x2c, 0x8b, 0x1c, 0x5d, 0xab, 0xb8, 0x07,
-+    0xc7, 0xae, 0x29, 0x93, 0x68, 0xbf, 0x61, 0xe9, 0xa4, 0x37,
-+    0x83, 0x7d, 0x13, 0xc7, 0x18, 0xf0, 0x7d, 0xa4, 0x20, 0x47,
-+    0x14, 0x68, 0x95, 0x46, 0x56, 0x6d, 0xd5, 0x7b, 0xe1, 0x51,
-+    0x8f, 0x96, 0xc1, 0x7b, 0x35, 0x09, 0x7a, 0x89, 0x0e, 0xdf,
-+    0x12, 0xd5, 0xe1, 0x9c, 0x2a, 0x94, 0x95, 0x43, 0x93, 0x48,
-+    0xa6, 0x23, 0xe6, 0xd8, 0xf2, 0xb8, 0x0e, 0xba, 0x6d, 0x61,
-+    0x03, 0xaf, 0x40, 0x63, 0x2b, 0x2f, 0xee, 0x61, 0x4c, 0xc4,
-+    0x70, 0x3d, 0x78, 0xc1, 0x4f, 0x8e, 0x0b, 0x9b, 0x06, 0x35,
-+    0x6d, 0x6d, 0x83, 0x37, 0xbb, 0x39, 0x7d, 0x7f, 0x33, 0x93,
-+    0xc4, 0xeb, 0x8e, 0xfc, 0xda, 0xf0, 0x54, 0xfe, 0x1d, 0xc4,
-+    0xd3, 0x83, 0x99, 0xdf, 0x65, 0xee, 0x00, 0x7d, 0x86, 0x27,
-+    0xd4, 0x3a, 0x6b, 0xe6, 0x82, 0x8e, 0x58, 0x2d, 0x03, 0x38,
-+    0xef, 0x6c, 0x82, 0x87, 0x18, 0x3b, 0x47, 0xe7, 0xbc, 0xe1,
-+    0x58, 0x70, 0x4d, 0x46, 0x96, 0x34, 0x60, 0x96, 0x15, 0x09,
-+    0x3c, 0x84, 0x40, 0xaf, 0x80, 0x32, 0x75, 0xc7, 0x23, 0x6c,
-+    0xfb, 0x1d, 0x57, 0x73, 0x19, 0x09, 0xe8, 0x1a, 0x4c, 0x02,
-+    0x5c, 0x7e, 0x4e, 0xbe, 0x75, 0xf8, 0x73, 0xff, 0x2d, 0x54,
-+    0x19, 0x55, 0xf5, 0xf4, 0x1b, 0xc9, 0xbc, 0xc2, 0x19, 0xcb,
-+    0xb7, 0x4e, 0x6a, 0x0d, 0xff, 0xca, 0x7d, 0xd0, 0x88, 0x91,
-+    0x8b, 0x9b, 0x21, 0xa4, 0xa2, 0x43, 0x0d, 0xbc, 0x9e, 0x73,
-+    0x7d, 0x54, 0x7d, 0x95, 0xcc, 0x63, 0x5e, 0xc1, 0xb8, 0xe6,
-+    0x27, 0xff, 0x20, 0x07, 0xe8, 0x6e, 0x7e, 0xf2, 0x0f, 0x5a,
-+    0x09, 0xef, 0xe5, 0x4d, 0x80, 0x39, 0x95, 0xd5, 0xf4, 0xee,
-+    0x3b, 0xca, 0x7c, 0x73, 0xf8, 0x39, 0x5a, 0xc1, 0x1d, 0x7d,
-+    0x94, 0x72, 0x32, 0xad, 0x58, 0xe2, 0xfc, 0x71, 0x6e, 0x66,
-+    0xaa, 0xa1, 0x59, 0xd6, 0xac, 0xab, 0xbe, 0x8c, 0x53, 0x99,
-+    0xcd, 0xe8, 0x2d, 0xb5, 0xb3, 0x46, 0x58, 0x2e, 0x16, 0xd7,
-+    0x4d, 0x8b, 0x7d, 0x4a, 0xb1, 0x4c, 0x85, 0x91, 0x1b, 0x57,
-+    0x54, 0xf8, 0x14, 0x59, 0xdb, 0xc4, 0x2c, 0x9c, 0x08, 0x6d,
-+    0x3d, 0xd7, 0xf6, 0xa6, 0xe6, 0xb3, 0x2a, 0xe7, 0x29, 0x1c,
-+    0xab, 0xb4, 0xed, 0x13, 0x19, 0xf8, 0xb6, 0x60, 0x92, 0x44,
-+    0x53, 0xd4, 0xa9, 0x7e, 0xba, 0x21, 0xa2, 0xdc, 0x6e, 0xa5,
-+    0x5e, 0x53, 0x59, 0x3c, 0x52, 0x61, 0x7b, 0x5f, 0x19, 0xad,
-+    0xc8, 0x6d, 0x68, 0x8d, 0x7a, 0xc9, 0xd6, 0xef, 0xeb, 0x67,
-+    0x4f, 0xca, 0xe7, 0xf6, 0x29, 0x36, 0x97, 0xfb, 0x3e, 0x37,
-+    0x95, 0x85, 0x71, 0x70, 0xf6, 0x63, 0x86, 0x2a, 0x29, 0xd7,
-+    0x9a, 0x96, 0x76, 0xa7, 0x47, 0x98, 0x4e, 0x06, 0x31, 0xaf,
-+    0xf3, 0x4f, 0x2a, 0x65, 0x90, 0x6a, 0x4b, 0x8e, 0x43, 0x79,
-+    0xe2, 0xdd, 0xce, 0x08, 0x1c, 0x01, 0xec, 0x38, 0x41, 0xdd,
-+    0x19, 0xd8, 0xf3, 0x36, 0x03, 0x35, 0x03, 0xaf, 0x1c, 0x45,
-+    0x3c, 0xac, 0x13, 0xaa, 0x36, 0x16, 0x48, 0x77, 0xb3, 0xbe,
-+    0xa3, 0xb3, 0x9d, 0x7f, 0x20, 0xca, 0x74, 0x65, 0xac, 0x93,
-+    0xa7, 0x54, 0xad, 0xc8, 0x68, 0x0e, 0xf8, 0x44, 0x1f, 0xad,
-+    0x2c, 0xb7, 0x9a, 0x9a, 0x07, 0xe5, 0xcd, 0x87, 0xe0, 0x14,
-+    0xb5, 0xaf, 0xd3, 0xd7, 0xcf, 0x13, 0x9f, 0x3b, 0xbd, 0xfe,
-+    0x29, 0x0b, 0x72, 0xf5, 0x4c, 0x54, 0x94, 0xc7, 0x66, 0xec,
-+    0xa8, 0x41, 0x96, 0x3d, 0x17, 0xed, 0x19, 0xc0, 0x82, 0x3e,
-+    0x5f, 0x9a, 0x91, 0xfe, 0xd1, 0x2f, 0xb8, 0x94, 0xaa, 0x58,
-+    0x68, 0x95, 0x31, 0x87, 0x57, 0x9a, 0x75, 0x94, 0x4d, 0x38,
-+    0x7d, 0x56, 0x82, 0x81, 0x9c, 0xb9, 0x34, 0x2b, 0xe7, 0x40,
-+    0xd9, 0x3c, 0x77, 0x5b, 0x95, 0x51, 0x06, 0x11, 0x41, 0xe3,
-+    0x8b, 0xb7, 0x32, 0xeb, 0xe1, 0x05, 0x1b, 0x10, 0xa8, 0x0e,
-+    0xa1, 0x02, 0x82, 0x01, 0xe1, 0x00, 0xfa, 0x38, 0x34, 0xfe,
-+    0x55, 0x87, 0x71, 0x62, 0x47, 0x00, 0x33, 0x64, 0x67, 0x70,
-+    0x79, 0x76, 0xdf, 0xfe, 0xc3, 0x28, 0x38, 0xdf, 0x90, 0xd4,
-+    0xc0, 0xee, 0x98, 0xbf, 0x9d, 0x9b, 0x85, 0xd8, 0x61, 0x65,
-+    0xa5, 0x70, 0xf5, 0xd2, 0x2c, 0xbf, 0x2f, 0xb5, 0x55, 0x79,
-+    0x92, 0x13, 0xba, 0x4d, 0x3c, 0x39, 0xbf, 0xd5, 0x31, 0x13,
-+    0x7a, 0x31, 0xf4, 0x8b, 0xce, 0xf8, 0xd0, 0xd3, 0x9b, 0xe2,
-+    0xee, 0x31, 0xdb, 0xba, 0xcc, 0x1a, 0xba, 0x1c, 0x8d, 0xee,
-+    0xea, 0xcb, 0xd3, 0x5a, 0xad, 0x87, 0xd6, 0xf9, 0x15, 0x2f,
-+    0x6e, 0x00, 0x06, 0x74, 0x25, 0x8d, 0xff, 0xc8, 0xa6, 0x11,
-+    0x1c, 0xe8, 0x16, 0x1a, 0xde, 0x53, 0x05, 0xb9, 0x53, 0x55,
-+    0x28, 0x83, 0x3d, 0xbe, 0x61, 0x0c, 0xc4, 0x98, 0x7d, 0xf6,
-+    0xec, 0x36, 0xc3, 0xe5, 0xe7, 0x1d, 0x14, 0x64, 0xcb, 0x0d,
-+    0x62, 0x5d, 0x7a, 0xcd, 0x88, 0xfc, 0x66, 0x4e, 0xf9, 0x36,
-+    0x47, 0x95, 0x18, 0x3a, 0x48, 0x2a, 0xff, 0x62, 0x8f, 0x6c,
-+    0xe2, 0xc2, 0xe9, 0xd3, 0x6a, 0x45, 0x5c, 0xf5, 0x89, 0x53,
-+    0x5c, 0xbe, 0xcf, 0xad, 0x87, 0x22, 0x9c, 0x31, 0x48, 0xdb,
-+    0xd8, 0xe4, 0xe5, 0x38, 0xae, 0xc2, 0xb0, 0xd2, 0xba, 0xb7,
-+    0x30, 0x53, 0x2d, 0xb1, 0x35, 0xf1, 0x58, 0x0f, 0x8a, 0x06,
-+    0x51, 0x76, 0xb9, 0x2c, 0x32, 0xe0, 0xd1, 0xaa, 0x82, 0x34,
-+    0x69, 0x71, 0x1c, 0x5f, 0x35, 0xa8, 0x9d, 0x11, 0xac, 0x13,
-+    0xdb, 0x7b, 0xf6, 0x93, 0xe3, 0xb9, 0xbd, 0xd9, 0xb2, 0x86,
-+    0xff, 0x61, 0x88, 0x2b, 0x72, 0x5c, 0x84, 0xe1, 0x0c, 0x72,
-+    0xab, 0x44, 0xff, 0x23, 0x13, 0xaf, 0xd1, 0x5a, 0xd3, 0xea,
-+    0x73, 0xfe, 0xd5, 0xa4, 0x7d, 0x9e, 0x4e, 0xac, 0x03, 0x93,
-+    0x72, 0x14, 0x2d, 0x96, 0x6f, 0xee, 0xb4, 0xcd, 0x4e, 0xab,
-+    0xea, 0x71, 0x93, 0x81, 0xe0, 0x3d, 0xcd, 0x61, 0x96, 0x25,
-+    0x76, 0xbd, 0xc4, 0xb5, 0xdd, 0x7c, 0xf1, 0xb9, 0xe1, 0x2c,
-+    0x58, 0x1b, 0xa4, 0x46, 0x4b, 0x12, 0x57, 0x58, 0xaa, 0x3a,
-+    0xae, 0x89, 0xa3, 0xb3, 0xcf, 0x1f, 0x8d, 0x67, 0xdf, 0x6d,
-+    0x7e, 0x8e, 0xfa, 0xc5, 0x09, 0x73, 0x46, 0x56, 0x55, 0x90,
-+    0xeb, 0x77, 0x4e, 0x16, 0x4f, 0x68, 0x7b, 0x1f, 0x61, 0x23,
-+    0xec, 0xa9, 0x71, 0x30, 0x33, 0x25, 0xc7, 0x4e, 0x26, 0x2e,
-+    0x4e, 0x2b, 0xc2, 0x64, 0x5f, 0xf5, 0x8f, 0x7a, 0x4b, 0x1c,
-+    0x06, 0xb3, 0x91, 0xf6, 0x9b, 0x51, 0xb7, 0xb0, 0x64, 0x72,
-+    0x04, 0xe5, 0xfa, 0x14, 0x2f, 0xed, 0x61, 0x29, 0x03, 0x73,
-+    0x19, 0x15, 0x6e, 0x2c, 0x8b, 0x0e, 0xec, 0x4d, 0xf1, 0xe3,
-+    0x6f, 0x58, 0x7c, 0xc9, 0x48, 0x67, 0x3f, 0x51, 0xb5, 0xb7,
-+    0x26, 0x46, 0xa7, 0x25, 0x79, 0x55, 0xfe, 0x3a, 0x44, 0xb4,
-+    0x44, 0xfc, 0xb8, 0x14, 0x34, 0x47, 0xd7, 0xa3, 0x0e, 0x76,
-+    0xe7, 0x83, 0x9a, 0x02, 0xc3, 0xcf, 0x2b, 0xd9, 0x83, 0x93,
-+    0xd5, 0xee, 0x99, 0x74, 0x45, 0x62, 0x23, 0xa6, 0x02, 0xc9,
-+    0xc0, 0x10, 0x70, 0x0a, 0x99, 0x29, 0x0c, 0x79, 0x04, 0x4c,
-+    0x77, 0x21, 0x96, 0xf0, 0xa5, 0x17, 0x22, 0xbe, 0xab, 0x9b,
-+    0xd7, 0x42, 0xd3, 0xe9, 0xc0, 0x42, 0x44, 0x7d, 0x9d, 0xc9,
-+    0x3d, 0xf9, 0x36, 0x97, 0x1b, 0x75, 0x52, 0x8f, 0xe9, 0xb9,
-+    0x8c, 0xa7, 0x64, 0x19, 0x5b, 0x5d, 0x60, 0xb4, 0x42, 0x95,
-+    0xc9, 0xdb, 0x82, 0x03, 0xc6, 0xb0, 0x28, 0x72, 0x64, 0x03,
-+    0x41, 0x4d, 0x8f, 0xc6, 0xd0, 0xcd, 0x02, 0x82, 0x01, 0xe1,
-+    0x00, 0xe8, 0x66, 0xa7, 0xf9, 0x0f, 0x5a, 0x21, 0xfc, 0x88,
-+    0x4e, 0x91, 0xd5, 0x4a, 0xf0, 0xf4, 0x32, 0xe5, 0x0d, 0xf3,
-+    0x06, 0x95, 0xd0, 0x4e, 0x47, 0x0c, 0x04, 0x66, 0x77, 0xfd,
-+    0xb8, 0x93, 0x0d, 0xff, 0x8f, 0x97, 0xa0, 0x4a, 0x36, 0x37,
-+    0xa6, 0x5e, 0x95, 0x79, 0xc8, 0xb2, 0x21, 0x98, 0x81, 0xf1,
-+    0xb8, 0xf4, 0x52, 0xaf, 0x3c, 0x8c, 0x86, 0x85, 0x55, 0x56,
-+    0xfc, 0x90, 0xe3, 0x32, 0x50, 0x7c, 0x54, 0x07, 0x9e, 0xed,
-+    0xfc, 0xd4, 0xb9, 0x5c, 0x98, 0x22, 0xfb, 0x72, 0xd7, 0x83,
-+    0xf0, 0xd1, 0x61, 0x10, 0xbd, 0x68, 0x5d, 0x72, 0xc1, 0xce,
-+    0x92, 0x43, 0x77, 0x9f, 0xb8, 0x8d, 0x8e, 0xf2, 0xe3, 0x62,
-+    0x4a, 0x93, 0x03, 0xd3, 0xd9, 0x01, 0xa8, 0x99, 0x6f, 0xa3,
-+    0x4c, 0x6d, 0x7a, 0xf2, 0x9e, 0x8e, 0x6b, 0xbc, 0xe4, 0x9d,
-+    0x8e, 0xe7, 0x25, 0x86, 0xa4, 0xa9, 0xc2, 0xef, 0xdf, 0xbb,
-+    0x6e, 0x3d, 0x4b, 0x57, 0x95, 0x81, 0x6f, 0x68, 0x3f, 0x19,
-+    0xa8, 0xff, 0x5a, 0x08, 0x7a, 0xe4, 0x4c, 0x4e, 0xb4, 0xea,
-+    0xf4, 0xc8, 0x2f, 0xef, 0x8c, 0x5e, 0xcd, 0x62, 0x1c, 0x8c,
-+    0x93, 0x60, 0x5d, 0xa3, 0x11, 0x64, 0x0b, 0xeb, 0x6d, 0x21,
-+    0xbc, 0x3a, 0x5b, 0x5c, 0x0c, 0xa7, 0x8a, 0xc6, 0xa8, 0xe1,
-+    0x48, 0x81, 0x01, 0xb5, 0x65, 0xab, 0x2e, 0xbe, 0x38, 0x94,
-+    0xf7, 0xa6, 0x33, 0xc1, 0x6e, 0x0b, 0x88, 0x38, 0xe7, 0x1b,
-+    0x04, 0x9a, 0x10, 0x2d, 0x1d, 0x3f, 0x5f, 0x5f, 0xc8, 0xef,
-+    0xcd, 0xc5, 0x16, 0xdc, 0x84, 0xc0, 0x66, 0xe0, 0xa3, 0xfc,
-+    0xfa, 0x96, 0xc7, 0xb7, 0xec, 0x4f, 0x40, 0x0a, 0xc5, 0xbe,
-+    0x6d, 0x39, 0x4a, 0x7e, 0x91, 0x4f, 0xe1, 0x03, 0xd2, 0x39,
-+    0xbc, 0x87, 0x69, 0xa1, 0xf0, 0x6d, 0x11, 0xf5, 0xb4, 0x9d,
-+    0xae, 0x76, 0x6b, 0xc6, 0xbf, 0xe4, 0x47, 0xbc, 0x4d, 0x13,
-+    0x88, 0xa8, 0x83, 0xf5, 0xae, 0x1d, 0xfb, 0x4d, 0x4c, 0x44,
-+    0x03, 0xd8, 0xa4, 0x2e, 0x4d, 0xf8, 0x5f, 0x45, 0x94, 0x58,
-+    0xd7, 0xd9, 0x4b, 0x47, 0xd8, 0xfc, 0x35, 0x05, 0xed, 0xb4,
-+    0xb6, 0xc2, 0x36, 0x2e, 0xba, 0xd2, 0x7a, 0xba, 0x69, 0x34,
-+    0xbf, 0xf1, 0xa1, 0x5e, 0x17, 0x71, 0x89, 0xd3, 0x54, 0x57,
-+    0x05, 0x2b, 0x82, 0xe3, 0x0a, 0x64, 0x5c, 0x3b, 0x8c, 0x6b,
-+    0xc7, 0x10, 0x8a, 0xb5, 0xd3, 0xd7, 0x90, 0xeb, 0xdb, 0x1d,
-+    0xa0, 0xbf, 0x6b, 0xea, 0xcd, 0x31, 0x7a, 0x8d, 0x64, 0xcc,
-+    0x58, 0xc0, 0x07, 0xa4, 0x6e, 0x14, 0x0b, 0xf3, 0xea, 0x3e,
-+    0x87, 0x9f, 0x7c, 0xb8, 0x1c, 0x22, 0x26, 0x8a, 0x7d, 0x90,
-+    0xdd, 0x57, 0x28, 0x38, 0xcc, 0x0e, 0x71, 0x92, 0x89, 0xee,
-+    0x79, 0x88, 0xbc, 0x05, 0x21, 0xda, 0x42, 0x92, 0x52, 0x66,
-+    0xac, 0x4a, 0xe5, 0xf5, 0x6e, 0x47, 0xd5, 0xba, 0x37, 0xd3,
-+    0x7c, 0x89, 0xd4, 0xd8, 0x6f, 0xde, 0x63, 0x44, 0xb5, 0x88,
-+    0xdd, 0xb1, 0x30, 0xb4, 0x6d, 0xcd, 0xbf, 0xc8, 0x34, 0x27,
-+    0x59, 0x7d, 0x79, 0xdc, 0x96, 0x5b, 0x8e, 0xc0, 0x87, 0xc0,
-+    0x4e, 0x40, 0x07, 0x13, 0x91, 0x6b, 0x3a, 0x12, 0x03, 0x64,
-+    0x70, 0xaf, 0x80, 0x24, 0x1c, 0x5c, 0xfb, 0xf5, 0xc0, 0x74,
-+    0x5e, 0xaf, 0x06, 0x18, 0x04, 0x67, 0x4a, 0xbd, 0xac, 0xd7,
-+    0xca, 0xbe, 0x4e, 0xa1, 0x19, 0x48, 0x7d, 0xa6, 0x59, 0xf6,
-+    0x1a, 0x62, 0x50, 0x53, 0x46, 0xa4, 0x5b, 0x9c, 0x5a, 0xfd,
-+    0x89, 0x9d, 0xd4, 0xde, 0xf4, 0xa7, 0x3d, 0x88, 0x73, 0xa5,
-+    0xb9, 0x02, 0x82, 0x01, 0xe1, 0x00, 0xe7, 0x70, 0x59, 0xc3,
-+    0xed, 0xc4, 0x6b, 0xa1, 0xa5, 0x5e, 0x90, 0x2a, 0x8c, 0x6a,
-+    0xc2, 0x4e, 0xab, 0xfc, 0xee, 0xf2, 0x23, 0x38, 0xd6, 0xb3,
-+    0x93, 0x08, 0x9e, 0x0c, 0x8e, 0x71, 0x2d, 0xa9, 0xe8, 0xdc,
-+    0xa5, 0xdc, 0x07, 0xe3, 0xb1, 0x33, 0xdd, 0xa2, 0xf2, 0x3e,
-+    0x92, 0x58, 0xe0, 0xf7, 0x53, 0x7f, 0x6e, 0xea, 0x78, 0x8c,
-+    0x35, 0x78, 0x43, 0x63, 0x95, 0xbb, 0x1b, 0x1c, 0xbf, 0x91,
-+    0x75, 0x14, 0x74, 0xd3, 0x20, 0xba, 0x8f, 0xee, 0x9d, 0x71,
-+    0xa1, 0x87, 0x8a, 0x24, 0xd3, 0x61, 0x53, 0xfb, 0xec, 0x16,
-+    0x84, 0xbe, 0x4d, 0x39, 0xdd, 0x0a, 0xac, 0xce, 0x20, 0x9c,
-+    0xaf, 0x8a, 0x13, 0xf8, 0x22, 0x2f, 0xd4, 0x99, 0x88, 0x74,
-+    0xba, 0x16, 0x3a, 0x63, 0xff, 0x4c, 0x5a, 0x03, 0x5a, 0x6f,
-+    0xac, 0x29, 0x33, 0xa5, 0x50, 0xd1, 0xda, 0xed, 0x27, 0xcb,
-+    0x67, 0x72, 0x63, 0x85, 0xfc, 0xf0, 0xc8, 0x88, 0xbf, 0x85,
-+    0xef, 0x4b, 0xfe, 0xae, 0xd9, 0xd5, 0xbb, 0x86, 0xa4, 0x76,
-+    0xe8, 0x7f, 0xb4, 0xdb, 0xb1, 0xee, 0x1a, 0x7f, 0x99, 0xd7,
-+    0x9b, 0x6f, 0x7a, 0x94, 0x5c, 0xec, 0x2c, 0x60, 0x81, 0xad,
-+    0xa7, 0xbe, 0x80, 0x2e, 0x9f, 0xa6, 0xc0, 0xfb, 0x09, 0x6d,
-+    0x2b, 0xab, 0xa4, 0x15, 0xc7, 0x79, 0x46, 0x24, 0x89, 0x5c,
-+    0x32, 0xb9, 0x87, 0xa9, 0x54, 0x1e, 0x12, 0x90, 0x8e, 0x02,
-+    0x80, 0x8c, 0xf8, 0xdb, 0x2f, 0xbc, 0x98, 0x1b, 0xa2, 0x78,
-+    0x73, 0x89, 0x03, 0x97, 0xe3, 0x09, 0x08, 0x8b, 0x75, 0xcf,
-+    0xdc, 0x23, 0x90, 0x59, 0xef, 0x5b, 0x98, 0x24, 0xb8, 0xe8,
-+    0xcf, 0x75, 0xf0, 0x2f, 0xb7, 0xa3, 0xe6, 0x17, 0x06, 0xf0,
-+    0x52, 0xfe, 0x21, 0x0a, 0x16, 0x8e, 0xf8, 0xe1, 0xae, 0x25,
-+    0x11, 0x5d, 0x8c, 0x95, 0x1b, 0x4f, 0x45, 0xb8, 0xa8, 0xcd,
-+    0xe6, 0xf9, 0xca, 0xa0, 0x54, 0x93, 0x95, 0x86, 0x6f, 0xe4,
-+    0x93, 0x22, 0x0f, 0xf2, 0xcf, 0xbd, 0x23, 0xb0, 0xf4, 0x8f,
-+    0x99, 0xa7, 0x67, 0x99, 0x05, 0x13, 0x1f, 0xeb, 0x88, 0xf8,
-+    0xe2, 0x3b, 0xb9, 0x49, 0x35, 0x89, 0x4f, 0xb8, 0x06, 0x37,
-+    0x36, 0xda, 0x75, 0x25, 0x0f, 0x0a, 0xaa, 0xc2, 0x6c, 0x3e,
-+    0xb1, 0x2d, 0x16, 0xf3, 0x17, 0xdb, 0xe2, 0x16, 0x32, 0x39,
-+    0x92, 0x4b, 0x5f, 0xc0, 0x5f, 0x6e, 0xd0, 0x1c, 0x7e, 0xc0,
-+    0x51, 0xd9, 0xb3, 0xe2, 0x37, 0xc7, 0xe0, 0x40, 0x13, 0x7d,
-+    0x06, 0xcd, 0xcd, 0x72, 0xb6, 0x53, 0x2d, 0x7e, 0x60, 0x49,
-+    0xfe, 0x31, 0xe1, 0xd0, 0x0e, 0x4c, 0x98, 0x93, 0xe0, 0xf6,
-+    0xf2, 0xfa, 0x99, 0x7f, 0x65, 0xd8, 0x15, 0xc6, 0x3a, 0xb8,
-+    0x4d, 0x63, 0x21, 0x78, 0xe4, 0x19, 0x6b, 0xbd, 0xde, 0x40,
-+    0x5b, 0x8c, 0xfa, 0x49, 0x75, 0x23, 0x8f, 0x14, 0xc2, 0x3b,
-+    0xa3, 0x9b, 0xc5, 0x80, 0x1a, 0xa3, 0x60, 0xd7, 0x17, 0x27,
-+    0xf0, 0x18, 0x0f, 0xba, 0x02, 0xf7, 0x7a, 0xed, 0xa4, 0x00,
-+    0x77, 0xde, 0x4b, 0xdd, 0xf9, 0xd7, 0x3e, 0x75, 0xed, 0x1a,
-+    0x43, 0x26, 0x71, 0x1b, 0xbc, 0x72, 0xf5, 0x70, 0x72, 0x03,
-+    0x70, 0x25, 0x87, 0x81, 0x6a, 0x92, 0x2d, 0xb7, 0x02, 0xf0,
-+    0x10, 0x79, 0x65, 0x9d, 0x4e, 0x11, 0x7d, 0x5c, 0x5b, 0x37,
-+    0xaa, 0xb4, 0xfa, 0x43, 0x66, 0x48, 0x6c, 0x67, 0x64, 0x9e,
-+    0x15, 0x75, 0x36, 0xe7, 0x25, 0x55, 0x07, 0x7f, 0x74, 0x1f,
-+    0x2c, 0x28, 0x76, 0xe7, 0x9b, 0x3d, 0x91, 0x0b, 0xcd, 0x6a,
-+    0x1d, 0x5a, 0xea, 0x63, 0xd0, 0xf9, 0x02, 0x82, 0x01, 0xe0,
-+    0x3e, 0x31, 0xf2, 0xf4, 0x29, 0x92, 0xa2, 0x93, 0xd5, 0xda,
-+    0xc9, 0x16, 0x7e, 0xf6, 0xdb, 0x33, 0x9f, 0xaf, 0x4b, 0x01,
-+    0xd1, 0x28, 0x2d, 0x3a, 0xc0, 0x51, 0x91, 0x26, 0xbd, 0xa5,
-+    0x1e, 0xdd, 0xd9, 0x2e, 0x11, 0x93, 0x19, 0x29, 0x47, 0x5d,
-+    0x63, 0xe4, 0xb6, 0xf1, 0xea, 0x12, 0x29, 0xa1, 0x65, 0x12,
-+    0x6d, 0x78, 0x8f, 0x63, 0x31, 0xec, 0x72, 0x54, 0x73, 0x72,
-+    0x26, 0x48, 0x57, 0x57, 0xc8, 0xde, 0x28, 0x27, 0xf5, 0x62,
-+    0xfb, 0x7f, 0x1b, 0xf3, 0xaf, 0x31, 0x01, 0xfc, 0x01, 0x58,
-+    0x7a, 0x80, 0x72, 0x9d, 0x6e, 0x07, 0xcc, 0x45, 0x67, 0xc6,
-+    0x26, 0xfe, 0x25, 0xa5, 0x9b, 0x64, 0xcd, 0x45, 0xe3, 0x31,
-+    0x38, 0x05, 0x07, 0x36, 0x05, 0x46, 0x9c, 0xc1, 0x8e, 0xbf,
-+    0x4e, 0x71, 0x5f, 0xea, 0xe5, 0x0c, 0x9a, 0x41, 0xc8, 0x94,
-+    0xcc, 0xf1, 0x73, 0x06, 0x30, 0x54, 0x76, 0x23, 0xb7, 0x22,
-+    0x7a, 0x8e, 0xe6, 0x42, 0xa1, 0xa0, 0x32, 0x12, 0xe9, 0x08,
-+    0x1c, 0x46, 0x79, 0x0c, 0x82, 0x7a, 0x95, 0x79, 0xbf, 0x83,
-+    0x80, 0xeb, 0xab, 0x3d, 0x32, 0xc5, 0xde, 0x62, 0xeb, 0x90,
-+    0x29, 0x73, 0x05, 0xc8, 0x0a, 0xb1, 0x51, 0xf1, 0x23, 0xdd,
-+    0x1e, 0xf5, 0x02, 0x3e, 0x74, 0xbc, 0x24, 0x0c, 0x60, 0x36,
-+    0x2a, 0x28, 0x4d, 0xe6, 0x86, 0x98, 0x7c, 0xd9, 0xe1, 0xac,
-+    0x21, 0x33, 0xaa, 0xa9, 0x8b, 0xb6, 0x8a, 0x1b, 0xf7, 0x54,
-+    0x14, 0xf3, 0x0d, 0x4f, 0xcd, 0x7c, 0xf5, 0xc2, 0x6d, 0xc2,
-+    0xf0, 0xe2, 0xfc, 0x63, 0x1e, 0xa6, 0xa9, 0xa9, 0xd9, 0x73,
-+    0x2a, 0xd5, 0x0a, 0x38, 0xd8, 0xc0, 0xb7, 0xe1, 0x51, 0xe4,
-+    0x23, 0x37, 0xf7, 0x85, 0x66, 0x0e, 0x3f, 0x1a, 0x8c, 0xcf,
-+    0x12, 0xa2, 0x47, 0x6f, 0x73, 0x91, 0x21, 0xe3, 0x93, 0x6b,
-+    0x74, 0x4f, 0xc5, 0xa1, 0xe7, 0x32, 0xf7, 0x86, 0xdd, 0x1a,
-+    0x6e, 0x96, 0xda, 0x32, 0x1d, 0xdd, 0xfa, 0x42, 0xd5, 0xd4,
-+    0xfd, 0xae, 0x7a, 0xa1, 0xed, 0x3d, 0x79, 0xfe, 0x88, 0x84,
-+    0x43, 0xa7, 0xec, 0xf3, 0x7a, 0x13, 0xaa, 0xa1, 0x82, 0x02,
-+    0x83, 0x19, 0x43, 0x0a, 0x46, 0x78, 0x07, 0xd9, 0x4d, 0xff,
-+    0xac, 0x67, 0xd6, 0x29, 0x89, 0xfe, 0x2b, 0xab, 0x5f, 0x9a,
-+    0x87, 0x99, 0x80, 0xaf, 0x70, 0x4a, 0x6a, 0xb9, 0x5a, 0xc2,
-+    0xac, 0x7f, 0xa2, 0xc7, 0xad, 0xe2, 0x1f, 0xec, 0xc5, 0x12,
-+    0x17, 0x08, 0x87, 0x8f, 0x20, 0x95, 0xbe, 0xaf, 0x62, 0x2c,
-+    0xc2, 0x3f, 0x89, 0x56, 0xd8, 0x50, 0x96, 0x97, 0x72, 0xe2,
-+    0x92, 0xe1, 0x2a, 0xd8, 0x84, 0x9f, 0x31, 0xe3, 0x06, 0xd8,
-+    0xe5, 0x91, 0x63, 0x19, 0xe1, 0x27, 0xad, 0xe2, 0xf2, 0x0a,
-+    0x5e, 0x78, 0x8b, 0x1b, 0x13, 0x31, 0x4b, 0xbd, 0x77, 0xb2,
-+    0xd6, 0x5c, 0x92, 0x81, 0x50, 0x02, 0x37, 0xd2, 0xe6, 0xeb,
-+    0x66, 0x6b, 0xaa, 0xfc, 0xcd, 0x54, 0x5d, 0xb8, 0x03, 0x87,
-+    0xe8, 0xfa, 0xb2, 0xde, 0xcb, 0xf8, 0x6e, 0x58, 0xde, 0xcb,
-+    0x09, 0x54, 0x8a, 0x9f, 0x46, 0xa3, 0x7e, 0x8d, 0x15, 0xff,
-+    0x1b, 0x0d, 0x89, 0xc4, 0x1a, 0x21, 0x31, 0x5e, 0xed, 0x0b,
-+    0x67, 0x3c, 0x70, 0xed, 0x92, 0x48, 0xef, 0xec, 0xf0, 0x77,
-+    0xc2, 0x79, 0x6c, 0x06, 0x09, 0xaa, 0xab, 0xf6, 0x4c, 0xcd,
-+    0xfa, 0x7e, 0x4a, 0x88, 0xdc, 0xa8, 0x9b, 0xd3, 0x69, 0x94,
-+    0x88, 0x09, 0x1d, 0x30, 0x43, 0x9e, 0x2c, 0xcb, 0x01, 0x1d,
-+    0x4a, 0x3b, 0x04, 0xec, 0x0e, 0xb1, 0xde, 0x09, 0xad, 0x29,
-+    0x02, 0x82, 0x01, 0xe1, 0x00, 0x9f, 0x02, 0x13, 0x7a, 0xd0,
-+    0xa9, 0x8a, 0x7a, 0xa0, 0x05, 0xbb, 0x44, 0x6f, 0xaf, 0xf7,
-+    0xe3, 0xd4, 0x35, 0xef, 0x73, 0x39, 0xd5, 0xe0, 0xa2, 0x0f,
-+    0x1a, 0x25, 0xa8, 0xf7, 0xc2, 0xa5, 0xec, 0x57, 0xf8, 0x0d,
-+    0x2a, 0xb6, 0x64, 0x03, 0x8c, 0x22, 0x0f, 0xe7, 0x98, 0xa1,
-+    0x12, 0xfe, 0x24, 0xef, 0x61, 0x28, 0x9f, 0xa7, 0x22, 0x6b,
-+    0x6d, 0xab, 0x8d, 0x7d, 0x2a, 0x8b, 0xae, 0x8b, 0xfd, 0xcb,
-+    0xd5, 0x0b, 0x79, 0x1b, 0x89, 0xcb, 0x5b, 0x7a, 0x8c, 0xdc,
-+    0xe8, 0x8d, 0xdd, 0x35, 0x9f, 0x06, 0x69, 0x64, 0x12, 0xeb,
-+    0x46, 0x79, 0xdf, 0x82, 0x2c, 0x89, 0x75, 0x9e, 0x7a, 0xec,
-+    0xad, 0xe5, 0x88, 0x31, 0xfa, 0x86, 0x93, 0xca, 0xf1, 0x2d,
-+    0x9b, 0x62, 0x5a, 0xe9, 0x43, 0x09, 0xf3, 0x8c, 0xe5, 0xc7,
-+    0xc0, 0xce, 0x86, 0xe7, 0xdb, 0xc7, 0x4d, 0x27, 0xd5, 0xee,
-+    0x76, 0xce, 0x35, 0x30, 0x47, 0xef, 0x00, 0x1b, 0x69, 0x9a,
-+    0x3f, 0xa5, 0x2a, 0xc9, 0x07, 0xab, 0x99, 0xba, 0x2a, 0xe7,
-+    0xfb, 0xa9, 0x4e, 0xb9, 0xae, 0x2c, 0x50, 0xfc, 0x35, 0x49,
-+    0xe6, 0x97, 0x78, 0x3c, 0xb1, 0x59, 0xd7, 0x1d, 0x4e, 0x4e,
-+    0xea, 0xde, 0xa0, 0xd0, 0xc4, 0x1d, 0xb1, 0xd3, 0x53, 0x1e,
-+    0xf9, 0xbf, 0xb3, 0x6a, 0x17, 0xb4, 0xda, 0xcc, 0x27, 0x19,
-+    0xc6, 0x35, 0xe8, 0x28, 0xd3, 0xe3, 0x76, 0x3a, 0xdc, 0xd0,
-+    0x75, 0xc8, 0xb4, 0x6c, 0xbe, 0x84, 0x2a, 0x45, 0xd1, 0x43,
-+    0x22, 0x54, 0xd7, 0xc5, 0xd0, 0xd7, 0x73, 0x35, 0x6b, 0xa8,
-+    0xfa, 0xad, 0x60, 0xc0, 0x64, 0xc1, 0x58, 0x89, 0x09, 0x81,
-+    0x0a, 0x0b, 0xea, 0x33, 0x91, 0xb0, 0xef, 0x53, 0x50, 0x41,
-+    0xae, 0xd9, 0xee, 0xbe, 0x9e, 0xf0, 0x0b, 0xa0, 0x7c, 0xbf,
-+    0x3f, 0xc9, 0x4b, 0xe0, 0x48, 0xd8, 0x10, 0xd5, 0x2e, 0xce,
-+    0xf0, 0x7c, 0xd8, 0x05, 0xde, 0x09, 0x7e, 0x8c, 0x63, 0x4c,
-+    0xdb, 0x8b, 0x91, 0xcd, 0x7f, 0xb6, 0x6b, 0xad, 0xce, 0xb1,
-+    0x17, 0x6c, 0xf7, 0x08, 0x0d, 0x7c, 0xda, 0x4f, 0x0a, 0x07,
-+    0xd0, 0xae, 0x72, 0x3c, 0x67, 0x4a, 0x44, 0x54, 0x47, 0xce,
-+    0xe1, 0x17, 0x07, 0x12, 0xde, 0x52, 0xef, 0xef, 0x4c, 0x2b,
-+    0x42, 0x7d, 0x09, 0x80, 0x36, 0x34, 0xdc, 0x45, 0x6f, 0xb0,
-+    0x2d, 0xab, 0xa0, 0x0c, 0x58, 0xae, 0x35, 0xd3, 0x9b, 0x37,
-+    0xc1, 0x1d, 0xeb, 0xfe, 0xc3, 0x04, 0xc9, 0x1d, 0xe7, 0x3d,
-+    0x16, 0x64, 0xed, 0xf5, 0xe8, 0xdf, 0x99, 0xa4, 0xfb, 0xad,
-+    0x79, 0x88, 0xd5, 0x8c, 0x62, 0x33, 0x9e, 0x35, 0xa6, 0x7f,
-+    0x9d, 0xb6, 0x1a, 0x40, 0x6d, 0xc3, 0x89, 0x5d, 0x7b, 0xe2,
-+    0xc8, 0xd3, 0x16, 0x13, 0x07, 0x9a, 0x38, 0x22, 0x33, 0x03,
-+    0xac, 0x70, 0x3e, 0xce, 0x32, 0x56, 0x0b, 0x58, 0x56, 0xb8,
-+    0xe9, 0xd8, 0x42, 0x35, 0x6c, 0xb9, 0x02, 0xb3, 0x64, 0xeb,
-+    0xaa, 0x09, 0x3f, 0xac, 0x66, 0x08, 0xb4, 0x5f, 0x3e, 0xb4,
-+    0xec, 0x39, 0xb1, 0x99, 0xe4, 0x5d, 0x1d, 0x32, 0x14, 0xc1,
-+    0x48, 0x8f, 0x6c, 0x65, 0x87, 0x34, 0x50, 0xa4, 0xf4, 0x9b,
-+    0x5b, 0x2e, 0xb5, 0x79, 0x0d, 0x11, 0x62, 0xa4, 0x35, 0x9c,
-+    0x6f, 0x92, 0xd0, 0x68, 0x07, 0xdd, 0x69, 0x85, 0x48, 0xe3,
-+    0x5d, 0x10, 0x34, 0xaf, 0xea, 0x41, 0x72, 0x5a, 0x71, 0x00,
-+    0xf8, 0xe6, 0x47, 0x7f, 0xa0, 0x6f, 0x91, 0x96, 0x40, 0x00,
-+    0x40, 0x70, 0xfb, 0x63, 0xcf, 0xc9, 0x36, 0x04, 0x1c, 0x3b,
-+    0x11, 0x08, 0x29, 0x81, 0x9f
-+};
-+
-+static unsigned char test15360[] = {
-+    0x30, 0x82, 0x21, 0xe8, 0x02, 0x01, 0x00, 0x02, 0x82, 0x07,
-+    0x81, 0x00, 0xad, 0x3f, 0xaa, 0xdc, 0x8c, 0x85, 0xcb, 0x60,
-+    0xd2, 0xf5, 0x30, 0xa1, 0x0f, 0x26, 0xec, 0xdf, 0xfc, 0x91,
-+    0x39, 0xbd, 0x3e, 0x8f, 0x99, 0x64, 0x1e, 0x51, 0xd2, 0x27,
-+    0x5e, 0x76, 0xcd, 0x86, 0x33, 0x07, 0xf9, 0xbd, 0x3b, 0x06,
-+    0xc3, 0x3c, 0x85, 0xcb, 0x7e, 0x91, 0x14, 0xb0, 0x0b, 0x77,
-+    0x22, 0x30, 0x71, 0xb8, 0xbb, 0x74, 0x30, 0x33, 0x35, 0x56,
-+    0x34, 0x47, 0x10, 0x8f, 0x88, 0xe2, 0x6f, 0xdc, 0x3b, 0xe9,
-+    0x58, 0x9d, 0x0c, 0xdc, 0x8f, 0x70, 0x41, 0x7a, 0x12, 0xd2,
-+    0x9a, 0x35, 0xbe, 0x0a, 0x57, 0x13, 0x0c, 0xe9, 0xbf, 0x77,
-+    0x54, 0x00, 0x74, 0xb7, 0x1a, 0x3e, 0xa7, 0xe9, 0xb6, 0xe7,
-+    0x4f, 0x1e, 0xa4, 0xc0, 0x7c, 0x4c, 0x66, 0xc5, 0xce, 0xad,
-+    0x96, 0x1b, 0xe2, 0x1a, 0xf1, 0x3d, 0x8b, 0x50, 0xcf, 0xe2,
-+    0x15, 0x21, 0x6d, 0x83, 0x95, 0x00, 0xee, 0x97, 0xc4, 0xae,
-+    0xc9, 0x38, 0x62, 0x6c, 0xb2, 0xe7, 0x7f, 0x15, 0x0a, 0xab,
-+    0x86, 0xb9, 0xd9, 0x8a, 0xf8, 0xeb, 0x88, 0x5d, 0xdc, 0x0c,
-+    0x1e, 0xc5, 0xe6, 0xa1, 0x7b, 0xbf, 0xf1, 0x02, 0xe3, 0xad,
-+    0xf8, 0xed, 0x17, 0x9f, 0x83, 0x11, 0x31, 0x3b, 0xad, 0xb4,
-+    0xf9, 0x8d, 0x1d, 0x56, 0x9b, 0xac, 0x68, 0x55, 0x0a, 0x74,
-+    0x20, 0xee, 0x57, 0xe7, 0x1c, 0x6d, 0x05, 0xa1, 0x4e, 0xa5,
-+    0x11, 0x99, 0xb4, 0x86, 0xdb, 0x58, 0xe7, 0xf6, 0xb6, 0x4f,
-+    0x92, 0x58, 0x57, 0x9b, 0x74, 0x04, 0xe5, 0xd1, 0x1d, 0x7c,
-+    0x4b, 0xb8, 0x1f, 0x5d, 0x0e, 0x93, 0xee, 0x44, 0x18, 0xb6,
-+    0x58, 0x0e, 0xa1, 0x0b, 0x8e, 0x2e, 0x99, 0x4c, 0x72, 0x91,
-+    0xfa, 0xfa, 0xe2, 0x22, 0x05, 0x5d, 0x2b, 0x2d, 0xd8, 0x60,
-+    0xd5, 0x1b, 0x08, 0x56, 0x2b, 0xb5, 0x21, 0xdb, 0x1a, 0xe6,
-+    0xa8, 0x39, 0xa2, 0xf4, 0x58, 0xcb, 0xd2, 0xf9, 0xce, 0xc0,
-+    0x1e, 0x1b, 0xf9, 0xa7, 0x37, 0xca, 0xa3, 0x77, 0x6e, 0xb1,
-+    0xaf, 0x33, 0xb5, 0x6d, 0x5f, 0x33, 0x2e, 0x1a, 0x34, 0xdb,
-+    0x42, 0xbe, 0x5f, 0xf9, 0x09, 0xb7, 0x9f, 0xd4, 0x09, 0xfb,
-+    0x87, 0x13, 0x3c, 0xe2, 0x27, 0xb8, 0xf3, 0x1d, 0x7e, 0x92,
-+    0xdd, 0x87, 0x86, 0x55, 0x69, 0x9b, 0x55, 0xcd, 0xef, 0x7a,
-+    0x71, 0x5d, 0x81, 0x3a, 0xd9, 0xf7, 0x7f, 0xde, 0xe0, 0x92,
-+    0xd9, 0x78, 0x0f, 0x1d, 0x43, 0xb1, 0x1e, 0x29, 0xc1, 0x49,
-+    0xb6, 0x5e, 0x85, 0x83, 0xd9, 0x04, 0xfd, 0x79, 0xd8, 0x47,
-+    0x03, 0x2e, 0x85, 0x19, 0xfd, 0x63, 0xe7, 0xa4, 0x8b, 0xc0,
-+    0x94, 0x0e, 0xb7, 0x54, 0x97, 0xd6, 0x44, 0x5d, 0x63, 0x12,
-+    0xff, 0xdd, 0xde, 0x2c, 0x00, 0x0e, 0xc9, 0xca, 0x7e, 0xa2,
-+    0x65, 0x25, 0xb0, 0x1d, 0xa9, 0x20, 0x4f, 0xdd, 0xea, 0x3a,
-+    0xb5, 0xe8, 0x0f, 0xf3, 0xb2, 0xb7, 0x00, 0x4a, 0xe8, 0xa4,
-+    0x83, 0x49, 0xbd, 0x78, 0xdf, 0xac, 0x2c, 0x37, 0x81, 0xb3,
-+    0xf3, 0xb7, 0x13, 0x93, 0x3e, 0xb2, 0x79, 0x55, 0xf2, 0xd8,
-+    0x9c, 0xf7, 0xf2, 0xf1, 0xd5, 0x6c, 0x9c, 0xff, 0xec, 0xf4,
-+    0xea, 0x08, 0x3c, 0x65, 0x35, 0xb7, 0x09, 0x03, 0x6d, 0x99,
-+    0x1d, 0x5b, 0x73, 0x06, 0x61, 0xb4, 0xf0, 0xc5, 0xdb, 0x3e,
-+    0xe0, 0x1d, 0xa8, 0x5b, 0x7a, 0x5b, 0x5b, 0x9c, 0x11, 0x75,
-+    0x83, 0x1d, 0xf4, 0x73, 0x27, 0xf3, 0x79, 0xf2, 0x82, 0xd6,
-+    0x28, 0x45, 0x58, 0x23, 0x6c, 0x29, 0xd3, 0x50, 0x51, 0x1b,
-+    0x38, 0xef, 0x89, 0x90, 0x84, 0xa2, 0x4c, 0x35, 0x7b, 0x30,
-+    0x5e, 0xbd, 0x1a, 0xd5, 0xdf, 0xcd, 0xcd, 0x74, 0x3f, 0x2e,
-+    0x01, 0xea, 0x33, 0x07, 0x74, 0xfb, 0x86, 0x75, 0x20, 0x0e,
-+    0x4f, 0xbf, 0x65, 0xd4, 0x15, 0x19, 0x6f, 0x8d, 0x37, 0xcd,
-+    0xb6, 0x6f, 0x50, 0x9d, 0x5e, 0x04, 0x81, 0x7d, 0xec, 0xd6,
-+    0xbb, 0x40, 0x1b, 0xe0, 0xf5, 0xd5, 0x86, 0x26, 0xc5, 0x41,
-+    0x84, 0x0e, 0x3e, 0x73, 0xb7, 0xa4, 0xbe, 0x2a, 0xfe, 0xd7,
-+    0xe4, 0x4d, 0x5c, 0x2d, 0x6a, 0x04, 0xe6, 0xdd, 0x28, 0xa0,
-+    0x75, 0x4c, 0xe0, 0x23, 0x2c, 0xad, 0xec, 0xaa, 0x72, 0xfd,
-+    0x03, 0xc0, 0x65, 0xfa, 0xc4, 0x3c, 0x25, 0x10, 0xae, 0x3f,
-+    0x09, 0x96, 0x4e, 0xff, 0xfe, 0xc7, 0xe4, 0x9e, 0xec, 0xb5,
-+    0x6e, 0xec, 0xf3, 0x7a, 0x83, 0x7a, 0x8b, 0xbb, 0x91, 0x8d,
-+    0xab, 0x3c, 0x4d, 0x7f, 0x34, 0x77, 0xbe, 0x0c, 0x87, 0xf2,
-+    0xc3, 0xd6, 0xcb, 0xcc, 0xfa, 0x1e, 0xaf, 0x21, 0x24, 0xe9,
-+    0xaa, 0x89, 0x61, 0x0c, 0x7a, 0x1c, 0x7d, 0x00, 0x87, 0x69,
-+    0x30, 0xa0, 0xb4, 0x3b, 0x96, 0x1c, 0x00, 0x14, 0x07, 0xb8,
-+    0x3f, 0x59, 0x62, 0x3a, 0x3f, 0xfb, 0x68, 0xb8, 0x81, 0x7d,
-+    0x4a, 0x9d, 0x1c, 0xa2, 0x07, 0xa3, 0xb1, 0x42, 0x7b, 0xfa,
-+    0x9b, 0xbc, 0x94, 0x30, 0x7e, 0xea, 0xe7, 0x40, 0x7e, 0xd4,
-+    0x0f, 0x33, 0x3b, 0x57, 0xda, 0x8b, 0x6d, 0x64, 0xd5, 0xe4,
-+    0x91, 0x83, 0xf0, 0x3d, 0xae, 0x8b, 0x91, 0xf0, 0xcd, 0xb1,
-+    0xa0, 0xe0, 0x0d, 0xe1, 0xbb, 0x22, 0x78, 0x1f, 0x3a, 0xe5,
-+    0x53, 0x28, 0xf0, 0x35, 0xae, 0x71, 0xe6, 0xfd, 0x63, 0xb2,
-+    0x9c, 0x3f, 0xdd, 0x95, 0x7b, 0xc4, 0xe9, 0x2f, 0xd9, 0x93,
-+    0x3a, 0x10, 0x42, 0x1c, 0x90, 0xab, 0xfb, 0xd3, 0x02, 0xe9,
-+    0x59, 0xbc, 0x53, 0x7e, 0xf3, 0xe1, 0x52, 0x15, 0xa6, 0x58,
-+    0x9e, 0xc1, 0xa6, 0x0e, 0x2e, 0x35, 0x07, 0x3a, 0xc3, 0x1f,
-+    0xaa, 0x58, 0xe7, 0xc6, 0x33, 0x6a, 0x39, 0x4b, 0x21, 0x15,
-+    0x3d, 0x92, 0x4e, 0x5e, 0xf9, 0x01, 0xd6, 0x0f, 0x28, 0x61,
-+    0x15, 0xdf, 0xed, 0x6f, 0x75, 0xc4, 0x8f, 0xcb, 0x16, 0x55,
-+    0x09, 0xc7, 0x24, 0xb2, 0x0c, 0x49, 0x25, 0x8d, 0x5e, 0xf1,
-+    0x0e, 0xe0, 0xe2, 0xc4, 0xcc, 0x1f, 0x4e, 0x60, 0x5c, 0x5e,
-+    0xc6, 0x7f, 0x68, 0x7f, 0xdb, 0x1a, 0x01, 0x67, 0x07, 0xb1,
-+    0x56, 0x93, 0xf2, 0x26, 0x81, 0xc0, 0x33, 0xb8, 0x48, 0xf9,
-+    0x2c, 0x5c, 0x18, 0x29, 0xed, 0xe0, 0x6c, 0xa0, 0xac, 0xd2,
-+    0x90, 0x4b, 0x52, 0x87, 0xbb, 0xb5, 0x05, 0xd8, 0x56, 0xc5,
-+    0xb8, 0x8f, 0x3f, 0x49, 0x52, 0x9a, 0xa2, 0xd0, 0x40, 0x80,
-+    0x5b, 0x16, 0x15, 0xbc, 0x74, 0x8e, 0x00, 0x10, 0xaf, 0xfb,
-+    0x6d, 0xba, 0xcb, 0xbc, 0xe6, 0x13, 0x75, 0xce, 0x27, 0xae,
-+    0x85, 0x57, 0x6c, 0xc0, 0x8a, 0x84, 0x6f, 0x34, 0x16, 0xd4,
-+    0x35, 0xd2, 0xcc, 0x55, 0x00, 0xc1, 0xd8, 0x28, 0x2c, 0x9c,
-+    0x84, 0x78, 0xbf, 0xf0, 0x3b, 0x0d, 0x9f, 0x81, 0xd4, 0xef,
-+    0x99, 0x77, 0x53, 0xd2, 0x8e, 0x43, 0x52, 0xf0, 0x32, 0x7e,
-+    0xba, 0xbf, 0xb6, 0x0e, 0x9d, 0x9b, 0x00, 0xd0, 0x50, 0x55,
-+    0x67, 0x5a, 0x2c, 0x8b, 0x9b, 0x29, 0xfb, 0x41, 0x74, 0x4c,
-+    0xb7, 0xd8, 0x98, 0xa2, 0xfb, 0x73, 0x07, 0x96, 0xef, 0xcd,
-+    0x47, 0x13, 0x1d, 0xe2, 0xb1, 0xac, 0xf3, 0xcf, 0x47, 0x98,
-+    0x7b, 0x6f, 0xf6, 0x32, 0x44, 0x41, 0x78, 0x09, 0x8e, 0x64,
-+    0x0c, 0xbf, 0xe2, 0x0f, 0x8c, 0x44, 0x2f, 0x4e, 0x55, 0xe0,
-+    0xc6, 0xfd, 0x05, 0x74, 0x18, 0x1a, 0xb9, 0xfa, 0xcb, 0xd3,
-+    0xfa, 0x69, 0x50, 0x63, 0xce, 0x2b, 0xef, 0x92, 0x0f, 0x11,
-+    0xd4, 0x9b, 0x53, 0x6c, 0xed, 0xc5, 0x0b, 0x7c, 0xbd, 0xa1,
-+    0x5d, 0xdf, 0xab, 0xcf, 0xaa, 0x83, 0x5e, 0xa8, 0xc5, 0xfe,
-+    0x91, 0x2b, 0x23, 0x1f, 0x39, 0x3d, 0x71, 0x74, 0xbf, 0xa2,
-+    0xf1, 0xda, 0x2f, 0x29, 0x02, 0x9b, 0xea, 0x48, 0x2c, 0xaf,
-+    0xe7, 0xa9, 0xf5, 0x68, 0xab, 0x8f, 0x18, 0xb9, 0x7b, 0x28,
-+    0xf0, 0x92, 0xfb, 0x07, 0xd7, 0xbd, 0x43, 0xcd, 0x7f, 0xfc,
-+    0xb9, 0x5f, 0x24, 0xf8, 0x48, 0x2e, 0xbe, 0x42, 0x87, 0x80,
-+    0x38, 0x78, 0x9e, 0x8c, 0x52, 0x6d, 0xfa, 0x2e, 0x46, 0x35,
-+    0x7a, 0x59, 0x88, 0xb9, 0x3e, 0xcb, 0x79, 0xb4, 0x8a, 0x9e,
-+    0xd5, 0xd0, 0x30, 0x8c, 0xb2, 0x0c, 0x9d, 0x8d, 0x2d, 0x64,
-+    0x0b, 0xf6, 0xeb, 0xf1, 0xde, 0xea, 0x74, 0xfc, 0xbc, 0x01,
-+    0x18, 0x48, 0x4e, 0x35, 0x02, 0x83, 0x01, 0xb2, 0x50, 0xa0,
-+    0x44, 0x19, 0x30, 0x00, 0x12, 0x4a, 0xa0, 0x6d, 0x6b, 0x8b,
-+    0xf1, 0xce, 0xda, 0x2e, 0x16, 0x35, 0x52, 0x26, 0xf9, 0xbe,
-+    0xb1, 0x37, 0xfc, 0x0a, 0x8b, 0x6f, 0x06, 0x11, 0x7b, 0xf7,
-+    0xa8, 0x40, 0xbd, 0x8d, 0x94, 0xa4, 0xa2, 0xe0, 0xb6, 0xdf,
-+    0x62, 0xc0, 0x6f, 0xb3, 0x5d, 0x84, 0xb9, 0xaa, 0x2f, 0xc1,
-+    0x3b, 0xcb, 0x20, 0xc6, 0x68, 0x69, 0x15, 0x74, 0xbc, 0xdb,
-+    0x43, 0x9c, 0x4a, 0xfc, 0x72, 0xc1, 0xf5, 0x87, 0x80, 0xe8,
-+    0x6c, 0xd5, 0xc1, 0x2e, 0x34, 0x5e, 0x96, 0x76, 0x08, 0x3e,
-+    0x45, 0xe4, 0xa0, 0x4a, 0x7a, 0xc1, 0x67, 0x38, 0xf2, 0x31,
-+    0x1f, 0x7b, 0x0f, 0x54, 0xbd, 0x0d, 0x1f, 0x9e, 0x8e, 0x99,
-+    0x8b, 0x58, 0xd9, 0x94, 0x87, 0xaa, 0x8b, 0x82, 0x5d, 0x5e,
-+    0xe8, 0x50, 0xf4, 0xf2, 0xc7, 0xe9, 0x85, 0x6b, 0xd2, 0xef,
-+    0x13, 0xc1, 0xed, 0x57, 0x2a, 0xc5, 0xd6, 0x5d, 0xa4, 0x3b,
-+    0x29, 0xba, 0xab, 0x1b, 0xaa, 0x21, 0x41, 0xe9, 0xdc, 0x47,
-+    0x88, 0xef, 0x0c, 0xfc, 0xb2, 0xdc, 0xf7, 0xdb, 0x55, 0x4d,
-+    0x70, 0xc7, 0xe2, 0x8a, 0x8a, 0xe1, 0xde, 0xcf, 0xe5, 0xca,
-+    0x23, 0x36, 0x29, 0xe5, 0xfc, 0x54, 0x66, 0xda, 0xe9, 0xab,
-+    0x58, 0x20, 0xb2, 0x8e, 0xb2, 0x7d, 0x5d, 0xb8, 0xc7, 0x6c,
-+    0x48, 0x53, 0x2b, 0x47, 0xe0, 0x12, 0x00, 0x0e, 0xfe, 0xa5,
-+    0x93, 0x34, 0xf9, 0x3e, 0xa6, 0x3f, 0x56, 0xaa, 0x43, 0x65,
-+    0xbb, 0x5a, 0x70, 0x3e, 0x62, 0xac, 0x3f, 0x5b, 0x90, 0x02,
-+    0x50, 0x5d, 0x05, 0xa8, 0xd5, 0x67, 0x1a, 0x62, 0xec, 0xd4,
-+    0xde, 0x29, 0x04, 0xac, 0x6d, 0x15, 0x5d, 0xa0, 0xec, 0xf2,
-+    0x57, 0x13, 0x0e, 0x17, 0x96, 0x0c, 0x32, 0x6a, 0xc5, 0xe0,
-+    0xa8, 0xff, 0x85, 0xa4, 0xa3, 0xe3, 0x0e, 0x35, 0x5d, 0xd1,
-+    0x28, 0x84, 0xaa, 0xc4, 0x84, 0xcd, 0x25, 0x63, 0x85, 0x82,
-+    0x3e, 0x12, 0x30, 0x17, 0x57, 0x45, 0xb8, 0xb4, 0x34, 0x01,
-+    0x3a, 0xa2, 0x77, 0x61, 0xc8, 0x3d, 0x1f, 0xc5, 0x0e, 0x4a,
-+    0xbb, 0xf6, 0xa0, 0x5d, 0x79, 0x4b, 0xc8, 0xf3, 0x9c, 0x87,
-+    0x05, 0x2f, 0xea, 0x25, 0x28, 0x91, 0x69, 0x77, 0x7c, 0xba,
-+    0xea, 0x4a, 0x75, 0x2e, 0x2b, 0x17, 0x83, 0x50, 0x32, 0x43,
-+    0x4f, 0xcd, 0xf1, 0x77, 0xb1, 0x22, 0x0a, 0x8b, 0x69, 0x58,
-+    0x09, 0x35, 0x07, 0x6d, 0x61, 0x4a, 0x8d, 0x18, 0x65, 0x6e,
-+    0x9b, 0x62, 0x07, 0xd0, 0x6a, 0x92, 0x39, 0x05, 0x80, 0x14,
-+    0xfa, 0x1c, 0x93, 0x84, 0x0c, 0xb5, 0x8c, 0x41, 0x91, 0x4e,
-+    0x48, 0xf0, 0xf2, 0xba, 0x1d, 0x73, 0x2f, 0x1e, 0xa1, 0x55,
-+    0xc3, 0x02, 0x8c, 0xb1, 0xf2, 0x37, 0xa6, 0x9a, 0x6b, 0xcd,
-+    0x45, 0x2e, 0x08, 0x90, 0x26, 0x63, 0x91, 0xff, 0x22, 0x5e,
-+    0xcd, 0xae, 0x9b, 0x19, 0x1e, 0x10, 0x62, 0x4e, 0x1f, 0x2d,
-+    0x81, 0x69, 0x4f, 0x41, 0xe5, 0x94, 0xff, 0x7e, 0xcc, 0x15,
-+    0x36, 0x1e, 0x29, 0x59, 0x37, 0xe7, 0x64, 0x40, 0x17, 0x1a,
-+    0x32, 0xba, 0x01, 0x26, 0x30, 0x80, 0x60, 0x07, 0x86, 0x6e,
-+    0xd4, 0xb3, 0xe2, 0x44, 0x16, 0x33, 0xf2, 0x4c, 0x84, 0x0e,
-+    0xb1, 0x4a, 0xc7, 0x92, 0xa6, 0xa3, 0x42, 0x36, 0x05, 0x3e,
-+    0x74, 0xa8, 0xb1, 0xc5, 0x63, 0x59, 0x0d, 0x1e, 0x36, 0x45,
-+    0x2b, 0x36, 0x5e, 0xca, 0xab, 0x97, 0x49, 0xd3, 0xab, 0xae,
-+    0x63, 0x0a, 0xd1, 0x03, 0x57, 0x88, 0xa4, 0xa4, 0x3c, 0xda,
-+    0x15, 0x49, 0x1a, 0x5d, 0xe6, 0x5e, 0xb9, 0x82, 0x23, 0xc0,
-+    0x83, 0x96, 0xfe, 0x38, 0x0b, 0x80, 0x0e, 0xde, 0x22, 0xeb,
-+    0x5d, 0xe4, 0x56, 0x32, 0xbe, 0xe0, 0xc0, 0x6e, 0x69, 0x63,
-+    0x27, 0x4e, 0x00, 0x58, 0x80, 0x70, 0xd9, 0xcc, 0x4e, 0xae,
-+    0x6c, 0x5e, 0x6a, 0x43, 0x81, 0xfd, 0x45, 0xb2, 0xa4, 0x6c,
-+    0xf0, 0x9c, 0x66, 0x5c, 0x7d, 0x5c, 0x78, 0x55, 0x33, 0x4b,
-+    0x3c, 0x3b, 0x1d, 0x18, 0x58, 0x79, 0x6a, 0x02, 0xec, 0xce,
-+    0x53, 0x69, 0xc0, 0x17, 0xed, 0x57, 0xaf, 0x71, 0x5b, 0x42,
-+    0x1b, 0x49, 0xd8, 0xe8, 0x96, 0x80, 0xb6, 0x48, 0x1b, 0x7c,
-+    0xf8, 0x74, 0x1c, 0xb1, 0xc4, 0x10, 0xb7, 0xf4, 0x97, 0x7e,
-+    0x6b, 0x8f, 0x54, 0xba, 0x37, 0xb9, 0x35, 0x9e, 0x7b, 0x17,
-+    0x16, 0x9b, 0x89, 0x39, 0xae, 0x4f, 0x2e, 0x18, 0x65, 0xb4,
-+    0x76, 0x20, 0x9a, 0x58, 0xe2, 0x57, 0x6e, 0x1c, 0x3f, 0x8e,
-+    0x9a, 0xbb, 0xd8, 0xfc, 0x4c, 0xd6, 0x2d, 0xc1, 0xa6, 0x46,
-+    0xac, 0x13, 0x1e, 0xa7, 0xf7, 0x1d, 0x28, 0x3a, 0xf4, 0xd6,
-+    0x48, 0xfb, 0xe5, 0xb3, 0x84, 0x94, 0x47, 0x92, 0xae, 0x9a,
-+    0x58, 0xc5, 0xac, 0x23, 0x1b, 0xb5, 0xcd, 0x96, 0xd2, 0x5e,
-+    0xb2, 0x41, 0xfc, 0x9a, 0xae, 0x19, 0xf1, 0x7b, 0x4b, 0x53,
-+    0x1b, 0xfa, 0xa5, 0x0c, 0x49, 0x6d, 0xff, 0xf4, 0x51, 0x88,
-+    0x19, 0x04, 0xd9, 0x85, 0x8e, 0xe2, 0x3a, 0x62, 0x31, 0x5c,
-+    0x6e, 0xe8, 0x4d, 0x04, 0x1d, 0xd8, 0xc2, 0x7b, 0x51, 0xe7,
-+    0x59, 0xbc, 0x85, 0x5c, 0xc4, 0xcc, 0xad, 0xcb, 0x93, 0x69,
-+    0x18, 0xe4, 0x71, 0x9e, 0x63, 0x33, 0x99, 0xb6, 0x3b, 0x23,
-+    0x11, 0x17, 0x7a, 0x3d, 0x6f, 0xb9, 0x6b, 0xf1, 0xf2, 0xa7,
-+    0x03, 0xfd, 0xf0, 0xcd, 0x5b, 0xb5, 0xda, 0x9a, 0xd9, 0x95,
-+    0x02, 0x76, 0xd8, 0x38, 0xd3, 0xbd, 0xa0, 0x4a, 0x9a, 0xab,
-+    0x70, 0xde, 0xc6, 0xf9, 0xa5, 0x19, 0x9c, 0xc4, 0xf9, 0x07,
-+    0x4d, 0xea, 0x15, 0xc2, 0x91, 0x4d, 0x54, 0xa9, 0x2c, 0xca,
-+    0xdf, 0xaa, 0xd1, 0xc4, 0xc0, 0x18, 0x77, 0x28, 0x2a, 0x2c,
-+    0xc3, 0x7c, 0x26, 0xbd, 0xd8, 0x0d, 0x51, 0xa1, 0x4d, 0xad,
-+    0x76, 0x76, 0xaa, 0xa9, 0x45, 0x82, 0x4f, 0x76, 0xfb, 0x1a,
-+    0xd3, 0x71, 0x3c, 0x55, 0xa2, 0x5c, 0xe0, 0xd6, 0xda, 0x35,
-+    0xbe, 0x25, 0x23, 0x26, 0x51, 0xc6, 0xb4, 0xf3, 0x3e, 0x2c,
-+    0x54, 0x09, 0xc7, 0x6f, 0xa5, 0x08, 0x81, 0xba, 0x75, 0xda,
-+    0xcb, 0x4d, 0x05, 0xdd, 0xca, 0x93, 0x48, 0x30, 0xe8, 0x4a,
-+    0x1f, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x07,
-+    0x80, 0x25, 0x2f, 0xbc, 0x49, 0xf8, 0xb3, 0xa3, 0x32, 0xd6,
-+    0x35, 0x20, 0xca, 0x01, 0x49, 0x96, 0xa0, 0x81, 0x42, 0xde,
-+    0xc4, 0xdb, 0x0f, 0xd1, 0x99, 0xe6, 0xd4, 0x23, 0x2a, 0xa6,
-+    0x21, 0x13, 0xfe, 0x51, 0x27, 0xce, 0x18, 0x2a, 0xfa, 0x49,
-+    0x9f, 0xcd, 0x0c, 0x1f, 0xcf, 0x9e, 0x44, 0x27, 0x41, 0xdc,
-+    0x09, 0xcf, 0xef, 0x19, 0xf5, 0x57, 0x7f, 0x36, 0x5c, 0x99,
-+    0x7e, 0x03, 0x74, 0xfb, 0xa9, 0xb6, 0xde, 0xeb, 0xd1, 0x2b,
-+    0x5f, 0x12, 0x6a, 0xa9, 0x33, 0x2c, 0x2a, 0xba, 0xad, 0x8f,
-+    0xc2, 0x27, 0x57, 0x6a, 0xd7, 0x40, 0xf7, 0x4f, 0x4c, 0x9a,
-+    0xb0, 0x3a, 0x5d, 0x2e, 0xf9, 0xf1, 0xea, 0xbd, 0x82, 0xaa,
-+    0xbd, 0xe6, 0x19, 0x16, 0xd5, 0x03, 0x5e, 0x43, 0xfd, 0x88,
-+    0x71, 0xd5, 0xb7, 0x78, 0xbe, 0x80, 0x0f, 0xc9, 0x7f, 0x3a,
-+    0x8f, 0xe1, 0x44, 0xd4, 0x0f, 0xce, 0x26, 0xaf, 0x65, 0xe0,
-+    0xf5, 0x04, 0x53, 0x56, 0x97, 0x4f, 0xf4, 0xc1, 0x44, 0x8d,
-+    0xf7, 0x88, 0x55, 0x47, 0x16, 0xaf, 0x3f, 0x8e, 0x42, 0xdf,
-+    0xbc, 0x14, 0xc3, 0xe6, 0x9f, 0x0d, 0x69, 0x54, 0x5b, 0x7c,
-+    0x49, 0xcf, 0xbf, 0x42, 0x4f, 0xc7, 0x64, 0x8a, 0xe5, 0x84,
-+    0x87, 0x20, 0x9b, 0xfd, 0x70, 0x25, 0x38, 0xd3, 0xb4, 0x97,
-+    0x78, 0xf1, 0x4f, 0x3f, 0x0f, 0xbb, 0x9c, 0xa3, 0x17, 0xd5,
-+    0x4e, 0x4b, 0xac, 0x82, 0x9a, 0x73, 0xb7, 0xc5, 0xec, 0x10,
-+    0x7a, 0x7b, 0xdb, 0x77, 0x2c, 0xb1, 0xf3, 0x8f, 0xc3, 0xa5,
-+    0x31, 0x11, 0x32, 0x55, 0x35, 0xb5, 0x77, 0xd2, 0x62, 0x19,
-+    0x46, 0x92, 0x94, 0xbb, 0x61, 0x0f, 0x30, 0x94, 0x8a, 0xf6,
-+    0xf7, 0x30, 0xe0, 0xa2, 0x8c, 0x1b, 0xff, 0x8c, 0x29, 0x44,
-+    0xb4, 0xb7, 0xb6, 0x5f, 0x4d, 0x52, 0xc6, 0x07, 0xe1, 0x28,
-+    0x8c, 0xae, 0x88, 0x8a, 0x22, 0xbd, 0xd7, 0x36, 0xe4, 0x8f,
-+    0xd1, 0xeb, 0x65, 0x54, 0x19, 0x5f, 0xba, 0xfb, 0xfc, 0x91,
-+    0xa1, 0xa4, 0xb8, 0xa4, 0x2d, 0x85, 0x20, 0xc4, 0xe5, 0xa7,
-+    0x4e, 0xdb, 0xa4, 0xc5, 0xcc, 0x2f, 0x37, 0x41, 0x29, 0x47,
-+    0x15, 0xff, 0x04, 0x80, 0x08, 0x37, 0xce, 0xc5, 0xe3, 0x5a,
-+    0x3f, 0x83, 0xbb, 0x03, 0x9e, 0xfe, 0xec, 0xe4, 0x11, 0x41,
-+    0x12, 0x13, 0xf2, 0x00, 0xe5, 0x1a, 0x02, 0x49, 0xeb, 0xdb,
-+    0x57, 0xe4, 0xce, 0xa0, 0x3f, 0xfd, 0x3c, 0x73, 0x2b, 0x92,
-+    0x44, 0x79, 0x9e, 0x12, 0x4f, 0xfa, 0xe4, 0x53, 0x62, 0xf2,
-+    0xb0, 0xe2, 0x8a, 0xf0, 0x93, 0xa8, 0x1d, 0xee, 0x8d, 0x58,
-+    0x7a, 0x4c, 0x29, 0x91, 0x29, 0xc1, 0xa4, 0xd5, 0xe6, 0x37,
-+    0x1b, 0x75, 0x5b, 0xb6, 0x6b, 0x76, 0x2e, 0xcb, 0xbd, 0xa9,
-+    0xbe, 0x4c, 0x2e, 0x21, 0xa6, 0x38, 0xde, 0x66, 0x2f, 0x51,
-+    0xea, 0x4c, 0xba, 0x3f, 0x4a, 0xfe, 0x7a, 0x15, 0xb3, 0x72,
-+    0x26, 0xba, 0xcf, 0x9e, 0x1b, 0x03, 0xa6, 0xaa, 0x65, 0x68,
-+    0xd3, 0x8c, 0x15, 0x17, 0xe9, 0x11, 0x18, 0x3c, 0xb6, 0xf8,
-+    0x02, 0x54, 0x98, 0x49, 0xfa, 0x35, 0x3c, 0xcd, 0xac, 0xc8,
-+    0x2b, 0x1a, 0x63, 0x93, 0x03, 0x05, 0xa1, 0x41, 0xbe, 0x12,
-+    0xca, 0x15, 0x47, 0x72, 0x63, 0x77, 0x26, 0xd0, 0xe7, 0x8f,
-+    0x0d, 0x6e, 0x9c, 0xac, 0x07, 0xbe, 0x03, 0x22, 0xd0, 0x39,
-+    0x63, 0x8d, 0x9b, 0xc6, 0x20, 0x81, 0xb5, 0x67, 0x15, 0xf6,
-+    0xb0, 0xe3, 0xb9, 0x3e, 0xb7, 0x3f, 0x8f, 0x46, 0xc9, 0x74,
-+    0x10, 0x1e, 0x53, 0xf1, 0xd4, 0x30, 0x4d, 0x6e, 0x72, 0xb4,
-+    0x73, 0x1c, 0xb6, 0x79, 0x82, 0x60, 0x2e, 0x2a, 0x7d, 0x82,
-+    0x95, 0xb5, 0x7c, 0x4d, 0x44, 0xcb, 0xd8, 0x8a, 0x17, 0xe8,
-+    0x50, 0x29, 0xd8, 0x3a, 0xeb, 0x29, 0xc1, 0x83, 0x0f, 0xd9,
-+    0xaf, 0xcc, 0xfa, 0xea, 0x3a, 0x47, 0x5d, 0x33, 0x1f, 0xe8,
-+    0x33, 0x5b, 0x88, 0x8e, 0xdb, 0xd5, 0x1e, 0xaf, 0x4a, 0x5f,
-+    0xc0, 0xfa, 0xf0, 0xb5, 0xa3, 0x5b, 0xda, 0x38, 0xb7, 0x38,
-+    0x5e, 0xce, 0x81, 0x44, 0xf7, 0x66, 0x62, 0x64, 0x1d, 0x04,
-+    0xf0, 0x8a, 0x4f, 0xa2, 0x80, 0x76, 0x83, 0x23, 0x89, 0x61,
-+    0x6b, 0xc3, 0xb7, 0xee, 0xb5, 0x06, 0x33, 0xad, 0x63, 0x04,
-+    0x78, 0xc9, 0xde, 0x32, 0xde, 0xcf, 0x18, 0xb9, 0xb0, 0x3b,
-+    0xee, 0x0a, 0x58, 0xea, 0xad, 0xbc, 0x1e, 0x77, 0xa0, 0x93,
-+    0xf7, 0xae, 0x9e, 0xb6, 0x31, 0x59, 0x8e, 0xb1, 0x03, 0x8f,
-+    0xbb, 0xa4, 0x25, 0x0c, 0x2e, 0xd7, 0xe2, 0x62, 0x5c, 0xf1,
-+    0x68, 0xe9, 0x76, 0xd7, 0x23, 0x14, 0x45, 0xaf, 0xcb, 0x09,
-+    0x50, 0x05, 0x3f, 0xa0, 0xf9, 0xc3, 0x9e, 0x89, 0x05, 0xa8,
-+    0x3b, 0x54, 0x55, 0x32, 0x74, 0x91, 0x46, 0xc1, 0x2c, 0x96,
-+    0x7e, 0x60, 0xad, 0xfa, 0xbb, 0xcd, 0x09, 0x7b, 0x39, 0x10,
-+    0x82, 0x8a, 0xc0, 0x5a, 0x0d, 0xab, 0xb3, 0x71, 0x45, 0xad,
-+    0x39, 0x8e, 0xec, 0x4d, 0x91, 0x8d, 0xda, 0x8d, 0xfa, 0xb0,
-+    0xad, 0x44, 0x3c, 0xc9, 0x21, 0x56, 0x22, 0xfc, 0xd3, 0xba,
-+    0xb7, 0x3c, 0xe3, 0x8d, 0xda, 0x59, 0x34, 0x42, 0xdd, 0x04,
-+    0x5b, 0x8e, 0x2b, 0xc7, 0x94, 0xd5, 0x42, 0xe0, 0x4a, 0x6f,
-+    0x35, 0x5a, 0x27, 0x82, 0xd8, 0x82, 0x40, 0xee, 0x0f, 0xa6,
-+    0xef, 0xe4, 0x70, 0xe3, 0x30, 0xb7, 0x2d, 0xd4, 0xbb, 0x27,
-+    0xb2, 0xbf, 0xad, 0x49, 0x45, 0xbc, 0xeb, 0xbe, 0xb7, 0xd8,
-+    0xe3, 0xb1, 0xf3, 0xeb, 0x41, 0x20, 0x9b, 0x21, 0x54, 0xc3,
-+    0xa8, 0xaf, 0x9f, 0x20, 0x5c, 0x15, 0x8e, 0x25, 0xbc, 0xbc,
-+    0x69, 0x91, 0xfe, 0xda, 0xad, 0xe5, 0x37, 0x7d, 0xb0, 0x51,
-+    0x14, 0xae, 0x8f, 0x35, 0x15, 0x0a, 0xd4, 0x49, 0xa7, 0xd9,
-+    0x20, 0x70, 0xa4, 0xf2, 0xf4, 0x24, 0x66, 0x52, 0xd1, 0xa5,
-+    0x22, 0xea, 0x29, 0xd9, 0xb2, 0x82, 0x8d, 0x36, 0x66, 0x75,
-+    0x6e, 0xd5, 0x8c, 0x54, 0x08, 0x21, 0xf2, 0xee, 0x78, 0xc7,
-+    0x1f, 0x9c, 0x63, 0x5d, 0x88, 0x56, 0xd1, 0xa0, 0x80, 0x33,
-+    0x60, 0x55, 0x23, 0x72, 0xd6, 0xb0, 0x1a, 0x50, 0xde, 0x25,
-+    0x70, 0xb5, 0x77, 0x42, 0xf8, 0x19, 0x18, 0x15, 0x8f, 0xfd,
-+    0x0c, 0x6a, 0x46, 0x1f, 0xbf, 0xe7, 0x60, 0x91, 0xe7, 0xbb,
-+    0x25, 0x63, 0x66, 0xff, 0x11, 0x97, 0xbb, 0xfd, 0x3a, 0x17,
-+    0x94, 0x77, 0xb4, 0xc5, 0x21, 0xba, 0x30, 0x94, 0xdd, 0xe5,
-+    0xeb, 0x1d, 0x01, 0xba, 0xf9, 0xb0, 0x30, 0xdb, 0x11, 0x93,
-+    0xb7, 0xfa, 0x79, 0xe8, 0x5e, 0xb3, 0x39, 0xf4, 0x51, 0x68,
-+    0x31, 0xce, 0xe9, 0x0e, 0x93, 0xde, 0xff, 0xec, 0x27, 0xbd,
-+    0xa6, 0x1a, 0x4c, 0xe0, 0x92, 0x5c, 0xd4, 0x07, 0xd2, 0xa1,
-+    0xdd, 0x12, 0x83, 0xd2, 0x9a, 0x79, 0xb3, 0x3c, 0xfb, 0x07,
-+    0xe3, 0x18, 0x1a, 0xa3, 0x24, 0x80, 0xb4, 0xcc, 0xf4, 0xc6,
-+    0xa5, 0x6c, 0x25, 0xd7, 0x99, 0x1a, 0x30, 0xf0, 0xa9, 0xfc,
-+    0x2e, 0x83, 0x44, 0xac, 0x64, 0x76, 0x34, 0xb0, 0xa6, 0x6f,
-+    0x20, 0x5a, 0x14, 0xf2, 0x07, 0xa7, 0x6f, 0x4d, 0xab, 0xf5,
-+    0xfc, 0x9d, 0xd6, 0x3e, 0x82, 0x48, 0x31, 0x25, 0x47, 0xc9,
-+    0x0e, 0x1d, 0xdb, 0x98, 0x91, 0x56, 0xf5, 0xfe, 0x66, 0x8d,
-+    0x48, 0xf0, 0x4c, 0x6c, 0x2c, 0x96, 0x54, 0x43, 0xec, 0x76,
-+    0xf2, 0xe1, 0x76, 0x68, 0xc8, 0xe1, 0xde, 0x0d, 0x8e, 0x6f,
-+    0xfc, 0x15, 0xd5, 0x93, 0x92, 0xfe, 0xca, 0x9b, 0x30, 0x61,
-+    0x03, 0x0b, 0xca, 0x99, 0x2f, 0xd3, 0x15, 0xe9, 0x66, 0x81,
-+    0xbd, 0x56, 0x17, 0x14, 0x4a, 0x2e, 0xf1, 0x34, 0x84, 0x55,
-+    0x9d, 0xc0, 0x2b, 0xa7, 0x4a, 0xee, 0xf1, 0x7c, 0x67, 0xc7,
-+    0xf3, 0x08, 0x1e, 0x6d, 0x6b, 0x5b, 0xcc, 0x81, 0x91, 0x5c,
-+    0x94, 0x1a, 0x80, 0xda, 0x3a, 0xce, 0x36, 0x05, 0xb0, 0x7a,
-+    0xe8, 0xd0, 0xb4, 0x57, 0x9c, 0xf9, 0xea, 0xf3, 0x26, 0x1d,
-+    0xcb, 0xf8, 0xdd, 0x65, 0xaf, 0xf7, 0xcd, 0xf7, 0xa1, 0x3d,
-+    0xfc, 0x9a, 0x3b, 0x08, 0xb9, 0xfa, 0x3c, 0x16, 0x49, 0x4a,
-+    0xf1, 0xba, 0x4d, 0x31, 0xdd, 0x5e, 0x4f, 0x3d, 0x66, 0x22,
-+    0x1b, 0x08, 0x91, 0x7d, 0xc6, 0xaf, 0x15, 0x07, 0x3c, 0xa1,
-+    0xf7, 0x07, 0xfd, 0x3e, 0x90, 0xbb, 0x6f, 0x7a, 0xe9, 0xe1,
-+    0x2f, 0xb9, 0xee, 0x91, 0x8e, 0x18, 0xcc, 0x8d, 0x1d, 0x22,
-+    0xa0, 0xa0, 0x28, 0x25, 0xfc, 0xd4, 0x94, 0xd3, 0xaa, 0xcf,
-+    0xce, 0xd0, 0x85, 0x82, 0x6f, 0x20, 0x9f, 0x55, 0x0e, 0xe5,
-+    0x72, 0x0d, 0x17, 0x3e, 0x34, 0xc7, 0x2c, 0x0a, 0x14, 0x45,
-+    0x27, 0xe2, 0xc7, 0x2f, 0x86, 0xa1, 0x55, 0x3e, 0x78, 0x03,
-+    0xe9, 0x78, 0x2e, 0xd3, 0x99, 0xee, 0xa0, 0x14, 0xf8, 0xe3,
-+    0x6c, 0xeb, 0x3f, 0x9a, 0xf3, 0x15, 0xce, 0xd5, 0x76, 0xf6,
-+    0x3a, 0x86, 0x30, 0x76, 0xf9, 0x88, 0x30, 0xf5, 0x4a, 0x50,
-+    0x58, 0x80, 0xe9, 0xd9, 0xd4, 0xb9, 0x34, 0x42, 0xa6, 0x4e,
-+    0x9c, 0x1a, 0x07, 0x16, 0x9e, 0xee, 0xe4, 0x88, 0x04, 0x8e,
-+    0xa8, 0xe7, 0xcd, 0xe8, 0x47, 0x1e, 0x54, 0x45, 0xd2, 0x65,
-+    0xd8, 0xee, 0x4b, 0xbd, 0xd0, 0x85, 0xaa, 0xfb, 0x06, 0x53,
-+    0x91, 0x7e, 0xe0, 0x59, 0x20, 0x57, 0x6a, 0xee, 0xd8, 0x9f,
-+    0x77, 0x7f, 0xd7, 0x40, 0x63, 0xbb, 0x21, 0x75, 0x76, 0x11,
-+    0x27, 0xcf, 0x05, 0xbb, 0x41, 0x30, 0x98, 0xbf, 0xdc, 0x5f,
-+    0xc6, 0xa4, 0x1e, 0x30, 0xa1, 0x53, 0xd4, 0x36, 0x7f, 0x2e,
-+    0x86, 0xd7, 0xd9, 0x95, 0x29, 0xd5, 0x46, 0x18, 0x60, 0x27,
-+    0xe4, 0x6f, 0xcb, 0xf4, 0xe2, 0xfe, 0xff, 0x3e, 0xff, 0x15,
-+    0xc6, 0xf2, 0x31, 0xf9, 0x2a, 0xc8, 0x05, 0x4e, 0x7c, 0x2e,
-+    0x92, 0xc8, 0x41, 0x4f, 0x9e, 0x23, 0x21, 0x4d, 0x74, 0xf8,
-+    0xc3, 0x44, 0x39, 0xc2, 0x69, 0x4b, 0x2e, 0x76, 0x5e, 0x44,
-+    0x12, 0x65, 0x31, 0x98, 0xbe, 0x0a, 0x10, 0x11, 0x12, 0x2c,
-+    0x67, 0x3d, 0x85, 0x2e, 0xd3, 0x97, 0x54, 0x1e, 0xb6, 0xad,
-+    0xd9, 0x45, 0x11, 0x53, 0x04, 0x7c, 0x3f, 0xf4, 0xc9, 0xac,
-+    0x82, 0x1b, 0x84, 0xf4, 0x20, 0x6b, 0xf1, 0xf5, 0x72, 0x04,
-+    0x24, 0xc1, 0xd3, 0x42, 0x43, 0x52, 0x9d, 0x2d, 0xd3, 0x89,
-+    0x8e, 0xd8, 0x28, 0xb9, 0xa2, 0xb4, 0xed, 0xbc, 0x76, 0x87,
-+    0x55, 0x67, 0x39, 0xd9, 0xb7, 0x20, 0x6a, 0xec, 0xec, 0xb8,
-+    0x14, 0x51, 0x91, 0xb9, 0x96, 0x0f, 0x7a, 0x3a, 0x12, 0xde,
-+    0x14, 0x3b, 0x83, 0xcf, 0x41, 0x5b, 0x5d, 0xff, 0x33, 0x68,
-+    0xdb, 0x53, 0x64, 0x93, 0xb1, 0xc3, 0x8a, 0x46, 0xa8, 0x44,
-+    0x9c, 0x14, 0x12, 0x6c, 0x92, 0x6f, 0xae, 0xc3, 0x45, 0xb2,
-+    0xa1, 0x67, 0x81, 0x3c, 0x22, 0x47, 0xfd, 0xa4, 0x7a, 0x79,
-+    0xa8, 0x0a, 0xfb, 0x7a, 0x91, 0x6e, 0xe9, 0x53, 0xec, 0x98,
-+    0x82, 0x57, 0xad, 0x05, 0x38, 0x55, 0xc1, 0xce, 0x3a, 0x04,
-+    0x4d, 0x12, 0x72, 0x37, 0x4a, 0x36, 0x54, 0x3f, 0x67, 0x8a,
-+    0xee, 0xd9, 0xf3, 0x80, 0xd5, 0xd7, 0xb8, 0xfc, 0x6e, 0x4f,
-+    0x60, 0x2b, 0x5a, 0xa4, 0xc5, 0x05, 0xdb, 0xe5, 0x09, 0xe3,
-+    0xeb, 0xa2, 0x51, 0x33, 0x30, 0x96, 0x46, 0x01, 0x26, 0x8f,
-+    0x38, 0xc9, 0x97, 0x32, 0x2d, 0xb4, 0x59, 0x15, 0x15, 0x38,
-+    0x66, 0x66, 0xfe, 0xcb, 0xee, 0xc1, 0xf6, 0x4e, 0xb7, 0xdf,
-+    0x7b, 0x63, 0xe6, 0x3f, 0xe0, 0x1c, 0x97, 0xed, 0x86, 0xf3,
-+    0xd2, 0xad, 0x42, 0x29, 0x20, 0x28, 0xa6, 0x59, 0x58, 0x7d,
-+    0x8f, 0x5c, 0x43, 0x07, 0xd1, 0x7e, 0x83, 0xba, 0x9c, 0x1b,
-+    0xfe, 0x17, 0x9e, 0xc8, 0x09, 0x63, 0x9a, 0x2d, 0x61, 0x33,
-+    0x51, 0x46, 0x01, 0xa8, 0xe9, 0x43, 0x1e, 0x4e, 0xfe, 0x61,
-+    0x1a, 0x28, 0x11, 0x65, 0x70, 0x43, 0x9f, 0xfc, 0x21, 0x1d,
-+    0x76, 0x7b, 0x40, 0x08, 0x18, 0xd3, 0xe8, 0xc2, 0xe3, 0x8c,
-+    0xe7, 0x27, 0xc2, 0xec, 0xb0, 0x08, 0x3e, 0x6b, 0x8f, 0x77,
-+    0x6d, 0x9e, 0xa6, 0xab, 0xce, 0x9a, 0xf8, 0x8f, 0x77, 0xb3,
-+    0xf4, 0xe8, 0x8b, 0xe7, 0xd9, 0xa1, 0x95, 0x40, 0x6b, 0xca,
-+    0x21, 0x98, 0xff, 0xdc, 0xdc, 0x96, 0xc3, 0x08, 0x81, 0x72,
-+    0x9a, 0xdd, 0xe2, 0xcf, 0x95, 0x99, 0xa6, 0xa3, 0x5e, 0x9e,
-+    0x25, 0x60, 0xa3, 0xc3, 0x39, 0xf7, 0x54, 0x6c, 0xf2, 0x75,
-+    0xa9, 0x38, 0x12, 0x38, 0x4d, 0x42, 0xe8, 0xec, 0x13, 0x25,
-+    0xa0, 0xf8, 0x04, 0xb8, 0xf6, 0x66, 0x0b, 0x56, 0xe1, 0xfb,
-+    0x26, 0x03, 0xe6, 0xa5, 0xf1, 0x4d, 0x7f, 0xa5, 0x9d, 0x58,
-+    0x71, 0xd8, 0xc7, 0x6a, 0xbe, 0xdc, 0x90, 0x89, 0xb1, 0x36,
-+    0xb4, 0xb6, 0xb4, 0xbb, 0xaf, 0x6e, 0x43, 0x10, 0xa6, 0xea,
-+    0xee, 0x12, 0xcb, 0x08, 0x2c, 0x4e, 0x66, 0xf0, 0x1f, 0xf4,
-+    0xbf, 0xd3, 0xeb, 0x63, 0x48, 0xd0, 0xbe, 0x8a, 0xed, 0x24,
-+    0xdb, 0x0f, 0x23, 0x1d, 0x2e, 0x30, 0x97, 0x0f, 0xd8, 0xc6,
-+    0x3b, 0x04, 0x2f, 0x33, 0x78, 0x20, 0x6e, 0xb1, 0x33, 0x03,
-+    0x27, 0xac, 0x0a, 0x37, 0x15, 0x31, 0xef, 0x4d, 0x43, 0xcc,
-+    0xa0, 0x49, 0x80, 0xe3, 0x8c, 0xc0, 0xf3, 0xf7, 0x2d, 0x37,
-+    0x1d, 0xd3, 0x90, 0x5f, 0xad, 0x31, 0xb5, 0x95, 0x17, 0x69,
-+    0x4b, 0xec, 0x84, 0x9d, 0x2b, 0x8d, 0xdd, 0x9b, 0x58, 0x04,
-+    0xba, 0x28, 0x0e, 0x28, 0xc1, 0x54, 0x6c, 0xb0, 0x25, 0x0c,
-+    0x4f, 0x98, 0x47, 0xf7, 0x93, 0xc2, 0xae, 0x2f, 0x6d, 0x29,
-+    0x9c, 0x3d, 0xe3, 0xb5, 0xe3, 0x28, 0x43, 0x14, 0xe6, 0x92,
-+    0x4c, 0x79, 0x90, 0x59, 0x75, 0x77, 0x56, 0x43, 0xda, 0xac,
-+    0xa9, 0x42, 0xd7, 0xca, 0x95, 0x73, 0x26, 0x54, 0x1f, 0x3a,
-+    0x8a, 0x37, 0x64, 0xd7, 0xcf, 0xe1, 0x31, 0xf7, 0x40, 0x59,
-+    0xfd, 0xff, 0xea, 0x72, 0xfd, 0xc4, 0xde, 0xe3, 0x4d, 0x8a,
-+    0xf5, 0x80, 0xc0, 0x61, 0x21, 0xbd, 0xbd, 0x8e, 0x42, 0xd5,
-+    0x4c, 0xe4, 0xf4, 0x78, 0x31, 0xca, 0xf1, 0xec, 0x7c, 0x7b,
-+    0x85, 0x6a, 0x05, 0x54, 0xbe, 0x38, 0x54, 0x2f, 0x1f, 0xda,
-+    0x9f, 0x98, 0xe2, 0x79, 0xd7, 0x42, 0xca, 0xba, 0x85, 0x21,
-+    0xe2, 0xcb, 0x2b, 0xae, 0x4a, 0x4e, 0x35, 0xfb, 0xcf, 0x3d,
-+    0xc5, 0xae, 0x27, 0x30, 0xa9, 0x45, 0xe6, 0x3b, 0x43, 0x3e,
-+    0x35, 0xe3, 0xf2, 0x0d, 0x53, 0x32, 0x2b, 0xf6, 0xe6, 0xc7,
-+    0xd5, 0x02, 0x82, 0x03, 0xc1, 0x00, 0xd4, 0x04, 0x9b, 0xef,
-+    0x5d, 0x58, 0xb0, 0xa3, 0xaa, 0xd2, 0xab, 0x53, 0x65, 0x99,
-+    0x03, 0x49, 0x48, 0x4d, 0xf5, 0xdf, 0x5d, 0x16, 0x14, 0x11,
-+    0x60, 0x45, 0x1b, 0xff, 0x4a, 0x60, 0x2b, 0x37, 0x63, 0xf6,
-+    0xa7, 0x8a, 0xa8, 0xff, 0x08, 0x97, 0x08, 0xfc, 0xbb, 0xb3,
-+    0x20, 0xa3, 0xcd, 0xd9, 0x58, 0xdb, 0x16, 0x1b, 0x88, 0x02,
-+    0x1e, 0x0f, 0x43, 0x9b, 0x16, 0x7e, 0xbe, 0xb1, 0x9c, 0x13,
-+    0x10, 0xdc, 0xa1, 0x56, 0xff, 0xa3, 0xff, 0x5e, 0x69, 0x30,
-+    0xee, 0x7e, 0x76, 0x5f, 0x84, 0x94, 0xeb, 0x8f, 0x58, 0xf8,
-+    0xcf, 0xbb, 0x99, 0x6e, 0xf0, 0xd8, 0x32, 0xf6, 0xce, 0x48,
-+    0x6f, 0x7c, 0xc8, 0x8f, 0xd3, 0x86, 0x22, 0x49, 0x9f, 0xde,
-+    0x11, 0x05, 0xa4, 0xdc, 0x92, 0xfb, 0x0f, 0xfa, 0x09, 0x4d,
-+    0x17, 0x1a, 0xe2, 0x76, 0x67, 0x40, 0xa9, 0x5b, 0x1b, 0x54,
-+    0x66, 0x48, 0xf7, 0xc3, 0x59, 0xd4, 0xcf, 0x55, 0xd0, 0x7f,
-+    0x3b, 0xb0, 0xa2, 0xd8, 0xec, 0xb7, 0x88, 0xe7, 0xb0, 0x30,
-+    0x72, 0x42, 0x65, 0xe2, 0x91, 0xa7, 0x9b, 0xf6, 0x07, 0x45,
-+    0x52, 0x51, 0xaa, 0xbe, 0x32, 0x35, 0xe4, 0x88, 0x23, 0xe7,
-+    0xcb, 0x3c, 0x1c, 0xfb, 0x0b, 0x96, 0xd5, 0xb3, 0x92, 0x86,
-+    0x79, 0x5b, 0x47, 0x93, 0xd6, 0xbd, 0xc7, 0x21, 0x17, 0xd0,
-+    0xc9, 0xc7, 0x69, 0x84, 0x80, 0x98, 0xaf, 0x2c, 0x63, 0xd1,
-+    0xef, 0x6e, 0xca, 0x84, 0x30, 0x32, 0x83, 0x2d, 0x49, 0xbb,
-+    0x1f, 0x2a, 0xfe, 0x40, 0x7c, 0x03, 0xd4, 0x45, 0xdc, 0xfe,
-+    0x94, 0xf9, 0xe4, 0x36, 0x47, 0xfa, 0x7e, 0x2e, 0x93, 0x03,
-+    0xf8, 0x15, 0xf9, 0xce, 0xc3, 0x5b, 0x76, 0x10, 0xec, 0x89,
-+    0x8c, 0xce, 0x25, 0xa5, 0x77, 0x9a, 0xc5, 0x1e, 0xdd, 0x07,
-+    0x1b, 0x5b, 0xac, 0x6f, 0xdb, 0x94, 0x85, 0xdf, 0x02, 0x22,
-+    0xd1, 0xa9, 0x01, 0x8e, 0x63, 0xa1, 0xee, 0x94, 0x9c, 0xdb,
-+    0xb4, 0x1a, 0x43, 0xe1, 0x1f, 0x4e, 0x2f, 0x68, 0x50, 0x0c,
-+    0x2f, 0x5b, 0xc5, 0x1b, 0xe1, 0x8d, 0x4b, 0xe0, 0x63, 0x8d,
-+    0x7a, 0x30, 0xbe, 0xb7, 0x2e, 0x02, 0xc6, 0x02, 0xac, 0xa8,
-+    0xb8, 0x65, 0xc6, 0x28, 0xee, 0xe4, 0xec, 0x99, 0xa1, 0x9a,
-+    0xfd, 0x1f, 0xb5, 0x85, 0x7a, 0x94, 0x16, 0xe2, 0xe7, 0x74,
-+    0x06, 0x54, 0x1b, 0xd0, 0xaf, 0x58, 0x4e, 0x50, 0x7e, 0xd6,
-+    0xe4, 0x31, 0xd2, 0x0c, 0xd7, 0x9d, 0xe2, 0x00, 0x30, 0xbe,
-+    0x26, 0x30, 0x48, 0x99, 0x98, 0x58, 0x54, 0x5a, 0xc4, 0x0a,
-+    0x6c, 0xa1, 0x06, 0xe9, 0x38, 0xe6, 0x79, 0x39, 0x00, 0x9e,
-+    0xb6, 0xe3, 0xf7, 0x01, 0xcf, 0x2f, 0x82, 0x5e, 0xc3, 0x21,
-+    0x1b, 0x79, 0x93, 0xb5, 0xe4, 0x39, 0x9d, 0x32, 0x9d, 0x72,
-+    0xa4, 0xa8, 0xc9, 0x90, 0xce, 0xaf, 0xc0, 0x00, 0xad, 0x20,
-+    0x87, 0x26, 0xc7, 0xd3, 0x5f, 0x2e, 0xf0, 0x5e, 0xf8, 0x8b,
-+    0x85, 0xa3, 0xc6, 0x66, 0xd8, 0x2f, 0x86, 0xfe, 0x7d, 0x8d,
-+    0x22, 0xa5, 0x6d, 0x68, 0x3e, 0x87, 0x6e, 0xf7, 0xf1, 0xf0,
-+    0x07, 0xc4, 0xe3, 0xf1, 0x84, 0xc4, 0x93, 0x42, 0x06, 0x20,
-+    0x80, 0x64, 0xb3, 0x52, 0x5c, 0xa5, 0xcf, 0xee, 0xfe, 0xa4,
-+    0x09, 0x41, 0xbe, 0xaa, 0x78, 0x52, 0x76, 0x3f, 0xf7, 0xe8,
-+    0xa1, 0x6b, 0x0a, 0xbc, 0x22, 0xbe, 0xdf, 0x72, 0x7b, 0xea,
-+    0x90, 0x43, 0xee, 0xc2, 0x0b, 0x26, 0xdc, 0x02, 0x26, 0xa7,
-+    0x50, 0x04, 0x7a, 0x06, 0x91, 0xae, 0x93, 0xd5, 0xd2, 0xc9,
-+    0xa1, 0xe1, 0xfc, 0xb9, 0x8c, 0x94, 0xca, 0xa8, 0x1c, 0x2c,
-+    0x57, 0x97, 0x3e, 0x50, 0xed, 0x93, 0x45, 0x7a, 0x2c, 0x59,
-+    0x7b, 0x34, 0x8f, 0xcd, 0xd6, 0x17, 0x93, 0xd8, 0xde, 0xe8,
-+    0xb0, 0x9e, 0x27, 0x15, 0xc5, 0xbb, 0xa5, 0xbb, 0xc2, 0x30,
-+    0x9b, 0xc7, 0x27, 0x02, 0x18, 0xd8, 0xdb, 0xa4, 0x84, 0x37,
-+    0x64, 0xf7, 0xf7, 0xf1, 0xc8, 0x86, 0x4c, 0x64, 0x97, 0x08,
-+    0xe9, 0x4e, 0x0e, 0xb6, 0x92, 0xe9, 0x4c, 0x7b, 0x7f, 0xe1,
-+    0xcc, 0xa0, 0x71, 0xa7, 0x34, 0x48, 0x46, 0xbb, 0x37, 0xce,
-+    0xb0, 0x4d, 0x39, 0xa8, 0x0e, 0xab, 0xf6, 0x2f, 0x7c, 0x88,
-+    0xae, 0xcf, 0x90, 0xc6, 0x01, 0xd3, 0x5b, 0x37, 0xe9, 0xb1,
-+    0x28, 0x42, 0x14, 0xbf, 0x59, 0x35, 0x04, 0xab, 0x46, 0x6e,
-+    0xa8, 0x29, 0xe2, 0x7a, 0x77, 0x0e, 0x07, 0x67, 0xe4, 0x2b,
-+    0x03, 0xd2, 0x02, 0x36, 0x16, 0xd7, 0x81, 0x5d, 0x38, 0x9c,
-+    0x68, 0x9c, 0xf5, 0x9e, 0x49, 0x7d, 0x99, 0xfd, 0xcd, 0x1d,
-+    0xd2, 0xdf, 0x3c, 0x36, 0x19, 0x85, 0xaa, 0xb1, 0x30, 0x7a,
-+    0x21, 0xb1, 0x83, 0x16, 0xcf, 0xd1, 0x75, 0xa5, 0x9d, 0xd7,
-+    0xc1, 0x60, 0xa8, 0xdb, 0x1e, 0xb9, 0x3e, 0x9c, 0x12, 0x42,
-+    0xe8, 0x47, 0x49, 0x18, 0x9f, 0x5c, 0x12, 0xd1, 0x69, 0xd5,
-+    0x7d, 0xa8, 0x3c, 0xda, 0x35, 0x8a, 0x6c, 0x63, 0xb8, 0x62,
-+    0x8a, 0x61, 0xfa, 0xf2, 0x61, 0x11, 0x1e, 0xb6, 0xf3, 0x5c,
-+    0x62, 0x9d, 0xa7, 0x62, 0x0c, 0x87, 0x93, 0xe2, 0x23, 0x6c,
-+    0x3d, 0xa9, 0x2c, 0x4b, 0xd5, 0x7f, 0xfe, 0x72, 0x27, 0x36,
-+    0x06, 0xcb, 0x65, 0x38, 0xef, 0x13, 0x57, 0x6a, 0xc9, 0xc6,
-+    0x4f, 0x51, 0xd0, 0x90, 0x06, 0xa0, 0x23, 0x65, 0x95, 0xce,
-+    0x16, 0x8f, 0x8d, 0xb2, 0xf9, 0x7f, 0x3c, 0x2c, 0x30, 0x5a,
-+    0x38, 0xf1, 0x62, 0x79, 0x4b, 0xe5, 0xd7, 0x0a, 0x3f, 0x83,
-+    0x5f, 0x46, 0x26, 0x97, 0xb7, 0x08, 0x8c, 0x5b, 0xb8, 0x02,
-+    0x28, 0xf2, 0x4d, 0xdf, 0x93, 0x97, 0xc5, 0x94, 0x4b, 0x0e,
-+    0x42, 0xc3, 0x35, 0x91, 0x6b, 0x69, 0x61, 0x76, 0x7f, 0x94,
-+    0xcf, 0x0b, 0x81, 0x33, 0xff, 0xf3, 0x0c, 0xc7, 0x01, 0x94,
-+    0x94, 0xa9, 0xed, 0xcd, 0x4b, 0xc8, 0xcb, 0x91, 0xf9, 0x7a,
-+    0x47, 0xcd, 0x79, 0x3c, 0xa6, 0xde, 0x52, 0xd2, 0x47, 0x5c,
-+    0x10, 0x62, 0xbb, 0xe5, 0x32, 0xde, 0x83, 0xcf, 0xa8, 0x52,
-+    0xb3, 0xe7, 0xf9, 0xec, 0x17, 0x34, 0xbf, 0x33, 0x5d, 0xb2,
-+    0x4e, 0x56, 0xf7, 0x29, 0xd9, 0x5c, 0x1b, 0x83, 0x01, 0xbb,
-+    0xb9, 0x2b, 0x95, 0x52, 0x08, 0xab, 0xa4, 0x51, 0x03, 0xa1,
-+    0xfb, 0x6a, 0x50, 0xcd, 0xa8, 0x9d, 0x95, 0x6f, 0x7e, 0xb1,
-+    0x80, 0x1e, 0x9d, 0x81, 0x01, 0x26, 0x41, 0x78, 0x36, 0x3c,
-+    0x8a, 0x44, 0xf4, 0x98, 0x88, 0x1c, 0x5d, 0x06, 0xd3, 0xd2,
-+    0xb2, 0x58, 0x7d, 0xa1, 0x45, 0x1b, 0xbf, 0x8c, 0xf6, 0x6a,
-+    0xfa, 0xfd, 0x08, 0x29, 0x3e, 0x91, 0x57, 0xf1, 0x3d, 0x20,
-+    0xed, 0x49, 0x6e, 0x9c, 0x46, 0xd5, 0x08, 0x8d, 0x9b, 0xf8,
-+    0xef, 0xa3, 0x3a, 0x98, 0xcb, 0xb4, 0xcb, 0x5b, 0x30, 0x25,
-+    0x20, 0xcc, 0x04, 0xa1, 0xeb, 0xeb, 0xee, 0x1b, 0x36, 0x85,
-+    0xc1, 0x93, 0x16, 0x5a, 0x31, 0xdf, 0xd6, 0x0e, 0x73, 0x9e,
-+    0x63, 0x6e, 0x96, 0x90, 0x54, 0xd2, 0xc2, 0x53, 0x69, 0x93,
-+    0xd5, 0x54, 0xca, 0xd8, 0x84, 0xf7, 0x8f, 0x9a, 0xd1, 0x80,
-+    0x0d, 0x57, 0xa8, 0x26, 0xbe, 0x45, 0x64, 0xd5, 0x2b, 0xbb,
-+    0x45, 0xb5, 0x08, 0xb9, 0x37, 0x57, 0x02, 0x82, 0x03, 0xc1,
-+    0x00, 0xd1, 0x30, 0x2e, 0xb7, 0x9b, 0xe7, 0x5d, 0x13, 0x74,
-+    0x1f, 0x52, 0xf2, 0x02, 0x18, 0xe9, 0x07, 0x87, 0x9e, 0xed,
-+    0xde, 0x83, 0x92, 0xcf, 0x73, 0x61, 0x21, 0xc4, 0x62, 0x30,
-+    0x6c, 0xa2, 0x36, 0xbd, 0xe2, 0xc5, 0x19, 0xf6, 0xdf, 0x51,
-+    0x7b, 0xca, 0xd4, 0xe4, 0x51, 0x83, 0x49, 0x27, 0xdd, 0xbd,
-+    0xb0, 0x10, 0x79, 0x39, 0xdd, 0x0e, 0x3d, 0x65, 0xad, 0x6d,
-+    0xa3, 0x95, 0x52, 0x85, 0xdb, 0x18, 0x94, 0x60, 0xaa, 0xc0,
-+    0xc8, 0x8b, 0xdb, 0xfe, 0xf9, 0xf0, 0x86, 0xf9, 0x33, 0x8a,
-+    0xd7, 0xbe, 0x8d, 0x43, 0x83, 0x4d, 0xe4, 0x17, 0x2b, 0x46,
-+    0x54, 0x44, 0x1b, 0xbe, 0x52, 0x64, 0x47, 0x02, 0x6c, 0x4a,
-+    0x64, 0xb4, 0x3f, 0x21, 0x2f, 0xbb, 0xe3, 0x72, 0x7c, 0x26,
-+    0x14, 0xdf, 0x80, 0x50, 0xd4, 0x94, 0xe9, 0xc6, 0x7d, 0x71,
-+    0xd8, 0xaf, 0xfb, 0x74, 0x36, 0x33, 0xbe, 0x58, 0x63, 0xad,
-+    0xcb, 0xdf, 0xc0, 0x73, 0x9e, 0x19, 0xb0, 0x65, 0xe1, 0xd1,
-+    0x10, 0x44, 0xf1, 0xf0, 0x08, 0xa3, 0x09, 0x25, 0xeb, 0xd5,
-+    0xcb, 0xdd, 0x98, 0xdd, 0xbc, 0x09, 0x2c, 0xef, 0xc1, 0x8d,
-+    0x43, 0x15, 0x41, 0xc2, 0xa1, 0x84, 0x37, 0x70, 0x5a, 0xd5,
-+    0xf5, 0xb2, 0x6a, 0x1f, 0xbb, 0xcc, 0x30, 0xb9, 0xd9, 0xc7,
-+    0x36, 0x21, 0xf3, 0x69, 0x3e, 0x91, 0x38, 0x4d, 0xa5, 0xc4,
-+    0xf7, 0x84, 0x90, 0x34, 0x0e, 0x47, 0x7e, 0x26, 0xf2, 0x98,
-+    0x25, 0x26, 0xda, 0xf0, 0x4e, 0x55, 0xea, 0x4d, 0x9b, 0x8a,
-+    0x4a, 0xe1, 0x1f, 0xa0, 0x07, 0x90, 0x9e, 0x59, 0x64, 0xae,
-+    0xd9, 0xd6, 0x7e, 0x72, 0xa1, 0xc4, 0xea, 0x7d, 0xbd, 0x1f,
-+    0x7d, 0x2b, 0xd9, 0x2c, 0xdc, 0x8b, 0xc0, 0xda, 0x52, 0x0c,
-+    0xd1, 0xd0, 0x56, 0xb7, 0x93, 0xc7, 0x26, 0x79, 0x71, 0xd0,
-+    0x0d, 0xae, 0xaa, 0xa7, 0xe4, 0xc1, 0x59, 0x27, 0x68, 0x97,
-+    0x9a, 0xff, 0x3d, 0x36, 0x07, 0x55, 0x77, 0x07, 0x97, 0x69,
-+    0xf3, 0x99, 0x91, 0x3f, 0x63, 0xfd, 0x70, 0x8c, 0xa1, 0xeb,
-+    0xc5, 0x21, 0xa3, 0xfe, 0x99, 0x96, 0x11, 0x37, 0xb9, 0xe6,
-+    0x93, 0xf8, 0xd0, 0xb1, 0xa3, 0x57, 0x7a, 0xa8, 0x63, 0xdd,
-+    0x09, 0x56, 0xb0, 0x3b, 0xa6, 0x59, 0xc7, 0x89, 0x54, 0x16,
-+    0xe9, 0x2d, 0x78, 0x7d, 0xaf, 0x4e, 0x0a, 0x5b, 0x62, 0x3b,
-+    0x0b, 0xcb, 0x24, 0x89, 0x4e, 0x1c, 0x3d, 0xe1, 0xbd, 0x5a,
-+    0x3e, 0xc5, 0xfd, 0x15, 0x3d, 0x08, 0x38, 0x33, 0x5e, 0x37,
-+    0x4c, 0xe3, 0xe3, 0xe9, 0xc4, 0x1d, 0x2b, 0xd4, 0x58, 0x25,
-+    0x58, 0x23, 0x8e, 0xc6, 0x83, 0x9a, 0xf3, 0x9a, 0x78, 0xe9,
-+    0xa7, 0xca, 0xd7, 0xdd, 0x89, 0x20, 0x6e, 0x02, 0xea, 0x6b,
-+    0x37, 0x74, 0xda, 0xa0, 0xc2, 0x5a, 0x2b, 0x80, 0x1c, 0x28,
-+    0x91, 0x0d, 0x50, 0x64, 0xf0, 0x12, 0xe7, 0xc4, 0x7e, 0xdd,
-+    0x28, 0x3b, 0x26, 0x9a, 0xf4, 0x39, 0x56, 0xa4, 0x72, 0x4d,
-+    0xcb, 0x67, 0x3c, 0x68, 0xb2, 0x6f, 0xf0, 0xd0, 0x15, 0x90,
-+    0xc8, 0x08, 0xbb, 0x0b, 0x08, 0x6b, 0x8a, 0xde, 0x41, 0x57,
-+    0xbc, 0x63, 0x0e, 0x00, 0x8d, 0xf8, 0xdd, 0x93, 0xce, 0x58,
-+    0x7b, 0xa8, 0xb9, 0x64, 0x26, 0x06, 0xe7, 0x71, 0x23, 0x0f,
-+    0x41, 0xf1, 0xb7, 0xae, 0x59, 0x2e, 0xd0, 0x73, 0xc5, 0xd9,
-+    0xdc, 0x0e, 0x1c, 0x02, 0x58, 0x69, 0xb3, 0x15, 0x6d, 0x96,
-+    0x2b, 0xdb, 0x7b, 0x3b, 0x6c, 0x38, 0x32, 0x6b, 0xd8, 0x08,
-+    0xb2, 0xbd, 0xa7, 0x49, 0x43, 0xeb, 0x90, 0x42, 0x70, 0xc5,
-+    0xba, 0xcd, 0x4a, 0x44, 0x8f, 0x83, 0x0d, 0x17, 0x51, 0x5a,
-+    0x95, 0xa2, 0x57, 0x9a, 0x16, 0x19, 0x91, 0xbb, 0x90, 0x5c,
-+    0x2a, 0x16, 0xe8, 0x26, 0x10, 0x3c, 0xb7, 0x10, 0x5c, 0xf8,
-+    0xc5, 0x15, 0x2b, 0x70, 0x75, 0x69, 0xba, 0x7b, 0x3d, 0x0b,
-+    0x57, 0xac, 0x39, 0x12, 0x2e, 0xd6, 0xd9, 0x13, 0x74, 0x8e,
-+    0xa8, 0x0b, 0x17, 0xe1, 0x03, 0x7a, 0xba, 0x1d, 0x07, 0x91,
-+    0x8c, 0x2a, 0x3a, 0x8d, 0xe0, 0x2a, 0x94, 0xd4, 0x16, 0x35,
-+    0x64, 0x8b, 0x92, 0x2c, 0x2f, 0xa4, 0x18, 0xfe, 0x3f, 0x02,
-+    0x19, 0x8c, 0xb9, 0xeb, 0xaf, 0x01, 0x06, 0xa8, 0x37, 0x7f,
-+    0xe2, 0x44, 0x10, 0xce, 0xeb, 0x8d, 0xd0, 0x73, 0xc4, 0x1e,
-+    0x3d, 0x2c, 0xaf, 0x77, 0xb2, 0xef, 0xe5, 0x95, 0x8b, 0xdf,
-+    0x02, 0xfc, 0x93, 0xb8, 0xa9, 0x27, 0x88, 0x1d, 0x1d, 0x82,
-+    0x9f, 0xb6, 0xe4, 0x12, 0x05, 0x79, 0xb6, 0x1c, 0x41, 0x0d,
-+    0xc1, 0x53, 0x49, 0x8f, 0x3d, 0xc9, 0xad, 0x84, 0xcb, 0x0b,
-+    0x88, 0x7e, 0xfe, 0x73, 0x59, 0x21, 0x64, 0xc5, 0x50, 0x53,
-+    0xdc, 0x98, 0xc6, 0x43, 0xb8, 0xf5, 0xc3, 0xa1, 0xf5, 0xb2,
-+    0xd8, 0x86, 0xe9, 0xae, 0x98, 0xf9, 0x3b, 0x99, 0xc0, 0xe7,
-+    0xd7, 0x4a, 0xed, 0xac, 0x89, 0x84, 0xb0, 0x8e, 0xd3, 0xab,
-+    0xec, 0x03, 0x02, 0x12, 0x4b, 0x44, 0x17, 0x4d, 0x98, 0x26,
-+    0x1e, 0x51, 0xc5, 0xbb, 0xcd, 0xdc, 0x50, 0xab, 0x83, 0x37,
-+    0x49, 0x90, 0x1e, 0x34, 0xad, 0x81, 0x22, 0x6c, 0xe4, 0xdd,
-+    0x19, 0x01, 0x09, 0x25, 0x2d, 0x9e, 0x52, 0x90, 0x72, 0xa1,
-+    0x68, 0x3d, 0x0c, 0x49, 0x99, 0x19, 0x75, 0x5a, 0xca, 0x08,
-+    0x69, 0xa1, 0xd2, 0x88, 0x8c, 0xea, 0xcf, 0x9c, 0xbc, 0x23,
-+    0xad, 0x3f, 0xb9, 0xfc, 0xb9, 0x30, 0x0d, 0xd6, 0xd9, 0x65,
-+    0x0c, 0x7e, 0x99, 0x68, 0x35, 0x26, 0x07, 0xd1, 0x55, 0xbf,
-+    0x8e, 0xde, 0xe7, 0xe7, 0x01, 0xcb, 0xca, 0x0a, 0x39, 0x2e,
-+    0xcc, 0x19, 0xec, 0x77, 0xf3, 0xab, 0xb2, 0xe6, 0x0e, 0x54,
-+    0x06, 0x01, 0x50, 0x77, 0xd3, 0x61, 0x36, 0x05, 0x90, 0xe4,
-+    0xd8, 0xc4, 0x1d, 0xf5, 0xc7, 0xfa, 0x65, 0xf0, 0x46, 0x6a,
-+    0x5f, 0xa7, 0xc3, 0x8c, 0x6f, 0x04, 0x7f, 0xcf, 0x97, 0xb9,
-+    0x68, 0x92, 0x31, 0x09, 0x02, 0x9f, 0x22, 0xc9, 0xf8, 0xe6,
-+    0x7e, 0xa8, 0x95, 0x5b, 0x6b, 0xfe, 0x9c, 0x4e, 0x63, 0x2d,
-+    0x8c, 0x1a, 0x4c, 0x8b, 0x14, 0x79, 0x08, 0xd5, 0x96, 0x76,
-+    0xd1, 0xb4, 0x2f, 0xae, 0x5d, 0x91, 0x88, 0x7c, 0xdd, 0xd2,
-+    0x06, 0x86, 0xcf, 0x0a, 0x83, 0x6f, 0xda, 0xca, 0x71, 0x7c,
-+    0xe7, 0xe5, 0x34, 0xa8, 0x9a, 0x53, 0x8d, 0xa5, 0xaa, 0x5d,
-+    0xb5, 0x17, 0x81, 0x34, 0x6f, 0xbe, 0xbb, 0xb6, 0x58, 0x22,
-+    0x90, 0x80, 0xf6, 0x9c, 0x1c, 0xb0, 0x79, 0x8f, 0x92, 0x5b,
-+    0x7d, 0x1c, 0x71, 0x5f, 0xb4, 0x87, 0x36, 0xbe, 0x81, 0x8d,
-+    0x4a, 0xfc, 0x28, 0x72, 0x81, 0xaf, 0x5f, 0xbd, 0x5f, 0x99,
-+    0xe3, 0xc9, 0x37, 0xb0, 0x6e, 0xad, 0x70, 0x96, 0xfa, 0xe3,
-+    0x99, 0xf7, 0x08, 0x14, 0x21, 0x21, 0xb7, 0x1a, 0xaa, 0xe8,
-+    0x07, 0xb6, 0xfd, 0xa3, 0x7a, 0x2d, 0x93, 0x64, 0x8f, 0x89,
-+    0x2c, 0x71, 0x49, 0x71, 0xb8, 0x45, 0xca, 0xe0, 0x7c, 0x00,
-+    0x8d, 0xbd, 0xb8, 0x1c, 0x3a, 0x94, 0xa2, 0xa7, 0x6d, 0x0a,
-+    0x2e, 0x84, 0xaf, 0xbd, 0xab, 0x05, 0x95, 0x64, 0x8b, 0x05,
-+    0xc8, 0xc9, 0x4e, 0xea, 0xb5, 0x96, 0x4a, 0x47, 0xdd, 0xf2,
-+    0xcb, 0x02, 0x82, 0x03, 0xc0, 0x59, 0xb3, 0xd9, 0x85, 0xdc,
-+    0xa8, 0xb9, 0x93, 0x85, 0xa2, 0xbc, 0x79, 0xfc, 0x72, 0x50,
-+    0xc1, 0xa0, 0xa5, 0xdb, 0x71, 0x35, 0xa1, 0x31, 0xbc, 0x68,
-+    0x4e, 0xd5, 0x19, 0x9e, 0x0e, 0x32, 0x3a, 0xad, 0x40, 0x9e,
-+    0x82, 0x3c, 0x1e, 0x2b, 0x34, 0x3b, 0xc9, 0x32, 0x61, 0x07,
-+    0x5e, 0x46, 0xa9, 0xbe, 0xbe, 0x73, 0x0c, 0x12, 0xef, 0x52,
-+    0x68, 0x82, 0xe2, 0x0b, 0x12, 0x74, 0xfc, 0x10, 0x5c, 0xc0,
-+    0xb5, 0x98, 0x4d, 0x86, 0xbb, 0x8c, 0x40, 0x15, 0xa1, 0x6e,
-+    0x46, 0x73, 0x2e, 0xd6, 0x99, 0x6b, 0x50, 0xab, 0x04, 0x1a,
-+    0x5f, 0xf4, 0xfa, 0xcb, 0x4b, 0xad, 0xc4, 0x5e, 0x62, 0xa7,
-+    0x48, 0xd4, 0x52, 0x85, 0xdc, 0x2a, 0x85, 0x9b, 0xee, 0x08,
-+    0xa5, 0xaa, 0xaa, 0xe8, 0x44, 0xf0, 0xed, 0x89, 0x21, 0xe4,
-+    0xb4, 0xab, 0x3c, 0x0d, 0x53, 0x7e, 0x53, 0xdd, 0xac, 0x47,
-+    0xda, 0x77, 0x79, 0x5f, 0x78, 0x7a, 0x80, 0x84, 0x46, 0x50,
-+    0xaa, 0xdb, 0x3b, 0x8c, 0x6b, 0xda, 0xb0, 0xac, 0x0a, 0xd3,
-+    0x4c, 0xe4, 0x6e, 0x87, 0xd1, 0xb2, 0x5a, 0xd5, 0x98, 0xae,
-+    0xcb, 0x7e, 0xc2, 0x19, 0xdc, 0x53, 0x64, 0x86, 0x4c, 0x7b,
-+    0xe0, 0x63, 0x22, 0x94, 0x34, 0xad, 0x15, 0xdc, 0xd8, 0xa8,
-+    0x5f, 0xc6, 0x58, 0xf6, 0x72, 0x34, 0xdd, 0xfb, 0x85, 0x8a,
-+    0xd9, 0xa3, 0xfb, 0x3b, 0xad, 0x5d, 0xf0, 0x1a, 0x0b, 0xa8,
-+    0x91, 0xe7, 0x7d, 0x26, 0x27, 0x38, 0xf8, 0xe0, 0x49, 0x1b,
-+    0x56, 0xc5, 0x5b, 0xe3, 0x1c, 0x7b, 0xa3, 0x53, 0x6d, 0x22,
-+    0xfa, 0xd7, 0x63, 0x5f, 0xf0, 0xcb, 0x92, 0x49, 0x01, 0x54,
-+    0xe5, 0x77, 0x5b, 0xd3, 0xab, 0xce, 0xb8, 0x3a, 0x5b, 0xb8,
-+    0x07, 0x40, 0x46, 0x51, 0xe4, 0x59, 0xa2, 0x45, 0x41, 0xcc,
-+    0x81, 0x6c, 0xe3, 0xa6, 0xb3, 0xa0, 0x30, 0x4a, 0x67, 0x10,
-+    0xed, 0xc0, 0x8a, 0xcd, 0xfc, 0xa5, 0x44, 0x9b, 0x59, 0x19,
-+    0x4a, 0x43, 0x8d, 0xec, 0x00, 0xd8, 0x6d, 0xf9, 0xf0, 0x2d,
-+    0xd9, 0x55, 0xfc, 0x05, 0xe2, 0x12, 0x48, 0x4d, 0xd6, 0x7d,
-+    0xec, 0x41, 0xc4, 0x9e, 0xe2, 0xed, 0x84, 0x14, 0x29, 0x0e,
-+    0x5b, 0x81, 0x0b, 0xb0, 0x87, 0x8a, 0xd3, 0x35, 0x5c, 0xad,
-+    0xdb, 0xcc, 0xa1, 0x3c, 0xcb, 0x8b, 0x23, 0x55, 0x69, 0xf1,
-+    0x83, 0x84, 0x81, 0x36, 0xae, 0xd5, 0xf3, 0x98, 0xb6, 0xb2,
-+    0xb5, 0xa1, 0x79, 0x6d, 0x80, 0x8f, 0x2e, 0x25, 0x71, 0x4e,
-+    0x16, 0xff, 0xa0, 0x7c, 0xa4, 0x62, 0x8c, 0x44, 0x85, 0x64,
-+    0x90, 0x7c, 0xac, 0x10, 0x36, 0xf2, 0xf2, 0xfb, 0x20, 0x2b,
-+    0xa1, 0x27, 0xd0, 0xcc, 0x27, 0xfd, 0xb0, 0xba, 0x3e, 0x37,
-+    0xb1, 0xa8, 0x9d, 0x3c, 0x82, 0x63, 0xd0, 0x16, 0x6d, 0x7a,
-+    0xdd, 0x2e, 0xea, 0xe5, 0x87, 0xd6, 0x64, 0x72, 0xdb, 0x60,
-+    0x53, 0x38, 0x18, 0x66, 0x1d, 0x25, 0xf6, 0x08, 0x92, 0x7f,
-+    0x68, 0x5b, 0x79, 0x07, 0xde, 0x93, 0xee, 0xf8, 0x8f, 0xce,
-+    0x28, 0xcf, 0xb1, 0x5b, 0x43, 0x51, 0xdf, 0xf5, 0xac, 0xe8,
-+    0x9c, 0x95, 0x14, 0x8a, 0x67, 0xe1, 0x25, 0xfe, 0x11, 0xa2,
-+    0x40, 0xf8, 0xdd, 0xcf, 0xf5, 0x17, 0x94, 0xb6, 0x88, 0x10,
-+    0xa2, 0x90, 0x58, 0xef, 0xaf, 0x73, 0xf8, 0x7c, 0x9b, 0x20,
-+    0x30, 0x79, 0xca, 0x3f, 0xa9, 0x22, 0x40, 0xfd, 0xcc, 0xb0,
-+    0x5d, 0x0d, 0x97, 0x6b, 0xc0, 0x75, 0x35, 0x33, 0xc5, 0x76,
-+    0x45, 0x6e, 0x9b, 0x78, 0xe7, 0xb4, 0x04, 0xb3, 0xba, 0x3b,
-+    0x93, 0xb1, 0xa9, 0x8f, 0xa1, 0x24, 0x5d, 0x1c, 0x0e, 0x66,
-+    0xc0, 0xc6, 0xcc, 0xd6, 0xb7, 0x88, 0x9d, 0xb8, 0x45, 0xe3,
-+    0xaa, 0xc9, 0x6c, 0xfd, 0x37, 0xdc, 0x85, 0xd5, 0x49, 0xfd,
-+    0xef, 0xeb, 0xf9, 0x7a, 0x3f, 0x7a, 0x4f, 0x86, 0x49, 0xaa,
-+    0x9f, 0x08, 0x12, 0x0b, 0x11, 0x35, 0x5c, 0xd5, 0xd3, 0xda,
-+    0x14, 0x50, 0x03, 0x2c, 0x24, 0x26, 0x0e, 0x29, 0x18, 0xcc,
-+    0x1d, 0x0a, 0x7c, 0x94, 0x8b, 0xc0, 0xa0, 0x3f, 0xea, 0xf8,
-+    0xf8, 0xa9, 0x1d, 0x65, 0x31, 0x6f, 0x3b, 0xa6, 0xd0, 0xfc,
-+    0x26, 0xb0, 0x4e, 0x3a, 0x66, 0xe7, 0x32, 0x10, 0x2e, 0x84,
-+    0x47, 0xad, 0xa9, 0x18, 0xfc, 0xa3, 0x8b, 0x74, 0x84, 0x4f,
-+    0xd4, 0x25, 0x93, 0x0f, 0xdb, 0x2e, 0xae, 0x88, 0x8e, 0x28,
-+    0xf8, 0x0f, 0xaa, 0x60, 0xd4, 0xbe, 0xad, 0x66, 0x0c, 0x0d,
-+    0x01, 0xbd, 0x8d, 0xc4, 0xfc, 0x48, 0xef, 0x78, 0x14, 0x34,
-+    0xee, 0xb3, 0xbc, 0xd4, 0xbb, 0x1f, 0x7c, 0x12, 0x5c, 0x9b,
-+    0xeb, 0x77, 0x3e, 0x2c, 0x6e, 0x31, 0x59, 0xe6, 0x78, 0xc5,
-+    0xe8, 0xa4, 0xdd, 0xf1, 0xef, 0x5d, 0x27, 0x45, 0x31, 0x13,
-+    0xd0, 0x21, 0xa1, 0x13, 0xce, 0xac, 0x7e, 0xbb, 0xfb, 0x32,
-+    0xeb, 0x76, 0x31, 0xc4, 0xba, 0xdf, 0xfb, 0x5a, 0x1b, 0xc9,
-+    0x9e, 0x74, 0xa0, 0x9e, 0x26, 0x82, 0xd5, 0x6e, 0x1d, 0xc3,
-+    0x0e, 0xd1, 0x6d, 0xdb, 0x43, 0xb3, 0x0b, 0x14, 0xcb, 0xf1,
-+    0xad, 0x62, 0x34, 0x49, 0xb8, 0xd3, 0x08, 0xca, 0x93, 0xf1,
-+    0x42, 0xb2, 0x4b, 0x23, 0x79, 0x93, 0xde, 0x18, 0x58, 0xf3,
-+    0x66, 0xfa, 0xdc, 0xab, 0xca, 0x33, 0x22, 0x2b, 0x5c, 0x8c,
-+    0x12, 0xc1, 0x7b, 0x2e, 0x52, 0x72, 0xa7, 0x78, 0x4a, 0x49,
-+    0xa1, 0x53, 0x02, 0x76, 0x2d, 0x2e, 0xf8, 0x43, 0x3c, 0xe8,
-+    0xfa, 0xb7, 0xff, 0x39, 0xed, 0x74, 0x9e, 0x11, 0x61, 0x33,
-+    0xde, 0x2a, 0x55, 0xe6, 0x4a, 0xe7, 0x97, 0xa6, 0xb2, 0xc3,
-+    0x40, 0x41, 0x52, 0x66, 0xcf, 0xbf, 0xf8, 0x8e, 0x08, 0xea,
-+    0x96, 0x4d, 0x03, 0xc9, 0xbe, 0x3c, 0x4e, 0x36, 0x8c, 0x6f,
-+    0x4d, 0x1e, 0xcd, 0x31, 0x6d, 0x53, 0xea, 0x9e, 0xf0, 0x8e,
-+    0x35, 0x97, 0x37, 0x54, 0xe9, 0x0f, 0xb8, 0x23, 0x25, 0x69,
-+    0x5b, 0xb5, 0xff, 0xc3, 0x5a, 0x2d, 0x10, 0x6a, 0xc0, 0xb8,
-+    0xee, 0x0d, 0x31, 0x5b, 0xe4, 0x69, 0x40, 0x62, 0xa7, 0x1b,
-+    0x16, 0xfa, 0xd6, 0xb8, 0xba, 0xc8, 0x6a, 0xa3, 0x29, 0xdd,
-+    0x9b, 0x4d, 0xd7, 0x96, 0xef, 0x31, 0x74, 0xac, 0x37, 0x10,
-+    0x91, 0x30, 0x0c, 0x15, 0x3f, 0x09, 0xb6, 0x7d, 0x22, 0xfb,
-+    0x8c, 0x6f, 0xc3, 0x93, 0xa3, 0x98, 0xa6, 0x23, 0xa4, 0x55,
-+    0xe0, 0x9e, 0x23, 0x06, 0xa9, 0x78, 0xe9, 0xb3, 0x88, 0xc9,
-+    0xb7, 0x83, 0x05, 0x46, 0x11, 0x3a, 0x0a, 0xb9, 0x74, 0x5b,
-+    0xa0, 0xb5, 0x06, 0x96, 0x86, 0xb6, 0xf4, 0x9d, 0x0d, 0x86,
-+    0x43, 0xa8, 0x40, 0x4b, 0x08, 0x93, 0x7c, 0xad, 0xb0, 0x50,
-+    0xb4, 0xd0, 0xe7, 0xad, 0xd0, 0x54, 0x5e, 0x15, 0xaf, 0xad,
-+    0x34, 0x12, 0x86, 0xb3, 0x29, 0x3b, 0x20, 0xc9, 0xad, 0xeb,
-+    0xc2, 0x65, 0xf3, 0x5c, 0x2d, 0xe5, 0xff, 0xfd, 0x81, 0x79,
-+    0xf5, 0x11, 0x6f, 0xf7, 0xca, 0x0c, 0x76, 0xf0, 0xd4, 0x02,
-+    0x9d, 0xb7, 0x76, 0x39, 0x6d, 0x32, 0x6a, 0xb8, 0x30, 0xa4,
-+    0x01, 0xcc, 0x10, 0xef, 0xb1, 0x0e, 0x41, 0x22, 0x82, 0x5b,
-+    0x22, 0xcb, 0x32, 0x19, 0x2e, 0xa3, 0x0a, 0xce, 0x05, 0xdd,
-+    0xe8, 0x4a, 0x58, 0x92, 0xe1, 0x02, 0x82, 0x03, 0xc0, 0x22,
-+    0x0f, 0x95, 0x5b, 0xc2, 0x1f, 0xde, 0xf0, 0xde, 0xf4, 0x86,
-+    0xbd, 0xef, 0x07, 0x7d, 0x52, 0x03, 0x8c, 0x26, 0x31, 0x17,
-+    0xfd, 0x5c, 0x97, 0xed, 0xd5, 0xe0, 0xb3, 0x18, 0x2d, 0x68,
-+    0x10, 0x3f, 0xc4, 0xdf, 0xd1, 0x05, 0x78, 0x81, 0x3d, 0x05,
-+    0xde, 0xba, 0x3a, 0x67, 0x85, 0x0e, 0xdf, 0xb5, 0x16, 0x28,
-+    0xe8, 0x84, 0x3a, 0x71, 0x2a, 0x20, 0x17, 0x28, 0x05, 0xfd,
-+    0xb7, 0x4d, 0x22, 0x4a, 0x93, 0x46, 0x56, 0x27, 0x43, 0xc0,
-+    0x3a, 0x16, 0xff, 0x3d, 0x61, 0xcc, 0xcb, 0xce, 0xac, 0xa8,
-+    0x53, 0x3a, 0x0d, 0xf4, 0x2d, 0xd2, 0x73, 0xf2, 0x64, 0xa0,
-+    0x1e, 0x60, 0x53, 0xec, 0x0d, 0xff, 0xe0, 0x00, 0x10, 0xfb,
-+    0xa4, 0x57, 0xd3, 0xfc, 0xe4, 0xe0, 0xec, 0x44, 0x0b, 0x1c,
-+    0x05, 0x39, 0xa4, 0x13, 0x87, 0x29, 0x11, 0x9d, 0xea, 0xe9,
-+    0x64, 0xa9, 0x1c, 0x76, 0x3a, 0x65, 0x0b, 0xfd, 0xed, 0x77,
-+    0x46, 0x4f, 0xcd, 0x0b, 0x63, 0xc4, 0x83, 0x0b, 0x56, 0x79,
-+    0xd3, 0x67, 0x01, 0x11, 0x02, 0xd9, 0x50, 0xd8, 0x23, 0xf4,
-+    0xb6, 0x02, 0x4c, 0xae, 0xb5, 0xc9, 0x68, 0x1b, 0x87, 0x33,
-+    0xbb, 0xdc, 0x64, 0x0e, 0x32, 0x34, 0xb2, 0x25, 0xaa, 0x76,
-+    0xdd, 0x7e, 0xc3, 0x46, 0x51, 0x1c, 0xc1, 0xd0, 0x05, 0x09,
-+    0x6c, 0x27, 0xd3, 0xcf, 0x33, 0x7a, 0xb9, 0x26, 0x24, 0x23,
-+    0x4a, 0x93, 0x9f, 0x4b, 0x96, 0xc7, 0xe2, 0xb2, 0x51, 0x42,
-+    0x4d, 0x5d, 0xd9, 0x73, 0x75, 0xce, 0x23, 0x28, 0x56, 0x5e,
-+    0xe7, 0x96, 0x58, 0x04, 0xfd, 0x33, 0x93, 0x08, 0x41, 0x62,
-+    0x02, 0x7e, 0xc9, 0xc6, 0x55, 0x64, 0x19, 0xda, 0x39, 0xb8,
-+    0x5d, 0x09, 0x47, 0xf3, 0xdd, 0x77, 0xee, 0xea, 0x35, 0x73,
-+    0x95, 0xdb, 0x18, 0x4d, 0xd1, 0xfe, 0xee, 0x40, 0x31, 0x2a,
-+    0x22, 0x91, 0x69, 0xd6, 0xed, 0x9c, 0x54, 0x14, 0x73, 0x61,
-+    0x61, 0xe7, 0x1d, 0x34, 0x96, 0x47, 0xff, 0x28, 0x7a, 0x48,
-+    0xa3, 0xf4, 0xcd, 0x64, 0x23, 0xe2, 0x52, 0x2f, 0x20, 0x8f,
-+    0x04, 0xb3, 0xdc, 0xf0, 0x29, 0x67, 0x88, 0x76, 0x79, 0xdb,
-+    0x86, 0xa7, 0x95, 0xf0, 0x15, 0x81, 0xbb, 0x98, 0xee, 0xff,
-+    0x55, 0x7c, 0xb0, 0xee, 0x67, 0x65, 0xfd, 0xf2, 0x29, 0x0f,
-+    0x85, 0x51, 0xf9, 0xac, 0x5c, 0x55, 0x5a, 0xde, 0x40, 0x62,
-+    0x58, 0x55, 0x9f, 0x09, 0x4c, 0x2e, 0x28, 0x75, 0xbc, 0x48,
-+    0xe2, 0x97, 0x85, 0xb3, 0x83, 0xeb, 0x21, 0x49, 0x21, 0xd4,
-+    0xed, 0x74, 0x4f, 0xc1, 0x6c, 0x34, 0x8c, 0x11, 0xb0, 0x93,
-+    0x41, 0x99, 0x23, 0x2e, 0xa4, 0xc1, 0x9f, 0x34, 0x74, 0x64,
-+    0xbb, 0xd7, 0x4f, 0x8f, 0x9f, 0x3a, 0x0c, 0x4f, 0x5e, 0xdd,
-+    0x41, 0x07, 0xf1, 0xfd, 0x5a, 0x9d, 0xe6, 0x77, 0xd8, 0x7e,
-+    0x71, 0x7b, 0xad, 0xf7, 0x76, 0x13, 0x71, 0x90, 0xb3, 0x0f,
-+    0x46, 0x8e, 0xee, 0x7b, 0x33, 0x97, 0x5d, 0x21, 0x3b, 0xa0,
-+    0x58, 0x9e, 0xb7, 0x87, 0x30, 0x8f, 0xc1, 0x23, 0x2c, 0xde,
-+    0xf7, 0x0d, 0xa9, 0xd6, 0x50, 0xeb, 0x35, 0x7a, 0x82, 0xab,
-+    0x22, 0x49, 0x86, 0xd4, 0x61, 0xc7, 0xc2, 0x4e, 0x77, 0xfc,
-+    0x16, 0x0b, 0xaf, 0x81, 0x6a, 0x47, 0xea, 0xac, 0x7e, 0x51,
-+    0x4c, 0x56, 0x30, 0x21, 0x46, 0x41, 0xc3, 0x92, 0x60, 0x99,
-+    0x4f, 0x88, 0x36, 0x3b, 0x27, 0xb4, 0xb2, 0x7e, 0x44, 0x2f,
-+    0xdd, 0x95, 0xe4, 0x5e, 0x16, 0x1f, 0xa7, 0x32, 0x6b, 0x60,
-+    0x24, 0x0f, 0xf2, 0xe6, 0x35, 0x3c, 0x0c, 0x3e, 0xb5, 0xd6,
-+    0xdd, 0x63, 0xe2, 0x76, 0x35, 0x38, 0x79, 0xbf, 0xa5, 0x23,
-+    0xa4, 0xdd, 0xeb, 0x01, 0x48, 0xd0, 0x60, 0x86, 0x11, 0x38,
-+    0x5f, 0x9e, 0x6b, 0x00, 0x67, 0xd2, 0x5b, 0x41, 0x0a, 0x5e,
-+    0x13, 0x0f, 0xa1, 0x9e, 0x90, 0x85, 0xa6, 0x7f, 0xe5, 0x4b,
-+    0x9e, 0x93, 0x4e, 0x5b, 0x1f, 0x47, 0x62, 0xb0, 0x23, 0xbe,
-+    0x82, 0xa9, 0xd9, 0xb6, 0x2e, 0xfd, 0xb1, 0x10, 0xca, 0xe0,
-+    0xc9, 0x5d, 0xf6, 0x85, 0x18, 0x6c, 0x9c, 0x1d, 0x1f, 0x7c,
-+    0xf6, 0x55, 0x09, 0x80, 0xcf, 0xac, 0xfe, 0x37, 0x6a, 0x4f,
-+    0x96, 0xaa, 0x40, 0x79, 0x8b, 0x4a, 0xf2, 0x96, 0x79, 0x12,
-+    0x1a, 0x26, 0x87, 0x06, 0x35, 0x4d, 0xd4, 0x3e, 0x14, 0x39,
-+    0xe5, 0x6c, 0x39, 0x0f, 0x84, 0xb3, 0x5f, 0xed, 0xf4, 0xff,
-+    0x89, 0x52, 0x05, 0x00, 0xf1, 0xd1, 0xc3, 0xcf, 0x54, 0x10,
-+    0x24, 0x7c, 0xa6, 0xb5, 0x95, 0xa8, 0x6e, 0x13, 0x3e, 0x4a,
-+    0x40, 0x6c, 0xf9, 0x63, 0x90, 0x44, 0x52, 0x07, 0x53, 0xb7,
-+    0x51, 0xd9, 0x18, 0x47, 0x2e, 0xb0, 0x4e, 0x0f, 0x09, 0x99,
-+    0x3a, 0x97, 0x26, 0x53, 0xa6, 0x02, 0x06, 0x0e, 0x93, 0xe1,
-+    0x0b, 0xc5, 0xa9, 0x14, 0xd3, 0xd6, 0x8a, 0x29, 0x75, 0xcd,
-+    0xb6, 0x7b, 0x64, 0x7c, 0xdd, 0x7e, 0xb4, 0x0a, 0x87, 0x48,
-+    0x4a, 0x1b, 0x0e, 0x74, 0x4c, 0xd3, 0x0e, 0x96, 0x0e, 0x53,
-+    0xc4, 0x3d, 0x7b, 0x1c, 0x87, 0x6a, 0x15, 0xd8, 0x77, 0xba,
-+    0xe6, 0xa0, 0x2f, 0x2c, 0x1a, 0x9d, 0xde, 0x79, 0xfd, 0xab,
-+    0x44, 0x80, 0xf0, 0x37, 0x9a, 0x3b, 0xf8, 0xde, 0x3d, 0x29,
-+    0xcb, 0x89, 0x64, 0x4b, 0x57, 0xe7, 0x6b, 0x84, 0x09, 0x27,
-+    0x17, 0x2f, 0xb2, 0xba, 0x3d, 0x09, 0xc9, 0x3c, 0x89, 0xe6,
-+    0x19, 0x73, 0x83, 0xf7, 0xc6, 0x19, 0x18, 0x96, 0xb2, 0x7d,
-+    0x1e, 0x9f, 0x70, 0x1f, 0xfc, 0x1f, 0xe2, 0xb5, 0x69, 0x1e,
-+    0xf4, 0x65, 0x91, 0xce, 0x4b, 0xdc, 0x74, 0x49, 0x21, 0x64,
-+    0x8b, 0x33, 0x50, 0xd2, 0xc1, 0x33, 0x62, 0x5b, 0xde, 0x0a,
-+    0x72, 0xbe, 0xc0, 0x05, 0x51, 0x15, 0x80, 0xed, 0x32, 0x3a,
-+    0x64, 0xa2, 0x73, 0x68, 0x5b, 0x16, 0xcf, 0x70, 0x5c, 0x98,
-+    0xe5, 0x67, 0x45, 0x60, 0x57, 0x2b, 0x47, 0x0a, 0x22, 0x73,
-+    0xc3, 0x56, 0x33, 0x3e, 0x14, 0x1d, 0x0c, 0xd1, 0x03, 0x08,
-+    0x92, 0x21, 0x2b, 0xa9, 0x6e, 0x6b, 0xf9, 0x0c, 0x1e, 0x86,
-+    0xdd, 0xb5, 0xbb, 0xa4, 0xa5, 0x82, 0x99, 0x98, 0x49, 0x36,
-+    0xec, 0x98, 0x98, 0x95, 0xac, 0xc2, 0xa0, 0x1f, 0xa5, 0x7e,
-+    0x67, 0xd1, 0xcf, 0x6a, 0xf4, 0x16, 0x08, 0x7a, 0x8d, 0x0b,
-+    0xae, 0x12, 0x51, 0xe6, 0x8e, 0xe6, 0xcd, 0xa1, 0xaa, 0x6d,
-+    0xe4, 0x54, 0xd4, 0x69, 0x1b, 0x09, 0x6a, 0xba, 0x5e, 0x0b,
-+    0x11, 0x9c, 0x83, 0xb3, 0x5c, 0x67, 0xbb, 0x2d, 0xf8, 0x66,
-+    0x1c, 0x33, 0xb8, 0x22, 0x58, 0x10, 0x96, 0xe9, 0x99, 0xaf,
-+    0x0b, 0x2a, 0xf1, 0xe0, 0xcb, 0x56, 0xfb, 0x6d, 0x04, 0x40,
-+    0xec, 0x37, 0x67, 0x1e, 0x08, 0x7a, 0x1c, 0xe9, 0xd8, 0x54,
-+    0xf7, 0xd4, 0xc7, 0x3c, 0x45, 0x23, 0x2b, 0x76, 0xd2, 0x62,
-+    0xc2, 0x53, 0xce, 0xfe, 0x02, 0xc4, 0xd9, 0xf6, 0x3c, 0xed,
-+    0x49, 0x47, 0x21, 0xf9, 0x03, 0x3a, 0xa0, 0x16, 0x3a, 0xfe,
-+    0x0c, 0x2f, 0x54, 0x7e, 0x85, 0x29, 0x7b, 0xc0, 0xaf, 0xa8,
-+    0x5d, 0x31, 0x25, 0xda, 0xa7, 0xe3, 0x92, 0x1b, 0x64, 0x01,
-+    0x1b, 0x3f, 0x6e, 0x47, 0xc5, 0x5a, 0x84, 0x52, 0x17, 0x02,
-+    0x82, 0x03, 0xc1, 0x00, 0x81, 0x99, 0x2e, 0x72, 0x41, 0x6e,
-+    0x86, 0xeb, 0x6f, 0x42, 0xd1, 0x38, 0x6e, 0xaa, 0x1a, 0xd5,
-+    0x0a, 0xad, 0x51, 0xb1, 0xce, 0xd6, 0x35, 0xbe, 0x34, 0xd8,
-+    0xc1, 0xe4, 0x5f, 0xdf, 0x2e, 0xe4, 0x90, 0xf2, 0x61, 0x21,
-+    0x46, 0xc6, 0xfe, 0xab, 0x0f, 0x6c, 0x97, 0x78, 0xcd, 0x55,
-+    0x86, 0x83, 0x61, 0x99, 0x49, 0x14, 0x86, 0xc6, 0x86, 0xf1,
-+    0x41, 0x66, 0xc9, 0x39, 0x52, 0x99, 0x49, 0x07, 0xd6, 0x9d,
-+    0xb7, 0x40, 0x34, 0x5f, 0xe7, 0x3a, 0xfa, 0x95, 0xeb, 0xa1,
-+    0x03, 0xb7, 0x52, 0x71, 0x93, 0x30, 0x0b, 0x51, 0x58, 0x82,
-+    0x07, 0x2f, 0x44, 0xa9, 0x4f, 0x9b, 0x1b, 0xf3, 0xd6, 0x21,
-+    0x3d, 0x68, 0xef, 0x3f, 0xaf, 0xc2, 0x6f, 0xa0, 0xd5, 0x2b,
-+    0xb8, 0x73, 0x84, 0x67, 0x36, 0x8b, 0xa4, 0x25, 0xe0, 0x86,
-+    0xd9, 0x14, 0x5c, 0x6c, 0xd8, 0x61, 0xe1, 0x0a, 0x6c, 0xaf,
-+    0xbb, 0x9c, 0xf6, 0x74, 0xca, 0x5a, 0x04, 0xac, 0x85, 0xc1,
-+    0x1b, 0x4d, 0xf2, 0x07, 0xb6, 0x1e, 0x97, 0x7b, 0x75, 0xdf,
-+    0x9b, 0x8a, 0x31, 0xc6, 0x90, 0xd5, 0x8d, 0x39, 0xc2, 0x54,
-+    0xf4, 0xe2, 0x83, 0x57, 0x12, 0x19, 0xf5, 0xb2, 0xd2, 0x53,
-+    0x81, 0x6d, 0xf0, 0x09, 0xc9, 0x80, 0x8b, 0x07, 0x7c, 0x59,
-+    0xcd, 0x78, 0x00, 0xd6, 0x44, 0x7f, 0xe4, 0xdb, 0x77, 0x02,
-+    0x00, 0x25, 0x79, 0x91, 0xc9, 0xde, 0xd0, 0xed, 0x3f, 0xfc,
-+    0x37, 0x36, 0xea, 0xf0, 0x56, 0x50, 0xe7, 0x38, 0xca, 0xe1,
-+    0x67, 0x12, 0x96, 0x55, 0x3e, 0xff, 0x97, 0xe5, 0xa7, 0x03,
-+    0x5b, 0x72, 0x80, 0xd6, 0xa5, 0x23, 0x39, 0x78, 0x07, 0xc8,
-+    0x83, 0x19, 0x74, 0xfb, 0x79, 0xc2, 0x9e, 0xbd, 0xf9, 0xaf,
-+    0x09, 0x0f, 0xbd, 0x3d, 0x34, 0xe8, 0x44, 0x89, 0xb1, 0xf1,
-+    0x2b, 0xa5, 0xff, 0x22, 0xc9, 0x47, 0xe2, 0x31, 0xb5, 0x6b,
-+    0x8a, 0x65, 0x5f, 0x81, 0x5f, 0x89, 0xb0, 0x03, 0x5d, 0x53,
-+    0x0e, 0xdd, 0xfb, 0xe5, 0x70, 0xaa, 0xd2, 0x37, 0x4d, 0xa1,
-+    0x7c, 0xf2, 0xe4, 0x7f, 0xf1, 0x4a, 0xaf, 0x12, 0xd1, 0x83,
-+    0xdc, 0xb2, 0x9e, 0xc1, 0x95, 0x3d, 0x04, 0x9f, 0xa3, 0xad,
-+    0xcc, 0x78, 0x14, 0x9a, 0xf9, 0x58, 0x39, 0x08, 0x15, 0xda,
-+    0x1b, 0x94, 0x50, 0x2d, 0x44, 0xc0, 0x23, 0x1c, 0x36, 0x5f,
-+    0x16, 0x08, 0xa3, 0xdf, 0x9e, 0x4f, 0xbb, 0x07, 0xcd, 0xe3,
-+    0x8c, 0xbf, 0xf1, 0xc3, 0x3e, 0x98, 0xf8, 0x49, 0x79, 0x58,
-+    0xc9, 0x0f, 0x47, 0xc0, 0xab, 0x2f, 0x21, 0x63, 0xf6, 0xe6,
-+    0xfe, 0x8a, 0xea, 0xbc, 0x32, 0x63, 0xca, 0x75, 0xf8, 0xa4,
-+    0x1b, 0x6c, 0xfe, 0x9a, 0x6e, 0x68, 0x1f, 0x48, 0x59, 0xfb,
-+    0x34, 0x43, 0x10, 0xd5, 0x0d, 0x80, 0x54, 0xcb, 0x67, 0x21,
-+    0xc7, 0x13, 0x85, 0x38, 0x0c, 0xf9, 0x40, 0x2e, 0x2e, 0x4a,
-+    0x05, 0x9e, 0x51, 0xae, 0xdd, 0xba, 0x23, 0x83, 0x66, 0x2a,
-+    0xbf, 0x7f, 0xca, 0x9c, 0x6c, 0x2d, 0x6b, 0x7d, 0x68, 0x52,
-+    0x81, 0x56, 0x2f, 0xea, 0xf9, 0xe7, 0xf1, 0x55, 0x16, 0xfc,
-+    0x29, 0xe2, 0xa5, 0x1e, 0x0a, 0x06, 0xe0, 0x85, 0x4e, 0xa6,
-+    0x5d, 0x20, 0x9d, 0x2b, 0xa2, 0xad, 0xaa, 0xd6, 0x9b, 0xd2,
-+    0x98, 0x29, 0x45, 0x5c, 0x55, 0xc0, 0x91, 0xa2, 0x65, 0xcd,
-+    0xac, 0xc6, 0x1a, 0x53, 0xa1, 0x46, 0x13, 0xf9, 0xfe, 0x1a,
-+    0xf6, 0xdf, 0xa5, 0x1a, 0x58, 0x7c, 0x81, 0x2e, 0x46, 0x46,
-+    0xf7, 0x2f, 0xd6, 0xaa, 0x21, 0xb0, 0x0e, 0x7e, 0xac, 0xb8,
-+    0xc6, 0x76, 0x62, 0x82, 0x3b, 0x0a, 0x36, 0xbe, 0x97, 0x16,
-+    0xd5, 0x79, 0x55, 0x15, 0x64, 0x2a, 0xbe, 0x19, 0x4e, 0x93,
-+    0x3b, 0x44, 0x7c, 0xe2, 0xfc, 0x18, 0x4e, 0x83, 0x37, 0xfb,
-+    0x26, 0x78, 0x6d, 0x24, 0x6b, 0x48, 0x21, 0x67, 0xde, 0xf5,
-+    0x00, 0x22, 0x9a, 0xec, 0x40, 0x16, 0x96, 0x8a, 0x3f, 0xd5,
-+    0xa6, 0x5e, 0x03, 0x84, 0xbb, 0x15, 0x4d, 0x55, 0x71, 0x00,
-+    0x90, 0xc2, 0x96, 0x25, 0x01, 0xab, 0xe6, 0x47, 0x44, 0x6f,
-+    0xf9, 0x53, 0x80, 0x2b, 0xa8, 0x83, 0xc8, 0x14, 0x77, 0x13,
-+    0x00, 0x66, 0xee, 0x7e, 0x7a, 0xa0, 0x28, 0x65, 0xf3, 0x31,
-+    0xb6, 0xac, 0xd7, 0x87, 0x84, 0x29, 0xed, 0x5b, 0xcd, 0x74,
-+    0xc0, 0x89, 0x51, 0x11, 0x9a, 0xd5, 0x7b, 0xe0, 0x9c, 0xd0,
-+    0x8d, 0x72, 0xe3, 0x77, 0xda, 0x0a, 0xc2, 0xdc, 0x6f, 0xad,
-+    0x49, 0x03, 0xfa, 0xe6, 0x7e, 0xa6, 0x24, 0x32, 0xe6, 0x8f,
-+    0xd9, 0x70, 0xfa, 0x59, 0x70, 0xa9, 0xa3, 0x08, 0x7d, 0x89,
-+    0xc4, 0x96, 0x61, 0xc2, 0xf5, 0xe5, 0xb5, 0x3b, 0x0d, 0xec,
-+    0xb8, 0x9c, 0xee, 0x09, 0x77, 0x27, 0xbd, 0x35, 0x66, 0x90,
-+    0x9e, 0x46, 0xf7, 0xbd, 0xa6, 0xc5, 0x31, 0xd4, 0x6a, 0x52,
-+    0x17, 0x5d, 0x0a, 0x0e, 0x2c, 0x34, 0x7a, 0x6a, 0x21, 0xac,
-+    0x42, 0xf0, 0x31, 0xde, 0x48, 0xe0, 0x27, 0xd0, 0x79, 0xc9,
-+    0x06, 0x94, 0x7b, 0x51, 0x4b, 0x5b, 0x02, 0x6a, 0x19, 0xba,
-+    0x71, 0x45, 0x9c, 0xdf, 0xe6, 0x30, 0x9e, 0xaa, 0xad, 0xa1,
-+    0x87, 0xf6, 0x37, 0xde, 0xa2, 0x97, 0x68, 0x20, 0x2d, 0x5a,
-+    0xdc, 0xdd, 0x91, 0x63, 0x5f, 0x79, 0xda, 0x99, 0x20, 0x3a,
-+    0x4b, 0xe5, 0x43, 0x0e, 0x12, 0x70, 0x57, 0x91, 0xfa, 0xee,
-+    0xc4, 0xb6, 0xb6, 0xb1, 0xf1, 0x06, 0xbd, 0xcf, 0x8d, 0x2a,
-+    0x05, 0xc0, 0x07, 0x23, 0x84, 0x85, 0xef, 0x9c, 0xbb, 0x6f,
-+    0x5f, 0x4a, 0x9a, 0x27, 0x9f, 0x9f, 0x32, 0x97, 0xe8, 0x24,
-+    0xb9, 0x64, 0x2c, 0x39, 0xff, 0x2f, 0x4b, 0xc4, 0x7e, 0x65,
-+    0xfe, 0xbb, 0x5c, 0xa0, 0xb2, 0x6e, 0xc4, 0xb6, 0x93, 0x2b,
-+    0x51, 0x9e, 0x2e, 0x1f, 0xd8, 0xcf, 0x60, 0xe0, 0x75, 0x15,
-+    0xf9, 0xa0, 0x67, 0x99, 0x88, 0x2b, 0x76, 0xce, 0x41, 0x42,
-+    0x10, 0x29, 0x89, 0xbf, 0xca, 0xb7, 0x61, 0x08, 0x94, 0xee,
-+    0xa0, 0xb3, 0x3a, 0x09, 0xc5, 0x6f, 0x04, 0xf9, 0x1b, 0xb5,
-+    0x64, 0x99, 0x08, 0xe4, 0xcc, 0xce, 0xdf, 0x71, 0x65, 0x8a,
-+    0x6d, 0x62, 0xde, 0x76, 0x1d, 0x6d, 0x6b, 0x78, 0x22, 0x32,
-+    0x63, 0xdd, 0x53, 0x7d, 0xec, 0xed, 0x9d, 0x82, 0xa9, 0x2c,
-+    0x5c, 0x8a, 0x17, 0xdd, 0x85, 0xf9, 0xd2, 0xac, 0x6e, 0x98,
-+    0x60, 0x2e, 0x08, 0xd4, 0x06, 0x76, 0xf4, 0x97, 0xca, 0xb1,
-+    0x72, 0x50, 0x5b, 0x83, 0xea, 0xbb, 0x39, 0x0f, 0x18, 0xb3,
-+    0xb8, 0x03, 0xee, 0x7c, 0x84, 0xa9, 0x69, 0xcd, 0x1d, 0xbd,
-+    0xe2, 0xb7, 0xce, 0xe2, 0x6f, 0x03, 0x49, 0x52, 0x67, 0xa0,
-+    0x1b, 0x23, 0x43, 0x92, 0x2c, 0x7c, 0x3b, 0x65, 0xe8, 0x61,
-+    0x99, 0xde, 0xb5, 0xf1, 0x63, 0x73, 0x92, 0x6c, 0x70, 0x8b,
-+    0x83, 0x10, 0xb4, 0x06, 0x2c, 0x99, 0x12, 0x73, 0xec, 0x87,
-+    0x92, 0x09, 0x67, 0x96, 0xd6, 0x9c, 0x9f, 0x35, 0x48, 0x48,
-+    0x3b, 0x44, 0x00, 0x73, 0x1c, 0x59, 0xeb, 0x81, 0x7b, 0xd1,
-+    0xda, 0x76, 0xcf, 0xc2, 0x4d, 0xf1, 0xa2, 0x5b, 0x2f, 0x5f,
-+    0x91, 0x29, 0x6e, 0x08, 0x37, 0xd6, 0xaa, 0xd2, 0xf8, 0x4f,
-+    0x5e, 0x00, 0x16, 0x52
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/timeouts.h b/CryptoPkg/Library/OpensslLib/openssl/apps/timeouts.h
-new file mode 100644
-index 0000000..e023b0a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/timeouts.h
-@@ -0,0 +1,17 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef INCLUDED_TIMEOUTS_H
-+# define INCLUDED_TIMEOUTS_H
-+
-+/* numbers in us */
-+# define DGRAM_RCV_TIMEOUT         250000
-+# define DGRAM_SND_TIMEOUT         250000
-+
-+#endif                          /* ! INCLUDED_TIMEOUTS_H */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/ts.c b/CryptoPkg/Library/OpensslLib/openssl/apps/ts.c
-new file mode 100644
-index 0000000..14c533b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/ts.c
-@@ -0,0 +1,995 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#ifdef OPENSSL_NO_TS
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+# include 
-+# include 
-+# include 
-+# include "apps.h"
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+
-+/* Request nonce length, in bits (must be a multiple of 8). */
-+# define NONCE_LENGTH            64
-+
-+/* Name of config entry that defines the OID file. */
-+# define ENV_OID_FILE            "oid_file"
-+
-+/* Is |EXACTLY_ONE| of three pointers set? */
-+# define EXACTLY_ONE(a, b, c) \
-+        (( a && !b && !c) || \
-+         ( b && !a && !c) || \
-+         ( c && !a && !b))
-+
-+static ASN1_OBJECT *txt2obj(const char *oid);
-+static CONF *load_config_file(const char *configfile);
-+
-+/* Query related functions. */
-+static int query_command(const char *data, const char *digest,
-+                         const EVP_MD *md, const char *policy, int no_nonce,
-+                         int cert, const char *in, const char *out, int text);
-+static TS_REQ *create_query(BIO *data_bio, const char *digest, const EVP_MD *md,
-+                            const char *policy, int no_nonce, int cert);
-+static int create_digest(BIO *input, const char *digest,
-+                         const EVP_MD *md, unsigned char **md_value);
-+static ASN1_INTEGER *create_nonce(int bits);
-+
-+/* Reply related functions. */
-+static int reply_command(CONF *conf, const char *section, const char *engine,
-+                         const char *queryfile, const char *passin, const char *inkey,
-+                         const EVP_MD *md, const char *signer, const char *chain,
-+                         const char *policy, const char *in, int token_in,
-+                         const char *out, int token_out, int text);
-+static TS_RESP *read_PKCS7(BIO *in_bio);
-+static TS_RESP *create_response(CONF *conf, const char *section, const char *engine,
-+                                const char *queryfile, const char *passin,
-+                                const char *inkey, const EVP_MD *md, const char *signer,
-+                                const char *chain, const char *policy);
-+static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data);
-+static ASN1_INTEGER *next_serial(const char *serialfile);
-+static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
-+
-+/* Verify related functions. */
-+static int verify_command(const char *data, const char *digest, const char *queryfile,
-+                          const char *in, int token_in,
-+                          const char *CApath, const char *CAfile, const char *untrusted,
-+                          X509_VERIFY_PARAM *vpm);
-+static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest,
-+                                        const char *queryfile,
-+                                        const char *CApath, const char *CAfile,
-+                                        const char *untrusted,
-+                                        X509_VERIFY_PARAM *vpm);
-+static X509_STORE *create_cert_store(const char *CApath, const char *CAfile,
-+                                     X509_VERIFY_PARAM *vpm);
-+static int verify_cb(int ok, X509_STORE_CTX *ctx);
-+
-+typedef enum OPTION_choice {
-+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-+    OPT_ENGINE, OPT_CONFIG, OPT_SECTION, OPT_QUERY, OPT_DATA,
-+    OPT_DIGEST, OPT_RAND, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT,
-+    OPT_IN, OPT_TOKEN_IN, OPT_OUT, OPT_TOKEN_OUT, OPT_TEXT,
-+    OPT_REPLY, OPT_QUERYFILE, OPT_PASSIN, OPT_INKEY, OPT_SIGNER,
-+    OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_UNTRUSTED,
-+    OPT_MD, OPT_V_ENUM
-+} OPTION_CHOICE;
-+
-+OPTIONS ts_options[] = {
-+    {"help", OPT_HELP, '-', "Display this summary"},
-+    {"config", OPT_CONFIG, '<', "Configuration file"},
-+    {"section", OPT_SECTION, 's', "Section to use within config file"},
-+    {"query", OPT_QUERY, '-', "Generate a TS query"},
-+    {"data", OPT_DATA, '<', "File to hash"},
-+    {"digest", OPT_DIGEST, 's', "Digest (as a hex string)"},
-+    {"rand", OPT_RAND, 's',
-+     "Load the file(s) into the random number generator"},
-+    {"tspolicy", OPT_TSPOLICY, 's', "Policy OID to use"},
-+    {"no_nonce", OPT_NO_NONCE, '-', "Do not include a nonce"},
-+    {"cert", OPT_CERT, '-', "Put cert request into query"},
-+    {"in", OPT_IN, '<', "Input file"},
-+    {"token_in", OPT_TOKEN_IN, '-', "Input is a PKCS#7 file"},
-+    {"out", OPT_OUT, '>', "Output file"},
-+    {"token_out", OPT_TOKEN_OUT, '-', "Output is a PKCS#7 file"},
-+    {"text", OPT_TEXT, '-', "Output text (not DER)"},
-+    {"reply", OPT_REPLY, '-', "Generate a TS reply"},
-+    {"queryfile", OPT_QUERYFILE, '<', "File containing a TS query"},
-+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
-+    {"inkey", OPT_INKEY, '<', "File with private key for reply"},
-+    {"signer", OPT_SIGNER, 's', "Signer certificate file"},
-+    {"chain", OPT_CHAIN, '<', "File with signer CA chain"},
-+    {"verify", OPT_VERIFY, '-', "Verify a TS response"},
-+    {"CApath", OPT_CAPATH, '/', "Path to trusted CA files"},
-+    {"CAfile", OPT_CAFILE, '<', "File with trusted CA certs"},
-+    {"untrusted", OPT_UNTRUSTED, '<', "File with untrusted certs"},
-+    {"", OPT_MD, '-', "Any supported digest"},
-+# ifndef OPENSSL_NO_ENGINE
-+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
-+# endif
-+    {OPT_HELP_STR, 1, '-', "\nOptions specific to 'ts -verify': \n"},
-+    OPT_V_OPTIONS,
-+    {OPT_HELP_STR, 1, '-', "\n"},
-+    {NULL}
-+};
-+
-+/*
-+ * This command is so complex, special help is needed.
-+ */
-+static char* opt_helplist[] = {
-+    "Typical uses:",
-+    "ts -query [-rand file...] [-config file] [-data file]",
-+    "          [-digest hexstring] [-tspolicy oid] [-no_nonce] [-cert]",
-+    "          [-in file] [-out file] [-text]",
-+    "  or",
-+    "ts -reply [-config file] [-section tsa_section]",
-+    "          [-queryfile file] [-passin password]",
-+    "          [-signer tsa_cert.pem] [-inkey private_key.pem]",
-+    "          [-chain certs_file.pem] [-tspolicy oid]",
-+    "          [-in file] [-token_in] [-out file] [-token_out]",
-+# ifndef OPENSSL_NO_ENGINE
-+    "          [-text] [-engine id]",
-+# else
-+    "          [-text]",
-+# endif
-+    "  or",
-+    "ts -verify -CApath dir -CAfile file.pem -untrusted file.pem",
-+    "           [-data file] [-digest hexstring]",
-+    "           [-queryfile file] -in file [-token_in]",
-+    "           [[options specific to 'ts -verify']]",
-+    NULL,
-+};
-+
-+int ts_main(int argc, char **argv)
-+{
-+    CONF *conf = NULL;
-+    const char *CAfile = NULL, *untrusted = NULL, *prog;
-+    const char *configfile = default_config_file, *engine = NULL;
-+    const char *section = NULL;
-+    char **helpp;
-+    char *password = NULL;
-+    char *data = NULL, *digest = NULL, *rnd = NULL, *policy = NULL;
-+    char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL;
-+    char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL;
-+    const EVP_MD *md = NULL;
-+    OPTION_CHOICE o, mode = OPT_ERR;
-+    int ret = 1, no_nonce = 0, cert = 0, text = 0;
-+    int vpmtouched = 0;
-+    X509_VERIFY_PARAM *vpm = NULL;
-+    /* Input is ContentInfo instead of TimeStampResp. */
-+    int token_in = 0;
-+    /* Output is ContentInfo instead of TimeStampResp. */
-+    int token_out = 0;
-+
-+    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
-+        goto end;
-+
-+    prog = opt_init(argc, argv, ts_options);
-+    while ((o = opt_next()) != OPT_EOF) {
-+        switch (o) {
-+        case OPT_EOF:
-+        case OPT_ERR:
-+ opthelp:
-+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-+            goto end;
-+        case OPT_HELP:
-+            opt_help(ts_options);
-+            for (helpp = opt_helplist; *helpp; ++helpp)
-+                BIO_printf(bio_err, "%s\n", *helpp);
-+            ret = 0;
-+            goto end;
-+        case OPT_CONFIG:
-+            configfile = opt_arg();
-+            break;
-+        case OPT_SECTION:
-+            section = opt_arg();
-+            break;
-+        case OPT_QUERY:
-+        case OPT_REPLY:
-+        case OPT_VERIFY:
-+            if (mode != OPT_ERR)
-+                goto opthelp;
-+            mode = o;
-+            break;
-+        case OPT_DATA:
-+            data = opt_arg();
-+            break;
-+        case OPT_DIGEST:
-+            digest = opt_arg();
-+            break;
-+        case OPT_RAND:
-+            rnd = opt_arg();
-+            break;
-+        case OPT_TSPOLICY:
-+            policy = opt_arg();
-+            break;
-+        case OPT_NO_NONCE:
-+            no_nonce = 1;
-+            break;
-+        case OPT_CERT:
-+            cert = 1;
-+            break;
-+        case OPT_IN:
-+            in = opt_arg();
-+            break;
-+        case OPT_TOKEN_IN:
-+            token_in = 1;
-+            break;
-+        case OPT_OUT:
-+            out = opt_arg();
-+            break;
-+        case OPT_TOKEN_OUT:
-+            token_out = 1;
-+            break;
-+        case OPT_TEXT:
-+            text = 1;
-+            break;
-+        case OPT_QUERYFILE:
-+            queryfile = opt_arg();
-+            break;
-+        case OPT_PASSIN:
-+            passin = opt_arg();
-+            break;
-+        case OPT_INKEY:
-+            inkey = opt_arg();
-+            break;
-+        case OPT_SIGNER:
-+            signer = opt_arg();
-+            break;
-+        case OPT_CHAIN:
-+            chain = opt_arg();
-+            break;
-+        case OPT_CAPATH:
-+            CApath = opt_arg();
-+            break;
-+        case OPT_CAFILE:
-+            CAfile = opt_arg();
-+            break;
-+        case OPT_UNTRUSTED:
-+            untrusted = opt_arg();
-+            break;
-+        case OPT_ENGINE:
-+            engine = opt_arg();
-+            break;
-+        case OPT_MD:
-+            if (!opt_md(opt_unknown(), &md))
-+                goto opthelp;
-+            break;
-+        case OPT_V_CASES:
-+            if (!opt_verify(o, vpm))
-+                goto end;
-+            vpmtouched++;
-+            break;
-+        }
-+    }
-+    if (mode == OPT_ERR || opt_num_rest() != 0)
-+        goto opthelp;
-+
-+    /* Seed the random number generator if it is going to be used. */
-+    if (mode == OPT_QUERY && !no_nonce) {
-+        if (!app_RAND_load_file(NULL, 1) && rnd == NULL)
-+            BIO_printf(bio_err, "warning, not much extra random "
-+                       "data, consider using the -rand option\n");
-+        if (rnd != NULL)
-+            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
-+                       app_RAND_load_files(rnd));
-+    }
-+
-+    if (mode == OPT_REPLY && passin &&
-+        !app_passwd(passin, NULL, &password, NULL)) {
-+        BIO_printf(bio_err, "Error getting password.\n");
-+        goto end;
-+    }
-+
-+    conf = load_config_file(configfile);
-+    if (configfile != default_config_file && !app_load_modules(conf))
-+        goto end;
-+
-+    /* Check parameter consistency and execute the appropriate function. */
-+    switch (mode) {
-+    default:
-+    case OPT_ERR:
-+        goto opthelp;
-+    case OPT_QUERY:
-+        if (vpmtouched)
-+            goto opthelp;
-+        if ((data != NULL) && (digest != NULL))
-+            goto opthelp;
-+        ret = !query_command(data, digest, md, policy, no_nonce, cert,
-+                             in, out, text);
-+        break;
-+    case OPT_REPLY:
-+        if (vpmtouched)
-+            goto opthelp;
-+        if ((in != NULL) && (queryfile != NULL))
-+            goto opthelp;
-+        if (in == NULL) {
-+            if ((conf == NULL) || (token_in != 0))
-+                goto opthelp;
-+        }
-+        ret = !reply_command(conf, section, engine, queryfile,
-+                             password, inkey, md, signer, chain, policy,
-+                             in, token_in, out, token_out, text);
-+        break;
-+    case OPT_VERIFY:
-+        if ((in == NULL) || !EXACTLY_ONE(queryfile, data, digest))
-+            goto opthelp;
-+        ret = !verify_command(data, digest, queryfile, in, token_in,
-+                              CApath, CAfile, untrusted,
-+                              vpmtouched ? vpm : NULL);
-+    }
-+
-+ end:
-+    X509_VERIFY_PARAM_free(vpm);
-+    app_RAND_write_file(NULL);
-+    NCONF_free(conf);
-+    OPENSSL_free(password);
-+    return (ret);
-+}
-+
-+/*
-+ * Configuration file-related function definitions.
-+ */
-+
-+static ASN1_OBJECT *txt2obj(const char *oid)
-+{
-+    ASN1_OBJECT *oid_obj = NULL;
-+
-+    if ((oid_obj = OBJ_txt2obj(oid, 0)) == NULL)
-+        BIO_printf(bio_err, "cannot convert %s to OID\n", oid);
-+
-+    return oid_obj;
-+}
-+
-+static CONF *load_config_file(const char *configfile)
-+{
-+    CONF *conf = app_load_config(configfile);
-+
-+    if (conf != NULL) {
-+        const char *p;
-+
-+        BIO_printf(bio_err, "Using configuration from %s\n", configfile);
-+        p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
-+        if (p != NULL) {
-+            BIO *oid_bio = BIO_new_file(p, "r");
-+            if (!oid_bio)
-+                ERR_print_errors(bio_err);
-+            else {
-+                OBJ_create_objects(oid_bio);
-+                BIO_free_all(oid_bio);
-+            }
-+        } else
-+            ERR_clear_error();
-+        if (!add_oid_section(conf))
-+            ERR_print_errors(bio_err);
-+    }
-+    return conf;
-+}
-+
-+/*
-+ * Query-related method definitions.
-+ */
-+static int query_command(const char *data, const char *digest, const EVP_MD *md,
-+                         const char *policy, int no_nonce,
-+                         int cert, const char *in, const char *out, int text)
-+{
-+    int ret = 0;
-+    TS_REQ *query = NULL;
-+    BIO *in_bio = NULL;
-+    BIO *data_bio = NULL;
-+    BIO *out_bio = NULL;
-+
-+    /* Build query object. */
-+    if (in != NULL) {
-+        if ((in_bio = bio_open_default(in, 'r', FORMAT_ASN1)) == NULL)
-+            goto end;
-+        query = d2i_TS_REQ_bio(in_bio, NULL);
-+    } else {
-+        if (digest == NULL
-+            && (data_bio = bio_open_default(data, 'r', FORMAT_ASN1)) == NULL)
-+            goto end;
-+        query = create_query(data_bio, digest, md, policy, no_nonce, cert);
-+    }
-+    if (query == NULL)
-+        goto end;
-+
-+    if (text) {
-+        if ((out_bio = bio_open_default(out, 'w', FORMAT_TEXT)) == NULL)
-+            goto end;
-+        if (!TS_REQ_print_bio(out_bio, query))
-+            goto end;
-+    } else {
-+        if ((out_bio = bio_open_default(out, 'w', FORMAT_ASN1)) == NULL)
-+            goto end;
-+        if (!i2d_TS_REQ_bio(out_bio, query))
-+            goto end;
-+    }
-+
-+    ret = 1;
-+
-+ end:
-+    ERR_print_errors(bio_err);
-+    BIO_free_all(in_bio);
-+    BIO_free_all(data_bio);
-+    BIO_free_all(out_bio);
-+    TS_REQ_free(query);
-+    return ret;
-+}
-+
-+static TS_REQ *create_query(BIO *data_bio, const char *digest, const EVP_MD *md,
-+                            const char *policy, int no_nonce, int cert)
-+{
-+    int ret = 0;
-+    TS_REQ *ts_req = NULL;
-+    int len;
-+    TS_MSG_IMPRINT *msg_imprint = NULL;
-+    X509_ALGOR *algo = NULL;
-+    unsigned char *data = NULL;
-+    ASN1_OBJECT *policy_obj = NULL;
-+    ASN1_INTEGER *nonce_asn1 = NULL;
-+
-+    if (md == NULL && (md = EVP_get_digestbyname("sha1")) == NULL)
-+        goto err;
-+    if ((ts_req = TS_REQ_new()) == NULL)
-+        goto err;
-+    if (!TS_REQ_set_version(ts_req, 1))
-+        goto err;
-+    if ((msg_imprint = TS_MSG_IMPRINT_new()) == NULL)
-+        goto err;
-+    if ((algo = X509_ALGOR_new()) == NULL)
-+        goto err;
-+    if ((algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))) == NULL)
-+        goto err;
-+    if ((algo->parameter = ASN1_TYPE_new()) == NULL)
-+        goto err;
-+    algo->parameter->type = V_ASN1_NULL;
-+    if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo))
-+        goto err;
-+    if ((len = create_digest(data_bio, digest, md, &data)) == 0)
-+        goto err;
-+    if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len))
-+        goto err;
-+    if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint))
-+        goto err;
-+    if (policy && (policy_obj = txt2obj(policy)) == NULL)
-+        goto err;
-+    if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj))
-+        goto err;
-+
-+    /* Setting nonce if requested. */
-+    if (!no_nonce && (nonce_asn1 = create_nonce(NONCE_LENGTH)) == NULL)
-+        goto err;
-+    if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1))
-+        goto err;
-+    if (!TS_REQ_set_cert_req(ts_req, cert))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    if (!ret) {
-+        TS_REQ_free(ts_req);
-+        ts_req = NULL;
-+        BIO_printf(bio_err, "could not create query\n");
-+        ERR_print_errors(bio_err);
-+    }
-+    TS_MSG_IMPRINT_free(msg_imprint);
-+    X509_ALGOR_free(algo);
-+    OPENSSL_free(data);
-+    ASN1_OBJECT_free(policy_obj);
-+    ASN1_INTEGER_free(nonce_asn1);
-+    return ts_req;
-+}
-+
-+static int create_digest(BIO *input, const char *digest, const EVP_MD *md,
-+                         unsigned char **md_value)
-+{
-+    int md_value_len;
-+    int rv = 0;
-+    EVP_MD_CTX *md_ctx = NULL;
-+
-+    md_value_len = EVP_MD_size(md);
-+    if (md_value_len < 0)
-+        return 0;
-+
-+    if (input) {
-+        unsigned char buffer[4096];
-+        int length;
-+
-+        md_ctx = EVP_MD_CTX_new();
-+        if (md_ctx == NULL)
-+            return 0;
-+        *md_value = app_malloc(md_value_len, "digest buffer");
-+        if (!EVP_DigestInit(md_ctx, md))
-+            goto err;
-+        while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0) {
-+            if (!EVP_DigestUpdate(md_ctx, buffer, length))
-+                goto err;
-+        }
-+        if (!EVP_DigestFinal(md_ctx, *md_value, NULL))
-+            goto err;
-+        md_value_len = EVP_MD_size(md);
-+    } else {
-+        long digest_len;
-+        *md_value = OPENSSL_hexstr2buf(digest, &digest_len);
-+        if (!*md_value || md_value_len != digest_len) {
-+            OPENSSL_free(*md_value);
-+            *md_value = NULL;
-+            BIO_printf(bio_err, "bad digest, %d bytes "
-+                       "must be specified\n", md_value_len);
-+            return 0;
-+        }
-+    }
-+    rv = md_value_len;
-+ err:
-+    EVP_MD_CTX_free(md_ctx);
-+    return rv;
-+}
-+
-+static ASN1_INTEGER *create_nonce(int bits)
-+{
-+    unsigned char buf[20];
-+    ASN1_INTEGER *nonce = NULL;
-+    int len = (bits - 1) / 8 + 1;
-+    int i;
-+
-+    if (len > (int)sizeof(buf))
-+        goto err;
-+    if (RAND_bytes(buf, len) <= 0)
-+        goto err;
-+
-+    /* Find the first non-zero byte and creating ASN1_INTEGER object. */
-+    for (i = 0; i < len && !buf[i]; ++i)
-+        continue;
-+    if ((nonce = ASN1_INTEGER_new()) == NULL)
-+        goto err;
-+    OPENSSL_free(nonce->data);
-+    nonce->length = len - i;
-+    nonce->data = app_malloc(nonce->length + 1, "nonce buffer");
-+    memcpy(nonce->data, buf + i, nonce->length);
-+    return nonce;
-+
-+ err:
-+    BIO_printf(bio_err, "could not create nonce\n");
-+    ASN1_INTEGER_free(nonce);
-+    return NULL;
-+}
-+
-+/*
-+ * Reply-related method definitions.
-+ */
-+
-+static int reply_command(CONF *conf, const char *section, const char *engine,
-+                         const char *queryfile, const char *passin, const char *inkey,
-+                         const EVP_MD *md, const char *signer, const char *chain,
-+                         const char *policy, const char *in, int token_in,
-+                         const char *out, int token_out, int text)
-+{
-+    int ret = 0;
-+    TS_RESP *response = NULL;
-+    BIO *in_bio = NULL;
-+    BIO *query_bio = NULL;
-+    BIO *inkey_bio = NULL;
-+    BIO *signer_bio = NULL;
-+    BIO *out_bio = NULL;
-+
-+    if (in != NULL) {
-+        if ((in_bio = BIO_new_file(in, "rb")) == NULL)
-+            goto end;
-+        if (token_in) {
-+            response = read_PKCS7(in_bio);
-+        } else {
-+            response = d2i_TS_RESP_bio(in_bio, NULL);
-+        }
-+    } else {
-+        response = create_response(conf, section, engine, queryfile,
-+                                   passin, inkey, md, signer, chain, policy);
-+        if (response)
-+            BIO_printf(bio_err, "Response has been generated.\n");
-+        else
-+            BIO_printf(bio_err, "Response is not generated.\n");
-+    }
-+    if (response == NULL)
-+        goto end;
-+
-+    /* Write response. */
-+    if (text) {
-+        if ((out_bio = bio_open_default(out, 'w', FORMAT_TEXT)) == NULL)
-+        goto end;
-+        if (token_out) {
-+            TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
-+            if (!TS_TST_INFO_print_bio(out_bio, tst_info))
-+                goto end;
-+        } else {
-+            if (!TS_RESP_print_bio(out_bio, response))
-+                goto end;
-+        }
-+    } else {
-+        if ((out_bio = bio_open_default(out, 'w', FORMAT_ASN1)) == NULL)
-+            goto end;
-+        if (token_out) {
-+            PKCS7 *token = TS_RESP_get_token(response);
-+            if (!i2d_PKCS7_bio(out_bio, token))
-+                goto end;
-+        } else {
-+            if (!i2d_TS_RESP_bio(out_bio, response))
-+                goto end;
-+        }
-+    }
-+
-+    ret = 1;
-+
-+ end:
-+    ERR_print_errors(bio_err);
-+    BIO_free_all(in_bio);
-+    BIO_free_all(query_bio);
-+    BIO_free_all(inkey_bio);
-+    BIO_free_all(signer_bio);
-+    BIO_free_all(out_bio);
-+    TS_RESP_free(response);
-+    return ret;
-+}
-+
-+/* Reads a PKCS7 token and adds default 'granted' status info to it. */
-+static TS_RESP *read_PKCS7(BIO *in_bio)
-+{
-+    int ret = 0;
-+    PKCS7 *token = NULL;
-+    TS_TST_INFO *tst_info = NULL;
-+    TS_RESP *resp = NULL;
-+    TS_STATUS_INFO *si = NULL;
-+
-+    if ((token = d2i_PKCS7_bio(in_bio, NULL)) == NULL)
-+        goto end;
-+    if ((tst_info = PKCS7_to_TS_TST_INFO(token)) == NULL)
-+        goto end;
-+    if ((resp = TS_RESP_new()) == NULL)
-+        goto end;
-+    if ((si = TS_STATUS_INFO_new()) == NULL)
-+        goto end;
-+    if (!TS_STATUS_INFO_set_status(si, TS_STATUS_GRANTED))
-+        goto end;
-+    if (!TS_RESP_set_status_info(resp, si))
-+        goto end;
-+    TS_RESP_set_tst_info(resp, token, tst_info);
-+    token = NULL;               /* Ownership is lost. */
-+    tst_info = NULL;            /* Ownership is lost. */
-+    ret = 1;
-+
-+ end:
-+    PKCS7_free(token);
-+    TS_TST_INFO_free(tst_info);
-+    if (!ret) {
-+        TS_RESP_free(resp);
-+        resp = NULL;
-+    }
-+    TS_STATUS_INFO_free(si);
-+    return resp;
-+}
-+
-+static TS_RESP *create_response(CONF *conf, const char *section, const char *engine,
-+                                const char *queryfile, const char *passin,
-+                                const char *inkey, const EVP_MD *md, const char *signer,
-+                                const char *chain, const char *policy)
-+{
-+    int ret = 0;
-+    TS_RESP *response = NULL;
-+    BIO *query_bio = NULL;
-+    TS_RESP_CTX *resp_ctx = NULL;
-+
-+    if ((query_bio = BIO_new_file(queryfile, "rb")) == NULL)
-+        goto end;
-+    if ((section = TS_CONF_get_tsa_section(conf, section)) == NULL)
-+        goto end;
-+    if ((resp_ctx = TS_RESP_CTX_new()) == NULL)
-+        goto end;
-+    if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx))
-+        goto end;
-+# ifndef OPENSSL_NO_ENGINE
-+    if (!TS_CONF_set_crypto_device(conf, section, engine))
-+        goto end;
-+# endif
-+    if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx))
-+        goto end;
-+    if (!TS_CONF_set_certs(conf, section, chain, resp_ctx))
-+        goto end;
-+    if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
-+        goto end;
-+
-+    if (md) {
-+        if (!TS_RESP_CTX_set_signer_digest(resp_ctx, md))
-+            goto end;
-+    } else if (!TS_CONF_set_signer_digest(conf, section, NULL, resp_ctx)) {
-+            goto end;
-+    }
-+
-+    if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx))
-+        goto end;
-+    if (!TS_CONF_set_policies(conf, section, resp_ctx))
-+        goto end;
-+    if (!TS_CONF_set_digests(conf, section, resp_ctx))
-+        goto end;
-+    if (!TS_CONF_set_accuracy(conf, section, resp_ctx))
-+        goto end;
-+    if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx))
-+        goto end;
-+    if (!TS_CONF_set_ordering(conf, section, resp_ctx))
-+        goto end;
-+    if (!TS_CONF_set_tsa_name(conf, section, resp_ctx))
-+        goto end;
-+    if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx))
-+        goto end;
-+    if ((response = TS_RESP_create_response(resp_ctx, query_bio)) == NULL)
-+        goto end;
-+    ret = 1;
-+
-+ end:
-+    if (!ret) {
-+        TS_RESP_free(response);
-+        response = NULL;
-+    }
-+    TS_RESP_CTX_free(resp_ctx);
-+    BIO_free_all(query_bio);
-+    return response;
-+}
-+
-+static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data)
-+{
-+    const char *serial_file = (const char *)data;
-+    ASN1_INTEGER *serial = next_serial(serial_file);
-+
-+    if (!serial) {
-+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                    "Error during serial number "
-+                                    "generation.");
-+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_ADD_INFO_NOT_AVAILABLE);
-+    } else
-+        save_ts_serial(serial_file, serial);
-+
-+    return serial;
-+}
-+
-+static ASN1_INTEGER *next_serial(const char *serialfile)
-+{
-+    int ret = 0;
-+    BIO *in = NULL;
-+    ASN1_INTEGER *serial = NULL;
-+    BIGNUM *bn = NULL;
-+
-+    if ((serial = ASN1_INTEGER_new()) == NULL)
-+        goto err;
-+
-+    if ((in = BIO_new_file(serialfile, "r")) == NULL) {
-+        ERR_clear_error();
-+        BIO_printf(bio_err, "Warning: could not open file %s for "
-+                   "reading, using serial number: 1\n", serialfile);
-+        if (!ASN1_INTEGER_set(serial, 1))
-+            goto err;
-+    } else {
-+        char buf[1024];
-+        if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf))) {
-+            BIO_printf(bio_err, "unable to load number from %s\n",
-+                       serialfile);
-+            goto err;
-+        }
-+        if ((bn = ASN1_INTEGER_to_BN(serial, NULL)) == NULL)
-+            goto err;
-+        ASN1_INTEGER_free(serial);
-+        serial = NULL;
-+        if (!BN_add_word(bn, 1))
-+            goto err;
-+        if ((serial = BN_to_ASN1_INTEGER(bn, NULL)) == NULL)
-+            goto err;
-+    }
-+    ret = 1;
-+
-+ err:
-+    if (!ret) {
-+        ASN1_INTEGER_free(serial);
-+        serial = NULL;
-+    }
-+    BIO_free_all(in);
-+    BN_free(bn);
-+    return serial;
-+}
-+
-+static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial)
-+{
-+    int ret = 0;
-+    BIO *out = NULL;
-+
-+    if ((out = BIO_new_file(serialfile, "w")) == NULL)
-+        goto err;
-+    if (i2a_ASN1_INTEGER(out, serial) <= 0)
-+        goto err;
-+    if (BIO_puts(out, "\n") <= 0)
-+        goto err;
-+    ret = 1;
-+ err:
-+    if (!ret)
-+        BIO_printf(bio_err, "could not save serial number to %s\n",
-+                   serialfile);
-+    BIO_free_all(out);
-+    return ret;
-+}
-+
-+
-+/*
-+ * Verify-related method definitions.
-+ */
-+
-+static int verify_command(const char *data, const char *digest, const char *queryfile,
-+                          const char *in, int token_in,
-+                          const char *CApath, const char *CAfile, const char *untrusted,
-+                          X509_VERIFY_PARAM *vpm)
-+{
-+    BIO *in_bio = NULL;
-+    PKCS7 *token = NULL;
-+    TS_RESP *response = NULL;
-+    TS_VERIFY_CTX *verify_ctx = NULL;
-+    int ret = 0;
-+
-+    if ((in_bio = BIO_new_file(in, "rb")) == NULL)
-+        goto end;
-+    if (token_in) {
-+        if ((token = d2i_PKCS7_bio(in_bio, NULL)) == NULL)
-+            goto end;
-+    } else {
-+        if ((response = d2i_TS_RESP_bio(in_bio, NULL)) == NULL)
-+            goto end;
-+    }
-+
-+    if ((verify_ctx = create_verify_ctx(data, digest, queryfile,
-+                                        CApath, CAfile, untrusted,
-+                                        vpm)) == NULL)
-+        goto end;
-+
-+    ret = token_in
-+        ? TS_RESP_verify_token(verify_ctx, token)
-+        : TS_RESP_verify_response(verify_ctx, response);
-+
-+ end:
-+    printf("Verification: ");
-+    if (ret)
-+        printf("OK\n");
-+    else {
-+        printf("FAILED\n");
-+        ERR_print_errors(bio_err);
-+    }
-+
-+    BIO_free_all(in_bio);
-+    PKCS7_free(token);
-+    TS_RESP_free(response);
-+    TS_VERIFY_CTX_free(verify_ctx);
-+    return ret;
-+}
-+
-+static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest,
-+                                        const char *queryfile,
-+                                        const char *CApath, const char *CAfile,
-+                                        const char *untrusted,
-+                                        X509_VERIFY_PARAM *vpm)
-+{
-+    TS_VERIFY_CTX *ctx = NULL;
-+    BIO *input = NULL;
-+    TS_REQ *request = NULL;
-+    int ret = 0;
-+    int f = 0;
-+
-+    if (data != NULL || digest != NULL) {
-+        if ((ctx = TS_VERIFY_CTX_new()) == NULL)
-+            goto err;
-+        f = TS_VFY_VERSION | TS_VFY_SIGNER;
-+        if (data != NULL) {
-+            BIO *out = NULL;
-+
-+            f |= TS_VFY_DATA;
-+            if ((out = BIO_new_file(data, "rb")) == NULL)
-+                goto err;
-+            if (TS_VERIFY_CTX_set_data(ctx, out) == NULL) {
-+                BIO_free_all(out);
-+                goto err;
-+            }
-+        } else if (digest != NULL) {
-+            long imprint_len;
-+            unsigned char *hexstr = OPENSSL_hexstr2buf(digest, &imprint_len);
-+            f |= TS_VFY_IMPRINT;
-+            if (TS_VERIFY_CTX_set_imprint(ctx, hexstr, imprint_len) == NULL) {
-+                BIO_printf(bio_err, "invalid digest string\n");
-+                goto err;
-+            }
-+        }
-+
-+    } else if (queryfile != NULL) {
-+        if ((input = BIO_new_file(queryfile, "rb")) == NULL)
-+            goto err;
-+        if ((request = d2i_TS_REQ_bio(input, NULL)) == NULL)
-+            goto err;
-+        if ((ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL)) == NULL)
-+            goto err;
-+    } else
-+        return NULL;
-+
-+    /* Add the signature verification flag and arguments. */
-+    TS_VERIFY_CTX_add_flags(ctx, f | TS_VFY_SIGNATURE);
-+
-+    /* Initialising the X509_STORE object. */
-+    if (TS_VERIFY_CTX_set_store(ctx, create_cert_store(CApath, CAfile, vpm))
-+            == NULL)
-+        goto err;
-+
-+    /* Loading untrusted certificates. */
-+    if (untrusted
-+        && TS_VERIFY_CTS_set_certs(ctx, TS_CONF_load_certs(untrusted)) == NULL)
-+        goto err;
-+    ret = 1;
-+
-+ err:
-+    if (!ret) {
-+        TS_VERIFY_CTX_free(ctx);
-+        ctx = NULL;
-+    }
-+    BIO_free_all(input);
-+    TS_REQ_free(request);
-+    return ctx;
-+}
-+
-+static X509_STORE *create_cert_store(const char *CApath, const char *CAfile,
-+                                     X509_VERIFY_PARAM *vpm)
-+{
-+    X509_STORE *cert_ctx = NULL;
-+    X509_LOOKUP *lookup = NULL;
-+    int i;
-+
-+    cert_ctx = X509_STORE_new();
-+    X509_STORE_set_verify_cb(cert_ctx, verify_cb);
-+    if (CApath != NULL) {
-+        lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
-+        if (lookup == NULL) {
-+            BIO_printf(bio_err, "memory allocation failure\n");
-+            goto err;
-+        }
-+        i = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
-+        if (!i) {
-+            BIO_printf(bio_err, "Error loading directory %s\n", CApath);
-+            goto err;
-+        }
-+    }
-+
-+    if (CAfile != NULL) {
-+        lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
-+        if (lookup == NULL) {
-+            BIO_printf(bio_err, "memory allocation failure\n");
-+            goto err;
-+        }
-+        i = X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM);
-+        if (!i) {
-+            BIO_printf(bio_err, "Error loading file %s\n", CAfile);
-+            goto err;
-+        }
-+    }
-+
-+    if (vpm != NULL)
-+        X509_STORE_set1_param(cert_ctx, vpm);
-+
-+    return cert_ctx;
-+
-+ err:
-+    X509_STORE_free(cert_ctx);
-+    return NULL;
-+}
-+
-+static int verify_cb(int ok, X509_STORE_CTX *ctx)
-+{
-+    return ok;
-+}
-+#endif  /* ndef OPENSSL_NO_TS */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/tsget.in b/CryptoPkg/Library/OpensslLib/openssl/apps/tsget.in
-new file mode 100644
-index 0000000..89d1bc7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/tsget.in
-@@ -0,0 +1,201 @@
-+#!{- $config{hashbangperl} -}
-+# Copyright (c) 2002 The OpenTSA Project. All rights reserved.
-+# Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+use strict;
-+use IO::Handle;
-+use Getopt::Std;
-+use File::Basename;
-+use WWW::Curl::Easy;
-+
-+use vars qw(%options);
-+
-+# Callback for reading the body.
-+sub read_body {
-+    my ($maxlength, $state) = @_;
-+    my $return_data = "";
-+    my $data_len = length ${$state->{data}};
-+    if ($state->{bytes} < $data_len) {
-+	$data_len = $data_len - $state->{bytes};
-+	$data_len = $maxlength if $data_len > $maxlength;
-+	$return_data = substr ${$state->{data}}, $state->{bytes}, $data_len;
-+	$state->{bytes} += $data_len;
-+    }
-+    return $return_data;
-+}
-+
-+# Callback for writing the body into a variable.
-+sub write_body {
-+    my ($data, $pointer) = @_;
-+    ${$pointer} .= $data;
-+    return length($data);
-+}
-+
-+# Initialise a new Curl object.
-+sub create_curl {
-+    my $url = shift;
-+
-+    # Create Curl object.
-+    my $curl = WWW::Curl::Easy::new();
-+
-+    # Error-handling related options.
-+    $curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
-+    $curl->setopt(CURLOPT_FAILONERROR, 1);
-+    $curl->setopt(CURLOPT_USERAGENT,
-+        "OpenTSA tsget.pl/openssl-{- $config{version} -}");
-+
-+    # Options for POST method.
-+    $curl->setopt(CURLOPT_UPLOAD, 1);
-+    $curl->setopt(CURLOPT_CUSTOMREQUEST, "POST");
-+    $curl->setopt(CURLOPT_HTTPHEADER,
-+		["Content-Type: application/timestamp-query",
-+		"Accept: application/timestamp-reply,application/timestamp-response"]);
-+    $curl->setopt(CURLOPT_READFUNCTION, \&read_body);
-+    $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($_[0]); });
-+
-+    # Options for getting the result.
-+    $curl->setopt(CURLOPT_WRITEFUNCTION, \&write_body);
-+
-+    # SSL related options.
-+    $curl->setopt(CURLOPT_SSLKEYTYPE, "PEM");
-+    $curl->setopt(CURLOPT_SSL_VERIFYPEER, 1);	# Verify server's certificate.
-+    $curl->setopt(CURLOPT_SSL_VERIFYHOST, 2);	# Check server's CN.
-+    $curl->setopt(CURLOPT_SSLKEY, $options{k}) if defined($options{k});
-+    $curl->setopt(CURLOPT_SSLKEYPASSWD, $options{p}) if defined($options{p});
-+    $curl->setopt(CURLOPT_SSLCERT, $options{c}) if defined($options{c});
-+    $curl->setopt(CURLOPT_CAINFO, $options{C}) if defined($options{C});
-+    $curl->setopt(CURLOPT_CAPATH, $options{P}) if defined($options{P});
-+    $curl->setopt(CURLOPT_RANDOM_FILE, $options{r}) if defined($options{r});
-+    $curl->setopt(CURLOPT_EGDSOCKET, $options{g}) if defined($options{g});
-+
-+    # Setting destination.
-+    $curl->setopt(CURLOPT_URL, $url);
-+
-+    return $curl;
-+}
-+
-+# Send a request and returns the body back.
-+sub get_timestamp {
-+    my $curl = shift;
-+    my $body = shift;
-+    my $ts_body;
-+    local $::error_buf;
-+
-+    # Error-handling related options.
-+    $curl->setopt(CURLOPT_ERRORBUFFER, "::error_buf");
-+
-+    # Options for POST method.
-+    $curl->setopt(CURLOPT_INFILE, {data => $body, bytes => 0});
-+    $curl->setopt(CURLOPT_INFILESIZE, length(${$body}));
-+
-+    # Options for getting the result.
-+    $curl->setopt(CURLOPT_FILE, \$ts_body);
-+
-+    # Send the request...
-+    my $error_code = $curl->perform();
-+    my $error_string;
-+    if ($error_code != 0) {
-+        my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE);
-+	$error_string = "could not get timestamp";
-+	$error_string .= ", http code: $http_code" unless $http_code == 0;
-+	$error_string .= ", curl code: $error_code";
-+	$error_string .= " ($::error_buf)" if defined($::error_buf);
-+    } else {
-+        my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE);
-+	if (lc($ct) ne "application/timestamp-reply"
-+	    && lc($ct) ne "application/timestamp-response") {
-+	    $error_string = "unexpected content type returned: $ct";
-+        }
-+    }
-+    return ($ts_body, $error_string);
-+
-+}
-+
-+# Print usage information and exists.
-+sub usage {
-+
-+    print STDERR "usage: $0 -h  [-e ] [-o ] ";
-+    print STDERR "[-v] [-d] [-k ] [-p ] ";
-+    print STDERR "[-c ] [-C ] [-P ] ";
-+    print STDERR "[-r ] [-g ] []...\n";
-+    exit 1;
-+}
-+
-+# ----------------------------------------------------------------------
-+#   Main program
-+# ----------------------------------------------------------------------
-+
-+# Getting command-line options (default comes from TSGET environment variable).
-+my $getopt_arg =  "h:e:o:vdk:p:c:C:P:r:g:";
-+if (exists $ENV{TSGET}) {
-+    my @old_argv = @ARGV;
-+    @ARGV = split /\s+/, $ENV{TSGET};
-+    getopts($getopt_arg, \%options) or usage;
-+    @ARGV = @old_argv;
-+}
-+getopts($getopt_arg, \%options) or usage;
-+
-+# Checking argument consistency.
-+if (!exists($options{h}) || (@ARGV == 0 && !exists($options{o}))
-+    || (@ARGV > 1 && exists($options{o}))) {
-+    print STDERR "Inconsistent command line options.\n";
-+    usage;
-+}
-+# Setting defaults.
-+@ARGV = ("-") unless @ARGV != 0;
-+$options{e} = ".tsr" unless defined($options{e});
-+
-+# Processing requests.
-+my $curl = create_curl $options{h};
-+undef $/;   # For reading whole files.
-+REQUEST: foreach (@ARGV) {
-+    my $input = $_;
-+    my ($base, $path) = fileparse($input, '\.[^.]*');
-+    my $output_base = $base . $options{e};
-+    my $output = defined($options{o}) ? $options{o} : $path . $output_base;
-+
-+    STDERR->printflush("$input: ") if $options{v};
-+    # Read request.
-+    my $body;
-+    if ($input eq "-") {
-+	# Read the request from STDIN;
-+	$body = ;
-+    } else {
-+	# Read the request from file.
-+        open INPUT, "<" . $input
-+	    or warn("$input: could not open input file: $!\n"), next REQUEST;
-+        $body = ;
-+        close INPUT
-+	    or warn("$input: could not close input file: $!\n"), next REQUEST;
-+    }
-+
-+    # Send request.
-+    STDERR->printflush("sending request") if $options{v};
-+
-+    my ($ts_body, $error) = get_timestamp $curl, \$body;
-+    if (defined($error)) {
-+	die "$input: fatal error: $error\n";
-+    }
-+    STDERR->printflush(", reply received") if $options{v};
-+
-+    # Write response.
-+    if ($output eq "-") {
-+	# Write to STDOUT.
-+        print $ts_body;
-+    } else {
-+	# Write to file.
-+        open OUTPUT, ">", $output
-+	    or warn("$output: could not open output file: $!\n"), next REQUEST;
-+        print OUTPUT $ts_body;
-+        close OUTPUT
-+	    or warn("$output: could not close output file: $!\n"), next REQUEST;
-+    }
-+    STDERR->printflush(", $output written.\n") if $options{v};
-+}
-+$curl->cleanup();
-+WWW::Curl::Easy::global_cleanup();
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/verify.c b/CryptoPkg/Library/OpensslLib/openssl/apps/verify.c
-new file mode 100644
-index 0000000..3c45663
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/verify.c
-@@ -0,0 +1,311 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "apps.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+static int cb(int ok, X509_STORE_CTX *ctx);
-+static int check(X509_STORE *ctx, const char *file,
-+                 STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
-+                 STACK_OF(X509_CRL) *crls, int show_chain);
-+static int v_verbose = 0, vflags = 0;
-+
-+typedef enum OPTION_choice {
-+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-+    OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE,
-+    OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
-+    OPT_V_ENUM,
-+    OPT_VERBOSE
-+} OPTION_CHOICE;
-+
-+OPTIONS verify_options[] = {
-+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"},
-+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
-+    {"help", OPT_HELP, '-', "Display this summary"},
-+    {"verbose", OPT_VERBOSE, '-',
-+        "Print extra information about the operations being performed."},
-+    {"CApath", OPT_CAPATH, '/', "A directory of trusted certificates"},
-+    {"CAfile", OPT_CAFILE, '<', "A file of trusted certificates"},
-+    {"no-CAfile", OPT_NOCAFILE, '-',
-+     "Do not load the default certificates file"},
-+    {"no-CApath", OPT_NOCAPATH, '-',
-+     "Do not load certificates from the default certificates directory"},
-+    {"untrusted", OPT_UNTRUSTED, '<', "A file of untrusted certificates"},
-+    {"trusted", OPT_TRUSTED, '<', "A file of trusted certificates"},
-+    {"CRLfile", OPT_CRLFILE, '<',
-+        "File containing one or more CRL's (in PEM format) to load"},
-+    {"crl_download", OPT_CRL_DOWNLOAD, '-',
-+        "Attempt to download CRL information for this certificate"},
-+    {"show_chain", OPT_SHOW_CHAIN, '-',
-+        "Display information about the certificate chain"},
-+    OPT_V_OPTIONS,
-+#ifndef OPENSSL_NO_ENGINE
-+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
-+#endif
-+    {NULL}
-+};
-+
-+int verify_main(int argc, char **argv)
-+{
-+    ENGINE *e = NULL;
-+    STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
-+    STACK_OF(X509_CRL) *crls = NULL;
-+    X509_STORE *store = NULL;
-+    X509_VERIFY_PARAM *vpm = NULL;
-+    const char *prog, *CApath = NULL, *CAfile = NULL;
-+    int noCApath = 0, noCAfile = 0;
-+    int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1;
-+    OPTION_CHOICE o;
-+
-+    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
-+        goto end;
-+
-+    prog = opt_init(argc, argv, verify_options);
-+    while ((o = opt_next()) != OPT_EOF) {
-+        switch (o) {
-+        case OPT_EOF:
-+        case OPT_ERR:
-+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-+            goto end;
-+        case OPT_HELP:
-+            opt_help(verify_options);
-+            BIO_printf(bio_err, "Recognized usages:\n");
-+            for (i = 0; i < X509_PURPOSE_get_count(); i++) {
-+                X509_PURPOSE *ptmp;
-+                ptmp = X509_PURPOSE_get0(i);
-+                BIO_printf(bio_err, "\t%-10s\t%s\n",
-+                        X509_PURPOSE_get0_sname(ptmp),
-+                        X509_PURPOSE_get0_name(ptmp));
-+            }
-+
-+            BIO_printf(bio_err, "Recognized verify names:\n");
-+            for (i = 0; i < X509_VERIFY_PARAM_get_count(); i++) {
-+                const X509_VERIFY_PARAM *vptmp;
-+                vptmp = X509_VERIFY_PARAM_get0(i);
-+                BIO_printf(bio_err, "\t%-10s\n",
-+                        X509_VERIFY_PARAM_get0_name(vptmp));
-+            }
-+            ret = 0;
-+            goto end;
-+        case OPT_V_CASES:
-+            if (!opt_verify(o, vpm))
-+                goto end;
-+            vpmtouched++;
-+            break;
-+        case OPT_CAPATH:
-+            CApath = opt_arg();
-+            break;
-+        case OPT_CAFILE:
-+            CAfile = opt_arg();
-+            break;
-+        case OPT_NOCAPATH:
-+            noCApath = 1;
-+            break;
-+        case OPT_NOCAFILE:
-+            noCAfile = 1;
-+            break;
-+        case OPT_UNTRUSTED:
-+            /* Zero or more times */
-+            if (!load_certs(opt_arg(), &untrusted, FORMAT_PEM, NULL,
-+                            "untrusted certificates"))
-+                goto end;
-+            break;
-+        case OPT_TRUSTED:
-+            /* Zero or more times */
-+            noCAfile = 1;
-+            noCApath = 1;
-+            if (!load_certs(opt_arg(), &trusted, FORMAT_PEM, NULL,
-+                            "trusted certificates"))
-+                goto end;
-+            break;
-+        case OPT_CRLFILE:
-+            /* Zero or more times */
-+            if (!load_crls(opt_arg(), &crls, FORMAT_PEM, NULL,
-+                           "other CRLs"))
-+                goto end;
-+            break;
-+        case OPT_CRL_DOWNLOAD:
-+            crl_download = 1;
-+            break;
-+        case OPT_ENGINE:
-+            if ((e = setup_engine(opt_arg(), 0)) == NULL) {
-+                /* Failure message already displayed */
-+                goto end;
-+            }
-+            break;
-+        case OPT_SHOW_CHAIN:
-+            show_chain = 1;
-+            break;
-+        case OPT_VERBOSE:
-+            v_verbose = 1;
-+            break;
-+        }
-+    }
-+    argc = opt_num_rest();
-+    argv = opt_rest();
-+    if (trusted != NULL && (CAfile || CApath)) {
-+        BIO_printf(bio_err,
-+                   "%s: Cannot use -trusted with -CAfile or -CApath\n",
-+                   prog);
-+        goto end;
-+    }
-+
-+    if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
-+        goto end;
-+    X509_STORE_set_verify_cb(store, cb);
-+
-+    if (vpmtouched)
-+        X509_STORE_set1_param(store, vpm);
-+
-+    ERR_clear_error();
-+
-+    if (crl_download)
-+        store_setup_crl_download(store);
-+
-+    ret = 0;
-+    if (argc < 1) {
-+        if (check(store, NULL, untrusted, trusted, crls, show_chain) != 1)
-+            ret = -1;
-+    } else {
-+        for (i = 0; i < argc; i++)
-+            if (check(store, argv[i], untrusted, trusted, crls,
-+                      show_chain) != 1)
-+                ret = -1;
-+    }
-+
-+ end:
-+    X509_VERIFY_PARAM_free(vpm);
-+    X509_STORE_free(store);
-+    sk_X509_pop_free(untrusted, X509_free);
-+    sk_X509_pop_free(trusted, X509_free);
-+    sk_X509_CRL_pop_free(crls, X509_CRL_free);
-+    release_engine(e);
-+    return (ret < 0 ? 2 : ret);
-+}
-+
-+static int check(X509_STORE *ctx, const char *file,
-+                 STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
-+                 STACK_OF(X509_CRL) *crls, int show_chain)
-+{
-+    X509 *x = NULL;
-+    int i = 0, ret = 0;
-+    X509_STORE_CTX *csc;
-+    STACK_OF(X509) *chain = NULL;
-+    int num_untrusted;
-+
-+    x = load_cert(file, FORMAT_PEM, "certificate file");
-+    if (x == NULL)
-+        goto end;
-+
-+    csc = X509_STORE_CTX_new();
-+    if (csc == NULL) {
-+        printf("error %s: X.509 store context allocation failed\n",
-+               (file == NULL) ? "stdin" : file);
-+        goto end;
-+    }
-+
-+    X509_STORE_set_flags(ctx, vflags);
-+    if (!X509_STORE_CTX_init(csc, ctx, x, uchain)) {
-+        printf("error %s: X.509 store context initialization failed\n",
-+               (file == NULL) ? "stdin" : file);
-+        goto end;
-+    }
-+    if (tchain)
-+        X509_STORE_CTX_set0_trusted_stack(csc, tchain);
-+    if (crls)
-+        X509_STORE_CTX_set0_crls(csc, crls);
-+    i = X509_verify_cert(csc);
-+    if (i > 0 && X509_STORE_CTX_get_error(csc) == X509_V_OK) {
-+        printf("%s: OK\n", (file == NULL) ? "stdin" : file);
-+        ret = 1;
-+        if (show_chain) {
-+            int j;
-+
-+            chain = X509_STORE_CTX_get1_chain(csc);
-+            num_untrusted = X509_STORE_CTX_get_num_untrusted(csc);
-+            printf("Chain:\n");
-+            for (j = 0; j < sk_X509_num(chain); j++) {
-+                X509 *cert = sk_X509_value(chain, j);
-+                printf("depth=%d: ", j);
-+                X509_NAME_print_ex_fp(stdout,
-+                                      X509_get_subject_name(cert),
-+                                      0, XN_FLAG_ONELINE);
-+                if (j < num_untrusted)
-+                    printf(" (untrusted)");
-+                printf("\n");
-+            }
-+            sk_X509_pop_free(chain, X509_free);
-+        }
-+    } else {
-+        printf("error %s: verification failed\n", (file == NULL) ? "stdin" : file);
-+    }
-+    X509_STORE_CTX_free(csc);
-+
-+ end:
-+    if (i <= 0)
-+        ERR_print_errors(bio_err);
-+    X509_free(x);
-+
-+    return ret;
-+}
-+
-+static int cb(int ok, X509_STORE_CTX *ctx)
-+{
-+    int cert_error = X509_STORE_CTX_get_error(ctx);
-+    X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
-+
-+    if (!ok) {
-+        if (current_cert) {
-+            X509_NAME_print_ex(bio_err,
-+                            X509_get_subject_name(current_cert),
-+                            0, XN_FLAG_ONELINE);
-+            BIO_printf(bio_err, "\n");
-+        }
-+        BIO_printf(bio_err, "%serror %d at %d depth lookup: %s\n",
-+               X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path] " : "",
-+               cert_error,
-+               X509_STORE_CTX_get_error_depth(ctx),
-+               X509_verify_cert_error_string(cert_error));
-+        switch (cert_error) {
-+        case X509_V_ERR_NO_EXPLICIT_POLICY:
-+            policies_print(ctx);
-+        case X509_V_ERR_CERT_HAS_EXPIRED:
-+
-+            /*
-+             * since we are just checking the certificates, it is ok if they
-+             * are self signed. But we should still warn the user.
-+             */
-+        case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
-+            /* Continue after extension errors too */
-+        case X509_V_ERR_INVALID_CA:
-+        case X509_V_ERR_INVALID_NON_CA:
-+        case X509_V_ERR_PATH_LENGTH_EXCEEDED:
-+        case X509_V_ERR_INVALID_PURPOSE:
-+        case X509_V_ERR_CRL_HAS_EXPIRED:
-+        case X509_V_ERR_CRL_NOT_YET_VALID:
-+        case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
-+            ok = 1;
-+        }
-+
-+        return ok;
-+
-+    }
-+    if (cert_error == X509_V_OK && ok == 2)
-+        policies_print(ctx);
-+    if (!v_verbose)
-+        ERR_clear_error();
-+    return (ok);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/version.c b/CryptoPkg/Library/OpensslLib/openssl/apps/version.c
-new file mode 100644
-index 0000000..e3c8299
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/version.c
-@@ -0,0 +1,140 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "apps.h"
-+#include 
-+#include 
-+#include 
-+#ifndef OPENSSL_NO_MD2
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_RC4
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_DES
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_IDEA
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_BF
-+# include 
-+#endif
-+
-+typedef enum OPTION_choice {
-+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-+    OPT_B, OPT_D, OPT_E, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A
-+} OPTION_CHOICE;
-+
-+OPTIONS version_options[] = {
-+    {"help", OPT_HELP, '-', "Display this summary"},
-+    {"a", OPT_A, '-', "Show all data"},
-+    {"b", OPT_B, '-', "Show build date"},
-+    {"d", OPT_D, '-', "Show configuration directory"},
-+    {"e", OPT_E, '-', "Show engines directory"},
-+    {"f", OPT_F, '-', "Show compiler flags used"},
-+    {"o", OPT_O, '-', "Show some internal datatype options"},
-+    {"p", OPT_P, '-', "Show target build platform"},
-+    {"v", OPT_V, '-', "Show library version"},
-+    {NULL}
-+};
-+
-+int version_main(int argc, char **argv)
-+{
-+    int ret = 1, dirty = 0;
-+    int cflags = 0, version = 0, date = 0, options = 0, platform = 0, dir = 0;
-+    int engdir = 0;
-+    char *prog;
-+    OPTION_CHOICE o;
-+
-+    prog = opt_init(argc, argv, version_options);
-+    while ((o = opt_next()) != OPT_EOF) {
-+        switch (o) {
-+        case OPT_EOF:
-+        case OPT_ERR:
-+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-+            goto end;
-+        case OPT_HELP:
-+            opt_help(version_options);
-+            ret = 0;
-+            goto end;
-+        case OPT_B:
-+            dirty = date = 1;
-+            break;
-+        case OPT_D:
-+            dirty = dir = 1;
-+            break;
-+        case OPT_E:
-+            dirty = engdir = 1;
-+            break;
-+        case OPT_F:
-+            dirty = cflags = 1;
-+            break;
-+        case OPT_O:
-+            dirty = options = 1;
-+            break;
-+        case OPT_P:
-+            dirty = platform = 1;
-+            break;
-+        case OPT_V:
-+            dirty = version = 1;
-+            break;
-+        case OPT_A:
-+            cflags = version = date = platform = dir = engdir = 1;
-+            break;
-+        }
-+    }
-+    if (!dirty)
-+        version = 1;
-+
-+    if (version) {
-+        if (OpenSSL_version_num() == OPENSSL_VERSION_NUMBER) {
-+            printf("%s\n", OpenSSL_version(OPENSSL_VERSION));
-+        } else {
-+            printf("%s (Library: %s)\n",
-+                   OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION));
-+        }
-+    }
-+    if (date)
-+        printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
-+    if (platform)
-+        printf("%s\n", OpenSSL_version(OPENSSL_PLATFORM));
-+    if (options) {
-+        printf("options:  ");
-+        printf("%s ", BN_options());
-+#ifndef OPENSSL_NO_MD2
-+        printf("%s ", MD2_options());
-+#endif
-+#ifndef OPENSSL_NO_RC4
-+        printf("%s ", RC4_options());
-+#endif
-+#ifndef OPENSSL_NO_DES
-+        printf("%s ", DES_options());
-+#endif
-+#ifndef OPENSSL_NO_IDEA
-+        printf("%s ", IDEA_options());
-+#endif
-+#ifndef OPENSSL_NO_BF
-+        printf("%s ", BF_options());
-+#endif
-+        printf("\n");
-+    }
-+    if (cflags)
-+        printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
-+    if (dir)
-+        printf("%s\n", OpenSSL_version(OPENSSL_DIR));
-+    if (engdir)
-+        printf("%s\n", OpenSSL_version(OPENSSL_ENGINES_DIR));
-+    ret = 0;
-+ end:
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/vms_decc_init.c b/CryptoPkg/Library/OpensslLib/openssl/apps/vms_decc_init.c
-new file mode 100644
-index 0000000..f83f716
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/vms_decc_init.c
-@@ -0,0 +1,214 @@
-+/*
-+ * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#if defined( __VMS) && !defined( OPENSSL_NO_DECC_INIT) && \
-+ defined( __DECC) && !defined( __VAX) && (__CRTL_VER >= 70301000)
-+# define USE_DECC_INIT 1
-+#endif
-+
-+#ifdef USE_DECC_INIT
-+
-+/*
-+ * ----------------------------------------------------------------------
-+ * decc_init() On non-VAX systems, uses LIB$INITIALIZE to set a collection
-+ * of C RTL features without using the DECC$* logical name method.
-+ * ----------------------------------------------------------------------
-+ */
-+
-+# include 
-+# include 
-+# include 
-+
-+# include "apps.h"
-+
-+/* Global storage. */
-+
-+/* Flag to sense if decc_init() was called. */
-+
-+int decc_init_done = -1;
-+
-+/* Structure to hold a DECC$* feature name and its desired value. */
-+
-+typedef struct {
-+    char *name;
-+    int value;
-+} decc_feat_t;
-+
-+/*
-+ * Array of DECC$* feature names and their desired values. Note:
-+ * DECC$ARGV_PARSE_STYLE is the urgent one.
-+ */
-+
-+decc_feat_t decc_feat_array[] = {
-+    /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
-+    {"DECC$ARGV_PARSE_STYLE", 1},
-+
-+    /* Preserve case for file names on ODS5 disks. */
-+    {"DECC$EFS_CASE_PRESERVE", 1},
-+
-+    /*
-+     * Enable multiple dots (and most characters) in ODS5 file names, while
-+     * preserving VMS-ness of ";version".
-+     */
-+    {"DECC$EFS_CHARSET", 1},
-+
-+    /* List terminator. */
-+    {(char *)NULL, 0}
-+};
-+
-+
-+char **copy_argv(int *argc, char *argv[])
-+{
-+    /*-
-+     * The note below is for historical purpose.  On VMS now we always
-+     * copy argv "safely."
-+     *
-+     * 2011-03-22 SMS.
-+     * If we have 32-bit pointers everywhere, then we're safe, and
-+     * we bypass this mess, as on non-VMS systems.
-+     * Problem 1: Compaq/HP C before V7.3 always used 32-bit
-+     * pointers for argv[].
-+     * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers
-+     * everywhere else, we always allocate and use a 64-bit
-+     * duplicate of argv[].
-+     * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed
-+     * to NULL-terminate a 64-bit argv[].  (As this was written, the
-+     * compiler ECO was available only on IA64.)
-+     * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a
-+     * 64-bit argv[argc] for NULL, and, if necessary, use a
-+     * (properly) NULL-terminated (64-bit) duplicate of argv[].
-+     * The same code is used in either case to duplicate argv[].
-+     * Some of these decisions could be handled in preprocessing,
-+     * but the code tends to get even uglier, and the penalty for
-+     * deciding at compile- or run-time is tiny.
-+     */
-+
-+    int i, count = *argc;
-+    char **newargv = app_malloc(sizeof(*newargv) * (count + 1), "argv copy");
-+
-+    for (i = 0; i < count; i++)
-+        newargv[i] = argv[i];
-+    newargv[i] = NULL;
-+    *argc = i;
-+    return newargv;
-+}
-+
-+/* LIB$INITIALIZE initialization function. */
-+
-+static void decc_init(void)
-+{
-+    char *openssl_debug_decc_init;
-+    int verbose = 0;
-+    int feat_index;
-+    int feat_value;
-+    int feat_value_max;
-+    int feat_value_min;
-+    int i;
-+    int sts;
-+
-+    /* Get debug option. */
-+    openssl_debug_decc_init = getenv("OPENSSL_DEBUG_DECC_INIT");
-+    if (openssl_debug_decc_init != NULL) {
-+        verbose = strtol(openssl_debug_decc_init, NULL, 10);
-+        if (verbose <= 0) {
-+            verbose = 1;
-+        }
-+    }
-+
-+    /* Set the global flag to indicate that LIB$INITIALIZE worked. */
-+    decc_init_done = 1;
-+
-+    /* Loop through all items in the decc_feat_array[]. */
-+
-+    for (i = 0; decc_feat_array[i].name != NULL; i++) {
-+        /* Get the feature index. */
-+        feat_index = decc$feature_get_index(decc_feat_array[i].name);
-+        if (feat_index >= 0) {
-+            /* Valid item.  Collect its properties. */
-+            feat_value = decc$feature_get_value(feat_index, 1);
-+            feat_value_min = decc$feature_get_value(feat_index, 2);
-+            feat_value_max = decc$feature_get_value(feat_index, 3);
-+
-+            /* Check the validity of our desired value. */
-+            if ((decc_feat_array[i].value >= feat_value_min) &&
-+                (decc_feat_array[i].value <= feat_value_max)) {
-+                /* Valid value.  Set it if necessary. */
-+                if (feat_value != decc_feat_array[i].value) {
-+                    sts = decc$feature_set_value(feat_index,
-+                                                 1, decc_feat_array[i].value);
-+
-+                    if (verbose > 1) {
-+                        fprintf(stderr, " %s = %d, sts = %d.\n",
-+                                decc_feat_array[i].name,
-+                                decc_feat_array[i].value, sts);
-+                    }
-+                }
-+            } else {
-+                /* Invalid DECC feature value. */
-+                fprintf(stderr,
-+                        " INVALID DECC$FEATURE VALUE, %d: %d <= %s <= %d.\n",
-+                        feat_value,
-+                        feat_value_min, decc_feat_array[i].name,
-+                        feat_value_max);
-+            }
-+        } else {
-+            /* Invalid DECC feature name. */
-+            fprintf(stderr,
-+                    " UNKNOWN DECC$FEATURE: %s.\n", decc_feat_array[i].name);
-+        }
-+    }
-+
-+    if (verbose > 0) {
-+        fprintf(stderr, " DECC_INIT complete.\n");
-+    }
-+}
-+
-+/* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
-+
-+# pragma nostandard
-+
-+/*
-+ * Establish the LIB$INITIALIZE PSECTs, with proper alignment and other
-+ * attributes.  Note that "nopic" is significant only on VAX.
-+ */
-+# pragma extern_model save
-+
-+# if __INITIAL_POINTER_SIZE == 64
-+#  define PSECT_ALIGN 3
-+# else
-+#  define PSECT_ALIGN 2
-+# endif
-+
-+# pragma extern_model strict_refdef "LIB$INITIALIZ" PSECT_ALIGN, nopic, nowrt
-+const int spare[8] = { 0 };
-+
-+# pragma extern_model strict_refdef "LIB$INITIALIZE" PSECT_ALIGN, nopic, nowrt
-+void (*const x_decc_init) () = decc_init;
-+
-+# pragma extern_model restore
-+
-+/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
-+
-+# pragma extern_model save
-+
-+int LIB$INITIALIZE(void);
-+
-+# pragma extern_model strict_refdef
-+int dmy_lib$initialize = (int)LIB$INITIALIZE;
-+
-+# pragma extern_model restore
-+
-+# pragma standard
-+
-+#else                           /* def USE_DECC_INIT */
-+
-+/* Dummy code to avoid a %CC-W-EMPTYFILE complaint. */
-+int decc_init_dummy(void);
-+
-+#endif                          /* def USE_DECC_INIT */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/vms_term_sock.c b/CryptoPkg/Library/OpensslLib/openssl/apps/vms_term_sock.c
-new file mode 100644
-index 0000000..a7d87ff
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/vms_term_sock.c
-@@ -0,0 +1,590 @@
-+/*
-+ * Copyright 2016 VMS Software, Inc. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifdef __VMS
-+# define OPENSSL_SYS_VMS
-+# pragma message disable DOLLARID
-+
-+
-+# include 
-+
-+# if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
-+/*
-+ * On VMS, you need to define this to get the declaration of fileno().  The
-+ * value 2 is to make sure no function defined in POSIX-2 is left undefined.
-+ */
-+#  define _POSIX_C_SOURCE 2
-+# endif
-+
-+# include 
-+
-+# undef _POSIX_C_SOURCE
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# ifdef __alpha
-+#  include 
-+# else
-+typedef struct _iosb {           /* Copied from IOSBDEF.H for Alpha  */
-+#  pragma __nomember_alignment
-+    __union  {
-+        __struct  {
-+            unsigned short int iosb$w_status; /* Final I/O status           */
-+            __union  {
-+                __struct  {             /* 16-bit byte count variant        */
-+                    unsigned short int iosb$w_bcnt; /* 16-bit byte count    */
-+                    __union  {
-+                        unsigned int iosb$l_dev_depend; /* 32-bit device dependent info */
-+                        unsigned int iosb$l_pid; /* 32-bit pid              */
-+                    } iosb$r_l;
-+                } iosb$r_bcnt_16;
-+                __struct  {             /* 32-bit byte count variant        */
-+                    unsigned int iosb$l_bcnt; /* 32-bit byte count (unaligned) */
-+                    unsigned short int iosb$w_dev_depend_high; /* 16-bit device dependent info */
-+                } iosb$r_bcnt_32;
-+            } iosb$r_devdepend;
-+        } iosb$r_io_64;
-+        __struct  {
-+            __union  {
-+                unsigned int iosb$l_getxxi_status; /* Final GETxxI status   */
-+                unsigned int iosb$l_reg_status; /* Final $Registry status   */
-+            } iosb$r_l_status;
-+            unsigned int iosb$l_reserved; /* Reserved field                 */
-+        } iosb$r_get_64;
-+    } iosb$r_io_get;
-+} IOSB;
-+
-+#  if !defined(__VAXC)
-+#   define iosb$w_status iosb$r_io_get.iosb$r_io_64.iosb$w_status
-+#   define iosb$w_bcnt iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_16.iosb$w_bcnt
-+#   define iosb$r_l        iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_16.iosb$r_l
-+#   define iosb$l_dev_depend iosb$r_l.iosb$l_dev_depend
-+#   define iosb$l_pid iosb$r_l.iosb$l_pid
-+#   define iosb$l_bcnt iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_32.iosb$l_bcnt
-+#   define iosb$w_dev_depend_high iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_32.iosb$w_dev_depend_high
-+#   define iosb$l_getxxi_status iosb$r_io_get.iosb$r_get_64.iosb$r_l_status.iosb$l_getxxi_status
-+#   define iosb$l_reg_status iosb$r_io_get.iosb$r_get_64.iosb$r_l_status.iosb$l_reg_status
-+#  endif          /* #if !defined(__VAXC) */
-+
-+# endif  /* End of IOSBDEF */
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+
-+# include "vms_term_sock.h"
-+
-+# ifdef __alpha
-+static struct _iosb TerminalDeviceIosb;
-+# else
-+IOSB TerminalDeviceIosb;
-+# endif
-+
-+static char TerminalDeviceBuff[255 + 2];
-+static int TerminalSocketPair[2] = {0, 0};
-+static unsigned short TerminalDeviceChan = 0;
-+
-+static int CreateSocketPair (int, int, int, int *);
-+static void SocketPairTimeoutAst (int);
-+static int TerminalDeviceAst (int);
-+static void LogMessage (char *, ...);
-+
-+/*
-+** Socket Pair Timeout Value (must be 0-59 seconds)
-+*/
-+# define SOCKET_PAIR_TIMEOUT_VALUE 20
-+
-+/*
-+** Socket Pair Timeout Block which is passed to timeout AST
-+*/
-+typedef struct _SocketPairTimeoutBlock {
-+    unsigned short SockChan1;
-+    unsigned short SockChan2;
-+} SPTB;
-+
-+# ifdef TERM_SOCK_TEST
-+
-+/*----------------------------------------------------------------------------*/
-+/*                                                                            */
-+/*----------------------------------------------------------------------------*/
-+int main (int argc, char *argv[], char *envp[])
-+{
-+    char TermBuff[80];
-+    int TermSock,
-+        status,
-+        len;
-+
-+    LogMessage ("Enter 'q' or 'Q' to quit ...");
-+    while (strcasecmp (TermBuff, "Q")) {
-+        /*
-+        ** Create the terminal socket
-+        */
-+        status = TerminalSocket (TERM_SOCK_CREATE, &TermSock);
-+        if (status != TERM_SOCK_SUCCESS)
-+            exit (1);
-+
-+        /*
-+        ** Process the terminal input
-+        */
-+        LogMessage ("Waiting on terminal I/O ...\n");
-+        len = recv (TermSock, TermBuff, sizeof (TermBuff), 0) ;
-+        TermBuff[len] = '\0';
-+        LogMessage ("Received terminal I/O [%s]", TermBuff);
-+
-+        /*
-+        ** Delete the terminal socket
-+        */
-+        status = TerminalSocket (TERM_SOCK_DELETE, &TermSock);
-+        if (status != TERM_SOCK_SUCCESS)
-+            exit (1);
-+    }
-+
-+    return 1;
-+
-+}
-+# endif
-+
-+/*----------------------------------------------------------------------------*/
-+/*                                                                            */
-+/*----------------------------------------------------------------------------*/
-+int TerminalSocket (int FunctionCode, int *ReturnSocket)
-+{
-+    int status;
-+    $DESCRIPTOR (TerminalDeviceDesc, "SYS$COMMAND");
-+
-+    /*
-+    ** Process the requested function code
-+    */
-+    switch (FunctionCode) {
-+    case TERM_SOCK_CREATE:
-+        /*
-+        ** Create a socket pair
-+        */
-+        status = CreateSocketPair (AF_INET, SOCK_STREAM, 0, TerminalSocketPair);
-+        if (status == -1) {
-+            LogMessage ("TerminalSocket: CreateSocketPair () - %08X", status);
-+            if (TerminalSocketPair[0])
-+                close (TerminalSocketPair[0]);
-+            if (TerminalSocketPair[1])
-+                close (TerminalSocketPair[1]);
-+            return (TERM_SOCK_FAILURE);
-+        }
-+
-+        /*
-+        ** Assign a channel to the terminal device
-+        */
-+        status = sys$assign (&TerminalDeviceDesc,
-+                             &TerminalDeviceChan,
-+                             0, 0, 0);
-+        if (! (status & 1)) {
-+            LogMessage ("TerminalSocket: SYS$ASSIGN () - %08X", status);
-+            close (TerminalSocketPair[0]);
-+            close (TerminalSocketPair[1]);
-+            return (TERM_SOCK_FAILURE);
-+        }
-+
-+        /*
-+        ** Queue an async IO to the terminal device
-+        */
-+        status = sys$qio (EFN$C_ENF,
-+                          TerminalDeviceChan,
-+                          IO$_READVBLK,
-+                          &TerminalDeviceIosb,
-+                          TerminalDeviceAst,
-+                          0,
-+                          TerminalDeviceBuff,
-+                          sizeof (TerminalDeviceBuff) - 2,
-+                          0, 0, 0, 0);
-+        if (! (status & 1)) {
-+            LogMessage ("TerminalSocket: SYS$QIO () - %08X", status);
-+            close (TerminalSocketPair[0]);
-+            close (TerminalSocketPair[1]);
-+            return (TERM_SOCK_FAILURE);
-+        }
-+
-+        /*
-+        ** Return the input side of the socket pair
-+        */
-+        *ReturnSocket = TerminalSocketPair[1];
-+        break;
-+
-+    case TERM_SOCK_DELETE:
-+        /*
-+        ** Cancel any pending IO on the terminal channel
-+        */
-+        status = sys$cancel (TerminalDeviceChan);
-+        if (! (status & 1)) {
-+            LogMessage ("TerminalSocket: SYS$CANCEL () - %08X", status);
-+            close (TerminalSocketPair[0]);
-+            close (TerminalSocketPair[1]);
-+            return (TERM_SOCK_FAILURE);
-+        }
-+
-+        /*
-+	** Deassign the terminal channel
-+	*/
-+        status = sys$dassgn (TerminalDeviceChan);
-+        if (! (status & 1)) {
-+            LogMessage ("TerminalSocket: SYS$DASSGN () - %08X", status);
-+            close (TerminalSocketPair[0]);
-+            close (TerminalSocketPair[1]);
-+            return (TERM_SOCK_FAILURE);
-+        }
-+
-+        /*
-+        ** Close the terminal socket pair
-+        */
-+        close (TerminalSocketPair[0]);
-+        close (TerminalSocketPair[1]);
-+
-+        /*
-+	** Return the initialized socket
-+	*/
-+        *ReturnSocket = 0;
-+        break;
-+
-+    default:
-+        /*
-+	** Invalid function code
-+	*/
-+        LogMessage ("TerminalSocket: Invalid Function Code - %d", FunctionCode);
-+        return (TERM_SOCK_FAILURE);
-+        break;
-+    }
-+
-+    /*
-+    ** Return success
-+    */
-+    return (TERM_SOCK_SUCCESS);
-+
-+}
-+
-+/*----------------------------------------------------------------------------*/
-+/*                                                                            */
-+/*----------------------------------------------------------------------------*/
-+static int CreateSocketPair (int SocketFamily,
-+                             int SocketType,
-+                             int SocketProtocol,
-+                             int *SocketPair)
-+{
-+    struct dsc$descriptor AscTimeDesc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
-+    static const char* LocalHostAddr = {"127.0.0.1"};
-+    unsigned short TcpAcceptChan = 0,
-+        TcpDeviceChan = 0;
-+    unsigned long BinTimeBuff[2];
-+    struct sockaddr_in sin;
-+    char AscTimeBuff[32];
-+    short LocalHostPort;
-+    int status;
-+    unsigned int slen;
-+
-+# ifdef __alpha
-+    struct _iosb iosb;
-+# else
-+    IOSB iosb;
-+# endif
-+
-+    int SockDesc1 = 0,
-+        SockDesc2 = 0;
-+    SPTB sptb;
-+    $DESCRIPTOR (TcpDeviceDesc, "TCPIP$DEVICE");
-+
-+    /*
-+    ** Create a socket
-+    */
-+    SockDesc1 = socket (SocketFamily, SocketType, 0);
-+    if (SockDesc1 < 0) {
-+        LogMessage ("CreateSocketPair: socket () - %d", errno);
-+        return (-1);
-+    }
-+
-+    /*
-+    ** Initialize the socket information
-+    */
-+    slen = sizeof (sin);
-+    memset ((char *) &sin, 0, slen);
-+    sin.sin_family = SocketFamily;
-+    sin.sin_addr.s_addr = inet_addr (LocalHostAddr);
-+    sin.sin_port = 0;
-+
-+    /*
-+    ** Bind the socket to the local IP
-+    */
-+    status = bind (SockDesc1, (struct sockaddr *) &sin, slen);
-+    if (status < 0) {
-+        LogMessage ("CreateSocketPair: bind () - %d", errno);
-+        close (SockDesc1);
-+        return (-1);
-+    }
-+
-+    /*
-+    ** Get the socket name so we can save the port number
-+    */
-+    status = getsockname (SockDesc1, (struct sockaddr *) &sin, &slen);
-+    if (status < 0) {
-+        LogMessage ("CreateSocketPair: getsockname () - %d", errno);
-+        close (SockDesc1);
-+        return (-1);
-+    } else
-+        LocalHostPort = sin.sin_port;
-+
-+    /*
-+    ** Setup a listen for the socket
-+    */
-+    listen (SockDesc1, 5);
-+
-+    /*
-+    ** Get the binary (64-bit) time of the specified timeout value
-+    */
-+    sprintf (AscTimeBuff, "0 0:0:%02d.00", SOCKET_PAIR_TIMEOUT_VALUE);
-+    AscTimeDesc.dsc$w_length = strlen (AscTimeBuff);
-+    AscTimeDesc.dsc$a_pointer = AscTimeBuff;
-+    status = sys$bintim (&AscTimeDesc, BinTimeBuff);
-+    if (! (status & 1)) {
-+        LogMessage ("CreateSocketPair: SYS$BINTIM () - %08X", status);
-+        close (SockDesc1);
-+        return (-1);
-+    }
-+
-+    /*
-+    ** Assign another channel to the TCP/IP device for the accept.
-+    ** This is the channel that ends up being connected to.
-+    */
-+    status = sys$assign (&TcpDeviceDesc, &TcpDeviceChan, 0, 0, 0);
-+    if (! (status & 1)) {
-+        LogMessage ("CreateSocketPair: SYS$ASSIGN () - %08X", status);
-+        close (SockDesc1);
-+        return (-1);
-+    }
-+
-+    /*
-+    ** Get the channel of the first socket for the accept
-+    */
-+    TcpAcceptChan = decc$get_sdc (SockDesc1);
-+
-+    /*
-+    ** Perform the accept using $QIO so we can do this asynchronously
-+    */
-+    status = sys$qio (EFN$C_ENF,
-+                      TcpAcceptChan,
-+                      IO$_ACCESS | IO$M_ACCEPT,
-+                      &iosb,
-+                      0, 0, 0, 0, 0,
-+                      &TcpDeviceChan,
-+                      0, 0);
-+    if (! (status & 1)) {
-+        LogMessage ("CreateSocketPair: SYS$QIO () - %08X", status);
-+        close (SockDesc1);
-+        sys$dassgn (TcpDeviceChan);
-+        return (-1);
-+    }
-+
-+    /*
-+    ** Create the second socket to do the connect
-+    */
-+    SockDesc2 = socket (SocketFamily, SocketType, 0);
-+    if (SockDesc2 < 0) {
-+        LogMessage ("CreateSocketPair: socket () - %d", errno);
-+        sys$cancel (TcpAcceptChan);
-+        close (SockDesc1);
-+        sys$dassgn (TcpDeviceChan);
-+        return (-1) ;
-+    }
-+
-+    /*
-+    ** Setup the Socket Pair Timeout Block
-+    */
-+    sptb.SockChan1 = TcpAcceptChan;
-+    sptb.SockChan2 = decc$get_sdc (SockDesc2);
-+
-+    /*
-+    ** Before we block on the connect, set a timer that can cancel I/O on our
-+    ** two sockets if it never connects.
-+    */
-+    status = sys$setimr (EFN$C_ENF,
-+                         BinTimeBuff,
-+                         SocketPairTimeoutAst,
-+                         &sptb,
-+                         0);
-+    if (! (status & 1)) {
-+        LogMessage ("CreateSocketPair: SYS$SETIMR () - %08X", status);
-+        sys$cancel (TcpAcceptChan);
-+        close (SockDesc1);
-+        close (SockDesc2);
-+        sys$dassgn (TcpDeviceChan);
-+        return (-1);
-+    }
-+
-+    /*
-+    ** Now issue the connect
-+    */
-+    memset ((char *) &sin, 0, sizeof (sin)) ;
-+    sin.sin_family = SocketFamily;
-+    sin.sin_addr.s_addr = inet_addr (LocalHostAddr) ;
-+    sin.sin_port = LocalHostPort ;
-+
-+    status = connect (SockDesc2, (struct sockaddr *) &sin, sizeof (sin));
-+    if (status < 0 ) {
-+        LogMessage ("CreateSocketPair: connect () - %d", errno);
-+        sys$cantim (&sptb, 0);
-+        sys$cancel (TcpAcceptChan);
-+        close (SockDesc1);
-+        close (SockDesc2);
-+        sys$dassgn (TcpDeviceChan);
-+        return (-1);
-+    }
-+
-+    /*
-+    ** Wait for the asynch $QIO to finish.  Note that if the I/O was aborted
-+    ** (SS$_ABORT), then we probably canceled it from the AST routine - so log
-+    ** a timeout.
-+    */
-+    status = sys$synch (EFN$C_ENF, &iosb);
-+    if (! (iosb.iosb$w_status & 1)) {
-+        if (iosb.iosb$w_status == SS$_ABORT)
-+            LogMessage ("CreateSocketPair: SYS$QIO(iosb) timeout");
-+        else {
-+            LogMessage ("CreateSocketPair: SYS$QIO(iosb) - %d",
-+                        iosb.iosb$w_status);
-+            sys$cantim (&sptb, 0);
-+        }
-+        close (SockDesc1);
-+        close (SockDesc2);
-+        sys$dassgn (TcpDeviceChan);
-+        return (-1);
-+    }
-+
-+    /*
-+    ** Here we're successfully connected, so cancel the timer, convert the
-+    ** I/O channel to a socket fd, close the listener socket and return the
-+    ** connected pair.
-+    */
-+    sys$cantim (&sptb, 0);
-+
-+    close (SockDesc1) ;
-+    SocketPair[0] = SockDesc2 ;
-+    SocketPair[1] = socket_fd (TcpDeviceChan);
-+
-+    return (0) ;
-+
-+}
-+
-+/*----------------------------------------------------------------------------*/
-+/*                                                                            */
-+/*----------------------------------------------------------------------------*/
-+static void SocketPairTimeoutAst (int astparm)
-+{
-+    SPTB *sptb = (SPTB *) astparm;
-+
-+    sys$cancel (sptb->SockChan2); /* Cancel the connect() */
-+    sys$cancel (sptb->SockChan1); /* Cancel the accept() */
-+
-+    return;
-+
-+}
-+
-+/*----------------------------------------------------------------------------*/
-+/*                                                                            */
-+/*----------------------------------------------------------------------------*/
-+static int TerminalDeviceAst (int astparm)
-+{
-+    int status;
-+
-+    /*
-+    ** Terminate the terminal buffer
-+    */
-+    TerminalDeviceBuff[TerminalDeviceIosb.iosb$w_bcnt] = '\0';
-+    strcat (TerminalDeviceBuff, "\n");
-+
-+    /*
-+    ** Send the data read from the terminal device throught the socket pair
-+    */
-+    send (TerminalSocketPair[0], TerminalDeviceBuff,
-+          TerminalDeviceIosb.iosb$w_bcnt + 1, 0);
-+
-+    /*
-+    ** Queue another async IO to the terminal device
-+    */
-+    status = sys$qio (EFN$C_ENF,
-+                      TerminalDeviceChan,
-+                      IO$_READVBLK,
-+                      &TerminalDeviceIosb,
-+                      TerminalDeviceAst,
-+                      0,
-+                      TerminalDeviceBuff,
-+                      sizeof (TerminalDeviceBuff) - 1,
-+                      0, 0, 0, 0);
-+
-+    /*
-+    ** Return status
-+    */
-+    return status;
-+
-+}
-+
-+/*----------------------------------------------------------------------------*/
-+/*                                                                            */
-+/*----------------------------------------------------------------------------*/
-+static void LogMessage (char *msg, ...)
-+{
-+    char *Month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
-+                     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-+    static unsigned int pid = 0;
-+    va_list args;
-+    time_t CurTime;
-+    struct tm *LocTime;
-+    char MsgBuff[256];
-+
-+    /*
-+    ** Get the process pid
-+    */
-+    if (pid == 0)
-+        pid = getpid ();
-+
-+    /*
-+    ** Convert the current time into local time
-+    */
-+    CurTime = time (NULL);
-+    LocTime = localtime (&CurTime);
-+
-+    /*
-+    ** Format the message buffer
-+    */
-+    sprintf (MsgBuff, "%02d-%s-%04d %02d:%02d:%02d [%08X] %s\n",
-+             LocTime->tm_mday, Month[LocTime->tm_mon],
-+             (LocTime->tm_year + 1900), LocTime->tm_hour, LocTime->tm_min,
-+             LocTime->tm_sec, pid, msg);
-+
-+    /*
-+    ** Get any variable arguments and add them to the print of the message
-+    ** buffer
-+    */
-+    va_start (args, msg);
-+    vfprintf (stderr, MsgBuff, args);
-+    va_end (args);
-+
-+    /*
-+    ** Flush standard error output
-+    */
-+    fsync (fileno (stderr));
-+
-+    return;
-+
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/vms_term_sock.h b/CryptoPkg/Library/OpensslLib/openssl/apps/vms_term_sock.h
-new file mode 100644
-index 0000000..662fa0a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/vms_term_sock.h
-@@ -0,0 +1,30 @@
-+/*
-+ * Copyright 2016 VMS Software, Inc. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef TERM_SOCK_H
-+# define TERM_SOCK_H
-+
-+/*
-+** Terminal Socket Function Codes
-+*/
-+# define TERM_SOCK_CREATE       1
-+# define TERM_SOCK_DELETE       2
-+
-+/*
-+** Terminal Socket Status Codes
-+*/
-+# define TERM_SOCK_FAILURE      0
-+# define TERM_SOCK_SUCCESS      1
-+
-+/*
-+** Terminal Socket Prototype
-+*/
-+int TerminalSocket (int FunctionCode, int *ReturnSocket);
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/win32_init.c b/CryptoPkg/Library/OpensslLib/openssl/apps/win32_init.c
-new file mode 100644
-index 0000000..ebe92bc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/win32_init.c
-@@ -0,0 +1,307 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#if defined(CP_UTF8)
-+
-+static UINT saved_cp;
-+static int newargc;
-+static char **newargv;
-+
-+static void cleanup(void)
-+{
-+    int i;
-+
-+    SetConsoleOutputCP(saved_cp);
-+
-+    for (i = 0; i < newargc; i++)
-+        free(newargv[i]);
-+
-+    free(newargv);
-+}
-+
-+/*
-+ * Incrementally [re]allocate newargv and keep it NULL-terminated.
-+ */
-+static int validate_argv(int argc)
-+{
-+    static int size = 0;
-+
-+    if (argc >= size) {
-+        char **ptr;
-+
-+        while (argc >= size)
-+            size += 64;
-+
-+        ptr = realloc(newargv, size * sizeof(newargv[0]));
-+        if (ptr == NULL)
-+            return 0;
-+
-+        (newargv = ptr)[argc] = NULL;
-+    } else {
-+        newargv[argc] = NULL;
-+    }
-+
-+    return 1;
-+}
-+
-+static int process_glob(WCHAR *wstr, int wlen)
-+{
-+    int i, slash, udlen;
-+    WCHAR saved_char;
-+    WIN32_FIND_DATAW data;
-+    HANDLE h;
-+
-+    /*
-+     * Note that we support wildcard characters only in filename part
-+     * of the path, and not in directories. Windows users are used to
-+     * this, that's why recursive glob processing is not implemented.
-+     */
-+    /*
-+     * Start by looking for last slash or backslash, ...
-+     */
-+    for (slash = 0, i = 0; i < wlen; i++)
-+        if (wstr[i] == L'/' || wstr[i] == L'\\')
-+            slash = i + 1;
-+    /*
-+     * ... then look for asterisk or question mark in the file name.
-+     */
-+    for (i = slash; i < wlen; i++)
-+        if (wstr[i] == L'*' || wstr[i] == L'?')
-+            break;
-+
-+    if (i == wlen)
-+        return 0;   /* definitely not a glob */
-+
-+    saved_char = wstr[wlen];
-+    wstr[wlen] = L'\0';
-+    h = FindFirstFileW(wstr, &data);
-+    wstr[wlen] = saved_char;
-+    if (h == INVALID_HANDLE_VALUE)
-+        return 0;   /* not a valid glob, just pass... */
-+
-+    if (slash)
-+        udlen = WideCharToMultiByte(CP_UTF8, 0, wstr, slash,
-+                                    NULL, 0, NULL, NULL);
-+    else
-+        udlen = 0;
-+
-+    do {
-+        int uflen;
-+        char *arg;
-+
-+        /*
-+         * skip over . and ..
-+         */
-+        if (data.cFileName[0] == L'.') {
-+            if ((data.cFileName[1] == L'\0') ||
-+                (data.cFileName[1] == L'.' && data.cFileName[2] == L'\0'))
-+                continue;
-+        }
-+
-+        if (!validate_argv(newargc + 1))
-+            break;
-+
-+        /*
-+         * -1 below means "scan for trailing '\0' *and* count it",
-+         * so that |uflen| covers even trailing '\0'.
-+         */
-+        uflen = WideCharToMultiByte(CP_UTF8, 0, data.cFileName, -1,
-+                                    NULL, 0, NULL, NULL);
-+
-+        arg = malloc(udlen + uflen);
-+        if (arg == NULL)
-+            break;
-+
-+        if (udlen)
-+            WideCharToMultiByte(CP_UTF8, 0, wstr, slash,
-+                                arg, udlen, NULL, NULL);
-+
-+        WideCharToMultiByte(CP_UTF8, 0, data.cFileName, -1,
-+                            arg + udlen, uflen, NULL, NULL);
-+
-+        newargv[newargc++] = arg;
-+    } while (FindNextFileW(h, &data));
-+
-+    CloseHandle(h);
-+
-+    return 1;
-+}
-+
-+void win32_utf8argv(int *argc, char **argv[])
-+{
-+    const WCHAR *wcmdline;
-+    WCHAR *warg, *wend, *p;
-+    int wlen, ulen, valid = 1;
-+    char *arg;
-+
-+    if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) == 0)
-+        return;
-+
-+    newargc = 0;
-+    newargv = NULL;
-+    if (!validate_argv(newargc))
-+        return;
-+
-+    wcmdline = GetCommandLineW();
-+    if (wcmdline == NULL) return;
-+
-+    /*
-+     * make a copy of the command line, since we might have to modify it...
-+     */
-+    wlen = wcslen(wcmdline);
-+    p = _alloca((wlen + 1) * sizeof(WCHAR));
-+    wcscpy(p, wcmdline);
-+
-+    while (*p != L'\0') {
-+        int in_quote = 0;
-+
-+        if (*p == L' ' || *p == L'\t') {
-+            p++; /* skip over white spaces */
-+            continue;
-+        }
-+
-+        /*
-+         * Note: because we may need to fiddle with the number of backslashes,
-+         * the argument string is copied into itself.  This is safe because
-+         * the number of characters will never expand.
-+         */
-+        warg = wend = p;
-+        while (*p != L'\0'
-+               && (in_quote || (*p != L' ' && *p != L'\t'))) {
-+            switch (*p) {
-+            case L'\\':
-+                /*
-+                 * Microsoft documentation on how backslashes are treated
-+                 * is:
-+                 *
-+                 * + Backslashes are interpreted literally, unless they
-+                 *   immediately precede a double quotation mark.
-+                 * + If an even number of backslashes is followed by a double
-+                 *   quotation mark, one backslash is placed in the argv array
-+                 *   for every pair of backslashes, and the double quotation
-+                 *   mark is interpreted as a string delimiter.
-+                 * + If an odd number of backslashes is followed by a double
-+                 *   quotation mark, one backslash is placed in the argv array
-+                 *   for every pair of backslashes, and the double quotation
-+                 *   mark is "escaped" by the remaining backslash, causing a
-+                 *   literal double quotation mark (") to be placed in argv.
-+                 *
-+                 * Ref: https://msdn.microsoft.com/en-us/library/17w5ykft.aspx
-+                 *
-+                 * Though referred page doesn't mention it, multiple qouble
-+                 * quotes are also special. Pair of double quotes in quoted
-+                 * string is counted as single double quote.
-+                 */
-+                {
-+                    const WCHAR *q = p;
-+                    int i;
-+
-+                    while (*p == L'\\')
-+                        p++;
-+
-+                    if (*p == L'"') {
-+                        int i;
-+
-+                        for (i = (p - q) / 2; i > 0; i--)
-+                            *wend++ = L'\\';
-+
-+                        /*
-+                         * if odd amount of backslashes before the quote,
-+                         * said quote is part of the argument, not a delimiter
-+                         */
-+                        if ((p - q) % 2 == 1)
-+                            *wend++ = *p++;
-+                    } else {
-+                        for (i = p - q; i > 0; i--)
-+                            *wend++ = L'\\';
-+                    }
-+                }
-+                break;
-+            case L'"':
-+                /*
-+                 * Without the preceding backslash (or when preceded with an
-+                 * even number of backslashes), the double quote is a simple
-+                 * string delimiter and just slightly change the parsing state
-+                 */
-+                if (in_quote && p[1] == L'"')
-+                    *wend++ = *p++;
-+                else
-+                    in_quote = !in_quote;
-+                p++;
-+                break;
-+            default:
-+                /*
-+                 * Any other non-delimiter character is just taken verbatim
-+                 */
-+                *wend++ = *p++;
-+            }
-+        }
-+
-+        wlen = wend - warg;
-+
-+        if (wlen == 0 || !process_glob(warg, wlen)) {
-+            if (!validate_argv(newargc + 1)) {
-+                valid = 0;
-+                break;
-+            }
-+
-+            ulen = 0;
-+            if (wlen > 0) {
-+                ulen = WideCharToMultiByte(CP_UTF8, 0, warg, wlen,
-+                                           NULL, 0, NULL, NULL);
-+                if (ulen <= 0)
-+                    continue;
-+            }
-+
-+            arg = malloc(ulen + 1);
-+            if (arg == NULL) {
-+                valid = 0;
-+                break;
-+            }
-+
-+            if (wlen > 0)
-+                WideCharToMultiByte(CP_UTF8, 0, warg, wlen,
-+                                    arg, ulen, NULL, NULL);
-+            arg[ulen] = '\0';
-+
-+            newargv[newargc++] = arg;
-+        }
-+    }
-+
-+    if (valid) {
-+        saved_cp = GetConsoleOutputCP();
-+        SetConsoleOutputCP(CP_UTF8);
-+
-+        *argc = newargc;
-+        *argv = newargv;
-+
-+        atexit(cleanup);
-+    } else if (newargv != NULL) {
-+        int i;
-+
-+        for (i = 0; i < newargc; i++)
-+            free(newargv[i]);
-+
-+        free(newargv);
-+
-+        newargc = 0;
-+        newargv = NULL;
-+    }
-+
-+    return;
-+}
-+#else
-+void win32_utf8argv(int &argc, char **argv[])
-+{   return;   }
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/apps/x509.c b/CryptoPkg/Library/OpensslLib/openssl/apps/x509.c
-new file mode 100644
-index 0000000..577c35d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/apps/x509.c
-@@ -0,0 +1,1101 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "apps.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#ifndef OPENSSL_NO_RSA
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+# include 
-+#endif
-+
-+#undef POSTFIX
-+#define POSTFIX ".srl"
-+#define DEF_DAYS        30
-+
-+static int callb(int ok, X509_STORE_CTX *ctx);
-+static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
-+                const EVP_MD *digest, CONF *conf, const char *section);
-+static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest,
-+                        X509 *x, X509 *xca, EVP_PKEY *pkey,
-+                        STACK_OF(OPENSSL_STRING) *sigopts, const char *serialfile,
-+                        int create, int days, int clrext, CONF *conf,
-+                        const char *section, ASN1_INTEGER *sno, int reqfile);
-+static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
-+
-+typedef enum OPTION_choice {
-+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-+    OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM,
-+    OPT_CAKEYFORM, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE,
-+    OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_SIGNKEY, OPT_CA,
-+    OPT_CAKEY, OPT_CASERIAL, OPT_SET_SERIAL, OPT_FORCE_PUBKEY,
-+    OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_NAMEOPT,
-+    OPT_C, OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL,
-+    OPT_MODULUS, OPT_PUBKEY, OPT_X509TOREQ, OPT_TEXT, OPT_HASH,
-+    OPT_ISSUER_HASH, OPT_SUBJECT, OPT_ISSUER, OPT_FINGERPRINT, OPT_DATES,
-+    OPT_PURPOSE, OPT_STARTDATE, OPT_ENDDATE, OPT_CHECKEND, OPT_CHECKHOST,
-+    OPT_CHECKEMAIL, OPT_CHECKIP, OPT_NOOUT, OPT_TRUSTOUT, OPT_CLRTRUST,
-+    OPT_CLRREJECT, OPT_ALIAS, OPT_CACREATESERIAL, OPT_CLREXT, OPT_OCSPID,
-+    OPT_SUBJECT_HASH_OLD,
-+    OPT_ISSUER_HASH_OLD,
-+    OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT
-+} OPTION_CHOICE;
-+
-+OPTIONS x509_options[] = {
-+    {"help", OPT_HELP, '-', "Display this summary"},
-+    {"inform", OPT_INFORM, 'f',
-+     "Input format - default PEM (one of DER, NET or PEM)"},
-+    {"in", OPT_IN, '<', "Input file - default stdin"},
-+    {"outform", OPT_OUTFORM, 'f',
-+     "Output format - default PEM (one of DER, NET or PEM)"},
-+    {"out", OPT_OUT, '>', "Output file - default stdout"},
-+    {"keyform", OPT_KEYFORM, 'F', "Private key format - default PEM"},
-+    {"passin", OPT_PASSIN, 's', "Private key password/pass-phrase source"},
-+    {"serial", OPT_SERIAL, '-', "Print serial number value"},
-+    {"subject_hash", OPT_HASH, '-', "Print subject hash value"},
-+    {"issuer_hash", OPT_ISSUER_HASH, '-', "Print issuer hash value"},
-+    {"hash", OPT_HASH, '-', "Synonym for -subject_hash"},
-+    {"subject", OPT_SUBJECT, '-', "Print subject DN"},
-+    {"issuer", OPT_ISSUER, '-', "Print issuer DN"},
-+    {"email", OPT_EMAIL, '-', "Print email address(es)"},
-+    {"startdate", OPT_STARTDATE, '-', "Set notBefore field"},
-+    {"enddate", OPT_ENDDATE, '-', "Set notAfter field"},
-+    {"purpose", OPT_PURPOSE, '-', "Print out certificate purposes"},
-+    {"dates", OPT_DATES, '-', "Both Before and After dates"},
-+    {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"},
-+    {"pubkey", OPT_PUBKEY, '-', "Output the public key"},
-+    {"fingerprint", OPT_FINGERPRINT, '-',
-+     "Print the certificate fingerprint"},
-+    {"alias", OPT_ALIAS, '-', "Output certificate alias"},
-+    {"noout", OPT_NOOUT, '-', "No output, just status"},
-+    {"nocert", OPT_NOCERT, '-', "No certificate output"},
-+    {"ocspid", OPT_OCSPID, '-',
-+     "Print OCSP hash values for the subject name and public key"},
-+    {"ocsp_uri", OPT_OCSP_URI, '-', "Print OCSP Responder URL(s)"},
-+    {"trustout", OPT_TRUSTOUT, '-', "Output a trusted certificate"},
-+    {"clrtrust", OPT_CLRTRUST, '-', "Clear all trusted purposes"},
-+    {"clrext", OPT_CLREXT, '-', "Clear all certificate extensions"},
-+    {"addtrust", OPT_ADDTRUST, 's', "Trust certificate for a given purpose"},
-+    {"addreject", OPT_ADDREJECT, 's',
-+     "Reject certificate for a given purpose"},
-+    {"setalias", OPT_SETALIAS, 's', "Set certificate alias"},
-+    {"days", OPT_DAYS, 'n',
-+     "How long till expiry of a signed certificate - def 30 days"},
-+    {"checkend", OPT_CHECKEND, 'M',
-+     "Check whether the cert expires in the next arg seconds"},
-+    {OPT_MORE_STR, 1, 1, "Exit 1 if so, 0 if not"},
-+    {"signkey", OPT_SIGNKEY, '<', "Self sign cert with arg"},
-+    {"x509toreq", OPT_X509TOREQ, '-',
-+     "Output a certification request object"},
-+    {"req", OPT_REQ, '-', "Input is a certificate request, sign and output"},
-+    {"CA", OPT_CA, '<', "Set the CA certificate, must be PEM format"},
-+    {"CAkey", OPT_CAKEY, 's',
-+     "The CA key, must be PEM format; if not in CAfile"},
-+    {"CAcreateserial", OPT_CACREATESERIAL, '-',
-+     "Create serial number file if it does not exist"},
-+    {"CAserial", OPT_CASERIAL, 's', "Serial file"},
-+    {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"},
-+    {"text", OPT_TEXT, '-', "Print the certificate in text form"},
-+    {"C", OPT_C, '-', "Print out C code forms"},
-+    {"extfile", OPT_EXTFILE, '<', "File with X509V3 extensions to add"},
-+    {"extensions", OPT_EXTENSIONS, 's', "Section from config file to use"},
-+    {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
-+    {"certopt", OPT_CERTOPT, 's', "Various certificate text options"},
-+    {"checkhost", OPT_CHECKHOST, 's', "Check certificate matches host"},
-+    {"checkemail", OPT_CHECKEMAIL, 's', "Check certificate matches email"},
-+    {"checkip", OPT_CHECKIP, 's', "Check certificate matches ipaddr"},
-+    {"CAform", OPT_CAFORM, 'F', "CA format - default PEM"},
-+    {"CAkeyform", OPT_CAKEYFORM, 'F', "CA key format - default PEM"},
-+    {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
-+    {"force_pubkey", OPT_FORCE_PUBKEY, '<', "Force the Key to put inside certificate"},
-+    {"next_serial", OPT_NEXT_SERIAL, '-', "Increment current certificate serial number"},
-+    {"clrreject", OPT_CLRREJECT, '-',
-+     "Clears all the prohibited or rejected uses of the certificate"},
-+    {"badsig", OPT_BADSIG, '-', "Corrupt last byte of certificate signature (for test)"},
-+    {"", OPT_MD, '-', "Any supported digest"},
-+#ifndef OPENSSL_NO_MD5
-+    {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-',
-+     "Print old-style (MD5) issuer hash value"},
-+    {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-',
-+     "Print old-style (MD5) subject hash value"},
-+#endif
-+#ifndef OPENSSL_NO_ENGINE
-+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
-+#endif
-+    {NULL}
-+};
-+
-+int x509_main(int argc, char **argv)
-+{
-+    ASN1_INTEGER *sno = NULL;
-+    ASN1_OBJECT *objtmp = NULL;
-+    BIO *out = NULL;
-+    CONF *extconf = NULL;
-+    EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL;
-+    STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
-+    STACK_OF(OPENSSL_STRING) *sigopts = NULL;
-+    X509 *x = NULL, *xca = NULL;
-+    X509_REQ *req = NULL, *rq = NULL;
-+    X509_STORE *ctx = NULL;
-+    const EVP_MD *digest = NULL;
-+    char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL;
-+    char *checkhost = NULL, *checkemail = NULL, *checkip = NULL;
-+    char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL;
-+    char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
-+    char buf[256], *prog;
-+    int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0;
-+    int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM;
-+    int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = 0;
-+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
-+    int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0;
-+    int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
-+    int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0;
-+    int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0;
-+    int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0;
-+    int enddate = 0;
-+    time_t checkoffset = 0;
-+    unsigned long nmflag = 0, certflag = 0;
-+    char nmflag_set = 0;
-+    OPTION_CHOICE o;
-+    ENGINE *e = NULL;
-+#ifndef OPENSSL_NO_MD5
-+    int subject_hash_old = 0, issuer_hash_old = 0;
-+#endif
-+
-+    ctx = X509_STORE_new();
-+    if (ctx == NULL)
-+        goto end;
-+    X509_STORE_set_verify_cb(ctx, callb);
-+
-+    prog = opt_init(argc, argv, x509_options);
-+    while ((o = opt_next()) != OPT_EOF) {
-+        switch (o) {
-+        case OPT_EOF:
-+        case OPT_ERR:
-+ opthelp:
-+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-+            goto end;
-+        case OPT_HELP:
-+            opt_help(x509_options);
-+            ret = 0;
-+            goto end;
-+        case OPT_INFORM:
-+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
-+                goto opthelp;
-+            break;
-+        case OPT_IN:
-+            infile = opt_arg();
-+            break;
-+        case OPT_OUTFORM:
-+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat))
-+                goto opthelp;
-+            break;
-+        case OPT_KEYFORM:
-+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat))
-+                goto opthelp;
-+            break;
-+        case OPT_CAFORM:
-+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat))
-+                goto opthelp;
-+            break;
-+        case OPT_CAKEYFORM:
-+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &CAkeyformat))
-+                goto opthelp;
-+            break;
-+        case OPT_OUT:
-+            outfile = opt_arg();
-+            break;
-+        case OPT_REQ:
-+            reqfile = need_rand = 1;
-+            break;
-+
-+        case OPT_SIGOPT:
-+            if (!sigopts)
-+                sigopts = sk_OPENSSL_STRING_new_null();
-+            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
-+                goto opthelp;
-+            break;
-+        case OPT_DAYS:
-+            days = atoi(opt_arg());
-+            break;
-+        case OPT_PASSIN:
-+            passinarg = opt_arg();
-+            break;
-+        case OPT_EXTFILE:
-+            extfile = opt_arg();
-+            break;
-+        case OPT_EXTENSIONS:
-+            extsect = opt_arg();
-+            break;
-+        case OPT_SIGNKEY:
-+            keyfile = opt_arg();
-+            sign_flag = ++num;
-+            need_rand = 1;
-+            break;
-+        case OPT_CA:
-+            CAfile = opt_arg();
-+            CA_flag = ++num;
-+            need_rand = 1;
-+            break;
-+        case OPT_CAKEY:
-+            CAkeyfile = opt_arg();
-+            break;
-+        case OPT_CASERIAL:
-+            CAserial = opt_arg();
-+            break;
-+        case OPT_SET_SERIAL:
-+            if (sno != NULL) {
-+                BIO_printf(bio_err, "Serial number supplied twice\n");
-+                goto opthelp;
-+            }
-+            if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL)
-+                goto opthelp;
-+            break;
-+        case OPT_FORCE_PUBKEY:
-+            fkeyfile = opt_arg();
-+            break;
-+        case OPT_ADDTRUST:
-+            if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
-+                BIO_printf(bio_err,
-+                           "%s: Invalid trust object value %s\n",
-+                           prog, opt_arg());
-+                goto opthelp;
-+            }
-+            if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL)
-+                goto end;
-+            sk_ASN1_OBJECT_push(trust, objtmp);
-+            objtmp = NULL;
-+            trustout = 1;
-+            break;
-+        case OPT_ADDREJECT:
-+            if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
-+                BIO_printf(bio_err,
-+                           "%s: Invalid reject object value %s\n",
-+                           prog, opt_arg());
-+                goto opthelp;
-+            }
-+            if (reject == NULL
-+                && (reject = sk_ASN1_OBJECT_new_null()) == NULL)
-+                goto end;
-+            sk_ASN1_OBJECT_push(reject, objtmp);
-+            objtmp = NULL;
-+            trustout = 1;
-+            break;
-+        case OPT_SETALIAS:
-+            alias = opt_arg();
-+            trustout = 1;
-+            break;
-+        case OPT_CERTOPT:
-+            if (!set_cert_ex(&certflag, opt_arg()))
-+                goto opthelp;
-+            break;
-+        case OPT_NAMEOPT:
-+            nmflag_set = 1;
-+            if (!set_name_ex(&nmflag, opt_arg()))
-+                goto opthelp;
-+            break;
-+        case OPT_ENGINE:
-+            e = setup_engine(opt_arg(), 0);
-+            break;
-+        case OPT_C:
-+            C = ++num;
-+            break;
-+        case OPT_EMAIL:
-+            email = ++num;
-+            break;
-+        case OPT_OCSP_URI:
-+            ocsp_uri = ++num;
-+            break;
-+        case OPT_SERIAL:
-+            serial = ++num;
-+            break;
-+        case OPT_NEXT_SERIAL:
-+            next_serial = ++num;
-+            break;
-+        case OPT_MODULUS:
-+            modulus = ++num;
-+            break;
-+        case OPT_PUBKEY:
-+            pubkey = ++num;
-+            break;
-+        case OPT_X509TOREQ:
-+            x509req = ++num;
-+            break;
-+        case OPT_TEXT:
-+            text = ++num;
-+            break;
-+        case OPT_SUBJECT:
-+            subject = ++num;
-+            break;
-+        case OPT_ISSUER:
-+            issuer = ++num;
-+            break;
-+        case OPT_FINGERPRINT:
-+            fingerprint = ++num;
-+            break;
-+        case OPT_HASH:
-+            subject_hash = ++num;
-+            break;
-+        case OPT_ISSUER_HASH:
-+            issuer_hash = ++num;
-+            break;
-+        case OPT_PURPOSE:
-+            pprint = ++num;
-+            break;
-+        case OPT_STARTDATE:
-+            startdate = ++num;
-+            break;
-+        case OPT_ENDDATE:
-+            enddate = ++num;
-+            break;
-+        case OPT_NOOUT:
-+            noout = ++num;
-+            break;
-+        case OPT_NOCERT:
-+            nocert = 1;
-+            break;
-+        case OPT_TRUSTOUT:
-+            trustout = 1;
-+            break;
-+        case OPT_CLRTRUST:
-+            clrtrust = ++num;
-+            break;
-+        case OPT_CLRREJECT:
-+            clrreject = ++num;
-+            break;
-+        case OPT_ALIAS:
-+            aliasout = ++num;
-+            break;
-+        case OPT_CACREATESERIAL:
-+            CA_createserial = ++num;
-+            break;
-+        case OPT_CLREXT:
-+            clrext = 1;
-+            break;
-+        case OPT_OCSPID:
-+            ocspid = ++num;
-+            break;
-+        case OPT_BADSIG:
-+            badsig = 1;
-+            break;
-+#ifndef OPENSSL_NO_MD5
-+        case OPT_SUBJECT_HASH_OLD:
-+            subject_hash_old = ++num;
-+            break;
-+        case OPT_ISSUER_HASH_OLD:
-+            issuer_hash_old = ++num;
-+            break;
-+#else
-+        case OPT_SUBJECT_HASH_OLD:
-+        case OPT_ISSUER_HASH_OLD:
-+            break;
-+#endif
-+        case OPT_DATES:
-+            startdate = ++num;
-+            enddate = ++num;
-+            break;
-+        case OPT_CHECKEND:
-+            checkend = 1;
-+            {
-+                intmax_t temp = 0;
-+                if (!opt_imax(opt_arg(), &temp))
-+                    goto opthelp;
-+                checkoffset = (time_t)temp;
-+                if ((intmax_t)checkoffset != temp) {
-+                    BIO_printf(bio_err, "%s: checkend time out of range %s\n",
-+                               prog, opt_arg());
-+                    goto opthelp;
-+                }
-+            }
-+            break;
-+        case OPT_CHECKHOST:
-+            checkhost = opt_arg();
-+            break;
-+        case OPT_CHECKEMAIL:
-+            checkemail = opt_arg();
-+            break;
-+        case OPT_CHECKIP:
-+            checkip = opt_arg();
-+            break;
-+        case OPT_MD:
-+            if (!opt_md(opt_unknown(), &digest))
-+                goto opthelp;
-+        }
-+    }
-+    argc = opt_num_rest();
-+    argv = opt_rest();
-+    if (argc != 0) {
-+        BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]);
-+        goto opthelp;
-+    }
-+
-+    if (!nmflag_set)
-+        nmflag = XN_FLAG_ONELINE;
-+
-+    out = bio_open_default(outfile, 'w', outformat);
-+    if (out == NULL)
-+        goto end;
-+
-+    if (need_rand)
-+        app_RAND_load_file(NULL, 0);
-+
-+    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
-+        BIO_printf(bio_err, "Error getting password\n");
-+        goto end;
-+    }
-+
-+    if (!X509_STORE_set_default_paths(ctx)) {
-+        ERR_print_errors(bio_err);
-+        goto end;
-+    }
-+
-+    if (fkeyfile) {
-+        fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key");
-+        if (fkey == NULL)
-+            goto end;
-+    }
-+
-+    if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
-+        CAkeyfile = CAfile;
-+    } else if ((CA_flag) && (CAkeyfile == NULL)) {
-+        BIO_printf(bio_err,
-+                   "need to specify a CAkey if using the CA command\n");
-+        goto end;
-+    }
-+
-+    if (extfile) {
-+        X509V3_CTX ctx2;
-+        if ((extconf = app_load_config(extfile)) == NULL)
-+            goto end;
-+        if (!extsect) {
-+            extsect = NCONF_get_string(extconf, "default", "extensions");
-+            if (!extsect) {
-+                ERR_clear_error();
-+                extsect = "default";
-+            }
-+        }
-+        X509V3_set_ctx_test(&ctx2);
-+        X509V3_set_nconf(&ctx2, extconf);
-+        if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
-+            BIO_printf(bio_err,
-+                       "Error Loading extension section %s\n", extsect);
-+            ERR_print_errors(bio_err);
-+            goto end;
-+        }
-+    }
-+
-+    if (reqfile) {
-+        EVP_PKEY *pkey;
-+        BIO *in;
-+
-+        if (!sign_flag && !CA_flag) {
-+            BIO_printf(bio_err, "We need a private key to sign with\n");
-+            goto end;
-+        }
-+        in = bio_open_default(infile, 'r', informat);
-+        if (in == NULL)
-+            goto end;
-+        req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
-+        BIO_free(in);
-+
-+        if (req == NULL) {
-+            ERR_print_errors(bio_err);
-+            goto end;
-+        }
-+
-+        if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) {
-+            BIO_printf(bio_err, "error unpacking public key\n");
-+            goto end;
-+        }
-+        i = X509_REQ_verify(req, pkey);
-+        if (i < 0) {
-+            BIO_printf(bio_err, "Signature verification error\n");
-+            ERR_print_errors(bio_err);
-+            goto end;
-+        }
-+        if (i == 0) {
-+            BIO_printf(bio_err,
-+                       "Signature did not match the certificate request\n");
-+            goto end;
-+        } else
-+            BIO_printf(bio_err, "Signature ok\n");
-+
-+        print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
-+                   nmflag);
-+
-+        if ((x = X509_new()) == NULL)
-+            goto end;
-+
-+        if (sno == NULL) {
-+            sno = ASN1_INTEGER_new();
-+            if (sno == NULL || !rand_serial(NULL, sno))
-+                goto end;
-+            if (!X509_set_serialNumber(x, sno))
-+                goto end;
-+            ASN1_INTEGER_free(sno);
-+            sno = NULL;
-+        } else if (!X509_set_serialNumber(x, sno))
-+            goto end;
-+
-+        if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req)))
-+            goto end;
-+        if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req)))
-+            goto end;
-+        if (!set_cert_times(x, NULL, NULL, days))
-+            goto end;
-+
-+        if (fkey)
-+            X509_set_pubkey(x, fkey);
-+        else {
-+            pkey = X509_REQ_get0_pubkey(req);
-+            X509_set_pubkey(x, pkey);
-+        }
-+    } else
-+        x = load_cert(infile, informat, "Certificate");
-+
-+    if (x == NULL)
-+        goto end;
-+    if (CA_flag) {
-+        xca = load_cert(CAfile, CAformat, "CA Certificate");
-+        if (xca == NULL)
-+            goto end;
-+    }
-+
-+    if (!noout || text || next_serial) {
-+        OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");
-+
-+    }
-+
-+    if (alias)
-+        X509_alias_set1(x, (unsigned char *)alias, -1);
-+
-+    if (clrtrust)
-+        X509_trust_clear(x);
-+    if (clrreject)
-+        X509_reject_clear(x);
-+
-+    if (trust) {
-+        for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
-+            objtmp = sk_ASN1_OBJECT_value(trust, i);
-+            X509_add1_trust_object(x, objtmp);
-+        }
-+        objtmp = NULL;
-+    }
-+
-+    if (reject) {
-+        for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
-+            objtmp = sk_ASN1_OBJECT_value(reject, i);
-+            X509_add1_reject_object(x, objtmp);
-+        }
-+        objtmp = NULL;
-+    }
-+
-+    if (badsig) {
-+        const ASN1_BIT_STRING *signature;
-+
-+        X509_get0_signature(&signature, NULL, x);
-+        corrupt_signature(signature);
-+    }
-+
-+    if (num) {
-+        for (i = 1; i <= num; i++) {
-+            if (issuer == i) {
-+                print_name(out, "issuer=", X509_get_issuer_name(x), nmflag);
-+            } else if (subject == i) {
-+                print_name(out, "subject=",
-+                           X509_get_subject_name(x), nmflag);
-+            } else if (serial == i) {
-+                BIO_printf(out, "serial=");
-+                i2a_ASN1_INTEGER(out, X509_get_serialNumber(x));
-+                BIO_printf(out, "\n");
-+            } else if (next_serial == i) {
-+                ASN1_INTEGER *ser = X509_get_serialNumber(x);
-+                BIGNUM *bnser = ASN1_INTEGER_to_BN(ser, NULL);
-+
-+                if (!bnser)
-+                    goto end;
-+                if (!BN_add_word(bnser, 1))
-+                    goto end;
-+                ser = BN_to_ASN1_INTEGER(bnser, NULL);
-+                if (!ser)
-+                    goto end;
-+                BN_free(bnser);
-+                i2a_ASN1_INTEGER(out, ser);
-+                ASN1_INTEGER_free(ser);
-+                BIO_puts(out, "\n");
-+            } else if ((email == i) || (ocsp_uri == i)) {
-+                int j;
-+                STACK_OF(OPENSSL_STRING) *emlst;
-+                if (email == i)
-+                    emlst = X509_get1_email(x);
-+                else
-+                    emlst = X509_get1_ocsp(x);
-+                for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
-+                    BIO_printf(out, "%s\n",
-+                               sk_OPENSSL_STRING_value(emlst, j));
-+                X509_email_free(emlst);
-+            } else if (aliasout == i) {
-+                unsigned char *alstr;
-+                alstr = X509_alias_get0(x, NULL);
-+                if (alstr)
-+                    BIO_printf(out, "%s\n", alstr);
-+                else
-+                    BIO_puts(out, "\n");
-+            } else if (subject_hash == i) {
-+                BIO_printf(out, "%08lx\n", X509_subject_name_hash(x));
-+            }
-+#ifndef OPENSSL_NO_MD5
-+            else if (subject_hash_old == i) {
-+                BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x));
-+            }
-+#endif
-+            else if (issuer_hash == i) {
-+                BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x));
-+            }
-+#ifndef OPENSSL_NO_MD5
-+            else if (issuer_hash_old == i) {
-+                BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x));
-+            }
-+#endif
-+            else if (pprint == i) {
-+                X509_PURPOSE *ptmp;
-+                int j;
-+                BIO_printf(out, "Certificate purposes:\n");
-+                for (j = 0; j < X509_PURPOSE_get_count(); j++) {
-+                    ptmp = X509_PURPOSE_get0(j);
-+                    purpose_print(out, x, ptmp);
-+                }
-+            } else if (modulus == i) {
-+                EVP_PKEY *pkey;
-+
-+                pkey = X509_get0_pubkey(x);
-+                if (pkey == NULL) {
-+                    BIO_printf(bio_err, "Modulus=unavailable\n");
-+                    ERR_print_errors(bio_err);
-+                    goto end;
-+                }
-+                BIO_printf(out, "Modulus=");
-+#ifndef OPENSSL_NO_RSA
-+                if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
-+                    const BIGNUM *n;
-+                    RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, NULL, NULL);
-+                    BN_print(out, n);
-+                } else
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+                if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA) {
-+                    const BIGNUM *dsapub = NULL;
-+                    DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &dsapub, NULL);
-+                    BN_print(out, dsapub);
-+                } else
-+#endif
-+                {
-+                    BIO_printf(out, "Wrong Algorithm type");
-+                }
-+                BIO_printf(out, "\n");
-+            } else if (pubkey == i) {
-+                EVP_PKEY *pkey;
-+
-+                pkey = X509_get0_pubkey(x);
-+                if (pkey == NULL) {
-+                    BIO_printf(bio_err, "Error getting public key\n");
-+                    ERR_print_errors(bio_err);
-+                    goto end;
-+                }
-+                PEM_write_bio_PUBKEY(out, pkey);
-+            } else if (C == i) {
-+                unsigned char *d;
-+                char *m;
-+                int len;
-+
-+                X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf);
-+                BIO_printf(out, "/*\n"
-+                                " * Subject: %s\n", buf);
-+
-+                X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf);
-+                BIO_printf(out, " * Issuer:  %s\n"
-+                                " */\n", buf);
-+
-+                len = i2d_X509(x, NULL);
-+                m = app_malloc(len, "x509 name buffer");
-+                d = (unsigned char *)m;
-+                len = i2d_X509_NAME(X509_get_subject_name(x), &d);
-+                print_array(out, "the_subject_name", len, (unsigned char *)m);
-+                d = (unsigned char *)m;
-+                len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
-+                print_array(out, "the_public_key", len, (unsigned char *)m);
-+                d = (unsigned char *)m;
-+                len = i2d_X509(x, &d);
-+                print_array(out, "the_certificate", len, (unsigned char *)m);
-+                OPENSSL_free(m);
-+            } else if (text == i) {
-+                X509_print_ex(out, x, nmflag, certflag);
-+            } else if (startdate == i) {
-+                BIO_puts(out, "notBefore=");
-+                ASN1_TIME_print(out, X509_get0_notBefore(x));
-+                BIO_puts(out, "\n");
-+            } else if (enddate == i) {
-+                BIO_puts(out, "notAfter=");
-+                ASN1_TIME_print(out, X509_get0_notAfter(x));
-+                BIO_puts(out, "\n");
-+            } else if (fingerprint == i) {
-+                int j;
-+                unsigned int n;
-+                unsigned char md[EVP_MAX_MD_SIZE];
-+                const EVP_MD *fdig = digest;
-+
-+                if (!fdig)
-+                    fdig = EVP_sha1();
-+
-+                if (!X509_digest(x, fdig, md, &n)) {
-+                    BIO_printf(bio_err, "out of memory\n");
-+                    goto end;
-+                }
-+                BIO_printf(out, "%s Fingerprint=",
-+                           OBJ_nid2sn(EVP_MD_type(fdig)));
-+                for (j = 0; j < (int)n; j++) {
-+                    BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n)
-+                               ? '\n' : ':');
-+                }
-+            }
-+
-+            /* should be in the library */
-+            else if ((sign_flag == i) && (x509req == 0)) {
-+                BIO_printf(bio_err, "Getting Private key\n");
-+                if (Upkey == NULL) {
-+                    Upkey = load_key(keyfile, keyformat, 0,
-+                                     passin, e, "Private key");
-+                    if (Upkey == NULL)
-+                        goto end;
-+                }
-+
-+                assert(need_rand);
-+                if (!sign(x, Upkey, days, clrext, digest, extconf, extsect))
-+                    goto end;
-+            } else if (CA_flag == i) {
-+                BIO_printf(bio_err, "Getting CA Private Key\n");
-+                if (CAkeyfile != NULL) {
-+                    CApkey = load_key(CAkeyfile, CAkeyformat,
-+                                      0, passin, e, "CA Private Key");
-+                    if (CApkey == NULL)
-+                        goto end;
-+                }
-+
-+                assert(need_rand);
-+                if (!x509_certify(ctx, CAfile, digest, x, xca,
-+                                  CApkey, sigopts,
-+                                  CAserial, CA_createserial, days, clrext,
-+                                  extconf, extsect, sno, reqfile))
-+                    goto end;
-+            } else if (x509req == i) {
-+                EVP_PKEY *pk;
-+
-+                BIO_printf(bio_err, "Getting request Private Key\n");
-+                if (keyfile == NULL) {
-+                    BIO_printf(bio_err, "no request key file specified\n");
-+                    goto end;
-+                } else {
-+                    pk = load_key(keyfile, keyformat, 0,
-+                                  passin, e, "request key");
-+                    if (pk == NULL)
-+                        goto end;
-+                }
-+
-+                BIO_printf(bio_err, "Generating certificate request\n");
-+
-+                rq = X509_to_X509_REQ(x, pk, digest);
-+                EVP_PKEY_free(pk);
-+                if (rq == NULL) {
-+                    ERR_print_errors(bio_err);
-+                    goto end;
-+                }
-+                if (!noout) {
-+                    X509_REQ_print(out, rq);
-+                    PEM_write_bio_X509_REQ(out, rq);
-+                }
-+                noout = 1;
-+            } else if (ocspid == i) {
-+                X509_ocspid_print(out, x);
-+            }
-+        }
-+    }
-+
-+    if (checkend) {
-+        time_t tcheck = time(NULL) + checkoffset;
-+
-+        if (X509_cmp_time(X509_get0_notAfter(x), &tcheck) < 0) {
-+            BIO_printf(out, "Certificate will expire\n");
-+            ret = 1;
-+        } else {
-+            BIO_printf(out, "Certificate will not expire\n");
-+            ret = 0;
-+        }
-+        goto end;
-+    }
-+
-+    print_cert_checks(out, x, checkhost, checkemail, checkip);
-+
-+    if (noout || nocert) {
-+        ret = 0;
-+        goto end;
-+    }
-+
-+    if (outformat == FORMAT_ASN1)
-+        i = i2d_X509_bio(out, x);
-+    else if (outformat == FORMAT_PEM) {
-+        if (trustout)
-+            i = PEM_write_bio_X509_AUX(out, x);
-+        else
-+            i = PEM_write_bio_X509(out, x);
-+    } else {
-+        BIO_printf(bio_err, "bad output format specified for outfile\n");
-+        goto end;
-+    }
-+    if (!i) {
-+        BIO_printf(bio_err, "unable to write certificate\n");
-+        ERR_print_errors(bio_err);
-+        goto end;
-+    }
-+    ret = 0;
-+ end:
-+    if (need_rand)
-+        app_RAND_write_file(NULL);
-+    NCONF_free(extconf);
-+    BIO_free_all(out);
-+    X509_STORE_free(ctx);
-+    X509_REQ_free(req);
-+    X509_free(x);
-+    X509_free(xca);
-+    EVP_PKEY_free(Upkey);
-+    EVP_PKEY_free(CApkey);
-+    EVP_PKEY_free(fkey);
-+    sk_OPENSSL_STRING_free(sigopts);
-+    X509_REQ_free(rq);
-+    ASN1_INTEGER_free(sno);
-+    sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
-+    sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
-+    ASN1_OBJECT_free(objtmp);
-+    release_engine(e);
-+    OPENSSL_free(passin);
-+    return (ret);
-+}
-+
-+static ASN1_INTEGER *x509_load_serial(const char *CAfile, const char *serialfile,
-+                                      int create)
-+{
-+    char *buf = NULL, *p;
-+    ASN1_INTEGER *bs = NULL;
-+    BIGNUM *serial = NULL;
-+    size_t len;
-+
-+    len = ((serialfile == NULL)
-+           ? (strlen(CAfile) + strlen(POSTFIX) + 1)
-+           : (strlen(serialfile))) + 1;
-+    buf = app_malloc(len, "serial# buffer");
-+    if (serialfile == NULL) {
-+        OPENSSL_strlcpy(buf, CAfile, len);
-+        for (p = buf; *p; p++)
-+            if (*p == '.') {
-+                *p = '\0';
-+                break;
-+            }
-+        OPENSSL_strlcat(buf, POSTFIX, len);
-+    } else
-+        OPENSSL_strlcpy(buf, serialfile, len);
-+
-+    serial = load_serial(buf, create, NULL);
-+    if (serial == NULL)
-+        goto end;
-+
-+    if (!BN_add_word(serial, 1)) {
-+        BIO_printf(bio_err, "add_word failure\n");
-+        goto end;
-+    }
-+
-+    if (!save_serial(buf, NULL, serial, &bs))
-+        goto end;
-+
-+ end:
-+    OPENSSL_free(buf);
-+    BN_free(serial);
-+    return bs;
-+}
-+
-+static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest,
-+                        X509 *x, X509 *xca, EVP_PKEY *pkey,
-+                        STACK_OF(OPENSSL_STRING) *sigopts,
-+                        const char *serialfile, int create,
-+                        int days, int clrext, CONF *conf, const char *section,
-+                        ASN1_INTEGER *sno, int reqfile)
-+{
-+    int ret = 0;
-+    ASN1_INTEGER *bs = NULL;
-+    X509_STORE_CTX *xsc = NULL;
-+    EVP_PKEY *upkey;
-+
-+    upkey = X509_get0_pubkey(xca);
-+    if (upkey == NULL) {
-+        BIO_printf(bio_err, "Error obtaining CA X509 public key\n");
-+        goto end;
-+    }
-+    EVP_PKEY_copy_parameters(upkey, pkey);
-+
-+    xsc = X509_STORE_CTX_new();
-+    if (xsc == NULL || !X509_STORE_CTX_init(xsc, ctx, x, NULL)) {
-+        BIO_printf(bio_err, "Error initialising X509 store\n");
-+        goto end;
-+    }
-+    if (sno)
-+        bs = sno;
-+    else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL)
-+        goto end;
-+
-+    /*
-+     * NOTE: this certificate can/should be self signed, unless it was a
-+     * certificate request in which case it is not.
-+     */
-+    X509_STORE_CTX_set_cert(xsc, x);
-+    X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
-+    if (!reqfile && X509_verify_cert(xsc) <= 0)
-+        goto end;
-+
-+    if (!X509_check_private_key(xca, pkey)) {
-+        BIO_printf(bio_err,
-+                   "CA certificate and CA private key do not match\n");
-+        goto end;
-+    }
-+
-+    if (!X509_set_issuer_name(x, X509_get_subject_name(xca)))
-+        goto end;
-+    if (!X509_set_serialNumber(x, bs))
-+        goto end;
-+
-+    if (!set_cert_times(x, NULL, NULL, days))
-+        goto end;
-+
-+    if (clrext) {
-+        while (X509_get_ext_count(x) > 0)
-+            X509_delete_ext(x, 0);
-+    }
-+
-+    if (conf) {
-+        X509V3_CTX ctx2;
-+        X509_set_version(x, 2); /* version 3 certificate */
-+        X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
-+        X509V3_set_nconf(&ctx2, conf);
-+        if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
-+            goto end;
-+    }
-+
-+    if (!do_X509_sign(x, pkey, digest, sigopts))
-+        goto end;
-+    ret = 1;
-+ end:
-+    X509_STORE_CTX_free(xsc);
-+    if (!ret)
-+        ERR_print_errors(bio_err);
-+    if (!sno)
-+        ASN1_INTEGER_free(bs);
-+    return ret;
-+}
-+
-+static int callb(int ok, X509_STORE_CTX *ctx)
-+{
-+    int err;
-+    X509 *err_cert;
-+
-+    /*
-+     * it is ok to use a self signed certificate This case will catch both
-+     * the initial ok == 0 and the final ok == 1 calls to this function
-+     */
-+    err = X509_STORE_CTX_get_error(ctx);
-+    if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
-+        return 1;
-+
-+    /*
-+     * BAD we should have gotten an error.  Normally if everything worked
-+     * X509_STORE_CTX_get_error(ctx) will still be set to
-+     * DEPTH_ZERO_SELF_....
-+     */
-+    if (ok) {
-+        BIO_printf(bio_err,
-+                   "error with certificate to be certified - should be self signed\n");
-+        return 0;
-+    } else {
-+        err_cert = X509_STORE_CTX_get_current_cert(ctx);
-+        print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0);
-+        BIO_printf(bio_err,
-+                   "error with certificate - error %d at depth %d\n%s\n", err,
-+                   X509_STORE_CTX_get_error_depth(ctx),
-+                   X509_verify_cert_error_string(err));
-+        return 1;
-+    }
-+}
-+
-+/* self sign */
-+static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
-+                const EVP_MD *digest, CONF *conf, const char *section)
-+{
-+
-+    if (!X509_set_issuer_name(x, X509_get_subject_name(x)))
-+        goto err;
-+    if (!set_cert_times(x, NULL, NULL, days))
-+        goto err;
-+    if (!X509_set_pubkey(x, pkey))
-+        goto err;
-+    if (clrext) {
-+        while (X509_get_ext_count(x) > 0)
-+            X509_delete_ext(x, 0);
-+    }
-+    if (conf) {
-+        X509V3_CTX ctx;
-+        X509_set_version(x, 2); /* version 3 certificate */
-+        X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
-+        X509V3_set_nconf(&ctx, conf);
-+        if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
-+            goto err;
-+    }
-+    if (!X509_sign(x, pkey, digest))
-+        goto err;
-+    return 1;
-+ err:
-+    ERR_print_errors(bio_err);
-+    return 0;
-+}
-+
-+static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
-+{
-+    int id, i, idret;
-+    const char *pname;
-+    id = X509_PURPOSE_get_id(pt);
-+    pname = X509_PURPOSE_get0_name(pt);
-+    for (i = 0; i < 2; i++) {
-+        idret = X509_check_purpose(cert, id, i);
-+        BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
-+        if (idret == 1)
-+            BIO_printf(bio, "Yes\n");
-+        else if (idret == 0)
-+            BIO_printf(bio, "No\n");
-+        else
-+            BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
-+    }
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/appveyor.yml b/CryptoPkg/Library/OpensslLib/openssl/appveyor.yml
-new file mode 100644
-index 0000000..9074a8c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/appveyor.yml
-@@ -0,0 +1,53 @@
-+platform:
-+    - x86
-+    - x64
-+
-+environment:
-+    matrix:
-+        - VSVER: 14
-+
-+configuration:
-+    - plain
-+    - shared
-+
-+before_build:
-+    - ps: >-
-+        If ($env:Platform -Match "x86") {
-+            $env:VCVARS_PLATFORM="x86"
-+            $env:TARGET="VC-WIN32"
-+        } Else {
-+            $env:VCVARS_PLATFORM="amd64"
-+            $env:TARGET="VC-WIN64A"
-+        }
-+    - ps: >-
-+        If ($env:Configuration -Match "shared") {
-+            $env:SHARED=""
-+        } Else {
-+            $env:SHARED="no-shared"
-+        }
-+    - ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS"))
-+    - call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM%
-+    - mkdir _build
-+    - cd _build
-+    - perl ..\Configure %TARGET% no-asm %SHARED%
-+    - cd ..
-+
-+build_script:
-+    - cd _build
-+    - nmake
-+    - cd ..
-+
-+test_script:
-+    - cd _build
-+    - nmake test
-+    - mkdir ..\_install
-+    - nmake install install_docs DESTDIR=..\_install
-+    - cd ..
-+
-+notifications:
-+    - provider: Email
-+      to:
-+          - openssl-commits@openssl.org
-+      on_build_success: false
-+      on_build_failure: true
-+      on_build_status_changed: true
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/build.info b/CryptoPkg/Library/OpensslLib/openssl/build.info
-new file mode 100644
-index 0000000..fa136dc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/build.info
-@@ -0,0 +1,41 @@
-+LIBS=libcrypto libssl
-+ORDINALS[libcrypto]=crypto
-+ORDINALS[libssl]=ssl
-+INCLUDE[libcrypto]=. crypto/include include
-+INCLUDE[libssl]=. include
-+DEPEND[libssl]=libcrypto
-+
-+# Empty DEPEND "indices" means the dependencies are expected to be built
-+# unconditionally before anything else.
-+DEPEND[]=include/openssl/opensslconf.h crypto/include/internal/bn_conf.h \
-+         crypto/include/internal/dso_conf.h
-+DEPEND[include/openssl/opensslconf.h]=configdata.pm
-+GENERATE[include/openssl/opensslconf.h]=include/openssl/opensslconf.h.in
-+DEPEND[crypto/include/internal/bn_conf.h]=configdata.pm
-+GENERATE[crypto/include/internal/bn_conf.h]=crypto/include/internal/bn_conf.h.in
-+DEPEND[crypto/include/internal/dso_conf.h]=configdata.pm
-+GENERATE[crypto/include/internal/dso_conf.h]=crypto/include/internal/dso_conf.h.in
-+
-+
-+IF[{- $config{target} =~ /^Cygwin/ -}]
-+ SHARED_NAME[libcrypto]=cygcrypto-{- $config{shlib_major}.".".$config{shlib_minor} -}
-+ SHARED_NAME[libssl]=cygssl-{- $config{shlib_major}.".".$config{shlib_minor} -}
-+ELSIF[{- $config{target} =~ /^mingw/ -}]
-+ SHARED_NAME[libcrypto]=libcrypto-{- $config{shlib_major}."_".$config{shlib_minor} -}{- $config{target} eq "mingw64" ? "-x64" : "" -}
-+ SHARED_NAME[libssl]=libssl-{- $config{shlib_major}."_".$config{shlib_minor} -}{- $config{target} eq "mingw64" ? "-x64" : "" -}
-+ELSIF[{- $config{target} =~ /^VC-/ -}]
-+ SHARED_NAME[libcrypto]=libcrypto-{- $config{shlib_major}."_".$config{shlib_minor} -}{- $target{multilib} -}
-+ SHARED_NAME[libssl]=libssl-{- $config{shlib_major}."_".$config{shlib_minor} -}{- $target{multilib} -}
-+ENDIF
-+
-+# VMS has a cultural standard where all libraries are prefixed.
-+# For OpenSSL, the choice is 'ossl$' (this prefix was claimed in a
-+# conversation with VSI, Tuesday January 26 2016)
-+# Also, it seems it's usual to have the pointer size the libraries
-+# were built for as part of the name.
-+IF[{- $config{target} =~ /^vms/ -}]
-+ RENAME[libcrypto]=ossl$libcrypto{- $target{pointer_size} -}
-+ RENAME[libssl]=ossl$libssl{- $target{pointer_size} -}
-+ SHARED_NAME[libcrypto]=ossl$libcrypto{- sprintf "%02d%02d", $config{shlib_major}, $config{shlib_minor} -}_shr{- $target{pointer_size} -}
-+ SHARED_NAME[libssl]=ossl$libssl{- sprintf "%02d%02d", $config{shlib_major}, $config{shlib_minor} -}_shr{- $target{pointer_size} -}
-+ENDIF
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/config b/CryptoPkg/Library/OpensslLib/openssl/config
-new file mode 100755
-index 0000000..1341fd6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/config
-@@ -0,0 +1,924 @@
-+#!/bin/sh
-+# Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+# OpenSSL config: determine the operating system and run ./Configure
-+# Derived from minarch and GuessOS from Apache.
-+#
-+# Do "config -h" for usage information.
-+SUFFIX=""
-+DRYRUN="false"
-+VERBOSE="false"
-+EXE=""
-+THERE=`dirname $0`
-+
-+# pick up any command line args to config
-+for i
-+do
-+case "$i" in 
-+-d*) options=$options" --debug";;
-+-t*) DRYRUN="true" VERBOSE="true";;
-+-v*) VERBOSE="true";;
-+-h*) DRYRUN="true"; cat </dev/null` || MACHINE="unknown"
-+[ "$RELEASE" ] || RELEASE=`(uname -r) 2>/dev/null` || RELEASE="unknown"
-+[ "$SYSTEM" ] || SYSTEM=`(uname -s) 2>/dev/null`  || SYSTEM="unknown"
-+[ "$BUILD" ] || VERSION=`(uname -v) 2>/dev/null` || VERSION="unknown"
-+
-+
-+# Now test for ISC and SCO, since it is has a braindamaged uname.
-+#
-+# We need to work around FreeBSD 1.1.5.1 
-+(
-+XREL=`uname -X 2>/dev/null | grep "^Release" | awk '{print $3}'`
-+if [ "x$XREL" != "x" ]; then
-+    if [ -f /etc/kconfig ]; then
-+	case "$XREL" in
-+	    4.0|4.1)
-+		    echo "${MACHINE}-whatever-isc4"; exit 0
-+		;;
-+	esac
-+    else
-+	case "$XREL" in
-+	    3.2v4.2)
-+		echo "whatever-whatever-sco3"; exit 0
-+		;;
-+	    3.2v5.0*)
-+		echo "whatever-whatever-sco5"; exit 0
-+		;;
-+	    4.2MP)
-+		case "x${VERSION}" in
-+		    x2.0*) echo "whatever-whatever-unixware20"; exit 0 ;;
-+		    x2.1*) echo "whatever-whatever-unixware21"; exit 0 ;;
-+		    x2*)   echo "whatever-whatever-unixware2";  exit 0 ;;
-+		esac
-+		;;
-+	    4.2)
-+		echo "whatever-whatever-unixware1"; exit 0
-+		;;
-+	    5*)
-+		case "x${VERSION}" in
-+		    # We hardcode i586 in place of ${MACHINE} for the
-+		    # following reason. The catch is that even though Pentium
-+		    # is minimum requirement for platforms in question,
-+		    # ${MACHINE} gets always assigned to i386. Now, problem
-+		    # with i386 is that it makes ./config pass 386 to
-+		    # ./Configure, which in turn makes make generate
-+		    # inefficient SHA-1 (for this moment) code.
-+		    x[678]*)  echo "i586-sco-unixware7"; exit 0 ;;
-+		esac
-+		;;
-+	esac
-+    fi
-+fi
-+# Now we simply scan though... In most cases, the SYSTEM info is enough
-+#
-+case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in
-+    A/UX:*)
-+	echo "m68k-apple-aux3"; exit 0
-+	;;
-+
-+    AIX:[3-9]:4:*)
-+	echo "${MACHINE}-ibm-aix"; exit 0
-+	;;
-+
-+    AIX:*:[5-9]:*)
-+	echo "${MACHINE}-ibm-aix"; exit 0
-+	;;
-+
-+    AIX:*)
-+	echo "${MACHINE}-ibm-aix3"; exit 0
-+	;;
-+
-+    HI-UX:*)
-+	echo "${MACHINE}-hi-hiux"; exit 0
-+	;;
-+
-+    HP-UX:*)
-+	HPUXVER=`echo ${RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-+	case "$HPUXVER" in
-+	    1[0-9].*)	# HPUX 10 and 11 targets are unified
-+		echo "${MACHINE}-hp-hpux1x"; exit 0
-+		;;
-+	    *)
-+		echo "${MACHINE}-hp-hpux"; exit 0
-+		;;
-+	esac
-+	;;
-+
-+    IRIX:6.*)
-+	echo "mips3-sgi-irix"; exit 0
-+	;;
-+
-+    IRIX64:*)
-+	echo "mips4-sgi-irix64"; exit 0
-+	;;
-+
-+    Linux:[2-9].*)
-+	echo "${MACHINE}-whatever-linux2"; exit 0
-+	;;
-+
-+    Linux:1.*)
-+	echo "${MACHINE}-whatever-linux1"; exit 0
-+	;;
-+
-+    GNU*)
-+	echo "hurd-x86"; exit 0;
-+	;;
-+
-+    LynxOS:*)
-+	echo "${MACHINE}-lynx-lynxos"; exit 0
-+	;;
-+
-+    BSD/OS:4.*)  # BSD/OS always says 386
-+	echo "i486-whatever-bsdi4"; exit 0
-+	;;
-+
-+    BSD/386:*:*:*486*|BSD/OS:*:*:*:*486*)
-+        case `/sbin/sysctl -n hw.model` in
-+	    Pentium*)
-+                echo "i586-whatever-bsdi"; exit 0
-+                ;;
-+            *)
-+                echo "i386-whatever-bsdi"; exit 0
-+                ;;
-+            esac;
-+	;;
-+
-+    BSD/386:*|BSD/OS:*)
-+	echo "${MACHINE}-whatever-bsdi"; exit 0
-+	;;
-+
-+    FreeBSD:*:*:*386*)
-+        VERS=`echo ${RELEASE} | sed -e 's/[-(].*//'`
-+        MACH=`sysctl -n hw.model`
-+        ARCH='whatever'
-+        case ${MACH} in
-+           *386*       ) MACH="i386"     ;;
-+           *486*       ) MACH="i486"     ;;
-+           Pentium\ II*) MACH="i686"     ;;
-+           Pentium*    ) MACH="i586"     ;;
-+           *           ) MACH="$MACHINE" ;;
-+        esac
-+        case ${MACH} in
-+           i[0-9]86 ) ARCH="pc" ;;
-+        esac
-+        echo "${MACH}-${ARCH}-freebsd${VERS}"; exit 0
-+        ;;
-+
-+    FreeBSD:*)
-+	echo "${MACHINE}-whatever-freebsd"; exit 0
-+	;;
-+
-+    Haiku:*)
-+	echo "${MACHINE}-whatever-haiku"; exit 0
-+	;;
-+
-+    NetBSD:*:*:*386*)
-+        echo "`(/usr/sbin/sysctl -n hw.model || /sbin/sysctl -n hw.model) | sed 's,.*\(.\)86-class.*,i\186,'`-whatever-netbsd"; exit 0
-+	;;
-+
-+    NetBSD:*)
-+	echo "${MACHINE}-whatever-netbsd"; exit 0
-+	;;
-+
-+    OpenBSD:*)
-+	echo "${MACHINE}-whatever-openbsd"; exit 0
-+	;;
-+
-+    OpenUNIX:*)
-+	echo "${MACHINE}-unknown-OpenUNIX${VERSION}"; exit 0
-+	;;
-+
-+    OSF1:*:*:*alpha*)
-+	OSFMAJOR=`echo ${RELEASE}| sed -e 's/^V\([0-9]*\)\..*$/\1/'`
-+	case "$OSFMAJOR" in
-+	    4|5)
-+		echo "${MACHINE}-dec-tru64"; exit 0
-+		;;
-+	    1|2|3)
-+		echo "${MACHINE}-dec-osf"; exit 0
-+		;;
-+	    *)
-+		echo "${MACHINE}-dec-osf"; exit 0
-+		;;
-+	esac
-+	;;
-+
-+    QNX:*)
-+	case "$RELEASE" in
-+	    4*)
-+		echo "${MACHINE}-whatever-qnx4"
-+		;;
-+	    6*)
-+		echo "${MACHINE}-whatever-qnx6"
-+		;;
-+	    *)
-+		echo "${MACHINE}-whatever-qnx"
-+		;;
-+	esac
-+	exit 0
-+	;;
-+
-+    Paragon*:*:*:*)
-+	echo "i860-intel-osf1"; exit 0
-+	;;
-+
-+    Rhapsody:*)
-+	echo "ppc-apple-rhapsody"; exit 0
-+	;;
-+
-+    Darwin:*)
-+	case "$MACHINE" in
-+	    Power*)
-+		echo "ppc-apple-darwin${VERSION}"
-+		;;
-+	    x86_64)
-+		echo "x86_64-apple-darwin${VERSION}"
-+		;;
-+	    *)
-+		echo "i686-apple-darwin${VERSION}"
-+		;;
-+	esac
-+	exit 0
-+	;;
-+
-+    SunOS:5.*)
-+	echo "${MACHINE}-whatever-solaris2"; exit 0
-+	;;
-+
-+    SunOS:*)
-+	echo "${MACHINE}-sun-sunos4"; exit 0
-+	;;
-+
-+    UNIX_System_V:4.*:*)
-+	echo "${MACHINE}-whatever-sysv4"; exit 0
-+	;;
-+
-+    VOS:*:*:i786)
-+     echo "i386-stratus-vos"; exit 0
-+     ;;
-+
-+    VOS:*:*:*)
-+     echo "hppa1.1-stratus-vos"; exit 0
-+     ;;
-+
-+    *:4*:R4*:m88k)
-+	echo "${MACHINE}-whatever-sysv4"; exit 0
-+	;;
-+
-+    DYNIX/ptx:4*:*)
-+	echo "${MACHINE}-whatever-sysv4"; exit 0
-+	;;
-+
-+    *:4.0:3.0:3[34]?? | *:4.0:3.0:3[34]??,*)
-+	echo "i486-ncr-sysv4"; exit 0
-+	;;
-+
-+    ULTRIX:*)
-+	echo "${MACHINE}-unknown-ultrix"; exit 0
-+	;;
-+
-+    POSIX-BC*)
-+	echo "${MACHINE}-siemens-sysv4"; exit 0   # Here, $MACHINE == "BS2000"
-+	;;
-+
-+    machten:*)
-+       echo "${MACHINE}-tenon-${SYSTEM}"; exit 0;
-+       ;;
-+
-+    library:*)
-+	echo "${MACHINE}-ncr-sysv4"; exit 0
-+	;;
-+
-+    ConvexOS:*:11.0:*)
-+	echo "${MACHINE}-v11-${SYSTEM}"; exit 0;
-+	;;
-+
-+    MINGW*)
-+	echo "${MACHINE}-whatever-mingw"; exit 0;
-+	;;
-+    CYGWIN*)
-+	echo "${MACHINE}-pc-cygwin"; exit 0
-+	;;
-+
-+    vxworks*)
-+       echo "${MACHINE}-whatever-vxworks"; exit 0;
-+       ;;
-+esac
-+
-+#
-+# Ugg. These are all we can determine by what we know about
-+# the output of uname. Be more creative:
-+#
-+
-+# Do the Apollo stuff first. Here, we just simply assume
-+# that the existence of the /usr/apollo directory is proof
-+# enough
-+if [ -d /usr/apollo ]; then
-+    echo "whatever-apollo-whatever"
-+    exit 0
-+fi
-+
-+# Now NeXT
-+ISNEXT=`hostinfo 2>/dev/null`
-+case "$ISNEXT" in
-+    *'NeXT Mach 3.3'*)
-+	echo "whatever-next-nextstep3.3"; exit 0
-+	;;
-+    *NeXT*)
-+	echo "whatever-next-nextstep"; exit 0
-+	;;
-+esac
-+
-+# At this point we gone through all the one's
-+# we know of: Punt
-+
-+echo "${MACHINE}-whatever-${SYSTEM}" 
-+exit 0
-+) 2>/dev/null | (
-+
-+# ---------------------------------------------------------------------------
-+# this is where the translation occurs into SSLeay terms
-+# ---------------------------------------------------------------------------
-+
-+# Only set CC if not supplied already
-+if [ -z "$CROSS_COMPILE$CC" ]; then
-+  GCCVER=`sh -c "gcc -dumpversion" 2>/dev/null`
-+  if [ "$GCCVER" != "" ]; then
-+    # then strip off whatever prefix egcs prepends the number with...
-+    # Hopefully, this will work for any future prefixes as well.
-+    GCCVER=`echo $GCCVER | LC_ALL=C sed 's/^[a-zA-Z]*\-//'`
-+    # Since gcc 3.1 gcc --version behaviour has changed.  gcc -dumpversion
-+    # does give us what we want though, so we use that.  We just just the
-+    # major and minor version numbers.
-+    # peak single digit before and after first dot, e.g. 2.95.1 gives 29
-+    GCCVER=`echo $GCCVER | sed 's/\([0-9]\)\.\([0-9]\).*/\1\2/'`
-+    CC=gcc
-+  else
-+    CC=cc
-+  fi
-+fi
-+GCCVER=${GCCVER:-0}
-+if [ "$SYSTEM" = "HP-UX" ];then
-+  # By default gcc is a ILP32 compiler (with long long == 64).
-+  GCC_BITS="32"
-+  if [ $GCCVER -ge 30 ]; then
-+    # PA64 support only came in with gcc 3.0.x.
-+    # We check if the preprocessor symbol __LP64__ is defined...
-+    if echo "__LP64__" | gcc -v -E -x c - 2>/dev/null | grep "^__LP64__" 2>&1 > /dev/null; then
-+      : # __LP64__ has slipped through, it therefore is not defined
-+    else
-+      GCC_BITS="64"
-+    fi
-+  fi
-+fi
-+if [ "$SYSTEM" = "SunOS" ]; then
-+  if [ $GCCVER -ge 30 ]; then
-+    # 64-bit ABI isn't officially supported in gcc 3.0, but it appears
-+    # to be working, at the very least 'make test' passes...
-+    if gcc -v -E -x c /dev/null 2>&1 | grep __arch64__ > /dev/null; then
-+      GCC_ARCH="-m64"
-+    else
-+      GCC_ARCH="-m32"
-+    fi
-+  fi
-+  # check for WorkShop C, expected output is "cc: blah-blah C x.x"
-+  CCVER=`(cc -V 2>&1) 2>/dev/null | \
-+  	egrep -e '^cc: .* C [0-9]\.[0-9]' | \
-+	sed 's/.* C \([0-9]\)\.\([0-9]\).*/\1\2/'`
-+  CCVER=${CCVER:-0}
-+  if [ $MACHINE != i86pc -a $CCVER -gt 40 ]; then
-+    CC=cc	# overrides gcc!!!
-+    if [ $CCVER -eq 50 ]; then
-+      echo "WARNING! Detected WorkShop C 5.0. Do make sure you have"
-+      echo "         patch #107357-01 or later applied."
-+      sleep 5
-+    fi
-+  fi
-+fi
-+
-+if [ "${SYSTEM}" = "AIX" ]; then	# favor vendor cc over gcc
-+    (cc) 2>&1 | grep -iv "not found" > /dev/null && CC=cc
-+fi
-+
-+CCVER=${CCVER:-0}
-+
-+# read the output of the embedded GuessOS 
-+read GUESSOS
-+
-+echo Operating system: $GUESSOS
-+
-+# now map the output into SSLeay terms ... really should hack into the
-+# script above so we end up with values in vars but that would take
-+# more time that I want to waste at the moment
-+case "$GUESSOS" in
-+  uClinux*64*)
-+    OUT=uClinux-dist64
-+	;;
-+  uClinux*)
-+    OUT=uClinux-dist
-+	;;
-+  mips3-sgi-irix)
-+	#CPU=`(hinv -t cpu) 2>/dev/null | head -1 | sed 's/^CPU:[^R]*R\([0-9]*\).*/\1/'`
-+	#CPU=${CPU:-0}
-+	#if [ $CPU -ge 5000 ]; then
-+	#	options="$options -mips4"
-+	#else
-+	#	options="$options -mips3"
-+	#fi
-+	OUT="irix-mips3-$CC"
-+	;;
-+  mips4-sgi-irix64)
-+	echo "WARNING! If you wish to build 64-bit library, then you have to"
-+	echo "         invoke '$THERE/Configure irix64-mips4-$CC' *manually*."
-+	if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+	  echo "         You have about 5 seconds to press Ctrl-C to abort."
-+	  (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+	fi
-+        #CPU=`(hinv -t cpu) 2>/dev/null | head -1 | sed 's/^CPU:[^R]*R\([0-9]*\).*/\1/'`
-+        #CPU=${CPU:-0}
-+        #if [ $CPU -ge 5000 ]; then
-+        #        options="$options -mips4"
-+        #else
-+        #        options="$options -mips3"
-+        #fi
-+	OUT="irix-mips3-$CC"
-+	;;
-+  ppc-apple-rhapsody) OUT="rhapsody-ppc-cc" ;;
-+  ppc-apple-darwin*)
-+	ISA64=`(sysctl -n hw.optional.64bitops) 2>/dev/null`
-+	if [ "$ISA64" = "1" -a -z "$KERNEL_BITS" ]; then
-+	    echo "WARNING! If you wish to build 64-bit library, then you have to"
-+	    echo "         invoke '$THERE/Configure darwin64-ppc-cc' *manually*."
-+	    if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+	      echo "         You have about 5 seconds to press Ctrl-C to abort."
-+	      (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+	    fi
-+	fi
-+	if [ "$ISA64" = "1" -a "$KERNEL_BITS" = "64" ]; then
-+	    OUT="darwin64-ppc-cc"
-+	else
-+	    OUT="darwin-ppc-cc"
-+	fi ;;
-+  i?86-apple-darwin*)
-+	ISA64=`(sysctl -n hw.optional.x86_64) 2>/dev/null`
-+	if [ "$ISA64" = "1" -a -z "$KERNEL_BITS" ]; then
-+	    echo "WARNING! If you wish to build 64-bit library, then you have to"
-+	    echo "         invoke 'KERNEL_BITS=64 $THERE/config $options'."
-+	    if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+	      echo "         You have about 5 seconds to press Ctrl-C to abort."
-+	      # The stty technique used elsewhere doesn't work on
-+	      # MacOS. At least, right now on this Mac.
-+	      sleep 5
-+	    fi
-+	fi
-+	if [ "$ISA64" = "1" -a "$KERNEL_BITS" = "64" ]; then
-+	    OUT="darwin64-x86_64-cc"
-+	else
-+	    OUT="darwin-i386-cc"
-+	fi ;;
-+  x86_64-apple-darwin*)
-+	if [ -z "$KERNEL_BITS" ]; then
-+	    echo "WARNING! If you wish to build 32-bit library, then you have to"
-+	    echo "         invoke 'KERNEL_BITS=32 $THERE/config $options'."
-+	    if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+	      echo "         You have about 5 seconds to press Ctrl-C to abort."
-+	      # The stty technique used elsewhere doesn't work on
-+	      # MacOS. At least, right now on this Mac.
-+	      sleep 5
-+	    fi
-+	fi
-+	if [ "$KERNEL_BITS" = "32" ]; then
-+	    OUT="darwin-i386-cc"
-+	else
-+	    OUT="darwin64-x86_64-cc"
-+	fi ;;
-+  armv6+7-*-iphoneos)
-+	options="$options -arch%20armv6 -arch%20armv7"
-+	OUT="iphoneos-cross" ;;
-+  *-*-iphoneos)
-+	options="$options -arch%20${MACHINE}"
-+	OUT="iphoneos-cross" ;;
-+  arm64-*-iphoneos|*-*-ios64)
-+	OUT="ios64-cross" ;;
-+  alpha-*-linux2)
-+        ISA=`awk '/cpu model/{print$4;exit(0);}' /proc/cpuinfo`
-+	case ${ISA:-generic} in
-+	*[678])	OUT="linux-alpha+bwx-$CC" ;;
-+	*)	OUT="linux-alpha-$CC" ;;
-+	esac
-+	if [ "$CC" = "gcc" ]; then
-+	    case ${ISA:-generic} in
-+	    EV5|EV45)		options="$options -mcpu=ev5";;
-+	    EV56|PCA56)		options="$options -mcpu=ev56";;
-+	    *)			options="$options -mcpu=ev6";;
-+	    esac
-+	fi
-+	;;
-+  ppc64-*-linux2)
-+	if [ -z "$KERNEL_BITS" ]; then
-+	    echo "WARNING! If you wish to build 64-bit library, then you have to"
-+	    echo "         invoke '$THERE/Configure linux-ppc64' *manually*."
-+	    if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+		echo "         You have about 5 seconds to press Ctrl-C to abort."
-+		(trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+	    fi
-+	fi
-+	if [ "$KERNEL_BITS" = "64" ]; then
-+	    OUT="linux-ppc64"
-+	else
-+	    OUT="linux-ppc"
-+	    (echo "__LP64__" | gcc -E -x c - 2>/dev/null | grep "^__LP64__" 2>&1 > /dev/null) || options="$options -m32"
-+	fi
-+	;;
-+  ppc64le-*-linux2) OUT="linux-ppc64le" ;;
-+  ppc-*-linux2) OUT="linux-ppc" ;;
-+  mips64*-*-linux2)
-+	echo "WARNING! If you wish to build 64-bit library, then you have to"
-+	echo "         invoke '$THERE/Configure linux64-mips64' *manually*."
-+	if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+	    echo "         You have about 5 seconds to press Ctrl-C to abort."
-+	    (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+	fi
-+	OUT="linux-mips64"
-+	;;
-+  mips*-*-linux2) OUT="linux-mips32" ;;
-+  ppc60x-*-vxworks*) OUT="vxworks-ppc60x" ;;
-+  ppcgen-*-vxworks*) OUT="vxworks-ppcgen" ;;
-+  pentium-*-vxworks*) OUT="vxworks-pentium" ;;
-+  simlinux-*-vxworks*) OUT="vxworks-simlinux" ;;
-+  mips-*-vxworks*) OUT="vxworks-mips";;
-+  ia64-*-linux?) OUT="linux-ia64" ;;
-+  sparc64-*-linux2)
-+	echo "WARNING! If you *know* that your GNU C supports 64-bit/V9 ABI"
-+	echo "         and wish to build 64-bit library, then you have to"
-+	echo "         invoke '$THERE/Configure linux64-sparcv9' *manually*."
-+	if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+	  echo "          You have about 5 seconds to press Ctrl-C to abort."
-+	  (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+	fi
-+	OUT="linux-sparcv9" ;;
-+  sparc-*-linux2)
-+	KARCH=`awk '/^type/{print$3;exit(0);}' /proc/cpuinfo`
-+	case ${KARCH:-sun4} in
-+	sun4u*)	OUT="linux-sparcv9" ;;
-+	sun4m)	OUT="linux-sparcv8" ;;
-+	sun4d)	OUT="linux-sparcv8" ;;
-+	*)	OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
-+	esac ;;
-+  parisc*-*-linux2)
-+	# 64-bit builds under parisc64 linux are not supported and
-+	# compiler is expected to generate 32-bit objects...
-+	CPUARCH=`awk '/cpu family/{print substr($5,1,3); exit(0);}' /proc/cpuinfo`
-+	CPUSCHEDULE=`awk '/^cpu.[ 	]*: PA/{print substr($3,3); exit(0);}' /proc/cpuinfo`
-+
-+	# ??TODO ??  Model transformations
-+	# 0. CPU Architecture for the 1.1 processor has letter suffixes. We strip that off
-+	#    assuming no further arch. identification will ever be used by GCC.
-+	# 1. I'm most concerned about whether is a 7300LC is closer to a 7100 versus a 7100LC.
-+	# 2. The variant 64-bit processors cause concern should GCC support explicit schedulers
-+	#    for these chips in the future.
-+	#         PA7300LC -> 7100LC (1.1)
-+	#         PA8200   -> 8000   (2.0)
-+	#         PA8500   -> 8000   (2.0)
-+	#         PA8600   -> 8000   (2.0)
-+
-+	CPUSCHEDULE=`echo $CPUSCHEDULE|sed -e 's/7300LC/7100LC/' -e 's/8.00/8000/'`
-+	# Finish Model transformations
-+
-+	options="$options -DB_ENDIAN -mschedule=$CPUSCHEDULE -march=$CPUARCH"
-+	OUT="linux-generic32" ;;
-+  armv[1-3]*-*-linux2) OUT="linux-generic32" ;;
-+  armv[7-9]*-*-linux2) OUT="linux-armv4"; options="$options -march=armv7-a" ;;
-+  arm*-*-linux2) OUT="linux-armv4" ;;
-+  aarch64-*-linux2) OUT="linux-aarch64" ;;
-+  sh*b-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
-+  sh*-*-linux2)  OUT="linux-generic32"; options="$options -DL_ENDIAN" ;;
-+  m68k*-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
-+  s390-*-linux2) OUT="linux-generic32"; options="$options -DB_ENDIAN" ;;
-+  s390x-*-linux2)
-+	# To be uncommented when glibc bug is fixed, see Configure...
-+	#if egrep -e '^features.* highgprs' /proc/cpuinfo >/dev/null ; then
-+	#  echo "WARNING! If you wish to build \"highgprs\" 32-bit library, then you"
-+	#  echo "         have to invoke './Configure linux32-s390x' *manually*."
-+	#  if [ "$DRYRUN" = "false" -a -t -1 ]; then
-+	#    echo "         You have about 5 seconds to press Ctrl-C to abort."
-+	#    (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+	#  fi
-+	#fi
-+	OUT="linux64-s390x"
-+	;;
-+  x86_64-*-linux?)
-+	if $CC -dM -E -x c /dev/null 2>&1 | grep -q ILP32 > /dev/null; then
-+	    OUT="linux-x32"
-+	else
-+	    OUT="linux-x86_64"
-+	fi ;;
-+  *86-*-linux2)
-+        # On machines where the compiler understands -m32, prefer a
-+        # config target that uses it
-+        if $CC -m32 -E -x c /dev/null > /dev/null 2>&1; then
-+            OUT="linux-x86"
-+        else
-+            OUT="linux-elf"
-+        fi ;;
-+  *86-*-linux1) OUT="linux-aout" ;;
-+  *-*-linux?) OUT="linux-generic32" ;;
-+  sun4[uv]*-*-solaris2)
-+	OUT="solaris-sparcv9-$CC"
-+	ISA64=`(isainfo) 2>/dev/null | grep sparcv9`
-+	if [ "$ISA64" != "" -a "$KERNEL_BITS" = "" ]; then
-+	    if [ "$CC" = "cc" -a $CCVER -ge 50 ]; then
-+		echo "WARNING! If you wish to build 64-bit library, then you have to"
-+		echo "         invoke '$THERE/Configure solaris64-sparcv9-cc' *manually*."
-+		if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+		  echo "         You have about 5 seconds to press Ctrl-C to abort."
-+		  (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+		fi
-+	    elif [ "$CC" = "gcc" -a "$GCC_ARCH" = "-m64" ]; then
-+		# $GCC_ARCH denotes default ABI chosen by compiler driver
-+		# (first one found on the $PATH). I assume that user
-+		# expects certain consistency with the rest of his builds
-+		# and therefore switch over to 64-bit. 
-+		OUT="solaris64-sparcv9-gcc"
-+		echo "WARNING! If you wish to build 32-bit library, then you have to"
-+		echo "         invoke '$THERE/Configure solaris-sparcv9-gcc' *manually*."
-+		if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+		  echo "         You have about 5 seconds to press Ctrl-C to abort."
-+		  (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+		fi
-+	    elif [ "$GCC_ARCH" = "-m32" ]; then
-+		echo "NOTICE! If you *know* that your GNU C supports 64-bit/V9 ABI"
-+		echo "        and wish to build 64-bit library, then you have to"
-+		echo "        invoke '$THERE/Configure solaris64-sparcv9-gcc' *manually*."
-+		if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+		  echo "         You have about 5 seconds to press Ctrl-C to abort."
-+		  (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+		fi
-+	    fi
-+	fi
-+	if [ "$ISA64" != "" -a "$KERNEL_BITS" = "64" ]; then
-+	    OUT="solaris64-sparcv9-$CC"
-+	fi
-+	;;
-+  sun4m-*-solaris2)	OUT="solaris-sparcv8-$CC" ;;
-+  sun4d-*-solaris2)	OUT="solaris-sparcv8-$CC" ;;
-+  sun4*-*-solaris2)	OUT="solaris-sparcv7-$CC" ;;
-+  *86*-*-solaris2)
-+	ISA64=`(isainfo) 2>/dev/null | grep amd64`
-+	if [ "$ISA64" != "" -a ${KERNEL_BITS:-64} -eq 64 ]; then
-+	    OUT="solaris64-x86_64-$CC"
-+	else
-+	    OUT="solaris-x86-$CC"
-+	    if [ `uname -r | sed -e 's/5\.//'` -lt 10 ]; then
-+		options="$options no-sse2"
-+	    fi
-+	fi
-+	;;
-+  *-*-sunos4)		OUT="sunos-$CC" ;;
-+
-+  *86*-*-bsdi4)		OUT="BSD-x86-elf"; options="$options no-sse2 -ldl" ;;
-+  alpha*-*-*bsd*)	OUT="BSD-generic64"; options="$options -DL_ENDIAN" ;;
-+  powerpc64-*-*bsd*)	OUT="BSD-generic64"; options="$options -DB_ENDIAN" ;;
-+  sparc64-*-*bsd*)	OUT="BSD-sparc64" ;;
-+  ia64-*-*bsd*)		OUT="BSD-ia64" ;;
-+  amd64-*-*bsd*)	OUT="BSD-x86_64" ;;
-+  *86*-*-*bsd*)		# mimic ld behaviour when it's looking for libc...
-+			if [ -L /usr/lib/libc.so ]; then	# [Free|Net]BSD
-+			    libc=/usr/lib/libc.so
-+			else					# OpenBSD
-+			    # ld searches for highest libc.so.* and so do we
-+			    libc=`(ls /usr/lib/libc.so.* /lib/libc.so.* | tail -1) 2>/dev/null`
-+			fi
-+			case "`(file -L $libc) 2>/dev/null`" in
-+			*ELF*)	OUT="BSD-x86-elf" ;;
-+			*)	OUT="BSD-x86"; options="$options no-sse2" ;;
-+			esac ;;
-+  *-*-*bsd*)		OUT="BSD-generic32" ;;
-+
-+  x86_64-*-haiku)	OUT="haiku-x86_64" ;;
-+  *-*-haiku)		OUT="haiku-x86" ;;
-+
-+  *-*-osf)		OUT="osf1-alpha-cc" ;;
-+  *-*-tru64)		OUT="tru64-alpha-cc" ;;
-+  *-*-[Uu]nix[Ww]are7)
-+	if [ "$CC" = "gcc" ]; then
-+	  OUT="unixware-7-gcc" ; options="$options no-sse2"
-+	else    
-+	  OUT="unixware-7" ; options="$options no-sse2 -D__i386__"
-+	fi
-+	;;
-+  *-*-[Uu]nix[Ww]are20*) OUT="unixware-2.0"; options="$options no-sse2 no-sha512" ;;
-+  *-*-[Uu]nix[Ww]are21*) OUT="unixware-2.1"; options="$options no-sse2 no-sha512" ;;
-+  *-*-vos)
-+	options="$options no-threads no-shared no-asm no-dso"
-+	EXE=".pm"
-+	OUT="vos-$CC" ;;
-+  BS2000-siemens-sysv4) OUT="BS2000-OSD" ;;
-+  *-hpux1*)
-+	if [ $CC = "gcc" -a $GCC_BITS = "64" ]; then
-+	    OUT="hpux64-parisc2-gcc"
-+	fi
-+	[ "$KERNEL_BITS" ] || KERNEL_BITS=`(getconf KERNEL_BITS) 2>/dev/null`
-+	KERNEL_BITS=${KERNEL_BITS:-32}
-+	CPU_VERSION=`(getconf CPU_VERSION) 2>/dev/null`
-+	CPU_VERSION=${CPU_VERSION:-0}
-+	# See  for further info on CPU_VERSION.
-+	if   [ $CPU_VERSION -ge 768 ]; then	# IA-64 CPU
-+	     if [ $KERNEL_BITS -eq 64 -a "$CC" = "cc" ]; then
-+	        OUT="hpux64-ia64-cc"
-+             else
-+	        OUT="hpux-ia64-cc"
-+             fi
-+	elif [ $CPU_VERSION -ge 532 ]; then	# PA-RISC 2.x CPU
-+	     OUT=${OUT:-"hpux-parisc2-${CC}"}
-+	     if [ $KERNEL_BITS -eq 64 -a "$CC" = "cc" ]; then
-+		echo "WARNING! If you wish to build 64-bit library then you have to"
-+		echo "         invoke '$THERE/Configure hpux64-parisc2-cc' *manually*."
-+		if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+		  echo "         You have about 5 seconds to press Ctrl-C to abort."
-+		  (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+		fi
-+	     fi
-+	     # PA-RISC 2.0 is no longer supported as separate 32-bit
-+	     # target. This is compensated for by run-time detection
-+	     # in most critical assembly modules and taking advantage
-+	     # of 2.0 architecture in PA-RISC 1.1 build.
-+	     OUT="hpux-parisc1_1-${CC}"
-+	elif [ $CPU_VERSION -ge 528 ]; then	# PA-RISC 1.1+ CPU
-+	     OUT="hpux-parisc1_1-${CC}"
-+	elif [ $CPU_VERSION -ge 523 ]; then	# PA-RISC 1.0 CPU
-+	     OUT="hpux-parisc-${CC}"
-+	else					# Motorola(?) CPU
-+	     OUT="hpux-$CC"
-+	fi
-+	options="$options -D_REENTRANT" ;;
-+  *-hpux)	OUT="hpux-parisc-$CC" ;;
-+  *-aix)
-+	[ "$KERNEL_BITS" ] || KERNEL_BITS=`(getconf KERNEL_BITMODE) 2>/dev/null`
-+	KERNEL_BITS=${KERNEL_BITS:-32}
-+	OBJECT_MODE=${OBJECT_MODE:-32}
-+	if [ "$CC" = "gcc" ]; then
-+	    OUT="aix-gcc"
-+          if [ $OBJECT_MODE -eq 64 ]; then
-+            echo 'Your $OBJECT_MODE was found to be set to 64'
-+            OUT="aix64-gcc"
-+          fi
-+	elif [ $OBJECT_MODE -eq 64 ]; then
-+	    echo 'Your $OBJECT_MODE was found to be set to 64' 
-+	    OUT="aix64-cc"
-+	else
-+	    OUT="aix-cc"
-+	    if [ $KERNEL_BITS -eq 64 ]; then
-+		echo "WARNING! If you wish to build 64-bit kit, then you have to"
-+		echo "         invoke '$THERE/Configure aix64-cc' *manually*."
-+		if [ "$DRYRUN" = "false" -a -t 1 ]; then
-+		    echo "         You have ~5 seconds to press Ctrl-C to abort."
-+		    (trap "stty `stty -g`; exit 0" 2 0; stty -icanon min 0 time 50; read waste) <&1
-+		fi
-+	    fi
-+	fi
-+	if (lsattr -E -O -l `lsdev -c processor|awk '{print$1;exit}'` | grep -i powerpc) >/dev/null 2>&1; then
-+	    :	# this applies even to Power3 and later, as they return PowerPC_POWER[345]
-+	else
-+	    options="$options no-asm"
-+	fi
-+	;;
-+  # these are all covered by the catchall below
-+  i[3456]86-*-cygwin) OUT="Cygwin-x86" ;;
-+  *-*-cygwin) OUT="Cygwin-${MACHINE}" ;;
-+  x86pc-*-qnx6) OUT="QNX6-i386" ;;
-+  *-*-qnx6) OUT="QNX6" ;;
-+  x86-*-android|i?86-*-android) OUT="android-x86" ;;
-+  armv[7-9]*-*-android)
-+      OUT="android-armeabi"; options="$options -march=armv7-a" ;;
-+  arm*-*-android) OUT="android-armeabi" ;;
-+  *) OUT=`echo $GUESSOS | awk -F- '{print $3}'`;;
-+esac
-+
-+# NB: This atalla support has been superseded by the ENGINE support
-+# That contains its own header and definitions anyway. Support can
-+# be enabled or disabled on any supported platform without external
-+# headers, eg. by adding the "hw-atalla" switch to ./config or
-+# perl Configure
-+#
-+# See whether we can compile Atalla support
-+#if [ -f /usr/include/atasi.h ]
-+#then
-+#  options="$options -DATALLA"
-+#fi
-+
-+if [ -n "$CONFIG_OPTIONS" ]; then
-+  options="$options $CONFIG_OPTIONS"
-+fi
-+
-+if expr "$options" : '.*no\-asm' > /dev/null; then :; else
-+  sh -c "$CROSS_COMPILE${CC:-gcc} -Wa,--help -c -o /tmp/null.$$.o -x assembler /dev/null && rm /tmp/null.$$.o" 2>&1 | \
-+  grep \\--noexecstack >/dev/null && \
-+  options="$options -Wa,--noexecstack"
-+fi
-+
-+# gcc < 2.8 does not support -march=ultrasparc
-+if [ "$OUT" = solaris-sparcv9-gcc -a $GCCVER -lt 28 ]
-+then
-+  echo "WARNING! Falling down to 'solaris-sparcv8-gcc'."
-+  echo "         Upgrade to gcc-2.8 or later."
-+  sleep 5
-+  OUT=solaris-sparcv8-gcc
-+fi
-+if [ "$OUT" = "linux-sparcv9" -a $GCCVER -lt 28 ]
-+then
-+  echo "WARNING! Falling down to 'linux-sparcv8'."
-+  echo "         Upgrade to gcc-2.8 or later."
-+  sleep 5
-+  OUT=linux-sparcv8
-+fi
-+
-+case "$GUESSOS" in
-+  i386-*) options="$options 386" ;;
-+esac
-+
-+for i in aes bf camellia cast des dh dsa ec hmac idea md2 md5 mdc2 rc2 rc4 rc5 ripemd rsa seed sha
-+do
-+  if [ ! -d $THERE/crypto/$i ]
-+  then
-+    options="$options no-$i"
-+  fi
-+done
-+
-+if [ -z "$OUT" ]; then
-+  OUT="$CC"
-+fi
-+
-+if [ ".$PERL" = . ] ; then
-+	for i in . `echo $PATH | sed 's/:/ /g'`; do
-+		if [ -f "$i/perl5$EXE" ] ; then
-+			PERL="$i/perl5$EXE"
-+			break;
-+		fi;
-+	done
-+fi
-+
-+if [ ".$PERL" = . ] ; then
-+	for i in . `echo $PATH | sed 's/:/ /g'`; do
-+		if [ -f "$i/perl$EXE" ] ; then
-+			if "$i/perl$EXE" -e 'exit($]<5.0)'; then
-+				PERL="$i/perl$EXE"
-+				break;
-+			fi;
-+		fi;
-+	done
-+fi
-+
-+if [ ".$PERL" = . ] ; then
-+	echo "You need Perl 5."
-+	exit 1
-+fi
-+
-+# run Configure to check to see if we need to specify the 
-+# compiler for the platform ... in which case we add it on
-+# the end ... otherwise we leave it off
-+
-+$PERL $THERE/Configure LIST | grep "$OUT-$CC" > /dev/null
-+if [ $? = "0" ]; then
-+  OUT="$OUT-$CC"
-+fi
-+
-+OUT="$OUT"
-+
-+$PERL $THERE/Configure LIST | grep "$OUT" > /dev/null
-+if [ $? = "0" ]; then
-+  echo Configuring for $OUT
-+
-+  if [ "$VERBOSE" = "true" ]; then
-+    echo $PERL $THERE/Configure $OUT $options
-+  fi  
-+  if [ "$DRYRUN" = "false" ]; then
-+    $PERL $THERE/Configure $OUT $options
-+  fi
-+else
-+  echo "This system ($OUT) is not supported. See file INSTALL for details."
-+fi
-+)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/config.com b/CryptoPkg/Library/OpensslLib/openssl/config.com
-new file mode 100644
-index 0000000..5b54995
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/config.com
-@@ -0,0 +1,93 @@
-+$	! OpenSSL config: determine the architecture and run Configure
-+$	! Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+$	!
-+$	! Licensed under the OpenSSL license (the "License").  You may not use
-+$	! this file except in compliance with the License.  You can obtain a
-+$	! copy in the file LICENSE in the source distribution or at
-+$	! https://www.openssl.org/source/license.html
-+$	!
-+$	! Very simple for the moment, it will take the following arguments:
-+$	!
-+$	! -32 or 32	sets /POINTER_SIZE=32
-+$	! -64 or 64	sets /POINTER_SIZE=64
-+$	! -d		sets debugging
-+$	! -h		prints a usage and exits
-+$	! -t		test mode, doesn't run Configure
-+$
-+$	arch = f$edit( f$getsyi( "arch_name"), "lowercase")
-+$	pointer_size = ""
-+$	dryrun = 0
-+$	verbose = 0
-+$	here = F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"),,,"SYNTAX_ONLY") - "A.;"
-+$
-+$	collected_args = ""
-+$	P_index = 0
-+$	LOOP1:
-+$	    P_index = P_index + 1
-+$	    IF P_index .GT. 8 THEN GOTO ENDLOOP1
-+$	    P = F$EDIT(P1,"TRIM,LOWERCASE")
-+$	    IF P .EQS. "-h"
-+$           THEN
-+$               dryrun = 1
-+$               P = ""
-+$               TYPE SYS$INPUT
-+$               DECK
-+Usage: @config [options]
-+
-+  -32 or 32	Build with 32-bit pointer size.
-+  -64 or 64	Build with 64-bit pointer size.
-+  -d		Build with debugging.
-+  -t            Test mode, do not run the Configure perl script.
-+  -v            Verbose mode, show the exact Configure call that is being made.
-+  -h		This help.
-+
-+Any other text will be passed to the Configure perl script.
-+See INSTALL for instructions.
-+
-+$               EOD
-+$           ENDIF
-+$	    IF P .EQS. "-t"
-+$	    THEN
-+$		dryrun = 1
-+$		verbose = 1
-+$		P = ""
-+$	    ENDIF
-+$	    IF P .EQS. "-v"
-+$	    THEN
-+$		verbose = 1
-+$		P = ""
-+$	    ENDIF
-+$	    IF P .EQS. "-32" .OR. P .EQS. "32"
-+$	    THEN
-+$		pointer_size = "-P32"
-+$		P = ""
-+$	    ENDIF
-+$	    IF P .EQS. "-64" .OR. P .EQS. "64"
-+$	    THEN
-+$		pointer_size = "-P64"
-+$		P = ""
-+$	    ENDIF
-+$	    IF P .EQS. "-d"
-+$	    THEN
-+$               collected_args = collected_args + " --debug"
-+$		P = ""
-+$	    ENDIF
-+$	    IF P .NES. "" THEN -
-+	       collected_args = collected_args + " " + P1
-+$	    P1 = P2
-+$	    P2 = P3
-+$	    P3 = P4
-+$	    P4 = P5
-+$	    P5 = P6
-+$	    P6 = P7
-+$	    P7 = P8
-+$	    P8 = ""
-+$	    GOTO LOOP1
-+$	ENDLOOP1:
-+$
-+$	target = "vms-''arch'''pointer_size'"
-+$       IF verbose THEN -
-+           WRITE SYS$OUTPUT "PERL ''here'Configure ""''target'""''collected_args'"
-+$       IF .not. dryrun THEN -
-+           PERL 'here'Configure "''target'" 'debug' 'collected_args'
-+$       EXIT $STATUS
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_nyi.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_nyi.c
-new file mode 100644
-index 0000000..049044c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_nyi.c
-@@ -0,0 +1,53 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Copyright (c) 2004, Richard Levitte 
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#ifndef LPDIR_H
-+# include "LPdir.h"
-+#endif
-+
-+struct LP_dir_context_st {
-+    void *dummy;
-+};
-+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
-+{
-+    errno = EINVAL;
-+    return 0;
-+}
-+
-+int LP_find_file_end(LP_DIR_CTX **ctx)
-+{
-+    errno = EINVAL;
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_unix.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_unix.c
-new file mode 100644
-index 0000000..1bb2940
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_unix.c
-@@ -0,0 +1,131 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Copyright (c) 2004, Richard Levitte 
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#ifndef LPDIR_H
-+# include "LPdir.h"
-+#endif
-+
-+/*
-+ * The POSIXly macro for the maximum number of characters in a file path is
-+ * NAME_MAX.  However, some operating systems use PATH_MAX instead.
-+ * Therefore, it seems natural to first check for PATH_MAX and use that, and
-+ * if it doesn't exist, use NAME_MAX.
-+ */
-+#if defined(PATH_MAX)
-+# define LP_ENTRY_SIZE PATH_MAX
-+#elif defined(NAME_MAX)
-+# define LP_ENTRY_SIZE NAME_MAX
-+#endif
-+
-+/*
-+ * Of course, there's the possibility that neither PATH_MAX nor NAME_MAX
-+ * exist.  It's also possible that NAME_MAX exists but is define to a very
-+ * small value (HP-UX offers 14), so we need to check if we got a result, and
-+ * if it meets a minimum standard, and create or change it if not.
-+ */
-+#if !defined(LP_ENTRY_SIZE) || LP_ENTRY_SIZE<255
-+# undef LP_ENTRY_SIZE
-+# define LP_ENTRY_SIZE 255
-+#endif
-+
-+struct LP_dir_context_st {
-+    DIR *dir;
-+    char entry_name[LP_ENTRY_SIZE + 1];
-+};
-+
-+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
-+{
-+    struct dirent *direntry = NULL;
-+
-+    if (ctx == NULL || directory == NULL) {
-+        errno = EINVAL;
-+        return 0;
-+    }
-+
-+    errno = 0;
-+    if (*ctx == NULL) {
-+        *ctx = malloc(sizeof(**ctx));
-+        if (*ctx == NULL) {
-+            errno = ENOMEM;
-+            return 0;
-+        }
-+        memset(*ctx, 0, sizeof(**ctx));
-+
-+        (*ctx)->dir = opendir(directory);
-+        if ((*ctx)->dir == NULL) {
-+            int save_errno = errno; /* Probably not needed, but I'm paranoid */
-+            free(*ctx);
-+            *ctx = NULL;
-+            errno = save_errno;
-+            return 0;
-+        }
-+    }
-+
-+    direntry = readdir((*ctx)->dir);
-+    if (direntry == NULL) {
-+        return 0;
-+    }
-+
-+    strncpy((*ctx)->entry_name, direntry->d_name,
-+            sizeof((*ctx)->entry_name) - 1);
-+    (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
-+    return (*ctx)->entry_name;
-+}
-+
-+int LP_find_file_end(LP_DIR_CTX **ctx)
-+{
-+    if (ctx != NULL && *ctx != NULL) {
-+        int ret = closedir((*ctx)->dir);
-+
-+        free(*ctx);
-+        switch (ret) {
-+        case 0:
-+            return 1;
-+        case -1:
-+            return 0;
-+        default:
-+            break;
-+        }
-+    }
-+    errno = EINVAL;
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_vms.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_vms.c
-new file mode 100644
-index 0000000..1a5b60f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_vms.c
-@@ -0,0 +1,204 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Copyright (c) 2004, Richard Levitte 
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#ifndef LPDIR_H
-+# include "LPdir.h"
-+#endif
-+#include "vms_rms.h"
-+
-+/* Some compiler options hide EVMSERR. */
-+#ifndef EVMSERR
-+# define EVMSERR        65535   /* error for non-translatable VMS errors */
-+#endif
-+
-+struct LP_dir_context_st {
-+    unsigned long VMS_context;
-+    char filespec[NAMX_MAXRSS + 1];
-+    char result[NAMX_MAXRSS + 1];
-+    struct dsc$descriptor_d filespec_dsc;
-+    struct dsc$descriptor_d result_dsc;
-+};
-+
-+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
-+{
-+    int status;
-+    char *p, *r;
-+    size_t l;
-+    unsigned long flags = 0;
-+
-+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
-+#if __INITIAL_POINTER_SIZE == 64
-+# pragma pointer_size save
-+# pragma pointer_size 32
-+    char *ctx_filespec_32p;
-+# pragma pointer_size restore
-+    char ctx_filespec_32[NAMX_MAXRSS + 1];
-+#endif                          /* __INITIAL_POINTER_SIZE == 64 */
-+
-+#ifdef NAML$C_MAXRSS
-+    flags |= LIB$M_FIL_LONG_NAMES;
-+#endif
-+
-+    if (ctx == NULL || directory == NULL) {
-+        errno = EINVAL;
-+        return 0;
-+    }
-+
-+    errno = 0;
-+    if (*ctx == NULL) {
-+        size_t filespeclen = strlen(directory);
-+        char *filespec = NULL;
-+
-+        if (filespeclen == 0) {
-+            errno = ENOENT;
-+            return 0;
-+        }
-+
-+        /* MUST be a VMS directory specification!  Let's estimate if it is. */
-+        if (directory[filespeclen - 1] != ']'
-+            && directory[filespeclen - 1] != '>'
-+            && directory[filespeclen - 1] != ':') {
-+            errno = EINVAL;
-+            return 0;
-+        }
-+
-+        filespeclen += 4;       /* "*.*;" */
-+
-+        if (filespeclen > NAMX_MAXRSS) {
-+            errno = ENAMETOOLONG;
-+            return 0;
-+        }
-+
-+        *ctx = malloc(sizeof(**ctx));
-+        if (*ctx == NULL) {
-+            errno = ENOMEM;
-+            return 0;
-+        }
-+        memset(*ctx, 0, sizeof(**ctx));
-+
-+        strcpy((*ctx)->filespec, directory);
-+        strcat((*ctx)->filespec, "*.*;");
-+
-+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
-+#if __INITIAL_POINTER_SIZE == 64
-+# define CTX_FILESPEC ctx_filespec_32p
-+        /* Copy the file name to storage with a 32-bit pointer. */
-+        ctx_filespec_32p = ctx_filespec_32;
-+        strcpy(ctx_filespec_32p, (*ctx)->filespec);
-+#else                           /* __INITIAL_POINTER_SIZE == 64 */
-+# define CTX_FILESPEC (*ctx)->filespec
-+#endif                          /* __INITIAL_POINTER_SIZE == 64 [else] */
-+
-+        (*ctx)->filespec_dsc.dsc$w_length = filespeclen;
-+        (*ctx)->filespec_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
-+        (*ctx)->filespec_dsc.dsc$b_class = DSC$K_CLASS_S;
-+        (*ctx)->filespec_dsc.dsc$a_pointer = CTX_FILESPEC;
-+    }
-+
-+    (*ctx)->result_dsc.dsc$w_length = 0;
-+    (*ctx)->result_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
-+    (*ctx)->result_dsc.dsc$b_class = DSC$K_CLASS_D;
-+    (*ctx)->result_dsc.dsc$a_pointer = 0;
-+
-+    status = lib$find_file(&(*ctx)->filespec_dsc, &(*ctx)->result_dsc,
-+                           &(*ctx)->VMS_context, 0, 0, 0, &flags);
-+
-+    if (status == RMS$_NMF) {
-+        errno = 0;
-+        vaxc$errno = status;
-+        return NULL;
-+    }
-+
-+    if (!$VMS_STATUS_SUCCESS(status)) {
-+        errno = EVMSERR;
-+        vaxc$errno = status;
-+        return NULL;
-+    }
-+
-+    /*
-+     * Quick, cheap and dirty way to discard any device and directory, since
-+     * we only want file names
-+     */
-+    l = (*ctx)->result_dsc.dsc$w_length;
-+    p = (*ctx)->result_dsc.dsc$a_pointer;
-+    r = p;
-+    for (; *p; p++) {
-+        if (*p == '^' && p[1] != '\0') { /* Take care of ODS-5 escapes */
-+            p++;
-+        } else if (*p == ':' || *p == '>' || *p == ']') {
-+            l -= p + 1 - r;
-+            r = p + 1;
-+        } else if (*p == ';') {
-+            l = p - r;
-+            break;
-+        }
-+    }
-+
-+    strncpy((*ctx)->result, r, l);
-+    (*ctx)->result[l] = '\0';
-+    str$free1_dx(&(*ctx)->result_dsc);
-+
-+    return (*ctx)->result;
-+}
-+
-+int LP_find_file_end(LP_DIR_CTX **ctx)
-+{
-+    if (ctx != NULL && *ctx != NULL) {
-+        int status = lib$find_file_end(&(*ctx)->VMS_context);
-+
-+        free(*ctx);
-+
-+        if (!$VMS_STATUS_SUCCESS(status)) {
-+            errno = EVMSERR;
-+            vaxc$errno = status;
-+            return 0;
-+        }
-+        return 1;
-+    }
-+    errno = EINVAL;
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_win.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_win.c
-new file mode 100644
-index 0000000..8f674d3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_win.c
-@@ -0,0 +1,211 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Copyright (c) 2004, Richard Levitte 
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include 
-+#include 
-+#include "internal/numbers.h"
-+#ifndef LPDIR_H
-+# include "LPdir.h"
-+#endif
-+
-+/*
-+ * We're most likely overcautious here, but let's reserve for broken WinCE
-+ * headers and explicitly opt for UNICODE call. Keep in mind that our WinCE
-+ * builds are compiled with -DUNICODE [as well as -D_UNICODE].
-+ */
-+#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
-+# define FindFirstFile FindFirstFileW
-+#endif
-+#if defined(LP_SYS_WINCE) && !defined(FindNextFile)
-+# define FindNextFile FindNextFileW
-+#endif
-+
-+#ifndef NAME_MAX
-+# define NAME_MAX 255
-+#endif
-+
-+#ifdef CP_UTF8
-+# define CP_DEFAULT CP_UTF8
-+#else
-+# define CP_DEFAULT CP_ACP
-+#endif
-+
-+struct LP_dir_context_st {
-+    WIN32_FIND_DATA ctx;
-+    HANDLE handle;
-+    char entry_name[NAME_MAX + 1];
-+};
-+
-+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
-+{
-+    if (ctx == NULL || directory == NULL) {
-+        errno = EINVAL;
-+        return 0;
-+    }
-+
-+    errno = 0;
-+    if (*ctx == NULL) {
-+        size_t dirlen = strlen(directory);
-+
-+        if (dirlen == 0 || dirlen > INT_MAX - 3) {
-+            errno = ENOENT;
-+            return 0;
-+        }
-+
-+        *ctx = malloc(sizeof(**ctx));
-+        if (*ctx == NULL) {
-+            errno = ENOMEM;
-+            return 0;
-+        }
-+        memset(*ctx, 0, sizeof(**ctx));
-+
-+        if (sizeof(TCHAR) != sizeof(char)) {
-+            TCHAR *wdir = NULL;
-+            /* len_0 denotes string length *with* trailing 0 */
-+            size_t index = 0, len_0 = dirlen + 1;
-+#ifdef LP_MULTIBYTE_AVAILABLE
-+            int sz = 0;
-+            UINT cp;
-+
-+            do {
-+# ifdef CP_UTF8
-+                if ((sz = MultiByteToWideChar((cp = CP_UTF8), 0,
-+                                              directory, len_0,
-+                                              NULL, 0)) > 0 ||
-+                    GetLastError() != ERROR_NO_UNICODE_TRANSLATION)
-+                    break;
-+# endif
-+                sz = MultiByteToWideChar((cp = CP_ACP), 0,
-+                                         directory, len_0,
-+                                         NULL, 0);
-+            } while (0);
-+
-+            if (sz > 0) {
-+                /*
-+                 * allocate two additional characters in case we need to
-+                 * concatenate asterisk, |sz| covers trailing '\0'!
-+                 */
-+                wdir = _alloca((sz + 2) * sizeof(TCHAR));
-+                if (!MultiByteToWideChar(cp, 0, directory, len_0,
-+                                         (WCHAR *)wdir, sz)) {
-+                    free(*ctx);
-+                    *ctx = NULL;
-+                    errno = EINVAL;
-+                    return 0;
-+                }
-+            } else
-+#endif
-+            {
-+                sz = len_0;
-+                /*
-+                 * allocate two additional characters in case we need to
-+                 * concatenate asterisk, |sz| covers trailing '\0'!
-+                 */
-+                wdir = _alloca((sz + 2) * sizeof(TCHAR));
-+                for (index = 0; index < len_0; index++)
-+                    wdir[index] = (TCHAR)directory[index];
-+            }
-+
-+            sz--; /* wdir[sz] is trailing '\0' now */
-+            if (wdir[sz - 1] != TEXT('*')) {
-+                if (wdir[sz - 1] != TEXT('/') && wdir[sz - 1] != TEXT('\\'))
-+                    _tcscpy(wdir + sz, TEXT("/*"));
-+                else
-+                    _tcscpy(wdir + sz, TEXT("*"));
-+            }
-+
-+            (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
-+        } else {
-+            if (directory[dirlen - 1] != '*') {
-+                char *buf = _alloca(dirlen + 3);
-+
-+                strcpy(buf, directory);
-+                if (buf[dirlen - 1] != '/' && buf[dirlen - 1] != '\\')
-+                    strcpy(buf + dirlen, "/*");
-+                else
-+                    strcpy(buf + dirlen, "*");
-+
-+                directory = buf;
-+            }
-+
-+            (*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
-+        }
-+
-+        if ((*ctx)->handle == INVALID_HANDLE_VALUE) {
-+            free(*ctx);
-+            *ctx = NULL;
-+            errno = EINVAL;
-+            return 0;
-+        }
-+    } else {
-+        if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) {
-+            return 0;
-+        }
-+    }
-+    if (sizeof(TCHAR) != sizeof(char)) {
-+        TCHAR *wdir = (*ctx)->ctx.cFileName;
-+        size_t index, len_0 = 0;
-+
-+        while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1))
-+            len_0++;
-+        len_0++;
-+
-+#ifdef LP_MULTIBYTE_AVAILABLE
-+        if (!WideCharToMultiByte(CP_DEFAULT, 0, (WCHAR *)wdir, len_0,
-+                                 (*ctx)->entry_name,
-+                                 sizeof((*ctx)->entry_name), NULL, 0))
-+#endif
-+            for (index = 0; index < len_0; index++)
-+                (*ctx)->entry_name[index] = (char)wdir[index];
-+    } else
-+        strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
-+                sizeof((*ctx)->entry_name) - 1);
-+
-+    (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
-+
-+    return (*ctx)->entry_name;
-+}
-+
-+int LP_find_file_end(LP_DIR_CTX **ctx)
-+{
-+    if (ctx != NULL && *ctx != NULL) {
-+        FindClose((*ctx)->handle);
-+        free(*ctx);
-+        *ctx = NULL;
-+        return 1;
-+    }
-+    errno = EINVAL;
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_win32.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_win32.c
-new file mode 100644
-index 0000000..59ed485
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_win32.c
-@@ -0,0 +1,38 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Copyright (c) 2004, Richard Levitte 
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#define LP_SYS_WIN32
-+#define LP_MULTIBYTE_AVAILABLE
-+#include "LPdir_win.c"
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_wince.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_wince.c
-new file mode 100644
-index 0000000..dbc1052
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/LPdir_wince.c
-@@ -0,0 +1,41 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Copyright (c) 2004, Richard Levitte 
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#define LP_SYS_WINCE
-+/*
-+ * We might want to define LP_MULTIBYTE_AVAILABLE here.  It's currently under
-+ * investigation what the exact conditions would be
-+ */
-+#include "LPdir_win.c"
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_cbc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_cbc.c
-new file mode 100644
-index 0000000..342841f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_cbc.c
-@@ -0,0 +1,24 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                     size_t len, const AES_KEY *key,
-+                     unsigned char *ivec, const int enc)
-+{
-+
-+    if (enc)
-+        CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
-+                              (block128_f) AES_encrypt);
-+    else
-+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
-+                              (block128_f) AES_decrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_cfb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_cfb.c
-new file mode 100644
-index 0000000..f010e3c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_cfb.c
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+/*
-+ * The input and output encrypted as though 128bit cfb mode is being used.
-+ * The extra state information to record how much of the 128bit block we have
-+ * used is contained in *num;
-+ */
-+
-+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
-+                        size_t length, const AES_KEY *key,
-+                        unsigned char *ivec, int *num, const int enc)
-+{
-+
-+    CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
-+                          (block128_f) AES_encrypt);
-+}
-+
-+/* N.B. This expects the input to be packed, MS bit first */
-+void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
-+                      size_t length, const AES_KEY *key,
-+                      unsigned char *ivec, int *num, const int enc)
-+{
-+    CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
-+                            (block128_f) AES_encrypt);
-+}
-+
-+void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
-+                      size_t length, const AES_KEY *key,
-+                      unsigned char *ivec, int *num, const int enc)
-+{
-+    CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
-+                            (block128_f) AES_encrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_core.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_core.c
-new file mode 100644
-index 0000000..bd5c779
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_core.c
-@@ -0,0 +1,1367 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/**
-+ * rijndael-alg-fst.c
-+ *
-+ * @version 3.0 (December 2000)
-+ *
-+ * Optimised ANSI C code for the Rijndael cipher (now AES)
-+ *
-+ * @author Vincent Rijmen 
-+ * @author Antoon Bosselaers 
-+ * @author Paulo Barreto 
-+ *
-+ * This code is hereby placed in the public domain.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* Note: rewritten a little bit to provide error control and an OpenSSL-
-+   compatible API */
-+
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+#include "aes_locl.h"
-+
-+#ifndef AES_ASM
-+/*-
-+Te0[x] = S [x].[02, 01, 01, 03];
-+Te1[x] = S [x].[03, 02, 01, 01];
-+Te2[x] = S [x].[01, 03, 02, 01];
-+Te3[x] = S [x].[01, 01, 03, 02];
-+
-+Td0[x] = Si[x].[0e, 09, 0d, 0b];
-+Td1[x] = Si[x].[0b, 0e, 09, 0d];
-+Td2[x] = Si[x].[0d, 0b, 0e, 09];
-+Td3[x] = Si[x].[09, 0d, 0b, 0e];
-+Td4[x] = Si[x].[01];
-+*/
-+
-+static const u32 Te0[256] = {
-+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
-+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
-+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
-+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
-+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
-+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
-+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
-+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
-+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
-+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
-+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
-+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
-+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
-+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
-+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
-+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
-+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
-+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
-+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
-+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
-+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
-+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
-+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
-+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
-+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
-+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
-+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
-+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
-+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
-+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
-+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
-+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
-+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
-+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
-+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
-+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
-+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
-+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
-+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
-+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
-+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
-+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
-+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
-+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
-+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
-+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
-+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
-+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
-+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
-+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
-+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
-+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
-+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
-+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
-+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
-+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
-+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
-+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
-+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
-+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
-+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
-+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
-+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
-+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
-+};
-+static const u32 Te1[256] = {
-+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
-+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
-+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
-+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
-+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
-+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
-+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
-+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
-+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
-+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
-+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
-+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
-+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
-+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
-+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
-+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
-+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
-+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
-+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
-+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
-+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
-+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
-+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
-+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
-+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
-+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
-+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
-+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
-+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
-+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
-+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
-+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
-+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
-+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
-+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
-+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
-+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
-+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
-+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
-+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
-+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
-+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
-+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
-+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
-+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
-+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
-+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
-+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
-+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
-+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
-+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
-+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
-+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
-+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
-+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
-+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
-+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
-+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
-+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
-+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
-+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
-+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
-+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
-+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
-+};
-+static const u32 Te2[256] = {
-+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
-+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
-+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
-+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
-+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
-+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
-+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
-+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
-+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
-+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
-+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
-+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
-+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
-+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
-+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
-+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
-+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
-+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
-+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
-+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
-+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
-+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
-+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
-+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
-+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
-+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
-+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
-+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
-+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
-+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
-+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
-+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
-+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
-+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
-+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
-+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
-+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
-+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
-+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
-+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
-+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
-+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
-+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
-+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
-+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
-+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
-+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
-+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
-+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
-+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
-+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
-+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
-+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
-+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
-+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
-+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
-+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
-+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
-+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
-+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
-+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
-+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
-+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
-+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
-+};
-+static const u32 Te3[256] = {
-+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
-+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
-+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
-+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
-+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
-+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
-+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
-+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
-+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
-+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
-+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
-+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
-+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
-+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
-+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
-+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
-+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
-+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
-+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
-+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
-+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
-+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
-+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
-+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
-+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
-+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
-+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
-+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
-+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
-+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
-+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
-+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
-+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
-+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
-+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
-+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
-+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
-+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
-+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
-+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
-+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
-+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
-+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
-+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
-+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
-+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
-+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
-+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
-+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
-+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
-+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
-+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
-+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
-+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
-+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
-+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
-+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
-+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
-+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
-+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
-+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
-+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
-+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
-+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
-+};
-+
-+static const u32 Td0[256] = {
-+    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
-+    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
-+    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
-+    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
-+    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
-+    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
-+    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
-+    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
-+    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
-+    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
-+    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
-+    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
-+    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
-+    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
-+    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
-+    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
-+    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
-+    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
-+    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
-+    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
-+    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
-+    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
-+    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
-+    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
-+    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
-+    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
-+    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
-+    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
-+    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
-+    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
-+    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
-+    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
-+    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
-+    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
-+    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
-+    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
-+    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
-+    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
-+    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
-+    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
-+    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
-+    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
-+    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
-+    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
-+    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
-+    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
-+    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
-+    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
-+    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
-+    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
-+    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
-+    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
-+    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
-+    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
-+    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
-+    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
-+    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
-+    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
-+    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
-+    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
-+    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
-+    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
-+    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
-+    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
-+};
-+static const u32 Td1[256] = {
-+    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
-+    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
-+    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
-+    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
-+    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
-+    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
-+    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
-+    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
-+    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
-+    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
-+    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
-+    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
-+    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
-+    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
-+    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
-+    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
-+    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
-+    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
-+    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
-+    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
-+    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
-+    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
-+    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
-+    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
-+    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
-+    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
-+    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
-+    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
-+    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
-+    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
-+    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
-+    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
-+    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
-+    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
-+    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
-+    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
-+    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
-+    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
-+    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
-+    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
-+    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
-+    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
-+    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
-+    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
-+    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
-+    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
-+    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
-+    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
-+    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
-+    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
-+    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
-+    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
-+    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
-+    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
-+    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
-+    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
-+    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
-+    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
-+    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
-+    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
-+    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
-+    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
-+    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
-+    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
-+};
-+static const u32 Td2[256] = {
-+    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
-+    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
-+    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
-+    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
-+    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
-+    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
-+    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
-+    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
-+    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
-+    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
-+    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
-+    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
-+    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
-+    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
-+    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
-+    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
-+    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
-+    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
-+    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
-+    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
-+    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
-+    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
-+    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
-+    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
-+    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
-+    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
-+    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
-+    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
-+    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
-+    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
-+    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
-+    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
-+    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
-+    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
-+    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
-+    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
-+    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
-+    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
-+    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
-+    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
-+    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
-+    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
-+    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
-+    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
-+    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
-+    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
-+    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
-+    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
-+    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
-+    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
-+    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
-+    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
-+    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
-+    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
-+    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
-+    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
-+    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
-+    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
-+    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
-+    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
-+    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
-+    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
-+    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
-+    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
-+};
-+static const u32 Td3[256] = {
-+    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
-+    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
-+    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
-+    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
-+    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
-+    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
-+    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
-+    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
-+    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
-+    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
-+    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
-+    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
-+    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
-+    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
-+    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
-+    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
-+    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
-+    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
-+    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
-+    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
-+    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
-+    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
-+    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
-+    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
-+    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
-+    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
-+    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
-+    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
-+    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
-+    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
-+    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
-+    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
-+    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
-+    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
-+    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
-+    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
-+    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
-+    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
-+    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
-+    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
-+    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
-+    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
-+    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
-+    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
-+    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
-+    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
-+    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
-+    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
-+    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
-+    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
-+    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
-+    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
-+    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
-+    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
-+    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
-+    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
-+    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
-+    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
-+    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
-+    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
-+    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
-+    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
-+    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
-+    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
-+};
-+static const u8 Td4[256] = {
-+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
-+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
-+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
-+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
-+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
-+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
-+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
-+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
-+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
-+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
-+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
-+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
-+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
-+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
-+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
-+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
-+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
-+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
-+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
-+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
-+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
-+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
-+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
-+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
-+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
-+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
-+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
-+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
-+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
-+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
-+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
-+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
-+};
-+static const u32 rcon[] = {
-+    0x01000000, 0x02000000, 0x04000000, 0x08000000,
-+    0x10000000, 0x20000000, 0x40000000, 0x80000000,
-+    0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-+};
-+
-+/**
-+ * Expand the cipher key into the encryption key schedule.
-+ */
-+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
-+                        AES_KEY *key)
-+{
-+
-+    u32 *rk;
-+    int i = 0;
-+    u32 temp;
-+
-+    if (!userKey || !key)
-+        return -1;
-+    if (bits != 128 && bits != 192 && bits != 256)
-+        return -2;
-+
-+    rk = key->rd_key;
-+
-+    if (bits == 128)
-+        key->rounds = 10;
-+    else if (bits == 192)
-+        key->rounds = 12;
-+    else
-+        key->rounds = 14;
-+
-+    rk[0] = GETU32(userKey     );
-+    rk[1] = GETU32(userKey +  4);
-+    rk[2] = GETU32(userKey +  8);
-+    rk[3] = GETU32(userKey + 12);
-+    if (bits == 128) {
-+        while (1) {
-+            temp  = rk[3];
-+            rk[4] = rk[0] ^
-+                (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
-+                (Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
-+                (Te0[(temp      ) & 0xff] & 0x0000ff00) ^
-+                (Te1[(temp >> 24)       ] & 0x000000ff) ^
-+                rcon[i];
-+            rk[5] = rk[1] ^ rk[4];
-+            rk[6] = rk[2] ^ rk[5];
-+            rk[7] = rk[3] ^ rk[6];
-+            if (++i == 10) {
-+                return 0;
-+            }
-+            rk += 4;
-+        }
-+    }
-+    rk[4] = GETU32(userKey + 16);
-+    rk[5] = GETU32(userKey + 20);
-+    if (bits == 192) {
-+        while (1) {
-+            temp = rk[ 5];
-+            rk[ 6] = rk[ 0] ^
-+                (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
-+                (Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
-+                (Te0[(temp      ) & 0xff] & 0x0000ff00) ^
-+                (Te1[(temp >> 24)       ] & 0x000000ff) ^
-+                rcon[i];
-+            rk[ 7] = rk[ 1] ^ rk[ 6];
-+            rk[ 8] = rk[ 2] ^ rk[ 7];
-+            rk[ 9] = rk[ 3] ^ rk[ 8];
-+            if (++i == 8) {
-+                return 0;
-+            }
-+            rk[10] = rk[ 4] ^ rk[ 9];
-+            rk[11] = rk[ 5] ^ rk[10];
-+            rk += 6;
-+        }
-+    }
-+    rk[6] = GETU32(userKey + 24);
-+    rk[7] = GETU32(userKey + 28);
-+    if (bits == 256) {
-+        while (1) {
-+            temp = rk[ 7];
-+            rk[ 8] = rk[ 0] ^
-+                (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
-+                (Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
-+                (Te0[(temp      ) & 0xff] & 0x0000ff00) ^
-+                (Te1[(temp >> 24)       ] & 0x000000ff) ^
-+                rcon[i];
-+            rk[ 9] = rk[ 1] ^ rk[ 8];
-+            rk[10] = rk[ 2] ^ rk[ 9];
-+            rk[11] = rk[ 3] ^ rk[10];
-+            if (++i == 7) {
-+                return 0;
-+            }
-+            temp = rk[11];
-+            rk[12] = rk[ 4] ^
-+                (Te2[(temp >> 24)       ] & 0xff000000) ^
-+                (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
-+                (Te0[(temp >>  8) & 0xff] & 0x0000ff00) ^
-+                (Te1[(temp      ) & 0xff] & 0x000000ff);
-+            rk[13] = rk[ 5] ^ rk[12];
-+            rk[14] = rk[ 6] ^ rk[13];
-+            rk[15] = rk[ 7] ^ rk[14];
-+
-+            rk += 8;
-+            }
-+    }
-+    return 0;
-+}
-+
-+/**
-+ * Expand the cipher key into the decryption key schedule.
-+ */
-+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
-+                        AES_KEY *key)
-+{
-+
-+    u32 *rk;
-+    int i, j, status;
-+    u32 temp;
-+
-+    /* first, start with an encryption schedule */
-+    status = AES_set_encrypt_key(userKey, bits, key);
-+    if (status < 0)
-+        return status;
-+
-+    rk = key->rd_key;
-+
-+    /* invert the order of the round keys: */
-+    for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
-+        temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
-+        temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
-+        temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
-+        temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
-+    }
-+    /* apply the inverse MixColumn transform to all round keys but the first and the last: */
-+    for (i = 1; i < (key->rounds); i++) {
-+        rk += 4;
-+        rk[0] =
-+            Td0[Te1[(rk[0] >> 24)       ] & 0xff] ^
-+            Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
-+            Td2[Te1[(rk[0] >>  8) & 0xff] & 0xff] ^
-+            Td3[Te1[(rk[0]      ) & 0xff] & 0xff];
-+        rk[1] =
-+            Td0[Te1[(rk[1] >> 24)       ] & 0xff] ^
-+            Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
-+            Td2[Te1[(rk[1] >>  8) & 0xff] & 0xff] ^
-+            Td3[Te1[(rk[1]      ) & 0xff] & 0xff];
-+        rk[2] =
-+            Td0[Te1[(rk[2] >> 24)       ] & 0xff] ^
-+            Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
-+            Td2[Te1[(rk[2] >>  8) & 0xff] & 0xff] ^
-+            Td3[Te1[(rk[2]      ) & 0xff] & 0xff];
-+        rk[3] =
-+            Td0[Te1[(rk[3] >> 24)       ] & 0xff] ^
-+            Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
-+            Td2[Te1[(rk[3] >>  8) & 0xff] & 0xff] ^
-+            Td3[Te1[(rk[3]      ) & 0xff] & 0xff];
-+    }
-+    return 0;
-+}
-+
-+/*
-+ * Encrypt a single block
-+ * in and out can overlap
-+ */
-+void AES_encrypt(const unsigned char *in, unsigned char *out,
-+                 const AES_KEY *key) {
-+
-+    const u32 *rk;
-+    u32 s0, s1, s2, s3, t0, t1, t2, t3;
-+#ifndef FULL_UNROLL
-+    int r;
-+#endif /* ?FULL_UNROLL */
-+
-+    assert(in && out && key);
-+    rk = key->rd_key;
-+
-+    /*
-+     * map byte array block to cipher state
-+     * and add initial round key:
-+     */
-+    s0 = GETU32(in     ) ^ rk[0];
-+    s1 = GETU32(in +  4) ^ rk[1];
-+    s2 = GETU32(in +  8) ^ rk[2];
-+    s3 = GETU32(in + 12) ^ rk[3];
-+#ifdef FULL_UNROLL
-+    /* round 1: */
-+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
-+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
-+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
-+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
-+    /* round 2: */
-+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
-+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
-+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
-+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
-+    /* round 3: */
-+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
-+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
-+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
-+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
-+    /* round 4: */
-+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
-+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
-+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
-+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
-+    /* round 5: */
-+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
-+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
-+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
-+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
-+    /* round 6: */
-+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
-+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
-+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
-+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
-+    /* round 7: */
-+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
-+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
-+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
-+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
-+    /* round 8: */
-+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
-+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
-+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
-+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
-+    /* round 9: */
-+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
-+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
-+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
-+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
-+    if (key->rounds > 10) {
-+        /* round 10: */
-+        s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
-+        s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
-+        s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
-+        s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
-+        /* round 11: */
-+        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
-+        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
-+        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
-+        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
-+        if (key->rounds > 12) {
-+            /* round 12: */
-+            s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
-+            s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
-+            s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
-+            s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
-+            /* round 13: */
-+            t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
-+            t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
-+            t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
-+            t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
-+        }
-+    }
-+    rk += key->rounds << 2;
-+#else  /* !FULL_UNROLL */
-+    /*
-+     * Nr - 1 full rounds:
-+     */
-+    r = key->rounds >> 1;
-+    for (;;) {
-+        t0 =
-+            Te0[(s0 >> 24)       ] ^
-+            Te1[(s1 >> 16) & 0xff] ^
-+            Te2[(s2 >>  8) & 0xff] ^
-+            Te3[(s3      ) & 0xff] ^
-+            rk[4];
-+        t1 =
-+            Te0[(s1 >> 24)       ] ^
-+            Te1[(s2 >> 16) & 0xff] ^
-+            Te2[(s3 >>  8) & 0xff] ^
-+            Te3[(s0      ) & 0xff] ^
-+            rk[5];
-+        t2 =
-+            Te0[(s2 >> 24)       ] ^
-+            Te1[(s3 >> 16) & 0xff] ^
-+            Te2[(s0 >>  8) & 0xff] ^
-+            Te3[(s1      ) & 0xff] ^
-+            rk[6];
-+        t3 =
-+            Te0[(s3 >> 24)       ] ^
-+            Te1[(s0 >> 16) & 0xff] ^
-+            Te2[(s1 >>  8) & 0xff] ^
-+            Te3[(s2      ) & 0xff] ^
-+            rk[7];
-+
-+        rk += 8;
-+        if (--r == 0) {
-+            break;
-+        }
-+
-+        s0 =
-+            Te0[(t0 >> 24)       ] ^
-+            Te1[(t1 >> 16) & 0xff] ^
-+            Te2[(t2 >>  8) & 0xff] ^
-+            Te3[(t3      ) & 0xff] ^
-+            rk[0];
-+        s1 =
-+            Te0[(t1 >> 24)       ] ^
-+            Te1[(t2 >> 16) & 0xff] ^
-+            Te2[(t3 >>  8) & 0xff] ^
-+            Te3[(t0      ) & 0xff] ^
-+            rk[1];
-+        s2 =
-+            Te0[(t2 >> 24)       ] ^
-+            Te1[(t3 >> 16) & 0xff] ^
-+            Te2[(t0 >>  8) & 0xff] ^
-+            Te3[(t1      ) & 0xff] ^
-+            rk[2];
-+        s3 =
-+            Te0[(t3 >> 24)       ] ^
-+            Te1[(t0 >> 16) & 0xff] ^
-+            Te2[(t1 >>  8) & 0xff] ^
-+            Te3[(t2      ) & 0xff] ^
-+            rk[3];
-+    }
-+#endif /* ?FULL_UNROLL */
-+    /*
-+     * apply last round and
-+     * map cipher state to byte array block:
-+     */
-+    s0 =
-+        (Te2[(t0 >> 24)       ] & 0xff000000) ^
-+        (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
-+        (Te0[(t2 >>  8) & 0xff] & 0x0000ff00) ^
-+        (Te1[(t3      ) & 0xff] & 0x000000ff) ^
-+        rk[0];
-+    PUTU32(out     , s0);
-+    s1 =
-+        (Te2[(t1 >> 24)       ] & 0xff000000) ^
-+        (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
-+        (Te0[(t3 >>  8) & 0xff] & 0x0000ff00) ^
-+        (Te1[(t0      ) & 0xff] & 0x000000ff) ^
-+        rk[1];
-+    PUTU32(out +  4, s1);
-+    s2 =
-+        (Te2[(t2 >> 24)       ] & 0xff000000) ^
-+        (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
-+        (Te0[(t0 >>  8) & 0xff] & 0x0000ff00) ^
-+        (Te1[(t1      ) & 0xff] & 0x000000ff) ^
-+        rk[2];
-+    PUTU32(out +  8, s2);
-+    s3 =
-+        (Te2[(t3 >> 24)       ] & 0xff000000) ^
-+        (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
-+        (Te0[(t1 >>  8) & 0xff] & 0x0000ff00) ^
-+        (Te1[(t2      ) & 0xff] & 0x000000ff) ^
-+        rk[3];
-+    PUTU32(out + 12, s3);
-+}
-+
-+/*
-+ * Decrypt a single block
-+ * in and out can overlap
-+ */
-+void AES_decrypt(const unsigned char *in, unsigned char *out,
-+                 const AES_KEY *key)
-+{
-+
-+    const u32 *rk;
-+    u32 s0, s1, s2, s3, t0, t1, t2, t3;
-+#ifndef FULL_UNROLL
-+    int r;
-+#endif /* ?FULL_UNROLL */
-+
-+    assert(in && out && key);
-+    rk = key->rd_key;
-+
-+    /*
-+     * map byte array block to cipher state
-+     * and add initial round key:
-+     */
-+    s0 = GETU32(in     ) ^ rk[0];
-+    s1 = GETU32(in +  4) ^ rk[1];
-+    s2 = GETU32(in +  8) ^ rk[2];
-+    s3 = GETU32(in + 12) ^ rk[3];
-+#ifdef FULL_UNROLL
-+    /* round 1: */
-+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
-+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
-+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
-+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
-+    /* round 2: */
-+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
-+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
-+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
-+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
-+    /* round 3: */
-+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
-+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
-+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
-+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
-+    /* round 4: */
-+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
-+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
-+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
-+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
-+    /* round 5: */
-+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
-+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
-+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
-+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
-+    /* round 6: */
-+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
-+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
-+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
-+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
-+    /* round 7: */
-+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
-+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
-+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
-+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
-+    /* round 8: */
-+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
-+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
-+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
-+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
-+    /* round 9: */
-+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
-+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
-+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
-+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
-+    if (key->rounds > 10) {
-+        /* round 10: */
-+        s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
-+        s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
-+        s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
-+        s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
-+        /* round 11: */
-+        t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
-+        t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
-+        t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
-+        t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
-+        if (key->rounds > 12) {
-+            /* round 12: */
-+            s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
-+            s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
-+            s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
-+            s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
-+            /* round 13: */
-+            t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
-+            t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
-+            t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
-+            t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
-+        }
-+    }
-+    rk += key->rounds << 2;
-+#else  /* !FULL_UNROLL */
-+    /*
-+     * Nr - 1 full rounds:
-+     */
-+    r = key->rounds >> 1;
-+    for (;;) {
-+        t0 =
-+            Td0[(s0 >> 24)       ] ^
-+            Td1[(s3 >> 16) & 0xff] ^
-+            Td2[(s2 >>  8) & 0xff] ^
-+            Td3[(s1      ) & 0xff] ^
-+            rk[4];
-+        t1 =
-+            Td0[(s1 >> 24)       ] ^
-+            Td1[(s0 >> 16) & 0xff] ^
-+            Td2[(s3 >>  8) & 0xff] ^
-+            Td3[(s2      ) & 0xff] ^
-+            rk[5];
-+        t2 =
-+            Td0[(s2 >> 24)       ] ^
-+            Td1[(s1 >> 16) & 0xff] ^
-+            Td2[(s0 >>  8) & 0xff] ^
-+            Td3[(s3      ) & 0xff] ^
-+            rk[6];
-+        t3 =
-+            Td0[(s3 >> 24)       ] ^
-+            Td1[(s2 >> 16) & 0xff] ^
-+            Td2[(s1 >>  8) & 0xff] ^
-+            Td3[(s0      ) & 0xff] ^
-+            rk[7];
-+
-+        rk += 8;
-+        if (--r == 0) {
-+            break;
-+        }
-+
-+        s0 =
-+            Td0[(t0 >> 24)       ] ^
-+            Td1[(t3 >> 16) & 0xff] ^
-+            Td2[(t2 >>  8) & 0xff] ^
-+            Td3[(t1      ) & 0xff] ^
-+            rk[0];
-+        s1 =
-+            Td0[(t1 >> 24)       ] ^
-+            Td1[(t0 >> 16) & 0xff] ^
-+            Td2[(t3 >>  8) & 0xff] ^
-+            Td3[(t2      ) & 0xff] ^
-+            rk[1];
-+        s2 =
-+            Td0[(t2 >> 24)       ] ^
-+            Td1[(t1 >> 16) & 0xff] ^
-+            Td2[(t0 >>  8) & 0xff] ^
-+            Td3[(t3      ) & 0xff] ^
-+            rk[2];
-+        s3 =
-+            Td0[(t3 >> 24)       ] ^
-+            Td1[(t2 >> 16) & 0xff] ^
-+            Td2[(t1 >>  8) & 0xff] ^
-+            Td3[(t0      ) & 0xff] ^
-+            rk[3];
-+    }
-+#endif /* ?FULL_UNROLL */
-+    /*
-+     * apply last round and
-+     * map cipher state to byte array block:
-+     */
-+    s0 =
-+        ((u32)Td4[(t0 >> 24)       ] << 24) ^
-+        ((u32)Td4[(t3 >> 16) & 0xff] << 16) ^
-+        ((u32)Td4[(t2 >>  8) & 0xff] <<  8) ^
-+        ((u32)Td4[(t1      ) & 0xff])       ^
-+        rk[0];
-+    PUTU32(out     , s0);
-+    s1 =
-+        ((u32)Td4[(t1 >> 24)       ] << 24) ^
-+        ((u32)Td4[(t0 >> 16) & 0xff] << 16) ^
-+        ((u32)Td4[(t3 >>  8) & 0xff] <<  8) ^
-+        ((u32)Td4[(t2      ) & 0xff])       ^
-+        rk[1];
-+    PUTU32(out +  4, s1);
-+    s2 =
-+        ((u32)Td4[(t2 >> 24)       ] << 24) ^
-+        ((u32)Td4[(t1 >> 16) & 0xff] << 16) ^
-+        ((u32)Td4[(t0 >>  8) & 0xff] <<  8) ^
-+        ((u32)Td4[(t3      ) & 0xff])       ^
-+        rk[2];
-+    PUTU32(out +  8, s2);
-+    s3 =
-+        ((u32)Td4[(t3 >> 24)       ] << 24) ^
-+        ((u32)Td4[(t2 >> 16) & 0xff] << 16) ^
-+        ((u32)Td4[(t1 >>  8) & 0xff] <<  8) ^
-+        ((u32)Td4[(t0      ) & 0xff])       ^
-+        rk[3];
-+    PUTU32(out + 12, s3);
-+}
-+
-+#else /* AES_ASM */
-+
-+static const u8 Te4[256] = {
-+    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
-+    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
-+    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
-+    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
-+    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
-+    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
-+    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
-+    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
-+    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
-+    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
-+    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
-+    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
-+    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
-+    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
-+    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
-+    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
-+    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
-+    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
-+    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
-+    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
-+    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
-+    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
-+    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
-+    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
-+    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
-+    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
-+    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
-+    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
-+    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
-+    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
-+    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
-+    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
-+};
-+static const u32 rcon[] = {
-+    0x01000000, 0x02000000, 0x04000000, 0x08000000,
-+    0x10000000, 0x20000000, 0x40000000, 0x80000000,
-+    0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-+};
-+
-+/**
-+ * Expand the cipher key into the encryption key schedule.
-+ */
-+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
-+                        AES_KEY *key)
-+{
-+    u32 *rk;
-+    int i = 0;
-+    u32 temp;
-+
-+    if (!userKey || !key)
-+        return -1;
-+    if (bits != 128 && bits != 192 && bits != 256)
-+        return -2;
-+
-+    rk = key->rd_key;
-+
-+    if (bits == 128)
-+        key->rounds = 10;
-+    else if (bits == 192)
-+        key->rounds = 12;
-+    else
-+        key->rounds = 14;
-+
-+    rk[0] = GETU32(userKey     );
-+    rk[1] = GETU32(userKey +  4);
-+    rk[2] = GETU32(userKey +  8);
-+    rk[3] = GETU32(userKey + 12);
-+    if (bits == 128) {
-+        while (1) {
-+            temp  = rk[3];
-+            rk[4] = rk[0] ^
-+                ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
-+                ((u32)Te4[(temp >>  8) & 0xff] << 16) ^
-+                ((u32)Te4[(temp      ) & 0xff] << 8) ^
-+                ((u32)Te4[(temp >> 24)       ]) ^
-+                rcon[i];
-+            rk[5] = rk[1] ^ rk[4];
-+            rk[6] = rk[2] ^ rk[5];
-+            rk[7] = rk[3] ^ rk[6];
-+            if (++i == 10) {
-+                return 0;
-+            }
-+            rk += 4;
-+        }
-+    }
-+    rk[4] = GETU32(userKey + 16);
-+    rk[5] = GETU32(userKey + 20);
-+    if (bits == 192) {
-+        while (1) {
-+            temp = rk[ 5];
-+            rk[ 6] = rk[ 0] ^
-+                ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
-+                ((u32)Te4[(temp >>  8) & 0xff] << 16) ^
-+                ((u32)Te4[(temp      ) & 0xff] << 8) ^
-+                ((u32)Te4[(temp >> 24)       ]) ^
-+                rcon[i];
-+            rk[ 7] = rk[ 1] ^ rk[ 6];
-+            rk[ 8] = rk[ 2] ^ rk[ 7];
-+            rk[ 9] = rk[ 3] ^ rk[ 8];
-+            if (++i == 8) {
-+                return 0;
-+            }
-+            rk[10] = rk[ 4] ^ rk[ 9];
-+            rk[11] = rk[ 5] ^ rk[10];
-+            rk += 6;
-+        }
-+    }
-+    rk[6] = GETU32(userKey + 24);
-+    rk[7] = GETU32(userKey + 28);
-+    if (bits == 256) {
-+        while (1) {
-+            temp = rk[ 7];
-+            rk[ 8] = rk[ 0] ^
-+                ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
-+                ((u32)Te4[(temp >>  8) & 0xff] << 16) ^
-+                ((u32)Te4[(temp      ) & 0xff] << 8) ^
-+                ((u32)Te4[(temp >> 24)       ]) ^
-+                rcon[i];
-+            rk[ 9] = rk[ 1] ^ rk[ 8];
-+            rk[10] = rk[ 2] ^ rk[ 9];
-+            rk[11] = rk[ 3] ^ rk[10];
-+            if (++i == 7) {
-+                return 0;
-+            }
-+            temp = rk[11];
-+            rk[12] = rk[ 4] ^
-+                ((u32)Te4[(temp >> 24)       ] << 24) ^
-+                ((u32)Te4[(temp >> 16) & 0xff] << 16) ^
-+                ((u32)Te4[(temp >>  8) & 0xff] << 8) ^
-+                ((u32)Te4[(temp      ) & 0xff]);
-+            rk[13] = rk[ 5] ^ rk[12];
-+            rk[14] = rk[ 6] ^ rk[13];
-+            rk[15] = rk[ 7] ^ rk[14];
-+
-+            rk += 8;
-+        }
-+    }
-+    return 0;
-+}
-+
-+/**
-+ * Expand the cipher key into the decryption key schedule.
-+ */
-+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
-+                        AES_KEY *key)
-+{
-+
-+    u32 *rk;
-+    int i, j, status;
-+    u32 temp;
-+
-+    /* first, start with an encryption schedule */
-+    status = AES_set_encrypt_key(userKey, bits, key);
-+    if (status < 0)
-+        return status;
-+
-+    rk = key->rd_key;
-+
-+    /* invert the order of the round keys: */
-+    for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
-+        temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
-+        temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
-+        temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
-+        temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
-+    }
-+    /* apply the inverse MixColumn transform to all round keys but the first and the last: */
-+    for (i = 1; i < (key->rounds); i++) {
-+        rk += 4;
-+        for (j = 0; j < 4; j++) {
-+            u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
-+
-+            tp1 = rk[j];
-+            m = tp1 & 0x80808080;
-+            tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            m = tp2 & 0x80808080;
-+            tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            m = tp4 & 0x80808080;
-+            tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            tp9 = tp8 ^ tp1;
-+            tpb = tp9 ^ tp2;
-+            tpd = tp9 ^ tp4;
-+            tpe = tp8 ^ tp4 ^ tp2;
-+#if defined(ROTATE)
-+            rk[j] = tpe ^ ROTATE(tpd,16) ^
-+                ROTATE(tp9,24) ^ ROTATE(tpb,8);
-+#else
-+            rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
-+                (tp9 >> 8) ^ (tp9 << 24) ^
-+                (tpb >> 24) ^ (tpb << 8);
-+#endif
-+        }
-+    }
-+    return 0;
-+}
-+
-+#endif /* AES_ASM */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ecb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ecb.c
-new file mode 100644
-index 0000000..29bfc1a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ecb.c
-@@ -0,0 +1,26 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#include 
-+#include "aes_locl.h"
-+
-+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
-+                     const AES_KEY *key, const int enc)
-+{
-+
-+    assert(in && out && key);
-+    assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
-+
-+    if (AES_ENCRYPT == enc)
-+        AES_encrypt(in, out, key);
-+    else
-+        AES_decrypt(in, out, key);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ige.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ige.c
-new file mode 100644
-index 0000000..9125264
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ige.c
-@@ -0,0 +1,281 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+
-+#include 
-+#include "aes_locl.h"
-+
-+#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
-+typedef struct {
-+    unsigned long data[N_WORDS];
-+} aes_block_t;
-+
-+/* XXX: probably some better way to do this */
-+#if defined(__i386__) || defined(__x86_64__)
-+# define UNALIGNED_MEMOPS_ARE_FAST 1
-+#else
-+# define UNALIGNED_MEMOPS_ARE_FAST 0
-+#endif
-+
-+#if UNALIGNED_MEMOPS_ARE_FAST
-+# define load_block(d, s)        (d) = *(const aes_block_t *)(s)
-+# define store_block(d, s)       *(aes_block_t *)(d) = (s)
-+#else
-+# define load_block(d, s)        memcpy((d).data, (s), AES_BLOCK_SIZE)
-+# define store_block(d, s)       memcpy((d), (s).data, AES_BLOCK_SIZE)
-+#endif
-+
-+/* N.B. The IV for this mode is _twice_ the block size */
-+
-+void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
-+                     size_t length, const AES_KEY *key,
-+                     unsigned char *ivec, const int enc)
-+{
-+    size_t n;
-+    size_t len = length;
-+
-+    OPENSSL_assert(in && out && key && ivec);
-+    OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
-+    OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);
-+
-+    len = length / AES_BLOCK_SIZE;
-+
-+    if (AES_ENCRYPT == enc) {
-+        if (in != out &&
-+            (UNALIGNED_MEMOPS_ARE_FAST
-+             || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) ==
-+             0)) {
-+            aes_block_t *ivp = (aes_block_t *) ivec;
-+            aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE);
-+
-+            while (len) {
-+                aes_block_t *inp = (aes_block_t *) in;
-+                aes_block_t *outp = (aes_block_t *) out;
-+
-+                for (n = 0; n < N_WORDS; ++n)
-+                    outp->data[n] = inp->data[n] ^ ivp->data[n];
-+                AES_encrypt((unsigned char *)outp->data,
-+                            (unsigned char *)outp->data, key);
-+                for (n = 0; n < N_WORDS; ++n)
-+                    outp->data[n] ^= iv2p->data[n];
-+                ivp = outp;
-+                iv2p = inp;
-+                --len;
-+                in += AES_BLOCK_SIZE;
-+                out += AES_BLOCK_SIZE;
-+            }
-+            memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
-+            memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
-+        } else {
-+            aes_block_t tmp, tmp2;
-+            aes_block_t iv;
-+            aes_block_t iv2;
-+
-+            load_block(iv, ivec);
-+            load_block(iv2, ivec + AES_BLOCK_SIZE);
-+
-+            while (len) {
-+                load_block(tmp, in);
-+                for (n = 0; n < N_WORDS; ++n)
-+                    tmp2.data[n] = tmp.data[n] ^ iv.data[n];
-+                AES_encrypt((unsigned char *)tmp2.data,
-+                            (unsigned char *)tmp2.data, key);
-+                for (n = 0; n < N_WORDS; ++n)
-+                    tmp2.data[n] ^= iv2.data[n];
-+                store_block(out, tmp2);
-+                iv = tmp2;
-+                iv2 = tmp;
-+                --len;
-+                in += AES_BLOCK_SIZE;
-+                out += AES_BLOCK_SIZE;
-+            }
-+            memcpy(ivec, iv.data, AES_BLOCK_SIZE);
-+            memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
-+        }
-+    } else {
-+        if (in != out &&
-+            (UNALIGNED_MEMOPS_ARE_FAST
-+             || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) ==
-+             0)) {
-+            aes_block_t *ivp = (aes_block_t *) ivec;
-+            aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE);
-+
-+            while (len) {
-+                aes_block_t tmp;
-+                aes_block_t *inp = (aes_block_t *) in;
-+                aes_block_t *outp = (aes_block_t *) out;
-+
-+                for (n = 0; n < N_WORDS; ++n)
-+                    tmp.data[n] = inp->data[n] ^ iv2p->data[n];
-+                AES_decrypt((unsigned char *)tmp.data,
-+                            (unsigned char *)outp->data, key);
-+                for (n = 0; n < N_WORDS; ++n)
-+                    outp->data[n] ^= ivp->data[n];
-+                ivp = inp;
-+                iv2p = outp;
-+                --len;
-+                in += AES_BLOCK_SIZE;
-+                out += AES_BLOCK_SIZE;
-+            }
-+            memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
-+            memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
-+        } else {
-+            aes_block_t tmp, tmp2;
-+            aes_block_t iv;
-+            aes_block_t iv2;
-+
-+            load_block(iv, ivec);
-+            load_block(iv2, ivec + AES_BLOCK_SIZE);
-+
-+            while (len) {
-+                load_block(tmp, in);
-+                tmp2 = tmp;
-+                for (n = 0; n < N_WORDS; ++n)
-+                    tmp.data[n] ^= iv2.data[n];
-+                AES_decrypt((unsigned char *)tmp.data,
-+                            (unsigned char *)tmp.data, key);
-+                for (n = 0; n < N_WORDS; ++n)
-+                    tmp.data[n] ^= iv.data[n];
-+                store_block(out, tmp);
-+                iv = tmp2;
-+                iv2 = tmp;
-+                --len;
-+                in += AES_BLOCK_SIZE;
-+                out += AES_BLOCK_SIZE;
-+            }
-+            memcpy(ivec, iv.data, AES_BLOCK_SIZE);
-+            memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
-+        }
-+    }
-+}
-+
-+/*
-+ * Note that its effectively impossible to do biIGE in anything other
-+ * than a single pass, so no provision is made for chaining.
-+ */
-+
-+/* N.B. The IV for this mode is _four times_ the block size */
-+
-+void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
-+                        size_t length, const AES_KEY *key,
-+                        const AES_KEY *key2, const unsigned char *ivec,
-+                        const int enc)
-+{
-+    size_t n;
-+    size_t len = length;
-+    unsigned char tmp[AES_BLOCK_SIZE];
-+    unsigned char tmp2[AES_BLOCK_SIZE];
-+    unsigned char tmp3[AES_BLOCK_SIZE];
-+    unsigned char prev[AES_BLOCK_SIZE];
-+    const unsigned char *iv;
-+    const unsigned char *iv2;
-+
-+    OPENSSL_assert(in && out && key && ivec);
-+    OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
-+    OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);
-+
-+    if (AES_ENCRYPT == enc) {
-+        /*
-+         * XXX: Do a separate case for when in != out (strictly should check
-+         * for overlap, too)
-+         */
-+
-+        /* First the forward pass */
-+        iv = ivec;
-+        iv2 = ivec + AES_BLOCK_SIZE;
-+        while (len >= AES_BLOCK_SIZE) {
-+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
-+                out[n] = in[n] ^ iv[n];
-+            AES_encrypt(out, out, key);
-+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
-+                out[n] ^= iv2[n];
-+            iv = out;
-+            memcpy(prev, in, AES_BLOCK_SIZE);
-+            iv2 = prev;
-+            len -= AES_BLOCK_SIZE;
-+            in += AES_BLOCK_SIZE;
-+            out += AES_BLOCK_SIZE;
-+        }
-+
-+        /* And now backwards */
-+        iv = ivec + AES_BLOCK_SIZE * 2;
-+        iv2 = ivec + AES_BLOCK_SIZE * 3;
-+        len = length;
-+        while (len >= AES_BLOCK_SIZE) {
-+            out -= AES_BLOCK_SIZE;
-+            /*
-+             * XXX: reduce copies by alternating between buffers
-+             */
-+            memcpy(tmp, out, AES_BLOCK_SIZE);
-+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
-+                out[n] ^= iv[n];
-+            /*
-+             * hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE);
-+             */
-+            AES_encrypt(out, out, key);
-+            /*
-+             * hexdump(stdout,"enc", out, AES_BLOCK_SIZE);
-+             */
-+            /*
-+             * hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE);
-+             */
-+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
-+                out[n] ^= iv2[n];
-+            /*
-+             * hexdump(stdout,"out", out, AES_BLOCK_SIZE);
-+             */
-+            iv = out;
-+            memcpy(prev, tmp, AES_BLOCK_SIZE);
-+            iv2 = prev;
-+            len -= AES_BLOCK_SIZE;
-+        }
-+    } else {
-+        /* First backwards */
-+        iv = ivec + AES_BLOCK_SIZE * 2;
-+        iv2 = ivec + AES_BLOCK_SIZE * 3;
-+        in += length;
-+        out += length;
-+        while (len >= AES_BLOCK_SIZE) {
-+            in -= AES_BLOCK_SIZE;
-+            out -= AES_BLOCK_SIZE;
-+            memcpy(tmp, in, AES_BLOCK_SIZE);
-+            memcpy(tmp2, in, AES_BLOCK_SIZE);
-+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
-+                tmp[n] ^= iv2[n];
-+            AES_decrypt(tmp, out, key);
-+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
-+                out[n] ^= iv[n];
-+            memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
-+            iv = tmp3;
-+            iv2 = out;
-+            len -= AES_BLOCK_SIZE;
-+        }
-+
-+        /* And now forwards */
-+        iv = ivec;
-+        iv2 = ivec + AES_BLOCK_SIZE;
-+        len = length;
-+        while (len >= AES_BLOCK_SIZE) {
-+            memcpy(tmp, out, AES_BLOCK_SIZE);
-+            memcpy(tmp2, out, AES_BLOCK_SIZE);
-+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
-+                tmp[n] ^= iv2[n];
-+            AES_decrypt(tmp, out, key);
-+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
-+                out[n] ^= iv[n];
-+            memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
-+            iv = tmp3;
-+            iv2 = out;
-+            len -= AES_BLOCK_SIZE;
-+            in += AES_BLOCK_SIZE;
-+            out += AES_BLOCK_SIZE;
-+        }
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_locl.h
-new file mode 100644
-index 0000000..adee29d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_locl.h
-@@ -0,0 +1,42 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_AES_LOCL_H
-+# define HEADER_AES_LOCL_H
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+
-+# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
-+#  define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
-+#  define GETU32(p) SWAP(*((u32 *)(p)))
-+#  define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
-+# else
-+#  define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
-+#  define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
-+# endif
-+
-+# ifdef AES_LONG
-+typedef unsigned long u32;
-+# else
-+typedef unsigned int u32;
-+# endif
-+typedef unsigned short u16;
-+typedef unsigned char u8;
-+
-+# define MAXKC   (256/32)
-+# define MAXKB   (256/8)
-+# define MAXNR   14
-+
-+/* This controls loop-unrolling in aes_core.c */
-+# undef FULL_UNROLL
-+
-+#endif                          /* !HEADER_AES_LOCL_H */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_misc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_misc.c
-new file mode 100644
-index 0000000..7403c84
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_misc.c
-@@ -0,0 +1,21 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "aes_locl.h"
-+
-+const char *AES_options(void)
-+{
-+#ifdef FULL_UNROLL
-+    return "aes(full)";
-+#else
-+    return "aes(partial)";
-+#endif
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ofb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ofb.c
-new file mode 100644
-index 0000000..215b538
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_ofb.c
-@@ -0,0 +1,19 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
-+                        size_t length, const AES_KEY *key,
-+                        unsigned char *ivec, int *num)
-+{
-+    CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
-+                          (block128_f) AES_encrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_wrap.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_wrap.c
-new file mode 100644
-index 0000000..cae0b21
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_wrap.c
-@@ -0,0 +1,27 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
-+                 unsigned char *out,
-+                 const unsigned char *in, unsigned int inlen)
-+{
-+    return CRYPTO_128_wrap(key, iv, out, in, inlen, (block128_f) AES_encrypt);
-+}
-+
-+int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
-+                   unsigned char *out,
-+                   const unsigned char *in, unsigned int inlen)
-+{
-+    return CRYPTO_128_unwrap(key, iv, out, in, inlen,
-+                             (block128_f) AES_decrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_x86core.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_x86core.c
-new file mode 100644
-index 0000000..95b49bb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/aes_x86core.c
-@@ -0,0 +1,1075 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/**
-+ * rijndael-alg-fst.c
-+ *
-+ * @version 3.0 (December 2000)
-+ *
-+ * Optimised ANSI C code for the Rijndael cipher (now AES)
-+ *
-+ * @author Vincent Rijmen 
-+ * @author Antoon Bosselaers 
-+ * @author Paulo Barreto 
-+ *
-+ * This code is hereby placed in the public domain.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
-+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * This is experimental x86[_64] derivative. It assumes little-endian
-+ * byte order and expects CPU to sustain unaligned memory references.
-+ * It is used as playground for cache-time attack mitigations and
-+ * serves as reference C implementation for x86[_64] assembler.
-+ *
-+ *                  
-+ */
-+
-+
-+#include 
-+
-+#include 
-+#include 
-+#include "aes_locl.h"
-+
-+/*
-+ * These two parameters control which table, 256-byte or 2KB, is
-+ * referenced in outer and respectively inner rounds.
-+ */
-+#define AES_COMPACT_IN_OUTER_ROUNDS
-+#ifdef  AES_COMPACT_IN_OUTER_ROUNDS
-+/* AES_COMPACT_IN_OUTER_ROUNDS costs ~30% in performance, while
-+ * adding AES_COMPACT_IN_INNER_ROUNDS reduces benchmark *further*
-+ * by factor of ~2. */
-+# undef  AES_COMPACT_IN_INNER_ROUNDS
-+#endif
-+
-+#if 1
-+static void prefetch256(const void *table)
-+{
-+    volatile unsigned long *t=(void *)table,ret;
-+    unsigned long sum;
-+    int i;
-+
-+    /* 32 is common least cache-line size */
-+    for (sum=0,i=0;i<256/sizeof(t[0]);i+=32/sizeof(t[0]))   sum ^= t[i];
-+
-+    ret = sum;
-+}
-+#else
-+# define prefetch256(t)
-+#endif
-+
-+#undef GETU32
-+#define GETU32(p) (*((u32*)(p)))
-+
-+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
-+typedef unsigned __int64 u64;
-+#define U64(C)  C##UI64
-+#elif defined(__arch64__)
-+typedef unsigned long u64;
-+#define U64(C)  C##UL
-+#else
-+typedef unsigned long long u64;
-+#define U64(C)  C##ULL
-+#endif
-+
-+#undef ROTATE
-+#if defined(_MSC_VER)
-+# define ROTATE(a,n)    _lrotl(a,n)
-+#elif defined(__ICC)
-+# define ROTATE(a,n)    _rotl(a,n)
-+#elif defined(__GNUC__) && __GNUC__>=2
-+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
-+#   define ROTATE(a,n)  ({ register unsigned int ret;   \
-+                asm (           \
-+                "roll %1,%0"        \
-+                : "=r"(ret)     \
-+                : "I"(n), "0"(a)    \
-+                : "cc");        \
-+               ret;             \
-+            })
-+# endif
-+#endif
-+/*-
-+Te [x] = S [x].[02, 01, 01, 03, 02, 01, 01, 03];
-+Te0[x] = S [x].[02, 01, 01, 03];
-+Te1[x] = S [x].[03, 02, 01, 01];
-+Te2[x] = S [x].[01, 03, 02, 01];
-+Te3[x] = S [x].[01, 01, 03, 02];
-+*/
-+#define Te0 (u32)((u64*)((u8*)Te+0))
-+#define Te1 (u32)((u64*)((u8*)Te+3))
-+#define Te2 (u32)((u64*)((u8*)Te+2))
-+#define Te3 (u32)((u64*)((u8*)Te+1))
-+/*-
-+Td [x] = Si[x].[0e, 09, 0d, 0b, 0e, 09, 0d, 0b];
-+Td0[x] = Si[x].[0e, 09, 0d, 0b];
-+Td1[x] = Si[x].[0b, 0e, 09, 0d];
-+Td2[x] = Si[x].[0d, 0b, 0e, 09];
-+Td3[x] = Si[x].[09, 0d, 0b, 0e];
-+Td4[x] = Si[x].[01];
-+*/
-+#define Td0 (u32)((u64*)((u8*)Td+0))
-+#define Td1 (u32)((u64*)((u8*)Td+3))
-+#define Td2 (u32)((u64*)((u8*)Td+2))
-+#define Td3 (u32)((u64*)((u8*)Td+1))
-+
-+static const u64 Te[256] = {
-+    U64(0xa56363c6a56363c6), U64(0x847c7cf8847c7cf8),
-+    U64(0x997777ee997777ee), U64(0x8d7b7bf68d7b7bf6),
-+    U64(0x0df2f2ff0df2f2ff), U64(0xbd6b6bd6bd6b6bd6),
-+    U64(0xb16f6fdeb16f6fde), U64(0x54c5c59154c5c591),
-+    U64(0x5030306050303060), U64(0x0301010203010102),
-+    U64(0xa96767cea96767ce), U64(0x7d2b2b567d2b2b56),
-+    U64(0x19fefee719fefee7), U64(0x62d7d7b562d7d7b5),
-+    U64(0xe6abab4de6abab4d), U64(0x9a7676ec9a7676ec),
-+    U64(0x45caca8f45caca8f), U64(0x9d82821f9d82821f),
-+    U64(0x40c9c98940c9c989), U64(0x877d7dfa877d7dfa),
-+    U64(0x15fafaef15fafaef), U64(0xeb5959b2eb5959b2),
-+    U64(0xc947478ec947478e), U64(0x0bf0f0fb0bf0f0fb),
-+    U64(0xecadad41ecadad41), U64(0x67d4d4b367d4d4b3),
-+    U64(0xfda2a25ffda2a25f), U64(0xeaafaf45eaafaf45),
-+    U64(0xbf9c9c23bf9c9c23), U64(0xf7a4a453f7a4a453),
-+    U64(0x967272e4967272e4), U64(0x5bc0c09b5bc0c09b),
-+    U64(0xc2b7b775c2b7b775), U64(0x1cfdfde11cfdfde1),
-+    U64(0xae93933dae93933d), U64(0x6a26264c6a26264c),
-+    U64(0x5a36366c5a36366c), U64(0x413f3f7e413f3f7e),
-+    U64(0x02f7f7f502f7f7f5), U64(0x4fcccc834fcccc83),
-+    U64(0x5c3434685c343468), U64(0xf4a5a551f4a5a551),
-+    U64(0x34e5e5d134e5e5d1), U64(0x08f1f1f908f1f1f9),
-+    U64(0x937171e2937171e2), U64(0x73d8d8ab73d8d8ab),
-+    U64(0x5331316253313162), U64(0x3f15152a3f15152a),
-+    U64(0x0c0404080c040408), U64(0x52c7c79552c7c795),
-+    U64(0x6523234665232346), U64(0x5ec3c39d5ec3c39d),
-+    U64(0x2818183028181830), U64(0xa1969637a1969637),
-+    U64(0x0f05050a0f05050a), U64(0xb59a9a2fb59a9a2f),
-+    U64(0x0907070e0907070e), U64(0x3612122436121224),
-+    U64(0x9b80801b9b80801b), U64(0x3de2e2df3de2e2df),
-+    U64(0x26ebebcd26ebebcd), U64(0x6927274e6927274e),
-+    U64(0xcdb2b27fcdb2b27f), U64(0x9f7575ea9f7575ea),
-+    U64(0x1b0909121b090912), U64(0x9e83831d9e83831d),
-+    U64(0x742c2c58742c2c58), U64(0x2e1a1a342e1a1a34),
-+    U64(0x2d1b1b362d1b1b36), U64(0xb26e6edcb26e6edc),
-+    U64(0xee5a5ab4ee5a5ab4), U64(0xfba0a05bfba0a05b),
-+    U64(0xf65252a4f65252a4), U64(0x4d3b3b764d3b3b76),
-+    U64(0x61d6d6b761d6d6b7), U64(0xceb3b37dceb3b37d),
-+    U64(0x7b2929527b292952), U64(0x3ee3e3dd3ee3e3dd),
-+    U64(0x712f2f5e712f2f5e), U64(0x9784841397848413),
-+    U64(0xf55353a6f55353a6), U64(0x68d1d1b968d1d1b9),
-+    U64(0x0000000000000000), U64(0x2cededc12cededc1),
-+    U64(0x6020204060202040), U64(0x1ffcfce31ffcfce3),
-+    U64(0xc8b1b179c8b1b179), U64(0xed5b5bb6ed5b5bb6),
-+    U64(0xbe6a6ad4be6a6ad4), U64(0x46cbcb8d46cbcb8d),
-+    U64(0xd9bebe67d9bebe67), U64(0x4b3939724b393972),
-+    U64(0xde4a4a94de4a4a94), U64(0xd44c4c98d44c4c98),
-+    U64(0xe85858b0e85858b0), U64(0x4acfcf854acfcf85),
-+    U64(0x6bd0d0bb6bd0d0bb), U64(0x2aefefc52aefefc5),
-+    U64(0xe5aaaa4fe5aaaa4f), U64(0x16fbfbed16fbfbed),
-+    U64(0xc5434386c5434386), U64(0xd74d4d9ad74d4d9a),
-+    U64(0x5533336655333366), U64(0x9485851194858511),
-+    U64(0xcf45458acf45458a), U64(0x10f9f9e910f9f9e9),
-+    U64(0x0602020406020204), U64(0x817f7ffe817f7ffe),
-+    U64(0xf05050a0f05050a0), U64(0x443c3c78443c3c78),
-+    U64(0xba9f9f25ba9f9f25), U64(0xe3a8a84be3a8a84b),
-+    U64(0xf35151a2f35151a2), U64(0xfea3a35dfea3a35d),
-+    U64(0xc0404080c0404080), U64(0x8a8f8f058a8f8f05),
-+    U64(0xad92923fad92923f), U64(0xbc9d9d21bc9d9d21),
-+    U64(0x4838387048383870), U64(0x04f5f5f104f5f5f1),
-+    U64(0xdfbcbc63dfbcbc63), U64(0xc1b6b677c1b6b677),
-+    U64(0x75dadaaf75dadaaf), U64(0x6321214263212142),
-+    U64(0x3010102030101020), U64(0x1affffe51affffe5),
-+    U64(0x0ef3f3fd0ef3f3fd), U64(0x6dd2d2bf6dd2d2bf),
-+    U64(0x4ccdcd814ccdcd81), U64(0x140c0c18140c0c18),
-+    U64(0x3513132635131326), U64(0x2fececc32fececc3),
-+    U64(0xe15f5fbee15f5fbe), U64(0xa2979735a2979735),
-+    U64(0xcc444488cc444488), U64(0x3917172e3917172e),
-+    U64(0x57c4c49357c4c493), U64(0xf2a7a755f2a7a755),
-+    U64(0x827e7efc827e7efc), U64(0x473d3d7a473d3d7a),
-+    U64(0xac6464c8ac6464c8), U64(0xe75d5dbae75d5dba),
-+    U64(0x2b1919322b191932), U64(0x957373e6957373e6),
-+    U64(0xa06060c0a06060c0), U64(0x9881811998818119),
-+    U64(0xd14f4f9ed14f4f9e), U64(0x7fdcdca37fdcdca3),
-+    U64(0x6622224466222244), U64(0x7e2a2a547e2a2a54),
-+    U64(0xab90903bab90903b), U64(0x8388880b8388880b),
-+    U64(0xca46468cca46468c), U64(0x29eeeec729eeeec7),
-+    U64(0xd3b8b86bd3b8b86b), U64(0x3c1414283c141428),
-+    U64(0x79dedea779dedea7), U64(0xe25e5ebce25e5ebc),
-+    U64(0x1d0b0b161d0b0b16), U64(0x76dbdbad76dbdbad),
-+    U64(0x3be0e0db3be0e0db), U64(0x5632326456323264),
-+    U64(0x4e3a3a744e3a3a74), U64(0x1e0a0a141e0a0a14),
-+    U64(0xdb494992db494992), U64(0x0a06060c0a06060c),
-+    U64(0x6c2424486c242448), U64(0xe45c5cb8e45c5cb8),
-+    U64(0x5dc2c29f5dc2c29f), U64(0x6ed3d3bd6ed3d3bd),
-+    U64(0xefacac43efacac43), U64(0xa66262c4a66262c4),
-+    U64(0xa8919139a8919139), U64(0xa4959531a4959531),
-+    U64(0x37e4e4d337e4e4d3), U64(0x8b7979f28b7979f2),
-+    U64(0x32e7e7d532e7e7d5), U64(0x43c8c88b43c8c88b),
-+    U64(0x5937376e5937376e), U64(0xb76d6ddab76d6dda),
-+    U64(0x8c8d8d018c8d8d01), U64(0x64d5d5b164d5d5b1),
-+    U64(0xd24e4e9cd24e4e9c), U64(0xe0a9a949e0a9a949),
-+    U64(0xb46c6cd8b46c6cd8), U64(0xfa5656acfa5656ac),
-+    U64(0x07f4f4f307f4f4f3), U64(0x25eaeacf25eaeacf),
-+    U64(0xaf6565caaf6565ca), U64(0x8e7a7af48e7a7af4),
-+    U64(0xe9aeae47e9aeae47), U64(0x1808081018080810),
-+    U64(0xd5baba6fd5baba6f), U64(0x887878f0887878f0),
-+    U64(0x6f25254a6f25254a), U64(0x722e2e5c722e2e5c),
-+    U64(0x241c1c38241c1c38), U64(0xf1a6a657f1a6a657),
-+    U64(0xc7b4b473c7b4b473), U64(0x51c6c69751c6c697),
-+    U64(0x23e8e8cb23e8e8cb), U64(0x7cdddda17cdddda1),
-+    U64(0x9c7474e89c7474e8), U64(0x211f1f3e211f1f3e),
-+    U64(0xdd4b4b96dd4b4b96), U64(0xdcbdbd61dcbdbd61),
-+    U64(0x868b8b0d868b8b0d), U64(0x858a8a0f858a8a0f),
-+    U64(0x907070e0907070e0), U64(0x423e3e7c423e3e7c),
-+    U64(0xc4b5b571c4b5b571), U64(0xaa6666ccaa6666cc),
-+    U64(0xd8484890d8484890), U64(0x0503030605030306),
-+    U64(0x01f6f6f701f6f6f7), U64(0x120e0e1c120e0e1c),
-+    U64(0xa36161c2a36161c2), U64(0x5f35356a5f35356a),
-+    U64(0xf95757aef95757ae), U64(0xd0b9b969d0b9b969),
-+    U64(0x9186861791868617), U64(0x58c1c19958c1c199),
-+    U64(0x271d1d3a271d1d3a), U64(0xb99e9e27b99e9e27),
-+    U64(0x38e1e1d938e1e1d9), U64(0x13f8f8eb13f8f8eb),
-+    U64(0xb398982bb398982b), U64(0x3311112233111122),
-+    U64(0xbb6969d2bb6969d2), U64(0x70d9d9a970d9d9a9),
-+    U64(0x898e8e07898e8e07), U64(0xa7949433a7949433),
-+    U64(0xb69b9b2db69b9b2d), U64(0x221e1e3c221e1e3c),
-+    U64(0x9287871592878715), U64(0x20e9e9c920e9e9c9),
-+    U64(0x49cece8749cece87), U64(0xff5555aaff5555aa),
-+    U64(0x7828285078282850), U64(0x7adfdfa57adfdfa5),
-+    U64(0x8f8c8c038f8c8c03), U64(0xf8a1a159f8a1a159),
-+    U64(0x8089890980898909), U64(0x170d0d1a170d0d1a),
-+    U64(0xdabfbf65dabfbf65), U64(0x31e6e6d731e6e6d7),
-+    U64(0xc6424284c6424284), U64(0xb86868d0b86868d0),
-+    U64(0xc3414182c3414182), U64(0xb0999929b0999929),
-+    U64(0x772d2d5a772d2d5a), U64(0x110f0f1e110f0f1e),
-+    U64(0xcbb0b07bcbb0b07b), U64(0xfc5454a8fc5454a8),
-+    U64(0xd6bbbb6dd6bbbb6d), U64(0x3a16162c3a16162c)
-+};
-+
-+static const u8 Te4[256] = {
-+    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
-+    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
-+    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
-+    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
-+    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
-+    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
-+    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
-+    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
-+    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
-+    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
-+    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
-+    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
-+    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
-+    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
-+    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
-+    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
-+    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
-+    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
-+    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
-+    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
-+    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
-+    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
-+    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
-+    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
-+    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
-+    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
-+    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
-+    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
-+    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
-+    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
-+    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
-+    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
-+};
-+
-+static const u64 Td[256] = {
-+    U64(0x50a7f45150a7f451), U64(0x5365417e5365417e),
-+    U64(0xc3a4171ac3a4171a), U64(0x965e273a965e273a),
-+    U64(0xcb6bab3bcb6bab3b), U64(0xf1459d1ff1459d1f),
-+    U64(0xab58faacab58faac), U64(0x9303e34b9303e34b),
-+    U64(0x55fa302055fa3020), U64(0xf66d76adf66d76ad),
-+    U64(0x9176cc889176cc88), U64(0x254c02f5254c02f5),
-+    U64(0xfcd7e54ffcd7e54f), U64(0xd7cb2ac5d7cb2ac5),
-+    U64(0x8044352680443526), U64(0x8fa362b58fa362b5),
-+    U64(0x495ab1de495ab1de), U64(0x671bba25671bba25),
-+    U64(0x980eea45980eea45), U64(0xe1c0fe5de1c0fe5d),
-+    U64(0x02752fc302752fc3), U64(0x12f04c8112f04c81),
-+    U64(0xa397468da397468d), U64(0xc6f9d36bc6f9d36b),
-+    U64(0xe75f8f03e75f8f03), U64(0x959c9215959c9215),
-+    U64(0xeb7a6dbfeb7a6dbf), U64(0xda595295da595295),
-+    U64(0x2d83bed42d83bed4), U64(0xd3217458d3217458),
-+    U64(0x2969e0492969e049), U64(0x44c8c98e44c8c98e),
-+    U64(0x6a89c2756a89c275), U64(0x78798ef478798ef4),
-+    U64(0x6b3e58996b3e5899), U64(0xdd71b927dd71b927),
-+    U64(0xb64fe1beb64fe1be), U64(0x17ad88f017ad88f0),
-+    U64(0x66ac20c966ac20c9), U64(0xb43ace7db43ace7d),
-+    U64(0x184adf63184adf63), U64(0x82311ae582311ae5),
-+    U64(0x6033519760335197), U64(0x457f5362457f5362),
-+    U64(0xe07764b1e07764b1), U64(0x84ae6bbb84ae6bbb),
-+    U64(0x1ca081fe1ca081fe), U64(0x942b08f9942b08f9),
-+    U64(0x5868487058684870), U64(0x19fd458f19fd458f),
-+    U64(0x876cde94876cde94), U64(0xb7f87b52b7f87b52),
-+    U64(0x23d373ab23d373ab), U64(0xe2024b72e2024b72),
-+    U64(0x578f1fe3578f1fe3), U64(0x2aab55662aab5566),
-+    U64(0x0728ebb20728ebb2), U64(0x03c2b52f03c2b52f),
-+    U64(0x9a7bc5869a7bc586), U64(0xa50837d3a50837d3),
-+    U64(0xf2872830f2872830), U64(0xb2a5bf23b2a5bf23),
-+    U64(0xba6a0302ba6a0302), U64(0x5c8216ed5c8216ed),
-+    U64(0x2b1ccf8a2b1ccf8a), U64(0x92b479a792b479a7),
-+    U64(0xf0f207f3f0f207f3), U64(0xa1e2694ea1e2694e),
-+    U64(0xcdf4da65cdf4da65), U64(0xd5be0506d5be0506),
-+    U64(0x1f6234d11f6234d1), U64(0x8afea6c48afea6c4),
-+    U64(0x9d532e349d532e34), U64(0xa055f3a2a055f3a2),
-+    U64(0x32e18a0532e18a05), U64(0x75ebf6a475ebf6a4),
-+    U64(0x39ec830b39ec830b), U64(0xaaef6040aaef6040),
-+    U64(0x069f715e069f715e), U64(0x51106ebd51106ebd),
-+    U64(0xf98a213ef98a213e), U64(0x3d06dd963d06dd96),
-+    U64(0xae053eddae053edd), U64(0x46bde64d46bde64d),
-+    U64(0xb58d5491b58d5491), U64(0x055dc471055dc471),
-+    U64(0x6fd406046fd40604), U64(0xff155060ff155060),
-+    U64(0x24fb981924fb9819), U64(0x97e9bdd697e9bdd6),
-+    U64(0xcc434089cc434089), U64(0x779ed967779ed967),
-+    U64(0xbd42e8b0bd42e8b0), U64(0x888b8907888b8907),
-+    U64(0x385b19e7385b19e7), U64(0xdbeec879dbeec879),
-+    U64(0x470a7ca1470a7ca1), U64(0xe90f427ce90f427c),
-+    U64(0xc91e84f8c91e84f8), U64(0x0000000000000000),
-+    U64(0x8386800983868009), U64(0x48ed2b3248ed2b32),
-+    U64(0xac70111eac70111e), U64(0x4e725a6c4e725a6c),
-+    U64(0xfbff0efdfbff0efd), U64(0x5638850f5638850f),
-+    U64(0x1ed5ae3d1ed5ae3d), U64(0x27392d3627392d36),
-+    U64(0x64d90f0a64d90f0a), U64(0x21a65c6821a65c68),
-+    U64(0xd1545b9bd1545b9b), U64(0x3a2e36243a2e3624),
-+    U64(0xb1670a0cb1670a0c), U64(0x0fe757930fe75793),
-+    U64(0xd296eeb4d296eeb4), U64(0x9e919b1b9e919b1b),
-+    U64(0x4fc5c0804fc5c080), U64(0xa220dc61a220dc61),
-+    U64(0x694b775a694b775a), U64(0x161a121c161a121c),
-+    U64(0x0aba93e20aba93e2), U64(0xe52aa0c0e52aa0c0),
-+    U64(0x43e0223c43e0223c), U64(0x1d171b121d171b12),
-+    U64(0x0b0d090e0b0d090e), U64(0xadc78bf2adc78bf2),
-+    U64(0xb9a8b62db9a8b62d), U64(0xc8a91e14c8a91e14),
-+    U64(0x8519f1578519f157), U64(0x4c0775af4c0775af),
-+    U64(0xbbdd99eebbdd99ee), U64(0xfd607fa3fd607fa3),
-+    U64(0x9f2601f79f2601f7), U64(0xbcf5725cbcf5725c),
-+    U64(0xc53b6644c53b6644), U64(0x347efb5b347efb5b),
-+    U64(0x7629438b7629438b), U64(0xdcc623cbdcc623cb),
-+    U64(0x68fcedb668fcedb6), U64(0x63f1e4b863f1e4b8),
-+    U64(0xcadc31d7cadc31d7), U64(0x1085634210856342),
-+    U64(0x4022971340229713), U64(0x2011c6842011c684),
-+    U64(0x7d244a857d244a85), U64(0xf83dbbd2f83dbbd2),
-+    U64(0x1132f9ae1132f9ae), U64(0x6da129c76da129c7),
-+    U64(0x4b2f9e1d4b2f9e1d), U64(0xf330b2dcf330b2dc),
-+    U64(0xec52860dec52860d), U64(0xd0e3c177d0e3c177),
-+    U64(0x6c16b32b6c16b32b), U64(0x99b970a999b970a9),
-+    U64(0xfa489411fa489411), U64(0x2264e9472264e947),
-+    U64(0xc48cfca8c48cfca8), U64(0x1a3ff0a01a3ff0a0),
-+    U64(0xd82c7d56d82c7d56), U64(0xef903322ef903322),
-+    U64(0xc74e4987c74e4987), U64(0xc1d138d9c1d138d9),
-+    U64(0xfea2ca8cfea2ca8c), U64(0x360bd498360bd498),
-+    U64(0xcf81f5a6cf81f5a6), U64(0x28de7aa528de7aa5),
-+    U64(0x268eb7da268eb7da), U64(0xa4bfad3fa4bfad3f),
-+    U64(0xe49d3a2ce49d3a2c), U64(0x0d9278500d927850),
-+    U64(0x9bcc5f6a9bcc5f6a), U64(0x62467e5462467e54),
-+    U64(0xc2138df6c2138df6), U64(0xe8b8d890e8b8d890),
-+    U64(0x5ef7392e5ef7392e), U64(0xf5afc382f5afc382),
-+    U64(0xbe805d9fbe805d9f), U64(0x7c93d0697c93d069),
-+    U64(0xa92dd56fa92dd56f), U64(0xb31225cfb31225cf),
-+    U64(0x3b99acc83b99acc8), U64(0xa77d1810a77d1810),
-+    U64(0x6e639ce86e639ce8), U64(0x7bbb3bdb7bbb3bdb),
-+    U64(0x097826cd097826cd), U64(0xf418596ef418596e),
-+    U64(0x01b79aec01b79aec), U64(0xa89a4f83a89a4f83),
-+    U64(0x656e95e6656e95e6), U64(0x7ee6ffaa7ee6ffaa),
-+    U64(0x08cfbc2108cfbc21), U64(0xe6e815efe6e815ef),
-+    U64(0xd99be7bad99be7ba), U64(0xce366f4ace366f4a),
-+    U64(0xd4099fead4099fea), U64(0xd67cb029d67cb029),
-+    U64(0xafb2a431afb2a431), U64(0x31233f2a31233f2a),
-+    U64(0x3094a5c63094a5c6), U64(0xc066a235c066a235),
-+    U64(0x37bc4e7437bc4e74), U64(0xa6ca82fca6ca82fc),
-+    U64(0xb0d090e0b0d090e0), U64(0x15d8a73315d8a733),
-+    U64(0x4a9804f14a9804f1), U64(0xf7daec41f7daec41),
-+    U64(0x0e50cd7f0e50cd7f), U64(0x2ff691172ff69117),
-+    U64(0x8dd64d768dd64d76), U64(0x4db0ef434db0ef43),
-+    U64(0x544daacc544daacc), U64(0xdf0496e4df0496e4),
-+    U64(0xe3b5d19ee3b5d19e), U64(0x1b886a4c1b886a4c),
-+    U64(0xb81f2cc1b81f2cc1), U64(0x7f5165467f516546),
-+    U64(0x04ea5e9d04ea5e9d), U64(0x5d358c015d358c01),
-+    U64(0x737487fa737487fa), U64(0x2e410bfb2e410bfb),
-+    U64(0x5a1d67b35a1d67b3), U64(0x52d2db9252d2db92),
-+    U64(0x335610e9335610e9), U64(0x1347d66d1347d66d),
-+    U64(0x8c61d79a8c61d79a), U64(0x7a0ca1377a0ca137),
-+    U64(0x8e14f8598e14f859), U64(0x893c13eb893c13eb),
-+    U64(0xee27a9ceee27a9ce), U64(0x35c961b735c961b7),
-+    U64(0xede51ce1ede51ce1), U64(0x3cb1477a3cb1477a),
-+    U64(0x59dfd29c59dfd29c), U64(0x3f73f2553f73f255),
-+    U64(0x79ce141879ce1418), U64(0xbf37c773bf37c773),
-+    U64(0xeacdf753eacdf753), U64(0x5baafd5f5baafd5f),
-+    U64(0x146f3ddf146f3ddf), U64(0x86db447886db4478),
-+    U64(0x81f3afca81f3afca), U64(0x3ec468b93ec468b9),
-+    U64(0x2c3424382c342438), U64(0x5f40a3c25f40a3c2),
-+    U64(0x72c31d1672c31d16), U64(0x0c25e2bc0c25e2bc),
-+    U64(0x8b493c288b493c28), U64(0x41950dff41950dff),
-+    U64(0x7101a8397101a839), U64(0xdeb30c08deb30c08),
-+    U64(0x9ce4b4d89ce4b4d8), U64(0x90c1566490c15664),
-+    U64(0x6184cb7b6184cb7b), U64(0x70b632d570b632d5),
-+    U64(0x745c6c48745c6c48), U64(0x4257b8d04257b8d0)
-+};
-+static const u8 Td4[256] = {
-+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
-+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
-+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
-+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
-+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
-+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
-+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
-+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
-+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
-+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
-+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
-+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
-+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
-+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
-+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
-+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
-+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
-+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
-+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
-+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
-+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
-+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
-+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
-+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
-+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
-+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
-+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
-+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
-+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
-+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
-+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
-+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU
-+};
-+
-+static const u32 rcon[] = {
-+    0x00000001U, 0x00000002U, 0x00000004U, 0x00000008U,
-+    0x00000010U, 0x00000020U, 0x00000040U, 0x00000080U,
-+    0x0000001bU, 0x00000036U, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-+};
-+
-+/**
-+ * Expand the cipher key into the encryption key schedule.
-+ */
-+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
-+                        AES_KEY *key)
-+{
-+
-+    u32 *rk;
-+    int i = 0;
-+    u32 temp;
-+
-+    if (!userKey || !key)
-+        return -1;
-+    if (bits != 128 && bits != 192 && bits != 256)
-+        return -2;
-+
-+    rk = key->rd_key;
-+
-+    if (bits==128)
-+        key->rounds = 10;
-+    else if (bits==192)
-+        key->rounds = 12;
-+    else
-+        key->rounds = 14;
-+
-+    rk[0] = GETU32(userKey     );
-+    rk[1] = GETU32(userKey +  4);
-+    rk[2] = GETU32(userKey +  8);
-+    rk[3] = GETU32(userKey + 12);
-+    if (bits == 128) {
-+        while (1) {
-+            temp  = rk[3];
-+            rk[4] = rk[0] ^
-+                ((u32)Te4[(temp >>  8) & 0xff]      ) ^
-+                ((u32)Te4[(temp >> 16) & 0xff] <<  8) ^
-+                ((u32)Te4[(temp >> 24)       ] << 16) ^
-+                ((u32)Te4[(temp      ) & 0xff] << 24) ^
-+                rcon[i];
-+            rk[5] = rk[1] ^ rk[4];
-+            rk[6] = rk[2] ^ rk[5];
-+            rk[7] = rk[3] ^ rk[6];
-+            if (++i == 10) {
-+                return 0;
-+            }
-+            rk += 4;
-+        }
-+    }
-+    rk[4] = GETU32(userKey + 16);
-+    rk[5] = GETU32(userKey + 20);
-+    if (bits == 192) {
-+        while (1) {
-+            temp = rk[ 5];
-+            rk[ 6] = rk[ 0] ^
-+                ((u32)Te4[(temp >>  8) & 0xff]      ) ^
-+                ((u32)Te4[(temp >> 16) & 0xff] <<  8) ^
-+                ((u32)Te4[(temp >> 24)       ] << 16) ^
-+                ((u32)Te4[(temp      ) & 0xff] << 24) ^
-+                rcon[i];
-+            rk[ 7] = rk[ 1] ^ rk[ 6];
-+            rk[ 8] = rk[ 2] ^ rk[ 7];
-+            rk[ 9] = rk[ 3] ^ rk[ 8];
-+            if (++i == 8) {
-+                return 0;
-+            }
-+            rk[10] = rk[ 4] ^ rk[ 9];
-+            rk[11] = rk[ 5] ^ rk[10];
-+            rk += 6;
-+        }
-+    }
-+    rk[6] = GETU32(userKey + 24);
-+    rk[7] = GETU32(userKey + 28);
-+    if (bits == 256) {
-+        while (1) {
-+            temp = rk[ 7];
-+            rk[ 8] = rk[ 0] ^
-+                ((u32)Te4[(temp >>  8) & 0xff]      ) ^
-+                ((u32)Te4[(temp >> 16) & 0xff] <<  8) ^
-+                ((u32)Te4[(temp >> 24)       ] << 16) ^
-+                ((u32)Te4[(temp      ) & 0xff] << 24) ^
-+                rcon[i];
-+            rk[ 9] = rk[ 1] ^ rk[ 8];
-+            rk[10] = rk[ 2] ^ rk[ 9];
-+            rk[11] = rk[ 3] ^ rk[10];
-+            if (++i == 7) {
-+                return 0;
-+            }
-+            temp = rk[11];
-+            rk[12] = rk[ 4] ^
-+                ((u32)Te4[(temp      ) & 0xff]      ) ^
-+                ((u32)Te4[(temp >>  8) & 0xff] <<  8) ^
-+                ((u32)Te4[(temp >> 16) & 0xff] << 16) ^
-+                ((u32)Te4[(temp >> 24)       ] << 24);
-+            rk[13] = rk[ 5] ^ rk[12];
-+            rk[14] = rk[ 6] ^ rk[13];
-+            rk[15] = rk[ 7] ^ rk[14];
-+
-+            rk += 8;
-+            }
-+    }
-+    return 0;
-+}
-+
-+/**
-+ * Expand the cipher key into the decryption key schedule.
-+ */
-+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
-+                        AES_KEY *key)
-+{
-+
-+    u32 *rk;
-+    int i, j, status;
-+    u32 temp;
-+
-+    /* first, start with an encryption schedule */
-+    status = AES_set_encrypt_key(userKey, bits, key);
-+    if (status < 0)
-+        return status;
-+
-+    rk = key->rd_key;
-+
-+    /* invert the order of the round keys: */
-+    for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
-+        temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
-+        temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
-+        temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
-+        temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
-+    }
-+    /* apply the inverse MixColumn transform to all round keys but the first and the last: */
-+    for (i = 1; i < (key->rounds); i++) {
-+        rk += 4;
-+#if 1
-+        for (j = 0; j < 4; j++) {
-+            u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
-+
-+            tp1 = rk[j];
-+            m = tp1 & 0x80808080;
-+            tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            m = tp2 & 0x80808080;
-+            tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            m = tp4 & 0x80808080;
-+            tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            tp9 = tp8 ^ tp1;
-+            tpb = tp9 ^ tp2;
-+            tpd = tp9 ^ tp4;
-+            tpe = tp8 ^ tp4 ^ tp2;
-+#if defined(ROTATE)
-+            rk[j] = tpe ^ ROTATE(tpd,16) ^
-+                ROTATE(tp9,8) ^ ROTATE(tpb,24);
-+#else
-+            rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
-+                (tp9 >> 24) ^ (tp9 << 8) ^
-+                (tpb >> 8) ^ (tpb << 24);
-+#endif
-+        }
-+#else
-+        rk[0] =
-+            Td0[Te2[(rk[0]      ) & 0xff] & 0xff] ^
-+            Td1[Te2[(rk[0] >>  8) & 0xff] & 0xff] ^
-+            Td2[Te2[(rk[0] >> 16) & 0xff] & 0xff] ^
-+            Td3[Te2[(rk[0] >> 24)       ] & 0xff];
-+        rk[1] =
-+            Td0[Te2[(rk[1]      ) & 0xff] & 0xff] ^
-+            Td1[Te2[(rk[1] >>  8) & 0xff] & 0xff] ^
-+            Td2[Te2[(rk[1] >> 16) & 0xff] & 0xff] ^
-+            Td3[Te2[(rk[1] >> 24)       ] & 0xff];
-+        rk[2] =
-+            Td0[Te2[(rk[2]      ) & 0xff] & 0xff] ^
-+            Td1[Te2[(rk[2] >>  8) & 0xff] & 0xff] ^
-+            Td2[Te2[(rk[2] >> 16) & 0xff] & 0xff] ^
-+            Td3[Te2[(rk[2] >> 24)       ] & 0xff];
-+        rk[3] =
-+            Td0[Te2[(rk[3]      ) & 0xff] & 0xff] ^
-+            Td1[Te2[(rk[3] >>  8) & 0xff] & 0xff] ^
-+            Td2[Te2[(rk[3] >> 16) & 0xff] & 0xff] ^
-+            Td3[Te2[(rk[3] >> 24)       ] & 0xff];
-+#endif
-+    }
-+    return 0;
-+}
-+
-+/*
-+ * Encrypt a single block
-+ * in and out can overlap
-+ */
-+void AES_encrypt(const unsigned char *in, unsigned char *out,
-+                 const AES_KEY *key)
-+{
-+
-+    const u32 *rk;
-+    u32 s0, s1, s2, s3, t[4];
-+    int r;
-+
-+    assert(in && out && key);
-+    rk = key->rd_key;
-+
-+    /*
-+     * map byte array block to cipher state
-+     * and add initial round key:
-+     */
-+    s0 = GETU32(in     ) ^ rk[0];
-+    s1 = GETU32(in +  4) ^ rk[1];
-+    s2 = GETU32(in +  8) ^ rk[2];
-+    s3 = GETU32(in + 12) ^ rk[3];
-+
-+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
-+    prefetch256(Te4);
-+
-+    t[0] = (u32)Te4[(s0      ) & 0xff]       ^
-+           (u32)Te4[(s1 >>  8) & 0xff] <<  8 ^
-+           (u32)Te4[(s2 >> 16) & 0xff] << 16 ^
-+           (u32)Te4[(s3 >> 24)       ] << 24;
-+    t[1] = (u32)Te4[(s1      ) & 0xff]       ^
-+           (u32)Te4[(s2 >>  8) & 0xff] <<  8 ^
-+           (u32)Te4[(s3 >> 16) & 0xff] << 16 ^
-+           (u32)Te4[(s0 >> 24)       ] << 24;
-+    t[2] = (u32)Te4[(s2      ) & 0xff]       ^
-+           (u32)Te4[(s3 >>  8) & 0xff] <<  8 ^
-+           (u32)Te4[(s0 >> 16) & 0xff] << 16 ^
-+           (u32)Te4[(s1 >> 24)       ] << 24;
-+    t[3] = (u32)Te4[(s3      ) & 0xff]       ^
-+           (u32)Te4[(s0 >>  8) & 0xff] <<  8 ^
-+           (u32)Te4[(s1 >> 16) & 0xff] << 16 ^
-+           (u32)Te4[(s2 >> 24)       ] << 24;
-+
-+    /* now do the linear transform using words */
-+    {   int i;
-+        u32 r0, r1, r2;
-+
-+        for (i = 0; i < 4; i++) {
-+            r0 = t[i];
-+            r1 = r0 & 0x80808080;
-+            r2 = ((r0 & 0x7f7f7f7f) << 1) ^
-+                ((r1 - (r1 >> 7)) & 0x1b1b1b1b);
-+#if defined(ROTATE)
-+            t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
-+                ROTATE(r0,16) ^ ROTATE(r0,8);
-+#else
-+            t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
-+                (r0 << 16) ^ (r0 >> 16) ^
-+                (r0 << 8) ^ (r0 >> 24);
-+#endif
-+            t[i] ^= rk[4+i];
-+        }
-+    }
-+#else
-+    t[0] =  Te0[(s0      ) & 0xff] ^
-+        Te1[(s1 >>  8) & 0xff] ^
-+        Te2[(s2 >> 16) & 0xff] ^
-+        Te3[(s3 >> 24)       ] ^
-+        rk[4];
-+    t[1] =  Te0[(s1      ) & 0xff] ^
-+        Te1[(s2 >>  8) & 0xff] ^
-+        Te2[(s3 >> 16) & 0xff] ^
-+        Te3[(s0 >> 24)       ] ^
-+        rk[5];
-+    t[2] =  Te0[(s2      ) & 0xff] ^
-+        Te1[(s3 >>  8) & 0xff] ^
-+        Te2[(s0 >> 16) & 0xff] ^
-+        Te3[(s1 >> 24)       ] ^
-+        rk[6];
-+    t[3] =  Te0[(s3      ) & 0xff] ^
-+        Te1[(s0 >>  8) & 0xff] ^
-+        Te2[(s1 >> 16) & 0xff] ^
-+        Te3[(s2 >> 24)       ] ^
-+        rk[7];
-+#endif
-+    s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
-+
-+    /*
-+     * Nr - 2 full rounds:
-+     */
-+    for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
-+#if defined(AES_COMPACT_IN_INNER_ROUNDS)
-+        t[0] = (u32)Te4[(s0      ) & 0xff]       ^
-+               (u32)Te4[(s1 >>  8) & 0xff] <<  8 ^
-+               (u32)Te4[(s2 >> 16) & 0xff] << 16 ^
-+               (u32)Te4[(s3 >> 24)       ] << 24;
-+        t[1] = (u32)Te4[(s1      ) & 0xff]       ^
-+               (u32)Te4[(s2 >>  8) & 0xff] <<  8 ^
-+               (u32)Te4[(s3 >> 16) & 0xff] << 16 ^
-+               (u32)Te4[(s0 >> 24)       ] << 24;
-+        t[2] = (u32)Te4[(s2      ) & 0xff]       ^
-+               (u32)Te4[(s3 >>  8) & 0xff] <<  8 ^
-+               (u32)Te4[(s0 >> 16) & 0xff] << 16 ^
-+               (u32)Te4[(s1 >> 24)       ] << 24;
-+        t[3] = (u32)Te4[(s3      ) & 0xff]       ^
-+               (u32)Te4[(s0 >>  8) & 0xff] <<  8 ^
-+               (u32)Te4[(s1 >> 16) & 0xff] << 16 ^
-+               (u32)Te4[(s2 >> 24)       ] << 24;
-+
-+        /* now do the linear transform using words */
-+        {
-+            int i;
-+            u32 r0, r1, r2;
-+
-+            for (i = 0; i < 4; i++) {
-+                r0 = t[i];
-+                r1 = r0 & 0x80808080;
-+                r2 = ((r0 & 0x7f7f7f7f) << 1) ^
-+                    ((r1 - (r1 >> 7)) & 0x1b1b1b1b);
-+#if defined(ROTATE)
-+                t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
-+                    ROTATE(r0,16) ^ ROTATE(r0,8);
-+#else
-+                t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
-+                    (r0 << 16) ^ (r0 >> 16) ^
-+                    (r0 << 8) ^ (r0 >> 24);
-+#endif
-+                t[i] ^= rk[i];
-+            }
-+        }
-+#else
-+        t[0] =  Te0[(s0      ) & 0xff] ^
-+            Te1[(s1 >>  8) & 0xff] ^
-+            Te2[(s2 >> 16) & 0xff] ^
-+            Te3[(s3 >> 24)       ] ^
-+            rk[0];
-+        t[1] =  Te0[(s1      ) & 0xff] ^
-+            Te1[(s2 >>  8) & 0xff] ^
-+            Te2[(s3 >> 16) & 0xff] ^
-+            Te3[(s0 >> 24)       ] ^
-+            rk[1];
-+        t[2] =  Te0[(s2      ) & 0xff] ^
-+            Te1[(s3 >>  8) & 0xff] ^
-+            Te2[(s0 >> 16) & 0xff] ^
-+            Te3[(s1 >> 24)       ] ^
-+            rk[2];
-+        t[3] =  Te0[(s3      ) & 0xff] ^
-+            Te1[(s0 >>  8) & 0xff] ^
-+            Te2[(s1 >> 16) & 0xff] ^
-+            Te3[(s2 >> 24)       ] ^
-+            rk[3];
-+#endif
-+        s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
-+    }
-+    /*
-+     * apply last round and
-+     * map cipher state to byte array block:
-+     */
-+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
-+    prefetch256(Te4);
-+
-+    *(u32*)(out+0) =
-+           (u32)Te4[(s0      ) & 0xff]       ^
-+           (u32)Te4[(s1 >>  8) & 0xff] <<  8 ^
-+           (u32)Te4[(s2 >> 16) & 0xff] << 16 ^
-+           (u32)Te4[(s3 >> 24)       ] << 24 ^
-+        rk[0];
-+    *(u32*)(out+4) =
-+           (u32)Te4[(s1      ) & 0xff]       ^
-+           (u32)Te4[(s2 >>  8) & 0xff] <<  8 ^
-+           (u32)Te4[(s3 >> 16) & 0xff] << 16 ^
-+           (u32)Te4[(s0 >> 24)       ] << 24 ^
-+        rk[1];
-+    *(u32*)(out+8) =
-+           (u32)Te4[(s2      ) & 0xff]       ^
-+           (u32)Te4[(s3 >>  8) & 0xff] <<  8 ^
-+           (u32)Te4[(s0 >> 16) & 0xff] << 16 ^
-+           (u32)Te4[(s1 >> 24)       ] << 24 ^
-+        rk[2];
-+    *(u32*)(out+12) =
-+           (u32)Te4[(s3      ) & 0xff]       ^
-+           (u32)Te4[(s0 >>  8) & 0xff] <<  8 ^
-+           (u32)Te4[(s1 >> 16) & 0xff] << 16 ^
-+           (u32)Te4[(s2 >> 24)       ] << 24 ^
-+        rk[3];
-+#else
-+    *(u32*)(out+0) =
-+        (Te2[(s0      ) & 0xff] & 0x000000ffU) ^
-+        (Te3[(s1 >>  8) & 0xff] & 0x0000ff00U) ^
-+        (Te0[(s2 >> 16) & 0xff] & 0x00ff0000U) ^
-+        (Te1[(s3 >> 24)       ] & 0xff000000U) ^
-+        rk[0];
-+    *(u32*)(out+4) =
-+        (Te2[(s1      ) & 0xff] & 0x000000ffU) ^
-+        (Te3[(s2 >>  8) & 0xff] & 0x0000ff00U) ^
-+        (Te0[(s3 >> 16) & 0xff] & 0x00ff0000U) ^
-+        (Te1[(s0 >> 24)       ] & 0xff000000U) ^
-+        rk[1];
-+    *(u32*)(out+8) =
-+        (Te2[(s2      ) & 0xff] & 0x000000ffU) ^
-+        (Te3[(s3 >>  8) & 0xff] & 0x0000ff00U) ^
-+        (Te0[(s0 >> 16) & 0xff] & 0x00ff0000U) ^
-+        (Te1[(s1 >> 24)       ] & 0xff000000U) ^
-+        rk[2];
-+    *(u32*)(out+12) =
-+        (Te2[(s3      ) & 0xff] & 0x000000ffU) ^
-+        (Te3[(s0 >>  8) & 0xff] & 0x0000ff00U) ^
-+        (Te0[(s1 >> 16) & 0xff] & 0x00ff0000U) ^
-+        (Te1[(s2 >> 24)       ] & 0xff000000U) ^
-+        rk[3];
-+#endif
-+}
-+
-+/*
-+ * Decrypt a single block
-+ * in and out can overlap
-+ */
-+void AES_decrypt(const unsigned char *in, unsigned char *out,
-+                 const AES_KEY *key)
-+{
-+
-+    const u32 *rk;
-+    u32 s0, s1, s2, s3, t[4];
-+    int r;
-+
-+    assert(in && out && key);
-+    rk = key->rd_key;
-+
-+    /*
-+     * map byte array block to cipher state
-+     * and add initial round key:
-+     */
-+    s0 = GETU32(in     ) ^ rk[0];
-+    s1 = GETU32(in +  4) ^ rk[1];
-+    s2 = GETU32(in +  8) ^ rk[2];
-+    s3 = GETU32(in + 12) ^ rk[3];
-+
-+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
-+    prefetch256(Td4);
-+
-+    t[0] = (u32)Td4[(s0      ) & 0xff]       ^
-+           (u32)Td4[(s3 >>  8) & 0xff] <<  8 ^
-+           (u32)Td4[(s2 >> 16) & 0xff] << 16 ^
-+           (u32)Td4[(s1 >> 24)       ] << 24;
-+    t[1] = (u32)Td4[(s1      ) & 0xff]       ^
-+           (u32)Td4[(s0 >>  8) & 0xff] <<  8 ^
-+           (u32)Td4[(s3 >> 16) & 0xff] << 16 ^
-+           (u32)Td4[(s2 >> 24)       ] << 24;
-+    t[2] = (u32)Td4[(s2      ) & 0xff]       ^
-+           (u32)Td4[(s1 >>  8) & 0xff] <<  8 ^
-+           (u32)Td4[(s0 >> 16) & 0xff] << 16 ^
-+           (u32)Td4[(s3 >> 24)       ] << 24;
-+    t[3] = (u32)Td4[(s3      ) & 0xff]       ^
-+           (u32)Td4[(s2 >>  8) & 0xff] <<  8 ^
-+           (u32)Td4[(s1 >> 16) & 0xff] << 16 ^
-+           (u32)Td4[(s0 >> 24)       ] << 24;
-+
-+    /* now do the linear transform using words */
-+    {
-+        int i;
-+        u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
-+
-+        for (i = 0; i < 4; i++) {
-+            tp1 = t[i];
-+            m = tp1 & 0x80808080;
-+            tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            m = tp2 & 0x80808080;
-+            tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            m = tp4 & 0x80808080;
-+            tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            tp9 = tp8 ^ tp1;
-+            tpb = tp9 ^ tp2;
-+            tpd = tp9 ^ tp4;
-+            tpe = tp8 ^ tp4 ^ tp2;
-+#if defined(ROTATE)
-+            t[i] = tpe ^ ROTATE(tpd,16) ^
-+                ROTATE(tp9,8) ^ ROTATE(tpb,24);
-+#else
-+            t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
-+                (tp9 >> 24) ^ (tp9 << 8) ^
-+                (tpb >> 8) ^ (tpb << 24);
-+#endif
-+            t[i] ^= rk[4+i];
-+        }
-+    }
-+#else
-+    t[0] =  Td0[(s0      ) & 0xff] ^
-+        Td1[(s3 >>  8) & 0xff] ^
-+        Td2[(s2 >> 16) & 0xff] ^
-+        Td3[(s1 >> 24)       ] ^
-+        rk[4];
-+    t[1] =  Td0[(s1      ) & 0xff] ^
-+        Td1[(s0 >>  8) & 0xff] ^
-+        Td2[(s3 >> 16) & 0xff] ^
-+        Td3[(s2 >> 24)       ] ^
-+        rk[5];
-+    t[2] =  Td0[(s2      ) & 0xff] ^
-+        Td1[(s1 >>  8) & 0xff] ^
-+        Td2[(s0 >> 16) & 0xff] ^
-+        Td3[(s3 >> 24)       ] ^
-+        rk[6];
-+    t[3] =  Td0[(s3      ) & 0xff] ^
-+        Td1[(s2 >>  8) & 0xff] ^
-+        Td2[(s1 >> 16) & 0xff] ^
-+        Td3[(s0 >> 24)       ] ^
-+        rk[7];
-+#endif
-+    s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
-+
-+    /*
-+     * Nr - 2 full rounds:
-+     */
-+    for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
-+#if defined(AES_COMPACT_IN_INNER_ROUNDS)
-+        t[0] = (u32)Td4[(s0      ) & 0xff]       ^
-+               (u32)Td4[(s3 >>  8) & 0xff] <<  8 ^
-+               (u32)Td4[(s2 >> 16) & 0xff] << 16 ^
-+               (u32)Td4[(s1 >> 24)       ] << 24;
-+        t[1] = (u32)Td4[(s1      ) & 0xff]       ^
-+               (u32)Td4[(s0 >>  8) & 0xff] <<  8 ^
-+               (u32)Td4[(s3 >> 16) & 0xff] << 16 ^
-+               (u32)Td4[(s2 >> 24)       ] << 24;
-+        t[2] = (u32)Td4[(s2      ) & 0xff]       ^
-+               (u32)Td4[(s1 >>  8) & 0xff] <<  8 ^
-+               (u32)Td4[(s0 >> 16) & 0xff] << 16 ^
-+               (u32)Td4[(s3 >> 24)       ] << 24;
-+        t[3] = (u32)Td4[(s3      ) & 0xff]       ^
-+               (u32)Td4[(s2 >>  8) & 0xff] <<  8 ^
-+               (u32)Td4[(s1 >> 16) & 0xff] << 16 ^
-+               (u32)Td4[(s0 >> 24)       ] << 24;
-+
-+    /* now do the linear transform using words */
-+    {
-+        int i;
-+        u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
-+
-+        for (i = 0; i < 4; i++) {
-+            tp1 = t[i];
-+            m = tp1 & 0x80808080;
-+            tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            m = tp2 & 0x80808080;
-+            tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            m = tp4 & 0x80808080;
-+            tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
-+                ((m - (m >> 7)) & 0x1b1b1b1b);
-+            tp9 = tp8 ^ tp1;
-+            tpb = tp9 ^ tp2;
-+            tpd = tp9 ^ tp4;
-+            tpe = tp8 ^ tp4 ^ tp2;
-+#if defined(ROTATE)
-+            t[i] = tpe ^ ROTATE(tpd,16) ^
-+                ROTATE(tp9,8) ^ ROTATE(tpb,24);
-+#else
-+            t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
-+                (tp9 >> 24) ^ (tp9 << 8) ^
-+                (tpb >> 8) ^ (tpb << 24);
-+#endif
-+            t[i] ^= rk[i];
-+        }
-+    }
-+#else
-+    t[0] =  Td0[(s0      ) & 0xff] ^
-+        Td1[(s3 >>  8) & 0xff] ^
-+        Td2[(s2 >> 16) & 0xff] ^
-+        Td3[(s1 >> 24)       ] ^
-+        rk[0];
-+    t[1] =  Td0[(s1      ) & 0xff] ^
-+        Td1[(s0 >>  8) & 0xff] ^
-+        Td2[(s3 >> 16) & 0xff] ^
-+        Td3[(s2 >> 24)       ] ^
-+        rk[1];
-+    t[2] =  Td0[(s2      ) & 0xff] ^
-+        Td1[(s1 >>  8) & 0xff] ^
-+        Td2[(s0 >> 16) & 0xff] ^
-+        Td3[(s3 >> 24)       ] ^
-+        rk[2];
-+    t[3] =  Td0[(s3      ) & 0xff] ^
-+        Td1[(s2 >>  8) & 0xff] ^
-+        Td2[(s1 >> 16) & 0xff] ^
-+        Td3[(s0 >> 24)       ] ^
-+        rk[3];
-+#endif
-+    s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
-+    }
-+    /*
-+     * apply last round and
-+     * map cipher state to byte array block:
-+     */
-+    prefetch256(Td4);
-+
-+    *(u32*)(out+0) =
-+        ((u32)Td4[(s0      ) & 0xff])    ^
-+        ((u32)Td4[(s3 >>  8) & 0xff] <<  8) ^
-+        ((u32)Td4[(s2 >> 16) & 0xff] << 16) ^
-+        ((u32)Td4[(s1 >> 24)       ] << 24) ^
-+        rk[0];
-+    *(u32*)(out+4) =
-+        ((u32)Td4[(s1      ) & 0xff])     ^
-+        ((u32)Td4[(s0 >>  8) & 0xff] <<  8) ^
-+        ((u32)Td4[(s3 >> 16) & 0xff] << 16) ^
-+        ((u32)Td4[(s2 >> 24)       ] << 24) ^
-+        rk[1];
-+    *(u32*)(out+8) =
-+        ((u32)Td4[(s2      ) & 0xff])     ^
-+        ((u32)Td4[(s1 >>  8) & 0xff] <<  8) ^
-+        ((u32)Td4[(s0 >> 16) & 0xff] << 16) ^
-+        ((u32)Td4[(s3 >> 24)       ] << 24) ^
-+        rk[2];
-+    *(u32*)(out+12) =
-+        ((u32)Td4[(s3      ) & 0xff])     ^
-+        ((u32)Td4[(s2 >>  8) & 0xff] <<  8) ^
-+        ((u32)Td4[(s1 >> 16) & 0xff] << 16) ^
-+        ((u32)Td4[(s0 >> 24)       ] << 24) ^
-+        rk[3];
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-586.pl
-new file mode 100755
-index 0000000..1ba3565
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-586.pl
-@@ -0,0 +1,3000 @@
-+#! /usr/bin/env perl
-+# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# Version 4.3.
-+#
-+# You might fail to appreciate this module performance from the first
-+# try. If compared to "vanilla" linux-ia32-icc target, i.e. considered
-+# to be *the* best Intel C compiler without -KPIC, performance appears
-+# to be virtually identical... But try to re-configure with shared
-+# library support... Aha! Intel compiler "suddenly" lags behind by 30%
-+# [on P4, more on others]:-) And if compared to position-independent
-+# code generated by GNU C, this code performs *more* than *twice* as
-+# fast! Yes, all this buzz about PIC means that unlike other hand-
-+# coded implementations, this one was explicitly designed to be safe
-+# to use even in shared library context... This also means that this
-+# code isn't necessarily absolutely fastest "ever," because in order
-+# to achieve position independence an extra register has to be
-+# off-loaded to stack, which affects the benchmark result.
-+#
-+# Special note about instruction choice. Do you recall RC4_INT code
-+# performing poorly on P4? It might be the time to figure out why.
-+# RC4_INT code implies effective address calculations in base+offset*4
-+# form. Trouble is that it seems that offset scaling turned to be
-+# critical path... At least eliminating scaling resulted in 2.8x RC4
-+# performance improvement [as you might recall]. As AES code is hungry
-+# for scaling too, I [try to] avoid the latter by favoring off-by-2
-+# shifts and masking the result with 0xFF<<2 instead of "boring" 0xFF.
-+#
-+# As was shown by Dean Gaudet , the above note turned
-+# void. Performance improvement with off-by-2 shifts was observed on
-+# intermediate implementation, which was spilling yet another register
-+# to stack... Final offset*4 code below runs just a tad faster on P4,
-+# but exhibits up to 10% improvement on other cores.
-+#
-+# Second version is "monolithic" replacement for aes_core.c, which in
-+# addition to AES_[de|en]crypt implements AES_set_[de|en]cryption_key.
-+# This made it possible to implement little-endian variant of the
-+# algorithm without modifying the base C code. Motivating factor for
-+# the undertaken effort was that it appeared that in tight IA-32
-+# register window little-endian flavor could achieve slightly higher
-+# Instruction Level Parallelism, and it indeed resulted in up to 15%
-+# better performance on most recent µ-archs...
-+#
-+# Third version adds AES_cbc_encrypt implementation, which resulted in
-+# up to 40% performance imrovement of CBC benchmark results. 40% was
-+# observed on P4 core, where "overall" imrovement coefficient, i.e. if
-+# compared to PIC generated by GCC and in CBC mode, was observed to be
-+# as large as 4x:-) CBC performance is virtually identical to ECB now
-+# and on some platforms even better, e.g. 17.6 "small" cycles/byte on
-+# Opteron, because certain function prologues and epilogues are
-+# effectively taken out of the loop...
-+#
-+# Version 3.2 implements compressed tables and prefetch of these tables
-+# in CBC[!] mode. Former means that 3/4 of table references are now
-+# misaligned, which unfortunately has negative impact on elder IA-32
-+# implementations, Pentium suffered 30% penalty, PIII - 10%.
-+#
-+# Version 3.3 avoids L1 cache aliasing between stack frame and
-+# S-boxes, and 3.4 - L1 cache aliasing even between key schedule. The
-+# latter is achieved by copying the key schedule to controlled place in
-+# stack. This unfortunately has rather strong impact on small block CBC
-+# performance, ~2x deterioration on 16-byte block if compared to 3.3.
-+#
-+# Version 3.5 checks if there is L1 cache aliasing between user-supplied
-+# key schedule and S-boxes and abstains from copying the former if
-+# there is no. This allows end-user to consciously retain small block
-+# performance by aligning key schedule in specific manner.
-+#
-+# Version 3.6 compresses Td4 to 256 bytes and prefetches it in ECB.
-+#
-+# Current ECB performance numbers for 128-bit key in CPU cycles per
-+# processed byte [measure commonly used by AES benchmarkers] are:
-+#
-+#		small footprint		fully unrolled
-+# P4		24			22
-+# AMD K8	20			19
-+# PIII		25			23
-+# Pentium	81			78
-+#
-+# Version 3.7 reimplements outer rounds as "compact." Meaning that
-+# first and last rounds reference compact 256 bytes S-box. This means
-+# that first round consumes a lot more CPU cycles and that encrypt
-+# and decrypt performance becomes asymmetric. Encrypt performance
-+# drops by 10-12%, while decrypt - by 20-25%:-( 256 bytes S-box is
-+# aggressively pre-fetched.
-+#
-+# Version 4.0 effectively rolls back to 3.6 and instead implements
-+# additional set of functions, _[x86|sse]_AES_[en|de]crypt_compact,
-+# which use exclusively 256 byte S-box. These functions are to be
-+# called in modes not concealing plain text, such as ECB, or when
-+# we're asked to process smaller amount of data [or unconditionally
-+# on hyper-threading CPU]. Currently it's called unconditionally from
-+# AES_[en|de]crypt, which affects all modes, but CBC. CBC routine
-+# still needs to be modified to switch between slower and faster
-+# mode when appropriate... But in either case benchmark landscape
-+# changes dramatically and below numbers are CPU cycles per processed
-+# byte for 128-bit key.
-+#
-+#		ECB encrypt	ECB decrypt	CBC large chunk
-+# P4		52[54]		83[95]		23
-+# AMD K8	46[41]		66[70]		18
-+# PIII		41[50]		60[77]		24
-+# Core 2	31[36]		45[64]		18.5
-+# Atom		76[100]		96[138]		60
-+# Pentium	115		150		77
-+#
-+# Version 4.1 switches to compact S-box even in key schedule setup.
-+#
-+# Version 4.2 prefetches compact S-box in every SSE round or in other
-+# words every cache-line is *guaranteed* to be accessed within ~50
-+# cycles window. Why just SSE? Because it's needed on hyper-threading
-+# CPU! Which is also why it's prefetched with 64 byte stride. Best
-+# part is that it has no negative effect on performance:-)  
-+#
-+# Version 4.3 implements switch between compact and non-compact block
-+# functions in AES_cbc_encrypt depending on how much data was asked
-+# to be processed in one stroke.
-+#
-+######################################################################
-+# Timing attacks are classified in two classes: synchronous when
-+# attacker consciously initiates cryptographic operation and collects
-+# timing data of various character afterwards, and asynchronous when
-+# malicious code is executed on same CPU simultaneously with AES,
-+# instruments itself and performs statistical analysis of this data.
-+#
-+# As far as synchronous attacks go the root to the AES timing
-+# vulnerability is twofold. Firstly, of 256 S-box elements at most 160
-+# are referred to in single 128-bit block operation. Well, in C
-+# implementation with 4 distinct tables it's actually as little as 40
-+# references per 256 elements table, but anyway... Secondly, even
-+# though S-box elements are clustered into smaller amount of cache-
-+# lines, smaller than 160 and even 40, it turned out that for certain
-+# plain-text pattern[s] or simply put chosen plain-text and given key
-+# few cache-lines remain unaccessed during block operation. Now, if
-+# attacker can figure out this access pattern, he can deduct the key
-+# [or at least part of it]. The natural way to mitigate this kind of
-+# attacks is to minimize the amount of cache-lines in S-box and/or
-+# prefetch them to ensure that every one is accessed for more uniform
-+# timing. But note that *if* plain-text was concealed in such way that
-+# input to block function is distributed *uniformly*, then attack
-+# wouldn't apply. Now note that some encryption modes, most notably
-+# CBC, do mask the plain-text in this exact way [secure cipher output
-+# is distributed uniformly]. Yes, one still might find input that
-+# would reveal the information about given key, but if amount of
-+# candidate inputs to be tried is larger than amount of possible key
-+# combinations then attack becomes infeasible. This is why revised
-+# AES_cbc_encrypt "dares" to switch to larger S-box when larger chunk
-+# of data is to be processed in one stroke. The current size limit of
-+# 512 bytes is chosen to provide same [diminishigly low] probability
-+# for cache-line to remain untouched in large chunk operation with
-+# large S-box as for single block operation with compact S-box and
-+# surely needs more careful consideration...
-+#
-+# As for asynchronous attacks. There are two flavours: attacker code
-+# being interleaved with AES on hyper-threading CPU at *instruction*
-+# level, and two processes time sharing single core. As for latter.
-+# Two vectors. 1. Given that attacker process has higher priority,
-+# yield execution to process performing AES just before timer fires
-+# off the scheduler, immediately regain control of CPU and analyze the
-+# cache state. For this attack to be efficient attacker would have to
-+# effectively slow down the operation by several *orders* of magnitute,
-+# by ratio of time slice to duration of handful of AES rounds, which
-+# unlikely to remain unnoticed. Not to mention that this also means
-+# that he would spend correspondigly more time to collect enough
-+# statistical data to mount the attack. It's probably appropriate to
-+# say that if adeversary reckons that this attack is beneficial and
-+# risks to be noticed, you probably have larger problems having him
-+# mere opportunity. In other words suggested code design expects you
-+# to preclude/mitigate this attack by overall system security design.
-+# 2. Attacker manages to make his code interrupt driven. In order for
-+# this kind of attack to be feasible, interrupt rate has to be high
-+# enough, again comparable to duration of handful of AES rounds. But
-+# is there interrupt source of such rate? Hardly, not even 1Gbps NIC
-+# generates interrupts at such raging rate...
-+#
-+# And now back to the former, hyper-threading CPU or more specifically
-+# Intel P4. Recall that asynchronous attack implies that malicious
-+# code instruments itself. And naturally instrumentation granularity
-+# has be noticeably lower than duration of codepath accessing S-box.
-+# Given that all cache-lines are accessed during that time that is.
-+# Current implementation accesses *all* cache-lines within ~50 cycles
-+# window, which is actually *less* than RDTSC latency on Intel P4!
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output = pop;
-+open OUT,">$output";
-+*STDOUT=*OUT;
-+
-+&asm_init($ARGV[0],"aes-586.pl",$x86only = $ARGV[$#ARGV] eq "386");
-+&static_label("AES_Te");
-+&static_label("AES_Td");
-+
-+$s0="eax";
-+$s1="ebx";
-+$s2="ecx";
-+$s3="edx";
-+$key="edi";
-+$acc="esi";
-+$tbl="ebp";
-+
-+# stack frame layout in _[x86|sse]_AES_* routines, frame is allocated
-+# by caller
-+$__ra=&DWP(0,"esp");	# return address
-+$__s0=&DWP(4,"esp");	# s0 backing store
-+$__s1=&DWP(8,"esp");	# s1 backing store
-+$__s2=&DWP(12,"esp");	# s2 backing store
-+$__s3=&DWP(16,"esp");	# s3 backing store
-+$__key=&DWP(20,"esp");	# pointer to key schedule
-+$__end=&DWP(24,"esp");	# pointer to end of key schedule
-+$__tbl=&DWP(28,"esp");	# %ebp backing store
-+
-+# stack frame layout in AES_[en|crypt] routines, which differs from
-+# above by 4 and overlaps by %ebp backing store
-+$_tbl=&DWP(24,"esp");
-+$_esp=&DWP(28,"esp");
-+
-+sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
-+
-+$speed_limit=512;	# chunks smaller than $speed_limit are
-+			# processed with compact routine in CBC mode
-+$small_footprint=1;	# $small_footprint=1 code is ~5% slower [on
-+			# recent µ-archs], but ~5 times smaller!
-+			# I favor compact code to minimize cache
-+			# contention and in hope to "collect" 5% back
-+			# in real-life applications...
-+
-+$vertical_spin=0;	# shift "verticaly" defaults to 0, because of
-+			# its proof-of-concept status...
-+# Note that there is no decvert(), as well as last encryption round is
-+# performed with "horizontal" shifts. This is because this "vertical"
-+# implementation [one which groups shifts on a given $s[i] to form a
-+# "column," unlike "horizontal" one, which groups shifts on different
-+# $s[i] to form a "row"] is work in progress. It was observed to run
-+# few percents faster on Intel cores, but not AMD. On AMD K8 core it's
-+# whole 12% slower:-( So we face a trade-off... Shall it be resolved
-+# some day? Till then the code is considered experimental and by
-+# default remains dormant...
-+
-+sub encvert()
-+{ my ($te,@s) = @_;
-+  my ($v0,$v1) = ($acc,$key);
-+
-+	&mov	($v0,$s[3]);				# copy s3
-+	&mov	(&DWP(4,"esp"),$s[2]);			# save s2
-+	&mov	($v1,$s[0]);				# copy s0
-+	&mov	(&DWP(8,"esp"),$s[1]);			# save s1
-+
-+	&movz	($s[2],&HB($s[0]));
-+	&and	($s[0],0xFF);
-+	&mov	($s[0],&DWP(0,$te,$s[0],8));		# s0>>0
-+	&shr	($v1,16);
-+	&mov	($s[3],&DWP(3,$te,$s[2],8));		# s0>>8
-+	&movz	($s[1],&HB($v1));
-+	&and	($v1,0xFF);
-+	&mov	($s[2],&DWP(2,$te,$v1,8));		# s0>>16
-+	 &mov	($v1,$v0);
-+	&mov	($s[1],&DWP(1,$te,$s[1],8));		# s0>>24
-+
-+	&and	($v0,0xFF);
-+	&xor	($s[3],&DWP(0,$te,$v0,8));		# s3>>0
-+	&movz	($v0,&HB($v1));
-+	&shr	($v1,16);
-+	&xor	($s[2],&DWP(3,$te,$v0,8));		# s3>>8
-+	&movz	($v0,&HB($v1));
-+	&and	($v1,0xFF);
-+	&xor	($s[1],&DWP(2,$te,$v1,8));		# s3>>16
-+	 &mov	($v1,&DWP(4,"esp"));			# restore s2
-+	&xor	($s[0],&DWP(1,$te,$v0,8));		# s3>>24
-+
-+	&mov	($v0,$v1);
-+	&and	($v1,0xFF);
-+	&xor	($s[2],&DWP(0,$te,$v1,8));		# s2>>0
-+	&movz	($v1,&HB($v0));
-+	&shr	($v0,16);
-+	&xor	($s[1],&DWP(3,$te,$v1,8));		# s2>>8
-+	&movz	($v1,&HB($v0));
-+	&and	($v0,0xFF);
-+	&xor	($s[0],&DWP(2,$te,$v0,8));		# s2>>16
-+	 &mov	($v0,&DWP(8,"esp"));			# restore s1
-+	&xor	($s[3],&DWP(1,$te,$v1,8));		# s2>>24
-+
-+	&mov	($v1,$v0);
-+	&and	($v0,0xFF);
-+	&xor	($s[1],&DWP(0,$te,$v0,8));		# s1>>0
-+	&movz	($v0,&HB($v1));
-+	&shr	($v1,16);
-+	&xor	($s[0],&DWP(3,$te,$v0,8));		# s1>>8
-+	&movz	($v0,&HB($v1));
-+	&and	($v1,0xFF);
-+	&xor	($s[3],&DWP(2,$te,$v1,8));		# s1>>16
-+	 &mov	($key,$__key);				# reincarnate v1 as key
-+	&xor	($s[2],&DWP(1,$te,$v0,8));		# s1>>24
-+}
-+
-+# Another experimental routine, which features "horizontal spin," but
-+# eliminates one reference to stack. Strangely enough runs slower...
-+sub enchoriz()
-+{ my ($v0,$v1) = ($key,$acc);
-+
-+	&movz	($v0,&LB($s0));			#  3, 2, 1, 0*
-+	&rotr	($s2,8);			#  8,11,10, 9
-+	&mov	($v1,&DWP(0,$te,$v0,8));	#  0
-+	&movz	($v0,&HB($s1));			#  7, 6, 5*, 4
-+	&rotr	($s3,16);			# 13,12,15,14
-+	&xor	($v1,&DWP(3,$te,$v0,8));	#  5
-+	&movz	($v0,&HB($s2));			#  8,11,10*, 9
-+	&rotr	($s0,16);			#  1, 0, 3, 2
-+	&xor	($v1,&DWP(2,$te,$v0,8));	# 10
-+	&movz	($v0,&HB($s3));			# 13,12,15*,14
-+	&xor	($v1,&DWP(1,$te,$v0,8));	# 15, t[0] collected
-+	&mov	($__s0,$v1);			# t[0] saved
-+
-+	&movz	($v0,&LB($s1));			#  7, 6, 5, 4*
-+	&shr	($s1,16);			#  -, -, 7, 6
-+	&mov	($v1,&DWP(0,$te,$v0,8));	#  4
-+	&movz	($v0,&LB($s3));			# 13,12,15,14*
-+	&xor	($v1,&DWP(2,$te,$v0,8));	# 14
-+	&movz	($v0,&HB($s0));			#  1, 0, 3*, 2
-+	&and	($s3,0xffff0000);		# 13,12, -, -
-+	&xor	($v1,&DWP(1,$te,$v0,8));	#  3
-+	&movz	($v0,&LB($s2));			#  8,11,10, 9*
-+	&or	($s3,$s1);			# 13,12, 7, 6
-+	&xor	($v1,&DWP(3,$te,$v0,8));	#  9, t[1] collected
-+	&mov	($s1,$v1);			#  s[1]=t[1]
-+
-+	&movz	($v0,&LB($s0));			#  1, 0, 3, 2*
-+	&shr	($s2,16);			#  -, -, 8,11
-+	&mov	($v1,&DWP(2,$te,$v0,8));	#  2
-+	&movz	($v0,&HB($s3));			# 13,12, 7*, 6
-+	&xor	($v1,&DWP(1,$te,$v0,8));	#  7
-+	&movz	($v0,&HB($s2));			#  -, -, 8*,11
-+	&xor	($v1,&DWP(0,$te,$v0,8));	#  8
-+	&mov	($v0,$s3);
-+	&shr	($v0,24);			# 13
-+	&xor	($v1,&DWP(3,$te,$v0,8));	# 13, t[2] collected
-+
-+	&movz	($v0,&LB($s2));			#  -, -, 8,11*
-+	&shr	($s0,24);			#  1*
-+	&mov	($s2,&DWP(1,$te,$v0,8));	# 11
-+	&xor	($s2,&DWP(3,$te,$s0,8));	#  1
-+	&mov	($s0,$__s0);			# s[0]=t[0]
-+	&movz	($v0,&LB($s3));			# 13,12, 7, 6*
-+	&shr	($s3,16);			#   ,  ,13,12
-+	&xor	($s2,&DWP(2,$te,$v0,8));	#  6
-+	&mov	($key,$__key);			# reincarnate v0 as key
-+	&and	($s3,0xff);			#   ,  ,13,12*
-+	&mov	($s3,&DWP(0,$te,$s3,8));	# 12
-+	&xor	($s3,$s2);			# s[2]=t[3] collected
-+	&mov	($s2,$v1);			# s[2]=t[2]
-+}
-+
-+# More experimental code... SSE one... Even though this one eliminates
-+# *all* references to stack, it's not faster...
-+sub sse_encbody()
-+{
-+	&movz	($acc,&LB("eax"));		#  0
-+	&mov	("ecx",&DWP(0,$tbl,$acc,8));	#  0
-+	&pshufw	("mm2","mm0",0x0d);		#  7, 6, 3, 2
-+	&movz	("edx",&HB("eax"));		#  1
-+	&mov	("edx",&DWP(3,$tbl,"edx",8));	#  1
-+	&shr	("eax",16);			#  5, 4
-+
-+	&movz	($acc,&LB("ebx"));		# 10
-+	&xor	("ecx",&DWP(2,$tbl,$acc,8));	# 10
-+	&pshufw	("mm6","mm4",0x08);		# 13,12, 9, 8
-+	&movz	($acc,&HB("ebx"));		# 11
-+	&xor	("edx",&DWP(1,$tbl,$acc,8));	# 11
-+	&shr	("ebx",16);			# 15,14
-+
-+	&movz	($acc,&HB("eax"));		#  5
-+	&xor	("ecx",&DWP(3,$tbl,$acc,8));	#  5
-+	&movq	("mm3",QWP(16,$key));
-+	&movz	($acc,&HB("ebx"));		# 15
-+	&xor	("ecx",&DWP(1,$tbl,$acc,8));	# 15
-+	&movd	("mm0","ecx");			# t[0] collected
-+
-+	&movz	($acc,&LB("eax"));		#  4
-+	&mov	("ecx",&DWP(0,$tbl,$acc,8));	#  4
-+	&movd	("eax","mm2");			#  7, 6, 3, 2
-+	&movz	($acc,&LB("ebx"));		# 14
-+	&xor	("ecx",&DWP(2,$tbl,$acc,8));	# 14
-+	&movd	("ebx","mm6");			# 13,12, 9, 8
-+
-+	&movz	($acc,&HB("eax"));		#  3
-+	&xor	("ecx",&DWP(1,$tbl,$acc,8));	#  3
-+	&movz	($acc,&HB("ebx"));		#  9
-+	&xor	("ecx",&DWP(3,$tbl,$acc,8));	#  9
-+	&movd	("mm1","ecx");			# t[1] collected
-+
-+	&movz	($acc,&LB("eax"));		#  2
-+	&mov	("ecx",&DWP(2,$tbl,$acc,8));	#  2
-+	&shr	("eax",16);			#  7, 6
-+	&punpckldq	("mm0","mm1");		# t[0,1] collected
-+	&movz	($acc,&LB("ebx"));		#  8
-+	&xor	("ecx",&DWP(0,$tbl,$acc,8));	#  8
-+	&shr	("ebx",16);			# 13,12
-+
-+	&movz	($acc,&HB("eax"));		#  7
-+	&xor	("ecx",&DWP(1,$tbl,$acc,8));	#  7
-+	&pxor	("mm0","mm3");
-+	&movz	("eax",&LB("eax"));		#  6
-+	&xor	("edx",&DWP(2,$tbl,"eax",8));	#  6
-+	&pshufw	("mm1","mm0",0x08);		#  5, 4, 1, 0
-+	&movz	($acc,&HB("ebx"));		# 13
-+	&xor	("ecx",&DWP(3,$tbl,$acc,8));	# 13
-+	&xor	("ecx",&DWP(24,$key));		# t[2]
-+	&movd	("mm4","ecx");			# t[2] collected
-+	&movz	("ebx",&LB("ebx"));		# 12
-+	&xor	("edx",&DWP(0,$tbl,"ebx",8));	# 12
-+	&shr	("ecx",16);
-+	&movd	("eax","mm1");			#  5, 4, 1, 0
-+	&mov	("ebx",&DWP(28,$key));		# t[3]
-+	&xor	("ebx","edx");
-+	&movd	("mm5","ebx");			# t[3] collected
-+	&and	("ebx",0xffff0000);
-+	&or	("ebx","ecx");
-+
-+	&punpckldq	("mm4","mm5");		# t[2,3] collected
-+}
-+
-+######################################################################
-+# "Compact" block function
-+######################################################################
-+
-+sub enccompact()
-+{ my $Fn = \&mov;
-+  while ($#_>5) { pop(@_); $Fn=sub{}; }
-+  my ($i,$te,@s)=@_;
-+  my $tmp = $key;
-+  my $out = $i==3?$s[0]:$acc;
-+
-+	# $Fn is used in first compact round and its purpose is to
-+	# void restoration of some values from stack, so that after
-+	# 4xenccompact with extra argument $key value is left there...
-+	if ($i==3)  {	&$Fn	($key,$__key);			}##%edx
-+	else        {	&mov	($out,$s[0]);			}
-+			&and	($out,0xFF);
-+	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
-+	if ($i==2)  {	&shr	($s[0],24);			}#%ecx[2]
-+			&movz	($out,&BP(-128,$te,$out,1));
-+
-+	if ($i==3)  {	$tmp=$s[1];				}##%eax
-+			&movz	($tmp,&HB($s[1]));
-+			&movz	($tmp,&BP(-128,$te,$tmp,1));
-+			&shl	($tmp,8);
-+			&xor	($out,$tmp);
-+
-+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
-+	else        {	&mov	($tmp,$s[2]);
-+			&shr	($tmp,16);			}
-+	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
-+			&and	($tmp,0xFF);
-+			&movz	($tmp,&BP(-128,$te,$tmp,1));
-+			&shl	($tmp,16);
-+			&xor	($out,$tmp);
-+
-+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
-+	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
-+	else        {	&mov	($tmp,$s[3]);
-+			&shr	($tmp,24);			}
-+			&movz	($tmp,&BP(-128,$te,$tmp,1));
-+			&shl	($tmp,24);
-+			&xor	($out,$tmp);
-+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
-+	if ($i==3)  {	&mov	($s[3],$acc);			}
-+	&comment();
-+}
-+
-+sub enctransform()
-+{ my @s = ($s0,$s1,$s2,$s3);
-+  my $i = shift;
-+  my $tmp = $tbl;
-+  my $r2  = $key ;
-+
-+	&and	($tmp,$s[$i]);
-+	&lea	($r2,&DWP(0,$s[$i],$s[$i]));
-+	&mov	($acc,$tmp);
-+	&shr	($tmp,7);
-+	&and	($r2,0xfefefefe);
-+	&sub	($acc,$tmp);
-+	&mov	($tmp,$s[$i]);
-+	&and	($acc,0x1b1b1b1b);
-+	&rotr	($tmp,16);
-+	&xor	($acc,$r2);	# r2
-+	&mov	($r2,$s[$i]);
-+
-+	&xor	($s[$i],$acc);	# r0 ^ r2
-+	&rotr	($r2,16+8);
-+	&xor	($acc,$tmp);
-+	&rotl	($s[$i],24);
-+	&xor	($acc,$r2);
-+	&mov	($tmp,0x80808080)	if ($i!=1);
-+	&xor	($s[$i],$acc);	# ROTATE(r2^r0,24) ^ r2
-+}
-+
-+&function_begin_B("_x86_AES_encrypt_compact");
-+	# note that caller is expected to allocate stack frame for me!
-+	&mov	($__key,$key);			# save key
-+
-+	&xor	($s0,&DWP(0,$key));		# xor with key
-+	&xor	($s1,&DWP(4,$key));
-+	&xor	($s2,&DWP(8,$key));
-+	&xor	($s3,&DWP(12,$key));
-+
-+	&mov	($acc,&DWP(240,$key));		# load key->rounds
-+	&lea	($acc,&DWP(-2,$acc,$acc));
-+	&lea	($acc,&DWP(0,$key,$acc,8));
-+	&mov	($__end,$acc);			# end of key schedule
-+
-+	# prefetch Te4
-+	&mov	($key,&DWP(0-128,$tbl));
-+	&mov	($acc,&DWP(32-128,$tbl));
-+	&mov	($key,&DWP(64-128,$tbl));
-+	&mov	($acc,&DWP(96-128,$tbl));
-+	&mov	($key,&DWP(128-128,$tbl));
-+	&mov	($acc,&DWP(160-128,$tbl));
-+	&mov	($key,&DWP(192-128,$tbl));
-+	&mov	($acc,&DWP(224-128,$tbl));
-+
-+	&set_label("loop",16);
-+
-+		&enccompact(0,$tbl,$s0,$s1,$s2,$s3,1);
-+		&enccompact(1,$tbl,$s1,$s2,$s3,$s0,1);
-+		&enccompact(2,$tbl,$s2,$s3,$s0,$s1,1);
-+		&enccompact(3,$tbl,$s3,$s0,$s1,$s2,1);
-+		&mov	($tbl,0x80808080);
-+		&enctransform(2);
-+		&enctransform(3);
-+		&enctransform(0);
-+		&enctransform(1);
-+		&mov 	($key,$__key);
-+		&mov	($tbl,$__tbl);
-+		&add	($key,16);		# advance rd_key
-+		&xor	($s0,&DWP(0,$key));
-+		&xor	($s1,&DWP(4,$key));
-+		&xor	($s2,&DWP(8,$key));
-+		&xor	($s3,&DWP(12,$key));
-+
-+	&cmp	($key,$__end);
-+	&mov	($__key,$key);
-+	&jb	(&label("loop"));
-+
-+	&enccompact(0,$tbl,$s0,$s1,$s2,$s3);
-+	&enccompact(1,$tbl,$s1,$s2,$s3,$s0);
-+	&enccompact(2,$tbl,$s2,$s3,$s0,$s1);
-+	&enccompact(3,$tbl,$s3,$s0,$s1,$s2);
-+
-+	&xor	($s0,&DWP(16,$key));
-+	&xor	($s1,&DWP(20,$key));
-+	&xor	($s2,&DWP(24,$key));
-+	&xor	($s3,&DWP(28,$key));
-+
-+	&ret	();
-+&function_end_B("_x86_AES_encrypt_compact");
-+
-+######################################################################
-+# "Compact" SSE block function.
-+######################################################################
-+#
-+# Performance is not actually extraordinary in comparison to pure
-+# x86 code. In particular encrypt performance is virtually the same.
-+# Decrypt performance on the other hand is 15-20% better on newer
-+# µ-archs [but we're thankful for *any* improvement here], and ~50%
-+# better on PIII:-) And additionally on the pros side this code
-+# eliminates redundant references to stack and thus relieves/
-+# minimizes the pressure on the memory bus.
-+#
-+# MMX register layout                           lsb
-+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-+# |          mm4          |          mm0          |
-+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-+# |     s3    |     s2    |     s1    |     s0    |    
-+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-+# |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-+# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-+#
-+# Indexes translate as s[N/4]>>(8*(N%4)), e.g. 5 means s1>>8.
-+# In this terms encryption and decryption "compact" permutation
-+# matrices can be depicted as following:
-+#
-+# encryption              lsb	# decryption              lsb
-+# +----++----+----+----+----+	# +----++----+----+----+----+
-+# | t0 || 15 | 10 |  5 |  0 |	# | t0 ||  7 | 10 | 13 |  0 |
-+# +----++----+----+----+----+	# +----++----+----+----+----+
-+# | t1 ||  3 | 14 |  9 |  4 |	# | t1 || 11 | 14 |  1 |  4 |
-+# +----++----+----+----+----+	# +----++----+----+----+----+
-+# | t2 ||  7 |  2 | 13 |  8 |	# | t2 || 15 |  2 |  5 |  8 |
-+# +----++----+----+----+----+	# +----++----+----+----+----+
-+# | t3 || 11 |  6 |  1 | 12 |	# | t3 ||  3 |  6 |  9 | 12 |
-+# +----++----+----+----+----+	# +----++----+----+----+----+
-+#
-+######################################################################
-+# Why not xmm registers? Short answer. It was actually tested and
-+# was not any faster, but *contrary*, most notably on Intel CPUs.
-+# Longer answer. Main advantage of using mm registers is that movd
-+# latency is lower, especially on Intel P4. While arithmetic
-+# instructions are twice as many, they can be scheduled every cycle
-+# and not every second one when they are operating on xmm register,
-+# so that "arithmetic throughput" remains virtually the same. And
-+# finally the code can be executed even on elder SSE-only CPUs:-)
-+
-+sub sse_enccompact()
-+{
-+	&pshufw	("mm1","mm0",0x08);		#  5, 4, 1, 0
-+	&pshufw	("mm5","mm4",0x0d);		# 15,14,11,10
-+	&movd	("eax","mm1");			#  5, 4, 1, 0
-+	&movd	("ebx","mm5");			# 15,14,11,10
-+	&mov	($__key,$key);
-+
-+	&movz	($acc,&LB("eax"));		#  0
-+	&movz	("edx",&HB("eax"));		#  1
-+	&pshufw	("mm2","mm0",0x0d);		#  7, 6, 3, 2
-+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  0
-+	&movz	($key,&LB("ebx"));		# 10
-+	&movz	("edx",&BP(-128,$tbl,"edx",1));	#  1
-+	&shr	("eax",16);			#  5, 4
-+	&shl	("edx",8);			#  1
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	# 10
-+	&movz	($key,&HB("ebx"));		# 11
-+	&shl	($acc,16);			# 10
-+	&pshufw	("mm6","mm4",0x08);		# 13,12, 9, 8
-+	&or	("ecx",$acc);			# 10
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	# 11
-+	&movz	($key,&HB("eax"));		#  5
-+	&shl	($acc,24);			# 11
-+	&shr	("ebx",16);			# 15,14
-+	&or	("edx",$acc);			# 11
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  5
-+	&movz	($key,&HB("ebx"));		# 15
-+	&shl	($acc,8);			#  5
-+	&or	("ecx",$acc);			#  5
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	# 15
-+	&movz	($key,&LB("eax"));		#  4
-+	&shl	($acc,24);			# 15
-+	&or	("ecx",$acc);			# 15
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  4
-+	&movz	($key,&LB("ebx"));		# 14
-+	&movd	("eax","mm2");			#  7, 6, 3, 2
-+	&movd	("mm0","ecx");			# t[0] collected
-+	&movz	("ecx",&BP(-128,$tbl,$key,1));	# 14
-+	&movz	($key,&HB("eax"));		#  3
-+	&shl	("ecx",16);			# 14
-+	&movd	("ebx","mm6");			# 13,12, 9, 8
-+	&or	("ecx",$acc);			# 14
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  3
-+	&movz	($key,&HB("ebx"));		#  9
-+	&shl	($acc,24);			#  3
-+	&or	("ecx",$acc);			#  3
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  9
-+	&movz	($key,&LB("ebx"));		#  8
-+	&shl	($acc,8);			#  9
-+	&shr	("ebx",16);			# 13,12
-+	&or	("ecx",$acc);			#  9
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  8
-+	&movz	($key,&LB("eax"));		#  2
-+	&shr	("eax",16);			#  7, 6
-+	&movd	("mm1","ecx");			# t[1] collected
-+	&movz	("ecx",&BP(-128,$tbl,$key,1));	#  2
-+	&movz	($key,&HB("eax"));		#  7
-+	&shl	("ecx",16);			#  2
-+	&and	("eax",0xff);			#  6
-+	&or	("ecx",$acc);			#  2
-+
-+	&punpckldq	("mm0","mm1");		# t[0,1] collected
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  7
-+	&movz	($key,&HB("ebx"));		# 13
-+	&shl	($acc,24);			#  7
-+	&and	("ebx",0xff);			# 12
-+	&movz	("eax",&BP(-128,$tbl,"eax",1));	#  6
-+	&or	("ecx",$acc);			#  7
-+	&shl	("eax",16);			#  6
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	# 13
-+	&or	("edx","eax");			#  6
-+	&shl	($acc,8);			# 13
-+	&movz	("ebx",&BP(-128,$tbl,"ebx",1));	# 12
-+	&or	("ecx",$acc);			# 13
-+	&or	("edx","ebx");			# 12
-+	&mov	($key,$__key);
-+	&movd	("mm4","ecx");			# t[2] collected
-+	&movd	("mm5","edx");			# t[3] collected
-+
-+	&punpckldq	("mm4","mm5");		# t[2,3] collected
-+}
-+
-+					if (!$x86only) {
-+&function_begin_B("_sse_AES_encrypt_compact");
-+	&pxor	("mm0",&QWP(0,$key));	#  7, 6, 5, 4, 3, 2, 1, 0
-+	&pxor	("mm4",&QWP(8,$key));	# 15,14,13,12,11,10, 9, 8
-+
-+	# note that caller is expected to allocate stack frame for me!
-+	&mov	($acc,&DWP(240,$key));		# load key->rounds
-+	&lea	($acc,&DWP(-2,$acc,$acc));
-+	&lea	($acc,&DWP(0,$key,$acc,8));
-+	&mov	($__end,$acc);			# end of key schedule
-+
-+	&mov	($s0,0x1b1b1b1b);		# magic constant
-+	&mov	(&DWP(8,"esp"),$s0);
-+	&mov	(&DWP(12,"esp"),$s0);
-+
-+	# prefetch Te4
-+	&mov	($s0,&DWP(0-128,$tbl));
-+	&mov	($s1,&DWP(32-128,$tbl));
-+	&mov	($s2,&DWP(64-128,$tbl));
-+	&mov	($s3,&DWP(96-128,$tbl));
-+	&mov	($s0,&DWP(128-128,$tbl));
-+	&mov	($s1,&DWP(160-128,$tbl));
-+	&mov	($s2,&DWP(192-128,$tbl));
-+	&mov	($s3,&DWP(224-128,$tbl));
-+
-+	&set_label("loop",16);
-+		&sse_enccompact();
-+		&add	($key,16);
-+		&cmp	($key,$__end);
-+		&ja	(&label("out"));
-+
-+		&movq	("mm2",&QWP(8,"esp"));
-+		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
-+		&movq	("mm1","mm0");		&movq	("mm5","mm4");	# r0
-+		&pcmpgtb("mm3","mm0");		&pcmpgtb("mm7","mm4");
-+		&pand	("mm3","mm2");		&pand	("mm7","mm2");
-+		&pshufw	("mm2","mm0",0xb1);	&pshufw	("mm6","mm4",0xb1);# ROTATE(r0,16)
-+		&paddb	("mm0","mm0");		&paddb	("mm4","mm4");
-+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# = r2
-+		&pshufw	("mm3","mm2",0xb1);	&pshufw	("mm7","mm6",0xb1);# r0
-+		&pxor	("mm1","mm0");		&pxor	("mm5","mm4");	# r0^r2
-+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= ROTATE(r0,16)
-+
-+		&movq	("mm2","mm3");		&movq	("mm6","mm7");
-+		&pslld	("mm3",8);		&pslld	("mm7",8);
-+		&psrld	("mm2",24);		&psrld	("mm6",24);
-+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= r0<<8
-+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= r0>>24
-+
-+		&movq	("mm3","mm1");		&movq	("mm7","mm5");
-+		&movq	("mm2",&QWP(0,$key));	&movq	("mm6",&QWP(8,$key));
-+		&psrld	("mm1",8);		&psrld	("mm5",8);
-+		&mov	($s0,&DWP(0-128,$tbl));
-+		&pslld	("mm3",24);		&pslld	("mm7",24);
-+		&mov	($s1,&DWP(64-128,$tbl));
-+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= (r2^r0)<<8
-+		&mov	($s2,&DWP(128-128,$tbl));
-+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= (r2^r0)>>24
-+		&mov	($s3,&DWP(192-128,$tbl));
-+
-+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");
-+	&jmp	(&label("loop"));
-+
-+	&set_label("out",16);
-+	&pxor	("mm0",&QWP(0,$key));
-+	&pxor	("mm4",&QWP(8,$key));
-+
-+	&ret	();
-+&function_end_B("_sse_AES_encrypt_compact");
-+					}
-+
-+######################################################################
-+# Vanilla block function.
-+######################################################################
-+
-+sub encstep()
-+{ my ($i,$te,@s) = @_;
-+  my $tmp = $key;
-+  my $out = $i==3?$s[0]:$acc;
-+
-+	# lines marked with #%e?x[i] denote "reordered" instructions...
-+	if ($i==3)  {	&mov	($key,$__key);			}##%edx
-+	else        {	&mov	($out,$s[0]);
-+			&and	($out,0xFF);			}
-+	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
-+	if ($i==2)  {	&shr	($s[0],24);			}#%ecx[2]
-+			&mov	($out,&DWP(0,$te,$out,8));
-+
-+	if ($i==3)  {	$tmp=$s[1];				}##%eax
-+			&movz	($tmp,&HB($s[1]));
-+			&xor	($out,&DWP(3,$te,$tmp,8));
-+
-+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
-+	else        {	&mov	($tmp,$s[2]);
-+			&shr	($tmp,16);			}
-+	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
-+			&and	($tmp,0xFF);
-+			&xor	($out,&DWP(2,$te,$tmp,8));
-+
-+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
-+	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
-+	else        {	&mov	($tmp,$s[3]); 
-+			&shr	($tmp,24)			}
-+			&xor	($out,&DWP(1,$te,$tmp,8));
-+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
-+	if ($i==3)  {	&mov	($s[3],$acc);			}
-+			&comment();
-+}
-+
-+sub enclast()
-+{ my ($i,$te,@s)=@_;
-+  my $tmp = $key;
-+  my $out = $i==3?$s[0]:$acc;
-+
-+	if ($i==3)  {	&mov	($key,$__key);			}##%edx
-+	else        {	&mov	($out,$s[0]);			}
-+			&and	($out,0xFF);
-+	if ($i==1)  {	&shr	($s[0],16);			}#%ebx[1]
-+	if ($i==2)  {	&shr	($s[0],24);			}#%ecx[2]
-+			&mov	($out,&DWP(2,$te,$out,8));
-+			&and	($out,0x000000ff);
-+
-+	if ($i==3)  {	$tmp=$s[1];				}##%eax
-+			&movz	($tmp,&HB($s[1]));
-+			&mov	($tmp,&DWP(0,$te,$tmp,8));
-+			&and	($tmp,0x0000ff00);
-+			&xor	($out,$tmp);
-+
-+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$__s0);		}##%ebx
-+	else        {	&mov	($tmp,$s[2]);
-+			&shr	($tmp,16);			}
-+	if ($i==2)  {	&and	($s[1],0xFF);			}#%edx[2]
-+			&and	($tmp,0xFF);
-+			&mov	($tmp,&DWP(0,$te,$tmp,8));
-+			&and	($tmp,0x00ff0000);
-+			&xor	($out,$tmp);
-+
-+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}##%ecx
-+	elsif($i==2){	&movz	($tmp,&HB($s[3]));		}#%ebx[2]
-+	else        {	&mov	($tmp,$s[3]);
-+			&shr	($tmp,24);			}
-+			&mov	($tmp,&DWP(2,$te,$tmp,8));
-+			&and	($tmp,0xff000000);
-+			&xor	($out,$tmp);
-+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
-+	if ($i==3)  {	&mov	($s[3],$acc);			}
-+}
-+
-+&function_begin_B("_x86_AES_encrypt");
-+	if ($vertical_spin) {
-+		# I need high parts of volatile registers to be accessible...
-+		&exch	($s1="edi",$key="ebx");
-+		&mov	($s2="esi",$acc="ecx");
-+	}
-+
-+	# note that caller is expected to allocate stack frame for me!
-+	&mov	($__key,$key);			# save key
-+
-+	&xor	($s0,&DWP(0,$key));		# xor with key
-+	&xor	($s1,&DWP(4,$key));
-+	&xor	($s2,&DWP(8,$key));
-+	&xor	($s3,&DWP(12,$key));
-+
-+	&mov	($acc,&DWP(240,$key));		# load key->rounds
-+
-+	if ($small_footprint) {
-+	    &lea	($acc,&DWP(-2,$acc,$acc));
-+	    &lea	($acc,&DWP(0,$key,$acc,8));
-+	    &mov	($__end,$acc);		# end of key schedule
-+
-+	    &set_label("loop",16);
-+		if ($vertical_spin) {
-+		    &encvert($tbl,$s0,$s1,$s2,$s3);
-+		} else {
-+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
-+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
-+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
-+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
-+		}
-+		&add	($key,16);		# advance rd_key
-+		&xor	($s0,&DWP(0,$key));
-+		&xor	($s1,&DWP(4,$key));
-+		&xor	($s2,&DWP(8,$key));
-+		&xor	($s3,&DWP(12,$key));
-+	    &cmp	($key,$__end);
-+	    &mov	($__key,$key);
-+	    &jb		(&label("loop"));
-+	}
-+	else {
-+	    &cmp	($acc,10);
-+	    &jle	(&label("10rounds"));
-+	    &cmp	($acc,12);
-+	    &jle	(&label("12rounds"));
-+
-+	&set_label("14rounds",4);
-+	    for ($i=1;$i<3;$i++) {
-+		if ($vertical_spin) {
-+		    &encvert($tbl,$s0,$s1,$s2,$s3);
-+		} else {
-+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
-+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
-+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
-+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
-+		}
-+		&xor	($s0,&DWP(16*$i+0,$key));
-+		&xor	($s1,&DWP(16*$i+4,$key));
-+		&xor	($s2,&DWP(16*$i+8,$key));
-+		&xor	($s3,&DWP(16*$i+12,$key));
-+	    }
-+	    &add	($key,32);
-+	    &mov	($__key,$key);		# advance rd_key
-+	&set_label("12rounds",4);
-+	    for ($i=1;$i<3;$i++) {
-+		if ($vertical_spin) {
-+		    &encvert($tbl,$s0,$s1,$s2,$s3);
-+		} else {
-+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
-+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
-+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
-+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
-+		}
-+		&xor	($s0,&DWP(16*$i+0,$key));
-+		&xor	($s1,&DWP(16*$i+4,$key));
-+		&xor	($s2,&DWP(16*$i+8,$key));
-+		&xor	($s3,&DWP(16*$i+12,$key));
-+	    }
-+	    &add	($key,32);
-+	    &mov	($__key,$key);		# advance rd_key
-+	&set_label("10rounds",4);
-+	    for ($i=1;$i<10;$i++) {
-+		if ($vertical_spin) {
-+		    &encvert($tbl,$s0,$s1,$s2,$s3);
-+		} else {
-+		    &encstep(0,$tbl,$s0,$s1,$s2,$s3);
-+		    &encstep(1,$tbl,$s1,$s2,$s3,$s0);
-+		    &encstep(2,$tbl,$s2,$s3,$s0,$s1);
-+		    &encstep(3,$tbl,$s3,$s0,$s1,$s2);
-+		}
-+		&xor	($s0,&DWP(16*$i+0,$key));
-+		&xor	($s1,&DWP(16*$i+4,$key));
-+		&xor	($s2,&DWP(16*$i+8,$key));
-+		&xor	($s3,&DWP(16*$i+12,$key));
-+	    }
-+	}
-+
-+	if ($vertical_spin) {
-+	    # "reincarnate" some registers for "horizontal" spin...
-+	    &mov	($s1="ebx",$key="edi");
-+	    &mov	($s2="ecx",$acc="esi");
-+	}
-+	&enclast(0,$tbl,$s0,$s1,$s2,$s3);
-+	&enclast(1,$tbl,$s1,$s2,$s3,$s0);
-+	&enclast(2,$tbl,$s2,$s3,$s0,$s1);
-+	&enclast(3,$tbl,$s3,$s0,$s1,$s2);
-+
-+	&add	($key,$small_footprint?16:160);
-+	&xor	($s0,&DWP(0,$key));
-+	&xor	($s1,&DWP(4,$key));
-+	&xor	($s2,&DWP(8,$key));
-+	&xor	($s3,&DWP(12,$key));
-+
-+	&ret	();
-+
-+&set_label("AES_Te",64);	# Yes! I keep it in the code segment!
-+	&_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6);
-+	&_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591);
-+	&_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56);
-+	&_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec);
-+	&_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa);
-+	&_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb);
-+	&_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45);
-+	&_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b);
-+	&_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c);
-+	&_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83);
-+	&_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9);
-+	&_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a);
-+	&_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d);
-+	&_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f);
-+	&_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df);
-+	&_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea);
-+	&_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34);
-+	&_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b);
-+	&_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d);
-+	&_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413);
-+	&_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1);
-+	&_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6);
-+	&_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972);
-+	&_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85);
-+	&_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed);
-+	&_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511);
-+	&_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe);
-+	&_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b);
-+	&_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05);
-+	&_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1);
-+	&_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142);
-+	&_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf);
-+	&_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3);
-+	&_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e);
-+	&_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a);
-+	&_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6);
-+	&_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3);
-+	&_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b);
-+	&_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428);
-+	&_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad);
-+	&_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14);
-+	&_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8);
-+	&_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4);
-+	&_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2);
-+	&_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda);
-+	&_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949);
-+	&_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf);
-+	&_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810);
-+	&_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c);
-+	&_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697);
-+	&_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e);
-+	&_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f);
-+	&_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc);
-+	&_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c);
-+	&_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969);
-+	&_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27);
-+	&_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122);
-+	&_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433);
-+	&_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9);
-+	&_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5);
-+	&_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a);
-+	&_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
-+	&_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
-+	&_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
-+
-+#Te4	# four copies of Te4 to choose from to avoid L1 aliasing
-+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-+
-+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-+
-+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-+
-+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-+#rcon:
-+	&data_word(0x00000001, 0x00000002, 0x00000004, 0x00000008);
-+	&data_word(0x00000010, 0x00000020, 0x00000040, 0x00000080);
-+	&data_word(0x0000001b, 0x00000036, 0x00000000, 0x00000000);
-+	&data_word(0x00000000, 0x00000000, 0x00000000, 0x00000000);
-+&function_end_B("_x86_AES_encrypt");
-+
-+# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
-+&function_begin("AES_encrypt");
-+	&mov	($acc,&wparam(0));		# load inp
-+	&mov	($key,&wparam(2));		# load key
-+
-+	&mov	($s0,"esp");
-+	&sub	("esp",36);
-+	&and	("esp",-64);			# align to cache-line
-+
-+	# place stack frame just "above" the key schedule
-+	&lea	($s1,&DWP(-64-63,$key));
-+	&sub	($s1,"esp");
-+	&neg	($s1);
-+	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
-+	&sub	("esp",$s1);
-+	&add	("esp",4);	# 4 is reserved for caller's return address
-+	&mov	($_esp,$s0);			# save stack pointer
-+
-+	&call   (&label("pic_point"));          # make it PIC!
-+	&set_label("pic_point");
-+	&blindpop($tbl);
-+	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if (!$x86only);
-+	&lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
-+
-+	# pick Te4 copy which can't "overlap" with stack frame or key schedule
-+	&lea	($s1,&DWP(768-4,"esp"));
-+	&sub	($s1,$tbl);
-+	&and	($s1,0x300);
-+	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
-+
-+					if (!$x86only) {
-+	&bt	(&DWP(0,$s0),25);	# check for SSE bit
-+	&jnc	(&label("x86"));
-+
-+	&movq	("mm0",&QWP(0,$acc));
-+	&movq	("mm4",&QWP(8,$acc));
-+	&call	("_sse_AES_encrypt_compact");
-+	&mov	("esp",$_esp);			# restore stack pointer
-+	&mov	($acc,&wparam(1));		# load out
-+	&movq	(&QWP(0,$acc),"mm0");		# write output data
-+	&movq	(&QWP(8,$acc),"mm4");
-+	&emms	();
-+	&function_end_A();
-+					}
-+	&set_label("x86",16);
-+	&mov	($_tbl,$tbl);
-+	&mov	($s0,&DWP(0,$acc));		# load input data
-+	&mov	($s1,&DWP(4,$acc));
-+	&mov	($s2,&DWP(8,$acc));
-+	&mov	($s3,&DWP(12,$acc));
-+	&call	("_x86_AES_encrypt_compact");
-+	&mov	("esp",$_esp);			# restore stack pointer
-+	&mov	($acc,&wparam(1));		# load out
-+	&mov	(&DWP(0,$acc),$s0);		# write output data
-+	&mov	(&DWP(4,$acc),$s1);
-+	&mov	(&DWP(8,$acc),$s2);
-+	&mov	(&DWP(12,$acc),$s3);
-+&function_end("AES_encrypt");
-+
-+#--------------------------------------------------------------------#
-+
-+######################################################################
-+# "Compact" block function
-+######################################################################
-+
-+sub deccompact()
-+{ my $Fn = \&mov;
-+  while ($#_>5) { pop(@_); $Fn=sub{}; }
-+  my ($i,$td,@s)=@_;
-+  my $tmp = $key;
-+  my $out = $i==3?$s[0]:$acc;
-+
-+	# $Fn is used in first compact round and its purpose is to
-+	# void restoration of some values from stack, so that after
-+	# 4xdeccompact with extra argument $key, $s0 and $s1 values
-+	# are left there...
-+	if($i==3)   {	&$Fn	($key,$__key);			}
-+	else        {	&mov	($out,$s[0]);			}
-+			&and	($out,0xFF);
-+			&movz	($out,&BP(-128,$td,$out,1));
-+
-+	if ($i==3)  {	$tmp=$s[1];				}
-+			&movz	($tmp,&HB($s[1]));
-+			&movz	($tmp,&BP(-128,$td,$tmp,1));
-+			&shl	($tmp,8);
-+			&xor	($out,$tmp);
-+
-+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$acc);		}
-+	else        {	mov	($tmp,$s[2]);			}
-+			&shr	($tmp,16);
-+			&and	($tmp,0xFF);
-+			&movz	($tmp,&BP(-128,$td,$tmp,1));
-+			&shl	($tmp,16);
-+			&xor	($out,$tmp);
-+
-+	if ($i==3)  {	$tmp=$s[3]; &$Fn ($s[2],$__s1);		}
-+	else        {	&mov	($tmp,$s[3]);			}
-+			&shr	($tmp,24);
-+			&movz	($tmp,&BP(-128,$td,$tmp,1));
-+			&shl	($tmp,24);
-+			&xor	($out,$tmp);
-+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
-+	if ($i==3)  {	&$Fn	($s[3],$__s0);			}
-+}
-+
-+# must be called with 2,3,0,1 as argument sequence!!!
-+sub dectransform()
-+{ my @s = ($s0,$s1,$s2,$s3);
-+  my $i = shift;
-+  my $tmp = $key;
-+  my $tp2 = @s[($i+2)%4]; $tp2 = @s[2] if ($i==1);
-+  my $tp4 = @s[($i+3)%4]; $tp4 = @s[3] if ($i==1);
-+  my $tp8 = $tbl;
-+
-+	&mov	($tmp,0x80808080);
-+	&and	($tmp,$s[$i]);
-+	&mov	($acc,$tmp);
-+	&shr	($tmp,7);
-+	&lea	($tp2,&DWP(0,$s[$i],$s[$i]));
-+	&sub	($acc,$tmp);
-+	&and	($tp2,0xfefefefe);
-+	&and	($acc,0x1b1b1b1b);
-+	&xor	($tp2,$acc);
-+	&mov	($tmp,0x80808080);
-+
-+	&and	($tmp,$tp2);
-+	&mov	($acc,$tmp);
-+	&shr	($tmp,7);
-+	&lea	($tp4,&DWP(0,$tp2,$tp2));
-+	&sub	($acc,$tmp);
-+	&and	($tp4,0xfefefefe);
-+	&and	($acc,0x1b1b1b1b);
-+	 &xor	($tp2,$s[$i]);	# tp2^tp1
-+	&xor	($tp4,$acc);
-+	&mov	($tmp,0x80808080);
-+
-+	&and	($tmp,$tp4);
-+	&mov	($acc,$tmp);
-+	&shr	($tmp,7);
-+	&lea	($tp8,&DWP(0,$tp4,$tp4));
-+	&sub	($acc,$tmp);
-+	&and	($tp8,0xfefefefe);
-+	&and	($acc,0x1b1b1b1b);
-+	 &xor	($tp4,$s[$i]);	# tp4^tp1
-+	 &rotl	($s[$i],8);	# = ROTATE(tp1,8)
-+	&xor	($tp8,$acc);
-+
-+	&xor	($s[$i],$tp2);
-+	&xor	($tp2,$tp8);
-+	&xor	($s[$i],$tp4);
-+	&xor	($tp4,$tp8);
-+	&rotl	($tp2,24);
-+	&xor	($s[$i],$tp8);	# ^= tp8^(tp4^tp1)^(tp2^tp1)
-+	&rotl	($tp4,16);
-+	&xor	($s[$i],$tp2);	# ^= ROTATE(tp8^tp2^tp1,24)
-+	&rotl	($tp8,8);
-+	&xor	($s[$i],$tp4);	# ^= ROTATE(tp8^tp4^tp1,16)
-+	 &mov	($s[0],$__s0)			if($i==2); #prefetch $s0
-+	 &mov	($s[1],$__s1)			if($i==3); #prefetch $s1
-+	 &mov	($s[2],$__s2)			if($i==1);
-+	&xor	($s[$i],$tp8);	# ^= ROTATE(tp8,8)
-+
-+	&mov	($s[3],$__s3)			if($i==1);
-+	&mov	(&DWP(4+4*$i,"esp"),$s[$i])	if($i>=2);
-+}
-+
-+&function_begin_B("_x86_AES_decrypt_compact");
-+	# note that caller is expected to allocate stack frame for me!
-+	&mov	($__key,$key);			# save key
-+
-+	&xor	($s0,&DWP(0,$key));		# xor with key
-+	&xor	($s1,&DWP(4,$key));
-+	&xor	($s2,&DWP(8,$key));
-+	&xor	($s3,&DWP(12,$key));
-+
-+	&mov	($acc,&DWP(240,$key));		# load key->rounds
-+
-+	&lea	($acc,&DWP(-2,$acc,$acc));
-+	&lea	($acc,&DWP(0,$key,$acc,8));
-+	&mov	($__end,$acc);			# end of key schedule
-+
-+	# prefetch Td4
-+	&mov	($key,&DWP(0-128,$tbl));
-+	&mov	($acc,&DWP(32-128,$tbl));
-+	&mov	($key,&DWP(64-128,$tbl));
-+	&mov	($acc,&DWP(96-128,$tbl));
-+	&mov	($key,&DWP(128-128,$tbl));
-+	&mov	($acc,&DWP(160-128,$tbl));
-+	&mov	($key,&DWP(192-128,$tbl));
-+	&mov	($acc,&DWP(224-128,$tbl));
-+
-+	&set_label("loop",16);
-+
-+		&deccompact(0,$tbl,$s0,$s3,$s2,$s1,1);
-+		&deccompact(1,$tbl,$s1,$s0,$s3,$s2,1);
-+		&deccompact(2,$tbl,$s2,$s1,$s0,$s3,1);
-+		&deccompact(3,$tbl,$s3,$s2,$s1,$s0,1);
-+		&dectransform(2);
-+		&dectransform(3);
-+		&dectransform(0);
-+		&dectransform(1);
-+		&mov 	($key,$__key);
-+		&mov	($tbl,$__tbl);
-+		&add	($key,16);		# advance rd_key
-+		&xor	($s0,&DWP(0,$key));
-+		&xor	($s1,&DWP(4,$key));
-+		&xor	($s2,&DWP(8,$key));
-+		&xor	($s3,&DWP(12,$key));
-+
-+	&cmp	($key,$__end);
-+	&mov	($__key,$key);
-+	&jb	(&label("loop"));
-+
-+	&deccompact(0,$tbl,$s0,$s3,$s2,$s1);
-+	&deccompact(1,$tbl,$s1,$s0,$s3,$s2);
-+	&deccompact(2,$tbl,$s2,$s1,$s0,$s3);
-+	&deccompact(3,$tbl,$s3,$s2,$s1,$s0);
-+
-+	&xor	($s0,&DWP(16,$key));
-+	&xor	($s1,&DWP(20,$key));
-+	&xor	($s2,&DWP(24,$key));
-+	&xor	($s3,&DWP(28,$key));
-+
-+	&ret	();
-+&function_end_B("_x86_AES_decrypt_compact");
-+
-+######################################################################
-+# "Compact" SSE block function.
-+######################################################################
-+
-+sub sse_deccompact()
-+{
-+	&pshufw	("mm1","mm0",0x0c);		#  7, 6, 1, 0
-+	&pshufw	("mm5","mm4",0x09);		# 13,12,11,10
-+	&movd	("eax","mm1");			#  7, 6, 1, 0
-+	&movd	("ebx","mm5");			# 13,12,11,10
-+	&mov	($__key,$key);
-+
-+	&movz	($acc,&LB("eax"));		#  0
-+	&movz	("edx",&HB("eax"));		#  1
-+	&pshufw	("mm2","mm0",0x06);		#  3, 2, 5, 4
-+	&movz	("ecx",&BP(-128,$tbl,$acc,1));	#  0
-+	&movz	($key,&LB("ebx"));		# 10
-+	&movz	("edx",&BP(-128,$tbl,"edx",1));	#  1
-+	&shr	("eax",16);			#  7, 6
-+	&shl	("edx",8);			#  1
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	# 10
-+	&movz	($key,&HB("ebx"));		# 11
-+	&shl	($acc,16);			# 10
-+	&pshufw	("mm6","mm4",0x03);		# 9, 8,15,14
-+	&or	("ecx",$acc);			# 10
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	# 11
-+	&movz	($key,&HB("eax"));		#  7
-+	&shl	($acc,24);			# 11
-+	&shr	("ebx",16);			# 13,12
-+	&or	("edx",$acc);			# 11
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  7
-+	&movz	($key,&HB("ebx"));		# 13
-+	&shl	($acc,24);			#  7
-+	&or	("ecx",$acc);			#  7
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	# 13
-+	&movz	($key,&LB("eax"));		#  6
-+	&shl	($acc,8);			# 13
-+	&movd	("eax","mm2");			#  3, 2, 5, 4
-+	&or	("ecx",$acc);			# 13
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  6
-+	&movz	($key,&LB("ebx"));		# 12
-+	&shl	($acc,16);			#  6
-+	&movd	("ebx","mm6");			#  9, 8,15,14
-+	&movd	("mm0","ecx");			# t[0] collected
-+	&movz	("ecx",&BP(-128,$tbl,$key,1));	# 12
-+	&movz	($key,&LB("eax"));		#  4
-+	&or	("ecx",$acc);			# 12
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  4
-+	&movz	($key,&LB("ebx"));		# 14
-+	&or	("edx",$acc);			#  4
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	# 14
-+	&movz	($key,&HB("eax"));		#  5
-+	&shl	($acc,16);			# 14
-+	&shr	("eax",16);			#  3, 2
-+	&or	("edx",$acc);			# 14
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  5
-+	&movz	($key,&HB("ebx"));		# 15
-+	&shr	("ebx",16);			#  9, 8
-+	&shl	($acc,8);			#  5
-+	&movd	("mm1","edx");			# t[1] collected
-+	&movz	("edx",&BP(-128,$tbl,$key,1));	# 15
-+	&movz	($key,&HB("ebx"));		#  9
-+	&shl	("edx",24);			# 15
-+	&and	("ebx",0xff);			#  8
-+	&or	("edx",$acc);			# 15
-+
-+	&punpckldq	("mm0","mm1");		# t[0,1] collected
-+
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  9
-+	&movz	($key,&LB("eax"));		#  2
-+	&shl	($acc,8);			#  9
-+	&movz	("eax",&HB("eax"));		#  3
-+	&movz	("ebx",&BP(-128,$tbl,"ebx",1));	#  8
-+	&or	("ecx",$acc);			#  9
-+	&movz	($acc,&BP(-128,$tbl,$key,1));	#  2
-+	&or	("edx","ebx");			#  8
-+	&shl	($acc,16);			#  2
-+	&movz	("eax",&BP(-128,$tbl,"eax",1));	#  3
-+	&or	("edx",$acc);			#  2
-+	&shl	("eax",24);			#  3
-+	&or	("ecx","eax");			#  3
-+	&mov	($key,$__key);
-+	&movd	("mm4","edx");			# t[2] collected
-+	&movd	("mm5","ecx");			# t[3] collected
-+
-+	&punpckldq	("mm4","mm5");		# t[2,3] collected
-+}
-+
-+					if (!$x86only) {
-+&function_begin_B("_sse_AES_decrypt_compact");
-+	&pxor	("mm0",&QWP(0,$key));	#  7, 6, 5, 4, 3, 2, 1, 0
-+	&pxor	("mm4",&QWP(8,$key));	# 15,14,13,12,11,10, 9, 8
-+
-+	# note that caller is expected to allocate stack frame for me!
-+	&mov	($acc,&DWP(240,$key));		# load key->rounds
-+	&lea	($acc,&DWP(-2,$acc,$acc));
-+	&lea	($acc,&DWP(0,$key,$acc,8));
-+	&mov	($__end,$acc);			# end of key schedule
-+
-+	&mov	($s0,0x1b1b1b1b);		# magic constant
-+	&mov	(&DWP(8,"esp"),$s0);
-+	&mov	(&DWP(12,"esp"),$s0);
-+
-+	# prefetch Td4
-+	&mov	($s0,&DWP(0-128,$tbl));
-+	&mov	($s1,&DWP(32-128,$tbl));
-+	&mov	($s2,&DWP(64-128,$tbl));
-+	&mov	($s3,&DWP(96-128,$tbl));
-+	&mov	($s0,&DWP(128-128,$tbl));
-+	&mov	($s1,&DWP(160-128,$tbl));
-+	&mov	($s2,&DWP(192-128,$tbl));
-+	&mov	($s3,&DWP(224-128,$tbl));
-+
-+	&set_label("loop",16);
-+		&sse_deccompact();
-+		&add	($key,16);
-+		&cmp	($key,$__end);
-+		&ja	(&label("out"));
-+
-+		# ROTATE(x^y,N) == ROTATE(x,N)^ROTATE(y,N)
-+		&movq	("mm3","mm0");		&movq	("mm7","mm4");
-+		&movq	("mm2","mm0",1);	&movq	("mm6","mm4",1);
-+		&movq	("mm1","mm0");		&movq	("mm5","mm4");
-+		&pshufw	("mm0","mm0",0xb1);	&pshufw	("mm4","mm4",0xb1);# = ROTATE(tp0,16)
-+		&pslld	("mm2",8);		&pslld	("mm6",8);
-+		&psrld	("mm3",8);		&psrld	("mm7",8);
-+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp0<<8
-+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp0>>8
-+		&pslld	("mm2",16);		&pslld	("mm6",16);
-+		&psrld	("mm3",16);		&psrld	("mm7",16);
-+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp0<<24
-+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp0>>24
-+
-+		&movq	("mm3",&QWP(8,"esp"));
-+		&pxor	("mm2","mm2");		&pxor	("mm6","mm6");
-+		&pcmpgtb("mm2","mm1");		&pcmpgtb("mm6","mm5");
-+		&pand	("mm2","mm3");		&pand	("mm6","mm3");
-+		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
-+		&pxor	("mm1","mm2");		&pxor	("mm5","mm6");	# tp2
-+		&movq	("mm3","mm1");		&movq	("mm7","mm5");
-+		&movq	("mm2","mm1");		&movq	("mm6","mm5");
-+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp2
-+		&pslld	("mm3",24);		&pslld	("mm7",24);
-+		&psrld	("mm2",8);		&psrld	("mm6",8);
-+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp2<<24
-+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= tp2>>8
-+
-+		&movq	("mm2",&QWP(8,"esp"));
-+		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
-+		&pcmpgtb("mm3","mm1");		&pcmpgtb("mm7","mm5");
-+		&pand	("mm3","mm2");		&pand	("mm7","mm2");
-+		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
-+		&pxor	("mm1","mm3");		&pxor	("mm5","mm7");	# tp4
-+		&pshufw	("mm3","mm1",0xb1);	&pshufw	("mm7","mm5",0xb1);
-+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp4
-+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= ROTATE(tp4,16)	
-+
-+		&pxor	("mm3","mm3");		&pxor	("mm7","mm7");
-+		&pcmpgtb("mm3","mm1");		&pcmpgtb("mm7","mm5");
-+		&pand	("mm3","mm2");		&pand	("mm7","mm2");
-+		&paddb	("mm1","mm1");		&paddb	("mm5","mm5");
-+		&pxor	("mm1","mm3");		&pxor	("mm5","mm7");	# tp8
-+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8
-+		&movq	("mm3","mm1");		&movq	("mm7","mm5");
-+		&pshufw	("mm2","mm1",0xb1);	&pshufw	("mm6","mm5",0xb1);
-+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");	# ^= ROTATE(tp8,16)
-+		&pslld	("mm1",8);		&pslld	("mm5",8);
-+		&psrld	("mm3",8);		&psrld	("mm7",8);
-+		&movq	("mm2",&QWP(0,$key));	&movq	("mm6",&QWP(8,$key));
-+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8<<8
-+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp8>>8
-+		&mov	($s0,&DWP(0-128,$tbl));
-+		&pslld	("mm1",16);		&pslld	("mm5",16);
-+		&mov	($s1,&DWP(64-128,$tbl));
-+		&psrld	("mm3",16);		&psrld	("mm7",16);
-+		&mov	($s2,&DWP(128-128,$tbl));
-+		&pxor	("mm0","mm1");		&pxor	("mm4","mm5");	# ^= tp8<<24
-+		&mov	($s3,&DWP(192-128,$tbl));
-+		&pxor	("mm0","mm3");		&pxor	("mm4","mm7");	# ^= tp8>>24
-+
-+		&pxor	("mm0","mm2");		&pxor	("mm4","mm6");
-+	&jmp	(&label("loop"));
-+
-+	&set_label("out",16);
-+	&pxor	("mm0",&QWP(0,$key));
-+	&pxor	("mm4",&QWP(8,$key));
-+
-+	&ret	();
-+&function_end_B("_sse_AES_decrypt_compact");
-+					}
-+
-+######################################################################
-+# Vanilla block function.
-+######################################################################
-+
-+sub decstep()
-+{ my ($i,$td,@s) = @_;
-+  my $tmp = $key;
-+  my $out = $i==3?$s[0]:$acc;
-+
-+	# no instructions are reordered, as performance appears
-+	# optimal... or rather that all attempts to reorder didn't
-+	# result in better performance [which by the way is not a
-+	# bit lower than ecryption].
-+	if($i==3)   {	&mov	($key,$__key);			}
-+	else        {	&mov	($out,$s[0]);			}
-+			&and	($out,0xFF);
-+			&mov	($out,&DWP(0,$td,$out,8));
-+
-+	if ($i==3)  {	$tmp=$s[1];				}
-+			&movz	($tmp,&HB($s[1]));
-+			&xor	($out,&DWP(3,$td,$tmp,8));
-+
-+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$acc);		}
-+	else        {	&mov	($tmp,$s[2]);			}
-+			&shr	($tmp,16);
-+			&and	($tmp,0xFF);
-+			&xor	($out,&DWP(2,$td,$tmp,8));
-+
-+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}
-+	else        {	&mov	($tmp,$s[3]);			}
-+			&shr	($tmp,24);
-+			&xor	($out,&DWP(1,$td,$tmp,8));
-+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
-+	if ($i==3)  {	&mov	($s[3],$__s0);			}
-+			&comment();
-+}
-+
-+sub declast()
-+{ my ($i,$td,@s)=@_;
-+  my $tmp = $key;
-+  my $out = $i==3?$s[0]:$acc;
-+
-+	if($i==0)   {	&lea	($td,&DWP(2048+128,$td));
-+			&mov	($tmp,&DWP(0-128,$td));
-+			&mov	($acc,&DWP(32-128,$td));
-+			&mov	($tmp,&DWP(64-128,$td));
-+			&mov	($acc,&DWP(96-128,$td));
-+			&mov	($tmp,&DWP(128-128,$td));
-+			&mov	($acc,&DWP(160-128,$td));
-+			&mov	($tmp,&DWP(192-128,$td));
-+			&mov	($acc,&DWP(224-128,$td));
-+			&lea	($td,&DWP(-128,$td));		}
-+	if($i==3)   {	&mov	($key,$__key);			}
-+	else        {	&mov	($out,$s[0]);			}
-+			&and	($out,0xFF);
-+			&movz	($out,&BP(0,$td,$out,1));
-+
-+	if ($i==3)  {	$tmp=$s[1];				}
-+			&movz	($tmp,&HB($s[1]));
-+			&movz	($tmp,&BP(0,$td,$tmp,1));
-+			&shl	($tmp,8);
-+			&xor	($out,$tmp);
-+
-+	if ($i==3)  {	$tmp=$s[2]; &mov ($s[1],$acc);		}
-+	else        {	mov	($tmp,$s[2]);			}
-+			&shr	($tmp,16);
-+			&and	($tmp,0xFF);
-+			&movz	($tmp,&BP(0,$td,$tmp,1));
-+			&shl	($tmp,16);
-+			&xor	($out,$tmp);
-+
-+	if ($i==3)  {	$tmp=$s[3]; &mov ($s[2],$__s1);		}
-+	else        {	&mov	($tmp,$s[3]);			}
-+			&shr	($tmp,24);
-+			&movz	($tmp,&BP(0,$td,$tmp,1));
-+			&shl	($tmp,24);
-+			&xor	($out,$tmp);
-+	if ($i<2)   {	&mov	(&DWP(4+4*$i,"esp"),$out);	}
-+	if ($i==3)  {	&mov	($s[3],$__s0);
-+			&lea	($td,&DWP(-2048,$td));		}
-+}
-+
-+&function_begin_B("_x86_AES_decrypt");
-+	# note that caller is expected to allocate stack frame for me!
-+	&mov	($__key,$key);			# save key
-+
-+	&xor	($s0,&DWP(0,$key));		# xor with key
-+	&xor	($s1,&DWP(4,$key));
-+	&xor	($s2,&DWP(8,$key));
-+	&xor	($s3,&DWP(12,$key));
-+
-+	&mov	($acc,&DWP(240,$key));		# load key->rounds
-+
-+	if ($small_footprint) {
-+	    &lea	($acc,&DWP(-2,$acc,$acc));
-+	    &lea	($acc,&DWP(0,$key,$acc,8));
-+	    &mov	($__end,$acc);		# end of key schedule
-+	    &set_label("loop",16);
-+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
-+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
-+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
-+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
-+		&add	($key,16);		# advance rd_key
-+		&xor	($s0,&DWP(0,$key));
-+		&xor	($s1,&DWP(4,$key));
-+		&xor	($s2,&DWP(8,$key));
-+		&xor	($s3,&DWP(12,$key));
-+	    &cmp	($key,$__end);
-+	    &mov	($__key,$key);
-+	    &jb		(&label("loop"));
-+	}
-+	else {
-+	    &cmp	($acc,10);
-+	    &jle	(&label("10rounds"));
-+	    &cmp	($acc,12);
-+	    &jle	(&label("12rounds"));
-+
-+	&set_label("14rounds",4);
-+	    for ($i=1;$i<3;$i++) {
-+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
-+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
-+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
-+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
-+		&xor	($s0,&DWP(16*$i+0,$key));
-+		&xor	($s1,&DWP(16*$i+4,$key));
-+		&xor	($s2,&DWP(16*$i+8,$key));
-+		&xor	($s3,&DWP(16*$i+12,$key));
-+	    }
-+	    &add	($key,32);
-+	    &mov	($__key,$key);		# advance rd_key
-+	&set_label("12rounds",4);
-+	    for ($i=1;$i<3;$i++) {
-+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
-+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
-+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
-+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
-+		&xor	($s0,&DWP(16*$i+0,$key));
-+		&xor	($s1,&DWP(16*$i+4,$key));
-+		&xor	($s2,&DWP(16*$i+8,$key));
-+		&xor	($s3,&DWP(16*$i+12,$key));
-+	    }
-+	    &add	($key,32);
-+	    &mov	($__key,$key);		# advance rd_key
-+	&set_label("10rounds",4);
-+	    for ($i=1;$i<10;$i++) {
-+		&decstep(0,$tbl,$s0,$s3,$s2,$s1);
-+		&decstep(1,$tbl,$s1,$s0,$s3,$s2);
-+		&decstep(2,$tbl,$s2,$s1,$s0,$s3);
-+		&decstep(3,$tbl,$s3,$s2,$s1,$s0);
-+		&xor	($s0,&DWP(16*$i+0,$key));
-+		&xor	($s1,&DWP(16*$i+4,$key));
-+		&xor	($s2,&DWP(16*$i+8,$key));
-+		&xor	($s3,&DWP(16*$i+12,$key));
-+	    }
-+	}
-+
-+	&declast(0,$tbl,$s0,$s3,$s2,$s1);
-+	&declast(1,$tbl,$s1,$s0,$s3,$s2);
-+	&declast(2,$tbl,$s2,$s1,$s0,$s3);
-+	&declast(3,$tbl,$s3,$s2,$s1,$s0);
-+
-+	&add	($key,$small_footprint?16:160);
-+	&xor	($s0,&DWP(0,$key));
-+	&xor	($s1,&DWP(4,$key));
-+	&xor	($s2,&DWP(8,$key));
-+	&xor	($s3,&DWP(12,$key));
-+
-+	&ret	();
-+
-+&set_label("AES_Td",64);	# Yes! I keep it in the code segment!
-+	&_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a);
-+	&_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b);
-+	&_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5);
-+	&_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5);
-+	&_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d);
-+	&_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b);
-+	&_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295);
-+	&_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e);
-+	&_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927);
-+	&_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d);
-+	&_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362);
-+	&_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9);
-+	&_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52);
-+	&_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566);
-+	&_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3);
-+	&_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed);
-+	&_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e);
-+	&_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4);
-+	&_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4);
-+	&_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd);
-+	&_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d);
-+	&_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060);
-+	&_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967);
-+	&_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879);
-+	&_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000);
-+	&_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c);
-+	&_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36);
-+	&_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624);
-+	&_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b);
-+	&_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c);
-+	&_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12);
-+	&_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14);
-+	&_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3);
-+	&_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b);
-+	&_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8);
-+	&_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684);
-+	&_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7);
-+	&_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177);
-+	&_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947);
-+	&_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322);
-+	&_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498);
-+	&_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f);
-+	&_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54);
-+	&_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382);
-+	&_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf);
-+	&_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb);
-+	&_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83);
-+	&_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef);
-+	&_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029);
-+	&_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235);
-+	&_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733);
-+	&_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117);
-+	&_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4);
-+	&_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546);
-+	&_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb);
-+	&_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d);
-+	&_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb);
-+	&_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a);
-+	&_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773);
-+	&_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478);
-+	&_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2);
-+	&_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
-+	&_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
-+	&_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
-+
-+#Td4:	# four copies of Td4 to choose from to avoid L1 aliasing
-+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-+
-+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-+
-+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-+
-+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-+&function_end_B("_x86_AES_decrypt");
-+
-+# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
-+&function_begin("AES_decrypt");
-+	&mov	($acc,&wparam(0));		# load inp
-+	&mov	($key,&wparam(2));		# load key
-+
-+	&mov	($s0,"esp");
-+	&sub	("esp",36);
-+	&and	("esp",-64);			# align to cache-line
-+
-+	# place stack frame just "above" the key schedule
-+	&lea	($s1,&DWP(-64-63,$key));
-+	&sub	($s1,"esp");
-+	&neg	($s1);
-+	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
-+	&sub	("esp",$s1);
-+	&add	("esp",4);	# 4 is reserved for caller's return address
-+	&mov	($_esp,$s0);	# save stack pointer
-+
-+	&call   (&label("pic_point"));          # make it PIC!
-+	&set_label("pic_point");
-+	&blindpop($tbl);
-+	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
-+	&lea    ($tbl,&DWP(&label("AES_Td")."-".&label("pic_point"),$tbl));
-+
-+	# pick Td4 copy which can't "overlap" with stack frame or key schedule
-+	&lea	($s1,&DWP(768-4,"esp"));
-+	&sub	($s1,$tbl);
-+	&and	($s1,0x300);
-+	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
-+
-+					if (!$x86only) {
-+	&bt	(&DWP(0,$s0),25);	# check for SSE bit
-+	&jnc	(&label("x86"));
-+
-+	&movq	("mm0",&QWP(0,$acc));
-+	&movq	("mm4",&QWP(8,$acc));
-+	&call	("_sse_AES_decrypt_compact");
-+	&mov	("esp",$_esp);			# restore stack pointer
-+	&mov	($acc,&wparam(1));		# load out
-+	&movq	(&QWP(0,$acc),"mm0");		# write output data
-+	&movq	(&QWP(8,$acc),"mm4");
-+	&emms	();
-+	&function_end_A();
-+					}
-+	&set_label("x86",16);
-+	&mov	($_tbl,$tbl);
-+	&mov	($s0,&DWP(0,$acc));		# load input data
-+	&mov	($s1,&DWP(4,$acc));
-+	&mov	($s2,&DWP(8,$acc));
-+	&mov	($s3,&DWP(12,$acc));
-+	&call	("_x86_AES_decrypt_compact");
-+	&mov	("esp",$_esp);			# restore stack pointer
-+	&mov	($acc,&wparam(1));		# load out
-+	&mov	(&DWP(0,$acc),$s0);		# write output data
-+	&mov	(&DWP(4,$acc),$s1);
-+	&mov	(&DWP(8,$acc),$s2);
-+	&mov	(&DWP(12,$acc),$s3);
-+&function_end("AES_decrypt");
-+
-+# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
-+#			size_t length, const AES_KEY *key,
-+#			unsigned char *ivp,const int enc);
-+{
-+# stack frame layout
-+#             -4(%esp)		# return address	 0(%esp)
-+#              0(%esp)		# s0 backing store	 4(%esp)	
-+#              4(%esp)		# s1 backing store	 8(%esp)
-+#              8(%esp)		# s2 backing store	12(%esp)
-+#             12(%esp)		# s3 backing store	16(%esp)
-+#             16(%esp)		# key backup		20(%esp)
-+#             20(%esp)		# end of key schedule	24(%esp)
-+#             24(%esp)		# %ebp backup		28(%esp)
-+#             28(%esp)		# %esp backup
-+my $_inp=&DWP(32,"esp");	# copy of wparam(0)
-+my $_out=&DWP(36,"esp");	# copy of wparam(1)
-+my $_len=&DWP(40,"esp");	# copy of wparam(2)
-+my $_key=&DWP(44,"esp");	# copy of wparam(3)
-+my $_ivp=&DWP(48,"esp");	# copy of wparam(4)
-+my $_tmp=&DWP(52,"esp");	# volatile variable
-+#
-+my $ivec=&DWP(60,"esp");	# ivec[16]
-+my $aes_key=&DWP(76,"esp");	# copy of aes_key
-+my $mark=&DWP(76+240,"esp");	# copy of aes_key->rounds
-+
-+&function_begin("AES_cbc_encrypt");
-+	&mov	($s2 eq "ecx"? $s2 : "",&wparam(2));	# load len
-+	&cmp	($s2,0);
-+	&je	(&label("drop_out"));
-+
-+	&call   (&label("pic_point"));		# make it PIC!
-+	&set_label("pic_point");
-+	&blindpop($tbl);
-+	&picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only);
-+
-+	&cmp	(&wparam(5),0);
-+	&lea    ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
-+	&jne	(&label("picked_te"));
-+	&lea	($tbl,&DWP(&label("AES_Td")."-".&label("AES_Te"),$tbl));
-+	&set_label("picked_te");
-+
-+	# one can argue if this is required
-+	&pushf	();
-+	&cld	();
-+
-+	&cmp	($s2,$speed_limit);
-+	&jb	(&label("slow_way"));
-+	&test	($s2,15);
-+	&jnz	(&label("slow_way"));
-+					if (!$x86only) {
-+	&bt	(&DWP(0,$s0),28);	# check for hyper-threading bit
-+	&jc	(&label("slow_way"));
-+					}
-+	# pre-allocate aligned stack frame...
-+	&lea	($acc,&DWP(-80-244,"esp"));
-+	&and	($acc,-64);
-+
-+	# ... and make sure it doesn't alias with $tbl modulo 4096
-+	&mov	($s0,$tbl);
-+	&lea	($s1,&DWP(2048+256,$tbl));
-+	&mov	($s3,$acc);
-+	&and	($s0,0xfff);		# s = %ebp&0xfff
-+	&and	($s1,0xfff);		# e = (%ebp+2048+256)&0xfff
-+	&and	($s3,0xfff);		# p = %esp&0xfff
-+
-+	&cmp	($s3,$s1);		# if (p>=e) %esp =- (p-e);
-+	&jb	(&label("tbl_break_out"));
-+	&sub	($s3,$s1);
-+	&sub	($acc,$s3);
-+	&jmp	(&label("tbl_ok"));
-+	&set_label("tbl_break_out",4);	# else %esp -= (p-s)&0xfff + framesz;
-+	&sub	($s3,$s0);
-+	&and	($s3,0xfff);
-+	&add	($s3,384);
-+	&sub	($acc,$s3);
-+	&set_label("tbl_ok",4);
-+
-+	&lea	($s3,&wparam(0));	# obtain pointer to parameter block
-+	&exch	("esp",$acc);		# allocate stack frame
-+	&add	("esp",4);		# reserve for return address!
-+	&mov	($_tbl,$tbl);		# save %ebp
-+	&mov	($_esp,$acc);		# save %esp
-+
-+	&mov	($s0,&DWP(0,$s3));	# load inp
-+	&mov	($s1,&DWP(4,$s3));	# load out
-+	#&mov	($s2,&DWP(8,$s3));	# load len
-+	&mov	($key,&DWP(12,$s3));	# load key
-+	&mov	($acc,&DWP(16,$s3));	# load ivp
-+	&mov	($s3,&DWP(20,$s3));	# load enc flag
-+
-+	&mov	($_inp,$s0);		# save copy of inp
-+	&mov	($_out,$s1);		# save copy of out
-+	&mov	($_len,$s2);		# save copy of len
-+	&mov	($_key,$key);		# save copy of key
-+	&mov	($_ivp,$acc);		# save copy of ivp
-+
-+	&mov	($mark,0);		# copy of aes_key->rounds = 0;
-+	# do we copy key schedule to stack?
-+	&mov	($s1 eq "ebx" ? $s1 : "",$key);
-+	&mov	($s2 eq "ecx" ? $s2 : "",244/4);
-+	&sub	($s1,$tbl);
-+	&mov	("esi",$key);
-+	&and	($s1,0xfff);
-+	&lea	("edi",$aes_key);
-+	&cmp	($s1,2048+256);
-+	&jb	(&label("do_copy"));
-+	&cmp	($s1,4096-244);
-+	&jb	(&label("skip_copy"));
-+	&set_label("do_copy",4);
-+		&mov	($_key,"edi");
-+		&data_word(0xA5F3F689);	# rep movsd
-+	&set_label("skip_copy");
-+
-+	&mov	($key,16);
-+	&set_label("prefetch_tbl",4);
-+		&mov	($s0,&DWP(0,$tbl));
-+		&mov	($s1,&DWP(32,$tbl));
-+		&mov	($s2,&DWP(64,$tbl));
-+		&mov	($acc,&DWP(96,$tbl));
-+		&lea	($tbl,&DWP(128,$tbl));
-+		&sub	($key,1);
-+	&jnz	(&label("prefetch_tbl"));
-+	&sub	($tbl,2048);
-+
-+	&mov	($acc,$_inp);
-+	&mov	($key,$_ivp);
-+
-+	&cmp	($s3,0);
-+	&je	(&label("fast_decrypt"));
-+
-+#----------------------------- ENCRYPT -----------------------------#
-+	&mov	($s0,&DWP(0,$key));		# load iv
-+	&mov	($s1,&DWP(4,$key));
-+
-+	&set_label("fast_enc_loop",16);
-+		&mov	($s2,&DWP(8,$key));
-+		&mov	($s3,&DWP(12,$key));
-+
-+		&xor	($s0,&DWP(0,$acc));	# xor input data
-+		&xor	($s1,&DWP(4,$acc));
-+		&xor	($s2,&DWP(8,$acc));
-+		&xor	($s3,&DWP(12,$acc));
-+
-+		&mov	($key,$_key);		# load key
-+		&call	("_x86_AES_encrypt");
-+
-+		&mov	($acc,$_inp);		# load inp
-+		&mov	($key,$_out);		# load out
-+
-+		&mov	(&DWP(0,$key),$s0);	# save output data
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&mov	(&DWP(12,$key),$s3);
-+
-+		&lea	($acc,&DWP(16,$acc));	# advance inp
-+		&mov	($s2,$_len);		# load len
-+		&mov	($_inp,$acc);		# save inp
-+		&lea	($s3,&DWP(16,$key));	# advance out
-+		&mov	($_out,$s3);		# save out
-+		&sub	($s2,16);		# decrease len
-+		&mov	($_len,$s2);		# save len
-+	&jnz	(&label("fast_enc_loop"));
-+	&mov	($acc,$_ivp);		# load ivp
-+	&mov	($s2,&DWP(8,$key));	# restore last 2 dwords
-+	&mov	($s3,&DWP(12,$key));
-+	&mov	(&DWP(0,$acc),$s0);	# save ivec
-+	&mov	(&DWP(4,$acc),$s1);
-+	&mov	(&DWP(8,$acc),$s2);
-+	&mov	(&DWP(12,$acc),$s3);
-+
-+	&cmp	($mark,0);		# was the key schedule copied?
-+	&mov	("edi",$_key);
-+	&je	(&label("skip_ezero"));
-+	# zero copy of key schedule
-+	&mov	("ecx",240/4);
-+	&xor	("eax","eax");
-+	&align	(4);
-+	&data_word(0xABF3F689);		# rep stosd
-+	&set_label("skip_ezero");
-+	&mov	("esp",$_esp);
-+	&popf	();
-+    &set_label("drop_out");
-+	&function_end_A();
-+	&pushf	();			# kludge, never executed
-+
-+#----------------------------- DECRYPT -----------------------------#
-+&set_label("fast_decrypt",16);
-+
-+	&cmp	($acc,$_out);
-+	&je	(&label("fast_dec_in_place"));	# in-place processing...
-+
-+	&mov	($_tmp,$key);
-+
-+	&align	(4);
-+	&set_label("fast_dec_loop",16);
-+		&mov	($s0,&DWP(0,$acc));	# read input
-+		&mov	($s1,&DWP(4,$acc));
-+		&mov	($s2,&DWP(8,$acc));
-+		&mov	($s3,&DWP(12,$acc));
-+
-+		&mov	($key,$_key);		# load key
-+		&call	("_x86_AES_decrypt");
-+
-+		&mov	($key,$_tmp);		# load ivp
-+		&mov	($acc,$_len);		# load len
-+		&xor	($s0,&DWP(0,$key));	# xor iv
-+		&xor	($s1,&DWP(4,$key));
-+		&xor	($s2,&DWP(8,$key));
-+		&xor	($s3,&DWP(12,$key));
-+
-+		&mov	($key,$_out);		# load out
-+		&mov	($acc,$_inp);		# load inp
-+
-+		&mov	(&DWP(0,$key),$s0);	# write output
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&mov	(&DWP(12,$key),$s3);
-+
-+		&mov	($s2,$_len);		# load len
-+		&mov	($_tmp,$acc);		# save ivp
-+		&lea	($acc,&DWP(16,$acc));	# advance inp
-+		&mov	($_inp,$acc);		# save inp
-+		&lea	($key,&DWP(16,$key));	# advance out
-+		&mov	($_out,$key);		# save out
-+		&sub	($s2,16);		# decrease len
-+		&mov	($_len,$s2);		# save len
-+	&jnz	(&label("fast_dec_loop"));
-+	&mov	($key,$_tmp);		# load temp ivp
-+	&mov	($acc,$_ivp);		# load user ivp
-+	&mov	($s0,&DWP(0,$key));	# load iv
-+	&mov	($s1,&DWP(4,$key));
-+	&mov	($s2,&DWP(8,$key));
-+	&mov	($s3,&DWP(12,$key));
-+	&mov	(&DWP(0,$acc),$s0);	# copy back to user
-+	&mov	(&DWP(4,$acc),$s1);
-+	&mov	(&DWP(8,$acc),$s2);
-+	&mov	(&DWP(12,$acc),$s3);
-+	&jmp	(&label("fast_dec_out"));
-+
-+    &set_label("fast_dec_in_place",16);
-+	&set_label("fast_dec_in_place_loop");
-+		&mov	($s0,&DWP(0,$acc));	# read input
-+		&mov	($s1,&DWP(4,$acc));
-+		&mov	($s2,&DWP(8,$acc));
-+		&mov	($s3,&DWP(12,$acc));
-+
-+		&lea	($key,$ivec);
-+		&mov	(&DWP(0,$key),$s0);	# copy to temp
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&mov	(&DWP(12,$key),$s3);
-+
-+		&mov	($key,$_key);		# load key
-+		&call	("_x86_AES_decrypt");
-+
-+		&mov	($key,$_ivp);		# load ivp
-+		&mov	($acc,$_out);		# load out
-+		&xor	($s0,&DWP(0,$key));	# xor iv
-+		&xor	($s1,&DWP(4,$key));
-+		&xor	($s2,&DWP(8,$key));
-+		&xor	($s3,&DWP(12,$key));
-+
-+		&mov	(&DWP(0,$acc),$s0);	# write output
-+		&mov	(&DWP(4,$acc),$s1);
-+		&mov	(&DWP(8,$acc),$s2);
-+		&mov	(&DWP(12,$acc),$s3);
-+
-+		&lea	($acc,&DWP(16,$acc));	# advance out
-+		&mov	($_out,$acc);		# save out
-+
-+		&lea	($acc,$ivec);
-+		&mov	($s0,&DWP(0,$acc));	# read temp
-+		&mov	($s1,&DWP(4,$acc));
-+		&mov	($s2,&DWP(8,$acc));
-+		&mov	($s3,&DWP(12,$acc));
-+
-+		&mov	(&DWP(0,$key),$s0);	# copy iv
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&mov	(&DWP(12,$key),$s3);
-+
-+		&mov	($acc,$_inp);		# load inp
-+		&mov	($s2,$_len);		# load len
-+		&lea	($acc,&DWP(16,$acc));	# advance inp
-+		&mov	($_inp,$acc);		# save inp
-+		&sub	($s2,16);		# decrease len
-+		&mov	($_len,$s2);		# save len
-+	&jnz	(&label("fast_dec_in_place_loop"));
-+
-+    &set_label("fast_dec_out",4);
-+	&cmp	($mark,0);		# was the key schedule copied?
-+	&mov	("edi",$_key);
-+	&je	(&label("skip_dzero"));
-+	# zero copy of key schedule
-+	&mov	("ecx",240/4);
-+	&xor	("eax","eax");
-+	&align	(4);
-+	&data_word(0xABF3F689);		# rep stosd
-+	&set_label("skip_dzero");
-+	&mov	("esp",$_esp);
-+	&popf	();
-+	&function_end_A();
-+	&pushf	();			# kludge, never executed
-+
-+#--------------------------- SLOW ROUTINE ---------------------------#
-+&set_label("slow_way",16);
-+
-+	&mov	($s0,&DWP(0,$s0)) if (!$x86only);# load OPENSSL_ia32cap
-+	&mov	($key,&wparam(3));	# load key
-+
-+	# pre-allocate aligned stack frame...
-+	&lea	($acc,&DWP(-80,"esp"));
-+	&and	($acc,-64);
-+
-+	# ... and make sure it doesn't alias with $key modulo 1024
-+	&lea	($s1,&DWP(-80-63,$key));
-+	&sub	($s1,$acc);
-+	&neg	($s1);
-+	&and	($s1,0x3C0);	# modulo 1024, but aligned to cache-line
-+	&sub	($acc,$s1);
-+
-+	# pick S-box copy which can't overlap with stack frame or $key
-+	&lea	($s1,&DWP(768,$acc));
-+	&sub	($s1,$tbl);
-+	&and	($s1,0x300);
-+	&lea	($tbl,&DWP(2048+128,$tbl,$s1));
-+
-+	&lea	($s3,&wparam(0));	# pointer to parameter block
-+
-+	&exch	("esp",$acc);
-+	&add	("esp",4);		# reserve for return address!
-+	&mov	($_tbl,$tbl);		# save %ebp
-+	&mov	($_esp,$acc);		# save %esp
-+	&mov	($_tmp,$s0);		# save OPENSSL_ia32cap
-+
-+	&mov	($s0,&DWP(0,$s3));	# load inp
-+	&mov	($s1,&DWP(4,$s3));	# load out
-+	#&mov	($s2,&DWP(8,$s3));	# load len
-+	#&mov	($key,&DWP(12,$s3));	# load key
-+	&mov	($acc,&DWP(16,$s3));	# load ivp
-+	&mov	($s3,&DWP(20,$s3));	# load enc flag
-+
-+	&mov	($_inp,$s0);		# save copy of inp
-+	&mov	($_out,$s1);		# save copy of out
-+	&mov	($_len,$s2);		# save copy of len
-+	&mov	($_key,$key);		# save copy of key
-+	&mov	($_ivp,$acc);		# save copy of ivp
-+
-+	&mov	($key,$acc);
-+	&mov	($acc,$s0);
-+
-+	&cmp	($s3,0);
-+	&je	(&label("slow_decrypt"));
-+
-+#--------------------------- SLOW ENCRYPT ---------------------------#
-+	&cmp	($s2,16);
-+	&mov	($s3,$s1);
-+	&jb	(&label("slow_enc_tail"));
-+
-+					if (!$x86only) {
-+	&bt	($_tmp,25);		# check for SSE bit
-+	&jnc	(&label("slow_enc_x86"));
-+
-+	&movq	("mm0",&QWP(0,$key));	# load iv
-+	&movq	("mm4",&QWP(8,$key));
-+
-+	&set_label("slow_enc_loop_sse",16);
-+		&pxor	("mm0",&QWP(0,$acc));	# xor input data
-+		&pxor	("mm4",&QWP(8,$acc));
-+
-+		&mov	($key,$_key);
-+		&call	("_sse_AES_encrypt_compact");
-+
-+		&mov	($acc,$_inp);		# load inp
-+		&mov	($key,$_out);		# load out
-+		&mov	($s2,$_len);		# load len
-+
-+		&movq	(&QWP(0,$key),"mm0");	# save output data
-+		&movq	(&QWP(8,$key),"mm4");
-+
-+		&lea	($acc,&DWP(16,$acc));	# advance inp
-+		&mov	($_inp,$acc);		# save inp
-+		&lea	($s3,&DWP(16,$key));	# advance out
-+		&mov	($_out,$s3);		# save out
-+		&sub	($s2,16);		# decrease len
-+		&cmp	($s2,16);
-+		&mov	($_len,$s2);		# save len
-+	&jae	(&label("slow_enc_loop_sse"));
-+	&test	($s2,15);
-+	&jnz	(&label("slow_enc_tail"));
-+	&mov	($acc,$_ivp);		# load ivp
-+	&movq	(&QWP(0,$acc),"mm0");	# save ivec
-+	&movq	(&QWP(8,$acc),"mm4");
-+	&emms	();
-+	&mov	("esp",$_esp);
-+	&popf	();
-+	&function_end_A();
-+	&pushf	();			# kludge, never executed
-+					}
-+    &set_label("slow_enc_x86",16);
-+	&mov	($s0,&DWP(0,$key));	# load iv
-+	&mov	($s1,&DWP(4,$key));
-+
-+	&set_label("slow_enc_loop_x86",4);
-+		&mov	($s2,&DWP(8,$key));
-+		&mov	($s3,&DWP(12,$key));
-+
-+		&xor	($s0,&DWP(0,$acc));	# xor input data
-+		&xor	($s1,&DWP(4,$acc));
-+		&xor	($s2,&DWP(8,$acc));
-+		&xor	($s3,&DWP(12,$acc));
-+
-+		&mov	($key,$_key);		# load key
-+		&call	("_x86_AES_encrypt_compact");
-+
-+		&mov	($acc,$_inp);		# load inp
-+		&mov	($key,$_out);		# load out
-+
-+		&mov	(&DWP(0,$key),$s0);	# save output data
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&mov	(&DWP(12,$key),$s3);
-+
-+		&mov	($s2,$_len);		# load len
-+		&lea	($acc,&DWP(16,$acc));	# advance inp
-+		&mov	($_inp,$acc);		# save inp
-+		&lea	($s3,&DWP(16,$key));	# advance out
-+		&mov	($_out,$s3);		# save out
-+		&sub	($s2,16);		# decrease len
-+		&cmp	($s2,16);
-+		&mov	($_len,$s2);		# save len
-+	&jae	(&label("slow_enc_loop_x86"));
-+	&test	($s2,15);
-+	&jnz	(&label("slow_enc_tail"));
-+	&mov	($acc,$_ivp);		# load ivp
-+	&mov	($s2,&DWP(8,$key));	# restore last dwords
-+	&mov	($s3,&DWP(12,$key));
-+	&mov	(&DWP(0,$acc),$s0);	# save ivec
-+	&mov	(&DWP(4,$acc),$s1);
-+	&mov	(&DWP(8,$acc),$s2);
-+	&mov	(&DWP(12,$acc),$s3);
-+
-+	&mov	("esp",$_esp);
-+	&popf	();
-+	&function_end_A();
-+	&pushf	();			# kludge, never executed
-+
-+    &set_label("slow_enc_tail",16);
-+	&emms	()	if (!$x86only);
-+	&mov	($key eq "edi"? $key:"",$s3);	# load out to edi
-+	&mov	($s1,16);
-+	&sub	($s1,$s2);
-+	&cmp	($key,$acc eq "esi"? $acc:"");	# compare with inp
-+	&je	(&label("enc_in_place"));
-+	&align	(4);
-+	&data_word(0xA4F3F689);	# rep movsb	# copy input
-+	&jmp	(&label("enc_skip_in_place"));
-+    &set_label("enc_in_place");
-+	&lea	($key,&DWP(0,$key,$s2));
-+    &set_label("enc_skip_in_place");
-+	&mov	($s2,$s1);
-+	&xor	($s0,$s0);
-+	&align	(4);
-+	&data_word(0xAAF3F689);	# rep stosb	# zero tail
-+
-+	&mov	($key,$_ivp);			# restore ivp
-+	&mov	($acc,$s3);			# output as input
-+	&mov	($s0,&DWP(0,$key));
-+	&mov	($s1,&DWP(4,$key));
-+	&mov	($_len,16);			# len=16
-+	&jmp	(&label("slow_enc_loop_x86"));	# one more spin...
-+
-+#--------------------------- SLOW DECRYPT ---------------------------#
-+&set_label("slow_decrypt",16);
-+					if (!$x86only) {
-+	&bt	($_tmp,25);		# check for SSE bit
-+	&jnc	(&label("slow_dec_loop_x86"));
-+
-+	&set_label("slow_dec_loop_sse",4);
-+		&movq	("mm0",&QWP(0,$acc));	# read input
-+		&movq	("mm4",&QWP(8,$acc));
-+
-+		&mov	($key,$_key);
-+		&call	("_sse_AES_decrypt_compact");
-+
-+		&mov	($acc,$_inp);		# load inp
-+		&lea	($s0,$ivec);
-+		&mov	($s1,$_out);		# load out
-+		&mov	($s2,$_len);		# load len
-+		&mov	($key,$_ivp);		# load ivp
-+
-+		&movq	("mm1",&QWP(0,$acc));	# re-read input
-+		&movq	("mm5",&QWP(8,$acc));
-+
-+		&pxor	("mm0",&QWP(0,$key));	# xor iv
-+		&pxor	("mm4",&QWP(8,$key));
-+
-+		&movq	(&QWP(0,$key),"mm1");	# copy input to iv
-+		&movq	(&QWP(8,$key),"mm5");
-+
-+		&sub	($s2,16);		# decrease len
-+		&jc	(&label("slow_dec_partial_sse"));
-+
-+		&movq	(&QWP(0,$s1),"mm0");	# write output
-+		&movq	(&QWP(8,$s1),"mm4");
-+
-+		&lea	($s1,&DWP(16,$s1));	# advance out
-+		&mov	($_out,$s1);		# save out
-+		&lea	($acc,&DWP(16,$acc));	# advance inp
-+		&mov	($_inp,$acc);		# save inp
-+		&mov	($_len,$s2);		# save len
-+	&jnz	(&label("slow_dec_loop_sse"));
-+	&emms	();
-+	&mov	("esp",$_esp);
-+	&popf	();
-+	&function_end_A();
-+	&pushf	();			# kludge, never executed
-+
-+    &set_label("slow_dec_partial_sse",16);
-+	&movq	(&QWP(0,$s0),"mm0");	# save output to temp
-+	&movq	(&QWP(8,$s0),"mm4");
-+	&emms	();
-+
-+	&add	($s2 eq "ecx" ? "ecx":"",16);
-+	&mov	("edi",$s1);		# out
-+	&mov	("esi",$s0);		# temp
-+	&align	(4);
-+	&data_word(0xA4F3F689);		# rep movsb # copy partial output
-+
-+	&mov	("esp",$_esp);
-+	&popf	();
-+	&function_end_A();
-+	&pushf	();			# kludge, never executed
-+					}
-+	&set_label("slow_dec_loop_x86",16);
-+		&mov	($s0,&DWP(0,$acc));	# read input
-+		&mov	($s1,&DWP(4,$acc));
-+		&mov	($s2,&DWP(8,$acc));
-+		&mov	($s3,&DWP(12,$acc));
-+
-+		&lea	($key,$ivec);
-+		&mov	(&DWP(0,$key),$s0);	# copy to temp
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&mov	(&DWP(12,$key),$s3);
-+
-+		&mov	($key,$_key);		# load key
-+		&call	("_x86_AES_decrypt_compact");
-+
-+		&mov	($key,$_ivp);		# load ivp
-+		&mov	($acc,$_len);		# load len
-+		&xor	($s0,&DWP(0,$key));	# xor iv
-+		&xor	($s1,&DWP(4,$key));
-+		&xor	($s2,&DWP(8,$key));
-+		&xor	($s3,&DWP(12,$key));
-+
-+		&sub	($acc,16);
-+		&jc	(&label("slow_dec_partial_x86"));
-+
-+		&mov	($_len,$acc);		# save len
-+		&mov	($acc,$_out);		# load out
-+
-+		&mov	(&DWP(0,$acc),$s0);	# write output
-+		&mov	(&DWP(4,$acc),$s1);
-+		&mov	(&DWP(8,$acc),$s2);
-+		&mov	(&DWP(12,$acc),$s3);
-+
-+		&lea	($acc,&DWP(16,$acc));	# advance out
-+		&mov	($_out,$acc);		# save out
-+
-+		&lea	($acc,$ivec);
-+		&mov	($s0,&DWP(0,$acc));	# read temp
-+		&mov	($s1,&DWP(4,$acc));
-+		&mov	($s2,&DWP(8,$acc));
-+		&mov	($s3,&DWP(12,$acc));
-+
-+		&mov	(&DWP(0,$key),$s0);	# copy it to iv
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&mov	(&DWP(12,$key),$s3);
-+
-+		&mov	($acc,$_inp);		# load inp
-+		&lea	($acc,&DWP(16,$acc));	# advance inp
-+		&mov	($_inp,$acc);		# save inp
-+	&jnz	(&label("slow_dec_loop_x86"));
-+	&mov	("esp",$_esp);
-+	&popf	();
-+	&function_end_A();
-+	&pushf	();			# kludge, never executed
-+
-+    &set_label("slow_dec_partial_x86",16);
-+	&lea	($acc,$ivec);
-+	&mov	(&DWP(0,$acc),$s0);	# save output to temp
-+	&mov	(&DWP(4,$acc),$s1);
-+	&mov	(&DWP(8,$acc),$s2);
-+	&mov	(&DWP(12,$acc),$s3);
-+
-+	&mov	($acc,$_inp);
-+	&mov	($s0,&DWP(0,$acc));	# re-read input
-+	&mov	($s1,&DWP(4,$acc));
-+	&mov	($s2,&DWP(8,$acc));
-+	&mov	($s3,&DWP(12,$acc));
-+
-+	&mov	(&DWP(0,$key),$s0);	# copy it to iv
-+	&mov	(&DWP(4,$key),$s1);
-+	&mov	(&DWP(8,$key),$s2);
-+	&mov	(&DWP(12,$key),$s3);
-+
-+	&mov	("ecx",$_len);
-+	&mov	("edi",$_out);
-+	&lea	("esi",$ivec);
-+	&align	(4);
-+	&data_word(0xA4F3F689);		# rep movsb # copy partial output
-+
-+	&mov	("esp",$_esp);
-+	&popf	();
-+&function_end("AES_cbc_encrypt");
-+}
-+
-+#------------------------------------------------------------------#
-+
-+sub enckey()
-+{
-+	&movz	("esi",&LB("edx"));		# rk[i]>>0
-+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
-+	&movz	("esi",&HB("edx"));		# rk[i]>>8
-+	&shl	("ebx",24);
-+	&xor	("eax","ebx");
-+
-+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
-+	&shr	("edx",16);
-+	&movz	("esi",&LB("edx"));		# rk[i]>>16
-+	&xor	("eax","ebx");
-+
-+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
-+	&movz	("esi",&HB("edx"));		# rk[i]>>24
-+	&shl	("ebx",8);
-+	&xor	("eax","ebx");
-+
-+	&movz	("ebx",&BP(-128,$tbl,"esi",1));
-+	&shl	("ebx",16);
-+	&xor	("eax","ebx");
-+
-+	&xor	("eax",&DWP(1024-128,$tbl,"ecx",4));	# rcon
-+}
-+
-+&function_begin("_x86_AES_set_encrypt_key");
-+	&mov	("esi",&wparam(1));		# user supplied key
-+	&mov	("edi",&wparam(3));		# private key schedule
-+
-+	&test	("esi",-1);
-+	&jz	(&label("badpointer"));
-+	&test	("edi",-1);
-+	&jz	(&label("badpointer"));
-+
-+	&call	(&label("pic_point"));
-+	&set_label("pic_point");
-+	&blindpop($tbl);
-+	&lea	($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl));
-+	&lea	($tbl,&DWP(2048+128,$tbl));
-+
-+	# prefetch Te4
-+	&mov	("eax",&DWP(0-128,$tbl));
-+	&mov	("ebx",&DWP(32-128,$tbl));
-+	&mov	("ecx",&DWP(64-128,$tbl));
-+	&mov	("edx",&DWP(96-128,$tbl));
-+	&mov	("eax",&DWP(128-128,$tbl));
-+	&mov	("ebx",&DWP(160-128,$tbl));
-+	&mov	("ecx",&DWP(192-128,$tbl));
-+	&mov	("edx",&DWP(224-128,$tbl));
-+
-+	&mov	("ecx",&wparam(2));		# number of bits in key
-+	&cmp	("ecx",128);
-+	&je	(&label("10rounds"));
-+	&cmp	("ecx",192);
-+	&je	(&label("12rounds"));
-+	&cmp	("ecx",256);
-+	&je	(&label("14rounds"));
-+	&mov	("eax",-2);			# invalid number of bits
-+	&jmp	(&label("exit"));
-+
-+    &set_label("10rounds");
-+	&mov	("eax",&DWP(0,"esi"));		# copy first 4 dwords
-+	&mov	("ebx",&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&mov	("edx",&DWP(12,"esi"));
-+	&mov	(&DWP(0,"edi"),"eax");
-+	&mov	(&DWP(4,"edi"),"ebx");
-+	&mov	(&DWP(8,"edi"),"ecx");
-+	&mov	(&DWP(12,"edi"),"edx");
-+
-+	&xor	("ecx","ecx");
-+	&jmp	(&label("10shortcut"));
-+
-+	&align	(4);
-+	&set_label("10loop");
-+		&mov	("eax",&DWP(0,"edi"));		# rk[0]
-+		&mov	("edx",&DWP(12,"edi"));		# rk[3]
-+	&set_label("10shortcut");
-+		&enckey	();
-+
-+		&mov	(&DWP(16,"edi"),"eax");		# rk[4]
-+		&xor	("eax",&DWP(4,"edi"));
-+		&mov	(&DWP(20,"edi"),"eax");		# rk[5]
-+		&xor	("eax",&DWP(8,"edi"));
-+		&mov	(&DWP(24,"edi"),"eax");		# rk[6]
-+		&xor	("eax",&DWP(12,"edi"));
-+		&mov	(&DWP(28,"edi"),"eax");		# rk[7]
-+		&inc	("ecx");
-+		&add	("edi",16);
-+		&cmp	("ecx",10);
-+	&jl	(&label("10loop"));
-+
-+	&mov	(&DWP(80,"edi"),10);		# setup number of rounds
-+	&xor	("eax","eax");
-+	&jmp	(&label("exit"));
-+		
-+    &set_label("12rounds");
-+	&mov	("eax",&DWP(0,"esi"));		# copy first 6 dwords
-+	&mov	("ebx",&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&mov	("edx",&DWP(12,"esi"));
-+	&mov	(&DWP(0,"edi"),"eax");
-+	&mov	(&DWP(4,"edi"),"ebx");
-+	&mov	(&DWP(8,"edi"),"ecx");
-+	&mov	(&DWP(12,"edi"),"edx");
-+	&mov	("ecx",&DWP(16,"esi"));
-+	&mov	("edx",&DWP(20,"esi"));
-+	&mov	(&DWP(16,"edi"),"ecx");
-+	&mov	(&DWP(20,"edi"),"edx");
-+
-+	&xor	("ecx","ecx");
-+	&jmp	(&label("12shortcut"));
-+
-+	&align	(4);
-+	&set_label("12loop");
-+		&mov	("eax",&DWP(0,"edi"));		# rk[0]
-+		&mov	("edx",&DWP(20,"edi"));		# rk[5]
-+	&set_label("12shortcut");
-+		&enckey	();
-+
-+		&mov	(&DWP(24,"edi"),"eax");		# rk[6]
-+		&xor	("eax",&DWP(4,"edi"));
-+		&mov	(&DWP(28,"edi"),"eax");		# rk[7]
-+		&xor	("eax",&DWP(8,"edi"));
-+		&mov	(&DWP(32,"edi"),"eax");		# rk[8]
-+		&xor	("eax",&DWP(12,"edi"));
-+		&mov	(&DWP(36,"edi"),"eax");		# rk[9]
-+
-+		&cmp	("ecx",7);
-+		&je	(&label("12break"));
-+		&inc	("ecx");
-+
-+		&xor	("eax",&DWP(16,"edi"));
-+		&mov	(&DWP(40,"edi"),"eax");		# rk[10]
-+		&xor	("eax",&DWP(20,"edi"));
-+		&mov	(&DWP(44,"edi"),"eax");		# rk[11]
-+
-+		&add	("edi",24);
-+	&jmp	(&label("12loop"));
-+
-+	&set_label("12break");
-+	&mov	(&DWP(72,"edi"),12);		# setup number of rounds
-+	&xor	("eax","eax");
-+	&jmp	(&label("exit"));
-+
-+    &set_label("14rounds");
-+	&mov	("eax",&DWP(0,"esi"));		# copy first 8 dwords
-+	&mov	("ebx",&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&mov	("edx",&DWP(12,"esi"));
-+	&mov	(&DWP(0,"edi"),"eax");
-+	&mov	(&DWP(4,"edi"),"ebx");
-+	&mov	(&DWP(8,"edi"),"ecx");
-+	&mov	(&DWP(12,"edi"),"edx");
-+	&mov	("eax",&DWP(16,"esi"));
-+	&mov	("ebx",&DWP(20,"esi"));
-+	&mov	("ecx",&DWP(24,"esi"));
-+	&mov	("edx",&DWP(28,"esi"));
-+	&mov	(&DWP(16,"edi"),"eax");
-+	&mov	(&DWP(20,"edi"),"ebx");
-+	&mov	(&DWP(24,"edi"),"ecx");
-+	&mov	(&DWP(28,"edi"),"edx");
-+
-+	&xor	("ecx","ecx");
-+	&jmp	(&label("14shortcut"));
-+
-+	&align	(4);
-+	&set_label("14loop");
-+		&mov	("edx",&DWP(28,"edi"));		# rk[7]
-+	&set_label("14shortcut");
-+		&mov	("eax",&DWP(0,"edi"));		# rk[0]
-+
-+		&enckey	();
-+
-+		&mov	(&DWP(32,"edi"),"eax");		# rk[8]
-+		&xor	("eax",&DWP(4,"edi"));
-+		&mov	(&DWP(36,"edi"),"eax");		# rk[9]
-+		&xor	("eax",&DWP(8,"edi"));
-+		&mov	(&DWP(40,"edi"),"eax");		# rk[10]
-+		&xor	("eax",&DWP(12,"edi"));
-+		&mov	(&DWP(44,"edi"),"eax");		# rk[11]
-+
-+		&cmp	("ecx",6);
-+		&je	(&label("14break"));
-+		&inc	("ecx");
-+
-+		&mov	("edx","eax");
-+		&mov	("eax",&DWP(16,"edi"));		# rk[4]
-+		&movz	("esi",&LB("edx"));		# rk[11]>>0
-+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
-+		&movz	("esi",&HB("edx"));		# rk[11]>>8
-+		&xor	("eax","ebx");
-+
-+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
-+		&shr	("edx",16);
-+		&shl	("ebx",8);
-+		&movz	("esi",&LB("edx"));		# rk[11]>>16
-+		&xor	("eax","ebx");
-+
-+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
-+		&movz	("esi",&HB("edx"));		# rk[11]>>24
-+		&shl	("ebx",16);
-+		&xor	("eax","ebx");
-+
-+		&movz	("ebx",&BP(-128,$tbl,"esi",1));
-+		&shl	("ebx",24);
-+		&xor	("eax","ebx");
-+
-+		&mov	(&DWP(48,"edi"),"eax");		# rk[12]
-+		&xor	("eax",&DWP(20,"edi"));
-+		&mov	(&DWP(52,"edi"),"eax");		# rk[13]
-+		&xor	("eax",&DWP(24,"edi"));
-+		&mov	(&DWP(56,"edi"),"eax");		# rk[14]
-+		&xor	("eax",&DWP(28,"edi"));
-+		&mov	(&DWP(60,"edi"),"eax");		# rk[15]
-+
-+		&add	("edi",32);
-+	&jmp	(&label("14loop"));
-+
-+	&set_label("14break");
-+	&mov	(&DWP(48,"edi"),14);		# setup number of rounds
-+	&xor	("eax","eax");
-+	&jmp	(&label("exit"));
-+
-+    &set_label("badpointer");
-+	&mov	("eax",-1);
-+    &set_label("exit");
-+&function_end("_x86_AES_set_encrypt_key");
-+
-+# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
-+#                        AES_KEY *key)
-+&function_begin_B("AES_set_encrypt_key");
-+	&call	("_x86_AES_set_encrypt_key");
-+	&ret	();
-+&function_end_B("AES_set_encrypt_key");
-+
-+sub deckey()
-+{ my ($i,$key,$tp1,$tp2,$tp4,$tp8) = @_;
-+  my $tmp = $tbl;
-+
-+	&mov	($tmp,0x80808080);
-+	&and	($tmp,$tp1);
-+	&lea	($tp2,&DWP(0,$tp1,$tp1));
-+	&mov	($acc,$tmp);
-+	&shr	($tmp,7);
-+	&sub	($acc,$tmp);
-+	&and	($tp2,0xfefefefe);
-+	&and	($acc,0x1b1b1b1b);
-+	&xor	($tp2,$acc);
-+	&mov	($tmp,0x80808080);
-+
-+	&and	($tmp,$tp2);
-+	&lea	($tp4,&DWP(0,$tp2,$tp2));
-+	&mov	($acc,$tmp);
-+	&shr	($tmp,7);
-+	&sub	($acc,$tmp);
-+	&and	($tp4,0xfefefefe);
-+	&and	($acc,0x1b1b1b1b);
-+	 &xor	($tp2,$tp1);	# tp2^tp1
-+	&xor	($tp4,$acc);
-+	&mov	($tmp,0x80808080);
-+
-+	&and	($tmp,$tp4);
-+	&lea	($tp8,&DWP(0,$tp4,$tp4));
-+	&mov	($acc,$tmp);
-+	&shr	($tmp,7);
-+	 &xor	($tp4,$tp1);	# tp4^tp1
-+	&sub	($acc,$tmp);
-+	&and	($tp8,0xfefefefe);
-+	&and	($acc,0x1b1b1b1b);
-+	 &rotl	($tp1,8);	# = ROTATE(tp1,8)
-+	&xor	($tp8,$acc);
-+
-+	&mov	($tmp,&DWP(4*($i+1),$key));	# modulo-scheduled load
-+
-+	&xor	($tp1,$tp2);
-+	&xor	($tp2,$tp8);
-+	&xor	($tp1,$tp4);
-+	&rotl	($tp2,24);
-+	&xor	($tp4,$tp8);
-+	&xor	($tp1,$tp8);	# ^= tp8^(tp4^tp1)^(tp2^tp1)
-+	&rotl	($tp4,16);
-+	&xor	($tp1,$tp2);	# ^= ROTATE(tp8^tp2^tp1,24)
-+	&rotl	($tp8,8);
-+	&xor	($tp1,$tp4);	# ^= ROTATE(tp8^tp4^tp1,16)
-+	&mov	($tp2,$tmp);
-+	&xor	($tp1,$tp8);	# ^= ROTATE(tp8,8)
-+
-+	&mov	(&DWP(4*$i,$key),$tp1);
-+}
-+
-+# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
-+#                        AES_KEY *key)
-+&function_begin_B("AES_set_decrypt_key");
-+	&call	("_x86_AES_set_encrypt_key");
-+	&cmp	("eax",0);
-+	&je	(&label("proceed"));
-+	&ret	();
-+
-+    &set_label("proceed");
-+	&push	("ebp");
-+	&push	("ebx");
-+	&push	("esi");
-+	&push	("edi");
-+
-+	&mov	("esi",&wparam(2));
-+	&mov	("ecx",&DWP(240,"esi"));	# pull number of rounds
-+	&lea	("ecx",&DWP(0,"","ecx",4));
-+	&lea	("edi",&DWP(0,"esi","ecx",4));	# pointer to last chunk
-+
-+	&set_label("invert",4);			# invert order of chunks
-+		&mov	("eax",&DWP(0,"esi"));
-+		&mov	("ebx",&DWP(4,"esi"));
-+		&mov	("ecx",&DWP(0,"edi"));
-+		&mov	("edx",&DWP(4,"edi"));
-+		&mov	(&DWP(0,"edi"),"eax");
-+		&mov	(&DWP(4,"edi"),"ebx");
-+		&mov	(&DWP(0,"esi"),"ecx");
-+		&mov	(&DWP(4,"esi"),"edx");
-+		&mov	("eax",&DWP(8,"esi"));
-+		&mov	("ebx",&DWP(12,"esi"));
-+		&mov	("ecx",&DWP(8,"edi"));
-+		&mov	("edx",&DWP(12,"edi"));
-+		&mov	(&DWP(8,"edi"),"eax");
-+		&mov	(&DWP(12,"edi"),"ebx");
-+		&mov	(&DWP(8,"esi"),"ecx");
-+		&mov	(&DWP(12,"esi"),"edx");
-+		&add	("esi",16);
-+		&sub	("edi",16);
-+		&cmp	("esi","edi");
-+	&jne	(&label("invert"));
-+
-+	&mov	($key,&wparam(2));
-+	&mov	($acc,&DWP(240,$key));		# pull number of rounds
-+	&lea	($acc,&DWP(-2,$acc,$acc));
-+	&lea	($acc,&DWP(0,$key,$acc,8));
-+	&mov	(&wparam(2),$acc);
-+
-+	&mov	($s0,&DWP(16,$key));		# modulo-scheduled load
-+	&set_label("permute",4);		# permute the key schedule
-+		&add	($key,16);
-+		&deckey	(0,$key,$s0,$s1,$s2,$s3);
-+		&deckey	(1,$key,$s1,$s2,$s3,$s0);
-+		&deckey	(2,$key,$s2,$s3,$s0,$s1);
-+		&deckey	(3,$key,$s3,$s0,$s1,$s2);
-+		&cmp	($key,&wparam(2));
-+	&jb	(&label("permute"));
-+
-+	&xor	("eax","eax");			# return success
-+&function_end("AES_set_decrypt_key");
-+&asciz("AES for x86, CRYPTOGAMS by ");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-armv4.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-armv4.pl
-new file mode 100644
-index 0000000..16d79aa
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-armv4.pl
-@@ -0,0 +1,1245 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# AES for ARMv4
-+
-+# January 2007.
-+#
-+# Code uses single 1K S-box and is >2 times faster than code generated
-+# by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
-+# allows to merge logical or arithmetic operation with shift or rotate
-+# in one instruction and emit combined result every cycle. The module
-+# is endian-neutral. The performance is ~42 cycles/byte for 128-bit
-+# key [on single-issue Xscale PXA250 core].
-+
-+# May 2007.
-+#
-+# AES_set_[en|de]crypt_key is added.
-+
-+# July 2010.
-+#
-+# Rescheduling for dual-issue pipeline resulted in 12% improvement on
-+# Cortex A8 core and ~25 cycles per byte processed with 128-bit key.
-+
-+# February 2011.
-+#
-+# Profiler-assisted and platform-specific optimization resulted in 16%
-+# improvement on Cortex A8 core and ~21.5 cycles per byte.
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+$s0="r0";
-+$s1="r1";
-+$s2="r2";
-+$s3="r3";
-+$t1="r4";
-+$t2="r5";
-+$t3="r6";
-+$i1="r7";
-+$i2="r8";
-+$i3="r9";
-+
-+$tbl="r10";
-+$key="r11";
-+$rounds="r12";
-+
-+$code=<<___;
-+#ifndef __KERNEL__
-+# include "arm_arch.h"
-+#else
-+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
-+#endif
-+
-+.text
-+#if defined(__thumb2__) && !defined(__APPLE__)
-+.syntax	unified
-+.thumb
-+#else
-+.code	32
-+#undef __thumb2__
-+#endif
-+
-+.type	AES_Te,%object
-+.align	5
-+AES_Te:
-+.word	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
-+.word	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
-+.word	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
-+.word	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
-+.word	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
-+.word	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
-+.word	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
-+.word	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
-+.word	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
-+.word	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
-+.word	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
-+.word	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
-+.word	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
-+.word	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
-+.word	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
-+.word	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
-+.word	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
-+.word	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
-+.word	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
-+.word	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
-+.word	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
-+.word	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
-+.word	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
-+.word	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
-+.word	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
-+.word	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
-+.word	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
-+.word	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
-+.word	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
-+.word	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
-+.word	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
-+.word	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
-+.word	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
-+.word	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
-+.word	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
-+.word	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
-+.word	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
-+.word	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
-+.word	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
-+.word	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
-+.word	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
-+.word	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
-+.word	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
-+.word	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
-+.word	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
-+.word	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
-+.word	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
-+.word	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
-+.word	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
-+.word	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
-+.word	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
-+.word	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
-+.word	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
-+.word	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
-+.word	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
-+.word	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
-+.word	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
-+.word	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
-+.word	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
-+.word	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
-+.word	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
-+.word	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
-+.word	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
-+.word	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
-+@ Te4[256]
-+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+@ rcon[]
-+.word	0x01000000, 0x02000000, 0x04000000, 0x08000000
-+.word	0x10000000, 0x20000000, 0x40000000, 0x80000000
-+.word	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
-+.size	AES_Te,.-AES_Te
-+
-+@ void AES_encrypt(const unsigned char *in, unsigned char *out,
-+@ 		 const AES_KEY *key) {
-+.global AES_encrypt
-+.type   AES_encrypt,%function
-+.align	5
-+AES_encrypt:
-+#ifndef	__thumb2__
-+	sub	r3,pc,#8		@ AES_encrypt
-+#else
-+	adr	r3,AES_encrypt
-+#endif
-+	stmdb   sp!,{r1,r4-r12,lr}
-+#ifdef	__APPLE__
-+	adr	$tbl,AES_Te
-+#else
-+	sub	$tbl,r3,#AES_encrypt-AES_Te	@ Te
-+#endif
-+	mov	$rounds,r0		@ inp
-+	mov	$key,r2
-+#if __ARM_ARCH__<7
-+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
-+	ldrb	$t1,[$rounds,#2]	@ manner...
-+	ldrb	$t2,[$rounds,#1]
-+	ldrb	$t3,[$rounds,#0]
-+	orr	$s0,$s0,$t1,lsl#8
-+	ldrb	$s1,[$rounds,#7]
-+	orr	$s0,$s0,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#6]
-+	orr	$s0,$s0,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#5]
-+	ldrb	$t3,[$rounds,#4]
-+	orr	$s1,$s1,$t1,lsl#8
-+	ldrb	$s2,[$rounds,#11]
-+	orr	$s1,$s1,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#10]
-+	orr	$s1,$s1,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#9]
-+	ldrb	$t3,[$rounds,#8]
-+	orr	$s2,$s2,$t1,lsl#8
-+	ldrb	$s3,[$rounds,#15]
-+	orr	$s2,$s2,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#14]
-+	orr	$s2,$s2,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#13]
-+	ldrb	$t3,[$rounds,#12]
-+	orr	$s3,$s3,$t1,lsl#8
-+	orr	$s3,$s3,$t2,lsl#16
-+	orr	$s3,$s3,$t3,lsl#24
-+#else
-+	ldr	$s0,[$rounds,#0]
-+	ldr	$s1,[$rounds,#4]
-+	ldr	$s2,[$rounds,#8]
-+	ldr	$s3,[$rounds,#12]
-+#ifdef __ARMEL__
-+	rev	$s0,$s0
-+	rev	$s1,$s1
-+	rev	$s2,$s2
-+	rev	$s3,$s3
-+#endif
-+#endif
-+	bl	_armv4_AES_encrypt
-+
-+	ldr	$rounds,[sp],#4		@ pop out
-+#if __ARM_ARCH__>=7
-+#ifdef __ARMEL__
-+	rev	$s0,$s0
-+	rev	$s1,$s1
-+	rev	$s2,$s2
-+	rev	$s3,$s3
-+#endif
-+	str	$s0,[$rounds,#0]
-+	str	$s1,[$rounds,#4]
-+	str	$s2,[$rounds,#8]
-+	str	$s3,[$rounds,#12]
-+#else
-+	mov	$t1,$s0,lsr#24		@ write output in endian-neutral
-+	mov	$t2,$s0,lsr#16		@ manner...
-+	mov	$t3,$s0,lsr#8
-+	strb	$t1,[$rounds,#0]
-+	strb	$t2,[$rounds,#1]
-+	mov	$t1,$s1,lsr#24
-+	strb	$t3,[$rounds,#2]
-+	mov	$t2,$s1,lsr#16
-+	strb	$s0,[$rounds,#3]
-+	mov	$t3,$s1,lsr#8
-+	strb	$t1,[$rounds,#4]
-+	strb	$t2,[$rounds,#5]
-+	mov	$t1,$s2,lsr#24
-+	strb	$t3,[$rounds,#6]
-+	mov	$t2,$s2,lsr#16
-+	strb	$s1,[$rounds,#7]
-+	mov	$t3,$s2,lsr#8
-+	strb	$t1,[$rounds,#8]
-+	strb	$t2,[$rounds,#9]
-+	mov	$t1,$s3,lsr#24
-+	strb	$t3,[$rounds,#10]
-+	mov	$t2,$s3,lsr#16
-+	strb	$s2,[$rounds,#11]
-+	mov	$t3,$s3,lsr#8
-+	strb	$t1,[$rounds,#12]
-+	strb	$t2,[$rounds,#13]
-+	strb	$t3,[$rounds,#14]
-+	strb	$s3,[$rounds,#15]
-+#endif
-+#if __ARM_ARCH__>=5
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia   sp!,{r4-r12,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	AES_encrypt,.-AES_encrypt
-+
-+.type   _armv4_AES_encrypt,%function
-+.align	2
-+_armv4_AES_encrypt:
-+	str	lr,[sp,#-4]!		@ push lr
-+	ldmia	$key!,{$t1-$i1}
-+	eor	$s0,$s0,$t1
-+	ldr	$rounds,[$key,#240-16]
-+	eor	$s1,$s1,$t2
-+	eor	$s2,$s2,$t3
-+	eor	$s3,$s3,$i1
-+	sub	$rounds,$rounds,#1
-+	mov	lr,#255
-+
-+	and	$i1,lr,$s0
-+	and	$i2,lr,$s0,lsr#8
-+	and	$i3,lr,$s0,lsr#16
-+	mov	$s0,$s0,lsr#24
-+.Lenc_loop:
-+	ldr	$t1,[$tbl,$i1,lsl#2]	@ Te3[s0>>0]
-+	and	$i1,lr,$s1,lsr#16	@ i0
-+	ldr	$t2,[$tbl,$i2,lsl#2]	@ Te2[s0>>8]
-+	and	$i2,lr,$s1
-+	ldr	$t3,[$tbl,$i3,lsl#2]	@ Te1[s0>>16]
-+	and	$i3,lr,$s1,lsr#8
-+	ldr	$s0,[$tbl,$s0,lsl#2]	@ Te0[s0>>24]
-+	mov	$s1,$s1,lsr#24
-+
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te1[s1>>16]
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te3[s1>>0]
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te2[s1>>8]
-+	eor	$s0,$s0,$i1,ror#8
-+	ldr	$s1,[$tbl,$s1,lsl#2]	@ Te0[s1>>24]
-+	and	$i1,lr,$s2,lsr#8	@ i0
-+	eor	$t2,$t2,$i2,ror#8
-+	and	$i2,lr,$s2,lsr#16	@ i1
-+	eor	$t3,$t3,$i3,ror#8
-+	and	$i3,lr,$s2
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te2[s2>>8]
-+	eor	$s1,$s1,$t1,ror#24
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te1[s2>>16]
-+	mov	$s2,$s2,lsr#24
-+
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te3[s2>>0]
-+	eor	$s0,$s0,$i1,ror#16
-+	ldr	$s2,[$tbl,$s2,lsl#2]	@ Te0[s2>>24]
-+	and	$i1,lr,$s3		@ i0
-+	eor	$s1,$s1,$i2,ror#8
-+	and	$i2,lr,$s3,lsr#8	@ i1
-+	eor	$t3,$t3,$i3,ror#16
-+	and	$i3,lr,$s3,lsr#16	@ i2
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te3[s3>>0]
-+	eor	$s2,$s2,$t2,ror#16
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te2[s3>>8]
-+	mov	$s3,$s3,lsr#24
-+
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te1[s3>>16]
-+	eor	$s0,$s0,$i1,ror#24
-+	ldr	$i1,[$key],#16
-+	eor	$s1,$s1,$i2,ror#16
-+	ldr	$s3,[$tbl,$s3,lsl#2]	@ Te0[s3>>24]
-+	eor	$s2,$s2,$i3,ror#8
-+	ldr	$t1,[$key,#-12]
-+	eor	$s3,$s3,$t3,ror#8
-+
-+	ldr	$t2,[$key,#-8]
-+	eor	$s0,$s0,$i1
-+	ldr	$t3,[$key,#-4]
-+	and	$i1,lr,$s0
-+	eor	$s1,$s1,$t1
-+	and	$i2,lr,$s0,lsr#8
-+	eor	$s2,$s2,$t2
-+	and	$i3,lr,$s0,lsr#16
-+	eor	$s3,$s3,$t3
-+	mov	$s0,$s0,lsr#24
-+
-+	subs	$rounds,$rounds,#1
-+	bne	.Lenc_loop
-+
-+	add	$tbl,$tbl,#2
-+
-+	ldrb	$t1,[$tbl,$i1,lsl#2]	@ Te4[s0>>0]
-+	and	$i1,lr,$s1,lsr#16	@ i0
-+	ldrb	$t2,[$tbl,$i2,lsl#2]	@ Te4[s0>>8]
-+	and	$i2,lr,$s1
-+	ldrb	$t3,[$tbl,$i3,lsl#2]	@ Te4[s0>>16]
-+	and	$i3,lr,$s1,lsr#8
-+	ldrb	$s0,[$tbl,$s0,lsl#2]	@ Te4[s0>>24]
-+	mov	$s1,$s1,lsr#24
-+
-+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s1>>16]
-+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s1>>0]
-+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s1>>8]
-+	eor	$s0,$i1,$s0,lsl#8
-+	ldrb	$s1,[$tbl,$s1,lsl#2]	@ Te4[s1>>24]
-+	and	$i1,lr,$s2,lsr#8	@ i0
-+	eor	$t2,$i2,$t2,lsl#8
-+	and	$i2,lr,$s2,lsr#16	@ i1
-+	eor	$t3,$i3,$t3,lsl#8
-+	and	$i3,lr,$s2
-+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s2>>8]
-+	eor	$s1,$t1,$s1,lsl#24
-+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s2>>16]
-+	mov	$s2,$s2,lsr#24
-+
-+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s2>>0]
-+	eor	$s0,$i1,$s0,lsl#8
-+	ldrb	$s2,[$tbl,$s2,lsl#2]	@ Te4[s2>>24]
-+	and	$i1,lr,$s3		@ i0
-+	eor	$s1,$s1,$i2,lsl#16
-+	and	$i2,lr,$s3,lsr#8	@ i1
-+	eor	$t3,$i3,$t3,lsl#8
-+	and	$i3,lr,$s3,lsr#16	@ i2
-+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s3>>0]
-+	eor	$s2,$t2,$s2,lsl#24
-+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s3>>8]
-+	mov	$s3,$s3,lsr#24
-+
-+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s3>>16]
-+	eor	$s0,$i1,$s0,lsl#8
-+	ldr	$i1,[$key,#0]
-+	ldrb	$s3,[$tbl,$s3,lsl#2]	@ Te4[s3>>24]
-+	eor	$s1,$s1,$i2,lsl#8
-+	ldr	$t1,[$key,#4]
-+	eor	$s2,$s2,$i3,lsl#16
-+	ldr	$t2,[$key,#8]
-+	eor	$s3,$t3,$s3,lsl#24
-+	ldr	$t3,[$key,#12]
-+
-+	eor	$s0,$s0,$i1
-+	eor	$s1,$s1,$t1
-+	eor	$s2,$s2,$t2
-+	eor	$s3,$s3,$t3
-+
-+	sub	$tbl,$tbl,#2
-+	ldr	pc,[sp],#4		@ pop and return
-+.size	_armv4_AES_encrypt,.-_armv4_AES_encrypt
-+
-+.global AES_set_encrypt_key
-+.type   AES_set_encrypt_key,%function
-+.align	5
-+AES_set_encrypt_key:
-+_armv4_AES_set_encrypt_key:
-+#ifndef	__thumb2__
-+	sub	r3,pc,#8		@ AES_set_encrypt_key
-+#else
-+	adr	r3,AES_set_encrypt_key
-+#endif
-+	teq	r0,#0
-+#ifdef	__thumb2__
-+	itt	eq			@ Thumb2 thing, sanity check in ARM
-+#endif
-+	moveq	r0,#-1
-+	beq	.Labrt
-+	teq	r2,#0
-+#ifdef	__thumb2__
-+	itt	eq			@ Thumb2 thing, sanity check in ARM
-+#endif
-+	moveq	r0,#-1
-+	beq	.Labrt
-+
-+	teq	r1,#128
-+	beq	.Lok
-+	teq	r1,#192
-+	beq	.Lok
-+	teq	r1,#256
-+#ifdef	__thumb2__
-+	itt	ne			@ Thumb2 thing, sanity check in ARM
-+#endif
-+	movne	r0,#-1
-+	bne	.Labrt
-+
-+.Lok:	stmdb   sp!,{r4-r12,lr}
-+	mov	$rounds,r0		@ inp
-+	mov	lr,r1			@ bits
-+	mov	$key,r2			@ key
-+
-+#ifdef	__APPLE__
-+	adr	$tbl,AES_Te+1024				@ Te4
-+#else
-+	sub	$tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024	@ Te4
-+#endif
-+
-+#if __ARM_ARCH__<7
-+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
-+	ldrb	$t1,[$rounds,#2]	@ manner...
-+	ldrb	$t2,[$rounds,#1]
-+	ldrb	$t3,[$rounds,#0]
-+	orr	$s0,$s0,$t1,lsl#8
-+	ldrb	$s1,[$rounds,#7]
-+	orr	$s0,$s0,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#6]
-+	orr	$s0,$s0,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#5]
-+	ldrb	$t3,[$rounds,#4]
-+	orr	$s1,$s1,$t1,lsl#8
-+	ldrb	$s2,[$rounds,#11]
-+	orr	$s1,$s1,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#10]
-+	orr	$s1,$s1,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#9]
-+	ldrb	$t3,[$rounds,#8]
-+	orr	$s2,$s2,$t1,lsl#8
-+	ldrb	$s3,[$rounds,#15]
-+	orr	$s2,$s2,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#14]
-+	orr	$s2,$s2,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#13]
-+	ldrb	$t3,[$rounds,#12]
-+	orr	$s3,$s3,$t1,lsl#8
-+	str	$s0,[$key],#16
-+	orr	$s3,$s3,$t2,lsl#16
-+	str	$s1,[$key,#-12]
-+	orr	$s3,$s3,$t3,lsl#24
-+	str	$s2,[$key,#-8]
-+	str	$s3,[$key,#-4]
-+#else
-+	ldr	$s0,[$rounds,#0]
-+	ldr	$s1,[$rounds,#4]
-+	ldr	$s2,[$rounds,#8]
-+	ldr	$s3,[$rounds,#12]
-+#ifdef __ARMEL__
-+	rev	$s0,$s0
-+	rev	$s1,$s1
-+	rev	$s2,$s2
-+	rev	$s3,$s3
-+#endif
-+	str	$s0,[$key],#16
-+	str	$s1,[$key,#-12]
-+	str	$s2,[$key,#-8]
-+	str	$s3,[$key,#-4]
-+#endif
-+
-+	teq	lr,#128
-+	bne	.Lnot128
-+	mov	$rounds,#10
-+	str	$rounds,[$key,#240-16]
-+	add	$t3,$tbl,#256			@ rcon
-+	mov	lr,#255
-+
-+.L128_loop:
-+	and	$t2,lr,$s3,lsr#24
-+	and	$i1,lr,$s3,lsr#16
-+	ldrb	$t2,[$tbl,$t2]
-+	and	$i2,lr,$s3,lsr#8
-+	ldrb	$i1,[$tbl,$i1]
-+	and	$i3,lr,$s3
-+	ldrb	$i2,[$tbl,$i2]
-+	orr	$t2,$t2,$i1,lsl#24
-+	ldrb	$i3,[$tbl,$i3]
-+	orr	$t2,$t2,$i2,lsl#16
-+	ldr	$t1,[$t3],#4			@ rcon[i++]
-+	orr	$t2,$t2,$i3,lsl#8
-+	eor	$t2,$t2,$t1
-+	eor	$s0,$s0,$t2			@ rk[4]=rk[0]^...
-+	eor	$s1,$s1,$s0			@ rk[5]=rk[1]^rk[4]
-+	str	$s0,[$key],#16
-+	eor	$s2,$s2,$s1			@ rk[6]=rk[2]^rk[5]
-+	str	$s1,[$key,#-12]
-+	eor	$s3,$s3,$s2			@ rk[7]=rk[3]^rk[6]
-+	str	$s2,[$key,#-8]
-+	subs	$rounds,$rounds,#1
-+	str	$s3,[$key,#-4]
-+	bne	.L128_loop
-+	sub	r2,$key,#176
-+	b	.Ldone
-+
-+.Lnot128:
-+#if __ARM_ARCH__<7
-+	ldrb	$i2,[$rounds,#19]
-+	ldrb	$t1,[$rounds,#18]
-+	ldrb	$t2,[$rounds,#17]
-+	ldrb	$t3,[$rounds,#16]
-+	orr	$i2,$i2,$t1,lsl#8
-+	ldrb	$i3,[$rounds,#23]
-+	orr	$i2,$i2,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#22]
-+	orr	$i2,$i2,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#21]
-+	ldrb	$t3,[$rounds,#20]
-+	orr	$i3,$i3,$t1,lsl#8
-+	orr	$i3,$i3,$t2,lsl#16
-+	str	$i2,[$key],#8
-+	orr	$i3,$i3,$t3,lsl#24
-+	str	$i3,[$key,#-4]
-+#else
-+	ldr	$i2,[$rounds,#16]
-+	ldr	$i3,[$rounds,#20]
-+#ifdef __ARMEL__
-+	rev	$i2,$i2
-+	rev	$i3,$i3
-+#endif
-+	str	$i2,[$key],#8
-+	str	$i3,[$key,#-4]
-+#endif
-+
-+	teq	lr,#192
-+	bne	.Lnot192
-+	mov	$rounds,#12
-+	str	$rounds,[$key,#240-24]
-+	add	$t3,$tbl,#256			@ rcon
-+	mov	lr,#255
-+	mov	$rounds,#8
-+
-+.L192_loop:
-+	and	$t2,lr,$i3,lsr#24
-+	and	$i1,lr,$i3,lsr#16
-+	ldrb	$t2,[$tbl,$t2]
-+	and	$i2,lr,$i3,lsr#8
-+	ldrb	$i1,[$tbl,$i1]
-+	and	$i3,lr,$i3
-+	ldrb	$i2,[$tbl,$i2]
-+	orr	$t2,$t2,$i1,lsl#24
-+	ldrb	$i3,[$tbl,$i3]
-+	orr	$t2,$t2,$i2,lsl#16
-+	ldr	$t1,[$t3],#4			@ rcon[i++]
-+	orr	$t2,$t2,$i3,lsl#8
-+	eor	$i3,$t2,$t1
-+	eor	$s0,$s0,$i3			@ rk[6]=rk[0]^...
-+	eor	$s1,$s1,$s0			@ rk[7]=rk[1]^rk[6]
-+	str	$s0,[$key],#24
-+	eor	$s2,$s2,$s1			@ rk[8]=rk[2]^rk[7]
-+	str	$s1,[$key,#-20]
-+	eor	$s3,$s3,$s2			@ rk[9]=rk[3]^rk[8]
-+	str	$s2,[$key,#-16]
-+	subs	$rounds,$rounds,#1
-+	str	$s3,[$key,#-12]
-+#ifdef	__thumb2__
-+	itt	eq				@ Thumb2 thing, sanity check in ARM
-+#endif
-+	subeq	r2,$key,#216
-+	beq	.Ldone
-+
-+	ldr	$i1,[$key,#-32]
-+	ldr	$i2,[$key,#-28]
-+	eor	$i1,$i1,$s3			@ rk[10]=rk[4]^rk[9]
-+	eor	$i3,$i2,$i1			@ rk[11]=rk[5]^rk[10]
-+	str	$i1,[$key,#-8]
-+	str	$i3,[$key,#-4]
-+	b	.L192_loop
-+
-+.Lnot192:
-+#if __ARM_ARCH__<7
-+	ldrb	$i2,[$rounds,#27]
-+	ldrb	$t1,[$rounds,#26]
-+	ldrb	$t2,[$rounds,#25]
-+	ldrb	$t3,[$rounds,#24]
-+	orr	$i2,$i2,$t1,lsl#8
-+	ldrb	$i3,[$rounds,#31]
-+	orr	$i2,$i2,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#30]
-+	orr	$i2,$i2,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#29]
-+	ldrb	$t3,[$rounds,#28]
-+	orr	$i3,$i3,$t1,lsl#8
-+	orr	$i3,$i3,$t2,lsl#16
-+	str	$i2,[$key],#8
-+	orr	$i3,$i3,$t3,lsl#24
-+	str	$i3,[$key,#-4]
-+#else
-+	ldr	$i2,[$rounds,#24]
-+	ldr	$i3,[$rounds,#28]
-+#ifdef __ARMEL__
-+	rev	$i2,$i2
-+	rev	$i3,$i3
-+#endif
-+	str	$i2,[$key],#8
-+	str	$i3,[$key,#-4]
-+#endif
-+
-+	mov	$rounds,#14
-+	str	$rounds,[$key,#240-32]
-+	add	$t3,$tbl,#256			@ rcon
-+	mov	lr,#255
-+	mov	$rounds,#7
-+
-+.L256_loop:
-+	and	$t2,lr,$i3,lsr#24
-+	and	$i1,lr,$i3,lsr#16
-+	ldrb	$t2,[$tbl,$t2]
-+	and	$i2,lr,$i3,lsr#8
-+	ldrb	$i1,[$tbl,$i1]
-+	and	$i3,lr,$i3
-+	ldrb	$i2,[$tbl,$i2]
-+	orr	$t2,$t2,$i1,lsl#24
-+	ldrb	$i3,[$tbl,$i3]
-+	orr	$t2,$t2,$i2,lsl#16
-+	ldr	$t1,[$t3],#4			@ rcon[i++]
-+	orr	$t2,$t2,$i3,lsl#8
-+	eor	$i3,$t2,$t1
-+	eor	$s0,$s0,$i3			@ rk[8]=rk[0]^...
-+	eor	$s1,$s1,$s0			@ rk[9]=rk[1]^rk[8]
-+	str	$s0,[$key],#32
-+	eor	$s2,$s2,$s1			@ rk[10]=rk[2]^rk[9]
-+	str	$s1,[$key,#-28]
-+	eor	$s3,$s3,$s2			@ rk[11]=rk[3]^rk[10]
-+	str	$s2,[$key,#-24]
-+	subs	$rounds,$rounds,#1
-+	str	$s3,[$key,#-20]
-+#ifdef	__thumb2__
-+	itt	eq				@ Thumb2 thing, sanity check in ARM
-+#endif
-+	subeq	r2,$key,#256
-+	beq	.Ldone
-+
-+	and	$t2,lr,$s3
-+	and	$i1,lr,$s3,lsr#8
-+	ldrb	$t2,[$tbl,$t2]
-+	and	$i2,lr,$s3,lsr#16
-+	ldrb	$i1,[$tbl,$i1]
-+	and	$i3,lr,$s3,lsr#24
-+	ldrb	$i2,[$tbl,$i2]
-+	orr	$t2,$t2,$i1,lsl#8
-+	ldrb	$i3,[$tbl,$i3]
-+	orr	$t2,$t2,$i2,lsl#16
-+	ldr	$t1,[$key,#-48]
-+	orr	$t2,$t2,$i3,lsl#24
-+
-+	ldr	$i1,[$key,#-44]
-+	ldr	$i2,[$key,#-40]
-+	eor	$t1,$t1,$t2			@ rk[12]=rk[4]^...
-+	ldr	$i3,[$key,#-36]
-+	eor	$i1,$i1,$t1			@ rk[13]=rk[5]^rk[12]
-+	str	$t1,[$key,#-16]
-+	eor	$i2,$i2,$i1			@ rk[14]=rk[6]^rk[13]
-+	str	$i1,[$key,#-12]
-+	eor	$i3,$i3,$i2			@ rk[15]=rk[7]^rk[14]
-+	str	$i2,[$key,#-8]
-+	str	$i3,[$key,#-4]
-+	b	.L256_loop
-+
-+.align	2
-+.Ldone:	mov	r0,#0
-+	ldmia   sp!,{r4-r12,lr}
-+.Labrt:
-+#if __ARM_ARCH__>=5
-+	ret				@ bx lr
-+#else
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
-+
-+.global AES_set_decrypt_key
-+.type   AES_set_decrypt_key,%function
-+.align	5
-+AES_set_decrypt_key:
-+	str	lr,[sp,#-4]!            @ push lr
-+	bl	_armv4_AES_set_encrypt_key
-+	teq	r0,#0
-+	ldr	lr,[sp],#4              @ pop lr
-+	bne	.Labrt
-+
-+	mov	r0,r2			@ AES_set_encrypt_key preserves r2,
-+	mov	r1,r2			@ which is AES_KEY *key
-+	b	_armv4_AES_set_enc2dec_key
-+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
-+
-+@ void AES_set_enc2dec_key(const AES_KEY *inp,AES_KEY *out)
-+.global	AES_set_enc2dec_key
-+.type	AES_set_enc2dec_key,%function
-+.align	5
-+AES_set_enc2dec_key:
-+_armv4_AES_set_enc2dec_key:
-+	stmdb   sp!,{r4-r12,lr}
-+
-+	ldr	$rounds,[r0,#240]
-+	mov	$i1,r0			@ input
-+	add	$i2,r0,$rounds,lsl#4
-+	mov	$key,r1			@ output
-+	add	$tbl,r1,$rounds,lsl#4
-+	str	$rounds,[r1,#240]
-+
-+.Linv:	ldr	$s0,[$i1],#16
-+	ldr	$s1,[$i1,#-12]
-+	ldr	$s2,[$i1,#-8]
-+	ldr	$s3,[$i1,#-4]
-+	ldr	$t1,[$i2],#-16
-+	ldr	$t2,[$i2,#16+4]
-+	ldr	$t3,[$i2,#16+8]
-+	ldr	$i3,[$i2,#16+12]
-+	str	$s0,[$tbl],#-16
-+	str	$s1,[$tbl,#16+4]
-+	str	$s2,[$tbl,#16+8]
-+	str	$s3,[$tbl,#16+12]
-+	str	$t1,[$key],#16
-+	str	$t2,[$key,#-12]
-+	str	$t3,[$key,#-8]
-+	str	$i3,[$key,#-4]
-+	teq	$i1,$i2
-+	bne	.Linv
-+
-+	ldr	$s0,[$i1]
-+	ldr	$s1,[$i1,#4]
-+	ldr	$s2,[$i1,#8]
-+	ldr	$s3,[$i1,#12]
-+	str	$s0,[$key]
-+	str	$s1,[$key,#4]
-+	str	$s2,[$key,#8]
-+	str	$s3,[$key,#12]
-+	sub	$key,$key,$rounds,lsl#3
-+___
-+$mask80=$i1;
-+$mask1b=$i2;
-+$mask7f=$i3;
-+$code.=<<___;
-+	ldr	$s0,[$key,#16]!		@ prefetch tp1
-+	mov	$mask80,#0x80
-+	mov	$mask1b,#0x1b
-+	orr	$mask80,$mask80,#0x8000
-+	orr	$mask1b,$mask1b,#0x1b00
-+	orr	$mask80,$mask80,$mask80,lsl#16
-+	orr	$mask1b,$mask1b,$mask1b,lsl#16
-+	sub	$rounds,$rounds,#1
-+	mvn	$mask7f,$mask80
-+	mov	$rounds,$rounds,lsl#2	@ (rounds-1)*4
-+
-+.Lmix:	and	$t1,$s0,$mask80
-+	and	$s1,$s0,$mask7f
-+	sub	$t1,$t1,$t1,lsr#7
-+	and	$t1,$t1,$mask1b
-+	eor	$s1,$t1,$s1,lsl#1	@ tp2
-+
-+	and	$t1,$s1,$mask80
-+	and	$s2,$s1,$mask7f
-+	sub	$t1,$t1,$t1,lsr#7
-+	and	$t1,$t1,$mask1b
-+	eor	$s2,$t1,$s2,lsl#1	@ tp4
-+
-+	and	$t1,$s2,$mask80
-+	and	$s3,$s2,$mask7f
-+	sub	$t1,$t1,$t1,lsr#7
-+	and	$t1,$t1,$mask1b
-+	eor	$s3,$t1,$s3,lsl#1	@ tp8
-+
-+	eor	$t1,$s1,$s2
-+	eor	$t2,$s0,$s3		@ tp9
-+	eor	$t1,$t1,$s3		@ tpe
-+	eor	$t1,$t1,$s1,ror#24
-+	eor	$t1,$t1,$t2,ror#24	@ ^= ROTATE(tpb=tp9^tp2,8)
-+	eor	$t1,$t1,$s2,ror#16
-+	eor	$t1,$t1,$t2,ror#16	@ ^= ROTATE(tpd=tp9^tp4,16)
-+	eor	$t1,$t1,$t2,ror#8	@ ^= ROTATE(tp9,24)
-+
-+	ldr	$s0,[$key,#4]		@ prefetch tp1
-+	str	$t1,[$key],#4
-+	subs	$rounds,$rounds,#1
-+	bne	.Lmix
-+
-+	mov	r0,#0
-+#if __ARM_ARCH__>=5
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia   sp!,{r4-r12,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	AES_set_enc2dec_key,.-AES_set_enc2dec_key
-+
-+.type	AES_Td,%object
-+.align	5
-+AES_Td:
-+.word	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
-+.word	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
-+.word	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
-+.word	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
-+.word	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
-+.word	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
-+.word	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
-+.word	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
-+.word	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
-+.word	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
-+.word	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
-+.word	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
-+.word	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
-+.word	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
-+.word	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
-+.word	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
-+.word	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
-+.word	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
-+.word	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
-+.word	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
-+.word	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
-+.word	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
-+.word	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
-+.word	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
-+.word	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
-+.word	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
-+.word	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
-+.word	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
-+.word	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
-+.word	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
-+.word	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
-+.word	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
-+.word	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
-+.word	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
-+.word	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
-+.word	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
-+.word	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
-+.word	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
-+.word	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
-+.word	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
-+.word	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
-+.word	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
-+.word	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
-+.word	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
-+.word	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
-+.word	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
-+.word	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
-+.word	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
-+.word	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
-+.word	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
-+.word	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
-+.word	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
-+.word	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
-+.word	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
-+.word	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
-+.word	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
-+.word	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
-+.word	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
-+.word	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
-+.word	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
-+.word	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
-+.word	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
-+.word	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
-+.word	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
-+@ Td4[256]
-+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+.size	AES_Td,.-AES_Td
-+
-+@ void AES_decrypt(const unsigned char *in, unsigned char *out,
-+@ 		 const AES_KEY *key) {
-+.global AES_decrypt
-+.type   AES_decrypt,%function
-+.align	5
-+AES_decrypt:
-+#ifndef	__thumb2__
-+	sub	r3,pc,#8		@ AES_decrypt
-+#else
-+	adr	r3,AES_decrypt
-+#endif
-+	stmdb   sp!,{r1,r4-r12,lr}
-+#ifdef	__APPLE__
-+	adr	$tbl,AES_Td
-+#else
-+	sub	$tbl,r3,#AES_decrypt-AES_Td	@ Td
-+#endif
-+	mov	$rounds,r0		@ inp
-+	mov	$key,r2
-+#if __ARM_ARCH__<7
-+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
-+	ldrb	$t1,[$rounds,#2]	@ manner...
-+	ldrb	$t2,[$rounds,#1]
-+	ldrb	$t3,[$rounds,#0]
-+	orr	$s0,$s0,$t1,lsl#8
-+	ldrb	$s1,[$rounds,#7]
-+	orr	$s0,$s0,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#6]
-+	orr	$s0,$s0,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#5]
-+	ldrb	$t3,[$rounds,#4]
-+	orr	$s1,$s1,$t1,lsl#8
-+	ldrb	$s2,[$rounds,#11]
-+	orr	$s1,$s1,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#10]
-+	orr	$s1,$s1,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#9]
-+	ldrb	$t3,[$rounds,#8]
-+	orr	$s2,$s2,$t1,lsl#8
-+	ldrb	$s3,[$rounds,#15]
-+	orr	$s2,$s2,$t2,lsl#16
-+	ldrb	$t1,[$rounds,#14]
-+	orr	$s2,$s2,$t3,lsl#24
-+	ldrb	$t2,[$rounds,#13]
-+	ldrb	$t3,[$rounds,#12]
-+	orr	$s3,$s3,$t1,lsl#8
-+	orr	$s3,$s3,$t2,lsl#16
-+	orr	$s3,$s3,$t3,lsl#24
-+#else
-+	ldr	$s0,[$rounds,#0]
-+	ldr	$s1,[$rounds,#4]
-+	ldr	$s2,[$rounds,#8]
-+	ldr	$s3,[$rounds,#12]
-+#ifdef __ARMEL__
-+	rev	$s0,$s0
-+	rev	$s1,$s1
-+	rev	$s2,$s2
-+	rev	$s3,$s3
-+#endif
-+#endif
-+	bl	_armv4_AES_decrypt
-+
-+	ldr	$rounds,[sp],#4		@ pop out
-+#if __ARM_ARCH__>=7
-+#ifdef __ARMEL__
-+	rev	$s0,$s0
-+	rev	$s1,$s1
-+	rev	$s2,$s2
-+	rev	$s3,$s3
-+#endif
-+	str	$s0,[$rounds,#0]
-+	str	$s1,[$rounds,#4]
-+	str	$s2,[$rounds,#8]
-+	str	$s3,[$rounds,#12]
-+#else
-+	mov	$t1,$s0,lsr#24		@ write output in endian-neutral
-+	mov	$t2,$s0,lsr#16		@ manner...
-+	mov	$t3,$s0,lsr#8
-+	strb	$t1,[$rounds,#0]
-+	strb	$t2,[$rounds,#1]
-+	mov	$t1,$s1,lsr#24
-+	strb	$t3,[$rounds,#2]
-+	mov	$t2,$s1,lsr#16
-+	strb	$s0,[$rounds,#3]
-+	mov	$t3,$s1,lsr#8
-+	strb	$t1,[$rounds,#4]
-+	strb	$t2,[$rounds,#5]
-+	mov	$t1,$s2,lsr#24
-+	strb	$t3,[$rounds,#6]
-+	mov	$t2,$s2,lsr#16
-+	strb	$s1,[$rounds,#7]
-+	mov	$t3,$s2,lsr#8
-+	strb	$t1,[$rounds,#8]
-+	strb	$t2,[$rounds,#9]
-+	mov	$t1,$s3,lsr#24
-+	strb	$t3,[$rounds,#10]
-+	mov	$t2,$s3,lsr#16
-+	strb	$s2,[$rounds,#11]
-+	mov	$t3,$s3,lsr#8
-+	strb	$t1,[$rounds,#12]
-+	strb	$t2,[$rounds,#13]
-+	strb	$t3,[$rounds,#14]
-+	strb	$s3,[$rounds,#15]
-+#endif
-+#if __ARM_ARCH__>=5
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia   sp!,{r4-r12,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	AES_decrypt,.-AES_decrypt
-+
-+.type   _armv4_AES_decrypt,%function
-+.align	2
-+_armv4_AES_decrypt:
-+	str	lr,[sp,#-4]!		@ push lr
-+	ldmia	$key!,{$t1-$i1}
-+	eor	$s0,$s0,$t1
-+	ldr	$rounds,[$key,#240-16]
-+	eor	$s1,$s1,$t2
-+	eor	$s2,$s2,$t3
-+	eor	$s3,$s3,$i1
-+	sub	$rounds,$rounds,#1
-+	mov	lr,#255
-+
-+	and	$i1,lr,$s0,lsr#16
-+	and	$i2,lr,$s0,lsr#8
-+	and	$i3,lr,$s0
-+	mov	$s0,$s0,lsr#24
-+.Ldec_loop:
-+	ldr	$t1,[$tbl,$i1,lsl#2]	@ Td1[s0>>16]
-+	and	$i1,lr,$s1		@ i0
-+	ldr	$t2,[$tbl,$i2,lsl#2]	@ Td2[s0>>8]
-+	and	$i2,lr,$s1,lsr#16
-+	ldr	$t3,[$tbl,$i3,lsl#2]	@ Td3[s0>>0]
-+	and	$i3,lr,$s1,lsr#8
-+	ldr	$s0,[$tbl,$s0,lsl#2]	@ Td0[s0>>24]
-+	mov	$s1,$s1,lsr#24
-+
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td3[s1>>0]
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td1[s1>>16]
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td2[s1>>8]
-+	eor	$s0,$s0,$i1,ror#24
-+	ldr	$s1,[$tbl,$s1,lsl#2]	@ Td0[s1>>24]
-+	and	$i1,lr,$s2,lsr#8	@ i0
-+	eor	$t2,$i2,$t2,ror#8
-+	and	$i2,lr,$s2		@ i1
-+	eor	$t3,$i3,$t3,ror#8
-+	and	$i3,lr,$s2,lsr#16
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td2[s2>>8]
-+	eor	$s1,$s1,$t1,ror#8
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td3[s2>>0]
-+	mov	$s2,$s2,lsr#24
-+
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td1[s2>>16]
-+	eor	$s0,$s0,$i1,ror#16
-+	ldr	$s2,[$tbl,$s2,lsl#2]	@ Td0[s2>>24]
-+	and	$i1,lr,$s3,lsr#16	@ i0
-+	eor	$s1,$s1,$i2,ror#24
-+	and	$i2,lr,$s3,lsr#8	@ i1
-+	eor	$t3,$i3,$t3,ror#8
-+	and	$i3,lr,$s3		@ i2
-+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td1[s3>>16]
-+	eor	$s2,$s2,$t2,ror#8
-+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td2[s3>>8]
-+	mov	$s3,$s3,lsr#24
-+
-+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td3[s3>>0]
-+	eor	$s0,$s0,$i1,ror#8
-+	ldr	$i1,[$key],#16
-+	eor	$s1,$s1,$i2,ror#16
-+	ldr	$s3,[$tbl,$s3,lsl#2]	@ Td0[s3>>24]
-+	eor	$s2,$s2,$i3,ror#24
-+
-+	ldr	$t1,[$key,#-12]
-+	eor	$s0,$s0,$i1
-+	ldr	$t2,[$key,#-8]
-+	eor	$s3,$s3,$t3,ror#8
-+	ldr	$t3,[$key,#-4]
-+	and	$i1,lr,$s0,lsr#16
-+	eor	$s1,$s1,$t1
-+	and	$i2,lr,$s0,lsr#8
-+	eor	$s2,$s2,$t2
-+	and	$i3,lr,$s0
-+	eor	$s3,$s3,$t3
-+	mov	$s0,$s0,lsr#24
-+
-+	subs	$rounds,$rounds,#1
-+	bne	.Ldec_loop
-+
-+	add	$tbl,$tbl,#1024
-+
-+	ldr	$t2,[$tbl,#0]		@ prefetch Td4
-+	ldr	$t3,[$tbl,#32]
-+	ldr	$t1,[$tbl,#64]
-+	ldr	$t2,[$tbl,#96]
-+	ldr	$t3,[$tbl,#128]
-+	ldr	$t1,[$tbl,#160]
-+	ldr	$t2,[$tbl,#192]
-+	ldr	$t3,[$tbl,#224]
-+
-+	ldrb	$s0,[$tbl,$s0]		@ Td4[s0>>24]
-+	ldrb	$t1,[$tbl,$i1]		@ Td4[s0>>16]
-+	and	$i1,lr,$s1		@ i0
-+	ldrb	$t2,[$tbl,$i2]		@ Td4[s0>>8]
-+	and	$i2,lr,$s1,lsr#16
-+	ldrb	$t3,[$tbl,$i3]		@ Td4[s0>>0]
-+	and	$i3,lr,$s1,lsr#8
-+
-+	add	$s1,$tbl,$s1,lsr#24
-+	ldrb	$i1,[$tbl,$i1]		@ Td4[s1>>0]
-+	ldrb	$s1,[$s1]		@ Td4[s1>>24]
-+	ldrb	$i2,[$tbl,$i2]		@ Td4[s1>>16]
-+	eor	$s0,$i1,$s0,lsl#24
-+	ldrb	$i3,[$tbl,$i3]		@ Td4[s1>>8]
-+	eor	$s1,$t1,$s1,lsl#8
-+	and	$i1,lr,$s2,lsr#8	@ i0
-+	eor	$t2,$t2,$i2,lsl#8
-+	and	$i2,lr,$s2		@ i1
-+	ldrb	$i1,[$tbl,$i1]		@ Td4[s2>>8]
-+	eor	$t3,$t3,$i3,lsl#8
-+	ldrb	$i2,[$tbl,$i2]		@ Td4[s2>>0]
-+	and	$i3,lr,$s2,lsr#16
-+
-+	add	$s2,$tbl,$s2,lsr#24
-+	ldrb	$s2,[$s2]		@ Td4[s2>>24]
-+	eor	$s0,$s0,$i1,lsl#8
-+	ldrb	$i3,[$tbl,$i3]		@ Td4[s2>>16]
-+	eor	$s1,$i2,$s1,lsl#16
-+	and	$i1,lr,$s3,lsr#16	@ i0
-+	eor	$s2,$t2,$s2,lsl#16
-+	and	$i2,lr,$s3,lsr#8	@ i1
-+	ldrb	$i1,[$tbl,$i1]		@ Td4[s3>>16]
-+	eor	$t3,$t3,$i3,lsl#16
-+	ldrb	$i2,[$tbl,$i2]		@ Td4[s3>>8]
-+	and	$i3,lr,$s3		@ i2
-+
-+	add	$s3,$tbl,$s3,lsr#24
-+	ldrb	$i3,[$tbl,$i3]		@ Td4[s3>>0]
-+	ldrb	$s3,[$s3]		@ Td4[s3>>24]
-+	eor	$s0,$s0,$i1,lsl#16
-+	ldr	$i1,[$key,#0]
-+	eor	$s1,$s1,$i2,lsl#8
-+	ldr	$t1,[$key,#4]
-+	eor	$s2,$i3,$s2,lsl#8
-+	ldr	$t2,[$key,#8]
-+	eor	$s3,$t3,$s3,lsl#24
-+	ldr	$t3,[$key,#12]
-+
-+	eor	$s0,$s0,$i1
-+	eor	$s1,$s1,$t1
-+	eor	$s2,$s2,$t2
-+	eor	$s3,$s3,$t3
-+
-+	sub	$tbl,$tbl,#1024
-+	ldr	pc,[sp],#4		@ pop and return
-+.size	_armv4_AES_decrypt,.-_armv4_AES_decrypt
-+.asciz	"AES for ARMv4, CRYPTOGAMS by "
-+.align	2
-+___
-+
-+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
-+$code =~ s/\bret\b/bx\tlr/gm;
-+
-+open SELF,$0;
-+while() {
-+	next if (/^#!/);
-+	last if (!s/^#/@/ and !/^$/);
-+	print;
-+}
-+close SELF;
-+
-+print $code;
-+close STDOUT;	# enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-c64xplus.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-c64xplus.pl
-new file mode 100644
-index 0000000..19d2cc1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-c64xplus.pl
-@@ -0,0 +1,1382 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# [Endian-neutral] AES for C64x+.
-+#
-+# Even though SPLOOPs are scheduled for 13 cycles, and thus expected
-+# performance is ~8.5 cycles per byte processed with 128-bit key,
-+# measured performance turned to be ~10 cycles per byte. Discrepancy
-+# must be caused by limitations of L1D memory banking(*), see SPRU871
-+# TI publication for further details. If any consolation it's still
-+# ~20% faster than TI's linear assembly module anyway... Compared to
-+# aes_core.c compiled with cl6x 6.0 with -mv6400+ -o2 options this
-+# code is 3.75x faster and almost 3x smaller (tables included).
-+#
-+# (*)	This means that there might be subtle correlation between data
-+#	and timing and one can wonder if it can be ... attacked:-(
-+#	On the other hand this also means that *if* one chooses to
-+#	implement *4* T-tables variant [instead of 1 T-table as in
-+#	this implementation, or in addition to], then one ought to
-+#	*interleave* them. Even though it complicates addressing,
-+#	references to interleaved tables would be guaranteed not to
-+#	clash. I reckon that it should be possible to break 8 cycles
-+#	per byte "barrier," i.e. improve by ~20%, naturally at the
-+#	cost of 8x increased pressure on L1D. 8x because you'd have
-+#	to interleave both Te and Td tables...
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+($TEA,$TEB)=("A5","B5");
-+($KPA,$KPB)=("A3","B1");
-+@K=("A6","B6","A7","B7");
-+@s=("A8","B8","A9","B9");
-+@Te0=@Td0=("A16","B16","A17","B17");
-+@Te1=@Td1=("A18","B18","A19","B19");
-+@Te2=@Td2=("A20","B20","A21","B21");
-+@Te3=@Td3=("A22","B22","A23","B23");
-+
-+$code=<<___;
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.nocmp
-+	.asg	AES_encrypt,_AES_encrypt
-+	.asg	AES_decrypt,_AES_decrypt
-+	.asg	AES_set_encrypt_key,_AES_set_encrypt_key
-+	.asg	AES_set_decrypt_key,_AES_set_decrypt_key
-+	.asg	AES_ctr32_encrypt,_AES_ctr32_encrypt
-+	.endif
-+
-+	.asg	B3,RA
-+	.asg	A4,INP
-+	.asg	B4,OUT
-+	.asg	A6,KEY
-+	.asg	A4,RET
-+	.asg	B15,SP
-+
-+	.eval	24,EXT0
-+	.eval	16,EXT1
-+	.eval	8,EXT2
-+	.eval	0,EXT3
-+	.eval	8,TBL1
-+	.eval	16,TBL2
-+	.eval	24,TBL3
-+
-+	.if	.BIG_ENDIAN
-+	.eval	24-EXT0,EXT0
-+	.eval	24-EXT1,EXT1
-+	.eval	24-EXT2,EXT2
-+	.eval	24-EXT3,EXT3
-+	.eval	32-TBL1,TBL1
-+	.eval	32-TBL2,TBL2
-+	.eval	32-TBL3,TBL3
-+	.endif
-+
-+	.global	_AES_encrypt
-+_AES_encrypt:
-+	.asmfunc
-+	MVK	1,B2
-+__encrypt:
-+	.if	__TI_EABI__
-+   [B2]	LDNDW	*INP++,A9:A8			; load input
-+||	MVKL	\$PCR_OFFSET(AES_Te,__encrypt),$TEA
-+||	ADDKPC	__encrypt,B0
-+   [B2]	LDNDW	*INP++,B9:B8
-+||	MVKH	\$PCR_OFFSET(AES_Te,__encrypt),$TEA
-+||	ADD	0,KEY,$KPA
-+||	ADD	4,KEY,$KPB
-+	.else
-+   [B2]	LDNDW	*INP++,A9:A8			; load input
-+||	MVKL	(AES_Te-__encrypt),$TEA
-+||	ADDKPC	__encrypt,B0
-+   [B2]	LDNDW	*INP++,B9:B8
-+||	MVKH	(AES_Te-__encrypt),$TEA
-+||	ADD	0,KEY,$KPA
-+||	ADD	4,KEY,$KPB
-+	.endif
-+	LDW	*$KPA++[2],$Te0[0]		; zero round key
-+||	LDW	*$KPB++[2],$Te0[1]
-+||	MVK	60,A0
-+||	ADD	B0,$TEA,$TEA			; AES_Te
-+	LDW	*KEY[A0],B0			; rounds
-+||	MVK	1024,A0				; sizeof(AES_Te)
-+	LDW	*$KPA++[2],$Te0[2]
-+||	LDW	*$KPB++[2],$Te0[3]
-+||	MV	$TEA,$TEB
-+	NOP
-+	.if	.BIG_ENDIAN
-+	MV	A9,$s[0]
-+||	MV	A8,$s[1]
-+||	MV	B9,$s[2]
-+||	MV	B8,$s[3]
-+	.else
-+	MV	A8,$s[0]
-+||	MV	A9,$s[1]
-+||	MV	B8,$s[2]
-+||	MV	B9,$s[3]
-+	.endif
-+	XOR	$Te0[0],$s[0],$s[0]
-+||	XOR	$Te0[1],$s[1],$s[1]
-+||	LDW	*$KPA++[2],$K[0]		; 1st round key
-+||	LDW	*$KPB++[2],$K[1]
-+	SUB	B0,2,B0
-+
-+	SPLOOPD	13
-+||	MVC	B0,ILC
-+||	LDW	*$KPA++[2],$K[2]
-+||	LDW	*$KPB++[2],$K[3]
-+;;====================================================================
-+	EXTU	$s[1],EXT1,24,$Te1[1]
-+||	EXTU	$s[0],EXT3,24,$Te3[0]
-+	LDW	*${TEB}[$Te1[1]],$Te1[1]	; Te1[s1>>8],	t0
-+||	LDW	*${TEA}[$Te3[0]],$Te3[0]	; Te3[s0>>24],	t1
-+||	XOR	$s[2],$Te0[2],$s[2]		; modulo-scheduled
-+||	XOR	$s[3],$Te0[3],$s[3]		; modulo-scheduled
-+||	EXTU	$s[1],EXT3,24,$Te3[1]
-+||	EXTU	$s[0],EXT1,24,$Te1[0]
-+	LDW	*${TEB}[$Te3[1]],$Te3[1]	; Te3[s1>>24],	t2
-+||	LDW	*${TEA}[$Te1[0]],$Te1[0]	; Te1[s0>>8],	t3
-+||	EXTU	$s[2],EXT2,24,$Te2[2]
-+||	EXTU	$s[3],EXT2,24,$Te2[3]
-+	LDW	*${TEA}[$Te2[2]],$Te2[2]	; Te2[s2>>16],	t0
-+||	LDW	*${TEB}[$Te2[3]],$Te2[3]	; Te2[s3>>16],	t1
-+||	EXTU	$s[3],EXT3,24,$Te3[3]
-+||	EXTU	$s[2],EXT1,24,$Te1[2]
-+	LDW	*${TEB}[$Te3[3]],$Te3[3]	; Te3[s3>>24],	t0
-+||	LDW	*${TEA}[$Te1[2]],$Te1[2]	; Te1[s2>>8],	t1
-+||	EXTU	$s[0],EXT2,24,$Te2[0]
-+||	EXTU	$s[1],EXT2,24,$Te2[1]
-+	LDW	*${TEA}[$Te2[0]],$Te2[0]	; Te2[s0>>16],	t2
-+||	LDW	*${TEB}[$Te2[1]],$Te2[1]	; Te2[s1>>16],	t3
-+||	EXTU	$s[3],EXT1,24,$Te1[3]
-+||	EXTU	$s[2],EXT3,24,$Te3[2]
-+	LDW	*${TEB}[$Te1[3]],$Te1[3]	; Te1[s3>>8],	t2
-+||	LDW	*${TEA}[$Te3[2]],$Te3[2]	; Te3[s2>>24],	t3
-+||	ROTL	$Te1[1],TBL1,$Te3[0]		; t0
-+||	ROTL	$Te3[0],TBL3,$Te1[1]		; t1
-+||	EXTU	$s[0],EXT0,24,$Te0[0]
-+||	EXTU	$s[1],EXT0,24,$Te0[1]
-+	LDW	*${TEA}[$Te0[0]],$Te0[0]	; Te0[s0],	t0
-+||	LDW	*${TEB}[$Te0[1]],$Te0[1]	; Te0[s1],	t1
-+||	ROTL	$Te3[1],TBL3,$Te1[0]		; t2
-+||	ROTL	$Te1[0],TBL1,$Te3[1]		; t3
-+||	EXTU	$s[2],EXT0,24,$Te0[2]
-+||	EXTU	$s[3],EXT0,24,$Te0[3]
-+	LDW	*${TEA}[$Te0[2]],$Te0[2]	; Te0[s2],	t2
-+||	LDW	*${TEB}[$Te0[3]],$Te0[3]	; Te0[s3],	t3
-+||	ROTL	$Te2[2],TBL2,$Te2[2]		; t0
-+||	ROTL	$Te2[3],TBL2,$Te2[3]		; t1
-+||	XOR	$K[0],$Te3[0],$s[0]
-+||	XOR	$K[1],$Te1[1],$s[1]
-+	ROTL	$Te3[3],TBL3,$Te1[2]		; t0
-+||	ROTL	$Te1[2],TBL1,$Te3[3]		; t1
-+||	XOR	$K[2],$Te1[0],$s[2]
-+||	XOR	$K[3],$Te3[1],$s[3]
-+||	LDW	*$KPA++[2],$K[0]		; next round key
-+||	LDW	*$KPB++[2],$K[1]
-+	ROTL	$Te2[0],TBL2,$Te2[0]		; t2
-+||	ROTL	$Te2[1],TBL2,$Te2[1]		; t3
-+||	XOR	$s[0],$Te2[2],$s[0]
-+||	XOR	$s[1],$Te2[3],$s[1]
-+||	LDW	*$KPA++[2],$K[2]
-+||	LDW	*$KPB++[2],$K[3]
-+	ROTL	$Te1[3],TBL1,$Te3[2]		; t2
-+||	ROTL	$Te3[2],TBL3,$Te1[3]		; t3
-+||	XOR	$s[0],$Te1[2],$s[0]
-+||	XOR	$s[1],$Te3[3],$s[1]
-+	XOR	$s[2],$Te2[0],$s[2]
-+||	XOR	$s[3],$Te2[1],$s[3]
-+||	XOR	$s[0],$Te0[0],$s[0]
-+||	XOR	$s[1],$Te0[1],$s[1]
-+	SPKERNEL
-+||	XOR.L	$s[2],$Te3[2],$s[2]
-+||	XOR.L	$s[3],$Te1[3],$s[3]
-+;;====================================================================
-+	ADD.D	${TEA},A0,${TEA}		; point to Te4
-+||	ADD.D	${TEB},A0,${TEB}
-+||	EXTU	$s[1],EXT1,24,$Te1[1]
-+||	EXTU	$s[0],EXT3,24,$Te3[0]
-+	LDBU	*${TEB}[$Te1[1]],$Te1[1]	; Te1[s1>>8],	t0
-+||	LDBU	*${TEA}[$Te3[0]],$Te3[0]	; Te3[s0>>24],	t1
-+||	XOR	$s[2],$Te0[2],$s[2]		; modulo-scheduled
-+||	XOR	$s[3],$Te0[3],$s[3]		; modulo-scheduled
-+||	EXTU	$s[0],EXT0,24,$Te0[0]
-+||	EXTU	$s[1],EXT0,24,$Te0[1]
-+	LDBU	*${TEA}[$Te0[0]],$Te0[0]	; Te0[s0],	t0
-+||	LDBU	*${TEB}[$Te0[1]],$Te0[1]	; Te0[s1],	t1
-+||	EXTU	$s[3],EXT3,24,$Te3[3]
-+||	EXTU	$s[2],EXT1,24,$Te1[2]
-+	LDBU	*${TEB}[$Te3[3]],$Te3[3]	; Te3[s3>>24],	t0
-+||	LDBU	*${TEA}[$Te1[2]],$Te1[2]	; Te1[s2>>8],	t1
-+||	EXTU	$s[2],EXT2,24,$Te2[2]
-+||	EXTU	$s[3],EXT2,24,$Te2[3]
-+	LDBU	*${TEA}[$Te2[2]],$Te2[2]	; Te2[s2>>16],	t0
-+||	LDBU	*${TEB}[$Te2[3]],$Te2[3]	; Te2[s3>>16],	t1
-+||	EXTU	$s[1],EXT3,24,$Te3[1]
-+||	EXTU	$s[0],EXT1,24,$Te1[0]
-+	LDBU	*${TEB}[$Te3[1]],$Te3[1]	; Te3[s1>>24],	t2
-+||	LDBU	*${TEA}[$Te1[0]],$Te1[0]	; Te1[s0>>8],	t3
-+||	EXTU	$s[3],EXT1,24,$Te1[3]
-+||	EXTU	$s[2],EXT3,24,$Te3[2]
-+	LDBU	*${TEB}[$Te1[3]],$Te1[3]	; Te1[s3>>8],	t2
-+||	LDBU	*${TEA}[$Te3[2]],$Te3[2]	; Te3[s2>>24],	t3
-+||	EXTU	$s[2],EXT0,24,$Te0[2]
-+||	EXTU	$s[3],EXT0,24,$Te0[3]
-+	LDBU	*${TEA}[$Te0[2]],$Te0[2]	; Te0[s2],	t2
-+||	LDBU	*${TEB}[$Te0[3]],$Te0[3]	; Te0[s3],	t3
-+||	EXTU	$s[0],EXT2,24,$Te2[0]
-+||	EXTU	$s[1],EXT2,24,$Te2[1]
-+	LDBU	*${TEA}[$Te2[0]],$Te2[0]	; Te2[s0>>16],	t2
-+||	LDBU	*${TEB}[$Te2[1]],$Te2[1]	; Te2[s1>>16],	t3
-+
-+	.if	.BIG_ENDIAN
-+	PACK2	$Te0[0],$Te1[1],$Te0[0]
-+||	PACK2	$Te0[1],$Te1[2],$Te0[1]
-+	PACK2	$Te2[2],$Te3[3],$Te2[2]
-+||	PACK2	$Te2[3],$Te3[0],$Te2[3]
-+	PACKL4	$Te0[0],$Te2[2],$Te0[0]
-+||	PACKL4	$Te0[1],$Te2[3],$Te0[1]
-+	XOR	$K[0],$Te0[0],$Te0[0]		; s[0]
-+||	XOR	$K[1],$Te0[1],$Te0[1]		; s[1]
-+
-+	PACK2	$Te0[2],$Te1[3],$Te0[2]
-+||	PACK2	$Te0[3],$Te1[0],$Te0[3]
-+	PACK2	$Te2[0],$Te3[1],$Te2[0]
-+||	PACK2	$Te2[1],$Te3[2],$Te2[1]
-+||	BNOP	RA
-+	PACKL4	$Te0[2],$Te2[0],$Te0[2]
-+||	PACKL4	$Te0[3],$Te2[1],$Te0[3]
-+	XOR	$K[2],$Te0[2],$Te0[2]		; s[2]
-+||	XOR	$K[3],$Te0[3],$Te0[3]		; s[3]
-+
-+	MV	$Te0[0],A9
-+||	MV	$Te0[1],A8
-+	MV	$Te0[2],B9
-+||	MV	$Te0[3],B8
-+|| [B2]	STNDW	A9:A8,*OUT++
-+   [B2]	STNDW	B9:B8,*OUT++
-+	.else
-+	PACK2	$Te1[1],$Te0[0],$Te1[1]
-+||	PACK2	$Te1[2],$Te0[1],$Te1[2]
-+	PACK2	$Te3[3],$Te2[2],$Te3[3]
-+||	PACK2	$Te3[0],$Te2[3],$Te3[0]
-+	PACKL4	$Te3[3],$Te1[1],$Te1[1]
-+||	PACKL4	$Te3[0],$Te1[2],$Te1[2]
-+	XOR	$K[0],$Te1[1],$Te1[1]		; s[0]
-+||	XOR	$K[1],$Te1[2],$Te1[2]		; s[1]
-+
-+	PACK2	$Te1[3],$Te0[2],$Te1[3]
-+||	PACK2	$Te1[0],$Te0[3],$Te1[0]
-+	PACK2	$Te3[1],$Te2[0],$Te3[1]
-+||	PACK2	$Te3[2],$Te2[1],$Te3[2]
-+||	BNOP	RA
-+	PACKL4	$Te3[1],$Te1[3],$Te1[3]
-+||	PACKL4	$Te3[2],$Te1[0],$Te1[0]
-+	XOR	$K[2],$Te1[3],$Te1[3]		; s[2]
-+||	XOR	$K[3],$Te1[0],$Te1[0]		; s[3]
-+
-+	MV	$Te1[1],A8
-+||	MV	$Te1[2],A9
-+	MV	$Te1[3],B8
-+||	MV	$Te1[0],B9
-+|| [B2]	STNDW	A9:A8,*OUT++
-+   [B2]	STNDW	B9:B8,*OUT++
-+	.endif
-+	.endasmfunc
-+
-+	.global	_AES_decrypt
-+_AES_decrypt:
-+	.asmfunc
-+	MVK	1,B2
-+__decrypt:
-+	.if	__TI_EABI__
-+   [B2]	LDNDW	*INP++,A9:A8			; load input
-+||	MVKL	\$PCR_OFFSET(AES_Td,__decrypt),$TEA
-+||	ADDKPC	__decrypt,B0
-+   [B2]	LDNDW	*INP++,B9:B8
-+||	MVKH	\$PCR_OFFSET(AES_Td,__decrypt),$TEA
-+||	ADD	0,KEY,$KPA
-+||	ADD	4,KEY,$KPB
-+	.else
-+   [B2]	LDNDW	*INP++,A9:A8			; load input
-+||	MVKL	(AES_Td-__decrypt),$TEA
-+||	ADDKPC	__decrypt,B0
-+   [B2]	LDNDW	*INP++,B9:B8
-+||	MVKH	(AES_Td-__decrypt),$TEA
-+||	ADD	0,KEY,$KPA
-+||	ADD	4,KEY,$KPB
-+	.endif
-+	LDW	*$KPA++[2],$Td0[0]		; zero round key
-+||	LDW	*$KPB++[2],$Td0[1]
-+||	MVK	60,A0
-+||	ADD	B0,$TEA,$TEA			; AES_Td
-+	LDW	*KEY[A0],B0			; rounds
-+||	MVK	1024,A0				; sizeof(AES_Td)
-+	LDW	*$KPA++[2],$Td0[2]
-+||	LDW	*$KPB++[2],$Td0[3]
-+||	MV	$TEA,$TEB
-+	NOP
-+	.if	.BIG_ENDIAN
-+	MV	A9,$s[0]
-+||	MV	A8,$s[1]
-+||	MV	B9,$s[2]
-+||	MV	B8,$s[3]
-+	.else
-+	MV	A8,$s[0]
-+||	MV	A9,$s[1]
-+||	MV	B8,$s[2]
-+||	MV	B9,$s[3]
-+	.endif
-+	XOR	$Td0[0],$s[0],$s[0]
-+||	XOR	$Td0[1],$s[1],$s[1]
-+||	LDW	*$KPA++[2],$K[0]		; 1st round key
-+||	LDW	*$KPB++[2],$K[1]
-+	SUB	B0,2,B0
-+
-+	SPLOOPD	13
-+||	MVC	B0,ILC
-+||	LDW	*$KPA++[2],$K[2]
-+||	LDW	*$KPB++[2],$K[3]
-+;;====================================================================
-+	EXTU	$s[1],EXT3,24,$Td3[1]
-+||	EXTU	$s[0],EXT1,24,$Td1[0]
-+	LDW	*${TEB}[$Td3[1]],$Td3[1]	; Td3[s1>>24],	t0
-+||	LDW	*${TEA}[$Td1[0]],$Td1[0]	; Td1[s0>>8],	t1
-+||	XOR	$s[2],$Td0[2],$s[2]		; modulo-scheduled
-+||	XOR	$s[3],$Td0[3],$s[3]		; modulo-scheduled
-+||	EXTU	$s[1],EXT1,24,$Td1[1]
-+||	EXTU	$s[0],EXT3,24,$Td3[0]
-+	LDW	*${TEB}[$Td1[1]],$Td1[1]	; Td1[s1>>8],	t2
-+||	LDW	*${TEA}[$Td3[0]],$Td3[0]	; Td3[s0>>24],	t3
-+||	EXTU	$s[2],EXT2,24,$Td2[2]
-+||	EXTU	$s[3],EXT2,24,$Td2[3]
-+	LDW	*${TEA}[$Td2[2]],$Td2[2]	; Td2[s2>>16],	t0
-+||	LDW	*${TEB}[$Td2[3]],$Td2[3]	; Td2[s3>>16],	t1
-+||	EXTU	$s[3],EXT1,24,$Td1[3]
-+||	EXTU	$s[2],EXT3,24,$Td3[2]
-+	LDW	*${TEB}[$Td1[3]],$Td1[3]	; Td1[s3>>8],	t0
-+||	LDW	*${TEA}[$Td3[2]],$Td3[2]	; Td3[s2>>24],	t1
-+||	EXTU	$s[0],EXT2,24,$Td2[0]
-+||	EXTU	$s[1],EXT2,24,$Td2[1]
-+	LDW	*${TEA}[$Td2[0]],$Td2[0]	; Td2[s0>>16],	t2
-+||	LDW	*${TEB}[$Td2[1]],$Td2[1]	; Td2[s1>>16],	t3
-+||	EXTU	$s[3],EXT3,24,$Td3[3]
-+||	EXTU	$s[2],EXT1,24,$Td1[2]
-+	LDW	*${TEB}[$Td3[3]],$Td3[3]	; Td3[s3>>24],	t2
-+||	LDW	*${TEA}[$Td1[2]],$Td1[2]	; Td1[s2>>8],	t3
-+||	ROTL	$Td3[1],TBL3,$Td1[0]		; t0
-+||	ROTL	$Td1[0],TBL1,$Td3[1]		; t1
-+||	EXTU	$s[0],EXT0,24,$Td0[0]
-+||	EXTU	$s[1],EXT0,24,$Td0[1]
-+	LDW	*${TEA}[$Td0[0]],$Td0[0]	; Td0[s0],	t0
-+||	LDW	*${TEB}[$Td0[1]],$Td0[1]	; Td0[s1],	t1
-+||	ROTL	$Td1[1],TBL1,$Td3[0]		; t2
-+||	ROTL	$Td3[0],TBL3,$Td1[1]		; t3
-+||	EXTU	$s[2],EXT0,24,$Td0[2]
-+||	EXTU	$s[3],EXT0,24,$Td0[3]
-+	LDW	*${TEA}[$Td0[2]],$Td0[2]	; Td0[s2],	t2
-+||	LDW	*${TEB}[$Td0[3]],$Td0[3]	; Td0[s3],	t3
-+||	ROTL	$Td2[2],TBL2,$Td2[2]		; t0
-+||	ROTL	$Td2[3],TBL2,$Td2[3]		; t1
-+||	XOR	$K[0],$Td1[0],$s[0]
-+||	XOR	$K[1],$Td3[1],$s[1]
-+	ROTL	$Td1[3],TBL1,$Td3[2]		; t0
-+||	ROTL	$Td3[2],TBL3,$Td1[3]		; t1
-+||	XOR	$K[2],$Td3[0],$s[2]
-+||	XOR	$K[3],$Td1[1],$s[3]
-+||	LDW	*$KPA++[2],$K[0]		; next round key
-+||	LDW	*$KPB++[2],$K[1]
-+	ROTL	$Td2[0],TBL2,$Td2[0]		; t2
-+||	ROTL	$Td2[1],TBL2,$Td2[1]		; t3
-+||	XOR	$s[0],$Td2[2],$s[0]
-+||	XOR	$s[1],$Td2[3],$s[1]
-+||	LDW	*$KPA++[2],$K[2]
-+||	LDW	*$KPB++[2],$K[3]
-+	ROTL	$Td3[3],TBL3,$Td1[2]		; t2
-+||	ROTL	$Td1[2],TBL1,$Td3[3]		; t3
-+||	XOR	$s[0],$Td3[2],$s[0]
-+||	XOR	$s[1],$Td1[3],$s[1]
-+	XOR	$s[2],$Td2[0],$s[2]
-+||	XOR	$s[3],$Td2[1],$s[3]
-+||	XOR	$s[0],$Td0[0],$s[0]
-+||	XOR	$s[1],$Td0[1],$s[1]
-+	SPKERNEL
-+||	XOR.L	$s[2],$Td1[2],$s[2]
-+||	XOR.L	$s[3],$Td3[3],$s[3]
-+;;====================================================================
-+	ADD.D	${TEA},A0,${TEA}		; point to Td4
-+||	ADD.D	${TEB},A0,${TEB}
-+||	EXTU	$s[1],EXT3,24,$Td3[1]
-+||	EXTU	$s[0],EXT1,24,$Td1[0]
-+	LDBU	*${TEB}[$Td3[1]],$Td3[1]	; Td3[s1>>24],	t0
-+||	LDBU	*${TEA}[$Td1[0]],$Td1[0]	; Td1[s0>>8],	t1
-+||	XOR	$s[2],$Td0[2],$s[2]		; modulo-scheduled
-+||	XOR	$s[3],$Td0[3],$s[3]		; modulo-scheduled
-+||	EXTU	$s[0],EXT0,24,$Td0[0]
-+||	EXTU	$s[1],EXT0,24,$Td0[1]
-+	LDBU	*${TEA}[$Td0[0]],$Td0[0]	; Td0[s0],	t0
-+||	LDBU	*${TEB}[$Td0[1]],$Td0[1]	; Td0[s1],	t1
-+||	EXTU	$s[2],EXT2,24,$Td2[2]
-+||	EXTU	$s[3],EXT2,24,$Td2[3]
-+	LDBU	*${TEA}[$Td2[2]],$Td2[2]	; Td2[s2>>16],	t0
-+||	LDBU	*${TEB}[$Td2[3]],$Td2[3]	; Td2[s3>>16],	t1
-+||	EXTU	$s[3],EXT1,24,$Td1[3]
-+||	EXTU	$s[2],EXT3,24,$Td3[2]
-+	LDBU	*${TEB}[$Td1[3]],$Td1[3]	; Td1[s3>>8],	t0
-+||	LDBU	*${TEA}[$Td3[2]],$Td3[2]	; Td3[s2>>24],	t1
-+||	EXTU	$s[1],EXT1,24,$Td1[1]
-+||	EXTU	$s[0],EXT3,24,$Td3[0]
-+	LDBU	*${TEB}[$Td1[1]],$Td1[1]	; Td1[s1>>8],	t2
-+||	LDBU	*${TEA}[$Td3[0]],$Td3[0]	; Td3[s0>>24],	t3
-+||	EXTU	$s[0],EXT2,24,$Td2[0]
-+||	EXTU	$s[1],EXT2,24,$Td2[1]
-+	LDBU	*${TEA}[$Td2[0]],$Td2[0]	; Td2[s0>>16],	t2
-+||	LDBU	*${TEB}[$Td2[1]],$Td2[1]	; Td2[s1>>16],	t3
-+||	EXTU	$s[3],EXT3,24,$Td3[3]
-+||	EXTU	$s[2],EXT1,24,$Td1[2]
-+	LDBU	*${TEB}[$Td3[3]],$Td3[3]	; Td3[s3>>24],	t2
-+||	LDBU	*${TEA}[$Td1[2]],$Td1[2]	; Td1[s2>>8],	t3
-+||	EXTU	$s[2],EXT0,24,$Td0[2]
-+||	EXTU	$s[3],EXT0,24,$Td0[3]
-+	LDBU	*${TEA}[$Td0[2]],$Td0[2]	; Td0[s2],	t2
-+||	LDBU	*${TEB}[$Td0[3]],$Td0[3]	; Td0[s3],	t3
-+
-+	.if	.BIG_ENDIAN
-+	PACK2	$Td0[0],$Td1[3],$Td0[0]
-+||	PACK2	$Td0[1],$Td1[0],$Td0[1]
-+	PACK2	$Td2[2],$Td3[1],$Td2[2]
-+||	PACK2	$Td2[3],$Td3[2],$Td2[3]
-+	PACKL4	$Td0[0],$Td2[2],$Td0[0]
-+||	PACKL4	$Td0[1],$Td2[3],$Td0[1]
-+	XOR	$K[0],$Td0[0],$Td0[0]		; s[0]
-+||	XOR	$K[1],$Td0[1],$Td0[1]		; s[1]
-+
-+	PACK2	$Td0[2],$Td1[1],$Td0[2]
-+||	PACK2	$Td0[3],$Td1[2],$Td0[3]
-+	PACK2	$Td2[0],$Td3[3],$Td2[0]
-+||	PACK2	$Td2[1],$Td3[0],$Td2[1]
-+||	BNOP	RA
-+	PACKL4	$Td0[2],$Td2[0],$Td0[2]
-+||	PACKL4	$Td0[3],$Td2[1],$Td0[3]
-+	XOR	$K[2],$Td0[2],$Td0[2]		; s[2]
-+||	XOR	$K[3],$Td0[3],$Td0[3]		; s[3]
-+
-+	MV	$Td0[0],A9
-+||	MV	$Td0[1],A8
-+	MV	$Td0[2],B9
-+||	MV	$Td0[3],B8
-+|| [B2]	STNDW	A9:A8,*OUT++
-+   [B2]	STNDW	B9:B8,*OUT++
-+	.else
-+	PACK2	$Td1[3],$Td0[0],$Td1[3]
-+||	PACK2	$Td1[0],$Td0[1],$Td1[0]
-+	PACK2	$Td3[1],$Td2[2],$Td3[1]
-+||	PACK2	$Td3[2],$Td2[3],$Td3[2]
-+	PACKL4	$Td3[1],$Td1[3],$Td1[3]
-+||	PACKL4	$Td3[2],$Td1[0],$Td1[0]
-+	XOR	$K[0],$Td1[3],$Td1[3]		; s[0]
-+||	XOR	$K[1],$Td1[0],$Td1[0]		; s[1]
-+
-+	PACK2	$Td1[1],$Td0[2],$Td1[1]
-+||	PACK2	$Td1[2],$Td0[3],$Td1[2]
-+	PACK2	$Td3[3],$Td2[0],$Td3[3]
-+||	PACK2	$Td3[0],$Td2[1],$Td3[0]
-+||	BNOP	RA
-+	PACKL4	$Td3[3],$Td1[1],$Td1[1]
-+||	PACKL4	$Td3[0],$Td1[2],$Td1[2]
-+	XOR	$K[2],$Td1[1],$Td1[1]		; s[2]
-+||	XOR	$K[3],$Td1[2],$Td1[2]		; s[3]
-+
-+	MV	$Td1[3],A8
-+||	MV	$Td1[0],A9
-+	MV	$Td1[1],B8
-+||	MV	$Td1[2],B9
-+|| [B2]	STNDW	A9:A8,*OUT++
-+   [B2]	STNDW	B9:B8,*OUT++
-+	.endif
-+	.endasmfunc
-+___
-+{
-+my @K=(@K,@s);			# extended key
-+my @Te4=map("B$_",(16..19));
-+
-+my @Kx9=@Te0;			# used in AES_set_decrypt_key
-+my @KxB=@Te1;
-+my @KxD=@Te2;
-+my @KxE=@Te3;
-+
-+$code.=<<___;
-+	.asg	OUT,BITS
-+
-+	.global	_AES_set_encrypt_key
-+_AES_set_encrypt_key:
-+__set_encrypt_key:
-+	.asmfunc
-+	MV	INP,A0
-+||	SHRU	BITS,5,BITS			; 128-192-256 -> 4-6-8
-+||	MV	KEY,A1
-+  [!A0]	B	RA
-+||[!A0]	MVK	-1,RET
-+||[!A0]	MVK	1,A1				; only one B RA
-+  [!A1]	B	RA
-+||[!A1]	MVK	-1,RET
-+||[!A1]	MVK	0,A0
-+||	MVK	0,B0
-+||	MVK	0,A1
-+   [A0]	LDNDW	*INP++,A9:A8
-+|| [A0]	CMPEQ	4,BITS,B0
-+|| [A0]	CMPLT	3,BITS,A1
-+   [B0]	B	key128?
-+|| [A1]	LDNDW	*INP++,B9:B8
-+|| [A0]	CMPEQ	6,BITS,B0
-+|| [A0]	CMPLT	5,BITS,A1
-+   [B0]	B	key192?
-+|| [A1]	LDNDW	*INP++,B17:B16
-+|| [A0]	CMPEQ	8,BITS,B0
-+|| [A0]	CMPLT	7,BITS,A1
-+   [B0]	B	key256?
-+|| [A1]	LDNDW	*INP++,B19:B18
-+
-+	.if	__TI_EABI__
-+   [A0]	ADD	0,KEY,$KPA
-+|| [A0]	ADD	4,KEY,$KPB
-+|| [A0]	MVKL	\$PCR_OFFSET(AES_Te4,__set_encrypt_key),$TEA
-+|| [A0]	ADDKPC	__set_encrypt_key,B6
-+   [A0]	MVKH	\$PCR_OFFSET(AES_Te4,__set_encrypt_key),$TEA
-+   [A0]	ADD	B6,$TEA,$TEA			; AES_Te4
-+	.else
-+   [A0]	ADD	0,KEY,$KPA
-+|| [A0]	ADD	4,KEY,$KPB
-+|| [A0]	MVKL	(AES_Te4-__set_encrypt_key),$TEA
-+|| [A0]	ADDKPC	__set_encrypt_key,B6
-+   [A0]	MVKH	(AES_Te4-__set_encrypt_key),$TEA
-+   [A0]	ADD	B6,$TEA,$TEA			; AES_Te4
-+	.endif
-+	NOP
-+	NOP
-+
-+	BNOP	RA,5
-+||	MVK	-2,RET				; unknown bit length
-+||	MVK	0,B0				; redundant
-+;;====================================================================
-+;;====================================================================
-+key128?:
-+	.if	.BIG_ENDIAN
-+	MV	A9,$K[0]
-+||	MV	A8,$K[1]
-+||	MV	B9,$Te4[2]
-+||	MV	B8,$K[3]
-+	.else
-+	MV	A8,$K[0]
-+||	MV	A9,$K[1]
-+||	MV	B8,$Te4[2]
-+||	MV	B9,$K[3]
-+	.endif
-+
-+	MVK	256,A0
-+||	MVK	9,B0
-+
-+	SPLOOPD	14
-+||	MVC	B0,ILC
-+||	MV	$TEA,$TEB
-+||	ADD	$TEA,A0,A30			; rcon
-+;;====================================================================
-+	LDW	*A30++[1],A31			; rcon[i]
-+||	MV	$Te4[2],$K[2]
-+||	EXTU	$K[3],EXT1,24,$Te4[0]
-+	LDBU	*${TEB}[$Te4[0]],$Te4[0]
-+||	MV	$K[3],A0
-+||	EXTU	$K[3],EXT2,24,$Te4[1]
-+	LDBU	*${TEB}[$Te4[1]],$Te4[1]
-+||	EXTU	A0,EXT3,24,A0
-+||	EXTU	$K[3],EXT0,24,$Te4[3]
-+	.if	.BIG_ENDIAN
-+	LDBU	*${TEA}[A0],$Te4[3]
-+||	LDBU	*${TEB}[$Te4[3]],A0
-+	.else
-+	LDBU	*${TEA}[A0],A0
-+||	LDBU	*${TEB}[$Te4[3]],$Te4[3]
-+	.endif
-+
-+	STW	$K[0],*$KPA++[2]
-+||	STW	$K[1],*$KPB++[2]
-+	STW	$K[2],*$KPA++[2]
-+||	STW	$K[3],*$KPB++[2]
-+
-+	XOR	A31,$K[0],$K[0]			; ^=rcon[i]
-+	.if	.BIG_ENDIAN
-+	PACK2	$Te4[0],$Te4[1],$Te4[1]
-+	PACK2	$Te4[3],A0,$Te4[3]
-+	PACKL4	$Te4[1],$Te4[3],$Te4[3]
-+	.else
-+	PACK2	$Te4[1],$Te4[0],$Te4[1]
-+	PACK2	$Te4[3],A0,$Te4[3]
-+	PACKL4	$Te4[3],$Te4[1],$Te4[3]
-+	.endif
-+	XOR	$Te4[3],$K[0],$Te4[0]		; K[0]
-+	XOR	$Te4[0],$K[1],$K[1]		; K[1]
-+	MV	$Te4[0],$K[0]
-+||	XOR	$K[1],$K[2],$Te4[2]		; K[2]
-+	XOR	$Te4[2],$K[3],$K[3]		; K[3]
-+	SPKERNEL
-+;;====================================================================
-+	BNOP	RA
-+	MV	$Te4[2],$K[2]
-+||	STW	$K[0],*$KPA++[2]
-+||	STW	$K[1],*$KPB++[2]
-+	STW	$K[2],*$KPA++[2]
-+||	STW	$K[3],*$KPB++[2]
-+	MVK	10,B0				; rounds
-+	STW	B0,*++${KPB}[15]
-+	MVK	0,RET
-+;;====================================================================
-+;;====================================================================
-+key192?:
-+	.if	.BIG_ENDIAN
-+	MV	A9,$K[0]
-+||	MV	A8,$K[1]
-+||	MV	B9,$K[2]
-+||	MV	B8,$K[3]
-+	MV	B17,$Te4[2]
-+||	MV	B16,$K[5]
-+	.else
-+	MV	A8,$K[0]
-+||	MV	A9,$K[1]
-+||	MV	B8,$K[2]
-+||	MV	B9,$K[3]
-+	MV	B16,$Te4[2]
-+||	MV	B17,$K[5]
-+	.endif
-+
-+	MVK	256,A0
-+||	MVK	6,B0
-+	MV	$TEA,$TEB
-+||	ADD	$TEA,A0,A30			; rcon
-+;;====================================================================
-+loop192?:
-+	LDW	*A30++[1],A31			; rcon[i]
-+||	MV	$Te4[2],$K[4]
-+||	EXTU	$K[5],EXT1,24,$Te4[0]
-+	LDBU	*${TEB}[$Te4[0]],$Te4[0]
-+||	MV	$K[5],A0
-+||	EXTU	$K[5],EXT2,24,$Te4[1]
-+	LDBU	*${TEB}[$Te4[1]],$Te4[1]
-+||	EXTU	A0,EXT3,24,A0
-+||	EXTU	$K[5],EXT0,24,$Te4[3]
-+	.if	.BIG_ENDIAN
-+	LDBU	*${TEA}[A0],$Te4[3]
-+||	LDBU	*${TEB}[$Te4[3]],A0
-+	.else
-+	LDBU	*${TEA}[A0],A0
-+||	LDBU	*${TEB}[$Te4[3]],$Te4[3]
-+	.endif
-+
-+	STW	$K[0],*$KPA++[2]
-+||	STW	$K[1],*$KPB++[2]
-+	STW	$K[2],*$KPA++[2]
-+||	STW	$K[3],*$KPB++[2]
-+	STW	$K[4],*$KPA++[2]
-+||	STW	$K[5],*$KPB++[2]
-+
-+	XOR	A31,$K[0],$K[0]			; ^=rcon[i]
-+	.if	.BIG_ENDIAN
-+	PACK2	$Te4[0],$Te4[1],$Te4[1]
-+||	PACK2	$Te4[3],A0,$Te4[3]
-+	PACKL4	$Te4[1],$Te4[3],$Te4[3]
-+	.else
-+	PACK2	$Te4[1],$Te4[0],$Te4[1]
-+||	PACK2	$Te4[3],A0,$Te4[3]
-+	PACKL4	$Te4[3],$Te4[1],$Te4[3]
-+	.endif
-+	BDEC	loop192?,B0
-+||	XOR	$Te4[3],$K[0],$Te4[0]		; K[0]
-+	XOR	$Te4[0],$K[1],$K[1]		; K[1]
-+	MV	$Te4[0],$K[0]
-+||	XOR	$K[1],$K[2],$Te4[2]		; K[2]
-+	XOR	$Te4[2],$K[3],$K[3]		; K[3]
-+	MV	$Te4[2],$K[2]
-+||	XOR	$K[3],$K[4],$Te4[2]		; K[4]
-+	XOR	$Te4[2],$K[5],$K[5]		; K[5]
-+;;====================================================================
-+	BNOP	RA
-+	STW	$K[0],*$KPA++[2]
-+||	STW	$K[1],*$KPB++[2]
-+	STW	$K[2],*$KPA++[2]
-+||	STW	$K[3],*$KPB++[2]
-+	MVK	12,B0				; rounds
-+	STW	B0,*++${KPB}[7]
-+	MVK	0,RET
-+;;====================================================================
-+;;====================================================================
-+key256?:
-+	.if	.BIG_ENDIAN
-+	MV	A9,$K[0]
-+||	MV	A8,$K[1]
-+||	MV	B9,$K[2]
-+||	MV	B8,$K[3]
-+	MV	B17,$K[4]
-+||	MV	B16,$K[5]
-+||	MV	B19,$Te4[2]
-+||	MV	B18,$K[7]
-+	.else
-+	MV	A8,$K[0]
-+||	MV	A9,$K[1]
-+||	MV	B8,$K[2]
-+||	MV	B9,$K[3]
-+	MV	B16,$K[4]
-+||	MV	B17,$K[5]
-+||	MV	B18,$Te4[2]
-+||	MV	B19,$K[7]
-+	.endif
-+
-+	MVK	256,A0
-+||	MVK	6,B0
-+	MV	$TEA,$TEB
-+||	ADD	$TEA,A0,A30			; rcon
-+;;====================================================================
-+loop256?:
-+	LDW	*A30++[1],A31			; rcon[i]
-+||	MV	$Te4[2],$K[6]
-+||	EXTU	$K[7],EXT1,24,$Te4[0]
-+	LDBU	*${TEB}[$Te4[0]],$Te4[0]
-+||	MV	$K[7],A0
-+||	EXTU	$K[7],EXT2,24,$Te4[1]
-+	LDBU	*${TEB}[$Te4[1]],$Te4[1]
-+||	EXTU	A0,EXT3,24,A0
-+||	EXTU	$K[7],EXT0,24,$Te4[3]
-+	.if	.BIG_ENDIAN
-+	LDBU	*${TEA}[A0],$Te4[3]
-+||	LDBU	*${TEB}[$Te4[3]],A0
-+	.else
-+	LDBU	*${TEA}[A0],A0
-+||	LDBU	*${TEB}[$Te4[3]],$Te4[3]
-+	.endif
-+
-+	STW	$K[0],*$KPA++[2]
-+||	STW	$K[1],*$KPB++[2]
-+	STW	$K[2],*$KPA++[2]
-+||	STW	$K[3],*$KPB++[2]
-+	STW	$K[4],*$KPA++[2]
-+||	STW	$K[5],*$KPB++[2]
-+	STW	$K[6],*$KPA++[2]
-+||	STW	$K[7],*$KPB++[2]
-+||	XOR	A31,$K[0],$K[0]			; ^=rcon[i]
-+	.if	.BIG_ENDIAN
-+	PACK2	$Te4[0],$Te4[1],$Te4[1]
-+||	PACK2	$Te4[3],A0,$Te4[3]
-+	PACKL4	$Te4[1],$Te4[3],$Te4[3]
-+||[!B0]	B	done256?
-+	.else
-+	PACK2	$Te4[1],$Te4[0],$Te4[1]
-+||	PACK2	$Te4[3],A0,$Te4[3]
-+	PACKL4	$Te4[3],$Te4[1],$Te4[3]
-+||[!B0]	B	done256?
-+	.endif
-+	XOR	$Te4[3],$K[0],$Te4[0]		; K[0]
-+	XOR	$Te4[0],$K[1],$K[1]		; K[1]
-+	MV	$Te4[0],$K[0]
-+||	XOR	$K[1],$K[2],$Te4[2]		; K[2]
-+	XOR	$Te4[2],$K[3],$K[3]		; K[3]
-+
-+	MV	$Te4[2],$K[2]
-+|| [B0]	EXTU	$K[3],EXT0,24,$Te4[0]
-+|| [B0]	SUB	B0,1,B0
-+	LDBU	*${TEB}[$Te4[0]],$Te4[0]
-+||	MV	$K[3],A0
-+||	EXTU	$K[3],EXT1,24,$Te4[1]
-+	LDBU	*${TEB}[$Te4[1]],$Te4[1]
-+||	EXTU	A0,EXT2,24,A0
-+||	EXTU	$K[3],EXT3,24,$Te4[3]
-+
-+	.if	.BIG_ENDIAN
-+	LDBU	*${TEA}[A0],$Te4[3]
-+||	LDBU	*${TEB}[$Te4[3]],A0
-+	NOP	3
-+	PACK2	$Te4[0],$Te4[1],$Te4[1]
-+	PACK2	$Te4[3],A0,$Te4[3]
-+||	B	loop256?
-+	PACKL4	$Te4[1],$Te4[3],$Te4[3]
-+	.else
-+	LDBU	*${TEA}[A0],A0
-+||	LDBU	*${TEB}[$Te4[3]],$Te4[3]
-+	NOP	3
-+	PACK2	$Te4[1],$Te4[0],$Te4[1]
-+	PACK2	$Te4[3],A0,$Te4[3]
-+||	B	loop256?
-+	PACKL4	$Te4[3],$Te4[1],$Te4[3]
-+	.endif
-+
-+	XOR	$Te4[3],$K[4],$Te4[0]		; K[4]
-+	XOR	$Te4[0],$K[5],$K[5]		; K[5]
-+	MV	$Te4[0],$K[4]
-+||	XOR	$K[5],$K[6],$Te4[2]		; K[6]
-+	XOR	$Te4[2],$K[7],$K[7]		; K[7]
-+;;====================================================================
-+done256?:
-+	BNOP	RA
-+	STW	$K[0],*$KPA++[2]
-+||	STW	$K[1],*$KPB++[2]
-+	STW	$K[2],*$KPA++[2]
-+||	STW	$K[3],*$KPB++[2]
-+	MVK	14,B0				; rounds
-+	STW	B0,*--${KPB}[1]
-+	MVK	0,RET
-+	.endasmfunc
-+
-+	.global	_AES_set_decrypt_key
-+_AES_set_decrypt_key:
-+	.asmfunc
-+	B	__set_encrypt_key		; guarantee local call
-+	MV	KEY,B30				; B30 is not modified
-+	MV	RA, B31				; B31 is not modified
-+	ADDKPC	ret?,RA,2
-+ret?:						; B0 holds rounds or zero
-+  [!B0]	BNOP	B31				; return if zero
-+   [B0]	SHL	B0,4,A0				; offset to last round key
-+   [B0]	SHRU	B0,1,B1
-+   [B0]	SUB	B1,1,B1
-+   [B0]	MVK	0x0000001B,B3			; AES polynomial
-+   [B0]	MVKH	0x07000000,B3
-+
-+	SPLOOPD	9				; flip round keys
-+||	MVC	B1,ILC
-+||	MV	B30,$KPA
-+||	ADD	B30,A0,$KPB
-+||	MVK	16,A0				; sizeof(round key)
-+;;====================================================================
-+	LDW	*${KPA}[0],A16
-+||	LDW	*${KPB}[0],B16
-+	LDW	*${KPA}[1],A17
-+||	LDW	*${KPB}[1],B17
-+	LDW	*${KPA}[2],A18
-+||	LDW	*${KPB}[2],B18
-+	LDW	*${KPA}[3],A19
-+||	ADD	$KPA,A0,$KPA
-+||	LDW	*${KPB}[3],B19
-+||	SUB	$KPB,A0,$KPB
-+	NOP
-+	STW	B16,*${KPA}[-4]
-+||	STW	A16,*${KPB}[4]
-+	STW	B17,*${KPA}[-3]
-+||	STW	A17,*${KPB}[5]
-+	STW	B18,*${KPA}[-2]
-+||	STW	A18,*${KPB}[6]
-+	STW	B19,*${KPA}[-1]
-+||	STW	A19,*${KPB}[7]
-+	SPKERNEL
-+;;====================================================================
-+	SUB	B0,1,B0				; skip last round
-+||	ADD	B30,A0,$KPA			; skip first round
-+||	ADD	B30,A0,$KPB
-+||	MVC	GFPGFR,B30			; save GFPGFR
-+	LDW	*${KPA}[0],$K[0]
-+||	LDW	*${KPB}[1],$K[1]
-+||	MVC	B3,GFPGFR
-+	LDW	*${KPA}[2],$K[2]
-+||	LDW	*${KPB}[3],$K[3]
-+	MVK	0x00000909,A24
-+||	MVK	0x00000B0B,B24
-+	MVKH	0x09090000,A24
-+||	MVKH	0x0B0B0000,B24
-+	MVC	B0,ILC
-+||	SUB	B0,1,B0
-+
-+	GMPY4	$K[0],A24,$Kx9[0]		; ·0x09
-+||	GMPY4	$K[1],A24,$Kx9[1]
-+||	MVK	0x00000D0D,A25
-+||	MVK	0x00000E0E,B25
-+	GMPY4	$K[2],A24,$Kx9[2]
-+||	GMPY4	$K[3],A24,$Kx9[3]
-+||	MVKH	0x0D0D0000,A25
-+||	MVKH	0x0E0E0000,B25
-+
-+	GMPY4	$K[0],B24,$KxB[0]		; ·0x0B
-+||	GMPY4	$K[1],B24,$KxB[1]
-+	GMPY4	$K[2],B24,$KxB[2]
-+||	GMPY4	$K[3],B24,$KxB[3]
-+
-+	SPLOOP	11				; InvMixColumns
-+;;====================================================================
-+	GMPY4	$K[0],A25,$KxD[0]		; ·0x0D
-+||	GMPY4	$K[1],A25,$KxD[1]
-+||	SWAP2	$Kx9[0],$Kx9[0]			; rotate by 16
-+||	SWAP2	$Kx9[1],$Kx9[1]
-+||	MV	$K[0],$s[0]			; this or DINT
-+||	MV	$K[1],$s[1]
-+|| [B0]	LDW	*${KPA}[4],$K[0]
-+|| [B0]	LDW	*${KPB}[5],$K[1]
-+	GMPY4	$K[2],A25,$KxD[2]
-+||	GMPY4	$K[3],A25,$KxD[3]
-+||	SWAP2	$Kx9[2],$Kx9[2]
-+||	SWAP2	$Kx9[3],$Kx9[3]
-+||	MV	$K[2],$s[2]
-+||	MV	$K[3],$s[3]
-+|| [B0]	LDW	*${KPA}[6],$K[2]
-+|| [B0]	LDW	*${KPB}[7],$K[3]
-+
-+	GMPY4	$s[0],B25,$KxE[0]		; ·0x0E
-+||	GMPY4	$s[1],B25,$KxE[1]
-+||	XOR	$Kx9[0],$KxB[0],$KxB[0]
-+||	XOR	$Kx9[1],$KxB[1],$KxB[1]
-+	GMPY4	$s[2],B25,$KxE[2]
-+||	GMPY4	$s[3],B25,$KxE[3]
-+||	XOR	$Kx9[2],$KxB[2],$KxB[2]
-+||	XOR	$Kx9[3],$KxB[3],$KxB[3]
-+
-+	ROTL	$KxB[0],TBL3,$KxB[0]
-+||	ROTL	$KxB[1],TBL3,$KxB[1]
-+||	SWAP2	$KxD[0],$KxD[0]			; rotate by 16
-+||	SWAP2	$KxD[1],$KxD[1]
-+	ROTL	$KxB[2],TBL3,$KxB[2]
-+||	ROTL	$KxB[3],TBL3,$KxB[3]
-+||	SWAP2	$KxD[2],$KxD[2]
-+||	SWAP2	$KxD[3],$KxD[3]
-+
-+	XOR	$KxE[0],$KxD[0],$KxE[0]
-+||	XOR	$KxE[1],$KxD[1],$KxE[1]
-+|| [B0]	GMPY4	$K[0],A24,$Kx9[0]		; ·0x09
-+|| [B0]	GMPY4	$K[1],A24,$Kx9[1]
-+||	ADDAW	$KPA,4,$KPA
-+	XOR	$KxE[2],$KxD[2],$KxE[2]
-+||	XOR	$KxE[3],$KxD[3],$KxE[3]
-+|| [B0]	GMPY4	$K[2],A24,$Kx9[2]
-+|| [B0]	GMPY4	$K[3],A24,$Kx9[3]
-+||	ADDAW	$KPB,4,$KPB
-+
-+	XOR	$KxB[0],$KxE[0],$KxE[0]
-+||	XOR	$KxB[1],$KxE[1],$KxE[1]
-+|| [B0]	GMPY4	$K[0],B24,$KxB[0]		; ·0x0B
-+|| [B0]	GMPY4	$K[1],B24,$KxB[1]
-+	XOR	$KxB[2],$KxE[2],$KxE[2]
-+||	XOR	$KxB[3],$KxE[3],$KxE[3]
-+|| [B0]	GMPY4	$K[2],B24,$KxB[2]
-+|| [B0]	GMPY4	$K[3],B24,$KxB[3]
-+||	STW	$KxE[0],*${KPA}[-4]
-+||	STW	$KxE[1],*${KPB}[-3]
-+	STW	$KxE[2],*${KPA}[-2]
-+||	STW	$KxE[3],*${KPB}[-1]
-+|| [B0]	SUB	B0,1,B0
-+	SPKERNEL
-+;;====================================================================
-+	BNOP	B31,3
-+	MVC	B30,GFPGFR			; restore GFPGFR(*)
-+	MVK	0,RET
-+	.endasmfunc
-+___
-+# (*)	Even though ABI doesn't specify GFPGFR as non-volatile, there
-+#	are code samples out there that *assume* its default value.
-+}
-+{
-+my ($inp,$out,$blocks,$key,$ivp)=("A4","B4","A6","B6","A8");
-+$code.=<<___;
-+	.global	_AES_ctr32_encrypt
-+_AES_ctr32_encrypt:
-+	.asmfunc
-+	LDNDW	*${ivp}[0],A31:A30	; load counter value
-+||	MV	$blocks,A2		; reassign $blocks
-+||	DMV	RA,$key,B27:B26		; reassign RA and $key
-+	LDNDW	*${ivp}[1],B31:B30
-+||	MVK	0,B2			; don't let __encrypt load input
-+||	MVK	0,A1			; and postpone writing output
-+	.if	.BIG_ENDIAN
-+	NOP
-+	.else
-+	NOP	4
-+	SWAP2	B31,B31			; keep least significant 32 bits
-+	SWAP4	B31,B31			; in host byte order
-+	.endif
-+ctr32_loop?:
-+   [A2]	BNOP	__encrypt
-+|| [A1]	XOR	A29,A9,A9		; input^Ek(counter)
-+|| [A1]	XOR	A28,A8,A8
-+|| [A2]	LDNDW	*INP++,A29:A28		; load input
-+  [!A2]	BNOP	B27			; return
-+|| [A1]	XOR	B29,B9,B9
-+|| [A1]	XOR	B28,B8,B8
-+|| [A2]	LDNDW	*INP++,B29:B28
-+	.if	.BIG_ENDIAN
-+   [A1]	STNDW	A9:A8,*OUT++		; save output
-+|| [A2]	DMV	A31,A30,A9:A8		; pass counter value to __encrypt
-+   [A1]	STNDW	B9:B8,*OUT++
-+|| [A2]	DMV	B31,B30,B9:B8
-+|| [A2]	ADD	B30,1,B30		; counter++
-+	.else
-+   [A1]	STNDW	A9:A8,*OUT++		; save output
-+|| [A2]	DMV	A31,A30,A9:A8
-+|| [A2]	SWAP2	B31,B0
-+|| [A2]	ADD	B31,1,B31		; counter++
-+   [A1]	STNDW	B9:B8,*OUT++
-+|| [A2]	MV	B30,B8
-+|| [A2]	SWAP4	B0,B9
-+	.endif
-+   [A2]	ADDKPC	ctr32_loop?,RA		; return to ctr32_loop?
-+|| [A2]	MV	B26,KEY			; pass $key
-+|| [A2]	SUB	A2,1,A2			; $blocks--
-+||[!A1]	MVK	1,A1
-+	NOP
-+	NOP
-+	.endasmfunc
-+___
-+}
-+# Tables are kept in endian-neutral manner
-+$code.=<<___;
-+	.if	__TI_EABI__
-+	.sect	".text:aes_asm.const"
-+	.else
-+	.sect	".const:aes_asm"
-+	.endif
-+	.align	128
-+AES_Te:
-+	.byte	0xc6,0x63,0x63,0xa5,	0xf8,0x7c,0x7c,0x84
-+	.byte	0xee,0x77,0x77,0x99,	0xf6,0x7b,0x7b,0x8d
-+	.byte	0xff,0xf2,0xf2,0x0d,	0xd6,0x6b,0x6b,0xbd
-+	.byte	0xde,0x6f,0x6f,0xb1,	0x91,0xc5,0xc5,0x54
-+	.byte	0x60,0x30,0x30,0x50,	0x02,0x01,0x01,0x03
-+	.byte	0xce,0x67,0x67,0xa9,	0x56,0x2b,0x2b,0x7d
-+	.byte	0xe7,0xfe,0xfe,0x19,	0xb5,0xd7,0xd7,0x62
-+	.byte	0x4d,0xab,0xab,0xe6,	0xec,0x76,0x76,0x9a
-+	.byte	0x8f,0xca,0xca,0x45,	0x1f,0x82,0x82,0x9d
-+	.byte	0x89,0xc9,0xc9,0x40,	0xfa,0x7d,0x7d,0x87
-+	.byte	0xef,0xfa,0xfa,0x15,	0xb2,0x59,0x59,0xeb
-+	.byte	0x8e,0x47,0x47,0xc9,	0xfb,0xf0,0xf0,0x0b
-+	.byte	0x41,0xad,0xad,0xec,	0xb3,0xd4,0xd4,0x67
-+	.byte	0x5f,0xa2,0xa2,0xfd,	0x45,0xaf,0xaf,0xea
-+	.byte	0x23,0x9c,0x9c,0xbf,	0x53,0xa4,0xa4,0xf7
-+	.byte	0xe4,0x72,0x72,0x96,	0x9b,0xc0,0xc0,0x5b
-+	.byte	0x75,0xb7,0xb7,0xc2,	0xe1,0xfd,0xfd,0x1c
-+	.byte	0x3d,0x93,0x93,0xae,	0x4c,0x26,0x26,0x6a
-+	.byte	0x6c,0x36,0x36,0x5a,	0x7e,0x3f,0x3f,0x41
-+	.byte	0xf5,0xf7,0xf7,0x02,	0x83,0xcc,0xcc,0x4f
-+	.byte	0x68,0x34,0x34,0x5c,	0x51,0xa5,0xa5,0xf4
-+	.byte	0xd1,0xe5,0xe5,0x34,	0xf9,0xf1,0xf1,0x08
-+	.byte	0xe2,0x71,0x71,0x93,	0xab,0xd8,0xd8,0x73
-+	.byte	0x62,0x31,0x31,0x53,	0x2a,0x15,0x15,0x3f
-+	.byte	0x08,0x04,0x04,0x0c,	0x95,0xc7,0xc7,0x52
-+	.byte	0x46,0x23,0x23,0x65,	0x9d,0xc3,0xc3,0x5e
-+	.byte	0x30,0x18,0x18,0x28,	0x37,0x96,0x96,0xa1
-+	.byte	0x0a,0x05,0x05,0x0f,	0x2f,0x9a,0x9a,0xb5
-+	.byte	0x0e,0x07,0x07,0x09,	0x24,0x12,0x12,0x36
-+	.byte	0x1b,0x80,0x80,0x9b,	0xdf,0xe2,0xe2,0x3d
-+	.byte	0xcd,0xeb,0xeb,0x26,	0x4e,0x27,0x27,0x69
-+	.byte	0x7f,0xb2,0xb2,0xcd,	0xea,0x75,0x75,0x9f
-+	.byte	0x12,0x09,0x09,0x1b,	0x1d,0x83,0x83,0x9e
-+	.byte	0x58,0x2c,0x2c,0x74,	0x34,0x1a,0x1a,0x2e
-+	.byte	0x36,0x1b,0x1b,0x2d,	0xdc,0x6e,0x6e,0xb2
-+	.byte	0xb4,0x5a,0x5a,0xee,	0x5b,0xa0,0xa0,0xfb
-+	.byte	0xa4,0x52,0x52,0xf6,	0x76,0x3b,0x3b,0x4d
-+	.byte	0xb7,0xd6,0xd6,0x61,	0x7d,0xb3,0xb3,0xce
-+	.byte	0x52,0x29,0x29,0x7b,	0xdd,0xe3,0xe3,0x3e
-+	.byte	0x5e,0x2f,0x2f,0x71,	0x13,0x84,0x84,0x97
-+	.byte	0xa6,0x53,0x53,0xf5,	0xb9,0xd1,0xd1,0x68
-+	.byte	0x00,0x00,0x00,0x00,	0xc1,0xed,0xed,0x2c
-+	.byte	0x40,0x20,0x20,0x60,	0xe3,0xfc,0xfc,0x1f
-+	.byte	0x79,0xb1,0xb1,0xc8,	0xb6,0x5b,0x5b,0xed
-+	.byte	0xd4,0x6a,0x6a,0xbe,	0x8d,0xcb,0xcb,0x46
-+	.byte	0x67,0xbe,0xbe,0xd9,	0x72,0x39,0x39,0x4b
-+	.byte	0x94,0x4a,0x4a,0xde,	0x98,0x4c,0x4c,0xd4
-+	.byte	0xb0,0x58,0x58,0xe8,	0x85,0xcf,0xcf,0x4a
-+	.byte	0xbb,0xd0,0xd0,0x6b,	0xc5,0xef,0xef,0x2a
-+	.byte	0x4f,0xaa,0xaa,0xe5,	0xed,0xfb,0xfb,0x16
-+	.byte	0x86,0x43,0x43,0xc5,	0x9a,0x4d,0x4d,0xd7
-+	.byte	0x66,0x33,0x33,0x55,	0x11,0x85,0x85,0x94
-+	.byte	0x8a,0x45,0x45,0xcf,	0xe9,0xf9,0xf9,0x10
-+	.byte	0x04,0x02,0x02,0x06,	0xfe,0x7f,0x7f,0x81
-+	.byte	0xa0,0x50,0x50,0xf0,	0x78,0x3c,0x3c,0x44
-+	.byte	0x25,0x9f,0x9f,0xba,	0x4b,0xa8,0xa8,0xe3
-+	.byte	0xa2,0x51,0x51,0xf3,	0x5d,0xa3,0xa3,0xfe
-+	.byte	0x80,0x40,0x40,0xc0,	0x05,0x8f,0x8f,0x8a
-+	.byte	0x3f,0x92,0x92,0xad,	0x21,0x9d,0x9d,0xbc
-+	.byte	0x70,0x38,0x38,0x48,	0xf1,0xf5,0xf5,0x04
-+	.byte	0x63,0xbc,0xbc,0xdf,	0x77,0xb6,0xb6,0xc1
-+	.byte	0xaf,0xda,0xda,0x75,	0x42,0x21,0x21,0x63
-+	.byte	0x20,0x10,0x10,0x30,	0xe5,0xff,0xff,0x1a
-+	.byte	0xfd,0xf3,0xf3,0x0e,	0xbf,0xd2,0xd2,0x6d
-+	.byte	0x81,0xcd,0xcd,0x4c,	0x18,0x0c,0x0c,0x14
-+	.byte	0x26,0x13,0x13,0x35,	0xc3,0xec,0xec,0x2f
-+	.byte	0xbe,0x5f,0x5f,0xe1,	0x35,0x97,0x97,0xa2
-+	.byte	0x88,0x44,0x44,0xcc,	0x2e,0x17,0x17,0x39
-+	.byte	0x93,0xc4,0xc4,0x57,	0x55,0xa7,0xa7,0xf2
-+	.byte	0xfc,0x7e,0x7e,0x82,	0x7a,0x3d,0x3d,0x47
-+	.byte	0xc8,0x64,0x64,0xac,	0xba,0x5d,0x5d,0xe7
-+	.byte	0x32,0x19,0x19,0x2b,	0xe6,0x73,0x73,0x95
-+	.byte	0xc0,0x60,0x60,0xa0,	0x19,0x81,0x81,0x98
-+	.byte	0x9e,0x4f,0x4f,0xd1,	0xa3,0xdc,0xdc,0x7f
-+	.byte	0x44,0x22,0x22,0x66,	0x54,0x2a,0x2a,0x7e
-+	.byte	0x3b,0x90,0x90,0xab,	0x0b,0x88,0x88,0x83
-+	.byte	0x8c,0x46,0x46,0xca,	0xc7,0xee,0xee,0x29
-+	.byte	0x6b,0xb8,0xb8,0xd3,	0x28,0x14,0x14,0x3c
-+	.byte	0xa7,0xde,0xde,0x79,	0xbc,0x5e,0x5e,0xe2
-+	.byte	0x16,0x0b,0x0b,0x1d,	0xad,0xdb,0xdb,0x76
-+	.byte	0xdb,0xe0,0xe0,0x3b,	0x64,0x32,0x32,0x56
-+	.byte	0x74,0x3a,0x3a,0x4e,	0x14,0x0a,0x0a,0x1e
-+	.byte	0x92,0x49,0x49,0xdb,	0x0c,0x06,0x06,0x0a
-+	.byte	0x48,0x24,0x24,0x6c,	0xb8,0x5c,0x5c,0xe4
-+	.byte	0x9f,0xc2,0xc2,0x5d,	0xbd,0xd3,0xd3,0x6e
-+	.byte	0x43,0xac,0xac,0xef,	0xc4,0x62,0x62,0xa6
-+	.byte	0x39,0x91,0x91,0xa8,	0x31,0x95,0x95,0xa4
-+	.byte	0xd3,0xe4,0xe4,0x37,	0xf2,0x79,0x79,0x8b
-+	.byte	0xd5,0xe7,0xe7,0x32,	0x8b,0xc8,0xc8,0x43
-+	.byte	0x6e,0x37,0x37,0x59,	0xda,0x6d,0x6d,0xb7
-+	.byte	0x01,0x8d,0x8d,0x8c,	0xb1,0xd5,0xd5,0x64
-+	.byte	0x9c,0x4e,0x4e,0xd2,	0x49,0xa9,0xa9,0xe0
-+	.byte	0xd8,0x6c,0x6c,0xb4,	0xac,0x56,0x56,0xfa
-+	.byte	0xf3,0xf4,0xf4,0x07,	0xcf,0xea,0xea,0x25
-+	.byte	0xca,0x65,0x65,0xaf,	0xf4,0x7a,0x7a,0x8e
-+	.byte	0x47,0xae,0xae,0xe9,	0x10,0x08,0x08,0x18
-+	.byte	0x6f,0xba,0xba,0xd5,	0xf0,0x78,0x78,0x88
-+	.byte	0x4a,0x25,0x25,0x6f,	0x5c,0x2e,0x2e,0x72
-+	.byte	0x38,0x1c,0x1c,0x24,	0x57,0xa6,0xa6,0xf1
-+	.byte	0x73,0xb4,0xb4,0xc7,	0x97,0xc6,0xc6,0x51
-+	.byte	0xcb,0xe8,0xe8,0x23,	0xa1,0xdd,0xdd,0x7c
-+	.byte	0xe8,0x74,0x74,0x9c,	0x3e,0x1f,0x1f,0x21
-+	.byte	0x96,0x4b,0x4b,0xdd,	0x61,0xbd,0xbd,0xdc
-+	.byte	0x0d,0x8b,0x8b,0x86,	0x0f,0x8a,0x8a,0x85
-+	.byte	0xe0,0x70,0x70,0x90,	0x7c,0x3e,0x3e,0x42
-+	.byte	0x71,0xb5,0xb5,0xc4,	0xcc,0x66,0x66,0xaa
-+	.byte	0x90,0x48,0x48,0xd8,	0x06,0x03,0x03,0x05
-+	.byte	0xf7,0xf6,0xf6,0x01,	0x1c,0x0e,0x0e,0x12
-+	.byte	0xc2,0x61,0x61,0xa3,	0x6a,0x35,0x35,0x5f
-+	.byte	0xae,0x57,0x57,0xf9,	0x69,0xb9,0xb9,0xd0
-+	.byte	0x17,0x86,0x86,0x91,	0x99,0xc1,0xc1,0x58
-+	.byte	0x3a,0x1d,0x1d,0x27,	0x27,0x9e,0x9e,0xb9
-+	.byte	0xd9,0xe1,0xe1,0x38,	0xeb,0xf8,0xf8,0x13
-+	.byte	0x2b,0x98,0x98,0xb3,	0x22,0x11,0x11,0x33
-+	.byte	0xd2,0x69,0x69,0xbb,	0xa9,0xd9,0xd9,0x70
-+	.byte	0x07,0x8e,0x8e,0x89,	0x33,0x94,0x94,0xa7
-+	.byte	0x2d,0x9b,0x9b,0xb6,	0x3c,0x1e,0x1e,0x22
-+	.byte	0x15,0x87,0x87,0x92,	0xc9,0xe9,0xe9,0x20
-+	.byte	0x87,0xce,0xce,0x49,	0xaa,0x55,0x55,0xff
-+	.byte	0x50,0x28,0x28,0x78,	0xa5,0xdf,0xdf,0x7a
-+	.byte	0x03,0x8c,0x8c,0x8f,	0x59,0xa1,0xa1,0xf8
-+	.byte	0x09,0x89,0x89,0x80,	0x1a,0x0d,0x0d,0x17
-+	.byte	0x65,0xbf,0xbf,0xda,	0xd7,0xe6,0xe6,0x31
-+	.byte	0x84,0x42,0x42,0xc6,	0xd0,0x68,0x68,0xb8
-+	.byte	0x82,0x41,0x41,0xc3,	0x29,0x99,0x99,0xb0
-+	.byte	0x5a,0x2d,0x2d,0x77,	0x1e,0x0f,0x0f,0x11
-+	.byte	0x7b,0xb0,0xb0,0xcb,	0xa8,0x54,0x54,0xfc
-+	.byte	0x6d,0xbb,0xbb,0xd6,	0x2c,0x16,0x16,0x3a
-+AES_Te4:
-+	.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-+	.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-+	.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-+	.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-+	.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-+	.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-+	.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-+	.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-+	.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-+	.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-+	.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-+	.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-+	.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-+	.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-+	.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-+	.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-+	.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-+	.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-+	.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-+	.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-+	.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-+	.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-+	.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-+	.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-+	.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-+	.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-+	.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-+	.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-+	.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-+	.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-+	.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-+	.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+rcon:
-+	.byte	0x01,0x00,0x00,0x00,	0x02,0x00,0x00,0x00
-+	.byte	0x04,0x00,0x00,0x00,	0x08,0x00,0x00,0x00
-+	.byte	0x10,0x00,0x00,0x00,	0x20,0x00,0x00,0x00
-+	.byte	0x40,0x00,0x00,0x00,	0x80,0x00,0x00,0x00
-+	.byte	0x1B,0x00,0x00,0x00,	0x36,0x00,0x00,0x00
-+	.align	128
-+AES_Td:
-+	.byte	0x51,0xf4,0xa7,0x50,	0x7e,0x41,0x65,0x53
-+	.byte	0x1a,0x17,0xa4,0xc3,	0x3a,0x27,0x5e,0x96
-+	.byte	0x3b,0xab,0x6b,0xcb,	0x1f,0x9d,0x45,0xf1
-+	.byte	0xac,0xfa,0x58,0xab,	0x4b,0xe3,0x03,0x93
-+	.byte	0x20,0x30,0xfa,0x55,	0xad,0x76,0x6d,0xf6
-+	.byte	0x88,0xcc,0x76,0x91,	0xf5,0x02,0x4c,0x25
-+	.byte	0x4f,0xe5,0xd7,0xfc,	0xc5,0x2a,0xcb,0xd7
-+	.byte	0x26,0x35,0x44,0x80,	0xb5,0x62,0xa3,0x8f
-+	.byte	0xde,0xb1,0x5a,0x49,	0x25,0xba,0x1b,0x67
-+	.byte	0x45,0xea,0x0e,0x98,	0x5d,0xfe,0xc0,0xe1
-+	.byte	0xc3,0x2f,0x75,0x02,	0x81,0x4c,0xf0,0x12
-+	.byte	0x8d,0x46,0x97,0xa3,	0x6b,0xd3,0xf9,0xc6
-+	.byte	0x03,0x8f,0x5f,0xe7,	0x15,0x92,0x9c,0x95
-+	.byte	0xbf,0x6d,0x7a,0xeb,	0x95,0x52,0x59,0xda
-+	.byte	0xd4,0xbe,0x83,0x2d,	0x58,0x74,0x21,0xd3
-+	.byte	0x49,0xe0,0x69,0x29,	0x8e,0xc9,0xc8,0x44
-+	.byte	0x75,0xc2,0x89,0x6a,	0xf4,0x8e,0x79,0x78
-+	.byte	0x99,0x58,0x3e,0x6b,	0x27,0xb9,0x71,0xdd
-+	.byte	0xbe,0xe1,0x4f,0xb6,	0xf0,0x88,0xad,0x17
-+	.byte	0xc9,0x20,0xac,0x66,	0x7d,0xce,0x3a,0xb4
-+	.byte	0x63,0xdf,0x4a,0x18,	0xe5,0x1a,0x31,0x82
-+	.byte	0x97,0x51,0x33,0x60,	0x62,0x53,0x7f,0x45
-+	.byte	0xb1,0x64,0x77,0xe0,	0xbb,0x6b,0xae,0x84
-+	.byte	0xfe,0x81,0xa0,0x1c,	0xf9,0x08,0x2b,0x94
-+	.byte	0x70,0x48,0x68,0x58,	0x8f,0x45,0xfd,0x19
-+	.byte	0x94,0xde,0x6c,0x87,	0x52,0x7b,0xf8,0xb7
-+	.byte	0xab,0x73,0xd3,0x23,	0x72,0x4b,0x02,0xe2
-+	.byte	0xe3,0x1f,0x8f,0x57,	0x66,0x55,0xab,0x2a
-+	.byte	0xb2,0xeb,0x28,0x07,	0x2f,0xb5,0xc2,0x03
-+	.byte	0x86,0xc5,0x7b,0x9a,	0xd3,0x37,0x08,0xa5
-+	.byte	0x30,0x28,0x87,0xf2,	0x23,0xbf,0xa5,0xb2
-+	.byte	0x02,0x03,0x6a,0xba,	0xed,0x16,0x82,0x5c
-+	.byte	0x8a,0xcf,0x1c,0x2b,	0xa7,0x79,0xb4,0x92
-+	.byte	0xf3,0x07,0xf2,0xf0,	0x4e,0x69,0xe2,0xa1
-+	.byte	0x65,0xda,0xf4,0xcd,	0x06,0x05,0xbe,0xd5
-+	.byte	0xd1,0x34,0x62,0x1f,	0xc4,0xa6,0xfe,0x8a
-+	.byte	0x34,0x2e,0x53,0x9d,	0xa2,0xf3,0x55,0xa0
-+	.byte	0x05,0x8a,0xe1,0x32,	0xa4,0xf6,0xeb,0x75
-+	.byte	0x0b,0x83,0xec,0x39,	0x40,0x60,0xef,0xaa
-+	.byte	0x5e,0x71,0x9f,0x06,	0xbd,0x6e,0x10,0x51
-+	.byte	0x3e,0x21,0x8a,0xf9,	0x96,0xdd,0x06,0x3d
-+	.byte	0xdd,0x3e,0x05,0xae,	0x4d,0xe6,0xbd,0x46
-+	.byte	0x91,0x54,0x8d,0xb5,	0x71,0xc4,0x5d,0x05
-+	.byte	0x04,0x06,0xd4,0x6f,	0x60,0x50,0x15,0xff
-+	.byte	0x19,0x98,0xfb,0x24,	0xd6,0xbd,0xe9,0x97
-+	.byte	0x89,0x40,0x43,0xcc,	0x67,0xd9,0x9e,0x77
-+	.byte	0xb0,0xe8,0x42,0xbd,	0x07,0x89,0x8b,0x88
-+	.byte	0xe7,0x19,0x5b,0x38,	0x79,0xc8,0xee,0xdb
-+	.byte	0xa1,0x7c,0x0a,0x47,	0x7c,0x42,0x0f,0xe9
-+	.byte	0xf8,0x84,0x1e,0xc9,	0x00,0x00,0x00,0x00
-+	.byte	0x09,0x80,0x86,0x83,	0x32,0x2b,0xed,0x48
-+	.byte	0x1e,0x11,0x70,0xac,	0x6c,0x5a,0x72,0x4e
-+	.byte	0xfd,0x0e,0xff,0xfb,	0x0f,0x85,0x38,0x56
-+	.byte	0x3d,0xae,0xd5,0x1e,	0x36,0x2d,0x39,0x27
-+	.byte	0x0a,0x0f,0xd9,0x64,	0x68,0x5c,0xa6,0x21
-+	.byte	0x9b,0x5b,0x54,0xd1,	0x24,0x36,0x2e,0x3a
-+	.byte	0x0c,0x0a,0x67,0xb1,	0x93,0x57,0xe7,0x0f
-+	.byte	0xb4,0xee,0x96,0xd2,	0x1b,0x9b,0x91,0x9e
-+	.byte	0x80,0xc0,0xc5,0x4f,	0x61,0xdc,0x20,0xa2
-+	.byte	0x5a,0x77,0x4b,0x69,	0x1c,0x12,0x1a,0x16
-+	.byte	0xe2,0x93,0xba,0x0a,	0xc0,0xa0,0x2a,0xe5
-+	.byte	0x3c,0x22,0xe0,0x43,	0x12,0x1b,0x17,0x1d
-+	.byte	0x0e,0x09,0x0d,0x0b,	0xf2,0x8b,0xc7,0xad
-+	.byte	0x2d,0xb6,0xa8,0xb9,	0x14,0x1e,0xa9,0xc8
-+	.byte	0x57,0xf1,0x19,0x85,	0xaf,0x75,0x07,0x4c
-+	.byte	0xee,0x99,0xdd,0xbb,	0xa3,0x7f,0x60,0xfd
-+	.byte	0xf7,0x01,0x26,0x9f,	0x5c,0x72,0xf5,0xbc
-+	.byte	0x44,0x66,0x3b,0xc5,	0x5b,0xfb,0x7e,0x34
-+	.byte	0x8b,0x43,0x29,0x76,	0xcb,0x23,0xc6,0xdc
-+	.byte	0xb6,0xed,0xfc,0x68,	0xb8,0xe4,0xf1,0x63
-+	.byte	0xd7,0x31,0xdc,0xca,	0x42,0x63,0x85,0x10
-+	.byte	0x13,0x97,0x22,0x40,	0x84,0xc6,0x11,0x20
-+	.byte	0x85,0x4a,0x24,0x7d,	0xd2,0xbb,0x3d,0xf8
-+	.byte	0xae,0xf9,0x32,0x11,	0xc7,0x29,0xa1,0x6d
-+	.byte	0x1d,0x9e,0x2f,0x4b,	0xdc,0xb2,0x30,0xf3
-+	.byte	0x0d,0x86,0x52,0xec,	0x77,0xc1,0xe3,0xd0
-+	.byte	0x2b,0xb3,0x16,0x6c,	0xa9,0x70,0xb9,0x99
-+	.byte	0x11,0x94,0x48,0xfa,	0x47,0xe9,0x64,0x22
-+	.byte	0xa8,0xfc,0x8c,0xc4,	0xa0,0xf0,0x3f,0x1a
-+	.byte	0x56,0x7d,0x2c,0xd8,	0x22,0x33,0x90,0xef
-+	.byte	0x87,0x49,0x4e,0xc7,	0xd9,0x38,0xd1,0xc1
-+	.byte	0x8c,0xca,0xa2,0xfe,	0x98,0xd4,0x0b,0x36
-+	.byte	0xa6,0xf5,0x81,0xcf,	0xa5,0x7a,0xde,0x28
-+	.byte	0xda,0xb7,0x8e,0x26,	0x3f,0xad,0xbf,0xa4
-+	.byte	0x2c,0x3a,0x9d,0xe4,	0x50,0x78,0x92,0x0d
-+	.byte	0x6a,0x5f,0xcc,0x9b,	0x54,0x7e,0x46,0x62
-+	.byte	0xf6,0x8d,0x13,0xc2,	0x90,0xd8,0xb8,0xe8
-+	.byte	0x2e,0x39,0xf7,0x5e,	0x82,0xc3,0xaf,0xf5
-+	.byte	0x9f,0x5d,0x80,0xbe,	0x69,0xd0,0x93,0x7c
-+	.byte	0x6f,0xd5,0x2d,0xa9,	0xcf,0x25,0x12,0xb3
-+	.byte	0xc8,0xac,0x99,0x3b,	0x10,0x18,0x7d,0xa7
-+	.byte	0xe8,0x9c,0x63,0x6e,	0xdb,0x3b,0xbb,0x7b
-+	.byte	0xcd,0x26,0x78,0x09,	0x6e,0x59,0x18,0xf4
-+	.byte	0xec,0x9a,0xb7,0x01,	0x83,0x4f,0x9a,0xa8
-+	.byte	0xe6,0x95,0x6e,0x65,	0xaa,0xff,0xe6,0x7e
-+	.byte	0x21,0xbc,0xcf,0x08,	0xef,0x15,0xe8,0xe6
-+	.byte	0xba,0xe7,0x9b,0xd9,	0x4a,0x6f,0x36,0xce
-+	.byte	0xea,0x9f,0x09,0xd4,	0x29,0xb0,0x7c,0xd6
-+	.byte	0x31,0xa4,0xb2,0xaf,	0x2a,0x3f,0x23,0x31
-+	.byte	0xc6,0xa5,0x94,0x30,	0x35,0xa2,0x66,0xc0
-+	.byte	0x74,0x4e,0xbc,0x37,	0xfc,0x82,0xca,0xa6
-+	.byte	0xe0,0x90,0xd0,0xb0,	0x33,0xa7,0xd8,0x15
-+	.byte	0xf1,0x04,0x98,0x4a,	0x41,0xec,0xda,0xf7
-+	.byte	0x7f,0xcd,0x50,0x0e,	0x17,0x91,0xf6,0x2f
-+	.byte	0x76,0x4d,0xd6,0x8d,	0x43,0xef,0xb0,0x4d
-+	.byte	0xcc,0xaa,0x4d,0x54,	0xe4,0x96,0x04,0xdf
-+	.byte	0x9e,0xd1,0xb5,0xe3,	0x4c,0x6a,0x88,0x1b
-+	.byte	0xc1,0x2c,0x1f,0xb8,	0x46,0x65,0x51,0x7f
-+	.byte	0x9d,0x5e,0xea,0x04,	0x01,0x8c,0x35,0x5d
-+	.byte	0xfa,0x87,0x74,0x73,	0xfb,0x0b,0x41,0x2e
-+	.byte	0xb3,0x67,0x1d,0x5a,	0x92,0xdb,0xd2,0x52
-+	.byte	0xe9,0x10,0x56,0x33,	0x6d,0xd6,0x47,0x13
-+	.byte	0x9a,0xd7,0x61,0x8c,	0x37,0xa1,0x0c,0x7a
-+	.byte	0x59,0xf8,0x14,0x8e,	0xeb,0x13,0x3c,0x89
-+	.byte	0xce,0xa9,0x27,0xee,	0xb7,0x61,0xc9,0x35
-+	.byte	0xe1,0x1c,0xe5,0xed,	0x7a,0x47,0xb1,0x3c
-+	.byte	0x9c,0xd2,0xdf,0x59,	0x55,0xf2,0x73,0x3f
-+	.byte	0x18,0x14,0xce,0x79,	0x73,0xc7,0x37,0xbf
-+	.byte	0x53,0xf7,0xcd,0xea,	0x5f,0xfd,0xaa,0x5b
-+	.byte	0xdf,0x3d,0x6f,0x14,	0x78,0x44,0xdb,0x86
-+	.byte	0xca,0xaf,0xf3,0x81,	0xb9,0x68,0xc4,0x3e
-+	.byte	0x38,0x24,0x34,0x2c,	0xc2,0xa3,0x40,0x5f
-+	.byte	0x16,0x1d,0xc3,0x72,	0xbc,0xe2,0x25,0x0c
-+	.byte	0x28,0x3c,0x49,0x8b,	0xff,0x0d,0x95,0x41
-+	.byte	0x39,0xa8,0x01,0x71,	0x08,0x0c,0xb3,0xde
-+	.byte	0xd8,0xb4,0xe4,0x9c,	0x64,0x56,0xc1,0x90
-+	.byte	0x7b,0xcb,0x84,0x61,	0xd5,0x32,0xb6,0x70
-+	.byte	0x48,0x6c,0x5c,0x74,	0xd0,0xb8,0x57,0x42
-+AES_Td4:
-+	.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-+	.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-+	.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-+	.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-+	.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-+	.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-+	.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-+	.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-+	.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-+	.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-+	.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-+	.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-+	.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-+	.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-+	.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-+	.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-+	.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-+	.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-+	.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-+	.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-+	.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-+	.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-+	.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-+	.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-+	.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-+	.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-+	.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-+	.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-+	.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-+	.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-+	.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-+	.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+	.cstring "AES for C64x+, CRYPTOGAMS by "
-+	.align	4
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-ia64.S b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-ia64.S
-new file mode 100644
-index 0000000..f7f1f63
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-ia64.S
-@@ -0,0 +1,1130 @@
-+// Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+//
-+// Licensed under the OpenSSL license (the "License").  You may not use
-+// this file except in compliance with the License.  You can obtain a copy
-+// in the file LICENSE in the source distribution or at
-+// https://www.openssl.org/source/license.html
-+//
-+// ====================================================================
-+// Written by Andy Polyakov  for the OpenSSL
-+// project. Rights for redistribution and usage in source and binary
-+// forms are granted according to the OpenSSL license.
-+// ====================================================================
-+//
-+// What's wrong with compiler generated code? Compiler never uses
-+// variable 'shr' which is pairable with 'extr'/'dep' instructions.
-+// Then it uses 'zxt' which is an I-type, but can be replaced with
-+// 'and' which in turn can be assigned to M-port [there're double as
-+// much M-ports as there're I-ports on Itanium 2]. By sacrificing few
-+// registers for small constants (255, 24 and 16) to be used with
-+// 'shr' and 'and' instructions I can achieve better ILP, Instruction
-+// Level Parallelism, and performance. This code outperforms GCC 3.3
-+// generated code by over factor of 2 (two), GCC 3.4 - by 70% and
-+// HP C - by 40%. Measured best-case scenario, i.e. aligned
-+// big-endian input, ECB timing on Itanium 2 is (18 + 13*rounds)
-+// ticks per block, or 9.25 CPU cycles per byte for 128 bit key.
-+
-+// Version 1.2 mitigates the hazard of cache-timing attacks by
-+// a) compressing S-boxes from 8KB to 2KB+256B, b) scheduling
-+// references to S-boxes for L2 cache latency, c) prefetching T[ed]4
-+// prior last round. As result performance dropped to (26 + 15*rounds)
-+// ticks per block or 11 cycles per byte processed with 128-bit key.
-+// This is ~16% deterioration. For reference Itanium 2 L1 cache has
-+// 64 bytes line size and L2 - 128 bytes...
-+
-+.ident	"aes-ia64.S, version 1.2"
-+.ident	"IA-64 ISA artwork by Andy Polyakov "
-+.explicit
-+.text
-+
-+rk0=r8;     rk1=r9;
-+
-+pfssave=r2;
-+lcsave=r10;
-+prsave=r3;
-+maskff=r11;
-+twenty4=r14;
-+sixteen=r15;
-+
-+te00=r16;   te11=r17;   te22=r18;   te33=r19;
-+te01=r20;   te12=r21;   te23=r22;   te30=r23;
-+te02=r24;   te13=r25;   te20=r26;   te31=r27;
-+te03=r28;   te10=r29;   te21=r30;   te32=r31;
-+
-+// these are rotating...
-+t0=r32;     s0=r33;
-+t1=r34;     s1=r35;
-+t2=r36;     s2=r37;
-+t3=r38;     s3=r39;
-+
-+te0=r40;    te1=r41;    te2=r42;    te3=r43;
-+
-+#if defined(_HPUX_SOURCE) && !defined(_LP64)
-+# define ADDP	addp4
-+#else
-+# define ADDP	add
-+#endif
-+
-+// Offsets from Te0
-+#define TE0	0
-+#define TE2	2
-+#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
-+#define TE1	3
-+#define TE3	1
-+#else
-+#define TE1	1
-+#define TE3	3
-+#endif
-+
-+// This implies that AES_KEY comprises 32-bit key schedule elements
-+// even on LP64 platforms.
-+#ifndef	KSZ
-+# define KSZ	4
-+# define LDKEY	ld4
-+#endif
-+
-+.proc	_ia64_AES_encrypt#
-+// Input:	rk0-rk1
-+//		te0
-+//		te3	as AES_KEY->rounds!!!
-+//		s0-s3
-+//		maskff,twenty4,sixteen
-+// Output:	r16,r20,r24,r28 as s0-s3
-+// Clobber:	r16-r31,rk0-rk1,r32-r43
-+.align	32
-+_ia64_AES_encrypt:
-+	.prologue
-+	.altrp	b6
-+	.body
-+{ .mmi;	alloc	r16=ar.pfs,12,0,0,8
-+	LDKEY	t0=[rk0],2*KSZ
-+	mov	pr.rot=1<<16	}
-+{ .mmi;	LDKEY	t1=[rk1],2*KSZ
-+	add	te1=TE1,te0
-+	add	te3=-3,te3	};;
-+{ .mib;	LDKEY	t2=[rk0],2*KSZ
-+	mov	ar.ec=2		}
-+{ .mib;	LDKEY	t3=[rk1],2*KSZ
-+	add	te2=TE2,te0
-+	brp.loop.imp	.Le_top,.Le_end-16	};;
-+
-+{ .mmi;	xor	s0=s0,t0
-+	xor	s1=s1,t1
-+	mov	ar.lc=te3	}
-+{ .mmi;	xor	s2=s2,t2
-+	xor	s3=s3,t3
-+	add	te3=TE3,te0	};;
-+
-+.align	32
-+.Le_top:
-+{ .mmi;	(p0)	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
-+	(p0)	and	te33=s3,maskff		// 0/0:s3&0xff
-+	(p0)	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
-+{ .mmi; (p0)	LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
-+	(p0)	and	te30=s0,maskff		// 0/1:s0&0xff
-+	(p0)	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
-+{ .mmi;	(p0)	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
-+	(p0)	shladd	te33=te33,3,te3		// 1/0:te0+s0>>24
-+	(p0)	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
-+{ .mmi;	(p0)	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
-+	(p0)	shladd	te30=te30,3,te3		// 1/1:te3+s0
-+	(p0)	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
-+{ .mmi;	(p0)	ld4	te33=[te33]		// 2/0:te3[s3&0xff]
-+	(p0)	shladd	te22=te22,3,te2		// 2/0:te2+s2>>8&0xff
-+	(p0)	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
-+{ .mmi;	(p0)	ld4	te30=[te30]		// 2/1:te3[s0]
-+	(p0)	shladd	te23=te23,3,te2		// 2/1:te2+s3>>8
-+	(p0)	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
-+{ .mmi;	(p0)	ld4	te22=[te22]		// 3/0:te2[s2>>8]
-+	(p0)	shladd	te20=te20,3,te2		// 3/2:te2+s0>>8
-+	(p0)	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
-+{ .mmi;	(p0)	ld4	te23=[te23]		// 3/1:te2[s3>>8]
-+	(p0)	shladd	te00=te00,3,te0		// 3/0:te0+s0>>24
-+	(p0)	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
-+{ .mmi;	(p0)	ld4	te20=[te20]		// 4/2:te2[s0>>8]
-+	(p0)	shladd	te21=te21,3,te2		// 4/3:te3+s2
-+	(p0)	extr.u	te11=s1,16,8	}	// 4/0:s1>>16&0xff
-+{ .mmi;	(p0)	ld4	te00=[te00]		// 4/0:te0[s0>>24]
-+	(p0)	shladd	te01=te01,3,te0		// 4/1:te0+s1>>24
-+	(p0)	shr.u	te13=s3,sixteen	};;	// 4/2:s3>>16
-+{ .mmi;	(p0)	ld4	te21=[te21]		// 5/3:te2[s1>>8]
-+	(p0)	shladd	te11=te11,3,te1		// 5/0:te1+s1>>16
-+	(p0)	extr.u	te12=s2,16,8	}	// 5/1:s2>>16&0xff
-+{ .mmi;	(p0)	ld4	te01=[te01]		// 5/1:te0[s1>>24]
-+	(p0)	shladd	te02=te02,3,te0		// 5/2:te0+s2>>24
-+	(p0)	and	te31=s1,maskff	};;	// 5/2:s1&0xff
-+{ .mmi;	(p0)	ld4	te11=[te11]		// 6/0:te1[s1>>16]
-+	(p0)	shladd	te12=te12,3,te1		// 6/1:te1+s2>>16
-+	(p0)	extr.u	te10=s0,16,8	}	// 6/3:s0>>16&0xff
-+{ .mmi;	(p0)	ld4	te02=[te02]		// 6/2:te0[s2>>24]
-+	(p0)	shladd	te03=te03,3,te0		// 6/3:te1+s0>>16
-+	(p0)	and	te32=s2,maskff	};;	// 6/3:s2&0xff
-+
-+{ .mmi;	(p0)	ld4	te12=[te12]		// 7/1:te1[s2>>16]
-+	(p0)	shladd	te31=te31,3,te3		// 7/2:te3+s1&0xff
-+	(p0)	and	te13=te13,maskff}	// 7/2:s3>>16&0xff
-+{ .mmi;	(p0)	ld4	te03=[te03]		// 7/3:te0[s3>>24]
-+	(p0)	shladd	te32=te32,3,te3		// 7/3:te3+s2
-+	(p0)	xor	t0=t0,te33	};;	// 7/0:
-+{ .mmi;	(p0)	ld4	te31=[te31]		// 8/2:te3[s1]
-+	(p0)	shladd	te13=te13,3,te1		// 8/2:te1+s3>>16
-+	(p0)	xor	t0=t0,te22	}	// 8/0:
-+{ .mmi;	(p0)	ld4	te32=[te32]		// 8/3:te3[s2]
-+	(p0)	shladd	te10=te10,3,te1		// 8/3:te1+s0>>16
-+	(p0)	xor	t1=t1,te30	};;	// 8/1:
-+{ .mmi;	(p0)	ld4	te13=[te13]		// 9/2:te1[s3>>16]
-+	(p0)	ld4	te10=[te10]		// 9/3:te1[s0>>16]
-+	(p0)	xor	t0=t0,te00	};;	// 9/0:		!L2 scheduling
-+{ .mmi;	(p0)	xor	t1=t1,te23		// 10[9]/1:	
-+	(p0)	xor	t2=t2,te20		// 10[9]/2:
-+	(p0)	xor	t3=t3,te21	};;	// 10[9]/3:
-+{ .mmi;	(p0)	xor	t0=t0,te11		// 11[10]/0:done!
-+	(p0)	xor	t1=t1,te01		// 11[10]/1:
-+	(p0)	xor	t2=t2,te02	};;	// 11[10]/2:	!L2 scheduling
-+{ .mmi;	(p0)	xor	t3=t3,te03		// 12[10]/3:
-+	(p16)	cmp.eq	p0,p17=r0,r0 	};;	// 12[10]/clear (p17)
-+{ .mmi;	(p0)	xor	t1=t1,te12		// 13[11]/1:done!
-+	(p0)	xor	t2=t2,te31		// 13[11]/2:
-+	(p0)	xor	t3=t3,te32	}	// 13[11]/3:
-+{ .mmi;	(p17)	add	te0=2048,te0		// 13[11]/
-+	(p17)	add	te1=2048+64-TE1,te1};;	// 13[11]/
-+{ .mib;	(p0)	xor	t2=t2,te13		// 14[12]/2:done!
-+	(p17)	add	te2=2048+128-TE2,te2}	// 14[12]/
-+{ .mib;	(p0)	xor	t3=t3,te10		// 14[12]/3:done!
-+	(p17)	add	te3=2048+192-TE3,te3	// 14[12]/
-+	br.ctop.sptk	.Le_top		};;
-+.Le_end:
-+
-+
-+{ .mmi;	ld8	te12=[te0]		// prefetch Te4
-+	ld8	te31=[te1]	}
-+{ .mmi;	ld8	te10=[te2]
-+	ld8	te32=[te3]	}
-+
-+{ .mmi;	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
-+	and	te33=s3,maskff		// 0/0:s3&0xff
-+	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
-+{ .mmi; LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
-+	and	te30=s0,maskff		// 0/1:s0&0xff
-+	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
-+{ .mmi;	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
-+	add	te33=te33,te0		// 1/0:te0+s0>>24
-+	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
-+{ .mmi;	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
-+	add	te30=te30,te0		// 1/1:te0+s0
-+	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
-+{ .mmi;	ld1	te33=[te33]		// 2/0:te0[s3&0xff]
-+	add	te22=te22,te0		// 2/0:te0+s2>>8&0xff
-+	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
-+{ .mmi;	ld1	te30=[te30]		// 2/1:te0[s0]
-+	add	te23=te23,te0		// 2/1:te0+s3>>8
-+	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
-+{ .mmi;	ld1	te22=[te22]		// 3/0:te0[s2>>8]
-+	add	te20=te20,te0		// 3/2:te0+s0>>8
-+	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
-+{ .mmi;	ld1	te23=[te23]		// 3/1:te0[s3>>8]
-+	add	te00=te00,te0		// 3/0:te0+s0>>24
-+	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
-+{ .mmi;	ld1	te20=[te20]		// 4/2:te0[s0>>8]
-+	add	te21=te21,te0		// 4/3:te0+s2
-+	extr.u	te11=s1,16,8	}	// 4/0:s1>>16&0xff
-+{ .mmi;	ld1	te00=[te00]		// 4/0:te0[s0>>24]
-+	add	te01=te01,te0		// 4/1:te0+s1>>24
-+	shr.u	te13=s3,sixteen	};;	// 4/2:s3>>16
-+{ .mmi;	ld1	te21=[te21]		// 5/3:te0[s1>>8]
-+	add	te11=te11,te0		// 5/0:te0+s1>>16
-+	extr.u	te12=s2,16,8	}	// 5/1:s2>>16&0xff
-+{ .mmi;	ld1	te01=[te01]		// 5/1:te0[s1>>24]
-+	add	te02=te02,te0		// 5/2:te0+s2>>24
-+	and	te31=s1,maskff	};;	// 5/2:s1&0xff
-+{ .mmi;	ld1	te11=[te11]		// 6/0:te0[s1>>16]
-+	add	te12=te12,te0		// 6/1:te0+s2>>16
-+	extr.u	te10=s0,16,8	}	// 6/3:s0>>16&0xff
-+{ .mmi;	ld1	te02=[te02]		// 6/2:te0[s2>>24]
-+	add	te03=te03,te0		// 6/3:te0+s0>>16
-+	and	te32=s2,maskff	};;	// 6/3:s2&0xff
-+
-+{ .mmi;	ld1	te12=[te12]		// 7/1:te0[s2>>16]
-+	add	te31=te31,te0		// 7/2:te0+s1&0xff
-+	dep	te33=te22,te33,8,8}	// 7/0:
-+{ .mmi;	ld1	te03=[te03]		// 7/3:te0[s3>>24]
-+	add	te32=te32,te0		// 7/3:te0+s2
-+	and	te13=te13,maskff};;	// 7/2:s3>>16&0xff
-+{ .mmi;	ld1	te31=[te31]		// 8/2:te0[s1]
-+	add	te13=te13,te0		// 8/2:te0+s3>>16
-+	dep	te30=te23,te30,8,8}	// 8/1:
-+{ .mmi;	ld1	te32=[te32]		// 8/3:te0[s2]
-+	add	te10=te10,te0		// 8/3:te0+s0>>16
-+	shl	te00=te00,twenty4};;	// 8/0:
-+{ .mii;	ld1	te13=[te13]		// 9/2:te0[s3>>16]
-+	dep	te33=te11,te33,16,8	// 9/0:
-+	shl	te01=te01,twenty4};;	// 9/1:
-+{ .mii;	ld1	te10=[te10]		// 10/3:te0[s0>>16]
-+	dep	te31=te20,te31,8,8	// 10/2:
-+	shl	te02=te02,twenty4};;	// 10/2:
-+{ .mii;	xor	t0=t0,te33		// 11/0:
-+	dep	te32=te21,te32,8,8	// 11/3:
-+	shl	te12=te12,sixteen};;	// 11/1:
-+{ .mii;	xor	r16=t0,te00		// 12/0:done!
-+	dep	te31=te13,te31,16,8	// 12/2:
-+	shl	te03=te03,twenty4};;	// 12/3:
-+{ .mmi;	xor	t1=t1,te01		// 13/1:
-+	xor	t2=t2,te02		// 13/2:
-+	dep	te32=te10,te32,16,8};;	// 13/3:
-+{ .mmi;	xor	t1=t1,te30		// 14/1:
-+	xor	r24=t2,te31		// 14/2:done!
-+	xor	t3=t3,te32	};;	// 14/3:
-+{ .mib;	xor	r20=t1,te12		// 15/1:done!
-+	xor	r28=t3,te03		// 15/3:done!
-+	br.ret.sptk	b6	};;
-+.endp	_ia64_AES_encrypt#
-+
-+// void AES_encrypt (const void *in,void *out,const AES_KEY *key);
-+.global	AES_encrypt#
-+.proc	AES_encrypt#
-+.align	32
-+AES_encrypt:
-+	.prologue
-+	.save	ar.pfs,pfssave
-+{ .mmi;	alloc	pfssave=ar.pfs,3,1,12,0
-+	and	out0=3,in0
-+	mov	r3=ip			}
-+{ .mmi;	ADDP	in0=0,in0
-+	mov	loc0=psr.um
-+	ADDP	out11=KSZ*60,in2	};;	// &AES_KEY->rounds
-+
-+{ .mmi;	ld4	out11=[out11]			// AES_KEY->rounds
-+	add	out8=(AES_Te#-AES_encrypt#),r3	// Te0
-+	.save	pr,prsave
-+	mov	prsave=pr		}
-+{ .mmi;	rum	1<<3				// clear um.ac
-+	.save	ar.lc,lcsave
-+	mov	lcsave=ar.lc		};;
-+
-+	.body
-+#if defined(_HPUX_SOURCE)	// HPUX is big-endian, cut 15+15 cycles...
-+{ .mib; cmp.ne	p6,p0=out0,r0
-+	add	out0=4,in0
-+(p6)	br.dpnt.many	.Le_i_unaligned	};;
-+
-+{ .mmi;	ld4	out1=[in0],8		// s0
-+	and	out9=3,in1
-+	mov	twenty4=24		}
-+{ .mmi;	ld4	out3=[out0],8		// s1
-+	ADDP	rk0=0,in2
-+	mov	sixteen=16		};;
-+{ .mmi;	ld4	out5=[in0]		// s2
-+	cmp.ne	p6,p0=out9,r0
-+	mov	maskff=0xff		}
-+{ .mmb;	ld4	out7=[out0]		// s3
-+	ADDP	rk1=KSZ,in2
-+	br.call.sptk.many	b6=_ia64_AES_encrypt	};;
-+
-+{ .mib;	ADDP	in0=4,in1
-+	ADDP	in1=0,in1
-+(p6)	br.spnt	.Le_o_unaligned		};;
-+
-+{ .mii;	mov	psr.um=loc0
-+	mov	ar.pfs=pfssave
-+	mov	ar.lc=lcsave		};;
-+{ .mmi;	st4	[in1]=r16,8		// s0
-+	st4	[in0]=r20,8		// s1
-+	mov	pr=prsave,0x1ffff	};;
-+{ .mmb;	st4	[in1]=r24		// s2
-+	st4	[in0]=r28		// s3
-+	br.ret.sptk.many	b0	};;
-+#endif
-+
-+.align	32
-+.Le_i_unaligned:
-+{ .mmi;	add	out0=1,in0
-+	add	out2=2,in0
-+	add	out4=3,in0	};;
-+{ .mmi;	ld1	r16=[in0],4
-+	ld1	r17=[out0],4	}//;;
-+{ .mmi;	ld1	r18=[out2],4
-+	ld1	out1=[out4],4	};;	// s0
-+{ .mmi;	ld1	r20=[in0],4
-+	ld1	r21=[out0],4	}//;;
-+{ .mmi;	ld1	r22=[out2],4
-+	ld1	out3=[out4],4	};;	// s1
-+{ .mmi;	ld1	r24=[in0],4
-+	ld1	r25=[out0],4	}//;;
-+{ .mmi;	ld1	r26=[out2],4
-+	ld1	out5=[out4],4	};;	// s2
-+{ .mmi;	ld1	r28=[in0]
-+	ld1	r29=[out0]	}//;;
-+{ .mmi;	ld1	r30=[out2]
-+	ld1	out7=[out4]	};;	// s3
-+
-+{ .mii;
-+	dep	out1=r16,out1,24,8	//;;
-+	dep	out3=r20,out3,24,8	}//;;
-+{ .mii;	ADDP	rk0=0,in2
-+	dep	out5=r24,out5,24,8	//;;
-+	dep	out7=r28,out7,24,8	};;
-+{ .mii;	ADDP	rk1=KSZ,in2
-+	dep	out1=r17,out1,16,8	//;;
-+	dep	out3=r21,out3,16,8	}//;;
-+{ .mii;	mov	twenty4=24
-+	dep	out5=r25,out5,16,8	//;;
-+	dep	out7=r29,out7,16,8	};;
-+{ .mii;	mov	sixteen=16
-+	dep	out1=r18,out1,8,8	//;;
-+	dep	out3=r22,out3,8,8	}//;;
-+{ .mii;	mov	maskff=0xff
-+	dep	out5=r26,out5,8,8	//;;
-+	dep	out7=r30,out7,8,8	};;
-+
-+{ .mib;	br.call.sptk.many	b6=_ia64_AES_encrypt	};;
-+
-+.Le_o_unaligned:
-+{ .mii;	ADDP	out0=0,in1
-+	extr.u	r17=r16,8,8			// s0
-+	shr.u	r19=r16,twenty4		}//;;
-+{ .mii;	ADDP	out1=1,in1
-+	extr.u	r18=r16,16,8
-+	shr.u	r23=r20,twenty4		}//;;	// s1
-+{ .mii;	ADDP	out2=2,in1
-+	extr.u	r21=r20,8,8
-+	shr.u	r22=r20,sixteen		}//;;
-+{ .mii;	ADDP	out3=3,in1
-+	extr.u	r25=r24,8,8			// s2
-+	shr.u	r27=r24,twenty4		};;
-+{ .mii;	st1	[out3]=r16,4
-+	extr.u	r26=r24,16,8
-+	shr.u	r31=r28,twenty4		}//;;	// s3
-+{ .mii;	st1	[out2]=r17,4
-+	extr.u	r29=r28,8,8
-+	shr.u	r30=r28,sixteen		}//;;
-+
-+{ .mmi;	st1	[out1]=r18,4
-+	st1	[out0]=r19,4		};;
-+{ .mmi;	st1	[out3]=r20,4
-+	st1	[out2]=r21,4		}//;;
-+{ .mmi;	st1	[out1]=r22,4
-+	st1	[out0]=r23,4		};;
-+{ .mmi;	st1	[out3]=r24,4
-+	st1	[out2]=r25,4
-+	mov	pr=prsave,0x1ffff	}//;;
-+{ .mmi;	st1	[out1]=r26,4
-+	st1	[out0]=r27,4
-+	mov	ar.pfs=pfssave		};;
-+{ .mmi;	st1	[out3]=r28
-+	st1	[out2]=r29
-+	mov	ar.lc=lcsave		}//;;
-+{ .mmi;	st1	[out1]=r30
-+	st1	[out0]=r31		}
-+{ .mfb;	mov	psr.um=loc0			// restore user mask
-+	br.ret.sptk.many	b0	};;
-+.endp	AES_encrypt#
-+
-+// *AES_decrypt are autogenerated by the following script:
-+#if 0
-+#!/usr/bin/env perl
-+print "// *AES_decrypt are autogenerated by the following script:\n#if 0\n";
-+open(PROG,'<'.$0); while() { print; } close(PROG);
-+print "#endif\n";
-+while(<>) {
-+	$process=1	if (/\.proc\s+_ia64_AES_encrypt/);
-+	next		if (!$process);
-+
-+	#s/te00=s0/td00=s0/;	s/te00/td00/g;
-+	s/te11=s1/td13=s3/;	s/te11/td13/g;
-+	#s/te22=s2/td22=s2/;	s/te22/td22/g;
-+	s/te33=s3/td31=s1/;	s/te33/td31/g;
-+
-+	#s/te01=s1/td01=s1/;	s/te01/td01/g;
-+	s/te12=s2/td10=s0/;	s/te12/td10/g;
-+	#s/te23=s3/td23=s3/;	s/te23/td23/g;
-+	s/te30=s0/td32=s2/;	s/te30/td32/g;
-+
-+	#s/te02=s2/td02=s2/;	s/te02/td02/g;
-+	s/te13=s3/td11=s1/;	s/te13/td11/g;
-+	#s/te20=s0/td20=s0/;	s/te20/td20/g;
-+	s/te31=s1/td33=s3/;	s/te31/td33/g;
-+
-+	#s/te03=s3/td03=s3/;	s/te03/td03/g;
-+	s/te10=s0/td12=s2/;	s/te10/td12/g;
-+	#s/te21=s1/td21=s1/;	s/te21/td21/g;
-+	s/te32=s2/td30=s0/;	s/te32/td30/g;
-+
-+	s/td/te/g;
-+
-+	s/AES_encrypt/AES_decrypt/g;
-+	s/\.Le_/.Ld_/g;
-+	s/AES_Te#/AES_Td#/g;
-+
-+	print;
-+
-+	exit		if (/\.endp\s+AES_decrypt/);
-+}
-+#endif
-+.proc	_ia64_AES_decrypt#
-+// Input:	rk0-rk1
-+//		te0
-+//		te3	as AES_KEY->rounds!!!
-+//		s0-s3
-+//		maskff,twenty4,sixteen
-+// Output:	r16,r20,r24,r28 as s0-s3
-+// Clobber:	r16-r31,rk0-rk1,r32-r43
-+.align	32
-+_ia64_AES_decrypt:
-+	.prologue
-+	.altrp	b6
-+	.body
-+{ .mmi;	alloc	r16=ar.pfs,12,0,0,8
-+	LDKEY	t0=[rk0],2*KSZ
-+	mov	pr.rot=1<<16	}
-+{ .mmi;	LDKEY	t1=[rk1],2*KSZ
-+	add	te1=TE1,te0
-+	add	te3=-3,te3	};;
-+{ .mib;	LDKEY	t2=[rk0],2*KSZ
-+	mov	ar.ec=2		}
-+{ .mib;	LDKEY	t3=[rk1],2*KSZ
-+	add	te2=TE2,te0
-+	brp.loop.imp	.Ld_top,.Ld_end-16	};;
-+
-+{ .mmi;	xor	s0=s0,t0
-+	xor	s1=s1,t1
-+	mov	ar.lc=te3	}
-+{ .mmi;	xor	s2=s2,t2
-+	xor	s3=s3,t3
-+	add	te3=TE3,te0	};;
-+
-+.align	32
-+.Ld_top:
-+{ .mmi;	(p0)	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
-+	(p0)	and	te31=s1,maskff		// 0/0:s3&0xff
-+	(p0)	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
-+{ .mmi; (p0)	LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
-+	(p0)	and	te32=s2,maskff		// 0/1:s0&0xff
-+	(p0)	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
-+{ .mmi;	(p0)	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
-+	(p0)	shladd	te31=te31,3,te3		// 1/0:te0+s0>>24
-+	(p0)	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
-+{ .mmi;	(p0)	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
-+	(p0)	shladd	te32=te32,3,te3		// 1/1:te3+s0
-+	(p0)	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
-+{ .mmi;	(p0)	ld4	te31=[te31]		// 2/0:te3[s3&0xff]
-+	(p0)	shladd	te22=te22,3,te2		// 2/0:te2+s2>>8&0xff
-+	(p0)	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
-+{ .mmi;	(p0)	ld4	te32=[te32]		// 2/1:te3[s0]
-+	(p0)	shladd	te23=te23,3,te2		// 2/1:te2+s3>>8
-+	(p0)	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
-+{ .mmi;	(p0)	ld4	te22=[te22]		// 3/0:te2[s2>>8]
-+	(p0)	shladd	te20=te20,3,te2		// 3/2:te2+s0>>8
-+	(p0)	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
-+{ .mmi;	(p0)	ld4	te23=[te23]		// 3/1:te2[s3>>8]
-+	(p0)	shladd	te00=te00,3,te0		// 3/0:te0+s0>>24
-+	(p0)	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
-+{ .mmi;	(p0)	ld4	te20=[te20]		// 4/2:te2[s0>>8]
-+	(p0)	shladd	te21=te21,3,te2		// 4/3:te3+s2
-+	(p0)	extr.u	te13=s3,16,8	}	// 4/0:s1>>16&0xff
-+{ .mmi;	(p0)	ld4	te00=[te00]		// 4/0:te0[s0>>24]
-+	(p0)	shladd	te01=te01,3,te0		// 4/1:te0+s1>>24
-+	(p0)	shr.u	te11=s1,sixteen	};;	// 4/2:s3>>16
-+{ .mmi;	(p0)	ld4	te21=[te21]		// 5/3:te2[s1>>8]
-+	(p0)	shladd	te13=te13,3,te1		// 5/0:te1+s1>>16
-+	(p0)	extr.u	te10=s0,16,8	}	// 5/1:s2>>16&0xff
-+{ .mmi;	(p0)	ld4	te01=[te01]		// 5/1:te0[s1>>24]
-+	(p0)	shladd	te02=te02,3,te0		// 5/2:te0+s2>>24
-+	(p0)	and	te33=s3,maskff	};;	// 5/2:s1&0xff
-+{ .mmi;	(p0)	ld4	te13=[te13]		// 6/0:te1[s1>>16]
-+	(p0)	shladd	te10=te10,3,te1		// 6/1:te1+s2>>16
-+	(p0)	extr.u	te12=s2,16,8	}	// 6/3:s0>>16&0xff
-+{ .mmi;	(p0)	ld4	te02=[te02]		// 6/2:te0[s2>>24]
-+	(p0)	shladd	te03=te03,3,te0		// 6/3:te1+s0>>16
-+	(p0)	and	te30=s0,maskff	};;	// 6/3:s2&0xff
-+
-+{ .mmi;	(p0)	ld4	te10=[te10]		// 7/1:te1[s2>>16]
-+	(p0)	shladd	te33=te33,3,te3		// 7/2:te3+s1&0xff
-+	(p0)	and	te11=te11,maskff}	// 7/2:s3>>16&0xff
-+{ .mmi;	(p0)	ld4	te03=[te03]		// 7/3:te0[s3>>24]
-+	(p0)	shladd	te30=te30,3,te3		// 7/3:te3+s2
-+	(p0)	xor	t0=t0,te31	};;	// 7/0:
-+{ .mmi;	(p0)	ld4	te33=[te33]		// 8/2:te3[s1]
-+	(p0)	shladd	te11=te11,3,te1		// 8/2:te1+s3>>16
-+	(p0)	xor	t0=t0,te22	}	// 8/0:
-+{ .mmi;	(p0)	ld4	te30=[te30]		// 8/3:te3[s2]
-+	(p0)	shladd	te12=te12,3,te1		// 8/3:te1+s0>>16
-+	(p0)	xor	t1=t1,te32	};;	// 8/1:
-+{ .mmi;	(p0)	ld4	te11=[te11]		// 9/2:te1[s3>>16]
-+	(p0)	ld4	te12=[te12]		// 9/3:te1[s0>>16]
-+	(p0)	xor	t0=t0,te00	};;	// 9/0:		!L2 scheduling
-+{ .mmi;	(p0)	xor	t1=t1,te23		// 10[9]/1:	
-+	(p0)	xor	t2=t2,te20		// 10[9]/2:
-+	(p0)	xor	t3=t3,te21	};;	// 10[9]/3:
-+{ .mmi;	(p0)	xor	t0=t0,te13		// 11[10]/0:done!
-+	(p0)	xor	t1=t1,te01		// 11[10]/1:
-+	(p0)	xor	t2=t2,te02	};;	// 11[10]/2:	!L2 scheduling
-+{ .mmi;	(p0)	xor	t3=t3,te03		// 12[10]/3:
-+	(p16)	cmp.eq	p0,p17=r0,r0 	};;	// 12[10]/clear (p17)
-+{ .mmi;	(p0)	xor	t1=t1,te10		// 13[11]/1:done!
-+	(p0)	xor	t2=t2,te33		// 13[11]/2:
-+	(p0)	xor	t3=t3,te30	}	// 13[11]/3:
-+{ .mmi;	(p17)	add	te0=2048,te0		// 13[11]/
-+	(p17)	add	te1=2048+64-TE1,te1};;	// 13[11]/
-+{ .mib;	(p0)	xor	t2=t2,te11		// 14[12]/2:done!
-+	(p17)	add	te2=2048+128-TE2,te2}	// 14[12]/
-+{ .mib;	(p0)	xor	t3=t3,te12		// 14[12]/3:done!
-+	(p17)	add	te3=2048+192-TE3,te3	// 14[12]/
-+	br.ctop.sptk	.Ld_top		};;
-+.Ld_end:
-+
-+
-+{ .mmi;	ld8	te10=[te0]		// prefetch Td4
-+	ld8	te33=[te1]	}
-+{ .mmi;	ld8	te12=[te2]
-+	ld8	te30=[te3]	}
-+
-+{ .mmi;	LDKEY	t0=[rk0],2*KSZ		// 0/0:rk[0]
-+	and	te31=s1,maskff		// 0/0:s3&0xff
-+	extr.u	te22=s2,8,8	}	// 0/0:s2>>8&0xff
-+{ .mmi; LDKEY	t1=[rk1],2*KSZ		// 0/1:rk[1]
-+	and	te32=s2,maskff		// 0/1:s0&0xff
-+	shr.u	te00=s0,twenty4	};;	// 0/0:s0>>24
-+{ .mmi;	LDKEY	t2=[rk0],2*KSZ		// 1/2:rk[2]
-+	add	te31=te31,te0		// 1/0:te0+s0>>24
-+	extr.u	te23=s3,8,8	}	// 1/1:s3>>8&0xff
-+{ .mmi;	LDKEY	t3=[rk1],2*KSZ		// 1/3:rk[3]
-+	add	te32=te32,te0		// 1/1:te0+s0
-+	shr.u	te01=s1,twenty4	};;	// 1/1:s1>>24
-+{ .mmi;	ld1	te31=[te31]		// 2/0:te0[s3&0xff]
-+	add	te22=te22,te0		// 2/0:te0+s2>>8&0xff
-+	extr.u	te20=s0,8,8	}	// 2/2:s0>>8&0xff
-+{ .mmi;	ld1	te32=[te32]		// 2/1:te0[s0]
-+	add	te23=te23,te0		// 2/1:te0+s3>>8
-+	shr.u	te02=s2,twenty4	};;	// 2/2:s2>>24
-+{ .mmi;	ld1	te22=[te22]		// 3/0:te0[s2>>8]
-+	add	te20=te20,te0		// 3/2:te0+s0>>8
-+	extr.u	te21=s1,8,8	}	// 3/3:s1>>8&0xff
-+{ .mmi;	ld1	te23=[te23]		// 3/1:te0[s3>>8]
-+	add	te00=te00,te0		// 3/0:te0+s0>>24
-+	shr.u	te03=s3,twenty4	};;	// 3/3:s3>>24
-+{ .mmi;	ld1	te20=[te20]		// 4/2:te0[s0>>8]
-+	add	te21=te21,te0		// 4/3:te0+s2
-+	extr.u	te13=s3,16,8	}	// 4/0:s1>>16&0xff
-+{ .mmi;	ld1	te00=[te00]		// 4/0:te0[s0>>24]
-+	add	te01=te01,te0		// 4/1:te0+s1>>24
-+	shr.u	te11=s1,sixteen	};;	// 4/2:s3>>16
-+{ .mmi;	ld1	te21=[te21]		// 5/3:te0[s1>>8]
-+	add	te13=te13,te0		// 5/0:te0+s1>>16
-+	extr.u	te10=s0,16,8	}	// 5/1:s2>>16&0xff
-+{ .mmi;	ld1	te01=[te01]		// 5/1:te0[s1>>24]
-+	add	te02=te02,te0		// 5/2:te0+s2>>24
-+	and	te33=s3,maskff	};;	// 5/2:s1&0xff
-+{ .mmi;	ld1	te13=[te13]		// 6/0:te0[s1>>16]
-+	add	te10=te10,te0		// 6/1:te0+s2>>16
-+	extr.u	te12=s2,16,8	}	// 6/3:s0>>16&0xff
-+{ .mmi;	ld1	te02=[te02]		// 6/2:te0[s2>>24]
-+	add	te03=te03,te0		// 6/3:te0+s0>>16
-+	and	te30=s0,maskff	};;	// 6/3:s2&0xff
-+
-+{ .mmi;	ld1	te10=[te10]		// 7/1:te0[s2>>16]
-+	add	te33=te33,te0		// 7/2:te0+s1&0xff
-+	dep	te31=te22,te31,8,8}	// 7/0:
-+{ .mmi;	ld1	te03=[te03]		// 7/3:te0[s3>>24]
-+	add	te30=te30,te0		// 7/3:te0+s2
-+	and	te11=te11,maskff};;	// 7/2:s3>>16&0xff
-+{ .mmi;	ld1	te33=[te33]		// 8/2:te0[s1]
-+	add	te11=te11,te0		// 8/2:te0+s3>>16
-+	dep	te32=te23,te32,8,8}	// 8/1:
-+{ .mmi;	ld1	te30=[te30]		// 8/3:te0[s2]
-+	add	te12=te12,te0		// 8/3:te0+s0>>16
-+	shl	te00=te00,twenty4};;	// 8/0:
-+{ .mii;	ld1	te11=[te11]		// 9/2:te0[s3>>16]
-+	dep	te31=te13,te31,16,8	// 9/0:
-+	shl	te01=te01,twenty4};;	// 9/1:
-+{ .mii;	ld1	te12=[te12]		// 10/3:te0[s0>>16]
-+	dep	te33=te20,te33,8,8	// 10/2:
-+	shl	te02=te02,twenty4};;	// 10/2:
-+{ .mii;	xor	t0=t0,te31		// 11/0:
-+	dep	te30=te21,te30,8,8	// 11/3:
-+	shl	te10=te10,sixteen};;	// 11/1:
-+{ .mii;	xor	r16=t0,te00		// 12/0:done!
-+	dep	te33=te11,te33,16,8	// 12/2:
-+	shl	te03=te03,twenty4};;	// 12/3:
-+{ .mmi;	xor	t1=t1,te01		// 13/1:
-+	xor	t2=t2,te02		// 13/2:
-+	dep	te30=te12,te30,16,8};;	// 13/3:
-+{ .mmi;	xor	t1=t1,te32		// 14/1:
-+	xor	r24=t2,te33		// 14/2:done!
-+	xor	t3=t3,te30	};;	// 14/3:
-+{ .mib;	xor	r20=t1,te10		// 15/1:done!
-+	xor	r28=t3,te03		// 15/3:done!
-+	br.ret.sptk	b6	};;
-+.endp	_ia64_AES_decrypt#
-+
-+// void AES_decrypt (const void *in,void *out,const AES_KEY *key);
-+.global	AES_decrypt#
-+.proc	AES_decrypt#
-+.align	32
-+AES_decrypt:
-+	.prologue
-+	.save	ar.pfs,pfssave
-+{ .mmi;	alloc	pfssave=ar.pfs,3,1,12,0
-+	and	out0=3,in0
-+	mov	r3=ip			}
-+{ .mmi;	ADDP	in0=0,in0
-+	mov	loc0=psr.um
-+	ADDP	out11=KSZ*60,in2	};;	// &AES_KEY->rounds
-+
-+{ .mmi;	ld4	out11=[out11]			// AES_KEY->rounds
-+	add	out8=(AES_Td#-AES_decrypt#),r3	// Te0
-+	.save	pr,prsave
-+	mov	prsave=pr		}
-+{ .mmi;	rum	1<<3				// clear um.ac
-+	.save	ar.lc,lcsave
-+	mov	lcsave=ar.lc		};;
-+
-+	.body
-+#if defined(_HPUX_SOURCE)	// HPUX is big-endian, cut 15+15 cycles...
-+{ .mib; cmp.ne	p6,p0=out0,r0
-+	add	out0=4,in0
-+(p6)	br.dpnt.many	.Ld_i_unaligned	};;
-+
-+{ .mmi;	ld4	out1=[in0],8		// s0
-+	and	out9=3,in1
-+	mov	twenty4=24		}
-+{ .mmi;	ld4	out3=[out0],8		// s1
-+	ADDP	rk0=0,in2
-+	mov	sixteen=16		};;
-+{ .mmi;	ld4	out5=[in0]		// s2
-+	cmp.ne	p6,p0=out9,r0
-+	mov	maskff=0xff		}
-+{ .mmb;	ld4	out7=[out0]		// s3
-+	ADDP	rk1=KSZ,in2
-+	br.call.sptk.many	b6=_ia64_AES_decrypt	};;
-+
-+{ .mib;	ADDP	in0=4,in1
-+	ADDP	in1=0,in1
-+(p6)	br.spnt	.Ld_o_unaligned		};;
-+
-+{ .mii;	mov	psr.um=loc0
-+	mov	ar.pfs=pfssave
-+	mov	ar.lc=lcsave		};;
-+{ .mmi;	st4	[in1]=r16,8		// s0
-+	st4	[in0]=r20,8		// s1
-+	mov	pr=prsave,0x1ffff	};;
-+{ .mmb;	st4	[in1]=r24		// s2
-+	st4	[in0]=r28		// s3
-+	br.ret.sptk.many	b0	};;
-+#endif
-+
-+.align	32
-+.Ld_i_unaligned:
-+{ .mmi;	add	out0=1,in0
-+	add	out2=2,in0
-+	add	out4=3,in0	};;
-+{ .mmi;	ld1	r16=[in0],4
-+	ld1	r17=[out0],4	}//;;
-+{ .mmi;	ld1	r18=[out2],4
-+	ld1	out1=[out4],4	};;	// s0
-+{ .mmi;	ld1	r20=[in0],4
-+	ld1	r21=[out0],4	}//;;
-+{ .mmi;	ld1	r22=[out2],4
-+	ld1	out3=[out4],4	};;	// s1
-+{ .mmi;	ld1	r24=[in0],4
-+	ld1	r25=[out0],4	}//;;
-+{ .mmi;	ld1	r26=[out2],4
-+	ld1	out5=[out4],4	};;	// s2
-+{ .mmi;	ld1	r28=[in0]
-+	ld1	r29=[out0]	}//;;
-+{ .mmi;	ld1	r30=[out2]
-+	ld1	out7=[out4]	};;	// s3
-+
-+{ .mii;
-+	dep	out1=r16,out1,24,8	//;;
-+	dep	out3=r20,out3,24,8	}//;;
-+{ .mii;	ADDP	rk0=0,in2
-+	dep	out5=r24,out5,24,8	//;;
-+	dep	out7=r28,out7,24,8	};;
-+{ .mii;	ADDP	rk1=KSZ,in2
-+	dep	out1=r17,out1,16,8	//;;
-+	dep	out3=r21,out3,16,8	}//;;
-+{ .mii;	mov	twenty4=24
-+	dep	out5=r25,out5,16,8	//;;
-+	dep	out7=r29,out7,16,8	};;
-+{ .mii;	mov	sixteen=16
-+	dep	out1=r18,out1,8,8	//;;
-+	dep	out3=r22,out3,8,8	}//;;
-+{ .mii;	mov	maskff=0xff
-+	dep	out5=r26,out5,8,8	//;;
-+	dep	out7=r30,out7,8,8	};;
-+
-+{ .mib;	br.call.sptk.many	b6=_ia64_AES_decrypt	};;
-+
-+.Ld_o_unaligned:
-+{ .mii;	ADDP	out0=0,in1
-+	extr.u	r17=r16,8,8			// s0
-+	shr.u	r19=r16,twenty4		}//;;
-+{ .mii;	ADDP	out1=1,in1
-+	extr.u	r18=r16,16,8
-+	shr.u	r23=r20,twenty4		}//;;	// s1
-+{ .mii;	ADDP	out2=2,in1
-+	extr.u	r21=r20,8,8
-+	shr.u	r22=r20,sixteen		}//;;
-+{ .mii;	ADDP	out3=3,in1
-+	extr.u	r25=r24,8,8			// s2
-+	shr.u	r27=r24,twenty4		};;
-+{ .mii;	st1	[out3]=r16,4
-+	extr.u	r26=r24,16,8
-+	shr.u	r31=r28,twenty4		}//;;	// s3
-+{ .mii;	st1	[out2]=r17,4
-+	extr.u	r29=r28,8,8
-+	shr.u	r30=r28,sixteen		}//;;
-+
-+{ .mmi;	st1	[out1]=r18,4
-+	st1	[out0]=r19,4		};;
-+{ .mmi;	st1	[out3]=r20,4
-+	st1	[out2]=r21,4		}//;;
-+{ .mmi;	st1	[out1]=r22,4
-+	st1	[out0]=r23,4		};;
-+{ .mmi;	st1	[out3]=r24,4
-+	st1	[out2]=r25,4
-+	mov	pr=prsave,0x1ffff	}//;;
-+{ .mmi;	st1	[out1]=r26,4
-+	st1	[out0]=r27,4
-+	mov	ar.pfs=pfssave		};;
-+{ .mmi;	st1	[out3]=r28
-+	st1	[out2]=r29
-+	mov	ar.lc=lcsave		}//;;
-+{ .mmi;	st1	[out1]=r30
-+	st1	[out0]=r31		}
-+{ .mfb;	mov	psr.um=loc0			// restore user mask
-+	br.ret.sptk.many	b0	};;
-+.endp	AES_decrypt#
-+
-+// leave it in .text segment...
-+.align	64
-+.global	AES_Te#
-+.type	AES_Te#,@object
-+AES_Te:	data4	0xc66363a5,0xc66363a5, 0xf87c7c84,0xf87c7c84
-+	data4	0xee777799,0xee777799, 0xf67b7b8d,0xf67b7b8d
-+	data4	0xfff2f20d,0xfff2f20d, 0xd66b6bbd,0xd66b6bbd
-+	data4	0xde6f6fb1,0xde6f6fb1, 0x91c5c554,0x91c5c554
-+	data4	0x60303050,0x60303050, 0x02010103,0x02010103
-+	data4	0xce6767a9,0xce6767a9, 0x562b2b7d,0x562b2b7d
-+	data4	0xe7fefe19,0xe7fefe19, 0xb5d7d762,0xb5d7d762
-+	data4	0x4dababe6,0x4dababe6, 0xec76769a,0xec76769a
-+	data4	0x8fcaca45,0x8fcaca45, 0x1f82829d,0x1f82829d
-+	data4	0x89c9c940,0x89c9c940, 0xfa7d7d87,0xfa7d7d87
-+	data4	0xeffafa15,0xeffafa15, 0xb25959eb,0xb25959eb
-+	data4	0x8e4747c9,0x8e4747c9, 0xfbf0f00b,0xfbf0f00b
-+	data4	0x41adadec,0x41adadec, 0xb3d4d467,0xb3d4d467
-+	data4	0x5fa2a2fd,0x5fa2a2fd, 0x45afafea,0x45afafea
-+	data4	0x239c9cbf,0x239c9cbf, 0x53a4a4f7,0x53a4a4f7
-+	data4	0xe4727296,0xe4727296, 0x9bc0c05b,0x9bc0c05b
-+	data4	0x75b7b7c2,0x75b7b7c2, 0xe1fdfd1c,0xe1fdfd1c
-+	data4	0x3d9393ae,0x3d9393ae, 0x4c26266a,0x4c26266a
-+	data4	0x6c36365a,0x6c36365a, 0x7e3f3f41,0x7e3f3f41
-+	data4	0xf5f7f702,0xf5f7f702, 0x83cccc4f,0x83cccc4f
-+	data4	0x6834345c,0x6834345c, 0x51a5a5f4,0x51a5a5f4
-+	data4	0xd1e5e534,0xd1e5e534, 0xf9f1f108,0xf9f1f108
-+	data4	0xe2717193,0xe2717193, 0xabd8d873,0xabd8d873
-+	data4	0x62313153,0x62313153, 0x2a15153f,0x2a15153f
-+	data4	0x0804040c,0x0804040c, 0x95c7c752,0x95c7c752
-+	data4	0x46232365,0x46232365, 0x9dc3c35e,0x9dc3c35e
-+	data4	0x30181828,0x30181828, 0x379696a1,0x379696a1
-+	data4	0x0a05050f,0x0a05050f, 0x2f9a9ab5,0x2f9a9ab5
-+	data4	0x0e070709,0x0e070709, 0x24121236,0x24121236
-+	data4	0x1b80809b,0x1b80809b, 0xdfe2e23d,0xdfe2e23d
-+	data4	0xcdebeb26,0xcdebeb26, 0x4e272769,0x4e272769
-+	data4	0x7fb2b2cd,0x7fb2b2cd, 0xea75759f,0xea75759f
-+	data4	0x1209091b,0x1209091b, 0x1d83839e,0x1d83839e
-+	data4	0x582c2c74,0x582c2c74, 0x341a1a2e,0x341a1a2e
-+	data4	0x361b1b2d,0x361b1b2d, 0xdc6e6eb2,0xdc6e6eb2
-+	data4	0xb45a5aee,0xb45a5aee, 0x5ba0a0fb,0x5ba0a0fb
-+	data4	0xa45252f6,0xa45252f6, 0x763b3b4d,0x763b3b4d
-+	data4	0xb7d6d661,0xb7d6d661, 0x7db3b3ce,0x7db3b3ce
-+	data4	0x5229297b,0x5229297b, 0xdde3e33e,0xdde3e33e
-+	data4	0x5e2f2f71,0x5e2f2f71, 0x13848497,0x13848497
-+	data4	0xa65353f5,0xa65353f5, 0xb9d1d168,0xb9d1d168
-+	data4	0x00000000,0x00000000, 0xc1eded2c,0xc1eded2c
-+	data4	0x40202060,0x40202060, 0xe3fcfc1f,0xe3fcfc1f
-+	data4	0x79b1b1c8,0x79b1b1c8, 0xb65b5bed,0xb65b5bed
-+	data4	0xd46a6abe,0xd46a6abe, 0x8dcbcb46,0x8dcbcb46
-+	data4	0x67bebed9,0x67bebed9, 0x7239394b,0x7239394b
-+	data4	0x944a4ade,0x944a4ade, 0x984c4cd4,0x984c4cd4
-+	data4	0xb05858e8,0xb05858e8, 0x85cfcf4a,0x85cfcf4a
-+	data4	0xbbd0d06b,0xbbd0d06b, 0xc5efef2a,0xc5efef2a
-+	data4	0x4faaaae5,0x4faaaae5, 0xedfbfb16,0xedfbfb16
-+	data4	0x864343c5,0x864343c5, 0x9a4d4dd7,0x9a4d4dd7
-+	data4	0x66333355,0x66333355, 0x11858594,0x11858594
-+	data4	0x8a4545cf,0x8a4545cf, 0xe9f9f910,0xe9f9f910
-+	data4	0x04020206,0x04020206, 0xfe7f7f81,0xfe7f7f81
-+	data4	0xa05050f0,0xa05050f0, 0x783c3c44,0x783c3c44
-+	data4	0x259f9fba,0x259f9fba, 0x4ba8a8e3,0x4ba8a8e3
-+	data4	0xa25151f3,0xa25151f3, 0x5da3a3fe,0x5da3a3fe
-+	data4	0x804040c0,0x804040c0, 0x058f8f8a,0x058f8f8a
-+	data4	0x3f9292ad,0x3f9292ad, 0x219d9dbc,0x219d9dbc
-+	data4	0x70383848,0x70383848, 0xf1f5f504,0xf1f5f504
-+	data4	0x63bcbcdf,0x63bcbcdf, 0x77b6b6c1,0x77b6b6c1
-+	data4	0xafdada75,0xafdada75, 0x42212163,0x42212163
-+	data4	0x20101030,0x20101030, 0xe5ffff1a,0xe5ffff1a
-+	data4	0xfdf3f30e,0xfdf3f30e, 0xbfd2d26d,0xbfd2d26d
-+	data4	0x81cdcd4c,0x81cdcd4c, 0x180c0c14,0x180c0c14
-+	data4	0x26131335,0x26131335, 0xc3ecec2f,0xc3ecec2f
-+	data4	0xbe5f5fe1,0xbe5f5fe1, 0x359797a2,0x359797a2
-+	data4	0x884444cc,0x884444cc, 0x2e171739,0x2e171739
-+	data4	0x93c4c457,0x93c4c457, 0x55a7a7f2,0x55a7a7f2
-+	data4	0xfc7e7e82,0xfc7e7e82, 0x7a3d3d47,0x7a3d3d47
-+	data4	0xc86464ac,0xc86464ac, 0xba5d5de7,0xba5d5de7
-+	data4	0x3219192b,0x3219192b, 0xe6737395,0xe6737395
-+	data4	0xc06060a0,0xc06060a0, 0x19818198,0x19818198
-+	data4	0x9e4f4fd1,0x9e4f4fd1, 0xa3dcdc7f,0xa3dcdc7f
-+	data4	0x44222266,0x44222266, 0x542a2a7e,0x542a2a7e
-+	data4	0x3b9090ab,0x3b9090ab, 0x0b888883,0x0b888883
-+	data4	0x8c4646ca,0x8c4646ca, 0xc7eeee29,0xc7eeee29
-+	data4	0x6bb8b8d3,0x6bb8b8d3, 0x2814143c,0x2814143c
-+	data4	0xa7dede79,0xa7dede79, 0xbc5e5ee2,0xbc5e5ee2
-+	data4	0x160b0b1d,0x160b0b1d, 0xaddbdb76,0xaddbdb76
-+	data4	0xdbe0e03b,0xdbe0e03b, 0x64323256,0x64323256
-+	data4	0x743a3a4e,0x743a3a4e, 0x140a0a1e,0x140a0a1e
-+	data4	0x924949db,0x924949db, 0x0c06060a,0x0c06060a
-+	data4	0x4824246c,0x4824246c, 0xb85c5ce4,0xb85c5ce4
-+	data4	0x9fc2c25d,0x9fc2c25d, 0xbdd3d36e,0xbdd3d36e
-+	data4	0x43acacef,0x43acacef, 0xc46262a6,0xc46262a6
-+	data4	0x399191a8,0x399191a8, 0x319595a4,0x319595a4
-+	data4	0xd3e4e437,0xd3e4e437, 0xf279798b,0xf279798b
-+	data4	0xd5e7e732,0xd5e7e732, 0x8bc8c843,0x8bc8c843
-+	data4	0x6e373759,0x6e373759, 0xda6d6db7,0xda6d6db7
-+	data4	0x018d8d8c,0x018d8d8c, 0xb1d5d564,0xb1d5d564
-+	data4	0x9c4e4ed2,0x9c4e4ed2, 0x49a9a9e0,0x49a9a9e0
-+	data4	0xd86c6cb4,0xd86c6cb4, 0xac5656fa,0xac5656fa
-+	data4	0xf3f4f407,0xf3f4f407, 0xcfeaea25,0xcfeaea25
-+	data4	0xca6565af,0xca6565af, 0xf47a7a8e,0xf47a7a8e
-+	data4	0x47aeaee9,0x47aeaee9, 0x10080818,0x10080818
-+	data4	0x6fbabad5,0x6fbabad5, 0xf0787888,0xf0787888
-+	data4	0x4a25256f,0x4a25256f, 0x5c2e2e72,0x5c2e2e72
-+	data4	0x381c1c24,0x381c1c24, 0x57a6a6f1,0x57a6a6f1
-+	data4	0x73b4b4c7,0x73b4b4c7, 0x97c6c651,0x97c6c651
-+	data4	0xcbe8e823,0xcbe8e823, 0xa1dddd7c,0xa1dddd7c
-+	data4	0xe874749c,0xe874749c, 0x3e1f1f21,0x3e1f1f21
-+	data4	0x964b4bdd,0x964b4bdd, 0x61bdbddc,0x61bdbddc
-+	data4	0x0d8b8b86,0x0d8b8b86, 0x0f8a8a85,0x0f8a8a85
-+	data4	0xe0707090,0xe0707090, 0x7c3e3e42,0x7c3e3e42
-+	data4	0x71b5b5c4,0x71b5b5c4, 0xcc6666aa,0xcc6666aa
-+	data4	0x904848d8,0x904848d8, 0x06030305,0x06030305
-+	data4	0xf7f6f601,0xf7f6f601, 0x1c0e0e12,0x1c0e0e12
-+	data4	0xc26161a3,0xc26161a3, 0x6a35355f,0x6a35355f
-+	data4	0xae5757f9,0xae5757f9, 0x69b9b9d0,0x69b9b9d0
-+	data4	0x17868691,0x17868691, 0x99c1c158,0x99c1c158
-+	data4	0x3a1d1d27,0x3a1d1d27, 0x279e9eb9,0x279e9eb9
-+	data4	0xd9e1e138,0xd9e1e138, 0xebf8f813,0xebf8f813
-+	data4	0x2b9898b3,0x2b9898b3, 0x22111133,0x22111133
-+	data4	0xd26969bb,0xd26969bb, 0xa9d9d970,0xa9d9d970
-+	data4	0x078e8e89,0x078e8e89, 0x339494a7,0x339494a7
-+	data4	0x2d9b9bb6,0x2d9b9bb6, 0x3c1e1e22,0x3c1e1e22
-+	data4	0x15878792,0x15878792, 0xc9e9e920,0xc9e9e920
-+	data4	0x87cece49,0x87cece49, 0xaa5555ff,0xaa5555ff
-+	data4	0x50282878,0x50282878, 0xa5dfdf7a,0xa5dfdf7a
-+	data4	0x038c8c8f,0x038c8c8f, 0x59a1a1f8,0x59a1a1f8
-+	data4	0x09898980,0x09898980, 0x1a0d0d17,0x1a0d0d17
-+	data4	0x65bfbfda,0x65bfbfda, 0xd7e6e631,0xd7e6e631
-+	data4	0x844242c6,0x844242c6, 0xd06868b8,0xd06868b8
-+	data4	0x824141c3,0x824141c3, 0x299999b0,0x299999b0
-+	data4	0x5a2d2d77,0x5a2d2d77, 0x1e0f0f11,0x1e0f0f11
-+	data4	0x7bb0b0cb,0x7bb0b0cb, 0xa85454fc,0xa85454fc
-+	data4	0x6dbbbbd6,0x6dbbbbd6, 0x2c16163a,0x2c16163a
-+// Te4:
-+	data1	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-+	data1	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-+	data1	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-+	data1	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-+	data1	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-+	data1	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-+	data1	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-+	data1	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-+	data1	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-+	data1	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-+	data1	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-+	data1	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-+	data1	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-+	data1	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-+	data1	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-+	data1	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-+	data1	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-+	data1	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-+	data1	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-+	data1	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-+	data1	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-+	data1	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-+	data1	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-+	data1	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-+	data1	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-+	data1	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-+	data1	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-+	data1	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-+	data1	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-+	data1	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-+	data1	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-+	data1	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+.size	AES_Te#,2048+256	// HP-UX assembler fails to ".-AES_Te#"
-+
-+.align	64
-+.global	AES_Td#
-+.type	AES_Td#,@object
-+AES_Td:	data4	0x51f4a750,0x51f4a750, 0x7e416553,0x7e416553
-+	data4	0x1a17a4c3,0x1a17a4c3, 0x3a275e96,0x3a275e96
-+	data4	0x3bab6bcb,0x3bab6bcb, 0x1f9d45f1,0x1f9d45f1
-+	data4	0xacfa58ab,0xacfa58ab, 0x4be30393,0x4be30393
-+	data4	0x2030fa55,0x2030fa55, 0xad766df6,0xad766df6
-+	data4	0x88cc7691,0x88cc7691, 0xf5024c25,0xf5024c25
-+	data4	0x4fe5d7fc,0x4fe5d7fc, 0xc52acbd7,0xc52acbd7
-+	data4	0x26354480,0x26354480, 0xb562a38f,0xb562a38f
-+	data4	0xdeb15a49,0xdeb15a49, 0x25ba1b67,0x25ba1b67
-+	data4	0x45ea0e98,0x45ea0e98, 0x5dfec0e1,0x5dfec0e1
-+	data4	0xc32f7502,0xc32f7502, 0x814cf012,0x814cf012
-+	data4	0x8d4697a3,0x8d4697a3, 0x6bd3f9c6,0x6bd3f9c6
-+	data4	0x038f5fe7,0x038f5fe7, 0x15929c95,0x15929c95
-+	data4	0xbf6d7aeb,0xbf6d7aeb, 0x955259da,0x955259da
-+	data4	0xd4be832d,0xd4be832d, 0x587421d3,0x587421d3
-+	data4	0x49e06929,0x49e06929, 0x8ec9c844,0x8ec9c844
-+	data4	0x75c2896a,0x75c2896a, 0xf48e7978,0xf48e7978
-+	data4	0x99583e6b,0x99583e6b, 0x27b971dd,0x27b971dd
-+	data4	0xbee14fb6,0xbee14fb6, 0xf088ad17,0xf088ad17
-+	data4	0xc920ac66,0xc920ac66, 0x7dce3ab4,0x7dce3ab4
-+	data4	0x63df4a18,0x63df4a18, 0xe51a3182,0xe51a3182
-+	data4	0x97513360,0x97513360, 0x62537f45,0x62537f45
-+	data4	0xb16477e0,0xb16477e0, 0xbb6bae84,0xbb6bae84
-+	data4	0xfe81a01c,0xfe81a01c, 0xf9082b94,0xf9082b94
-+	data4	0x70486858,0x70486858, 0x8f45fd19,0x8f45fd19
-+	data4	0x94de6c87,0x94de6c87, 0x527bf8b7,0x527bf8b7
-+	data4	0xab73d323,0xab73d323, 0x724b02e2,0x724b02e2
-+	data4	0xe31f8f57,0xe31f8f57, 0x6655ab2a,0x6655ab2a
-+	data4	0xb2eb2807,0xb2eb2807, 0x2fb5c203,0x2fb5c203
-+	data4	0x86c57b9a,0x86c57b9a, 0xd33708a5,0xd33708a5
-+	data4	0x302887f2,0x302887f2, 0x23bfa5b2,0x23bfa5b2
-+	data4	0x02036aba,0x02036aba, 0xed16825c,0xed16825c
-+	data4	0x8acf1c2b,0x8acf1c2b, 0xa779b492,0xa779b492
-+	data4	0xf307f2f0,0xf307f2f0, 0x4e69e2a1,0x4e69e2a1
-+	data4	0x65daf4cd,0x65daf4cd, 0x0605bed5,0x0605bed5
-+	data4	0xd134621f,0xd134621f, 0xc4a6fe8a,0xc4a6fe8a
-+	data4	0x342e539d,0x342e539d, 0xa2f355a0,0xa2f355a0
-+	data4	0x058ae132,0x058ae132, 0xa4f6eb75,0xa4f6eb75
-+	data4	0x0b83ec39,0x0b83ec39, 0x4060efaa,0x4060efaa
-+	data4	0x5e719f06,0x5e719f06, 0xbd6e1051,0xbd6e1051
-+	data4	0x3e218af9,0x3e218af9, 0x96dd063d,0x96dd063d
-+	data4	0xdd3e05ae,0xdd3e05ae, 0x4de6bd46,0x4de6bd46
-+	data4	0x91548db5,0x91548db5, 0x71c45d05,0x71c45d05
-+	data4	0x0406d46f,0x0406d46f, 0x605015ff,0x605015ff
-+	data4	0x1998fb24,0x1998fb24, 0xd6bde997,0xd6bde997
-+	data4	0x894043cc,0x894043cc, 0x67d99e77,0x67d99e77
-+	data4	0xb0e842bd,0xb0e842bd, 0x07898b88,0x07898b88
-+	data4	0xe7195b38,0xe7195b38, 0x79c8eedb,0x79c8eedb
-+	data4	0xa17c0a47,0xa17c0a47, 0x7c420fe9,0x7c420fe9
-+	data4	0xf8841ec9,0xf8841ec9, 0x00000000,0x00000000
-+	data4	0x09808683,0x09808683, 0x322bed48,0x322bed48
-+	data4	0x1e1170ac,0x1e1170ac, 0x6c5a724e,0x6c5a724e
-+	data4	0xfd0efffb,0xfd0efffb, 0x0f853856,0x0f853856
-+	data4	0x3daed51e,0x3daed51e, 0x362d3927,0x362d3927
-+	data4	0x0a0fd964,0x0a0fd964, 0x685ca621,0x685ca621
-+	data4	0x9b5b54d1,0x9b5b54d1, 0x24362e3a,0x24362e3a
-+	data4	0x0c0a67b1,0x0c0a67b1, 0x9357e70f,0x9357e70f
-+	data4	0xb4ee96d2,0xb4ee96d2, 0x1b9b919e,0x1b9b919e
-+	data4	0x80c0c54f,0x80c0c54f, 0x61dc20a2,0x61dc20a2
-+	data4	0x5a774b69,0x5a774b69, 0x1c121a16,0x1c121a16
-+	data4	0xe293ba0a,0xe293ba0a, 0xc0a02ae5,0xc0a02ae5
-+	data4	0x3c22e043,0x3c22e043, 0x121b171d,0x121b171d
-+	data4	0x0e090d0b,0x0e090d0b, 0xf28bc7ad,0xf28bc7ad
-+	data4	0x2db6a8b9,0x2db6a8b9, 0x141ea9c8,0x141ea9c8
-+	data4	0x57f11985,0x57f11985, 0xaf75074c,0xaf75074c
-+	data4	0xee99ddbb,0xee99ddbb, 0xa37f60fd,0xa37f60fd
-+	data4	0xf701269f,0xf701269f, 0x5c72f5bc,0x5c72f5bc
-+	data4	0x44663bc5,0x44663bc5, 0x5bfb7e34,0x5bfb7e34
-+	data4	0x8b432976,0x8b432976, 0xcb23c6dc,0xcb23c6dc
-+	data4	0xb6edfc68,0xb6edfc68, 0xb8e4f163,0xb8e4f163
-+	data4	0xd731dcca,0xd731dcca, 0x42638510,0x42638510
-+	data4	0x13972240,0x13972240, 0x84c61120,0x84c61120
-+	data4	0x854a247d,0x854a247d, 0xd2bb3df8,0xd2bb3df8
-+	data4	0xaef93211,0xaef93211, 0xc729a16d,0xc729a16d
-+	data4	0x1d9e2f4b,0x1d9e2f4b, 0xdcb230f3,0xdcb230f3
-+	data4	0x0d8652ec,0x0d8652ec, 0x77c1e3d0,0x77c1e3d0
-+	data4	0x2bb3166c,0x2bb3166c, 0xa970b999,0xa970b999
-+	data4	0x119448fa,0x119448fa, 0x47e96422,0x47e96422
-+	data4	0xa8fc8cc4,0xa8fc8cc4, 0xa0f03f1a,0xa0f03f1a
-+	data4	0x567d2cd8,0x567d2cd8, 0x223390ef,0x223390ef
-+	data4	0x87494ec7,0x87494ec7, 0xd938d1c1,0xd938d1c1
-+	data4	0x8ccaa2fe,0x8ccaa2fe, 0x98d40b36,0x98d40b36
-+	data4	0xa6f581cf,0xa6f581cf, 0xa57ade28,0xa57ade28
-+	data4	0xdab78e26,0xdab78e26, 0x3fadbfa4,0x3fadbfa4
-+	data4	0x2c3a9de4,0x2c3a9de4, 0x5078920d,0x5078920d
-+	data4	0x6a5fcc9b,0x6a5fcc9b, 0x547e4662,0x547e4662
-+	data4	0xf68d13c2,0xf68d13c2, 0x90d8b8e8,0x90d8b8e8
-+	data4	0x2e39f75e,0x2e39f75e, 0x82c3aff5,0x82c3aff5
-+	data4	0x9f5d80be,0x9f5d80be, 0x69d0937c,0x69d0937c
-+	data4	0x6fd52da9,0x6fd52da9, 0xcf2512b3,0xcf2512b3
-+	data4	0xc8ac993b,0xc8ac993b, 0x10187da7,0x10187da7
-+	data4	0xe89c636e,0xe89c636e, 0xdb3bbb7b,0xdb3bbb7b
-+	data4	0xcd267809,0xcd267809, 0x6e5918f4,0x6e5918f4
-+	data4	0xec9ab701,0xec9ab701, 0x834f9aa8,0x834f9aa8
-+	data4	0xe6956e65,0xe6956e65, 0xaaffe67e,0xaaffe67e
-+	data4	0x21bccf08,0x21bccf08, 0xef15e8e6,0xef15e8e6
-+	data4	0xbae79bd9,0xbae79bd9, 0x4a6f36ce,0x4a6f36ce
-+	data4	0xea9f09d4,0xea9f09d4, 0x29b07cd6,0x29b07cd6
-+	data4	0x31a4b2af,0x31a4b2af, 0x2a3f2331,0x2a3f2331
-+	data4	0xc6a59430,0xc6a59430, 0x35a266c0,0x35a266c0
-+	data4	0x744ebc37,0x744ebc37, 0xfc82caa6,0xfc82caa6
-+	data4	0xe090d0b0,0xe090d0b0, 0x33a7d815,0x33a7d815
-+	data4	0xf104984a,0xf104984a, 0x41ecdaf7,0x41ecdaf7
-+	data4	0x7fcd500e,0x7fcd500e, 0x1791f62f,0x1791f62f
-+	data4	0x764dd68d,0x764dd68d, 0x43efb04d,0x43efb04d
-+	data4	0xccaa4d54,0xccaa4d54, 0xe49604df,0xe49604df
-+	data4	0x9ed1b5e3,0x9ed1b5e3, 0x4c6a881b,0x4c6a881b
-+	data4	0xc12c1fb8,0xc12c1fb8, 0x4665517f,0x4665517f
-+	data4	0x9d5eea04,0x9d5eea04, 0x018c355d,0x018c355d
-+	data4	0xfa877473,0xfa877473, 0xfb0b412e,0xfb0b412e
-+	data4	0xb3671d5a,0xb3671d5a, 0x92dbd252,0x92dbd252
-+	data4	0xe9105633,0xe9105633, 0x6dd64713,0x6dd64713
-+	data4	0x9ad7618c,0x9ad7618c, 0x37a10c7a,0x37a10c7a
-+	data4	0x59f8148e,0x59f8148e, 0xeb133c89,0xeb133c89
-+	data4	0xcea927ee,0xcea927ee, 0xb761c935,0xb761c935
-+	data4	0xe11ce5ed,0xe11ce5ed, 0x7a47b13c,0x7a47b13c
-+	data4	0x9cd2df59,0x9cd2df59, 0x55f2733f,0x55f2733f
-+	data4	0x1814ce79,0x1814ce79, 0x73c737bf,0x73c737bf
-+	data4	0x53f7cdea,0x53f7cdea, 0x5ffdaa5b,0x5ffdaa5b
-+	data4	0xdf3d6f14,0xdf3d6f14, 0x7844db86,0x7844db86
-+	data4	0xcaaff381,0xcaaff381, 0xb968c43e,0xb968c43e
-+	data4	0x3824342c,0x3824342c, 0xc2a3405f,0xc2a3405f
-+	data4	0x161dc372,0x161dc372, 0xbce2250c,0xbce2250c
-+	data4	0x283c498b,0x283c498b, 0xff0d9541,0xff0d9541
-+	data4	0x39a80171,0x39a80171, 0x080cb3de,0x080cb3de
-+	data4	0xd8b4e49c,0xd8b4e49c, 0x6456c190,0x6456c190
-+	data4	0x7bcb8461,0x7bcb8461, 0xd532b670,0xd532b670
-+	data4	0x486c5c74,0x486c5c74, 0xd0b85742,0xd0b85742
-+// Td4:
-+	data1	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-+	data1	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-+	data1	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-+	data1	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-+	data1	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-+	data1	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-+	data1	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-+	data1	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-+	data1	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-+	data1	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-+	data1	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-+	data1	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-+	data1	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-+	data1	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-+	data1	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-+	data1	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-+	data1	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-+	data1	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-+	data1	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-+	data1	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-+	data1	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-+	data1	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-+	data1	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-+	data1	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-+	data1	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-+	data1	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-+	data1	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-+	data1	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-+	data1	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-+	data1	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-+	data1	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-+	data1	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+.size	AES_Td#,2048+256	// HP-UX assembler fails to ".-AES_Td#"
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-mips.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-mips.pl
-new file mode 100644
-index 0000000..439578d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-mips.pl
-@@ -0,0 +1,2131 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# AES for MIPS
-+
-+# October 2010
-+#
-+# Code uses 1K[+256B] S-box and on single-issue core [such as R5000]
-+# spends ~68 cycles per byte processed with 128-bit key. This is ~16%
-+# faster than gcc-generated code, which is not very impressive. But
-+# recall that compressed S-box requires extra processing, namely
-+# additional rotations. Rotations are implemented with lwl/lwr pairs,
-+# which is normally used for loading unaligned data. Another cool
-+# thing about this module is its endian neutrality, which means that
-+# it processes data without ever changing byte order...
-+
-+# September 2012
-+#
-+# Add MIPS32R2 (~10% less instructions) and SmartMIPS ASE (further
-+# ~25% less instructions) code. Note that there is no run-time switch,
-+# instead, code path is chosen upon pre-process time, pass -mips32r2
-+# or/and -msmartmips.
-+
-+######################################################################
-+# There is a number of MIPS ABI in use, O32 and N32/64 are most
-+# widely used. Then there is a new contender: NUBI. It appears that if
-+# one picks the latter, it's possible to arrange code in ABI neutral
-+# manner. Therefore let's stick to NUBI register layout:
-+#
-+($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
-+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
-+($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
-+#
-+# The return value is placed in $a0. Following coding rules facilitate
-+# interoperability:
-+#
-+# - never ever touch $tp, "thread pointer", former $gp;
-+# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
-+#   old code];
-+# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
-+#
-+# For reference here is register layout for N32/64 MIPS ABIs:
-+#
-+# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
-+# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
-+# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
-+# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
-+#
-+$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64
-+
-+if ($flavour =~ /64|n32/i) {
-+	$PTR_LA="dla";
-+	$PTR_ADD="dadd";	# incidentally works even on n32
-+	$PTR_SUB="dsub";	# incidentally works even on n32
-+	$PTR_INS="dins";
-+	$REG_S="sd";
-+	$REG_L="ld";
-+	$PTR_SLL="dsll";	# incidentally works even on n32
-+	$SZREG=8;
-+} else {
-+	$PTR_LA="la";
-+	$PTR_ADD="add";
-+	$PTR_SUB="sub";
-+	$PTR_INS="ins";
-+	$REG_S="sw";
-+	$REG_L="lw";
-+	$PTR_SLL="sll";
-+	$SZREG=4;
-+}
-+$pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
-+#
-+# 
-+#
-+######################################################################
-+
-+$big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC});
-+
-+for (@ARGV) {	$output=$_ if (/\w[\w\-]*\.\w+$/);	}
-+open STDOUT,">$output";
-+
-+if (!defined($big_endian))
-+{    $big_endian=(unpack('L',pack('N',1))==1);   }
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+my ($MSB,$LSB)=(0,3);	# automatically converted to little-endian
-+
-+$code.=<<___;
-+.text
-+#ifdef OPENSSL_FIPSCANISTER
-+# include 
-+#endif
-+
-+#if defined(__mips_smartmips) && !defined(_MIPS_ARCH_MIPS32R2)
-+#define _MIPS_ARCH_MIPS32R2
-+#endif
-+
-+#if !defined(__mips_eabi) && (!defined(__vxworks) || defined(__pic__))
-+.option	pic2
-+#endif
-+.set	noat
-+___
-+
-+{{{
-+my $FRAMESIZE=16*$SZREG;
-+my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? "0xc0fff008" : "0xc0ff0000";
-+
-+my ($inp,$out,$key,$Tbl,$s0,$s1,$s2,$s3)=($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7);
-+my ($i0,$i1,$i2,$i3)=($at,$t0,$t1,$t2);
-+my ($t0,$t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$t9,$t10,$t11) = map("\$$_",(12..23));
-+my ($key0,$cnt)=($gp,$fp);
-+
-+# instuction ordering is "stolen" from output from MIPSpro assembler
-+# invoked with -mips3 -O3 arguments...
-+$code.=<<___;
-+.align	5
-+.ent	_mips_AES_encrypt
-+_mips_AES_encrypt:
-+	.frame	$sp,0,$ra
-+	.set	reorder
-+	lw	$t0,0($key)
-+	lw	$t1,4($key)
-+	lw	$t2,8($key)
-+	lw	$t3,12($key)
-+	lw	$cnt,240($key)
-+	$PTR_ADD $key0,$key,16
-+
-+	xor	$s0,$t0
-+	xor	$s1,$t1
-+	xor	$s2,$t2
-+	xor	$s3,$t3
-+
-+	sub	$cnt,1
-+#if defined(__mips_smartmips)
-+	ext	$i0,$s1,16,8
-+.Loop_enc:
-+	ext	$i1,$s2,16,8
-+	ext	$i2,$s3,16,8
-+	ext	$i3,$s0,16,8
-+	lwxs	$t0,$i0($Tbl)		# Te1[s1>>16]
-+	ext	$i0,$s2,8,8
-+	lwxs	$t1,$i1($Tbl)		# Te1[s2>>16]
-+	ext	$i1,$s3,8,8
-+	lwxs	$t2,$i2($Tbl)		# Te1[s3>>16]
-+	ext	$i2,$s0,8,8
-+	lwxs	$t3,$i3($Tbl)		# Te1[s0>>16]
-+	ext	$i3,$s1,8,8
-+
-+	lwxs	$t4,$i0($Tbl)		# Te2[s2>>8]
-+	ext	$i0,$s3,0,8
-+	lwxs	$t5,$i1($Tbl)		# Te2[s3>>8]
-+	ext	$i1,$s0,0,8
-+	lwxs	$t6,$i2($Tbl)		# Te2[s0>>8]
-+	ext	$i2,$s1,0,8
-+	lwxs	$t7,$i3($Tbl)		# Te2[s1>>8]
-+	ext	$i3,$s2,0,8
-+
-+	lwxs	$t8,$i0($Tbl)		# Te3[s3]
-+	ext	$i0,$s0,24,8
-+	lwxs	$t9,$i1($Tbl)		# Te3[s0]
-+	ext	$i1,$s1,24,8
-+	lwxs	$t10,$i2($Tbl)		# Te3[s1]
-+	ext	$i2,$s2,24,8
-+	lwxs	$t11,$i3($Tbl)		# Te3[s2]
-+	ext	$i3,$s3,24,8
-+
-+	rotr	$t0,$t0,8
-+	rotr	$t1,$t1,8
-+	rotr	$t2,$t2,8
-+	rotr	$t3,$t3,8
-+
-+	rotr	$t4,$t4,16
-+	rotr	$t5,$t5,16
-+	rotr	$t6,$t6,16
-+	rotr	$t7,$t7,16
-+
-+	xor	$t0,$t4
-+	lwxs	$t4,$i0($Tbl)		# Te0[s0>>24]
-+	xor	$t1,$t5
-+	lwxs	$t5,$i1($Tbl)		# Te0[s1>>24]
-+	xor	$t2,$t6
-+	lwxs	$t6,$i2($Tbl)		# Te0[s2>>24]
-+	xor	$t3,$t7
-+	lwxs	$t7,$i3($Tbl)		# Te0[s3>>24]
-+
-+	rotr	$t8,$t8,24
-+	lw	$s0,0($key0)
-+	rotr	$t9,$t9,24
-+	lw	$s1,4($key0)
-+	rotr	$t10,$t10,24
-+	lw	$s2,8($key0)
-+	rotr	$t11,$t11,24
-+	lw	$s3,12($key0)
-+
-+	xor	$t0,$t8
-+	xor	$t1,$t9
-+	xor	$t2,$t10
-+	xor	$t3,$t11
-+
-+	xor	$t0,$t4
-+	xor	$t1,$t5
-+	xor	$t2,$t6
-+	xor	$t3,$t7
-+
-+	sub	$cnt,1
-+	$PTR_ADD $key0,16
-+	xor	$s0,$t0
-+	xor	$s1,$t1
-+	xor	$s2,$t2
-+	xor	$s3,$t3
-+	.set	noreorder
-+	bnez	$cnt,.Loop_enc
-+	ext	$i0,$s1,16,8
-+
-+	_xtr	$i0,$s1,16-2
-+#else
-+	_xtr	$i0,$s1,16-2
-+.Loop_enc:
-+	_xtr	$i1,$s2,16-2
-+	_xtr	$i2,$s3,16-2
-+	_xtr	$i3,$s0,16-2
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	lw	$t0,0($i0)		# Te1[s1>>16]
-+	_xtr	$i0,$s2,8-2
-+	lw	$t1,0($i1)		# Te1[s2>>16]
-+	_xtr	$i1,$s3,8-2
-+	lw	$t2,0($i2)		# Te1[s3>>16]
-+	_xtr	$i2,$s0,8-2
-+	lw	$t3,0($i3)		# Te1[s0>>16]
-+	_xtr	$i3,$s1,8-2
-+#else
-+	lwl	$t0,3($i0)		# Te1[s1>>16]
-+	lwl	$t1,3($i1)		# Te1[s2>>16]
-+	lwl	$t2,3($i2)		# Te1[s3>>16]
-+	lwl	$t3,3($i3)		# Te1[s0>>16]
-+	lwr	$t0,2($i0)		# Te1[s1>>16]
-+	_xtr	$i0,$s2,8-2
-+	lwr	$t1,2($i1)		# Te1[s2>>16]
-+	_xtr	$i1,$s3,8-2
-+	lwr	$t2,2($i2)		# Te1[s3>>16]
-+	_xtr	$i2,$s0,8-2
-+	lwr	$t3,2($i3)		# Te1[s0>>16]
-+	_xtr	$i3,$s1,8-2
-+#endif
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	rotr	$t0,$t0,8
-+	rotr	$t1,$t1,8
-+	rotr	$t2,$t2,8
-+	rotr	$t3,$t3,8
-+# if defined(_MIPSEL)
-+	lw	$t4,0($i0)		# Te2[s2>>8]
-+	_xtr	$i0,$s3,0-2
-+	lw	$t5,0($i1)		# Te2[s3>>8]
-+	_xtr	$i1,$s0,0-2
-+	lw	$t6,0($i2)		# Te2[s0>>8]
-+	_xtr	$i2,$s1,0-2
-+	lw	$t7,0($i3)		# Te2[s1>>8]
-+	_xtr	$i3,$s2,0-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lw	$t8,0($i0)		# Te3[s3]
-+	$PTR_INS $i0,$s0,2,8
-+	lw	$t9,0($i1)		# Te3[s0]
-+	$PTR_INS $i1,$s1,2,8
-+	lw	$t10,0($i2)		# Te3[s1]
-+	$PTR_INS $i2,$s2,2,8
-+	lw	$t11,0($i3)		# Te3[s2]
-+	$PTR_INS $i3,$s3,2,8
-+# else
-+	lw	$t4,0($i0)		# Te2[s2>>8]
-+	$PTR_INS $i0,$s3,2,8
-+	lw	$t5,0($i1)		# Te2[s3>>8]
-+	$PTR_INS $i1,$s0,2,8
-+	lw	$t6,0($i2)		# Te2[s0>>8]
-+	$PTR_INS $i2,$s1,2,8
-+	lw	$t7,0($i3)		# Te2[s1>>8]
-+	$PTR_INS $i3,$s2,2,8
-+
-+	lw	$t8,0($i0)		# Te3[s3]
-+	_xtr	$i0,$s0,24-2
-+	lw	$t9,0($i1)		# Te3[s0]
-+	_xtr	$i1,$s1,24-2
-+	lw	$t10,0($i2)		# Te3[s1]
-+	_xtr	$i2,$s2,24-2
-+	lw	$t11,0($i3)		# Te3[s2]
-+	_xtr	$i3,$s3,24-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+# endif
-+	rotr	$t4,$t4,16
-+	rotr	$t5,$t5,16
-+	rotr	$t6,$t6,16
-+	rotr	$t7,$t7,16
-+
-+	rotr	$t8,$t8,24
-+	rotr	$t9,$t9,24
-+	rotr	$t10,$t10,24
-+	rotr	$t11,$t11,24
-+#else
-+	lwl	$t4,2($i0)		# Te2[s2>>8]
-+	lwl	$t5,2($i1)		# Te2[s3>>8]
-+	lwl	$t6,2($i2)		# Te2[s0>>8]
-+	lwl	$t7,2($i3)		# Te2[s1>>8]
-+	lwr	$t4,1($i0)		# Te2[s2>>8]
-+	_xtr	$i0,$s3,0-2
-+	lwr	$t5,1($i1)		# Te2[s3>>8]
-+	_xtr	$i1,$s0,0-2
-+	lwr	$t6,1($i2)		# Te2[s0>>8]
-+	_xtr	$i2,$s1,0-2
-+	lwr	$t7,1($i3)		# Te2[s1>>8]
-+	_xtr	$i3,$s2,0-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lwl	$t8,1($i0)		# Te3[s3]
-+	lwl	$t9,1($i1)		# Te3[s0]
-+	lwl	$t10,1($i2)		# Te3[s1]
-+	lwl	$t11,1($i3)		# Te3[s2]
-+	lwr	$t8,0($i0)		# Te3[s3]
-+	_xtr	$i0,$s0,24-2
-+	lwr	$t9,0($i1)		# Te3[s0]
-+	_xtr	$i1,$s1,24-2
-+	lwr	$t10,0($i2)		# Te3[s1]
-+	_xtr	$i2,$s2,24-2
-+	lwr	$t11,0($i3)		# Te3[s2]
-+	_xtr	$i3,$s3,24-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+#endif
-+	xor	$t0,$t4
-+	lw	$t4,0($i0)		# Te0[s0>>24]
-+	xor	$t1,$t5
-+	lw	$t5,0($i1)		# Te0[s1>>24]
-+	xor	$t2,$t6
-+	lw	$t6,0($i2)		# Te0[s2>>24]
-+	xor	$t3,$t7
-+	lw	$t7,0($i3)		# Te0[s3>>24]
-+
-+	xor	$t0,$t8
-+	lw	$s0,0($key0)
-+	xor	$t1,$t9
-+	lw	$s1,4($key0)
-+	xor	$t2,$t10
-+	lw	$s2,8($key0)
-+	xor	$t3,$t11
-+	lw	$s3,12($key0)
-+
-+	xor	$t0,$t4
-+	xor	$t1,$t5
-+	xor	$t2,$t6
-+	xor	$t3,$t7
-+
-+	sub	$cnt,1
-+	$PTR_ADD $key0,16
-+	xor	$s0,$t0
-+	xor	$s1,$t1
-+	xor	$s2,$t2
-+	xor	$s3,$t3
-+	.set	noreorder
-+	bnez	$cnt,.Loop_enc
-+	_xtr	$i0,$s1,16-2
-+#endif
-+
-+	.set	reorder
-+	_xtr	$i1,$s2,16-2
-+	_xtr	$i2,$s3,16-2
-+	_xtr	$i3,$s0,16-2
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lbu	$t0,2($i0)		# Te4[s1>>16]
-+	_xtr	$i0,$s2,8-2
-+	lbu	$t1,2($i1)		# Te4[s2>>16]
-+	_xtr	$i1,$s3,8-2
-+	lbu	$t2,2($i2)		# Te4[s3>>16]
-+	_xtr	$i2,$s0,8-2
-+	lbu	$t3,2($i3)		# Te4[s0>>16]
-+	_xtr	$i3,$s1,8-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+# if defined(_MIPSEL)
-+	lbu	$t4,2($i0)		# Te4[s2>>8]
-+	$PTR_INS $i0,$s0,2,8
-+	lbu	$t5,2($i1)		# Te4[s3>>8]
-+	$PTR_INS $i1,$s1,2,8
-+	lbu	$t6,2($i2)		# Te4[s0>>8]
-+	$PTR_INS $i2,$s2,2,8
-+	lbu	$t7,2($i3)		# Te4[s1>>8]
-+	$PTR_INS $i3,$s3,2,8
-+
-+	lbu	$t8,2($i0)		# Te4[s0>>24]
-+	_xtr	$i0,$s3,0-2
-+	lbu	$t9,2($i1)		# Te4[s1>>24]
-+	_xtr	$i1,$s0,0-2
-+	lbu	$t10,2($i2)		# Te4[s2>>24]
-+	_xtr	$i2,$s1,0-2
-+	lbu	$t11,2($i3)		# Te4[s3>>24]
-+	_xtr	$i3,$s2,0-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+# else
-+	lbu	$t4,2($i0)		# Te4[s2>>8]
-+	_xtr	$i0,$s0,24-2
-+	lbu	$t5,2($i1)		# Te4[s3>>8]
-+	_xtr	$i1,$s1,24-2
-+	lbu	$t6,2($i2)		# Te4[s0>>8]
-+	_xtr	$i2,$s2,24-2
-+	lbu	$t7,2($i3)		# Te4[s1>>8]
-+	_xtr	$i3,$s3,24-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lbu	$t8,2($i0)		# Te4[s0>>24]
-+	$PTR_INS $i0,$s3,2,8
-+	lbu	$t9,2($i1)		# Te4[s1>>24]
-+	$PTR_INS $i1,$s0,2,8
-+	lbu	$t10,2($i2)		# Te4[s2>>24]
-+	$PTR_INS $i2,$s1,2,8
-+	lbu	$t11,2($i3)		# Te4[s3>>24]
-+	$PTR_INS $i3,$s2,2,8
-+# endif
-+	_ins	$t0,16
-+	_ins	$t1,16
-+	_ins	$t2,16
-+	_ins	$t3,16
-+
-+	_ins2	$t0,$t4,8
-+	lbu	$t4,2($i0)		# Te4[s3]
-+	_ins2	$t1,$t5,8
-+	lbu	$t5,2($i1)		# Te4[s0]
-+	_ins2	$t2,$t6,8
-+	lbu	$t6,2($i2)		# Te4[s1]
-+	_ins2	$t3,$t7,8
-+	lbu	$t7,2($i3)		# Te4[s2]
-+
-+	_ins2	$t0,$t8,24
-+	lw	$s0,0($key0)
-+	_ins2	$t1,$t9,24
-+	lw	$s1,4($key0)
-+	_ins2	$t2,$t10,24
-+	lw	$s2,8($key0)
-+	_ins2	$t3,$t11,24
-+	lw	$s3,12($key0)
-+
-+	_ins2	$t0,$t4,0
-+	_ins2	$t1,$t5,0
-+	_ins2	$t2,$t6,0
-+	_ins2	$t3,$t7,0
-+#else
-+	lbu	$t4,2($i0)		# Te4[s2>>8]
-+	_xtr	$i0,$s0,24-2
-+	lbu	$t5,2($i1)		# Te4[s3>>8]
-+	_xtr	$i1,$s1,24-2
-+	lbu	$t6,2($i2)		# Te4[s0>>8]
-+	_xtr	$i2,$s2,24-2
-+	lbu	$t7,2($i3)		# Te4[s1>>8]
-+	_xtr	$i3,$s3,24-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lbu	$t8,2($i0)		# Te4[s0>>24]
-+	_xtr	$i0,$s3,0-2
-+	lbu	$t9,2($i1)		# Te4[s1>>24]
-+	_xtr	$i1,$s0,0-2
-+	lbu	$t10,2($i2)		# Te4[s2>>24]
-+	_xtr	$i2,$s1,0-2
-+	lbu	$t11,2($i3)		# Te4[s3>>24]
-+	_xtr	$i3,$s2,0-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+
-+	_ins	$t0,16
-+	_ins	$t1,16
-+	_ins	$t2,16
-+	_ins	$t3,16
-+
-+	_ins	$t4,8
-+	_ins	$t5,8
-+	_ins	$t6,8
-+	_ins	$t7,8
-+
-+	xor	$t0,$t4
-+	lbu	$t4,2($i0)		# Te4[s3]
-+	xor	$t1,$t5
-+	lbu	$t5,2($i1)		# Te4[s0]
-+	xor	$t2,$t6
-+	lbu	$t6,2($i2)		# Te4[s1]
-+	xor	$t3,$t7
-+	lbu	$t7,2($i3)		# Te4[s2]
-+
-+	_ins	$t8,24
-+	lw	$s0,0($key0)
-+	_ins	$t9,24
-+	lw	$s1,4($key0)
-+	_ins	$t10,24
-+	lw	$s2,8($key0)
-+	_ins	$t11,24
-+	lw	$s3,12($key0)
-+
-+	xor	$t0,$t8
-+	xor	$t1,$t9
-+	xor	$t2,$t10
-+	xor	$t3,$t11
-+
-+	_ins	$t4,0
-+	_ins	$t5,0
-+	_ins	$t6,0
-+	_ins	$t7,0
-+
-+	xor	$t0,$t4
-+	xor	$t1,$t5
-+	xor	$t2,$t6
-+	xor	$t3,$t7
-+#endif
-+	xor	$s0,$t0
-+	xor	$s1,$t1
-+	xor	$s2,$t2
-+	xor	$s3,$t3
-+
-+	jr	$ra
-+.end	_mips_AES_encrypt
-+
-+.align	5
-+.globl	AES_encrypt
-+.ent	AES_encrypt
-+AES_encrypt:
-+	.frame	$sp,$FRAMESIZE,$ra
-+	.mask	$SAVED_REGS_MASK,-$SZREG
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
-+	.cpload	$pf
-+___
-+$code.=<<___;
-+	$PTR_SUB $sp,$FRAMESIZE
-+	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
-+	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
-+	$REG_S	$s11,$FRAMESIZE-3*$SZREG($sp)
-+	$REG_S	$s10,$FRAMESIZE-4*$SZREG($sp)
-+	$REG_S	$s9,$FRAMESIZE-5*$SZREG($sp)
-+	$REG_S	$s8,$FRAMESIZE-6*$SZREG($sp)
-+	$REG_S	$s7,$FRAMESIZE-7*$SZREG($sp)
-+	$REG_S	$s6,$FRAMESIZE-8*$SZREG($sp)
-+	$REG_S	$s5,$FRAMESIZE-9*$SZREG($sp)
-+	$REG_S	$s4,$FRAMESIZE-10*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
-+	$REG_S	\$15,$FRAMESIZE-11*$SZREG($sp)
-+	$REG_S	\$14,$FRAMESIZE-12*$SZREG($sp)
-+	$REG_S	\$13,$FRAMESIZE-13*$SZREG($sp)
-+	$REG_S	\$12,$FRAMESIZE-14*$SZREG($sp)
-+	$REG_S	$gp,$FRAMESIZE-15*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
-+	.cplocal	$Tbl
-+	.cpsetup	$pf,$zero,AES_encrypt
-+___
-+$code.=<<___;
-+	.set	reorder
-+	$PTR_LA	$Tbl,AES_Te		# PIC-ified 'load address'
-+
-+	lwl	$s0,0+$MSB($inp)
-+	lwl	$s1,4+$MSB($inp)
-+	lwl	$s2,8+$MSB($inp)
-+	lwl	$s3,12+$MSB($inp)
-+	lwr	$s0,0+$LSB($inp)
-+	lwr	$s1,4+$LSB($inp)
-+	lwr	$s2,8+$LSB($inp)
-+	lwr	$s3,12+$LSB($inp)
-+
-+	bal	_mips_AES_encrypt
-+
-+	swr	$s0,0+$LSB($out)
-+	swr	$s1,4+$LSB($out)
-+	swr	$s2,8+$LSB($out)
-+	swr	$s3,12+$LSB($out)
-+	swl	$s0,0+$MSB($out)
-+	swl	$s1,4+$MSB($out)
-+	swl	$s2,8+$MSB($out)
-+	swl	$s3,12+$MSB($out)
-+
-+	.set	noreorder
-+	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
-+	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
-+	$REG_L	$s11,$FRAMESIZE-3*$SZREG($sp)
-+	$REG_L	$s10,$FRAMESIZE-4*$SZREG($sp)
-+	$REG_L	$s9,$FRAMESIZE-5*$SZREG($sp)
-+	$REG_L	$s8,$FRAMESIZE-6*$SZREG($sp)
-+	$REG_L	$s7,$FRAMESIZE-7*$SZREG($sp)
-+	$REG_L	$s6,$FRAMESIZE-8*$SZREG($sp)
-+	$REG_L	$s5,$FRAMESIZE-9*$SZREG($sp)
-+	$REG_L	$s4,$FRAMESIZE-10*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	\$15,$FRAMESIZE-11*$SZREG($sp)
-+	$REG_L	\$14,$FRAMESIZE-12*$SZREG($sp)
-+	$REG_L	\$13,$FRAMESIZE-13*$SZREG($sp)
-+	$REG_L	\$12,$FRAMESIZE-14*$SZREG($sp)
-+	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
-+___
-+$code.=<<___;
-+	jr	$ra
-+	$PTR_ADD $sp,$FRAMESIZE
-+.end	AES_encrypt
-+___
-+
-+$code.=<<___;
-+.align	5
-+.ent	_mips_AES_decrypt
-+_mips_AES_decrypt:
-+	.frame	$sp,0,$ra
-+	.set	reorder
-+	lw	$t0,0($key)
-+	lw	$t1,4($key)
-+	lw	$t2,8($key)
-+	lw	$t3,12($key)
-+	lw	$cnt,240($key)
-+	$PTR_ADD $key0,$key,16
-+
-+	xor	$s0,$t0
-+	xor	$s1,$t1
-+	xor	$s2,$t2
-+	xor	$s3,$t3
-+
-+	sub	$cnt,1
-+#if defined(__mips_smartmips)
-+	ext	$i0,$s3,16,8
-+.Loop_dec:
-+	ext	$i1,$s0,16,8
-+	ext	$i2,$s1,16,8
-+	ext	$i3,$s2,16,8
-+	lwxs	$t0,$i0($Tbl)		# Td1[s3>>16]
-+	ext	$i0,$s2,8,8
-+	lwxs	$t1,$i1($Tbl)		# Td1[s0>>16]
-+	ext	$i1,$s3,8,8
-+	lwxs	$t2,$i2($Tbl)		# Td1[s1>>16]
-+	ext	$i2,$s0,8,8
-+	lwxs	$t3,$i3($Tbl)		# Td1[s2>>16]
-+	ext	$i3,$s1,8,8
-+
-+	lwxs	$t4,$i0($Tbl)		# Td2[s2>>8]
-+	ext	$i0,$s1,0,8
-+	lwxs	$t5,$i1($Tbl)		# Td2[s3>>8]
-+	ext	$i1,$s2,0,8
-+	lwxs	$t6,$i2($Tbl)		# Td2[s0>>8]
-+	ext	$i2,$s3,0,8
-+	lwxs	$t7,$i3($Tbl)		# Td2[s1>>8]
-+	ext	$i3,$s0,0,8
-+
-+	lwxs	$t8,$i0($Tbl)		# Td3[s1]
-+	ext	$i0,$s0,24,8
-+	lwxs	$t9,$i1($Tbl)		# Td3[s2]
-+	ext	$i1,$s1,24,8
-+	lwxs	$t10,$i2($Tbl)		# Td3[s3]
-+	ext	$i2,$s2,24,8
-+	lwxs	$t11,$i3($Tbl)		# Td3[s0]
-+	ext	$i3,$s3,24,8
-+
-+	rotr	$t0,$t0,8
-+	rotr	$t1,$t1,8
-+	rotr	$t2,$t2,8
-+	rotr	$t3,$t3,8
-+
-+	rotr	$t4,$t4,16
-+	rotr	$t5,$t5,16
-+	rotr	$t6,$t6,16
-+	rotr	$t7,$t7,16
-+
-+	xor	$t0,$t4
-+	lwxs	$t4,$i0($Tbl)		# Td0[s0>>24]
-+	xor	$t1,$t5
-+	lwxs	$t5,$i1($Tbl)		# Td0[s1>>24]
-+	xor	$t2,$t6
-+	lwxs	$t6,$i2($Tbl)		# Td0[s2>>24]
-+	xor	$t3,$t7
-+	lwxs	$t7,$i3($Tbl)		# Td0[s3>>24]
-+
-+	rotr	$t8,$t8,24
-+	lw	$s0,0($key0)
-+	rotr	$t9,$t9,24
-+	lw	$s1,4($key0)
-+	rotr	$t10,$t10,24
-+	lw	$s2,8($key0)
-+	rotr	$t11,$t11,24
-+	lw	$s3,12($key0)
-+
-+	xor	$t0,$t8
-+	xor	$t1,$t9
-+	xor	$t2,$t10
-+	xor	$t3,$t11
-+
-+	xor	$t0,$t4
-+	xor	$t1,$t5
-+	xor	$t2,$t6
-+	xor	$t3,$t7
-+
-+	sub	$cnt,1
-+	$PTR_ADD $key0,16
-+	xor	$s0,$t0
-+	xor	$s1,$t1
-+	xor	$s2,$t2
-+	xor	$s3,$t3
-+	.set	noreorder
-+	bnez	$cnt,.Loop_dec
-+	ext	$i0,$s3,16,8
-+
-+	_xtr	$i0,$s3,16-2
-+#else
-+	_xtr	$i0,$s3,16-2
-+.Loop_dec:
-+	_xtr	$i1,$s0,16-2
-+	_xtr	$i2,$s1,16-2
-+	_xtr	$i3,$s2,16-2
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	lw	$t0,0($i0)		# Td1[s3>>16]
-+	_xtr	$i0,$s2,8-2
-+	lw	$t1,0($i1)		# Td1[s0>>16]
-+	_xtr	$i1,$s3,8-2
-+	lw	$t2,0($i2)		# Td1[s1>>16]
-+	_xtr	$i2,$s0,8-2
-+	lw	$t3,0($i3)		# Td1[s2>>16]
-+	_xtr	$i3,$s1,8-2
-+#else
-+	lwl	$t0,3($i0)		# Td1[s3>>16]
-+	lwl	$t1,3($i1)		# Td1[s0>>16]
-+	lwl	$t2,3($i2)		# Td1[s1>>16]
-+	lwl	$t3,3($i3)		# Td1[s2>>16]
-+	lwr	$t0,2($i0)		# Td1[s3>>16]
-+	_xtr	$i0,$s2,8-2
-+	lwr	$t1,2($i1)		# Td1[s0>>16]
-+	_xtr	$i1,$s3,8-2
-+	lwr	$t2,2($i2)		# Td1[s1>>16]
-+	_xtr	$i2,$s0,8-2
-+	lwr	$t3,2($i3)		# Td1[s2>>16]
-+	_xtr	$i3,$s1,8-2
-+#endif
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	rotr	$t0,$t0,8
-+	rotr	$t1,$t1,8
-+	rotr	$t2,$t2,8
-+	rotr	$t3,$t3,8
-+# if defined(_MIPSEL)
-+	lw	$t4,0($i0)		# Td2[s2>>8]
-+	_xtr	$i0,$s1,0-2
-+	lw	$t5,0($i1)		# Td2[s3>>8]
-+	_xtr	$i1,$s2,0-2
-+	lw	$t6,0($i2)		# Td2[s0>>8]
-+	_xtr	$i2,$s3,0-2
-+	lw	$t7,0($i3)		# Td2[s1>>8]
-+	_xtr	$i3,$s0,0-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lw	$t8,0($i0)		# Td3[s1]
-+	$PTR_INS $i0,$s0,2,8
-+	lw	$t9,0($i1)		# Td3[s2]
-+	$PTR_INS $i1,$s1,2,8
-+	lw	$t10,0($i2)		# Td3[s3]
-+	$PTR_INS $i2,$s2,2,8
-+	lw	$t11,0($i3)		# Td3[s0]
-+	$PTR_INS $i3,$s3,2,8
-+#else
-+	lw	$t4,0($i0)		# Td2[s2>>8]
-+	$PTR_INS $i0,$s1,2,8
-+	lw	$t5,0($i1)		# Td2[s3>>8]
-+	$PTR_INS $i1,$s2,2,8
-+	lw	$t6,0($i2)		# Td2[s0>>8]
-+	$PTR_INS $i2,$s3,2,8
-+	lw	$t7,0($i3)		# Td2[s1>>8]
-+	$PTR_INS $i3,$s0,2,8
-+
-+	lw	$t8,0($i0)		# Td3[s1]
-+	_xtr	$i0,$s0,24-2
-+	lw	$t9,0($i1)		# Td3[s2]
-+	_xtr	$i1,$s1,24-2
-+	lw	$t10,0($i2)		# Td3[s3]
-+	_xtr	$i2,$s2,24-2
-+	lw	$t11,0($i3)		# Td3[s0]
-+	_xtr	$i3,$s3,24-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+#endif
-+	rotr	$t4,$t4,16
-+	rotr	$t5,$t5,16
-+	rotr	$t6,$t6,16
-+	rotr	$t7,$t7,16
-+
-+	rotr	$t8,$t8,24
-+	rotr	$t9,$t9,24
-+	rotr	$t10,$t10,24
-+	rotr	$t11,$t11,24
-+#else
-+	lwl	$t4,2($i0)		# Td2[s2>>8]
-+	lwl	$t5,2($i1)		# Td2[s3>>8]
-+	lwl	$t6,2($i2)		# Td2[s0>>8]
-+	lwl	$t7,2($i3)		# Td2[s1>>8]
-+	lwr	$t4,1($i0)		# Td2[s2>>8]
-+	_xtr	$i0,$s1,0-2
-+	lwr	$t5,1($i1)		# Td2[s3>>8]
-+	_xtr	$i1,$s2,0-2
-+	lwr	$t6,1($i2)		# Td2[s0>>8]
-+	_xtr	$i2,$s3,0-2
-+	lwr	$t7,1($i3)		# Td2[s1>>8]
-+	_xtr	$i3,$s0,0-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lwl	$t8,1($i0)		# Td3[s1]
-+	lwl	$t9,1($i1)		# Td3[s2]
-+	lwl	$t10,1($i2)		# Td3[s3]
-+	lwl	$t11,1($i3)		# Td3[s0]
-+	lwr	$t8,0($i0)		# Td3[s1]
-+	_xtr	$i0,$s0,24-2
-+	lwr	$t9,0($i1)		# Td3[s2]
-+	_xtr	$i1,$s1,24-2
-+	lwr	$t10,0($i2)		# Td3[s3]
-+	_xtr	$i2,$s2,24-2
-+	lwr	$t11,0($i3)		# Td3[s0]
-+	_xtr	$i3,$s3,24-2
-+
-+	and	$i0,0x3fc
-+	and	$i1,0x3fc
-+	and	$i2,0x3fc
-+	and	$i3,0x3fc
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+#endif
-+
-+	xor	$t0,$t4
-+	lw	$t4,0($i0)		# Td0[s0>>24]
-+	xor	$t1,$t5
-+	lw	$t5,0($i1)		# Td0[s1>>24]
-+	xor	$t2,$t6
-+	lw	$t6,0($i2)		# Td0[s2>>24]
-+	xor	$t3,$t7
-+	lw	$t7,0($i3)		# Td0[s3>>24]
-+
-+	xor	$t0,$t8
-+	lw	$s0,0($key0)
-+	xor	$t1,$t9
-+	lw	$s1,4($key0)
-+	xor	$t2,$t10
-+	lw	$s2,8($key0)
-+	xor	$t3,$t11
-+	lw	$s3,12($key0)
-+
-+	xor	$t0,$t4
-+	xor	$t1,$t5
-+	xor	$t2,$t6
-+	xor	$t3,$t7
-+
-+	sub	$cnt,1
-+	$PTR_ADD $key0,16
-+	xor	$s0,$t0
-+	xor	$s1,$t1
-+	xor	$s2,$t2
-+	xor	$s3,$t3
-+	.set	noreorder
-+	bnez	$cnt,.Loop_dec
-+	_xtr	$i0,$s3,16-2
-+#endif
-+
-+	.set	reorder
-+	lw	$t4,1024($Tbl)		# prefetch Td4
-+	_xtr	$i0,$s3,16
-+	lw	$t5,1024+32($Tbl)
-+	_xtr	$i1,$s0,16
-+	lw	$t6,1024+64($Tbl)
-+	_xtr	$i2,$s1,16
-+	lw	$t7,1024+96($Tbl)
-+	_xtr	$i3,$s2,16
-+	lw	$t8,1024+128($Tbl)
-+	and	$i0,0xff
-+	lw	$t9,1024+160($Tbl)
-+	and	$i1,0xff
-+	lw	$t10,1024+192($Tbl)
-+	and	$i2,0xff
-+	lw	$t11,1024+224($Tbl)
-+	and	$i3,0xff
-+
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lbu	$t0,1024($i0)		# Td4[s3>>16]
-+	_xtr	$i0,$s2,8
-+	lbu	$t1,1024($i1)		# Td4[s0>>16]
-+	_xtr	$i1,$s3,8
-+	lbu	$t2,1024($i2)		# Td4[s1>>16]
-+	_xtr	$i2,$s0,8
-+	lbu	$t3,1024($i3)		# Td4[s2>>16]
-+	_xtr	$i3,$s1,8
-+
-+	and	$i0,0xff
-+	and	$i1,0xff
-+	and	$i2,0xff
-+	and	$i3,0xff
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+# if defined(_MIPSEL)
-+	lbu	$t4,1024($i0)		# Td4[s2>>8]
-+	$PTR_INS $i0,$s0,0,8
-+	lbu	$t5,1024($i1)		# Td4[s3>>8]
-+	$PTR_INS $i1,$s1,0,8
-+	lbu	$t6,1024($i2)		# Td4[s0>>8]
-+	$PTR_INS $i2,$s2,0,8
-+	lbu	$t7,1024($i3)		# Td4[s1>>8]
-+	$PTR_INS $i3,$s3,0,8
-+
-+	lbu	$t8,1024($i0)		# Td4[s0>>24]
-+	_xtr	$i0,$s1,0
-+	lbu	$t9,1024($i1)		# Td4[s1>>24]
-+	_xtr	$i1,$s2,0
-+	lbu	$t10,1024($i2)		# Td4[s2>>24]
-+	_xtr	$i2,$s3,0
-+	lbu	$t11,1024($i3)		# Td4[s3>>24]
-+	_xtr	$i3,$s0,0
-+
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+# else
-+	lbu	$t4,1024($i0)		# Td4[s2>>8]
-+	_xtr	$i0,$s0,24
-+	lbu	$t5,1024($i1)		# Td4[s3>>8]
-+	_xtr	$i1,$s1,24
-+	lbu	$t6,1024($i2)		# Td4[s0>>8]
-+	_xtr	$i2,$s2,24
-+	lbu	$t7,1024($i3)		# Td4[s1>>8]
-+	_xtr	$i3,$s3,24
-+
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lbu	$t8,1024($i0)		# Td4[s0>>24]
-+	$PTR_INS $i0,$s1,0,8
-+	lbu	$t9,1024($i1)		# Td4[s1>>24]
-+	$PTR_INS $i1,$s2,0,8
-+	lbu	$t10,1024($i2)		# Td4[s2>>24]
-+	$PTR_INS $i2,$s3,0,8
-+	lbu	$t11,1024($i3)		# Td4[s3>>24]
-+	$PTR_INS $i3,$s0,0,8
-+# endif
-+	_ins	$t0,16
-+	_ins	$t1,16
-+	_ins	$t2,16
-+	_ins	$t3,16
-+
-+	_ins2	$t0,$t4,8
-+	lbu	$t4,1024($i0)		# Td4[s1]
-+	_ins2	$t1,$t5,8
-+	lbu	$t5,1024($i1)		# Td4[s2]
-+	_ins2	$t2,$t6,8
-+	lbu	$t6,1024($i2)		# Td4[s3]
-+	_ins2	$t3,$t7,8
-+	lbu	$t7,1024($i3)		# Td4[s0]
-+
-+	_ins2	$t0,$t8,24
-+	lw	$s0,0($key0)
-+	_ins2	$t1,$t9,24
-+	lw	$s1,4($key0)
-+	_ins2	$t2,$t10,24
-+	lw	$s2,8($key0)
-+	_ins2	$t3,$t11,24
-+	lw	$s3,12($key0)
-+
-+	_ins2	$t0,$t4,0
-+	_ins2	$t1,$t5,0
-+	_ins2	$t2,$t6,0
-+	_ins2	$t3,$t7,0
-+#else
-+	lbu	$t4,1024($i0)		# Td4[s2>>8]
-+	_xtr	$i0,$s0,24
-+	lbu	$t5,1024($i1)		# Td4[s3>>8]
-+	_xtr	$i1,$s1,24
-+	lbu	$t6,1024($i2)		# Td4[s0>>8]
-+	_xtr	$i2,$s2,24
-+	lbu	$t7,1024($i3)		# Td4[s1>>8]
-+	_xtr	$i3,$s3,24
-+
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lbu	$t8,1024($i0)		# Td4[s0>>24]
-+	_xtr	$i0,$s1,0
-+	lbu	$t9,1024($i1)		# Td4[s1>>24]
-+	_xtr	$i1,$s2,0
-+	lbu	$t10,1024($i2)		# Td4[s2>>24]
-+	_xtr	$i2,$s3,0
-+	lbu	$t11,1024($i3)		# Td4[s3>>24]
-+	_xtr	$i3,$s0,0
-+
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+
-+	_ins	$t0,16
-+	_ins	$t1,16
-+	_ins	$t2,16
-+	_ins	$t3,16
-+
-+	_ins	$t4,8
-+	_ins	$t5,8
-+	_ins	$t6,8
-+	_ins	$t7,8
-+
-+	xor	$t0,$t4
-+	lbu	$t4,1024($i0)		# Td4[s1]
-+	xor	$t1,$t5
-+	lbu	$t5,1024($i1)		# Td4[s2]
-+	xor	$t2,$t6
-+	lbu	$t6,1024($i2)		# Td4[s3]
-+	xor	$t3,$t7
-+	lbu	$t7,1024($i3)		# Td4[s0]
-+
-+	_ins	$t8,24
-+	lw	$s0,0($key0)
-+	_ins	$t9,24
-+	lw	$s1,4($key0)
-+	_ins	$t10,24
-+	lw	$s2,8($key0)
-+	_ins	$t11,24
-+	lw	$s3,12($key0)
-+
-+	xor	$t0,$t8
-+	xor	$t1,$t9
-+	xor	$t2,$t10
-+	xor	$t3,$t11
-+
-+	_ins	$t4,0
-+	_ins	$t5,0
-+	_ins	$t6,0
-+	_ins	$t7,0
-+
-+	xor	$t0,$t4
-+	xor	$t1,$t5
-+	xor	$t2,$t6
-+	xor	$t3,$t7
-+#endif
-+
-+	xor	$s0,$t0
-+	xor	$s1,$t1
-+	xor	$s2,$t2
-+	xor	$s3,$t3
-+
-+	jr	$ra
-+.end	_mips_AES_decrypt
-+
-+.align	5
-+.globl	AES_decrypt
-+.ent	AES_decrypt
-+AES_decrypt:
-+	.frame	$sp,$FRAMESIZE,$ra
-+	.mask	$SAVED_REGS_MASK,-$SZREG
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
-+	.cpload	$pf
-+___
-+$code.=<<___;
-+	$PTR_SUB $sp,$FRAMESIZE
-+	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
-+	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
-+	$REG_S	$s11,$FRAMESIZE-3*$SZREG($sp)
-+	$REG_S	$s10,$FRAMESIZE-4*$SZREG($sp)
-+	$REG_S	$s9,$FRAMESIZE-5*$SZREG($sp)
-+	$REG_S	$s8,$FRAMESIZE-6*$SZREG($sp)
-+	$REG_S	$s7,$FRAMESIZE-7*$SZREG($sp)
-+	$REG_S	$s6,$FRAMESIZE-8*$SZREG($sp)
-+	$REG_S	$s5,$FRAMESIZE-9*$SZREG($sp)
-+	$REG_S	$s4,$FRAMESIZE-10*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
-+	$REG_S	\$15,$FRAMESIZE-11*$SZREG($sp)
-+	$REG_S	\$14,$FRAMESIZE-12*$SZREG($sp)
-+	$REG_S	\$13,$FRAMESIZE-13*$SZREG($sp)
-+	$REG_S	\$12,$FRAMESIZE-14*$SZREG($sp)
-+	$REG_S	$gp,$FRAMESIZE-15*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
-+	.cplocal	$Tbl
-+	.cpsetup	$pf,$zero,AES_decrypt
-+___
-+$code.=<<___;
-+	.set	reorder
-+	$PTR_LA	$Tbl,AES_Td		# PIC-ified 'load address'
-+
-+	lwl	$s0,0+$MSB($inp)
-+	lwl	$s1,4+$MSB($inp)
-+	lwl	$s2,8+$MSB($inp)
-+	lwl	$s3,12+$MSB($inp)
-+	lwr	$s0,0+$LSB($inp)
-+	lwr	$s1,4+$LSB($inp)
-+	lwr	$s2,8+$LSB($inp)
-+	lwr	$s3,12+$LSB($inp)
-+
-+	bal	_mips_AES_decrypt
-+
-+	swr	$s0,0+$LSB($out)
-+	swr	$s1,4+$LSB($out)
-+	swr	$s2,8+$LSB($out)
-+	swr	$s3,12+$LSB($out)
-+	swl	$s0,0+$MSB($out)
-+	swl	$s1,4+$MSB($out)
-+	swl	$s2,8+$MSB($out)
-+	swl	$s3,12+$MSB($out)
-+
-+	.set	noreorder
-+	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
-+	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
-+	$REG_L	$s11,$FRAMESIZE-3*$SZREG($sp)
-+	$REG_L	$s10,$FRAMESIZE-4*$SZREG($sp)
-+	$REG_L	$s9,$FRAMESIZE-5*$SZREG($sp)
-+	$REG_L	$s8,$FRAMESIZE-6*$SZREG($sp)
-+	$REG_L	$s7,$FRAMESIZE-7*$SZREG($sp)
-+	$REG_L	$s6,$FRAMESIZE-8*$SZREG($sp)
-+	$REG_L	$s5,$FRAMESIZE-9*$SZREG($sp)
-+	$REG_L	$s4,$FRAMESIZE-10*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	\$15,$FRAMESIZE-11*$SZREG($sp)
-+	$REG_L	\$14,$FRAMESIZE-12*$SZREG($sp)
-+	$REG_L	\$13,$FRAMESIZE-13*$SZREG($sp)
-+	$REG_L	\$12,$FRAMESIZE-14*$SZREG($sp)
-+	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
-+___
-+$code.=<<___;
-+	jr	$ra
-+	$PTR_ADD $sp,$FRAMESIZE
-+.end	AES_decrypt
-+___
-+}}}
-+
-+{{{
-+my $FRAMESIZE=8*$SZREG;
-+my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? "0xc000f008" : "0xc0000000";
-+
-+my ($inp,$bits,$key,$Tbl)=($a0,$a1,$a2,$a3);
-+my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7)=($a4,$a5,$a6,$a7,$s0,$s1,$s2,$s3);
-+my ($i0,$i1,$i2,$i3)=($at,$t0,$t1,$t2);
-+my ($rcon,$cnt)=($gp,$fp);
-+
-+$code.=<<___;
-+.align	5
-+.ent	_mips_AES_set_encrypt_key
-+_mips_AES_set_encrypt_key:
-+	.frame	$sp,0,$ra
-+	.set	noreorder
-+	beqz	$inp,.Lekey_done
-+	li	$t0,-1
-+	beqz	$key,.Lekey_done
-+	$PTR_ADD $rcon,$Tbl,256
-+
-+	.set	reorder
-+	lwl	$rk0,0+$MSB($inp)	# load 128 bits
-+	lwl	$rk1,4+$MSB($inp)
-+	lwl	$rk2,8+$MSB($inp)
-+	lwl	$rk3,12+$MSB($inp)
-+	li	$at,128
-+	lwr	$rk0,0+$LSB($inp)
-+	lwr	$rk1,4+$LSB($inp)
-+	lwr	$rk2,8+$LSB($inp)
-+	lwr	$rk3,12+$LSB($inp)
-+	.set	noreorder
-+	beq	$bits,$at,.L128bits
-+	li	$cnt,10
-+
-+	.set	reorder
-+	lwl	$rk4,16+$MSB($inp)	# load 192 bits
-+	lwl	$rk5,20+$MSB($inp)
-+	li	$at,192
-+	lwr	$rk4,16+$LSB($inp)
-+	lwr	$rk5,20+$LSB($inp)
-+	.set	noreorder
-+	beq	$bits,$at,.L192bits
-+	li	$cnt,8
-+
-+	.set	reorder
-+	lwl	$rk6,24+$MSB($inp)	# load 256 bits
-+	lwl	$rk7,28+$MSB($inp)
-+	li	$at,256
-+	lwr	$rk6,24+$LSB($inp)
-+	lwr	$rk7,28+$LSB($inp)
-+	.set	noreorder
-+	beq	$bits,$at,.L256bits
-+	li	$cnt,7
-+
-+	b	.Lekey_done
-+	li	$t0,-2
-+
-+.align	4
-+.L128bits:
-+	.set	reorder
-+	srl	$i0,$rk3,16
-+	srl	$i1,$rk3,8
-+	and	$i0,0xff
-+	and	$i1,0xff
-+	and	$i2,$rk3,0xff
-+	srl	$i3,$rk3,24
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lbu	$i0,0($i0)
-+	lbu	$i1,0($i1)
-+	lbu	$i2,0($i2)
-+	lbu	$i3,0($i3)
-+
-+	sw	$rk0,0($key)
-+	sw	$rk1,4($key)
-+	sw	$rk2,8($key)
-+	sw	$rk3,12($key)
-+	sub	$cnt,1
-+	$PTR_ADD $key,16
-+
-+	_bias	$i0,24
-+	_bias	$i1,16
-+	_bias	$i2,8
-+	_bias	$i3,0
-+
-+	xor	$rk0,$i0
-+	lw	$i0,0($rcon)
-+	xor	$rk0,$i1
-+	xor	$rk0,$i2
-+	xor	$rk0,$i3
-+	xor	$rk0,$i0
-+
-+	xor	$rk1,$rk0
-+	xor	$rk2,$rk1
-+	xor	$rk3,$rk2
-+
-+	.set	noreorder
-+	bnez	$cnt,.L128bits
-+	$PTR_ADD $rcon,4
-+
-+	sw	$rk0,0($key)
-+	sw	$rk1,4($key)
-+	sw	$rk2,8($key)
-+	li	$cnt,10
-+	sw	$rk3,12($key)
-+	li	$t0,0
-+	sw	$cnt,80($key)
-+	b	.Lekey_done
-+	$PTR_SUB $key,10*16
-+
-+.align	4
-+.L192bits:
-+	.set	reorder
-+	srl	$i0,$rk5,16
-+	srl	$i1,$rk5,8
-+	and	$i0,0xff
-+	and	$i1,0xff
-+	and	$i2,$rk5,0xff
-+	srl	$i3,$rk5,24
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lbu	$i0,0($i0)
-+	lbu	$i1,0($i1)
-+	lbu	$i2,0($i2)
-+	lbu	$i3,0($i3)
-+
-+	sw	$rk0,0($key)
-+	sw	$rk1,4($key)
-+	sw	$rk2,8($key)
-+	sw	$rk3,12($key)
-+	sw	$rk4,16($key)
-+	sw	$rk5,20($key)
-+	sub	$cnt,1
-+	$PTR_ADD $key,24
-+
-+	_bias	$i0,24
-+	_bias	$i1,16
-+	_bias	$i2,8
-+	_bias	$i3,0
-+
-+	xor	$rk0,$i0
-+	lw	$i0,0($rcon)
-+	xor	$rk0,$i1
-+	xor	$rk0,$i2
-+	xor	$rk0,$i3
-+	xor	$rk0,$i0
-+
-+	xor	$rk1,$rk0
-+	xor	$rk2,$rk1
-+	xor	$rk3,$rk2
-+	xor	$rk4,$rk3
-+	xor	$rk5,$rk4
-+
-+	.set	noreorder
-+	bnez	$cnt,.L192bits
-+	$PTR_ADD $rcon,4
-+
-+	sw	$rk0,0($key)
-+	sw	$rk1,4($key)
-+	sw	$rk2,8($key)
-+	li	$cnt,12
-+	sw	$rk3,12($key)
-+	li	$t0,0
-+	sw	$cnt,48($key)
-+	b	.Lekey_done
-+	$PTR_SUB $key,12*16
-+
-+.align	4
-+.L256bits:
-+	.set	reorder
-+	srl	$i0,$rk7,16
-+	srl	$i1,$rk7,8
-+	and	$i0,0xff
-+	and	$i1,0xff
-+	and	$i2,$rk7,0xff
-+	srl	$i3,$rk7,24
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lbu	$i0,0($i0)
-+	lbu	$i1,0($i1)
-+	lbu	$i2,0($i2)
-+	lbu	$i3,0($i3)
-+
-+	sw	$rk0,0($key)
-+	sw	$rk1,4($key)
-+	sw	$rk2,8($key)
-+	sw	$rk3,12($key)
-+	sw	$rk4,16($key)
-+	sw	$rk5,20($key)
-+	sw	$rk6,24($key)
-+	sw	$rk7,28($key)
-+	sub	$cnt,1
-+
-+	_bias	$i0,24
-+	_bias	$i1,16
-+	_bias	$i2,8
-+	_bias	$i3,0
-+
-+	xor	$rk0,$i0
-+	lw	$i0,0($rcon)
-+	xor	$rk0,$i1
-+	xor	$rk0,$i2
-+	xor	$rk0,$i3
-+	xor	$rk0,$i0
-+
-+	xor	$rk1,$rk0
-+	xor	$rk2,$rk1
-+	xor	$rk3,$rk2
-+	beqz	$cnt,.L256bits_done
-+
-+	srl	$i0,$rk3,24
-+	srl	$i1,$rk3,16
-+	srl	$i2,$rk3,8
-+	and	$i3,$rk3,0xff
-+	and	$i1,0xff
-+	and	$i2,0xff
-+	$PTR_ADD $i0,$Tbl
-+	$PTR_ADD $i1,$Tbl
-+	$PTR_ADD $i2,$Tbl
-+	$PTR_ADD $i3,$Tbl
-+	lbu	$i0,0($i0)
-+	lbu	$i1,0($i1)
-+	lbu	$i2,0($i2)
-+	lbu	$i3,0($i3)
-+	sll	$i0,24
-+	sll	$i1,16
-+	sll	$i2,8
-+
-+	xor	$rk4,$i0
-+	xor	$rk4,$i1
-+	xor	$rk4,$i2
-+	xor	$rk4,$i3
-+
-+	xor	$rk5,$rk4
-+	xor	$rk6,$rk5
-+	xor	$rk7,$rk6
-+
-+	$PTR_ADD $key,32
-+	.set	noreorder
-+	b	.L256bits
-+	$PTR_ADD $rcon,4
-+
-+.L256bits_done:
-+	sw	$rk0,32($key)
-+	sw	$rk1,36($key)
-+	sw	$rk2,40($key)
-+	li	$cnt,14
-+	sw	$rk3,44($key)
-+	li	$t0,0
-+	sw	$cnt,48($key)
-+	$PTR_SUB $key,12*16
-+
-+.Lekey_done:
-+	jr	$ra
-+	nop
-+.end	_mips_AES_set_encrypt_key
-+
-+.globl	AES_set_encrypt_key
-+.ent	AES_set_encrypt_key
-+AES_set_encrypt_key:
-+	.frame	$sp,$FRAMESIZE,$ra
-+	.mask	$SAVED_REGS_MASK,-$SZREG
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
-+	.cpload	$pf
-+___
-+$code.=<<___;
-+	$PTR_SUB $sp,$FRAMESIZE
-+	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
-+	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
-+	$REG_S	$s3,$FRAMESIZE-3*$SZREG($sp)
-+	$REG_S	$s2,$FRAMESIZE-4*$SZREG($sp)
-+	$REG_S	$s1,$FRAMESIZE-5*$SZREG($sp)
-+	$REG_S	$s0,$FRAMESIZE-6*$SZREG($sp)
-+	$REG_S	$gp,$FRAMESIZE-7*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
-+	.cplocal	$Tbl
-+	.cpsetup	$pf,$zero,AES_set_encrypt_key
-+___
-+$code.=<<___;
-+	.set	reorder
-+	$PTR_LA	$Tbl,AES_Te4		# PIC-ified 'load address'
-+
-+	bal	_mips_AES_set_encrypt_key
-+
-+	.set	noreorder
-+	move	$a0,$t0
-+	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
-+	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$s3,$FRAMESIZE-11*$SZREG($sp)
-+	$REG_L	$s2,$FRAMESIZE-12*$SZREG($sp)
-+	$REG_L	$s1,$FRAMESIZE-13*$SZREG($sp)
-+	$REG_L	$s0,$FRAMESIZE-14*$SZREG($sp)
-+	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
-+___
-+$code.=<<___;
-+	jr	$ra
-+	$PTR_ADD $sp,$FRAMESIZE
-+.end	AES_set_encrypt_key
-+___
-+
-+my ($head,$tail)=($inp,$bits);
-+my ($tp1,$tp2,$tp4,$tp8,$tp9,$tpb,$tpd,$tpe)=($a4,$a5,$a6,$a7,$s0,$s1,$s2,$s3);
-+my ($m,$x80808080,$x7f7f7f7f,$x1b1b1b1b)=($at,$t0,$t1,$t2);
-+$code.=<<___;
-+.align	5
-+.globl	AES_set_decrypt_key
-+.ent	AES_set_decrypt_key
-+AES_set_decrypt_key:
-+	.frame	$sp,$FRAMESIZE,$ra
-+	.mask	$SAVED_REGS_MASK,-$SZREG
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
-+	.cpload	$pf
-+___
-+$code.=<<___;
-+	$PTR_SUB $sp,$FRAMESIZE
-+	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
-+	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
-+	$REG_S	$s3,$FRAMESIZE-3*$SZREG($sp)
-+	$REG_S	$s2,$FRAMESIZE-4*$SZREG($sp)
-+	$REG_S	$s1,$FRAMESIZE-5*$SZREG($sp)
-+	$REG_S	$s0,$FRAMESIZE-6*$SZREG($sp)
-+	$REG_S	$gp,$FRAMESIZE-7*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
-+	.cplocal	$Tbl
-+	.cpsetup	$pf,$zero,AES_set_decrypt_key
-+___
-+$code.=<<___;
-+	.set	reorder
-+	$PTR_LA	$Tbl,AES_Te4		# PIC-ified 'load address'
-+
-+	bal	_mips_AES_set_encrypt_key
-+
-+	bltz	$t0,.Ldkey_done
-+
-+	sll	$at,$cnt,4
-+	$PTR_ADD $head,$key,0
-+	$PTR_ADD $tail,$key,$at
-+.align	4
-+.Lswap:
-+	lw	$rk0,0($head)
-+	lw	$rk1,4($head)
-+	lw	$rk2,8($head)
-+	lw	$rk3,12($head)
-+	lw	$rk4,0($tail)
-+	lw	$rk5,4($tail)
-+	lw	$rk6,8($tail)
-+	lw	$rk7,12($tail)
-+	sw	$rk0,0($tail)
-+	sw	$rk1,4($tail)
-+	sw	$rk2,8($tail)
-+	sw	$rk3,12($tail)
-+	$PTR_ADD $head,16
-+	$PTR_SUB $tail,16
-+	sw	$rk4,-16($head)
-+	sw	$rk5,-12($head)
-+	sw	$rk6,-8($head)
-+	sw	$rk7,-4($head)
-+	bne	$head,$tail,.Lswap
-+
-+	lw	$tp1,16($key)		# modulo-scheduled
-+	lui	$x80808080,0x8080
-+	sub	$cnt,1
-+	or	$x80808080,0x8080
-+	sll	$cnt,2
-+	$PTR_ADD $key,16
-+	lui	$x1b1b1b1b,0x1b1b
-+	nor	$x7f7f7f7f,$zero,$x80808080
-+	or	$x1b1b1b1b,0x1b1b
-+.align	4
-+.Lmix:
-+	and	$m,$tp1,$x80808080
-+	and	$tp2,$tp1,$x7f7f7f7f
-+	srl	$tp4,$m,7
-+	addu	$tp2,$tp2		# tp2<<1
-+	subu	$m,$tp4
-+	and	$m,$x1b1b1b1b
-+	xor	$tp2,$m
-+
-+	and	$m,$tp2,$x80808080
-+	and	$tp4,$tp2,$x7f7f7f7f
-+	srl	$tp8,$m,7
-+	addu	$tp4,$tp4		# tp4<<1
-+	subu	$m,$tp8
-+	and	$m,$x1b1b1b1b
-+	xor	$tp4,$m
-+
-+	and	$m,$tp4,$x80808080
-+	and	$tp8,$tp4,$x7f7f7f7f
-+	srl	$tp9,$m,7
-+	addu	$tp8,$tp8		# tp8<<1
-+	subu	$m,$tp9
-+	and	$m,$x1b1b1b1b
-+	xor	$tp8,$m
-+
-+	xor	$tp9,$tp8,$tp1
-+	xor	$tpe,$tp8,$tp4
-+	xor	$tpb,$tp9,$tp2
-+	xor	$tpd,$tp9,$tp4
-+
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	rotr	$tp1,$tpd,16
-+	 xor	$tpe,$tp2
-+	rotr	$tp2,$tp9,8
-+	xor	$tpe,$tp1
-+	rotr	$tp4,$tpb,24
-+	xor	$tpe,$tp2
-+	lw	$tp1,4($key)		# modulo-scheduled
-+	xor	$tpe,$tp4
-+#else
-+	_ror	$tp1,$tpd,16
-+	 xor	$tpe,$tp2
-+	_ror	$tp2,$tpd,-16
-+	xor	$tpe,$tp1
-+	_ror	$tp1,$tp9,8
-+	xor	$tpe,$tp2
-+	_ror	$tp2,$tp9,-24
-+	xor	$tpe,$tp1
-+	_ror	$tp1,$tpb,24
-+	xor	$tpe,$tp2
-+	_ror	$tp2,$tpb,-8
-+	xor	$tpe,$tp1
-+	lw	$tp1,4($key)		# modulo-scheduled
-+	xor	$tpe,$tp2
-+#endif
-+	sub	$cnt,1
-+	sw	$tpe,0($key)
-+	$PTR_ADD $key,4
-+	bnez	$cnt,.Lmix
-+
-+	li	$t0,0
-+.Ldkey_done:
-+	.set	noreorder
-+	move	$a0,$t0
-+	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
-+	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$s3,$FRAMESIZE-11*$SZREG($sp)
-+	$REG_L	$s2,$FRAMESIZE-12*$SZREG($sp)
-+	$REG_L	$s1,$FRAMESIZE-13*$SZREG($sp)
-+	$REG_L	$s0,$FRAMESIZE-14*$SZREG($sp)
-+	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
-+___
-+$code.=<<___;
-+	jr	$ra
-+	$PTR_ADD $sp,$FRAMESIZE
-+.end	AES_set_decrypt_key
-+___
-+}}}
-+
-+######################################################################
-+# Tables are kept in endian-neutral manner
-+$code.=<<___;
-+.rdata
-+.align	10
-+AES_Te:
-+.byte	0xc6,0x63,0x63,0xa5,	0xf8,0x7c,0x7c,0x84	# Te0
-+.byte	0xee,0x77,0x77,0x99,	0xf6,0x7b,0x7b,0x8d
-+.byte	0xff,0xf2,0xf2,0x0d,	0xd6,0x6b,0x6b,0xbd
-+.byte	0xde,0x6f,0x6f,0xb1,	0x91,0xc5,0xc5,0x54
-+.byte	0x60,0x30,0x30,0x50,	0x02,0x01,0x01,0x03
-+.byte	0xce,0x67,0x67,0xa9,	0x56,0x2b,0x2b,0x7d
-+.byte	0xe7,0xfe,0xfe,0x19,	0xb5,0xd7,0xd7,0x62
-+.byte	0x4d,0xab,0xab,0xe6,	0xec,0x76,0x76,0x9a
-+.byte	0x8f,0xca,0xca,0x45,	0x1f,0x82,0x82,0x9d
-+.byte	0x89,0xc9,0xc9,0x40,	0xfa,0x7d,0x7d,0x87
-+.byte	0xef,0xfa,0xfa,0x15,	0xb2,0x59,0x59,0xeb
-+.byte	0x8e,0x47,0x47,0xc9,	0xfb,0xf0,0xf0,0x0b
-+.byte	0x41,0xad,0xad,0xec,	0xb3,0xd4,0xd4,0x67
-+.byte	0x5f,0xa2,0xa2,0xfd,	0x45,0xaf,0xaf,0xea
-+.byte	0x23,0x9c,0x9c,0xbf,	0x53,0xa4,0xa4,0xf7
-+.byte	0xe4,0x72,0x72,0x96,	0x9b,0xc0,0xc0,0x5b
-+.byte	0x75,0xb7,0xb7,0xc2,	0xe1,0xfd,0xfd,0x1c
-+.byte	0x3d,0x93,0x93,0xae,	0x4c,0x26,0x26,0x6a
-+.byte	0x6c,0x36,0x36,0x5a,	0x7e,0x3f,0x3f,0x41
-+.byte	0xf5,0xf7,0xf7,0x02,	0x83,0xcc,0xcc,0x4f
-+.byte	0x68,0x34,0x34,0x5c,	0x51,0xa5,0xa5,0xf4
-+.byte	0xd1,0xe5,0xe5,0x34,	0xf9,0xf1,0xf1,0x08
-+.byte	0xe2,0x71,0x71,0x93,	0xab,0xd8,0xd8,0x73
-+.byte	0x62,0x31,0x31,0x53,	0x2a,0x15,0x15,0x3f
-+.byte	0x08,0x04,0x04,0x0c,	0x95,0xc7,0xc7,0x52
-+.byte	0x46,0x23,0x23,0x65,	0x9d,0xc3,0xc3,0x5e
-+.byte	0x30,0x18,0x18,0x28,	0x37,0x96,0x96,0xa1
-+.byte	0x0a,0x05,0x05,0x0f,	0x2f,0x9a,0x9a,0xb5
-+.byte	0x0e,0x07,0x07,0x09,	0x24,0x12,0x12,0x36
-+.byte	0x1b,0x80,0x80,0x9b,	0xdf,0xe2,0xe2,0x3d
-+.byte	0xcd,0xeb,0xeb,0x26,	0x4e,0x27,0x27,0x69
-+.byte	0x7f,0xb2,0xb2,0xcd,	0xea,0x75,0x75,0x9f
-+.byte	0x12,0x09,0x09,0x1b,	0x1d,0x83,0x83,0x9e
-+.byte	0x58,0x2c,0x2c,0x74,	0x34,0x1a,0x1a,0x2e
-+.byte	0x36,0x1b,0x1b,0x2d,	0xdc,0x6e,0x6e,0xb2
-+.byte	0xb4,0x5a,0x5a,0xee,	0x5b,0xa0,0xa0,0xfb
-+.byte	0xa4,0x52,0x52,0xf6,	0x76,0x3b,0x3b,0x4d
-+.byte	0xb7,0xd6,0xd6,0x61,	0x7d,0xb3,0xb3,0xce
-+.byte	0x52,0x29,0x29,0x7b,	0xdd,0xe3,0xe3,0x3e
-+.byte	0x5e,0x2f,0x2f,0x71,	0x13,0x84,0x84,0x97
-+.byte	0xa6,0x53,0x53,0xf5,	0xb9,0xd1,0xd1,0x68
-+.byte	0x00,0x00,0x00,0x00,	0xc1,0xed,0xed,0x2c
-+.byte	0x40,0x20,0x20,0x60,	0xe3,0xfc,0xfc,0x1f
-+.byte	0x79,0xb1,0xb1,0xc8,	0xb6,0x5b,0x5b,0xed
-+.byte	0xd4,0x6a,0x6a,0xbe,	0x8d,0xcb,0xcb,0x46
-+.byte	0x67,0xbe,0xbe,0xd9,	0x72,0x39,0x39,0x4b
-+.byte	0x94,0x4a,0x4a,0xde,	0x98,0x4c,0x4c,0xd4
-+.byte	0xb0,0x58,0x58,0xe8,	0x85,0xcf,0xcf,0x4a
-+.byte	0xbb,0xd0,0xd0,0x6b,	0xc5,0xef,0xef,0x2a
-+.byte	0x4f,0xaa,0xaa,0xe5,	0xed,0xfb,0xfb,0x16
-+.byte	0x86,0x43,0x43,0xc5,	0x9a,0x4d,0x4d,0xd7
-+.byte	0x66,0x33,0x33,0x55,	0x11,0x85,0x85,0x94
-+.byte	0x8a,0x45,0x45,0xcf,	0xe9,0xf9,0xf9,0x10
-+.byte	0x04,0x02,0x02,0x06,	0xfe,0x7f,0x7f,0x81
-+.byte	0xa0,0x50,0x50,0xf0,	0x78,0x3c,0x3c,0x44
-+.byte	0x25,0x9f,0x9f,0xba,	0x4b,0xa8,0xa8,0xe3
-+.byte	0xa2,0x51,0x51,0xf3,	0x5d,0xa3,0xa3,0xfe
-+.byte	0x80,0x40,0x40,0xc0,	0x05,0x8f,0x8f,0x8a
-+.byte	0x3f,0x92,0x92,0xad,	0x21,0x9d,0x9d,0xbc
-+.byte	0x70,0x38,0x38,0x48,	0xf1,0xf5,0xf5,0x04
-+.byte	0x63,0xbc,0xbc,0xdf,	0x77,0xb6,0xb6,0xc1
-+.byte	0xaf,0xda,0xda,0x75,	0x42,0x21,0x21,0x63
-+.byte	0x20,0x10,0x10,0x30,	0xe5,0xff,0xff,0x1a
-+.byte	0xfd,0xf3,0xf3,0x0e,	0xbf,0xd2,0xd2,0x6d
-+.byte	0x81,0xcd,0xcd,0x4c,	0x18,0x0c,0x0c,0x14
-+.byte	0x26,0x13,0x13,0x35,	0xc3,0xec,0xec,0x2f
-+.byte	0xbe,0x5f,0x5f,0xe1,	0x35,0x97,0x97,0xa2
-+.byte	0x88,0x44,0x44,0xcc,	0x2e,0x17,0x17,0x39
-+.byte	0x93,0xc4,0xc4,0x57,	0x55,0xa7,0xa7,0xf2
-+.byte	0xfc,0x7e,0x7e,0x82,	0x7a,0x3d,0x3d,0x47
-+.byte	0xc8,0x64,0x64,0xac,	0xba,0x5d,0x5d,0xe7
-+.byte	0x32,0x19,0x19,0x2b,	0xe6,0x73,0x73,0x95
-+.byte	0xc0,0x60,0x60,0xa0,	0x19,0x81,0x81,0x98
-+.byte	0x9e,0x4f,0x4f,0xd1,	0xa3,0xdc,0xdc,0x7f
-+.byte	0x44,0x22,0x22,0x66,	0x54,0x2a,0x2a,0x7e
-+.byte	0x3b,0x90,0x90,0xab,	0x0b,0x88,0x88,0x83
-+.byte	0x8c,0x46,0x46,0xca,	0xc7,0xee,0xee,0x29
-+.byte	0x6b,0xb8,0xb8,0xd3,	0x28,0x14,0x14,0x3c
-+.byte	0xa7,0xde,0xde,0x79,	0xbc,0x5e,0x5e,0xe2
-+.byte	0x16,0x0b,0x0b,0x1d,	0xad,0xdb,0xdb,0x76
-+.byte	0xdb,0xe0,0xe0,0x3b,	0x64,0x32,0x32,0x56
-+.byte	0x74,0x3a,0x3a,0x4e,	0x14,0x0a,0x0a,0x1e
-+.byte	0x92,0x49,0x49,0xdb,	0x0c,0x06,0x06,0x0a
-+.byte	0x48,0x24,0x24,0x6c,	0xb8,0x5c,0x5c,0xe4
-+.byte	0x9f,0xc2,0xc2,0x5d,	0xbd,0xd3,0xd3,0x6e
-+.byte	0x43,0xac,0xac,0xef,	0xc4,0x62,0x62,0xa6
-+.byte	0x39,0x91,0x91,0xa8,	0x31,0x95,0x95,0xa4
-+.byte	0xd3,0xe4,0xe4,0x37,	0xf2,0x79,0x79,0x8b
-+.byte	0xd5,0xe7,0xe7,0x32,	0x8b,0xc8,0xc8,0x43
-+.byte	0x6e,0x37,0x37,0x59,	0xda,0x6d,0x6d,0xb7
-+.byte	0x01,0x8d,0x8d,0x8c,	0xb1,0xd5,0xd5,0x64
-+.byte	0x9c,0x4e,0x4e,0xd2,	0x49,0xa9,0xa9,0xe0
-+.byte	0xd8,0x6c,0x6c,0xb4,	0xac,0x56,0x56,0xfa
-+.byte	0xf3,0xf4,0xf4,0x07,	0xcf,0xea,0xea,0x25
-+.byte	0xca,0x65,0x65,0xaf,	0xf4,0x7a,0x7a,0x8e
-+.byte	0x47,0xae,0xae,0xe9,	0x10,0x08,0x08,0x18
-+.byte	0x6f,0xba,0xba,0xd5,	0xf0,0x78,0x78,0x88
-+.byte	0x4a,0x25,0x25,0x6f,	0x5c,0x2e,0x2e,0x72
-+.byte	0x38,0x1c,0x1c,0x24,	0x57,0xa6,0xa6,0xf1
-+.byte	0x73,0xb4,0xb4,0xc7,	0x97,0xc6,0xc6,0x51
-+.byte	0xcb,0xe8,0xe8,0x23,	0xa1,0xdd,0xdd,0x7c
-+.byte	0xe8,0x74,0x74,0x9c,	0x3e,0x1f,0x1f,0x21
-+.byte	0x96,0x4b,0x4b,0xdd,	0x61,0xbd,0xbd,0xdc
-+.byte	0x0d,0x8b,0x8b,0x86,	0x0f,0x8a,0x8a,0x85
-+.byte	0xe0,0x70,0x70,0x90,	0x7c,0x3e,0x3e,0x42
-+.byte	0x71,0xb5,0xb5,0xc4,	0xcc,0x66,0x66,0xaa
-+.byte	0x90,0x48,0x48,0xd8,	0x06,0x03,0x03,0x05
-+.byte	0xf7,0xf6,0xf6,0x01,	0x1c,0x0e,0x0e,0x12
-+.byte	0xc2,0x61,0x61,0xa3,	0x6a,0x35,0x35,0x5f
-+.byte	0xae,0x57,0x57,0xf9,	0x69,0xb9,0xb9,0xd0
-+.byte	0x17,0x86,0x86,0x91,	0x99,0xc1,0xc1,0x58
-+.byte	0x3a,0x1d,0x1d,0x27,	0x27,0x9e,0x9e,0xb9
-+.byte	0xd9,0xe1,0xe1,0x38,	0xeb,0xf8,0xf8,0x13
-+.byte	0x2b,0x98,0x98,0xb3,	0x22,0x11,0x11,0x33
-+.byte	0xd2,0x69,0x69,0xbb,	0xa9,0xd9,0xd9,0x70
-+.byte	0x07,0x8e,0x8e,0x89,	0x33,0x94,0x94,0xa7
-+.byte	0x2d,0x9b,0x9b,0xb6,	0x3c,0x1e,0x1e,0x22
-+.byte	0x15,0x87,0x87,0x92,	0xc9,0xe9,0xe9,0x20
-+.byte	0x87,0xce,0xce,0x49,	0xaa,0x55,0x55,0xff
-+.byte	0x50,0x28,0x28,0x78,	0xa5,0xdf,0xdf,0x7a
-+.byte	0x03,0x8c,0x8c,0x8f,	0x59,0xa1,0xa1,0xf8
-+.byte	0x09,0x89,0x89,0x80,	0x1a,0x0d,0x0d,0x17
-+.byte	0x65,0xbf,0xbf,0xda,	0xd7,0xe6,0xe6,0x31
-+.byte	0x84,0x42,0x42,0xc6,	0xd0,0x68,0x68,0xb8
-+.byte	0x82,0x41,0x41,0xc3,	0x29,0x99,0x99,0xb0
-+.byte	0x5a,0x2d,0x2d,0x77,	0x1e,0x0f,0x0f,0x11
-+.byte	0x7b,0xb0,0xb0,0xcb,	0xa8,0x54,0x54,0xfc
-+.byte	0x6d,0xbb,0xbb,0xd6,	0x2c,0x16,0x16,0x3a
-+
-+AES_Td:
-+.byte	0x51,0xf4,0xa7,0x50,	0x7e,0x41,0x65,0x53	# Td0
-+.byte	0x1a,0x17,0xa4,0xc3,	0x3a,0x27,0x5e,0x96
-+.byte	0x3b,0xab,0x6b,0xcb,	0x1f,0x9d,0x45,0xf1
-+.byte	0xac,0xfa,0x58,0xab,	0x4b,0xe3,0x03,0x93
-+.byte	0x20,0x30,0xfa,0x55,	0xad,0x76,0x6d,0xf6
-+.byte	0x88,0xcc,0x76,0x91,	0xf5,0x02,0x4c,0x25
-+.byte	0x4f,0xe5,0xd7,0xfc,	0xc5,0x2a,0xcb,0xd7
-+.byte	0x26,0x35,0x44,0x80,	0xb5,0x62,0xa3,0x8f
-+.byte	0xde,0xb1,0x5a,0x49,	0x25,0xba,0x1b,0x67
-+.byte	0x45,0xea,0x0e,0x98,	0x5d,0xfe,0xc0,0xe1
-+.byte	0xc3,0x2f,0x75,0x02,	0x81,0x4c,0xf0,0x12
-+.byte	0x8d,0x46,0x97,0xa3,	0x6b,0xd3,0xf9,0xc6
-+.byte	0x03,0x8f,0x5f,0xe7,	0x15,0x92,0x9c,0x95
-+.byte	0xbf,0x6d,0x7a,0xeb,	0x95,0x52,0x59,0xda
-+.byte	0xd4,0xbe,0x83,0x2d,	0x58,0x74,0x21,0xd3
-+.byte	0x49,0xe0,0x69,0x29,	0x8e,0xc9,0xc8,0x44
-+.byte	0x75,0xc2,0x89,0x6a,	0xf4,0x8e,0x79,0x78
-+.byte	0x99,0x58,0x3e,0x6b,	0x27,0xb9,0x71,0xdd
-+.byte	0xbe,0xe1,0x4f,0xb6,	0xf0,0x88,0xad,0x17
-+.byte	0xc9,0x20,0xac,0x66,	0x7d,0xce,0x3a,0xb4
-+.byte	0x63,0xdf,0x4a,0x18,	0xe5,0x1a,0x31,0x82
-+.byte	0x97,0x51,0x33,0x60,	0x62,0x53,0x7f,0x45
-+.byte	0xb1,0x64,0x77,0xe0,	0xbb,0x6b,0xae,0x84
-+.byte	0xfe,0x81,0xa0,0x1c,	0xf9,0x08,0x2b,0x94
-+.byte	0x70,0x48,0x68,0x58,	0x8f,0x45,0xfd,0x19
-+.byte	0x94,0xde,0x6c,0x87,	0x52,0x7b,0xf8,0xb7
-+.byte	0xab,0x73,0xd3,0x23,	0x72,0x4b,0x02,0xe2
-+.byte	0xe3,0x1f,0x8f,0x57,	0x66,0x55,0xab,0x2a
-+.byte	0xb2,0xeb,0x28,0x07,	0x2f,0xb5,0xc2,0x03
-+.byte	0x86,0xc5,0x7b,0x9a,	0xd3,0x37,0x08,0xa5
-+.byte	0x30,0x28,0x87,0xf2,	0x23,0xbf,0xa5,0xb2
-+.byte	0x02,0x03,0x6a,0xba,	0xed,0x16,0x82,0x5c
-+.byte	0x8a,0xcf,0x1c,0x2b,	0xa7,0x79,0xb4,0x92
-+.byte	0xf3,0x07,0xf2,0xf0,	0x4e,0x69,0xe2,0xa1
-+.byte	0x65,0xda,0xf4,0xcd,	0x06,0x05,0xbe,0xd5
-+.byte	0xd1,0x34,0x62,0x1f,	0xc4,0xa6,0xfe,0x8a
-+.byte	0x34,0x2e,0x53,0x9d,	0xa2,0xf3,0x55,0xa0
-+.byte	0x05,0x8a,0xe1,0x32,	0xa4,0xf6,0xeb,0x75
-+.byte	0x0b,0x83,0xec,0x39,	0x40,0x60,0xef,0xaa
-+.byte	0x5e,0x71,0x9f,0x06,	0xbd,0x6e,0x10,0x51
-+.byte	0x3e,0x21,0x8a,0xf9,	0x96,0xdd,0x06,0x3d
-+.byte	0xdd,0x3e,0x05,0xae,	0x4d,0xe6,0xbd,0x46
-+.byte	0x91,0x54,0x8d,0xb5,	0x71,0xc4,0x5d,0x05
-+.byte	0x04,0x06,0xd4,0x6f,	0x60,0x50,0x15,0xff
-+.byte	0x19,0x98,0xfb,0x24,	0xd6,0xbd,0xe9,0x97
-+.byte	0x89,0x40,0x43,0xcc,	0x67,0xd9,0x9e,0x77
-+.byte	0xb0,0xe8,0x42,0xbd,	0x07,0x89,0x8b,0x88
-+.byte	0xe7,0x19,0x5b,0x38,	0x79,0xc8,0xee,0xdb
-+.byte	0xa1,0x7c,0x0a,0x47,	0x7c,0x42,0x0f,0xe9
-+.byte	0xf8,0x84,0x1e,0xc9,	0x00,0x00,0x00,0x00
-+.byte	0x09,0x80,0x86,0x83,	0x32,0x2b,0xed,0x48
-+.byte	0x1e,0x11,0x70,0xac,	0x6c,0x5a,0x72,0x4e
-+.byte	0xfd,0x0e,0xff,0xfb,	0x0f,0x85,0x38,0x56
-+.byte	0x3d,0xae,0xd5,0x1e,	0x36,0x2d,0x39,0x27
-+.byte	0x0a,0x0f,0xd9,0x64,	0x68,0x5c,0xa6,0x21
-+.byte	0x9b,0x5b,0x54,0xd1,	0x24,0x36,0x2e,0x3a
-+.byte	0x0c,0x0a,0x67,0xb1,	0x93,0x57,0xe7,0x0f
-+.byte	0xb4,0xee,0x96,0xd2,	0x1b,0x9b,0x91,0x9e
-+.byte	0x80,0xc0,0xc5,0x4f,	0x61,0xdc,0x20,0xa2
-+.byte	0x5a,0x77,0x4b,0x69,	0x1c,0x12,0x1a,0x16
-+.byte	0xe2,0x93,0xba,0x0a,	0xc0,0xa0,0x2a,0xe5
-+.byte	0x3c,0x22,0xe0,0x43,	0x12,0x1b,0x17,0x1d
-+.byte	0x0e,0x09,0x0d,0x0b,	0xf2,0x8b,0xc7,0xad
-+.byte	0x2d,0xb6,0xa8,0xb9,	0x14,0x1e,0xa9,0xc8
-+.byte	0x57,0xf1,0x19,0x85,	0xaf,0x75,0x07,0x4c
-+.byte	0xee,0x99,0xdd,0xbb,	0xa3,0x7f,0x60,0xfd
-+.byte	0xf7,0x01,0x26,0x9f,	0x5c,0x72,0xf5,0xbc
-+.byte	0x44,0x66,0x3b,0xc5,	0x5b,0xfb,0x7e,0x34
-+.byte	0x8b,0x43,0x29,0x76,	0xcb,0x23,0xc6,0xdc
-+.byte	0xb6,0xed,0xfc,0x68,	0xb8,0xe4,0xf1,0x63
-+.byte	0xd7,0x31,0xdc,0xca,	0x42,0x63,0x85,0x10
-+.byte	0x13,0x97,0x22,0x40,	0x84,0xc6,0x11,0x20
-+.byte	0x85,0x4a,0x24,0x7d,	0xd2,0xbb,0x3d,0xf8
-+.byte	0xae,0xf9,0x32,0x11,	0xc7,0x29,0xa1,0x6d
-+.byte	0x1d,0x9e,0x2f,0x4b,	0xdc,0xb2,0x30,0xf3
-+.byte	0x0d,0x86,0x52,0xec,	0x77,0xc1,0xe3,0xd0
-+.byte	0x2b,0xb3,0x16,0x6c,	0xa9,0x70,0xb9,0x99
-+.byte	0x11,0x94,0x48,0xfa,	0x47,0xe9,0x64,0x22
-+.byte	0xa8,0xfc,0x8c,0xc4,	0xa0,0xf0,0x3f,0x1a
-+.byte	0x56,0x7d,0x2c,0xd8,	0x22,0x33,0x90,0xef
-+.byte	0x87,0x49,0x4e,0xc7,	0xd9,0x38,0xd1,0xc1
-+.byte	0x8c,0xca,0xa2,0xfe,	0x98,0xd4,0x0b,0x36
-+.byte	0xa6,0xf5,0x81,0xcf,	0xa5,0x7a,0xde,0x28
-+.byte	0xda,0xb7,0x8e,0x26,	0x3f,0xad,0xbf,0xa4
-+.byte	0x2c,0x3a,0x9d,0xe4,	0x50,0x78,0x92,0x0d
-+.byte	0x6a,0x5f,0xcc,0x9b,	0x54,0x7e,0x46,0x62
-+.byte	0xf6,0x8d,0x13,0xc2,	0x90,0xd8,0xb8,0xe8
-+.byte	0x2e,0x39,0xf7,0x5e,	0x82,0xc3,0xaf,0xf5
-+.byte	0x9f,0x5d,0x80,0xbe,	0x69,0xd0,0x93,0x7c
-+.byte	0x6f,0xd5,0x2d,0xa9,	0xcf,0x25,0x12,0xb3
-+.byte	0xc8,0xac,0x99,0x3b,	0x10,0x18,0x7d,0xa7
-+.byte	0xe8,0x9c,0x63,0x6e,	0xdb,0x3b,0xbb,0x7b
-+.byte	0xcd,0x26,0x78,0x09,	0x6e,0x59,0x18,0xf4
-+.byte	0xec,0x9a,0xb7,0x01,	0x83,0x4f,0x9a,0xa8
-+.byte	0xe6,0x95,0x6e,0x65,	0xaa,0xff,0xe6,0x7e
-+.byte	0x21,0xbc,0xcf,0x08,	0xef,0x15,0xe8,0xe6
-+.byte	0xba,0xe7,0x9b,0xd9,	0x4a,0x6f,0x36,0xce
-+.byte	0xea,0x9f,0x09,0xd4,	0x29,0xb0,0x7c,0xd6
-+.byte	0x31,0xa4,0xb2,0xaf,	0x2a,0x3f,0x23,0x31
-+.byte	0xc6,0xa5,0x94,0x30,	0x35,0xa2,0x66,0xc0
-+.byte	0x74,0x4e,0xbc,0x37,	0xfc,0x82,0xca,0xa6
-+.byte	0xe0,0x90,0xd0,0xb0,	0x33,0xa7,0xd8,0x15
-+.byte	0xf1,0x04,0x98,0x4a,	0x41,0xec,0xda,0xf7
-+.byte	0x7f,0xcd,0x50,0x0e,	0x17,0x91,0xf6,0x2f
-+.byte	0x76,0x4d,0xd6,0x8d,	0x43,0xef,0xb0,0x4d
-+.byte	0xcc,0xaa,0x4d,0x54,	0xe4,0x96,0x04,0xdf
-+.byte	0x9e,0xd1,0xb5,0xe3,	0x4c,0x6a,0x88,0x1b
-+.byte	0xc1,0x2c,0x1f,0xb8,	0x46,0x65,0x51,0x7f
-+.byte	0x9d,0x5e,0xea,0x04,	0x01,0x8c,0x35,0x5d
-+.byte	0xfa,0x87,0x74,0x73,	0xfb,0x0b,0x41,0x2e
-+.byte	0xb3,0x67,0x1d,0x5a,	0x92,0xdb,0xd2,0x52
-+.byte	0xe9,0x10,0x56,0x33,	0x6d,0xd6,0x47,0x13
-+.byte	0x9a,0xd7,0x61,0x8c,	0x37,0xa1,0x0c,0x7a
-+.byte	0x59,0xf8,0x14,0x8e,	0xeb,0x13,0x3c,0x89
-+.byte	0xce,0xa9,0x27,0xee,	0xb7,0x61,0xc9,0x35
-+.byte	0xe1,0x1c,0xe5,0xed,	0x7a,0x47,0xb1,0x3c
-+.byte	0x9c,0xd2,0xdf,0x59,	0x55,0xf2,0x73,0x3f
-+.byte	0x18,0x14,0xce,0x79,	0x73,0xc7,0x37,0xbf
-+.byte	0x53,0xf7,0xcd,0xea,	0x5f,0xfd,0xaa,0x5b
-+.byte	0xdf,0x3d,0x6f,0x14,	0x78,0x44,0xdb,0x86
-+.byte	0xca,0xaf,0xf3,0x81,	0xb9,0x68,0xc4,0x3e
-+.byte	0x38,0x24,0x34,0x2c,	0xc2,0xa3,0x40,0x5f
-+.byte	0x16,0x1d,0xc3,0x72,	0xbc,0xe2,0x25,0x0c
-+.byte	0x28,0x3c,0x49,0x8b,	0xff,0x0d,0x95,0x41
-+.byte	0x39,0xa8,0x01,0x71,	0x08,0x0c,0xb3,0xde
-+.byte	0xd8,0xb4,0xe4,0x9c,	0x64,0x56,0xc1,0x90
-+.byte	0x7b,0xcb,0x84,0x61,	0xd5,0x32,0xb6,0x70
-+.byte	0x48,0x6c,0x5c,0x74,	0xd0,0xb8,0x57,0x42
-+
-+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38	# Td4
-+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+
-+AES_Te4:
-+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5	# Te4
-+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+
-+.byte	0x01,0x00,0x00,0x00,	0x02,0x00,0x00,0x00	# rcon
-+.byte	0x04,0x00,0x00,0x00,	0x08,0x00,0x00,0x00
-+.byte	0x10,0x00,0x00,0x00,	0x20,0x00,0x00,0x00
-+.byte	0x40,0x00,0x00,0x00,	0x80,0x00,0x00,0x00
-+.byte	0x1B,0x00,0x00,0x00,	0x36,0x00,0x00,0x00
-+___
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	# made-up _instructions, _xtr, _ins, _ror and _bias, cope
-+	# with byte order dependencies...
-+	if (/^\s+_/) {
-+	    s/(_[a-z]+\s+)(\$[0-9]+),([^,]+)(#.*)*$/$1$2,$2,$3/;
-+
-+	    s/_xtr\s+(\$[0-9]+),(\$[0-9]+),([0-9]+(\-2)*)/
-+		sprintf("srl\t$1,$2,%d",$big_endian ?	eval($3)
-+					:		eval("24-$3"))/e or
-+	    s/_ins\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/
-+		sprintf("sll\t$1,$2,%d",$big_endian ?	eval($3)
-+					:		eval("24-$3"))/e or
-+	    s/_ins2\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/
-+		sprintf("ins\t$1,$2,%d,8",$big_endian ?	eval($3)
-+					:		eval("24-$3"))/e or
-+	    s/_ror\s+(\$[0-9]+),(\$[0-9]+),(\-?[0-9]+)/
-+		sprintf("srl\t$1,$2,%d",$big_endian ?	eval($3)
-+					:		eval("$3*-1"))/e or
-+	    s/_bias\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/
-+		sprintf("sll\t$1,$2,%d",$big_endian ?	eval($3)
-+					:		eval("($3-16)&31"))/e;
-+
-+	    s/srl\s+(\$[0-9]+),(\$[0-9]+),\-([0-9]+)/
-+		sprintf("sll\t$1,$2,$3")/e				or
-+	    s/srl\s+(\$[0-9]+),(\$[0-9]+),0/
-+		sprintf("and\t$1,$2,0xff")/e				or
-+	    s/(sll\s+\$[0-9]+,\$[0-9]+,0)/#$1/;
-+	}
-+
-+	# convert lwl/lwr and swr/swl to little-endian order
-+	if (!$big_endian && /^\s+[sl]w[lr]\s+/) {
-+	    s/([sl]wl.*)([0-9]+)\((\$[0-9]+)\)/
-+		sprintf("$1%d($3)",eval("$2-$2%4+($2%4-1)&3"))/e	or
-+	    s/([sl]wr.*)([0-9]+)\((\$[0-9]+)\)/
-+		sprintf("$1%d($3)",eval("$2-$2%4+($2%4+1)&3"))/e;
-+	}
-+
-+	if (!$big_endian) {
-+	    s/(rotr\s+\$[0-9]+,\$[0-9]+),([0-9]+)/sprintf("$1,%d",32-$2)/e;
-+	    s/(ext\s+\$[0-9]+,\$[0-9]+),([0-9]+),8/sprintf("$1,%d,8",24-$2)/e;
-+	}
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-parisc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-parisc.pl
-new file mode 100644
-index 0000000..2c785bc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-parisc.pl
-@@ -0,0 +1,1029 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# AES for PA-RISC.
-+#
-+# June 2009.
-+#
-+# The module is mechanical transliteration of aes-sparcv9.pl, but with
-+# a twist: S-boxes are compressed even further down to 1K+256B. On
-+# PA-7100LC performance is ~40% better than gcc 3.2 generated code and
-+# is about 33 cycles per byte processed with 128-bit key. Newer CPUs
-+# perform at 16 cycles per byte. It's not faster than code generated
-+# by vendor compiler, but recall that it has compressed S-boxes, which
-+# requires extra processing.
-+#
-+# Special thanks to polarhome.com for providing HP-UX account.
-+
-+$flavour = shift;
-+$output = shift;
-+open STDOUT,">$output";
-+
-+if ($flavour =~ /64/) {
-+	$LEVEL		="2.0W";
-+	$SIZE_T		=8;
-+	$FRAME_MARKER	=80;
-+	$SAVED_RP	=16;
-+	$PUSH		="std";
-+	$PUSHMA		="std,ma";
-+	$POP		="ldd";
-+	$POPMB		="ldd,mb";
-+} else {
-+	$LEVEL		="1.0";
-+	$SIZE_T		=4;
-+	$FRAME_MARKER	=48;
-+	$SAVED_RP	=20;
-+	$PUSH		="stw";
-+	$PUSHMA		="stwm";
-+	$POP		="ldw";
-+	$POPMB		="ldwm";
-+}
-+
-+$FRAME=16*$SIZE_T+$FRAME_MARKER;# 16 saved regs + frame marker
-+				#                 [+ argument transfer]
-+$inp="%r26";	# arg0
-+$out="%r25";	# arg1
-+$key="%r24";	# arg2
-+
-+($s0,$s1,$s2,$s3) = ("%r1","%r2","%r3","%r4");
-+($t0,$t1,$t2,$t3) = ("%r5","%r6","%r7","%r8");
-+
-+($acc0, $acc1, $acc2, $acc3, $acc4, $acc5, $acc6, $acc7,
-+ $acc8, $acc9,$acc10,$acc11,$acc12,$acc13,$acc14,$acc15) =
-+("%r9","%r10","%r11","%r12","%r13","%r14","%r15","%r16",
-+"%r17","%r18","%r19","%r20","%r21","%r22","%r23","%r26");
-+
-+$tbl="%r28";
-+$rounds="%r29";
-+
-+$code=<<___;
-+	.LEVEL	$LEVEL
-+	.SPACE	\$TEXT\$
-+	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
-+
-+	.EXPORT	AES_encrypt,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
-+	.ALIGN	64
-+AES_encrypt
-+	.PROC
-+	.CALLINFO	FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18
-+	.ENTRY
-+	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
-+	$PUSHMA	%r3,$FRAME(%sp)
-+	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
-+	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
-+	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
-+	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
-+	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
-+	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
-+	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
-+	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
-+	$PUSH	%r12,`-$FRAME+9*$SIZE_T`(%sp)
-+	$PUSH	%r13,`-$FRAME+10*$SIZE_T`(%sp)
-+	$PUSH	%r14,`-$FRAME+11*$SIZE_T`(%sp)
-+	$PUSH	%r15,`-$FRAME+12*$SIZE_T`(%sp)
-+	$PUSH	%r16,`-$FRAME+13*$SIZE_T`(%sp)
-+	$PUSH	%r17,`-$FRAME+14*$SIZE_T`(%sp)
-+	$PUSH	%r18,`-$FRAME+15*$SIZE_T`(%sp)
-+
-+	blr	%r0,$tbl
-+	ldi	3,$t0
-+L\$enc_pic
-+	andcm	$tbl,$t0,$tbl
-+	ldo	L\$AES_Te-L\$enc_pic($tbl),$tbl
-+
-+	and	$inp,$t0,$t0
-+	sub	$inp,$t0,$inp
-+	ldw	0($inp),$s0
-+	ldw	4($inp),$s1
-+	ldw	8($inp),$s2
-+	comib,=	0,$t0,L\$enc_inp_aligned
-+	ldw	12($inp),$s3
-+
-+	sh3addl	$t0,%r0,$t0
-+	subi	32,$t0,$t0
-+	mtctl	$t0,%cr11
-+	ldw	16($inp),$t1
-+	vshd	$s0,$s1,$s0
-+	vshd	$s1,$s2,$s1
-+	vshd	$s2,$s3,$s2
-+	vshd	$s3,$t1,$s3
-+
-+L\$enc_inp_aligned
-+	bl	_parisc_AES_encrypt,%r31
-+	nop
-+
-+	extru,<> $out,31,2,%r0
-+	b	L\$enc_out_aligned
-+	nop
-+
-+	_srm	$s0,24,$acc0
-+	_srm	$s0,16,$acc1
-+	stb	$acc0,0($out)
-+	_srm	$s0,8,$acc2
-+	stb	$acc1,1($out)
-+	_srm	$s1,24,$acc4
-+	stb	$acc2,2($out)
-+	_srm	$s1,16,$acc5
-+	stb	$s0,3($out)
-+	_srm	$s1,8,$acc6
-+	stb	$acc4,4($out)
-+	_srm	$s2,24,$acc0
-+	stb	$acc5,5($out)
-+	_srm	$s2,16,$acc1
-+	stb	$acc6,6($out)
-+	_srm	$s2,8,$acc2
-+	stb	$s1,7($out)
-+	_srm	$s3,24,$acc4
-+	stb	$acc0,8($out)
-+	_srm	$s3,16,$acc5
-+	stb	$acc1,9($out)
-+	_srm	$s3,8,$acc6
-+	stb	$acc2,10($out)
-+	stb	$s2,11($out)
-+	stb	$acc4,12($out)
-+	stb	$acc5,13($out)
-+	stb	$acc6,14($out)
-+	b	L\$enc_done
-+	stb	$s3,15($out)
-+
-+L\$enc_out_aligned
-+	stw	$s0,0($out)
-+	stw	$s1,4($out)
-+	stw	$s2,8($out)
-+	stw	$s3,12($out)
-+
-+L\$enc_done
-+	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2	; standard epilogue
-+	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
-+	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
-+	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
-+	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
-+	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
-+	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
-+	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
-+	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
-+	$POP	`-$FRAME+9*$SIZE_T`(%sp),%r12
-+	$POP	`-$FRAME+10*$SIZE_T`(%sp),%r13
-+	$POP	`-$FRAME+11*$SIZE_T`(%sp),%r14
-+	$POP	`-$FRAME+12*$SIZE_T`(%sp),%r15
-+	$POP	`-$FRAME+13*$SIZE_T`(%sp),%r16
-+	$POP	`-$FRAME+14*$SIZE_T`(%sp),%r17
-+	$POP	`-$FRAME+15*$SIZE_T`(%sp),%r18
-+	bv	(%r2)
-+	.EXIT
-+	$POPMB	-$FRAME(%sp),%r3
-+	.PROCEND
-+
-+	.ALIGN	16
-+_parisc_AES_encrypt
-+	.PROC
-+	.CALLINFO	MILLICODE
-+	.ENTRY
-+	ldw	240($key),$rounds
-+	ldw	0($key),$t0
-+	ldw	4($key),$t1
-+	ldw	8($key),$t2
-+	_srm	$rounds,1,$rounds
-+	xor	$t0,$s0,$s0
-+	ldw	12($key),$t3
-+	_srm	$s0,24,$acc0
-+	xor	$t1,$s1,$s1
-+	ldw	16($key),$t0
-+	_srm	$s1,16,$acc1
-+	xor	$t2,$s2,$s2
-+	ldw	20($key),$t1
-+	xor	$t3,$s3,$s3
-+	ldw	24($key),$t2
-+	ldw	28($key),$t3
-+L\$enc_loop
-+	_srm	$s2,8,$acc2
-+	ldwx,s	$acc0($tbl),$acc0
-+	_srm	$s3,0,$acc3
-+	ldwx,s	$acc1($tbl),$acc1
-+	_srm	$s1,24,$acc4
-+	ldwx,s	$acc2($tbl),$acc2
-+	_srm	$s2,16,$acc5
-+	ldwx,s	$acc3($tbl),$acc3
-+	_srm	$s3,8,$acc6
-+	ldwx,s	$acc4($tbl),$acc4
-+	_srm	$s0,0,$acc7
-+	ldwx,s	$acc5($tbl),$acc5
-+	_srm	$s2,24,$acc8
-+	ldwx,s	$acc6($tbl),$acc6
-+	_srm	$s3,16,$acc9
-+	ldwx,s	$acc7($tbl),$acc7
-+	_srm	$s0,8,$acc10
-+	ldwx,s	$acc8($tbl),$acc8
-+	_srm	$s1,0,$acc11
-+	ldwx,s	$acc9($tbl),$acc9
-+	_srm	$s3,24,$acc12
-+	ldwx,s	$acc10($tbl),$acc10
-+	_srm	$s0,16,$acc13
-+	ldwx,s	$acc11($tbl),$acc11
-+	_srm	$s1,8,$acc14
-+	ldwx,s	$acc12($tbl),$acc12
-+	_srm	$s2,0,$acc15
-+	ldwx,s	$acc13($tbl),$acc13
-+	ldwx,s	$acc14($tbl),$acc14
-+	ldwx,s	$acc15($tbl),$acc15
-+	addib,= -1,$rounds,L\$enc_last
-+	ldo	32($key),$key
-+
-+		_ror	$acc1,8,$acc1
-+		xor	$acc0,$t0,$t0
-+	ldw	0($key),$s0
-+		_ror	$acc2,16,$acc2
-+		xor	$acc1,$t0,$t0
-+	ldw	4($key),$s1
-+		_ror	$acc3,24,$acc3
-+		xor	$acc2,$t0,$t0
-+	ldw	8($key),$s2
-+		_ror	$acc5,8,$acc5
-+		xor	$acc3,$t0,$t0
-+	ldw	12($key),$s3
-+		_ror	$acc6,16,$acc6
-+		xor	$acc4,$t1,$t1
-+		_ror	$acc7,24,$acc7
-+		xor	$acc5,$t1,$t1
-+		_ror	$acc9,8,$acc9
-+		xor	$acc6,$t1,$t1
-+		_ror	$acc10,16,$acc10
-+		xor	$acc7,$t1,$t1
-+		_ror	$acc11,24,$acc11
-+		xor	$acc8,$t2,$t2
-+		_ror	$acc13,8,$acc13
-+		xor	$acc9,$t2,$t2
-+		_ror	$acc14,16,$acc14
-+		xor	$acc10,$t2,$t2
-+		_ror	$acc15,24,$acc15
-+		xor	$acc11,$t2,$t2
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$t3,$t3
-+	_srm	$t0,24,$acc0
-+		xor	$acc14,$t3,$t3
-+	_srm	$t1,16,$acc1
-+		xor	$acc15,$t3,$t3
-+
-+	_srm	$t2,8,$acc2
-+	ldwx,s	$acc0($tbl),$acc0
-+	_srm	$t3,0,$acc3
-+	ldwx,s	$acc1($tbl),$acc1
-+	_srm	$t1,24,$acc4
-+	ldwx,s	$acc2($tbl),$acc2
-+	_srm	$t2,16,$acc5
-+	ldwx,s	$acc3($tbl),$acc3
-+	_srm	$t3,8,$acc6
-+	ldwx,s	$acc4($tbl),$acc4
-+	_srm	$t0,0,$acc7
-+	ldwx,s	$acc5($tbl),$acc5
-+	_srm	$t2,24,$acc8
-+	ldwx,s	$acc6($tbl),$acc6
-+	_srm	$t3,16,$acc9
-+	ldwx,s	$acc7($tbl),$acc7
-+	_srm	$t0,8,$acc10
-+	ldwx,s	$acc8($tbl),$acc8
-+	_srm	$t1,0,$acc11
-+	ldwx,s	$acc9($tbl),$acc9
-+	_srm	$t3,24,$acc12
-+	ldwx,s	$acc10($tbl),$acc10
-+	_srm	$t0,16,$acc13
-+	ldwx,s	$acc11($tbl),$acc11
-+	_srm	$t1,8,$acc14
-+	ldwx,s	$acc12($tbl),$acc12
-+	_srm	$t2,0,$acc15
-+	ldwx,s	$acc13($tbl),$acc13
-+		_ror	$acc1,8,$acc1
-+	ldwx,s	$acc14($tbl),$acc14
-+
-+		_ror	$acc2,16,$acc2
-+		xor	$acc0,$s0,$s0
-+	ldwx,s	$acc15($tbl),$acc15
-+		_ror	$acc3,24,$acc3
-+		xor	$acc1,$s0,$s0
-+	ldw	16($key),$t0
-+		_ror	$acc5,8,$acc5
-+		xor	$acc2,$s0,$s0
-+	ldw	20($key),$t1
-+		_ror	$acc6,16,$acc6
-+		xor	$acc3,$s0,$s0
-+	ldw	24($key),$t2
-+		_ror	$acc7,24,$acc7
-+		xor	$acc4,$s1,$s1
-+	ldw	28($key),$t3
-+		_ror	$acc9,8,$acc9
-+		xor	$acc5,$s1,$s1
-+	ldw	1024+0($tbl),%r0		; prefetch te4
-+		_ror	$acc10,16,$acc10
-+		xor	$acc6,$s1,$s1
-+	ldw	1024+32($tbl),%r0		; prefetch te4
-+		_ror	$acc11,24,$acc11
-+		xor	$acc7,$s1,$s1
-+	ldw	1024+64($tbl),%r0		; prefetch te4
-+		_ror	$acc13,8,$acc13
-+		xor	$acc8,$s2,$s2
-+	ldw	1024+96($tbl),%r0		; prefetch te4
-+		_ror	$acc14,16,$acc14
-+		xor	$acc9,$s2,$s2
-+	ldw	1024+128($tbl),%r0		; prefetch te4
-+		_ror	$acc15,24,$acc15
-+		xor	$acc10,$s2,$s2
-+	ldw	1024+160($tbl),%r0		; prefetch te4
-+	_srm	$s0,24,$acc0
-+		xor	$acc11,$s2,$s2
-+	ldw	1024+192($tbl),%r0		; prefetch te4
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$s3,$s3
-+	ldw	1024+224($tbl),%r0		; prefetch te4
-+	_srm	$s1,16,$acc1
-+		xor	$acc14,$s3,$s3
-+	b	L\$enc_loop
-+		xor	$acc15,$s3,$s3
-+
-+	.ALIGN	16
-+L\$enc_last
-+	ldo	1024($tbl),$rounds
-+		_ror	$acc1,8,$acc1
-+		xor	$acc0,$t0,$t0
-+	ldw	0($key),$s0
-+		_ror	$acc2,16,$acc2
-+		xor	$acc1,$t0,$t0
-+	ldw	4($key),$s1
-+		_ror	$acc3,24,$acc3
-+		xor	$acc2,$t0,$t0
-+	ldw	8($key),$s2
-+		_ror	$acc5,8,$acc5
-+		xor	$acc3,$t0,$t0
-+	ldw	12($key),$s3
-+		_ror	$acc6,16,$acc6
-+		xor	$acc4,$t1,$t1
-+		_ror	$acc7,24,$acc7
-+		xor	$acc5,$t1,$t1
-+		_ror	$acc9,8,$acc9
-+		xor	$acc6,$t1,$t1
-+		_ror	$acc10,16,$acc10
-+		xor	$acc7,$t1,$t1
-+		_ror	$acc11,24,$acc11
-+		xor	$acc8,$t2,$t2
-+		_ror	$acc13,8,$acc13
-+		xor	$acc9,$t2,$t2
-+		_ror	$acc14,16,$acc14
-+		xor	$acc10,$t2,$t2
-+		_ror	$acc15,24,$acc15
-+		xor	$acc11,$t2,$t2
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$t3,$t3
-+	_srm	$t0,24,$acc0
-+		xor	$acc14,$t3,$t3
-+	_srm	$t1,16,$acc1
-+		xor	$acc15,$t3,$t3
-+
-+	_srm	$t2,8,$acc2
-+	ldbx	$acc0($rounds),$acc0
-+	_srm	$t1,24,$acc4
-+	ldbx	$acc1($rounds),$acc1
-+	_srm	$t2,16,$acc5
-+	_srm	$t3,0,$acc3
-+	ldbx	$acc2($rounds),$acc2
-+	ldbx	$acc3($rounds),$acc3
-+	_srm	$t3,8,$acc6
-+	ldbx	$acc4($rounds),$acc4
-+	_srm	$t2,24,$acc8
-+	ldbx	$acc5($rounds),$acc5
-+	_srm	$t3,16,$acc9
-+	_srm	$t0,0,$acc7
-+	ldbx	$acc6($rounds),$acc6
-+	ldbx	$acc7($rounds),$acc7
-+	_srm	$t0,8,$acc10
-+	ldbx	$acc8($rounds),$acc8
-+	_srm	$t3,24,$acc12
-+	ldbx	$acc9($rounds),$acc9
-+	_srm	$t0,16,$acc13
-+	_srm	$t1,0,$acc11
-+	ldbx	$acc10($rounds),$acc10
-+	_srm	$t1,8,$acc14
-+	ldbx	$acc11($rounds),$acc11
-+	ldbx	$acc12($rounds),$acc12
-+	ldbx	$acc13($rounds),$acc13
-+	_srm	$t2,0,$acc15
-+	ldbx	$acc14($rounds),$acc14
-+
-+		dep	$acc0,7,8,$acc3
-+	ldbx	$acc15($rounds),$acc15
-+		dep	$acc4,7,8,$acc7
-+		dep	$acc1,15,8,$acc3
-+		dep	$acc5,15,8,$acc7
-+		dep	$acc2,23,8,$acc3
-+		dep	$acc6,23,8,$acc7
-+		xor	$acc3,$s0,$s0
-+		xor	$acc7,$s1,$s1
-+		dep	$acc8,7,8,$acc11
-+		dep	$acc12,7,8,$acc15
-+		dep	$acc9,15,8,$acc11
-+		dep	$acc13,15,8,$acc15
-+		dep	$acc10,23,8,$acc11
-+		dep	$acc14,23,8,$acc15
-+		xor	$acc11,$s2,$s2
-+
-+	bv	(%r31)
-+	.EXIT
-+		xor	$acc15,$s3,$s3
-+	.PROCEND
-+
-+	.ALIGN	64
-+L\$AES_Te
-+	.WORD	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
-+	.WORD	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
-+	.WORD	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
-+	.WORD	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
-+	.WORD	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
-+	.WORD	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
-+	.WORD	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
-+	.WORD	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
-+	.WORD	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
-+	.WORD	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
-+	.WORD	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
-+	.WORD	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
-+	.WORD	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
-+	.WORD	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
-+	.WORD	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
-+	.WORD	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
-+	.WORD	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
-+	.WORD	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
-+	.WORD	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
-+	.WORD	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
-+	.WORD	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
-+	.WORD	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
-+	.WORD	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
-+	.WORD	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
-+	.WORD	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
-+	.WORD	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
-+	.WORD	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
-+	.WORD	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
-+	.WORD	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
-+	.WORD	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
-+	.WORD	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
-+	.WORD	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
-+	.WORD	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
-+	.WORD	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
-+	.WORD	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
-+	.WORD	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
-+	.WORD	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
-+	.WORD	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
-+	.WORD	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
-+	.WORD	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
-+	.WORD	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
-+	.WORD	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
-+	.WORD	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
-+	.WORD	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
-+	.WORD	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
-+	.WORD	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
-+	.WORD	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
-+	.WORD	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
-+	.WORD	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
-+	.WORD	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
-+	.WORD	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
-+	.WORD	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
-+	.WORD	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
-+	.WORD	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
-+	.WORD	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
-+	.WORD	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
-+	.WORD	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
-+	.WORD	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
-+	.WORD	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
-+	.WORD	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
-+	.WORD	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
-+	.WORD	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
-+	.WORD	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
-+	.WORD	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
-+	.BYTE	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-+	.BYTE	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-+	.BYTE	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-+	.BYTE	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-+	.BYTE	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-+	.BYTE	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-+	.BYTE	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-+	.BYTE	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-+	.BYTE	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-+	.BYTE	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-+	.BYTE	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-+	.BYTE	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-+	.BYTE	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-+	.BYTE	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-+	.BYTE	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-+	.BYTE	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-+	.BYTE	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-+	.BYTE	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-+	.BYTE	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-+	.BYTE	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-+	.BYTE	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-+	.BYTE	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-+	.BYTE	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-+	.BYTE	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-+	.BYTE	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-+	.BYTE	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-+	.BYTE	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-+	.BYTE	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-+	.BYTE	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-+	.BYTE	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-+	.BYTE	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-+	.BYTE	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+___
-+
-+$code.=<<___;
-+	.EXPORT	AES_decrypt,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
-+	.ALIGN	16
-+AES_decrypt
-+	.PROC
-+	.CALLINFO	FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18
-+	.ENTRY
-+	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
-+	$PUSHMA	%r3,$FRAME(%sp)
-+	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
-+	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
-+	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
-+	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
-+	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
-+	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
-+	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
-+	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
-+	$PUSH	%r12,`-$FRAME+9*$SIZE_T`(%sp)
-+	$PUSH	%r13,`-$FRAME+10*$SIZE_T`(%sp)
-+	$PUSH	%r14,`-$FRAME+11*$SIZE_T`(%sp)
-+	$PUSH	%r15,`-$FRAME+12*$SIZE_T`(%sp)
-+	$PUSH	%r16,`-$FRAME+13*$SIZE_T`(%sp)
-+	$PUSH	%r17,`-$FRAME+14*$SIZE_T`(%sp)
-+	$PUSH	%r18,`-$FRAME+15*$SIZE_T`(%sp)
-+
-+	blr	%r0,$tbl
-+	ldi	3,$t0
-+L\$dec_pic
-+	andcm	$tbl,$t0,$tbl
-+	ldo	L\$AES_Td-L\$dec_pic($tbl),$tbl
-+
-+	and	$inp,$t0,$t0
-+	sub	$inp,$t0,$inp
-+	ldw	0($inp),$s0
-+	ldw	4($inp),$s1
-+	ldw	8($inp),$s2
-+	comib,=	0,$t0,L\$dec_inp_aligned
-+	ldw	12($inp),$s3
-+
-+	sh3addl	$t0,%r0,$t0
-+	subi	32,$t0,$t0
-+	mtctl	$t0,%cr11
-+	ldw	16($inp),$t1
-+	vshd	$s0,$s1,$s0
-+	vshd	$s1,$s2,$s1
-+	vshd	$s2,$s3,$s2
-+	vshd	$s3,$t1,$s3
-+
-+L\$dec_inp_aligned
-+	bl	_parisc_AES_decrypt,%r31
-+	nop
-+
-+	extru,<> $out,31,2,%r0
-+	b	L\$dec_out_aligned
-+	nop
-+
-+	_srm	$s0,24,$acc0
-+	_srm	$s0,16,$acc1
-+	stb	$acc0,0($out)
-+	_srm	$s0,8,$acc2
-+	stb	$acc1,1($out)
-+	_srm	$s1,24,$acc4
-+	stb	$acc2,2($out)
-+	_srm	$s1,16,$acc5
-+	stb	$s0,3($out)
-+	_srm	$s1,8,$acc6
-+	stb	$acc4,4($out)
-+	_srm	$s2,24,$acc0
-+	stb	$acc5,5($out)
-+	_srm	$s2,16,$acc1
-+	stb	$acc6,6($out)
-+	_srm	$s2,8,$acc2
-+	stb	$s1,7($out)
-+	_srm	$s3,24,$acc4
-+	stb	$acc0,8($out)
-+	_srm	$s3,16,$acc5
-+	stb	$acc1,9($out)
-+	_srm	$s3,8,$acc6
-+	stb	$acc2,10($out)
-+	stb	$s2,11($out)
-+	stb	$acc4,12($out)
-+	stb	$acc5,13($out)
-+	stb	$acc6,14($out)
-+	b	L\$dec_done
-+	stb	$s3,15($out)
-+
-+L\$dec_out_aligned
-+	stw	$s0,0($out)
-+	stw	$s1,4($out)
-+	stw	$s2,8($out)
-+	stw	$s3,12($out)
-+
-+L\$dec_done
-+	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2	; standard epilogue
-+	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
-+	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
-+	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
-+	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
-+	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
-+	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
-+	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
-+	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
-+	$POP	`-$FRAME+9*$SIZE_T`(%sp),%r12
-+	$POP	`-$FRAME+10*$SIZE_T`(%sp),%r13
-+	$POP	`-$FRAME+11*$SIZE_T`(%sp),%r14
-+	$POP	`-$FRAME+12*$SIZE_T`(%sp),%r15
-+	$POP	`-$FRAME+13*$SIZE_T`(%sp),%r16
-+	$POP	`-$FRAME+14*$SIZE_T`(%sp),%r17
-+	$POP	`-$FRAME+15*$SIZE_T`(%sp),%r18
-+	bv	(%r2)
-+	.EXIT
-+	$POPMB	-$FRAME(%sp),%r3
-+	.PROCEND
-+
-+	.ALIGN	16
-+_parisc_AES_decrypt
-+	.PROC
-+	.CALLINFO	MILLICODE
-+	.ENTRY
-+	ldw	240($key),$rounds
-+	ldw	0($key),$t0
-+	ldw	4($key),$t1
-+	ldw	8($key),$t2
-+	ldw	12($key),$t3
-+	_srm	$rounds,1,$rounds
-+	xor	$t0,$s0,$s0
-+	ldw	16($key),$t0
-+	xor	$t1,$s1,$s1
-+	ldw	20($key),$t1
-+	_srm	$s0,24,$acc0
-+	xor	$t2,$s2,$s2
-+	ldw	24($key),$t2
-+	xor	$t3,$s3,$s3
-+	ldw	28($key),$t3
-+	_srm	$s3,16,$acc1
-+L\$dec_loop
-+	_srm	$s2,8,$acc2
-+	ldwx,s	$acc0($tbl),$acc0
-+	_srm	$s1,0,$acc3
-+	ldwx,s	$acc1($tbl),$acc1
-+	_srm	$s1,24,$acc4
-+	ldwx,s	$acc2($tbl),$acc2
-+	_srm	$s0,16,$acc5
-+	ldwx,s	$acc3($tbl),$acc3
-+	_srm	$s3,8,$acc6
-+	ldwx,s	$acc4($tbl),$acc4
-+	_srm	$s2,0,$acc7
-+	ldwx,s	$acc5($tbl),$acc5
-+	_srm	$s2,24,$acc8
-+	ldwx,s	$acc6($tbl),$acc6
-+	_srm	$s1,16,$acc9
-+	ldwx,s	$acc7($tbl),$acc7
-+	_srm	$s0,8,$acc10
-+	ldwx,s	$acc8($tbl),$acc8
-+	_srm	$s3,0,$acc11
-+	ldwx,s	$acc9($tbl),$acc9
-+	_srm	$s3,24,$acc12
-+	ldwx,s	$acc10($tbl),$acc10
-+	_srm	$s2,16,$acc13
-+	ldwx,s	$acc11($tbl),$acc11
-+	_srm	$s1,8,$acc14
-+	ldwx,s	$acc12($tbl),$acc12
-+	_srm	$s0,0,$acc15
-+	ldwx,s	$acc13($tbl),$acc13
-+	ldwx,s	$acc14($tbl),$acc14
-+	ldwx,s	$acc15($tbl),$acc15
-+	addib,= -1,$rounds,L\$dec_last
-+	ldo	32($key),$key
-+
-+		_ror	$acc1,8,$acc1
-+		xor	$acc0,$t0,$t0
-+	ldw	0($key),$s0
-+		_ror	$acc2,16,$acc2
-+		xor	$acc1,$t0,$t0
-+	ldw	4($key),$s1
-+		_ror	$acc3,24,$acc3
-+		xor	$acc2,$t0,$t0
-+	ldw	8($key),$s2
-+		_ror	$acc5,8,$acc5
-+		xor	$acc3,$t0,$t0
-+	ldw	12($key),$s3
-+		_ror	$acc6,16,$acc6
-+		xor	$acc4,$t1,$t1
-+		_ror	$acc7,24,$acc7
-+		xor	$acc5,$t1,$t1
-+		_ror	$acc9,8,$acc9
-+		xor	$acc6,$t1,$t1
-+		_ror	$acc10,16,$acc10
-+		xor	$acc7,$t1,$t1
-+		_ror	$acc11,24,$acc11
-+		xor	$acc8,$t2,$t2
-+		_ror	$acc13,8,$acc13
-+		xor	$acc9,$t2,$t2
-+		_ror	$acc14,16,$acc14
-+		xor	$acc10,$t2,$t2
-+		_ror	$acc15,24,$acc15
-+		xor	$acc11,$t2,$t2
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$t3,$t3
-+	_srm	$t0,24,$acc0
-+		xor	$acc14,$t3,$t3
-+		xor	$acc15,$t3,$t3
-+	_srm	$t3,16,$acc1
-+
-+	_srm	$t2,8,$acc2
-+	ldwx,s	$acc0($tbl),$acc0
-+	_srm	$t1,0,$acc3
-+	ldwx,s	$acc1($tbl),$acc1
-+	_srm	$t1,24,$acc4
-+	ldwx,s	$acc2($tbl),$acc2
-+	_srm	$t0,16,$acc5
-+	ldwx,s	$acc3($tbl),$acc3
-+	_srm	$t3,8,$acc6
-+	ldwx,s	$acc4($tbl),$acc4
-+	_srm	$t2,0,$acc7
-+	ldwx,s	$acc5($tbl),$acc5
-+	_srm	$t2,24,$acc8
-+	ldwx,s	$acc6($tbl),$acc6
-+	_srm	$t1,16,$acc9
-+	ldwx,s	$acc7($tbl),$acc7
-+	_srm	$t0,8,$acc10
-+	ldwx,s	$acc8($tbl),$acc8
-+	_srm	$t3,0,$acc11
-+	ldwx,s	$acc9($tbl),$acc9
-+	_srm	$t3,24,$acc12
-+	ldwx,s	$acc10($tbl),$acc10
-+	_srm	$t2,16,$acc13
-+	ldwx,s	$acc11($tbl),$acc11
-+	_srm	$t1,8,$acc14
-+	ldwx,s	$acc12($tbl),$acc12
-+	_srm	$t0,0,$acc15
-+	ldwx,s	$acc13($tbl),$acc13
-+		_ror	$acc1,8,$acc1
-+	ldwx,s	$acc14($tbl),$acc14
-+
-+		_ror	$acc2,16,$acc2
-+		xor	$acc0,$s0,$s0
-+	ldwx,s	$acc15($tbl),$acc15
-+		_ror	$acc3,24,$acc3
-+		xor	$acc1,$s0,$s0
-+	ldw	16($key),$t0
-+		_ror	$acc5,8,$acc5
-+		xor	$acc2,$s0,$s0
-+	ldw	20($key),$t1
-+		_ror	$acc6,16,$acc6
-+		xor	$acc3,$s0,$s0
-+	ldw	24($key),$t2
-+		_ror	$acc7,24,$acc7
-+		xor	$acc4,$s1,$s1
-+	ldw	28($key),$t3
-+		_ror	$acc9,8,$acc9
-+		xor	$acc5,$s1,$s1
-+	ldw	1024+0($tbl),%r0		; prefetch td4
-+		_ror	$acc10,16,$acc10
-+		xor	$acc6,$s1,$s1
-+	ldw	1024+32($tbl),%r0		; prefetch td4
-+		_ror	$acc11,24,$acc11
-+		xor	$acc7,$s1,$s1
-+	ldw	1024+64($tbl),%r0		; prefetch td4
-+		_ror	$acc13,8,$acc13
-+		xor	$acc8,$s2,$s2
-+	ldw	1024+96($tbl),%r0		; prefetch td4
-+		_ror	$acc14,16,$acc14
-+		xor	$acc9,$s2,$s2
-+	ldw	1024+128($tbl),%r0		; prefetch td4
-+		_ror	$acc15,24,$acc15
-+		xor	$acc10,$s2,$s2
-+	ldw	1024+160($tbl),%r0		; prefetch td4
-+	_srm	$s0,24,$acc0
-+		xor	$acc11,$s2,$s2
-+	ldw	1024+192($tbl),%r0		; prefetch td4
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$s3,$s3
-+	ldw	1024+224($tbl),%r0		; prefetch td4
-+		xor	$acc14,$s3,$s3
-+		xor	$acc15,$s3,$s3
-+	b	L\$dec_loop
-+	_srm	$s3,16,$acc1
-+
-+	.ALIGN	16
-+L\$dec_last
-+	ldo	1024($tbl),$rounds
-+		_ror	$acc1,8,$acc1
-+		xor	$acc0,$t0,$t0
-+	ldw	0($key),$s0
-+		_ror	$acc2,16,$acc2
-+		xor	$acc1,$t0,$t0
-+	ldw	4($key),$s1
-+		_ror	$acc3,24,$acc3
-+		xor	$acc2,$t0,$t0
-+	ldw	8($key),$s2
-+		_ror	$acc5,8,$acc5
-+		xor	$acc3,$t0,$t0
-+	ldw	12($key),$s3
-+		_ror	$acc6,16,$acc6
-+		xor	$acc4,$t1,$t1
-+		_ror	$acc7,24,$acc7
-+		xor	$acc5,$t1,$t1
-+		_ror	$acc9,8,$acc9
-+		xor	$acc6,$t1,$t1
-+		_ror	$acc10,16,$acc10
-+		xor	$acc7,$t1,$t1
-+		_ror	$acc11,24,$acc11
-+		xor	$acc8,$t2,$t2
-+		_ror	$acc13,8,$acc13
-+		xor	$acc9,$t2,$t2
-+		_ror	$acc14,16,$acc14
-+		xor	$acc10,$t2,$t2
-+		_ror	$acc15,24,$acc15
-+		xor	$acc11,$t2,$t2
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$t3,$t3
-+	_srm	$t0,24,$acc0
-+		xor	$acc14,$t3,$t3
-+		xor	$acc15,$t3,$t3
-+	_srm	$t3,16,$acc1
-+
-+	_srm	$t2,8,$acc2
-+	ldbx	$acc0($rounds),$acc0
-+	_srm	$t1,24,$acc4
-+	ldbx	$acc1($rounds),$acc1
-+	_srm	$t0,16,$acc5
-+	_srm	$t1,0,$acc3
-+	ldbx	$acc2($rounds),$acc2
-+	ldbx	$acc3($rounds),$acc3
-+	_srm	$t3,8,$acc6
-+	ldbx	$acc4($rounds),$acc4
-+	_srm	$t2,24,$acc8
-+	ldbx	$acc5($rounds),$acc5
-+	_srm	$t1,16,$acc9
-+	_srm	$t2,0,$acc7
-+	ldbx	$acc6($rounds),$acc6
-+	ldbx	$acc7($rounds),$acc7
-+	_srm	$t0,8,$acc10
-+	ldbx	$acc8($rounds),$acc8
-+	_srm	$t3,24,$acc12
-+	ldbx	$acc9($rounds),$acc9
-+	_srm	$t2,16,$acc13
-+	_srm	$t3,0,$acc11
-+	ldbx	$acc10($rounds),$acc10
-+	_srm	$t1,8,$acc14
-+	ldbx	$acc11($rounds),$acc11
-+	ldbx	$acc12($rounds),$acc12
-+	ldbx	$acc13($rounds),$acc13
-+	_srm	$t0,0,$acc15
-+	ldbx	$acc14($rounds),$acc14
-+
-+		dep	$acc0,7,8,$acc3
-+	ldbx	$acc15($rounds),$acc15
-+		dep	$acc4,7,8,$acc7
-+		dep	$acc1,15,8,$acc3
-+		dep	$acc5,15,8,$acc7
-+		dep	$acc2,23,8,$acc3
-+		dep	$acc6,23,8,$acc7
-+		xor	$acc3,$s0,$s0
-+		xor	$acc7,$s1,$s1
-+		dep	$acc8,7,8,$acc11
-+		dep	$acc12,7,8,$acc15
-+		dep	$acc9,15,8,$acc11
-+		dep	$acc13,15,8,$acc15
-+		dep	$acc10,23,8,$acc11
-+		dep	$acc14,23,8,$acc15
-+		xor	$acc11,$s2,$s2
-+
-+	bv	(%r31)
-+	.EXIT
-+		xor	$acc15,$s3,$s3
-+	.PROCEND
-+
-+	.ALIGN	64
-+L\$AES_Td
-+	.WORD	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
-+	.WORD	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
-+	.WORD	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
-+	.WORD	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
-+	.WORD	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
-+	.WORD	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
-+	.WORD	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
-+	.WORD	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
-+	.WORD	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
-+	.WORD	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
-+	.WORD	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
-+	.WORD	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
-+	.WORD	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
-+	.WORD	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
-+	.WORD	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
-+	.WORD	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
-+	.WORD	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
-+	.WORD	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
-+	.WORD	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
-+	.WORD	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
-+	.WORD	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
-+	.WORD	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
-+	.WORD	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
-+	.WORD	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
-+	.WORD	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
-+	.WORD	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
-+	.WORD	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
-+	.WORD	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
-+	.WORD	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
-+	.WORD	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
-+	.WORD	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
-+	.WORD	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
-+	.WORD	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
-+	.WORD	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
-+	.WORD	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
-+	.WORD	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
-+	.WORD	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
-+	.WORD	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
-+	.WORD	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
-+	.WORD	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
-+	.WORD	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
-+	.WORD	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
-+	.WORD	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
-+	.WORD	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
-+	.WORD	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
-+	.WORD	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
-+	.WORD	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
-+	.WORD	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
-+	.WORD	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
-+	.WORD	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
-+	.WORD	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
-+	.WORD	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
-+	.WORD	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
-+	.WORD	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
-+	.WORD	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
-+	.WORD	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
-+	.WORD	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
-+	.WORD	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
-+	.WORD	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
-+	.WORD	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
-+	.WORD	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
-+	.WORD	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
-+	.WORD	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
-+	.WORD	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
-+	.BYTE	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-+	.BYTE	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-+	.BYTE	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-+	.BYTE	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-+	.BYTE	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-+	.BYTE	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-+	.BYTE	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-+	.BYTE	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-+	.BYTE	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-+	.BYTE	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-+	.BYTE	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-+	.BYTE	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-+	.BYTE	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-+	.BYTE	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-+	.BYTE	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-+	.BYTE	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-+	.BYTE	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-+	.BYTE	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-+	.BYTE	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-+	.BYTE	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-+	.BYTE	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-+	.BYTE	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-+	.BYTE	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-+	.BYTE	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-+	.BYTE	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-+	.BYTE	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-+	.BYTE	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-+	.BYTE	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-+	.BYTE	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-+	.BYTE	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-+	.BYTE	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-+	.BYTE	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+	.STRINGZ "AES for PA-RISC, CRYPTOGAMS by "
-+___
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	# translate made up instructons: _ror, _srm
-+	s/_ror(\s+)(%r[0-9]+),/shd$1$2,$2,/				or
-+
-+	s/_srm(\s+%r[0-9]+),([0-9]+),/
-+		$SIZE_T==4 ? sprintf("extru%s,%d,8,",$1,31-$2)
-+		:            sprintf("extrd,u%s,%d,8,",$1,63-$2)/e;
-+
-+	s/,\*/,/			if ($SIZE_T==4);
-+	s/\bbv\b(.*\(%r2\))/bve$1/	if ($SIZE_T==8);
-+	print $_,"\n";
-+}
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-ppc.pl
-new file mode 100644
-index 0000000..1558d8e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-ppc.pl
-@@ -0,0 +1,1459 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# Needs more work: key setup, CBC routine...
-+#
-+# ppc_AES_[en|de]crypt perform at 18 cycles per byte processed with
-+# 128-bit key, which is ~40% better than 64-bit code generated by gcc
-+# 4.0. But these are not the ones currently used! Their "compact"
-+# counterparts are, for security reason. ppc_AES_encrypt_compact runs
-+# at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact -
-+# at 1/3 of ppc_AES_decrypt.
-+
-+# February 2010
-+#
-+# Rescheduling instructions to favour Power6 pipeline gave 10%
-+# performance improvement on the platform in question (and marginal
-+# improvement even on others). It should be noted that Power6 fails
-+# to process byte in 18 cycles, only in 23, because it fails to issue
-+# 4 load instructions in two cycles, only in 3. As result non-compact
-+# block subroutines are 25% slower than one would expect. Compact
-+# functions scale better, because they have pure computational part,
-+# which scales perfectly with clock frequency. To be specific
-+# ppc_AES_encrypt_compact operates at 42 cycles per byte, while
-+# ppc_AES_decrypt_compact - at 55 (in 64-bit build).
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /64/) {
-+	$SIZE_T	=8;
-+	$LRSAVE	=2*$SIZE_T;
-+	$STU	="stdu";
-+	$POP	="ld";
-+	$PUSH	="std";
-+} elsif ($flavour =~ /32/) {
-+	$SIZE_T	=4;
-+	$LRSAVE	=$SIZE_T;
-+	$STU	="stwu";
-+	$POP	="lwz";
-+	$PUSH	="stw";
-+} else { die "nonsense $flavour"; }
-+
-+$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-+
-+$FRAME=32*$SIZE_T;
-+
-+sub _data_word()
-+{ my $i;
-+    while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
-+}
-+
-+$sp="r1";
-+$toc="r2";
-+$inp="r3";
-+$out="r4";
-+$key="r5";
-+
-+$Tbl0="r3";
-+$Tbl1="r6";
-+$Tbl2="r7";
-+$Tbl3=$out;	# stay away from "r2"; $out is offloaded to stack
-+
-+$s0="r8";
-+$s1="r9";
-+$s2="r10";
-+$s3="r11";
-+
-+$t0="r12";
-+$t1="r0";	# stay away from "r13";
-+$t2="r14";
-+$t3="r15";
-+
-+$acc00="r16";
-+$acc01="r17";
-+$acc02="r18";
-+$acc03="r19";
-+
-+$acc04="r20";
-+$acc05="r21";
-+$acc06="r22";
-+$acc07="r23";
-+
-+$acc08="r24";
-+$acc09="r25";
-+$acc10="r26";
-+$acc11="r27";
-+
-+$acc12="r28";
-+$acc13="r29";
-+$acc14="r30";
-+$acc15="r31";
-+
-+$mask80=$Tbl2;
-+$mask1b=$Tbl3;
-+
-+$code.=<<___;
-+.machine	"any"
-+.text
-+
-+.align	7
-+LAES_Te:
-+	mflr	r0
-+	bcl	20,31,\$+4
-+	mflr	$Tbl0	;    vvvvv "distance" between . and 1st data entry
-+	addi	$Tbl0,$Tbl0,`128-8`
-+	mtlr	r0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+	.space	`64-9*4`
-+LAES_Td:
-+	mflr	r0
-+	bcl	20,31,\$+4
-+	mflr	$Tbl0	;    vvvvvvvv "distance" between . and 1st data entry
-+	addi	$Tbl0,$Tbl0,`128-64-8+2048+256`
-+	mtlr	r0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+	.space	`128-64-9*4`
-+___
-+&_data_word(
-+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
-+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
-+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
-+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
-+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
-+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
-+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
-+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
-+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
-+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
-+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
-+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
-+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
-+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
-+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
-+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
-+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
-+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
-+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
-+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
-+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
-+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
-+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
-+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
-+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
-+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
-+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
-+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
-+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
-+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
-+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
-+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
-+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
-+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
-+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
-+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
-+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
-+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
-+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
-+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
-+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
-+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
-+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
-+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
-+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
-+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
-+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
-+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
-+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
-+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
-+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
-+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
-+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
-+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
-+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
-+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
-+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
-+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
-+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
-+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
-+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
-+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
-+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
-+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
-+$code.=<<___;
-+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+___
-+&_data_word(
-+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
-+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
-+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
-+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
-+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
-+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
-+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
-+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
-+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
-+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
-+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
-+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
-+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
-+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
-+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
-+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
-+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
-+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
-+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
-+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
-+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
-+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
-+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
-+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
-+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
-+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
-+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
-+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
-+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
-+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
-+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
-+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
-+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
-+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
-+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
-+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
-+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
-+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
-+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
-+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
-+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
-+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
-+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
-+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
-+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
-+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
-+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
-+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
-+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
-+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
-+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
-+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
-+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
-+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
-+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
-+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
-+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
-+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
-+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
-+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
-+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
-+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
-+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
-+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
-+$code.=<<___;
-+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+
-+
-+.globl	.AES_encrypt
-+.align	7
-+.AES_encrypt:
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+
-+	$PUSH	$out,`$FRAME-$SIZE_T*19`($sp)
-+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
-+	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
-+
-+	andi.	$t0,$inp,3
-+	andi.	$t1,$out,3
-+	or.	$t0,$t0,$t1
-+	bne	Lenc_unaligned
-+
-+Lenc_unaligned_ok:
-+___
-+$code.=<<___ if (!$LITTLE_ENDIAN);
-+	lwz	$s0,0($inp)
-+	lwz	$s1,4($inp)
-+	lwz	$s2,8($inp)
-+	lwz	$s3,12($inp)
-+___
-+$code.=<<___ if ($LITTLE_ENDIAN);
-+	lwz	$t0,0($inp)
-+	lwz	$t1,4($inp)
-+	lwz	$t2,8($inp)
-+	lwz	$t3,12($inp)
-+	rotlwi	$s0,$t0,8
-+	rotlwi	$s1,$t1,8
-+	rotlwi	$s2,$t2,8
-+	rotlwi	$s3,$t3,8
-+	rlwimi	$s0,$t0,24,0,7
-+	rlwimi	$s1,$t1,24,0,7
-+	rlwimi	$s2,$t2,24,0,7
-+	rlwimi	$s3,$t3,24,0,7
-+	rlwimi	$s0,$t0,24,16,23
-+	rlwimi	$s1,$t1,24,16,23
-+	rlwimi	$s2,$t2,24,16,23
-+	rlwimi	$s3,$t3,24,16,23
-+___
-+$code.=<<___;
-+	bl	LAES_Te
-+	bl	Lppc_AES_encrypt_compact
-+	$POP	$out,`$FRAME-$SIZE_T*19`($sp)
-+___
-+$code.=<<___ if ($LITTLE_ENDIAN);
-+	rotlwi	$t0,$s0,8
-+	rotlwi	$t1,$s1,8
-+	rotlwi	$t2,$s2,8
-+	rotlwi	$t3,$s3,8
-+	rlwimi	$t0,$s0,24,0,7
-+	rlwimi	$t1,$s1,24,0,7
-+	rlwimi	$t2,$s2,24,0,7
-+	rlwimi	$t3,$s3,24,0,7
-+	rlwimi	$t0,$s0,24,16,23
-+	rlwimi	$t1,$s1,24,16,23
-+	rlwimi	$t2,$s2,24,16,23
-+	rlwimi	$t3,$s3,24,16,23
-+	stw	$t0,0($out)
-+	stw	$t1,4($out)
-+	stw	$t2,8($out)
-+	stw	$t3,12($out)
-+___
-+$code.=<<___ if (!$LITTLE_ENDIAN);
-+	stw	$s0,0($out)
-+	stw	$s1,4($out)
-+	stw	$s2,8($out)
-+	stw	$s3,12($out)
-+___
-+$code.=<<___;
-+	b	Lenc_done
-+
-+Lenc_unaligned:
-+	subfic	$t0,$inp,4096
-+	subfic	$t1,$out,4096
-+	andi.	$t0,$t0,4096-16
-+	beq	Lenc_xpage
-+	andi.	$t1,$t1,4096-16
-+	bne	Lenc_unaligned_ok
-+
-+Lenc_xpage:
-+	lbz	$acc00,0($inp)
-+	lbz	$acc01,1($inp)
-+	lbz	$acc02,2($inp)
-+	lbz	$s0,3($inp)
-+	lbz	$acc04,4($inp)
-+	lbz	$acc05,5($inp)
-+	lbz	$acc06,6($inp)
-+	lbz	$s1,7($inp)
-+	lbz	$acc08,8($inp)
-+	lbz	$acc09,9($inp)
-+	lbz	$acc10,10($inp)
-+	insrwi	$s0,$acc00,8,0
-+	lbz	$s2,11($inp)
-+	insrwi	$s1,$acc04,8,0
-+	lbz	$acc12,12($inp)
-+	insrwi	$s0,$acc01,8,8
-+	lbz	$acc13,13($inp)
-+	insrwi	$s1,$acc05,8,8
-+	lbz	$acc14,14($inp)
-+	insrwi	$s0,$acc02,8,16
-+	lbz	$s3,15($inp)
-+	insrwi	$s1,$acc06,8,16
-+	insrwi	$s2,$acc08,8,0
-+	insrwi	$s3,$acc12,8,0
-+	insrwi	$s2,$acc09,8,8
-+	insrwi	$s3,$acc13,8,8
-+	insrwi	$s2,$acc10,8,16
-+	insrwi	$s3,$acc14,8,16
-+
-+	bl	LAES_Te
-+	bl	Lppc_AES_encrypt_compact
-+	$POP	$out,`$FRAME-$SIZE_T*19`($sp)
-+
-+	extrwi	$acc00,$s0,8,0
-+	extrwi	$acc01,$s0,8,8
-+	stb	$acc00,0($out)
-+	extrwi	$acc02,$s0,8,16
-+	stb	$acc01,1($out)
-+	stb	$acc02,2($out)
-+	extrwi	$acc04,$s1,8,0
-+	stb	$s0,3($out)
-+	extrwi	$acc05,$s1,8,8
-+	stb	$acc04,4($out)
-+	extrwi	$acc06,$s1,8,16
-+	stb	$acc05,5($out)
-+	stb	$acc06,6($out)
-+	extrwi	$acc08,$s2,8,0
-+	stb	$s1,7($out)
-+	extrwi	$acc09,$s2,8,8
-+	stb	$acc08,8($out)
-+	extrwi	$acc10,$s2,8,16
-+	stb	$acc09,9($out)
-+	stb	$acc10,10($out)
-+	extrwi	$acc12,$s3,8,0
-+	stb	$s2,11($out)
-+	extrwi	$acc13,$s3,8,8
-+	stb	$acc12,12($out)
-+	extrwi	$acc14,$s3,8,16
-+	stb	$acc13,13($out)
-+	stb	$acc14,14($out)
-+	stb	$s3,15($out)
-+
-+Lenc_done:
-+	$POP	r0,`$FRAME+$LRSAVE`($sp)
-+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
-+	mtlr	r0
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,18,3,0
-+	.long	0
-+
-+.align	5
-+Lppc_AES_encrypt:
-+	lwz	$acc00,240($key)
-+	addi	$Tbl1,$Tbl0,3
-+	lwz	$t0,0($key)
-+	addi	$Tbl2,$Tbl0,2
-+	lwz	$t1,4($key)
-+	addi	$Tbl3,$Tbl0,1
-+	lwz	$t2,8($key)
-+	addi	$acc00,$acc00,-1
-+	lwz	$t3,12($key)
-+	addi	$key,$key,16
-+	xor	$s0,$s0,$t0
-+	xor	$s1,$s1,$t1
-+	xor	$s2,$s2,$t2
-+	xor	$s3,$s3,$t3
-+	mtctr	$acc00
-+.align	4
-+Lenc_loop:
-+	rlwinm	$acc00,$s0,`32-24+3`,21,28
-+	rlwinm	$acc01,$s1,`32-24+3`,21,28
-+	rlwinm	$acc02,$s2,`32-24+3`,21,28
-+	rlwinm	$acc03,$s3,`32-24+3`,21,28
-+	lwz	$t0,0($key)
-+	rlwinm	$acc04,$s1,`32-16+3`,21,28
-+	lwz	$t1,4($key)
-+	rlwinm	$acc05,$s2,`32-16+3`,21,28
-+	lwz	$t2,8($key)
-+	rlwinm	$acc06,$s3,`32-16+3`,21,28
-+	lwz	$t3,12($key)
-+	rlwinm	$acc07,$s0,`32-16+3`,21,28
-+	lwzx	$acc00,$Tbl0,$acc00
-+	rlwinm	$acc08,$s2,`32-8+3`,21,28
-+	lwzx	$acc01,$Tbl0,$acc01
-+	rlwinm	$acc09,$s3,`32-8+3`,21,28
-+	lwzx	$acc02,$Tbl0,$acc02
-+	rlwinm	$acc10,$s0,`32-8+3`,21,28
-+	lwzx	$acc03,$Tbl0,$acc03
-+	rlwinm	$acc11,$s1,`32-8+3`,21,28
-+	lwzx	$acc04,$Tbl1,$acc04
-+	rlwinm	$acc12,$s3,`0+3`,21,28
-+	lwzx	$acc05,$Tbl1,$acc05
-+	rlwinm	$acc13,$s0,`0+3`,21,28
-+	lwzx	$acc06,$Tbl1,$acc06
-+	rlwinm	$acc14,$s1,`0+3`,21,28
-+	lwzx	$acc07,$Tbl1,$acc07
-+	rlwinm	$acc15,$s2,`0+3`,21,28
-+	lwzx	$acc08,$Tbl2,$acc08
-+	xor	$t0,$t0,$acc00
-+	lwzx	$acc09,$Tbl2,$acc09
-+	xor	$t1,$t1,$acc01
-+	lwzx	$acc10,$Tbl2,$acc10
-+	xor	$t2,$t2,$acc02
-+	lwzx	$acc11,$Tbl2,$acc11
-+	xor	$t3,$t3,$acc03
-+	lwzx	$acc12,$Tbl3,$acc12
-+	xor	$t0,$t0,$acc04
-+	lwzx	$acc13,$Tbl3,$acc13
-+	xor	$t1,$t1,$acc05
-+	lwzx	$acc14,$Tbl3,$acc14
-+	xor	$t2,$t2,$acc06
-+	lwzx	$acc15,$Tbl3,$acc15
-+	xor	$t3,$t3,$acc07
-+	xor	$t0,$t0,$acc08
-+	xor	$t1,$t1,$acc09
-+	xor	$t2,$t2,$acc10
-+	xor	$t3,$t3,$acc11
-+	xor	$s0,$t0,$acc12
-+	xor	$s1,$t1,$acc13
-+	xor	$s2,$t2,$acc14
-+	xor	$s3,$t3,$acc15
-+	addi	$key,$key,16
-+	bdnz	Lenc_loop
-+
-+	addi	$Tbl2,$Tbl0,2048
-+	nop
-+	lwz	$t0,0($key)
-+	rlwinm	$acc00,$s0,`32-24`,24,31
-+	lwz	$t1,4($key)
-+	rlwinm	$acc01,$s1,`32-24`,24,31
-+	lwz	$t2,8($key)
-+	rlwinm	$acc02,$s2,`32-24`,24,31
-+	lwz	$t3,12($key)
-+	rlwinm	$acc03,$s3,`32-24`,24,31
-+	lwz	$acc08,`2048+0`($Tbl0)	! prefetch Te4
-+	rlwinm	$acc04,$s1,`32-16`,24,31
-+	lwz	$acc09,`2048+32`($Tbl0)
-+	rlwinm	$acc05,$s2,`32-16`,24,31
-+	lwz	$acc10,`2048+64`($Tbl0)
-+	rlwinm	$acc06,$s3,`32-16`,24,31
-+	lwz	$acc11,`2048+96`($Tbl0)
-+	rlwinm	$acc07,$s0,`32-16`,24,31
-+	lwz	$acc12,`2048+128`($Tbl0)
-+	rlwinm	$acc08,$s2,`32-8`,24,31
-+	lwz	$acc13,`2048+160`($Tbl0)
-+	rlwinm	$acc09,$s3,`32-8`,24,31
-+	lwz	$acc14,`2048+192`($Tbl0)
-+	rlwinm	$acc10,$s0,`32-8`,24,31
-+	lwz	$acc15,`2048+224`($Tbl0)
-+	rlwinm	$acc11,$s1,`32-8`,24,31
-+	lbzx	$acc00,$Tbl2,$acc00
-+	rlwinm	$acc12,$s3,`0`,24,31
-+	lbzx	$acc01,$Tbl2,$acc01
-+	rlwinm	$acc13,$s0,`0`,24,31
-+	lbzx	$acc02,$Tbl2,$acc02
-+	rlwinm	$acc14,$s1,`0`,24,31
-+	lbzx	$acc03,$Tbl2,$acc03
-+	rlwinm	$acc15,$s2,`0`,24,31
-+	lbzx	$acc04,$Tbl2,$acc04
-+	rlwinm	$s0,$acc00,24,0,7
-+	lbzx	$acc05,$Tbl2,$acc05
-+	rlwinm	$s1,$acc01,24,0,7
-+	lbzx	$acc06,$Tbl2,$acc06
-+	rlwinm	$s2,$acc02,24,0,7
-+	lbzx	$acc07,$Tbl2,$acc07
-+	rlwinm	$s3,$acc03,24,0,7
-+	lbzx	$acc08,$Tbl2,$acc08
-+	rlwimi	$s0,$acc04,16,8,15
-+	lbzx	$acc09,$Tbl2,$acc09
-+	rlwimi	$s1,$acc05,16,8,15
-+	lbzx	$acc10,$Tbl2,$acc10
-+	rlwimi	$s2,$acc06,16,8,15
-+	lbzx	$acc11,$Tbl2,$acc11
-+	rlwimi	$s3,$acc07,16,8,15
-+	lbzx	$acc12,$Tbl2,$acc12
-+	rlwimi	$s0,$acc08,8,16,23
-+	lbzx	$acc13,$Tbl2,$acc13
-+	rlwimi	$s1,$acc09,8,16,23
-+	lbzx	$acc14,$Tbl2,$acc14
-+	rlwimi	$s2,$acc10,8,16,23
-+	lbzx	$acc15,$Tbl2,$acc15
-+	rlwimi	$s3,$acc11,8,16,23
-+	or	$s0,$s0,$acc12
-+	or	$s1,$s1,$acc13
-+	or	$s2,$s2,$acc14
-+	or	$s3,$s3,$acc15
-+	xor	$s0,$s0,$t0
-+	xor	$s1,$s1,$t1
-+	xor	$s2,$s2,$t2
-+	xor	$s3,$s3,$t3
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+.align	4
-+Lppc_AES_encrypt_compact:
-+	lwz	$acc00,240($key)
-+	addi	$Tbl1,$Tbl0,2048
-+	lwz	$t0,0($key)
-+	lis	$mask80,0x8080
-+	lwz	$t1,4($key)
-+	lis	$mask1b,0x1b1b
-+	lwz	$t2,8($key)
-+	ori	$mask80,$mask80,0x8080
-+	lwz	$t3,12($key)
-+	ori	$mask1b,$mask1b,0x1b1b
-+	addi	$key,$key,16
-+	mtctr	$acc00
-+.align	4
-+Lenc_compact_loop:
-+	xor	$s0,$s0,$t0
-+	xor	$s1,$s1,$t1
-+	rlwinm	$acc00,$s0,`32-24`,24,31
-+	xor	$s2,$s2,$t2
-+	rlwinm	$acc01,$s1,`32-24`,24,31
-+	xor	$s3,$s3,$t3
-+	rlwinm	$acc02,$s2,`32-24`,24,31
-+	rlwinm	$acc03,$s3,`32-24`,24,31
-+	rlwinm	$acc04,$s1,`32-16`,24,31
-+	rlwinm	$acc05,$s2,`32-16`,24,31
-+	rlwinm	$acc06,$s3,`32-16`,24,31
-+	rlwinm	$acc07,$s0,`32-16`,24,31
-+	lbzx	$acc00,$Tbl1,$acc00
-+	rlwinm	$acc08,$s2,`32-8`,24,31
-+	lbzx	$acc01,$Tbl1,$acc01
-+	rlwinm	$acc09,$s3,`32-8`,24,31
-+	lbzx	$acc02,$Tbl1,$acc02
-+	rlwinm	$acc10,$s0,`32-8`,24,31
-+	lbzx	$acc03,$Tbl1,$acc03
-+	rlwinm	$acc11,$s1,`32-8`,24,31
-+	lbzx	$acc04,$Tbl1,$acc04
-+	rlwinm	$acc12,$s3,`0`,24,31
-+	lbzx	$acc05,$Tbl1,$acc05
-+	rlwinm	$acc13,$s0,`0`,24,31
-+	lbzx	$acc06,$Tbl1,$acc06
-+	rlwinm	$acc14,$s1,`0`,24,31
-+	lbzx	$acc07,$Tbl1,$acc07
-+	rlwinm	$acc15,$s2,`0`,24,31
-+	lbzx	$acc08,$Tbl1,$acc08
-+	rlwinm	$s0,$acc00,24,0,7
-+	lbzx	$acc09,$Tbl1,$acc09
-+	rlwinm	$s1,$acc01,24,0,7
-+	lbzx	$acc10,$Tbl1,$acc10
-+	rlwinm	$s2,$acc02,24,0,7
-+	lbzx	$acc11,$Tbl1,$acc11
-+	rlwinm	$s3,$acc03,24,0,7
-+	lbzx	$acc12,$Tbl1,$acc12
-+	rlwimi	$s0,$acc04,16,8,15
-+	lbzx	$acc13,$Tbl1,$acc13
-+	rlwimi	$s1,$acc05,16,8,15
-+	lbzx	$acc14,$Tbl1,$acc14
-+	rlwimi	$s2,$acc06,16,8,15
-+	lbzx	$acc15,$Tbl1,$acc15
-+	rlwimi	$s3,$acc07,16,8,15
-+	rlwimi	$s0,$acc08,8,16,23
-+	rlwimi	$s1,$acc09,8,16,23
-+	rlwimi	$s2,$acc10,8,16,23
-+	rlwimi	$s3,$acc11,8,16,23
-+	lwz	$t0,0($key)
-+	or	$s0,$s0,$acc12
-+	lwz	$t1,4($key)
-+	or	$s1,$s1,$acc13
-+	lwz	$t2,8($key)
-+	or	$s2,$s2,$acc14
-+	lwz	$t3,12($key)
-+	or	$s3,$s3,$acc15
-+
-+	addi	$key,$key,16
-+	bdz	Lenc_compact_done
-+
-+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
-+	and	$acc01,$s1,$mask80
-+	and	$acc02,$s2,$mask80
-+	and	$acc03,$s3,$mask80
-+	srwi	$acc04,$acc00,7		# r1>>7
-+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
-+	srwi	$acc05,$acc01,7
-+	andc	$acc09,$s1,$mask80
-+	srwi	$acc06,$acc02,7
-+	andc	$acc10,$s2,$mask80
-+	srwi	$acc07,$acc03,7
-+	andc	$acc11,$s3,$mask80
-+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
-+	sub	$acc01,$acc01,$acc05
-+	sub	$acc02,$acc02,$acc06
-+	sub	$acc03,$acc03,$acc07
-+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
-+	add	$acc09,$acc09,$acc09
-+	add	$acc10,$acc10,$acc10
-+	add	$acc11,$acc11,$acc11
-+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
-+	and	$acc01,$acc01,$mask1b
-+	and	$acc02,$acc02,$mask1b
-+	and	$acc03,$acc03,$mask1b
-+	xor	$acc00,$acc00,$acc08	# r2
-+	xor	$acc01,$acc01,$acc09
-+	 rotlwi	$acc12,$s0,16		# ROTATE(r0,16)
-+	xor	$acc02,$acc02,$acc10
-+	 rotlwi	$acc13,$s1,16
-+	xor	$acc03,$acc03,$acc11
-+	 rotlwi	$acc14,$s2,16
-+
-+	xor	$s0,$s0,$acc00		# r0^r2
-+	rotlwi	$acc15,$s3,16
-+	xor	$s1,$s1,$acc01
-+	rotrwi	$s0,$s0,24		# ROTATE(r2^r0,24)
-+	xor	$s2,$s2,$acc02
-+	rotrwi	$s1,$s1,24
-+	xor	$s3,$s3,$acc03
-+	rotrwi	$s2,$s2,24
-+	xor	$s0,$s0,$acc00		# ROTATE(r2^r0,24)^r2
-+	rotrwi	$s3,$s3,24
-+	xor	$s1,$s1,$acc01
-+	xor	$s2,$s2,$acc02
-+	xor	$s3,$s3,$acc03
-+	rotlwi	$acc08,$acc12,8		# ROTATE(r0,24)
-+	xor	$s0,$s0,$acc12		#
-+	rotlwi	$acc09,$acc13,8
-+	xor	$s1,$s1,$acc13
-+	rotlwi	$acc10,$acc14,8
-+	xor	$s2,$s2,$acc14
-+	rotlwi	$acc11,$acc15,8
-+	xor	$s3,$s3,$acc15
-+	xor	$s0,$s0,$acc08		#
-+	xor	$s1,$s1,$acc09
-+	xor	$s2,$s2,$acc10
-+	xor	$s3,$s3,$acc11
-+
-+	b	Lenc_compact_loop
-+.align	4
-+Lenc_compact_done:
-+	xor	$s0,$s0,$t0
-+	xor	$s1,$s1,$t1
-+	xor	$s2,$s2,$t2
-+	xor	$s3,$s3,$t3
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+.size	.AES_encrypt,.-.AES_encrypt
-+
-+.globl	.AES_decrypt
-+.align	7
-+.AES_decrypt:
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+
-+	$PUSH	$out,`$FRAME-$SIZE_T*19`($sp)
-+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
-+	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
-+
-+	andi.	$t0,$inp,3
-+	andi.	$t1,$out,3
-+	or.	$t0,$t0,$t1
-+	bne	Ldec_unaligned
-+
-+Ldec_unaligned_ok:
-+___
-+$code.=<<___ if (!$LITTLE_ENDIAN);
-+	lwz	$s0,0($inp)
-+	lwz	$s1,4($inp)
-+	lwz	$s2,8($inp)
-+	lwz	$s3,12($inp)
-+___
-+$code.=<<___ if ($LITTLE_ENDIAN);
-+	lwz	$t0,0($inp)
-+	lwz	$t1,4($inp)
-+	lwz	$t2,8($inp)
-+	lwz	$t3,12($inp)
-+	rotlwi	$s0,$t0,8
-+	rotlwi	$s1,$t1,8
-+	rotlwi	$s2,$t2,8
-+	rotlwi	$s3,$t3,8
-+	rlwimi	$s0,$t0,24,0,7
-+	rlwimi	$s1,$t1,24,0,7
-+	rlwimi	$s2,$t2,24,0,7
-+	rlwimi	$s3,$t3,24,0,7
-+	rlwimi	$s0,$t0,24,16,23
-+	rlwimi	$s1,$t1,24,16,23
-+	rlwimi	$s2,$t2,24,16,23
-+	rlwimi	$s3,$t3,24,16,23
-+___
-+$code.=<<___;
-+	bl	LAES_Td
-+	bl	Lppc_AES_decrypt_compact
-+	$POP	$out,`$FRAME-$SIZE_T*19`($sp)
-+___
-+$code.=<<___ if ($LITTLE_ENDIAN);
-+	rotlwi	$t0,$s0,8
-+	rotlwi	$t1,$s1,8
-+	rotlwi	$t2,$s2,8
-+	rotlwi	$t3,$s3,8
-+	rlwimi	$t0,$s0,24,0,7
-+	rlwimi	$t1,$s1,24,0,7
-+	rlwimi	$t2,$s2,24,0,7
-+	rlwimi	$t3,$s3,24,0,7
-+	rlwimi	$t0,$s0,24,16,23
-+	rlwimi	$t1,$s1,24,16,23
-+	rlwimi	$t2,$s2,24,16,23
-+	rlwimi	$t3,$s3,24,16,23
-+	stw	$t0,0($out)
-+	stw	$t1,4($out)
-+	stw	$t2,8($out)
-+	stw	$t3,12($out)
-+___
-+$code.=<<___ if (!$LITTLE_ENDIAN);
-+	stw	$s0,0($out)
-+	stw	$s1,4($out)
-+	stw	$s2,8($out)
-+	stw	$s3,12($out)
-+___
-+$code.=<<___;
-+	b	Ldec_done
-+
-+Ldec_unaligned:
-+	subfic	$t0,$inp,4096
-+	subfic	$t1,$out,4096
-+	andi.	$t0,$t0,4096-16
-+	beq	Ldec_xpage
-+	andi.	$t1,$t1,4096-16
-+	bne	Ldec_unaligned_ok
-+
-+Ldec_xpage:
-+	lbz	$acc00,0($inp)
-+	lbz	$acc01,1($inp)
-+	lbz	$acc02,2($inp)
-+	lbz	$s0,3($inp)
-+	lbz	$acc04,4($inp)
-+	lbz	$acc05,5($inp)
-+	lbz	$acc06,6($inp)
-+	lbz	$s1,7($inp)
-+	lbz	$acc08,8($inp)
-+	lbz	$acc09,9($inp)
-+	lbz	$acc10,10($inp)
-+	insrwi	$s0,$acc00,8,0
-+	lbz	$s2,11($inp)
-+	insrwi	$s1,$acc04,8,0
-+	lbz	$acc12,12($inp)
-+	insrwi	$s0,$acc01,8,8
-+	lbz	$acc13,13($inp)
-+	insrwi	$s1,$acc05,8,8
-+	lbz	$acc14,14($inp)
-+	insrwi	$s0,$acc02,8,16
-+	lbz	$s3,15($inp)
-+	insrwi	$s1,$acc06,8,16
-+	insrwi	$s2,$acc08,8,0
-+	insrwi	$s3,$acc12,8,0
-+	insrwi	$s2,$acc09,8,8
-+	insrwi	$s3,$acc13,8,8
-+	insrwi	$s2,$acc10,8,16
-+	insrwi	$s3,$acc14,8,16
-+
-+	bl	LAES_Td
-+	bl	Lppc_AES_decrypt_compact
-+	$POP	$out,`$FRAME-$SIZE_T*19`($sp)
-+
-+	extrwi	$acc00,$s0,8,0
-+	extrwi	$acc01,$s0,8,8
-+	stb	$acc00,0($out)
-+	extrwi	$acc02,$s0,8,16
-+	stb	$acc01,1($out)
-+	stb	$acc02,2($out)
-+	extrwi	$acc04,$s1,8,0
-+	stb	$s0,3($out)
-+	extrwi	$acc05,$s1,8,8
-+	stb	$acc04,4($out)
-+	extrwi	$acc06,$s1,8,16
-+	stb	$acc05,5($out)
-+	stb	$acc06,6($out)
-+	extrwi	$acc08,$s2,8,0
-+	stb	$s1,7($out)
-+	extrwi	$acc09,$s2,8,8
-+	stb	$acc08,8($out)
-+	extrwi	$acc10,$s2,8,16
-+	stb	$acc09,9($out)
-+	stb	$acc10,10($out)
-+	extrwi	$acc12,$s3,8,0
-+	stb	$s2,11($out)
-+	extrwi	$acc13,$s3,8,8
-+	stb	$acc12,12($out)
-+	extrwi	$acc14,$s3,8,16
-+	stb	$acc13,13($out)
-+	stb	$acc14,14($out)
-+	stb	$s3,15($out)
-+
-+Ldec_done:
-+	$POP	r0,`$FRAME+$LRSAVE`($sp)
-+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
-+	mtlr	r0
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,18,3,0
-+	.long	0
-+
-+.align	5
-+Lppc_AES_decrypt:
-+	lwz	$acc00,240($key)
-+	addi	$Tbl1,$Tbl0,3
-+	lwz	$t0,0($key)
-+	addi	$Tbl2,$Tbl0,2
-+	lwz	$t1,4($key)
-+	addi	$Tbl3,$Tbl0,1
-+	lwz	$t2,8($key)
-+	addi	$acc00,$acc00,-1
-+	lwz	$t3,12($key)
-+	addi	$key,$key,16
-+	xor	$s0,$s0,$t0
-+	xor	$s1,$s1,$t1
-+	xor	$s2,$s2,$t2
-+	xor	$s3,$s3,$t3
-+	mtctr	$acc00
-+.align	4
-+Ldec_loop:
-+	rlwinm	$acc00,$s0,`32-24+3`,21,28
-+	rlwinm	$acc01,$s1,`32-24+3`,21,28
-+	rlwinm	$acc02,$s2,`32-24+3`,21,28
-+	rlwinm	$acc03,$s3,`32-24+3`,21,28
-+	lwz	$t0,0($key)
-+	rlwinm	$acc04,$s3,`32-16+3`,21,28
-+	lwz	$t1,4($key)
-+	rlwinm	$acc05,$s0,`32-16+3`,21,28
-+	lwz	$t2,8($key)
-+	rlwinm	$acc06,$s1,`32-16+3`,21,28
-+	lwz	$t3,12($key)
-+	rlwinm	$acc07,$s2,`32-16+3`,21,28
-+	lwzx	$acc00,$Tbl0,$acc00
-+	rlwinm	$acc08,$s2,`32-8+3`,21,28
-+	lwzx	$acc01,$Tbl0,$acc01
-+	rlwinm	$acc09,$s3,`32-8+3`,21,28
-+	lwzx	$acc02,$Tbl0,$acc02
-+	rlwinm	$acc10,$s0,`32-8+3`,21,28
-+	lwzx	$acc03,$Tbl0,$acc03
-+	rlwinm	$acc11,$s1,`32-8+3`,21,28
-+	lwzx	$acc04,$Tbl1,$acc04
-+	rlwinm	$acc12,$s1,`0+3`,21,28
-+	lwzx	$acc05,$Tbl1,$acc05
-+	rlwinm	$acc13,$s2,`0+3`,21,28
-+	lwzx	$acc06,$Tbl1,$acc06
-+	rlwinm	$acc14,$s3,`0+3`,21,28
-+	lwzx	$acc07,$Tbl1,$acc07
-+	rlwinm	$acc15,$s0,`0+3`,21,28
-+	lwzx	$acc08,$Tbl2,$acc08
-+	xor	$t0,$t0,$acc00
-+	lwzx	$acc09,$Tbl2,$acc09
-+	xor	$t1,$t1,$acc01
-+	lwzx	$acc10,$Tbl2,$acc10
-+	xor	$t2,$t2,$acc02
-+	lwzx	$acc11,$Tbl2,$acc11
-+	xor	$t3,$t3,$acc03
-+	lwzx	$acc12,$Tbl3,$acc12
-+	xor	$t0,$t0,$acc04
-+	lwzx	$acc13,$Tbl3,$acc13
-+	xor	$t1,$t1,$acc05
-+	lwzx	$acc14,$Tbl3,$acc14
-+	xor	$t2,$t2,$acc06
-+	lwzx	$acc15,$Tbl3,$acc15
-+	xor	$t3,$t3,$acc07
-+	xor	$t0,$t0,$acc08
-+	xor	$t1,$t1,$acc09
-+	xor	$t2,$t2,$acc10
-+	xor	$t3,$t3,$acc11
-+	xor	$s0,$t0,$acc12
-+	xor	$s1,$t1,$acc13
-+	xor	$s2,$t2,$acc14
-+	xor	$s3,$t3,$acc15
-+	addi	$key,$key,16
-+	bdnz	Ldec_loop
-+
-+	addi	$Tbl2,$Tbl0,2048
-+	nop
-+	lwz	$t0,0($key)
-+	rlwinm	$acc00,$s0,`32-24`,24,31
-+	lwz	$t1,4($key)
-+	rlwinm	$acc01,$s1,`32-24`,24,31
-+	lwz	$t2,8($key)
-+	rlwinm	$acc02,$s2,`32-24`,24,31
-+	lwz	$t3,12($key)
-+	rlwinm	$acc03,$s3,`32-24`,24,31
-+	lwz	$acc08,`2048+0`($Tbl0)	! prefetch Td4
-+	rlwinm	$acc04,$s3,`32-16`,24,31
-+	lwz	$acc09,`2048+32`($Tbl0)
-+	rlwinm	$acc05,$s0,`32-16`,24,31
-+	lwz	$acc10,`2048+64`($Tbl0)
-+	lbzx	$acc00,$Tbl2,$acc00
-+	lwz	$acc11,`2048+96`($Tbl0)
-+	lbzx	$acc01,$Tbl2,$acc01
-+	lwz	$acc12,`2048+128`($Tbl0)
-+	rlwinm	$acc06,$s1,`32-16`,24,31
-+	lwz	$acc13,`2048+160`($Tbl0)
-+	rlwinm	$acc07,$s2,`32-16`,24,31
-+	lwz	$acc14,`2048+192`($Tbl0)
-+	rlwinm	$acc08,$s2,`32-8`,24,31
-+	lwz	$acc15,`2048+224`($Tbl0)
-+	rlwinm	$acc09,$s3,`32-8`,24,31
-+	lbzx	$acc02,$Tbl2,$acc02
-+	rlwinm	$acc10,$s0,`32-8`,24,31
-+	lbzx	$acc03,$Tbl2,$acc03
-+	rlwinm	$acc11,$s1,`32-8`,24,31
-+	lbzx	$acc04,$Tbl2,$acc04
-+	rlwinm	$acc12,$s1,`0`,24,31
-+	lbzx	$acc05,$Tbl2,$acc05
-+	rlwinm	$acc13,$s2,`0`,24,31
-+	lbzx	$acc06,$Tbl2,$acc06
-+	rlwinm	$acc14,$s3,`0`,24,31
-+	lbzx	$acc07,$Tbl2,$acc07
-+	rlwinm	$acc15,$s0,`0`,24,31
-+	lbzx	$acc08,$Tbl2,$acc08
-+	rlwinm	$s0,$acc00,24,0,7
-+	lbzx	$acc09,$Tbl2,$acc09
-+	rlwinm	$s1,$acc01,24,0,7
-+	lbzx	$acc10,$Tbl2,$acc10
-+	rlwinm	$s2,$acc02,24,0,7
-+	lbzx	$acc11,$Tbl2,$acc11
-+	rlwinm	$s3,$acc03,24,0,7
-+	lbzx	$acc12,$Tbl2,$acc12
-+	rlwimi	$s0,$acc04,16,8,15
-+	lbzx	$acc13,$Tbl2,$acc13
-+	rlwimi	$s1,$acc05,16,8,15
-+	lbzx	$acc14,$Tbl2,$acc14
-+	rlwimi	$s2,$acc06,16,8,15
-+	lbzx	$acc15,$Tbl2,$acc15
-+	rlwimi	$s3,$acc07,16,8,15
-+	rlwimi	$s0,$acc08,8,16,23
-+	rlwimi	$s1,$acc09,8,16,23
-+	rlwimi	$s2,$acc10,8,16,23
-+	rlwimi	$s3,$acc11,8,16,23
-+	or	$s0,$s0,$acc12
-+	or	$s1,$s1,$acc13
-+	or	$s2,$s2,$acc14
-+	or	$s3,$s3,$acc15
-+	xor	$s0,$s0,$t0
-+	xor	$s1,$s1,$t1
-+	xor	$s2,$s2,$t2
-+	xor	$s3,$s3,$t3
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+.align	4
-+Lppc_AES_decrypt_compact:
-+	lwz	$acc00,240($key)
-+	addi	$Tbl1,$Tbl0,2048
-+	lwz	$t0,0($key)
-+	lis	$mask80,0x8080
-+	lwz	$t1,4($key)
-+	lis	$mask1b,0x1b1b
-+	lwz	$t2,8($key)
-+	ori	$mask80,$mask80,0x8080
-+	lwz	$t3,12($key)
-+	ori	$mask1b,$mask1b,0x1b1b
-+	addi	$key,$key,16
-+___
-+$code.=<<___ if ($SIZE_T==8);
-+	insrdi	$mask80,$mask80,32,0
-+	insrdi	$mask1b,$mask1b,32,0
-+___
-+$code.=<<___;
-+	mtctr	$acc00
-+.align	4
-+Ldec_compact_loop:
-+	xor	$s0,$s0,$t0
-+	xor	$s1,$s1,$t1
-+	rlwinm	$acc00,$s0,`32-24`,24,31
-+	xor	$s2,$s2,$t2
-+	rlwinm	$acc01,$s1,`32-24`,24,31
-+	xor	$s3,$s3,$t3
-+	rlwinm	$acc02,$s2,`32-24`,24,31
-+	rlwinm	$acc03,$s3,`32-24`,24,31
-+	rlwinm	$acc04,$s3,`32-16`,24,31
-+	rlwinm	$acc05,$s0,`32-16`,24,31
-+	rlwinm	$acc06,$s1,`32-16`,24,31
-+	rlwinm	$acc07,$s2,`32-16`,24,31
-+	lbzx	$acc00,$Tbl1,$acc00
-+	rlwinm	$acc08,$s2,`32-8`,24,31
-+	lbzx	$acc01,$Tbl1,$acc01
-+	rlwinm	$acc09,$s3,`32-8`,24,31
-+	lbzx	$acc02,$Tbl1,$acc02
-+	rlwinm	$acc10,$s0,`32-8`,24,31
-+	lbzx	$acc03,$Tbl1,$acc03
-+	rlwinm	$acc11,$s1,`32-8`,24,31
-+	lbzx	$acc04,$Tbl1,$acc04
-+	rlwinm	$acc12,$s1,`0`,24,31
-+	lbzx	$acc05,$Tbl1,$acc05
-+	rlwinm	$acc13,$s2,`0`,24,31
-+	lbzx	$acc06,$Tbl1,$acc06
-+	rlwinm	$acc14,$s3,`0`,24,31
-+	lbzx	$acc07,$Tbl1,$acc07
-+	rlwinm	$acc15,$s0,`0`,24,31
-+	lbzx	$acc08,$Tbl1,$acc08
-+	rlwinm	$s0,$acc00,24,0,7
-+	lbzx	$acc09,$Tbl1,$acc09
-+	rlwinm	$s1,$acc01,24,0,7
-+	lbzx	$acc10,$Tbl1,$acc10
-+	rlwinm	$s2,$acc02,24,0,7
-+	lbzx	$acc11,$Tbl1,$acc11
-+	rlwinm	$s3,$acc03,24,0,7
-+	lbzx	$acc12,$Tbl1,$acc12
-+	rlwimi	$s0,$acc04,16,8,15
-+	lbzx	$acc13,$Tbl1,$acc13
-+	rlwimi	$s1,$acc05,16,8,15
-+	lbzx	$acc14,$Tbl1,$acc14
-+	rlwimi	$s2,$acc06,16,8,15
-+	lbzx	$acc15,$Tbl1,$acc15
-+	rlwimi	$s3,$acc07,16,8,15
-+	rlwimi	$s0,$acc08,8,16,23
-+	rlwimi	$s1,$acc09,8,16,23
-+	rlwimi	$s2,$acc10,8,16,23
-+	rlwimi	$s3,$acc11,8,16,23
-+	lwz	$t0,0($key)
-+	or	$s0,$s0,$acc12
-+	lwz	$t1,4($key)
-+	or	$s1,$s1,$acc13
-+	lwz	$t2,8($key)
-+	or	$s2,$s2,$acc14
-+	lwz	$t3,12($key)
-+	or	$s3,$s3,$acc15
-+
-+	addi	$key,$key,16
-+	bdz	Ldec_compact_done
-+___
-+$code.=<<___ if ($SIZE_T==8);
-+	# vectorized permutation improves decrypt performance by 10%
-+	insrdi	$s0,$s1,32,0
-+	insrdi	$s2,$s3,32,0
-+
-+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
-+	and	$acc02,$s2,$mask80
-+	srdi	$acc04,$acc00,7		# r1>>7
-+	srdi	$acc06,$acc02,7
-+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
-+	andc	$acc10,$s2,$mask80
-+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
-+	sub	$acc02,$acc02,$acc06
-+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
-+	add	$acc10,$acc10,$acc10
-+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
-+	and	$acc02,$acc02,$mask1b
-+	xor	$acc00,$acc00,$acc08	# r2
-+	xor	$acc02,$acc02,$acc10
-+
-+	and	$acc04,$acc00,$mask80	# r1=r2&0x80808080
-+	and	$acc06,$acc02,$mask80
-+	srdi	$acc08,$acc04,7		# r1>>7
-+	srdi	$acc10,$acc06,7
-+	andc	$acc12,$acc00,$mask80	# r2&0x7f7f7f7f
-+	andc	$acc14,$acc02,$mask80
-+	sub	$acc04,$acc04,$acc08	# r1-(r1>>7)
-+	sub	$acc06,$acc06,$acc10
-+	add	$acc12,$acc12,$acc12	# (r2&0x7f7f7f7f)<<1
-+	add	$acc14,$acc14,$acc14
-+	and	$acc04,$acc04,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
-+	and	$acc06,$acc06,$mask1b
-+	xor	$acc04,$acc04,$acc12	# r4
-+	xor	$acc06,$acc06,$acc14
-+
-+	and	$acc08,$acc04,$mask80	# r1=r4&0x80808080
-+	and	$acc10,$acc06,$mask80
-+	srdi	$acc12,$acc08,7		# r1>>7
-+	srdi	$acc14,$acc10,7
-+	sub	$acc08,$acc08,$acc12	# r1-(r1>>7)
-+	sub	$acc10,$acc10,$acc14
-+	andc	$acc12,$acc04,$mask80	# r4&0x7f7f7f7f
-+	andc	$acc14,$acc06,$mask80
-+	add	$acc12,$acc12,$acc12	# (r4&0x7f7f7f7f)<<1
-+	add	$acc14,$acc14,$acc14
-+	and	$acc08,$acc08,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
-+	and	$acc10,$acc10,$mask1b
-+	xor	$acc08,$acc08,$acc12	# r8
-+	xor	$acc10,$acc10,$acc14
-+
-+	xor	$acc00,$acc00,$s0	# r2^r0
-+	xor	$acc02,$acc02,$s2
-+	xor	$acc04,$acc04,$s0	# r4^r0
-+	xor	$acc06,$acc06,$s2
-+
-+	extrdi	$acc01,$acc00,32,0
-+	extrdi	$acc03,$acc02,32,0
-+	extrdi	$acc05,$acc04,32,0
-+	extrdi	$acc07,$acc06,32,0
-+	extrdi	$acc09,$acc08,32,0
-+	extrdi	$acc11,$acc10,32,0
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
-+	and	$acc01,$s1,$mask80
-+	and	$acc02,$s2,$mask80
-+	and	$acc03,$s3,$mask80
-+	srwi	$acc04,$acc00,7		# r1>>7
-+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
-+	srwi	$acc05,$acc01,7
-+	andc	$acc09,$s1,$mask80
-+	srwi	$acc06,$acc02,7
-+	andc	$acc10,$s2,$mask80
-+	srwi	$acc07,$acc03,7
-+	andc	$acc11,$s3,$mask80
-+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
-+	sub	$acc01,$acc01,$acc05
-+	sub	$acc02,$acc02,$acc06
-+	sub	$acc03,$acc03,$acc07
-+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
-+	add	$acc09,$acc09,$acc09
-+	add	$acc10,$acc10,$acc10
-+	add	$acc11,$acc11,$acc11
-+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
-+	and	$acc01,$acc01,$mask1b
-+	and	$acc02,$acc02,$mask1b
-+	and	$acc03,$acc03,$mask1b
-+	xor	$acc00,$acc00,$acc08	# r2
-+	xor	$acc01,$acc01,$acc09
-+	xor	$acc02,$acc02,$acc10
-+	xor	$acc03,$acc03,$acc11
-+
-+	and	$acc04,$acc00,$mask80	# r1=r2&0x80808080
-+	and	$acc05,$acc01,$mask80
-+	and	$acc06,$acc02,$mask80
-+	and	$acc07,$acc03,$mask80
-+	srwi	$acc08,$acc04,7		# r1>>7
-+	andc	$acc12,$acc00,$mask80	# r2&0x7f7f7f7f
-+	srwi	$acc09,$acc05,7
-+	andc	$acc13,$acc01,$mask80
-+	srwi	$acc10,$acc06,7
-+	andc	$acc14,$acc02,$mask80
-+	srwi	$acc11,$acc07,7
-+	andc	$acc15,$acc03,$mask80
-+	sub	$acc04,$acc04,$acc08	# r1-(r1>>7)
-+	sub	$acc05,$acc05,$acc09
-+	sub	$acc06,$acc06,$acc10
-+	sub	$acc07,$acc07,$acc11
-+	add	$acc12,$acc12,$acc12	# (r2&0x7f7f7f7f)<<1
-+	add	$acc13,$acc13,$acc13
-+	add	$acc14,$acc14,$acc14
-+	add	$acc15,$acc15,$acc15
-+	and	$acc04,$acc04,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
-+	and	$acc05,$acc05,$mask1b
-+	and	$acc06,$acc06,$mask1b
-+	and	$acc07,$acc07,$mask1b
-+	xor	$acc04,$acc04,$acc12	# r4
-+	xor	$acc05,$acc05,$acc13
-+	xor	$acc06,$acc06,$acc14
-+	xor	$acc07,$acc07,$acc15
-+
-+	and	$acc08,$acc04,$mask80	# r1=r4&0x80808080
-+	and	$acc09,$acc05,$mask80
-+	srwi	$acc12,$acc08,7		# r1>>7
-+	and	$acc10,$acc06,$mask80
-+	srwi	$acc13,$acc09,7
-+	and	$acc11,$acc07,$mask80
-+	srwi	$acc14,$acc10,7
-+	sub	$acc08,$acc08,$acc12	# r1-(r1>>7)
-+	srwi	$acc15,$acc11,7
-+	sub	$acc09,$acc09,$acc13
-+	sub	$acc10,$acc10,$acc14
-+	sub	$acc11,$acc11,$acc15
-+	andc	$acc12,$acc04,$mask80	# r4&0x7f7f7f7f
-+	andc	$acc13,$acc05,$mask80
-+	andc	$acc14,$acc06,$mask80
-+	andc	$acc15,$acc07,$mask80
-+	add	$acc12,$acc12,$acc12	# (r4&0x7f7f7f7f)<<1
-+	add	$acc13,$acc13,$acc13
-+	add	$acc14,$acc14,$acc14
-+	add	$acc15,$acc15,$acc15
-+	and	$acc08,$acc08,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
-+	and	$acc09,$acc09,$mask1b
-+	and	$acc10,$acc10,$mask1b
-+	and	$acc11,$acc11,$mask1b
-+	xor	$acc08,$acc08,$acc12	# r8
-+	xor	$acc09,$acc09,$acc13
-+	xor	$acc10,$acc10,$acc14
-+	xor	$acc11,$acc11,$acc15
-+
-+	xor	$acc00,$acc00,$s0	# r2^r0
-+	xor	$acc01,$acc01,$s1
-+	xor	$acc02,$acc02,$s2
-+	xor	$acc03,$acc03,$s3
-+	xor	$acc04,$acc04,$s0	# r4^r0
-+	xor	$acc05,$acc05,$s1
-+	xor	$acc06,$acc06,$s2
-+	xor	$acc07,$acc07,$s3
-+___
-+$code.=<<___;
-+	rotrwi	$s0,$s0,8		# = ROTATE(r0,8)
-+	rotrwi	$s1,$s1,8
-+	xor	$s0,$s0,$acc00		# ^= r2^r0
-+	rotrwi	$s2,$s2,8
-+	xor	$s1,$s1,$acc01
-+	rotrwi	$s3,$s3,8
-+	xor	$s2,$s2,$acc02
-+	xor	$s3,$s3,$acc03
-+	xor	$acc00,$acc00,$acc08
-+	xor	$acc01,$acc01,$acc09
-+	xor	$acc02,$acc02,$acc10
-+	xor	$acc03,$acc03,$acc11
-+	xor	$s0,$s0,$acc04		# ^= r4^r0
-+	rotrwi	$acc00,$acc00,24
-+	xor	$s1,$s1,$acc05
-+	rotrwi	$acc01,$acc01,24
-+	xor	$s2,$s2,$acc06
-+	rotrwi	$acc02,$acc02,24
-+	xor	$s3,$s3,$acc07
-+	rotrwi	$acc03,$acc03,24
-+	xor	$acc04,$acc04,$acc08
-+	xor	$acc05,$acc05,$acc09
-+	xor	$acc06,$acc06,$acc10
-+	xor	$acc07,$acc07,$acc11
-+	xor	$s0,$s0,$acc08		# ^= r8 [^((r4^r0)^(r2^r0)=r4^r2)]
-+	rotrwi	$acc04,$acc04,16
-+	xor	$s1,$s1,$acc09
-+	rotrwi	$acc05,$acc05,16
-+	xor	$s2,$s2,$acc10
-+	rotrwi	$acc06,$acc06,16
-+	xor	$s3,$s3,$acc11
-+	rotrwi	$acc07,$acc07,16
-+	xor	$s0,$s0,$acc00		# ^= ROTATE(r8^r2^r0,24)
-+	rotrwi	$acc08,$acc08,8
-+	xor	$s1,$s1,$acc01
-+	rotrwi	$acc09,$acc09,8
-+	xor	$s2,$s2,$acc02
-+	rotrwi	$acc10,$acc10,8
-+	xor	$s3,$s3,$acc03
-+	rotrwi	$acc11,$acc11,8
-+	xor	$s0,$s0,$acc04		# ^= ROTATE(r8^r4^r0,16)
-+	xor	$s1,$s1,$acc05
-+	xor	$s2,$s2,$acc06
-+	xor	$s3,$s3,$acc07
-+	xor	$s0,$s0,$acc08		# ^= ROTATE(r8,8)	
-+	xor	$s1,$s1,$acc09	
-+	xor	$s2,$s2,$acc10	
-+	xor	$s3,$s3,$acc11	
-+
-+	b	Ldec_compact_loop
-+.align	4
-+Ldec_compact_done:
-+	xor	$s0,$s0,$t0
-+	xor	$s1,$s1,$t1
-+	xor	$s2,$s2,$t2
-+	xor	$s3,$s3,$t3
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+.size	.AES_decrypt,.-.AES_decrypt
-+
-+.asciz	"AES for PPC, CRYPTOGAMS by "
-+.align	7
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-s390x.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-s390x.pl
-new file mode 100644
-index 0000000..a93d601
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-s390x.pl
-@@ -0,0 +1,2235 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# AES for s390x.
-+
-+# April 2007.
-+#
-+# Software performance improvement over gcc-generated code is ~70% and
-+# in absolute terms is ~73 cycles per byte processed with 128-bit key.
-+# You're likely to exclaim "why so slow?" Keep in mind that z-CPUs are
-+# *strictly* in-order execution and issued instruction [in this case
-+# load value from memory is critical] has to complete before execution
-+# flow proceeds. S-boxes are compressed to 2KB[+256B].
-+#
-+# As for hardware acceleration support. It's basically a "teaser," as
-+# it can and should be improved in several ways. Most notably support
-+# for CBC is not utilized, nor multiple blocks are ever processed.
-+# Then software key schedule can be postponed till hardware support
-+# detection... Performance improvement over assembler is reportedly
-+# ~2.5x, but can reach >8x [naturally on larger chunks] if proper
-+# support is implemented.
-+
-+# May 2007.
-+#
-+# Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided
-+# for 128-bit keys, if hardware support is detected.
-+
-+# Januray 2009.
-+#
-+# Add support for hardware AES192/256 and reschedule instructions to
-+# minimize/avoid Address Generation Interlock hazard and to favour
-+# dual-issue z10 pipeline. This gave ~25% improvement on z10 and
-+# almost 50% on z9. The gain is smaller on z10, because being dual-
-+# issue z10 makes it improssible to eliminate the interlock condition:
-+# critial path is not long enough. Yet it spends ~24 cycles per byte
-+# processed with 128-bit key.
-+#
-+# Unlike previous version hardware support detection takes place only
-+# at the moment of key schedule setup, which is denoted in key->rounds.
-+# This is done, because deferred key setup can't be made MT-safe, not
-+# for keys longer than 128 bits.
-+#
-+# Add AES_cbc_encrypt, which gives incredible performance improvement,
-+# it was measured to be ~6.6x. It's less than previously mentioned 8x,
-+# because software implementation was optimized.
-+
-+# May 2010.
-+#
-+# Add AES_ctr32_encrypt. If hardware-assisted, it provides up to 4.3x
-+# performance improvement over "generic" counter mode routine relying
-+# on single-block, also hardware-assisted, AES_encrypt. "Up to" refers
-+# to the fact that exact throughput value depends on current stack
-+# frame alignment within 4KB page. In worst case you get ~75% of the
-+# maximum, but *on average* it would be as much as ~98%. Meaning that
-+# worst case is unlike, it's like hitting ravine on plateau.
-+
-+# November 2010.
-+#
-+# Adapt for -m31 build. If kernel supports what's called "highgprs"
-+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
-+# instructions and achieve "64-bit" performance even in 31-bit legacy
-+# application context. The feature is not specific to any particular
-+# processor, as long as it's "z-CPU". Latter implies that the code
-+# remains z/Architecture specific. On z990 it was measured to perform
-+# 2x better than code generated by gcc 4.3.
-+
-+# December 2010.
-+#
-+# Add support for z196 "cipher message with counter" instruction.
-+# Note however that it's disengaged, because it was measured to
-+# perform ~12% worse than vanilla km-based code...
-+
-+# February 2011.
-+#
-+# Add AES_xts_[en|de]crypt. This includes support for z196 km-xts-aes
-+# instructions, which deliver ~70% improvement at 8KB block size over
-+# vanilla km-based code, 37% - at most like 512-bytes block size.
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /3[12]/) {
-+	$SIZE_T=4;
-+	$g="";
-+} else {
-+	$SIZE_T=8;
-+	$g="g";
-+}
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+$softonly=0;	# allow hardware support
-+
-+$t0="%r0";	$mask="%r0";
-+$t1="%r1";
-+$t2="%r2";	$inp="%r2";
-+$t3="%r3";	$out="%r3";	$bits="%r3";
-+$key="%r4";
-+$i1="%r5";
-+$i2="%r6";
-+$i3="%r7";
-+$s0="%r8";
-+$s1="%r9";
-+$s2="%r10";
-+$s3="%r11";
-+$tbl="%r12";
-+$rounds="%r13";
-+$ra="%r14";
-+$sp="%r15";
-+
-+$stdframe=16*$SIZE_T+4*8;
-+
-+sub _data_word()
-+{ my $i;
-+    while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
-+}
-+
-+$code=<<___;
-+.text
-+
-+.type	AES_Te,\@object
-+.align	256
-+AES_Te:
-+___
-+&_data_word(
-+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
-+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
-+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
-+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
-+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
-+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
-+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
-+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
-+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
-+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
-+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
-+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
-+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
-+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
-+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
-+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
-+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
-+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
-+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
-+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
-+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
-+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
-+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
-+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
-+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
-+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
-+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
-+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
-+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
-+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
-+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
-+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
-+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
-+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
-+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
-+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
-+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
-+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
-+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
-+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
-+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
-+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
-+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
-+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
-+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
-+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
-+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
-+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
-+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
-+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
-+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
-+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
-+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
-+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
-+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
-+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
-+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
-+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
-+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
-+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
-+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
-+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
-+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
-+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
-+$code.=<<___;
-+# Te4[256]
-+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+# rcon[]
-+.long	0x01000000, 0x02000000, 0x04000000, 0x08000000
-+.long	0x10000000, 0x20000000, 0x40000000, 0x80000000
-+.long	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
-+.align	256
-+.size	AES_Te,.-AES_Te
-+
-+# void AES_encrypt(const unsigned char *inp, unsigned char *out,
-+# 		 const AES_KEY *key) {
-+.globl	AES_encrypt
-+.type	AES_encrypt,\@function
-+AES_encrypt:
-+___
-+$code.=<<___ if (!$softonly);
-+	l	%r0,240($key)
-+	lhi	%r1,16
-+	clr	%r0,%r1
-+	jl	.Lesoft
-+
-+	la	%r1,0($key)
-+	#la	%r2,0($inp)
-+	la	%r4,0($out)
-+	lghi	%r3,16		# single block length
-+	.long	0xb92e0042	# km %r4,%r2
-+	brc	1,.-4		# can this happen?
-+	br	%r14
-+.align	64
-+.Lesoft:
-+___
-+$code.=<<___;
-+	stm${g}	%r3,$ra,3*$SIZE_T($sp)
-+
-+	llgf	$s0,0($inp)
-+	llgf	$s1,4($inp)
-+	llgf	$s2,8($inp)
-+	llgf	$s3,12($inp)
-+
-+	larl	$tbl,AES_Te
-+	bras	$ra,_s390x_AES_encrypt
-+
-+	l${g}	$out,3*$SIZE_T($sp)
-+	st	$s0,0($out)
-+	st	$s1,4($out)
-+	st	$s2,8($out)
-+	st	$s3,12($out)
-+
-+	lm${g}	%r6,$ra,6*$SIZE_T($sp)
-+	br	$ra
-+.size	AES_encrypt,.-AES_encrypt
-+
-+.type   _s390x_AES_encrypt,\@function
-+.align	16
-+_s390x_AES_encrypt:
-+	st${g}	$ra,15*$SIZE_T($sp)
-+	x	$s0,0($key)
-+	x	$s1,4($key)
-+	x	$s2,8($key)
-+	x	$s3,12($key)
-+	l	$rounds,240($key)
-+	llill	$mask,`0xff<<3`
-+	aghi	$rounds,-1
-+	j	.Lenc_loop
-+.align	16
-+.Lenc_loop:
-+	sllg	$t1,$s0,`0+3`
-+	srlg	$t2,$s0,`8-3`
-+	srlg	$t3,$s0,`16-3`
-+	srl	$s0,`24-3`
-+	nr	$s0,$mask
-+	ngr	$t1,$mask
-+	nr	$t2,$mask
-+	nr	$t3,$mask
-+
-+	srlg	$i1,$s1,`16-3`	# i0
-+	sllg	$i2,$s1,`0+3`
-+	srlg	$i3,$s1,`8-3`
-+	srl	$s1,`24-3`
-+	nr	$i1,$mask
-+	nr	$s1,$mask
-+	ngr	$i2,$mask
-+	nr	$i3,$mask
-+
-+	l	$s0,0($s0,$tbl)	# Te0[s0>>24]
-+	l	$t1,1($t1,$tbl)	# Te3[s0>>0]
-+	l	$t2,2($t2,$tbl) # Te2[s0>>8]
-+	l	$t3,3($t3,$tbl)	# Te1[s0>>16]
-+
-+	x	$s0,3($i1,$tbl)	# Te1[s1>>16]
-+	l	$s1,0($s1,$tbl)	# Te0[s1>>24]
-+	x	$t2,1($i2,$tbl)	# Te3[s1>>0]
-+	x	$t3,2($i3,$tbl)	# Te2[s1>>8]
-+
-+	srlg	$i1,$s2,`8-3`	# i0
-+	srlg	$i2,$s2,`16-3`	# i1
-+	nr	$i1,$mask
-+	nr	$i2,$mask
-+	sllg	$i3,$s2,`0+3`
-+	srl	$s2,`24-3`
-+	nr	$s2,$mask
-+	ngr	$i3,$mask
-+
-+	xr	$s1,$t1
-+	srlg	$ra,$s3,`8-3`	# i1
-+	sllg	$t1,$s3,`0+3`	# i0
-+	nr	$ra,$mask
-+	la	$key,16($key)
-+	ngr	$t1,$mask
-+
-+	x	$s0,2($i1,$tbl)	# Te2[s2>>8]
-+	x	$s1,3($i2,$tbl)	# Te1[s2>>16]
-+	l	$s2,0($s2,$tbl)	# Te0[s2>>24]
-+	x	$t3,1($i3,$tbl)	# Te3[s2>>0]
-+
-+	srlg	$i3,$s3,`16-3`	# i2
-+	xr	$s2,$t2
-+	srl	$s3,`24-3`
-+	nr	$i3,$mask
-+	nr	$s3,$mask
-+
-+	x	$s0,0($key)
-+	x	$s1,4($key)
-+	x	$s2,8($key)
-+	x	$t3,12($key)
-+
-+	x	$s0,1($t1,$tbl)	# Te3[s3>>0]
-+	x	$s1,2($ra,$tbl)	# Te2[s3>>8]
-+	x	$s2,3($i3,$tbl)	# Te1[s3>>16]
-+	l	$s3,0($s3,$tbl)	# Te0[s3>>24]
-+	xr	$s3,$t3
-+
-+	brct	$rounds,.Lenc_loop
-+	.align	16
-+
-+	sllg	$t1,$s0,`0+3`
-+	srlg	$t2,$s0,`8-3`
-+	ngr	$t1,$mask
-+	srlg	$t3,$s0,`16-3`
-+	srl	$s0,`24-3`
-+	nr	$s0,$mask
-+	nr	$t2,$mask
-+	nr	$t3,$mask
-+
-+	srlg	$i1,$s1,`16-3`	# i0
-+	sllg	$i2,$s1,`0+3`
-+	ngr	$i2,$mask
-+	srlg	$i3,$s1,`8-3`
-+	srl	$s1,`24-3`
-+	nr	$i1,$mask
-+	nr	$s1,$mask
-+	nr	$i3,$mask
-+
-+	llgc	$s0,2($s0,$tbl)	# Te4[s0>>24]
-+	llgc	$t1,2($t1,$tbl)	# Te4[s0>>0]
-+	sll	$s0,24
-+	llgc	$t2,2($t2,$tbl)	# Te4[s0>>8]
-+	llgc	$t3,2($t3,$tbl)	# Te4[s0>>16]
-+	sll	$t2,8
-+	sll	$t3,16
-+
-+	llgc	$i1,2($i1,$tbl)	# Te4[s1>>16]
-+	llgc	$s1,2($s1,$tbl)	# Te4[s1>>24]
-+	llgc	$i2,2($i2,$tbl)	# Te4[s1>>0]
-+	llgc	$i3,2($i3,$tbl)	# Te4[s1>>8]
-+	sll	$i1,16
-+	sll	$s1,24
-+	sll	$i3,8
-+	or	$s0,$i1
-+	or	$s1,$t1
-+	or	$t2,$i2
-+	or	$t3,$i3
-+	
-+	srlg	$i1,$s2,`8-3`	# i0
-+	srlg	$i2,$s2,`16-3`	# i1
-+	nr	$i1,$mask
-+	nr	$i2,$mask
-+	sllg	$i3,$s2,`0+3`
-+	srl	$s2,`24-3`
-+	ngr	$i3,$mask
-+	nr	$s2,$mask
-+
-+	sllg	$t1,$s3,`0+3`	# i0
-+	srlg	$ra,$s3,`8-3`	# i1
-+	ngr	$t1,$mask
-+
-+	llgc	$i1,2($i1,$tbl)	# Te4[s2>>8]
-+	llgc	$i2,2($i2,$tbl)	# Te4[s2>>16]
-+	sll	$i1,8
-+	llgc	$s2,2($s2,$tbl)	# Te4[s2>>24]
-+	llgc	$i3,2($i3,$tbl)	# Te4[s2>>0]
-+	sll	$i2,16
-+	nr	$ra,$mask
-+	sll	$s2,24
-+	or	$s0,$i1
-+	or	$s1,$i2
-+	or	$s2,$t2
-+	or	$t3,$i3
-+
-+	srlg	$i3,$s3,`16-3`	# i2
-+	srl	$s3,`24-3`
-+	nr	$i3,$mask
-+	nr	$s3,$mask
-+
-+	l	$t0,16($key)
-+	l	$t2,20($key)
-+
-+	llgc	$i1,2($t1,$tbl)	# Te4[s3>>0]
-+	llgc	$i2,2($ra,$tbl)	# Te4[s3>>8]
-+	llgc	$i3,2($i3,$tbl)	# Te4[s3>>16]
-+	llgc	$s3,2($s3,$tbl)	# Te4[s3>>24]
-+	sll	$i2,8
-+	sll	$i3,16
-+	sll	$s3,24
-+	or	$s0,$i1
-+	or	$s1,$i2
-+	or	$s2,$i3
-+	or	$s3,$t3
-+
-+	l${g}	$ra,15*$SIZE_T($sp)
-+	xr	$s0,$t0
-+	xr	$s1,$t2
-+	x	$s2,24($key)
-+	x	$s3,28($key)
-+
-+	br	$ra	
-+.size	_s390x_AES_encrypt,.-_s390x_AES_encrypt
-+___
-+
-+$code.=<<___;
-+.type	AES_Td,\@object
-+.align	256
-+AES_Td:
-+___
-+&_data_word(
-+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
-+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
-+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
-+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
-+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
-+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
-+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
-+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
-+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
-+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
-+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
-+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
-+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
-+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
-+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
-+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
-+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
-+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
-+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
-+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
-+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
-+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
-+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
-+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
-+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
-+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
-+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
-+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
-+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
-+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
-+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
-+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
-+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
-+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
-+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
-+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
-+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
-+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
-+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
-+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
-+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
-+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
-+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
-+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
-+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
-+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
-+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
-+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
-+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
-+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
-+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
-+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
-+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
-+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
-+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
-+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
-+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
-+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
-+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
-+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
-+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
-+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
-+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
-+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
-+$code.=<<___;
-+# Td4[256]
-+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+.size	AES_Td,.-AES_Td
-+
-+# void AES_decrypt(const unsigned char *inp, unsigned char *out,
-+# 		 const AES_KEY *key) {
-+.globl	AES_decrypt
-+.type	AES_decrypt,\@function
-+AES_decrypt:
-+___
-+$code.=<<___ if (!$softonly);
-+	l	%r0,240($key)
-+	lhi	%r1,16
-+	clr	%r0,%r1
-+	jl	.Ldsoft
-+
-+	la	%r1,0($key)
-+	#la	%r2,0($inp)
-+	la	%r4,0($out)
-+	lghi	%r3,16		# single block length
-+	.long	0xb92e0042	# km %r4,%r2
-+	brc	1,.-4		# can this happen?
-+	br	%r14
-+.align	64
-+.Ldsoft:
-+___
-+$code.=<<___;
-+	stm${g}	%r3,$ra,3*$SIZE_T($sp)
-+
-+	llgf	$s0,0($inp)
-+	llgf	$s1,4($inp)
-+	llgf	$s2,8($inp)
-+	llgf	$s3,12($inp)
-+
-+	larl	$tbl,AES_Td
-+	bras	$ra,_s390x_AES_decrypt
-+
-+	l${g}	$out,3*$SIZE_T($sp)
-+	st	$s0,0($out)
-+	st	$s1,4($out)
-+	st	$s2,8($out)
-+	st	$s3,12($out)
-+
-+	lm${g}	%r6,$ra,6*$SIZE_T($sp)
-+	br	$ra
-+.size	AES_decrypt,.-AES_decrypt
-+
-+.type   _s390x_AES_decrypt,\@function
-+.align	16
-+_s390x_AES_decrypt:
-+	st${g}	$ra,15*$SIZE_T($sp)
-+	x	$s0,0($key)
-+	x	$s1,4($key)
-+	x	$s2,8($key)
-+	x	$s3,12($key)
-+	l	$rounds,240($key)
-+	llill	$mask,`0xff<<3`
-+	aghi	$rounds,-1
-+	j	.Ldec_loop
-+.align	16
-+.Ldec_loop:
-+	srlg	$t1,$s0,`16-3`
-+	srlg	$t2,$s0,`8-3`
-+	sllg	$t3,$s0,`0+3`
-+	srl	$s0,`24-3`
-+	nr	$s0,$mask
-+	nr	$t1,$mask
-+	nr	$t2,$mask
-+	ngr	$t3,$mask
-+
-+	sllg	$i1,$s1,`0+3`	# i0
-+	srlg	$i2,$s1,`16-3`
-+	srlg	$i3,$s1,`8-3`
-+	srl	$s1,`24-3`
-+	ngr	$i1,$mask
-+	nr	$s1,$mask
-+	nr	$i2,$mask
-+	nr	$i3,$mask
-+
-+	l	$s0,0($s0,$tbl)	# Td0[s0>>24]
-+	l	$t1,3($t1,$tbl)	# Td1[s0>>16]
-+	l	$t2,2($t2,$tbl)	# Td2[s0>>8]
-+	l	$t3,1($t3,$tbl)	# Td3[s0>>0]
-+
-+	x	$s0,1($i1,$tbl)	# Td3[s1>>0]
-+	l	$s1,0($s1,$tbl)	# Td0[s1>>24]
-+	x	$t2,3($i2,$tbl)	# Td1[s1>>16]
-+	x	$t3,2($i3,$tbl)	# Td2[s1>>8]
-+
-+	srlg	$i1,$s2,`8-3`	# i0
-+	sllg	$i2,$s2,`0+3`	# i1
-+	srlg	$i3,$s2,`16-3`
-+	srl	$s2,`24-3`
-+	nr	$i1,$mask
-+	ngr	$i2,$mask
-+	nr	$s2,$mask
-+	nr	$i3,$mask
-+
-+	xr	$s1,$t1
-+	srlg	$ra,$s3,`8-3`	# i1
-+	srlg	$t1,$s3,`16-3`	# i0
-+	nr	$ra,$mask
-+	la	$key,16($key)
-+	nr	$t1,$mask
-+
-+	x	$s0,2($i1,$tbl)	# Td2[s2>>8]
-+	x	$s1,1($i2,$tbl)	# Td3[s2>>0]
-+	l	$s2,0($s2,$tbl)	# Td0[s2>>24]
-+	x	$t3,3($i3,$tbl)	# Td1[s2>>16]
-+
-+	sllg	$i3,$s3,`0+3`	# i2
-+	srl	$s3,`24-3`
-+	ngr	$i3,$mask
-+	nr	$s3,$mask
-+
-+	xr	$s2,$t2
-+	x	$s0,0($key)
-+	x	$s1,4($key)
-+	x	$s2,8($key)
-+	x	$t3,12($key)
-+
-+	x	$s0,3($t1,$tbl)	# Td1[s3>>16]
-+	x	$s1,2($ra,$tbl)	# Td2[s3>>8]
-+	x	$s2,1($i3,$tbl)	# Td3[s3>>0]
-+	l	$s3,0($s3,$tbl)	# Td0[s3>>24]
-+	xr	$s3,$t3
-+
-+	brct	$rounds,.Ldec_loop
-+	.align	16
-+
-+	l	$t1,`2048+0`($tbl)	# prefetch Td4
-+	l	$t2,`2048+64`($tbl)
-+	l	$t3,`2048+128`($tbl)
-+	l	$i1,`2048+192`($tbl)
-+	llill	$mask,0xff
-+
-+	srlg	$i3,$s0,24	# i0
-+	srlg	$t1,$s0,16
-+	srlg	$t2,$s0,8
-+	nr	$s0,$mask	# i3
-+	nr	$t1,$mask
-+
-+	srlg	$i1,$s1,24
-+	nr	$t2,$mask
-+	srlg	$i2,$s1,16
-+	srlg	$ra,$s1,8
-+	nr	$s1,$mask	# i0
-+	nr	$i2,$mask
-+	nr	$ra,$mask
-+
-+	llgc	$i3,2048($i3,$tbl)	# Td4[s0>>24]
-+	llgc	$t1,2048($t1,$tbl)	# Td4[s0>>16]
-+	llgc	$t2,2048($t2,$tbl)	# Td4[s0>>8]
-+	sll	$t1,16
-+	llgc	$t3,2048($s0,$tbl)	# Td4[s0>>0]
-+	sllg	$s0,$i3,24
-+	sll	$t2,8
-+
-+	llgc	$s1,2048($s1,$tbl)	# Td4[s1>>0]
-+	llgc	$i1,2048($i1,$tbl)	# Td4[s1>>24]
-+	llgc	$i2,2048($i2,$tbl)	# Td4[s1>>16]
-+	sll	$i1,24
-+	llgc	$i3,2048($ra,$tbl)	# Td4[s1>>8]
-+	sll	$i2,16
-+	sll	$i3,8
-+	or	$s0,$s1
-+	or	$t1,$i1
-+	or	$t2,$i2
-+	or	$t3,$i3
-+
-+	srlg	$i1,$s2,8	# i0
-+	srlg	$i2,$s2,24
-+	srlg	$i3,$s2,16
-+	nr	$s2,$mask	# i1
-+	nr	$i1,$mask
-+	nr	$i3,$mask
-+	llgc	$i1,2048($i1,$tbl)	# Td4[s2>>8]
-+	llgc	$s1,2048($s2,$tbl)	# Td4[s2>>0]
-+	llgc	$i2,2048($i2,$tbl)	# Td4[s2>>24]
-+	llgc	$i3,2048($i3,$tbl)	# Td4[s2>>16]
-+	sll	$i1,8
-+	sll	$i2,24
-+	or	$s0,$i1
-+	sll	$i3,16
-+	or	$t2,$i2
-+	or	$t3,$i3
-+
-+	srlg	$i1,$s3,16	# i0
-+	srlg	$i2,$s3,8	# i1
-+	srlg	$i3,$s3,24
-+	nr	$s3,$mask	# i2
-+	nr	$i1,$mask
-+	nr	$i2,$mask
-+
-+	l${g}	$ra,15*$SIZE_T($sp)
-+	or	$s1,$t1
-+	l	$t0,16($key)
-+	l	$t1,20($key)
-+
-+	llgc	$i1,2048($i1,$tbl)	# Td4[s3>>16]
-+	llgc	$i2,2048($i2,$tbl)	# Td4[s3>>8]
-+	sll	$i1,16
-+	llgc	$s2,2048($s3,$tbl)	# Td4[s3>>0]
-+	llgc	$s3,2048($i3,$tbl)	# Td4[s3>>24]
-+	sll	$i2,8
-+	sll	$s3,24
-+	or	$s0,$i1
-+	or	$s1,$i2
-+	or	$s2,$t2
-+	or	$s3,$t3
-+
-+	xr	$s0,$t0
-+	xr	$s1,$t1
-+	x	$s2,24($key)
-+	x	$s3,28($key)
-+
-+	br	$ra	
-+.size	_s390x_AES_decrypt,.-_s390x_AES_decrypt
-+___
-+
-+$code.=<<___;
-+# void AES_set_encrypt_key(const unsigned char *in, int bits,
-+# 		 AES_KEY *key) {
-+.globl	AES_set_encrypt_key
-+.type	AES_set_encrypt_key,\@function
-+.align	16
-+AES_set_encrypt_key:
-+_s390x_AES_set_encrypt_key:
-+	lghi	$t0,0
-+	cl${g}r	$inp,$t0
-+	je	.Lminus1
-+	cl${g}r	$key,$t0
-+	je	.Lminus1
-+
-+	lghi	$t0,128
-+	clr	$bits,$t0
-+	je	.Lproceed
-+	lghi	$t0,192
-+	clr	$bits,$t0
-+	je	.Lproceed
-+	lghi	$t0,256
-+	clr	$bits,$t0
-+	je	.Lproceed
-+	lghi	%r2,-2
-+	br	%r14
-+
-+.align	16
-+.Lproceed:
-+___
-+$code.=<<___ if (!$softonly);
-+	# convert bits to km code, [128,192,256]->[18,19,20]
-+	lhi	%r5,-128
-+	lhi	%r0,18
-+	ar	%r5,$bits
-+	srl	%r5,6
-+	ar	%r5,%r0
-+
-+	larl	%r1,OPENSSL_s390xcap_P
-+	lg	%r0,0(%r1)
-+	tmhl	%r0,0x4000	# check for message-security assist
-+	jz	.Lekey_internal
-+
-+	llihh	%r0,0x8000
-+	srlg	%r0,%r0,0(%r5)
-+	ng	%r0,48(%r1)	# check kmc capability vector
-+	jz	.Lekey_internal
-+
-+	lmg	%r0,%r1,0($inp)	# just copy 128 bits...
-+	stmg	%r0,%r1,0($key)
-+	lhi	%r0,192
-+	cr	$bits,%r0
-+	jl	1f
-+	lg	%r1,16($inp)
-+	stg	%r1,16($key)
-+	je	1f
-+	lg	%r1,24($inp)
-+	stg	%r1,24($key)
-+1:	st	$bits,236($key)	# save bits [for debugging purposes]
-+	lgr	$t0,%r5
-+	st	%r5,240($key)	# save km code
-+	lghi	%r2,0
-+	br	%r14
-+___
-+$code.=<<___;
-+.align	16
-+.Lekey_internal:
-+	stm${g}	%r4,%r13,4*$SIZE_T($sp)	# all non-volatile regs and $key
-+
-+	larl	$tbl,AES_Te+2048
-+
-+	llgf	$s0,0($inp)
-+	llgf	$s1,4($inp)
-+	llgf	$s2,8($inp)
-+	llgf	$s3,12($inp)
-+	st	$s0,0($key)
-+	st	$s1,4($key)
-+	st	$s2,8($key)
-+	st	$s3,12($key)
-+	lghi	$t0,128
-+	cr	$bits,$t0
-+	jne	.Lnot128
-+
-+	llill	$mask,0xff
-+	lghi	$t3,0			# i=0
-+	lghi	$rounds,10
-+	st	$rounds,240($key)
-+
-+	llgfr	$t2,$s3			# temp=rk[3]
-+	srlg	$i1,$s3,8
-+	srlg	$i2,$s3,16
-+	srlg	$i3,$s3,24
-+	nr	$t2,$mask
-+	nr	$i1,$mask
-+	nr	$i2,$mask
-+
-+.align	16
-+.L128_loop:
-+	la	$t2,0($t2,$tbl)
-+	la	$i1,0($i1,$tbl)
-+	la	$i2,0($i2,$tbl)
-+	la	$i3,0($i3,$tbl)
-+	icm	$t2,2,0($t2)		# Te4[rk[3]>>0]<<8
-+	icm	$t2,4,0($i1)		# Te4[rk[3]>>8]<<16
-+	icm	$t2,8,0($i2)		# Te4[rk[3]>>16]<<24
-+	icm	$t2,1,0($i3)		# Te4[rk[3]>>24]
-+	x	$t2,256($t3,$tbl)	# rcon[i]
-+	xr	$s0,$t2			# rk[4]=rk[0]^...
-+	xr	$s1,$s0			# rk[5]=rk[1]^rk[4]
-+	xr	$s2,$s1			# rk[6]=rk[2]^rk[5]
-+	xr	$s3,$s2			# rk[7]=rk[3]^rk[6]
-+
-+	llgfr	$t2,$s3			# temp=rk[3]
-+	srlg	$i1,$s3,8
-+	srlg	$i2,$s3,16
-+	nr	$t2,$mask
-+	nr	$i1,$mask
-+	srlg	$i3,$s3,24
-+	nr	$i2,$mask
-+
-+	st	$s0,16($key)
-+	st	$s1,20($key)
-+	st	$s2,24($key)
-+	st	$s3,28($key)
-+	la	$key,16($key)		# key+=4
-+	la	$t3,4($t3)		# i++
-+	brct	$rounds,.L128_loop
-+	lghi	$t0,10
-+	lghi	%r2,0
-+	lm${g}	%r4,%r13,4*$SIZE_T($sp)
-+	br	$ra
-+
-+.align	16
-+.Lnot128:
-+	llgf	$t0,16($inp)
-+	llgf	$t1,20($inp)
-+	st	$t0,16($key)
-+	st	$t1,20($key)
-+	lghi	$t0,192
-+	cr	$bits,$t0
-+	jne	.Lnot192
-+
-+	llill	$mask,0xff
-+	lghi	$t3,0			# i=0
-+	lghi	$rounds,12
-+	st	$rounds,240($key)
-+	lghi	$rounds,8
-+
-+	srlg	$i1,$t1,8
-+	srlg	$i2,$t1,16
-+	srlg	$i3,$t1,24
-+	nr	$t1,$mask
-+	nr	$i1,$mask
-+	nr	$i2,$mask
-+
-+.align	16
-+.L192_loop:
-+	la	$t1,0($t1,$tbl)
-+	la	$i1,0($i1,$tbl)
-+	la	$i2,0($i2,$tbl)
-+	la	$i3,0($i3,$tbl)
-+	icm	$t1,2,0($t1)		# Te4[rk[5]>>0]<<8
-+	icm	$t1,4,0($i1)		# Te4[rk[5]>>8]<<16
-+	icm	$t1,8,0($i2)		# Te4[rk[5]>>16]<<24
-+	icm	$t1,1,0($i3)		# Te4[rk[5]>>24]
-+	x	$t1,256($t3,$tbl)	# rcon[i]
-+	xr	$s0,$t1			# rk[6]=rk[0]^...
-+	xr	$s1,$s0			# rk[7]=rk[1]^rk[6]
-+	xr	$s2,$s1			# rk[8]=rk[2]^rk[7]
-+	xr	$s3,$s2			# rk[9]=rk[3]^rk[8]
-+
-+	st	$s0,24($key)
-+	st	$s1,28($key)
-+	st	$s2,32($key)
-+	st	$s3,36($key)
-+	brct	$rounds,.L192_continue
-+	lghi	$t0,12
-+	lghi	%r2,0
-+	lm${g}	%r4,%r13,4*$SIZE_T($sp)
-+	br	$ra
-+
-+.align	16
-+.L192_continue:
-+	lgr	$t1,$s3
-+	x	$t1,16($key)		# rk[10]=rk[4]^rk[9]
-+	st	$t1,40($key)
-+	x	$t1,20($key)		# rk[11]=rk[5]^rk[10]
-+	st	$t1,44($key)
-+
-+	srlg	$i1,$t1,8
-+	srlg	$i2,$t1,16
-+	srlg	$i3,$t1,24
-+	nr	$t1,$mask
-+	nr	$i1,$mask
-+	nr	$i2,$mask
-+
-+	la	$key,24($key)		# key+=6
-+	la	$t3,4($t3)		# i++
-+	j	.L192_loop
-+
-+.align	16
-+.Lnot192:
-+	llgf	$t0,24($inp)
-+	llgf	$t1,28($inp)
-+	st	$t0,24($key)
-+	st	$t1,28($key)
-+	llill	$mask,0xff
-+	lghi	$t3,0			# i=0
-+	lghi	$rounds,14
-+	st	$rounds,240($key)
-+	lghi	$rounds,7
-+
-+	srlg	$i1,$t1,8
-+	srlg	$i2,$t1,16
-+	srlg	$i3,$t1,24
-+	nr	$t1,$mask
-+	nr	$i1,$mask
-+	nr	$i2,$mask
-+
-+.align	16
-+.L256_loop:
-+	la	$t1,0($t1,$tbl)
-+	la	$i1,0($i1,$tbl)
-+	la	$i2,0($i2,$tbl)
-+	la	$i3,0($i3,$tbl)
-+	icm	$t1,2,0($t1)		# Te4[rk[7]>>0]<<8
-+	icm	$t1,4,0($i1)		# Te4[rk[7]>>8]<<16
-+	icm	$t1,8,0($i2)		# Te4[rk[7]>>16]<<24
-+	icm	$t1,1,0($i3)		# Te4[rk[7]>>24]
-+	x	$t1,256($t3,$tbl)	# rcon[i]
-+	xr	$s0,$t1			# rk[8]=rk[0]^...
-+	xr	$s1,$s0			# rk[9]=rk[1]^rk[8]
-+	xr	$s2,$s1			# rk[10]=rk[2]^rk[9]
-+	xr	$s3,$s2			# rk[11]=rk[3]^rk[10]
-+	st	$s0,32($key)
-+	st	$s1,36($key)
-+	st	$s2,40($key)
-+	st	$s3,44($key)
-+	brct	$rounds,.L256_continue
-+	lghi	$t0,14
-+	lghi	%r2,0
-+	lm${g}	%r4,%r13,4*$SIZE_T($sp)
-+	br	$ra
-+
-+.align	16
-+.L256_continue:
-+	lgr	$t1,$s3			# temp=rk[11]
-+	srlg	$i1,$s3,8
-+	srlg	$i2,$s3,16
-+	srlg	$i3,$s3,24
-+	nr	$t1,$mask
-+	nr	$i1,$mask
-+	nr	$i2,$mask
-+	la	$t1,0($t1,$tbl)
-+	la	$i1,0($i1,$tbl)
-+	la	$i2,0($i2,$tbl)
-+	la	$i3,0($i3,$tbl)
-+	llgc	$t1,0($t1)		# Te4[rk[11]>>0]
-+	icm	$t1,2,0($i1)		# Te4[rk[11]>>8]<<8
-+	icm	$t1,4,0($i2)		# Te4[rk[11]>>16]<<16
-+	icm	$t1,8,0($i3)		# Te4[rk[11]>>24]<<24
-+	x	$t1,16($key)		# rk[12]=rk[4]^...
-+	st	$t1,48($key)
-+	x	$t1,20($key)		# rk[13]=rk[5]^rk[12]
-+	st	$t1,52($key)
-+	x	$t1,24($key)		# rk[14]=rk[6]^rk[13]
-+	st	$t1,56($key)
-+	x	$t1,28($key)		# rk[15]=rk[7]^rk[14]
-+	st	$t1,60($key)
-+
-+	srlg	$i1,$t1,8
-+	srlg	$i2,$t1,16
-+	srlg	$i3,$t1,24
-+	nr	$t1,$mask
-+	nr	$i1,$mask
-+	nr	$i2,$mask
-+
-+	la	$key,32($key)		# key+=8
-+	la	$t3,4($t3)		# i++
-+	j	.L256_loop
-+
-+.Lminus1:
-+	lghi	%r2,-1
-+	br	$ra
-+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
-+
-+# void AES_set_decrypt_key(const unsigned char *in, int bits,
-+# 		 AES_KEY *key) {
-+.globl	AES_set_decrypt_key
-+.type	AES_set_decrypt_key,\@function
-+.align	16
-+AES_set_decrypt_key:
-+	#st${g}	$key,4*$SIZE_T($sp)	# I rely on AES_set_encrypt_key to
-+	st${g}	$ra,14*$SIZE_T($sp)	# save non-volatile registers and $key!
-+	bras	$ra,_s390x_AES_set_encrypt_key
-+	#l${g}	$key,4*$SIZE_T($sp)
-+	l${g}	$ra,14*$SIZE_T($sp)
-+	ltgr	%r2,%r2
-+	bnzr	$ra
-+___
-+$code.=<<___ if (!$softonly);
-+	#l	$t0,240($key)
-+	lhi	$t1,16
-+	cr	$t0,$t1
-+	jl	.Lgo
-+	oill	$t0,0x80	# set "decrypt" bit
-+	st	$t0,240($key)
-+	br	$ra
-+___
-+$code.=<<___;
-+.align	16
-+.Lgo:	lgr	$rounds,$t0	#llgf	$rounds,240($key)
-+	la	$i1,0($key)
-+	sllg	$i2,$rounds,4
-+	la	$i2,0($i2,$key)
-+	srl	$rounds,1
-+	lghi	$t1,-16
-+
-+.align	16
-+.Linv:	lmg	$s0,$s1,0($i1)
-+	lmg	$s2,$s3,0($i2)
-+	stmg	$s0,$s1,0($i2)
-+	stmg	$s2,$s3,0($i1)
-+	la	$i1,16($i1)
-+	la	$i2,0($t1,$i2)
-+	brct	$rounds,.Linv
-+___
-+$mask80=$i1;
-+$mask1b=$i2;
-+$maskfe=$i3;
-+$code.=<<___;
-+	llgf	$rounds,240($key)
-+	aghi	$rounds,-1
-+	sll	$rounds,2	# (rounds-1)*4
-+	llilh	$mask80,0x8080
-+	llilh	$mask1b,0x1b1b
-+	llilh	$maskfe,0xfefe
-+	oill	$mask80,0x8080
-+	oill	$mask1b,0x1b1b
-+	oill	$maskfe,0xfefe
-+
-+.align	16
-+.Lmix:	l	$s0,16($key)	# tp1
-+	lr	$s1,$s0
-+	ngr	$s1,$mask80
-+	srlg	$t1,$s1,7
-+	slr	$s1,$t1
-+	nr	$s1,$mask1b
-+	sllg	$t1,$s0,1
-+	nr	$t1,$maskfe
-+	xr	$s1,$t1		# tp2
-+
-+	lr	$s2,$s1
-+	ngr	$s2,$mask80
-+	srlg	$t1,$s2,7
-+	slr	$s2,$t1
-+	nr	$s2,$mask1b
-+	sllg	$t1,$s1,1
-+	nr	$t1,$maskfe
-+	xr	$s2,$t1		# tp4
-+
-+	lr	$s3,$s2
-+	ngr	$s3,$mask80
-+	srlg	$t1,$s3,7
-+	slr	$s3,$t1
-+	nr	$s3,$mask1b
-+	sllg	$t1,$s2,1
-+	nr	$t1,$maskfe
-+	xr	$s3,$t1		# tp8
-+
-+	xr	$s1,$s0		# tp2^tp1
-+	xr	$s2,$s0		# tp4^tp1
-+	rll	$s0,$s0,24	# = ROTATE(tp1,8)
-+	xr	$s2,$s3		# ^=tp8
-+	xr	$s0,$s1		# ^=tp2^tp1
-+	xr	$s1,$s3		# tp2^tp1^tp8
-+	xr	$s0,$s2		# ^=tp4^tp1^tp8
-+	rll	$s1,$s1,8
-+	rll	$s2,$s2,16
-+	xr	$s0,$s1		# ^= ROTATE(tp8^tp2^tp1,24)
-+	rll	$s3,$s3,24
-+	xr	$s0,$s2    	# ^= ROTATE(tp8^tp4^tp1,16)
-+	xr	$s0,$s3		# ^= ROTATE(tp8,8)
-+
-+	st	$s0,16($key)
-+	la	$key,4($key)
-+	brct	$rounds,.Lmix
-+
-+	lm${g}	%r6,%r13,6*$SIZE_T($sp)# as was saved by AES_set_encrypt_key!
-+	lghi	%r2,0
-+	br	$ra
-+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
-+___
-+
-+########################################################################
-+# void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+#                     size_t length, const AES_KEY *key,
-+#                     unsigned char *ivec, const int enc)
-+{
-+my $inp="%r2";
-+my $out="%r4";	# length and out are swapped
-+my $len="%r3";
-+my $key="%r5";
-+my $ivp="%r6";
-+
-+$code.=<<___;
-+.globl	AES_cbc_encrypt
-+.type	AES_cbc_encrypt,\@function
-+.align	16
-+AES_cbc_encrypt:
-+	xgr	%r3,%r4		# flip %r3 and %r4, out and len
-+	xgr	%r4,%r3
-+	xgr	%r3,%r4
-+___
-+$code.=<<___ if (!$softonly);
-+	lhi	%r0,16
-+	cl	%r0,240($key)
-+	jh	.Lcbc_software
-+
-+	lg	%r0,0($ivp)	# copy ivec
-+	lg	%r1,8($ivp)
-+	stmg	%r0,%r1,16($sp)
-+	lmg	%r0,%r1,0($key)	# copy key, cover 256 bit
-+	stmg	%r0,%r1,32($sp)
-+	lmg	%r0,%r1,16($key)
-+	stmg	%r0,%r1,48($sp)
-+	l	%r0,240($key)	# load kmc code
-+	lghi	$key,15		# res=len%16, len-=res;
-+	ngr	$key,$len
-+	sl${g}r	$len,$key
-+	la	%r1,16($sp)	# parameter block - ivec || key
-+	jz	.Lkmc_truncated
-+	.long	0xb92f0042	# kmc %r4,%r2
-+	brc	1,.-4		# pay attention to "partial completion"
-+	ltr	$key,$key
-+	jnz	.Lkmc_truncated
-+.Lkmc_done:
-+	lmg	%r0,%r1,16($sp)	# copy ivec to caller
-+	stg	%r0,0($ivp)
-+	stg	%r1,8($ivp)
-+	br	$ra
-+.align	16
-+.Lkmc_truncated:
-+	ahi	$key,-1		# it's the way it's encoded in mvc
-+	tmll	%r0,0x80
-+	jnz	.Lkmc_truncated_dec
-+	lghi	%r1,0
-+	stg	%r1,16*$SIZE_T($sp)
-+	stg	%r1,16*$SIZE_T+8($sp)
-+	bras	%r1,1f
-+	mvc	16*$SIZE_T(1,$sp),0($inp)
-+1:	ex	$key,0(%r1)
-+	la	%r1,16($sp)	# restore parameter block
-+	la	$inp,16*$SIZE_T($sp)
-+	lghi	$len,16
-+	.long	0xb92f0042	# kmc %r4,%r2
-+	j	.Lkmc_done
-+.align	16
-+.Lkmc_truncated_dec:
-+	st${g}	$out,4*$SIZE_T($sp)
-+	la	$out,16*$SIZE_T($sp)
-+	lghi	$len,16
-+	.long	0xb92f0042	# kmc %r4,%r2
-+	l${g}	$out,4*$SIZE_T($sp)
-+	bras	%r1,2f
-+	mvc	0(1,$out),16*$SIZE_T($sp)
-+2:	ex	$key,0(%r1)
-+	j	.Lkmc_done
-+.align	16
-+.Lcbc_software:
-+___
-+$code.=<<___;
-+	stm${g}	$key,$ra,5*$SIZE_T($sp)
-+	lhi	%r0,0
-+	cl	%r0,`$stdframe+$SIZE_T-4`($sp)
-+	je	.Lcbc_decrypt
-+
-+	larl	$tbl,AES_Te
-+
-+	llgf	$s0,0($ivp)
-+	llgf	$s1,4($ivp)
-+	llgf	$s2,8($ivp)
-+	llgf	$s3,12($ivp)
-+
-+	lghi	$t0,16
-+	sl${g}r	$len,$t0
-+	brc	4,.Lcbc_enc_tail	# if borrow
-+.Lcbc_enc_loop:
-+	stm${g}	$inp,$out,2*$SIZE_T($sp)
-+	x	$s0,0($inp)
-+	x	$s1,4($inp)
-+	x	$s2,8($inp)
-+	x	$s3,12($inp)
-+	lgr	%r4,$key
-+
-+	bras	$ra,_s390x_AES_encrypt
-+
-+	lm${g}	$inp,$key,2*$SIZE_T($sp)
-+	st	$s0,0($out)
-+	st	$s1,4($out)
-+	st	$s2,8($out)
-+	st	$s3,12($out)
-+
-+	la	$inp,16($inp)
-+	la	$out,16($out)
-+	lghi	$t0,16
-+	lt${g}r	$len,$len
-+	jz	.Lcbc_enc_done
-+	sl${g}r	$len,$t0
-+	brc	4,.Lcbc_enc_tail	# if borrow
-+	j	.Lcbc_enc_loop
-+.align	16
-+.Lcbc_enc_done:
-+	l${g}	$ivp,6*$SIZE_T($sp)
-+	st	$s0,0($ivp)
-+	st	$s1,4($ivp)	
-+	st	$s2,8($ivp)
-+	st	$s3,12($ivp)
-+
-+	lm${g}	%r7,$ra,7*$SIZE_T($sp)
-+	br	$ra
-+
-+.align	16
-+.Lcbc_enc_tail:
-+	aghi	$len,15
-+	lghi	$t0,0
-+	stg	$t0,16*$SIZE_T($sp)
-+	stg	$t0,16*$SIZE_T+8($sp)
-+	bras	$t1,3f
-+	mvc	16*$SIZE_T(1,$sp),0($inp)
-+3:	ex	$len,0($t1)
-+	lghi	$len,0
-+	la	$inp,16*$SIZE_T($sp)
-+	j	.Lcbc_enc_loop
-+
-+.align	16
-+.Lcbc_decrypt:
-+	larl	$tbl,AES_Td
-+
-+	lg	$t0,0($ivp)
-+	lg	$t1,8($ivp)
-+	stmg	$t0,$t1,16*$SIZE_T($sp)
-+
-+.Lcbc_dec_loop:
-+	stm${g}	$inp,$out,2*$SIZE_T($sp)
-+	llgf	$s0,0($inp)
-+	llgf	$s1,4($inp)
-+	llgf	$s2,8($inp)
-+	llgf	$s3,12($inp)
-+	lgr	%r4,$key
-+
-+	bras	$ra,_s390x_AES_decrypt
-+
-+	lm${g}	$inp,$key,2*$SIZE_T($sp)
-+	sllg	$s0,$s0,32
-+	sllg	$s2,$s2,32
-+	lr	$s0,$s1
-+	lr	$s2,$s3
-+
-+	lg	$t0,0($inp)
-+	lg	$t1,8($inp)
-+	xg	$s0,16*$SIZE_T($sp)
-+	xg	$s2,16*$SIZE_T+8($sp)
-+	lghi	$s1,16
-+	sl${g}r	$len,$s1
-+	brc	4,.Lcbc_dec_tail	# if borrow
-+	brc	2,.Lcbc_dec_done	# if zero
-+	stg	$s0,0($out)
-+	stg	$s2,8($out)
-+	stmg	$t0,$t1,16*$SIZE_T($sp)
-+
-+	la	$inp,16($inp)
-+	la	$out,16($out)
-+	j	.Lcbc_dec_loop
-+
-+.Lcbc_dec_done:
-+	stg	$s0,0($out)
-+	stg	$s2,8($out)
-+.Lcbc_dec_exit:
-+	lm${g}	%r6,$ra,6*$SIZE_T($sp)
-+	stmg	$t0,$t1,0($ivp)
-+
-+	br	$ra
-+
-+.align	16
-+.Lcbc_dec_tail:
-+	aghi	$len,15
-+	stg	$s0,16*$SIZE_T($sp)
-+	stg	$s2,16*$SIZE_T+8($sp)
-+	bras	$s1,4f
-+	mvc	0(1,$out),16*$SIZE_T($sp)
-+4:	ex	$len,0($s1)
-+	j	.Lcbc_dec_exit
-+.size	AES_cbc_encrypt,.-AES_cbc_encrypt
-+___
-+}
-+########################################################################
-+# void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
-+#                     size_t blocks, const AES_KEY *key,
-+#                     const unsigned char *ivec)
-+{
-+my $inp="%r2";
-+my $out="%r4";	# blocks and out are swapped
-+my $len="%r3";
-+my $key="%r5";	my $iv0="%r5";
-+my $ivp="%r6";
-+my $fp ="%r7";
-+
-+$code.=<<___;
-+.globl	AES_ctr32_encrypt
-+.type	AES_ctr32_encrypt,\@function
-+.align	16
-+AES_ctr32_encrypt:
-+	xgr	%r3,%r4		# flip %r3 and %r4, $out and $len
-+	xgr	%r4,%r3
-+	xgr	%r3,%r4
-+	llgfr	$len,$len	# safe in ctr32 subroutine even in 64-bit case
-+___
-+$code.=<<___ if (!$softonly);
-+	l	%r0,240($key)
-+	lhi	%r1,16
-+	clr	%r0,%r1
-+	jl	.Lctr32_software
-+
-+	stm${g}	%r6,$s3,6*$SIZE_T($sp)
-+
-+	slgr	$out,$inp
-+	la	%r1,0($key)	# %r1 is permanent copy of $key
-+	lg	$iv0,0($ivp)	# load ivec
-+	lg	$ivp,8($ivp)
-+
-+	# prepare and allocate stack frame at the top of 4K page
-+	# with 1K reserved for eventual signal handling
-+	lghi	$s0,-1024-256-16# guarantee at least 256-bytes buffer
-+	lghi	$s1,-4096
-+	algr	$s0,$sp
-+	lgr	$fp,$sp
-+	ngr	$s0,$s1		# align at page boundary
-+	slgr	$fp,$s0		# total buffer size
-+	lgr	$s2,$sp
-+	lghi	$s1,1024+16	# sl[g]fi is extended-immediate facility
-+	slgr	$fp,$s1		# deduct reservation to get usable buffer size
-+	# buffer size is at lest 256 and at most 3072+256-16
-+
-+	la	$sp,1024($s0)	# alloca
-+	srlg	$fp,$fp,4	# convert bytes to blocks, minimum 16
-+	st${g}	$s2,0($sp)	# back-chain
-+	st${g}	$fp,$SIZE_T($sp)
-+
-+	slgr	$len,$fp
-+	brc	1,.Lctr32_hw_switch	# not zero, no borrow
-+	algr	$fp,$len	# input is shorter than allocated buffer
-+	lghi	$len,0
-+	st${g}	$fp,$SIZE_T($sp)
-+
-+.Lctr32_hw_switch:
-+___
-+$code.=<<___ if (0);	######### kmctr code was measured to be ~12% slower
-+	larl	$s0,OPENSSL_s390xcap_P
-+	lg	$s0,8($s0)
-+	tmhh	$s0,0x0004	# check for message_security-assist-4
-+	jz	.Lctr32_km_loop
-+
-+	llgfr	$s0,%r0
-+	lgr	$s1,%r1
-+	larl	%r1,OPENSSL_s390xcap_P
-+	llihh	%r0,0x8000	# check if kmctr supports the function code
-+	srlg	%r0,%r0,0($s0)
-+	ng	%r0,64(%r1)	# check kmctr capability vector
-+	lgr	%r0,$s0
-+	lgr	%r1,$s1
-+	jz	.Lctr32_km_loop
-+
-+####### kmctr code
-+	algr	$out,$inp	# restore $out
-+	lgr	$s1,$len	# $s1 undertakes $len
-+	j	.Lctr32_kmctr_loop
-+.align	16
-+.Lctr32_kmctr_loop:
-+	la	$s2,16($sp)
-+	lgr	$s3,$fp
-+.Lctr32_kmctr_prepare:
-+	stg	$iv0,0($s2)
-+	stg	$ivp,8($s2)
-+	la	$s2,16($s2)
-+	ahi	$ivp,1		# 32-bit increment, preserves upper half
-+	brct	$s3,.Lctr32_kmctr_prepare
-+
-+	#la	$inp,0($inp)	# inp
-+	sllg	$len,$fp,4	# len
-+	#la	$out,0($out)	# out
-+	la	$s2,16($sp)	# iv
-+	.long	0xb92da042	# kmctr $out,$s2,$inp
-+	brc	1,.-4		# pay attention to "partial completion"
-+
-+	slgr	$s1,$fp
-+	brc	1,.Lctr32_kmctr_loop	# not zero, no borrow
-+	algr	$fp,$s1
-+	lghi	$s1,0
-+	brc	4+1,.Lctr32_kmctr_loop	# not zero
-+
-+	l${g}	$sp,0($sp)
-+	lm${g}	%r6,$s3,6*$SIZE_T($sp)
-+	br	$ra
-+.align	16
-+___
-+$code.=<<___;
-+.Lctr32_km_loop:
-+	la	$s2,16($sp)
-+	lgr	$s3,$fp
-+.Lctr32_km_prepare:
-+	stg	$iv0,0($s2)
-+	stg	$ivp,8($s2)
-+	la	$s2,16($s2)
-+	ahi	$ivp,1		# 32-bit increment, preserves upper half
-+	brct	$s3,.Lctr32_km_prepare
-+
-+	la	$s0,16($sp)	# inp
-+	sllg	$s1,$fp,4	# len
-+	la	$s2,16($sp)	# out
-+	.long	0xb92e00a8	# km %r10,%r8
-+	brc	1,.-4		# pay attention to "partial completion"
-+
-+	la	$s2,16($sp)
-+	lgr	$s3,$fp
-+	slgr	$s2,$inp
-+.Lctr32_km_xor:
-+	lg	$s0,0($inp)
-+	lg	$s1,8($inp)
-+	xg	$s0,0($s2,$inp)
-+	xg	$s1,8($s2,$inp)
-+	stg	$s0,0($out,$inp)
-+	stg	$s1,8($out,$inp)
-+	la	$inp,16($inp)
-+	brct	$s3,.Lctr32_km_xor
-+
-+	slgr	$len,$fp
-+	brc	1,.Lctr32_km_loop	# not zero, no borrow
-+	algr	$fp,$len
-+	lghi	$len,0
-+	brc	4+1,.Lctr32_km_loop	# not zero
-+
-+	l${g}	$s0,0($sp)
-+	l${g}	$s1,$SIZE_T($sp)
-+	la	$s2,16($sp)
-+.Lctr32_km_zap:
-+	stg	$s0,0($s2)
-+	stg	$s0,8($s2)
-+	la	$s2,16($s2)
-+	brct	$s1,.Lctr32_km_zap
-+
-+	la	$sp,0($s0)
-+	lm${g}	%r6,$s3,6*$SIZE_T($sp)
-+	br	$ra
-+.align	16
-+.Lctr32_software:
-+___
-+$code.=<<___;
-+	stm${g}	$key,$ra,5*$SIZE_T($sp)
-+	sl${g}r	$inp,$out
-+	larl	$tbl,AES_Te
-+	llgf	$t1,12($ivp)
-+
-+.Lctr32_loop:
-+	stm${g}	$inp,$out,2*$SIZE_T($sp)
-+	llgf	$s0,0($ivp)
-+	llgf	$s1,4($ivp)
-+	llgf	$s2,8($ivp)
-+	lgr	$s3,$t1
-+	st	$t1,16*$SIZE_T($sp)
-+	lgr	%r4,$key
-+
-+	bras	$ra,_s390x_AES_encrypt
-+
-+	lm${g}	$inp,$ivp,2*$SIZE_T($sp)
-+	llgf	$t1,16*$SIZE_T($sp)
-+	x	$s0,0($inp,$out)
-+	x	$s1,4($inp,$out)
-+	x	$s2,8($inp,$out)
-+	x	$s3,12($inp,$out)
-+	stm	$s0,$s3,0($out)
-+
-+	la	$out,16($out)
-+	ahi	$t1,1		# 32-bit increment
-+	brct	$len,.Lctr32_loop
-+
-+	lm${g}	%r6,$ra,6*$SIZE_T($sp)
-+	br	$ra
-+.size	AES_ctr32_encrypt,.-AES_ctr32_encrypt
-+___
-+}
-+
-+########################################################################
-+# void AES_xts_encrypt(const char *inp,char *out,size_t len,
-+#	const AES_KEY *key1, const AES_KEY *key2,
-+#	const unsigned char iv[16]);
-+#
-+{
-+my $inp="%r2";
-+my $out="%r4";	# len and out are swapped
-+my $len="%r3";
-+my $key1="%r5";	# $i1
-+my $key2="%r6";	# $i2
-+my $fp="%r7";	# $i3
-+my $tweak=16*$SIZE_T+16;	# or $stdframe-16, bottom of the frame...
-+
-+$code.=<<___;
-+.type	_s390x_xts_km,\@function
-+.align	16
-+_s390x_xts_km:
-+___
-+$code.=<<___ if(1);
-+	llgfr	$s0,%r0			# put aside the function code
-+	lghi	$s1,0x7f
-+	nr	$s1,%r0
-+	larl	%r1,OPENSSL_s390xcap_P
-+	llihh	%r0,0x8000
-+	srlg	%r0,%r0,32($s1)		# check for 32+function code
-+	ng	%r0,32(%r1)		# check km capability vector
-+	lgr	%r0,$s0			# restore the function code
-+	la	%r1,0($key1)		# restore $key1
-+	jz	.Lxts_km_vanilla
-+
-+	lmg	$i2,$i3,$tweak($sp)	# put aside the tweak value
-+	algr	$out,$inp
-+
-+	oill	%r0,32			# switch to xts function code
-+	aghi	$s1,-18			#
-+	sllg	$s1,$s1,3		# (function code - 18)*8, 0 or 16
-+	la	%r1,$tweak-16($sp)
-+	slgr	%r1,$s1			# parameter block position
-+	lmg	$s0,$s3,0($key1)	# load 256 bits of key material,
-+	stmg	$s0,$s3,0(%r1)		# and copy it to parameter block.
-+					# yes, it contains junk and overlaps
-+					# with the tweak in 128-bit case.
-+					# it's done to avoid conditional
-+					# branch.
-+	stmg	$i2,$i3,$tweak($sp)	# "re-seat" the tweak value
-+
-+	.long	0xb92e0042		# km %r4,%r2
-+	brc	1,.-4			# pay attention to "partial completion"
-+
-+	lrvg	$s0,$tweak+0($sp)	# load the last tweak
-+	lrvg	$s1,$tweak+8($sp)
-+	stmg	%r0,%r3,$tweak-32($sp)	# wipe copy of the key
-+
-+	nill	%r0,0xffdf		# switch back to original function code
-+	la	%r1,0($key1)		# restore pointer to $key1
-+	slgr	$out,$inp
-+
-+	llgc	$len,2*$SIZE_T-1($sp)
-+	nill	$len,0x0f		# $len%=16
-+	br	$ra
-+	
-+.align	16
-+.Lxts_km_vanilla:
-+___
-+$code.=<<___;
-+	# prepare and allocate stack frame at the top of 4K page
-+	# with 1K reserved for eventual signal handling
-+	lghi	$s0,-1024-256-16# guarantee at least 256-bytes buffer
-+	lghi	$s1,-4096
-+	algr	$s0,$sp
-+	lgr	$fp,$sp
-+	ngr	$s0,$s1		# align at page boundary
-+	slgr	$fp,$s0		# total buffer size
-+	lgr	$s2,$sp
-+	lghi	$s1,1024+16	# sl[g]fi is extended-immediate facility
-+	slgr	$fp,$s1		# deduct reservation to get usable buffer size
-+	# buffer size is at lest 256 and at most 3072+256-16
-+
-+	la	$sp,1024($s0)	# alloca
-+	nill	$fp,0xfff0	# round to 16*n
-+	st${g}	$s2,0($sp)	# back-chain
-+	nill	$len,0xfff0	# redundant
-+	st${g}	$fp,$SIZE_T($sp)
-+
-+	slgr	$len,$fp
-+	brc	1,.Lxts_km_go	# not zero, no borrow
-+	algr	$fp,$len	# input is shorter than allocated buffer
-+	lghi	$len,0
-+	st${g}	$fp,$SIZE_T($sp)
-+
-+.Lxts_km_go:
-+	lrvg	$s0,$tweak+0($s2)	# load the tweak value in little-endian
-+	lrvg	$s1,$tweak+8($s2)
-+
-+	la	$s2,16($sp)		# vector of ascending tweak values
-+	slgr	$s2,$inp
-+	srlg	$s3,$fp,4
-+	j	.Lxts_km_start
-+
-+.Lxts_km_loop:
-+	la	$s2,16($sp)
-+	slgr	$s2,$inp
-+	srlg	$s3,$fp,4
-+.Lxts_km_prepare:
-+	lghi	$i1,0x87
-+	srag	$i2,$s1,63		# broadcast upper bit
-+	ngr	$i1,$i2			# rem
-+	algr	$s0,$s0
-+	alcgr	$s1,$s1
-+	xgr	$s0,$i1
-+.Lxts_km_start:
-+	lrvgr	$i1,$s0			# flip byte order
-+	lrvgr	$i2,$s1
-+	stg	$i1,0($s2,$inp)
-+	stg	$i2,8($s2,$inp)
-+	xg	$i1,0($inp)
-+	xg	$i2,8($inp)
-+	stg	$i1,0($out,$inp)
-+	stg	$i2,8($out,$inp)
-+	la	$inp,16($inp)
-+	brct	$s3,.Lxts_km_prepare
-+
-+	slgr	$inp,$fp		# rewind $inp
-+	la	$s2,0($out,$inp)
-+	lgr	$s3,$fp
-+	.long	0xb92e00aa		# km $s2,$s2
-+	brc	1,.-4			# pay attention to "partial completion"
-+
-+	la	$s2,16($sp)
-+	slgr	$s2,$inp
-+	srlg	$s3,$fp,4
-+.Lxts_km_xor:
-+	lg	$i1,0($out,$inp)
-+	lg	$i2,8($out,$inp)
-+	xg	$i1,0($s2,$inp)
-+	xg	$i2,8($s2,$inp)
-+	stg	$i1,0($out,$inp)
-+	stg	$i2,8($out,$inp)
-+	la	$inp,16($inp)
-+	brct	$s3,.Lxts_km_xor
-+
-+	slgr	$len,$fp
-+	brc	1,.Lxts_km_loop		# not zero, no borrow
-+	algr	$fp,$len
-+	lghi	$len,0
-+	brc	4+1,.Lxts_km_loop	# not zero
-+
-+	l${g}	$i1,0($sp)		# back-chain
-+	llgf	$fp,`2*$SIZE_T-4`($sp)	# bytes used
-+	la	$i2,16($sp)
-+	srlg	$fp,$fp,4
-+.Lxts_km_zap:
-+	stg	$i1,0($i2)
-+	stg	$i1,8($i2)
-+	la	$i2,16($i2)
-+	brct	$fp,.Lxts_km_zap
-+
-+	la	$sp,0($i1)
-+	llgc	$len,2*$SIZE_T-1($i1)
-+	nill	$len,0x0f		# $len%=16
-+	bzr	$ra
-+
-+	# generate one more tweak...
-+	lghi	$i1,0x87
-+	srag	$i2,$s1,63		# broadcast upper bit
-+	ngr	$i1,$i2			# rem
-+	algr	$s0,$s0
-+	alcgr	$s1,$s1
-+	xgr	$s0,$i1
-+
-+	ltr	$len,$len		# clear zero flag
-+	br	$ra
-+.size	_s390x_xts_km,.-_s390x_xts_km
-+
-+.globl	AES_xts_encrypt
-+.type	AES_xts_encrypt,\@function
-+.align	16
-+AES_xts_encrypt:
-+	xgr	%r3,%r4			# flip %r3 and %r4, $out and $len
-+	xgr	%r4,%r3
-+	xgr	%r3,%r4
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	llgfr	$len,$len
-+___
-+$code.=<<___;
-+	st${g}	$len,1*$SIZE_T($sp)	# save copy of $len
-+	srag	$len,$len,4		# formally wrong, because it expands
-+					# sign byte, but who can afford asking
-+					# to process more than 2^63-1 bytes?
-+					# I use it, because it sets condition
-+					# code...
-+	bcr	8,$ra			# abort if zero (i.e. less than 16)
-+___
-+$code.=<<___ if (!$softonly);
-+	llgf	%r0,240($key2)
-+	lhi	%r1,16
-+	clr	%r0,%r1
-+	jl	.Lxts_enc_software
-+
-+	st${g}	$ra,5*$SIZE_T($sp)
-+	stm${g}	%r6,$s3,6*$SIZE_T($sp)
-+
-+	sllg	$len,$len,4		# $len&=~15
-+	slgr	$out,$inp
-+
-+	# generate the tweak value
-+	l${g}	$s3,$stdframe($sp)	# pointer to iv
-+	la	$s2,$tweak($sp)
-+	lmg	$s0,$s1,0($s3)
-+	lghi	$s3,16
-+	stmg	$s0,$s1,0($s2)
-+	la	%r1,0($key2)		# $key2 is not needed anymore
-+	.long	0xb92e00aa		# km $s2,$s2, generate the tweak
-+	brc	1,.-4			# can this happen?
-+
-+	l	%r0,240($key1)
-+	la	%r1,0($key1)		# $key1 is not needed anymore
-+	bras	$ra,_s390x_xts_km
-+	jz	.Lxts_enc_km_done
-+
-+	aghi	$inp,-16		# take one step back
-+	la	$i3,0($out,$inp)	# put aside real $out
-+.Lxts_enc_km_steal:
-+	llgc	$i1,16($inp)
-+	llgc	$i2,0($out,$inp)
-+	stc	$i1,0($out,$inp)
-+	stc	$i2,16($out,$inp)
-+	la	$inp,1($inp)
-+	brct	$len,.Lxts_enc_km_steal
-+
-+	la	$s2,0($i3)
-+	lghi	$s3,16
-+	lrvgr	$i1,$s0			# flip byte order
-+	lrvgr	$i2,$s1
-+	xg	$i1,0($s2)
-+	xg	$i2,8($s2)
-+	stg	$i1,0($s2)
-+	stg	$i2,8($s2)
-+	.long	0xb92e00aa		# km $s2,$s2
-+	brc	1,.-4			# can this happen?
-+	lrvgr	$i1,$s0			# flip byte order
-+	lrvgr	$i2,$s1
-+	xg	$i1,0($i3)
-+	xg	$i2,8($i3)
-+	stg	$i1,0($i3)
-+	stg	$i2,8($i3)
-+
-+.Lxts_enc_km_done:
-+	stg	$sp,$tweak+0($sp)	# wipe tweak
-+	stg	$sp,$tweak+8($sp)
-+	l${g}	$ra,5*$SIZE_T($sp)
-+	lm${g}	%r6,$s3,6*$SIZE_T($sp)
-+	br	$ra
-+.align	16
-+.Lxts_enc_software:
-+___
-+$code.=<<___;
-+	stm${g}	%r6,$ra,6*$SIZE_T($sp)
-+
-+	slgr	$out,$inp
-+
-+	l${g}	$s3,$stdframe($sp)	# ivp
-+	llgf	$s0,0($s3)		# load iv
-+	llgf	$s1,4($s3)
-+	llgf	$s2,8($s3)
-+	llgf	$s3,12($s3)
-+	stm${g}	%r2,%r5,2*$SIZE_T($sp)
-+	la	$key,0($key2)
-+	larl	$tbl,AES_Te
-+	bras	$ra,_s390x_AES_encrypt	# generate the tweak
-+	lm${g}	%r2,%r5,2*$SIZE_T($sp)
-+	stm	$s0,$s3,$tweak($sp)	# save the tweak
-+	j	.Lxts_enc_enter
-+
-+.align	16
-+.Lxts_enc_loop:
-+	lrvg	$s1,$tweak+0($sp)	# load the tweak in little-endian
-+	lrvg	$s3,$tweak+8($sp)
-+	lghi	%r1,0x87
-+	srag	%r0,$s3,63		# broadcast upper bit
-+	ngr	%r1,%r0			# rem
-+	algr	$s1,$s1
-+	alcgr	$s3,$s3
-+	xgr	$s1,%r1
-+	lrvgr	$s1,$s1			# flip byte order
-+	lrvgr	$s3,$s3
-+	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits 
-+	stg	$s1,$tweak+0($sp)	# save the tweak
-+	llgfr	$s1,$s1
-+	srlg	$s2,$s3,32
-+	stg	$s3,$tweak+8($sp)
-+	llgfr	$s3,$s3
-+	la	$inp,16($inp)		# $inp+=16
-+.Lxts_enc_enter:
-+	x	$s0,0($inp)		# ^=*($inp)
-+	x	$s1,4($inp)
-+	x	$s2,8($inp)
-+	x	$s3,12($inp)
-+	stm${g}	%r2,%r3,2*$SIZE_T($sp)	# only two registers are changing
-+	la	$key,0($key1)
-+	bras	$ra,_s390x_AES_encrypt
-+	lm${g}	%r2,%r5,2*$SIZE_T($sp)
-+	x	$s0,$tweak+0($sp)	# ^=tweak
-+	x	$s1,$tweak+4($sp)
-+	x	$s2,$tweak+8($sp)
-+	x	$s3,$tweak+12($sp)
-+	st	$s0,0($out,$inp)
-+	st	$s1,4($out,$inp)
-+	st	$s2,8($out,$inp)
-+	st	$s3,12($out,$inp)
-+	brct${g}	$len,.Lxts_enc_loop
-+
-+	llgc	$len,`2*$SIZE_T-1`($sp)
-+	nill	$len,0x0f		# $len%16
-+	jz	.Lxts_enc_done
-+
-+	la	$i3,0($inp,$out)	# put aside real $out
-+.Lxts_enc_steal:
-+	llgc	%r0,16($inp)
-+	llgc	%r1,0($out,$inp)
-+	stc	%r0,0($out,$inp)
-+	stc	%r1,16($out,$inp)
-+	la	$inp,1($inp)
-+	brct	$len,.Lxts_enc_steal
-+	la	$out,0($i3)		# restore real $out
-+
-+	# generate last tweak...
-+	lrvg	$s1,$tweak+0($sp)	# load the tweak in little-endian
-+	lrvg	$s3,$tweak+8($sp)
-+	lghi	%r1,0x87
-+	srag	%r0,$s3,63		# broadcast upper bit
-+	ngr	%r1,%r0			# rem
-+	algr	$s1,$s1
-+	alcgr	$s3,$s3
-+	xgr	$s1,%r1
-+	lrvgr	$s1,$s1			# flip byte order
-+	lrvgr	$s3,$s3
-+	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits 
-+	stg	$s1,$tweak+0($sp)	# save the tweak
-+	llgfr	$s1,$s1
-+	srlg	$s2,$s3,32
-+	stg	$s3,$tweak+8($sp)
-+	llgfr	$s3,$s3
-+
-+	x	$s0,0($out)		# ^=*(inp)|stolen cipther-text
-+	x	$s1,4($out)
-+	x	$s2,8($out)
-+	x	$s3,12($out)
-+	st${g}	$out,4*$SIZE_T($sp)
-+	la	$key,0($key1)
-+	bras	$ra,_s390x_AES_encrypt
-+	l${g}	$out,4*$SIZE_T($sp)
-+	x	$s0,`$tweak+0`($sp)	# ^=tweak
-+	x	$s1,`$tweak+4`($sp)
-+	x	$s2,`$tweak+8`($sp)
-+	x	$s3,`$tweak+12`($sp)
-+	st	$s0,0($out)
-+	st	$s1,4($out)
-+	st	$s2,8($out)
-+	st	$s3,12($out)
-+
-+.Lxts_enc_done:
-+	stg	$sp,$tweak+0($sp)	# wipe tweak
-+	stg	$sp,$twesk+8($sp)
-+	lm${g}	%r6,$ra,6*$SIZE_T($sp)
-+	br	$ra
-+.size	AES_xts_encrypt,.-AES_xts_encrypt
-+___
-+# void AES_xts_decrypt(const char *inp,char *out,size_t len,
-+#	const AES_KEY *key1, const AES_KEY *key2,
-+#	const unsigned char iv[16]);
-+#
-+$code.=<<___;
-+.globl	AES_xts_decrypt
-+.type	AES_xts_decrypt,\@function
-+.align	16
-+AES_xts_decrypt:
-+	xgr	%r3,%r4			# flip %r3 and %r4, $out and $len
-+	xgr	%r4,%r3
-+	xgr	%r3,%r4
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	llgfr	$len,$len
-+___
-+$code.=<<___;
-+	st${g}	$len,1*$SIZE_T($sp)	# save copy of $len
-+	aghi	$len,-16
-+	bcr	4,$ra			# abort if less than zero. formally
-+					# wrong, because $len is unsigned,
-+					# but who can afford asking to
-+					# process more than 2^63-1 bytes?
-+	tmll	$len,0x0f
-+	jnz	.Lxts_dec_proceed
-+	aghi	$len,16
-+.Lxts_dec_proceed:
-+___
-+$code.=<<___ if (!$softonly);
-+	llgf	%r0,240($key2)
-+	lhi	%r1,16
-+	clr	%r0,%r1
-+	jl	.Lxts_dec_software
-+
-+	st${g}	$ra,5*$SIZE_T($sp)
-+	stm${g}	%r6,$s3,6*$SIZE_T($sp)
-+
-+	nill	$len,0xfff0		# $len&=~15
-+	slgr	$out,$inp
-+
-+	# generate the tweak value
-+	l${g}	$s3,$stdframe($sp)	# pointer to iv
-+	la	$s2,$tweak($sp)
-+	lmg	$s0,$s1,0($s3)
-+	lghi	$s3,16
-+	stmg	$s0,$s1,0($s2)
-+	la	%r1,0($key2)		# $key2 is not needed past this point
-+	.long	0xb92e00aa		# km $s2,$s2, generate the tweak
-+	brc	1,.-4			# can this happen?
-+
-+	l	%r0,240($key1)
-+	la	%r1,0($key1)		# $key1 is not needed anymore
-+
-+	ltgr	$len,$len
-+	jz	.Lxts_dec_km_short
-+	bras	$ra,_s390x_xts_km
-+	jz	.Lxts_dec_km_done
-+
-+	lrvgr	$s2,$s0			# make copy in reverse byte order
-+	lrvgr	$s3,$s1
-+	j	.Lxts_dec_km_2ndtweak
-+
-+.Lxts_dec_km_short:
-+	llgc	$len,`2*$SIZE_T-1`($sp)
-+	nill	$len,0x0f		# $len%=16
-+	lrvg	$s0,$tweak+0($sp)	# load the tweak
-+	lrvg	$s1,$tweak+8($sp)
-+	lrvgr	$s2,$s0			# make copy in reverse byte order
-+	lrvgr	$s3,$s1
-+
-+.Lxts_dec_km_2ndtweak:
-+	lghi	$i1,0x87
-+	srag	$i2,$s1,63		# broadcast upper bit
-+	ngr	$i1,$i2			# rem
-+	algr	$s0,$s0
-+	alcgr	$s1,$s1
-+	xgr	$s0,$i1
-+	lrvgr	$i1,$s0			# flip byte order
-+	lrvgr	$i2,$s1
-+
-+	xg	$i1,0($inp)
-+	xg	$i2,8($inp)
-+	stg	$i1,0($out,$inp)
-+	stg	$i2,8($out,$inp)
-+	la	$i2,0($out,$inp)
-+	lghi	$i3,16
-+	.long	0xb92e0066		# km $i2,$i2
-+	brc	1,.-4			# can this happen?
-+	lrvgr	$i1,$s0
-+	lrvgr	$i2,$s1
-+	xg	$i1,0($out,$inp)
-+	xg	$i2,8($out,$inp)
-+	stg	$i1,0($out,$inp)
-+	stg	$i2,8($out,$inp)
-+
-+	la	$i3,0($out,$inp)	# put aside real $out
-+.Lxts_dec_km_steal:
-+	llgc	$i1,16($inp)
-+	llgc	$i2,0($out,$inp)
-+	stc	$i1,0($out,$inp)
-+	stc	$i2,16($out,$inp)
-+	la	$inp,1($inp)
-+	brct	$len,.Lxts_dec_km_steal
-+
-+	lgr	$s0,$s2
-+	lgr	$s1,$s3
-+	xg	$s0,0($i3)
-+	xg	$s1,8($i3)
-+	stg	$s0,0($i3)
-+	stg	$s1,8($i3)
-+	la	$s0,0($i3)
-+	lghi	$s1,16
-+	.long	0xb92e0088		# km $s0,$s0
-+	brc	1,.-4			# can this happen?
-+	xg	$s2,0($i3)
-+	xg	$s3,8($i3)
-+	stg	$s2,0($i3)
-+	stg	$s3,8($i3)
-+.Lxts_dec_km_done:
-+	stg	$sp,$tweak+0($sp)	# wipe tweak
-+	stg	$sp,$tweak+8($sp)
-+	l${g}	$ra,5*$SIZE_T($sp)
-+	lm${g}	%r6,$s3,6*$SIZE_T($sp)
-+	br	$ra
-+.align	16
-+.Lxts_dec_software:
-+___
-+$code.=<<___;
-+	stm${g}	%r6,$ra,6*$SIZE_T($sp)
-+
-+	srlg	$len,$len,4
-+	slgr	$out,$inp
-+
-+	l${g}	$s3,$stdframe($sp)	# ivp
-+	llgf	$s0,0($s3)		# load iv
-+	llgf	$s1,4($s3)
-+	llgf	$s2,8($s3)
-+	llgf	$s3,12($s3)
-+	stm${g}	%r2,%r5,2*$SIZE_T($sp)
-+	la	$key,0($key2)
-+	larl	$tbl,AES_Te
-+	bras	$ra,_s390x_AES_encrypt	# generate the tweak
-+	lm${g}	%r2,%r5,2*$SIZE_T($sp)
-+	larl	$tbl,AES_Td
-+	lt${g}r	$len,$len
-+	stm	$s0,$s3,$tweak($sp)	# save the tweak
-+	jz	.Lxts_dec_short
-+	j	.Lxts_dec_enter
-+
-+.align	16
-+.Lxts_dec_loop:
-+	lrvg	$s1,$tweak+0($sp)	# load the tweak in little-endian
-+	lrvg	$s3,$tweak+8($sp)
-+	lghi	%r1,0x87
-+	srag	%r0,$s3,63		# broadcast upper bit
-+	ngr	%r1,%r0			# rem
-+	algr	$s1,$s1
-+	alcgr	$s3,$s3
-+	xgr	$s1,%r1
-+	lrvgr	$s1,$s1			# flip byte order
-+	lrvgr	$s3,$s3
-+	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits 
-+	stg	$s1,$tweak+0($sp)	# save the tweak
-+	llgfr	$s1,$s1
-+	srlg	$s2,$s3,32
-+	stg	$s3,$tweak+8($sp)
-+	llgfr	$s3,$s3
-+.Lxts_dec_enter:
-+	x	$s0,0($inp)		# tweak^=*(inp)
-+	x	$s1,4($inp)
-+	x	$s2,8($inp)
-+	x	$s3,12($inp)
-+	stm${g}	%r2,%r3,2*$SIZE_T($sp)	# only two registers are changing
-+	la	$key,0($key1)
-+	bras	$ra,_s390x_AES_decrypt
-+	lm${g}	%r2,%r5,2*$SIZE_T($sp)
-+	x	$s0,$tweak+0($sp)	# ^=tweak
-+	x	$s1,$tweak+4($sp)
-+	x	$s2,$tweak+8($sp)
-+	x	$s3,$tweak+12($sp)
-+	st	$s0,0($out,$inp)
-+	st	$s1,4($out,$inp)
-+	st	$s2,8($out,$inp)
-+	st	$s3,12($out,$inp)
-+	la	$inp,16($inp)
-+	brct${g}	$len,.Lxts_dec_loop
-+
-+	llgc	$len,`2*$SIZE_T-1`($sp)
-+	nill	$len,0x0f		# $len%16
-+	jz	.Lxts_dec_done
-+
-+	# generate pair of tweaks...
-+	lrvg	$s1,$tweak+0($sp)	# load the tweak in little-endian
-+	lrvg	$s3,$tweak+8($sp)
-+	lghi	%r1,0x87
-+	srag	%r0,$s3,63		# broadcast upper bit
-+	ngr	%r1,%r0			# rem
-+	algr	$s1,$s1
-+	alcgr	$s3,$s3
-+	xgr	$s1,%r1
-+	lrvgr	$i2,$s1			# flip byte order
-+	lrvgr	$i3,$s3
-+	stmg	$i2,$i3,$tweak($sp)	# save the 1st tweak
-+	j	.Lxts_dec_2ndtweak
-+
-+.align	16
-+.Lxts_dec_short:
-+	llgc	$len,`2*$SIZE_T-1`($sp)
-+	nill	$len,0x0f		# $len%16
-+	lrvg	$s1,$tweak+0($sp)	# load the tweak in little-endian
-+	lrvg	$s3,$tweak+8($sp)
-+.Lxts_dec_2ndtweak:
-+	lghi	%r1,0x87
-+	srag	%r0,$s3,63		# broadcast upper bit
-+	ngr	%r1,%r0			# rem
-+	algr	$s1,$s1
-+	alcgr	$s3,$s3
-+	xgr	$s1,%r1
-+	lrvgr	$s1,$s1			# flip byte order
-+	lrvgr	$s3,$s3
-+	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits
-+	stg	$s1,$tweak-16+0($sp)	# save the 2nd tweak
-+	llgfr	$s1,$s1
-+	srlg	$s2,$s3,32
-+	stg	$s3,$tweak-16+8($sp)
-+	llgfr	$s3,$s3
-+
-+	x	$s0,0($inp)		# tweak_the_2nd^=*(inp)
-+	x	$s1,4($inp)
-+	x	$s2,8($inp)
-+	x	$s3,12($inp)
-+	stm${g}	%r2,%r3,2*$SIZE_T($sp)
-+	la	$key,0($key1)
-+	bras	$ra,_s390x_AES_decrypt
-+	lm${g}	%r2,%r5,2*$SIZE_T($sp)
-+	x	$s0,$tweak-16+0($sp)	# ^=tweak_the_2nd
-+	x	$s1,$tweak-16+4($sp)
-+	x	$s2,$tweak-16+8($sp)
-+	x	$s3,$tweak-16+12($sp)
-+	st	$s0,0($out,$inp)
-+	st	$s1,4($out,$inp)
-+	st	$s2,8($out,$inp)
-+	st	$s3,12($out,$inp)
-+
-+	la	$i3,0($out,$inp)	# put aside real $out
-+.Lxts_dec_steal:
-+	llgc	%r0,16($inp)
-+	llgc	%r1,0($out,$inp)
-+	stc	%r0,0($out,$inp)
-+	stc	%r1,16($out,$inp)
-+	la	$inp,1($inp)
-+	brct	$len,.Lxts_dec_steal
-+	la	$out,0($i3)		# restore real $out
-+
-+	lm	$s0,$s3,$tweak($sp)	# load the 1st tweak
-+	x	$s0,0($out)		# tweak^=*(inp)|stolen cipher-text
-+	x	$s1,4($out)
-+	x	$s2,8($out)
-+	x	$s3,12($out)
-+	st${g}	$out,4*$SIZE_T($sp)
-+	la	$key,0($key1)
-+	bras	$ra,_s390x_AES_decrypt
-+	l${g}	$out,4*$SIZE_T($sp)
-+	x	$s0,$tweak+0($sp)	# ^=tweak
-+	x	$s1,$tweak+4($sp)
-+	x	$s2,$tweak+8($sp)
-+	x	$s3,$tweak+12($sp)
-+	st	$s0,0($out)
-+	st	$s1,4($out)
-+	st	$s2,8($out)
-+	st	$s3,12($out)
-+	stg	$sp,$tweak-16+0($sp)	# wipe 2nd tweak
-+	stg	$sp,$tweak-16+8($sp)
-+.Lxts_dec_done:
-+	stg	$sp,$tweak+0($sp)	# wipe tweak
-+	stg	$sp,$twesk+8($sp)
-+	lm${g}	%r6,$ra,6*$SIZE_T($sp)
-+	br	$ra
-+.size	AES_xts_decrypt,.-AES_xts_decrypt
-+___
-+}
-+$code.=<<___;
-+.string	"AES for s390x, CRYPTOGAMS by "
-+.comm	OPENSSL_s390xcap_P,80,8
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;	# force flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-sparcv9.pl
-new file mode 100755
-index 0000000..883fae8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-sparcv9.pl
-@@ -0,0 +1,1192 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. Rights for redistribution and usage in source and binary
-+# forms are granted according to the OpenSSL license.
-+# ====================================================================
-+#
-+# Version 1.1
-+#
-+# The major reason for undertaken effort was to mitigate the hazard of
-+# cache-timing attack. This is [currently and initially!] addressed in
-+# two ways. 1. S-boxes are compressed from 5KB to 2KB+256B size each.
-+# 2. References to them are scheduled for L2 cache latency, meaning
-+# that the tables don't have to reside in L1 cache. Once again, this
-+# is an initial draft and one should expect more countermeasures to
-+# be implemented...
-+#
-+# Version 1.1 prefetches T[ed]4 in order to mitigate attack on last
-+# round.
-+#
-+# Even though performance was not the primary goal [on the contrary,
-+# extra shifts "induced" by compressed S-box and longer loop epilogue
-+# "induced" by scheduling for L2 have negative effect on performance],
-+# the code turned out to run in ~23 cycles per processed byte en-/
-+# decrypted with 128-bit key. This is pretty good result for code
-+# with mentioned qualities and UltraSPARC core. Compared to Sun C
-+# generated code my encrypt procedure runs just few percents faster,
-+# while decrypt one - whole 50% faster [yes, Sun C failed to generate
-+# optimal decrypt procedure]. Compared to GNU C generated code both
-+# procedures are more than 60% faster:-)
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+$frame="STACK_FRAME";
-+$bias="STACK_BIAS";
-+$locals=16;
-+
-+$acc0="%l0";
-+$acc1="%o0";
-+$acc2="%o1";
-+$acc3="%o2";
-+
-+$acc4="%l1";
-+$acc5="%o3";
-+$acc6="%o4";
-+$acc7="%o5";
-+
-+$acc8="%l2";
-+$acc9="%o7";
-+$acc10="%g1";
-+$acc11="%g2";
-+
-+$acc12="%l3";
-+$acc13="%g3";
-+$acc14="%g4";
-+$acc15="%g5";
-+
-+$t0="%l4";
-+$t1="%l5";
-+$t2="%l6";
-+$t3="%l7";
-+
-+$s0="%i0";
-+$s1="%i1";
-+$s2="%i2";
-+$s3="%i3";
-+$tbl="%i4";
-+$key="%i5";
-+$rounds="%i7";	# aliases with return address, which is off-loaded to stack
-+
-+sub _data_word()
-+{ my $i;
-+    while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
-+}
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#ifdef  __arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+#endif
-+.section	".text",#alloc,#execinstr
-+
-+.align	256
-+AES_Te:
-+___
-+&_data_word(
-+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
-+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
-+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
-+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
-+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
-+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
-+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
-+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
-+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
-+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
-+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
-+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
-+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
-+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
-+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
-+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
-+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
-+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
-+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
-+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
-+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
-+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
-+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
-+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
-+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
-+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
-+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
-+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
-+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
-+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
-+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
-+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
-+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
-+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
-+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
-+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
-+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
-+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
-+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
-+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
-+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
-+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
-+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
-+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
-+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
-+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
-+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
-+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
-+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
-+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
-+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
-+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
-+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
-+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
-+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
-+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
-+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
-+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
-+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
-+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
-+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
-+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
-+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
-+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
-+$code.=<<___;
-+	.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
-+	.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-+	.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-+	.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-+	.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-+	.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-+	.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-+	.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-+	.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-+	.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-+	.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-+	.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-+	.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-+	.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-+	.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-+	.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-+	.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-+	.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-+	.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-+	.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-+	.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-+	.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-+	.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-+	.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-+	.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-+	.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-+	.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-+	.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-+	.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-+	.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-+	.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-+	.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+.type	AES_Te,#object
-+.size	AES_Te,(.-AES_Te)
-+
-+.align	64
-+.skip	16
-+_sparcv9_AES_encrypt:
-+	save	%sp,-$frame-$locals,%sp
-+	stx	%i7,[%sp+$bias+$frame+0]	! off-load return address
-+	ld	[$key+240],$rounds
-+	ld	[$key+0],$t0
-+	ld	[$key+4],$t1			!
-+	ld	[$key+8],$t2
-+	srl	$rounds,1,$rounds
-+	xor	$t0,$s0,$s0
-+	ld	[$key+12],$t3
-+	srl	$s0,21,$acc0
-+	xor	$t1,$s1,$s1
-+	ld	[$key+16],$t0
-+	srl	$s1,13,$acc1			!
-+	xor	$t2,$s2,$s2
-+	ld	[$key+20],$t1
-+	xor	$t3,$s3,$s3
-+	ld	[$key+24],$t2
-+	and	$acc0,2040,$acc0
-+	ld	[$key+28],$t3
-+	nop
-+.Lenc_loop:
-+	srl	$s2,5,$acc2			!
-+	and	$acc1,2040,$acc1
-+	ldx	[$tbl+$acc0],$acc0
-+	sll	$s3,3,$acc3
-+	and	$acc2,2040,$acc2
-+	ldx	[$tbl+$acc1],$acc1
-+	srl	$s1,21,$acc4
-+	and	$acc3,2040,$acc3
-+	ldx	[$tbl+$acc2],$acc2		!
-+	srl	$s2,13,$acc5
-+	and	$acc4,2040,$acc4
-+	ldx	[$tbl+$acc3],$acc3
-+	srl	$s3,5,$acc6
-+	and	$acc5,2040,$acc5
-+	ldx	[$tbl+$acc4],$acc4
-+	fmovs	%f0,%f0
-+	sll	$s0,3,$acc7			!
-+	and	$acc6,2040,$acc6
-+	ldx	[$tbl+$acc5],$acc5
-+	srl	$s2,21,$acc8
-+	and	$acc7,2040,$acc7
-+	ldx	[$tbl+$acc6],$acc6
-+	srl	$s3,13,$acc9
-+	and	$acc8,2040,$acc8
-+	ldx	[$tbl+$acc7],$acc7		!
-+	srl	$s0,5,$acc10
-+	and	$acc9,2040,$acc9
-+	ldx	[$tbl+$acc8],$acc8
-+	sll	$s1,3,$acc11
-+	and	$acc10,2040,$acc10
-+	ldx	[$tbl+$acc9],$acc9
-+	fmovs	%f0,%f0
-+	srl	$s3,21,$acc12			!
-+	and	$acc11,2040,$acc11
-+	ldx	[$tbl+$acc10],$acc10
-+	srl	$s0,13,$acc13
-+	and	$acc12,2040,$acc12
-+	ldx	[$tbl+$acc11],$acc11
-+	srl	$s1,5,$acc14
-+	and	$acc13,2040,$acc13
-+	ldx	[$tbl+$acc12],$acc12		!
-+	sll	$s2,3,$acc15
-+	and	$acc14,2040,$acc14
-+	ldx	[$tbl+$acc13],$acc13
-+	and	$acc15,2040,$acc15
-+	add	$key,32,$key
-+	ldx	[$tbl+$acc14],$acc14
-+	fmovs	%f0,%f0
-+	subcc	$rounds,1,$rounds		!
-+	ldx	[$tbl+$acc15],$acc15
-+	bz,a,pn	%icc,.Lenc_last
-+	add	$tbl,2048,$rounds
-+
-+		srlx	$acc1,8,$acc1
-+		xor	$acc0,$t0,$t0
-+	ld	[$key+0],$s0
-+	fmovs	%f0,%f0
-+		srlx	$acc2,16,$acc2		!
-+		xor	$acc1,$t0,$t0
-+	ld	[$key+4],$s1
-+		srlx	$acc3,24,$acc3
-+		xor	$acc2,$t0,$t0
-+	ld	[$key+8],$s2
-+		srlx	$acc5,8,$acc5
-+		xor	$acc3,$t0,$t0
-+	ld	[$key+12],$s3			!
-+		srlx	$acc6,16,$acc6
-+		xor	$acc4,$t1,$t1
-+	fmovs	%f0,%f0
-+		srlx	$acc7,24,$acc7
-+		xor	$acc5,$t1,$t1
-+		srlx	$acc9,8,$acc9
-+		xor	$acc6,$t1,$t1
-+		srlx	$acc10,16,$acc10	!
-+		xor	$acc7,$t1,$t1
-+		srlx	$acc11,24,$acc11
-+		xor	$acc8,$t2,$t2
-+		srlx	$acc13,8,$acc13
-+		xor	$acc9,$t2,$t2
-+		srlx	$acc14,16,$acc14
-+		xor	$acc10,$t2,$t2
-+		srlx	$acc15,24,$acc15	!
-+		xor	$acc11,$t2,$t2
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$t3,$t3
-+	srl	$t0,21,$acc0
-+		xor	$acc14,$t3,$t3
-+	srl	$t1,13,$acc1
-+		xor	$acc15,$t3,$t3
-+
-+	and	$acc0,2040,$acc0		!
-+	srl	$t2,5,$acc2
-+	and	$acc1,2040,$acc1
-+	ldx	[$tbl+$acc0],$acc0
-+	sll	$t3,3,$acc3
-+	and	$acc2,2040,$acc2
-+	ldx	[$tbl+$acc1],$acc1
-+	fmovs	%f0,%f0
-+	srl	$t1,21,$acc4			!
-+	and	$acc3,2040,$acc3
-+	ldx	[$tbl+$acc2],$acc2
-+	srl	$t2,13,$acc5
-+	and	$acc4,2040,$acc4
-+	ldx	[$tbl+$acc3],$acc3
-+	srl	$t3,5,$acc6
-+	and	$acc5,2040,$acc5
-+	ldx	[$tbl+$acc4],$acc4		!
-+	sll	$t0,3,$acc7
-+	and	$acc6,2040,$acc6
-+	ldx	[$tbl+$acc5],$acc5
-+	srl	$t2,21,$acc8
-+	and	$acc7,2040,$acc7
-+	ldx	[$tbl+$acc6],$acc6
-+	fmovs	%f0,%f0
-+	srl	$t3,13,$acc9			!
-+	and	$acc8,2040,$acc8
-+	ldx	[$tbl+$acc7],$acc7
-+	srl	$t0,5,$acc10
-+	and	$acc9,2040,$acc9
-+	ldx	[$tbl+$acc8],$acc8
-+	sll	$t1,3,$acc11
-+	and	$acc10,2040,$acc10
-+	ldx	[$tbl+$acc9],$acc9		!
-+	srl	$t3,21,$acc12
-+	and	$acc11,2040,$acc11
-+	ldx	[$tbl+$acc10],$acc10
-+	srl	$t0,13,$acc13
-+	and	$acc12,2040,$acc12
-+	ldx	[$tbl+$acc11],$acc11
-+	fmovs	%f0,%f0
-+	srl	$t1,5,$acc14			!
-+	and	$acc13,2040,$acc13
-+	ldx	[$tbl+$acc12],$acc12
-+	sll	$t2,3,$acc15
-+	and	$acc14,2040,$acc14
-+	ldx	[$tbl+$acc13],$acc13
-+		srlx	$acc1,8,$acc1
-+	and	$acc15,2040,$acc15
-+	ldx	[$tbl+$acc14],$acc14		!
-+
-+		srlx	$acc2,16,$acc2
-+		xor	$acc0,$s0,$s0
-+	ldx	[$tbl+$acc15],$acc15
-+		srlx	$acc3,24,$acc3
-+		xor	$acc1,$s0,$s0
-+	ld	[$key+16],$t0
-+	fmovs	%f0,%f0
-+		srlx	$acc5,8,$acc5		!
-+		xor	$acc2,$s0,$s0
-+	ld	[$key+20],$t1
-+		srlx	$acc6,16,$acc6
-+		xor	$acc3,$s0,$s0
-+	ld	[$key+24],$t2
-+		srlx	$acc7,24,$acc7
-+		xor	$acc4,$s1,$s1
-+	ld	[$key+28],$t3			!
-+		srlx	$acc9,8,$acc9
-+		xor	$acc5,$s1,$s1
-+	ldx	[$tbl+2048+0],%g0		! prefetch te4
-+		srlx	$acc10,16,$acc10
-+		xor	$acc6,$s1,$s1
-+	ldx	[$tbl+2048+32],%g0		! prefetch te4
-+		srlx	$acc11,24,$acc11
-+		xor	$acc7,$s1,$s1
-+	ldx	[$tbl+2048+64],%g0		! prefetch te4
-+		srlx	$acc13,8,$acc13
-+		xor	$acc8,$s2,$s2
-+	ldx	[$tbl+2048+96],%g0		! prefetch te4
-+		srlx	$acc14,16,$acc14	!
-+		xor	$acc9,$s2,$s2
-+	ldx	[$tbl+2048+128],%g0		! prefetch te4
-+		srlx	$acc15,24,$acc15
-+		xor	$acc10,$s2,$s2
-+	ldx	[$tbl+2048+160],%g0		! prefetch te4
-+	srl	$s0,21,$acc0
-+		xor	$acc11,$s2,$s2
-+	ldx	[$tbl+2048+192],%g0		! prefetch te4
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$s3,$s3
-+	ldx	[$tbl+2048+224],%g0		! prefetch te4
-+	srl	$s1,13,$acc1			!
-+		xor	$acc14,$s3,$s3
-+		xor	$acc15,$s3,$s3
-+	ba	.Lenc_loop
-+	and	$acc0,2040,$acc0
-+
-+.align	32
-+.Lenc_last:
-+		srlx	$acc1,8,$acc1		!
-+		xor	$acc0,$t0,$t0
-+	ld	[$key+0],$s0
-+		srlx	$acc2,16,$acc2
-+		xor	$acc1,$t0,$t0
-+	ld	[$key+4],$s1
-+		srlx	$acc3,24,$acc3
-+		xor	$acc2,$t0,$t0
-+	ld	[$key+8],$s2			!
-+		srlx	$acc5,8,$acc5
-+		xor	$acc3,$t0,$t0
-+	ld	[$key+12],$s3
-+		srlx	$acc6,16,$acc6
-+		xor	$acc4,$t1,$t1
-+		srlx	$acc7,24,$acc7
-+		xor	$acc5,$t1,$t1
-+		srlx	$acc9,8,$acc9		!
-+		xor	$acc6,$t1,$t1
-+		srlx	$acc10,16,$acc10
-+		xor	$acc7,$t1,$t1
-+		srlx	$acc11,24,$acc11
-+		xor	$acc8,$t2,$t2
-+		srlx	$acc13,8,$acc13
-+		xor	$acc9,$t2,$t2
-+		srlx	$acc14,16,$acc14	!
-+		xor	$acc10,$t2,$t2
-+		srlx	$acc15,24,$acc15
-+		xor	$acc11,$t2,$t2
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$t3,$t3
-+	srl	$t0,24,$acc0
-+		xor	$acc14,$t3,$t3
-+	srl	$t1,16,$acc1			!
-+		xor	$acc15,$t3,$t3
-+
-+	srl	$t2,8,$acc2
-+	and	$acc1,255,$acc1
-+	ldub	[$rounds+$acc0],$acc0
-+	srl	$t1,24,$acc4
-+	and	$acc2,255,$acc2
-+	ldub	[$rounds+$acc1],$acc1
-+	srl	$t2,16,$acc5			!
-+	and	$t3,255,$acc3
-+	ldub	[$rounds+$acc2],$acc2
-+	ldub	[$rounds+$acc3],$acc3
-+	srl	$t3,8,$acc6
-+	and	$acc5,255,$acc5
-+	ldub	[$rounds+$acc4],$acc4
-+	fmovs	%f0,%f0
-+	srl	$t2,24,$acc8			!
-+	and	$acc6,255,$acc6
-+	ldub	[$rounds+$acc5],$acc5
-+	srl	$t3,16,$acc9
-+	and	$t0,255,$acc7
-+	ldub	[$rounds+$acc6],$acc6
-+	ldub	[$rounds+$acc7],$acc7
-+	fmovs	%f0,%f0
-+	srl	$t0,8,$acc10			!
-+	and	$acc9,255,$acc9
-+	ldub	[$rounds+$acc8],$acc8
-+	srl	$t3,24,$acc12
-+	and	$acc10,255,$acc10
-+	ldub	[$rounds+$acc9],$acc9
-+	srl	$t0,16,$acc13
-+	and	$t1,255,$acc11
-+	ldub	[$rounds+$acc10],$acc10		!
-+	srl	$t1,8,$acc14
-+	and	$acc13,255,$acc13
-+	ldub	[$rounds+$acc11],$acc11
-+	ldub	[$rounds+$acc12],$acc12
-+	and	$acc14,255,$acc14
-+	ldub	[$rounds+$acc13],$acc13
-+	and	$t2,255,$acc15
-+	ldub	[$rounds+$acc14],$acc14		!
-+
-+		sll	$acc0,24,$acc0
-+		xor	$acc3,$s0,$s0
-+	ldub	[$rounds+$acc15],$acc15
-+		sll	$acc1,16,$acc1
-+		xor	$acc0,$s0,$s0
-+	ldx	[%sp+$bias+$frame+0],%i7	! restore return address
-+	fmovs	%f0,%f0
-+		sll	$acc2,8,$acc2		!
-+		xor	$acc1,$s0,$s0
-+		sll	$acc4,24,$acc4
-+		xor	$acc2,$s0,$s0
-+		sll	$acc5,16,$acc5
-+		xor	$acc7,$s1,$s1
-+		sll	$acc6,8,$acc6
-+		xor	$acc4,$s1,$s1
-+		sll	$acc8,24,$acc8		!
-+		xor	$acc5,$s1,$s1
-+		sll	$acc9,16,$acc9
-+		xor	$acc11,$s2,$s2
-+		sll	$acc10,8,$acc10
-+		xor	$acc6,$s1,$s1
-+		sll	$acc12,24,$acc12
-+		xor	$acc8,$s2,$s2
-+		sll	$acc13,16,$acc13	!
-+		xor	$acc9,$s2,$s2
-+		sll	$acc14,8,$acc14
-+		xor	$acc10,$s2,$s2
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$s3,$s3
-+		xor	$acc14,$s3,$s3
-+		xor	$acc15,$s3,$s3
-+
-+	ret
-+	restore
-+.type	_sparcv9_AES_encrypt,#function
-+.size	_sparcv9_AES_encrypt,(.-_sparcv9_AES_encrypt)
-+
-+.align	32
-+.globl	AES_encrypt
-+AES_encrypt:
-+	or	%o0,%o1,%g1
-+	andcc	%g1,3,%g0
-+	bnz,pn	%xcc,.Lunaligned_enc
-+	save	%sp,-$frame,%sp
-+
-+	ld	[%i0+0],%o0
-+	ld	[%i0+4],%o1
-+	ld	[%i0+8],%o2
-+	ld	[%i0+12],%o3
-+
-+1:	call	.+8
-+	add	%o7,AES_Te-1b,%o4
-+	call	_sparcv9_AES_encrypt
-+	mov	%i2,%o5
-+
-+	st	%o0,[%i1+0]
-+	st	%o1,[%i1+4]
-+	st	%o2,[%i1+8]
-+	st	%o3,[%i1+12]
-+
-+	ret
-+	restore
-+
-+.align	32
-+.Lunaligned_enc:
-+	ldub	[%i0+0],%l0
-+	ldub	[%i0+1],%l1
-+	ldub	[%i0+2],%l2
-+
-+	sll	%l0,24,%l0
-+	ldub	[%i0+3],%l3
-+	sll	%l1,16,%l1
-+	ldub	[%i0+4],%l4
-+	sll	%l2,8,%l2
-+	or	%l1,%l0,%l0
-+	ldub	[%i0+5],%l5
-+	sll	%l4,24,%l4
-+	or	%l3,%l2,%l2
-+	ldub	[%i0+6],%l6
-+	sll	%l5,16,%l5
-+	or	%l0,%l2,%o0
-+	ldub	[%i0+7],%l7
-+
-+	sll	%l6,8,%l6
-+	or	%l5,%l4,%l4
-+	ldub	[%i0+8],%l0
-+	or	%l7,%l6,%l6
-+	ldub	[%i0+9],%l1
-+	or	%l4,%l6,%o1
-+	ldub	[%i0+10],%l2
-+
-+	sll	%l0,24,%l0
-+	ldub	[%i0+11],%l3
-+	sll	%l1,16,%l1
-+	ldub	[%i0+12],%l4
-+	sll	%l2,8,%l2
-+	or	%l1,%l0,%l0
-+	ldub	[%i0+13],%l5
-+	sll	%l4,24,%l4
-+	or	%l3,%l2,%l2
-+	ldub	[%i0+14],%l6
-+	sll	%l5,16,%l5
-+	or	%l0,%l2,%o2
-+	ldub	[%i0+15],%l7
-+
-+	sll	%l6,8,%l6
-+	or	%l5,%l4,%l4
-+	or	%l7,%l6,%l6
-+	or	%l4,%l6,%o3
-+
-+1:	call	.+8
-+	add	%o7,AES_Te-1b,%o4
-+	call	_sparcv9_AES_encrypt
-+	mov	%i2,%o5
-+
-+	srl	%o0,24,%l0
-+	srl	%o0,16,%l1
-+	stb	%l0,[%i1+0]
-+	srl	%o0,8,%l2
-+	stb	%l1,[%i1+1]
-+	stb	%l2,[%i1+2]
-+	srl	%o1,24,%l4
-+	stb	%o0,[%i1+3]
-+
-+	srl	%o1,16,%l5
-+	stb	%l4,[%i1+4]
-+	srl	%o1,8,%l6
-+	stb	%l5,[%i1+5]
-+	stb	%l6,[%i1+6]
-+	srl	%o2,24,%l0
-+	stb	%o1,[%i1+7]
-+
-+	srl	%o2,16,%l1
-+	stb	%l0,[%i1+8]
-+	srl	%o2,8,%l2
-+	stb	%l1,[%i1+9]
-+	stb	%l2,[%i1+10]
-+	srl	%o3,24,%l4
-+	stb	%o2,[%i1+11]
-+
-+	srl	%o3,16,%l5
-+	stb	%l4,[%i1+12]
-+	srl	%o3,8,%l6
-+	stb	%l5,[%i1+13]
-+	stb	%l6,[%i1+14]
-+	stb	%o3,[%i1+15]
-+
-+	ret
-+	restore
-+.type	AES_encrypt,#function
-+.size	AES_encrypt,(.-AES_encrypt)
-+
-+___
-+
-+$code.=<<___;
-+.align	256
-+AES_Td:
-+___
-+&_data_word(
-+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
-+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
-+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
-+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
-+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
-+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
-+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
-+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
-+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
-+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
-+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
-+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
-+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
-+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
-+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
-+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
-+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
-+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
-+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
-+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
-+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
-+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
-+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
-+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
-+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
-+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
-+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
-+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
-+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
-+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
-+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
-+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
-+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
-+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
-+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
-+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
-+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
-+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
-+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
-+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
-+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
-+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
-+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
-+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
-+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
-+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
-+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
-+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
-+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
-+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
-+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
-+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
-+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
-+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
-+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
-+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
-+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
-+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
-+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
-+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
-+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
-+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
-+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
-+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
-+$code.=<<___;
-+	.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
-+	.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
-+	.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
-+	.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
-+	.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
-+	.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
-+	.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
-+	.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
-+	.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
-+	.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
-+	.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
-+	.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
-+	.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
-+	.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
-+	.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
-+	.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
-+	.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
-+	.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
-+	.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
-+	.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
-+	.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
-+	.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
-+	.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
-+	.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
-+	.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
-+	.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
-+	.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
-+	.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
-+	.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
-+	.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
-+	.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
-+	.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+.type	AES_Td,#object
-+.size	AES_Td,(.-AES_Td)
-+
-+.align	64
-+.skip	16
-+_sparcv9_AES_decrypt:
-+	save	%sp,-$frame-$locals,%sp
-+	stx	%i7,[%sp+$bias+$frame+0]	! off-load return address
-+	ld	[$key+240],$rounds
-+	ld	[$key+0],$t0
-+	ld	[$key+4],$t1			!
-+	ld	[$key+8],$t2
-+	ld	[$key+12],$t3
-+	srl	$rounds,1,$rounds
-+	xor	$t0,$s0,$s0
-+	ld	[$key+16],$t0
-+	xor	$t1,$s1,$s1
-+	ld	[$key+20],$t1
-+	srl	$s0,21,$acc0			!
-+	xor	$t2,$s2,$s2
-+	ld	[$key+24],$t2
-+	xor	$t3,$s3,$s3
-+	and	$acc0,2040,$acc0
-+	ld	[$key+28],$t3
-+	srl	$s3,13,$acc1
-+	nop
-+.Ldec_loop:
-+	srl	$s2,5,$acc2			!
-+	and	$acc1,2040,$acc1
-+	ldx	[$tbl+$acc0],$acc0
-+	sll	$s1,3,$acc3
-+	and	$acc2,2040,$acc2
-+	ldx	[$tbl+$acc1],$acc1
-+	srl	$s1,21,$acc4
-+	and	$acc3,2040,$acc3
-+	ldx	[$tbl+$acc2],$acc2		!
-+	srl	$s0,13,$acc5
-+	and	$acc4,2040,$acc4
-+	ldx	[$tbl+$acc3],$acc3
-+	srl	$s3,5,$acc6
-+	and	$acc5,2040,$acc5
-+	ldx	[$tbl+$acc4],$acc4
-+	fmovs	%f0,%f0
-+	sll	$s2,3,$acc7			!
-+	and	$acc6,2040,$acc6
-+	ldx	[$tbl+$acc5],$acc5
-+	srl	$s2,21,$acc8
-+	and	$acc7,2040,$acc7
-+	ldx	[$tbl+$acc6],$acc6
-+	srl	$s1,13,$acc9
-+	and	$acc8,2040,$acc8
-+	ldx	[$tbl+$acc7],$acc7		!
-+	srl	$s0,5,$acc10
-+	and	$acc9,2040,$acc9
-+	ldx	[$tbl+$acc8],$acc8
-+	sll	$s3,3,$acc11
-+	and	$acc10,2040,$acc10
-+	ldx	[$tbl+$acc9],$acc9
-+	fmovs	%f0,%f0
-+	srl	$s3,21,$acc12			!
-+	and	$acc11,2040,$acc11
-+	ldx	[$tbl+$acc10],$acc10
-+	srl	$s2,13,$acc13
-+	and	$acc12,2040,$acc12
-+	ldx	[$tbl+$acc11],$acc11
-+	srl	$s1,5,$acc14
-+	and	$acc13,2040,$acc13
-+	ldx	[$tbl+$acc12],$acc12		!
-+	sll	$s0,3,$acc15
-+	and	$acc14,2040,$acc14
-+	ldx	[$tbl+$acc13],$acc13
-+	and	$acc15,2040,$acc15
-+	add	$key,32,$key
-+	ldx	[$tbl+$acc14],$acc14
-+	fmovs	%f0,%f0
-+	subcc	$rounds,1,$rounds		!
-+	ldx	[$tbl+$acc15],$acc15
-+	bz,a,pn	%icc,.Ldec_last
-+	add	$tbl,2048,$rounds
-+
-+		srlx	$acc1,8,$acc1
-+		xor	$acc0,$t0,$t0
-+	ld	[$key+0],$s0
-+	fmovs	%f0,%f0
-+		srlx	$acc2,16,$acc2		!
-+		xor	$acc1,$t0,$t0
-+	ld	[$key+4],$s1
-+		srlx	$acc3,24,$acc3
-+		xor	$acc2,$t0,$t0
-+	ld	[$key+8],$s2
-+		srlx	$acc5,8,$acc5
-+		xor	$acc3,$t0,$t0
-+	ld	[$key+12],$s3			!
-+		srlx	$acc6,16,$acc6
-+		xor	$acc4,$t1,$t1
-+	fmovs	%f0,%f0
-+		srlx	$acc7,24,$acc7
-+		xor	$acc5,$t1,$t1
-+		srlx	$acc9,8,$acc9
-+		xor	$acc6,$t1,$t1
-+		srlx	$acc10,16,$acc10	!
-+		xor	$acc7,$t1,$t1
-+		srlx	$acc11,24,$acc11
-+		xor	$acc8,$t2,$t2
-+		srlx	$acc13,8,$acc13
-+		xor	$acc9,$t2,$t2
-+		srlx	$acc14,16,$acc14
-+		xor	$acc10,$t2,$t2
-+		srlx	$acc15,24,$acc15	!
-+		xor	$acc11,$t2,$t2
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$t3,$t3
-+	srl	$t0,21,$acc0
-+		xor	$acc14,$t3,$t3
-+		xor	$acc15,$t3,$t3
-+	srl	$t3,13,$acc1
-+
-+	and	$acc0,2040,$acc0		!
-+	srl	$t2,5,$acc2
-+	and	$acc1,2040,$acc1
-+	ldx	[$tbl+$acc0],$acc0
-+	sll	$t1,3,$acc3
-+	and	$acc2,2040,$acc2
-+	ldx	[$tbl+$acc1],$acc1
-+	fmovs	%f0,%f0
-+	srl	$t1,21,$acc4			!
-+	and	$acc3,2040,$acc3
-+	ldx	[$tbl+$acc2],$acc2
-+	srl	$t0,13,$acc5
-+	and	$acc4,2040,$acc4
-+	ldx	[$tbl+$acc3],$acc3
-+	srl	$t3,5,$acc6
-+	and	$acc5,2040,$acc5
-+	ldx	[$tbl+$acc4],$acc4		!
-+	sll	$t2,3,$acc7
-+	and	$acc6,2040,$acc6
-+	ldx	[$tbl+$acc5],$acc5
-+	srl	$t2,21,$acc8
-+	and	$acc7,2040,$acc7
-+	ldx	[$tbl+$acc6],$acc6
-+	fmovs	%f0,%f0
-+	srl	$t1,13,$acc9			!
-+	and	$acc8,2040,$acc8
-+	ldx	[$tbl+$acc7],$acc7
-+	srl	$t0,5,$acc10
-+	and	$acc9,2040,$acc9
-+	ldx	[$tbl+$acc8],$acc8
-+	sll	$t3,3,$acc11
-+	and	$acc10,2040,$acc10
-+	ldx	[$tbl+$acc9],$acc9		!
-+	srl	$t3,21,$acc12
-+	and	$acc11,2040,$acc11
-+	ldx	[$tbl+$acc10],$acc10
-+	srl	$t2,13,$acc13
-+	and	$acc12,2040,$acc12
-+	ldx	[$tbl+$acc11],$acc11
-+	fmovs	%f0,%f0
-+	srl	$t1,5,$acc14			!
-+	and	$acc13,2040,$acc13
-+	ldx	[$tbl+$acc12],$acc12
-+	sll	$t0,3,$acc15
-+	and	$acc14,2040,$acc14
-+	ldx	[$tbl+$acc13],$acc13
-+		srlx	$acc1,8,$acc1
-+	and	$acc15,2040,$acc15
-+	ldx	[$tbl+$acc14],$acc14		!
-+
-+		srlx	$acc2,16,$acc2
-+		xor	$acc0,$s0,$s0
-+	ldx	[$tbl+$acc15],$acc15
-+		srlx	$acc3,24,$acc3
-+		xor	$acc1,$s0,$s0
-+	ld	[$key+16],$t0
-+	fmovs	%f0,%f0
-+		srlx	$acc5,8,$acc5		!
-+		xor	$acc2,$s0,$s0
-+	ld	[$key+20],$t1
-+		srlx	$acc6,16,$acc6
-+		xor	$acc3,$s0,$s0
-+	ld	[$key+24],$t2
-+		srlx	$acc7,24,$acc7
-+		xor	$acc4,$s1,$s1
-+	ld	[$key+28],$t3			!
-+		srlx	$acc9,8,$acc9
-+		xor	$acc5,$s1,$s1
-+	ldx	[$tbl+2048+0],%g0		! prefetch td4
-+		srlx	$acc10,16,$acc10
-+		xor	$acc6,$s1,$s1
-+	ldx	[$tbl+2048+32],%g0		! prefetch td4
-+		srlx	$acc11,24,$acc11
-+		xor	$acc7,$s1,$s1
-+	ldx	[$tbl+2048+64],%g0		! prefetch td4
-+		srlx	$acc13,8,$acc13
-+		xor	$acc8,$s2,$s2
-+	ldx	[$tbl+2048+96],%g0		! prefetch td4
-+		srlx	$acc14,16,$acc14	!
-+		xor	$acc9,$s2,$s2
-+	ldx	[$tbl+2048+128],%g0		! prefetch td4
-+		srlx	$acc15,24,$acc15
-+		xor	$acc10,$s2,$s2
-+	ldx	[$tbl+2048+160],%g0		! prefetch td4
-+	srl	$s0,21,$acc0
-+		xor	$acc11,$s2,$s2
-+	ldx	[$tbl+2048+192],%g0		! prefetch td4
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$s3,$s3
-+	ldx	[$tbl+2048+224],%g0		! prefetch td4
-+	and	$acc0,2040,$acc0		!
-+		xor	$acc14,$s3,$s3
-+		xor	$acc15,$s3,$s3
-+	ba	.Ldec_loop
-+	srl	$s3,13,$acc1
-+
-+.align	32
-+.Ldec_last:
-+		srlx	$acc1,8,$acc1		!
-+		xor	$acc0,$t0,$t0
-+	ld	[$key+0],$s0
-+		srlx	$acc2,16,$acc2
-+		xor	$acc1,$t0,$t0
-+	ld	[$key+4],$s1
-+		srlx	$acc3,24,$acc3
-+		xor	$acc2,$t0,$t0
-+	ld	[$key+8],$s2			!
-+		srlx	$acc5,8,$acc5
-+		xor	$acc3,$t0,$t0
-+	ld	[$key+12],$s3
-+		srlx	$acc6,16,$acc6
-+		xor	$acc4,$t1,$t1
-+		srlx	$acc7,24,$acc7
-+		xor	$acc5,$t1,$t1
-+		srlx	$acc9,8,$acc9		!
-+		xor	$acc6,$t1,$t1
-+		srlx	$acc10,16,$acc10
-+		xor	$acc7,$t1,$t1
-+		srlx	$acc11,24,$acc11
-+		xor	$acc8,$t2,$t2
-+		srlx	$acc13,8,$acc13
-+		xor	$acc9,$t2,$t2
-+		srlx	$acc14,16,$acc14	!
-+		xor	$acc10,$t2,$t2
-+		srlx	$acc15,24,$acc15
-+		xor	$acc11,$t2,$t2
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$t3,$t3
-+	srl	$t0,24,$acc0
-+		xor	$acc14,$t3,$t3
-+		xor	$acc15,$t3,$t3		!
-+	srl	$t3,16,$acc1
-+
-+	srl	$t2,8,$acc2
-+	and	$acc1,255,$acc1
-+	ldub	[$rounds+$acc0],$acc0
-+	srl	$t1,24,$acc4
-+	and	$acc2,255,$acc2
-+	ldub	[$rounds+$acc1],$acc1
-+	srl	$t0,16,$acc5			!
-+	and	$t1,255,$acc3
-+	ldub	[$rounds+$acc2],$acc2
-+	ldub	[$rounds+$acc3],$acc3
-+	srl	$t3,8,$acc6
-+	and	$acc5,255,$acc5
-+	ldub	[$rounds+$acc4],$acc4
-+	fmovs	%f0,%f0
-+	srl	$t2,24,$acc8			!
-+	and	$acc6,255,$acc6
-+	ldub	[$rounds+$acc5],$acc5
-+	srl	$t1,16,$acc9
-+	and	$t2,255,$acc7
-+	ldub	[$rounds+$acc6],$acc6
-+	ldub	[$rounds+$acc7],$acc7
-+	fmovs	%f0,%f0
-+	srl	$t0,8,$acc10			!
-+	and	$acc9,255,$acc9
-+	ldub	[$rounds+$acc8],$acc8
-+	srl	$t3,24,$acc12
-+	and	$acc10,255,$acc10
-+	ldub	[$rounds+$acc9],$acc9
-+	srl	$t2,16,$acc13
-+	and	$t3,255,$acc11
-+	ldub	[$rounds+$acc10],$acc10		!
-+	srl	$t1,8,$acc14
-+	and	$acc13,255,$acc13
-+	ldub	[$rounds+$acc11],$acc11
-+	ldub	[$rounds+$acc12],$acc12
-+	and	$acc14,255,$acc14
-+	ldub	[$rounds+$acc13],$acc13
-+	and	$t0,255,$acc15
-+	ldub	[$rounds+$acc14],$acc14		!
-+
-+		sll	$acc0,24,$acc0
-+		xor	$acc3,$s0,$s0
-+	ldub	[$rounds+$acc15],$acc15
-+		sll	$acc1,16,$acc1
-+		xor	$acc0,$s0,$s0
-+	ldx	[%sp+$bias+$frame+0],%i7	! restore return address
-+	fmovs	%f0,%f0
-+		sll	$acc2,8,$acc2		!
-+		xor	$acc1,$s0,$s0
-+		sll	$acc4,24,$acc4
-+		xor	$acc2,$s0,$s0
-+		sll	$acc5,16,$acc5
-+		xor	$acc7,$s1,$s1
-+		sll	$acc6,8,$acc6
-+		xor	$acc4,$s1,$s1
-+		sll	$acc8,24,$acc8		!
-+		xor	$acc5,$s1,$s1
-+		sll	$acc9,16,$acc9
-+		xor	$acc11,$s2,$s2
-+		sll	$acc10,8,$acc10
-+		xor	$acc6,$s1,$s1
-+		sll	$acc12,24,$acc12
-+		xor	$acc8,$s2,$s2
-+		sll	$acc13,16,$acc13	!
-+		xor	$acc9,$s2,$s2
-+		sll	$acc14,8,$acc14
-+		xor	$acc10,$s2,$s2
-+		xor	$acc12,$acc14,$acc14
-+		xor	$acc13,$s3,$s3
-+		xor	$acc14,$s3,$s3
-+		xor	$acc15,$s3,$s3
-+
-+	ret
-+	restore
-+.type	_sparcv9_AES_decrypt,#function
-+.size	_sparcv9_AES_decrypt,(.-_sparcv9_AES_decrypt)
-+
-+.align	32
-+.globl	AES_decrypt
-+AES_decrypt:
-+	or	%o0,%o1,%g1
-+	andcc	%g1,3,%g0
-+	bnz,pn	%xcc,.Lunaligned_dec
-+	save	%sp,-$frame,%sp
-+
-+	ld	[%i0+0],%o0
-+	ld	[%i0+4],%o1
-+	ld	[%i0+8],%o2
-+	ld	[%i0+12],%o3
-+
-+1:	call	.+8
-+	add	%o7,AES_Td-1b,%o4
-+	call	_sparcv9_AES_decrypt
-+	mov	%i2,%o5
-+
-+	st	%o0,[%i1+0]
-+	st	%o1,[%i1+4]
-+	st	%o2,[%i1+8]
-+	st	%o3,[%i1+12]
-+
-+	ret
-+	restore
-+
-+.align	32
-+.Lunaligned_dec:
-+	ldub	[%i0+0],%l0
-+	ldub	[%i0+1],%l1
-+	ldub	[%i0+2],%l2
-+
-+	sll	%l0,24,%l0
-+	ldub	[%i0+3],%l3
-+	sll	%l1,16,%l1
-+	ldub	[%i0+4],%l4
-+	sll	%l2,8,%l2
-+	or	%l1,%l0,%l0
-+	ldub	[%i0+5],%l5
-+	sll	%l4,24,%l4
-+	or	%l3,%l2,%l2
-+	ldub	[%i0+6],%l6
-+	sll	%l5,16,%l5
-+	or	%l0,%l2,%o0
-+	ldub	[%i0+7],%l7
-+
-+	sll	%l6,8,%l6
-+	or	%l5,%l4,%l4
-+	ldub	[%i0+8],%l0
-+	or	%l7,%l6,%l6
-+	ldub	[%i0+9],%l1
-+	or	%l4,%l6,%o1
-+	ldub	[%i0+10],%l2
-+
-+	sll	%l0,24,%l0
-+	ldub	[%i0+11],%l3
-+	sll	%l1,16,%l1
-+	ldub	[%i0+12],%l4
-+	sll	%l2,8,%l2
-+	or	%l1,%l0,%l0
-+	ldub	[%i0+13],%l5
-+	sll	%l4,24,%l4
-+	or	%l3,%l2,%l2
-+	ldub	[%i0+14],%l6
-+	sll	%l5,16,%l5
-+	or	%l0,%l2,%o2
-+	ldub	[%i0+15],%l7
-+
-+	sll	%l6,8,%l6
-+	or	%l5,%l4,%l4
-+	or	%l7,%l6,%l6
-+	or	%l4,%l6,%o3
-+
-+1:	call	.+8
-+	add	%o7,AES_Td-1b,%o4
-+	call	_sparcv9_AES_decrypt
-+	mov	%i2,%o5
-+
-+	srl	%o0,24,%l0
-+	srl	%o0,16,%l1
-+	stb	%l0,[%i1+0]
-+	srl	%o0,8,%l2
-+	stb	%l1,[%i1+1]
-+	stb	%l2,[%i1+2]
-+	srl	%o1,24,%l4
-+	stb	%o0,[%i1+3]
-+
-+	srl	%o1,16,%l5
-+	stb	%l4,[%i1+4]
-+	srl	%o1,8,%l6
-+	stb	%l5,[%i1+5]
-+	stb	%l6,[%i1+6]
-+	srl	%o2,24,%l0
-+	stb	%o1,[%i1+7]
-+
-+	srl	%o2,16,%l1
-+	stb	%l0,[%i1+8]
-+	srl	%o2,8,%l2
-+	stb	%l1,[%i1+9]
-+	stb	%l2,[%i1+10]
-+	srl	%o3,24,%l4
-+	stb	%o2,[%i1+11]
-+
-+	srl	%o3,16,%l5
-+	stb	%l4,[%i1+12]
-+	srl	%o3,8,%l6
-+	stb	%l5,[%i1+13]
-+	stb	%l6,[%i1+14]
-+	stb	%o3,[%i1+15]
-+
-+	ret
-+	restore
-+.type	AES_decrypt,#function
-+.size	AES_decrypt,(.-AES_decrypt)
-+___
-+
-+# fmovs instructions substituting for FP nops were originally added
-+# to meet specific instruction alignment requirements to maximize ILP.
-+# As UltraSPARC T1, a.k.a. Niagara, has shared FPU, FP nops can have
-+# undesired effect, so just omit them and sacrifice some portion of
-+# percent in performance...
-+$code =~ s/fmovs.*$//gm;
-+
-+print $code;
-+close STDOUT;	# ensure flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-x86_64.pl
-new file mode 100755
-index 0000000..ce4ca30
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aes-x86_64.pl
-@@ -0,0 +1,2820 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# Version 2.1.
-+#
-+# aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on
-+# Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version
-+# [you'll notice a lot of resemblance], such as compressed S-boxes
-+# in little-endian byte order, prefetch of these tables in CBC mode,
-+# as well as avoiding L1 cache aliasing between stack frame and key
-+# schedule and already mentioned tables, compressed Td4...
-+#
-+# Performance in number of cycles per processed byte for 128-bit key:
-+#
-+#		ECB encrypt	ECB decrypt	CBC large chunk
-+# AMD64		33		43		13.0
-+# EM64T		38		56		18.6(*)
-+# Core 2	30		42		14.5(*)
-+# Atom		65		86		32.1(*)
-+#
-+# (*) with hyper-threading off
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+$verticalspin=1;	# unlike 32-bit version $verticalspin performs
-+			# ~15% better on both AMD and Intel cores
-+$speed_limit=512;	# see aes-586.pl for details
-+
-+$code=".text\n";
-+
-+$s0="%eax";
-+$s1="%ebx";
-+$s2="%ecx";
-+$s3="%edx";
-+$acc0="%esi";	$mask80="%rsi";
-+$acc1="%edi";	$maskfe="%rdi";
-+$acc2="%ebp";	$mask1b="%rbp";
-+$inp="%r8";
-+$out="%r9";
-+$t0="%r10d";
-+$t1="%r11d";
-+$t2="%r12d";
-+$rnds="%r13d";
-+$sbox="%r14";
-+$key="%r15";
-+
-+sub hi() { my $r=shift;	$r =~ s/%[er]([a-d])x/%\1h/;	$r; }
-+sub lo() { my $r=shift;	$r =~ s/%[er]([a-d])x/%\1l/;
-+			$r =~ s/%[er]([sd]i)/%\1l/;
-+			$r =~ s/%(r[0-9]+)[d]?/%\1b/;	$r; }
-+sub LO() { my $r=shift; $r =~ s/%r([a-z]+)/%e\1/;
-+			$r =~ s/%r([0-9]+)/%r\1d/;	$r; }
-+sub _data_word()
-+{ my $i;
-+    while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
-+}
-+sub data_word()
-+{ my $i;
-+  my $last=pop(@_);
-+    $code.=".long\t";
-+    while(defined($i=shift)) { $code.=sprintf"0x%08x,",$i; }
-+    $code.=sprintf"0x%08x\n",$last;
-+}
-+
-+sub data_byte()
-+{ my $i;
-+  my $last=pop(@_);
-+    $code.=".byte\t";
-+    while(defined($i=shift)) { $code.=sprintf"0x%02x,",$i&0xff; }
-+    $code.=sprintf"0x%02x\n",$last&0xff;
-+}
-+
-+sub encvert()
-+{ my $t3="%r8d";	# zaps $inp!
-+
-+$code.=<<___;
-+	# favor 3-way issue Opteron pipeline...
-+	movzb	`&lo("$s0")`,$acc0
-+	movzb	`&lo("$s1")`,$acc1
-+	movzb	`&lo("$s2")`,$acc2
-+	mov	0($sbox,$acc0,8),$t0
-+	mov	0($sbox,$acc1,8),$t1
-+	mov	0($sbox,$acc2,8),$t2
-+
-+	movzb	`&hi("$s1")`,$acc0
-+	movzb	`&hi("$s2")`,$acc1
-+	movzb	`&lo("$s3")`,$acc2
-+	xor	3($sbox,$acc0,8),$t0
-+	xor	3($sbox,$acc1,8),$t1
-+	mov	0($sbox,$acc2,8),$t3
-+
-+	movzb	`&hi("$s3")`,$acc0
-+	shr	\$16,$s2
-+	movzb	`&hi("$s0")`,$acc2
-+	xor	3($sbox,$acc0,8),$t2
-+	shr	\$16,$s3
-+	xor	3($sbox,$acc2,8),$t3
-+
-+	shr	\$16,$s1
-+	lea	16($key),$key
-+	shr	\$16,$s0
-+
-+	movzb	`&lo("$s2")`,$acc0
-+	movzb	`&lo("$s3")`,$acc1
-+	movzb	`&lo("$s0")`,$acc2
-+	xor	2($sbox,$acc0,8),$t0
-+	xor	2($sbox,$acc1,8),$t1
-+	xor	2($sbox,$acc2,8),$t2
-+
-+	movzb	`&hi("$s3")`,$acc0
-+	movzb	`&hi("$s0")`,$acc1
-+	movzb	`&lo("$s1")`,$acc2
-+	xor	1($sbox,$acc0,8),$t0
-+	xor	1($sbox,$acc1,8),$t1
-+	xor	2($sbox,$acc2,8),$t3
-+
-+	mov	12($key),$s3
-+	movzb	`&hi("$s1")`,$acc1
-+	movzb	`&hi("$s2")`,$acc2
-+	mov	0($key),$s0
-+	xor	1($sbox,$acc1,8),$t2
-+	xor	1($sbox,$acc2,8),$t3
-+
-+	mov	4($key),$s1
-+	mov	8($key),$s2
-+	xor	$t0,$s0
-+	xor	$t1,$s1
-+	xor	$t2,$s2
-+	xor	$t3,$s3
-+___
-+}
-+
-+sub enclastvert()
-+{ my $t3="%r8d";	# zaps $inp!
-+
-+$code.=<<___;
-+	movzb	`&lo("$s0")`,$acc0
-+	movzb	`&lo("$s1")`,$acc1
-+	movzb	`&lo("$s2")`,$acc2
-+	movzb	2($sbox,$acc0,8),$t0
-+	movzb	2($sbox,$acc1,8),$t1
-+	movzb	2($sbox,$acc2,8),$t2
-+
-+	movzb	`&lo("$s3")`,$acc0
-+	movzb	`&hi("$s1")`,$acc1
-+	movzb	`&hi("$s2")`,$acc2
-+	movzb	2($sbox,$acc0,8),$t3
-+	mov	0($sbox,$acc1,8),$acc1	#$t0
-+	mov	0($sbox,$acc2,8),$acc2	#$t1
-+
-+	and	\$0x0000ff00,$acc1
-+	and	\$0x0000ff00,$acc2
-+
-+	xor	$acc1,$t0
-+	xor	$acc2,$t1
-+	shr	\$16,$s2
-+
-+	movzb	`&hi("$s3")`,$acc0
-+	movzb	`&hi("$s0")`,$acc1
-+	shr	\$16,$s3
-+	mov	0($sbox,$acc0,8),$acc0	#$t2
-+	mov	0($sbox,$acc1,8),$acc1	#$t3
-+
-+	and	\$0x0000ff00,$acc0
-+	and	\$0x0000ff00,$acc1
-+	shr	\$16,$s1
-+	xor	$acc0,$t2
-+	xor	$acc1,$t3
-+	shr	\$16,$s0
-+
-+	movzb	`&lo("$s2")`,$acc0
-+	movzb	`&lo("$s3")`,$acc1
-+	movzb	`&lo("$s0")`,$acc2
-+	mov	0($sbox,$acc0,8),$acc0	#$t0
-+	mov	0($sbox,$acc1,8),$acc1	#$t1
-+	mov	0($sbox,$acc2,8),$acc2	#$t2
-+
-+	and	\$0x00ff0000,$acc0
-+	and	\$0x00ff0000,$acc1
-+	and	\$0x00ff0000,$acc2
-+
-+	xor	$acc0,$t0
-+	xor	$acc1,$t1
-+	xor	$acc2,$t2
-+
-+	movzb	`&lo("$s1")`,$acc0
-+	movzb	`&hi("$s3")`,$acc1
-+	movzb	`&hi("$s0")`,$acc2
-+	mov	0($sbox,$acc0,8),$acc0	#$t3
-+	mov	2($sbox,$acc1,8),$acc1	#$t0
-+	mov	2($sbox,$acc2,8),$acc2	#$t1
-+
-+	and	\$0x00ff0000,$acc0
-+	and	\$0xff000000,$acc1
-+	and	\$0xff000000,$acc2
-+
-+	xor	$acc0,$t3
-+	xor	$acc1,$t0
-+	xor	$acc2,$t1
-+
-+	movzb	`&hi("$s1")`,$acc0
-+	movzb	`&hi("$s2")`,$acc1
-+	mov	16+12($key),$s3
-+	mov	2($sbox,$acc0,8),$acc0	#$t2
-+	mov	2($sbox,$acc1,8),$acc1	#$t3
-+	mov	16+0($key),$s0
-+
-+	and	\$0xff000000,$acc0
-+	and	\$0xff000000,$acc1
-+
-+	xor	$acc0,$t2
-+	xor	$acc1,$t3
-+
-+	mov	16+4($key),$s1
-+	mov	16+8($key),$s2
-+	xor	$t0,$s0
-+	xor	$t1,$s1
-+	xor	$t2,$s2
-+	xor	$t3,$s3
-+___
-+}
-+
-+sub encstep()
-+{ my ($i,@s) = @_;
-+  my $tmp0=$acc0;
-+  my $tmp1=$acc1;
-+  my $tmp2=$acc2;
-+  my $out=($t0,$t1,$t2,$s[0])[$i];
-+
-+	if ($i==3) {
-+		$tmp0=$s[1];
-+		$tmp1=$s[2];
-+		$tmp2=$s[3];
-+	}
-+	$code.="	movzb	".&lo($s[0]).",$out\n";
-+	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
-+	$code.="	lea	16($key),$key\n"	if ($i==0);
-+
-+	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
-+	$code.="	mov	0($sbox,$out,8),$out\n";
-+
-+	$code.="	shr	\$16,$tmp1\n";
-+	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
-+	$code.="	xor	3($sbox,$tmp0,8),$out\n";
-+
-+	$code.="	movzb	".&lo($tmp1).",$tmp1\n";
-+	$code.="	shr	\$24,$tmp2\n";
-+	$code.="	xor	4*$i($key),$out\n";
-+
-+	$code.="	xor	2($sbox,$tmp1,8),$out\n";
-+	$code.="	xor	1($sbox,$tmp2,8),$out\n";
-+
-+	$code.="	mov	$t0,$s[1]\n"		if ($i==3);
-+	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
-+	$code.="	mov	$t2,$s[3]\n"		if ($i==3);
-+	$code.="\n";
-+}
-+
-+sub enclast()
-+{ my ($i,@s)=@_;
-+  my $tmp0=$acc0;
-+  my $tmp1=$acc1;
-+  my $tmp2=$acc2;
-+  my $out=($t0,$t1,$t2,$s[0])[$i];
-+
-+	if ($i==3) {
-+		$tmp0=$s[1];
-+		$tmp1=$s[2];
-+		$tmp2=$s[3];
-+	}
-+	$code.="	movzb	".&lo($s[0]).",$out\n";
-+	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
-+
-+	$code.="	mov	2($sbox,$out,8),$out\n";
-+	$code.="	shr	\$16,$tmp1\n";
-+	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
-+
-+	$code.="	and	\$0x000000ff,$out\n";
-+	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
-+	$code.="	movzb	".&lo($tmp1).",$tmp1\n";
-+	$code.="	shr	\$24,$tmp2\n";
-+
-+	$code.="	mov	0($sbox,$tmp0,8),$tmp0\n";
-+	$code.="	mov	0($sbox,$tmp1,8),$tmp1\n";
-+	$code.="	mov	2($sbox,$tmp2,8),$tmp2\n";
-+
-+	$code.="	and	\$0x0000ff00,$tmp0\n";
-+	$code.="	and	\$0x00ff0000,$tmp1\n";
-+	$code.="	and	\$0xff000000,$tmp2\n";
-+
-+	$code.="	xor	$tmp0,$out\n";
-+	$code.="	mov	$t0,$s[1]\n"		if ($i==3);
-+	$code.="	xor	$tmp1,$out\n";
-+	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
-+	$code.="	xor	$tmp2,$out\n";
-+	$code.="	mov	$t2,$s[3]\n"		if ($i==3);
-+	$code.="\n";
-+}
-+
-+$code.=<<___;
-+.type	_x86_64_AES_encrypt,\@abi-omnipotent
-+.align	16
-+_x86_64_AES_encrypt:
-+	xor	0($key),$s0			# xor with key
-+	xor	4($key),$s1
-+	xor	8($key),$s2
-+	xor	12($key),$s3
-+
-+	mov	240($key),$rnds			# load key->rounds
-+	sub	\$1,$rnds
-+	jmp	.Lenc_loop
-+.align	16
-+.Lenc_loop:
-+___
-+	if ($verticalspin) { &encvert(); }
-+	else {	&encstep(0,$s0,$s1,$s2,$s3);
-+		&encstep(1,$s1,$s2,$s3,$s0);
-+		&encstep(2,$s2,$s3,$s0,$s1);
-+		&encstep(3,$s3,$s0,$s1,$s2);
-+	}
-+$code.=<<___;
-+	sub	\$1,$rnds
-+	jnz	.Lenc_loop
-+___
-+	if ($verticalspin) { &enclastvert(); }
-+	else {	&enclast(0,$s0,$s1,$s2,$s3);
-+		&enclast(1,$s1,$s2,$s3,$s0);
-+		&enclast(2,$s2,$s3,$s0,$s1);
-+		&enclast(3,$s3,$s0,$s1,$s2);
-+		$code.=<<___;
-+		xor	16+0($key),$s0		# xor with key
-+		xor	16+4($key),$s1
-+		xor	16+8($key),$s2
-+		xor	16+12($key),$s3
-+___
-+	}
-+$code.=<<___;
-+	.byte	0xf3,0xc3			# rep ret
-+.size	_x86_64_AES_encrypt,.-_x86_64_AES_encrypt
-+___
-+
-+# it's possible to implement this by shifting tN by 8, filling least
-+# significant byte with byte load and finally bswap-ing at the end,
-+# but such partial register load kills Core 2...
-+sub enccompactvert()
-+{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
-+
-+$code.=<<___;
-+	movzb	`&lo("$s0")`,$t0
-+	movzb	`&lo("$s1")`,$t1
-+	movzb	`&lo("$s2")`,$t2
-+	movzb	`&lo("$s3")`,$t3
-+	movzb	`&hi("$s1")`,$acc0
-+	movzb	`&hi("$s2")`,$acc1
-+	shr	\$16,$s2
-+	movzb	`&hi("$s3")`,$acc2
-+	movzb	($sbox,$t0,1),$t0
-+	movzb	($sbox,$t1,1),$t1
-+	movzb	($sbox,$t2,1),$t2
-+	movzb	($sbox,$t3,1),$t3
-+
-+	movzb	($sbox,$acc0,1),$t4	#$t0
-+	movzb	`&hi("$s0")`,$acc0
-+	movzb	($sbox,$acc1,1),$t5	#$t1
-+	movzb	`&lo("$s2")`,$acc1
-+	movzb	($sbox,$acc2,1),$acc2	#$t2
-+	movzb	($sbox,$acc0,1),$acc0	#$t3
-+
-+	shl	\$8,$t4
-+	shr	\$16,$s3
-+	shl	\$8,$t5
-+	xor	$t4,$t0
-+	shr	\$16,$s0
-+	movzb	`&lo("$s3")`,$t4
-+	shr	\$16,$s1
-+	xor	$t5,$t1
-+	shl	\$8,$acc2
-+	movzb	`&lo("$s0")`,$t5
-+	movzb	($sbox,$acc1,1),$acc1	#$t0
-+	xor	$acc2,$t2
-+
-+	shl	\$8,$acc0
-+	movzb	`&lo("$s1")`,$acc2
-+	shl	\$16,$acc1
-+	xor	$acc0,$t3
-+	movzb	($sbox,$t4,1),$t4	#$t1
-+	movzb	`&hi("$s3")`,$acc0
-+	movzb	($sbox,$t5,1),$t5	#$t2
-+	xor	$acc1,$t0
-+
-+	shr	\$8,$s2
-+	movzb	`&hi("$s0")`,$acc1
-+	shl	\$16,$t4
-+	shr	\$8,$s1
-+	shl	\$16,$t5
-+	xor	$t4,$t1
-+	movzb	($sbox,$acc2,1),$acc2	#$t3
-+	movzb	($sbox,$acc0,1),$acc0	#$t0
-+	movzb	($sbox,$acc1,1),$acc1	#$t1
-+	movzb	($sbox,$s2,1),$s3	#$t3
-+	movzb	($sbox,$s1,1),$s2	#$t2
-+
-+	shl	\$16,$acc2
-+	xor	$t5,$t2
-+	shl	\$24,$acc0
-+	xor	$acc2,$t3
-+	shl	\$24,$acc1
-+	xor	$acc0,$t0
-+	shl	\$24,$s3
-+	xor	$acc1,$t1
-+	shl	\$24,$s2
-+	mov	$t0,$s0
-+	mov	$t1,$s1
-+	xor	$t2,$s2
-+	xor	$t3,$s3
-+___
-+}
-+
-+sub enctransform_ref()
-+{ my $sn = shift;
-+  my ($acc,$r2,$tmp)=("%r8d","%r9d","%r13d");
-+
-+$code.=<<___;
-+	mov	$sn,$acc
-+	and	\$0x80808080,$acc
-+	mov	$acc,$tmp
-+	shr	\$7,$tmp
-+	lea	($sn,$sn),$r2
-+	sub	$tmp,$acc
-+	and	\$0xfefefefe,$r2
-+	and	\$0x1b1b1b1b,$acc
-+	mov	$sn,$tmp
-+	xor	$acc,$r2
-+
-+	xor	$r2,$sn
-+	rol	\$24,$sn
-+	xor	$r2,$sn
-+	ror	\$16,$tmp
-+	xor	$tmp,$sn
-+	ror	\$8,$tmp
-+	xor	$tmp,$sn
-+___
-+}
-+
-+# unlike decrypt case it does not pay off to parallelize enctransform
-+sub enctransform()
-+{ my ($t3,$r20,$r21)=($acc2,"%r8d","%r9d");
-+
-+$code.=<<___;
-+	mov	\$0x80808080,$t0
-+	mov	\$0x80808080,$t1
-+	and	$s0,$t0
-+	and	$s1,$t1
-+	mov	$t0,$acc0
-+	mov	$t1,$acc1
-+	shr	\$7,$t0
-+	lea	($s0,$s0),$r20
-+	shr	\$7,$t1
-+	lea	($s1,$s1),$r21
-+	sub	$t0,$acc0
-+	sub	$t1,$acc1
-+	and	\$0xfefefefe,$r20
-+	and	\$0xfefefefe,$r21
-+	and	\$0x1b1b1b1b,$acc0
-+	and	\$0x1b1b1b1b,$acc1
-+	mov	$s0,$t0
-+	mov	$s1,$t1
-+	xor	$acc0,$r20
-+	xor	$acc1,$r21
-+
-+	xor	$r20,$s0
-+	xor	$r21,$s1
-+	 mov	\$0x80808080,$t2
-+	rol	\$24,$s0
-+	 mov	\$0x80808080,$t3
-+	rol	\$24,$s1
-+	 and	$s2,$t2
-+	 and	$s3,$t3
-+	xor	$r20,$s0
-+	xor	$r21,$s1
-+	 mov	$t2,$acc0
-+	ror	\$16,$t0
-+	 mov	$t3,$acc1
-+	ror	\$16,$t1
-+	 lea	($s2,$s2),$r20
-+	 shr	\$7,$t2
-+	xor	$t0,$s0
-+	 shr	\$7,$t3
-+	xor	$t1,$s1
-+	ror	\$8,$t0
-+	 lea	($s3,$s3),$r21
-+	ror	\$8,$t1
-+	 sub	$t2,$acc0
-+	 sub	$t3,$acc1
-+	xor	$t0,$s0
-+	xor	$t1,$s1
-+
-+	and	\$0xfefefefe,$r20
-+	and	\$0xfefefefe,$r21
-+	and	\$0x1b1b1b1b,$acc0
-+	and	\$0x1b1b1b1b,$acc1
-+	mov	$s2,$t2
-+	mov	$s3,$t3
-+	xor	$acc0,$r20
-+	xor	$acc1,$r21
-+
-+	ror	\$16,$t2
-+	xor	$r20,$s2
-+	ror	\$16,$t3
-+	xor	$r21,$s3
-+	rol	\$24,$s2
-+	mov	0($sbox),$acc0			# prefetch Te4
-+	rol	\$24,$s3
-+	xor	$r20,$s2
-+	mov	64($sbox),$acc1
-+	xor	$r21,$s3
-+	mov	128($sbox),$r20
-+	xor	$t2,$s2
-+	ror	\$8,$t2
-+	xor	$t3,$s3
-+	ror	\$8,$t3
-+	xor	$t2,$s2
-+	mov	192($sbox),$r21
-+	xor	$t3,$s3
-+___
-+}
-+
-+$code.=<<___;
-+.type	_x86_64_AES_encrypt_compact,\@abi-omnipotent
-+.align	16
-+_x86_64_AES_encrypt_compact:
-+	lea	128($sbox),$inp			# size optimization
-+	mov	0-128($inp),$acc1		# prefetch Te4
-+	mov	32-128($inp),$acc2
-+	mov	64-128($inp),$t0
-+	mov	96-128($inp),$t1
-+	mov	128-128($inp),$acc1
-+	mov	160-128($inp),$acc2
-+	mov	192-128($inp),$t0
-+	mov	224-128($inp),$t1
-+	jmp	.Lenc_loop_compact
-+.align	16
-+.Lenc_loop_compact:
-+		xor	0($key),$s0		# xor with key
-+		xor	4($key),$s1
-+		xor	8($key),$s2
-+		xor	12($key),$s3
-+		lea	16($key),$key
-+___
-+		&enccompactvert();
-+$code.=<<___;
-+		cmp	16(%rsp),$key
-+		je	.Lenc_compact_done
-+___
-+		&enctransform();
-+$code.=<<___;
-+	jmp	.Lenc_loop_compact
-+.align	16
-+.Lenc_compact_done:
-+	xor	0($key),$s0
-+	xor	4($key),$s1
-+	xor	8($key),$s2
-+	xor	12($key),$s3
-+	.byte	0xf3,0xc3			# rep ret
-+.size	_x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact
-+___
-+
-+# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
-+$code.=<<___;
-+.globl	AES_encrypt
-+.type	AES_encrypt,\@function,3
-+.align	16
-+.globl	asm_AES_encrypt
-+.hidden	asm_AES_encrypt
-+asm_AES_encrypt:
-+AES_encrypt:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	# allocate frame "above" key schedule
-+	mov	%rsp,%r10
-+	lea	-63(%rdx),%rcx	# %rdx is key argument
-+	and	\$-64,%rsp
-+	sub	%rsp,%rcx
-+	neg	%rcx
-+	and	\$0x3c0,%rcx
-+	sub	%rcx,%rsp
-+	sub	\$32,%rsp
-+
-+	mov	%rsi,16(%rsp)	# save out
-+	mov	%r10,24(%rsp)	# save real stack pointer
-+.Lenc_prologue:
-+
-+	mov	%rdx,$key
-+	mov	240($key),$rnds	# load rounds
-+
-+	mov	0(%rdi),$s0	# load input vector
-+	mov	4(%rdi),$s1
-+	mov	8(%rdi),$s2
-+	mov	12(%rdi),$s3
-+
-+	shl	\$4,$rnds
-+	lea	($key,$rnds),%rbp
-+	mov	$key,(%rsp)	# key schedule
-+	mov	%rbp,8(%rsp)	# end of key schedule
-+
-+	# pick Te4 copy which can't "overlap" with stack frame or key schedule
-+	lea	.LAES_Te+2048(%rip),$sbox
-+	lea	768(%rsp),%rbp
-+	sub	$sbox,%rbp
-+	and	\$0x300,%rbp
-+	lea	($sbox,%rbp),$sbox
-+
-+	call	_x86_64_AES_encrypt_compact
-+
-+	mov	16(%rsp),$out	# restore out
-+	mov	24(%rsp),%rsi	# restore saved stack pointer
-+	mov	$s0,0($out)	# write output vector
-+	mov	$s1,4($out)
-+	mov	$s2,8($out)
-+	mov	$s3,12($out)
-+
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lenc_epilogue:
-+	ret
-+.size	AES_encrypt,.-AES_encrypt
-+___
-+
-+#------------------------------------------------------------------#
-+
-+sub decvert()
-+{ my $t3="%r8d";	# zaps $inp!
-+
-+$code.=<<___;
-+	# favor 3-way issue Opteron pipeline...
-+	movzb	`&lo("$s0")`,$acc0
-+	movzb	`&lo("$s1")`,$acc1
-+	movzb	`&lo("$s2")`,$acc2
-+	mov	0($sbox,$acc0,8),$t0
-+	mov	0($sbox,$acc1,8),$t1
-+	mov	0($sbox,$acc2,8),$t2
-+
-+	movzb	`&hi("$s3")`,$acc0
-+	movzb	`&hi("$s0")`,$acc1
-+	movzb	`&lo("$s3")`,$acc2
-+	xor	3($sbox,$acc0,8),$t0
-+	xor	3($sbox,$acc1,8),$t1
-+	mov	0($sbox,$acc2,8),$t3
-+
-+	movzb	`&hi("$s1")`,$acc0
-+	shr	\$16,$s0
-+	movzb	`&hi("$s2")`,$acc2
-+	xor	3($sbox,$acc0,8),$t2
-+	shr	\$16,$s3
-+	xor	3($sbox,$acc2,8),$t3
-+
-+	shr	\$16,$s1
-+	lea	16($key),$key
-+	shr	\$16,$s2
-+
-+	movzb	`&lo("$s2")`,$acc0
-+	movzb	`&lo("$s3")`,$acc1
-+	movzb	`&lo("$s0")`,$acc2
-+	xor	2($sbox,$acc0,8),$t0
-+	xor	2($sbox,$acc1,8),$t1
-+	xor	2($sbox,$acc2,8),$t2
-+
-+	movzb	`&hi("$s1")`,$acc0
-+	movzb	`&hi("$s2")`,$acc1
-+	movzb	`&lo("$s1")`,$acc2
-+	xor	1($sbox,$acc0,8),$t0
-+	xor	1($sbox,$acc1,8),$t1
-+	xor	2($sbox,$acc2,8),$t3
-+
-+	movzb	`&hi("$s3")`,$acc0
-+	mov	12($key),$s3
-+	movzb	`&hi("$s0")`,$acc2
-+	xor	1($sbox,$acc0,8),$t2
-+	mov	0($key),$s0
-+	xor	1($sbox,$acc2,8),$t3
-+
-+	xor	$t0,$s0
-+	mov	4($key),$s1
-+	mov	8($key),$s2
-+	xor	$t2,$s2
-+	xor	$t1,$s1
-+	xor	$t3,$s3
-+___
-+}
-+
-+sub declastvert()
-+{ my $t3="%r8d";	# zaps $inp!
-+
-+$code.=<<___;
-+	lea	2048($sbox),$sbox	# size optimization
-+	movzb	`&lo("$s0")`,$acc0
-+	movzb	`&lo("$s1")`,$acc1
-+	movzb	`&lo("$s2")`,$acc2
-+	movzb	($sbox,$acc0,1),$t0
-+	movzb	($sbox,$acc1,1),$t1
-+	movzb	($sbox,$acc2,1),$t2
-+
-+	movzb	`&lo("$s3")`,$acc0
-+	movzb	`&hi("$s3")`,$acc1
-+	movzb	`&hi("$s0")`,$acc2
-+	movzb	($sbox,$acc0,1),$t3
-+	movzb	($sbox,$acc1,1),$acc1	#$t0
-+	movzb	($sbox,$acc2,1),$acc2	#$t1
-+
-+	shl	\$8,$acc1
-+	shl	\$8,$acc2
-+
-+	xor	$acc1,$t0
-+	xor	$acc2,$t1
-+	shr	\$16,$s3
-+
-+	movzb	`&hi("$s1")`,$acc0
-+	movzb	`&hi("$s2")`,$acc1
-+	shr	\$16,$s0
-+	movzb	($sbox,$acc0,1),$acc0	#$t2
-+	movzb	($sbox,$acc1,1),$acc1	#$t3
-+
-+	shl	\$8,$acc0
-+	shl	\$8,$acc1
-+	shr	\$16,$s1
-+	xor	$acc0,$t2
-+	xor	$acc1,$t3
-+	shr	\$16,$s2
-+
-+	movzb	`&lo("$s2")`,$acc0
-+	movzb	`&lo("$s3")`,$acc1
-+	movzb	`&lo("$s0")`,$acc2
-+	movzb	($sbox,$acc0,1),$acc0	#$t0
-+	movzb	($sbox,$acc1,1),$acc1	#$t1
-+	movzb	($sbox,$acc2,1),$acc2	#$t2
-+
-+	shl	\$16,$acc0
-+	shl	\$16,$acc1
-+	shl	\$16,$acc2
-+
-+	xor	$acc0,$t0
-+	xor	$acc1,$t1
-+	xor	$acc2,$t2
-+
-+	movzb	`&lo("$s1")`,$acc0
-+	movzb	`&hi("$s1")`,$acc1
-+	movzb	`&hi("$s2")`,$acc2
-+	movzb	($sbox,$acc0,1),$acc0	#$t3
-+	movzb	($sbox,$acc1,1),$acc1	#$t0
-+	movzb	($sbox,$acc2,1),$acc2	#$t1
-+
-+	shl	\$16,$acc0
-+	shl	\$24,$acc1
-+	shl	\$24,$acc2
-+
-+	xor	$acc0,$t3
-+	xor	$acc1,$t0
-+	xor	$acc2,$t1
-+
-+	movzb	`&hi("$s3")`,$acc0
-+	movzb	`&hi("$s0")`,$acc1
-+	mov	16+12($key),$s3
-+	movzb	($sbox,$acc0,1),$acc0	#$t2
-+	movzb	($sbox,$acc1,1),$acc1	#$t3
-+	mov	16+0($key),$s0
-+
-+	shl	\$24,$acc0
-+	shl	\$24,$acc1
-+
-+	xor	$acc0,$t2
-+	xor	$acc1,$t3
-+
-+	mov	16+4($key),$s1
-+	mov	16+8($key),$s2
-+	lea	-2048($sbox),$sbox
-+	xor	$t0,$s0
-+	xor	$t1,$s1
-+	xor	$t2,$s2
-+	xor	$t3,$s3
-+___
-+}
-+
-+sub decstep()
-+{ my ($i,@s) = @_;
-+  my $tmp0=$acc0;
-+  my $tmp1=$acc1;
-+  my $tmp2=$acc2;
-+  my $out=($t0,$t1,$t2,$s[0])[$i];
-+
-+	$code.="	mov	$s[0],$out\n"		if ($i!=3);
-+			$tmp1=$s[2]			if ($i==3);
-+	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
-+	$code.="	and	\$0xFF,$out\n";
-+
-+	$code.="	mov	0($sbox,$out,8),$out\n";
-+	$code.="	shr	\$16,$tmp1\n";
-+			$tmp2=$s[3]			if ($i==3);
-+	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
-+
-+			$tmp0=$s[1]			if ($i==3);
-+	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
-+	$code.="	and	\$0xFF,$tmp1\n";
-+	$code.="	shr	\$24,$tmp2\n";
-+
-+	$code.="	xor	3($sbox,$tmp0,8),$out\n";
-+	$code.="	xor	2($sbox,$tmp1,8),$out\n";
-+	$code.="	xor	1($sbox,$tmp2,8),$out\n";
-+
-+	$code.="	mov	$t2,$s[1]\n"		if ($i==3);
-+	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
-+	$code.="	mov	$t0,$s[3]\n"		if ($i==3);
-+	$code.="\n";
-+}
-+
-+sub declast()
-+{ my ($i,@s)=@_;
-+  my $tmp0=$acc0;
-+  my $tmp1=$acc1;
-+  my $tmp2=$acc2;
-+  my $out=($t0,$t1,$t2,$s[0])[$i];
-+
-+	$code.="	mov	$s[0],$out\n"		if ($i!=3);
-+			$tmp1=$s[2]			if ($i==3);
-+	$code.="	mov	$s[2],$tmp1\n"		if ($i!=3);
-+	$code.="	and	\$0xFF,$out\n";
-+
-+	$code.="	movzb	2048($sbox,$out,1),$out\n";
-+	$code.="	shr	\$16,$tmp1\n";
-+			$tmp2=$s[3]			if ($i==3);
-+	$code.="	mov	$s[3],$tmp2\n"		if ($i!=3);
-+
-+			$tmp0=$s[1]			if ($i==3);
-+	$code.="	movzb	".&hi($s[1]).",$tmp0\n";
-+	$code.="	and	\$0xFF,$tmp1\n";
-+	$code.="	shr	\$24,$tmp2\n";
-+
-+	$code.="	movzb	2048($sbox,$tmp0,1),$tmp0\n";
-+	$code.="	movzb	2048($sbox,$tmp1,1),$tmp1\n";
-+	$code.="	movzb	2048($sbox,$tmp2,1),$tmp2\n";
-+
-+	$code.="	shl	\$8,$tmp0\n";
-+	$code.="	shl	\$16,$tmp1\n";
-+	$code.="	shl	\$24,$tmp2\n";
-+
-+	$code.="	xor	$tmp0,$out\n";
-+	$code.="	mov	$t2,$s[1]\n"		if ($i==3);
-+	$code.="	xor	$tmp1,$out\n";
-+	$code.="	mov	$t1,$s[2]\n"		if ($i==3);
-+	$code.="	xor	$tmp2,$out\n";
-+	$code.="	mov	$t0,$s[3]\n"		if ($i==3);
-+	$code.="\n";
-+}
-+
-+$code.=<<___;
-+.type	_x86_64_AES_decrypt,\@abi-omnipotent
-+.align	16
-+_x86_64_AES_decrypt:
-+	xor	0($key),$s0			# xor with key
-+	xor	4($key),$s1
-+	xor	8($key),$s2
-+	xor	12($key),$s3
-+
-+	mov	240($key),$rnds			# load key->rounds
-+	sub	\$1,$rnds
-+	jmp	.Ldec_loop
-+.align	16
-+.Ldec_loop:
-+___
-+	if ($verticalspin) { &decvert(); }
-+	else {	&decstep(0,$s0,$s3,$s2,$s1);
-+		&decstep(1,$s1,$s0,$s3,$s2);
-+		&decstep(2,$s2,$s1,$s0,$s3);
-+		&decstep(3,$s3,$s2,$s1,$s0);
-+		$code.=<<___;
-+		lea	16($key),$key
-+		xor	0($key),$s0			# xor with key
-+		xor	4($key),$s1
-+		xor	8($key),$s2
-+		xor	12($key),$s3
-+___
-+	}
-+$code.=<<___;
-+	sub	\$1,$rnds
-+	jnz	.Ldec_loop
-+___
-+	if ($verticalspin) { &declastvert(); }
-+	else {	&declast(0,$s0,$s3,$s2,$s1);
-+		&declast(1,$s1,$s0,$s3,$s2);
-+		&declast(2,$s2,$s1,$s0,$s3);
-+		&declast(3,$s3,$s2,$s1,$s0);
-+		$code.=<<___;
-+		xor	16+0($key),$s0			# xor with key
-+		xor	16+4($key),$s1
-+		xor	16+8($key),$s2
-+		xor	16+12($key),$s3
-+___
-+	}
-+$code.=<<___;
-+	.byte	0xf3,0xc3			# rep ret
-+.size	_x86_64_AES_decrypt,.-_x86_64_AES_decrypt
-+___
-+
-+sub deccompactvert()
-+{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d");
-+
-+$code.=<<___;
-+	movzb	`&lo("$s0")`,$t0
-+	movzb	`&lo("$s1")`,$t1
-+	movzb	`&lo("$s2")`,$t2
-+	movzb	`&lo("$s3")`,$t3
-+	movzb	`&hi("$s3")`,$acc0
-+	movzb	`&hi("$s0")`,$acc1
-+	shr	\$16,$s3
-+	movzb	`&hi("$s1")`,$acc2
-+	movzb	($sbox,$t0,1),$t0
-+	movzb	($sbox,$t1,1),$t1
-+	movzb	($sbox,$t2,1),$t2
-+	movzb	($sbox,$t3,1),$t3
-+
-+	movzb	($sbox,$acc0,1),$t4	#$t0
-+	movzb	`&hi("$s2")`,$acc0
-+	movzb	($sbox,$acc1,1),$t5	#$t1
-+	movzb	($sbox,$acc2,1),$acc2	#$t2
-+	movzb	($sbox,$acc0,1),$acc0	#$t3
-+
-+	shr	\$16,$s2
-+	shl	\$8,$t5
-+	shl	\$8,$t4
-+	movzb	`&lo("$s2")`,$acc1
-+	shr	\$16,$s0
-+	xor	$t4,$t0
-+	shr	\$16,$s1
-+	movzb	`&lo("$s3")`,$t4
-+
-+	shl	\$8,$acc2
-+	xor	$t5,$t1
-+	shl	\$8,$acc0
-+	movzb	`&lo("$s0")`,$t5
-+	movzb	($sbox,$acc1,1),$acc1	#$t0
-+	xor	$acc2,$t2
-+	movzb	`&lo("$s1")`,$acc2
-+
-+	shl	\$16,$acc1
-+	xor	$acc0,$t3
-+	movzb	($sbox,$t4,1),$t4	#$t1
-+	movzb	`&hi("$s1")`,$acc0
-+	movzb	($sbox,$acc2,1),$acc2	#$t3
-+	xor	$acc1,$t0
-+	movzb	($sbox,$t5,1),$t5	#$t2
-+	movzb	`&hi("$s2")`,$acc1
-+
-+	shl	\$16,$acc2
-+	shl	\$16,$t4
-+	shl	\$16,$t5
-+	xor	$acc2,$t3
-+	movzb	`&hi("$s3")`,$acc2
-+	xor	$t4,$t1
-+	shr	\$8,$s0
-+	xor	$t5,$t2
-+
-+	movzb	($sbox,$acc0,1),$acc0	#$t0
-+	movzb	($sbox,$acc1,1),$s1	#$t1
-+	movzb	($sbox,$acc2,1),$s2	#$t2
-+	movzb	($sbox,$s0,1),$s3	#$t3
-+
-+	mov	$t0,$s0
-+	shl	\$24,$acc0
-+	shl	\$24,$s1
-+	shl	\$24,$s2
-+	xor	$acc0,$s0
-+	shl	\$24,$s3
-+	xor	$t1,$s1
-+	xor	$t2,$s2
-+	xor	$t3,$s3
-+___
-+}
-+
-+# parallelized version! input is pair of 64-bit values: %rax=s1.s0
-+# and %rcx=s3.s2, output is four 32-bit values in %eax=s0, %ebx=s1,
-+# %ecx=s2 and %edx=s3.
-+sub dectransform()
-+{ my ($tp10,$tp20,$tp40,$tp80,$acc0)=("%rax","%r8", "%r9", "%r10","%rbx");
-+  my ($tp18,$tp28,$tp48,$tp88,$acc8)=("%rcx","%r11","%r12","%r13","%rdx");
-+  my $prefetch = shift;
-+
-+$code.=<<___;
-+	mov	$mask80,$tp40
-+	mov	$mask80,$tp48
-+	and	$tp10,$tp40
-+	and	$tp18,$tp48
-+	mov	$tp40,$acc0
-+	mov	$tp48,$acc8
-+	shr	\$7,$tp40
-+	lea	($tp10,$tp10),$tp20
-+	shr	\$7,$tp48
-+	lea	($tp18,$tp18),$tp28
-+	sub	$tp40,$acc0
-+	sub	$tp48,$acc8
-+	and	$maskfe,$tp20
-+	and	$maskfe,$tp28
-+	and	$mask1b,$acc0
-+	and	$mask1b,$acc8
-+	xor	$acc0,$tp20
-+	xor	$acc8,$tp28
-+	mov	$mask80,$tp80
-+	mov	$mask80,$tp88
-+
-+	and	$tp20,$tp80
-+	and	$tp28,$tp88
-+	mov	$tp80,$acc0
-+	mov	$tp88,$acc8
-+	shr	\$7,$tp80
-+	lea	($tp20,$tp20),$tp40
-+	shr	\$7,$tp88
-+	lea	($tp28,$tp28),$tp48
-+	sub	$tp80,$acc0
-+	sub	$tp88,$acc8
-+	and	$maskfe,$tp40
-+	and	$maskfe,$tp48
-+	and	$mask1b,$acc0
-+	and	$mask1b,$acc8
-+	xor	$acc0,$tp40
-+	xor	$acc8,$tp48
-+	mov	$mask80,$tp80
-+	mov	$mask80,$tp88
-+
-+	and	$tp40,$tp80
-+	and	$tp48,$tp88
-+	mov	$tp80,$acc0
-+	mov	$tp88,$acc8
-+	shr	\$7,$tp80
-+	 xor	$tp10,$tp20		# tp2^=tp1
-+	shr	\$7,$tp88
-+	 xor	$tp18,$tp28		# tp2^=tp1
-+	sub	$tp80,$acc0
-+	sub	$tp88,$acc8
-+	lea	($tp40,$tp40),$tp80
-+	lea	($tp48,$tp48),$tp88
-+	 xor	$tp10,$tp40		# tp4^=tp1
-+	 xor	$tp18,$tp48		# tp4^=tp1
-+	and	$maskfe,$tp80
-+	and	$maskfe,$tp88
-+	and	$mask1b,$acc0
-+	and	$mask1b,$acc8
-+	xor	$acc0,$tp80
-+	xor	$acc8,$tp88
-+
-+	xor	$tp80,$tp10		# tp1^=tp8
-+	xor	$tp88,$tp18		# tp1^=tp8
-+	xor	$tp80,$tp20		# tp2^tp1^=tp8
-+	xor	$tp88,$tp28		# tp2^tp1^=tp8
-+	mov	$tp10,$acc0
-+	mov	$tp18,$acc8
-+	xor	$tp80,$tp40		# tp4^tp1^=tp8
-+	shr	\$32,$acc0
-+	xor	$tp88,$tp48		# tp4^tp1^=tp8
-+	shr	\$32,$acc8
-+	xor	$tp20,$tp80		# tp8^=tp8^tp2^tp1=tp2^tp1
-+	rol	\$8,`&LO("$tp10")`	# ROTATE(tp1^tp8,8)
-+	xor	$tp28,$tp88		# tp8^=tp8^tp2^tp1=tp2^tp1
-+	rol	\$8,`&LO("$tp18")`	# ROTATE(tp1^tp8,8)
-+	xor	$tp40,$tp80		# tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
-+	rol	\$8,`&LO("$acc0")`	# ROTATE(tp1^tp8,8)
-+	xor	$tp48,$tp88		# tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2
-+
-+	rol	\$8,`&LO("$acc8")`	# ROTATE(tp1^tp8,8)
-+	xor	`&LO("$tp80")`,`&LO("$tp10")`
-+	shr	\$32,$tp80
-+	xor	`&LO("$tp88")`,`&LO("$tp18")`
-+	shr	\$32,$tp88
-+	xor	`&LO("$tp80")`,`&LO("$acc0")`
-+	xor	`&LO("$tp88")`,`&LO("$acc8")`
-+
-+	mov	$tp20,$tp80
-+	rol	\$24,`&LO("$tp20")`	# ROTATE(tp2^tp1^tp8,24)
-+	mov	$tp28,$tp88
-+	rol	\$24,`&LO("$tp28")`	# ROTATE(tp2^tp1^tp8,24)
-+	shr	\$32,$tp80
-+	xor	`&LO("$tp20")`,`&LO("$tp10")`
-+	shr	\$32,$tp88
-+	xor	`&LO("$tp28")`,`&LO("$tp18")`
-+	rol	\$24,`&LO("$tp80")`	# ROTATE(tp2^tp1^tp8,24)
-+	mov	$tp40,$tp20
-+	rol	\$24,`&LO("$tp88")`	# ROTATE(tp2^tp1^tp8,24)
-+	mov	$tp48,$tp28
-+	shr	\$32,$tp20
-+	xor	`&LO("$tp80")`,`&LO("$acc0")`
-+	shr	\$32,$tp28
-+	xor	`&LO("$tp88")`,`&LO("$acc8")`
-+
-+	`"mov	0($sbox),$mask80"	if ($prefetch)`
-+	rol	\$16,`&LO("$tp40")`	# ROTATE(tp4^tp1^tp8,16)
-+	`"mov	64($sbox),$maskfe"	if ($prefetch)`
-+	rol	\$16,`&LO("$tp48")`	# ROTATE(tp4^tp1^tp8,16)
-+	`"mov	128($sbox),$mask1b"	if ($prefetch)`
-+	rol	\$16,`&LO("$tp20")`	# ROTATE(tp4^tp1^tp8,16)
-+	`"mov	192($sbox),$tp80"	if ($prefetch)`
-+	xor	`&LO("$tp40")`,`&LO("$tp10")`
-+	rol	\$16,`&LO("$tp28")`	# ROTATE(tp4^tp1^tp8,16)
-+	xor	`&LO("$tp48")`,`&LO("$tp18")`
-+	`"mov	256($sbox),$tp88"	if ($prefetch)`
-+	xor	`&LO("$tp20")`,`&LO("$acc0")`
-+	xor	`&LO("$tp28")`,`&LO("$acc8")`
-+___
-+}
-+
-+$code.=<<___;
-+.type	_x86_64_AES_decrypt_compact,\@abi-omnipotent
-+.align	16
-+_x86_64_AES_decrypt_compact:
-+	lea	128($sbox),$inp			# size optimization
-+	mov	0-128($inp),$acc1		# prefetch Td4
-+	mov	32-128($inp),$acc2
-+	mov	64-128($inp),$t0
-+	mov	96-128($inp),$t1
-+	mov	128-128($inp),$acc1
-+	mov	160-128($inp),$acc2
-+	mov	192-128($inp),$t0
-+	mov	224-128($inp),$t1
-+	jmp	.Ldec_loop_compact
-+
-+.align	16
-+.Ldec_loop_compact:
-+		xor	0($key),$s0		# xor with key
-+		xor	4($key),$s1
-+		xor	8($key),$s2
-+		xor	12($key),$s3
-+		lea	16($key),$key
-+___
-+		&deccompactvert();
-+$code.=<<___;
-+		cmp	16(%rsp),$key
-+		je	.Ldec_compact_done
-+
-+		mov	256+0($sbox),$mask80
-+		shl	\$32,%rbx
-+		shl	\$32,%rdx
-+		mov	256+8($sbox),$maskfe
-+		or	%rbx,%rax
-+		or	%rdx,%rcx
-+		mov	256+16($sbox),$mask1b
-+___
-+		&dectransform(1);
-+$code.=<<___;
-+	jmp	.Ldec_loop_compact
-+.align	16
-+.Ldec_compact_done:
-+	xor	0($key),$s0
-+	xor	4($key),$s1
-+	xor	8($key),$s2
-+	xor	12($key),$s3
-+	.byte	0xf3,0xc3			# rep ret
-+.size	_x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact
-+___
-+
-+# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
-+$code.=<<___;
-+.globl	AES_decrypt
-+.type	AES_decrypt,\@function,3
-+.align	16
-+.globl	asm_AES_decrypt
-+.hidden	asm_AES_decrypt
-+asm_AES_decrypt:
-+AES_decrypt:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	# allocate frame "above" key schedule
-+	mov	%rsp,%r10
-+	lea	-63(%rdx),%rcx	# %rdx is key argument
-+	and	\$-64,%rsp
-+	sub	%rsp,%rcx
-+	neg	%rcx
-+	and	\$0x3c0,%rcx
-+	sub	%rcx,%rsp
-+	sub	\$32,%rsp
-+
-+	mov	%rsi,16(%rsp)	# save out
-+	mov	%r10,24(%rsp)	# save real stack pointer
-+.Ldec_prologue:
-+
-+	mov	%rdx,$key
-+	mov	240($key),$rnds	# load rounds
-+
-+	mov	0(%rdi),$s0	# load input vector
-+	mov	4(%rdi),$s1
-+	mov	8(%rdi),$s2
-+	mov	12(%rdi),$s3
-+
-+	shl	\$4,$rnds
-+	lea	($key,$rnds),%rbp
-+	mov	$key,(%rsp)	# key schedule
-+	mov	%rbp,8(%rsp)	# end of key schedule
-+
-+	# pick Td4 copy which can't "overlap" with stack frame or key schedule
-+	lea	.LAES_Td+2048(%rip),$sbox
-+	lea	768(%rsp),%rbp
-+	sub	$sbox,%rbp
-+	and	\$0x300,%rbp
-+	lea	($sbox,%rbp),$sbox
-+	shr	\$3,%rbp	# recall "magic" constants!
-+	add	%rbp,$sbox
-+
-+	call	_x86_64_AES_decrypt_compact
-+
-+	mov	16(%rsp),$out	# restore out
-+	mov	24(%rsp),%rsi	# restore saved stack pointer
-+	mov	$s0,0($out)	# write output vector
-+	mov	$s1,4($out)
-+	mov	$s2,8($out)
-+	mov	$s3,12($out)
-+
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Ldec_epilogue:
-+	ret
-+.size	AES_decrypt,.-AES_decrypt
-+___
-+#------------------------------------------------------------------#
-+
-+sub enckey()
-+{
-+$code.=<<___;
-+	movz	%dl,%esi		# rk[i]>>0
-+	movzb	-128(%rbp,%rsi),%ebx
-+	movz	%dh,%esi		# rk[i]>>8
-+	shl	\$24,%ebx
-+	xor	%ebx,%eax
-+
-+	movzb	-128(%rbp,%rsi),%ebx
-+	shr	\$16,%edx
-+	movz	%dl,%esi		# rk[i]>>16
-+	xor	%ebx,%eax
-+
-+	movzb	-128(%rbp,%rsi),%ebx
-+	movz	%dh,%esi		# rk[i]>>24
-+	shl	\$8,%ebx
-+	xor	%ebx,%eax
-+
-+	movzb	-128(%rbp,%rsi),%ebx
-+	shl	\$16,%ebx
-+	xor	%ebx,%eax
-+
-+	xor	1024-128(%rbp,%rcx,4),%eax		# rcon
-+___
-+}
-+
-+# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
-+#                        AES_KEY *key)
-+$code.=<<___;
-+.globl	AES_set_encrypt_key
-+.type	AES_set_encrypt_key,\@function,3
-+.align	16
-+AES_set_encrypt_key:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12			# redundant, but allows to share 
-+	push	%r13			# exception handler...
-+	push	%r14
-+	push	%r15
-+	sub	\$8,%rsp
-+.Lenc_key_prologue:
-+
-+	call	_x86_64_AES_set_encrypt_key
-+
-+	mov	40(%rsp),%rbp
-+	mov	48(%rsp),%rbx
-+	add	\$56,%rsp
-+.Lenc_key_epilogue:
-+	ret
-+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
-+
-+.type	_x86_64_AES_set_encrypt_key,\@abi-omnipotent
-+.align	16
-+_x86_64_AES_set_encrypt_key:
-+	mov	%esi,%ecx			# %ecx=bits
-+	mov	%rdi,%rsi			# %rsi=userKey
-+	mov	%rdx,%rdi			# %rdi=key
-+
-+	test	\$-1,%rsi
-+	jz	.Lbadpointer
-+	test	\$-1,%rdi
-+	jz	.Lbadpointer
-+
-+	lea	.LAES_Te(%rip),%rbp
-+	lea	2048+128(%rbp),%rbp
-+
-+	# prefetch Te4
-+	mov	0-128(%rbp),%eax
-+	mov	32-128(%rbp),%ebx
-+	mov	64-128(%rbp),%r8d
-+	mov	96-128(%rbp),%edx
-+	mov	128-128(%rbp),%eax
-+	mov	160-128(%rbp),%ebx
-+	mov	192-128(%rbp),%r8d
-+	mov	224-128(%rbp),%edx
-+
-+	cmp	\$128,%ecx
-+	je	.L10rounds
-+	cmp	\$192,%ecx
-+	je	.L12rounds
-+	cmp	\$256,%ecx
-+	je	.L14rounds
-+	mov	\$-2,%rax			# invalid number of bits
-+	jmp	.Lexit
-+
-+.L10rounds:
-+	mov	0(%rsi),%rax			# copy first 4 dwords
-+	mov	8(%rsi),%rdx
-+	mov	%rax,0(%rdi)
-+	mov	%rdx,8(%rdi)
-+
-+	shr	\$32,%rdx
-+	xor	%ecx,%ecx
-+	jmp	.L10shortcut
-+.align	4
-+.L10loop:
-+		mov	0(%rdi),%eax			# rk[0]
-+		mov	12(%rdi),%edx			# rk[3]
-+.L10shortcut:
-+___
-+		&enckey	();
-+$code.=<<___;
-+		mov	%eax,16(%rdi)			# rk[4]
-+		xor	4(%rdi),%eax
-+		mov	%eax,20(%rdi)			# rk[5]
-+		xor	8(%rdi),%eax
-+		mov	%eax,24(%rdi)			# rk[6]
-+		xor	12(%rdi),%eax
-+		mov	%eax,28(%rdi)			# rk[7]
-+		add	\$1,%ecx
-+		lea	16(%rdi),%rdi
-+		cmp	\$10,%ecx
-+	jl	.L10loop
-+
-+	movl	\$10,80(%rdi)			# setup number of rounds
-+	xor	%rax,%rax
-+	jmp	.Lexit
-+
-+.L12rounds:
-+	mov	0(%rsi),%rax			# copy first 6 dwords
-+	mov	8(%rsi),%rbx
-+	mov	16(%rsi),%rdx
-+	mov	%rax,0(%rdi)
-+	mov	%rbx,8(%rdi)
-+	mov	%rdx,16(%rdi)
-+
-+	shr	\$32,%rdx
-+	xor	%ecx,%ecx
-+	jmp	.L12shortcut
-+.align	4
-+.L12loop:
-+		mov	0(%rdi),%eax			# rk[0]
-+		mov	20(%rdi),%edx			# rk[5]
-+.L12shortcut:
-+___
-+		&enckey	();
-+$code.=<<___;
-+		mov	%eax,24(%rdi)			# rk[6]
-+		xor	4(%rdi),%eax
-+		mov	%eax,28(%rdi)			# rk[7]
-+		xor	8(%rdi),%eax
-+		mov	%eax,32(%rdi)			# rk[8]
-+		xor	12(%rdi),%eax
-+		mov	%eax,36(%rdi)			# rk[9]
-+
-+		cmp	\$7,%ecx
-+		je	.L12break
-+		add	\$1,%ecx
-+
-+		xor	16(%rdi),%eax
-+		mov	%eax,40(%rdi)			# rk[10]
-+		xor	20(%rdi),%eax
-+		mov	%eax,44(%rdi)			# rk[11]
-+
-+		lea	24(%rdi),%rdi
-+	jmp	.L12loop
-+.L12break:
-+	movl	\$12,72(%rdi)		# setup number of rounds
-+	xor	%rax,%rax
-+	jmp	.Lexit
-+
-+.L14rounds:		
-+	mov	0(%rsi),%rax			# copy first 8 dwords
-+	mov	8(%rsi),%rbx
-+	mov	16(%rsi),%rcx
-+	mov	24(%rsi),%rdx
-+	mov	%rax,0(%rdi)
-+	mov	%rbx,8(%rdi)
-+	mov	%rcx,16(%rdi)
-+	mov	%rdx,24(%rdi)
-+
-+	shr	\$32,%rdx
-+	xor	%ecx,%ecx
-+	jmp	.L14shortcut
-+.align	4
-+.L14loop:
-+		mov	0(%rdi),%eax			# rk[0]
-+		mov	28(%rdi),%edx			# rk[4]
-+.L14shortcut:
-+___
-+		&enckey	();
-+$code.=<<___;
-+		mov	%eax,32(%rdi)			# rk[8]
-+		xor	4(%rdi),%eax
-+		mov	%eax,36(%rdi)			# rk[9]
-+		xor	8(%rdi),%eax
-+		mov	%eax,40(%rdi)			# rk[10]
-+		xor	12(%rdi),%eax
-+		mov	%eax,44(%rdi)			# rk[11]
-+
-+		cmp	\$6,%ecx
-+		je	.L14break
-+		add	\$1,%ecx
-+
-+		mov	%eax,%edx
-+		mov	16(%rdi),%eax			# rk[4]
-+		movz	%dl,%esi			# rk[11]>>0
-+		movzb	-128(%rbp,%rsi),%ebx
-+		movz	%dh,%esi			# rk[11]>>8
-+		xor	%ebx,%eax
-+
-+		movzb	-128(%rbp,%rsi),%ebx
-+		shr	\$16,%edx
-+		shl	\$8,%ebx
-+		movz	%dl,%esi			# rk[11]>>16
-+		xor	%ebx,%eax
-+
-+		movzb	-128(%rbp,%rsi),%ebx
-+		movz	%dh,%esi			# rk[11]>>24
-+		shl	\$16,%ebx
-+		xor	%ebx,%eax
-+
-+		movzb	-128(%rbp,%rsi),%ebx
-+		shl	\$24,%ebx
-+		xor	%ebx,%eax
-+
-+		mov	%eax,48(%rdi)			# rk[12]
-+		xor	20(%rdi),%eax
-+		mov	%eax,52(%rdi)			# rk[13]
-+		xor	24(%rdi),%eax
-+		mov	%eax,56(%rdi)			# rk[14]
-+		xor	28(%rdi),%eax
-+		mov	%eax,60(%rdi)			# rk[15]
-+
-+		lea	32(%rdi),%rdi
-+	jmp	.L14loop
-+.L14break:
-+	movl	\$14,48(%rdi)		# setup number of rounds
-+	xor	%rax,%rax
-+	jmp	.Lexit
-+
-+.Lbadpointer:
-+	mov	\$-1,%rax
-+.Lexit:
-+	.byte	0xf3,0xc3			# rep ret
-+.size	_x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key
-+___
-+
-+sub deckey_ref()
-+{ my ($i,$ptr,$te,$td) = @_;
-+  my ($tp1,$tp2,$tp4,$tp8,$acc)=("%eax","%ebx","%edi","%edx","%r8d");
-+$code.=<<___;
-+	mov	$i($ptr),$tp1
-+	mov	$tp1,$acc
-+	and	\$0x80808080,$acc
-+	mov	$acc,$tp4
-+	shr	\$7,$tp4
-+	lea	0($tp1,$tp1),$tp2
-+	sub	$tp4,$acc
-+	and	\$0xfefefefe,$tp2
-+	and	\$0x1b1b1b1b,$acc
-+	xor	$tp2,$acc
-+	mov	$acc,$tp2
-+
-+	and	\$0x80808080,$acc
-+	mov	$acc,$tp8
-+	shr	\$7,$tp8
-+	lea	0($tp2,$tp2),$tp4
-+	sub	$tp8,$acc
-+	and	\$0xfefefefe,$tp4
-+	and	\$0x1b1b1b1b,$acc
-+	 xor	$tp1,$tp2		# tp2^tp1
-+	xor	$tp4,$acc
-+	mov	$acc,$tp4
-+
-+	and	\$0x80808080,$acc
-+	mov	$acc,$tp8
-+	shr	\$7,$tp8
-+	sub	$tp8,$acc
-+	lea	0($tp4,$tp4),$tp8
-+	 xor	$tp1,$tp4		# tp4^tp1
-+	and	\$0xfefefefe,$tp8
-+	and	\$0x1b1b1b1b,$acc
-+	xor	$acc,$tp8
-+
-+	xor	$tp8,$tp1		# tp1^tp8
-+	rol	\$8,$tp1		# ROTATE(tp1^tp8,8)
-+	xor	$tp8,$tp2		# tp2^tp1^tp8
-+	xor	$tp8,$tp4		# tp4^tp1^tp8
-+	xor	$tp2,$tp8
-+	xor	$tp4,$tp8		# tp8^(tp8^tp4^tp1)^(tp8^tp2^tp1)=tp8^tp4^tp2
-+
-+	xor	$tp8,$tp1
-+	rol	\$24,$tp2		# ROTATE(tp2^tp1^tp8,24)
-+	xor	$tp2,$tp1
-+	rol	\$16,$tp4		# ROTATE(tp4^tp1^tp8,16)
-+	xor	$tp4,$tp1
-+
-+	mov	$tp1,$i($ptr)
-+___
-+}
-+
-+# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
-+#                        AES_KEY *key)
-+$code.=<<___;
-+.globl	AES_set_decrypt_key
-+.type	AES_set_decrypt_key,\@function,3
-+.align	16
-+AES_set_decrypt_key:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	push	%rdx			# save key schedule
-+.Ldec_key_prologue:
-+
-+	call	_x86_64_AES_set_encrypt_key
-+	mov	(%rsp),%r8		# restore key schedule
-+	cmp	\$0,%eax
-+	jne	.Labort
-+
-+	mov	240(%r8),%r14d		# pull number of rounds
-+	xor	%rdi,%rdi
-+	lea	(%rdi,%r14d,4),%rcx
-+	mov	%r8,%rsi
-+	lea	(%r8,%rcx,4),%rdi	# pointer to last chunk
-+.align	4
-+.Linvert:
-+		mov	0(%rsi),%rax
-+		mov	8(%rsi),%rbx
-+		mov	0(%rdi),%rcx
-+		mov	8(%rdi),%rdx
-+		mov	%rax,0(%rdi)
-+		mov	%rbx,8(%rdi)
-+		mov	%rcx,0(%rsi)
-+		mov	%rdx,8(%rsi)
-+		lea	16(%rsi),%rsi
-+		lea	-16(%rdi),%rdi
-+		cmp	%rsi,%rdi
-+	jne	.Linvert
-+
-+	lea	.LAES_Te+2048+1024(%rip),%rax	# rcon
-+
-+	mov	40(%rax),$mask80
-+	mov	48(%rax),$maskfe
-+	mov	56(%rax),$mask1b
-+
-+	mov	%r8,$key
-+	sub	\$1,%r14d
-+.align	4
-+.Lpermute:
-+		lea	16($key),$key
-+		mov	0($key),%rax
-+		mov	8($key),%rcx
-+___
-+		&dectransform ();
-+$code.=<<___;
-+		mov	%eax,0($key)
-+		mov	%ebx,4($key)
-+		mov	%ecx,8($key)
-+		mov	%edx,12($key)
-+		sub	\$1,%r14d
-+	jnz	.Lpermute
-+
-+	xor	%rax,%rax
-+.Labort:
-+	mov	8(%rsp),%r15
-+	mov	16(%rsp),%r14
-+	mov	24(%rsp),%r13
-+	mov	32(%rsp),%r12
-+	mov	40(%rsp),%rbp
-+	mov	48(%rsp),%rbx
-+	add	\$56,%rsp
-+.Ldec_key_epilogue:
-+	ret
-+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
-+___
-+
-+# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
-+#			size_t length, const AES_KEY *key,
-+#			unsigned char *ivp,const int enc);
-+{
-+# stack frame layout
-+# -8(%rsp)		return address
-+my $keyp="0(%rsp)";		# one to pass as $key
-+my $keyend="8(%rsp)";		# &(keyp->rd_key[4*keyp->rounds])
-+my $_rsp="16(%rsp)";		# saved %rsp
-+my $_inp="24(%rsp)";		# copy of 1st parameter, inp
-+my $_out="32(%rsp)";		# copy of 2nd parameter, out
-+my $_len="40(%rsp)";		# copy of 3rd parameter, length
-+my $_key="48(%rsp)";		# copy of 4th parameter, key
-+my $_ivp="56(%rsp)";		# copy of 5th parameter, ivp
-+my $ivec="64(%rsp)";		# ivec[16]
-+my $aes_key="80(%rsp)";		# copy of aes_key
-+my $mark="80+240(%rsp)";	# copy of aes_key->rounds
-+
-+$code.=<<___;
-+.globl	AES_cbc_encrypt
-+.type	AES_cbc_encrypt,\@function,6
-+.align	16
-+.extern	OPENSSL_ia32cap_P
-+.globl	asm_AES_cbc_encrypt
-+.hidden	asm_AES_cbc_encrypt
-+asm_AES_cbc_encrypt:
-+AES_cbc_encrypt:
-+	cmp	\$0,%rdx	# check length
-+	je	.Lcbc_epilogue
-+	pushfq
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lcbc_prologue:
-+
-+	cld
-+	mov	%r9d,%r9d	# clear upper half of enc
-+
-+	lea	.LAES_Te(%rip),$sbox
-+	cmp	\$0,%r9
-+	jne	.Lcbc_picked_te
-+	lea	.LAES_Td(%rip),$sbox
-+.Lcbc_picked_te:
-+
-+	mov	OPENSSL_ia32cap_P(%rip),%r10d
-+	cmp	\$$speed_limit,%rdx
-+	jb	.Lcbc_slow_prologue
-+	test	\$15,%rdx
-+	jnz	.Lcbc_slow_prologue
-+	bt	\$28,%r10d
-+	jc	.Lcbc_slow_prologue
-+
-+	# allocate aligned stack frame...
-+	lea	-88-248(%rsp),$key
-+	and	\$-64,$key
-+
-+	# ... and make sure it doesn't alias with AES_T[ed] modulo 4096
-+	mov	$sbox,%r10
-+	lea	2304($sbox),%r11
-+	mov	$key,%r12
-+	and	\$0xFFF,%r10	# s = $sbox&0xfff
-+	and	\$0xFFF,%r11	# e = ($sbox+2048)&0xfff
-+	and	\$0xFFF,%r12	# p = %rsp&0xfff
-+
-+	cmp	%r11,%r12	# if (p=>e) %rsp =- (p-e);
-+	jb	.Lcbc_te_break_out
-+	sub	%r11,%r12
-+	sub	%r12,$key
-+	jmp	.Lcbc_te_ok
-+.Lcbc_te_break_out:		# else %rsp -= (p-s)&0xfff + framesz
-+	sub	%r10,%r12
-+	and	\$0xFFF,%r12
-+	add	\$320,%r12
-+	sub	%r12,$key
-+.align	4
-+.Lcbc_te_ok:
-+
-+	xchg	%rsp,$key
-+	#add	\$8,%rsp	# reserve for return address!
-+	mov	$key,$_rsp	# save %rsp
-+.Lcbc_fast_body:
-+	mov	%rdi,$_inp	# save copy of inp
-+	mov	%rsi,$_out	# save copy of out
-+	mov	%rdx,$_len	# save copy of len
-+	mov	%rcx,$_key	# save copy of key
-+	mov	%r8,$_ivp	# save copy of ivp
-+	movl	\$0,$mark	# copy of aes_key->rounds = 0;
-+	mov	%r8,%rbp	# rearrange input arguments
-+	mov	%r9,%rbx
-+	mov	%rsi,$out
-+	mov	%rdi,$inp
-+	mov	%rcx,$key
-+
-+	mov	240($key),%eax		# key->rounds
-+	# do we copy key schedule to stack?
-+	mov	$key,%r10
-+	sub	$sbox,%r10
-+	and	\$0xfff,%r10
-+	cmp	\$2304,%r10
-+	jb	.Lcbc_do_ecopy
-+	cmp	\$4096-248,%r10
-+	jb	.Lcbc_skip_ecopy
-+.align	4
-+.Lcbc_do_ecopy:
-+		mov	$key,%rsi
-+		lea	$aes_key,%rdi
-+		lea	$aes_key,$key
-+		mov	\$240/8,%ecx
-+		.long	0x90A548F3	# rep movsq
-+		mov	%eax,(%rdi)	# copy aes_key->rounds
-+.Lcbc_skip_ecopy:
-+	mov	$key,$keyp	# save key pointer
-+
-+	mov	\$18,%ecx
-+.align	4
-+.Lcbc_prefetch_te:
-+		mov	0($sbox),%r10
-+		mov	32($sbox),%r11
-+		mov	64($sbox),%r12
-+		mov	96($sbox),%r13
-+		lea	128($sbox),$sbox
-+		sub	\$1,%ecx
-+	jnz	.Lcbc_prefetch_te
-+	lea	-2304($sbox),$sbox
-+
-+	cmp	\$0,%rbx
-+	je	.LFAST_DECRYPT
-+
-+#----------------------------- ENCRYPT -----------------------------#
-+	mov	0(%rbp),$s0		# load iv
-+	mov	4(%rbp),$s1
-+	mov	8(%rbp),$s2
-+	mov	12(%rbp),$s3
-+
-+.align	4
-+.Lcbc_fast_enc_loop:
-+		xor	0($inp),$s0
-+		xor	4($inp),$s1
-+		xor	8($inp),$s2
-+		xor	12($inp),$s3
-+		mov	$keyp,$key	# restore key
-+		mov	$inp,$_inp	# if ($verticalspin) save inp
-+
-+		call	_x86_64_AES_encrypt
-+
-+		mov	$_inp,$inp	# if ($verticalspin) restore inp
-+		mov	$_len,%r10
-+		mov	$s0,0($out)
-+		mov	$s1,4($out)
-+		mov	$s2,8($out)
-+		mov	$s3,12($out)
-+
-+		lea	16($inp),$inp
-+		lea	16($out),$out
-+		sub	\$16,%r10
-+		test	\$-16,%r10
-+		mov	%r10,$_len
-+	jnz	.Lcbc_fast_enc_loop
-+	mov	$_ivp,%rbp	# restore ivp
-+	mov	$s0,0(%rbp)	# save ivec
-+	mov	$s1,4(%rbp)
-+	mov	$s2,8(%rbp)
-+	mov	$s3,12(%rbp)
-+
-+	jmp	.Lcbc_fast_cleanup
-+
-+#----------------------------- DECRYPT -----------------------------#
-+.align	16
-+.LFAST_DECRYPT:
-+	cmp	$inp,$out
-+	je	.Lcbc_fast_dec_in_place
-+
-+	mov	%rbp,$ivec
-+.align	4
-+.Lcbc_fast_dec_loop:
-+		mov	0($inp),$s0	# read input
-+		mov	4($inp),$s1
-+		mov	8($inp),$s2
-+		mov	12($inp),$s3
-+		mov	$keyp,$key	# restore key
-+		mov	$inp,$_inp	# if ($verticalspin) save inp
-+
-+		call	_x86_64_AES_decrypt
-+
-+		mov	$ivec,%rbp	# load ivp
-+		mov	$_inp,$inp	# if ($verticalspin) restore inp
-+		mov	$_len,%r10	# load len
-+		xor	0(%rbp),$s0	# xor iv
-+		xor	4(%rbp),$s1
-+		xor	8(%rbp),$s2
-+		xor	12(%rbp),$s3
-+		mov	$inp,%rbp	# current input, next iv
-+
-+		sub	\$16,%r10
-+		mov	%r10,$_len	# update len
-+		mov	%rbp,$ivec	# update ivp
-+
-+		mov	$s0,0($out)	# write output
-+		mov	$s1,4($out)
-+		mov	$s2,8($out)
-+		mov	$s3,12($out)
-+
-+		lea	16($inp),$inp
-+		lea	16($out),$out
-+	jnz	.Lcbc_fast_dec_loop
-+	mov	$_ivp,%r12		# load user ivp
-+	mov	0(%rbp),%r10		# load iv
-+	mov	8(%rbp),%r11
-+	mov	%r10,0(%r12)		# copy back to user
-+	mov	%r11,8(%r12)
-+	jmp	.Lcbc_fast_cleanup
-+
-+.align	16
-+.Lcbc_fast_dec_in_place:
-+	mov	0(%rbp),%r10		# copy iv to stack
-+	mov	8(%rbp),%r11
-+	mov	%r10,0+$ivec
-+	mov	%r11,8+$ivec
-+.align	4
-+.Lcbc_fast_dec_in_place_loop:
-+		mov	0($inp),$s0	# load input
-+		mov	4($inp),$s1
-+		mov	8($inp),$s2
-+		mov	12($inp),$s3
-+		mov	$keyp,$key	# restore key
-+		mov	$inp,$_inp	# if ($verticalspin) save inp
-+
-+		call	_x86_64_AES_decrypt
-+
-+		mov	$_inp,$inp	# if ($verticalspin) restore inp
-+		mov	$_len,%r10
-+		xor	0+$ivec,$s0
-+		xor	4+$ivec,$s1
-+		xor	8+$ivec,$s2
-+		xor	12+$ivec,$s3
-+
-+		mov	0($inp),%r11	# load input
-+		mov	8($inp),%r12
-+		sub	\$16,%r10
-+		jz	.Lcbc_fast_dec_in_place_done
-+
-+		mov	%r11,0+$ivec	# copy input to iv
-+		mov	%r12,8+$ivec
-+
-+		mov	$s0,0($out)	# save output [zaps input]
-+		mov	$s1,4($out)
-+		mov	$s2,8($out)
-+		mov	$s3,12($out)
-+
-+		lea	16($inp),$inp
-+		lea	16($out),$out
-+		mov	%r10,$_len
-+	jmp	.Lcbc_fast_dec_in_place_loop
-+.Lcbc_fast_dec_in_place_done:
-+	mov	$_ivp,%rdi
-+	mov	%r11,0(%rdi)	# copy iv back to user
-+	mov	%r12,8(%rdi)
-+
-+	mov	$s0,0($out)	# save output [zaps input]
-+	mov	$s1,4($out)
-+	mov	$s2,8($out)
-+	mov	$s3,12($out)
-+
-+.align	4
-+.Lcbc_fast_cleanup:
-+	cmpl	\$0,$mark	# was the key schedule copied?
-+	lea	$aes_key,%rdi
-+	je	.Lcbc_exit
-+		mov	\$240/8,%ecx
-+		xor	%rax,%rax
-+		.long	0x90AB48F3	# rep stosq
-+
-+	jmp	.Lcbc_exit
-+
-+#--------------------------- SLOW ROUTINE ---------------------------#
-+.align	16
-+.Lcbc_slow_prologue:
-+	# allocate aligned stack frame...
-+	lea	-88(%rsp),%rbp
-+	and	\$-64,%rbp
-+	# ... just "above" key schedule
-+	lea	-88-63(%rcx),%r10
-+	sub	%rbp,%r10
-+	neg	%r10
-+	and	\$0x3c0,%r10
-+	sub	%r10,%rbp
-+
-+	xchg	%rsp,%rbp
-+	#add	\$8,%rsp	# reserve for return address!
-+	mov	%rbp,$_rsp	# save %rsp
-+.Lcbc_slow_body:
-+	#mov	%rdi,$_inp	# save copy of inp
-+	#mov	%rsi,$_out	# save copy of out
-+	#mov	%rdx,$_len	# save copy of len
-+	#mov	%rcx,$_key	# save copy of key
-+	mov	%r8,$_ivp	# save copy of ivp
-+	mov	%r8,%rbp	# rearrange input arguments
-+	mov	%r9,%rbx
-+	mov	%rsi,$out
-+	mov	%rdi,$inp
-+	mov	%rcx,$key
-+	mov	%rdx,%r10
-+
-+	mov	240($key),%eax
-+	mov	$key,$keyp	# save key pointer
-+	shl	\$4,%eax
-+	lea	($key,%rax),%rax
-+	mov	%rax,$keyend
-+
-+	# pick Te4 copy which can't "overlap" with stack frame or key scdedule
-+	lea	2048($sbox),$sbox
-+	lea	768-8(%rsp),%rax
-+	sub	$sbox,%rax
-+	and	\$0x300,%rax
-+	lea	($sbox,%rax),$sbox
-+
-+	cmp	\$0,%rbx
-+	je	.LSLOW_DECRYPT
-+
-+#--------------------------- SLOW ENCRYPT ---------------------------#
-+	test	\$-16,%r10		# check upon length
-+	mov	0(%rbp),$s0		# load iv
-+	mov	4(%rbp),$s1
-+	mov	8(%rbp),$s2
-+	mov	12(%rbp),$s3
-+	jz	.Lcbc_slow_enc_tail	# short input...
-+
-+.align	4
-+.Lcbc_slow_enc_loop:
-+		xor	0($inp),$s0
-+		xor	4($inp),$s1
-+		xor	8($inp),$s2
-+		xor	12($inp),$s3
-+		mov	$keyp,$key	# restore key
-+		mov	$inp,$_inp	# save inp
-+		mov	$out,$_out	# save out
-+		mov	%r10,$_len	# save len
-+
-+		call	_x86_64_AES_encrypt_compact
-+
-+		mov	$_inp,$inp	# restore inp
-+		mov	$_out,$out	# restore out
-+		mov	$_len,%r10	# restore len
-+		mov	$s0,0($out)
-+		mov	$s1,4($out)
-+		mov	$s2,8($out)
-+		mov	$s3,12($out)
-+
-+		lea	16($inp),$inp
-+		lea	16($out),$out
-+		sub	\$16,%r10
-+		test	\$-16,%r10
-+	jnz	.Lcbc_slow_enc_loop
-+	test	\$15,%r10
-+	jnz	.Lcbc_slow_enc_tail
-+	mov	$_ivp,%rbp	# restore ivp
-+	mov	$s0,0(%rbp)	# save ivec
-+	mov	$s1,4(%rbp)
-+	mov	$s2,8(%rbp)
-+	mov	$s3,12(%rbp)
-+
-+	jmp	.Lcbc_exit
-+
-+.align	4
-+.Lcbc_slow_enc_tail:
-+	mov	%rax,%r11
-+	mov	%rcx,%r12
-+	mov	%r10,%rcx
-+	mov	$inp,%rsi
-+	mov	$out,%rdi
-+	.long	0x9066A4F3		# rep movsb
-+	mov	\$16,%rcx		# zero tail
-+	sub	%r10,%rcx
-+	xor	%rax,%rax
-+	.long	0x9066AAF3		# rep stosb
-+	mov	$out,$inp		# this is not a mistake!
-+	mov	\$16,%r10		# len=16
-+	mov	%r11,%rax
-+	mov	%r12,%rcx
-+	jmp	.Lcbc_slow_enc_loop	# one more spin...
-+#--------------------------- SLOW DECRYPT ---------------------------#
-+.align	16
-+.LSLOW_DECRYPT:
-+	shr	\$3,%rax
-+	add	%rax,$sbox		# recall "magic" constants!
-+
-+	mov	0(%rbp),%r11		# copy iv to stack
-+	mov	8(%rbp),%r12
-+	mov	%r11,0+$ivec
-+	mov	%r12,8+$ivec
-+
-+.align	4
-+.Lcbc_slow_dec_loop:
-+		mov	0($inp),$s0	# load input
-+		mov	4($inp),$s1
-+		mov	8($inp),$s2
-+		mov	12($inp),$s3
-+		mov	$keyp,$key	# restore key
-+		mov	$inp,$_inp	# save inp
-+		mov	$out,$_out	# save out
-+		mov	%r10,$_len	# save len
-+
-+		call	_x86_64_AES_decrypt_compact
-+
-+		mov	$_inp,$inp	# restore inp
-+		mov	$_out,$out	# restore out
-+		mov	$_len,%r10
-+		xor	0+$ivec,$s0
-+		xor	4+$ivec,$s1
-+		xor	8+$ivec,$s2
-+		xor	12+$ivec,$s3
-+
-+		mov	0($inp),%r11	# load input
-+		mov	8($inp),%r12
-+		sub	\$16,%r10
-+		jc	.Lcbc_slow_dec_partial
-+		jz	.Lcbc_slow_dec_done
-+
-+		mov	%r11,0+$ivec	# copy input to iv
-+		mov	%r12,8+$ivec
-+
-+		mov	$s0,0($out)	# save output [can zap input]
-+		mov	$s1,4($out)
-+		mov	$s2,8($out)
-+		mov	$s3,12($out)
-+
-+		lea	16($inp),$inp
-+		lea	16($out),$out
-+	jmp	.Lcbc_slow_dec_loop
-+.Lcbc_slow_dec_done:
-+	mov	$_ivp,%rdi
-+	mov	%r11,0(%rdi)		# copy iv back to user
-+	mov	%r12,8(%rdi)
-+
-+	mov	$s0,0($out)		# save output [can zap input]
-+	mov	$s1,4($out)
-+	mov	$s2,8($out)
-+	mov	$s3,12($out)
-+
-+	jmp	.Lcbc_exit
-+
-+.align	4
-+.Lcbc_slow_dec_partial:
-+	mov	$_ivp,%rdi
-+	mov	%r11,0(%rdi)		# copy iv back to user
-+	mov	%r12,8(%rdi)
-+
-+	mov	$s0,0+$ivec		# save output to stack
-+	mov	$s1,4+$ivec
-+	mov	$s2,8+$ivec
-+	mov	$s3,12+$ivec
-+
-+	mov	$out,%rdi
-+	lea	$ivec,%rsi
-+	lea	16(%r10),%rcx
-+	.long	0x9066A4F3	# rep movsb
-+	jmp	.Lcbc_exit
-+
-+.align	16
-+.Lcbc_exit:
-+	mov	$_rsp,%rsi
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lcbc_popfq:
-+	popfq
-+.Lcbc_epilogue:
-+	ret
-+.size	AES_cbc_encrypt,.-AES_cbc_encrypt
-+___
-+}
-+
-+$code.=<<___;
-+.align	64
-+.LAES_Te:
-+___
-+	&_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6);
-+	&_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591);
-+	&_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56);
-+	&_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec);
-+	&_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa);
-+	&_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb);
-+	&_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45);
-+	&_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b);
-+	&_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c);
-+	&_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83);
-+	&_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9);
-+	&_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a);
-+	&_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d);
-+	&_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f);
-+	&_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df);
-+	&_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea);
-+	&_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34);
-+	&_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b);
-+	&_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d);
-+	&_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413);
-+	&_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1);
-+	&_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6);
-+	&_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972);
-+	&_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85);
-+	&_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed);
-+	&_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511);
-+	&_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe);
-+	&_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b);
-+	&_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05);
-+	&_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1);
-+	&_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142);
-+	&_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf);
-+	&_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3);
-+	&_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e);
-+	&_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a);
-+	&_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6);
-+	&_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3);
-+	&_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b);
-+	&_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428);
-+	&_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad);
-+	&_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14);
-+	&_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8);
-+	&_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4);
-+	&_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2);
-+	&_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda);
-+	&_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949);
-+	&_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf);
-+	&_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810);
-+	&_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c);
-+	&_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697);
-+	&_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e);
-+	&_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f);
-+	&_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc);
-+	&_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c);
-+	&_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969);
-+	&_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27);
-+	&_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122);
-+	&_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433);
-+	&_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9);
-+	&_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5);
-+	&_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a);
-+	&_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0);
-+	&_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e);
-+	&_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c);
-+
-+#Te4	# four copies of Te4 to choose from to avoid L1 aliasing
-+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-+
-+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-+
-+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-+
-+	&data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5);
-+	&data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76);
-+	&data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0);
-+	&data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0);
-+	&data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc);
-+	&data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15);
-+	&data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a);
-+	&data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75);
-+	&data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0);
-+	&data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84);
-+	&data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b);
-+	&data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf);
-+	&data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85);
-+	&data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8);
-+	&data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5);
-+	&data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2);
-+	&data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17);
-+	&data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73);
-+	&data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88);
-+	&data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb);
-+	&data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c);
-+	&data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79);
-+	&data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9);
-+	&data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08);
-+	&data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6);
-+	&data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a);
-+	&data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e);
-+	&data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e);
-+	&data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94);
-+	&data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf);
-+	&data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68);
-+	&data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16);
-+#rcon:
-+$code.=<<___;
-+	.long	0x00000001, 0x00000002, 0x00000004, 0x00000008
-+	.long	0x00000010, 0x00000020, 0x00000040, 0x00000080
-+	.long	0x0000001b, 0x00000036, 0x80808080, 0x80808080
-+	.long	0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b
-+___
-+$code.=<<___;
-+.align	64
-+.LAES_Td:
-+___
-+	&_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a);
-+	&_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b);
-+	&_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5);
-+	&_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5);
-+	&_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d);
-+	&_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b);
-+	&_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295);
-+	&_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e);
-+	&_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927);
-+	&_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d);
-+	&_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362);
-+	&_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9);
-+	&_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52);
-+	&_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566);
-+	&_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3);
-+	&_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed);
-+	&_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e);
-+	&_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4);
-+	&_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4);
-+	&_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd);
-+	&_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d);
-+	&_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060);
-+	&_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967);
-+	&_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879);
-+	&_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000);
-+	&_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c);
-+	&_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36);
-+	&_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624);
-+	&_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b);
-+	&_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c);
-+	&_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12);
-+	&_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14);
-+	&_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3);
-+	&_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b);
-+	&_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8);
-+	&_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684);
-+	&_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7);
-+	&_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177);
-+	&_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947);
-+	&_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322);
-+	&_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498);
-+	&_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f);
-+	&_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54);
-+	&_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382);
-+	&_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf);
-+	&_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb);
-+	&_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83);
-+	&_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef);
-+	&_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029);
-+	&_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235);
-+	&_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733);
-+	&_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117);
-+	&_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4);
-+	&_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546);
-+	&_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb);
-+	&_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d);
-+	&_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb);
-+	&_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a);
-+	&_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773);
-+	&_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478);
-+	&_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2);
-+	&_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff);
-+	&_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664);
-+	&_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0);
-+
-+#Td4:	# four copies of Td4 to choose from to avoid L1 aliasing
-+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-+$code.=<<___;
-+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
-+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
-+___
-+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-+$code.=<<___;
-+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
-+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
-+___
-+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-+$code.=<<___;
-+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
-+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
-+___
-+	&data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38);
-+	&data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb);
-+	&data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87);
-+	&data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb);
-+	&data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d);
-+	&data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e);
-+	&data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2);
-+	&data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25);
-+	&data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16);
-+	&data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92);
-+	&data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda);
-+	&data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84);
-+	&data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a);
-+	&data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06);
-+	&data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02);
-+	&data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b);
-+	&data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea);
-+	&data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73);
-+	&data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85);
-+	&data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e);
-+	&data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89);
-+	&data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b);
-+	&data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20);
-+	&data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4);
-+	&data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31);
-+	&data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f);
-+	&data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d);
-+	&data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef);
-+	&data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0);
-+	&data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61);
-+	&data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26);
-+	&data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d);
-+$code.=<<___;
-+	.long	0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe
-+	.long	0x1b1b1b1b, 0x1b1b1b1b, 0, 0
-+.asciz  "AES for x86_64, CRYPTOGAMS by "
-+.align	64
-+___
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	block_se_handler,\@abi-omnipotent
-+.align	16
-+block_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_block_prologue
-+
-+	mov	24(%rax),%rax		# pull saved real stack pointer
-+	lea	48(%rax),%rax		# adjust...
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lin_block_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	jmp	.Lcommon_seh_exit
-+.size	block_se_handler,.-block_se_handler
-+
-+.type	key_se_handler,\@abi-omnipotent
-+.align	16
-+key_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_key_prologue
-+
-+	lea	56(%rax),%rax
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lin_key_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	jmp	.Lcommon_seh_exit
-+.size	key_se_handler,.-key_se_handler
-+
-+.type	cbc_se_handler,\@abi-omnipotent
-+.align	16
-+cbc_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lcbc_prologue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lcbc_prologue
-+	jb	.Lin_cbc_prologue
-+
-+	lea	.Lcbc_fast_body(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lcbc_fast_body
-+	jb	.Lin_cbc_frame_setup
-+
-+	lea	.Lcbc_slow_prologue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lcbc_slow_prologue
-+	jb	.Lin_cbc_body
-+
-+	lea	.Lcbc_slow_body(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lcbc_slow_body
-+	jb	.Lin_cbc_frame_setup
-+
-+.Lin_cbc_body:
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	lea	.Lcbc_epilogue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip>=.Lcbc_epilogue
-+	jae	.Lin_cbc_prologue
-+
-+	lea	8(%rax),%rax
-+
-+	lea	.Lcbc_popfq(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip>=.Lcbc_popfq
-+	jae	.Lin_cbc_prologue
-+
-+	mov	`16-8`(%rax),%rax	# biased $_rsp
-+	lea	56(%rax),%rax
-+
-+.Lin_cbc_frame_setup:
-+	mov	-16(%rax),%rbx
-+	mov	-24(%rax),%rbp
-+	mov	-32(%rax),%r12
-+	mov	-40(%rax),%r13
-+	mov	-48(%rax),%r14
-+	mov	-56(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lin_cbc_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+.Lcommon_seh_exit:
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	cbc_se_handler,.-cbc_se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_AES_encrypt
-+	.rva	.LSEH_end_AES_encrypt
-+	.rva	.LSEH_info_AES_encrypt
-+
-+	.rva	.LSEH_begin_AES_decrypt
-+	.rva	.LSEH_end_AES_decrypt
-+	.rva	.LSEH_info_AES_decrypt
-+
-+	.rva	.LSEH_begin_AES_set_encrypt_key
-+	.rva	.LSEH_end_AES_set_encrypt_key
-+	.rva	.LSEH_info_AES_set_encrypt_key
-+
-+	.rva	.LSEH_begin_AES_set_decrypt_key
-+	.rva	.LSEH_end_AES_set_decrypt_key
-+	.rva	.LSEH_info_AES_set_decrypt_key
-+
-+	.rva	.LSEH_begin_AES_cbc_encrypt
-+	.rva	.LSEH_end_AES_cbc_encrypt
-+	.rva	.LSEH_info_AES_cbc_encrypt
-+
-+.section	.xdata
-+.align	8
-+.LSEH_info_AES_encrypt:
-+	.byte	9,0,0,0
-+	.rva	block_se_handler
-+	.rva	.Lenc_prologue,.Lenc_epilogue	# HandlerData[]
-+.LSEH_info_AES_decrypt:
-+	.byte	9,0,0,0
-+	.rva	block_se_handler
-+	.rva	.Ldec_prologue,.Ldec_epilogue	# HandlerData[]
-+.LSEH_info_AES_set_encrypt_key:
-+	.byte	9,0,0,0
-+	.rva	key_se_handler
-+	.rva	.Lenc_key_prologue,.Lenc_key_epilogue	# HandlerData[]
-+.LSEH_info_AES_set_decrypt_key:
-+	.byte	9,0,0,0
-+	.rva	key_se_handler
-+	.rva	.Ldec_key_prologue,.Ldec_key_epilogue	# HandlerData[]
-+.LSEH_info_AES_cbc_encrypt:
-+	.byte	9,0,0,0
-+	.rva	cbc_se_handler
-+___
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesfx-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesfx-sparcv9.pl
-new file mode 100644
-index 0000000..04b3cf7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesfx-sparcv9.pl
-@@ -0,0 +1,1270 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# March 2016
-+#
-+# Initial support for Fujitsu SPARC64 X/X+ comprises minimally
-+# required key setup and single-block procedures.
-+#
-+# April 2016
-+#
-+# Add "teaser" CBC and CTR mode-specific subroutines. "Teaser" means
-+# that parallelizeable nature of CBC decrypt and CTR is not utilized
-+# yet. CBC encrypt on the other hand is as good as it can possibly
-+# get processing one byte in 4.1 cycles with 128-bit key on SPARC64 X.
-+# This is ~6x faster than pure software implementation...
-+#
-+# July 2016
-+#
-+# Switch from faligndata to fshiftorx, which allows to omit alignaddr
-+# instructions and improve single-block and short-input performance
-+# with misaligned data.
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+{
-+my ($inp,$out,$key,$rounds,$tmp,$mask) = map("%o$_",(0..5));
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#define LOCALS (STACK_BIAS+STACK_FRAME)
-+
-+.text
-+
-+.globl	aes_fx_encrypt
-+.align	32
-+aes_fx_encrypt:
-+	and		$inp, 7, $tmp		! is input aligned?
-+	andn		$inp, 7, $inp
-+	ldd		[$key +  0], %f6	! round[0]
-+	ldd		[$key +  8], %f8
-+	mov		%o7, %g1
-+	ld		[$key + 240], $rounds
-+
-+1:	call		.+8
-+	add		%o7, .Linp_align-1b, %o7
-+
-+	sll		$tmp, 3, $tmp
-+	ldd		[$inp + 0], %f0		! load input
-+	brz,pt		$tmp, .Lenc_inp_aligned
-+	ldd		[$inp + 8], %f2
-+
-+	ldd		[%o7 + $tmp], %f14	! shift left params
-+	ldd		[$inp + 16], %f4
-+	fshiftorx	%f0, %f2, %f14, %f0
-+	fshiftorx	%f2, %f4, %f14, %f2
-+
-+.Lenc_inp_aligned:
-+	ldd		[$key + 16], %f10	! round[1]
-+	ldd		[$key + 24], %f12
-+
-+	fxor		%f0, %f6, %f0		! ^=round[0]
-+	fxor		%f2, %f8, %f2
-+	ldd		[$key + 32], %f6	! round[2]
-+	ldd		[$key + 40], %f8
-+	add		$key, 32, $key
-+	sub		$rounds, 4, $rounds
-+
-+.Loop_enc:
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$key + 16], %f10
-+	ldd		[$key + 24], %f12
-+	add		$key, 32, $key
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+	ldd		[$key +  0], %f6
-+	ldd		[$key +  8], %f8
-+
-+	brnz,a		$rounds, .Loop_enc
-+	sub		$rounds, 2, $rounds
-+
-+	andcc		$out, 7, $tmp		! is output aligned?
-+	andn		$out, 7, $out
-+	mov		0xff, $mask
-+	srl		$mask, $tmp, $mask
-+	add		%o7, 64, %o7
-+	sll		$tmp, 3, $tmp
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[%o7 + $tmp], %f14	! shift right params
-+
-+	fmovd		%f0, %f4
-+	faesenclx	%f2, %f6, %f0
-+	faesenclx	%f4, %f8, %f2
-+
-+	bnz,pn		%icc, .Lenc_out_unaligned
-+	mov		%g1, %o7
-+
-+	std		%f0, [$out + 0]
-+	retl
-+	std		%f2, [$out + 8]
-+
-+.align	16
-+.Lenc_out_unaligned:
-+	add		$out, 16, $inp
-+	orn		%g0, $mask, $tmp
-+	fshiftorx	%f0, %f0, %f14, %f4
-+	fshiftorx	%f0, %f2, %f14, %f6
-+	fshiftorx	%f2, %f2, %f14, %f8
-+
-+	stda		%f4, [$out + $mask]0xc0	! partial store
-+	std		%f6, [$out + 8]
-+	stda		%f8, [$inp + $tmp]0xc0	! partial store
-+	retl
-+	nop
-+.type	aes_fx_encrypt,#function
-+.size	aes_fx_encrypt,.-aes_fx_encrypt
-+
-+.globl	aes_fx_decrypt
-+.align	32
-+aes_fx_decrypt:
-+	and		$inp, 7, $tmp		! is input aligned?
-+	andn		$inp, 7, $inp
-+	ldd		[$key +  0], %f6	! round[0]
-+	ldd		[$key +  8], %f8
-+	mov		%o7, %g1
-+	ld		[$key + 240], $rounds
-+
-+1:	call		.+8
-+	add		%o7, .Linp_align-1b, %o7
-+
-+	sll		$tmp, 3, $tmp
-+	ldd		[$inp + 0], %f0		! load input
-+	brz,pt		$tmp, .Ldec_inp_aligned
-+	ldd		[$inp + 8], %f2
-+
-+	ldd		[%o7 + $tmp], %f14	! shift left params
-+	ldd		[$inp + 16], %f4
-+	fshiftorx	%f0, %f2, %f14, %f0
-+	fshiftorx	%f2, %f4, %f14, %f2
-+
-+.Ldec_inp_aligned:
-+	ldd		[$key + 16], %f10	! round[1]
-+	ldd		[$key + 24], %f12
-+
-+	fxor		%f0, %f6, %f0		! ^=round[0]
-+	fxor		%f2, %f8, %f2
-+	ldd		[$key + 32], %f6	! round[2]
-+	ldd		[$key + 40], %f8
-+	add		$key, 32, $key
-+	sub		$rounds, 4, $rounds
-+
-+.Loop_dec:
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f10, %f0
-+	faesdecx	%f4, %f12, %f2
-+	ldd		[$key + 16], %f10
-+	ldd		[$key + 24], %f12
-+	add		$key, 32, $key
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f6, %f0
-+	faesdecx	%f4, %f8, %f2
-+	ldd		[$key +  0], %f6
-+	ldd		[$key +  8], %f8
-+
-+	brnz,a		$rounds, .Loop_dec
-+	sub		$rounds, 2, $rounds
-+
-+	andcc		$out, 7, $tmp		! is output aligned?
-+	andn		$out, 7, $out
-+	mov		0xff, $mask
-+	srl		$mask, $tmp, $mask
-+	add		%o7, 64, %o7
-+	sll		$tmp, 3, $tmp
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f10, %f0
-+	faesdecx	%f4, %f12, %f2
-+	ldd		[%o7 + $tmp], %f14	! shift right params
-+
-+	fmovd		%f0, %f4
-+	faesdeclx	%f2, %f6, %f0
-+	faesdeclx	%f4, %f8, %f2
-+
-+	bnz,pn		%icc, .Ldec_out_unaligned
-+	mov		%g1, %o7
-+
-+	std		%f0, [$out + 0]
-+	retl
-+	std		%f2, [$out + 8]
-+
-+.align	16
-+.Ldec_out_unaligned:
-+	add		$out, 16, $inp
-+	orn		%g0, $mask, $tmp
-+	fshiftorx	%f0, %f0, %f14, %f4
-+	fshiftorx	%f0, %f2, %f14, %f6
-+	fshiftorx	%f2, %f2, %f14, %f8
-+
-+	stda		%f4, [$out + $mask]0xc0	! partial store
-+	std		%f6, [$out + 8]
-+	stda		%f8, [$inp + $tmp]0xc0	! partial store
-+	retl
-+	nop
-+.type	aes_fx_decrypt,#function
-+.size	aes_fx_decrypt,.-aes_fx_decrypt
-+___
-+}
-+{
-+my ($inp,$bits,$out,$tmp,$inc) = map("%o$_",(0..5));
-+$code.=<<___;
-+.globl	aes_fx_set_decrypt_key
-+.align	32
-+aes_fx_set_decrypt_key:
-+	b		.Lset_encrypt_key
-+	mov		-1, $inc
-+	retl
-+	nop
-+.type	aes_fx_set_decrypt_key,#function
-+.size	aes_fx_set_decrypt_key,.-aes_fx_set_decrypt_key
-+
-+.globl	aes_fx_set_encrypt_key
-+.align	32
-+aes_fx_set_encrypt_key:
-+	mov		1, $inc
-+	nop
-+.Lset_encrypt_key:
-+	and		$inp, 7, $tmp
-+	andn		$inp, 7, $inp
-+	sll		$tmp, 3, $tmp
-+	mov		%o7, %g1
-+
-+1:	call		.+8
-+	add		%o7, .Linp_align-1b, %o7
-+
-+	ldd		[%o7 + $tmp], %f10	! shift left params
-+	mov		%g1, %o7
-+
-+	cmp		$bits, 192
-+	ldd		[$inp + 0], %f0
-+	bl,pt		%icc, .L128
-+	ldd		[$inp + 8], %f2
-+
-+	be,pt		%icc, .L192
-+	ldd		[$inp + 16], %f4
-+	brz,pt		$tmp, .L256aligned
-+	ldd		[$inp + 24], %f6
-+
-+	ldd		[$inp + 32], %f8
-+	fshiftorx	%f0, %f2, %f10, %f0
-+	fshiftorx	%f2, %f4, %f10, %f2
-+	fshiftorx	%f4, %f6, %f10, %f4
-+	fshiftorx	%f6, %f8, %f10, %f6
-+
-+.L256aligned:
-+	mov		14, $bits
-+	and		$inc, `14*16`, $tmp
-+	st		$bits, [$out + 240]	! store rounds
-+	add		$out, $tmp, $out	! start or end of key schedule
-+	sllx		$inc, 4, $inc		! 16 or -16
-+___
-+for ($i=0; $i<6; $i++) {
-+    $code.=<<___;
-+	std		%f0, [$out + 0]
-+	faeskeyx	%f6, `0x10+$i`, %f0
-+	std		%f2, [$out + 8]
-+	add		$out, $inc, $out
-+	faeskeyx	%f0, 0x00, %f2
-+	std		%f4, [$out + 0]
-+	faeskeyx	%f2, 0x01, %f4
-+	std		%f6, [$out + 8]
-+	add		$out, $inc, $out
-+	faeskeyx	%f4, 0x00, %f6
-+___
-+}
-+$code.=<<___;
-+	std		%f0, [$out + 0]
-+	faeskeyx	%f6, `0x10+$i`, %f0
-+	std		%f2, [$out + 8]
-+	add		$out, $inc, $out
-+	faeskeyx	%f0, 0x00, %f2
-+	std		%f4,[$out + 0]
-+	std		%f6,[$out + 8]
-+	add		$out, $inc, $out
-+	std		%f0,[$out + 0]
-+	std		%f2,[$out + 8]
-+	retl
-+	xor		%o0, %o0, %o0		! return 0
-+
-+.align	16
-+.L192:
-+	brz,pt		$tmp, .L192aligned
-+	nop
-+
-+	ldd		[$inp + 24], %f6
-+	fshiftorx	%f0, %f2, %f10, %f0
-+	fshiftorx	%f2, %f4, %f10, %f2
-+	fshiftorx	%f4, %f6, %f10, %f4
-+
-+.L192aligned:
-+	mov		12, $bits
-+	and		$inc, `12*16`, $tmp
-+	st		$bits, [$out + 240]	! store rounds
-+	add		$out, $tmp, $out	! start or end of key schedule
-+	sllx		$inc, 4, $inc		! 16 or -16
-+___
-+for ($i=0; $i<8; $i+=2) {
-+    $code.=<<___;
-+	std		%f0, [$out + 0]
-+	faeskeyx	%f4, `0x10+$i`, %f0
-+	std		%f2, [$out + 8]
-+	add		$out, $inc, $out
-+	faeskeyx	%f0, 0x00, %f2
-+	std		%f4, [$out + 0]
-+	faeskeyx	%f2, 0x00, %f4
-+	std		%f0, [$out + 8]
-+	add		$out, $inc, $out
-+	faeskeyx	%f4, `0x10+$i+1`, %f0
-+	std		%f2, [$out + 0]
-+	faeskeyx	%f0, 0x00, %f2
-+	std		%f4, [$out + 8]
-+	add		$out, $inc, $out
-+___
-+$code.=<<___		if ($i<6);
-+	faeskeyx	%f2, 0x00, %f4
-+___
-+}
-+$code.=<<___;
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	retl
-+	xor		%o0, %o0, %o0		! return 0
-+
-+.align	16
-+.L128:
-+	brz,pt		$tmp, .L128aligned
-+	nop
-+
-+	ldd		[$inp + 16], %f4
-+	fshiftorx	%f0, %f2, %f10, %f0
-+	fshiftorx	%f2, %f4, %f10, %f2
-+
-+.L128aligned:
-+	mov		10, $bits
-+	and		$inc, `10*16`, $tmp
-+	st		$bits, [$out + 240]	! store rounds
-+	add		$out, $tmp, $out	! start or end of key schedule
-+	sllx		$inc, 4, $inc		! 16 or -16
-+___
-+for ($i=0; $i<10; $i++) {
-+    $code.=<<___;
-+	std		%f0, [$out + 0]
-+	faeskeyx	%f2, `0x10+$i`, %f0
-+	std		%f2, [$out + 8]
-+	add		$out, $inc, $out
-+	faeskeyx	%f0, 0x00, %f2
-+___
-+}
-+$code.=<<___;
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	retl
-+	xor		%o0, %o0, %o0		! return 0
-+.type	aes_fx_set_encrypt_key,#function
-+.size	aes_fx_set_encrypt_key,.-aes_fx_set_encrypt_key
-+___
-+}
-+{
-+my ($inp,$out,$len,$key,$ivp,$dir) = map("%i$_",(0..5));
-+my ($rounds,$inner,$end,$inc,$ialign,$oalign,$mask) = map("%l$_",(0..7));
-+my ($iv0,$iv1,$r0hi,$r0lo,$rlhi,$rllo,$in0,$in1,$intail,$outhead,$fshift)
-+   = map("%f$_",grep { !($_ & 1) } (16 .. 62));
-+my ($ileft,$iright) = ($ialign,$oalign);
-+
-+$code.=<<___;
-+.globl	aes_fx_cbc_encrypt
-+.align	32
-+aes_fx_cbc_encrypt:
-+	save		%sp, -STACK_FRAME-16, %sp
-+	srln		$len, 4, $len
-+	and		$inp, 7, $ialign
-+	andn		$inp, 7, $inp
-+	brz,pn		$len, .Lcbc_no_data
-+	sll		$ialign, 3, $ileft
-+
-+1:	call		.+8
-+	add		%o7, .Linp_align-1b, %o7
-+
-+	ld		[$key + 240], $rounds
-+	and		$out, 7, $oalign
-+	ld		[$ivp + 0], %f0		! load ivec
-+	andn		$out, 7, $out
-+	ld		[$ivp + 4], %f1
-+	sll		$oalign, 3, $mask
-+	ld		[$ivp + 8], %f2
-+	ld		[$ivp + 12], %f3
-+
-+	sll		$rounds, 4, $rounds
-+	add		$rounds, $key, $end
-+	ldd		[$key + 0], $r0hi	! round[0]
-+	ldd		[$key + 8], $r0lo
-+
-+	add		$inp, 16, $inp
-+	sub		$len,  1, $len
-+	ldd		[$end + 0], $rlhi	! round[last]
-+	ldd		[$end + 8], $rllo
-+
-+	mov		16, $inc
-+	movrz		$len, 0, $inc
-+	ldd		[$key + 16], %f10	! round[1]
-+	ldd		[$key + 24], %f12
-+
-+	ldd		[%o7 + $ileft], $fshift	! shift left params
-+	add		%o7, 64, %o7
-+	ldd		[$inp - 16], $in0	! load input
-+	ldd		[$inp -  8], $in1
-+	ldda		[$inp]0x82, $intail	! non-faulting load
-+	brz		$dir, .Lcbc_decrypt
-+	add		$inp, $inc, $inp	! inp+=16
-+
-+	fxor		$r0hi, %f0, %f0		! ivec^=round[0]
-+	fxor		$r0lo, %f2, %f2
-+	fshiftorx	$in0, $in1, $fshift, $in0
-+	fshiftorx	$in1, $intail, $fshift, $in1
-+	nop
-+
-+.Loop_cbc_enc:
-+	fxor		$in0, %f0, %f0		! inp^ivec^round[0]
-+	fxor		$in1, %f2, %f2
-+	ldd		[$key + 32], %f6	! round[2]
-+	ldd		[$key + 40], %f8
-+	add		$key, 32, $end
-+	sub		$rounds, 16*6, $inner
-+
-+.Lcbc_enc:
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10
-+	ldd		[$end + 24], %f12
-+	add		$end, 32, $end
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+	ldd		[$end + 0], %f6
-+	ldd		[$end + 8], %f8
-+
-+	brnz,a		$inner, .Lcbc_enc
-+	sub		$inner, 16*2, $inner
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10	! round[last-1]
-+	ldd		[$end + 24], %f12
-+
-+	movrz		$len, 0, $inc
-+	fmovd		$intail, $in0
-+	ldd		[$inp - 8], $in1	! load next input block
-+	ldda		[$inp]0x82, $intail	! non-faulting load
-+	add		$inp, $inc, $inp	! inp+=16
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+
-+	fshiftorx	$in0, $in1, $fshift, $in0
-+	fshiftorx	$in1, $intail, $fshift, $in1
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$key + 16], %f10	! round[1]
-+	ldd		[$key + 24], %f12
-+
-+	fxor		$r0hi, $in0, $in0	! inp^=round[0]
-+	fxor		$r0lo, $in1, $in1
-+
-+	fmovd		%f0, %f4
-+	faesenclx	%f2, $rlhi, %f0
-+	faesenclx	%f4, $rllo, %f2
-+
-+	brnz,pn		$oalign, .Lcbc_enc_unaligned_out
-+	nop
-+
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	add		$out, 16, $out
-+
-+	brnz,a		$len, .Loop_cbc_enc
-+	sub		$len, 1, $len
-+
-+	st		%f0, [$ivp + 0]		! output ivec
-+	st		%f1, [$ivp + 4]
-+	st		%f2, [$ivp + 8]
-+	st		%f3, [$ivp + 12]
-+
-+.Lcbc_no_data:
-+	ret
-+	restore
-+
-+.align	32
-+.Lcbc_enc_unaligned_out:
-+	ldd		[%o7 + $mask], $fshift	! shift right params
-+	mov		0xff, $mask
-+	srl		$mask, $oalign, $mask
-+	sub		%g0, $ileft, $iright
-+
-+	fshiftorx	%f0, %f0, $fshift, %f6
-+	fshiftorx	%f0, %f2, $fshift, %f8
-+
-+	stda		%f6, [$out + $mask]0xc0	! partial store
-+	orn		%g0, $mask, $mask
-+	std		%f8, [$out + 8]
-+	add		$out, 16, $out
-+	brz		$len, .Lcbc_enc_unaligned_out_done
-+	sub		$len, 1, $len
-+	b		.Loop_cbc_enc_unaligned_out
-+	nop
-+
-+.align	32
-+.Loop_cbc_enc_unaligned_out:
-+	fmovd		%f2, $outhead
-+	fxor		$in0, %f0, %f0		! inp^ivec^round[0]
-+	fxor		$in1, %f2, %f2
-+	ldd		[$key + 32], %f6	! round[2]
-+	ldd		[$key + 40], %f8
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$key + 48], %f10	! round[3]
-+	ldd		[$key + 56], %f12
-+
-+	ldx		[$inp - 16], %o0
-+	ldx		[$inp -  8], %o1
-+	brz		$ileft, .Lcbc_enc_aligned_inp
-+	movrz		$len, 0, $inc
-+
-+	ldx		[$inp], %o2
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	sllx		%o1, $ileft, %o1
-+	or		%g1, %o0, %o0
-+	srlx		%o2, $iright, %o2
-+	or		%o2, %o1, %o1
-+
-+.Lcbc_enc_aligned_inp:
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+	ldd		[$key + 64], %f6	! round[4]
-+	ldd		[$key + 72], %f8
-+	add		$key, 64, $end
-+	sub		$rounds, 16*8, $inner
-+
-+	stx		%o0, [%sp + LOCALS + 0]
-+	stx		%o1, [%sp + LOCALS + 8]
-+	add		$inp, $inc, $inp	! inp+=16
-+	nop
-+
-+.Lcbc_enc_unaligned:
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10
-+	ldd		[$end + 24], %f12
-+	add		$end, 32, $end
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+	ldd		[$end + 0], %f6
-+	ldd		[$end + 8], %f8
-+
-+	brnz,a		$inner, .Lcbc_enc_unaligned
-+	sub		$inner, 16*2, $inner
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10	! round[last-1]
-+	ldd		[$end + 24], %f12
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+
-+	ldd		[%sp + LOCALS + 0], $in0
-+	ldd		[%sp + LOCALS + 8], $in1
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$key + 16], %f10	! round[1]
-+	ldd		[$key + 24], %f12
-+
-+	fxor		$r0hi, $in0, $in0	! inp^=round[0]
-+	fxor		$r0lo, $in1, $in1
-+
-+	fmovd		%f0, %f4
-+	faesenclx	%f2, $rlhi, %f0
-+	faesenclx	%f4, $rllo, %f2
-+
-+	fshiftorx	$outhead, %f0, $fshift, %f6
-+	fshiftorx	%f0, %f2, $fshift, %f8
-+	std		%f6, [$out + 0]
-+	std		%f8, [$out + 8]
-+	add		$out, 16, $out
-+
-+	brnz,a		$len, .Loop_cbc_enc_unaligned_out
-+	sub		$len, 1, $len
-+
-+.Lcbc_enc_unaligned_out_done:
-+	fshiftorx	%f2, %f2, $fshift, %f8
-+	stda		%f8, [$out + $mask]0xc0	! partial store
-+
-+	st		%f0, [$ivp + 0]		! output ivec
-+	st		%f1, [$ivp + 4]
-+	st		%f2, [$ivp + 8]
-+	st		%f3, [$ivp + 12]
-+
-+	ret
-+	restore
-+
-+.align	32
-+.Lcbc_decrypt:
-+	fshiftorx	$in0, $in1, $fshift, $in0
-+	fshiftorx	$in1, $intail, $fshift, $in1
-+	fmovd		%f0, $iv0
-+	fmovd		%f2, $iv1
-+
-+.Loop_cbc_dec:
-+	fxor		$in0, $r0hi, %f0	! inp^round[0]
-+	fxor		$in1, $r0lo, %f2
-+	ldd		[$key + 32], %f6	! round[2]
-+	ldd		[$key + 40], %f8
-+	add		$key, 32, $end
-+	sub		$rounds, 16*6, $inner
-+
-+.Lcbc_dec:
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f10, %f0
-+	faesdecx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10
-+	ldd		[$end + 24], %f12
-+	add		$end, 32, $end
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f6, %f0
-+	faesdecx	%f4, %f8, %f2
-+	ldd		[$end + 0], %f6
-+	ldd		[$end + 8], %f8
-+
-+	brnz,a		$inner, .Lcbc_dec
-+	sub		$inner, 16*2, $inner
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f10, %f0
-+	faesdecx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10	! round[last-1]
-+	ldd		[$end + 24], %f12
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f6, %f0
-+	faesdecx	%f4, %f8, %f2
-+	fxor		$iv0, $rlhi, %f6	! ivec^round[last]
-+	fxor		$iv1, $rllo, %f8
-+	fmovd		$in0, $iv0
-+	fmovd		$in1, $iv1
-+
-+	movrz		$len, 0, $inc
-+	fmovd		$intail, $in0
-+	ldd		[$inp - 8], $in1	! load next input block
-+	ldda		[$inp]0x82, $intail	! non-faulting load
-+	add		$inp, $inc, $inp	! inp+=16
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f10, %f0
-+	faesdecx	%f4, %f12, %f2
-+	ldd		[$key + 16], %f10	! round[1]
-+	ldd		[$key + 24], %f12
-+
-+	fshiftorx	$in0, $in1, $fshift, $in0
-+	fshiftorx	$in1, $intail, $fshift, $in1
-+
-+	fmovd		%f0, %f4
-+	faesdeclx	%f2, %f6, %f0
-+	faesdeclx	%f4, %f8, %f2
-+
-+	brnz,pn		$oalign, .Lcbc_dec_unaligned_out
-+	nop
-+
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	add		$out, 16, $out
-+
-+	brnz,a		$len, .Loop_cbc_dec
-+	sub		$len, 1, $len
-+
-+	st		$iv0,    [$ivp + 0]	! output ivec
-+	st		$iv0#lo, [$ivp + 4]
-+	st		$iv1,    [$ivp + 8]
-+	st		$iv1#lo, [$ivp + 12]
-+
-+	ret
-+	restore
-+
-+.align	32
-+.Lcbc_dec_unaligned_out:
-+	ldd		[%o7 + $mask], $fshift	! shift right params
-+	mov		0xff, $mask
-+	srl		$mask, $oalign, $mask
-+	sub		%g0, $ileft, $iright
-+
-+	fshiftorx	%f0, %f0, $fshift, %f6
-+	fshiftorx	%f0, %f2, $fshift, %f8
-+
-+	stda		%f6, [$out + $mask]0xc0	! partial store
-+	orn		%g0, $mask, $mask
-+	std		%f8, [$out + 8]
-+	add		$out, 16, $out
-+	brz		$len, .Lcbc_dec_unaligned_out_done
-+	sub		$len, 1, $len
-+	b		.Loop_cbc_dec_unaligned_out
-+	nop
-+
-+.align	32
-+.Loop_cbc_dec_unaligned_out:
-+	fmovd		%f2, $outhead
-+	fxor		$in0, $r0hi, %f0	! inp^round[0]
-+	fxor		$in1, $r0lo, %f2
-+	ldd		[$key + 32], %f6	! round[2]
-+	ldd		[$key + 40], %f8
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f10, %f0
-+	faesdecx	%f4, %f12, %f2
-+	ldd		[$key + 48], %f10	! round[3]
-+	ldd		[$key + 56], %f12
-+
-+	ldx		[$inp - 16], %o0
-+	ldx		[$inp - 8], %o1
-+	brz		$ileft, .Lcbc_dec_aligned_inp
-+	movrz		$len, 0, $inc
-+
-+	ldx		[$inp], %o2
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	sllx		%o1, $ileft, %o1
-+	or		%g1, %o0, %o0
-+	srlx		%o2, $iright, %o2
-+	or		%o2, %o1, %o1
-+
-+.Lcbc_dec_aligned_inp:
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f6, %f0
-+	faesdecx	%f4, %f8, %f2
-+	ldd		[$key + 64], %f6	! round[4]
-+	ldd		[$key + 72], %f8
-+	add		$key, 64, $end
-+	sub		$rounds, 16*8, $inner
-+
-+	stx		%o0, [%sp + LOCALS + 0]
-+	stx		%o1, [%sp + LOCALS + 8]
-+	add		$inp, $inc, $inp	! inp+=16
-+	nop
-+
-+.Lcbc_dec_unaligned:
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f10, %f0
-+	faesdecx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10
-+	ldd		[$end + 24], %f12
-+	add		$end, 32, $end
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f6, %f0
-+	faesdecx	%f4, %f8, %f2
-+	ldd		[$end + 0], %f6
-+	ldd		[$end + 8], %f8
-+
-+	brnz,a		$inner, .Lcbc_dec_unaligned
-+	sub		$inner, 16*2, $inner
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f10, %f0
-+	faesdecx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10	! round[last-1]
-+	ldd		[$end + 24], %f12
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f6, %f0
-+	faesdecx	%f4, %f8, %f2
-+
-+	fxor		$iv0, $rlhi, %f6	! ivec^round[last]
-+	fxor		$iv1, $rllo, %f8
-+	fmovd		$in0, $iv0
-+	fmovd		$in1, $iv1
-+	ldd		[%sp + LOCALS + 0], $in0
-+	ldd		[%sp + LOCALS + 8], $in1
-+
-+	fmovd		%f0, %f4
-+	faesdecx	%f2, %f10, %f0
-+	faesdecx	%f4, %f12, %f2
-+	ldd		[$key + 16], %f10	! round[1]
-+	ldd		[$key + 24], %f12
-+
-+	fmovd		%f0, %f4
-+	faesdeclx	%f2, %f6, %f0
-+	faesdeclx	%f4, %f8, %f2
-+
-+	fshiftorx	$outhead, %f0, $fshift, %f6
-+	fshiftorx	%f0, %f2, $fshift, %f8
-+	std		%f6, [$out + 0]
-+	std		%f8, [$out + 8]
-+	add		$out, 16, $out
-+
-+	brnz,a		$len, .Loop_cbc_dec_unaligned_out
-+	sub		$len, 1, $len
-+
-+.Lcbc_dec_unaligned_out_done:
-+	fshiftorx	%f2, %f2, $fshift, %f8
-+	stda		%f8, [$out + $mask]0xc0	! partial store
-+
-+	st		$iv0,    [$ivp + 0]	! output ivec
-+	st		$iv0#lo, [$ivp + 4]
-+	st		$iv1,    [$ivp + 8]
-+	st		$iv1#lo, [$ivp + 12]
-+
-+	ret
-+	restore
-+.type	aes_fx_cbc_encrypt,#function
-+.size	aes_fx_cbc_encrypt,.-aes_fx_cbc_encrypt
-+___
-+}
-+{
-+my ($inp,$out,$len,$key,$ivp) = map("%i$_",(0..5));
-+my ($rounds,$inner,$end,$inc,$ialign,$oalign,$mask) = map("%l$_",(0..7));
-+my ($ctr0,$ctr1,$r0hi,$r0lo,$rlhi,$rllo,$in0,$in1,$intail,$outhead,$fshift)
-+   = map("%f$_",grep { !($_ & 1) } (16 .. 62));
-+my ($ileft,$iright) = ($ialign, $oalign);
-+my $one = "%f14";
-+
-+$code.=<<___;
-+.globl	aes_fx_ctr32_encrypt_blocks
-+.align	32
-+aes_fx_ctr32_encrypt_blocks:
-+	save		%sp, -STACK_FRAME-16, %sp
-+	srln		$len, 0, $len
-+	and		$inp, 7, $ialign
-+	andn		$inp, 7, $inp
-+	brz,pn		$len, .Lctr32_no_data
-+	sll		$ialign, 3, $ileft
-+
-+.Lpic:	call		.+8
-+	add		%o7, .Linp_align - .Lpic, %o7
-+
-+	ld		[$key + 240], $rounds
-+	and		$out, 7, $oalign
-+	ld		[$ivp +  0], $ctr0	! load counter
-+	andn		$out, 7, $out
-+	ld		[$ivp +  4], $ctr0#lo
-+	sll		$oalign, 3, $mask
-+	ld		[$ivp +  8], $ctr1
-+	ld		[$ivp + 12], $ctr1#lo
-+	ldd		[%o7 + 128], $one
-+
-+	sll		$rounds, 4, $rounds
-+	add		$rounds, $key, $end
-+	ldd		[$key + 0], $r0hi	! round[0]
-+	ldd		[$key + 8], $r0lo
-+
-+	add		$inp, 16, $inp
-+	sub		$len, 1, $len
-+	ldd		[$key + 16], %f10	! round[1]
-+	ldd		[$key + 24], %f12
-+
-+	mov		16, $inc
-+	movrz		$len, 0, $inc
-+	ldd		[$end + 0], $rlhi	! round[last]
-+	ldd		[$end + 8], $rllo
-+
-+	ldd		[%o7 + $ileft], $fshift	! shiftleft params
-+	add		%o7, 64, %o7
-+	ldd		[$inp - 16], $in0	! load input
-+	ldd		[$inp -  8], $in1
-+	ldda		[$inp]0x82, $intail	! non-faulting load
-+	add		$inp, $inc, $inp	! inp+=16
-+
-+	fshiftorx	$in0, $in1, $fshift, $in0
-+	fshiftorx	$in1, $intail, $fshift, $in1
-+
-+.Loop_ctr32:
-+	fxor		$ctr0, $r0hi, %f0	! counter^round[0]
-+	fxor		$ctr1, $r0lo, %f2
-+	ldd		[$key + 32], %f6	! round[2]
-+	ldd		[$key + 40], %f8
-+	add		$key, 32, $end
-+	sub		$rounds, 16*6, $inner
-+
-+.Lctr32_enc:
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10
-+	ldd		[$end + 24], %f12
-+	add		$end, 32, $end
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+	ldd		[$end + 0], %f6
-+	ldd		[$end + 8], %f8
-+
-+	brnz,a		$inner, .Lctr32_enc
-+	sub		$inner, 16*2, $inner
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10	! round[last-1]
-+	ldd		[$end + 24], %f12
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+	fxor		$in0, $rlhi, %f6	! inp^round[last]
-+	fxor		$in1, $rllo, %f8
-+
-+	movrz		$len, 0, $inc
-+	fmovd		$intail, $in0
-+	ldd		[$inp - 8], $in1	! load next input block
-+	ldda		[$inp]0x82, $intail	! non-faulting load
-+	add		$inp, $inc, $inp	! inp+=16
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$key + 16], %f10	! round[1]
-+	ldd		[$key + 24], %f12
-+
-+	fshiftorx	$in0, $in1, $fshift, $in0
-+	fshiftorx	$in1, $intail, $fshift, $in1
-+	fpadd32		$ctr1, $one, $ctr1	! increment counter
-+
-+	fmovd		%f0, %f4
-+	faesenclx	%f2, %f6, %f0
-+	faesenclx	%f4, %f8, %f2
-+
-+	brnz,pn		$oalign, .Lctr32_unaligned_out
-+	nop
-+
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	add		$out, 16, $out
-+
-+	brnz,a		$len, .Loop_ctr32
-+	sub		$len, 1, $len
-+
-+.Lctr32_no_data:
-+	ret
-+	restore
-+
-+.align	32
-+.Lctr32_unaligned_out:
-+	ldd		[%o7 + $mask], $fshift	! shift right params
-+	mov		0xff, $mask
-+	srl		$mask, $oalign, $mask
-+	sub		%g0, $ileft, $iright
-+
-+	fshiftorx	%f0, %f0, $fshift, %f6
-+	fshiftorx	%f0, %f2, $fshift, %f8
-+
-+	stda		%f6, [$out + $mask]0xc0	! partial store
-+	orn		%g0, $mask, $mask
-+	std		%f8, [$out + 8]
-+	add		$out, 16, $out
-+	brz		$len, .Lctr32_unaligned_out_done
-+	sub		$len, 1, $len
-+	b		.Loop_ctr32_unaligned_out
-+	nop
-+
-+.align	32
-+.Loop_ctr32_unaligned_out:
-+	fmovd		%f2, $outhead
-+	fxor		$ctr0, $r0hi, %f0	! counter^round[0]
-+	fxor		$ctr1, $r0lo, %f2
-+	ldd		[$key + 32], %f6	! round[2]
-+	ldd		[$key + 40], %f8
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$key + 48], %f10	! round[3]
-+	ldd		[$key + 56], %f12
-+
-+	ldx		[$inp - 16], %o0
-+	ldx		[$inp -  8], %o1
-+	brz		$ileft, .Lctr32_aligned_inp
-+	movrz		$len, 0, $inc
-+
-+	ldx		[$inp], %o2
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	sllx		%o1, $ileft, %o1
-+	or		%g1, %o0, %o0
-+	srlx		%o2, $iright, %o2
-+	or		%o2, %o1, %o1
-+
-+.Lctr32_aligned_inp:
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+	ldd		[$key + 64], %f6	! round[4]
-+	ldd		[$key + 72], %f8
-+	add		$key, 64, $end
-+	sub		$rounds, 16*8, $inner
-+
-+	stx		%o0, [%sp + LOCALS + 0]
-+	stx		%o1, [%sp + LOCALS + 8]
-+	add		$inp, $inc, $inp	! inp+=16
-+	nop
-+
-+.Lctr32_enc_unaligned:
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10
-+	ldd		[$end + 24], %f12
-+	add		$end, 32, $end
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+	ldd		[$end + 0], %f6
-+	ldd		[$end + 8], %f8
-+
-+	brnz,a		$inner, .Lctr32_enc_unaligned
-+	sub		$inner, 16*2, $inner
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$end + 16], %f10	! round[last-1]
-+	ldd		[$end + 24], %f12
-+	fpadd32		$ctr1, $one, $ctr1	! increment counter
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f6, %f0
-+	faesencx	%f4, %f8, %f2
-+	fxor		$in0, $rlhi, %f6	! inp^round[last]
-+	fxor		$in1, $rllo, %f8
-+	ldd		[%sp + LOCALS + 0], $in0
-+	ldd		[%sp + LOCALS + 8], $in1
-+
-+	fmovd		%f0, %f4
-+	faesencx	%f2, %f10, %f0
-+	faesencx	%f4, %f12, %f2
-+	ldd		[$key + 16], %f10	! round[1]
-+	ldd		[$key + 24], %f12
-+
-+	fmovd		%f0, %f4
-+	faesenclx	%f2, %f6, %f0
-+	faesenclx	%f4, %f8, %f2
-+
-+	fshiftorx	$outhead, %f0, $fshift, %f6
-+	fshiftorx	%f0, %f2, $fshift, %f8
-+	std		%f6, [$out + 0]
-+	std		%f8, [$out + 8]
-+	add		$out, 16, $out
-+
-+	brnz,a		$len, .Loop_ctr32_unaligned_out
-+	sub		$len, 1, $len
-+
-+.Lctr32_unaligned_out_done:
-+	fshiftorx	%f2, %f2, $fshift, %f8
-+	stda		%f8, [$out + $mask]0xc0	! partial store
-+
-+	ret
-+	restore
-+.type	aes_fx_ctr32_encrypt_blocks,#function
-+.size	aes_fx_ctr32_encrypt_blocks,.-aes_fx_ctr32_encrypt_blocks
-+
-+.align	32
-+.Linp_align:		! fshiftorx parameters for left shift toward %rs1
-+	.byte	0, 0, 64,  0,	0, 64,  0, -64
-+	.byte	0, 0, 56,  8,	0, 56,  8, -56
-+	.byte	0, 0, 48, 16,	0, 48, 16, -48
-+	.byte	0, 0, 40, 24,	0, 40, 24, -40
-+	.byte	0, 0, 32, 32,	0, 32, 32, -32
-+	.byte	0, 0, 24, 40,	0, 24, 40, -24
-+	.byte	0, 0, 16, 48,	0, 16, 48, -16
-+	.byte	0, 0,  8, 56,	0,  8, 56, -8
-+.Lout_align:		! fshiftorx parameters for right shift toward %rs2
-+	.byte	0, 0,  0, 64,	0,  0, 64,   0
-+	.byte	0, 0,  8, 56,	0,  8, 56,  -8
-+	.byte	0, 0, 16, 48,	0, 16, 48, -16
-+	.byte	0, 0, 24, 40,	0, 24, 40, -24
-+	.byte	0, 0, 32, 32,	0, 32, 32, -32
-+	.byte	0, 0, 40, 24,	0, 40, 24, -40
-+	.byte	0, 0, 48, 16,	0, 48, 16, -48
-+	.byte	0, 0, 56,  8,	0, 56,  8, -56
-+.Lone:
-+	.word	0, 1
-+.asciz	"AES for Fujitsu SPARC64 X, CRYPTOGAMS by "
-+.align	4
-+___
-+}
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my ($ref,$opf);
-+my %visopf = (	"faligndata"	=> 0x048,
-+		"bshuffle"	=> 0x04c,
-+		"fpadd32"	=> 0x052,
-+		"fxor"		=> 0x06c,
-+		"fsrc2"		=> 0x078	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub unvis3 {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my ($ref,$opf);
-+my %visopf = (	"alignaddr"	=> 0x018,
-+		"bmask"		=> 0x019,
-+		"alignaddrl"	=> 0x01a	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%([goli])([0-9])/);
-+	    $_=$bias{$1}+$2;
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub unfx {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my ($ref,$opf);
-+my %aesopf = (	"faesencx"	=> 0x90,
-+		"faesdecx"	=> 0x91,
-+		"faesenclx"	=> 0x92,
-+		"faesdeclx"	=> 0x93,
-+		"faeskeyx"	=> 0x94	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if (defined($opf=$aesopf{$mnemonic})) {
-+	$rs2 = ($rs2 =~ /%f([0-6]*[02468])/) ? (($1|$1>>5)&31) : $rs2;
-+	$rs2 = oct($rs2) if ($rs2 =~ /^0/);
-+
-+	foreach ($rs1,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			2<<30|$rd<<25|0x36<<19|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub unfx3src {
-+my ($mnemonic,$rs1,$rs2,$rs3,$rd)=@_;
-+my ($ref,$opf);
-+my %aesopf = (	"fshiftorx"	=> 0x0b	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rs3,$rd";
-+
-+    if (defined($opf=$aesopf{$mnemonic})) {
-+	foreach ($rs1,$rs2,$rs3,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			2<<30|$rd<<25|0x37<<19|$rs1<<14|$rs3<<9|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+foreach (split("\n",$code)) {
-+    s/\`([^\`]*)\`/eval $1/ge;
-+
-+    s/%f([0-9]+)#lo/sprintf "%%f%d",$1+1/ge;
-+
-+    s/\b(faes[^x]{3,4}x)\s+(%f[0-9]{1,2}),\s*([%fx0-9]+),\s*(%f[0-9]{1,2})/
-+		&unfx($1,$2,$3,$4)
-+     /ge or
-+    s/\b([f][^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-+		&unfx3src($1,$2,$3,$4,$5)
-+     /ge or
-+    s/\b([fb][^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-+		&unvis($1,$2,$3,$4)
-+     /ge or
-+    s/\b(alignaddr[l]*)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+		&unvis3($1,$2,$3,$4)
-+     /ge;
-+    print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-mb-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-mb-x86_64.pl
-new file mode 100644
-index 0000000..aa2735e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-mb-x86_64.pl
-@@ -0,0 +1,1402 @@
-+#! /usr/bin/env perl
-+# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# Multi-buffer AES-NI procedures process several independent buffers
-+# in parallel by interleaving independent instructions.
-+#
-+# Cycles per byte for interleave factor 4:
-+#
-+#			asymptotic	measured
-+#			---------------------------
-+# Westmere		5.00/4=1.25	5.13/4=1.28
-+# Atom			15.0/4=3.75	?15.7/4=3.93
-+# Sandy Bridge		5.06/4=1.27	5.18/4=1.29
-+# Ivy Bridge		5.06/4=1.27	5.14/4=1.29
-+# Haswell		4.44/4=1.11	4.44/4=1.11
-+# Bulldozer		5.75/4=1.44	5.76/4=1.44
-+#
-+# Cycles per byte for interleave factor 8 (not implemented for
-+# pre-AVX processors, where higher interleave factor incidentally
-+# doesn't result in improvement):
-+#
-+#			asymptotic	measured
-+#			---------------------------
-+# Sandy Bridge		5.06/8=0.64	7.10/8=0.89(*)
-+# Ivy Bridge		5.06/8=0.64	7.14/8=0.89(*)
-+# Haswell		5.00/8=0.63	5.00/8=0.63
-+# Bulldozer		5.75/8=0.72	5.77/8=0.72
-+#
-+# (*)	Sandy/Ivy Bridge are known to handle high interleave factors
-+#	suboptimally;
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+$avx=0;
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	   `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+# void aesni_multi_cbc_encrypt (
-+#     struct {	void *inp,*out; int blocks; double iv[2]; } inp[8];
-+#     const AES_KEY *key,
-+#     int num);		/* 1 or 2 */
-+#
-+$inp="%rdi";	# 1st arg
-+$key="%rsi";	# 2nd arg
-+$num="%edx";
-+
-+@inptr=map("%r$_",(8..11));
-+@outptr=map("%r$_",(12..15));
-+
-+($rndkey0,$rndkey1)=("%xmm0","%xmm1");
-+@out=map("%xmm$_",(2..5));
-+@inp=map("%xmm$_",(6..9));
-+($counters,$mask,$zero)=map("%xmm$_",(10..12));
-+
-+($rounds,$one,$sink,$offset)=("%eax","%ecx","%rbp","%rbx");
-+
-+$code.=<<___;
-+.text
-+
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	aesni_multi_cbc_encrypt
-+.type	aesni_multi_cbc_encrypt,\@function,3
-+.align	32
-+aesni_multi_cbc_encrypt:
-+___
-+$code.=<<___ if ($avx);
-+	cmp	\$2,$num
-+	jb	.Lenc_non_avx
-+	mov	OPENSSL_ia32cap_P+4(%rip),%ecx
-+	test	\$`1<<28`,%ecx			# AVX bit
-+	jnz	_avx_cbc_enc_shortcut
-+	jmp	.Lenc_non_avx
-+.align	16
-+.Lenc_non_avx:
-+___
-+$code.=<<___;
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,0x40(%rsp)
-+	movaps	%xmm11,0x50(%rsp)
-+	movaps	%xmm12,0x60(%rsp)
-+	movaps	%xmm13,-0x68(%rax)	# not used, saved to share se_handler 
-+	movaps	%xmm14,-0x58(%rax)
-+	movaps	%xmm15,-0x48(%rax)
-+___
-+$code.=<<___;
-+	# stack layout
-+	#
-+	# +0	output sink
-+	# +16	input sink [original %rsp and $num]
-+	# +32	counters
-+
-+	sub	\$48,%rsp
-+	and	\$-64,%rsp
-+	mov	%rax,16(%rsp)			# original %rsp
-+
-+.Lenc4x_body:
-+	movdqu	($key),$zero			# 0-round key
-+	lea	0x78($key),$key			# size optimization
-+	lea	40*2($inp),$inp
-+
-+.Lenc4x_loop_grande:
-+	mov	$num,24(%rsp)			# original $num
-+	xor	$num,$num
-+___
-+for($i=0;$i<4;$i++) {
-+    $code.=<<___;
-+	mov	`40*$i+16-40*2`($inp),$one	# borrow $one for number of blocks
-+	mov	`40*$i+0-40*2`($inp),@inptr[$i]
-+	cmp	$num,$one
-+	mov	`40*$i+8-40*2`($inp),@outptr[$i]
-+	cmovg	$one,$num			# find maximum
-+	test	$one,$one
-+	movdqu	`40*$i+24-40*2`($inp),@out[$i]	# load IV
-+	mov	$one,`32+4*$i`(%rsp)		# initialize counters
-+	cmovle	%rsp,@inptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	test	$num,$num
-+	jz	.Lenc4x_done
-+
-+	movups	0x10-0x78($key),$rndkey1
-+	 pxor	$zero,@out[0]
-+	movups	0x20-0x78($key),$rndkey0
-+	 pxor	$zero,@out[1]
-+	mov	0xf0-0x78($key),$rounds
-+	 pxor	$zero,@out[2]
-+	movdqu	(@inptr[0]),@inp[0]		# load inputs
-+	 pxor	$zero,@out[3]
-+	movdqu	(@inptr[1]),@inp[1]
-+	 pxor	@inp[0],@out[0]
-+	movdqu	(@inptr[2]),@inp[2]
-+	 pxor	@inp[1],@out[1]
-+	movdqu	(@inptr[3]),@inp[3]
-+	 pxor	@inp[2],@out[2]
-+	 pxor	@inp[3],@out[3]
-+	movdqa	32(%rsp),$counters		# load counters
-+	xor	$offset,$offset
-+	jmp	.Loop_enc4x
-+
-+.align	32
-+.Loop_enc4x:
-+	add	\$16,$offset
-+	lea	16(%rsp),$sink			# sink pointer
-+	mov	\$1,$one			# constant of 1
-+	sub	$offset,$sink
-+
-+	aesenc		$rndkey1,@out[0]
-+	prefetcht0	31(@inptr[0],$offset)	# prefetch input
-+	prefetcht0	31(@inptr[1],$offset)
-+	aesenc		$rndkey1,@out[1]
-+	prefetcht0	31(@inptr[2],$offset)
-+	prefetcht0	31(@inptr[2],$offset)
-+	aesenc		$rndkey1,@out[2]
-+	aesenc		$rndkey1,@out[3]
-+	movups		0x30-0x78($key),$rndkey1
-+___
-+for($i=0;$i<4;$i++) {
-+my $rndkey = ($i&1) ? $rndkey1 : $rndkey0;
-+$code.=<<___;
-+	 cmp		`32+4*$i`(%rsp),$one
-+	aesenc		$rndkey,@out[0]
-+	aesenc		$rndkey,@out[1]
-+	aesenc		$rndkey,@out[2]
-+	 cmovge		$sink,@inptr[$i]	# cancel input
-+	 cmovg		$sink,@outptr[$i]	# sink output
-+	aesenc		$rndkey,@out[3]
-+	movups		`0x40+16*$i-0x78`($key),$rndkey
-+___
-+}
-+$code.=<<___;
-+	 movdqa		$counters,$mask
-+	aesenc		$rndkey0,@out[0]
-+	prefetcht0	15(@outptr[0],$offset)	# prefetch output
-+	prefetcht0	15(@outptr[1],$offset)
-+	aesenc		$rndkey0,@out[1]
-+	prefetcht0	15(@outptr[2],$offset)
-+	prefetcht0	15(@outptr[3],$offset)
-+	aesenc		$rndkey0,@out[2]
-+	aesenc		$rndkey0,@out[3]
-+	movups		0x80-0x78($key),$rndkey0
-+	 pxor		$zero,$zero
-+
-+	aesenc		$rndkey1,@out[0]
-+	 pcmpgtd	$zero,$mask
-+	 movdqu		-0x78($key),$zero	# reload 0-round key
-+	aesenc		$rndkey1,@out[1]
-+	 paddd		$mask,$counters		# decrement counters
-+	 movdqa		$counters,32(%rsp)	# update counters
-+	aesenc		$rndkey1,@out[2]
-+	aesenc		$rndkey1,@out[3]
-+	movups		0x90-0x78($key),$rndkey1
-+
-+	cmp	\$11,$rounds
-+
-+	aesenc		$rndkey0,@out[0]
-+	aesenc		$rndkey0,@out[1]
-+	aesenc		$rndkey0,@out[2]
-+	aesenc		$rndkey0,@out[3]
-+	movups		0xa0-0x78($key),$rndkey0
-+
-+	jb	.Lenc4x_tail
-+
-+	aesenc		$rndkey1,@out[0]
-+	aesenc		$rndkey1,@out[1]
-+	aesenc		$rndkey1,@out[2]
-+	aesenc		$rndkey1,@out[3]
-+	movups		0xb0-0x78($key),$rndkey1
-+
-+	aesenc		$rndkey0,@out[0]
-+	aesenc		$rndkey0,@out[1]
-+	aesenc		$rndkey0,@out[2]
-+	aesenc		$rndkey0,@out[3]
-+	movups		0xc0-0x78($key),$rndkey0
-+
-+	je	.Lenc4x_tail
-+
-+	aesenc		$rndkey1,@out[0]
-+	aesenc		$rndkey1,@out[1]
-+	aesenc		$rndkey1,@out[2]
-+	aesenc		$rndkey1,@out[3]
-+	movups		0xd0-0x78($key),$rndkey1
-+
-+	aesenc		$rndkey0,@out[0]
-+	aesenc		$rndkey0,@out[1]
-+	aesenc		$rndkey0,@out[2]
-+	aesenc		$rndkey0,@out[3]
-+	movups		0xe0-0x78($key),$rndkey0
-+	jmp	.Lenc4x_tail
-+
-+.align	32
-+.Lenc4x_tail:
-+	aesenc		$rndkey1,@out[0]
-+	aesenc		$rndkey1,@out[1]
-+	aesenc		$rndkey1,@out[2]
-+	aesenc		$rndkey1,@out[3]
-+	 movdqu		(@inptr[0],$offset),@inp[0]
-+	movdqu		0x10-0x78($key),$rndkey1
-+
-+	aesenclast	$rndkey0,@out[0]
-+	 movdqu		(@inptr[1],$offset),@inp[1]
-+	 pxor		$zero,@inp[0]
-+	aesenclast	$rndkey0,@out[1]
-+	 movdqu		(@inptr[2],$offset),@inp[2]
-+	 pxor		$zero,@inp[1]
-+	aesenclast	$rndkey0,@out[2]
-+	 movdqu		(@inptr[3],$offset),@inp[3]
-+	 pxor		$zero,@inp[2]
-+	aesenclast	$rndkey0,@out[3]
-+	movdqu		0x20-0x78($key),$rndkey0
-+	 pxor		$zero,@inp[3]
-+
-+	movups		@out[0],-16(@outptr[0],$offset)
-+	 pxor		@inp[0],@out[0]
-+	movups		@out[1],-16(@outptr[1],$offset)	
-+	 pxor		@inp[1],@out[1]
-+	movups		@out[2],-16(@outptr[2],$offset)	
-+	 pxor		@inp[2],@out[2]
-+	movups		@out[3],-16(@outptr[3],$offset)
-+	 pxor		@inp[3],@out[3]
-+
-+	dec	$num
-+	jnz	.Loop_enc4x
-+
-+	mov	16(%rsp),%rax			# original %rsp
-+	mov	24(%rsp),$num
-+
-+	#pxor	@inp[0],@out[0]
-+	#pxor	@inp[1],@out[1]
-+	#movdqu	@out[0],`40*0+24-40*2`($inp)	# output iv FIX ME!
-+	#pxor	@inp[2],@out[2]
-+	#movdqu	@out[1],`40*1+24-40*2`($inp)
-+	#pxor	@inp[3],@out[3]
-+	#movdqu	@out[2],`40*2+24-40*2`($inp)	# won't fix, let caller
-+	#movdqu	@out[3],`40*3+24-40*2`($inp)	# figure this out...
-+
-+	lea	`40*4`($inp),$inp
-+	dec	$num
-+	jnz	.Lenc4x_loop_grande
-+
-+.Lenc4x_done:
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xd8(%rax),%xmm6
-+	movaps	-0xc8(%rax),%xmm7
-+	movaps	-0xb8(%rax),%xmm8
-+	movaps	-0xa8(%rax),%xmm9
-+	movaps	-0x98(%rax),%xmm10
-+	movaps	-0x88(%rax),%xmm11
-+	movaps	-0x78(%rax),%xmm12
-+	#movaps	-0x68(%rax),%xmm13
-+	#movaps	-0x58(%rax),%xmm14
-+	#movaps	-0x48(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Lenc4x_epilogue:
-+	ret
-+.size	aesni_multi_cbc_encrypt,.-aesni_multi_cbc_encrypt
-+
-+.globl	aesni_multi_cbc_decrypt
-+.type	aesni_multi_cbc_decrypt,\@function,3
-+.align	32
-+aesni_multi_cbc_decrypt:
-+___
-+$code.=<<___ if ($avx);
-+	cmp	\$2,$num
-+	jb	.Ldec_non_avx
-+	mov	OPENSSL_ia32cap_P+4(%rip),%ecx
-+	test	\$`1<<28`,%ecx			# AVX bit
-+	jnz	_avx_cbc_dec_shortcut
-+	jmp	.Ldec_non_avx
-+.align	16
-+.Ldec_non_avx:
-+___
-+$code.=<<___;
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,0x40(%rsp)
-+	movaps	%xmm11,0x50(%rsp)
-+	movaps	%xmm12,0x60(%rsp)
-+	movaps	%xmm13,-0x68(%rax)	# not used, saved to share se_handler 
-+	movaps	%xmm14,-0x58(%rax)
-+	movaps	%xmm15,-0x48(%rax)
-+___
-+$code.=<<___;
-+	# stack layout
-+	#
-+	# +0	output sink
-+	# +16	input sink [original %rsp and $num]
-+	# +32	counters
-+
-+	sub	\$48,%rsp
-+	and	\$-64,%rsp
-+	mov	%rax,16(%rsp)			# original %rsp
-+
-+.Ldec4x_body:
-+	movdqu	($key),$zero			# 0-round key
-+	lea	0x78($key),$key			# size optimization
-+	lea	40*2($inp),$inp
-+
-+.Ldec4x_loop_grande:
-+	mov	$num,24(%rsp)			# original $num
-+	xor	$num,$num
-+___
-+for($i=0;$i<4;$i++) {
-+    $code.=<<___;
-+	mov	`40*$i+16-40*2`($inp),$one	# borrow $one for number of blocks
-+	mov	`40*$i+0-40*2`($inp),@inptr[$i]
-+	cmp	$num,$one
-+	mov	`40*$i+8-40*2`($inp),@outptr[$i]
-+	cmovg	$one,$num			# find maximum
-+	test	$one,$one
-+	movdqu	`40*$i+24-40*2`($inp),@inp[$i]	# load IV
-+	mov	$one,`32+4*$i`(%rsp)		# initialize counters
-+	cmovle	%rsp,@inptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	test	$num,$num
-+	jz	.Ldec4x_done
-+
-+	movups	0x10-0x78($key),$rndkey1
-+	movups	0x20-0x78($key),$rndkey0
-+	mov	0xf0-0x78($key),$rounds
-+	movdqu	(@inptr[0]),@out[0]		# load inputs
-+	movdqu	(@inptr[1]),@out[1]
-+	 pxor	$zero,@out[0]
-+	movdqu	(@inptr[2]),@out[2]
-+	 pxor	$zero,@out[1]
-+	movdqu	(@inptr[3]),@out[3]
-+	 pxor	$zero,@out[2]
-+	 pxor	$zero,@out[3]
-+	movdqa	32(%rsp),$counters		# load counters
-+	xor	$offset,$offset
-+	jmp	.Loop_dec4x
-+
-+.align	32
-+.Loop_dec4x:
-+	add	\$16,$offset
-+	lea	16(%rsp),$sink			# sink pointer
-+	mov	\$1,$one			# constant of 1
-+	sub	$offset,$sink
-+
-+	aesdec		$rndkey1,@out[0]
-+	prefetcht0	31(@inptr[0],$offset)	# prefetch input
-+	prefetcht0	31(@inptr[1],$offset)
-+	aesdec		$rndkey1,@out[1]
-+	prefetcht0	31(@inptr[2],$offset)
-+	prefetcht0	31(@inptr[3],$offset)
-+	aesdec		$rndkey1,@out[2]
-+	aesdec		$rndkey1,@out[3]
-+	movups		0x30-0x78($key),$rndkey1
-+___
-+for($i=0;$i<4;$i++) {
-+my $rndkey = ($i&1) ? $rndkey1 : $rndkey0;
-+$code.=<<___;
-+	 cmp		`32+4*$i`(%rsp),$one
-+	aesdec		$rndkey,@out[0]
-+	aesdec		$rndkey,@out[1]
-+	aesdec		$rndkey,@out[2]
-+	 cmovge		$sink,@inptr[$i]	# cancel input
-+	 cmovg		$sink,@outptr[$i]	# sink output
-+	aesdec		$rndkey,@out[3]
-+	movups		`0x40+16*$i-0x78`($key),$rndkey
-+___
-+}
-+$code.=<<___;
-+	 movdqa		$counters,$mask
-+	aesdec		$rndkey0,@out[0]
-+	prefetcht0	15(@outptr[0],$offset)	# prefetch output
-+	prefetcht0	15(@outptr[1],$offset)
-+	aesdec		$rndkey0,@out[1]
-+	prefetcht0	15(@outptr[2],$offset)
-+	prefetcht0	15(@outptr[3],$offset)
-+	aesdec		$rndkey0,@out[2]
-+	aesdec		$rndkey0,@out[3]
-+	movups		0x80-0x78($key),$rndkey0
-+	 pxor		$zero,$zero
-+
-+	aesdec		$rndkey1,@out[0]
-+	 pcmpgtd	$zero,$mask
-+	 movdqu		-0x78($key),$zero	# reload 0-round key
-+	aesdec		$rndkey1,@out[1]
-+	 paddd		$mask,$counters		# decrement counters
-+	 movdqa		$counters,32(%rsp)	# update counters
-+	aesdec		$rndkey1,@out[2]
-+	aesdec		$rndkey1,@out[3]
-+	movups		0x90-0x78($key),$rndkey1
-+
-+	cmp	\$11,$rounds
-+
-+	aesdec		$rndkey0,@out[0]
-+	aesdec		$rndkey0,@out[1]
-+	aesdec		$rndkey0,@out[2]
-+	aesdec		$rndkey0,@out[3]
-+	movups		0xa0-0x78($key),$rndkey0
-+
-+	jb	.Ldec4x_tail
-+
-+	aesdec		$rndkey1,@out[0]
-+	aesdec		$rndkey1,@out[1]
-+	aesdec		$rndkey1,@out[2]
-+	aesdec		$rndkey1,@out[3]
-+	movups		0xb0-0x78($key),$rndkey1
-+
-+	aesdec		$rndkey0,@out[0]
-+	aesdec		$rndkey0,@out[1]
-+	aesdec		$rndkey0,@out[2]
-+	aesdec		$rndkey0,@out[3]
-+	movups		0xc0-0x78($key),$rndkey0
-+
-+	je	.Ldec4x_tail
-+
-+	aesdec		$rndkey1,@out[0]
-+	aesdec		$rndkey1,@out[1]
-+	aesdec		$rndkey1,@out[2]
-+	aesdec		$rndkey1,@out[3]
-+	movups		0xd0-0x78($key),$rndkey1
-+
-+	aesdec		$rndkey0,@out[0]
-+	aesdec		$rndkey0,@out[1]
-+	aesdec		$rndkey0,@out[2]
-+	aesdec		$rndkey0,@out[3]
-+	movups		0xe0-0x78($key),$rndkey0
-+	jmp	.Ldec4x_tail
-+
-+.align	32
-+.Ldec4x_tail:
-+	aesdec		$rndkey1,@out[0]
-+	aesdec		$rndkey1,@out[1]
-+	aesdec		$rndkey1,@out[2]
-+	 pxor		$rndkey0,@inp[0]
-+	 pxor		$rndkey0,@inp[1]
-+	aesdec		$rndkey1,@out[3]
-+	movdqu		0x10-0x78($key),$rndkey1
-+	 pxor		$rndkey0,@inp[2]
-+	 pxor		$rndkey0,@inp[3]
-+	movdqu		0x20-0x78($key),$rndkey0
-+
-+	aesdeclast	@inp[0],@out[0]
-+	aesdeclast	@inp[1],@out[1]
-+	 movdqu		-16(@inptr[0],$offset),@inp[0]	# load next IV
-+	 movdqu		-16(@inptr[1],$offset),@inp[1]
-+	aesdeclast	@inp[2],@out[2]
-+	aesdeclast	@inp[3],@out[3]
-+	 movdqu		-16(@inptr[2],$offset),@inp[2]
-+	 movdqu		-16(@inptr[3],$offset),@inp[3]
-+
-+	movups		@out[0],-16(@outptr[0],$offset)
-+	 movdqu		(@inptr[0],$offset),@out[0]
-+	movups		@out[1],-16(@outptr[1],$offset)	
-+	 movdqu		(@inptr[1],$offset),@out[1]
-+	 pxor		$zero,@out[0]
-+	movups		@out[2],-16(@outptr[2],$offset)	
-+	 movdqu		(@inptr[2],$offset),@out[2]
-+	 pxor		$zero,@out[1]
-+	movups		@out[3],-16(@outptr[3],$offset)
-+	 movdqu		(@inptr[3],$offset),@out[3]
-+	 pxor		$zero,@out[2]
-+	 pxor		$zero,@out[3]
-+
-+	dec	$num
-+	jnz	.Loop_dec4x
-+
-+	mov	16(%rsp),%rax			# original %rsp
-+	mov	24(%rsp),$num
-+
-+	lea	`40*4`($inp),$inp
-+	dec	$num
-+	jnz	.Ldec4x_loop_grande
-+
-+.Ldec4x_done:
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xd8(%rax),%xmm6
-+	movaps	-0xc8(%rax),%xmm7
-+	movaps	-0xb8(%rax),%xmm8
-+	movaps	-0xa8(%rax),%xmm9
-+	movaps	-0x98(%rax),%xmm10
-+	movaps	-0x88(%rax),%xmm11
-+	movaps	-0x78(%rax),%xmm12
-+	#movaps	-0x68(%rax),%xmm13
-+	#movaps	-0x58(%rax),%xmm14
-+	#movaps	-0x48(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Ldec4x_epilogue:
-+	ret
-+.size	aesni_multi_cbc_decrypt,.-aesni_multi_cbc_decrypt
-+___
-+
-+						if ($avx) {{{
-+my @ptr=map("%r$_",(8..15));
-+my $offload=$sink;
-+
-+my @out=map("%xmm$_",(2..9));
-+my @inp=map("%xmm$_",(10..13));
-+my ($counters,$zero)=("%xmm14","%xmm15");
-+
-+$code.=<<___;
-+.type	aesni_multi_cbc_encrypt_avx,\@function,3
-+.align	32
-+aesni_multi_cbc_encrypt_avx:
-+_avx_cbc_enc_shortcut:
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,0x40(%rsp)
-+	movaps	%xmm11,0x50(%rsp)
-+	movaps	%xmm12,-0x78(%rax)
-+	movaps	%xmm13,-0x68(%rax)
-+	movaps	%xmm14,-0x58(%rax)
-+	movaps	%xmm15,-0x48(%rax)
-+___
-+$code.=<<___;
-+	# stack layout
-+	#
-+	# +0	output sink
-+	# +16	input sink [original %rsp and $num]
-+	# +32	counters
-+	# +64	distances between inputs and outputs
-+	# +128	off-load area for @inp[0..3]
-+
-+	sub	\$192,%rsp
-+	and	\$-128,%rsp
-+	mov	%rax,16(%rsp)			# original %rsp
-+
-+.Lenc8x_body:
-+	vzeroupper
-+	vmovdqu	($key),$zero			# 0-round key
-+	lea	0x78($key),$key			# size optimization
-+	lea	40*4($inp),$inp
-+	shr	\$1,$num
-+
-+.Lenc8x_loop_grande:
-+	#mov	$num,24(%rsp)			# original $num
-+	xor	$num,$num
-+___
-+for($i=0;$i<8;$i++) {
-+  my $temp = $i ? $offload : $offset;
-+    $code.=<<___;
-+	mov	`40*$i+16-40*4`($inp),$one	# borrow $one for number of blocks
-+	mov	`40*$i+0-40*4`($inp),@ptr[$i]	# input pointer
-+	cmp	$num,$one
-+	mov	`40*$i+8-40*4`($inp),$temp	# output pointer
-+	cmovg	$one,$num			# find maximum
-+	test	$one,$one
-+	vmovdqu	`40*$i+24-40*4`($inp),@out[$i]	# load IV
-+	mov	$one,`32+4*$i`(%rsp)		# initialize counters
-+	cmovle	%rsp,@ptr[$i]			# cancel input
-+	sub	@ptr[$i],$temp			# distance between input and output
-+	mov	$temp,`64+8*$i`(%rsp)		# initialize distances
-+___
-+}
-+$code.=<<___;
-+	test	$num,$num
-+	jz	.Lenc8x_done
-+
-+	vmovups	0x10-0x78($key),$rndkey1
-+	vmovups	0x20-0x78($key),$rndkey0
-+	mov	0xf0-0x78($key),$rounds
-+
-+	vpxor	(@ptr[0]),$zero,@inp[0]		# load inputs and xor with 0-round
-+	 lea	128(%rsp),$offload		# offload area
-+	vpxor	(@ptr[1]),$zero,@inp[1]
-+	vpxor	(@ptr[2]),$zero,@inp[2]
-+	vpxor	(@ptr[3]),$zero,@inp[3]
-+	 vpxor	@inp[0],@out[0],@out[0]
-+	vpxor	(@ptr[4]),$zero,@inp[0]
-+	 vpxor	@inp[1],@out[1],@out[1]
-+	vpxor	(@ptr[5]),$zero,@inp[1]
-+	 vpxor	@inp[2],@out[2],@out[2]
-+	vpxor	(@ptr[6]),$zero,@inp[2]
-+	 vpxor	@inp[3],@out[3],@out[3]
-+	vpxor	(@ptr[7]),$zero,@inp[3]
-+	 vpxor	@inp[0],@out[4],@out[4]
-+	mov	\$1,$one			# constant of 1
-+	 vpxor	@inp[1],@out[5],@out[5]
-+	 vpxor	@inp[2],@out[6],@out[6]
-+	 vpxor	@inp[3],@out[7],@out[7]
-+	jmp	.Loop_enc8x
-+
-+.align	32
-+.Loop_enc8x:
-+___
-+for($i=0;$i<8;$i++) {
-+my $rndkey=($i&1)?$rndkey0:$rndkey1;
-+$code.=<<___;
-+	vaesenc		$rndkey,@out[0],@out[0]
-+	 cmp		32+4*$i(%rsp),$one
-+___
-+$code.=<<___ if ($i);
-+	 mov		64+8*$i(%rsp),$offset
-+___
-+$code.=<<___;
-+	vaesenc		$rndkey,@out[1],@out[1]
-+	prefetcht0	31(@ptr[$i])			# prefetch input
-+	vaesenc		$rndkey,@out[2],@out[2]
-+___
-+$code.=<<___ if ($i>1);
-+	prefetcht0	15(@ptr[$i-2])			# prefetch output
-+___
-+$code.=<<___;
-+	vaesenc		$rndkey,@out[3],@out[3]
-+	 lea		(@ptr[$i],$offset),$offset
-+	 cmovge		%rsp,@ptr[$i]			# cancel input
-+	vaesenc		$rndkey,@out[4],@out[4]
-+	 cmovg		%rsp,$offset			# sink output
-+	vaesenc		$rndkey,@out[5],@out[5]
-+	 sub		@ptr[$i],$offset
-+	vaesenc		$rndkey,@out[6],@out[6]
-+	 vpxor		16(@ptr[$i]),$zero,@inp[$i%4]	# load input and xor with 0-round
-+	 mov		$offset,64+8*$i(%rsp)
-+	vaesenc		$rndkey,@out[7],@out[7]
-+	vmovups		`16*(3+$i)-0x78`($key),$rndkey
-+	 lea		16(@ptr[$i],$offset),@ptr[$i]	# switch to output
-+___
-+$code.=<<___ if ($i<4)
-+	 vmovdqu	@inp[$i%4],`16*$i`($offload)	# off-load
-+___
-+}
-+$code.=<<___;
-+	 vmovdqu	32(%rsp),$counters
-+	prefetcht0	15(@ptr[$i-2])			# prefetch output
-+	prefetcht0	15(@ptr[$i-1])
-+	cmp	\$11,$rounds
-+	jb	.Lenc8x_tail
-+
-+	vaesenc		$rndkey1,@out[0],@out[0]
-+	vaesenc		$rndkey1,@out[1],@out[1]
-+	vaesenc		$rndkey1,@out[2],@out[2]
-+	vaesenc		$rndkey1,@out[3],@out[3]
-+	vaesenc		$rndkey1,@out[4],@out[4]
-+	vaesenc		$rndkey1,@out[5],@out[5]
-+	vaesenc		$rndkey1,@out[6],@out[6]
-+	vaesenc		$rndkey1,@out[7],@out[7]
-+	vmovups		0xb0-0x78($key),$rndkey1
-+
-+	vaesenc		$rndkey0,@out[0],@out[0]
-+	vaesenc		$rndkey0,@out[1],@out[1]
-+	vaesenc		$rndkey0,@out[2],@out[2]
-+	vaesenc		$rndkey0,@out[3],@out[3]
-+	vaesenc		$rndkey0,@out[4],@out[4]
-+	vaesenc		$rndkey0,@out[5],@out[5]
-+	vaesenc		$rndkey0,@out[6],@out[6]
-+	vaesenc		$rndkey0,@out[7],@out[7]
-+	vmovups		0xc0-0x78($key),$rndkey0
-+	je	.Lenc8x_tail
-+
-+	vaesenc		$rndkey1,@out[0],@out[0]
-+	vaesenc		$rndkey1,@out[1],@out[1]
-+	vaesenc		$rndkey1,@out[2],@out[2]
-+	vaesenc		$rndkey1,@out[3],@out[3]
-+	vaesenc		$rndkey1,@out[4],@out[4]
-+	vaesenc		$rndkey1,@out[5],@out[5]
-+	vaesenc		$rndkey1,@out[6],@out[6]
-+	vaesenc		$rndkey1,@out[7],@out[7]
-+	vmovups		0xd0-0x78($key),$rndkey1
-+
-+	vaesenc		$rndkey0,@out[0],@out[0]
-+	vaesenc		$rndkey0,@out[1],@out[1]
-+	vaesenc		$rndkey0,@out[2],@out[2]
-+	vaesenc		$rndkey0,@out[3],@out[3]
-+	vaesenc		$rndkey0,@out[4],@out[4]
-+	vaesenc		$rndkey0,@out[5],@out[5]
-+	vaesenc		$rndkey0,@out[6],@out[6]
-+	vaesenc		$rndkey0,@out[7],@out[7]
-+	vmovups		0xe0-0x78($key),$rndkey0
-+
-+.Lenc8x_tail:
-+	vaesenc		$rndkey1,@out[0],@out[0]
-+	 vpxor		$zero,$zero,$zero
-+	vaesenc		$rndkey1,@out[1],@out[1]
-+	vaesenc		$rndkey1,@out[2],@out[2]
-+	 vpcmpgtd	$zero,$counters,$zero
-+	vaesenc		$rndkey1,@out[3],@out[3]
-+	vaesenc		$rndkey1,@out[4],@out[4]
-+	 vpaddd		$counters,$zero,$zero		# decrement counters
-+	 vmovdqu	48(%rsp),$counters
-+	vaesenc		$rndkey1,@out[5],@out[5]
-+	 mov		64(%rsp),$offset		# pre-load 1st offset
-+	vaesenc		$rndkey1,@out[6],@out[6]
-+	vaesenc		$rndkey1,@out[7],@out[7]
-+	vmovups		0x10-0x78($key),$rndkey1
-+
-+	vaesenclast	$rndkey0,@out[0],@out[0]
-+	 vmovdqa	$zero,32(%rsp)			# update counters
-+	 vpxor		$zero,$zero,$zero
-+	vaesenclast	$rndkey0,@out[1],@out[1]
-+	vaesenclast	$rndkey0,@out[2],@out[2]
-+	 vpcmpgtd	$zero,$counters,$zero
-+	vaesenclast	$rndkey0,@out[3],@out[3]
-+	vaesenclast	$rndkey0,@out[4],@out[4]
-+	 vpaddd		$zero,$counters,$counters	# decrement counters
-+	 vmovdqu	-0x78($key),$zero		# 0-round
-+	vaesenclast	$rndkey0,@out[5],@out[5]
-+	vaesenclast	$rndkey0,@out[6],@out[6]
-+	 vmovdqa	$counters,48(%rsp)		# update counters
-+	vaesenclast	$rndkey0,@out[7],@out[7]
-+	vmovups		0x20-0x78($key),$rndkey0
-+
-+	vmovups		@out[0],-16(@ptr[0])		# write output
-+	 sub		$offset,@ptr[0]			# switch to input
-+	 vpxor		0x00($offload),@out[0],@out[0]
-+	vmovups		@out[1],-16(@ptr[1])	
-+	 sub		`64+1*8`(%rsp),@ptr[1]
-+	 vpxor		0x10($offload),@out[1],@out[1]
-+	vmovups		@out[2],-16(@ptr[2])	
-+	 sub		`64+2*8`(%rsp),@ptr[2]
-+	 vpxor		0x20($offload),@out[2],@out[2]
-+	vmovups		@out[3],-16(@ptr[3])
-+	 sub		`64+3*8`(%rsp),@ptr[3]
-+	 vpxor		0x30($offload),@out[3],@out[3]
-+	vmovups		@out[4],-16(@ptr[4])
-+	 sub		`64+4*8`(%rsp),@ptr[4]
-+	 vpxor		@inp[0],@out[4],@out[4]
-+	vmovups		@out[5],-16(@ptr[5])	
-+	 sub		`64+5*8`(%rsp),@ptr[5]
-+	 vpxor		@inp[1],@out[5],@out[5]
-+	vmovups		@out[6],-16(@ptr[6])	
-+	 sub		`64+6*8`(%rsp),@ptr[6]
-+	 vpxor		@inp[2],@out[6],@out[6]
-+	vmovups		@out[7],-16(@ptr[7])
-+	 sub		`64+7*8`(%rsp),@ptr[7]
-+	 vpxor		@inp[3],@out[7],@out[7]
-+
-+	dec	$num
-+	jnz	.Loop_enc8x
-+
-+	mov	16(%rsp),%rax			# original %rsp
-+	#mov	24(%rsp),$num
-+	#lea	`40*8`($inp),$inp
-+	#dec	$num
-+	#jnz	.Lenc8x_loop_grande
-+
-+.Lenc8x_done:
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xd8(%rax),%xmm6
-+	movaps	-0xc8(%rax),%xmm7
-+	movaps	-0xb8(%rax),%xmm8
-+	movaps	-0xa8(%rax),%xmm9
-+	movaps	-0x98(%rax),%xmm10
-+	movaps	-0x88(%rax),%xmm11
-+	movaps	-0x78(%rax),%xmm12
-+	movaps	-0x68(%rax),%xmm13
-+	movaps	-0x58(%rax),%xmm14
-+	movaps	-0x48(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Lenc8x_epilogue:
-+	ret
-+.size	aesni_multi_cbc_encrypt_avx,.-aesni_multi_cbc_encrypt_avx
-+
-+.type	aesni_multi_cbc_decrypt_avx,\@function,3
-+.align	32
-+aesni_multi_cbc_decrypt_avx:
-+_avx_cbc_dec_shortcut:
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,0x40(%rsp)
-+	movaps	%xmm11,0x50(%rsp)
-+	movaps	%xmm12,-0x78(%rax)
-+	movaps	%xmm13,-0x68(%rax)
-+	movaps	%xmm14,-0x58(%rax)
-+	movaps	%xmm15,-0x48(%rax)
-+___
-+$code.=<<___;
-+	# stack layout
-+	#
-+	# +0	output sink
-+	# +16	input sink [original %rsp and $num]
-+	# +32	counters
-+	# +64	distances between inputs and outputs
-+	# +128	off-load area for @inp[0..3]
-+	# +192	IV/input offload
-+
-+	sub	\$256,%rsp
-+	and	\$-256,%rsp
-+	sub	\$192,%rsp
-+	mov	%rax,16(%rsp)			# original %rsp
-+
-+.Ldec8x_body:
-+	vzeroupper
-+	vmovdqu	($key),$zero			# 0-round key
-+	lea	0x78($key),$key			# size optimization
-+	lea	40*4($inp),$inp
-+	shr	\$1,$num
-+
-+.Ldec8x_loop_grande:
-+	#mov	$num,24(%rsp)			# original $num
-+	xor	$num,$num
-+___
-+for($i=0;$i<8;$i++) {
-+  my $temp = $i ? $offload : $offset;
-+    $code.=<<___;
-+	mov	`40*$i+16-40*4`($inp),$one	# borrow $one for number of blocks
-+	mov	`40*$i+0-40*4`($inp),@ptr[$i]	# input pointer
-+	cmp	$num,$one
-+	mov	`40*$i+8-40*4`($inp),$temp	# output pointer
-+	cmovg	$one,$num			# find maximum
-+	test	$one,$one
-+	vmovdqu	`40*$i+24-40*4`($inp),@out[$i]	# load IV
-+	mov	$one,`32+4*$i`(%rsp)		# initialize counters
-+	cmovle	%rsp,@ptr[$i]			# cancel input
-+	sub	@ptr[$i],$temp			# distance between input and output
-+	mov	$temp,`64+8*$i`(%rsp)		# initialize distances
-+	vmovdqu	@out[$i],`192+16*$i`(%rsp)	# offload IV
-+___
-+}
-+$code.=<<___;
-+	test	$num,$num
-+	jz	.Ldec8x_done
-+
-+	vmovups	0x10-0x78($key),$rndkey1
-+	vmovups	0x20-0x78($key),$rndkey0
-+	mov	0xf0-0x78($key),$rounds
-+	 lea	192+128(%rsp),$offload		# offload area
-+
-+	vmovdqu	(@ptr[0]),@out[0]		# load inputs
-+	vmovdqu	(@ptr[1]),@out[1]
-+	vmovdqu	(@ptr[2]),@out[2]
-+	vmovdqu	(@ptr[3]),@out[3]
-+	vmovdqu	(@ptr[4]),@out[4]
-+	vmovdqu	(@ptr[5]),@out[5]
-+	vmovdqu	(@ptr[6]),@out[6]
-+	vmovdqu	(@ptr[7]),@out[7]
-+	vmovdqu	@out[0],0x00($offload)		# offload inputs
-+	vpxor	$zero,@out[0],@out[0]		# xor inputs with 0-round
-+	vmovdqu	@out[1],0x10($offload)
-+	vpxor	$zero,@out[1],@out[1]
-+	vmovdqu	@out[2],0x20($offload)
-+	vpxor	$zero,@out[2],@out[2]
-+	vmovdqu	@out[3],0x30($offload)
-+	vpxor	$zero,@out[3],@out[3]
-+	vmovdqu	@out[4],0x40($offload)
-+	vpxor	$zero,@out[4],@out[4]
-+	vmovdqu	@out[5],0x50($offload)
-+	vpxor	$zero,@out[5],@out[5]
-+	vmovdqu	@out[6],0x60($offload)
-+	vpxor	$zero,@out[6],@out[6]
-+	vmovdqu	@out[7],0x70($offload)
-+	vpxor	$zero,@out[7],@out[7]
-+	xor	\$0x80,$offload
-+	mov	\$1,$one			# constant of 1
-+	jmp	.Loop_dec8x
-+
-+.align	32
-+.Loop_dec8x:
-+___
-+for($i=0;$i<8;$i++) {
-+my $rndkey=($i&1)?$rndkey0:$rndkey1;
-+$code.=<<___;
-+	vaesdec		$rndkey,@out[0],@out[0]
-+	 cmp		32+4*$i(%rsp),$one
-+___
-+$code.=<<___ if ($i);
-+	 mov		64+8*$i(%rsp),$offset
-+___
-+$code.=<<___;
-+	vaesdec		$rndkey,@out[1],@out[1]
-+	prefetcht0	31(@ptr[$i])			# prefetch input
-+	vaesdec		$rndkey,@out[2],@out[2]
-+___
-+$code.=<<___ if ($i>1);
-+	prefetcht0	15(@ptr[$i-2])			# prefetch output
-+___
-+$code.=<<___;
-+	vaesdec		$rndkey,@out[3],@out[3]
-+	 lea		(@ptr[$i],$offset),$offset
-+	 cmovge		%rsp,@ptr[$i]			# cancel input
-+	vaesdec		$rndkey,@out[4],@out[4]
-+	 cmovg		%rsp,$offset			# sink output
-+	vaesdec		$rndkey,@out[5],@out[5]
-+	 sub		@ptr[$i],$offset
-+	vaesdec		$rndkey,@out[6],@out[6]
-+	 vmovdqu	16(@ptr[$i]),@inp[$i%4]		# load input
-+	 mov		$offset,64+8*$i(%rsp)
-+	vaesdec		$rndkey,@out[7],@out[7]
-+	vmovups		`16*(3+$i)-0x78`($key),$rndkey
-+	 lea		16(@ptr[$i],$offset),@ptr[$i]	# switch to output
-+___
-+$code.=<<___ if ($i<4);
-+	 vmovdqu	@inp[$i%4],`128+16*$i`(%rsp)	# off-load
-+___
-+}
-+$code.=<<___;
-+	 vmovdqu	32(%rsp),$counters
-+	prefetcht0	15(@ptr[$i-2])			# prefetch output
-+	prefetcht0	15(@ptr[$i-1])
-+	cmp	\$11,$rounds
-+	jb	.Ldec8x_tail
-+
-+	vaesdec		$rndkey1,@out[0],@out[0]
-+	vaesdec		$rndkey1,@out[1],@out[1]
-+	vaesdec		$rndkey1,@out[2],@out[2]
-+	vaesdec		$rndkey1,@out[3],@out[3]
-+	vaesdec		$rndkey1,@out[4],@out[4]
-+	vaesdec		$rndkey1,@out[5],@out[5]
-+	vaesdec		$rndkey1,@out[6],@out[6]
-+	vaesdec		$rndkey1,@out[7],@out[7]
-+	vmovups		0xb0-0x78($key),$rndkey1
-+
-+	vaesdec		$rndkey0,@out[0],@out[0]
-+	vaesdec		$rndkey0,@out[1],@out[1]
-+	vaesdec		$rndkey0,@out[2],@out[2]
-+	vaesdec		$rndkey0,@out[3],@out[3]
-+	vaesdec		$rndkey0,@out[4],@out[4]
-+	vaesdec		$rndkey0,@out[5],@out[5]
-+	vaesdec		$rndkey0,@out[6],@out[6]
-+	vaesdec		$rndkey0,@out[7],@out[7]
-+	vmovups		0xc0-0x78($key),$rndkey0
-+	je	.Ldec8x_tail
-+
-+	vaesdec		$rndkey1,@out[0],@out[0]
-+	vaesdec		$rndkey1,@out[1],@out[1]
-+	vaesdec		$rndkey1,@out[2],@out[2]
-+	vaesdec		$rndkey1,@out[3],@out[3]
-+	vaesdec		$rndkey1,@out[4],@out[4]
-+	vaesdec		$rndkey1,@out[5],@out[5]
-+	vaesdec		$rndkey1,@out[6],@out[6]
-+	vaesdec		$rndkey1,@out[7],@out[7]
-+	vmovups		0xd0-0x78($key),$rndkey1
-+
-+	vaesdec		$rndkey0,@out[0],@out[0]
-+	vaesdec		$rndkey0,@out[1],@out[1]
-+	vaesdec		$rndkey0,@out[2],@out[2]
-+	vaesdec		$rndkey0,@out[3],@out[3]
-+	vaesdec		$rndkey0,@out[4],@out[4]
-+	vaesdec		$rndkey0,@out[5],@out[5]
-+	vaesdec		$rndkey0,@out[6],@out[6]
-+	vaesdec		$rndkey0,@out[7],@out[7]
-+	vmovups		0xe0-0x78($key),$rndkey0
-+
-+.Ldec8x_tail:
-+	vaesdec		$rndkey1,@out[0],@out[0]
-+	 vpxor		$zero,$zero,$zero
-+	vaesdec		$rndkey1,@out[1],@out[1]
-+	vaesdec		$rndkey1,@out[2],@out[2]
-+	 vpcmpgtd	$zero,$counters,$zero
-+	vaesdec		$rndkey1,@out[3],@out[3]
-+	vaesdec		$rndkey1,@out[4],@out[4]
-+	 vpaddd		$counters,$zero,$zero		# decrement counters
-+	 vmovdqu	48(%rsp),$counters
-+	vaesdec		$rndkey1,@out[5],@out[5]
-+	 mov		64(%rsp),$offset		# pre-load 1st offset
-+	vaesdec		$rndkey1,@out[6],@out[6]
-+	vaesdec		$rndkey1,@out[7],@out[7]
-+	vmovups		0x10-0x78($key),$rndkey1
-+
-+	vaesdeclast	$rndkey0,@out[0],@out[0]
-+	 vmovdqa	$zero,32(%rsp)			# update counters
-+	 vpxor		$zero,$zero,$zero
-+	vaesdeclast	$rndkey0,@out[1],@out[1]
-+	vpxor		0x00($offload),@out[0],@out[0]	# xor with IV
-+	vaesdeclast	$rndkey0,@out[2],@out[2]
-+	vpxor		0x10($offload),@out[1],@out[1]
-+	 vpcmpgtd	$zero,$counters,$zero
-+	vaesdeclast	$rndkey0,@out[3],@out[3]
-+	vpxor		0x20($offload),@out[2],@out[2]
-+	vaesdeclast	$rndkey0,@out[4],@out[4]
-+	vpxor		0x30($offload),@out[3],@out[3]
-+	 vpaddd		$zero,$counters,$counters	# decrement counters
-+	 vmovdqu	-0x78($key),$zero		# 0-round
-+	vaesdeclast	$rndkey0,@out[5],@out[5]
-+	vpxor		0x40($offload),@out[4],@out[4]
-+	vaesdeclast	$rndkey0,@out[6],@out[6]
-+	vpxor		0x50($offload),@out[5],@out[5]
-+	 vmovdqa	$counters,48(%rsp)		# update counters
-+	vaesdeclast	$rndkey0,@out[7],@out[7]
-+	vpxor		0x60($offload),@out[6],@out[6]
-+	vmovups		0x20-0x78($key),$rndkey0
-+
-+	vmovups		@out[0],-16(@ptr[0])		# write output
-+	 sub		$offset,@ptr[0]			# switch to input
-+	 vmovdqu	128+0(%rsp),@out[0]
-+	vpxor		0x70($offload),@out[7],@out[7]
-+	vmovups		@out[1],-16(@ptr[1])	
-+	 sub		`64+1*8`(%rsp),@ptr[1]
-+	 vmovdqu	@out[0],0x00($offload)
-+	 vpxor		$zero,@out[0],@out[0]
-+	 vmovdqu	128+16(%rsp),@out[1]
-+	vmovups		@out[2],-16(@ptr[2])	
-+	 sub		`64+2*8`(%rsp),@ptr[2]
-+	 vmovdqu	@out[1],0x10($offload)
-+	 vpxor		$zero,@out[1],@out[1]
-+	 vmovdqu	128+32(%rsp),@out[2]
-+	vmovups		@out[3],-16(@ptr[3])
-+	 sub		`64+3*8`(%rsp),@ptr[3]
-+	 vmovdqu	@out[2],0x20($offload)
-+	 vpxor		$zero,@out[2],@out[2]
-+	 vmovdqu	128+48(%rsp),@out[3]
-+	vmovups		@out[4],-16(@ptr[4])
-+	 sub		`64+4*8`(%rsp),@ptr[4]
-+	 vmovdqu	@out[3],0x30($offload)
-+	 vpxor		$zero,@out[3],@out[3]
-+	 vmovdqu	@inp[0],0x40($offload)
-+	 vpxor		@inp[0],$zero,@out[4]
-+	vmovups		@out[5],-16(@ptr[5])	
-+	 sub		`64+5*8`(%rsp),@ptr[5]
-+	 vmovdqu	@inp[1],0x50($offload)
-+	 vpxor		@inp[1],$zero,@out[5]
-+	vmovups		@out[6],-16(@ptr[6])	
-+	 sub		`64+6*8`(%rsp),@ptr[6]
-+	 vmovdqu	@inp[2],0x60($offload)
-+	 vpxor		@inp[2],$zero,@out[6]
-+	vmovups		@out[7],-16(@ptr[7])
-+	 sub		`64+7*8`(%rsp),@ptr[7]
-+	 vmovdqu	@inp[3],0x70($offload)
-+	 vpxor		@inp[3],$zero,@out[7]
-+
-+	xor	\$128,$offload
-+	dec	$num
-+	jnz	.Loop_dec8x
-+
-+	mov	16(%rsp),%rax			# original %rsp
-+	#mov	24(%rsp),$num
-+	#lea	`40*8`($inp),$inp
-+	#dec	$num
-+	#jnz	.Ldec8x_loop_grande
-+
-+.Ldec8x_done:
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xd8(%rax),%xmm6
-+	movaps	-0xc8(%rax),%xmm7
-+	movaps	-0xb8(%rax),%xmm8
-+	movaps	-0xa8(%rax),%xmm9
-+	movaps	-0x98(%rax),%xmm10
-+	movaps	-0x88(%rax),%xmm11
-+	movaps	-0x78(%rax),%xmm12
-+	movaps	-0x68(%rax),%xmm13
-+	movaps	-0x58(%rax),%xmm14
-+	movaps	-0x48(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Ldec8x_epilogue:
-+	ret
-+.size	aesni_multi_cbc_decrypt_avx,.-aesni_multi_cbc_decrypt_avx
-+___
-+						}}}
-+
-+if ($win64) {
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->Rip<.Lprologue
-+	jb	.Lin_prologue
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
-+	jae	.Lin_prologue
-+
-+	mov	16(%rax),%rax		# pull saved stack pointer
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore cotnext->R12
-+	mov	%r13,224($context)	# restore cotnext->R13
-+	mov	%r14,232($context)	# restore cotnext->R14
-+	mov	%r15,240($context)	# restore cotnext->R15
-+
-+	lea	-56-10*16(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_aesni_multi_cbc_encrypt
-+	.rva	.LSEH_end_aesni_multi_cbc_encrypt
-+	.rva	.LSEH_info_aesni_multi_cbc_encrypt
-+	.rva	.LSEH_begin_aesni_multi_cbc_decrypt
-+	.rva	.LSEH_end_aesni_multi_cbc_decrypt
-+	.rva	.LSEH_info_aesni_multi_cbc_decrypt
-+___
-+$code.=<<___ if ($avx);
-+	.rva	.LSEH_begin_aesni_multi_cbc_encrypt_avx
-+	.rva	.LSEH_end_aesni_multi_cbc_encrypt_avx
-+	.rva	.LSEH_info_aesni_multi_cbc_encrypt_avx
-+	.rva	.LSEH_begin_aesni_multi_cbc_decrypt_avx
-+	.rva	.LSEH_end_aesni_multi_cbc_decrypt_avx
-+	.rva	.LSEH_info_aesni_multi_cbc_decrypt_avx
-+___
-+$code.=<<___;
-+.section	.xdata
-+.align	8
-+.LSEH_info_aesni_multi_cbc_encrypt:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lenc4x_body,.Lenc4x_epilogue		# HandlerData[]
-+.LSEH_info_aesni_multi_cbc_decrypt:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Ldec4x_body,.Ldec4x_epilogue		# HandlerData[]
-+___
-+$code.=<<___ if ($avx);
-+.LSEH_info_aesni_multi_cbc_encrypt_avx:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lenc8x_body,.Lenc8x_epilogue		# HandlerData[]
-+.LSEH_info_aesni_multi_cbc_decrypt_avx:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Ldec8x_body,.Ldec8x_epilogue		# HandlerData[]
-+___
-+}
-+####################################################################
-+
-+sub rex {
-+  local *opcode=shift;
-+  my ($dst,$src)=@_;
-+  my $rex=0;
-+
-+    $rex|=0x04			if($dst>=8);
-+    $rex|=0x01			if($src>=8);
-+    push @opcode,$rex|0x40	if($rex);
-+}
-+
-+sub aesni {
-+  my $line=shift;
-+  my @opcode=(0x66);
-+
-+    if ($line=~/(aeskeygenassist)\s+\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+	rex(\@opcode,$4,$3);
-+	push @opcode,0x0f,0x3a,0xdf;
-+	push @opcode,0xc0|($3&7)|(($4&7)<<3);	# ModR/M
-+	my $c=$2;
-+	push @opcode,$c=~/^0/?oct($c):$c;
-+	return ".byte\t".join(',',@opcode);
-+    }
-+    elsif ($line=~/(aes[a-z]+)\s+%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+	my %opcodelet = (
-+		"aesimc" => 0xdb,
-+		"aesenc" => 0xdc,	"aesenclast" => 0xdd,
-+		"aesdec" => 0xde,	"aesdeclast" => 0xdf
-+	);
-+	return undef if (!defined($opcodelet{$1}));
-+	rex(\@opcode,$3,$2);
-+	push @opcode,0x0f,0x38,$opcodelet{$1};
-+	push @opcode,0xc0|($2&7)|(($3&7)<<3);	# ModR/M
-+	return ".byte\t".join(',',@opcode);
-+    }
-+    elsif ($line=~/(aes[a-z]+)\s+([0x1-9a-fA-F]*)\(%rsp\),\s*%xmm([0-9]+)/) {
-+	my %opcodelet = (
-+		"aesenc" => 0xdc,	"aesenclast" => 0xdd,
-+		"aesdec" => 0xde,	"aesdeclast" => 0xdf
-+	);
-+	return undef if (!defined($opcodelet{$1}));
-+	my $off = $2;
-+	push @opcode,0x44 if ($3>=8);
-+	push @opcode,0x0f,0x38,$opcodelet{$1};
-+	push @opcode,0x44|(($3&7)<<3),0x24;	# ModR/M
-+	push @opcode,($off=~/^0/?oct($off):$off)&0xff;
-+	return ".byte\t".join(',',@opcode);
-+    }
-+    return $line;
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+$code =~ s/\b(aes.*%xmm[0-9]+).*$/aesni($1)/gem;
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
-new file mode 100644
-index 0000000..4b979a7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl
-@@ -0,0 +1,2066 @@
-+#! /usr/bin/env perl
-+# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# June 2011
-+#
-+# This is AESNI-CBC+SHA1 "stitch" implementation. The idea, as spelled
-+# in http://download.intel.com/design/intarch/papers/323686.pdf, is
-+# that since AESNI-CBC encrypt exhibit *very* low instruction-level
-+# parallelism, interleaving it with another algorithm would allow to
-+# utilize processor resources better and achieve better performance.
-+# SHA1 instruction sequences(*) are taken from sha1-x86_64.pl and
-+# AESNI code is weaved into it. Below are performance numbers in
-+# cycles per processed byte, less is better, for standalone AESNI-CBC
-+# encrypt, sum of the latter and standalone SHA1, and "stitched"
-+# subroutine:
-+#
-+#		AES-128-CBC	+SHA1		stitch      gain
-+# Westmere	3.77[+5.3]	9.07		6.55	    +38%
-+# Sandy Bridge	5.05[+5.0(6.1)]	10.06(11.15)	5.98(7.05)  +68%(+58%)
-+# Ivy Bridge	5.05[+4.6]	9.65		5.54        +74%
-+# Haswell	4.43[+3.6(4.2)]	8.00(8.58)	4.55(5.21)  +75%(+65%)
-+# Skylake	2.63[+3.5(4.1)]	6.17(6.69)	4.23(4.44)  +46%(+51%)
-+# Bulldozer	5.77[+6.0]	11.72		6.37        +84%
-+#
-+#		AES-192-CBC
-+# Westmere	4.51		9.81		6.80	    +44%
-+# Sandy Bridge	6.05		11.06(12.15)	6.11(7.19)  +81%(+69%)
-+# Ivy Bridge	6.05		10.65		6.07        +75%
-+# Haswell	5.29		8.86(9.44)	5.32(5.32)  +67%(+77%)
-+# Bulldozer	6.89		12.84		6.96        +84%
-+#
-+#		AES-256-CBC
-+# Westmere	5.25		10.55		7.21	    +46%
-+# Sandy Bridge	7.05		12.06(13.15)	7.12(7.72)  +69%(+70%)
-+# Ivy Bridge	7.05		11.65		7.12        +64%
-+# Haswell	6.19		9.76(10.34)	6.21(6.25)  +57%(+65%)
-+# Skylake	3.62		7.16(7.68)	4.56(4.76)  +57%(+61$)
-+# Bulldozer	8.00		13.95		8.25        +69%
-+#
-+# (*)	There are two code paths: SSSE3 and AVX. See sha1-568.pl for
-+#	background information. Above numbers in parentheses are SSSE3
-+#	results collected on AVX-capable CPU, i.e. apply on OSes that
-+#	don't support AVX.
-+#
-+# Needless to mention that it makes no sense to implement "stitched"
-+# *decrypt* subroutine. Because *both* AESNI-CBC decrypt and SHA1
-+# fully utilize parallelism, so stitching would not give any gain
-+# anyway. Well, there might be some, e.g. because of better cache
-+# locality... For reference, here are performance results for
-+# standalone AESNI-CBC decrypt:
-+#
-+#		AES-128-CBC	AES-192-CBC	AES-256-CBC
-+# Westmere	1.25		1.50		1.75
-+# Sandy Bridge	0.74		0.91		1.09
-+# Ivy Bridge	0.74		0.90		1.11
-+# Haswell	0.63		0.76		0.88
-+# Bulldozer	0.70		0.85		0.99
-+
-+# And indeed:
-+#
-+#		AES-256-CBC	+SHA1		stitch      gain
-+# Westmere	1.75		7.20		6.68        +7.8%
-+# Sandy Bridge	1.09		6.09(7.22)	5.82(6.95)  +4.6%(+3.9%)
-+# Ivy Bridge	1.11		5.70		5.45        +4.6%
-+# Haswell	0.88		4.45(5.00)	4.39(4.69)  +1.4%(*)(+6.6%)
-+# Bulldozer	0.99		6.95		5.95        +17%(**)
-+#
-+# (*)	Tiny improvement coefficient on Haswell is because we compare
-+#	AVX1 stitch to sum with AVX2 SHA1.
-+# (**)	Execution is fully dominated by integer code sequence and
-+#	SIMD still hardly shows [in single-process benchmark;-]
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+$avx=1 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
-+	   $1>=2.19);
-+$avx=1 if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
-+	   $1>=2.09);
-+$avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	   `ml64 2>&1` =~ /Version ([0-9]+)\./ &&
-+	   $1>=10);
-+$avx=1 if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/ && $2>=3.0);
-+
-+$shaext=1;	### set to zero if compiling for 1.0.1
-+
-+$stitched_decrypt=0;
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+# void aesni_cbc_sha1_enc(const void *inp,
-+#			void *out,
-+#			size_t length,
-+#			const AES_KEY *key,
-+#			unsigned char *iv,
-+#			SHA_CTX *ctx,
-+#			const void *in0);
-+
-+$code.=<<___;
-+.text
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	aesni_cbc_sha1_enc
-+.type	aesni_cbc_sha1_enc,\@abi-omnipotent
-+.align	32
-+aesni_cbc_sha1_enc:
-+	# caller should check for SSSE3 and AES-NI bits
-+	mov	OPENSSL_ia32cap_P+0(%rip),%r10d
-+	mov	OPENSSL_ia32cap_P+4(%rip),%r11
-+___
-+$code.=<<___ if ($shaext);
-+	bt	\$61,%r11		# check SHA bit
-+	jc	aesni_cbc_sha1_enc_shaext
-+___
-+$code.=<<___ if ($avx);
-+	and	\$`1<<28`,%r11d		# mask AVX bit
-+	and	\$`1<<30`,%r10d		# mask "Intel CPU" bit
-+	or	%r11d,%r10d
-+	cmp	\$`1<<28|1<<30`,%r10d
-+	je	aesni_cbc_sha1_enc_avx
-+___
-+$code.=<<___;
-+	jmp	aesni_cbc_sha1_enc_ssse3
-+	ret
-+.size	aesni_cbc_sha1_enc,.-aesni_cbc_sha1_enc
-+___
-+
-+my ($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
-+
-+my $Xi=4;
-+my @X=map("%xmm$_",(4..7,0..3));
-+my @Tx=map("%xmm$_",(8..10));
-+my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp");	# size optimization
-+my @T=("%esi","%edi");
-+my $j=0; my $jj=0; my $r=0; my $sn=0; my $rx=0;
-+my $K_XX_XX="%r11";
-+my ($rndkey0,$iv,$in)=map("%xmm$_",(11..13));			# for enc
-+my @rndkey=("%xmm14","%xmm15");					# for enc
-+my ($inout0,$inout1,$inout2,$inout3)=map("%xmm$_",(12..15));	# for dec
-+
-+if (1) {	# reassign for Atom Silvermont
-+    # The goal is to minimize amount of instructions with more than
-+    # 3 prefix bytes. Or in more practical terms to keep AES-NI *and*
-+    # SSSE3 instructions to upper half of the register bank.
-+    @X=map("%xmm$_",(8..11,4..7));
-+    @Tx=map("%xmm$_",(12,13,3));
-+    ($iv,$in,$rndkey0)=map("%xmm$_",(2,14,15));
-+    @rndkey=("%xmm0","%xmm1");
-+}
-+
-+sub AUTOLOAD()		# thunk [simplified] 32-bit style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
-+  my $arg = pop;
-+    $arg = "\$$arg" if ($arg*1 eq $arg);
-+    $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
-+}
-+
-+my $_rol=sub { &rol(@_) };
-+my $_ror=sub { &ror(@_) };
-+
-+$code.=<<___;
-+.type	aesni_cbc_sha1_enc_ssse3,\@function,6
-+.align	32
-+aesni_cbc_sha1_enc_ssse3:
-+	mov	`($win64?56:8)`(%rsp),$inp	# load 7th argument
-+	#shr	\$6,$len			# debugging artefact
-+	#jz	.Lepilogue_ssse3		# debugging artefact
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	lea	`-104-($win64?10*16:0)`(%rsp),%rsp
-+	#mov	$in0,$inp			# debugging artefact
-+	#lea	64(%rsp),$ctx			# debugging artefact
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,96+0(%rsp)
-+	movaps	%xmm7,96+16(%rsp)
-+	movaps	%xmm8,96+32(%rsp)
-+	movaps	%xmm9,96+48(%rsp)
-+	movaps	%xmm10,96+64(%rsp)
-+	movaps	%xmm11,96+80(%rsp)
-+	movaps	%xmm12,96+96(%rsp)
-+	movaps	%xmm13,96+112(%rsp)
-+	movaps	%xmm14,96+128(%rsp)
-+	movaps	%xmm15,96+144(%rsp)
-+.Lprologue_ssse3:
-+___
-+$code.=<<___;
-+	mov	$in0,%r12			# reassign arguments
-+	mov	$out,%r13
-+	mov	$len,%r14
-+	lea	112($key),%r15			# size optimization
-+	movdqu	($ivp),$iv			# load IV
-+	mov	$ivp,88(%rsp)			# save $ivp
-+___
-+($in0,$out,$len,$key)=map("%r$_",(12..15));	# reassign arguments
-+my $rounds="${ivp}d";
-+$code.=<<___;
-+	shl	\$6,$len
-+	sub	$in0,$out
-+	mov	240-112($key),$rounds
-+	add	$inp,$len		# end of input
-+
-+	lea	K_XX_XX(%rip),$K_XX_XX
-+	mov	0($ctx),$A		# load context
-+	mov	4($ctx),$B
-+	mov	8($ctx),$C
-+	mov	12($ctx),$D
-+	mov	$B,@T[0]		# magic seed
-+	mov	16($ctx),$E
-+	mov	$C,@T[1]
-+	xor	$D,@T[1]
-+	and	@T[1],@T[0]
-+
-+	movdqa	64($K_XX_XX),@Tx[2]	# pbswap mask
-+	movdqa	0($K_XX_XX),@Tx[1]	# K_00_19
-+	movdqu	0($inp),@X[-4&7]	# load input to %xmm[0-3]
-+	movdqu	16($inp),@X[-3&7]
-+	movdqu	32($inp),@X[-2&7]
-+	movdqu	48($inp),@X[-1&7]
-+	pshufb	@Tx[2],@X[-4&7]		# byte swap
-+	pshufb	@Tx[2],@X[-3&7]
-+	pshufb	@Tx[2],@X[-2&7]
-+	add	\$64,$inp
-+	paddd	@Tx[1],@X[-4&7]		# add K_00_19
-+	pshufb	@Tx[2],@X[-1&7]
-+	paddd	@Tx[1],@X[-3&7]
-+	paddd	@Tx[1],@X[-2&7]
-+	movdqa	@X[-4&7],0(%rsp)	# X[]+K xfer to IALU
-+	psubd	@Tx[1],@X[-4&7]		# restore X[]
-+	movdqa	@X[-3&7],16(%rsp)
-+	psubd	@Tx[1],@X[-3&7]
-+	movdqa	@X[-2&7],32(%rsp)
-+	psubd	@Tx[1],@X[-2&7]
-+	movups	-112($key),$rndkey0	# $key[0]
-+	movups	16-112($key),$rndkey[0]	# forward reference
-+	jmp	.Loop_ssse3
-+___
-+
-+my $aesenc=sub {
-+  use integer;
-+  my ($n,$k)=($r/10,$r%10);
-+    if ($k==0) {
-+      $code.=<<___;
-+	movups		`16*$n`($in0),$in		# load input
-+	xorps		$rndkey0,$in
-+___
-+      $code.=<<___ if ($n);
-+	movups		$iv,`16*($n-1)`($out,$in0)	# write output
-+___
-+      $code.=<<___;
-+	xorps		$in,$iv
-+	movups		`32+16*$k-112`($key),$rndkey[1]
-+	aesenc		$rndkey[0],$iv
-+___
-+    } elsif ($k==9) {
-+      $sn++;
-+      $code.=<<___;
-+	cmp		\$11,$rounds
-+	jb		.Laesenclast$sn
-+	movups		`32+16*($k+0)-112`($key),$rndkey[1]
-+	aesenc		$rndkey[0],$iv
-+	movups		`32+16*($k+1)-112`($key),$rndkey[0]
-+	aesenc		$rndkey[1],$iv
-+	je		.Laesenclast$sn
-+	movups		`32+16*($k+2)-112`($key),$rndkey[1]
-+	aesenc		$rndkey[0],$iv
-+	movups		`32+16*($k+3)-112`($key),$rndkey[0]
-+	aesenc		$rndkey[1],$iv
-+.Laesenclast$sn:
-+	aesenclast	$rndkey[0],$iv
-+	movups		16-112($key),$rndkey[1]		# forward reference
-+___
-+    } else {
-+      $code.=<<___;
-+	movups		`32+16*$k-112`($key),$rndkey[1]
-+	aesenc		$rndkey[0],$iv
-+___
-+    }
-+    $r++;	unshift(@rndkey,pop(@rndkey));
-+};
-+
-+sub Xupdate_ssse3_16_31()		# recall that $Xi starts wtih 4
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));		# ror
-+	&pshufd	(@X[0],@X[-4&7],0xee);	# was &movdqa	(@X[0],@X[-3&7]);
-+	 eval(shift(@insns));
-+	&movdqa	(@Tx[0],@X[-1&7]);
-+	  &paddd	(@Tx[1],@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&punpcklqdq(@X[0],@X[-3&7]);	# compose "X[-14]" in "X[0]", was &palignr(@X[0],@X[-4&7],8);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	&psrldq	(@Tx[0],4);		# "X[-3]", 3 dwords
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@X[-4&7]);	# "X[0]"^="X[-16]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	&pxor	(@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@Tx[0]);		# "X[0]"^="X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&movdqa	(@Tx[2],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	&movdqa	(@Tx[0],@X[0]);
-+	 eval(shift(@insns));
-+
-+	&pslldq	(@Tx[2],12);		# "X[0]"<<96, extract one dword
-+	&paddd	(@X[0],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&psrld	(@Tx[0],31);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	&movdqa	(@Tx[1],@Tx[2]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&psrld	(@Tx[2],30);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	&por	(@X[0],@Tx[0]);		# "X[0]"<<<=1
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pslld	(@Tx[1],2);
-+	&pxor	(@X[0],@Tx[2]);
-+	 eval(shift(@insns));
-+	  &movdqa	(@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)");	# K_XX_XX
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@Tx[1]);		# "X[0]"^=("X[0]">>96)<<<2
-+	&pshufd (@Tx[1],@X[-1&7],0xee)	if ($Xi==7);	# was &movdqa	(@Tx[0],@X[-1&7]) in Xupdate_ssse3_32_79
-+
-+	 foreach (@insns) { eval; }	# remaining instructions [if any]
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+		push(@Tx,shift(@Tx));
-+}
-+
-+sub Xupdate_ssse3_32_79()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 44 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns))		if ($Xi==8);
-+	&pxor	(@X[0],@X[-4&7]);	# "X[0]"="X[-32]"^"X[-16]"
-+	 eval(shift(@insns))		if ($Xi==8);
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns))		if (@insns[1] =~ /_ror/);
-+	 eval(shift(@insns))		if (@insns[0] =~ /_ror/);
-+	&punpcklqdq(@Tx[0],@X[-1&7]);	# compose "X[-6]", was &palignr(@Tx[0],@X[-2&7],8);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+
-+	&pxor	(@X[0],@X[-7&7]);	# "X[0]"^="X[-28]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	if ($Xi%5) {
-+	  &movdqa	(@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX...
-+	} else {			# ... or load next one
-+	  &movdqa	(@Tx[2],eval(16*($Xi/5))."($K_XX_XX)");
-+	}
-+	 eval(shift(@insns));		# ror
-+	  &paddd	(@Tx[1],@X[-1&7]);
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@Tx[0]);		# "X[0]"^="X[-6]"
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns))		if (@insns[0] =~ /_ror/);
-+
-+	&movdqa	(@Tx[0],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# body_20_39
-+
-+	&pslld	(@X[0],2);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&psrld	(@Tx[0],30);
-+	 eval(shift(@insns))		if (@insns[0] =~ /_rol/);# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+
-+	&por	(@X[0],@Tx[0]);		# "X[0]"<<<=2
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns))		if (@insns[1] =~ /_rol/);
-+	 eval(shift(@insns))		if (@insns[0] =~ /_rol/);
-+	  &pshufd(@Tx[1],@X[-1&7],0xee)	if ($Xi<19);	# was &movdqa	(@Tx[1],@X[0])
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+
-+	 foreach (@insns) { eval; }	# remaining instructions
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+		push(@Tx,shift(@Tx));
-+}
-+
-+sub Xuplast_ssse3_80()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &paddd	(@Tx[1],@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer IALU
-+
-+	 foreach (@insns) { eval; }		# remaining instructions
-+
-+	&cmp	($inp,$len);
-+	&je	(shift);
-+
-+	unshift(@Tx,pop(@Tx));
-+
-+	&movdqa	(@Tx[2],"64($K_XX_XX)");	# pbswap mask
-+	&movdqa	(@Tx[1],"0($K_XX_XX)");		# K_00_19
-+	&movdqu	(@X[-4&7],"0($inp)");		# load input
-+	&movdqu	(@X[-3&7],"16($inp)");
-+	&movdqu	(@X[-2&7],"32($inp)");
-+	&movdqu	(@X[-1&7],"48($inp)");
-+	&pshufb	(@X[-4&7],@Tx[2]);		# byte swap
-+	&add	($inp,64);
-+
-+  $Xi=0;
-+}
-+
-+sub Xloop_ssse3()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&pshufb	(@X[($Xi-3)&7],@Tx[2]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&paddd	(@X[($Xi-4)&7],@Tx[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&movdqa	(eval(16*$Xi)."(%rsp)",@X[($Xi-4)&7]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&psubd	(@X[($Xi-4)&7],@Tx[1]);
-+
-+	foreach (@insns) { eval; }
-+  $Xi++;
-+}
-+
-+sub Xtail_ssse3()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	foreach (@insns) { eval; }
-+}
-+
-+my @body_00_19 = (
-+	'($a,$b,$c,$d,$e)=@V;'.
-+	'&$_ror	($b,$j?7:2);',	# $b>>>2
-+	'&xor	(@T[0],$d);',
-+	'&mov	(@T[1],$a);',	# $b for next round
-+
-+	'&add	($e,eval(4*($j&15))."(%rsp)");',# X[]+K xfer
-+	'&xor	($b,$c);',	# $c^$d for next round
-+
-+	'&$_rol	($a,5);',
-+	'&add	($e,@T[0]);',
-+	'&and	(@T[1],$b);',	# ($b&($c^$d)) for next round
-+
-+	'&xor	($b,$c);',	# restore $b
-+	'&add	($e,$a);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+
-+sub body_00_19 () {	# ((c^d)&b)^d
-+    # on start @T[0]=(c^d)&b
-+    return &body_20_39() if ($rx==19); $rx++;
-+
-+    use integer;
-+    my ($k,$n);
-+    my @r=@body_00_19;
-+
-+	$n = scalar(@r);
-+	$k = (($jj+1)*12/20)*20*$n/12;	# 12 aesencs per these 20 rounds
-+	@r[$k%$n].='&$aesenc();'	if ($jj==$k/$n);
-+	$jj++;
-+
-+    return @r;
-+}
-+
-+my @body_20_39 = (
-+	'($a,$b,$c,$d,$e)=@V;'.
-+	'&add	($e,eval(4*($j&15))."(%rsp)");',# X[]+K xfer
-+	'&xor	(@T[0],$d)	if($j==19);'.
-+	'&xor	(@T[0],$c)	if($j> 19);',	# ($b^$d^$c)
-+	'&mov	(@T[1],$a);',	# $b for next round
-+
-+	'&$_rol	($a,5);',
-+	'&add	($e,@T[0]);',
-+	'&xor	(@T[1],$c)	if ($j< 79);',	# $b^$d for next round
-+
-+	'&$_ror	($b,7);',	# $b>>>2
-+	'&add	($e,$a);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+
-+sub body_20_39 () {	# b^d^c
-+    # on entry @T[0]=b^d
-+    return &body_40_59() if ($rx==39); $rx++;
-+
-+    use integer;
-+    my ($k,$n);
-+    my @r=@body_20_39;
-+
-+	$n = scalar(@r);
-+	$k = (($jj+1)*8/20)*20*$n/8;	# 8 aesencs per these 20 rounds
-+	@r[$k%$n].='&$aesenc();'	if ($jj==$k/$n && $rx!=20);
-+	$jj++;
-+
-+    return @r;
-+}
-+
-+my @body_40_59 = (
-+	'($a,$b,$c,$d,$e)=@V;'.
-+	'&add	($e,eval(4*($j&15))."(%rsp)");',# X[]+K xfer
-+	'&and	(@T[0],$c)	if ($j>=40);',	# (b^c)&(c^d)
-+	'&xor	($c,$d)		if ($j>=40);',	# restore $c
-+
-+	'&$_ror	($b,7);',	# $b>>>2
-+	'&mov	(@T[1],$a);',	# $b for next round
-+	'&xor	(@T[0],$c);',
-+
-+	'&$_rol	($a,5);',
-+	'&add	($e,@T[0]);',
-+	'&xor	(@T[1],$c)	if ($j==59);'.
-+	'&xor	(@T[1],$b)	if ($j< 59);',	# b^c for next round
-+
-+	'&xor	($b,$c)		if ($j< 59);',	# c^d for next round
-+	'&add	($e,$a);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+
-+sub body_40_59 () {	# ((b^c)&(c^d))^c
-+    # on entry @T[0]=(b^c), (c^=d)
-+    $rx++;
-+
-+    use integer;
-+    my ($k,$n);
-+    my @r=@body_40_59;
-+
-+	$n = scalar(@r);
-+	$k=(($jj+1)*12/20)*20*$n/12;	# 12 aesencs per these 20 rounds
-+	@r[$k%$n].='&$aesenc();'	if ($jj==$k/$n && $rx!=40);
-+	$jj++;
-+
-+    return @r;
-+}
-+$code.=<<___;
-+.align	32
-+.Loop_ssse3:
-+___
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_32_79(\&body_00_19);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xuplast_ssse3_80(\&body_20_39,".Ldone_ssse3");	# can jump to "done"
-+
-+				$saved_j=$j; @saved_V=@V;
-+				$saved_r=$r; @saved_rndkey=@rndkey;
-+
-+	&Xloop_ssse3(\&body_20_39);
-+	&Xloop_ssse3(\&body_20_39);
-+	&Xloop_ssse3(\&body_20_39);
-+
-+$code.=<<___;
-+	movups	$iv,48($out,$in0)		# write output
-+	lea	64($in0),$in0
-+
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	add	12($ctx),$D
-+	mov	$A,0($ctx)
-+	add	16($ctx),$E
-+	mov	@T[0],4($ctx)
-+	mov	@T[0],$B			# magic seed
-+	mov	$C,8($ctx)
-+	mov	$C,@T[1]
-+	mov	$D,12($ctx)
-+	xor	$D,@T[1]
-+	mov	$E,16($ctx)
-+	and	@T[1],@T[0]
-+	jmp	.Loop_ssse3
-+
-+.Ldone_ssse3:
-+___
-+				$jj=$j=$saved_j; @V=@saved_V;
-+				$r=$saved_r;     @rndkey=@saved_rndkey;
-+
-+	&Xtail_ssse3(\&body_20_39);
-+	&Xtail_ssse3(\&body_20_39);
-+	&Xtail_ssse3(\&body_20_39);
-+
-+$code.=<<___;
-+	movups	$iv,48($out,$in0)		# write output
-+	mov	88(%rsp),$ivp			# restore $ivp
-+
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	mov	$A,0($ctx)
-+	add	12($ctx),$D
-+	mov	@T[0],4($ctx)
-+	add	16($ctx),$E
-+	mov	$C,8($ctx)
-+	mov	$D,12($ctx)
-+	mov	$E,16($ctx)
-+	movups	$iv,($ivp)			# write IV
-+___
-+$code.=<<___ if ($win64);
-+	movaps	96+0(%rsp),%xmm6
-+	movaps	96+16(%rsp),%xmm7
-+	movaps	96+32(%rsp),%xmm8
-+	movaps	96+48(%rsp),%xmm9
-+	movaps	96+64(%rsp),%xmm10
-+	movaps	96+80(%rsp),%xmm11
-+	movaps	96+96(%rsp),%xmm12
-+	movaps	96+112(%rsp),%xmm13
-+	movaps	96+128(%rsp),%xmm14
-+	movaps	96+144(%rsp),%xmm15
-+___
-+$code.=<<___;
-+	lea	`104+($win64?10*16:0)`(%rsp),%rsi
-+	mov	0(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_ssse3:
-+	ret
-+.size	aesni_cbc_sha1_enc_ssse3,.-aesni_cbc_sha1_enc_ssse3
-+___
-+
-+						if ($stitched_decrypt) {{{
-+# reset
-+($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
-+$j=$jj=$r=$rx=0;
-+$Xi=4;
-+
-+# reassign for Atom Silvermont (see above)
-+($inout0,$inout1,$inout2,$inout3,$rndkey0)=map("%xmm$_",(0..4));
-+@X=map("%xmm$_",(8..13,6,7));
-+@Tx=map("%xmm$_",(14,15,5));
-+
-+my @aes256_dec = (
-+	'&movdqu($inout0,"0x00($in0)");',
-+	'&movdqu($inout1,"0x10($in0)");	&pxor	($inout0,$rndkey0);',
-+	'&movdqu($inout2,"0x20($in0)");	&pxor	($inout1,$rndkey0);',
-+	'&movdqu($inout3,"0x30($in0)");	&pxor	($inout2,$rndkey0);',
-+
-+	'&pxor	($inout3,$rndkey0);	&movups	($rndkey0,"16-112($key)");',
-+	'&movaps("64(%rsp)",@X[2]);',	# save IV, originally @X[3]
-+	undef,undef
-+	);
-+for ($i=0;$i<13;$i++) {
-+    push (@aes256_dec,(
-+	'&aesdec	($inout0,$rndkey0);',
-+	'&aesdec	($inout1,$rndkey0);',
-+	'&aesdec	($inout2,$rndkey0);',
-+	'&aesdec	($inout3,$rndkey0);	&movups($rndkey0,"'.(16*($i+2)-112).'($key)");'
-+	));
-+    push (@aes256_dec,(undef,undef))	if (($i>=3 && $i<=5) || $i>=11);
-+    push (@aes256_dec,(undef,undef))	if ($i==5);
-+}
-+push(@aes256_dec,(
-+	'&aesdeclast	($inout0,$rndkey0);	&movups	(@X[0],"0x00($in0)");',
-+	'&aesdeclast	($inout1,$rndkey0);	&movups	(@X[1],"0x10($in0)");',
-+	'&aesdeclast	($inout2,$rndkey0);	&movups	(@X[2],"0x20($in0)");',
-+	'&aesdeclast	($inout3,$rndkey0);	&movups	(@X[3],"0x30($in0)");',
-+
-+	'&xorps		($inout0,"64(%rsp)");	&movdqu	($rndkey0,"-112($key)");',
-+	'&xorps		($inout1,@X[0]);	&movups	("0x00($out,$in0)",$inout0);',
-+	'&xorps		($inout2,@X[1]);	&movups	("0x10($out,$in0)",$inout1);',
-+	'&xorps		($inout3,@X[2]);	&movups	("0x20($out,$in0)",$inout2);',
-+
-+	'&movups	("0x30($out,$in0)",$inout3);'
-+	));
-+
-+sub body_00_19_dec () {	# ((c^d)&b)^d
-+    # on start @T[0]=(c^d)&b
-+    return &body_20_39_dec() if ($rx==19);
-+
-+    my @r=@body_00_19;
-+
-+	unshift (@r,@aes256_dec[$rx])	if (@aes256_dec[$rx]);
-+	$rx++;
-+
-+    return @r;
-+}
-+
-+sub body_20_39_dec () {	# b^d^c
-+    # on entry @T[0]=b^d
-+    return &body_40_59_dec() if ($rx==39);
-+  
-+    my @r=@body_20_39;
-+
-+	unshift (@r,@aes256_dec[$rx])	if (@aes256_dec[$rx]);
-+	$rx++;
-+
-+    return @r;
-+}
-+
-+sub body_40_59_dec () {	# ((b^c)&(c^d))^c
-+    # on entry @T[0]=(b^c), (c^=d)
-+
-+    my @r=@body_40_59;
-+
-+	unshift (@r,@aes256_dec[$rx])	if (@aes256_dec[$rx]);
-+	$rx++;
-+
-+    return @r;
-+}
-+
-+$code.=<<___;
-+.globl	aesni256_cbc_sha1_dec
-+.type	aesni256_cbc_sha1_dec,\@abi-omnipotent
-+.align	32
-+aesni256_cbc_sha1_dec:
-+	# caller should check for SSSE3 and AES-NI bits
-+	mov	OPENSSL_ia32cap_P+0(%rip),%r10d
-+	mov	OPENSSL_ia32cap_P+4(%rip),%r11d
-+___
-+$code.=<<___ if ($avx);
-+	and	\$`1<<28`,%r11d		# mask AVX bit
-+	and	\$`1<<30`,%r10d		# mask "Intel CPU" bit
-+	or	%r11d,%r10d
-+	cmp	\$`1<<28|1<<30`,%r10d
-+	je	aesni256_cbc_sha1_dec_avx
-+___
-+$code.=<<___;
-+	jmp	aesni256_cbc_sha1_dec_ssse3
-+	ret
-+.size	aesni256_cbc_sha1_dec,.-aesni256_cbc_sha1_dec
-+
-+.type	aesni256_cbc_sha1_dec_ssse3,\@function,6
-+.align	32
-+aesni256_cbc_sha1_dec_ssse3:
-+	mov	`($win64?56:8)`(%rsp),$inp	# load 7th argument
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	lea	`-104-($win64?10*16:0)`(%rsp),%rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,96+0(%rsp)
-+	movaps	%xmm7,96+16(%rsp)
-+	movaps	%xmm8,96+32(%rsp)
-+	movaps	%xmm9,96+48(%rsp)
-+	movaps	%xmm10,96+64(%rsp)
-+	movaps	%xmm11,96+80(%rsp)
-+	movaps	%xmm12,96+96(%rsp)
-+	movaps	%xmm13,96+112(%rsp)
-+	movaps	%xmm14,96+128(%rsp)
-+	movaps	%xmm15,96+144(%rsp)
-+.Lprologue_dec_ssse3:
-+___
-+$code.=<<___;
-+	mov	$in0,%r12			# reassign arguments
-+	mov	$out,%r13
-+	mov	$len,%r14
-+	lea	112($key),%r15			# size optimization
-+	movdqu	($ivp),@X[3]			# load IV
-+	#mov	$ivp,88(%rsp)			# save $ivp
-+___
-+($in0,$out,$len,$key)=map("%r$_",(12..15));	# reassign arguments
-+$code.=<<___;
-+	shl	\$6,$len
-+	sub	$in0,$out
-+	add	$inp,$len		# end of input
-+
-+	lea	K_XX_XX(%rip),$K_XX_XX
-+	mov	0($ctx),$A		# load context
-+	mov	4($ctx),$B
-+	mov	8($ctx),$C
-+	mov	12($ctx),$D
-+	mov	$B,@T[0]		# magic seed
-+	mov	16($ctx),$E
-+	mov	$C,@T[1]
-+	xor	$D,@T[1]
-+	and	@T[1],@T[0]
-+
-+	movdqa	64($K_XX_XX),@Tx[2]	# pbswap mask
-+	movdqa	0($K_XX_XX),@Tx[1]	# K_00_19
-+	movdqu	0($inp),@X[-4&7]	# load input to %xmm[0-3]
-+	movdqu	16($inp),@X[-3&7]
-+	movdqu	32($inp),@X[-2&7]
-+	movdqu	48($inp),@X[-1&7]
-+	pshufb	@Tx[2],@X[-4&7]		# byte swap
-+	add	\$64,$inp
-+	pshufb	@Tx[2],@X[-3&7]
-+	pshufb	@Tx[2],@X[-2&7]
-+	pshufb	@Tx[2],@X[-1&7]
-+	paddd	@Tx[1],@X[-4&7]		# add K_00_19
-+	paddd	@Tx[1],@X[-3&7]
-+	paddd	@Tx[1],@X[-2&7]
-+	movdqa	@X[-4&7],0(%rsp)	# X[]+K xfer to IALU
-+	psubd	@Tx[1],@X[-4&7]		# restore X[]
-+	movdqa	@X[-3&7],16(%rsp)
-+	psubd	@Tx[1],@X[-3&7]
-+	movdqa	@X[-2&7],32(%rsp)
-+	psubd	@Tx[1],@X[-2&7]
-+	movdqu	-112($key),$rndkey0	# $key[0]
-+	jmp	.Loop_dec_ssse3
-+
-+.align	32
-+.Loop_dec_ssse3:
-+___
-+	&Xupdate_ssse3_16_31(\&body_00_19_dec);
-+	&Xupdate_ssse3_16_31(\&body_00_19_dec);
-+	&Xupdate_ssse3_16_31(\&body_00_19_dec);
-+	&Xupdate_ssse3_16_31(\&body_00_19_dec);
-+	&Xupdate_ssse3_32_79(\&body_00_19_dec);
-+	&Xupdate_ssse3_32_79(\&body_20_39_dec);
-+	&Xupdate_ssse3_32_79(\&body_20_39_dec);
-+	&Xupdate_ssse3_32_79(\&body_20_39_dec);
-+	&Xupdate_ssse3_32_79(\&body_20_39_dec);
-+	&Xupdate_ssse3_32_79(\&body_20_39_dec);
-+	&Xupdate_ssse3_32_79(\&body_40_59_dec);
-+	&Xupdate_ssse3_32_79(\&body_40_59_dec);
-+	&Xupdate_ssse3_32_79(\&body_40_59_dec);
-+	&Xupdate_ssse3_32_79(\&body_40_59_dec);
-+	&Xupdate_ssse3_32_79(\&body_40_59_dec);
-+	&Xupdate_ssse3_32_79(\&body_20_39_dec);
-+	&Xuplast_ssse3_80(\&body_20_39_dec,".Ldone_dec_ssse3");	# can jump to "done"
-+
-+				$saved_j=$j;   @saved_V=@V;
-+				$saved_rx=$rx;
-+
-+	&Xloop_ssse3(\&body_20_39_dec);
-+	&Xloop_ssse3(\&body_20_39_dec);
-+	&Xloop_ssse3(\&body_20_39_dec);
-+
-+	eval(@aes256_dec[-1]);			# last store
-+$code.=<<___;
-+	lea	64($in0),$in0
-+
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	add	12($ctx),$D
-+	mov	$A,0($ctx)
-+	add	16($ctx),$E
-+	mov	@T[0],4($ctx)
-+	mov	@T[0],$B			# magic seed
-+	mov	$C,8($ctx)
-+	mov	$C,@T[1]
-+	mov	$D,12($ctx)
-+	xor	$D,@T[1]
-+	mov	$E,16($ctx)
-+	and	@T[1],@T[0]
-+	jmp	.Loop_dec_ssse3
-+
-+.Ldone_dec_ssse3:
-+___
-+				$jj=$j=$saved_j; @V=@saved_V;
-+				$rx=$saved_rx;
-+
-+	&Xtail_ssse3(\&body_20_39_dec);
-+	&Xtail_ssse3(\&body_20_39_dec);
-+	&Xtail_ssse3(\&body_20_39_dec);
-+
-+	eval(@aes256_dec[-1]);			# last store
-+$code.=<<___;
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	mov	$A,0($ctx)
-+	add	12($ctx),$D
-+	mov	@T[0],4($ctx)
-+	add	16($ctx),$E
-+	mov	$C,8($ctx)
-+	mov	$D,12($ctx)
-+	mov	$E,16($ctx)
-+	movups	@X[3],($ivp)			# write IV
-+___
-+$code.=<<___ if ($win64);
-+	movaps	96+0(%rsp),%xmm6
-+	movaps	96+16(%rsp),%xmm7
-+	movaps	96+32(%rsp),%xmm8
-+	movaps	96+48(%rsp),%xmm9
-+	movaps	96+64(%rsp),%xmm10
-+	movaps	96+80(%rsp),%xmm11
-+	movaps	96+96(%rsp),%xmm12
-+	movaps	96+112(%rsp),%xmm13
-+	movaps	96+128(%rsp),%xmm14
-+	movaps	96+144(%rsp),%xmm15
-+___
-+$code.=<<___;
-+	lea	`104+($win64?10*16:0)`(%rsp),%rsi
-+	mov	0(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_dec_ssse3:
-+	ret
-+.size	aesni256_cbc_sha1_dec_ssse3,.-aesni256_cbc_sha1_dec_ssse3
-+___
-+						}}}
-+$j=$jj=$r=$rx=0;
-+
-+if ($avx) {
-+my ($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
-+
-+my $Xi=4;
-+my @X=map("%xmm$_",(4..7,0..3));
-+my @Tx=map("%xmm$_",(8..10));
-+my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp");	# size optimization
-+my @T=("%esi","%edi");
-+my ($rndkey0,$iv,$in)=map("%xmm$_",(11..13));
-+my @rndkey=("%xmm14","%xmm15");
-+my ($inout0,$inout1,$inout2,$inout3)=map("%xmm$_",(12..15));	# for dec
-+my $Kx=@Tx[2];
-+
-+my $_rol=sub { &shld(@_[0],@_) };
-+my $_ror=sub { &shrd(@_[0],@_) };
-+
-+$code.=<<___;
-+.type	aesni_cbc_sha1_enc_avx,\@function,6
-+.align	32
-+aesni_cbc_sha1_enc_avx:
-+	mov	`($win64?56:8)`(%rsp),$inp	# load 7th argument
-+	#shr	\$6,$len			# debugging artefact
-+	#jz	.Lepilogue_avx			# debugging artefact
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	lea	`-104-($win64?10*16:0)`(%rsp),%rsp
-+	#mov	$in0,$inp			# debugging artefact
-+	#lea	64(%rsp),$ctx			# debugging artefact
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,96+0(%rsp)
-+	movaps	%xmm7,96+16(%rsp)
-+	movaps	%xmm8,96+32(%rsp)
-+	movaps	%xmm9,96+48(%rsp)
-+	movaps	%xmm10,96+64(%rsp)
-+	movaps	%xmm11,96+80(%rsp)
-+	movaps	%xmm12,96+96(%rsp)
-+	movaps	%xmm13,96+112(%rsp)
-+	movaps	%xmm14,96+128(%rsp)
-+	movaps	%xmm15,96+144(%rsp)
-+.Lprologue_avx:
-+___
-+$code.=<<___;
-+	vzeroall
-+	mov	$in0,%r12			# reassign arguments
-+	mov	$out,%r13
-+	mov	$len,%r14
-+	lea	112($key),%r15			# size optimization
-+	vmovdqu	($ivp),$iv			# load IV
-+	mov	$ivp,88(%rsp)			# save $ivp
-+___
-+($in0,$out,$len,$key)=map("%r$_",(12..15));	# reassign arguments
-+my $rounds="${ivp}d";
-+$code.=<<___;
-+	shl	\$6,$len
-+	sub	$in0,$out
-+	mov	240-112($key),$rounds
-+	add	$inp,$len		# end of input
-+
-+	lea	K_XX_XX(%rip),$K_XX_XX
-+	mov	0($ctx),$A		# load context
-+	mov	4($ctx),$B
-+	mov	8($ctx),$C
-+	mov	12($ctx),$D
-+	mov	$B,@T[0]		# magic seed
-+	mov	16($ctx),$E
-+	mov	$C,@T[1]
-+	xor	$D,@T[1]
-+	and	@T[1],@T[0]
-+
-+	vmovdqa	64($K_XX_XX),@X[2]	# pbswap mask
-+	vmovdqa	0($K_XX_XX),$Kx		# K_00_19
-+	vmovdqu	0($inp),@X[-4&7]	# load input to %xmm[0-3]
-+	vmovdqu	16($inp),@X[-3&7]
-+	vmovdqu	32($inp),@X[-2&7]
-+	vmovdqu	48($inp),@X[-1&7]
-+	vpshufb	@X[2],@X[-4&7],@X[-4&7]	# byte swap
-+	add	\$64,$inp
-+	vpshufb	@X[2],@X[-3&7],@X[-3&7]
-+	vpshufb	@X[2],@X[-2&7],@X[-2&7]
-+	vpshufb	@X[2],@X[-1&7],@X[-1&7]
-+	vpaddd	$Kx,@X[-4&7],@X[0]	# add K_00_19
-+	vpaddd	$Kx,@X[-3&7],@X[1]
-+	vpaddd	$Kx,@X[-2&7],@X[2]
-+	vmovdqa	@X[0],0(%rsp)		# X[]+K xfer to IALU
-+	vmovdqa	@X[1],16(%rsp)
-+	vmovdqa	@X[2],32(%rsp)
-+	vmovups	-112($key),$rndkey[1]	# $key[0]
-+	vmovups	16-112($key),$rndkey[0]	# forward reference
-+	jmp	.Loop_avx
-+___
-+
-+my $aesenc=sub {
-+  use integer;
-+  my ($n,$k)=($r/10,$r%10);
-+    if ($k==0) {
-+      $code.=<<___;
-+	vmovdqu		`16*$n`($in0),$in		# load input
-+	vpxor		$rndkey[1],$in,$in
-+___
-+      $code.=<<___ if ($n);
-+	vmovups		$iv,`16*($n-1)`($out,$in0)	# write output
-+___
-+      $code.=<<___;
-+	vpxor		$in,$iv,$iv
-+	vaesenc		$rndkey[0],$iv,$iv
-+	vmovups		`32+16*$k-112`($key),$rndkey[1]
-+___
-+    } elsif ($k==9) {
-+      $sn++;
-+      $code.=<<___;
-+	cmp		\$11,$rounds
-+	jb		.Lvaesenclast$sn
-+	vaesenc		$rndkey[0],$iv,$iv
-+	vmovups		`32+16*($k+0)-112`($key),$rndkey[1]
-+	vaesenc		$rndkey[1],$iv,$iv
-+	vmovups		`32+16*($k+1)-112`($key),$rndkey[0]
-+	je		.Lvaesenclast$sn
-+	vaesenc		$rndkey[0],$iv,$iv
-+	vmovups		`32+16*($k+2)-112`($key),$rndkey[1]
-+	vaesenc		$rndkey[1],$iv,$iv
-+	vmovups		`32+16*($k+3)-112`($key),$rndkey[0]
-+.Lvaesenclast$sn:
-+	vaesenclast	$rndkey[0],$iv,$iv
-+	vmovups		-112($key),$rndkey[0]
-+	vmovups		16-112($key),$rndkey[1]		# forward reference
-+___
-+    } else {
-+      $code.=<<___;
-+	vaesenc		$rndkey[0],$iv,$iv
-+	vmovups		`32+16*$k-112`($key),$rndkey[1]
-+___
-+    }
-+    $r++;	unshift(@rndkey,pop(@rndkey));
-+};
-+
-+sub Xupdate_avx_16_31()		# recall that $Xi starts wtih 4
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpalignr(@X[0],@X[-3&7],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	  &vpaddd	(@Tx[1],$Kx,@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpsrldq(@Tx[0],@X[-1&7],4);		# "X[-3]", 3 dwords
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"^="X[-16]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@Tx[0],@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vmovdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpsrld	(@Tx[0],@X[0],31);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpslldq(@Tx[1],@X[0],12);		# "X[0]"<<96, extract one dword
-+	&vpaddd	(@X[0],@X[0],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=1
-+	&vpsrld	(@Tx[0],@Tx[1],30);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpslld	(@Tx[1],@Tx[1],2);
-+	&vpxor	(@X[0],@X[0],@Tx[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@Tx[1]);		# "X[0]"^=("X[0]">>96)<<<2
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vmovdqa	($Kx,eval(16*(($Xi)/5))."($K_XX_XX)")	if ($Xi%5==0);	# K_XX_XX
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+
-+	 foreach (@insns) { eval; }	# remaining instructions [if any]
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xupdate_avx_32_79()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 48 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	&vpalignr(@Tx[0],@X[-1&7],@X[-2&7],8);	# compose "X[-6]"
-+	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"="X[-32]"^"X[-16]"
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+
-+	&vpxor	(@X[0],@X[0],@X[-7&7]);		# "X[0]"^="X[-28]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns))	if (@insns[0] !~ /&ro[rl]/);
-+	  &vpaddd	(@Tx[1],$Kx,@X[-1&7]);
-+	  &vmovdqa	($Kx,eval(16*($Xi/5))."($K_XX_XX)")	if ($Xi%5==0);
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-6]"
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+
-+	&vpsrld	(@Tx[0],@X[0],30);
-+	  &vmovdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+
-+	&vpslld	(@X[0],@X[0],2);
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+
-+	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=2
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+
-+	 foreach (@insns) { eval; }	# remaining instructions
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xuplast_avx_80()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	  &vpaddd	(@Tx[1],$Kx,@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	  &vmovdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer IALU
-+
-+	 foreach (@insns) { eval; }		# remaining instructions
-+
-+	&cmp	($inp,$len);
-+	&je	(shift);
-+
-+	&vmovdqa(@Tx[1],"64($K_XX_XX)");	# pbswap mask
-+	&vmovdqa($Kx,"0($K_XX_XX)");		# K_00_19
-+	&vmovdqu(@X[-4&7],"0($inp)");		# load input
-+	&vmovdqu(@X[-3&7],"16($inp)");
-+	&vmovdqu(@X[-2&7],"32($inp)");
-+	&vmovdqu(@X[-1&7],"48($inp)");
-+	&vpshufb(@X[-4&7],@X[-4&7],@Tx[1]);	# byte swap
-+	&add	($inp,64);
-+
-+  $Xi=0;
-+}
-+
-+sub Xloop_avx()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpshufb(@X[($Xi-3)&7],@X[($Xi-3)&7],@Tx[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpaddd	(@Tx[0],@X[($Xi-4)&7],$Kx);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vmovdqa(eval(16*$Xi)."(%rsp)",@Tx[0]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	foreach (@insns) { eval; }
-+  $Xi++;
-+}
-+
-+sub Xtail_avx()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	foreach (@insns) { eval; }
-+}
-+
-+$code.=<<___;
-+.align	32
-+.Loop_avx:
-+___
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_32_79(\&body_00_19);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xuplast_avx_80(\&body_20_39,".Ldone_avx");	# can jump to "done"
-+
-+				$saved_j=$j; @saved_V=@V;
-+				$saved_r=$r; @saved_rndkey=@rndkey;
-+
-+	&Xloop_avx(\&body_20_39);
-+	&Xloop_avx(\&body_20_39);
-+	&Xloop_avx(\&body_20_39);
-+
-+$code.=<<___;
-+	vmovups	$iv,48($out,$in0)		# write output
-+	lea	64($in0),$in0
-+
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	add	12($ctx),$D
-+	mov	$A,0($ctx)
-+	add	16($ctx),$E
-+	mov	@T[0],4($ctx)
-+	mov	@T[0],$B			# magic seed
-+	mov	$C,8($ctx)
-+	mov	$C,@T[1]
-+	mov	$D,12($ctx)
-+	xor	$D,@T[1]
-+	mov	$E,16($ctx)
-+	and	@T[1],@T[0]
-+	jmp	.Loop_avx
-+
-+.Ldone_avx:
-+___
-+				$jj=$j=$saved_j; @V=@saved_V;
-+				$r=$saved_r;     @rndkey=@saved_rndkey;
-+
-+	&Xtail_avx(\&body_20_39);
-+	&Xtail_avx(\&body_20_39);
-+	&Xtail_avx(\&body_20_39);
-+
-+$code.=<<___;
-+	vmovups	$iv,48($out,$in0)		# write output
-+	mov	88(%rsp),$ivp			# restore $ivp
-+
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	mov	$A,0($ctx)
-+	add	12($ctx),$D
-+	mov	@T[0],4($ctx)
-+	add	16($ctx),$E
-+	mov	$C,8($ctx)
-+	mov	$D,12($ctx)
-+	mov	$E,16($ctx)
-+	vmovups	$iv,($ivp)			# write IV
-+	vzeroall
-+___
-+$code.=<<___ if ($win64);
-+	movaps	96+0(%rsp),%xmm6
-+	movaps	96+16(%rsp),%xmm7
-+	movaps	96+32(%rsp),%xmm8
-+	movaps	96+48(%rsp),%xmm9
-+	movaps	96+64(%rsp),%xmm10
-+	movaps	96+80(%rsp),%xmm11
-+	movaps	96+96(%rsp),%xmm12
-+	movaps	96+112(%rsp),%xmm13
-+	movaps	96+128(%rsp),%xmm14
-+	movaps	96+144(%rsp),%xmm15
-+___
-+$code.=<<___;
-+	lea	`104+($win64?10*16:0)`(%rsp),%rsi
-+	mov	0(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_avx:
-+	ret
-+.size	aesni_cbc_sha1_enc_avx,.-aesni_cbc_sha1_enc_avx
-+___
-+
-+						if ($stitched_decrypt) {{{
-+# reset
-+($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
-+
-+$j=$jj=$r=$rx=0;
-+$Xi=4;
-+
-+@aes256_dec = (
-+	'&vpxor	($inout0,$rndkey0,"0x00($in0)");',
-+	'&vpxor	($inout1,$rndkey0,"0x10($in0)");',
-+	'&vpxor	($inout2,$rndkey0,"0x20($in0)");',
-+	'&vpxor	($inout3,$rndkey0,"0x30($in0)");',
-+
-+	'&vmovups($rndkey0,"16-112($key)");',
-+	'&vmovups("64(%rsp)",@X[2]);',		# save IV, originally @X[3]
-+	undef,undef
-+	);
-+for ($i=0;$i<13;$i++) {
-+    push (@aes256_dec,(
-+	'&vaesdec	($inout0,$inout0,$rndkey0);',
-+	'&vaesdec	($inout1,$inout1,$rndkey0);',
-+	'&vaesdec	($inout2,$inout2,$rndkey0);',
-+	'&vaesdec	($inout3,$inout3,$rndkey0);	&vmovups($rndkey0,"'.(16*($i+2)-112).'($key)");'
-+	));
-+    push (@aes256_dec,(undef,undef))	if (($i>=3 && $i<=5) || $i>=11);
-+    push (@aes256_dec,(undef,undef))	if ($i==5);
-+}
-+push(@aes256_dec,(
-+	'&vaesdeclast	($inout0,$inout0,$rndkey0);	&vmovups(@X[0],"0x00($in0)");',
-+	'&vaesdeclast	($inout1,$inout1,$rndkey0);	&vmovups(@X[1],"0x10($in0)");',
-+	'&vaesdeclast	($inout2,$inout2,$rndkey0);	&vmovups(@X[2],"0x20($in0)");',
-+	'&vaesdeclast	($inout3,$inout3,$rndkey0);	&vmovups(@X[3],"0x30($in0)");',
-+
-+	'&vxorps	($inout0,$inout0,"64(%rsp)");	&vmovdqu($rndkey0,"-112($key)");',
-+	'&vxorps	($inout1,$inout1,@X[0]);	&vmovups("0x00($out,$in0)",$inout0);',
-+	'&vxorps	($inout2,$inout2,@X[1]);	&vmovups("0x10($out,$in0)",$inout1);',
-+	'&vxorps	($inout3,$inout3,@X[2]);	&vmovups("0x20($out,$in0)",$inout2);',
-+
-+	'&vmovups	("0x30($out,$in0)",$inout3);'
-+	));
-+
-+$code.=<<___;
-+.type	aesni256_cbc_sha1_dec_avx,\@function,6
-+.align	32
-+aesni256_cbc_sha1_dec_avx:
-+	mov	`($win64?56:8)`(%rsp),$inp	# load 7th argument
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	lea	`-104-($win64?10*16:0)`(%rsp),%rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,96+0(%rsp)
-+	movaps	%xmm7,96+16(%rsp)
-+	movaps	%xmm8,96+32(%rsp)
-+	movaps	%xmm9,96+48(%rsp)
-+	movaps	%xmm10,96+64(%rsp)
-+	movaps	%xmm11,96+80(%rsp)
-+	movaps	%xmm12,96+96(%rsp)
-+	movaps	%xmm13,96+112(%rsp)
-+	movaps	%xmm14,96+128(%rsp)
-+	movaps	%xmm15,96+144(%rsp)
-+.Lprologue_dec_avx:
-+___
-+$code.=<<___;
-+	vzeroall
-+	mov	$in0,%r12			# reassign arguments
-+	mov	$out,%r13
-+	mov	$len,%r14
-+	lea	112($key),%r15			# size optimization
-+	vmovdqu	($ivp),@X[3]			# load IV
-+___
-+($in0,$out,$len,$key)=map("%r$_",(12..15));	# reassign arguments
-+$code.=<<___;
-+	shl	\$6,$len
-+	sub	$in0,$out
-+	add	$inp,$len		# end of input
-+
-+	lea	K_XX_XX(%rip),$K_XX_XX
-+	mov	0($ctx),$A		# load context
-+	mov	4($ctx),$B
-+	mov	8($ctx),$C
-+	mov	12($ctx),$D
-+	mov	$B,@T[0]		# magic seed
-+	mov	16($ctx),$E
-+	mov	$C,@T[1]
-+	xor	$D,@T[1]
-+	and	@T[1],@T[0]
-+
-+	vmovdqa	64($K_XX_XX),@X[2]	# pbswap mask
-+	vmovdqa	0($K_XX_XX),$Kx		# K_00_19
-+	vmovdqu	0($inp),@X[-4&7]	# load input to %xmm[0-3]
-+	vmovdqu	16($inp),@X[-3&7]
-+	vmovdqu	32($inp),@X[-2&7]
-+	vmovdqu	48($inp),@X[-1&7]
-+	vpshufb	@X[2],@X[-4&7],@X[-4&7]	# byte swap
-+	add	\$64,$inp
-+	vpshufb	@X[2],@X[-3&7],@X[-3&7]
-+	vpshufb	@X[2],@X[-2&7],@X[-2&7]
-+	vpshufb	@X[2],@X[-1&7],@X[-1&7]
-+	vpaddd	$Kx,@X[-4&7],@X[0]	# add K_00_19
-+	vpaddd	$Kx,@X[-3&7],@X[1]
-+	vpaddd	$Kx,@X[-2&7],@X[2]
-+	vmovdqa	@X[0],0(%rsp)		# X[]+K xfer to IALU
-+	vmovdqa	@X[1],16(%rsp)
-+	vmovdqa	@X[2],32(%rsp)
-+	vmovups	-112($key),$rndkey0	# $key[0]
-+	jmp	.Loop_dec_avx
-+
-+.align	32
-+.Loop_dec_avx:
-+___
-+	&Xupdate_avx_16_31(\&body_00_19_dec);
-+	&Xupdate_avx_16_31(\&body_00_19_dec);
-+	&Xupdate_avx_16_31(\&body_00_19_dec);
-+	&Xupdate_avx_16_31(\&body_00_19_dec);
-+	&Xupdate_avx_32_79(\&body_00_19_dec);
-+	&Xupdate_avx_32_79(\&body_20_39_dec);
-+	&Xupdate_avx_32_79(\&body_20_39_dec);
-+	&Xupdate_avx_32_79(\&body_20_39_dec);
-+	&Xupdate_avx_32_79(\&body_20_39_dec);
-+	&Xupdate_avx_32_79(\&body_20_39_dec);
-+	&Xupdate_avx_32_79(\&body_40_59_dec);
-+	&Xupdate_avx_32_79(\&body_40_59_dec);
-+	&Xupdate_avx_32_79(\&body_40_59_dec);
-+	&Xupdate_avx_32_79(\&body_40_59_dec);
-+	&Xupdate_avx_32_79(\&body_40_59_dec);
-+	&Xupdate_avx_32_79(\&body_20_39_dec);
-+	&Xuplast_avx_80(\&body_20_39_dec,".Ldone_dec_avx");	# can jump to "done"
-+
-+				$saved_j=$j; @saved_V=@V;
-+				$saved_rx=$rx;
-+
-+	&Xloop_avx(\&body_20_39_dec);
-+	&Xloop_avx(\&body_20_39_dec);
-+	&Xloop_avx(\&body_20_39_dec);
-+
-+	eval(@aes256_dec[-1]);			# last store
-+$code.=<<___;
-+	lea	64($in0),$in0
-+
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	add	12($ctx),$D
-+	mov	$A,0($ctx)
-+	add	16($ctx),$E
-+	mov	@T[0],4($ctx)
-+	mov	@T[0],$B			# magic seed
-+	mov	$C,8($ctx)
-+	mov	$C,@T[1]
-+	mov	$D,12($ctx)
-+	xor	$D,@T[1]
-+	mov	$E,16($ctx)
-+	and	@T[1],@T[0]
-+	jmp	.Loop_dec_avx
-+
-+.Ldone_dec_avx:
-+___
-+				$jj=$j=$saved_j; @V=@saved_V;
-+				$rx=$saved_rx;
-+
-+	&Xtail_avx(\&body_20_39_dec);
-+	&Xtail_avx(\&body_20_39_dec);
-+	&Xtail_avx(\&body_20_39_dec);
-+
-+	eval(@aes256_dec[-1]);			# last store
-+$code.=<<___;
-+
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	mov	$A,0($ctx)
-+	add	12($ctx),$D
-+	mov	@T[0],4($ctx)
-+	add	16($ctx),$E
-+	mov	$C,8($ctx)
-+	mov	$D,12($ctx)
-+	mov	$E,16($ctx)
-+	vmovups	@X[3],($ivp)			# write IV
-+	vzeroall
-+___
-+$code.=<<___ if ($win64);
-+	movaps	96+0(%rsp),%xmm6
-+	movaps	96+16(%rsp),%xmm7
-+	movaps	96+32(%rsp),%xmm8
-+	movaps	96+48(%rsp),%xmm9
-+	movaps	96+64(%rsp),%xmm10
-+	movaps	96+80(%rsp),%xmm11
-+	movaps	96+96(%rsp),%xmm12
-+	movaps	96+112(%rsp),%xmm13
-+	movaps	96+128(%rsp),%xmm14
-+	movaps	96+144(%rsp),%xmm15
-+___
-+$code.=<<___;
-+	lea	`104+($win64?10*16:0)`(%rsp),%rsi
-+	mov	0(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_dec_avx:
-+	ret
-+.size	aesni256_cbc_sha1_dec_avx,.-aesni256_cbc_sha1_dec_avx
-+___
-+						}}}
-+}
-+$code.=<<___;
-+.align	64
-+K_XX_XX:
-+.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	# K_00_19
-+.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	# K_20_39
-+.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	# K_40_59
-+.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	# K_60_79
-+.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	# pbswap mask
-+.byte	0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0
-+
-+.asciz	"AESNI-CBC+SHA1 stitch for x86_64, CRYPTOGAMS by "
-+.align	64
-+___
-+						if ($shaext) {{{
-+($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
-+
-+$rounds="%r11d";
-+
-+($iv,$in,$rndkey0)=map("%xmm$_",(2,14,15));
-+@rndkey=("%xmm0","%xmm1");
-+$r=0;
-+
-+my ($BSWAP,$ABCD,$E,$E_,$ABCD_SAVE,$E_SAVE)=map("%xmm$_",(7..12));
-+my @MSG=map("%xmm$_",(3..6));
-+
-+$code.=<<___;
-+.type	aesni_cbc_sha1_enc_shaext,\@function,6
-+.align	32
-+aesni_cbc_sha1_enc_shaext:
-+	mov	`($win64?56:8)`(%rsp),$inp	# load 7th argument
-+___
-+$code.=<<___ if ($win64);
-+	lea	`-8-10*16`(%rsp),%rsp
-+	movaps	%xmm6,-8-10*16(%rax)
-+	movaps	%xmm7,-8-9*16(%rax)
-+	movaps	%xmm8,-8-8*16(%rax)
-+	movaps	%xmm9,-8-7*16(%rax)
-+	movaps	%xmm10,-8-6*16(%rax)
-+	movaps	%xmm11,-8-5*16(%rax)
-+	movaps	%xmm12,-8-4*16(%rax)
-+	movaps	%xmm13,-8-3*16(%rax)
-+	movaps	%xmm14,-8-2*16(%rax)
-+	movaps	%xmm15,-8-1*16(%rax)
-+.Lprologue_shaext:
-+___
-+$code.=<<___;
-+	movdqu	($ctx),$ABCD
-+	movd	16($ctx),$E
-+	movdqa	K_XX_XX+0x50(%rip),$BSWAP	# byte-n-word swap
-+
-+	mov	240($key),$rounds
-+	sub	$in0,$out
-+	movups	($key),$rndkey0			# $key[0]
-+	movups	16($key),$rndkey[0]		# forward reference
-+	lea	112($key),$key			# size optimization
-+
-+	pshufd	\$0b00011011,$ABCD,$ABCD	# flip word order
-+	pshufd	\$0b00011011,$E,$E		# flip word order
-+	jmp	.Loop_shaext
-+
-+.align	16
-+.Loop_shaext:
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	movdqu		($inp),@MSG[0]
-+	movdqa		$E,$E_SAVE		# offload $E
-+	pshufb		$BSWAP,@MSG[0]
-+	movdqu		0x10($inp),@MSG[1]
-+	movdqa		$ABCD,$ABCD_SAVE	# offload $ABCD
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	pshufb		$BSWAP,@MSG[1]
-+
-+	paddd		@MSG[0],$E
-+	movdqu		0x20($inp),@MSG[2]
-+	lea		0x40($inp),$inp
-+	pxor		$E_SAVE,@MSG[0]		# black magic
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	pxor		$E_SAVE,@MSG[0]		# black magic
-+	movdqa		$ABCD,$E_
-+	pshufb		$BSWAP,@MSG[2]
-+	sha1rnds4	\$0,$E,$ABCD		# 0-3
-+	sha1nexte	@MSG[1],$E_
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha1msg1	@MSG[1],@MSG[0]
-+	movdqu		-0x10($inp),@MSG[3]
-+	movdqa		$ABCD,$E
-+	pshufb		$BSWAP,@MSG[3]
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha1rnds4	\$0,$E_,$ABCD		# 4-7
-+	sha1nexte	@MSG[2],$E
-+	pxor		@MSG[2],@MSG[0]
-+	sha1msg1	@MSG[2],@MSG[1]
-+___
-+	&$aesenc();
-+
-+for($i=2;$i<20-4;$i++) {
-+$code.=<<___;
-+	movdqa		$ABCD,$E_
-+	sha1rnds4	\$`int($i/5)`,$E,$ABCD	# 8-11
-+	sha1nexte	@MSG[3],$E_
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha1msg2	@MSG[3],@MSG[0]
-+	pxor		@MSG[3],@MSG[1]
-+	sha1msg1	@MSG[3],@MSG[2]
-+___
-+	($E,$E_)=($E_,$E);
-+	push(@MSG,shift(@MSG));
-+
-+	&$aesenc();
-+}
-+$code.=<<___;
-+	movdqa		$ABCD,$E_
-+	sha1rnds4	\$3,$E,$ABCD		# 64-67
-+	sha1nexte	@MSG[3],$E_
-+	sha1msg2	@MSG[3],@MSG[0]
-+	pxor		@MSG[3],@MSG[1]
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	movdqa		$ABCD,$E
-+	sha1rnds4	\$3,$E_,$ABCD		# 68-71
-+	sha1nexte	@MSG[0],$E
-+	sha1msg2	@MSG[0],@MSG[1]
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	movdqa		$E_SAVE,@MSG[0]
-+	movdqa		$ABCD,$E_
-+	sha1rnds4	\$3,$E,$ABCD		# 72-75
-+	sha1nexte	@MSG[1],$E_
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	movdqa		$ABCD,$E
-+	sha1rnds4	\$3,$E_,$ABCD		# 76-79
-+	sha1nexte	$MSG[0],$E
-+___
-+	while($r<40)	{ &$aesenc(); }		# remaining aesenc's
-+$code.=<<___;
-+	dec		$len
-+
-+	paddd		$ABCD_SAVE,$ABCD
-+	movups		$iv,48($out,$in0)	# write output
-+	lea		64($in0),$in0
-+	jnz		.Loop_shaext
-+
-+	pshufd	\$0b00011011,$ABCD,$ABCD
-+	pshufd	\$0b00011011,$E,$E
-+	movups	$iv,($ivp)			# write IV
-+	movdqu	$ABCD,($ctx)
-+	movd	$E,16($ctx)
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-8-10*16(%rax),%xmm6
-+	movaps	-8-9*16(%rax),%xmm7
-+	movaps	-8-8*16(%rax),%xmm8
-+	movaps	-8-7*16(%rax),%xmm9
-+	movaps	-8-6*16(%rax),%xmm10
-+	movaps	-8-5*16(%rax),%xmm11
-+	movaps	-8-4*16(%rax),%xmm12
-+	movaps	-8-3*16(%rax),%xmm13
-+	movaps	-8-2*16(%rax),%xmm14
-+	movaps	-8-1*16(%rax),%xmm15
-+	mov	%rax,%rsp
-+.Lepilogue_shaext:
-+___
-+$code.=<<___;
-+	ret
-+.size	aesni_cbc_sha1_enc_shaext,.-aesni_cbc_sha1_enc_shaext
-+___
-+						}}}
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	ssse3_handler,\@abi-omnipotent
-+.align	16
-+ssse3_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+___
-+$code.=<<___ if ($shaext);
-+	lea	aesni_cbc_sha1_enc_shaext(%rip),%r10
-+	cmp	%r10,%rbx
-+	jb	.Lseh_no_shaext
-+
-+	lea	(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+	lea	168(%rax),%rax		# adjust stack pointer
-+	jmp	.Lcommon_seh_tail
-+.Lseh_no_shaext:
-+___
-+$code.=<<___;
-+	lea	96(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+	lea	`104+10*16`(%rax),%rax	# adjust stack pointer
-+
-+	mov	0(%rax),%r15
-+	mov	8(%rax),%r14
-+	mov	16(%rax),%r13
-+	mov	24(%rax),%r12
-+	mov	32(%rax),%rbp
-+	mov	40(%rax),%rbx
-+	lea	48(%rax),%rax
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lcommon_seh_tail:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	ssse3_handler,.-ssse3_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_aesni_cbc_sha1_enc_ssse3
-+	.rva	.LSEH_end_aesni_cbc_sha1_enc_ssse3
-+	.rva	.LSEH_info_aesni_cbc_sha1_enc_ssse3
-+___
-+$code.=<<___ if ($avx);
-+	.rva	.LSEH_begin_aesni_cbc_sha1_enc_avx
-+	.rva	.LSEH_end_aesni_cbc_sha1_enc_avx
-+	.rva	.LSEH_info_aesni_cbc_sha1_enc_avx
-+___
-+$code.=<<___ if ($shaext);
-+	.rva	.LSEH_begin_aesni_cbc_sha1_enc_shaext
-+	.rva	.LSEH_end_aesni_cbc_sha1_enc_shaext
-+	.rva	.LSEH_info_aesni_cbc_sha1_enc_shaext
-+___
-+$code.=<<___;
-+.section	.xdata
-+.align	8
-+.LSEH_info_aesni_cbc_sha1_enc_ssse3:
-+	.byte	9,0,0,0
-+	.rva	ssse3_handler
-+	.rva	.Lprologue_ssse3,.Lepilogue_ssse3	# HandlerData[]
-+___
-+$code.=<<___ if ($avx);
-+.LSEH_info_aesni_cbc_sha1_enc_avx:
-+	.byte	9,0,0,0
-+	.rva	ssse3_handler
-+	.rva	.Lprologue_avx,.Lepilogue_avx		# HandlerData[]
-+___
-+$code.=<<___ if ($shaext);
-+.LSEH_info_aesni_cbc_sha1_enc_shaext:
-+	.byte	9,0,0,0
-+	.rva	ssse3_handler
-+	.rva	.Lprologue_shaext,.Lepilogue_shaext	# HandlerData[]
-+___
-+}
-+
-+####################################################################
-+sub rex {
-+  local *opcode=shift;
-+  my ($dst,$src)=@_;
-+  my $rex=0;
-+
-+    $rex|=0x04			if($dst>=8);
-+    $rex|=0x01			if($src>=8);
-+    unshift @opcode,$rex|0x40	if($rex);
-+}
-+
-+sub sha1rnds4 {
-+    if (@_[0] =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x0f,0x3a,0xcc);
-+	rex(\@opcode,$3,$2);
-+	push @opcode,0xc0|($2&7)|(($3&7)<<3);		# ModR/M
-+	my $c=$1;
-+	push @opcode,$c=~/^0/?oct($c):$c;
-+	return ".byte\t".join(',',@opcode);
-+    } else {
-+	return "sha1rnds4\t".@_[0];
-+    }
-+}
-+
-+sub sha1op38 {
-+    my $instr = shift;
-+    my %opcodelet = (
-+		"sha1nexte" => 0xc8,
-+  		"sha1msg1"  => 0xc9,
-+		"sha1msg2"  => 0xca	);
-+
-+    if (defined($opcodelet{$instr}) && @_[0] =~ /%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x0f,0x38);
-+	rex(\@opcode,$2,$1);
-+	push @opcode,$opcodelet{$instr};
-+	push @opcode,0xc0|($1&7)|(($2&7)<<3);		# ModR/M
-+	return ".byte\t".join(',',@opcode);
-+    } else {
-+	return $instr."\t".@_[0];
-+    }
-+}
-+
-+sub aesni {
-+  my $line=shift;
-+  my @opcode=(0x0f,0x38);
-+
-+    if ($line=~/(aes[a-z]+)\s+%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+	my %opcodelet = (
-+		"aesenc" => 0xdc,	"aesenclast" => 0xdd,
-+		"aesdec" => 0xde,	"aesdeclast" => 0xdf
-+	);
-+	return undef if (!defined($opcodelet{$1}));
-+	rex(\@opcode,$3,$2);
-+	push @opcode,$opcodelet{$1},0xc0|($2&7)|(($3&7)<<3);	# ModR/M
-+	unshift @opcode,0x66;
-+	return ".byte\t".join(',',@opcode);
-+    }
-+    return $line;
-+}
-+
-+foreach (split("\n",$code)) {
-+        s/\`([^\`]*)\`/eval $1/geo;
-+
-+	s/\b(sha1rnds4)\s+(.*)/sha1rnds4($2)/geo		or
-+	s/\b(sha1[^\s]*)\s+(.*)/sha1op38($1,$2)/geo		or
-+	s/\b(aes.*%xmm[0-9]+).*$/aesni($1)/geo;
-+
-+	print $_,"\n";
-+}
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl
-new file mode 100644
-index 0000000..a5fde2e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl
-@@ -0,0 +1,1713 @@
-+#! /usr/bin/env perl
-+# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# January 2013
-+#
-+# This is AESNI-CBC+SHA256 stitch implementation. The idea, as spelled
-+# in http://download.intel.com/design/intarch/papers/323686.pdf, is
-+# that since AESNI-CBC encrypt exhibit *very* low instruction-level
-+# parallelism, interleaving it with another algorithm would allow to
-+# utilize processor resources better and achieve better performance.
-+# SHA256 instruction sequences(*) are taken from sha512-x86_64.pl and
-+# AESNI code is weaved into it. As SHA256 dominates execution time,
-+# stitch performance does not depend on AES key length. Below are
-+# performance numbers in cycles per processed byte, less is better,
-+# for standalone AESNI-CBC encrypt, standalone SHA256, and stitched
-+# subroutine:
-+#
-+#		 AES-128/-192/-256+SHA256	this(**)gain
-+# Sandy Bridge	    5.05/6.05/7.05+11.6		13.0	+28%/36%/43%
-+# Ivy Bridge	    5.05/6.05/7.05+10.3		11.6	+32%/41%/50%
-+# Haswell	    4.43/5.29/6.19+7.80		8.79	+39%/49%/59%
-+# Skylake	    2.62/3.14/3.62+7.70		8.10	+27%/34%/40%
-+# Bulldozer	    5.77/6.89/8.00+13.7		13.7	+42%/50%/58%
-+#
-+# (*)	there are XOP, AVX1 and AVX2 code paths, meaning that
-+#	Westmere is omitted from loop, this is because gain was not
-+#	estimated high enough to justify the effort;
-+# (**)	these are EVP-free results, results obtained with 'speed
-+#	-evp aes-256-cbc-hmac-sha256' will vary by percent or two;
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	   `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=12);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+$shaext=$avx;	### set to zero if compiling for 1.0.1
-+$avx=1		if (!$shaext && $avx);
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+$func="aesni_cbc_sha256_enc";
-+$TABLE="K256";
-+$SZ=4;
-+@ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%eax","%ebx","%ecx","%edx",
-+				"%r8d","%r9d","%r10d","%r11d");
-+($T1,$a0,$a1,$a2,$a3)=("%r12d","%r13d","%r14d","%r15d","%esi");
-+@Sigma0=( 2,13,22);
-+@Sigma1=( 6,11,25);
-+@sigma0=( 7,18, 3);
-+@sigma1=(17,19,10);
-+$rounds=64;
-+
-+########################################################################
-+# void aesni_cbc_sha256_enc(const void *inp,
-+#			void *out,
-+#			size_t length,
-+#			const AES_KEY *key,
-+#			unsigned char *iv,
-+#			SHA256_CTX *ctx,
-+#			const void *in0);
-+($inp,  $out,  $len,  $key,  $ivp, $ctx, $in0) =
-+("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
-+
-+$Tbl="%rbp";
-+
-+$_inp="16*$SZ+0*8(%rsp)";
-+$_out="16*$SZ+1*8(%rsp)";
-+$_end="16*$SZ+2*8(%rsp)";
-+$_key="16*$SZ+3*8(%rsp)";
-+$_ivp="16*$SZ+4*8(%rsp)";
-+$_ctx="16*$SZ+5*8(%rsp)";
-+$_in0="16*$SZ+6*8(%rsp)";
-+$_rsp="16*$SZ+7*8(%rsp)";
-+$framesz=16*$SZ+8*8;
-+
-+$code=<<___;
-+.text
-+
-+.extern	OPENSSL_ia32cap_P
-+.globl	$func
-+.type	$func,\@abi-omnipotent
-+.align	16
-+$func:
-+___
-+						if ($avx) {
-+$code.=<<___;
-+	lea	OPENSSL_ia32cap_P(%rip),%r11
-+	mov	\$1,%eax
-+	cmp	\$0,`$win64?"%rcx":"%rdi"`
-+	je	.Lprobe
-+	mov	0(%r11),%eax
-+	mov	4(%r11),%r10
-+___
-+$code.=<<___ if ($shaext);
-+	bt	\$61,%r10			# check for SHA
-+	jc	${func}_shaext
-+___
-+$code.=<<___;
-+	mov	%r10,%r11
-+	shr	\$32,%r11
-+
-+	test	\$`1<<11`,%r10d			# check for XOP
-+	jnz	${func}_xop
-+___
-+$code.=<<___ if ($avx>1);
-+	and	\$`1<<8|1<<5|1<<3`,%r11d	# check for BMI2+AVX2+BMI1
-+	cmp	\$`1<<8|1<<5|1<<3`,%r11d
-+	je	${func}_avx2
-+___
-+$code.=<<___;
-+	and	\$`1<<28`,%r10d			# check for AVX
-+	jnz	${func}_avx
-+	ud2
-+___
-+						}
-+$code.=<<___;
-+	xor	%eax,%eax
-+	cmp	\$0,`$win64?"%rcx":"%rdi"`
-+	je	.Lprobe
-+	ud2
-+.Lprobe:
-+	ret
-+.size	$func,.-$func
-+
-+.align	64
-+.type	$TABLE,\@object
-+$TABLE:
-+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+
-+	.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
-+	.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
-+	.long	0,0,0,0,   0,0,0,0,   -1,-1,-1,-1
-+	.long	0,0,0,0,   0,0,0,0
-+	.asciz	"AESNI-CBC+SHA256 stitch for x86_64, CRYPTOGAMS by "
-+.align	64
-+___
-+
-+######################################################################
-+# SIMD code paths
-+#
-+{{{
-+($iv,$inout,$roundkey,$temp,
-+ $mask10,$mask12,$mask14,$offload)=map("%xmm$_",(8..15));
-+
-+$aesni_cbc_idx=0;
-+@aesni_cbc_block = (
-+##	&vmovdqu	($roundkey,"0x00-0x80($inp)");'
-+##	&vmovdqu	($inout,($inp));
-+##	&mov		($_inp,$inp);
-+
-+	'&vpxor		($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0x10-0x80($inp)");',
-+
-+	'&vpxor		($inout,$inout,$iv);',
-+
-+	'&vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0x20-0x80($inp)");',
-+
-+	'&vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0x30-0x80($inp)");',
-+
-+	'&vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0x40-0x80($inp)");',
-+
-+	'&vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0x50-0x80($inp)");',
-+
-+	'&vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0x60-0x80($inp)");',
-+
-+	'&vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0x70-0x80($inp)");',
-+
-+	'&vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0x80-0x80($inp)");',
-+
-+	'&vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0x90-0x80($inp)");',
-+
-+	'&vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0xa0-0x80($inp)");',
-+
-+	'&vaesenclast	($temp,$inout,$roundkey);'.
-+	' &vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0xb0-0x80($inp)");',
-+
-+	'&vpand		($iv,$temp,$mask10);'.
-+	' &vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0xc0-0x80($inp)");',
-+
-+	'&vaesenclast	($temp,$inout,$roundkey);'.
-+	' &vaesenc	($inout,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0xd0-0x80($inp)");',
-+
-+	'&vpand		($temp,$temp,$mask12);'.
-+	' &vaesenc	($inout,$inout,$roundkey);'.
-+	 '&vmovdqu	($roundkey,"0xe0-0x80($inp)");',
-+
-+	'&vpor		($iv,$iv,$temp);'.
-+	' &vaesenclast	($temp,$inout,$roundkey);'.
-+	' &vmovdqu	($roundkey,"0x00-0x80($inp)");'
-+
-+##	&mov		($inp,$_inp);
-+##	&mov		($out,$_out);
-+##	&vpand		($temp,$temp,$mask14);
-+##	&vpor		($iv,$iv,$temp);
-+##	&vmovdqu	($iv,($out,$inp);
-+##	&lea		(inp,16($inp));
-+);
-+
-+my $a4=$T1;
-+my ($a,$b,$c,$d,$e,$f,$g,$h);
-+
-+sub AUTOLOAD()		# thunk [simplified] 32-bit style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
-+  my $arg = pop;
-+    $arg = "\$$arg" if ($arg*1 eq $arg);
-+    $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
-+}
-+
-+sub body_00_15 () {
-+	(
-+	'($a,$b,$c,$d,$e,$f,$g,$h)=@ROT;'.
-+
-+	'&ror	($a0,$Sigma1[2]-$Sigma1[1])',
-+	'&mov	($a,$a1)',
-+	'&mov	($a4,$f)',
-+
-+	'&xor	($a0,$e)',
-+	'&ror	($a1,$Sigma0[2]-$Sigma0[1])',
-+	'&xor	($a4,$g)',			# f^g
-+
-+	'&ror	($a0,$Sigma1[1]-$Sigma1[0])',
-+	'&xor	($a1,$a)',
-+	'&and	($a4,$e)',			# (f^g)&e
-+
-+	@aesni_cbc_block[$aesni_cbc_idx++].
-+	'&xor	($a0,$e)',
-+	'&add	($h,$SZ*($i&15)."(%rsp)")',	# h+=X[i]+K[i]
-+	'&mov	($a2,$a)',
-+
-+	'&ror	($a1,$Sigma0[1]-$Sigma0[0])',
-+	'&xor	($a4,$g)',			# Ch(e,f,g)=((f^g)&e)^g
-+	'&xor	($a2,$b)',			# a^b, b^c in next round
-+
-+	'&ror	($a0,$Sigma1[0])',		# Sigma1(e)
-+	'&add	($h,$a4)',			# h+=Ch(e,f,g)
-+	'&and	($a3,$a2)',			# (b^c)&(a^b)
-+
-+	'&xor	($a1,$a)',
-+	'&add	($h,$a0)',			# h+=Sigma1(e)
-+	'&xor	($a3,$b)',			# Maj(a,b,c)=Ch(a^b,c,b)
-+
-+	'&add	($d,$h)',			# d+=h
-+	'&ror	($a1,$Sigma0[0])',		# Sigma0(a)
-+	'&add	($h,$a3)',			# h+=Maj(a,b,c)
-+
-+	'&mov	($a0,$d)',
-+	'&add	($a1,$h);'.			# h+=Sigma0(a)
-+	'($a2,$a3) = ($a3,$a2); unshift(@ROT,pop(@ROT)); $i++;'
-+	);
-+}
-+
-+if ($avx) {{
-+######################################################################
-+# XOP code path
-+#
-+$code.=<<___;
-+.type	${func}_xop,\@function,6
-+.align	64
-+${func}_xop:
-+.Lxop_shortcut:
-+	mov	`($win64?56:8)`(%rsp),$in0	# load 7th parameter
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	mov	%rsp,%r11		# copy %rsp
-+	sub	\$`$framesz+$win64*16*10`,%rsp
-+	and	\$-64,%rsp		# align stack frame
-+
-+	shl	\$6,$len
-+	sub	$inp,$out		# re-bias
-+	sub	$inp,$in0
-+	add	$inp,$len		# end of input
-+
-+	#mov	$inp,$_inp		# saved later
-+	mov	$out,$_out
-+	mov	$len,$_end
-+	#mov	$key,$_key		# remains resident in $inp register
-+	mov	$ivp,$_ivp
-+	mov	$ctx,$_ctx
-+	mov	$in0,$_in0
-+	mov	%r11,$_rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,`$framesz+16*0`(%rsp)
-+	movaps	%xmm7,`$framesz+16*1`(%rsp)
-+	movaps	%xmm8,`$framesz+16*2`(%rsp)
-+	movaps	%xmm9,`$framesz+16*3`(%rsp)
-+	movaps	%xmm10,`$framesz+16*4`(%rsp)
-+	movaps	%xmm11,`$framesz+16*5`(%rsp)
-+	movaps	%xmm12,`$framesz+16*6`(%rsp)
-+	movaps	%xmm13,`$framesz+16*7`(%rsp)
-+	movaps	%xmm14,`$framesz+16*8`(%rsp)
-+	movaps	%xmm15,`$framesz+16*9`(%rsp)
-+___
-+$code.=<<___;
-+.Lprologue_xop:
-+	vzeroall
-+
-+	mov	$inp,%r12		# borrow $a4
-+	lea	0x80($key),$inp		# size optimization, reassign
-+	lea	$TABLE+`$SZ*2*$rounds+32`(%rip),%r13	# borrow $a0
-+	mov	0xf0-0x80($inp),%r14d	# rounds, borrow $a1
-+	mov	$ctx,%r15		# borrow $a2
-+	mov	$in0,%rsi		# borrow $a3
-+	vmovdqu	($ivp),$iv		# load IV
-+	sub	\$9,%r14
-+
-+	mov	$SZ*0(%r15),$A
-+	mov	$SZ*1(%r15),$B
-+	mov	$SZ*2(%r15),$C
-+	mov	$SZ*3(%r15),$D
-+	mov	$SZ*4(%r15),$E
-+	mov	$SZ*5(%r15),$F
-+	mov	$SZ*6(%r15),$G
-+	mov	$SZ*7(%r15),$H
-+
-+	vmovdqa	0x00(%r13,%r14,8),$mask14
-+	vmovdqa	0x10(%r13,%r14,8),$mask12
-+	vmovdqa	0x20(%r13,%r14,8),$mask10
-+	vmovdqu	0x00-0x80($inp),$roundkey
-+	jmp	.Lloop_xop
-+___
-+					if ($SZ==4) {	# SHA256
-+    my @X = map("%xmm$_",(0..3));
-+    my ($t0,$t1,$t2,$t3) = map("%xmm$_",(4..7));
-+
-+$code.=<<___;
-+.align	16
-+.Lloop_xop:
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`(%rip),$t3
-+	vmovdqu	0x00(%rsi,%r12),@X[0]
-+	vmovdqu	0x10(%rsi,%r12),@X[1]
-+	vmovdqu	0x20(%rsi,%r12),@X[2]
-+	vmovdqu	0x30(%rsi,%r12),@X[3]
-+	vpshufb	$t3,@X[0],@X[0]
-+	lea	$TABLE(%rip),$Tbl
-+	vpshufb	$t3,@X[1],@X[1]
-+	vpshufb	$t3,@X[2],@X[2]
-+	vpaddd	0x00($Tbl),@X[0],$t0
-+	vpshufb	$t3,@X[3],@X[3]
-+	vpaddd	0x20($Tbl),@X[1],$t1
-+	vpaddd	0x40($Tbl),@X[2],$t2
-+	vpaddd	0x60($Tbl),@X[3],$t3
-+	vmovdqa	$t0,0x00(%rsp)
-+	mov	$A,$a1
-+	vmovdqa	$t1,0x10(%rsp)
-+	mov	$B,$a3
-+	vmovdqa	$t2,0x20(%rsp)
-+	xor	$C,$a3			# magic
-+	vmovdqa	$t3,0x30(%rsp)
-+	mov	$E,$a0
-+	jmp	.Lxop_00_47
-+
-+.align	16
-+.Lxop_00_47:
-+	sub	\$-16*2*$SZ,$Tbl	# size optimization
-+	vmovdqu	(%r12),$inout		# $a4
-+	mov	%r12,$_inp		# $a4
-+___
-+sub XOP_256_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body,&$body,&$body);	# 104 instructions
-+
-+	&vpalignr	($t0,@X[1],@X[0],$SZ);	# X[1..4]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpalignr	($t3,@X[3],@X[2],$SZ);	# X[9..12]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vprotd		($t1,$t0,8*$SZ-$sigma0[1]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpsrld		($t0,$t0,$sigma0[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpaddd	(@X[0],@X[0],$t3);	# X[0..3] += X[9..12]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vprotd		($t2,$t1,$sigma0[1]-$sigma0[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpxor		($t0,$t0,$t1);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vprotd	($t3,@X[3],8*$SZ-$sigma1[1]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpxor		($t0,$t0,$t2);		# sigma0(X[1..4])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpsrld	($t2,@X[3],$sigma1[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddd		(@X[0],@X[0],$t0);	# X[0..3] += sigma0(X[1..4])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vprotd	($t1,$t3,$sigma1[1]-$sigma1[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpxor		($t3,$t3,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpxor		($t3,$t3,$t1);		# sigma1(X[14..15])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpsrldq	($t3,$t3,8);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddd		(@X[0],@X[0],$t3);	# X[0..1] += sigma1(X[14..15])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vprotd	($t3,@X[0],8*$SZ-$sigma1[1]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpsrld	($t2,@X[0],$sigma1[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vprotd	($t1,$t3,$sigma1[1]-$sigma1[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpxor		($t3,$t3,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpxor		($t3,$t3,$t1);		# sigma1(X[16..17])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpslldq	($t3,$t3,8);		# 22 instructions
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddd		(@X[0],@X[0],$t3);	# X[2..3] += sigma1(X[16..17])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddd		($t2,@X[0],16*2*$j."($Tbl)");
-+	  foreach (@insns) { eval; }		# remaining instructions
-+	&vmovdqa	(16*$j."(%rsp)",$t2);
-+}
-+
-+    $aesni_cbc_idx=0;
-+    for ($i=0,$j=0; $j<4; $j++) {
-+	&XOP_256_00_47($j,\&body_00_15,@X);
-+	push(@X,shift(@X));			# rotate(@X)
-+    }
-+    	&mov		("%r12",$_inp);		# borrow $a4
-+	&vpand		($temp,$temp,$mask14);
-+	&mov		("%r15",$_out);		# borrow $a2
-+	&vpor		($iv,$iv,$temp);
-+	&vmovdqu	("(%r15,%r12)",$iv);	# write output
-+	&lea		("%r12","16(%r12)");	# inp++
-+
-+	&cmpb	($SZ-1+16*2*$SZ."($Tbl)",0);
-+	&jne	(".Lxop_00_47");
-+
-+	&vmovdqu	($inout,"(%r12)");
-+	&mov		($_inp,"%r12");
-+
-+    $aesni_cbc_idx=0;
-+    for ($i=0; $i<16; ) {
-+	foreach(body_00_15()) { eval; }
-+    }
-+					}
-+$code.=<<___;
-+	mov	$_inp,%r12		# borrow $a4
-+	mov	$_out,%r13		# borrow $a0
-+	mov	$_ctx,%r15		# borrow $a2
-+	mov	$_in0,%rsi		# borrow $a3
-+
-+	vpand	$mask14,$temp,$temp
-+	mov	$a1,$A
-+	vpor	$temp,$iv,$iv
-+	vmovdqu	$iv,(%r13,%r12)		# write output
-+	lea	16(%r12),%r12		# inp++
-+
-+	add	$SZ*0(%r15),$A
-+	add	$SZ*1(%r15),$B
-+	add	$SZ*2(%r15),$C
-+	add	$SZ*3(%r15),$D
-+	add	$SZ*4(%r15),$E
-+	add	$SZ*5(%r15),$F
-+	add	$SZ*6(%r15),$G
-+	add	$SZ*7(%r15),$H
-+
-+	cmp	$_end,%r12
-+
-+	mov	$A,$SZ*0(%r15)
-+	mov	$B,$SZ*1(%r15)
-+	mov	$C,$SZ*2(%r15)
-+	mov	$D,$SZ*3(%r15)
-+	mov	$E,$SZ*4(%r15)
-+	mov	$F,$SZ*5(%r15)
-+	mov	$G,$SZ*6(%r15)
-+	mov	$H,$SZ*7(%r15)
-+
-+	jb	.Lloop_xop
-+
-+	mov	$_ivp,$ivp
-+	mov	$_rsp,%rsi
-+	vmovdqu	$iv,($ivp)		# output IV
-+	vzeroall
-+___
-+$code.=<<___ if ($win64);
-+	movaps	`$framesz+16*0`(%rsp),%xmm6
-+	movaps	`$framesz+16*1`(%rsp),%xmm7
-+	movaps	`$framesz+16*2`(%rsp),%xmm8
-+	movaps	`$framesz+16*3`(%rsp),%xmm9
-+	movaps	`$framesz+16*4`(%rsp),%xmm10
-+	movaps	`$framesz+16*5`(%rsp),%xmm11
-+	movaps	`$framesz+16*6`(%rsp),%xmm12
-+	movaps	`$framesz+16*7`(%rsp),%xmm13
-+	movaps	`$framesz+16*8`(%rsp),%xmm14
-+	movaps	`$framesz+16*9`(%rsp),%xmm15
-+___
-+$code.=<<___;
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_xop:
-+	ret
-+.size	${func}_xop,.-${func}_xop
-+___
-+######################################################################
-+# AVX+shrd code path
-+#
-+local *ror = sub { &shrd(@_[0],@_) };
-+
-+$code.=<<___;
-+.type	${func}_avx,\@function,6
-+.align	64
-+${func}_avx:
-+.Lavx_shortcut:
-+	mov	`($win64?56:8)`(%rsp),$in0	# load 7th parameter
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	mov	%rsp,%r11		# copy %rsp
-+	sub	\$`$framesz+$win64*16*10`,%rsp
-+	and	\$-64,%rsp		# align stack frame
-+
-+	shl	\$6,$len
-+	sub	$inp,$out		# re-bias
-+	sub	$inp,$in0
-+	add	$inp,$len		# end of input
-+
-+	#mov	$inp,$_inp		# saved later
-+	mov	$out,$_out
-+	mov	$len,$_end
-+	#mov	$key,$_key		# remains resident in $inp register
-+	mov	$ivp,$_ivp
-+	mov	$ctx,$_ctx
-+	mov	$in0,$_in0
-+	mov	%r11,$_rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,`$framesz+16*0`(%rsp)
-+	movaps	%xmm7,`$framesz+16*1`(%rsp)
-+	movaps	%xmm8,`$framesz+16*2`(%rsp)
-+	movaps	%xmm9,`$framesz+16*3`(%rsp)
-+	movaps	%xmm10,`$framesz+16*4`(%rsp)
-+	movaps	%xmm11,`$framesz+16*5`(%rsp)
-+	movaps	%xmm12,`$framesz+16*6`(%rsp)
-+	movaps	%xmm13,`$framesz+16*7`(%rsp)
-+	movaps	%xmm14,`$framesz+16*8`(%rsp)
-+	movaps	%xmm15,`$framesz+16*9`(%rsp)
-+___
-+$code.=<<___;
-+.Lprologue_avx:
-+	vzeroall
-+
-+	mov	$inp,%r12		# borrow $a4
-+	lea	0x80($key),$inp		# size optimization, reassign
-+	lea	$TABLE+`$SZ*2*$rounds+32`(%rip),%r13	# borrow $a0
-+	mov	0xf0-0x80($inp),%r14d	# rounds, borrow $a1
-+	mov	$ctx,%r15		# borrow $a2
-+	mov	$in0,%rsi		# borrow $a3
-+	vmovdqu	($ivp),$iv		# load IV
-+	sub	\$9,%r14
-+
-+	mov	$SZ*0(%r15),$A
-+	mov	$SZ*1(%r15),$B
-+	mov	$SZ*2(%r15),$C
-+	mov	$SZ*3(%r15),$D
-+	mov	$SZ*4(%r15),$E
-+	mov	$SZ*5(%r15),$F
-+	mov	$SZ*6(%r15),$G
-+	mov	$SZ*7(%r15),$H
-+
-+	vmovdqa	0x00(%r13,%r14,8),$mask14
-+	vmovdqa	0x10(%r13,%r14,8),$mask12
-+	vmovdqa	0x20(%r13,%r14,8),$mask10
-+	vmovdqu	0x00-0x80($inp),$roundkey
-+___
-+					if ($SZ==4) {	# SHA256
-+    my @X = map("%xmm$_",(0..3));
-+    my ($t0,$t1,$t2,$t3) = map("%xmm$_",(4..7));
-+
-+$code.=<<___;
-+	jmp	.Lloop_avx
-+.align	16
-+.Lloop_avx:
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`(%rip),$t3
-+	vmovdqu	0x00(%rsi,%r12),@X[0]
-+	vmovdqu	0x10(%rsi,%r12),@X[1]
-+	vmovdqu	0x20(%rsi,%r12),@X[2]
-+	vmovdqu	0x30(%rsi,%r12),@X[3]
-+	vpshufb	$t3,@X[0],@X[0]
-+	lea	$TABLE(%rip),$Tbl
-+	vpshufb	$t3,@X[1],@X[1]
-+	vpshufb	$t3,@X[2],@X[2]
-+	vpaddd	0x00($Tbl),@X[0],$t0
-+	vpshufb	$t3,@X[3],@X[3]
-+	vpaddd	0x20($Tbl),@X[1],$t1
-+	vpaddd	0x40($Tbl),@X[2],$t2
-+	vpaddd	0x60($Tbl),@X[3],$t3
-+	vmovdqa	$t0,0x00(%rsp)
-+	mov	$A,$a1
-+	vmovdqa	$t1,0x10(%rsp)
-+	mov	$B,$a3
-+	vmovdqa	$t2,0x20(%rsp)
-+	xor	$C,$a3			# magic
-+	vmovdqa	$t3,0x30(%rsp)
-+	mov	$E,$a0
-+	jmp	.Lavx_00_47
-+
-+.align	16
-+.Lavx_00_47:
-+	sub	\$-16*2*$SZ,$Tbl	# size optimization
-+	vmovdqu	(%r12),$inout		# $a4
-+	mov	%r12,$_inp		# $a4
-+___
-+sub Xupdate_256_AVX () {
-+	(
-+	'&vpalignr	($t0,@X[1],@X[0],$SZ)',	# X[1..4]
-+	 '&vpalignr	($t3,@X[3],@X[2],$SZ)',	# X[9..12]
-+	'&vpsrld	($t2,$t0,$sigma0[0]);',
-+	 '&vpaddd	(@X[0],@X[0],$t3)',	# X[0..3] += X[9..12]
-+	'&vpsrld	($t3,$t0,$sigma0[2])',
-+	'&vpslld	($t1,$t0,8*$SZ-$sigma0[1]);',
-+	'&vpxor		($t0,$t3,$t2)',
-+	 '&vpshufd	($t3,@X[3],0b11111010)',# X[14..15]
-+	'&vpsrld	($t2,$t2,$sigma0[1]-$sigma0[0]);',
-+	'&vpxor		($t0,$t0,$t1)',
-+	'&vpslld	($t1,$t1,$sigma0[1]-$sigma0[0]);',
-+	'&vpxor		($t0,$t0,$t2)',
-+	 '&vpsrld	($t2,$t3,$sigma1[2]);',
-+	'&vpxor		($t0,$t0,$t1)',		# sigma0(X[1..4])
-+	 '&vpsrlq	($t3,$t3,$sigma1[0]);',
-+	'&vpaddd	(@X[0],@X[0],$t0)',	# X[0..3] += sigma0(X[1..4])
-+	 '&vpxor	($t2,$t2,$t3);',
-+	 '&vpsrlq	($t3,$t3,$sigma1[1]-$sigma1[0])',
-+	 '&vpxor	($t2,$t2,$t3)',		# sigma1(X[14..15])
-+	 '&vpshufd	($t2,$t2,0b10000100)',
-+	 '&vpsrldq	($t2,$t2,8)',
-+	'&vpaddd	(@X[0],@X[0],$t2)',	# X[0..1] += sigma1(X[14..15])
-+	 '&vpshufd	($t3,@X[0],0b01010000)',# X[16..17]
-+	 '&vpsrld	($t2,$t3,$sigma1[2])',
-+	 '&vpsrlq	($t3,$t3,$sigma1[0])',
-+	 '&vpxor	($t2,$t2,$t3);',
-+	 '&vpsrlq	($t3,$t3,$sigma1[1]-$sigma1[0])',
-+	 '&vpxor	($t2,$t2,$t3)',
-+	 '&vpshufd	($t2,$t2,0b11101000)',
-+	 '&vpslldq	($t2,$t2,8)',
-+	'&vpaddd	(@X[0],@X[0],$t2)'	# X[2..3] += sigma1(X[16..17])
-+	);
-+}
-+
-+sub AVX_256_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body,&$body,&$body);	# 104 instructions
-+
-+	foreach (Xupdate_256_AVX()) {		# 29 instructions
-+	    eval;
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	}
-+	&vpaddd		($t2,@X[0],16*2*$j."($Tbl)");
-+	  foreach (@insns) { eval; }		# remaining instructions
-+	&vmovdqa	(16*$j."(%rsp)",$t2);
-+}
-+
-+    $aesni_cbc_idx=0;
-+    for ($i=0,$j=0; $j<4; $j++) {
-+	&AVX_256_00_47($j,\&body_00_15,@X);
-+	push(@X,shift(@X));			# rotate(@X)
-+    }
-+    	&mov		("%r12",$_inp);		# borrow $a4
-+	&vpand		($temp,$temp,$mask14);
-+	&mov		("%r15",$_out);		# borrow $a2
-+	&vpor		($iv,$iv,$temp);
-+	&vmovdqu	("(%r15,%r12)",$iv);	# write output
-+	&lea		("%r12","16(%r12)");	# inp++
-+
-+	&cmpb	($SZ-1+16*2*$SZ."($Tbl)",0);
-+	&jne	(".Lavx_00_47");
-+
-+	&vmovdqu	($inout,"(%r12)");
-+	&mov		($_inp,"%r12");
-+
-+    $aesni_cbc_idx=0;
-+    for ($i=0; $i<16; ) {
-+	foreach(body_00_15()) { eval; }
-+    }
-+
-+					}
-+$code.=<<___;
-+	mov	$_inp,%r12		# borrow $a4
-+	mov	$_out,%r13		# borrow $a0
-+	mov	$_ctx,%r15		# borrow $a2
-+	mov	$_in0,%rsi		# borrow $a3
-+
-+	vpand	$mask14,$temp,$temp
-+	mov	$a1,$A
-+	vpor	$temp,$iv,$iv
-+	vmovdqu	$iv,(%r13,%r12)		# write output
-+	lea	16(%r12),%r12		# inp++
-+
-+	add	$SZ*0(%r15),$A
-+	add	$SZ*1(%r15),$B
-+	add	$SZ*2(%r15),$C
-+	add	$SZ*3(%r15),$D
-+	add	$SZ*4(%r15),$E
-+	add	$SZ*5(%r15),$F
-+	add	$SZ*6(%r15),$G
-+	add	$SZ*7(%r15),$H
-+
-+	cmp	$_end,%r12
-+
-+	mov	$A,$SZ*0(%r15)
-+	mov	$B,$SZ*1(%r15)
-+	mov	$C,$SZ*2(%r15)
-+	mov	$D,$SZ*3(%r15)
-+	mov	$E,$SZ*4(%r15)
-+	mov	$F,$SZ*5(%r15)
-+	mov	$G,$SZ*6(%r15)
-+	mov	$H,$SZ*7(%r15)
-+	jb	.Lloop_avx
-+
-+	mov	$_ivp,$ivp
-+	mov	$_rsp,%rsi
-+	vmovdqu	$iv,($ivp)		# output IV
-+	vzeroall
-+___
-+$code.=<<___ if ($win64);
-+	movaps	`$framesz+16*0`(%rsp),%xmm6
-+	movaps	`$framesz+16*1`(%rsp),%xmm7
-+	movaps	`$framesz+16*2`(%rsp),%xmm8
-+	movaps	`$framesz+16*3`(%rsp),%xmm9
-+	movaps	`$framesz+16*4`(%rsp),%xmm10
-+	movaps	`$framesz+16*5`(%rsp),%xmm11
-+	movaps	`$framesz+16*6`(%rsp),%xmm12
-+	movaps	`$framesz+16*7`(%rsp),%xmm13
-+	movaps	`$framesz+16*8`(%rsp),%xmm14
-+	movaps	`$framesz+16*9`(%rsp),%xmm15
-+___
-+$code.=<<___;
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_avx:
-+	ret
-+.size	${func}_avx,.-${func}_avx
-+___
-+
-+if ($avx>1) {{
-+######################################################################
-+# AVX2+BMI code path
-+#
-+my $a5=$SZ==4?"%esi":"%rsi";	# zap $inp 
-+my $PUSH8=8*2*$SZ;
-+use integer;
-+
-+sub bodyx_00_15 () {
-+	# at start $a1 should be zero, $a3 - $b^$c and $a4 copy of $f
-+	(
-+	'($a,$b,$c,$d,$e,$f,$g,$h)=@ROT;'.
-+
-+	'&add	($h,(32*($i/(16/$SZ))+$SZ*($i%(16/$SZ)))%$PUSH8.$base)',    # h+=X[i]+K[i]
-+	'&and	($a4,$e)',		# f&e
-+	'&rorx	($a0,$e,$Sigma1[2])',
-+	'&rorx	($a2,$e,$Sigma1[1])',
-+
-+	'&lea	($a,"($a,$a1)")',	# h+=Sigma0(a) from the past
-+	'&lea	($h,"($h,$a4)")',
-+	'&andn	($a4,$e,$g)',		# ~e&g
-+	'&xor	($a0,$a2)',
-+
-+	'&rorx	($a1,$e,$Sigma1[0])',
-+	'&lea	($h,"($h,$a4)")',	# h+=Ch(e,f,g)=(e&f)+(~e&g)
-+	'&xor	($a0,$a1)',		# Sigma1(e)
-+	'&mov	($a2,$a)',
-+
-+	'&rorx	($a4,$a,$Sigma0[2])',
-+	'&lea	($h,"($h,$a0)")',	# h+=Sigma1(e)
-+	'&xor	($a2,$b)',		# a^b, b^c in next round
-+	'&rorx	($a1,$a,$Sigma0[1])',
-+
-+	'&rorx	($a0,$a,$Sigma0[0])',
-+	'&lea	($d,"($d,$h)")',	# d+=h
-+	'&and	($a3,$a2)',		# (b^c)&(a^b)
-+	@aesni_cbc_block[$aesni_cbc_idx++].
-+	'&xor	($a1,$a4)',
-+
-+	'&xor	($a3,$b)',		# Maj(a,b,c)=Ch(a^b,c,b)
-+	'&xor	($a1,$a0)',		# Sigma0(a)
-+	'&lea	($h,"($h,$a3)");'.	# h+=Maj(a,b,c)
-+	'&mov	($a4,$e)',		# copy of f in future
-+
-+	'($a2,$a3) = ($a3,$a2); unshift(@ROT,pop(@ROT)); $i++;'
-+	);
-+	# and at the finish one has to $a+=$a1
-+}
-+
-+$code.=<<___;
-+.type	${func}_avx2,\@function,6
-+.align	64
-+${func}_avx2:
-+.Lavx2_shortcut:
-+	mov	`($win64?56:8)`(%rsp),$in0	# load 7th parameter
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	mov	%rsp,%r11		# copy %rsp
-+	sub	\$`2*$SZ*$rounds+8*8+$win64*16*10`,%rsp
-+	and	\$-256*$SZ,%rsp		# align stack frame
-+	add	\$`2*$SZ*($rounds-8)`,%rsp
-+
-+	shl	\$6,$len
-+	sub	$inp,$out		# re-bias
-+	sub	$inp,$in0
-+	add	$inp,$len		# end of input
-+
-+	#mov	$inp,$_inp		# saved later
-+	#mov	$out,$_out		# kept in $offload
-+	mov	$len,$_end
-+	#mov	$key,$_key		# remains resident in $inp register
-+	mov	$ivp,$_ivp
-+	mov	$ctx,$_ctx
-+	mov	$in0,$_in0
-+	mov	%r11,$_rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,`$framesz+16*0`(%rsp)
-+	movaps	%xmm7,`$framesz+16*1`(%rsp)
-+	movaps	%xmm8,`$framesz+16*2`(%rsp)
-+	movaps	%xmm9,`$framesz+16*3`(%rsp)
-+	movaps	%xmm10,`$framesz+16*4`(%rsp)
-+	movaps	%xmm11,`$framesz+16*5`(%rsp)
-+	movaps	%xmm12,`$framesz+16*6`(%rsp)
-+	movaps	%xmm13,`$framesz+16*7`(%rsp)
-+	movaps	%xmm14,`$framesz+16*8`(%rsp)
-+	movaps	%xmm15,`$framesz+16*9`(%rsp)
-+___
-+$code.=<<___;
-+.Lprologue_avx2:
-+	vzeroall
-+
-+	mov	$inp,%r13		# borrow $a0
-+	vpinsrq	\$1,$out,$offload,$offload
-+	lea	0x80($key),$inp		# size optimization, reassign
-+	lea	$TABLE+`$SZ*2*$rounds+32`(%rip),%r12	# borrow $a4
-+	mov	0xf0-0x80($inp),%r14d	# rounds, borrow $a1
-+	mov	$ctx,%r15		# borrow $a2
-+	mov	$in0,%rsi		# borrow $a3
-+	vmovdqu	($ivp),$iv		# load IV
-+	lea	-9(%r14),%r14
-+
-+	vmovdqa	0x00(%r12,%r14,8),$mask14
-+	vmovdqa	0x10(%r12,%r14,8),$mask12
-+	vmovdqa	0x20(%r12,%r14,8),$mask10
-+
-+	sub	\$-16*$SZ,%r13		# inp++, size optimization
-+	mov	$SZ*0(%r15),$A
-+	lea	(%rsi,%r13),%r12	# borrow $a0
-+	mov	$SZ*1(%r15),$B
-+	cmp	$len,%r13		# $_end
-+	mov	$SZ*2(%r15),$C
-+	cmove	%rsp,%r12		# next block or random data
-+	mov	$SZ*3(%r15),$D
-+	mov	$SZ*4(%r15),$E
-+	mov	$SZ*5(%r15),$F
-+	mov	$SZ*6(%r15),$G
-+	mov	$SZ*7(%r15),$H
-+	vmovdqu	0x00-0x80($inp),$roundkey
-+___
-+					if ($SZ==4) {	# SHA256
-+    my @X = map("%ymm$_",(0..3));
-+    my ($t0,$t1,$t2,$t3) = map("%ymm$_",(4..7));
-+
-+$code.=<<___;
-+	jmp	.Loop_avx2
-+.align	16
-+.Loop_avx2:
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`(%rip),$t3
-+	vmovdqu	-16*$SZ+0(%rsi,%r13),%xmm0
-+	vmovdqu	-16*$SZ+16(%rsi,%r13),%xmm1
-+	vmovdqu	-16*$SZ+32(%rsi,%r13),%xmm2
-+	vmovdqu	-16*$SZ+48(%rsi,%r13),%xmm3
-+
-+	vinserti128	\$1,(%r12),@X[0],@X[0]
-+	vinserti128	\$1,16(%r12),@X[1],@X[1]
-+	 vpshufb	$t3,@X[0],@X[0]
-+	vinserti128	\$1,32(%r12),@X[2],@X[2]
-+	 vpshufb	$t3,@X[1],@X[1]
-+	vinserti128	\$1,48(%r12),@X[3],@X[3]
-+
-+	lea	$TABLE(%rip),$Tbl
-+	vpshufb	$t3,@X[2],@X[2]
-+	lea	-16*$SZ(%r13),%r13
-+	vpaddd	0x00($Tbl),@X[0],$t0
-+	vpshufb	$t3,@X[3],@X[3]
-+	vpaddd	0x20($Tbl),@X[1],$t1
-+	vpaddd	0x40($Tbl),@X[2],$t2
-+	vpaddd	0x60($Tbl),@X[3],$t3
-+	vmovdqa	$t0,0x00(%rsp)
-+	xor	$a1,$a1
-+	vmovdqa	$t1,0x20(%rsp)
-+	lea	-$PUSH8(%rsp),%rsp
-+	mov	$B,$a3
-+	vmovdqa	$t2,0x00(%rsp)
-+	xor	$C,$a3			# magic
-+	vmovdqa	$t3,0x20(%rsp)
-+	mov	$F,$a4
-+	sub	\$-16*2*$SZ,$Tbl	# size optimization
-+	jmp	.Lavx2_00_47
-+
-+.align	16
-+.Lavx2_00_47:
-+	vmovdqu	(%r13),$inout
-+	vpinsrq	\$0,%r13,$offload,$offload
-+___
-+
-+sub AVX2_256_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body,&$body,&$body);	# 96 instructions
-+my $base = "+2*$PUSH8(%rsp)";
-+
-+	&lea	("%rsp","-$PUSH8(%rsp)")	if (($j%2)==0);
-+	foreach (Xupdate_256_AVX()) {		# 29 instructions
-+	    eval;
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	}
-+	&vpaddd		($t2,@X[0],16*2*$j."($Tbl)");
-+	  foreach (@insns) { eval; }		# remaining instructions
-+	&vmovdqa	((32*$j)%$PUSH8."(%rsp)",$t2);
-+}
-+    $aesni_cbc_idx=0;
-+    for ($i=0,$j=0; $j<4; $j++) {
-+	&AVX2_256_00_47($j,\&bodyx_00_15,@X);
-+	push(@X,shift(@X));			# rotate(@X)
-+    }
-+	&vmovq		("%r13",$offload);	# borrow $a0
-+	&vpextrq	("%r15",$offload,1);	# borrow $a2
-+	&vpand		($temp,$temp,$mask14);
-+	&vpor		($iv,$iv,$temp);
-+	&vmovdqu	("(%r15,%r13)",$iv);	# write output
-+	&lea		("%r13","16(%r13)");	# inp++
-+
-+	&lea	($Tbl,16*2*$SZ."($Tbl)");
-+	&cmpb	(($SZ-1)."($Tbl)",0);
-+	&jne	(".Lavx2_00_47");
-+
-+	&vmovdqu	($inout,"(%r13)");
-+	&vpinsrq	($offload,$offload,"%r13",0);
-+
-+    $aesni_cbc_idx=0;
-+    for ($i=0; $i<16; ) {
-+	my $base=$i<8?"+$PUSH8(%rsp)":"(%rsp)";
-+	foreach(bodyx_00_15()) { eval; }
-+    }
-+					}
-+$code.=<<___;
-+	vpextrq	\$1,$offload,%r12		# $_out, borrow $a4
-+	vmovq	$offload,%r13			# $_inp, borrow $a0
-+	mov	`2*$SZ*$rounds+5*8`(%rsp),%r15	# $_ctx, borrow $a2
-+	add	$a1,$A
-+	lea	`2*$SZ*($rounds-8)`(%rsp),$Tbl
-+
-+	vpand	$mask14,$temp,$temp
-+	vpor	$temp,$iv,$iv
-+	vmovdqu	$iv,(%r12,%r13)			# write output
-+	lea	16(%r13),%r13
-+
-+	add	$SZ*0(%r15),$A
-+	add	$SZ*1(%r15),$B
-+	add	$SZ*2(%r15),$C
-+	add	$SZ*3(%r15),$D
-+	add	$SZ*4(%r15),$E
-+	add	$SZ*5(%r15),$F
-+	add	$SZ*6(%r15),$G
-+	add	$SZ*7(%r15),$H
-+
-+	mov	$A,$SZ*0(%r15)
-+	mov	$B,$SZ*1(%r15)
-+	mov	$C,$SZ*2(%r15)
-+	mov	$D,$SZ*3(%r15)
-+	mov	$E,$SZ*4(%r15)
-+	mov	$F,$SZ*5(%r15)
-+	mov	$G,$SZ*6(%r15)
-+	mov	$H,$SZ*7(%r15)
-+
-+	cmp	`$PUSH8+2*8`($Tbl),%r13		# $_end
-+	je	.Ldone_avx2
-+
-+	xor	$a1,$a1
-+	mov	$B,$a3
-+	mov	$F,$a4
-+	xor	$C,$a3			# magic
-+	jmp	.Lower_avx2
-+.align	16
-+.Lower_avx2:
-+	vmovdqu	(%r13),$inout
-+	vpinsrq	\$0,%r13,$offload,$offload
-+___
-+    $aesni_cbc_idx=0;
-+    for ($i=0; $i<16; ) {
-+	my $base="+16($Tbl)";
-+	foreach(bodyx_00_15()) { eval; }
-+	&lea	($Tbl,"-$PUSH8($Tbl)")	if ($i==8);
-+    }
-+$code.=<<___;
-+	vmovq	$offload,%r13			# borrow $a0
-+	vpextrq	\$1,$offload,%r15		# borrow $a2
-+	vpand	$mask14,$temp,$temp
-+	vpor	$temp,$iv,$iv
-+	lea	-$PUSH8($Tbl),$Tbl
-+	vmovdqu	$iv,(%r15,%r13)			# write output
-+	lea	16(%r13),%r13			# inp++
-+	cmp	%rsp,$Tbl
-+	jae	.Lower_avx2
-+
-+	mov	`2*$SZ*$rounds+5*8`(%rsp),%r15	# $_ctx, borrow $a2
-+	lea	16*$SZ(%r13),%r13
-+	mov	`2*$SZ*$rounds+6*8`(%rsp),%rsi	# $_in0, borrow $a3
-+	add	$a1,$A
-+	lea	`2*$SZ*($rounds-8)`(%rsp),%rsp
-+
-+	add	$SZ*0(%r15),$A
-+	add	$SZ*1(%r15),$B
-+	add	$SZ*2(%r15),$C
-+	add	$SZ*3(%r15),$D
-+	add	$SZ*4(%r15),$E
-+	add	$SZ*5(%r15),$F
-+	add	$SZ*6(%r15),$G
-+	lea	(%rsi,%r13),%r12
-+	add	$SZ*7(%r15),$H
-+
-+	cmp	$_end,%r13
-+
-+	mov	$A,$SZ*0(%r15)
-+	cmove	%rsp,%r12		# next block or stale data
-+	mov	$B,$SZ*1(%r15)
-+	mov	$C,$SZ*2(%r15)
-+	mov	$D,$SZ*3(%r15)
-+	mov	$E,$SZ*4(%r15)
-+	mov	$F,$SZ*5(%r15)
-+	mov	$G,$SZ*6(%r15)
-+	mov	$H,$SZ*7(%r15)
-+
-+	jbe	.Loop_avx2
-+	lea	(%rsp),$Tbl
-+
-+.Ldone_avx2:
-+	lea	($Tbl),%rsp
-+	mov	$_ivp,$ivp
-+	mov	$_rsp,%rsi
-+	vmovdqu	$iv,($ivp)		# output IV
-+	vzeroall
-+___
-+$code.=<<___ if ($win64);
-+	movaps	`$framesz+16*0`(%rsp),%xmm6
-+	movaps	`$framesz+16*1`(%rsp),%xmm7
-+	movaps	`$framesz+16*2`(%rsp),%xmm8
-+	movaps	`$framesz+16*3`(%rsp),%xmm9
-+	movaps	`$framesz+16*4`(%rsp),%xmm10
-+	movaps	`$framesz+16*5`(%rsp),%xmm11
-+	movaps	`$framesz+16*6`(%rsp),%xmm12
-+	movaps	`$framesz+16*7`(%rsp),%xmm13
-+	movaps	`$framesz+16*8`(%rsp),%xmm14
-+	movaps	`$framesz+16*9`(%rsp),%xmm15
-+___
-+$code.=<<___;
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_avx2:
-+	ret
-+.size	${func}_avx2,.-${func}_avx2
-+___
-+}}
-+}}
-+{{
-+my ($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10");
-+
-+my ($rounds,$Tbl)=("%r11d","%rbx");
-+
-+my ($iv,$in,$rndkey0)=map("%xmm$_",(6,14,15));
-+my @rndkey=("%xmm4","%xmm5");
-+my $r=0;
-+my $sn=0;
-+
-+my ($Wi,$ABEF,$CDGH,$TMP,$BSWAP,$ABEF_SAVE,$CDGH_SAVE)=map("%xmm$_",(0..3,7..9));
-+my @MSG=map("%xmm$_",(10..13));
-+
-+my $aesenc=sub {
-+  use integer;
-+  my ($n,$k)=($r/10,$r%10);
-+    if ($k==0) {
-+      $code.=<<___;
-+	movups		`16*$n`($in0),$in		# load input
-+	xorps		$rndkey0,$in
-+___
-+      $code.=<<___ if ($n);
-+	movups		$iv,`16*($n-1)`($out,$in0)	# write output
-+___
-+      $code.=<<___;
-+	xorps		$in,$iv
-+	movups		`32+16*$k-112`($key),$rndkey[1]
-+	aesenc		$rndkey[0],$iv
-+___
-+    } elsif ($k==9) {
-+      $sn++;
-+      $code.=<<___;
-+	cmp		\$11,$rounds
-+	jb		.Laesenclast$sn
-+	movups		`32+16*($k+0)-112`($key),$rndkey[1]
-+	aesenc		$rndkey[0],$iv
-+	movups		`32+16*($k+1)-112`($key),$rndkey[0]
-+	aesenc		$rndkey[1],$iv
-+	je		.Laesenclast$sn
-+	movups		`32+16*($k+2)-112`($key),$rndkey[1]
-+	aesenc		$rndkey[0],$iv
-+	movups		`32+16*($k+3)-112`($key),$rndkey[0]
-+	aesenc		$rndkey[1],$iv
-+.Laesenclast$sn:
-+	aesenclast	$rndkey[0],$iv
-+	movups		16-112($key),$rndkey[1]		# forward reference
-+	nop
-+___
-+    } else {
-+      $code.=<<___;
-+	movups		`32+16*$k-112`($key),$rndkey[1]
-+	aesenc		$rndkey[0],$iv
-+___
-+    }
-+    $r++;	unshift(@rndkey,pop(@rndkey));
-+};
-+
-+if ($shaext) {
-+my $Tbl="%rax";
-+
-+$code.=<<___;
-+.type	${func}_shaext,\@function,6
-+.align	32
-+${func}_shaext:
-+	mov	`($win64?56:8)`(%rsp),$inp	# load 7th argument
-+___
-+$code.=<<___ if ($win64);
-+	lea	`-8-10*16`(%rsp),%rsp
-+	movaps	%xmm6,-8-10*16(%rax)
-+	movaps	%xmm7,-8-9*16(%rax)
-+	movaps	%xmm8,-8-8*16(%rax)
-+	movaps	%xmm9,-8-7*16(%rax)
-+	movaps	%xmm10,-8-6*16(%rax)
-+	movaps	%xmm11,-8-5*16(%rax)
-+	movaps	%xmm12,-8-4*16(%rax)
-+	movaps	%xmm13,-8-3*16(%rax)
-+	movaps	%xmm14,-8-2*16(%rax)
-+	movaps	%xmm15,-8-1*16(%rax)
-+.Lprologue_shaext:
-+___
-+$code.=<<___;
-+	lea		K256+0x80(%rip),$Tbl
-+	movdqu		($ctx),$ABEF		# DCBA
-+	movdqu		16($ctx),$CDGH		# HGFE
-+	movdqa		0x200-0x80($Tbl),$TMP	# byte swap mask
-+
-+	mov		240($key),$rounds
-+	sub		$in0,$out
-+	movups		($key),$rndkey0		# $key[0]
-+	movups		16($key),$rndkey[0]	# forward reference
-+	lea		112($key),$key		# size optimization
-+
-+	pshufd		\$0x1b,$ABEF,$Wi	# ABCD
-+	pshufd		\$0xb1,$ABEF,$ABEF	# CDAB
-+	pshufd		\$0x1b,$CDGH,$CDGH	# EFGH
-+	movdqa		$TMP,$BSWAP		# offload
-+	palignr		\$8,$CDGH,$ABEF		# ABEF
-+	punpcklqdq	$Wi,$CDGH		# CDGH
-+
-+	jmp	.Loop_shaext
-+
-+.align	16
-+.Loop_shaext:
-+	movdqu		($inp),@MSG[0]
-+	movdqu		0x10($inp),@MSG[1]
-+	movdqu		0x20($inp),@MSG[2]
-+	pshufb		$TMP,@MSG[0]
-+	movdqu		0x30($inp),@MSG[3]
-+
-+	movdqa		0*32-0x80($Tbl),$Wi
-+	paddd		@MSG[0],$Wi
-+	pshufb		$TMP,@MSG[1]
-+	movdqa		$CDGH,$CDGH_SAVE	# offload
-+	movdqa		$ABEF,$ABEF_SAVE	# offload
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$ABEF,$CDGH		# 0-3
-+	pshufd		\$0x0e,$Wi,$Wi
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$CDGH,$ABEF
-+
-+	movdqa		1*32-0x80($Tbl),$Wi
-+	paddd		@MSG[1],$Wi
-+	pshufb		$TMP,@MSG[2]
-+	lea		0x40($inp),$inp
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$ABEF,$CDGH		# 4-7
-+	pshufd		\$0x0e,$Wi,$Wi
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$CDGH,$ABEF
-+
-+	movdqa		2*32-0x80($Tbl),$Wi
-+	paddd		@MSG[2],$Wi
-+	pshufb		$TMP,@MSG[3]
-+	sha256msg1	@MSG[1],@MSG[0]
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$ABEF,$CDGH		# 8-11
-+	pshufd		\$0x0e,$Wi,$Wi
-+	movdqa		@MSG[3],$TMP
-+	palignr		\$4,@MSG[2],$TMP
-+	paddd		$TMP,@MSG[0]
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$CDGH,$ABEF
-+
-+	movdqa		3*32-0x80($Tbl),$Wi
-+	paddd		@MSG[3],$Wi
-+	sha256msg2	@MSG[3],@MSG[0]
-+	sha256msg1	@MSG[2],@MSG[1]
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$ABEF,$CDGH		# 12-15
-+	pshufd		\$0x0e,$Wi,$Wi
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	movdqa		@MSG[0],$TMP
-+	palignr		\$4,@MSG[3],$TMP
-+	paddd		$TMP,@MSG[1]
-+	sha256rnds2	$CDGH,$ABEF
-+___
-+for($i=4;$i<16-3;$i++) {
-+	&$aesenc()	if (($r%10)==0);
-+$code.=<<___;
-+	movdqa		$i*32-0x80($Tbl),$Wi
-+	paddd		@MSG[0],$Wi
-+	sha256msg2	@MSG[0],@MSG[1]
-+	sha256msg1	@MSG[3],@MSG[2]
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$ABEF,$CDGH		# 16-19...
-+	pshufd		\$0x0e,$Wi,$Wi
-+	movdqa		@MSG[1],$TMP
-+	palignr		\$4,@MSG[0],$TMP
-+	paddd		$TMP,@MSG[2]
-+___
-+	&$aesenc();
-+	&$aesenc()	if ($r==19);
-+$code.=<<___;
-+	sha256rnds2	$CDGH,$ABEF
-+___
-+	push(@MSG,shift(@MSG));
-+}
-+$code.=<<___;
-+	movdqa		13*32-0x80($Tbl),$Wi
-+	paddd		@MSG[0],$Wi
-+	sha256msg2	@MSG[0],@MSG[1]
-+	sha256msg1	@MSG[3],@MSG[2]
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$ABEF,$CDGH		# 52-55
-+	pshufd		\$0x0e,$Wi,$Wi
-+	movdqa		@MSG[1],$TMP
-+	palignr		\$4,@MSG[0],$TMP
-+	paddd		$TMP,@MSG[2]
-+___
-+	&$aesenc();
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$CDGH,$ABEF
-+
-+	movdqa		14*32-0x80($Tbl),$Wi
-+	paddd		@MSG[1],$Wi
-+	sha256msg2	@MSG[1],@MSG[2]
-+	movdqa		$BSWAP,$TMP
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$ABEF,$CDGH		# 56-59
-+	pshufd		\$0x0e,$Wi,$Wi
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$CDGH,$ABEF
-+
-+	movdqa		15*32-0x80($Tbl),$Wi
-+	paddd		@MSG[2],$Wi
-+___
-+	&$aesenc();
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$ABEF,$CDGH		# 60-63
-+	pshufd		\$0x0e,$Wi,$Wi
-+___
-+	&$aesenc();
-+$code.=<<___;
-+	sha256rnds2	$CDGH,$ABEF
-+	#pxor		$CDGH,$rndkey0		# black magic
-+___
-+	while ($r<40)	{ &$aesenc(); }		# remaining aesenc's
-+$code.=<<___;
-+	#xorps		$CDGH,$rndkey0		# black magic
-+	paddd		$CDGH_SAVE,$CDGH
-+	paddd		$ABEF_SAVE,$ABEF
-+
-+	dec		$len
-+	movups		$iv,48($out,$in0)	# write output
-+	lea		64($in0),$in0
-+	jnz		.Loop_shaext
-+
-+	pshufd		\$0xb1,$CDGH,$CDGH	# DCHG
-+	pshufd		\$0x1b,$ABEF,$TMP	# FEBA
-+	pshufd		\$0xb1,$ABEF,$ABEF	# BAFE
-+	punpckhqdq	$CDGH,$ABEF		# DCBA
-+	palignr		\$8,$TMP,$CDGH		# HGFE
-+
-+	movups		$iv,($ivp)		# write IV
-+	movdqu		$ABEF,($ctx)
-+	movdqu		$CDGH,16($ctx)
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0*16(%rsp),%xmm6
-+	movaps	1*16(%rsp),%xmm7
-+	movaps	2*16(%rsp),%xmm8
-+	movaps	3*16(%rsp),%xmm9
-+	movaps	4*16(%rsp),%xmm10
-+	movaps	5*16(%rsp),%xmm11
-+	movaps	6*16(%rsp),%xmm12
-+	movaps	7*16(%rsp),%xmm13
-+	movaps	8*16(%rsp),%xmm14
-+	movaps	9*16(%rsp),%xmm15
-+	lea	8+10*16(%rsp),%rsp
-+.Lepilogue_shaext:
-+___
-+$code.=<<___;
-+	ret
-+.size	${func}_shaext,.-${func}_shaext
-+___
-+}
-+}}}}}
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64 && $avx) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HanderlData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_prologue
-+___
-+$code.=<<___ if ($shaext);
-+	lea	aesni_cbc_sha256_enc_shaext(%rip),%r10
-+	cmp	%r10,%rbx
-+	jb	.Lnot_in_shaext
-+
-+	lea	(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+	lea	168(%rax),%rax		# adjust stack pointer
-+	jmp	.Lin_prologue
-+.Lnot_in_shaext:
-+___
-+$code.=<<___ if ($avx>1);
-+	lea	.Lavx2_shortcut(%rip),%r10
-+	cmp	%r10,%rbx		# context->RipRbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+	lea	16*$SZ+8*8(%rsi),%rsi	# Xmm6- save area
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+
-+.section	.pdata
-+	.rva	.LSEH_begin_${func}_xop
-+	.rva	.LSEH_end_${func}_xop
-+	.rva	.LSEH_info_${func}_xop
-+
-+	.rva	.LSEH_begin_${func}_avx
-+	.rva	.LSEH_end_${func}_avx
-+	.rva	.LSEH_info_${func}_avx
-+___
-+$code.=<<___ if ($avx>1);
-+	.rva	.LSEH_begin_${func}_avx2
-+	.rva	.LSEH_end_${func}_avx2
-+	.rva	.LSEH_info_${func}_avx2
-+___
-+$code.=<<___ if ($shaext);
-+	.rva	.LSEH_begin_${func}_shaext
-+	.rva	.LSEH_end_${func}_shaext
-+	.rva	.LSEH_info_${func}_shaext
-+___
-+$code.=<<___;
-+.section	.xdata
-+.align	8
-+.LSEH_info_${func}_xop:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lprologue_xop,.Lepilogue_xop		# HandlerData[]
-+
-+.LSEH_info_${func}_avx:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lprologue_avx,.Lepilogue_avx		# HandlerData[]
-+___
-+$code.=<<___ if ($avx>1);
-+.LSEH_info_${func}_avx2:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lprologue_avx2,.Lepilogue_avx2		# HandlerData[]
-+___
-+$code.=<<___ if ($shaext);
-+.LSEH_info_${func}_shaext:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lprologue_shaext,.Lepilogue_shaext	# HandlerData[]
-+___
-+}
-+
-+####################################################################
-+sub rex {
-+  local *opcode=shift;
-+  my ($dst,$src)=@_;
-+  my $rex=0;
-+
-+    $rex|=0x04			if($dst>=8);
-+    $rex|=0x01			if($src>=8);
-+    unshift @opcode,$rex|0x40	if($rex);
-+}
-+
-+{
-+  my %opcodelet = (
-+		"sha256rnds2" => 0xcb,
-+  		"sha256msg1"  => 0xcc,
-+		"sha256msg2"  => 0xcd	);
-+
-+  sub sha256op38 {
-+    my $instr = shift;
-+
-+    if (defined($opcodelet{$instr}) && @_[0] =~ /%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x0f,0x38);
-+	rex(\@opcode,$2,$1);
-+	push @opcode,$opcodelet{$instr};
-+	push @opcode,0xc0|($1&7)|(($2&7)<<3);		# ModR/M
-+	return ".byte\t".join(',',@opcode);
-+    } else {
-+	return $instr."\t".@_[0];
-+    }
-+  }
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+$code =~ s/\b(sha256[^\s]*)\s+(.*)/sha256op38($1,$2)/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-x86.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-x86.pl
-new file mode 100644
-index 0000000..ed1a47c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-x86.pl
-@@ -0,0 +1,3413 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements support for Intel AES-NI extension. In
-+# OpenSSL context it's used with Intel engine, but can also be used as
-+# drop-in replacement for crypto/aes/asm/aes-586.pl [see below for
-+# details].
-+#
-+# Performance.
-+#
-+# To start with see corresponding paragraph in aesni-x86_64.pl...
-+# Instead of filling table similar to one found there I've chosen to
-+# summarize *comparison* results for raw ECB, CTR and CBC benchmarks.
-+# The simplified table below represents 32-bit performance relative
-+# to 64-bit one in every given point. Ratios vary for different
-+# encryption modes, therefore interval values.
-+#
-+#	16-byte     64-byte     256-byte    1-KB        8-KB
-+#	53-67%      67-84%      91-94%      95-98%      97-99.5%
-+#
-+# Lower ratios for smaller block sizes are perfectly understandable,
-+# because function call overhead is higher in 32-bit mode. Largest
-+# 8-KB block performance is virtually same: 32-bit code is less than
-+# 1% slower for ECB, CBC and CCM, and ~3% slower otherwise.
-+
-+# January 2011
-+#
-+# See aesni-x86_64.pl for details. Unlike x86_64 version this module
-+# interleaves at most 6 aes[enc|dec] instructions, because there are
-+# not enough registers for 8x interleave [which should be optimal for
-+# Sandy Bridge]. Actually, performance results for 6x interleave
-+# factor presented in aesni-x86_64.pl (except for CTR) are for this
-+# module.
-+
-+# April 2011
-+#
-+# Add aesni_xts_[en|de]crypt. Westmere spends 1.50 cycles processing
-+# one byte out of 8KB with 128-bit key, Sandy Bridge - 1.09.
-+
-+# November 2015
-+#
-+# Add aesni_ocb_[en|de]crypt.
-+
-+######################################################################
-+# Current large-block performance in cycles per byte processed with
-+# 128-bit key (less is better).
-+#
-+#		CBC en-/decrypt	CTR	XTS	ECB	OCB
-+# Westmere	3.77/1.37	1.37	1.52	1.27
-+# * Bridge	5.07/0.98	0.99	1.09	0.91	1.10
-+# Haswell	4.44/0.80	0.97	1.03	0.72	0.76
-+# Silvermont	5.77/3.56	3.67	4.03	3.46	4.03
-+# Bulldozer	5.80/0.98	1.05	1.24	0.93	1.23
-+
-+$PREFIX="aesni";	# if $PREFIX is set to "AES", the script
-+			# generates drop-in replacement for
-+			# crypto/aes/asm/aes-586.pl:-)
-+$inline=1;		# inline _aesni_[en|de]crypt
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output = pop;
-+open OUT,">$output";
-+*STDOUT=*OUT;
-+
-+&asm_init($ARGV[0],$0);
-+
-+&external_label("OPENSSL_ia32cap_P");
-+&static_label("key_const");
-+
-+if ($PREFIX eq "aesni")	{ $movekey=\&movups; }
-+else			{ $movekey=\&movups; }
-+
-+$len="eax";
-+$rounds="ecx";
-+$key="edx";
-+$inp="esi";
-+$out="edi";
-+$rounds_="ebx";	# backup copy for $rounds
-+$key_="ebp";	# backup copy for $key
-+
-+$rndkey0="xmm0";
-+$rndkey1="xmm1";
-+$inout0="xmm2";
-+$inout1="xmm3";
-+$inout2="xmm4";
-+$inout3="xmm5";	$in1="xmm5";
-+$inout4="xmm6";	$in0="xmm6";
-+$inout5="xmm7";	$ivec="xmm7";
-+
-+# AESNI extension
-+sub aeskeygenassist
-+{ my($dst,$src,$imm)=@_;
-+    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
-+    {	&data_byte(0x66,0x0f,0x3a,0xdf,0xc0|($1<<3)|$2,$imm);	}
-+}
-+sub aescommon
-+{ my($opcodelet,$dst,$src)=@_;
-+    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
-+    {	&data_byte(0x66,0x0f,0x38,$opcodelet,0xc0|($1<<3)|$2);}
-+}
-+sub aesimc	{ aescommon(0xdb,@_); }
-+sub aesenc	{ aescommon(0xdc,@_); }
-+sub aesenclast	{ aescommon(0xdd,@_); }
-+sub aesdec	{ aescommon(0xde,@_); }
-+sub aesdeclast	{ aescommon(0xdf,@_); }
-+
-+# Inline version of internal aesni_[en|de]crypt1
-+{ my $sn;
-+sub aesni_inline_generate1
-+{ my ($p,$inout,$ivec)=@_; $inout=$inout0 if (!defined($inout));
-+  $sn++;
-+
-+    &$movekey		($rndkey0,&QWP(0,$key));
-+    &$movekey		($rndkey1,&QWP(16,$key));
-+    &xorps		($ivec,$rndkey0)	if (defined($ivec));
-+    &lea		($key,&DWP(32,$key));
-+    &xorps		($inout,$ivec)		if (defined($ivec));
-+    &xorps		($inout,$rndkey0)	if (!defined($ivec));
-+    &set_label("${p}1_loop_$sn");
-+	eval"&aes${p}	($inout,$rndkey1)";
-+	&dec		($rounds);
-+	&$movekey	($rndkey1,&QWP(0,$key));
-+	&lea		($key,&DWP(16,$key));
-+    &jnz		(&label("${p}1_loop_$sn"));
-+    eval"&aes${p}last	($inout,$rndkey1)";
-+}}
-+
-+sub aesni_generate1	# fully unrolled loop
-+{ my ($p,$inout)=@_; $inout=$inout0 if (!defined($inout));
-+
-+    &function_begin_B("_aesni_${p}rypt1");
-+	&movups		($rndkey0,&QWP(0,$key));
-+	&$movekey	($rndkey1,&QWP(0x10,$key));
-+	&xorps		($inout,$rndkey0);
-+	&$movekey	($rndkey0,&QWP(0x20,$key));
-+	&lea		($key,&DWP(0x30,$key));
-+	&cmp		($rounds,11);
-+	&jb		(&label("${p}128"));
-+	&lea		($key,&DWP(0x20,$key));
-+	&je		(&label("${p}192"));
-+	&lea		($key,&DWP(0x20,$key));
-+	eval"&aes${p}	($inout,$rndkey1)";
-+	&$movekey	($rndkey1,&QWP(-0x40,$key));
-+	eval"&aes${p}	($inout,$rndkey0)";
-+	&$movekey	($rndkey0,&QWP(-0x30,$key));
-+    &set_label("${p}192");
-+	eval"&aes${p}	($inout,$rndkey1)";
-+	&$movekey	($rndkey1,&QWP(-0x20,$key));
-+	eval"&aes${p}	($inout,$rndkey0)";
-+	&$movekey	($rndkey0,&QWP(-0x10,$key));
-+    &set_label("${p}128");
-+	eval"&aes${p}	($inout,$rndkey1)";
-+	&$movekey	($rndkey1,&QWP(0,$key));
-+	eval"&aes${p}	($inout,$rndkey0)";
-+	&$movekey	($rndkey0,&QWP(0x10,$key));
-+	eval"&aes${p}	($inout,$rndkey1)";
-+	&$movekey	($rndkey1,&QWP(0x20,$key));
-+	eval"&aes${p}	($inout,$rndkey0)";
-+	&$movekey	($rndkey0,&QWP(0x30,$key));
-+	eval"&aes${p}	($inout,$rndkey1)";
-+	&$movekey	($rndkey1,&QWP(0x40,$key));
-+	eval"&aes${p}	($inout,$rndkey0)";
-+	&$movekey	($rndkey0,&QWP(0x50,$key));
-+	eval"&aes${p}	($inout,$rndkey1)";
-+	&$movekey	($rndkey1,&QWP(0x60,$key));
-+	eval"&aes${p}	($inout,$rndkey0)";
-+	&$movekey	($rndkey0,&QWP(0x70,$key));
-+	eval"&aes${p}	($inout,$rndkey1)";
-+    eval"&aes${p}last	($inout,$rndkey0)";
-+    &ret();
-+    &function_end_B("_aesni_${p}rypt1");
-+}
-+
-+# void $PREFIX_encrypt (const void *inp,void *out,const AES_KEY *key);
-+&aesni_generate1("enc") if (!$inline);
-+&function_begin_B("${PREFIX}_encrypt");
-+	&mov	("eax",&wparam(0));
-+	&mov	($key,&wparam(2));
-+	&movups	($inout0,&QWP(0,"eax"));
-+	&mov	($rounds,&DWP(240,$key));
-+	&mov	("eax",&wparam(1));
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc");	}
-+	else
-+	{   &call	("_aesni_encrypt1");	}
-+	&pxor	($rndkey0,$rndkey0);		# clear register bank
-+	&pxor	($rndkey1,$rndkey1);
-+	&movups	(&QWP(0,"eax"),$inout0);
-+	&pxor	($inout0,$inout0);
-+	&ret	();
-+&function_end_B("${PREFIX}_encrypt");
-+
-+# void $PREFIX_decrypt (const void *inp,void *out,const AES_KEY *key);
-+&aesni_generate1("dec") if(!$inline);
-+&function_begin_B("${PREFIX}_decrypt");
-+	&mov	("eax",&wparam(0));
-+	&mov	($key,&wparam(2));
-+	&movups	($inout0,&QWP(0,"eax"));
-+	&mov	($rounds,&DWP(240,$key));
-+	&mov	("eax",&wparam(1));
-+	if ($inline)
-+	{   &aesni_inline_generate1("dec");	}
-+	else
-+	{   &call	("_aesni_decrypt1");	}
-+	&pxor	($rndkey0,$rndkey0);		# clear register bank
-+	&pxor	($rndkey1,$rndkey1);
-+	&movups	(&QWP(0,"eax"),$inout0);
-+	&pxor	($inout0,$inout0);
-+	&ret	();
-+&function_end_B("${PREFIX}_decrypt");
-+
-+# _aesni_[en|de]cryptN are private interfaces, N denotes interleave
-+# factor. Why 3x subroutine were originally used in loops? Even though
-+# aes[enc|dec] latency was originally 6, it could be scheduled only
-+# every *2nd* cycle. Thus 3x interleave was the one providing optimal
-+# utilization, i.e. when subroutine's throughput is virtually same as
-+# of non-interleaved subroutine [for number of input blocks up to 3].
-+# This is why it originally made no sense to implement 2x subroutine.
-+# But times change and it became appropriate to spend extra 192 bytes
-+# on 2x subroutine on Atom Silvermont account. For processors that
-+# can schedule aes[enc|dec] every cycle optimal interleave factor
-+# equals to corresponding instructions latency. 8x is optimal for
-+# * Bridge, but it's unfeasible to accommodate such implementation
-+# in XMM registers addreassable in 32-bit mode and therefore maximum
-+# of 6x is used instead...
-+
-+sub aesni_generate2
-+{ my $p=shift;
-+
-+    &function_begin_B("_aesni_${p}rypt2");
-+	&$movekey	($rndkey0,&QWP(0,$key));
-+	&shl		($rounds,4);
-+	&$movekey	($rndkey1,&QWP(16,$key));
-+	&xorps		($inout0,$rndkey0);
-+	&pxor		($inout1,$rndkey0);
-+	&$movekey	($rndkey0,&QWP(32,$key));
-+	&lea		($key,&DWP(32,$key,$rounds));
-+	&neg		($rounds);
-+	&add		($rounds,16);
-+
-+    &set_label("${p}2_loop");
-+	eval"&aes${p}	($inout0,$rndkey1)";
-+	eval"&aes${p}	($inout1,$rndkey1)";
-+	&$movekey	($rndkey1,&QWP(0,$key,$rounds));
-+	&add		($rounds,32);
-+	eval"&aes${p}	($inout0,$rndkey0)";
-+	eval"&aes${p}	($inout1,$rndkey0)";
-+	&$movekey	($rndkey0,&QWP(-16,$key,$rounds));
-+	&jnz		(&label("${p}2_loop"));
-+    eval"&aes${p}	($inout0,$rndkey1)";
-+    eval"&aes${p}	($inout1,$rndkey1)";
-+    eval"&aes${p}last	($inout0,$rndkey0)";
-+    eval"&aes${p}last	($inout1,$rndkey0)";
-+    &ret();
-+    &function_end_B("_aesni_${p}rypt2");
-+}
-+
-+sub aesni_generate3
-+{ my $p=shift;
-+
-+    &function_begin_B("_aesni_${p}rypt3");
-+	&$movekey	($rndkey0,&QWP(0,$key));
-+	&shl		($rounds,4);
-+	&$movekey	($rndkey1,&QWP(16,$key));
-+	&xorps		($inout0,$rndkey0);
-+	&pxor		($inout1,$rndkey0);
-+	&pxor		($inout2,$rndkey0);
-+	&$movekey	($rndkey0,&QWP(32,$key));
-+	&lea		($key,&DWP(32,$key,$rounds));
-+	&neg		($rounds);
-+	&add		($rounds,16);
-+
-+    &set_label("${p}3_loop");
-+	eval"&aes${p}	($inout0,$rndkey1)";
-+	eval"&aes${p}	($inout1,$rndkey1)";
-+	eval"&aes${p}	($inout2,$rndkey1)";
-+	&$movekey	($rndkey1,&QWP(0,$key,$rounds));
-+	&add		($rounds,32);
-+	eval"&aes${p}	($inout0,$rndkey0)";
-+	eval"&aes${p}	($inout1,$rndkey0)";
-+	eval"&aes${p}	($inout2,$rndkey0)";
-+	&$movekey	($rndkey0,&QWP(-16,$key,$rounds));
-+	&jnz		(&label("${p}3_loop"));
-+    eval"&aes${p}	($inout0,$rndkey1)";
-+    eval"&aes${p}	($inout1,$rndkey1)";
-+    eval"&aes${p}	($inout2,$rndkey1)";
-+    eval"&aes${p}last	($inout0,$rndkey0)";
-+    eval"&aes${p}last	($inout1,$rndkey0)";
-+    eval"&aes${p}last	($inout2,$rndkey0)";
-+    &ret();
-+    &function_end_B("_aesni_${p}rypt3");
-+}
-+
-+# 4x interleave is implemented to improve small block performance,
-+# most notably [and naturally] 4 block by ~30%. One can argue that one
-+# should have implemented 5x as well, but improvement  would be <20%,
-+# so it's not worth it...
-+sub aesni_generate4
-+{ my $p=shift;
-+
-+    &function_begin_B("_aesni_${p}rypt4");
-+	&$movekey	($rndkey0,&QWP(0,$key));
-+	&$movekey	($rndkey1,&QWP(16,$key));
-+	&shl		($rounds,4);
-+	&xorps		($inout0,$rndkey0);
-+	&pxor		($inout1,$rndkey0);
-+	&pxor		($inout2,$rndkey0);
-+	&pxor		($inout3,$rndkey0);
-+	&$movekey	($rndkey0,&QWP(32,$key));
-+	&lea		($key,&DWP(32,$key,$rounds));
-+	&neg		($rounds);
-+	&data_byte	(0x0f,0x1f,0x40,0x00);
-+	&add		($rounds,16);
-+
-+    &set_label("${p}4_loop");
-+	eval"&aes${p}	($inout0,$rndkey1)";
-+	eval"&aes${p}	($inout1,$rndkey1)";
-+	eval"&aes${p}	($inout2,$rndkey1)";
-+	eval"&aes${p}	($inout3,$rndkey1)";
-+	&$movekey	($rndkey1,&QWP(0,$key,$rounds));
-+	&add		($rounds,32);
-+	eval"&aes${p}	($inout0,$rndkey0)";
-+	eval"&aes${p}	($inout1,$rndkey0)";
-+	eval"&aes${p}	($inout2,$rndkey0)";
-+	eval"&aes${p}	($inout3,$rndkey0)";
-+	&$movekey	($rndkey0,&QWP(-16,$key,$rounds));
-+    &jnz		(&label("${p}4_loop"));
-+
-+    eval"&aes${p}	($inout0,$rndkey1)";
-+    eval"&aes${p}	($inout1,$rndkey1)";
-+    eval"&aes${p}	($inout2,$rndkey1)";
-+    eval"&aes${p}	($inout3,$rndkey1)";
-+    eval"&aes${p}last	($inout0,$rndkey0)";
-+    eval"&aes${p}last	($inout1,$rndkey0)";
-+    eval"&aes${p}last	($inout2,$rndkey0)";
-+    eval"&aes${p}last	($inout3,$rndkey0)";
-+    &ret();
-+    &function_end_B("_aesni_${p}rypt4");
-+}
-+
-+sub aesni_generate6
-+{ my $p=shift;
-+
-+    &function_begin_B("_aesni_${p}rypt6");
-+    &static_label("_aesni_${p}rypt6_enter");
-+	&$movekey	($rndkey0,&QWP(0,$key));
-+	&shl		($rounds,4);
-+	&$movekey	($rndkey1,&QWP(16,$key));
-+	&xorps		($inout0,$rndkey0);
-+	&pxor		($inout1,$rndkey0);	# pxor does better here
-+	&pxor		($inout2,$rndkey0);
-+	eval"&aes${p}	($inout0,$rndkey1)";
-+	&pxor		($inout3,$rndkey0);
-+	&pxor		($inout4,$rndkey0);
-+	eval"&aes${p}	($inout1,$rndkey1)";
-+	&lea		($key,&DWP(32,$key,$rounds));
-+	&neg		($rounds);
-+	eval"&aes${p}	($inout2,$rndkey1)";
-+	&pxor		($inout5,$rndkey0);
-+	&$movekey	($rndkey0,&QWP(0,$key,$rounds));
-+	&add		($rounds,16);
-+	&jmp		(&label("_aesni_${p}rypt6_inner"));
-+
-+    &set_label("${p}6_loop",16);
-+	eval"&aes${p}	($inout0,$rndkey1)";
-+	eval"&aes${p}	($inout1,$rndkey1)";
-+	eval"&aes${p}	($inout2,$rndkey1)";
-+    &set_label("_aesni_${p}rypt6_inner");
-+	eval"&aes${p}	($inout3,$rndkey1)";
-+	eval"&aes${p}	($inout4,$rndkey1)";
-+	eval"&aes${p}	($inout5,$rndkey1)";
-+    &set_label("_aesni_${p}rypt6_enter");
-+	&$movekey	($rndkey1,&QWP(0,$key,$rounds));
-+	&add		($rounds,32);
-+	eval"&aes${p}	($inout0,$rndkey0)";
-+	eval"&aes${p}	($inout1,$rndkey0)";
-+	eval"&aes${p}	($inout2,$rndkey0)";
-+	eval"&aes${p}	($inout3,$rndkey0)";
-+	eval"&aes${p}	($inout4,$rndkey0)";
-+	eval"&aes${p}	($inout5,$rndkey0)";
-+	&$movekey	($rndkey0,&QWP(-16,$key,$rounds));
-+    &jnz		(&label("${p}6_loop"));
-+
-+    eval"&aes${p}	($inout0,$rndkey1)";
-+    eval"&aes${p}	($inout1,$rndkey1)";
-+    eval"&aes${p}	($inout2,$rndkey1)";
-+    eval"&aes${p}	($inout3,$rndkey1)";
-+    eval"&aes${p}	($inout4,$rndkey1)";
-+    eval"&aes${p}	($inout5,$rndkey1)";
-+    eval"&aes${p}last	($inout0,$rndkey0)";
-+    eval"&aes${p}last	($inout1,$rndkey0)";
-+    eval"&aes${p}last	($inout2,$rndkey0)";
-+    eval"&aes${p}last	($inout3,$rndkey0)";
-+    eval"&aes${p}last	($inout4,$rndkey0)";
-+    eval"&aes${p}last	($inout5,$rndkey0)";
-+    &ret();
-+    &function_end_B("_aesni_${p}rypt6");
-+}
-+&aesni_generate2("enc") if ($PREFIX eq "aesni");
-+&aesni_generate2("dec");
-+&aesni_generate3("enc") if ($PREFIX eq "aesni");
-+&aesni_generate3("dec");
-+&aesni_generate4("enc") if ($PREFIX eq "aesni");
-+&aesni_generate4("dec");
-+&aesni_generate6("enc") if ($PREFIX eq "aesni");
-+&aesni_generate6("dec");
-+
-+if ($PREFIX eq "aesni") {
-+######################################################################
-+# void aesni_ecb_encrypt (const void *in, void *out,
-+#                         size_t length, const AES_KEY *key,
-+#                         int enc);
-+&function_begin("aesni_ecb_encrypt");
-+	&mov	($inp,&wparam(0));
-+	&mov	($out,&wparam(1));
-+	&mov	($len,&wparam(2));
-+	&mov	($key,&wparam(3));
-+	&mov	($rounds_,&wparam(4));
-+	&and	($len,-16);
-+	&jz	(&label("ecb_ret"));
-+	&mov	($rounds,&DWP(240,$key));
-+	&test	($rounds_,$rounds_);
-+	&jz	(&label("ecb_decrypt"));
-+
-+	&mov	($key_,$key);		# backup $key
-+	&mov	($rounds_,$rounds);	# backup $rounds
-+	&cmp	($len,0x60);
-+	&jb	(&label("ecb_enc_tail"));
-+
-+	&movdqu	($inout0,&QWP(0,$inp));
-+	&movdqu	($inout1,&QWP(0x10,$inp));
-+	&movdqu	($inout2,&QWP(0x20,$inp));
-+	&movdqu	($inout3,&QWP(0x30,$inp));
-+	&movdqu	($inout4,&QWP(0x40,$inp));
-+	&movdqu	($inout5,&QWP(0x50,$inp));
-+	&lea	($inp,&DWP(0x60,$inp));
-+	&sub	($len,0x60);
-+	&jmp	(&label("ecb_enc_loop6_enter"));
-+
-+&set_label("ecb_enc_loop6",16);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movdqu	($inout0,&QWP(0,$inp));
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movdqu	($inout1,&QWP(0x10,$inp));
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&movdqu	($inout2,&QWP(0x20,$inp));
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&movdqu	($inout3,&QWP(0x30,$inp));
-+	&movups	(&QWP(0x40,$out),$inout4);
-+	&movdqu	($inout4,&QWP(0x40,$inp));
-+	&movups	(&QWP(0x50,$out),$inout5);
-+	&lea	($out,&DWP(0x60,$out));
-+	&movdqu	($inout5,&QWP(0x50,$inp));
-+	&lea	($inp,&DWP(0x60,$inp));
-+&set_label("ecb_enc_loop6_enter");
-+
-+	&call	("_aesni_encrypt6");
-+
-+	&mov	($key,$key_);		# restore $key
-+	&mov	($rounds,$rounds_);	# restore $rounds
-+	&sub	($len,0x60);
-+	&jnc	(&label("ecb_enc_loop6"));
-+
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&movups	(&QWP(0x40,$out),$inout4);
-+	&movups	(&QWP(0x50,$out),$inout5);
-+	&lea	($out,&DWP(0x60,$out));
-+	&add	($len,0x60);
-+	&jz	(&label("ecb_ret"));
-+
-+&set_label("ecb_enc_tail");
-+	&movups	($inout0,&QWP(0,$inp));
-+	&cmp	($len,0x20);
-+	&jb	(&label("ecb_enc_one"));
-+	&movups	($inout1,&QWP(0x10,$inp));
-+	&je	(&label("ecb_enc_two"));
-+	&movups	($inout2,&QWP(0x20,$inp));
-+	&cmp	($len,0x40);
-+	&jb	(&label("ecb_enc_three"));
-+	&movups	($inout3,&QWP(0x30,$inp));
-+	&je	(&label("ecb_enc_four"));
-+	&movups	($inout4,&QWP(0x40,$inp));
-+	&xorps	($inout5,$inout5);
-+	&call	("_aesni_encrypt6");
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&movups	(&QWP(0x40,$out),$inout4);
-+	jmp	(&label("ecb_ret"));
-+
-+&set_label("ecb_enc_one",16);
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc");	}
-+	else
-+	{   &call	("_aesni_encrypt1");	}
-+	&movups	(&QWP(0,$out),$inout0);
-+	&jmp	(&label("ecb_ret"));
-+
-+&set_label("ecb_enc_two",16);
-+	&call	("_aesni_encrypt2");
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&jmp	(&label("ecb_ret"));
-+
-+&set_label("ecb_enc_three",16);
-+	&call	("_aesni_encrypt3");
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&jmp	(&label("ecb_ret"));
-+
-+&set_label("ecb_enc_four",16);
-+	&call	("_aesni_encrypt4");
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&jmp	(&label("ecb_ret"));
-+######################################################################
-+&set_label("ecb_decrypt",16);
-+	&mov	($key_,$key);		# backup $key
-+	&mov	($rounds_,$rounds);	# backup $rounds
-+	&cmp	($len,0x60);
-+	&jb	(&label("ecb_dec_tail"));
-+
-+	&movdqu	($inout0,&QWP(0,$inp));
-+	&movdqu	($inout1,&QWP(0x10,$inp));
-+	&movdqu	($inout2,&QWP(0x20,$inp));
-+	&movdqu	($inout3,&QWP(0x30,$inp));
-+	&movdqu	($inout4,&QWP(0x40,$inp));
-+	&movdqu	($inout5,&QWP(0x50,$inp));
-+	&lea	($inp,&DWP(0x60,$inp));
-+	&sub	($len,0x60);
-+	&jmp	(&label("ecb_dec_loop6_enter"));
-+
-+&set_label("ecb_dec_loop6",16);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movdqu	($inout0,&QWP(0,$inp));
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movdqu	($inout1,&QWP(0x10,$inp));
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&movdqu	($inout2,&QWP(0x20,$inp));
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&movdqu	($inout3,&QWP(0x30,$inp));
-+	&movups	(&QWP(0x40,$out),$inout4);
-+	&movdqu	($inout4,&QWP(0x40,$inp));
-+	&movups	(&QWP(0x50,$out),$inout5);
-+	&lea	($out,&DWP(0x60,$out));
-+	&movdqu	($inout5,&QWP(0x50,$inp));
-+	&lea	($inp,&DWP(0x60,$inp));
-+&set_label("ecb_dec_loop6_enter");
-+
-+	&call	("_aesni_decrypt6");
-+
-+	&mov	($key,$key_);		# restore $key
-+	&mov	($rounds,$rounds_);	# restore $rounds
-+	&sub	($len,0x60);
-+	&jnc	(&label("ecb_dec_loop6"));
-+
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&movups	(&QWP(0x40,$out),$inout4);
-+	&movups	(&QWP(0x50,$out),$inout5);
-+	&lea	($out,&DWP(0x60,$out));
-+	&add	($len,0x60);
-+	&jz	(&label("ecb_ret"));
-+
-+&set_label("ecb_dec_tail");
-+	&movups	($inout0,&QWP(0,$inp));
-+	&cmp	($len,0x20);
-+	&jb	(&label("ecb_dec_one"));
-+	&movups	($inout1,&QWP(0x10,$inp));
-+	&je	(&label("ecb_dec_two"));
-+	&movups	($inout2,&QWP(0x20,$inp));
-+	&cmp	($len,0x40);
-+	&jb	(&label("ecb_dec_three"));
-+	&movups	($inout3,&QWP(0x30,$inp));
-+	&je	(&label("ecb_dec_four"));
-+	&movups	($inout4,&QWP(0x40,$inp));
-+	&xorps	($inout5,$inout5);
-+	&call	("_aesni_decrypt6");
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&movups	(&QWP(0x40,$out),$inout4);
-+	&jmp	(&label("ecb_ret"));
-+
-+&set_label("ecb_dec_one",16);
-+	if ($inline)
-+	{   &aesni_inline_generate1("dec");	}
-+	else
-+	{   &call	("_aesni_decrypt1");	}
-+	&movups	(&QWP(0,$out),$inout0);
-+	&jmp	(&label("ecb_ret"));
-+
-+&set_label("ecb_dec_two",16);
-+	&call	("_aesni_decrypt2");
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&jmp	(&label("ecb_ret"));
-+
-+&set_label("ecb_dec_three",16);
-+	&call	("_aesni_decrypt3");
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&jmp	(&label("ecb_ret"));
-+
-+&set_label("ecb_dec_four",16);
-+	&call	("_aesni_decrypt4");
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&movups	(&QWP(0x30,$out),$inout3);
-+
-+&set_label("ecb_ret");
-+	&pxor	("xmm0","xmm0");		# clear register bank
-+	&pxor	("xmm1","xmm1");
-+	&pxor	("xmm2","xmm2");
-+	&pxor	("xmm3","xmm3");
-+	&pxor	("xmm4","xmm4");
-+	&pxor	("xmm5","xmm5");
-+	&pxor	("xmm6","xmm6");
-+	&pxor	("xmm7","xmm7");
-+&function_end("aesni_ecb_encrypt");
-+
-+######################################################################
-+# void aesni_ccm64_[en|de]crypt_blocks (const void *in, void *out,
-+#                         size_t blocks, const AES_KEY *key,
-+#                         const char *ivec,char *cmac);
-+#
-+# Handles only complete blocks, operates on 64-bit counter and
-+# does not update *ivec! Nor does it finalize CMAC value
-+# (see engine/eng_aesni.c for details)
-+#
-+{ my $cmac=$inout1;
-+&function_begin("aesni_ccm64_encrypt_blocks");
-+	&mov	($inp,&wparam(0));
-+	&mov	($out,&wparam(1));
-+	&mov	($len,&wparam(2));
-+	&mov	($key,&wparam(3));
-+	&mov	($rounds_,&wparam(4));
-+	&mov	($rounds,&wparam(5));
-+	&mov	($key_,"esp");
-+	&sub	("esp",60);
-+	&and	("esp",-16);			# align stack
-+	&mov	(&DWP(48,"esp"),$key_);
-+
-+	&movdqu	($ivec,&QWP(0,$rounds_));	# load ivec
-+	&movdqu	($cmac,&QWP(0,$rounds));	# load cmac
-+	&mov	($rounds,&DWP(240,$key));
-+
-+	# compose byte-swap control mask for pshufb on stack
-+	&mov	(&DWP(0,"esp"),0x0c0d0e0f);
-+	&mov	(&DWP(4,"esp"),0x08090a0b);
-+	&mov	(&DWP(8,"esp"),0x04050607);
-+	&mov	(&DWP(12,"esp"),0x00010203);
-+
-+	# compose counter increment vector on stack
-+	&mov	($rounds_,1);
-+	&xor	($key_,$key_);
-+	&mov	(&DWP(16,"esp"),$rounds_);
-+	&mov	(&DWP(20,"esp"),$key_);
-+	&mov	(&DWP(24,"esp"),$key_);
-+	&mov	(&DWP(28,"esp"),$key_);
-+
-+	&shl	($rounds,4);
-+	&mov	($rounds_,16);
-+	&lea	($key_,&DWP(0,$key));
-+	&movdqa	($inout3,&QWP(0,"esp"));
-+	&movdqa	($inout0,$ivec);
-+	&lea	($key,&DWP(32,$key,$rounds));
-+	&sub	($rounds_,$rounds);
-+	&pshufb	($ivec,$inout3);
-+
-+&set_label("ccm64_enc_outer");
-+	&$movekey	($rndkey0,&QWP(0,$key_));
-+	&mov		($rounds,$rounds_);
-+	&movups		($in0,&QWP(0,$inp));
-+
-+	&xorps		($inout0,$rndkey0);
-+	&$movekey	($rndkey1,&QWP(16,$key_));
-+	&xorps		($rndkey0,$in0);
-+	&xorps		($cmac,$rndkey0);		# cmac^=inp
-+	&$movekey	($rndkey0,&QWP(32,$key_));
-+
-+&set_label("ccm64_enc2_loop");
-+	&aesenc		($inout0,$rndkey1);
-+	&aesenc		($cmac,$rndkey1);
-+	&$movekey	($rndkey1,&QWP(0,$key,$rounds));
-+	&add		($rounds,32);
-+	&aesenc		($inout0,$rndkey0);
-+	&aesenc		($cmac,$rndkey0);
-+	&$movekey	($rndkey0,&QWP(-16,$key,$rounds));
-+	&jnz		(&label("ccm64_enc2_loop"));
-+	&aesenc		($inout0,$rndkey1);
-+	&aesenc		($cmac,$rndkey1);
-+	&paddq		($ivec,&QWP(16,"esp"));
-+	&dec		($len);
-+	&aesenclast	($inout0,$rndkey0);
-+	&aesenclast	($cmac,$rndkey0);
-+
-+	&lea	($inp,&DWP(16,$inp));
-+	&xorps	($in0,$inout0);			# inp^=E(ivec)
-+	&movdqa	($inout0,$ivec);
-+	&movups	(&QWP(0,$out),$in0);		# save output
-+	&pshufb	($inout0,$inout3);
-+	&lea	($out,&DWP(16,$out));
-+	&jnz	(&label("ccm64_enc_outer"));
-+
-+	&mov	("esp",&DWP(48,"esp"));
-+	&mov	($out,&wparam(5));
-+	&movups	(&QWP(0,$out),$cmac);
-+
-+	&pxor	("xmm0","xmm0");		# clear register bank
-+	&pxor	("xmm1","xmm1");
-+	&pxor	("xmm2","xmm2");
-+	&pxor	("xmm3","xmm3");
-+	&pxor	("xmm4","xmm4");
-+	&pxor	("xmm5","xmm5");
-+	&pxor	("xmm6","xmm6");
-+	&pxor	("xmm7","xmm7");
-+&function_end("aesni_ccm64_encrypt_blocks");
-+
-+&function_begin("aesni_ccm64_decrypt_blocks");
-+	&mov	($inp,&wparam(0));
-+	&mov	($out,&wparam(1));
-+	&mov	($len,&wparam(2));
-+	&mov	($key,&wparam(3));
-+	&mov	($rounds_,&wparam(4));
-+	&mov	($rounds,&wparam(5));
-+	&mov	($key_,"esp");
-+	&sub	("esp",60);
-+	&and	("esp",-16);			# align stack
-+	&mov	(&DWP(48,"esp"),$key_);
-+
-+	&movdqu	($ivec,&QWP(0,$rounds_));	# load ivec
-+	&movdqu	($cmac,&QWP(0,$rounds));	# load cmac
-+	&mov	($rounds,&DWP(240,$key));
-+
-+	# compose byte-swap control mask for pshufb on stack
-+	&mov	(&DWP(0,"esp"),0x0c0d0e0f);
-+	&mov	(&DWP(4,"esp"),0x08090a0b);
-+	&mov	(&DWP(8,"esp"),0x04050607);
-+	&mov	(&DWP(12,"esp"),0x00010203);
-+
-+	# compose counter increment vector on stack
-+	&mov	($rounds_,1);
-+	&xor	($key_,$key_);
-+	&mov	(&DWP(16,"esp"),$rounds_);
-+	&mov	(&DWP(20,"esp"),$key_);
-+	&mov	(&DWP(24,"esp"),$key_);
-+	&mov	(&DWP(28,"esp"),$key_);
-+
-+	&movdqa	($inout3,&QWP(0,"esp"));	# bswap mask
-+	&movdqa	($inout0,$ivec);
-+
-+	&mov	($key_,$key);
-+	&mov	($rounds_,$rounds);
-+
-+	&pshufb	($ivec,$inout3);
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc");	}
-+	else
-+	{   &call	("_aesni_encrypt1");	}
-+	&shl	($rounds_,4);
-+	&mov	($rounds,16);
-+	&movups	($in0,&QWP(0,$inp));		# load inp
-+	&paddq	($ivec,&QWP(16,"esp"));
-+	&lea	($inp,&QWP(16,$inp));
-+	&sub	($rounds,$rounds_);
-+	&lea	($key,&DWP(32,$key_,$rounds_));
-+	&mov	($rounds_,$rounds);
-+	&jmp	(&label("ccm64_dec_outer"));
-+
-+&set_label("ccm64_dec_outer",16);
-+	&xorps	($in0,$inout0);			# inp ^= E(ivec)
-+	&movdqa	($inout0,$ivec);
-+	&movups	(&QWP(0,$out),$in0);		# save output
-+	&lea	($out,&DWP(16,$out));
-+	&pshufb	($inout0,$inout3);
-+
-+	&sub	($len,1);
-+	&jz	(&label("ccm64_dec_break"));
-+
-+	&$movekey	($rndkey0,&QWP(0,$key_));
-+	&mov		($rounds,$rounds_);
-+	&$movekey	($rndkey1,&QWP(16,$key_));
-+	&xorps		($in0,$rndkey0);
-+	&xorps		($inout0,$rndkey0);
-+	&xorps		($cmac,$in0);		# cmac^=out
-+	&$movekey	($rndkey0,&QWP(32,$key_));
-+
-+&set_label("ccm64_dec2_loop");
-+	&aesenc		($inout0,$rndkey1);
-+	&aesenc		($cmac,$rndkey1);
-+	&$movekey	($rndkey1,&QWP(0,$key,$rounds));
-+	&add		($rounds,32);
-+	&aesenc		($inout0,$rndkey0);
-+	&aesenc		($cmac,$rndkey0);
-+	&$movekey	($rndkey0,&QWP(-16,$key,$rounds));
-+	&jnz		(&label("ccm64_dec2_loop"));
-+	&movups		($in0,&QWP(0,$inp));	# load inp
-+	&paddq		($ivec,&QWP(16,"esp"));
-+	&aesenc		($inout0,$rndkey1);
-+	&aesenc		($cmac,$rndkey1);
-+	&aesenclast	($inout0,$rndkey0);
-+	&aesenclast	($cmac,$rndkey0);
-+	&lea		($inp,&QWP(16,$inp));
-+	&jmp	(&label("ccm64_dec_outer"));
-+
-+&set_label("ccm64_dec_break",16);
-+	&mov	($rounds,&DWP(240,$key_));
-+	&mov	($key,$key_);
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc",$cmac,$in0);	}
-+	else
-+	{   &call	("_aesni_encrypt1",$cmac);	}
-+
-+	&mov	("esp",&DWP(48,"esp"));
-+	&mov	($out,&wparam(5));
-+	&movups	(&QWP(0,$out),$cmac);
-+
-+	&pxor	("xmm0","xmm0");		# clear register bank
-+	&pxor	("xmm1","xmm1");
-+	&pxor	("xmm2","xmm2");
-+	&pxor	("xmm3","xmm3");
-+	&pxor	("xmm4","xmm4");
-+	&pxor	("xmm5","xmm5");
-+	&pxor	("xmm6","xmm6");
-+	&pxor	("xmm7","xmm7");
-+&function_end("aesni_ccm64_decrypt_blocks");
-+}
-+
-+######################################################################
-+# void aesni_ctr32_encrypt_blocks (const void *in, void *out,
-+#                         size_t blocks, const AES_KEY *key,
-+#                         const char *ivec);
-+#
-+# Handles only complete blocks, operates on 32-bit counter and
-+# does not update *ivec! (see crypto/modes/ctr128.c for details)
-+#
-+# stack layout:
-+#	0	pshufb mask
-+#	16	vector addend: 0,6,6,6
-+# 	32	counter-less ivec
-+#	48	1st triplet of counter vector
-+#	64	2nd triplet of counter vector
-+#	80	saved %esp
-+
-+&function_begin("aesni_ctr32_encrypt_blocks");
-+	&mov	($inp,&wparam(0));
-+	&mov	($out,&wparam(1));
-+	&mov	($len,&wparam(2));
-+	&mov	($key,&wparam(3));
-+	&mov	($rounds_,&wparam(4));
-+	&mov	($key_,"esp");
-+	&sub	("esp",88);
-+	&and	("esp",-16);			# align stack
-+	&mov	(&DWP(80,"esp"),$key_);
-+
-+	&cmp	($len,1);
-+	&je	(&label("ctr32_one_shortcut"));
-+
-+	&movdqu	($inout5,&QWP(0,$rounds_));	# load ivec
-+
-+	# compose byte-swap control mask for pshufb on stack
-+	&mov	(&DWP(0,"esp"),0x0c0d0e0f);
-+	&mov	(&DWP(4,"esp"),0x08090a0b);
-+	&mov	(&DWP(8,"esp"),0x04050607);
-+	&mov	(&DWP(12,"esp"),0x00010203);
-+
-+	# compose counter increment vector on stack
-+	&mov	($rounds,6);
-+	&xor	($key_,$key_);
-+	&mov	(&DWP(16,"esp"),$rounds);
-+	&mov	(&DWP(20,"esp"),$rounds);
-+	&mov	(&DWP(24,"esp"),$rounds);
-+	&mov	(&DWP(28,"esp"),$key_);
-+
-+	&pextrd	($rounds_,$inout5,3);		# pull 32-bit counter
-+	&pinsrd	($inout5,$key_,3);		# wipe 32-bit counter
-+
-+	&mov	($rounds,&DWP(240,$key));	# key->rounds
-+
-+	# compose 2 vectors of 3x32-bit counters
-+	&bswap	($rounds_);
-+	&pxor	($rndkey0,$rndkey0);
-+	&pxor	($rndkey1,$rndkey1);
-+	&movdqa	($inout0,&QWP(0,"esp"));	# load byte-swap mask
-+	&pinsrd	($rndkey0,$rounds_,0);
-+	&lea	($key_,&DWP(3,$rounds_));
-+	&pinsrd	($rndkey1,$key_,0);
-+	&inc	($rounds_);
-+	&pinsrd	($rndkey0,$rounds_,1);
-+	&inc	($key_);
-+	&pinsrd	($rndkey1,$key_,1);
-+	&inc	($rounds_);
-+	&pinsrd	($rndkey0,$rounds_,2);
-+	&inc	($key_);
-+	&pinsrd	($rndkey1,$key_,2);
-+	&movdqa	(&QWP(48,"esp"),$rndkey0);	# save 1st triplet
-+	&pshufb	($rndkey0,$inout0);		# byte swap
-+	&movdqu	($inout4,&QWP(0,$key));		# key[0]
-+	&movdqa	(&QWP(64,"esp"),$rndkey1);	# save 2nd triplet
-+	&pshufb	($rndkey1,$inout0);		# byte swap
-+
-+	&pshufd	($inout0,$rndkey0,3<<6);	# place counter to upper dword
-+	&pshufd	($inout1,$rndkey0,2<<6);
-+	&cmp	($len,6);
-+	&jb	(&label("ctr32_tail"));
-+	&pxor	($inout5,$inout4);		# counter-less ivec^key[0]
-+	&shl	($rounds,4);
-+	&mov	($rounds_,16);
-+	&movdqa	(&QWP(32,"esp"),$inout5);	# save counter-less ivec^key[0]
-+	&mov	($key_,$key);			# backup $key
-+	&sub	($rounds_,$rounds);		# backup twisted $rounds
-+	&lea	($key,&DWP(32,$key,$rounds));
-+	&sub	($len,6);
-+	&jmp	(&label("ctr32_loop6"));
-+
-+&set_label("ctr32_loop6",16);
-+	# inlining _aesni_encrypt6's prologue gives ~6% improvement...
-+	&pshufd	($inout2,$rndkey0,1<<6);
-+	&movdqa	($rndkey0,&QWP(32,"esp"));	# pull counter-less ivec
-+	&pshufd	($inout3,$rndkey1,3<<6);
-+	&pxor		($inout0,$rndkey0);	# merge counter-less ivec
-+	&pshufd	($inout4,$rndkey1,2<<6);
-+	&pxor		($inout1,$rndkey0);
-+	&pshufd	($inout5,$rndkey1,1<<6);
-+	&$movekey	($rndkey1,&QWP(16,$key_));
-+	&pxor		($inout2,$rndkey0);
-+	&pxor		($inout3,$rndkey0);
-+	&aesenc		($inout0,$rndkey1);
-+	&pxor		($inout4,$rndkey0);
-+	&pxor		($inout5,$rndkey0);
-+	&aesenc		($inout1,$rndkey1);
-+	&$movekey	($rndkey0,&QWP(32,$key_));
-+	&mov		($rounds,$rounds_);
-+	&aesenc		($inout2,$rndkey1);
-+	&aesenc		($inout3,$rndkey1);
-+	&aesenc		($inout4,$rndkey1);
-+	&aesenc		($inout5,$rndkey1);
-+
-+	&call		(&label("_aesni_encrypt6_enter"));
-+
-+	&movups	($rndkey1,&QWP(0,$inp));
-+	&movups	($rndkey0,&QWP(0x10,$inp));
-+	&xorps	($inout0,$rndkey1);
-+	&movups	($rndkey1,&QWP(0x20,$inp));
-+	&xorps	($inout1,$rndkey0);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movdqa	($rndkey0,&QWP(16,"esp"));	# load increment
-+	&xorps	($inout2,$rndkey1);
-+	&movdqa	($rndkey1,&QWP(64,"esp"));	# load 2nd triplet
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+
-+	&paddd	($rndkey1,$rndkey0);		# 2nd triplet increment
-+	&paddd	($rndkey0,&QWP(48,"esp"));	# 1st triplet increment
-+	&movdqa	($inout0,&QWP(0,"esp"));	# load byte swap mask
-+
-+	&movups	($inout1,&QWP(0x30,$inp));
-+	&movups	($inout2,&QWP(0x40,$inp));
-+	&xorps	($inout3,$inout1);
-+	&movups	($inout1,&QWP(0x50,$inp));
-+	&lea	($inp,&DWP(0x60,$inp));
-+	&movdqa	(&QWP(48,"esp"),$rndkey0);	# save 1st triplet
-+	&pshufb	($rndkey0,$inout0);		# byte swap
-+	&xorps	($inout4,$inout2);
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&xorps	($inout5,$inout1);
-+	&movdqa	(&QWP(64,"esp"),$rndkey1);	# save 2nd triplet
-+	&pshufb	($rndkey1,$inout0);		# byte swap
-+	&movups	(&QWP(0x40,$out),$inout4);
-+	&pshufd	($inout0,$rndkey0,3<<6);
-+	&movups	(&QWP(0x50,$out),$inout5);
-+	&lea	($out,&DWP(0x60,$out));
-+
-+	&pshufd	($inout1,$rndkey0,2<<6);
-+	&sub	($len,6);
-+	&jnc	(&label("ctr32_loop6"));
-+
-+	&add	($len,6);
-+	&jz	(&label("ctr32_ret"));
-+	&movdqu	($inout5,&QWP(0,$key_));
-+	&mov	($key,$key_);
-+	&pxor	($inout5,&QWP(32,"esp"));	# restore count-less ivec
-+	&mov	($rounds,&DWP(240,$key_));	# restore $rounds
-+
-+&set_label("ctr32_tail");
-+	&por	($inout0,$inout5);
-+	&cmp	($len,2);
-+	&jb	(&label("ctr32_one"));
-+
-+	&pshufd	($inout2,$rndkey0,1<<6);
-+	&por	($inout1,$inout5);
-+	&je	(&label("ctr32_two"));
-+
-+	&pshufd	($inout3,$rndkey1,3<<6);
-+	&por	($inout2,$inout5);
-+	&cmp	($len,4);
-+	&jb	(&label("ctr32_three"));
-+
-+	&pshufd	($inout4,$rndkey1,2<<6);
-+	&por	($inout3,$inout5);
-+	&je	(&label("ctr32_four"));
-+
-+	&por	($inout4,$inout5);
-+	&call	("_aesni_encrypt6");
-+	&movups	($rndkey1,&QWP(0,$inp));
-+	&movups	($rndkey0,&QWP(0x10,$inp));
-+	&xorps	($inout0,$rndkey1);
-+	&movups	($rndkey1,&QWP(0x20,$inp));
-+	&xorps	($inout1,$rndkey0);
-+	&movups	($rndkey0,&QWP(0x30,$inp));
-+	&xorps	($inout2,$rndkey1);
-+	&movups	($rndkey1,&QWP(0x40,$inp));
-+	&xorps	($inout3,$rndkey0);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&xorps	($inout4,$rndkey1);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&movups	(&QWP(0x40,$out),$inout4);
-+	&jmp	(&label("ctr32_ret"));
-+
-+&set_label("ctr32_one_shortcut",16);
-+	&movups	($inout0,&QWP(0,$rounds_));	# load ivec
-+	&mov	($rounds,&DWP(240,$key));
-+	
-+&set_label("ctr32_one");
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc");	}
-+	else
-+	{   &call	("_aesni_encrypt1");	}
-+	&movups	($in0,&QWP(0,$inp));
-+	&xorps	($in0,$inout0);
-+	&movups	(&QWP(0,$out),$in0);
-+	&jmp	(&label("ctr32_ret"));
-+
-+&set_label("ctr32_two",16);
-+	&call	("_aesni_encrypt2");
-+	&movups	($inout3,&QWP(0,$inp));
-+	&movups	($inout4,&QWP(0x10,$inp));
-+	&xorps	($inout0,$inout3);
-+	&xorps	($inout1,$inout4);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&jmp	(&label("ctr32_ret"));
-+
-+&set_label("ctr32_three",16);
-+	&call	("_aesni_encrypt3");
-+	&movups	($inout3,&QWP(0,$inp));
-+	&movups	($inout4,&QWP(0x10,$inp));
-+	&xorps	($inout0,$inout3);
-+	&movups	($inout5,&QWP(0x20,$inp));
-+	&xorps	($inout1,$inout4);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&xorps	($inout2,$inout5);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&jmp	(&label("ctr32_ret"));
-+
-+&set_label("ctr32_four",16);
-+	&call	("_aesni_encrypt4");
-+	&movups	($inout4,&QWP(0,$inp));
-+	&movups	($inout5,&QWP(0x10,$inp));
-+	&movups	($rndkey1,&QWP(0x20,$inp));
-+	&xorps	($inout0,$inout4);
-+	&movups	($rndkey0,&QWP(0x30,$inp));
-+	&xorps	($inout1,$inout5);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&xorps	($inout2,$rndkey1);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&xorps	($inout3,$rndkey0);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&movups	(&QWP(0x30,$out),$inout3);
-+
-+&set_label("ctr32_ret");
-+	&pxor	("xmm0","xmm0");		# clear register bank
-+	&pxor	("xmm1","xmm1");
-+	&pxor	("xmm2","xmm2");
-+	&pxor	("xmm3","xmm3");
-+	&pxor	("xmm4","xmm4");
-+	&movdqa	(&QWP(32,"esp"),"xmm0");	# clear stack
-+	&pxor	("xmm5","xmm5");
-+	&movdqa	(&QWP(48,"esp"),"xmm0");
-+	&pxor	("xmm6","xmm6");
-+	&movdqa	(&QWP(64,"esp"),"xmm0");
-+	&pxor	("xmm7","xmm7");
-+	&mov	("esp",&DWP(80,"esp"));
-+&function_end("aesni_ctr32_encrypt_blocks");
-+
-+######################################################################
-+# void aesni_xts_[en|de]crypt(const char *inp,char *out,size_t len,
-+#	const AES_KEY *key1, const AES_KEY *key2
-+#	const unsigned char iv[16]);
-+#
-+{ my ($tweak,$twtmp,$twres,$twmask)=($rndkey1,$rndkey0,$inout0,$inout1);
-+
-+&function_begin("aesni_xts_encrypt");
-+	&mov	($key,&wparam(4));		# key2
-+	&mov	($inp,&wparam(5));		# clear-text tweak
-+
-+	&mov	($rounds,&DWP(240,$key));	# key2->rounds
-+	&movups	($inout0,&QWP(0,$inp));
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc");	}
-+	else
-+	{   &call	("_aesni_encrypt1");	}
-+
-+	&mov	($inp,&wparam(0));
-+	&mov	($out,&wparam(1));
-+	&mov	($len,&wparam(2));
-+	&mov	($key,&wparam(3));		# key1
-+
-+	&mov	($key_,"esp");
-+	&sub	("esp",16*7+8);
-+	&mov	($rounds,&DWP(240,$key));	# key1->rounds
-+	&and	("esp",-16);			# align stack
-+
-+	&mov	(&DWP(16*6+0,"esp"),0x87);	# compose the magic constant
-+	&mov	(&DWP(16*6+4,"esp"),0);
-+	&mov	(&DWP(16*6+8,"esp"),1);
-+	&mov	(&DWP(16*6+12,"esp"),0);
-+	&mov	(&DWP(16*7+0,"esp"),$len);	# save original $len
-+	&mov	(&DWP(16*7+4,"esp"),$key_);	# save original %esp
-+
-+	&movdqa	($tweak,$inout0);
-+	&pxor	($twtmp,$twtmp);
-+	&movdqa	($twmask,&QWP(6*16,"esp"));	# 0x0...010...87
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+
-+	&and	($len,-16);
-+	&mov	($key_,$key);			# backup $key
-+	&mov	($rounds_,$rounds);		# backup $rounds
-+	&sub	($len,16*6);
-+	&jc	(&label("xts_enc_short"));
-+
-+	&shl	($rounds,4);
-+	&mov	($rounds_,16);
-+	&sub	($rounds_,$rounds);
-+	&lea	($key,&DWP(32,$key,$rounds));
-+	&jmp	(&label("xts_enc_loop6"));
-+
-+&set_label("xts_enc_loop6",16);
-+	for ($i=0;$i<4;$i++) {
-+	    &pshufd	($twres,$twtmp,0x13);
-+	    &pxor	($twtmp,$twtmp);
-+	    &movdqa	(&QWP(16*$i,"esp"),$tweak);
-+	    &paddq	($tweak,$tweak);	# &psllq($tweak,1);
-+	    &pand	($twres,$twmask);	# isolate carry and residue
-+	    &pcmpgtd	($twtmp,$tweak);	# broadcast upper bits
-+	    &pxor	($tweak,$twres);
-+	}
-+	&pshufd	($inout5,$twtmp,0x13);
-+	&movdqa	(&QWP(16*$i++,"esp"),$tweak);
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	 &$movekey	($rndkey0,&QWP(0,$key_));
-+	&pand	($inout5,$twmask);		# isolate carry and residue
-+	 &movups	($inout0,&QWP(0,$inp));	# load input
-+	&pxor	($inout5,$tweak);
-+
-+	# inline _aesni_encrypt6 prologue and flip xor with tweak and key[0]
-+	&mov	($rounds,$rounds_);		# restore $rounds
-+	&movdqu	($inout1,&QWP(16*1,$inp));
-+	 &xorps		($inout0,$rndkey0);	# input^=rndkey[0]
-+	&movdqu	($inout2,&QWP(16*2,$inp));
-+	 &pxor		($inout1,$rndkey0);
-+	&movdqu	($inout3,&QWP(16*3,$inp));
-+	 &pxor		($inout2,$rndkey0);
-+	&movdqu	($inout4,&QWP(16*4,$inp));
-+	 &pxor		($inout3,$rndkey0);
-+	&movdqu	($rndkey1,&QWP(16*5,$inp));
-+	 &pxor		($inout4,$rndkey0);
-+	&lea	($inp,&DWP(16*6,$inp));
-+	&pxor	($inout0,&QWP(16*0,"esp"));	# input^=tweak
-+	&movdqa	(&QWP(16*$i,"esp"),$inout5);	# save last tweak
-+	&pxor	($inout5,$rndkey1);
-+
-+	 &$movekey	($rndkey1,&QWP(16,$key_));
-+	&pxor	($inout1,&QWP(16*1,"esp"));
-+	&pxor	($inout2,&QWP(16*2,"esp"));
-+	 &aesenc	($inout0,$rndkey1);
-+	&pxor	($inout3,&QWP(16*3,"esp"));
-+	&pxor	($inout4,&QWP(16*4,"esp"));
-+	 &aesenc	($inout1,$rndkey1);
-+	&pxor		($inout5,$rndkey0);
-+	 &$movekey	($rndkey0,&QWP(32,$key_));
-+	 &aesenc	($inout2,$rndkey1);
-+	 &aesenc	($inout3,$rndkey1);
-+	 &aesenc	($inout4,$rndkey1);
-+	 &aesenc	($inout5,$rndkey1);
-+	&call		(&label("_aesni_encrypt6_enter"));
-+
-+	&movdqa	($tweak,&QWP(16*5,"esp"));	# last tweak
-+       &pxor	($twtmp,$twtmp);
-+	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
-+       &pcmpgtd	($twtmp,$tweak);		# broadcast upper bits
-+	&xorps	($inout1,&QWP(16*1,"esp"));
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&xorps	($inout2,&QWP(16*2,"esp"));
-+	&movups	(&QWP(16*1,$out),$inout1);
-+	&xorps	($inout3,&QWP(16*3,"esp"));
-+	&movups	(&QWP(16*2,$out),$inout2);
-+	&xorps	($inout4,&QWP(16*4,"esp"));
-+	&movups	(&QWP(16*3,$out),$inout3);
-+	&xorps	($inout5,$tweak);
-+	&movups	(&QWP(16*4,$out),$inout4);
-+       &pshufd	($twres,$twtmp,0x13);
-+	&movups	(&QWP(16*5,$out),$inout5);
-+	&lea	($out,&DWP(16*6,$out));
-+       &movdqa	($twmask,&QWP(16*6,"esp"));	# 0x0...010...87
-+
-+	&pxor	($twtmp,$twtmp);
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($twres,$twmask);		# isolate carry and residue
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&pxor	($tweak,$twres);
-+
-+	&sub	($len,16*6);
-+	&jnc	(&label("xts_enc_loop6"));
-+
-+	&mov	($rounds,&DWP(240,$key_));	# restore $rounds
-+	&mov	($key,$key_);			# restore $key
-+	&mov	($rounds_,$rounds);
-+
-+&set_label("xts_enc_short");
-+	&add	($len,16*6);
-+	&jz	(&label("xts_enc_done6x"));
-+
-+	&movdqa	($inout3,$tweak);		# put aside previous tweak
-+	&cmp	($len,0x20);
-+	&jb	(&label("xts_enc_one"));
-+
-+	&pshufd	($twres,$twtmp,0x13);
-+	&pxor	($twtmp,$twtmp);
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($twres,$twmask);		# isolate carry and residue
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&pxor	($tweak,$twres);
-+	&je	(&label("xts_enc_two"));
-+
-+	&pshufd	($twres,$twtmp,0x13);
-+	&pxor	($twtmp,$twtmp);
-+	&movdqa	($inout4,$tweak);		# put aside previous tweak
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($twres,$twmask);		# isolate carry and residue
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&pxor	($tweak,$twres);
-+	&cmp	($len,0x40);
-+	&jb	(&label("xts_enc_three"));
-+
-+	&pshufd	($twres,$twtmp,0x13);
-+	&pxor	($twtmp,$twtmp);
-+	&movdqa	($inout5,$tweak);		# put aside previous tweak
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($twres,$twmask);		# isolate carry and residue
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&pxor	($tweak,$twres);
-+	&movdqa	(&QWP(16*0,"esp"),$inout3);
-+	&movdqa	(&QWP(16*1,"esp"),$inout4);
-+	&je	(&label("xts_enc_four"));
-+
-+	&movdqa	(&QWP(16*2,"esp"),$inout5);
-+	&pshufd	($inout5,$twtmp,0x13);
-+	&movdqa	(&QWP(16*3,"esp"),$tweak);
-+	&paddq	($tweak,$tweak);		# &psllq($inout0,1);
-+	&pand	($inout5,$twmask);		# isolate carry and residue
-+	&pxor	($inout5,$tweak);
-+
-+	&movdqu	($inout0,&QWP(16*0,$inp));	# load input
-+	&movdqu	($inout1,&QWP(16*1,$inp));
-+	&movdqu	($inout2,&QWP(16*2,$inp));
-+	&pxor	($inout0,&QWP(16*0,"esp"));	# input^=tweak
-+	&movdqu	($inout3,&QWP(16*3,$inp));
-+	&pxor	($inout1,&QWP(16*1,"esp"));
-+	&movdqu	($inout4,&QWP(16*4,$inp));
-+	&pxor	($inout2,&QWP(16*2,"esp"));
-+	&lea	($inp,&DWP(16*5,$inp));
-+	&pxor	($inout3,&QWP(16*3,"esp"));
-+	&movdqa	(&QWP(16*4,"esp"),$inout5);	# save last tweak
-+	&pxor	($inout4,$inout5);
-+
-+	&call	("_aesni_encrypt6");
-+
-+	&movaps	($tweak,&QWP(16*4,"esp"));	# last tweak
-+	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
-+	&xorps	($inout1,&QWP(16*1,"esp"));
-+	&xorps	($inout2,&QWP(16*2,"esp"));
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&xorps	($inout3,&QWP(16*3,"esp"));
-+	&movups	(&QWP(16*1,$out),$inout1);
-+	&xorps	($inout4,$tweak);
-+	&movups	(&QWP(16*2,$out),$inout2);
-+	&movups	(&QWP(16*3,$out),$inout3);
-+	&movups	(&QWP(16*4,$out),$inout4);
-+	&lea	($out,&DWP(16*5,$out));
-+	&jmp	(&label("xts_enc_done"));
-+
-+&set_label("xts_enc_one",16);
-+	&movups	($inout0,&QWP(16*0,$inp));	# load input
-+	&lea	($inp,&DWP(16*1,$inp));
-+	&xorps	($inout0,$inout3);		# input^=tweak
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc");	}
-+	else
-+	{   &call	("_aesni_encrypt1");	}
-+	&xorps	($inout0,$inout3);		# output^=tweak
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&lea	($out,&DWP(16*1,$out));
-+
-+	&movdqa	($tweak,$inout3);		# last tweak
-+	&jmp	(&label("xts_enc_done"));
-+
-+&set_label("xts_enc_two",16);
-+	&movaps	($inout4,$tweak);		# put aside last tweak
-+
-+	&movups	($inout0,&QWP(16*0,$inp));	# load input
-+	&movups	($inout1,&QWP(16*1,$inp));
-+	&lea	($inp,&DWP(16*2,$inp));
-+	&xorps	($inout0,$inout3);		# input^=tweak
-+	&xorps	($inout1,$inout4);
-+
-+	&call	("_aesni_encrypt2");
-+
-+	&xorps	($inout0,$inout3);		# output^=tweak
-+	&xorps	($inout1,$inout4);
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&movups	(&QWP(16*1,$out),$inout1);
-+	&lea	($out,&DWP(16*2,$out));
-+
-+	&movdqa	($tweak,$inout4);		# last tweak
-+	&jmp	(&label("xts_enc_done"));
-+
-+&set_label("xts_enc_three",16);
-+	&movaps	($inout5,$tweak);		# put aside last tweak
-+	&movups	($inout0,&QWP(16*0,$inp));	# load input
-+	&movups	($inout1,&QWP(16*1,$inp));
-+	&movups	($inout2,&QWP(16*2,$inp));
-+	&lea	($inp,&DWP(16*3,$inp));
-+	&xorps	($inout0,$inout3);		# input^=tweak
-+	&xorps	($inout1,$inout4);
-+	&xorps	($inout2,$inout5);
-+
-+	&call	("_aesni_encrypt3");
-+
-+	&xorps	($inout0,$inout3);		# output^=tweak
-+	&xorps	($inout1,$inout4);
-+	&xorps	($inout2,$inout5);
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&movups	(&QWP(16*1,$out),$inout1);
-+	&movups	(&QWP(16*2,$out),$inout2);
-+	&lea	($out,&DWP(16*3,$out));
-+
-+	&movdqa	($tweak,$inout5);		# last tweak
-+	&jmp	(&label("xts_enc_done"));
-+
-+&set_label("xts_enc_four",16);
-+	&movaps	($inout4,$tweak);		# put aside last tweak
-+
-+	&movups	($inout0,&QWP(16*0,$inp));	# load input
-+	&movups	($inout1,&QWP(16*1,$inp));
-+	&movups	($inout2,&QWP(16*2,$inp));
-+	&xorps	($inout0,&QWP(16*0,"esp"));	# input^=tweak
-+	&movups	($inout3,&QWP(16*3,$inp));
-+	&lea	($inp,&DWP(16*4,$inp));
-+	&xorps	($inout1,&QWP(16*1,"esp"));
-+	&xorps	($inout2,$inout5);
-+	&xorps	($inout3,$inout4);
-+
-+	&call	("_aesni_encrypt4");
-+
-+	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
-+	&xorps	($inout1,&QWP(16*1,"esp"));
-+	&xorps	($inout2,$inout5);
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&xorps	($inout3,$inout4);
-+	&movups	(&QWP(16*1,$out),$inout1);
-+	&movups	(&QWP(16*2,$out),$inout2);
-+	&movups	(&QWP(16*3,$out),$inout3);
-+	&lea	($out,&DWP(16*4,$out));
-+
-+	&movdqa	($tweak,$inout4);		# last tweak
-+	&jmp	(&label("xts_enc_done"));
-+
-+&set_label("xts_enc_done6x",16);		# $tweak is pre-calculated
-+	&mov	($len,&DWP(16*7+0,"esp"));	# restore original $len
-+	&and	($len,15);
-+	&jz	(&label("xts_enc_ret"));
-+	&movdqa	($inout3,$tweak);
-+	&mov	(&DWP(16*7+0,"esp"),$len);	# save $len%16
-+	&jmp	(&label("xts_enc_steal"));
-+
-+&set_label("xts_enc_done",16);
-+	&mov	($len,&DWP(16*7+0,"esp"));	# restore original $len
-+	&pxor	($twtmp,$twtmp);
-+	&and	($len,15);
-+	&jz	(&label("xts_enc_ret"));
-+
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&mov	(&DWP(16*7+0,"esp"),$len);	# save $len%16
-+	&pshufd	($inout3,$twtmp,0x13);
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($inout3,&QWP(16*6,"esp"));	# isolate carry and residue
-+	&pxor	($inout3,$tweak);
-+
-+&set_label("xts_enc_steal");
-+	&movz	($rounds,&BP(0,$inp));
-+	&movz	($key,&BP(-16,$out));
-+	&lea	($inp,&DWP(1,$inp));
-+	&mov	(&BP(-16,$out),&LB($rounds));
-+	&mov	(&BP(0,$out),&LB($key));
-+	&lea	($out,&DWP(1,$out));
-+	&sub	($len,1);
-+	&jnz	(&label("xts_enc_steal"));
-+
-+	&sub	($out,&DWP(16*7+0,"esp"));	# rewind $out
-+	&mov	($key,$key_);			# restore $key
-+	&mov	($rounds,$rounds_);		# restore $rounds
-+
-+	&movups	($inout0,&QWP(-16,$out));	# load input
-+	&xorps	($inout0,$inout3);		# input^=tweak
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc");	}
-+	else
-+	{   &call	("_aesni_encrypt1");	}
-+	&xorps	($inout0,$inout3);		# output^=tweak
-+	&movups	(&QWP(-16,$out),$inout0);	# write output
-+
-+&set_label("xts_enc_ret");
-+	&pxor	("xmm0","xmm0");		# clear register bank
-+	&pxor	("xmm1","xmm1");
-+	&pxor	("xmm2","xmm2");
-+	&movdqa	(&QWP(16*0,"esp"),"xmm0");	# clear stack
-+	&pxor	("xmm3","xmm3");
-+	&movdqa	(&QWP(16*1,"esp"),"xmm0");
-+	&pxor	("xmm4","xmm4");
-+	&movdqa	(&QWP(16*2,"esp"),"xmm0");
-+	&pxor	("xmm5","xmm5");
-+	&movdqa	(&QWP(16*3,"esp"),"xmm0");
-+	&pxor	("xmm6","xmm6");
-+	&movdqa	(&QWP(16*4,"esp"),"xmm0");
-+	&pxor	("xmm7","xmm7");
-+	&movdqa	(&QWP(16*5,"esp"),"xmm0");
-+	&mov	("esp",&DWP(16*7+4,"esp"));	# restore %esp
-+&function_end("aesni_xts_encrypt");
-+
-+&function_begin("aesni_xts_decrypt");
-+	&mov	($key,&wparam(4));		# key2
-+	&mov	($inp,&wparam(5));		# clear-text tweak
-+
-+	&mov	($rounds,&DWP(240,$key));	# key2->rounds
-+	&movups	($inout0,&QWP(0,$inp));
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc");	}
-+	else
-+	{   &call	("_aesni_encrypt1");	}
-+
-+	&mov	($inp,&wparam(0));
-+	&mov	($out,&wparam(1));
-+	&mov	($len,&wparam(2));
-+	&mov	($key,&wparam(3));		# key1
-+
-+	&mov	($key_,"esp");
-+	&sub	("esp",16*7+8);
-+	&and	("esp",-16);			# align stack
-+
-+	&xor	($rounds_,$rounds_);		# if(len%16) len-=16;
-+	&test	($len,15);
-+	&setnz	(&LB($rounds_));
-+	&shl	($rounds_,4);
-+	&sub	($len,$rounds_);
-+
-+	&mov	(&DWP(16*6+0,"esp"),0x87);	# compose the magic constant
-+	&mov	(&DWP(16*6+4,"esp"),0);
-+	&mov	(&DWP(16*6+8,"esp"),1);
-+	&mov	(&DWP(16*6+12,"esp"),0);
-+	&mov	(&DWP(16*7+0,"esp"),$len);	# save original $len
-+	&mov	(&DWP(16*7+4,"esp"),$key_);	# save original %esp
-+
-+	&mov	($rounds,&DWP(240,$key));	# key1->rounds
-+	&mov	($key_,$key);			# backup $key
-+	&mov	($rounds_,$rounds);		# backup $rounds
-+
-+	&movdqa	($tweak,$inout0);
-+	&pxor	($twtmp,$twtmp);
-+	&movdqa	($twmask,&QWP(6*16,"esp"));	# 0x0...010...87
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+
-+	&and	($len,-16);
-+	&sub	($len,16*6);
-+	&jc	(&label("xts_dec_short"));
-+
-+	&shl	($rounds,4);
-+	&mov	($rounds_,16);
-+	&sub	($rounds_,$rounds);
-+	&lea	($key,&DWP(32,$key,$rounds));
-+	&jmp	(&label("xts_dec_loop6"));
-+
-+&set_label("xts_dec_loop6",16);
-+	for ($i=0;$i<4;$i++) {
-+	    &pshufd	($twres,$twtmp,0x13);
-+	    &pxor	($twtmp,$twtmp);
-+	    &movdqa	(&QWP(16*$i,"esp"),$tweak);
-+	    &paddq	($tweak,$tweak);	# &psllq($tweak,1);
-+	    &pand	($twres,$twmask);	# isolate carry and residue
-+	    &pcmpgtd	($twtmp,$tweak);	# broadcast upper bits
-+	    &pxor	($tweak,$twres);
-+	}
-+	&pshufd	($inout5,$twtmp,0x13);
-+	&movdqa	(&QWP(16*$i++,"esp"),$tweak);
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	 &$movekey	($rndkey0,&QWP(0,$key_));
-+	&pand	($inout5,$twmask);		# isolate carry and residue
-+	 &movups	($inout0,&QWP(0,$inp));	# load input
-+	&pxor	($inout5,$tweak);
-+
-+	# inline _aesni_encrypt6 prologue and flip xor with tweak and key[0]
-+	&mov	($rounds,$rounds_);
-+	&movdqu	($inout1,&QWP(16*1,$inp));
-+	 &xorps		($inout0,$rndkey0);	# input^=rndkey[0]
-+	&movdqu	($inout2,&QWP(16*2,$inp));
-+	 &pxor		($inout1,$rndkey0);
-+	&movdqu	($inout3,&QWP(16*3,$inp));
-+	 &pxor		($inout2,$rndkey0);
-+	&movdqu	($inout4,&QWP(16*4,$inp));
-+	 &pxor		($inout3,$rndkey0);
-+	&movdqu	($rndkey1,&QWP(16*5,$inp));
-+	 &pxor		($inout4,$rndkey0);
-+	&lea	($inp,&DWP(16*6,$inp));
-+	&pxor	($inout0,&QWP(16*0,"esp"));	# input^=tweak
-+	&movdqa	(&QWP(16*$i,"esp"),$inout5);	# save last tweak
-+	&pxor	($inout5,$rndkey1);
-+
-+	 &$movekey	($rndkey1,&QWP(16,$key_));
-+	&pxor	($inout1,&QWP(16*1,"esp"));
-+	&pxor	($inout2,&QWP(16*2,"esp"));
-+	 &aesdec	($inout0,$rndkey1);
-+	&pxor	($inout3,&QWP(16*3,"esp"));
-+	&pxor	($inout4,&QWP(16*4,"esp"));
-+	 &aesdec	($inout1,$rndkey1);
-+	&pxor		($inout5,$rndkey0);
-+	 &$movekey	($rndkey0,&QWP(32,$key_));
-+	 &aesdec	($inout2,$rndkey1);
-+	 &aesdec	($inout3,$rndkey1);
-+	 &aesdec	($inout4,$rndkey1);
-+	 &aesdec	($inout5,$rndkey1);
-+	&call		(&label("_aesni_decrypt6_enter"));
-+
-+	&movdqa	($tweak,&QWP(16*5,"esp"));	# last tweak
-+       &pxor	($twtmp,$twtmp);
-+	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
-+       &pcmpgtd	($twtmp,$tweak);		# broadcast upper bits
-+	&xorps	($inout1,&QWP(16*1,"esp"));
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&xorps	($inout2,&QWP(16*2,"esp"));
-+	&movups	(&QWP(16*1,$out),$inout1);
-+	&xorps	($inout3,&QWP(16*3,"esp"));
-+	&movups	(&QWP(16*2,$out),$inout2);
-+	&xorps	($inout4,&QWP(16*4,"esp"));
-+	&movups	(&QWP(16*3,$out),$inout3);
-+	&xorps	($inout5,$tweak);
-+	&movups	(&QWP(16*4,$out),$inout4);
-+       &pshufd	($twres,$twtmp,0x13);
-+	&movups	(&QWP(16*5,$out),$inout5);
-+	&lea	($out,&DWP(16*6,$out));
-+       &movdqa	($twmask,&QWP(16*6,"esp"));	# 0x0...010...87
-+
-+	&pxor	($twtmp,$twtmp);
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($twres,$twmask);		# isolate carry and residue
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&pxor	($tweak,$twres);
-+
-+	&sub	($len,16*6);
-+	&jnc	(&label("xts_dec_loop6"));
-+
-+	&mov	($rounds,&DWP(240,$key_));	# restore $rounds
-+	&mov	($key,$key_);			# restore $key
-+	&mov	($rounds_,$rounds);
-+
-+&set_label("xts_dec_short");
-+	&add	($len,16*6);
-+	&jz	(&label("xts_dec_done6x"));
-+
-+	&movdqa	($inout3,$tweak);		# put aside previous tweak
-+	&cmp	($len,0x20);
-+	&jb	(&label("xts_dec_one"));
-+
-+	&pshufd	($twres,$twtmp,0x13);
-+	&pxor	($twtmp,$twtmp);
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($twres,$twmask);		# isolate carry and residue
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&pxor	($tweak,$twres);
-+	&je	(&label("xts_dec_two"));
-+
-+	&pshufd	($twres,$twtmp,0x13);
-+	&pxor	($twtmp,$twtmp);
-+	&movdqa	($inout4,$tweak);		# put aside previous tweak
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($twres,$twmask);		# isolate carry and residue
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&pxor	($tweak,$twres);
-+	&cmp	($len,0x40);
-+	&jb	(&label("xts_dec_three"));
-+
-+	&pshufd	($twres,$twtmp,0x13);
-+	&pxor	($twtmp,$twtmp);
-+	&movdqa	($inout5,$tweak);		# put aside previous tweak
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($twres,$twmask);		# isolate carry and residue
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&pxor	($tweak,$twres);
-+	&movdqa	(&QWP(16*0,"esp"),$inout3);
-+	&movdqa	(&QWP(16*1,"esp"),$inout4);
-+	&je	(&label("xts_dec_four"));
-+
-+	&movdqa	(&QWP(16*2,"esp"),$inout5);
-+	&pshufd	($inout5,$twtmp,0x13);
-+	&movdqa	(&QWP(16*3,"esp"),$tweak);
-+	&paddq	($tweak,$tweak);		# &psllq($inout0,1);
-+	&pand	($inout5,$twmask);		# isolate carry and residue
-+	&pxor	($inout5,$tweak);
-+
-+	&movdqu	($inout0,&QWP(16*0,$inp));	# load input
-+	&movdqu	($inout1,&QWP(16*1,$inp));
-+	&movdqu	($inout2,&QWP(16*2,$inp));
-+	&pxor	($inout0,&QWP(16*0,"esp"));	# input^=tweak
-+	&movdqu	($inout3,&QWP(16*3,$inp));
-+	&pxor	($inout1,&QWP(16*1,"esp"));
-+	&movdqu	($inout4,&QWP(16*4,$inp));
-+	&pxor	($inout2,&QWP(16*2,"esp"));
-+	&lea	($inp,&DWP(16*5,$inp));
-+	&pxor	($inout3,&QWP(16*3,"esp"));
-+	&movdqa	(&QWP(16*4,"esp"),$inout5);	# save last tweak
-+	&pxor	($inout4,$inout5);
-+
-+	&call	("_aesni_decrypt6");
-+
-+	&movaps	($tweak,&QWP(16*4,"esp"));	# last tweak
-+	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
-+	&xorps	($inout1,&QWP(16*1,"esp"));
-+	&xorps	($inout2,&QWP(16*2,"esp"));
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&xorps	($inout3,&QWP(16*3,"esp"));
-+	&movups	(&QWP(16*1,$out),$inout1);
-+	&xorps	($inout4,$tweak);
-+	&movups	(&QWP(16*2,$out),$inout2);
-+	&movups	(&QWP(16*3,$out),$inout3);
-+	&movups	(&QWP(16*4,$out),$inout4);
-+	&lea	($out,&DWP(16*5,$out));
-+	&jmp	(&label("xts_dec_done"));
-+
-+&set_label("xts_dec_one",16);
-+	&movups	($inout0,&QWP(16*0,$inp));	# load input
-+	&lea	($inp,&DWP(16*1,$inp));
-+	&xorps	($inout0,$inout3);		# input^=tweak
-+	if ($inline)
-+	{   &aesni_inline_generate1("dec");	}
-+	else
-+	{   &call	("_aesni_decrypt1");	}
-+	&xorps	($inout0,$inout3);		# output^=tweak
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&lea	($out,&DWP(16*1,$out));
-+
-+	&movdqa	($tweak,$inout3);		# last tweak
-+	&jmp	(&label("xts_dec_done"));
-+
-+&set_label("xts_dec_two",16);
-+	&movaps	($inout4,$tweak);		# put aside last tweak
-+
-+	&movups	($inout0,&QWP(16*0,$inp));	# load input
-+	&movups	($inout1,&QWP(16*1,$inp));
-+	&lea	($inp,&DWP(16*2,$inp));
-+	&xorps	($inout0,$inout3);		# input^=tweak
-+	&xorps	($inout1,$inout4);
-+
-+	&call	("_aesni_decrypt2");
-+
-+	&xorps	($inout0,$inout3);		# output^=tweak
-+	&xorps	($inout1,$inout4);
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&movups	(&QWP(16*1,$out),$inout1);
-+	&lea	($out,&DWP(16*2,$out));
-+
-+	&movdqa	($tweak,$inout4);		# last tweak
-+	&jmp	(&label("xts_dec_done"));
-+
-+&set_label("xts_dec_three",16);
-+	&movaps	($inout5,$tweak);		# put aside last tweak
-+	&movups	($inout0,&QWP(16*0,$inp));	# load input
-+	&movups	($inout1,&QWP(16*1,$inp));
-+	&movups	($inout2,&QWP(16*2,$inp));
-+	&lea	($inp,&DWP(16*3,$inp));
-+	&xorps	($inout0,$inout3);		# input^=tweak
-+	&xorps	($inout1,$inout4);
-+	&xorps	($inout2,$inout5);
-+
-+	&call	("_aesni_decrypt3");
-+
-+	&xorps	($inout0,$inout3);		# output^=tweak
-+	&xorps	($inout1,$inout4);
-+	&xorps	($inout2,$inout5);
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&movups	(&QWP(16*1,$out),$inout1);
-+	&movups	(&QWP(16*2,$out),$inout2);
-+	&lea	($out,&DWP(16*3,$out));
-+
-+	&movdqa	($tweak,$inout5);		# last tweak
-+	&jmp	(&label("xts_dec_done"));
-+
-+&set_label("xts_dec_four",16);
-+	&movaps	($inout4,$tweak);		# put aside last tweak
-+
-+	&movups	($inout0,&QWP(16*0,$inp));	# load input
-+	&movups	($inout1,&QWP(16*1,$inp));
-+	&movups	($inout2,&QWP(16*2,$inp));
-+	&xorps	($inout0,&QWP(16*0,"esp"));	# input^=tweak
-+	&movups	($inout3,&QWP(16*3,$inp));
-+	&lea	($inp,&DWP(16*4,$inp));
-+	&xorps	($inout1,&QWP(16*1,"esp"));
-+	&xorps	($inout2,$inout5);
-+	&xorps	($inout3,$inout4);
-+
-+	&call	("_aesni_decrypt4");
-+
-+	&xorps	($inout0,&QWP(16*0,"esp"));	# output^=tweak
-+	&xorps	($inout1,&QWP(16*1,"esp"));
-+	&xorps	($inout2,$inout5);
-+	&movups	(&QWP(16*0,$out),$inout0);	# write output
-+	&xorps	($inout3,$inout4);
-+	&movups	(&QWP(16*1,$out),$inout1);
-+	&movups	(&QWP(16*2,$out),$inout2);
-+	&movups	(&QWP(16*3,$out),$inout3);
-+	&lea	($out,&DWP(16*4,$out));
-+
-+	&movdqa	($tweak,$inout4);		# last tweak
-+	&jmp	(&label("xts_dec_done"));
-+
-+&set_label("xts_dec_done6x",16);		# $tweak is pre-calculated
-+	&mov	($len,&DWP(16*7+0,"esp"));	# restore original $len
-+	&and	($len,15);
-+	&jz	(&label("xts_dec_ret"));
-+	&mov	(&DWP(16*7+0,"esp"),$len);	# save $len%16
-+	&jmp	(&label("xts_dec_only_one_more"));
-+
-+&set_label("xts_dec_done",16);
-+	&mov	($len,&DWP(16*7+0,"esp"));	# restore original $len
-+	&pxor	($twtmp,$twtmp);
-+	&and	($len,15);
-+	&jz	(&label("xts_dec_ret"));
-+
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&mov	(&DWP(16*7+0,"esp"),$len);	# save $len%16
-+	&pshufd	($twres,$twtmp,0x13);
-+	&pxor	($twtmp,$twtmp);
-+	&movdqa	($twmask,&QWP(16*6,"esp"));
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($twres,$twmask);		# isolate carry and residue
-+	&pcmpgtd($twtmp,$tweak);		# broadcast upper bits
-+	&pxor	($tweak,$twres);
-+
-+&set_label("xts_dec_only_one_more");
-+	&pshufd	($inout3,$twtmp,0x13);
-+	&movdqa	($inout4,$tweak);		# put aside previous tweak
-+	&paddq	($tweak,$tweak);		# &psllq($tweak,1);
-+	&pand	($inout3,$twmask);		# isolate carry and residue
-+	&pxor	($inout3,$tweak);
-+
-+	&mov	($key,$key_);			# restore $key
-+	&mov	($rounds,$rounds_);		# restore $rounds
-+
-+	&movups	($inout0,&QWP(0,$inp));		# load input
-+	&xorps	($inout0,$inout3);		# input^=tweak
-+	if ($inline)
-+	{   &aesni_inline_generate1("dec");	}
-+	else
-+	{   &call	("_aesni_decrypt1");	}
-+	&xorps	($inout0,$inout3);		# output^=tweak
-+	&movups	(&QWP(0,$out),$inout0);		# write output
-+
-+&set_label("xts_dec_steal");
-+	&movz	($rounds,&BP(16,$inp));
-+	&movz	($key,&BP(0,$out));
-+	&lea	($inp,&DWP(1,$inp));
-+	&mov	(&BP(0,$out),&LB($rounds));
-+	&mov	(&BP(16,$out),&LB($key));
-+	&lea	($out,&DWP(1,$out));
-+	&sub	($len,1);
-+	&jnz	(&label("xts_dec_steal"));
-+
-+	&sub	($out,&DWP(16*7+0,"esp"));	# rewind $out
-+	&mov	($key,$key_);			# restore $key
-+	&mov	($rounds,$rounds_);		# restore $rounds
-+
-+	&movups	($inout0,&QWP(0,$out));		# load input
-+	&xorps	($inout0,$inout4);		# input^=tweak
-+	if ($inline)
-+	{   &aesni_inline_generate1("dec");	}
-+	else
-+	{   &call	("_aesni_decrypt1");	}
-+	&xorps	($inout0,$inout4);		# output^=tweak
-+	&movups	(&QWP(0,$out),$inout0);		# write output
-+
-+&set_label("xts_dec_ret");
-+	&pxor	("xmm0","xmm0");		# clear register bank
-+	&pxor	("xmm1","xmm1");
-+	&pxor	("xmm2","xmm2");
-+	&movdqa	(&QWP(16*0,"esp"),"xmm0");	# clear stack
-+	&pxor	("xmm3","xmm3");
-+	&movdqa	(&QWP(16*1,"esp"),"xmm0");
-+	&pxor	("xmm4","xmm4");
-+	&movdqa	(&QWP(16*2,"esp"),"xmm0");
-+	&pxor	("xmm5","xmm5");
-+	&movdqa	(&QWP(16*3,"esp"),"xmm0");
-+	&pxor	("xmm6","xmm6");
-+	&movdqa	(&QWP(16*4,"esp"),"xmm0");
-+	&pxor	("xmm7","xmm7");
-+	&movdqa	(&QWP(16*5,"esp"),"xmm0");
-+	&mov	("esp",&DWP(16*7+4,"esp"));	# restore %esp
-+&function_end("aesni_xts_decrypt");
-+}
-+
-+######################################################################
-+# void aesni_ocb_[en|de]crypt(const char *inp, char *out, size_t blocks,
-+#	const AES_KEY *key, unsigned int start_block_num,
-+#	unsigned char offset_i[16], const unsigned char L_[][16],
-+#	unsigned char checksum[16]);
-+#
-+{
-+# offsets within stack frame
-+my $checksum = 16*6;
-+my ($key_off,$rounds_off,$out_off,$end_off,$esp_off)=map(16*7+4*$_,(0..4));
-+
-+# reassigned registers
-+my ($l_,$block,$i1,$i3,$i5) = ($rounds_,$key_,$rounds,$len,$out);
-+# $l_, $blocks, $inp, $key are permanently allocated in registers;
-+# remaining non-volatile ones are offloaded to stack, which even
-+# stay invariant after written to stack.
-+
-+&function_begin("aesni_ocb_encrypt");
-+	&mov	($rounds,&wparam(5));		# &offset_i
-+	&mov	($rounds_,&wparam(7));		# &checksum
-+
-+	&mov	($inp,&wparam(0));
-+	&mov	($out,&wparam(1));
-+	&mov	($len,&wparam(2));
-+	&mov	($key,&wparam(3));
-+	&movdqu	($rndkey0,&QWP(0,$rounds));	# load offset_i
-+	&mov	($block,&wparam(4));		# start_block_num
-+	&movdqu	($rndkey1,&QWP(0,$rounds_));	# load checksum
-+	&mov	($l_,&wparam(6));		# L_
-+
-+	&mov	($rounds,"esp");
-+	&sub	("esp",$esp_off+4);		# alloca
-+	&and	("esp",-16);			# align stack
-+
-+	&sub	($out,$inp);
-+	&shl	($len,4);
-+	&lea	($len,&DWP(-16*6,$inp,$len));	# end of input - 16*6
-+	&mov	(&DWP($out_off,"esp"),$out);
-+	&mov	(&DWP($end_off,"esp"),$len);
-+	&mov	(&DWP($esp_off,"esp"),$rounds);
-+
-+	&mov	($rounds,&DWP(240,$key));
-+
-+	&test	($block,1);
-+	&jnz	(&label("odd"));
-+
-+	&bsf		($i3,$block);
-+	&add		($block,1);
-+	&shl		($i3,4);
-+	&movdqu		($inout5,&QWP(0,$l_,$i3));
-+	&mov		($i3,$key);			# put aside key
-+
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&lea		($inp,&DWP(16,$inp));
-+
-+	&pxor		($inout5,$rndkey0);		# ^ last offset_i
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&pxor		($inout0,$inout5);		# ^ offset_i
-+
-+	&movdqa		($inout4,$rndkey1);
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc");	}
-+	else
-+	{   &call	("_aesni_encrypt1");	}
-+
-+	&xorps		($inout0,$inout5);		# ^ offset_i
-+	&movdqa		($rndkey0,$inout5);		# pass last offset_i
-+	&movdqa		($rndkey1,$inout4);		# pass the checksum
-+
-+	&movups		(&QWP(-16,$out,$inp),$inout0);	# store output
-+
-+	&mov		($rounds,&DWP(240,$i3));
-+	&mov		($key,$i3);			# restore key
-+	&mov		($len,&DWP($end_off,"esp"));
-+
-+&set_label("odd");
-+	&shl		($rounds,4);
-+	&mov		($out,16);
-+	&sub		($out,$rounds);			# twisted rounds
-+	&mov		(&DWP($key_off,"esp"),$key);
-+	&lea		($key,&DWP(32,$key,$rounds));	# end of key schedule
-+	&mov		(&DWP($rounds_off,"esp"),$out);
-+
-+	&cmp		($inp,$len);
-+	&ja		(&label("short"));
-+	&jmp		(&label("grandloop"));
-+
-+&set_label("grandloop",32);
-+	&lea		($i1,&DWP(1,$block));
-+	&lea		($i3,&DWP(3,$block));
-+	&lea		($i5,&DWP(5,$block));
-+	&add		($block,6);
-+	&bsf		($i1,$i1);
-+	&bsf		($i3,$i3);
-+	&bsf		($i5,$i5);
-+	&shl		($i1,4);
-+	&shl		($i3,4);
-+	&shl		($i5,4);
-+	&movdqu		($inout0,&QWP(0,$l_));
-+	&movdqu		($inout1,&QWP(0,$l_,$i1));
-+	&mov		($rounds,&DWP($rounds_off,"esp"));
-+	&movdqa		($inout2,$inout0);
-+	&movdqu		($inout3,&QWP(0,$l_,$i3));
-+	&movdqa		($inout4,$inout0);
-+	&movdqu		($inout5,&QWP(0,$l_,$i5));
-+
-+	&pxor		($inout0,$rndkey0);		# ^ last offset_i
-+	&pxor		($inout1,$inout0);
-+	&movdqa		(&QWP(16*0,"esp"),$inout0);
-+	&pxor		($inout2,$inout1);
-+	&movdqa		(&QWP(16*1,"esp"),$inout1);
-+	&pxor		($inout3,$inout2);
-+	&movdqa		(&QWP(16*2,"esp"),$inout2);
-+	&pxor		($inout4,$inout3);
-+	&movdqa		(&QWP(16*3,"esp"),$inout3);
-+	&pxor		($inout5,$inout4);
-+	&movdqa		(&QWP(16*4,"esp"),$inout4);
-+	&movdqa		(&QWP(16*5,"esp"),$inout5);
-+
-+	&$movekey	($rndkey0,&QWP(-48,$key,$rounds));
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&movdqu		($inout1,&QWP(16*1,$inp));
-+	&movdqu		($inout2,&QWP(16*2,$inp));
-+	&movdqu		($inout3,&QWP(16*3,$inp));
-+	&movdqu		($inout4,&QWP(16*4,$inp));
-+	&movdqu		($inout5,&QWP(16*5,$inp));
-+	&lea		($inp,&DWP(16*6,$inp));
-+
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&pxor		($inout0,$rndkey0);		# ^ roundkey[0]
-+	&pxor		($rndkey1,$inout1);
-+	&pxor		($inout1,$rndkey0);
-+	&pxor		($rndkey1,$inout2);
-+	&pxor		($inout2,$rndkey0);
-+	&pxor		($rndkey1,$inout3);
-+	&pxor		($inout3,$rndkey0);
-+	&pxor		($rndkey1,$inout4);
-+	&pxor		($inout4,$rndkey0);
-+	&pxor		($rndkey1,$inout5);
-+	&pxor		($inout5,$rndkey0);
-+	&movdqa		(&QWP($checksum,"esp"),$rndkey1);
-+
-+	&$movekey	($rndkey1,&QWP(-32,$key,$rounds));
-+	&pxor		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&pxor		($inout1,&QWP(16*1,"esp"));
-+	&pxor		($inout2,&QWP(16*2,"esp"));
-+	&pxor		($inout3,&QWP(16*3,"esp"));
-+	&pxor		($inout4,&QWP(16*4,"esp"));
-+	&pxor		($inout5,&QWP(16*5,"esp"));
-+
-+	&$movekey	($rndkey0,&QWP(-16,$key,$rounds));
-+	&aesenc		($inout0,$rndkey1);
-+	&aesenc		($inout1,$rndkey1);
-+	&aesenc		($inout2,$rndkey1);
-+	&aesenc		($inout3,$rndkey1);
-+	&aesenc		($inout4,$rndkey1);
-+	&aesenc		($inout5,$rndkey1);
-+
-+	&mov		($out,&DWP($out_off,"esp"));
-+	&mov		($len,&DWP($end_off,"esp"));
-+	&call		("_aesni_encrypt6_enter");
-+
-+	&movdqa		($rndkey0,&QWP(16*5,"esp"));	# pass last offset_i
-+	&pxor		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&pxor		($inout1,&QWP(16*1,"esp"));
-+	&pxor		($inout2,&QWP(16*2,"esp"));
-+	&pxor		($inout3,&QWP(16*3,"esp"));
-+	&pxor		($inout4,&QWP(16*4,"esp"));
-+	&pxor		($inout5,$rndkey0);
-+	&movdqa		($rndkey1,&QWP($checksum,"esp"));# pass the checksum
-+
-+	&movdqu		(&QWP(-16*6,$out,$inp),$inout0);# store output
-+	&movdqu		(&QWP(-16*5,$out,$inp),$inout1);
-+	&movdqu		(&QWP(-16*4,$out,$inp),$inout2);
-+	&movdqu		(&QWP(-16*3,$out,$inp),$inout3);
-+	&movdqu		(&QWP(-16*2,$out,$inp),$inout4);
-+	&movdqu		(&QWP(-16*1,$out,$inp),$inout5);
-+	&cmp		($inp,$len);			# done yet?
-+	&jb		(&label("grandloop"));
-+
-+&set_label("short");
-+	&add		($len,16*6);
-+	&sub		($len,$inp);
-+	&jz		(&label("done"));
-+
-+	&cmp		($len,16*2);
-+	&jb		(&label("one"));
-+	&je		(&label("two"));
-+
-+	&cmp		($len,16*4);
-+	&jb		(&label("three"));
-+	&je		(&label("four"));
-+
-+	&lea		($i1,&DWP(1,$block));
-+	&lea		($i3,&DWP(3,$block));
-+	&bsf		($i1,$i1);
-+	&bsf		($i3,$i3);
-+	&shl		($i1,4);
-+	&shl		($i3,4);
-+	&movdqu		($inout0,&QWP(0,$l_));
-+	&movdqu		($inout1,&QWP(0,$l_,$i1));
-+	&mov		($rounds,&DWP($rounds_off,"esp"));
-+	&movdqa		($inout2,$inout0);
-+	&movdqu		($inout3,&QWP(0,$l_,$i3));
-+	&movdqa		($inout4,$inout0);
-+
-+	&pxor		($inout0,$rndkey0);		# ^ last offset_i
-+	&pxor		($inout1,$inout0);
-+	&movdqa		(&QWP(16*0,"esp"),$inout0);
-+	&pxor		($inout2,$inout1);
-+	&movdqa		(&QWP(16*1,"esp"),$inout1);
-+	&pxor		($inout3,$inout2);
-+	&movdqa		(&QWP(16*2,"esp"),$inout2);
-+	&pxor		($inout4,$inout3);
-+	&movdqa		(&QWP(16*3,"esp"),$inout3);
-+	&pxor		($inout5,$inout4);
-+	&movdqa		(&QWP(16*4,"esp"),$inout4);
-+
-+	&$movekey	($rndkey0,&QWP(-48,$key,$rounds));
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&movdqu		($inout1,&QWP(16*1,$inp));
-+	&movdqu		($inout2,&QWP(16*2,$inp));
-+	&movdqu		($inout3,&QWP(16*3,$inp));
-+	&movdqu		($inout4,&QWP(16*4,$inp));
-+	&pxor		($inout5,$inout5);
-+
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&pxor		($inout0,$rndkey0);		# ^ roundkey[0]
-+	&pxor		($rndkey1,$inout1);
-+	&pxor		($inout1,$rndkey0);
-+	&pxor		($rndkey1,$inout2);
-+	&pxor		($inout2,$rndkey0);
-+	&pxor		($rndkey1,$inout3);
-+	&pxor		($inout3,$rndkey0);
-+	&pxor		($rndkey1,$inout4);
-+	&pxor		($inout4,$rndkey0);
-+	&movdqa		(&QWP($checksum,"esp"),$rndkey1);
-+
-+	&$movekey	($rndkey1,&QWP(-32,$key,$rounds));
-+	&pxor		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&pxor		($inout1,&QWP(16*1,"esp"));
-+	&pxor		($inout2,&QWP(16*2,"esp"));
-+	&pxor		($inout3,&QWP(16*3,"esp"));
-+	&pxor		($inout4,&QWP(16*4,"esp"));
-+
-+	&$movekey	($rndkey0,&QWP(-16,$key,$rounds));
-+	&aesenc		($inout0,$rndkey1);
-+	&aesenc		($inout1,$rndkey1);
-+	&aesenc		($inout2,$rndkey1);
-+	&aesenc		($inout3,$rndkey1);
-+	&aesenc		($inout4,$rndkey1);
-+	&aesenc		($inout5,$rndkey1);
-+
-+	&mov		($out,&DWP($out_off,"esp"));
-+	&call		("_aesni_encrypt6_enter");
-+
-+	&movdqa		($rndkey0,&QWP(16*4,"esp"));	# pass last offset_i
-+	&pxor		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&pxor		($inout1,&QWP(16*1,"esp"));
-+	&pxor		($inout2,&QWP(16*2,"esp"));
-+	&pxor		($inout3,&QWP(16*3,"esp"));
-+	&pxor		($inout4,$rndkey0);
-+	&movdqa		($rndkey1,&QWP($checksum,"esp"));# pass the checksum
-+
-+	&movdqu		(&QWP(16*0,$out,$inp),$inout0);	# store output
-+	&movdqu		(&QWP(16*1,$out,$inp),$inout1);
-+	&movdqu		(&QWP(16*2,$out,$inp),$inout2);
-+	&movdqu		(&QWP(16*3,$out,$inp),$inout3);
-+	&movdqu		(&QWP(16*4,$out,$inp),$inout4);
-+
-+	&jmp		(&label("done"));
-+
-+&set_label("one",16);
-+	&movdqu		($inout5,&QWP(0,$l_));
-+	&mov		($key,&DWP($key_off,"esp"));	# restore key
-+
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&mov		($rounds,&DWP(240,$key));
-+
-+	&pxor		($inout5,$rndkey0);		# ^ last offset_i
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&pxor		($inout0,$inout5);		# ^ offset_i
-+
-+	&movdqa		($inout4,$rndkey1);
-+	&mov		($out,&DWP($out_off,"esp"));
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc");	}
-+	else
-+	{   &call	("_aesni_encrypt1");	}
-+
-+	&xorps		($inout0,$inout5);		# ^ offset_i
-+	&movdqa		($rndkey0,$inout5);		# pass last offset_i
-+	&movdqa		($rndkey1,$inout4);		# pass the checksum
-+	&movups		(&QWP(0,$out,$inp),$inout0);
-+
-+	&jmp		(&label("done"));
-+
-+&set_label("two",16);
-+	&lea		($i1,&DWP(1,$block));
-+	&mov		($key,&DWP($key_off,"esp"));	# restore key
-+	&bsf		($i1,$i1);
-+	&shl		($i1,4);
-+	&movdqu		($inout4,&QWP(0,$l_));
-+	&movdqu		($inout5,&QWP(0,$l_,$i1));
-+
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&movdqu		($inout1,&QWP(16*1,$inp));
-+	&mov		($rounds,&DWP(240,$key));
-+
-+	&pxor		($inout4,$rndkey0);		# ^ last offset_i
-+	&pxor		($inout5,$inout4);
-+
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&pxor		($inout0,$inout4);		# ^ offset_i
-+	&pxor		($rndkey1,$inout1);
-+	&pxor		($inout1,$inout5);
-+
-+	&movdqa		($inout3,$rndkey1)
-+	&mov		($out,&DWP($out_off,"esp"));
-+	&call		("_aesni_encrypt2");
-+
-+	&xorps		($inout0,$inout4);		# ^ offset_i
-+	&xorps		($inout1,$inout5);
-+	&movdqa		($rndkey0,$inout5);		# pass last offset_i
-+	&movdqa		($rndkey1,$inout3);		# pass the checksum
-+	&movups		(&QWP(16*0,$out,$inp),$inout0);	# store output
-+	&movups		(&QWP(16*1,$out,$inp),$inout1);
-+
-+	&jmp		(&label("done"));
-+
-+&set_label("three",16);
-+	&lea		($i1,&DWP(1,$block));
-+	&mov		($key,&DWP($key_off,"esp"));	# restore key
-+	&bsf		($i1,$i1);
-+	&shl		($i1,4);
-+	&movdqu		($inout3,&QWP(0,$l_));
-+	&movdqu		($inout4,&QWP(0,$l_,$i1));
-+	&movdqa		($inout5,$inout3);
-+
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&movdqu		($inout1,&QWP(16*1,$inp));
-+	&movdqu		($inout2,&QWP(16*2,$inp));
-+	&mov		($rounds,&DWP(240,$key));
-+
-+	&pxor		($inout3,$rndkey0);		# ^ last offset_i
-+	&pxor		($inout4,$inout3);
-+	&pxor		($inout5,$inout4);
-+
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&pxor		($inout0,$inout3);		# ^ offset_i
-+	&pxor		($rndkey1,$inout1);
-+	&pxor		($inout1,$inout4);
-+	&pxor		($rndkey1,$inout2);
-+	&pxor		($inout2,$inout5);
-+
-+	&movdqa		(&QWP($checksum,"esp"),$rndkey1);
-+	&mov		($out,&DWP($out_off,"esp"));
-+	&call		("_aesni_encrypt3");
-+
-+	&xorps		($inout0,$inout3);		# ^ offset_i
-+	&xorps		($inout1,$inout4);
-+	&xorps		($inout2,$inout5);
-+	&movdqa		($rndkey0,$inout5);		# pass last offset_i
-+	&movdqa		($rndkey1,&QWP($checksum,"esp"));# pass the checksum
-+	&movups		(&QWP(16*0,$out,$inp),$inout0);	# store output
-+	&movups		(&QWP(16*1,$out,$inp),$inout1);
-+	&movups		(&QWP(16*2,$out,$inp),$inout2);
-+
-+	&jmp		(&label("done"));
-+
-+&set_label("four",16);
-+	&lea		($i1,&DWP(1,$block));
-+	&lea		($i3,&DWP(3,$block));
-+	&bsf		($i1,$i1);
-+	&bsf		($i3,$i3);
-+	&mov		($key,&DWP($key_off,"esp"));	# restore key
-+	&shl		($i1,4);
-+	&shl		($i3,4);
-+	&movdqu		($inout2,&QWP(0,$l_));
-+	&movdqu		($inout3,&QWP(0,$l_,$i1));
-+	&movdqa		($inout4,$inout2);
-+	&movdqu		($inout5,&QWP(0,$l_,$i3));
-+
-+	&pxor		($inout2,$rndkey0);		# ^ last offset_i
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&pxor		($inout3,$inout2);
-+	&movdqu		($inout1,&QWP(16*1,$inp));
-+	&pxor		($inout4,$inout3);
-+	&movdqa		(&QWP(16*0,"esp"),$inout2);
-+	&pxor		($inout5,$inout4);
-+	&movdqa		(&QWP(16*1,"esp"),$inout3);
-+	&movdqu		($inout2,&QWP(16*2,$inp));
-+	&movdqu		($inout3,&QWP(16*3,$inp));
-+	&mov		($rounds,&DWP(240,$key));
-+
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&pxor		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&pxor		($rndkey1,$inout1);
-+	&pxor		($inout1,&QWP(16*1,"esp"));
-+	&pxor		($rndkey1,$inout2);
-+	&pxor		($inout2,$inout4);
-+	&pxor		($rndkey1,$inout3);
-+	&pxor		($inout3,$inout5);
-+
-+	&movdqa		(&QWP($checksum,"esp"),$rndkey1)
-+	&mov		($out,&DWP($out_off,"esp"));
-+	&call		("_aesni_encrypt4");
-+
-+	&xorps		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&xorps		($inout1,&QWP(16*1,"esp"));
-+	&xorps		($inout2,$inout4);
-+	&movups		(&QWP(16*0,$out,$inp),$inout0);	# store output
-+	&xorps		($inout3,$inout5);
-+	&movups		(&QWP(16*1,$out,$inp),$inout1);
-+	&movdqa		($rndkey0,$inout5);		# pass last offset_i
-+	&movups		(&QWP(16*2,$out,$inp),$inout2);
-+	&movdqa		($rndkey1,&QWP($checksum,"esp"));# pass the checksum
-+	&movups		(&QWP(16*3,$out,$inp),$inout3);
-+
-+&set_label("done");
-+	&mov	($key,&DWP($esp_off,"esp"));
-+	&pxor	($inout0,$inout0);		# clear register bank
-+	&pxor	($inout1,$inout1);
-+	&movdqa	(&QWP(16*0,"esp"),$inout0);	# clear stack
-+	&pxor	($inout2,$inout2);
-+	&movdqa	(&QWP(16*1,"esp"),$inout0);
-+	&pxor	($inout3,$inout3);
-+	&movdqa	(&QWP(16*2,"esp"),$inout0);
-+	&pxor	($inout4,$inout4);
-+	&movdqa	(&QWP(16*3,"esp"),$inout0);
-+	&pxor	($inout5,$inout5);
-+	&movdqa	(&QWP(16*4,"esp"),$inout0);
-+	&movdqa	(&QWP(16*5,"esp"),$inout0);
-+	&movdqa	(&QWP(16*6,"esp"),$inout0);
-+
-+	&lea	("esp",&DWP(0,$key));
-+	&mov	($rounds,&wparam(5));		# &offset_i
-+	&mov	($rounds_,&wparam(7));		# &checksum
-+	&movdqu	(&QWP(0,$rounds),$rndkey0);
-+	&pxor	($rndkey0,$rndkey0);
-+	&movdqu	(&QWP(0,$rounds_),$rndkey1);
-+	&pxor	($rndkey1,$rndkey1);
-+&function_end("aesni_ocb_encrypt");
-+
-+&function_begin("aesni_ocb_decrypt");
-+	&mov	($rounds,&wparam(5));		# &offset_i
-+	&mov	($rounds_,&wparam(7));		# &checksum
-+
-+	&mov	($inp,&wparam(0));
-+	&mov	($out,&wparam(1));
-+	&mov	($len,&wparam(2));
-+	&mov	($key,&wparam(3));
-+	&movdqu	($rndkey0,&QWP(0,$rounds));	# load offset_i
-+	&mov	($block,&wparam(4));		# start_block_num
-+	&movdqu	($rndkey1,&QWP(0,$rounds_));	# load checksum
-+	&mov	($l_,&wparam(6));		# L_
-+
-+	&mov	($rounds,"esp");
-+	&sub	("esp",$esp_off+4);		# alloca
-+	&and	("esp",-16);			# align stack
-+
-+	&sub	($out,$inp);
-+	&shl	($len,4);
-+	&lea	($len,&DWP(-16*6,$inp,$len));	# end of input - 16*6
-+	&mov	(&DWP($out_off,"esp"),$out);
-+	&mov	(&DWP($end_off,"esp"),$len);
-+	&mov	(&DWP($esp_off,"esp"),$rounds);
-+
-+	&mov	($rounds,&DWP(240,$key));
-+
-+	&test	($block,1);
-+	&jnz	(&label("odd"));
-+
-+	&bsf		($i3,$block);
-+	&add		($block,1);
-+	&shl		($i3,4);
-+	&movdqu		($inout5,&QWP(0,$l_,$i3));
-+	&mov		($i3,$key);			# put aside key
-+
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&lea		($inp,&DWP(16,$inp));
-+
-+	&pxor		($inout5,$rndkey0);		# ^ last offset_i
-+	&pxor		($inout0,$inout5);		# ^ offset_i
-+
-+	&movdqa		($inout4,$rndkey1);
-+	if ($inline)
-+	{   &aesni_inline_generate1("dec");	}
-+	else
-+	{   &call	("_aesni_decrypt1");	}
-+
-+	&xorps		($inout0,$inout5);		# ^ offset_i
-+	&movaps		($rndkey1,$inout4);		# pass the checksum
-+	&movdqa		($rndkey0,$inout5);		# pass last offset_i
-+	&xorps		($rndkey1,$inout0);		# checksum
-+	&movups		(&QWP(-16,$out,$inp),$inout0);	# store output
-+
-+	&mov		($rounds,&DWP(240,$i3));
-+	&mov		($key,$i3);			# restore key
-+	&mov		($len,&DWP($end_off,"esp"));
-+
-+&set_label("odd");
-+	&shl		($rounds,4);
-+	&mov		($out,16);
-+	&sub		($out,$rounds);			# twisted rounds
-+	&mov		(&DWP($key_off,"esp"),$key);
-+	&lea		($key,&DWP(32,$key,$rounds));	# end of key schedule
-+	&mov		(&DWP($rounds_off,"esp"),$out);
-+
-+	&cmp		($inp,$len);
-+	&ja		(&label("short"));
-+	&jmp		(&label("grandloop"));
-+
-+&set_label("grandloop",32);
-+	&lea		($i1,&DWP(1,$block));
-+	&lea		($i3,&DWP(3,$block));
-+	&lea		($i5,&DWP(5,$block));
-+	&add		($block,6);
-+	&bsf		($i1,$i1);
-+	&bsf		($i3,$i3);
-+	&bsf		($i5,$i5);
-+	&shl		($i1,4);
-+	&shl		($i3,4);
-+	&shl		($i5,4);
-+	&movdqu		($inout0,&QWP(0,$l_));
-+	&movdqu		($inout1,&QWP(0,$l_,$i1));
-+	&mov		($rounds,&DWP($rounds_off,"esp"));
-+	&movdqa		($inout2,$inout0);
-+	&movdqu		($inout3,&QWP(0,$l_,$i3));
-+	&movdqa		($inout4,$inout0);
-+	&movdqu		($inout5,&QWP(0,$l_,$i5));
-+
-+	&pxor		($inout0,$rndkey0);		# ^ last offset_i
-+	&pxor		($inout1,$inout0);
-+	&movdqa		(&QWP(16*0,"esp"),$inout0);
-+	&pxor		($inout2,$inout1);
-+	&movdqa		(&QWP(16*1,"esp"),$inout1);
-+	&pxor		($inout3,$inout2);
-+	&movdqa		(&QWP(16*2,"esp"),$inout2);
-+	&pxor		($inout4,$inout3);
-+	&movdqa		(&QWP(16*3,"esp"),$inout3);
-+	&pxor		($inout5,$inout4);
-+	&movdqa		(&QWP(16*4,"esp"),$inout4);
-+	&movdqa		(&QWP(16*5,"esp"),$inout5);
-+
-+	&$movekey	($rndkey0,&QWP(-48,$key,$rounds));
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&movdqu		($inout1,&QWP(16*1,$inp));
-+	&movdqu		($inout2,&QWP(16*2,$inp));
-+	&movdqu		($inout3,&QWP(16*3,$inp));
-+	&movdqu		($inout4,&QWP(16*4,$inp));
-+	&movdqu		($inout5,&QWP(16*5,$inp));
-+	&lea		($inp,&DWP(16*6,$inp));
-+
-+	&movdqa		(&QWP($checksum,"esp"),$rndkey1);
-+	&pxor		($inout0,$rndkey0);		# ^ roundkey[0]
-+	&pxor		($inout1,$rndkey0);
-+	&pxor		($inout2,$rndkey0);
-+	&pxor		($inout3,$rndkey0);
-+	&pxor		($inout4,$rndkey0);
-+	&pxor		($inout5,$rndkey0);
-+
-+	&$movekey	($rndkey1,&QWP(-32,$key,$rounds));
-+	&pxor		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&pxor		($inout1,&QWP(16*1,"esp"));
-+	&pxor		($inout2,&QWP(16*2,"esp"));
-+	&pxor		($inout3,&QWP(16*3,"esp"));
-+	&pxor		($inout4,&QWP(16*4,"esp"));
-+	&pxor		($inout5,&QWP(16*5,"esp"));
-+
-+	&$movekey	($rndkey0,&QWP(-16,$key,$rounds));
-+	&aesdec		($inout0,$rndkey1);
-+	&aesdec		($inout1,$rndkey1);
-+	&aesdec		($inout2,$rndkey1);
-+	&aesdec		($inout3,$rndkey1);
-+	&aesdec		($inout4,$rndkey1);
-+	&aesdec		($inout5,$rndkey1);
-+
-+	&mov		($out,&DWP($out_off,"esp"));
-+	&mov		($len,&DWP($end_off,"esp"));
-+	&call		("_aesni_decrypt6_enter");
-+
-+	&movdqa		($rndkey0,&QWP(16*5,"esp"));	# pass last offset_i
-+	&pxor		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&movdqa		($rndkey1,&QWP($checksum,"esp"));
-+	&pxor		($inout1,&QWP(16*1,"esp"));
-+	&pxor		($inout2,&QWP(16*2,"esp"));
-+	&pxor		($inout3,&QWP(16*3,"esp"));
-+	&pxor		($inout4,&QWP(16*4,"esp"));
-+	&pxor		($inout5,$rndkey0);
-+
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&movdqu		(&QWP(-16*6,$out,$inp),$inout0);# store output
-+	&pxor		($rndkey1,$inout1);
-+	&movdqu		(&QWP(-16*5,$out,$inp),$inout1);
-+	&pxor		($rndkey1,$inout2);
-+	&movdqu		(&QWP(-16*4,$out,$inp),$inout2);
-+	&pxor		($rndkey1,$inout3);
-+	&movdqu		(&QWP(-16*3,$out,$inp),$inout3);
-+	&pxor		($rndkey1,$inout4);
-+	&movdqu		(&QWP(-16*2,$out,$inp),$inout4);
-+	&pxor		($rndkey1,$inout5);
-+	&movdqu		(&QWP(-16*1,$out,$inp),$inout5);
-+	&cmp		($inp,$len);			# done yet?
-+	&jb		(&label("grandloop"));
-+
-+&set_label("short");
-+	&add		($len,16*6);
-+	&sub		($len,$inp);
-+	&jz		(&label("done"));
-+
-+	&cmp		($len,16*2);
-+	&jb		(&label("one"));
-+	&je		(&label("two"));
-+
-+	&cmp		($len,16*4);
-+	&jb		(&label("three"));
-+	&je		(&label("four"));
-+
-+	&lea		($i1,&DWP(1,$block));
-+	&lea		($i3,&DWP(3,$block));
-+	&bsf		($i1,$i1);
-+	&bsf		($i3,$i3);
-+	&shl		($i1,4);
-+	&shl		($i3,4);
-+	&movdqu		($inout0,&QWP(0,$l_));
-+	&movdqu		($inout1,&QWP(0,$l_,$i1));
-+	&mov		($rounds,&DWP($rounds_off,"esp"));
-+	&movdqa		($inout2,$inout0);
-+	&movdqu		($inout3,&QWP(0,$l_,$i3));
-+	&movdqa		($inout4,$inout0);
-+
-+	&pxor		($inout0,$rndkey0);		# ^ last offset_i
-+	&pxor		($inout1,$inout0);
-+	&movdqa		(&QWP(16*0,"esp"),$inout0);
-+	&pxor		($inout2,$inout1);
-+	&movdqa		(&QWP(16*1,"esp"),$inout1);
-+	&pxor		($inout3,$inout2);
-+	&movdqa		(&QWP(16*2,"esp"),$inout2);
-+	&pxor		($inout4,$inout3);
-+	&movdqa		(&QWP(16*3,"esp"),$inout3);
-+	&pxor		($inout5,$inout4);
-+	&movdqa		(&QWP(16*4,"esp"),$inout4);
-+
-+	&$movekey	($rndkey0,&QWP(-48,$key,$rounds));
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&movdqu		($inout1,&QWP(16*1,$inp));
-+	&movdqu		($inout2,&QWP(16*2,$inp));
-+	&movdqu		($inout3,&QWP(16*3,$inp));
-+	&movdqu		($inout4,&QWP(16*4,$inp));
-+	&pxor		($inout5,$inout5);
-+
-+	&movdqa		(&QWP($checksum,"esp"),$rndkey1);
-+	&pxor		($inout0,$rndkey0);		# ^ roundkey[0]
-+	&pxor		($inout1,$rndkey0);
-+	&pxor		($inout2,$rndkey0);
-+	&pxor		($inout3,$rndkey0);
-+	&pxor		($inout4,$rndkey0);
-+
-+	&$movekey	($rndkey1,&QWP(-32,$key,$rounds));
-+	&pxor		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&pxor		($inout1,&QWP(16*1,"esp"));
-+	&pxor		($inout2,&QWP(16*2,"esp"));
-+	&pxor		($inout3,&QWP(16*3,"esp"));
-+	&pxor		($inout4,&QWP(16*4,"esp"));
-+
-+	&$movekey	($rndkey0,&QWP(-16,$key,$rounds));
-+	&aesdec		($inout0,$rndkey1);
-+	&aesdec		($inout1,$rndkey1);
-+	&aesdec		($inout2,$rndkey1);
-+	&aesdec		($inout3,$rndkey1);
-+	&aesdec		($inout4,$rndkey1);
-+	&aesdec		($inout5,$rndkey1);
-+
-+	&mov		($out,&DWP($out_off,"esp"));
-+	&call		("_aesni_decrypt6_enter");
-+
-+	&movdqa		($rndkey0,&QWP(16*4,"esp"));	# pass last offset_i
-+	&pxor		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&movdqa		($rndkey1,&QWP($checksum,"esp"));
-+	&pxor		($inout1,&QWP(16*1,"esp"));
-+	&pxor		($inout2,&QWP(16*2,"esp"));
-+	&pxor		($inout3,&QWP(16*3,"esp"));
-+	&pxor		($inout4,$rndkey0);
-+
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&movdqu		(&QWP(16*0,$out,$inp),$inout0);	# store output
-+	&pxor		($rndkey1,$inout1);
-+	&movdqu		(&QWP(16*1,$out,$inp),$inout1);
-+	&pxor		($rndkey1,$inout2);
-+	&movdqu		(&QWP(16*2,$out,$inp),$inout2);
-+	&pxor		($rndkey1,$inout3);
-+	&movdqu		(&QWP(16*3,$out,$inp),$inout3);
-+	&pxor		($rndkey1,$inout4);
-+	&movdqu		(&QWP(16*4,$out,$inp),$inout4);
-+
-+	&jmp		(&label("done"));
-+
-+&set_label("one",16);
-+	&movdqu		($inout5,&QWP(0,$l_));
-+	&mov		($key,&DWP($key_off,"esp"));	# restore key
-+
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&mov		($rounds,&DWP(240,$key));
-+
-+	&pxor		($inout5,$rndkey0);		# ^ last offset_i
-+	&pxor		($inout0,$inout5);		# ^ offset_i
-+
-+	&movdqa		($inout4,$rndkey1);
-+	&mov		($out,&DWP($out_off,"esp"));
-+	if ($inline)
-+	{   &aesni_inline_generate1("dec");	}
-+	else
-+	{   &call	("_aesni_decrypt1");	}
-+
-+	&xorps		($inout0,$inout5);		# ^ offset_i
-+	&movaps		($rndkey1,$inout4);		# pass the checksum
-+	&movdqa		($rndkey0,$inout5);		# pass last offset_i
-+	&xorps		($rndkey1,$inout0);		# checksum
-+	&movups		(&QWP(0,$out,$inp),$inout0);
-+
-+	&jmp		(&label("done"));
-+
-+&set_label("two",16);
-+	&lea		($i1,&DWP(1,$block));
-+	&mov		($key,&DWP($key_off,"esp"));	# restore key
-+	&bsf		($i1,$i1);
-+	&shl		($i1,4);
-+	&movdqu		($inout4,&QWP(0,$l_));
-+	&movdqu		($inout5,&QWP(0,$l_,$i1));
-+
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&movdqu		($inout1,&QWP(16*1,$inp));
-+	&mov		($rounds,&DWP(240,$key));
-+
-+	&movdqa		($inout3,$rndkey1);
-+	&pxor		($inout4,$rndkey0);		# ^ last offset_i
-+	&pxor		($inout5,$inout4);
-+
-+	&pxor		($inout0,$inout4);		# ^ offset_i
-+	&pxor		($inout1,$inout5);
-+
-+	&mov		($out,&DWP($out_off,"esp"));
-+	&call		("_aesni_decrypt2");
-+
-+	&xorps		($inout0,$inout4);		# ^ offset_i
-+	&xorps		($inout1,$inout5);
-+	&movdqa		($rndkey0,$inout5);		# pass last offset_i
-+	&xorps		($inout3,$inout0);		# checksum
-+	&movups		(&QWP(16*0,$out,$inp),$inout0);	# store output
-+	&xorps		($inout3,$inout1);
-+	&movups		(&QWP(16*1,$out,$inp),$inout1);
-+	&movaps		($rndkey1,$inout3);		# pass the checksum
-+
-+	&jmp		(&label("done"));
-+
-+&set_label("three",16);
-+	&lea		($i1,&DWP(1,$block));
-+	&mov		($key,&DWP($key_off,"esp"));	# restore key
-+	&bsf		($i1,$i1);
-+	&shl		($i1,4);
-+	&movdqu		($inout3,&QWP(0,$l_));
-+	&movdqu		($inout4,&QWP(0,$l_,$i1));
-+	&movdqa		($inout5,$inout3);
-+
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&movdqu		($inout1,&QWP(16*1,$inp));
-+	&movdqu		($inout2,&QWP(16*2,$inp));
-+	&mov		($rounds,&DWP(240,$key));
-+
-+	&movdqa		(&QWP($checksum,"esp"),$rndkey1);
-+	&pxor		($inout3,$rndkey0);		# ^ last offset_i
-+	&pxor		($inout4,$inout3);
-+	&pxor		($inout5,$inout4);
-+
-+	&pxor		($inout0,$inout3);		# ^ offset_i
-+	&pxor		($inout1,$inout4);
-+	&pxor		($inout2,$inout5);
-+
-+	&mov		($out,&DWP($out_off,"esp"));
-+	&call		("_aesni_decrypt3");
-+
-+	&movdqa		($rndkey1,&QWP($checksum,"esp"));# pass the checksum
-+	&xorps		($inout0,$inout3);		# ^ offset_i
-+	&xorps		($inout1,$inout4);
-+	&xorps		($inout2,$inout5);
-+	&movups		(&QWP(16*0,$out,$inp),$inout0);	# store output
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&movdqa		($rndkey0,$inout5);		# pass last offset_i
-+	&movups		(&QWP(16*1,$out,$inp),$inout1);
-+	&pxor		($rndkey1,$inout1);
-+	&movups		(&QWP(16*2,$out,$inp),$inout2);
-+	&pxor		($rndkey1,$inout2);
-+
-+	&jmp		(&label("done"));
-+
-+&set_label("four",16);
-+	&lea		($i1,&DWP(1,$block));
-+	&lea		($i3,&DWP(3,$block));
-+	&bsf		($i1,$i1);
-+	&bsf		($i3,$i3);
-+	&mov		($key,&DWP($key_off,"esp"));	# restore key
-+	&shl		($i1,4);
-+	&shl		($i3,4);
-+	&movdqu		($inout2,&QWP(0,$l_));
-+	&movdqu		($inout3,&QWP(0,$l_,$i1));
-+	&movdqa		($inout4,$inout2);
-+	&movdqu		($inout5,&QWP(0,$l_,$i3));
-+
-+	&pxor		($inout2,$rndkey0);		# ^ last offset_i
-+	&movdqu		($inout0,&QWP(16*0,$inp));	# load input
-+	&pxor		($inout3,$inout2);
-+	&movdqu		($inout1,&QWP(16*1,$inp));
-+	&pxor		($inout4,$inout3);
-+	&movdqa		(&QWP(16*0,"esp"),$inout2);
-+	&pxor		($inout5,$inout4);
-+	&movdqa		(&QWP(16*1,"esp"),$inout3);
-+	&movdqu		($inout2,&QWP(16*2,$inp));
-+	&movdqu		($inout3,&QWP(16*3,$inp));
-+	&mov		($rounds,&DWP(240,$key));
-+
-+	&movdqa		(&QWP($checksum,"esp"),$rndkey1);
-+	&pxor		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&pxor		($inout1,&QWP(16*1,"esp"));
-+	&pxor		($inout2,$inout4);
-+	&pxor		($inout3,$inout5);
-+
-+	&mov		($out,&DWP($out_off,"esp"));
-+	&call		("_aesni_decrypt4");
-+
-+	&movdqa		($rndkey1,&QWP($checksum,"esp"));# pass the checksum
-+	&xorps		($inout0,&QWP(16*0,"esp"));	# ^ offset_i
-+	&xorps		($inout1,&QWP(16*1,"esp"));
-+	&xorps		($inout2,$inout4);
-+	&movups		(&QWP(16*0,$out,$inp),$inout0);	# store output
-+	&pxor		($rndkey1,$inout0);		# checksum
-+	&xorps		($inout3,$inout5);
-+	&movups		(&QWP(16*1,$out,$inp),$inout1);
-+	&pxor		($rndkey1,$inout1);
-+	&movdqa		($rndkey0,$inout5);		# pass last offset_i
-+	&movups		(&QWP(16*2,$out,$inp),$inout2);
-+	&pxor		($rndkey1,$inout2);
-+	&movups		(&QWP(16*3,$out,$inp),$inout3);
-+	&pxor		($rndkey1,$inout3);
-+
-+&set_label("done");
-+	&mov	($key,&DWP($esp_off,"esp"));
-+	&pxor	($inout0,$inout0);		# clear register bank
-+	&pxor	($inout1,$inout1);
-+	&movdqa	(&QWP(16*0,"esp"),$inout0);	# clear stack
-+	&pxor	($inout2,$inout2);
-+	&movdqa	(&QWP(16*1,"esp"),$inout0);
-+	&pxor	($inout3,$inout3);
-+	&movdqa	(&QWP(16*2,"esp"),$inout0);
-+	&pxor	($inout4,$inout4);
-+	&movdqa	(&QWP(16*3,"esp"),$inout0);
-+	&pxor	($inout5,$inout5);
-+	&movdqa	(&QWP(16*4,"esp"),$inout0);
-+	&movdqa	(&QWP(16*5,"esp"),$inout0);
-+	&movdqa	(&QWP(16*6,"esp"),$inout0);
-+
-+	&lea	("esp",&DWP(0,$key));
-+	&mov	($rounds,&wparam(5));		# &offset_i
-+	&mov	($rounds_,&wparam(7));		# &checksum
-+	&movdqu	(&QWP(0,$rounds),$rndkey0);
-+	&pxor	($rndkey0,$rndkey0);
-+	&movdqu	(&QWP(0,$rounds_),$rndkey1);
-+	&pxor	($rndkey1,$rndkey1);
-+&function_end("aesni_ocb_decrypt");
-+}
-+}
-+
-+######################################################################
-+# void $PREFIX_cbc_encrypt (const void *inp, void *out,
-+#                           size_t length, const AES_KEY *key,
-+#                           unsigned char *ivp,const int enc);
-+&function_begin("${PREFIX}_cbc_encrypt");
-+	&mov	($inp,&wparam(0));
-+	&mov	($rounds_,"esp");
-+	&mov	($out,&wparam(1));
-+	&sub	($rounds_,24);
-+	&mov	($len,&wparam(2));
-+	&and	($rounds_,-16);
-+	&mov	($key,&wparam(3));
-+	&mov	($key_,&wparam(4));
-+	&test	($len,$len);
-+	&jz	(&label("cbc_abort"));
-+
-+	&cmp	(&wparam(5),0);
-+	&xchg	($rounds_,"esp");		# alloca
-+	&movups	($ivec,&QWP(0,$key_));		# load IV
-+	&mov	($rounds,&DWP(240,$key));
-+	&mov	($key_,$key);			# backup $key
-+	&mov	(&DWP(16,"esp"),$rounds_);	# save original %esp
-+	&mov	($rounds_,$rounds);		# backup $rounds
-+	&je	(&label("cbc_decrypt"));
-+
-+	&movaps	($inout0,$ivec);
-+	&cmp	($len,16);
-+	&jb	(&label("cbc_enc_tail"));
-+	&sub	($len,16);
-+	&jmp	(&label("cbc_enc_loop"));
-+
-+&set_label("cbc_enc_loop",16);
-+	&movups	($ivec,&QWP(0,$inp));		# input actually
-+	&lea	($inp,&DWP(16,$inp));
-+	if ($inline)
-+	{   &aesni_inline_generate1("enc",$inout0,$ivec);	}
-+	else
-+	{   &xorps($inout0,$ivec); &call("_aesni_encrypt1");	}
-+	&mov	($rounds,$rounds_);	# restore $rounds
-+	&mov	($key,$key_);		# restore $key
-+	&movups	(&QWP(0,$out),$inout0);	# store output
-+	&lea	($out,&DWP(16,$out));
-+	&sub	($len,16);
-+	&jnc	(&label("cbc_enc_loop"));
-+	&add	($len,16);
-+	&jnz	(&label("cbc_enc_tail"));
-+	&movaps	($ivec,$inout0);
-+	&pxor	($inout0,$inout0);
-+	&jmp	(&label("cbc_ret"));
-+
-+&set_label("cbc_enc_tail");
-+	&mov	("ecx",$len);		# zaps $rounds
-+	&data_word(0xA4F3F689);		# rep movsb
-+	&mov	("ecx",16);		# zero tail
-+	&sub	("ecx",$len);
-+	&xor	("eax","eax");		# zaps $len
-+	&data_word(0xAAF3F689);		# rep stosb
-+	&lea	($out,&DWP(-16,$out));	# rewind $out by 1 block
-+	&mov	($rounds,$rounds_);	# restore $rounds
-+	&mov	($inp,$out);		# $inp and $out are the same
-+	&mov	($key,$key_);		# restore $key
-+	&jmp	(&label("cbc_enc_loop"));
-+######################################################################
-+&set_label("cbc_decrypt",16);
-+	&cmp	($len,0x50);
-+	&jbe	(&label("cbc_dec_tail"));
-+	&movaps	(&QWP(0,"esp"),$ivec);		# save IV
-+	&sub	($len,0x50);
-+	&jmp	(&label("cbc_dec_loop6_enter"));
-+
-+&set_label("cbc_dec_loop6",16);
-+	&movaps	(&QWP(0,"esp"),$rndkey0);	# save IV
-+	&movups	(&QWP(0,$out),$inout5);
-+	&lea	($out,&DWP(0x10,$out));
-+&set_label("cbc_dec_loop6_enter");
-+	&movdqu	($inout0,&QWP(0,$inp));
-+	&movdqu	($inout1,&QWP(0x10,$inp));
-+	&movdqu	($inout2,&QWP(0x20,$inp));
-+	&movdqu	($inout3,&QWP(0x30,$inp));
-+	&movdqu	($inout4,&QWP(0x40,$inp));
-+	&movdqu	($inout5,&QWP(0x50,$inp));
-+
-+	&call	("_aesni_decrypt6");
-+
-+	&movups	($rndkey1,&QWP(0,$inp));
-+	&movups	($rndkey0,&QWP(0x10,$inp));
-+	&xorps	($inout0,&QWP(0,"esp"));	# ^=IV
-+	&xorps	($inout1,$rndkey1);
-+	&movups	($rndkey1,&QWP(0x20,$inp));
-+	&xorps	($inout2,$rndkey0);
-+	&movups	($rndkey0,&QWP(0x30,$inp));
-+	&xorps	($inout3,$rndkey1);
-+	&movups	($rndkey1,&QWP(0x40,$inp));
-+	&xorps	($inout4,$rndkey0);
-+	&movups	($rndkey0,&QWP(0x50,$inp));	# IV
-+	&xorps	($inout5,$rndkey1);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&lea	($inp,&DWP(0x60,$inp));
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&mov	($rounds,$rounds_);		# restore $rounds
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&mov	($key,$key_);			# restore $key
-+	&movups	(&QWP(0x40,$out),$inout4);
-+	&lea	($out,&DWP(0x50,$out));
-+	&sub	($len,0x60);
-+	&ja	(&label("cbc_dec_loop6"));
-+
-+	&movaps	($inout0,$inout5);
-+	&movaps	($ivec,$rndkey0);
-+	&add	($len,0x50);
-+	&jle	(&label("cbc_dec_clear_tail_collected"));
-+	&movups	(&QWP(0,$out),$inout0);
-+	&lea	($out,&DWP(0x10,$out));
-+&set_label("cbc_dec_tail");
-+	&movups	($inout0,&QWP(0,$inp));
-+	&movaps	($in0,$inout0);
-+	&cmp	($len,0x10);
-+	&jbe	(&label("cbc_dec_one"));
-+
-+	&movups	($inout1,&QWP(0x10,$inp));
-+	&movaps	($in1,$inout1);
-+	&cmp	($len,0x20);
-+	&jbe	(&label("cbc_dec_two"));
-+
-+	&movups	($inout2,&QWP(0x20,$inp));
-+	&cmp	($len,0x30);
-+	&jbe	(&label("cbc_dec_three"));
-+
-+	&movups	($inout3,&QWP(0x30,$inp));
-+	&cmp	($len,0x40);
-+	&jbe	(&label("cbc_dec_four"));
-+
-+	&movups	($inout4,&QWP(0x40,$inp));
-+	&movaps	(&QWP(0,"esp"),$ivec);		# save IV
-+	&movups	($inout0,&QWP(0,$inp));
-+	&xorps	($inout5,$inout5);
-+	&call	("_aesni_decrypt6");
-+	&movups	($rndkey1,&QWP(0,$inp));
-+	&movups	($rndkey0,&QWP(0x10,$inp));
-+	&xorps	($inout0,&QWP(0,"esp"));	# ^= IV
-+	&xorps	($inout1,$rndkey1);
-+	&movups	($rndkey1,&QWP(0x20,$inp));
-+	&xorps	($inout2,$rndkey0);
-+	&movups	($rndkey0,&QWP(0x30,$inp));
-+	&xorps	($inout3,$rndkey1);
-+	&movups	($ivec,&QWP(0x40,$inp));	# IV
-+	&xorps	($inout4,$rndkey0);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&pxor	($inout1,$inout1);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&pxor	($inout2,$inout2);
-+	&movups	(&QWP(0x30,$out),$inout3);
-+	&pxor	($inout3,$inout3);
-+	&lea	($out,&DWP(0x40,$out));
-+	&movaps	($inout0,$inout4);
-+	&pxor	($inout4,$inout4);
-+	&sub	($len,0x50);
-+	&jmp	(&label("cbc_dec_tail_collected"));
-+
-+&set_label("cbc_dec_one",16);
-+	if ($inline)
-+	{   &aesni_inline_generate1("dec");	}
-+	else
-+	{   &call	("_aesni_decrypt1");	}
-+	&xorps	($inout0,$ivec);
-+	&movaps	($ivec,$in0);
-+	&sub	($len,0x10);
-+	&jmp	(&label("cbc_dec_tail_collected"));
-+
-+&set_label("cbc_dec_two",16);
-+	&call	("_aesni_decrypt2");
-+	&xorps	($inout0,$ivec);
-+	&xorps	($inout1,$in0);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movaps	($inout0,$inout1);
-+	&pxor	($inout1,$inout1);
-+	&lea	($out,&DWP(0x10,$out));
-+	&movaps	($ivec,$in1);
-+	&sub	($len,0x20);
-+	&jmp	(&label("cbc_dec_tail_collected"));
-+
-+&set_label("cbc_dec_three",16);
-+	&call	("_aesni_decrypt3");
-+	&xorps	($inout0,$ivec);
-+	&xorps	($inout1,$in0);
-+	&xorps	($inout2,$in1);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&movaps	($inout0,$inout2);
-+	&pxor	($inout2,$inout2);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&pxor	($inout1,$inout1);
-+	&lea	($out,&DWP(0x20,$out));
-+	&movups	($ivec,&QWP(0x20,$inp));
-+	&sub	($len,0x30);
-+	&jmp	(&label("cbc_dec_tail_collected"));
-+
-+&set_label("cbc_dec_four",16);
-+	&call	("_aesni_decrypt4");
-+	&movups	($rndkey1,&QWP(0x10,$inp));
-+	&movups	($rndkey0,&QWP(0x20,$inp));
-+	&xorps	($inout0,$ivec);
-+	&movups	($ivec,&QWP(0x30,$inp));
-+	&xorps	($inout1,$in0);
-+	&movups	(&QWP(0,$out),$inout0);
-+	&xorps	($inout2,$rndkey1);
-+	&movups	(&QWP(0x10,$out),$inout1);
-+	&pxor	($inout1,$inout1);
-+	&xorps	($inout3,$rndkey0);
-+	&movups	(&QWP(0x20,$out),$inout2);
-+	&pxor	($inout2,$inout2);
-+	&lea	($out,&DWP(0x30,$out));
-+	&movaps	($inout0,$inout3);
-+	&pxor	($inout3,$inout3);
-+	&sub	($len,0x40);
-+	&jmp	(&label("cbc_dec_tail_collected"));
-+
-+&set_label("cbc_dec_clear_tail_collected",16);
-+	&pxor	($inout1,$inout1);
-+	&pxor	($inout2,$inout2);
-+	&pxor	($inout3,$inout3);
-+	&pxor	($inout4,$inout4);
-+&set_label("cbc_dec_tail_collected");
-+	&and	($len,15);
-+	&jnz	(&label("cbc_dec_tail_partial"));
-+	&movups	(&QWP(0,$out),$inout0);
-+	&pxor	($rndkey0,$rndkey0);
-+	&jmp	(&label("cbc_ret"));
-+
-+&set_label("cbc_dec_tail_partial",16);
-+	&movaps	(&QWP(0,"esp"),$inout0);
-+	&pxor	($rndkey0,$rndkey0);
-+	&mov	("ecx",16);
-+	&mov	($inp,"esp");
-+	&sub	("ecx",$len);
-+	&data_word(0xA4F3F689);		# rep movsb
-+	&movdqa	(&QWP(0,"esp"),$inout0);
-+
-+&set_label("cbc_ret");
-+	&mov	("esp",&DWP(16,"esp"));	# pull original %esp
-+	&mov	($key_,&wparam(4));
-+	&pxor	($inout0,$inout0);
-+	&pxor	($rndkey1,$rndkey1);
-+	&movups	(&QWP(0,$key_),$ivec);	# output IV
-+	&pxor	($ivec,$ivec);
-+&set_label("cbc_abort");
-+&function_end("${PREFIX}_cbc_encrypt");
-+
-+######################################################################
-+# Mechanical port from aesni-x86_64.pl.
-+#
-+# _aesni_set_encrypt_key is private interface,
-+# input:
-+#	"eax"	const unsigned char *userKey
-+#	$rounds	int bits
-+#	$key	AES_KEY *key
-+# output:
-+#	"eax"	return code
-+#	$round	rounds
-+
-+&function_begin_B("_aesni_set_encrypt_key");
-+	&push	("ebp");
-+	&push	("ebx");
-+	&test	("eax","eax");
-+	&jz	(&label("bad_pointer"));
-+	&test	($key,$key);
-+	&jz	(&label("bad_pointer"));
-+
-+	&call	(&label("pic"));
-+&set_label("pic");
-+	&blindpop("ebx");
-+	&lea	("ebx",&DWP(&label("key_const")."-".&label("pic"),"ebx"));
-+
-+	&picmeup("ebp","OPENSSL_ia32cap_P","ebx",&label("key_const"));
-+	&movups	("xmm0",&QWP(0,"eax"));	# pull first 128 bits of *userKey
-+	&xorps	("xmm4","xmm4");	# low dword of xmm4 is assumed 0
-+	&mov	("ebp",&DWP(4,"ebp"));
-+	&lea	($key,&DWP(16,$key));
-+	&and	("ebp",1<<28|1<<11);	# AVX and XOP bits
-+	&cmp	($rounds,256);
-+	&je	(&label("14rounds"));
-+	&cmp	($rounds,192);
-+	&je	(&label("12rounds"));
-+	&cmp	($rounds,128);
-+	&jne	(&label("bad_keybits"));
-+
-+&set_label("10rounds",16);
-+	&cmp		("ebp",1<<28);
-+	&je		(&label("10rounds_alt"));
-+
-+	&mov		($rounds,9);
-+	&$movekey	(&QWP(-16,$key),"xmm0");	# round 0
-+	&aeskeygenassist("xmm1","xmm0",0x01);		# round 1
-+	&call		(&label("key_128_cold"));
-+	&aeskeygenassist("xmm1","xmm0",0x2);		# round 2
-+	&call		(&label("key_128"));
-+	&aeskeygenassist("xmm1","xmm0",0x04);		# round 3
-+	&call		(&label("key_128"));
-+	&aeskeygenassist("xmm1","xmm0",0x08);		# round 4
-+	&call		(&label("key_128"));
-+	&aeskeygenassist("xmm1","xmm0",0x10);		# round 5
-+	&call		(&label("key_128"));
-+	&aeskeygenassist("xmm1","xmm0",0x20);		# round 6
-+	&call		(&label("key_128"));
-+	&aeskeygenassist("xmm1","xmm0",0x40);		# round 7
-+	&call		(&label("key_128"));
-+	&aeskeygenassist("xmm1","xmm0",0x80);		# round 8
-+	&call		(&label("key_128"));
-+	&aeskeygenassist("xmm1","xmm0",0x1b);		# round 9
-+	&call		(&label("key_128"));
-+	&aeskeygenassist("xmm1","xmm0",0x36);		# round 10
-+	&call		(&label("key_128"));
-+	&$movekey	(&QWP(0,$key),"xmm0");
-+	&mov		(&DWP(80,$key),$rounds);
-+
-+	&jmp	(&label("good_key"));
-+
-+&set_label("key_128",16);
-+	&$movekey	(&QWP(0,$key),"xmm0");
-+	&lea		($key,&DWP(16,$key));
-+&set_label("key_128_cold");
-+	&shufps		("xmm4","xmm0",0b00010000);
-+	&xorps		("xmm0","xmm4");
-+	&shufps		("xmm4","xmm0",0b10001100);
-+	&xorps		("xmm0","xmm4");
-+	&shufps		("xmm1","xmm1",0b11111111);	# critical path
-+	&xorps		("xmm0","xmm1");
-+	&ret();
-+
-+&set_label("10rounds_alt",16);
-+	&movdqa		("xmm5",&QWP(0x00,"ebx"));
-+	&mov		($rounds,8);
-+	&movdqa		("xmm4",&QWP(0x20,"ebx"));
-+	&movdqa		("xmm2","xmm0");
-+	&movdqu		(&QWP(-16,$key),"xmm0");
-+
-+&set_label("loop_key128");
-+	&pshufb		("xmm0","xmm5");
-+	&aesenclast	("xmm0","xmm4");
-+	&pslld		("xmm4",1);
-+	&lea		($key,&DWP(16,$key));
-+
-+	&movdqa		("xmm3","xmm2");
-+	&pslldq		("xmm2",4);
-+	&pxor		("xmm3","xmm2");
-+	&pslldq		("xmm2",4);
-+	&pxor		("xmm3","xmm2");
-+	&pslldq		("xmm2",4);
-+	&pxor		("xmm2","xmm3");
-+
-+	&pxor		("xmm0","xmm2");
-+	&movdqu		(&QWP(-16,$key),"xmm0");
-+	&movdqa		("xmm2","xmm0");
-+
-+	&dec		($rounds);
-+	&jnz		(&label("loop_key128"));
-+
-+	&movdqa		("xmm4",&QWP(0x30,"ebx"));
-+
-+	&pshufb		("xmm0","xmm5");
-+	&aesenclast	("xmm0","xmm4");
-+	&pslld		("xmm4",1);
-+
-+	&movdqa		("xmm3","xmm2");
-+	&pslldq		("xmm2",4);
-+	&pxor		("xmm3","xmm2");
-+	&pslldq		("xmm2",4);
-+	&pxor		("xmm3","xmm2");
-+	&pslldq		("xmm2",4);
-+	&pxor		("xmm2","xmm3");
-+
-+	&pxor		("xmm0","xmm2");
-+	&movdqu		(&QWP(0,$key),"xmm0");
-+
-+	&movdqa		("xmm2","xmm0");
-+	&pshufb		("xmm0","xmm5");
-+	&aesenclast	("xmm0","xmm4");
-+
-+	&movdqa		("xmm3","xmm2");
-+	&pslldq		("xmm2",4);
-+	&pxor		("xmm3","xmm2");
-+	&pslldq		("xmm2",4);
-+	&pxor		("xmm3","xmm2");
-+	&pslldq		("xmm2",4);
-+	&pxor		("xmm2","xmm3");
-+
-+	&pxor		("xmm0","xmm2");
-+	&movdqu		(&QWP(16,$key),"xmm0");
-+
-+	&mov		($rounds,9);
-+	&mov		(&DWP(96,$key),$rounds);
-+
-+	&jmp	(&label("good_key"));
-+
-+&set_label("12rounds",16);
-+	&movq		("xmm2",&QWP(16,"eax"));	# remaining 1/3 of *userKey
-+	&cmp		("ebp",1<<28);
-+	&je		(&label("12rounds_alt"));
-+
-+	&mov		($rounds,11);
-+	&$movekey	(&QWP(-16,$key),"xmm0");	# round 0
-+	&aeskeygenassist("xmm1","xmm2",0x01);		# round 1,2
-+	&call		(&label("key_192a_cold"));
-+	&aeskeygenassist("xmm1","xmm2",0x02);		# round 2,3
-+	&call		(&label("key_192b"));
-+	&aeskeygenassist("xmm1","xmm2",0x04);		# round 4,5
-+	&call		(&label("key_192a"));
-+	&aeskeygenassist("xmm1","xmm2",0x08);		# round 5,6
-+	&call		(&label("key_192b"));
-+	&aeskeygenassist("xmm1","xmm2",0x10);		# round 7,8
-+	&call		(&label("key_192a"));
-+	&aeskeygenassist("xmm1","xmm2",0x20);		# round 8,9
-+	&call		(&label("key_192b"));
-+	&aeskeygenassist("xmm1","xmm2",0x40);		# round 10,11
-+	&call		(&label("key_192a"));
-+	&aeskeygenassist("xmm1","xmm2",0x80);		# round 11,12
-+	&call		(&label("key_192b"));
-+	&$movekey	(&QWP(0,$key),"xmm0");
-+	&mov		(&DWP(48,$key),$rounds);
-+
-+	&jmp	(&label("good_key"));
-+
-+&set_label("key_192a",16);
-+	&$movekey	(&QWP(0,$key),"xmm0");
-+	&lea		($key,&DWP(16,$key));
-+&set_label("key_192a_cold",16);
-+	&movaps		("xmm5","xmm2");
-+&set_label("key_192b_warm");
-+	&shufps		("xmm4","xmm0",0b00010000);
-+	&movdqa		("xmm3","xmm2");
-+	&xorps		("xmm0","xmm4");
-+	&shufps		("xmm4","xmm0",0b10001100);
-+	&pslldq		("xmm3",4);
-+	&xorps		("xmm0","xmm4");
-+	&pshufd		("xmm1","xmm1",0b01010101);	# critical path
-+	&pxor		("xmm2","xmm3");
-+	&pxor		("xmm0","xmm1");
-+	&pshufd		("xmm3","xmm0",0b11111111);
-+	&pxor		("xmm2","xmm3");
-+	&ret();
-+
-+&set_label("key_192b",16);
-+	&movaps		("xmm3","xmm0");
-+	&shufps		("xmm5","xmm0",0b01000100);
-+	&$movekey	(&QWP(0,$key),"xmm5");
-+	&shufps		("xmm3","xmm2",0b01001110);
-+	&$movekey	(&QWP(16,$key),"xmm3");
-+	&lea		($key,&DWP(32,$key));
-+	&jmp		(&label("key_192b_warm"));
-+
-+&set_label("12rounds_alt",16);
-+	&movdqa		("xmm5",&QWP(0x10,"ebx"));
-+	&movdqa		("xmm4",&QWP(0x20,"ebx"));
-+	&mov		($rounds,8);
-+	&movdqu		(&QWP(-16,$key),"xmm0");
-+
-+&set_label("loop_key192");
-+	&movq		(&QWP(0,$key),"xmm2");
-+	&movdqa		("xmm1","xmm2");
-+	&pshufb		("xmm2","xmm5");
-+	&aesenclast	("xmm2","xmm4");
-+	&pslld		("xmm4",1);
-+	&lea		($key,&DWP(24,$key));
-+
-+	&movdqa		("xmm3","xmm0");
-+	&pslldq		("xmm0",4);
-+	&pxor		("xmm3","xmm0");
-+	&pslldq		("xmm0",4);
-+	&pxor		("xmm3","xmm0");
-+	&pslldq		("xmm0",4);
-+	&pxor		("xmm0","xmm3");
-+
-+	&pshufd		("xmm3","xmm0",0xff);
-+	&pxor		("xmm3","xmm1");
-+	&pslldq		("xmm1",4);
-+	&pxor		("xmm3","xmm1");
-+
-+	&pxor		("xmm0","xmm2");
-+	&pxor		("xmm2","xmm3");
-+	&movdqu		(&QWP(-16,$key),"xmm0");
-+
-+	&dec		($rounds);
-+	&jnz		(&label("loop_key192"));
-+
-+	&mov	($rounds,11);
-+	&mov	(&DWP(32,$key),$rounds);
-+
-+	&jmp	(&label("good_key"));
-+
-+&set_label("14rounds",16);
-+	&movups		("xmm2",&QWP(16,"eax"));	# remaining half of *userKey
-+	&lea		($key,&DWP(16,$key));
-+	&cmp		("ebp",1<<28);
-+	&je		(&label("14rounds_alt"));
-+
-+	&mov		($rounds,13);
-+	&$movekey	(&QWP(-32,$key),"xmm0");	# round 0
-+	&$movekey	(&QWP(-16,$key),"xmm2");	# round 1
-+	&aeskeygenassist("xmm1","xmm2",0x01);		# round 2
-+	&call		(&label("key_256a_cold"));
-+	&aeskeygenassist("xmm1","xmm0",0x01);		# round 3
-+	&call		(&label("key_256b"));
-+	&aeskeygenassist("xmm1","xmm2",0x02);		# round 4
-+	&call		(&label("key_256a"));
-+	&aeskeygenassist("xmm1","xmm0",0x02);		# round 5
-+	&call		(&label("key_256b"));
-+	&aeskeygenassist("xmm1","xmm2",0x04);		# round 6
-+	&call		(&label("key_256a"));
-+	&aeskeygenassist("xmm1","xmm0",0x04);		# round 7
-+	&call		(&label("key_256b"));
-+	&aeskeygenassist("xmm1","xmm2",0x08);		# round 8
-+	&call		(&label("key_256a"));
-+	&aeskeygenassist("xmm1","xmm0",0x08);		# round 9
-+	&call		(&label("key_256b"));
-+	&aeskeygenassist("xmm1","xmm2",0x10);		# round 10
-+	&call		(&label("key_256a"));
-+	&aeskeygenassist("xmm1","xmm0",0x10);		# round 11
-+	&call		(&label("key_256b"));
-+	&aeskeygenassist("xmm1","xmm2",0x20);		# round 12
-+	&call		(&label("key_256a"));
-+	&aeskeygenassist("xmm1","xmm0",0x20);		# round 13
-+	&call		(&label("key_256b"));
-+	&aeskeygenassist("xmm1","xmm2",0x40);		# round 14
-+	&call		(&label("key_256a"));
-+	&$movekey	(&QWP(0,$key),"xmm0");
-+	&mov		(&DWP(16,$key),$rounds);
-+	&xor		("eax","eax");
-+
-+	&jmp	(&label("good_key"));
-+
-+&set_label("key_256a",16);
-+	&$movekey	(&QWP(0,$key),"xmm2");
-+	&lea		($key,&DWP(16,$key));
-+&set_label("key_256a_cold");
-+	&shufps		("xmm4","xmm0",0b00010000);
-+	&xorps		("xmm0","xmm4");
-+	&shufps		("xmm4","xmm0",0b10001100);
-+	&xorps		("xmm0","xmm4");
-+	&shufps		("xmm1","xmm1",0b11111111);	# critical path
-+	&xorps		("xmm0","xmm1");
-+	&ret();
-+
-+&set_label("key_256b",16);
-+	&$movekey	(&QWP(0,$key),"xmm0");
-+	&lea		($key,&DWP(16,$key));
-+
-+	&shufps		("xmm4","xmm2",0b00010000);
-+	&xorps		("xmm2","xmm4");
-+	&shufps		("xmm4","xmm2",0b10001100);
-+	&xorps		("xmm2","xmm4");
-+	&shufps		("xmm1","xmm1",0b10101010);	# critical path
-+	&xorps		("xmm2","xmm1");
-+	&ret();
-+
-+&set_label("14rounds_alt",16);
-+	&movdqa		("xmm5",&QWP(0x00,"ebx"));
-+	&movdqa		("xmm4",&QWP(0x20,"ebx"));
-+	&mov		($rounds,7);
-+	&movdqu		(&QWP(-32,$key),"xmm0");
-+	&movdqa		("xmm1","xmm2");
-+	&movdqu		(&QWP(-16,$key),"xmm2");
-+
-+&set_label("loop_key256");
-+	&pshufb		("xmm2","xmm5");
-+	&aesenclast	("xmm2","xmm4");
-+
-+	&movdqa		("xmm3","xmm0");
-+	&pslldq		("xmm0",4);
-+	&pxor		("xmm3","xmm0");
-+	&pslldq		("xmm0",4);
-+	&pxor		("xmm3","xmm0");
-+	&pslldq		("xmm0",4);
-+	&pxor		("xmm0","xmm3");
-+	&pslld		("xmm4",1);
-+
-+	&pxor		("xmm0","xmm2");
-+	&movdqu		(&QWP(0,$key),"xmm0");
-+
-+	&dec		($rounds);
-+	&jz		(&label("done_key256"));
-+
-+	&pshufd		("xmm2","xmm0",0xff);
-+	&pxor		("xmm3","xmm3");
-+	&aesenclast	("xmm2","xmm3");
-+
-+	&movdqa		("xmm3","xmm1");
-+	&pslldq		("xmm1",4);
-+	&pxor		("xmm3","xmm1");
-+	&pslldq		("xmm1",4);
-+	&pxor		("xmm3","xmm1");
-+	&pslldq		("xmm1",4);
-+	&pxor		("xmm1","xmm3");
-+
-+	&pxor		("xmm2","xmm1");
-+	&movdqu		(&QWP(16,$key),"xmm2");
-+	&lea		($key,&DWP(32,$key));
-+	&movdqa		("xmm1","xmm2");
-+	&jmp		(&label("loop_key256"));
-+
-+&set_label("done_key256");
-+	&mov		($rounds,13);
-+	&mov		(&DWP(16,$key),$rounds);
-+
-+&set_label("good_key");
-+	&pxor	("xmm0","xmm0");
-+	&pxor	("xmm1","xmm1");
-+	&pxor	("xmm2","xmm2");
-+	&pxor	("xmm3","xmm3");
-+	&pxor	("xmm4","xmm4");
-+	&pxor	("xmm5","xmm5");
-+	&xor	("eax","eax");
-+	&pop	("ebx");
-+	&pop	("ebp");
-+	&ret	();
-+
-+&set_label("bad_pointer",4);
-+	&mov	("eax",-1);
-+	&pop	("ebx");
-+	&pop	("ebp");
-+	&ret	();
-+&set_label("bad_keybits",4);
-+	&pxor	("xmm0","xmm0");
-+	&mov	("eax",-2);
-+	&pop	("ebx");
-+	&pop	("ebp");
-+	&ret	();
-+&function_end_B("_aesni_set_encrypt_key");
-+
-+# int $PREFIX_set_encrypt_key (const unsigned char *userKey, int bits,
-+#                              AES_KEY *key)
-+&function_begin_B("${PREFIX}_set_encrypt_key");
-+	&mov	("eax",&wparam(0));
-+	&mov	($rounds,&wparam(1));
-+	&mov	($key,&wparam(2));
-+	&call	("_aesni_set_encrypt_key");
-+	&ret	();
-+&function_end_B("${PREFIX}_set_encrypt_key");
-+
-+# int $PREFIX_set_decrypt_key (const unsigned char *userKey, int bits,
-+#                              AES_KEY *key)
-+&function_begin_B("${PREFIX}_set_decrypt_key");
-+	&mov	("eax",&wparam(0));
-+	&mov	($rounds,&wparam(1));
-+	&mov	($key,&wparam(2));
-+	&call	("_aesni_set_encrypt_key");
-+	&mov	($key,&wparam(2));
-+	&shl	($rounds,4);	# rounds-1 after _aesni_set_encrypt_key
-+	&test	("eax","eax");
-+	&jnz	(&label("dec_key_ret"));
-+	&lea	("eax",&DWP(16,$key,$rounds));	# end of key schedule
-+
-+	&$movekey	("xmm0",&QWP(0,$key));	# just swap
-+	&$movekey	("xmm1",&QWP(0,"eax"));
-+	&$movekey	(&QWP(0,"eax"),"xmm0");
-+	&$movekey	(&QWP(0,$key),"xmm1");
-+	&lea		($key,&DWP(16,$key));
-+	&lea		("eax",&DWP(-16,"eax"));
-+
-+&set_label("dec_key_inverse");
-+	&$movekey	("xmm0",&QWP(0,$key));	# swap and inverse
-+	&$movekey	("xmm1",&QWP(0,"eax"));
-+	&aesimc		("xmm0","xmm0");
-+	&aesimc		("xmm1","xmm1");
-+	&lea		($key,&DWP(16,$key));
-+	&lea		("eax",&DWP(-16,"eax"));
-+	&$movekey	(&QWP(16,"eax"),"xmm0");
-+	&$movekey	(&QWP(-16,$key),"xmm1");
-+	&cmp		("eax",$key);
-+	&ja		(&label("dec_key_inverse"));
-+
-+	&$movekey	("xmm0",&QWP(0,$key));	# inverse middle
-+	&aesimc		("xmm0","xmm0");
-+	&$movekey	(&QWP(0,$key),"xmm0");
-+
-+	&pxor		("xmm0","xmm0");
-+	&pxor		("xmm1","xmm1");
-+	&xor		("eax","eax");		# return success
-+&set_label("dec_key_ret");
-+	&ret	();
-+&function_end_B("${PREFIX}_set_decrypt_key");
-+
-+&set_label("key_const",64);
-+&data_word(0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d);
-+&data_word(0x04070605,0x04070605,0x04070605,0x04070605);
-+&data_word(1,1,1,1);
-+&data_word(0x1b,0x1b,0x1b,0x1b);
-+&asciz("AES for Intel AES-NI, CRYPTOGAMS by ");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-x86_64.pl
-new file mode 100644
-index 0000000..98ca179
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesni-x86_64.pl
-@@ -0,0 +1,5060 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements support for Intel AES-NI extension. In
-+# OpenSSL context it's used with Intel engine, but can also be used as
-+# drop-in replacement for crypto/aes/asm/aes-x86_64.pl [see below for
-+# details].
-+#
-+# Performance.
-+#
-+# Given aes(enc|dec) instructions' latency asymptotic performance for
-+# non-parallelizable modes such as CBC encrypt is 3.75 cycles per byte
-+# processed with 128-bit key. And given their throughput asymptotic
-+# performance for parallelizable modes is 1.25 cycles per byte. Being
-+# asymptotic limit it's not something you commonly achieve in reality,
-+# but how close does one get? Below are results collected for
-+# different modes and block sized. Pairs of numbers are for en-/
-+# decryption.
-+#
-+#	16-byte     64-byte     256-byte    1-KB        8-KB
-+# ECB	4.25/4.25   1.38/1.38   1.28/1.28   1.26/1.26	1.26/1.26
-+# CTR	5.42/5.42   1.92/1.92   1.44/1.44   1.28/1.28   1.26/1.26
-+# CBC	4.38/4.43   4.15/1.43   4.07/1.32   4.07/1.29   4.06/1.28
-+# CCM	5.66/9.42   4.42/5.41   4.16/4.40   4.09/4.15   4.06/4.07   
-+# OFB	5.42/5.42   4.64/4.64   4.44/4.44   4.39/4.39   4.38/4.38
-+# CFB	5.73/5.85   5.56/5.62   5.48/5.56   5.47/5.55   5.47/5.55
-+#
-+# ECB, CTR, CBC and CCM results are free from EVP overhead. This means
-+# that otherwise used 'openssl speed -evp aes-128-??? -engine aesni
-+# [-decrypt]' will exhibit 10-15% worse results for smaller blocks.
-+# The results were collected with specially crafted speed.c benchmark
-+# in order to compare them with results reported in "Intel Advanced
-+# Encryption Standard (AES) New Instruction Set" White Paper Revision
-+# 3.0 dated May 2010. All above results are consistently better. This
-+# module also provides better performance for block sizes smaller than
-+# 128 bytes in points *not* represented in the above table.
-+#
-+# Looking at the results for 8-KB buffer.
-+#
-+# CFB and OFB results are far from the limit, because implementation
-+# uses "generic" CRYPTO_[c|o]fb128_encrypt interfaces relying on
-+# single-block aesni_encrypt, which is not the most optimal way to go.
-+# CBC encrypt result is unexpectedly high and there is no documented
-+# explanation for it. Seemingly there is a small penalty for feeding
-+# the result back to AES unit the way it's done in CBC mode. There is
-+# nothing one can do and the result appears optimal. CCM result is
-+# identical to CBC, because CBC-MAC is essentially CBC encrypt without
-+# saving output. CCM CTR "stays invisible," because it's neatly
-+# interleaved wih CBC-MAC. This provides ~30% improvement over
-+# "straghtforward" CCM implementation with CTR and CBC-MAC performed
-+# disjointly. Parallelizable modes practically achieve the theoretical
-+# limit.
-+#
-+# Looking at how results vary with buffer size.
-+#
-+# Curves are practically saturated at 1-KB buffer size. In most cases
-+# "256-byte" performance is >95%, and "64-byte" is ~90% of "8-KB" one.
-+# CTR curve doesn't follow this pattern and is "slowest" changing one
-+# with "256-byte" result being 87% of "8-KB." This is because overhead
-+# in CTR mode is most computationally intensive. Small-block CCM
-+# decrypt is slower than encrypt, because first CTR and last CBC-MAC
-+# iterations can't be interleaved.
-+#
-+# Results for 192- and 256-bit keys.
-+#
-+# EVP-free results were observed to scale perfectly with number of
-+# rounds for larger block sizes, i.e. 192-bit result being 10/12 times
-+# lower and 256-bit one - 10/14. Well, in CBC encrypt case differences
-+# are a tad smaller, because the above mentioned penalty biases all
-+# results by same constant value. In similar way function call
-+# overhead affects small-block performance, as well as OFB and CFB
-+# results. Differences are not large, most common coefficients are
-+# 10/11.7 and 10/13.4 (as opposite to 10/12.0 and 10/14.0), but one
-+# observe even 10/11.2 and 10/12.4 (CTR, OFB, CFB)...
-+
-+# January 2011
-+#
-+# While Westmere processor features 6 cycles latency for aes[enc|dec]
-+# instructions, which can be scheduled every second cycle, Sandy
-+# Bridge spends 8 cycles per instruction, but it can schedule them
-+# every cycle. This means that code targeting Westmere would perform
-+# suboptimally on Sandy Bridge. Therefore this update.
-+#
-+# In addition, non-parallelizable CBC encrypt (as well as CCM) is
-+# optimized. Relative improvement might appear modest, 8% on Westmere,
-+# but in absolute terms it's 3.77 cycles per byte encrypted with
-+# 128-bit key on Westmere, and 5.07 - on Sandy Bridge. These numbers
-+# should be compared to asymptotic limits of 3.75 for Westmere and
-+# 5.00 for Sandy Bridge. Actually, the fact that they get this close
-+# to asymptotic limits is quite amazing. Indeed, the limit is
-+# calculated as latency times number of rounds, 10 for 128-bit key,
-+# and divided by 16, the number of bytes in block, or in other words
-+# it accounts *solely* for aesenc instructions. But there are extra
-+# instructions, and numbers so close to the asymptotic limits mean
-+# that it's as if it takes as little as *one* additional cycle to
-+# execute all of them. How is it possible? It is possible thanks to
-+# out-of-order execution logic, which manages to overlap post-
-+# processing of previous block, things like saving the output, with
-+# actual encryption of current block, as well as pre-processing of
-+# current block, things like fetching input and xor-ing it with
-+# 0-round element of the key schedule, with actual encryption of
-+# previous block. Keep this in mind...
-+#
-+# For parallelizable modes, such as ECB, CBC decrypt, CTR, higher
-+# performance is achieved by interleaving instructions working on
-+# independent blocks. In which case asymptotic limit for such modes
-+# can be obtained by dividing above mentioned numbers by AES
-+# instructions' interleave factor. Westmere can execute at most 3 
-+# instructions at a time, meaning that optimal interleave factor is 3,
-+# and that's where the "magic" number of 1.25 come from. "Optimal
-+# interleave factor" means that increase of interleave factor does
-+# not improve performance. The formula has proven to reflect reality
-+# pretty well on Westmere... Sandy Bridge on the other hand can
-+# execute up to 8 AES instructions at a time, so how does varying
-+# interleave factor affect the performance? Here is table for ECB
-+# (numbers are cycles per byte processed with 128-bit key):
-+#
-+# instruction interleave factor		3x	6x	8x
-+# theoretical asymptotic limit		1.67	0.83	0.625
-+# measured performance for 8KB block	1.05	0.86	0.84
-+#
-+# "as if" interleave factor		4.7x	5.8x	6.0x
-+#
-+# Further data for other parallelizable modes:
-+#
-+# CBC decrypt				1.16	0.93	0.74
-+# CTR					1.14	0.91	0.74
-+#
-+# Well, given 3x column it's probably inappropriate to call the limit
-+# asymptotic, if it can be surpassed, isn't it? What happens there?
-+# Rewind to CBC paragraph for the answer. Yes, out-of-order execution
-+# magic is responsible for this. Processor overlaps not only the
-+# additional instructions with AES ones, but even AES instuctions
-+# processing adjacent triplets of independent blocks. In the 6x case
-+# additional instructions  still claim disproportionally small amount
-+# of additional cycles, but in 8x case number of instructions must be
-+# a tad too high for out-of-order logic to cope with, and AES unit
-+# remains underutilized... As you can see 8x interleave is hardly
-+# justifiable, so there no need to feel bad that 32-bit aesni-x86.pl
-+# utilizies 6x interleave because of limited register bank capacity.
-+#
-+# Higher interleave factors do have negative impact on Westmere
-+# performance. While for ECB mode it's negligible ~1.5%, other
-+# parallelizables perform ~5% worse, which is outweighed by ~25%
-+# improvement on Sandy Bridge. To balance regression on Westmere
-+# CTR mode was implemented with 6x aesenc interleave factor.
-+
-+# April 2011
-+#
-+# Add aesni_xts_[en|de]crypt. Westmere spends 1.25 cycles processing
-+# one byte out of 8KB with 128-bit key, Sandy Bridge - 0.90. Just like
-+# in CTR mode AES instruction interleave factor was chosen to be 6x.
-+
-+# November 2015
-+#
-+# Add aesni_ocb_[en|de]crypt. AES instruction interleave factor was
-+# chosen to be 6x.
-+
-+######################################################################
-+# Current large-block performance in cycles per byte processed with
-+# 128-bit key (less is better).
-+#
-+#		CBC en-/decrypt	CTR	XTS	ECB	OCB
-+# Westmere	3.77/1.25	1.25	1.25	1.26
-+# * Bridge	5.07/0.74	0.75	0.90	0.85	0.98
-+# Haswell	4.44/0.63	0.63	0.73	0.63	0.70
-+# Skylake	2.62/0.63	0.63	0.63	0.63
-+# Silvermont	5.75/3.54	3.56	4.12	3.87(*)	4.11
-+# Goldmont	3.82/1.26	1.26	1.29	1.29	1.50
-+# Bulldozer	5.77/0.70	0.72	0.90	0.70	0.95
-+#
-+# (*)	Atom Silvermont ECB result is suboptimal because of penalties
-+#	incurred by operations on %xmm8-15. As ECB is not considered
-+#	critical, nothing was done to mitigate the problem.
-+
-+$PREFIX="aesni";	# if $PREFIX is set to "AES", the script
-+			# generates drop-in replacement for
-+			# crypto/aes/asm/aes-x86_64.pl:-)
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+$movkey = $PREFIX eq "aesni" ? "movups" : "movups";
-+@_4args=$win64?	("%rcx","%rdx","%r8", "%r9") :	# Win64 order
-+		("%rdi","%rsi","%rdx","%rcx");	# Unix order
-+
-+$code=".text\n";
-+$code.=".extern	OPENSSL_ia32cap_P\n";
-+
-+$rounds="%eax";	# input to and changed by aesni_[en|de]cryptN !!!
-+# this is natural Unix argument order for public $PREFIX_[ecb|cbc]_encrypt ...
-+$inp="%rdi";
-+$out="%rsi";
-+$len="%rdx";
-+$key="%rcx";	# input to and changed by aesni_[en|de]cryptN !!!
-+$ivp="%r8";	# cbc, ctr, ...
-+
-+$rnds_="%r10d";	# backup copy for $rounds
-+$key_="%r11";	# backup copy for $key
-+
-+# %xmm register layout
-+$rndkey0="%xmm0";	$rndkey1="%xmm1";
-+$inout0="%xmm2";	$inout1="%xmm3";
-+$inout2="%xmm4";	$inout3="%xmm5";
-+$inout4="%xmm6";	$inout5="%xmm7";
-+$inout6="%xmm8";	$inout7="%xmm9";
-+
-+$in2="%xmm6";		$in1="%xmm7";	# used in CBC decrypt, CTR, ...
-+$in0="%xmm8";		$iv="%xmm9";
-+
-+# Inline version of internal aesni_[en|de]crypt1.
-+#
-+# Why folded loop? Because aes[enc|dec] is slow enough to accommodate
-+# cycles which take care of loop variables...
-+{ my $sn;
-+sub aesni_generate1 {
-+my ($p,$key,$rounds,$inout,$ivec)=@_;	$inout=$inout0 if (!defined($inout));
-+++$sn;
-+$code.=<<___;
-+	$movkey	($key),$rndkey0
-+	$movkey	16($key),$rndkey1
-+___
-+$code.=<<___ if (defined($ivec));
-+	xorps	$rndkey0,$ivec
-+	lea	32($key),$key
-+	xorps	$ivec,$inout
-+___
-+$code.=<<___ if (!defined($ivec));
-+	lea	32($key),$key
-+	xorps	$rndkey0,$inout
-+___
-+$code.=<<___;
-+.Loop_${p}1_$sn:
-+	aes${p}	$rndkey1,$inout
-+	dec	$rounds
-+	$movkey	($key),$rndkey1
-+	lea	16($key),$key
-+	jnz	.Loop_${p}1_$sn	# loop body is 16 bytes
-+	aes${p}last	$rndkey1,$inout
-+___
-+}}
-+# void $PREFIX_[en|de]crypt (const void *inp,void *out,const AES_KEY *key);
-+#
-+{ my ($inp,$out,$key) = @_4args;
-+
-+$code.=<<___;
-+.globl	${PREFIX}_encrypt
-+.type	${PREFIX}_encrypt,\@abi-omnipotent
-+.align	16
-+${PREFIX}_encrypt:
-+	movups	($inp),$inout0		# load input
-+	mov	240($key),$rounds	# key->rounds
-+___
-+	&aesni_generate1("enc",$key,$rounds);
-+$code.=<<___;
-+	 pxor	$rndkey0,$rndkey0	# clear register bank
-+	 pxor	$rndkey1,$rndkey1
-+	movups	$inout0,($out)		# output
-+	 pxor	$inout0,$inout0
-+	ret
-+.size	${PREFIX}_encrypt,.-${PREFIX}_encrypt
-+
-+.globl	${PREFIX}_decrypt
-+.type	${PREFIX}_decrypt,\@abi-omnipotent
-+.align	16
-+${PREFIX}_decrypt:
-+	movups	($inp),$inout0		# load input
-+	mov	240($key),$rounds	# key->rounds
-+___
-+	&aesni_generate1("dec",$key,$rounds);
-+$code.=<<___;
-+	 pxor	$rndkey0,$rndkey0	# clear register bank
-+	 pxor	$rndkey1,$rndkey1
-+	movups	$inout0,($out)		# output
-+	 pxor	$inout0,$inout0
-+	ret
-+.size	${PREFIX}_decrypt, .-${PREFIX}_decrypt
-+___
-+}
-+
-+# _aesni_[en|de]cryptN are private interfaces, N denotes interleave
-+# factor. Why 3x subroutine were originally used in loops? Even though
-+# aes[enc|dec] latency was originally 6, it could be scheduled only
-+# every *2nd* cycle. Thus 3x interleave was the one providing optimal
-+# utilization, i.e. when subroutine's throughput is virtually same as
-+# of non-interleaved subroutine [for number of input blocks up to 3].
-+# This is why it originally made no sense to implement 2x subroutine.
-+# But times change and it became appropriate to spend extra 192 bytes
-+# on 2x subroutine on Atom Silvermont account. For processors that
-+# can schedule aes[enc|dec] every cycle optimal interleave factor
-+# equals to corresponding instructions latency. 8x is optimal for
-+# * Bridge and "super-optimal" for other Intel CPUs... 
-+
-+sub aesni_generate2 {
-+my $dir=shift;
-+# As already mentioned it takes in $key and $rounds, which are *not*
-+# preserved. $inout[0-1] is cipher/clear text...
-+$code.=<<___;
-+.type	_aesni_${dir}rypt2,\@abi-omnipotent
-+.align	16
-+_aesni_${dir}rypt2:
-+	$movkey	($key),$rndkey0
-+	shl	\$4,$rounds
-+	$movkey	16($key),$rndkey1
-+	xorps	$rndkey0,$inout0
-+	xorps	$rndkey0,$inout1
-+	$movkey	32($key),$rndkey0
-+	lea	32($key,$rounds),$key
-+	neg	%rax				# $rounds
-+	add	\$16,%rax
-+
-+.L${dir}_loop2:
-+	aes${dir}	$rndkey1,$inout0
-+	aes${dir}	$rndkey1,$inout1
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+	aes${dir}	$rndkey0,$inout0
-+	aes${dir}	$rndkey0,$inout1
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.L${dir}_loop2
-+
-+	aes${dir}	$rndkey1,$inout0
-+	aes${dir}	$rndkey1,$inout1
-+	aes${dir}last	$rndkey0,$inout0
-+	aes${dir}last	$rndkey0,$inout1
-+	ret
-+.size	_aesni_${dir}rypt2,.-_aesni_${dir}rypt2
-+___
-+}
-+sub aesni_generate3 {
-+my $dir=shift;
-+# As already mentioned it takes in $key and $rounds, which are *not*
-+# preserved. $inout[0-2] is cipher/clear text...
-+$code.=<<___;
-+.type	_aesni_${dir}rypt3,\@abi-omnipotent
-+.align	16
-+_aesni_${dir}rypt3:
-+	$movkey	($key),$rndkey0
-+	shl	\$4,$rounds
-+	$movkey	16($key),$rndkey1
-+	xorps	$rndkey0,$inout0
-+	xorps	$rndkey0,$inout1
-+	xorps	$rndkey0,$inout2
-+	$movkey	32($key),$rndkey0
-+	lea	32($key,$rounds),$key
-+	neg	%rax				# $rounds
-+	add	\$16,%rax
-+
-+.L${dir}_loop3:
-+	aes${dir}	$rndkey1,$inout0
-+	aes${dir}	$rndkey1,$inout1
-+	aes${dir}	$rndkey1,$inout2
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+	aes${dir}	$rndkey0,$inout0
-+	aes${dir}	$rndkey0,$inout1
-+	aes${dir}	$rndkey0,$inout2
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.L${dir}_loop3
-+
-+	aes${dir}	$rndkey1,$inout0
-+	aes${dir}	$rndkey1,$inout1
-+	aes${dir}	$rndkey1,$inout2
-+	aes${dir}last	$rndkey0,$inout0
-+	aes${dir}last	$rndkey0,$inout1
-+	aes${dir}last	$rndkey0,$inout2
-+	ret
-+.size	_aesni_${dir}rypt3,.-_aesni_${dir}rypt3
-+___
-+}
-+# 4x interleave is implemented to improve small block performance,
-+# most notably [and naturally] 4 block by ~30%. One can argue that one
-+# should have implemented 5x as well, but improvement would be <20%,
-+# so it's not worth it...
-+sub aesni_generate4 {
-+my $dir=shift;
-+# As already mentioned it takes in $key and $rounds, which are *not*
-+# preserved. $inout[0-3] is cipher/clear text...
-+$code.=<<___;
-+.type	_aesni_${dir}rypt4,\@abi-omnipotent
-+.align	16
-+_aesni_${dir}rypt4:
-+	$movkey	($key),$rndkey0
-+	shl	\$4,$rounds
-+	$movkey	16($key),$rndkey1
-+	xorps	$rndkey0,$inout0
-+	xorps	$rndkey0,$inout1
-+	xorps	$rndkey0,$inout2
-+	xorps	$rndkey0,$inout3
-+	$movkey	32($key),$rndkey0
-+	lea	32($key,$rounds),$key
-+	neg	%rax				# $rounds
-+	.byte	0x0f,0x1f,0x00
-+	add	\$16,%rax
-+
-+.L${dir}_loop4:
-+	aes${dir}	$rndkey1,$inout0
-+	aes${dir}	$rndkey1,$inout1
-+	aes${dir}	$rndkey1,$inout2
-+	aes${dir}	$rndkey1,$inout3
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+	aes${dir}	$rndkey0,$inout0
-+	aes${dir}	$rndkey0,$inout1
-+	aes${dir}	$rndkey0,$inout2
-+	aes${dir}	$rndkey0,$inout3
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.L${dir}_loop4
-+
-+	aes${dir}	$rndkey1,$inout0
-+	aes${dir}	$rndkey1,$inout1
-+	aes${dir}	$rndkey1,$inout2
-+	aes${dir}	$rndkey1,$inout3
-+	aes${dir}last	$rndkey0,$inout0
-+	aes${dir}last	$rndkey0,$inout1
-+	aes${dir}last	$rndkey0,$inout2
-+	aes${dir}last	$rndkey0,$inout3
-+	ret
-+.size	_aesni_${dir}rypt4,.-_aesni_${dir}rypt4
-+___
-+}
-+sub aesni_generate6 {
-+my $dir=shift;
-+# As already mentioned it takes in $key and $rounds, which are *not*
-+# preserved. $inout[0-5] is cipher/clear text...
-+$code.=<<___;
-+.type	_aesni_${dir}rypt6,\@abi-omnipotent
-+.align	16
-+_aesni_${dir}rypt6:
-+	$movkey		($key),$rndkey0
-+	shl		\$4,$rounds
-+	$movkey		16($key),$rndkey1
-+	xorps		$rndkey0,$inout0
-+	pxor		$rndkey0,$inout1
-+	pxor		$rndkey0,$inout2
-+	aes${dir}	$rndkey1,$inout0
-+	lea		32($key,$rounds),$key
-+	neg		%rax			# $rounds
-+	aes${dir}	$rndkey1,$inout1
-+	pxor		$rndkey0,$inout3
-+	pxor		$rndkey0,$inout4
-+	aes${dir}	$rndkey1,$inout2
-+	pxor		$rndkey0,$inout5
-+	$movkey		($key,%rax),$rndkey0
-+	add		\$16,%rax
-+	jmp		.L${dir}_loop6_enter
-+.align	16
-+.L${dir}_loop6:
-+	aes${dir}	$rndkey1,$inout0
-+	aes${dir}	$rndkey1,$inout1
-+	aes${dir}	$rndkey1,$inout2
-+.L${dir}_loop6_enter:
-+	aes${dir}	$rndkey1,$inout3
-+	aes${dir}	$rndkey1,$inout4
-+	aes${dir}	$rndkey1,$inout5
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+	aes${dir}	$rndkey0,$inout0
-+	aes${dir}	$rndkey0,$inout1
-+	aes${dir}	$rndkey0,$inout2
-+	aes${dir}	$rndkey0,$inout3
-+	aes${dir}	$rndkey0,$inout4
-+	aes${dir}	$rndkey0,$inout5
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.L${dir}_loop6
-+
-+	aes${dir}	$rndkey1,$inout0
-+	aes${dir}	$rndkey1,$inout1
-+	aes${dir}	$rndkey1,$inout2
-+	aes${dir}	$rndkey1,$inout3
-+	aes${dir}	$rndkey1,$inout4
-+	aes${dir}	$rndkey1,$inout5
-+	aes${dir}last	$rndkey0,$inout0
-+	aes${dir}last	$rndkey0,$inout1
-+	aes${dir}last	$rndkey0,$inout2
-+	aes${dir}last	$rndkey0,$inout3
-+	aes${dir}last	$rndkey0,$inout4
-+	aes${dir}last	$rndkey0,$inout5
-+	ret
-+.size	_aesni_${dir}rypt6,.-_aesni_${dir}rypt6
-+___
-+}
-+sub aesni_generate8 {
-+my $dir=shift;
-+# As already mentioned it takes in $key and $rounds, which are *not*
-+# preserved. $inout[0-7] is cipher/clear text...
-+$code.=<<___;
-+.type	_aesni_${dir}rypt8,\@abi-omnipotent
-+.align	16
-+_aesni_${dir}rypt8:
-+	$movkey		($key),$rndkey0
-+	shl		\$4,$rounds
-+	$movkey		16($key),$rndkey1
-+	xorps		$rndkey0,$inout0
-+	xorps		$rndkey0,$inout1
-+	pxor		$rndkey0,$inout2
-+	pxor		$rndkey0,$inout3
-+	pxor		$rndkey0,$inout4
-+	lea		32($key,$rounds),$key
-+	neg		%rax			# $rounds
-+	aes${dir}	$rndkey1,$inout0
-+	pxor		$rndkey0,$inout5
-+	pxor		$rndkey0,$inout6
-+	aes${dir}	$rndkey1,$inout1
-+	pxor		$rndkey0,$inout7
-+	$movkey		($key,%rax),$rndkey0
-+	add		\$16,%rax
-+	jmp		.L${dir}_loop8_inner
-+.align	16
-+.L${dir}_loop8:
-+	aes${dir}	$rndkey1,$inout0
-+	aes${dir}	$rndkey1,$inout1
-+.L${dir}_loop8_inner:
-+	aes${dir}	$rndkey1,$inout2
-+	aes${dir}	$rndkey1,$inout3
-+	aes${dir}	$rndkey1,$inout4
-+	aes${dir}	$rndkey1,$inout5
-+	aes${dir}	$rndkey1,$inout6
-+	aes${dir}	$rndkey1,$inout7
-+.L${dir}_loop8_enter:
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+	aes${dir}	$rndkey0,$inout0
-+	aes${dir}	$rndkey0,$inout1
-+	aes${dir}	$rndkey0,$inout2
-+	aes${dir}	$rndkey0,$inout3
-+	aes${dir}	$rndkey0,$inout4
-+	aes${dir}	$rndkey0,$inout5
-+	aes${dir}	$rndkey0,$inout6
-+	aes${dir}	$rndkey0,$inout7
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.L${dir}_loop8
-+
-+	aes${dir}	$rndkey1,$inout0
-+	aes${dir}	$rndkey1,$inout1
-+	aes${dir}	$rndkey1,$inout2
-+	aes${dir}	$rndkey1,$inout3
-+	aes${dir}	$rndkey1,$inout4
-+	aes${dir}	$rndkey1,$inout5
-+	aes${dir}	$rndkey1,$inout6
-+	aes${dir}	$rndkey1,$inout7
-+	aes${dir}last	$rndkey0,$inout0
-+	aes${dir}last	$rndkey0,$inout1
-+	aes${dir}last	$rndkey0,$inout2
-+	aes${dir}last	$rndkey0,$inout3
-+	aes${dir}last	$rndkey0,$inout4
-+	aes${dir}last	$rndkey0,$inout5
-+	aes${dir}last	$rndkey0,$inout6
-+	aes${dir}last	$rndkey0,$inout7
-+	ret
-+.size	_aesni_${dir}rypt8,.-_aesni_${dir}rypt8
-+___
-+}
-+&aesni_generate2("enc") if ($PREFIX eq "aesni");
-+&aesni_generate2("dec");
-+&aesni_generate3("enc") if ($PREFIX eq "aesni");
-+&aesni_generate3("dec");
-+&aesni_generate4("enc") if ($PREFIX eq "aesni");
-+&aesni_generate4("dec");
-+&aesni_generate6("enc") if ($PREFIX eq "aesni");
-+&aesni_generate6("dec");
-+&aesni_generate8("enc") if ($PREFIX eq "aesni");
-+&aesni_generate8("dec");
-+
-+if ($PREFIX eq "aesni") {
-+########################################################################
-+# void aesni_ecb_encrypt (const void *in, void *out,
-+#			  size_t length, const AES_KEY *key,
-+#			  int enc);
-+$code.=<<___;
-+.globl	aesni_ecb_encrypt
-+.type	aesni_ecb_encrypt,\@function,5
-+.align	16
-+aesni_ecb_encrypt:
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0x58(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)		# offload $inout4..7
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+.Lecb_enc_body:
-+___
-+$code.=<<___;
-+	and	\$-16,$len		# if ($len<16)
-+	jz	.Lecb_ret		# return
-+
-+	mov	240($key),$rounds	# key->rounds
-+	$movkey	($key),$rndkey0
-+	mov	$key,$key_		# backup $key
-+	mov	$rounds,$rnds_		# backup $rounds
-+	test	%r8d,%r8d		# 5th argument
-+	jz	.Lecb_decrypt
-+#--------------------------- ECB ENCRYPT ------------------------------#
-+	cmp	\$0x80,$len		# if ($len<8*16)
-+	jb	.Lecb_enc_tail		# short input
-+
-+	movdqu	($inp),$inout0		# load 8 input blocks
-+	movdqu	0x10($inp),$inout1
-+	movdqu	0x20($inp),$inout2
-+	movdqu	0x30($inp),$inout3
-+	movdqu	0x40($inp),$inout4
-+	movdqu	0x50($inp),$inout5
-+	movdqu	0x60($inp),$inout6
-+	movdqu	0x70($inp),$inout7
-+	lea	0x80($inp),$inp		# $inp+=8*16
-+	sub	\$0x80,$len		# $len-=8*16 (can be zero)
-+	jmp	.Lecb_enc_loop8_enter
-+.align 16
-+.Lecb_enc_loop8:
-+	movups	$inout0,($out)		# store 8 output blocks
-+	mov	$key_,$key		# restore $key
-+	movdqu	($inp),$inout0		# load 8 input blocks
-+	mov	$rnds_,$rounds		# restore $rounds
-+	movups	$inout1,0x10($out)
-+	movdqu	0x10($inp),$inout1
-+	movups	$inout2,0x20($out)
-+	movdqu	0x20($inp),$inout2
-+	movups	$inout3,0x30($out)
-+	movdqu	0x30($inp),$inout3
-+	movups	$inout4,0x40($out)
-+	movdqu	0x40($inp),$inout4
-+	movups	$inout5,0x50($out)
-+	movdqu	0x50($inp),$inout5
-+	movups	$inout6,0x60($out)
-+	movdqu	0x60($inp),$inout6
-+	movups	$inout7,0x70($out)
-+	lea	0x80($out),$out		# $out+=8*16
-+	movdqu	0x70($inp),$inout7
-+	lea	0x80($inp),$inp		# $inp+=8*16
-+.Lecb_enc_loop8_enter:
-+
-+	call	_aesni_encrypt8
-+
-+	sub	\$0x80,$len
-+	jnc	.Lecb_enc_loop8		# loop if $len-=8*16 didn't borrow
-+
-+	movups	$inout0,($out)		# store 8 output blocks
-+	mov	$key_,$key		# restore $key
-+	movups	$inout1,0x10($out)
-+	mov	$rnds_,$rounds		# restore $rounds
-+	movups	$inout2,0x20($out)
-+	movups	$inout3,0x30($out)
-+	movups	$inout4,0x40($out)
-+	movups	$inout5,0x50($out)
-+	movups	$inout6,0x60($out)
-+	movups	$inout7,0x70($out)
-+	lea	0x80($out),$out		# $out+=8*16
-+	add	\$0x80,$len		# restore real remaining $len
-+	jz	.Lecb_ret		# done if ($len==0)
-+
-+.Lecb_enc_tail:				# $len is less than 8*16
-+	movups	($inp),$inout0
-+	cmp	\$0x20,$len
-+	jb	.Lecb_enc_one
-+	movups	0x10($inp),$inout1
-+	je	.Lecb_enc_two
-+	movups	0x20($inp),$inout2
-+	cmp	\$0x40,$len
-+	jb	.Lecb_enc_three
-+	movups	0x30($inp),$inout3
-+	je	.Lecb_enc_four
-+	movups	0x40($inp),$inout4
-+	cmp	\$0x60,$len
-+	jb	.Lecb_enc_five
-+	movups	0x50($inp),$inout5
-+	je	.Lecb_enc_six
-+	movdqu	0x60($inp),$inout6
-+	xorps	$inout7,$inout7
-+	call	_aesni_encrypt8
-+	movups	$inout0,($out)		# store 7 output blocks
-+	movups	$inout1,0x10($out)
-+	movups	$inout2,0x20($out)
-+	movups	$inout3,0x30($out)
-+	movups	$inout4,0x40($out)
-+	movups	$inout5,0x50($out)
-+	movups	$inout6,0x60($out)
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_enc_one:
-+___
-+	&aesni_generate1("enc",$key,$rounds);
-+$code.=<<___;
-+	movups	$inout0,($out)		# store one output block
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_enc_two:
-+	call	_aesni_encrypt2
-+	movups	$inout0,($out)		# store 2 output blocks
-+	movups	$inout1,0x10($out)
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_enc_three:
-+	call	_aesni_encrypt3
-+	movups	$inout0,($out)		# store 3 output blocks
-+	movups	$inout1,0x10($out)
-+	movups	$inout2,0x20($out)
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_enc_four:
-+	call	_aesni_encrypt4
-+	movups	$inout0,($out)		# store 4 output blocks
-+	movups	$inout1,0x10($out)
-+	movups	$inout2,0x20($out)
-+	movups	$inout3,0x30($out)
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_enc_five:
-+	xorps	$inout5,$inout5
-+	call	_aesni_encrypt6
-+	movups	$inout0,($out)		# store 5 output blocks
-+	movups	$inout1,0x10($out)
-+	movups	$inout2,0x20($out)
-+	movups	$inout3,0x30($out)
-+	movups	$inout4,0x40($out)
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_enc_six:
-+	call	_aesni_encrypt6
-+	movups	$inout0,($out)		# store 6 output blocks
-+	movups	$inout1,0x10($out)
-+	movups	$inout2,0x20($out)
-+	movups	$inout3,0x30($out)
-+	movups	$inout4,0x40($out)
-+	movups	$inout5,0x50($out)
-+	jmp	.Lecb_ret
-+#--------------------------- ECB DECRYPT ------------------------------#
-+.align	16
-+.Lecb_decrypt:
-+	cmp	\$0x80,$len		# if ($len<8*16)
-+	jb	.Lecb_dec_tail		# short input
-+
-+	movdqu	($inp),$inout0		# load 8 input blocks
-+	movdqu	0x10($inp),$inout1
-+	movdqu	0x20($inp),$inout2
-+	movdqu	0x30($inp),$inout3
-+	movdqu	0x40($inp),$inout4
-+	movdqu	0x50($inp),$inout5
-+	movdqu	0x60($inp),$inout6
-+	movdqu	0x70($inp),$inout7
-+	lea	0x80($inp),$inp		# $inp+=8*16
-+	sub	\$0x80,$len		# $len-=8*16 (can be zero)
-+	jmp	.Lecb_dec_loop8_enter
-+.align 16
-+.Lecb_dec_loop8:
-+	movups	$inout0,($out)		# store 8 output blocks
-+	mov	$key_,$key		# restore $key
-+	movdqu	($inp),$inout0		# load 8 input blocks
-+	mov	$rnds_,$rounds		# restore $rounds
-+	movups	$inout1,0x10($out)
-+	movdqu	0x10($inp),$inout1
-+	movups	$inout2,0x20($out)
-+	movdqu	0x20($inp),$inout2
-+	movups	$inout3,0x30($out)
-+	movdqu	0x30($inp),$inout3
-+	movups	$inout4,0x40($out)
-+	movdqu	0x40($inp),$inout4
-+	movups	$inout5,0x50($out)
-+	movdqu	0x50($inp),$inout5
-+	movups	$inout6,0x60($out)
-+	movdqu	0x60($inp),$inout6
-+	movups	$inout7,0x70($out)
-+	lea	0x80($out),$out		# $out+=8*16
-+	movdqu	0x70($inp),$inout7
-+	lea	0x80($inp),$inp		# $inp+=8*16
-+.Lecb_dec_loop8_enter:
-+
-+	call	_aesni_decrypt8
-+
-+	$movkey	($key_),$rndkey0
-+	sub	\$0x80,$len
-+	jnc	.Lecb_dec_loop8		# loop if $len-=8*16 didn't borrow
-+
-+	movups	$inout0,($out)		# store 8 output blocks
-+	 pxor	$inout0,$inout0		# clear register bank
-+	mov	$key_,$key		# restore $key
-+	movups	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1
-+	mov	$rnds_,$rounds		# restore $rounds
-+	movups	$inout2,0x20($out)
-+	 pxor	$inout2,$inout2
-+	movups	$inout3,0x30($out)
-+	 pxor	$inout3,$inout3
-+	movups	$inout4,0x40($out)
-+	 pxor	$inout4,$inout4
-+	movups	$inout5,0x50($out)
-+	 pxor	$inout5,$inout5
-+	movups	$inout6,0x60($out)
-+	 pxor	$inout6,$inout6
-+	movups	$inout7,0x70($out)
-+	 pxor	$inout7,$inout7
-+	lea	0x80($out),$out		# $out+=8*16
-+	add	\$0x80,$len		# restore real remaining $len
-+	jz	.Lecb_ret		# done if ($len==0)
-+
-+.Lecb_dec_tail:
-+	movups	($inp),$inout0
-+	cmp	\$0x20,$len
-+	jb	.Lecb_dec_one
-+	movups	0x10($inp),$inout1
-+	je	.Lecb_dec_two
-+	movups	0x20($inp),$inout2
-+	cmp	\$0x40,$len
-+	jb	.Lecb_dec_three
-+	movups	0x30($inp),$inout3
-+	je	.Lecb_dec_four
-+	movups	0x40($inp),$inout4
-+	cmp	\$0x60,$len
-+	jb	.Lecb_dec_five
-+	movups	0x50($inp),$inout5
-+	je	.Lecb_dec_six
-+	movups	0x60($inp),$inout6
-+	$movkey	($key),$rndkey0
-+	xorps	$inout7,$inout7
-+	call	_aesni_decrypt8
-+	movups	$inout0,($out)		# store 7 output blocks
-+	 pxor	$inout0,$inout0		# clear register bank
-+	movups	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1
-+	movups	$inout2,0x20($out)
-+	 pxor	$inout2,$inout2
-+	movups	$inout3,0x30($out)
-+	 pxor	$inout3,$inout3
-+	movups	$inout4,0x40($out)
-+	 pxor	$inout4,$inout4
-+	movups	$inout5,0x50($out)
-+	 pxor	$inout5,$inout5
-+	movups	$inout6,0x60($out)
-+	 pxor	$inout6,$inout6
-+	 pxor	$inout7,$inout7
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_dec_one:
-+___
-+	&aesni_generate1("dec",$key,$rounds);
-+$code.=<<___;
-+	movups	$inout0,($out)		# store one output block
-+	 pxor	$inout0,$inout0		# clear register bank
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_dec_two:
-+	call	_aesni_decrypt2
-+	movups	$inout0,($out)		# store 2 output blocks
-+	 pxor	$inout0,$inout0		# clear register bank
-+	movups	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_dec_three:
-+	call	_aesni_decrypt3
-+	movups	$inout0,($out)		# store 3 output blocks
-+	 pxor	$inout0,$inout0		# clear register bank
-+	movups	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1
-+	movups	$inout2,0x20($out)
-+	 pxor	$inout2,$inout2
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_dec_four:
-+	call	_aesni_decrypt4
-+	movups	$inout0,($out)		# store 4 output blocks
-+	 pxor	$inout0,$inout0		# clear register bank
-+	movups	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1
-+	movups	$inout2,0x20($out)
-+	 pxor	$inout2,$inout2
-+	movups	$inout3,0x30($out)
-+	 pxor	$inout3,$inout3
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_dec_five:
-+	xorps	$inout5,$inout5
-+	call	_aesni_decrypt6
-+	movups	$inout0,($out)		# store 5 output blocks
-+	 pxor	$inout0,$inout0		# clear register bank
-+	movups	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1
-+	movups	$inout2,0x20($out)
-+	 pxor	$inout2,$inout2
-+	movups	$inout3,0x30($out)
-+	 pxor	$inout3,$inout3
-+	movups	$inout4,0x40($out)
-+	 pxor	$inout4,$inout4
-+	 pxor	$inout5,$inout5
-+	jmp	.Lecb_ret
-+.align	16
-+.Lecb_dec_six:
-+	call	_aesni_decrypt6
-+	movups	$inout0,($out)		# store 6 output blocks
-+	 pxor	$inout0,$inout0		# clear register bank
-+	movups	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1
-+	movups	$inout2,0x20($out)
-+	 pxor	$inout2,$inout2
-+	movups	$inout3,0x30($out)
-+	 pxor	$inout3,$inout3
-+	movups	$inout4,0x40($out)
-+	 pxor	$inout4,$inout4
-+	movups	$inout5,0x50($out)
-+	 pxor	$inout5,$inout5
-+
-+.Lecb_ret:
-+	xorps	$rndkey0,$rndkey0	# %xmm0
-+	pxor	$rndkey1,$rndkey1
-+___
-+$code.=<<___ if ($win64);
-+	movaps	(%rsp),%xmm6
-+	movaps	%xmm0,(%rsp)		# clear stack
-+	movaps	0x10(%rsp),%xmm7
-+	movaps	%xmm0,0x10(%rsp)
-+	movaps	0x20(%rsp),%xmm8
-+	movaps	%xmm0,0x20(%rsp)
-+	movaps	0x30(%rsp),%xmm9
-+	movaps	%xmm0,0x30(%rsp)
-+	lea	0x58(%rsp),%rsp
-+.Lecb_enc_ret:
-+___
-+$code.=<<___;
-+	ret
-+.size	aesni_ecb_encrypt,.-aesni_ecb_encrypt
-+___
-+
-+{
-+######################################################################
-+# void aesni_ccm64_[en|de]crypt_blocks (const void *in, void *out,
-+#                         size_t blocks, const AES_KEY *key,
-+#                         const char *ivec,char *cmac);
-+#
-+# Handles only complete blocks, operates on 64-bit counter and
-+# does not update *ivec! Nor does it finalize CMAC value
-+# (see engine/eng_aesni.c for details)
-+#
-+{
-+my $cmac="%r9";	# 6th argument
-+
-+my $increment="%xmm9";
-+my $iv="%xmm6";
-+my $bswap_mask="%xmm7";
-+
-+$code.=<<___;
-+.globl	aesni_ccm64_encrypt_blocks
-+.type	aesni_ccm64_encrypt_blocks,\@function,6
-+.align	16
-+aesni_ccm64_encrypt_blocks:
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0x58(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)		# $iv
-+	movaps	%xmm7,0x10(%rsp)	# $bswap_mask
-+	movaps	%xmm8,0x20(%rsp)	# $in0
-+	movaps	%xmm9,0x30(%rsp)	# $increment
-+.Lccm64_enc_body:
-+___
-+$code.=<<___;
-+	mov	240($key),$rounds		# key->rounds
-+	movdqu	($ivp),$iv
-+	movdqa	.Lincrement64(%rip),$increment
-+	movdqa	.Lbswap_mask(%rip),$bswap_mask
-+
-+	shl	\$4,$rounds
-+	mov	\$16,$rnds_
-+	lea	0($key),$key_
-+	movdqu	($cmac),$inout1
-+	movdqa	$iv,$inout0
-+	lea	32($key,$rounds),$key		# end of key schedule
-+	pshufb	$bswap_mask,$iv
-+	sub	%rax,%r10			# twisted $rounds
-+	jmp	.Lccm64_enc_outer
-+.align	16
-+.Lccm64_enc_outer:
-+	$movkey	($key_),$rndkey0
-+	mov	%r10,%rax
-+	movups	($inp),$in0			# load inp
-+
-+	xorps	$rndkey0,$inout0		# counter
-+	$movkey	16($key_),$rndkey1
-+	xorps	$in0,$rndkey0
-+	xorps	$rndkey0,$inout1		# cmac^=inp
-+	$movkey	32($key_),$rndkey0
-+
-+.Lccm64_enc2_loop:
-+	aesenc	$rndkey1,$inout0
-+	aesenc	$rndkey1,$inout1
-+	$movkey	($key,%rax),$rndkey1
-+	add	\$32,%rax
-+	aesenc	$rndkey0,$inout0
-+	aesenc	$rndkey0,$inout1
-+	$movkey	-16($key,%rax),$rndkey0
-+	jnz	.Lccm64_enc2_loop
-+	aesenc	$rndkey1,$inout0
-+	aesenc	$rndkey1,$inout1
-+	paddq	$increment,$iv
-+	dec	$len				# $len-- ($len is in blocks)
-+	aesenclast	$rndkey0,$inout0
-+	aesenclast	$rndkey0,$inout1
-+
-+	lea	16($inp),$inp
-+	xorps	$inout0,$in0			# inp ^= E(iv)
-+	movdqa	$iv,$inout0
-+	movups	$in0,($out)			# save output
-+	pshufb	$bswap_mask,$inout0
-+	lea	16($out),$out			# $out+=16
-+	jnz	.Lccm64_enc_outer		# loop if ($len!=0)
-+
-+	 pxor	$rndkey0,$rndkey0		# clear register bank
-+	 pxor	$rndkey1,$rndkey1
-+	 pxor	$inout0,$inout0
-+	movups	$inout1,($cmac)			# store resulting mac
-+	 pxor	$inout1,$inout1
-+	 pxor	$in0,$in0
-+	 pxor	$iv,$iv
-+___
-+$code.=<<___ if ($win64);
-+	movaps	(%rsp),%xmm6
-+	movaps	%xmm0,(%rsp)			# clear stack
-+	movaps	0x10(%rsp),%xmm7
-+	movaps	%xmm0,0x10(%rsp)
-+	movaps	0x20(%rsp),%xmm8
-+	movaps	%xmm0,0x20(%rsp)
-+	movaps	0x30(%rsp),%xmm9
-+	movaps	%xmm0,0x30(%rsp)
-+	lea	0x58(%rsp),%rsp
-+.Lccm64_enc_ret:
-+___
-+$code.=<<___;
-+	ret
-+.size	aesni_ccm64_encrypt_blocks,.-aesni_ccm64_encrypt_blocks
-+___
-+######################################################################
-+$code.=<<___;
-+.globl	aesni_ccm64_decrypt_blocks
-+.type	aesni_ccm64_decrypt_blocks,\@function,6
-+.align	16
-+aesni_ccm64_decrypt_blocks:
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0x58(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)		# $iv
-+	movaps	%xmm7,0x10(%rsp)	# $bswap_mask
-+	movaps	%xmm8,0x20(%rsp)	# $in8
-+	movaps	%xmm9,0x30(%rsp)	# $increment
-+.Lccm64_dec_body:
-+___
-+$code.=<<___;
-+	mov	240($key),$rounds		# key->rounds
-+	movups	($ivp),$iv
-+	movdqu	($cmac),$inout1
-+	movdqa	.Lincrement64(%rip),$increment
-+	movdqa	.Lbswap_mask(%rip),$bswap_mask
-+
-+	movaps	$iv,$inout0
-+	mov	$rounds,$rnds_
-+	mov	$key,$key_
-+	pshufb	$bswap_mask,$iv
-+___
-+	&aesni_generate1("enc",$key,$rounds);
-+$code.=<<___;
-+	shl	\$4,$rnds_
-+	mov	\$16,$rounds
-+	movups	($inp),$in0			# load inp
-+	paddq	$increment,$iv
-+	lea	16($inp),$inp			# $inp+=16
-+	sub	%r10,%rax			# twisted $rounds
-+	lea	32($key_,$rnds_),$key		# end of key schedule
-+	mov	%rax,%r10
-+	jmp	.Lccm64_dec_outer
-+.align	16
-+.Lccm64_dec_outer:
-+	xorps	$inout0,$in0			# inp ^= E(iv)
-+	movdqa	$iv,$inout0
-+	movups	$in0,($out)			# save output
-+	lea	16($out),$out			# $out+=16
-+	pshufb	$bswap_mask,$inout0
-+
-+	sub	\$1,$len			# $len-- ($len is in blocks)
-+	jz	.Lccm64_dec_break		# if ($len==0) break
-+
-+	$movkey	($key_),$rndkey0
-+	mov	%r10,%rax
-+	$movkey	16($key_),$rndkey1
-+	xorps	$rndkey0,$in0
-+	xorps	$rndkey0,$inout0
-+	xorps	$in0,$inout1			# cmac^=out
-+	$movkey	32($key_),$rndkey0
-+	jmp	.Lccm64_dec2_loop
-+.align	16
-+.Lccm64_dec2_loop:
-+	aesenc	$rndkey1,$inout0
-+	aesenc	$rndkey1,$inout1
-+	$movkey	($key,%rax),$rndkey1
-+	add	\$32,%rax
-+	aesenc	$rndkey0,$inout0
-+	aesenc	$rndkey0,$inout1
-+	$movkey	-16($key,%rax),$rndkey0
-+	jnz	.Lccm64_dec2_loop
-+	movups	($inp),$in0			# load input
-+	paddq	$increment,$iv
-+	aesenc	$rndkey1,$inout0
-+	aesenc	$rndkey1,$inout1
-+	aesenclast	$rndkey0,$inout0
-+	aesenclast	$rndkey0,$inout1
-+	lea	16($inp),$inp			# $inp+=16
-+	jmp	.Lccm64_dec_outer
-+
-+.align	16
-+.Lccm64_dec_break:
-+	#xorps	$in0,$inout1			# cmac^=out
-+	mov	240($key_),$rounds
-+___
-+	&aesni_generate1("enc",$key_,$rounds,$inout1,$in0);
-+$code.=<<___;
-+	 pxor	$rndkey0,$rndkey0		# clear register bank
-+	 pxor	$rndkey1,$rndkey1
-+	 pxor	$inout0,$inout0
-+	movups	$inout1,($cmac)			# store resulting mac
-+	 pxor	$inout1,$inout1
-+	 pxor	$in0,$in0
-+	 pxor	$iv,$iv
-+___
-+$code.=<<___ if ($win64);
-+	movaps	(%rsp),%xmm6
-+	movaps	%xmm0,(%rsp)			# clear stack
-+	movaps	0x10(%rsp),%xmm7
-+	movaps	%xmm0,0x10(%rsp)
-+	movaps	0x20(%rsp),%xmm8
-+	movaps	%xmm0,0x20(%rsp)
-+	movaps	0x30(%rsp),%xmm9
-+	movaps	%xmm0,0x30(%rsp)
-+	lea	0x58(%rsp),%rsp
-+.Lccm64_dec_ret:
-+___
-+$code.=<<___;
-+	ret
-+.size	aesni_ccm64_decrypt_blocks,.-aesni_ccm64_decrypt_blocks
-+___
-+}
-+######################################################################
-+# void aesni_ctr32_encrypt_blocks (const void *in, void *out,
-+#                         size_t blocks, const AES_KEY *key,
-+#                         const char *ivec);
-+#
-+# Handles only complete blocks, operates on 32-bit counter and
-+# does not update *ivec! (see crypto/modes/ctr128.c for details)
-+#
-+# Overhaul based on suggestions from Shay Gueron and Vlad Krasnov,
-+# http://rt.openssl.org/Ticket/Display.html?id=3021&user=guest&pass=guest.
-+# Keywords are full unroll and modulo-schedule counter calculations
-+# with zero-round key xor.
-+{
-+my ($in0,$in1,$in2,$in3,$in4,$in5)=map("%xmm$_",(10..15));
-+my ($key0,$ctr)=("${key_}d","${ivp}d");
-+my $frame_size = 0x80 + ($win64?160:0);
-+
-+$code.=<<___;
-+.globl	aesni_ctr32_encrypt_blocks
-+.type	aesni_ctr32_encrypt_blocks,\@function,5
-+.align	16
-+aesni_ctr32_encrypt_blocks:
-+	cmp	\$1,$len
-+	jne	.Lctr32_bulk
-+
-+	# handle single block without allocating stack frame,
-+	# useful when handling edges
-+	movups	($ivp),$inout0
-+	movups	($inp),$inout1
-+	mov	240($key),%edx			# key->rounds
-+___
-+	&aesni_generate1("enc",$key,"%edx");
-+$code.=<<___;
-+	 pxor	$rndkey0,$rndkey0		# clear register bank
-+	 pxor	$rndkey1,$rndkey1
-+	xorps	$inout1,$inout0
-+	 pxor	$inout1,$inout1
-+	movups	$inout0,($out)
-+	 xorps	$inout0,$inout0
-+	jmp	.Lctr32_epilogue
-+
-+.align	16
-+.Lctr32_bulk:
-+	lea	(%rsp),%rax
-+	push	%rbp
-+	sub	\$$frame_size,%rsp
-+	and	\$-16,%rsp	# Linux kernel stack can be incorrectly seeded
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,-0xa8(%rax)		# offload everything
-+	movaps	%xmm7,-0x98(%rax)
-+	movaps	%xmm8,-0x88(%rax)
-+	movaps	%xmm9,-0x78(%rax)
-+	movaps	%xmm10,-0x68(%rax)
-+	movaps	%xmm11,-0x58(%rax)
-+	movaps	%xmm12,-0x48(%rax)
-+	movaps	%xmm13,-0x38(%rax)
-+	movaps	%xmm14,-0x28(%rax)
-+	movaps	%xmm15,-0x18(%rax)
-+.Lctr32_body:
-+___
-+$code.=<<___;
-+	lea	-8(%rax),%rbp
-+
-+	# 8 16-byte words on top of stack are counter values
-+	# xor-ed with zero-round key
-+
-+	movdqu	($ivp),$inout0
-+	movdqu	($key),$rndkey0
-+	mov	12($ivp),$ctr			# counter LSB
-+	pxor	$rndkey0,$inout0
-+	mov	12($key),$key0			# 0-round key LSB
-+	movdqa	$inout0,0x00(%rsp)		# populate counter block
-+	bswap	$ctr
-+	movdqa	$inout0,$inout1
-+	movdqa	$inout0,$inout2
-+	movdqa	$inout0,$inout3
-+	movdqa	$inout0,0x40(%rsp)
-+	movdqa	$inout0,0x50(%rsp)
-+	movdqa	$inout0,0x60(%rsp)
-+	mov	%rdx,%r10			# about to borrow %rdx
-+	movdqa	$inout0,0x70(%rsp)
-+
-+	lea	1($ctr),%rax
-+	 lea	2($ctr),%rdx
-+	bswap	%eax
-+	 bswap	%edx
-+	xor	$key0,%eax
-+	 xor	$key0,%edx
-+	pinsrd	\$3,%eax,$inout1
-+	lea	3($ctr),%rax
-+	movdqa	$inout1,0x10(%rsp)
-+	 pinsrd	\$3,%edx,$inout2
-+	bswap	%eax
-+	 mov	%r10,%rdx			# restore %rdx
-+	 lea	4($ctr),%r10
-+	 movdqa	$inout2,0x20(%rsp)
-+	xor	$key0,%eax
-+	 bswap	%r10d
-+	pinsrd	\$3,%eax,$inout3
-+	 xor	$key0,%r10d
-+	movdqa	$inout3,0x30(%rsp)
-+	lea	5($ctr),%r9
-+	 mov	%r10d,0x40+12(%rsp)
-+	bswap	%r9d
-+	 lea	6($ctr),%r10
-+	mov	240($key),$rounds		# key->rounds
-+	xor	$key0,%r9d
-+	 bswap	%r10d
-+	mov	%r9d,0x50+12(%rsp)
-+	 xor	$key0,%r10d
-+	lea	7($ctr),%r9
-+	 mov	%r10d,0x60+12(%rsp)
-+	bswap	%r9d
-+	 mov	OPENSSL_ia32cap_P+4(%rip),%r10d 
-+	xor	$key0,%r9d
-+	 and	\$`1<<26|1<<22`,%r10d		# isolate XSAVE+MOVBE
-+	mov	%r9d,0x70+12(%rsp)
-+
-+	$movkey	0x10($key),$rndkey1
-+
-+	movdqa	0x40(%rsp),$inout4
-+	movdqa	0x50(%rsp),$inout5
-+
-+	cmp	\$8,$len		# $len is in blocks
-+	jb	.Lctr32_tail		# short input if ($len<8)
-+
-+	sub	\$6,$len		# $len is biased by -6
-+	cmp	\$`1<<22`,%r10d		# check for MOVBE without XSAVE
-+	je	.Lctr32_6x		# [which denotes Atom Silvermont]
-+
-+	lea	0x80($key),$key		# size optimization
-+	sub	\$2,$len		# $len is biased by -8
-+	jmp	.Lctr32_loop8
-+
-+.align	16
-+.Lctr32_6x:
-+	shl	\$4,$rounds
-+	mov	\$48,$rnds_
-+	bswap	$key0
-+	lea	32($key,$rounds),$key	# end of key schedule
-+	sub	%rax,%r10		# twisted $rounds
-+	jmp	.Lctr32_loop6
-+
-+.align	16
-+.Lctr32_loop6:
-+	 add	\$6,$ctr		# next counter value
-+	$movkey	-48($key,$rnds_),$rndkey0
-+	aesenc	$rndkey1,$inout0
-+	 mov	$ctr,%eax
-+	 xor	$key0,%eax
-+	aesenc	$rndkey1,$inout1
-+	 movbe	%eax,`0x00+12`(%rsp)	# store next counter value
-+	 lea	1($ctr),%eax
-+	aesenc	$rndkey1,$inout2
-+	 xor	$key0,%eax
-+	 movbe	%eax,`0x10+12`(%rsp)
-+	aesenc	$rndkey1,$inout3
-+	 lea	2($ctr),%eax
-+	 xor	$key0,%eax
-+	aesenc	$rndkey1,$inout4
-+	 movbe	%eax,`0x20+12`(%rsp)
-+	 lea	3($ctr),%eax
-+	aesenc	$rndkey1,$inout5
-+	$movkey	-32($key,$rnds_),$rndkey1
-+	 xor	$key0,%eax
-+
-+	aesenc	$rndkey0,$inout0
-+	 movbe	%eax,`0x30+12`(%rsp)
-+	 lea	4($ctr),%eax
-+	aesenc	$rndkey0,$inout1
-+	 xor	$key0,%eax
-+	 movbe	%eax,`0x40+12`(%rsp)
-+	aesenc	$rndkey0,$inout2
-+	 lea	5($ctr),%eax
-+	 xor	$key0,%eax
-+	aesenc	$rndkey0,$inout3
-+	 movbe	%eax,`0x50+12`(%rsp)
-+	 mov	%r10,%rax		# mov	$rnds_,$rounds
-+	aesenc	$rndkey0,$inout4
-+	aesenc	$rndkey0,$inout5
-+	$movkey	-16($key,$rnds_),$rndkey0
-+
-+	call	.Lenc_loop6
-+
-+	movdqu	($inp),$inout6		# load 6 input blocks
-+	movdqu	0x10($inp),$inout7
-+	movdqu	0x20($inp),$in0
-+	movdqu	0x30($inp),$in1
-+	movdqu	0x40($inp),$in2
-+	movdqu	0x50($inp),$in3
-+	lea	0x60($inp),$inp		# $inp+=6*16
-+	$movkey	-64($key,$rnds_),$rndkey1
-+	pxor	$inout0,$inout6		# inp^=E(ctr)
-+	movaps	0x00(%rsp),$inout0	# load next counter [xor-ed with 0 round]
-+	pxor	$inout1,$inout7
-+	movaps	0x10(%rsp),$inout1
-+	pxor	$inout2,$in0
-+	movaps	0x20(%rsp),$inout2
-+	pxor	$inout3,$in1
-+	movaps	0x30(%rsp),$inout3
-+	pxor	$inout4,$in2
-+	movaps	0x40(%rsp),$inout4
-+	pxor	$inout5,$in3
-+	movaps	0x50(%rsp),$inout5
-+	movdqu	$inout6,($out)		# store 6 output blocks
-+	movdqu	$inout7,0x10($out)
-+	movdqu	$in0,0x20($out)
-+	movdqu	$in1,0x30($out)
-+	movdqu	$in2,0x40($out)
-+	movdqu	$in3,0x50($out)
-+	lea	0x60($out),$out		# $out+=6*16
-+
-+	sub	\$6,$len
-+	jnc	.Lctr32_loop6		# loop if $len-=6 didn't borrow
-+
-+	add	\$6,$len		# restore real remaining $len
-+	jz	.Lctr32_done		# done if ($len==0)
-+
-+	lea	-48($rnds_),$rounds
-+	lea	-80($key,$rnds_),$key	# restore $key
-+	neg	$rounds
-+	shr	\$4,$rounds		# restore $rounds
-+	jmp	.Lctr32_tail
-+
-+.align	32
-+.Lctr32_loop8:
-+	 add		\$8,$ctr		# next counter value
-+	movdqa		0x60(%rsp),$inout6
-+	aesenc		$rndkey1,$inout0
-+	 mov		$ctr,%r9d
-+	movdqa		0x70(%rsp),$inout7
-+	aesenc		$rndkey1,$inout1
-+	 bswap		%r9d
-+	$movkey		0x20-0x80($key),$rndkey0
-+	aesenc		$rndkey1,$inout2
-+	 xor		$key0,%r9d
-+	 nop
-+	aesenc		$rndkey1,$inout3
-+	 mov		%r9d,0x00+12(%rsp)	# store next counter value
-+	 lea		1($ctr),%r9
-+	aesenc		$rndkey1,$inout4
-+	aesenc		$rndkey1,$inout5
-+	aesenc		$rndkey1,$inout6
-+	aesenc		$rndkey1,$inout7
-+	$movkey		0x30-0x80($key),$rndkey1
-+___
-+for($i=2;$i<8;$i++) {
-+my $rndkeyx = ($i&1)?$rndkey1:$rndkey0;
-+$code.=<<___;
-+	 bswap		%r9d
-+	aesenc		$rndkeyx,$inout0
-+	aesenc		$rndkeyx,$inout1
-+	 xor		$key0,%r9d
-+	 .byte		0x66,0x90
-+	aesenc		$rndkeyx,$inout2
-+	aesenc		$rndkeyx,$inout3
-+	 mov		%r9d,`0x10*($i-1)`+12(%rsp)
-+	 lea		$i($ctr),%r9
-+	aesenc		$rndkeyx,$inout4
-+	aesenc		$rndkeyx,$inout5
-+	aesenc		$rndkeyx,$inout6
-+	aesenc		$rndkeyx,$inout7
-+	$movkey		`0x20+0x10*$i`-0x80($key),$rndkeyx
-+___
-+}
-+$code.=<<___;
-+	 bswap		%r9d
-+	aesenc		$rndkey0,$inout0
-+	aesenc		$rndkey0,$inout1
-+	aesenc		$rndkey0,$inout2
-+	 xor		$key0,%r9d
-+	 movdqu		0x00($inp),$in0		# start loading input
-+	aesenc		$rndkey0,$inout3
-+	 mov		%r9d,0x70+12(%rsp)
-+	 cmp		\$11,$rounds
-+	aesenc		$rndkey0,$inout4
-+	aesenc		$rndkey0,$inout5
-+	aesenc		$rndkey0,$inout6
-+	aesenc		$rndkey0,$inout7
-+	$movkey		0xa0-0x80($key),$rndkey0
-+
-+	jb		.Lctr32_enc_done
-+
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	aesenc		$rndkey1,$inout4
-+	aesenc		$rndkey1,$inout5
-+	aesenc		$rndkey1,$inout6
-+	aesenc		$rndkey1,$inout7
-+	$movkey		0xb0-0x80($key),$rndkey1
-+
-+	aesenc		$rndkey0,$inout0
-+	aesenc		$rndkey0,$inout1
-+	aesenc		$rndkey0,$inout2
-+	aesenc		$rndkey0,$inout3
-+	aesenc		$rndkey0,$inout4
-+	aesenc		$rndkey0,$inout5
-+	aesenc		$rndkey0,$inout6
-+	aesenc		$rndkey0,$inout7
-+	$movkey		0xc0-0x80($key),$rndkey0
-+	je		.Lctr32_enc_done
-+
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	aesenc		$rndkey1,$inout4
-+	aesenc		$rndkey1,$inout5
-+	aesenc		$rndkey1,$inout6
-+	aesenc		$rndkey1,$inout7
-+	$movkey		0xd0-0x80($key),$rndkey1
-+
-+	aesenc		$rndkey0,$inout0
-+	aesenc		$rndkey0,$inout1
-+	aesenc		$rndkey0,$inout2
-+	aesenc		$rndkey0,$inout3
-+	aesenc		$rndkey0,$inout4
-+	aesenc		$rndkey0,$inout5
-+	aesenc		$rndkey0,$inout6
-+	aesenc		$rndkey0,$inout7
-+	$movkey		0xe0-0x80($key),$rndkey0
-+	jmp		.Lctr32_enc_done
-+
-+.align	16
-+.Lctr32_enc_done:
-+	movdqu		0x10($inp),$in1
-+	pxor		$rndkey0,$in0		# input^=round[last]
-+	movdqu		0x20($inp),$in2
-+	pxor		$rndkey0,$in1
-+	movdqu		0x30($inp),$in3
-+	pxor		$rndkey0,$in2
-+	movdqu		0x40($inp),$in4
-+	pxor		$rndkey0,$in3
-+	movdqu		0x50($inp),$in5
-+	pxor		$rndkey0,$in4
-+	pxor		$rndkey0,$in5
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	aesenc		$rndkey1,$inout4
-+	aesenc		$rndkey1,$inout5
-+	aesenc		$rndkey1,$inout6
-+	aesenc		$rndkey1,$inout7
-+	movdqu		0x60($inp),$rndkey1	# borrow $rndkey1 for inp[6]
-+	lea		0x80($inp),$inp		# $inp+=8*16
-+
-+	aesenclast	$in0,$inout0		# $inN is inp[N]^round[last]
-+	pxor		$rndkey0,$rndkey1	# borrowed $rndkey
-+	movdqu		0x70-0x80($inp),$in0
-+	aesenclast	$in1,$inout1
-+	pxor		$rndkey0,$in0
-+	movdqa		0x00(%rsp),$in1		# load next counter block
-+	aesenclast	$in2,$inout2
-+	aesenclast	$in3,$inout3
-+	movdqa		0x10(%rsp),$in2
-+	movdqa		0x20(%rsp),$in3
-+	aesenclast	$in4,$inout4
-+	aesenclast	$in5,$inout5
-+	movdqa		0x30(%rsp),$in4
-+	movdqa		0x40(%rsp),$in5
-+	aesenclast	$rndkey1,$inout6
-+	movdqa		0x50(%rsp),$rndkey0
-+	$movkey		0x10-0x80($key),$rndkey1#real 1st-round key
-+	aesenclast	$in0,$inout7
-+
-+	movups		$inout0,($out)		# store 8 output blocks
-+	movdqa		$in1,$inout0
-+	movups		$inout1,0x10($out)
-+	movdqa		$in2,$inout1
-+	movups		$inout2,0x20($out)
-+	movdqa		$in3,$inout2
-+	movups		$inout3,0x30($out)
-+	movdqa		$in4,$inout3
-+	movups		$inout4,0x40($out)
-+	movdqa		$in5,$inout4
-+	movups		$inout5,0x50($out)
-+	movdqa		$rndkey0,$inout5
-+	movups		$inout6,0x60($out)
-+	movups		$inout7,0x70($out)
-+	lea		0x80($out),$out		# $out+=8*16
-+
-+	sub	\$8,$len
-+	jnc	.Lctr32_loop8			# loop if $len-=8 didn't borrow
-+
-+	add	\$8,$len			# restore real remainig $len
-+	jz	.Lctr32_done			# done if ($len==0)
-+	lea	-0x80($key),$key
-+
-+.Lctr32_tail:
-+	# note that at this point $inout0..5 are populated with
-+	# counter values xor-ed with 0-round key 
-+	lea	16($key),$key
-+	cmp	\$4,$len
-+	jb	.Lctr32_loop3
-+	je	.Lctr32_loop4
-+
-+	# if ($len>4) compute 7 E(counter)
-+	shl		\$4,$rounds
-+	movdqa		0x60(%rsp),$inout6
-+	pxor		$inout7,$inout7
-+
-+	$movkey		16($key),$rndkey0
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	lea		32-16($key,$rounds),$key# prepare for .Lenc_loop8_enter
-+	neg		%rax
-+	aesenc		$rndkey1,$inout2
-+	add		\$16,%rax		# prepare for .Lenc_loop8_enter
-+	 movups		($inp),$in0
-+	aesenc		$rndkey1,$inout3
-+	aesenc		$rndkey1,$inout4
-+	 movups		0x10($inp),$in1		# pre-load input
-+	 movups		0x20($inp),$in2
-+	aesenc		$rndkey1,$inout5
-+	aesenc		$rndkey1,$inout6
-+
-+	call            .Lenc_loop8_enter
-+
-+	movdqu	0x30($inp),$in3
-+	pxor	$in0,$inout0
-+	movdqu	0x40($inp),$in0
-+	pxor	$in1,$inout1
-+	movdqu	$inout0,($out)			# store output
-+	pxor	$in2,$inout2
-+	movdqu	$inout1,0x10($out)
-+	pxor	$in3,$inout3
-+	movdqu	$inout2,0x20($out)
-+	pxor	$in0,$inout4
-+	movdqu	$inout3,0x30($out)
-+	movdqu	$inout4,0x40($out)
-+	cmp	\$6,$len
-+	jb	.Lctr32_done			# $len was 5, stop store
-+
-+	movups	0x50($inp),$in1
-+	xorps	$in1,$inout5
-+	movups	$inout5,0x50($out)
-+	je	.Lctr32_done			# $len was 6, stop store
-+
-+	movups	0x60($inp),$in2
-+	xorps	$in2,$inout6
-+	movups	$inout6,0x60($out)
-+	jmp	.Lctr32_done			# $len was 7, stop store
-+
-+.align	32
-+.Lctr32_loop4:
-+	aesenc		$rndkey1,$inout0
-+	lea		16($key),$key
-+	dec		$rounds
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	$movkey		($key),$rndkey1
-+	jnz		.Lctr32_loop4
-+	aesenclast	$rndkey1,$inout0
-+	aesenclast	$rndkey1,$inout1
-+	 movups		($inp),$in0		# load input
-+	 movups		0x10($inp),$in1
-+	aesenclast	$rndkey1,$inout2
-+	aesenclast	$rndkey1,$inout3
-+	 movups		0x20($inp),$in2
-+	 movups		0x30($inp),$in3
-+
-+	xorps	$in0,$inout0
-+	movups	$inout0,($out)			# store output
-+	xorps	$in1,$inout1
-+	movups	$inout1,0x10($out)
-+	pxor	$in2,$inout2
-+	movdqu	$inout2,0x20($out)
-+	pxor	$in3,$inout3
-+	movdqu	$inout3,0x30($out)
-+	jmp	.Lctr32_done			# $len was 4, stop store
-+
-+.align	32
-+.Lctr32_loop3:
-+	aesenc		$rndkey1,$inout0
-+	lea		16($key),$key
-+	dec		$rounds
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	$movkey		($key),$rndkey1
-+	jnz		.Lctr32_loop3
-+	aesenclast	$rndkey1,$inout0
-+	aesenclast	$rndkey1,$inout1
-+	aesenclast	$rndkey1,$inout2
-+
-+	movups	($inp),$in0			# load input
-+	xorps	$in0,$inout0
-+	movups	$inout0,($out)			# store output
-+	cmp	\$2,$len
-+	jb	.Lctr32_done			# $len was 1, stop store
-+
-+	movups	0x10($inp),$in1
-+	xorps	$in1,$inout1
-+	movups	$inout1,0x10($out)
-+	je	.Lctr32_done			# $len was 2, stop store
-+
-+	movups	0x20($inp),$in2
-+	xorps	$in2,$inout2
-+	movups	$inout2,0x20($out)		# $len was 3, stop store
-+
-+.Lctr32_done:
-+	xorps	%xmm0,%xmm0			# clear regiser bank
-+	xor	$key0,$key0
-+	pxor	%xmm1,%xmm1
-+	pxor	%xmm2,%xmm2
-+	pxor	%xmm3,%xmm3
-+	pxor	%xmm4,%xmm4
-+	pxor	%xmm5,%xmm5
-+___
-+$code.=<<___ if (!$win64);
-+	pxor	%xmm6,%xmm6
-+	pxor	%xmm7,%xmm7
-+	movaps	%xmm0,0x00(%rsp)		# clear stack
-+	pxor	%xmm8,%xmm8
-+	movaps	%xmm0,0x10(%rsp)
-+	pxor	%xmm9,%xmm9
-+	movaps	%xmm0,0x20(%rsp)
-+	pxor	%xmm10,%xmm10
-+	movaps	%xmm0,0x30(%rsp)
-+	pxor	%xmm11,%xmm11
-+	movaps	%xmm0,0x40(%rsp)
-+	pxor	%xmm12,%xmm12
-+	movaps	%xmm0,0x50(%rsp)
-+	pxor	%xmm13,%xmm13
-+	movaps	%xmm0,0x60(%rsp)
-+	pxor	%xmm14,%xmm14
-+	movaps	%xmm0,0x70(%rsp)
-+	pxor	%xmm15,%xmm15
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xa0(%rbp),%xmm6
-+	movaps	%xmm0,-0xa0(%rbp)		# clear stack
-+	movaps	-0x90(%rbp),%xmm7
-+	movaps	%xmm0,-0x90(%rbp)
-+	movaps	-0x80(%rbp),%xmm8
-+	movaps	%xmm0,-0x80(%rbp)
-+	movaps	-0x70(%rbp),%xmm9
-+	movaps	%xmm0,-0x70(%rbp)
-+	movaps	-0x60(%rbp),%xmm10
-+	movaps	%xmm0,-0x60(%rbp)
-+	movaps	-0x50(%rbp),%xmm11
-+	movaps	%xmm0,-0x50(%rbp)
-+	movaps	-0x40(%rbp),%xmm12
-+	movaps	%xmm0,-0x40(%rbp)
-+	movaps	-0x30(%rbp),%xmm13
-+	movaps	%xmm0,-0x30(%rbp)
-+	movaps	-0x20(%rbp),%xmm14
-+	movaps	%xmm0,-0x20(%rbp)
-+	movaps	-0x10(%rbp),%xmm15
-+	movaps	%xmm0,-0x10(%rbp)
-+	movaps	%xmm0,0x00(%rsp)
-+	movaps	%xmm0,0x10(%rsp)
-+	movaps	%xmm0,0x20(%rsp)
-+	movaps	%xmm0,0x30(%rsp)
-+	movaps	%xmm0,0x40(%rsp)
-+	movaps	%xmm0,0x50(%rsp)
-+	movaps	%xmm0,0x60(%rsp)
-+	movaps	%xmm0,0x70(%rsp)
-+___
-+$code.=<<___;
-+	lea	(%rbp),%rsp
-+	pop	%rbp
-+.Lctr32_epilogue:
-+	ret
-+.size	aesni_ctr32_encrypt_blocks,.-aesni_ctr32_encrypt_blocks
-+___
-+}
-+
-+######################################################################
-+# void aesni_xts_[en|de]crypt(const char *inp,char *out,size_t len,
-+#	const AES_KEY *key1, const AES_KEY *key2
-+#	const unsigned char iv[16]);
-+#
-+{
-+my @tweak=map("%xmm$_",(10..15));
-+my ($twmask,$twres,$twtmp)=("%xmm8","%xmm9",@tweak[4]);
-+my ($key2,$ivp,$len_)=("%r8","%r9","%r9");
-+my $frame_size = 0x70 + ($win64?160:0);
-+
-+$code.=<<___;
-+.globl	aesni_xts_encrypt
-+.type	aesni_xts_encrypt,\@function,6
-+.align	16
-+aesni_xts_encrypt:
-+	lea	(%rsp),%rax
-+	push	%rbp
-+	sub	\$$frame_size,%rsp
-+	and	\$-16,%rsp	# Linux kernel stack can be incorrectly seeded
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,-0xa8(%rax)		# offload everything
-+	movaps	%xmm7,-0x98(%rax)
-+	movaps	%xmm8,-0x88(%rax)
-+	movaps	%xmm9,-0x78(%rax)
-+	movaps	%xmm10,-0x68(%rax)
-+	movaps	%xmm11,-0x58(%rax)
-+	movaps	%xmm12,-0x48(%rax)
-+	movaps	%xmm13,-0x38(%rax)
-+	movaps	%xmm14,-0x28(%rax)
-+	movaps	%xmm15,-0x18(%rax)
-+.Lxts_enc_body:
-+___
-+$code.=<<___;
-+	lea	-8(%rax),%rbp
-+	movups	($ivp),$inout0			# load clear-text tweak
-+	mov	240(%r8),$rounds		# key2->rounds
-+	mov	240($key),$rnds_		# key1->rounds
-+___
-+	# generate the tweak
-+	&aesni_generate1("enc",$key2,$rounds,$inout0);
-+$code.=<<___;
-+	$movkey	($key),$rndkey0			# zero round key
-+	mov	$key,$key_			# backup $key
-+	mov	$rnds_,$rounds			# backup $rounds
-+	shl	\$4,$rnds_
-+	mov	$len,$len_			# backup $len
-+	and	\$-16,$len
-+
-+	$movkey	16($key,$rnds_),$rndkey1	# last round key
-+
-+	movdqa	.Lxts_magic(%rip),$twmask
-+	movdqa	$inout0,@tweak[5]
-+	pshufd	\$0x5f,$inout0,$twres
-+	pxor	$rndkey0,$rndkey1
-+___
-+    # alternative tweak calculation algorithm is based on suggestions
-+    # by Shay Gueron. psrad doesn't conflict with AES-NI instructions
-+    # and should help in the future...
-+    for ($i=0;$i<4;$i++) {
-+    $code.=<<___;
-+	movdqa	$twres,$twtmp
-+	paddd	$twres,$twres
-+	movdqa	@tweak[5],@tweak[$i]
-+	psrad	\$31,$twtmp			# broadcast upper bits
-+	paddq	@tweak[5],@tweak[5]
-+	pand	$twmask,$twtmp
-+	pxor	$rndkey0,@tweak[$i]
-+	pxor	$twtmp,@tweak[5]
-+___
-+    }
-+$code.=<<___;
-+	movdqa	@tweak[5],@tweak[4]
-+	psrad	\$31,$twres
-+	paddq	@tweak[5],@tweak[5]
-+	pand	$twmask,$twres
-+	pxor	$rndkey0,@tweak[4]
-+	pxor	$twres,@tweak[5]
-+	movaps	$rndkey1,0x60(%rsp)		# save round[0]^round[last]
-+
-+	sub	\$16*6,$len
-+	jc	.Lxts_enc_short			# if $len-=6*16 borrowed
-+
-+	mov	\$16+96,$rounds
-+	lea	32($key_,$rnds_),$key		# end of key schedule
-+	sub	%r10,%rax			# twisted $rounds
-+	$movkey	16($key_),$rndkey1
-+	mov	%rax,%r10			# backup twisted $rounds
-+	lea	.Lxts_magic(%rip),%r8
-+	jmp	.Lxts_enc_grandloop
-+
-+.align	32
-+.Lxts_enc_grandloop:
-+	movdqu	`16*0`($inp),$inout0		# load input
-+	movdqa	$rndkey0,$twmask
-+	movdqu	`16*1`($inp),$inout1
-+	pxor	@tweak[0],$inout0		# input^=tweak^round[0]
-+	movdqu	`16*2`($inp),$inout2
-+	pxor	@tweak[1],$inout1
-+	 aesenc		$rndkey1,$inout0
-+	movdqu	`16*3`($inp),$inout3
-+	pxor	@tweak[2],$inout2
-+	 aesenc		$rndkey1,$inout1
-+	movdqu	`16*4`($inp),$inout4
-+	pxor	@tweak[3],$inout3
-+	 aesenc		$rndkey1,$inout2
-+	movdqu	`16*5`($inp),$inout5
-+	pxor	@tweak[5],$twmask		# round[0]^=tweak[5]
-+	 movdqa	0x60(%rsp),$twres		# load round[0]^round[last]
-+	pxor	@tweak[4],$inout4
-+	 aesenc		$rndkey1,$inout3
-+	$movkey	32($key_),$rndkey0
-+	lea	`16*6`($inp),$inp
-+	pxor	$twmask,$inout5
-+
-+	 pxor	$twres,@tweak[0]		# calclulate tweaks^round[last]
-+	aesenc		$rndkey1,$inout4
-+	 pxor	$twres,@tweak[1]
-+	 movdqa	@tweak[0],`16*0`(%rsp)		# put aside tweaks^round[last]
-+	aesenc		$rndkey1,$inout5
-+	$movkey		48($key_),$rndkey1
-+	 pxor	$twres,@tweak[2]
-+
-+	aesenc		$rndkey0,$inout0
-+	 pxor	$twres,@tweak[3]
-+	 movdqa	@tweak[1],`16*1`(%rsp)
-+	aesenc		$rndkey0,$inout1
-+	 pxor	$twres,@tweak[4]
-+	 movdqa	@tweak[2],`16*2`(%rsp)
-+	aesenc		$rndkey0,$inout2
-+	aesenc		$rndkey0,$inout3
-+	 pxor	$twres,$twmask
-+	 movdqa	@tweak[4],`16*4`(%rsp)
-+	aesenc		$rndkey0,$inout4
-+	aesenc		$rndkey0,$inout5
-+	$movkey		64($key_),$rndkey0
-+	 movdqa	$twmask,`16*5`(%rsp)
-+	pshufd	\$0x5f,@tweak[5],$twres
-+	jmp	.Lxts_enc_loop6
-+.align	32
-+.Lxts_enc_loop6:
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	aesenc		$rndkey1,$inout4
-+	aesenc		$rndkey1,$inout5
-+	$movkey		-64($key,%rax),$rndkey1
-+	add		\$32,%rax
-+
-+	aesenc		$rndkey0,$inout0
-+	aesenc		$rndkey0,$inout1
-+	aesenc		$rndkey0,$inout2
-+	aesenc		$rndkey0,$inout3
-+	aesenc		$rndkey0,$inout4
-+	aesenc		$rndkey0,$inout5
-+	$movkey		-80($key,%rax),$rndkey0
-+	jnz		.Lxts_enc_loop6
-+
-+	movdqa	(%r8),$twmask			# start calculating next tweak
-+	movdqa	$twres,$twtmp
-+	paddd	$twres,$twres
-+	 aesenc		$rndkey1,$inout0
-+	paddq	@tweak[5],@tweak[5]
-+	psrad	\$31,$twtmp
-+	 aesenc		$rndkey1,$inout1
-+	pand	$twmask,$twtmp
-+	$movkey	($key_),@tweak[0]		# load round[0]
-+	 aesenc		$rndkey1,$inout2
-+	 aesenc		$rndkey1,$inout3
-+	 aesenc		$rndkey1,$inout4
-+	pxor	$twtmp,@tweak[5]
-+	movaps	@tweak[0],@tweak[1]		# copy round[0]
-+	 aesenc		$rndkey1,$inout5
-+	 $movkey	-64($key),$rndkey1
-+
-+	movdqa	$twres,$twtmp
-+	 aesenc		$rndkey0,$inout0
-+	paddd	$twres,$twres
-+	pxor	@tweak[5],@tweak[0]
-+	 aesenc		$rndkey0,$inout1
-+	psrad	\$31,$twtmp
-+	paddq	@tweak[5],@tweak[5]
-+	 aesenc		$rndkey0,$inout2
-+	 aesenc		$rndkey0,$inout3
-+	pand	$twmask,$twtmp
-+	movaps	@tweak[1],@tweak[2]
-+	 aesenc		$rndkey0,$inout4
-+	pxor	$twtmp,@tweak[5]
-+	movdqa	$twres,$twtmp
-+	 aesenc		$rndkey0,$inout5
-+	 $movkey	-48($key),$rndkey0
-+
-+	paddd	$twres,$twres
-+	 aesenc		$rndkey1,$inout0
-+	pxor	@tweak[5],@tweak[1]
-+	psrad	\$31,$twtmp
-+	 aesenc		$rndkey1,$inout1
-+	paddq	@tweak[5],@tweak[5]
-+	pand	$twmask,$twtmp
-+	 aesenc		$rndkey1,$inout2
-+	 aesenc		$rndkey1,$inout3
-+	 movdqa	@tweak[3],`16*3`(%rsp)
-+	pxor	$twtmp,@tweak[5]
-+	 aesenc		$rndkey1,$inout4
-+	movaps	@tweak[2],@tweak[3]
-+	movdqa	$twres,$twtmp
-+	 aesenc		$rndkey1,$inout5
-+	 $movkey	-32($key),$rndkey1
-+
-+	paddd	$twres,$twres
-+	 aesenc		$rndkey0,$inout0
-+	pxor	@tweak[5],@tweak[2]
-+	psrad	\$31,$twtmp
-+	 aesenc		$rndkey0,$inout1
-+	paddq	@tweak[5],@tweak[5]
-+	pand	$twmask,$twtmp
-+	 aesenc		$rndkey0,$inout2
-+	 aesenc		$rndkey0,$inout3
-+	 aesenc		$rndkey0,$inout4
-+	pxor	$twtmp,@tweak[5]
-+	movaps	@tweak[3],@tweak[4]
-+	 aesenc		$rndkey0,$inout5
-+
-+	movdqa	$twres,$rndkey0
-+	paddd	$twres,$twres
-+	 aesenc		$rndkey1,$inout0
-+	pxor	@tweak[5],@tweak[3]
-+	psrad	\$31,$rndkey0
-+	 aesenc		$rndkey1,$inout1
-+	paddq	@tweak[5],@tweak[5]
-+	pand	$twmask,$rndkey0
-+	 aesenc		$rndkey1,$inout2
-+	 aesenc		$rndkey1,$inout3
-+	pxor	$rndkey0,@tweak[5]
-+	$movkey		($key_),$rndkey0
-+	 aesenc		$rndkey1,$inout4
-+	 aesenc		$rndkey1,$inout5
-+	$movkey		16($key_),$rndkey1
-+
-+	pxor	@tweak[5],@tweak[4]
-+	 aesenclast	`16*0`(%rsp),$inout0
-+	psrad	\$31,$twres
-+	paddq	@tweak[5],@tweak[5]
-+	 aesenclast	`16*1`(%rsp),$inout1
-+	 aesenclast	`16*2`(%rsp),$inout2
-+	pand	$twmask,$twres
-+	mov	%r10,%rax			# restore $rounds
-+	 aesenclast	`16*3`(%rsp),$inout3
-+	 aesenclast	`16*4`(%rsp),$inout4
-+	 aesenclast	`16*5`(%rsp),$inout5
-+	pxor	$twres,@tweak[5]
-+
-+	lea	`16*6`($out),$out		# $out+=6*16
-+	movups	$inout0,`-16*6`($out)		# store 6 output blocks
-+	movups	$inout1,`-16*5`($out)
-+	movups	$inout2,`-16*4`($out)
-+	movups	$inout3,`-16*3`($out)
-+	movups	$inout4,`-16*2`($out)
-+	movups	$inout5,`-16*1`($out)
-+	sub	\$16*6,$len
-+	jnc	.Lxts_enc_grandloop		# loop if $len-=6*16 didn't borrow
-+
-+	mov	\$16+96,$rounds
-+	sub	$rnds_,$rounds
-+	mov	$key_,$key			# restore $key
-+	shr	\$4,$rounds			# restore original value
-+
-+.Lxts_enc_short:
-+	# at the point @tweak[0..5] are populated with tweak values
-+	mov	$rounds,$rnds_			# backup $rounds
-+	pxor	$rndkey0,@tweak[0]
-+	add	\$16*6,$len			# restore real remaining $len
-+	jz	.Lxts_enc_done			# done if ($len==0)
-+
-+	pxor	$rndkey0,@tweak[1]
-+	cmp	\$0x20,$len
-+	jb	.Lxts_enc_one			# $len is 1*16
-+	pxor	$rndkey0,@tweak[2]
-+	je	.Lxts_enc_two			# $len is 2*16
-+
-+	pxor	$rndkey0,@tweak[3]
-+	cmp	\$0x40,$len
-+	jb	.Lxts_enc_three			# $len is 3*16
-+	pxor	$rndkey0,@tweak[4]
-+	je	.Lxts_enc_four			# $len is 4*16
-+
-+	movdqu	($inp),$inout0			# $len is 5*16
-+	movdqu	16*1($inp),$inout1
-+	movdqu	16*2($inp),$inout2
-+	pxor	@tweak[0],$inout0
-+	movdqu	16*3($inp),$inout3
-+	pxor	@tweak[1],$inout1
-+	movdqu	16*4($inp),$inout4
-+	lea	16*5($inp),$inp			# $inp+=5*16
-+	pxor	@tweak[2],$inout2
-+	pxor	@tweak[3],$inout3
-+	pxor	@tweak[4],$inout4
-+	pxor	$inout5,$inout5
-+
-+	call	_aesni_encrypt6
-+
-+	xorps	@tweak[0],$inout0
-+	movdqa	@tweak[5],@tweak[0]
-+	xorps	@tweak[1],$inout1
-+	xorps	@tweak[2],$inout2
-+	movdqu	$inout0,($out)			# store 5 output blocks
-+	xorps	@tweak[3],$inout3
-+	movdqu	$inout1,16*1($out)
-+	xorps	@tweak[4],$inout4
-+	movdqu	$inout2,16*2($out)
-+	movdqu	$inout3,16*3($out)
-+	movdqu	$inout4,16*4($out)
-+	lea	16*5($out),$out			# $out+=5*16
-+	jmp	.Lxts_enc_done
-+
-+.align	16
-+.Lxts_enc_one:
-+	movups	($inp),$inout0
-+	lea	16*1($inp),$inp			# inp+=1*16
-+	xorps	@tweak[0],$inout0
-+___
-+	&aesni_generate1("enc",$key,$rounds);
-+$code.=<<___;
-+	xorps	@tweak[0],$inout0
-+	movdqa	@tweak[1],@tweak[0]
-+	movups	$inout0,($out)			# store one output block
-+	lea	16*1($out),$out			# $out+=1*16
-+	jmp	.Lxts_enc_done
-+
-+.align	16
-+.Lxts_enc_two:
-+	movups	($inp),$inout0
-+	movups	16($inp),$inout1
-+	lea	32($inp),$inp			# $inp+=2*16
-+	xorps	@tweak[0],$inout0
-+	xorps	@tweak[1],$inout1
-+
-+	call	_aesni_encrypt2
-+
-+	xorps	@tweak[0],$inout0
-+	movdqa	@tweak[2],@tweak[0]
-+	xorps	@tweak[1],$inout1
-+	movups	$inout0,($out)			# store 2 output blocks
-+	movups	$inout1,16*1($out)
-+	lea	16*2($out),$out			# $out+=2*16
-+	jmp	.Lxts_enc_done
-+
-+.align	16
-+.Lxts_enc_three:
-+	movups	($inp),$inout0
-+	movups	16*1($inp),$inout1
-+	movups	16*2($inp),$inout2
-+	lea	16*3($inp),$inp			# $inp+=3*16
-+	xorps	@tweak[0],$inout0
-+	xorps	@tweak[1],$inout1
-+	xorps	@tweak[2],$inout2
-+
-+	call	_aesni_encrypt3
-+
-+	xorps	@tweak[0],$inout0
-+	movdqa	@tweak[3],@tweak[0]
-+	xorps	@tweak[1],$inout1
-+	xorps	@tweak[2],$inout2
-+	movups	$inout0,($out)			# store 3 output blocks
-+	movups	$inout1,16*1($out)
-+	movups	$inout2,16*2($out)
-+	lea	16*3($out),$out			# $out+=3*16
-+	jmp	.Lxts_enc_done
-+
-+.align	16
-+.Lxts_enc_four:
-+	movups	($inp),$inout0
-+	movups	16*1($inp),$inout1
-+	movups	16*2($inp),$inout2
-+	xorps	@tweak[0],$inout0
-+	movups	16*3($inp),$inout3
-+	lea	16*4($inp),$inp			# $inp+=4*16
-+	xorps	@tweak[1],$inout1
-+	xorps	@tweak[2],$inout2
-+	xorps	@tweak[3],$inout3
-+
-+	call	_aesni_encrypt4
-+
-+	pxor	@tweak[0],$inout0
-+	movdqa	@tweak[4],@tweak[0]
-+	pxor	@tweak[1],$inout1
-+	pxor	@tweak[2],$inout2
-+	movdqu	$inout0,($out)			# store 4 output blocks
-+	pxor	@tweak[3],$inout3
-+	movdqu	$inout1,16*1($out)
-+	movdqu	$inout2,16*2($out)
-+	movdqu	$inout3,16*3($out)
-+	lea	16*4($out),$out			# $out+=4*16
-+	jmp	.Lxts_enc_done
-+
-+.align	16
-+.Lxts_enc_done:
-+	and	\$15,$len_			# see if $len%16 is 0
-+	jz	.Lxts_enc_ret
-+	mov	$len_,$len
-+
-+.Lxts_enc_steal:
-+	movzb	($inp),%eax			# borrow $rounds ...
-+	movzb	-16($out),%ecx			# ... and $key
-+	lea	1($inp),$inp
-+	mov	%al,-16($out)
-+	mov	%cl,0($out)
-+	lea	1($out),$out
-+	sub	\$1,$len
-+	jnz	.Lxts_enc_steal
-+
-+	sub	$len_,$out			# rewind $out
-+	mov	$key_,$key			# restore $key
-+	mov	$rnds_,$rounds			# restore $rounds
-+
-+	movups	-16($out),$inout0
-+	xorps	@tweak[0],$inout0
-+___
-+	&aesni_generate1("enc",$key,$rounds);
-+$code.=<<___;
-+	xorps	@tweak[0],$inout0
-+	movups	$inout0,-16($out)
-+
-+.Lxts_enc_ret:
-+	xorps	%xmm0,%xmm0			# clear register bank
-+	pxor	%xmm1,%xmm1
-+	pxor	%xmm2,%xmm2
-+	pxor	%xmm3,%xmm3
-+	pxor	%xmm4,%xmm4
-+	pxor	%xmm5,%xmm5
-+___
-+$code.=<<___ if (!$win64);
-+	pxor	%xmm6,%xmm6
-+	pxor	%xmm7,%xmm7
-+	movaps	%xmm0,0x00(%rsp)		# clear stack
-+	pxor	%xmm8,%xmm8
-+	movaps	%xmm0,0x10(%rsp)
-+	pxor	%xmm9,%xmm9
-+	movaps	%xmm0,0x20(%rsp)
-+	pxor	%xmm10,%xmm10
-+	movaps	%xmm0,0x30(%rsp)
-+	pxor	%xmm11,%xmm11
-+	movaps	%xmm0,0x40(%rsp)
-+	pxor	%xmm12,%xmm12
-+	movaps	%xmm0,0x50(%rsp)
-+	pxor	%xmm13,%xmm13
-+	movaps	%xmm0,0x60(%rsp)
-+	pxor	%xmm14,%xmm14
-+	pxor	%xmm15,%xmm15
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xa0(%rbp),%xmm6
-+	movaps	%xmm0,-0xa0(%rbp)		# clear stack
-+	movaps	-0x90(%rbp),%xmm7
-+	movaps	%xmm0,-0x90(%rbp)
-+	movaps	-0x80(%rbp),%xmm8
-+	movaps	%xmm0,-0x80(%rbp)
-+	movaps	-0x70(%rbp),%xmm9
-+	movaps	%xmm0,-0x70(%rbp)
-+	movaps	-0x60(%rbp),%xmm10
-+	movaps	%xmm0,-0x60(%rbp)
-+	movaps	-0x50(%rbp),%xmm11
-+	movaps	%xmm0,-0x50(%rbp)
-+	movaps	-0x40(%rbp),%xmm12
-+	movaps	%xmm0,-0x40(%rbp)
-+	movaps	-0x30(%rbp),%xmm13
-+	movaps	%xmm0,-0x30(%rbp)
-+	movaps	-0x20(%rbp),%xmm14
-+	movaps	%xmm0,-0x20(%rbp)
-+	movaps	-0x10(%rbp),%xmm15
-+	movaps	%xmm0,-0x10(%rbp)
-+	movaps	%xmm0,0x00(%rsp)
-+	movaps	%xmm0,0x10(%rsp)
-+	movaps	%xmm0,0x20(%rsp)
-+	movaps	%xmm0,0x30(%rsp)
-+	movaps	%xmm0,0x40(%rsp)
-+	movaps	%xmm0,0x50(%rsp)
-+	movaps	%xmm0,0x60(%rsp)
-+___
-+$code.=<<___;
-+	lea	(%rbp),%rsp
-+	pop	%rbp
-+.Lxts_enc_epilogue:
-+	ret
-+.size	aesni_xts_encrypt,.-aesni_xts_encrypt
-+___
-+
-+$code.=<<___;
-+.globl	aesni_xts_decrypt
-+.type	aesni_xts_decrypt,\@function,6
-+.align	16
-+aesni_xts_decrypt:
-+	lea	(%rsp),%rax
-+	push	%rbp
-+	sub	\$$frame_size,%rsp
-+	and	\$-16,%rsp	# Linux kernel stack can be incorrectly seeded
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,-0xa8(%rax)		# offload everything
-+	movaps	%xmm7,-0x98(%rax)
-+	movaps	%xmm8,-0x88(%rax)
-+	movaps	%xmm9,-0x78(%rax)
-+	movaps	%xmm10,-0x68(%rax)
-+	movaps	%xmm11,-0x58(%rax)
-+	movaps	%xmm12,-0x48(%rax)
-+	movaps	%xmm13,-0x38(%rax)
-+	movaps	%xmm14,-0x28(%rax)
-+	movaps	%xmm15,-0x18(%rax)
-+.Lxts_dec_body:
-+___
-+$code.=<<___;
-+	lea	-8(%rax),%rbp
-+	movups	($ivp),$inout0			# load clear-text tweak
-+	mov	240($key2),$rounds		# key2->rounds
-+	mov	240($key),$rnds_		# key1->rounds
-+___
-+	# generate the tweak
-+	&aesni_generate1("enc",$key2,$rounds,$inout0);
-+$code.=<<___;
-+	xor	%eax,%eax			# if ($len%16) len-=16;
-+	test	\$15,$len
-+	setnz	%al
-+	shl	\$4,%rax
-+	sub	%rax,$len
-+
-+	$movkey	($key),$rndkey0			# zero round key
-+	mov	$key,$key_			# backup $key
-+	mov	$rnds_,$rounds			# backup $rounds
-+	shl	\$4,$rnds_
-+	mov	$len,$len_			# backup $len
-+	and	\$-16,$len
-+
-+	$movkey	16($key,$rnds_),$rndkey1	# last round key
-+
-+	movdqa	.Lxts_magic(%rip),$twmask
-+	movdqa	$inout0,@tweak[5]
-+	pshufd	\$0x5f,$inout0,$twres
-+	pxor	$rndkey0,$rndkey1
-+___
-+    for ($i=0;$i<4;$i++) {
-+    $code.=<<___;
-+	movdqa	$twres,$twtmp
-+	paddd	$twres,$twres
-+	movdqa	@tweak[5],@tweak[$i]
-+	psrad	\$31,$twtmp			# broadcast upper bits
-+	paddq	@tweak[5],@tweak[5]
-+	pand	$twmask,$twtmp
-+	pxor	$rndkey0,@tweak[$i]
-+	pxor	$twtmp,@tweak[5]
-+___
-+    }
-+$code.=<<___;
-+	movdqa	@tweak[5],@tweak[4]
-+	psrad	\$31,$twres
-+	paddq	@tweak[5],@tweak[5]
-+	pand	$twmask,$twres
-+	pxor	$rndkey0,@tweak[4]
-+	pxor	$twres,@tweak[5]
-+	movaps	$rndkey1,0x60(%rsp)		# save round[0]^round[last]
-+
-+	sub	\$16*6,$len
-+	jc	.Lxts_dec_short			# if $len-=6*16 borrowed
-+
-+	mov	\$16+96,$rounds
-+	lea	32($key_,$rnds_),$key		# end of key schedule
-+	sub	%r10,%rax			# twisted $rounds
-+	$movkey	16($key_),$rndkey1
-+	mov	%rax,%r10			# backup twisted $rounds
-+	lea	.Lxts_magic(%rip),%r8
-+	jmp	.Lxts_dec_grandloop
-+
-+.align	32
-+.Lxts_dec_grandloop:
-+	movdqu	`16*0`($inp),$inout0		# load input
-+	movdqa	$rndkey0,$twmask
-+	movdqu	`16*1`($inp),$inout1
-+	pxor	@tweak[0],$inout0		# intput^=tweak^round[0]
-+	movdqu	`16*2`($inp),$inout2
-+	pxor	@tweak[1],$inout1
-+	 aesdec		$rndkey1,$inout0
-+	movdqu	`16*3`($inp),$inout3
-+	pxor	@tweak[2],$inout2
-+	 aesdec		$rndkey1,$inout1
-+	movdqu	`16*4`($inp),$inout4
-+	pxor	@tweak[3],$inout3
-+	 aesdec		$rndkey1,$inout2
-+	movdqu	`16*5`($inp),$inout5
-+	pxor	@tweak[5],$twmask		# round[0]^=tweak[5]
-+	 movdqa	0x60(%rsp),$twres		# load round[0]^round[last]
-+	pxor	@tweak[4],$inout4
-+	 aesdec		$rndkey1,$inout3
-+	$movkey	32($key_),$rndkey0
-+	lea	`16*6`($inp),$inp
-+	pxor	$twmask,$inout5
-+
-+	 pxor	$twres,@tweak[0]		# calclulate tweaks^round[last]
-+	aesdec		$rndkey1,$inout4
-+	 pxor	$twres,@tweak[1]
-+	 movdqa	@tweak[0],`16*0`(%rsp)		# put aside tweaks^last round key
-+	aesdec		$rndkey1,$inout5
-+	$movkey		48($key_),$rndkey1
-+	 pxor	$twres,@tweak[2]
-+
-+	aesdec		$rndkey0,$inout0
-+	 pxor	$twres,@tweak[3]
-+	 movdqa	@tweak[1],`16*1`(%rsp)
-+	aesdec		$rndkey0,$inout1
-+	 pxor	$twres,@tweak[4]
-+	 movdqa	@tweak[2],`16*2`(%rsp)
-+	aesdec		$rndkey0,$inout2
-+	aesdec		$rndkey0,$inout3
-+	 pxor	$twres,$twmask
-+	 movdqa	@tweak[4],`16*4`(%rsp)
-+	aesdec		$rndkey0,$inout4
-+	aesdec		$rndkey0,$inout5
-+	$movkey		64($key_),$rndkey0
-+	 movdqa	$twmask,`16*5`(%rsp)
-+	pshufd	\$0x5f,@tweak[5],$twres
-+	jmp	.Lxts_dec_loop6
-+.align	32
-+.Lxts_dec_loop6:
-+	aesdec		$rndkey1,$inout0
-+	aesdec		$rndkey1,$inout1
-+	aesdec		$rndkey1,$inout2
-+	aesdec		$rndkey1,$inout3
-+	aesdec		$rndkey1,$inout4
-+	aesdec		$rndkey1,$inout5
-+	$movkey		-64($key,%rax),$rndkey1
-+	add		\$32,%rax
-+
-+	aesdec		$rndkey0,$inout0
-+	aesdec		$rndkey0,$inout1
-+	aesdec		$rndkey0,$inout2
-+	aesdec		$rndkey0,$inout3
-+	aesdec		$rndkey0,$inout4
-+	aesdec		$rndkey0,$inout5
-+	$movkey		-80($key,%rax),$rndkey0
-+	jnz		.Lxts_dec_loop6
-+
-+	movdqa	(%r8),$twmask			# start calculating next tweak
-+	movdqa	$twres,$twtmp
-+	paddd	$twres,$twres
-+	 aesdec		$rndkey1,$inout0
-+	paddq	@tweak[5],@tweak[5]
-+	psrad	\$31,$twtmp
-+	 aesdec		$rndkey1,$inout1
-+	pand	$twmask,$twtmp
-+	$movkey	($key_),@tweak[0]		# load round[0]
-+	 aesdec		$rndkey1,$inout2
-+	 aesdec		$rndkey1,$inout3
-+	 aesdec		$rndkey1,$inout4
-+	pxor	$twtmp,@tweak[5]
-+	movaps	@tweak[0],@tweak[1]		# copy round[0]
-+	 aesdec		$rndkey1,$inout5
-+	 $movkey	-64($key),$rndkey1
-+
-+	movdqa	$twres,$twtmp
-+	 aesdec		$rndkey0,$inout0
-+	paddd	$twres,$twres
-+	pxor	@tweak[5],@tweak[0]
-+	 aesdec		$rndkey0,$inout1
-+	psrad	\$31,$twtmp
-+	paddq	@tweak[5],@tweak[5]
-+	 aesdec		$rndkey0,$inout2
-+	 aesdec		$rndkey0,$inout3
-+	pand	$twmask,$twtmp
-+	movaps	@tweak[1],@tweak[2]
-+	 aesdec		$rndkey0,$inout4
-+	pxor	$twtmp,@tweak[5]
-+	movdqa	$twres,$twtmp
-+	 aesdec		$rndkey0,$inout5
-+	 $movkey	-48($key),$rndkey0
-+
-+	paddd	$twres,$twres
-+	 aesdec		$rndkey1,$inout0
-+	pxor	@tweak[5],@tweak[1]
-+	psrad	\$31,$twtmp
-+	 aesdec		$rndkey1,$inout1
-+	paddq	@tweak[5],@tweak[5]
-+	pand	$twmask,$twtmp
-+	 aesdec		$rndkey1,$inout2
-+	 aesdec		$rndkey1,$inout3
-+	 movdqa	@tweak[3],`16*3`(%rsp)
-+	pxor	$twtmp,@tweak[5]
-+	 aesdec		$rndkey1,$inout4
-+	movaps	@tweak[2],@tweak[3]
-+	movdqa	$twres,$twtmp
-+	 aesdec		$rndkey1,$inout5
-+	 $movkey	-32($key),$rndkey1
-+
-+	paddd	$twres,$twres
-+	 aesdec		$rndkey0,$inout0
-+	pxor	@tweak[5],@tweak[2]
-+	psrad	\$31,$twtmp
-+	 aesdec		$rndkey0,$inout1
-+	paddq	@tweak[5],@tweak[5]
-+	pand	$twmask,$twtmp
-+	 aesdec		$rndkey0,$inout2
-+	 aesdec		$rndkey0,$inout3
-+	 aesdec		$rndkey0,$inout4
-+	pxor	$twtmp,@tweak[5]
-+	movaps	@tweak[3],@tweak[4]
-+	 aesdec		$rndkey0,$inout5
-+
-+	movdqa	$twres,$rndkey0
-+	paddd	$twres,$twres
-+	 aesdec		$rndkey1,$inout0
-+	pxor	@tweak[5],@tweak[3]
-+	psrad	\$31,$rndkey0
-+	 aesdec		$rndkey1,$inout1
-+	paddq	@tweak[5],@tweak[5]
-+	pand	$twmask,$rndkey0
-+	 aesdec		$rndkey1,$inout2
-+	 aesdec		$rndkey1,$inout3
-+	pxor	$rndkey0,@tweak[5]
-+	$movkey		($key_),$rndkey0
-+	 aesdec		$rndkey1,$inout4
-+	 aesdec		$rndkey1,$inout5
-+	$movkey		16($key_),$rndkey1
-+
-+	pxor	@tweak[5],@tweak[4]
-+	 aesdeclast	`16*0`(%rsp),$inout0
-+	psrad	\$31,$twres
-+	paddq	@tweak[5],@tweak[5]
-+	 aesdeclast	`16*1`(%rsp),$inout1
-+	 aesdeclast	`16*2`(%rsp),$inout2
-+	pand	$twmask,$twres
-+	mov	%r10,%rax			# restore $rounds
-+	 aesdeclast	`16*3`(%rsp),$inout3
-+	 aesdeclast	`16*4`(%rsp),$inout4
-+	 aesdeclast	`16*5`(%rsp),$inout5
-+	pxor	$twres,@tweak[5]
-+
-+	lea	`16*6`($out),$out		# $out+=6*16
-+	movups	$inout0,`-16*6`($out)		# store 6 output blocks
-+	movups	$inout1,`-16*5`($out)
-+	movups	$inout2,`-16*4`($out)
-+	movups	$inout3,`-16*3`($out)
-+	movups	$inout4,`-16*2`($out)
-+	movups	$inout5,`-16*1`($out)
-+	sub	\$16*6,$len
-+	jnc	.Lxts_dec_grandloop		# loop if $len-=6*16 didn't borrow
-+
-+	mov	\$16+96,$rounds
-+	sub	$rnds_,$rounds
-+	mov	$key_,$key			# restore $key
-+	shr	\$4,$rounds			# restore original value
-+
-+.Lxts_dec_short:
-+	# at the point @tweak[0..5] are populated with tweak values
-+	mov	$rounds,$rnds_			# backup $rounds
-+	pxor	$rndkey0,@tweak[0]
-+	pxor	$rndkey0,@tweak[1]
-+	add	\$16*6,$len			# restore real remaining $len
-+	jz	.Lxts_dec_done			# done if ($len==0)
-+
-+	pxor	$rndkey0,@tweak[2]
-+	cmp	\$0x20,$len
-+	jb	.Lxts_dec_one			# $len is 1*16
-+	pxor	$rndkey0,@tweak[3]
-+	je	.Lxts_dec_two			# $len is 2*16
-+
-+	pxor	$rndkey0,@tweak[4]
-+	cmp	\$0x40,$len
-+	jb	.Lxts_dec_three			# $len is 3*16
-+	je	.Lxts_dec_four			# $len is 4*16
-+
-+	movdqu	($inp),$inout0			# $len is 5*16
-+	movdqu	16*1($inp),$inout1
-+	movdqu	16*2($inp),$inout2
-+	pxor	@tweak[0],$inout0
-+	movdqu	16*3($inp),$inout3
-+	pxor	@tweak[1],$inout1
-+	movdqu	16*4($inp),$inout4
-+	lea	16*5($inp),$inp			# $inp+=5*16
-+	pxor	@tweak[2],$inout2
-+	pxor	@tweak[3],$inout3
-+	pxor	@tweak[4],$inout4
-+
-+	call	_aesni_decrypt6
-+
-+	xorps	@tweak[0],$inout0
-+	xorps	@tweak[1],$inout1
-+	xorps	@tweak[2],$inout2
-+	movdqu	$inout0,($out)			# store 5 output blocks
-+	xorps	@tweak[3],$inout3
-+	movdqu	$inout1,16*1($out)
-+	xorps	@tweak[4],$inout4
-+	movdqu	$inout2,16*2($out)
-+	 pxor		$twtmp,$twtmp
-+	movdqu	$inout3,16*3($out)
-+	 pcmpgtd	@tweak[5],$twtmp
-+	movdqu	$inout4,16*4($out)
-+	lea	16*5($out),$out			# $out+=5*16
-+	 pshufd		\$0x13,$twtmp,@tweak[1]	# $twres
-+	and	\$15,$len_
-+	jz	.Lxts_dec_ret
-+
-+	movdqa	@tweak[5],@tweak[0]
-+	paddq	@tweak[5],@tweak[5]		# psllq 1,$tweak
-+	pand	$twmask,@tweak[1]		# isolate carry and residue
-+	pxor	@tweak[5],@tweak[1]
-+	jmp	.Lxts_dec_done2
-+
-+.align	16
-+.Lxts_dec_one:
-+	movups	($inp),$inout0
-+	lea	16*1($inp),$inp			# $inp+=1*16
-+	xorps	@tweak[0],$inout0
-+___
-+	&aesni_generate1("dec",$key,$rounds);
-+$code.=<<___;
-+	xorps	@tweak[0],$inout0
-+	movdqa	@tweak[1],@tweak[0]
-+	movups	$inout0,($out)			# store one output block
-+	movdqa	@tweak[2],@tweak[1]
-+	lea	16*1($out),$out			# $out+=1*16
-+	jmp	.Lxts_dec_done
-+
-+.align	16
-+.Lxts_dec_two:
-+	movups	($inp),$inout0
-+	movups	16($inp),$inout1
-+	lea	32($inp),$inp			# $inp+=2*16
-+	xorps	@tweak[0],$inout0
-+	xorps	@tweak[1],$inout1
-+
-+	call	_aesni_decrypt2
-+
-+	xorps	@tweak[0],$inout0
-+	movdqa	@tweak[2],@tweak[0]
-+	xorps	@tweak[1],$inout1
-+	movdqa	@tweak[3],@tweak[1]
-+	movups	$inout0,($out)			# store 2 output blocks
-+	movups	$inout1,16*1($out)
-+	lea	16*2($out),$out			# $out+=2*16
-+	jmp	.Lxts_dec_done
-+
-+.align	16
-+.Lxts_dec_three:
-+	movups	($inp),$inout0
-+	movups	16*1($inp),$inout1
-+	movups	16*2($inp),$inout2
-+	lea	16*3($inp),$inp			# $inp+=3*16
-+	xorps	@tweak[0],$inout0
-+	xorps	@tweak[1],$inout1
-+	xorps	@tweak[2],$inout2
-+
-+	call	_aesni_decrypt3
-+
-+	xorps	@tweak[0],$inout0
-+	movdqa	@tweak[3],@tweak[0]
-+	xorps	@tweak[1],$inout1
-+	movdqa	@tweak[4],@tweak[1]
-+	xorps	@tweak[2],$inout2
-+	movups	$inout0,($out)			# store 3 output blocks
-+	movups	$inout1,16*1($out)
-+	movups	$inout2,16*2($out)
-+	lea	16*3($out),$out			# $out+=3*16
-+	jmp	.Lxts_dec_done
-+
-+.align	16
-+.Lxts_dec_four:
-+	movups	($inp),$inout0
-+	movups	16*1($inp),$inout1
-+	movups	16*2($inp),$inout2
-+	xorps	@tweak[0],$inout0
-+	movups	16*3($inp),$inout3
-+	lea	16*4($inp),$inp			# $inp+=4*16
-+	xorps	@tweak[1],$inout1
-+	xorps	@tweak[2],$inout2
-+	xorps	@tweak[3],$inout3
-+
-+	call	_aesni_decrypt4
-+
-+	pxor	@tweak[0],$inout0
-+	movdqa	@tweak[4],@tweak[0]
-+	pxor	@tweak[1],$inout1
-+	movdqa	@tweak[5],@tweak[1]
-+	pxor	@tweak[2],$inout2
-+	movdqu	$inout0,($out)			# store 4 output blocks
-+	pxor	@tweak[3],$inout3
-+	movdqu	$inout1,16*1($out)
-+	movdqu	$inout2,16*2($out)
-+	movdqu	$inout3,16*3($out)
-+	lea	16*4($out),$out			# $out+=4*16
-+	jmp	.Lxts_dec_done
-+
-+.align	16
-+.Lxts_dec_done:
-+	and	\$15,$len_			# see if $len%16 is 0
-+	jz	.Lxts_dec_ret
-+.Lxts_dec_done2:
-+	mov	$len_,$len
-+	mov	$key_,$key			# restore $key
-+	mov	$rnds_,$rounds			# restore $rounds
-+
-+	movups	($inp),$inout0
-+	xorps	@tweak[1],$inout0
-+___
-+	&aesni_generate1("dec",$key,$rounds);
-+$code.=<<___;
-+	xorps	@tweak[1],$inout0
-+	movups	$inout0,($out)
-+
-+.Lxts_dec_steal:
-+	movzb	16($inp),%eax			# borrow $rounds ...
-+	movzb	($out),%ecx			# ... and $key
-+	lea	1($inp),$inp
-+	mov	%al,($out)
-+	mov	%cl,16($out)
-+	lea	1($out),$out
-+	sub	\$1,$len
-+	jnz	.Lxts_dec_steal
-+
-+	sub	$len_,$out			# rewind $out
-+	mov	$key_,$key			# restore $key
-+	mov	$rnds_,$rounds			# restore $rounds
-+
-+	movups	($out),$inout0
-+	xorps	@tweak[0],$inout0
-+___
-+	&aesni_generate1("dec",$key,$rounds);
-+$code.=<<___;
-+	xorps	@tweak[0],$inout0
-+	movups	$inout0,($out)
-+
-+.Lxts_dec_ret:
-+	xorps	%xmm0,%xmm0			# clear register bank
-+	pxor	%xmm1,%xmm1
-+	pxor	%xmm2,%xmm2
-+	pxor	%xmm3,%xmm3
-+	pxor	%xmm4,%xmm4
-+	pxor	%xmm5,%xmm5
-+___
-+$code.=<<___ if (!$win64);
-+	pxor	%xmm6,%xmm6
-+	pxor	%xmm7,%xmm7
-+	movaps	%xmm0,0x00(%rsp)		# clear stack
-+	pxor	%xmm8,%xmm8
-+	movaps	%xmm0,0x10(%rsp)
-+	pxor	%xmm9,%xmm9
-+	movaps	%xmm0,0x20(%rsp)
-+	pxor	%xmm10,%xmm10
-+	movaps	%xmm0,0x30(%rsp)
-+	pxor	%xmm11,%xmm11
-+	movaps	%xmm0,0x40(%rsp)
-+	pxor	%xmm12,%xmm12
-+	movaps	%xmm0,0x50(%rsp)
-+	pxor	%xmm13,%xmm13
-+	movaps	%xmm0,0x60(%rsp)
-+	pxor	%xmm14,%xmm14
-+	pxor	%xmm15,%xmm15
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xa0(%rbp),%xmm6
-+	movaps	%xmm0,-0xa0(%rbp)		# clear stack
-+	movaps	-0x90(%rbp),%xmm7
-+	movaps	%xmm0,-0x90(%rbp)
-+	movaps	-0x80(%rbp),%xmm8
-+	movaps	%xmm0,-0x80(%rbp)
-+	movaps	-0x70(%rbp),%xmm9
-+	movaps	%xmm0,-0x70(%rbp)
-+	movaps	-0x60(%rbp),%xmm10
-+	movaps	%xmm0,-0x60(%rbp)
-+	movaps	-0x50(%rbp),%xmm11
-+	movaps	%xmm0,-0x50(%rbp)
-+	movaps	-0x40(%rbp),%xmm12
-+	movaps	%xmm0,-0x40(%rbp)
-+	movaps	-0x30(%rbp),%xmm13
-+	movaps	%xmm0,-0x30(%rbp)
-+	movaps	-0x20(%rbp),%xmm14
-+	movaps	%xmm0,-0x20(%rbp)
-+	movaps	-0x10(%rbp),%xmm15
-+	movaps	%xmm0,-0x10(%rbp)
-+	movaps	%xmm0,0x00(%rsp)
-+	movaps	%xmm0,0x10(%rsp)
-+	movaps	%xmm0,0x20(%rsp)
-+	movaps	%xmm0,0x30(%rsp)
-+	movaps	%xmm0,0x40(%rsp)
-+	movaps	%xmm0,0x50(%rsp)
-+	movaps	%xmm0,0x60(%rsp)
-+___
-+$code.=<<___;
-+	lea	(%rbp),%rsp
-+	pop	%rbp
-+.Lxts_dec_epilogue:
-+	ret
-+.size	aesni_xts_decrypt,.-aesni_xts_decrypt
-+___
-+}
-+
-+######################################################################
-+# void aesni_ocb_[en|de]crypt(const char *inp, char *out, size_t blocks,
-+#	const AES_KEY *key, unsigned int start_block_num,
-+#	unsigned char offset_i[16], const unsigned char L_[][16],
-+#	unsigned char checksum[16]);
-+#
-+{
-+my @offset=map("%xmm$_",(10..15));
-+my ($checksum,$rndkey0l)=("%xmm8","%xmm9");
-+my ($block_num,$offset_p)=("%r8","%r9");		# 5th and 6th arguments
-+my ($L_p,$checksum_p) = ("%rbx","%rbp");
-+my ($i1,$i3,$i5) = ("%r12","%r13","%r14");
-+my $seventh_arg = $win64 ? 56 : 8;
-+my $blocks = $len;
-+
-+$code.=<<___;
-+.globl	aesni_ocb_encrypt
-+.type	aesni_ocb_encrypt,\@function,6
-+.align	32
-+aesni_ocb_encrypt:
-+	lea	(%rsp),%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa0(%rsp),%rsp
-+	movaps	%xmm6,0x00(%rsp)		# offload everything
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,0x40(%rsp)
-+	movaps	%xmm11,0x50(%rsp)
-+	movaps	%xmm12,0x60(%rsp)
-+	movaps	%xmm13,0x70(%rsp)
-+	movaps	%xmm14,0x80(%rsp)
-+	movaps	%xmm15,0x90(%rsp)
-+.Locb_enc_body:
-+___
-+$code.=<<___;
-+	mov	$seventh_arg(%rax),$L_p		# 7th argument
-+	mov	$seventh_arg+8(%rax),$checksum_p# 8th argument
-+
-+	mov	240($key),$rnds_
-+	mov	$key,$key_
-+	shl	\$4,$rnds_
-+	$movkey	($key),$rndkey0l		# round[0]
-+	$movkey	16($key,$rnds_),$rndkey1	# round[last]
-+
-+	movdqu	($offset_p),@offset[5]		# load last offset_i
-+	pxor	$rndkey1,$rndkey0l		# round[0] ^ round[last]
-+	pxor	$rndkey1,@offset[5]		# offset_i ^ round[last]
-+
-+	mov	\$16+32,$rounds
-+	lea	32($key_,$rnds_),$key
-+	$movkey	16($key_),$rndkey1		# round[1]
-+	sub	%r10,%rax			# twisted $rounds
-+	mov	%rax,%r10			# backup twisted $rounds
-+
-+	movdqu	($L_p),@offset[0]		# L_0 for all odd-numbered blocks
-+	movdqu	($checksum_p),$checksum		# load checksum
-+
-+	test	\$1,$block_num			# is first block number odd?
-+	jnz	.Locb_enc_odd
-+
-+	bsf	$block_num,$i1
-+	add	\$1,$block_num
-+	shl	\$4,$i1
-+	movdqu	($L_p,$i1),$inout5		# borrow
-+	movdqu	($inp),$inout0
-+	lea	16($inp),$inp
-+
-+	call	__ocb_encrypt1
-+
-+	movdqa	$inout5,@offset[5]
-+	movups	$inout0,($out)
-+	lea	16($out),$out
-+	sub	\$1,$blocks
-+	jz	.Locb_enc_done
-+
-+.Locb_enc_odd:
-+	lea	1($block_num),$i1		# even-numbered blocks
-+	lea	3($block_num),$i3
-+	lea	5($block_num),$i5
-+	lea	6($block_num),$block_num
-+	bsf	$i1,$i1				# ntz(block)
-+	bsf	$i3,$i3
-+	bsf	$i5,$i5
-+	shl	\$4,$i1				# ntz(block) -> table offset
-+	shl	\$4,$i3
-+	shl	\$4,$i5
-+
-+	sub	\$6,$blocks
-+	jc	.Locb_enc_short
-+	jmp	.Locb_enc_grandloop
-+
-+.align	32
-+.Locb_enc_grandloop:
-+	movdqu	`16*0`($inp),$inout0		# load input
-+	movdqu	`16*1`($inp),$inout1
-+	movdqu	`16*2`($inp),$inout2
-+	movdqu	`16*3`($inp),$inout3
-+	movdqu	`16*4`($inp),$inout4
-+	movdqu	`16*5`($inp),$inout5
-+	lea	`16*6`($inp),$inp
-+
-+	call	__ocb_encrypt6
-+
-+	movups	$inout0,`16*0`($out)		# store output
-+	movups	$inout1,`16*1`($out)
-+	movups	$inout2,`16*2`($out)
-+	movups	$inout3,`16*3`($out)
-+	movups	$inout4,`16*4`($out)
-+	movups	$inout5,`16*5`($out)
-+	lea	`16*6`($out),$out
-+	sub	\$6,$blocks
-+	jnc	.Locb_enc_grandloop
-+
-+.Locb_enc_short:
-+	add	\$6,$blocks
-+	jz	.Locb_enc_done
-+
-+	movdqu	`16*0`($inp),$inout0
-+	cmp	\$2,$blocks
-+	jb	.Locb_enc_one
-+	movdqu	`16*1`($inp),$inout1
-+	je	.Locb_enc_two
-+
-+	movdqu	`16*2`($inp),$inout2
-+	cmp	\$4,$blocks
-+	jb	.Locb_enc_three
-+	movdqu	`16*3`($inp),$inout3
-+	je	.Locb_enc_four
-+
-+	movdqu	`16*4`($inp),$inout4
-+	pxor	$inout5,$inout5
-+
-+	call	__ocb_encrypt6
-+
-+	movdqa	@offset[4],@offset[5]
-+	movups	$inout0,`16*0`($out)
-+	movups	$inout1,`16*1`($out)
-+	movups	$inout2,`16*2`($out)
-+	movups	$inout3,`16*3`($out)
-+	movups	$inout4,`16*4`($out)
-+
-+	jmp	.Locb_enc_done
-+
-+.align	16
-+.Locb_enc_one:
-+	movdqa	@offset[0],$inout5		# borrow
-+
-+	call	__ocb_encrypt1
-+
-+	movdqa	$inout5,@offset[5]
-+	movups	$inout0,`16*0`($out)
-+	jmp	.Locb_enc_done
-+
-+.align	16
-+.Locb_enc_two:
-+	pxor	$inout2,$inout2
-+	pxor	$inout3,$inout3
-+
-+	call	__ocb_encrypt4
-+
-+	movdqa	@offset[1],@offset[5]
-+	movups	$inout0,`16*0`($out)
-+	movups	$inout1,`16*1`($out)
-+
-+	jmp	.Locb_enc_done
-+
-+.align	16
-+.Locb_enc_three:
-+	pxor	$inout3,$inout3
-+
-+	call	__ocb_encrypt4
-+
-+	movdqa	@offset[2],@offset[5]
-+	movups	$inout0,`16*0`($out)
-+	movups	$inout1,`16*1`($out)
-+	movups	$inout2,`16*2`($out)
-+
-+	jmp	.Locb_enc_done
-+
-+.align	16
-+.Locb_enc_four:
-+	call	__ocb_encrypt4
-+
-+	movdqa	@offset[3],@offset[5]
-+	movups	$inout0,`16*0`($out)
-+	movups	$inout1,`16*1`($out)
-+	movups	$inout2,`16*2`($out)
-+	movups	$inout3,`16*3`($out)
-+
-+.Locb_enc_done:
-+	pxor	$rndkey0,@offset[5]		# "remove" round[last]
-+	movdqu	$checksum,($checksum_p)		# store checksum
-+	movdqu	@offset[5],($offset_p)		# store last offset_i
-+
-+	xorps	%xmm0,%xmm0			# clear register bank
-+	pxor	%xmm1,%xmm1
-+	pxor	%xmm2,%xmm2
-+	pxor	%xmm3,%xmm3
-+	pxor	%xmm4,%xmm4
-+	pxor	%xmm5,%xmm5
-+___
-+$code.=<<___ if (!$win64);
-+	pxor	%xmm6,%xmm6
-+	pxor	%xmm7,%xmm7
-+	pxor	%xmm8,%xmm8
-+	pxor	%xmm9,%xmm9
-+	pxor	%xmm10,%xmm10
-+	pxor	%xmm11,%xmm11
-+	pxor	%xmm12,%xmm12
-+	pxor	%xmm13,%xmm13
-+	pxor	%xmm14,%xmm14
-+	pxor	%xmm15,%xmm15
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x00(%rsp),%xmm6
-+	movaps	%xmm0,0x00(%rsp)		# clear stack
-+	movaps	0x10(%rsp),%xmm7
-+	movaps	%xmm0,0x10(%rsp)
-+	movaps	0x20(%rsp),%xmm8
-+	movaps	%xmm0,0x20(%rsp)
-+	movaps	0x30(%rsp),%xmm9
-+	movaps	%xmm0,0x30(%rsp)
-+	movaps	0x40(%rsp),%xmm10
-+	movaps	%xmm0,0x40(%rsp)
-+	movaps	0x50(%rsp),%xmm11
-+	movaps	%xmm0,0x50(%rsp)
-+	movaps	0x60(%rsp),%xmm12
-+	movaps	%xmm0,0x60(%rsp)
-+	movaps	0x70(%rsp),%xmm13
-+	movaps	%xmm0,0x70(%rsp)
-+	movaps	0x80(%rsp),%xmm14
-+	movaps	%xmm0,0x80(%rsp)
-+	movaps	0x90(%rsp),%xmm15
-+	movaps	%xmm0,0x90(%rsp)
-+	lea	0xa0+0x28(%rsp),%rax
-+.Locb_enc_pop:
-+	lea	0xa0(%rsp),%rsp
-+___
-+$code.=<<___;
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+.Locb_enc_epilogue:
-+	ret
-+.size	aesni_ocb_encrypt,.-aesni_ocb_encrypt
-+
-+.type	__ocb_encrypt6,\@abi-omnipotent
-+.align	32
-+__ocb_encrypt6:
-+	 pxor		$rndkey0l,@offset[5]	# offset_i ^ round[0]
-+	 movdqu		($L_p,$i1),@offset[1]
-+	 movdqa		@offset[0],@offset[2]
-+	 movdqu		($L_p,$i3),@offset[3]
-+	 movdqa		@offset[0],@offset[4]
-+	 pxor		@offset[5],@offset[0]
-+	 movdqu		($L_p,$i5),@offset[5]
-+	 pxor		@offset[0],@offset[1]
-+	pxor		$inout0,$checksum	# accumulate checksum
-+	pxor		@offset[0],$inout0	# input ^ round[0] ^ offset_i
-+	 pxor		@offset[1],@offset[2]
-+	pxor		$inout1,$checksum
-+	pxor		@offset[1],$inout1
-+	 pxor		@offset[2],@offset[3]
-+	pxor		$inout2,$checksum
-+	pxor		@offset[2],$inout2
-+	 pxor		@offset[3],@offset[4]
-+	pxor		$inout3,$checksum
-+	pxor		@offset[3],$inout3
-+	 pxor		@offset[4],@offset[5]
-+	pxor		$inout4,$checksum
-+	pxor		@offset[4],$inout4
-+	pxor		$inout5,$checksum
-+	pxor		@offset[5],$inout5
-+	$movkey		32($key_),$rndkey0
-+
-+	lea		1($block_num),$i1	# even-numbered blocks
-+	lea		3($block_num),$i3
-+	lea		5($block_num),$i5
-+	add		\$6,$block_num
-+	 pxor		$rndkey0l,@offset[0]	# offset_i ^ round[last]
-+	bsf		$i1,$i1			# ntz(block)
-+	bsf		$i3,$i3
-+	bsf		$i5,$i5
-+
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	 pxor		$rndkey0l,@offset[1]
-+	 pxor		$rndkey0l,@offset[2]
-+	aesenc		$rndkey1,$inout4
-+	 pxor		$rndkey0l,@offset[3]
-+	 pxor		$rndkey0l,@offset[4]
-+	aesenc		$rndkey1,$inout5
-+	$movkey		48($key_),$rndkey1
-+	 pxor		$rndkey0l,@offset[5]
-+
-+	aesenc		$rndkey0,$inout0
-+	aesenc		$rndkey0,$inout1
-+	aesenc		$rndkey0,$inout2
-+	aesenc		$rndkey0,$inout3
-+	aesenc		$rndkey0,$inout4
-+	aesenc		$rndkey0,$inout5
-+	$movkey		64($key_),$rndkey0
-+	shl		\$4,$i1			# ntz(block) -> table offset
-+	shl		\$4,$i3
-+	jmp		.Locb_enc_loop6
-+
-+.align	32
-+.Locb_enc_loop6:
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	aesenc		$rndkey1,$inout4
-+	aesenc		$rndkey1,$inout5
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+
-+	aesenc		$rndkey0,$inout0
-+	aesenc		$rndkey0,$inout1
-+	aesenc		$rndkey0,$inout2
-+	aesenc		$rndkey0,$inout3
-+	aesenc		$rndkey0,$inout4
-+	aesenc		$rndkey0,$inout5
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.Locb_enc_loop6
-+
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	aesenc		$rndkey1,$inout4
-+	aesenc		$rndkey1,$inout5
-+	$movkey		16($key_),$rndkey1
-+	shl		\$4,$i5
-+
-+	aesenclast	@offset[0],$inout0
-+	movdqu		($L_p),@offset[0]	# L_0 for all odd-numbered blocks
-+	mov		%r10,%rax		# restore twisted rounds
-+	aesenclast	@offset[1],$inout1
-+	aesenclast	@offset[2],$inout2
-+	aesenclast	@offset[3],$inout3
-+	aesenclast	@offset[4],$inout4
-+	aesenclast	@offset[5],$inout5
-+	ret
-+.size	__ocb_encrypt6,.-__ocb_encrypt6
-+
-+.type	__ocb_encrypt4,\@abi-omnipotent
-+.align	32
-+__ocb_encrypt4:
-+	 pxor		$rndkey0l,@offset[5]	# offset_i ^ round[0]
-+	 movdqu		($L_p,$i1),@offset[1]
-+	 movdqa		@offset[0],@offset[2]
-+	 movdqu		($L_p,$i3),@offset[3]
-+	 pxor		@offset[5],@offset[0]
-+	 pxor		@offset[0],@offset[1]
-+	pxor		$inout0,$checksum	# accumulate checksum
-+	pxor		@offset[0],$inout0	# input ^ round[0] ^ offset_i
-+	 pxor		@offset[1],@offset[2]
-+	pxor		$inout1,$checksum
-+	pxor		@offset[1],$inout1
-+	 pxor		@offset[2],@offset[3]
-+	pxor		$inout2,$checksum
-+	pxor		@offset[2],$inout2
-+	pxor		$inout3,$checksum
-+	pxor		@offset[3],$inout3
-+	$movkey		32($key_),$rndkey0
-+
-+	 pxor		$rndkey0l,@offset[0]	# offset_i ^ round[last]
-+	 pxor		$rndkey0l,@offset[1]
-+	 pxor		$rndkey0l,@offset[2]
-+	 pxor		$rndkey0l,@offset[3]
-+
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	$movkey		48($key_),$rndkey1
-+
-+	aesenc		$rndkey0,$inout0
-+	aesenc		$rndkey0,$inout1
-+	aesenc		$rndkey0,$inout2
-+	aesenc		$rndkey0,$inout3
-+	$movkey		64($key_),$rndkey0
-+	jmp		.Locb_enc_loop4
-+
-+.align	32
-+.Locb_enc_loop4:
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+
-+	aesenc		$rndkey0,$inout0
-+	aesenc		$rndkey0,$inout1
-+	aesenc		$rndkey0,$inout2
-+	aesenc		$rndkey0,$inout3
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.Locb_enc_loop4
-+
-+	aesenc		$rndkey1,$inout0
-+	aesenc		$rndkey1,$inout1
-+	aesenc		$rndkey1,$inout2
-+	aesenc		$rndkey1,$inout3
-+	$movkey		16($key_),$rndkey1
-+	mov		%r10,%rax		# restore twisted rounds
-+
-+	aesenclast	@offset[0],$inout0
-+	aesenclast	@offset[1],$inout1
-+	aesenclast	@offset[2],$inout2
-+	aesenclast	@offset[3],$inout3
-+	ret
-+.size	__ocb_encrypt4,.-__ocb_encrypt4
-+
-+.type	__ocb_encrypt1,\@abi-omnipotent
-+.align	32
-+__ocb_encrypt1:
-+	 pxor		@offset[5],$inout5	# offset_i
-+	 pxor		$rndkey0l,$inout5	# offset_i ^ round[0]
-+	pxor		$inout0,$checksum	# accumulate checksum
-+	pxor		$inout5,$inout0		# input ^ round[0] ^ offset_i
-+	$movkey		32($key_),$rndkey0
-+
-+	aesenc		$rndkey1,$inout0
-+	$movkey		48($key_),$rndkey1
-+	pxor		$rndkey0l,$inout5	# offset_i ^ round[last]
-+
-+	aesenc		$rndkey0,$inout0
-+	$movkey		64($key_),$rndkey0
-+	jmp		.Locb_enc_loop1
-+
-+.align	32
-+.Locb_enc_loop1:
-+	aesenc		$rndkey1,$inout0
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+
-+	aesenc		$rndkey0,$inout0
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.Locb_enc_loop1
-+
-+	aesenc		$rndkey1,$inout0
-+	$movkey		16($key_),$rndkey1	# redundant in tail
-+	mov		%r10,%rax		# restore twisted rounds
-+
-+	aesenclast	$inout5,$inout0
-+	ret
-+.size	__ocb_encrypt1,.-__ocb_encrypt1
-+
-+.globl	aesni_ocb_decrypt
-+.type	aesni_ocb_decrypt,\@function,6
-+.align	32
-+aesni_ocb_decrypt:
-+	lea	(%rsp),%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa0(%rsp),%rsp
-+	movaps	%xmm6,0x00(%rsp)		# offload everything
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,0x40(%rsp)
-+	movaps	%xmm11,0x50(%rsp)
-+	movaps	%xmm12,0x60(%rsp)
-+	movaps	%xmm13,0x70(%rsp)
-+	movaps	%xmm14,0x80(%rsp)
-+	movaps	%xmm15,0x90(%rsp)
-+.Locb_dec_body:
-+___
-+$code.=<<___;
-+	mov	$seventh_arg(%rax),$L_p		# 7th argument
-+	mov	$seventh_arg+8(%rax),$checksum_p# 8th argument
-+
-+	mov	240($key),$rnds_
-+	mov	$key,$key_
-+	shl	\$4,$rnds_
-+	$movkey	($key),$rndkey0l		# round[0]
-+	$movkey	16($key,$rnds_),$rndkey1	# round[last]
-+
-+	movdqu	($offset_p),@offset[5]		# load last offset_i
-+	pxor	$rndkey1,$rndkey0l		# round[0] ^ round[last]
-+	pxor	$rndkey1,@offset[5]		# offset_i ^ round[last]
-+
-+	mov	\$16+32,$rounds
-+	lea	32($key_,$rnds_),$key
-+	$movkey	16($key_),$rndkey1		# round[1]
-+	sub	%r10,%rax			# twisted $rounds
-+	mov	%rax,%r10			# backup twisted $rounds
-+
-+	movdqu	($L_p),@offset[0]		# L_0 for all odd-numbered blocks
-+	movdqu	($checksum_p),$checksum		# load checksum
-+
-+	test	\$1,$block_num			# is first block number odd?
-+	jnz	.Locb_dec_odd
-+
-+	bsf	$block_num,$i1
-+	add	\$1,$block_num
-+	shl	\$4,$i1
-+	movdqu	($L_p,$i1),$inout5		# borrow
-+	movdqu	($inp),$inout0
-+	lea	16($inp),$inp
-+
-+	call	__ocb_decrypt1
-+
-+	movdqa	$inout5,@offset[5]
-+	movups	$inout0,($out)
-+	xorps	$inout0,$checksum		# accumulate checksum
-+	lea	16($out),$out
-+	sub	\$1,$blocks
-+	jz	.Locb_dec_done
-+
-+.Locb_dec_odd:
-+	lea	1($block_num),$i1		# even-numbered blocks
-+	lea	3($block_num),$i3
-+	lea	5($block_num),$i5
-+	lea	6($block_num),$block_num
-+	bsf	$i1,$i1				# ntz(block)
-+	bsf	$i3,$i3
-+	bsf	$i5,$i5
-+	shl	\$4,$i1				# ntz(block) -> table offset
-+	shl	\$4,$i3
-+	shl	\$4,$i5
-+
-+	sub	\$6,$blocks
-+	jc	.Locb_dec_short
-+	jmp	.Locb_dec_grandloop
-+
-+.align	32
-+.Locb_dec_grandloop:
-+	movdqu	`16*0`($inp),$inout0		# load input
-+	movdqu	`16*1`($inp),$inout1
-+	movdqu	`16*2`($inp),$inout2
-+	movdqu	`16*3`($inp),$inout3
-+	movdqu	`16*4`($inp),$inout4
-+	movdqu	`16*5`($inp),$inout5
-+	lea	`16*6`($inp),$inp
-+
-+	call	__ocb_decrypt6
-+
-+	movups	$inout0,`16*0`($out)		# store output
-+	pxor	$inout0,$checksum		# accumulate checksum
-+	movups	$inout1,`16*1`($out)
-+	pxor	$inout1,$checksum
-+	movups	$inout2,`16*2`($out)
-+	pxor	$inout2,$checksum
-+	movups	$inout3,`16*3`($out)
-+	pxor	$inout3,$checksum
-+	movups	$inout4,`16*4`($out)
-+	pxor	$inout4,$checksum
-+	movups	$inout5,`16*5`($out)
-+	pxor	$inout5,$checksum
-+	lea	`16*6`($out),$out
-+	sub	\$6,$blocks
-+	jnc	.Locb_dec_grandloop
-+
-+.Locb_dec_short:
-+	add	\$6,$blocks
-+	jz	.Locb_dec_done
-+
-+	movdqu	`16*0`($inp),$inout0
-+	cmp	\$2,$blocks
-+	jb	.Locb_dec_one
-+	movdqu	`16*1`($inp),$inout1
-+	je	.Locb_dec_two
-+
-+	movdqu	`16*2`($inp),$inout2
-+	cmp	\$4,$blocks
-+	jb	.Locb_dec_three
-+	movdqu	`16*3`($inp),$inout3
-+	je	.Locb_dec_four
-+
-+	movdqu	`16*4`($inp),$inout4
-+	pxor	$inout5,$inout5
-+
-+	call	__ocb_decrypt6
-+
-+	movdqa	@offset[4],@offset[5]
-+	movups	$inout0,`16*0`($out)		# store output
-+	pxor	$inout0,$checksum		# accumulate checksum
-+	movups	$inout1,`16*1`($out)
-+	pxor	$inout1,$checksum
-+	movups	$inout2,`16*2`($out)
-+	pxor	$inout2,$checksum
-+	movups	$inout3,`16*3`($out)
-+	pxor	$inout3,$checksum
-+	movups	$inout4,`16*4`($out)
-+	pxor	$inout4,$checksum
-+
-+	jmp	.Locb_dec_done
-+
-+.align	16
-+.Locb_dec_one:
-+	movdqa	@offset[0],$inout5		# borrow
-+
-+	call	__ocb_decrypt1
-+
-+	movdqa	$inout5,@offset[5]
-+	movups	$inout0,`16*0`($out)		# store output
-+	xorps	$inout0,$checksum		# accumulate checksum
-+	jmp	.Locb_dec_done
-+
-+.align	16
-+.Locb_dec_two:
-+	pxor	$inout2,$inout2
-+	pxor	$inout3,$inout3
-+
-+	call	__ocb_decrypt4
-+
-+	movdqa	@offset[1],@offset[5]
-+	movups	$inout0,`16*0`($out)		# store output
-+	xorps	$inout0,$checksum		# accumulate checksum
-+	movups	$inout1,`16*1`($out)
-+	xorps	$inout1,$checksum
-+
-+	jmp	.Locb_dec_done
-+
-+.align	16
-+.Locb_dec_three:
-+	pxor	$inout3,$inout3
-+
-+	call	__ocb_decrypt4
-+
-+	movdqa	@offset[2],@offset[5]
-+	movups	$inout0,`16*0`($out)		# store output
-+	xorps	$inout0,$checksum		# accumulate checksum
-+	movups	$inout1,`16*1`($out)
-+	xorps	$inout1,$checksum
-+	movups	$inout2,`16*2`($out)
-+	xorps	$inout2,$checksum
-+
-+	jmp	.Locb_dec_done
-+
-+.align	16
-+.Locb_dec_four:
-+	call	__ocb_decrypt4
-+
-+	movdqa	@offset[3],@offset[5]
-+	movups	$inout0,`16*0`($out)		# store output
-+	pxor	$inout0,$checksum		# accumulate checksum
-+	movups	$inout1,`16*1`($out)
-+	pxor	$inout1,$checksum
-+	movups	$inout2,`16*2`($out)
-+	pxor	$inout2,$checksum
-+	movups	$inout3,`16*3`($out)
-+	pxor	$inout3,$checksum
-+
-+.Locb_dec_done:
-+	pxor	$rndkey0,@offset[5]		# "remove" round[last]
-+	movdqu	$checksum,($checksum_p)		# store checksum
-+	movdqu	@offset[5],($offset_p)		# store last offset_i
-+
-+	xorps	%xmm0,%xmm0			# clear register bank
-+	pxor	%xmm1,%xmm1
-+	pxor	%xmm2,%xmm2
-+	pxor	%xmm3,%xmm3
-+	pxor	%xmm4,%xmm4
-+	pxor	%xmm5,%xmm5
-+___
-+$code.=<<___ if (!$win64);
-+	pxor	%xmm6,%xmm6
-+	pxor	%xmm7,%xmm7
-+	pxor	%xmm8,%xmm8
-+	pxor	%xmm9,%xmm9
-+	pxor	%xmm10,%xmm10
-+	pxor	%xmm11,%xmm11
-+	pxor	%xmm12,%xmm12
-+	pxor	%xmm13,%xmm13
-+	pxor	%xmm14,%xmm14
-+	pxor	%xmm15,%xmm15
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x00(%rsp),%xmm6
-+	movaps	%xmm0,0x00(%rsp)		# clear stack
-+	movaps	0x10(%rsp),%xmm7
-+	movaps	%xmm0,0x10(%rsp)
-+	movaps	0x20(%rsp),%xmm8
-+	movaps	%xmm0,0x20(%rsp)
-+	movaps	0x30(%rsp),%xmm9
-+	movaps	%xmm0,0x30(%rsp)
-+	movaps	0x40(%rsp),%xmm10
-+	movaps	%xmm0,0x40(%rsp)
-+	movaps	0x50(%rsp),%xmm11
-+	movaps	%xmm0,0x50(%rsp)
-+	movaps	0x60(%rsp),%xmm12
-+	movaps	%xmm0,0x60(%rsp)
-+	movaps	0x70(%rsp),%xmm13
-+	movaps	%xmm0,0x70(%rsp)
-+	movaps	0x80(%rsp),%xmm14
-+	movaps	%xmm0,0x80(%rsp)
-+	movaps	0x90(%rsp),%xmm15
-+	movaps	%xmm0,0x90(%rsp)
-+	lea	0xa0+0x28(%rsp),%rax
-+.Locb_dec_pop:
-+	lea	0xa0(%rsp),%rsp
-+___
-+$code.=<<___;
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+.Locb_dec_epilogue:
-+	ret
-+.size	aesni_ocb_decrypt,.-aesni_ocb_decrypt
-+
-+.type	__ocb_decrypt6,\@abi-omnipotent
-+.align	32
-+__ocb_decrypt6:
-+	 pxor		$rndkey0l,@offset[5]	# offset_i ^ round[0]
-+	 movdqu		($L_p,$i1),@offset[1]
-+	 movdqa		@offset[0],@offset[2]
-+	 movdqu		($L_p,$i3),@offset[3]
-+	 movdqa		@offset[0],@offset[4]
-+	 pxor		@offset[5],@offset[0]
-+	 movdqu		($L_p,$i5),@offset[5]
-+	 pxor		@offset[0],@offset[1]
-+	pxor		@offset[0],$inout0	# input ^ round[0] ^ offset_i
-+	 pxor		@offset[1],@offset[2]
-+	pxor		@offset[1],$inout1
-+	 pxor		@offset[2],@offset[3]
-+	pxor		@offset[2],$inout2
-+	 pxor		@offset[3],@offset[4]
-+	pxor		@offset[3],$inout3
-+	 pxor		@offset[4],@offset[5]
-+	pxor		@offset[4],$inout4
-+	pxor		@offset[5],$inout5
-+	$movkey		32($key_),$rndkey0
-+
-+	lea		1($block_num),$i1	# even-numbered blocks
-+	lea		3($block_num),$i3
-+	lea		5($block_num),$i5
-+	add		\$6,$block_num
-+	 pxor		$rndkey0l,@offset[0]	# offset_i ^ round[last]
-+	bsf		$i1,$i1			# ntz(block)
-+	bsf		$i3,$i3
-+	bsf		$i5,$i5
-+
-+	aesdec		$rndkey1,$inout0
-+	aesdec		$rndkey1,$inout1
-+	aesdec		$rndkey1,$inout2
-+	aesdec		$rndkey1,$inout3
-+	 pxor		$rndkey0l,@offset[1]
-+	 pxor		$rndkey0l,@offset[2]
-+	aesdec		$rndkey1,$inout4
-+	 pxor		$rndkey0l,@offset[3]
-+	 pxor		$rndkey0l,@offset[4]
-+	aesdec		$rndkey1,$inout5
-+	$movkey		48($key_),$rndkey1
-+	 pxor		$rndkey0l,@offset[5]
-+
-+	aesdec		$rndkey0,$inout0
-+	aesdec		$rndkey0,$inout1
-+	aesdec		$rndkey0,$inout2
-+	aesdec		$rndkey0,$inout3
-+	aesdec		$rndkey0,$inout4
-+	aesdec		$rndkey0,$inout5
-+	$movkey		64($key_),$rndkey0
-+	shl		\$4,$i1			# ntz(block) -> table offset
-+	shl		\$4,$i3
-+	jmp		.Locb_dec_loop6
-+
-+.align	32
-+.Locb_dec_loop6:
-+	aesdec		$rndkey1,$inout0
-+	aesdec		$rndkey1,$inout1
-+	aesdec		$rndkey1,$inout2
-+	aesdec		$rndkey1,$inout3
-+	aesdec		$rndkey1,$inout4
-+	aesdec		$rndkey1,$inout5
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+
-+	aesdec		$rndkey0,$inout0
-+	aesdec		$rndkey0,$inout1
-+	aesdec		$rndkey0,$inout2
-+	aesdec		$rndkey0,$inout3
-+	aesdec		$rndkey0,$inout4
-+	aesdec		$rndkey0,$inout5
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.Locb_dec_loop6
-+
-+	aesdec		$rndkey1,$inout0
-+	aesdec		$rndkey1,$inout1
-+	aesdec		$rndkey1,$inout2
-+	aesdec		$rndkey1,$inout3
-+	aesdec		$rndkey1,$inout4
-+	aesdec		$rndkey1,$inout5
-+	$movkey		16($key_),$rndkey1
-+	shl		\$4,$i5
-+
-+	aesdeclast	@offset[0],$inout0
-+	movdqu		($L_p),@offset[0]	# L_0 for all odd-numbered blocks
-+	mov		%r10,%rax		# restore twisted rounds
-+	aesdeclast	@offset[1],$inout1
-+	aesdeclast	@offset[2],$inout2
-+	aesdeclast	@offset[3],$inout3
-+	aesdeclast	@offset[4],$inout4
-+	aesdeclast	@offset[5],$inout5
-+	ret
-+.size	__ocb_decrypt6,.-__ocb_decrypt6
-+
-+.type	__ocb_decrypt4,\@abi-omnipotent
-+.align	32
-+__ocb_decrypt4:
-+	 pxor		$rndkey0l,@offset[5]	# offset_i ^ round[0]
-+	 movdqu		($L_p,$i1),@offset[1]
-+	 movdqa		@offset[0],@offset[2]
-+	 movdqu		($L_p,$i3),@offset[3]
-+	 pxor		@offset[5],@offset[0]
-+	 pxor		@offset[0],@offset[1]
-+	pxor		@offset[0],$inout0	# input ^ round[0] ^ offset_i
-+	 pxor		@offset[1],@offset[2]
-+	pxor		@offset[1],$inout1
-+	 pxor		@offset[2],@offset[3]
-+	pxor		@offset[2],$inout2
-+	pxor		@offset[3],$inout3
-+	$movkey		32($key_),$rndkey0
-+
-+	 pxor		$rndkey0l,@offset[0]	# offset_i ^ round[last]
-+	 pxor		$rndkey0l,@offset[1]
-+	 pxor		$rndkey0l,@offset[2]
-+	 pxor		$rndkey0l,@offset[3]
-+
-+	aesdec		$rndkey1,$inout0
-+	aesdec		$rndkey1,$inout1
-+	aesdec		$rndkey1,$inout2
-+	aesdec		$rndkey1,$inout3
-+	$movkey		48($key_),$rndkey1
-+
-+	aesdec		$rndkey0,$inout0
-+	aesdec		$rndkey0,$inout1
-+	aesdec		$rndkey0,$inout2
-+	aesdec		$rndkey0,$inout3
-+	$movkey		64($key_),$rndkey0
-+	jmp		.Locb_dec_loop4
-+
-+.align	32
-+.Locb_dec_loop4:
-+	aesdec		$rndkey1,$inout0
-+	aesdec		$rndkey1,$inout1
-+	aesdec		$rndkey1,$inout2
-+	aesdec		$rndkey1,$inout3
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+
-+	aesdec		$rndkey0,$inout0
-+	aesdec		$rndkey0,$inout1
-+	aesdec		$rndkey0,$inout2
-+	aesdec		$rndkey0,$inout3
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.Locb_dec_loop4
-+
-+	aesdec		$rndkey1,$inout0
-+	aesdec		$rndkey1,$inout1
-+	aesdec		$rndkey1,$inout2
-+	aesdec		$rndkey1,$inout3
-+	$movkey		16($key_),$rndkey1
-+	mov		%r10,%rax		# restore twisted rounds
-+
-+	aesdeclast	@offset[0],$inout0
-+	aesdeclast	@offset[1],$inout1
-+	aesdeclast	@offset[2],$inout2
-+	aesdeclast	@offset[3],$inout3
-+	ret
-+.size	__ocb_decrypt4,.-__ocb_decrypt4
-+
-+.type	__ocb_decrypt1,\@abi-omnipotent
-+.align	32
-+__ocb_decrypt1:
-+	 pxor		@offset[5],$inout5	# offset_i
-+	 pxor		$rndkey0l,$inout5	# offset_i ^ round[0]
-+	pxor		$inout5,$inout0		# input ^ round[0] ^ offset_i
-+	$movkey		32($key_),$rndkey0
-+
-+	aesdec		$rndkey1,$inout0
-+	$movkey		48($key_),$rndkey1
-+	pxor		$rndkey0l,$inout5	# offset_i ^ round[last]
-+
-+	aesdec		$rndkey0,$inout0
-+	$movkey		64($key_),$rndkey0
-+	jmp		.Locb_dec_loop1
-+
-+.align	32
-+.Locb_dec_loop1:
-+	aesdec		$rndkey1,$inout0
-+	$movkey		($key,%rax),$rndkey1
-+	add		\$32,%rax
-+
-+	aesdec		$rndkey0,$inout0
-+	$movkey		-16($key,%rax),$rndkey0
-+	jnz		.Locb_dec_loop1
-+
-+	aesdec		$rndkey1,$inout0
-+	$movkey		16($key_),$rndkey1	# redundant in tail
-+	mov		%r10,%rax		# restore twisted rounds
-+
-+	aesdeclast	$inout5,$inout0
-+	ret
-+.size	__ocb_decrypt1,.-__ocb_decrypt1
-+___
-+} }}
-+
-+########################################################################
-+# void $PREFIX_cbc_encrypt (const void *inp, void *out,
-+#			    size_t length, const AES_KEY *key,
-+#			    unsigned char *ivp,const int enc);
-+{
-+my $frame_size = 0x10 + ($win64?0xa0:0);	# used in decrypt
-+my ($iv,$in0,$in1,$in2,$in3,$in4)=map("%xmm$_",(10..15));
-+my $inp_=$key_;
-+
-+$code.=<<___;
-+.globl	${PREFIX}_cbc_encrypt
-+.type	${PREFIX}_cbc_encrypt,\@function,6
-+.align	16
-+${PREFIX}_cbc_encrypt:
-+	test	$len,$len		# check length
-+	jz	.Lcbc_ret
-+
-+	mov	240($key),$rnds_	# key->rounds
-+	mov	$key,$key_		# backup $key
-+	test	%r9d,%r9d		# 6th argument
-+	jz	.Lcbc_decrypt
-+#--------------------------- CBC ENCRYPT ------------------------------#
-+	movups	($ivp),$inout0		# load iv as initial state
-+	mov	$rnds_,$rounds
-+	cmp	\$16,$len
-+	jb	.Lcbc_enc_tail
-+	sub	\$16,$len
-+	jmp	.Lcbc_enc_loop
-+.align	16
-+.Lcbc_enc_loop:
-+	movups	($inp),$inout1		# load input
-+	lea	16($inp),$inp
-+	#xorps	$inout1,$inout0
-+___
-+	&aesni_generate1("enc",$key,$rounds,$inout0,$inout1);
-+$code.=<<___;
-+	mov	$rnds_,$rounds		# restore $rounds
-+	mov	$key_,$key		# restore $key
-+	movups	$inout0,0($out)		# store output
-+	lea	16($out),$out
-+	sub	\$16,$len
-+	jnc	.Lcbc_enc_loop
-+	add	\$16,$len
-+	jnz	.Lcbc_enc_tail
-+	 pxor	$rndkey0,$rndkey0	# clear register bank
-+	 pxor	$rndkey1,$rndkey1
-+	movups	$inout0,($ivp)
-+	 pxor	$inout0,$inout0
-+	 pxor	$inout1,$inout1
-+	jmp	.Lcbc_ret
-+
-+.Lcbc_enc_tail:
-+	mov	$len,%rcx	# zaps $key
-+	xchg	$inp,$out	# $inp is %rsi and $out is %rdi now
-+	.long	0x9066A4F3	# rep movsb
-+	mov	\$16,%ecx	# zero tail
-+	sub	$len,%rcx
-+	xor	%eax,%eax
-+	.long	0x9066AAF3	# rep stosb
-+	lea	-16(%rdi),%rdi	# rewind $out by 1 block
-+	mov	$rnds_,$rounds	# restore $rounds
-+	mov	%rdi,%rsi	# $inp and $out are the same
-+	mov	$key_,$key	# restore $key
-+	xor	$len,$len	# len=16
-+	jmp	.Lcbc_enc_loop	# one more spin
-+#--------------------------- CBC DECRYPT ------------------------------#
-+.align	16
-+.Lcbc_decrypt:
-+	cmp	\$16,$len
-+	jne	.Lcbc_decrypt_bulk
-+
-+	# handle single block without allocating stack frame,
-+	# useful in ciphertext stealing mode
-+	movdqu	($inp),$inout0		# load input
-+	movdqu	($ivp),$inout1		# load iv
-+	movdqa	$inout0,$inout2		# future iv
-+___
-+	&aesni_generate1("dec",$key,$rnds_);
-+$code.=<<___;
-+	 pxor	$rndkey0,$rndkey0	# clear register bank
-+	 pxor	$rndkey1,$rndkey1
-+	movdqu	$inout2,($ivp)		# store iv
-+	xorps	$inout1,$inout0		# ^=iv
-+	 pxor	$inout1,$inout1
-+	movups	$inout0,($out)		# store output
-+	 pxor	$inout0,$inout0
-+	jmp	.Lcbc_ret
-+.align	16
-+.Lcbc_decrypt_bulk:
-+	lea	(%rsp),%rax
-+	push	%rbp
-+	sub	\$$frame_size,%rsp
-+	and	\$-16,%rsp	# Linux kernel stack can be incorrectly seeded
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,0x10(%rsp)
-+	movaps	%xmm7,0x20(%rsp)
-+	movaps	%xmm8,0x30(%rsp)
-+	movaps	%xmm9,0x40(%rsp)
-+	movaps	%xmm10,0x50(%rsp)
-+	movaps	%xmm11,0x60(%rsp)
-+	movaps	%xmm12,0x70(%rsp)
-+	movaps	%xmm13,0x80(%rsp)
-+	movaps	%xmm14,0x90(%rsp)
-+	movaps	%xmm15,0xa0(%rsp)
-+.Lcbc_decrypt_body:
-+___
-+$code.=<<___;
-+	lea	-8(%rax),%rbp
-+	movups	($ivp),$iv
-+	mov	$rnds_,$rounds
-+	cmp	\$0x50,$len
-+	jbe	.Lcbc_dec_tail
-+
-+	$movkey	($key),$rndkey0
-+	movdqu	0x00($inp),$inout0	# load input
-+	movdqu	0x10($inp),$inout1
-+	movdqa	$inout0,$in0
-+	movdqu	0x20($inp),$inout2
-+	movdqa	$inout1,$in1
-+	movdqu	0x30($inp),$inout3
-+	movdqa	$inout2,$in2
-+	movdqu	0x40($inp),$inout4
-+	movdqa	$inout3,$in3
-+	movdqu	0x50($inp),$inout5
-+	movdqa	$inout4,$in4
-+	mov	OPENSSL_ia32cap_P+4(%rip),%r9d
-+	cmp	\$0x70,$len
-+	jbe	.Lcbc_dec_six_or_seven
-+
-+	and	\$`1<<26|1<<22`,%r9d	# isolate XSAVE+MOVBE
-+	sub	\$0x50,$len		# $len is biased by -5*16
-+	cmp	\$`1<<22`,%r9d		# check for MOVBE without XSAVE
-+	je	.Lcbc_dec_loop6_enter	# [which denotes Atom Silvermont]
-+	sub	\$0x20,$len		# $len is biased by -7*16
-+	lea	0x70($key),$key		# size optimization
-+	jmp	.Lcbc_dec_loop8_enter
-+.align	16
-+.Lcbc_dec_loop8:
-+	movups	$inout7,($out)
-+	lea	0x10($out),$out
-+.Lcbc_dec_loop8_enter:
-+	movdqu		0x60($inp),$inout6
-+	pxor		$rndkey0,$inout0
-+	movdqu		0x70($inp),$inout7
-+	pxor		$rndkey0,$inout1
-+	$movkey		0x10-0x70($key),$rndkey1
-+	pxor		$rndkey0,$inout2
-+	xor		$inp_,$inp_
-+	cmp		\$0x70,$len	# is there at least 0x60 bytes ahead?
-+	pxor		$rndkey0,$inout3
-+	pxor		$rndkey0,$inout4
-+	pxor		$rndkey0,$inout5
-+	pxor		$rndkey0,$inout6
-+
-+	aesdec		$rndkey1,$inout0
-+	pxor		$rndkey0,$inout7
-+	$movkey		0x20-0x70($key),$rndkey0
-+	aesdec		$rndkey1,$inout1
-+	aesdec		$rndkey1,$inout2
-+	aesdec		$rndkey1,$inout3
-+	aesdec		$rndkey1,$inout4
-+	aesdec		$rndkey1,$inout5
-+	aesdec		$rndkey1,$inout6
-+	setnc		${inp_}b
-+	shl		\$7,$inp_
-+	aesdec		$rndkey1,$inout7
-+	add		$inp,$inp_
-+	$movkey		0x30-0x70($key),$rndkey1
-+___
-+for($i=1;$i<12;$i++) {
-+my $rndkeyx = ($i&1)?$rndkey0:$rndkey1;
-+$code.=<<___	if ($i==7);
-+	cmp		\$11,$rounds
-+___
-+$code.=<<___;
-+	aesdec		$rndkeyx,$inout0
-+	aesdec		$rndkeyx,$inout1
-+	aesdec		$rndkeyx,$inout2
-+	aesdec		$rndkeyx,$inout3
-+	aesdec		$rndkeyx,$inout4
-+	aesdec		$rndkeyx,$inout5
-+	aesdec		$rndkeyx,$inout6
-+	aesdec		$rndkeyx,$inout7
-+	$movkey		`0x30+0x10*$i`-0x70($key),$rndkeyx
-+___
-+$code.=<<___	if ($i<6 || (!($i&1) && $i>7));
-+	nop
-+___
-+$code.=<<___	if ($i==7);
-+	jb		.Lcbc_dec_done
-+___
-+$code.=<<___	if ($i==9);
-+	je		.Lcbc_dec_done
-+___
-+$code.=<<___	if ($i==11);
-+	jmp		.Lcbc_dec_done
-+___
-+}
-+$code.=<<___;
-+.align	16
-+.Lcbc_dec_done:
-+	aesdec		$rndkey1,$inout0
-+	aesdec		$rndkey1,$inout1
-+	pxor		$rndkey0,$iv
-+	pxor		$rndkey0,$in0
-+	aesdec		$rndkey1,$inout2
-+	aesdec		$rndkey1,$inout3
-+	pxor		$rndkey0,$in1
-+	pxor		$rndkey0,$in2
-+	aesdec		$rndkey1,$inout4
-+	aesdec		$rndkey1,$inout5
-+	pxor		$rndkey0,$in3
-+	pxor		$rndkey0,$in4
-+	aesdec		$rndkey1,$inout6
-+	aesdec		$rndkey1,$inout7
-+	movdqu		0x50($inp),$rndkey1
-+
-+	aesdeclast	$iv,$inout0
-+	movdqu		0x60($inp),$iv		# borrow $iv
-+	pxor		$rndkey0,$rndkey1
-+	aesdeclast	$in0,$inout1
-+	pxor		$rndkey0,$iv
-+	movdqu		0x70($inp),$rndkey0	# next IV
-+	aesdeclast	$in1,$inout2
-+	lea		0x80($inp),$inp
-+	movdqu		0x00($inp_),$in0
-+	aesdeclast	$in2,$inout3
-+	aesdeclast	$in3,$inout4
-+	movdqu		0x10($inp_),$in1
-+	movdqu		0x20($inp_),$in2
-+	aesdeclast	$in4,$inout5
-+	aesdeclast	$rndkey1,$inout6
-+	movdqu		0x30($inp_),$in3
-+	movdqu		0x40($inp_),$in4
-+	aesdeclast	$iv,$inout7
-+	movdqa		$rndkey0,$iv		# return $iv
-+	movdqu		0x50($inp_),$rndkey1
-+	$movkey		-0x70($key),$rndkey0
-+
-+	movups		$inout0,($out)		# store output
-+	movdqa		$in0,$inout0
-+	movups		$inout1,0x10($out)
-+	movdqa		$in1,$inout1
-+	movups		$inout2,0x20($out)
-+	movdqa		$in2,$inout2
-+	movups		$inout3,0x30($out)
-+	movdqa		$in3,$inout3
-+	movups		$inout4,0x40($out)
-+	movdqa		$in4,$inout4
-+	movups		$inout5,0x50($out)
-+	movdqa		$rndkey1,$inout5
-+	movups		$inout6,0x60($out)
-+	lea		0x70($out),$out
-+
-+	sub	\$0x80,$len
-+	ja	.Lcbc_dec_loop8
-+
-+	movaps	$inout7,$inout0
-+	lea	-0x70($key),$key
-+	add	\$0x70,$len
-+	jle	.Lcbc_dec_clear_tail_collected
-+	movups	$inout7,($out)
-+	lea	0x10($out),$out
-+	cmp	\$0x50,$len
-+	jbe	.Lcbc_dec_tail
-+
-+	movaps	$in0,$inout0
-+.Lcbc_dec_six_or_seven:
-+	cmp	\$0x60,$len
-+	ja	.Lcbc_dec_seven
-+
-+	movaps	$inout5,$inout6
-+	call	_aesni_decrypt6
-+	pxor	$iv,$inout0		# ^= IV
-+	movaps	$inout6,$iv
-+	pxor	$in0,$inout1
-+	movdqu	$inout0,($out)
-+	pxor	$in1,$inout2
-+	movdqu	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1		# clear register bank
-+	pxor	$in2,$inout3
-+	movdqu	$inout2,0x20($out)
-+	 pxor	$inout2,$inout2
-+	pxor	$in3,$inout4
-+	movdqu	$inout3,0x30($out)
-+	 pxor	$inout3,$inout3
-+	pxor	$in4,$inout5
-+	movdqu	$inout4,0x40($out)
-+	 pxor	$inout4,$inout4
-+	lea	0x50($out),$out
-+	movdqa	$inout5,$inout0
-+	 pxor	$inout5,$inout5
-+	jmp	.Lcbc_dec_tail_collected
-+
-+.align	16
-+.Lcbc_dec_seven:
-+	movups	0x60($inp),$inout6
-+	xorps	$inout7,$inout7
-+	call	_aesni_decrypt8
-+	movups	0x50($inp),$inout7
-+	pxor	$iv,$inout0		# ^= IV
-+	movups	0x60($inp),$iv
-+	pxor	$in0,$inout1
-+	movdqu	$inout0,($out)
-+	pxor	$in1,$inout2
-+	movdqu	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1		# clear register bank
-+	pxor	$in2,$inout3
-+	movdqu	$inout2,0x20($out)
-+	 pxor	$inout2,$inout2
-+	pxor	$in3,$inout4
-+	movdqu	$inout3,0x30($out)
-+	 pxor	$inout3,$inout3
-+	pxor	$in4,$inout5
-+	movdqu	$inout4,0x40($out)
-+	 pxor	$inout4,$inout4
-+	pxor	$inout7,$inout6
-+	movdqu	$inout5,0x50($out)
-+	 pxor	$inout5,$inout5
-+	lea	0x60($out),$out
-+	movdqa	$inout6,$inout0
-+	 pxor	$inout6,$inout6
-+	 pxor	$inout7,$inout7
-+	jmp	.Lcbc_dec_tail_collected
-+
-+.align	16
-+.Lcbc_dec_loop6:
-+	movups	$inout5,($out)
-+	lea	0x10($out),$out
-+	movdqu	0x00($inp),$inout0	# load input
-+	movdqu	0x10($inp),$inout1
-+	movdqa	$inout0,$in0
-+	movdqu	0x20($inp),$inout2
-+	movdqa	$inout1,$in1
-+	movdqu	0x30($inp),$inout3
-+	movdqa	$inout2,$in2
-+	movdqu	0x40($inp),$inout4
-+	movdqa	$inout3,$in3
-+	movdqu	0x50($inp),$inout5
-+	movdqa	$inout4,$in4
-+.Lcbc_dec_loop6_enter:
-+	lea	0x60($inp),$inp
-+	movdqa	$inout5,$inout6
-+
-+	call	_aesni_decrypt6
-+
-+	pxor	$iv,$inout0		# ^= IV
-+	movdqa	$inout6,$iv
-+	pxor	$in0,$inout1
-+	movdqu	$inout0,($out)
-+	pxor	$in1,$inout2
-+	movdqu	$inout1,0x10($out)
-+	pxor	$in2,$inout3
-+	movdqu	$inout2,0x20($out)
-+	pxor	$in3,$inout4
-+	mov	$key_,$key
-+	movdqu	$inout3,0x30($out)
-+	pxor	$in4,$inout5
-+	mov	$rnds_,$rounds
-+	movdqu	$inout4,0x40($out)
-+	lea	0x50($out),$out
-+	sub	\$0x60,$len
-+	ja	.Lcbc_dec_loop6
-+
-+	movdqa	$inout5,$inout0
-+	add	\$0x50,$len
-+	jle	.Lcbc_dec_clear_tail_collected
-+	movups	$inout5,($out)
-+	lea	0x10($out),$out
-+
-+.Lcbc_dec_tail:
-+	movups	($inp),$inout0
-+	sub	\$0x10,$len
-+	jbe	.Lcbc_dec_one		# $len is 1*16 or less
-+
-+	movups	0x10($inp),$inout1
-+	movaps	$inout0,$in0
-+	sub	\$0x10,$len
-+	jbe	.Lcbc_dec_two		# $len is 2*16 or less
-+
-+	movups	0x20($inp),$inout2
-+	movaps	$inout1,$in1
-+	sub	\$0x10,$len
-+	jbe	.Lcbc_dec_three		# $len is 3*16 or less
-+
-+	movups	0x30($inp),$inout3
-+	movaps	$inout2,$in2
-+	sub	\$0x10,$len
-+	jbe	.Lcbc_dec_four		# $len is 4*16 or less
-+
-+	movups	0x40($inp),$inout4	# $len is 5*16 or less
-+	movaps	$inout3,$in3
-+	movaps	$inout4,$in4
-+	xorps	$inout5,$inout5
-+	call	_aesni_decrypt6
-+	pxor	$iv,$inout0
-+	movaps	$in4,$iv
-+	pxor	$in0,$inout1
-+	movdqu	$inout0,($out)
-+	pxor	$in1,$inout2
-+	movdqu	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1		# clear register bank
-+	pxor	$in2,$inout3
-+	movdqu	$inout2,0x20($out)
-+	 pxor	$inout2,$inout2
-+	pxor	$in3,$inout4
-+	movdqu	$inout3,0x30($out)
-+	 pxor	$inout3,$inout3
-+	lea	0x40($out),$out
-+	movdqa	$inout4,$inout0
-+	 pxor	$inout4,$inout4
-+	 pxor	$inout5,$inout5
-+	sub	\$0x10,$len
-+	jmp	.Lcbc_dec_tail_collected
-+
-+.align	16
-+.Lcbc_dec_one:
-+	movaps	$inout0,$in0
-+___
-+	&aesni_generate1("dec",$key,$rounds);
-+$code.=<<___;
-+	xorps	$iv,$inout0
-+	movaps	$in0,$iv
-+	jmp	.Lcbc_dec_tail_collected
-+.align	16
-+.Lcbc_dec_two:
-+	movaps	$inout1,$in1
-+	call	_aesni_decrypt2
-+	pxor	$iv,$inout0
-+	movaps	$in1,$iv
-+	pxor	$in0,$inout1
-+	movdqu	$inout0,($out)
-+	movdqa	$inout1,$inout0
-+	 pxor	$inout1,$inout1		# clear register bank
-+	lea	0x10($out),$out
-+	jmp	.Lcbc_dec_tail_collected
-+.align	16
-+.Lcbc_dec_three:
-+	movaps	$inout2,$in2
-+	call	_aesni_decrypt3
-+	pxor	$iv,$inout0
-+	movaps	$in2,$iv
-+	pxor	$in0,$inout1
-+	movdqu	$inout0,($out)
-+	pxor	$in1,$inout2
-+	movdqu	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1		# clear register bank
-+	movdqa	$inout2,$inout0
-+	 pxor	$inout2,$inout2
-+	lea	0x20($out),$out
-+	jmp	.Lcbc_dec_tail_collected
-+.align	16
-+.Lcbc_dec_four:
-+	movaps	$inout3,$in3
-+	call	_aesni_decrypt4
-+	pxor	$iv,$inout0
-+	movaps	$in3,$iv
-+	pxor	$in0,$inout1
-+	movdqu	$inout0,($out)
-+	pxor	$in1,$inout2
-+	movdqu	$inout1,0x10($out)
-+	 pxor	$inout1,$inout1		# clear register bank
-+	pxor	$in2,$inout3
-+	movdqu	$inout2,0x20($out)
-+	 pxor	$inout2,$inout2
-+	movdqa	$inout3,$inout0
-+	 pxor	$inout3,$inout3
-+	lea	0x30($out),$out
-+	jmp	.Lcbc_dec_tail_collected
-+
-+.align	16
-+.Lcbc_dec_clear_tail_collected:
-+	pxor	$inout1,$inout1		# clear register bank
-+	pxor	$inout2,$inout2
-+	pxor	$inout3,$inout3
-+___
-+$code.=<<___ if (!$win64);
-+	pxor	$inout4,$inout4		# %xmm6..9
-+	pxor	$inout5,$inout5
-+	pxor	$inout6,$inout6
-+	pxor	$inout7,$inout7
-+___
-+$code.=<<___;
-+.Lcbc_dec_tail_collected:
-+	movups	$iv,($ivp)
-+	and	\$15,$len
-+	jnz	.Lcbc_dec_tail_partial
-+	movups	$inout0,($out)
-+	pxor	$inout0,$inout0
-+	jmp	.Lcbc_dec_ret
-+.align	16
-+.Lcbc_dec_tail_partial:
-+	movaps	$inout0,(%rsp)
-+	pxor	$inout0,$inout0
-+	mov	\$16,%rcx
-+	mov	$out,%rdi
-+	sub	$len,%rcx
-+	lea	(%rsp),%rsi
-+	.long	0x9066A4F3		# rep movsb
-+	movdqa	$inout0,(%rsp)
-+
-+.Lcbc_dec_ret:
-+	xorps	$rndkey0,$rndkey0	# %xmm0
-+	pxor	$rndkey1,$rndkey1
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x10(%rsp),%xmm6
-+	movaps	%xmm0,0x10(%rsp)	# clear stack
-+	movaps	0x20(%rsp),%xmm7
-+	movaps	%xmm0,0x20(%rsp)
-+	movaps	0x30(%rsp),%xmm8
-+	movaps	%xmm0,0x30(%rsp)
-+	movaps	0x40(%rsp),%xmm9
-+	movaps	%xmm0,0x40(%rsp)
-+	movaps	0x50(%rsp),%xmm10
-+	movaps	%xmm0,0x50(%rsp)
-+	movaps	0x60(%rsp),%xmm11
-+	movaps	%xmm0,0x60(%rsp)
-+	movaps	0x70(%rsp),%xmm12
-+	movaps	%xmm0,0x70(%rsp)
-+	movaps	0x80(%rsp),%xmm13
-+	movaps	%xmm0,0x80(%rsp)
-+	movaps	0x90(%rsp),%xmm14
-+	movaps	%xmm0,0x90(%rsp)
-+	movaps	0xa0(%rsp),%xmm15
-+	movaps	%xmm0,0xa0(%rsp)
-+___
-+$code.=<<___;
-+	lea	(%rbp),%rsp
-+	pop	%rbp
-+.Lcbc_ret:
-+	ret
-+.size	${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt
-+___
-+} 
-+# int ${PREFIX}_set_decrypt_key(const unsigned char *inp,
-+#				int bits, AES_KEY *key)
-+#
-+# input:	$inp	user-supplied key
-+#		$bits	$inp length in bits
-+#		$key	pointer to key schedule
-+# output:	%eax	0 denoting success, -1 or -2 - failure (see C)
-+#		*$key	key schedule
-+#
-+{ my ($inp,$bits,$key) = @_4args;
-+  $bits =~ s/%r/%e/;
-+
-+$code.=<<___;
-+.globl	${PREFIX}_set_decrypt_key
-+.type	${PREFIX}_set_decrypt_key,\@abi-omnipotent
-+.align	16
-+${PREFIX}_set_decrypt_key:
-+	.byte	0x48,0x83,0xEC,0x08	# sub rsp,8
-+	call	__aesni_set_encrypt_key
-+	shl	\$4,$bits		# rounds-1 after _aesni_set_encrypt_key
-+	test	%eax,%eax
-+	jnz	.Ldec_key_ret
-+	lea	16($key,$bits),$inp	# points at the end of key schedule
-+
-+	$movkey	($key),%xmm0		# just swap
-+	$movkey	($inp),%xmm1
-+	$movkey	%xmm0,($inp)
-+	$movkey	%xmm1,($key)
-+	lea	16($key),$key
-+	lea	-16($inp),$inp
-+
-+.Ldec_key_inverse:
-+	$movkey	($key),%xmm0		# swap and inverse
-+	$movkey	($inp),%xmm1
-+	aesimc	%xmm0,%xmm0
-+	aesimc	%xmm1,%xmm1
-+	lea	16($key),$key
-+	lea	-16($inp),$inp
-+	$movkey	%xmm0,16($inp)
-+	$movkey	%xmm1,-16($key)
-+	cmp	$key,$inp
-+	ja	.Ldec_key_inverse
-+
-+	$movkey	($key),%xmm0		# inverse middle
-+	aesimc	%xmm0,%xmm0
-+	pxor	%xmm1,%xmm1
-+	$movkey	%xmm0,($inp)
-+	pxor	%xmm0,%xmm0
-+.Ldec_key_ret:
-+	add	\$8,%rsp
-+	ret
-+.LSEH_end_set_decrypt_key:
-+.size	${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key
-+___
-+
-+# This is based on submission by
-+#
-+#	Huang Ying 
-+#	Vinodh Gopal 
-+#	Kahraman Akdemir
-+#
-+# Aggressively optimized in respect to aeskeygenassist's critical path
-+# and is contained in %xmm0-5 to meet Win64 ABI requirement.
-+#
-+# int ${PREFIX}_set_encrypt_key(const unsigned char *inp,
-+#				int bits, AES_KEY * const key);
-+#
-+# input:	$inp	user-supplied key
-+#		$bits	$inp length in bits
-+#		$key	pointer to key schedule
-+# output:	%eax	0 denoting success, -1 or -2 - failure (see C)
-+#		$bits	rounds-1 (used in aesni_set_decrypt_key)
-+#		*$key	key schedule
-+#		$key	pointer to key schedule (used in
-+#			aesni_set_decrypt_key)
-+#
-+# Subroutine is frame-less, which means that only volatile registers
-+# are used. Note that it's declared "abi-omnipotent", which means that
-+# amount of volatile registers is smaller on Windows.
-+#
-+$code.=<<___;
-+.globl	${PREFIX}_set_encrypt_key
-+.type	${PREFIX}_set_encrypt_key,\@abi-omnipotent
-+.align	16
-+${PREFIX}_set_encrypt_key:
-+__aesni_set_encrypt_key:
-+	.byte	0x48,0x83,0xEC,0x08	# sub rsp,8
-+	mov	\$-1,%rax
-+	test	$inp,$inp
-+	jz	.Lenc_key_ret
-+	test	$key,$key
-+	jz	.Lenc_key_ret
-+
-+	mov	\$`1<<28|1<<11`,%r10d	# AVX and XOP bits
-+	movups	($inp),%xmm0		# pull first 128 bits of *userKey
-+	xorps	%xmm4,%xmm4		# low dword of xmm4 is assumed 0
-+	and	OPENSSL_ia32cap_P+4(%rip),%r10d
-+	lea	16($key),%rax		# %rax is used as modifiable copy of $key
-+	cmp	\$256,$bits
-+	je	.L14rounds
-+	cmp	\$192,$bits
-+	je	.L12rounds
-+	cmp	\$128,$bits
-+	jne	.Lbad_keybits
-+
-+.L10rounds:
-+	mov	\$9,$bits			# 10 rounds for 128-bit key
-+	cmp	\$`1<<28`,%r10d			# AVX, bit no XOP
-+	je	.L10rounds_alt
-+
-+	$movkey	%xmm0,($key)			# round 0
-+	aeskeygenassist	\$0x1,%xmm0,%xmm1	# round 1
-+	call		.Lkey_expansion_128_cold
-+	aeskeygenassist	\$0x2,%xmm0,%xmm1	# round 2
-+	call		.Lkey_expansion_128
-+	aeskeygenassist	\$0x4,%xmm0,%xmm1	# round 3
-+	call		.Lkey_expansion_128
-+	aeskeygenassist	\$0x8,%xmm0,%xmm1	# round 4
-+	call		.Lkey_expansion_128
-+	aeskeygenassist	\$0x10,%xmm0,%xmm1	# round 5
-+	call		.Lkey_expansion_128
-+	aeskeygenassist	\$0x20,%xmm0,%xmm1	# round 6
-+	call		.Lkey_expansion_128
-+	aeskeygenassist	\$0x40,%xmm0,%xmm1	# round 7
-+	call		.Lkey_expansion_128
-+	aeskeygenassist	\$0x80,%xmm0,%xmm1	# round 8
-+	call		.Lkey_expansion_128
-+	aeskeygenassist	\$0x1b,%xmm0,%xmm1	# round 9
-+	call		.Lkey_expansion_128
-+	aeskeygenassist	\$0x36,%xmm0,%xmm1	# round 10
-+	call		.Lkey_expansion_128
-+	$movkey	%xmm0,(%rax)
-+	mov	$bits,80(%rax)	# 240(%rdx)
-+	xor	%eax,%eax
-+	jmp	.Lenc_key_ret
-+
-+.align	16
-+.L10rounds_alt:
-+	movdqa	.Lkey_rotate(%rip),%xmm5
-+	mov	\$8,%r10d
-+	movdqa	.Lkey_rcon1(%rip),%xmm4
-+	movdqa	%xmm0,%xmm2
-+	movdqu	%xmm0,($key)
-+	jmp	.Loop_key128
-+
-+.align	16
-+.Loop_key128:
-+	pshufb		%xmm5,%xmm0
-+	aesenclast	%xmm4,%xmm0
-+	pslld		\$1,%xmm4
-+	lea		16(%rax),%rax
-+
-+	movdqa		%xmm2,%xmm3
-+	pslldq		\$4,%xmm2
-+	pxor		%xmm2,%xmm3
-+	pslldq		\$4,%xmm2
-+	pxor		%xmm2,%xmm3
-+	pslldq		\$4,%xmm2
-+	pxor		%xmm3,%xmm2
-+
-+	pxor		%xmm2,%xmm0
-+	movdqu		%xmm0,-16(%rax)
-+	movdqa		%xmm0,%xmm2
-+
-+	dec	%r10d
-+	jnz	.Loop_key128
-+
-+	movdqa		.Lkey_rcon1b(%rip),%xmm4
-+
-+	pshufb		%xmm5,%xmm0
-+	aesenclast	%xmm4,%xmm0
-+	pslld		\$1,%xmm4
-+
-+	movdqa		%xmm2,%xmm3
-+	pslldq		\$4,%xmm2
-+	pxor		%xmm2,%xmm3
-+	pslldq		\$4,%xmm2
-+	pxor		%xmm2,%xmm3
-+	pslldq		\$4,%xmm2
-+	pxor		%xmm3,%xmm2
-+
-+	pxor		%xmm2,%xmm0
-+	movdqu		%xmm0,(%rax)
-+
-+	movdqa		%xmm0,%xmm2
-+	pshufb		%xmm5,%xmm0
-+	aesenclast	%xmm4,%xmm0
-+
-+	movdqa		%xmm2,%xmm3
-+	pslldq		\$4,%xmm2
-+	pxor		%xmm2,%xmm3
-+	pslldq		\$4,%xmm2
-+	pxor		%xmm2,%xmm3
-+	pslldq		\$4,%xmm2
-+	pxor		%xmm3,%xmm2
-+
-+	pxor		%xmm2,%xmm0
-+	movdqu		%xmm0,16(%rax)
-+
-+	mov	$bits,96(%rax)	# 240($key)
-+	xor	%eax,%eax
-+	jmp	.Lenc_key_ret
-+
-+.align	16
-+.L12rounds:
-+	movq	16($inp),%xmm2			# remaining 1/3 of *userKey
-+	mov	\$11,$bits			# 12 rounds for 192
-+	cmp	\$`1<<28`,%r10d			# AVX, but no XOP
-+	je	.L12rounds_alt
-+
-+	$movkey	%xmm0,($key)			# round 0
-+	aeskeygenassist	\$0x1,%xmm2,%xmm1	# round 1,2
-+	call		.Lkey_expansion_192a_cold
-+	aeskeygenassist	\$0x2,%xmm2,%xmm1	# round 2,3
-+	call		.Lkey_expansion_192b
-+	aeskeygenassist	\$0x4,%xmm2,%xmm1	# round 4,5
-+	call		.Lkey_expansion_192a
-+	aeskeygenassist	\$0x8,%xmm2,%xmm1	# round 5,6
-+	call		.Lkey_expansion_192b
-+	aeskeygenassist	\$0x10,%xmm2,%xmm1	# round 7,8
-+	call		.Lkey_expansion_192a
-+	aeskeygenassist	\$0x20,%xmm2,%xmm1	# round 8,9
-+	call		.Lkey_expansion_192b
-+	aeskeygenassist	\$0x40,%xmm2,%xmm1	# round 10,11
-+	call		.Lkey_expansion_192a
-+	aeskeygenassist	\$0x80,%xmm2,%xmm1	# round 11,12
-+	call		.Lkey_expansion_192b
-+	$movkey	%xmm0,(%rax)
-+	mov	$bits,48(%rax)	# 240(%rdx)
-+	xor	%rax, %rax
-+	jmp	.Lenc_key_ret
-+
-+.align	16
-+.L12rounds_alt:
-+	movdqa	.Lkey_rotate192(%rip),%xmm5
-+	movdqa	.Lkey_rcon1(%rip),%xmm4
-+	mov	\$8,%r10d
-+	movdqu	%xmm0,($key)
-+	jmp	.Loop_key192
-+
-+.align	16
-+.Loop_key192:
-+	movq		%xmm2,0(%rax)
-+	movdqa		%xmm2,%xmm1
-+	pshufb		%xmm5,%xmm2
-+	aesenclast	%xmm4,%xmm2
-+	pslld		\$1, %xmm4
-+	lea		24(%rax),%rax
-+
-+	movdqa		%xmm0,%xmm3
-+	pslldq		\$4,%xmm0
-+	pxor		%xmm0,%xmm3
-+	pslldq		\$4,%xmm0
-+	pxor		%xmm0,%xmm3
-+	pslldq		\$4,%xmm0
-+	pxor		%xmm3,%xmm0
-+
-+	pshufd		\$0xff,%xmm0,%xmm3
-+	pxor		%xmm1,%xmm3
-+	pslldq		\$4,%xmm1
-+	pxor		%xmm1,%xmm3
-+
-+	pxor		%xmm2,%xmm0
-+	pxor		%xmm3,%xmm2
-+	movdqu		%xmm0,-16(%rax)
-+
-+	dec	%r10d
-+	jnz	.Loop_key192
-+
-+	mov	$bits,32(%rax)	# 240($key)
-+	xor	%eax,%eax
-+	jmp	.Lenc_key_ret
-+
-+.align	16
-+.L14rounds:
-+	movups	16($inp),%xmm2			# remaning half of *userKey
-+	mov	\$13,$bits			# 14 rounds for 256
-+	lea	16(%rax),%rax
-+	cmp	\$`1<<28`,%r10d			# AVX, but no XOP
-+	je	.L14rounds_alt
-+
-+	$movkey	%xmm0,($key)			# round 0
-+	$movkey	%xmm2,16($key)			# round 1
-+	aeskeygenassist	\$0x1,%xmm2,%xmm1	# round 2
-+	call		.Lkey_expansion_256a_cold
-+	aeskeygenassist	\$0x1,%xmm0,%xmm1	# round 3
-+	call		.Lkey_expansion_256b
-+	aeskeygenassist	\$0x2,%xmm2,%xmm1	# round 4
-+	call		.Lkey_expansion_256a
-+	aeskeygenassist	\$0x2,%xmm0,%xmm1	# round 5
-+	call		.Lkey_expansion_256b
-+	aeskeygenassist	\$0x4,%xmm2,%xmm1	# round 6
-+	call		.Lkey_expansion_256a
-+	aeskeygenassist	\$0x4,%xmm0,%xmm1	# round 7
-+	call		.Lkey_expansion_256b
-+	aeskeygenassist	\$0x8,%xmm2,%xmm1	# round 8
-+	call		.Lkey_expansion_256a
-+	aeskeygenassist	\$0x8,%xmm0,%xmm1	# round 9
-+	call		.Lkey_expansion_256b
-+	aeskeygenassist	\$0x10,%xmm2,%xmm1	# round 10
-+	call		.Lkey_expansion_256a
-+	aeskeygenassist	\$0x10,%xmm0,%xmm1	# round 11
-+	call		.Lkey_expansion_256b
-+	aeskeygenassist	\$0x20,%xmm2,%xmm1	# round 12
-+	call		.Lkey_expansion_256a
-+	aeskeygenassist	\$0x20,%xmm0,%xmm1	# round 13
-+	call		.Lkey_expansion_256b
-+	aeskeygenassist	\$0x40,%xmm2,%xmm1	# round 14
-+	call		.Lkey_expansion_256a
-+	$movkey	%xmm0,(%rax)
-+	mov	$bits,16(%rax)	# 240(%rdx)
-+	xor	%rax,%rax
-+	jmp	.Lenc_key_ret
-+
-+.align	16
-+.L14rounds_alt:
-+	movdqa	.Lkey_rotate(%rip),%xmm5
-+	movdqa	.Lkey_rcon1(%rip),%xmm4
-+	mov	\$7,%r10d
-+	movdqu	%xmm0,0($key)
-+	movdqa	%xmm2,%xmm1
-+	movdqu	%xmm2,16($key)
-+	jmp	.Loop_key256
-+
-+.align	16
-+.Loop_key256:
-+	pshufb		%xmm5,%xmm2
-+	aesenclast	%xmm4,%xmm2
-+
-+	movdqa		%xmm0,%xmm3
-+	pslldq		\$4,%xmm0
-+	pxor		%xmm0,%xmm3
-+	pslldq		\$4,%xmm0
-+	pxor		%xmm0,%xmm3
-+	pslldq		\$4,%xmm0
-+	pxor		%xmm3,%xmm0
-+	pslld		\$1,%xmm4
-+
-+	pxor		%xmm2,%xmm0
-+	movdqu		%xmm0,(%rax)
-+
-+	dec	%r10d
-+	jz	.Ldone_key256
-+
-+	pshufd		\$0xff,%xmm0,%xmm2
-+	pxor		%xmm3,%xmm3
-+	aesenclast	%xmm3,%xmm2
-+
-+	movdqa		%xmm1,%xmm3
-+	pslldq		\$4,%xmm1
-+	pxor		%xmm1,%xmm3
-+	pslldq		\$4,%xmm1
-+	pxor		%xmm1,%xmm3
-+	pslldq		\$4,%xmm1
-+	pxor		%xmm3,%xmm1
-+
-+	pxor		%xmm1,%xmm2
-+	movdqu		%xmm2,16(%rax)
-+	lea		32(%rax),%rax
-+	movdqa		%xmm2,%xmm1
-+
-+	jmp	.Loop_key256
-+
-+.Ldone_key256:
-+	mov	$bits,16(%rax)	# 240($key)
-+	xor	%eax,%eax
-+	jmp	.Lenc_key_ret
-+
-+.align	16
-+.Lbad_keybits:
-+	mov	\$-2,%rax
-+.Lenc_key_ret:
-+	pxor	%xmm0,%xmm0
-+	pxor	%xmm1,%xmm1
-+	pxor	%xmm2,%xmm2
-+	pxor	%xmm3,%xmm3
-+	pxor	%xmm4,%xmm4
-+	pxor	%xmm5,%xmm5
-+	add	\$8,%rsp
-+	ret
-+.LSEH_end_set_encrypt_key:
-+
-+.align	16
-+.Lkey_expansion_128:
-+	$movkey	%xmm0,(%rax)
-+	lea	16(%rax),%rax
-+.Lkey_expansion_128_cold:
-+	shufps	\$0b00010000,%xmm0,%xmm4
-+	xorps	%xmm4, %xmm0
-+	shufps	\$0b10001100,%xmm0,%xmm4
-+	xorps	%xmm4, %xmm0
-+	shufps	\$0b11111111,%xmm1,%xmm1	# critical path
-+	xorps	%xmm1,%xmm0
-+	ret
-+
-+.align 16
-+.Lkey_expansion_192a:
-+	$movkey	%xmm0,(%rax)
-+	lea	16(%rax),%rax
-+.Lkey_expansion_192a_cold:
-+	movaps	%xmm2, %xmm5
-+.Lkey_expansion_192b_warm:
-+	shufps	\$0b00010000,%xmm0,%xmm4
-+	movdqa	%xmm2,%xmm3
-+	xorps	%xmm4,%xmm0
-+	shufps	\$0b10001100,%xmm0,%xmm4
-+	pslldq	\$4,%xmm3
-+	xorps	%xmm4,%xmm0
-+	pshufd	\$0b01010101,%xmm1,%xmm1	# critical path
-+	pxor	%xmm3,%xmm2
-+	pxor	%xmm1,%xmm0
-+	pshufd	\$0b11111111,%xmm0,%xmm3
-+	pxor	%xmm3,%xmm2
-+	ret
-+
-+.align 16
-+.Lkey_expansion_192b:
-+	movaps	%xmm0,%xmm3
-+	shufps	\$0b01000100,%xmm0,%xmm5
-+	$movkey	%xmm5,(%rax)
-+	shufps	\$0b01001110,%xmm2,%xmm3
-+	$movkey	%xmm3,16(%rax)
-+	lea	32(%rax),%rax
-+	jmp	.Lkey_expansion_192b_warm
-+
-+.align	16
-+.Lkey_expansion_256a:
-+	$movkey	%xmm2,(%rax)
-+	lea	16(%rax),%rax
-+.Lkey_expansion_256a_cold:
-+	shufps	\$0b00010000,%xmm0,%xmm4
-+	xorps	%xmm4,%xmm0
-+	shufps	\$0b10001100,%xmm0,%xmm4
-+	xorps	%xmm4,%xmm0
-+	shufps	\$0b11111111,%xmm1,%xmm1	# critical path
-+	xorps	%xmm1,%xmm0
-+	ret
-+
-+.align 16
-+.Lkey_expansion_256b:
-+	$movkey	%xmm0,(%rax)
-+	lea	16(%rax),%rax
-+
-+	shufps	\$0b00010000,%xmm2,%xmm4
-+	xorps	%xmm4,%xmm2
-+	shufps	\$0b10001100,%xmm2,%xmm4
-+	xorps	%xmm4,%xmm2
-+	shufps	\$0b10101010,%xmm1,%xmm1	# critical path
-+	xorps	%xmm1,%xmm2
-+	ret
-+.size	${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key
-+.size	__aesni_set_encrypt_key,.-__aesni_set_encrypt_key
-+___
-+}
-+
-+$code.=<<___;
-+.align	64
-+.Lbswap_mask:
-+	.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
-+.Lincrement32:
-+	.long	6,6,6,0
-+.Lincrement64:
-+	.long	1,0,0,0
-+.Lxts_magic:
-+	.long	0x87,0,1,0
-+.Lincrement1:
-+	.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
-+.Lkey_rotate:
-+	.long	0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d
-+.Lkey_rotate192:
-+	.long	0x04070605,0x04070605,0x04070605,0x04070605
-+.Lkey_rcon1:
-+	.long	1,1,1,1
-+.Lkey_rcon1b:
-+	.long	0x1b,0x1b,0x1b,0x1b
-+
-+.asciz  "AES for Intel AES-NI, CRYPTOGAMS by "
-+.align	64
-+___
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+___
-+$code.=<<___ if ($PREFIX eq "aesni");
-+.type	ecb_ccm64_se_handler,\@abi-omnipotent
-+.align	16
-+ecb_ccm64_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+
-+	lea	0(%rax),%rsi		# %xmm save area
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$8,%ecx		# 4*sizeof(%xmm0)/sizeof(%rax)
-+	.long	0xa548f3fc		# cld; rep movsq
-+	lea	0x58(%rax),%rax		# adjust stack pointer
-+
-+	jmp	.Lcommon_seh_tail
-+.size	ecb_ccm64_se_handler,.-ecb_ccm64_se_handler
-+
-+.type	ctr_xts_se_handler,\@abi-omnipotent
-+.align	16
-+ctr_xts_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue lable
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+
-+	mov	160($context),%rax	# pull context->Rbp
-+	lea	-0xa0(%rax),%rsi	# %xmm save area
-+	lea	512($context),%rdi	# & context.Xmm6
-+	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	jmp	.Lcommon_rbp_tail
-+.size	ctr_xts_se_handler,.-ctr_xts_se_handler
-+
-+.type	ocb_se_handler,\@abi-omnipotent
-+.align	16
-+ocb_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue lable
-+	cmp	%r10,%rbx		# context->RipRip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+
-+	mov	8(%r11),%r10d		# HandlerData[2]
-+	lea	(%rsi,%r10),%r10
-+	cmp	%r10,%rbx		# context->Rip>=pop label
-+	jae	.Locb_no_xmm
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	lea	(%rax),%rsi		# %xmm save area
-+	lea	512($context),%rdi	# & context.Xmm6
-+	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
-+	.long	0xa548f3fc		# cld; rep movsq
-+	lea	0xa0+0x28(%rax),%rax
-+
-+.Locb_no_xmm:
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+
-+	jmp	.Lcommon_seh_tail
-+.size	ocb_se_handler,.-ocb_se_handler
-+___
-+$code.=<<___;
-+.type	cbc_se_handler,\@abi-omnipotent
-+.align	16
-+cbc_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lcbc_decrypt_bulk(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<"prologue" label
-+	jb	.Lcommon_seh_tail
-+
-+	lea	.Lcbc_decrypt_body(%rip),%r10
-+	cmp	%r10,%rbx		# context->RipRip>="epilogue" label
-+	jae	.Lcommon_seh_tail
-+
-+	lea	16(%rax),%rsi		# %xmm save area
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+.Lcommon_rbp_tail:
-+	mov	160($context),%rax	# pull context->Rbp
-+	mov	(%rax),%rbp		# restore saved %rbp
-+	lea	8(%rax),%rax		# adjust stack pointer
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	jmp	.Lcommon_seh_tail
-+
-+.Lrestore_cbc_rax:
-+	mov	120($context),%rax
-+
-+.Lcommon_seh_tail:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	cbc_se_handler,.-cbc_se_handler
-+
-+.section	.pdata
-+.align	4
-+___
-+$code.=<<___ if ($PREFIX eq "aesni");
-+	.rva	.LSEH_begin_aesni_ecb_encrypt
-+	.rva	.LSEH_end_aesni_ecb_encrypt
-+	.rva	.LSEH_info_ecb
-+
-+	.rva	.LSEH_begin_aesni_ccm64_encrypt_blocks
-+	.rva	.LSEH_end_aesni_ccm64_encrypt_blocks
-+	.rva	.LSEH_info_ccm64_enc
-+
-+	.rva	.LSEH_begin_aesni_ccm64_decrypt_blocks
-+	.rva	.LSEH_end_aesni_ccm64_decrypt_blocks
-+	.rva	.LSEH_info_ccm64_dec
-+
-+	.rva	.LSEH_begin_aesni_ctr32_encrypt_blocks
-+	.rva	.LSEH_end_aesni_ctr32_encrypt_blocks
-+	.rva	.LSEH_info_ctr32
-+
-+	.rva	.LSEH_begin_aesni_xts_encrypt
-+	.rva	.LSEH_end_aesni_xts_encrypt
-+	.rva	.LSEH_info_xts_enc
-+
-+	.rva	.LSEH_begin_aesni_xts_decrypt
-+	.rva	.LSEH_end_aesni_xts_decrypt
-+	.rva	.LSEH_info_xts_dec
-+
-+	.rva	.LSEH_begin_aesni_ocb_encrypt
-+	.rva	.LSEH_end_aesni_ocb_encrypt
-+	.rva	.LSEH_info_ocb_enc
-+
-+	.rva	.LSEH_begin_aesni_ocb_decrypt
-+	.rva	.LSEH_end_aesni_ocb_decrypt
-+	.rva	.LSEH_info_ocb_dec
-+___
-+$code.=<<___;
-+	.rva	.LSEH_begin_${PREFIX}_cbc_encrypt
-+	.rva	.LSEH_end_${PREFIX}_cbc_encrypt
-+	.rva	.LSEH_info_cbc
-+
-+	.rva	${PREFIX}_set_decrypt_key
-+	.rva	.LSEH_end_set_decrypt_key
-+	.rva	.LSEH_info_key
-+
-+	.rva	${PREFIX}_set_encrypt_key
-+	.rva	.LSEH_end_set_encrypt_key
-+	.rva	.LSEH_info_key
-+.section	.xdata
-+.align	8
-+___
-+$code.=<<___ if ($PREFIX eq "aesni");
-+.LSEH_info_ecb:
-+	.byte	9,0,0,0
-+	.rva	ecb_ccm64_se_handler
-+	.rva	.Lecb_enc_body,.Lecb_enc_ret		# HandlerData[]
-+.LSEH_info_ccm64_enc:
-+	.byte	9,0,0,0
-+	.rva	ecb_ccm64_se_handler
-+	.rva	.Lccm64_enc_body,.Lccm64_enc_ret	# HandlerData[]
-+.LSEH_info_ccm64_dec:
-+	.byte	9,0,0,0
-+	.rva	ecb_ccm64_se_handler
-+	.rva	.Lccm64_dec_body,.Lccm64_dec_ret	# HandlerData[]
-+.LSEH_info_ctr32:
-+	.byte	9,0,0,0
-+	.rva	ctr_xts_se_handler
-+	.rva	.Lctr32_body,.Lctr32_epilogue		# HandlerData[]
-+.LSEH_info_xts_enc:
-+	.byte	9,0,0,0
-+	.rva	ctr_xts_se_handler
-+	.rva	.Lxts_enc_body,.Lxts_enc_epilogue	# HandlerData[]
-+.LSEH_info_xts_dec:
-+	.byte	9,0,0,0
-+	.rva	ctr_xts_se_handler
-+	.rva	.Lxts_dec_body,.Lxts_dec_epilogue	# HandlerData[]
-+.LSEH_info_ocb_enc:
-+	.byte	9,0,0,0
-+	.rva	ocb_se_handler
-+	.rva	.Locb_enc_body,.Locb_enc_epilogue	# HandlerData[]
-+	.rva	.Locb_enc_pop
-+	.long	0
-+.LSEH_info_ocb_dec:
-+	.byte	9,0,0,0
-+	.rva	ocb_se_handler
-+	.rva	.Locb_dec_body,.Locb_dec_epilogue	# HandlerData[]
-+	.rva	.Locb_dec_pop
-+	.long	0
-+___
-+$code.=<<___;
-+.LSEH_info_cbc:
-+	.byte	9,0,0,0
-+	.rva	cbc_se_handler
-+.LSEH_info_key:
-+	.byte	0x01,0x04,0x01,0x00
-+	.byte	0x04,0x02,0x00,0x00	# sub rsp,8
-+___
-+}
-+
-+sub rex {
-+  local *opcode=shift;
-+  my ($dst,$src)=@_;
-+  my $rex=0;
-+
-+    $rex|=0x04			if($dst>=8);
-+    $rex|=0x01			if($src>=8);
-+    push @opcode,$rex|0x40	if($rex);
-+}
-+
-+sub aesni {
-+  my $line=shift;
-+  my @opcode=(0x66);
-+
-+    if ($line=~/(aeskeygenassist)\s+\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+	rex(\@opcode,$4,$3);
-+	push @opcode,0x0f,0x3a,0xdf;
-+	push @opcode,0xc0|($3&7)|(($4&7)<<3);	# ModR/M
-+	my $c=$2;
-+	push @opcode,$c=~/^0/?oct($c):$c;
-+	return ".byte\t".join(',',@opcode);
-+    }
-+    elsif ($line=~/(aes[a-z]+)\s+%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+	my %opcodelet = (
-+		"aesimc" => 0xdb,
-+		"aesenc" => 0xdc,	"aesenclast" => 0xdd,
-+		"aesdec" => 0xde,	"aesdeclast" => 0xdf
-+	);
-+	return undef if (!defined($opcodelet{$1}));
-+	rex(\@opcode,$3,$2);
-+	push @opcode,0x0f,0x38,$opcodelet{$1};
-+	push @opcode,0xc0|($2&7)|(($3&7)<<3);	# ModR/M
-+	return ".byte\t".join(',',@opcode);
-+    }
-+    elsif ($line=~/(aes[a-z]+)\s+([0x1-9a-fA-F]*)\(%rsp\),\s*%xmm([0-9]+)/) {
-+	my %opcodelet = (
-+		"aesenc" => 0xdc,	"aesenclast" => 0xdd,
-+		"aesdec" => 0xde,	"aesdeclast" => 0xdf
-+	);
-+	return undef if (!defined($opcodelet{$1}));
-+	my $off = $2;
-+	push @opcode,0x44 if ($3>=8);
-+	push @opcode,0x0f,0x38,$opcodelet{$1};
-+	push @opcode,0x44|(($3&7)<<3),0x24;	# ModR/M
-+	push @opcode,($off=~/^0/?oct($off):$off)&0xff;
-+	return ".byte\t".join(',',@opcode);
-+    }
-+    return $line;
-+}
-+
-+sub movbe {
-+	".byte	0x0f,0x38,0xf1,0x44,0x24,".shift;
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+$code =~ s/\b(aes.*%xmm[0-9]+).*$/aesni($1)/gem;
-+#$code =~ s/\bmovbe\s+%eax/bswap %eax; mov %eax/gm;	# debugging artefact
-+$code =~ s/\bmovbe\s+%eax,\s*([0-9]+)\(%rsp\)/movbe($1)/gem;
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesp8-ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesp8-ppc.pl
-new file mode 100755
-index 0000000..b7e92f6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesp8-ppc.pl
-@@ -0,0 +1,3805 @@
-+#! /usr/bin/env perl
-+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements support for AES instructions as per PowerISA
-+# specification version 2.07, first implemented by POWER8 processor.
-+# The module is endian-agnostic in sense that it supports both big-
-+# and little-endian cases. Data alignment in parallelizable modes is
-+# handled with VSX loads and stores, which implies MSR.VSX flag being
-+# set. It should also be noted that ISA specification doesn't prohibit
-+# alignment exceptions for these instructions on page boundaries.
-+# Initially alignment was handled in pure AltiVec/VMX way [when data
-+# is aligned programmatically, which in turn guarantees exception-
-+# free execution], but it turned to hamper performance when vcipher
-+# instructions are interleaved. It's reckoned that eventual
-+# misalignment penalties at page boundaries are in average lower
-+# than additional overhead in pure AltiVec approach.
-+#
-+# May 2016
-+#
-+# Add XTS subroutine, 9x on little- and 12x improvement on big-endian
-+# systems were measured.
-+#
-+######################################################################
-+# Current large-block performance in cycles per byte processed with
-+# 128-bit key (less is better).
-+#
-+#		CBC en-/decrypt	CTR	XTS
-+# POWER8[le]	3.96/0.72	0.74	1.1
-+# POWER8[be]	3.75/0.65	0.66	1.0
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /64/) {
-+	$SIZE_T	=8;
-+	$LRSAVE	=2*$SIZE_T;
-+	$STU	="stdu";
-+	$POP	="ld";
-+	$PUSH	="std";
-+	$UCMP	="cmpld";
-+	$SHL	="sldi";
-+} elsif ($flavour =~ /32/) {
-+	$SIZE_T	=4;
-+	$LRSAVE	=$SIZE_T;
-+	$STU	="stwu";
-+	$POP	="lwz";
-+	$PUSH	="stw";
-+	$UCMP	="cmplw";
-+	$SHL	="slwi";
-+} else { die "nonsense $flavour"; }
-+
-+$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-+
-+$FRAME=8*$SIZE_T;
-+$prefix="aes_p8";
-+
-+$sp="r1";
-+$vrsave="r12";
-+
-+#########################################################################
-+{{{	# Key setup procedures						#
-+my ($inp,$bits,$out,$ptr,$cnt,$rounds)=map("r$_",(3..8));
-+my ($zero,$in0,$in1,$key,$rcon,$mask,$tmp)=map("v$_",(0..6));
-+my ($stage,$outperm,$outmask,$outhead,$outtail)=map("v$_",(7..11));
-+
-+$code.=<<___;
-+.machine	"any"
-+
-+.text
-+
-+.align	7
-+rcon:
-+.long	0x01000000, 0x01000000, 0x01000000, 0x01000000	?rev
-+.long	0x1b000000, 0x1b000000, 0x1b000000, 0x1b000000	?rev
-+.long	0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c	?rev
-+.long	0,0,0,0						?asis
-+Lconsts:
-+	mflr	r0
-+	bcl	20,31,\$+4
-+	mflr	$ptr	 #vvvvv "distance between . and rcon
-+	addi	$ptr,$ptr,-0x48
-+	mtlr	r0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+.asciz	"AES for PowerISA 2.07, CRYPTOGAMS by "
-+
-+.globl	.${prefix}_set_encrypt_key
-+.align	5
-+.${prefix}_set_encrypt_key:
-+Lset_encrypt_key:
-+	mflr		r11
-+	$PUSH		r11,$LRSAVE($sp)
-+
-+	li		$ptr,-1
-+	${UCMP}i	$inp,0
-+	beq-		Lenc_key_abort		# if ($inp==0) return -1;
-+	${UCMP}i	$out,0
-+	beq-		Lenc_key_abort		# if ($out==0) return -1;
-+	li		$ptr,-2
-+	cmpwi		$bits,128
-+	blt-		Lenc_key_abort
-+	cmpwi		$bits,256
-+	bgt-		Lenc_key_abort
-+	andi.		r0,$bits,0x3f
-+	bne-		Lenc_key_abort
-+
-+	lis		r0,0xfff0
-+	mfspr		$vrsave,256
-+	mtspr		256,r0
-+
-+	bl		Lconsts
-+	mtlr		r11
-+
-+	neg		r9,$inp
-+	lvx		$in0,0,$inp
-+	addi		$inp,$inp,15		# 15 is not typo
-+	lvsr		$key,0,r9		# borrow $key
-+	li		r8,0x20
-+	cmpwi		$bits,192
-+	lvx		$in1,0,$inp
-+	le?vspltisb	$mask,0x0f		# borrow $mask
-+	lvx		$rcon,0,$ptr
-+	le?vxor		$key,$key,$mask		# adjust for byte swap
-+	lvx		$mask,r8,$ptr
-+	addi		$ptr,$ptr,0x10
-+	vperm		$in0,$in0,$in1,$key	# align [and byte swap in LE]
-+	li		$cnt,8
-+	vxor		$zero,$zero,$zero
-+	mtctr		$cnt
-+
-+	?lvsr		$outperm,0,$out
-+	vspltisb	$outmask,-1
-+	lvx		$outhead,0,$out
-+	?vperm		$outmask,$zero,$outmask,$outperm
-+
-+	blt		Loop128
-+	addi		$inp,$inp,8
-+	beq		L192
-+	addi		$inp,$inp,8
-+	b		L256
-+
-+.align	4
-+Loop128:
-+	vperm		$key,$in0,$in0,$mask	# rotate-n-splat
-+	vsldoi		$tmp,$zero,$in0,12	# >>32
-+	 vperm		$outtail,$in0,$in0,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	vcipherlast	$key,$key,$rcon
-+	 stvx		$stage,0,$out
-+	 addi		$out,$out,16
-+
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+	 vadduwm	$rcon,$rcon,$rcon
-+	vxor		$in0,$in0,$key
-+	bdnz		Loop128
-+
-+	lvx		$rcon,0,$ptr		# last two round keys
-+
-+	vperm		$key,$in0,$in0,$mask	# rotate-n-splat
-+	vsldoi		$tmp,$zero,$in0,12	# >>32
-+	 vperm		$outtail,$in0,$in0,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	vcipherlast	$key,$key,$rcon
-+	 stvx		$stage,0,$out
-+	 addi		$out,$out,16
-+
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+	 vadduwm	$rcon,$rcon,$rcon
-+	vxor		$in0,$in0,$key
-+
-+	vperm		$key,$in0,$in0,$mask	# rotate-n-splat
-+	vsldoi		$tmp,$zero,$in0,12	# >>32
-+	 vperm		$outtail,$in0,$in0,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	vcipherlast	$key,$key,$rcon
-+	 stvx		$stage,0,$out
-+	 addi		$out,$out,16
-+
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+	vxor		$in0,$in0,$key
-+	 vperm		$outtail,$in0,$in0,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	 stvx		$stage,0,$out
-+
-+	addi		$inp,$out,15		# 15 is not typo
-+	addi		$out,$out,0x50
-+
-+	li		$rounds,10
-+	b		Ldone
-+
-+.align	4
-+L192:
-+	lvx		$tmp,0,$inp
-+	li		$cnt,4
-+	 vperm		$outtail,$in0,$in0,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	 stvx		$stage,0,$out
-+	 addi		$out,$out,16
-+	vperm		$in1,$in1,$tmp,$key	# align [and byte swap in LE]
-+	vspltisb	$key,8			# borrow $key
-+	mtctr		$cnt
-+	vsububm		$mask,$mask,$key	# adjust the mask
-+
-+Loop192:
-+	vperm		$key,$in1,$in1,$mask	# roate-n-splat
-+	vsldoi		$tmp,$zero,$in0,12	# >>32
-+	vcipherlast	$key,$key,$rcon
-+
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+
-+	 vsldoi		$stage,$zero,$in1,8
-+	vspltw		$tmp,$in0,3
-+	vxor		$tmp,$tmp,$in1
-+	vsldoi		$in1,$zero,$in1,12	# >>32
-+	 vadduwm	$rcon,$rcon,$rcon
-+	vxor		$in1,$in1,$tmp
-+	vxor		$in0,$in0,$key
-+	vxor		$in1,$in1,$key
-+	 vsldoi		$stage,$stage,$in0,8
-+
-+	vperm		$key,$in1,$in1,$mask	# rotate-n-splat
-+	vsldoi		$tmp,$zero,$in0,12	# >>32
-+	 vperm		$outtail,$stage,$stage,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	vcipherlast	$key,$key,$rcon
-+	 stvx		$stage,0,$out
-+	 addi		$out,$out,16
-+
-+	 vsldoi		$stage,$in0,$in1,8
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	 vperm		$outtail,$stage,$stage,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+	 stvx		$stage,0,$out
-+	 addi		$out,$out,16
-+
-+	vspltw		$tmp,$in0,3
-+	vxor		$tmp,$tmp,$in1
-+	vsldoi		$in1,$zero,$in1,12	# >>32
-+	 vadduwm	$rcon,$rcon,$rcon
-+	vxor		$in1,$in1,$tmp
-+	vxor		$in0,$in0,$key
-+	vxor		$in1,$in1,$key
-+	 vperm		$outtail,$in0,$in0,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	 stvx		$stage,0,$out
-+	 addi		$inp,$out,15		# 15 is not typo
-+	 addi		$out,$out,16
-+	bdnz		Loop192
-+
-+	li		$rounds,12
-+	addi		$out,$out,0x20
-+	b		Ldone
-+
-+.align	4
-+L256:
-+	lvx		$tmp,0,$inp
-+	li		$cnt,7
-+	li		$rounds,14
-+	 vperm		$outtail,$in0,$in0,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	 stvx		$stage,0,$out
-+	 addi		$out,$out,16
-+	vperm		$in1,$in1,$tmp,$key	# align [and byte swap in LE]
-+	mtctr		$cnt
-+
-+Loop256:
-+	vperm		$key,$in1,$in1,$mask	# rotate-n-splat
-+	vsldoi		$tmp,$zero,$in0,12	# >>32
-+	 vperm		$outtail,$in1,$in1,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	vcipherlast	$key,$key,$rcon
-+	 stvx		$stage,0,$out
-+	 addi		$out,$out,16
-+
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in0,$in0,$tmp
-+	 vadduwm	$rcon,$rcon,$rcon
-+	vxor		$in0,$in0,$key
-+	 vperm		$outtail,$in0,$in0,$outperm	# rotate
-+	 vsel		$stage,$outhead,$outtail,$outmask
-+	 vmr		$outhead,$outtail
-+	 stvx		$stage,0,$out
-+	 addi		$inp,$out,15		# 15 is not typo
-+	 addi		$out,$out,16
-+	bdz		Ldone
-+
-+	vspltw		$key,$in0,3		# just splat
-+	vsldoi		$tmp,$zero,$in1,12	# >>32
-+	vsbox		$key,$key
-+
-+	vxor		$in1,$in1,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in1,$in1,$tmp
-+	vsldoi		$tmp,$zero,$tmp,12	# >>32
-+	vxor		$in1,$in1,$tmp
-+
-+	vxor		$in1,$in1,$key
-+	b		Loop256
-+
-+.align	4
-+Ldone:
-+	lvx		$in1,0,$inp		# redundant in aligned case
-+	vsel		$in1,$outhead,$in1,$outmask
-+	stvx		$in1,0,$inp
-+	li		$ptr,0
-+	mtspr		256,$vrsave
-+	stw		$rounds,0($out)
-+
-+Lenc_key_abort:
-+	mr		r3,$ptr
-+	blr
-+	.long		0
-+	.byte		0,12,0x14,1,0,0,3,0
-+	.long		0
-+.size	.${prefix}_set_encrypt_key,.-.${prefix}_set_encrypt_key
-+
-+.globl	.${prefix}_set_decrypt_key
-+.align	5
-+.${prefix}_set_decrypt_key:
-+	$STU		$sp,-$FRAME($sp)
-+	mflr		r10
-+	$PUSH		r10,$FRAME+$LRSAVE($sp)
-+	bl		Lset_encrypt_key
-+	mtlr		r10
-+
-+	cmpwi		r3,0
-+	bne-		Ldec_key_abort
-+
-+	slwi		$cnt,$rounds,4
-+	subi		$inp,$out,240		# first round key
-+	srwi		$rounds,$rounds,1
-+	add		$out,$inp,$cnt		# last round key
-+	mtctr		$rounds
-+
-+Ldeckey:
-+	lwz		r0, 0($inp)
-+	lwz		r6, 4($inp)
-+	lwz		r7, 8($inp)
-+	lwz		r8, 12($inp)
-+	addi		$inp,$inp,16
-+	lwz		r9, 0($out)
-+	lwz		r10,4($out)
-+	lwz		r11,8($out)
-+	lwz		r12,12($out)
-+	stw		r0, 0($out)
-+	stw		r6, 4($out)
-+	stw		r7, 8($out)
-+	stw		r8, 12($out)
-+	subi		$out,$out,16
-+	stw		r9, -16($inp)
-+	stw		r10,-12($inp)
-+	stw		r11,-8($inp)
-+	stw		r12,-4($inp)
-+	bdnz		Ldeckey
-+
-+	xor		r3,r3,r3		# return value
-+Ldec_key_abort:
-+	addi		$sp,$sp,$FRAME
-+	blr
-+	.long		0
-+	.byte		0,12,4,1,0x80,0,3,0
-+	.long		0
-+.size	.${prefix}_set_decrypt_key,.-.${prefix}_set_decrypt_key
-+___
-+}}}
-+#########################################################################
-+{{{	# Single block en- and decrypt procedures			#
-+sub gen_block () {
-+my $dir = shift;
-+my $n   = $dir eq "de" ? "n" : "";
-+my ($inp,$out,$key,$rounds,$idx)=map("r$_",(3..7));
-+
-+$code.=<<___;
-+.globl	.${prefix}_${dir}crypt
-+.align	5
-+.${prefix}_${dir}crypt:
-+	lwz		$rounds,240($key)
-+	lis		r0,0xfc00
-+	mfspr		$vrsave,256
-+	li		$idx,15			# 15 is not typo
-+	mtspr		256,r0
-+
-+	lvx		v0,0,$inp
-+	neg		r11,$out
-+	lvx		v1,$idx,$inp
-+	lvsl		v2,0,$inp		# inpperm
-+	le?vspltisb	v4,0x0f
-+	?lvsl		v3,0,r11		# outperm
-+	le?vxor		v2,v2,v4
-+	li		$idx,16
-+	vperm		v0,v0,v1,v2		# align [and byte swap in LE]
-+	lvx		v1,0,$key
-+	?lvsl		v5,0,$key		# keyperm
-+	srwi		$rounds,$rounds,1
-+	lvx		v2,$idx,$key
-+	addi		$idx,$idx,16
-+	subi		$rounds,$rounds,1
-+	?vperm		v1,v1,v2,v5		# align round key
-+
-+	vxor		v0,v0,v1
-+	lvx		v1,$idx,$key
-+	addi		$idx,$idx,16
-+	mtctr		$rounds
-+
-+Loop_${dir}c:
-+	?vperm		v2,v2,v1,v5
-+	v${n}cipher	v0,v0,v2
-+	lvx		v2,$idx,$key
-+	addi		$idx,$idx,16
-+	?vperm		v1,v1,v2,v5
-+	v${n}cipher	v0,v0,v1
-+	lvx		v1,$idx,$key
-+	addi		$idx,$idx,16
-+	bdnz		Loop_${dir}c
-+
-+	?vperm		v2,v2,v1,v5
-+	v${n}cipher	v0,v0,v2
-+	lvx		v2,$idx,$key
-+	?vperm		v1,v1,v2,v5
-+	v${n}cipherlast	v0,v0,v1
-+
-+	vspltisb	v2,-1
-+	vxor		v1,v1,v1
-+	li		$idx,15			# 15 is not typo
-+	?vperm		v2,v1,v2,v3		# outmask
-+	le?vxor		v3,v3,v4
-+	lvx		v1,0,$out		# outhead
-+	vperm		v0,v0,v0,v3		# rotate [and byte swap in LE]
-+	vsel		v1,v1,v0,v2
-+	lvx		v4,$idx,$out
-+	stvx		v1,0,$out
-+	vsel		v0,v0,v4,v2
-+	stvx		v0,$idx,$out
-+
-+	mtspr		256,$vrsave
-+	blr
-+	.long		0
-+	.byte		0,12,0x14,0,0,0,3,0
-+	.long		0
-+.size	.${prefix}_${dir}crypt,.-.${prefix}_${dir}crypt
-+___
-+}
-+&gen_block("en");
-+&gen_block("de");
-+}}}
-+#########################################################################
-+{{{	# CBC en- and decrypt procedures				#
-+my ($inp,$out,$len,$key,$ivp,$enc,$rounds,$idx)=map("r$_",(3..10));
-+my ($rndkey0,$rndkey1,$inout,$tmp)=		map("v$_",(0..3));
-+my ($ivec,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm)=
-+						map("v$_",(4..10));
-+$code.=<<___;
-+.globl	.${prefix}_cbc_encrypt
-+.align	5
-+.${prefix}_cbc_encrypt:
-+	${UCMP}i	$len,16
-+	bltlr-
-+
-+	cmpwi		$enc,0			# test direction
-+	lis		r0,0xffe0
-+	mfspr		$vrsave,256
-+	mtspr		256,r0
-+
-+	li		$idx,15
-+	vxor		$rndkey0,$rndkey0,$rndkey0
-+	le?vspltisb	$tmp,0x0f
-+
-+	lvx		$ivec,0,$ivp		# load [unaligned] iv
-+	lvsl		$inpperm,0,$ivp
-+	lvx		$inptail,$idx,$ivp
-+	le?vxor		$inpperm,$inpperm,$tmp
-+	vperm		$ivec,$ivec,$inptail,$inpperm
-+
-+	neg		r11,$inp
-+	?lvsl		$keyperm,0,$key		# prepare for unaligned key
-+	lwz		$rounds,240($key)
-+
-+	lvsr		$inpperm,0,r11		# prepare for unaligned load
-+	lvx		$inptail,0,$inp
-+	addi		$inp,$inp,15		# 15 is not typo
-+	le?vxor		$inpperm,$inpperm,$tmp
-+
-+	?lvsr		$outperm,0,$out		# prepare for unaligned store
-+	vspltisb	$outmask,-1
-+	lvx		$outhead,0,$out
-+	?vperm		$outmask,$rndkey0,$outmask,$outperm
-+	le?vxor		$outperm,$outperm,$tmp
-+
-+	srwi		$rounds,$rounds,1
-+	li		$idx,16
-+	subi		$rounds,$rounds,1
-+	beq		Lcbc_dec
-+
-+Lcbc_enc:
-+	vmr		$inout,$inptail
-+	lvx		$inptail,0,$inp
-+	addi		$inp,$inp,16
-+	mtctr		$rounds
-+	subi		$len,$len,16		# len-=16
-+
-+	lvx		$rndkey0,0,$key
-+	 vperm		$inout,$inout,$inptail,$inpperm
-+	lvx		$rndkey1,$idx,$key
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key
-+	addi		$idx,$idx,16
-+	vxor		$inout,$inout,$ivec
-+
-+Loop_cbc_enc:
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vcipher		$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vcipher		$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key
-+	addi		$idx,$idx,16
-+	bdnz		Loop_cbc_enc
-+
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vcipher		$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key
-+	li		$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vcipherlast	$ivec,$inout,$rndkey0
-+	${UCMP}i	$len,16
-+
-+	vperm		$tmp,$ivec,$ivec,$outperm
-+	vsel		$inout,$outhead,$tmp,$outmask
-+	vmr		$outhead,$tmp
-+	stvx		$inout,0,$out
-+	addi		$out,$out,16
-+	bge		Lcbc_enc
-+
-+	b		Lcbc_done
-+
-+.align	4
-+Lcbc_dec:
-+	${UCMP}i	$len,128
-+	bge		_aesp8_cbc_decrypt8x
-+	vmr		$tmp,$inptail
-+	lvx		$inptail,0,$inp
-+	addi		$inp,$inp,16
-+	mtctr		$rounds
-+	subi		$len,$len,16		# len-=16
-+
-+	lvx		$rndkey0,0,$key
-+	 vperm		$tmp,$tmp,$inptail,$inpperm
-+	lvx		$rndkey1,$idx,$key
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$inout,$tmp,$rndkey0
-+	lvx		$rndkey0,$idx,$key
-+	addi		$idx,$idx,16
-+
-+Loop_cbc_dec:
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vncipher	$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vncipher	$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key
-+	addi		$idx,$idx,16
-+	bdnz		Loop_cbc_dec
-+
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vncipher	$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key
-+	li		$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vncipherlast	$inout,$inout,$rndkey0
-+	${UCMP}i	$len,16
-+
-+	vxor		$inout,$inout,$ivec
-+	vmr		$ivec,$tmp
-+	vperm		$tmp,$inout,$inout,$outperm
-+	vsel		$inout,$outhead,$tmp,$outmask
-+	vmr		$outhead,$tmp
-+	stvx		$inout,0,$out
-+	addi		$out,$out,16
-+	bge		Lcbc_dec
-+
-+Lcbc_done:
-+	addi		$out,$out,-1
-+	lvx		$inout,0,$out		# redundant in aligned case
-+	vsel		$inout,$outhead,$inout,$outmask
-+	stvx		$inout,0,$out
-+
-+	neg		$enc,$ivp		# write [unaligned] iv
-+	li		$idx,15			# 15 is not typo
-+	vxor		$rndkey0,$rndkey0,$rndkey0
-+	vspltisb	$outmask,-1
-+	le?vspltisb	$tmp,0x0f
-+	?lvsl		$outperm,0,$enc
-+	?vperm		$outmask,$rndkey0,$outmask,$outperm
-+	le?vxor		$outperm,$outperm,$tmp
-+	lvx		$outhead,0,$ivp
-+	vperm		$ivec,$ivec,$ivec,$outperm
-+	vsel		$inout,$outhead,$ivec,$outmask
-+	lvx		$inptail,$idx,$ivp
-+	stvx		$inout,0,$ivp
-+	vsel		$inout,$ivec,$inptail,$outmask
-+	stvx		$inout,$idx,$ivp
-+
-+	mtspr		256,$vrsave
-+	blr
-+	.long		0
-+	.byte		0,12,0x14,0,0,0,6,0
-+	.long		0
-+___
-+#########################################################################
-+{{	# Optimized CBC decrypt procedure				#
-+my $key_="r11";
-+my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,8,26..31));
-+    $x00=0 if ($flavour =~ /osx/);
-+my ($in0, $in1, $in2, $in3, $in4, $in5, $in6, $in7 )=map("v$_",(0..3,10..13));
-+my ($out0,$out1,$out2,$out3,$out4,$out5,$out6,$out7)=map("v$_",(14..21));
-+my $rndkey0="v23";	# v24-v25 rotating buffer for first found keys
-+			# v26-v31 last 6 round keys
-+my ($tmp,$keyperm)=($in3,$in4);	# aliases with "caller", redundant assignment
-+
-+$code.=<<___;
-+.align	5
-+_aesp8_cbc_decrypt8x:
-+	$STU		$sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
-+	li		r10,`$FRAME+8*16+15`
-+	li		r11,`$FRAME+8*16+31`
-+	stvx		v20,r10,$sp		# ABI says so
-+	addi		r10,r10,32
-+	stvx		v21,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v22,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v23,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v24,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v25,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v26,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v27,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v28,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v29,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v30,r10,$sp
-+	stvx		v31,r11,$sp
-+	li		r0,-1
-+	stw		$vrsave,`$FRAME+21*16-4`($sp)	# save vrsave
-+	li		$x10,0x10
-+	$PUSH		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
-+	li		$x20,0x20
-+	$PUSH		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
-+	li		$x30,0x30
-+	$PUSH		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
-+	li		$x40,0x40
-+	$PUSH		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
-+	li		$x50,0x50
-+	$PUSH		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
-+	li		$x60,0x60
-+	$PUSH		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
-+	li		$x70,0x70
-+	mtspr		256,r0
-+
-+	subi		$rounds,$rounds,3	# -4 in total
-+	subi		$len,$len,128		# bias
-+
-+	lvx		$rndkey0,$x00,$key	# load key schedule
-+	lvx		v30,$x10,$key
-+	addi		$key,$key,0x20
-+	lvx		v31,$x00,$key
-+	?vperm		$rndkey0,$rndkey0,v30,$keyperm
-+	addi		$key_,$sp,$FRAME+15
-+	mtctr		$rounds
-+
-+Load_cbc_dec_key:
-+	?vperm		v24,v30,v31,$keyperm
-+	lvx		v30,$x10,$key
-+	addi		$key,$key,0x20
-+	stvx		v24,$x00,$key_		# off-load round[1]
-+	?vperm		v25,v31,v30,$keyperm
-+	lvx		v31,$x00,$key
-+	stvx		v25,$x10,$key_		# off-load round[2]
-+	addi		$key_,$key_,0x20
-+	bdnz		Load_cbc_dec_key
-+
-+	lvx		v26,$x10,$key
-+	?vperm		v24,v30,v31,$keyperm
-+	lvx		v27,$x20,$key
-+	stvx		v24,$x00,$key_		# off-load round[3]
-+	?vperm		v25,v31,v26,$keyperm
-+	lvx		v28,$x30,$key
-+	stvx		v25,$x10,$key_		# off-load round[4]
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	?vperm		v26,v26,v27,$keyperm
-+	lvx		v29,$x40,$key
-+	?vperm		v27,v27,v28,$keyperm
-+	lvx		v30,$x50,$key
-+	?vperm		v28,v28,v29,$keyperm
-+	lvx		v31,$x60,$key
-+	?vperm		v29,v29,v30,$keyperm
-+	lvx		$out0,$x70,$key		# borrow $out0
-+	?vperm		v30,v30,v31,$keyperm
-+	lvx		v24,$x00,$key_		# pre-load round[1]
-+	?vperm		v31,v31,$out0,$keyperm
-+	lvx		v25,$x10,$key_		# pre-load round[2]
-+
-+	#lvx		$inptail,0,$inp		# "caller" already did this
-+	#addi		$inp,$inp,15		# 15 is not typo
-+	subi		$inp,$inp,15		# undo "caller"
-+
-+	 le?li		$idx,8
-+	lvx_u		$in0,$x00,$inp		# load first 8 "words"
-+	 le?lvsl	$inpperm,0,$idx
-+	 le?vspltisb	$tmp,0x0f
-+	lvx_u		$in1,$x10,$inp
-+	 le?vxor	$inpperm,$inpperm,$tmp	# transform for lvx_u/stvx_u
-+	lvx_u		$in2,$x20,$inp
-+	 le?vperm	$in0,$in0,$in0,$inpperm
-+	lvx_u		$in3,$x30,$inp
-+	 le?vperm	$in1,$in1,$in1,$inpperm
-+	lvx_u		$in4,$x40,$inp
-+	 le?vperm	$in2,$in2,$in2,$inpperm
-+	vxor		$out0,$in0,$rndkey0
-+	lvx_u		$in5,$x50,$inp
-+	 le?vperm	$in3,$in3,$in3,$inpperm
-+	vxor		$out1,$in1,$rndkey0
-+	lvx_u		$in6,$x60,$inp
-+	 le?vperm	$in4,$in4,$in4,$inpperm
-+	vxor		$out2,$in2,$rndkey0
-+	lvx_u		$in7,$x70,$inp
-+	addi		$inp,$inp,0x80
-+	 le?vperm	$in5,$in5,$in5,$inpperm
-+	vxor		$out3,$in3,$rndkey0
-+	 le?vperm	$in6,$in6,$in6,$inpperm
-+	vxor		$out4,$in4,$rndkey0
-+	 le?vperm	$in7,$in7,$in7,$inpperm
-+	vxor		$out5,$in5,$rndkey0
-+	vxor		$out6,$in6,$rndkey0
-+	vxor		$out7,$in7,$rndkey0
-+
-+	mtctr		$rounds
-+	b		Loop_cbc_dec8x
-+.align	5
-+Loop_cbc_dec8x:
-+	vncipher	$out0,$out0,v24
-+	vncipher	$out1,$out1,v24
-+	vncipher	$out2,$out2,v24
-+	vncipher	$out3,$out3,v24
-+	vncipher	$out4,$out4,v24
-+	vncipher	$out5,$out5,v24
-+	vncipher	$out6,$out6,v24
-+	vncipher	$out7,$out7,v24
-+	lvx		v24,$x20,$key_		# round[3]
-+	addi		$key_,$key_,0x20
-+
-+	vncipher	$out0,$out0,v25
-+	vncipher	$out1,$out1,v25
-+	vncipher	$out2,$out2,v25
-+	vncipher	$out3,$out3,v25
-+	vncipher	$out4,$out4,v25
-+	vncipher	$out5,$out5,v25
-+	vncipher	$out6,$out6,v25
-+	vncipher	$out7,$out7,v25
-+	lvx		v25,$x10,$key_		# round[4]
-+	bdnz		Loop_cbc_dec8x
-+
-+	subic		$len,$len,128		# $len-=128
-+	vncipher	$out0,$out0,v24
-+	vncipher	$out1,$out1,v24
-+	vncipher	$out2,$out2,v24
-+	vncipher	$out3,$out3,v24
-+	vncipher	$out4,$out4,v24
-+	vncipher	$out5,$out5,v24
-+	vncipher	$out6,$out6,v24
-+	vncipher	$out7,$out7,v24
-+
-+	subfe.		r0,r0,r0		# borrow?-1:0
-+	vncipher	$out0,$out0,v25
-+	vncipher	$out1,$out1,v25
-+	vncipher	$out2,$out2,v25
-+	vncipher	$out3,$out3,v25
-+	vncipher	$out4,$out4,v25
-+	vncipher	$out5,$out5,v25
-+	vncipher	$out6,$out6,v25
-+	vncipher	$out7,$out7,v25
-+
-+	and		r0,r0,$len
-+	vncipher	$out0,$out0,v26
-+	vncipher	$out1,$out1,v26
-+	vncipher	$out2,$out2,v26
-+	vncipher	$out3,$out3,v26
-+	vncipher	$out4,$out4,v26
-+	vncipher	$out5,$out5,v26
-+	vncipher	$out6,$out6,v26
-+	vncipher	$out7,$out7,v26
-+
-+	add		$inp,$inp,r0		# $inp is adjusted in such
-+						# way that at exit from the
-+						# loop inX-in7 are loaded
-+						# with last "words"
-+	vncipher	$out0,$out0,v27
-+	vncipher	$out1,$out1,v27
-+	vncipher	$out2,$out2,v27
-+	vncipher	$out3,$out3,v27
-+	vncipher	$out4,$out4,v27
-+	vncipher	$out5,$out5,v27
-+	vncipher	$out6,$out6,v27
-+	vncipher	$out7,$out7,v27
-+
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	vncipher	$out0,$out0,v28
-+	vncipher	$out1,$out1,v28
-+	vncipher	$out2,$out2,v28
-+	vncipher	$out3,$out3,v28
-+	vncipher	$out4,$out4,v28
-+	vncipher	$out5,$out5,v28
-+	vncipher	$out6,$out6,v28
-+	vncipher	$out7,$out7,v28
-+	lvx		v24,$x00,$key_		# re-pre-load round[1]
-+
-+	vncipher	$out0,$out0,v29
-+	vncipher	$out1,$out1,v29
-+	vncipher	$out2,$out2,v29
-+	vncipher	$out3,$out3,v29
-+	vncipher	$out4,$out4,v29
-+	vncipher	$out5,$out5,v29
-+	vncipher	$out6,$out6,v29
-+	vncipher	$out7,$out7,v29
-+	lvx		v25,$x10,$key_		# re-pre-load round[2]
-+
-+	vncipher	$out0,$out0,v30
-+	 vxor		$ivec,$ivec,v31		# xor with last round key
-+	vncipher	$out1,$out1,v30
-+	 vxor		$in0,$in0,v31
-+	vncipher	$out2,$out2,v30
-+	 vxor		$in1,$in1,v31
-+	vncipher	$out3,$out3,v30
-+	 vxor		$in2,$in2,v31
-+	vncipher	$out4,$out4,v30
-+	 vxor		$in3,$in3,v31
-+	vncipher	$out5,$out5,v30
-+	 vxor		$in4,$in4,v31
-+	vncipher	$out6,$out6,v30
-+	 vxor		$in5,$in5,v31
-+	vncipher	$out7,$out7,v30
-+	 vxor		$in6,$in6,v31
-+
-+	vncipherlast	$out0,$out0,$ivec
-+	vncipherlast	$out1,$out1,$in0
-+	 lvx_u		$in0,$x00,$inp		# load next input block
-+	vncipherlast	$out2,$out2,$in1
-+	 lvx_u		$in1,$x10,$inp
-+	vncipherlast	$out3,$out3,$in2
-+	 le?vperm	$in0,$in0,$in0,$inpperm
-+	 lvx_u		$in2,$x20,$inp
-+	vncipherlast	$out4,$out4,$in3
-+	 le?vperm	$in1,$in1,$in1,$inpperm
-+	 lvx_u		$in3,$x30,$inp
-+	vncipherlast	$out5,$out5,$in4
-+	 le?vperm	$in2,$in2,$in2,$inpperm
-+	 lvx_u		$in4,$x40,$inp
-+	vncipherlast	$out6,$out6,$in5
-+	 le?vperm	$in3,$in3,$in3,$inpperm
-+	 lvx_u		$in5,$x50,$inp
-+	vncipherlast	$out7,$out7,$in6
-+	 le?vperm	$in4,$in4,$in4,$inpperm
-+	 lvx_u		$in6,$x60,$inp
-+	vmr		$ivec,$in7
-+	 le?vperm	$in5,$in5,$in5,$inpperm
-+	 lvx_u		$in7,$x70,$inp
-+	 addi		$inp,$inp,0x80
-+
-+	le?vperm	$out0,$out0,$out0,$inpperm
-+	le?vperm	$out1,$out1,$out1,$inpperm
-+	stvx_u		$out0,$x00,$out
-+	 le?vperm	$in6,$in6,$in6,$inpperm
-+	 vxor		$out0,$in0,$rndkey0
-+	le?vperm	$out2,$out2,$out2,$inpperm
-+	stvx_u		$out1,$x10,$out
-+	 le?vperm	$in7,$in7,$in7,$inpperm
-+	 vxor		$out1,$in1,$rndkey0
-+	le?vperm	$out3,$out3,$out3,$inpperm
-+	stvx_u		$out2,$x20,$out
-+	 vxor		$out2,$in2,$rndkey0
-+	le?vperm	$out4,$out4,$out4,$inpperm
-+	stvx_u		$out3,$x30,$out
-+	 vxor		$out3,$in3,$rndkey0
-+	le?vperm	$out5,$out5,$out5,$inpperm
-+	stvx_u		$out4,$x40,$out
-+	 vxor		$out4,$in4,$rndkey0
-+	le?vperm	$out6,$out6,$out6,$inpperm
-+	stvx_u		$out5,$x50,$out
-+	 vxor		$out5,$in5,$rndkey0
-+	le?vperm	$out7,$out7,$out7,$inpperm
-+	stvx_u		$out6,$x60,$out
-+	 vxor		$out6,$in6,$rndkey0
-+	stvx_u		$out7,$x70,$out
-+	addi		$out,$out,0x80
-+	 vxor		$out7,$in7,$rndkey0
-+
-+	mtctr		$rounds
-+	beq		Loop_cbc_dec8x		# did $len-=128 borrow?
-+
-+	addic.		$len,$len,128
-+	beq		Lcbc_dec8x_done
-+	nop
-+	nop
-+
-+Loop_cbc_dec8x_tail:				# up to 7 "words" tail...
-+	vncipher	$out1,$out1,v24
-+	vncipher	$out2,$out2,v24
-+	vncipher	$out3,$out3,v24
-+	vncipher	$out4,$out4,v24
-+	vncipher	$out5,$out5,v24
-+	vncipher	$out6,$out6,v24
-+	vncipher	$out7,$out7,v24
-+	lvx		v24,$x20,$key_		# round[3]
-+	addi		$key_,$key_,0x20
-+
-+	vncipher	$out1,$out1,v25
-+	vncipher	$out2,$out2,v25
-+	vncipher	$out3,$out3,v25
-+	vncipher	$out4,$out4,v25
-+	vncipher	$out5,$out5,v25
-+	vncipher	$out6,$out6,v25
-+	vncipher	$out7,$out7,v25
-+	lvx		v25,$x10,$key_		# round[4]
-+	bdnz		Loop_cbc_dec8x_tail
-+
-+	vncipher	$out1,$out1,v24
-+	vncipher	$out2,$out2,v24
-+	vncipher	$out3,$out3,v24
-+	vncipher	$out4,$out4,v24
-+	vncipher	$out5,$out5,v24
-+	vncipher	$out6,$out6,v24
-+	vncipher	$out7,$out7,v24
-+
-+	vncipher	$out1,$out1,v25
-+	vncipher	$out2,$out2,v25
-+	vncipher	$out3,$out3,v25
-+	vncipher	$out4,$out4,v25
-+	vncipher	$out5,$out5,v25
-+	vncipher	$out6,$out6,v25
-+	vncipher	$out7,$out7,v25
-+
-+	vncipher	$out1,$out1,v26
-+	vncipher	$out2,$out2,v26
-+	vncipher	$out3,$out3,v26
-+	vncipher	$out4,$out4,v26
-+	vncipher	$out5,$out5,v26
-+	vncipher	$out6,$out6,v26
-+	vncipher	$out7,$out7,v26
-+
-+	vncipher	$out1,$out1,v27
-+	vncipher	$out2,$out2,v27
-+	vncipher	$out3,$out3,v27
-+	vncipher	$out4,$out4,v27
-+	vncipher	$out5,$out5,v27
-+	vncipher	$out6,$out6,v27
-+	vncipher	$out7,$out7,v27
-+
-+	vncipher	$out1,$out1,v28
-+	vncipher	$out2,$out2,v28
-+	vncipher	$out3,$out3,v28
-+	vncipher	$out4,$out4,v28
-+	vncipher	$out5,$out5,v28
-+	vncipher	$out6,$out6,v28
-+	vncipher	$out7,$out7,v28
-+
-+	vncipher	$out1,$out1,v29
-+	vncipher	$out2,$out2,v29
-+	vncipher	$out3,$out3,v29
-+	vncipher	$out4,$out4,v29
-+	vncipher	$out5,$out5,v29
-+	vncipher	$out6,$out6,v29
-+	vncipher	$out7,$out7,v29
-+
-+	vncipher	$out1,$out1,v30
-+	 vxor		$ivec,$ivec,v31		# last round key
-+	vncipher	$out2,$out2,v30
-+	 vxor		$in1,$in1,v31
-+	vncipher	$out3,$out3,v30
-+	 vxor		$in2,$in2,v31
-+	vncipher	$out4,$out4,v30
-+	 vxor		$in3,$in3,v31
-+	vncipher	$out5,$out5,v30
-+	 vxor		$in4,$in4,v31
-+	vncipher	$out6,$out6,v30
-+	 vxor		$in5,$in5,v31
-+	vncipher	$out7,$out7,v30
-+	 vxor		$in6,$in6,v31
-+
-+	cmplwi		$len,32			# switch($len)
-+	blt		Lcbc_dec8x_one
-+	nop
-+	beq		Lcbc_dec8x_two
-+	cmplwi		$len,64
-+	blt		Lcbc_dec8x_three
-+	nop
-+	beq		Lcbc_dec8x_four
-+	cmplwi		$len,96
-+	blt		Lcbc_dec8x_five
-+	nop
-+	beq		Lcbc_dec8x_six
-+
-+Lcbc_dec8x_seven:
-+	vncipherlast	$out1,$out1,$ivec
-+	vncipherlast	$out2,$out2,$in1
-+	vncipherlast	$out3,$out3,$in2
-+	vncipherlast	$out4,$out4,$in3
-+	vncipherlast	$out5,$out5,$in4
-+	vncipherlast	$out6,$out6,$in5
-+	vncipherlast	$out7,$out7,$in6
-+	vmr		$ivec,$in7
-+
-+	le?vperm	$out1,$out1,$out1,$inpperm
-+	le?vperm	$out2,$out2,$out2,$inpperm
-+	stvx_u		$out1,$x00,$out
-+	le?vperm	$out3,$out3,$out3,$inpperm
-+	stvx_u		$out2,$x10,$out
-+	le?vperm	$out4,$out4,$out4,$inpperm
-+	stvx_u		$out3,$x20,$out
-+	le?vperm	$out5,$out5,$out5,$inpperm
-+	stvx_u		$out4,$x30,$out
-+	le?vperm	$out6,$out6,$out6,$inpperm
-+	stvx_u		$out5,$x40,$out
-+	le?vperm	$out7,$out7,$out7,$inpperm
-+	stvx_u		$out6,$x50,$out
-+	stvx_u		$out7,$x60,$out
-+	addi		$out,$out,0x70
-+	b		Lcbc_dec8x_done
-+
-+.align	5
-+Lcbc_dec8x_six:
-+	vncipherlast	$out2,$out2,$ivec
-+	vncipherlast	$out3,$out3,$in2
-+	vncipherlast	$out4,$out4,$in3
-+	vncipherlast	$out5,$out5,$in4
-+	vncipherlast	$out6,$out6,$in5
-+	vncipherlast	$out7,$out7,$in6
-+	vmr		$ivec,$in7
-+
-+	le?vperm	$out2,$out2,$out2,$inpperm
-+	le?vperm	$out3,$out3,$out3,$inpperm
-+	stvx_u		$out2,$x00,$out
-+	le?vperm	$out4,$out4,$out4,$inpperm
-+	stvx_u		$out3,$x10,$out
-+	le?vperm	$out5,$out5,$out5,$inpperm
-+	stvx_u		$out4,$x20,$out
-+	le?vperm	$out6,$out6,$out6,$inpperm
-+	stvx_u		$out5,$x30,$out
-+	le?vperm	$out7,$out7,$out7,$inpperm
-+	stvx_u		$out6,$x40,$out
-+	stvx_u		$out7,$x50,$out
-+	addi		$out,$out,0x60
-+	b		Lcbc_dec8x_done
-+
-+.align	5
-+Lcbc_dec8x_five:
-+	vncipherlast	$out3,$out3,$ivec
-+	vncipherlast	$out4,$out4,$in3
-+	vncipherlast	$out5,$out5,$in4
-+	vncipherlast	$out6,$out6,$in5
-+	vncipherlast	$out7,$out7,$in6
-+	vmr		$ivec,$in7
-+
-+	le?vperm	$out3,$out3,$out3,$inpperm
-+	le?vperm	$out4,$out4,$out4,$inpperm
-+	stvx_u		$out3,$x00,$out
-+	le?vperm	$out5,$out5,$out5,$inpperm
-+	stvx_u		$out4,$x10,$out
-+	le?vperm	$out6,$out6,$out6,$inpperm
-+	stvx_u		$out5,$x20,$out
-+	le?vperm	$out7,$out7,$out7,$inpperm
-+	stvx_u		$out6,$x30,$out
-+	stvx_u		$out7,$x40,$out
-+	addi		$out,$out,0x50
-+	b		Lcbc_dec8x_done
-+
-+.align	5
-+Lcbc_dec8x_four:
-+	vncipherlast	$out4,$out4,$ivec
-+	vncipherlast	$out5,$out5,$in4
-+	vncipherlast	$out6,$out6,$in5
-+	vncipherlast	$out7,$out7,$in6
-+	vmr		$ivec,$in7
-+
-+	le?vperm	$out4,$out4,$out4,$inpperm
-+	le?vperm	$out5,$out5,$out5,$inpperm
-+	stvx_u		$out4,$x00,$out
-+	le?vperm	$out6,$out6,$out6,$inpperm
-+	stvx_u		$out5,$x10,$out
-+	le?vperm	$out7,$out7,$out7,$inpperm
-+	stvx_u		$out6,$x20,$out
-+	stvx_u		$out7,$x30,$out
-+	addi		$out,$out,0x40
-+	b		Lcbc_dec8x_done
-+
-+.align	5
-+Lcbc_dec8x_three:
-+	vncipherlast	$out5,$out5,$ivec
-+	vncipherlast	$out6,$out6,$in5
-+	vncipherlast	$out7,$out7,$in6
-+	vmr		$ivec,$in7
-+
-+	le?vperm	$out5,$out5,$out5,$inpperm
-+	le?vperm	$out6,$out6,$out6,$inpperm
-+	stvx_u		$out5,$x00,$out
-+	le?vperm	$out7,$out7,$out7,$inpperm
-+	stvx_u		$out6,$x10,$out
-+	stvx_u		$out7,$x20,$out
-+	addi		$out,$out,0x30
-+	b		Lcbc_dec8x_done
-+
-+.align	5
-+Lcbc_dec8x_two:
-+	vncipherlast	$out6,$out6,$ivec
-+	vncipherlast	$out7,$out7,$in6
-+	vmr		$ivec,$in7
-+
-+	le?vperm	$out6,$out6,$out6,$inpperm
-+	le?vperm	$out7,$out7,$out7,$inpperm
-+	stvx_u		$out6,$x00,$out
-+	stvx_u		$out7,$x10,$out
-+	addi		$out,$out,0x20
-+	b		Lcbc_dec8x_done
-+
-+.align	5
-+Lcbc_dec8x_one:
-+	vncipherlast	$out7,$out7,$ivec
-+	vmr		$ivec,$in7
-+
-+	le?vperm	$out7,$out7,$out7,$inpperm
-+	stvx_u		$out7,0,$out
-+	addi		$out,$out,0x10
-+
-+Lcbc_dec8x_done:
-+	le?vperm	$ivec,$ivec,$ivec,$inpperm
-+	stvx_u		$ivec,0,$ivp		# write [unaligned] iv
-+
-+	li		r10,`$FRAME+15`
-+	li		r11,`$FRAME+31`
-+	stvx		$inpperm,r10,$sp	# wipe copies of round keys
-+	addi		r10,r10,32
-+	stvx		$inpperm,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$inpperm,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$inpperm,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$inpperm,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$inpperm,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$inpperm,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$inpperm,r11,$sp
-+	addi		r11,r11,32
-+
-+	mtspr		256,$vrsave
-+	lvx		v20,r10,$sp		# ABI says so
-+	addi		r10,r10,32
-+	lvx		v21,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v22,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v23,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v24,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v25,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v26,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v27,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v28,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v29,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v30,r10,$sp
-+	lvx		v31,r11,$sp
-+	$POP		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
-+	$POP		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
-+	$POP		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
-+	$POP		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
-+	$POP		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
-+	$POP		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
-+	addi		$sp,$sp,`$FRAME+21*16+6*$SIZE_T`
-+	blr
-+	.long		0
-+	.byte		0,12,0x04,0,0x80,6,6,0
-+	.long		0
-+.size	.${prefix}_cbc_encrypt,.-.${prefix}_cbc_encrypt
-+___
-+}}	}}}
-+
-+#########################################################################
-+{{{	# CTR procedure[s]						#
-+my ($inp,$out,$len,$key,$ivp,$x10,$rounds,$idx)=map("r$_",(3..10));
-+my ($rndkey0,$rndkey1,$inout,$tmp)=		map("v$_",(0..3));
-+my ($ivec,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm,$one)=
-+						map("v$_",(4..11));
-+my $dat=$tmp;
-+
-+$code.=<<___;
-+.globl	.${prefix}_ctr32_encrypt_blocks
-+.align	5
-+.${prefix}_ctr32_encrypt_blocks:
-+	${UCMP}i	$len,1
-+	bltlr-
-+
-+	lis		r0,0xfff0
-+	mfspr		$vrsave,256
-+	mtspr		256,r0
-+
-+	li		$idx,15
-+	vxor		$rndkey0,$rndkey0,$rndkey0
-+	le?vspltisb	$tmp,0x0f
-+
-+	lvx		$ivec,0,$ivp		# load [unaligned] iv
-+	lvsl		$inpperm,0,$ivp
-+	lvx		$inptail,$idx,$ivp
-+	 vspltisb	$one,1
-+	le?vxor		$inpperm,$inpperm,$tmp
-+	vperm		$ivec,$ivec,$inptail,$inpperm
-+	 vsldoi		$one,$rndkey0,$one,1
-+
-+	neg		r11,$inp
-+	?lvsl		$keyperm,0,$key		# prepare for unaligned key
-+	lwz		$rounds,240($key)
-+
-+	lvsr		$inpperm,0,r11		# prepare for unaligned load
-+	lvx		$inptail,0,$inp
-+	addi		$inp,$inp,15		# 15 is not typo
-+	le?vxor		$inpperm,$inpperm,$tmp
-+
-+	srwi		$rounds,$rounds,1
-+	li		$idx,16
-+	subi		$rounds,$rounds,1
-+
-+	${UCMP}i	$len,8
-+	bge		_aesp8_ctr32_encrypt8x
-+
-+	?lvsr		$outperm,0,$out		# prepare for unaligned store
-+	vspltisb	$outmask,-1
-+	lvx		$outhead,0,$out
-+	?vperm		$outmask,$rndkey0,$outmask,$outperm
-+	le?vxor		$outperm,$outperm,$tmp
-+
-+	lvx		$rndkey0,0,$key
-+	mtctr		$rounds
-+	lvx		$rndkey1,$idx,$key
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$inout,$ivec,$rndkey0
-+	lvx		$rndkey0,$idx,$key
-+	addi		$idx,$idx,16
-+	b		Loop_ctr32_enc
-+
-+.align	5
-+Loop_ctr32_enc:
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vcipher		$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vcipher		$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key
-+	addi		$idx,$idx,16
-+	bdnz		Loop_ctr32_enc
-+
-+	vadduwm		$ivec,$ivec,$one
-+	 vmr		$dat,$inptail
-+	 lvx		$inptail,0,$inp
-+	 addi		$inp,$inp,16
-+	 subic.		$len,$len,1		# blocks--
-+
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vcipher		$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key
-+	 vperm		$dat,$dat,$inptail,$inpperm
-+	 li		$idx,16
-+	?vperm		$rndkey1,$rndkey0,$rndkey1,$keyperm
-+	 lvx		$rndkey0,0,$key
-+	vxor		$dat,$dat,$rndkey1	# last round key
-+	vcipherlast	$inout,$inout,$dat
-+
-+	 lvx		$rndkey1,$idx,$key
-+	 addi		$idx,$idx,16
-+	vperm		$inout,$inout,$inout,$outperm
-+	vsel		$dat,$outhead,$inout,$outmask
-+	 mtctr		$rounds
-+	 ?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vmr		$outhead,$inout
-+	 vxor		$inout,$ivec,$rndkey0
-+	 lvx		$rndkey0,$idx,$key
-+	 addi		$idx,$idx,16
-+	stvx		$dat,0,$out
-+	addi		$out,$out,16
-+	bne		Loop_ctr32_enc
-+
-+	addi		$out,$out,-1
-+	lvx		$inout,0,$out		# redundant in aligned case
-+	vsel		$inout,$outhead,$inout,$outmask
-+	stvx		$inout,0,$out
-+
-+	mtspr		256,$vrsave
-+	blr
-+	.long		0
-+	.byte		0,12,0x14,0,0,0,6,0
-+	.long		0
-+___
-+#########################################################################
-+{{	# Optimized CTR procedure					#
-+my $key_="r11";
-+my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,8,26..31));
-+    $x00=0 if ($flavour =~ /osx/);
-+my ($in0, $in1, $in2, $in3, $in4, $in5, $in6, $in7 )=map("v$_",(0..3,10,12..14));
-+my ($out0,$out1,$out2,$out3,$out4,$out5,$out6,$out7)=map("v$_",(15..22));
-+my $rndkey0="v23";	# v24-v25 rotating buffer for first found keys
-+			# v26-v31 last 6 round keys
-+my ($tmp,$keyperm)=($in3,$in4);	# aliases with "caller", redundant assignment
-+my ($two,$three,$four)=($outhead,$outperm,$outmask);
-+
-+$code.=<<___;
-+.align	5
-+_aesp8_ctr32_encrypt8x:
-+	$STU		$sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
-+	li		r10,`$FRAME+8*16+15`
-+	li		r11,`$FRAME+8*16+31`
-+	stvx		v20,r10,$sp		# ABI says so
-+	addi		r10,r10,32
-+	stvx		v21,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v22,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v23,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v24,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v25,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v26,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v27,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v28,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v29,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v30,r10,$sp
-+	stvx		v31,r11,$sp
-+	li		r0,-1
-+	stw		$vrsave,`$FRAME+21*16-4`($sp)	# save vrsave
-+	li		$x10,0x10
-+	$PUSH		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
-+	li		$x20,0x20
-+	$PUSH		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
-+	li		$x30,0x30
-+	$PUSH		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
-+	li		$x40,0x40
-+	$PUSH		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
-+	li		$x50,0x50
-+	$PUSH		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
-+	li		$x60,0x60
-+	$PUSH		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
-+	li		$x70,0x70
-+	mtspr		256,r0
-+
-+	subi		$rounds,$rounds,3	# -4 in total
-+
-+	lvx		$rndkey0,$x00,$key	# load key schedule
-+	lvx		v30,$x10,$key
-+	addi		$key,$key,0x20
-+	lvx		v31,$x00,$key
-+	?vperm		$rndkey0,$rndkey0,v30,$keyperm
-+	addi		$key_,$sp,$FRAME+15
-+	mtctr		$rounds
-+
-+Load_ctr32_enc_key:
-+	?vperm		v24,v30,v31,$keyperm
-+	lvx		v30,$x10,$key
-+	addi		$key,$key,0x20
-+	stvx		v24,$x00,$key_		# off-load round[1]
-+	?vperm		v25,v31,v30,$keyperm
-+	lvx		v31,$x00,$key
-+	stvx		v25,$x10,$key_		# off-load round[2]
-+	addi		$key_,$key_,0x20
-+	bdnz		Load_ctr32_enc_key
-+
-+	lvx		v26,$x10,$key
-+	?vperm		v24,v30,v31,$keyperm
-+	lvx		v27,$x20,$key
-+	stvx		v24,$x00,$key_		# off-load round[3]
-+	?vperm		v25,v31,v26,$keyperm
-+	lvx		v28,$x30,$key
-+	stvx		v25,$x10,$key_		# off-load round[4]
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	?vperm		v26,v26,v27,$keyperm
-+	lvx		v29,$x40,$key
-+	?vperm		v27,v27,v28,$keyperm
-+	lvx		v30,$x50,$key
-+	?vperm		v28,v28,v29,$keyperm
-+	lvx		v31,$x60,$key
-+	?vperm		v29,v29,v30,$keyperm
-+	lvx		$out0,$x70,$key		# borrow $out0
-+	?vperm		v30,v30,v31,$keyperm
-+	lvx		v24,$x00,$key_		# pre-load round[1]
-+	?vperm		v31,v31,$out0,$keyperm
-+	lvx		v25,$x10,$key_		# pre-load round[2]
-+
-+	vadduwm		$two,$one,$one
-+	subi		$inp,$inp,15		# undo "caller"
-+	$SHL		$len,$len,4
-+
-+	vadduwm		$out1,$ivec,$one	# counter values ...
-+	vadduwm		$out2,$ivec,$two
-+	vxor		$out0,$ivec,$rndkey0	# ... xored with rndkey[0]
-+	 le?li		$idx,8
-+	vadduwm		$out3,$out1,$two
-+	vxor		$out1,$out1,$rndkey0
-+	 le?lvsl	$inpperm,0,$idx
-+	vadduwm		$out4,$out2,$two
-+	vxor		$out2,$out2,$rndkey0
-+	 le?vspltisb	$tmp,0x0f
-+	vadduwm		$out5,$out3,$two
-+	vxor		$out3,$out3,$rndkey0
-+	 le?vxor	$inpperm,$inpperm,$tmp	# transform for lvx_u/stvx_u
-+	vadduwm		$out6,$out4,$two
-+	vxor		$out4,$out4,$rndkey0
-+	vadduwm		$out7,$out5,$two
-+	vxor		$out5,$out5,$rndkey0
-+	vadduwm		$ivec,$out6,$two	# next counter value
-+	vxor		$out6,$out6,$rndkey0
-+	vxor		$out7,$out7,$rndkey0
-+
-+	mtctr		$rounds
-+	b		Loop_ctr32_enc8x
-+.align	5
-+Loop_ctr32_enc8x:
-+	vcipher 	$out0,$out0,v24
-+	vcipher 	$out1,$out1,v24
-+	vcipher 	$out2,$out2,v24
-+	vcipher 	$out3,$out3,v24
-+	vcipher 	$out4,$out4,v24
-+	vcipher 	$out5,$out5,v24
-+	vcipher 	$out6,$out6,v24
-+	vcipher 	$out7,$out7,v24
-+Loop_ctr32_enc8x_middle:
-+	lvx		v24,$x20,$key_		# round[3]
-+	addi		$key_,$key_,0x20
-+
-+	vcipher 	$out0,$out0,v25
-+	vcipher 	$out1,$out1,v25
-+	vcipher 	$out2,$out2,v25
-+	vcipher 	$out3,$out3,v25
-+	vcipher 	$out4,$out4,v25
-+	vcipher 	$out5,$out5,v25
-+	vcipher 	$out6,$out6,v25
-+	vcipher 	$out7,$out7,v25
-+	lvx		v25,$x10,$key_		# round[4]
-+	bdnz		Loop_ctr32_enc8x
-+
-+	subic		r11,$len,256		# $len-256, borrow $key_
-+	vcipher 	$out0,$out0,v24
-+	vcipher 	$out1,$out1,v24
-+	vcipher 	$out2,$out2,v24
-+	vcipher 	$out3,$out3,v24
-+	vcipher 	$out4,$out4,v24
-+	vcipher 	$out5,$out5,v24
-+	vcipher 	$out6,$out6,v24
-+	vcipher 	$out7,$out7,v24
-+
-+	subfe		r0,r0,r0		# borrow?-1:0
-+	vcipher 	$out0,$out0,v25
-+	vcipher 	$out1,$out1,v25
-+	vcipher 	$out2,$out2,v25
-+	vcipher 	$out3,$out3,v25
-+	vcipher 	$out4,$out4,v25
-+	vcipher		$out5,$out5,v25
-+	vcipher		$out6,$out6,v25
-+	vcipher		$out7,$out7,v25
-+
-+	and		r0,r0,r11
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	vcipher		$out0,$out0,v26
-+	vcipher		$out1,$out1,v26
-+	vcipher		$out2,$out2,v26
-+	vcipher		$out3,$out3,v26
-+	vcipher		$out4,$out4,v26
-+	vcipher		$out5,$out5,v26
-+	vcipher		$out6,$out6,v26
-+	vcipher		$out7,$out7,v26
-+	lvx		v24,$x00,$key_		# re-pre-load round[1]
-+
-+	subic		$len,$len,129		# $len-=129
-+	vcipher		$out0,$out0,v27
-+	addi		$len,$len,1		# $len-=128 really
-+	vcipher		$out1,$out1,v27
-+	vcipher		$out2,$out2,v27
-+	vcipher		$out3,$out3,v27
-+	vcipher		$out4,$out4,v27
-+	vcipher		$out5,$out5,v27
-+	vcipher		$out6,$out6,v27
-+	vcipher		$out7,$out7,v27
-+	lvx		v25,$x10,$key_		# re-pre-load round[2]
-+
-+	vcipher		$out0,$out0,v28
-+	 lvx_u		$in0,$x00,$inp		# load input
-+	vcipher		$out1,$out1,v28
-+	 lvx_u		$in1,$x10,$inp
-+	vcipher		$out2,$out2,v28
-+	 lvx_u		$in2,$x20,$inp
-+	vcipher		$out3,$out3,v28
-+	 lvx_u		$in3,$x30,$inp
-+	vcipher		$out4,$out4,v28
-+	 lvx_u		$in4,$x40,$inp
-+	vcipher		$out5,$out5,v28
-+	 lvx_u		$in5,$x50,$inp
-+	vcipher		$out6,$out6,v28
-+	 lvx_u		$in6,$x60,$inp
-+	vcipher		$out7,$out7,v28
-+	 lvx_u		$in7,$x70,$inp
-+	 addi		$inp,$inp,0x80
-+
-+	vcipher		$out0,$out0,v29
-+	 le?vperm	$in0,$in0,$in0,$inpperm
-+	vcipher		$out1,$out1,v29
-+	 le?vperm	$in1,$in1,$in1,$inpperm
-+	vcipher		$out2,$out2,v29
-+	 le?vperm	$in2,$in2,$in2,$inpperm
-+	vcipher		$out3,$out3,v29
-+	 le?vperm	$in3,$in3,$in3,$inpperm
-+	vcipher		$out4,$out4,v29
-+	 le?vperm	$in4,$in4,$in4,$inpperm
-+	vcipher		$out5,$out5,v29
-+	 le?vperm	$in5,$in5,$in5,$inpperm
-+	vcipher		$out6,$out6,v29
-+	 le?vperm	$in6,$in6,$in6,$inpperm
-+	vcipher		$out7,$out7,v29
-+	 le?vperm	$in7,$in7,$in7,$inpperm
-+
-+	add		$inp,$inp,r0		# $inp is adjusted in such
-+						# way that at exit from the
-+						# loop inX-in7 are loaded
-+						# with last "words"
-+	subfe.		r0,r0,r0		# borrow?-1:0
-+	vcipher		$out0,$out0,v30
-+	 vxor		$in0,$in0,v31		# xor with last round key
-+	vcipher		$out1,$out1,v30
-+	 vxor		$in1,$in1,v31
-+	vcipher		$out2,$out2,v30
-+	 vxor		$in2,$in2,v31
-+	vcipher		$out3,$out3,v30
-+	 vxor		$in3,$in3,v31
-+	vcipher		$out4,$out4,v30
-+	 vxor		$in4,$in4,v31
-+	vcipher		$out5,$out5,v30
-+	 vxor		$in5,$in5,v31
-+	vcipher		$out6,$out6,v30
-+	 vxor		$in6,$in6,v31
-+	vcipher		$out7,$out7,v30
-+	 vxor		$in7,$in7,v31
-+
-+	bne		Lctr32_enc8x_break	# did $len-129 borrow?
-+
-+	vcipherlast	$in0,$out0,$in0
-+	vcipherlast	$in1,$out1,$in1
-+	 vadduwm	$out1,$ivec,$one	# counter values ...
-+	vcipherlast	$in2,$out2,$in2
-+	 vadduwm	$out2,$ivec,$two
-+	 vxor		$out0,$ivec,$rndkey0	# ... xored with rndkey[0]
-+	vcipherlast	$in3,$out3,$in3
-+	 vadduwm	$out3,$out1,$two
-+	 vxor		$out1,$out1,$rndkey0
-+	vcipherlast	$in4,$out4,$in4
-+	 vadduwm	$out4,$out2,$two
-+	 vxor		$out2,$out2,$rndkey0
-+	vcipherlast	$in5,$out5,$in5
-+	 vadduwm	$out5,$out3,$two
-+	 vxor		$out3,$out3,$rndkey0
-+	vcipherlast	$in6,$out6,$in6
-+	 vadduwm	$out6,$out4,$two
-+	 vxor		$out4,$out4,$rndkey0
-+	vcipherlast	$in7,$out7,$in7
-+	 vadduwm	$out7,$out5,$two
-+	 vxor		$out5,$out5,$rndkey0
-+	le?vperm	$in0,$in0,$in0,$inpperm
-+	 vadduwm	$ivec,$out6,$two	# next counter value
-+	 vxor		$out6,$out6,$rndkey0
-+	le?vperm	$in1,$in1,$in1,$inpperm
-+	 vxor		$out7,$out7,$rndkey0
-+	mtctr		$rounds
-+
-+	 vcipher	$out0,$out0,v24
-+	stvx_u		$in0,$x00,$out
-+	le?vperm	$in2,$in2,$in2,$inpperm
-+	 vcipher	$out1,$out1,v24
-+	stvx_u		$in1,$x10,$out
-+	le?vperm	$in3,$in3,$in3,$inpperm
-+	 vcipher	$out2,$out2,v24
-+	stvx_u		$in2,$x20,$out
-+	le?vperm	$in4,$in4,$in4,$inpperm
-+	 vcipher	$out3,$out3,v24
-+	stvx_u		$in3,$x30,$out
-+	le?vperm	$in5,$in5,$in5,$inpperm
-+	 vcipher	$out4,$out4,v24
-+	stvx_u		$in4,$x40,$out
-+	le?vperm	$in6,$in6,$in6,$inpperm
-+	 vcipher	$out5,$out5,v24
-+	stvx_u		$in5,$x50,$out
-+	le?vperm	$in7,$in7,$in7,$inpperm
-+	 vcipher	$out6,$out6,v24
-+	stvx_u		$in6,$x60,$out
-+	 vcipher	$out7,$out7,v24
-+	stvx_u		$in7,$x70,$out
-+	addi		$out,$out,0x80
-+
-+	b		Loop_ctr32_enc8x_middle
-+
-+.align	5
-+Lctr32_enc8x_break:
-+	cmpwi		$len,-0x60
-+	blt		Lctr32_enc8x_one
-+	nop
-+	beq		Lctr32_enc8x_two
-+	cmpwi		$len,-0x40
-+	blt		Lctr32_enc8x_three
-+	nop
-+	beq		Lctr32_enc8x_four
-+	cmpwi		$len,-0x20
-+	blt		Lctr32_enc8x_five
-+	nop
-+	beq		Lctr32_enc8x_six
-+	cmpwi		$len,0x00
-+	blt		Lctr32_enc8x_seven
-+
-+Lctr32_enc8x_eight:
-+	vcipherlast	$out0,$out0,$in0
-+	vcipherlast	$out1,$out1,$in1
-+	vcipherlast	$out2,$out2,$in2
-+	vcipherlast	$out3,$out3,$in3
-+	vcipherlast	$out4,$out4,$in4
-+	vcipherlast	$out5,$out5,$in5
-+	vcipherlast	$out6,$out6,$in6
-+	vcipherlast	$out7,$out7,$in7
-+
-+	le?vperm	$out0,$out0,$out0,$inpperm
-+	le?vperm	$out1,$out1,$out1,$inpperm
-+	stvx_u		$out0,$x00,$out
-+	le?vperm	$out2,$out2,$out2,$inpperm
-+	stvx_u		$out1,$x10,$out
-+	le?vperm	$out3,$out3,$out3,$inpperm
-+	stvx_u		$out2,$x20,$out
-+	le?vperm	$out4,$out4,$out4,$inpperm
-+	stvx_u		$out3,$x30,$out
-+	le?vperm	$out5,$out5,$out5,$inpperm
-+	stvx_u		$out4,$x40,$out
-+	le?vperm	$out6,$out6,$out6,$inpperm
-+	stvx_u		$out5,$x50,$out
-+	le?vperm	$out7,$out7,$out7,$inpperm
-+	stvx_u		$out6,$x60,$out
-+	stvx_u		$out7,$x70,$out
-+	addi		$out,$out,0x80
-+	b		Lctr32_enc8x_done
-+
-+.align	5
-+Lctr32_enc8x_seven:
-+	vcipherlast	$out0,$out0,$in1
-+	vcipherlast	$out1,$out1,$in2
-+	vcipherlast	$out2,$out2,$in3
-+	vcipherlast	$out3,$out3,$in4
-+	vcipherlast	$out4,$out4,$in5
-+	vcipherlast	$out5,$out5,$in6
-+	vcipherlast	$out6,$out6,$in7
-+
-+	le?vperm	$out0,$out0,$out0,$inpperm
-+	le?vperm	$out1,$out1,$out1,$inpperm
-+	stvx_u		$out0,$x00,$out
-+	le?vperm	$out2,$out2,$out2,$inpperm
-+	stvx_u		$out1,$x10,$out
-+	le?vperm	$out3,$out3,$out3,$inpperm
-+	stvx_u		$out2,$x20,$out
-+	le?vperm	$out4,$out4,$out4,$inpperm
-+	stvx_u		$out3,$x30,$out
-+	le?vperm	$out5,$out5,$out5,$inpperm
-+	stvx_u		$out4,$x40,$out
-+	le?vperm	$out6,$out6,$out6,$inpperm
-+	stvx_u		$out5,$x50,$out
-+	stvx_u		$out6,$x60,$out
-+	addi		$out,$out,0x70
-+	b		Lctr32_enc8x_done
-+
-+.align	5
-+Lctr32_enc8x_six:
-+	vcipherlast	$out0,$out0,$in2
-+	vcipherlast	$out1,$out1,$in3
-+	vcipherlast	$out2,$out2,$in4
-+	vcipherlast	$out3,$out3,$in5
-+	vcipherlast	$out4,$out4,$in6
-+	vcipherlast	$out5,$out5,$in7
-+
-+	le?vperm	$out0,$out0,$out0,$inpperm
-+	le?vperm	$out1,$out1,$out1,$inpperm
-+	stvx_u		$out0,$x00,$out
-+	le?vperm	$out2,$out2,$out2,$inpperm
-+	stvx_u		$out1,$x10,$out
-+	le?vperm	$out3,$out3,$out3,$inpperm
-+	stvx_u		$out2,$x20,$out
-+	le?vperm	$out4,$out4,$out4,$inpperm
-+	stvx_u		$out3,$x30,$out
-+	le?vperm	$out5,$out5,$out5,$inpperm
-+	stvx_u		$out4,$x40,$out
-+	stvx_u		$out5,$x50,$out
-+	addi		$out,$out,0x60
-+	b		Lctr32_enc8x_done
-+
-+.align	5
-+Lctr32_enc8x_five:
-+	vcipherlast	$out0,$out0,$in3
-+	vcipherlast	$out1,$out1,$in4
-+	vcipherlast	$out2,$out2,$in5
-+	vcipherlast	$out3,$out3,$in6
-+	vcipherlast	$out4,$out4,$in7
-+
-+	le?vperm	$out0,$out0,$out0,$inpperm
-+	le?vperm	$out1,$out1,$out1,$inpperm
-+	stvx_u		$out0,$x00,$out
-+	le?vperm	$out2,$out2,$out2,$inpperm
-+	stvx_u		$out1,$x10,$out
-+	le?vperm	$out3,$out3,$out3,$inpperm
-+	stvx_u		$out2,$x20,$out
-+	le?vperm	$out4,$out4,$out4,$inpperm
-+	stvx_u		$out3,$x30,$out
-+	stvx_u		$out4,$x40,$out
-+	addi		$out,$out,0x50
-+	b		Lctr32_enc8x_done
-+
-+.align	5
-+Lctr32_enc8x_four:
-+	vcipherlast	$out0,$out0,$in4
-+	vcipherlast	$out1,$out1,$in5
-+	vcipherlast	$out2,$out2,$in6
-+	vcipherlast	$out3,$out3,$in7
-+
-+	le?vperm	$out0,$out0,$out0,$inpperm
-+	le?vperm	$out1,$out1,$out1,$inpperm
-+	stvx_u		$out0,$x00,$out
-+	le?vperm	$out2,$out2,$out2,$inpperm
-+	stvx_u		$out1,$x10,$out
-+	le?vperm	$out3,$out3,$out3,$inpperm
-+	stvx_u		$out2,$x20,$out
-+	stvx_u		$out3,$x30,$out
-+	addi		$out,$out,0x40
-+	b		Lctr32_enc8x_done
-+
-+.align	5
-+Lctr32_enc8x_three:
-+	vcipherlast	$out0,$out0,$in5
-+	vcipherlast	$out1,$out1,$in6
-+	vcipherlast	$out2,$out2,$in7
-+
-+	le?vperm	$out0,$out0,$out0,$inpperm
-+	le?vperm	$out1,$out1,$out1,$inpperm
-+	stvx_u		$out0,$x00,$out
-+	le?vperm	$out2,$out2,$out2,$inpperm
-+	stvx_u		$out1,$x10,$out
-+	stvx_u		$out2,$x20,$out
-+	addi		$out,$out,0x30
-+	b		Lcbc_dec8x_done
-+
-+.align	5
-+Lctr32_enc8x_two:
-+	vcipherlast	$out0,$out0,$in6
-+	vcipherlast	$out1,$out1,$in7
-+
-+	le?vperm	$out0,$out0,$out0,$inpperm
-+	le?vperm	$out1,$out1,$out1,$inpperm
-+	stvx_u		$out0,$x00,$out
-+	stvx_u		$out1,$x10,$out
-+	addi		$out,$out,0x20
-+	b		Lcbc_dec8x_done
-+
-+.align	5
-+Lctr32_enc8x_one:
-+	vcipherlast	$out0,$out0,$in7
-+
-+	le?vperm	$out0,$out0,$out0,$inpperm
-+	stvx_u		$out0,0,$out
-+	addi		$out,$out,0x10
-+
-+Lctr32_enc8x_done:
-+	li		r10,`$FRAME+15`
-+	li		r11,`$FRAME+31`
-+	stvx		$inpperm,r10,$sp	# wipe copies of round keys
-+	addi		r10,r10,32
-+	stvx		$inpperm,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$inpperm,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$inpperm,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$inpperm,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$inpperm,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$inpperm,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$inpperm,r11,$sp
-+	addi		r11,r11,32
-+
-+	mtspr		256,$vrsave
-+	lvx		v20,r10,$sp		# ABI says so
-+	addi		r10,r10,32
-+	lvx		v21,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v22,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v23,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v24,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v25,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v26,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v27,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v28,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v29,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v30,r10,$sp
-+	lvx		v31,r11,$sp
-+	$POP		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
-+	$POP		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
-+	$POP		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
-+	$POP		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
-+	$POP		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
-+	$POP		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
-+	addi		$sp,$sp,`$FRAME+21*16+6*$SIZE_T`
-+	blr
-+	.long		0
-+	.byte		0,12,0x04,0,0x80,6,6,0
-+	.long		0
-+.size	.${prefix}_ctr32_encrypt_blocks,.-.${prefix}_ctr32_encrypt_blocks
-+___
-+}}	}}}
-+
-+#########################################################################
-+{{{	# XTS procedures						#
-+# int aes_p8_xts_[en|de]crypt(const char *inp, char *out, size_t len,	#
-+#                             const AES_KEY *key1, const AES_KEY *key2,	#
-+#                             [const] unsigned char iv[16]);		#
-+# If $key2 is NULL, then a "tweak chaining" mode is engaged, in which	#
-+# input tweak value is assumed to be encrypted already, and last tweak	#
-+# value, one suitable for consecutive call on same chunk of data, is	#
-+# written back to original buffer. In addition, in "tweak chaining"	#
-+# mode only complete input blocks are processed.			#
-+
-+my ($inp,$out,$len,$key1,$key2,$ivp,$rounds,$idx) =	map("r$_",(3..10));
-+my ($rndkey0,$rndkey1,$inout) =				map("v$_",(0..2));
-+my ($output,$inptail,$inpperm,$leperm,$keyperm) =	map("v$_",(3..7));
-+my ($tweak,$seven,$eighty7,$tmp,$tweak1) =		map("v$_",(8..12));
-+my $taillen = $key2;
-+
-+   ($inp,$idx) = ($idx,$inp);				# reassign
-+
-+$code.=<<___;
-+.globl	.${prefix}_xts_encrypt
-+.align	5
-+.${prefix}_xts_encrypt:
-+	mr		$inp,r3				# reassign
-+	li		r3,-1
-+	${UCMP}i	$len,16
-+	bltlr-
-+
-+	lis		r0,0xfff0
-+	mfspr		r12,256				# save vrsave
-+	li		r11,0
-+	mtspr		256,r0
-+
-+	vspltisb	$seven,0x07			# 0x070707..07
-+	le?lvsl		$leperm,r11,r11
-+	le?vspltisb	$tmp,0x0f
-+	le?vxor		$leperm,$leperm,$seven
-+
-+	li		$idx,15
-+	lvx		$tweak,0,$ivp			# load [unaligned] iv
-+	lvsl		$inpperm,0,$ivp
-+	lvx		$inptail,$idx,$ivp
-+	le?vxor		$inpperm,$inpperm,$tmp
-+	vperm		$tweak,$tweak,$inptail,$inpperm
-+
-+	neg		r11,$inp
-+	lvsr		$inpperm,0,r11			# prepare for unaligned load
-+	lvx		$inout,0,$inp
-+	addi		$inp,$inp,15			# 15 is not typo
-+	le?vxor		$inpperm,$inpperm,$tmp
-+
-+	${UCMP}i	$key2,0				# key2==NULL?
-+	beq		Lxts_enc_no_key2
-+
-+	?lvsl		$keyperm,0,$key2		# prepare for unaligned key
-+	lwz		$rounds,240($key2)
-+	srwi		$rounds,$rounds,1
-+	subi		$rounds,$rounds,1
-+	li		$idx,16
-+
-+	lvx		$rndkey0,0,$key2
-+	lvx		$rndkey1,$idx,$key2
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$tweak,$tweak,$rndkey0
-+	lvx		$rndkey0,$idx,$key2
-+	addi		$idx,$idx,16
-+	mtctr		$rounds
-+
-+Ltweak_xts_enc:
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vcipher		$tweak,$tweak,$rndkey1
-+	lvx		$rndkey1,$idx,$key2
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vcipher		$tweak,$tweak,$rndkey0
-+	lvx		$rndkey0,$idx,$key2
-+	addi		$idx,$idx,16
-+	bdnz		Ltweak_xts_enc
-+
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vcipher		$tweak,$tweak,$rndkey1
-+	lvx		$rndkey1,$idx,$key2
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vcipherlast	$tweak,$tweak,$rndkey0
-+
-+	li		$ivp,0				# don't chain the tweak
-+	b		Lxts_enc
-+
-+Lxts_enc_no_key2:
-+	li		$idx,-16
-+	and		$len,$len,$idx			# in "tweak chaining"
-+							# mode only complete
-+							# blocks are processed
-+Lxts_enc:
-+	lvx		$inptail,0,$inp
-+	addi		$inp,$inp,16
-+
-+	?lvsl		$keyperm,0,$key1		# prepare for unaligned key
-+	lwz		$rounds,240($key1)
-+	srwi		$rounds,$rounds,1
-+	subi		$rounds,$rounds,1
-+	li		$idx,16
-+
-+	vslb		$eighty7,$seven,$seven		# 0x808080..80
-+	vor		$eighty7,$eighty7,$seven	# 0x878787..87
-+	vspltisb	$tmp,1				# 0x010101..01
-+	vsldoi		$eighty7,$eighty7,$tmp,15	# 0x870101..01
-+
-+	${UCMP}i	$len,96
-+	bge		_aesp8_xts_encrypt6x
-+
-+	andi.		$taillen,$len,15
-+	subic		r0,$len,32
-+	subi		$taillen,$taillen,16
-+	subfe		r0,r0,r0
-+	and		r0,r0,$taillen
-+	add		$inp,$inp,r0
-+
-+	lvx		$rndkey0,0,$key1
-+	lvx		$rndkey1,$idx,$key1
-+	addi		$idx,$idx,16
-+	vperm		$inout,$inout,$inptail,$inpperm
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$inout,$inout,$tweak
-+	vxor		$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key1
-+	addi		$idx,$idx,16
-+	mtctr		$rounds
-+	b		Loop_xts_enc
-+
-+.align	5
-+Loop_xts_enc:
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vcipher		$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key1
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vcipher		$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key1
-+	addi		$idx,$idx,16
-+	bdnz		Loop_xts_enc
-+
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vcipher		$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key1
-+	li		$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$rndkey0,$rndkey0,$tweak
-+	vcipherlast	$output,$inout,$rndkey0
-+
-+	le?vperm	$tmp,$output,$output,$leperm
-+	be?nop
-+	le?stvx_u	$tmp,0,$out
-+	be?stvx_u	$output,0,$out
-+	addi		$out,$out,16
-+
-+	subic.		$len,$len,16
-+	beq		Lxts_enc_done
-+
-+	vmr		$inout,$inptail
-+	lvx		$inptail,0,$inp
-+	addi		$inp,$inp,16
-+	lvx		$rndkey0,0,$key1
-+	lvx		$rndkey1,$idx,$key1
-+	addi		$idx,$idx,16
-+
-+	subic		r0,$len,32
-+	subfe		r0,r0,r0
-+	and		r0,r0,$taillen
-+	add		$inp,$inp,r0
-+
-+	vsrab		$tmp,$tweak,$seven		# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	vand		$tmp,$tmp,$eighty7
-+	vxor		$tweak,$tweak,$tmp
-+
-+	vperm		$inout,$inout,$inptail,$inpperm
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$inout,$inout,$tweak
-+	vxor		$output,$output,$rndkey0	# just in case $len<16
-+	vxor		$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key1
-+	addi		$idx,$idx,16
-+
-+	mtctr		$rounds
-+	${UCMP}i	$len,16
-+	bge		Loop_xts_enc
-+
-+	vxor		$output,$output,$tweak
-+	lvsr		$inpperm,0,$len			# $inpperm is no longer needed
-+	vxor		$inptail,$inptail,$inptail	# $inptail is no longer needed
-+	vspltisb	$tmp,-1
-+	vperm		$inptail,$inptail,$tmp,$inpperm
-+	vsel		$inout,$inout,$output,$inptail
-+
-+	subi		r11,$out,17
-+	subi		$out,$out,16
-+	mtctr		$len
-+	li		$len,16
-+Loop_xts_enc_steal:
-+	lbzu		r0,1(r11)
-+	stb		r0,16(r11)
-+	bdnz		Loop_xts_enc_steal
-+
-+	mtctr		$rounds
-+	b		Loop_xts_enc			# one more time...
-+
-+Lxts_enc_done:
-+	${UCMP}i	$ivp,0
-+	beq		Lxts_enc_ret
-+
-+	vsrab		$tmp,$tweak,$seven		# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	vand		$tmp,$tmp,$eighty7
-+	vxor		$tweak,$tweak,$tmp
-+
-+	le?vperm	$tweak,$tweak,$tweak,$leperm
-+	stvx_u		$tweak,0,$ivp
-+
-+Lxts_enc_ret:
-+	mtspr		256,r12				# restore vrsave
-+	li		r3,0
-+	blr
-+	.long		0
-+	.byte		0,12,0x04,0,0x80,6,6,0
-+	.long		0
-+.size	.${prefix}_xts_encrypt,.-.${prefix}_xts_encrypt
-+
-+.globl	.${prefix}_xts_decrypt
-+.align	5
-+.${prefix}_xts_decrypt:
-+	mr		$inp,r3				# reassign
-+	li		r3,-1
-+	${UCMP}i	$len,16
-+	bltlr-
-+
-+	lis		r0,0xfff8
-+	mfspr		r12,256				# save vrsave
-+	li		r11,0
-+	mtspr		256,r0
-+
-+	andi.		r0,$len,15
-+	neg		r0,r0
-+	andi.		r0,r0,16
-+	sub		$len,$len,r0
-+
-+	vspltisb	$seven,0x07			# 0x070707..07
-+	le?lvsl		$leperm,r11,r11
-+	le?vspltisb	$tmp,0x0f
-+	le?vxor		$leperm,$leperm,$seven
-+
-+	li		$idx,15
-+	lvx		$tweak,0,$ivp			# load [unaligned] iv
-+	lvsl		$inpperm,0,$ivp
-+	lvx		$inptail,$idx,$ivp
-+	le?vxor		$inpperm,$inpperm,$tmp
-+	vperm		$tweak,$tweak,$inptail,$inpperm
-+
-+	neg		r11,$inp
-+	lvsr		$inpperm,0,r11			# prepare for unaligned load
-+	lvx		$inout,0,$inp
-+	addi		$inp,$inp,15			# 15 is not typo
-+	le?vxor		$inpperm,$inpperm,$tmp
-+
-+	${UCMP}i	$key2,0				# key2==NULL?
-+	beq		Lxts_dec_no_key2
-+
-+	?lvsl		$keyperm,0,$key2		# prepare for unaligned key
-+	lwz		$rounds,240($key2)
-+	srwi		$rounds,$rounds,1
-+	subi		$rounds,$rounds,1
-+	li		$idx,16
-+
-+	lvx		$rndkey0,0,$key2
-+	lvx		$rndkey1,$idx,$key2
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$tweak,$tweak,$rndkey0
-+	lvx		$rndkey0,$idx,$key2
-+	addi		$idx,$idx,16
-+	mtctr		$rounds
-+
-+Ltweak_xts_dec:
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vcipher		$tweak,$tweak,$rndkey1
-+	lvx		$rndkey1,$idx,$key2
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vcipher		$tweak,$tweak,$rndkey0
-+	lvx		$rndkey0,$idx,$key2
-+	addi		$idx,$idx,16
-+	bdnz		Ltweak_xts_dec
-+
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vcipher		$tweak,$tweak,$rndkey1
-+	lvx		$rndkey1,$idx,$key2
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vcipherlast	$tweak,$tweak,$rndkey0
-+
-+	li		$ivp,0				# don't chain the tweak
-+	b		Lxts_dec
-+
-+Lxts_dec_no_key2:
-+	neg		$idx,$len
-+	andi.		$idx,$idx,15
-+	add		$len,$len,$idx			# in "tweak chaining"
-+							# mode only complete
-+							# blocks are processed
-+Lxts_dec:
-+	lvx		$inptail,0,$inp
-+	addi		$inp,$inp,16
-+
-+	?lvsl		$keyperm,0,$key1		# prepare for unaligned key
-+	lwz		$rounds,240($key1)
-+	srwi		$rounds,$rounds,1
-+	subi		$rounds,$rounds,1
-+	li		$idx,16
-+
-+	vslb		$eighty7,$seven,$seven		# 0x808080..80
-+	vor		$eighty7,$eighty7,$seven	# 0x878787..87
-+	vspltisb	$tmp,1				# 0x010101..01
-+	vsldoi		$eighty7,$eighty7,$tmp,15	# 0x870101..01
-+
-+	${UCMP}i	$len,96
-+	bge		_aesp8_xts_decrypt6x
-+
-+	lvx		$rndkey0,0,$key1
-+	lvx		$rndkey1,$idx,$key1
-+	addi		$idx,$idx,16
-+	vperm		$inout,$inout,$inptail,$inpperm
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$inout,$inout,$tweak
-+	vxor		$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key1
-+	addi		$idx,$idx,16
-+	mtctr		$rounds
-+
-+	${UCMP}i	$len,16
-+	blt		Ltail_xts_dec
-+	be?b		Loop_xts_dec
-+
-+.align	5
-+Loop_xts_dec:
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vncipher	$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key1
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vncipher	$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key1
-+	addi		$idx,$idx,16
-+	bdnz		Loop_xts_dec
-+
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vncipher	$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key1
-+	li		$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$rndkey0,$rndkey0,$tweak
-+	vncipherlast	$output,$inout,$rndkey0
-+
-+	le?vperm	$tmp,$output,$output,$leperm
-+	be?nop
-+	le?stvx_u	$tmp,0,$out
-+	be?stvx_u	$output,0,$out
-+	addi		$out,$out,16
-+
-+	subic.		$len,$len,16
-+	beq		Lxts_dec_done
-+
-+	vmr		$inout,$inptail
-+	lvx		$inptail,0,$inp
-+	addi		$inp,$inp,16
-+	lvx		$rndkey0,0,$key1
-+	lvx		$rndkey1,$idx,$key1
-+	addi		$idx,$idx,16
-+
-+	vsrab		$tmp,$tweak,$seven		# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	vand		$tmp,$tmp,$eighty7
-+	vxor		$tweak,$tweak,$tmp
-+
-+	vperm		$inout,$inout,$inptail,$inpperm
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$inout,$inout,$tweak
-+	vxor		$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key1
-+	addi		$idx,$idx,16
-+
-+	mtctr		$rounds
-+	${UCMP}i	$len,16
-+	bge		Loop_xts_dec
-+
-+Ltail_xts_dec:
-+	vsrab		$tmp,$tweak,$seven		# next tweak value
-+	vaddubm		$tweak1,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	vand		$tmp,$tmp,$eighty7
-+	vxor		$tweak1,$tweak1,$tmp
-+
-+	subi		$inp,$inp,16
-+	add		$inp,$inp,$len
-+
-+	vxor		$inout,$inout,$tweak		# :-(
-+	vxor		$inout,$inout,$tweak1		# :-)
-+
-+Loop_xts_dec_short:
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vncipher	$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key1
-+	addi		$idx,$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vncipher	$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key1
-+	addi		$idx,$idx,16
-+	bdnz		Loop_xts_dec_short
-+
-+	?vperm		$rndkey1,$rndkey1,$rndkey0,$keyperm
-+	vncipher	$inout,$inout,$rndkey1
-+	lvx		$rndkey1,$idx,$key1
-+	li		$idx,16
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+	vxor		$rndkey0,$rndkey0,$tweak1
-+	vncipherlast	$output,$inout,$rndkey0
-+
-+	le?vperm	$tmp,$output,$output,$leperm
-+	be?nop
-+	le?stvx_u	$tmp,0,$out
-+	be?stvx_u	$output,0,$out
-+
-+	vmr		$inout,$inptail
-+	lvx		$inptail,0,$inp
-+	#addi		$inp,$inp,16
-+	lvx		$rndkey0,0,$key1
-+	lvx		$rndkey1,$idx,$key1
-+	addi		$idx,$idx,16
-+	vperm		$inout,$inout,$inptail,$inpperm
-+	?vperm		$rndkey0,$rndkey0,$rndkey1,$keyperm
-+
-+	lvsr		$inpperm,0,$len			# $inpperm is no longer needed
-+	vxor		$inptail,$inptail,$inptail	# $inptail is no longer needed
-+	vspltisb	$tmp,-1
-+	vperm		$inptail,$inptail,$tmp,$inpperm
-+	vsel		$inout,$inout,$output,$inptail
-+
-+	vxor		$rndkey0,$rndkey0,$tweak
-+	vxor		$inout,$inout,$rndkey0
-+	lvx		$rndkey0,$idx,$key1
-+	addi		$idx,$idx,16
-+
-+	subi		r11,$out,1
-+	mtctr		$len
-+	li		$len,16
-+Loop_xts_dec_steal:
-+	lbzu		r0,1(r11)
-+	stb		r0,16(r11)
-+	bdnz		Loop_xts_dec_steal
-+
-+	mtctr		$rounds
-+	b		Loop_xts_dec			# one more time...
-+
-+Lxts_dec_done:
-+	${UCMP}i	$ivp,0
-+	beq		Lxts_dec_ret
-+
-+	vsrab		$tmp,$tweak,$seven		# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	vand		$tmp,$tmp,$eighty7
-+	vxor		$tweak,$tweak,$tmp
-+
-+	le?vperm	$tweak,$tweak,$tweak,$leperm
-+	stvx_u		$tweak,0,$ivp
-+
-+Lxts_dec_ret:
-+	mtspr		256,r12				# restore vrsave
-+	li		r3,0
-+	blr
-+	.long		0
-+	.byte		0,12,0x04,0,0x80,6,6,0
-+	.long		0
-+.size	.${prefix}_xts_decrypt,.-.${prefix}_xts_decrypt
-+___
-+#########################################################################
-+{{	# Optimized XTS procedures					#
-+my $key_=$key2;
-+my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,3,26..31));
-+    $x00=0 if ($flavour =~ /osx/);
-+my ($in0,  $in1,  $in2,  $in3,  $in4,  $in5 )=map("v$_",(0..5));
-+my ($out0, $out1, $out2, $out3, $out4, $out5)=map("v$_",(7,12..16));
-+my ($twk0, $twk1, $twk2, $twk3, $twk4, $twk5)=map("v$_",(17..22));
-+my $rndkey0="v23";	# v24-v25 rotating buffer for first found keys
-+			# v26-v31 last 6 round keys
-+my ($keyperm)=($out0);	# aliases with "caller", redundant assignment
-+my $taillen=$x70;
-+
-+$code.=<<___;
-+.align	5
-+_aesp8_xts_encrypt6x:
-+	$STU		$sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
-+	mflr		r11
-+	li		r7,`$FRAME+8*16+15`
-+	li		r3,`$FRAME+8*16+31`
-+	$PUSH		r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp)
-+	stvx		v20,r7,$sp		# ABI says so
-+	addi		r7,r7,32
-+	stvx		v21,r3,$sp
-+	addi		r3,r3,32
-+	stvx		v22,r7,$sp
-+	addi		r7,r7,32
-+	stvx		v23,r3,$sp
-+	addi		r3,r3,32
-+	stvx		v24,r7,$sp
-+	addi		r7,r7,32
-+	stvx		v25,r3,$sp
-+	addi		r3,r3,32
-+	stvx		v26,r7,$sp
-+	addi		r7,r7,32
-+	stvx		v27,r3,$sp
-+	addi		r3,r3,32
-+	stvx		v28,r7,$sp
-+	addi		r7,r7,32
-+	stvx		v29,r3,$sp
-+	addi		r3,r3,32
-+	stvx		v30,r7,$sp
-+	stvx		v31,r3,$sp
-+	li		r0,-1
-+	stw		$vrsave,`$FRAME+21*16-4`($sp)	# save vrsave
-+	li		$x10,0x10
-+	$PUSH		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
-+	li		$x20,0x20
-+	$PUSH		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
-+	li		$x30,0x30
-+	$PUSH		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
-+	li		$x40,0x40
-+	$PUSH		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
-+	li		$x50,0x50
-+	$PUSH		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
-+	li		$x60,0x60
-+	$PUSH		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
-+	li		$x70,0x70
-+	mtspr		256,r0
-+
-+	subi		$rounds,$rounds,3	# -4 in total
-+
-+	lvx		$rndkey0,$x00,$key1	# load key schedule
-+	lvx		v30,$x10,$key1
-+	addi		$key1,$key1,0x20
-+	lvx		v31,$x00,$key1
-+	?vperm		$rndkey0,$rndkey0,v30,$keyperm
-+	addi		$key_,$sp,$FRAME+15
-+	mtctr		$rounds
-+
-+Load_xts_enc_key:
-+	?vperm		v24,v30,v31,$keyperm
-+	lvx		v30,$x10,$key1
-+	addi		$key1,$key1,0x20
-+	stvx		v24,$x00,$key_		# off-load round[1]
-+	?vperm		v25,v31,v30,$keyperm
-+	lvx		v31,$x00,$key1
-+	stvx		v25,$x10,$key_		# off-load round[2]
-+	addi		$key_,$key_,0x20
-+	bdnz		Load_xts_enc_key
-+
-+	lvx		v26,$x10,$key1
-+	?vperm		v24,v30,v31,$keyperm
-+	lvx		v27,$x20,$key1
-+	stvx		v24,$x00,$key_		# off-load round[3]
-+	?vperm		v25,v31,v26,$keyperm
-+	lvx		v28,$x30,$key1
-+	stvx		v25,$x10,$key_		# off-load round[4]
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	?vperm		v26,v26,v27,$keyperm
-+	lvx		v29,$x40,$key1
-+	?vperm		v27,v27,v28,$keyperm
-+	lvx		v30,$x50,$key1
-+	?vperm		v28,v28,v29,$keyperm
-+	lvx		v31,$x60,$key1
-+	?vperm		v29,v29,v30,$keyperm
-+	lvx		$twk5,$x70,$key1	# borrow $twk5
-+	?vperm		v30,v30,v31,$keyperm
-+	lvx		v24,$x00,$key_		# pre-load round[1]
-+	?vperm		v31,v31,$twk5,$keyperm
-+	lvx		v25,$x10,$key_		# pre-load round[2]
-+
-+	 vperm		$in0,$inout,$inptail,$inpperm
-+	 subi		$inp,$inp,31		# undo "caller"
-+	vxor		$twk0,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out0,$in0,$twk0
-+	vxor		$tweak,$tweak,$tmp
-+
-+	 lvx_u		$in1,$x10,$inp
-+	vxor		$twk1,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	 le?vperm	$in1,$in1,$in1,$leperm
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out1,$in1,$twk1
-+	vxor		$tweak,$tweak,$tmp
-+
-+	 lvx_u		$in2,$x20,$inp
-+	 andi.		$taillen,$len,15
-+	vxor		$twk2,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	 le?vperm	$in2,$in2,$in2,$leperm
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out2,$in2,$twk2
-+	vxor		$tweak,$tweak,$tmp
-+
-+	 lvx_u		$in3,$x30,$inp
-+	 sub		$len,$len,$taillen
-+	vxor		$twk3,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	 le?vperm	$in3,$in3,$in3,$leperm
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out3,$in3,$twk3
-+	vxor		$tweak,$tweak,$tmp
-+
-+	 lvx_u		$in4,$x40,$inp
-+	 subi		$len,$len,0x60
-+	vxor		$twk4,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	 le?vperm	$in4,$in4,$in4,$leperm
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out4,$in4,$twk4
-+	vxor		$tweak,$tweak,$tmp
-+
-+	 lvx_u		$in5,$x50,$inp
-+	 addi		$inp,$inp,0x60
-+	vxor		$twk5,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	 le?vperm	$in5,$in5,$in5,$leperm
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out5,$in5,$twk5
-+	vxor		$tweak,$tweak,$tmp
-+
-+	vxor		v31,v31,$rndkey0
-+	mtctr		$rounds
-+	b		Loop_xts_enc6x
-+
-+.align	5
-+Loop_xts_enc6x:
-+	vcipher		$out0,$out0,v24
-+	vcipher		$out1,$out1,v24
-+	vcipher		$out2,$out2,v24
-+	vcipher		$out3,$out3,v24
-+	vcipher		$out4,$out4,v24
-+	vcipher		$out5,$out5,v24
-+	lvx		v24,$x20,$key_		# round[3]
-+	addi		$key_,$key_,0x20
-+
-+	vcipher		$out0,$out0,v25
-+	vcipher		$out1,$out1,v25
-+	vcipher		$out2,$out2,v25
-+	vcipher		$out3,$out3,v25
-+	vcipher		$out4,$out4,v25
-+	vcipher		$out5,$out5,v25
-+	lvx		v25,$x10,$key_		# round[4]
-+	bdnz		Loop_xts_enc6x
-+
-+	subic		$len,$len,96		# $len-=96
-+	 vxor		$in0,$twk0,v31		# xor with last round key
-+	vcipher		$out0,$out0,v24
-+	vcipher		$out1,$out1,v24
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk0,$tweak,$rndkey0
-+	 vaddubm	$tweak,$tweak,$tweak
-+	vcipher		$out2,$out2,v24
-+	vcipher		$out3,$out3,v24
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+	vcipher		$out4,$out4,v24
-+	vcipher		$out5,$out5,v24
-+
-+	subfe.		r0,r0,r0		# borrow?-1:0
-+	 vand		$tmp,$tmp,$eighty7
-+	vcipher		$out0,$out0,v25
-+	vcipher		$out1,$out1,v25
-+	 vxor		$tweak,$tweak,$tmp
-+	vcipher		$out2,$out2,v25
-+	vcipher		$out3,$out3,v25
-+	 vxor		$in1,$twk1,v31
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk1,$tweak,$rndkey0
-+	vcipher		$out4,$out4,v25
-+	vcipher		$out5,$out5,v25
-+
-+	and		r0,r0,$len
-+	 vaddubm	$tweak,$tweak,$tweak
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+	vcipher		$out0,$out0,v26
-+	vcipher		$out1,$out1,v26
-+	 vand		$tmp,$tmp,$eighty7
-+	vcipher		$out2,$out2,v26
-+	vcipher		$out3,$out3,v26
-+	 vxor		$tweak,$tweak,$tmp
-+	vcipher		$out4,$out4,v26
-+	vcipher		$out5,$out5,v26
-+
-+	add		$inp,$inp,r0		# $inp is adjusted in such
-+						# way that at exit from the
-+						# loop inX-in5 are loaded
-+						# with last "words"
-+	 vxor		$in2,$twk2,v31
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk2,$tweak,$rndkey0
-+	 vaddubm	$tweak,$tweak,$tweak
-+	vcipher		$out0,$out0,v27
-+	vcipher		$out1,$out1,v27
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+	vcipher		$out2,$out2,v27
-+	vcipher		$out3,$out3,v27
-+	 vand		$tmp,$tmp,$eighty7
-+	vcipher		$out4,$out4,v27
-+	vcipher		$out5,$out5,v27
-+
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	 vxor		$tweak,$tweak,$tmp
-+	vcipher		$out0,$out0,v28
-+	vcipher		$out1,$out1,v28
-+	 vxor		$in3,$twk3,v31
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk3,$tweak,$rndkey0
-+	vcipher		$out2,$out2,v28
-+	vcipher		$out3,$out3,v28
-+	 vaddubm	$tweak,$tweak,$tweak
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+	vcipher		$out4,$out4,v28
-+	vcipher		$out5,$out5,v28
-+	lvx		v24,$x00,$key_		# re-pre-load round[1]
-+	 vand		$tmp,$tmp,$eighty7
-+
-+	vcipher		$out0,$out0,v29
-+	vcipher		$out1,$out1,v29
-+	 vxor		$tweak,$tweak,$tmp
-+	vcipher		$out2,$out2,v29
-+	vcipher		$out3,$out3,v29
-+	 vxor		$in4,$twk4,v31
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk4,$tweak,$rndkey0
-+	vcipher		$out4,$out4,v29
-+	vcipher		$out5,$out5,v29
-+	lvx		v25,$x10,$key_		# re-pre-load round[2]
-+	 vaddubm	$tweak,$tweak,$tweak
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+
-+	vcipher		$out0,$out0,v30
-+	vcipher		$out1,$out1,v30
-+	 vand		$tmp,$tmp,$eighty7
-+	vcipher		$out2,$out2,v30
-+	vcipher		$out3,$out3,v30
-+	 vxor		$tweak,$tweak,$tmp
-+	vcipher		$out4,$out4,v30
-+	vcipher		$out5,$out5,v30
-+	 vxor		$in5,$twk5,v31
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk5,$tweak,$rndkey0
-+
-+	vcipherlast	$out0,$out0,$in0
-+	 lvx_u		$in0,$x00,$inp		# load next input block
-+	 vaddubm	$tweak,$tweak,$tweak
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+	vcipherlast	$out1,$out1,$in1
-+	 lvx_u		$in1,$x10,$inp
-+	vcipherlast	$out2,$out2,$in2
-+	 le?vperm	$in0,$in0,$in0,$leperm
-+	 lvx_u		$in2,$x20,$inp
-+	 vand		$tmp,$tmp,$eighty7
-+	vcipherlast	$out3,$out3,$in3
-+	 le?vperm	$in1,$in1,$in1,$leperm
-+	 lvx_u		$in3,$x30,$inp
-+	vcipherlast	$out4,$out4,$in4
-+	 le?vperm	$in2,$in2,$in2,$leperm
-+	 lvx_u		$in4,$x40,$inp
-+	 vxor		$tweak,$tweak,$tmp
-+	vcipherlast	$tmp,$out5,$in5		# last block might be needed
-+						# in stealing mode
-+	 le?vperm	$in3,$in3,$in3,$leperm
-+	 lvx_u		$in5,$x50,$inp
-+	 addi		$inp,$inp,0x60
-+	 le?vperm	$in4,$in4,$in4,$leperm
-+	 le?vperm	$in5,$in5,$in5,$leperm
-+
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	le?vperm	$out1,$out1,$out1,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	 vxor		$out0,$in0,$twk0
-+	le?vperm	$out2,$out2,$out2,$leperm
-+	stvx_u		$out1,$x10,$out
-+	 vxor		$out1,$in1,$twk1
-+	le?vperm	$out3,$out3,$out3,$leperm
-+	stvx_u		$out2,$x20,$out
-+	 vxor		$out2,$in2,$twk2
-+	le?vperm	$out4,$out4,$out4,$leperm
-+	stvx_u		$out3,$x30,$out
-+	 vxor		$out3,$in3,$twk3
-+	le?vperm	$out5,$tmp,$tmp,$leperm
-+	stvx_u		$out4,$x40,$out
-+	 vxor		$out4,$in4,$twk4
-+	le?stvx_u	$out5,$x50,$out
-+	be?stvx_u	$tmp, $x50,$out
-+	 vxor		$out5,$in5,$twk5
-+	addi		$out,$out,0x60
-+
-+	mtctr		$rounds
-+	beq		Loop_xts_enc6x		# did $len-=96 borrow?
-+
-+	addic.		$len,$len,0x60
-+	beq		Lxts_enc6x_zero
-+	cmpwi		$len,0x20
-+	blt		Lxts_enc6x_one
-+	nop
-+	beq		Lxts_enc6x_two
-+	cmpwi		$len,0x40
-+	blt		Lxts_enc6x_three
-+	nop
-+	beq		Lxts_enc6x_four
-+
-+Lxts_enc6x_five:
-+	vxor		$out0,$in1,$twk0
-+	vxor		$out1,$in2,$twk1
-+	vxor		$out2,$in3,$twk2
-+	vxor		$out3,$in4,$twk3
-+	vxor		$out4,$in5,$twk4
-+
-+	bl		_aesp8_xts_enc5x
-+
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	vmr		$twk0,$twk5		# unused tweak
-+	le?vperm	$out1,$out1,$out1,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	le?vperm	$out2,$out2,$out2,$leperm
-+	stvx_u		$out1,$x10,$out
-+	le?vperm	$out3,$out3,$out3,$leperm
-+	stvx_u		$out2,$x20,$out
-+	vxor		$tmp,$out4,$twk5	# last block prep for stealing
-+	le?vperm	$out4,$out4,$out4,$leperm
-+	stvx_u		$out3,$x30,$out
-+	stvx_u		$out4,$x40,$out
-+	addi		$out,$out,0x50
-+	bne		Lxts_enc6x_steal
-+	b		Lxts_enc6x_done
-+
-+.align	4
-+Lxts_enc6x_four:
-+	vxor		$out0,$in2,$twk0
-+	vxor		$out1,$in3,$twk1
-+	vxor		$out2,$in4,$twk2
-+	vxor		$out3,$in5,$twk3
-+	vxor		$out4,$out4,$out4
-+
-+	bl		_aesp8_xts_enc5x
-+
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	vmr		$twk0,$twk4		# unused tweak
-+	le?vperm	$out1,$out1,$out1,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	le?vperm	$out2,$out2,$out2,$leperm
-+	stvx_u		$out1,$x10,$out
-+	vxor		$tmp,$out3,$twk4	# last block prep for stealing
-+	le?vperm	$out3,$out3,$out3,$leperm
-+	stvx_u		$out2,$x20,$out
-+	stvx_u		$out3,$x30,$out
-+	addi		$out,$out,0x40
-+	bne		Lxts_enc6x_steal
-+	b		Lxts_enc6x_done
-+
-+.align	4
-+Lxts_enc6x_three:
-+	vxor		$out0,$in3,$twk0
-+	vxor		$out1,$in4,$twk1
-+	vxor		$out2,$in5,$twk2
-+	vxor		$out3,$out3,$out3
-+	vxor		$out4,$out4,$out4
-+
-+	bl		_aesp8_xts_enc5x
-+
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	vmr		$twk0,$twk3		# unused tweak
-+	le?vperm	$out1,$out1,$out1,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	vxor		$tmp,$out2,$twk3	# last block prep for stealing
-+	le?vperm	$out2,$out2,$out2,$leperm
-+	stvx_u		$out1,$x10,$out
-+	stvx_u		$out2,$x20,$out
-+	addi		$out,$out,0x30
-+	bne		Lxts_enc6x_steal
-+	b		Lxts_enc6x_done
-+
-+.align	4
-+Lxts_enc6x_two:
-+	vxor		$out0,$in4,$twk0
-+	vxor		$out1,$in5,$twk1
-+	vxor		$out2,$out2,$out2
-+	vxor		$out3,$out3,$out3
-+	vxor		$out4,$out4,$out4
-+
-+	bl		_aesp8_xts_enc5x
-+
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	vmr		$twk0,$twk2		# unused tweak
-+	vxor		$tmp,$out1,$twk2	# last block prep for stealing
-+	le?vperm	$out1,$out1,$out1,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	stvx_u		$out1,$x10,$out
-+	addi		$out,$out,0x20
-+	bne		Lxts_enc6x_steal
-+	b		Lxts_enc6x_done
-+
-+.align	4
-+Lxts_enc6x_one:
-+	vxor		$out0,$in5,$twk0
-+	nop
-+Loop_xts_enc1x:
-+	vcipher		$out0,$out0,v24
-+	lvx		v24,$x20,$key_		# round[3]
-+	addi		$key_,$key_,0x20
-+
-+	vcipher		$out0,$out0,v25
-+	lvx		v25,$x10,$key_		# round[4]
-+	bdnz		Loop_xts_enc1x
-+
-+	add		$inp,$inp,$taillen
-+	cmpwi		$taillen,0
-+	vcipher		$out0,$out0,v24
-+
-+	subi		$inp,$inp,16
-+	vcipher		$out0,$out0,v25
-+
-+	lvsr		$inpperm,0,$taillen
-+	vcipher		$out0,$out0,v26
-+
-+	lvx_u		$in0,0,$inp
-+	vcipher		$out0,$out0,v27
-+
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	vcipher		$out0,$out0,v28
-+	lvx		v24,$x00,$key_		# re-pre-load round[1]
-+
-+	vcipher		$out0,$out0,v29
-+	lvx		v25,$x10,$key_		# re-pre-load round[2]
-+	 vxor		$twk0,$twk0,v31
-+
-+	le?vperm	$in0,$in0,$in0,$leperm
-+	vcipher		$out0,$out0,v30
-+
-+	vperm		$in0,$in0,$in0,$inpperm
-+	vcipherlast	$out0,$out0,$twk0
-+
-+	vmr		$twk0,$twk1		# unused tweak
-+	vxor		$tmp,$out0,$twk1	# last block prep for stealing
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	addi		$out,$out,0x10
-+	bne		Lxts_enc6x_steal
-+	b		Lxts_enc6x_done
-+
-+.align	4
-+Lxts_enc6x_zero:
-+	cmpwi		$taillen,0
-+	beq		Lxts_enc6x_done
-+
-+	add		$inp,$inp,$taillen
-+	subi		$inp,$inp,16
-+	lvx_u		$in0,0,$inp
-+	lvsr		$inpperm,0,$taillen	# $in5 is no more
-+	le?vperm	$in0,$in0,$in0,$leperm
-+	vperm		$in0,$in0,$in0,$inpperm
-+	vxor		$tmp,$tmp,$twk0
-+Lxts_enc6x_steal:
-+	vxor		$in0,$in0,$twk0
-+	vxor		$out0,$out0,$out0
-+	vspltisb	$out1,-1
-+	vperm		$out0,$out0,$out1,$inpperm
-+	vsel		$out0,$in0,$tmp,$out0	# $tmp is last block, remember?
-+
-+	subi		r30,$out,17
-+	subi		$out,$out,16
-+	mtctr		$taillen
-+Loop_xts_enc6x_steal:
-+	lbzu		r0,1(r30)
-+	stb		r0,16(r30)
-+	bdnz		Loop_xts_enc6x_steal
-+
-+	li		$taillen,0
-+	mtctr		$rounds
-+	b		Loop_xts_enc1x		# one more time...
-+
-+.align	4
-+Lxts_enc6x_done:
-+	${UCMP}i	$ivp,0
-+	beq		Lxts_enc6x_ret
-+
-+	vxor		$tweak,$twk0,$rndkey0
-+	le?vperm	$tweak,$tweak,$tweak,$leperm
-+	stvx_u		$tweak,0,$ivp
-+
-+Lxts_enc6x_ret:
-+	mtlr		r11
-+	li		r10,`$FRAME+15`
-+	li		r11,`$FRAME+31`
-+	stvx		$seven,r10,$sp		# wipe copies of round keys
-+	addi		r10,r10,32
-+	stvx		$seven,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$seven,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$seven,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$seven,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$seven,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$seven,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$seven,r11,$sp
-+	addi		r11,r11,32
-+
-+	mtspr		256,$vrsave
-+	lvx		v20,r10,$sp		# ABI says so
-+	addi		r10,r10,32
-+	lvx		v21,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v22,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v23,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v24,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v25,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v26,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v27,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v28,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v29,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v30,r10,$sp
-+	lvx		v31,r11,$sp
-+	$POP		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
-+	$POP		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
-+	$POP		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
-+	$POP		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
-+	$POP		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
-+	$POP		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
-+	addi		$sp,$sp,`$FRAME+21*16+6*$SIZE_T`
-+	blr
-+	.long		0
-+	.byte		0,12,0x04,1,0x80,6,6,0
-+	.long		0
-+
-+.align	5
-+_aesp8_xts_enc5x:
-+	vcipher		$out0,$out0,v24
-+	vcipher		$out1,$out1,v24
-+	vcipher		$out2,$out2,v24
-+	vcipher		$out3,$out3,v24
-+	vcipher		$out4,$out4,v24
-+	lvx		v24,$x20,$key_		# round[3]
-+	addi		$key_,$key_,0x20
-+
-+	vcipher		$out0,$out0,v25
-+	vcipher		$out1,$out1,v25
-+	vcipher		$out2,$out2,v25
-+	vcipher		$out3,$out3,v25
-+	vcipher		$out4,$out4,v25
-+	lvx		v25,$x10,$key_		# round[4]
-+	bdnz		_aesp8_xts_enc5x
-+
-+	add		$inp,$inp,$taillen
-+	cmpwi		$taillen,0
-+	vcipher		$out0,$out0,v24
-+	vcipher		$out1,$out1,v24
-+	vcipher		$out2,$out2,v24
-+	vcipher		$out3,$out3,v24
-+	vcipher		$out4,$out4,v24
-+
-+	subi		$inp,$inp,16
-+	vcipher		$out0,$out0,v25
-+	vcipher		$out1,$out1,v25
-+	vcipher		$out2,$out2,v25
-+	vcipher		$out3,$out3,v25
-+	vcipher		$out4,$out4,v25
-+	 vxor		$twk0,$twk0,v31
-+
-+	vcipher		$out0,$out0,v26
-+	lvsr		$inpperm,0,$taillen	# $in5 is no more
-+	vcipher		$out1,$out1,v26
-+	vcipher		$out2,$out2,v26
-+	vcipher		$out3,$out3,v26
-+	vcipher		$out4,$out4,v26
-+	 vxor		$in1,$twk1,v31
-+
-+	vcipher		$out0,$out0,v27
-+	lvx_u		$in0,0,$inp
-+	vcipher		$out1,$out1,v27
-+	vcipher		$out2,$out2,v27
-+	vcipher		$out3,$out3,v27
-+	vcipher		$out4,$out4,v27
-+	 vxor		$in2,$twk2,v31
-+
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	vcipher		$out0,$out0,v28
-+	vcipher		$out1,$out1,v28
-+	vcipher		$out2,$out2,v28
-+	vcipher		$out3,$out3,v28
-+	vcipher		$out4,$out4,v28
-+	lvx		v24,$x00,$key_		# re-pre-load round[1]
-+	 vxor		$in3,$twk3,v31
-+
-+	vcipher		$out0,$out0,v29
-+	le?vperm	$in0,$in0,$in0,$leperm
-+	vcipher		$out1,$out1,v29
-+	vcipher		$out2,$out2,v29
-+	vcipher		$out3,$out3,v29
-+	vcipher		$out4,$out4,v29
-+	lvx		v25,$x10,$key_		# re-pre-load round[2]
-+	 vxor		$in4,$twk4,v31
-+
-+	vcipher		$out0,$out0,v30
-+	vperm		$in0,$in0,$in0,$inpperm
-+	vcipher		$out1,$out1,v30
-+	vcipher		$out2,$out2,v30
-+	vcipher		$out3,$out3,v30
-+	vcipher		$out4,$out4,v30
-+
-+	vcipherlast	$out0,$out0,$twk0
-+	vcipherlast	$out1,$out1,$in1
-+	vcipherlast	$out2,$out2,$in2
-+	vcipherlast	$out3,$out3,$in3
-+	vcipherlast	$out4,$out4,$in4
-+	blr
-+        .long   	0
-+        .byte   	0,12,0x14,0,0,0,0,0
-+
-+.align	5
-+_aesp8_xts_decrypt6x:
-+	$STU		$sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
-+	mflr		r11
-+	li		r7,`$FRAME+8*16+15`
-+	li		r3,`$FRAME+8*16+31`
-+	$PUSH		r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp)
-+	stvx		v20,r7,$sp		# ABI says so
-+	addi		r7,r7,32
-+	stvx		v21,r3,$sp
-+	addi		r3,r3,32
-+	stvx		v22,r7,$sp
-+	addi		r7,r7,32
-+	stvx		v23,r3,$sp
-+	addi		r3,r3,32
-+	stvx		v24,r7,$sp
-+	addi		r7,r7,32
-+	stvx		v25,r3,$sp
-+	addi		r3,r3,32
-+	stvx		v26,r7,$sp
-+	addi		r7,r7,32
-+	stvx		v27,r3,$sp
-+	addi		r3,r3,32
-+	stvx		v28,r7,$sp
-+	addi		r7,r7,32
-+	stvx		v29,r3,$sp
-+	addi		r3,r3,32
-+	stvx		v30,r7,$sp
-+	stvx		v31,r3,$sp
-+	li		r0,-1
-+	stw		$vrsave,`$FRAME+21*16-4`($sp)	# save vrsave
-+	li		$x10,0x10
-+	$PUSH		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
-+	li		$x20,0x20
-+	$PUSH		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
-+	li		$x30,0x30
-+	$PUSH		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
-+	li		$x40,0x40
-+	$PUSH		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
-+	li		$x50,0x50
-+	$PUSH		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
-+	li		$x60,0x60
-+	$PUSH		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
-+	li		$x70,0x70
-+	mtspr		256,r0
-+
-+	subi		$rounds,$rounds,3	# -4 in total
-+
-+	lvx		$rndkey0,$x00,$key1	# load key schedule
-+	lvx		v30,$x10,$key1
-+	addi		$key1,$key1,0x20
-+	lvx		v31,$x00,$key1
-+	?vperm		$rndkey0,$rndkey0,v30,$keyperm
-+	addi		$key_,$sp,$FRAME+15
-+	mtctr		$rounds
-+
-+Load_xts_dec_key:
-+	?vperm		v24,v30,v31,$keyperm
-+	lvx		v30,$x10,$key1
-+	addi		$key1,$key1,0x20
-+	stvx		v24,$x00,$key_		# off-load round[1]
-+	?vperm		v25,v31,v30,$keyperm
-+	lvx		v31,$x00,$key1
-+	stvx		v25,$x10,$key_		# off-load round[2]
-+	addi		$key_,$key_,0x20
-+	bdnz		Load_xts_dec_key
-+
-+	lvx		v26,$x10,$key1
-+	?vperm		v24,v30,v31,$keyperm
-+	lvx		v27,$x20,$key1
-+	stvx		v24,$x00,$key_		# off-load round[3]
-+	?vperm		v25,v31,v26,$keyperm
-+	lvx		v28,$x30,$key1
-+	stvx		v25,$x10,$key_		# off-load round[4]
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	?vperm		v26,v26,v27,$keyperm
-+	lvx		v29,$x40,$key1
-+	?vperm		v27,v27,v28,$keyperm
-+	lvx		v30,$x50,$key1
-+	?vperm		v28,v28,v29,$keyperm
-+	lvx		v31,$x60,$key1
-+	?vperm		v29,v29,v30,$keyperm
-+	lvx		$twk5,$x70,$key1	# borrow $twk5
-+	?vperm		v30,v30,v31,$keyperm
-+	lvx		v24,$x00,$key_		# pre-load round[1]
-+	?vperm		v31,v31,$twk5,$keyperm
-+	lvx		v25,$x10,$key_		# pre-load round[2]
-+
-+	 vperm		$in0,$inout,$inptail,$inpperm
-+	 subi		$inp,$inp,31		# undo "caller"
-+	vxor		$twk0,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out0,$in0,$twk0
-+	vxor		$tweak,$tweak,$tmp
-+
-+	 lvx_u		$in1,$x10,$inp
-+	vxor		$twk1,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	 le?vperm	$in1,$in1,$in1,$leperm
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out1,$in1,$twk1
-+	vxor		$tweak,$tweak,$tmp
-+
-+	 lvx_u		$in2,$x20,$inp
-+	 andi.		$taillen,$len,15
-+	vxor		$twk2,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	 le?vperm	$in2,$in2,$in2,$leperm
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out2,$in2,$twk2
-+	vxor		$tweak,$tweak,$tmp
-+
-+	 lvx_u		$in3,$x30,$inp
-+	 sub		$len,$len,$taillen
-+	vxor		$twk3,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	 le?vperm	$in3,$in3,$in3,$leperm
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out3,$in3,$twk3
-+	vxor		$tweak,$tweak,$tmp
-+
-+	 lvx_u		$in4,$x40,$inp
-+	 subi		$len,$len,0x60
-+	vxor		$twk4,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	 le?vperm	$in4,$in4,$in4,$leperm
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out4,$in4,$twk4
-+	vxor		$tweak,$tweak,$tmp
-+
-+	 lvx_u		$in5,$x50,$inp
-+	 addi		$inp,$inp,0x60
-+	vxor		$twk5,$tweak,$rndkey0
-+	vsrab		$tmp,$tweak,$seven	# next tweak value
-+	vaddubm		$tweak,$tweak,$tweak
-+	vsldoi		$tmp,$tmp,$tmp,15
-+	 le?vperm	$in5,$in5,$in5,$leperm
-+	vand		$tmp,$tmp,$eighty7
-+	 vxor		$out5,$in5,$twk5
-+	vxor		$tweak,$tweak,$tmp
-+
-+	vxor		v31,v31,$rndkey0
-+	mtctr		$rounds
-+	b		Loop_xts_dec6x
-+
-+.align	5
-+Loop_xts_dec6x:
-+	vncipher	$out0,$out0,v24
-+	vncipher	$out1,$out1,v24
-+	vncipher	$out2,$out2,v24
-+	vncipher	$out3,$out3,v24
-+	vncipher	$out4,$out4,v24
-+	vncipher	$out5,$out5,v24
-+	lvx		v24,$x20,$key_		# round[3]
-+	addi		$key_,$key_,0x20
-+
-+	vncipher	$out0,$out0,v25
-+	vncipher	$out1,$out1,v25
-+	vncipher	$out2,$out2,v25
-+	vncipher	$out3,$out3,v25
-+	vncipher	$out4,$out4,v25
-+	vncipher	$out5,$out5,v25
-+	lvx		v25,$x10,$key_		# round[4]
-+	bdnz		Loop_xts_dec6x
-+
-+	subic		$len,$len,96		# $len-=96
-+	 vxor		$in0,$twk0,v31		# xor with last round key
-+	vncipher	$out0,$out0,v24
-+	vncipher	$out1,$out1,v24
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk0,$tweak,$rndkey0
-+	 vaddubm	$tweak,$tweak,$tweak
-+	vncipher	$out2,$out2,v24
-+	vncipher	$out3,$out3,v24
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+	vncipher	$out4,$out4,v24
-+	vncipher	$out5,$out5,v24
-+
-+	subfe.		r0,r0,r0		# borrow?-1:0
-+	 vand		$tmp,$tmp,$eighty7
-+	vncipher	$out0,$out0,v25
-+	vncipher	$out1,$out1,v25
-+	 vxor		$tweak,$tweak,$tmp
-+	vncipher	$out2,$out2,v25
-+	vncipher	$out3,$out3,v25
-+	 vxor		$in1,$twk1,v31
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk1,$tweak,$rndkey0
-+	vncipher	$out4,$out4,v25
-+	vncipher	$out5,$out5,v25
-+
-+	and		r0,r0,$len
-+	 vaddubm	$tweak,$tweak,$tweak
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+	vncipher	$out0,$out0,v26
-+	vncipher	$out1,$out1,v26
-+	 vand		$tmp,$tmp,$eighty7
-+	vncipher	$out2,$out2,v26
-+	vncipher	$out3,$out3,v26
-+	 vxor		$tweak,$tweak,$tmp
-+	vncipher	$out4,$out4,v26
-+	vncipher	$out5,$out5,v26
-+
-+	add		$inp,$inp,r0		# $inp is adjusted in such
-+						# way that at exit from the
-+						# loop inX-in5 are loaded
-+						# with last "words"
-+	 vxor		$in2,$twk2,v31
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk2,$tweak,$rndkey0
-+	 vaddubm	$tweak,$tweak,$tweak
-+	vncipher	$out0,$out0,v27
-+	vncipher	$out1,$out1,v27
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+	vncipher	$out2,$out2,v27
-+	vncipher	$out3,$out3,v27
-+	 vand		$tmp,$tmp,$eighty7
-+	vncipher	$out4,$out4,v27
-+	vncipher	$out5,$out5,v27
-+
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	 vxor		$tweak,$tweak,$tmp
-+	vncipher	$out0,$out0,v28
-+	vncipher	$out1,$out1,v28
-+	 vxor		$in3,$twk3,v31
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk3,$tweak,$rndkey0
-+	vncipher	$out2,$out2,v28
-+	vncipher	$out3,$out3,v28
-+	 vaddubm	$tweak,$tweak,$tweak
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+	vncipher	$out4,$out4,v28
-+	vncipher	$out5,$out5,v28
-+	lvx		v24,$x00,$key_		# re-pre-load round[1]
-+	 vand		$tmp,$tmp,$eighty7
-+
-+	vncipher	$out0,$out0,v29
-+	vncipher	$out1,$out1,v29
-+	 vxor		$tweak,$tweak,$tmp
-+	vncipher	$out2,$out2,v29
-+	vncipher	$out3,$out3,v29
-+	 vxor		$in4,$twk4,v31
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk4,$tweak,$rndkey0
-+	vncipher	$out4,$out4,v29
-+	vncipher	$out5,$out5,v29
-+	lvx		v25,$x10,$key_		# re-pre-load round[2]
-+	 vaddubm	$tweak,$tweak,$tweak
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+
-+	vncipher	$out0,$out0,v30
-+	vncipher	$out1,$out1,v30
-+	 vand		$tmp,$tmp,$eighty7
-+	vncipher	$out2,$out2,v30
-+	vncipher	$out3,$out3,v30
-+	 vxor		$tweak,$tweak,$tmp
-+	vncipher	$out4,$out4,v30
-+	vncipher	$out5,$out5,v30
-+	 vxor		$in5,$twk5,v31
-+	 vsrab		$tmp,$tweak,$seven	# next tweak value
-+	 vxor		$twk5,$tweak,$rndkey0
-+
-+	vncipherlast	$out0,$out0,$in0
-+	 lvx_u		$in0,$x00,$inp		# load next input block
-+	 vaddubm	$tweak,$tweak,$tweak
-+	 vsldoi		$tmp,$tmp,$tmp,15
-+	vncipherlast	$out1,$out1,$in1
-+	 lvx_u		$in1,$x10,$inp
-+	vncipherlast	$out2,$out2,$in2
-+	 le?vperm	$in0,$in0,$in0,$leperm
-+	 lvx_u		$in2,$x20,$inp
-+	 vand		$tmp,$tmp,$eighty7
-+	vncipherlast	$out3,$out3,$in3
-+	 le?vperm	$in1,$in1,$in1,$leperm
-+	 lvx_u		$in3,$x30,$inp
-+	vncipherlast	$out4,$out4,$in4
-+	 le?vperm	$in2,$in2,$in2,$leperm
-+	 lvx_u		$in4,$x40,$inp
-+	 vxor		$tweak,$tweak,$tmp
-+	vncipherlast	$out5,$out5,$in5
-+	 le?vperm	$in3,$in3,$in3,$leperm
-+	 lvx_u		$in5,$x50,$inp
-+	 addi		$inp,$inp,0x60
-+	 le?vperm	$in4,$in4,$in4,$leperm
-+	 le?vperm	$in5,$in5,$in5,$leperm
-+
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	le?vperm	$out1,$out1,$out1,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	 vxor		$out0,$in0,$twk0
-+	le?vperm	$out2,$out2,$out2,$leperm
-+	stvx_u		$out1,$x10,$out
-+	 vxor		$out1,$in1,$twk1
-+	le?vperm	$out3,$out3,$out3,$leperm
-+	stvx_u		$out2,$x20,$out
-+	 vxor		$out2,$in2,$twk2
-+	le?vperm	$out4,$out4,$out4,$leperm
-+	stvx_u		$out3,$x30,$out
-+	 vxor		$out3,$in3,$twk3
-+	le?vperm	$out5,$out5,$out5,$leperm
-+	stvx_u		$out4,$x40,$out
-+	 vxor		$out4,$in4,$twk4
-+	stvx_u		$out5,$x50,$out
-+	 vxor		$out5,$in5,$twk5
-+	addi		$out,$out,0x60
-+
-+	mtctr		$rounds
-+	beq		Loop_xts_dec6x		# did $len-=96 borrow?
-+
-+	addic.		$len,$len,0x60
-+	beq		Lxts_dec6x_zero
-+	cmpwi		$len,0x20
-+	blt		Lxts_dec6x_one
-+	nop
-+	beq		Lxts_dec6x_two
-+	cmpwi		$len,0x40
-+	blt		Lxts_dec6x_three
-+	nop
-+	beq		Lxts_dec6x_four
-+
-+Lxts_dec6x_five:
-+	vxor		$out0,$in1,$twk0
-+	vxor		$out1,$in2,$twk1
-+	vxor		$out2,$in3,$twk2
-+	vxor		$out3,$in4,$twk3
-+	vxor		$out4,$in5,$twk4
-+
-+	bl		_aesp8_xts_dec5x
-+
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	vmr		$twk0,$twk5		# unused tweak
-+	vxor		$twk1,$tweak,$rndkey0
-+	le?vperm	$out1,$out1,$out1,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	vxor		$out0,$in0,$twk1
-+	le?vperm	$out2,$out2,$out2,$leperm
-+	stvx_u		$out1,$x10,$out
-+	le?vperm	$out3,$out3,$out3,$leperm
-+	stvx_u		$out2,$x20,$out
-+	le?vperm	$out4,$out4,$out4,$leperm
-+	stvx_u		$out3,$x30,$out
-+	stvx_u		$out4,$x40,$out
-+	addi		$out,$out,0x50
-+	bne		Lxts_dec6x_steal
-+	b		Lxts_dec6x_done
-+
-+.align	4
-+Lxts_dec6x_four:
-+	vxor		$out0,$in2,$twk0
-+	vxor		$out1,$in3,$twk1
-+	vxor		$out2,$in4,$twk2
-+	vxor		$out3,$in5,$twk3
-+	vxor		$out4,$out4,$out4
-+
-+	bl		_aesp8_xts_dec5x
-+
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	vmr		$twk0,$twk4		# unused tweak
-+	vmr		$twk1,$twk5
-+	le?vperm	$out1,$out1,$out1,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	vxor		$out0,$in0,$twk5
-+	le?vperm	$out2,$out2,$out2,$leperm
-+	stvx_u		$out1,$x10,$out
-+	le?vperm	$out3,$out3,$out3,$leperm
-+	stvx_u		$out2,$x20,$out
-+	stvx_u		$out3,$x30,$out
-+	addi		$out,$out,0x40
-+	bne		Lxts_dec6x_steal
-+	b		Lxts_dec6x_done
-+
-+.align	4
-+Lxts_dec6x_three:
-+	vxor		$out0,$in3,$twk0
-+	vxor		$out1,$in4,$twk1
-+	vxor		$out2,$in5,$twk2
-+	vxor		$out3,$out3,$out3
-+	vxor		$out4,$out4,$out4
-+
-+	bl		_aesp8_xts_dec5x
-+
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	vmr		$twk0,$twk3		# unused tweak
-+	vmr		$twk1,$twk4
-+	le?vperm	$out1,$out1,$out1,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	vxor		$out0,$in0,$twk4
-+	le?vperm	$out2,$out2,$out2,$leperm
-+	stvx_u		$out1,$x10,$out
-+	stvx_u		$out2,$x20,$out
-+	addi		$out,$out,0x30
-+	bne		Lxts_dec6x_steal
-+	b		Lxts_dec6x_done
-+
-+.align	4
-+Lxts_dec6x_two:
-+	vxor		$out0,$in4,$twk0
-+	vxor		$out1,$in5,$twk1
-+	vxor		$out2,$out2,$out2
-+	vxor		$out3,$out3,$out3
-+	vxor		$out4,$out4,$out4
-+
-+	bl		_aesp8_xts_dec5x
-+
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	vmr		$twk0,$twk2		# unused tweak
-+	vmr		$twk1,$twk3
-+	le?vperm	$out1,$out1,$out1,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	vxor		$out0,$in0,$twk3
-+	stvx_u		$out1,$x10,$out
-+	addi		$out,$out,0x20
-+	bne		Lxts_dec6x_steal
-+	b		Lxts_dec6x_done
-+
-+.align	4
-+Lxts_dec6x_one:
-+	vxor		$out0,$in5,$twk0
-+	nop
-+Loop_xts_dec1x:
-+	vncipher	$out0,$out0,v24
-+	lvx		v24,$x20,$key_		# round[3]
-+	addi		$key_,$key_,0x20
-+
-+	vncipher	$out0,$out0,v25
-+	lvx		v25,$x10,$key_		# round[4]
-+	bdnz		Loop_xts_dec1x
-+
-+	subi		r0,$taillen,1
-+	vncipher	$out0,$out0,v24
-+
-+	andi.		r0,r0,16
-+	cmpwi		$taillen,0
-+	vncipher	$out0,$out0,v25
-+
-+	sub		$inp,$inp,r0
-+	vncipher	$out0,$out0,v26
-+
-+	lvx_u		$in0,0,$inp
-+	vncipher	$out0,$out0,v27
-+
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	vncipher	$out0,$out0,v28
-+	lvx		v24,$x00,$key_		# re-pre-load round[1]
-+
-+	vncipher	$out0,$out0,v29
-+	lvx		v25,$x10,$key_		# re-pre-load round[2]
-+	 vxor		$twk0,$twk0,v31
-+
-+	le?vperm	$in0,$in0,$in0,$leperm
-+	vncipher	$out0,$out0,v30
-+
-+	mtctr		$rounds
-+	vncipherlast	$out0,$out0,$twk0
-+
-+	vmr		$twk0,$twk1		# unused tweak
-+	vmr		$twk1,$twk2
-+	le?vperm	$out0,$out0,$out0,$leperm
-+	stvx_u		$out0,$x00,$out		# store output
-+	addi		$out,$out,0x10
-+	vxor		$out0,$in0,$twk2
-+	bne		Lxts_dec6x_steal
-+	b		Lxts_dec6x_done
-+
-+.align	4
-+Lxts_dec6x_zero:
-+	cmpwi		$taillen,0
-+	beq		Lxts_dec6x_done
-+
-+	lvx_u		$in0,0,$inp
-+	le?vperm	$in0,$in0,$in0,$leperm
-+	vxor		$out0,$in0,$twk1
-+Lxts_dec6x_steal:
-+	vncipher	$out0,$out0,v24
-+	lvx		v24,$x20,$key_		# round[3]
-+	addi		$key_,$key_,0x20
-+
-+	vncipher	$out0,$out0,v25
-+	lvx		v25,$x10,$key_		# round[4]
-+	bdnz		Lxts_dec6x_steal
-+
-+	add		$inp,$inp,$taillen
-+	vncipher	$out0,$out0,v24
-+
-+	cmpwi		$taillen,0
-+	vncipher	$out0,$out0,v25
-+
-+	lvx_u		$in0,0,$inp
-+	vncipher	$out0,$out0,v26
-+
-+	lvsr		$inpperm,0,$taillen	# $in5 is no more
-+	vncipher	$out0,$out0,v27
-+
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	vncipher	$out0,$out0,v28
-+	lvx		v24,$x00,$key_		# re-pre-load round[1]
-+
-+	vncipher	$out0,$out0,v29
-+	lvx		v25,$x10,$key_		# re-pre-load round[2]
-+	 vxor		$twk1,$twk1,v31
-+
-+	le?vperm	$in0,$in0,$in0,$leperm
-+	vncipher	$out0,$out0,v30
-+
-+	vperm		$in0,$in0,$in0,$inpperm
-+	vncipherlast	$tmp,$out0,$twk1
-+
-+	le?vperm	$out0,$tmp,$tmp,$leperm
-+	le?stvx_u	$out0,0,$out
-+	be?stvx_u	$tmp,0,$out
-+
-+	vxor		$out0,$out0,$out0
-+	vspltisb	$out1,-1
-+	vperm		$out0,$out0,$out1,$inpperm
-+	vsel		$out0,$in0,$tmp,$out0
-+	vxor		$out0,$out0,$twk0
-+
-+	subi		r30,$out,1
-+	mtctr		$taillen
-+Loop_xts_dec6x_steal:
-+	lbzu		r0,1(r30)
-+	stb		r0,16(r30)
-+	bdnz		Loop_xts_dec6x_steal
-+
-+	li		$taillen,0
-+	mtctr		$rounds
-+	b		Loop_xts_dec1x		# one more time...
-+
-+.align	4
-+Lxts_dec6x_done:
-+	${UCMP}i	$ivp,0
-+	beq		Lxts_dec6x_ret
-+
-+	vxor		$tweak,$twk0,$rndkey0
-+	le?vperm	$tweak,$tweak,$tweak,$leperm
-+	stvx_u		$tweak,0,$ivp
-+
-+Lxts_dec6x_ret:
-+	mtlr		r11
-+	li		r10,`$FRAME+15`
-+	li		r11,`$FRAME+31`
-+	stvx		$seven,r10,$sp		# wipe copies of round keys
-+	addi		r10,r10,32
-+	stvx		$seven,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$seven,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$seven,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$seven,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$seven,r11,$sp
-+	addi		r11,r11,32
-+	stvx		$seven,r10,$sp
-+	addi		r10,r10,32
-+	stvx		$seven,r11,$sp
-+	addi		r11,r11,32
-+
-+	mtspr		256,$vrsave
-+	lvx		v20,r10,$sp		# ABI says so
-+	addi		r10,r10,32
-+	lvx		v21,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v22,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v23,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v24,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v25,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v26,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v27,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v28,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v29,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v30,r10,$sp
-+	lvx		v31,r11,$sp
-+	$POP		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
-+	$POP		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
-+	$POP		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
-+	$POP		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
-+	$POP		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
-+	$POP		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
-+	addi		$sp,$sp,`$FRAME+21*16+6*$SIZE_T`
-+	blr
-+	.long		0
-+	.byte		0,12,0x04,1,0x80,6,6,0
-+	.long		0
-+
-+.align	5
-+_aesp8_xts_dec5x:
-+	vncipher	$out0,$out0,v24
-+	vncipher	$out1,$out1,v24
-+	vncipher	$out2,$out2,v24
-+	vncipher	$out3,$out3,v24
-+	vncipher	$out4,$out4,v24
-+	lvx		v24,$x20,$key_		# round[3]
-+	addi		$key_,$key_,0x20
-+
-+	vncipher	$out0,$out0,v25
-+	vncipher	$out1,$out1,v25
-+	vncipher	$out2,$out2,v25
-+	vncipher	$out3,$out3,v25
-+	vncipher	$out4,$out4,v25
-+	lvx		v25,$x10,$key_		# round[4]
-+	bdnz		_aesp8_xts_dec5x
-+
-+	subi		r0,$taillen,1
-+	vncipher	$out0,$out0,v24
-+	vncipher	$out1,$out1,v24
-+	vncipher	$out2,$out2,v24
-+	vncipher	$out3,$out3,v24
-+	vncipher	$out4,$out4,v24
-+
-+	andi.		r0,r0,16
-+	cmpwi		$taillen,0
-+	vncipher	$out0,$out0,v25
-+	vncipher	$out1,$out1,v25
-+	vncipher	$out2,$out2,v25
-+	vncipher	$out3,$out3,v25
-+	vncipher	$out4,$out4,v25
-+	 vxor		$twk0,$twk0,v31
-+
-+	sub		$inp,$inp,r0
-+	vncipher	$out0,$out0,v26
-+	vncipher	$out1,$out1,v26
-+	vncipher	$out2,$out2,v26
-+	vncipher	$out3,$out3,v26
-+	vncipher	$out4,$out4,v26
-+	 vxor		$in1,$twk1,v31
-+
-+	vncipher	$out0,$out0,v27
-+	lvx_u		$in0,0,$inp
-+	vncipher	$out1,$out1,v27
-+	vncipher	$out2,$out2,v27
-+	vncipher	$out3,$out3,v27
-+	vncipher	$out4,$out4,v27
-+	 vxor		$in2,$twk2,v31
-+
-+	addi		$key_,$sp,$FRAME+15	# rewind $key_
-+	vncipher	$out0,$out0,v28
-+	vncipher	$out1,$out1,v28
-+	vncipher	$out2,$out2,v28
-+	vncipher	$out3,$out3,v28
-+	vncipher	$out4,$out4,v28
-+	lvx		v24,$x00,$key_		# re-pre-load round[1]
-+	 vxor		$in3,$twk3,v31
-+
-+	vncipher	$out0,$out0,v29
-+	le?vperm	$in0,$in0,$in0,$leperm
-+	vncipher	$out1,$out1,v29
-+	vncipher	$out2,$out2,v29
-+	vncipher	$out3,$out3,v29
-+	vncipher	$out4,$out4,v29
-+	lvx		v25,$x10,$key_		# re-pre-load round[2]
-+	 vxor		$in4,$twk4,v31
-+
-+	vncipher	$out0,$out0,v30
-+	vncipher	$out1,$out1,v30
-+	vncipher	$out2,$out2,v30
-+	vncipher	$out3,$out3,v30
-+	vncipher	$out4,$out4,v30
-+
-+	vncipherlast	$out0,$out0,$twk0
-+	vncipherlast	$out1,$out1,$in1
-+	vncipherlast	$out2,$out2,$in2
-+	vncipherlast	$out3,$out3,$in3
-+	vncipherlast	$out4,$out4,$in4
-+	mtctr		$rounds
-+	blr
-+        .long   	0
-+        .byte   	0,12,0x14,0,0,0,0,0
-+___
-+}}	}}}
-+
-+my $consts=1;
-+foreach(split("\n",$code)) {
-+        s/\`([^\`]*)\`/eval($1)/geo;
-+
-+	# constants table endian-specific conversion
-+	if ($consts && m/\.(long|byte)\s+(.+)\s+(\?[a-z]*)$/o) {
-+	    my $conv=$3;
-+	    my @bytes=();
-+
-+	    # convert to endian-agnostic format
-+	    if ($1 eq "long") {
-+	      foreach (split(/,\s*/,$2)) {
-+		my $l = /^0/?oct:int;
-+		push @bytes,($l>>24)&0xff,($l>>16)&0xff,($l>>8)&0xff,$l&0xff;
-+	      }
-+	    } else {
-+		@bytes = map(/^0/?oct:int,split(/,\s*/,$2));
-+	    }
-+
-+	    # little-endian conversion
-+	    if ($flavour =~ /le$/o) {
-+		SWITCH: for($conv)  {
-+		    /\?inv/ && do   { @bytes=map($_^0xf,@bytes); last; };
-+		    /\?rev/ && do   { @bytes=reverse(@bytes);    last; }; 
-+		}
-+	    }
-+
-+	    #emit
-+	    print ".byte\t",join(',',map (sprintf("0x%02x",$_),@bytes)),"\n";
-+	    next;
-+	}
-+	$consts=0 if (m/Lconsts:/o);	# end of table
-+
-+	# instructions prefixed with '?' are endian-specific and need
-+	# to be adjusted accordingly...
-+	if ($flavour =~ /le$/o) {	# little-endian
-+	    s/le\?//o		or
-+	    s/be\?/#be#/o	or
-+	    s/\?lvsr/lvsl/o	or
-+	    s/\?lvsl/lvsr/o	or
-+	    s/\?(vperm\s+v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+)/$1$3$2$4/o or
-+	    s/\?(vsldoi\s+v[0-9]+,\s*)(v[0-9]+,)\s*(v[0-9]+,\s*)([0-9]+)/$1$3$2 16-$4/o or
-+	    s/\?(vspltw\s+v[0-9]+,\s*)(v[0-9]+,)\s*([0-9])/$1$2 3-$3/o;
-+	} else {			# big-endian
-+	    s/le\?/#le#/o	or
-+	    s/be\?//o		or
-+	    s/\?([a-z]+)/$1/o;
-+	}
-+
-+        print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aest4-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aest4-sparcv9.pl
-new file mode 100644
-index 0000000..bf479c6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aest4-sparcv9.pl
-@@ -0,0 +1,929 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by David S. Miller  and Andy Polyakov
-+# . The module is licensed under 2-clause BSD
-+# license. October 2012. All rights reserved.
-+# ====================================================================
-+
-+######################################################################
-+# AES for SPARC T4.
-+#
-+# AES round instructions complete in 3 cycles and can be issued every
-+# cycle. It means that round calculations should take 4*rounds cycles,
-+# because any given round instruction depends on result of *both*
-+# previous instructions:
-+#
-+#	|0 |1 |2 |3 |4
-+#	|01|01|01|
-+#	   |23|23|23|
-+#	            |01|01|...
-+#	               |23|...
-+#
-+# Provided that fxor [with IV] takes 3 cycles to complete, critical
-+# path length for CBC encrypt would be 3+4*rounds, or in other words
-+# it should process one byte in at least (3+4*rounds)/16 cycles. This
-+# estimate doesn't account for "collateral" instructions, such as
-+# fetching input from memory, xor-ing it with zero-round key and
-+# storing the result. Yet, *measured* performance [for data aligned
-+# at 64-bit boundary!] deviates from this equation by less than 0.5%:
-+#
-+#		128-bit key	192-		256-
-+# CBC encrypt	2.70/2.90(*)	3.20/3.40	3.70/3.90
-+#			 (*) numbers after slash are for
-+#			     misaligned data.
-+#
-+# Out-of-order execution logic managed to fully overlap "collateral"
-+# instructions with those on critical path. Amazing!
-+#
-+# As with Intel AES-NI, question is if it's possible to improve
-+# performance of parallelizeable modes by interleaving round
-+# instructions. Provided round instruction latency and throughput
-+# optimal interleave factor is 2. But can we expect 2x performance
-+# improvement? Well, as round instructions can be issued one per
-+# cycle, they don't saturate the 2-way issue pipeline and therefore
-+# there is room for "collateral" calculations... Yet, 2x speed-up
-+# over CBC encrypt remains unattaintable:
-+#
-+#		128-bit key	192-		256-
-+# CBC decrypt	1.64/2.11	1.89/2.37	2.23/2.61
-+# CTR		1.64/2.08(*)	1.89/2.33	2.23/2.61
-+#			 (*) numbers after slash are for
-+#			     misaligned data.
-+#
-+# Estimates based on amount of instructions under assumption that
-+# round instructions are not pairable with any other instruction
-+# suggest that latter is the actual case and pipeline runs
-+# underutilized. It should be noted that T4 out-of-order execution
-+# logic is so capable that performance gain from 2x interleave is
-+# not even impressive, ~7-13% over non-interleaved code, largest
-+# for 256-bit keys.
-+
-+# To anchor to something else, software implementation processes
-+# one byte in 29 cycles with 128-bit key on same processor. Intel
-+# Sandy Bridge encrypts byte in 5.07 cycles in CBC mode and decrypts
-+# in 0.93, naturally with AES-NI.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "sparcv9_modes.pl";
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+$::evp=1;	# if $evp is set to 0, script generates module with
-+# AES_[en|de]crypt, AES_set_[en|de]crypt_key and AES_cbc_encrypt entry
-+# points. These however are not fully compatible with openssl/aes.h,
-+# because they expect AES_KEY to be aligned at 64-bit boundary. When
-+# used through EVP, alignment is arranged at EVP layer. Second thing
-+# that is arranged by EVP is at least 32-bit alignment of IV.
-+
-+######################################################################
-+# single-round subroutines
-+#
-+{
-+my ($inp,$out,$key,$rounds,$tmp,$mask)=map("%o$_",(0..5));
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#ifdef	__arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+#endif
-+
-+.text
-+
-+.globl	aes_t4_encrypt
-+.align	32
-+aes_t4_encrypt:
-+	andcc		$inp, 7, %g1		! is input aligned?
-+	andn		$inp, 7, $inp
-+
-+	ldx		[$key + 0], %g4
-+	ldx		[$key + 8], %g5
-+
-+	ldx		[$inp + 0], %o4
-+	bz,pt		%icc, 1f
-+	ldx		[$inp + 8], %o5
-+	ldx		[$inp + 16], $inp
-+	sll		%g1, 3, %g1
-+	sub		%g0, %g1, %o3
-+	sllx		%o4, %g1, %o4
-+	sllx		%o5, %g1, %g1
-+	srlx		%o5, %o3, %o5
-+	srlx		$inp, %o3, %o3
-+	or		%o5, %o4, %o4
-+	or		%o3, %g1, %o5
-+1:
-+	ld		[$key + 240], $rounds
-+	ldd		[$key + 16], %f12
-+	ldd		[$key + 24], %f14
-+	xor		%g4, %o4, %o4
-+	xor		%g5, %o5, %o5
-+	movxtod		%o4, %f0
-+	movxtod		%o5, %f2
-+	srl		$rounds, 1, $rounds
-+	ldd		[$key + 32], %f16
-+	sub		$rounds, 1, $rounds
-+	ldd		[$key + 40], %f18
-+	add		$key, 48, $key
-+
-+.Lenc:
-+	aes_eround01	%f12, %f0, %f2, %f4
-+	aes_eround23	%f14, %f0, %f2, %f2
-+	ldd		[$key + 0], %f12
-+	ldd		[$key + 8], %f14
-+	sub		$rounds,1,$rounds
-+	aes_eround01	%f16, %f4, %f2, %f0
-+	aes_eround23	%f18, %f4, %f2, %f2
-+	ldd		[$key + 16], %f16
-+	ldd		[$key + 24], %f18
-+	brnz,pt		$rounds, .Lenc
-+	add		$key, 32, $key
-+
-+	andcc		$out, 7, $tmp		! is output aligned?
-+	aes_eround01	%f12, %f0, %f2, %f4
-+	aes_eround23	%f14, %f0, %f2, %f2
-+	aes_eround01_l	%f16, %f4, %f2, %f0
-+	aes_eround23_l	%f18, %f4, %f2, %f2
-+
-+	bnz,pn		%icc, 2f
-+	nop
-+
-+	std		%f0, [$out + 0]
-+	retl
-+	std		%f2, [$out + 8]
-+
-+2:	alignaddrl	$out, %g0, $out
-+	mov		0xff, $mask
-+	srl		$mask, $tmp, $mask
-+
-+	faligndata	%f0, %f0, %f4
-+	faligndata	%f0, %f2, %f6
-+	faligndata	%f2, %f2, %f8
-+
-+	stda		%f4, [$out + $mask]0xc0	! partial store
-+	std		%f6, [$out + 8]
-+	add		$out, 16, $out
-+	orn		%g0, $mask, $mask
-+	retl
-+	stda		%f8, [$out + $mask]0xc0	! partial store
-+.type	aes_t4_encrypt,#function
-+.size	aes_t4_encrypt,.-aes_t4_encrypt
-+
-+.globl	aes_t4_decrypt
-+.align	32
-+aes_t4_decrypt:
-+	andcc		$inp, 7, %g1		! is input aligned?
-+	andn		$inp, 7, $inp
-+
-+	ldx		[$key + 0], %g4
-+	ldx		[$key + 8], %g5
-+
-+	ldx		[$inp + 0], %o4
-+	bz,pt		%icc, 1f
-+	ldx		[$inp + 8], %o5
-+	ldx		[$inp + 16], $inp
-+	sll		%g1, 3, %g1
-+	sub		%g0, %g1, %o3
-+	sllx		%o4, %g1, %o4
-+	sllx		%o5, %g1, %g1
-+	srlx		%o5, %o3, %o5
-+	srlx		$inp, %o3, %o3
-+	or		%o5, %o4, %o4
-+	or		%o3, %g1, %o5
-+1:
-+	ld		[$key + 240], $rounds
-+	ldd		[$key + 16], %f12
-+	ldd		[$key + 24], %f14
-+	xor		%g4, %o4, %o4
-+	xor		%g5, %o5, %o5
-+	movxtod		%o4, %f0
-+	movxtod		%o5, %f2
-+	srl		$rounds, 1, $rounds
-+	ldd		[$key + 32], %f16
-+	sub		$rounds, 1, $rounds
-+	ldd		[$key + 40], %f18
-+	add		$key, 48, $key
-+
-+.Ldec:
-+	aes_dround01	%f12, %f0, %f2, %f4
-+	aes_dround23	%f14, %f0, %f2, %f2
-+	ldd		[$key + 0], %f12
-+	ldd		[$key + 8], %f14
-+	sub		$rounds,1,$rounds
-+	aes_dround01	%f16, %f4, %f2, %f0
-+	aes_dround23	%f18, %f4, %f2, %f2
-+	ldd		[$key + 16], %f16
-+	ldd		[$key + 24], %f18
-+	brnz,pt		$rounds, .Ldec
-+	add		$key, 32, $key
-+
-+	andcc		$out, 7, $tmp		! is output aligned?
-+	aes_dround01	%f12, %f0, %f2, %f4
-+	aes_dround23	%f14, %f0, %f2, %f2
-+	aes_dround01_l	%f16, %f4, %f2, %f0
-+	aes_dround23_l	%f18, %f4, %f2, %f2
-+
-+	bnz,pn		%icc, 2f
-+	nop
-+
-+	std		%f0, [$out + 0]
-+	retl
-+	std		%f2, [$out + 8]
-+
-+2:	alignaddrl	$out, %g0, $out
-+	mov		0xff, $mask
-+	srl		$mask, $tmp, $mask
-+
-+	faligndata	%f0, %f0, %f4
-+	faligndata	%f0, %f2, %f6
-+	faligndata	%f2, %f2, %f8
-+
-+	stda		%f4, [$out + $mask]0xc0	! partial store
-+	std		%f6, [$out + 8]
-+	add		$out, 16, $out
-+	orn		%g0, $mask, $mask
-+	retl
-+	stda		%f8, [$out + $mask]0xc0	! partial store
-+.type	aes_t4_decrypt,#function
-+.size	aes_t4_decrypt,.-aes_t4_decrypt
-+___
-+}
-+
-+######################################################################
-+# key setup subroutines
-+#
-+{
-+my ($inp,$bits,$out,$tmp)=map("%o$_",(0..5));
-+$code.=<<___;
-+.globl	aes_t4_set_encrypt_key
-+.align	32
-+aes_t4_set_encrypt_key:
-+.Lset_encrypt_key:
-+	and		$inp, 7, $tmp
-+	alignaddr	$inp, %g0, $inp
-+	cmp		$bits, 192
-+	ldd		[$inp + 0], %f0
-+	bl,pt		%icc,.L128
-+	ldd		[$inp + 8], %f2
-+
-+	be,pt		%icc,.L192
-+	ldd		[$inp + 16], %f4
-+	brz,pt		$tmp, .L256aligned
-+	ldd		[$inp + 24], %f6
-+
-+	ldd		[$inp + 32], %f8
-+	faligndata	%f0, %f2, %f0
-+	faligndata	%f2, %f4, %f2
-+	faligndata	%f4, %f6, %f4
-+	faligndata	%f6, %f8, %f6
-+.L256aligned:
-+___
-+for ($i=0; $i<6; $i++) {
-+    $code.=<<___;
-+	std		%f0, [$out + `32*$i+0`]
-+	aes_kexpand1	%f0, %f6, $i, %f0
-+	std		%f2, [$out + `32*$i+8`]
-+	aes_kexpand2	%f2, %f0, %f2
-+	std		%f4, [$out + `32*$i+16`]
-+	aes_kexpand0	%f4, %f2, %f4
-+	std		%f6, [$out + `32*$i+24`]
-+	aes_kexpand2	%f6, %f4, %f6
-+___
-+}
-+$code.=<<___;
-+	std		%f0, [$out + `32*$i+0`]
-+	aes_kexpand1	%f0, %f6, $i, %f0
-+	std		%f2, [$out + `32*$i+8`]
-+	aes_kexpand2	%f2, %f0, %f2
-+	std		%f4, [$out + `32*$i+16`]
-+	std		%f6, [$out + `32*$i+24`]
-+	std		%f0, [$out + `32*$i+32`]
-+	std		%f2, [$out + `32*$i+40`]
-+
-+	mov		14, $tmp
-+	st		$tmp, [$out + 240]
-+	retl
-+	xor		%o0, %o0, %o0
-+
-+.align	16
-+.L192:
-+	brz,pt		$tmp, .L192aligned
-+	nop
-+
-+	ldd		[$inp + 24], %f6
-+	faligndata	%f0, %f2, %f0
-+	faligndata	%f2, %f4, %f2
-+	faligndata	%f4, %f6, %f4
-+.L192aligned:
-+___
-+for ($i=0; $i<7; $i++) {
-+    $code.=<<___;
-+	std		%f0, [$out + `24*$i+0`]
-+	aes_kexpand1	%f0, %f4, $i, %f0
-+	std		%f2, [$out + `24*$i+8`]
-+	aes_kexpand2	%f2, %f0, %f2
-+	std		%f4, [$out + `24*$i+16`]
-+	aes_kexpand2	%f4, %f2, %f4
-+___
-+}
-+$code.=<<___;
-+	std		%f0, [$out + `24*$i+0`]
-+	aes_kexpand1	%f0, %f4, $i, %f0
-+	std		%f2, [$out + `24*$i+8`]
-+	aes_kexpand2	%f2, %f0, %f2
-+	std		%f4, [$out + `24*$i+16`]
-+	std		%f0, [$out + `24*$i+24`]
-+	std		%f2, [$out + `24*$i+32`]
-+
-+	mov		12, $tmp
-+	st		$tmp, [$out + 240]
-+	retl
-+	xor		%o0, %o0, %o0
-+
-+.align	16
-+.L128:
-+	brz,pt		$tmp, .L128aligned
-+	nop
-+
-+	ldd		[$inp + 16], %f4
-+	faligndata	%f0, %f2, %f0
-+	faligndata	%f2, %f4, %f2
-+.L128aligned:
-+___
-+for ($i=0; $i<10; $i++) {
-+    $code.=<<___;
-+	std		%f0, [$out + `16*$i+0`]
-+	aes_kexpand1	%f0, %f2, $i, %f0
-+	std		%f2, [$out + `16*$i+8`]
-+	aes_kexpand2	%f2, %f0, %f2
-+___
-+}
-+$code.=<<___;
-+	std		%f0, [$out + `16*$i+0`]
-+	std		%f2, [$out + `16*$i+8`]
-+
-+	mov		10, $tmp
-+	st		$tmp, [$out + 240]
-+	retl
-+	xor		%o0, %o0, %o0
-+.type	aes_t4_set_encrypt_key,#function
-+.size	aes_t4_set_encrypt_key,.-aes_t4_set_encrypt_key
-+
-+.globl	aes_t4_set_decrypt_key
-+.align	32
-+aes_t4_set_decrypt_key:
-+	mov		%o7, %o5
-+	call		.Lset_encrypt_key
-+	nop
-+
-+	mov		%o5, %o7
-+	sll		$tmp, 4, $inp		! $tmp is number of rounds
-+	add		$tmp, 2, $tmp
-+	add		$out, $inp, $inp	! $inp=$out+16*rounds
-+	srl		$tmp, 2, $tmp		! $tmp=(rounds+2)/4
-+
-+.Lkey_flip:
-+	ldd		[$out + 0],  %f0
-+	ldd		[$out + 8],  %f2
-+	ldd		[$out + 16], %f4
-+	ldd		[$out + 24], %f6
-+	ldd		[$inp + 0],  %f8
-+	ldd		[$inp + 8],  %f10
-+	ldd		[$inp - 16], %f12
-+	ldd		[$inp - 8],  %f14
-+	sub		$tmp, 1, $tmp
-+	std		%f0, [$inp + 0]
-+	std		%f2, [$inp + 8]
-+	std		%f4, [$inp - 16]
-+	std		%f6, [$inp - 8]
-+	std		%f8, [$out + 0]
-+	std		%f10, [$out + 8]
-+	std		%f12, [$out + 16]
-+	std		%f14, [$out + 24]
-+	add		$out, 32, $out
-+	brnz		$tmp, .Lkey_flip
-+	sub		$inp, 32, $inp
-+
-+	retl
-+	xor		%o0, %o0, %o0
-+.type	aes_t4_set_decrypt_key,#function
-+.size	aes_t4_set_decrypt_key,.-aes_t4_set_decrypt_key
-+___
-+}
-+
-+{{{
-+my ($inp,$out,$len,$key,$ivec,$enc)=map("%i$_",(0..5));
-+my ($ileft,$iright,$ooff,$omask,$ivoff)=map("%l$_",(1..7));
-+
-+$code.=<<___;
-+.align	32
-+_aes128_encrypt_1x:
-+___
-+for ($i=0; $i<4; $i++) {
-+    $code.=<<___;
-+	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f4
-+	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_eround01	%f`16+8*$i+4`, %f4, %f2, %f0
-+	aes_eround23	%f`16+8*$i+6`, %f4, %f2, %f2
-+___
-+}
-+$code.=<<___;
-+	aes_eround01	%f48, %f0, %f2, %f4
-+	aes_eround23	%f50, %f0, %f2, %f2
-+	aes_eround01_l	%f52, %f4, %f2, %f0
-+	retl
-+	aes_eround23_l	%f54, %f4, %f2, %f2
-+.type	_aes128_encrypt_1x,#function
-+.size	_aes128_encrypt_1x,.-_aes128_encrypt_1x
-+
-+.align	32
-+_aes128_encrypt_2x:
-+___
-+for ($i=0; $i<4; $i++) {
-+    $code.=<<___;
-+	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f8
-+	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_eround01	%f`16+8*$i+0`, %f4, %f6, %f10
-+	aes_eround23	%f`16+8*$i+2`, %f4, %f6, %f6
-+	aes_eround01	%f`16+8*$i+4`, %f8, %f2, %f0
-+	aes_eround23	%f`16+8*$i+6`, %f8, %f2, %f2
-+	aes_eround01	%f`16+8*$i+4`, %f10, %f6, %f4
-+	aes_eround23	%f`16+8*$i+6`, %f10, %f6, %f6
-+___
-+}
-+$code.=<<___;
-+	aes_eround01	%f48, %f0, %f2, %f8
-+	aes_eround23	%f50, %f0, %f2, %f2
-+	aes_eround01	%f48, %f4, %f6, %f10
-+	aes_eround23	%f50, %f4, %f6, %f6
-+	aes_eround01_l	%f52, %f8, %f2, %f0
-+	aes_eround23_l	%f54, %f8, %f2, %f2
-+	aes_eround01_l	%f52, %f10, %f6, %f4
-+	retl
-+	aes_eround23_l	%f54, %f10, %f6, %f6
-+.type	_aes128_encrypt_2x,#function
-+.size	_aes128_encrypt_2x,.-_aes128_encrypt_2x
-+
-+.align	32
-+_aes128_loadkey:
-+	ldx		[$key + 0], %g4
-+	ldx		[$key + 8], %g5
-+___
-+for ($i=2; $i<22;$i++) {			# load key schedule
-+    $code.=<<___;
-+	ldd		[$key + `8*$i`], %f`12+2*$i`
-+___
-+}
-+$code.=<<___;
-+	retl
-+	nop
-+.type	_aes128_loadkey,#function
-+.size	_aes128_loadkey,.-_aes128_loadkey
-+_aes128_load_enckey=_aes128_loadkey
-+_aes128_load_deckey=_aes128_loadkey
-+
-+___
-+
-+&alg_cbc_encrypt_implement("aes",128);
-+if ($::evp) {
-+    &alg_ctr32_implement("aes",128);
-+    &alg_xts_implement("aes",128,"en");
-+    &alg_xts_implement("aes",128,"de");
-+}
-+&alg_cbc_decrypt_implement("aes",128);
-+
-+$code.=<<___;
-+.align	32
-+_aes128_decrypt_1x:
-+___
-+for ($i=0; $i<4; $i++) {
-+    $code.=<<___;
-+	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f4
-+	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_dround01	%f`16+8*$i+4`, %f4, %f2, %f0
-+	aes_dround23	%f`16+8*$i+6`, %f4, %f2, %f2
-+___
-+}
-+$code.=<<___;
-+	aes_dround01	%f48, %f0, %f2, %f4
-+	aes_dround23	%f50, %f0, %f2, %f2
-+	aes_dround01_l	%f52, %f4, %f2, %f0
-+	retl
-+	aes_dround23_l	%f54, %f4, %f2, %f2
-+.type	_aes128_decrypt_1x,#function
-+.size	_aes128_decrypt_1x,.-_aes128_decrypt_1x
-+
-+.align	32
-+_aes128_decrypt_2x:
-+___
-+for ($i=0; $i<4; $i++) {
-+    $code.=<<___;
-+	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f8
-+	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_dround01	%f`16+8*$i+0`, %f4, %f6, %f10
-+	aes_dround23	%f`16+8*$i+2`, %f4, %f6, %f6
-+	aes_dround01	%f`16+8*$i+4`, %f8, %f2, %f0
-+	aes_dround23	%f`16+8*$i+6`, %f8, %f2, %f2
-+	aes_dround01	%f`16+8*$i+4`, %f10, %f6, %f4
-+	aes_dround23	%f`16+8*$i+6`, %f10, %f6, %f6
-+___
-+}
-+$code.=<<___;
-+	aes_dround01	%f48, %f0, %f2, %f8
-+	aes_dround23	%f50, %f0, %f2, %f2
-+	aes_dround01	%f48, %f4, %f6, %f10
-+	aes_dround23	%f50, %f4, %f6, %f6
-+	aes_dround01_l	%f52, %f8, %f2, %f0
-+	aes_dround23_l	%f54, %f8, %f2, %f2
-+	aes_dround01_l	%f52, %f10, %f6, %f4
-+	retl
-+	aes_dround23_l	%f54, %f10, %f6, %f6
-+.type	_aes128_decrypt_2x,#function
-+.size	_aes128_decrypt_2x,.-_aes128_decrypt_2x
-+___
-+
-+$code.=<<___;
-+.align	32
-+_aes192_encrypt_1x:
-+___
-+for ($i=0; $i<5; $i++) {
-+    $code.=<<___;
-+	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f4
-+	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_eround01	%f`16+8*$i+4`, %f4, %f2, %f0
-+	aes_eround23	%f`16+8*$i+6`, %f4, %f2, %f2
-+___
-+}
-+$code.=<<___;
-+	aes_eround01	%f56, %f0, %f2, %f4
-+	aes_eround23	%f58, %f0, %f2, %f2
-+	aes_eround01_l	%f60, %f4, %f2, %f0
-+	retl
-+	aes_eround23_l	%f62, %f4, %f2, %f2
-+.type	_aes192_encrypt_1x,#function
-+.size	_aes192_encrypt_1x,.-_aes192_encrypt_1x
-+
-+.align	32
-+_aes192_encrypt_2x:
-+___
-+for ($i=0; $i<5; $i++) {
-+    $code.=<<___;
-+	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f8
-+	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_eround01	%f`16+8*$i+0`, %f4, %f6, %f10
-+	aes_eround23	%f`16+8*$i+2`, %f4, %f6, %f6
-+	aes_eround01	%f`16+8*$i+4`, %f8, %f2, %f0
-+	aes_eround23	%f`16+8*$i+6`, %f8, %f2, %f2
-+	aes_eround01	%f`16+8*$i+4`, %f10, %f6, %f4
-+	aes_eround23	%f`16+8*$i+6`, %f10, %f6, %f6
-+___
-+}
-+$code.=<<___;
-+	aes_eround01	%f56, %f0, %f2, %f8
-+	aes_eround23	%f58, %f0, %f2, %f2
-+	aes_eround01	%f56, %f4, %f6, %f10
-+	aes_eround23	%f58, %f4, %f6, %f6
-+	aes_eround01_l	%f60, %f8, %f2, %f0
-+	aes_eround23_l	%f62, %f8, %f2, %f2
-+	aes_eround01_l	%f60, %f10, %f6, %f4
-+	retl
-+	aes_eround23_l	%f62, %f10, %f6, %f6
-+.type	_aes192_encrypt_2x,#function
-+.size	_aes192_encrypt_2x,.-_aes192_encrypt_2x
-+
-+.align	32
-+_aes256_encrypt_1x:
-+	aes_eround01	%f16, %f0, %f2, %f4
-+	aes_eround23	%f18, %f0, %f2, %f2
-+	ldd		[$key + 208], %f16
-+	ldd		[$key + 216], %f18
-+	aes_eround01	%f20, %f4, %f2, %f0
-+	aes_eround23	%f22, %f4, %f2, %f2
-+	ldd		[$key + 224], %f20
-+	ldd		[$key + 232], %f22
-+___
-+for ($i=1; $i<6; $i++) {
-+    $code.=<<___;
-+	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f4
-+	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_eround01	%f`16+8*$i+4`, %f4, %f2, %f0
-+	aes_eround23	%f`16+8*$i+6`, %f4, %f2, %f2
-+___
-+}
-+$code.=<<___;
-+	aes_eround01	%f16, %f0, %f2, %f4
-+	aes_eround23	%f18, %f0, %f2, %f2
-+	ldd		[$key + 16], %f16
-+	ldd		[$key + 24], %f18
-+	aes_eround01_l	%f20, %f4, %f2, %f0
-+	aes_eround23_l	%f22, %f4, %f2, %f2
-+	ldd		[$key + 32], %f20
-+	retl
-+	ldd		[$key + 40], %f22
-+.type	_aes256_encrypt_1x,#function
-+.size	_aes256_encrypt_1x,.-_aes256_encrypt_1x
-+
-+.align	32
-+_aes256_encrypt_2x:
-+	aes_eround01	%f16, %f0, %f2, %f8
-+	aes_eround23	%f18, %f0, %f2, %f2
-+	aes_eround01	%f16, %f4, %f6, %f10
-+	aes_eround23	%f18, %f4, %f6, %f6
-+	ldd		[$key + 208], %f16
-+	ldd		[$key + 216], %f18
-+	aes_eround01	%f20, %f8, %f2, %f0
-+	aes_eround23	%f22, %f8, %f2, %f2
-+	aes_eround01	%f20, %f10, %f6, %f4
-+	aes_eround23	%f22, %f10, %f6, %f6
-+	ldd		[$key + 224], %f20
-+	ldd		[$key + 232], %f22
-+___
-+for ($i=1; $i<6; $i++) {
-+    $code.=<<___;
-+	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f8
-+	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_eround01	%f`16+8*$i+0`, %f4, %f6, %f10
-+	aes_eround23	%f`16+8*$i+2`, %f4, %f6, %f6
-+	aes_eround01	%f`16+8*$i+4`, %f8, %f2, %f0
-+	aes_eround23	%f`16+8*$i+6`, %f8, %f2, %f2
-+	aes_eround01	%f`16+8*$i+4`, %f10, %f6, %f4
-+	aes_eround23	%f`16+8*$i+6`, %f10, %f6, %f6
-+___
-+}
-+$code.=<<___;
-+	aes_eround01	%f16, %f0, %f2, %f8
-+	aes_eround23	%f18, %f0, %f2, %f2
-+	aes_eround01	%f16, %f4, %f6, %f10
-+	aes_eround23	%f18, %f4, %f6, %f6
-+	ldd		[$key + 16], %f16
-+	ldd		[$key + 24], %f18
-+	aes_eround01_l	%f20, %f8, %f2, %f0
-+	aes_eround23_l	%f22, %f8, %f2, %f2
-+	aes_eround01_l	%f20, %f10, %f6, %f4
-+	aes_eround23_l	%f22, %f10, %f6, %f6
-+	ldd		[$key + 32], %f20
-+	retl
-+	ldd		[$key + 40], %f22
-+.type	_aes256_encrypt_2x,#function
-+.size	_aes256_encrypt_2x,.-_aes256_encrypt_2x
-+
-+.align	32
-+_aes192_loadkey:
-+	ldx		[$key + 0], %g4
-+	ldx		[$key + 8], %g5
-+___
-+for ($i=2; $i<26;$i++) {			# load key schedule
-+    $code.=<<___;
-+	ldd		[$key + `8*$i`], %f`12+2*$i`
-+___
-+}
-+$code.=<<___;
-+	retl
-+	nop
-+.type	_aes192_loadkey,#function
-+.size	_aes192_loadkey,.-_aes192_loadkey
-+_aes256_loadkey=_aes192_loadkey
-+_aes192_load_enckey=_aes192_loadkey
-+_aes192_load_deckey=_aes192_loadkey
-+_aes256_load_enckey=_aes192_loadkey
-+_aes256_load_deckey=_aes192_loadkey
-+___
-+
-+&alg_cbc_encrypt_implement("aes",256);
-+&alg_cbc_encrypt_implement("aes",192);
-+if ($::evp) {
-+    &alg_ctr32_implement("aes",256);
-+    &alg_xts_implement("aes",256,"en");
-+    &alg_xts_implement("aes",256,"de");
-+    &alg_ctr32_implement("aes",192);
-+}
-+&alg_cbc_decrypt_implement("aes",192);
-+&alg_cbc_decrypt_implement("aes",256);
-+
-+$code.=<<___;
-+.align	32
-+_aes256_decrypt_1x:
-+	aes_dround01	%f16, %f0, %f2, %f4
-+	aes_dround23	%f18, %f0, %f2, %f2
-+	ldd		[$key + 208], %f16
-+	ldd		[$key + 216], %f18
-+	aes_dround01	%f20, %f4, %f2, %f0
-+	aes_dround23	%f22, %f4, %f2, %f2
-+	ldd		[$key + 224], %f20
-+	ldd		[$key + 232], %f22
-+___
-+for ($i=1; $i<6; $i++) {
-+    $code.=<<___;
-+	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f4
-+	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_dround01	%f`16+8*$i+4`, %f4, %f2, %f0
-+	aes_dround23	%f`16+8*$i+6`, %f4, %f2, %f2
-+___
-+}
-+$code.=<<___;
-+	aes_dround01	%f16, %f0, %f2, %f4
-+	aes_dround23	%f18, %f0, %f2, %f2
-+	ldd		[$key + 16], %f16
-+	ldd		[$key + 24], %f18
-+	aes_dround01_l	%f20, %f4, %f2, %f0
-+	aes_dround23_l	%f22, %f4, %f2, %f2
-+	ldd		[$key + 32], %f20
-+	retl
-+	ldd		[$key + 40], %f22
-+.type	_aes256_decrypt_1x,#function
-+.size	_aes256_decrypt_1x,.-_aes256_decrypt_1x
-+
-+.align	32
-+_aes256_decrypt_2x:
-+	aes_dround01	%f16, %f0, %f2, %f8
-+	aes_dround23	%f18, %f0, %f2, %f2
-+	aes_dround01	%f16, %f4, %f6, %f10
-+	aes_dround23	%f18, %f4, %f6, %f6
-+	ldd		[$key + 208], %f16
-+	ldd		[$key + 216], %f18
-+	aes_dround01	%f20, %f8, %f2, %f0
-+	aes_dround23	%f22, %f8, %f2, %f2
-+	aes_dround01	%f20, %f10, %f6, %f4
-+	aes_dround23	%f22, %f10, %f6, %f6
-+	ldd		[$key + 224], %f20
-+	ldd		[$key + 232], %f22
-+___
-+for ($i=1; $i<6; $i++) {
-+    $code.=<<___;
-+	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f8
-+	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_dround01	%f`16+8*$i+0`, %f4, %f6, %f10
-+	aes_dround23	%f`16+8*$i+2`, %f4, %f6, %f6
-+	aes_dround01	%f`16+8*$i+4`, %f8, %f2, %f0
-+	aes_dround23	%f`16+8*$i+6`, %f8, %f2, %f2
-+	aes_dround01	%f`16+8*$i+4`, %f10, %f6, %f4
-+	aes_dround23	%f`16+8*$i+6`, %f10, %f6, %f6
-+___
-+}
-+$code.=<<___;
-+	aes_dround01	%f16, %f0, %f2, %f8
-+	aes_dround23	%f18, %f0, %f2, %f2
-+	aes_dround01	%f16, %f4, %f6, %f10
-+	aes_dround23	%f18, %f4, %f6, %f6
-+	ldd		[$key + 16], %f16
-+	ldd		[$key + 24], %f18
-+	aes_dround01_l	%f20, %f8, %f2, %f0
-+	aes_dround23_l	%f22, %f8, %f2, %f2
-+	aes_dround01_l	%f20, %f10, %f6, %f4
-+	aes_dround23_l	%f22, %f10, %f6, %f6
-+	ldd		[$key + 32], %f20
-+	retl
-+	ldd		[$key + 40], %f22
-+.type	_aes256_decrypt_2x,#function
-+.size	_aes256_decrypt_2x,.-_aes256_decrypt_2x
-+
-+.align	32
-+_aes192_decrypt_1x:
-+___
-+for ($i=0; $i<5; $i++) {
-+    $code.=<<___;
-+	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f4
-+	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_dround01	%f`16+8*$i+4`, %f4, %f2, %f0
-+	aes_dround23	%f`16+8*$i+6`, %f4, %f2, %f2
-+___
-+}
-+$code.=<<___;
-+	aes_dround01	%f56, %f0, %f2, %f4
-+	aes_dround23	%f58, %f0, %f2, %f2
-+	aes_dround01_l	%f60, %f4, %f2, %f0
-+	retl
-+	aes_dround23_l	%f62, %f4, %f2, %f2
-+.type	_aes192_decrypt_1x,#function
-+.size	_aes192_decrypt_1x,.-_aes192_decrypt_1x
-+
-+.align	32
-+_aes192_decrypt_2x:
-+___
-+for ($i=0; $i<5; $i++) {
-+    $code.=<<___;
-+	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f8
-+	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-+	aes_dround01	%f`16+8*$i+0`, %f4, %f6, %f10
-+	aes_dround23	%f`16+8*$i+2`, %f4, %f6, %f6
-+	aes_dround01	%f`16+8*$i+4`, %f8, %f2, %f0
-+	aes_dround23	%f`16+8*$i+6`, %f8, %f2, %f2
-+	aes_dround01	%f`16+8*$i+4`, %f10, %f6, %f4
-+	aes_dround23	%f`16+8*$i+6`, %f10, %f6, %f6
-+___
-+}
-+$code.=<<___;
-+	aes_dround01	%f56, %f0, %f2, %f8
-+	aes_dround23	%f58, %f0, %f2, %f2
-+	aes_dround01	%f56, %f4, %f6, %f10
-+	aes_dround23	%f58, %f4, %f6, %f6
-+	aes_dround01_l	%f60, %f8, %f2, %f0
-+	aes_dround23_l	%f62, %f8, %f2, %f2
-+	aes_dround01_l	%f60, %f10, %f6, %f4
-+	retl
-+	aes_dround23_l	%f62, %f10, %f6, %f6
-+.type	_aes192_decrypt_2x,#function
-+.size	_aes192_decrypt_2x,.-_aes192_decrypt_2x
-+___
-+}}}
-+
-+if (!$::evp) {
-+$code.=<<___;
-+.global	AES_encrypt
-+AES_encrypt=aes_t4_encrypt
-+.global	AES_decrypt
-+AES_decrypt=aes_t4_decrypt
-+.global	AES_set_encrypt_key
-+.align	32
-+AES_set_encrypt_key:
-+	andcc		%o2, 7, %g0		! check alignment
-+	bnz,a,pn	%icc, 1f
-+	mov		-1, %o0
-+	brz,a,pn	%o0, 1f
-+	mov		-1, %o0
-+	brz,a,pn	%o2, 1f
-+	mov		-1, %o0
-+	andncc		%o1, 0x1c0, %g0
-+	bnz,a,pn	%icc, 1f
-+	mov		-2, %o0
-+	cmp		%o1, 128
-+	bl,a,pn		%icc, 1f
-+	mov		-2, %o0
-+	b		aes_t4_set_encrypt_key
-+	nop
-+1:	retl
-+	nop
-+.type	AES_set_encrypt_key,#function
-+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
-+
-+.global	AES_set_decrypt_key
-+.align	32
-+AES_set_decrypt_key:
-+	andcc		%o2, 7, %g0		! check alignment
-+	bnz,a,pn	%icc, 1f
-+	mov		-1, %o0
-+	brz,a,pn	%o0, 1f
-+	mov		-1, %o0
-+	brz,a,pn	%o2, 1f
-+	mov		-1, %o0
-+	andncc		%o1, 0x1c0, %g0
-+	bnz,a,pn	%icc, 1f
-+	mov		-2, %o0
-+	cmp		%o1, 128
-+	bl,a,pn		%icc, 1f
-+	mov		-2, %o0
-+	b		aes_t4_set_decrypt_key
-+	nop
-+1:	retl
-+	nop
-+.type	AES_set_decrypt_key,#function
-+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
-+___
-+
-+my ($inp,$out,$len,$key,$ivec,$enc)=map("%o$_",(0..5));
-+
-+$code.=<<___;
-+.globl	AES_cbc_encrypt
-+.align	32
-+AES_cbc_encrypt:
-+	ld		[$key + 240], %g1
-+	nop
-+	brz		$enc, .Lcbc_decrypt
-+	cmp		%g1, 12
-+
-+	bl,pt		%icc, aes128_t4_cbc_encrypt
-+	nop
-+	be,pn		%icc, aes192_t4_cbc_encrypt
-+	nop
-+	ba		aes256_t4_cbc_encrypt
-+	nop
-+
-+.Lcbc_decrypt:
-+	bl,pt		%icc, aes128_t4_cbc_decrypt
-+	nop
-+	be,pn		%icc, aes192_t4_cbc_decrypt
-+	nop
-+	ba		aes256_t4_cbc_decrypt
-+	nop
-+.type	AES_cbc_encrypt,#function
-+.size	AES_cbc_encrypt,.-AES_cbc_encrypt
-+___
-+}
-+$code.=<<___;
-+.asciz	"AES for SPARC T4, David S. Miller, Andy Polyakov"
-+.align	4
-+___
-+
-+&emit_assembler();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesv8-armx.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesv8-armx.pl
-new file mode 100755
-index 0000000..1782d5b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/aesv8-armx.pl
-@@ -0,0 +1,1008 @@
-+#! /usr/bin/env perl
-+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements support for ARMv8 AES instructions. The
-+# module is endian-agnostic in sense that it supports both big- and
-+# little-endian cases. As does it support both 32- and 64-bit modes
-+# of operation. Latter is achieved by limiting amount of utilized
-+# registers to 16, which implies additional NEON load and integer
-+# instructions. This has no effect on mighty Apple A7, where results
-+# are literally equal to the theoretical estimates based on AES
-+# instruction latencies and issue rates. On Cortex-A53, an in-order
-+# execution core, this costs up to 10-15%, which is partially
-+# compensated by implementing dedicated code path for 128-bit
-+# CBC encrypt case. On Cortex-A57 parallelizable mode performance
-+# seems to be limited by sheer amount of NEON instructions...
-+#
-+# Performance in cycles per byte processed with 128-bit key:
-+#
-+#		CBC enc		CBC dec		CTR
-+# Apple A7	2.39		1.20		1.20
-+# Cortex-A53	1.32		1.29		1.46
-+# Cortex-A57(*)	1.95		0.85		0.93
-+# Denver	1.96		0.86		0.80
-+# Mongoose	1.33		1.20		1.20
-+#
-+# (*)	original 3.64/1.34/1.32 results were for r0p0 revision
-+#	and are still same even for updated module;
-+
-+$flavour = shift;
-+$output  = shift;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+$prefix="aes_v8";
-+
-+$code=<<___;
-+#include "arm_arch.h"
-+
-+#if __ARM_MAX_ARCH__>=7
-+.text
-+___
-+$code.=".arch	armv8-a+crypto\n"			if ($flavour =~ /64/);
-+$code.=<<___						if ($flavour !~ /64/);
-+.arch	armv7-a	// don't confuse not-so-latest binutils with argv8 :-)
-+.fpu	neon
-+.code	32
-+#undef	__thumb2__
-+___
-+
-+# Assembler mnemonics are an eclectic mix of 32- and 64-bit syntax,
-+# NEON is mostly 32-bit mnemonics, integer - mostly 64. Goal is to
-+# maintain both 32- and 64-bit codes within single module and
-+# transliterate common code to either flavour with regex vodoo.
-+#
-+{{{
-+my ($inp,$bits,$out,$ptr,$rounds)=("x0","w1","x2","x3","w12");
-+my ($zero,$rcon,$mask,$in0,$in1,$tmp,$key)=
-+	$flavour=~/64/? map("q$_",(0..6)) : map("q$_",(0..3,8..10));
-+
-+
-+$code.=<<___;
-+.align	5
-+.Lrcon:
-+.long	0x01,0x01,0x01,0x01
-+.long	0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d	// rotate-n-splat
-+.long	0x1b,0x1b,0x1b,0x1b
-+
-+.globl	${prefix}_set_encrypt_key
-+.type	${prefix}_set_encrypt_key,%function
-+.align	5
-+${prefix}_set_encrypt_key:
-+.Lenc_key:
-+___
-+$code.=<<___	if ($flavour =~ /64/);
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+___
-+$code.=<<___;
-+	mov	$ptr,#-1
-+	cmp	$inp,#0
-+	b.eq	.Lenc_key_abort
-+	cmp	$out,#0
-+	b.eq	.Lenc_key_abort
-+	mov	$ptr,#-2
-+	cmp	$bits,#128
-+	b.lt	.Lenc_key_abort
-+	cmp	$bits,#256
-+	b.gt	.Lenc_key_abort
-+	tst	$bits,#0x3f
-+	b.ne	.Lenc_key_abort
-+
-+	adr	$ptr,.Lrcon
-+	cmp	$bits,#192
-+
-+	veor	$zero,$zero,$zero
-+	vld1.8	{$in0},[$inp],#16
-+	mov	$bits,#8		// reuse $bits
-+	vld1.32	{$rcon,$mask},[$ptr],#32
-+
-+	b.lt	.Loop128
-+	b.eq	.L192
-+	b	.L256
-+
-+.align	4
-+.Loop128:
-+	vtbl.8	$key,{$in0},$mask
-+	vext.8	$tmp,$zero,$in0,#12
-+	vst1.32	{$in0},[$out],#16
-+	aese	$key,$zero
-+	subs	$bits,$bits,#1
-+
-+	veor	$in0,$in0,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	veor	$in0,$in0,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	 veor	$key,$key,$rcon
-+	veor	$in0,$in0,$tmp
-+	vshl.u8	$rcon,$rcon,#1
-+	veor	$in0,$in0,$key
-+	b.ne	.Loop128
-+
-+	vld1.32	{$rcon},[$ptr]
-+
-+	vtbl.8	$key,{$in0},$mask
-+	vext.8	$tmp,$zero,$in0,#12
-+	vst1.32	{$in0},[$out],#16
-+	aese	$key,$zero
-+
-+	veor	$in0,$in0,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	veor	$in0,$in0,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	 veor	$key,$key,$rcon
-+	veor	$in0,$in0,$tmp
-+	vshl.u8	$rcon,$rcon,#1
-+	veor	$in0,$in0,$key
-+
-+	vtbl.8	$key,{$in0},$mask
-+	vext.8	$tmp,$zero,$in0,#12
-+	vst1.32	{$in0},[$out],#16
-+	aese	$key,$zero
-+
-+	veor	$in0,$in0,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	veor	$in0,$in0,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	 veor	$key,$key,$rcon
-+	veor	$in0,$in0,$tmp
-+	veor	$in0,$in0,$key
-+	vst1.32	{$in0},[$out]
-+	add	$out,$out,#0x50
-+
-+	mov	$rounds,#10
-+	b	.Ldone
-+
-+.align	4
-+.L192:
-+	vld1.8	{$in1},[$inp],#8
-+	vmov.i8	$key,#8			// borrow $key
-+	vst1.32	{$in0},[$out],#16
-+	vsub.i8	$mask,$mask,$key	// adjust the mask
-+
-+.Loop192:
-+	vtbl.8	$key,{$in1},$mask
-+	vext.8	$tmp,$zero,$in0,#12
-+	vst1.32	{$in1},[$out],#8
-+	aese	$key,$zero
-+	subs	$bits,$bits,#1
-+
-+	veor	$in0,$in0,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	veor	$in0,$in0,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	veor	$in0,$in0,$tmp
-+
-+	vdup.32	$tmp,${in0}[3]
-+	veor	$tmp,$tmp,$in1
-+	 veor	$key,$key,$rcon
-+	vext.8	$in1,$zero,$in1,#12
-+	vshl.u8	$rcon,$rcon,#1
-+	veor	$in1,$in1,$tmp
-+	veor	$in0,$in0,$key
-+	veor	$in1,$in1,$key
-+	vst1.32	{$in0},[$out],#16
-+	b.ne	.Loop192
-+
-+	mov	$rounds,#12
-+	add	$out,$out,#0x20
-+	b	.Ldone
-+
-+.align	4
-+.L256:
-+	vld1.8	{$in1},[$inp]
-+	mov	$bits,#7
-+	mov	$rounds,#14
-+	vst1.32	{$in0},[$out],#16
-+
-+.Loop256:
-+	vtbl.8	$key,{$in1},$mask
-+	vext.8	$tmp,$zero,$in0,#12
-+	vst1.32	{$in1},[$out],#16
-+	aese	$key,$zero
-+	subs	$bits,$bits,#1
-+
-+	veor	$in0,$in0,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	veor	$in0,$in0,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	 veor	$key,$key,$rcon
-+	veor	$in0,$in0,$tmp
-+	vshl.u8	$rcon,$rcon,#1
-+	veor	$in0,$in0,$key
-+	vst1.32	{$in0},[$out],#16
-+	b.eq	.Ldone
-+
-+	vdup.32	$key,${in0}[3]		// just splat
-+	vext.8	$tmp,$zero,$in1,#12
-+	aese	$key,$zero
-+
-+	veor	$in1,$in1,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	veor	$in1,$in1,$tmp
-+	vext.8	$tmp,$zero,$tmp,#12
-+	veor	$in1,$in1,$tmp
-+
-+	veor	$in1,$in1,$key
-+	b	.Loop256
-+
-+.Ldone:
-+	str	$rounds,[$out]
-+	mov	$ptr,#0
-+
-+.Lenc_key_abort:
-+	mov	x0,$ptr			// return value
-+	`"ldr	x29,[sp],#16"		if ($flavour =~ /64/)`
-+	ret
-+.size	${prefix}_set_encrypt_key,.-${prefix}_set_encrypt_key
-+
-+.globl	${prefix}_set_decrypt_key
-+.type	${prefix}_set_decrypt_key,%function
-+.align	5
-+${prefix}_set_decrypt_key:
-+___
-+$code.=<<___	if ($flavour =~ /64/);
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+___
-+$code.=<<___	if ($flavour !~ /64/);
-+	stmdb	sp!,{r4,lr}
-+___
-+$code.=<<___;
-+	bl	.Lenc_key
-+
-+	cmp	x0,#0
-+	b.ne	.Ldec_key_abort
-+
-+	sub	$out,$out,#240		// restore original $out
-+	mov	x4,#-16
-+	add	$inp,$out,x12,lsl#4	// end of key schedule
-+
-+	vld1.32	{v0.16b},[$out]
-+	vld1.32	{v1.16b},[$inp]
-+	vst1.32	{v0.16b},[$inp],x4
-+	vst1.32	{v1.16b},[$out],#16
-+
-+.Loop_imc:
-+	vld1.32	{v0.16b},[$out]
-+	vld1.32	{v1.16b},[$inp]
-+	aesimc	v0.16b,v0.16b
-+	aesimc	v1.16b,v1.16b
-+	vst1.32	{v0.16b},[$inp],x4
-+	vst1.32	{v1.16b},[$out],#16
-+	cmp	$inp,$out
-+	b.hi	.Loop_imc
-+
-+	vld1.32	{v0.16b},[$out]
-+	aesimc	v0.16b,v0.16b
-+	vst1.32	{v0.16b},[$inp]
-+
-+	eor	x0,x0,x0		// return value
-+.Ldec_key_abort:
-+___
-+$code.=<<___	if ($flavour !~ /64/);
-+	ldmia	sp!,{r4,pc}
-+___
-+$code.=<<___	if ($flavour =~ /64/);
-+	ldp	x29,x30,[sp],#16
-+	ret
-+___
-+$code.=<<___;
-+.size	${prefix}_set_decrypt_key,.-${prefix}_set_decrypt_key
-+___
-+}}}
-+{{{
-+sub gen_block () {
-+my $dir = shift;
-+my ($e,$mc) = $dir eq "en" ? ("e","mc") : ("d","imc");
-+my ($inp,$out,$key)=map("x$_",(0..2));
-+my $rounds="w3";
-+my ($rndkey0,$rndkey1,$inout)=map("q$_",(0..3));
-+
-+$code.=<<___;
-+.globl	${prefix}_${dir}crypt
-+.type	${prefix}_${dir}crypt,%function
-+.align	5
-+${prefix}_${dir}crypt:
-+	ldr	$rounds,[$key,#240]
-+	vld1.32	{$rndkey0},[$key],#16
-+	vld1.8	{$inout},[$inp]
-+	sub	$rounds,$rounds,#2
-+	vld1.32	{$rndkey1},[$key],#16
-+
-+.Loop_${dir}c:
-+	aes$e	$inout,$rndkey0
-+	aes$mc	$inout,$inout
-+	vld1.32	{$rndkey0},[$key],#16
-+	subs	$rounds,$rounds,#2
-+	aes$e	$inout,$rndkey1
-+	aes$mc	$inout,$inout
-+	vld1.32	{$rndkey1},[$key],#16
-+	b.gt	.Loop_${dir}c
-+
-+	aes$e	$inout,$rndkey0
-+	aes$mc	$inout,$inout
-+	vld1.32	{$rndkey0},[$key]
-+	aes$e	$inout,$rndkey1
-+	veor	$inout,$inout,$rndkey0
-+
-+	vst1.8	{$inout},[$out]
-+	ret
-+.size	${prefix}_${dir}crypt,.-${prefix}_${dir}crypt
-+___
-+}
-+&gen_block("en");
-+&gen_block("de");
-+}}}
-+{{{
-+my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4)); my $enc="w5";
-+my ($rounds,$cnt,$key_,$step,$step1)=($enc,"w6","x7","x8","x12");
-+my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$ivec,$rndlast)=map("q$_",(0..7));
-+
-+my ($dat,$tmp,$rndzero_n_last)=($dat0,$tmp0,$tmp1);
-+my ($key4,$key5,$key6,$key7)=("x6","x12","x14",$key);
-+
-+### q8-q15	preloaded key schedule
-+
-+$code.=<<___;
-+.globl	${prefix}_cbc_encrypt
-+.type	${prefix}_cbc_encrypt,%function
-+.align	5
-+${prefix}_cbc_encrypt:
-+___
-+$code.=<<___	if ($flavour =~ /64/);
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+___
-+$code.=<<___	if ($flavour !~ /64/);
-+	mov	ip,sp
-+	stmdb	sp!,{r4-r8,lr}
-+	vstmdb	sp!,{d8-d15}            @ ABI specification says so
-+	ldmia	ip,{r4-r5}		@ load remaining args
-+___
-+$code.=<<___;
-+	subs	$len,$len,#16
-+	mov	$step,#16
-+	b.lo	.Lcbc_abort
-+	cclr	$step,eq
-+
-+	cmp	$enc,#0			// en- or decrypting?
-+	ldr	$rounds,[$key,#240]
-+	and	$len,$len,#-16
-+	vld1.8	{$ivec},[$ivp]
-+	vld1.8	{$dat},[$inp],$step
-+
-+	vld1.32	{q8-q9},[$key]		// load key schedule...
-+	sub	$rounds,$rounds,#6
-+	add	$key_,$key,x5,lsl#4	// pointer to last 7 round keys
-+	sub	$rounds,$rounds,#2
-+	vld1.32	{q10-q11},[$key_],#32
-+	vld1.32	{q12-q13},[$key_],#32
-+	vld1.32	{q14-q15},[$key_],#32
-+	vld1.32	{$rndlast},[$key_]
-+
-+	add	$key_,$key,#32
-+	mov	$cnt,$rounds
-+	b.eq	.Lcbc_dec
-+
-+	cmp	$rounds,#2
-+	veor	$dat,$dat,$ivec
-+	veor	$rndzero_n_last,q8,$rndlast
-+	b.eq	.Lcbc_enc128
-+
-+	vld1.32	{$in0-$in1},[$key_]
-+	add	$key_,$key,#16
-+	add	$key4,$key,#16*4
-+	add	$key5,$key,#16*5
-+	aese	$dat,q8
-+	aesmc	$dat,$dat
-+	add	$key6,$key,#16*6
-+	add	$key7,$key,#16*7
-+	b	.Lenter_cbc_enc
-+
-+.align	4
-+.Loop_cbc_enc:
-+	aese	$dat,q8
-+	aesmc	$dat,$dat
-+	 vst1.8	{$ivec},[$out],#16
-+.Lenter_cbc_enc:
-+	aese	$dat,q9
-+	aesmc	$dat,$dat
-+	aese	$dat,$in0
-+	aesmc	$dat,$dat
-+	vld1.32	{q8},[$key4]
-+	cmp	$rounds,#4
-+	aese	$dat,$in1
-+	aesmc	$dat,$dat
-+	vld1.32	{q9},[$key5]
-+	b.eq	.Lcbc_enc192
-+
-+	aese	$dat,q8
-+	aesmc	$dat,$dat
-+	vld1.32	{q8},[$key6]
-+	aese	$dat,q9
-+	aesmc	$dat,$dat
-+	vld1.32	{q9},[$key7]
-+	nop
-+
-+.Lcbc_enc192:
-+	aese	$dat,q8
-+	aesmc	$dat,$dat
-+	 subs	$len,$len,#16
-+	aese	$dat,q9
-+	aesmc	$dat,$dat
-+	 cclr	$step,eq
-+	aese	$dat,q10
-+	aesmc	$dat,$dat
-+	aese	$dat,q11
-+	aesmc	$dat,$dat
-+	 vld1.8	{q8},[$inp],$step
-+	aese	$dat,q12
-+	aesmc	$dat,$dat
-+	 veor	q8,q8,$rndzero_n_last
-+	aese	$dat,q13
-+	aesmc	$dat,$dat
-+	 vld1.32 {q9},[$key_]		// re-pre-load rndkey[1]
-+	aese	$dat,q14
-+	aesmc	$dat,$dat
-+	aese	$dat,q15
-+	veor	$ivec,$dat,$rndlast
-+	b.hs	.Loop_cbc_enc
-+
-+	vst1.8	{$ivec},[$out],#16
-+	b	.Lcbc_done
-+
-+.align	5
-+.Lcbc_enc128:
-+	vld1.32	{$in0-$in1},[$key_]
-+	aese	$dat,q8
-+	aesmc	$dat,$dat
-+	b	.Lenter_cbc_enc128
-+.Loop_cbc_enc128:
-+	aese	$dat,q8
-+	aesmc	$dat,$dat
-+	 vst1.8	{$ivec},[$out],#16
-+.Lenter_cbc_enc128:
-+	aese	$dat,q9
-+	aesmc	$dat,$dat
-+	 subs	$len,$len,#16
-+	aese	$dat,$in0
-+	aesmc	$dat,$dat
-+	 cclr	$step,eq
-+	aese	$dat,$in1
-+	aesmc	$dat,$dat
-+	aese	$dat,q10
-+	aesmc	$dat,$dat
-+	aese	$dat,q11
-+	aesmc	$dat,$dat
-+	 vld1.8	{q8},[$inp],$step
-+	aese	$dat,q12
-+	aesmc	$dat,$dat
-+	aese	$dat,q13
-+	aesmc	$dat,$dat
-+	aese	$dat,q14
-+	aesmc	$dat,$dat
-+	 veor	q8,q8,$rndzero_n_last
-+	aese	$dat,q15
-+	veor	$ivec,$dat,$rndlast
-+	b.hs	.Loop_cbc_enc128
-+
-+	vst1.8	{$ivec},[$out],#16
-+	b	.Lcbc_done
-+___
-+{
-+my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9));
-+$code.=<<___;
-+.align	5
-+.Lcbc_dec:
-+	vld1.8	{$dat2},[$inp],#16
-+	subs	$len,$len,#32		// bias
-+	add	$cnt,$rounds,#2
-+	vorr	$in1,$dat,$dat
-+	vorr	$dat1,$dat,$dat
-+	vorr	$in2,$dat2,$dat2
-+	b.lo	.Lcbc_dec_tail
-+
-+	vorr	$dat1,$dat2,$dat2
-+	vld1.8	{$dat2},[$inp],#16
-+	vorr	$in0,$dat,$dat
-+	vorr	$in1,$dat1,$dat1
-+	vorr	$in2,$dat2,$dat2
-+
-+.Loop3x_cbc_dec:
-+	aesd	$dat0,q8
-+	aesimc	$dat0,$dat0
-+	aesd	$dat1,q8
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q8
-+	aesimc	$dat2,$dat2
-+	vld1.32	{q8},[$key_],#16
-+	subs	$cnt,$cnt,#2
-+	aesd	$dat0,q9
-+	aesimc	$dat0,$dat0
-+	aesd	$dat1,q9
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q9
-+	aesimc	$dat2,$dat2
-+	vld1.32	{q9},[$key_],#16
-+	b.gt	.Loop3x_cbc_dec
-+
-+	aesd	$dat0,q8
-+	aesimc	$dat0,$dat0
-+	aesd	$dat1,q8
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q8
-+	aesimc	$dat2,$dat2
-+	 veor	$tmp0,$ivec,$rndlast
-+	 subs	$len,$len,#0x30
-+	 veor	$tmp1,$in0,$rndlast
-+	 mov.lo	x6,$len			// x6, $cnt, is zero at this point
-+	aesd	$dat0,q9
-+	aesimc	$dat0,$dat0
-+	aesd	$dat1,q9
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q9
-+	aesimc	$dat2,$dat2
-+	 veor	$tmp2,$in1,$rndlast
-+	 add	$inp,$inp,x6		// $inp is adjusted in such way that
-+					// at exit from the loop $dat1-$dat2
-+					// are loaded with last "words"
-+	 vorr	$ivec,$in2,$in2
-+	 mov	$key_,$key
-+	aesd	$dat0,q12
-+	aesimc	$dat0,$dat0
-+	aesd	$dat1,q12
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q12
-+	aesimc	$dat2,$dat2
-+	 vld1.8	{$in0},[$inp],#16
-+	aesd	$dat0,q13
-+	aesimc	$dat0,$dat0
-+	aesd	$dat1,q13
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q13
-+	aesimc	$dat2,$dat2
-+	 vld1.8	{$in1},[$inp],#16
-+	aesd	$dat0,q14
-+	aesimc	$dat0,$dat0
-+	aesd	$dat1,q14
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q14
-+	aesimc	$dat2,$dat2
-+	 vld1.8	{$in2},[$inp],#16
-+	aesd	$dat0,q15
-+	aesd	$dat1,q15
-+	aesd	$dat2,q15
-+	 vld1.32 {q8},[$key_],#16	// re-pre-load rndkey[0]
-+	 add	$cnt,$rounds,#2
-+	veor	$tmp0,$tmp0,$dat0
-+	veor	$tmp1,$tmp1,$dat1
-+	veor	$dat2,$dat2,$tmp2
-+	 vld1.32 {q9},[$key_],#16	// re-pre-load rndkey[1]
-+	vst1.8	{$tmp0},[$out],#16
-+	 vorr	$dat0,$in0,$in0
-+	vst1.8	{$tmp1},[$out],#16
-+	 vorr	$dat1,$in1,$in1
-+	vst1.8	{$dat2},[$out],#16
-+	 vorr	$dat2,$in2,$in2
-+	b.hs	.Loop3x_cbc_dec
-+
-+	cmn	$len,#0x30
-+	b.eq	.Lcbc_done
-+	nop
-+
-+.Lcbc_dec_tail:
-+	aesd	$dat1,q8
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q8
-+	aesimc	$dat2,$dat2
-+	vld1.32	{q8},[$key_],#16
-+	subs	$cnt,$cnt,#2
-+	aesd	$dat1,q9
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q9
-+	aesimc	$dat2,$dat2
-+	vld1.32	{q9},[$key_],#16
-+	b.gt	.Lcbc_dec_tail
-+
-+	aesd	$dat1,q8
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q8
-+	aesimc	$dat2,$dat2
-+	aesd	$dat1,q9
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q9
-+	aesimc	$dat2,$dat2
-+	aesd	$dat1,q12
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q12
-+	aesimc	$dat2,$dat2
-+	 cmn	$len,#0x20
-+	aesd	$dat1,q13
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q13
-+	aesimc	$dat2,$dat2
-+	 veor	$tmp1,$ivec,$rndlast
-+	aesd	$dat1,q14
-+	aesimc	$dat1,$dat1
-+	aesd	$dat2,q14
-+	aesimc	$dat2,$dat2
-+	 veor	$tmp2,$in1,$rndlast
-+	aesd	$dat1,q15
-+	aesd	$dat2,q15
-+	b.eq	.Lcbc_dec_one
-+	veor	$tmp1,$tmp1,$dat1
-+	veor	$tmp2,$tmp2,$dat2
-+	 vorr	$ivec,$in2,$in2
-+	vst1.8	{$tmp1},[$out],#16
-+	vst1.8	{$tmp2},[$out],#16
-+	b	.Lcbc_done
-+
-+.Lcbc_dec_one:
-+	veor	$tmp1,$tmp1,$dat2
-+	 vorr	$ivec,$in2,$in2
-+	vst1.8	{$tmp1},[$out],#16
-+
-+.Lcbc_done:
-+	vst1.8	{$ivec},[$ivp]
-+.Lcbc_abort:
-+___
-+}
-+$code.=<<___	if ($flavour !~ /64/);
-+	vldmia	sp!,{d8-d15}
-+	ldmia	sp!,{r4-r8,pc}
-+___
-+$code.=<<___	if ($flavour =~ /64/);
-+	ldr	x29,[sp],#16
-+	ret
-+___
-+$code.=<<___;
-+.size	${prefix}_cbc_encrypt,.-${prefix}_cbc_encrypt
-+___
-+}}}
-+{{{
-+my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4));
-+my ($rounds,$cnt,$key_)=("w5","w6","x7");
-+my ($ctr,$tctr0,$tctr1,$tctr2)=map("w$_",(8..10,12));
-+my $step="x12";		# aliases with $tctr2
-+
-+my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$ivec,$rndlast)=map("q$_",(0..7));
-+my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9));
-+
-+my ($dat,$tmp)=($dat0,$tmp0);
-+
-+### q8-q15	preloaded key schedule
-+
-+$code.=<<___;
-+.globl	${prefix}_ctr32_encrypt_blocks
-+.type	${prefix}_ctr32_encrypt_blocks,%function
-+.align	5
-+${prefix}_ctr32_encrypt_blocks:
-+___
-+$code.=<<___	if ($flavour =~ /64/);
-+	stp		x29,x30,[sp,#-16]!
-+	add		x29,sp,#0
-+___
-+$code.=<<___	if ($flavour !~ /64/);
-+	mov		ip,sp
-+	stmdb		sp!,{r4-r10,lr}
-+	vstmdb		sp!,{d8-d15}            @ ABI specification says so
-+	ldr		r4, [ip]		@ load remaining arg
-+___
-+$code.=<<___;
-+	ldr		$rounds,[$key,#240]
-+
-+	ldr		$ctr, [$ivp, #12]
-+	vld1.32		{$dat0},[$ivp]
-+
-+	vld1.32		{q8-q9},[$key]		// load key schedule...
-+	sub		$rounds,$rounds,#4
-+	mov		$step,#16
-+	cmp		$len,#2
-+	add		$key_,$key,x5,lsl#4	// pointer to last 5 round keys
-+	sub		$rounds,$rounds,#2
-+	vld1.32		{q12-q13},[$key_],#32
-+	vld1.32		{q14-q15},[$key_],#32
-+	vld1.32		{$rndlast},[$key_]
-+	add		$key_,$key,#32
-+	mov		$cnt,$rounds
-+	cclr		$step,lo
-+#ifndef __ARMEB__
-+	rev		$ctr, $ctr
-+#endif
-+	vorr		$dat1,$dat0,$dat0
-+	add		$tctr1, $ctr, #1
-+	vorr		$dat2,$dat0,$dat0
-+	add		$ctr, $ctr, #2
-+	vorr		$ivec,$dat0,$dat0
-+	rev		$tctr1, $tctr1
-+	vmov.32		${dat1}[3],$tctr1
-+	b.ls		.Lctr32_tail
-+	rev		$tctr2, $ctr
-+	sub		$len,$len,#3		// bias
-+	vmov.32		${dat2}[3],$tctr2
-+	b		.Loop3x_ctr32
-+
-+.align	4
-+.Loop3x_ctr32:
-+	aese		$dat0,q8
-+	aesmc		$dat0,$dat0
-+	aese		$dat1,q8
-+	aesmc		$dat1,$dat1
-+	aese		$dat2,q8
-+	aesmc		$dat2,$dat2
-+	vld1.32		{q8},[$key_],#16
-+	subs		$cnt,$cnt,#2
-+	aese		$dat0,q9
-+	aesmc		$dat0,$dat0
-+	aese		$dat1,q9
-+	aesmc		$dat1,$dat1
-+	aese		$dat2,q9
-+	aesmc		$dat2,$dat2
-+	vld1.32		{q9},[$key_],#16
-+	b.gt		.Loop3x_ctr32
-+
-+	aese		$dat0,q8
-+	aesmc		$tmp0,$dat0
-+	aese		$dat1,q8
-+	aesmc		$tmp1,$dat1
-+	 vld1.8		{$in0},[$inp],#16
-+	 vorr		$dat0,$ivec,$ivec
-+	aese		$dat2,q8
-+	aesmc		$dat2,$dat2
-+	 vld1.8		{$in1},[$inp],#16
-+	 vorr		$dat1,$ivec,$ivec
-+	aese		$tmp0,q9
-+	aesmc		$tmp0,$tmp0
-+	aese		$tmp1,q9
-+	aesmc		$tmp1,$tmp1
-+	 vld1.8		{$in2},[$inp],#16
-+	 mov		$key_,$key
-+	aese		$dat2,q9
-+	aesmc		$tmp2,$dat2
-+	 vorr		$dat2,$ivec,$ivec
-+	 add		$tctr0,$ctr,#1
-+	aese		$tmp0,q12
-+	aesmc		$tmp0,$tmp0
-+	aese		$tmp1,q12
-+	aesmc		$tmp1,$tmp1
-+	 veor		$in0,$in0,$rndlast
-+	 add		$tctr1,$ctr,#2
-+	aese		$tmp2,q12
-+	aesmc		$tmp2,$tmp2
-+	 veor		$in1,$in1,$rndlast
-+	 add		$ctr,$ctr,#3
-+	aese		$tmp0,q13
-+	aesmc		$tmp0,$tmp0
-+	aese		$tmp1,q13
-+	aesmc		$tmp1,$tmp1
-+	 veor		$in2,$in2,$rndlast
-+	 rev		$tctr0,$tctr0
-+	aese		$tmp2,q13
-+	aesmc		$tmp2,$tmp2
-+	 vmov.32	${dat0}[3], $tctr0
-+	 rev		$tctr1,$tctr1
-+	aese		$tmp0,q14
-+	aesmc		$tmp0,$tmp0
-+	aese		$tmp1,q14
-+	aesmc		$tmp1,$tmp1
-+	 vmov.32	${dat1}[3], $tctr1
-+	 rev		$tctr2,$ctr
-+	aese		$tmp2,q14
-+	aesmc		$tmp2,$tmp2
-+	 vmov.32	${dat2}[3], $tctr2
-+	 subs		$len,$len,#3
-+	aese		$tmp0,q15
-+	aese		$tmp1,q15
-+	aese		$tmp2,q15
-+
-+	veor		$in0,$in0,$tmp0
-+	 vld1.32	 {q8},[$key_],#16	// re-pre-load rndkey[0]
-+	vst1.8		{$in0},[$out],#16
-+	veor		$in1,$in1,$tmp1
-+	 mov		$cnt,$rounds
-+	vst1.8		{$in1},[$out],#16
-+	veor		$in2,$in2,$tmp2
-+	 vld1.32	 {q9},[$key_],#16	// re-pre-load rndkey[1]
-+	vst1.8		{$in2},[$out],#16
-+	b.hs		.Loop3x_ctr32
-+
-+	adds		$len,$len,#3
-+	b.eq		.Lctr32_done
-+	cmp		$len,#1
-+	mov		$step,#16
-+	cclr		$step,eq
-+
-+.Lctr32_tail:
-+	aese		$dat0,q8
-+	aesmc		$dat0,$dat0
-+	aese		$dat1,q8
-+	aesmc		$dat1,$dat1
-+	vld1.32		{q8},[$key_],#16
-+	subs		$cnt,$cnt,#2
-+	aese		$dat0,q9
-+	aesmc		$dat0,$dat0
-+	aese		$dat1,q9
-+	aesmc		$dat1,$dat1
-+	vld1.32		{q9},[$key_],#16
-+	b.gt		.Lctr32_tail
-+
-+	aese		$dat0,q8
-+	aesmc		$dat0,$dat0
-+	aese		$dat1,q8
-+	aesmc		$dat1,$dat1
-+	aese		$dat0,q9
-+	aesmc		$dat0,$dat0
-+	aese		$dat1,q9
-+	aesmc		$dat1,$dat1
-+	 vld1.8		{$in0},[$inp],$step
-+	aese		$dat0,q12
-+	aesmc		$dat0,$dat0
-+	aese		$dat1,q12
-+	aesmc		$dat1,$dat1
-+	 vld1.8		{$in1},[$inp]
-+	aese		$dat0,q13
-+	aesmc		$dat0,$dat0
-+	aese		$dat1,q13
-+	aesmc		$dat1,$dat1
-+	 veor		$in0,$in0,$rndlast
-+	aese		$dat0,q14
-+	aesmc		$dat0,$dat0
-+	aese		$dat1,q14
-+	aesmc		$dat1,$dat1
-+	 veor		$in1,$in1,$rndlast
-+	aese		$dat0,q15
-+	aese		$dat1,q15
-+
-+	cmp		$len,#1
-+	veor		$in0,$in0,$dat0
-+	veor		$in1,$in1,$dat1
-+	vst1.8		{$in0},[$out],#16
-+	b.eq		.Lctr32_done
-+	vst1.8		{$in1},[$out]
-+
-+.Lctr32_done:
-+___
-+$code.=<<___	if ($flavour !~ /64/);
-+	vldmia		sp!,{d8-d15}
-+	ldmia		sp!,{r4-r10,pc}
-+___
-+$code.=<<___	if ($flavour =~ /64/);
-+	ldr		x29,[sp],#16
-+	ret
-+___
-+$code.=<<___;
-+.size	${prefix}_ctr32_encrypt_blocks,.-${prefix}_ctr32_encrypt_blocks
-+___
-+}}}
-+$code.=<<___;
-+#endif
-+___
-+########################################
-+if ($flavour =~ /64/) {			######## 64-bit code
-+    my %opcode = (
-+	"aesd"	=>	0x4e285800,	"aese"	=>	0x4e284800,
-+	"aesimc"=>	0x4e287800,	"aesmc"	=>	0x4e286800	);
-+
-+    local *unaes = sub {
-+	my ($mnemonic,$arg)=@_;
-+
-+	$arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)/o	&&
-+	sprintf ".inst\t0x%08x\t//%s %s",
-+			$opcode{$mnemonic}|$1|($2<<5),
-+			$mnemonic,$arg;
-+    };
-+
-+    foreach(split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval($1)/geo;
-+
-+	s/\bq([0-9]+)\b/"v".($1<8?$1:$1+8).".16b"/geo;	# old->new registers
-+	s/@\s/\/\//o;			# old->new style commentary
-+
-+	#s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo	or
-+	s/cclr\s+([wx])([^,]+),\s*([a-z]+)/csel	$1$2,$1zr,$1$2,$3/o	or
-+	s/mov\.([a-z]+)\s+([wx][0-9]+),\s*([wx][0-9]+)/csel	$2,$3,$2,$1/o	or
-+	s/vmov\.i8/movi/o	or	# fix up legacy mnemonics
-+	s/vext\.8/ext/o		or
-+	s/vrev32\.8/rev32/o	or
-+	s/vtst\.8/cmtst/o	or
-+	s/vshr/ushr/o		or
-+	s/^(\s+)v/$1/o		or	# strip off v prefix
-+	s/\bbx\s+lr\b/ret/o;
-+
-+	# fix up remainig legacy suffixes
-+	s/\.[ui]?8//o;
-+	m/\],#8/o and s/\.16b/\.8b/go;
-+	s/\.[ui]?32//o and s/\.16b/\.4s/go;
-+	s/\.[ui]?64//o and s/\.16b/\.2d/go;
-+	s/\.[42]([sd])\[([0-3])\]/\.$1\[$2\]/o;
-+
-+	print $_,"\n";
-+    }
-+} else {				######## 32-bit code
-+    my %opcode = (
-+	"aesd"	=>	0xf3b00340,	"aese"	=>	0xf3b00300,
-+	"aesimc"=>	0xf3b003c0,	"aesmc"	=>	0xf3b00380	);
-+
-+    local *unaes = sub {
-+	my ($mnemonic,$arg)=@_;
-+
-+	if ($arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)/o) {
-+	    my $word = $opcode{$mnemonic}|(($1&7)<<13)|(($1&8)<<19)
-+					 |(($2&7)<<1) |(($2&8)<<2);
-+	    # since ARMv7 instructions are always encoded little-endian.
-+	    # correct solution is to use .inst directive, but older
-+	    # assemblers don't implement it:-(
-+	    sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s",
-+			$word&0xff,($word>>8)&0xff,
-+			($word>>16)&0xff,($word>>24)&0xff,
-+			$mnemonic,$arg;
-+	}
-+    };
-+
-+    sub unvtbl {
-+	my $arg=shift;
-+
-+	$arg =~ m/q([0-9]+),\s*\{q([0-9]+)\},\s*q([0-9]+)/o &&
-+	sprintf	"vtbl.8	d%d,{q%d},d%d\n\t".
-+		"vtbl.8	d%d,{q%d},d%d", 2*$1,$2,2*$3, 2*$1+1,$2,2*$3+1;	
-+    }
-+
-+    sub unvdup32 {
-+	my $arg=shift;
-+
-+	$arg =~ m/q([0-9]+),\s*q([0-9]+)\[([0-3])\]/o &&
-+	sprintf	"vdup.32	q%d,d%d[%d]",$1,2*$2+($3>>1),$3&1;	
-+    }
-+
-+    sub unvmov32 {
-+	my $arg=shift;
-+
-+	$arg =~ m/q([0-9]+)\[([0-3])\],(.*)/o &&
-+	sprintf	"vmov.32	d%d[%d],%s",2*$1+($2>>1),$2&1,$3;	
-+    }
-+
-+    foreach(split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval($1)/geo;
-+
-+	s/\b[wx]([0-9]+)\b/r$1/go;		# new->old registers
-+	s/\bv([0-9])\.[12468]+[bsd]\b/q$1/go;	# new->old registers
-+	s/\/\/\s?/@ /o;				# new->old style commentary
-+
-+	# fix up remainig new-style suffixes
-+	s/\{q([0-9]+)\},\s*\[(.+)\],#8/sprintf "{d%d},[$2]!",2*$1/eo	or
-+	s/\],#[0-9]+/]!/o;
-+
-+	s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo	or
-+	s/cclr\s+([^,]+),\s*([a-z]+)/mov$2	$1,#0/o	or
-+	s/vtbl\.8\s+(.*)/unvtbl($1)/geo			or
-+	s/vdup\.32\s+(.*)/unvdup32($1)/geo		or
-+	s/vmov\.32\s+(.*)/unvmov32($1)/geo		or
-+	s/^(\s+)b\./$1b/o				or
-+	s/^(\s+)mov\./$1mov/o				or
-+	s/^(\s+)ret/$1bx\tlr/o;
-+
-+	print $_,"\n";
-+    }
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/bsaes-armv7.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/bsaes-armv7.pl
-new file mode 100644
-index 0000000..12091ef
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/bsaes-armv7.pl
-@@ -0,0 +1,2495 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+#
-+# Specific modes and adaptation for Linux kernel by Ard Biesheuvel
-+# . Permission to use under GPL terms is
-+# granted.
-+# ====================================================================
-+
-+# Bit-sliced AES for ARM NEON
-+#
-+# February 2012.
-+#
-+# This implementation is direct adaptation of bsaes-x86_64 module for
-+# ARM NEON. Except that this module is endian-neutral [in sense that
-+# it can be compiled for either endianness] by courtesy of vld1.8's
-+# neutrality. Initial version doesn't implement interface to OpenSSL,
-+# only low-level primitives and unsupported entry points, just enough
-+# to collect performance results, which for Cortex-A8 core are:
-+#
-+# encrypt	19.5 cycles per byte processed with 128-bit key
-+# decrypt	22.1 cycles per byte processed with 128-bit key
-+# key conv.	440  cycles per 128-bit key/0.18 of 8x block
-+#
-+# Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7,
-+# which is [much] worse than anticipated (for further details see
-+# http://www.openssl.org/~appro/Snapdragon-S4.html).
-+#
-+# Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code
-+# manages in 20.0 cycles].
-+#
-+# When comparing to x86_64 results keep in mind that NEON unit is
-+# [mostly] single-issue and thus can't [fully] benefit from
-+# instruction-level parallelism. And when comparing to aes-armv4
-+# results keep in mind key schedule conversion overhead (see
-+# bsaes-x86_64.pl for further details)...
-+#
-+#						
-+
-+# April-August 2013
-+#
-+# Add CBC, CTR and XTS subroutines, adapt for kernel use.
-+#
-+#					
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+my ($inp,$out,$len,$key)=("r0","r1","r2","r3");
-+my @XMM=map("q$_",(0..15));
-+
-+{
-+my ($key,$rounds,$const)=("r4","r5","r6");
-+
-+sub Dlo()   { shift=~m|q([1]?[0-9])|?"d".($1*2):"";     }
-+sub Dhi()   { shift=~m|q([1]?[0-9])|?"d".($1*2+1):"";   }
-+
-+sub Sbox {
-+# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-+# output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb
-+my @b=@_[0..7];
-+my @t=@_[8..11];
-+my @s=@_[12..15];
-+	&InBasisChange	(@b);
-+	&Inv_GF256	(@b[6,5,0,3,7,1,4,2],@t,@s);
-+	&OutBasisChange	(@b[7,1,4,2,6,5,0,3]);
-+}
-+
-+sub InBasisChange {
-+# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-+# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb 
-+my @b=@_[0..7];
-+$code.=<<___;
-+	veor	@b[2], @b[2], @b[1]
-+	veor	@b[5], @b[5], @b[6]
-+	veor	@b[3], @b[3], @b[0]
-+	veor	@b[6], @b[6], @b[2]
-+	veor	@b[5], @b[5], @b[0]
-+
-+	veor	@b[6], @b[6], @b[3]
-+	veor	@b[3], @b[3], @b[7]
-+	veor	@b[7], @b[7], @b[5]
-+	veor	@b[3], @b[3], @b[4]
-+	veor	@b[4], @b[4], @b[5]
-+
-+	veor	@b[2], @b[2], @b[7]
-+	veor	@b[3], @b[3], @b[1]
-+	veor	@b[1], @b[1], @b[5]
-+___
-+}
-+
-+sub OutBasisChange {
-+# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-+# output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb
-+my @b=@_[0..7];
-+$code.=<<___;
-+	veor	@b[0], @b[0], @b[6]
-+	veor	@b[1], @b[1], @b[4]
-+	veor	@b[4], @b[4], @b[6]
-+	veor	@b[2], @b[2], @b[0]
-+	veor	@b[6], @b[6], @b[1]
-+
-+	veor	@b[1], @b[1], @b[5]
-+	veor	@b[5], @b[5], @b[3]
-+	veor	@b[3], @b[3], @b[7]
-+	veor	@b[7], @b[7], @b[5]
-+	veor	@b[2], @b[2], @b[5]
-+
-+	veor	@b[4], @b[4], @b[7]
-+___
-+}
-+
-+sub InvSbox {
-+# input in lsb 	> [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-+# output in lsb	> [b0, b1, b6, b4, b2, b7, b3, b5] < msb
-+my @b=@_[0..7];
-+my @t=@_[8..11];
-+my @s=@_[12..15];
-+	&InvInBasisChange	(@b);
-+	&Inv_GF256		(@b[5,1,2,6,3,7,0,4],@t,@s);
-+	&InvOutBasisChange	(@b[3,7,0,4,5,1,2,6]);
-+}
-+
-+sub InvInBasisChange {		# OutBasisChange in reverse (with twist)
-+my @b=@_[5,1,2,6,3,7,0,4];
-+$code.=<<___
-+	 veor	@b[1], @b[1], @b[7]
-+	veor	@b[4], @b[4], @b[7]
-+
-+	veor	@b[7], @b[7], @b[5]
-+	 veor	@b[1], @b[1], @b[3]
-+	veor	@b[2], @b[2], @b[5]
-+	veor	@b[3], @b[3], @b[7]
-+
-+	veor	@b[6], @b[6], @b[1]
-+	veor	@b[2], @b[2], @b[0]
-+	 veor	@b[5], @b[5], @b[3]
-+	veor	@b[4], @b[4], @b[6]
-+	veor	@b[0], @b[0], @b[6]
-+	veor	@b[1], @b[1], @b[4]
-+___
-+}
-+
-+sub InvOutBasisChange {		# InBasisChange in reverse
-+my @b=@_[2,5,7,3,6,1,0,4];
-+$code.=<<___;
-+	veor	@b[1], @b[1], @b[5]
-+	veor	@b[2], @b[2], @b[7]
-+
-+	veor	@b[3], @b[3], @b[1]
-+	veor	@b[4], @b[4], @b[5]
-+	veor	@b[7], @b[7], @b[5]
-+	veor	@b[3], @b[3], @b[4]
-+	 veor 	@b[5], @b[5], @b[0]
-+	veor	@b[3], @b[3], @b[7]
-+	 veor	@b[6], @b[6], @b[2]
-+	 veor	@b[2], @b[2], @b[1]
-+	veor	@b[6], @b[6], @b[3]
-+
-+	veor	@b[3], @b[3], @b[0]
-+	veor	@b[5], @b[5], @b[6]
-+___
-+}
-+
-+sub Mul_GF4 {
-+#;*************************************************************
-+#;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) *
-+#;*************************************************************
-+my ($x0,$x1,$y0,$y1,$t0,$t1)=@_;
-+$code.=<<___;
-+	veor 	$t0, $y0, $y1
-+	vand	$t0, $t0, $x0
-+	veor	$x0, $x0, $x1
-+	vand	$t1, $x1, $y0
-+	vand	$x0, $x0, $y1
-+	veor	$x1, $t1, $t0
-+	veor	$x0, $x0, $t1
-+___
-+}
-+
-+sub Mul_GF4_N {				# not used, see next subroutine
-+# multiply and scale by N
-+my ($x0,$x1,$y0,$y1,$t0)=@_;
-+$code.=<<___;
-+	veor	$t0, $y0, $y1
-+	vand	$t0, $t0, $x0
-+	veor	$x0, $x0, $x1
-+	vand	$x1, $x1, $y0
-+	vand	$x0, $x0, $y1
-+	veor	$x1, $x1, $x0
-+	veor	$x0, $x0, $t0
-+___
-+}
-+
-+sub Mul_GF4_N_GF4 {
-+# interleaved Mul_GF4_N and Mul_GF4
-+my ($x0,$x1,$y0,$y1,$t0,
-+    $x2,$x3,$y2,$y3,$t1)=@_;
-+$code.=<<___;
-+	veor	$t0, $y0, $y1
-+	 veor 	$t1, $y2, $y3
-+	vand	$t0, $t0, $x0
-+	 vand	$t1, $t1, $x2
-+	veor	$x0, $x0, $x1
-+	 veor	$x2, $x2, $x3
-+	vand	$x1, $x1, $y0
-+	 vand	$x3, $x3, $y2
-+	vand	$x0, $x0, $y1
-+	 vand	$x2, $x2, $y3
-+	veor	$x1, $x1, $x0
-+	 veor	$x2, $x2, $x3
-+	veor	$x0, $x0, $t0
-+	 veor	$x3, $x3, $t1
-+___
-+}
-+sub Mul_GF16_2 {
-+my @x=@_[0..7];
-+my @y=@_[8..11];
-+my @t=@_[12..15];
-+$code.=<<___;
-+	veor	@t[0], @x[0], @x[2]
-+	veor	@t[1], @x[1], @x[3]
-+___
-+	&Mul_GF4  	(@x[0], @x[1], @y[0], @y[1], @t[2..3]);
-+$code.=<<___;
-+	veor	@y[0], @y[0], @y[2]
-+	veor	@y[1], @y[1], @y[3]
-+___
-+	Mul_GF4_N_GF4	(@t[0], @t[1], @y[0], @y[1], @t[3],
-+			 @x[2], @x[3], @y[2], @y[3], @t[2]);
-+$code.=<<___;
-+	veor	@x[0], @x[0], @t[0]
-+	veor	@x[2], @x[2], @t[0]
-+	veor	@x[1], @x[1], @t[1]
-+	veor	@x[3], @x[3], @t[1]
-+
-+	veor	@t[0], @x[4], @x[6]
-+	veor	@t[1], @x[5], @x[7]
-+___
-+	&Mul_GF4_N_GF4	(@t[0], @t[1], @y[0], @y[1], @t[3],
-+			 @x[6], @x[7], @y[2], @y[3], @t[2]);
-+$code.=<<___;
-+	veor	@y[0], @y[0], @y[2]
-+	veor	@y[1], @y[1], @y[3]
-+___
-+	&Mul_GF4  	(@x[4], @x[5], @y[0], @y[1], @t[2..3]);
-+$code.=<<___;
-+	veor	@x[4], @x[4], @t[0]
-+	veor	@x[6], @x[6], @t[0]
-+	veor	@x[5], @x[5], @t[1]
-+	veor	@x[7], @x[7], @t[1]
-+___
-+}
-+sub Inv_GF256 {
-+#;********************************************************************
-+#;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144)       *
-+#;********************************************************************
-+my @x=@_[0..7];
-+my @t=@_[8..11];
-+my @s=@_[12..15];
-+# direct optimizations from hardware
-+$code.=<<___;
-+	veor	@t[3], @x[4], @x[6]
-+	veor	@t[2], @x[5], @x[7]
-+	veor	@t[1], @x[1], @x[3]
-+	veor	@s[1], @x[7], @x[6]
-+	 vmov	@t[0], @t[2]
-+	veor	@s[0], @x[0], @x[2]
-+
-+	vorr	@t[2], @t[2], @t[1]
-+	veor	@s[3], @t[3], @t[0]
-+	vand	@s[2], @t[3], @s[0]
-+	vorr	@t[3], @t[3], @s[0]
-+	veor	@s[0], @s[0], @t[1]
-+	vand	@t[0], @t[0], @t[1]
-+	veor	@t[1], @x[3], @x[2]
-+	vand	@s[3], @s[3], @s[0]
-+	vand	@s[1], @s[1], @t[1]
-+	veor	@t[1], @x[4], @x[5]
-+	veor	@s[0], @x[1], @x[0]
-+	veor	@t[3], @t[3], @s[1]
-+	veor	@t[2], @t[2], @s[1]
-+	vand	@s[1], @t[1], @s[0]
-+	vorr	@t[1], @t[1], @s[0]
-+	veor	@t[3], @t[3], @s[3]
-+	veor	@t[0], @t[0], @s[1]
-+	veor	@t[2], @t[2], @s[2]
-+	veor	@t[1], @t[1], @s[3]
-+	veor	@t[0], @t[0], @s[2]
-+	vand	@s[0], @x[7], @x[3]
-+	veor	@t[1], @t[1], @s[2]
-+	vand	@s[1], @x[6], @x[2]
-+	vand	@s[2], @x[5], @x[1]
-+	vorr	@s[3], @x[4], @x[0]
-+	veor	@t[3], @t[3], @s[0]
-+	veor	@t[1], @t[1], @s[2]
-+	veor	@t[0], @t[0], @s[3]
-+	veor	@t[2], @t[2], @s[1]
-+
-+	@ Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
-+
-+	@ new smaller inversion
-+
-+	vand	@s[2], @t[3], @t[1]
-+	vmov	@s[0], @t[0]
-+
-+	veor	@s[1], @t[2], @s[2]
-+	veor	@s[3], @t[0], @s[2]
-+	veor	@s[2], @t[0], @s[2]	@ @s[2]=@s[3]
-+
-+	vbsl	@s[1], @t[1], @t[0]
-+	vbsl	@s[3], @t[3], @t[2]
-+	veor	@t[3], @t[3], @t[2]
-+
-+	vbsl	@s[0], @s[1], @s[2]
-+	vbsl	@t[0], @s[2], @s[1]
-+
-+	vand	@s[2], @s[0], @s[3]
-+	veor	@t[1], @t[1], @t[0]
-+
-+	veor	@s[2], @s[2], @t[3]
-+___
-+# output in s3, s2, s1, t1
-+
-+# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3
-+
-+# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
-+	&Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]);
-+
-+### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb
-+}
-+
-+# AES linear components
-+
-+sub ShiftRows {
-+my @x=@_[0..7];
-+my @t=@_[8..11];
-+my $mask=pop;
-+$code.=<<___;
-+	vldmia	$key!, {@t[0]-@t[3]}
-+	veor	@t[0], @t[0], @x[0]
-+	veor	@t[1], @t[1], @x[1]
-+	vtbl.8	`&Dlo(@x[0])`, {@t[0]}, `&Dlo($mask)`
-+	vtbl.8	`&Dhi(@x[0])`, {@t[0]}, `&Dhi($mask)`
-+	vldmia	$key!, {@t[0]}
-+	veor	@t[2], @t[2], @x[2]
-+	vtbl.8	`&Dlo(@x[1])`, {@t[1]}, `&Dlo($mask)`
-+	vtbl.8	`&Dhi(@x[1])`, {@t[1]}, `&Dhi($mask)`
-+	vldmia	$key!, {@t[1]}
-+	veor	@t[3], @t[3], @x[3]
-+	vtbl.8	`&Dlo(@x[2])`, {@t[2]}, `&Dlo($mask)`
-+	vtbl.8	`&Dhi(@x[2])`, {@t[2]}, `&Dhi($mask)`
-+	vldmia	$key!, {@t[2]}
-+	vtbl.8	`&Dlo(@x[3])`, {@t[3]}, `&Dlo($mask)`
-+	vtbl.8	`&Dhi(@x[3])`, {@t[3]}, `&Dhi($mask)`
-+	vldmia	$key!, {@t[3]}
-+	veor	@t[0], @t[0], @x[4]
-+	veor	@t[1], @t[1], @x[5]
-+	vtbl.8	`&Dlo(@x[4])`, {@t[0]}, `&Dlo($mask)`
-+	vtbl.8	`&Dhi(@x[4])`, {@t[0]}, `&Dhi($mask)`
-+	veor	@t[2], @t[2], @x[6]
-+	vtbl.8	`&Dlo(@x[5])`, {@t[1]}, `&Dlo($mask)`
-+	vtbl.8	`&Dhi(@x[5])`, {@t[1]}, `&Dhi($mask)`
-+	veor	@t[3], @t[3], @x[7]
-+	vtbl.8	`&Dlo(@x[6])`, {@t[2]}, `&Dlo($mask)`
-+	vtbl.8	`&Dhi(@x[6])`, {@t[2]}, `&Dhi($mask)`
-+	vtbl.8	`&Dlo(@x[7])`, {@t[3]}, `&Dlo($mask)`
-+	vtbl.8	`&Dhi(@x[7])`, {@t[3]}, `&Dhi($mask)`
-+___
-+}
-+
-+sub MixColumns {
-+# modified to emit output in order suitable for feeding back to aesenc[last]
-+my @x=@_[0..7];
-+my @t=@_[8..15];
-+my $inv=@_[16];	# optional
-+$code.=<<___;
-+	vext.8	@t[0], @x[0], @x[0], #12	@ x0 <<< 32
-+	vext.8	@t[1], @x[1], @x[1], #12
-+	 veor	@x[0], @x[0], @t[0]		@ x0 ^ (x0 <<< 32)
-+	vext.8	@t[2], @x[2], @x[2], #12
-+	 veor	@x[1], @x[1], @t[1]
-+	vext.8	@t[3], @x[3], @x[3], #12
-+	 veor	@x[2], @x[2], @t[2]
-+	vext.8	@t[4], @x[4], @x[4], #12
-+	 veor	@x[3], @x[3], @t[3]
-+	vext.8	@t[5], @x[5], @x[5], #12
-+	 veor	@x[4], @x[4], @t[4]
-+	vext.8	@t[6], @x[6], @x[6], #12
-+	 veor	@x[5], @x[5], @t[5]
-+	vext.8	@t[7], @x[7], @x[7], #12
-+	 veor	@x[6], @x[6], @t[6]
-+
-+	veor	@t[1], @t[1], @x[0]
-+	 veor	@x[7], @x[7], @t[7]
-+	 vext.8	@x[0], @x[0], @x[0], #8		@ (x0 ^ (x0 <<< 32)) <<< 64)
-+	veor	@t[2], @t[2], @x[1]
-+	veor	@t[0], @t[0], @x[7]
-+	veor	@t[1], @t[1], @x[7]
-+	 vext.8	@x[1], @x[1], @x[1], #8
-+	veor	@t[5], @t[5], @x[4]
-+	 veor	@x[0], @x[0], @t[0]
-+	veor	@t[6], @t[6], @x[5]
-+	 veor	@x[1], @x[1], @t[1]
-+	 vext.8	@t[0], @x[4], @x[4], #8
-+	veor	@t[4], @t[4], @x[3]
-+	 vext.8	@t[1], @x[5], @x[5], #8
-+	veor	@t[7], @t[7], @x[6]
-+	 vext.8	@x[4], @x[3], @x[3], #8
-+	veor	@t[3], @t[3], @x[2]
-+	 vext.8	@x[5], @x[7], @x[7], #8
-+	veor	@t[4], @t[4], @x[7]
-+	 vext.8	@x[3], @x[6], @x[6], #8
-+	veor	@t[3], @t[3], @x[7]
-+	 vext.8	@x[6], @x[2], @x[2], #8
-+	veor	@x[7], @t[1], @t[5]
-+___
-+$code.=<<___ if (!$inv);
-+	veor	@x[2], @t[0], @t[4]
-+	veor	@x[4], @x[4], @t[3]
-+	veor	@x[5], @x[5], @t[7]
-+	veor	@x[3], @x[3], @t[6]
-+	 @ vmov	@x[2], @t[0]
-+	veor	@x[6], @x[6], @t[2]
-+	 @ vmov	@x[7], @t[1]
-+___
-+$code.=<<___ if ($inv);
-+	veor	@t[3], @t[3], @x[4]
-+	veor	@x[5], @x[5], @t[7]
-+	veor	@x[2], @x[3], @t[6]
-+	veor	@x[3], @t[0], @t[4]
-+	veor	@x[4], @x[6], @t[2]
-+	vmov	@x[6], @t[3]
-+	 @ vmov	@x[7], @t[1]
-+___
-+}
-+
-+sub InvMixColumns_orig {
-+my @x=@_[0..7];
-+my @t=@_[8..15];
-+
-+$code.=<<___;
-+	@ multiplication by 0x0e
-+	vext.8	@t[7], @x[7], @x[7], #12
-+	vmov	@t[2], @x[2]
-+	veor	@x[2], @x[2], @x[5]		@ 2 5
-+	veor	@x[7], @x[7], @x[5]		@ 7 5
-+	vext.8	@t[0], @x[0], @x[0], #12
-+	vmov	@t[5], @x[5]
-+	veor	@x[5], @x[5], @x[0]		@ 5 0		[1]
-+	veor	@x[0], @x[0], @x[1]		@ 0 1
-+	vext.8	@t[1], @x[1], @x[1], #12
-+	veor	@x[1], @x[1], @x[2]		@ 1 25
-+	veor	@x[0], @x[0], @x[6]		@ 01 6		[2]
-+	vext.8	@t[3], @x[3], @x[3], #12
-+	veor	@x[1], @x[1], @x[3]		@ 125 3		[4]
-+	veor	@x[2], @x[2], @x[0]		@ 25 016	[3]
-+	veor	@x[3], @x[3], @x[7]		@ 3 75
-+	veor	@x[7], @x[7], @x[6]		@ 75 6		[0]
-+	vext.8	@t[6], @x[6], @x[6], #12
-+	vmov	@t[4], @x[4]
-+	veor	@x[6], @x[6], @x[4]		@ 6 4
-+	veor	@x[4], @x[4], @x[3]		@ 4 375		[6]
-+	veor	@x[3], @x[3], @x[7]		@ 375 756=36
-+	veor	@x[6], @x[6], @t[5]		@ 64 5		[7]
-+	veor	@x[3], @x[3], @t[2]		@ 36 2
-+	vext.8	@t[5], @t[5], @t[5], #12
-+	veor	@x[3], @x[3], @t[4]		@ 362 4		[5]
-+___
-+					my @y = @x[7,5,0,2,1,3,4,6];
-+$code.=<<___;
-+	@ multiplication by 0x0b
-+	veor	@y[1], @y[1], @y[0]
-+	veor	@y[0], @y[0], @t[0]
-+	vext.8	@t[2], @t[2], @t[2], #12
-+	veor	@y[1], @y[1], @t[1]
-+	veor	@y[0], @y[0], @t[5]
-+	vext.8	@t[4], @t[4], @t[4], #12
-+	veor	@y[1], @y[1], @t[6]
-+	veor	@y[0], @y[0], @t[7]
-+	veor	@t[7], @t[7], @t[6]		@ clobber t[7]
-+
-+	veor	@y[3], @y[3], @t[0]
-+	 veor	@y[1], @y[1], @y[0]
-+	vext.8	@t[0], @t[0], @t[0], #12
-+	veor	@y[2], @y[2], @t[1]
-+	veor	@y[4], @y[4], @t[1]
-+	vext.8	@t[1], @t[1], @t[1], #12
-+	veor	@y[2], @y[2], @t[2]
-+	veor	@y[3], @y[3], @t[2]
-+	veor	@y[5], @y[5], @t[2]
-+	veor	@y[2], @y[2], @t[7]
-+	vext.8	@t[2], @t[2], @t[2], #12
-+	veor	@y[3], @y[3], @t[3]
-+	veor	@y[6], @y[6], @t[3]
-+	veor	@y[4], @y[4], @t[3]
-+	veor	@y[7], @y[7], @t[4]
-+	vext.8	@t[3], @t[3], @t[3], #12
-+	veor	@y[5], @y[5], @t[4]
-+	veor	@y[7], @y[7], @t[7]
-+	veor	@t[7], @t[7], @t[5]		@ clobber t[7] even more
-+	veor	@y[3], @y[3], @t[5]
-+	veor	@y[4], @y[4], @t[4]
-+
-+	veor	@y[5], @y[5], @t[7]
-+	vext.8	@t[4], @t[4], @t[4], #12
-+	veor	@y[6], @y[6], @t[7]
-+	veor	@y[4], @y[4], @t[7]
-+
-+	veor	@t[7], @t[7], @t[5]
-+	vext.8	@t[5], @t[5], @t[5], #12
-+
-+	@ multiplication by 0x0d
-+	veor	@y[4], @y[4], @y[7]
-+	 veor	@t[7], @t[7], @t[6]		@ restore t[7]
-+	veor	@y[7], @y[7], @t[4]
-+	vext.8	@t[6], @t[6], @t[6], #12
-+	veor	@y[2], @y[2], @t[0]
-+	veor	@y[7], @y[7], @t[5]
-+	vext.8	@t[7], @t[7], @t[7], #12
-+	veor	@y[2], @y[2], @t[2]
-+
-+	veor	@y[3], @y[3], @y[1]
-+	veor	@y[1], @y[1], @t[1]
-+	veor	@y[0], @y[0], @t[0]
-+	veor	@y[3], @y[3], @t[0]
-+	veor	@y[1], @y[1], @t[5]
-+	veor	@y[0], @y[0], @t[5]
-+	vext.8	@t[0], @t[0], @t[0], #12
-+	veor	@y[1], @y[1], @t[7]
-+	veor	@y[0], @y[0], @t[6]
-+	veor	@y[3], @y[3], @y[1]
-+	veor	@y[4], @y[4], @t[1]
-+	vext.8	@t[1], @t[1], @t[1], #12
-+
-+	veor	@y[7], @y[7], @t[7]
-+	veor	@y[4], @y[4], @t[2]
-+	veor	@y[5], @y[5], @t[2]
-+	veor	@y[2], @y[2], @t[6]
-+	veor	@t[6], @t[6], @t[3]		@ clobber t[6]
-+	vext.8	@t[2], @t[2], @t[2], #12
-+	veor	@y[4], @y[4], @y[7]
-+	veor	@y[3], @y[3], @t[6]
-+
-+	veor	@y[6], @y[6], @t[6]
-+	veor	@y[5], @y[5], @t[5]
-+	vext.8	@t[5], @t[5], @t[5], #12
-+	veor	@y[6], @y[6], @t[4]
-+	vext.8	@t[4], @t[4], @t[4], #12
-+	veor	@y[5], @y[5], @t[6]
-+	veor	@y[6], @y[6], @t[7]
-+	vext.8	@t[7], @t[7], @t[7], #12
-+	veor	@t[6], @t[6], @t[3]		@ restore t[6]
-+	vext.8	@t[3], @t[3], @t[3], #12
-+
-+	@ multiplication by 0x09
-+	veor	@y[4], @y[4], @y[1]
-+	veor	@t[1], @t[1], @y[1]		@ t[1]=y[1]
-+	veor	@t[0], @t[0], @t[5]		@ clobber t[0]
-+	vext.8	@t[6], @t[6], @t[6], #12
-+	veor	@t[1], @t[1], @t[5]
-+	veor	@y[3], @y[3], @t[0]
-+	veor	@t[0], @t[0], @y[0]		@ t[0]=y[0]
-+	veor	@t[1], @t[1], @t[6]
-+	veor	@t[6], @t[6], @t[7]		@ clobber t[6]
-+	veor	@y[4], @y[4], @t[1]
-+	veor	@y[7], @y[7], @t[4]
-+	veor	@y[6], @y[6], @t[3]
-+	veor	@y[5], @y[5], @t[2]
-+	veor	@t[4], @t[4], @y[4]		@ t[4]=y[4]
-+	veor	@t[3], @t[3], @y[3]		@ t[3]=y[3]
-+	veor	@t[5], @t[5], @y[5]		@ t[5]=y[5]
-+	veor	@t[2], @t[2], @y[2]		@ t[2]=y[2]
-+	veor	@t[3], @t[3], @t[7]
-+	veor	@XMM[5], @t[5], @t[6]
-+	veor	@XMM[6], @t[6], @y[6]		@ t[6]=y[6]
-+	veor	@XMM[2], @t[2], @t[6]
-+	veor	@XMM[7], @t[7], @y[7]		@ t[7]=y[7]
-+
-+	vmov	@XMM[0], @t[0]
-+	vmov	@XMM[1], @t[1]
-+	@ vmov	@XMM[2], @t[2]
-+	vmov	@XMM[3], @t[3]
-+	vmov	@XMM[4], @t[4]
-+	@ vmov	@XMM[5], @t[5]
-+	@ vmov	@XMM[6], @t[6]
-+	@ vmov	@XMM[7], @t[7]
-+___
-+}
-+
-+sub InvMixColumns {
-+my @x=@_[0..7];
-+my @t=@_[8..15];
-+
-+# Thanks to Jussi Kivilinna for providing pointer to
-+#
-+# | 0e 0b 0d 09 |   | 02 03 01 01 |   | 05 00 04 00 |
-+# | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 |
-+# | 0d 09 0e 0b |   | 01 01 02 03 |   | 04 00 05 00 |
-+# | 0b 0d 09 0e |   | 03 01 01 02 |   | 00 04 00 05 |
-+
-+$code.=<<___;
-+	@ multiplication by 0x05-0x00-0x04-0x00
-+	vext.8	@t[0], @x[0], @x[0], #8
-+	vext.8	@t[6], @x[6], @x[6], #8
-+	vext.8	@t[7], @x[7], @x[7], #8
-+	veor	@t[0], @t[0], @x[0]
-+	vext.8	@t[1], @x[1], @x[1], #8
-+	veor	@t[6], @t[6], @x[6]
-+	vext.8	@t[2], @x[2], @x[2], #8
-+	veor	@t[7], @t[7], @x[7]
-+	vext.8	@t[3], @x[3], @x[3], #8
-+	veor	@t[1], @t[1], @x[1]
-+	vext.8	@t[4], @x[4], @x[4], #8
-+	veor	@t[2], @t[2], @x[2]
-+	vext.8	@t[5], @x[5], @x[5], #8
-+	veor	@t[3], @t[3], @x[3]
-+	veor	@t[4], @t[4], @x[4]
-+	veor	@t[5], @t[5], @x[5]
-+
-+	 veor	@x[0], @x[0], @t[6]
-+	 veor	@x[1], @x[1], @t[6]
-+	 veor	@x[2], @x[2], @t[0]
-+	 veor	@x[4], @x[4], @t[2]
-+	 veor	@x[3], @x[3], @t[1]
-+	 veor	@x[1], @x[1], @t[7]
-+	 veor	@x[2], @x[2], @t[7]
-+	 veor	@x[4], @x[4], @t[6]
-+	 veor	@x[5], @x[5], @t[3]
-+	 veor	@x[3], @x[3], @t[6]
-+	 veor	@x[6], @x[6], @t[4]
-+	 veor	@x[4], @x[4], @t[7]
-+	 veor	@x[5], @x[5], @t[7]
-+	 veor	@x[7], @x[7], @t[5]
-+___
-+	&MixColumns	(@x,@t,1);	# flipped 2<->3 and 4<->6
-+}
-+
-+sub swapmove {
-+my ($a,$b,$n,$mask,$t)=@_;
-+$code.=<<___;
-+	vshr.u64	$t, $b, #$n
-+	veor		$t, $t, $a
-+	vand		$t, $t, $mask
-+	veor		$a, $a, $t
-+	vshl.u64	$t, $t, #$n
-+	veor		$b, $b, $t
-+___
-+}
-+sub swapmove2x {
-+my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_;
-+$code.=<<___;
-+	vshr.u64	$t0, $b0, #$n
-+	 vshr.u64	$t1, $b1, #$n
-+	veor		$t0, $t0, $a0
-+	 veor		$t1, $t1, $a1
-+	vand		$t0, $t0, $mask
-+	 vand		$t1, $t1, $mask
-+	veor		$a0, $a0, $t0
-+	vshl.u64	$t0, $t0, #$n
-+	 veor		$a1, $a1, $t1
-+	 vshl.u64	$t1, $t1, #$n
-+	veor		$b0, $b0, $t0
-+	 veor		$b1, $b1, $t1
-+___
-+}
-+
-+sub bitslice {
-+my @x=reverse(@_[0..7]);
-+my ($t0,$t1,$t2,$t3)=@_[8..11];
-+$code.=<<___;
-+	vmov.i8	$t0,#0x55			@ compose .LBS0
-+	vmov.i8	$t1,#0x33			@ compose .LBS1
-+___
-+	&swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3);
-+	&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
-+$code.=<<___;
-+	vmov.i8	$t0,#0x0f			@ compose .LBS2
-+___
-+	&swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3);
-+	&swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
-+
-+	&swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3);
-+	&swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3);
-+}
-+
-+$code.=<<___;
-+#ifndef __KERNEL__
-+# include "arm_arch.h"
-+
-+# define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
-+# define VFP_ABI_POP	vldmia	sp!,{d8-d15}
-+# define VFP_ABI_FRAME	0x40
-+#else
-+# define VFP_ABI_PUSH
-+# define VFP_ABI_POP
-+# define VFP_ABI_FRAME	0
-+# define BSAES_ASM_EXTENDED_KEY
-+# define XTS_CHAIN_TWEAK
-+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
-+# define __ARM_MAX_ARCH__ 7
-+#endif
-+
-+#ifdef __thumb__
-+# define adrl adr
-+#endif
-+
-+#if __ARM_MAX_ARCH__>=7
-+.arch	armv7-a
-+.fpu	neon
-+
-+.text
-+.syntax	unified 	@ ARMv7-capable assembler is expected to handle this
-+#if defined(__thumb2__) && !defined(__APPLE__)
-+.thumb
-+#else
-+.code   32
-+# undef __thumb2__
-+#endif
-+
-+.type	_bsaes_decrypt8,%function
-+.align	4
-+_bsaes_decrypt8:
-+	adr	$const,_bsaes_decrypt8
-+	vldmia	$key!, {@XMM[9]}		@ round 0 key
-+#ifdef	__APPLE__
-+	adr	$const,.LM0ISR
-+#else
-+	add	$const,$const,#.LM0ISR-_bsaes_decrypt8
-+#endif
-+
-+	vldmia	$const!, {@XMM[8]}		@ .LM0ISR
-+	veor	@XMM[10], @XMM[0], @XMM[9]	@ xor with round0 key
-+	veor	@XMM[11], @XMM[1], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[0])`, {@XMM[10]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[0])`, {@XMM[10]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[12], @XMM[2], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[1])`, {@XMM[11]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[1])`, {@XMM[11]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[13], @XMM[3], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[2])`, {@XMM[12]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[2])`, {@XMM[12]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[14], @XMM[4], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[3])`, {@XMM[13]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[3])`, {@XMM[13]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[15], @XMM[5], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[4])`, {@XMM[14]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[4])`, {@XMM[14]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[10], @XMM[6], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[5])`, {@XMM[15]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[5])`, {@XMM[15]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[11], @XMM[7], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[6])`, {@XMM[10]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[6])`, {@XMM[10]}, `&Dhi(@XMM[8])`
-+	 vtbl.8	`&Dlo(@XMM[7])`, {@XMM[11]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[7])`, {@XMM[11]}, `&Dhi(@XMM[8])`
-+___
-+	&bitslice	(@XMM[0..7, 8..11]);
-+$code.=<<___;
-+	sub	$rounds,$rounds,#1
-+	b	.Ldec_sbox
-+.align	4
-+.Ldec_loop:
-+___
-+	&ShiftRows	(@XMM[0..7, 8..12]);
-+$code.=".Ldec_sbox:\n";
-+	&InvSbox	(@XMM[0..7, 8..15]);
-+$code.=<<___;
-+	subs	$rounds,$rounds,#1
-+	bcc	.Ldec_done
-+___
-+	&InvMixColumns	(@XMM[0,1,6,4,2,7,3,5, 8..15]);
-+$code.=<<___;
-+	vldmia	$const, {@XMM[12]}		@ .LISR
-+	ite	eq				@ Thumb2 thing, sanity check in ARM
-+	addeq	$const,$const,#0x10
-+	bne	.Ldec_loop
-+	vldmia	$const, {@XMM[12]}		@ .LISRM0
-+	b	.Ldec_loop
-+.align	4
-+.Ldec_done:
-+___
-+	&bitslice	(@XMM[0,1,6,4,2,7,3,5, 8..11]);
-+$code.=<<___;
-+	vldmia	$key, {@XMM[8]}			@ last round key
-+	veor	@XMM[6], @XMM[6], @XMM[8]
-+	veor	@XMM[4], @XMM[4], @XMM[8]
-+	veor	@XMM[2], @XMM[2], @XMM[8]
-+	veor	@XMM[7], @XMM[7], @XMM[8]
-+	veor	@XMM[3], @XMM[3], @XMM[8]
-+	veor	@XMM[5], @XMM[5], @XMM[8]
-+	veor	@XMM[0], @XMM[0], @XMM[8]
-+	veor	@XMM[1], @XMM[1], @XMM[8]
-+	bx	lr
-+.size	_bsaes_decrypt8,.-_bsaes_decrypt8
-+
-+.type	_bsaes_const,%object
-+.align	6
-+_bsaes_const:
-+.LM0ISR:	@ InvShiftRows constants
-+	.quad	0x0a0e0206070b0f03, 0x0004080c0d010509
-+.LISR:
-+	.quad	0x0504070602010003, 0x0f0e0d0c080b0a09
-+.LISRM0:
-+	.quad	0x01040b0e0205080f, 0x0306090c00070a0d
-+.LM0SR:		@ ShiftRows constants
-+	.quad	0x0a0e02060f03070b, 0x0004080c05090d01
-+.LSR:
-+	.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
-+.LSRM0:
-+	.quad	0x0304090e00050a0f, 0x01060b0c0207080d
-+.LM0:
-+	.quad	0x02060a0e03070b0f, 0x0004080c0105090d
-+.LREVM0SR:
-+	.quad	0x090d01050c000408, 0x03070b0f060a0e02
-+.asciz	"Bit-sliced AES for NEON, CRYPTOGAMS by "
-+.align	6
-+.size	_bsaes_const,.-_bsaes_const
-+
-+.type	_bsaes_encrypt8,%function
-+.align	4
-+_bsaes_encrypt8:
-+	adr	$const,_bsaes_encrypt8
-+	vldmia	$key!, {@XMM[9]}		@ round 0 key
-+#ifdef	__APPLE__
-+	adr	$const,.LM0SR
-+#else
-+	sub	$const,$const,#_bsaes_encrypt8-.LM0SR
-+#endif
-+
-+	vldmia	$const!, {@XMM[8]}		@ .LM0SR
-+_bsaes_encrypt8_alt:
-+	veor	@XMM[10], @XMM[0], @XMM[9]	@ xor with round0 key
-+	veor	@XMM[11], @XMM[1], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[0])`, {@XMM[10]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[0])`, {@XMM[10]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[12], @XMM[2], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[1])`, {@XMM[11]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[1])`, {@XMM[11]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[13], @XMM[3], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[2])`, {@XMM[12]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[2])`, {@XMM[12]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[14], @XMM[4], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[3])`, {@XMM[13]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[3])`, {@XMM[13]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[15], @XMM[5], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[4])`, {@XMM[14]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[4])`, {@XMM[14]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[10], @XMM[6], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[5])`, {@XMM[15]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[5])`, {@XMM[15]}, `&Dhi(@XMM[8])`
-+	veor	@XMM[11], @XMM[7], @XMM[9]
-+	 vtbl.8	`&Dlo(@XMM[6])`, {@XMM[10]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[6])`, {@XMM[10]}, `&Dhi(@XMM[8])`
-+	 vtbl.8	`&Dlo(@XMM[7])`, {@XMM[11]}, `&Dlo(@XMM[8])`
-+	 vtbl.8	`&Dhi(@XMM[7])`, {@XMM[11]}, `&Dhi(@XMM[8])`
-+_bsaes_encrypt8_bitslice:
-+___
-+	&bitslice	(@XMM[0..7, 8..11]);
-+$code.=<<___;
-+	sub	$rounds,$rounds,#1
-+	b	.Lenc_sbox
-+.align	4
-+.Lenc_loop:
-+___
-+	&ShiftRows	(@XMM[0..7, 8..12]);
-+$code.=".Lenc_sbox:\n";
-+	&Sbox		(@XMM[0..7, 8..15]);
-+$code.=<<___;
-+	subs	$rounds,$rounds,#1
-+	bcc	.Lenc_done
-+___
-+	&MixColumns	(@XMM[0,1,4,6,3,7,2,5, 8..15]);
-+$code.=<<___;
-+	vldmia	$const, {@XMM[12]}		@ .LSR
-+	ite	eq				@ Thumb2 thing, samity check in ARM
-+	addeq	$const,$const,#0x10
-+	bne	.Lenc_loop
-+	vldmia	$const, {@XMM[12]}		@ .LSRM0
-+	b	.Lenc_loop
-+.align	4
-+.Lenc_done:
-+___
-+	# output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb
-+	&bitslice	(@XMM[0,1,4,6,3,7,2,5, 8..11]);
-+$code.=<<___;
-+	vldmia	$key, {@XMM[8]}			@ last round key
-+	veor	@XMM[4], @XMM[4], @XMM[8]
-+	veor	@XMM[6], @XMM[6], @XMM[8]
-+	veor	@XMM[3], @XMM[3], @XMM[8]
-+	veor	@XMM[7], @XMM[7], @XMM[8]
-+	veor	@XMM[2], @XMM[2], @XMM[8]
-+	veor	@XMM[5], @XMM[5], @XMM[8]
-+	veor	@XMM[0], @XMM[0], @XMM[8]
-+	veor	@XMM[1], @XMM[1], @XMM[8]
-+	bx	lr
-+.size	_bsaes_encrypt8,.-_bsaes_encrypt8
-+___
-+}
-+{
-+my ($out,$inp,$rounds,$const)=("r12","r4","r5","r6");
-+
-+sub bitslice_key {
-+my @x=reverse(@_[0..7]);
-+my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12];
-+
-+	&swapmove	(@x[0,1],1,$bs0,$t2,$t3);
-+$code.=<<___;
-+	@ &swapmove(@x[2,3],1,$t0,$t2,$t3);
-+	vmov	@x[2], @x[0]
-+	vmov	@x[3], @x[1]
-+___
-+	#&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
-+
-+	&swapmove2x	(@x[0,2,1,3],2,$bs1,$t2,$t3);
-+$code.=<<___;
-+	@ &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
-+	vmov	@x[4], @x[0]
-+	vmov	@x[6], @x[2]
-+	vmov	@x[5], @x[1]
-+	vmov	@x[7], @x[3]
-+___
-+	&swapmove2x	(@x[0,4,1,5],4,$bs2,$t2,$t3);
-+	&swapmove2x	(@x[2,6,3,7],4,$bs2,$t2,$t3);
-+}
-+
-+$code.=<<___;
-+.type	_bsaes_key_convert,%function
-+.align	4
-+_bsaes_key_convert:
-+	adr	$const,_bsaes_key_convert
-+	vld1.8	{@XMM[7]},  [$inp]!		@ load round 0 key
-+#ifdef	__APPLE__
-+	adr	$const,.LM0
-+#else
-+	sub	$const,$const,#_bsaes_key_convert-.LM0
-+#endif
-+	vld1.8	{@XMM[15]}, [$inp]!		@ load round 1 key
-+
-+	vmov.i8	@XMM[8],  #0x01			@ bit masks
-+	vmov.i8	@XMM[9],  #0x02
-+	vmov.i8	@XMM[10], #0x04
-+	vmov.i8	@XMM[11], #0x08
-+	vmov.i8	@XMM[12], #0x10
-+	vmov.i8	@XMM[13], #0x20
-+	vldmia	$const, {@XMM[14]}		@ .LM0
-+
-+#ifdef __ARMEL__
-+	vrev32.8	@XMM[7],  @XMM[7]
-+	vrev32.8	@XMM[15], @XMM[15]
-+#endif
-+	sub	$rounds,$rounds,#1
-+	vstmia	$out!, {@XMM[7]}		@ save round 0 key
-+	b	.Lkey_loop
-+
-+.align	4
-+.Lkey_loop:
-+	vtbl.8	`&Dlo(@XMM[7])`,{@XMM[15]},`&Dlo(@XMM[14])`
-+	vtbl.8	`&Dhi(@XMM[7])`,{@XMM[15]},`&Dhi(@XMM[14])`
-+	vmov.i8	@XMM[6],  #0x40
-+	vmov.i8	@XMM[15], #0x80
-+
-+	vtst.8	@XMM[0], @XMM[7], @XMM[8]
-+	vtst.8	@XMM[1], @XMM[7], @XMM[9]
-+	vtst.8	@XMM[2], @XMM[7], @XMM[10]
-+	vtst.8	@XMM[3], @XMM[7], @XMM[11]
-+	vtst.8	@XMM[4], @XMM[7], @XMM[12]
-+	vtst.8	@XMM[5], @XMM[7], @XMM[13]
-+	vtst.8	@XMM[6], @XMM[7], @XMM[6]
-+	vtst.8	@XMM[7], @XMM[7], @XMM[15]
-+	vld1.8	{@XMM[15]}, [$inp]!		@ load next round key
-+	vmvn	@XMM[0], @XMM[0]		@ "pnot"
-+	vmvn	@XMM[1], @XMM[1]
-+	vmvn	@XMM[5], @XMM[5]
-+	vmvn	@XMM[6], @XMM[6]
-+#ifdef __ARMEL__
-+	vrev32.8	@XMM[15], @XMM[15]
-+#endif
-+	subs	$rounds,$rounds,#1
-+	vstmia	$out!,{@XMM[0]-@XMM[7]}		@ write bit-sliced round key
-+	bne	.Lkey_loop
-+
-+	vmov.i8	@XMM[7],#0x63			@ compose .L63
-+	@ don't save last round key
-+	bx	lr
-+.size	_bsaes_key_convert,.-_bsaes_key_convert
-+___
-+}
-+
-+if (0) {		# following four functions are unsupported interface
-+			# used for benchmarking...
-+$code.=<<___;
-+.globl	bsaes_enc_key_convert
-+.type	bsaes_enc_key_convert,%function
-+.align	4
-+bsaes_enc_key_convert:
-+	stmdb	sp!,{r4-r6,lr}
-+	vstmdb	sp!,{d8-d15}		@ ABI specification says so
-+
-+	ldr	r5,[$inp,#240]			@ pass rounds
-+	mov	r4,$inp				@ pass key
-+	mov	r12,$out			@ pass key schedule
-+	bl	_bsaes_key_convert
-+	veor	@XMM[7],@XMM[7],@XMM[15]	@ fix up last round key
-+	vstmia	r12, {@XMM[7]}			@ save last round key
-+
-+	vldmia	sp!,{d8-d15}
-+	ldmia	sp!,{r4-r6,pc}
-+.size	bsaes_enc_key_convert,.-bsaes_enc_key_convert
-+
-+.globl	bsaes_encrypt_128
-+.type	bsaes_encrypt_128,%function
-+.align	4
-+bsaes_encrypt_128:
-+	stmdb	sp!,{r4-r6,lr}
-+	vstmdb	sp!,{d8-d15}		@ ABI specification says so
-+.Lenc128_loop:
-+	vld1.8	{@XMM[0]-@XMM[1]}, [$inp]!	@ load input
-+	vld1.8	{@XMM[2]-@XMM[3]}, [$inp]!
-+	mov	r4,$key				@ pass the key
-+	vld1.8	{@XMM[4]-@XMM[5]}, [$inp]!
-+	mov	r5,#10				@ pass rounds
-+	vld1.8	{@XMM[6]-@XMM[7]}, [$inp]!
-+
-+	bl	_bsaes_encrypt8
-+
-+	vst1.8	{@XMM[0]-@XMM[1]}, [$out]!	@ write output
-+	vst1.8	{@XMM[4]}, [$out]!
-+	vst1.8	{@XMM[6]}, [$out]!
-+	vst1.8	{@XMM[3]}, [$out]!
-+	vst1.8	{@XMM[7]}, [$out]!
-+	vst1.8	{@XMM[2]}, [$out]!
-+	subs	$len,$len,#0x80
-+	vst1.8	{@XMM[5]}, [$out]!
-+	bhi	.Lenc128_loop
-+
-+	vldmia	sp!,{d8-d15}
-+	ldmia	sp!,{r4-r6,pc}
-+.size	bsaes_encrypt_128,.-bsaes_encrypt_128
-+
-+.globl	bsaes_dec_key_convert
-+.type	bsaes_dec_key_convert,%function
-+.align	4
-+bsaes_dec_key_convert:
-+	stmdb	sp!,{r4-r6,lr}
-+	vstmdb	sp!,{d8-d15}		@ ABI specification says so
-+
-+	ldr	r5,[$inp,#240]			@ pass rounds
-+	mov	r4,$inp				@ pass key
-+	mov	r12,$out			@ pass key schedule
-+	bl	_bsaes_key_convert
-+	vldmia	$out, {@XMM[6]}
-+	vstmia	r12,  {@XMM[15]}		@ save last round key
-+	veor	@XMM[7], @XMM[7], @XMM[6]	@ fix up round 0 key
-+	vstmia	$out, {@XMM[7]}
-+
-+	vldmia	sp!,{d8-d15}
-+	ldmia	sp!,{r4-r6,pc}
-+.size	bsaes_dec_key_convert,.-bsaes_dec_key_convert
-+
-+.globl	bsaes_decrypt_128
-+.type	bsaes_decrypt_128,%function
-+.align	4
-+bsaes_decrypt_128:
-+	stmdb	sp!,{r4-r6,lr}
-+	vstmdb	sp!,{d8-d15}		@ ABI specification says so
-+.Ldec128_loop:
-+	vld1.8	{@XMM[0]-@XMM[1]}, [$inp]!	@ load input
-+	vld1.8	{@XMM[2]-@XMM[3]}, [$inp]!
-+	mov	r4,$key				@ pass the key
-+	vld1.8	{@XMM[4]-@XMM[5]}, [$inp]!
-+	mov	r5,#10				@ pass rounds
-+	vld1.8	{@XMM[6]-@XMM[7]}, [$inp]!
-+
-+	bl	_bsaes_decrypt8
-+
-+	vst1.8	{@XMM[0]-@XMM[1]}, [$out]!	@ write output
-+	vst1.8	{@XMM[6]}, [$out]!
-+	vst1.8	{@XMM[4]}, [$out]!
-+	vst1.8	{@XMM[2]}, [$out]!
-+	vst1.8	{@XMM[7]}, [$out]!
-+	vst1.8	{@XMM[3]}, [$out]!
-+	subs	$len,$len,#0x80
-+	vst1.8	{@XMM[5]}, [$out]!
-+	bhi	.Ldec128_loop
-+
-+	vldmia	sp!,{d8-d15}
-+	ldmia	sp!,{r4-r6,pc}
-+.size	bsaes_decrypt_128,.-bsaes_decrypt_128
-+___
-+}
-+{
-+my ($inp,$out,$len,$key, $ivp,$fp,$rounds)=map("r$_",(0..3,8..10));
-+my ($keysched)=("sp");
-+
-+$code.=<<___;
-+.extern AES_cbc_encrypt
-+.extern AES_decrypt
-+
-+.global	bsaes_cbc_encrypt
-+.type	bsaes_cbc_encrypt,%function
-+.align	5
-+bsaes_cbc_encrypt:
-+#ifndef	__KERNEL__
-+	cmp	$len, #128
-+#ifndef	__thumb__
-+	blo	AES_cbc_encrypt
-+#else
-+	bhs	1f
-+	b	AES_cbc_encrypt
-+1:
-+#endif
-+#endif
-+
-+	@ it is up to the caller to make sure we are called with enc == 0
-+
-+	mov	ip, sp
-+	stmdb	sp!, {r4-r10, lr}
-+	VFP_ABI_PUSH
-+	ldr	$ivp, [ip]			@ IV is 1st arg on the stack
-+	mov	$len, $len, lsr#4		@ len in 16 byte blocks
-+	sub	sp, #0x10			@ scratch space to carry over the IV
-+	mov	$fp, sp				@ save sp
-+
-+	ldr	$rounds, [$key, #240]		@ get # of rounds
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	@ allocate the key schedule on the stack
-+	sub	r12, sp, $rounds, lsl#7		@ 128 bytes per inner round key
-+	add	r12, #`128-32`			@ sifze of bit-slices key schedule
-+
-+	@ populate the key schedule
-+	mov	r4, $key			@ pass key
-+	mov	r5, $rounds			@ pass # of rounds
-+	mov	sp, r12				@ sp is $keysched
-+	bl	_bsaes_key_convert
-+	vldmia	$keysched, {@XMM[6]}
-+	vstmia	r12,  {@XMM[15]}		@ save last round key
-+	veor	@XMM[7], @XMM[7], @XMM[6]	@ fix up round 0 key
-+	vstmia	$keysched, {@XMM[7]}
-+#else
-+	ldr	r12, [$key, #244]
-+	eors	r12, #1
-+	beq	0f
-+
-+	@ populate the key schedule
-+	str	r12, [$key, #244]
-+	mov	r4, $key			@ pass key
-+	mov	r5, $rounds			@ pass # of rounds
-+	add	r12, $key, #248			@ pass key schedule
-+	bl	_bsaes_key_convert
-+	add	r4, $key, #248
-+	vldmia	r4, {@XMM[6]}
-+	vstmia	r12, {@XMM[15]}			@ save last round key
-+	veor	@XMM[7], @XMM[7], @XMM[6]	@ fix up round 0 key
-+	vstmia	r4, {@XMM[7]}
-+
-+.align	2
-+0:
-+#endif
-+
-+	vld1.8	{@XMM[15]}, [$ivp]		@ load IV
-+	b	.Lcbc_dec_loop
-+
-+.align	4
-+.Lcbc_dec_loop:
-+	subs	$len, $len, #0x8
-+	bmi	.Lcbc_dec_loop_finish
-+
-+	vld1.8	{@XMM[0]-@XMM[1]}, [$inp]!	@ load input
-+	vld1.8	{@XMM[2]-@XMM[3]}, [$inp]!
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	mov	r4, $keysched			@ pass the key
-+#else
-+	add	r4, $key, #248
-+#endif
-+	vld1.8	{@XMM[4]-@XMM[5]}, [$inp]!
-+	mov	r5, $rounds
-+	vld1.8	{@XMM[6]-@XMM[7]}, [$inp]
-+	sub	$inp, $inp, #0x60
-+	vstmia	$fp, {@XMM[15]}			@ put aside IV
-+
-+	bl	_bsaes_decrypt8
-+
-+	vldmia	$fp, {@XMM[14]}			@ reload IV
-+	vld1.8	{@XMM[8]-@XMM[9]}, [$inp]!	@ reload input
-+	veor	@XMM[0], @XMM[0], @XMM[14]	@ ^= IV
-+	vld1.8	{@XMM[10]-@XMM[11]}, [$inp]!
-+	veor	@XMM[1], @XMM[1], @XMM[8]
-+	veor	@XMM[6], @XMM[6], @XMM[9]
-+	vld1.8	{@XMM[12]-@XMM[13]}, [$inp]!
-+	veor	@XMM[4], @XMM[4], @XMM[10]
-+	veor	@XMM[2], @XMM[2], @XMM[11]
-+	vld1.8	{@XMM[14]-@XMM[15]}, [$inp]!
-+	veor	@XMM[7], @XMM[7], @XMM[12]
-+	vst1.8	{@XMM[0]-@XMM[1]}, [$out]!	@ write output
-+	veor	@XMM[3], @XMM[3], @XMM[13]
-+	vst1.8	{@XMM[6]}, [$out]!
-+	veor	@XMM[5], @XMM[5], @XMM[14]
-+	vst1.8	{@XMM[4]}, [$out]!
-+	vst1.8	{@XMM[2]}, [$out]!
-+	vst1.8	{@XMM[7]}, [$out]!
-+	vst1.8	{@XMM[3]}, [$out]!
-+	vst1.8	{@XMM[5]}, [$out]!
-+
-+	b	.Lcbc_dec_loop
-+
-+.Lcbc_dec_loop_finish:
-+	adds	$len, $len, #8
-+	beq	.Lcbc_dec_done
-+
-+	vld1.8	{@XMM[0]}, [$inp]!		@ load input
-+	cmp	$len, #2
-+	blo	.Lcbc_dec_one
-+	vld1.8	{@XMM[1]}, [$inp]!
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	mov	r4, $keysched			@ pass the key
-+#else
-+	add	r4, $key, #248
-+#endif
-+	mov	r5, $rounds
-+	vstmia	$fp, {@XMM[15]}			@ put aside IV
-+	beq	.Lcbc_dec_two
-+	vld1.8	{@XMM[2]}, [$inp]!
-+	cmp	$len, #4
-+	blo	.Lcbc_dec_three
-+	vld1.8	{@XMM[3]}, [$inp]!
-+	beq	.Lcbc_dec_four
-+	vld1.8	{@XMM[4]}, [$inp]!
-+	cmp	$len, #6
-+	blo	.Lcbc_dec_five
-+	vld1.8	{@XMM[5]}, [$inp]!
-+	beq	.Lcbc_dec_six
-+	vld1.8	{@XMM[6]}, [$inp]!
-+	sub	$inp, $inp, #0x70
-+
-+	bl	_bsaes_decrypt8
-+
-+	vldmia	$fp, {@XMM[14]}			@ reload IV
-+	vld1.8	{@XMM[8]-@XMM[9]}, [$inp]!	@ reload input
-+	veor	@XMM[0], @XMM[0], @XMM[14]	@ ^= IV
-+	vld1.8	{@XMM[10]-@XMM[11]}, [$inp]!
-+	veor	@XMM[1], @XMM[1], @XMM[8]
-+	veor	@XMM[6], @XMM[6], @XMM[9]
-+	vld1.8	{@XMM[12]-@XMM[13]}, [$inp]!
-+	veor	@XMM[4], @XMM[4], @XMM[10]
-+	veor	@XMM[2], @XMM[2], @XMM[11]
-+	vld1.8	{@XMM[15]}, [$inp]!
-+	veor	@XMM[7], @XMM[7], @XMM[12]
-+	vst1.8	{@XMM[0]-@XMM[1]}, [$out]!	@ write output
-+	veor	@XMM[3], @XMM[3], @XMM[13]
-+	vst1.8	{@XMM[6]}, [$out]!
-+	vst1.8	{@XMM[4]}, [$out]!
-+	vst1.8	{@XMM[2]}, [$out]!
-+	vst1.8	{@XMM[7]}, [$out]!
-+	vst1.8	{@XMM[3]}, [$out]!
-+	b	.Lcbc_dec_done
-+.align	4
-+.Lcbc_dec_six:
-+	sub	$inp, $inp, #0x60
-+	bl	_bsaes_decrypt8
-+	vldmia	$fp,{@XMM[14]}			@ reload IV
-+	vld1.8	{@XMM[8]-@XMM[9]}, [$inp]!	@ reload input
-+	veor	@XMM[0], @XMM[0], @XMM[14]	@ ^= IV
-+	vld1.8	{@XMM[10]-@XMM[11]}, [$inp]!
-+	veor	@XMM[1], @XMM[1], @XMM[8]
-+	veor	@XMM[6], @XMM[6], @XMM[9]
-+	vld1.8	{@XMM[12]}, [$inp]!
-+	veor	@XMM[4], @XMM[4], @XMM[10]
-+	veor	@XMM[2], @XMM[2], @XMM[11]
-+	vld1.8	{@XMM[15]}, [$inp]!
-+	veor	@XMM[7], @XMM[7], @XMM[12]
-+	vst1.8	{@XMM[0]-@XMM[1]}, [$out]!	@ write output
-+	vst1.8	{@XMM[6]}, [$out]!
-+	vst1.8	{@XMM[4]}, [$out]!
-+	vst1.8	{@XMM[2]}, [$out]!
-+	vst1.8	{@XMM[7]}, [$out]!
-+	b	.Lcbc_dec_done
-+.align	4
-+.Lcbc_dec_five:
-+	sub	$inp, $inp, #0x50
-+	bl	_bsaes_decrypt8
-+	vldmia	$fp, {@XMM[14]}			@ reload IV
-+	vld1.8	{@XMM[8]-@XMM[9]}, [$inp]!	@ reload input
-+	veor	@XMM[0], @XMM[0], @XMM[14]	@ ^= IV
-+	vld1.8	{@XMM[10]-@XMM[11]}, [$inp]!
-+	veor	@XMM[1], @XMM[1], @XMM[8]
-+	veor	@XMM[6], @XMM[6], @XMM[9]
-+	vld1.8	{@XMM[15]}, [$inp]!
-+	veor	@XMM[4], @XMM[4], @XMM[10]
-+	vst1.8	{@XMM[0]-@XMM[1]}, [$out]!	@ write output
-+	veor	@XMM[2], @XMM[2], @XMM[11]
-+	vst1.8	{@XMM[6]}, [$out]!
-+	vst1.8	{@XMM[4]}, [$out]!
-+	vst1.8	{@XMM[2]}, [$out]!
-+	b	.Lcbc_dec_done
-+.align	4
-+.Lcbc_dec_four:
-+	sub	$inp, $inp, #0x40
-+	bl	_bsaes_decrypt8
-+	vldmia	$fp, {@XMM[14]}			@ reload IV
-+	vld1.8	{@XMM[8]-@XMM[9]}, [$inp]!	@ reload input
-+	veor	@XMM[0], @XMM[0], @XMM[14]	@ ^= IV
-+	vld1.8	{@XMM[10]}, [$inp]!
-+	veor	@XMM[1], @XMM[1], @XMM[8]
-+	veor	@XMM[6], @XMM[6], @XMM[9]
-+	vld1.8	{@XMM[15]}, [$inp]!
-+	veor	@XMM[4], @XMM[4], @XMM[10]
-+	vst1.8	{@XMM[0]-@XMM[1]}, [$out]!	@ write output
-+	vst1.8	{@XMM[6]}, [$out]!
-+	vst1.8	{@XMM[4]}, [$out]!
-+	b	.Lcbc_dec_done
-+.align	4
-+.Lcbc_dec_three:
-+	sub	$inp, $inp, #0x30
-+	bl	_bsaes_decrypt8
-+	vldmia	$fp, {@XMM[14]}			@ reload IV
-+	vld1.8	{@XMM[8]-@XMM[9]}, [$inp]!	@ reload input
-+	veor	@XMM[0], @XMM[0], @XMM[14]	@ ^= IV
-+	vld1.8	{@XMM[15]}, [$inp]!
-+	veor	@XMM[1], @XMM[1], @XMM[8]
-+	veor	@XMM[6], @XMM[6], @XMM[9]
-+	vst1.8	{@XMM[0]-@XMM[1]}, [$out]!	@ write output
-+	vst1.8	{@XMM[6]}, [$out]!
-+	b	.Lcbc_dec_done
-+.align	4
-+.Lcbc_dec_two:
-+	sub	$inp, $inp, #0x20
-+	bl	_bsaes_decrypt8
-+	vldmia	$fp, {@XMM[14]}			@ reload IV
-+	vld1.8	{@XMM[8]}, [$inp]!		@ reload input
-+	veor	@XMM[0], @XMM[0], @XMM[14]	@ ^= IV
-+	vld1.8	{@XMM[15]}, [$inp]!		@ reload input
-+	veor	@XMM[1], @XMM[1], @XMM[8]
-+	vst1.8	{@XMM[0]-@XMM[1]}, [$out]!	@ write output
-+	b	.Lcbc_dec_done
-+.align	4
-+.Lcbc_dec_one:
-+	sub	$inp, $inp, #0x10
-+	mov	$rounds, $out			@ save original out pointer
-+	mov	$out, $fp			@ use the iv scratch space as out buffer
-+	mov	r2, $key
-+	vmov	@XMM[4],@XMM[15]		@ just in case ensure that IV
-+	vmov	@XMM[5],@XMM[0]			@ and input are preserved
-+	bl	AES_decrypt
-+	vld1.8	{@XMM[0]}, [$fp,:64]		@ load result
-+	veor	@XMM[0], @XMM[0], @XMM[4]	@ ^= IV
-+	vmov	@XMM[15], @XMM[5]		@ @XMM[5] holds input
-+	vst1.8	{@XMM[0]}, [$rounds]		@ write output
-+
-+.Lcbc_dec_done:
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	vmov.i32	q0, #0
-+	vmov.i32	q1, #0
-+.Lcbc_dec_bzero:				@ wipe key schedule [if any]
-+	vstmia		$keysched!, {q0-q1}
-+	cmp		$keysched, $fp
-+	bne		.Lcbc_dec_bzero
-+#endif
-+
-+	mov	sp, $fp
-+	add	sp, #0x10			@ add sp,$fp,#0x10 is no good for thumb
-+	vst1.8	{@XMM[15]}, [$ivp]		@ return IV
-+	VFP_ABI_POP
-+	ldmia	sp!, {r4-r10, pc}
-+.size	bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
-+___
-+}
-+{
-+my ($inp,$out,$len,$key, $ctr,$fp,$rounds)=(map("r$_",(0..3,8..10)));
-+my $const = "r6";	# shared with _bsaes_encrypt8_alt
-+my $keysched = "sp";
-+
-+$code.=<<___;
-+.extern	AES_encrypt
-+.global	bsaes_ctr32_encrypt_blocks
-+.type	bsaes_ctr32_encrypt_blocks,%function
-+.align	5
-+bsaes_ctr32_encrypt_blocks:
-+	cmp	$len, #8			@ use plain AES for
-+	blo	.Lctr_enc_short			@ small sizes
-+
-+	mov	ip, sp
-+	stmdb	sp!, {r4-r10, lr}
-+	VFP_ABI_PUSH
-+	ldr	$ctr, [ip]			@ ctr is 1st arg on the stack
-+	sub	sp, sp, #0x10			@ scratch space to carry over the ctr
-+	mov	$fp, sp				@ save sp
-+
-+	ldr	$rounds, [$key, #240]		@ get # of rounds
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	@ allocate the key schedule on the stack
-+	sub	r12, sp, $rounds, lsl#7		@ 128 bytes per inner round key
-+	add	r12, #`128-32`			@ size of bit-sliced key schedule
-+
-+	@ populate the key schedule
-+	mov	r4, $key			@ pass key
-+	mov	r5, $rounds			@ pass # of rounds
-+	mov	sp, r12				@ sp is $keysched
-+	bl	_bsaes_key_convert
-+	veor	@XMM[7],@XMM[7],@XMM[15]	@ fix up last round key
-+	vstmia	r12, {@XMM[7]}			@ save last round key
-+
-+	vld1.8	{@XMM[0]}, [$ctr]		@ load counter
-+#ifdef	__APPLE__
-+	mov	$ctr, #:lower16:(.LREVM0SR-.LM0)
-+	add	$ctr, $const, $ctr
-+#else
-+	add	$ctr, $const, #.LREVM0SR-.LM0	@ borrow $ctr
-+#endif
-+	vldmia	$keysched, {@XMM[4]}		@ load round0 key
-+#else
-+	ldr	r12, [$key, #244]
-+	eors	r12, #1
-+	beq	0f
-+
-+	@ populate the key schedule
-+	str	r12, [$key, #244]
-+	mov	r4, $key			@ pass key
-+	mov	r5, $rounds			@ pass # of rounds
-+	add	r12, $key, #248			@ pass key schedule
-+	bl	_bsaes_key_convert
-+	veor	@XMM[7],@XMM[7],@XMM[15]	@ fix up last round key
-+	vstmia	r12, {@XMM[7]}			@ save last round key
-+
-+.align	2
-+0:	add	r12, $key, #248
-+	vld1.8	{@XMM[0]}, [$ctr]		@ load counter
-+	adrl	$ctr, .LREVM0SR			@ borrow $ctr
-+	vldmia	r12, {@XMM[4]}			@ load round0 key
-+	sub	sp, #0x10			@ place for adjusted round0 key
-+#endif
-+
-+	vmov.i32	@XMM[8],#1		@ compose 1<<96
-+	veor		@XMM[9],@XMM[9],@XMM[9]
-+	vrev32.8	@XMM[0],@XMM[0]
-+	vext.8		@XMM[8],@XMM[9],@XMM[8],#4
-+	vrev32.8	@XMM[4],@XMM[4]
-+	vadd.u32	@XMM[9],@XMM[8],@XMM[8]	@ compose 2<<96
-+	vstmia	$keysched, {@XMM[4]}		@ save adjusted round0 key
-+	b	.Lctr_enc_loop
-+
-+.align	4
-+.Lctr_enc_loop:
-+	vadd.u32	@XMM[10], @XMM[8], @XMM[9]	@ compose 3<<96
-+	vadd.u32	@XMM[1], @XMM[0], @XMM[8]	@ +1
-+	vadd.u32	@XMM[2], @XMM[0], @XMM[9]	@ +2
-+	vadd.u32	@XMM[3], @XMM[0], @XMM[10]	@ +3
-+	vadd.u32	@XMM[4], @XMM[1], @XMM[10]
-+	vadd.u32	@XMM[5], @XMM[2], @XMM[10]
-+	vadd.u32	@XMM[6], @XMM[3], @XMM[10]
-+	vadd.u32	@XMM[7], @XMM[4], @XMM[10]
-+	vadd.u32	@XMM[10], @XMM[5], @XMM[10]	@ next counter
-+
-+	@ Borrow prologue from _bsaes_encrypt8 to use the opportunity
-+	@ to flip byte order in 32-bit counter
-+
-+	vldmia		$keysched, {@XMM[9]}		@ load round0 key
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, $keysched, #0x10		@ pass next round key
-+#else
-+	add		r4, $key, #`248+16`
-+#endif
-+	vldmia		$ctr, {@XMM[8]}			@ .LREVM0SR
-+	mov		r5, $rounds			@ pass rounds
-+	vstmia		$fp, {@XMM[10]}			@ save next counter
-+#ifdef	__APPLE__
-+	mov		$const, #:lower16:(.LREVM0SR-.LSR)
-+	sub		$const, $ctr, $const
-+#else
-+	sub		$const, $ctr, #.LREVM0SR-.LSR	@ pass constants
-+#endif
-+
-+	bl		_bsaes_encrypt8_alt
-+
-+	subs		$len, $len, #8
-+	blo		.Lctr_enc_loop_done
-+
-+	vld1.8		{@XMM[8]-@XMM[9]}, [$inp]!	@ load input
-+	vld1.8		{@XMM[10]-@XMM[11]}, [$inp]!
-+	veor		@XMM[0], @XMM[8]
-+	veor		@XMM[1], @XMM[9]
-+	vld1.8		{@XMM[12]-@XMM[13]}, [$inp]!
-+	veor		@XMM[4], @XMM[10]
-+	veor		@XMM[6], @XMM[11]
-+	vld1.8		{@XMM[14]-@XMM[15]}, [$inp]!
-+	veor		@XMM[3], @XMM[12]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!	@ write output
-+	veor		@XMM[7], @XMM[13]
-+	veor		@XMM[2], @XMM[14]
-+	vst1.8		{@XMM[4]}, [$out]!
-+	veor		@XMM[5], @XMM[15]
-+	vst1.8		{@XMM[6]}, [$out]!
-+	vmov.i32	@XMM[8], #1			@ compose 1<<96
-+	vst1.8		{@XMM[3]}, [$out]!
-+	veor		@XMM[9], @XMM[9], @XMM[9]
-+	vst1.8		{@XMM[7]}, [$out]!
-+	vext.8		@XMM[8], @XMM[9], @XMM[8], #4
-+	vst1.8		{@XMM[2]}, [$out]!
-+	vadd.u32	@XMM[9],@XMM[8],@XMM[8]		@ compose 2<<96
-+	vst1.8		{@XMM[5]}, [$out]!
-+	vldmia		$fp, {@XMM[0]}			@ load counter
-+
-+	bne		.Lctr_enc_loop
-+	b		.Lctr_enc_done
-+
-+.align	4
-+.Lctr_enc_loop_done:
-+	add		$len, $len, #8
-+	vld1.8		{@XMM[8]}, [$inp]!	@ load input
-+	veor		@XMM[0], @XMM[8]
-+	vst1.8		{@XMM[0]}, [$out]!	@ write output
-+	cmp		$len, #2
-+	blo		.Lctr_enc_done
-+	vld1.8		{@XMM[9]}, [$inp]!
-+	veor		@XMM[1], @XMM[9]
-+	vst1.8		{@XMM[1]}, [$out]!
-+	beq		.Lctr_enc_done
-+	vld1.8		{@XMM[10]}, [$inp]!
-+	veor		@XMM[4], @XMM[10]
-+	vst1.8		{@XMM[4]}, [$out]!
-+	cmp		$len, #4
-+	blo		.Lctr_enc_done
-+	vld1.8		{@XMM[11]}, [$inp]!
-+	veor		@XMM[6], @XMM[11]
-+	vst1.8		{@XMM[6]}, [$out]!
-+	beq		.Lctr_enc_done
-+	vld1.8		{@XMM[12]}, [$inp]!
-+	veor		@XMM[3], @XMM[12]
-+	vst1.8		{@XMM[3]}, [$out]!
-+	cmp		$len, #6
-+	blo		.Lctr_enc_done
-+	vld1.8		{@XMM[13]}, [$inp]!
-+	veor		@XMM[7], @XMM[13]
-+	vst1.8		{@XMM[7]}, [$out]!
-+	beq		.Lctr_enc_done
-+	vld1.8		{@XMM[14]}, [$inp]
-+	veor		@XMM[2], @XMM[14]
-+	vst1.8		{@XMM[2]}, [$out]!
-+
-+.Lctr_enc_done:
-+	vmov.i32	q0, #0
-+	vmov.i32	q1, #0
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+.Lctr_enc_bzero:			@ wipe key schedule [if any]
-+	vstmia		$keysched!, {q0-q1}
-+	cmp		$keysched, $fp
-+	bne		.Lctr_enc_bzero
-+#else
-+	vstmia		$keysched, {q0-q1}
-+#endif
-+
-+	mov	sp, $fp
-+	add	sp, #0x10		@ add sp,$fp,#0x10 is no good for thumb
-+	VFP_ABI_POP
-+	ldmia	sp!, {r4-r10, pc}	@ return
-+
-+.align	4
-+.Lctr_enc_short:
-+	ldr	ip, [sp]		@ ctr pointer is passed on stack
-+	stmdb	sp!, {r4-r8, lr}
-+
-+	mov	r4, $inp		@ copy arguments
-+	mov	r5, $out
-+	mov	r6, $len
-+	mov	r7, $key
-+	ldr	r8, [ip, #12]		@ load counter LSW
-+	vld1.8	{@XMM[1]}, [ip]		@ load whole counter value
-+#ifdef __ARMEL__
-+	rev	r8, r8
-+#endif
-+	sub	sp, sp, #0x10
-+	vst1.8	{@XMM[1]}, [sp]		@ copy counter value
-+	sub	sp, sp, #0x10
-+
-+.Lctr_enc_short_loop:
-+	add	r0, sp, #0x10		@ input counter value
-+	mov	r1, sp			@ output on the stack
-+	mov	r2, r7			@ key
-+
-+	bl	AES_encrypt
-+
-+	vld1.8	{@XMM[0]}, [r4]!	@ load input
-+	vld1.8	{@XMM[1]}, [sp]		@ load encrypted counter
-+	add	r8, r8, #1
-+#ifdef __ARMEL__
-+	rev	r0, r8
-+	str	r0, [sp, #0x1c]		@ next counter value
-+#else
-+	str	r8, [sp, #0x1c]		@ next counter value
-+#endif
-+	veor	@XMM[0],@XMM[0],@XMM[1]
-+	vst1.8	{@XMM[0]}, [r5]!	@ store output
-+	subs	r6, r6, #1
-+	bne	.Lctr_enc_short_loop
-+
-+	vmov.i32	q0, #0
-+	vmov.i32	q1, #0
-+	vstmia		sp!, {q0-q1}
-+
-+	ldmia	sp!, {r4-r8, pc}
-+.size	bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
-+___
-+}
-+{
-+######################################################################
-+# void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len,
-+#	const AES_KEY *key1, const AES_KEY *key2,
-+#	const unsigned char iv[16]);
-+#
-+my ($inp,$out,$len,$key,$rounds,$magic,$fp)=(map("r$_",(7..10,1..3)));
-+my $const="r6";		# returned by _bsaes_key_convert
-+my $twmask=@XMM[5];
-+my @T=@XMM[6..7];
-+
-+$code.=<<___;
-+.globl	bsaes_xts_encrypt
-+.type	bsaes_xts_encrypt,%function
-+.align	4
-+bsaes_xts_encrypt:
-+	mov	ip, sp
-+	stmdb	sp!, {r4-r10, lr}		@ 0x20
-+	VFP_ABI_PUSH
-+	mov	r6, sp				@ future $fp
-+
-+	mov	$inp, r0
-+	mov	$out, r1
-+	mov	$len, r2
-+	mov	$key, r3
-+
-+	sub	r0, sp, #0x10			@ 0x10
-+	bic	r0, #0xf			@ align at 16 bytes
-+	mov	sp, r0
-+
-+#ifdef	XTS_CHAIN_TWEAK
-+	ldr	r0, [ip]			@ pointer to input tweak
-+#else
-+	@ generate initial tweak
-+	ldr	r0, [ip, #4]			@ iv[]
-+	mov	r1, sp
-+	ldr	r2, [ip, #0]			@ key2
-+	bl	AES_encrypt
-+	mov	r0,sp				@ pointer to initial tweak
-+#endif
-+
-+	ldr	$rounds, [$key, #240]		@ get # of rounds
-+	mov	$fp, r6
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	@ allocate the key schedule on the stack
-+	sub	r12, sp, $rounds, lsl#7		@ 128 bytes per inner round key
-+	@ add	r12, #`128-32`			@ size of bit-sliced key schedule
-+	sub	r12, #`32+16`			@ place for tweak[9]
-+
-+	@ populate the key schedule
-+	mov	r4, $key			@ pass key
-+	mov	r5, $rounds			@ pass # of rounds
-+	mov	sp, r12
-+	add	r12, #0x90			@ pass key schedule
-+	bl	_bsaes_key_convert
-+	veor	@XMM[7], @XMM[7], @XMM[15]	@ fix up last round key
-+	vstmia	r12, {@XMM[7]}			@ save last round key
-+#else
-+	ldr	r12, [$key, #244]
-+	eors	r12, #1
-+	beq	0f
-+
-+	str	r12, [$key, #244]
-+	mov	r4, $key			@ pass key
-+	mov	r5, $rounds			@ pass # of rounds
-+	add	r12, $key, #248			@ pass key schedule
-+	bl	_bsaes_key_convert
-+	veor	@XMM[7], @XMM[7], @XMM[15]	@ fix up last round key
-+	vstmia	r12, {@XMM[7]}
-+
-+.align	2
-+0:	sub	sp, #0x90			@ place for tweak[9]
-+#endif
-+
-+	vld1.8	{@XMM[8]}, [r0]			@ initial tweak
-+	adr	$magic, .Lxts_magic
-+
-+	subs	$len, #0x80
-+	blo	.Lxts_enc_short
-+	b	.Lxts_enc_loop
-+
-+.align	4
-+.Lxts_enc_loop:
-+	vldmia		$magic, {$twmask}	@ load XTS magic
-+	vshr.s64	@T[0], @XMM[8], #63
-+	mov		r0, sp
-+	vand		@T[0], @T[0], $twmask
-+___
-+for($i=9;$i<16;$i++) {
-+$code.=<<___;
-+	vadd.u64	@XMM[$i], @XMM[$i-1], @XMM[$i-1]
-+	vst1.64		{@XMM[$i-1]}, [r0,:128]!
-+	vswp		`&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-+	vshr.s64	@T[1], @XMM[$i], #63
-+	veor		@XMM[$i], @XMM[$i], @T[0]
-+	vand		@T[1], @T[1], $twmask
-+___
-+	@T=reverse(@T);
-+
-+$code.=<<___ if ($i>=10);
-+	vld1.8		{@XMM[$i-10]}, [$inp]!
-+___
-+$code.=<<___ if ($i>=11);
-+	veor		@XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
-+___
-+}
-+$code.=<<___;
-+	vadd.u64	@XMM[8], @XMM[15], @XMM[15]
-+	vst1.64		{@XMM[15]}, [r0,:128]!
-+	vswp		`&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-+	veor		@XMM[8], @XMM[8], @T[0]
-+	vst1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+
-+	vld1.8		{@XMM[6]-@XMM[7]}, [$inp]!
-+	veor		@XMM[5], @XMM[5], @XMM[13]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[6], @XMM[6], @XMM[14]
-+	mov		r5, $rounds			@ pass rounds
-+	veor		@XMM[7], @XMM[7], @XMM[15]
-+	mov		r0, sp
-+
-+	bl		_bsaes_encrypt8
-+
-+	vld1.64		{@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]-@XMM[11]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	vld1.64		{@XMM[12]-@XMM[13]}, [r0,:128]!
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[4], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	veor		@XMM[9], @XMM[6], @XMM[11]
-+	vld1.64		{@XMM[14]-@XMM[15]}, [r0,:128]!
-+	veor		@XMM[10], @XMM[3], @XMM[12]
-+	vst1.8		{@XMM[8]-@XMM[9]}, [$out]!
-+	veor		@XMM[11], @XMM[7], @XMM[13]
-+	veor		@XMM[12], @XMM[2], @XMM[14]
-+	vst1.8		{@XMM[10]-@XMM[11]}, [$out]!
-+	veor		@XMM[13], @XMM[5], @XMM[15]
-+	vst1.8		{@XMM[12]-@XMM[13]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+
-+	subs		$len, #0x80
-+	bpl		.Lxts_enc_loop
-+
-+.Lxts_enc_short:
-+	adds		$len, #0x70
-+	bmi		.Lxts_enc_done
-+
-+	vldmia		$magic, {$twmask}	@ load XTS magic
-+	vshr.s64	@T[0], @XMM[8], #63
-+	mov		r0, sp
-+	vand		@T[0], @T[0], $twmask
-+___
-+for($i=9;$i<16;$i++) {
-+$code.=<<___;
-+	vadd.u64	@XMM[$i], @XMM[$i-1], @XMM[$i-1]
-+	vst1.64		{@XMM[$i-1]}, [r0,:128]!
-+	vswp		`&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-+	vshr.s64	@T[1], @XMM[$i], #63
-+	veor		@XMM[$i], @XMM[$i], @T[0]
-+	vand		@T[1], @T[1], $twmask
-+___
-+	@T=reverse(@T);
-+
-+$code.=<<___ if ($i>=10);
-+	vld1.8		{@XMM[$i-10]}, [$inp]!
-+	subs		$len, #0x10
-+	bmi		.Lxts_enc_`$i-9`
-+___
-+$code.=<<___ if ($i>=11);
-+	veor		@XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
-+___
-+}
-+$code.=<<___;
-+	sub		$len, #0x10
-+	vst1.64		{@XMM[15]}, [r0,:128]		@ next round tweak
-+
-+	vld1.8		{@XMM[6]}, [$inp]!
-+	veor		@XMM[5], @XMM[5], @XMM[13]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[6], @XMM[6], @XMM[14]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_encrypt8
-+
-+	vld1.64		{@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]-@XMM[11]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	vld1.64		{@XMM[12]-@XMM[13]}, [r0,:128]!
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[4], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	veor		@XMM[9], @XMM[6], @XMM[11]
-+	vld1.64		{@XMM[14]}, [r0,:128]!
-+	veor		@XMM[10], @XMM[3], @XMM[12]
-+	vst1.8		{@XMM[8]-@XMM[9]}, [$out]!
-+	veor		@XMM[11], @XMM[7], @XMM[13]
-+	veor		@XMM[12], @XMM[2], @XMM[14]
-+	vst1.8		{@XMM[10]-@XMM[11]}, [$out]!
-+	vst1.8		{@XMM[12]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_enc_done
-+.align	4
-+.Lxts_enc_6:
-+	veor		@XMM[4], @XMM[4], @XMM[12]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[5], @XMM[5], @XMM[13]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_encrypt8
-+
-+	vld1.64		{@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]-@XMM[11]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	vld1.64		{@XMM[12]-@XMM[13]}, [r0,:128]!
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[4], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	veor		@XMM[9], @XMM[6], @XMM[11]
-+	veor		@XMM[10], @XMM[3], @XMM[12]
-+	vst1.8		{@XMM[8]-@XMM[9]}, [$out]!
-+	veor		@XMM[11], @XMM[7], @XMM[13]
-+	vst1.8		{@XMM[10]-@XMM[11]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_enc_done
-+
-+@ put this in range for both ARM and Thumb mode adr instructions
-+.align	5
-+.Lxts_magic:
-+	.quad	1, 0x87
-+
-+.align	5
-+.Lxts_enc_5:
-+	veor		@XMM[3], @XMM[3], @XMM[11]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[4], @XMM[4], @XMM[12]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_encrypt8
-+
-+	vld1.64		{@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]-@XMM[11]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	vld1.64		{@XMM[12]}, [r0,:128]!
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[4], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	veor		@XMM[9], @XMM[6], @XMM[11]
-+	veor		@XMM[10], @XMM[3], @XMM[12]
-+	vst1.8		{@XMM[8]-@XMM[9]}, [$out]!
-+	vst1.8		{@XMM[10]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_enc_done
-+.align	4
-+.Lxts_enc_4:
-+	veor		@XMM[2], @XMM[2], @XMM[10]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[3], @XMM[3], @XMM[11]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_encrypt8
-+
-+	vld1.64		{@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]-@XMM[11]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[4], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	veor		@XMM[9], @XMM[6], @XMM[11]
-+	vst1.8		{@XMM[8]-@XMM[9]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_enc_done
-+.align	4
-+.Lxts_enc_3:
-+	veor		@XMM[1], @XMM[1], @XMM[9]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[2], @XMM[2], @XMM[10]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_encrypt8
-+
-+	vld1.64		{@XMM[8]-@XMM[9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[4], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	vst1.8		{@XMM[8]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_enc_done
-+.align	4
-+.Lxts_enc_2:
-+	veor		@XMM[0], @XMM[0], @XMM[8]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[1], @XMM[1], @XMM[9]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_encrypt8
-+
-+	vld1.64		{@XMM[8]-@XMM[9]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_enc_done
-+.align	4
-+.Lxts_enc_1:
-+	mov		r0, sp
-+	veor		@XMM[0], @XMM[0], @XMM[8]
-+	mov		r1, sp
-+	vst1.8		{@XMM[0]}, [sp,:128]
-+	mov		r2, $key
-+	mov		r4, $fp				@ preserve fp
-+
-+	bl		AES_encrypt
-+
-+	vld1.8		{@XMM[0]}, [sp,:128]
-+	veor		@XMM[0], @XMM[0], @XMM[8]
-+	vst1.8		{@XMM[0]}, [$out]!
-+	mov		$fp, r4
-+
-+	vmov		@XMM[8], @XMM[9]		@ next round tweak
-+
-+.Lxts_enc_done:
-+#ifndef	XTS_CHAIN_TWEAK
-+	adds		$len, #0x10
-+	beq		.Lxts_enc_ret
-+	sub		r6, $out, #0x10
-+
-+.Lxts_enc_steal:
-+	ldrb		r0, [$inp], #1
-+	ldrb		r1, [$out, #-0x10]
-+	strb		r0, [$out, #-0x10]
-+	strb		r1, [$out], #1
-+
-+	subs		$len, #1
-+	bhi		.Lxts_enc_steal
-+
-+	vld1.8		{@XMM[0]}, [r6]
-+	mov		r0, sp
-+	veor		@XMM[0], @XMM[0], @XMM[8]
-+	mov		r1, sp
-+	vst1.8		{@XMM[0]}, [sp,:128]
-+	mov		r2, $key
-+	mov		r4, $fp			@ preserve fp
-+
-+	bl		AES_encrypt
-+
-+	vld1.8		{@XMM[0]}, [sp,:128]
-+	veor		@XMM[0], @XMM[0], @XMM[8]
-+	vst1.8		{@XMM[0]}, [r6]
-+	mov		$fp, r4
-+#endif
-+
-+.Lxts_enc_ret:
-+	bic		r0, $fp, #0xf
-+	vmov.i32	q0, #0
-+	vmov.i32	q1, #0
-+#ifdef	XTS_CHAIN_TWEAK
-+	ldr		r1, [$fp, #0x20+VFP_ABI_FRAME]	@ chain tweak
-+#endif
-+.Lxts_enc_bzero:				@ wipe key schedule [if any]
-+	vstmia		sp!, {q0-q1}
-+	cmp		sp, r0
-+	bne		.Lxts_enc_bzero
-+
-+	mov		sp, $fp
-+#ifdef	XTS_CHAIN_TWEAK
-+	vst1.8		{@XMM[8]}, [r1]
-+#endif
-+	VFP_ABI_POP
-+	ldmia		sp!, {r4-r10, pc}	@ return
-+
-+.size	bsaes_xts_encrypt,.-bsaes_xts_encrypt
-+
-+.globl	bsaes_xts_decrypt
-+.type	bsaes_xts_decrypt,%function
-+.align	4
-+bsaes_xts_decrypt:
-+	mov	ip, sp
-+	stmdb	sp!, {r4-r10, lr}		@ 0x20
-+	VFP_ABI_PUSH
-+	mov	r6, sp				@ future $fp
-+
-+	mov	$inp, r0
-+	mov	$out, r1
-+	mov	$len, r2
-+	mov	$key, r3
-+
-+	sub	r0, sp, #0x10			@ 0x10
-+	bic	r0, #0xf			@ align at 16 bytes
-+	mov	sp, r0
-+
-+#ifdef	XTS_CHAIN_TWEAK
-+	ldr	r0, [ip]			@ pointer to input tweak
-+#else
-+	@ generate initial tweak
-+	ldr	r0, [ip, #4]			@ iv[]
-+	mov	r1, sp
-+	ldr	r2, [ip, #0]			@ key2
-+	bl	AES_encrypt
-+	mov	r0, sp				@ pointer to initial tweak
-+#endif
-+
-+	ldr	$rounds, [$key, #240]		@ get # of rounds
-+	mov	$fp, r6
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	@ allocate the key schedule on the stack
-+	sub	r12, sp, $rounds, lsl#7		@ 128 bytes per inner round key
-+	@ add	r12, #`128-32`			@ size of bit-sliced key schedule
-+	sub	r12, #`32+16`			@ place for tweak[9]
-+
-+	@ populate the key schedule
-+	mov	r4, $key			@ pass key
-+	mov	r5, $rounds			@ pass # of rounds
-+	mov	sp, r12
-+	add	r12, #0x90			@ pass key schedule
-+	bl	_bsaes_key_convert
-+	add	r4, sp, #0x90
-+	vldmia	r4, {@XMM[6]}
-+	vstmia	r12,  {@XMM[15]}		@ save last round key
-+	veor	@XMM[7], @XMM[7], @XMM[6]	@ fix up round 0 key
-+	vstmia	r4, {@XMM[7]}
-+#else
-+	ldr	r12, [$key, #244]
-+	eors	r12, #1
-+	beq	0f
-+
-+	str	r12, [$key, #244]
-+	mov	r4, $key			@ pass key
-+	mov	r5, $rounds			@ pass # of rounds
-+	add	r12, $key, #248			@ pass key schedule
-+	bl	_bsaes_key_convert
-+	add	r4, $key, #248
-+	vldmia	r4, {@XMM[6]}
-+	vstmia	r12,  {@XMM[15]}		@ save last round key
-+	veor	@XMM[7], @XMM[7], @XMM[6]	@ fix up round 0 key
-+	vstmia	r4, {@XMM[7]}
-+
-+.align	2
-+0:	sub	sp, #0x90			@ place for tweak[9]
-+#endif
-+	vld1.8	{@XMM[8]}, [r0]			@ initial tweak
-+	adr	$magic, .Lxts_magic
-+
-+#ifndef	XTS_CHAIN_TWEAK
-+	tst	$len, #0xf			@ if not multiple of 16
-+	it	ne				@ Thumb2 thing, sanity check in ARM
-+	subne	$len, #0x10			@ subtract another 16 bytes
-+#endif
-+	subs	$len, #0x80
-+
-+	blo	.Lxts_dec_short
-+	b	.Lxts_dec_loop
-+
-+.align	4
-+.Lxts_dec_loop:
-+	vldmia		$magic, {$twmask}	@ load XTS magic
-+	vshr.s64	@T[0], @XMM[8], #63
-+	mov		r0, sp
-+	vand		@T[0], @T[0], $twmask
-+___
-+for($i=9;$i<16;$i++) {
-+$code.=<<___;
-+	vadd.u64	@XMM[$i], @XMM[$i-1], @XMM[$i-1]
-+	vst1.64		{@XMM[$i-1]}, [r0,:128]!
-+	vswp		`&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-+	vshr.s64	@T[1], @XMM[$i], #63
-+	veor		@XMM[$i], @XMM[$i], @T[0]
-+	vand		@T[1], @T[1], $twmask
-+___
-+	@T=reverse(@T);
-+
-+$code.=<<___ if ($i>=10);
-+	vld1.8		{@XMM[$i-10]}, [$inp]!
-+___
-+$code.=<<___ if ($i>=11);
-+	veor		@XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
-+___
-+}
-+$code.=<<___;
-+	vadd.u64	@XMM[8], @XMM[15], @XMM[15]
-+	vst1.64		{@XMM[15]}, [r0,:128]!
-+	vswp		`&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-+	veor		@XMM[8], @XMM[8], @T[0]
-+	vst1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+
-+	vld1.8		{@XMM[6]-@XMM[7]}, [$inp]!
-+	veor		@XMM[5], @XMM[5], @XMM[13]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[6], @XMM[6], @XMM[14]
-+	mov		r5, $rounds			@ pass rounds
-+	veor		@XMM[7], @XMM[7], @XMM[15]
-+	mov		r0, sp
-+
-+	bl		_bsaes_decrypt8
-+
-+	vld1.64		{@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]-@XMM[11]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	vld1.64		{@XMM[12]-@XMM[13]}, [r0,:128]!
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[6], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	veor		@XMM[9], @XMM[4], @XMM[11]
-+	vld1.64		{@XMM[14]-@XMM[15]}, [r0,:128]!
-+	veor		@XMM[10], @XMM[2], @XMM[12]
-+	vst1.8		{@XMM[8]-@XMM[9]}, [$out]!
-+	veor		@XMM[11], @XMM[7], @XMM[13]
-+	veor		@XMM[12], @XMM[3], @XMM[14]
-+	vst1.8		{@XMM[10]-@XMM[11]}, [$out]!
-+	veor		@XMM[13], @XMM[5], @XMM[15]
-+	vst1.8		{@XMM[12]-@XMM[13]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+
-+	subs		$len, #0x80
-+	bpl		.Lxts_dec_loop
-+
-+.Lxts_dec_short:
-+	adds		$len, #0x70
-+	bmi		.Lxts_dec_done
-+
-+	vldmia		$magic, {$twmask}	@ load XTS magic
-+	vshr.s64	@T[0], @XMM[8], #63
-+	mov		r0, sp
-+	vand		@T[0], @T[0], $twmask
-+___
-+for($i=9;$i<16;$i++) {
-+$code.=<<___;
-+	vadd.u64	@XMM[$i], @XMM[$i-1], @XMM[$i-1]
-+	vst1.64		{@XMM[$i-1]}, [r0,:128]!
-+	vswp		`&Dhi("@T[0]")`,`&Dlo("@T[0]")`
-+	vshr.s64	@T[1], @XMM[$i], #63
-+	veor		@XMM[$i], @XMM[$i], @T[0]
-+	vand		@T[1], @T[1], $twmask
-+___
-+	@T=reverse(@T);
-+
-+$code.=<<___ if ($i>=10);
-+	vld1.8		{@XMM[$i-10]}, [$inp]!
-+	subs		$len, #0x10
-+	bmi		.Lxts_dec_`$i-9`
-+___
-+$code.=<<___ if ($i>=11);
-+	veor		@XMM[$i-11], @XMM[$i-11], @XMM[$i-3]
-+___
-+}
-+$code.=<<___;
-+	sub		$len, #0x10
-+	vst1.64		{@XMM[15]}, [r0,:128]		@ next round tweak
-+
-+	vld1.8		{@XMM[6]}, [$inp]!
-+	veor		@XMM[5], @XMM[5], @XMM[13]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[6], @XMM[6], @XMM[14]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_decrypt8
-+
-+	vld1.64		{@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]-@XMM[11]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	vld1.64		{@XMM[12]-@XMM[13]}, [r0,:128]!
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[6], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	veor		@XMM[9], @XMM[4], @XMM[11]
-+	vld1.64		{@XMM[14]}, [r0,:128]!
-+	veor		@XMM[10], @XMM[2], @XMM[12]
-+	vst1.8		{@XMM[8]-@XMM[9]}, [$out]!
-+	veor		@XMM[11], @XMM[7], @XMM[13]
-+	veor		@XMM[12], @XMM[3], @XMM[14]
-+	vst1.8		{@XMM[10]-@XMM[11]}, [$out]!
-+	vst1.8		{@XMM[12]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_dec_done
-+.align	4
-+.Lxts_dec_6:
-+	vst1.64		{@XMM[14]}, [r0,:128]		@ next round tweak
-+
-+	veor		@XMM[4], @XMM[4], @XMM[12]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[5], @XMM[5], @XMM[13]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_decrypt8
-+
-+	vld1.64		{@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]-@XMM[11]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	vld1.64		{@XMM[12]-@XMM[13]}, [r0,:128]!
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[6], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	veor		@XMM[9], @XMM[4], @XMM[11]
-+	veor		@XMM[10], @XMM[2], @XMM[12]
-+	vst1.8		{@XMM[8]-@XMM[9]}, [$out]!
-+	veor		@XMM[11], @XMM[7], @XMM[13]
-+	vst1.8		{@XMM[10]-@XMM[11]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_dec_done
-+.align	4
-+.Lxts_dec_5:
-+	veor		@XMM[3], @XMM[3], @XMM[11]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[4], @XMM[4], @XMM[12]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_decrypt8
-+
-+	vld1.64		{@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]-@XMM[11]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	vld1.64		{@XMM[12]}, [r0,:128]!
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[6], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	veor		@XMM[9], @XMM[4], @XMM[11]
-+	veor		@XMM[10], @XMM[2], @XMM[12]
-+	vst1.8		{@XMM[8]-@XMM[9]}, [$out]!
-+	vst1.8		{@XMM[10]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_dec_done
-+.align	4
-+.Lxts_dec_4:
-+	veor		@XMM[2], @XMM[2], @XMM[10]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[3], @XMM[3], @XMM[11]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_decrypt8
-+
-+	vld1.64		{@XMM[ 8]-@XMM[ 9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]-@XMM[11]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[6], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	veor		@XMM[9], @XMM[4], @XMM[11]
-+	vst1.8		{@XMM[8]-@XMM[9]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_dec_done
-+.align	4
-+.Lxts_dec_3:
-+	veor		@XMM[1], @XMM[1], @XMM[9]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[2], @XMM[2], @XMM[10]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_decrypt8
-+
-+	vld1.64		{@XMM[8]-@XMM[9]}, [r0,:128]!
-+	vld1.64		{@XMM[10]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	veor		@XMM[8], @XMM[6], @XMM[10]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+	vst1.8		{@XMM[8]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_dec_done
-+.align	4
-+.Lxts_dec_2:
-+	veor		@XMM[0], @XMM[0], @XMM[8]
-+#ifndef	BSAES_ASM_EXTENDED_KEY
-+	add		r4, sp, #0x90			@ pass key schedule
-+#else
-+	add		r4, $key, #248			@ pass key schedule
-+#endif
-+	veor		@XMM[1], @XMM[1], @XMM[9]
-+	mov		r5, $rounds			@ pass rounds
-+	mov		r0, sp
-+
-+	bl		_bsaes_decrypt8
-+
-+	vld1.64		{@XMM[8]-@XMM[9]}, [r0,:128]!
-+	veor		@XMM[0], @XMM[0], @XMM[ 8]
-+	veor		@XMM[1], @XMM[1], @XMM[ 9]
-+	vst1.8		{@XMM[0]-@XMM[1]}, [$out]!
-+
-+	vld1.64		{@XMM[8]}, [r0,:128]		@ next round tweak
-+	b		.Lxts_dec_done
-+.align	4
-+.Lxts_dec_1:
-+	mov		r0, sp
-+	veor		@XMM[0], @XMM[0], @XMM[8]
-+	mov		r1, sp
-+	vst1.8		{@XMM[0]}, [sp,:128]
-+	mov		r5, $magic			@ preserve magic
-+	mov		r2, $key
-+	mov		r4, $fp				@ preserve fp
-+
-+	bl		AES_decrypt
-+
-+	vld1.8		{@XMM[0]}, [sp,:128]
-+	veor		@XMM[0], @XMM[0], @XMM[8]
-+	vst1.8		{@XMM[0]}, [$out]!
-+	mov		$fp, r4
-+	mov		$magic, r5
-+
-+	vmov		@XMM[8], @XMM[9]		@ next round tweak
-+
-+.Lxts_dec_done:
-+#ifndef	XTS_CHAIN_TWEAK
-+	adds		$len, #0x10
-+	beq		.Lxts_dec_ret
-+
-+	@ calculate one round of extra tweak for the stolen ciphertext
-+	vldmia		$magic, {$twmask}
-+	vshr.s64	@XMM[6], @XMM[8], #63
-+	vand		@XMM[6], @XMM[6], $twmask
-+	vadd.u64	@XMM[9], @XMM[8], @XMM[8]
-+	vswp		`&Dhi("@XMM[6]")`,`&Dlo("@XMM[6]")`
-+	veor		@XMM[9], @XMM[9], @XMM[6]
-+
-+	@ perform the final decryption with the last tweak value
-+	vld1.8		{@XMM[0]}, [$inp]!
-+	mov		r0, sp
-+	veor		@XMM[0], @XMM[0], @XMM[9]
-+	mov		r1, sp
-+	vst1.8		{@XMM[0]}, [sp,:128]
-+	mov		r2, $key
-+	mov		r4, $fp			@ preserve fp
-+
-+	bl		AES_decrypt
-+
-+	vld1.8		{@XMM[0]}, [sp,:128]
-+	veor		@XMM[0], @XMM[0], @XMM[9]
-+	vst1.8		{@XMM[0]}, [$out]
-+
-+	mov		r6, $out
-+.Lxts_dec_steal:
-+	ldrb		r1, [$out]
-+	ldrb		r0, [$inp], #1
-+	strb		r1, [$out, #0x10]
-+	strb		r0, [$out], #1
-+
-+	subs		$len, #1
-+	bhi		.Lxts_dec_steal
-+
-+	vld1.8		{@XMM[0]}, [r6]
-+	mov		r0, sp
-+	veor		@XMM[0], @XMM[8]
-+	mov		r1, sp
-+	vst1.8		{@XMM[0]}, [sp,:128]
-+	mov		r2, $key
-+
-+	bl		AES_decrypt
-+
-+	vld1.8		{@XMM[0]}, [sp,:128]
-+	veor		@XMM[0], @XMM[0], @XMM[8]
-+	vst1.8		{@XMM[0]}, [r6]
-+	mov		$fp, r4
-+#endif
-+
-+.Lxts_dec_ret:
-+	bic		r0, $fp, #0xf
-+	vmov.i32	q0, #0
-+	vmov.i32	q1, #0
-+#ifdef	XTS_CHAIN_TWEAK
-+	ldr		r1, [$fp, #0x20+VFP_ABI_FRAME]	@ chain tweak
-+#endif
-+.Lxts_dec_bzero:				@ wipe key schedule [if any]
-+	vstmia		sp!, {q0-q1}
-+	cmp		sp, r0
-+	bne		.Lxts_dec_bzero
-+
-+	mov		sp, $fp
-+#ifdef	XTS_CHAIN_TWEAK
-+	vst1.8		{@XMM[8]}, [r1]
-+#endif
-+	VFP_ABI_POP
-+	ldmia		sp!, {r4-r10, pc}	@ return
-+
-+.size	bsaes_xts_decrypt,.-bsaes_xts_decrypt
-+___
-+}
-+$code.=<<___;
-+#endif
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+
-+open SELF,$0;
-+while() {
-+	next if (/^#!/);
-+        last if (!s/^#/@/ and !/^$/);
-+        print;
-+}
-+close SELF;
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/bsaes-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/bsaes-x86_64.pl
-new file mode 100644
-index 0000000..921d870
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/bsaes-x86_64.pl
-@@ -0,0 +1,3111 @@
-+#! /usr/bin/env perl
-+# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+###################################################################
-+### AES-128 [originally in CTR mode]				###
-+### bitsliced implementation for Intel Core 2 processors	###
-+### requires support of SSE extensions up to SSSE3		###
-+### Author: Emilia Käsper and Peter Schwabe			###
-+### Date: 2009-03-19						###
-+### Public domain						###
-+###								###
-+### See http://homes.esat.kuleuven.be/~ekasper/#software for	###
-+### further information.					###
-+###################################################################
-+#
-+# September 2011.
-+#
-+# Started as transliteration to "perlasm" the original code has
-+# undergone following changes:
-+#
-+# - code was made position-independent;
-+# - rounds were folded into a loop resulting in >5x size reduction
-+#   from 12.5KB to 2.2KB;
-+# - above was possibile thanks to mixcolumns() modification that
-+#   allowed to feed its output back to aesenc[last], this was
-+#   achieved at cost of two additional inter-registers moves;
-+# - some instruction reordering and interleaving;
-+# - this module doesn't implement key setup subroutine, instead it
-+#   relies on conversion of "conventional" key schedule as returned
-+#   by AES_set_encrypt_key (see discussion below);
-+# - first and last round keys are treated differently, which allowed
-+#   to skip one shiftrows(), reduce bit-sliced key schedule and
-+#   speed-up conversion by 22%;
-+# - support for 192- and 256-bit keys was added;
-+#
-+# Resulting performance in CPU cycles spent to encrypt one byte out
-+# of 4096-byte buffer with 128-bit key is:
-+#
-+#		Emilia's	this(*)		difference
-+#
-+# Core 2    	9.30		8.69		+7%
-+# Nehalem(**) 	7.63		6.88		+11%
-+# Atom	    	17.1		16.4		+4%
-+# Silvermont	-		12.9
-+# Goldmont	-		8.85
-+#
-+# (*)	Comparison is not completely fair, because "this" is ECB,
-+#	i.e. no extra processing such as counter values calculation
-+#	and xor-ing input as in Emilia's CTR implementation is
-+#	performed. However, the CTR calculations stand for not more
-+#	than 1% of total time, so comparison is *rather* fair.
-+#
-+# (**)	Results were collected on Westmere, which is considered to
-+#	be equivalent to Nehalem for this code.
-+#
-+# As for key schedule conversion subroutine. Interface to OpenSSL
-+# relies on per-invocation on-the-fly conversion. This naturally
-+# has impact on performance, especially for short inputs. Conversion
-+# time in CPU cycles and its ratio to CPU cycles spent in 8x block
-+# function is:
-+#
-+# 		conversion	conversion/8x block
-+# Core 2	240		0.22
-+# Nehalem	180		0.20
-+# Atom		430		0.20
-+#
-+# The ratio values mean that 128-byte blocks will be processed
-+# 16-18% slower, 256-byte blocks - 9-10%, 384-byte blocks - 6-7%,
-+# etc. Then keep in mind that input sizes not divisible by 128 are
-+# *effectively* slower, especially shortest ones, e.g. consecutive
-+# 144-byte blocks are processed 44% slower than one would expect,
-+# 272 - 29%, 400 - 22%, etc. Yet, despite all these "shortcomings"
-+# it's still faster than ["hyper-threading-safe" code path in]
-+# aes-x86_64.pl on all lengths above 64 bytes...
-+#
-+# October 2011.
-+#
-+# Add decryption procedure. Performance in CPU cycles spent to decrypt
-+# one byte out of 4096-byte buffer with 128-bit key is:
-+#
-+# Core 2	9.98
-+# Nehalem	7.80
-+# Atom		17.9
-+# Silvermont	14.0
-+# Goldmont	10.2
-+#
-+# November 2011.
-+#
-+# Add bsaes_xts_[en|de]crypt. Less-than-80-bytes-block performance is
-+# suboptimal, but XTS is meant to be used with larger blocks...
-+#
-+#						
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+my ($inp,$out,$len,$key,$ivp)=("%rdi","%rsi","%rdx","%rcx");
-+my @XMM=map("%xmm$_",(15,0..14));	# best on Atom, +10% over (0..15)
-+my $ecb=0;	# suppress unreferenced ECB subroutines, spare some space...
-+
-+{
-+my ($key,$rounds,$const)=("%rax","%r10d","%r11");
-+
-+sub Sbox {
-+# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-+# output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb
-+my @b=@_[0..7];
-+my @t=@_[8..11];
-+my @s=@_[12..15];
-+	&InBasisChange	(@b);
-+	&Inv_GF256	(@b[6,5,0,3,7,1,4,2],@t,@s);
-+	&OutBasisChange	(@b[7,1,4,2,6,5,0,3]);
-+}
-+
-+sub InBasisChange {
-+# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-+# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb 
-+my @b=@_[0..7];
-+$code.=<<___;
-+	pxor	@b[6], @b[5]
-+	pxor	@b[1], @b[2]
-+	pxor	@b[0], @b[3]
-+	pxor	@b[2], @b[6]
-+	pxor 	@b[0], @b[5]
-+
-+	pxor	@b[3], @b[6]
-+	pxor	@b[7], @b[3]
-+	pxor	@b[5], @b[7]
-+	pxor	@b[4], @b[3]
-+	pxor	@b[5], @b[4]
-+	pxor	@b[1], @b[3]
-+
-+	pxor	@b[7], @b[2]
-+	pxor	@b[5], @b[1]
-+___
-+}
-+
-+sub OutBasisChange {
-+# input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-+# output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb
-+my @b=@_[0..7];
-+$code.=<<___;
-+	pxor	@b[6], @b[0]
-+	pxor	@b[4], @b[1]
-+	pxor	@b[0], @b[2]
-+	pxor	@b[6], @b[4]
-+	pxor	@b[1], @b[6]
-+
-+	pxor	@b[5], @b[1]
-+	pxor	@b[3], @b[5]
-+	pxor	@b[7], @b[3]
-+	pxor	@b[5], @b[7]
-+	pxor	@b[5], @b[2]
-+
-+	pxor	@b[7], @b[4]
-+___
-+}
-+
-+sub InvSbox {
-+# input in lsb 	> [b0, b1, b2, b3, b4, b5, b6, b7] < msb
-+# output in lsb	> [b0, b1, b6, b4, b2, b7, b3, b5] < msb
-+my @b=@_[0..7];
-+my @t=@_[8..11];
-+my @s=@_[12..15];
-+	&InvInBasisChange	(@b);
-+	&Inv_GF256		(@b[5,1,2,6,3,7,0,4],@t,@s);
-+	&InvOutBasisChange	(@b[3,7,0,4,5,1,2,6]);
-+}
-+
-+sub InvInBasisChange {		# OutBasisChange in reverse
-+my @b=@_[5,1,2,6,3,7,0,4];
-+$code.=<<___
-+	pxor	@b[7], @b[4]
-+
-+	pxor	@b[5], @b[7]
-+	pxor	@b[5], @b[2]
-+	pxor	@b[7], @b[3]
-+	pxor	@b[3], @b[5]
-+	pxor	@b[5], @b[1]
-+
-+	pxor	@b[1], @b[6]
-+	pxor	@b[0], @b[2]
-+	pxor	@b[6], @b[4]
-+	pxor	@b[6], @b[0]
-+	pxor	@b[4], @b[1]
-+___
-+}
-+
-+sub InvOutBasisChange {		# InBasisChange in reverse
-+my @b=@_[2,5,7,3,6,1,0,4];
-+$code.=<<___;
-+	pxor	@b[5], @b[1]
-+	pxor	@b[7], @b[2]
-+
-+	pxor	@b[1], @b[3]
-+	pxor	@b[5], @b[4]
-+	pxor	@b[5], @b[7]
-+	pxor	@b[4], @b[3]
-+	 pxor 	@b[0], @b[5]
-+	pxor	@b[7], @b[3]
-+	 pxor	@b[2], @b[6]
-+	 pxor	@b[1], @b[2]
-+	pxor	@b[3], @b[6]
-+
-+	pxor	@b[0], @b[3]
-+	pxor	@b[6], @b[5]
-+___
-+}
-+
-+sub Mul_GF4 {
-+#;*************************************************************
-+#;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) *
-+#;*************************************************************
-+my ($x0,$x1,$y0,$y1,$t0)=@_;
-+$code.=<<___;
-+	movdqa	$y0, $t0
-+	pxor 	$y1, $t0
-+	pand	$x0, $t0
-+	pxor	$x1, $x0
-+	pand	$y0, $x1
-+	pand	$y1, $x0
-+	pxor	$x1, $x0
-+	pxor	$t0, $x1
-+___
-+}
-+
-+sub Mul_GF4_N {				# not used, see next subroutine
-+# multiply and scale by N
-+my ($x0,$x1,$y0,$y1,$t0)=@_;
-+$code.=<<___;
-+	movdqa	$y0, $t0
-+	pxor	$y1, $t0
-+	pand	$x0, $t0
-+	pxor	$x1, $x0
-+	pand	$y0, $x1
-+	pand	$y1, $x0
-+	pxor	$x0, $x1
-+	pxor	$t0, $x0
-+___
-+}
-+
-+sub Mul_GF4_N_GF4 {
-+# interleaved Mul_GF4_N and Mul_GF4
-+my ($x0,$x1,$y0,$y1,$t0,
-+    $x2,$x3,$y2,$y3,$t1)=@_;
-+$code.=<<___;
-+	movdqa	$y0, $t0
-+	 movdqa	$y2, $t1
-+	pxor	$y1, $t0
-+	 pxor 	$y3, $t1
-+	pand	$x0, $t0
-+	 pand	$x2, $t1
-+	pxor	$x1, $x0
-+	 pxor	$x3, $x2
-+	pand	$y0, $x1
-+	 pand	$y2, $x3
-+	pand	$y1, $x0
-+	 pand	$y3, $x2
-+	pxor	$x0, $x1
-+	 pxor	$x3, $x2
-+	pxor	$t0, $x0
-+	 pxor	$t1, $x3
-+___
-+}
-+sub Mul_GF16_2 {
-+my @x=@_[0..7];
-+my @y=@_[8..11];
-+my @t=@_[12..15];
-+$code.=<<___;
-+	movdqa	@x[0], @t[0]
-+	movdqa	@x[1], @t[1]
-+___
-+	&Mul_GF4  	(@x[0], @x[1], @y[0], @y[1], @t[2]);
-+$code.=<<___;
-+	pxor	@x[2], @t[0]
-+	pxor	@x[3], @t[1]
-+	pxor	@y[2], @y[0]
-+	pxor	@y[3], @y[1]
-+___
-+	Mul_GF4_N_GF4	(@t[0], @t[1], @y[0], @y[1], @t[3],
-+			 @x[2], @x[3], @y[2], @y[3], @t[2]);
-+$code.=<<___;
-+	pxor	@t[0], @x[0]
-+	pxor	@t[0], @x[2]
-+	pxor	@t[1], @x[1]
-+	pxor	@t[1], @x[3]
-+
-+	movdqa	@x[4], @t[0]
-+	movdqa	@x[5], @t[1]
-+	pxor	@x[6], @t[0]
-+	pxor	@x[7], @t[1]
-+___
-+	&Mul_GF4_N_GF4	(@t[0], @t[1], @y[0], @y[1], @t[3],
-+			 @x[6], @x[7], @y[2], @y[3], @t[2]);
-+$code.=<<___;
-+	pxor	@y[2], @y[0]
-+	pxor	@y[3], @y[1]
-+___
-+	&Mul_GF4  	(@x[4], @x[5], @y[0], @y[1], @t[3]);
-+$code.=<<___;
-+	pxor	@t[0], @x[4]
-+	pxor	@t[0], @x[6]
-+	pxor	@t[1], @x[5]
-+	pxor	@t[1], @x[7]
-+___
-+}
-+sub Inv_GF256 {
-+#;********************************************************************
-+#;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144)       *
-+#;********************************************************************
-+my @x=@_[0..7];
-+my @t=@_[8..11];
-+my @s=@_[12..15];
-+# direct optimizations from hardware
-+$code.=<<___;
-+	movdqa	@x[4], @t[3]
-+	movdqa	@x[5], @t[2]
-+	movdqa	@x[1], @t[1]
-+	movdqa	@x[7], @s[1]
-+	movdqa	@x[0], @s[0]
-+
-+	pxor	@x[6], @t[3]
-+	pxor	@x[7], @t[2]
-+	pxor	@x[3], @t[1]
-+	 movdqa	@t[3], @s[2]
-+	pxor	@x[6], @s[1]
-+	 movdqa	@t[2], @t[0]
-+	pxor	@x[2], @s[0]
-+	 movdqa	@t[3], @s[3]
-+
-+	por	@t[1], @t[2]
-+	por	@s[0], @t[3]
-+	pxor	@t[0], @s[3]
-+	pand	@s[0], @s[2]
-+	pxor	@t[1], @s[0]
-+	pand	@t[1], @t[0]
-+	pand	@s[0], @s[3]
-+	movdqa	@x[3], @s[0]
-+	pxor	@x[2], @s[0]
-+	pand	@s[0], @s[1]
-+	pxor	@s[1], @t[3]
-+	pxor	@s[1], @t[2]
-+	movdqa	@x[4], @s[1]
-+	movdqa	@x[1], @s[0]
-+	pxor	@x[5], @s[1]
-+	pxor	@x[0], @s[0]
-+	movdqa	@s[1], @t[1]
-+	pand	@s[0], @s[1]
-+	por	@s[0], @t[1]
-+	pxor	@s[1], @t[0]
-+	pxor	@s[3], @t[3]
-+	pxor	@s[2], @t[2]
-+	pxor	@s[3], @t[1]
-+	movdqa	@x[7], @s[0]
-+	pxor	@s[2], @t[0]
-+	movdqa	@x[6], @s[1]
-+	pxor	@s[2], @t[1]
-+	movdqa	@x[5], @s[2]
-+	pand	@x[3], @s[0]
-+	movdqa	@x[4], @s[3]
-+	pand	@x[2], @s[1]
-+	pand	@x[1], @s[2]
-+	por	@x[0], @s[3]
-+	pxor	@s[0], @t[3]
-+	pxor	@s[1], @t[2]
-+	pxor	@s[2], @t[1]
-+	pxor	@s[3], @t[0] 
-+
-+	#Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
-+
-+	# new smaller inversion
-+
-+	movdqa	@t[3], @s[0]
-+	pand	@t[1], @t[3]
-+	pxor	@t[2], @s[0]
-+
-+	movdqa	@t[0], @s[2]
-+	movdqa	@s[0], @s[3]
-+	pxor	@t[3], @s[2]
-+	pand	@s[2], @s[3]
-+
-+	movdqa	@t[1], @s[1]
-+	pxor	@t[2], @s[3]
-+	pxor	@t[0], @s[1]
-+
-+	pxor	@t[2], @t[3]
-+
-+	pand	@t[3], @s[1]
-+
-+	movdqa	@s[2], @t[2]
-+	pxor	@t[0], @s[1]
-+
-+	pxor	@s[1], @t[2]
-+	pxor	@s[1], @t[1]
-+
-+	pand	@t[0], @t[2]
-+
-+	pxor	@t[2], @s[2]
-+	pxor	@t[2], @t[1]
-+
-+	pand	@s[3], @s[2]
-+
-+	pxor	@s[0], @s[2]
-+___
-+# output in s3, s2, s1, t1
-+
-+# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3
-+
-+# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
-+	&Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]);
-+
-+### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb
-+}
-+
-+# AES linear components
-+
-+sub ShiftRows {
-+my @x=@_[0..7];
-+my $mask=pop;
-+$code.=<<___;
-+	pxor	0x00($key),@x[0]
-+	pxor	0x10($key),@x[1]
-+	pxor	0x20($key),@x[2]
-+	pxor	0x30($key),@x[3]
-+	pshufb	$mask,@x[0]
-+	pshufb	$mask,@x[1]
-+	pxor	0x40($key),@x[4]
-+	pxor	0x50($key),@x[5]
-+	pshufb	$mask,@x[2]
-+	pshufb	$mask,@x[3]
-+	pxor	0x60($key),@x[6]
-+	pxor	0x70($key),@x[7]
-+	pshufb	$mask,@x[4]
-+	pshufb	$mask,@x[5]
-+	pshufb	$mask,@x[6]
-+	pshufb	$mask,@x[7]
-+	lea	0x80($key),$key
-+___
-+}
-+
-+sub MixColumns {
-+# modified to emit output in order suitable for feeding back to aesenc[last]
-+my @x=@_[0..7];
-+my @t=@_[8..15];
-+my $inv=@_[16];	# optional
-+$code.=<<___;
-+	pshufd	\$0x93, @x[0], @t[0]	# x0 <<< 32
-+	pshufd	\$0x93, @x[1], @t[1]
-+	 pxor	@t[0], @x[0]		# x0 ^ (x0 <<< 32)
-+	pshufd	\$0x93, @x[2], @t[2]
-+	 pxor	@t[1], @x[1]
-+	pshufd	\$0x93, @x[3], @t[3]
-+	 pxor	@t[2], @x[2]
-+	pshufd	\$0x93, @x[4], @t[4]
-+	 pxor	@t[3], @x[3]
-+	pshufd	\$0x93, @x[5], @t[5]
-+	 pxor	@t[4], @x[4]
-+	pshufd	\$0x93, @x[6], @t[6]
-+	 pxor	@t[5], @x[5]
-+	pshufd	\$0x93, @x[7], @t[7]
-+	 pxor	@t[6], @x[6]
-+	 pxor	@t[7], @x[7]
-+
-+	pxor	@x[0], @t[1]
-+	pxor	@x[7], @t[0]
-+	pxor	@x[7], @t[1]
-+	 pshufd	\$0x4E, @x[0], @x[0] 	# (x0 ^ (x0 <<< 32)) <<< 64)
-+	pxor	@x[1], @t[2]
-+	 pshufd	\$0x4E, @x[1], @x[1]
-+	pxor	@x[4], @t[5]
-+	 pxor	@t[0], @x[0]
-+	pxor	@x[5], @t[6]
-+	 pxor	@t[1], @x[1]
-+	pxor	@x[3], @t[4]
-+	 pshufd	\$0x4E, @x[4], @t[0]
-+	pxor	@x[6], @t[7]
-+	 pshufd	\$0x4E, @x[5], @t[1]
-+	pxor	@x[2], @t[3]
-+	 pshufd	\$0x4E, @x[3], @x[4]
-+	pxor	@x[7], @t[3]
-+	 pshufd	\$0x4E, @x[7], @x[5]
-+	pxor	@x[7], @t[4]
-+	 pshufd	\$0x4E, @x[6], @x[3]
-+	pxor	@t[4], @t[0]
-+	 pshufd	\$0x4E, @x[2], @x[6]
-+	pxor	@t[5], @t[1]
-+___
-+$code.=<<___ if (!$inv);
-+	pxor	@t[3], @x[4]
-+	pxor	@t[7], @x[5]
-+	pxor	@t[6], @x[3]
-+	 movdqa	@t[0], @x[2]
-+	pxor	@t[2], @x[6]
-+	 movdqa	@t[1], @x[7]
-+___
-+$code.=<<___ if ($inv);
-+	pxor	@x[4], @t[3]
-+	pxor	@t[7], @x[5]
-+	pxor	@x[3], @t[6]
-+	 movdqa	@t[0], @x[3]
-+	pxor	@t[2], @x[6]
-+	 movdqa	@t[6], @x[2]
-+	 movdqa	@t[1], @x[7]
-+	 movdqa	@x[6], @x[4]
-+	 movdqa	@t[3], @x[6]
-+___
-+}
-+
-+sub InvMixColumns_orig {
-+my @x=@_[0..7];
-+my @t=@_[8..15];
-+
-+$code.=<<___;
-+	# multiplication by 0x0e
-+	pshufd	\$0x93, @x[7], @t[7]
-+	movdqa	@x[2], @t[2]
-+	pxor	@x[5], @x[7]		# 7 5
-+	pxor	@x[5], @x[2]		# 2 5
-+	pshufd	\$0x93, @x[0], @t[0]
-+	movdqa	@x[5], @t[5]
-+	pxor	@x[0], @x[5]		# 5 0		[1]
-+	pxor	@x[1], @x[0]		# 0 1
-+	pshufd	\$0x93, @x[1], @t[1]
-+	pxor	@x[2], @x[1]		# 1 25
-+	pxor	@x[6], @x[0]		# 01 6		[2]
-+	pxor	@x[3], @x[1]		# 125 3		[4]
-+	pshufd	\$0x93, @x[3], @t[3]
-+	pxor	@x[0], @x[2]		# 25 016	[3]
-+	pxor	@x[7], @x[3]		# 3 75
-+	pxor	@x[6], @x[7]		# 75 6		[0]
-+	pshufd	\$0x93, @x[6], @t[6]
-+	movdqa	@x[4], @t[4]
-+	pxor	@x[4], @x[6]		# 6 4
-+	pxor	@x[3], @x[4]		# 4 375		[6]
-+	pxor	@x[7], @x[3]		# 375 756=36
-+	pxor	@t[5], @x[6]		# 64 5		[7]
-+	pxor	@t[2], @x[3]		# 36 2
-+	pxor	@t[4], @x[3]		# 362 4		[5]
-+	pshufd	\$0x93, @t[5], @t[5]
-+___
-+					my @y = @x[7,5,0,2,1,3,4,6];
-+$code.=<<___;
-+	# multiplication by 0x0b
-+	pxor	@y[0], @y[1]
-+	pxor	@t[0], @y[0]
-+	pxor	@t[1], @y[1]
-+	pshufd	\$0x93, @t[2], @t[2]
-+	pxor	@t[5], @y[0]
-+	pxor	@t[6], @y[1]
-+	pxor	@t[7], @y[0]
-+	pshufd	\$0x93, @t[4], @t[4]
-+	pxor	@t[6], @t[7]		# clobber t[7]
-+	pxor	@y[0], @y[1]
-+
-+	pxor	@t[0], @y[3]
-+	pshufd	\$0x93, @t[0], @t[0]
-+	pxor	@t[1], @y[2]
-+	pxor	@t[1], @y[4]
-+	pxor	@t[2], @y[2]
-+	pshufd	\$0x93, @t[1], @t[1]
-+	pxor	@t[2], @y[3]
-+	pxor	@t[2], @y[5]
-+	pxor	@t[7], @y[2]
-+	pshufd	\$0x93, @t[2], @t[2]
-+	pxor	@t[3], @y[3]
-+	pxor	@t[3], @y[6]
-+	pxor	@t[3], @y[4]
-+	pshufd	\$0x93, @t[3], @t[3]
-+	pxor	@t[4], @y[7]
-+	pxor	@t[4], @y[5]
-+	pxor	@t[7], @y[7]
-+	pxor	@t[5], @y[3]
-+	pxor	@t[4], @y[4]
-+	pxor	@t[5], @t[7]		# clobber t[7] even more
-+
-+	pxor	@t[7], @y[5]
-+	pshufd	\$0x93, @t[4], @t[4]
-+	pxor	@t[7], @y[6]
-+	pxor	@t[7], @y[4]
-+
-+	pxor	@t[5], @t[7]
-+	pshufd	\$0x93, @t[5], @t[5]
-+	pxor	@t[6], @t[7]		# restore t[7]
-+
-+	# multiplication by 0x0d
-+	pxor	@y[7], @y[4]
-+	pxor	@t[4], @y[7]
-+	pshufd	\$0x93, @t[6], @t[6]
-+	pxor	@t[0], @y[2]
-+	pxor	@t[5], @y[7]
-+	pxor	@t[2], @y[2]
-+	pshufd	\$0x93, @t[7], @t[7]
-+
-+	pxor	@y[1], @y[3]
-+	pxor	@t[1], @y[1]
-+	pxor	@t[0], @y[0]
-+	pxor	@t[0], @y[3]
-+	pxor	@t[5], @y[1]
-+	pxor	@t[5], @y[0]
-+	pxor	@t[7], @y[1]
-+	pshufd	\$0x93, @t[0], @t[0]
-+	pxor	@t[6], @y[0]
-+	pxor	@y[1], @y[3]
-+	pxor	@t[1], @y[4]
-+	pshufd	\$0x93, @t[1], @t[1]
-+
-+	pxor	@t[7], @y[7]
-+	pxor	@t[2], @y[4]
-+	pxor	@t[2], @y[5]
-+	pshufd	\$0x93, @t[2], @t[2]
-+	pxor	@t[6], @y[2]
-+	pxor	@t[3], @t[6]		# clobber t[6]
-+	pxor	@y[7], @y[4]
-+	pxor	@t[6], @y[3]
-+
-+	pxor	@t[6], @y[6]
-+	pxor	@t[5], @y[5]
-+	pxor	@t[4], @y[6]
-+	pshufd	\$0x93, @t[4], @t[4]
-+	pxor	@t[6], @y[5]
-+	pxor	@t[7], @y[6]
-+	pxor	@t[3], @t[6]		# restore t[6]
-+
-+	pshufd	\$0x93, @t[5], @t[5]
-+	pshufd	\$0x93, @t[6], @t[6]
-+	pshufd	\$0x93, @t[7], @t[7]
-+	pshufd	\$0x93, @t[3], @t[3]
-+
-+	# multiplication by 0x09
-+	pxor	@y[1], @y[4]
-+	pxor	@y[1], @t[1]		# t[1]=y[1]
-+	pxor	@t[5], @t[0]		# clobber t[0]
-+	pxor	@t[5], @t[1]
-+	pxor	@t[0], @y[3]
-+	pxor	@y[0], @t[0]		# t[0]=y[0]
-+	pxor	@t[6], @t[1]
-+	pxor	@t[7], @t[6]		# clobber t[6]
-+	pxor	@t[1], @y[4]
-+	pxor	@t[4], @y[7]
-+	pxor	@y[4], @t[4]		# t[4]=y[4]
-+	pxor	@t[3], @y[6]
-+	pxor	@y[3], @t[3]		# t[3]=y[3]
-+	pxor	@t[2], @y[5]
-+	pxor	@y[2], @t[2]		# t[2]=y[2]
-+	pxor	@t[7], @t[3]
-+	pxor	@y[5], @t[5]		# t[5]=y[5]
-+	pxor	@t[6], @t[2]
-+	pxor	@t[6], @t[5]
-+	pxor	@y[6], @t[6]		# t[6]=y[6]
-+	pxor	@y[7], @t[7]		# t[7]=y[7]
-+
-+	movdqa	@t[0],@XMM[0]
-+	movdqa	@t[1],@XMM[1]
-+	movdqa	@t[2],@XMM[2]
-+	movdqa	@t[3],@XMM[3]
-+	movdqa	@t[4],@XMM[4]
-+	movdqa	@t[5],@XMM[5]
-+	movdqa	@t[6],@XMM[6]
-+	movdqa	@t[7],@XMM[7]
-+___
-+}
-+
-+sub InvMixColumns {
-+my @x=@_[0..7];
-+my @t=@_[8..15];
-+
-+# Thanks to Jussi Kivilinna for providing pointer to
-+#
-+# | 0e 0b 0d 09 |   | 02 03 01 01 |   | 05 00 04 00 |
-+# | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 |
-+# | 0d 09 0e 0b |   | 01 01 02 03 |   | 04 00 05 00 |
-+# | 0b 0d 09 0e |   | 03 01 01 02 |   | 00 04 00 05 |
-+
-+$code.=<<___;
-+	# multiplication by 0x05-0x00-0x04-0x00
-+	pshufd	\$0x4E, @x[0], @t[0]
-+	pshufd	\$0x4E, @x[6], @t[6]
-+	pxor	@x[0], @t[0]
-+	pshufd	\$0x4E, @x[7], @t[7]
-+	pxor	@x[6], @t[6]
-+	pshufd	\$0x4E, @x[1], @t[1]
-+	pxor	@x[7], @t[7]
-+	pshufd	\$0x4E, @x[2], @t[2]
-+	pxor	@x[1], @t[1]
-+	pshufd	\$0x4E, @x[3], @t[3]
-+	pxor	@x[2], @t[2]
-+	 pxor	@t[6], @x[0]
-+	 pxor	@t[6], @x[1]
-+	pshufd	\$0x4E, @x[4], @t[4]
-+	pxor	@x[3], @t[3]
-+	 pxor	@t[0], @x[2]
-+	 pxor	@t[1], @x[3]
-+	pshufd	\$0x4E, @x[5], @t[5]
-+	pxor	@x[4], @t[4]
-+	 pxor	@t[7], @x[1]
-+	 pxor	@t[2], @x[4]
-+	pxor	@x[5], @t[5]
-+
-+	 pxor	@t[7], @x[2]
-+	 pxor	@t[6], @x[3]
-+	 pxor	@t[6], @x[4]
-+	 pxor	@t[3], @x[5]
-+	 pxor	@t[4], @x[6]
-+	 pxor	@t[7], @x[4]
-+	 pxor	@t[7], @x[5]
-+	 pxor	@t[5], @x[7]
-+___
-+	&MixColumns	(@x,@t,1);	# flipped 2<->3 and 4<->6
-+}
-+
-+sub aesenc {				# not used
-+my @b=@_[0..7];
-+my @t=@_[8..15];
-+$code.=<<___;
-+	movdqa	0x30($const),@t[0]	# .LSR
-+___
-+	&ShiftRows	(@b,@t[0]);
-+	&Sbox		(@b,@t);
-+	&MixColumns	(@b[0,1,4,6,3,7,2,5],@t);
-+}
-+
-+sub aesenclast {			# not used
-+my @b=@_[0..7];
-+my @t=@_[8..15];
-+$code.=<<___;
-+	movdqa	0x40($const),@t[0]	# .LSRM0
-+___
-+	&ShiftRows	(@b,@t[0]);
-+	&Sbox		(@b,@t);
-+$code.=<<___
-+	pxor	0x00($key),@b[0]
-+	pxor	0x10($key),@b[1]
-+	pxor	0x20($key),@b[4]
-+	pxor	0x30($key),@b[6]
-+	pxor	0x40($key),@b[3]
-+	pxor	0x50($key),@b[7]
-+	pxor	0x60($key),@b[2]
-+	pxor	0x70($key),@b[5]
-+___
-+}
-+
-+sub swapmove {
-+my ($a,$b,$n,$mask,$t)=@_;
-+$code.=<<___;
-+	movdqa	$b,$t
-+	psrlq	\$$n,$b
-+	pxor  	$a,$b
-+	pand	$mask,$b
-+	pxor	$b,$a
-+	psllq	\$$n,$b
-+	pxor	$t,$b
-+___
-+}
-+sub swapmove2x {
-+my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_;
-+$code.=<<___;
-+	movdqa	$b0,$t0
-+	psrlq	\$$n,$b0
-+	 movdqa	$b1,$t1
-+	 psrlq	\$$n,$b1
-+	pxor  	$a0,$b0
-+	 pxor  	$a1,$b1
-+	pand	$mask,$b0
-+	 pand	$mask,$b1
-+	pxor	$b0,$a0
-+	psllq	\$$n,$b0
-+	 pxor	$b1,$a1
-+	 psllq	\$$n,$b1
-+	pxor	$t0,$b0
-+	 pxor	$t1,$b1
-+___
-+}
-+
-+sub bitslice {
-+my @x=reverse(@_[0..7]);
-+my ($t0,$t1,$t2,$t3)=@_[8..11];
-+$code.=<<___;
-+	movdqa	0x00($const),$t0	# .LBS0
-+	movdqa	0x10($const),$t1	# .LBS1
-+___
-+	&swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3);
-+	&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
-+$code.=<<___;
-+	movdqa	0x20($const),$t0	# .LBS2
-+___
-+	&swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3);
-+	&swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
-+
-+	&swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3);
-+	&swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3);
-+}
-+
-+$code.=<<___;
-+.text
-+
-+.extern	asm_AES_encrypt
-+.extern	asm_AES_decrypt
-+
-+.type	_bsaes_encrypt8,\@abi-omnipotent
-+.align	64
-+_bsaes_encrypt8:
-+	lea	.LBS0(%rip), $const	# constants table
-+
-+	movdqa	($key), @XMM[9]		# round 0 key
-+	lea	0x10($key), $key
-+	movdqa	0x50($const), @XMM[8]	# .LM0SR
-+	pxor	@XMM[9], @XMM[0]	# xor with round0 key
-+	pxor	@XMM[9], @XMM[1]
-+	pxor	@XMM[9], @XMM[2]
-+	pxor	@XMM[9], @XMM[3]
-+	 pshufb	@XMM[8], @XMM[0]
-+	 pshufb	@XMM[8], @XMM[1]
-+	pxor	@XMM[9], @XMM[4]
-+	pxor	@XMM[9], @XMM[5]
-+	 pshufb	@XMM[8], @XMM[2]
-+	 pshufb	@XMM[8], @XMM[3]
-+	pxor	@XMM[9], @XMM[6]
-+	pxor	@XMM[9], @XMM[7]
-+	 pshufb	@XMM[8], @XMM[4]
-+	 pshufb	@XMM[8], @XMM[5]
-+	 pshufb	@XMM[8], @XMM[6]
-+	 pshufb	@XMM[8], @XMM[7]
-+_bsaes_encrypt8_bitslice:
-+___
-+	&bitslice	(@XMM[0..7, 8..11]);
-+$code.=<<___;
-+	dec	$rounds
-+	jmp	.Lenc_sbox
-+.align	16
-+.Lenc_loop:
-+___
-+	&ShiftRows	(@XMM[0..7, 8]);
-+$code.=".Lenc_sbox:\n";
-+	&Sbox		(@XMM[0..7, 8..15]);
-+$code.=<<___;
-+	dec	$rounds
-+	jl	.Lenc_done
-+___
-+	&MixColumns	(@XMM[0,1,4,6,3,7,2,5, 8..15]);
-+$code.=<<___;
-+	movdqa	0x30($const), @XMM[8]	# .LSR
-+	jnz	.Lenc_loop
-+	movdqa	0x40($const), @XMM[8]	# .LSRM0
-+	jmp	.Lenc_loop
-+.align	16
-+.Lenc_done:
-+___
-+	# output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb
-+	&bitslice	(@XMM[0,1,4,6,3,7,2,5, 8..11]);
-+$code.=<<___;
-+	movdqa	($key), @XMM[8]		# last round key
-+	pxor	@XMM[8], @XMM[4]
-+	pxor	@XMM[8], @XMM[6]
-+	pxor	@XMM[8], @XMM[3]
-+	pxor	@XMM[8], @XMM[7]
-+	pxor	@XMM[8], @XMM[2]
-+	pxor	@XMM[8], @XMM[5]
-+	pxor	@XMM[8], @XMM[0]
-+	pxor	@XMM[8], @XMM[1]
-+	ret
-+.size	_bsaes_encrypt8,.-_bsaes_encrypt8
-+
-+.type	_bsaes_decrypt8,\@abi-omnipotent
-+.align	64
-+_bsaes_decrypt8:
-+	lea	.LBS0(%rip), $const	# constants table
-+
-+	movdqa	($key), @XMM[9]		# round 0 key
-+	lea	0x10($key), $key
-+	movdqa	-0x30($const), @XMM[8]	# .LM0ISR
-+	pxor	@XMM[9], @XMM[0]	# xor with round0 key
-+	pxor	@XMM[9], @XMM[1]
-+	pxor	@XMM[9], @XMM[2]
-+	pxor	@XMM[9], @XMM[3]
-+	 pshufb	@XMM[8], @XMM[0]
-+	 pshufb	@XMM[8], @XMM[1]
-+	pxor	@XMM[9], @XMM[4]
-+	pxor	@XMM[9], @XMM[5]
-+	 pshufb	@XMM[8], @XMM[2]
-+	 pshufb	@XMM[8], @XMM[3]
-+	pxor	@XMM[9], @XMM[6]
-+	pxor	@XMM[9], @XMM[7]
-+	 pshufb	@XMM[8], @XMM[4]
-+	 pshufb	@XMM[8], @XMM[5]
-+	 pshufb	@XMM[8], @XMM[6]
-+	 pshufb	@XMM[8], @XMM[7]
-+___
-+	&bitslice	(@XMM[0..7, 8..11]);
-+$code.=<<___;
-+	dec	$rounds
-+	jmp	.Ldec_sbox
-+.align	16
-+.Ldec_loop:
-+___
-+	&ShiftRows	(@XMM[0..7, 8]);
-+$code.=".Ldec_sbox:\n";
-+	&InvSbox	(@XMM[0..7, 8..15]);
-+$code.=<<___;
-+	dec	$rounds
-+	jl	.Ldec_done
-+___
-+	&InvMixColumns	(@XMM[0,1,6,4,2,7,3,5, 8..15]);
-+$code.=<<___;
-+	movdqa	-0x10($const), @XMM[8]	# .LISR
-+	jnz	.Ldec_loop
-+	movdqa	-0x20($const), @XMM[8]	# .LISRM0
-+	jmp	.Ldec_loop
-+.align	16
-+.Ldec_done:
-+___
-+	&bitslice	(@XMM[0,1,6,4,2,7,3,5, 8..11]);
-+$code.=<<___;
-+	movdqa	($key), @XMM[8]		# last round key
-+	pxor	@XMM[8], @XMM[6]
-+	pxor	@XMM[8], @XMM[4]
-+	pxor	@XMM[8], @XMM[2]
-+	pxor	@XMM[8], @XMM[7]
-+	pxor	@XMM[8], @XMM[3]
-+	pxor	@XMM[8], @XMM[5]
-+	pxor	@XMM[8], @XMM[0]
-+	pxor	@XMM[8], @XMM[1]
-+	ret
-+.size	_bsaes_decrypt8,.-_bsaes_decrypt8
-+___
-+}
-+{
-+my ($out,$inp,$rounds,$const)=("%rax","%rcx","%r10d","%r11");
-+
-+sub bitslice_key {
-+my @x=reverse(@_[0..7]);
-+my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12];
-+
-+	&swapmove	(@x[0,1],1,$bs0,$t2,$t3);
-+$code.=<<___;
-+	#&swapmove(@x[2,3],1,$t0,$t2,$t3);
-+	movdqa	@x[0], @x[2]
-+	movdqa	@x[1], @x[3]
-+___
-+	#&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
-+
-+	&swapmove2x	(@x[0,2,1,3],2,$bs1,$t2,$t3);
-+$code.=<<___;
-+	#&swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
-+	movdqa	@x[0], @x[4]
-+	movdqa	@x[2], @x[6]
-+	movdqa	@x[1], @x[5]
-+	movdqa	@x[3], @x[7]
-+___
-+	&swapmove2x	(@x[0,4,1,5],4,$bs2,$t2,$t3);
-+	&swapmove2x	(@x[2,6,3,7],4,$bs2,$t2,$t3);
-+}
-+
-+$code.=<<___;
-+.type	_bsaes_key_convert,\@abi-omnipotent
-+.align	16
-+_bsaes_key_convert:
-+	lea	.Lmasks(%rip), $const
-+	movdqu	($inp), %xmm7		# load round 0 key
-+	lea	0x10($inp), $inp
-+	movdqa	0x00($const), %xmm0	# 0x01...
-+	movdqa	0x10($const), %xmm1	# 0x02...
-+	movdqa	0x20($const), %xmm2	# 0x04...
-+	movdqa	0x30($const), %xmm3	# 0x08...
-+	movdqa	0x40($const), %xmm4	# .LM0
-+	pcmpeqd	%xmm5, %xmm5		# .LNOT
-+
-+	movdqu	($inp), %xmm6		# load round 1 key
-+	movdqa	%xmm7, ($out)		# save round 0 key
-+	lea	0x10($out), $out
-+	dec	$rounds
-+	jmp	.Lkey_loop
-+.align	16
-+.Lkey_loop:
-+	pshufb	%xmm4, %xmm6		# .LM0
-+
-+	movdqa	%xmm0,	%xmm8
-+	movdqa	%xmm1,	%xmm9
-+
-+	pand	%xmm6,	%xmm8
-+	pand	%xmm6,	%xmm9
-+	movdqa	%xmm2,	%xmm10
-+	pcmpeqb	%xmm0,	%xmm8
-+	psllq	\$4,	%xmm0		# 0x10...
-+	movdqa	%xmm3,	%xmm11
-+	pcmpeqb	%xmm1,	%xmm9
-+	psllq	\$4,	%xmm1		# 0x20...
-+
-+	pand	%xmm6,	%xmm10
-+	pand	%xmm6,	%xmm11
-+	movdqa	%xmm0,	%xmm12
-+	pcmpeqb	%xmm2,	%xmm10
-+	psllq	\$4,	%xmm2		# 0x40...
-+	movdqa	%xmm1,	%xmm13
-+	pcmpeqb	%xmm3,	%xmm11
-+	psllq	\$4,	%xmm3		# 0x80...
-+
-+	movdqa	%xmm2,	%xmm14
-+	movdqa	%xmm3,	%xmm15
-+	 pxor	%xmm5,	%xmm8		# "pnot"
-+	 pxor	%xmm5,	%xmm9
-+
-+	pand	%xmm6,	%xmm12
-+	pand	%xmm6,	%xmm13
-+	 movdqa	%xmm8, 0x00($out)	# write bit-sliced round key
-+	pcmpeqb	%xmm0,	%xmm12
-+	psrlq	\$4,	%xmm0		# 0x01...
-+	 movdqa	%xmm9, 0x10($out)
-+	pcmpeqb	%xmm1,	%xmm13
-+	psrlq	\$4,	%xmm1		# 0x02...
-+	 lea	0x10($inp), $inp
-+
-+	pand	%xmm6,	%xmm14
-+	pand	%xmm6,	%xmm15
-+	 movdqa	%xmm10, 0x20($out)
-+	pcmpeqb	%xmm2,	%xmm14
-+	psrlq	\$4,	%xmm2		# 0x04...
-+	 movdqa	%xmm11, 0x30($out)
-+	pcmpeqb	%xmm3,	%xmm15
-+	psrlq	\$4,	%xmm3		# 0x08...
-+	 movdqu	($inp), %xmm6		# load next round key
-+
-+	pxor	%xmm5, %xmm13		# "pnot"
-+	pxor	%xmm5, %xmm14
-+	movdqa	%xmm12, 0x40($out)
-+	movdqa	%xmm13, 0x50($out)
-+	movdqa	%xmm14, 0x60($out)
-+	movdqa	%xmm15, 0x70($out)
-+	lea	0x80($out),$out
-+	dec	$rounds
-+	jnz	.Lkey_loop
-+
-+	movdqa	0x50($const), %xmm7	# .L63
-+	#movdqa	%xmm6, ($out)		# don't save last round key
-+	ret
-+.size	_bsaes_key_convert,.-_bsaes_key_convert
-+___
-+}
-+
-+if (0 && !$win64) {	# following four functions are unsupported interface
-+			# used for benchmarking...
-+$code.=<<___;
-+.globl	bsaes_enc_key_convert
-+.type	bsaes_enc_key_convert,\@function,2
-+.align	16
-+bsaes_enc_key_convert:
-+	mov	240($inp),%r10d		# pass rounds
-+	mov	$inp,%rcx		# pass key
-+	mov	$out,%rax		# pass key schedule
-+	call	_bsaes_key_convert
-+	pxor	%xmm6,%xmm7		# fix up last round key
-+	movdqa	%xmm7,(%rax)		# save last round key
-+	ret
-+.size	bsaes_enc_key_convert,.-bsaes_enc_key_convert
-+
-+.globl	bsaes_encrypt_128
-+.type	bsaes_encrypt_128,\@function,4
-+.align	16
-+bsaes_encrypt_128:
-+.Lenc128_loop:
-+	movdqu	0x00($inp), @XMM[0]	# load input
-+	movdqu	0x10($inp), @XMM[1]
-+	movdqu	0x20($inp), @XMM[2]
-+	movdqu	0x30($inp), @XMM[3]
-+	movdqu	0x40($inp), @XMM[4]
-+	movdqu	0x50($inp), @XMM[5]
-+	movdqu	0x60($inp), @XMM[6]
-+	movdqu	0x70($inp), @XMM[7]
-+	mov	$key, %rax		# pass the $key
-+	lea	0x80($inp), $inp
-+	mov	\$10,%r10d
-+
-+	call	_bsaes_encrypt8
-+
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[4], 0x20($out)
-+	movdqu	@XMM[6], 0x30($out)
-+	movdqu	@XMM[3], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	movdqu	@XMM[2], 0x60($out)
-+	movdqu	@XMM[5], 0x70($out)
-+	lea	0x80($out), $out
-+	sub	\$0x80,$len
-+	ja	.Lenc128_loop
-+	ret
-+.size	bsaes_encrypt_128,.-bsaes_encrypt_128
-+
-+.globl	bsaes_dec_key_convert
-+.type	bsaes_dec_key_convert,\@function,2
-+.align	16
-+bsaes_dec_key_convert:
-+	mov	240($inp),%r10d		# pass rounds
-+	mov	$inp,%rcx		# pass key
-+	mov	$out,%rax		# pass key schedule
-+	call	_bsaes_key_convert
-+	pxor	($out),%xmm7		# fix up round 0 key
-+	movdqa	%xmm6,(%rax)		# save last round key
-+	movdqa	%xmm7,($out)
-+	ret
-+.size	bsaes_dec_key_convert,.-bsaes_dec_key_convert
-+
-+.globl	bsaes_decrypt_128
-+.type	bsaes_decrypt_128,\@function,4
-+.align	16
-+bsaes_decrypt_128:
-+.Ldec128_loop:
-+	movdqu	0x00($inp), @XMM[0]	# load input
-+	movdqu	0x10($inp), @XMM[1]
-+	movdqu	0x20($inp), @XMM[2]
-+	movdqu	0x30($inp), @XMM[3]
-+	movdqu	0x40($inp), @XMM[4]
-+	movdqu	0x50($inp), @XMM[5]
-+	movdqu	0x60($inp), @XMM[6]
-+	movdqu	0x70($inp), @XMM[7]
-+	mov	$key, %rax		# pass the $key
-+	lea	0x80($inp), $inp
-+	mov	\$10,%r10d
-+
-+	call	_bsaes_decrypt8
-+
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	movdqu	@XMM[2], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	movdqu	@XMM[3], 0x60($out)
-+	movdqu	@XMM[5], 0x70($out)
-+	lea	0x80($out), $out
-+	sub	\$0x80,$len
-+	ja	.Ldec128_loop
-+	ret
-+.size	bsaes_decrypt_128,.-bsaes_decrypt_128
-+___
-+}
-+{
-+######################################################################
-+#
-+# OpenSSL interface
-+#
-+my ($arg1,$arg2,$arg3,$arg4,$arg5,$arg6)=$win64	? ("%rcx","%rdx","%r8","%r9","%r10","%r11d")
-+						: ("%rdi","%rsi","%rdx","%rcx","%r8","%r9d");
-+my ($inp,$out,$len,$key)=("%r12","%r13","%r14","%r15");
-+
-+if ($ecb) {
-+$code.=<<___;
-+.globl	bsaes_ecb_encrypt_blocks
-+.type	bsaes_ecb_encrypt_blocks,\@abi-omnipotent
-+.align	16
-+bsaes_ecb_encrypt_blocks:
-+	mov	%rsp, %rax
-+.Lecb_enc_prologue:
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	lea	-0x48(%rsp),%rsp
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa0(%rsp), %rsp
-+	movaps	%xmm6, 0x40(%rsp)
-+	movaps	%xmm7, 0x50(%rsp)
-+	movaps	%xmm8, 0x60(%rsp)
-+	movaps	%xmm9, 0x70(%rsp)
-+	movaps	%xmm10, 0x80(%rsp)
-+	movaps	%xmm11, 0x90(%rsp)
-+	movaps	%xmm12, 0xa0(%rsp)
-+	movaps	%xmm13, 0xb0(%rsp)
-+	movaps	%xmm14, 0xc0(%rsp)
-+	movaps	%xmm15, 0xd0(%rsp)
-+.Lecb_enc_body:
-+___
-+$code.=<<___;
-+	mov	%rsp,%rbp		# backup %rsp
-+	mov	240($arg4),%eax		# rounds
-+	mov	$arg1,$inp		# backup arguments
-+	mov	$arg2,$out
-+	mov	$arg3,$len
-+	mov	$arg4,$key
-+	cmp	\$8,$arg3
-+	jb	.Lecb_enc_short
-+
-+	mov	%eax,%ebx		# backup rounds
-+	shl	\$7,%rax		# 128 bytes per inner round key
-+	sub	\$`128-32`,%rax		# size of bit-sliced key schedule
-+	sub	%rax,%rsp
-+	mov	%rsp,%rax		# pass key schedule
-+	mov	$key,%rcx		# pass key
-+	mov	%ebx,%r10d		# pass rounds
-+	call	_bsaes_key_convert
-+	pxor	%xmm6,%xmm7		# fix up last round key
-+	movdqa	%xmm7,(%rax)		# save last round key
-+
-+	sub	\$8,$len
-+.Lecb_enc_loop:
-+	movdqu	0x00($inp), @XMM[0]	# load input
-+	movdqu	0x10($inp), @XMM[1]
-+	movdqu	0x20($inp), @XMM[2]
-+	movdqu	0x30($inp), @XMM[3]
-+	movdqu	0x40($inp), @XMM[4]
-+	movdqu	0x50($inp), @XMM[5]
-+	mov	%rsp, %rax		# pass key schedule
-+	movdqu	0x60($inp), @XMM[6]
-+	mov	%ebx,%r10d		# pass rounds
-+	movdqu	0x70($inp), @XMM[7]
-+	lea	0x80($inp), $inp
-+
-+	call	_bsaes_encrypt8
-+
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[4], 0x20($out)
-+	movdqu	@XMM[6], 0x30($out)
-+	movdqu	@XMM[3], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	movdqu	@XMM[2], 0x60($out)
-+	movdqu	@XMM[5], 0x70($out)
-+	lea	0x80($out), $out
-+	sub	\$8,$len
-+	jnc	.Lecb_enc_loop
-+
-+	add	\$8,$len
-+	jz	.Lecb_enc_done
-+
-+	movdqu	0x00($inp), @XMM[0]	# load input
-+	mov	%rsp, %rax		# pass key schedule
-+	mov	%ebx,%r10d		# pass rounds
-+	cmp	\$2,$len
-+	jb	.Lecb_enc_one
-+	movdqu	0x10($inp), @XMM[1]
-+	je	.Lecb_enc_two
-+	movdqu	0x20($inp), @XMM[2]
-+	cmp	\$4,$len
-+	jb	.Lecb_enc_three
-+	movdqu	0x30($inp), @XMM[3]
-+	je	.Lecb_enc_four
-+	movdqu	0x40($inp), @XMM[4]
-+	cmp	\$6,$len
-+	jb	.Lecb_enc_five
-+	movdqu	0x50($inp), @XMM[5]
-+	je	.Lecb_enc_six
-+	movdqu	0x60($inp), @XMM[6]
-+	call	_bsaes_encrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[4], 0x20($out)
-+	movdqu	@XMM[6], 0x30($out)
-+	movdqu	@XMM[3], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	movdqu	@XMM[2], 0x60($out)
-+	jmp	.Lecb_enc_done
-+.align	16
-+.Lecb_enc_six:
-+	call	_bsaes_encrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[4], 0x20($out)
-+	movdqu	@XMM[6], 0x30($out)
-+	movdqu	@XMM[3], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	jmp	.Lecb_enc_done
-+.align	16
-+.Lecb_enc_five:
-+	call	_bsaes_encrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[4], 0x20($out)
-+	movdqu	@XMM[6], 0x30($out)
-+	movdqu	@XMM[3], 0x40($out)
-+	jmp	.Lecb_enc_done
-+.align	16
-+.Lecb_enc_four:
-+	call	_bsaes_encrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[4], 0x20($out)
-+	movdqu	@XMM[6], 0x30($out)
-+	jmp	.Lecb_enc_done
-+.align	16
-+.Lecb_enc_three:
-+	call	_bsaes_encrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[4], 0x20($out)
-+	jmp	.Lecb_enc_done
-+.align	16
-+.Lecb_enc_two:
-+	call	_bsaes_encrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	jmp	.Lecb_enc_done
-+.align	16
-+.Lecb_enc_one:
-+	call	_bsaes_encrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	jmp	.Lecb_enc_done
-+.align	16
-+.Lecb_enc_short:
-+	lea	($inp), $arg1
-+	lea	($out), $arg2
-+	lea	($key), $arg3
-+	call	asm_AES_encrypt
-+	lea	16($inp), $inp
-+	lea	16($out), $out
-+	dec	$len
-+	jnz	.Lecb_enc_short
-+
-+.Lecb_enc_done:
-+	lea	(%rsp),%rax
-+	pxor	%xmm0, %xmm0
-+.Lecb_enc_bzero:			# wipe key schedule [if any]
-+	movdqa	%xmm0, 0x00(%rax)
-+	movdqa	%xmm0, 0x10(%rax)
-+	lea	0x20(%rax), %rax
-+	cmp	%rax, %rbp
-+	jb	.Lecb_enc_bzero
-+
-+	lea	(%rbp),%rsp		# restore %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x40(%rbp), %xmm6
-+	movaps	0x50(%rbp), %xmm7
-+	movaps	0x60(%rbp), %xmm8
-+	movaps	0x70(%rbp), %xmm9
-+	movaps	0x80(%rbp), %xmm10
-+	movaps	0x90(%rbp), %xmm11
-+	movaps	0xa0(%rbp), %xmm12
-+	movaps	0xb0(%rbp), %xmm13
-+	movaps	0xc0(%rbp), %xmm14
-+	movaps	0xd0(%rbp), %xmm15
-+	lea	0xa0(%rbp), %rsp
-+___
-+$code.=<<___;
-+	mov	0x48(%rsp), %r15
-+	mov	0x50(%rsp), %r14
-+	mov	0x58(%rsp), %r13
-+	mov	0x60(%rsp), %r12
-+	mov	0x68(%rsp), %rbx
-+	mov	0x70(%rsp), %rax
-+	lea	0x78(%rsp), %rsp
-+	mov	%rax, %rbp
-+.Lecb_enc_epilogue:
-+	ret
-+.size	bsaes_ecb_encrypt_blocks,.-bsaes_ecb_encrypt_blocks
-+
-+.globl	bsaes_ecb_decrypt_blocks
-+.type	bsaes_ecb_decrypt_blocks,\@abi-omnipotent
-+.align	16
-+bsaes_ecb_decrypt_blocks:
-+	mov	%rsp, %rax
-+.Lecb_dec_prologue:
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	lea	-0x48(%rsp),%rsp
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa0(%rsp), %rsp
-+	movaps	%xmm6, 0x40(%rsp)
-+	movaps	%xmm7, 0x50(%rsp)
-+	movaps	%xmm8, 0x60(%rsp)
-+	movaps	%xmm9, 0x70(%rsp)
-+	movaps	%xmm10, 0x80(%rsp)
-+	movaps	%xmm11, 0x90(%rsp)
-+	movaps	%xmm12, 0xa0(%rsp)
-+	movaps	%xmm13, 0xb0(%rsp)
-+	movaps	%xmm14, 0xc0(%rsp)
-+	movaps	%xmm15, 0xd0(%rsp)
-+.Lecb_dec_body:
-+___
-+$code.=<<___;
-+	mov	%rsp,%rbp		# backup %rsp
-+	mov	240($arg4),%eax		# rounds
-+	mov	$arg1,$inp		# backup arguments
-+	mov	$arg2,$out
-+	mov	$arg3,$len
-+	mov	$arg4,$key
-+	cmp	\$8,$arg3
-+	jb	.Lecb_dec_short
-+
-+	mov	%eax,%ebx		# backup rounds
-+	shl	\$7,%rax		# 128 bytes per inner round key
-+	sub	\$`128-32`,%rax		# size of bit-sliced key schedule
-+	sub	%rax,%rsp
-+	mov	%rsp,%rax		# pass key schedule
-+	mov	$key,%rcx		# pass key
-+	mov	%ebx,%r10d		# pass rounds
-+	call	_bsaes_key_convert
-+	pxor	(%rsp),%xmm7		# fix up 0 round key
-+	movdqa	%xmm6,(%rax)		# save last round key
-+	movdqa	%xmm7,(%rsp)
-+
-+	sub	\$8,$len
-+.Lecb_dec_loop:
-+	movdqu	0x00($inp), @XMM[0]	# load input
-+	movdqu	0x10($inp), @XMM[1]
-+	movdqu	0x20($inp), @XMM[2]
-+	movdqu	0x30($inp), @XMM[3]
-+	movdqu	0x40($inp), @XMM[4]
-+	movdqu	0x50($inp), @XMM[5]
-+	mov	%rsp, %rax		# pass key schedule
-+	movdqu	0x60($inp), @XMM[6]
-+	mov	%ebx,%r10d		# pass rounds
-+	movdqu	0x70($inp), @XMM[7]
-+	lea	0x80($inp), $inp
-+
-+	call	_bsaes_decrypt8
-+
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	movdqu	@XMM[2], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	movdqu	@XMM[3], 0x60($out)
-+	movdqu	@XMM[5], 0x70($out)
-+	lea	0x80($out), $out
-+	sub	\$8,$len
-+	jnc	.Lecb_dec_loop
-+
-+	add	\$8,$len
-+	jz	.Lecb_dec_done
-+
-+	movdqu	0x00($inp), @XMM[0]	# load input
-+	mov	%rsp, %rax		# pass key schedule
-+	mov	%ebx,%r10d		# pass rounds
-+	cmp	\$2,$len
-+	jb	.Lecb_dec_one
-+	movdqu	0x10($inp), @XMM[1]
-+	je	.Lecb_dec_two
-+	movdqu	0x20($inp), @XMM[2]
-+	cmp	\$4,$len
-+	jb	.Lecb_dec_three
-+	movdqu	0x30($inp), @XMM[3]
-+	je	.Lecb_dec_four
-+	movdqu	0x40($inp), @XMM[4]
-+	cmp	\$6,$len
-+	jb	.Lecb_dec_five
-+	movdqu	0x50($inp), @XMM[5]
-+	je	.Lecb_dec_six
-+	movdqu	0x60($inp), @XMM[6]
-+	call	_bsaes_decrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	movdqu	@XMM[2], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	movdqu	@XMM[3], 0x60($out)
-+	jmp	.Lecb_dec_done
-+.align	16
-+.Lecb_dec_six:
-+	call	_bsaes_decrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	movdqu	@XMM[2], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	jmp	.Lecb_dec_done
-+.align	16
-+.Lecb_dec_five:
-+	call	_bsaes_decrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	movdqu	@XMM[2], 0x40($out)
-+	jmp	.Lecb_dec_done
-+.align	16
-+.Lecb_dec_four:
-+	call	_bsaes_decrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	jmp	.Lecb_dec_done
-+.align	16
-+.Lecb_dec_three:
-+	call	_bsaes_decrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	jmp	.Lecb_dec_done
-+.align	16
-+.Lecb_dec_two:
-+	call	_bsaes_decrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	jmp	.Lecb_dec_done
-+.align	16
-+.Lecb_dec_one:
-+	call	_bsaes_decrypt8
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	jmp	.Lecb_dec_done
-+.align	16
-+.Lecb_dec_short:
-+	lea	($inp), $arg1
-+	lea	($out), $arg2
-+	lea	($key), $arg3
-+	call	asm_AES_decrypt
-+	lea	16($inp), $inp
-+	lea	16($out), $out
-+	dec	$len
-+	jnz	.Lecb_dec_short
-+
-+.Lecb_dec_done:
-+	lea	(%rsp),%rax
-+	pxor	%xmm0, %xmm0
-+.Lecb_dec_bzero:			# wipe key schedule [if any]
-+	movdqa	%xmm0, 0x00(%rax)
-+	movdqa	%xmm0, 0x10(%rax)
-+	lea	0x20(%rax), %rax
-+	cmp	%rax, %rbp
-+	jb	.Lecb_dec_bzero
-+
-+	lea	(%rbp),%rsp		# restore %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x40(%rbp), %xmm6
-+	movaps	0x50(%rbp), %xmm7
-+	movaps	0x60(%rbp), %xmm8
-+	movaps	0x70(%rbp), %xmm9
-+	movaps	0x80(%rbp), %xmm10
-+	movaps	0x90(%rbp), %xmm11
-+	movaps	0xa0(%rbp), %xmm12
-+	movaps	0xb0(%rbp), %xmm13
-+	movaps	0xc0(%rbp), %xmm14
-+	movaps	0xd0(%rbp), %xmm15
-+	lea	0xa0(%rbp), %rsp
-+___
-+$code.=<<___;
-+	mov	0x48(%rsp), %r15
-+	mov	0x50(%rsp), %r14
-+	mov	0x58(%rsp), %r13
-+	mov	0x60(%rsp), %r12
-+	mov	0x68(%rsp), %rbx
-+	mov	0x70(%rsp), %rax
-+	lea	0x78(%rsp), %rsp
-+	mov	%rax, %rbp
-+.Lecb_dec_epilogue:
-+	ret
-+.size	bsaes_ecb_decrypt_blocks,.-bsaes_ecb_decrypt_blocks
-+___
-+}
-+$code.=<<___;
-+.extern	asm_AES_cbc_encrypt
-+.globl	bsaes_cbc_encrypt
-+.type	bsaes_cbc_encrypt,\@abi-omnipotent
-+.align	16
-+bsaes_cbc_encrypt:
-+___
-+$code.=<<___ if ($win64);
-+	mov	48(%rsp),$arg6		# pull direction flag
-+___
-+$code.=<<___;
-+	cmp	\$0,$arg6
-+	jne	asm_AES_cbc_encrypt
-+	cmp	\$128,$arg3
-+	jb	asm_AES_cbc_encrypt
-+
-+	mov	%rsp, %rax
-+.Lcbc_dec_prologue:
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	lea	-0x48(%rsp), %rsp
-+___
-+$code.=<<___ if ($win64);
-+	mov	0xa0(%rsp),$arg5	# pull ivp
-+	lea	-0xa0(%rsp), %rsp
-+	movaps	%xmm6, 0x40(%rsp)
-+	movaps	%xmm7, 0x50(%rsp)
-+	movaps	%xmm8, 0x60(%rsp)
-+	movaps	%xmm9, 0x70(%rsp)
-+	movaps	%xmm10, 0x80(%rsp)
-+	movaps	%xmm11, 0x90(%rsp)
-+	movaps	%xmm12, 0xa0(%rsp)
-+	movaps	%xmm13, 0xb0(%rsp)
-+	movaps	%xmm14, 0xc0(%rsp)
-+	movaps	%xmm15, 0xd0(%rsp)
-+.Lcbc_dec_body:
-+___
-+$code.=<<___;
-+	mov	%rsp, %rbp		# backup %rsp
-+	mov	240($arg4), %eax	# rounds
-+	mov	$arg1, $inp		# backup arguments
-+	mov	$arg2, $out
-+	mov	$arg3, $len
-+	mov	$arg4, $key
-+	mov	$arg5, %rbx
-+	shr	\$4, $len		# bytes to blocks
-+
-+	mov	%eax, %edx		# rounds
-+	shl	\$7, %rax		# 128 bytes per inner round key
-+	sub	\$`128-32`, %rax	# size of bit-sliced key schedule
-+	sub	%rax, %rsp
-+
-+	mov	%rsp, %rax		# pass key schedule
-+	mov	$key, %rcx		# pass key
-+	mov	%edx, %r10d		# pass rounds
-+	call	_bsaes_key_convert
-+	pxor	(%rsp),%xmm7		# fix up 0 round key
-+	movdqa	%xmm6,(%rax)		# save last round key
-+	movdqa	%xmm7,(%rsp)
-+
-+	movdqu	(%rbx), @XMM[15]	# load IV
-+	sub	\$8,$len
-+.Lcbc_dec_loop:
-+	movdqu	0x00($inp), @XMM[0]	# load input
-+	movdqu	0x10($inp), @XMM[1]
-+	movdqu	0x20($inp), @XMM[2]
-+	movdqu	0x30($inp), @XMM[3]
-+	movdqu	0x40($inp), @XMM[4]
-+	movdqu	0x50($inp), @XMM[5]
-+	mov	%rsp, %rax		# pass key schedule
-+	movdqu	0x60($inp), @XMM[6]
-+	mov	%edx,%r10d		# pass rounds
-+	movdqu	0x70($inp), @XMM[7]
-+	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
-+
-+	call	_bsaes_decrypt8
-+
-+	pxor	0x20(%rbp), @XMM[0]	# ^= IV
-+	movdqu	0x00($inp), @XMM[8]	# re-load input
-+	movdqu	0x10($inp), @XMM[9]
-+	pxor	@XMM[8], @XMM[1]
-+	movdqu	0x20($inp), @XMM[10]
-+	pxor	@XMM[9], @XMM[6]
-+	movdqu	0x30($inp), @XMM[11]
-+	pxor	@XMM[10], @XMM[4]
-+	movdqu	0x40($inp), @XMM[12]
-+	pxor	@XMM[11], @XMM[2]
-+	movdqu	0x50($inp), @XMM[13]
-+	pxor	@XMM[12], @XMM[7]
-+	movdqu	0x60($inp), @XMM[14]
-+	pxor	@XMM[13], @XMM[3]
-+	movdqu	0x70($inp), @XMM[15]	# IV
-+	pxor	@XMM[14], @XMM[5]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	lea	0x80($inp), $inp
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	movdqu	@XMM[2], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	movdqu	@XMM[3], 0x60($out)
-+	movdqu	@XMM[5], 0x70($out)
-+	lea	0x80($out), $out
-+	sub	\$8,$len
-+	jnc	.Lcbc_dec_loop
-+
-+	add	\$8,$len
-+	jz	.Lcbc_dec_done
-+
-+	movdqu	0x00($inp), @XMM[0]	# load input
-+	mov	%rsp, %rax		# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+	cmp	\$2,$len
-+	jb	.Lcbc_dec_one
-+	movdqu	0x10($inp), @XMM[1]
-+	je	.Lcbc_dec_two
-+	movdqu	0x20($inp), @XMM[2]
-+	cmp	\$4,$len
-+	jb	.Lcbc_dec_three
-+	movdqu	0x30($inp), @XMM[3]
-+	je	.Lcbc_dec_four
-+	movdqu	0x40($inp), @XMM[4]
-+	cmp	\$6,$len
-+	jb	.Lcbc_dec_five
-+	movdqu	0x50($inp), @XMM[5]
-+	je	.Lcbc_dec_six
-+	movdqu	0x60($inp), @XMM[6]
-+	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
-+	call	_bsaes_decrypt8
-+	pxor	0x20(%rbp), @XMM[0]	# ^= IV
-+	movdqu	0x00($inp), @XMM[8]	# re-load input
-+	movdqu	0x10($inp), @XMM[9]
-+	pxor	@XMM[8], @XMM[1]
-+	movdqu	0x20($inp), @XMM[10]
-+	pxor	@XMM[9], @XMM[6]
-+	movdqu	0x30($inp), @XMM[11]
-+	pxor	@XMM[10], @XMM[4]
-+	movdqu	0x40($inp), @XMM[12]
-+	pxor	@XMM[11], @XMM[2]
-+	movdqu	0x50($inp), @XMM[13]
-+	pxor	@XMM[12], @XMM[7]
-+	movdqu	0x60($inp), @XMM[15]	# IV
-+	pxor	@XMM[13], @XMM[3]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	movdqu	@XMM[2], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	movdqu	@XMM[3], 0x60($out)
-+	jmp	.Lcbc_dec_done
-+.align	16
-+.Lcbc_dec_six:
-+	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
-+	call	_bsaes_decrypt8
-+	pxor	0x20(%rbp), @XMM[0]	# ^= IV
-+	movdqu	0x00($inp), @XMM[8]	# re-load input
-+	movdqu	0x10($inp), @XMM[9]
-+	pxor	@XMM[8], @XMM[1]
-+	movdqu	0x20($inp), @XMM[10]
-+	pxor	@XMM[9], @XMM[6]
-+	movdqu	0x30($inp), @XMM[11]
-+	pxor	@XMM[10], @XMM[4]
-+	movdqu	0x40($inp), @XMM[12]
-+	pxor	@XMM[11], @XMM[2]
-+	movdqu	0x50($inp), @XMM[15]	# IV
-+	pxor	@XMM[12], @XMM[7]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	movdqu	@XMM[2], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	jmp	.Lcbc_dec_done
-+.align	16
-+.Lcbc_dec_five:
-+	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
-+	call	_bsaes_decrypt8
-+	pxor	0x20(%rbp), @XMM[0]	# ^= IV
-+	movdqu	0x00($inp), @XMM[8]	# re-load input
-+	movdqu	0x10($inp), @XMM[9]
-+	pxor	@XMM[8], @XMM[1]
-+	movdqu	0x20($inp), @XMM[10]
-+	pxor	@XMM[9], @XMM[6]
-+	movdqu	0x30($inp), @XMM[11]
-+	pxor	@XMM[10], @XMM[4]
-+	movdqu	0x40($inp), @XMM[15]	# IV
-+	pxor	@XMM[11], @XMM[2]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	movdqu	@XMM[2], 0x40($out)
-+	jmp	.Lcbc_dec_done
-+.align	16
-+.Lcbc_dec_four:
-+	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
-+	call	_bsaes_decrypt8
-+	pxor	0x20(%rbp), @XMM[0]	# ^= IV
-+	movdqu	0x00($inp), @XMM[8]	# re-load input
-+	movdqu	0x10($inp), @XMM[9]
-+	pxor	@XMM[8], @XMM[1]
-+	movdqu	0x20($inp), @XMM[10]
-+	pxor	@XMM[9], @XMM[6]
-+	movdqu	0x30($inp), @XMM[15]	# IV
-+	pxor	@XMM[10], @XMM[4]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	jmp	.Lcbc_dec_done
-+.align	16
-+.Lcbc_dec_three:
-+	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
-+	call	_bsaes_decrypt8
-+	pxor	0x20(%rbp), @XMM[0]	# ^= IV
-+	movdqu	0x00($inp), @XMM[8]	# re-load input
-+	movdqu	0x10($inp), @XMM[9]
-+	pxor	@XMM[8], @XMM[1]
-+	movdqu	0x20($inp), @XMM[15]	# IV
-+	pxor	@XMM[9], @XMM[6]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	jmp	.Lcbc_dec_done
-+.align	16
-+.Lcbc_dec_two:
-+	movdqa	@XMM[15], 0x20(%rbp)	# put aside IV
-+	call	_bsaes_decrypt8
-+	pxor	0x20(%rbp), @XMM[0]	# ^= IV
-+	movdqu	0x00($inp), @XMM[8]	# re-load input
-+	movdqu	0x10($inp), @XMM[15]	# IV
-+	pxor	@XMM[8], @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	jmp	.Lcbc_dec_done
-+.align	16
-+.Lcbc_dec_one:
-+	lea	($inp), $arg1
-+	lea	0x20(%rbp), $arg2	# buffer output
-+	lea	($key), $arg3
-+	call	asm_AES_decrypt		# doesn't touch %xmm
-+	pxor	0x20(%rbp), @XMM[15]	# ^= IV
-+	movdqu	@XMM[15], ($out)	# write output
-+	movdqa	@XMM[0], @XMM[15]	# IV
-+
-+.Lcbc_dec_done:
-+	movdqu	@XMM[15], (%rbx)	# return IV
-+	lea	(%rsp), %rax
-+	pxor	%xmm0, %xmm0
-+.Lcbc_dec_bzero:			# wipe key schedule [if any]
-+	movdqa	%xmm0, 0x00(%rax)
-+	movdqa	%xmm0, 0x10(%rax)
-+	lea	0x20(%rax), %rax
-+	cmp	%rax, %rbp
-+	ja	.Lcbc_dec_bzero
-+
-+	lea	(%rbp),%rsp		# restore %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x40(%rbp), %xmm6
-+	movaps	0x50(%rbp), %xmm7
-+	movaps	0x60(%rbp), %xmm8
-+	movaps	0x70(%rbp), %xmm9
-+	movaps	0x80(%rbp), %xmm10
-+	movaps	0x90(%rbp), %xmm11
-+	movaps	0xa0(%rbp), %xmm12
-+	movaps	0xb0(%rbp), %xmm13
-+	movaps	0xc0(%rbp), %xmm14
-+	movaps	0xd0(%rbp), %xmm15
-+	lea	0xa0(%rbp), %rsp
-+___
-+$code.=<<___;
-+	mov	0x48(%rsp), %r15
-+	mov	0x50(%rsp), %r14
-+	mov	0x58(%rsp), %r13
-+	mov	0x60(%rsp), %r12
-+	mov	0x68(%rsp), %rbx
-+	mov	0x70(%rsp), %rax
-+	lea	0x78(%rsp), %rsp
-+	mov	%rax, %rbp
-+.Lcbc_dec_epilogue:
-+	ret
-+.size	bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
-+
-+.globl	bsaes_ctr32_encrypt_blocks
-+.type	bsaes_ctr32_encrypt_blocks,\@abi-omnipotent
-+.align	16
-+bsaes_ctr32_encrypt_blocks:
-+	mov	%rsp, %rax
-+.Lctr_enc_prologue:
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	lea	-0x48(%rsp), %rsp
-+___
-+$code.=<<___ if ($win64);
-+	mov	0xa0(%rsp),$arg5	# pull ivp
-+	lea	-0xa0(%rsp), %rsp
-+	movaps	%xmm6, 0x40(%rsp)
-+	movaps	%xmm7, 0x50(%rsp)
-+	movaps	%xmm8, 0x60(%rsp)
-+	movaps	%xmm9, 0x70(%rsp)
-+	movaps	%xmm10, 0x80(%rsp)
-+	movaps	%xmm11, 0x90(%rsp)
-+	movaps	%xmm12, 0xa0(%rsp)
-+	movaps	%xmm13, 0xb0(%rsp)
-+	movaps	%xmm14, 0xc0(%rsp)
-+	movaps	%xmm15, 0xd0(%rsp)
-+.Lctr_enc_body:
-+___
-+$code.=<<___;
-+	mov	%rsp, %rbp		# backup %rsp
-+	movdqu	($arg5), %xmm0		# load counter
-+	mov	240($arg4), %eax	# rounds
-+	mov	$arg1, $inp		# backup arguments
-+	mov	$arg2, $out
-+	mov	$arg3, $len
-+	mov	$arg4, $key
-+	movdqa	%xmm0, 0x20(%rbp)	# copy counter
-+	cmp	\$8, $arg3
-+	jb	.Lctr_enc_short
-+
-+	mov	%eax, %ebx		# rounds
-+	shl	\$7, %rax		# 128 bytes per inner round key
-+	sub	\$`128-32`, %rax	# size of bit-sliced key schedule
-+	sub	%rax, %rsp
-+
-+	mov	%rsp, %rax		# pass key schedule
-+	mov	$key, %rcx		# pass key
-+	mov	%ebx, %r10d		# pass rounds
-+	call	_bsaes_key_convert
-+	pxor	%xmm6,%xmm7		# fix up last round key
-+	movdqa	%xmm7,(%rax)		# save last round key
-+
-+	movdqa	(%rsp), @XMM[9]		# load round0 key
-+	lea	.LADD1(%rip), %r11
-+	movdqa	0x20(%rbp), @XMM[0]	# counter copy
-+	movdqa	-0x20(%r11), @XMM[8]	# .LSWPUP
-+	pshufb	@XMM[8], @XMM[9]	# byte swap upper part
-+	pshufb	@XMM[8], @XMM[0]
-+	movdqa	@XMM[9], (%rsp)		# save adjusted round0 key
-+	jmp	.Lctr_enc_loop
-+.align	16
-+.Lctr_enc_loop:
-+	movdqa	@XMM[0], 0x20(%rbp)	# save counter
-+	movdqa	@XMM[0], @XMM[1]	# prepare 8 counter values
-+	movdqa	@XMM[0], @XMM[2]
-+	paddd	0x00(%r11), @XMM[1]	# .LADD1
-+	movdqa	@XMM[0], @XMM[3]
-+	paddd	0x10(%r11), @XMM[2]	# .LADD2
-+	movdqa	@XMM[0], @XMM[4]
-+	paddd	0x20(%r11), @XMM[3]	# .LADD3
-+	movdqa	@XMM[0], @XMM[5]
-+	paddd	0x30(%r11), @XMM[4]	# .LADD4
-+	movdqa	@XMM[0], @XMM[6]
-+	paddd	0x40(%r11), @XMM[5]	# .LADD5
-+	movdqa	@XMM[0], @XMM[7]
-+	paddd	0x50(%r11), @XMM[6]	# .LADD6
-+	paddd	0x60(%r11), @XMM[7]	# .LADD7
-+
-+	# Borrow prologue from _bsaes_encrypt8 to use the opportunity
-+	# to flip byte order in 32-bit counter
-+	movdqa	(%rsp), @XMM[9]		# round 0 key
-+	lea	0x10(%rsp), %rax	# pass key schedule
-+	movdqa	-0x10(%r11), @XMM[8]	# .LSWPUPM0SR
-+	pxor	@XMM[9], @XMM[0]	# xor with round0 key
-+	pxor	@XMM[9], @XMM[1]
-+	pxor	@XMM[9], @XMM[2]
-+	pxor	@XMM[9], @XMM[3]
-+	 pshufb	@XMM[8], @XMM[0]
-+	 pshufb	@XMM[8], @XMM[1]
-+	pxor	@XMM[9], @XMM[4]
-+	pxor	@XMM[9], @XMM[5]
-+	 pshufb	@XMM[8], @XMM[2]
-+	 pshufb	@XMM[8], @XMM[3]
-+	pxor	@XMM[9], @XMM[6]
-+	pxor	@XMM[9], @XMM[7]
-+	 pshufb	@XMM[8], @XMM[4]
-+	 pshufb	@XMM[8], @XMM[5]
-+	 pshufb	@XMM[8], @XMM[6]
-+	 pshufb	@XMM[8], @XMM[7]
-+	lea	.LBS0(%rip), %r11	# constants table
-+	mov	%ebx,%r10d		# pass rounds
-+
-+	call	_bsaes_encrypt8_bitslice
-+
-+	sub	\$8,$len
-+	jc	.Lctr_enc_loop_done
-+
-+	movdqu	0x00($inp), @XMM[8]	# load input
-+	movdqu	0x10($inp), @XMM[9]
-+	movdqu	0x20($inp), @XMM[10]
-+	movdqu	0x30($inp), @XMM[11]
-+	movdqu	0x40($inp), @XMM[12]
-+	movdqu	0x50($inp), @XMM[13]
-+	movdqu	0x60($inp), @XMM[14]
-+	movdqu	0x70($inp), @XMM[15]
-+	lea	0x80($inp),$inp
-+	pxor	@XMM[0], @XMM[8]
-+	movdqa	0x20(%rbp), @XMM[0]	# load counter
-+	pxor	@XMM[9], @XMM[1]
-+	movdqu	@XMM[8], 0x00($out)	# write output
-+	pxor	@XMM[10], @XMM[4]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	@XMM[11], @XMM[6]
-+	movdqu	@XMM[4], 0x20($out)
-+	pxor	@XMM[12], @XMM[3]
-+	movdqu	@XMM[6], 0x30($out)
-+	pxor	@XMM[13], @XMM[7]
-+	movdqu	@XMM[3], 0x40($out)
-+	pxor	@XMM[14], @XMM[2]
-+	movdqu	@XMM[7], 0x50($out)
-+	pxor	@XMM[15], @XMM[5]
-+	movdqu	@XMM[2], 0x60($out)
-+	lea	.LADD1(%rip), %r11
-+	movdqu	@XMM[5], 0x70($out)
-+	lea	0x80($out), $out
-+	paddd	0x70(%r11), @XMM[0]	# .LADD8
-+	jnz	.Lctr_enc_loop
-+
-+	jmp	.Lctr_enc_done
-+.align	16
-+.Lctr_enc_loop_done:
-+	add	\$8, $len
-+	movdqu	0x00($inp), @XMM[8]	# load input
-+	pxor	@XMM[8], @XMM[0]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	cmp	\$2,$len
-+	jb	.Lctr_enc_done
-+	movdqu	0x10($inp), @XMM[9]
-+	pxor	@XMM[9], @XMM[1]
-+	movdqu	@XMM[1], 0x10($out)
-+	je	.Lctr_enc_done
-+	movdqu	0x20($inp), @XMM[10]
-+	pxor	@XMM[10], @XMM[4]
-+	movdqu	@XMM[4], 0x20($out)
-+	cmp	\$4,$len
-+	jb	.Lctr_enc_done
-+	movdqu	0x30($inp), @XMM[11]
-+	pxor	@XMM[11], @XMM[6]
-+	movdqu	@XMM[6], 0x30($out)
-+	je	.Lctr_enc_done
-+	movdqu	0x40($inp), @XMM[12]
-+	pxor	@XMM[12], @XMM[3]
-+	movdqu	@XMM[3], 0x40($out)
-+	cmp	\$6,$len
-+	jb	.Lctr_enc_done
-+	movdqu	0x50($inp), @XMM[13]
-+	pxor	@XMM[13], @XMM[7]
-+	movdqu	@XMM[7], 0x50($out)
-+	je	.Lctr_enc_done
-+	movdqu	0x60($inp), @XMM[14]
-+	pxor	@XMM[14], @XMM[2]
-+	movdqu	@XMM[2], 0x60($out)
-+	jmp	.Lctr_enc_done
-+
-+.align	16
-+.Lctr_enc_short:
-+	lea	0x20(%rbp), $arg1
-+	lea	0x30(%rbp), $arg2
-+	lea	($key), $arg3
-+	call	asm_AES_encrypt
-+	movdqu	($inp), @XMM[1]
-+	lea	16($inp), $inp
-+	mov	0x2c(%rbp), %eax	# load 32-bit counter
-+	bswap	%eax
-+	pxor	0x30(%rbp), @XMM[1]
-+	inc	%eax			# increment
-+	movdqu	@XMM[1], ($out)
-+	bswap	%eax
-+	lea	16($out), $out
-+	mov	%eax, 0x2c(%rsp)	# save 32-bit counter
-+	dec	$len
-+	jnz	.Lctr_enc_short
-+
-+.Lctr_enc_done:
-+	lea	(%rsp), %rax
-+	pxor	%xmm0, %xmm0
-+.Lctr_enc_bzero:			# wipe key schedule [if any]
-+	movdqa	%xmm0, 0x00(%rax)
-+	movdqa	%xmm0, 0x10(%rax)
-+	lea	0x20(%rax), %rax
-+	cmp	%rax, %rbp
-+	ja	.Lctr_enc_bzero
-+
-+	lea	(%rbp),%rsp		# restore %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x40(%rbp), %xmm6
-+	movaps	0x50(%rbp), %xmm7
-+	movaps	0x60(%rbp), %xmm8
-+	movaps	0x70(%rbp), %xmm9
-+	movaps	0x80(%rbp), %xmm10
-+	movaps	0x90(%rbp), %xmm11
-+	movaps	0xa0(%rbp), %xmm12
-+	movaps	0xb0(%rbp), %xmm13
-+	movaps	0xc0(%rbp), %xmm14
-+	movaps	0xd0(%rbp), %xmm15
-+	lea	0xa0(%rbp), %rsp
-+___
-+$code.=<<___;
-+	mov	0x48(%rsp), %r15
-+	mov	0x50(%rsp), %r14
-+	mov	0x58(%rsp), %r13
-+	mov	0x60(%rsp), %r12
-+	mov	0x68(%rsp), %rbx
-+	mov	0x70(%rsp), %rax
-+	lea	0x78(%rsp), %rsp
-+	mov	%rax, %rbp
-+.Lctr_enc_epilogue:
-+	ret
-+.size	bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
-+___
-+######################################################################
-+# void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len,
-+#	const AES_KEY *key1, const AES_KEY *key2,
-+#	const unsigned char iv[16]);
-+#
-+my ($twmask,$twres,$twtmp)=@XMM[13..15];
-+$arg6=~s/d$//;
-+
-+$code.=<<___;
-+.globl	bsaes_xts_encrypt
-+.type	bsaes_xts_encrypt,\@abi-omnipotent
-+.align	16
-+bsaes_xts_encrypt:
-+	mov	%rsp, %rax
-+.Lxts_enc_prologue:
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	lea	-0x48(%rsp), %rsp
-+___
-+$code.=<<___ if ($win64);
-+	mov	0xa0(%rsp),$arg5	# pull key2
-+	mov	0xa8(%rsp),$arg6	# pull ivp
-+	lea	-0xa0(%rsp), %rsp
-+	movaps	%xmm6, 0x40(%rsp)
-+	movaps	%xmm7, 0x50(%rsp)
-+	movaps	%xmm8, 0x60(%rsp)
-+	movaps	%xmm9, 0x70(%rsp)
-+	movaps	%xmm10, 0x80(%rsp)
-+	movaps	%xmm11, 0x90(%rsp)
-+	movaps	%xmm12, 0xa0(%rsp)
-+	movaps	%xmm13, 0xb0(%rsp)
-+	movaps	%xmm14, 0xc0(%rsp)
-+	movaps	%xmm15, 0xd0(%rsp)
-+.Lxts_enc_body:
-+___
-+$code.=<<___;
-+	mov	%rsp, %rbp		# backup %rsp
-+	mov	$arg1, $inp		# backup arguments
-+	mov	$arg2, $out
-+	mov	$arg3, $len
-+	mov	$arg4, $key
-+
-+	lea	($arg6), $arg1
-+	lea	0x20(%rbp), $arg2
-+	lea	($arg5), $arg3
-+	call	asm_AES_encrypt		# generate initial tweak
-+
-+	mov	240($key), %eax		# rounds
-+	mov	$len, %rbx		# backup $len
-+
-+	mov	%eax, %edx		# rounds
-+	shl	\$7, %rax		# 128 bytes per inner round key
-+	sub	\$`128-32`, %rax	# size of bit-sliced key schedule
-+	sub	%rax, %rsp
-+
-+	mov	%rsp, %rax		# pass key schedule
-+	mov	$key, %rcx		# pass key
-+	mov	%edx, %r10d		# pass rounds
-+	call	_bsaes_key_convert
-+	pxor	%xmm6, %xmm7		# fix up last round key
-+	movdqa	%xmm7, (%rax)		# save last round key
-+
-+	and	\$-16, $len
-+	sub	\$0x80, %rsp		# place for tweak[8]
-+	movdqa	0x20(%rbp), @XMM[7]	# initial tweak
-+
-+	pxor	$twtmp, $twtmp
-+	movdqa	.Lxts_magic(%rip), $twmask
-+	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
-+
-+	sub	\$0x80, $len
-+	jc	.Lxts_enc_short
-+	jmp	.Lxts_enc_loop
-+
-+.align	16
-+.Lxts_enc_loop:
-+___
-+    for ($i=0;$i<7;$i++) {
-+    $code.=<<___;
-+	pshufd	\$0x13, $twtmp, $twres
-+	pxor	$twtmp, $twtmp
-+	movdqa	@XMM[7], @XMM[$i]
-+	movdqa	@XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
-+	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
-+	pand	$twmask, $twres		# isolate carry and residue
-+	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
-+	pxor	$twres, @XMM[7]
-+___
-+    $code.=<<___ if ($i>=1);
-+	movdqu	`0x10*($i-1)`($inp), @XMM[8+$i-1]
-+___
-+    $code.=<<___ if ($i>=2);
-+	pxor	@XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
-+___
-+    }
-+$code.=<<___;
-+	movdqu	0x60($inp), @XMM[8+6]
-+	pxor	@XMM[8+5], @XMM[5]
-+	movdqu	0x70($inp), @XMM[8+7]
-+	lea	0x80($inp), $inp
-+	movdqa	@XMM[7], 0x70(%rsp)
-+	pxor	@XMM[8+6], @XMM[6]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	pxor	@XMM[8+7], @XMM[7]
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_encrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[4]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	0x30(%rsp), @XMM[6]
-+	movdqu	@XMM[4], 0x20($out)
-+	pxor	0x40(%rsp), @XMM[3]
-+	movdqu	@XMM[6], 0x30($out)
-+	pxor	0x50(%rsp), @XMM[7]
-+	movdqu	@XMM[3], 0x40($out)
-+	pxor	0x60(%rsp), @XMM[2]
-+	movdqu	@XMM[7], 0x50($out)
-+	pxor	0x70(%rsp), @XMM[5]
-+	movdqu	@XMM[2], 0x60($out)
-+	movdqu	@XMM[5], 0x70($out)
-+	lea	0x80($out), $out
-+
-+	movdqa	0x70(%rsp), @XMM[7]	# prepare next iteration tweak
-+	pxor	$twtmp, $twtmp
-+	movdqa	.Lxts_magic(%rip), $twmask
-+	pcmpgtd	@XMM[7], $twtmp
-+	pshufd	\$0x13, $twtmp, $twres
-+	pxor	$twtmp, $twtmp
-+	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
-+	pand	$twmask, $twres		# isolate carry and residue
-+	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
-+	pxor	$twres, @XMM[7]
-+
-+	sub	\$0x80,$len
-+	jnc	.Lxts_enc_loop
-+
-+.Lxts_enc_short:
-+	add	\$0x80, $len
-+	jz	.Lxts_enc_done
-+___
-+    for ($i=0;$i<7;$i++) {
-+    $code.=<<___;
-+	pshufd	\$0x13, $twtmp, $twres
-+	pxor	$twtmp, $twtmp
-+	movdqa	@XMM[7], @XMM[$i]
-+	movdqa	@XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
-+	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
-+	pand	$twmask, $twres		# isolate carry and residue
-+	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
-+	pxor	$twres, @XMM[7]
-+___
-+    $code.=<<___ if ($i>=1);
-+	movdqu	`0x10*($i-1)`($inp), @XMM[8+$i-1]
-+	cmp	\$`0x10*$i`,$len
-+	je	.Lxts_enc_$i
-+___
-+    $code.=<<___ if ($i>=2);
-+	pxor	@XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
-+___
-+    }
-+$code.=<<___;
-+	movdqu	0x60($inp), @XMM[8+6]
-+	pxor	@XMM[8+5], @XMM[5]
-+	movdqa	@XMM[7], 0x70(%rsp)
-+	lea	0x70($inp), $inp
-+	pxor	@XMM[8+6], @XMM[6]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_encrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[4]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	0x30(%rsp), @XMM[6]
-+	movdqu	@XMM[4], 0x20($out)
-+	pxor	0x40(%rsp), @XMM[3]
-+	movdqu	@XMM[6], 0x30($out)
-+	pxor	0x50(%rsp), @XMM[7]
-+	movdqu	@XMM[3], 0x40($out)
-+	pxor	0x60(%rsp), @XMM[2]
-+	movdqu	@XMM[7], 0x50($out)
-+	movdqu	@XMM[2], 0x60($out)
-+	lea	0x70($out), $out
-+
-+	movdqa	0x70(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_enc_done
-+.align	16
-+.Lxts_enc_6:
-+	pxor	@XMM[8+4], @XMM[4]
-+	lea	0x60($inp), $inp
-+	pxor	@XMM[8+5], @XMM[5]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_encrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[4]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	0x30(%rsp), @XMM[6]
-+	movdqu	@XMM[4], 0x20($out)
-+	pxor	0x40(%rsp), @XMM[3]
-+	movdqu	@XMM[6], 0x30($out)
-+	pxor	0x50(%rsp), @XMM[7]
-+	movdqu	@XMM[3], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	lea	0x60($out), $out
-+
-+	movdqa	0x60(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_enc_done
-+.align	16
-+.Lxts_enc_5:
-+	pxor	@XMM[8+3], @XMM[3]
-+	lea	0x50($inp), $inp
-+	pxor	@XMM[8+4], @XMM[4]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_encrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[4]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	0x30(%rsp), @XMM[6]
-+	movdqu	@XMM[4], 0x20($out)
-+	pxor	0x40(%rsp), @XMM[3]
-+	movdqu	@XMM[6], 0x30($out)
-+	movdqu	@XMM[3], 0x40($out)
-+	lea	0x50($out), $out
-+
-+	movdqa	0x50(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_enc_done
-+.align	16
-+.Lxts_enc_4:
-+	pxor	@XMM[8+2], @XMM[2]
-+	lea	0x40($inp), $inp
-+	pxor	@XMM[8+3], @XMM[3]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_encrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[4]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	0x30(%rsp), @XMM[6]
-+	movdqu	@XMM[4], 0x20($out)
-+	movdqu	@XMM[6], 0x30($out)
-+	lea	0x40($out), $out
-+
-+	movdqa	0x40(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_enc_done
-+.align	16
-+.Lxts_enc_3:
-+	pxor	@XMM[8+1], @XMM[1]
-+	lea	0x30($inp), $inp
-+	pxor	@XMM[8+2], @XMM[2]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_encrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[4]
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[4], 0x20($out)
-+	lea	0x30($out), $out
-+
-+	movdqa	0x30(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_enc_done
-+.align	16
-+.Lxts_enc_2:
-+	pxor	@XMM[8+0], @XMM[0]
-+	lea	0x20($inp), $inp
-+	pxor	@XMM[8+1], @XMM[1]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_encrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	lea	0x20($out), $out
-+
-+	movdqa	0x20(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_enc_done
-+.align	16
-+.Lxts_enc_1:
-+	pxor	@XMM[0], @XMM[8]
-+	lea	0x10($inp), $inp
-+	movdqa	@XMM[8], 0x20(%rbp)
-+	lea	0x20(%rbp), $arg1
-+	lea	0x20(%rbp), $arg2
-+	lea	($key), $arg3
-+	call	asm_AES_encrypt		# doesn't touch %xmm
-+	pxor	0x20(%rbp), @XMM[0]	# ^= tweak[]
-+	#pxor	@XMM[8], @XMM[0]
-+	#lea	0x80(%rsp), %rax	# pass key schedule
-+	#mov	%edx, %r10d		# pass rounds
-+	#call	_bsaes_encrypt8
-+	#pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	lea	0x10($out), $out
-+
-+	movdqa	0x10(%rsp), @XMM[7]	# next iteration tweak
-+
-+.Lxts_enc_done:
-+	and	\$15, %ebx
-+	jz	.Lxts_enc_ret
-+	mov	$out, %rdx
-+
-+.Lxts_enc_steal:
-+	movzb	($inp), %eax
-+	movzb	-16(%rdx), %ecx
-+	lea	1($inp), $inp
-+	mov	%al, -16(%rdx)
-+	mov	%cl, 0(%rdx)
-+	lea	1(%rdx), %rdx
-+	sub	\$1,%ebx
-+	jnz	.Lxts_enc_steal
-+
-+	movdqu	-16($out), @XMM[0]
-+	lea	0x20(%rbp), $arg1
-+	pxor	@XMM[7], @XMM[0]
-+	lea	0x20(%rbp), $arg2
-+	movdqa	@XMM[0], 0x20(%rbp)
-+	lea	($key), $arg3
-+	call	asm_AES_encrypt		# doesn't touch %xmm
-+	pxor	0x20(%rbp), @XMM[7]
-+	movdqu	@XMM[7], -16($out)
-+
-+.Lxts_enc_ret:
-+	lea	(%rsp), %rax
-+	pxor	%xmm0, %xmm0
-+.Lxts_enc_bzero:			# wipe key schedule [if any]
-+	movdqa	%xmm0, 0x00(%rax)
-+	movdqa	%xmm0, 0x10(%rax)
-+	lea	0x20(%rax), %rax
-+	cmp	%rax, %rbp
-+	ja	.Lxts_enc_bzero
-+
-+	lea	(%rbp),%rsp		# restore %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x40(%rbp), %xmm6
-+	movaps	0x50(%rbp), %xmm7
-+	movaps	0x60(%rbp), %xmm8
-+	movaps	0x70(%rbp), %xmm9
-+	movaps	0x80(%rbp), %xmm10
-+	movaps	0x90(%rbp), %xmm11
-+	movaps	0xa0(%rbp), %xmm12
-+	movaps	0xb0(%rbp), %xmm13
-+	movaps	0xc0(%rbp), %xmm14
-+	movaps	0xd0(%rbp), %xmm15
-+	lea	0xa0(%rbp), %rsp
-+___
-+$code.=<<___;
-+	mov	0x48(%rsp), %r15
-+	mov	0x50(%rsp), %r14
-+	mov	0x58(%rsp), %r13
-+	mov	0x60(%rsp), %r12
-+	mov	0x68(%rsp), %rbx
-+	mov	0x70(%rsp), %rax
-+	lea	0x78(%rsp), %rsp
-+	mov	%rax, %rbp
-+.Lxts_enc_epilogue:
-+	ret
-+.size	bsaes_xts_encrypt,.-bsaes_xts_encrypt
-+
-+.globl	bsaes_xts_decrypt
-+.type	bsaes_xts_decrypt,\@abi-omnipotent
-+.align	16
-+bsaes_xts_decrypt:
-+	mov	%rsp, %rax
-+.Lxts_dec_prologue:
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	lea	-0x48(%rsp), %rsp
-+___
-+$code.=<<___ if ($win64);
-+	mov	0xa0(%rsp),$arg5	# pull key2
-+	mov	0xa8(%rsp),$arg6	# pull ivp
-+	lea	-0xa0(%rsp), %rsp
-+	movaps	%xmm6, 0x40(%rsp)
-+	movaps	%xmm7, 0x50(%rsp)
-+	movaps	%xmm8, 0x60(%rsp)
-+	movaps	%xmm9, 0x70(%rsp)
-+	movaps	%xmm10, 0x80(%rsp)
-+	movaps	%xmm11, 0x90(%rsp)
-+	movaps	%xmm12, 0xa0(%rsp)
-+	movaps	%xmm13, 0xb0(%rsp)
-+	movaps	%xmm14, 0xc0(%rsp)
-+	movaps	%xmm15, 0xd0(%rsp)
-+.Lxts_dec_body:
-+___
-+$code.=<<___;
-+	mov	%rsp, %rbp		# backup %rsp
-+	mov	$arg1, $inp		# backup arguments
-+	mov	$arg2, $out
-+	mov	$arg3, $len
-+	mov	$arg4, $key
-+
-+	lea	($arg6), $arg1
-+	lea	0x20(%rbp), $arg2
-+	lea	($arg5), $arg3
-+	call	asm_AES_encrypt		# generate initial tweak
-+
-+	mov	240($key), %eax		# rounds
-+	mov	$len, %rbx		# backup $len
-+
-+	mov	%eax, %edx		# rounds
-+	shl	\$7, %rax		# 128 bytes per inner round key
-+	sub	\$`128-32`, %rax	# size of bit-sliced key schedule
-+	sub	%rax, %rsp
-+
-+	mov	%rsp, %rax		# pass key schedule
-+	mov	$key, %rcx		# pass key
-+	mov	%edx, %r10d		# pass rounds
-+	call	_bsaes_key_convert
-+	pxor	(%rsp), %xmm7		# fix up round 0 key
-+	movdqa	%xmm6, (%rax)		# save last round key
-+	movdqa	%xmm7, (%rsp)
-+
-+	xor	%eax, %eax		# if ($len%16) len-=16;
-+	and	\$-16, $len
-+	test	\$15, %ebx
-+	setnz	%al
-+	shl	\$4, %rax
-+	sub	%rax, $len
-+
-+	sub	\$0x80, %rsp		# place for tweak[8]
-+	movdqa	0x20(%rbp), @XMM[7]	# initial tweak
-+
-+	pxor	$twtmp, $twtmp
-+	movdqa	.Lxts_magic(%rip), $twmask
-+	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
-+
-+	sub	\$0x80, $len
-+	jc	.Lxts_dec_short
-+	jmp	.Lxts_dec_loop
-+
-+.align	16
-+.Lxts_dec_loop:
-+___
-+    for ($i=0;$i<7;$i++) {
-+    $code.=<<___;
-+	pshufd	\$0x13, $twtmp, $twres
-+	pxor	$twtmp, $twtmp
-+	movdqa	@XMM[7], @XMM[$i]
-+	movdqa	@XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
-+	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
-+	pand	$twmask, $twres		# isolate carry and residue
-+	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
-+	pxor	$twres, @XMM[7]
-+___
-+    $code.=<<___ if ($i>=1);
-+	movdqu	`0x10*($i-1)`($inp), @XMM[8+$i-1]
-+___
-+    $code.=<<___ if ($i>=2);
-+	pxor	@XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
-+___
-+    }
-+$code.=<<___;
-+	movdqu	0x60($inp), @XMM[8+6]
-+	pxor	@XMM[8+5], @XMM[5]
-+	movdqu	0x70($inp), @XMM[8+7]
-+	lea	0x80($inp), $inp
-+	movdqa	@XMM[7], 0x70(%rsp)
-+	pxor	@XMM[8+6], @XMM[6]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	pxor	@XMM[8+7], @XMM[7]
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_decrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[6]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	0x30(%rsp), @XMM[4]
-+	movdqu	@XMM[6], 0x20($out)
-+	pxor	0x40(%rsp), @XMM[2]
-+	movdqu	@XMM[4], 0x30($out)
-+	pxor	0x50(%rsp), @XMM[7]
-+	movdqu	@XMM[2], 0x40($out)
-+	pxor	0x60(%rsp), @XMM[3]
-+	movdqu	@XMM[7], 0x50($out)
-+	pxor	0x70(%rsp), @XMM[5]
-+	movdqu	@XMM[3], 0x60($out)
-+	movdqu	@XMM[5], 0x70($out)
-+	lea	0x80($out), $out
-+
-+	movdqa	0x70(%rsp), @XMM[7]	# prepare next iteration tweak
-+	pxor	$twtmp, $twtmp
-+	movdqa	.Lxts_magic(%rip), $twmask
-+	pcmpgtd	@XMM[7], $twtmp
-+	pshufd	\$0x13, $twtmp, $twres
-+	pxor	$twtmp, $twtmp
-+	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
-+	pand	$twmask, $twres		# isolate carry and residue
-+	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
-+	pxor	$twres, @XMM[7]
-+
-+	sub	\$0x80,$len
-+	jnc	.Lxts_dec_loop
-+
-+.Lxts_dec_short:
-+	add	\$0x80, $len
-+	jz	.Lxts_dec_done
-+___
-+    for ($i=0;$i<7;$i++) {
-+    $code.=<<___;
-+	pshufd	\$0x13, $twtmp, $twres
-+	pxor	$twtmp, $twtmp
-+	movdqa	@XMM[7], @XMM[$i]
-+	movdqa	@XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
-+	paddq	@XMM[7], @XMM[7]	# psllq	1,$tweak
-+	pand	$twmask, $twres		# isolate carry and residue
-+	pcmpgtd	@XMM[7], $twtmp		# broadcast upper bits
-+	pxor	$twres, @XMM[7]
-+___
-+    $code.=<<___ if ($i>=1);
-+	movdqu	`0x10*($i-1)`($inp), @XMM[8+$i-1]
-+	cmp	\$`0x10*$i`,$len
-+	je	.Lxts_dec_$i
-+___
-+    $code.=<<___ if ($i>=2);
-+	pxor	@XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
-+___
-+    }
-+$code.=<<___;
-+	movdqu	0x60($inp), @XMM[8+6]
-+	pxor	@XMM[8+5], @XMM[5]
-+	movdqa	@XMM[7], 0x70(%rsp)
-+	lea	0x70($inp), $inp
-+	pxor	@XMM[8+6], @XMM[6]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_decrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[6]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	0x30(%rsp), @XMM[4]
-+	movdqu	@XMM[6], 0x20($out)
-+	pxor	0x40(%rsp), @XMM[2]
-+	movdqu	@XMM[4], 0x30($out)
-+	pxor	0x50(%rsp), @XMM[7]
-+	movdqu	@XMM[2], 0x40($out)
-+	pxor	0x60(%rsp), @XMM[3]
-+	movdqu	@XMM[7], 0x50($out)
-+	movdqu	@XMM[3], 0x60($out)
-+	lea	0x70($out), $out
-+
-+	movdqa	0x70(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_dec_done
-+.align	16
-+.Lxts_dec_6:
-+	pxor	@XMM[8+4], @XMM[4]
-+	lea	0x60($inp), $inp
-+	pxor	@XMM[8+5], @XMM[5]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_decrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[6]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	0x30(%rsp), @XMM[4]
-+	movdqu	@XMM[6], 0x20($out)
-+	pxor	0x40(%rsp), @XMM[2]
-+	movdqu	@XMM[4], 0x30($out)
-+	pxor	0x50(%rsp), @XMM[7]
-+	movdqu	@XMM[2], 0x40($out)
-+	movdqu	@XMM[7], 0x50($out)
-+	lea	0x60($out), $out
-+
-+	movdqa	0x60(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_dec_done
-+.align	16
-+.Lxts_dec_5:
-+	pxor	@XMM[8+3], @XMM[3]
-+	lea	0x50($inp), $inp
-+	pxor	@XMM[8+4], @XMM[4]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_decrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[6]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	0x30(%rsp), @XMM[4]
-+	movdqu	@XMM[6], 0x20($out)
-+	pxor	0x40(%rsp), @XMM[2]
-+	movdqu	@XMM[4], 0x30($out)
-+	movdqu	@XMM[2], 0x40($out)
-+	lea	0x50($out), $out
-+
-+	movdqa	0x50(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_dec_done
-+.align	16
-+.Lxts_dec_4:
-+	pxor	@XMM[8+2], @XMM[2]
-+	lea	0x40($inp), $inp
-+	pxor	@XMM[8+3], @XMM[3]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_decrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[6]
-+	movdqu	@XMM[1], 0x10($out)
-+	pxor	0x30(%rsp), @XMM[4]
-+	movdqu	@XMM[6], 0x20($out)
-+	movdqu	@XMM[4], 0x30($out)
-+	lea	0x40($out), $out
-+
-+	movdqa	0x40(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_dec_done
-+.align	16
-+.Lxts_dec_3:
-+	pxor	@XMM[8+1], @XMM[1]
-+	lea	0x30($inp), $inp
-+	pxor	@XMM[8+2], @XMM[2]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_decrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	pxor	0x20(%rsp), @XMM[6]
-+	movdqu	@XMM[1], 0x10($out)
-+	movdqu	@XMM[6], 0x20($out)
-+	lea	0x30($out), $out
-+
-+	movdqa	0x30(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_dec_done
-+.align	16
-+.Lxts_dec_2:
-+	pxor	@XMM[8+0], @XMM[0]
-+	lea	0x20($inp), $inp
-+	pxor	@XMM[8+1], @XMM[1]
-+	lea	0x80(%rsp), %rax	# pass key schedule
-+	mov	%edx, %r10d		# pass rounds
-+
-+	call	_bsaes_decrypt8
-+
-+	pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	pxor	0x10(%rsp), @XMM[1]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	movdqu	@XMM[1], 0x10($out)
-+	lea	0x20($out), $out
-+
-+	movdqa	0x20(%rsp), @XMM[7]	# next iteration tweak
-+	jmp	.Lxts_dec_done
-+.align	16
-+.Lxts_dec_1:
-+	pxor	@XMM[0], @XMM[8]
-+	lea	0x10($inp), $inp
-+	movdqa	@XMM[8], 0x20(%rbp)
-+	lea	0x20(%rbp), $arg1
-+	lea	0x20(%rbp), $arg2
-+	lea	($key), $arg3
-+	call	asm_AES_decrypt		# doesn't touch %xmm
-+	pxor	0x20(%rbp), @XMM[0]	# ^= tweak[]
-+	#pxor	@XMM[8], @XMM[0]
-+	#lea	0x80(%rsp), %rax	# pass key schedule
-+	#mov	%edx, %r10d		# pass rounds
-+	#call	_bsaes_decrypt8
-+	#pxor	0x00(%rsp), @XMM[0]	# ^= tweak[]
-+	movdqu	@XMM[0], 0x00($out)	# write output
-+	lea	0x10($out), $out
-+
-+	movdqa	0x10(%rsp), @XMM[7]	# next iteration tweak
-+
-+.Lxts_dec_done:
-+	and	\$15, %ebx
-+	jz	.Lxts_dec_ret
-+
-+	pxor	$twtmp, $twtmp
-+	movdqa	.Lxts_magic(%rip), $twmask
-+	pcmpgtd	@XMM[7], $twtmp
-+	pshufd	\$0x13, $twtmp, $twres
-+	movdqa	@XMM[7], @XMM[6]
-+	paddq	@XMM[7], @XMM[7]	# psllq 1,$tweak
-+	pand	$twmask, $twres		# isolate carry and residue
-+	movdqu	($inp), @XMM[0]
-+	pxor	$twres, @XMM[7]
-+
-+	lea	0x20(%rbp), $arg1
-+	pxor	@XMM[7], @XMM[0]
-+	lea	0x20(%rbp), $arg2
-+	movdqa	@XMM[0], 0x20(%rbp)
-+	lea	($key), $arg3
-+	call	asm_AES_decrypt		# doesn't touch %xmm
-+	pxor	0x20(%rbp), @XMM[7]
-+	mov	$out, %rdx
-+	movdqu	@XMM[7], ($out)
-+
-+.Lxts_dec_steal:
-+	movzb	16($inp), %eax
-+	movzb	(%rdx), %ecx
-+	lea	1($inp), $inp
-+	mov	%al, (%rdx)
-+	mov	%cl, 16(%rdx)
-+	lea	1(%rdx), %rdx
-+	sub	\$1,%ebx
-+	jnz	.Lxts_dec_steal
-+
-+	movdqu	($out), @XMM[0]
-+	lea	0x20(%rbp), $arg1
-+	pxor	@XMM[6], @XMM[0]
-+	lea	0x20(%rbp), $arg2
-+	movdqa	@XMM[0], 0x20(%rbp)
-+	lea	($key), $arg3
-+	call	asm_AES_decrypt		# doesn't touch %xmm
-+	pxor	0x20(%rbp), @XMM[6]
-+	movdqu	@XMM[6], ($out)
-+
-+.Lxts_dec_ret:
-+	lea	(%rsp), %rax
-+	pxor	%xmm0, %xmm0
-+.Lxts_dec_bzero:			# wipe key schedule [if any]
-+	movdqa	%xmm0, 0x00(%rax)
-+	movdqa	%xmm0, 0x10(%rax)
-+	lea	0x20(%rax), %rax
-+	cmp	%rax, %rbp
-+	ja	.Lxts_dec_bzero
-+
-+	lea	(%rbp),%rsp		# restore %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x40(%rbp), %xmm6
-+	movaps	0x50(%rbp), %xmm7
-+	movaps	0x60(%rbp), %xmm8
-+	movaps	0x70(%rbp), %xmm9
-+	movaps	0x80(%rbp), %xmm10
-+	movaps	0x90(%rbp), %xmm11
-+	movaps	0xa0(%rbp), %xmm12
-+	movaps	0xb0(%rbp), %xmm13
-+	movaps	0xc0(%rbp), %xmm14
-+	movaps	0xd0(%rbp), %xmm15
-+	lea	0xa0(%rbp), %rsp
-+___
-+$code.=<<___;
-+	mov	0x48(%rsp), %r15
-+	mov	0x50(%rsp), %r14
-+	mov	0x58(%rsp), %r13
-+	mov	0x60(%rsp), %r12
-+	mov	0x68(%rsp), %rbx
-+	mov	0x70(%rsp), %rax
-+	lea	0x78(%rsp), %rsp
-+	mov	%rax, %rbp
-+.Lxts_dec_epilogue:
-+	ret
-+.size	bsaes_xts_decrypt,.-bsaes_xts_decrypt
-+___
-+}
-+$code.=<<___;
-+.type	_bsaes_const,\@object
-+.align	64
-+_bsaes_const:
-+.LM0ISR:	# InvShiftRows constants
-+	.quad	0x0a0e0206070b0f03, 0x0004080c0d010509
-+.LISRM0:
-+	.quad	0x01040b0e0205080f, 0x0306090c00070a0d
-+.LISR:
-+	.quad	0x0504070602010003, 0x0f0e0d0c080b0a09
-+.LBS0:		# bit-slice constants
-+	.quad	0x5555555555555555, 0x5555555555555555
-+.LBS1:
-+	.quad	0x3333333333333333, 0x3333333333333333
-+.LBS2:
-+	.quad	0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f
-+.LSR:		# shiftrows constants
-+	.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
-+.LSRM0:
-+	.quad	0x0304090e00050a0f, 0x01060b0c0207080d
-+.LM0SR:
-+	.quad	0x0a0e02060f03070b, 0x0004080c05090d01
-+.LSWPUP:	# byte-swap upper dword
-+	.quad	0x0706050403020100, 0x0c0d0e0f0b0a0908
-+.LSWPUPM0SR:
-+	.quad	0x0a0d02060c03070b, 0x0004080f05090e01
-+.LADD1:		# counter increment constants
-+	.quad	0x0000000000000000, 0x0000000100000000
-+.LADD2:
-+	.quad	0x0000000000000000, 0x0000000200000000
-+.LADD3:
-+	.quad	0x0000000000000000, 0x0000000300000000
-+.LADD4:
-+	.quad	0x0000000000000000, 0x0000000400000000
-+.LADD5:
-+	.quad	0x0000000000000000, 0x0000000500000000
-+.LADD6:
-+	.quad	0x0000000000000000, 0x0000000600000000
-+.LADD7:
-+	.quad	0x0000000000000000, 0x0000000700000000
-+.LADD8:
-+	.quad	0x0000000000000000, 0x0000000800000000
-+.Lxts_magic:
-+	.long	0x87,0,1,0
-+.Lmasks:
-+	.quad	0x0101010101010101, 0x0101010101010101
-+	.quad	0x0202020202020202, 0x0202020202020202
-+	.quad	0x0404040404040404, 0x0404040404040404
-+	.quad	0x0808080808080808, 0x0808080808080808
-+.LM0:
-+	.quad	0x02060a0e03070b0f, 0x0004080c0105090d
-+.L63:
-+	.quad	0x6363636363636363, 0x6363636363636363
-+.asciz	"Bit-sliced AES for x86_64/SSSE3, Emilia Käsper, Peter Schwabe, Andy Polyakov"
-+.align	64
-+.size	_bsaes_const,.-_bsaes_const
-+___
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_prologue
-+
-+	mov	160($context),%rax	# pull context->Rbp
-+
-+	lea	0x40(%rax),%rsi		# %xmm save area
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
-+	.long	0xa548f3fc		# cld; rep movsq
-+	lea	0xa0(%rax),%rax		# adjust stack pointer
-+
-+	mov	0x70(%rax),%rbp
-+	mov	0x68(%rax),%rbx
-+	mov	0x60(%rax),%r12
-+	mov	0x58(%rax),%r13
-+	mov	0x50(%rax),%r14
-+	mov	0x48(%rax),%r15
-+	lea	0x78(%rax),%rax		# adjust stack pointer
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lin_prologue:
-+	mov	%rax,152($context)	# restore context->Rsp
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+
-+.section	.pdata
-+.align	4
-+___
-+$code.=<<___ if ($ecb);
-+	.rva	.Lecb_enc_prologue
-+	.rva	.Lecb_enc_epilogue
-+	.rva	.Lecb_enc_info
-+
-+	.rva	.Lecb_dec_prologue
-+	.rva	.Lecb_dec_epilogue
-+	.rva	.Lecb_dec_info
-+___
-+$code.=<<___;
-+	.rva	.Lcbc_dec_prologue
-+	.rva	.Lcbc_dec_epilogue
-+	.rva	.Lcbc_dec_info
-+
-+	.rva	.Lctr_enc_prologue
-+	.rva	.Lctr_enc_epilogue
-+	.rva	.Lctr_enc_info
-+
-+	.rva	.Lxts_enc_prologue
-+	.rva	.Lxts_enc_epilogue
-+	.rva	.Lxts_enc_info
-+
-+	.rva	.Lxts_dec_prologue
-+	.rva	.Lxts_dec_epilogue
-+	.rva	.Lxts_dec_info
-+
-+.section	.xdata
-+.align	8
-+___
-+$code.=<<___ if ($ecb);
-+.Lecb_enc_info:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lecb_enc_body,.Lecb_enc_epilogue	# HandlerData[]
-+.Lecb_dec_info:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lecb_dec_body,.Lecb_dec_epilogue	# HandlerData[]
-+___
-+$code.=<<___;
-+.Lcbc_dec_info:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lcbc_dec_body,.Lcbc_dec_epilogue	# HandlerData[]
-+.Lctr_enc_info:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lctr_enc_body,.Lctr_enc_epilogue	# HandlerData[]
-+.Lxts_enc_info:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lxts_enc_body,.Lxts_enc_epilogue	# HandlerData[]
-+.Lxts_dec_info:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lxts_dec_body,.Lxts_dec_epilogue	# HandlerData[]
-+___
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-armv8.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-armv8.pl
-new file mode 100755
-index 0000000..d6b5f56
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-armv8.pl
-@@ -0,0 +1,1259 @@
-+#! /usr/bin/env perl
-+# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+######################################################################
-+## Constant-time SSSE3 AES core implementation.
-+## version 0.1
-+##
-+## By Mike Hamburg (Stanford University), 2009
-+## Public domain.
-+##
-+## For details see http://shiftleft.org/papers/vector_aes/ and
-+## http://crypto.stanford.edu/vpaes/.
-+##
-+######################################################################
-+# ARMv8 NEON adaptation by 
-+#
-+# Reason for undertaken effort is that there is at least one popular
-+# SoC based on Cortex-A53 that doesn't have crypto extensions.
-+#
-+#                   CBC enc     ECB enc/dec(*)   [bit-sliced enc/dec]
-+# Cortex-A53        21.5        18.1/20.6        [17.5/19.8         ]
-+# Cortex-A57        36.0(**)    20.4/24.9(**)    [14.4/16.6         ]
-+# X-Gene            45.9(**)    45.8/57.7(**)    [33.1/37.6(**)     ]
-+# Denver(***)       16.6(**)    15.1/17.8(**)    [8.80/9.93         ]
-+# Apple A7(***)     22.7(**)    10.9/14.3        [8.45/10.0         ]
-+# Mongoose(***)     26.3(**)    21.0/25.0(**)    [13.3/16.8         ]
-+#
-+# (*)	ECB denotes approximate result for parallelizeable modes
-+#	such as CBC decrypt, CTR, etc.;
-+# (**)	these results are worse than scalar compiler-generated
-+#	code, but it's constant-time and therefore preferred;
-+# (***)	presented for reference/comparison purposes;
-+
-+$flavour = shift;
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+$code.=<<___;
-+.text
-+
-+.type	_vpaes_consts,%object
-+.align	7	// totally strategic alignment
-+_vpaes_consts:
-+.Lk_mc_forward:	// mc_forward
-+	.quad	0x0407060500030201, 0x0C0F0E0D080B0A09
-+	.quad	0x080B0A0904070605, 0x000302010C0F0E0D
-+	.quad	0x0C0F0E0D080B0A09, 0x0407060500030201
-+	.quad	0x000302010C0F0E0D, 0x080B0A0904070605
-+.Lk_mc_backward:// mc_backward
-+	.quad	0x0605040702010003, 0x0E0D0C0F0A09080B
-+	.quad	0x020100030E0D0C0F, 0x0A09080B06050407
-+	.quad	0x0E0D0C0F0A09080B, 0x0605040702010003
-+	.quad	0x0A09080B06050407, 0x020100030E0D0C0F
-+.Lk_sr:		// sr
-+	.quad	0x0706050403020100, 0x0F0E0D0C0B0A0908
-+	.quad	0x030E09040F0A0500, 0x0B06010C07020D08
-+	.quad	0x0F060D040B020900, 0x070E050C030A0108
-+	.quad	0x0B0E0104070A0D00, 0x0306090C0F020508
-+
-+//
-+// "Hot" constants
-+//
-+.Lk_inv:	// inv, inva
-+	.quad	0x0E05060F0D080180, 0x040703090A0B0C02
-+	.quad	0x01040A060F0B0780, 0x030D0E0C02050809
-+.Lk_ipt:	// input transform (lo, hi)
-+	.quad	0xC2B2E8985A2A7000, 0xCABAE09052227808
-+	.quad	0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
-+.Lk_sbo:	// sbou, sbot
-+	.quad	0xD0D26D176FBDC700, 0x15AABF7AC502A878
-+	.quad	0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
-+.Lk_sb1:	// sb1u, sb1t
-+	.quad	0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
-+	.quad	0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
-+.Lk_sb2:	// sb2u, sb2t
-+	.quad	0x69EB88400AE12900, 0xC2A163C8AB82234A
-+	.quad	0xE27A93C60B712400, 0x5EB7E955BC982FCD
-+
-+//
-+//  Decryption stuff
-+//
-+.Lk_dipt:	// decryption input transform
-+	.quad	0x0F505B040B545F00, 0x154A411E114E451A
-+	.quad	0x86E383E660056500, 0x12771772F491F194
-+.Lk_dsbo:	// decryption sbox final output
-+	.quad	0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
-+	.quad	0x12D7560F93441D00, 0xCA4B8159D8C58E9C
-+.Lk_dsb9:	// decryption sbox output *9*u, *9*t
-+	.quad	0x851C03539A86D600, 0xCAD51F504F994CC9
-+	.quad	0xC03B1789ECD74900, 0x725E2C9EB2FBA565
-+.Lk_dsbd:	// decryption sbox output *D*u, *D*t
-+	.quad	0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
-+	.quad	0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
-+.Lk_dsbb:	// decryption sbox output *B*u, *B*t
-+	.quad	0xD022649296B44200, 0x602646F6B0F2D404
-+	.quad	0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
-+.Lk_dsbe:	// decryption sbox output *E*u, *E*t
-+	.quad	0x46F2929626D4D000, 0x2242600464B4F6B0
-+	.quad	0x0C55A6CDFFAAC100, 0x9467F36B98593E32
-+
-+//
-+//  Key schedule constants
-+//
-+.Lk_dksd:	// decryption key schedule: invskew x*D
-+	.quad	0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
-+	.quad	0x41C277F4B5368300, 0x5FDC69EAAB289D1E
-+.Lk_dksb:	// decryption key schedule: invskew x*B
-+	.quad	0x9A4FCA1F8550D500, 0x03D653861CC94C99
-+	.quad	0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
-+.Lk_dkse:	// decryption key schedule: invskew x*E + 0x63
-+	.quad	0xD5031CCA1FC9D600, 0x53859A4C994F5086
-+	.quad	0xA23196054FDC7BE8, 0xCD5EF96A20B31487
-+.Lk_dks9:	// decryption key schedule: invskew x*9
-+	.quad	0xB6116FC87ED9A700, 0x4AED933482255BFC
-+	.quad	0x4576516227143300, 0x8BB89FACE9DAFDCE
-+
-+.Lk_rcon:	// rcon
-+	.quad	0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
-+
-+.Lk_opt:	// output transform
-+	.quad	0xFF9F4929D6B66000, 0xF7974121DEBE6808
-+	.quad	0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
-+.Lk_deskew:	// deskew tables: inverts the sbox's "skew"
-+	.quad	0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
-+	.quad	0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
-+
-+.asciz  "Vector Permutaion AES for ARMv8, Mike Hamburg (Stanford University)"
-+.size	_vpaes_consts,.-_vpaes_consts
-+.align	6
-+___
-+
-+{
-+my ($inp,$out,$key) = map("x$_",(0..2));
-+
-+my ($invlo,$invhi,$iptlo,$ipthi,$sbou,$sbot) = map("v$_.16b",(18..23));
-+my ($sb1u,$sb1t,$sb2u,$sb2t) = map("v$_.16b",(24..27));
-+my ($sb9u,$sb9t,$sbdu,$sbdt,$sbbu,$sbbt,$sbeu,$sbet)=map("v$_.16b",(24..31));
-+
-+$code.=<<___;
-+##
-+##  _aes_preheat
-+##
-+##  Fills register %r10 -> .aes_consts (so you can -fPIC)
-+##  and %xmm9-%xmm15 as specified below.
-+##
-+.type	_vpaes_encrypt_preheat,%function
-+.align	4
-+_vpaes_encrypt_preheat:
-+	adr	x10, .Lk_inv
-+	movi	v17.16b, #0x0f
-+	ld1	{v18.2d-v19.2d}, [x10],#32	// .Lk_inv
-+	ld1	{v20.2d-v23.2d}, [x10],#64	// .Lk_ipt, .Lk_sbo
-+	ld1	{v24.2d-v27.2d}, [x10]		// .Lk_sb1, .Lk_sb2
-+	ret
-+.size	_vpaes_encrypt_preheat,.-_vpaes_encrypt_preheat
-+
-+##
-+##  _aes_encrypt_core
-+##
-+##  AES-encrypt %xmm0.
-+##
-+##  Inputs:
-+##     %xmm0 = input
-+##     %xmm9-%xmm15 as in _vpaes_preheat
-+##    (%rdx) = scheduled keys
-+##
-+##  Output in %xmm0
-+##  Clobbers  %xmm1-%xmm5, %r9, %r10, %r11, %rax
-+##  Preserves %xmm6 - %xmm8 so you get some local vectors
-+##
-+##
-+.type	_vpaes_encrypt_core,%function
-+.align 4
-+_vpaes_encrypt_core:
-+	mov	x9, $key
-+	ldr	w8, [$key,#240]			// pull rounds
-+	adr	x11, .Lk_mc_forward+16
-+						// vmovdqa	.Lk_ipt(%rip),	%xmm2	# iptlo
-+	ld1	{v16.2d}, [x9], #16		// vmovdqu	(%r9),	%xmm5		# round0 key
-+	and	v1.16b, v7.16b, v17.16b		// vpand	%xmm9,	%xmm0,	%xmm1
-+	ushr	v0.16b, v7.16b, #4		// vpsrlb	\$4,	%xmm0,	%xmm0
-+	tbl	v1.16b, {$iptlo}, v1.16b	// vpshufb	%xmm1,	%xmm2,	%xmm1
-+						// vmovdqa	.Lk_ipt+16(%rip), %xmm3	# ipthi
-+	tbl	v2.16b, {$ipthi}, v0.16b	// vpshufb	%xmm0,	%xmm3,	%xmm2
-+	eor	v0.16b, v1.16b, v16.16b		// vpxor	%xmm5,	%xmm1,	%xmm0
-+	eor	v0.16b, v0.16b, v2.16b		// vpxor	%xmm2,	%xmm0,	%xmm0
-+	b	.Lenc_entry
-+
-+.align 4
-+.Lenc_loop:
-+	// middle of middle round
-+	add	x10, x11, #0x40
-+	tbl	v4.16b, {$sb1t}, v2.16b		// vpshufb	%xmm2,	%xmm13,	%xmm4	# 4 = sb1u
-+	ld1	{v1.2d}, [x11], #16		// vmovdqa	-0x40(%r11,%r10), %xmm1	# .Lk_mc_forward[]
-+	tbl	v0.16b, {$sb1u}, v3.16b		// vpshufb	%xmm3,	%xmm12,	%xmm0	# 0 = sb1t
-+	eor	v4.16b, v4.16b, v16.16b		// vpxor	%xmm5,	%xmm4,	%xmm4	# 4 = sb1u + k
-+	tbl	v5.16b,	{$sb2t}, v2.16b		// vpshufb	%xmm2,	%xmm15,	%xmm5	# 4 = sb2u
-+	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0,	%xmm0	# 0 = A
-+	tbl	v2.16b, {$sb2u}, v3.16b		// vpshufb	%xmm3,	%xmm14,	%xmm2	# 2 = sb2t
-+	ld1	{v4.2d}, [x10]			// vmovdqa	(%r11,%r10), %xmm4	# .Lk_mc_backward[]
-+	tbl	v3.16b, {v0.16b}, v1.16b	// vpshufb	%xmm1,	%xmm0,	%xmm3	# 0 = B
-+	eor	v2.16b, v2.16b, v5.16b		// vpxor	%xmm5,	%xmm2,	%xmm2	# 2 = 2A
-+	tbl	v0.16b, {v0.16b}, v4.16b	// vpshufb	%xmm4,	%xmm0,	%xmm0	# 3 = D
-+	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3	# 0 = 2A+B
-+	tbl	v4.16b, {v3.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm4	# 0 = 2B+C
-+	eor	v0.16b, v0.16b, v3.16b		// vpxor	%xmm3,	%xmm0,	%xmm0	# 3 = 2A+B+D
-+	and	x11, x11, #~(1<<6)		// and		\$0x30,	%r11		# ... mod 4
-+	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0, %xmm0	# 0 = 2A+3B+C+D
-+	sub	w8, w8, #1			// nr--
-+
-+.Lenc_entry:
-+	// top of round
-+	and	v1.16b, v0.16b, v17.16b		// vpand	%xmm0,	%xmm9,	%xmm1   # 0 = k
-+	ushr	v0.16b, v0.16b, #4		// vpsrlb	\$4,	%xmm0,	%xmm0	# 1 = i
-+	tbl	v5.16b, {$invhi}, v1.16b	// vpshufb	%xmm1,	%xmm11,	%xmm5	# 2 = a/k
-+	eor	v1.16b, v1.16b, v0.16b		// vpxor	%xmm0,	%xmm1,	%xmm1	# 0 = j
-+	tbl	v3.16b, {$invlo}, v0.16b	// vpshufb	%xmm0, 	%xmm10,	%xmm3  	# 3 = 1/i
-+	tbl	v4.16b, {$invlo}, v1.16b	// vpshufb	%xmm1, 	%xmm10,	%xmm4  	# 4 = 1/j
-+	eor	v3.16b, v3.16b, v5.16b		// vpxor	%xmm5,	%xmm3,	%xmm3	# 3 = iak = 1/i + a/k
-+	eor	v4.16b, v4.16b, v5.16b		// vpxor	%xmm5,	%xmm4,	%xmm4  	# 4 = jak = 1/j + a/k
-+	tbl	v2.16b, {$invlo}, v3.16b	// vpshufb	%xmm3,	%xmm10,	%xmm2  	# 2 = 1/iak
-+	tbl	v3.16b, {$invlo}, v4.16b	// vpshufb	%xmm4,	%xmm10,	%xmm3	# 3 = 1/jak
-+	eor	v2.16b, v2.16b, v1.16b		// vpxor	%xmm1,	%xmm2,	%xmm2  	# 2 = io
-+	eor	v3.16b, v3.16b, v0.16b		// vpxor	%xmm0,	%xmm3,	%xmm3	# 3 = jo
-+	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm5
-+	cbnz	w8, .Lenc_loop
-+
-+	// middle of last round
-+	add	x10, x11, #0x80
-+						// vmovdqa	-0x60(%r10), %xmm4	# 3 : sbou	.Lk_sbo
-+						// vmovdqa	-0x50(%r10), %xmm0	# 0 : sbot	.Lk_sbo+16
-+	tbl	v4.16b, {$sbou}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4	# 4 = sbou
-+	ld1	{v1.2d}, [x10]			// vmovdqa	0x40(%r11,%r10), %xmm1	# .Lk_sr[]
-+	tbl	v0.16b, {$sbot}, v3.16b		// vpshufb	%xmm3,	%xmm0,	%xmm0	# 0 = sb1t
-+	eor	v4.16b, v4.16b, v16.16b		// vpxor	%xmm5,	%xmm4,	%xmm4	# 4 = sb1u + k
-+	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0,	%xmm0	# 0 = A
-+	tbl	v0.16b, {v0.16b}, v1.16b	// vpshufb	%xmm1,	%xmm0,	%xmm0
-+	ret
-+.size	_vpaes_encrypt_core,.-_vpaes_encrypt_core
-+
-+.globl	vpaes_encrypt
-+.type	vpaes_encrypt,%function
-+.align	4
-+vpaes_encrypt:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	ld1	{v7.16b}, [$inp]
-+	bl	_vpaes_encrypt_preheat
-+	bl	_vpaes_encrypt_core
-+	st1	{v0.16b}, [$out]
-+
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	vpaes_encrypt,.-vpaes_encrypt
-+
-+.type	_vpaes_encrypt_2x,%function
-+.align 4
-+_vpaes_encrypt_2x:
-+	mov	x9, $key
-+	ldr	w8, [$key,#240]			// pull rounds
-+	adr	x11, .Lk_mc_forward+16
-+						// vmovdqa	.Lk_ipt(%rip),	%xmm2	# iptlo
-+	ld1	{v16.2d}, [x9], #16		// vmovdqu	(%r9),	%xmm5		# round0 key
-+	and	v1.16b,  v14.16b,  v17.16b	// vpand	%xmm9,	%xmm0,	%xmm1
-+	ushr	v0.16b,  v14.16b,  #4		// vpsrlb	\$4,	%xmm0,	%xmm0
-+	 and	v9.16b,  v15.16b,  v17.16b
-+	 ushr	v8.16b,  v15.16b,  #4
-+	tbl	v1.16b,  {$iptlo}, v1.16b	// vpshufb	%xmm1,	%xmm2,	%xmm1
-+	 tbl	v9.16b,  {$iptlo}, v9.16b
-+						// vmovdqa	.Lk_ipt+16(%rip), %xmm3	# ipthi
-+	tbl	v2.16b,  {$ipthi}, v0.16b	// vpshufb	%xmm0,	%xmm3,	%xmm2
-+	 tbl	v10.16b, {$ipthi}, v8.16b
-+	eor	v0.16b,  v1.16b,   v16.16b	// vpxor	%xmm5,	%xmm1,	%xmm0
-+	 eor	v8.16b,  v9.16b,   v16.16b
-+	eor	v0.16b,  v0.16b,   v2.16b	// vpxor	%xmm2,	%xmm0,	%xmm0
-+	 eor	v8.16b,  v8.16b,   v10.16b
-+	b	.Lenc_2x_entry
-+
-+.align 4
-+.Lenc_2x_loop:
-+	// middle of middle round
-+	add	x10, x11, #0x40
-+	tbl	v4.16b,  {$sb1t}, v2.16b	// vpshufb	%xmm2,	%xmm13,	%xmm4	# 4 = sb1u
-+	 tbl	v12.16b, {$sb1t}, v10.16b
-+	ld1	{v1.2d}, [x11], #16		// vmovdqa	-0x40(%r11,%r10), %xmm1	# .Lk_mc_forward[]
-+	tbl	v0.16b,  {$sb1u}, v3.16b	// vpshufb	%xmm3,	%xmm12,	%xmm0	# 0 = sb1t
-+	 tbl	v8.16b,  {$sb1u}, v11.16b
-+	eor	v4.16b,  v4.16b,  v16.16b	// vpxor	%xmm5,	%xmm4,	%xmm4	# 4 = sb1u + k
-+	 eor	v12.16b, v12.16b, v16.16b
-+	tbl	v5.16b,	 {$sb2t}, v2.16b	// vpshufb	%xmm2,	%xmm15,	%xmm5	# 4 = sb2u
-+	 tbl	v13.16b, {$sb2t}, v10.16b
-+	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0,	%xmm0	# 0 = A
-+	 eor	v8.16b,  v8.16b,  v12.16b
-+	tbl	v2.16b,  {$sb2u}, v3.16b	// vpshufb	%xmm3,	%xmm14,	%xmm2	# 2 = sb2t
-+	 tbl	v10.16b, {$sb2u}, v11.16b
-+	ld1	{v4.2d}, [x10]			// vmovdqa	(%r11,%r10), %xmm4	# .Lk_mc_backward[]
-+	tbl	v3.16b,  {v0.16b}, v1.16b	// vpshufb	%xmm1,	%xmm0,	%xmm3	# 0 = B
-+	 tbl	v11.16b, {v8.16b}, v1.16b
-+	eor	v2.16b,  v2.16b,  v5.16b	// vpxor	%xmm5,	%xmm2,	%xmm2	# 2 = 2A
-+	 eor	v10.16b, v10.16b, v13.16b
-+	tbl	v0.16b,  {v0.16b}, v4.16b	// vpshufb	%xmm4,	%xmm0,	%xmm0	# 3 = D
-+	 tbl	v8.16b,  {v8.16b}, v4.16b
-+	eor	v3.16b,  v3.16b,  v2.16b	// vpxor	%xmm2,	%xmm3,	%xmm3	# 0 = 2A+B
-+	 eor	v11.16b, v11.16b, v10.16b
-+	tbl	v4.16b,  {v3.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm4	# 0 = 2B+C
-+	 tbl	v12.16b, {v11.16b},v1.16b
-+	eor	v0.16b,  v0.16b,  v3.16b	// vpxor	%xmm3,	%xmm0,	%xmm0	# 3 = 2A+B+D
-+	 eor	v8.16b,  v8.16b,  v11.16b
-+	and	x11, x11, #~(1<<6)		// and		\$0x30,	%r11		# ... mod 4
-+	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0, %xmm0	# 0 = 2A+3B+C+D
-+	 eor	v8.16b,  v8.16b,  v12.16b
-+	sub	w8, w8, #1			// nr--
-+
-+.Lenc_2x_entry:
-+	// top of round
-+	and	v1.16b,  v0.16b, v17.16b	// vpand	%xmm0,	%xmm9,	%xmm1   # 0 = k
-+	ushr	v0.16b,  v0.16b, #4		// vpsrlb	\$4,	%xmm0,	%xmm0	# 1 = i
-+	 and	v9.16b,  v8.16b, v17.16b
-+	 ushr	v8.16b,  v8.16b, #4
-+	tbl	v5.16b,  {$invhi},v1.16b	// vpshufb	%xmm1,	%xmm11,	%xmm5	# 2 = a/k
-+	 tbl	v13.16b, {$invhi},v9.16b
-+	eor	v1.16b,  v1.16b,  v0.16b	// vpxor	%xmm0,	%xmm1,	%xmm1	# 0 = j
-+	 eor	v9.16b,  v9.16b,  v8.16b
-+	tbl	v3.16b,  {$invlo},v0.16b	// vpshufb	%xmm0, 	%xmm10,	%xmm3  	# 3 = 1/i
-+	 tbl	v11.16b, {$invlo},v8.16b
-+	tbl	v4.16b,  {$invlo},v1.16b	// vpshufb	%xmm1, 	%xmm10,	%xmm4  	# 4 = 1/j
-+	 tbl	v12.16b, {$invlo},v9.16b
-+	eor	v3.16b,  v3.16b,  v5.16b	// vpxor	%xmm5,	%xmm3,	%xmm3	# 3 = iak = 1/i + a/k
-+	 eor	v11.16b, v11.16b, v13.16b
-+	eor	v4.16b,  v4.16b,  v5.16b	// vpxor	%xmm5,	%xmm4,	%xmm4  	# 4 = jak = 1/j + a/k
-+	 eor	v12.16b, v12.16b, v13.16b
-+	tbl	v2.16b,  {$invlo},v3.16b	// vpshufb	%xmm3,	%xmm10,	%xmm2  	# 2 = 1/iak
-+	 tbl	v10.16b, {$invlo},v11.16b
-+	tbl	v3.16b,  {$invlo},v4.16b	// vpshufb	%xmm4,	%xmm10,	%xmm3	# 3 = 1/jak
-+	 tbl	v11.16b, {$invlo},v12.16b
-+	eor	v2.16b,  v2.16b,  v1.16b	// vpxor	%xmm1,	%xmm2,	%xmm2  	# 2 = io
-+	 eor	v10.16b, v10.16b, v9.16b
-+	eor	v3.16b,  v3.16b,  v0.16b	// vpxor	%xmm0,	%xmm3,	%xmm3	# 3 = jo
-+	 eor	v11.16b, v11.16b, v8.16b
-+	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm5
-+	cbnz	w8, .Lenc_2x_loop
-+
-+	// middle of last round
-+	add	x10, x11, #0x80
-+						// vmovdqa	-0x60(%r10), %xmm4	# 3 : sbou	.Lk_sbo
-+						// vmovdqa	-0x50(%r10), %xmm0	# 0 : sbot	.Lk_sbo+16
-+	tbl	v4.16b,  {$sbou}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4	# 4 = sbou
-+	 tbl	v12.16b, {$sbou}, v10.16b
-+	ld1	{v1.2d}, [x10]			// vmovdqa	0x40(%r11,%r10), %xmm1	# .Lk_sr[]
-+	tbl	v0.16b,  {$sbot}, v3.16b	// vpshufb	%xmm3,	%xmm0,	%xmm0	# 0 = sb1t
-+	 tbl	v8.16b,  {$sbot}, v11.16b
-+	eor	v4.16b,  v4.16b,  v16.16b	// vpxor	%xmm5,	%xmm4,	%xmm4	# 4 = sb1u + k
-+	 eor	v12.16b, v12.16b, v16.16b
-+	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0,	%xmm0	# 0 = A
-+	 eor	v8.16b,  v8.16b,  v12.16b
-+	tbl	v0.16b,  {v0.16b},v1.16b	// vpshufb	%xmm1,	%xmm0,	%xmm0
-+	 tbl	v1.16b,  {v8.16b},v1.16b
-+	ret
-+.size	_vpaes_encrypt_2x,.-_vpaes_encrypt_2x
-+
-+.type	_vpaes_decrypt_preheat,%function
-+.align	4
-+_vpaes_decrypt_preheat:
-+	adr	x10, .Lk_inv
-+	movi	v17.16b, #0x0f
-+	adr	x11, .Lk_dipt
-+	ld1	{v18.2d-v19.2d}, [x10],#32	// .Lk_inv
-+	ld1	{v20.2d-v23.2d}, [x11],#64	// .Lk_dipt, .Lk_dsbo
-+	ld1	{v24.2d-v27.2d}, [x11],#64	// .Lk_dsb9, .Lk_dsbd
-+	ld1	{v28.2d-v31.2d}, [x11]		// .Lk_dsbb, .Lk_dsbe
-+	ret
-+.size	_vpaes_decrypt_preheat,.-_vpaes_decrypt_preheat
-+
-+##
-+##  Decryption core
-+##
-+##  Same API as encryption core.
-+##
-+.type	_vpaes_decrypt_core,%function
-+.align	4
-+_vpaes_decrypt_core:
-+	mov	x9, $key
-+	ldr	w8, [$key,#240]			// pull rounds
-+
-+						// vmovdqa	.Lk_dipt(%rip), %xmm2	# iptlo
-+	lsl	x11, x8, #4			// mov	%rax,	%r11;	shl	\$4, %r11
-+	eor	x11, x11, #0x30			// xor		\$0x30,	%r11
-+	adr	x10, .Lk_sr
-+	and	x11, x11, #0x30			// and		\$0x30,	%r11
-+	add	x11, x11, x10
-+	adr	x10, .Lk_mc_forward+48
-+
-+	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm4		# round0 key
-+	and	v1.16b, v7.16b, v17.16b		// vpand	%xmm9,	%xmm0,	%xmm1
-+	ushr	v0.16b, v7.16b, #4		// vpsrlb	\$4,	%xmm0,	%xmm0
-+	tbl	v2.16b, {$iptlo}, v1.16b	// vpshufb	%xmm1,	%xmm2,	%xmm2
-+	ld1	{v5.2d}, [x10]			// vmovdqa	.Lk_mc_forward+48(%rip), %xmm5
-+						// vmovdqa	.Lk_dipt+16(%rip), %xmm1 # ipthi
-+	tbl	v0.16b, {$ipthi}, v0.16b	// vpshufb	%xmm0,	%xmm1,	%xmm0
-+	eor	v2.16b, v2.16b, v16.16b		// vpxor	%xmm4,	%xmm2,	%xmm2
-+	eor	v0.16b, v0.16b, v2.16b		// vpxor	%xmm2,	%xmm0,	%xmm0
-+	b	.Ldec_entry
-+
-+.align 4
-+.Ldec_loop:
-+//
-+//  Inverse mix columns
-+//
-+						// vmovdqa	-0x20(%r10),%xmm4		# 4 : sb9u
-+						// vmovdqa	-0x10(%r10),%xmm1		# 0 : sb9t
-+	tbl	v4.16b, {$sb9u}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sb9u
-+	tbl	v1.16b, {$sb9t}, v3.16b		// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sb9t
-+	eor	v0.16b, v4.16b, v16.16b		// vpxor	%xmm4,	%xmm0,	%xmm0
-+						// vmovdqa	0x00(%r10),%xmm4		# 4 : sbdu
-+	eor	v0.16b, v0.16b, v1.16b		// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+						// vmovdqa	0x10(%r10),%xmm1		# 0 : sbdt
-+
-+	tbl	v4.16b, {$sbdu}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbdu
-+	tbl 	v0.16b, {v0.16b}, v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
-+	tbl	v1.16b, {$sbdt}, v3.16b		// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbdt
-+	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
-+						// vmovdqa	0x20(%r10),	%xmm4		# 4 : sbbu
-+	eor	v0.16b, v0.16b, v1.16b		// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+						// vmovdqa	0x30(%r10),	%xmm1		# 0 : sbbt
-+
-+	tbl	v4.16b, {$sbbu}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbbu
-+	tbl	v0.16b, {v0.16b}, v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
-+	tbl	v1.16b, {$sbbt}, v3.16b		// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbbt
-+	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
-+						// vmovdqa	0x40(%r10),	%xmm4		# 4 : sbeu
-+	eor	v0.16b, v0.16b, v1.16b		// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+						// vmovdqa	0x50(%r10),	%xmm1		# 0 : sbet
-+
-+	tbl	v4.16b, {$sbeu}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbeu
-+	tbl	v0.16b, {v0.16b}, v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
-+	tbl	v1.16b, {$sbet}, v3.16b		// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbet
-+	eor	v0.16b, v0.16b, v4.16b		// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
-+	ext	v5.16b, v5.16b, v5.16b, #12	// vpalignr \$12,	%xmm5,	%xmm5,	%xmm5
-+	eor	v0.16b, v0.16b, v1.16b		// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+	sub	w8, w8, #1			// sub		\$1,%rax			# nr--
-+
-+.Ldec_entry:
-+	// top of round
-+	and	v1.16b, v0.16b, v17.16b		// vpand	%xmm9,	%xmm0,	%xmm1	# 0 = k
-+	ushr	v0.16b, v0.16b, #4		// vpsrlb	\$4,	%xmm0,	%xmm0	# 1 = i
-+	tbl	v2.16b, {$invhi}, v1.16b	// vpshufb	%xmm1,	%xmm11,	%xmm2	# 2 = a/k
-+	eor	v1.16b,	v1.16b, v0.16b		// vpxor	%xmm0,	%xmm1,	%xmm1	# 0 = j
-+	tbl	v3.16b, {$invlo}, v0.16b	// vpshufb	%xmm0, 	%xmm10,	%xmm3	# 3 = 1/i
-+	tbl	v4.16b, {$invlo}, v1.16b	// vpshufb	%xmm1,	%xmm10,	%xmm4	# 4 = 1/j
-+	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3	# 3 = iak = 1/i + a/k
-+	eor	v4.16b, v4.16b, v2.16b		// vpxor	%xmm2, 	%xmm4,	%xmm4	# 4 = jak = 1/j + a/k
-+	tbl	v2.16b, {$invlo}, v3.16b	// vpshufb	%xmm3,	%xmm10,	%xmm2	# 2 = 1/iak
-+	tbl	v3.16b, {$invlo}, v4.16b	// vpshufb	%xmm4,  %xmm10,	%xmm3	# 3 = 1/jak
-+	eor	v2.16b, v2.16b, v1.16b		// vpxor	%xmm1,	%xmm2,	%xmm2	# 2 = io
-+	eor	v3.16b, v3.16b, v0.16b		// vpxor	%xmm0,  %xmm3,	%xmm3	# 3 = jo
-+	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm0
-+	cbnz	w8, .Ldec_loop
-+
-+	// middle of last round
-+						// vmovdqa	0x60(%r10),	%xmm4	# 3 : sbou
-+	tbl	v4.16b, {$sbou}, v2.16b		// vpshufb	%xmm2,	%xmm4,	%xmm4	# 4 = sbou
-+						// vmovdqa	0x70(%r10),	%xmm1	# 0 : sbot
-+	ld1	{v2.2d}, [x11]			// vmovdqa	-0x160(%r11),	%xmm2	# .Lk_sr-.Lk_dsbd=-0x160
-+	tbl	v1.16b, {$sbot}, v3.16b		// vpshufb	%xmm3,	%xmm1,	%xmm1	# 0 = sb1t
-+	eor	v4.16b, v4.16b, v16.16b		// vpxor	%xmm0,	%xmm4,	%xmm4	# 4 = sb1u + k
-+	eor	v0.16b, v1.16b, v4.16b		// vpxor	%xmm4,	%xmm1,	%xmm0	# 0 = A
-+	tbl	v0.16b, {v0.16b}, v2.16b	// vpshufb	%xmm2,	%xmm0,	%xmm0
-+	ret
-+.size	_vpaes_decrypt_core,.-_vpaes_decrypt_core
-+
-+.globl	vpaes_decrypt
-+.type	vpaes_decrypt,%function
-+.align	4
-+vpaes_decrypt:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	ld1	{v7.16b}, [$inp]
-+	bl	_vpaes_decrypt_preheat
-+	bl	_vpaes_decrypt_core
-+	st1	{v0.16b}, [$out]
-+
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	vpaes_decrypt,.-vpaes_decrypt
-+
-+// v14-v15 input, v0-v1 output
-+.type	_vpaes_decrypt_2x,%function
-+.align	4
-+_vpaes_decrypt_2x:
-+	mov	x9, $key
-+	ldr	w8, [$key,#240]			// pull rounds
-+
-+						// vmovdqa	.Lk_dipt(%rip), %xmm2	# iptlo
-+	lsl	x11, x8, #4			// mov	%rax,	%r11;	shl	\$4, %r11
-+	eor	x11, x11, #0x30			// xor		\$0x30,	%r11
-+	adr	x10, .Lk_sr
-+	and	x11, x11, #0x30			// and		\$0x30,	%r11
-+	add	x11, x11, x10
-+	adr	x10, .Lk_mc_forward+48
-+
-+	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm4		# round0 key
-+	and	v1.16b,  v14.16b, v17.16b	// vpand	%xmm9,	%xmm0,	%xmm1
-+	ushr	v0.16b,  v14.16b, #4		// vpsrlb	\$4,	%xmm0,	%xmm0
-+	 and	v9.16b,  v15.16b, v17.16b
-+	 ushr	v8.16b,  v15.16b, #4
-+	tbl	v2.16b,  {$iptlo},v1.16b	// vpshufb	%xmm1,	%xmm2,	%xmm2
-+	 tbl	v10.16b, {$iptlo},v9.16b
-+	ld1	{v5.2d}, [x10]			// vmovdqa	.Lk_mc_forward+48(%rip), %xmm5
-+						// vmovdqa	.Lk_dipt+16(%rip), %xmm1 # ipthi
-+	tbl	v0.16b,  {$ipthi},v0.16b	// vpshufb	%xmm0,	%xmm1,	%xmm0
-+	 tbl	v8.16b,  {$ipthi},v8.16b
-+	eor	v2.16b,  v2.16b,  v16.16b	// vpxor	%xmm4,	%xmm2,	%xmm2
-+	 eor	v10.16b, v10.16b, v16.16b
-+	eor	v0.16b,  v0.16b,  v2.16b	// vpxor	%xmm2,	%xmm0,	%xmm0
-+	 eor	v8.16b,  v8.16b,  v10.16b
-+	b	.Ldec_2x_entry
-+
-+.align 4
-+.Ldec_2x_loop:
-+//
-+//  Inverse mix columns
-+//
-+						// vmovdqa	-0x20(%r10),%xmm4		# 4 : sb9u
-+						// vmovdqa	-0x10(%r10),%xmm1		# 0 : sb9t
-+	tbl	v4.16b,  {$sb9u}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sb9u
-+	 tbl	v12.16b, {$sb9u}, v10.16b
-+	tbl	v1.16b,  {$sb9t}, v3.16b	// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sb9t
-+	 tbl	v9.16b,  {$sb9t}, v11.16b
-+	eor	v0.16b,  v4.16b,  v16.16b	// vpxor	%xmm4,	%xmm0,	%xmm0
-+	 eor	v8.16b,  v12.16b, v16.16b
-+						// vmovdqa	0x00(%r10),%xmm4		# 4 : sbdu
-+	eor	v0.16b,  v0.16b,  v1.16b	// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+	 eor	v8.16b,  v8.16b,  v9.16b	// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+						// vmovdqa	0x10(%r10),%xmm1		# 0 : sbdt
-+
-+	tbl	v4.16b,  {$sbdu}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbdu
-+	 tbl	v12.16b, {$sbdu}, v10.16b
-+	tbl 	v0.16b,  {v0.16b},v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
-+	 tbl 	v8.16b,  {v8.16b},v5.16b
-+	tbl	v1.16b,  {$sbdt}, v3.16b	// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbdt
-+	 tbl	v9.16b,  {$sbdt}, v11.16b
-+	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
-+	 eor	v8.16b,  v8.16b,  v12.16b
-+						// vmovdqa	0x20(%r10),	%xmm4		# 4 : sbbu
-+	eor	v0.16b,  v0.16b,  v1.16b	// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+	 eor	v8.16b,  v8.16b,  v9.16b
-+						// vmovdqa	0x30(%r10),	%xmm1		# 0 : sbbt
-+
-+	tbl	v4.16b,  {$sbbu}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbbu
-+	 tbl	v12.16b, {$sbbu}, v10.16b
-+	tbl	v0.16b,  {v0.16b},v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
-+	 tbl	v8.16b,  {v8.16b},v5.16b
-+	tbl	v1.16b,  {$sbbt}, v3.16b	// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbbt
-+	 tbl	v9.16b,  {$sbbt}, v11.16b
-+	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
-+	 eor	v8.16b,  v8.16b,  v12.16b
-+						// vmovdqa	0x40(%r10),	%xmm4		# 4 : sbeu
-+	eor	v0.16b,  v0.16b,  v1.16b	// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+	 eor	v8.16b,  v8.16b,  v9.16b
-+						// vmovdqa	0x50(%r10),	%xmm1		# 0 : sbet
-+
-+	tbl	v4.16b,  {$sbeu}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbeu
-+	 tbl	v12.16b, {$sbeu}, v10.16b
-+	tbl	v0.16b,  {v0.16b},v5.16b	// vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
-+	 tbl	v8.16b,  {v8.16b},v5.16b
-+	tbl	v1.16b,  {$sbet}, v3.16b	// vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbet
-+	 tbl	v9.16b,  {$sbet}, v11.16b
-+	eor	v0.16b,  v0.16b,  v4.16b	// vpxor	%xmm4,	%xmm0,	%xmm0		# 4 = ch
-+	 eor	v8.16b,  v8.16b,  v12.16b
-+	ext	v5.16b,  v5.16b,  v5.16b, #12	// vpalignr \$12,	%xmm5,	%xmm5,	%xmm5
-+	eor	v0.16b,  v0.16b,  v1.16b	// vpxor	%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+	 eor	v8.16b,  v8.16b,  v9.16b
-+	sub	w8, w8, #1			// sub		\$1,%rax			# nr--
-+
-+.Ldec_2x_entry:
-+	// top of round
-+	and	v1.16b,  v0.16b,  v17.16b	// vpand	%xmm9,	%xmm0,	%xmm1	# 0 = k
-+	ushr	v0.16b,  v0.16b,  #4		// vpsrlb	\$4,	%xmm0,	%xmm0	# 1 = i
-+	 and	v9.16b,  v8.16b,  v17.16b
-+	 ushr	v8.16b,  v8.16b,  #4
-+	tbl	v2.16b,  {$invhi},v1.16b	// vpshufb	%xmm1,	%xmm11,	%xmm2	# 2 = a/k
-+	 tbl	v10.16b, {$invhi},v9.16b
-+	eor	v1.16b,	 v1.16b,  v0.16b	// vpxor	%xmm0,	%xmm1,	%xmm1	# 0 = j
-+	 eor	v9.16b,	 v9.16b,  v8.16b
-+	tbl	v3.16b,  {$invlo},v0.16b	// vpshufb	%xmm0, 	%xmm10,	%xmm3	# 3 = 1/i
-+	 tbl	v11.16b, {$invlo},v8.16b
-+	tbl	v4.16b,  {$invlo},v1.16b	// vpshufb	%xmm1,	%xmm10,	%xmm4	# 4 = 1/j
-+	 tbl	v12.16b, {$invlo},v9.16b
-+	eor	v3.16b,  v3.16b,  v2.16b	// vpxor	%xmm2,	%xmm3,	%xmm3	# 3 = iak = 1/i + a/k
-+	 eor	v11.16b, v11.16b, v10.16b
-+	eor	v4.16b,  v4.16b,  v2.16b	// vpxor	%xmm2, 	%xmm4,	%xmm4	# 4 = jak = 1/j + a/k
-+	 eor	v12.16b, v12.16b, v10.16b
-+	tbl	v2.16b,  {$invlo},v3.16b	// vpshufb	%xmm3,	%xmm10,	%xmm2	# 2 = 1/iak
-+	 tbl	v10.16b, {$invlo},v11.16b
-+	tbl	v3.16b,  {$invlo},v4.16b	// vpshufb	%xmm4,  %xmm10,	%xmm3	# 3 = 1/jak
-+	 tbl	v11.16b, {$invlo},v12.16b
-+	eor	v2.16b,  v2.16b,  v1.16b	// vpxor	%xmm1,	%xmm2,	%xmm2	# 2 = io
-+	 eor	v10.16b, v10.16b, v9.16b
-+	eor	v3.16b,  v3.16b,  v0.16b	// vpxor	%xmm0,  %xmm3,	%xmm3	# 3 = jo
-+	 eor	v11.16b, v11.16b, v8.16b
-+	ld1	{v16.2d}, [x9],#16		// vmovdqu	(%r9),	%xmm0
-+	cbnz	w8, .Ldec_2x_loop
-+
-+	// middle of last round
-+						// vmovdqa	0x60(%r10),	%xmm4	# 3 : sbou
-+	tbl	v4.16b,  {$sbou}, v2.16b	// vpshufb	%xmm2,	%xmm4,	%xmm4	# 4 = sbou
-+	 tbl	v12.16b, {$sbou}, v10.16b
-+						// vmovdqa	0x70(%r10),	%xmm1	# 0 : sbot
-+	tbl	v1.16b,  {$sbot}, v3.16b	// vpshufb	%xmm3,	%xmm1,	%xmm1	# 0 = sb1t
-+	 tbl	v9.16b,  {$sbot}, v11.16b
-+	ld1	{v2.2d}, [x11]			// vmovdqa	-0x160(%r11),	%xmm2	# .Lk_sr-.Lk_dsbd=-0x160
-+	eor	v4.16b,  v4.16b,  v16.16b	// vpxor	%xmm0,	%xmm4,	%xmm4	# 4 = sb1u + k
-+	 eor	v12.16b, v12.16b, v16.16b
-+	eor	v0.16b,  v1.16b,  v4.16b	// vpxor	%xmm4,	%xmm1,	%xmm0	# 0 = A
-+	 eor	v8.16b,  v9.16b,  v12.16b
-+	tbl	v0.16b,  {v0.16b},v2.16b	// vpshufb	%xmm2,	%xmm0,	%xmm0
-+	 tbl	v1.16b,  {v8.16b},v2.16b
-+	ret
-+.size	_vpaes_decrypt_2x,.-_vpaes_decrypt_2x
-+___
-+}
-+{
-+my ($inp,$bits,$out,$dir)=("x0","w1","x2","w3");
-+my ($invlo,$invhi,$iptlo,$ipthi,$rcon) = map("v$_.16b",(18..21,8));
-+
-+$code.=<<___;
-+########################################################
-+##                                                    ##
-+##                  AES key schedule                  ##
-+##                                                    ##
-+########################################################
-+.type	_vpaes_key_preheat,%function
-+.align	4
-+_vpaes_key_preheat:
-+	adr	x10, .Lk_inv
-+	movi	v16.16b, #0x5b			// .Lk_s63
-+	adr	x11, .Lk_sb1
-+	movi	v17.16b, #0x0f			// .Lk_s0F
-+	ld1	{v18.2d-v21.2d}, [x10]		// .Lk_inv, .Lk_ipt
-+	adr	x10, .Lk_dksd
-+	ld1	{v22.2d-v23.2d}, [x11]		// .Lk_sb1
-+	adr	x11, .Lk_mc_forward
-+	ld1	{v24.2d-v27.2d}, [x10],#64	// .Lk_dksd, .Lk_dksb
-+	ld1	{v28.2d-v31.2d}, [x10],#64	// .Lk_dkse, .Lk_dks9
-+	ld1	{v8.2d}, [x10]			// .Lk_rcon
-+	ld1	{v9.2d}, [x11]			// .Lk_mc_forward[0]
-+	ret
-+.size	_vpaes_key_preheat,.-_vpaes_key_preheat
-+
-+.type	_vpaes_schedule_core,%function
-+.align	4
-+_vpaes_schedule_core:
-+	stp	x29, x30, [sp,#-16]!
-+	add	x29,sp,#0
-+
-+	bl	_vpaes_key_preheat		// load the tables
-+
-+	ld1	{v0.16b}, [$inp],#16		// vmovdqu	(%rdi),	%xmm0		# load key (unaligned)
-+
-+	// input transform
-+	mov	v3.16b, v0.16b			// vmovdqa	%xmm0,	%xmm3
-+	bl	_vpaes_schedule_transform
-+	mov	v7.16b, v0.16b			// vmovdqa	%xmm0,	%xmm7
-+
-+	adr	x10, .Lk_sr			// lea	.Lk_sr(%rip),%r10
-+	add	x8, x8, x10
-+	cbnz	$dir, .Lschedule_am_decrypting
-+
-+	// encrypting, output zeroth round key after transform
-+	st1	{v0.2d}, [$out]			// vmovdqu	%xmm0,	(%rdx)
-+	b	.Lschedule_go
-+
-+.Lschedule_am_decrypting:
-+	// decrypting, output zeroth round key after shiftrows
-+	ld1	{v1.2d}, [x8]			// vmovdqa	(%r8,%r10),	%xmm1
-+	tbl	v3.16b, {v3.16b}, v1.16b	// vpshufb  %xmm1,	%xmm3,	%xmm3
-+	st1	{v3.2d}, [$out]			// vmovdqu	%xmm3,	(%rdx)
-+	eor	x8, x8, #0x30			// xor	\$0x30, %r8
-+
-+.Lschedule_go:
-+	cmp	$bits, #192			// cmp	\$192,	%esi
-+	b.hi	.Lschedule_256
-+	b.eq	.Lschedule_192
-+	// 128: fall though
-+
-+##
-+##  .schedule_128
-+##
-+##  128-bit specific part of key schedule.
-+##
-+##  This schedule is really simple, because all its parts
-+##  are accomplished by the subroutines.
-+##
-+.Lschedule_128:
-+	mov	$inp, #10			// mov	\$10, %esi
-+
-+.Loop_schedule_128:
-+	sub	$inp, $inp, #1			// dec	%esi
-+	bl 	_vpaes_schedule_round
-+	cbz 	$inp, .Lschedule_mangle_last
-+	bl	_vpaes_schedule_mangle		// write output
-+	b 	.Loop_schedule_128
-+
-+##
-+##  .aes_schedule_192
-+##
-+##  192-bit specific part of key schedule.
-+##
-+##  The main body of this schedule is the same as the 128-bit
-+##  schedule, but with more smearing.  The long, high side is
-+##  stored in %xmm7 as before, and the short, low side is in
-+##  the high bits of %xmm6.
-+##
-+##  This schedule is somewhat nastier, however, because each
-+##  round produces 192 bits of key material, or 1.5 round keys.
-+##  Therefore, on each cycle we do 2 rounds and produce 3 round
-+##  keys.
-+##
-+.align	4
-+.Lschedule_192:
-+	sub	$inp, $inp, #8
-+	ld1	{v0.16b}, [$inp]		// vmovdqu	8(%rdi),%xmm0		# load key part 2 (very unaligned)
-+	bl	_vpaes_schedule_transform	// input transform
-+	mov	v6.16b, v0.16b			// vmovdqa	%xmm0,	%xmm6		# save short part
-+	eor	v4.16b, v4.16b, v4.16b		// vpxor	%xmm4,	%xmm4, %xmm4	# clear 4
-+	ins	v6.d[0], v4.d[0]		// vmovhlps	%xmm4,	%xmm6,	%xmm6		# clobber low side with zeros
-+	mov	$inp, #4			// mov	\$4,	%esi
-+
-+.Loop_schedule_192:
-+	sub	$inp, $inp, #1			// dec	%esi
-+	bl	_vpaes_schedule_round
-+	ext	v0.16b, v6.16b, v0.16b, #8	// vpalignr	\$8,%xmm6,%xmm0,%xmm0
-+	bl	_vpaes_schedule_mangle		// save key n
-+	bl	_vpaes_schedule_192_smear
-+	bl	_vpaes_schedule_mangle		// save key n+1
-+	bl	_vpaes_schedule_round
-+	cbz 	$inp, .Lschedule_mangle_last
-+	bl	_vpaes_schedule_mangle		// save key n+2
-+	bl	_vpaes_schedule_192_smear
-+	b	.Loop_schedule_192
-+
-+##
-+##  .aes_schedule_256
-+##
-+##  256-bit specific part of key schedule.
-+##
-+##  The structure here is very similar to the 128-bit
-+##  schedule, but with an additional "low side" in
-+##  %xmm6.  The low side's rounds are the same as the
-+##  high side's, except no rcon and no rotation.
-+##
-+.align	4
-+.Lschedule_256:
-+	ld1	{v0.16b}, [$inp]		// vmovdqu	16(%rdi),%xmm0		# load key part 2 (unaligned)
-+	bl	_vpaes_schedule_transform	// input transform
-+	mov	$inp, #7			// mov	\$7, %esi
-+	
-+.Loop_schedule_256:
-+	sub	$inp, $inp, #1			// dec	%esi
-+	bl	_vpaes_schedule_mangle		// output low result
-+	mov	v6.16b, v0.16b			// vmovdqa	%xmm0,	%xmm6		# save cur_lo in xmm6
-+
-+	// high round
-+	bl	_vpaes_schedule_round
-+	cbz 	$inp, .Lschedule_mangle_last
-+	bl	_vpaes_schedule_mangle	
-+
-+	// low round. swap xmm7 and xmm6
-+	dup	v0.4s, v0.s[3]			// vpshufd	\$0xFF,	%xmm0,	%xmm0
-+	movi	v4.16b, #0
-+	mov	v5.16b, v7.16b			// vmovdqa	%xmm7,	%xmm5
-+	mov	v7.16b, v6.16b			// vmovdqa	%xmm6,	%xmm7
-+	bl	_vpaes_schedule_low_round
-+	mov	v7.16b, v5.16b			// vmovdqa	%xmm5,	%xmm7
-+	
-+	b	.Loop_schedule_256
-+
-+##
-+##  .aes_schedule_mangle_last
-+##
-+##  Mangler for last round of key schedule
-+##  Mangles %xmm0
-+##    when encrypting, outputs out(%xmm0) ^ 63
-+##    when decrypting, outputs unskew(%xmm0)
-+##
-+##  Always called right before return... jumps to cleanup and exits
-+##
-+.align	4
-+.Lschedule_mangle_last:
-+	// schedule last round key from xmm0
-+	adr	x11, .Lk_deskew			// lea	.Lk_deskew(%rip),%r11	# prepare to deskew
-+	cbnz	$dir, .Lschedule_mangle_last_dec
-+
-+	// encrypting
-+	ld1	{v1.2d}, [x8]			// vmovdqa	(%r8,%r10),%xmm1
-+	adr	x11, .Lk_opt			// lea	.Lk_opt(%rip),	%r11		# prepare to output transform
-+	add	$out, $out, #32			// add	\$32,	%rdx
-+	tbl	v0.16b, {v0.16b}, v1.16b	// vpshufb	%xmm1,	%xmm0,	%xmm0		# output permute
-+
-+.Lschedule_mangle_last_dec:
-+	ld1	{v20.2d-v21.2d}, [x11]		// reload constants
-+	sub	$out, $out, #16			// add	\$-16,	%rdx 
-+	eor	v0.16b, v0.16b, v16.16b		// vpxor	.Lk_s63(%rip),	%xmm0,	%xmm0
-+	bl	_vpaes_schedule_transform	// output transform
-+	st1	{v0.2d}, [$out]			// vmovdqu	%xmm0,	(%rdx)		# save last key
-+
-+	// cleanup
-+	eor	v0.16b, v0.16b, v0.16b		// vpxor	%xmm0,	%xmm0,	%xmm0
-+	eor	v1.16b, v1.16b, v1.16b		// vpxor	%xmm1,	%xmm1,	%xmm1
-+	eor	v2.16b, v2.16b, v2.16b		// vpxor	%xmm2,	%xmm2,	%xmm2
-+	eor	v3.16b, v3.16b, v3.16b		// vpxor	%xmm3,	%xmm3,	%xmm3
-+	eor	v4.16b, v4.16b, v4.16b		// vpxor	%xmm4,	%xmm4,	%xmm4
-+	eor	v5.16b, v5.16b, v5.16b		// vpxor	%xmm5,	%xmm5,	%xmm5
-+	eor	v6.16b, v6.16b, v6.16b		// vpxor	%xmm6,	%xmm6,	%xmm6
-+	eor	v7.16b, v7.16b, v7.16b		// vpxor	%xmm7,	%xmm7,	%xmm7
-+	ldp	x29, x30, [sp],#16
-+	ret
-+.size	_vpaes_schedule_core,.-_vpaes_schedule_core
-+
-+##
-+##  .aes_schedule_192_smear
-+##
-+##  Smear the short, low side in the 192-bit key schedule.
-+##
-+##  Inputs:
-+##    %xmm7: high side, b  a  x  y
-+##    %xmm6:  low side, d  c  0  0
-+##    %xmm13: 0
-+##
-+##  Outputs:
-+##    %xmm6: b+c+d  b+c  0  0
-+##    %xmm0: b+c+d  b+c  b  a
-+##
-+.type	_vpaes_schedule_192_smear,%function
-+.align	4
-+_vpaes_schedule_192_smear:
-+	movi	v1.16b, #0
-+	dup	v0.4s, v7.s[3]
-+	ins	v1.s[3], v6.s[2]	// vpshufd	\$0x80,	%xmm6,	%xmm1	# d c 0 0 -> c 0 0 0
-+	ins	v0.s[0], v7.s[2]	// vpshufd	\$0xFE,	%xmm7,	%xmm0	# b a _ _ -> b b b a
-+	eor	v6.16b, v6.16b, v1.16b	// vpxor	%xmm1,	%xmm6,	%xmm6	# -> c+d c 0 0
-+	eor	v1.16b, v1.16b, v1.16b	// vpxor	%xmm1,	%xmm1,	%xmm1
-+	eor	v6.16b, v6.16b, v0.16b	// vpxor	%xmm0,	%xmm6,	%xmm6	# -> b+c+d b+c b a
-+	mov	v0.16b, v6.16b		// vmovdqa	%xmm6,	%xmm0
-+	ins	v6.d[0], v1.d[0]	// vmovhlps	%xmm1,	%xmm6,	%xmm6	# clobber low side with zeros
-+	ret
-+.size	_vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
-+
-+##
-+##  .aes_schedule_round
-+##
-+##  Runs one main round of the key schedule on %xmm0, %xmm7
-+##
-+##  Specifically, runs subbytes on the high dword of %xmm0
-+##  then rotates it by one byte and xors into the low dword of
-+##  %xmm7.
-+##
-+##  Adds rcon from low byte of %xmm8, then rotates %xmm8 for
-+##  next rcon.
-+##
-+##  Smears the dwords of %xmm7 by xoring the low into the
-+##  second low, result into third, result into highest.
-+##
-+##  Returns results in %xmm7 = %xmm0.
-+##  Clobbers %xmm1-%xmm4, %r11.
-+##
-+.type	_vpaes_schedule_round,%function
-+.align	4
-+_vpaes_schedule_round:
-+	// extract rcon from xmm8
-+	movi	v4.16b, #0			// vpxor	%xmm4,	%xmm4,	%xmm4
-+	ext	v1.16b, $rcon, v4.16b, #15	// vpalignr	\$15,	%xmm8,	%xmm4,	%xmm1
-+	ext	$rcon, $rcon, $rcon, #15	// vpalignr	\$15,	%xmm8,	%xmm8,	%xmm8
-+	eor	v7.16b, v7.16b, v1.16b		// vpxor	%xmm1,	%xmm7,	%xmm7
-+
-+	// rotate
-+	dup	v0.4s, v0.s[3]			// vpshufd	\$0xFF,	%xmm0,	%xmm0
-+	ext	v0.16b, v0.16b, v0.16b, #1	// vpalignr	\$1,	%xmm0,	%xmm0,	%xmm0
-+
-+	// fall through...
-+
-+	// low round: same as high round, but no rotation and no rcon.
-+_vpaes_schedule_low_round:
-+	// smear xmm7
-+	ext	v1.16b, v4.16b, v7.16b, #12	// vpslldq	\$4,	%xmm7,	%xmm1
-+	eor	v7.16b, v7.16b, v1.16b		// vpxor	%xmm1,	%xmm7,	%xmm7
-+	ext	v4.16b, v4.16b, v7.16b, #8	// vpslldq	\$8,	%xmm7,	%xmm4
-+
-+	// subbytes
-+	and	v1.16b, v0.16b, v17.16b		// vpand	%xmm9,	%xmm0,	%xmm1		# 0 = k
-+	ushr	v0.16b, v0.16b, #4		// vpsrlb	\$4,	%xmm0,	%xmm0		# 1 = i
-+	 eor	v7.16b, v7.16b, v4.16b		// vpxor	%xmm4,	%xmm7,	%xmm7
-+	tbl	v2.16b, {$invhi}, v1.16b	// vpshufb	%xmm1,	%xmm11,	%xmm2		# 2 = a/k
-+	eor	v1.16b, v1.16b, v0.16b		// vpxor	%xmm0,	%xmm1,	%xmm1		# 0 = j
-+	tbl	v3.16b, {$invlo}, v0.16b	// vpshufb	%xmm0, 	%xmm10,	%xmm3		# 3 = 1/i
-+	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3		# 3 = iak = 1/i + a/k
-+	tbl	v4.16b, {$invlo}, v1.16b	// vpshufb	%xmm1,	%xmm10,	%xmm4		# 4 = 1/j
-+	 eor	v7.16b, v7.16b, v16.16b		// vpxor	.Lk_s63(%rip),	%xmm7,	%xmm7
-+	tbl	v3.16b, {$invlo}, v3.16b	// vpshufb	%xmm3,	%xmm10,	%xmm3		# 2 = 1/iak
-+	eor	v4.16b, v4.16b, v2.16b		// vpxor	%xmm2,	%xmm4,	%xmm4		# 4 = jak = 1/j + a/k
-+	tbl	v2.16b, {$invlo}, v4.16b	// vpshufb	%xmm4,	%xmm10,	%xmm2		# 3 = 1/jak
-+	eor	v3.16b, v3.16b, v1.16b		// vpxor	%xmm1,	%xmm3,	%xmm3		# 2 = io
-+	eor	v2.16b, v2.16b, v0.16b		// vpxor	%xmm0,	%xmm2,	%xmm2		# 3 = jo
-+	tbl	v4.16b, {v23.16b}, v3.16b	// vpshufb	%xmm3,	%xmm13,	%xmm4		# 4 = sbou
-+	tbl	v1.16b, {v22.16b}, v2.16b	// vpshufb	%xmm2,	%xmm12,	%xmm1		# 0 = sb1t
-+	eor	v1.16b, v1.16b, v4.16b		// vpxor	%xmm4,	%xmm1,	%xmm1		# 0 = sbox output
-+
-+	// add in smeared stuff
-+	eor	v0.16b, v1.16b, v7.16b		// vpxor	%xmm7,	%xmm1,	%xmm0
-+	eor	v7.16b, v1.16b, v7.16b		// vmovdqa	%xmm0,	%xmm7
-+	ret
-+.size	_vpaes_schedule_round,.-_vpaes_schedule_round
-+
-+##
-+##  .aes_schedule_transform
-+##
-+##  Linear-transform %xmm0 according to tables at (%r11)
-+##
-+##  Requires that %xmm9 = 0x0F0F... as in preheat
-+##  Output in %xmm0
-+##  Clobbers %xmm1, %xmm2
-+##
-+.type	_vpaes_schedule_transform,%function
-+.align	4
-+_vpaes_schedule_transform:
-+	and	v1.16b, v0.16b, v17.16b		// vpand	%xmm9,	%xmm0,	%xmm1
-+	ushr	v0.16b, v0.16b, #4		// vpsrlb	\$4,	%xmm0,	%xmm0
-+						// vmovdqa	(%r11),	%xmm2 	# lo
-+	tbl	v2.16b, {$iptlo}, v1.16b	// vpshufb	%xmm1,	%xmm2,	%xmm2
-+						// vmovdqa	16(%r11),	%xmm1 # hi
-+	tbl	v0.16b, {$ipthi}, v0.16b	// vpshufb	%xmm0,	%xmm1,	%xmm0
-+	eor	v0.16b, v0.16b, v2.16b		// vpxor	%xmm2,	%xmm0,	%xmm0
-+	ret
-+.size	_vpaes_schedule_transform,.-_vpaes_schedule_transform
-+
-+##
-+##  .aes_schedule_mangle
-+##
-+##  Mangle xmm0 from (basis-transformed) standard version
-+##  to our version.
-+##
-+##  On encrypt,
-+##    xor with 0x63
-+##    multiply by circulant 0,1,1,1
-+##    apply shiftrows transform
-+##
-+##  On decrypt,
-+##    xor with 0x63
-+##    multiply by "inverse mixcolumns" circulant E,B,D,9
-+##    deskew
-+##    apply shiftrows transform
-+##
-+##
-+##  Writes out to (%rdx), and increments or decrements it
-+##  Keeps track of round number mod 4 in %r8
-+##  Preserves xmm0
-+##  Clobbers xmm1-xmm5
-+##
-+.type	_vpaes_schedule_mangle,%function
-+.align	4
-+_vpaes_schedule_mangle:
-+	mov	v4.16b, v0.16b			// vmovdqa	%xmm0,	%xmm4	# save xmm0 for later
-+						// vmovdqa	.Lk_mc_forward(%rip),%xmm5
-+	cbnz	$dir, .Lschedule_mangle_dec
-+
-+	// encrypting
-+	eor	v4.16b, v0.16b, v16.16b		// vpxor	.Lk_s63(%rip),	%xmm0,	%xmm4
-+	add	$out, $out, #16			// add	\$16,	%rdx
-+	tbl	v4.16b, {v4.16b}, v9.16b	// vpshufb	%xmm5,	%xmm4,	%xmm4
-+	tbl	v1.16b, {v4.16b}, v9.16b	// vpshufb	%xmm5,	%xmm4,	%xmm1
-+	tbl	v3.16b, {v1.16b}, v9.16b	// vpshufb	%xmm5,	%xmm1,	%xmm3
-+	eor	v4.16b, v4.16b, v1.16b		// vpxor	%xmm1,	%xmm4,	%xmm4
-+	ld1	{v1.2d}, [x8]			// vmovdqa	(%r8,%r10),	%xmm1
-+	eor	v3.16b, v3.16b, v4.16b		// vpxor	%xmm4,	%xmm3,	%xmm3
-+
-+	b	.Lschedule_mangle_both
-+.align	4
-+.Lschedule_mangle_dec:
-+	// inverse mix columns
-+						// lea	.Lk_dksd(%rip),%r11
-+	ushr	v1.16b, v4.16b, #4		// vpsrlb	\$4,	%xmm4,	%xmm1	# 1 = hi
-+	and	v4.16b, v4.16b, v17.16b		// vpand	%xmm9,	%xmm4,	%xmm4	# 4 = lo
-+
-+						// vmovdqa	0x00(%r11),	%xmm2
-+	tbl	v2.16b, {v24.16b}, v4.16b	// vpshufb	%xmm4,	%xmm2,	%xmm2
-+						// vmovdqa	0x10(%r11),	%xmm3
-+	tbl	v3.16b,	{v25.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm3
-+	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3
-+	tbl	v3.16b, {v3.16b}, v9.16b	// vpshufb	%xmm5,	%xmm3,	%xmm3
-+
-+						// vmovdqa	0x20(%r11),	%xmm2
-+	tbl	v2.16b, {v26.16b}, v4.16b	// vpshufb	%xmm4,	%xmm2,	%xmm2
-+	eor	v2.16b, v2.16b, v3.16b		// vpxor	%xmm3,	%xmm2,	%xmm2
-+						// vmovdqa	0x30(%r11),	%xmm3
-+	tbl	v3.16b, {v27.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm3
-+	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3
-+	tbl	v3.16b, {v3.16b}, v9.16b	// vpshufb	%xmm5,	%xmm3,	%xmm3
-+
-+						// vmovdqa	0x40(%r11),	%xmm2
-+	tbl	v2.16b, {v28.16b}, v4.16b	// vpshufb	%xmm4,	%xmm2,	%xmm2
-+	eor	v2.16b, v2.16b, v3.16b		// vpxor	%xmm3,	%xmm2,	%xmm2
-+						// vmovdqa	0x50(%r11),	%xmm3
-+	tbl	v3.16b, {v29.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm3
-+	eor	v3.16b, v3.16b, v2.16b		// vpxor	%xmm2,	%xmm3,	%xmm3
-+
-+						// vmovdqa	0x60(%r11),	%xmm2
-+	tbl	v2.16b, {v30.16b}, v4.16b	// vpshufb	%xmm4,	%xmm2,	%xmm2
-+	tbl	v3.16b, {v3.16b}, v9.16b	// vpshufb	%xmm5,	%xmm3,	%xmm3
-+						// vmovdqa	0x70(%r11),	%xmm4
-+	tbl	v4.16b, {v31.16b}, v1.16b	// vpshufb	%xmm1,	%xmm4,	%xmm4
-+	ld1	{v1.2d}, [x8]			// vmovdqa	(%r8,%r10),	%xmm1
-+	eor	v2.16b, v2.16b, v3.16b		// vpxor	%xmm3,	%xmm2,	%xmm2
-+	eor	v3.16b, v4.16b, v2.16b		// vpxor	%xmm2,	%xmm4,	%xmm3
-+
-+	sub	$out, $out, #16			// add	\$-16,	%rdx
-+
-+.Lschedule_mangle_both:
-+	tbl	v3.16b, {v3.16b}, v1.16b	// vpshufb	%xmm1,	%xmm3,	%xmm3
-+	add	x8, x8, #64-16			// add	\$-16,	%r8
-+	and	x8, x8, #~(1<<6)		// and	\$0x30,	%r8
-+	st1	{v3.2d}, [$out]			// vmovdqu	%xmm3,	(%rdx)
-+	ret
-+.size	_vpaes_schedule_mangle,.-_vpaes_schedule_mangle
-+
-+.globl	vpaes_set_encrypt_key
-+.type	vpaes_set_encrypt_key,%function
-+.align	4
-+vpaes_set_encrypt_key:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+	stp	d8,d9,[sp,#-16]!	// ABI spec says so
-+
-+	lsr	w9, $bits, #5		// shr	\$5,%eax
-+	add	w9, w9, #5		// \$5,%eax
-+	str	w9, [$out,#240]		// mov	%eax,240(%rdx)	# AES_KEY->rounds = nbits/32+5;
-+
-+	mov	$dir, #0		// mov	\$0,%ecx
-+	mov	x8, #0x30		// mov	\$0x30,%r8d
-+	bl	_vpaes_schedule_core
-+	eor	x0, x0, x0
-+
-+	ldp	d8,d9,[sp],#16
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	vpaes_set_encrypt_key,.-vpaes_set_encrypt_key
-+
-+.globl	vpaes_set_decrypt_key
-+.type	vpaes_set_decrypt_key,%function
-+.align	4
-+vpaes_set_decrypt_key:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+	stp	d8,d9,[sp,#-16]!	// ABI spec says so
-+
-+	lsr	w9, $bits, #5		// shr	\$5,%eax
-+	add	w9, w9, #5		// \$5,%eax
-+	str	w9, [$out,#240]		// mov	%eax,240(%rdx)	# AES_KEY->rounds = nbits/32+5;
-+	lsl	w9, w9, #4		// shl	\$4,%eax
-+	add	$out, $out, #16		// lea	16(%rdx,%rax),%rdx
-+	add	$out, $out, x9
-+
-+	mov	$dir, #1		// mov	\$1,%ecx
-+	lsr	w8, $bits, #1		// shr	\$1,%r8d
-+	and	x8, x8, #32		// and	\$32,%r8d
-+	eor	x8, x8, #32		// xor	\$32,%r8d	# nbits==192?0:32
-+	bl	_vpaes_schedule_core
-+
-+	ldp	d8,d9,[sp],#16
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	vpaes_set_decrypt_key,.-vpaes_set_decrypt_key
-+___
-+}
-+{
-+my ($inp,$out,$len,$key,$ivec,$dir) = map("x$_",(0..5));
-+
-+$code.=<<___;
-+.globl	vpaes_cbc_encrypt
-+.type	vpaes_cbc_encrypt,%function
-+.align	4
-+vpaes_cbc_encrypt:
-+	cbz	$len, .Lcbc_abort
-+	cmp	w5, #0			// check direction
-+	b.eq	vpaes_cbc_decrypt
-+
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	mov	x17, $len		// reassign
-+	mov	x2,  $key		// reassign
-+
-+	ld1	{v0.16b}, [$ivec]	// load ivec
-+	bl	_vpaes_encrypt_preheat
-+	b	.Lcbc_enc_loop
-+
-+.align	4
-+.Lcbc_enc_loop:
-+	ld1	{v7.16b}, [$inp],#16	// load input
-+	eor	v7.16b, v7.16b, v0.16b	// xor with ivec
-+	bl	_vpaes_encrypt_core
-+	st1	{v0.16b}, [$out],#16	// save output
-+	subs	x17, x17, #16
-+	b.hi	.Lcbc_enc_loop
-+
-+	st1	{v0.16b}, [$ivec]	// write ivec
-+
-+	ldp	x29,x30,[sp],#16
-+.Lcbc_abort:
-+	ret
-+.size	vpaes_cbc_encrypt,.-vpaes_cbc_encrypt
-+
-+.type	vpaes_cbc_decrypt,%function
-+.align	4
-+vpaes_cbc_decrypt:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+	stp	d8,d9,[sp,#-16]!	// ABI spec says so
-+	stp	d10,d11,[sp,#-16]!
-+	stp	d12,d13,[sp,#-16]!
-+	stp	d14,d15,[sp,#-16]!
-+
-+	mov	x17, $len		// reassign
-+	mov	x2,  $key		// reassign
-+	ld1	{v6.16b}, [$ivec]	// load ivec
-+	bl	_vpaes_decrypt_preheat
-+	tst	x17, #16
-+	b.eq	.Lcbc_dec_loop2x
-+
-+	ld1	{v7.16b}, [$inp], #16	// load input
-+	bl	_vpaes_decrypt_core
-+	eor	v0.16b, v0.16b, v6.16b	// xor with ivec
-+	orr	v6.16b, v7.16b, v7.16b	// next ivec value
-+	st1	{v0.16b}, [$out], #16
-+	subs	x17, x17, #16
-+	b.ls	.Lcbc_dec_done
-+
-+.align	4
-+.Lcbc_dec_loop2x:
-+	ld1	{v14.16b,v15.16b}, [$inp], #32
-+	bl	_vpaes_decrypt_2x
-+	eor	v0.16b, v0.16b, v6.16b	// xor with ivec
-+	eor	v1.16b, v1.16b, v14.16b
-+	orr	v6.16b, v15.16b, v15.16b
-+	st1	{v0.16b,v1.16b}, [$out], #32
-+	subs	x17, x17, #32
-+	b.hi	.Lcbc_dec_loop2x
-+
-+.Lcbc_dec_done:
-+	st1	{v6.16b}, [$ivec]
-+
-+	ldp	d14,d15,[sp],#16
-+	ldp	d12,d13,[sp],#16
-+	ldp	d10,d11,[sp],#16
-+	ldp	d8,d9,[sp],#16
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	vpaes_cbc_decrypt,.-vpaes_cbc_decrypt
-+___
-+if (1) {
-+$code.=<<___;
-+.globl	vpaes_ecb_encrypt
-+.type	vpaes_ecb_encrypt,%function
-+.align	4
-+vpaes_ecb_encrypt:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+	stp	d8,d9,[sp,#-16]!	// ABI spec says so
-+	stp	d10,d11,[sp,#-16]!
-+	stp	d12,d13,[sp,#-16]!
-+	stp	d14,d15,[sp,#-16]!
-+
-+	mov	x17, $len
-+	mov	x2,  $key
-+	bl	_vpaes_encrypt_preheat
-+	tst	x17, #16
-+	b.eq	.Lecb_enc_loop
-+
-+	ld1	{v7.16b}, [$inp],#16
-+	bl	_vpaes_encrypt_core
-+	st1	{v0.16b}, [$out],#16
-+	subs	x17, x17, #16
-+	b.ls	.Lecb_enc_done
-+
-+.align	4
-+.Lecb_enc_loop:
-+	ld1	{v14.16b,v15.16b}, [$inp], #32
-+	bl	_vpaes_encrypt_2x
-+	st1	{v0.16b,v1.16b}, [$out], #32
-+	subs	x17, x17, #32
-+	b.hi	.Lecb_enc_loop
-+
-+.Lecb_enc_done:
-+	ldp	d14,d15,[sp],#16
-+	ldp	d12,d13,[sp],#16
-+	ldp	d10,d11,[sp],#16
-+	ldp	d8,d9,[sp],#16
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	vpaes_ecb_encrypt,.-vpaes_ecb_encrypt
-+
-+.globl	vpaes_ecb_decrypt
-+.type	vpaes_ecb_decrypt,%function
-+.align	4
-+vpaes_ecb_decrypt:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+	stp	d8,d9,[sp,#-16]!	// ABI spec says so
-+	stp	d10,d11,[sp,#-16]!
-+	stp	d12,d13,[sp,#-16]!
-+	stp	d14,d15,[sp,#-16]!
-+
-+	mov	x17, $len
-+	mov	x2,  $key
-+	bl	_vpaes_decrypt_preheat
-+	tst	x17, #16
-+	b.eq	.Lecb_dec_loop
-+
-+	ld1	{v7.16b}, [$inp],#16
-+	bl	_vpaes_encrypt_core
-+	st1	{v0.16b}, [$out],#16
-+	subs	x17, x17, #16
-+	b.ls	.Lecb_dec_done
-+
-+.align	4
-+.Lecb_dec_loop:
-+	ld1	{v14.16b,v15.16b}, [$inp], #32
-+	bl	_vpaes_decrypt_2x
-+	st1	{v0.16b,v1.16b}, [$out], #32
-+	subs	x17, x17, #32
-+	b.hi	.Lecb_dec_loop
-+
-+.Lecb_dec_done:
-+	ldp	d14,d15,[sp],#16
-+	ldp	d12,d13,[sp],#16
-+	ldp	d10,d11,[sp],#16
-+	ldp	d8,d9,[sp],#16
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	vpaes_ecb_decrypt,.-vpaes_ecb_decrypt
-+___
-+}	}
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-ppc.pl
-new file mode 100644
-index 0000000..bb38fbe
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-ppc.pl
-@@ -0,0 +1,1594 @@
-+#! /usr/bin/env perl
-+# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+######################################################################
-+## Constant-time SSSE3 AES core implementation.
-+## version 0.1
-+##
-+## By Mike Hamburg (Stanford University), 2009
-+## Public domain.
-+##
-+## For details see http://shiftleft.org/papers/vector_aes/ and
-+## http://crypto.stanford.edu/vpaes/.
-+
-+# CBC encrypt/decrypt performance in cycles per byte processed with
-+# 128-bit key.
-+#
-+#		aes-ppc.pl		this
-+# PPC74x0/G4e	35.5/52.1/(23.8)	11.9(*)/15.4
-+# PPC970/G5	37.9/55.0/(28.5)	22.2/28.5
-+# POWER6	42.7/54.3/(28.2)	63.0/92.8(**)
-+# POWER7	32.3/42.9/(18.4)	18.5/23.3
-+#
-+# (*)	This is ~10% worse than reported in paper. The reason is
-+#	twofold. This module doesn't make any assumption about
-+#	key schedule (or data for that matter) alignment and handles
-+#	it in-line. Secondly it, being transliterated from
-+#	vpaes-x86_64.pl, relies on "nested inversion" better suited
-+#	for Intel CPUs.
-+# (**)	Inadequate POWER6 performance is due to astronomic AltiVec
-+#	latency, 9 cycles per simple logical operation.
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /64/) {
-+	$SIZE_T	=8;
-+	$LRSAVE	=2*$SIZE_T;
-+	$STU	="stdu";
-+	$POP	="ld";
-+	$PUSH	="std";
-+	$UCMP	="cmpld";
-+} elsif ($flavour =~ /32/) {
-+	$SIZE_T	=4;
-+	$LRSAVE	=$SIZE_T;
-+	$STU	="stwu";
-+	$POP	="lwz";
-+	$PUSH	="stw";
-+	$UCMP	="cmplw";
-+} else { die "nonsense $flavour"; }
-+
-+$sp="r1";
-+$FRAME=6*$SIZE_T+13*16;	# 13*16 is for v20-v31 offload
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-+
-+$code.=<<___;
-+.machine	"any"
-+
-+.text
-+
-+.align	7	# totally strategic alignment
-+_vpaes_consts:
-+Lk_mc_forward:	# mc_forward
-+	.long	0x01020300, 0x05060704, 0x090a0b08, 0x0d0e0f0c	?inv
-+	.long	0x05060704, 0x090a0b08, 0x0d0e0f0c, 0x01020300	?inv
-+	.long	0x090a0b08, 0x0d0e0f0c, 0x01020300, 0x05060704	?inv
-+	.long	0x0d0e0f0c, 0x01020300, 0x05060704, 0x090a0b08	?inv
-+Lk_mc_backward:	# mc_backward
-+	.long	0x03000102, 0x07040506, 0x0b08090a, 0x0f0c0d0e	?inv
-+	.long	0x0f0c0d0e, 0x03000102, 0x07040506, 0x0b08090a	?inv
-+	.long	0x0b08090a, 0x0f0c0d0e, 0x03000102, 0x07040506	?inv
-+	.long	0x07040506, 0x0b08090a, 0x0f0c0d0e, 0x03000102	?inv
-+Lk_sr:		# sr
-+	.long	0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f	?inv
-+	.long	0x00050a0f, 0x04090e03, 0x080d0207, 0x0c01060b	?inv
-+	.long	0x0009020b, 0x040d060f, 0x08010a03, 0x0c050e07	?inv
-+	.long	0x000d0a07, 0x04010e0b, 0x0805020f, 0x0c090603	?inv
-+
-+##
-+## "Hot" constants
-+##
-+Lk_inv:		# inv, inva
-+	.long	0xf001080d, 0x0f06050e, 0x020c0b0a, 0x09030704	?rev
-+	.long	0xf0070b0f, 0x060a0401, 0x09080502, 0x0c0e0d03	?rev
-+Lk_ipt:		# input transform (lo, hi)
-+	.long	0x00702a5a, 0x98e8b2c2, 0x08782252, 0x90e0baca	?rev
-+	.long	0x004d7c31, 0x7d30014c, 0x81ccfdb0, 0xfcb180cd	?rev
-+Lk_sbo:		# sbou, sbot
-+	.long	0x00c7bd6f, 0x176dd2d0, 0x78a802c5, 0x7abfaa15	?rev
-+	.long	0x006abb5f, 0xa574e4cf, 0xfa352b41, 0xd1901e8e	?rev
-+Lk_sb1:		# sb1u, sb1t
-+	.long	0x0023e2fa, 0x15d41836, 0xefd92e0d, 0xc1ccf73b	?rev
-+	.long	0x003e50cb, 0x8fe19bb1, 0x44f52a14, 0x6e7adfa5	?rev
-+Lk_sb2:		# sb2u, sb2t
-+	.long	0x0029e10a, 0x4088eb69, 0x4a2382ab, 0xc863a1c2	?rev
-+	.long	0x0024710b, 0xc6937ae2, 0xcd2f98bc, 0x55e9b75e	?rev
-+
-+##
-+##  Decryption stuff
-+##
-+Lk_dipt:	# decryption input transform
-+	.long	0x005f540b, 0x045b500f, 0x1a454e11, 0x1e414a15	?rev
-+	.long	0x00650560, 0xe683e386, 0x94f191f4, 0x72177712	?rev
-+Lk_dsbo:	# decryption sbox final output
-+	.long	0x0040f97e, 0x53ea8713, 0x2d3e94d4, 0xb96daac7	?rev
-+	.long	0x001d4493, 0x0f56d712, 0x9c8ec5d8, 0x59814bca	?rev
-+Lk_dsb9:	# decryption sbox output *9*u, *9*t
-+	.long	0x00d6869a, 0x53031c85, 0xc94c994f, 0x501fd5ca	?rev
-+	.long	0x0049d7ec, 0x89173bc0, 0x65a5fbb2, 0x9e2c5e72	?rev
-+Lk_dsbd:	# decryption sbox output *D*u, *D*t
-+	.long	0x00a2b1e6, 0xdfcc577d, 0x39442a88, 0x139b6ef5	?rev
-+	.long	0x00cbc624, 0xf7fae23c, 0xd3efde15, 0x0d183129	?rev
-+Lk_dsbb:	# decryption sbox output *B*u, *B*t
-+	.long	0x0042b496, 0x926422d0, 0x04d4f2b0, 0xf6462660	?rev
-+	.long	0x006759cd, 0xa69894c1, 0x6baa5532, 0x3e0cfff3	?rev
-+Lk_dsbe:	# decryption sbox output *E*u, *E*t
-+	.long	0x00d0d426, 0x9692f246, 0xb0f6b464, 0x04604222	?rev
-+	.long	0x00c1aaff, 0xcda6550c, 0x323e5998, 0x6bf36794	?rev
-+
-+##
-+##  Key schedule constants
-+##
-+Lk_dksd:	# decryption key schedule: invskew x*D
-+	.long	0x0047e4a3, 0x5d1ab9fe, 0xf9be1d5a, 0xa4e34007	?rev
-+	.long	0x008336b5, 0xf477c241, 0x1e9d28ab, 0xea69dc5f	?rev
-+Lk_dksb:	# decryption key schedule: invskew x*B
-+	.long	0x00d55085, 0x1fca4f9a, 0x994cc91c, 0x8653d603	?rev
-+	.long	0x004afcb6, 0xa7ed5b11, 0xc882347e, 0x6f2593d9	?rev
-+Lk_dkse:	# decryption key schedule: invskew x*E + 0x63
-+	.long	0x00d6c91f, 0xca1c03d5, 0x86504f99, 0x4c9a8553	?rev
-+	.long	0xe87bdc4f, 0x059631a2, 0x8714b320, 0x6af95ecd	?rev
-+Lk_dks9:	# decryption key schedule: invskew x*9
-+	.long	0x00a7d97e, 0xc86f11b6, 0xfc5b2582, 0x3493ed4a	?rev
-+	.long	0x00331427, 0x62517645, 0xcefddae9, 0xac9fb88b	?rev
-+
-+Lk_rcon:	# rcon
-+	.long	0xb6ee9daf, 0xb991831f, 0x817d7c4d, 0x08982a70	?asis
-+Lk_s63:
-+	.long	0x5b5b5b5b, 0x5b5b5b5b, 0x5b5b5b5b, 0x5b5b5b5b	?asis
-+
-+Lk_opt:		# output transform
-+	.long	0x0060b6d6, 0x29499fff, 0x0868bede, 0x214197f7	?rev
-+	.long	0x00ecbc50, 0x51bded01, 0xe00c5cb0, 0xb15d0de1	?rev
-+Lk_deskew:	# deskew tables: inverts the sbox's "skew"
-+	.long	0x00e3a447, 0x40a3e407, 0x1af9be5d, 0x5ab9fe1d	?rev
-+	.long	0x0069ea83, 0xdcb5365f, 0x771e9df4, 0xabc24128	?rev
-+.align	5
-+Lconsts:
-+	mflr	r0
-+	bcl	20,31,\$+4
-+	mflr	r12	#vvvvv "distance between . and _vpaes_consts
-+	addi	r12,r12,-0x308
-+	mtlr	r0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+.asciz  "Vector Permutation AES for AltiVec, Mike Hamburg (Stanford University)"
-+.align	6
-+___
-+
-+my ($inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm) = map("v$_",(26..31));
-+{
-+my ($inp,$out,$key) = map("r$_",(3..5));
-+
-+my ($invlo,$invhi,$iptlo,$ipthi,$sbou,$sbot) = map("v$_",(10..15));
-+my ($sb1u,$sb1t,$sb2u,$sb2t) = map("v$_",(16..19));
-+my ($sb9u,$sb9t,$sbdu,$sbdt,$sbbu,$sbbt,$sbeu,$sbet)=map("v$_",(16..23));
-+
-+$code.=<<___;
-+##
-+##  _aes_preheat
-+##
-+##  Fills register %r10 -> .aes_consts (so you can -fPIC)
-+##  and %xmm9-%xmm15 as specified below.
-+##
-+.align	4
-+_vpaes_encrypt_preheat:
-+	mflr	r8
-+	bl	Lconsts
-+	mtlr	r8
-+	li	r11, 0xc0		# Lk_inv
-+	li	r10, 0xd0
-+	li	r9,  0xe0		# Lk_ipt
-+	li	r8,  0xf0
-+	vxor	v7, v7, v7		# 0x00..00
-+	vspltisb	v8,4		# 0x04..04
-+	vspltisb	v9,0x0f		# 0x0f..0f
-+	lvx	$invlo, r12, r11
-+	li	r11, 0x100
-+	lvx	$invhi, r12, r10
-+	li	r10, 0x110
-+	lvx	$iptlo, r12, r9
-+	li	r9,  0x120
-+	lvx	$ipthi, r12, r8
-+	li	r8,  0x130
-+	lvx	$sbou, r12, r11
-+	li	r11, 0x140
-+	lvx	$sbot, r12, r10
-+	li	r10, 0x150
-+	lvx	$sb1u, r12, r9
-+	lvx	$sb1t, r12, r8
-+	lvx	$sb2u, r12, r11
-+	lvx	$sb2t, r12, r10
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+##
-+##  _aes_encrypt_core
-+##
-+##  AES-encrypt %xmm0.
-+##
-+##  Inputs:
-+##     %xmm0 = input
-+##     %xmm9-%xmm15 as in _vpaes_preheat
-+##    (%rdx) = scheduled keys
-+##
-+##  Output in %xmm0
-+##  Clobbers  %xmm1-%xmm6, %r9, %r10, %r11, %rax
-+##
-+##
-+.align 5
-+_vpaes_encrypt_core:
-+	lwz	r8, 240($key)		# pull rounds
-+	li	r9, 16
-+	lvx	v5, 0, $key		# vmovdqu	(%r9),	%xmm5		# round0 key
-+	li	r11, 0x10
-+	lvx	v6, r9, $key
-+	addi	r9, r9, 16
-+	?vperm	v5, v5, v6, $keyperm	# align round key
-+	addi	r10, r11, 0x40
-+	vsrb	v1, v0, v8		# vpsrlb	\$4,	%xmm0,	%xmm0
-+	vperm	v0, $iptlo, $iptlo, v0	# vpshufb	%xmm1,	%xmm2,	%xmm1
-+	vperm	v1, $ipthi, $ipthi, v1	# vpshufb	%xmm0,	%xmm3,	%xmm2
-+	vxor	v0, v0, v5		# vpxor	%xmm5,	%xmm1,	%xmm0
-+	vxor	v0, v0, v1		# vpxor	%xmm2,	%xmm0,	%xmm0
-+	mtctr	r8
-+	b	Lenc_entry
-+
-+.align 4
-+Lenc_loop:
-+	# middle of middle round
-+	vperm	v4, $sb1t, v7, v2	# vpshufb	%xmm2,	%xmm13,	%xmm4	# 4 = sb1u
-+	lvx	v1, r12, r11		# vmovdqa	-0x40(%r11,%r10), %xmm1	# .Lk_mc_forward[]
-+	addi	r11, r11, 16
-+	vperm	v0, $sb1u, v7, v3	# vpshufb	%xmm3,	%xmm12,	%xmm0	# 0 = sb1t
-+	vxor	v4, v4, v5		# vpxor		%xmm5,	%xmm4,	%xmm4	# 4 = sb1u + k
-+	andi.	r11, r11, 0x30		# and		\$0x30, %r11	# ... mod 4
-+	vperm	v5, $sb2t, v7, v2	# vpshufb	%xmm2,	%xmm15,	%xmm5	# 4 = sb2u
-+	vxor	v0, v0, v4		# vpxor		%xmm4,	%xmm0,	%xmm0	# 0 = A
-+	vperm	v2, $sb2u, v7, v3	# vpshufb	%xmm3,	%xmm14,	%xmm2	# 2 = sb2t
-+	lvx	v4, r12, r10		# vmovdqa	(%r11,%r10), %xmm4	# .Lk_mc_backward[]
-+	addi	r10, r11, 0x40
-+	vperm	v3, v0, v7, v1		# vpshufb	%xmm1,	%xmm0,	%xmm3	# 0 = B
-+	vxor	v2, v2, v5		# vpxor		%xmm5,	%xmm2,	%xmm2	# 2 = 2A
-+	vperm	v0, v0, v7, v4		# vpshufb	%xmm4,	%xmm0,	%xmm0	# 3 = D
-+	vxor	v3, v3, v2		# vpxor		%xmm2,	%xmm3,	%xmm3	# 0 = 2A+B
-+	vperm	v4, v3, v7, v1		# vpshufb	%xmm1,	%xmm3,	%xmm4	# 0 = 2B+C
-+	vxor	v0, v0, v3		# vpxor		%xmm3,	%xmm0,	%xmm0	# 3 = 2A+B+D
-+	vxor	v0, v0, v4		# vpxor		%xmm4,	%xmm0, %xmm0	# 0 = 2A+3B+C+D
-+
-+Lenc_entry:
-+	# top of round
-+	vsrb	v1, v0, v8		# vpsrlb	\$4,	%xmm0,	%xmm0	# 1 = i
-+	vperm	v5, $invhi, $invhi, v0	# vpshufb	%xmm1,	%xmm11,	%xmm5	# 2 = a/k
-+	vxor	v0, v0, v1		# vpxor		%xmm0,	%xmm1,	%xmm1	# 0 = j
-+	vperm	v3, $invlo, $invlo, v1	# vpshufb	%xmm0, 	%xmm10,	%xmm3  	# 3 = 1/i
-+	vperm	v4, $invlo, $invlo, v0	# vpshufb	%xmm1, 	%xmm10,	%xmm4  	# 4 = 1/j
-+	vand	v0, v0, v9
-+	vxor	v3, v3, v5		# vpxor		%xmm5,	%xmm3,	%xmm3	# 3 = iak = 1/i + a/k
-+	vxor	v4, v4, v5		# vpxor		%xmm5,	%xmm4,	%xmm4  	# 4 = jak = 1/j + a/k
-+	vperm	v2, $invlo, v7, v3	# vpshufb	%xmm3,	%xmm10,	%xmm2  	# 2 = 1/iak
-+	vmr	v5, v6
-+	lvx	v6, r9, $key		# vmovdqu	(%r9), %xmm5
-+	vperm	v3, $invlo, v7, v4	# vpshufb	%xmm4,	%xmm10,	%xmm3	# 3 = 1/jak
-+	addi	r9, r9, 16
-+	vxor	v2, v2, v0		# vpxor		%xmm1,	%xmm2,	%xmm2  	# 2 = io
-+	?vperm	v5, v5, v6, $keyperm	# align round key
-+	vxor	v3, v3, v1		# vpxor		%xmm0,	%xmm3,	%xmm3	# 3 = jo
-+	bdnz	Lenc_loop
-+
-+	# middle of last round
-+	addi	r10, r11, 0x80
-+					# vmovdqa	-0x60(%r10), %xmm4	# 3 : sbou	.Lk_sbo
-+					# vmovdqa	-0x50(%r10), %xmm0	# 0 : sbot	.Lk_sbo+16
-+	vperm	v4, $sbou, v7, v2	# vpshufb	%xmm2,	%xmm4,	%xmm4	# 4 = sbou
-+	lvx	v1, r12, r10		# vmovdqa	0x40(%r11,%r10), %xmm1	# .Lk_sr[]
-+	vperm	v0, $sbot, v7, v3	# vpshufb	%xmm3,	%xmm0,	%xmm0	# 0 = sb1t
-+	vxor	v4, v4, v5		# vpxor		%xmm5,	%xmm4,	%xmm4	# 4 = sb1u + k
-+	vxor	v0, v0, v4		# vpxor		%xmm4,	%xmm0,	%xmm0	# 0 = A
-+	vperm	v0, v0, v7, v1		# vpshufb	%xmm1,	%xmm0,	%xmm0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+.globl	.vpaes_encrypt
-+.align	5
-+.vpaes_encrypt:
-+	$STU	$sp,-$FRAME($sp)
-+	li	r10,`15+6*$SIZE_T`
-+	li	r11,`31+6*$SIZE_T`
-+	mflr	r6
-+	mfspr	r7, 256			# save vrsave
-+	stvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v30,r10,$sp
-+	stvx	v31,r11,$sp
-+	stw	r7,`$FRAME-4`($sp)	# save vrsave
-+	li	r0, -1
-+	$PUSH	r6,`$FRAME+$LRSAVE`($sp)
-+	mtspr	256, r0			# preserve all AltiVec registers
-+
-+	bl	_vpaes_encrypt_preheat
-+
-+	?lvsl	$inpperm, 0, $inp	# prepare for unaligned access
-+	lvx	v0, 0, $inp
-+	addi	$inp, $inp, 15		# 15 is not a typo
-+	 ?lvsr	$outperm, 0, $out
-+	?lvsl	$keyperm, 0, $key	# prepare for unaligned access
-+	lvx	$inptail, 0, $inp	# redundant in aligned case
-+	?vperm	v0, v0, $inptail, $inpperm
-+
-+	bl	_vpaes_encrypt_core
-+
-+	andi.	r8, $out, 15
-+	li	r9, 16
-+	beq	Lenc_out_aligned
-+
-+	vperm	v0, v0, v0, $outperm	# rotate right/left
-+	mtctr	r9
-+Lenc_out_unaligned:
-+	stvebx	v0, 0, $out
-+	addi	$out, $out, 1
-+	bdnz	Lenc_out_unaligned
-+	b	Lenc_done
-+
-+.align	4
-+Lenc_out_aligned:
-+	stvx	v0, 0, $out
-+Lenc_done:
-+
-+	li	r10,`15+6*$SIZE_T`
-+	li	r11,`31+6*$SIZE_T`
-+	mtlr	r6
-+	mtspr	256, r7			# restore vrsave
-+	lvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v30,r10,$sp
-+	lvx	v31,r11,$sp
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,0x04,1,0x80,0,3,0
-+	.long	0
-+.size	.vpaes_encrypt,.-.vpaes_encrypt
-+
-+.align	4
-+_vpaes_decrypt_preheat:
-+	mflr	r8
-+	bl	Lconsts
-+	mtlr	r8
-+	li	r11, 0xc0		# Lk_inv
-+	li	r10, 0xd0
-+	li	r9,  0x160		# Ldipt
-+	li	r8,  0x170
-+	vxor	v7, v7, v7		# 0x00..00
-+	vspltisb	v8,4		# 0x04..04
-+	vspltisb	v9,0x0f		# 0x0f..0f
-+	lvx	$invlo, r12, r11
-+	li	r11, 0x180
-+	lvx	$invhi, r12, r10
-+	li	r10, 0x190
-+	lvx	$iptlo, r12, r9
-+	li	r9,  0x1a0
-+	lvx	$ipthi, r12, r8
-+	li	r8,  0x1b0
-+	lvx	$sbou, r12, r11
-+	li	r11, 0x1c0
-+	lvx	$sbot, r12, r10
-+	li	r10, 0x1d0
-+	lvx	$sb9u, r12, r9
-+	li	r9,  0x1e0
-+	lvx	$sb9t, r12, r8
-+	li	r8,  0x1f0
-+	lvx	$sbdu, r12, r11
-+	li	r11, 0x200
-+	lvx	$sbdt, r12, r10
-+	li	r10, 0x210
-+	lvx	$sbbu, r12, r9
-+	lvx	$sbbt, r12, r8
-+	lvx	$sbeu, r12, r11
-+	lvx	$sbet, r12, r10
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+##
-+##  Decryption core
-+##
-+##  Same API as encryption core.
-+##
-+.align	4
-+_vpaes_decrypt_core:
-+	lwz	r8, 240($key)		# pull rounds
-+	li	r9, 16
-+	lvx	v5, 0, $key		# vmovdqu	(%r9),	%xmm4		# round0 key
-+	li	r11, 0x30
-+	lvx	v6, r9, $key
-+	addi	r9, r9, 16
-+	?vperm	v5, v5, v6, $keyperm	# align round key
-+	vsrb	v1, v0, v8		# vpsrlb	\$4,	%xmm0,	%xmm0
-+	vperm	v0, $iptlo, $iptlo, v0	# vpshufb	%xmm1,	%xmm2,	%xmm2
-+	vperm	v1, $ipthi, $ipthi, v1	# vpshufb	%xmm0,	%xmm1,	%xmm0
-+	vxor	v0, v0, v5		# vpxor	%xmm4,	%xmm2,	%xmm2
-+	vxor	v0, v0, v1		# vpxor	%xmm2,	%xmm0,	%xmm0
-+	mtctr	r8
-+	b	Ldec_entry
-+
-+.align 4
-+Ldec_loop:
-+#
-+#  Inverse mix columns
-+#
-+	lvx	v0, r12, r11		# v5 and v0 are flipped
-+					# vmovdqa	-0x20(%r10),%xmm4		# 4 : sb9u
-+					# vmovdqa	-0x10(%r10),%xmm1		# 0 : sb9t
-+	vperm	v4, $sb9u, v7, v2	# vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sb9u
-+	subi	r11, r11, 16
-+	vperm	v1, $sb9t, v7, v3	# vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sb9t
-+	andi.	r11, r11, 0x30
-+	vxor	v5, v5, v4		# vpxor		%xmm4,	%xmm0,	%xmm0
-+					# vmovdqa	0x00(%r10),%xmm4		# 4 : sbdu
-+	vxor	v5, v5, v1		# vpxor		%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+					# vmovdqa	0x10(%r10),%xmm1		# 0 : sbdt
-+
-+	vperm	v4, $sbdu, v7, v2	# vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbdu
-+	vperm 	v5, v5, v7, v0		# vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
-+	vperm	v1, $sbdt, v7, v3	# vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbdt
-+	vxor	v5, v5, v4		# vpxor		%xmm4,	%xmm0,	%xmm0		# 4 = ch
-+					# vmovdqa	0x20(%r10),	%xmm4		# 4 : sbbu
-+	vxor	v5, v5, v1		# vpxor		%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+					# vmovdqa	0x30(%r10),	%xmm1		# 0 : sbbt
-+
-+	vperm	v4, $sbbu, v7, v2	# vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbbu
-+	vperm	v5, v5, v7, v0		# vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
-+	vperm	v1, $sbbt, v7, v3	# vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbbt
-+	vxor	v5, v5, v4		# vpxor		%xmm4,	%xmm0,	%xmm0		# 4 = ch
-+					# vmovdqa	0x40(%r10),	%xmm4		# 4 : sbeu
-+	vxor	v5, v5, v1		# vpxor		%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+					# vmovdqa	0x50(%r10),	%xmm1		# 0 : sbet
-+
-+	vperm	v4, $sbeu, v7, v2	# vpshufb	%xmm2,	%xmm4,	%xmm4		# 4 = sbeu
-+	vperm	v5, v5, v7, v0		# vpshufb	%xmm5,	%xmm0,	%xmm0		# MC ch
-+	vperm	v1, $sbet, v7, v3	# vpshufb	%xmm3,	%xmm1,	%xmm1		# 0 = sbet
-+	vxor	v0, v5, v4		# vpxor		%xmm4,	%xmm0,	%xmm0		# 4 = ch
-+	vxor	v0, v0, v1		# vpxor		%xmm1,	%xmm0,	%xmm0		# 0 = ch
-+
-+Ldec_entry:
-+	# top of round
-+	vsrb	v1, v0, v8		# vpsrlb	\$4,	%xmm0,	%xmm0	# 1 = i
-+	vperm	v2, $invhi, $invhi, v0	# vpshufb	%xmm1,	%xmm11,	%xmm2	# 2 = a/k
-+	vxor	v0, v0, v1		# vpxor		%xmm0,	%xmm1,	%xmm1	# 0 = j
-+	vperm	v3, $invlo, $invlo, v1	# vpshufb	%xmm0, 	%xmm10,	%xmm3	# 3 = 1/i
-+	vperm	v4, $invlo, $invlo, v0	# vpshufb	%xmm1,	%xmm10,	%xmm4	# 4 = 1/j
-+	vand	v0, v0, v9
-+	vxor	v3, v3, v2		# vpxor		%xmm2,	%xmm3,	%xmm3	# 3 = iak = 1/i + a/k
-+	vxor	v4, v4, v2		# vpxor		%xmm2, 	%xmm4,	%xmm4	# 4 = jak = 1/j + a/k
-+	vperm	v2, $invlo, v7, v3	# vpshufb	%xmm3,	%xmm10,	%xmm2	# 2 = 1/iak
-+	vmr	v5, v6
-+	lvx	v6, r9, $key		# vmovdqu	(%r9),	%xmm0
-+	vperm	v3, $invlo, v7, v4	# vpshufb	%xmm4,  %xmm10,	%xmm3	# 3 = 1/jak
-+	addi	r9, r9, 16
-+	vxor	v2, v2, v0		# vpxor		%xmm1,	%xmm2,	%xmm2	# 2 = io
-+	?vperm	v5, v5, v6, $keyperm	# align round key
-+	vxor	v3, v3, v1		# vpxor		%xmm0,  %xmm3,	%xmm3	# 3 = jo
-+	bdnz	Ldec_loop
-+
-+	# middle of last round
-+	addi	r10, r11, 0x80
-+					# vmovdqa	0x60(%r10),	%xmm4	# 3 : sbou
-+	vperm	v4, $sbou, v7, v2	# vpshufb	%xmm2,	%xmm4,	%xmm4	# 4 = sbou
-+					# vmovdqa	0x70(%r10),	%xmm1	# 0 : sbot
-+	lvx	v2, r12, r10		# vmovdqa	-0x160(%r11),	%xmm2	# .Lk_sr-.Lk_dsbd=-0x160
-+	vperm	v1, $sbot, v7, v3	# vpshufb	%xmm3,	%xmm1,	%xmm1	# 0 = sb1t
-+	vxor	v4, v4, v5		# vpxor		%xmm0,	%xmm4,	%xmm4	# 4 = sb1u + k
-+	vxor	v0, v1, v4		# vpxor		%xmm4,	%xmm1,	%xmm0	# 0 = A
-+	vperm	v0, v0, v7, v2		# vpshufb	%xmm2,	%xmm0,	%xmm0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+.globl	.vpaes_decrypt
-+.align	5
-+.vpaes_decrypt:
-+	$STU	$sp,-$FRAME($sp)
-+	li	r10,`15+6*$SIZE_T`
-+	li	r11,`31+6*$SIZE_T`
-+	mflr	r6
-+	mfspr	r7, 256			# save vrsave
-+	stvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v30,r10,$sp
-+	stvx	v31,r11,$sp
-+	stw	r7,`$FRAME-4`($sp)	# save vrsave
-+	li	r0, -1
-+	$PUSH	r6,`$FRAME+$LRSAVE`($sp)
-+	mtspr	256, r0			# preserve all AltiVec registers
-+
-+	bl	_vpaes_decrypt_preheat
-+
-+	?lvsl	$inpperm, 0, $inp	# prepare for unaligned access
-+	lvx	v0, 0, $inp
-+	addi	$inp, $inp, 15		# 15 is not a typo
-+	 ?lvsr	$outperm, 0, $out
-+	?lvsl	$keyperm, 0, $key
-+	lvx	$inptail, 0, $inp	# redundant in aligned case
-+	?vperm	v0, v0, $inptail, $inpperm
-+
-+	bl	_vpaes_decrypt_core
-+
-+	andi.	r8, $out, 15
-+	li	r9, 16
-+	beq	Ldec_out_aligned
-+
-+	vperm	v0, v0, v0, $outperm	# rotate right/left
-+	mtctr	r9
-+Ldec_out_unaligned:
-+	stvebx	v0, 0, $out
-+	addi	$out, $out, 1
-+	bdnz	Ldec_out_unaligned
-+	b	Ldec_done
-+
-+.align	4
-+Ldec_out_aligned:
-+	stvx	v0, 0, $out
-+Ldec_done:
-+
-+	li	r10,`15+6*$SIZE_T`
-+	li	r11,`31+6*$SIZE_T`
-+	mtlr	r6
-+	mtspr	256, r7			# restore vrsave
-+	lvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v30,r10,$sp
-+	lvx	v31,r11,$sp
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,0x04,1,0x80,0,3,0
-+	.long	0
-+.size	.vpaes_decrypt,.-.vpaes_decrypt
-+
-+.globl	.vpaes_cbc_encrypt
-+.align	5
-+.vpaes_cbc_encrypt:
-+	${UCMP}i r5,16
-+	bltlr-
-+
-+	$STU	$sp,-`($FRAME+2*$SIZE_T)`($sp)
-+	mflr	r0
-+	li	r10,`15+6*$SIZE_T`
-+	li	r11,`31+6*$SIZE_T`
-+	mfspr	r12, 256
-+	stvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v30,r10,$sp
-+	stvx	v31,r11,$sp
-+	stw	r12,`$FRAME-4`($sp)	# save vrsave
-+	$PUSH	r30,`$FRAME+$SIZE_T*0`($sp)
-+	$PUSH	r31,`$FRAME+$SIZE_T*1`($sp)
-+	li	r9, -16
-+	$PUSH	r0, `$FRAME+$SIZE_T*2+$LRSAVE`($sp)
-+
-+	and	r30, r5, r9		# copy length&-16
-+	andi.	r9, $out, 15		# is $out aligned?
-+	mr	r5, r6			# copy pointer to key
-+	mr	r31, r7			# copy pointer to iv
-+	li	r6, -1
-+	mcrf	cr1, cr0		# put aside $out alignment flag
-+	mr	r7, r12			# copy vrsave
-+	mtspr	256, r6			# preserve all AltiVec registers
-+
-+	lvx	v24, 0, r31		# load [potentially unaligned] iv
-+	li	r9, 15
-+	?lvsl	$inpperm, 0, r31
-+	lvx	v25, r9, r31
-+	?vperm	v24, v24, v25, $inpperm
-+
-+	cmpwi	r8, 0			# test direction
-+	neg	r8, $inp		# prepare for unaligned access
-+	 vxor	v7, v7, v7
-+	?lvsl	$keyperm, 0, $key
-+	 ?lvsr	$outperm, 0, $out
-+	?lvsr	$inpperm, 0, r8		# -$inp
-+	 vnor	$outmask, v7, v7	# 0xff..ff
-+	lvx	$inptail, 0, $inp
-+	 ?vperm	$outmask, v7, $outmask, $outperm
-+	addi	$inp, $inp, 15		# 15 is not a typo
-+
-+	beq	Lcbc_decrypt
-+
-+	bl	_vpaes_encrypt_preheat
-+	li	r0, 16
-+
-+	beq	cr1, Lcbc_enc_loop	# $out is aligned
-+
-+	vmr	v0, $inptail
-+	lvx	$inptail, 0, $inp
-+	addi	$inp, $inp, 16
-+	?vperm	v0, v0, $inptail, $inpperm
-+	vxor	v0, v0, v24		# ^= iv
-+
-+	bl	_vpaes_encrypt_core
-+
-+	andi.	r8, $out, 15
-+	vmr	v24, v0			# put aside iv
-+	sub	r9, $out, r8
-+	vperm	$outhead, v0, v0, $outperm	# rotate right/left
-+
-+Lcbc_enc_head:
-+	stvebx	$outhead, r8, r9
-+	cmpwi	r8, 15
-+	addi	r8, r8, 1
-+	bne	Lcbc_enc_head
-+
-+	sub.	r30, r30, r0		# len -= 16
-+	addi	$out, $out, 16
-+	beq	Lcbc_unaligned_done
-+
-+Lcbc_enc_loop:
-+	vmr	v0, $inptail
-+	lvx	$inptail, 0, $inp
-+	addi	$inp, $inp, 16
-+	?vperm	v0, v0, $inptail, $inpperm
-+	vxor	v0, v0, v24		# ^= iv
-+
-+	bl	_vpaes_encrypt_core
-+
-+	vmr	v24, v0			# put aside iv
-+	sub.	r30, r30, r0		# len -= 16
-+	vperm	v0, v0, v0, $outperm	# rotate right/left
-+	vsel	v1, $outhead, v0, $outmask
-+	vmr	$outhead, v0
-+	stvx	v1, 0, $out
-+	addi	$out, $out, 16
-+	bne	Lcbc_enc_loop
-+
-+	b	Lcbc_done
-+
-+.align	5
-+Lcbc_decrypt:
-+	bl	_vpaes_decrypt_preheat
-+	li	r0, 16
-+
-+	beq	cr1, Lcbc_dec_loop	# $out is aligned
-+
-+	vmr	v0, $inptail
-+	lvx	$inptail, 0, $inp
-+	addi	$inp, $inp, 16
-+	?vperm	v0, v0, $inptail, $inpperm
-+	vmr	v25, v0			# put aside input
-+
-+	bl	_vpaes_decrypt_core
-+
-+	andi.	r8, $out, 15
-+	vxor	v0, v0, v24		# ^= iv
-+	vmr	v24, v25
-+	sub	r9, $out, r8
-+	vperm	$outhead, v0, v0, $outperm	# rotate right/left
-+
-+Lcbc_dec_head:
-+	stvebx	$outhead, r8, r9
-+	cmpwi	r8, 15
-+	addi	r8, r8, 1
-+	bne	Lcbc_dec_head
-+
-+	sub.	r30, r30, r0		# len -= 16
-+	addi	$out, $out, 16
-+	beq	Lcbc_unaligned_done
-+
-+Lcbc_dec_loop:
-+	vmr	v0, $inptail
-+	lvx	$inptail, 0, $inp
-+	addi	$inp, $inp, 16
-+	?vperm	v0, v0, $inptail, $inpperm
-+	vmr	v25, v0			# put aside input
-+
-+	bl	_vpaes_decrypt_core
-+
-+	vxor	v0, v0, v24		# ^= iv
-+	vmr	v24, v25
-+	sub.	r30, r30, r0		# len -= 16
-+	vperm	v0, v0, v0, $outperm	# rotate right/left
-+	vsel	v1, $outhead, v0, $outmask
-+	vmr	$outhead, v0
-+	stvx	v1, 0, $out
-+	addi	$out, $out, 16
-+	bne	Lcbc_dec_loop
-+
-+Lcbc_done:
-+	beq	cr1, Lcbc_write_iv	# $out is aligned
-+
-+Lcbc_unaligned_done:
-+	andi.	r8, $out, 15
-+	sub	$out, $out, r8
-+	li	r9, 0
-+Lcbc_tail:
-+	stvebx	$outhead, r9, $out
-+	addi	r9, r9, 1
-+	cmpw	r9, r8
-+	bne	Lcbc_tail
-+
-+Lcbc_write_iv:
-+	neg	r8, r31			# write [potentially unaligned] iv
-+	li	r10, 4
-+	?lvsl	$outperm, 0, r8
-+	li	r11, 8
-+	li	r12, 12
-+	vperm	v24, v24, v24, $outperm	# rotate right/left
-+	stvewx	v24, 0, r31		# ivp is at least 32-bit aligned
-+	stvewx	v24, r10, r31
-+	stvewx	v24, r11, r31
-+	stvewx	v24, r12, r31
-+
-+	mtspr	256, r7			# restore vrsave
-+	li	r10,`15+6*$SIZE_T`
-+	li	r11,`31+6*$SIZE_T`
-+	lvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v30,r10,$sp
-+	lvx	v31,r11,$sp
-+Lcbc_abort:
-+	$POP	r0, `$FRAME+$SIZE_T*2+$LRSAVE`($sp)
-+	$POP	r30,`$FRAME+$SIZE_T*0`($sp)
-+	$POP	r31,`$FRAME+$SIZE_T*1`($sp)
-+	mtlr	r0
-+	addi	$sp,$sp,`$FRAME+$SIZE_T*2`
-+	blr
-+	.long	0
-+	.byte	0,12,0x04,1,0x80,2,6,0
-+	.long	0
-+.size	.vpaes_cbc_encrypt,.-.vpaes_cbc_encrypt
-+___
-+}
-+{
-+my ($inp,$bits,$out)=map("r$_",(3..5));
-+my $dir="cr1";
-+my ($invlo,$invhi,$iptlo,$ipthi,$rcon) = map("v$_",(10..13,24));
-+
-+$code.=<<___;
-+########################################################
-+##                                                    ##
-+##                  AES key schedule                  ##
-+##                                                    ##
-+########################################################
-+.align	4
-+_vpaes_key_preheat:
-+	mflr	r8
-+	bl	Lconsts
-+	mtlr	r8
-+	li	r11, 0xc0		# Lk_inv
-+	li	r10, 0xd0
-+	li	r9,  0xe0		# L_ipt
-+	li	r8,  0xf0
-+
-+	vspltisb	v8,4		# 0x04..04
-+	vxor	v9,v9,v9		# 0x00..00
-+	lvx	$invlo, r12, r11	# Lk_inv
-+	li	r11, 0x120
-+	lvx	$invhi, r12, r10
-+	li	r10, 0x130
-+	lvx	$iptlo, r12, r9		# Lk_ipt
-+	li	r9, 0x220
-+	lvx	$ipthi, r12, r8
-+	li	r8, 0x230
-+
-+	lvx	v14, r12, r11		# Lk_sb1
-+	li	r11, 0x240
-+	lvx	v15, r12, r10
-+	li	r10, 0x250
-+
-+	lvx	v16, r12, r9		# Lk_dksd
-+	li	r9, 0x260
-+	lvx	v17, r12, r8
-+	li	r8, 0x270
-+	lvx	v18, r12, r11		# Lk_dksb
-+	li	r11, 0x280
-+	lvx	v19, r12, r10
-+	li	r10, 0x290
-+	lvx	v20, r12, r9		# Lk_dkse
-+	li	r9, 0x2a0
-+	lvx	v21, r12, r8
-+	li	r8, 0x2b0
-+	lvx	v22, r12, r11		# Lk_dks9
-+	lvx	v23, r12, r10
-+
-+	lvx	v24, r12, r9		# Lk_rcon
-+	lvx	v25, 0, r12		# Lk_mc_forward[0]
-+	lvx	v26, r12, r8		# Lks63
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+.align	4
-+_vpaes_schedule_core:
-+	mflr	r7
-+
-+	bl	_vpaes_key_preheat	# load the tables
-+
-+	#lvx	v0, 0, $inp		# vmovdqu	(%rdi),	%xmm0		# load key (unaligned)
-+	neg	r8, $inp		# prepare for unaligned access
-+	lvx	v0, 0, $inp
-+	addi	$inp, $inp, 15		# 15 is not typo
-+	?lvsr	$inpperm, 0, r8		# -$inp
-+	lvx	v6, 0, $inp		# v6 serves as inptail
-+	addi	$inp, $inp, 8
-+	?vperm	v0, v0, v6, $inpperm
-+
-+	# input transform
-+	vmr	v3, v0			# vmovdqa	%xmm0,	%xmm3
-+	bl	_vpaes_schedule_transform
-+	vmr	v7, v0			# vmovdqa	%xmm0,	%xmm7
-+
-+	bne	$dir, Lschedule_am_decrypting
-+
-+	# encrypting, output zeroth round key after transform
-+	li	r8, 0x30		# mov	\$0x30,%r8d
-+	li	r9, 4
-+	li	r10, 8
-+	li	r11, 12
-+
-+	?lvsr	$outperm, 0, $out	# prepare for unaligned access
-+	vnor	$outmask, v9, v9	# 0xff..ff
-+	?vperm	$outmask, v9, $outmask, $outperm
-+
-+	#stvx	v0, 0, $out		# vmovdqu	%xmm0,	(%rdx)
-+	vperm	$outhead, v0, v0, $outperm	# rotate right/left
-+	stvewx	$outhead, 0, $out	# some are superfluous
-+	stvewx	$outhead, r9, $out
-+	stvewx	$outhead, r10, $out
-+	addi	r10, r12, 0x80		# lea	.Lk_sr(%rip),%r10
-+	stvewx	$outhead, r11, $out
-+	b	Lschedule_go
-+
-+Lschedule_am_decrypting:
-+	srwi	r8, $bits, 1		# shr	\$1,%r8d
-+	andi.	r8, r8, 32		# and	\$32,%r8d
-+	xori	r8, r8, 32		# xor	\$32,%r8d	# nbits==192?0:32
-+	addi	r10, r12, 0x80		# lea	.Lk_sr(%rip),%r10
-+	# decrypting, output zeroth round key after shiftrows
-+	lvx	v1, r8, r10		# vmovdqa	(%r8,%r10),	%xmm1
-+	li	r9, 4
-+	li	r10, 8
-+	li	r11, 12
-+	vperm	v4, v3, v3, v1		# vpshufb	%xmm1,	%xmm3,	%xmm3
-+
-+	neg	r0, $out		# prepare for unaligned access
-+	?lvsl	$outperm, 0, r0
-+	vnor	$outmask, v9, v9	# 0xff..ff
-+	?vperm	$outmask, $outmask, v9, $outperm
-+
-+	#stvx	v4, 0, $out		# vmovdqu	%xmm3,	(%rdx)
-+	vperm	$outhead, v4, v4, $outperm	# rotate right/left
-+	stvewx	$outhead, 0, $out	# some are superfluous
-+	stvewx	$outhead, r9, $out
-+	stvewx	$outhead, r10, $out
-+	addi	r10, r12, 0x80		# lea	.Lk_sr(%rip),%r10
-+	stvewx	$outhead, r11, $out
-+	addi	$out, $out, 15		# 15 is not typo
-+	xori	r8, r8, 0x30		# xor	\$0x30, %r8
-+
-+Lschedule_go:
-+	cmplwi	$bits, 192		# cmp	\$192,	%esi
-+	bgt	Lschedule_256
-+	beq	Lschedule_192
-+	# 128: fall though
-+
-+##
-+##  .schedule_128
-+##
-+##  128-bit specific part of key schedule.
-+##
-+##  This schedule is really simple, because all its parts
-+##  are accomplished by the subroutines.
-+##
-+Lschedule_128:
-+	li	r0, 10			# mov	\$10, %esi
-+	mtctr	r0
-+
-+Loop_schedule_128:
-+	bl 	_vpaes_schedule_round
-+	bdz 	Lschedule_mangle_last	# dec	%esi
-+	bl	_vpaes_schedule_mangle	# write output
-+	b 	Loop_schedule_128
-+
-+##
-+##  .aes_schedule_192
-+##
-+##  192-bit specific part of key schedule.
-+##
-+##  The main body of this schedule is the same as the 128-bit
-+##  schedule, but with more smearing.  The long, high side is
-+##  stored in %xmm7 as before, and the short, low side is in
-+##  the high bits of %xmm6.
-+##
-+##  This schedule is somewhat nastier, however, because each
-+##  round produces 192 bits of key material, or 1.5 round keys.
-+##  Therefore, on each cycle we do 2 rounds and produce 3 round
-+##  keys.
-+##
-+.align	4
-+Lschedule_192:
-+	li	r0, 4			# mov	\$4,	%esi
-+	lvx	v0, 0, $inp
-+	?vperm	v0, v6, v0, $inpperm
-+	?vsldoi	v0, v3, v0, 8		# vmovdqu	8(%rdi),%xmm0		# load key part 2 (very unaligned)
-+	bl	_vpaes_schedule_transform	# input transform
-+	?vsldoi	v6, v0, v9, 8
-+	?vsldoi	v6, v9, v6, 8		# clobber "low" side with zeros
-+	mtctr	r0
-+
-+Loop_schedule_192:
-+	bl	_vpaes_schedule_round
-+	?vsldoi	v0, v6, v0, 8		# vpalignr	\$8,%xmm6,%xmm0,%xmm0
-+	bl	_vpaes_schedule_mangle	# save key n
-+	bl	_vpaes_schedule_192_smear
-+	bl	_vpaes_schedule_mangle	# save key n+1
-+	bl	_vpaes_schedule_round
-+	bdz 	Lschedule_mangle_last	# dec	%esi
-+	bl	_vpaes_schedule_mangle	# save key n+2
-+	bl	_vpaes_schedule_192_smear
-+	b	Loop_schedule_192
-+
-+##
-+##  .aes_schedule_256
-+##
-+##  256-bit specific part of key schedule.
-+##
-+##  The structure here is very similar to the 128-bit
-+##  schedule, but with an additional "low side" in
-+##  %xmm6.  The low side's rounds are the same as the
-+##  high side's, except no rcon and no rotation.
-+##
-+.align	4
-+Lschedule_256:
-+	li	r0, 7			# mov	\$7, %esi
-+	addi	$inp, $inp, 8
-+	lvx	v0, 0, $inp		# vmovdqu	16(%rdi),%xmm0		# load key part 2 (unaligned)
-+	?vperm	v0, v6, v0, $inpperm
-+	bl	_vpaes_schedule_transform	# input transform
-+	mtctr	r0
-+
-+Loop_schedule_256:
-+	bl	_vpaes_schedule_mangle	# output low result
-+	vmr	v6, v0			# vmovdqa	%xmm0,	%xmm6		# save cur_lo in xmm6
-+
-+	# high round
-+	bl	_vpaes_schedule_round
-+	bdz 	Lschedule_mangle_last	# dec	%esi
-+	bl	_vpaes_schedule_mangle	
-+
-+	# low round. swap xmm7 and xmm6
-+	?vspltw	v0, v0, 3		# vpshufd	\$0xFF,	%xmm0,	%xmm0
-+	vmr	v5, v7			# vmovdqa	%xmm7,	%xmm5
-+	vmr	v7, v6			# vmovdqa	%xmm6,	%xmm7
-+	bl	_vpaes_schedule_low_round
-+	vmr	v7, v5			# vmovdqa	%xmm5,	%xmm7
-+	
-+	b	Loop_schedule_256
-+##
-+##  .aes_schedule_mangle_last
-+##
-+##  Mangler for last round of key schedule
-+##  Mangles %xmm0
-+##    when encrypting, outputs out(%xmm0) ^ 63
-+##    when decrypting, outputs unskew(%xmm0)
-+##
-+##  Always called right before return... jumps to cleanup and exits
-+##
-+.align	4
-+Lschedule_mangle_last:
-+	# schedule last round key from xmm0
-+	li	r11, 0x2e0		# lea	.Lk_deskew(%rip),%r11
-+	li	r9,  0x2f0
-+	bne	$dir, Lschedule_mangle_last_dec
-+
-+	# encrypting
-+	lvx	v1, r8, r10		# vmovdqa	(%r8,%r10),%xmm1
-+	li	r11, 0x2c0		# lea		.Lk_opt(%rip),	%r11	# prepare to output transform
-+	li	r9,  0x2d0		# prepare to output transform
-+	vperm	v0, v0, v0, v1		# vpshufb	%xmm1,	%xmm0,	%xmm0	# output permute
-+
-+	lvx	$iptlo, r11, r12	# reload $ipt
-+	lvx	$ipthi, r9, r12
-+	addi	$out, $out, 16		# add	\$16,	%rdx
-+	vxor	v0, v0, v26		# vpxor		.Lk_s63(%rip),	%xmm0,	%xmm0
-+	bl	_vpaes_schedule_transform	# output transform
-+
-+	#stvx	v0, r0, $out		# vmovdqu	%xmm0,	(%rdx)		# save last key
-+	vperm	v0, v0, v0, $outperm	# rotate right/left
-+	li	r10, 4
-+	vsel	v2, $outhead, v0, $outmask
-+	li	r11, 8
-+	stvx	v2, 0, $out
-+	li	r12, 12
-+	stvewx	v0, 0, $out		# some (or all) are redundant
-+	stvewx	v0, r10, $out
-+	stvewx	v0, r11, $out
-+	stvewx	v0, r12, $out
-+	b	Lschedule_mangle_done
-+
-+.align	4
-+Lschedule_mangle_last_dec:
-+	lvx	$iptlo, r11, r12	# reload $ipt
-+	lvx	$ipthi, r9,  r12
-+	addi	$out, $out, -16		# add	\$-16,	%rdx 
-+	vxor	v0, v0, v26		# vpxor	.Lk_s63(%rip),	%xmm0,	%xmm0
-+	bl	_vpaes_schedule_transform	# output transform
-+
-+	#stvx	v0, r0, $out		# vmovdqu	%xmm0,	(%rdx)		# save last key
-+	addi	r9, $out, -15		# -15 is not typo
-+	vperm	v0, v0, v0, $outperm	# rotate right/left
-+	li	r10, 4
-+	vsel	v2, $outhead, v0, $outmask
-+	li	r11, 8
-+	stvx	v2, 0, $out
-+	li	r12, 12
-+	stvewx	v0, 0, r9		# some (or all) are redundant
-+	stvewx	v0, r10, r9
-+	stvewx	v0, r11, r9
-+	stvewx	v0, r12, r9
-+
-+
-+Lschedule_mangle_done:
-+	mtlr	r7
-+	# cleanup
-+	vxor	v0, v0, v0		# vpxor		%xmm0,	%xmm0,	%xmm0
-+	vxor	v1, v1, v1		# vpxor		%xmm1,	%xmm1,	%xmm1
-+	vxor	v2, v2, v2		# vpxor		%xmm2,	%xmm2,	%xmm2
-+	vxor	v3, v3, v3		# vpxor		%xmm3,	%xmm3,	%xmm3
-+	vxor	v4, v4, v4		# vpxor		%xmm4,	%xmm4,	%xmm4
-+	vxor	v5, v5, v5		# vpxor		%xmm5,	%xmm5,	%xmm5
-+	vxor	v6, v6, v6		# vpxor		%xmm6,	%xmm6,	%xmm6
-+	vxor	v7, v7, v7		# vpxor		%xmm7,	%xmm7,	%xmm7
-+
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+##
-+##  .aes_schedule_192_smear
-+##
-+##  Smear the short, low side in the 192-bit key schedule.
-+##
-+##  Inputs:
-+##    %xmm7: high side, b  a  x  y
-+##    %xmm6:  low side, d  c  0  0
-+##    %xmm13: 0
-+##
-+##  Outputs:
-+##    %xmm6: b+c+d  b+c  0  0
-+##    %xmm0: b+c+d  b+c  b  a
-+##
-+.align	4
-+_vpaes_schedule_192_smear:
-+	?vspltw	v0, v7, 3
-+	?vsldoi	v1, v9, v6, 12		# vpshufd	\$0x80,	%xmm6,	%xmm1	# d c 0 0 -> c 0 0 0
-+	?vsldoi	v0, v7, v0, 8		# vpshufd	\$0xFE,	%xmm7,	%xmm0	# b a _ _ -> b b b a
-+	vxor	v6, v6, v1		# vpxor		%xmm1,	%xmm6,	%xmm6	# -> c+d c 0 0
-+	vxor	v6, v6, v0		# vpxor		%xmm0,	%xmm6,	%xmm6	# -> b+c+d b+c b a
-+	vmr	v0, v6
-+	?vsldoi	v6, v6, v9, 8
-+	?vsldoi	v6, v9, v6, 8		# clobber low side with zeros
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+##
-+##  .aes_schedule_round
-+##
-+##  Runs one main round of the key schedule on %xmm0, %xmm7
-+##
-+##  Specifically, runs subbytes on the high dword of %xmm0
-+##  then rotates it by one byte and xors into the low dword of
-+##  %xmm7.
-+##
-+##  Adds rcon from low byte of %xmm8, then rotates %xmm8 for
-+##  next rcon.
-+##
-+##  Smears the dwords of %xmm7 by xoring the low into the
-+##  second low, result into third, result into highest.
-+##
-+##  Returns results in %xmm7 = %xmm0.
-+##  Clobbers %xmm1-%xmm4, %r11.
-+##
-+.align	4
-+_vpaes_schedule_round:
-+	# extract rcon from xmm8
-+	#vxor	v4, v4, v4		# vpxor		%xmm4,	%xmm4,	%xmm4
-+	?vsldoi	v1, $rcon, v9, 15	# vpalignr	\$15,	%xmm8,	%xmm4,	%xmm1
-+	?vsldoi	$rcon, $rcon, $rcon, 15	# vpalignr	\$15,	%xmm8,	%xmm8,	%xmm8
-+	vxor	v7, v7, v1		# vpxor		%xmm1,	%xmm7,	%xmm7
-+
-+	# rotate
-+	?vspltw	v0, v0, 3		# vpshufd	\$0xFF,	%xmm0,	%xmm0
-+	?vsldoi	v0, v0, v0, 1		# vpalignr	\$1,	%xmm0,	%xmm0,	%xmm0
-+
-+	# fall through...
-+
-+	# low round: same as high round, but no rotation and no rcon.
-+_vpaes_schedule_low_round:
-+	# smear xmm7
-+	?vsldoi	v1, v9, v7, 12		# vpslldq	\$4,	%xmm7,	%xmm1
-+	vxor	v7, v7, v1		# vpxor		%xmm1,	%xmm7,	%xmm7
-+	vspltisb	v1, 0x0f	# 0x0f..0f
-+	?vsldoi	v4, v9, v7, 8		# vpslldq	\$8,	%xmm7,	%xmm4
-+
-+	# subbytes
-+	vand	v1, v1, v0		# vpand		%xmm9,	%xmm0,	%xmm1		# 0 = k
-+	vsrb	v0, v0, v8		# vpsrlb	\$4,	%xmm0,	%xmm0		# 1 = i
-+	 vxor	v7, v7, v4		# vpxor		%xmm4,	%xmm7,	%xmm7
-+	vperm	v2, $invhi, v9, v1	# vpshufb	%xmm1,	%xmm11,	%xmm2		# 2 = a/k
-+	vxor	v1, v1, v0		# vpxor		%xmm0,	%xmm1,	%xmm1		# 0 = j
-+	vperm	v3, $invlo, v9, v0	# vpshufb	%xmm0, 	%xmm10,	%xmm3		# 3 = 1/i
-+	vxor	v3, v3, v2		# vpxor		%xmm2,	%xmm3,	%xmm3		# 3 = iak = 1/i + a/k
-+	vperm	v4, $invlo, v9, v1	# vpshufb	%xmm1,	%xmm10,	%xmm4		# 4 = 1/j
-+	 vxor	v7, v7, v26		# vpxor		.Lk_s63(%rip),	%xmm7,	%xmm7
-+	vperm	v3, $invlo, v9, v3	# vpshufb	%xmm3,	%xmm10,	%xmm3		# 2 = 1/iak
-+	vxor	v4, v4, v2		# vpxor		%xmm2,	%xmm4,	%xmm4		# 4 = jak = 1/j + a/k
-+	vperm	v2, $invlo, v9, v4	# vpshufb	%xmm4,	%xmm10,	%xmm2		# 3 = 1/jak
-+	vxor	v3, v3, v1		# vpxor		%xmm1,	%xmm3,	%xmm3		# 2 = io
-+	vxor	v2, v2, v0		# vpxor		%xmm0,	%xmm2,	%xmm2		# 3 = jo
-+	vperm	v4, v15, v9, v3		# vpshufb	%xmm3,	%xmm13,	%xmm4		# 4 = sbou
-+	vperm	v1, v14, v9, v2		# vpshufb	%xmm2,	%xmm12,	%xmm1		# 0 = sb1t
-+	vxor	v1, v1, v4		# vpxor		%xmm4,	%xmm1,	%xmm1		# 0 = sbox output
-+
-+	# add in smeared stuff
-+	vxor	v0, v1, v7		# vpxor		%xmm7,	%xmm1,	%xmm0
-+	vxor	v7, v1, v7		# vmovdqa	%xmm0,	%xmm7
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+##
-+##  .aes_schedule_transform
-+##
-+##  Linear-transform %xmm0 according to tables at (%r11)
-+##
-+##  Requires that %xmm9 = 0x0F0F... as in preheat
-+##  Output in %xmm0
-+##  Clobbers %xmm2
-+##
-+.align	4
-+_vpaes_schedule_transform:
-+	#vand	v1, v0, v9		# vpand		%xmm9,	%xmm0,	%xmm1
-+	vsrb	v2, v0, v8		# vpsrlb	\$4,	%xmm0,	%xmm0
-+					# vmovdqa	(%r11),	%xmm2 	# lo
-+	vperm	v0, $iptlo, $iptlo, v0	# vpshufb	%xmm1,	%xmm2,	%xmm2
-+					# vmovdqa	16(%r11),	%xmm1 # hi
-+	vperm	v2, $ipthi, $ipthi, v2	# vpshufb	%xmm0,	%xmm1,	%xmm0
-+	vxor	v0, v0, v2		# vpxor		%xmm2,	%xmm0,	%xmm0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+##
-+##  .aes_schedule_mangle
-+##
-+##  Mangle xmm0 from (basis-transformed) standard version
-+##  to our version.
-+##
-+##  On encrypt,
-+##    xor with 0x63
-+##    multiply by circulant 0,1,1,1
-+##    apply shiftrows transform
-+##
-+##  On decrypt,
-+##    xor with 0x63
-+##    multiply by "inverse mixcolumns" circulant E,B,D,9
-+##    deskew
-+##    apply shiftrows transform
-+##
-+##
-+##  Writes out to (%rdx), and increments or decrements it
-+##  Keeps track of round number mod 4 in %r8
-+##  Preserves xmm0
-+##  Clobbers xmm1-xmm5
-+##
-+.align	4
-+_vpaes_schedule_mangle:
-+	#vmr	v4, v0			# vmovdqa	%xmm0,	%xmm4	# save xmm0 for later
-+					# vmovdqa	.Lk_mc_forward(%rip),%xmm5
-+	bne	$dir, Lschedule_mangle_dec
-+
-+	# encrypting
-+	vxor	v4, v0, v26		# vpxor	.Lk_s63(%rip),	%xmm0,	%xmm4
-+	addi	$out, $out, 16		# add	\$16,	%rdx
-+	vperm	v4, v4, v4, v25		# vpshufb	%xmm5,	%xmm4,	%xmm4
-+	vperm	v1, v4, v4, v25		# vpshufb	%xmm5,	%xmm4,	%xmm1
-+	vperm	v3, v1, v1, v25		# vpshufb	%xmm5,	%xmm1,	%xmm3
-+	vxor	v4, v4, v1		# vpxor		%xmm1,	%xmm4,	%xmm4
-+	lvx	v1, r8, r10		# vmovdqa	(%r8,%r10),	%xmm1
-+	vxor	v3, v3, v4		# vpxor		%xmm4,	%xmm3,	%xmm3
-+
-+	vperm	v3, v3, v3, v1		# vpshufb	%xmm1,	%xmm3,	%xmm3
-+	addi	r8, r8, -16		# add	\$-16,	%r8
-+	andi.	r8, r8, 0x30		# and	\$0x30,	%r8
-+
-+	#stvx	v3, 0, $out		# vmovdqu	%xmm3,	(%rdx)
-+	vperm	v1, v3, v3, $outperm	# rotate right/left
-+	vsel	v2, $outhead, v1, $outmask
-+	vmr	$outhead, v1
-+	stvx	v2, 0, $out
-+	blr
-+
-+.align	4
-+Lschedule_mangle_dec:
-+	# inverse mix columns
-+					# lea	.Lk_dksd(%rip),%r11
-+	vsrb	v1, v0, v8		# vpsrlb	\$4,	%xmm4,	%xmm1	# 1 = hi
-+	#and	v4, v0, v9		# vpand		%xmm9,	%xmm4,	%xmm4	# 4 = lo
-+
-+					# vmovdqa	0x00(%r11),	%xmm2
-+	vperm	v2, v16, v16, v0	# vpshufb	%xmm4,	%xmm2,	%xmm2
-+					# vmovdqa	0x10(%r11),	%xmm3
-+	vperm	v3, v17, v17, v1	# vpshufb	%xmm1,	%xmm3,	%xmm3
-+	vxor	v3, v3, v2		# vpxor		%xmm2,	%xmm3,	%xmm3
-+	vperm	v3, v3, v9, v25		# vpshufb	%xmm5,	%xmm3,	%xmm3
-+
-+					# vmovdqa	0x20(%r11),	%xmm2
-+	vperm	v2, v18, v18, v0	# vpshufb	%xmm4,	%xmm2,	%xmm2
-+	vxor	v2, v2, v3		# vpxor		%xmm3,	%xmm2,	%xmm2
-+					# vmovdqa	0x30(%r11),	%xmm3
-+	vperm	v3, v19, v19, v1	# vpshufb	%xmm1,	%xmm3,	%xmm3
-+	vxor	v3, v3, v2		# vpxor		%xmm2,	%xmm3,	%xmm3
-+	vperm	v3, v3, v9, v25		# vpshufb	%xmm5,	%xmm3,	%xmm3
-+
-+					# vmovdqa	0x40(%r11),	%xmm2
-+	vperm	v2, v20, v20, v0	# vpshufb	%xmm4,	%xmm2,	%xmm2
-+	vxor	v2, v2, v3		# vpxor		%xmm3,	%xmm2,	%xmm2
-+					# vmovdqa	0x50(%r11),	%xmm3
-+	vperm	v3, v21, v21, v1	# vpshufb	%xmm1,	%xmm3,	%xmm3
-+	vxor	v3, v3, v2		# vpxor		%xmm2,	%xmm3,	%xmm3
-+
-+					# vmovdqa	0x60(%r11),	%xmm2
-+	vperm	v2, v22, v22, v0	# vpshufb	%xmm4,	%xmm2,	%xmm2
-+	vperm	v3, v3, v9, v25		# vpshufb	%xmm5,	%xmm3,	%xmm3
-+					# vmovdqa	0x70(%r11),	%xmm4
-+	vperm	v4, v23, v23, v1	# vpshufb	%xmm1,	%xmm4,	%xmm4
-+	lvx	v1, r8, r10		# vmovdqa	(%r8,%r10),	%xmm1
-+	vxor	v2, v2, v3		# vpxor		%xmm3,	%xmm2,	%xmm2
-+	vxor	v3, v4, v2		# vpxor		%xmm2,	%xmm4,	%xmm3
-+
-+	addi	$out, $out, -16		# add	\$-16,	%rdx
-+
-+	vperm	v3, v3, v3, v1		# vpshufb	%xmm1,	%xmm3,	%xmm3
-+	addi	r8, r8, -16		# add	\$-16,	%r8
-+	andi.	r8, r8, 0x30		# and	\$0x30,	%r8
-+
-+	#stvx	v3, 0, $out		# vmovdqu	%xmm3,	(%rdx)
-+	vperm	v1, v3, v3, $outperm	# rotate right/left
-+	vsel	v2, $outhead, v1, $outmask
-+	vmr	$outhead, v1
-+	stvx	v2, 0, $out
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+
-+.globl	.vpaes_set_encrypt_key
-+.align	5
-+.vpaes_set_encrypt_key:
-+	$STU	$sp,-$FRAME($sp)
-+	li	r10,`15+6*$SIZE_T`
-+	li	r11,`31+6*$SIZE_T`
-+	mflr	r0
-+	mfspr	r6, 256			# save vrsave
-+	stvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v30,r10,$sp
-+	stvx	v31,r11,$sp
-+	stw	r6,`$FRAME-4`($sp)	# save vrsave
-+	li	r7, -1
-+	$PUSH	r0, `$FRAME+$LRSAVE`($sp)
-+	mtspr	256, r7			# preserve all AltiVec registers
-+
-+	srwi	r9, $bits, 5		# shr	\$5,%eax
-+	addi	r9, r9, 6		# add	\$5,%eax
-+	stw	r9, 240($out)		# mov	%eax,240(%rdx)	# AES_KEY->rounds = nbits/32+5;
-+
-+	cmplw	$dir, $bits, $bits	# set encrypt direction
-+	li	r8, 0x30		# mov	\$0x30,%r8d
-+	bl	_vpaes_schedule_core
-+
-+	$POP	r0, `$FRAME+$LRSAVE`($sp)
-+	li	r10,`15+6*$SIZE_T`
-+	li	r11,`31+6*$SIZE_T`
-+	mtspr	256, r6			# restore vrsave
-+	mtlr	r0
-+	xor	r3, r3, r3
-+	lvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v30,r10,$sp
-+	lvx	v31,r11,$sp
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,0x04,1,0x80,0,3,0
-+	.long	0
-+.size	.vpaes_set_encrypt_key,.-.vpaes_set_encrypt_key
-+
-+.globl	.vpaes_set_decrypt_key
-+.align	4
-+.vpaes_set_decrypt_key:
-+	$STU	$sp,-$FRAME($sp)
-+	li	r10,`15+6*$SIZE_T`
-+	li	r11,`31+6*$SIZE_T`
-+	mflr	r0
-+	mfspr	r6, 256			# save vrsave
-+	stvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v30,r10,$sp
-+	stvx	v31,r11,$sp
-+	stw	r6,`$FRAME-4`($sp)	# save vrsave
-+	li	r7, -1
-+	$PUSH	r0, `$FRAME+$LRSAVE`($sp)
-+	mtspr	256, r7			# preserve all AltiVec registers
-+
-+	srwi	r9, $bits, 5		# shr	\$5,%eax
-+	addi	r9, r9, 6		# add	\$5,%eax
-+	stw	r9, 240($out)		# mov	%eax,240(%rdx)	# AES_KEY->rounds = nbits/32+5;
-+
-+	slwi	r9, r9, 4		# shl	\$4,%eax
-+	add	$out, $out, r9		# lea	(%rdx,%rax),%rdx
-+
-+	cmplwi	$dir, $bits, 0		# set decrypt direction
-+	srwi	r8, $bits, 1		# shr	\$1,%r8d
-+	andi.	r8, r8, 32		# and	\$32,%r8d
-+	xori	r8, r8, 32		# xor	\$32,%r8d	# nbits==192?0:32
-+	bl	_vpaes_schedule_core
-+
-+	$POP	r0,  `$FRAME+$LRSAVE`($sp)
-+	li	r10,`15+6*$SIZE_T`
-+	li	r11,`31+6*$SIZE_T`
-+	mtspr	256, r6			# restore vrsave
-+	mtlr	r0
-+	xor	r3, r3, r3
-+	lvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v30,r10,$sp
-+	lvx	v31,r11,$sp
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,0x04,1,0x80,0,3,0
-+	.long	0
-+.size	.vpaes_set_decrypt_key,.-.vpaes_set_decrypt_key
-+___
-+}
-+
-+my $consts=1;
-+foreach  (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	# constants table endian-specific conversion
-+	if ($consts && m/\.long\s+(.+)\s+(\?[a-z]*)$/o) {
-+	    my $conv=$2;
-+	    my @bytes=();
-+
-+	    # convert to endian-agnostic format
-+	    foreach (split(/,\s+/,$1)) {
-+		my $l = /^0/?oct:int;
-+		push @bytes,($l>>24)&0xff,($l>>16)&0xff,($l>>8)&0xff,$l&0xff;
-+	    }
-+
-+	    # little-endian conversion
-+	    if ($flavour =~ /le$/o) {
-+		SWITCH: for($conv)  {
-+		    /\?inv/ && do   { @bytes=map($_^0xf,@bytes); last; };
-+		    /\?rev/ && do   { @bytes=reverse(@bytes);    last; }; 
-+		}
-+	    }
-+
-+	    #emit
-+	    print ".byte\t",join(',',map (sprintf("0x%02x",$_),@bytes)),"\n";
-+	    next;
-+	}
-+	$consts=0 if (m/Lconsts:/o);	# end of table
-+
-+	# instructions prefixed with '?' are endian-specific and need
-+	# to be adjusted accordingly...
-+	if ($flavour =~ /le$/o) {	# little-endian
-+	    s/\?lvsr/lvsl/o or
-+	    s/\?lvsl/lvsr/o or
-+	    s/\?(vperm\s+v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+)/$1$3$2$4/o or
-+	    s/\?(vsldoi\s+v[0-9]+,\s*)(v[0-9]+,)\s*(v[0-9]+,\s*)([0-9]+)/$1$3$2 16-$4/o or
-+	    s/\?(vspltw\s+v[0-9]+,\s*)(v[0-9]+,)\s*([0-9])/$1$2 3-$3/o;
-+	} else {			# big-endian
-+	    s/\?([a-z]+)/$1/o;
-+	}
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-x86.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-x86.pl
-new file mode 100644
-index 0000000..47615c0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-x86.pl
-@@ -0,0 +1,916 @@
-+#! /usr/bin/env perl
-+# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+######################################################################
-+## Constant-time SSSE3 AES core implementation.
-+## version 0.1
-+##
-+## By Mike Hamburg (Stanford University), 2009
-+## Public domain.
-+##
-+## For details see http://shiftleft.org/papers/vector_aes/ and
-+## http://crypto.stanford.edu/vpaes/.
-+
-+######################################################################
-+# September 2011.
-+#
-+# Port vpaes-x86_64.pl as 32-bit "almost" drop-in replacement for
-+# aes-586.pl. "Almost" refers to the fact that AES_cbc_encrypt
-+# doesn't handle partial vectors (doesn't have to if called from
-+# EVP only). "Drop-in" implies that this module doesn't share key
-+# schedule structure with the original nor does it make assumption
-+# about its alignment...
-+#
-+# Performance summary. aes-586.pl column lists large-block CBC
-+# encrypt/decrypt/with-hyper-threading-off(*) results in cycles per
-+# byte processed with 128-bit key, and vpaes-x86.pl column - [also
-+# large-block CBC] encrypt/decrypt.
-+#
-+#		aes-586.pl		vpaes-x86.pl
-+#
-+# Core 2(**)	28.1/41.4/18.3		21.9/25.2(***)
-+# Nehalem	27.9/40.4/18.1		10.2/11.9
-+# Atom		70.7/92.1/60.1		61.1/75.4(***)
-+# Silvermont	45.4/62.9/24.1		49.2/61.1(***)
-+#
-+# (*)	"Hyper-threading" in the context refers rather to cache shared
-+#	among multiple cores, than to specifically Intel HTT. As vast
-+#	majority of contemporary cores share cache, slower code path
-+#	is common place. In other words "with-hyper-threading-off"
-+#	results are presented mostly for reference purposes.
-+#
-+# (**)	"Core 2" refers to initial 65nm design, a.k.a. Conroe.
-+#
-+# (***)	Less impressive improvement on Core 2 and Atom is due to slow
-+#	pshufb,	yet it's respectable +28%/64%  improvement on Core 2
-+#	and +15% on Atom (as implied, over "hyper-threading-safe"
-+#	code path).
-+#
-+#						
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output = pop;
-+open OUT,">$output";
-+*STDOUT=*OUT;
-+
-+&asm_init($ARGV[0],"vpaes-x86.pl",$x86only = $ARGV[$#ARGV] eq "386");
-+
-+$PREFIX="vpaes";
-+
-+my  ($round, $base, $magic, $key, $const, $inp, $out)=
-+    ("eax",  "ebx", "ecx",  "edx","ebp",  "esi","edi");
-+
-+&static_label("_vpaes_consts");
-+&static_label("_vpaes_schedule_low_round");
-+
-+&set_label("_vpaes_consts",64);
-+$k_inv=-0x30;		# inv, inva
-+	&data_word(0x0D080180,0x0E05060F,0x0A0B0C02,0x04070309);
-+	&data_word(0x0F0B0780,0x01040A06,0x02050809,0x030D0E0C);
-+
-+$k_s0F=-0x10;		# s0F
-+	&data_word(0x0F0F0F0F,0x0F0F0F0F,0x0F0F0F0F,0x0F0F0F0F);
-+
-+$k_ipt=0x00;		# input transform (lo, hi)
-+	&data_word(0x5A2A7000,0xC2B2E898,0x52227808,0xCABAE090);
-+	&data_word(0x317C4D00,0x4C01307D,0xB0FDCC81,0xCD80B1FC);
-+
-+$k_sb1=0x20;		# sb1u, sb1t
-+	&data_word(0xCB503E00,0xB19BE18F,0x142AF544,0xA5DF7A6E);
-+	&data_word(0xFAE22300,0x3618D415,0x0D2ED9EF,0x3BF7CCC1);
-+$k_sb2=0x40;		# sb2u, sb2t
-+	&data_word(0x0B712400,0xE27A93C6,0xBC982FCD,0x5EB7E955);
-+	&data_word(0x0AE12900,0x69EB8840,0xAB82234A,0xC2A163C8);
-+$k_sbo=0x60;		# sbou, sbot
-+	&data_word(0x6FBDC700,0xD0D26D17,0xC502A878,0x15AABF7A);
-+	&data_word(0x5FBB6A00,0xCFE474A5,0x412B35FA,0x8E1E90D1);
-+
-+$k_mc_forward=0x80;	# mc_forward
-+	&data_word(0x00030201,0x04070605,0x080B0A09,0x0C0F0E0D);
-+	&data_word(0x04070605,0x080B0A09,0x0C0F0E0D,0x00030201);
-+	&data_word(0x080B0A09,0x0C0F0E0D,0x00030201,0x04070605);
-+	&data_word(0x0C0F0E0D,0x00030201,0x04070605,0x080B0A09);
-+
-+$k_mc_backward=0xc0;	# mc_backward
-+	&data_word(0x02010003,0x06050407,0x0A09080B,0x0E0D0C0F);
-+	&data_word(0x0E0D0C0F,0x02010003,0x06050407,0x0A09080B);
-+	&data_word(0x0A09080B,0x0E0D0C0F,0x02010003,0x06050407);
-+	&data_word(0x06050407,0x0A09080B,0x0E0D0C0F,0x02010003);
-+
-+$k_sr=0x100;		# sr
-+	&data_word(0x03020100,0x07060504,0x0B0A0908,0x0F0E0D0C);
-+	&data_word(0x0F0A0500,0x030E0904,0x07020D08,0x0B06010C);
-+	&data_word(0x0B020900,0x0F060D04,0x030A0108,0x070E050C);
-+	&data_word(0x070A0D00,0x0B0E0104,0x0F020508,0x0306090C);
-+
-+$k_rcon=0x140;		# rcon
-+	&data_word(0xAF9DEEB6,0x1F8391B9,0x4D7C7D81,0x702A9808);
-+
-+$k_s63=0x150;		# s63: all equal to 0x63 transformed
-+	&data_word(0x5B5B5B5B,0x5B5B5B5B,0x5B5B5B5B,0x5B5B5B5B);
-+
-+$k_opt=0x160;		# output transform
-+	&data_word(0xD6B66000,0xFF9F4929,0xDEBE6808,0xF7974121);
-+	&data_word(0x50BCEC00,0x01EDBD51,0xB05C0CE0,0xE10D5DB1);
-+
-+$k_deskew=0x180;	# deskew tables: inverts the sbox's "skew"
-+	&data_word(0x47A4E300,0x07E4A340,0x5DBEF91A,0x1DFEB95A);
-+	&data_word(0x83EA6900,0x5F36B5DC,0xF49D1E77,0x2841C2AB);
-+##
-+##  Decryption stuff
-+##  Key schedule constants
-+##
-+$k_dksd=0x1a0;		# decryption key schedule: invskew x*D
-+	&data_word(0xA3E44700,0xFEB91A5D,0x5A1DBEF9,0x0740E3A4);
-+	&data_word(0xB5368300,0x41C277F4,0xAB289D1E,0x5FDC69EA);
-+$k_dksb=0x1c0;		# decryption key schedule: invskew x*B
-+	&data_word(0x8550D500,0x9A4FCA1F,0x1CC94C99,0x03D65386);
-+	&data_word(0xB6FC4A00,0x115BEDA7,0x7E3482C8,0xD993256F);
-+$k_dkse=0x1e0;		# decryption key schedule: invskew x*E + 0x63
-+	&data_word(0x1FC9D600,0xD5031CCA,0x994F5086,0x53859A4C);
-+	&data_word(0x4FDC7BE8,0xA2319605,0x20B31487,0xCD5EF96A);
-+$k_dks9=0x200;		# decryption key schedule: invskew x*9
-+	&data_word(0x7ED9A700,0xB6116FC8,0x82255BFC,0x4AED9334);
-+	&data_word(0x27143300,0x45765162,0xE9DAFDCE,0x8BB89FAC);
-+
-+##
-+##  Decryption stuff
-+##  Round function constants
-+##
-+$k_dipt=0x220;		# decryption input transform
-+	&data_word(0x0B545F00,0x0F505B04,0x114E451A,0x154A411E);
-+	&data_word(0x60056500,0x86E383E6,0xF491F194,0x12771772);
-+
-+$k_dsb9=0x240;		# decryption sbox output *9*u, *9*t
-+	&data_word(0x9A86D600,0x851C0353,0x4F994CC9,0xCAD51F50);
-+	&data_word(0xECD74900,0xC03B1789,0xB2FBA565,0x725E2C9E);
-+$k_dsbd=0x260;		# decryption sbox output *D*u, *D*t
-+	&data_word(0xE6B1A200,0x7D57CCDF,0x882A4439,0xF56E9B13);
-+	&data_word(0x24C6CB00,0x3CE2FAF7,0x15DEEFD3,0x2931180D);
-+$k_dsbb=0x280;		# decryption sbox output *B*u, *B*t
-+	&data_word(0x96B44200,0xD0226492,0xB0F2D404,0x602646F6);
-+	&data_word(0xCD596700,0xC19498A6,0x3255AA6B,0xF3FF0C3E);
-+$k_dsbe=0x2a0;		# decryption sbox output *E*u, *E*t
-+	&data_word(0x26D4D000,0x46F29296,0x64B4F6B0,0x22426004);
-+	&data_word(0xFFAAC100,0x0C55A6CD,0x98593E32,0x9467F36B);
-+$k_dsbo=0x2c0;		# decryption sbox final output
-+	&data_word(0x7EF94000,0x1387EA53,0xD4943E2D,0xC7AA6DB9);
-+	&data_word(0x93441D00,0x12D7560F,0xD8C58E9C,0xCA4B8159);
-+&asciz	("Vector Permutation AES for x86/SSSE3, Mike Hamburg (Stanford University)");
-+&align	(64);
-+
-+&function_begin_B("_vpaes_preheat");
-+	&add	($const,&DWP(0,"esp"));
-+	&movdqa	("xmm7",&QWP($k_inv,$const));
-+	&movdqa	("xmm6",&QWP($k_s0F,$const));
-+	&ret	();
-+&function_end_B("_vpaes_preheat");
-+
-+##
-+##  _aes_encrypt_core
-+##
-+##  AES-encrypt %xmm0.
-+##
-+##  Inputs:
-+##     %xmm0 = input
-+##     %xmm6-%xmm7 as in _vpaes_preheat
-+##    (%edx) = scheduled keys
-+##
-+##  Output in %xmm0
-+##  Clobbers  %xmm1-%xmm5, %eax, %ebx, %ecx, %edx
-+##
-+##
-+&function_begin_B("_vpaes_encrypt_core");
-+	&mov	($magic,16);
-+	&mov	($round,&DWP(240,$key));
-+	&movdqa	("xmm1","xmm6")
-+	&movdqa	("xmm2",&QWP($k_ipt,$const));
-+	&pandn	("xmm1","xmm0");
-+	&pand	("xmm0","xmm6");
-+	&movdqu	("xmm5",&QWP(0,$key));
-+	&pshufb	("xmm2","xmm0");
-+	&movdqa	("xmm0",&QWP($k_ipt+16,$const));
-+	&pxor	("xmm2","xmm5");
-+	&psrld	("xmm1",4);
-+	&add	($key,16);
-+	&pshufb	("xmm0","xmm1");
-+	&lea	($base,&DWP($k_mc_backward,$const));
-+	&pxor	("xmm0","xmm2");
-+	&jmp	(&label("enc_entry"));
-+
-+
-+&set_label("enc_loop",16);
-+	# middle of middle round
-+	&movdqa	("xmm4",&QWP($k_sb1,$const));	# 4 : sb1u
-+	&movdqa	("xmm0",&QWP($k_sb1+16,$const));# 0 : sb1t
-+	&pshufb	("xmm4","xmm2");		# 4 = sb1u
-+	&pshufb	("xmm0","xmm3");		# 0 = sb1t
-+	&pxor	("xmm4","xmm5");		# 4 = sb1u + k
-+	&movdqa	("xmm5",&QWP($k_sb2,$const));	# 4 : sb2u
-+	&pxor	("xmm0","xmm4");		# 0 = A
-+	&movdqa	("xmm1",&QWP(-0x40,$base,$magic));# .Lk_mc_forward[]
-+	&pshufb	("xmm5","xmm2");		# 4 = sb2u
-+	&movdqa	("xmm2",&QWP($k_sb2+16,$const));# 2 : sb2t
-+	&movdqa	("xmm4",&QWP(0,$base,$magic));	# .Lk_mc_backward[]
-+	&pshufb	("xmm2","xmm3");		# 2 = sb2t
-+	&movdqa	("xmm3","xmm0");		# 3 = A
-+	&pxor	("xmm2","xmm5");		# 2 = 2A
-+	&pshufb	("xmm0","xmm1");		# 0 = B
-+	&add	($key,16);			# next key
-+	&pxor	("xmm0","xmm2");		# 0 = 2A+B
-+	&pshufb	("xmm3","xmm4");		# 3 = D
-+	&add	($magic,16);			# next mc
-+	&pxor	("xmm3","xmm0");		# 3 = 2A+B+D
-+	&pshufb	("xmm0","xmm1");		# 0 = 2B+C
-+	&and	($magic,0x30);			# ... mod 4
-+	&sub	($round,1);			# nr--
-+	&pxor	("xmm0","xmm3");		# 0 = 2A+3B+C+D
-+
-+&set_label("enc_entry");
-+	# top of round
-+	&movdqa	("xmm1","xmm6");		# 1 : i
-+	&movdqa	("xmm5",&QWP($k_inv+16,$const));# 2 : a/k
-+	&pandn	("xmm1","xmm0");		# 1 = i<<4
-+	&psrld	("xmm1",4);			# 1 = i
-+	&pand	("xmm0","xmm6");		# 0 = k
-+	&pshufb	("xmm5","xmm0");		# 2 = a/k
-+	&movdqa	("xmm3","xmm7");		# 3 : 1/i
-+	&pxor	("xmm0","xmm1");		# 0 = j
-+	&pshufb	("xmm3","xmm1");		# 3 = 1/i
-+	&movdqa	("xmm4","xmm7");		# 4 : 1/j
-+	&pxor	("xmm3","xmm5");		# 3 = iak = 1/i + a/k
-+	&pshufb	("xmm4","xmm0");		# 4 = 1/j
-+	&movdqa	("xmm2","xmm7");		# 2 : 1/iak
-+	&pxor	("xmm4","xmm5");		# 4 = jak = 1/j + a/k
-+	&pshufb	("xmm2","xmm3");		# 2 = 1/iak
-+	&movdqa	("xmm3","xmm7");		# 3 : 1/jak
-+	&pxor	("xmm2","xmm0");		# 2 = io
-+	&pshufb	("xmm3","xmm4");		# 3 = 1/jak
-+	&movdqu	("xmm5",&QWP(0,$key));
-+	&pxor	("xmm3","xmm1");		# 3 = jo
-+	&jnz	(&label("enc_loop"));
-+
-+	# middle of last round
-+	&movdqa	("xmm4",&QWP($k_sbo,$const));	# 3 : sbou      .Lk_sbo
-+	&movdqa	("xmm0",&QWP($k_sbo+16,$const));# 3 : sbot      .Lk_sbo+16
-+	&pshufb	("xmm4","xmm2");		# 4 = sbou
-+	&pxor	("xmm4","xmm5");		# 4 = sb1u + k
-+	&pshufb	("xmm0","xmm3");		# 0 = sb1t
-+	&movdqa	("xmm1",&QWP(0x40,$base,$magic));# .Lk_sr[]
-+	&pxor	("xmm0","xmm4");		# 0 = A
-+	&pshufb	("xmm0","xmm1");
-+	&ret	();
-+&function_end_B("_vpaes_encrypt_core");
-+
-+##
-+##  Decryption core
-+##
-+##  Same API as encryption core.
-+##
-+&function_begin_B("_vpaes_decrypt_core");
-+	&lea	($base,&DWP($k_dsbd,$const));
-+	&mov	($round,&DWP(240,$key));
-+	&movdqa	("xmm1","xmm6");
-+	&movdqa	("xmm2",&QWP($k_dipt-$k_dsbd,$base));
-+	&pandn	("xmm1","xmm0");
-+	&mov	($magic,$round);
-+	&psrld	("xmm1",4)
-+	&movdqu	("xmm5",&QWP(0,$key));
-+	&shl	($magic,4);
-+	&pand	("xmm0","xmm6");
-+	&pshufb	("xmm2","xmm0");
-+	&movdqa	("xmm0",&QWP($k_dipt-$k_dsbd+16,$base));
-+	&xor	($magic,0x30);
-+	&pshufb	("xmm0","xmm1");
-+	&and	($magic,0x30);
-+	&pxor	("xmm2","xmm5");
-+	&movdqa	("xmm5",&QWP($k_mc_forward+48,$const));
-+	&pxor	("xmm0","xmm2");
-+	&add	($key,16);
-+	&lea	($magic,&DWP($k_sr-$k_dsbd,$base,$magic));
-+	&jmp	(&label("dec_entry"));
-+
-+&set_label("dec_loop",16);
-+##
-+##  Inverse mix columns
-+##
-+	&movdqa	("xmm4",&QWP(-0x20,$base));	# 4 : sb9u
-+	&movdqa	("xmm1",&QWP(-0x10,$base));	# 0 : sb9t
-+	&pshufb	("xmm4","xmm2");		# 4 = sb9u
-+	&pshufb	("xmm1","xmm3");		# 0 = sb9t
-+	&pxor	("xmm0","xmm4");
-+	&movdqa	("xmm4",&QWP(0,$base));		# 4 : sbdu
-+	&pxor	("xmm0","xmm1");		# 0 = ch
-+	&movdqa	("xmm1",&QWP(0x10,$base));	# 0 : sbdt
-+
-+	&pshufb	("xmm4","xmm2");		# 4 = sbdu
-+	&pshufb	("xmm0","xmm5");		# MC ch
-+	&pshufb	("xmm1","xmm3");		# 0 = sbdt
-+	&pxor	("xmm0","xmm4");		# 4 = ch
-+	&movdqa	("xmm4",&QWP(0x20,$base));	# 4 : sbbu
-+	&pxor	("xmm0","xmm1");		# 0 = ch
-+	&movdqa	("xmm1",&QWP(0x30,$base));	# 0 : sbbt
-+
-+	&pshufb	("xmm4","xmm2");		# 4 = sbbu
-+	&pshufb	("xmm0","xmm5");		# MC ch
-+	&pshufb	("xmm1","xmm3");		# 0 = sbbt
-+	&pxor	("xmm0","xmm4");		# 4 = ch
-+	&movdqa	("xmm4",&QWP(0x40,$base));	# 4 : sbeu
-+	&pxor	("xmm0","xmm1");		# 0 = ch
-+	&movdqa	("xmm1",&QWP(0x50,$base));	# 0 : sbet
-+
-+	&pshufb	("xmm4","xmm2");		# 4 = sbeu
-+	&pshufb	("xmm0","xmm5");		# MC ch
-+	&pshufb	("xmm1","xmm3");		# 0 = sbet
-+	&pxor	("xmm0","xmm4");		# 4 = ch
-+	&add	($key,16);			# next round key
-+	&palignr("xmm5","xmm5",12);
-+	&pxor	("xmm0","xmm1");		# 0 = ch
-+	&sub	($round,1);			# nr--
-+
-+&set_label("dec_entry");
-+	# top of round
-+	&movdqa	("xmm1","xmm6");		# 1 : i
-+	&movdqa	("xmm2",&QWP($k_inv+16,$const));# 2 : a/k
-+	&pandn	("xmm1","xmm0");		# 1 = i<<4
-+	&pand	("xmm0","xmm6");		# 0 = k
-+	&psrld	("xmm1",4);			# 1 = i
-+	&pshufb	("xmm2","xmm0");		# 2 = a/k
-+	&movdqa	("xmm3","xmm7");		# 3 : 1/i
-+	&pxor	("xmm0","xmm1");		# 0 = j
-+	&pshufb	("xmm3","xmm1");		# 3 = 1/i
-+	&movdqa	("xmm4","xmm7");		# 4 : 1/j
-+	&pxor	("xmm3","xmm2");		# 3 = iak = 1/i + a/k
-+	&pshufb	("xmm4","xmm0");		# 4 = 1/j
-+	&pxor	("xmm4","xmm2");		# 4 = jak = 1/j + a/k
-+	&movdqa	("xmm2","xmm7");		# 2 : 1/iak
-+	&pshufb	("xmm2","xmm3");		# 2 = 1/iak
-+	&movdqa	("xmm3","xmm7");		# 3 : 1/jak
-+	&pxor	("xmm2","xmm0");		# 2 = io
-+	&pshufb	("xmm3","xmm4");		# 3 = 1/jak
-+	&movdqu	("xmm0",&QWP(0,$key));
-+	&pxor	("xmm3","xmm1");		# 3 = jo
-+	&jnz	(&label("dec_loop"));
-+
-+	# middle of last round
-+	&movdqa	("xmm4",&QWP(0x60,$base));	# 3 : sbou
-+	&pshufb	("xmm4","xmm2");		# 4 = sbou
-+	&pxor	("xmm4","xmm0");		# 4 = sb1u + k
-+	&movdqa	("xmm0",&QWP(0x70,$base));	# 0 : sbot
-+	&movdqa	("xmm2",&QWP(0,$magic));
-+	&pshufb	("xmm0","xmm3");		# 0 = sb1t
-+	&pxor	("xmm0","xmm4");		# 0 = A
-+	&pshufb	("xmm0","xmm2");
-+	&ret	();
-+&function_end_B("_vpaes_decrypt_core");
-+
-+########################################################
-+##                                                    ##
-+##                  AES key schedule                  ##
-+##                                                    ##
-+########################################################
-+&function_begin_B("_vpaes_schedule_core");
-+	&add	($const,&DWP(0,"esp"));
-+	&movdqu	("xmm0",&QWP(0,$inp));		# load key (unaligned)
-+	&movdqa	("xmm2",&QWP($k_rcon,$const));	# load rcon
-+
-+	# input transform
-+	&movdqa	("xmm3","xmm0");
-+	&lea	($base,&DWP($k_ipt,$const));
-+	&movdqa	(&QWP(4,"esp"),"xmm2");		# xmm8
-+	&call	("_vpaes_schedule_transform");
-+	&movdqa	("xmm7","xmm0");
-+
-+	&test	($out,$out);
-+	&jnz	(&label("schedule_am_decrypting"));
-+
-+	# encrypting, output zeroth round key after transform
-+	&movdqu	(&QWP(0,$key),"xmm0");
-+	&jmp	(&label("schedule_go"));
-+
-+&set_label("schedule_am_decrypting");
-+	# decrypting, output zeroth round key after shiftrows
-+	&movdqa	("xmm1",&QWP($k_sr,$const,$magic));
-+	&pshufb	("xmm3","xmm1");
-+	&movdqu	(&QWP(0,$key),"xmm3");
-+	&xor	($magic,0x30);
-+
-+&set_label("schedule_go");
-+	&cmp	($round,192);
-+	&ja	(&label("schedule_256"));
-+	&je	(&label("schedule_192"));
-+	# 128: fall though
-+
-+##
-+##  .schedule_128
-+##
-+##  128-bit specific part of key schedule.
-+##
-+##  This schedule is really simple, because all its parts
-+##  are accomplished by the subroutines.
-+##
-+&set_label("schedule_128");
-+	&mov	($round,10);
-+
-+&set_label("loop_schedule_128");
-+	&call	("_vpaes_schedule_round");
-+	&dec	($round);
-+	&jz	(&label("schedule_mangle_last"));
-+	&call	("_vpaes_schedule_mangle");	# write output
-+	&jmp	(&label("loop_schedule_128"));
-+
-+##
-+##  .aes_schedule_192
-+##
-+##  192-bit specific part of key schedule.
-+##
-+##  The main body of this schedule is the same as the 128-bit
-+##  schedule, but with more smearing.  The long, high side is
-+##  stored in %xmm7 as before, and the short, low side is in
-+##  the high bits of %xmm6.
-+##
-+##  This schedule is somewhat nastier, however, because each
-+##  round produces 192 bits of key material, or 1.5 round keys.
-+##  Therefore, on each cycle we do 2 rounds and produce 3 round
-+##  keys.
-+##
-+&set_label("schedule_192",16);
-+	&movdqu	("xmm0",&QWP(8,$inp));		# load key part 2 (very unaligned)
-+	&call	("_vpaes_schedule_transform");	# input transform	
-+	&movdqa	("xmm6","xmm0");		# save short part
-+	&pxor	("xmm4","xmm4");		# clear 4
-+	&movhlps("xmm6","xmm4");		# clobber low side with zeros
-+	&mov	($round,4);
-+
-+&set_label("loop_schedule_192");
-+	&call	("_vpaes_schedule_round");
-+	&palignr("xmm0","xmm6",8);
-+	&call	("_vpaes_schedule_mangle");	# save key n
-+	&call	("_vpaes_schedule_192_smear");
-+	&call	("_vpaes_schedule_mangle");	# save key n+1
-+	&call	("_vpaes_schedule_round");
-+	&dec	($round);
-+	&jz	(&label("schedule_mangle_last"));
-+	&call	("_vpaes_schedule_mangle");	# save key n+2
-+	&call	("_vpaes_schedule_192_smear");
-+	&jmp	(&label("loop_schedule_192"));
-+
-+##
-+##  .aes_schedule_256
-+##
-+##  256-bit specific part of key schedule.
-+##
-+##  The structure here is very similar to the 128-bit
-+##  schedule, but with an additional "low side" in
-+##  %xmm6.  The low side's rounds are the same as the
-+##  high side's, except no rcon and no rotation.
-+##
-+&set_label("schedule_256",16);
-+	&movdqu	("xmm0",&QWP(16,$inp));		# load key part 2 (unaligned)
-+	&call	("_vpaes_schedule_transform");	# input transform	
-+	&mov	($round,7);
-+
-+&set_label("loop_schedule_256");
-+	&call	("_vpaes_schedule_mangle");	# output low result
-+	&movdqa	("xmm6","xmm0");		# save cur_lo in xmm6
-+
-+	# high round
-+	&call	("_vpaes_schedule_round");
-+	&dec	($round);
-+	&jz	(&label("schedule_mangle_last"));
-+	&call	("_vpaes_schedule_mangle");	
-+
-+	# low round. swap xmm7 and xmm6
-+	&pshufd	("xmm0","xmm0",0xFF);
-+	&movdqa	(&QWP(20,"esp"),"xmm7");
-+	&movdqa	("xmm7","xmm6");
-+	&call	("_vpaes_schedule_low_round");
-+	&movdqa	("xmm7",&QWP(20,"esp"));
-+
-+	&jmp	(&label("loop_schedule_256"));
-+
-+##
-+##  .aes_schedule_mangle_last
-+##
-+##  Mangler for last round of key schedule
-+##  Mangles %xmm0
-+##    when encrypting, outputs out(%xmm0) ^ 63
-+##    when decrypting, outputs unskew(%xmm0)
-+##
-+##  Always called right before return... jumps to cleanup and exits
-+##
-+&set_label("schedule_mangle_last",16);
-+	# schedule last round key from xmm0
-+	&lea	($base,&DWP($k_deskew,$const));
-+	&test	($out,$out);
-+	&jnz	(&label("schedule_mangle_last_dec"));
-+
-+	# encrypting
-+	&movdqa	("xmm1",&QWP($k_sr,$const,$magic));
-+	&pshufb	("xmm0","xmm1");		# output permute
-+	&lea	($base,&DWP($k_opt,$const));	# prepare to output transform
-+	&add	($key,32);
-+
-+&set_label("schedule_mangle_last_dec");
-+	&add	($key,-16);
-+	&pxor	("xmm0",&QWP($k_s63,$const));
-+	&call	("_vpaes_schedule_transform");	# output transform
-+	&movdqu	(&QWP(0,$key),"xmm0");		# save last key
-+
-+	# cleanup
-+	&pxor	("xmm0","xmm0");
-+	&pxor	("xmm1","xmm1");
-+	&pxor	("xmm2","xmm2");
-+	&pxor	("xmm3","xmm3");
-+	&pxor	("xmm4","xmm4");
-+	&pxor	("xmm5","xmm5");
-+	&pxor	("xmm6","xmm6");
-+	&pxor	("xmm7","xmm7");
-+	&ret	();
-+&function_end_B("_vpaes_schedule_core");
-+
-+##
-+##  .aes_schedule_192_smear
-+##
-+##  Smear the short, low side in the 192-bit key schedule.
-+##
-+##  Inputs:
-+##    %xmm7: high side, b  a  x  y
-+##    %xmm6:  low side, d  c  0  0
-+##    %xmm13: 0
-+##
-+##  Outputs:
-+##    %xmm6: b+c+d  b+c  0  0
-+##    %xmm0: b+c+d  b+c  b  a
-+##
-+&function_begin_B("_vpaes_schedule_192_smear");
-+	&pshufd	("xmm1","xmm6",0x80);		# d c 0 0 -> c 0 0 0
-+	&pshufd	("xmm0","xmm7",0xFE);		# b a _ _ -> b b b a
-+	&pxor	("xmm6","xmm1");		# -> c+d c 0 0
-+	&pxor	("xmm1","xmm1");
-+	&pxor	("xmm6","xmm0");		# -> b+c+d b+c b a
-+	&movdqa	("xmm0","xmm6");
-+	&movhlps("xmm6","xmm1");		# clobber low side with zeros
-+	&ret	();
-+&function_end_B("_vpaes_schedule_192_smear");
-+
-+##
-+##  .aes_schedule_round
-+##
-+##  Runs one main round of the key schedule on %xmm0, %xmm7
-+##
-+##  Specifically, runs subbytes on the high dword of %xmm0
-+##  then rotates it by one byte and xors into the low dword of
-+##  %xmm7.
-+##
-+##  Adds rcon from low byte of %xmm8, then rotates %xmm8 for
-+##  next rcon.
-+##
-+##  Smears the dwords of %xmm7 by xoring the low into the
-+##  second low, result into third, result into highest.
-+##
-+##  Returns results in %xmm7 = %xmm0.
-+##  Clobbers %xmm1-%xmm5.
-+##
-+&function_begin_B("_vpaes_schedule_round");
-+	# extract rcon from xmm8
-+	&movdqa	("xmm2",&QWP(8,"esp"));		# xmm8
-+	&pxor	("xmm1","xmm1");
-+	&palignr("xmm1","xmm2",15);
-+	&palignr("xmm2","xmm2",15);
-+	&pxor	("xmm7","xmm1");
-+
-+	# rotate
-+	&pshufd	("xmm0","xmm0",0xFF);
-+	&palignr("xmm0","xmm0",1);
-+
-+	# fall through...
-+	&movdqa	(&QWP(8,"esp"),"xmm2");		# xmm8
-+
-+	# low round: same as high round, but no rotation and no rcon.
-+&set_label("_vpaes_schedule_low_round");
-+	# smear xmm7
-+	&movdqa	("xmm1","xmm7");
-+	&pslldq	("xmm7",4);
-+	&pxor	("xmm7","xmm1");
-+	&movdqa	("xmm1","xmm7");
-+	&pslldq	("xmm7",8);
-+	&pxor	("xmm7","xmm1");
-+	&pxor	("xmm7",&QWP($k_s63,$const));
-+
-+	# subbyte
-+	&movdqa	("xmm4",&QWP($k_s0F,$const));
-+	&movdqa	("xmm5",&QWP($k_inv,$const));	# 4 : 1/j
-+	&movdqa	("xmm1","xmm4");	
-+	&pandn	("xmm1","xmm0");
-+	&psrld	("xmm1",4);			# 1 = i
-+	&pand	("xmm0","xmm4");		# 0 = k
-+	&movdqa	("xmm2",&QWP($k_inv+16,$const));# 2 : a/k
-+	&pshufb	("xmm2","xmm0");		# 2 = a/k
-+	&pxor	("xmm0","xmm1");		# 0 = j
-+	&movdqa	("xmm3","xmm5");		# 3 : 1/i
-+	&pshufb	("xmm3","xmm1");		# 3 = 1/i
-+	&pxor	("xmm3","xmm2");		# 3 = iak = 1/i + a/k
-+	&movdqa	("xmm4","xmm5");		# 4 : 1/j
-+	&pshufb	("xmm4","xmm0");		# 4 = 1/j
-+	&pxor	("xmm4","xmm2");		# 4 = jak = 1/j + a/k
-+	&movdqa	("xmm2","xmm5");		# 2 : 1/iak
-+	&pshufb	("xmm2","xmm3");		# 2 = 1/iak
-+	&pxor	("xmm2","xmm0");		# 2 = io
-+	&movdqa	("xmm3","xmm5");		# 3 : 1/jak
-+	&pshufb	("xmm3","xmm4");		# 3 = 1/jak
-+	&pxor	("xmm3","xmm1");		# 3 = jo
-+	&movdqa	("xmm4",&QWP($k_sb1,$const));	# 4 : sbou
-+	&pshufb	("xmm4","xmm2");		# 4 = sbou
-+	&movdqa	("xmm0",&QWP($k_sb1+16,$const));# 0 : sbot
-+	&pshufb	("xmm0","xmm3");		# 0 = sb1t
-+	&pxor	("xmm0","xmm4");		# 0 = sbox output
-+
-+	# add in smeared stuff
-+	&pxor	("xmm0","xmm7");
-+	&movdqa	("xmm7","xmm0");
-+	&ret	();
-+&function_end_B("_vpaes_schedule_round");
-+
-+##
-+##  .aes_schedule_transform
-+##
-+##  Linear-transform %xmm0 according to tables at (%ebx)
-+##
-+##  Output in %xmm0
-+##  Clobbers %xmm1, %xmm2
-+##
-+&function_begin_B("_vpaes_schedule_transform");
-+	&movdqa	("xmm2",&QWP($k_s0F,$const));
-+	&movdqa	("xmm1","xmm2");
-+	&pandn	("xmm1","xmm0");
-+	&psrld	("xmm1",4);
-+	&pand	("xmm0","xmm2");
-+	&movdqa	("xmm2",&QWP(0,$base));
-+	&pshufb	("xmm2","xmm0");
-+	&movdqa	("xmm0",&QWP(16,$base));
-+	&pshufb	("xmm0","xmm1");
-+	&pxor	("xmm0","xmm2");
-+	&ret	();
-+&function_end_B("_vpaes_schedule_transform");
-+
-+##
-+##  .aes_schedule_mangle
-+##
-+##  Mangle xmm0 from (basis-transformed) standard version
-+##  to our version.
-+##
-+##  On encrypt,
-+##    xor with 0x63
-+##    multiply by circulant 0,1,1,1
-+##    apply shiftrows transform
-+##
-+##  On decrypt,
-+##    xor with 0x63
-+##    multiply by "inverse mixcolumns" circulant E,B,D,9
-+##    deskew
-+##    apply shiftrows transform
-+##
-+##
-+##  Writes out to (%edx), and increments or decrements it
-+##  Keeps track of round number mod 4 in %ecx
-+##  Preserves xmm0
-+##  Clobbers xmm1-xmm5
-+##
-+&function_begin_B("_vpaes_schedule_mangle");
-+	&movdqa	("xmm4","xmm0");	# save xmm0 for later
-+	&movdqa	("xmm5",&QWP($k_mc_forward,$const));
-+	&test	($out,$out);
-+	&jnz	(&label("schedule_mangle_dec"));
-+
-+	# encrypting
-+	&add	($key,16);
-+	&pxor	("xmm4",&QWP($k_s63,$const));
-+	&pshufb	("xmm4","xmm5");
-+	&movdqa	("xmm3","xmm4");
-+	&pshufb	("xmm4","xmm5");
-+	&pxor	("xmm3","xmm4");
-+	&pshufb	("xmm4","xmm5");
-+	&pxor	("xmm3","xmm4");
-+
-+	&jmp	(&label("schedule_mangle_both"));
-+
-+&set_label("schedule_mangle_dec",16);
-+	# inverse mix columns
-+	&movdqa	("xmm2",&QWP($k_s0F,$const));
-+	&lea	($inp,&DWP($k_dksd,$const));
-+	&movdqa	("xmm1","xmm2");
-+	&pandn	("xmm1","xmm4");
-+	&psrld	("xmm1",4);			# 1 = hi
-+	&pand	("xmm4","xmm2");		# 4 = lo
-+
-+	&movdqa	("xmm2",&QWP(0,$inp));
-+	&pshufb	("xmm2","xmm4");
-+	&movdqa	("xmm3",&QWP(0x10,$inp));
-+	&pshufb	("xmm3","xmm1");
-+	&pxor	("xmm3","xmm2");
-+	&pshufb	("xmm3","xmm5");
-+
-+	&movdqa	("xmm2",&QWP(0x20,$inp));
-+	&pshufb	("xmm2","xmm4");
-+	&pxor	("xmm2","xmm3");
-+	&movdqa	("xmm3",&QWP(0x30,$inp));
-+	&pshufb	("xmm3","xmm1");
-+	&pxor	("xmm3","xmm2");
-+	&pshufb	("xmm3","xmm5");
-+
-+	&movdqa	("xmm2",&QWP(0x40,$inp));
-+	&pshufb	("xmm2","xmm4");
-+	&pxor	("xmm2","xmm3");
-+	&movdqa	("xmm3",&QWP(0x50,$inp));
-+	&pshufb	("xmm3","xmm1");
-+	&pxor	("xmm3","xmm2");
-+	&pshufb	("xmm3","xmm5");
-+
-+	&movdqa	("xmm2",&QWP(0x60,$inp));
-+	&pshufb	("xmm2","xmm4");
-+	&pxor	("xmm2","xmm3");
-+	&movdqa	("xmm3",&QWP(0x70,$inp));
-+	&pshufb	("xmm3","xmm1");
-+	&pxor	("xmm3","xmm2");
-+
-+	&add	($key,-16);
-+
-+&set_label("schedule_mangle_both");
-+	&movdqa	("xmm1",&QWP($k_sr,$const,$magic));
-+	&pshufb	("xmm3","xmm1");
-+	&add	($magic,-16);
-+	&and	($magic,0x30);
-+	&movdqu	(&QWP(0,$key),"xmm3");
-+	&ret	();
-+&function_end_B("_vpaes_schedule_mangle");
-+
-+#
-+# Interface to OpenSSL
-+#
-+&function_begin("${PREFIX}_set_encrypt_key");
-+	&mov	($inp,&wparam(0));		# inp
-+	&lea	($base,&DWP(-56,"esp"));
-+	&mov	($round,&wparam(1));		# bits
-+	&and	($base,-16);
-+	&mov	($key,&wparam(2));		# key
-+	&xchg	($base,"esp");			# alloca
-+	&mov	(&DWP(48,"esp"),$base);
-+
-+	&mov	($base,$round);
-+	&shr	($base,5);
-+	&add	($base,5);
-+	&mov	(&DWP(240,$key),$base);		# AES_KEY->rounds = nbits/32+5;
-+	&mov	($magic,0x30);
-+	&mov	($out,0);
-+
-+	&lea	($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
-+	&call	("_vpaes_schedule_core");
-+&set_label("pic_point");
-+
-+	&mov	("esp",&DWP(48,"esp"));
-+	&xor	("eax","eax");
-+&function_end("${PREFIX}_set_encrypt_key");
-+
-+&function_begin("${PREFIX}_set_decrypt_key");
-+	&mov	($inp,&wparam(0));		# inp
-+	&lea	($base,&DWP(-56,"esp"));
-+	&mov	($round,&wparam(1));		# bits
-+	&and	($base,-16);
-+	&mov	($key,&wparam(2));		# key
-+	&xchg	($base,"esp");			# alloca
-+	&mov	(&DWP(48,"esp"),$base);
-+
-+	&mov	($base,$round);
-+	&shr	($base,5);
-+	&add	($base,5);
-+	&mov	(&DWP(240,$key),$base);	# AES_KEY->rounds = nbits/32+5;
-+	&shl	($base,4);
-+	&lea	($key,&DWP(16,$key,$base));
-+
-+	&mov	($out,1);
-+	&mov	($magic,$round);
-+	&shr	($magic,1);
-+	&and	($magic,32);
-+	&xor	($magic,32);			# nbist==192?0:32;
-+
-+	&lea	($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
-+	&call	("_vpaes_schedule_core");
-+&set_label("pic_point");
-+
-+	&mov	("esp",&DWP(48,"esp"));
-+	&xor	("eax","eax");
-+&function_end("${PREFIX}_set_decrypt_key");
-+
-+&function_begin("${PREFIX}_encrypt");
-+	&lea	($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
-+	&call	("_vpaes_preheat");
-+&set_label("pic_point");
-+	&mov	($inp,&wparam(0));		# inp
-+	&lea	($base,&DWP(-56,"esp"));
-+	&mov	($out,&wparam(1));		# out
-+	&and	($base,-16);
-+	&mov	($key,&wparam(2));		# key
-+	&xchg	($base,"esp");			# alloca
-+	&mov	(&DWP(48,"esp"),$base);
-+
-+	&movdqu	("xmm0",&QWP(0,$inp));
-+	&call	("_vpaes_encrypt_core");
-+	&movdqu	(&QWP(0,$out),"xmm0");
-+
-+	&mov	("esp",&DWP(48,"esp"));
-+&function_end("${PREFIX}_encrypt");
-+
-+&function_begin("${PREFIX}_decrypt");
-+	&lea	($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
-+	&call	("_vpaes_preheat");
-+&set_label("pic_point");
-+	&mov	($inp,&wparam(0));		# inp
-+	&lea	($base,&DWP(-56,"esp"));
-+	&mov	($out,&wparam(1));		# out
-+	&and	($base,-16);
-+	&mov	($key,&wparam(2));		# key
-+	&xchg	($base,"esp");			# alloca
-+	&mov	(&DWP(48,"esp"),$base);
-+
-+	&movdqu	("xmm0",&QWP(0,$inp));
-+	&call	("_vpaes_decrypt_core");
-+	&movdqu	(&QWP(0,$out),"xmm0");
-+
-+	&mov	("esp",&DWP(48,"esp"));
-+&function_end("${PREFIX}_decrypt");
-+
-+&function_begin("${PREFIX}_cbc_encrypt");
-+	&mov	($inp,&wparam(0));		# inp
-+	&mov	($out,&wparam(1));		# out
-+	&mov	($round,&wparam(2));		# len
-+	&mov	($key,&wparam(3));		# key
-+	&sub	($round,16);
-+	&jc	(&label("cbc_abort"));
-+	&lea	($base,&DWP(-56,"esp"));
-+	&mov	($const,&wparam(4));		# ivp
-+	&and	($base,-16);
-+	&mov	($magic,&wparam(5));		# enc
-+	&xchg	($base,"esp");			# alloca
-+	&movdqu	("xmm1",&QWP(0,$const));	# load IV
-+	&sub	($out,$inp);
-+	&mov	(&DWP(48,"esp"),$base);
-+
-+	&mov	(&DWP(0,"esp"),$out);		# save out
-+	&mov	(&DWP(4,"esp"),$key)		# save key
-+	&mov	(&DWP(8,"esp"),$const);		# save ivp
-+	&mov	($out,$round);			# $out works as $len
-+
-+	&lea	($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point")));
-+	&call	("_vpaes_preheat");
-+&set_label("pic_point");
-+	&cmp	($magic,0);
-+	&je	(&label("cbc_dec_loop"));
-+	&jmp	(&label("cbc_enc_loop"));
-+
-+&set_label("cbc_enc_loop",16);
-+	&movdqu	("xmm0",&QWP(0,$inp));		# load input
-+	&pxor	("xmm0","xmm1");		# inp^=iv
-+	&call	("_vpaes_encrypt_core");
-+	&mov	($base,&DWP(0,"esp"));		# restore out
-+	&mov	($key,&DWP(4,"esp"));		# restore key
-+	&movdqa	("xmm1","xmm0");
-+	&movdqu	(&QWP(0,$base,$inp),"xmm0");	# write output
-+	&lea	($inp,&DWP(16,$inp));
-+	&sub	($out,16);
-+	&jnc	(&label("cbc_enc_loop"));
-+	&jmp	(&label("cbc_done"));
-+
-+&set_label("cbc_dec_loop",16);
-+	&movdqu	("xmm0",&QWP(0,$inp));		# load input
-+	&movdqa	(&QWP(16,"esp"),"xmm1");	# save IV
-+	&movdqa	(&QWP(32,"esp"),"xmm0");	# save future IV
-+	&call	("_vpaes_decrypt_core");
-+	&mov	($base,&DWP(0,"esp"));		# restore out
-+	&mov	($key,&DWP(4,"esp"));		# restore key
-+	&pxor	("xmm0",&QWP(16,"esp"));	# out^=iv
-+	&movdqa	("xmm1",&QWP(32,"esp"));	# load next IV
-+	&movdqu	(&QWP(0,$base,$inp),"xmm0");	# write output
-+	&lea	($inp,&DWP(16,$inp));
-+	&sub	($out,16);
-+	&jnc	(&label("cbc_dec_loop"));
-+
-+&set_label("cbc_done");
-+	&mov	($base,&DWP(8,"esp"));		# restore ivp
-+	&mov	("esp",&DWP(48,"esp"));
-+	&movdqu	(&QWP(0,$base),"xmm1");		# write IV
-+&set_label("cbc_abort");
-+&function_end("${PREFIX}_cbc_encrypt");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-x86_64.pl
-new file mode 100644
-index 0000000..422e8ee
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/asm/vpaes-x86_64.pl
-@@ -0,0 +1,1215 @@
-+#! /usr/bin/env perl
-+# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+######################################################################
-+## Constant-time SSSE3 AES core implementation.
-+## version 0.1
-+##
-+## By Mike Hamburg (Stanford University), 2009
-+## Public domain.
-+##
-+## For details see http://shiftleft.org/papers/vector_aes/ and
-+## http://crypto.stanford.edu/vpaes/.
-+
-+######################################################################
-+# September 2011.
-+#
-+# Interface to OpenSSL as "almost" drop-in replacement for
-+# aes-x86_64.pl. "Almost" refers to the fact that AES_cbc_encrypt
-+# doesn't handle partial vectors (doesn't have to if called from
-+# EVP only). "Drop-in" implies that this module doesn't share key
-+# schedule structure with the original nor does it make assumption
-+# about its alignment...
-+#
-+# Performance summary. aes-x86_64.pl column lists large-block CBC
-+# encrypt/decrypt/with-hyper-threading-off(*) results in cycles per
-+# byte processed with 128-bit key, and vpaes-x86_64.pl column -
-+# [also large-block CBC] encrypt/decrypt.
-+#
-+#		aes-x86_64.pl		vpaes-x86_64.pl
-+#
-+# Core 2(**)	29.6/41.1/14.3		21.9/25.2(***)
-+# Nehalem	29.6/40.3/14.6		10.0/11.8
-+# Atom		57.3/74.2/32.1		60.9/77.2(***)
-+# Silvermont	52.7/64.0/19.5		48.8/60.8(***)
-+# Goldmont	38.9/49.0/17.8		10.6/12.6
-+#
-+# (*)	"Hyper-threading" in the context refers rather to cache shared
-+#	among multiple cores, than to specifically Intel HTT. As vast
-+#	majority of contemporary cores share cache, slower code path
-+#	is common place. In other words "with-hyper-threading-off"
-+#	results are presented mostly for reference purposes.
-+#
-+# (**)	"Core 2" refers to initial 65nm design, a.k.a. Conroe.
-+#
-+# (***)	Less impressive improvement on Core 2 and Atom is due to slow
-+#	pshufb,	yet it's respectable +36%/62% improvement on Core 2
-+#	(as implied, over "hyper-threading-safe" code path).
-+#
-+#						
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+$PREFIX="vpaes";
-+
-+$code.=<<___;
-+.text
-+
-+##
-+##  _aes_encrypt_core
-+##
-+##  AES-encrypt %xmm0.
-+##
-+##  Inputs:
-+##     %xmm0 = input
-+##     %xmm9-%xmm15 as in _vpaes_preheat
-+##    (%rdx) = scheduled keys
-+##
-+##  Output in %xmm0
-+##  Clobbers  %xmm1-%xmm5, %r9, %r10, %r11, %rax
-+##  Preserves %xmm6 - %xmm8 so you get some local vectors
-+##
-+##
-+.type	_vpaes_encrypt_core,\@abi-omnipotent
-+.align 16
-+_vpaes_encrypt_core:
-+	mov	%rdx,	%r9
-+	mov	\$16,	%r11
-+	mov	240(%rdx),%eax
-+	movdqa	%xmm9,	%xmm1
-+	movdqa	.Lk_ipt(%rip), %xmm2	# iptlo
-+	pandn	%xmm0,	%xmm1
-+	movdqu	(%r9),	%xmm5		# round0 key
-+	psrld	\$4,	%xmm1
-+	pand	%xmm9,	%xmm0
-+	pshufb	%xmm0,	%xmm2
-+	movdqa	.Lk_ipt+16(%rip), %xmm0	# ipthi
-+	pshufb	%xmm1,	%xmm0
-+	pxor	%xmm5,	%xmm2
-+	add	\$16,	%r9
-+	pxor	%xmm2,	%xmm0
-+	lea	.Lk_mc_backward(%rip),%r10
-+	jmp	.Lenc_entry
-+
-+.align 16
-+.Lenc_loop:
-+	# middle of middle round
-+	movdqa  %xmm13,	%xmm4	# 4 : sb1u
-+	movdqa  %xmm12,	%xmm0	# 0 : sb1t
-+	pshufb  %xmm2,	%xmm4	# 4 = sb1u
-+	pshufb  %xmm3,	%xmm0	# 0 = sb1t
-+	pxor	%xmm5,	%xmm4	# 4 = sb1u + k
-+	movdqa  %xmm15,	%xmm5	# 4 : sb2u
-+	pxor	%xmm4,	%xmm0	# 0 = A
-+	movdqa	-0x40(%r11,%r10), %xmm1		# .Lk_mc_forward[]
-+	pshufb	%xmm2,	%xmm5	# 4 = sb2u
-+	movdqa	(%r11,%r10), %xmm4		# .Lk_mc_backward[]
-+	movdqa	%xmm14, %xmm2	# 2 : sb2t
-+	pshufb	%xmm3,  %xmm2	# 2 = sb2t
-+	movdqa	%xmm0,  %xmm3	# 3 = A
-+	pxor	%xmm5,	%xmm2	# 2 = 2A
-+	pshufb  %xmm1,  %xmm0	# 0 = B
-+	add	\$16,	%r9	# next key
-+	pxor	%xmm2,  %xmm0	# 0 = 2A+B
-+	pshufb	%xmm4,	%xmm3	# 3 = D
-+	add	\$16,	%r11	# next mc
-+	pxor	%xmm0,	%xmm3	# 3 = 2A+B+D
-+	pshufb  %xmm1,	%xmm0	# 0 = 2B+C
-+	and	\$0x30,	%r11	# ... mod 4
-+	sub	\$1,%rax	# nr--
-+	pxor	%xmm3,	%xmm0	# 0 = 2A+3B+C+D
-+
-+.Lenc_entry:
-+	# top of round
-+	movdqa  %xmm9, 	%xmm1	# 1 : i
-+	movdqa	%xmm11, %xmm5	# 2 : a/k
-+	pandn	%xmm0, 	%xmm1	# 1 = i<<4
-+	psrld	\$4,   	%xmm1   # 1 = i
-+	pand	%xmm9, 	%xmm0   # 0 = k
-+	pshufb  %xmm0,  %xmm5	# 2 = a/k
-+	movdqa	%xmm10,	%xmm3  	# 3 : 1/i
-+	pxor	%xmm1,	%xmm0	# 0 = j
-+	pshufb  %xmm1, 	%xmm3  	# 3 = 1/i
-+	movdqa	%xmm10,	%xmm4  	# 4 : 1/j
-+	pxor	%xmm5, 	%xmm3  	# 3 = iak = 1/i + a/k
-+	pshufb	%xmm0, 	%xmm4  	# 4 = 1/j
-+	movdqa	%xmm10,	%xmm2  	# 2 : 1/iak
-+	pxor	%xmm5, 	%xmm4  	# 4 = jak = 1/j + a/k
-+	pshufb  %xmm3,	%xmm2  	# 2 = 1/iak
-+	movdqa	%xmm10, %xmm3   # 3 : 1/jak
-+	pxor	%xmm0, 	%xmm2  	# 2 = io
-+	pshufb  %xmm4,  %xmm3   # 3 = 1/jak
-+	movdqu	(%r9),	%xmm5
-+	pxor	%xmm1,  %xmm3   # 3 = jo
-+	jnz	.Lenc_loop
-+
-+	# middle of last round
-+	movdqa	-0x60(%r10), %xmm4	# 3 : sbou	.Lk_sbo
-+	movdqa	-0x50(%r10), %xmm0	# 0 : sbot	.Lk_sbo+16
-+	pshufb  %xmm2,  %xmm4	# 4 = sbou
-+	pxor	%xmm5,  %xmm4	# 4 = sb1u + k
-+	pshufb  %xmm3,	%xmm0	# 0 = sb1t
-+	movdqa	0x40(%r11,%r10), %xmm1		# .Lk_sr[]
-+	pxor	%xmm4,	%xmm0	# 0 = A
-+	pshufb	%xmm1,	%xmm0
-+	ret
-+.size	_vpaes_encrypt_core,.-_vpaes_encrypt_core
-+	
-+##
-+##  Decryption core
-+##
-+##  Same API as encryption core.
-+##
-+.type	_vpaes_decrypt_core,\@abi-omnipotent
-+.align	16
-+_vpaes_decrypt_core:
-+	mov	%rdx,	%r9		# load key
-+	mov	240(%rdx),%eax
-+	movdqa	%xmm9,	%xmm1
-+	movdqa	.Lk_dipt(%rip), %xmm2	# iptlo
-+	pandn	%xmm0,	%xmm1
-+	mov	%rax,	%r11
-+	psrld	\$4,	%xmm1
-+	movdqu	(%r9),	%xmm5		# round0 key
-+	shl	\$4,	%r11
-+	pand	%xmm9,	%xmm0
-+	pshufb	%xmm0,	%xmm2
-+	movdqa	.Lk_dipt+16(%rip), %xmm0 # ipthi
-+	xor	\$0x30,	%r11
-+	lea	.Lk_dsbd(%rip),%r10
-+	pshufb	%xmm1,	%xmm0
-+	and	\$0x30,	%r11
-+	pxor	%xmm5,	%xmm2
-+	movdqa	.Lk_mc_forward+48(%rip), %xmm5
-+	pxor	%xmm2,	%xmm0
-+	add	\$16,	%r9
-+	add	%r10,	%r11
-+	jmp	.Ldec_entry
-+
-+.align 16
-+.Ldec_loop:
-+##
-+##  Inverse mix columns
-+##
-+	movdqa  -0x20(%r10),%xmm4	# 4 : sb9u
-+	movdqa  -0x10(%r10),%xmm1	# 0 : sb9t
-+	pshufb	%xmm2,	%xmm4		# 4 = sb9u
-+	pshufb	%xmm3,	%xmm1		# 0 = sb9t
-+	pxor	%xmm4,	%xmm0
-+	movdqa  0x00(%r10),%xmm4	# 4 : sbdu
-+	pxor	%xmm1,	%xmm0		# 0 = ch
-+	movdqa  0x10(%r10),%xmm1	# 0 : sbdt
-+
-+	pshufb	%xmm2,	%xmm4		# 4 = sbdu
-+	pshufb	%xmm5,	%xmm0		# MC ch
-+	pshufb	%xmm3,	%xmm1		# 0 = sbdt
-+	pxor	%xmm4,	%xmm0		# 4 = ch
-+	movdqa  0x20(%r10),%xmm4	# 4 : sbbu
-+	pxor	%xmm1,	%xmm0		# 0 = ch
-+	movdqa  0x30(%r10),%xmm1	# 0 : sbbt
-+
-+	pshufb	%xmm2,	%xmm4		# 4 = sbbu
-+	pshufb	%xmm5,	%xmm0		# MC ch
-+	pshufb	%xmm3,	%xmm1		# 0 = sbbt
-+	pxor	%xmm4,	%xmm0		# 4 = ch
-+	movdqa  0x40(%r10),%xmm4	# 4 : sbeu
-+	pxor	%xmm1,	%xmm0		# 0 = ch
-+	movdqa  0x50(%r10),%xmm1	# 0 : sbet
-+
-+	pshufb	%xmm2,	%xmm4		# 4 = sbeu
-+	pshufb	%xmm5,	%xmm0		# MC ch
-+	pshufb	%xmm3,	%xmm1		# 0 = sbet
-+	pxor	%xmm4,	%xmm0		# 4 = ch
-+	add	\$16, %r9		# next round key
-+	palignr	\$12,	%xmm5,	%xmm5
-+	pxor	%xmm1,	%xmm0		# 0 = ch
-+	sub	\$1,%rax		# nr--
-+
-+.Ldec_entry:
-+	# top of round
-+	movdqa  %xmm9, 	%xmm1	# 1 : i
-+	pandn	%xmm0, 	%xmm1	# 1 = i<<4
-+	movdqa	%xmm11, %xmm2	# 2 : a/k
-+	psrld	\$4,    %xmm1	# 1 = i
-+	pand	%xmm9, 	%xmm0	# 0 = k
-+	pshufb  %xmm0,  %xmm2	# 2 = a/k
-+	movdqa	%xmm10,	%xmm3	# 3 : 1/i
-+	pxor	%xmm1,	%xmm0	# 0 = j
-+	pshufb  %xmm1, 	%xmm3	# 3 = 1/i
-+	movdqa	%xmm10,	%xmm4	# 4 : 1/j
-+	pxor	%xmm2, 	%xmm3	# 3 = iak = 1/i + a/k
-+	pshufb	%xmm0, 	%xmm4	# 4 = 1/j
-+	pxor	%xmm2, 	%xmm4	# 4 = jak = 1/j + a/k
-+	movdqa	%xmm10,	%xmm2	# 2 : 1/iak
-+	pshufb  %xmm3,	%xmm2	# 2 = 1/iak
-+	movdqa	%xmm10, %xmm3	# 3 : 1/jak
-+	pxor	%xmm0, 	%xmm2	# 2 = io
-+	pshufb  %xmm4,  %xmm3	# 3 = 1/jak
-+	movdqu	(%r9),	%xmm0
-+	pxor	%xmm1,  %xmm3	# 3 = jo
-+	jnz	.Ldec_loop
-+
-+	# middle of last round
-+	movdqa	0x60(%r10), %xmm4	# 3 : sbou
-+	pshufb  %xmm2,  %xmm4	# 4 = sbou
-+	pxor	%xmm0,  %xmm4	# 4 = sb1u + k
-+	movdqa	0x70(%r10), %xmm0	# 0 : sbot
-+	movdqa	-0x160(%r11), %xmm2	# .Lk_sr-.Lk_dsbd=-0x160
-+	pshufb  %xmm3,	%xmm0	# 0 = sb1t
-+	pxor	%xmm4,	%xmm0	# 0 = A
-+	pshufb	%xmm2,	%xmm0
-+	ret
-+.size	_vpaes_decrypt_core,.-_vpaes_decrypt_core
-+
-+########################################################
-+##                                                    ##
-+##                  AES key schedule                  ##
-+##                                                    ##
-+########################################################
-+.type	_vpaes_schedule_core,\@abi-omnipotent
-+.align	16
-+_vpaes_schedule_core:
-+	# rdi = key
-+	# rsi = size in bits
-+	# rdx = buffer
-+	# rcx = direction.  0=encrypt, 1=decrypt
-+
-+	call	_vpaes_preheat		# load the tables
-+	movdqa	.Lk_rcon(%rip), %xmm8	# load rcon
-+	movdqu	(%rdi),	%xmm0		# load key (unaligned)
-+
-+	# input transform
-+	movdqa	%xmm0,	%xmm3
-+	lea	.Lk_ipt(%rip), %r11
-+	call	_vpaes_schedule_transform
-+	movdqa	%xmm0,	%xmm7
-+
-+	lea	.Lk_sr(%rip),%r10
-+	test	%rcx,	%rcx
-+	jnz	.Lschedule_am_decrypting
-+
-+	# encrypting, output zeroth round key after transform
-+	movdqu	%xmm0,	(%rdx)
-+	jmp	.Lschedule_go
-+
-+.Lschedule_am_decrypting:
-+	# decrypting, output zeroth round key after shiftrows
-+	movdqa	(%r8,%r10),%xmm1
-+	pshufb  %xmm1,	%xmm3
-+	movdqu	%xmm3,	(%rdx)
-+	xor	\$0x30, %r8
-+
-+.Lschedule_go:
-+	cmp	\$192,	%esi
-+	ja	.Lschedule_256
-+	je	.Lschedule_192
-+	# 128: fall though
-+
-+##
-+##  .schedule_128
-+##
-+##  128-bit specific part of key schedule.
-+##
-+##  This schedule is really simple, because all its parts
-+##  are accomplished by the subroutines.
-+##
-+.Lschedule_128:
-+	mov	\$10, %esi
-+	
-+.Loop_schedule_128:
-+	call 	_vpaes_schedule_round
-+	dec	%rsi
-+	jz 	.Lschedule_mangle_last
-+	call	_vpaes_schedule_mangle	# write output
-+	jmp 	.Loop_schedule_128
-+
-+##
-+##  .aes_schedule_192
-+##
-+##  192-bit specific part of key schedule.
-+##
-+##  The main body of this schedule is the same as the 128-bit
-+##  schedule, but with more smearing.  The long, high side is
-+##  stored in %xmm7 as before, and the short, low side is in
-+##  the high bits of %xmm6.
-+##
-+##  This schedule is somewhat nastier, however, because each
-+##  round produces 192 bits of key material, or 1.5 round keys.
-+##  Therefore, on each cycle we do 2 rounds and produce 3 round
-+##  keys.
-+##
-+.align	16
-+.Lschedule_192:
-+	movdqu	8(%rdi),%xmm0		# load key part 2 (very unaligned)
-+	call	_vpaes_schedule_transform	# input transform
-+	movdqa	%xmm0,	%xmm6		# save short part
-+	pxor	%xmm4,	%xmm4		# clear 4
-+	movhlps	%xmm4,	%xmm6		# clobber low side with zeros
-+	mov	\$4,	%esi
-+
-+.Loop_schedule_192:
-+	call	_vpaes_schedule_round
-+	palignr	\$8,%xmm6,%xmm0	
-+	call	_vpaes_schedule_mangle	# save key n
-+	call	_vpaes_schedule_192_smear
-+	call	_vpaes_schedule_mangle	# save key n+1
-+	call	_vpaes_schedule_round
-+	dec	%rsi
-+	jz 	.Lschedule_mangle_last
-+	call	_vpaes_schedule_mangle	# save key n+2
-+	call	_vpaes_schedule_192_smear
-+	jmp	.Loop_schedule_192
-+
-+##
-+##  .aes_schedule_256
-+##
-+##  256-bit specific part of key schedule.
-+##
-+##  The structure here is very similar to the 128-bit
-+##  schedule, but with an additional "low side" in
-+##  %xmm6.  The low side's rounds are the same as the
-+##  high side's, except no rcon and no rotation.
-+##
-+.align	16
-+.Lschedule_256:
-+	movdqu	16(%rdi),%xmm0		# load key part 2 (unaligned)
-+	call	_vpaes_schedule_transform	# input transform
-+	mov	\$7, %esi
-+	
-+.Loop_schedule_256:
-+	call	_vpaes_schedule_mangle	# output low result
-+	movdqa	%xmm0,	%xmm6		# save cur_lo in xmm6
-+
-+	# high round
-+	call	_vpaes_schedule_round
-+	dec	%rsi
-+	jz 	.Lschedule_mangle_last
-+	call	_vpaes_schedule_mangle	
-+
-+	# low round. swap xmm7 and xmm6
-+	pshufd	\$0xFF,	%xmm0,	%xmm0
-+	movdqa	%xmm7,	%xmm5
-+	movdqa	%xmm6,	%xmm7
-+	call	_vpaes_schedule_low_round
-+	movdqa	%xmm5,	%xmm7
-+	
-+	jmp	.Loop_schedule_256
-+
-+	
-+##
-+##  .aes_schedule_mangle_last
-+##
-+##  Mangler for last round of key schedule
-+##  Mangles %xmm0
-+##    when encrypting, outputs out(%xmm0) ^ 63
-+##    when decrypting, outputs unskew(%xmm0)
-+##
-+##  Always called right before return... jumps to cleanup and exits
-+##
-+.align	16
-+.Lschedule_mangle_last:
-+	# schedule last round key from xmm0
-+	lea	.Lk_deskew(%rip),%r11	# prepare to deskew
-+	test	%rcx, 	%rcx
-+	jnz	.Lschedule_mangle_last_dec
-+
-+	# encrypting
-+	movdqa	(%r8,%r10),%xmm1
-+	pshufb	%xmm1,	%xmm0		# output permute
-+	lea	.Lk_opt(%rip),	%r11	# prepare to output transform
-+	add	\$32,	%rdx
-+
-+.Lschedule_mangle_last_dec:
-+	add	\$-16,	%rdx
-+	pxor	.Lk_s63(%rip),	%xmm0
-+	call	_vpaes_schedule_transform # output transform
-+	movdqu	%xmm0,	(%rdx)		# save last key
-+
-+	# cleanup
-+	pxor	%xmm0,  %xmm0
-+	pxor	%xmm1,  %xmm1
-+	pxor	%xmm2,  %xmm2
-+	pxor	%xmm3,  %xmm3
-+	pxor	%xmm4,  %xmm4
-+	pxor	%xmm5,  %xmm5
-+	pxor	%xmm6,  %xmm6
-+	pxor	%xmm7,  %xmm7
-+	ret
-+.size	_vpaes_schedule_core,.-_vpaes_schedule_core
-+
-+##
-+##  .aes_schedule_192_smear
-+##
-+##  Smear the short, low side in the 192-bit key schedule.
-+##
-+##  Inputs:
-+##    %xmm7: high side, b  a  x  y
-+##    %xmm6:  low side, d  c  0  0
-+##    %xmm13: 0
-+##
-+##  Outputs:
-+##    %xmm6: b+c+d  b+c  0  0
-+##    %xmm0: b+c+d  b+c  b  a
-+##
-+.type	_vpaes_schedule_192_smear,\@abi-omnipotent
-+.align	16
-+_vpaes_schedule_192_smear:
-+	pshufd	\$0x80,	%xmm6,	%xmm1	# d c 0 0 -> c 0 0 0
-+	pshufd	\$0xFE,	%xmm7,	%xmm0	# b a _ _ -> b b b a
-+	pxor	%xmm1,	%xmm6		# -> c+d c 0 0
-+	pxor	%xmm1,	%xmm1
-+	pxor	%xmm0,	%xmm6		# -> b+c+d b+c b a
-+	movdqa	%xmm6,	%xmm0
-+	movhlps	%xmm1,	%xmm6		# clobber low side with zeros
-+	ret
-+.size	_vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
-+
-+##
-+##  .aes_schedule_round
-+##
-+##  Runs one main round of the key schedule on %xmm0, %xmm7
-+##
-+##  Specifically, runs subbytes on the high dword of %xmm0
-+##  then rotates it by one byte and xors into the low dword of
-+##  %xmm7.
-+##
-+##  Adds rcon from low byte of %xmm8, then rotates %xmm8 for
-+##  next rcon.
-+##
-+##  Smears the dwords of %xmm7 by xoring the low into the
-+##  second low, result into third, result into highest.
-+##
-+##  Returns results in %xmm7 = %xmm0.
-+##  Clobbers %xmm1-%xmm4, %r11.
-+##
-+.type	_vpaes_schedule_round,\@abi-omnipotent
-+.align	16
-+_vpaes_schedule_round:
-+	# extract rcon from xmm8
-+	pxor	%xmm1,	%xmm1
-+	palignr	\$15,	%xmm8,	%xmm1
-+	palignr	\$15,	%xmm8,	%xmm8
-+	pxor	%xmm1,	%xmm7
-+
-+	# rotate
-+	pshufd	\$0xFF,	%xmm0,	%xmm0
-+	palignr	\$1,	%xmm0,	%xmm0
-+	
-+	# fall through...
-+	
-+	# low round: same as high round, but no rotation and no rcon.
-+_vpaes_schedule_low_round:
-+	# smear xmm7
-+	movdqa	%xmm7,	%xmm1
-+	pslldq	\$4,	%xmm7
-+	pxor	%xmm1,	%xmm7
-+	movdqa	%xmm7,	%xmm1
-+	pslldq	\$8,	%xmm7
-+	pxor	%xmm1,	%xmm7
-+	pxor	.Lk_s63(%rip), %xmm7
-+
-+	# subbytes
-+	movdqa  %xmm9, 	%xmm1
-+	pandn	%xmm0, 	%xmm1
-+	psrld	\$4,    %xmm1		# 1 = i
-+	pand	%xmm9, 	%xmm0		# 0 = k
-+	movdqa	%xmm11, %xmm2		# 2 : a/k
-+	pshufb  %xmm0,  %xmm2		# 2 = a/k
-+	pxor	%xmm1,	%xmm0		# 0 = j
-+	movdqa	%xmm10,	%xmm3		# 3 : 1/i
-+	pshufb  %xmm1, 	%xmm3		# 3 = 1/i
-+	pxor	%xmm2, 	%xmm3		# 3 = iak = 1/i + a/k
-+	movdqa	%xmm10,	%xmm4		# 4 : 1/j
-+	pshufb	%xmm0, 	%xmm4		# 4 = 1/j
-+	pxor	%xmm2, 	%xmm4		# 4 = jak = 1/j + a/k
-+	movdqa	%xmm10,	%xmm2		# 2 : 1/iak
-+	pshufb  %xmm3,	%xmm2		# 2 = 1/iak
-+	pxor	%xmm0, 	%xmm2		# 2 = io
-+	movdqa	%xmm10, %xmm3		# 3 : 1/jak
-+	pshufb  %xmm4,  %xmm3		# 3 = 1/jak
-+	pxor	%xmm1,  %xmm3		# 3 = jo
-+	movdqa	%xmm13, %xmm4		# 4 : sbou
-+	pshufb  %xmm2,  %xmm4		# 4 = sbou
-+	movdqa	%xmm12, %xmm0		# 0 : sbot
-+	pshufb  %xmm3,	%xmm0		# 0 = sb1t
-+	pxor	%xmm4, 	%xmm0		# 0 = sbox output
-+
-+	# add in smeared stuff
-+	pxor	%xmm7,	%xmm0	
-+	movdqa	%xmm0,	%xmm7
-+	ret
-+.size	_vpaes_schedule_round,.-_vpaes_schedule_round
-+
-+##
-+##  .aes_schedule_transform
-+##
-+##  Linear-transform %xmm0 according to tables at (%r11)
-+##
-+##  Requires that %xmm9 = 0x0F0F... as in preheat
-+##  Output in %xmm0
-+##  Clobbers %xmm1, %xmm2
-+##
-+.type	_vpaes_schedule_transform,\@abi-omnipotent
-+.align	16
-+_vpaes_schedule_transform:
-+	movdqa	%xmm9,	%xmm1
-+	pandn	%xmm0,	%xmm1
-+	psrld	\$4,	%xmm1
-+	pand	%xmm9,	%xmm0
-+	movdqa	(%r11), %xmm2 	# lo
-+	pshufb	%xmm0,	%xmm2
-+	movdqa	16(%r11), %xmm0 # hi
-+	pshufb	%xmm1,	%xmm0
-+	pxor	%xmm2,	%xmm0
-+	ret
-+.size	_vpaes_schedule_transform,.-_vpaes_schedule_transform
-+
-+##
-+##  .aes_schedule_mangle
-+##
-+##  Mangle xmm0 from (basis-transformed) standard version
-+##  to our version.
-+##
-+##  On encrypt,
-+##    xor with 0x63
-+##    multiply by circulant 0,1,1,1
-+##    apply shiftrows transform
-+##
-+##  On decrypt,
-+##    xor with 0x63
-+##    multiply by "inverse mixcolumns" circulant E,B,D,9
-+##    deskew
-+##    apply shiftrows transform
-+##
-+##
-+##  Writes out to (%rdx), and increments or decrements it
-+##  Keeps track of round number mod 4 in %r8
-+##  Preserves xmm0
-+##  Clobbers xmm1-xmm5
-+##
-+.type	_vpaes_schedule_mangle,\@abi-omnipotent
-+.align	16
-+_vpaes_schedule_mangle:
-+	movdqa	%xmm0,	%xmm4	# save xmm0 for later
-+	movdqa	.Lk_mc_forward(%rip),%xmm5
-+	test	%rcx, 	%rcx
-+	jnz	.Lschedule_mangle_dec
-+
-+	# encrypting
-+	add	\$16,	%rdx
-+	pxor	.Lk_s63(%rip),%xmm4
-+	pshufb	%xmm5,	%xmm4
-+	movdqa	%xmm4,	%xmm3
-+	pshufb	%xmm5,	%xmm4
-+	pxor	%xmm4,	%xmm3
-+	pshufb	%xmm5,	%xmm4
-+	pxor	%xmm4,	%xmm3
-+
-+	jmp	.Lschedule_mangle_both
-+.align	16
-+.Lschedule_mangle_dec:
-+	# inverse mix columns
-+	lea	.Lk_dksd(%rip),%r11
-+	movdqa	%xmm9,	%xmm1
-+	pandn	%xmm4,	%xmm1
-+	psrld	\$4,	%xmm1	# 1 = hi
-+	pand	%xmm9,	%xmm4	# 4 = lo
-+
-+	movdqa	0x00(%r11), %xmm2
-+	pshufb	%xmm4,	%xmm2
-+	movdqa	0x10(%r11), %xmm3
-+	pshufb	%xmm1,	%xmm3
-+	pxor	%xmm2,	%xmm3
-+	pshufb	%xmm5,	%xmm3
-+
-+	movdqa	0x20(%r11), %xmm2
-+	pshufb	%xmm4,	%xmm2
-+	pxor	%xmm3,	%xmm2
-+	movdqa	0x30(%r11), %xmm3
-+	pshufb	%xmm1,	%xmm3
-+	pxor	%xmm2,	%xmm3
-+	pshufb	%xmm5,	%xmm3
-+
-+	movdqa	0x40(%r11), %xmm2
-+	pshufb	%xmm4,	%xmm2
-+	pxor	%xmm3,	%xmm2
-+	movdqa	0x50(%r11), %xmm3
-+	pshufb	%xmm1,	%xmm3
-+	pxor	%xmm2,	%xmm3
-+	pshufb	%xmm5,	%xmm3
-+
-+	movdqa	0x60(%r11), %xmm2
-+	pshufb	%xmm4,	%xmm2
-+	pxor	%xmm3,	%xmm2
-+	movdqa	0x70(%r11), %xmm3
-+	pshufb	%xmm1,	%xmm3
-+	pxor	%xmm2,	%xmm3
-+
-+	add	\$-16,	%rdx
-+
-+.Lschedule_mangle_both:
-+	movdqa	(%r8,%r10),%xmm1
-+	pshufb	%xmm1,%xmm3
-+	add	\$-16,	%r8
-+	and	\$0x30,	%r8
-+	movdqu	%xmm3,	(%rdx)
-+	ret
-+.size	_vpaes_schedule_mangle,.-_vpaes_schedule_mangle
-+
-+#
-+# Interface to OpenSSL
-+#
-+.globl	${PREFIX}_set_encrypt_key
-+.type	${PREFIX}_set_encrypt_key,\@function,3
-+.align	16
-+${PREFIX}_set_encrypt_key:
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xb8(%rsp),%rsp
-+	movaps	%xmm6,0x10(%rsp)
-+	movaps	%xmm7,0x20(%rsp)
-+	movaps	%xmm8,0x30(%rsp)
-+	movaps	%xmm9,0x40(%rsp)
-+	movaps	%xmm10,0x50(%rsp)
-+	movaps	%xmm11,0x60(%rsp)
-+	movaps	%xmm12,0x70(%rsp)
-+	movaps	%xmm13,0x80(%rsp)
-+	movaps	%xmm14,0x90(%rsp)
-+	movaps	%xmm15,0xa0(%rsp)
-+.Lenc_key_body:
-+___
-+$code.=<<___;
-+	mov	%esi,%eax
-+	shr	\$5,%eax
-+	add	\$5,%eax
-+	mov	%eax,240(%rdx)	# AES_KEY->rounds = nbits/32+5;
-+
-+	mov	\$0,%ecx
-+	mov	\$0x30,%r8d
-+	call	_vpaes_schedule_core
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x10(%rsp),%xmm6
-+	movaps	0x20(%rsp),%xmm7
-+	movaps	0x30(%rsp),%xmm8
-+	movaps	0x40(%rsp),%xmm9
-+	movaps	0x50(%rsp),%xmm10
-+	movaps	0x60(%rsp),%xmm11
-+	movaps	0x70(%rsp),%xmm12
-+	movaps	0x80(%rsp),%xmm13
-+	movaps	0x90(%rsp),%xmm14
-+	movaps	0xa0(%rsp),%xmm15
-+	lea	0xb8(%rsp),%rsp
-+.Lenc_key_epilogue:
-+___
-+$code.=<<___;
-+	xor	%eax,%eax
-+	ret
-+.size	${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key
-+
-+.globl	${PREFIX}_set_decrypt_key
-+.type	${PREFIX}_set_decrypt_key,\@function,3
-+.align	16
-+${PREFIX}_set_decrypt_key:
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xb8(%rsp),%rsp
-+	movaps	%xmm6,0x10(%rsp)
-+	movaps	%xmm7,0x20(%rsp)
-+	movaps	%xmm8,0x30(%rsp)
-+	movaps	%xmm9,0x40(%rsp)
-+	movaps	%xmm10,0x50(%rsp)
-+	movaps	%xmm11,0x60(%rsp)
-+	movaps	%xmm12,0x70(%rsp)
-+	movaps	%xmm13,0x80(%rsp)
-+	movaps	%xmm14,0x90(%rsp)
-+	movaps	%xmm15,0xa0(%rsp)
-+.Ldec_key_body:
-+___
-+$code.=<<___;
-+	mov	%esi,%eax
-+	shr	\$5,%eax
-+	add	\$5,%eax
-+	mov	%eax,240(%rdx)	# AES_KEY->rounds = nbits/32+5;
-+	shl	\$4,%eax
-+	lea	16(%rdx,%rax),%rdx
-+
-+	mov	\$1,%ecx
-+	mov	%esi,%r8d
-+	shr	\$1,%r8d
-+	and	\$32,%r8d
-+	xor	\$32,%r8d	# nbits==192?0:32
-+	call	_vpaes_schedule_core
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x10(%rsp),%xmm6
-+	movaps	0x20(%rsp),%xmm7
-+	movaps	0x30(%rsp),%xmm8
-+	movaps	0x40(%rsp),%xmm9
-+	movaps	0x50(%rsp),%xmm10
-+	movaps	0x60(%rsp),%xmm11
-+	movaps	0x70(%rsp),%xmm12
-+	movaps	0x80(%rsp),%xmm13
-+	movaps	0x90(%rsp),%xmm14
-+	movaps	0xa0(%rsp),%xmm15
-+	lea	0xb8(%rsp),%rsp
-+.Ldec_key_epilogue:
-+___
-+$code.=<<___;
-+	xor	%eax,%eax
-+	ret
-+.size	${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key
-+
-+.globl	${PREFIX}_encrypt
-+.type	${PREFIX}_encrypt,\@function,3
-+.align	16
-+${PREFIX}_encrypt:
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xb8(%rsp),%rsp
-+	movaps	%xmm6,0x10(%rsp)
-+	movaps	%xmm7,0x20(%rsp)
-+	movaps	%xmm8,0x30(%rsp)
-+	movaps	%xmm9,0x40(%rsp)
-+	movaps	%xmm10,0x50(%rsp)
-+	movaps	%xmm11,0x60(%rsp)
-+	movaps	%xmm12,0x70(%rsp)
-+	movaps	%xmm13,0x80(%rsp)
-+	movaps	%xmm14,0x90(%rsp)
-+	movaps	%xmm15,0xa0(%rsp)
-+.Lenc_body:
-+___
-+$code.=<<___;
-+	movdqu	(%rdi),%xmm0
-+	call	_vpaes_preheat
-+	call	_vpaes_encrypt_core
-+	movdqu	%xmm0,(%rsi)
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x10(%rsp),%xmm6
-+	movaps	0x20(%rsp),%xmm7
-+	movaps	0x30(%rsp),%xmm8
-+	movaps	0x40(%rsp),%xmm9
-+	movaps	0x50(%rsp),%xmm10
-+	movaps	0x60(%rsp),%xmm11
-+	movaps	0x70(%rsp),%xmm12
-+	movaps	0x80(%rsp),%xmm13
-+	movaps	0x90(%rsp),%xmm14
-+	movaps	0xa0(%rsp),%xmm15
-+	lea	0xb8(%rsp),%rsp
-+.Lenc_epilogue:
-+___
-+$code.=<<___;
-+	ret
-+.size	${PREFIX}_encrypt,.-${PREFIX}_encrypt
-+
-+.globl	${PREFIX}_decrypt
-+.type	${PREFIX}_decrypt,\@function,3
-+.align	16
-+${PREFIX}_decrypt:
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xb8(%rsp),%rsp
-+	movaps	%xmm6,0x10(%rsp)
-+	movaps	%xmm7,0x20(%rsp)
-+	movaps	%xmm8,0x30(%rsp)
-+	movaps	%xmm9,0x40(%rsp)
-+	movaps	%xmm10,0x50(%rsp)
-+	movaps	%xmm11,0x60(%rsp)
-+	movaps	%xmm12,0x70(%rsp)
-+	movaps	%xmm13,0x80(%rsp)
-+	movaps	%xmm14,0x90(%rsp)
-+	movaps	%xmm15,0xa0(%rsp)
-+.Ldec_body:
-+___
-+$code.=<<___;
-+	movdqu	(%rdi),%xmm0
-+	call	_vpaes_preheat
-+	call	_vpaes_decrypt_core
-+	movdqu	%xmm0,(%rsi)
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x10(%rsp),%xmm6
-+	movaps	0x20(%rsp),%xmm7
-+	movaps	0x30(%rsp),%xmm8
-+	movaps	0x40(%rsp),%xmm9
-+	movaps	0x50(%rsp),%xmm10
-+	movaps	0x60(%rsp),%xmm11
-+	movaps	0x70(%rsp),%xmm12
-+	movaps	0x80(%rsp),%xmm13
-+	movaps	0x90(%rsp),%xmm14
-+	movaps	0xa0(%rsp),%xmm15
-+	lea	0xb8(%rsp),%rsp
-+.Ldec_epilogue:
-+___
-+$code.=<<___;
-+	ret
-+.size	${PREFIX}_decrypt,.-${PREFIX}_decrypt
-+___
-+{
-+my ($inp,$out,$len,$key,$ivp,$enc)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9");
-+# void AES_cbc_encrypt (const void char *inp, unsigned char *out,
-+#                       size_t length, const AES_KEY *key,
-+#                       unsigned char *ivp,const int enc);
-+$code.=<<___;
-+.globl	${PREFIX}_cbc_encrypt
-+.type	${PREFIX}_cbc_encrypt,\@function,6
-+.align	16
-+${PREFIX}_cbc_encrypt:
-+	xchg	$key,$len
-+___
-+($len,$key)=($key,$len);
-+$code.=<<___;
-+	sub	\$16,$len
-+	jc	.Lcbc_abort
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xb8(%rsp),%rsp
-+	movaps	%xmm6,0x10(%rsp)
-+	movaps	%xmm7,0x20(%rsp)
-+	movaps	%xmm8,0x30(%rsp)
-+	movaps	%xmm9,0x40(%rsp)
-+	movaps	%xmm10,0x50(%rsp)
-+	movaps	%xmm11,0x60(%rsp)
-+	movaps	%xmm12,0x70(%rsp)
-+	movaps	%xmm13,0x80(%rsp)
-+	movaps	%xmm14,0x90(%rsp)
-+	movaps	%xmm15,0xa0(%rsp)
-+.Lcbc_body:
-+___
-+$code.=<<___;
-+	movdqu	($ivp),%xmm6		# load IV
-+	sub	$inp,$out
-+	call	_vpaes_preheat
-+	cmp	\$0,${enc}d
-+	je	.Lcbc_dec_loop
-+	jmp	.Lcbc_enc_loop
-+.align	16
-+.Lcbc_enc_loop:
-+	movdqu	($inp),%xmm0
-+	pxor	%xmm6,%xmm0
-+	call	_vpaes_encrypt_core
-+	movdqa	%xmm0,%xmm6
-+	movdqu	%xmm0,($out,$inp)
-+	lea	16($inp),$inp
-+	sub	\$16,$len
-+	jnc	.Lcbc_enc_loop
-+	jmp	.Lcbc_done
-+.align	16
-+.Lcbc_dec_loop:
-+	movdqu	($inp),%xmm0
-+	movdqa	%xmm0,%xmm7
-+	call	_vpaes_decrypt_core
-+	pxor	%xmm6,%xmm0
-+	movdqa	%xmm7,%xmm6
-+	movdqu	%xmm0,($out,$inp)
-+	lea	16($inp),$inp
-+	sub	\$16,$len
-+	jnc	.Lcbc_dec_loop
-+.Lcbc_done:
-+	movdqu	%xmm6,($ivp)		# save IV
-+___
-+$code.=<<___ if ($win64);
-+	movaps	0x10(%rsp),%xmm6
-+	movaps	0x20(%rsp),%xmm7
-+	movaps	0x30(%rsp),%xmm8
-+	movaps	0x40(%rsp),%xmm9
-+	movaps	0x50(%rsp),%xmm10
-+	movaps	0x60(%rsp),%xmm11
-+	movaps	0x70(%rsp),%xmm12
-+	movaps	0x80(%rsp),%xmm13
-+	movaps	0x90(%rsp),%xmm14
-+	movaps	0xa0(%rsp),%xmm15
-+	lea	0xb8(%rsp),%rsp
-+.Lcbc_epilogue:
-+___
-+$code.=<<___;
-+.Lcbc_abort:
-+	ret
-+.size	${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt
-+___
-+}
-+$code.=<<___;
-+##
-+##  _aes_preheat
-+##
-+##  Fills register %r10 -> .aes_consts (so you can -fPIC)
-+##  and %xmm9-%xmm15 as specified below.
-+##
-+.type	_vpaes_preheat,\@abi-omnipotent
-+.align	16
-+_vpaes_preheat:
-+	lea	.Lk_s0F(%rip), %r10
-+	movdqa	-0x20(%r10), %xmm10	# .Lk_inv
-+	movdqa	-0x10(%r10), %xmm11	# .Lk_inv+16
-+	movdqa	0x00(%r10), %xmm9	# .Lk_s0F
-+	movdqa	0x30(%r10), %xmm13	# .Lk_sb1
-+	movdqa	0x40(%r10), %xmm12	# .Lk_sb1+16
-+	movdqa	0x50(%r10), %xmm15	# .Lk_sb2
-+	movdqa	0x60(%r10), %xmm14	# .Lk_sb2+16
-+	ret
-+.size	_vpaes_preheat,.-_vpaes_preheat
-+########################################################
-+##                                                    ##
-+##                     Constants                      ##
-+##                                                    ##
-+########################################################
-+.type	_vpaes_consts,\@object
-+.align	64
-+_vpaes_consts:
-+.Lk_inv:	# inv, inva
-+	.quad	0x0E05060F0D080180, 0x040703090A0B0C02
-+	.quad	0x01040A060F0B0780, 0x030D0E0C02050809
-+
-+.Lk_s0F:	# s0F
-+	.quad	0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F
-+
-+.Lk_ipt:	# input transform (lo, hi)
-+	.quad	0xC2B2E8985A2A7000, 0xCABAE09052227808
-+	.quad	0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
-+
-+.Lk_sb1:	# sb1u, sb1t
-+	.quad	0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
-+	.quad	0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
-+.Lk_sb2:	# sb2u, sb2t
-+	.quad	0xE27A93C60B712400, 0x5EB7E955BC982FCD
-+	.quad	0x69EB88400AE12900, 0xC2A163C8AB82234A
-+.Lk_sbo:	# sbou, sbot
-+	.quad	0xD0D26D176FBDC700, 0x15AABF7AC502A878
-+	.quad	0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
-+
-+.Lk_mc_forward:	# mc_forward
-+	.quad	0x0407060500030201, 0x0C0F0E0D080B0A09
-+	.quad	0x080B0A0904070605, 0x000302010C0F0E0D
-+	.quad	0x0C0F0E0D080B0A09, 0x0407060500030201
-+	.quad	0x000302010C0F0E0D, 0x080B0A0904070605
-+
-+.Lk_mc_backward:# mc_backward
-+	.quad	0x0605040702010003, 0x0E0D0C0F0A09080B
-+	.quad	0x020100030E0D0C0F, 0x0A09080B06050407
-+	.quad	0x0E0D0C0F0A09080B, 0x0605040702010003
-+	.quad	0x0A09080B06050407, 0x020100030E0D0C0F
-+
-+.Lk_sr:		# sr
-+	.quad	0x0706050403020100, 0x0F0E0D0C0B0A0908
-+	.quad	0x030E09040F0A0500, 0x0B06010C07020D08
-+	.quad	0x0F060D040B020900, 0x070E050C030A0108
-+	.quad	0x0B0E0104070A0D00, 0x0306090C0F020508
-+
-+.Lk_rcon:	# rcon
-+	.quad	0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
-+
-+.Lk_s63:	# s63: all equal to 0x63 transformed
-+	.quad	0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B
-+
-+.Lk_opt:	# output transform
-+	.quad	0xFF9F4929D6B66000, 0xF7974121DEBE6808
-+	.quad	0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
-+
-+.Lk_deskew:	# deskew tables: inverts the sbox's "skew"
-+	.quad	0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
-+	.quad	0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
-+
-+##
-+##  Decryption stuff
-+##  Key schedule constants
-+##
-+.Lk_dksd:	# decryption key schedule: invskew x*D
-+	.quad	0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
-+	.quad	0x41C277F4B5368300, 0x5FDC69EAAB289D1E
-+.Lk_dksb:	# decryption key schedule: invskew x*B
-+	.quad	0x9A4FCA1F8550D500, 0x03D653861CC94C99
-+	.quad	0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
-+.Lk_dkse:	# decryption key schedule: invskew x*E + 0x63
-+	.quad	0xD5031CCA1FC9D600, 0x53859A4C994F5086
-+	.quad	0xA23196054FDC7BE8, 0xCD5EF96A20B31487
-+.Lk_dks9:	# decryption key schedule: invskew x*9
-+	.quad	0xB6116FC87ED9A700, 0x4AED933482255BFC
-+	.quad	0x4576516227143300, 0x8BB89FACE9DAFDCE
-+
-+##
-+##  Decryption stuff
-+##  Round function constants
-+##
-+.Lk_dipt:	# decryption input transform
-+	.quad	0x0F505B040B545F00, 0x154A411E114E451A
-+	.quad	0x86E383E660056500, 0x12771772F491F194
-+
-+.Lk_dsb9:	# decryption sbox output *9*u, *9*t
-+	.quad	0x851C03539A86D600, 0xCAD51F504F994CC9
-+	.quad	0xC03B1789ECD74900, 0x725E2C9EB2FBA565
-+.Lk_dsbd:	# decryption sbox output *D*u, *D*t
-+	.quad	0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
-+	.quad	0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
-+.Lk_dsbb:	# decryption sbox output *B*u, *B*t
-+	.quad	0xD022649296B44200, 0x602646F6B0F2D404
-+	.quad	0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
-+.Lk_dsbe:	# decryption sbox output *E*u, *E*t
-+	.quad	0x46F2929626D4D000, 0x2242600464B4F6B0
-+	.quad	0x0C55A6CDFFAAC100, 0x9467F36B98593E32
-+.Lk_dsbo:	# decryption sbox final output
-+	.quad	0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
-+	.quad	0x12D7560F93441D00, 0xCA4B8159D8C58E9C
-+.asciz	"Vector Permutation AES for x86_64/SSSE3, Mike Hamburg (Stanford University)"
-+.align	64
-+.size	_vpaes_consts,.-_vpaes_consts
-+___
-+
-+if ($win64) {
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_prologue
-+
-+	lea	16(%rax),%rsi		# %xmm save area
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
-+	.long	0xa548f3fc		# cld; rep movsq
-+	lea	0xb8(%rax),%rax		# adjust stack pointer
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_${PREFIX}_set_encrypt_key
-+	.rva	.LSEH_end_${PREFIX}_set_encrypt_key
-+	.rva	.LSEH_info_${PREFIX}_set_encrypt_key
-+
-+	.rva	.LSEH_begin_${PREFIX}_set_decrypt_key
-+	.rva	.LSEH_end_${PREFIX}_set_decrypt_key
-+	.rva	.LSEH_info_${PREFIX}_set_decrypt_key
-+
-+	.rva	.LSEH_begin_${PREFIX}_encrypt
-+	.rva	.LSEH_end_${PREFIX}_encrypt
-+	.rva	.LSEH_info_${PREFIX}_encrypt
-+
-+	.rva	.LSEH_begin_${PREFIX}_decrypt
-+	.rva	.LSEH_end_${PREFIX}_decrypt
-+	.rva	.LSEH_info_${PREFIX}_decrypt
-+
-+	.rva	.LSEH_begin_${PREFIX}_cbc_encrypt
-+	.rva	.LSEH_end_${PREFIX}_cbc_encrypt
-+	.rva	.LSEH_info_${PREFIX}_cbc_encrypt
-+
-+.section	.xdata
-+.align	8
-+.LSEH_info_${PREFIX}_set_encrypt_key:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lenc_key_body,.Lenc_key_epilogue	# HandlerData[]
-+.LSEH_info_${PREFIX}_set_decrypt_key:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Ldec_key_body,.Ldec_key_epilogue	# HandlerData[]
-+.LSEH_info_${PREFIX}_encrypt:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lenc_body,.Lenc_epilogue		# HandlerData[]
-+.LSEH_info_${PREFIX}_decrypt:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Ldec_body,.Ldec_epilogue		# HandlerData[]
-+.LSEH_info_${PREFIX}_cbc_encrypt:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lcbc_body,.Lcbc_epilogue		# HandlerData[]
-+___
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/build.info
-new file mode 100644
-index 0000000..cf6cb5e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/aes/build.info
-@@ -0,0 +1,57 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        aes_misc.c aes_ecb.c aes_cfb.c aes_ofb.c \
-+        aes_ige.c aes_wrap.c {- $target{aes_asm_src} -}
-+
-+GENERATE[aes-ia64.s]=asm/aes-ia64.S
-+
-+GENERATE[aes-586.s]=asm/aes-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[aes-586.s]=../perlasm/x86asm.pl
-+GENERATE[vpaes-x86.s]=asm/vpaes-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[vpaes-586.s]=../perlasm/x86asm.pl
-+GENERATE[aesni-x86.s]=asm/aesni-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[aesni-586.s]=../perlasm/x86asm.pl
-+
-+GENERATE[aes-x86_64.s]=asm/aes-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[vpaes-x86_64.s]=asm/vpaes-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[bsaes-x86_64.s]=asm/bsaes-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[aesni-x86_64.s]=asm/aesni-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[aesni-sha1-x86_64.s]=asm/aesni-sha1-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[aesni-sha256-x86_64.s]=asm/aesni-sha256-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[aesni-mb-x86_64.s]=asm/aesni-mb-x86_64.pl $(PERLASM_SCHEME)
-+
-+GENERATE[aes-sparcv9.S]=asm/aes-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[aes-sparcv9.o]=..
-+GENERATE[aest4-sparcv9.S]=asm/aest4-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[aest4-sparcv9.o]=..
-+DEPEND[aest4-sparcv9.S]=../perlasm/sparcv9_modes.pl
-+GENERATE[aesfx-sparcv9.S]=asm/aesfx-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[aesfx-sparcv9.o]=..
-+
-+GENERATE[aes-ppc.s]=asm/aes-ppc.pl $(PERLASM_SCHEME)
-+GENERATE[vpaes-ppc.s]=asm/vpaes-ppc.pl $(PERLASM_SCHEME)
-+GENERATE[aesp8-ppc.s]=asm/aesp8-ppc.pl $(PERLASM_SCHEME)
-+
-+GENERATE[aes-parisc.s]=asm/aes-parisc.pl $(PERLASM_SCHEME)
-+
-+GENERATE[aes-mips.S]=asm/aes-mips.pl $(PERLASM_SCHEME)
-+
-+GENERATE[aesv8-armx.S]=asm/aesv8-armx.pl $(PERLASM_SCHEME)
-+INCLUDE[aesv8-armx.o]=..
-+GENERATE[vpaes-armv8.S]=asm/vpaes-armv8.pl $(PERLASM_SCHEME)
-+
-+GENERATE[aes-armv4.S]=asm/aes-armv4.pl $(PERLASM_SCHEME)
-+INCLUDE[aes-armv4.o]=..
-+GENERATE[bsaes-armv7.S]=asm/bsaes-armv7.pl $(PERLASM_SCHEME)
-+INCLUDE[bsaes-armv7.o]=..
-+
-+BEGINRAW[Makefile]
-+##### AES assembler implementations
-+
-+# GNU make "catch all"
-+{- $builddir -}/aes-%.S:	{- $sourcedir -}/asm/aes-%.pl
-+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-+{- $builddir -}/bsaes-%.S:	{- $sourcedir -}/asm/bsaes-%.pl
-+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-+
-+ENDRAW[Makefile]
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/alphacpuid.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/alphacpuid.pl
-new file mode 100644
-index 0000000..6c7fd4c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/alphacpuid.pl
-@@ -0,0 +1,257 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+print <<'___';
-+.text
-+
-+.set	noat
-+
-+.globl	OPENSSL_cpuid_setup
-+.ent	OPENSSL_cpuid_setup
-+OPENSSL_cpuid_setup:
-+	.frame	$30,0,$26
-+	.prologue 0
-+	ret	($26)
-+.end	OPENSSL_cpuid_setup
-+
-+.globl	OPENSSL_wipe_cpu
-+.ent	OPENSSL_wipe_cpu
-+OPENSSL_wipe_cpu:
-+	.frame	$30,0,$26
-+	.prologue 0
-+	clr	$1
-+	clr	$2
-+	clr	$3
-+	clr	$4
-+	clr	$5
-+	clr	$6
-+	clr	$7
-+	clr	$8
-+	clr	$16
-+	clr	$17
-+	clr	$18
-+	clr	$19
-+	clr	$20
-+	clr	$21
-+	clr	$22
-+	clr	$23
-+	clr	$24
-+	clr	$25
-+	clr	$27
-+	clr	$at
-+	clr	$29
-+	fclr	$f0
-+	fclr	$f1
-+	fclr	$f10
-+	fclr	$f11
-+	fclr	$f12
-+	fclr	$f13
-+	fclr	$f14
-+	fclr	$f15
-+	fclr	$f16
-+	fclr	$f17
-+	fclr	$f18
-+	fclr	$f19
-+	fclr	$f20
-+	fclr	$f21
-+	fclr	$f22
-+	fclr	$f23
-+	fclr	$f24
-+	fclr	$f25
-+	fclr	$f26
-+	fclr	$f27
-+	fclr	$f28
-+	fclr	$f29
-+	fclr	$f30
-+	mov	$sp,$0
-+	ret	($26)
-+.end	OPENSSL_wipe_cpu
-+
-+.globl	OPENSSL_atomic_add
-+.ent	OPENSSL_atomic_add
-+OPENSSL_atomic_add:
-+	.frame	$30,0,$26
-+	.prologue 0
-+1:	ldl_l	$0,0($16)
-+	addl	$0,$17,$1
-+	stl_c	$1,0($16)
-+	beq	$1,1b
-+	addl	$0,$17,$0
-+	ret	($26)
-+.end	OPENSSL_atomic_add
-+
-+.globl	OPENSSL_rdtsc
-+.ent	OPENSSL_rdtsc
-+OPENSSL_rdtsc:
-+	.frame	$30,0,$26
-+	.prologue 0
-+	rpcc	$0
-+	ret	($26)
-+.end	OPENSSL_rdtsc
-+
-+.globl	OPENSSL_cleanse
-+.ent	OPENSSL_cleanse
-+OPENSSL_cleanse:
-+	.frame	$30,0,$26
-+	.prologue 0
-+	beq	$17,.Ldone
-+	and	$16,7,$0
-+	bic	$17,7,$at
-+	beq	$at,.Little
-+	beq	$0,.Laligned
-+
-+.Little:
-+	subq	$0,8,$0
-+	ldq_u	$1,0($16)
-+	mov	$16,$2
-+.Lalign:
-+	mskbl	$1,$16,$1
-+	lda	$16,1($16)
-+	subq	$17,1,$17
-+	addq	$0,1,$0
-+	beq	$17,.Lout
-+	bne	$0,.Lalign
-+.Lout:	stq_u	$1,0($2)
-+	beq	$17,.Ldone
-+	bic	$17,7,$at
-+	beq	$at,.Little
-+
-+.Laligned:
-+	stq	$31,0($16)
-+	subq	$17,8,$17
-+	lda	$16,8($16)
-+	bic	$17,7,$at
-+	bne	$at,.Laligned
-+	bne	$17,.Little
-+.Ldone: ret	($26)
-+.end	OPENSSL_cleanse
-+
-+.globl	CRYPTO_memcmp
-+.ent	CRYPTO_memcmp
-+CRYPTO_memcmp:
-+	.frame	$30,0,$26
-+	.prologue 0
-+	xor	$0,$0,$0
-+	beq	$18,.Lno_data
-+
-+	xor	$1,$1,$1
-+	nop
-+.Loop_cmp:
-+	ldq_u	$2,0($16)
-+	subq	$18,1,$18
-+	ldq_u	$3,0($17)
-+	extbl	$2,$16,$2
-+	lda	$16,1($16)
-+	extbl	$3,$17,$3
-+	lda	$17,1($17)
-+	xor	$3,$2,$2
-+	or	$2,$0,$0
-+	bne	$18,.Loop_cmp
-+
-+	subq	$31,$0,$0
-+	srl	$0,63,$0
-+.Lno_data:
-+	ret	($26)
-+.end	CRYPTO_memcmp
-+___
-+{
-+my ($out,$cnt,$max)=("\$16","\$17","\$18");
-+my ($tick,$lasttick)=("\$19","\$20");
-+my ($diff,$lastdiff)=("\$21","\$22");
-+my ($v0,$ra,$sp,$zero)=("\$0","\$26","\$30","\$31");
-+
-+print <<___;
-+.globl	OPENSSL_instrument_bus
-+.ent	OPENSSL_instrument_bus
-+OPENSSL_instrument_bus:
-+	.frame	$sp,0,$ra
-+	.prologue 0
-+	mov	$cnt,$v0
-+
-+	rpcc	$lasttick
-+	mov	0,$diff
-+
-+	ecb	($out)
-+	ldl_l	$tick,0($out)
-+	addl	$diff,$tick,$tick
-+	mov	$tick,$diff
-+	stl_c	$tick,0($out)
-+	stl	$diff,0($out)
-+
-+.Loop:	rpcc	$tick
-+	subq	$tick,$lasttick,$diff
-+	mov	$tick,$lasttick
-+
-+	ecb	($out)
-+	ldl_l	$tick,0($out)
-+	addl	$diff,$tick,$tick
-+	mov	$tick,$diff
-+	stl_c	$tick,0($out)
-+	stl	$diff,0($out)
-+
-+	subl	$cnt,1,$cnt
-+	lda	$out,4($out)
-+	bne	$cnt,.Loop
-+
-+	ret	($ra)
-+.end	OPENSSL_instrument_bus
-+
-+.globl	OPENSSL_instrument_bus2
-+.ent	OPENSSL_instrument_bus2
-+OPENSSL_instrument_bus2:
-+	.frame	$sp,0,$ra
-+	.prologue 0
-+	mov	$cnt,$v0
-+
-+	rpcc	$lasttick
-+	mov	0,$diff
-+
-+	ecb	($out)
-+	ldl_l	$tick,0($out)
-+	addl	$diff,$tick,$tick
-+	mov	$tick,$diff
-+	stl_c	$tick,0($out)
-+	stl	$diff,0($out)
-+
-+	rpcc	$tick
-+	subq	$tick,$lasttick,$diff
-+	mov	$tick,$lasttick
-+	mov	$diff,$lastdiff
-+.Loop2:
-+	ecb	($out)
-+	ldl_l	$tick,0($out)
-+	addl	$diff,$tick,$tick
-+	mov	$tick,$diff
-+	stl_c	$tick,0($out)
-+	stl	$diff,0($out)
-+
-+	subl	$max,1,$max
-+	beq	$max,.Ldone2
-+
-+	rpcc	$tick
-+	subq	$tick,$lasttick,$diff
-+	mov	$tick,$lasttick
-+	subq	$lastdiff,$diff,$tick
-+	mov	$diff,$lastdiff
-+	cmovne	$tick,1,$tick
-+	subl	$cnt,$tick,$cnt
-+	s4addq	$tick,$out,$out
-+	bne	$cnt,.Loop2
-+
-+.Ldone2:
-+	subl	$v0,$cnt,$v0
-+	ret	($ra)
-+.end	OPENSSL_instrument_bus2
-+___
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/arm64cpuid.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/arm64cpuid.pl
-new file mode 100755
-index 0000000..caa3387
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/arm64cpuid.pl
-@@ -0,0 +1,126 @@
-+#! /usr/bin/env perl
-+# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+$flavour = shift;
-+$output  = shift;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+$code.=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+.arch	armv8-a+crypto
-+
-+.align	5
-+.globl	_armv7_neon_probe
-+.type	_armv7_neon_probe,%function
-+_armv7_neon_probe:
-+	orr	v15.16b, v15.16b, v15.16b
-+	ret
-+.size	_armv7_neon_probe,.-_armv7_neon_probe
-+
-+.globl	_armv7_tick
-+.type	_armv7_tick,%function
-+_armv7_tick:
-+#ifdef	__APPLE__
-+	mrs	x0, CNTPCT_EL0
-+#else
-+	mrs	x0, CNTVCT_EL0
-+#endif
-+	ret
-+.size	_armv7_tick,.-_armv7_tick
-+
-+.globl	_armv8_aes_probe
-+.type	_armv8_aes_probe,%function
-+_armv8_aes_probe:
-+	aese	v0.16b, v0.16b
-+	ret
-+.size	_armv8_aes_probe,.-_armv8_aes_probe
-+
-+.globl	_armv8_sha1_probe
-+.type	_armv8_sha1_probe,%function
-+_armv8_sha1_probe:
-+	sha1h	s0, s0
-+	ret
-+.size	_armv8_sha1_probe,.-_armv8_sha1_probe
-+
-+.globl	_armv8_sha256_probe
-+.type	_armv8_sha256_probe,%function
-+_armv8_sha256_probe:
-+	sha256su0	v0.4s, v0.4s
-+	ret
-+.size	_armv8_sha256_probe,.-_armv8_sha256_probe
-+.globl	_armv8_pmull_probe
-+.type	_armv8_pmull_probe,%function
-+_armv8_pmull_probe:
-+	pmull	v0.1q, v0.1d, v0.1d
-+	ret
-+.size	_armv8_pmull_probe,.-_armv8_pmull_probe
-+
-+.globl	OPENSSL_cleanse
-+.type	OPENSSL_cleanse,%function
-+.align	5
-+OPENSSL_cleanse:
-+	cbz	x1,.Lret	// len==0?
-+	cmp	x1,#15
-+	b.hi	.Lot		// len>15
-+	nop
-+.Little:
-+	strb	wzr,[x0],#1	// store byte-by-byte
-+	subs	x1,x1,#1
-+	b.ne	.Little
-+.Lret:	ret
-+
-+.align	4
-+.Lot:	tst	x0,#7
-+	b.eq	.Laligned	// inp is aligned
-+	strb	wzr,[x0],#1	// store byte-by-byte
-+	sub	x1,x1,#1
-+	b	.Lot
-+
-+.align	4
-+.Laligned:
-+	str	xzr,[x0],#8	// store word-by-word
-+	sub	x1,x1,#8
-+	tst	x1,#-8
-+	b.ne	.Laligned	// len>=8
-+	cbnz	x1,.Little	// len!=0?
-+	ret
-+.size	OPENSSL_cleanse,.-OPENSSL_cleanse
-+
-+.globl	CRYPTO_memcmp
-+.type	CRYPTO_memcmp,%function
-+.align	4
-+CRYPTO_memcmp:
-+	eor	w3,w3,w3
-+	cbz	x2,.Lno_data	// len==0?
-+.Loop_cmp:
-+	ldrb	w4,[x0],#1
-+	ldrb	w5,[x1],#1
-+	eor	w4,w4,w5
-+	orr	w3,w3,w4
-+	subs	x2,x2,#1
-+	b.ne	.Loop_cmp
-+
-+.Lno_data:
-+	neg	w0,w3
-+	lsr	w0,w0,#31
-+	ret
-+.size	CRYPTO_memcmp,.-CRYPTO_memcmp
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/arm_arch.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/arm_arch.h
-new file mode 100644
-index 0000000..3fc9e69
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/arm_arch.h
-@@ -0,0 +1,83 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef __ARM_ARCH_H__
-+# define __ARM_ARCH_H__
-+
-+# if !defined(__ARM_ARCH__)
-+#  if defined(__CC_ARM)
-+#   define __ARM_ARCH__ __TARGET_ARCH_ARM
-+#   if defined(__BIG_ENDIAN)
-+#    define __ARMEB__
-+#   else
-+#    define __ARMEL__
-+#   endif
-+#  elif defined(__GNUC__)
-+#   if   defined(__aarch64__)
-+#    define __ARM_ARCH__ 8
-+#    if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
-+#     define __ARMEB__
-+#    else
-+#     define __ARMEL__
-+#    endif
-+  /*
-+   * Why doesn't gcc define __ARM_ARCH__? Instead it defines
-+   * bunch of below macros. See all_architectires[] table in
-+   * gcc/config/arm/arm.c. On a side note it defines
-+   * __ARMEL__/__ARMEB__ for little-/big-endian.
-+   */
-+#   elif defined(__ARM_ARCH)
-+#    define __ARM_ARCH__ __ARM_ARCH
-+#   elif defined(__ARM_ARCH_8A__)
-+#    define __ARM_ARCH__ 8
-+#   elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)     || \
-+        defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__)     || \
-+        defined(__ARM_ARCH_7EM__)
-+#    define __ARM_ARCH__ 7
-+#   elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__)     || \
-+        defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__)     || \
-+        defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__)    || \
-+        defined(__ARM_ARCH_6T2__)
-+#    define __ARM_ARCH__ 6
-+#   elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__)     || \
-+        defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__)    || \
-+        defined(__ARM_ARCH_5TEJ__)
-+#    define __ARM_ARCH__ 5
-+#   elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
-+#    define __ARM_ARCH__ 4
-+#   else
-+#    error "unsupported ARM architecture"
-+#   endif
-+#  endif
-+# endif
-+
-+# if !defined(__ARM_MAX_ARCH__)
-+#  define __ARM_MAX_ARCH__ __ARM_ARCH__
-+# endif
-+
-+# if __ARM_MAX_ARCH__<__ARM_ARCH__
-+#  error "__ARM_MAX_ARCH__ can't be less than __ARM_ARCH__"
-+# elif __ARM_MAX_ARCH__!=__ARM_ARCH__
-+#  if __ARM_ARCH__<7 && __ARM_MAX_ARCH__>=7 && defined(__ARMEB__)
-+#   error "can't build universal big-endian binary"
-+#  endif
-+# endif
-+
-+# if !__ASSEMBLER__
-+extern unsigned int OPENSSL_armcap_P;
-+# endif
-+
-+# define ARMV7_NEON      (1<<0)
-+# define ARMV7_TICK      (1<<1)
-+# define ARMV8_AES       (1<<2)
-+# define ARMV8_SHA1      (1<<3)
-+# define ARMV8_SHA256    (1<<4)
-+# define ARMV8_PMULL     (1<<5)
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/armcap.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/armcap.c
-new file mode 100644
-index 0000000..2953484
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/armcap.c
-@@ -0,0 +1,193 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include "arm_arch.h"
-+
-+unsigned int OPENSSL_armcap_P = 0;
-+
-+#if __ARM_MAX_ARCH__<7
-+void OPENSSL_cpuid_setup(void)
-+{
-+}
-+
-+unsigned long OPENSSL_rdtsc(void)
-+{
-+    return 0;
-+}
-+#else
-+static sigset_t all_masked;
-+
-+static sigjmp_buf ill_jmp;
-+static void ill_handler(int sig)
-+{
-+    siglongjmp(ill_jmp, sig);
-+}
-+
-+/*
-+ * Following subroutines could have been inlined, but it's not all
-+ * ARM compilers support inline assembler...
-+ */
-+void _armv7_neon_probe(void);
-+void _armv8_aes_probe(void);
-+void _armv8_sha1_probe(void);
-+void _armv8_sha256_probe(void);
-+void _armv8_pmull_probe(void);
-+unsigned long _armv7_tick(void);
-+
-+unsigned long OPENSSL_rdtsc(void)
-+{
-+    if (OPENSSL_armcap_P & ARMV7_TICK)
-+        return _armv7_tick();
-+    else
-+        return 0;
-+}
-+
-+# if defined(__GNUC__) && __GNUC__>=2
-+void OPENSSL_cpuid_setup(void) __attribute__ ((constructor));
-+# endif
-+/*
-+ * Use a weak reference to getauxval() so we can use it if it is available but
-+ * don't break the build if it is not.
-+ */
-+# if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__)
-+extern unsigned long getauxval(unsigned long type) __attribute__ ((weak));
-+# else
-+static unsigned long (*getauxval) (unsigned long) = NULL;
-+# endif
-+
-+/*
-+ * ARM puts the the feature bits for Crypto Extensions in AT_HWCAP2, whereas
-+ * AArch64 used AT_HWCAP.
-+ */
-+# if defined(__arm__) || defined (__arm)
-+#  define HWCAP                  16
-+                                  /* AT_HWCAP */
-+#  define HWCAP_NEON             (1 << 12)
-+
-+#  define HWCAP_CE               26
-+                                  /* AT_HWCAP2 */
-+#  define HWCAP_CE_AES           (1 << 0)
-+#  define HWCAP_CE_PMULL         (1 << 1)
-+#  define HWCAP_CE_SHA1          (1 << 2)
-+#  define HWCAP_CE_SHA256        (1 << 3)
-+# elif defined(__aarch64__)
-+#  define HWCAP                  16
-+                                  /* AT_HWCAP */
-+#  define HWCAP_NEON             (1 << 1)
-+
-+#  define HWCAP_CE               HWCAP
-+#  define HWCAP_CE_AES           (1 << 3)
-+#  define HWCAP_CE_PMULL         (1 << 4)
-+#  define HWCAP_CE_SHA1          (1 << 5)
-+#  define HWCAP_CE_SHA256        (1 << 6)
-+# endif
-+
-+void OPENSSL_cpuid_setup(void)
-+{
-+    char *e;
-+    struct sigaction ill_oact, ill_act;
-+    sigset_t oset;
-+    static int trigger = 0;
-+
-+    if (trigger)
-+        return;
-+    trigger = 1;
-+
-+    if ((e = getenv("OPENSSL_armcap"))) {
-+        OPENSSL_armcap_P = (unsigned int)strtoul(e, NULL, 0);
-+        return;
-+    }
-+
-+# if defined(__APPLE__) && !defined(__aarch64__)
-+    /*
-+     * Capability probing by catching SIGILL appears to be problematic
-+     * on iOS. But since Apple universe is "monocultural", it's actually
-+     * possible to simply set pre-defined processor capability mask.
-+     */
-+    if (1) {
-+        OPENSSL_armcap_P = ARMV7_NEON;
-+        return;
-+    }
-+    /*
-+     * One could do same even for __aarch64__ iOS builds. It's not done
-+     * exclusively for reasons of keeping code unified across platforms.
-+     * Unified code works because it never triggers SIGILL on Apple
-+     * devices...
-+     */
-+# endif
-+
-+    sigfillset(&all_masked);
-+    sigdelset(&all_masked, SIGILL);
-+    sigdelset(&all_masked, SIGTRAP);
-+    sigdelset(&all_masked, SIGFPE);
-+    sigdelset(&all_masked, SIGBUS);
-+    sigdelset(&all_masked, SIGSEGV);
-+
-+    OPENSSL_armcap_P = 0;
-+
-+    memset(&ill_act, 0, sizeof(ill_act));
-+    ill_act.sa_handler = ill_handler;
-+    ill_act.sa_mask = all_masked;
-+
-+    sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
-+    sigaction(SIGILL, &ill_act, &ill_oact);
-+
-+    if (getauxval != NULL) {
-+        if (getauxval(HWCAP) & HWCAP_NEON) {
-+            unsigned long hwcap = getauxval(HWCAP_CE);
-+
-+            OPENSSL_armcap_P |= ARMV7_NEON;
-+
-+            if (hwcap & HWCAP_CE_AES)
-+                OPENSSL_armcap_P |= ARMV8_AES;
-+
-+            if (hwcap & HWCAP_CE_PMULL)
-+                OPENSSL_armcap_P |= ARMV8_PMULL;
-+
-+            if (hwcap & HWCAP_CE_SHA1)
-+                OPENSSL_armcap_P |= ARMV8_SHA1;
-+
-+            if (hwcap & HWCAP_CE_SHA256)
-+                OPENSSL_armcap_P |= ARMV8_SHA256;
-+        }
-+    } else if (sigsetjmp(ill_jmp, 1) == 0) {
-+        _armv7_neon_probe();
-+        OPENSSL_armcap_P |= ARMV7_NEON;
-+        if (sigsetjmp(ill_jmp, 1) == 0) {
-+            _armv8_pmull_probe();
-+            OPENSSL_armcap_P |= ARMV8_PMULL | ARMV8_AES;
-+        } else if (sigsetjmp(ill_jmp, 1) == 0) {
-+            _armv8_aes_probe();
-+            OPENSSL_armcap_P |= ARMV8_AES;
-+        }
-+        if (sigsetjmp(ill_jmp, 1) == 0) {
-+            _armv8_sha1_probe();
-+            OPENSSL_armcap_P |= ARMV8_SHA1;
-+        }
-+        if (sigsetjmp(ill_jmp, 1) == 0) {
-+            _armv8_sha256_probe();
-+            OPENSSL_armcap_P |= ARMV8_SHA256;
-+        }
-+    }
-+    if (sigsetjmp(ill_jmp, 1) == 0) {
-+        _armv7_tick();
-+        OPENSSL_armcap_P |= ARMV7_TICK;
-+    }
-+
-+    sigaction(SIGILL, &ill_oact, NULL);
-+    sigprocmask(SIG_SETMASK, &oset, NULL);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/armv4cpuid.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/armv4cpuid.pl
-new file mode 100644
-index 0000000..f7d31a6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/armv4cpuid.pl
-@@ -0,0 +1,296 @@
-+#! /usr/bin/env perl
-+# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+$flavour = shift;
-+$output  = shift;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+$code.=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+#if defined(__thumb2__) && !defined(__APPLE__)
-+.syntax	unified
-+.thumb
-+#else
-+.code	32
-+#undef	__thumb2__
-+#endif
-+
-+.align	5
-+.global	OPENSSL_atomic_add
-+.type	OPENSSL_atomic_add,%function
-+OPENSSL_atomic_add:
-+#if __ARM_ARCH__>=6
-+.Ladd:	ldrex	r2,[r0]
-+	add	r3,r2,r1
-+	strex	r2,r3,[r0]
-+	cmp	r2,#0
-+	bne	.Ladd
-+	mov	r0,r3
-+	bx	lr
-+#else
-+	stmdb	sp!,{r4-r6,lr}
-+	ldr	r2,.Lspinlock
-+	adr	r3,.Lspinlock
-+	mov	r4,r0
-+	mov	r5,r1
-+	add	r6,r3,r2	@ &spinlock
-+	b	.+8
-+.Lspin:	bl	sched_yield
-+	mov	r0,#-1
-+	swp	r0,r0,[r6]
-+	cmp	r0,#0
-+	bne	.Lspin
-+
-+	ldr	r2,[r4]
-+	add	r2,r2,r5
-+	str	r2,[r4]
-+	str	r0,[r6]		@ release spinlock
-+	ldmia	sp!,{r4-r6,lr}
-+	tst	lr,#1
-+	moveq	pc,lr
-+	.word	0xe12fff1e	@ bx	lr
-+#endif
-+.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
-+
-+.global	OPENSSL_cleanse
-+.type	OPENSSL_cleanse,%function
-+OPENSSL_cleanse:
-+	eor	ip,ip,ip
-+	cmp	r1,#7
-+#ifdef	__thumb2__
-+	itt	hs
-+#endif
-+	subhs	r1,r1,#4
-+	bhs	.Lot
-+	cmp	r1,#0
-+	beq	.Lcleanse_done
-+.Little:
-+	strb	ip,[r0],#1
-+	subs	r1,r1,#1
-+	bhi	.Little
-+	b	.Lcleanse_done
-+
-+.Lot:	tst	r0,#3
-+	beq	.Laligned
-+	strb	ip,[r0],#1
-+	sub	r1,r1,#1
-+	b	.Lot
-+.Laligned:
-+	str	ip,[r0],#4
-+	subs	r1,r1,#4
-+	bhs	.Laligned
-+	adds	r1,r1,#4
-+	bne	.Little
-+.Lcleanse_done:
-+#if __ARM_ARCH__>=5
-+	bx	lr
-+#else
-+	tst	lr,#1
-+	moveq	pc,lr
-+	.word	0xe12fff1e	@ bx	lr
-+#endif
-+.size	OPENSSL_cleanse,.-OPENSSL_cleanse
-+
-+.global	CRYPTO_memcmp
-+.type	CRYPTO_memcmp,%function
-+.align	4
-+CRYPTO_memcmp:
-+	eor	ip,ip,ip
-+	cmp	r2,#0
-+	beq	.Lno_data
-+	stmdb	sp!,{r4,r5}
-+
-+.Loop_cmp:
-+	ldrb	r4,[r0],#1
-+	ldrb	r5,[r1],#1
-+	eor	r4,r4,r5
-+	orr	ip,ip,r4
-+	subs	r2,r2,#1
-+	bne	.Loop_cmp
-+
-+	ldmia	sp!,{r4,r5}
-+.Lno_data:
-+	neg	r0,ip
-+	mov	r0,r0,lsr#31
-+#if __ARM_ARCH__>=5
-+	bx	lr
-+#else
-+	tst	lr,#1
-+	moveq	pc,lr
-+	.word	0xe12fff1e	@ bx	lr
-+#endif
-+.size	CRYPTO_memcmp,.-CRYPTO_memcmp
-+
-+#if __ARM_MAX_ARCH__>=7
-+.arch	armv7-a
-+.fpu	neon
-+
-+.align	5
-+.global	_armv7_neon_probe
-+.type	_armv7_neon_probe,%function
-+_armv7_neon_probe:
-+	vorr	q0,q0,q0
-+	bx	lr
-+.size	_armv7_neon_probe,.-_armv7_neon_probe
-+
-+.global	_armv7_tick
-+.type	_armv7_tick,%function
-+_armv7_tick:
-+#ifdef	__APPLE__
-+	mrrc	p15,0,r0,r1,c14		@ CNTPCT
-+#else
-+	mrrc	p15,1,r0,r1,c14		@ CNTVCT
-+#endif
-+	bx	lr
-+.size	_armv7_tick,.-_armv7_tick
-+
-+.global	_armv8_aes_probe
-+.type	_armv8_aes_probe,%function
-+_armv8_aes_probe:
-+#if defined(__thumb2__) && !defined(__APPLE__)
-+	.byte	0xb0,0xff,0x00,0x03	@ aese.8	q0,q0
-+#else
-+	.byte	0x00,0x03,0xb0,0xf3	@ aese.8	q0,q0
-+#endif
-+	bx	lr
-+.size	_armv8_aes_probe,.-_armv8_aes_probe
-+
-+.global	_armv8_sha1_probe
-+.type	_armv8_sha1_probe,%function
-+_armv8_sha1_probe:
-+#if defined(__thumb2__) && !defined(__APPLE__)
-+	.byte	0x00,0xef,0x40,0x0c	@ sha1c.32	q0,q0,q0
-+#else
-+	.byte	0x40,0x0c,0x00,0xf2	@ sha1c.32	q0,q0,q0
-+#endif
-+	bx	lr
-+.size	_armv8_sha1_probe,.-_armv8_sha1_probe
-+
-+.global	_armv8_sha256_probe
-+.type	_armv8_sha256_probe,%function
-+_armv8_sha256_probe:
-+#if defined(__thumb2__) && !defined(__APPLE__)
-+	.byte	0x00,0xff,0x40,0x0c	@ sha256h.32	q0,q0,q0
-+#else
-+	.byte	0x40,0x0c,0x00,0xf3	@ sha256h.32	q0,q0,q0
-+#endif
-+	bx	lr
-+.size	_armv8_sha256_probe,.-_armv8_sha256_probe
-+.global	_armv8_pmull_probe
-+.type	_armv8_pmull_probe,%function
-+_armv8_pmull_probe:
-+#if defined(__thumb2__) && !defined(__APPLE__)
-+	.byte	0xa0,0xef,0x00,0x0e	@ vmull.p64	q0,d0,d0
-+#else
-+	.byte	0x00,0x0e,0xa0,0xf2	@ vmull.p64	q0,d0,d0
-+#endif
-+	bx	lr
-+.size	_armv8_pmull_probe,.-_armv8_pmull_probe
-+#endif
-+
-+.global	OPENSSL_wipe_cpu
-+.type	OPENSSL_wipe_cpu,%function
-+OPENSSL_wipe_cpu:
-+#if __ARM_MAX_ARCH__>=7
-+	ldr	r0,.LOPENSSL_armcap
-+	adr	r1,.LOPENSSL_armcap
-+	ldr	r0,[r1,r0]
-+#ifdef	__APPLE__
-+	ldr	r0,[r0]
-+#endif
-+#endif
-+	eor	r2,r2,r2
-+	eor	r3,r3,r3
-+	eor	ip,ip,ip
-+#if __ARM_MAX_ARCH__>=7
-+	tst	r0,#1
-+	beq	.Lwipe_done
-+	veor	q0, q0, q0
-+	veor	q1, q1, q1
-+	veor	q2, q2, q2
-+	veor	q3, q3, q3
-+	veor	q8, q8, q8
-+	veor	q9, q9, q9
-+	veor	q10, q10, q10
-+	veor	q11, q11, q11
-+	veor	q12, q12, q12
-+	veor	q13, q13, q13
-+	veor	q14, q14, q14
-+	veor	q15, q15, q15
-+.Lwipe_done:
-+#endif
-+	mov	r0,sp
-+#if __ARM_ARCH__>=5
-+	bx	lr
-+#else
-+	tst	lr,#1
-+	moveq	pc,lr
-+	.word	0xe12fff1e	@ bx	lr
-+#endif
-+.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
-+
-+.global	OPENSSL_instrument_bus
-+.type	OPENSSL_instrument_bus,%function
-+OPENSSL_instrument_bus:
-+	eor	r0,r0,r0
-+#if __ARM_ARCH__>=5
-+	bx	lr
-+#else
-+	tst	lr,#1
-+	moveq	pc,lr
-+	.word	0xe12fff1e	@ bx	lr
-+#endif
-+.size	OPENSSL_instrument_bus,.-OPENSSL_instrument_bus
-+
-+.global	OPENSSL_instrument_bus2
-+.type	OPENSSL_instrument_bus2,%function
-+OPENSSL_instrument_bus2:
-+	eor	r0,r0,r0
-+#if __ARM_ARCH__>=5
-+	bx	lr
-+#else
-+	tst	lr,#1
-+	moveq	pc,lr
-+	.word	0xe12fff1e	@ bx	lr
-+#endif
-+.size	OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2
-+
-+.align	5
-+#if __ARM_MAX_ARCH__>=7
-+.LOPENSSL_armcap:
-+.word	OPENSSL_armcap_P-.
-+#endif
-+#if __ARM_ARCH__>=6
-+.align	5
-+#else
-+.Lspinlock:
-+.word	atomic_add_spinlock-.Lspinlock
-+.align	5
-+
-+.data
-+.align	2
-+atomic_add_spinlock:
-+.word	0
-+#endif
-+
-+.comm	OPENSSL_armcap_P,4,4
-+.hidden	OPENSSL_armcap_P
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_bitstr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_bitstr.c
-new file mode 100644
-index 0000000..33be907
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_bitstr.c
-@@ -0,0 +1,210 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "asn1_locl.h"
-+
-+int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
-+{
-+    return ASN1_STRING_set(x, d, len);
-+}
-+
-+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
-+{
-+    int ret, j, bits, len;
-+    unsigned char *p, *d;
-+
-+    if (a == NULL)
-+        return (0);
-+
-+    len = a->length;
-+
-+    if (len > 0) {
-+        if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
-+            bits = (int)a->flags & 0x07;
-+        } else {
-+            for (; len > 0; len--) {
-+                if (a->data[len - 1])
-+                    break;
-+            }
-+            j = a->data[len - 1];
-+            if (j & 0x01)
-+                bits = 0;
-+            else if (j & 0x02)
-+                bits = 1;
-+            else if (j & 0x04)
-+                bits = 2;
-+            else if (j & 0x08)
-+                bits = 3;
-+            else if (j & 0x10)
-+                bits = 4;
-+            else if (j & 0x20)
-+                bits = 5;
-+            else if (j & 0x40)
-+                bits = 6;
-+            else if (j & 0x80)
-+                bits = 7;
-+            else
-+                bits = 0;       /* should not happen */
-+        }
-+    } else
-+        bits = 0;
-+
-+    ret = 1 + len;
-+    if (pp == NULL)
-+        return (ret);
-+
-+    p = *pp;
-+
-+    *(p++) = (unsigned char)bits;
-+    d = a->data;
-+    if (len > 0) {
-+        memcpy(p, d, len);
-+        p += len;
-+        p[-1] &= (0xff << bits);
-+    }
-+    *pp = p;
-+    return (ret);
-+}
-+
-+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
-+                                     const unsigned char **pp, long len)
-+{
-+    ASN1_BIT_STRING *ret = NULL;
-+    const unsigned char *p;
-+    unsigned char *s;
-+    int i;
-+
-+    if (len < 1) {
-+        i = ASN1_R_STRING_TOO_SHORT;
-+        goto err;
-+    }
-+
-+    if ((a == NULL) || ((*a) == NULL)) {
-+        if ((ret = ASN1_BIT_STRING_new()) == NULL)
-+            return (NULL);
-+    } else
-+        ret = (*a);
-+
-+    p = *pp;
-+    i = *(p++);
-+    if (i > 7) {
-+        i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
-+        goto err;
-+    }
-+    /*
-+     * We do this to preserve the settings.  If we modify the settings, via
-+     * the _set_bit function, we will recalculate on output
-+     */
-+    ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
-+    ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */
-+
-+    if (len-- > 1) {            /* using one because of the bits left byte */
-+        s = OPENSSL_malloc((int)len);
-+        if (s == NULL) {
-+            i = ERR_R_MALLOC_FAILURE;
-+            goto err;
-+        }
-+        memcpy(s, p, (int)len);
-+        s[len - 1] &= (0xff << i);
-+        p += len;
-+    } else
-+        s = NULL;
-+
-+    ret->length = (int)len;
-+    OPENSSL_free(ret->data);
-+    ret->data = s;
-+    ret->type = V_ASN1_BIT_STRING;
-+    if (a != NULL)
-+        (*a) = ret;
-+    *pp = p;
-+    return (ret);
-+ err:
-+    ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i);
-+    if ((a == NULL) || (*a != ret))
-+        ASN1_BIT_STRING_free(ret);
-+    return (NULL);
-+}
-+
-+/*
-+ * These next 2 functions from Goetz Babin-Ebell 
-+ */
-+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
-+{
-+    int w, v, iv;
-+    unsigned char *c;
-+
-+    w = n / 8;
-+    v = 1 << (7 - (n & 0x07));
-+    iv = ~v;
-+    if (!value)
-+        v = 0;
-+
-+    if (a == NULL)
-+        return 0;
-+
-+    a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
-+
-+    if ((a->length < (w + 1)) || (a->data == NULL)) {
-+        if (!value)
-+            return (1);         /* Don't need to set */
-+        c = OPENSSL_clear_realloc(a->data, a->length, w + 1);
-+        if (c == NULL) {
-+            ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        if (w + 1 - a->length > 0)
-+            memset(c + a->length, 0, w + 1 - a->length);
-+        a->data = c;
-+        a->length = w + 1;
-+    }
-+    a->data[w] = ((a->data[w]) & iv) | v;
-+    while ((a->length > 0) && (a->data[a->length - 1] == 0))
-+        a->length--;
-+    return (1);
-+}
-+
-+int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
-+{
-+    int w, v;
-+
-+    w = n / 8;
-+    v = 1 << (7 - (n & 0x07));
-+    if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
-+        return (0);
-+    return ((a->data[w] & v) != 0);
-+}
-+
-+/*
-+ * Checks if the given bit string contains only bits specified by
-+ * the flags vector. Returns 0 if there is at least one bit set in 'a'
-+ * which is not specified in 'flags', 1 otherwise.
-+ * 'len' is the length of 'flags'.
-+ */
-+int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a,
-+                          const unsigned char *flags, int flags_len)
-+{
-+    int i, ok;
-+    /* Check if there is one bit set at all. */
-+    if (!a || !a->data)
-+        return 1;
-+
-+    /*
-+     * Check each byte of the internal representation of the bit string.
-+     */
-+    ok = 1;
-+    for (i = 0; i < a->length && ok; ++i) {
-+        unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
-+        /* We are done if there is an unneeded bit set. */
-+        ok = (a->data[i] & mask) == 0;
-+    }
-+    return ok;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_d2i_fp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_d2i_fp.c
-new file mode 100644
-index 0000000..e5c1d0e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_d2i_fp.c
-@@ -0,0 +1,235 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include "internal/numbers.h"
-+#include 
-+#include 
-+
-+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
-+
-+#ifndef NO_OLD_ASN1
-+# ifndef OPENSSL_NO_STDIO
-+
-+void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x)
-+{
-+    BIO *b;
-+    void *ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB);
-+        return (NULL);
-+    }
-+    BIO_set_fp(b, in, BIO_NOCLOSE);
-+    ret = ASN1_d2i_bio(xnew, d2i, b, x);
-+    BIO_free(b);
-+    return (ret);
-+}
-+# endif
-+
-+void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x)
-+{
-+    BUF_MEM *b = NULL;
-+    const unsigned char *p;
-+    void *ret = NULL;
-+    int len;
-+
-+    len = asn1_d2i_read_bio(in, &b);
-+    if (len < 0)
-+        goto err;
-+
-+    p = (unsigned char *)b->data;
-+    ret = d2i(x, &p, len);
-+ err:
-+    BUF_MEM_free(b);
-+    return (ret);
-+}
-+
-+#endif
-+
-+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
-+{
-+    BUF_MEM *b = NULL;
-+    const unsigned char *p;
-+    void *ret = NULL;
-+    int len;
-+
-+    len = asn1_d2i_read_bio(in, &b);
-+    if (len < 0)
-+        goto err;
-+
-+    p = (const unsigned char *)b->data;
-+    ret = ASN1_item_d2i(x, &p, len, it);
-+ err:
-+    BUF_MEM_free(b);
-+    return (ret);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
-+{
-+    BIO *b;
-+    char *ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB);
-+        return (NULL);
-+    }
-+    BIO_set_fp(b, in, BIO_NOCLOSE);
-+    ret = ASN1_item_d2i_bio(it, b, x);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-+
-+#define HEADER_SIZE   8
-+#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
-+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
-+{
-+    BUF_MEM *b;
-+    unsigned char *p;
-+    int i;
-+    size_t want = HEADER_SIZE;
-+    uint32_t eos = 0;
-+    size_t off = 0;
-+    size_t len = 0;
-+
-+    const unsigned char *q;
-+    long slen;
-+    int inf, tag, xclass;
-+
-+    b = BUF_MEM_new();
-+    if (b == NULL) {
-+        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
-+        return -1;
-+    }
-+
-+    ERR_clear_error();
-+    for (;;) {
-+        if (want >= (len - off)) {
-+            want -= (len - off);
-+
-+            if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
-+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            i = BIO_read(in, &(b->data[len]), want);
-+            if ((i < 0) && ((len - off) == 0)) {
-+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA);
-+                goto err;
-+            }
-+            if (i > 0) {
-+                if (len + i < len) {
-+                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
-+                    goto err;
-+                }
-+                len += i;
-+            }
-+        }
-+        /* else data already loaded */
-+
-+        p = (unsigned char *)&(b->data[off]);
-+        q = p;
-+        inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off);
-+        if (inf & 0x80) {
-+            unsigned long e;
-+
-+            e = ERR_GET_REASON(ERR_peek_error());
-+            if (e != ASN1_R_TOO_LONG)
-+                goto err;
-+            else
-+                ERR_clear_error(); /* clear error */
-+        }
-+        i = q - p;            /* header length */
-+        off += i;               /* end of data */
-+
-+        if (inf & 1) {
-+            /* no data body so go round again */
-+            if (eos == UINT32_MAX) {
-+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG);
-+                goto err;
-+            }
-+            eos++;
-+            want = HEADER_SIZE;
-+        } else if (eos && (slen == 0) && (tag == V_ASN1_EOC)) {
-+            /* eos value, so go back and read another header */
-+            eos--;
-+            if (eos == 0)
-+                break;
-+            else
-+                want = HEADER_SIZE;
-+        } else {
-+            /* suck in slen bytes of data */
-+            want = slen;
-+            if (want > (len - off)) {
-+                size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
-+
-+                want -= (len - off);
-+                if (want > INT_MAX /* BIO_read takes an int length */  ||
-+                    len + want < len) {
-+                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
-+                    goto err;
-+                }
-+                while (want > 0) {
-+                    /*
-+                     * Read content in chunks of increasing size
-+                     * so we can return an error for EOF without
-+                     * having to allocate the entire content length
-+                     * in one go.
-+                     */
-+                    size_t chunk = want > chunk_max ? chunk_max : want;
-+
-+                    if (!BUF_MEM_grow_clean(b, len + chunk)) {
-+                        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
-+                        goto err;
-+                    }
-+                    want -= chunk;
-+                    while (chunk > 0) {
-+                        i = BIO_read(in, &(b->data[len]), chunk);
-+                        if (i <= 0) {
-+                            ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
-+                                    ASN1_R_NOT_ENOUGH_DATA);
-+                            goto err;
-+                        }
-+                    /*
-+                     * This can't overflow because |len+want| didn't
-+                     * overflow.
-+                     */
-+                        len += i;
-+                        chunk -= i;
-+                    }
-+                    if (chunk_max < INT_MAX/2)
-+                        chunk_max *= 2;
-+                }
-+            }
-+            if (off + slen < off) {
-+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
-+                goto err;
-+            }
-+            off += slen;
-+            if (eos == 0) {
-+                break;
-+            } else
-+                want = HEADER_SIZE;
-+        }
-+    }
-+
-+    if (off > INT_MAX) {
-+        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
-+        goto err;
-+    }
-+
-+    *pb = b;
-+    return off;
-+ err:
-+    BUF_MEM_free(b);
-+    return -1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_digest.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_digest.c
-new file mode 100644
-index 0000000..46bff0d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_digest.c
-@@ -0,0 +1,66 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+#include "internal/cryptlib.h"
-+
-+#ifndef NO_SYS_TYPES_H
-+# include 
-+#endif
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifndef NO_ASN1_OLD
-+
-+int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
-+                unsigned char *md, unsigned int *len)
-+{
-+    int i;
-+    unsigned char *str, *p;
-+
-+    i = i2d(data, NULL);
-+    if ((str = OPENSSL_malloc(i)) == NULL) {
-+        ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_MALLOC_FAILURE);
-+        return (0);
-+    }
-+    p = str;
-+    i2d(data, &p);
-+
-+    if (!EVP_Digest(str, i, md, len, type, NULL)) {
-+        OPENSSL_free(str);
-+        return 0;
-+    }
-+    OPENSSL_free(str);
-+    return (1);
-+}
-+
-+#endif
-+
-+int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
-+                     unsigned char *md, unsigned int *len)
-+{
-+    int i;
-+    unsigned char *str = NULL;
-+
-+    i = ASN1_item_i2d(asn, &str, it);
-+    if (!str)
-+        return (0);
-+
-+    if (!EVP_Digest(str, i, md, len, type, NULL)) {
-+        OPENSSL_free(str);
-+        return 0;
-+    }
-+    OPENSSL_free(str);
-+    return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_dup.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_dup.c
-new file mode 100644
-index 0000000..d9a57b2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_dup.c
-@@ -0,0 +1,68 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+#ifndef NO_OLD_ASN1
-+
-+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
-+{
-+    unsigned char *b, *p;
-+    const unsigned char *p2;
-+    int i;
-+    char *ret;
-+
-+    if (x == NULL)
-+        return (NULL);
-+
-+    i = i2d(x, NULL);
-+    b = OPENSSL_malloc(i + 10);
-+    if (b == NULL) {
-+        ASN1err(ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+    p = b;
-+    i = i2d(x, &p);
-+    p2 = b;
-+    ret = d2i(NULL, &p2, i);
-+    OPENSSL_free(b);
-+    return (ret);
-+}
-+
-+#endif
-+
-+/*
-+ * ASN1_ITEM version of dup: this follows the model above except we don't
-+ * need to allocate the buffer. At some point this could be rewritten to
-+ * directly dup the underlying structure instead of doing and encode and
-+ * decode.
-+ */
-+
-+void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
-+{
-+    unsigned char *b = NULL;
-+    const unsigned char *p;
-+    long i;
-+    void *ret;
-+
-+    if (x == NULL)
-+        return (NULL);
-+
-+    i = ASN1_item_i2d(x, &b, it);
-+    if (b == NULL) {
-+        ASN1err(ASN1_F_ASN1_ITEM_DUP, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+    p = b;
-+    ret = ASN1_item_d2i(NULL, &p, i, it);
-+    OPENSSL_free(b);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_gentm.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_gentm.c
-new file mode 100644
-index 0000000..c02c8d9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_gentm.c
-@@ -0,0 +1,273 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * GENERALIZEDTIME implementation. Based on UTCTIME
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "asn1_locl.h"
-+
-+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
-+{
-+    static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
-+    static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
-+    char *a;
-+    int n, i, l, o;
-+
-+    if (d->type != V_ASN1_GENERALIZEDTIME)
-+        return (0);
-+    l = d->length;
-+    a = (char *)d->data;
-+    o = 0;
-+    /*
-+     * GENERALIZEDTIME is similar to UTCTIME except the year is represented
-+     * as YYYY. This stuff treats everything as a two digit field so make
-+     * first two fields 00 to 99
-+     */
-+    if (l < 13)
-+        goto err;
-+    for (i = 0; i < 7; i++) {
-+        if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
-+            i++;
-+            if (tm)
-+                tm->tm_sec = 0;
-+            break;
-+        }
-+        if ((a[o] < '0') || (a[o] > '9'))
-+            goto err;
-+        n = a[o] - '0';
-+        if (++o > l)
-+            goto err;
-+
-+        if ((a[o] < '0') || (a[o] > '9'))
-+            goto err;
-+        n = (n * 10) + a[o] - '0';
-+        if (++o > l)
-+            goto err;
-+
-+        if ((n < min[i]) || (n > max[i]))
-+            goto err;
-+        if (tm) {
-+            switch (i) {
-+            case 0:
-+                tm->tm_year = n * 100 - 1900;
-+                break;
-+            case 1:
-+                tm->tm_year += n;
-+                break;
-+            case 2:
-+                tm->tm_mon = n - 1;
-+                break;
-+            case 3:
-+                tm->tm_mday = n;
-+                break;
-+            case 4:
-+                tm->tm_hour = n;
-+                break;
-+            case 5:
-+                tm->tm_min = n;
-+                break;
-+            case 6:
-+                tm->tm_sec = n;
-+                break;
-+            }
-+        }
-+    }
-+    /*
-+     * Optional fractional seconds: decimal point followed by one or more
-+     * digits.
-+     */
-+    if (a[o] == '.') {
-+        if (++o > l)
-+            goto err;
-+        i = o;
-+        while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
-+            o++;
-+        /* Must have at least one digit after decimal point */
-+        if (i == o)
-+            goto err;
-+    }
-+
-+    if (a[o] == 'Z')
-+        o++;
-+    else if ((a[o] == '+') || (a[o] == '-')) {
-+        int offsign = a[o] == '-' ? -1 : 1, offset = 0;
-+        o++;
-+        if (o + 4 > l)
-+            goto err;
-+        for (i = 7; i < 9; i++) {
-+            if ((a[o] < '0') || (a[o] > '9'))
-+                goto err;
-+            n = a[o] - '0';
-+            o++;
-+            if ((a[o] < '0') || (a[o] > '9'))
-+                goto err;
-+            n = (n * 10) + a[o] - '0';
-+            if ((n < min[i]) || (n > max[i]))
-+                goto err;
-+            if (tm) {
-+                if (i == 7)
-+                    offset = n * 3600;
-+                else if (i == 8)
-+                    offset += n * 60;
-+            }
-+            o++;
-+        }
-+        if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
-+            return 0;
-+    } else if (a[o]) {
-+        /* Missing time zone information. */
-+        goto err;
-+    }
-+    return (o == l);
-+ err:
-+    return (0);
-+}
-+
-+int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
-+{
-+    return asn1_generalizedtime_to_tm(NULL, d);
-+}
-+
-+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
-+{
-+    ASN1_GENERALIZEDTIME t;
-+
-+    t.type = V_ASN1_GENERALIZEDTIME;
-+    t.length = strlen(str);
-+    t.data = (unsigned char *)str;
-+    if (ASN1_GENERALIZEDTIME_check(&t)) {
-+        if (s != NULL) {
-+            if (!ASN1_STRING_set((ASN1_STRING *)s, str, t.length))
-+                return 0;
-+            s->type = V_ASN1_GENERALIZEDTIME;
-+        }
-+        return (1);
-+    } else
-+        return (0);
-+}
-+
-+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
-+                                               time_t t)
-+{
-+    return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
-+}
-+
-+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
-+                                               time_t t, int offset_day,
-+                                               long offset_sec)
-+{
-+    char *p;
-+    struct tm *ts;
-+    struct tm data;
-+    size_t len = 20;
-+    ASN1_GENERALIZEDTIME *tmps = NULL;
-+
-+    if (s == NULL)
-+        tmps = ASN1_GENERALIZEDTIME_new();
-+    else
-+        tmps = s;
-+    if (tmps == NULL)
-+        return NULL;
-+
-+    ts = OPENSSL_gmtime(&t, &data);
-+    if (ts == NULL)
-+        goto err;
-+
-+    if (offset_day || offset_sec) {
-+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
-+            goto err;
-+    }
-+
-+    p = (char *)tmps->data;
-+    if ((p == NULL) || ((size_t)tmps->length < len)) {
-+        p = OPENSSL_malloc(len);
-+        if (p == NULL) {
-+            ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        OPENSSL_free(tmps->data);
-+        tmps->data = (unsigned char *)p;
-+    }
-+
-+    BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
-+                 ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
-+                 ts->tm_sec);
-+    tmps->length = strlen(p);
-+    tmps->type = V_ASN1_GENERALIZEDTIME;
-+#ifdef CHARSET_EBCDIC_not
-+    ebcdic2ascii(tmps->data, tmps->data, tmps->length);
-+#endif
-+    return tmps;
-+ err:
-+    if (s == NULL)
-+        ASN1_GENERALIZEDTIME_free(tmps);
-+    return NULL;
-+}
-+
-+const char *_asn1_mon[12] = {
-+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-+};
-+
-+int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
-+{
-+    char *v;
-+    int gmt = 0;
-+    int i;
-+    int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
-+    char *f = NULL;
-+    int f_len = 0;
-+
-+    i = tm->length;
-+    v = (char *)tm->data;
-+
-+    if (i < 12)
-+        goto err;
-+    if (v[i - 1] == 'Z')
-+        gmt = 1;
-+    for (i = 0; i < 12; i++)
-+        if ((v[i] > '9') || (v[i] < '0'))
-+            goto err;
-+    y = (v[0] - '0') * 1000 + (v[1] - '0') * 100
-+        + (v[2] - '0') * 10 + (v[3] - '0');
-+    M = (v[4] - '0') * 10 + (v[5] - '0');
-+    if ((M > 12) || (M < 1))
-+        goto err;
-+    d = (v[6] - '0') * 10 + (v[7] - '0');
-+    h = (v[8] - '0') * 10 + (v[9] - '0');
-+    m = (v[10] - '0') * 10 + (v[11] - '0');
-+    if (tm->length >= 14 &&
-+        (v[12] >= '0') && (v[12] <= '9') &&
-+        (v[13] >= '0') && (v[13] <= '9')) {
-+        s = (v[12] - '0') * 10 + (v[13] - '0');
-+        /* Check for fractions of seconds. */
-+        if (tm->length >= 15 && v[14] == '.') {
-+            int l = tm->length;
-+            f = &v[14];         /* The decimal point. */
-+            f_len = 1;
-+            while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
-+                ++f_len;
-+        }
-+    }
-+
-+    if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
-+                   _asn1_mon[M - 1], d, h, m, s, f_len, f, y,
-+                   (gmt) ? " GMT" : "") <= 0)
-+        return (0);
-+    else
-+        return (1);
-+ err:
-+    BIO_write(bp, "Bad time value", 14);
-+    return (0);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_i2d_fp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_i2d_fp.c
-new file mode 100644
-index 0000000..1514ede
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_i2d_fp.c
-@@ -0,0 +1,108 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+#ifndef NO_OLD_ASN1
-+
-+# ifndef OPENSSL_NO_STDIO
-+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        ASN1err(ASN1_F_ASN1_I2D_FP, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, out, BIO_NOCLOSE);
-+    ret = ASN1_i2d_bio(i2d, b, x);
-+    BIO_free(b);
-+    return (ret);
-+}
-+# endif
-+
-+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
-+{
-+    char *b;
-+    unsigned char *p;
-+    int i, j = 0, n, ret = 1;
-+
-+    n = i2d(x, NULL);
-+    b = OPENSSL_malloc(n);
-+    if (b == NULL) {
-+        ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE);
-+        return (0);
-+    }
-+
-+    p = (unsigned char *)b;
-+    i2d(x, &p);
-+
-+    for (;;) {
-+        i = BIO_write(out, &(b[j]), n);
-+        if (i == n)
-+            break;
-+        if (i <= 0) {
-+            ret = 0;
-+            break;
-+        }
-+        j += i;
-+        n -= i;
-+    }
-+    OPENSSL_free(b);
-+    return (ret);
-+}
-+
-+#endif
-+
-+#ifndef OPENSSL_NO_STDIO
-+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        ASN1err(ASN1_F_ASN1_ITEM_I2D_FP, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, out, BIO_NOCLOSE);
-+    ret = ASN1_item_i2d_bio(it, b, x);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-+
-+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
-+{
-+    unsigned char *b = NULL;
-+    int i, j = 0, n, ret = 1;
-+
-+    n = ASN1_item_i2d(x, &b, it);
-+    if (b == NULL) {
-+        ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO, ERR_R_MALLOC_FAILURE);
-+        return (0);
-+    }
-+
-+    for (;;) {
-+        i = BIO_write(out, &(b[j]), n);
-+        if (i == n)
-+            break;
-+        if (i <= 0) {
-+            ret = 0;
-+            break;
-+        }
-+        j += i;
-+        n -= i;
-+    }
-+    OPENSSL_free(b);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_int.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_int.c
-new file mode 100644
-index 0000000..e0bcd6e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_int.c
-@@ -0,0 +1,624 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "internal/numbers.h"
-+#include 
-+#include 
-+#include 
-+#include "asn1_locl.h"
-+
-+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
-+{
-+    return ASN1_STRING_dup(x);
-+}
-+
-+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
-+{
-+    int neg, ret;
-+    /* Compare signs */
-+    neg = x->type & V_ASN1_NEG;
-+    if (neg != (y->type & V_ASN1_NEG)) {
-+        if (neg)
-+            return -1;
-+        else
-+            return 1;
-+    }
-+
-+    ret = ASN1_STRING_cmp(x, y);
-+
-+    if (neg)
-+        return -ret;
-+    else
-+        return ret;
-+}
-+
-+/*-
-+ * This converts a big endian buffer and sign into its content encoding.
-+ * This is used for INTEGER and ENUMERATED types.
-+ * The internal representation is an ASN1_STRING whose data is a big endian
-+ * representation of the value, ignoring the sign. The sign is determined by
-+ * the type: if type & V_ASN1_NEG is true it is negative, otherwise positive.
-+ *
-+ * Positive integers are no problem: they are almost the same as the DER
-+ * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
-+ *
-+ * Negative integers are a bit trickier...
-+ * The DER representation of negative integers is in 2s complement form.
-+ * The internal form is converted by complementing each octet and finally
-+ * adding one to the result. This can be done less messily with a little trick.
-+ * If the internal form has trailing zeroes then they will become FF by the
-+ * complement and 0 by the add one (due to carry) so just copy as many trailing
-+ * zeros to the destination as there are in the source. The carry will add one
-+ * to the last none zero octet: so complement this octet and add one and finally
-+ * complement any left over until you get to the start of the string.
-+ *
-+ * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
-+ * with 0xff. However if the first byte is 0x80 and one of the following bytes
-+ * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
-+ * followed by optional zeros isn't padded.
-+ */
-+
-+static size_t i2c_ibuf(const unsigned char *b, size_t blen, int neg,
-+                       unsigned char **pp)
-+{
-+    int pad = 0;
-+    size_t ret, i;
-+    unsigned char *p, pb = 0;
-+    const unsigned char *n;
-+
-+    if (b == NULL || blen == 0)
-+        ret = 1;
-+    else {
-+        ret = blen;
-+        i = b[0];
-+        if (ret == 1 && i == 0)
-+            neg = 0;
-+        if (!neg && (i > 127)) {
-+            pad = 1;
-+            pb = 0;
-+        } else if (neg) {
-+            if (i > 128) {
-+                pad = 1;
-+                pb = 0xFF;
-+            } else if (i == 128) {
-+                /*
-+                 * Special case: if any other bytes non zero we pad:
-+                 * otherwise we don't.
-+                 */
-+                for (i = 1; i < blen; i++)
-+                    if (b[i]) {
-+                        pad = 1;
-+                        pb = 0xFF;
-+                        break;
-+                    }
-+            }
-+        }
-+        ret += pad;
-+    }
-+    if (pp == NULL)
-+        return ret;
-+    p = *pp;
-+
-+    if (pad)
-+        *(p++) = pb;
-+    if (b == NULL || blen == 0)
-+        *p = 0;
-+    else if (!neg)
-+        memcpy(p, b, blen);
-+    else {
-+        /* Begin at the end of the encoding */
-+        n = b + blen;
-+        p += blen;
-+        i = blen;
-+        /* Copy zeros to destination as long as source is zero */
-+        while (!n[-1] && i > 1) {
-+            *(--p) = 0;
-+            n--;
-+            i--;
-+        }
-+        /* Complement and increment next octet */
-+        *(--p) = ((*(--n)) ^ 0xff) + 1;
-+        i--;
-+        /* Complement any octets left */
-+        for (; i > 0; i--)
-+            *(--p) = *(--n) ^ 0xff;
-+    }
-+
-+    *pp += ret;
-+    return ret;
-+}
-+
-+/*
-+ * convert content octets into a big endian buffer. Returns the length
-+ * of buffer or 0 on error: for malformed INTEGER. If output buffer is
-+ * NULL just return length.
-+ */
-+
-+static size_t c2i_ibuf(unsigned char *b, int *pneg,
-+                       const unsigned char *p, size_t plen)
-+{
-+    size_t i;
-+    int neg, pad;
-+    /* Zero content length is illegal */
-+    if (plen == 0) {
-+        ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_ZERO_CONTENT);
-+        return 0;
-+    }
-+    neg = p[0] & 0x80;
-+    if (pneg)
-+        *pneg = neg;
-+    /* Handle common case where length is 1 octet separately */
-+    if (plen == 1) {
-+        if (b) {
-+            if (neg)
-+                b[0] = (p[0] ^ 0xFF) + 1;
-+            else
-+                b[0] = p[0];
-+        }
-+        return 1;
-+    }
-+    if (p[0] == 0 || p[0] == 0xFF)
-+        pad = 1;
-+    else
-+        pad = 0;
-+    /* reject illegal padding: first two octets MSB can't match */
-+    if (pad && (neg == (p[1] & 0x80))) {
-+        ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_PADDING);
-+        return 0;
-+    }
-+    /* If positive just copy across */
-+    if (neg == 0) {
-+        if (b)
-+            memcpy(b, p + pad, plen - pad);
-+        return plen - pad;
-+    }
-+
-+    if (neg && pad) {
-+        /* check is any following octets are non zero */
-+        for (i = 1; i < plen; i++) {
-+            if (p[i] != 0)
-+                break;
-+        }
-+        /* if all bytes are zero handle as special case */
-+        if (i == plen) {
-+            if (b) {
-+                b[0] = 1;
-+                memset(b + 1, 0, plen - 1);
-+            }
-+            return plen;
-+        }
-+    }
-+
-+    plen -= pad;
-+    /* Must be negative: calculate twos complement */
-+    if (b) {
-+        const unsigned char *from = p + plen - 1 + pad;
-+        unsigned char *to = b + plen;
-+        i = plen;
-+        while (*from == 0 && i) {
-+            *--to = 0;
-+            i--;
-+            from--;
-+        }
-+        *--to = (*from-- ^ 0xff) + 1;
-+        OPENSSL_assert(i != 0);
-+        i--;
-+        for (; i > 0; i--)
-+            *--to = *from-- ^ 0xff;
-+    }
-+    return plen;
-+}
-+
-+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
-+{
-+    return i2c_ibuf(a->data, a->length, a->type & V_ASN1_NEG, pp);
-+}
-+
-+/* Convert big endian buffer into uint64_t, return 0 on error */
-+static int asn1_get_uint64(uint64_t *pr, const unsigned char *b, size_t blen)
-+{
-+    size_t i;
-+    if (blen > sizeof(*pr)) {
-+        ASN1err(ASN1_F_ASN1_GET_UINT64, ASN1_R_TOO_LARGE);
-+        return 0;
-+    }
-+    *pr = 0;
-+    if (b == NULL)
-+        return 0;
-+    for (i = 0; i < blen; i++) {
-+        *pr <<= 8;
-+        *pr |= b[i];
-+    }
-+    return 1;
-+}
-+
-+static size_t asn1_put_uint64(unsigned char *b, uint64_t r)
-+{
-+    if (r >= 0x100) {
-+        unsigned char *p;
-+        uint64_t rtmp = r;
-+        size_t i = 0;
-+
-+        /* Work out how many bytes we need */
-+        while (rtmp) {
-+            rtmp >>= 8;
-+            i++;
-+        }
-+
-+        /* Copy from end to beginning */
-+        p = b + i - 1;
-+
-+        do {
-+            *p-- = r & 0xFF;
-+            r >>= 8;
-+        } while (p >= b);
-+
-+        return i;
-+    }
-+
-+    b[0] = (unsigned char)r;
-+    return 1;
-+
-+}
-+
-+/*
-+ * Absolute value of INT64_MIN: we can't just use -INT64_MIN as it produces
-+ * overflow warnings.
-+ */
-+
-+#define ABS_INT64_MIN \
-+    ((uint64_t)INT64_MAX + (uint64_t)(-(INT64_MIN + INT64_MAX)))
-+
-+/* signed version of asn1_get_uint64 */
-+static int asn1_get_int64(int64_t *pr, const unsigned char *b, size_t blen,
-+                          int neg)
-+{
-+    uint64_t r;
-+    if (asn1_get_uint64(&r, b, blen) == 0)
-+        return 0;
-+    if (neg) {
-+        if (r > ABS_INT64_MIN) {
-+            ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_SMALL);
-+            return 0;
-+        }
-+        *pr = 0 - (uint64_t)r;
-+    } else {
-+        if (r > INT64_MAX) {
-+            ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_LARGE);
-+            return 0;
-+        }
-+        *pr = (int64_t)r;
-+    }
-+    return 1;
-+}
-+
-+/* Convert ASN1 INTEGER content octets to ASN1_INTEGER structure */
-+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
-+                               long len)
-+{
-+    ASN1_INTEGER *ret = NULL;
-+    size_t r;
-+    int neg;
-+
-+    r = c2i_ibuf(NULL, NULL, *pp, len);
-+
-+    if (r == 0)
-+        return NULL;
-+
-+    if ((a == NULL) || ((*a) == NULL)) {
-+        ret = ASN1_INTEGER_new();
-+        if (ret == NULL)
-+            return NULL;
-+        ret->type = V_ASN1_INTEGER;
-+    } else
-+        ret = *a;
-+
-+    if (ASN1_STRING_set(ret, NULL, r) == 0)
-+        goto err;
-+
-+    c2i_ibuf(ret->data, &neg, *pp, len);
-+
-+    if (neg)
-+        ret->type |= V_ASN1_NEG;
-+
-+    *pp += len;
-+    if (a != NULL)
-+        (*a) = ret;
-+    return ret;
-+ err:
-+    ASN1err(ASN1_F_C2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
-+    if ((a == NULL) || (*a != ret))
-+        ASN1_INTEGER_free(ret);
-+    return NULL;
-+}
-+
-+static int asn1_string_get_int64(int64_t *pr, const ASN1_STRING *a, int itype)
-+{
-+    if (a == NULL) {
-+        ASN1err(ASN1_F_ASN1_STRING_GET_INT64, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    if ((a->type & ~V_ASN1_NEG) != itype) {
-+        ASN1err(ASN1_F_ASN1_STRING_GET_INT64, ASN1_R_WRONG_INTEGER_TYPE);
-+        return 0;
-+    }
-+    return asn1_get_int64(pr, a->data, a->length, a->type & V_ASN1_NEG);
-+}
-+
-+static int asn1_string_set_int64(ASN1_STRING *a, int64_t r, int itype)
-+{
-+    unsigned char tbuf[sizeof(r)];
-+    size_t l;
-+    a->type = itype;
-+    if (r < 0) {
-+        l = asn1_put_uint64(tbuf, -r);
-+        a->type |= V_ASN1_NEG;
-+    } else {
-+        l = asn1_put_uint64(tbuf, r);
-+        a->type &= ~V_ASN1_NEG;
-+    }
-+    if (l == 0)
-+        return 0;
-+    return ASN1_STRING_set(a, tbuf, l);
-+}
-+
-+static int asn1_string_get_uint64(uint64_t *pr, const ASN1_STRING *a,
-+                                  int itype)
-+{
-+    if (a == NULL) {
-+        ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    if ((a->type & ~V_ASN1_NEG) != itype) {
-+        ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ASN1_R_WRONG_INTEGER_TYPE);
-+        return 0;
-+    }
-+    if (a->type & V_ASN1_NEG) {
-+        ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
-+        return 0;
-+    }
-+    return asn1_get_uint64(pr, a->data, a->length);
-+}
-+
-+static int asn1_string_set_uint64(ASN1_STRING *a, uint64_t r, int itype)
-+{
-+    unsigned char tbuf[sizeof(r)];
-+    size_t l;
-+    a->type = itype;
-+    l = asn1_put_uint64(tbuf, r);
-+    if (l == 0)
-+        return 0;
-+    return ASN1_STRING_set(a, tbuf, l);
-+}
-+
-+/*
-+ * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
-+ * integers: some broken software can encode a positive INTEGER with its MSB
-+ * set as negative (it doesn't add a padding zero).
-+ */
-+
-+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
-+                                long length)
-+{
-+    ASN1_INTEGER *ret = NULL;
-+    const unsigned char *p;
-+    unsigned char *s;
-+    long len;
-+    int inf, tag, xclass;
-+    int i;
-+
-+    if ((a == NULL) || ((*a) == NULL)) {
-+        if ((ret = ASN1_INTEGER_new()) == NULL)
-+            return (NULL);
-+        ret->type = V_ASN1_INTEGER;
-+    } else
-+        ret = (*a);
-+
-+    p = *pp;
-+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
-+    if (inf & 0x80) {
-+        i = ASN1_R_BAD_OBJECT_HEADER;
-+        goto err;
-+    }
-+
-+    if (tag != V_ASN1_INTEGER) {
-+        i = ASN1_R_EXPECTING_AN_INTEGER;
-+        goto err;
-+    }
-+
-+    /*
-+     * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
-+     * a missing NULL parameter.
-+     */
-+    s = OPENSSL_malloc((int)len + 1);
-+    if (s == NULL) {
-+        i = ERR_R_MALLOC_FAILURE;
-+        goto err;
-+    }
-+    ret->type = V_ASN1_INTEGER;
-+    if (len) {
-+        if ((*p == 0) && (len != 1)) {
-+            p++;
-+            len--;
-+        }
-+        memcpy(s, p, (int)len);
-+        p += len;
-+    }
-+
-+    OPENSSL_free(ret->data);
-+    ret->data = s;
-+    ret->length = (int)len;
-+    if (a != NULL)
-+        (*a) = ret;
-+    *pp = p;
-+    return (ret);
-+ err:
-+    ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
-+    if ((a == NULL) || (*a != ret))
-+        ASN1_INTEGER_free(ret);
-+    return (NULL);
-+}
-+
-+static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
-+                                      int atype)
-+{
-+    ASN1_INTEGER *ret;
-+    int len;
-+
-+    if (ai == NULL) {
-+        ret = ASN1_STRING_type_new(atype);
-+    } else {
-+        ret = ai;
-+        ret->type = atype;
-+    }
-+
-+    if (ret == NULL) {
-+        ASN1err(ASN1_F_BN_TO_ASN1_STRING, ERR_R_NESTED_ASN1_ERROR);
-+        goto err;
-+    }
-+
-+    if (BN_is_negative(bn) && !BN_is_zero(bn))
-+        ret->type |= V_ASN1_NEG_INTEGER;
-+
-+    len = BN_num_bytes(bn);
-+
-+    if (len == 0)
-+        len = 1;
-+
-+    if (ASN1_STRING_set(ret, NULL, len) == 0) {
-+        ASN1err(ASN1_F_BN_TO_ASN1_STRING, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    /* Correct zero case */
-+    if (BN_is_zero(bn))
-+        ret->data[0] = 0;
-+    else
-+        len = BN_bn2bin(bn, ret->data);
-+    ret->length = len;
-+    return ret;
-+ err:
-+    if (ret != ai)
-+        ASN1_INTEGER_free(ret);
-+    return (NULL);
-+}
-+
-+static BIGNUM *asn1_string_to_bn(const ASN1_INTEGER *ai, BIGNUM *bn,
-+                                 int itype)
-+{
-+    BIGNUM *ret;
-+
-+    if ((ai->type & ~V_ASN1_NEG) != itype) {
-+        ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_WRONG_INTEGER_TYPE);
-+        return NULL;
-+    }
-+
-+    ret = BN_bin2bn(ai->data, ai->length, bn);
-+    if (ret == 0) {
-+        ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_BN_LIB);
-+        return NULL;
-+    }
-+    if (ai->type & V_ASN1_NEG)
-+        BN_set_negative(ret, 1);
-+    return ret;
-+}
-+
-+int ASN1_INTEGER_get_int64(int64_t *pr, const ASN1_INTEGER *a)
-+{
-+    return asn1_string_get_int64(pr, a, V_ASN1_INTEGER);
-+}
-+
-+int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t r)
-+{
-+    return asn1_string_set_int64(a, r, V_ASN1_INTEGER);
-+}
-+
-+int ASN1_INTEGER_get_uint64(uint64_t *pr, const ASN1_INTEGER *a)
-+{
-+    return asn1_string_get_uint64(pr, a, V_ASN1_INTEGER);
-+}
-+
-+int ASN1_INTEGER_set_uint64(ASN1_INTEGER *a, uint64_t r)
-+{
-+    return asn1_string_set_uint64(a, r, V_ASN1_INTEGER);
-+}
-+
-+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
-+{
-+    return ASN1_INTEGER_set_int64(a, v);
-+}
-+
-+long ASN1_INTEGER_get(const ASN1_INTEGER *a)
-+{
-+    int i;
-+    int64_t r;
-+    if (a == NULL)
-+        return 0;
-+    i = ASN1_INTEGER_get_int64(&r, a);
-+    if (i == 0)
-+        return -1;
-+    if (r > LONG_MAX || r < LONG_MIN)
-+        return -1;
-+    return (long)r;
-+}
-+
-+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
-+{
-+    return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER);
-+}
-+
-+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
-+{
-+    return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER);
-+}
-+
-+int ASN1_ENUMERATED_get_int64(int64_t *pr, const ASN1_ENUMERATED *a)
-+{
-+    return asn1_string_get_int64(pr, a, V_ASN1_ENUMERATED);
-+}
-+
-+int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t r)
-+{
-+    return asn1_string_set_int64(a, r, V_ASN1_ENUMERATED);
-+}
-+
-+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
-+{
-+    return ASN1_ENUMERATED_set_int64(a, v);
-+}
-+
-+long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a)
-+{
-+    int i;
-+    int64_t r;
-+    if (a == NULL)
-+        return 0;
-+    if ((a->type & ~V_ASN1_NEG) != V_ASN1_ENUMERATED)
-+        return -1;
-+    if (a->length > (int)sizeof(long))
-+        return 0xffffffffL;
-+    i = ASN1_ENUMERATED_get_int64(&r, a);
-+    if (i == 0)
-+        return -1;
-+    if (r > LONG_MAX || r < LONG_MIN)
-+        return -1;
-+    return (long)r;
-+}
-+
-+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai)
-+{
-+    return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED);
-+}
-+
-+BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn)
-+{
-+    return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_mbstr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_mbstr.c
-new file mode 100644
-index 0000000..5578e92
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_mbstr.c
-@@ -0,0 +1,395 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+static int traverse_string(const unsigned char *p, int len, int inform,
-+                           int (*rfunc) (unsigned long value, void *in),
-+                           void *arg);
-+static int in_utf8(unsigned long value, void *arg);
-+static int out_utf8(unsigned long value, void *arg);
-+static int type_str(unsigned long value, void *arg);
-+static int cpy_asc(unsigned long value, void *arg);
-+static int cpy_bmp(unsigned long value, void *arg);
-+static int cpy_univ(unsigned long value, void *arg);
-+static int cpy_utf8(unsigned long value, void *arg);
-+static int is_numeric(unsigned long value);
-+static int is_printable(unsigned long value);
-+
-+/*
-+ * These functions take a string in UTF8, ASCII or multibyte form and a mask
-+ * of permissible ASN1 string types. It then works out the minimal type
-+ * (using the order Numeric < Printable < IA5 < T61 < BMP < Universal < UTF8)
-+ * and creates a string of the correct type with the supplied data. Yes this is
-+ * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum
-+ * size limits too.
-+ */
-+
-+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
-+                       int inform, unsigned long mask)
-+{
-+    return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
-+}
-+
-+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
-+                        int inform, unsigned long mask,
-+                        long minsize, long maxsize)
-+{
-+    int str_type;
-+    int ret;
-+    char free_out;
-+    int outform, outlen = 0;
-+    ASN1_STRING *dest;
-+    unsigned char *p;
-+    int nchar;
-+    char strbuf[32];
-+    int (*cpyfunc) (unsigned long, void *) = NULL;
-+    if (len == -1)
-+        len = strlen((const char *)in);
-+    if (!mask)
-+        mask = DIRSTRING_TYPE;
-+
-+    /* First do a string check and work out the number of characters */
-+    switch (inform) {
-+
-+    case MBSTRING_BMP:
-+        if (len & 1) {
-+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
-+                    ASN1_R_INVALID_BMPSTRING_LENGTH);
-+            return -1;
-+        }
-+        nchar = len >> 1;
-+        break;
-+
-+    case MBSTRING_UNIV:
-+        if (len & 3) {
-+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
-+                    ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
-+            return -1;
-+        }
-+        nchar = len >> 2;
-+        break;
-+
-+    case MBSTRING_UTF8:
-+        nchar = 0;
-+        /* This counts the characters and does utf8 syntax checking */
-+        ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
-+        if (ret < 0) {
-+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING);
-+            return -1;
-+        }
-+        break;
-+
-+    case MBSTRING_ASC:
-+        nchar = len;
-+        break;
-+
-+    default:
-+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
-+        return -1;
-+    }
-+
-+    if ((minsize > 0) && (nchar < minsize)) {
-+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
-+        BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
-+        ERR_add_error_data(2, "minsize=", strbuf);
-+        return -1;
-+    }
-+
-+    if ((maxsize > 0) && (nchar > maxsize)) {
-+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
-+        BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
-+        ERR_add_error_data(2, "maxsize=", strbuf);
-+        return -1;
-+    }
-+
-+    /* Now work out minimal type (if any) */
-+    if (traverse_string(in, len, inform, type_str, &mask) < 0) {
-+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
-+        return -1;
-+    }
-+
-+    /* Now work out output format and string type */
-+    outform = MBSTRING_ASC;
-+    if (mask & B_ASN1_NUMERICSTRING)
-+        str_type = V_ASN1_NUMERICSTRING;
-+    else if (mask & B_ASN1_PRINTABLESTRING)
-+        str_type = V_ASN1_PRINTABLESTRING;
-+    else if (mask & B_ASN1_IA5STRING)
-+        str_type = V_ASN1_IA5STRING;
-+    else if (mask & B_ASN1_T61STRING)
-+        str_type = V_ASN1_T61STRING;
-+    else if (mask & B_ASN1_BMPSTRING) {
-+        str_type = V_ASN1_BMPSTRING;
-+        outform = MBSTRING_BMP;
-+    } else if (mask & B_ASN1_UNIVERSALSTRING) {
-+        str_type = V_ASN1_UNIVERSALSTRING;
-+        outform = MBSTRING_UNIV;
-+    } else {
-+        str_type = V_ASN1_UTF8STRING;
-+        outform = MBSTRING_UTF8;
-+    }
-+    if (!out)
-+        return str_type;
-+    if (*out) {
-+        free_out = 0;
-+        dest = *out;
-+        OPENSSL_free(dest->data);
-+        dest->data = NULL;
-+        dest->length = 0;
-+        dest->type = str_type;
-+    } else {
-+        free_out = 1;
-+        dest = ASN1_STRING_type_new(str_type);
-+        if (dest == NULL) {
-+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
-+            return -1;
-+        }
-+        *out = dest;
-+    }
-+    /* If both the same type just copy across */
-+    if (inform == outform) {
-+        if (!ASN1_STRING_set(dest, in, len)) {
-+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
-+            return -1;
-+        }
-+        return str_type;
-+    }
-+
-+    /* Work out how much space the destination will need */
-+    switch (outform) {
-+    case MBSTRING_ASC:
-+        outlen = nchar;
-+        cpyfunc = cpy_asc;
-+        break;
-+
-+    case MBSTRING_BMP:
-+        outlen = nchar << 1;
-+        cpyfunc = cpy_bmp;
-+        break;
-+
-+    case MBSTRING_UNIV:
-+        outlen = nchar << 2;
-+        cpyfunc = cpy_univ;
-+        break;
-+
-+    case MBSTRING_UTF8:
-+        outlen = 0;
-+        traverse_string(in, len, inform, out_utf8, &outlen);
-+        cpyfunc = cpy_utf8;
-+        break;
-+    }
-+    if ((p = OPENSSL_malloc(outlen + 1)) == NULL) {
-+        if (free_out)
-+            ASN1_STRING_free(dest);
-+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
-+        return -1;
-+    }
-+    dest->length = outlen;
-+    dest->data = p;
-+    p[outlen] = 0;
-+    traverse_string(in, len, inform, cpyfunc, &p);
-+    return str_type;
-+}
-+
-+/*
-+ * This function traverses a string and passes the value of each character to
-+ * an optional function along with a void * argument.
-+ */
-+
-+static int traverse_string(const unsigned char *p, int len, int inform,
-+                           int (*rfunc) (unsigned long value, void *in),
-+                           void *arg)
-+{
-+    unsigned long value;
-+    int ret;
-+    while (len) {
-+        if (inform == MBSTRING_ASC) {
-+            value = *p++;
-+            len--;
-+        } else if (inform == MBSTRING_BMP) {
-+            value = *p++ << 8;
-+            value |= *p++;
-+            len -= 2;
-+        } else if (inform == MBSTRING_UNIV) {
-+            value = ((unsigned long)*p++) << 24;
-+            value |= ((unsigned long)*p++) << 16;
-+            value |= *p++ << 8;
-+            value |= *p++;
-+            len -= 4;
-+        } else {
-+            ret = UTF8_getc(p, len, &value);
-+            if (ret < 0)
-+                return -1;
-+            len -= ret;
-+            p += ret;
-+        }
-+        if (rfunc) {
-+            ret = rfunc(value, arg);
-+            if (ret <= 0)
-+                return ret;
-+        }
-+    }
-+    return 1;
-+}
-+
-+/* Various utility functions for traverse_string */
-+
-+/* Just count number of characters */
-+
-+static int in_utf8(unsigned long value, void *arg)
-+{
-+    int *nchar;
-+    nchar = arg;
-+    (*nchar)++;
-+    return 1;
-+}
-+
-+/* Determine size of output as a UTF8 String */
-+
-+static int out_utf8(unsigned long value, void *arg)
-+{
-+    int *outlen;
-+    outlen = arg;
-+    *outlen += UTF8_putc(NULL, -1, value);
-+    return 1;
-+}
-+
-+/*
-+ * Determine the "type" of a string: check each character against a supplied
-+ * "mask".
-+ */
-+
-+static int type_str(unsigned long value, void *arg)
-+{
-+    unsigned long types;
-+    types = *((unsigned long *)arg);
-+    if ((types & B_ASN1_NUMERICSTRING) && !is_numeric(value))
-+        types &= ~B_ASN1_NUMERICSTRING;
-+    if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
-+        types &= ~B_ASN1_PRINTABLESTRING;
-+    if ((types & B_ASN1_IA5STRING) && (value > 127))
-+        types &= ~B_ASN1_IA5STRING;
-+    if ((types & B_ASN1_T61STRING) && (value > 0xff))
-+        types &= ~B_ASN1_T61STRING;
-+    if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
-+        types &= ~B_ASN1_BMPSTRING;
-+    if (!types)
-+        return -1;
-+    *((unsigned long *)arg) = types;
-+    return 1;
-+}
-+
-+/* Copy one byte per character ASCII like strings */
-+
-+static int cpy_asc(unsigned long value, void *arg)
-+{
-+    unsigned char **p, *q;
-+    p = arg;
-+    q = *p;
-+    *q = (unsigned char)value;
-+    (*p)++;
-+    return 1;
-+}
-+
-+/* Copy two byte per character BMPStrings */
-+
-+static int cpy_bmp(unsigned long value, void *arg)
-+{
-+    unsigned char **p, *q;
-+    p = arg;
-+    q = *p;
-+    *q++ = (unsigned char)((value >> 8) & 0xff);
-+    *q = (unsigned char)(value & 0xff);
-+    *p += 2;
-+    return 1;
-+}
-+
-+/* Copy four byte per character UniversalStrings */
-+
-+static int cpy_univ(unsigned long value, void *arg)
-+{
-+    unsigned char **p, *q;
-+    p = arg;
-+    q = *p;
-+    *q++ = (unsigned char)((value >> 24) & 0xff);
-+    *q++ = (unsigned char)((value >> 16) & 0xff);
-+    *q++ = (unsigned char)((value >> 8) & 0xff);
-+    *q = (unsigned char)(value & 0xff);
-+    *p += 4;
-+    return 1;
-+}
-+
-+/* Copy to a UTF8String */
-+
-+static int cpy_utf8(unsigned long value, void *arg)
-+{
-+    unsigned char **p;
-+    int ret;
-+    p = arg;
-+    /* We already know there is enough room so pass 0xff as the length */
-+    ret = UTF8_putc(*p, 0xff, value);
-+    *p += ret;
-+    return 1;
-+}
-+
-+/* Return 1 if the character is permitted in a PrintableString */
-+static int is_printable(unsigned long value)
-+{
-+    int ch;
-+    if (value > 0x7f)
-+        return 0;
-+    ch = (int)value;
-+    /*
-+     * Note: we can't use 'isalnum' because certain accented characters may
-+     * count as alphanumeric in some environments.
-+     */
-+#ifndef CHARSET_EBCDIC
-+    if ((ch >= 'a') && (ch <= 'z'))
-+        return 1;
-+    if ((ch >= 'A') && (ch <= 'Z'))
-+        return 1;
-+    if ((ch >= '0') && (ch <= '9'))
-+        return 1;
-+    if ((ch == ' ') || strchr("'()+,-./:=?", ch))
-+        return 1;
-+#else                           /* CHARSET_EBCDIC */
-+    if ((ch >= os_toascii['a']) && (ch <= os_toascii['z']))
-+        return 1;
-+    if ((ch >= os_toascii['A']) && (ch <= os_toascii['Z']))
-+        return 1;
-+    if ((ch >= os_toascii['0']) && (ch <= os_toascii['9']))
-+        return 1;
-+    if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch]))
-+        return 1;
-+#endif                          /* CHARSET_EBCDIC */
-+    return 0;
-+}
-+
-+/* Return 1 if the character is a digit or space */
-+static int is_numeric(unsigned long value)
-+{
-+    int ch;
-+    if (value > 0x7f)
-+        return 0;
-+    ch = (int)value;
-+#ifndef CHARSET_EBCDIC
-+    if (!isdigit(ch) && ch != ' ')
-+        return 0;
-+#else
-+    if (ch > os_toascii['9'])
-+        return 0;
-+    if (ch < os_toascii['0'] && ch != os_toascii[' '])
-+        return 0;
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_object.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_object.c
-new file mode 100644
-index 0000000..79f0ecd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_object.c
-@@ -0,0 +1,370 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "asn1_locl.h"
-+
-+int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
-+{
-+    unsigned char *p;
-+    int objsize;
-+
-+    if ((a == NULL) || (a->data == NULL))
-+        return (0);
-+
-+    objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
-+    if (pp == NULL || objsize == -1)
-+        return objsize;
-+
-+    p = *pp;
-+    ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
-+    memcpy(p, a->data, a->length);
-+    p += a->length;
-+
-+    *pp = p;
-+    return (objsize);
-+}
-+
-+int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
-+{
-+    int i, first, len = 0, c, use_bn;
-+    char ftmp[24], *tmp = ftmp;
-+    int tmpsize = sizeof ftmp;
-+    const char *p;
-+    unsigned long l;
-+    BIGNUM *bl = NULL;
-+
-+    if (num == 0)
-+        return (0);
-+    else if (num == -1)
-+        num = strlen(buf);
-+
-+    p = buf;
-+    c = *(p++);
-+    num--;
-+    if ((c >= '0') && (c <= '2')) {
-+        first = c - '0';
-+    } else {
-+        ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
-+        goto err;
-+    }
-+
-+    if (num <= 0) {
-+        ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
-+        goto err;
-+    }
-+    c = *(p++);
-+    num--;
-+    for (;;) {
-+        if (num <= 0)
-+            break;
-+        if ((c != '.') && (c != ' ')) {
-+            ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
-+            goto err;
-+        }
-+        l = 0;
-+        use_bn = 0;
-+        for (;;) {
-+            if (num <= 0)
-+                break;
-+            num--;
-+            c = *(p++);
-+            if ((c == ' ') || (c == '.'))
-+                break;
-+            if ((c < '0') || (c > '9')) {
-+                ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
-+                goto err;
-+            }
-+            if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
-+                use_bn = 1;
-+                if (bl == NULL)
-+                    bl = BN_new();
-+                if (bl == NULL || !BN_set_word(bl, l))
-+                    goto err;
-+            }
-+            if (use_bn) {
-+                if (!BN_mul_word(bl, 10L)
-+                    || !BN_add_word(bl, c - '0'))
-+                    goto err;
-+            } else
-+                l = l * 10L + (long)(c - '0');
-+        }
-+        if (len == 0) {
-+            if ((first < 2) && (l >= 40)) {
-+                ASN1err(ASN1_F_A2D_ASN1_OBJECT,
-+                        ASN1_R_SECOND_NUMBER_TOO_LARGE);
-+                goto err;
-+            }
-+            if (use_bn) {
-+                if (!BN_add_word(bl, first * 40))
-+                    goto err;
-+            } else
-+                l += (long)first *40;
-+        }
-+        i = 0;
-+        if (use_bn) {
-+            int blsize;
-+            blsize = BN_num_bits(bl);
-+            blsize = (blsize + 6) / 7;
-+            if (blsize > tmpsize) {
-+                if (tmp != ftmp)
-+                    OPENSSL_free(tmp);
-+                tmpsize = blsize + 32;
-+                tmp = OPENSSL_malloc(tmpsize);
-+                if (tmp == NULL)
-+                    goto err;
-+            }
-+            while (blsize--) {
-+                BN_ULONG t = BN_div_word(bl, 0x80L);
-+                if (t == (BN_ULONG)-1)
-+                    goto err;
-+                tmp[i++] = (unsigned char)t;
-+            }
-+        } else {
-+
-+            for (;;) {
-+                tmp[i++] = (unsigned char)l & 0x7f;
-+                l >>= 7L;
-+                if (l == 0L)
-+                    break;
-+            }
-+
-+        }
-+        if (out != NULL) {
-+            if (len + i > olen) {
-+                ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
-+                goto err;
-+            }
-+            while (--i > 0)
-+                out[len++] = tmp[i] | 0x80;
-+            out[len++] = tmp[0];
-+        } else
-+            len += i;
-+    }
-+    if (tmp != ftmp)
-+        OPENSSL_free(tmp);
-+    BN_free(bl);
-+    return (len);
-+ err:
-+    if (tmp != ftmp)
-+        OPENSSL_free(tmp);
-+    BN_free(bl);
-+    return (0);
-+}
-+
-+int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a)
-+{
-+    return OBJ_obj2txt(buf, buf_len, a, 0);
-+}
-+
-+int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a)
-+{
-+    char buf[80], *p = buf;
-+    int i;
-+
-+    if ((a == NULL) || (a->data == NULL))
-+        return (BIO_write(bp, "NULL", 4));
-+    i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
-+    if (i > (int)(sizeof(buf) - 1)) {
-+        p = OPENSSL_malloc(i + 1);
-+        if (p == NULL)
-+            return -1;
-+        i2t_ASN1_OBJECT(p, i + 1, a);
-+    }
-+    if (i <= 0) {
-+        i = BIO_write(bp, "", 9);
-+        i += BIO_dump(bp, (const char *)a->data, a->length);
-+        return i;
-+    }
-+    BIO_write(bp, p, i);
-+    if (p != buf)
-+        OPENSSL_free(p);
-+    return (i);
-+}
-+
-+ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
-+                             long length)
-+{
-+    const unsigned char *p;
-+    long len;
-+    int tag, xclass;
-+    int inf, i;
-+    ASN1_OBJECT *ret = NULL;
-+    p = *pp;
-+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
-+    if (inf & 0x80) {
-+        i = ASN1_R_BAD_OBJECT_HEADER;
-+        goto err;
-+    }
-+
-+    if (tag != V_ASN1_OBJECT) {
-+        i = ASN1_R_EXPECTING_AN_OBJECT;
-+        goto err;
-+    }
-+    ret = c2i_ASN1_OBJECT(a, &p, len);
-+    if (ret)
-+        *pp = p;
-+    return ret;
-+ err:
-+    ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
-+    return (NULL);
-+}
-+
-+ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
-+                             long len)
-+{
-+    ASN1_OBJECT *ret = NULL, tobj;
-+    const unsigned char *p;
-+    unsigned char *data;
-+    int i, length;
-+
-+    /*
-+     * Sanity check OID encoding. Need at least one content octet. MSB must
-+     * be clear in the last octet. can't have leading 0x80 in subidentifiers,
-+     * see: X.690 8.19.2
-+     */
-+    if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
-+        p[len - 1] & 0x80) {
-+        ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
-+        return NULL;
-+    }
-+    /* Now 0 < len <= INT_MAX, so the cast is safe. */
-+    length = (int)len;
-+    /*
-+     * Try to lookup OID in table: these are all valid encodings so if we get
-+     * a match we know the OID is valid.
-+     */
-+    tobj.nid = NID_undef;
-+    tobj.data = p;
-+    tobj.length = length;
-+    tobj.flags = 0;
-+    i = OBJ_obj2nid(&tobj);
-+    if (i != NID_undef) {
-+        /*
-+         * Return shared registered OID object: this improves efficiency
-+         * because we don't have to return a dynamically allocated OID
-+         * and NID lookups can use the cached value.
-+         */
-+        ret = OBJ_nid2obj(i);
-+        if (a) {
-+            ASN1_OBJECT_free(*a);
-+            *a = ret;
-+        }
-+        *pp += len;
-+        return ret;
-+    }
-+    for (i = 0; i < length; i++, p++) {
-+        if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
-+            ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
-+            return NULL;
-+        }
-+    }
-+
-+    /*
-+     * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
-+     * ->ln
-+     */
-+    if ((a == NULL) || ((*a) == NULL) ||
-+        !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
-+        if ((ret = ASN1_OBJECT_new()) == NULL)
-+            return (NULL);
-+    } else
-+        ret = (*a);
-+
-+    p = *pp;
-+    /* detach data from object */
-+    data = (unsigned char *)ret->data;
-+    ret->data = NULL;
-+    /* once detached we can change it */
-+    if ((data == NULL) || (ret->length < length)) {
-+        ret->length = 0;
-+        OPENSSL_free(data);
-+        data = OPENSSL_malloc(length);
-+        if (data == NULL) {
-+            i = ERR_R_MALLOC_FAILURE;
-+            goto err;
-+        }
-+        ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
-+    }
-+    memcpy(data, p, length);
-+    /* reattach data to object, after which it remains const */
-+    ret->data = data;
-+    ret->length = length;
-+    ret->sn = NULL;
-+    ret->ln = NULL;
-+    /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
-+    p += length;
-+
-+    if (a != NULL)
-+        (*a) = ret;
-+    *pp = p;
-+    return (ret);
-+ err:
-+    ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
-+    if ((a == NULL) || (*a != ret))
-+        ASN1_OBJECT_free(ret);
-+    return (NULL);
-+}
-+
-+ASN1_OBJECT *ASN1_OBJECT_new(void)
-+{
-+    ASN1_OBJECT *ret;
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL) {
-+        ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+    ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
-+    return (ret);
-+}
-+
-+void ASN1_OBJECT_free(ASN1_OBJECT *a)
-+{
-+    if (a == NULL)
-+        return;
-+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
-+#ifndef CONST_STRICT            /* disable purely for compile-time strict
-+                                 * const checking. Doing this on a "real"
-+                                 * compile will cause memory leaks */
-+        OPENSSL_free((void*)a->sn);
-+        OPENSSL_free((void*)a->ln);
-+#endif
-+        a->sn = a->ln = NULL;
-+    }
-+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
-+        OPENSSL_free((void*)a->data);
-+        a->data = NULL;
-+        a->length = 0;
-+    }
-+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
-+        OPENSSL_free(a);
-+}
-+
-+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
-+                                const char *sn, const char *ln)
-+{
-+    ASN1_OBJECT o;
-+
-+    o.sn = sn;
-+    o.ln = ln;
-+    o.data = data;
-+    o.nid = nid;
-+    o.length = len;
-+    o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
-+        ASN1_OBJECT_FLAG_DYNAMIC_DATA;
-+    return (OBJ_dup(&o));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_octet.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_octet.c
-new file mode 100644
-index 0000000..2e1205c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_octet.c
-@@ -0,0 +1,29 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
-+{
-+    return ASN1_STRING_dup(x);
-+}
-+
-+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
-+                          const ASN1_OCTET_STRING *b)
-+{
-+    return ASN1_STRING_cmp(a, b);
-+}
-+
-+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
-+                          int len)
-+{
-+    return ASN1_STRING_set(x, d, len);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_print.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_print.c
-new file mode 100644
-index 0000000..1aafe7c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_print.c
-@@ -0,0 +1,109 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+int ASN1_PRINTABLE_type(const unsigned char *s, int len)
-+{
-+    int c;
-+    int ia5 = 0;
-+    int t61 = 0;
-+
-+    if (len <= 0)
-+        len = -1;
-+    if (s == NULL)
-+        return (V_ASN1_PRINTABLESTRING);
-+
-+    while ((*s) && (len-- != 0)) {
-+        c = *(s++);
-+#ifndef CHARSET_EBCDIC
-+        if (!(((c >= 'a') && (c <= 'z')) ||
-+              ((c >= 'A') && (c <= 'Z')) ||
-+              ((c >= '0') && (c <= '9')) ||
-+              (c == ' ') || (c == '\'') ||
-+              (c == '(') || (c == ')') ||
-+              (c == '+') || (c == ',') ||
-+              (c == '-') || (c == '.') ||
-+              (c == '/') || (c == ':') || (c == '=') || (c == '?')))
-+            ia5 = 1;
-+        if (c & 0x80)
-+            t61 = 1;
-+#else
-+        if (!isalnum(c) && (c != ' ') && strchr("'()+,-./:=?", c) == NULL)
-+            ia5 = 1;
-+        if (os_toascii[c] & 0x80)
-+            t61 = 1;
-+#endif
-+    }
-+    if (t61)
-+        return (V_ASN1_T61STRING);
-+    if (ia5)
-+        return (V_ASN1_IA5STRING);
-+    return (V_ASN1_PRINTABLESTRING);
-+}
-+
-+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
-+{
-+    int i;
-+    unsigned char *p;
-+
-+    if (s->type != V_ASN1_UNIVERSALSTRING)
-+        return (0);
-+    if ((s->length % 4) != 0)
-+        return (0);
-+    p = s->data;
-+    for (i = 0; i < s->length; i += 4) {
-+        if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
-+            break;
-+        else
-+            p += 4;
-+    }
-+    if (i < s->length)
-+        return (0);
-+    p = s->data;
-+    for (i = 3; i < s->length; i += 4) {
-+        *(p++) = s->data[i];
-+    }
-+    *(p) = '\0';
-+    s->length /= 4;
-+    s->type = ASN1_PRINTABLE_type(s->data, s->length);
-+    return (1);
-+}
-+
-+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
-+{
-+    int i, n;
-+    char buf[80];
-+    const char *p;
-+
-+    if (v == NULL)
-+        return (0);
-+    n = 0;
-+    p = (const char *)v->data;
-+    for (i = 0; i < v->length; i++) {
-+        if ((p[i] > '~') || ((p[i] < ' ') &&
-+                             (p[i] != '\n') && (p[i] != '\r')))
-+            buf[n] = '.';
-+        else
-+            buf[n] = p[i];
-+        n++;
-+        if (n >= 80) {
-+            if (BIO_write(bp, buf, n) <= 0)
-+                return (0);
-+            n = 0;
-+        }
-+    }
-+    if (n > 0)
-+        if (BIO_write(bp, buf, n) <= 0)
-+            return (0);
-+    return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_sign.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_sign.c
-new file mode 100644
-index 0000000..7e21a5e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_sign.c
-@@ -0,0 +1,228 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+#include "internal/cryptlib.h"
-+
-+#ifndef NO_SYS_TYPES_H
-+# include 
-+#endif
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+#ifndef NO_ASN1_OLD
-+
-+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
-+              ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
-+              const EVP_MD *type)
-+{
-+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
-+    unsigned char *p, *buf_in = NULL, *buf_out = NULL;
-+    int i, inl = 0, outl = 0, outll = 0;
-+    X509_ALGOR *a;
-+
-+    if (ctx == NULL) {
-+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    for (i = 0; i < 2; i++) {
-+        if (i == 0)
-+            a = algor1;
-+        else
-+            a = algor2;
-+        if (a == NULL)
-+            continue;
-+        if (type->pkey_type == NID_dsaWithSHA1) {
-+            /*
-+             * special case: RFC 2459 tells us to omit 'parameters' with
-+             * id-dsa-with-sha1
-+             */
-+            ASN1_TYPE_free(a->parameter);
-+            a->parameter = NULL;
-+        } else if ((a->parameter == NULL) ||
-+                   (a->parameter->type != V_ASN1_NULL)) {
-+            ASN1_TYPE_free(a->parameter);
-+            if ((a->parameter = ASN1_TYPE_new()) == NULL)
-+                goto err;
-+            a->parameter->type = V_ASN1_NULL;
-+        }
-+        ASN1_OBJECT_free(a->algorithm);
-+        a->algorithm = OBJ_nid2obj(type->pkey_type);
-+        if (a->algorithm == NULL) {
-+            ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE);
-+            goto err;
-+        }
-+        if (a->algorithm->length == 0) {
-+            ASN1err(ASN1_F_ASN1_SIGN,
-+                    ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
-+            goto err;
-+        }
-+    }
-+    inl = i2d(data, NULL);
-+    buf_in = OPENSSL_malloc((unsigned int)inl);
-+    outll = outl = EVP_PKEY_size(pkey);
-+    buf_out = OPENSSL_malloc((unsigned int)outl);
-+    if ((buf_in == NULL) || (buf_out == NULL)) {
-+        outl = 0;
-+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    p = buf_in;
-+
-+    i2d(data, &p);
-+    if (!EVP_SignInit_ex(ctx, type, NULL)
-+        || !EVP_SignUpdate(ctx, (unsigned char *)buf_in, inl)
-+        || !EVP_SignFinal(ctx, (unsigned char *)buf_out,
-+                          (unsigned int *)&outl, pkey)) {
-+        outl = 0;
-+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB);
-+        goto err;
-+    }
-+    OPENSSL_free(signature->data);
-+    signature->data = buf_out;
-+    buf_out = NULL;
-+    signature->length = outl;
-+    /*
-+     * In the interests of compatibility, I'll make sure that the bit string
-+     * has a 'not-used bits' value of 0
-+     */
-+    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-+    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-+ err:
-+    EVP_MD_CTX_free(ctx);
-+    OPENSSL_clear_free((char *)buf_in, (unsigned int)inl);
-+    OPENSSL_clear_free((char *)buf_out, outll);
-+    return (outl);
-+}
-+
-+#endif
-+
-+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
-+                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
-+                   EVP_PKEY *pkey, const EVP_MD *type)
-+{
-+    int rv;
-+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
-+
-+    if (ctx == NULL) {
-+        ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    if (!EVP_DigestSignInit(ctx, NULL, type, NULL, pkey)) {
-+        EVP_MD_CTX_free(ctx);
-+        return 0;
-+    }
-+
-+    rv = ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, ctx);
-+
-+    EVP_MD_CTX_free(ctx);
-+    return rv;
-+}
-+
-+int ASN1_item_sign_ctx(const ASN1_ITEM *it,
-+                       X509_ALGOR *algor1, X509_ALGOR *algor2,
-+                       ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
-+{
-+    const EVP_MD *type;
-+    EVP_PKEY *pkey;
-+    unsigned char *buf_in = NULL, *buf_out = NULL;
-+    size_t inl = 0, outl = 0, outll = 0;
-+    int signid, paramtype;
-+    int rv;
-+
-+    type = EVP_MD_CTX_md(ctx);
-+    pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
-+
-+    if (type == NULL || pkey == NULL) {
-+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
-+        goto err;
-+    }
-+
-+    if (pkey->ameth == NULL) {
-+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
-+        goto err;
-+    }
-+
-+    if (pkey->ameth->item_sign) {
-+        rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature);
-+        if (rv == 1)
-+            outl = signature->length;
-+        /*-
-+         * Return value meanings:
-+         * <=0: error.
-+         *   1: method does everything.
-+         *   2: carry on as normal.
-+         *   3: ASN1 method sets algorithm identifiers: just sign.
-+         */
-+        if (rv <= 0)
-+            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
-+        if (rv <= 1)
-+            goto err;
-+    } else
-+        rv = 2;
-+
-+    if (rv == 2) {
-+        if (!OBJ_find_sigid_by_algs(&signid,
-+                                    EVP_MD_nid(type),
-+                                    pkey->ameth->pkey_id)) {
-+            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
-+                    ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
-+            goto err;
-+        }
-+
-+        if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
-+            paramtype = V_ASN1_NULL;
-+        else
-+            paramtype = V_ASN1_UNDEF;
-+
-+        if (algor1)
-+            X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
-+        if (algor2)
-+            X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
-+
-+    }
-+
-+    inl = ASN1_item_i2d(asn, &buf_in, it);
-+    outll = outl = EVP_PKEY_size(pkey);
-+    buf_out = OPENSSL_malloc((unsigned int)outl);
-+    if ((buf_in == NULL) || (buf_out == NULL)) {
-+        outl = 0;
-+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
-+        || !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
-+        outl = 0;
-+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
-+        goto err;
-+    }
-+    OPENSSL_free(signature->data);
-+    signature->data = buf_out;
-+    buf_out = NULL;
-+    signature->length = outl;
-+    /*
-+     * In the interests of compatibility, I'll make sure that the bit string
-+     * has a 'not-used bits' value of 0
-+     */
-+    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-+    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-+ err:
-+    OPENSSL_clear_free((char *)buf_in, (unsigned int)inl);
-+    OPENSSL_clear_free((char *)buf_out, outll);
-+    return (outl);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_strex.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_strex.c
-new file mode 100644
-index 0000000..9839f5c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_strex.c
-@@ -0,0 +1,645 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include "internal/asn1_int.h"
-+#include 
-+#include 
-+#include 
-+
-+#include "charmap.h"
-+
-+/*
-+ * ASN1_STRING_print_ex() and X509_NAME_print_ex(). Enhanced string and name
-+ * printing routines handling multibyte characters, RFC2253 and a host of
-+ * other options.
-+ */
-+
-+#define CHARTYPE_BS_ESC         (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
-+
-+#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
-+                  ASN1_STRFLGS_ESC_2254 | \
-+                  ASN1_STRFLGS_ESC_QUOTE | \
-+                  ASN1_STRFLGS_ESC_CTRL | \
-+                  ASN1_STRFLGS_ESC_MSB)
-+
-+/*
-+ * Three IO functions for sending data to memory, a BIO and and a FILE
-+ * pointer.
-+ */
-+static int send_bio_chars(void *arg, const void *buf, int len)
-+{
-+    if (!arg)
-+        return 1;
-+    if (BIO_write(arg, buf, len) != len)
-+        return 0;
-+    return 1;
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+static int send_fp_chars(void *arg, const void *buf, int len)
-+{
-+    if (!arg)
-+        return 1;
-+    if (fwrite(buf, 1, len, arg) != (unsigned int)len)
-+        return 0;
-+    return 1;
-+}
-+#endif
-+
-+typedef int char_io (void *arg, const void *buf, int len);
-+
-+/*
-+ * This function handles display of strings, one character at a time. It is
-+ * passed an unsigned long for each character because it could come from 2 or
-+ * even 4 byte forms.
-+ */
-+
-+static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes,
-+                       char_io *io_ch, void *arg)
-+{
-+    unsigned short chflgs;
-+    unsigned char chtmp;
-+    char tmphex[HEX_SIZE(long) + 3];
-+
-+    if (c > 0xffffffffL)
-+        return -1;
-+    if (c > 0xffff) {
-+        BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
-+        if (!io_ch(arg, tmphex, 10))
-+            return -1;
-+        return 10;
-+    }
-+    if (c > 0xff) {
-+        BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
-+        if (!io_ch(arg, tmphex, 6))
-+            return -1;
-+        return 6;
-+    }
-+    chtmp = (unsigned char)c;
-+    if (chtmp > 0x7f)
-+        chflgs = flags & ASN1_STRFLGS_ESC_MSB;
-+    else
-+        chflgs = char_type[chtmp] & flags;
-+    if (chflgs & CHARTYPE_BS_ESC) {
-+        /* If we don't escape with quotes, signal we need quotes */
-+        if (chflgs & ASN1_STRFLGS_ESC_QUOTE) {
-+            if (do_quotes)
-+                *do_quotes = 1;
-+            if (!io_ch(arg, &chtmp, 1))
-+                return -1;
-+            return 1;
-+        }
-+        if (!io_ch(arg, "\\", 1))
-+            return -1;
-+        if (!io_ch(arg, &chtmp, 1))
-+            return -1;
-+        return 2;
-+    }
-+    if (chflgs & (ASN1_STRFLGS_ESC_CTRL
-+                  | ASN1_STRFLGS_ESC_MSB
-+                  | ASN1_STRFLGS_ESC_2254)) {
-+        BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
-+        if (!io_ch(arg, tmphex, 3))
-+            return -1;
-+        return 3;
-+    }
-+    /*
-+     * If we get this far and do any escaping at all must escape the escape
-+     * character itself: backslash.
-+     */
-+    if (chtmp == '\\' && flags & ESC_FLAGS) {
-+        if (!io_ch(arg, "\\\\", 2))
-+            return -1;
-+        return 2;
-+    }
-+    if (!io_ch(arg, &chtmp, 1))
-+        return -1;
-+    return 1;
-+}
-+
-+#define BUF_TYPE_WIDTH_MASK     0x7
-+#define BUF_TYPE_CONVUTF8       0x8
-+
-+/*
-+ * This function sends each character in a buffer to do_esc_char(). It
-+ * interprets the content formats and converts to or from UTF8 as
-+ * appropriate.
-+ */
-+
-+static int do_buf(unsigned char *buf, int buflen,
-+                  int type, unsigned short flags, char *quotes, char_io *io_ch,
-+                  void *arg)
-+{
-+    int i, outlen, len;
-+    unsigned short orflags;
-+    unsigned char *p, *q;
-+    unsigned long c;
-+    p = buf;
-+    q = buf + buflen;
-+    outlen = 0;
-+    while (p != q) {
-+        if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
-+            orflags = CHARTYPE_FIRST_ESC_2253;
-+        else
-+            orflags = 0;
-+        switch (type & BUF_TYPE_WIDTH_MASK) {
-+        case 4:
-+            c = ((unsigned long)*p++) << 24;
-+            c |= ((unsigned long)*p++) << 16;
-+            c |= ((unsigned long)*p++) << 8;
-+            c |= *p++;
-+            break;
-+
-+        case 2:
-+            c = ((unsigned long)*p++) << 8;
-+            c |= *p++;
-+            break;
-+
-+        case 1:
-+            c = *p++;
-+            break;
-+
-+        case 0:
-+            i = UTF8_getc(p, buflen, &c);
-+            if (i < 0)
-+                return -1;      /* Invalid UTF8String */
-+            p += i;
-+            break;
-+        default:
-+            return -1;          /* invalid width */
-+        }
-+        if (p == q && flags & ASN1_STRFLGS_ESC_2253)
-+            orflags = CHARTYPE_LAST_ESC_2253;
-+        if (type & BUF_TYPE_CONVUTF8) {
-+            unsigned char utfbuf[6];
-+            int utflen;
-+            utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
-+            for (i = 0; i < utflen; i++) {
-+                /*
-+                 * We don't need to worry about setting orflags correctly
-+                 * because if utflen==1 its value will be correct anyway
-+                 * otherwise each character will be > 0x7f and so the
-+                 * character will never be escaped on first and last.
-+                 */
-+                len =
-+                    do_esc_char(utfbuf[i], (unsigned short)(flags | orflags),
-+                                quotes, io_ch, arg);
-+                if (len < 0)
-+                    return -1;
-+                outlen += len;
-+            }
-+        } else {
-+            len =
-+                do_esc_char(c, (unsigned short)(flags | orflags), quotes,
-+                            io_ch, arg);
-+            if (len < 0)
-+                return -1;
-+            outlen += len;
-+        }
-+    }
-+    return outlen;
-+}
-+
-+/* This function hex dumps a buffer of characters */
-+
-+static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
-+                       int buflen)
-+{
-+    static const char hexdig[] = "0123456789ABCDEF";
-+    unsigned char *p, *q;
-+    char hextmp[2];
-+    if (arg) {
-+        p = buf;
-+        q = buf + buflen;
-+        while (p != q) {
-+            hextmp[0] = hexdig[*p >> 4];
-+            hextmp[1] = hexdig[*p & 0xf];
-+            if (!io_ch(arg, hextmp, 2))
-+                return -1;
-+            p++;
-+        }
-+    }
-+    return buflen << 1;
-+}
-+
-+/*
-+ * "dump" a string. This is done when the type is unknown, or the flags
-+ * request it. We can either dump the content octets or the entire DER
-+ * encoding. This uses the RFC2253 #01234 format.
-+ */
-+
-+static int do_dump(unsigned long lflags, char_io *io_ch, void *arg,
-+                   const ASN1_STRING *str)
-+{
-+    /*
-+     * Placing the ASN1_STRING in a temp ASN1_TYPE allows the DER encoding to
-+     * readily obtained
-+     */
-+    ASN1_TYPE t;
-+    unsigned char *der_buf, *p;
-+    int outlen, der_len;
-+
-+    if (!io_ch(arg, "#", 1))
-+        return -1;
-+    /* If we don't dump DER encoding just dump content octets */
-+    if (!(lflags & ASN1_STRFLGS_DUMP_DER)) {
-+        outlen = do_hex_dump(io_ch, arg, str->data, str->length);
-+        if (outlen < 0)
-+            return -1;
-+        return outlen + 1;
-+    }
-+    t.type = str->type;
-+    t.value.ptr = (char *)str;
-+    der_len = i2d_ASN1_TYPE(&t, NULL);
-+    der_buf = OPENSSL_malloc(der_len);
-+    if (der_buf == NULL)
-+        return -1;
-+    p = der_buf;
-+    i2d_ASN1_TYPE(&t, &p);
-+    outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
-+    OPENSSL_free(der_buf);
-+    if (outlen < 0)
-+        return -1;
-+    return outlen + 1;
-+}
-+
-+/*
-+ * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is
-+ * used for non string types otherwise it is the number of bytes per
-+ * character
-+ */
-+
-+static const signed char tag2nbyte[] = {
-+    -1, -1, -1, -1, -1,         /* 0-4 */
-+    -1, -1, -1, -1, -1,         /* 5-9 */
-+    -1, -1, 0, -1,              /* 10-13 */
-+    -1, -1, -1, -1,             /* 15-17 */
-+    1, 1, 1,                    /* 18-20 */
-+    -1, 1, 1, 1,                /* 21-24 */
-+    -1, 1, -1,                  /* 25-27 */
-+    4, -1, 2                    /* 28-30 */
-+};
-+
-+/*
-+ * This is the main function, print out an ASN1_STRING taking note of various
-+ * escape and display options. Returns number of characters written or -1 if
-+ * an error occurred.
-+ */
-+
-+static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
-+                       const ASN1_STRING *str)
-+{
-+    int outlen, len;
-+    int type;
-+    char quotes;
-+    unsigned short flags;
-+    quotes = 0;
-+    /* Keep a copy of escape flags */
-+    flags = (unsigned short)(lflags & ESC_FLAGS);
-+
-+    type = str->type;
-+
-+    outlen = 0;
-+
-+    if (lflags & ASN1_STRFLGS_SHOW_TYPE) {
-+        const char *tagname;
-+        tagname = ASN1_tag2str(type);
-+        outlen += strlen(tagname);
-+        if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1))
-+            return -1;
-+        outlen++;
-+    }
-+
-+    /* Decide what to do with type, either dump content or display it */
-+
-+    /* Dump everything */
-+    if (lflags & ASN1_STRFLGS_DUMP_ALL)
-+        type = -1;
-+    /* Ignore the string type */
-+    else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
-+        type = 1;
-+    else {
-+        /* Else determine width based on type */
-+        if ((type > 0) && (type < 31))
-+            type = tag2nbyte[type];
-+        else
-+            type = -1;
-+        if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
-+            type = 1;
-+    }
-+
-+    if (type == -1) {
-+        len = do_dump(lflags, io_ch, arg, str);
-+        if (len < 0)
-+            return -1;
-+        outlen += len;
-+        return outlen;
-+    }
-+
-+    if (lflags & ASN1_STRFLGS_UTF8_CONVERT) {
-+        /*
-+         * Note: if string is UTF8 and we want to convert to UTF8 then we
-+         * just interpret it as 1 byte per character to avoid converting
-+         * twice.
-+         */
-+        if (!type)
-+            type = 1;
-+        else
-+            type |= BUF_TYPE_CONVUTF8;
-+    }
-+
-+    len = do_buf(str->data, str->length, type, flags, "es, io_ch, NULL);
-+    if (len < 0)
-+        return -1;
-+    outlen += len;
-+    if (quotes)
-+        outlen += 2;
-+    if (!arg)
-+        return outlen;
-+    if (quotes && !io_ch(arg, "\"", 1))
-+        return -1;
-+    if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
-+        return -1;
-+    if (quotes && !io_ch(arg, "\"", 1))
-+        return -1;
-+    return outlen;
-+}
-+
-+/* Used for line indenting: print 'indent' spaces */
-+
-+static int do_indent(char_io *io_ch, void *arg, int indent)
-+{
-+    int i;
-+    for (i = 0; i < indent; i++)
-+        if (!io_ch(arg, " ", 1))
-+            return 0;
-+    return 1;
-+}
-+
-+#define FN_WIDTH_LN     25
-+#define FN_WIDTH_SN     10
-+
-+static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n,
-+                      int indent, unsigned long flags)
-+{
-+    int i, prev = -1, orflags, cnt;
-+    int fn_opt, fn_nid;
-+    ASN1_OBJECT *fn;
-+    const ASN1_STRING *val;
-+    const X509_NAME_ENTRY *ent;
-+    char objtmp[80];
-+    const char *objbuf;
-+    int outlen, len;
-+    char *sep_dn, *sep_mv, *sep_eq;
-+    int sep_dn_len, sep_mv_len, sep_eq_len;
-+    if (indent < 0)
-+        indent = 0;
-+    outlen = indent;
-+    if (!do_indent(io_ch, arg, indent))
-+        return -1;
-+    switch (flags & XN_FLAG_SEP_MASK) {
-+    case XN_FLAG_SEP_MULTILINE:
-+        sep_dn = "\n";
-+        sep_dn_len = 1;
-+        sep_mv = " + ";
-+        sep_mv_len = 3;
-+        break;
-+
-+    case XN_FLAG_SEP_COMMA_PLUS:
-+        sep_dn = ",";
-+        sep_dn_len = 1;
-+        sep_mv = "+";
-+        sep_mv_len = 1;
-+        indent = 0;
-+        break;
-+
-+    case XN_FLAG_SEP_CPLUS_SPC:
-+        sep_dn = ", ";
-+        sep_dn_len = 2;
-+        sep_mv = " + ";
-+        sep_mv_len = 3;
-+        indent = 0;
-+        break;
-+
-+    case XN_FLAG_SEP_SPLUS_SPC:
-+        sep_dn = "; ";
-+        sep_dn_len = 2;
-+        sep_mv = " + ";
-+        sep_mv_len = 3;
-+        indent = 0;
-+        break;
-+
-+    default:
-+        return -1;
-+    }
-+
-+    if (flags & XN_FLAG_SPC_EQ) {
-+        sep_eq = " = ";
-+        sep_eq_len = 3;
-+    } else {
-+        sep_eq = "=";
-+        sep_eq_len = 1;
-+    }
-+
-+    fn_opt = flags & XN_FLAG_FN_MASK;
-+
-+    cnt = X509_NAME_entry_count(n);
-+    for (i = 0; i < cnt; i++) {
-+        if (flags & XN_FLAG_DN_REV)
-+            ent = X509_NAME_get_entry(n, cnt - i - 1);
-+        else
-+            ent = X509_NAME_get_entry(n, i);
-+        if (prev != -1) {
-+            if (prev == X509_NAME_ENTRY_set(ent)) {
-+                if (!io_ch(arg, sep_mv, sep_mv_len))
-+                    return -1;
-+                outlen += sep_mv_len;
-+            } else {
-+                if (!io_ch(arg, sep_dn, sep_dn_len))
-+                    return -1;
-+                outlen += sep_dn_len;
-+                if (!do_indent(io_ch, arg, indent))
-+                    return -1;
-+                outlen += indent;
-+            }
-+        }
-+        prev = X509_NAME_ENTRY_set(ent);
-+        fn = X509_NAME_ENTRY_get_object(ent);
-+        val = X509_NAME_ENTRY_get_data(ent);
-+        fn_nid = OBJ_obj2nid(fn);
-+        if (fn_opt != XN_FLAG_FN_NONE) {
-+            int objlen, fld_len;
-+            if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) {
-+                OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
-+                fld_len = 0;    /* XXX: what should this be? */
-+                objbuf = objtmp;
-+            } else {
-+                if (fn_opt == XN_FLAG_FN_SN) {
-+                    fld_len = FN_WIDTH_SN;
-+                    objbuf = OBJ_nid2sn(fn_nid);
-+                } else if (fn_opt == XN_FLAG_FN_LN) {
-+                    fld_len = FN_WIDTH_LN;
-+                    objbuf = OBJ_nid2ln(fn_nid);
-+                } else {
-+                    fld_len = 0; /* XXX: what should this be? */
-+                    objbuf = "";
-+                }
-+            }
-+            objlen = strlen(objbuf);
-+            if (!io_ch(arg, objbuf, objlen))
-+                return -1;
-+            if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
-+                if (!do_indent(io_ch, arg, fld_len - objlen))
-+                    return -1;
-+                outlen += fld_len - objlen;
-+            }
-+            if (!io_ch(arg, sep_eq, sep_eq_len))
-+                return -1;
-+            outlen += objlen + sep_eq_len;
-+        }
-+        /*
-+         * If the field name is unknown then fix up the DER dump flag. We
-+         * might want to limit this further so it will DER dump on anything
-+         * other than a few 'standard' fields.
-+         */
-+        if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
-+            orflags = ASN1_STRFLGS_DUMP_ALL;
-+        else
-+            orflags = 0;
-+
-+        len = do_print_ex(io_ch, arg, flags | orflags, val);
-+        if (len < 0)
-+            return -1;
-+        outlen += len;
-+    }
-+    return outlen;
-+}
-+
-+/* Wrappers round the main functions */
-+
-+int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent,
-+                       unsigned long flags)
-+{
-+    if (flags == XN_FLAG_COMPAT)
-+        return X509_NAME_print(out, nm, indent);
-+    return do_name_ex(send_bio_chars, out, nm, indent, flags);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent,
-+                          unsigned long flags)
-+{
-+    if (flags == XN_FLAG_COMPAT) {
-+        BIO *btmp;
-+        int ret;
-+        btmp = BIO_new_fp(fp, BIO_NOCLOSE);
-+        if (!btmp)
-+            return -1;
-+        ret = X509_NAME_print(btmp, nm, indent);
-+        BIO_free(btmp);
-+        return ret;
-+    }
-+    return do_name_ex(send_fp_chars, fp, nm, indent, flags);
-+}
-+#endif
-+
-+int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags)
-+{
-+    return do_print_ex(send_bio_chars, out, flags, str);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags)
-+{
-+    return do_print_ex(send_fp_chars, fp, flags, str);
-+}
-+#endif
-+
-+/*
-+ * Utility function: convert any string type to UTF8, returns number of bytes
-+ * in output string or a negative error code
-+ */
-+
-+int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in)
-+{
-+    ASN1_STRING stmp, *str = &stmp;
-+    int mbflag, type, ret;
-+    if (!in)
-+        return -1;
-+    type = in->type;
-+    if ((type < 0) || (type > 30))
-+        return -1;
-+    mbflag = tag2nbyte[type];
-+    if (mbflag == -1)
-+        return -1;
-+    mbflag |= MBSTRING_FLAG;
-+    stmp.data = NULL;
-+    stmp.length = 0;
-+    stmp.flags = 0;
-+    ret =
-+        ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
-+                           B_ASN1_UTF8STRING);
-+    if (ret < 0)
-+        return ret;
-+    *out = stmp.data;
-+    return stmp.length;
-+}
-+
-+/* Return 1 if host is a valid hostname and 0 otherwise */
-+int asn1_valid_host(const ASN1_STRING *host)
-+{
-+    int hostlen = host->length;
-+    const unsigned char *hostptr = host->data;
-+    int type = host->type;
-+    int i;
-+    char width = -1;
-+    unsigned short chflags = 0, prevchflags;
-+
-+    if (type > 0 && type < 31)
-+        width = tag2nbyte[type];
-+    if (width == -1 || hostlen == 0)
-+        return 0;
-+    /* Treat UTF8String as width 1 as any MSB set is invalid */
-+    if (width == 0)
-+        width = 1;
-+    for (i = 0 ; i < hostlen; i+= width) {
-+        prevchflags = chflags;
-+        /* Value must be <= 0x7F: check upper bytes are all zeroes */
-+        if (width == 4) {
-+            if (*hostptr++ != 0 || *hostptr++ != 0 || *hostptr++ != 0)
-+                return 0;
-+        } else if (width == 2) {
-+            if (*hostptr++ != 0)
-+                return 0;
-+        }
-+        if (*hostptr > 0x7f)
-+            return 0;
-+        chflags = char_type[*hostptr++];
-+        if (!(chflags & (CHARTYPE_HOST_ANY | CHARTYPE_HOST_WILD))) {
-+            /* Nothing else allowed at start or end of string */
-+            if (i == 0 || i == hostlen - 1)
-+                return 0;
-+            /* Otherwise invalid if not dot or hyphen */
-+            if (!(chflags & (CHARTYPE_HOST_DOT | CHARTYPE_HOST_HYPHEN)))
-+                return 0;
-+            /*
-+             * If previous is dot or hyphen then illegal unless both
-+             * are hyphens: as .- -. .. are all illegal
-+             */
-+            if (prevchflags & (CHARTYPE_HOST_DOT | CHARTYPE_HOST_HYPHEN)
-+                && ((prevchflags & CHARTYPE_HOST_DOT)
-+                    || (chflags & CHARTYPE_HOST_DOT)))
-+                return 0;
-+        }
-+    }
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_strnid.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_strnid.c
-new file mode 100644
-index 0000000..53832c8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_strnid.c
-@@ -0,0 +1,287 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
-+static void st_free(ASN1_STRING_TABLE *tbl);
-+static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
-+                        const ASN1_STRING_TABLE *const *b);
-+
-+/*
-+ * This is the global mask for the mbstring functions: this is use to mask
-+ * out certain types (such as BMPString and UTF8String) because certain
-+ * software (e.g. Netscape) has problems with them.
-+ */
-+
-+static unsigned long global_mask = B_ASN1_UTF8STRING;
-+
-+void ASN1_STRING_set_default_mask(unsigned long mask)
-+{
-+    global_mask = mask;
-+}
-+
-+unsigned long ASN1_STRING_get_default_mask(void)
-+{
-+    return global_mask;
-+}
-+
-+/*-
-+ * This function sets the default to various "flavours" of configuration.
-+ * based on an ASCII string. Currently this is:
-+ * MASK:XXXX : a numerical mask value.
-+ * nobmp : Don't use BMPStrings (just Printable, T61).
-+ * pkix : PKIX recommendation in RFC2459.
-+ * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
-+ * default:   the default value, Printable, T61, BMP.
-+ */
-+
-+int ASN1_STRING_set_default_mask_asc(const char *p)
-+{
-+    unsigned long mask;
-+    char *end;
-+    if (strncmp(p, "MASK:", 5) == 0) {
-+        if (!p[5])
-+            return 0;
-+        mask = strtoul(p + 5, &end, 0);
-+        if (*end)
-+            return 0;
-+    } else if (strcmp(p, "nombstr") == 0)
-+        mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING));
-+    else if (strcmp(p, "pkix") == 0)
-+        mask = ~((unsigned long)B_ASN1_T61STRING);
-+    else if (strcmp(p, "utf8only") == 0)
-+        mask = B_ASN1_UTF8STRING;
-+    else if (strcmp(p, "default") == 0)
-+        mask = 0xFFFFFFFFL;
-+    else
-+        return 0;
-+    ASN1_STRING_set_default_mask(mask);
-+    return 1;
-+}
-+
-+/*
-+ * The following function generates an ASN1_STRING based on limits in a
-+ * table. Frequently the types and length of an ASN1_STRING are restricted by
-+ * a corresponding OID. For example certificates and certificate requests.
-+ */
-+
-+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
-+                                    const unsigned char *in, int inlen,
-+                                    int inform, int nid)
-+{
-+    ASN1_STRING_TABLE *tbl;
-+    ASN1_STRING *str = NULL;
-+    unsigned long mask;
-+    int ret;
-+    if (!out)
-+        out = &str;
-+    tbl = ASN1_STRING_TABLE_get(nid);
-+    if (tbl) {
-+        mask = tbl->mask;
-+        if (!(tbl->flags & STABLE_NO_MASK))
-+            mask &= global_mask;
-+        ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
-+                                  tbl->minsize, tbl->maxsize);
-+    } else
-+        ret =
-+            ASN1_mbstring_copy(out, in, inlen, inform,
-+                               DIRSTRING_TYPE & global_mask);
-+    if (ret <= 0)
-+        return NULL;
-+    return *out;
-+}
-+
-+/*
-+ * Now the tables and helper functions for the string table:
-+ */
-+
-+/* size limits: this stuff is taken straight from RFC3280 */
-+
-+#define ub_name                         32768
-+#define ub_common_name                  64
-+#define ub_locality_name                128
-+#define ub_state_name                   128
-+#define ub_organization_name            64
-+#define ub_organization_unit_name       64
-+#define ub_title                        64
-+#define ub_email_address                128
-+#define ub_serial_number                64
-+
-+/* From RFC4524 */
-+
-+#define ub_rfc822_mailbox               256
-+
-+/* This table must be kept in NID order */
-+
-+static const ASN1_STRING_TABLE tbl_standard[] = {
-+    {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
-+    {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-+    {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
-+    {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
-+    {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
-+    {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
-+     0},
-+    {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
-+     STABLE_NO_MASK},
-+    {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
-+    {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
-+    {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
-+    {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
-+    {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
-+    {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
-+    {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
-+     STABLE_NO_MASK},
-+    {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
-+    {NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
-+    {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
-+    {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
-+    {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
-+    {NID_rfc822Mailbox, 1, ub_rfc822_mailbox, B_ASN1_IA5STRING,
-+     STABLE_NO_MASK},
-+    {NID_INN, 1, 12, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
-+    {NID_OGRN, 1, 13, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
-+    {NID_SNILS, 1, 11, B_ASN1_NUMERICSTRING, STABLE_NO_MASK}
-+};
-+
-+static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
-+                        const ASN1_STRING_TABLE *const *b)
-+{
-+    return (*a)->nid - (*b)->nid;
-+}
-+
-+DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
-+
-+static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
-+{
-+    return a->nid - b->nid;
-+}
-+
-+IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
-+
-+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
-+{
-+    int idx;
-+    ASN1_STRING_TABLE fnd;
-+    fnd.nid = nid;
-+    if (stable) {
-+        idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
-+        if (idx >= 0)
-+            return sk_ASN1_STRING_TABLE_value(stable, idx);
-+    }
-+    return OBJ_bsearch_table(&fnd, tbl_standard, OSSL_NELEM(tbl_standard));
-+}
-+
-+/*
-+ * Return a string table pointer which can be modified: either directly from
-+ * table or a copy of an internal value added to the table.
-+ */
-+
-+static ASN1_STRING_TABLE *stable_get(int nid)
-+{
-+    ASN1_STRING_TABLE *tmp, *rv;
-+    /* Always need a string table so allocate one if NULL */
-+    if (stable == NULL) {
-+        stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
-+        if (stable == NULL)
-+            return NULL;
-+    }
-+    tmp = ASN1_STRING_TABLE_get(nid);
-+    if (tmp && tmp->flags & STABLE_FLAGS_MALLOC)
-+        return tmp;
-+    rv = OPENSSL_zalloc(sizeof(*rv));
-+    if (rv == NULL)
-+        return NULL;
-+    if (!sk_ASN1_STRING_TABLE_push(stable, rv)) {
-+        OPENSSL_free(rv);
-+        return NULL;
-+    }
-+    if (tmp) {
-+        rv->nid = tmp->nid;
-+        rv->minsize = tmp->minsize;
-+        rv->maxsize = tmp->maxsize;
-+        rv->mask = tmp->mask;
-+        rv->flags = tmp->flags | STABLE_FLAGS_MALLOC;
-+    } else {
-+        rv->minsize = -1;
-+        rv->maxsize = -1;
-+        rv->flags = STABLE_FLAGS_MALLOC;
-+    }
-+    return rv;
-+}
-+
-+int ASN1_STRING_TABLE_add(int nid,
-+                          long minsize, long maxsize, unsigned long mask,
-+                          unsigned long flags)
-+{
-+    ASN1_STRING_TABLE *tmp;
-+    tmp = stable_get(nid);
-+    if (!tmp) {
-+        ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    if (minsize >= 0)
-+        tmp->minsize = minsize;
-+    if (maxsize >= 0)
-+        tmp->maxsize = maxsize;
-+    if (mask)
-+        tmp->mask = mask;
-+    if (flags)
-+        tmp->flags = STABLE_FLAGS_MALLOC | flags;
-+    return 1;
-+}
-+
-+void ASN1_STRING_TABLE_cleanup(void)
-+{
-+    STACK_OF(ASN1_STRING_TABLE) *tmp;
-+    tmp = stable;
-+    if (!tmp)
-+        return;
-+    stable = NULL;
-+    sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
-+}
-+
-+static void st_free(ASN1_STRING_TABLE *tbl)
-+{
-+    if (tbl->flags & STABLE_FLAGS_MALLOC)
-+        OPENSSL_free(tbl);
-+}
-+
-+
-+#ifdef STRING_TABLE_TEST
-+
-+main()
-+{
-+    ASN1_STRING_TABLE *tmp;
-+    int i, last_nid = -1;
-+
-+    for (tmp = tbl_standard, i = 0; i < OSSL_NELEM(tbl_standard); i++, tmp++) {
-+        if (tmp->nid < last_nid) {
-+            last_nid = 0;
-+            break;
-+        }
-+        last_nid = tmp->nid;
-+    }
-+
-+    if (last_nid != 0) {
-+        printf("Table order OK\n");
-+        exit(0);
-+    }
-+
-+    for (tmp = tbl_standard, i = 0; i < OSSL_NELEM(tbl_standard); i++, tmp++)
-+        printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
-+               OBJ_nid2ln(tmp->nid));
-+
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_time.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_time.c
-new file mode 100644
-index 0000000..3f82c2b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_time.c
-@@ -0,0 +1,163 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*-
-+ * This is an implementation of the ASN1 Time structure which is:
-+ *    Time ::= CHOICE {
-+ *      utcTime        UTCTime,
-+ *      generalTime    GeneralizedTime }
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "asn1_locl.h"
-+
-+IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
-+
-+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
-+{
-+    return ASN1_TIME_adj(s, t, 0, 0);
-+}
-+
-+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
-+                         int offset_day, long offset_sec)
-+{
-+    struct tm *ts;
-+    struct tm data;
-+
-+    ts = OPENSSL_gmtime(&t, &data);
-+    if (ts == NULL) {
-+        ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
-+        return NULL;
-+    }
-+    if (offset_day || offset_sec) {
-+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
-+            return NULL;
-+    }
-+    if ((ts->tm_year >= 50) && (ts->tm_year < 150))
-+        return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
-+    return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
-+}
-+
-+int ASN1_TIME_check(const ASN1_TIME *t)
-+{
-+    if (t->type == V_ASN1_GENERALIZEDTIME)
-+        return ASN1_GENERALIZEDTIME_check(t);
-+    else if (t->type == V_ASN1_UTCTIME)
-+        return ASN1_UTCTIME_check(t);
-+    return 0;
-+}
-+
-+/* Convert an ASN1_TIME structure to GeneralizedTime */
-+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
-+                                                   ASN1_GENERALIZEDTIME **out)
-+{
-+    ASN1_GENERALIZEDTIME *ret;
-+    char *str;
-+    int newlen;
-+
-+    if (!ASN1_TIME_check(t))
-+        return NULL;
-+
-+    if (out == NULL || *out == NULL) {
-+        if ((ret = ASN1_GENERALIZEDTIME_new()) == NULL)
-+            return NULL;
-+        if (out)
-+            *out = ret;
-+    } else
-+        ret = *out;
-+
-+    /* If already GeneralizedTime just copy across */
-+    if (t->type == V_ASN1_GENERALIZEDTIME) {
-+        if (!ASN1_STRING_set(ret, t->data, t->length))
-+            return NULL;
-+        return ret;
-+    }
-+
-+    /* grow the string */
-+    if (!ASN1_STRING_set(ret, NULL, t->length + 2))
-+        return NULL;
-+    /* ASN1_STRING_set() allocated 'len + 1' bytes. */
-+    newlen = t->length + 2 + 1;
-+    str = (char *)ret->data;
-+    /* Work out the century and prepend */
-+    if (t->data[0] >= '5')
-+        OPENSSL_strlcpy(str, "19", newlen);
-+    else
-+        OPENSSL_strlcpy(str, "20", newlen);
-+
-+    OPENSSL_strlcat(str, (char *)t->data, newlen);
-+
-+    return ret;
-+}
-+
-+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
-+{
-+    ASN1_TIME t;
-+
-+    t.length = strlen(str);
-+    t.data = (unsigned char *)str;
-+    t.flags = 0;
-+
-+    t.type = V_ASN1_UTCTIME;
-+
-+    if (!ASN1_TIME_check(&t)) {
-+        t.type = V_ASN1_GENERALIZEDTIME;
-+        if (!ASN1_TIME_check(&t))
-+            return 0;
-+    }
-+
-+    if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
-+        return 0;
-+
-+    return 1;
-+}
-+
-+static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t)
-+{
-+    if (t == NULL) {
-+        time_t now_t;
-+        time(&now_t);
-+        if (OPENSSL_gmtime(&now_t, tm))
-+            return 1;
-+        return 0;
-+    }
-+
-+    if (t->type == V_ASN1_UTCTIME)
-+        return asn1_utctime_to_tm(tm, t);
-+    else if (t->type == V_ASN1_GENERALIZEDTIME)
-+        return asn1_generalizedtime_to_tm(tm, t);
-+
-+    return 0;
-+}
-+
-+int ASN1_TIME_diff(int *pday, int *psec,
-+                   const ASN1_TIME *from, const ASN1_TIME *to)
-+{
-+    struct tm tm_from, tm_to;
-+    if (!asn1_time_to_tm(&tm_from, from))
-+        return 0;
-+    if (!asn1_time_to_tm(&tm_to, to))
-+        return 0;
-+    return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
-+}
-+
-+int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
-+{
-+    if (tm->type == V_ASN1_UTCTIME)
-+        return ASN1_UTCTIME_print(bp, tm);
-+    if (tm->type == V_ASN1_GENERALIZEDTIME)
-+        return ASN1_GENERALIZEDTIME_print(bp, tm);
-+    BIO_write(bp, "Bad time value", 14);
-+    return (0);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_type.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_type.c
-new file mode 100644
-index 0000000..df42360
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_type.c
-@@ -0,0 +1,134 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "asn1_locl.h"
-+
-+int ASN1_TYPE_get(const ASN1_TYPE *a)
-+{
-+    if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
-+        return (a->type);
-+    else
-+        return (0);
-+}
-+
-+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
-+{
-+    if (a->value.ptr != NULL) {
-+        ASN1_TYPE **tmp_a = &a;
-+        asn1_primitive_free((ASN1_VALUE **)tmp_a, NULL, 0);
-+    }
-+    a->type = type;
-+    if (type == V_ASN1_BOOLEAN)
-+        a->value.boolean = value ? 0xff : 0;
-+    else
-+        a->value.ptr = value;
-+}
-+
-+int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
-+{
-+    if (!value || (type == V_ASN1_BOOLEAN)) {
-+        void *p = (void *)value;
-+        ASN1_TYPE_set(a, type, p);
-+    } else if (type == V_ASN1_OBJECT) {
-+        ASN1_OBJECT *odup;
-+        odup = OBJ_dup(value);
-+        if (!odup)
-+            return 0;
-+        ASN1_TYPE_set(a, type, odup);
-+    } else {
-+        ASN1_STRING *sdup;
-+        sdup = ASN1_STRING_dup(value);
-+        if (!sdup)
-+            return 0;
-+        ASN1_TYPE_set(a, type, sdup);
-+    }
-+    return 1;
-+}
-+
-+/* Returns 0 if they are equal, != 0 otherwise. */
-+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
-+{
-+    int result = -1;
-+
-+    if (!a || !b || a->type != b->type)
-+        return -1;
-+
-+    switch (a->type) {
-+    case V_ASN1_OBJECT:
-+        result = OBJ_cmp(a->value.object, b->value.object);
-+        break;
-+    case V_ASN1_BOOLEAN:
-+        result = a->value.boolean - b->value.boolean;
-+        break;
-+    case V_ASN1_NULL:
-+        result = 0;             /* They do not have content. */
-+        break;
-+    case V_ASN1_INTEGER:
-+    case V_ASN1_ENUMERATED:
-+    case V_ASN1_BIT_STRING:
-+    case V_ASN1_OCTET_STRING:
-+    case V_ASN1_SEQUENCE:
-+    case V_ASN1_SET:
-+    case V_ASN1_NUMERICSTRING:
-+    case V_ASN1_PRINTABLESTRING:
-+    case V_ASN1_T61STRING:
-+    case V_ASN1_VIDEOTEXSTRING:
-+    case V_ASN1_IA5STRING:
-+    case V_ASN1_UTCTIME:
-+    case V_ASN1_GENERALIZEDTIME:
-+    case V_ASN1_GRAPHICSTRING:
-+    case V_ASN1_VISIBLESTRING:
-+    case V_ASN1_GENERALSTRING:
-+    case V_ASN1_UNIVERSALSTRING:
-+    case V_ASN1_BMPSTRING:
-+    case V_ASN1_UTF8STRING:
-+    case V_ASN1_OTHER:
-+    default:
-+        result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
-+                                 (ASN1_STRING *)b->value.ptr);
-+        break;
-+    }
-+
-+    return result;
-+}
-+
-+ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t)
-+{
-+    ASN1_OCTET_STRING *oct;
-+    ASN1_TYPE *rt;
-+
-+    oct = ASN1_item_pack(s, it, NULL);
-+    if (oct == NULL)
-+        return NULL;
-+
-+    if (t && *t) {
-+        rt = *t;
-+    } else {
-+        rt = ASN1_TYPE_new();
-+        if (rt == NULL) {
-+            ASN1_OCTET_STRING_free(oct);
-+            return NULL;
-+        }
-+        if (t)
-+            *t = rt;
-+    }
-+    ASN1_TYPE_set(rt, V_ASN1_SEQUENCE, oct);
-+    return rt;
-+}
-+
-+void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t)
-+{
-+    if (t == NULL || t->type != V_ASN1_SEQUENCE || t->value.sequence == NULL)
-+        return NULL;
-+    return ASN1_item_unpack(t->value.sequence, it);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_utctm.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_utctm.c
-new file mode 100644
-index 0000000..7916e30
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_utctm.c
-@@ -0,0 +1,254 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "asn1_locl.h"
-+
-+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
-+{
-+    static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
-+    static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
-+    char *a;
-+    int n, i, l, o;
-+
-+    if (d->type != V_ASN1_UTCTIME)
-+        return (0);
-+    l = d->length;
-+    a = (char *)d->data;
-+    o = 0;
-+
-+    if (l < 11)
-+        goto err;
-+    for (i = 0; i < 6; i++) {
-+        if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
-+            i++;
-+            if (tm)
-+                tm->tm_sec = 0;
-+            break;
-+        }
-+        if ((a[o] < '0') || (a[o] > '9'))
-+            goto err;
-+        n = a[o] - '0';
-+        if (++o > l)
-+            goto err;
-+
-+        if ((a[o] < '0') || (a[o] > '9'))
-+            goto err;
-+        n = (n * 10) + a[o] - '0';
-+        if (++o > l)
-+            goto err;
-+
-+        if ((n < min[i]) || (n > max[i]))
-+            goto err;
-+        if (tm) {
-+            switch (i) {
-+            case 0:
-+                tm->tm_year = n < 50 ? n + 100 : n;
-+                break;
-+            case 1:
-+                tm->tm_mon = n - 1;
-+                break;
-+            case 2:
-+                tm->tm_mday = n;
-+                break;
-+            case 3:
-+                tm->tm_hour = n;
-+                break;
-+            case 4:
-+                tm->tm_min = n;
-+                break;
-+            case 5:
-+                tm->tm_sec = n;
-+                break;
-+            }
-+        }
-+    }
-+    if (a[o] == 'Z')
-+        o++;
-+    else if ((a[o] == '+') || (a[o] == '-')) {
-+        int offsign = a[o] == '-' ? -1 : 1, offset = 0;
-+        o++;
-+        if (o + 4 > l)
-+            goto err;
-+        for (i = 6; i < 8; i++) {
-+            if ((a[o] < '0') || (a[o] > '9'))
-+                goto err;
-+            n = a[o] - '0';
-+            o++;
-+            if ((a[o] < '0') || (a[o] > '9'))
-+                goto err;
-+            n = (n * 10) + a[o] - '0';
-+            if ((n < min[i]) || (n > max[i]))
-+                goto err;
-+            if (tm) {
-+                if (i == 6)
-+                    offset = n * 3600;
-+                else if (i == 7)
-+                    offset += n * 60;
-+            }
-+            o++;
-+        }
-+        if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
-+            return 0;
-+    }
-+    return o == l;
-+ err:
-+    return 0;
-+}
-+
-+int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
-+{
-+    return asn1_utctime_to_tm(NULL, d);
-+}
-+
-+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
-+{
-+    ASN1_UTCTIME t;
-+
-+    t.type = V_ASN1_UTCTIME;
-+    t.length = strlen(str);
-+    t.data = (unsigned char *)str;
-+    if (ASN1_UTCTIME_check(&t)) {
-+        if (s != NULL) {
-+            if (!ASN1_STRING_set((ASN1_STRING *)s, str, t.length))
-+                return 0;
-+            s->type = V_ASN1_UTCTIME;
-+        }
-+        return (1);
-+    } else
-+        return (0);
-+}
-+
-+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
-+{
-+    return ASN1_UTCTIME_adj(s, t, 0, 0);
-+}
-+
-+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
-+                               int offset_day, long offset_sec)
-+{
-+    char *p;
-+    struct tm *ts;
-+    struct tm data;
-+    size_t len = 20;
-+    int free_s = 0;
-+
-+    if (s == NULL) {
-+        s = ASN1_UTCTIME_new();
-+        if (s == NULL)
-+            goto err;
-+        free_s = 1;
-+    }
-+
-+    ts = OPENSSL_gmtime(&t, &data);
-+    if (ts == NULL)
-+        goto err;
-+
-+    if (offset_day || offset_sec) {
-+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
-+            goto err;
-+    }
-+
-+    if ((ts->tm_year < 50) || (ts->tm_year >= 150))
-+        goto err;
-+
-+    p = (char *)s->data;
-+    if ((p == NULL) || ((size_t)s->length < len)) {
-+        p = OPENSSL_malloc(len);
-+        if (p == NULL) {
-+            ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        OPENSSL_free(s->data);
-+        s->data = (unsigned char *)p;
-+    }
-+
-+    BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100,
-+                 ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
-+                 ts->tm_sec);
-+    s->length = strlen(p);
-+    s->type = V_ASN1_UTCTIME;
-+#ifdef CHARSET_EBCDIC_not
-+    ebcdic2ascii(s->data, s->data, s->length);
-+#endif
-+    return (s);
-+ err:
-+    if (free_s)
-+        ASN1_UTCTIME_free(s);
-+    return NULL;
-+}
-+
-+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
-+{
-+    struct tm stm, ttm;
-+    int day, sec;
-+
-+    if (!asn1_utctime_to_tm(&stm, s))
-+        return -2;
-+
-+    if (!OPENSSL_gmtime(&t, &ttm))
-+        return -2;
-+
-+    if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
-+        return -2;
-+
-+    if (day > 0)
-+        return 1;
-+    if (day < 0)
-+        return -1;
-+    if (sec > 0)
-+        return 1;
-+    if (sec < 0)
-+        return -1;
-+    return 0;
-+}
-+
-+int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
-+{
-+    const char *v;
-+    int gmt = 0;
-+    int i;
-+    int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
-+
-+    i = tm->length;
-+    v = (const char *)tm->data;
-+
-+    if (i < 10)
-+        goto err;
-+    if (v[i - 1] == 'Z')
-+        gmt = 1;
-+    for (i = 0; i < 10; i++)
-+        if ((v[i] > '9') || (v[i] < '0'))
-+            goto err;
-+    y = (v[0] - '0') * 10 + (v[1] - '0');
-+    if (y < 50)
-+        y += 100;
-+    M = (v[2] - '0') * 10 + (v[3] - '0');
-+    if ((M > 12) || (M < 1))
-+        goto err;
-+    d = (v[4] - '0') * 10 + (v[5] - '0');
-+    h = (v[6] - '0') * 10 + (v[7] - '0');
-+    m = (v[8] - '0') * 10 + (v[9] - '0');
-+    if (tm->length >= 12 &&
-+        (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
-+        s = (v[10] - '0') * 10 + (v[11] - '0');
-+
-+    if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
-+                   _asn1_mon[M - 1], d, h, m, s, y + 1900,
-+                   (gmt) ? " GMT" : "") <= 0)
-+        return (0);
-+    else
-+        return (1);
-+ err:
-+    BIO_write(bp, "Bad time value", 14);
-+    return (0);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_utf8.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_utf8.c
-new file mode 100644
-index 0000000..e2dc09f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_utf8.c
-@@ -0,0 +1,188 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+/* UTF8 utilities */
-+
-+/*-
-+ * This parses a UTF8 string one character at a time. It is passed a pointer
-+ * to the string and the length of the string. It sets 'value' to the value of
-+ * the current character. It returns the number of characters read or a
-+ * negative error code:
-+ * -1 = string too short
-+ * -2 = illegal character
-+ * -3 = subsequent characters not of the form 10xxxxxx
-+ * -4 = character encoded incorrectly (not minimal length).
-+ */
-+
-+int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
-+{
-+    const unsigned char *p;
-+    unsigned long value;
-+    int ret;
-+    if (len <= 0)
-+        return 0;
-+    p = str;
-+
-+    /* Check syntax and work out the encoded value (if correct) */
-+    if ((*p & 0x80) == 0) {
-+        value = *p++ & 0x7f;
-+        ret = 1;
-+    } else if ((*p & 0xe0) == 0xc0) {
-+        if (len < 2)
-+            return -1;
-+        if ((p[1] & 0xc0) != 0x80)
-+            return -3;
-+        value = (*p++ & 0x1f) << 6;
-+        value |= *p++ & 0x3f;
-+        if (value < 0x80)
-+            return -4;
-+        ret = 2;
-+    } else if ((*p & 0xf0) == 0xe0) {
-+        if (len < 3)
-+            return -1;
-+        if (((p[1] & 0xc0) != 0x80)
-+            || ((p[2] & 0xc0) != 0x80))
-+            return -3;
-+        value = (*p++ & 0xf) << 12;
-+        value |= (*p++ & 0x3f) << 6;
-+        value |= *p++ & 0x3f;
-+        if (value < 0x800)
-+            return -4;
-+        ret = 3;
-+    } else if ((*p & 0xf8) == 0xf0) {
-+        if (len < 4)
-+            return -1;
-+        if (((p[1] & 0xc0) != 0x80)
-+            || ((p[2] & 0xc0) != 0x80)
-+            || ((p[3] & 0xc0) != 0x80))
-+            return -3;
-+        value = ((unsigned long)(*p++ & 0x7)) << 18;
-+        value |= (*p++ & 0x3f) << 12;
-+        value |= (*p++ & 0x3f) << 6;
-+        value |= *p++ & 0x3f;
-+        if (value < 0x10000)
-+            return -4;
-+        ret = 4;
-+    } else if ((*p & 0xfc) == 0xf8) {
-+        if (len < 5)
-+            return -1;
-+        if (((p[1] & 0xc0) != 0x80)
-+            || ((p[2] & 0xc0) != 0x80)
-+            || ((p[3] & 0xc0) != 0x80)
-+            || ((p[4] & 0xc0) != 0x80))
-+            return -3;
-+        value = ((unsigned long)(*p++ & 0x3)) << 24;
-+        value |= ((unsigned long)(*p++ & 0x3f)) << 18;
-+        value |= ((unsigned long)(*p++ & 0x3f)) << 12;
-+        value |= (*p++ & 0x3f) << 6;
-+        value |= *p++ & 0x3f;
-+        if (value < 0x200000)
-+            return -4;
-+        ret = 5;
-+    } else if ((*p & 0xfe) == 0xfc) {
-+        if (len < 6)
-+            return -1;
-+        if (((p[1] & 0xc0) != 0x80)
-+            || ((p[2] & 0xc0) != 0x80)
-+            || ((p[3] & 0xc0) != 0x80)
-+            || ((p[4] & 0xc0) != 0x80)
-+            || ((p[5] & 0xc0) != 0x80))
-+            return -3;
-+        value = ((unsigned long)(*p++ & 0x1)) << 30;
-+        value |= ((unsigned long)(*p++ & 0x3f)) << 24;
-+        value |= ((unsigned long)(*p++ & 0x3f)) << 18;
-+        value |= ((unsigned long)(*p++ & 0x3f)) << 12;
-+        value |= (*p++ & 0x3f) << 6;
-+        value |= *p++ & 0x3f;
-+        if (value < 0x4000000)
-+            return -4;
-+        ret = 6;
-+    } else
-+        return -2;
-+    *val = value;
-+    return ret;
-+}
-+
-+/*
-+ * This takes a character 'value' and writes the UTF8 encoded value in 'str'
-+ * where 'str' is a buffer containing 'len' characters. Returns the number of
-+ * characters written or -1 if 'len' is too small. 'str' can be set to NULL
-+ * in which case it just returns the number of characters. It will need at
-+ * most 6 characters.
-+ */
-+
-+int UTF8_putc(unsigned char *str, int len, unsigned long value)
-+{
-+    if (!str)
-+        len = 6;                /* Maximum we will need */
-+    else if (len <= 0)
-+        return -1;
-+    if (value < 0x80) {
-+        if (str)
-+            *str = (unsigned char)value;
-+        return 1;
-+    }
-+    if (value < 0x800) {
-+        if (len < 2)
-+            return -1;
-+        if (str) {
-+            *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
-+            *str = (unsigned char)((value & 0x3f) | 0x80);
-+        }
-+        return 2;
-+    }
-+    if (value < 0x10000) {
-+        if (len < 3)
-+            return -1;
-+        if (str) {
-+            *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
-+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
-+            *str = (unsigned char)((value & 0x3f) | 0x80);
-+        }
-+        return 3;
-+    }
-+    if (value < 0x200000) {
-+        if (len < 4)
-+            return -1;
-+        if (str) {
-+            *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
-+            *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
-+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
-+            *str = (unsigned char)((value & 0x3f) | 0x80);
-+        }
-+        return 4;
-+    }
-+    if (value < 0x4000000) {
-+        if (len < 5)
-+            return -1;
-+        if (str) {
-+            *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
-+            *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
-+            *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
-+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
-+            *str = (unsigned char)((value & 0x3f) | 0x80);
-+        }
-+        return 5;
-+    }
-+    if (len < 6)
-+        return -1;
-+    if (str) {
-+        *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
-+        *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
-+        *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
-+        *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
-+        *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
-+        *str = (unsigned char)((value & 0x3f) | 0x80);
-+    }
-+    return 6;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_verify.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_verify.c
-new file mode 100644
-index 0000000..00ab136
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/a_verify.c
-@@ -0,0 +1,182 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+#include "internal/cryptlib.h"
-+
-+#ifndef NO_SYS_TYPES_H
-+# include 
-+#endif
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+#ifndef NO_ASN1_OLD
-+
-+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
-+                char *data, EVP_PKEY *pkey)
-+{
-+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
-+    const EVP_MD *type;
-+    unsigned char *p, *buf_in = NULL;
-+    int ret = -1, i, inl;
-+
-+    if (ctx == NULL) {
-+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    i = OBJ_obj2nid(a->algorithm);
-+    type = EVP_get_digestbyname(OBJ_nid2sn(i));
-+    if (type == NULL) {
-+        ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
-+        goto err;
-+    }
-+
-+    if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
-+        ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
-+        goto err;
-+    }
-+
-+    inl = i2d(data, NULL);
-+    buf_in = OPENSSL_malloc((unsigned int)inl);
-+    if (buf_in == NULL) {
-+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    p = buf_in;
-+
-+    i2d(data, &p);
-+    ret = EVP_VerifyInit_ex(ctx, type, NULL)
-+        && EVP_VerifyUpdate(ctx, (unsigned char *)buf_in, inl);
-+
-+    OPENSSL_clear_free(buf_in, (unsigned int)inl);
-+
-+    if (!ret) {
-+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
-+        goto err;
-+    }
-+    ret = -1;
-+
-+    if (EVP_VerifyFinal(ctx, (unsigned char *)signature->data,
-+                        (unsigned int)signature->length, pkey) <= 0) {
-+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
-+        ret = 0;
-+        goto err;
-+    }
-+    ret = 1;
-+ err:
-+    EVP_MD_CTX_free(ctx);
-+    return (ret);
-+}
-+
-+#endif
-+
-+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
-+                     ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
-+{
-+    EVP_MD_CTX *ctx = NULL;
-+    unsigned char *buf_in = NULL;
-+    int ret = -1, inl;
-+
-+    int mdnid, pknid;
-+
-+    if (!pkey) {
-+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
-+        return -1;
-+    }
-+
-+    if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
-+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
-+        return -1;
-+    }
-+
-+    ctx = EVP_MD_CTX_new();
-+    if (ctx == NULL) {
-+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    /* Convert signature OID into digest and public key OIDs */
-+    if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
-+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
-+        goto err;
-+    }
-+    if (mdnid == NID_undef) {
-+        if (!pkey->ameth || !pkey->ameth->item_verify) {
-+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
-+                    ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
-+            goto err;
-+        }
-+        ret = pkey->ameth->item_verify(ctx, it, asn, a, signature, pkey);
-+        /*
-+         * Return value of 2 means carry on, anything else means we exit
-+         * straight away: either a fatal error of the underlying verification
-+         * routine handles all verification.
-+         */
-+        if (ret != 2)
-+            goto err;
-+        ret = -1;
-+    } else {
-+        const EVP_MD *type;
-+        type = EVP_get_digestbynid(mdnid);
-+        if (type == NULL) {
-+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
-+                    ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
-+            goto err;
-+        }
-+
-+        /* Check public key OID matches public key type */
-+        if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
-+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
-+            goto err;
-+        }
-+
-+        if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) {
-+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
-+            ret = 0;
-+            goto err;
-+        }
-+
-+    }
-+
-+    inl = ASN1_item_i2d(asn, &buf_in, it);
-+
-+    if (buf_in == NULL) {
-+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    ret = EVP_DigestVerifyUpdate(ctx, buf_in, inl);
-+
-+    OPENSSL_clear_free(buf_in, (unsigned int)inl);
-+
-+    if (!ret) {
-+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
-+        goto err;
-+    }
-+    ret = -1;
-+
-+    if (EVP_DigestVerifyFinal(ctx, signature->data,
-+                              (size_t)signature->length) <= 0) {
-+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
-+        ret = 0;
-+        goto err;
-+    }
-+    ret = 1;
-+ err:
-+    EVP_MD_CTX_free(ctx);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/ameth_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/ameth_lib.c
-new file mode 100644
-index 0000000..cfde49a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/ameth_lib.c
-@@ -0,0 +1,400 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+/* Keep this sorted in type order !! */
-+static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
-+#ifndef OPENSSL_NO_RSA
-+    &rsa_asn1_meths[0],
-+    &rsa_asn1_meths[1],
-+#endif
-+#ifndef OPENSSL_NO_DH
-+    &dh_asn1_meth,
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    &dsa_asn1_meths[0],
-+    &dsa_asn1_meths[1],
-+    &dsa_asn1_meths[2],
-+    &dsa_asn1_meths[3],
-+    &dsa_asn1_meths[4],
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    &eckey_asn1_meth,
-+#endif
-+    &hmac_asn1_meth,
-+#ifndef OPENSSL_NO_CMAC
-+    &cmac_asn1_meth,
-+#endif
-+#ifndef OPENSSL_NO_DH
-+    &dhx_asn1_meth,
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    &ecx25519_asn1_meth
-+#endif
-+};
-+
-+typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
-+static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
-+
-+#ifdef TEST
-+void main()
-+{
-+    int i;
-+    for (i = 0; i < OSSL_NELEM(standard_methods); i++)
-+        fprintf(stderr, "Number %d id=%d (%s)\n", i,
-+                standard_methods[i]->pkey_id,
-+                OBJ_nid2sn(standard_methods[i]->pkey_id));
-+}
-+#endif
-+
-+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
-+                           const EVP_PKEY_ASN1_METHOD *, ameth);
-+
-+static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a,
-+                     const EVP_PKEY_ASN1_METHOD *const *b)
-+{
-+    return ((*a)->pkey_id - (*b)->pkey_id);
-+}
-+
-+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
-+                             const EVP_PKEY_ASN1_METHOD *, ameth);
-+
-+int EVP_PKEY_asn1_get_count(void)
-+{
-+    int num = OSSL_NELEM(standard_methods);
-+    if (app_methods)
-+        num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
-+    return num;
-+}
-+
-+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
-+{
-+    int num = OSSL_NELEM(standard_methods);
-+    if (idx < 0)
-+        return NULL;
-+    if (idx < num)
-+        return standard_methods[idx];
-+    idx -= num;
-+    return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
-+}
-+
-+static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
-+{
-+    EVP_PKEY_ASN1_METHOD tmp;
-+    const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
-+    tmp.pkey_id = type;
-+    if (app_methods) {
-+        int idx;
-+        idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
-+        if (idx >= 0)
-+            return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
-+    }
-+    ret = OBJ_bsearch_ameth(&t, standard_methods, OSSL_NELEM(standard_methods));
-+    if (!ret || !*ret)
-+        return NULL;
-+    return *ret;
-+}
-+
-+/*
-+ * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also
-+ * search through engines and set *pe to a functional reference to the engine
-+ * implementing 'type' or NULL if no engine implements it.
-+ */
-+
-+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
-+{
-+    const EVP_PKEY_ASN1_METHOD *t;
-+
-+    for (;;) {
-+        t = pkey_asn1_find(type);
-+        if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
-+            break;
-+        type = t->pkey_base_id;
-+    }
-+    if (pe) {
-+#ifndef OPENSSL_NO_ENGINE
-+        ENGINE *e;
-+        /* type will contain the final unaliased type */
-+        e = ENGINE_get_pkey_asn1_meth_engine(type);
-+        if (e) {
-+            *pe = e;
-+            return ENGINE_get_pkey_asn1_meth(e, type);
-+        }
-+#endif
-+        *pe = NULL;
-+    }
-+    return t;
-+}
-+
-+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
-+                                                   const char *str, int len)
-+{
-+    int i;
-+    const EVP_PKEY_ASN1_METHOD *ameth;
-+    if (len == -1)
-+        len = strlen(str);
-+    if (pe) {
-+#ifndef OPENSSL_NO_ENGINE
-+        ENGINE *e;
-+        ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
-+        if (ameth) {
-+            /*
-+             * Convert structural into functional reference
-+             */
-+            if (!ENGINE_init(e))
-+                ameth = NULL;
-+            ENGINE_free(e);
-+            *pe = e;
-+            return ameth;
-+        }
-+#endif
-+        *pe = NULL;
-+    }
-+    for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
-+        ameth = EVP_PKEY_asn1_get0(i);
-+        if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
-+            continue;
-+        if (((int)strlen(ameth->pem_str) == len)
-+            && (strncasecmp(ameth->pem_str, str, len) == 0))
-+            return ameth;
-+    }
-+    return NULL;
-+}
-+
-+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
-+{
-+    if (app_methods == NULL) {
-+        app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
-+        if (app_methods == NULL)
-+            return 0;
-+    }
-+    if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
-+        return 0;
-+    sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
-+    return 1;
-+}
-+
-+int EVP_PKEY_asn1_add_alias(int to, int from)
-+{
-+    EVP_PKEY_ASN1_METHOD *ameth;
-+    ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
-+    if (ameth == NULL)
-+        return 0;
-+    ameth->pkey_base_id = to;
-+    if (!EVP_PKEY_asn1_add0(ameth)) {
-+        EVP_PKEY_asn1_free(ameth);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id,
-+                            int *ppkey_flags, const char **pinfo,
-+                            const char **ppem_str,
-+                            const EVP_PKEY_ASN1_METHOD *ameth)
-+{
-+    if (!ameth)
-+        return 0;
-+    if (ppkey_id)
-+        *ppkey_id = ameth->pkey_id;
-+    if (ppkey_base_id)
-+        *ppkey_base_id = ameth->pkey_base_id;
-+    if (ppkey_flags)
-+        *ppkey_flags = ameth->pkey_flags;
-+    if (pinfo)
-+        *pinfo = ameth->info;
-+    if (ppem_str)
-+        *ppem_str = ameth->pem_str;
-+    return 1;
-+}
-+
-+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey)
-+{
-+    return pkey->ameth;
-+}
-+
-+EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
-+                                        const char *pem_str, const char *info)
-+{
-+    EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth));
-+
-+    if (ameth == NULL)
-+        return NULL;
-+
-+    ameth->pkey_id = id;
-+    ameth->pkey_base_id = id;
-+    ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
-+
-+    if (info) {
-+        ameth->info = OPENSSL_strdup(info);
-+        if (!ameth->info)
-+            goto err;
-+    }
-+
-+    if (pem_str) {
-+        ameth->pem_str = OPENSSL_strdup(pem_str);
-+        if (!ameth->pem_str)
-+            goto err;
-+    }
-+
-+    return ameth;
-+
-+ err:
-+    EVP_PKEY_asn1_free(ameth);
-+    return NULL;
-+
-+}
-+
-+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
-+                        const EVP_PKEY_ASN1_METHOD *src)
-+{
-+
-+    dst->pub_decode = src->pub_decode;
-+    dst->pub_encode = src->pub_encode;
-+    dst->pub_cmp = src->pub_cmp;
-+    dst->pub_print = src->pub_print;
-+
-+    dst->priv_decode = src->priv_decode;
-+    dst->priv_encode = src->priv_encode;
-+    dst->priv_print = src->priv_print;
-+
-+    dst->old_priv_encode = src->old_priv_encode;
-+    dst->old_priv_decode = src->old_priv_decode;
-+
-+    dst->pkey_size = src->pkey_size;
-+    dst->pkey_bits = src->pkey_bits;
-+
-+    dst->param_decode = src->param_decode;
-+    dst->param_encode = src->param_encode;
-+    dst->param_missing = src->param_missing;
-+    dst->param_copy = src->param_copy;
-+    dst->param_cmp = src->param_cmp;
-+    dst->param_print = src->param_print;
-+
-+    dst->pkey_free = src->pkey_free;
-+    dst->pkey_ctrl = src->pkey_ctrl;
-+
-+    dst->item_sign = src->item_sign;
-+    dst->item_verify = src->item_verify;
-+
-+}
-+
-+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
-+{
-+    if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
-+        OPENSSL_free(ameth->pem_str);
-+        OPENSSL_free(ameth->info);
-+        OPENSSL_free(ameth);
-+    }
-+}
-+
-+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
-+                              int (*pub_decode) (EVP_PKEY *pk,
-+                                                 X509_PUBKEY *pub),
-+                              int (*pub_encode) (X509_PUBKEY *pub,
-+                                                 const EVP_PKEY *pk),
-+                              int (*pub_cmp) (const EVP_PKEY *a,
-+                                              const EVP_PKEY *b),
-+                              int (*pub_print) (BIO *out,
-+                                                const EVP_PKEY *pkey,
-+                                                int indent, ASN1_PCTX *pctx),
-+                              int (*pkey_size) (const EVP_PKEY *pk),
-+                              int (*pkey_bits) (const EVP_PKEY *pk))
-+{
-+    ameth->pub_decode = pub_decode;
-+    ameth->pub_encode = pub_encode;
-+    ameth->pub_cmp = pub_cmp;
-+    ameth->pub_print = pub_print;
-+    ameth->pkey_size = pkey_size;
-+    ameth->pkey_bits = pkey_bits;
-+}
-+
-+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
-+                               int (*priv_decode) (EVP_PKEY *pk,
-+                                                   const PKCS8_PRIV_KEY_INFO
-+                                                   *p8inf),
-+                               int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
-+                                                   const EVP_PKEY *pk),
-+                               int (*priv_print) (BIO *out,
-+                                                  const EVP_PKEY *pkey,
-+                                                  int indent,
-+                                                  ASN1_PCTX *pctx))
-+{
-+    ameth->priv_decode = priv_decode;
-+    ameth->priv_encode = priv_encode;
-+    ameth->priv_print = priv_print;
-+}
-+
-+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
-+                             int (*param_decode) (EVP_PKEY *pkey,
-+                                                  const unsigned char **pder,
-+                                                  int derlen),
-+                             int (*param_encode) (const EVP_PKEY *pkey,
-+                                                  unsigned char **pder),
-+                             int (*param_missing) (const EVP_PKEY *pk),
-+                             int (*param_copy) (EVP_PKEY *to,
-+                                                const EVP_PKEY *from),
-+                             int (*param_cmp) (const EVP_PKEY *a,
-+                                               const EVP_PKEY *b),
-+                             int (*param_print) (BIO *out,
-+                                                 const EVP_PKEY *pkey,
-+                                                 int indent, ASN1_PCTX *pctx))
-+{
-+    ameth->param_decode = param_decode;
-+    ameth->param_encode = param_encode;
-+    ameth->param_missing = param_missing;
-+    ameth->param_copy = param_copy;
-+    ameth->param_cmp = param_cmp;
-+    ameth->param_print = param_print;
-+}
-+
-+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
-+                            void (*pkey_free) (EVP_PKEY *pkey))
-+{
-+    ameth->pkey_free = pkey_free;
-+}
-+
-+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
-+                            int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
-+                                              long arg1, void *arg2))
-+{
-+    ameth->pkey_ctrl = pkey_ctrl;
-+}
-+
-+void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
-+                                     int (*pkey_security_bits) (const EVP_PKEY
-+                                                                *pk))
-+{
-+    ameth->pkey_security_bits = pkey_security_bits;
-+}
-+
-+void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
-+                            int (*item_verify) (EVP_MD_CTX *ctx,
-+                                                const ASN1_ITEM *it,
-+                                                void *asn,
-+                                                X509_ALGOR *a,
-+                                                ASN1_BIT_STRING *sig,
-+                                                EVP_PKEY *pkey),
-+                            int (*item_sign) (EVP_MD_CTX *ctx,
-+                                              const ASN1_ITEM *it,
-+                                              void *asn,
-+                                              X509_ALGOR *alg1,
-+                                              X509_ALGOR *alg2,
-+                                              ASN1_BIT_STRING *sig))
-+{
-+    ameth->item_sign = item_sign;
-+    ameth->item_verify = item_verify;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_err.c
-new file mode 100644
-index 0000000..97c3dec
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_err.c
-@@ -0,0 +1,267 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
-+
-+static ERR_STRING_DATA ASN1_str_functs[] = {
-+    {ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"},
-+    {ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"},
-+    {ERR_FUNC(ASN1_F_A2I_ASN1_STRING), "a2i_ASN1_STRING"},
-+    {ERR_FUNC(ASN1_F_APPEND_EXP), "append_exp"},
-+    {ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"},
-+    {ERR_FUNC(ASN1_F_ASN1_CB), "asn1_cb"},
-+    {ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "asn1_check_tlen"},
-+    {ERR_FUNC(ASN1_F_ASN1_COLLECT), "asn1_collect"},
-+    {ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "asn1_d2i_ex_primitive"},
-+    {ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"},
-+    {ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "asn1_d2i_read_bio"},
-+    {ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"},
-+    {ERR_FUNC(ASN1_F_ASN1_DO_ADB), "asn1_do_adb"},
-+    {ERR_FUNC(ASN1_F_ASN1_DO_LOCK), "asn1_do_lock"},
-+    {ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"},
-+    {ERR_FUNC(ASN1_F_ASN1_EX_C2I), "asn1_ex_c2i"},
-+    {ERR_FUNC(ASN1_F_ASN1_FIND_END), "asn1_find_end"},
-+    {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"},
-+    {ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"},
-+    {ERR_FUNC(ASN1_F_ASN1_GET_INT64), "asn1_get_int64"},
-+    {ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"},
-+    {ERR_FUNC(ASN1_F_ASN1_GET_UINT64), "asn1_get_uint64"},
-+    {ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"},
-+    {ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_EMBED_D2I), "asn1_item_embed_d2i"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_EMBED_NEW), "asn1_item_embed_new"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"},
-+    {ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
-+    {ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
-+    {ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"},
-+    {ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "asn1_output_data"},
-+    {ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"},
-+    {ERR_FUNC(ASN1_F_ASN1_SCTX_NEW), "ASN1_SCTX_new"},
-+    {ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"},
-+    {ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "asn1_str2type"},
-+    {ERR_FUNC(ASN1_F_ASN1_STRING_GET_INT64), "asn1_string_get_int64"},
-+    {ERR_FUNC(ASN1_F_ASN1_STRING_GET_UINT64), "asn1_string_get_uint64"},
-+    {ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"},
-+    {ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"},
-+    {ERR_FUNC(ASN1_F_ASN1_STRING_TO_BN), "asn1_string_to_bn"},
-+    {ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"},
-+    {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "asn1_template_ex_d2i"},
-+    {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "asn1_template_new"},
-+    {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "asn1_template_noexp_d2i"},
-+    {ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"},
-+    {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING),
-+     "ASN1_TYPE_get_int_octetstring"},
-+    {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"},
-+    {ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"},
-+    {ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"},
-+    {ERR_FUNC(ASN1_F_B64_READ_ASN1), "b64_read_asn1"},
-+    {ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_write_ASN1"},
-+    {ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"},
-+    {ERR_FUNC(ASN1_F_BITSTR_CB), "bitstr_cb"},
-+    {ERR_FUNC(ASN1_F_BN_TO_ASN1_STRING), "bn_to_asn1_string"},
-+    {ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"},
-+    {ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"},
-+    {ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"},
-+    {ERR_FUNC(ASN1_F_C2I_IBUF), "c2i_ibuf"},
-+    {ERR_FUNC(ASN1_F_COLLECT_DATA), "collect_data"},
-+    {ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"},
-+    {ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"},
-+    {ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"},
-+    {ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"},
-+    {ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"},
-+    {ERR_FUNC(ASN1_F_DO_TCREATE), "do_tcreate"},
-+    {ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"},
-+    {ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"},
-+    {ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"},
-+    {ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"},
-+    {ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"},
-+    {ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"},
-+    {ERR_FUNC(ASN1_F_LONG_C2I), "long_c2i"},
-+    {ERR_FUNC(ASN1_F_OID_MODULE_INIT), "oid_module_init"},
-+    {ERR_FUNC(ASN1_F_PARSE_TAGGING), "parse_tagging"},
-+    {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"},
-+    {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_SCRYPT), "PKCS5_pbe2_set_scrypt"},
-+    {ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
-+    {ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"},
-+    {ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"},
-+    {ERR_FUNC(ASN1_F_PKCS5_SCRYPT_SET), "pkcs5_scrypt_set"},
-+    {ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"},
-+    {ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"},
-+    {ERR_FUNC(ASN1_F_STBL_MODULE_INIT), "stbl_module_init"},
-+    {ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"},
-+    {ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"},
-+    {ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "x509_name_encode"},
-+    {ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "x509_name_ex_d2i"},
-+    {ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "x509_name_ex_new"},
-+    {ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA ASN1_str_reasons[] = {
-+    {ERR_REASON(ASN1_R_ADDING_OBJECT), "adding object"},
-+    {ERR_REASON(ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error"},
-+    {ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR), "asn1 sig parse error"},
-+    {ERR_REASON(ASN1_R_AUX_ERROR), "aux error"},
-+    {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER), "bad object header"},
-+    {ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),
-+     "bmpstring is wrong length"},
-+    {ERR_REASON(ASN1_R_BN_LIB), "bn lib"},
-+    {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"},
-+    {ERR_REASON(ASN1_R_BUFFER_TOO_SMALL), "buffer too small"},
-+    {ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),
-+     "cipher has no object identifier"},
-+    {ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED), "context not initialised"},
-+    {ERR_REASON(ASN1_R_DATA_IS_WRONG), "data is wrong"},
-+    {ERR_REASON(ASN1_R_DECODE_ERROR), "decode error"},
-+    {ERR_REASON(ASN1_R_DEPTH_EXCEEDED), "depth exceeded"},
-+    {ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),
-+     "digest and key type not supported"},
-+    {ERR_REASON(ASN1_R_ENCODE_ERROR), "encode error"},
-+    {ERR_REASON(ASN1_R_ERROR_GETTING_TIME), "error getting time"},
-+    {ERR_REASON(ASN1_R_ERROR_LOADING_SECTION), "error loading section"},
-+    {ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS),
-+     "error setting cipher params"},
-+    {ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER), "expecting an integer"},
-+    {ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT), "expecting an object"},
-+    {ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH), "explicit length mismatch"},
-+    {ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED),
-+     "explicit tag not constructed"},
-+    {ERR_REASON(ASN1_R_FIELD_MISSING), "field missing"},
-+    {ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE), "first num too large"},
-+    {ERR_REASON(ASN1_R_HEADER_TOO_LONG), "header too long"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT), "illegal bitstring format"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN), "illegal boolean"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS), "illegal characters"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_FORMAT), "illegal format"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_HEX), "illegal hex"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG), "illegal implicit tag"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_INTEGER), "illegal integer"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_NEGATIVE_VALUE), "illegal negative value"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING), "illegal nested tagging"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_NULL), "illegal null"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE), "illegal null value"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_OBJECT), "illegal object"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY), "illegal optional any"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE),
-+     "illegal options on item template"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_PADDING), "illegal padding"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY), "illegal tagged any"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE), "illegal time value"},
-+    {ERR_REASON(ASN1_R_ILLEGAL_ZERO_CONTENT), "illegal zero content"},
-+    {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT), "integer not ascii format"},
-+    {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),
-+     "integer too large for long"},
-+    {ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),
-+     "invalid bit string bits left"},
-+    {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH), "invalid bmpstring length"},
-+    {ERR_REASON(ASN1_R_INVALID_DIGIT), "invalid digit"},
-+    {ERR_REASON(ASN1_R_INVALID_MIME_TYPE), "invalid mime type"},
-+    {ERR_REASON(ASN1_R_INVALID_MODIFIER), "invalid modifier"},
-+    {ERR_REASON(ASN1_R_INVALID_NUMBER), "invalid number"},
-+    {ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING), "invalid object encoding"},
-+    {ERR_REASON(ASN1_R_INVALID_SCRYPT_PARAMETERS),
-+     "invalid scrypt parameters"},
-+    {ERR_REASON(ASN1_R_INVALID_SEPARATOR), "invalid separator"},
-+    {ERR_REASON(ASN1_R_INVALID_STRING_TABLE_VALUE),
-+     "invalid string table value"},
-+    {ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),
-+     "invalid universalstring length"},
-+    {ERR_REASON(ASN1_R_INVALID_UTF8STRING), "invalid utf8string"},
-+    {ERR_REASON(ASN1_R_INVALID_VALUE), "invalid value"},
-+    {ERR_REASON(ASN1_R_LIST_ERROR), "list error"},
-+    {ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE), "mime no content type"},
-+    {ERR_REASON(ASN1_R_MIME_PARSE_ERROR), "mime parse error"},
-+    {ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"},
-+    {ERR_REASON(ASN1_R_MISSING_EOC), "missing eoc"},
-+    {ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER), "missing second number"},
-+    {ERR_REASON(ASN1_R_MISSING_VALUE), "missing value"},
-+    {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"},
-+    {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"},
-+    {ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"},
-+    {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"},
-+    {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"},
-+    {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"},
-+    {ERR_REASON(ASN1_R_NO_CONTENT_TYPE), "no content type"},
-+    {ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE), "no matching choice type"},
-+    {ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),
-+     "no multipart body failure"},
-+    {ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"},
-+    {ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE), "no sig content type"},
-+    {ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH), "null is wrong length"},
-+    {ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT), "object not ascii format"},
-+    {ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS), "odd number of chars"},
-+    {ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE), "second number too large"},
-+    {ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH), "sequence length mismatch"},
-+    {ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED), "sequence not constructed"},
-+    {ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),
-+     "sequence or set needs config"},
-+    {ERR_REASON(ASN1_R_SHORT_LINE), "short line"},
-+    {ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"},
-+    {ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED), "streaming not supported"},
-+    {ERR_REASON(ASN1_R_STRING_TOO_LONG), "string too long"},
-+    {ERR_REASON(ASN1_R_STRING_TOO_SHORT), "string too short"},
-+    {ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),
-+     "the asn1 object identifier is not known for this md"},
-+    {ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT), "time not ascii format"},
-+    {ERR_REASON(ASN1_R_TOO_LARGE), "too large"},
-+    {ERR_REASON(ASN1_R_TOO_LONG), "too long"},
-+    {ERR_REASON(ASN1_R_TOO_SMALL), "too small"},
-+    {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED), "type not constructed"},
-+    {ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE), "type not primitive"},
-+    {ERR_REASON(ASN1_R_UNEXPECTED_EOC), "unexpected eoc"},
-+    {ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),
-+     "universalstring is wrong length"},
-+    {ERR_REASON(ASN1_R_UNKNOWN_FORMAT), "unknown format"},
-+    {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),
-+     "unknown message digest algorithm"},
-+    {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE), "unknown object type"},
-+    {ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), "unknown public key type"},
-+    {ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),
-+     "unknown signature algorithm"},
-+    {ERR_REASON(ASN1_R_UNKNOWN_TAG), "unknown tag"},
-+    {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),
-+     "unsupported any defined by type"},
-+    {ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),
-+     "unsupported public key type"},
-+    {ERR_REASON(ASN1_R_UNSUPPORTED_TYPE), "unsupported type"},
-+    {ERR_REASON(ASN1_R_WRONG_INTEGER_TYPE), "wrong integer type"},
-+    {ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"},
-+    {ERR_REASON(ASN1_R_WRONG_TAG), "wrong tag"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_ASN1_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, ASN1_str_functs);
-+        ERR_load_strings(0, ASN1_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_gen.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_gen.c
-new file mode 100644
-index 0000000..493a693
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_gen.c
-@@ -0,0 +1,789 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+#define ASN1_GEN_FLAG           0x10000
-+#define ASN1_GEN_FLAG_IMP       (ASN1_GEN_FLAG|1)
-+#define ASN1_GEN_FLAG_EXP       (ASN1_GEN_FLAG|2)
-+#define ASN1_GEN_FLAG_TAG       (ASN1_GEN_FLAG|3)
-+#define ASN1_GEN_FLAG_BITWRAP   (ASN1_GEN_FLAG|4)
-+#define ASN1_GEN_FLAG_OCTWRAP   (ASN1_GEN_FLAG|5)
-+#define ASN1_GEN_FLAG_SEQWRAP   (ASN1_GEN_FLAG|6)
-+#define ASN1_GEN_FLAG_SETWRAP   (ASN1_GEN_FLAG|7)
-+#define ASN1_GEN_FLAG_FORMAT    (ASN1_GEN_FLAG|8)
-+
-+#define ASN1_GEN_STR(str,val)   {str, sizeof(str) - 1, val}
-+
-+#define ASN1_FLAG_EXP_MAX       20
-+/* Maximum number of nested sequences */
-+#define ASN1_GEN_SEQ_MAX_DEPTH  50
-+
-+/* Input formats */
-+
-+/* ASCII: default */
-+#define ASN1_GEN_FORMAT_ASCII   1
-+/* UTF8 */
-+#define ASN1_GEN_FORMAT_UTF8    2
-+/* Hex */
-+#define ASN1_GEN_FORMAT_HEX     3
-+/* List of bits */
-+#define ASN1_GEN_FORMAT_BITLIST 4
-+
-+struct tag_name_st {
-+    const char *strnam;
-+    int len;
-+    int tag;
-+};
-+
-+typedef struct {
-+    int exp_tag;
-+    int exp_class;
-+    int exp_constructed;
-+    int exp_pad;
-+    long exp_len;
-+} tag_exp_type;
-+
-+typedef struct {
-+    int imp_tag;
-+    int imp_class;
-+    int utype;
-+    int format;
-+    const char *str;
-+    tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
-+    int exp_count;
-+} tag_exp_arg;
-+
-+static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth,
-+                              int *perr);
-+static int bitstr_cb(const char *elem, int len, void *bitstr);
-+static int asn1_cb(const char *elem, int len, void *bitstr);
-+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
-+                      int exp_constructed, int exp_pad, int imp_ok);
-+static int parse_tagging(const char *vstart, int vlen, int *ptag,
-+                         int *pclass);
-+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
-+                             int depth, int *perr);
-+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
-+static int asn1_str2tag(const char *tagstr, int len);
-+
-+ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf)
-+{
-+    X509V3_CTX cnf;
-+
-+    if (!nconf)
-+        return ASN1_generate_v3(str, NULL);
-+
-+    X509V3_set_nconf(&cnf, nconf);
-+    return ASN1_generate_v3(str, &cnf);
-+}
-+
-+ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf)
-+{
-+    int err = 0;
-+    ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err);
-+    if (err)
-+        ASN1err(ASN1_F_ASN1_GENERATE_V3, err);
-+    return ret;
-+}
-+
-+static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth,
-+                              int *perr)
-+{
-+    ASN1_TYPE *ret;
-+    tag_exp_arg asn1_tags;
-+    tag_exp_type *etmp;
-+
-+    int i, len;
-+
-+    unsigned char *orig_der = NULL, *new_der = NULL;
-+    const unsigned char *cpy_start;
-+    unsigned char *p;
-+    const unsigned char *cp;
-+    int cpy_len;
-+    long hdr_len = 0;
-+    int hdr_constructed = 0, hdr_tag, hdr_class;
-+    int r;
-+
-+    asn1_tags.imp_tag = -1;
-+    asn1_tags.imp_class = -1;
-+    asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
-+    asn1_tags.exp_count = 0;
-+    if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) {
-+        *perr = ASN1_R_UNKNOWN_TAG;
-+        return NULL;
-+    }
-+
-+    if ((asn1_tags.utype == V_ASN1_SEQUENCE)
-+        || (asn1_tags.utype == V_ASN1_SET)) {
-+        if (!cnf) {
-+            *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG;
-+            return NULL;
-+        }
-+        if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) {
-+            *perr = ASN1_R_ILLEGAL_NESTED_TAGGING;
-+            return NULL;
-+        }
-+        ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr);
-+    } else
-+        ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
-+
-+    if (!ret)
-+        return NULL;
-+
-+    /* If no tagging return base type */
-+    if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
-+        return ret;
-+
-+    /* Generate the encoding */
-+    cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
-+    ASN1_TYPE_free(ret);
-+    ret = NULL;
-+    /* Set point to start copying for modified encoding */
-+    cpy_start = orig_der;
-+
-+    /* Do we need IMPLICIT tagging? */
-+    if (asn1_tags.imp_tag != -1) {
-+        /* If IMPLICIT we will replace the underlying tag */
-+        /* Skip existing tag+len */
-+        r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class,
-+                            cpy_len);
-+        if (r & 0x80)
-+            goto err;
-+        /* Update copy length */
-+        cpy_len -= cpy_start - orig_der;
-+        /*
-+         * For IMPLICIT tagging the length should match the original length
-+         * and constructed flag should be consistent.
-+         */
-+        if (r & 0x1) {
-+            /* Indefinite length constructed */
-+            hdr_constructed = 2;
-+            hdr_len = 0;
-+        } else
-+            /* Just retain constructed flag */
-+            hdr_constructed = r & V_ASN1_CONSTRUCTED;
-+        /*
-+         * Work out new length with IMPLICIT tag: ignore constructed because
-+         * it will mess up if indefinite length
-+         */
-+        len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
-+    } else
-+        len = cpy_len;
-+
-+    /* Work out length in any EXPLICIT, starting from end */
-+
-+    for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1;
-+         i < asn1_tags.exp_count; i++, etmp--) {
-+        /* Content length: number of content octets + any padding */
-+        len += etmp->exp_pad;
-+        etmp->exp_len = len;
-+        /* Total object length: length including new header */
-+        len = ASN1_object_size(0, len, etmp->exp_tag);
-+    }
-+
-+    /* Allocate buffer for new encoding */
-+
-+    new_der = OPENSSL_malloc(len);
-+    if (new_der == NULL)
-+        goto err;
-+
-+    /* Generate tagged encoding */
-+
-+    p = new_der;
-+
-+    /* Output explicit tags first */
-+
-+    for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count;
-+         i++, etmp++) {
-+        ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
-+                        etmp->exp_tag, etmp->exp_class);
-+        if (etmp->exp_pad)
-+            *p++ = 0;
-+    }
-+
-+    /* If IMPLICIT, output tag */
-+
-+    if (asn1_tags.imp_tag != -1) {
-+        if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
-+            && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
-+                || asn1_tags.imp_tag == V_ASN1_SET))
-+            hdr_constructed = V_ASN1_CONSTRUCTED;
-+        ASN1_put_object(&p, hdr_constructed, hdr_len,
-+                        asn1_tags.imp_tag, asn1_tags.imp_class);
-+    }
-+
-+    /* Copy across original encoding */
-+    memcpy(p, cpy_start, cpy_len);
-+
-+    cp = new_der;
-+
-+    /* Obtain new ASN1_TYPE structure */
-+    ret = d2i_ASN1_TYPE(NULL, &cp, len);
-+
-+ err:
-+    OPENSSL_free(orig_der);
-+    OPENSSL_free(new_der);
-+
-+    return ret;
-+
-+}
-+
-+static int asn1_cb(const char *elem, int len, void *bitstr)
-+{
-+    tag_exp_arg *arg = bitstr;
-+    int i;
-+    int utype;
-+    int vlen = 0;
-+    const char *p, *vstart = NULL;
-+
-+    int tmp_tag, tmp_class;
-+
-+    if (elem == NULL)
-+        return -1;
-+
-+    for (i = 0, p = elem; i < len; p++, i++) {
-+        /* Look for the ':' in name value pairs */
-+        if (*p == ':') {
-+            vstart = p + 1;
-+            vlen = len - (vstart - elem);
-+            len = p - elem;
-+            break;
-+        }
-+    }
-+
-+    utype = asn1_str2tag(elem, len);
-+
-+    if (utype == -1) {
-+        ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
-+        ERR_add_error_data(2, "tag=", elem);
-+        return -1;
-+    }
-+
-+    /* If this is not a modifier mark end of string and exit */
-+    if (!(utype & ASN1_GEN_FLAG)) {
-+        arg->utype = utype;
-+        arg->str = vstart;
-+        /* If no value and not end of string, error */
-+        if (!vstart && elem[len]) {
-+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
-+            return -1;
-+        }
-+        return 0;
-+    }
-+
-+    switch (utype) {
-+
-+    case ASN1_GEN_FLAG_IMP:
-+        /* Check for illegal multiple IMPLICIT tagging */
-+        if (arg->imp_tag != -1) {
-+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
-+            return -1;
-+        }
-+        if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
-+            return -1;
-+        break;
-+
-+    case ASN1_GEN_FLAG_EXP:
-+
-+        if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
-+            return -1;
-+        if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
-+            return -1;
-+        break;
-+
-+    case ASN1_GEN_FLAG_SEQWRAP:
-+        if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
-+            return -1;
-+        break;
-+
-+    case ASN1_GEN_FLAG_SETWRAP:
-+        if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
-+            return -1;
-+        break;
-+
-+    case ASN1_GEN_FLAG_BITWRAP:
-+        if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
-+            return -1;
-+        break;
-+
-+    case ASN1_GEN_FLAG_OCTWRAP:
-+        if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
-+            return -1;
-+        break;
-+
-+    case ASN1_GEN_FLAG_FORMAT:
-+        if (!vstart) {
-+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
-+            return -1;
-+        }
-+        if (strncmp(vstart, "ASCII", 5) == 0)
-+            arg->format = ASN1_GEN_FORMAT_ASCII;
-+        else if (strncmp(vstart, "UTF8", 4) == 0)
-+            arg->format = ASN1_GEN_FORMAT_UTF8;
-+        else if (strncmp(vstart, "HEX", 3) == 0)
-+            arg->format = ASN1_GEN_FORMAT_HEX;
-+        else if (strncmp(vstart, "BITLIST", 7) == 0)
-+            arg->format = ASN1_GEN_FORMAT_BITLIST;
-+        else {
-+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
-+            return -1;
-+        }
-+        break;
-+
-+    }
-+
-+    return 1;
-+
-+}
-+
-+static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
-+{
-+    char erch[2];
-+    long tag_num;
-+    char *eptr;
-+    if (!vstart)
-+        return 0;
-+    tag_num = strtoul(vstart, &eptr, 10);
-+    /* Check we haven't gone past max length: should be impossible */
-+    if (eptr && *eptr && (eptr > vstart + vlen))
-+        return 0;
-+    if (tag_num < 0) {
-+        ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);
-+        return 0;
-+    }
-+    *ptag = tag_num;
-+    /* If we have non numeric characters, parse them */
-+    if (eptr)
-+        vlen -= eptr - vstart;
-+    else
-+        vlen = 0;
-+    if (vlen) {
-+        switch (*eptr) {
-+
-+        case 'U':
-+            *pclass = V_ASN1_UNIVERSAL;
-+            break;
-+
-+        case 'A':
-+            *pclass = V_ASN1_APPLICATION;
-+            break;
-+
-+        case 'P':
-+            *pclass = V_ASN1_PRIVATE;
-+            break;
-+
-+        case 'C':
-+            *pclass = V_ASN1_CONTEXT_SPECIFIC;
-+            break;
-+
-+        default:
-+            erch[0] = *eptr;
-+            erch[1] = 0;
-+            ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER);
-+            ERR_add_error_data(2, "Char=", erch);
-+            return 0;
-+
-+        }
-+    } else
-+        *pclass = V_ASN1_CONTEXT_SPECIFIC;
-+
-+    return 1;
-+
-+}
-+
-+/* Handle multiple types: SET and SEQUENCE */
-+
-+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
-+                             int depth, int *perr)
-+{
-+    ASN1_TYPE *ret = NULL;
-+    STACK_OF(ASN1_TYPE) *sk = NULL;
-+    STACK_OF(CONF_VALUE) *sect = NULL;
-+    unsigned char *der = NULL;
-+    int derlen;
-+    int i;
-+    sk = sk_ASN1_TYPE_new_null();
-+    if (!sk)
-+        goto bad;
-+    if (section) {
-+        if (!cnf)
-+            goto bad;
-+        sect = X509V3_get_section(cnf, (char *)section);
-+        if (!sect)
-+            goto bad;
-+        for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
-+            ASN1_TYPE *typ =
-+                generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf,
-+                            depth + 1, perr);
-+            if (!typ)
-+                goto bad;
-+            if (!sk_ASN1_TYPE_push(sk, typ))
-+                goto bad;
-+        }
-+    }
-+
-+    /*
-+     * Now we has a STACK of the components, convert to the correct form
-+     */
-+
-+    if (utype == V_ASN1_SET)
-+        derlen = i2d_ASN1_SET_ANY(sk, &der);
-+    else
-+        derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
-+
-+    if (derlen < 0)
-+        goto bad;
-+    if ((ret = ASN1_TYPE_new()) == NULL)
-+        goto bad;
-+    if ((ret->value.asn1_string = ASN1_STRING_type_new(utype)) == NULL)
-+        goto bad;
-+
-+    ret->type = utype;
-+    ret->value.asn1_string->data = der;
-+    ret->value.asn1_string->length = derlen;
-+
-+    der = NULL;
-+
-+ bad:
-+
-+    OPENSSL_free(der);
-+
-+    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
-+    X509V3_section_free(cnf, sect);
-+
-+    return ret;
-+}
-+
-+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
-+                      int exp_constructed, int exp_pad, int imp_ok)
-+{
-+    tag_exp_type *exp_tmp;
-+    /* Can only have IMPLICIT if permitted */
-+    if ((arg->imp_tag != -1) && !imp_ok) {
-+        ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG);
-+        return 0;
-+    }
-+
-+    if (arg->exp_count == ASN1_FLAG_EXP_MAX) {
-+        ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED);
-+        return 0;
-+    }
-+
-+    exp_tmp = &arg->exp_list[arg->exp_count++];
-+
-+    /*
-+     * If IMPLICIT set tag to implicit value then reset implicit tag since it
-+     * has been used.
-+     */
-+    if (arg->imp_tag != -1) {
-+        exp_tmp->exp_tag = arg->imp_tag;
-+        exp_tmp->exp_class = arg->imp_class;
-+        arg->imp_tag = -1;
-+        arg->imp_class = -1;
-+    } else {
-+        exp_tmp->exp_tag = exp_tag;
-+        exp_tmp->exp_class = exp_class;
-+    }
-+    exp_tmp->exp_constructed = exp_constructed;
-+    exp_tmp->exp_pad = exp_pad;
-+
-+    return 1;
-+}
-+
-+static int asn1_str2tag(const char *tagstr, int len)
-+{
-+    unsigned int i;
-+    static const struct tag_name_st *tntmp, tnst[] = {
-+        ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
-+        ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
-+        ASN1_GEN_STR("NULL", V_ASN1_NULL),
-+        ASN1_GEN_STR("INT", V_ASN1_INTEGER),
-+        ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
-+        ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
-+        ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
-+        ASN1_GEN_STR("OID", V_ASN1_OBJECT),
-+        ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
-+        ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
-+        ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
-+        ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
-+        ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
-+        ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
-+        ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
-+        ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
-+        ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
-+        ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
-+        ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
-+        ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
-+        ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
-+        ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
-+        ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
-+        ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
-+        ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
-+        ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
-+        ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
-+        ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
-+        ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
-+        ASN1_GEN_STR("T61", V_ASN1_T61STRING),
-+        ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
-+        ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
-+        ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
-+        ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
-+        ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
-+        ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
-+
-+        /* Special cases */
-+        ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
-+        ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
-+        ASN1_GEN_STR("SET", V_ASN1_SET),
-+        /* type modifiers */
-+        /* Explicit tag */
-+        ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
-+        ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
-+        /* Implicit tag */
-+        ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
-+        ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
-+        /* OCTET STRING wrapper */
-+        ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
-+        /* SEQUENCE wrapper */
-+        ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
-+        /* SET wrapper */
-+        ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
-+        /* BIT STRING wrapper */
-+        ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
-+        ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
-+        ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
-+    };
-+
-+    if (len == -1)
-+        len = strlen(tagstr);
-+
-+    tntmp = tnst;
-+    for (i = 0; i < OSSL_NELEM(tnst); i++, tntmp++) {
-+        if ((len == tntmp->len) && (strncmp(tntmp->strnam, tagstr, len) == 0))
-+            return tntmp->tag;
-+    }
-+
-+    return -1;
-+}
-+
-+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
-+{
-+    ASN1_TYPE *atmp = NULL;
-+    CONF_VALUE vtmp;
-+    unsigned char *rdata;
-+    long rdlen;
-+    int no_unused = 1;
-+
-+    if ((atmp = ASN1_TYPE_new()) == NULL) {
-+        ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    if (!str)
-+        str = "";
-+
-+    switch (utype) {
-+
-+    case V_ASN1_NULL:
-+        if (str && *str) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
-+            goto bad_form;
-+        }
-+        break;
-+
-+    case V_ASN1_BOOLEAN:
-+        if (format != ASN1_GEN_FORMAT_ASCII) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
-+            goto bad_form;
-+        }
-+        vtmp.name = NULL;
-+        vtmp.section = NULL;
-+        vtmp.value = (char *)str;
-+        if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
-+            goto bad_str;
-+        }
-+        break;
-+
-+    case V_ASN1_INTEGER:
-+    case V_ASN1_ENUMERATED:
-+        if (format != ASN1_GEN_FORMAT_ASCII) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
-+            goto bad_form;
-+        }
-+        if ((atmp->value.integer
-+                    = s2i_ASN1_INTEGER(NULL, str)) == NULL) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
-+            goto bad_str;
-+        }
-+        break;
-+
-+    case V_ASN1_OBJECT:
-+        if (format != ASN1_GEN_FORMAT_ASCII) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
-+            goto bad_form;
-+        }
-+        if ((atmp->value.object = OBJ_txt2obj(str, 0)) == NULL) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
-+            goto bad_str;
-+        }
-+        break;
-+
-+    case V_ASN1_UTCTIME:
-+    case V_ASN1_GENERALIZEDTIME:
-+        if (format != ASN1_GEN_FORMAT_ASCII) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
-+            goto bad_form;
-+        }
-+        if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
-+            goto bad_str;
-+        }
-+        if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
-+            goto bad_str;
-+        }
-+        atmp->value.asn1_string->type = utype;
-+        if (!ASN1_TIME_check(atmp->value.asn1_string)) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
-+            goto bad_str;
-+        }
-+
-+        break;
-+
-+    case V_ASN1_BMPSTRING:
-+    case V_ASN1_PRINTABLESTRING:
-+    case V_ASN1_IA5STRING:
-+    case V_ASN1_T61STRING:
-+    case V_ASN1_UTF8STRING:
-+    case V_ASN1_VISIBLESTRING:
-+    case V_ASN1_UNIVERSALSTRING:
-+    case V_ASN1_GENERALSTRING:
-+    case V_ASN1_NUMERICSTRING:
-+        if (format == ASN1_GEN_FORMAT_ASCII)
-+            format = MBSTRING_ASC;
-+        else if (format == ASN1_GEN_FORMAT_UTF8)
-+            format = MBSTRING_UTF8;
-+        else {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
-+            goto bad_form;
-+        }
-+
-+        if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
-+                               -1, format, ASN1_tag2bit(utype)) <= 0) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
-+            goto bad_str;
-+        }
-+
-+        break;
-+
-+    case V_ASN1_BIT_STRING:
-+    case V_ASN1_OCTET_STRING:
-+        if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
-+            goto bad_form;
-+        }
-+
-+        if (format == ASN1_GEN_FORMAT_HEX) {
-+            if ((rdata = OPENSSL_hexstr2buf(str, &rdlen)) == NULL) {
-+                ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
-+                goto bad_str;
-+            }
-+            atmp->value.asn1_string->data = rdata;
-+            atmp->value.asn1_string->length = rdlen;
-+            atmp->value.asn1_string->type = utype;
-+        } else if (format == ASN1_GEN_FORMAT_ASCII)
-+            ASN1_STRING_set(atmp->value.asn1_string, str, -1);
-+        else if ((format == ASN1_GEN_FORMAT_BITLIST)
-+                 && (utype == V_ASN1_BIT_STRING)) {
-+            if (!CONF_parse_list
-+                (str, ',', 1, bitstr_cb, atmp->value.bit_string)) {
-+                ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
-+                goto bad_str;
-+            }
-+            no_unused = 0;
-+
-+        } else {
-+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
-+            goto bad_form;
-+        }
-+
-+        if ((utype == V_ASN1_BIT_STRING) && no_unused) {
-+            atmp->value.asn1_string->flags
-+                &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-+            atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-+        }
-+
-+        break;
-+
-+    default:
-+        ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
-+        goto bad_str;
-+    }
-+
-+    atmp->type = utype;
-+    return atmp;
-+
-+ bad_str:
-+    ERR_add_error_data(2, "string=", str);
-+ bad_form:
-+
-+    ASN1_TYPE_free(atmp);
-+    return NULL;
-+
-+}
-+
-+static int bitstr_cb(const char *elem, int len, void *bitstr)
-+{
-+    long bitnum;
-+    char *eptr;
-+    if (!elem)
-+        return 0;
-+    bitnum = strtoul(elem, &eptr, 10);
-+    if (eptr && *eptr && (eptr != elem + len))
-+        return 0;
-+    if (bitnum < 0) {
-+        ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
-+        return 0;
-+    }
-+    if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) {
-+        ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+static int mask_cb(const char *elem, int len, void *arg)
-+{
-+    unsigned long *pmask = arg, tmpmask;
-+    int tag;
-+    if (elem == NULL)
-+        return 0;
-+    if ((len == 3) && (strncmp(elem, "DIR", 3) == 0)) {
-+        *pmask |= B_ASN1_DIRECTORYSTRING;
-+        return 1;
-+    }
-+    tag = asn1_str2tag(elem, len);
-+    if (!tag || (tag & ASN1_GEN_FLAG))
-+        return 0;
-+    tmpmask = ASN1_tag2bit(tag);
-+    if (!tmpmask)
-+        return 0;
-+    *pmask |= tmpmask;
-+    return 1;
-+}
-+
-+int ASN1_str2mask(const char *str, unsigned long *pmask)
-+{
-+    *pmask = 0;
-+    return CONF_parse_list(str, '|', 1, mask_cb, pmask);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_lib.c
-new file mode 100644
-index 0000000..8ca53b4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_lib.c
-@@ -0,0 +1,384 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "asn1_locl.h"
-+
-+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
-+                           long max);
-+static void asn1_put_length(unsigned char **pp, int length);
-+
-+static int _asn1_check_infinite_end(const unsigned char **p, long len)
-+{
-+    /*
-+     * If there is 0 or 1 byte left, the length check should pick things up
-+     */
-+    if (len <= 0)
-+        return (1);
-+    else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
-+        (*p) += 2;
-+        return (1);
-+    }
-+    return (0);
-+}
-+
-+int ASN1_check_infinite_end(unsigned char **p, long len)
-+{
-+    return _asn1_check_infinite_end((const unsigned char **)p, len);
-+}
-+
-+int ASN1_const_check_infinite_end(const unsigned char **p, long len)
-+{
-+    return _asn1_check_infinite_end(p, len);
-+}
-+
-+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
-+                    int *pclass, long omax)
-+{
-+    int i, ret;
-+    long l;
-+    const unsigned char *p = *pp;
-+    int tag, xclass, inf;
-+    long max = omax;
-+
-+    if (!max)
-+        goto err;
-+    ret = (*p & V_ASN1_CONSTRUCTED);
-+    xclass = (*p & V_ASN1_PRIVATE);
-+    i = *p & V_ASN1_PRIMITIVE_TAG;
-+    if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
-+        p++;
-+        if (--max == 0)
-+            goto err;
-+        l = 0;
-+        while (*p & 0x80) {
-+            l <<= 7L;
-+            l |= *(p++) & 0x7f;
-+            if (--max == 0)
-+                goto err;
-+            if (l > (INT_MAX >> 7L))
-+                goto err;
-+        }
-+        l <<= 7L;
-+        l |= *(p++) & 0x7f;
-+        tag = (int)l;
-+        if (--max == 0)
-+            goto err;
-+    } else {
-+        tag = i;
-+        p++;
-+        if (--max == 0)
-+            goto err;
-+    }
-+    *ptag = tag;
-+    *pclass = xclass;
-+    if (!asn1_get_length(&p, &inf, plength, max))
-+        goto err;
-+
-+    if (inf && !(ret & V_ASN1_CONSTRUCTED))
-+        goto err;
-+
-+    if (*plength > (omax - (p - *pp))) {
-+        ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG);
-+        /*
-+         * Set this so that even if things are not long enough the values are
-+         * set correctly
-+         */
-+        ret |= 0x80;
-+    }
-+    *pp = p;
-+    return (ret | inf);
-+ err:
-+    ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG);
-+    return (0x80);
-+}
-+
-+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
-+                           long max)
-+{
-+    const unsigned char *p = *pp;
-+    unsigned long ret = 0;
-+    unsigned long i;
-+
-+    if (max-- < 1)
-+        return 0;
-+    if (*p == 0x80) {
-+        *inf = 1;
-+        ret = 0;
-+        p++;
-+    } else {
-+        *inf = 0;
-+        i = *p & 0x7f;
-+        if (*(p++) & 0x80) {
-+            if (max < (long)i + 1)
-+                return 0;
-+            /* Skip leading zeroes */
-+            while (i && *p == 0) {
-+                p++;
-+                i--;
-+            }
-+            if (i > sizeof(long))
-+                return 0;
-+            while (i-- > 0) {
-+                ret <<= 8L;
-+                ret |= *(p++);
-+            }
-+        } else
-+            ret = i;
-+    }
-+    if (ret > LONG_MAX)
-+        return 0;
-+    *pp = p;
-+    *rl = (long)ret;
-+    return 1;
-+}
-+
-+/*
-+ * class 0 is constructed constructed == 2 for indefinite length constructed
-+ */
-+void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
-+                     int xclass)
-+{
-+    unsigned char *p = *pp;
-+    int i, ttag;
-+
-+    i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
-+    i |= (xclass & V_ASN1_PRIVATE);
-+    if (tag < 31)
-+        *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
-+    else {
-+        *(p++) = i | V_ASN1_PRIMITIVE_TAG;
-+        for (i = 0, ttag = tag; ttag > 0; i++)
-+            ttag >>= 7;
-+        ttag = i;
-+        while (i-- > 0) {
-+            p[i] = tag & 0x7f;
-+            if (i != (ttag - 1))
-+                p[i] |= 0x80;
-+            tag >>= 7;
-+        }
-+        p += ttag;
-+    }
-+    if (constructed == 2)
-+        *(p++) = 0x80;
-+    else
-+        asn1_put_length(&p, length);
-+    *pp = p;
-+}
-+
-+int ASN1_put_eoc(unsigned char **pp)
-+{
-+    unsigned char *p = *pp;
-+    *p++ = 0;
-+    *p++ = 0;
-+    *pp = p;
-+    return 2;
-+}
-+
-+static void asn1_put_length(unsigned char **pp, int length)
-+{
-+    unsigned char *p = *pp;
-+    int i, l;
-+    if (length <= 127)
-+        *(p++) = (unsigned char)length;
-+    else {
-+        l = length;
-+        for (i = 0; l > 0; i++)
-+            l >>= 8;
-+        *(p++) = i | 0x80;
-+        l = i;
-+        while (i-- > 0) {
-+            p[i] = length & 0xff;
-+            length >>= 8;
-+        }
-+        p += l;
-+    }
-+    *pp = p;
-+}
-+
-+int ASN1_object_size(int constructed, int length, int tag)
-+{
-+    int ret = 1;
-+    if (length < 0)
-+        return -1;
-+    if (tag >= 31) {
-+        while (tag > 0) {
-+            tag >>= 7;
-+            ret++;
-+        }
-+    }
-+    if (constructed == 2) {
-+        ret += 3;
-+    } else {
-+        ret++;
-+        if (length > 127) {
-+            int tmplen = length;
-+            while (tmplen > 0) {
-+                tmplen >>= 8;
-+                ret++;
-+            }
-+        }
-+    }
-+    if (ret >= INT_MAX - length)
-+        return -1;
-+    return ret + length;
-+}
-+
-+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
-+{
-+    if (str == NULL)
-+        return 0;
-+    dst->type = str->type;
-+    if (!ASN1_STRING_set(dst, str->data, str->length))
-+        return 0;
-+    /* Copy flags but preserve embed value */
-+    dst->flags &= ASN1_STRING_FLAG_EMBED;
-+    dst->flags |= str->flags & ~ASN1_STRING_FLAG_EMBED;
-+    return 1;
-+}
-+
-+ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
-+{
-+    ASN1_STRING *ret;
-+    if (!str)
-+        return NULL;
-+    ret = ASN1_STRING_new();
-+    if (ret == NULL)
-+        return NULL;
-+    if (!ASN1_STRING_copy(ret, str)) {
-+        ASN1_STRING_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
-+{
-+    unsigned char *c;
-+    const char *data = _data;
-+
-+    if (len < 0) {
-+        if (data == NULL)
-+            return (0);
-+        else
-+            len = strlen(data);
-+    }
-+    if ((str->length <= len) || (str->data == NULL)) {
-+        c = str->data;
-+        str->data = OPENSSL_realloc(c, len + 1);
-+        if (str->data == NULL) {
-+            ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE);
-+            str->data = c;
-+            return (0);
-+        }
-+    }
-+    str->length = len;
-+    if (data != NULL) {
-+        memcpy(str->data, data, len);
-+        /* an allowance for strings :-) */
-+        str->data[len] = '\0';
-+    }
-+    return (1);
-+}
-+
-+void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
-+{
-+    OPENSSL_free(str->data);
-+    str->data = data;
-+    str->length = len;
-+}
-+
-+ASN1_STRING *ASN1_STRING_new(void)
-+{
-+    return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
-+}
-+
-+ASN1_STRING *ASN1_STRING_type_new(int type)
-+{
-+    ASN1_STRING *ret;
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL) {
-+        ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+    ret->type = type;
-+    return (ret);
-+}
-+
-+void asn1_string_embed_free(ASN1_STRING *a, int embed)
-+{
-+    if (a == NULL)
-+        return;
-+    if (!(a->flags & ASN1_STRING_FLAG_NDEF))
-+        OPENSSL_free(a->data);
-+    if (embed == 0)
-+        OPENSSL_free(a);
-+}
-+
-+void ASN1_STRING_free(ASN1_STRING *a)
-+{
-+    if (a == NULL)
-+        return;
-+    asn1_string_embed_free(a, a->flags & ASN1_STRING_FLAG_EMBED);
-+}
-+
-+void ASN1_STRING_clear_free(ASN1_STRING *a)
-+{
-+    if (a == NULL)
-+        return;
-+    if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
-+        OPENSSL_cleanse(a->data, a->length);
-+    ASN1_STRING_free(a);
-+}
-+
-+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
-+{
-+    int i;
-+
-+    i = (a->length - b->length);
-+    if (i == 0) {
-+        i = memcmp(a->data, b->data, a->length);
-+        if (i == 0)
-+            return (a->type - b->type);
-+        else
-+            return (i);
-+    } else
-+        return (i);
-+}
-+
-+int ASN1_STRING_length(const ASN1_STRING *x)
-+{
-+    return x->length;
-+}
-+
-+void ASN1_STRING_length_set(ASN1_STRING *x, int len)
-+{
-+    x->length = len;
-+}
-+
-+int ASN1_STRING_type(const ASN1_STRING *x)
-+{
-+    return x->type;
-+}
-+
-+const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
-+{
-+    return x->data;
-+}
-+
-+# if OPENSSL_API_COMPAT < 0x10100000L
-+unsigned char *ASN1_STRING_data(ASN1_STRING *x)
-+{
-+    return x->data;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_locl.h
-new file mode 100644
-index 0000000..5f597bd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_locl.h
-@@ -0,0 +1,78 @@
-+/*
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Internal ASN1 structures and functions: not for application use */
-+
-+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
-+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
-+
-+/* ASN1 scan context structure */
-+
-+struct asn1_sctx_st {
-+    /* The ASN1_ITEM associated with this field */
-+    const ASN1_ITEM *it;
-+    /* If ASN1_TEMPLATE associated with this field */
-+    const ASN1_TEMPLATE *tt;
-+    /* Various flags associated with field and context */
-+    unsigned long flags;
-+    /* If SEQUENCE OF or SET OF, field index */
-+    int skidx;
-+    /* ASN1 depth of field */
-+    int depth;
-+    /* Structure and field name */
-+    const char *sname, *fname;
-+    /* If a primitive type the type of underlying field */
-+    int prim_type;
-+    /* The field value itself */
-+    ASN1_VALUE **field;
-+    /* Callback to pass information to */
-+    int (*scan_cb) (ASN1_SCTX *ctx);
-+    /* Context specific application data */
-+    void *app_data;
-+} /* ASN1_SCTX */ ;
-+
-+typedef struct mime_param_st MIME_PARAM;
-+DEFINE_STACK_OF(MIME_PARAM)
-+typedef struct mime_header_st MIME_HEADER;
-+DEFINE_STACK_OF(MIME_HEADER)
-+
-+/* Month values for printing out times */
-+extern const char *_asn1_mon[12];
-+
-+void asn1_string_embed_free(ASN1_STRING *a, int embed);
-+
-+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
-+int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
-+                             const ASN1_ITEM *it);
-+
-+ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
-+
-+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
-+                                 int nullerr);
-+
-+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
-+
-+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
-+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
-+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
-+                     const ASN1_ITEM *it);
-+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
-+                  const ASN1_ITEM *it);
-+
-+void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed);
-+void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
-+
-+ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
-+                             long length);
-+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp);
-+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
-+                                     const unsigned char **pp, long length);
-+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp);
-+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
-+                               long length);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_par.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_par.c
-new file mode 100644
-index 0000000..4db3df9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn1_par.c
-@@ -0,0 +1,375 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+#ifndef ASN1_PARSE_MAXDEPTH
-+#define ASN1_PARSE_MAXDEPTH 128
-+#endif
-+
-+static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
-+                           int indent);
-+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
-+                       int offset, int depth, int indent, int dump);
-+static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
-+                           int indent)
-+{
-+    static const char fmt[] = "%-18s";
-+    char str[128];
-+    const char *p;
-+
-+    if (constructed & V_ASN1_CONSTRUCTED)
-+        p = "cons: ";
-+    else
-+        p = "prim: ";
-+    if (BIO_write(bp, p, 6) < 6)
-+        goto err;
-+    BIO_indent(bp, indent, 128);
-+
-+    p = str;
-+    if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
-+        BIO_snprintf(str, sizeof str, "priv [ %d ] ", tag);
-+    else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
-+        BIO_snprintf(str, sizeof str, "cont [ %d ]", tag);
-+    else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
-+        BIO_snprintf(str, sizeof str, "appl [ %d ]", tag);
-+    else if (tag > 30)
-+        BIO_snprintf(str, sizeof str, "", tag);
-+    else
-+        p = ASN1_tag2str(tag);
-+
-+    if (BIO_printf(bp, fmt, p) <= 0)
-+        goto err;
-+    return (1);
-+ err:
-+    return (0);
-+}
-+
-+int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
-+{
-+    return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0));
-+}
-+
-+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
-+                    int dump)
-+{
-+    return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump));
-+}
-+
-+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
-+                       int offset, int depth, int indent, int dump)
-+{
-+    const unsigned char *p, *ep, *tot, *op, *opp;
-+    long len;
-+    int tag, xclass, ret = 0;
-+    int nl, hl, j, r;
-+    ASN1_OBJECT *o = NULL;
-+    ASN1_OCTET_STRING *os = NULL;
-+    /* ASN1_BMPSTRING *bmp=NULL; */
-+    int dump_indent, dump_cont = 0;
-+
-+    if (depth > ASN1_PARSE_MAXDEPTH) {
-+            BIO_puts(bp, "BAD RECURSION DEPTH\n");
-+            return 0;
-+    }
-+
-+    dump_indent = 6;            /* Because we know BIO_dump_indent() */
-+    p = *pp;
-+    tot = p + length;
-+    while (length > 0) {
-+        op = p;
-+        j = ASN1_get_object(&p, &len, &tag, &xclass, length);
-+        if (j & 0x80) {
-+            if (BIO_write(bp, "Error in encoding\n", 18) <= 0)
-+                goto end;
-+            ret = 0;
-+            goto end;
-+        }
-+        hl = (p - op);
-+        length -= hl;
-+        /*
-+         * if j == 0x21 it is a constructed indefinite length object
-+         */
-+        if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp))
-+            <= 0)
-+            goto end;
-+
-+        if (j != (V_ASN1_CONSTRUCTED | 1)) {
-+            if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
-+                           depth, (long)hl, len) <= 0)
-+                goto end;
-+        } else {
-+            if (BIO_printf(bp, "d=%-2d hl=%ld l=inf  ", depth, (long)hl) <= 0)
-+                goto end;
-+        }
-+        if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
-+            goto end;
-+        if (j & V_ASN1_CONSTRUCTED) {
-+            const unsigned char *sp = p;
-+
-+            ep = p + len;
-+            if (BIO_write(bp, "\n", 1) <= 0)
-+                goto end;
-+            if (len > length) {
-+                BIO_printf(bp, "length is greater than %ld\n", length);
-+                ret = 0;
-+                goto end;
-+            }
-+            if ((j == 0x21) && (len == 0)) {
-+                for (;;) {
-+                    r = asn1_parse2(bp, &p, (long)(tot - p),
-+                                    offset + (p - *pp), depth + 1,
-+                                    indent, dump);
-+                    if (r == 0) {
-+                        ret = 0;
-+                        goto end;
-+                    }
-+                    if ((r == 2) || (p >= tot)) {
-+                        len = p - sp;
-+                        break;
-+                    }
-+                }
-+            } else {
-+                long tmp = len;
-+
-+                while (p < ep) {
-+                    sp = p;
-+                    r = asn1_parse2(bp, &p, tmp,
-+                                    offset + (p - *pp), depth + 1,
-+                                    indent, dump);
-+                    if (r == 0) {
-+                        ret = 0;
-+                        goto end;
-+                    }
-+                    tmp -= p - sp;
-+                }
-+            }
-+        } else if (xclass != 0) {
-+            p += len;
-+            if (BIO_write(bp, "\n", 1) <= 0)
-+                goto end;
-+        } else {
-+            nl = 0;
-+            if ((tag == V_ASN1_PRINTABLESTRING) ||
-+                (tag == V_ASN1_T61STRING) ||
-+                (tag == V_ASN1_IA5STRING) ||
-+                (tag == V_ASN1_VISIBLESTRING) ||
-+                (tag == V_ASN1_NUMERICSTRING) ||
-+                (tag == V_ASN1_UTF8STRING) ||
-+                (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) {
-+                if (BIO_write(bp, ":", 1) <= 0)
-+                    goto end;
-+                if ((len > 0) && BIO_write(bp, (const char *)p, (int)len)
-+                    != (int)len)
-+                    goto end;
-+            } else if (tag == V_ASN1_OBJECT) {
-+                opp = op;
-+                if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) {
-+                    if (BIO_write(bp, ":", 1) <= 0)
-+                        goto end;
-+                    i2a_ASN1_OBJECT(bp, o);
-+                } else {
-+                    if (BIO_puts(bp, ":BAD OBJECT") <= 0)
-+                        goto end;
-+                    dump_cont = 1;
-+                }
-+            } else if (tag == V_ASN1_BOOLEAN) {
-+                if (len != 1) {
-+                    if (BIO_puts(bp, ":BAD BOOLEAN") <= 0)
-+                        goto end;
-+                    dump_cont = 1;
-+                }
-+                if (len > 0)
-+                    BIO_printf(bp, ":%u", p[0]);
-+            } else if (tag == V_ASN1_BMPSTRING) {
-+                /* do the BMP thang */
-+            } else if (tag == V_ASN1_OCTET_STRING) {
-+                int i, printable = 1;
-+
-+                opp = op;
-+                os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
-+                if (os != NULL && os->length > 0) {
-+                    opp = os->data;
-+                    /*
-+                     * testing whether the octet string is printable
-+                     */
-+                    for (i = 0; i < os->length; i++) {
-+                        if (((opp[i] < ' ') &&
-+                             (opp[i] != '\n') &&
-+                             (opp[i] != '\r') &&
-+                             (opp[i] != '\t')) || (opp[i] > '~')) {
-+                            printable = 0;
-+                            break;
-+                        }
-+                    }
-+                    if (printable)
-+                        /* printable string */
-+                    {
-+                        if (BIO_write(bp, ":", 1) <= 0)
-+                            goto end;
-+                        if (BIO_write(bp, (const char *)opp, os->length) <= 0)
-+                            goto end;
-+                    } else if (!dump)
-+                        /*
-+                         * not printable => print octet string as hex dump
-+                         */
-+                    {
-+                        if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0)
-+                            goto end;
-+                        for (i = 0; i < os->length; i++) {
-+                            if (BIO_printf(bp, "%02X", opp[i]) <= 0)
-+                                goto end;
-+                        }
-+                    } else
-+                        /* print the normal dump */
-+                    {
-+                        if (!nl) {
-+                            if (BIO_write(bp, "\n", 1) <= 0)
-+                                goto end;
-+                        }
-+                        if (BIO_dump_indent(bp,
-+                                            (const char *)opp,
-+                                            ((dump == -1 || dump >
-+                                              os->
-+                                              length) ? os->length : dump),
-+                                            dump_indent) <= 0)
-+                            goto end;
-+                        nl = 1;
-+                    }
-+                }
-+                ASN1_OCTET_STRING_free(os);
-+                os = NULL;
-+            } else if (tag == V_ASN1_INTEGER) {
-+                ASN1_INTEGER *bs;
-+                int i;
-+
-+                opp = op;
-+                bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
-+                if (bs != NULL) {
-+                    if (BIO_write(bp, ":", 1) <= 0)
-+                        goto end;
-+                    if (bs->type == V_ASN1_NEG_INTEGER)
-+                        if (BIO_write(bp, "-", 1) <= 0)
-+                            goto end;
-+                    for (i = 0; i < bs->length; i++) {
-+                        if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
-+                            goto end;
-+                    }
-+                    if (bs->length == 0) {
-+                        if (BIO_write(bp, "00", 2) <= 0)
-+                            goto end;
-+                    }
-+                } else {
-+                    if (BIO_puts(bp, ":BAD INTEGER") <= 0)
-+                        goto end;
-+                    dump_cont = 1;
-+                }
-+                ASN1_INTEGER_free(bs);
-+            } else if (tag == V_ASN1_ENUMERATED) {
-+                ASN1_ENUMERATED *bs;
-+                int i;
-+
-+                opp = op;
-+                bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
-+                if (bs != NULL) {
-+                    if (BIO_write(bp, ":", 1) <= 0)
-+                        goto end;
-+                    if (bs->type == V_ASN1_NEG_ENUMERATED)
-+                        if (BIO_write(bp, "-", 1) <= 0)
-+                            goto end;
-+                    for (i = 0; i < bs->length; i++) {
-+                        if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
-+                            goto end;
-+                    }
-+                    if (bs->length == 0) {
-+                        if (BIO_write(bp, "00", 2) <= 0)
-+                            goto end;
-+                    }
-+                } else {
-+                    if (BIO_puts(bp, ":BAD ENUMERATED") <= 0)
-+                        goto end;
-+                    dump_cont = 1;
-+                }
-+                ASN1_ENUMERATED_free(bs);
-+            } else if (len > 0 && dump) {
-+                if (!nl) {
-+                    if (BIO_write(bp, "\n", 1) <= 0)
-+                        goto end;
-+                }
-+                if (BIO_dump_indent(bp, (const char *)p,
-+                                    ((dump == -1 || dump > len) ? len : dump),
-+                                    dump_indent) <= 0)
-+                    goto end;
-+                nl = 1;
-+            }
-+            if (dump_cont) {
-+                int i;
-+                const unsigned char *tmp = op + hl;
-+                if (BIO_puts(bp, ":[") <= 0)
-+                    goto end;
-+                for (i = 0; i < len; i++) {
-+                    if (BIO_printf(bp, "%02X", tmp[i]) <= 0)
-+                        goto end;
-+                }
-+                if (BIO_puts(bp, "]") <= 0)
-+                    goto end;
-+            }
-+
-+            if (!nl) {
-+                if (BIO_write(bp, "\n", 1) <= 0)
-+                    goto end;
-+            }
-+            p += len;
-+            if ((tag == V_ASN1_EOC) && (xclass == 0)) {
-+                ret = 2;        /* End of sequence */
-+                goto end;
-+            }
-+        }
-+        length -= len;
-+    }
-+    ret = 1;
-+ end:
-+    ASN1_OBJECT_free(o);
-+    ASN1_OCTET_STRING_free(os);
-+    *pp = p;
-+    return (ret);
-+}
-+
-+const char *ASN1_tag2str(int tag)
-+{
-+    static const char *const tag2str[] = {
-+        /* 0-4 */
-+        "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
-+        /* 5-9 */
-+        "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL",
-+        /* 10-13 */
-+        "ENUMERATED", "", "UTF8STRING", "",
-+        /* 15-17 */
-+        "", "", "SEQUENCE", "SET",
-+        /* 18-20 */
-+        "NUMERICSTRING", "PRINTABLESTRING", "T61STRING",
-+        /* 21-24 */
-+        "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME",
-+        /* 25-27 */
-+        "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",
-+        /* 28-30 */
-+        "UNIVERSALSTRING", "", "BMPSTRING"
-+    };
-+
-+    if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
-+        tag &= ~0x100;
-+
-+    if (tag < 0 || tag > 30)
-+        return "(unknown)";
-+    return tag2str[tag];
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_mime.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_mime.c
-new file mode 100644
-index 0000000..d7ec801
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_mime.c
-@@ -0,0 +1,980 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+#include "internal/bio.h"
-+#include "asn1_locl.h"
-+
-+/*
-+ * Generalised MIME like utilities for streaming ASN1. Although many have a
-+ * PKCS7/CMS like flavour others are more general purpose.
-+ */
-+
-+/*
-+ * MIME format structures Note that all are translated to lower case apart
-+ * from parameter values. Quotes are stripped off
-+ */
-+
-+struct mime_param_st {
-+    char *param_name;           /* Param name e.g. "micalg" */
-+    char *param_value;          /* Param value e.g. "sha1" */
-+};
-+
-+struct mime_header_st {
-+    char *name;                 /* Name of line e.g. "content-type" */
-+    char *value;                /* Value of line e.g. "text/plain" */
-+    STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
-+};
-+
-+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
-+                            const ASN1_ITEM *it);
-+static char *strip_ends(char *name);
-+static char *strip_start(char *name);
-+static char *strip_end(char *name);
-+static MIME_HEADER *mime_hdr_new(const char *name, const char *value);
-+static int mime_hdr_addparam(MIME_HEADER *mhdr, const char *name, const char *value);
-+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
-+static int mime_hdr_cmp(const MIME_HEADER *const *a,
-+                        const MIME_HEADER *const *b);
-+static int mime_param_cmp(const MIME_PARAM *const *a,
-+                          const MIME_PARAM *const *b);
-+static void mime_param_free(MIME_PARAM *param);
-+static int mime_bound_check(char *line, int linelen, const char *bound, int blen);
-+static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret);
-+static int strip_eol(char *linebuf, int *plen, int flags);
-+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, const char *name);
-+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, const char *name);
-+static void mime_hdr_free(MIME_HEADER *hdr);
-+
-+#define MAX_SMLEN 1024
-+#define mime_debug(x)           /* x */
-+
-+/* Output an ASN1 structure in BER format streaming if necessary */
-+
-+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
-+                        const ASN1_ITEM *it)
-+{
-+    /* If streaming create stream BIO and copy all content through it */
-+    if (flags & SMIME_STREAM) {
-+        BIO *bio, *tbio;
-+        bio = BIO_new_NDEF(out, val, it);
-+        if (!bio) {
-+            ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        SMIME_crlf_copy(in, bio, flags);
-+        (void)BIO_flush(bio);
-+        /* Free up successive BIOs until we hit the old output BIO */
-+        do {
-+            tbio = BIO_pop(bio);
-+            BIO_free(bio);
-+            bio = tbio;
-+        } while (bio != out);
-+    }
-+    /*
-+     * else just write out ASN1 structure which will have all content stored
-+     * internally
-+     */
-+    else
-+        ASN1_item_i2d_bio(it, out, val);
-+    return 1;
-+}
-+
-+/* Base 64 read and write of ASN1 structure */
-+
-+static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
-+                          const ASN1_ITEM *it)
-+{
-+    BIO *b64;
-+    int r;
-+    b64 = BIO_new(BIO_f_base64());
-+    if (b64 == NULL) {
-+        ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    /*
-+     * prepend the b64 BIO so all data is base64 encoded.
-+     */
-+    out = BIO_push(b64, out);
-+    r = i2d_ASN1_bio_stream(out, val, in, flags, it);
-+    (void)BIO_flush(out);
-+    BIO_pop(out);
-+    BIO_free(b64);
-+    return r;
-+}
-+
-+/* Streaming ASN1 PEM write */
-+
-+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
-+                              const char *hdr, const ASN1_ITEM *it)
-+{
-+    int r;
-+    BIO_printf(out, "-----BEGIN %s-----\n", hdr);
-+    r = B64_write_ASN1(out, val, in, flags, it);
-+    BIO_printf(out, "-----END %s-----\n", hdr);
-+    return r;
-+}
-+
-+static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
-+{
-+    BIO *b64;
-+    ASN1_VALUE *val;
-+
-+    if ((b64 = BIO_new(BIO_f_base64())) == NULL) {
-+        ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    bio = BIO_push(b64, bio);
-+    val = ASN1_item_d2i_bio(it, bio, NULL);
-+    if (!val)
-+        ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR);
-+    (void)BIO_flush(bio);
-+    BIO_pop(bio);
-+    BIO_free(b64);
-+    return val;
-+}
-+
-+/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
-+
-+static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
-+{
-+    const EVP_MD *md;
-+    int i, have_unknown = 0, write_comma, ret = 0, md_nid;
-+    have_unknown = 0;
-+    write_comma = 0;
-+    for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) {
-+        if (write_comma)
-+            BIO_write(out, ",", 1);
-+        write_comma = 1;
-+        md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
-+        md = EVP_get_digestbynid(md_nid);
-+        if (md && md->md_ctrl) {
-+            int rv;
-+            char *micstr;
-+            rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
-+            if (rv > 0) {
-+                BIO_puts(out, micstr);
-+                OPENSSL_free(micstr);
-+                continue;
-+            }
-+            if (rv != -2)
-+                goto err;
-+        }
-+        switch (md_nid) {
-+        case NID_sha1:
-+            BIO_puts(out, "sha1");
-+            break;
-+
-+        case NID_md5:
-+            BIO_puts(out, "md5");
-+            break;
-+
-+        case NID_sha256:
-+            BIO_puts(out, "sha-256");
-+            break;
-+
-+        case NID_sha384:
-+            BIO_puts(out, "sha-384");
-+            break;
-+
-+        case NID_sha512:
-+            BIO_puts(out, "sha-512");
-+            break;
-+
-+        case NID_id_GostR3411_94:
-+            BIO_puts(out, "gostr3411-94");
-+            goto err;
-+
-+        default:
-+            if (have_unknown)
-+                write_comma = 0;
-+            else {
-+                BIO_puts(out, "unknown");
-+                have_unknown = 1;
-+            }
-+            break;
-+
-+        }
-+    }
-+
-+    ret = 1;
-+ err:
-+
-+    return ret;
-+
-+}
-+
-+/* SMIME sender */
-+
-+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
-+                     int ctype_nid, int econt_nid,
-+                     STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it)
-+{
-+    char bound[33], c;
-+    int i;
-+    const char *mime_prefix, *mime_eol, *cname = "smime.p7m";
-+    const char *msg_type = NULL;
-+    if (flags & SMIME_OLDMIME)
-+        mime_prefix = "application/x-pkcs7-";
-+    else
-+        mime_prefix = "application/pkcs7-";
-+
-+    if (flags & SMIME_CRLFEOL)
-+        mime_eol = "\r\n";
-+    else
-+        mime_eol = "\n";
-+    if ((flags & SMIME_DETACHED) && data) {
-+        /* We want multipart/signed */
-+        /* Generate a random boundary */
-+        if (RAND_bytes((unsigned char *)bound, 32) <= 0)
-+            return 0;
-+        for (i = 0; i < 32; i++) {
-+            c = bound[i] & 0xf;
-+            if (c < 10)
-+                c += '0';
-+            else
-+                c += 'A' - 10;
-+            bound[i] = c;
-+        }
-+        bound[32] = 0;
-+        BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
-+        BIO_printf(bio, "Content-Type: multipart/signed;");
-+        BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
-+        BIO_puts(bio, " micalg=\"");
-+        asn1_write_micalg(bio, mdalgs);
-+        BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",
-+                   bound, mime_eol, mime_eol);
-+        BIO_printf(bio, "This is an S/MIME signed message%s%s",
-+                   mime_eol, mime_eol);
-+        /* Now write out the first part */
-+        BIO_printf(bio, "------%s%s", bound, mime_eol);
-+        if (!asn1_output_data(bio, data, val, flags, it))
-+            return 0;
-+        BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
-+
-+        /* Headers for signature */
-+
-+        BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
-+        BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
-+        BIO_printf(bio, "Content-Transfer-Encoding: base64%s", mime_eol);
-+        BIO_printf(bio, "Content-Disposition: attachment;");
-+        BIO_printf(bio, " filename=\"smime.p7s\"%s%s", mime_eol, mime_eol);
-+        B64_write_ASN1(bio, val, NULL, 0, it);
-+        BIO_printf(bio, "%s------%s--%s%s", mime_eol, bound,
-+                   mime_eol, mime_eol);
-+        return 1;
-+    }
-+
-+    /* Determine smime-type header */
-+
-+    if (ctype_nid == NID_pkcs7_enveloped)
-+        msg_type = "enveloped-data";
-+    else if (ctype_nid == NID_pkcs7_signed) {
-+        if (econt_nid == NID_id_smime_ct_receipt)
-+            msg_type = "signed-receipt";
-+        else if (sk_X509_ALGOR_num(mdalgs) >= 0)
-+            msg_type = "signed-data";
-+        else
-+            msg_type = "certs-only";
-+    } else if (ctype_nid == NID_id_smime_ct_compressedData) {
-+        msg_type = "compressed-data";
-+        cname = "smime.p7z";
-+    }
-+    /* MIME headers */
-+    BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
-+    BIO_printf(bio, "Content-Disposition: attachment;");
-+    BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol);
-+    BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
-+    if (msg_type)
-+        BIO_printf(bio, " smime-type=%s;", msg_type);
-+    BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol);
-+    BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
-+               mime_eol, mime_eol);
-+    if (!B64_write_ASN1(bio, val, data, flags, it))
-+        return 0;
-+    BIO_printf(bio, "%s", mime_eol);
-+    return 1;
-+}
-+
-+/* Handle output of ASN1 data */
-+
-+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
-+                            const ASN1_ITEM *it)
-+{
-+    BIO *tmpbio;
-+    const ASN1_AUX *aux = it->funcs;
-+    ASN1_STREAM_ARG sarg;
-+    int rv = 1;
-+
-+    /*
-+     * If data is not detached or resigning then the output BIO is already
-+     * set up to finalise when it is written through.
-+     */
-+    if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) {
-+        SMIME_crlf_copy(data, out, flags);
-+        return 1;
-+    }
-+
-+    if (!aux || !aux->asn1_cb) {
-+        ASN1err(ASN1_F_ASN1_OUTPUT_DATA, ASN1_R_STREAMING_NOT_SUPPORTED);
-+        return 0;
-+    }
-+
-+    sarg.out = out;
-+    sarg.ndef_bio = NULL;
-+    sarg.boundary = NULL;
-+
-+    /* Let ASN1 code prepend any needed BIOs */
-+
-+    if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0)
-+        return 0;
-+
-+    /* Copy data across, passing through filter BIOs for processing */
-+    SMIME_crlf_copy(data, sarg.ndef_bio, flags);
-+
-+    /* Finalize structure */
-+    if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
-+        rv = 0;
-+
-+    /* Now remove any digests prepended to the BIO */
-+
-+    while (sarg.ndef_bio != out) {
-+        tmpbio = BIO_pop(sarg.ndef_bio);
-+        BIO_free(sarg.ndef_bio);
-+        sarg.ndef_bio = tmpbio;
-+    }
-+
-+    return rv;
-+
-+}
-+
-+/*
-+ * SMIME reader: handle multipart/signed and opaque signing. in multipart
-+ * case the content is placed in a memory BIO pointed to by "bcont". In
-+ * opaque this is set to NULL
-+ */
-+
-+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
-+{
-+    BIO *asnin;
-+    STACK_OF(MIME_HEADER) *headers = NULL;
-+    STACK_OF(BIO) *parts = NULL;
-+    MIME_HEADER *hdr;
-+    MIME_PARAM *prm;
-+    ASN1_VALUE *val;
-+    int ret;
-+
-+    if (bcont)
-+        *bcont = NULL;
-+
-+    if ((headers = mime_parse_hdr(bio)) == NULL) {
-+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR);
-+        return NULL;
-+    }
-+
-+    if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
-+        || hdr->value == NULL) {
-+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
-+        return NULL;
-+    }
-+
-+    /* Handle multipart/signed */
-+
-+    if (strcmp(hdr->value, "multipart/signed") == 0) {
-+        /* Split into two parts */
-+        prm = mime_param_find(hdr, "boundary");
-+        if (!prm || !prm->param_value) {
-+            sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
-+            return NULL;
-+        }
-+        ret = multi_split(bio, prm->param_value, &parts);
-+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+        if (!ret || (sk_BIO_num(parts) != 2)) {
-+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
-+            sk_BIO_pop_free(parts, BIO_vfree);
-+            return NULL;
-+        }
-+
-+        /* Parse the signature piece */
-+        asnin = sk_BIO_value(parts, 1);
-+
-+        if ((headers = mime_parse_hdr(asnin)) == NULL) {
-+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR);
-+            sk_BIO_pop_free(parts, BIO_vfree);
-+            return NULL;
-+        }
-+
-+        /* Get content type */
-+
-+        if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
-+            || hdr->value == NULL) {
-+            sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
-+            return NULL;
-+        }
-+
-+        if (strcmp(hdr->value, "application/x-pkcs7-signature") &&
-+            strcmp(hdr->value, "application/pkcs7-signature")) {
-+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE);
-+            ERR_add_error_data(2, "type: ", hdr->value);
-+            sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+            sk_BIO_pop_free(parts, BIO_vfree);
-+            return NULL;
-+        }
-+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+        /* Read in ASN1 */
-+        if ((val = b64_read_asn1(asnin, it)) == NULL) {
-+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR);
-+            sk_BIO_pop_free(parts, BIO_vfree);
-+            return NULL;
-+        }
-+
-+        if (bcont) {
-+            *bcont = sk_BIO_value(parts, 0);
-+            BIO_free(asnin);
-+            sk_BIO_free(parts);
-+        } else
-+            sk_BIO_pop_free(parts, BIO_vfree);
-+        return val;
-+    }
-+
-+    /* OK, if not multipart/signed try opaque signature */
-+
-+    if (strcmp(hdr->value, "application/x-pkcs7-mime") &&
-+        strcmp(hdr->value, "application/pkcs7-mime")) {
-+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE);
-+        ERR_add_error_data(2, "type: ", hdr->value);
-+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+        return NULL;
-+    }
-+
-+    sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+
-+    if ((val = b64_read_asn1(bio, it)) == NULL) {
-+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
-+        return NULL;
-+    }
-+    return val;
-+
-+}
-+
-+/* Copy text from one BIO to another making the output CRLF at EOL */
-+int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
-+{
-+    BIO *bf;
-+    char eol;
-+    int len;
-+    char linebuf[MAX_SMLEN];
-+    /*
-+     * Buffer output so we don't write one line at a time. This is useful
-+     * when streaming as we don't end up with one OCTET STRING per line.
-+     */
-+    bf = BIO_new(BIO_f_buffer());
-+    if (bf == NULL)
-+        return 0;
-+    out = BIO_push(bf, out);
-+    if (flags & SMIME_BINARY) {
-+        while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
-+            BIO_write(out, linebuf, len);
-+    } else {
-+        int eolcnt = 0;
-+        if (flags & SMIME_TEXT)
-+            BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
-+        while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
-+            eol = strip_eol(linebuf, &len, flags);
-+            if (len) {
-+                /* Not EOF: write out all CRLF */
-+                if (flags & SMIME_ASCIICRLF) {
-+                    int i;
-+                    for (i = 0; i < eolcnt; i++)
-+                        BIO_write(out, "\r\n", 2);
-+                    eolcnt = 0;
-+                }
-+                BIO_write(out, linebuf, len);
-+                if (eol)
-+                    BIO_write(out, "\r\n", 2);
-+            } else if (flags & SMIME_ASCIICRLF)
-+                eolcnt++;
-+            else if (eol)
-+                BIO_write(out, "\r\n", 2);
-+        }
-+    }
-+    (void)BIO_flush(out);
-+    BIO_pop(out);
-+    BIO_free(bf);
-+    return 1;
-+}
-+
-+/* Strip off headers if they are text/plain */
-+int SMIME_text(BIO *in, BIO *out)
-+{
-+    char iobuf[4096];
-+    int len;
-+    STACK_OF(MIME_HEADER) *headers;
-+    MIME_HEADER *hdr;
-+
-+    if ((headers = mime_parse_hdr(in)) == NULL) {
-+        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
-+        return 0;
-+    }
-+    if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
-+        || hdr->value == NULL) {
-+        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE);
-+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+        return 0;
-+    }
-+    if (strcmp(hdr->value, "text/plain")) {
-+        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE);
-+        ERR_add_error_data(2, "type: ", hdr->value);
-+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+        return 0;
-+    }
-+    sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+    while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
-+        BIO_write(out, iobuf, len);
-+    if (len < 0)
-+        return 0;
-+    return 1;
-+}
-+
-+/*
-+ * Split a multipart/XXX message body into component parts: result is
-+ * canonical parts in a STACK of bios
-+ */
-+
-+static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret)
-+{
-+    char linebuf[MAX_SMLEN];
-+    int len, blen;
-+    int eol = 0, next_eol = 0;
-+    BIO *bpart = NULL;
-+    STACK_OF(BIO) *parts;
-+    char state, part, first;
-+
-+    blen = strlen(bound);
-+    part = 0;
-+    state = 0;
-+    first = 1;
-+    parts = sk_BIO_new_null();
-+    *ret = parts;
-+    if (*ret == NULL)
-+        return 0;
-+    while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
-+        state = mime_bound_check(linebuf, len, bound, blen);
-+        if (state == 1) {
-+            first = 1;
-+            part++;
-+        } else if (state == 2) {
-+            if (!sk_BIO_push(parts, bpart)) {
-+                BIO_free(bpart);
-+                return 0;
-+            }
-+            return 1;
-+        } else if (part) {
-+            /* Strip CR+LF from linebuf */
-+            next_eol = strip_eol(linebuf, &len, 0);
-+            if (first) {
-+                first = 0;
-+                if (bpart)
-+                    if (!sk_BIO_push(parts, bpart)) {
-+                        BIO_free(bpart);
-+                        return 0;
-+                    }
-+                bpart = BIO_new(BIO_s_mem());
-+                if (bpart == NULL)
-+                    return 0;
-+                BIO_set_mem_eof_return(bpart, 0);
-+            } else if (eol)
-+                BIO_write(bpart, "\r\n", 2);
-+            eol = next_eol;
-+            if (len)
-+                BIO_write(bpart, linebuf, len);
-+        }
-+    }
-+    BIO_free(bpart);
-+    return 0;
-+}
-+
-+/* This is the big one: parse MIME header lines up to message body */
-+
-+#define MIME_INVALID    0
-+#define MIME_START      1
-+#define MIME_TYPE       2
-+#define MIME_NAME       3
-+#define MIME_VALUE      4
-+#define MIME_QUOTE      5
-+#define MIME_COMMENT    6
-+
-+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
-+{
-+    char *p, *q, c;
-+    char *ntmp;
-+    char linebuf[MAX_SMLEN];
-+    MIME_HEADER *mhdr = NULL, *new_hdr = NULL;
-+    STACK_OF(MIME_HEADER) *headers;
-+    int len, state, save_state = 0;
-+
-+    headers = sk_MIME_HEADER_new(mime_hdr_cmp);
-+    if (headers == NULL)
-+        return NULL;
-+    while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
-+        /* If whitespace at line start then continuation line */
-+        if (mhdr && isspace((unsigned char)linebuf[0]))
-+            state = MIME_NAME;
-+        else
-+            state = MIME_START;
-+        ntmp = NULL;
-+        /* Go through all characters */
-+        for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
-+             p++) {
-+
-+            /*
-+             * State machine to handle MIME headers if this looks horrible
-+             * that's because it *is*
-+             */
-+
-+            switch (state) {
-+            case MIME_START:
-+                if (c == ':') {
-+                    state = MIME_TYPE;
-+                    *p = 0;
-+                    ntmp = strip_ends(q);
-+                    q = p + 1;
-+                }
-+                break;
-+
-+            case MIME_TYPE:
-+                if (c == ';') {
-+                    mime_debug("Found End Value\n");
-+                    *p = 0;
-+                    new_hdr = mime_hdr_new(ntmp, strip_ends(q));
-+                    if (new_hdr == NULL)
-+                        goto err;
-+                    if (!sk_MIME_HEADER_push(headers, new_hdr))
-+                        goto err;
-+                    mhdr = new_hdr;
-+                    new_hdr = NULL;
-+                    ntmp = NULL;
-+                    q = p + 1;
-+                    state = MIME_NAME;
-+                } else if (c == '(') {
-+                    save_state = state;
-+                    state = MIME_COMMENT;
-+                }
-+                break;
-+
-+            case MIME_COMMENT:
-+                if (c == ')') {
-+                    state = save_state;
-+                }
-+                break;
-+
-+            case MIME_NAME:
-+                if (c == '=') {
-+                    state = MIME_VALUE;
-+                    *p = 0;
-+                    ntmp = strip_ends(q);
-+                    q = p + 1;
-+                }
-+                break;
-+
-+            case MIME_VALUE:
-+                if (c == ';') {
-+                    state = MIME_NAME;
-+                    *p = 0;
-+                    mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
-+                    ntmp = NULL;
-+                    q = p + 1;
-+                } else if (c == '"') {
-+                    mime_debug("Found Quote\n");
-+                    state = MIME_QUOTE;
-+                } else if (c == '(') {
-+                    save_state = state;
-+                    state = MIME_COMMENT;
-+                }
-+                break;
-+
-+            case MIME_QUOTE:
-+                if (c == '"') {
-+                    mime_debug("Found Match Quote\n");
-+                    state = MIME_VALUE;
-+                }
-+                break;
-+            }
-+        }
-+
-+        if (state == MIME_TYPE) {
-+            new_hdr = mime_hdr_new(ntmp, strip_ends(q));
-+            if (new_hdr == NULL)
-+                goto err;
-+            if (!sk_MIME_HEADER_push(headers, new_hdr))
-+                goto err;
-+            mhdr = new_hdr;
-+            new_hdr = NULL;
-+        } else if (state == MIME_VALUE)
-+            mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
-+        if (p == linebuf)
-+            break;              /* Blank line means end of headers */
-+    }
-+
-+    return headers;
-+
-+err:
-+    mime_hdr_free(new_hdr);
-+    sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-+    return NULL;
-+}
-+
-+static char *strip_ends(char *name)
-+{
-+    return strip_end(strip_start(name));
-+}
-+
-+/* Strip a parameter of whitespace from start of param */
-+static char *strip_start(char *name)
-+{
-+    char *p, c;
-+    /* Look for first non white space or quote */
-+    for (p = name; (c = *p); p++) {
-+        if (c == '"') {
-+            /* Next char is start of string if non null */
-+            if (p[1])
-+                return p + 1;
-+            /* Else null string */
-+            return NULL;
-+        }
-+        if (!isspace((unsigned char)c))
-+            return p;
-+    }
-+    return NULL;
-+}
-+
-+/* As above but strip from end of string : maybe should handle brackets? */
-+static char *strip_end(char *name)
-+{
-+    char *p, c;
-+    if (!name)
-+        return NULL;
-+    /* Look for first non white space or quote */
-+    for (p = name + strlen(name) - 1; p >= name; p--) {
-+        c = *p;
-+        if (c == '"') {
-+            if (p - 1 == name)
-+                return NULL;
-+            *p = 0;
-+            return name;
-+        }
-+        if (isspace((unsigned char)c))
-+            *p = 0;
-+        else
-+            return name;
-+    }
-+    return NULL;
-+}
-+
-+static MIME_HEADER *mime_hdr_new(const char *name, const char *value)
-+{
-+    MIME_HEADER *mhdr = NULL;
-+    char *tmpname = NULL, *tmpval = NULL, *p;
-+    int c;
-+
-+    if (name) {
-+        if ((tmpname = OPENSSL_strdup(name)) == NULL)
-+            return NULL;
-+        for (p = tmpname; *p; p++) {
-+            c = (unsigned char)*p;
-+            if (isupper(c)) {
-+                c = tolower(c);
-+                *p = c;
-+            }
-+        }
-+    }
-+    if (value) {
-+        if ((tmpval = OPENSSL_strdup(value)) == NULL)
-+            goto err;
-+        for (p = tmpval; *p; p++) {
-+            c = (unsigned char)*p;
-+            if (isupper(c)) {
-+                c = tolower(c);
-+                *p = c;
-+            }
-+        }
-+    }
-+    mhdr = OPENSSL_malloc(sizeof(*mhdr));
-+    if (mhdr == NULL)
-+        goto err;
-+    mhdr->name = tmpname;
-+    mhdr->value = tmpval;
-+    if ((mhdr->params = sk_MIME_PARAM_new(mime_param_cmp)) == NULL)
-+        goto err;
-+    return mhdr;
-+
-+ err:
-+    OPENSSL_free(tmpname);
-+    OPENSSL_free(tmpval);
-+    OPENSSL_free(mhdr);
-+    return NULL;
-+}
-+
-+static int mime_hdr_addparam(MIME_HEADER *mhdr, const char *name, const char *value)
-+{
-+    char *tmpname = NULL, *tmpval = NULL, *p;
-+    int c;
-+    MIME_PARAM *mparam = NULL;
-+    if (name) {
-+        tmpname = OPENSSL_strdup(name);
-+        if (!tmpname)
-+            goto err;
-+        for (p = tmpname; *p; p++) {
-+            c = (unsigned char)*p;
-+            if (isupper(c)) {
-+                c = tolower(c);
-+                *p = c;
-+            }
-+        }
-+    }
-+    if (value) {
-+        tmpval = OPENSSL_strdup(value);
-+        if (!tmpval)
-+            goto err;
-+    }
-+    /* Parameter values are case sensitive so leave as is */
-+    mparam = OPENSSL_malloc(sizeof(*mparam));
-+    if (mparam == NULL)
-+        goto err;
-+    mparam->param_name = tmpname;
-+    mparam->param_value = tmpval;
-+    if (!sk_MIME_PARAM_push(mhdr->params, mparam))
-+        goto err;
-+    return 1;
-+ err:
-+    OPENSSL_free(tmpname);
-+    OPENSSL_free(tmpval);
-+    OPENSSL_free(mparam);
-+    return 0;
-+}
-+
-+static int mime_hdr_cmp(const MIME_HEADER *const *a,
-+                        const MIME_HEADER *const *b)
-+{
-+    if (!(*a)->name || !(*b)->name)
-+        return ! !(*a)->name - ! !(*b)->name;
-+
-+    return (strcmp((*a)->name, (*b)->name));
-+}
-+
-+static int mime_param_cmp(const MIME_PARAM *const *a,
-+                          const MIME_PARAM *const *b)
-+{
-+    if (!(*a)->param_name || !(*b)->param_name)
-+        return ! !(*a)->param_name - ! !(*b)->param_name;
-+    return (strcmp((*a)->param_name, (*b)->param_name));
-+}
-+
-+/* Find a header with a given name (if possible) */
-+
-+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, const char *name)
-+{
-+    MIME_HEADER htmp;
-+    int idx;
-+
-+    htmp.name = (char *)name;
-+    htmp.value = NULL;
-+    htmp.params = NULL;
-+
-+    idx = sk_MIME_HEADER_find(hdrs, &htmp);
-+    if (idx < 0)
-+        return NULL;
-+    return sk_MIME_HEADER_value(hdrs, idx);
-+}
-+
-+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, const char *name)
-+{
-+    MIME_PARAM param;
-+    int idx;
-+
-+    param.param_name = (char *)name;
-+    param.param_value = NULL;
-+    idx = sk_MIME_PARAM_find(hdr->params, ¶m);
-+    if (idx < 0)
-+        return NULL;
-+    return sk_MIME_PARAM_value(hdr->params, idx);
-+}
-+
-+static void mime_hdr_free(MIME_HEADER *hdr)
-+{
-+    if (hdr == NULL)
-+        return;
-+    OPENSSL_free(hdr->name);
-+    OPENSSL_free(hdr->value);
-+    if (hdr->params)
-+        sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
-+    OPENSSL_free(hdr);
-+}
-+
-+static void mime_param_free(MIME_PARAM *param)
-+{
-+    OPENSSL_free(param->param_name);
-+    OPENSSL_free(param->param_value);
-+    OPENSSL_free(param);
-+}
-+
-+/*-
-+ * Check for a multipart boundary. Returns:
-+ * 0 : no boundary
-+ * 1 : part boundary
-+ * 2 : final boundary
-+ */
-+static int mime_bound_check(char *line, int linelen, const char *bound, int blen)
-+{
-+    if (linelen == -1)
-+        linelen = strlen(line);
-+    if (blen == -1)
-+        blen = strlen(bound);
-+    /* Quickly eliminate if line length too short */
-+    if (blen + 2 > linelen)
-+        return 0;
-+    /* Check for part boundary */
-+    if ((strncmp(line, "--", 2) == 0)
-+        && strncmp(line + 2, bound, blen) == 0) {
-+        if (strncmp(line + blen + 2, "--", 2) == 0)
-+            return 2;
-+        else
-+            return 1;
-+    }
-+    return 0;
-+}
-+
-+static int strip_eol(char *linebuf, int *plen, int flags)
-+{
-+    int len = *plen;
-+    char *p, c;
-+    int is_eol = 0;
-+    p = linebuf + len - 1;
-+    for (p = linebuf + len - 1; len > 0; len--, p--) {
-+        c = *p;
-+        if (c == '\n')
-+            is_eol = 1;
-+        else if (is_eol && flags & SMIME_ASCIICRLF && c < 33)
-+            continue;
-+        else if (c != '\r')
-+            break;
-+    }
-+    *plen = len;
-+    return is_eol;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_moid.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_moid.c
-new file mode 100644
-index 0000000..8176b76
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_moid.c
-@@ -0,0 +1,105 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/objects.h"
-+
-+/* Simple ASN1 OID module: add all objects in a given section */
-+
-+static int do_create(const char *value, const char *name);
-+
-+static int oid_module_init(CONF_IMODULE *md, const CONF *cnf)
-+{
-+    int i;
-+    const char *oid_section;
-+    STACK_OF(CONF_VALUE) *sktmp;
-+    CONF_VALUE *oval;
-+
-+    oid_section = CONF_imodule_get_value(md);
-+    if ((sktmp = NCONF_get_section(cnf, oid_section)) == NULL) {
-+        ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
-+        return 0;
-+    }
-+    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
-+        oval = sk_CONF_VALUE_value(sktmp, i);
-+        if (!do_create(oval->value, oval->name)) {
-+            ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
-+            return 0;
-+        }
-+    }
-+    return 1;
-+}
-+
-+static void oid_module_finish(CONF_IMODULE *md)
-+{
-+}
-+
-+void ASN1_add_oid_module(void)
-+{
-+    CONF_module_add("oid_section", oid_module_init, oid_module_finish);
-+}
-+
-+/*-
-+ * Create an OID based on a name value pair. Accept two formats.
-+ * shortname = 1.2.3.4
-+ * shortname = some long name, 1.2.3.4
-+ */
-+
-+static int do_create(const char *value, const char *name)
-+{
-+    int nid;
-+    ASN1_OBJECT *oid;
-+    const char *ln, *ostr, *p;
-+    char *lntmp;
-+    p = strrchr(value, ',');
-+    if (!p) {
-+        ln = name;
-+        ostr = value;
-+    } else {
-+        ln = NULL;
-+        ostr = p + 1;
-+        if (!*ostr)
-+            return 0;
-+        while (isspace((unsigned char)*ostr))
-+            ostr++;
-+    }
-+
-+    nid = OBJ_create(ostr, name, ln);
-+
-+    if (nid == NID_undef)
-+        return 0;
-+
-+    if (p) {
-+        ln = value;
-+        while (isspace((unsigned char)*ln))
-+            ln++;
-+        p--;
-+        while (isspace((unsigned char)*p)) {
-+            if (p == ln)
-+                return 0;
-+            p--;
-+        }
-+        p++;
-+        lntmp = OPENSSL_malloc((p - ln) + 1);
-+        if (lntmp == NULL)
-+            return 0;
-+        memcpy(lntmp, ln, p - ln);
-+        lntmp[p - ln] = 0;
-+        oid = OBJ_nid2obj(nid);
-+        oid->ln = lntmp;
-+    }
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_mstbl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_mstbl.c
-new file mode 100644
-index 0000000..8260939
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_mstbl.c
-@@ -0,0 +1,114 @@
-+/*
-+ * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+/* Multi string module: add table entries from a given section */
-+
-+static int do_tcreate(const char *value, const char *name);
-+
-+static int stbl_module_init(CONF_IMODULE *md, const CONF *cnf)
-+{
-+    int i;
-+    const char *stbl_section;
-+    STACK_OF(CONF_VALUE) *sktmp;
-+    CONF_VALUE *mval;
-+
-+    stbl_section = CONF_imodule_get_value(md);
-+    if ((sktmp = NCONF_get_section(cnf, stbl_section)) == NULL) {
-+        ASN1err(ASN1_F_STBL_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
-+        return 0;
-+    }
-+    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
-+        mval = sk_CONF_VALUE_value(sktmp, i);
-+        if (!do_tcreate(mval->value, mval->name)) {
-+            ASN1err(ASN1_F_STBL_MODULE_INIT, ASN1_R_INVALID_VALUE);
-+            return 0;
-+        }
-+    }
-+    return 1;
-+}
-+
-+static void stbl_module_finish(CONF_IMODULE *md)
-+{
-+    ASN1_STRING_TABLE_cleanup();
-+}
-+
-+void ASN1_add_stable_module(void)
-+{
-+    CONF_module_add("stbl_section", stbl_module_init, stbl_module_finish);
-+}
-+
-+/*
-+ * Create an table entry based on a name value pair. format is oid_name =
-+ * n1:v1, n2:v2,... where name is "min", "max", "mask" or "flags".
-+ */
-+
-+static int do_tcreate(const char *value, const char *name)
-+{
-+    char *eptr;
-+    int nid, i, rv = 0;
-+    long tbl_min = -1, tbl_max = -1;
-+    unsigned long tbl_mask = 0, tbl_flags = 0;
-+    STACK_OF(CONF_VALUE) *lst = NULL;
-+    CONF_VALUE *cnf = NULL;
-+    nid = OBJ_sn2nid(name);
-+    if (nid == NID_undef)
-+        nid = OBJ_ln2nid(name);
-+    if (nid == NID_undef)
-+        goto err;
-+    lst = X509V3_parse_list(value);
-+    if (!lst)
-+        goto err;
-+    for (i = 0; i < sk_CONF_VALUE_num(lst); i++) {
-+        cnf = sk_CONF_VALUE_value(lst, i);
-+        if (strcmp(cnf->name, "min") == 0) {
-+            tbl_min = strtoul(cnf->value, &eptr, 0);
-+            if (*eptr)
-+                goto err;
-+        } else if (strcmp(cnf->name, "max") == 0) {
-+            tbl_max = strtoul(cnf->value, &eptr, 0);
-+            if (*eptr)
-+                goto err;
-+        } else if (strcmp(cnf->name, "mask") == 0) {
-+            if (!ASN1_str2mask(cnf->value, &tbl_mask) || !tbl_mask)
-+                goto err;
-+        } else if (strcmp(cnf->name, "flags") == 0) {
-+            if (strcmp(cnf->value, "nomask") == 0)
-+                tbl_flags = STABLE_NO_MASK;
-+            else if (strcmp(cnf->value, "none") == 0)
-+                tbl_flags = STABLE_FLAGS_CLEAR;
-+            else
-+                goto err;
-+        } else
-+            goto err;
-+    }
-+    rv = 1;
-+ err:
-+    if (rv == 0) {
-+        ASN1err(ASN1_F_DO_TCREATE, ASN1_R_INVALID_STRING_TABLE_VALUE);
-+        if (cnf)
-+            ERR_add_error_data(4, "field=", cnf->name,
-+                               ", value=", cnf->value);
-+        else
-+            ERR_add_error_data(4, "name=", name, ", value=", value);
-+    } else {
-+        rv = ASN1_STRING_TABLE_add(nid, tbl_min, tbl_max,
-+                                   tbl_mask, tbl_flags);
-+        if (!rv)
-+            ASN1err(ASN1_F_DO_TCREATE, ERR_R_MALLOC_FAILURE);
-+    }
-+    sk_CONF_VALUE_pop_free(lst, X509V3_conf_free);
-+    return rv;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_pack.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_pack.c
-new file mode 100644
-index 0000000..63bc306
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/asn_pack.c
-@@ -0,0 +1,62 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+/* ASN1 packing and unpacking functions */
-+
-+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
-+{
-+    ASN1_STRING *octmp;
-+
-+     if (oct == NULL || *oct == NULL) {
-+        if ((octmp = ASN1_STRING_new()) == NULL) {
-+            ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
-+            return NULL;
-+        }
-+    } else {
-+        octmp = *oct;
-+    }
-+
-+    OPENSSL_free(octmp->data);
-+    octmp->data = NULL;
-+
-+    if ((octmp->length = ASN1_item_i2d(obj, &octmp->data, it)) == 0) {
-+        ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR);
-+        goto err;
-+    }
-+    if (octmp->data == NULL) {
-+        ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (oct != NULL && *oct == NULL)
-+        *oct = octmp;
-+
-+    return octmp;
-+ err:
-+    if (oct == NULL || *oct == NULL)
-+        ASN1_STRING_free(octmp);
-+    return NULL;
-+}
-+
-+/* Extract an ASN1 object from an ASN1_STRING */
-+
-+void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it)
-+{
-+    const unsigned char *p;
-+    void *ret;
-+
-+    p = oct->data;
-+    if ((ret = ASN1_item_d2i(NULL, &p, oct->length, it)) == NULL)
-+        ASN1err(ASN1_F_ASN1_ITEM_UNPACK, ASN1_R_DECODE_ERROR);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_asn1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_asn1.c
-new file mode 100644
-index 0000000..400effa
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_asn1.c
-@@ -0,0 +1,437 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Experimental ASN1 BIO. When written through the data is converted to an
-+ * ASN1 string type: default is OCTET STRING. Additional functions can be
-+ * provided to add prefix and suffix data.
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* Must be large enough for biggest tag+length */
-+#define DEFAULT_ASN1_BUF_SIZE 20
-+
-+typedef enum {
-+    ASN1_STATE_START,
-+    ASN1_STATE_PRE_COPY,
-+    ASN1_STATE_HEADER,
-+    ASN1_STATE_HEADER_COPY,
-+    ASN1_STATE_DATA_COPY,
-+    ASN1_STATE_POST_COPY,
-+    ASN1_STATE_DONE
-+} asn1_bio_state_t;
-+
-+typedef struct BIO_ASN1_EX_FUNCS_st {
-+    asn1_ps_func *ex_func;
-+    asn1_ps_func *ex_free_func;
-+} BIO_ASN1_EX_FUNCS;
-+
-+typedef struct BIO_ASN1_BUF_CTX_t {
-+    /* Internal state */
-+    asn1_bio_state_t state;
-+    /* Internal buffer */
-+    unsigned char *buf;
-+    /* Size of buffer */
-+    int bufsize;
-+    /* Current position in buffer */
-+    int bufpos;
-+    /* Current buffer length */
-+    int buflen;
-+    /* Amount of data to copy */
-+    int copylen;
-+    /* Class and tag to use */
-+    int asn1_class, asn1_tag;
-+    asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
-+    /* Extra buffer for prefix and suffix data */
-+    unsigned char *ex_buf;
-+    int ex_len;
-+    int ex_pos;
-+    void *ex_arg;
-+} BIO_ASN1_BUF_CTX;
-+
-+static int asn1_bio_write(BIO *h, const char *buf, int num);
-+static int asn1_bio_read(BIO *h, char *buf, int size);
-+static int asn1_bio_puts(BIO *h, const char *str);
-+static int asn1_bio_gets(BIO *h, char *str, int size);
-+static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int asn1_bio_new(BIO *h);
-+static int asn1_bio_free(BIO *data);
-+static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-+
-+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
-+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
-+                             asn1_ps_func *cleanup, asn1_bio_state_t next);
-+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
-+                             asn1_ps_func *setup,
-+                             asn1_bio_state_t ex_state,
-+                             asn1_bio_state_t other_state);
-+
-+static const BIO_METHOD methods_asn1 = {
-+    BIO_TYPE_ASN1,
-+    "asn1",
-+    asn1_bio_write,
-+    asn1_bio_read,
-+    asn1_bio_puts,
-+    asn1_bio_gets,
-+    asn1_bio_ctrl,
-+    asn1_bio_new,
-+    asn1_bio_free,
-+    asn1_bio_callback_ctrl,
-+};
-+
-+const BIO_METHOD *BIO_f_asn1(void)
-+{
-+    return (&methods_asn1);
-+}
-+
-+static int asn1_bio_new(BIO *b)
-+{
-+    BIO_ASN1_BUF_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
-+
-+    if (ctx == NULL)
-+        return 0;
-+    if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
-+        OPENSSL_free(ctx);
-+        return 0;
-+    }
-+    BIO_set_data(b, ctx);
-+    BIO_set_init(b, 1);
-+
-+    return 1;
-+}
-+
-+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
-+{
-+    ctx->buf = OPENSSL_malloc(size);
-+    if (ctx->buf == NULL)
-+        return 0;
-+    ctx->bufsize = size;
-+    ctx->asn1_class = V_ASN1_UNIVERSAL;
-+    ctx->asn1_tag = V_ASN1_OCTET_STRING;
-+    ctx->state = ASN1_STATE_START;
-+    return 1;
-+}
-+
-+static int asn1_bio_free(BIO *b)
-+{
-+    BIO_ASN1_BUF_CTX *ctx;
-+
-+    if (b == NULL)
-+        return 0;
-+
-+    ctx = BIO_get_data(b);
-+    if (ctx == NULL)
-+        return 0;
-+
-+    OPENSSL_free(ctx->buf);
-+    OPENSSL_free(ctx);
-+    BIO_set_data(b, NULL);
-+    BIO_set_init(b, 0);
-+
-+    return 1;
-+}
-+
-+static int asn1_bio_write(BIO *b, const char *in, int inl)
-+{
-+    BIO_ASN1_BUF_CTX *ctx;
-+    int wrmax, wrlen, ret;
-+    unsigned char *p;
-+    BIO *next;
-+
-+    ctx = BIO_get_data(b);
-+    next = BIO_next(b);
-+    if (in == NULL || inl < 0 || ctx == NULL || next == NULL)
-+        return 0;
-+
-+    wrlen = 0;
-+    ret = -1;
-+
-+    for (;;) {
-+        switch (ctx->state) {
-+
-+            /* Setup prefix data, call it */
-+        case ASN1_STATE_START:
-+            if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
-+                                   ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
-+                return 0;
-+            break;
-+
-+            /* Copy any pre data first */
-+        case ASN1_STATE_PRE_COPY:
-+
-+            ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
-+                                    ASN1_STATE_HEADER);
-+
-+            if (ret <= 0)
-+                goto done;
-+
-+            break;
-+
-+        case ASN1_STATE_HEADER:
-+            ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
-+            OPENSSL_assert(ctx->buflen <= ctx->bufsize);
-+            p = ctx->buf;
-+            ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
-+            ctx->copylen = inl;
-+            ctx->state = ASN1_STATE_HEADER_COPY;
-+
-+            break;
-+
-+        case ASN1_STATE_HEADER_COPY:
-+            ret = BIO_write(next, ctx->buf + ctx->bufpos, ctx->buflen);
-+            if (ret <= 0)
-+                goto done;
-+
-+            ctx->buflen -= ret;
-+            if (ctx->buflen)
-+                ctx->bufpos += ret;
-+            else {
-+                ctx->bufpos = 0;
-+                ctx->state = ASN1_STATE_DATA_COPY;
-+            }
-+
-+            break;
-+
-+        case ASN1_STATE_DATA_COPY:
-+
-+            if (inl > ctx->copylen)
-+                wrmax = ctx->copylen;
-+            else
-+                wrmax = inl;
-+            ret = BIO_write(next, in, wrmax);
-+            if (ret <= 0)
-+                break;
-+            wrlen += ret;
-+            ctx->copylen -= ret;
-+            in += ret;
-+            inl -= ret;
-+
-+            if (ctx->copylen == 0)
-+                ctx->state = ASN1_STATE_HEADER;
-+
-+            if (inl == 0)
-+                goto done;
-+
-+            break;
-+
-+        default:
-+            BIO_clear_retry_flags(b);
-+            return 0;
-+
-+        }
-+
-+    }
-+
-+ done:
-+    BIO_clear_retry_flags(b);
-+    BIO_copy_next_retry(b);
-+
-+    return (wrlen > 0) ? wrlen : ret;
-+
-+}
-+
-+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
-+                             asn1_ps_func *cleanup, asn1_bio_state_t next)
-+{
-+    int ret;
-+
-+    if (ctx->ex_len <= 0)
-+        return 1;
-+    for (;;) {
-+        ret = BIO_write(BIO_next(b), ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
-+        if (ret <= 0)
-+            break;
-+        ctx->ex_len -= ret;
-+        if (ctx->ex_len > 0)
-+            ctx->ex_pos += ret;
-+        else {
-+            if (cleanup)
-+                cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
-+            ctx->state = next;
-+            ctx->ex_pos = 0;
-+            break;
-+        }
-+    }
-+    return ret;
-+}
-+
-+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
-+                             asn1_ps_func *setup,
-+                             asn1_bio_state_t ex_state,
-+                             asn1_bio_state_t other_state)
-+{
-+    if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
-+        BIO_clear_retry_flags(b);
-+        return 0;
-+    }
-+    if (ctx->ex_len > 0)
-+        ctx->state = ex_state;
-+    else
-+        ctx->state = other_state;
-+    return 1;
-+}
-+
-+static int asn1_bio_read(BIO *b, char *in, int inl)
-+{
-+    BIO *next = BIO_next(b);
-+    if (next == NULL)
-+        return 0;
-+    return BIO_read(next, in, inl);
-+}
-+
-+static int asn1_bio_puts(BIO *b, const char *str)
-+{
-+    return asn1_bio_write(b, str, strlen(str));
-+}
-+
-+static int asn1_bio_gets(BIO *b, char *str, int size)
-+{
-+    BIO *next = BIO_next(b);
-+    if (next == NULL)
-+        return 0;
-+    return BIO_gets(next, str, size);
-+}
-+
-+static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    BIO *next = BIO_next(b);
-+    if (next == NULL)
-+        return 0;
-+    return BIO_callback_ctrl(next, cmd, fp);
-+}
-+
-+static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
-+{
-+    BIO_ASN1_BUF_CTX *ctx;
-+    BIO_ASN1_EX_FUNCS *ex_func;
-+    long ret = 1;
-+    BIO *next;
-+
-+    ctx = BIO_get_data(b);
-+    if (ctx == NULL)
-+        return 0;
-+    next = BIO_next(b);
-+    switch (cmd) {
-+
-+    case BIO_C_SET_PREFIX:
-+        ex_func = arg2;
-+        ctx->prefix = ex_func->ex_func;
-+        ctx->prefix_free = ex_func->ex_free_func;
-+        break;
-+
-+    case BIO_C_GET_PREFIX:
-+        ex_func = arg2;
-+        ex_func->ex_func = ctx->prefix;
-+        ex_func->ex_free_func = ctx->prefix_free;
-+        break;
-+
-+    case BIO_C_SET_SUFFIX:
-+        ex_func = arg2;
-+        ctx->suffix = ex_func->ex_func;
-+        ctx->suffix_free = ex_func->ex_free_func;
-+        break;
-+
-+    case BIO_C_GET_SUFFIX:
-+        ex_func = arg2;
-+        ex_func->ex_func = ctx->suffix;
-+        ex_func->ex_free_func = ctx->suffix_free;
-+        break;
-+
-+    case BIO_C_SET_EX_ARG:
-+        ctx->ex_arg = arg2;
-+        break;
-+
-+    case BIO_C_GET_EX_ARG:
-+        *(void **)arg2 = ctx->ex_arg;
-+        break;
-+
-+    case BIO_CTRL_FLUSH:
-+        if (next == NULL)
-+            return 0;
-+
-+        /* Call post function if possible */
-+        if (ctx->state == ASN1_STATE_HEADER) {
-+            if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
-+                                   ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
-+                return 0;
-+        }
-+
-+        if (ctx->state == ASN1_STATE_POST_COPY) {
-+            ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
-+                                    ASN1_STATE_DONE);
-+            if (ret <= 0)
-+                return ret;
-+        }
-+
-+        if (ctx->state == ASN1_STATE_DONE)
-+            return BIO_ctrl(next, cmd, arg1, arg2);
-+        else {
-+            BIO_clear_retry_flags(b);
-+            return 0;
-+        }
-+
-+    default:
-+        if (next == NULL)
-+            return 0;
-+        return BIO_ctrl(next, cmd, arg1, arg2);
-+
-+    }
-+
-+    return ret;
-+}
-+
-+static int asn1_bio_set_ex(BIO *b, int cmd,
-+                           asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
-+{
-+    BIO_ASN1_EX_FUNCS extmp;
-+    extmp.ex_func = ex_func;
-+    extmp.ex_free_func = ex_free_func;
-+    return BIO_ctrl(b, cmd, 0, &extmp);
-+}
-+
-+static int asn1_bio_get_ex(BIO *b, int cmd,
-+                           asn1_ps_func **ex_func,
-+                           asn1_ps_func **ex_free_func)
-+{
-+    BIO_ASN1_EX_FUNCS extmp;
-+    int ret;
-+    ret = BIO_ctrl(b, cmd, 0, &extmp);
-+    if (ret > 0) {
-+        *ex_func = extmp.ex_func;
-+        *ex_free_func = extmp.ex_free_func;
-+    }
-+    return ret;
-+}
-+
-+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
-+                        asn1_ps_func *prefix_free)
-+{
-+    return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
-+}
-+
-+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
-+                        asn1_ps_func **pprefix_free)
-+{
-+    return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
-+}
-+
-+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
-+                        asn1_ps_func *suffix_free)
-+{
-+    return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
-+}
-+
-+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
-+                        asn1_ps_func **psuffix_free)
-+{
-+    return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_ndef.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_ndef.c
-new file mode 100644
-index 0000000..0f206b2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/bio_ndef.c
-@@ -0,0 +1,199 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include 
-+
-+/* Experimental NDEF ASN1 BIO support routines */
-+
-+/*
-+ * The usage is quite simple, initialize an ASN1 structure, get a BIO from it
-+ * then any data written through the BIO will end up translated to
-+ * appropriate format on the fly. The data is streamed out and does *not*
-+ * need to be all held in memory at once. When the BIO is flushed the output
-+ * is finalized and any signatures etc written out. The BIO is a 'proper'
-+ * BIO and can handle non blocking I/O correctly. The usage is simple. The
-+ * implementation is *not*...
-+ */
-+
-+/* BIO support data stored in the ASN1 BIO ex_arg */
-+
-+typedef struct ndef_aux_st {
-+    /* ASN1 structure this BIO refers to */
-+    ASN1_VALUE *val;
-+    const ASN1_ITEM *it;
-+    /* Top of the BIO chain */
-+    BIO *ndef_bio;
-+    /* Output BIO */
-+    BIO *out;
-+    /* Boundary where content is inserted */
-+    unsigned char **boundary;
-+    /* DER buffer start */
-+    unsigned char *derbuf;
-+} NDEF_SUPPORT;
-+
-+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
-+                            void *parg);
-+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
-+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
-+                            void *parg);
-+
-+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
-+{
-+    NDEF_SUPPORT *ndef_aux = NULL;
-+    BIO *asn_bio = NULL;
-+    const ASN1_AUX *aux = it->funcs;
-+    ASN1_STREAM_ARG sarg;
-+
-+    if (!aux || !aux->asn1_cb) {
-+        ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
-+        return NULL;
-+    }
-+    ndef_aux = OPENSSL_zalloc(sizeof(*ndef_aux));
-+    asn_bio = BIO_new(BIO_f_asn1());
-+    if (ndef_aux == NULL || asn_bio == NULL)
-+        goto err;
-+
-+    /* ASN1 bio needs to be next to output BIO */
-+    out = BIO_push(asn_bio, out);
-+    if (out == NULL)
-+        goto err;
-+
-+    BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
-+    BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
-+
-+    /*
-+     * Now let callback prepends any digest, cipher etc BIOs ASN1 structure
-+     * needs.
-+     */
-+
-+    sarg.out = out;
-+    sarg.ndef_bio = NULL;
-+    sarg.boundary = NULL;
-+
-+    if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
-+        goto err;
-+
-+    ndef_aux->val = val;
-+    ndef_aux->it = it;
-+    ndef_aux->ndef_bio = sarg.ndef_bio;
-+    ndef_aux->boundary = sarg.boundary;
-+    ndef_aux->out = out;
-+
-+    BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
-+
-+    return sarg.ndef_bio;
-+
-+ err:
-+    BIO_free(asn_bio);
-+    OPENSSL_free(ndef_aux);
-+    return NULL;
-+}
-+
-+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
-+{
-+    NDEF_SUPPORT *ndef_aux;
-+    unsigned char *p;
-+    int derlen;
-+
-+    if (!parg)
-+        return 0;
-+
-+    ndef_aux = *(NDEF_SUPPORT **)parg;
-+
-+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
-+    p = OPENSSL_malloc(derlen);
-+    if (p == NULL)
-+        return 0;
-+
-+    ndef_aux->derbuf = p;
-+    *pbuf = p;
-+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
-+
-+    if (!*ndef_aux->boundary)
-+        return 0;
-+
-+    *plen = *ndef_aux->boundary - *pbuf;
-+
-+    return 1;
-+}
-+
-+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
-+                            void *parg)
-+{
-+    NDEF_SUPPORT *ndef_aux;
-+
-+    if (!parg)
-+        return 0;
-+
-+    ndef_aux = *(NDEF_SUPPORT **)parg;
-+
-+    OPENSSL_free(ndef_aux->derbuf);
-+
-+    ndef_aux->derbuf = NULL;
-+    *pbuf = NULL;
-+    *plen = 0;
-+    return 1;
-+}
-+
-+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
-+                            void *parg)
-+{
-+    NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
-+    if (!ndef_prefix_free(b, pbuf, plen, parg))
-+        return 0;
-+    OPENSSL_free(*pndef_aux);
-+    *pndef_aux = NULL;
-+    return 1;
-+}
-+
-+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
-+{
-+    NDEF_SUPPORT *ndef_aux;
-+    unsigned char *p;
-+    int derlen;
-+    const ASN1_AUX *aux;
-+    ASN1_STREAM_ARG sarg;
-+
-+    if (!parg)
-+        return 0;
-+
-+    ndef_aux = *(NDEF_SUPPORT **)parg;
-+
-+    aux = ndef_aux->it->funcs;
-+
-+    /* Finalize structures */
-+    sarg.ndef_bio = ndef_aux->ndef_bio;
-+    sarg.out = ndef_aux->out;
-+    sarg.boundary = ndef_aux->boundary;
-+    if (aux->asn1_cb(ASN1_OP_STREAM_POST,
-+                     &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
-+        return 0;
-+
-+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
-+    p = OPENSSL_malloc(derlen);
-+    if (p == NULL)
-+        return 0;
-+
-+    ndef_aux->derbuf = p;
-+    *pbuf = p;
-+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
-+
-+    if (!*ndef_aux->boundary)
-+        return 0;
-+    *pbuf = *ndef_aux->boundary;
-+    *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/build.info
-new file mode 100644
-index 0000000..02d1120
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/build.info
-@@ -0,0 +1,16 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
-+        a_print.c a_type.c a_dup.c a_d2i_fp.c a_i2d_fp.c \
-+        a_utf8.c a_sign.c a_digest.c a_verify.c a_mbstr.c a_strex.c \
-+        x_algor.c x_val.c x_sig.c x_bignum.c \
-+        x_long.c x_info.c x_spki.c nsseq.c \
-+        d2i_pu.c d2i_pr.c i2d_pu.c i2d_pr.c\
-+        t_pkey.c t_spki.c t_bitst.c \
-+        tasn_new.c tasn_fre.c tasn_enc.c tasn_dec.c tasn_utl.c tasn_typ.c \
-+        tasn_prn.c tasn_scn.c ameth_lib.c \
-+        f_int.c f_string.c n_pkey.c \
-+        x_pkey.c bio_asn1.c bio_ndef.c asn_mime.c \
-+        asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_strnid.c \
-+        evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p5_scrypt.c p8_pkey.c \
-+        asn_moid.c asn_mstbl.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/charmap.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/charmap.h
-new file mode 100644
-index 0000000..2a75925
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/charmap.h
-@@ -0,0 +1,34 @@
-+/*
-+ * WARNING: do not edit!
-+ * Generated by crypto/asn1/charmap.pl
-+ *
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#define CHARTYPE_HOST_ANY 4096
-+#define CHARTYPE_HOST_DOT 8192
-+#define CHARTYPE_HOST_HYPHEN 16384
-+#define CHARTYPE_HOST_WILD 32768
-+
-+/*
-+ * Mask of various character properties
-+ */
-+
-+static const unsigned short char_type[] = {
-+    1026,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-+       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-+       2,    2,    2,    2,    2,    2,    2,    2,  120,    0,    1,   40,
-+       0,    0,    0,   16, 1040, 1040, 33792,   25,   25, 16400, 8208,   16,
-+    4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,   16,    9,
-+       9,   16,    9,   16,    0, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
-+    4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
-+    4112, 4112, 4112, 4112, 4112, 4112, 4112,    0, 1025,    0,    0,    0,
-+       0, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
-+    4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
-+    4112, 4112, 4112,    0,    0,    0,    0,    2
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/charmap.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/charmap.pl
-new file mode 100644
-index 0000000..26ca325
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/charmap.pl
-@@ -0,0 +1,117 @@
-+#! /usr/bin/env perl
-+# Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+use strict;
-+
-+my ($i, @arr);
-+
-+# Set up an array with the type of ASCII characters
-+# Each set bit represents a character property.
-+
-+# RFC2253 character properties
-+my $RFC2253_ESC = 1;	# Character escaped with \
-+my $ESC_CTRL	= 2;	# Escaped control character
-+# These are used with RFC1779 quoting using "
-+my $NOESC_QUOTE	= 8;	# Not escaped if quoted
-+my $PSTRING_CHAR = 0x10;	# Valid PrintableString character
-+my $RFC2253_FIRST_ESC = 0x20; # Escaped with \ if first character
-+my $RFC2253_LAST_ESC = 0x40;  # Escaped with \ if last character
-+my $RFC2254_ESC = 0x400;	# Character escaped \XX
-+my $HOST_ANY = 0x1000;      # Valid hostname character anywhere in label
-+my $HOST_DOT = 0x2000;  # Dot: hostname label separator
-+my $HOST_HYPHEN = 0x4000; # Hyphen: not valid at start or end.
-+my $HOST_WILD = 0x8000; # Wildcard character
-+
-+for($i = 0; $i < 128; $i++) {
-+	# Set the RFC2253 escape characters (control)
-+	$arr[$i] = 0;
-+	if(($i < 32) || ($i > 126)) {
-+		$arr[$i] |= $ESC_CTRL;
-+	}
-+
-+	# Some PrintableString characters
-+	if(		   ( ( $i >= ord("a")) && ( $i <= ord("z")) )
-+			|| (  ( $i >= ord("A")) && ( $i <= ord("Z")) )
-+			|| (  ( $i >= ord("0")) && ( $i <= ord("9")) )  ) {
-+		$arr[$i] |= $PSTRING_CHAR | $HOST_ANY;
-+	}
-+}
-+
-+# Now setup the rest
-+
-+# Remaining RFC2253 escaped characters
-+
-+$arr[ord(" ")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC | $RFC2253_LAST_ESC;
-+$arr[ord("#")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC;
-+
-+$arr[ord(",")] |= $NOESC_QUOTE | $RFC2253_ESC;
-+$arr[ord("+")] |= $NOESC_QUOTE | $RFC2253_ESC;
-+$arr[ord("\"")] |= $RFC2253_ESC;
-+$arr[ord("\\")] |= $RFC2253_ESC;
-+$arr[ord("<")] |= $NOESC_QUOTE | $RFC2253_ESC;
-+$arr[ord(">")] |= $NOESC_QUOTE | $RFC2253_ESC;
-+$arr[ord(";")] |= $NOESC_QUOTE | $RFC2253_ESC;
-+
-+# Remaining RFC2254 characters
-+
-+$arr[0] |= $RFC2254_ESC;
-+$arr[ord("(")] |= $RFC2254_ESC;
-+$arr[ord(")")] |= $RFC2254_ESC;
-+$arr[ord("*")] |= $RFC2254_ESC | $HOST_WILD;
-+$arr[ord("\\")] |= $RFC2254_ESC;
-+
-+# Remaining PrintableString characters
-+
-+$arr[ord(" ")] |= $PSTRING_CHAR;
-+$arr[ord("'")] |= $PSTRING_CHAR;
-+$arr[ord("(")] |= $PSTRING_CHAR;
-+$arr[ord(")")] |= $PSTRING_CHAR;
-+$arr[ord("+")] |= $PSTRING_CHAR;
-+$arr[ord(",")] |= $PSTRING_CHAR;
-+$arr[ord("-")] |= $PSTRING_CHAR | $HOST_HYPHEN;
-+$arr[ord(".")] |= $PSTRING_CHAR | $HOST_DOT;
-+$arr[ord("/")] |= $PSTRING_CHAR;
-+$arr[ord(":")] |= $PSTRING_CHAR;
-+$arr[ord("=")] |= $PSTRING_CHAR;
-+$arr[ord("?")] |= $PSTRING_CHAR;
-+
-+# Now generate the C code
-+
-+print <
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
-+                         long length)
-+{
-+    EVP_PKEY *ret;
-+    const unsigned char *p = *pp;
-+
-+    if ((a == NULL) || (*a == NULL)) {
-+        if ((ret = EVP_PKEY_new()) == NULL) {
-+            ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
-+            return (NULL);
-+        }
-+    } else {
-+        ret = *a;
-+#ifndef OPENSSL_NO_ENGINE
-+        ENGINE_finish(ret->engine);
-+        ret->engine = NULL;
-+#endif
-+    }
-+
-+    if (!EVP_PKEY_set_type(ret, type)) {
-+        ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
-+        goto err;
-+    }
-+
-+    if (!ret->ameth->old_priv_decode ||
-+        !ret->ameth->old_priv_decode(ret, &p, length)) {
-+        if (ret->ameth->priv_decode) {
-+            EVP_PKEY *tmp;
-+            PKCS8_PRIV_KEY_INFO *p8 = NULL;
-+            p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
-+            if (!p8)
-+                goto err;
-+            tmp = EVP_PKCS82PKEY(p8);
-+            PKCS8_PRIV_KEY_INFO_free(p8);
-+            if (tmp == NULL)
-+                goto err;
-+            EVP_PKEY_free(ret);
-+            ret = tmp;
-+        } else {
-+            ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
-+            goto err;
-+        }
-+    }
-+    *pp = p;
-+    if (a != NULL)
-+        (*a) = ret;
-+    return (ret);
-+ err:
-+    if (a == NULL || *a != ret)
-+        EVP_PKEY_free(ret);
-+    return (NULL);
-+}
-+
-+/*
-+ * This works like d2i_PrivateKey() except it automatically works out the
-+ * type
-+ */
-+
-+EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
-+                             long length)
-+{
-+    STACK_OF(ASN1_TYPE) *inkey;
-+    const unsigned char *p;
-+    int keytype;
-+    p = *pp;
-+    /*
-+     * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
-+     * analyzing it we can determine the passed structure: this assumes the
-+     * input is surrounded by an ASN1 SEQUENCE.
-+     */
-+    inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
-+    p = *pp;
-+    /*
-+     * Since we only need to discern "traditional format" RSA and DSA keys we
-+     * can just count the elements.
-+     */
-+    if (sk_ASN1_TYPE_num(inkey) == 6)
-+        keytype = EVP_PKEY_DSA;
-+    else if (sk_ASN1_TYPE_num(inkey) == 4)
-+        keytype = EVP_PKEY_EC;
-+    else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not
-+                                              * traditional format */
-+        PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
-+        EVP_PKEY *ret;
-+
-+        sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
-+        if (!p8) {
-+            ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
-+                    ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
-+            return NULL;
-+        }
-+        ret = EVP_PKCS82PKEY(p8);
-+        PKCS8_PRIV_KEY_INFO_free(p8);
-+        if (ret == NULL)
-+            return NULL;
-+        *pp = p;
-+        if (a) {
-+            *a = ret;
-+        }
-+        return ret;
-+    } else
-+        keytype = EVP_PKEY_RSA;
-+    sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
-+    return d2i_PrivateKey(keytype, a, pp, length);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/d2i_pu.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/d2i_pu.c
-new file mode 100644
-index 0000000..dfdc1a6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/d2i_pu.c
-@@ -0,0 +1,78 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include "internal/evp_int.h"
-+
-+EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
-+                        long length)
-+{
-+    EVP_PKEY *ret;
-+
-+    if ((a == NULL) || (*a == NULL)) {
-+        if ((ret = EVP_PKEY_new()) == NULL) {
-+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
-+            return (NULL);
-+        }
-+    } else
-+        ret = *a;
-+
-+    if (!EVP_PKEY_set_type(ret, type)) {
-+        ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
-+        goto err;
-+    }
-+
-+    switch (EVP_PKEY_id(ret)) {
-+#ifndef OPENSSL_NO_RSA
-+    case EVP_PKEY_RSA:
-+        if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) == NULL) {
-+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
-+            goto err;
-+        }
-+        break;
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    case EVP_PKEY_DSA:
-+        /* TMP UGLY CAST */
-+        if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) {
-+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
-+            goto err;
-+        }
-+        break;
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    case EVP_PKEY_EC:
-+        if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) {
-+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
-+            goto err;
-+        }
-+        break;
-+#endif
-+    default:
-+        ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
-+        goto err;
-+        /* break; */
-+    }
-+    if (a != NULL)
-+        (*a) = ret;
-+    return (ret);
-+ err:
-+    if (a == NULL || *a != ret)
-+        EVP_PKEY_free(ret);
-+    return (NULL);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/evp_asn1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/evp_asn1.c
-new file mode 100644
-index 0000000..a458367
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/evp_asn1.c
-@@ -0,0 +1,115 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
-+{
-+    ASN1_STRING *os;
-+
-+    if ((os = ASN1_OCTET_STRING_new()) == NULL)
-+        return (0);
-+    if (!ASN1_OCTET_STRING_set(os, data, len)) {
-+        ASN1_OCTET_STRING_free(os);
-+        return 0;
-+    }
-+    ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os);
-+    return (1);
-+}
-+
-+/* int max_len:  for returned value    */
-+int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len)
-+{
-+    int ret, num;
-+    const unsigned char *p;
-+
-+    if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) {
-+        ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
-+        return (-1);
-+    }
-+    p = ASN1_STRING_get0_data(a->value.octet_string);
-+    ret = ASN1_STRING_length(a->value.octet_string);
-+    if (ret < max_len)
-+        num = ret;
-+    else
-+        num = max_len;
-+    memcpy(data, p, num);
-+    return (ret);
-+}
-+
-+typedef struct {
-+    long num;
-+    ASN1_OCTET_STRING *oct;
-+} asn1_int_oct;
-+
-+ASN1_SEQUENCE(asn1_int_oct) = {
-+        ASN1_SIMPLE(asn1_int_oct, num, LONG),
-+        ASN1_SIMPLE(asn1_int_oct, oct, ASN1_OCTET_STRING)
-+} static_ASN1_SEQUENCE_END(asn1_int_oct)
-+
-+DECLARE_ASN1_ITEM(asn1_int_oct)
-+
-+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
-+                                  int len)
-+{
-+    asn1_int_oct atmp;
-+    ASN1_OCTET_STRING oct;
-+
-+    atmp.num = num;
-+    atmp.oct = &oct;
-+    oct.data = data;
-+    oct.type = V_ASN1_OCTET_STRING;
-+    oct.length = len;
-+    oct.flags = 0;
-+
-+    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(asn1_int_oct), &atmp, &a))
-+        return 1;
-+    return 0;
-+}
-+
-+/*
-+ * we return the actual length...
-+ */
-+/* int max_len:  for returned value    */
-+int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num,
-+                                  unsigned char *data, int max_len)
-+{
-+    asn1_int_oct *atmp = NULL;
-+    int ret = -1, n;
-+
-+    if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
-+        goto err;
-+    }
-+
-+    atmp = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(asn1_int_oct), a);
-+
-+    if (atmp == NULL)
-+        goto err;
-+
-+    if (num != NULL)
-+        *num = atmp->num;
-+
-+    ret = ASN1_STRING_length(atmp->oct);
-+    if (max_len > ret)
-+        n = ret;
-+    else
-+        n = max_len;
-+
-+    if (data != NULL)
-+        memcpy(data, ASN1_STRING_get0_data(atmp->oct), n);
-+    if (ret == -1) {
-+ err:
-+        ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
-+    }
-+    M_ASN1_free_of(atmp, asn1_int_oct);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/f_int.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/f_int.c
-new file mode 100644
-index 0000000..51fc884
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/f_int.c
-@@ -0,0 +1,167 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
-+{
-+    int i, n = 0;
-+    static const char *h = "0123456789ABCDEF";
-+    char buf[2];
-+
-+    if (a == NULL)
-+        return (0);
-+
-+    if (a->type & V_ASN1_NEG) {
-+        if (BIO_write(bp, "-", 1) != 1)
-+            goto err;
-+        n = 1;
-+    }
-+
-+    if (a->length == 0) {
-+        if (BIO_write(bp, "00", 2) != 2)
-+            goto err;
-+        n += 2;
-+    } else {
-+        for (i = 0; i < a->length; i++) {
-+            if ((i != 0) && (i % 35 == 0)) {
-+                if (BIO_write(bp, "\\\n", 2) != 2)
-+                    goto err;
-+                n += 2;
-+            }
-+            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
-+            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
-+            if (BIO_write(bp, buf, 2) != 2)
-+                goto err;
-+            n += 2;
-+        }
-+    }
-+    return (n);
-+ err:
-+    return (-1);
-+}
-+
-+int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
-+{
-+    int i, j, k, m, n, again, bufsize;
-+    unsigned char *s = NULL, *sp;
-+    unsigned char *bufp;
-+    int num = 0, slen = 0, first = 1;
-+
-+    bs->type = V_ASN1_INTEGER;
-+
-+    bufsize = BIO_gets(bp, buf, size);
-+    for (;;) {
-+        if (bufsize < 1)
-+            goto err;
-+        i = bufsize;
-+        if (buf[i - 1] == '\n')
-+            buf[--i] = '\0';
-+        if (i == 0)
-+            goto err;
-+        if (buf[i - 1] == '\r')
-+            buf[--i] = '\0';
-+        if (i == 0)
-+            goto err;
-+        again = (buf[i - 1] == '\\');
-+
-+        for (j = 0; j < i; j++) {
-+#ifndef CHARSET_EBCDIC
-+            if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
-+                  ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
-+                  ((buf[j] >= 'A') && (buf[j] <= 'F'))))
-+#else
-+            /*
-+             * This #ifdef is not strictly necessary, since the characters
-+             * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
-+             * not the whole alphabet). Nevertheless, isxdigit() is faster.
-+             */
-+            if (!isxdigit(buf[j]))
-+#endif
-+            {
-+                i = j;
-+                break;
-+            }
-+        }
-+        buf[i] = '\0';
-+        /*
-+         * We have now cleared all the crap off the end of the line
-+         */
-+        if (i < 2)
-+            goto err;
-+
-+        bufp = (unsigned char *)buf;
-+        if (first) {
-+            first = 0;
-+            if ((bufp[0] == '0') && (buf[1] == '0')) {
-+                bufp += 2;
-+                i -= 2;
-+            }
-+        }
-+        k = 0;
-+        i -= again;
-+        if (i % 2 != 0) {
-+            ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS);
-+            OPENSSL_free(s);
-+            return 0;
-+        }
-+        i /= 2;
-+        if (num + i > slen) {
-+            sp = OPENSSL_clear_realloc(s, slen, num + i * 2);
-+            if (sp == NULL) {
-+                ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
-+                OPENSSL_free(s);
-+                return 0;
-+            }
-+            s = sp;
-+            slen = num + i * 2;
-+        }
-+        for (j = 0; j < i; j++, k += 2) {
-+            for (n = 0; n < 2; n++) {
-+                m = OPENSSL_hexchar2int(bufp[k + n]);
-+                if (m < 0) {
-+                    ASN1err(ASN1_F_A2I_ASN1_INTEGER,
-+                            ASN1_R_NON_HEX_CHARACTERS);
-+                    goto err;
-+                }
-+                s[num + j] <<= 4;
-+                s[num + j] |= m;
-+            }
-+        }
-+        num += i;
-+        if (again)
-+            bufsize = BIO_gets(bp, buf, size);
-+        else
-+            break;
-+    }
-+    bs->length = num;
-+    bs->data = s;
-+    return 1;
-+ err:
-+    ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE);
-+    OPENSSL_free(s);
-+    return 0;
-+}
-+
-+int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a)
-+{
-+    return i2a_ASN1_INTEGER(bp, a);
-+}
-+
-+int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
-+{
-+    int rv = a2i_ASN1_INTEGER(bp, bs, buf, size);
-+    if (rv == 1)
-+        bs->type = V_ASN1_INTEGER | (bs->type & V_ASN1_NEG);
-+    return rv;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/f_string.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/f_string.c
-new file mode 100644
-index 0000000..b9258bb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/f_string.c
-@@ -0,0 +1,148 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type)
-+{
-+    int i, n = 0;
-+    static const char *h = "0123456789ABCDEF";
-+    char buf[2];
-+
-+    if (a == NULL)
-+        return (0);
-+
-+    if (a->length == 0) {
-+        if (BIO_write(bp, "0", 1) != 1)
-+            goto err;
-+        n = 1;
-+    } else {
-+        for (i = 0; i < a->length; i++) {
-+            if ((i != 0) && (i % 35 == 0)) {
-+                if (BIO_write(bp, "\\\n", 2) != 2)
-+                    goto err;
-+                n += 2;
-+            }
-+            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
-+            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
-+            if (BIO_write(bp, buf, 2) != 2)
-+                goto err;
-+            n += 2;
-+        }
-+    }
-+    return (n);
-+ err:
-+    return (-1);
-+}
-+
-+int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
-+{
-+    int i, j, k, m, n, again, bufsize, spec_char;
-+    unsigned char *s = NULL, *sp;
-+    unsigned char *bufp;
-+    int num = 0, slen = 0, first = 1;
-+
-+    bufsize = BIO_gets(bp, buf, size);
-+    for (;;) {
-+        if (bufsize < 1) {
-+            if (first)
-+                break;
-+            else
-+                goto err;
-+        }
-+        first = 0;
-+
-+        i = bufsize;
-+        if (buf[i - 1] == '\n')
-+            buf[--i] = '\0';
-+        if (i == 0)
-+            goto err;
-+        if (buf[i - 1] == '\r')
-+            buf[--i] = '\0';
-+        if (i == 0)
-+            goto err;
-+        again = (buf[i - 1] == '\\');
-+
-+        for (j = i - 1; j > 0; j--) {
-+#ifndef CHARSET_EBCDIC
-+            spec_char = (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
-+                  ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
-+                  ((buf[j] >= 'A') && (buf[j] <= 'F'))));
-+#else
-+            /*
-+             * This #ifdef is not strictly necessary, since the characters
-+             * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
-+             * not the whole alphabet). Nevertheless, isxdigit() is faster.
-+             */
-+            spec_char = (!isxdigit(buf[j]));
-+#endif
-+            if (spec_char) {
-+                i = j;
-+                break;
-+            }
-+        }
-+        buf[i] = '\0';
-+        /*
-+         * We have now cleared all the crap off the end of the line
-+         */
-+        if (i < 2)
-+            goto err;
-+
-+        bufp = (unsigned char *)buf;
-+
-+        k = 0;
-+        i -= again;
-+        if (i % 2 != 0) {
-+            ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
-+            OPENSSL_free(s);
-+            return 0;
-+        }
-+        i /= 2;
-+        if (num + i > slen) {
-+            sp = OPENSSL_realloc(s, (unsigned int)num + i * 2);
-+            if (sp == NULL) {
-+                ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE);
-+                OPENSSL_free(s);
-+                return 0;
-+            }
-+            s = sp;
-+            slen = num + i * 2;
-+        }
-+        for (j = 0; j < i; j++, k += 2) {
-+            for (n = 0; n < 2; n++) {
-+                m = OPENSSL_hexchar2int(bufp[k + n]);
-+                if (m < 0) {
-+                    ASN1err(ASN1_F_A2I_ASN1_STRING,
-+                            ASN1_R_NON_HEX_CHARACTERS);
-+                    OPENSSL_free(s);
-+                    return 0;
-+                }
-+                s[num + j] <<= 4;
-+                s[num + j] |= m;
-+            }
-+        }
-+        num += i;
-+        if (again)
-+            bufsize = BIO_gets(bp, buf, size);
-+        else
-+            break;
-+    }
-+    bs->length = num;
-+    bs->data = s;
-+    return 1;
-+
-+ err:
-+    ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE);
-+    OPENSSL_free(s);
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/i2d_pr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/i2d_pr.c
-new file mode 100644
-index 0000000..445b0c8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/i2d_pr.c
-@@ -0,0 +1,33 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
-+{
-+    if (a->ameth && a->ameth->old_priv_encode) {
-+        return a->ameth->old_priv_encode(a, pp);
-+    }
-+    if (a->ameth && a->ameth->priv_encode) {
-+        PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
-+        int ret = 0;
-+        if (p8 != NULL) {
-+            ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
-+            PKCS8_PRIV_KEY_INFO_free(p8);
-+        }
-+        return ret;
-+    }
-+    ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
-+    return -1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/i2d_pu.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/i2d_pu.c
-new file mode 100644
-index 0000000..8986c43
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/i2d_pu.c
-@@ -0,0 +1,38 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
-+{
-+    switch (EVP_PKEY_id(a)) {
-+#ifndef OPENSSL_NO_RSA
-+    case EVP_PKEY_RSA:
-+        return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp);
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    case EVP_PKEY_DSA:
-+        return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp);
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    case EVP_PKEY_EC:
-+        return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp);
-+#endif
-+    default:
-+        ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
-+        return -1;
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/n_pkey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/n_pkey.c
-new file mode 100644
-index 0000000..267ce60
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/n_pkey.c
-@@ -0,0 +1,62 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "openssl/opensslconf.h"
-+#ifdef OPENSSL_NO_RSA
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include "internal/cryptlib.h"
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+
-+# ifndef OPENSSL_NO_RC4
-+
-+typedef struct netscape_pkey_st {
-+    long version;
-+    X509_ALGOR *algor;
-+    ASN1_OCTET_STRING *private_key;
-+} NETSCAPE_PKEY;
-+
-+typedef struct netscape_encrypted_pkey_st {
-+    ASN1_OCTET_STRING *os;
-+    /*
-+     * This is the same structure as DigestInfo so use it: although this
-+     * isn't really anything to do with digests.
-+     */
-+    X509_SIG *enckey;
-+} NETSCAPE_ENCRYPTED_PKEY;
-+
-+
-+ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
-+        ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
-+        ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
-+} static_ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)
-+
-+DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
-+DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY)
-+IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
-+
-+ASN1_SEQUENCE(NETSCAPE_PKEY) = {
-+        ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG),
-+        ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
-+        ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
-+} static_ASN1_SEQUENCE_END(NETSCAPE_PKEY)
-+
-+DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
-+DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
-+IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
-+
-+# endif                         /* OPENSSL_NO_RC4 */
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/nsseq.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/nsseq.c
-new file mode 100644
-index 0000000..c7baf40
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/nsseq.c
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                    void *exarg)
-+{
-+    if (operation == ASN1_OP_NEW_POST) {
-+        NETSCAPE_CERT_SEQUENCE *nsseq;
-+        nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
-+        nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
-+    }
-+    return 1;
-+}
-+
-+/* Netscape certificate sequence structure */
-+
-+ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = {
-+        ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT),
-+        ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0)
-+} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_pbe.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_pbe.c
-new file mode 100644
-index 0000000..ab7e168
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_pbe.c
-@@ -0,0 +1,96 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+/* PKCS#5 password based encryption structure */
-+
-+ASN1_SEQUENCE(PBEPARAM) = {
-+        ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING),
-+        ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER)
-+} ASN1_SEQUENCE_END(PBEPARAM)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
-+
-+/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
-+
-+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
-+                         const unsigned char *salt, int saltlen)
-+{
-+    PBEPARAM *pbe = NULL;
-+    ASN1_STRING *pbe_str = NULL;
-+    unsigned char *sstr = NULL;
-+
-+    pbe = PBEPARAM_new();
-+    if (pbe == NULL) {
-+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if (iter <= 0)
-+        iter = PKCS5_DEFAULT_ITER;
-+    if (!ASN1_INTEGER_set(pbe->iter, iter)) {
-+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if (!saltlen)
-+        saltlen = PKCS5_SALT_LEN;
-+
-+    sstr = OPENSSL_malloc(saltlen);
-+    if (sstr == NULL) {
-+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if (salt)
-+        memcpy(sstr, salt, saltlen);
-+    else if (RAND_bytes(sstr, saltlen) <= 0)
-+        goto err;
-+
-+    ASN1_STRING_set0(pbe->salt, sstr, saltlen);
-+    sstr = NULL;
-+
-+    if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
-+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    PBEPARAM_free(pbe);
-+    pbe = NULL;
-+
-+    if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
-+        return 1;
-+
-+ err:
-+    OPENSSL_free(sstr);
-+    PBEPARAM_free(pbe);
-+    ASN1_STRING_free(pbe_str);
-+    return 0;
-+}
-+
-+/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
-+
-+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
-+                          const unsigned char *salt, int saltlen)
-+{
-+    X509_ALGOR *ret;
-+    ret = X509_ALGOR_new();
-+    if (ret == NULL) {
-+        ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
-+        return ret;
-+
-+    X509_ALGOR_free(ret);
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_pbev2.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_pbev2.c
-new file mode 100644
-index 0000000..14e8700
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_pbev2.c
-@@ -0,0 +1,221 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+/* PKCS#5 v2.0 password based encryption structures */
-+
-+ASN1_SEQUENCE(PBE2PARAM) = {
-+        ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
-+        ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
-+} ASN1_SEQUENCE_END(PBE2PARAM)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM)
-+
-+ASN1_SEQUENCE(PBKDF2PARAM) = {
-+        ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
-+        ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
-+        ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
-+        ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
-+} ASN1_SEQUENCE_END(PBKDF2PARAM)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
-+
-+/*
-+ * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know
-+ * this is horrible! Extended version to allow application supplied PRF NID
-+ * and IV.
-+ */
-+
-+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
-+                              unsigned char *salt, int saltlen,
-+                              unsigned char *aiv, int prf_nid)
-+{
-+    X509_ALGOR *scheme = NULL, *ret = NULL;
-+    int alg_nid, keylen;
-+    EVP_CIPHER_CTX *ctx = NULL;
-+    unsigned char iv[EVP_MAX_IV_LENGTH];
-+    PBE2PARAM *pbe2 = NULL;
-+
-+    alg_nid = EVP_CIPHER_type(cipher);
-+    if (alg_nid == NID_undef) {
-+        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
-+                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
-+        goto err;
-+    }
-+
-+    if ((pbe2 = PBE2PARAM_new()) == NULL)
-+        goto merr;
-+
-+    /* Setup the AlgorithmIdentifier for the encryption scheme */
-+    scheme = pbe2->encryption;
-+    scheme->algorithm = OBJ_nid2obj(alg_nid);
-+    if ((scheme->parameter = ASN1_TYPE_new()) == NULL)
-+        goto merr;
-+
-+    /* Create random IV */
-+    if (EVP_CIPHER_iv_length(cipher)) {
-+        if (aiv)
-+            memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
-+        else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0)
-+            goto err;
-+    }
-+
-+    ctx = EVP_CIPHER_CTX_new();
-+    if (ctx == NULL)
-+        goto merr;
-+
-+    /* Dummy cipherinit to just setup the IV, and PRF */
-+    if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0))
-+        goto err;
-+    if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) < 0) {
-+        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
-+        goto err;
-+    }
-+    /*
-+     * If prf NID unspecified see if cipher has a preference. An error is OK
-+     * here: just means use default PRF.
-+     */
-+    if ((prf_nid == -1) &&
-+        EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
-+        ERR_clear_error();
-+        prf_nid = NID_hmacWithSHA256;
-+    }
-+    EVP_CIPHER_CTX_free(ctx);
-+    ctx = NULL;
-+
-+    /* If its RC2 then we'd better setup the key length */
-+
-+    if (alg_nid == NID_rc2_cbc)
-+        keylen = EVP_CIPHER_key_length(cipher);
-+    else
-+        keylen = -1;
-+
-+    /* Setup keyfunc */
-+
-+    X509_ALGOR_free(pbe2->keyfunc);
-+
-+    pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
-+
-+    if (!pbe2->keyfunc)
-+        goto merr;
-+
-+    /* Now set up top level AlgorithmIdentifier */
-+
-+    if ((ret = X509_ALGOR_new()) == NULL)
-+        goto merr;
-+
-+    ret->algorithm = OBJ_nid2obj(NID_pbes2);
-+
-+    /* Encode PBE2PARAM into parameter */
-+
-+    if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
-+                                 &ret->parameter))
-+         goto merr;
-+
-+    PBE2PARAM_free(pbe2);
-+    pbe2 = NULL;
-+
-+    return ret;
-+
-+ merr:
-+    ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);
-+
-+ err:
-+    EVP_CIPHER_CTX_free(ctx);
-+    PBE2PARAM_free(pbe2);
-+    /* Note 'scheme' is freed as part of pbe2 */
-+    X509_ALGOR_free(ret);
-+
-+    return NULL;
-+}
-+
-+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
-+                           unsigned char *salt, int saltlen)
-+{
-+    return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
-+}
-+
-+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
-+                             int prf_nid, int keylen)
-+{
-+    X509_ALGOR *keyfunc = NULL;
-+    PBKDF2PARAM *kdf = NULL;
-+    ASN1_OCTET_STRING *osalt = NULL;
-+
-+    if ((kdf = PBKDF2PARAM_new()) == NULL)
-+        goto merr;
-+    if ((osalt = ASN1_OCTET_STRING_new()) == NULL)
-+        goto merr;
-+
-+    kdf->salt->value.octet_string = osalt;
-+    kdf->salt->type = V_ASN1_OCTET_STRING;
-+
-+    if (saltlen == 0)
-+        saltlen = PKCS5_SALT_LEN;
-+    if ((osalt->data = OPENSSL_malloc(saltlen)) == NULL)
-+        goto merr;
-+
-+    osalt->length = saltlen;
-+
-+    if (salt)
-+        memcpy(osalt->data, salt, saltlen);
-+    else if (RAND_bytes(osalt->data, saltlen) <= 0)
-+        goto merr;
-+
-+    if (iter <= 0)
-+        iter = PKCS5_DEFAULT_ITER;
-+
-+    if (!ASN1_INTEGER_set(kdf->iter, iter))
-+        goto merr;
-+
-+    /* If have a key len set it up */
-+
-+    if (keylen > 0) {
-+        if ((kdf->keylength = ASN1_INTEGER_new()) == NULL)
-+            goto merr;
-+        if (!ASN1_INTEGER_set(kdf->keylength, keylen))
-+            goto merr;
-+    }
-+
-+    /* prf can stay NULL if we are using hmacWithSHA1 */
-+    if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
-+        kdf->prf = X509_ALGOR_new();
-+        if (kdf->prf == NULL)
-+            goto merr;
-+        X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
-+    }
-+
-+    /* Finally setup the keyfunc structure */
-+
-+    keyfunc = X509_ALGOR_new();
-+    if (keyfunc == NULL)
-+        goto merr;
-+
-+    keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
-+
-+    /* Encode PBKDF2PARAM into parameter of pbe2 */
-+
-+    if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), kdf,
-+                                 &keyfunc->parameter))
-+         goto merr;
-+
-+    PBKDF2PARAM_free(kdf);
-+    return keyfunc;
-+
-+ merr:
-+    ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
-+    PBKDF2PARAM_free(kdf);
-+    X509_ALGOR_free(keyfunc);
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_scrypt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_scrypt.c
-new file mode 100644
-index 0000000..4cb7837
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p5_scrypt.c
-@@ -0,0 +1,283 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifndef OPENSSL_NO_SCRYPT
-+/* PKCS#5 scrypt password based encryption structures */
-+
-+typedef struct {
-+    ASN1_OCTET_STRING *salt;
-+    ASN1_INTEGER *costParameter;
-+    ASN1_INTEGER *blockSize;
-+    ASN1_INTEGER *parallelizationParameter;
-+    ASN1_INTEGER *keyLength;
-+} SCRYPT_PARAMS;
-+
-+ASN1_SEQUENCE(SCRYPT_PARAMS) = {
-+        ASN1_SIMPLE(SCRYPT_PARAMS, salt, ASN1_OCTET_STRING),
-+        ASN1_SIMPLE(SCRYPT_PARAMS, costParameter, ASN1_INTEGER),
-+        ASN1_SIMPLE(SCRYPT_PARAMS, blockSize, ASN1_INTEGER),
-+        ASN1_SIMPLE(SCRYPT_PARAMS, parallelizationParameter, ASN1_INTEGER),
-+        ASN1_OPT(SCRYPT_PARAMS, keyLength, ASN1_INTEGER),
-+} static_ASN1_SEQUENCE_END(SCRYPT_PARAMS)
-+
-+DECLARE_ASN1_ALLOC_FUNCTIONS(SCRYPT_PARAMS)
-+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(SCRYPT_PARAMS)
-+
-+static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen,
-+                                    size_t keylen, uint64_t N, uint64_t r,
-+                                    uint64_t p);
-+
-+/*
-+ * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm using scrypt
-+ */
-+
-+X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
-+                                  const unsigned char *salt, int saltlen,
-+                                  unsigned char *aiv, uint64_t N, uint64_t r,
-+                                  uint64_t p)
-+{
-+    X509_ALGOR *scheme = NULL, *ret = NULL;
-+    int alg_nid;
-+    size_t keylen = 0;
-+    EVP_CIPHER_CTX *ctx = NULL;
-+    unsigned char iv[EVP_MAX_IV_LENGTH];
-+    PBE2PARAM *pbe2 = NULL;
-+
-+    if (!cipher) {
-+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_PASSED_NULL_PARAMETER);
-+        goto err;
-+    }
-+
-+    if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
-+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
-+                ASN1_R_INVALID_SCRYPT_PARAMETERS);
-+        goto err;
-+    }
-+
-+    alg_nid = EVP_CIPHER_type(cipher);
-+    if (alg_nid == NID_undef) {
-+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
-+                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
-+        goto err;
-+    }
-+
-+    pbe2 = PBE2PARAM_new();
-+    if (pbe2 == NULL)
-+        goto merr;
-+
-+    /* Setup the AlgorithmIdentifier for the encryption scheme */
-+    scheme = pbe2->encryption;
-+
-+    scheme->algorithm = OBJ_nid2obj(alg_nid);
-+    scheme->parameter = ASN1_TYPE_new();
-+    if (scheme->parameter == NULL)
-+        goto merr;
-+
-+    /* Create random IV */
-+    if (EVP_CIPHER_iv_length(cipher)) {
-+        if (aiv)
-+            memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
-+        else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
-+            goto err;
-+    }
-+
-+    ctx = EVP_CIPHER_CTX_new();
-+    if (ctx == NULL)
-+        goto merr;
-+
-+    /* Dummy cipherinit to just setup the IV */
-+    if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0)
-+        goto err;
-+    if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) < 0) {
-+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
-+                ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
-+        goto err;
-+    }
-+    EVP_CIPHER_CTX_free(ctx);
-+    ctx = NULL;
-+
-+    /* If its RC2 then we'd better setup the key length */
-+
-+    if (alg_nid == NID_rc2_cbc)
-+        keylen = EVP_CIPHER_key_length(cipher);
-+
-+    /* Setup keyfunc */
-+
-+    X509_ALGOR_free(pbe2->keyfunc);
-+
-+    pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p);
-+
-+    if (pbe2->keyfunc == NULL)
-+        goto merr;
-+
-+    /* Now set up top level AlgorithmIdentifier */
-+
-+    ret = X509_ALGOR_new();
-+    if (ret == NULL)
-+        goto merr;
-+
-+    ret->algorithm = OBJ_nid2obj(NID_pbes2);
-+
-+    /* Encode PBE2PARAM into parameter */
-+
-+    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
-+                                &ret->parameter) == NULL)
-+        goto merr;
-+
-+    PBE2PARAM_free(pbe2);
-+    pbe2 = NULL;
-+
-+    return ret;
-+
-+ merr:
-+    ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_MALLOC_FAILURE);
-+
-+ err:
-+    PBE2PARAM_free(pbe2);
-+    X509_ALGOR_free(ret);
-+    EVP_CIPHER_CTX_free(ctx);
-+
-+    return NULL;
-+}
-+
-+static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen,
-+                                    size_t keylen, uint64_t N, uint64_t r,
-+                                    uint64_t p)
-+{
-+    X509_ALGOR *keyfunc = NULL;
-+    SCRYPT_PARAMS *sparam = SCRYPT_PARAMS_new();
-+
-+    if (sparam == NULL)
-+        goto merr;
-+
-+    if (!saltlen)
-+        saltlen = PKCS5_SALT_LEN;
-+
-+    /* This will either copy salt or grow the buffer */
-+    if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0)
-+        goto merr;
-+
-+    if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0)
-+        goto err;
-+
-+    if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0)
-+        goto merr;
-+
-+    if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0)
-+        goto merr;
-+
-+    if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0)
-+        goto merr;
-+
-+    /* If have a key len set it up */
-+
-+    if (keylen > 0) {
-+        sparam->keyLength = ASN1_INTEGER_new();
-+        if (sparam->keyLength == NULL)
-+            goto merr;
-+        if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0)
-+            goto merr;
-+    }
-+
-+    /* Finally setup the keyfunc structure */
-+
-+    keyfunc = X509_ALGOR_new();
-+    if (keyfunc == NULL)
-+        goto merr;
-+
-+    keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt);
-+
-+    /* Encode SCRYPT_PARAMS into parameter of pbe2 */
-+
-+    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam,
-+                                &keyfunc->parameter) == NULL)
-+        goto merr;
-+
-+    SCRYPT_PARAMS_free(sparam);
-+    return keyfunc;
-+
-+ merr:
-+    ASN1err(ASN1_F_PKCS5_SCRYPT_SET, ERR_R_MALLOC_FAILURE);
-+ err:
-+    SCRYPT_PARAMS_free(sparam);
-+    X509_ALGOR_free(keyfunc);
-+    return NULL;
-+}
-+
-+int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
-+                             int passlen, ASN1_TYPE *param,
-+                             const EVP_CIPHER *c, const EVP_MD *md, int en_de)
-+{
-+    unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
-+    uint64_t p, r, N;
-+    size_t saltlen;
-+    size_t keylen = 0;
-+    int rv = 0;
-+    SCRYPT_PARAMS *sparam = NULL;
-+
-+    if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
-+        EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_NO_CIPHER_SET);
-+        goto err;
-+    }
-+
-+    /* Decode parameter */
-+
-+    sparam = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), param);
-+
-+    if (sparam == NULL) {
-+        EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    keylen = EVP_CIPHER_CTX_key_length(ctx);
-+
-+    /* Now check the parameters of sparam */
-+
-+    if (sparam->keyLength) {
-+        uint64_t spkeylen;
-+        if ((ASN1_INTEGER_get_uint64(&spkeylen, sparam->keyLength) == 0)
-+            || (spkeylen != keylen)) {
-+            EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN,
-+                   EVP_R_UNSUPPORTED_KEYLENGTH);
-+            goto err;
-+        }
-+    }
-+    /* Check all parameters fit in uint64_t and are acceptable to scrypt */
-+    if (ASN1_INTEGER_get_uint64(&N, sparam->costParameter) == 0
-+        || ASN1_INTEGER_get_uint64(&r, sparam->blockSize) == 0
-+        || ASN1_INTEGER_get_uint64(&p, sparam->parallelizationParameter) == 0
-+        || EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
-+        EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN,
-+               EVP_R_ILLEGAL_SCRYPT_PARAMETERS);
-+        goto err;
-+    }
-+
-+    /* it seems that its all OK */
-+
-+    salt = sparam->salt->data;
-+    saltlen = sparam->salt->length;
-+    if (EVP_PBE_scrypt(pass, passlen, salt, saltlen, N, r, p, 0, key, keylen)
-+        == 0)
-+        goto err;
-+    rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
-+ err:
-+    if (keylen)
-+        OPENSSL_cleanse(key, keylen);
-+    SCRYPT_PARAMS_free(sparam);
-+    return rv;
-+}
-+#endif /* OPENSSL_NO_SCRYPT */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p8_pkey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p8_pkey.c
-new file mode 100644
-index 0000000..dbee827
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/p8_pkey.c
-@@ -0,0 +1,80 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/x509_int.h"
-+
-+/* Minor tweak to operation: zero private key data */
-+static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                   void *exarg)
-+{
-+    /* Since the structure must still be valid use ASN1_OP_FREE_PRE */
-+    if (operation == ASN1_OP_FREE_PRE) {
-+        PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
-+        if (key->pkey)
-+            OPENSSL_cleanse(key->pkey->data, key->pkey->length);
-+    }
-+    return 1;
-+}
-+
-+ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
-+        ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
-+        ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
-+        ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_OCTET_STRING),
-+        ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
-+} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
-+
-+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
-+                    int version,
-+                    int ptype, void *pval, unsigned char *penc, int penclen)
-+{
-+    if (version >= 0) {
-+        if (!ASN1_INTEGER_set(priv->version, version))
-+            return 0;
-+    }
-+    if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
-+        return 0;
-+    if (penc)
-+        ASN1_STRING_set0(priv->pkey, penc, penclen);
-+    return 1;
-+}
-+
-+int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg,
-+                    const unsigned char **pk, int *ppklen,
-+                    const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8)
-+{
-+    if (ppkalg)
-+        *ppkalg = p8->pkeyalg->algorithm;
-+    if (pk) {
-+        *pk = ASN1_STRING_get0_data(p8->pkey);
-+        *ppklen = ASN1_STRING_length(p8->pkey);
-+    }
-+    if (pa)
-+        *pa = p8->pkeyalg;
-+    return 1;
-+}
-+
-+const STACK_OF(X509_ATTRIBUTE) *
-+PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8)
-+{
-+    return p8->attributes;
-+}
-+
-+int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type,
-+                                const unsigned char *bytes, int len)
-+{
-+    if (X509at_add1_attr_by_NID(&p8->attributes, nid, type, bytes, len) != NULL)
-+        return 1;
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_bitst.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_bitst.c
-new file mode 100644
-index 0000000..c0aeca4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_bitst.c
-@@ -0,0 +1,56 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
-+                               BIT_STRING_BITNAME *tbl, int indent)
-+{
-+    BIT_STRING_BITNAME *bnam;
-+    char first = 1;
-+    BIO_printf(out, "%*s", indent, "");
-+    for (bnam = tbl; bnam->lname; bnam++) {
-+        if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
-+            if (!first)
-+                BIO_puts(out, ", ");
-+            BIO_puts(out, bnam->lname);
-+            first = 0;
-+        }
-+    }
-+    BIO_puts(out, "\n");
-+    return 1;
-+}
-+
-+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value,
-+                            BIT_STRING_BITNAME *tbl)
-+{
-+    int bitnum;
-+    bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
-+    if (bitnum < 0)
-+        return 0;
-+    if (bs) {
-+        if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
-+            return 0;
-+    }
-+    return 1;
-+}
-+
-+int ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl)
-+{
-+    BIT_STRING_BITNAME *bnam;
-+    for (bnam = tbl; bnam->lname; bnam++) {
-+        if ((strcmp(bnam->sname, name) == 0)
-+            || (strcmp(bnam->lname, name) == 0))
-+            return bnam->bitnum;
-+    }
-+    return -1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_pkey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_pkey.c
-new file mode 100644
-index 0000000..3b2c9df
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_pkey.c
-@@ -0,0 +1,93 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/bn_int.h"
-+
-+/* Number of octets per line */
-+#define ASN1_BUF_PRINT_WIDTH    15
-+/* Maximum indent */
-+#define ASN1_PRINT_MAX_INDENT 128
-+
-+int ASN1_buf_print(BIO *bp, const unsigned char *buf, size_t buflen, int indent)
-+{
-+    size_t i;
-+
-+    for (i = 0; i < buflen; i++) {
-+        if ((i % ASN1_BUF_PRINT_WIDTH) == 0) {
-+            if (i > 0 && BIO_puts(bp, "\n") <= 0)
-+                return 0;
-+            if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
-+                return 0;
-+        }
-+        /*
-+         * Use colon separators for each octet for compatibility as
-+         * this function is used to print out key components.
-+         */
-+        if (BIO_printf(bp, "%02x%s", buf[i],
-+                       (i == buflen - 1) ? "" : ":") <= 0)
-+                return 0;
-+    }
-+    if (BIO_write(bp, "\n", 1) <= 0)
-+        return 0;
-+    return 1;
-+}
-+
-+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
-+                  unsigned char *ign, int indent)
-+{
-+    int n, rv = 0;
-+    const char *neg;
-+    unsigned char *buf = NULL, *tmp = NULL;
-+    int buflen;
-+
-+    if (num == NULL)
-+        return 1;
-+    neg = BN_is_negative(num) ? "-" : "";
-+    if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
-+        return 0;
-+    if (BN_is_zero(num)) {
-+        if (BIO_printf(bp, "%s 0\n", number) <= 0)
-+            return 0;
-+        return 1;
-+    }
-+
-+    if (BN_num_bytes(num) <= BN_BYTES) {
-+        if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
-+                       (unsigned long)bn_get_words(num)[0], neg,
-+                       (unsigned long)bn_get_words(num)[0]) <= 0)
-+            return 0;
-+        return 1;
-+    }
-+
-+    buflen = BN_num_bytes(num) + 1;
-+    buf = tmp = OPENSSL_malloc(buflen);
-+    if (buf == NULL)
-+        goto err;
-+    buf[0] = 0;
-+    if (BIO_printf(bp, "%s%s\n", number,
-+                   (neg[0] == '-') ? " (Negative)" : "") <= 0)
-+        goto err;
-+    n = BN_bn2bin(num, buf + 1);
-+
-+    if (buf[1] & 0x80)
-+        n++;
-+    else
-+        tmp++;
-+
-+    if (ASN1_buf_print(bp, tmp, n, indent + 4) == 0)
-+        goto err;
-+    rv = 1;
-+    err:
-+    OPENSSL_clear_free(buf, buflen);
-+    return rv;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_spki.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_spki.c
-new file mode 100644
-index 0000000..51b56d0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/t_spki.c
-@@ -0,0 +1,56 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+/* Print out an SPKI */
-+
-+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
-+{
-+    EVP_PKEY *pkey;
-+    ASN1_IA5STRING *chal;
-+    ASN1_OBJECT *spkioid;
-+    int i, n;
-+    char *s;
-+    BIO_printf(out, "Netscape SPKI:\n");
-+    X509_PUBKEY_get0_param(&spkioid, NULL, NULL, NULL, spki->spkac->pubkey);
-+    i = OBJ_obj2nid(spkioid);
-+    BIO_printf(out, "  Public Key Algorithm: %s\n",
-+               (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
-+    pkey = X509_PUBKEY_get(spki->spkac->pubkey);
-+    if (!pkey)
-+        BIO_printf(out, "  Unable to load public key\n");
-+    else {
-+        EVP_PKEY_print_public(out, pkey, 4, NULL);
-+        EVP_PKEY_free(pkey);
-+    }
-+    chal = spki->spkac->challenge;
-+    if (chal->length)
-+        BIO_printf(out, "  Challenge String: %s\n", chal->data);
-+    i = OBJ_obj2nid(spki->sig_algor.algorithm);
-+    BIO_printf(out, "  Signature Algorithm: %s",
-+               (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
-+
-+    n = spki->signature->length;
-+    s = (char *)spki->signature->data;
-+    for (i = 0; i < n; i++) {
-+        if ((i % 18) == 0)
-+            BIO_write(out, "\n      ", 7);
-+        BIO_printf(out, "%02x%s", (unsigned char)s[i],
-+                   ((i + 1) == n) ? "" : ":");
-+    }
-+    BIO_write(out, "\n", 1);
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_dec.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_dec.c
-new file mode 100644
-index 0000000..c9b6375
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_dec.c
-@@ -0,0 +1,1142 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/numbers.h"
-+#include "asn1_locl.h"
-+
-+static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
-+                               long len, const ASN1_ITEM *it,
-+                               int tag, int aclass, char opt, ASN1_TLC *ctx);
-+
-+static int asn1_check_eoc(const unsigned char **in, long len);
-+static int asn1_find_end(const unsigned char **in, long len, char inf);
-+
-+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
-+                        char inf, int tag, int aclass, int depth);
-+
-+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
-+
-+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
-+                           char *inf, char *cst,
-+                           const unsigned char **in, long len,
-+                           int exptag, int expclass, char opt, ASN1_TLC *ctx);
-+
-+static int asn1_template_ex_d2i(ASN1_VALUE **pval,
-+                                const unsigned char **in, long len,
-+                                const ASN1_TEMPLATE *tt, char opt,
-+                                ASN1_TLC *ctx);
-+static int asn1_template_noexp_d2i(ASN1_VALUE **val,
-+                                   const unsigned char **in, long len,
-+                                   const ASN1_TEMPLATE *tt, char opt,
-+                                   ASN1_TLC *ctx);
-+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
-+                                 const unsigned char **in, long len,
-+                                 const ASN1_ITEM *it,
-+                                 int tag, int aclass, char opt,
-+                                 ASN1_TLC *ctx);
-+static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-+                       int utype, char *free_cont, const ASN1_ITEM *it);
-+
-+/* Table to convert tags to bit values, used for MSTRING type */
-+static const unsigned long tag2bit[32] = {
-+    /* tags  0 -  3 */
-+    0, 0, 0, B_ASN1_BIT_STRING,
-+    /* tags  4- 7 */
-+    B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,
-+    /* tags  8-11 */
-+    B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
-+    /* tags 12-15 */
-+    B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
-+    /* tags 16-19 */
-+    B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING,
-+    /* tags 20-22 */
-+    B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING,
-+    /* tags 23-24 */
-+    B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,
-+    /* tags 25-27 */
-+    B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING,
-+    /* tags 28-31 */
-+    B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN,
-+};
-+
-+unsigned long ASN1_tag2bit(int tag)
-+{
-+    if ((tag < 0) || (tag > 30))
-+        return 0;
-+    return tag2bit[tag];
-+}
-+
-+/* Macro to initialize and invalidate the cache */
-+
-+#define asn1_tlc_clear(c)       if (c) (c)->valid = 0
-+/* Version to avoid compiler warning about 'c' always non-NULL */
-+#define asn1_tlc_clear_nc(c)    (c)->valid = 0
-+
-+/*
-+ * Decode an ASN1 item, this currently behaves just like a standard 'd2i'
-+ * function. 'in' points to a buffer to read the data from, in future we
-+ * will have more advanced versions that can input data a piece at a time and
-+ * this will simply be a special case.
-+ */
-+
-+ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
-+                          const unsigned char **in, long len,
-+                          const ASN1_ITEM *it)
-+{
-+    ASN1_TLC c;
-+    ASN1_VALUE *ptmpval = NULL;
-+    if (!pval)
-+        pval = &ptmpval;
-+    asn1_tlc_clear_nc(&c);
-+    if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
-+        return *pval;
-+    return NULL;
-+}
-+
-+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
-+                     const ASN1_ITEM *it,
-+                     int tag, int aclass, char opt, ASN1_TLC *ctx)
-+{
-+    int rv;
-+    rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx);
-+    if (rv <= 0)
-+        ASN1_item_ex_free(pval, it);
-+    return rv;
-+}
-+
-+/*
-+ * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
-+ * tag mismatch return -1 to handle OPTIONAL
-+ */
-+
-+static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
-+                               long len, const ASN1_ITEM *it,
-+                               int tag, int aclass, char opt, ASN1_TLC *ctx)
-+{
-+    const ASN1_TEMPLATE *tt, *errtt = NULL;
-+    const ASN1_EXTERN_FUNCS *ef;
-+    const ASN1_AUX *aux = it->funcs;
-+    ASN1_aux_cb *asn1_cb;
-+    const unsigned char *p = NULL, *q;
-+    unsigned char oclass;
-+    char seq_eoc, seq_nolen, cst, isopt;
-+    long tmplen;
-+    int i;
-+    int otag;
-+    int ret = 0;
-+    ASN1_VALUE **pchptr;
-+    if (!pval)
-+        return 0;
-+    if (aux && aux->asn1_cb)
-+        asn1_cb = aux->asn1_cb;
-+    else
-+        asn1_cb = 0;
-+
-+    switch (it->itype) {
-+    case ASN1_ITYPE_PRIMITIVE:
-+        if (it->templates) {
-+            /*
-+             * tagging or OPTIONAL is currently illegal on an item template
-+             * because the flags can't get passed down. In practice this
-+             * isn't a problem: we include the relevant flags from the item
-+             * template in the template itself.
-+             */
-+            if ((tag != -1) || opt) {
-+                ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I,
-+                        ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
-+                goto err;
-+            }
-+            return asn1_template_ex_d2i(pval, in, len,
-+                                        it->templates, opt, ctx);
-+        }
-+        return asn1_d2i_ex_primitive(pval, in, len, it,
-+                                     tag, aclass, opt, ctx);
-+
-+    case ASN1_ITYPE_MSTRING:
-+        p = *in;
-+        /* Just read in tag and class */
-+        ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
-+                              &p, len, -1, 0, 1, ctx);
-+        if (!ret) {
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
-+            goto err;
-+        }
-+
-+        /* Must be UNIVERSAL class */
-+        if (oclass != V_ASN1_UNIVERSAL) {
-+            /* If OPTIONAL, assume this is OK */
-+            if (opt)
-+                return -1;
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
-+            goto err;
-+        }
-+        /* Check tag matches bit map */
-+        if (!(ASN1_tag2bit(otag) & it->utype)) {
-+            /* If OPTIONAL, assume this is OK */
-+            if (opt)
-+                return -1;
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_WRONG_TAG);
-+            goto err;
-+        }
-+        return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx);
-+
-+    case ASN1_ITYPE_EXTERN:
-+        /* Use new style d2i */
-+        ef = it->funcs;
-+        return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
-+
-+    case ASN1_ITYPE_CHOICE:
-+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
-+            goto auxerr;
-+        if (*pval) {
-+            /* Free up and zero CHOICE value if initialised */
-+            i = asn1_get_choice_selector(pval, it);
-+            if ((i >= 0) && (i < it->tcount)) {
-+                tt = it->templates + i;
-+                pchptr = asn1_get_field_ptr(pval, tt);
-+                asn1_template_free(pchptr, tt);
-+                asn1_set_choice_selector(pval, -1, it);
-+            }
-+        } else if (!ASN1_item_ex_new(pval, it)) {
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
-+            goto err;
-+        }
-+        /* CHOICE type, try each possibility in turn */
-+        p = *in;
-+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
-+            pchptr = asn1_get_field_ptr(pval, tt);
-+            /*
-+             * We mark field as OPTIONAL so its absence can be recognised.
-+             */
-+            ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
-+            /* If field not present, try the next one */
-+            if (ret == -1)
-+                continue;
-+            /* If positive return, read OK, break loop */
-+            if (ret > 0)
-+                break;
-+            /*
-+             * Must be an ASN1 parsing error.
-+             * Free up any partial choice value
-+             */
-+            asn1_template_free(pchptr, tt);
-+            errtt = tt;
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
-+            goto err;
-+        }
-+
-+        /* Did we fall off the end without reading anything? */
-+        if (i == it->tcount) {
-+            /* If OPTIONAL, this is OK */
-+            if (opt) {
-+                /* Free and zero it */
-+                ASN1_item_ex_free(pval, it);
-+                return -1;
-+            }
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE);
-+            goto err;
-+        }
-+
-+        asn1_set_choice_selector(pval, i, it);
-+
-+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
-+            goto auxerr;
-+        *in = p;
-+        return 1;
-+
-+    case ASN1_ITYPE_NDEF_SEQUENCE:
-+    case ASN1_ITYPE_SEQUENCE:
-+        p = *in;
-+        tmplen = len;
-+
-+        /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
-+        if (tag == -1) {
-+            tag = V_ASN1_SEQUENCE;
-+            aclass = V_ASN1_UNIVERSAL;
-+        }
-+        /* Get SEQUENCE length and update len, p */
-+        ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
-+                              &p, len, tag, aclass, opt, ctx);
-+        if (!ret) {
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
-+            goto err;
-+        } else if (ret == -1)
-+            return -1;
-+        if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
-+            len = tmplen - (p - *in);
-+            seq_nolen = 1;
-+        }
-+        /* If indefinite we don't do a length check */
-+        else
-+            seq_nolen = seq_eoc;
-+        if (!cst) {
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
-+            goto err;
-+        }
-+
-+        if (!*pval && !ASN1_item_ex_new(pval, it)) {
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
-+            goto err;
-+        }
-+
-+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
-+            goto auxerr;
-+
-+        /* Free up and zero any ADB found */
-+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
-+            if (tt->flags & ASN1_TFLG_ADB_MASK) {
-+                const ASN1_TEMPLATE *seqtt;
-+                ASN1_VALUE **pseqval;
-+                seqtt = asn1_do_adb(pval, tt, 0);
-+                if (seqtt == NULL)
-+                    continue;
-+                pseqval = asn1_get_field_ptr(pval, seqtt);
-+                asn1_template_free(pseqval, seqtt);
-+            }
-+        }
-+
-+        /* Get each field entry */
-+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
-+            const ASN1_TEMPLATE *seqtt;
-+            ASN1_VALUE **pseqval;
-+            seqtt = asn1_do_adb(pval, tt, 1);
-+            if (seqtt == NULL)
-+                goto err;
-+            pseqval = asn1_get_field_ptr(pval, seqtt);
-+            /* Have we ran out of data? */
-+            if (!len)
-+                break;
-+            q = p;
-+            if (asn1_check_eoc(&p, len)) {
-+                if (!seq_eoc) {
-+                    ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_UNEXPECTED_EOC);
-+                    goto err;
-+                }
-+                len -= p - q;
-+                seq_eoc = 0;
-+                q = p;
-+                break;
-+            }
-+            /*
-+             * This determines the OPTIONAL flag value. The field cannot be
-+             * omitted if it is the last of a SEQUENCE and there is still
-+             * data to be read. This isn't strictly necessary but it
-+             * increases efficiency in some cases.
-+             */
-+            if (i == (it->tcount - 1))
-+                isopt = 0;
-+            else
-+                isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
-+            /*
-+             * attempt to read in field, allowing each to be OPTIONAL
-+             */
-+
-+            ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
-+            if (!ret) {
-+                errtt = seqtt;
-+                goto err;
-+            } else if (ret == -1) {
-+                /*
-+                 * OPTIONAL component absent. Free and zero the field.
-+                 */
-+                asn1_template_free(pseqval, seqtt);
-+                continue;
-+            }
-+            /* Update length */
-+            len -= p - q;
-+        }
-+
-+        /* Check for EOC if expecting one */
-+        if (seq_eoc && !asn1_check_eoc(&p, len)) {
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MISSING_EOC);
-+            goto err;
-+        }
-+        /* Check all data read */
-+        if (!seq_nolen && len) {
-+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
-+            goto err;
-+        }
-+
-+        /*
-+         * If we get here we've got no more data in the SEQUENCE, however we
-+         * may not have read all fields so check all remaining are OPTIONAL
-+         * and clear any that are.
-+         */
-+        for (; i < it->tcount; tt++, i++) {
-+            const ASN1_TEMPLATE *seqtt;
-+            seqtt = asn1_do_adb(pval, tt, 1);
-+            if (seqtt == NULL)
-+                goto err;
-+            if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
-+                ASN1_VALUE **pseqval;
-+                pseqval = asn1_get_field_ptr(pval, seqtt);
-+                asn1_template_free(pseqval, seqtt);
-+            } else {
-+                errtt = seqtt;
-+                ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_FIELD_MISSING);
-+                goto err;
-+            }
-+        }
-+        /* Save encoding */
-+        if (!asn1_enc_save(pval, *in, p - *in, it))
-+            goto auxerr;
-+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
-+            goto auxerr;
-+        *in = p;
-+        return 1;
-+
-+    default:
-+        return 0;
-+    }
-+ auxerr:
-+    ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_AUX_ERROR);
-+ err:
-+    if (errtt)
-+        ERR_add_error_data(4, "Field=", errtt->field_name,
-+                           ", Type=", it->sname);
-+    else
-+        ERR_add_error_data(2, "Type=", it->sname);
-+    return 0;
-+}
-+
-+/*
-+ * Templates are handled with two separate functions. One handles any
-+ * EXPLICIT tag and the other handles the rest.
-+ */
-+
-+static int asn1_template_ex_d2i(ASN1_VALUE **val,
-+                                const unsigned char **in, long inlen,
-+                                const ASN1_TEMPLATE *tt, char opt,
-+                                ASN1_TLC *ctx)
-+{
-+    int flags, aclass;
-+    int ret;
-+    long len;
-+    const unsigned char *p, *q;
-+    char exp_eoc;
-+    if (!val)
-+        return 0;
-+    flags = tt->flags;
-+    aclass = flags & ASN1_TFLG_TAG_CLASS;
-+
-+    p = *in;
-+
-+    /* Check if EXPLICIT tag expected */
-+    if (flags & ASN1_TFLG_EXPTAG) {
-+        char cst;
-+        /*
-+         * Need to work out amount of data available to the inner content and
-+         * where it starts: so read in EXPLICIT header to get the info.
-+         */
-+        ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
-+                              &p, inlen, tt->tag, aclass, opt, ctx);
-+        q = p;
-+        if (!ret) {
-+            ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
-+            return 0;
-+        } else if (ret == -1)
-+            return -1;
-+        if (!cst) {
-+            ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
-+                    ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
-+            return 0;
-+        }
-+        /* We've found the field so it can't be OPTIONAL now */
-+        ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
-+        if (!ret) {
-+            ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
-+            return 0;
-+        }
-+        /* We read the field in OK so update length */
-+        len -= p - q;
-+        if (exp_eoc) {
-+            /* If NDEF we must have an EOC here */
-+            if (!asn1_check_eoc(&p, len)) {
-+                ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC);
-+                goto err;
-+            }
-+        } else {
-+            /*
-+             * Otherwise we must hit the EXPLICIT tag end or its an error
-+             */
-+            if (len) {
-+                ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
-+                        ASN1_R_EXPLICIT_LENGTH_MISMATCH);
-+                goto err;
-+            }
-+        }
-+    } else
-+        return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
-+
-+    *in = p;
-+    return 1;
-+
-+ err:
-+    return 0;
-+}
-+
-+static int asn1_template_noexp_d2i(ASN1_VALUE **val,
-+                                   const unsigned char **in, long len,
-+                                   const ASN1_TEMPLATE *tt, char opt,
-+                                   ASN1_TLC *ctx)
-+{
-+    int flags, aclass;
-+    int ret;
-+    ASN1_VALUE *tval;
-+    const unsigned char *p, *q;
-+    if (!val)
-+        return 0;
-+    flags = tt->flags;
-+    aclass = flags & ASN1_TFLG_TAG_CLASS;
-+
-+    p = *in;
-+    q = p;
-+
-+    /*
-+     * If field is embedded then val needs fixing so it is a pointer to
-+     * a pointer to a field.
-+     */
-+    if (tt->flags & ASN1_TFLG_EMBED) {
-+        tval = (ASN1_VALUE *)val;
-+        val = &tval;
-+    }
-+
-+    if (flags & ASN1_TFLG_SK_MASK) {
-+        /* SET OF, SEQUENCE OF */
-+        int sktag, skaclass;
-+        char sk_eoc;
-+        /* First work out expected inner tag value */
-+        if (flags & ASN1_TFLG_IMPTAG) {
-+            sktag = tt->tag;
-+            skaclass = aclass;
-+        } else {
-+            skaclass = V_ASN1_UNIVERSAL;
-+            if (flags & ASN1_TFLG_SET_OF)
-+                sktag = V_ASN1_SET;
-+            else
-+                sktag = V_ASN1_SEQUENCE;
-+        }
-+        /* Get the tag */
-+        ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
-+                              &p, len, sktag, skaclass, opt, ctx);
-+        if (!ret) {
-+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
-+            return 0;
-+        } else if (ret == -1)
-+            return -1;
-+        if (!*val)
-+            *val = (ASN1_VALUE *)OPENSSL_sk_new_null();
-+        else {
-+            /*
-+             * We've got a valid STACK: free up any items present
-+             */
-+            STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
-+            ASN1_VALUE *vtmp;
-+            while (sk_ASN1_VALUE_num(sktmp) > 0) {
-+                vtmp = sk_ASN1_VALUE_pop(sktmp);
-+                ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
-+            }
-+        }
-+
-+        if (!*val) {
-+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+
-+        /* Read as many items as we can */
-+        while (len > 0) {
-+            ASN1_VALUE *skfield;
-+            q = p;
-+            /* See if EOC found */
-+            if (asn1_check_eoc(&p, len)) {
-+                if (!sk_eoc) {
-+                    ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
-+                            ASN1_R_UNEXPECTED_EOC);
-+                    goto err;
-+                }
-+                len -= p - q;
-+                sk_eoc = 0;
-+                break;
-+            }
-+            skfield = NULL;
-+            if (!asn1_item_embed_d2i(&skfield, &p, len,
-+                                     ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
-+                ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
-+                        ERR_R_NESTED_ASN1_ERROR);
-+                /* |skfield| may be partially allocated despite failure. */
-+                ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item));
-+                goto err;
-+            }
-+            len -= p - q;
-+            if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
-+                ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
-+                ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item));
-+                goto err;
-+            }
-+        }
-+        if (sk_eoc) {
-+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
-+            goto err;
-+        }
-+    } else if (flags & ASN1_TFLG_IMPTAG) {
-+        /* IMPLICIT tagging */
-+        ret = asn1_item_embed_d2i(val, &p, len,
-+                                  ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
-+                                  ctx);
-+        if (!ret) {
-+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
-+            goto err;
-+        } else if (ret == -1)
-+            return -1;
-+    } else {
-+        /* Nothing special */
-+        ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
-+                                  -1, 0, opt, ctx);
-+        if (!ret) {
-+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
-+            goto err;
-+        } else if (ret == -1)
-+            return -1;
-+    }
-+
-+    *in = p;
-+    return 1;
-+
-+ err:
-+    return 0;
-+}
-+
-+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
-+                                 const unsigned char **in, long inlen,
-+                                 const ASN1_ITEM *it,
-+                                 int tag, int aclass, char opt, ASN1_TLC *ctx)
-+{
-+    int ret = 0, utype;
-+    long plen;
-+    char cst, inf, free_cont = 0;
-+    const unsigned char *p;
-+    BUF_MEM buf = { 0, NULL, 0, 0 };
-+    const unsigned char *cont = NULL;
-+    long len;
-+    if (!pval) {
-+        ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
-+        return 0;               /* Should never happen */
-+    }
-+
-+    if (it->itype == ASN1_ITYPE_MSTRING) {
-+        utype = tag;
-+        tag = -1;
-+    } else
-+        utype = it->utype;
-+
-+    if (utype == V_ASN1_ANY) {
-+        /* If type is ANY need to figure out type from tag */
-+        unsigned char oclass;
-+        if (tag >= 0) {
-+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY);
-+            return 0;
-+        }
-+        if (opt) {
-+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
-+                    ASN1_R_ILLEGAL_OPTIONAL_ANY);
-+            return 0;
-+        }
-+        p = *in;
-+        ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
-+                              &p, inlen, -1, 0, 0, ctx);
-+        if (!ret) {
-+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
-+            return 0;
-+        }
-+        if (oclass != V_ASN1_UNIVERSAL)
-+            utype = V_ASN1_OTHER;
-+    }
-+    if (tag == -1) {
-+        tag = utype;
-+        aclass = V_ASN1_UNIVERSAL;
-+    }
-+    p = *in;
-+    /* Check header */
-+    ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
-+                          &p, inlen, tag, aclass, opt, ctx);
-+    if (!ret) {
-+        ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
-+        return 0;
-+    } else if (ret == -1)
-+        return -1;
-+    ret = 0;
-+    /* SEQUENCE, SET and "OTHER" are left in encoded form */
-+    if ((utype == V_ASN1_SEQUENCE)
-+        || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
-+        /*
-+         * Clear context cache for type OTHER because the auto clear when we
-+         * have a exact match won't work
-+         */
-+        if (utype == V_ASN1_OTHER) {
-+            asn1_tlc_clear(ctx);
-+        }
-+        /* SEQUENCE and SET must be constructed */
-+        else if (!cst) {
-+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
-+                    ASN1_R_TYPE_NOT_CONSTRUCTED);
-+            return 0;
-+        }
-+
-+        cont = *in;
-+        /* If indefinite length constructed find the real end */
-+        if (inf) {
-+            if (!asn1_find_end(&p, plen, inf))
-+                goto err;
-+            len = p - cont;
-+        } else {
-+            len = p - cont + plen;
-+            p += plen;
-+        }
-+    } else if (cst) {
-+        if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
-+            || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
-+            || utype == V_ASN1_ENUMERATED) {
-+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE);
-+            return 0;
-+        }
-+
-+        /* Free any returned 'buf' content */
-+        free_cont = 1;
-+        /*
-+         * Should really check the internal tags are correct but some things
-+         * may get this wrong. The relevant specs say that constructed string
-+         * types should be OCTET STRINGs internally irrespective of the type.
-+         * So instead just check for UNIVERSAL class and ignore the tag.
-+         */
-+        if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
-+            goto err;
-+        }
-+        len = buf.length;
-+        /* Append a final null to string */
-+        if (!BUF_MEM_grow_clean(&buf, len + 1)) {
-+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        buf.data[len] = 0;
-+        cont = (const unsigned char *)buf.data;
-+    } else {
-+        cont = p;
-+        len = plen;
-+        p += plen;
-+    }
-+
-+    /* We now have content length and type: translate into a structure */
-+    /* asn1_ex_c2i may reuse allocated buffer, and so sets free_cont to 0 */
-+    if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
-+        goto err;
-+
-+    *in = p;
-+    ret = 1;
-+ err:
-+    if (free_cont)
-+        OPENSSL_free(buf.data);
-+    return ret;
-+}
-+
-+/* Translate ASN1 content octets into a structure */
-+
-+static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-+                       int utype, char *free_cont, const ASN1_ITEM *it)
-+{
-+    ASN1_VALUE **opval = NULL;
-+    ASN1_STRING *stmp;
-+    ASN1_TYPE *typ = NULL;
-+    int ret = 0;
-+    const ASN1_PRIMITIVE_FUNCS *pf;
-+    ASN1_INTEGER **tint;
-+    pf = it->funcs;
-+
-+    if (pf && pf->prim_c2i)
-+        return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
-+    /* If ANY type clear type and set pointer to internal value */
-+    if (it->utype == V_ASN1_ANY) {
-+        if (!*pval) {
-+            typ = ASN1_TYPE_new();
-+            if (typ == NULL)
-+                goto err;
-+            *pval = (ASN1_VALUE *)typ;
-+        } else
-+            typ = (ASN1_TYPE *)*pval;
-+
-+        if (utype != typ->type)
-+            ASN1_TYPE_set(typ, utype, NULL);
-+        opval = pval;
-+        pval = &typ->value.asn1_value;
-+    }
-+    switch (utype) {
-+    case V_ASN1_OBJECT:
-+        if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
-+            goto err;
-+        break;
-+
-+    case V_ASN1_NULL:
-+        if (len) {
-+            ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH);
-+            goto err;
-+        }
-+        *pval = (ASN1_VALUE *)1;
-+        break;
-+
-+    case V_ASN1_BOOLEAN:
-+        if (len != 1) {
-+            ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
-+            goto err;
-+        } else {
-+            ASN1_BOOLEAN *tbool;
-+            tbool = (ASN1_BOOLEAN *)pval;
-+            *tbool = *cont;
-+        }
-+        break;
-+
-+    case V_ASN1_BIT_STRING:
-+        if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
-+            goto err;
-+        break;
-+
-+    case V_ASN1_INTEGER:
-+    case V_ASN1_ENUMERATED:
-+        tint = (ASN1_INTEGER **)pval;
-+        if (!c2i_ASN1_INTEGER(tint, &cont, len))
-+            goto err;
-+        /* Fixup type to match the expected form */
-+        (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
-+        break;
-+
-+    case V_ASN1_OCTET_STRING:
-+    case V_ASN1_NUMERICSTRING:
-+    case V_ASN1_PRINTABLESTRING:
-+    case V_ASN1_T61STRING:
-+    case V_ASN1_VIDEOTEXSTRING:
-+    case V_ASN1_IA5STRING:
-+    case V_ASN1_UTCTIME:
-+    case V_ASN1_GENERALIZEDTIME:
-+    case V_ASN1_GRAPHICSTRING:
-+    case V_ASN1_VISIBLESTRING:
-+    case V_ASN1_GENERALSTRING:
-+    case V_ASN1_UNIVERSALSTRING:
-+    case V_ASN1_BMPSTRING:
-+    case V_ASN1_UTF8STRING:
-+    case V_ASN1_OTHER:
-+    case V_ASN1_SET:
-+    case V_ASN1_SEQUENCE:
-+    default:
-+        if (utype == V_ASN1_BMPSTRING && (len & 1)) {
-+            ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
-+            goto err;
-+        }
-+        if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) {
-+            ASN1err(ASN1_F_ASN1_EX_C2I,
-+                    ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
-+            goto err;
-+        }
-+        /* All based on ASN1_STRING and handled the same */
-+        if (!*pval) {
-+            stmp = ASN1_STRING_type_new(utype);
-+            if (stmp == NULL) {
-+                ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            *pval = (ASN1_VALUE *)stmp;
-+        } else {
-+            stmp = (ASN1_STRING *)*pval;
-+            stmp->type = utype;
-+        }
-+        /* If we've already allocated a buffer use it */
-+        if (*free_cont) {
-+            OPENSSL_free(stmp->data);
-+            stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
-+            stmp->length = len;
-+            *free_cont = 0;
-+        } else {
-+            if (!ASN1_STRING_set(stmp, cont, len)) {
-+                ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
-+                ASN1_STRING_free(stmp);
-+                *pval = NULL;
-+                goto err;
-+            }
-+        }
-+        break;
-+    }
-+    /* If ASN1_ANY and NULL type fix up value */
-+    if (typ && (utype == V_ASN1_NULL))
-+        typ->value.ptr = NULL;
-+
-+    ret = 1;
-+ err:
-+    if (!ret) {
-+        ASN1_TYPE_free(typ);
-+        if (opval)
-+            *opval = NULL;
-+    }
-+    return ret;
-+}
-+
-+/*
-+ * This function finds the end of an ASN1 structure when passed its maximum
-+ * length, whether it is indefinite length and a pointer to the content. This
-+ * is more efficient than calling asn1_collect because it does not recurse on
-+ * each indefinite length header.
-+ */
-+
-+static int asn1_find_end(const unsigned char **in, long len, char inf)
-+{
-+    uint32_t expected_eoc;
-+    long plen;
-+    const unsigned char *p = *in, *q;
-+    /* If not indefinite length constructed just add length */
-+    if (inf == 0) {
-+        *in += len;
-+        return 1;
-+    }
-+    expected_eoc = 1;
-+    /*
-+     * Indefinite length constructed form. Find the end when enough EOCs are
-+     * found. If more indefinite length constructed headers are encountered
-+     * increment the expected eoc count otherwise just skip to the end of the
-+     * data.
-+     */
-+    while (len > 0) {
-+        if (asn1_check_eoc(&p, len)) {
-+            expected_eoc--;
-+            if (expected_eoc == 0)
-+                break;
-+            len -= 2;
-+            continue;
-+        }
-+        q = p;
-+        /* Just read in a header: only care about the length */
-+        if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
-+                             -1, 0, 0, NULL)) {
-+            ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
-+            return 0;
-+        }
-+        if (inf) {
-+            if (expected_eoc == UINT32_MAX) {
-+                ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
-+                return 0;
-+            }
-+            expected_eoc++;
-+        } else {
-+            p += plen;
-+        }
-+        len -= p - q;
-+    }
-+    if (expected_eoc) {
-+        ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
-+        return 0;
-+    }
-+    *in = p;
-+    return 1;
-+}
-+
-+/*
-+ * This function collects the asn1 data from a constructed string type into
-+ * a buffer. The values of 'in' and 'len' should refer to the contents of the
-+ * constructed type and 'inf' should be set if it is indefinite length.
-+ */
-+
-+#ifndef ASN1_MAX_STRING_NEST
-+/*
-+ * This determines how many levels of recursion are permitted in ASN1 string
-+ * types. If it is not limited stack overflows can occur. If set to zero no
-+ * recursion is allowed at all. Although zero should be adequate examples
-+ * exist that require a value of 1. So 5 should be more than enough.
-+ */
-+# define ASN1_MAX_STRING_NEST 5
-+#endif
-+
-+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
-+                        char inf, int tag, int aclass, int depth)
-+{
-+    const unsigned char *p, *q;
-+    long plen;
-+    char cst, ininf;
-+    p = *in;
-+    inf &= 1;
-+    /*
-+     * If no buffer and not indefinite length constructed just pass over the
-+     * encoded data
-+     */
-+    if (!buf && !inf) {
-+        *in += len;
-+        return 1;
-+    }
-+    while (len > 0) {
-+        q = p;
-+        /* Check for EOC */
-+        if (asn1_check_eoc(&p, len)) {
-+            /*
-+             * EOC is illegal outside indefinite length constructed form
-+             */
-+            if (!inf) {
-+                ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC);
-+                return 0;
-+            }
-+            inf = 0;
-+            break;
-+        }
-+
-+        if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
-+                             len, tag, aclass, 0, NULL)) {
-+            ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
-+            return 0;
-+        }
-+
-+        /* If indefinite length constructed update max length */
-+        if (cst) {
-+            if (depth >= ASN1_MAX_STRING_NEST) {
-+                ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING);
-+                return 0;
-+            }
-+            if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1))
-+                return 0;
-+        } else if (plen && !collect_data(buf, &p, plen))
-+            return 0;
-+        len -= p - q;
-+    }
-+    if (inf) {
-+        ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
-+        return 0;
-+    }
-+    *in = p;
-+    return 1;
-+}
-+
-+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
-+{
-+    int len;
-+    if (buf) {
-+        len = buf->length;
-+        if (!BUF_MEM_grow_clean(buf, len + plen)) {
-+            ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        memcpy(buf->data + len, *p, plen);
-+    }
-+    *p += plen;
-+    return 1;
-+}
-+
-+/* Check for ASN1 EOC and swallow it if found */
-+
-+static int asn1_check_eoc(const unsigned char **in, long len)
-+{
-+    const unsigned char *p;
-+    if (len < 2)
-+        return 0;
-+    p = *in;
-+    if (!p[0] && !p[1]) {
-+        *in += 2;
-+        return 1;
-+    }
-+    return 0;
-+}
-+
-+/*
-+ * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the
-+ * length for indefinite length constructed form, we don't know the exact
-+ * length but we can set an upper bound to the amount of data available minus
-+ * the header length just read.
-+ */
-+
-+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
-+                           char *inf, char *cst,
-+                           const unsigned char **in, long len,
-+                           int exptag, int expclass, char opt, ASN1_TLC *ctx)
-+{
-+    int i;
-+    int ptag, pclass;
-+    long plen;
-+    const unsigned char *p, *q;
-+    p = *in;
-+    q = p;
-+
-+    if (ctx && ctx->valid) {
-+        i = ctx->ret;
-+        plen = ctx->plen;
-+        pclass = ctx->pclass;
-+        ptag = ctx->ptag;
-+        p += ctx->hdrlen;
-+    } else {
-+        i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
-+        if (ctx) {
-+            ctx->ret = i;
-+            ctx->plen = plen;
-+            ctx->pclass = pclass;
-+            ctx->ptag = ptag;
-+            ctx->hdrlen = p - q;
-+            ctx->valid = 1;
-+            /*
-+             * If definite length, and no error, length + header can't exceed
-+             * total amount of data available.
-+             */
-+            if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
-+                ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG);
-+                asn1_tlc_clear(ctx);
-+                return 0;
-+            }
-+        }
-+    }
-+
-+    if (i & 0x80) {
-+        ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
-+        asn1_tlc_clear(ctx);
-+        return 0;
-+    }
-+    if (exptag >= 0) {
-+        if ((exptag != ptag) || (expclass != pclass)) {
-+            /*
-+             * If type is OPTIONAL, not an error: indicate missing type.
-+             */
-+            if (opt)
-+                return -1;
-+            asn1_tlc_clear(ctx);
-+            ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
-+            return 0;
-+        }
-+        /*
-+         * We have a tag and class match: assume we are going to do something
-+         * with it
-+         */
-+        asn1_tlc_clear(ctx);
-+    }
-+
-+    if (i & 1)
-+        plen = len - (p - q);
-+
-+    if (inf)
-+        *inf = i & 1;
-+
-+    if (cst)
-+        *cst = i & V_ASN1_CONSTRUCTED;
-+
-+    if (olen)
-+        *olen = plen;
-+
-+    if (oclass)
-+        *oclass = pclass;
-+
-+    if (otag)
-+        *otag = ptag;
-+
-+    *in = p;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_enc.c
-new file mode 100644
-index 0000000..caa4869
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_enc.c
-@@ -0,0 +1,605 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "asn1_locl.h"
-+
-+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
-+                                 const ASN1_ITEM *it, int tag, int aclass);
-+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
-+                            int skcontlen, const ASN1_ITEM *item,
-+                            int do_sort, int iclass);
-+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
-+                                const ASN1_TEMPLATE *tt, int tag, int aclass);
-+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
-+                               const ASN1_ITEM *it, int flags);
-+static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
-+                       const ASN1_ITEM *it);
-+
-+/*
-+ * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use
-+ * indefinite length constructed encoding, where appropriate
-+ */
-+
-+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
-+                       const ASN1_ITEM *it)
-+{
-+    return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
-+}
-+
-+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
-+{
-+    return asn1_item_flags_i2d(val, out, it, 0);
-+}
-+
-+/*
-+ * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out'
-+ * points to a buffer to output the data to. The new i2d has one additional
-+ * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is
-+ * allocated and populated with the encoding.
-+ */
-+
-+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
-+                               const ASN1_ITEM *it, int flags)
-+{
-+    if (out && !*out) {
-+        unsigned char *p, *buf;
-+        int len;
-+        len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
-+        if (len <= 0)
-+            return len;
-+        buf = OPENSSL_malloc(len);
-+        if (buf == NULL)
-+            return -1;
-+        p = buf;
-+        ASN1_item_ex_i2d(&val, &p, it, -1, flags);
-+        *out = buf;
-+        return len;
-+    }
-+
-+    return ASN1_item_ex_i2d(&val, out, it, -1, flags);
-+}
-+
-+/*
-+ * Encode an item, taking care of IMPLICIT tagging (if any). This function
-+ * performs the normal item handling: it can be used in external types.
-+ */
-+
-+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
-+                     const ASN1_ITEM *it, int tag, int aclass)
-+{
-+    const ASN1_TEMPLATE *tt = NULL;
-+    int i, seqcontlen, seqlen, ndef = 1;
-+    const ASN1_EXTERN_FUNCS *ef;
-+    const ASN1_AUX *aux = it->funcs;
-+    ASN1_aux_cb *asn1_cb = 0;
-+
-+    if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
-+        return 0;
-+
-+    if (aux && aux->asn1_cb)
-+        asn1_cb = aux->asn1_cb;
-+
-+    switch (it->itype) {
-+
-+    case ASN1_ITYPE_PRIMITIVE:
-+        if (it->templates)
-+            return asn1_template_ex_i2d(pval, out, it->templates,
-+                                        tag, aclass);
-+        return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
-+
-+    case ASN1_ITYPE_MSTRING:
-+        return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
-+
-+    case ASN1_ITYPE_CHOICE:
-+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
-+            return 0;
-+        i = asn1_get_choice_selector(pval, it);
-+        if ((i >= 0) && (i < it->tcount)) {
-+            ASN1_VALUE **pchval;
-+            const ASN1_TEMPLATE *chtt;
-+            chtt = it->templates + i;
-+            pchval = asn1_get_field_ptr(pval, chtt);
-+            return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
-+        }
-+        /* Fixme: error condition if selector out of range */
-+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
-+            return 0;
-+        break;
-+
-+    case ASN1_ITYPE_EXTERN:
-+        /* If new style i2d it does all the work */
-+        ef = it->funcs;
-+        return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
-+
-+    case ASN1_ITYPE_NDEF_SEQUENCE:
-+        /* Use indefinite length constructed if requested */
-+        if (aclass & ASN1_TFLG_NDEF)
-+            ndef = 2;
-+        /* fall through */
-+
-+    case ASN1_ITYPE_SEQUENCE:
-+        i = asn1_enc_restore(&seqcontlen, out, pval, it);
-+        /* An error occurred */
-+        if (i < 0)
-+            return 0;
-+        /* We have a valid cached encoding... */
-+        if (i > 0)
-+            return seqcontlen;
-+        /* Otherwise carry on */
-+        seqcontlen = 0;
-+        /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
-+        if (tag == -1) {
-+            tag = V_ASN1_SEQUENCE;
-+            /* Retain any other flags in aclass */
-+            aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
-+                | V_ASN1_UNIVERSAL;
-+        }
-+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
-+            return 0;
-+        /* First work out sequence content length */
-+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
-+            const ASN1_TEMPLATE *seqtt;
-+            ASN1_VALUE **pseqval;
-+            int tmplen;
-+            seqtt = asn1_do_adb(pval, tt, 1);
-+            if (!seqtt)
-+                return 0;
-+            pseqval = asn1_get_field_ptr(pval, seqtt);
-+            tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass);
-+            if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen))
-+                return -1;
-+            seqcontlen += tmplen;
-+        }
-+
-+        seqlen = ASN1_object_size(ndef, seqcontlen, tag);
-+        if (!out || seqlen == -1)
-+            return seqlen;
-+        /* Output SEQUENCE header */
-+        ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
-+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
-+            const ASN1_TEMPLATE *seqtt;
-+            ASN1_VALUE **pseqval;
-+            seqtt = asn1_do_adb(pval, tt, 1);
-+            if (!seqtt)
-+                return 0;
-+            pseqval = asn1_get_field_ptr(pval, seqtt);
-+            /* FIXME: check for errors in enhanced version */
-+            asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
-+        }
-+        if (ndef == 2)
-+            ASN1_put_eoc(out);
-+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
-+            return 0;
-+        return seqlen;
-+
-+    default:
-+        return 0;
-+
-+    }
-+    return 0;
-+}
-+
-+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
-+                                const ASN1_TEMPLATE *tt, int tag, int iclass)
-+{
-+    int i, ret, flags, ttag, tclass, ndef;
-+    ASN1_VALUE *tval;
-+    flags = tt->flags;
-+
-+    /*
-+     * If field is embedded then val needs fixing so it is a pointer to
-+     * a pointer to a field.
-+     */
-+    if (flags & ASN1_TFLG_EMBED) {
-+        tval = (ASN1_VALUE *)pval;
-+        pval = &tval;
-+    }
-+    /*
-+     * Work out tag and class to use: tagging may come either from the
-+     * template or the arguments, not both because this would create
-+     * ambiguity. Additionally the iclass argument may contain some
-+     * additional flags which should be noted and passed down to other
-+     * levels.
-+     */
-+    if (flags & ASN1_TFLG_TAG_MASK) {
-+        /* Error if argument and template tagging */
-+        if (tag != -1)
-+            /* FIXME: error code here */
-+            return -1;
-+        /* Get tagging from template */
-+        ttag = tt->tag;
-+        tclass = flags & ASN1_TFLG_TAG_CLASS;
-+    } else if (tag != -1) {
-+        /* No template tagging, get from arguments */
-+        ttag = tag;
-+        tclass = iclass & ASN1_TFLG_TAG_CLASS;
-+    } else {
-+        ttag = -1;
-+        tclass = 0;
-+    }
-+    /*
-+     * Remove any class mask from iflag.
-+     */
-+    iclass &= ~ASN1_TFLG_TAG_CLASS;
-+
-+    /*
-+     * At this point 'ttag' contains the outer tag to use, 'tclass' is the
-+     * class and iclass is any flags passed to this function.
-+     */
-+
-+    /* if template and arguments require ndef, use it */
-+    if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
-+        ndef = 2;
-+    else
-+        ndef = 1;
-+
-+    if (flags & ASN1_TFLG_SK_MASK) {
-+        /* SET OF, SEQUENCE OF */
-+        STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
-+        int isset, sktag, skaclass;
-+        int skcontlen, sklen;
-+        ASN1_VALUE *skitem;
-+
-+        if (!*pval)
-+            return 0;
-+
-+        if (flags & ASN1_TFLG_SET_OF) {
-+            isset = 1;
-+            /* 2 means we reorder */
-+            if (flags & ASN1_TFLG_SEQUENCE_OF)
-+                isset = 2;
-+        } else
-+            isset = 0;
-+
-+        /*
-+         * Work out inner tag value: if EXPLICIT or no tagging use underlying
-+         * type.
-+         */
-+        if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
-+            sktag = ttag;
-+            skaclass = tclass;
-+        } else {
-+            skaclass = V_ASN1_UNIVERSAL;
-+            if (isset)
-+                sktag = V_ASN1_SET;
-+            else
-+                sktag = V_ASN1_SEQUENCE;
-+        }
-+
-+        /* Determine total length of items */
-+        skcontlen = 0;
-+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
-+            int tmplen;
-+            skitem = sk_ASN1_VALUE_value(sk, i);
-+            tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
-+                                      -1, iclass);
-+            if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
-+                return -1;
-+            skcontlen += tmplen;
-+        }
-+        sklen = ASN1_object_size(ndef, skcontlen, sktag);
-+        if (sklen == -1)
-+            return -1;
-+        /* If EXPLICIT need length of surrounding tag */
-+        if (flags & ASN1_TFLG_EXPTAG)
-+            ret = ASN1_object_size(ndef, sklen, ttag);
-+        else
-+            ret = sklen;
-+
-+        if (!out || ret == -1)
-+            return ret;
-+
-+        /* Now encode this lot... */
-+        /* EXPLICIT tag */
-+        if (flags & ASN1_TFLG_EXPTAG)
-+            ASN1_put_object(out, ndef, sklen, ttag, tclass);
-+        /* SET or SEQUENCE and IMPLICIT tag */
-+        ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
-+        /* And the stuff itself */
-+        asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
-+                         isset, iclass);
-+        if (ndef == 2) {
-+            ASN1_put_eoc(out);
-+            if (flags & ASN1_TFLG_EXPTAG)
-+                ASN1_put_eoc(out);
-+        }
-+
-+        return ret;
-+    }
-+
-+    if (flags & ASN1_TFLG_EXPTAG) {
-+        /* EXPLICIT tagging */
-+        /* Find length of tagged item */
-+        i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass);
-+        if (!i)
-+            return 0;
-+        /* Find length of EXPLICIT tag */
-+        ret = ASN1_object_size(ndef, i, ttag);
-+        if (out && ret != -1) {
-+            /* Output tag and item */
-+            ASN1_put_object(out, ndef, i, ttag, tclass);
-+            ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);
-+            if (ndef == 2)
-+                ASN1_put_eoc(out);
-+        }
-+        return ret;
-+    }
-+
-+    /* Either normal or IMPLICIT tagging: combine class and flags */
-+    return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
-+                            ttag, tclass | iclass);
-+
-+}
-+
-+/* Temporary structure used to hold DER encoding of items for SET OF */
-+
-+typedef struct {
-+    unsigned char *data;
-+    int length;
-+    ASN1_VALUE *field;
-+} DER_ENC;
-+
-+static int der_cmp(const void *a, const void *b)
-+{
-+    const DER_ENC *d1 = a, *d2 = b;
-+    int cmplen, i;
-+    cmplen = (d1->length < d2->length) ? d1->length : d2->length;
-+    i = memcmp(d1->data, d2->data, cmplen);
-+    if (i)
-+        return i;
-+    return d1->length - d2->length;
-+}
-+
-+/* Output the content octets of SET OF or SEQUENCE OF */
-+
-+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
-+                            int skcontlen, const ASN1_ITEM *item,
-+                            int do_sort, int iclass)
-+{
-+    int i;
-+    ASN1_VALUE *skitem;
-+    unsigned char *tmpdat = NULL, *p = NULL;
-+    DER_ENC *derlst = NULL, *tder;
-+    if (do_sort) {
-+        /* Don't need to sort less than 2 items */
-+        if (sk_ASN1_VALUE_num(sk) < 2)
-+            do_sort = 0;
-+        else {
-+            derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
-+                                    * sizeof(*derlst));
-+            if (derlst == NULL)
-+                return 0;
-+            tmpdat = OPENSSL_malloc(skcontlen);
-+            if (tmpdat == NULL) {
-+                OPENSSL_free(derlst);
-+                return 0;
-+            }
-+        }
-+    }
-+    /* If not sorting just output each item */
-+    if (!do_sort) {
-+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
-+            skitem = sk_ASN1_VALUE_value(sk, i);
-+            ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
-+        }
-+        return 1;
-+    }
-+    p = tmpdat;
-+
-+    /* Doing sort: build up a list of each member's DER encoding */
-+    for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
-+        skitem = sk_ASN1_VALUE_value(sk, i);
-+        tder->data = p;
-+        tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
-+        tder->field = skitem;
-+    }
-+
-+    /* Now sort them */
-+    qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
-+    /* Output sorted DER encoding */
-+    p = *out;
-+    for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
-+        memcpy(p, tder->data, tder->length);
-+        p += tder->length;
-+    }
-+    *out = p;
-+    /* If do_sort is 2 then reorder the STACK */
-+    if (do_sort == 2) {
-+        for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
-+            (void)sk_ASN1_VALUE_set(sk, i, tder->field);
-+    }
-+    OPENSSL_free(derlst);
-+    OPENSSL_free(tmpdat);
-+    return 1;
-+}
-+
-+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
-+                                 const ASN1_ITEM *it, int tag, int aclass)
-+{
-+    int len;
-+    int utype;
-+    int usetag;
-+    int ndef = 0;
-+
-+    utype = it->utype;
-+
-+    /*
-+     * Get length of content octets and maybe find out the underlying type.
-+     */
-+
-+    len = asn1_ex_i2c(pval, NULL, &utype, it);
-+
-+    /*
-+     * If SEQUENCE, SET or OTHER then header is included in pseudo content
-+     * octets so don't include tag+length. We need to check here because the
-+     * call to asn1_ex_i2c() could change utype.
-+     */
-+    if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
-+        (utype == V_ASN1_OTHER))
-+        usetag = 0;
-+    else
-+        usetag = 1;
-+
-+    /* -1 means omit type */
-+
-+    if (len == -1)
-+        return 0;
-+
-+    /* -2 return is special meaning use ndef */
-+    if (len == -2) {
-+        ndef = 2;
-+        len = 0;
-+    }
-+
-+    /* If not implicitly tagged get tag from underlying type */
-+    if (tag == -1)
-+        tag = utype;
-+
-+    /* Output tag+length followed by content octets */
-+    if (out) {
-+        if (usetag)
-+            ASN1_put_object(out, ndef, len, tag, aclass);
-+        asn1_ex_i2c(pval, *out, &utype, it);
-+        if (ndef)
-+            ASN1_put_eoc(out);
-+        else
-+            *out += len;
-+    }
-+
-+    if (usetag)
-+        return ASN1_object_size(ndef, len, tag);
-+    return len;
-+}
-+
-+/* Produce content octets from a structure */
-+
-+static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
-+                       const ASN1_ITEM *it)
-+{
-+    ASN1_BOOLEAN *tbool = NULL;
-+    ASN1_STRING *strtmp;
-+    ASN1_OBJECT *otmp;
-+    int utype;
-+    const unsigned char *cont;
-+    unsigned char c;
-+    int len;
-+    const ASN1_PRIMITIVE_FUNCS *pf;
-+    pf = it->funcs;
-+    if (pf && pf->prim_i2c)
-+        return pf->prim_i2c(pval, cout, putype, it);
-+
-+    /* Should type be omitted? */
-+    if ((it->itype != ASN1_ITYPE_PRIMITIVE)
-+        || (it->utype != V_ASN1_BOOLEAN)) {
-+        if (!*pval)
-+            return -1;
-+    }
-+
-+    if (it->itype == ASN1_ITYPE_MSTRING) {
-+        /* If MSTRING type set the underlying type */
-+        strtmp = (ASN1_STRING *)*pval;
-+        utype = strtmp->type;
-+        *putype = utype;
-+    } else if (it->utype == V_ASN1_ANY) {
-+        /* If ANY set type and pointer to value */
-+        ASN1_TYPE *typ;
-+        typ = (ASN1_TYPE *)*pval;
-+        utype = typ->type;
-+        *putype = utype;
-+        pval = &typ->value.asn1_value;
-+    } else
-+        utype = *putype;
-+
-+    switch (utype) {
-+    case V_ASN1_OBJECT:
-+        otmp = (ASN1_OBJECT *)*pval;
-+        cont = otmp->data;
-+        len = otmp->length;
-+        break;
-+
-+    case V_ASN1_NULL:
-+        cont = NULL;
-+        len = 0;
-+        break;
-+
-+    case V_ASN1_BOOLEAN:
-+        tbool = (ASN1_BOOLEAN *)pval;
-+        if (*tbool == -1)
-+            return -1;
-+        if (it->utype != V_ASN1_ANY) {
-+            /*
-+             * Default handling if value == size field then omit
-+             */
-+            if (*tbool && (it->size > 0))
-+                return -1;
-+            if (!*tbool && !it->size)
-+                return -1;
-+        }
-+        c = (unsigned char)*tbool;
-+        cont = &c;
-+        len = 1;
-+        break;
-+
-+    case V_ASN1_BIT_STRING:
-+        return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
-+                                   cout ? &cout : NULL);
-+
-+    case V_ASN1_INTEGER:
-+    case V_ASN1_ENUMERATED:
-+        /*
-+         * These are all have the same content format as ASN1_INTEGER
-+         */
-+        return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
-+
-+    case V_ASN1_OCTET_STRING:
-+    case V_ASN1_NUMERICSTRING:
-+    case V_ASN1_PRINTABLESTRING:
-+    case V_ASN1_T61STRING:
-+    case V_ASN1_VIDEOTEXSTRING:
-+    case V_ASN1_IA5STRING:
-+    case V_ASN1_UTCTIME:
-+    case V_ASN1_GENERALIZEDTIME:
-+    case V_ASN1_GRAPHICSTRING:
-+    case V_ASN1_VISIBLESTRING:
-+    case V_ASN1_GENERALSTRING:
-+    case V_ASN1_UNIVERSALSTRING:
-+    case V_ASN1_BMPSTRING:
-+    case V_ASN1_UTF8STRING:
-+    case V_ASN1_SEQUENCE:
-+    case V_ASN1_SET:
-+    default:
-+        /* All based on ASN1_STRING and handled the same */
-+        strtmp = (ASN1_STRING *)*pval;
-+        /* Special handling for NDEF */
-+        if ((it->size == ASN1_TFLG_NDEF)
-+            && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
-+            if (cout) {
-+                strtmp->data = cout;
-+                strtmp->length = 0;
-+            }
-+            /* Special return code */
-+            return -2;
-+        }
-+        cont = strtmp->data;
-+        len = strtmp->length;
-+
-+        break;
-+
-+    }
-+    if (cout && len)
-+        memcpy(cout, cont, len);
-+    return len;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_fre.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_fre.c
-new file mode 100644
-index 0000000..3c98efb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_fre.c
-@@ -0,0 +1,207 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "asn1_locl.h"
-+
-+static void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                                 int embed);
-+
-+/* Free up an ASN1 structure */
-+
-+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
-+{
-+    asn1_item_embed_free(&val, it, 0);
-+}
-+
-+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    asn1_item_embed_free(pval, it, 0);
-+}
-+
-+static void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                                 int embed)
-+{
-+    const ASN1_TEMPLATE *tt = NULL, *seqtt;
-+    const ASN1_EXTERN_FUNCS *ef;
-+    const ASN1_AUX *aux = it->funcs;
-+    ASN1_aux_cb *asn1_cb;
-+    int i;
-+
-+    if (!pval)
-+        return;
-+    if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
-+        return;
-+    if (aux && aux->asn1_cb)
-+        asn1_cb = aux->asn1_cb;
-+    else
-+        asn1_cb = 0;
-+
-+    switch (it->itype) {
-+
-+    case ASN1_ITYPE_PRIMITIVE:
-+        if (it->templates)
-+            asn1_template_free(pval, it->templates);
-+        else
-+            asn1_primitive_free(pval, it, embed);
-+        break;
-+
-+    case ASN1_ITYPE_MSTRING:
-+        asn1_primitive_free(pval, it, embed);
-+        break;
-+
-+    case ASN1_ITYPE_CHOICE:
-+        if (asn1_cb) {
-+            i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
-+            if (i == 2)
-+                return;
-+        }
-+        i = asn1_get_choice_selector(pval, it);
-+        if ((i >= 0) && (i < it->tcount)) {
-+            ASN1_VALUE **pchval;
-+
-+            tt = it->templates + i;
-+            pchval = asn1_get_field_ptr(pval, tt);
-+            asn1_template_free(pchval, tt);
-+        }
-+        if (asn1_cb)
-+            asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
-+        if (embed == 0) {
-+            OPENSSL_free(*pval);
-+            *pval = NULL;
-+        }
-+        break;
-+
-+    case ASN1_ITYPE_EXTERN:
-+        ef = it->funcs;
-+        if (ef && ef->asn1_ex_free)
-+            ef->asn1_ex_free(pval, it);
-+        break;
-+
-+    case ASN1_ITYPE_NDEF_SEQUENCE:
-+    case ASN1_ITYPE_SEQUENCE:
-+        if (asn1_do_lock(pval, -1, it) != 0) /* if error or ref-counter > 0 */
-+            return;
-+        if (asn1_cb) {
-+            i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
-+            if (i == 2)
-+                return;
-+        }
-+        asn1_enc_free(pval, it);
-+        /*
-+         * If we free up as normal we will invalidate any ANY DEFINED BY
-+         * field and we won't be able to determine the type of the field it
-+         * defines. So free up in reverse order.
-+         */
-+        tt = it->templates + it->tcount;
-+        for (i = 0; i < it->tcount; i++) {
-+            ASN1_VALUE **pseqval;
-+
-+            tt--;
-+            seqtt = asn1_do_adb(pval, tt, 0);
-+            if (!seqtt)
-+                continue;
-+            pseqval = asn1_get_field_ptr(pval, seqtt);
-+            asn1_template_free(pseqval, seqtt);
-+        }
-+        if (asn1_cb)
-+            asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
-+        if (embed == 0) {
-+            OPENSSL_free(*pval);
-+            *pval = NULL;
-+        }
-+        break;
-+    }
-+}
-+
-+void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
-+{
-+    int embed = tt->flags & ASN1_TFLG_EMBED;
-+    ASN1_VALUE *tval;
-+    if (embed) {
-+        tval = (ASN1_VALUE *)pval;
-+        pval = &tval;
-+    }
-+    if (tt->flags & ASN1_TFLG_SK_MASK) {
-+        STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
-+        int i;
-+
-+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
-+            ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i);
-+
-+            asn1_item_embed_free(&vtmp, ASN1_ITEM_ptr(tt->item), embed);
-+        }
-+        sk_ASN1_VALUE_free(sk);
-+        *pval = NULL;
-+    } else {
-+        asn1_item_embed_free(pval, ASN1_ITEM_ptr(tt->item), embed);
-+    }
-+}
-+
-+void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
-+{
-+    int utype;
-+
-+    /* Special case: if 'it' is a primitive with a free_func, use that. */
-+    if (it) {
-+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
-+
-+        if (pf && pf->prim_free) {
-+            pf->prim_free(pval, it);
-+            return;
-+        }
-+    }
-+
-+    /* Special case: if 'it' is NULL, free contents of ASN1_TYPE */
-+    if (!it) {
-+        ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
-+
-+        utype = typ->type;
-+        pval = &typ->value.asn1_value;
-+        if (!*pval)
-+            return;
-+    } else if (it->itype == ASN1_ITYPE_MSTRING) {
-+        utype = -1;
-+        if (!*pval)
-+            return;
-+    } else {
-+        utype = it->utype;
-+        if ((utype != V_ASN1_BOOLEAN) && !*pval)
-+            return;
-+    }
-+
-+    switch (utype) {
-+    case V_ASN1_OBJECT:
-+        ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
-+        break;
-+
-+    case V_ASN1_BOOLEAN:
-+        if (it)
-+            *(ASN1_BOOLEAN *)pval = it->size;
-+        else
-+            *(ASN1_BOOLEAN *)pval = -1;
-+        return;
-+
-+    case V_ASN1_NULL:
-+        break;
-+
-+    case V_ASN1_ANY:
-+        asn1_primitive_free(pval, NULL, 0);
-+        OPENSSL_free(*pval);
-+        break;
-+
-+    default:
-+        asn1_string_embed_free((ASN1_STRING *)*pval, embed);
-+        break;
-+    }
-+    *pval = NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_new.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_new.c
-new file mode 100644
-index 0000000..e9b8377
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_new.c
-@@ -0,0 +1,337 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "asn1_locl.h"
-+
-+static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                               int embed);
-+static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                              int embed);
-+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
-+static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
-+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
-+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
-+
-+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
-+{
-+    ASN1_VALUE *ret = NULL;
-+    if (ASN1_item_ex_new(&ret, it) > 0)
-+        return ret;
-+    return NULL;
-+}
-+
-+/* Allocate an ASN1 structure */
-+
-+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    return asn1_item_embed_new(pval, it, 0);
-+}
-+
-+int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
-+{
-+    const ASN1_TEMPLATE *tt = NULL;
-+    const ASN1_EXTERN_FUNCS *ef;
-+    const ASN1_AUX *aux = it->funcs;
-+    ASN1_aux_cb *asn1_cb;
-+    ASN1_VALUE **pseqval;
-+    int i;
-+    if (aux && aux->asn1_cb)
-+        asn1_cb = aux->asn1_cb;
-+    else
-+        asn1_cb = 0;
-+
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+    OPENSSL_mem_debug_push(it->sname ? it->sname : "asn1_item_embed_new");
-+#endif
-+
-+    switch (it->itype) {
-+
-+    case ASN1_ITYPE_EXTERN:
-+        ef = it->funcs;
-+        if (ef && ef->asn1_ex_new) {
-+            if (!ef->asn1_ex_new(pval, it))
-+                goto memerr;
-+        }
-+        break;
-+
-+    case ASN1_ITYPE_PRIMITIVE:
-+        if (it->templates) {
-+            if (!asn1_template_new(pval, it->templates))
-+                goto memerr;
-+        } else if (!asn1_primitive_new(pval, it, embed))
-+            goto memerr;
-+        break;
-+
-+    case ASN1_ITYPE_MSTRING:
-+        if (!asn1_primitive_new(pval, it, embed))
-+            goto memerr;
-+        break;
-+
-+    case ASN1_ITYPE_CHOICE:
-+        if (asn1_cb) {
-+            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
-+            if (!i)
-+                goto auxerr;
-+            if (i == 2) {
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+                OPENSSL_mem_debug_pop();
-+#endif
-+                return 1;
-+            }
-+        }
-+        if (embed) {
-+            memset(*pval, 0, it->size);
-+        } else {
-+            *pval = OPENSSL_zalloc(it->size);
-+            if (*pval == NULL)
-+                goto memerr;
-+        }
-+        asn1_set_choice_selector(pval, -1, it);
-+        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
-+            goto auxerr2;
-+        break;
-+
-+    case ASN1_ITYPE_NDEF_SEQUENCE:
-+    case ASN1_ITYPE_SEQUENCE:
-+        if (asn1_cb) {
-+            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
-+            if (!i)
-+                goto auxerr;
-+            if (i == 2) {
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+                OPENSSL_mem_debug_pop();
-+#endif
-+                return 1;
-+            }
-+        }
-+        if (embed) {
-+            memset(*pval, 0, it->size);
-+        } else {
-+            *pval = OPENSSL_zalloc(it->size);
-+            if (*pval == NULL)
-+                goto memerr;
-+        }
-+        /* 0 : init. lock */
-+        if (asn1_do_lock(pval, 0, it) < 0)
-+            goto memerr2;
-+        asn1_enc_init(pval, it);
-+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
-+            pseqval = asn1_get_field_ptr(pval, tt);
-+            if (!asn1_template_new(pseqval, tt))
-+                goto memerr2;
-+        }
-+        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
-+            goto auxerr2;
-+        break;
-+    }
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+    OPENSSL_mem_debug_pop();
-+#endif
-+    return 1;
-+
-+ memerr2:
-+    ASN1_item_ex_free(pval, it);
-+ memerr:
-+    ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE);
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+    OPENSSL_mem_debug_pop();
-+#endif
-+    return 0;
-+
-+ auxerr2:
-+    ASN1_item_ex_free(pval, it);
-+ auxerr:
-+    ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR);
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+    OPENSSL_mem_debug_pop();
-+#endif
-+    return 0;
-+
-+}
-+
-+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    const ASN1_EXTERN_FUNCS *ef;
-+
-+    switch (it->itype) {
-+
-+    case ASN1_ITYPE_EXTERN:
-+        ef = it->funcs;
-+        if (ef && ef->asn1_ex_clear)
-+            ef->asn1_ex_clear(pval, it);
-+        else
-+            *pval = NULL;
-+        break;
-+
-+    case ASN1_ITYPE_PRIMITIVE:
-+        if (it->templates)
-+            asn1_template_clear(pval, it->templates);
-+        else
-+            asn1_primitive_clear(pval, it);
-+        break;
-+
-+    case ASN1_ITYPE_MSTRING:
-+        asn1_primitive_clear(pval, it);
-+        break;
-+
-+    case ASN1_ITYPE_CHOICE:
-+    case ASN1_ITYPE_SEQUENCE:
-+    case ASN1_ITYPE_NDEF_SEQUENCE:
-+        *pval = NULL;
-+        break;
-+    }
-+}
-+
-+static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
-+{
-+    const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
-+    int embed = tt->flags & ASN1_TFLG_EMBED;
-+    ASN1_VALUE *tval;
-+    int ret;
-+    if (embed) {
-+        tval = (ASN1_VALUE *)pval;
-+        pval = &tval;
-+    }
-+    if (tt->flags & ASN1_TFLG_OPTIONAL) {
-+        asn1_template_clear(pval, tt);
-+        return 1;
-+    }
-+    /* If ANY DEFINED BY nothing to do */
-+
-+    if (tt->flags & ASN1_TFLG_ADB_MASK) {
-+        *pval = NULL;
-+        return 1;
-+    }
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+    OPENSSL_mem_debug_push(tt->field_name
-+            ? tt->field_name : "asn1_template_new");
-+#endif
-+    /* If SET OF or SEQUENCE OF, its a STACK */
-+    if (tt->flags & ASN1_TFLG_SK_MASK) {
-+        STACK_OF(ASN1_VALUE) *skval;
-+        skval = sk_ASN1_VALUE_new_null();
-+        if (!skval) {
-+            ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
-+            ret = 0;
-+            goto done;
-+        }
-+        *pval = (ASN1_VALUE *)skval;
-+        ret = 1;
-+        goto done;
-+    }
-+    /* Otherwise pass it back to the item routine */
-+    ret = asn1_item_embed_new(pval, it, embed);
-+ done:
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+    OPENSSL_mem_debug_pop();
-+#endif
-+    return ret;
-+}
-+
-+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
-+{
-+    /* If ADB or STACK just NULL the field */
-+    if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
-+        *pval = NULL;
-+    else
-+        asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
-+}
-+
-+/*
-+ * NB: could probably combine most of the real XXX_new() behaviour and junk
-+ * all the old functions.
-+ */
-+
-+static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                              int embed)
-+{
-+    ASN1_TYPE *typ;
-+    ASN1_STRING *str;
-+    int utype;
-+
-+    if (!it)
-+        return 0;
-+
-+    if (it->funcs) {
-+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
-+        if (pf->prim_new)
-+            return pf->prim_new(pval, it);
-+    }
-+
-+    if (it->itype == ASN1_ITYPE_MSTRING)
-+        utype = -1;
-+    else
-+        utype = it->utype;
-+    switch (utype) {
-+    case V_ASN1_OBJECT:
-+        *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
-+        return 1;
-+
-+    case V_ASN1_BOOLEAN:
-+        *(ASN1_BOOLEAN *)pval = it->size;
-+        return 1;
-+
-+    case V_ASN1_NULL:
-+        *pval = (ASN1_VALUE *)1;
-+        return 1;
-+
-+    case V_ASN1_ANY:
-+        typ = OPENSSL_malloc(sizeof(*typ));
-+        if (typ == NULL)
-+            return 0;
-+        typ->value.ptr = NULL;
-+        typ->type = -1;
-+        *pval = (ASN1_VALUE *)typ;
-+        break;
-+
-+    default:
-+        if (embed) {
-+            str = *(ASN1_STRING **)pval;
-+            memset(str, 0, sizeof(*str));
-+            str->type = utype;
-+            str->flags = ASN1_STRING_FLAG_EMBED;
-+        } else {
-+            str = ASN1_STRING_type_new(utype);
-+            *pval = (ASN1_VALUE *)str;
-+        }
-+        if (it->itype == ASN1_ITYPE_MSTRING && str)
-+            str->flags |= ASN1_STRING_FLAG_MSTRING;
-+        break;
-+    }
-+    if (*pval)
-+        return 1;
-+    return 0;
-+}
-+
-+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    int utype;
-+    if (it && it->funcs) {
-+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
-+        if (pf->prim_clear)
-+            pf->prim_clear(pval, it);
-+        else
-+            *pval = NULL;
-+        return;
-+    }
-+    if (!it || (it->itype == ASN1_ITYPE_MSTRING))
-+        utype = -1;
-+    else
-+        utype = it->utype;
-+    if (utype == V_ASN1_BOOLEAN)
-+        *(ASN1_BOOLEAN *)pval = it->size;
-+    else
-+        *pval = NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_prn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_prn.c
-new file mode 100644
-index 0000000..f53e905
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_prn.c
-@@ -0,0 +1,538 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "asn1_locl.h"
-+
-+/*
-+ * Print routines.
-+ */
-+
-+/* ASN1_PCTX routines */
-+
-+static ASN1_PCTX default_pctx = {
-+    ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
-+    0,                          /* nm_flags */
-+    0,                          /* cert_flags */
-+    0,                          /* oid_flags */
-+    0                           /* str_flags */
-+};
-+
-+ASN1_PCTX *ASN1_PCTX_new(void)
-+{
-+    ASN1_PCTX *ret;
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL) {
-+        ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+void ASN1_PCTX_free(ASN1_PCTX *p)
-+{
-+    OPENSSL_free(p);
-+}
-+
-+unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p)
-+{
-+    return p->flags;
-+}
-+
-+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
-+{
-+    p->flags = flags;
-+}
-+
-+unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p)
-+{
-+    return p->nm_flags;
-+}
-+
-+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
-+{
-+    p->nm_flags = flags;
-+}
-+
-+unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p)
-+{
-+    return p->cert_flags;
-+}
-+
-+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
-+{
-+    p->cert_flags = flags;
-+}
-+
-+unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p)
-+{
-+    return p->oid_flags;
-+}
-+
-+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
-+{
-+    p->oid_flags = flags;
-+}
-+
-+unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p)
-+{
-+    return p->str_flags;
-+}
-+
-+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
-+{
-+    p->str_flags = flags;
-+}
-+
-+/* Main print routines */
-+
-+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
-+                               const ASN1_ITEM *it,
-+                               const char *fname, const char *sname,
-+                               int nohdr, const ASN1_PCTX *pctx);
-+
-+static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
-+                            const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
-+
-+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
-+                                const ASN1_ITEM *it, int indent,
-+                                const char *fname, const char *sname,
-+                                const ASN1_PCTX *pctx);
-+
-+static int asn1_print_fsname(BIO *out, int indent,
-+                             const char *fname, const char *sname,
-+                             const ASN1_PCTX *pctx);
-+
-+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
-+                    const ASN1_ITEM *it, const ASN1_PCTX *pctx)
-+{
-+    const char *sname;
-+    if (pctx == NULL)
-+        pctx = &default_pctx;
-+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
-+        sname = NULL;
-+    else
-+        sname = it->sname;
-+    return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
-+}
-+
-+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
-+                               const ASN1_ITEM *it,
-+                               const char *fname, const char *sname,
-+                               int nohdr, const ASN1_PCTX *pctx)
-+{
-+    const ASN1_TEMPLATE *tt;
-+    const ASN1_EXTERN_FUNCS *ef;
-+    ASN1_VALUE **tmpfld;
-+    const ASN1_AUX *aux = it->funcs;
-+    ASN1_aux_cb *asn1_cb;
-+    ASN1_PRINT_ARG parg;
-+    int i;
-+    if (aux && aux->asn1_cb) {
-+        parg.out = out;
-+        parg.indent = indent;
-+        parg.pctx = pctx;
-+        asn1_cb = aux->asn1_cb;
-+    } else
-+        asn1_cb = 0;
-+
-+   if (((it->itype != ASN1_ITYPE_PRIMITIVE)
-+       || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) {
-+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
-+            if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
-+                return 0;
-+            if (BIO_puts(out, "\n") <= 0)
-+                return 0;
-+        }
-+        return 1;
-+    }
-+
-+    switch (it->itype) {
-+    case ASN1_ITYPE_PRIMITIVE:
-+        if (it->templates) {
-+            if (!asn1_template_print_ctx(out, fld, indent,
-+                                         it->templates, pctx))
-+                return 0;
-+            break;
-+        }
-+        /* fall through */
-+    case ASN1_ITYPE_MSTRING:
-+        if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
-+            return 0;
-+        break;
-+
-+    case ASN1_ITYPE_EXTERN:
-+        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
-+            return 0;
-+        /* Use new style print routine if possible */
-+        ef = it->funcs;
-+        if (ef && ef->asn1_ex_print) {
-+            i = ef->asn1_ex_print(out, fld, indent, "", pctx);
-+            if (!i)
-+                return 0;
-+            if ((i == 2) && (BIO_puts(out, "\n") <= 0))
-+                return 0;
-+            return 1;
-+        } else if (sname &&
-+                   BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
-+            return 0;
-+        break;
-+
-+    case ASN1_ITYPE_CHOICE:
-+        /* CHOICE type, get selector */
-+        i = asn1_get_choice_selector(fld, it);
-+        /* This should never happen... */
-+        if ((i < 0) || (i >= it->tcount)) {
-+            if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
-+                return 0;
-+            return 1;
-+        }
-+        tt = it->templates + i;
-+        tmpfld = asn1_get_field_ptr(fld, tt);
-+        if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
-+            return 0;
-+        break;
-+
-+    case ASN1_ITYPE_SEQUENCE:
-+    case ASN1_ITYPE_NDEF_SEQUENCE:
-+        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
-+            return 0;
-+        if (fname || sname) {
-+            if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
-+                if (BIO_puts(out, " {\n") <= 0)
-+                    return 0;
-+            } else {
-+                if (BIO_puts(out, "\n") <= 0)
-+                    return 0;
-+            }
-+        }
-+
-+        if (asn1_cb) {
-+            i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
-+            if (i == 0)
-+                return 0;
-+            if (i == 2)
-+                return 1;
-+        }
-+
-+        /* Print each field entry */
-+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
-+            const ASN1_TEMPLATE *seqtt;
-+            seqtt = asn1_do_adb(fld, tt, 1);
-+            if (!seqtt)
-+                return 0;
-+            tmpfld = asn1_get_field_ptr(fld, seqtt);
-+            if (!asn1_template_print_ctx(out, tmpfld,
-+                                         indent + 2, seqtt, pctx))
-+                return 0;
-+        }
-+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
-+            if (BIO_printf(out, "%*s}\n", indent, "") < 0)
-+                return 0;
-+        }
-+
-+        if (asn1_cb) {
-+            i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
-+            if (i == 0)
-+                return 0;
-+        }
-+        break;
-+
-+    default:
-+        BIO_printf(out, "Unprocessed type %d\n", it->itype);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
-+                            const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
-+{
-+    int i, flags;
-+    const char *sname, *fname;
-+    ASN1_VALUE *tfld;
-+    flags = tt->flags;
-+    if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
-+        sname = ASN1_ITEM_ptr(tt->item)->sname;
-+    else
-+        sname = NULL;
-+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
-+        fname = NULL;
-+    else
-+        fname = tt->field_name;
-+
-+    /*
-+     * If field is embedded then fld needs fixing so it is a pointer to
-+     * a pointer to a field.
-+     */
-+    if (flags & ASN1_TFLG_EMBED) {
-+        tfld = (ASN1_VALUE *)fld;
-+        fld = &tfld;
-+    }
-+
-+    if (flags & ASN1_TFLG_SK_MASK) {
-+        char *tname;
-+        ASN1_VALUE *skitem;
-+        STACK_OF(ASN1_VALUE) *stack;
-+
-+        /* SET OF, SEQUENCE OF */
-+        if (fname) {
-+            if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
-+                if (flags & ASN1_TFLG_SET_OF)
-+                    tname = "SET";
-+                else
-+                    tname = "SEQUENCE";
-+                if (BIO_printf(out, "%*s%s OF %s {\n",
-+                               indent, "", tname, tt->field_name) <= 0)
-+                    return 0;
-+            } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
-+                return 0;
-+        }
-+        stack = (STACK_OF(ASN1_VALUE) *)*fld;
-+        for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
-+            if ((i > 0) && (BIO_puts(out, "\n") <= 0))
-+                return 0;
-+
-+            skitem = sk_ASN1_VALUE_value(stack, i);
-+            if (!asn1_item_print_ctx(out, &skitem, indent + 2,
-+                                     ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
-+                                     pctx))
-+                return 0;
-+        }
-+        if (!i && BIO_printf(out, "%*s\n", indent + 2, "") <= 0)
-+            return 0;
-+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
-+            if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
-+                return 0;
-+        }
-+        return 1;
-+    }
-+    return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
-+                               fname, sname, 0, pctx);
-+}
-+
-+static int asn1_print_fsname(BIO *out, int indent,
-+                             const char *fname, const char *sname,
-+                             const ASN1_PCTX *pctx)
-+{
-+    static const char spaces[] = "                    ";
-+    static const int nspaces = sizeof(spaces) - 1;
-+
-+    while (indent > nspaces) {
-+        if (BIO_write(out, spaces, nspaces) != nspaces)
-+            return 0;
-+        indent -= nspaces;
-+    }
-+    if (BIO_write(out, spaces, indent) != indent)
-+        return 0;
-+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
-+        sname = NULL;
-+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
-+        fname = NULL;
-+    if (!sname && !fname)
-+        return 1;
-+    if (fname) {
-+        if (BIO_puts(out, fname) <= 0)
-+            return 0;
-+    }
-+    if (sname) {
-+        if (fname) {
-+            if (BIO_printf(out, " (%s)", sname) <= 0)
-+                return 0;
-+        } else {
-+            if (BIO_puts(out, sname) <= 0)
-+                return 0;
-+        }
-+    }
-+    if (BIO_write(out, ": ", 2) != 2)
-+        return 0;
-+    return 1;
-+}
-+
-+static int asn1_print_boolean(BIO *out, int boolval)
-+{
-+    const char *str;
-+    switch (boolval) {
-+    case -1:
-+        str = "BOOL ABSENT";
-+        break;
-+
-+    case 0:
-+        str = "FALSE";
-+        break;
-+
-+    default:
-+        str = "TRUE";
-+        break;
-+
-+    }
-+
-+    if (BIO_puts(out, str) <= 0)
-+        return 0;
-+    return 1;
-+
-+}
-+
-+static int asn1_print_integer(BIO *out, const ASN1_INTEGER *str)
-+{
-+    char *s;
-+    int ret = 1;
-+    s = i2s_ASN1_INTEGER(NULL, str);
-+    if (s == NULL)
-+        return 0;
-+    if (BIO_puts(out, s) <= 0)
-+        ret = 0;
-+    OPENSSL_free(s);
-+    return ret;
-+}
-+
-+static int asn1_print_oid(BIO *out, const ASN1_OBJECT *oid)
-+{
-+    char objbuf[80];
-+    const char *ln;
-+    ln = OBJ_nid2ln(OBJ_obj2nid(oid));
-+    if (!ln)
-+        ln = "";
-+    OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
-+    if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
-+        return 0;
-+    return 1;
-+}
-+
-+static int asn1_print_obstring(BIO *out, const ASN1_STRING *str, int indent)
-+{
-+    if (str->type == V_ASN1_BIT_STRING) {
-+        if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
-+            return 0;
-+    } else if (BIO_puts(out, "\n") <= 0)
-+        return 0;
-+    if ((str->length > 0)
-+        && BIO_dump_indent(out, (const char *)str->data, str->length,
-+                           indent + 2) <= 0)
-+        return 0;
-+    return 1;
-+}
-+
-+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
-+                                const ASN1_ITEM *it, int indent,
-+                                const char *fname, const char *sname,
-+                                const ASN1_PCTX *pctx)
-+{
-+    long utype;
-+    ASN1_STRING *str;
-+    int ret = 1, needlf = 1;
-+    const char *pname;
-+    const ASN1_PRIMITIVE_FUNCS *pf;
-+    pf = it->funcs;
-+    if (!asn1_print_fsname(out, indent, fname, sname, pctx))
-+        return 0;
-+    if (pf && pf->prim_print)
-+        return pf->prim_print(out, fld, it, indent, pctx);
-+    if (it->itype == ASN1_ITYPE_MSTRING) {
-+        str = (ASN1_STRING *)*fld;
-+        utype = str->type & ~V_ASN1_NEG;
-+    } else {
-+        utype = it->utype;
-+        if (utype == V_ASN1_BOOLEAN)
-+            str = NULL;
-+        else
-+            str = (ASN1_STRING *)*fld;
-+    }
-+    if (utype == V_ASN1_ANY) {
-+        ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
-+        utype = atype->type;
-+        fld = &atype->value.asn1_value;
-+        str = (ASN1_STRING *)*fld;
-+        if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
-+            pname = NULL;
-+        else
-+            pname = ASN1_tag2str(utype);
-+    } else {
-+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
-+            pname = ASN1_tag2str(utype);
-+        else
-+            pname = NULL;
-+    }
-+
-+    if (utype == V_ASN1_NULL) {
-+        if (BIO_puts(out, "NULL\n") <= 0)
-+            return 0;
-+        return 1;
-+    }
-+
-+    if (pname) {
-+        if (BIO_puts(out, pname) <= 0)
-+            return 0;
-+        if (BIO_puts(out, ":") <= 0)
-+            return 0;
-+    }
-+
-+    switch (utype) {
-+    case V_ASN1_BOOLEAN:
-+        {
-+            int boolval = *(int *)fld;
-+            if (boolval == -1)
-+                boolval = it->size;
-+            ret = asn1_print_boolean(out, boolval);
-+        }
-+        break;
-+
-+    case V_ASN1_INTEGER:
-+    case V_ASN1_ENUMERATED:
-+        ret = asn1_print_integer(out, str);
-+        break;
-+
-+    case V_ASN1_UTCTIME:
-+        ret = ASN1_UTCTIME_print(out, str);
-+        break;
-+
-+    case V_ASN1_GENERALIZEDTIME:
-+        ret = ASN1_GENERALIZEDTIME_print(out, str);
-+        break;
-+
-+    case V_ASN1_OBJECT:
-+        ret = asn1_print_oid(out, (const ASN1_OBJECT *)*fld);
-+        break;
-+
-+    case V_ASN1_OCTET_STRING:
-+    case V_ASN1_BIT_STRING:
-+        ret = asn1_print_obstring(out, str, indent);
-+        needlf = 0;
-+        break;
-+
-+    case V_ASN1_SEQUENCE:
-+    case V_ASN1_SET:
-+    case V_ASN1_OTHER:
-+        if (BIO_puts(out, "\n") <= 0)
-+            return 0;
-+        if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
-+            ret = 0;
-+        needlf = 0;
-+        break;
-+
-+    default:
-+        ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
-+
-+    }
-+    if (!ret)
-+        return 0;
-+    if (needlf && BIO_puts(out, "\n") <= 0)
-+        return 0;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_scn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_scn.c
-new file mode 100644
-index 0000000..e1df2cf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_scn.c
-@@ -0,0 +1,65 @@
-+/*
-+ * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "asn1_locl.h"
-+
-+/*
-+ * General ASN1 structure recursive scanner: iterate through all fields
-+ * passing details to a callback.
-+ */
-+
-+ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx))
-+{
-+    ASN1_SCTX *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        ASN1err(ASN1_F_ASN1_SCTX_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    ret->scan_cb = scan_cb;
-+    return ret;
-+}
-+
-+void ASN1_SCTX_free(ASN1_SCTX *p)
-+{
-+    OPENSSL_free(p);
-+}
-+
-+const ASN1_ITEM *ASN1_SCTX_get_item(ASN1_SCTX *p)
-+{
-+    return p->it;
-+}
-+
-+const ASN1_TEMPLATE *ASN1_SCTX_get_template(ASN1_SCTX *p)
-+{
-+    return p->tt;
-+}
-+
-+unsigned long ASN1_SCTX_get_flags(ASN1_SCTX *p)
-+{
-+    return p->flags;
-+}
-+
-+void ASN1_SCTX_set_app_data(ASN1_SCTX *p, void *data)
-+{
-+    p->app_data = data;
-+}
-+
-+void *ASN1_SCTX_get_app_data(ASN1_SCTX *p)
-+{
-+    return p->app_data;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_typ.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_typ.c
-new file mode 100644
-index 0000000..98d9879
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_typ.c
-@@ -0,0 +1,84 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* Declarations for string types */
-+
-+#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \
-+    IMPLEMENT_ASN1_TYPE(sname) \
-+    IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
-+sname *sname##_new(void) \
-+{ \
-+    return ASN1_STRING_type_new(V_##sname); \
-+} \
-+void sname##_free(sname *x) \
-+{ \
-+    ASN1_STRING_free(x); \
-+}
-+
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_ENUMERATED)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BIT_STRING)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTF8STRING)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_PRINTABLESTRING)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_T61STRING)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_IA5STRING)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALSTRING)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALIZEDTIME)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_VISIBLESTRING)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UNIVERSALSTRING)
-+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BMPSTRING)
-+
-+IMPLEMENT_ASN1_TYPE(ASN1_NULL)
-+IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL)
-+
-+IMPLEMENT_ASN1_TYPE(ASN1_OBJECT)
-+
-+IMPLEMENT_ASN1_TYPE(ASN1_ANY)
-+
-+/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */
-+IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE)
-+
-+IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
-+
-+/* Multistring types */
-+
-+IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE)
-+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
-+
-+IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT)
-+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
-+
-+IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING)
-+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
-+
-+/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */
-+IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1)
-+IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1)
-+IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
-+
-+/* Special, OCTET STRING with indefinite length constructed support */
-+
-+IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
-+
-+ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
-+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
-+ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
-+
-+ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) =
-+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
-+ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
-+
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_utl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_utl.c
-new file mode 100644
-index 0000000..f79d7d6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/tasn_utl.c
-@@ -0,0 +1,240 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "asn1_locl.h"
-+
-+/* Utility functions for manipulating fields and offsets */
-+
-+/* Add 'offset' to 'addr' */
-+#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
-+
-+/*
-+ * Given an ASN1_ITEM CHOICE type return the selector value
-+ */
-+
-+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    int *sel = offset2ptr(*pval, it->utype);
-+    return *sel;
-+}
-+
-+/*
-+ * Given an ASN1_ITEM CHOICE type set the selector value, return old value.
-+ */
-+
-+int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
-+                             const ASN1_ITEM *it)
-+{
-+    int *sel, ret;
-+    sel = offset2ptr(*pval, it->utype);
-+    ret = *sel;
-+    *sel = value;
-+    return ret;
-+}
-+
-+/*
-+ * Do atomic reference counting. The value 'op' decides what to do.
-+ * If it is +1 then the count is incremented.
-+ * If |op| is 0, lock is initialised and count is set to 1.
-+ * If |op| is -1, count is decremented and the return value is the current
-+ * reference count or 0 if no reference count is active.
-+ * It returns -1 on initialisation error.
-+ * Used by ASN1_SEQUENCE construct of X509, X509_REQ, X509_CRL objects
-+ */
-+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
-+{
-+    const ASN1_AUX *aux;
-+    int *lck, ret;
-+    CRYPTO_RWLOCK **lock;
-+    if ((it->itype != ASN1_ITYPE_SEQUENCE)
-+        && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
-+        return 0;
-+    aux = it->funcs;
-+    if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
-+        return 0;
-+    lck = offset2ptr(*pval, aux->ref_offset);
-+    lock = offset2ptr(*pval, aux->ref_lock);
-+    if (op == 0) {
-+        *lck = 1;
-+        *lock = CRYPTO_THREAD_lock_new();
-+        if (*lock == NULL) {
-+            ASN1err(ASN1_F_ASN1_DO_LOCK, ERR_R_MALLOC_FAILURE);
-+            return -1;
-+        }
-+        return 1;
-+    }
-+    if (CRYPTO_atomic_add(lck, op, &ret, *lock) < 0)
-+        return -1;  /* failed */
-+#ifdef REF_PRINT
-+    fprintf(stderr, "%p:%4d:%s\n", it, *lck, it->sname);
-+#endif
-+    REF_ASSERT_ISNT(ret < 0);
-+    if (ret == 0) {
-+        CRYPTO_THREAD_lock_free(*lock);
-+        *lock = NULL;
-+    }
-+    return ret;
-+}
-+
-+static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    const ASN1_AUX *aux;
-+    if (!pval || !*pval)
-+        return NULL;
-+    aux = it->funcs;
-+    if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
-+        return NULL;
-+    return offset2ptr(*pval, aux->enc_offset);
-+}
-+
-+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    ASN1_ENCODING *enc;
-+    enc = asn1_get_enc_ptr(pval, it);
-+    if (enc) {
-+        enc->enc = NULL;
-+        enc->len = 0;
-+        enc->modified = 1;
-+    }
-+}
-+
-+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    ASN1_ENCODING *enc;
-+    enc = asn1_get_enc_ptr(pval, it);
-+    if (enc) {
-+        OPENSSL_free(enc->enc);
-+        enc->enc = NULL;
-+        enc->len = 0;
-+        enc->modified = 1;
-+    }
-+}
-+
-+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
-+                  const ASN1_ITEM *it)
-+{
-+    ASN1_ENCODING *enc;
-+    enc = asn1_get_enc_ptr(pval, it);
-+    if (!enc)
-+        return 1;
-+
-+    OPENSSL_free(enc->enc);
-+    enc->enc = OPENSSL_malloc(inlen);
-+    if (enc->enc == NULL)
-+        return 0;
-+    memcpy(enc->enc, in, inlen);
-+    enc->len = inlen;
-+    enc->modified = 0;
-+
-+    return 1;
-+}
-+
-+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
-+                     const ASN1_ITEM *it)
-+{
-+    ASN1_ENCODING *enc;
-+    enc = asn1_get_enc_ptr(pval, it);
-+    if (!enc || enc->modified)
-+        return 0;
-+    if (out) {
-+        memcpy(*out, enc->enc, enc->len);
-+        *out += enc->len;
-+    }
-+    if (len)
-+        *len = enc->len;
-+    return 1;
-+}
-+
-+/* Given an ASN1_TEMPLATE get a pointer to a field */
-+ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
-+{
-+    ASN1_VALUE **pvaltmp;
-+    pvaltmp = offset2ptr(*pval, tt->offset);
-+    /*
-+     * NOTE for BOOLEAN types the field is just a plain int so we can't
-+     * return int **, so settle for (int *).
-+     */
-+    return pvaltmp;
-+}
-+
-+/*
-+ * Handle ANY DEFINED BY template, find the selector, look up the relevant
-+ * ASN1_TEMPLATE in the table and return it.
-+ */
-+
-+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
-+                                 int nullerr)
-+{
-+    const ASN1_ADB *adb;
-+    const ASN1_ADB_TABLE *atbl;
-+    long selector;
-+    ASN1_VALUE **sfld;
-+    int i;
-+    if (!(tt->flags & ASN1_TFLG_ADB_MASK))
-+        return tt;
-+
-+    /* Else ANY DEFINED BY ... get the table */
-+    adb = ASN1_ADB_ptr(tt->item);
-+
-+    /* Get the selector field */
-+    sfld = offset2ptr(*pval, adb->offset);
-+
-+    /* Check if NULL */
-+    if (*sfld == NULL) {
-+        if (!adb->null_tt)
-+            goto err;
-+        return adb->null_tt;
-+    }
-+
-+    /*
-+     * Convert type to a long: NB: don't check for NID_undef here because it
-+     * might be a legitimate value in the table
-+     */
-+    if (tt->flags & ASN1_TFLG_ADB_OID)
-+        selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
-+    else
-+        selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
-+
-+    /* Let application callback translate value */
-+    if (adb->adb_cb != NULL && adb->adb_cb(&selector) == 0) {
-+        ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
-+        return NULL;
-+    }
-+
-+    /*
-+     * Try to find matching entry in table Maybe should check application
-+     * types first to allow application override? Might also be useful to
-+     * have a flag which indicates table is sorted and we can do a binary
-+     * search. For now stick to a linear search.
-+     */
-+
-+    for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
-+        if (atbl->value == selector)
-+            return &atbl->tt;
-+
-+    /* FIXME: need to search application table too */
-+
-+    /* No match, return default type */
-+    if (!adb->default_tt)
-+        goto err;
-+    return adb->default_tt;
-+
-+ err:
-+    /* FIXME: should log the value or OID of unsupported type */
-+    if (nullerr)
-+        ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_algor.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_algor.c
-new file mode 100644
-index 0000000..72378db
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_algor.c
-@@ -0,0 +1,93 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+ASN1_SEQUENCE(X509_ALGOR) = {
-+        ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
-+        ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
-+} ASN1_SEQUENCE_END(X509_ALGOR)
-+
-+ASN1_ITEM_TEMPLATE(X509_ALGORS) =
-+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
-+ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS)
-+IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)
-+
-+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
-+{
-+    if (!alg)
-+        return 0;
-+    if (ptype != V_ASN1_UNDEF) {
-+        if (alg->parameter == NULL)
-+            alg->parameter = ASN1_TYPE_new();
-+        if (alg->parameter == NULL)
-+            return 0;
-+    }
-+    if (alg) {
-+        ASN1_OBJECT_free(alg->algorithm);
-+        alg->algorithm = aobj;
-+    }
-+    if (ptype == 0)
-+        return 1;
-+    if (ptype == V_ASN1_UNDEF) {
-+        ASN1_TYPE_free(alg->parameter);
-+        alg->parameter = NULL;
-+    } else
-+        ASN1_TYPE_set(alg->parameter, ptype, pval);
-+    return 1;
-+}
-+
-+void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
-+                     const void **ppval, const X509_ALGOR *algor)
-+{
-+    if (paobj)
-+        *paobj = algor->algorithm;
-+    if (pptype) {
-+        if (algor->parameter == NULL) {
-+            *pptype = V_ASN1_UNDEF;
-+            return;
-+        } else
-+            *pptype = algor->parameter->type;
-+        if (ppval)
-+            *ppval = algor->parameter->value.ptr;
-+    }
-+}
-+
-+/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
-+
-+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
-+{
-+    int param_type;
-+
-+    if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
-+        param_type = V_ASN1_UNDEF;
-+    else
-+        param_type = V_ASN1_NULL;
-+
-+    X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
-+
-+}
-+
-+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
-+{
-+    int rv;
-+    rv = OBJ_cmp(a->algorithm, b->algorithm);
-+    if (rv)
-+        return rv;
-+    if (!a->parameter && !b->parameter)
-+        return 0;
-+    return ASN1_TYPE_cmp(a->parameter, b->parameter);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_bignum.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_bignum.c
-new file mode 100644
-index 0000000..da57e77
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_bignum.c
-@@ -0,0 +1,146 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+/*
-+ * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER
-+ * as a BIGNUM directly. Currently it ignores the sign which isn't a problem
-+ * since all BIGNUMs used are non negative and anything that looks negative
-+ * is normally due to an encoding error.
-+ */
-+
-+#define BN_SENSITIVE    1
-+
-+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
-+static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
-+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
-+
-+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
-+                  const ASN1_ITEM *it);
-+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-+                  int utype, char *free_cont, const ASN1_ITEM *it);
-+static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-+                         int utype, char *free_cont, const ASN1_ITEM *it);
-+static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                    int indent, const ASN1_PCTX *pctx);
-+
-+static ASN1_PRIMITIVE_FUNCS bignum_pf = {
-+    NULL, 0,
-+    bn_new,
-+    bn_free,
-+    0,
-+    bn_c2i,
-+    bn_i2c,
-+    bn_print
-+};
-+
-+static ASN1_PRIMITIVE_FUNCS cbignum_pf = {
-+    NULL, 0,
-+    bn_secure_new,
-+    bn_free,
-+    0,
-+    bn_secure_c2i,
-+    bn_i2c,
-+    bn_print
-+};
-+
-+ASN1_ITEM_start(BIGNUM)
-+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
-+ASN1_ITEM_end(BIGNUM)
-+
-+ASN1_ITEM_start(CBIGNUM)
-+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &cbignum_pf, BN_SENSITIVE, "CBIGNUM"
-+ASN1_ITEM_end(CBIGNUM)
-+
-+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    *pval = (ASN1_VALUE *)BN_new();
-+    if (*pval != NULL)
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    *pval = (ASN1_VALUE *)BN_secure_new();
-+    if (*pval != NULL)
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    if (!*pval)
-+        return;
-+    if (it->size & BN_SENSITIVE)
-+        BN_clear_free((BIGNUM *)*pval);
-+    else
-+        BN_free((BIGNUM *)*pval);
-+    *pval = NULL;
-+}
-+
-+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
-+                  const ASN1_ITEM *it)
-+{
-+    BIGNUM *bn;
-+    int pad;
-+    if (!*pval)
-+        return -1;
-+    bn = (BIGNUM *)*pval;
-+    /* If MSB set in an octet we need a padding byte */
-+    if (BN_num_bits(bn) & 0x7)
-+        pad = 0;
-+    else
-+        pad = 1;
-+    if (cont) {
-+        if (pad)
-+            *cont++ = 0;
-+        BN_bn2bin(bn, cont);
-+    }
-+    return pad + BN_num_bytes(bn);
-+}
-+
-+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-+                  int utype, char *free_cont, const ASN1_ITEM *it)
-+{
-+    BIGNUM *bn;
-+
-+    if (*pval == NULL && !bn_new(pval, it))
-+        return 0;
-+    bn = (BIGNUM *)*pval;
-+    if (!BN_bin2bn(cont, len, bn)) {
-+        bn_free(pval, it);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-+                         int utype, char *free_cont, const ASN1_ITEM *it)
-+{
-+    if (!*pval)
-+        bn_secure_new(pval, it);
-+    return bn_c2i(pval, cont, len, utype, free_cont, it);
-+}
-+
-+static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                    int indent, const ASN1_PCTX *pctx)
-+{
-+    if (!BN_print(out, *(BIGNUM **)pval))
-+        return 0;
-+    if (BIO_puts(out, "\n") <= 0)
-+        return 0;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_info.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_info.c
-new file mode 100644
-index 0000000..8d99f07
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_info.c
-@@ -0,0 +1,39 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+X509_INFO *X509_INFO_new(void)
-+{
-+    X509_INFO *ret;
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL) {
-+        ASN1err(ASN1_F_X509_INFO_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    return ret;
-+}
-+
-+void X509_INFO_free(X509_INFO *x)
-+{
-+    if (x == NULL)
-+        return;
-+
-+    X509_free(x->x509);
-+    X509_CRL_free(x->crl);
-+    X509_PKEY_free(x->x_pkey);
-+    OPENSSL_free(x->enc_data);
-+    OPENSSL_free(x);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_long.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_long.c
-new file mode 100644
-index 0000000..c284471
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_long.c
-@@ -0,0 +1,146 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+/*
-+ * Custom primitive type for long handling. This converts between an
-+ * ASN1_INTEGER and a long directly.
-+ */
-+
-+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
-+static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
-+
-+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
-+                    const ASN1_ITEM *it);
-+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-+                    int utype, char *free_cont, const ASN1_ITEM *it);
-+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                      int indent, const ASN1_PCTX *pctx);
-+
-+static ASN1_PRIMITIVE_FUNCS long_pf = {
-+    NULL, 0,
-+    long_new,
-+    long_free,
-+    long_free,                  /* Clear should set to initial value */
-+    long_c2i,
-+    long_i2c,
-+    long_print
-+};
-+
-+ASN1_ITEM_start(LONG)
-+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
-+ASN1_ITEM_end(LONG)
-+
-+ASN1_ITEM_start(ZLONG)
-+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
-+ASN1_ITEM_end(ZLONG)
-+
-+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    *(long *)pval = it->size;
-+    return 1;
-+}
-+
-+static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    *(long *)pval = it->size;
-+}
-+
-+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
-+                    const ASN1_ITEM *it)
-+{
-+    long ltmp;
-+    unsigned long utmp;
-+    int clen, pad, i;
-+    /* this exists to bypass broken gcc optimization */
-+    char *cp = (char *)pval;
-+
-+    /* use memcpy, because we may not be long aligned */
-+    memcpy(<mp, cp, sizeof(long));
-+
-+    if (ltmp == it->size)
-+        return -1;
-+    /*
-+     * Convert the long to positive: we subtract one if negative so we can
-+     * cleanly handle the padding if only the MSB of the leading octet is
-+     * set.
-+     */
-+    if (ltmp < 0)
-+        utmp = 0 - (unsigned long)ltmp - 1;
-+    else
-+        utmp = ltmp;
-+    clen = BN_num_bits_word(utmp);
-+    /* If MSB of leading octet set we need to pad */
-+    if (!(clen & 0x7))
-+        pad = 1;
-+    else
-+        pad = 0;
-+
-+    /* Convert number of bits to number of octets */
-+    clen = (clen + 7) >> 3;
-+
-+    if (cont) {
-+        if (pad)
-+            *cont++ = (ltmp < 0) ? 0xff : 0;
-+        for (i = clen - 1; i >= 0; i--) {
-+            cont[i] = (unsigned char)(utmp & 0xff);
-+            if (ltmp < 0)
-+                cont[i] ^= 0xff;
-+            utmp >>= 8;
-+        }
-+    }
-+    return clen + pad;
-+}
-+
-+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
-+                    int utype, char *free_cont, const ASN1_ITEM *it)
-+{
-+    int neg, i;
-+    long ltmp;
-+    unsigned long utmp = 0;
-+    char *cp = (char *)pval;
-+    if (len > (int)sizeof(long)) {
-+        ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
-+        return 0;
-+    }
-+    /* Is it negative? */
-+    if (len && (cont[0] & 0x80))
-+        neg = 1;
-+    else
-+        neg = 0;
-+    utmp = 0;
-+    for (i = 0; i < len; i++) {
-+        utmp <<= 8;
-+        if (neg)
-+            utmp |= cont[i] ^ 0xff;
-+        else
-+            utmp |= cont[i];
-+    }
-+    ltmp = (long)utmp;
-+    if (neg) {
-+        ltmp = -ltmp;
-+        ltmp--;
-+    }
-+    if (ltmp == it->size) {
-+        ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
-+        return 0;
-+    }
-+    memcpy(cp, <mp, sizeof(long));
-+    return 1;
-+}
-+
-+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                      int indent, const ASN1_PCTX *pctx)
-+{
-+    return BIO_printf(out, "%ld\n", *(long *)pval);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_pkey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_pkey.c
-new file mode 100644
-index 0000000..593049f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_pkey.c
-@@ -0,0 +1,47 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+X509_PKEY *X509_PKEY_new(void)
-+{
-+    X509_PKEY *ret = NULL;
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL)
-+        goto err;
-+
-+    ret->enc_algor = X509_ALGOR_new();
-+    ret->enc_pkey = ASN1_OCTET_STRING_new();
-+    if (ret->enc_algor == NULL || ret->enc_pkey == NULL)
-+        goto err;
-+
-+    return ret;
-+err:
-+    X509_PKEY_free(ret);
-+    ASN1err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+void X509_PKEY_free(X509_PKEY *x)
-+{
-+    if (x == NULL)
-+        return;
-+
-+    X509_ALGOR_free(x->enc_algor);
-+    ASN1_OCTET_STRING_free(x->enc_pkey);
-+    EVP_PKEY_free(x->dec_pkey);
-+    if (x->key_free)
-+        OPENSSL_free(x->key_data);
-+    OPENSSL_free(x);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_sig.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_sig.c
-new file mode 100644
-index 0000000..e465cf2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_sig.c
-@@ -0,0 +1,39 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/x509_int.h"
-+
-+ASN1_SEQUENCE(X509_SIG) = {
-+        ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
-+        ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
-+} ASN1_SEQUENCE_END(X509_SIG)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)
-+
-+void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg,
-+                   const ASN1_OCTET_STRING **pdigest)
-+{
-+    if (palg)
-+        *palg = sig->algor;
-+    if (pdigest)
-+        *pdigest = sig->digest;
-+}
-+
-+void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg,
-+                   ASN1_OCTET_STRING **pdigest)
-+{
-+    if (palg)
-+        *palg = sig->algor;
-+    if (pdigest)
-+        *pdigest = sig->digest;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_spki.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_spki.c
-new file mode 100644
-index 0000000..c45400b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_spki.c
-@@ -0,0 +1,33 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+ /*
-+  * This module was send to me my Pat Richards  who wrote it.
-+  * It is under my Copyright with his permission
-+  */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+ASN1_SEQUENCE(NETSCAPE_SPKAC) = {
-+        ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
-+        ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
-+} ASN1_SEQUENCE_END(NETSCAPE_SPKAC)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
-+
-+ASN1_SEQUENCE(NETSCAPE_SPKI) = {
-+        ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
-+        ASN1_EMBED(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
-+        ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
-+} ASN1_SEQUENCE_END(NETSCAPE_SPKI)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_val.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_val.c
-new file mode 100644
-index 0000000..d1f1d3b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/asn1/x_val.c
-@@ -0,0 +1,20 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+ASN1_SEQUENCE(X509_VAL) = {
-+        ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
-+        ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
-+} ASN1_SEQUENCE_END(X509_VAL)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(X509_VAL)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_null.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_null.c
-new file mode 100644
-index 0000000..3eaf170
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_null.c
-@@ -0,0 +1,23 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* This must be the first #include file */
-+#include "../async_locl.h"
-+
-+#ifdef ASYNC_NULL
-+int ASYNC_is_capable(void)
-+{
-+    return 0;
-+}
-+
-+void async_local_cleanup(void)
-+{
-+}
-+#endif
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_null.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_null.h
-new file mode 100644
-index 0000000..aef40b5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_null.h
-@@ -0,0 +1,30 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+/*
-+ * If we haven't managed to detect any other async architecture then we default
-+ * to NULL.
-+ */
-+#ifndef ASYNC_ARCH
-+# define ASYNC_NULL
-+# define ASYNC_ARCH
-+
-+typedef struct async_fibre_st {
-+    int dummy;
-+} async_fibre;
-+
-+
-+# define async_fibre_swapcontext(o,n,r)         0
-+# define async_fibre_makecontext(c)             0
-+# define async_fibre_free(f)
-+# define async_fibre_init_dispatcher(f)
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_posix.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_posix.c
-new file mode 100644
-index 0000000..02c342d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_posix.c
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* This must be the first #include file */
-+#include "../async_locl.h"
-+
-+#ifdef ASYNC_POSIX
-+
-+# include 
-+# include 
-+
-+#define STACKSIZE       32768
-+
-+int ASYNC_is_capable(void)
-+{
-+    ucontext_t ctx;
-+
-+    /*
-+     * Some platforms provide getcontext() but it does not work (notably
-+     * MacOSX PPC64). Check for a working getcontext();
-+     */
-+    return getcontext(&ctx) == 0;
-+}
-+
-+void async_local_cleanup(void)
-+{
-+}
-+
-+int async_fibre_makecontext(async_fibre *fibre)
-+{
-+    fibre->env_init = 0;
-+    if (getcontext(&fibre->fibre) == 0) {
-+        fibre->fibre.uc_stack.ss_sp = OPENSSL_malloc(STACKSIZE);
-+        if (fibre->fibre.uc_stack.ss_sp != NULL) {
-+            fibre->fibre.uc_stack.ss_size = STACKSIZE;
-+            fibre->fibre.uc_link = NULL;
-+            makecontext(&fibre->fibre, async_start_func, 0);
-+            return 1;
-+        }
-+    } else {
-+        fibre->fibre.uc_stack.ss_sp = NULL;
-+    }
-+    return 0;
-+}
-+
-+void async_fibre_free(async_fibre *fibre)
-+{
-+    OPENSSL_free(fibre->fibre.uc_stack.ss_sp);
-+    fibre->fibre.uc_stack.ss_sp = NULL;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_posix.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_posix.h
-new file mode 100644
-index 0000000..3c61f7f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_posix.h
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef OPENSSL_ASYNC_ARCH_ASYNC_POSIX_H
-+#define OPENSSL_ASYNC_ARCH_ASYNC_POSIX_H
-+#include 
-+
-+#if (defined(OPENSSL_SYS_UNIX) || defined(OPENSSL_SYS_CYGWIN)) \
-+    && defined(OPENSSL_THREADS) && !defined(OPENSSL_NO_ASYNC) \
-+    && !defined(__ANDROID__) && !defined(__OpenBSD__)
-+
-+# include 
-+
-+# if _POSIX_VERSION >= 200112L
-+
-+# include 
-+
-+#  define ASYNC_POSIX
-+#  define ASYNC_ARCH
-+
-+#  include 
-+#  include 
-+#  include "e_os.h"
-+
-+typedef struct async_fibre_st {
-+    ucontext_t fibre;
-+    jmp_buf env;
-+    int env_init;
-+} async_fibre;
-+
-+static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r)
-+{
-+    o->env_init = 1;
-+
-+    if (!r || !_setjmp(o->env)) {
-+        if (n->env_init)
-+            _longjmp(n->env, 1);
-+        else
-+            setcontext(&n->fibre);
-+    }
-+
-+    return 1;
-+}
-+
-+#  define async_fibre_init_dispatcher(d)
-+
-+int async_fibre_makecontext(async_fibre *fibre);
-+void async_fibre_free(async_fibre *fibre);
-+
-+# endif
-+#endif
-+#endif /* OPENSSL_ASYNC_ARCH_ASYNC_POSIX_H */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_win.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_win.c
-new file mode 100644
-index 0000000..077d56c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_win.c
-@@ -0,0 +1,55 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* This must be the first #include file */
-+#include "../async_locl.h"
-+
-+#ifdef ASYNC_WIN
-+
-+# include 
-+# include "internal/cryptlib.h"
-+
-+int ASYNC_is_capable(void)
-+{
-+    return 1;
-+}
-+
-+void async_local_cleanup(void)
-+{
-+    async_ctx *ctx = async_get_ctx();
-+    if (ctx != NULL) {
-+        async_fibre *fibre = &ctx->dispatcher;
-+        if (fibre != NULL && fibre->fibre != NULL && fibre->converted) {
-+            ConvertFiberToThread();
-+            fibre->fibre = NULL;
-+        }
-+    }
-+}
-+
-+int async_fibre_init_dispatcher(async_fibre *fibre)
-+{
-+    fibre->fibre = ConvertThreadToFiber(NULL);
-+    if (fibre->fibre == NULL) {
-+        fibre->converted = 0;
-+        fibre->fibre = GetCurrentFiber();
-+        if (fibre->fibre == NULL)
-+            return 0;
-+    } else {
-+        fibre->converted = 1;
-+    }
-+
-+    return 1;
-+}
-+
-+VOID CALLBACK async_start_func_win(PVOID unused)
-+{
-+    async_start_func();
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_win.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_win.h
-new file mode 100644
-index 0000000..61cfdd7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/arch/async_win.h
-@@ -0,0 +1,36 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * This is the same detection used in cryptlib to set up the thread local
-+ * storage that we depend on, so just copy that
-+ */
-+#if defined(_WIN32) && !defined(OPENSSL_NO_ASYNC)
-+#include 
-+# define ASYNC_WIN
-+# define ASYNC_ARCH
-+
-+# include 
-+# include "internal/cryptlib.h"
-+
-+typedef struct async_fibre_st {
-+    LPVOID fibre;
-+    int converted;
-+} async_fibre;
-+
-+# define async_fibre_swapcontext(o,n,r) \
-+        (SwitchToFiber((n)->fibre), 1)
-+# define async_fibre_makecontext(c) \
-+        ((c)->fibre = CreateFiber(0, async_start_func_win, 0))
-+# define async_fibre_free(f)             (DeleteFiber((f)->fibre))
-+
-+int async_fibre_init_dispatcher(async_fibre *fibre);
-+VOID CALLBACK async_start_func_win(PVOID unused);
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async.c
-new file mode 100644
-index 0000000..8c699af
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async.c
-@@ -0,0 +1,433 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Without this we start getting longjmp crashes because it thinks we're jumping
-+ * up the stack when in fact we are jumping to an entirely different stack. The
-+ * cost of this is not having certain buffer overrun/underrun checks etc for
-+ * this source file :-(
-+ */
-+#undef _FORTIFY_SOURCE
-+
-+/* This must be the first #include file */
-+#include "async_locl.h"
-+
-+#include 
-+#include 
-+#include 
-+
-+#define ASYNC_JOB_RUNNING   0
-+#define ASYNC_JOB_PAUSING   1
-+#define ASYNC_JOB_PAUSED    2
-+#define ASYNC_JOB_STOPPING  3
-+
-+static CRYPTO_THREAD_LOCAL ctxkey;
-+static CRYPTO_THREAD_LOCAL poolkey;
-+
-+static void async_free_pool_internal(async_pool *pool);
-+
-+static async_ctx *async_ctx_new(void)
-+{
-+    async_ctx *nctx = NULL;
-+
-+    nctx = OPENSSL_malloc(sizeof (async_ctx));
-+    if (nctx == NULL) {
-+        ASYNCerr(ASYNC_F_ASYNC_CTX_NEW, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    async_fibre_init_dispatcher(&nctx->dispatcher);
-+    nctx->currjob = NULL;
-+    nctx->blocked = 0;
-+    if (!CRYPTO_THREAD_set_local(&ctxkey, nctx))
-+        goto err;
-+
-+    return nctx;
-+err:
-+    OPENSSL_free(nctx);
-+
-+    return NULL;
-+}
-+
-+async_ctx *async_get_ctx(void)
-+{
-+    if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL))
-+        return NULL;
-+
-+    return (async_ctx *)CRYPTO_THREAD_get_local(&ctxkey);
-+}
-+
-+static int async_ctx_free(void)
-+{
-+    async_ctx *ctx;
-+
-+    ctx = async_get_ctx();
-+
-+    if (!CRYPTO_THREAD_set_local(&ctxkey, NULL))
-+        return 0;
-+
-+    OPENSSL_free(ctx);
-+
-+    return 1;
-+}
-+
-+static ASYNC_JOB *async_job_new(void)
-+{
-+    ASYNC_JOB *job = NULL;
-+
-+    job = OPENSSL_zalloc(sizeof (ASYNC_JOB));
-+    if (job == NULL) {
-+        ASYNCerr(ASYNC_F_ASYNC_JOB_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    job->status = ASYNC_JOB_RUNNING;
-+
-+    return job;
-+}
-+
-+static void async_job_free(ASYNC_JOB *job)
-+{
-+    if (job != NULL) {
-+        OPENSSL_free(job->funcargs);
-+        async_fibre_free(&job->fibrectx);
-+        OPENSSL_free(job);
-+    }
-+}
-+
-+static ASYNC_JOB *async_get_pool_job(void) {
-+    ASYNC_JOB *job;
-+    async_pool *pool;
-+
-+    pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey);
-+    if (pool == NULL) {
-+        /*
-+         * Pool has not been initialised, so init with the defaults, i.e.
-+         * no max size and no pre-created jobs
-+         */
-+        if (ASYNC_init_thread(0, 0) == 0)
-+            return NULL;
-+        pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey);
-+    }
-+
-+    job = sk_ASYNC_JOB_pop(pool->jobs);
-+    if (job == NULL) {
-+        /* Pool is empty */
-+        if ((pool->max_size != 0) && (pool->curr_size >= pool->max_size))
-+            return NULL;
-+
-+        job = async_job_new();
-+        if (job != NULL) {
-+            if (! async_fibre_makecontext(&job->fibrectx)) {
-+                async_job_free(job);
-+                return NULL;
-+            }
-+            pool->curr_size++;
-+        }
-+    }
-+    return job;
-+}
-+
-+static void async_release_job(ASYNC_JOB *job) {
-+    async_pool *pool;
-+
-+    pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey);
-+    OPENSSL_free(job->funcargs);
-+    job->funcargs = NULL;
-+    sk_ASYNC_JOB_push(pool->jobs, job);
-+}
-+
-+void async_start_func(void)
-+{
-+    ASYNC_JOB *job;
-+    async_ctx *ctx = async_get_ctx();
-+
-+    while (1) {
-+        /* Run the job */
-+        job = ctx->currjob;
-+        job->ret = job->func(job->funcargs);
-+
-+        /* Stop the job */
-+        job->status = ASYNC_JOB_STOPPING;
-+        if (!async_fibre_swapcontext(&job->fibrectx,
-+                                     &ctx->dispatcher, 1)) {
-+            /*
-+             * Should not happen. Getting here will close the thread...can't do
-+             * much about it
-+             */
-+            ASYNCerr(ASYNC_F_ASYNC_START_FUNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT);
-+        }
-+    }
-+}
-+
-+int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret,
-+                    int (*func)(void *), void *args, size_t size)
-+{
-+    async_ctx *ctx = async_get_ctx();
-+    if (ctx == NULL)
-+        ctx = async_ctx_new();
-+    if (ctx == NULL) {
-+        return ASYNC_ERR;
-+    }
-+
-+    if (*job) {
-+        ctx->currjob = *job;
-+    }
-+
-+    for (;;) {
-+        if (ctx->currjob != NULL) {
-+            if (ctx->currjob->status == ASYNC_JOB_STOPPING) {
-+                *ret = ctx->currjob->ret;
-+                ctx->currjob->waitctx = NULL;
-+                async_release_job(ctx->currjob);
-+                ctx->currjob = NULL;
-+                *job = NULL;
-+                return ASYNC_FINISH;
-+            }
-+
-+            if (ctx->currjob->status == ASYNC_JOB_PAUSING) {
-+                *job = ctx->currjob;
-+                ctx->currjob->status = ASYNC_JOB_PAUSED;
-+                ctx->currjob = NULL;
-+                return ASYNC_PAUSE;
-+            }
-+
-+            if (ctx->currjob->status == ASYNC_JOB_PAUSED) {
-+                ctx->currjob = *job;
-+                /* Resume previous job */
-+                if (!async_fibre_swapcontext(&ctx->dispatcher,
-+                        &ctx->currjob->fibrectx, 1)) {
-+                    ASYNCerr(ASYNC_F_ASYNC_START_JOB,
-+                             ASYNC_R_FAILED_TO_SWAP_CONTEXT);
-+                    goto err;
-+                }
-+                continue;
-+            }
-+
-+            /* Should not happen */
-+            ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_INTERNAL_ERROR);
-+            async_release_job(ctx->currjob);
-+            ctx->currjob = NULL;
-+            *job = NULL;
-+            return ASYNC_ERR;
-+        }
-+
-+        /* Start a new job */
-+        if ((ctx->currjob = async_get_pool_job()) == NULL) {
-+            return ASYNC_NO_JOBS;
-+        }
-+
-+        if (args != NULL) {
-+            ctx->currjob->funcargs = OPENSSL_malloc(size);
-+            if (ctx->currjob->funcargs == NULL) {
-+                ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_MALLOC_FAILURE);
-+                async_release_job(ctx->currjob);
-+                ctx->currjob = NULL;
-+                return ASYNC_ERR;
-+            }
-+            memcpy(ctx->currjob->funcargs, args, size);
-+        } else {
-+            ctx->currjob->funcargs = NULL;
-+        }
-+
-+        ctx->currjob->func = func;
-+        ctx->currjob->waitctx = wctx;
-+        if (!async_fibre_swapcontext(&ctx->dispatcher,
-+                &ctx->currjob->fibrectx, 1)) {
-+            ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT);
-+            goto err;
-+        }
-+    }
-+
-+err:
-+    async_release_job(ctx->currjob);
-+    ctx->currjob = NULL;
-+    *job = NULL;
-+    return ASYNC_ERR;
-+}
-+
-+int ASYNC_pause_job(void)
-+{
-+    ASYNC_JOB *job;
-+    async_ctx *ctx = async_get_ctx();
-+
-+    if (ctx == NULL
-+            || ctx->currjob == NULL
-+            || ctx->blocked) {
-+        /*
-+         * Could be we've deliberately not been started within a job so this is
-+         * counted as success.
-+         */
-+        return 1;
-+    }
-+
-+    job = ctx->currjob;
-+    job->status = ASYNC_JOB_PAUSING;
-+
-+    if (!async_fibre_swapcontext(&job->fibrectx,
-+                                 &ctx->dispatcher, 1)) {
-+        ASYNCerr(ASYNC_F_ASYNC_PAUSE_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT);
-+        return 0;
-+    }
-+    /* Reset counts of added and deleted fds */
-+    async_wait_ctx_reset_counts(job->waitctx);
-+
-+    return 1;
-+}
-+
-+static void async_empty_pool(async_pool *pool)
-+{
-+    ASYNC_JOB *job;
-+
-+    if (!pool || !pool->jobs)
-+        return;
-+
-+    do {
-+        job = sk_ASYNC_JOB_pop(pool->jobs);
-+        async_job_free(job);
-+    } while (job);
-+}
-+
-+int async_init(void)
-+{
-+    if (!CRYPTO_THREAD_init_local(&ctxkey, NULL))
-+        return 0;
-+
-+    if (!CRYPTO_THREAD_init_local(&poolkey, NULL)) {
-+        CRYPTO_THREAD_cleanup_local(&ctxkey);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+void async_deinit(void)
-+{
-+    CRYPTO_THREAD_cleanup_local(&ctxkey);
-+    CRYPTO_THREAD_cleanup_local(&poolkey);
-+}
-+
-+int ASYNC_init_thread(size_t max_size, size_t init_size)
-+{
-+    async_pool *pool;
-+    size_t curr_size = 0;
-+
-+    if (init_size > max_size) {
-+        ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INVALID_POOL_SIZE);
-+        return 0;
-+    }
-+
-+    if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) {
-+        return 0;
-+    }
-+    if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) {
-+        return 0;
-+    }
-+
-+    pool = OPENSSL_zalloc(sizeof *pool);
-+    if (pool == NULL) {
-+        ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    pool->jobs = sk_ASYNC_JOB_new_null();
-+    if (pool->jobs == NULL) {
-+        ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(pool);
-+        return 0;
-+    }
-+
-+    pool->max_size = max_size;
-+
-+    /* Pre-create jobs as required */
-+    while (init_size--) {
-+        ASYNC_JOB *job;
-+        job = async_job_new();
-+        if (job == NULL || !async_fibre_makecontext(&job->fibrectx)) {
-+            /*
-+             * Not actually fatal because we already created the pool, just
-+             * skip creation of any more jobs
-+             */
-+            async_job_free(job);
-+            break;
-+        }
-+        job->funcargs = NULL;
-+        sk_ASYNC_JOB_push(pool->jobs, job);
-+        curr_size++;
-+    }
-+    pool->curr_size = curr_size;
-+    if (!CRYPTO_THREAD_set_local(&poolkey, pool)) {
-+        ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_FAILED_TO_SET_POOL);
-+        goto err;
-+    }
-+
-+    return 1;
-+err:
-+    async_free_pool_internal(pool);
-+    return 0;
-+}
-+
-+static void async_free_pool_internal(async_pool *pool)
-+{
-+    if (pool == NULL)
-+        return;
-+
-+    async_empty_pool(pool);
-+    sk_ASYNC_JOB_free(pool->jobs);
-+    OPENSSL_free(pool);
-+    CRYPTO_THREAD_set_local(&poolkey, NULL);
-+    async_local_cleanup();
-+    async_ctx_free();
-+}
-+
-+void ASYNC_cleanup_thread(void)
-+{
-+    async_free_pool_internal((async_pool *)CRYPTO_THREAD_get_local(&poolkey));
-+}
-+
-+ASYNC_JOB *ASYNC_get_current_job(void)
-+{
-+    async_ctx *ctx;
-+
-+    ctx = async_get_ctx();
-+    if (ctx == NULL)
-+        return NULL;
-+
-+    return ctx->currjob;
-+}
-+
-+ASYNC_WAIT_CTX *ASYNC_get_wait_ctx(ASYNC_JOB *job)
-+{
-+    return job->waitctx;
-+}
-+
-+void ASYNC_block_pause(void)
-+{
-+    async_ctx *ctx = async_get_ctx();
-+    if (ctx == NULL || ctx->currjob == NULL) {
-+        /*
-+         * We're not in a job anyway so ignore this
-+         */
-+        return;
-+    }
-+    ctx->blocked++;
-+}
-+
-+void ASYNC_unblock_pause(void)
-+{
-+    async_ctx *ctx = async_get_ctx();
-+    if (ctx == NULL || ctx->currjob == NULL) {
-+        /*
-+         * We're not in a job anyway so ignore this
-+         */
-+        return;
-+    }
-+    if (ctx->blocked > 0)
-+        ctx->blocked--;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_err.c
-new file mode 100644
-index 0000000..ae97e96
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_err.c
-@@ -0,0 +1,51 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASYNC,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASYNC,0,reason)
-+
-+static ERR_STRING_DATA ASYNC_str_functs[] = {
-+    {ERR_FUNC(ASYNC_F_ASYNC_CTX_NEW), "async_ctx_new"},
-+    {ERR_FUNC(ASYNC_F_ASYNC_INIT_THREAD), "ASYNC_init_thread"},
-+    {ERR_FUNC(ASYNC_F_ASYNC_JOB_NEW), "async_job_new"},
-+    {ERR_FUNC(ASYNC_F_ASYNC_PAUSE_JOB), "ASYNC_pause_job"},
-+    {ERR_FUNC(ASYNC_F_ASYNC_START_FUNC), "async_start_func"},
-+    {ERR_FUNC(ASYNC_F_ASYNC_START_JOB), "ASYNC_start_job"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA ASYNC_str_reasons[] = {
-+    {ERR_REASON(ASYNC_R_FAILED_TO_SET_POOL), "failed to set pool"},
-+    {ERR_REASON(ASYNC_R_FAILED_TO_SWAP_CONTEXT), "failed to swap context"},
-+    {ERR_REASON(ASYNC_R_INIT_FAILED), "init failed"},
-+    {ERR_REASON(ASYNC_R_INVALID_POOL_SIZE), "invalid pool size"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_ASYNC_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(ASYNC_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, ASYNC_str_functs);
-+        ERR_load_strings(0, ASYNC_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_locl.h
-new file mode 100644
-index 0000000..f0ac05a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_locl.h
-@@ -0,0 +1,77 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Must do this before including any header files, because on MacOS/X 
-+ * includes  which includes 
-+ */
-+#if defined(__APPLE__) && defined(__MACH__) && !defined(_XOPEN_SOURCE)
-+# define _XOPEN_SOURCE          /* Otherwise incomplete ucontext_t structure */
-+# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-+#endif
-+
-+#if defined(_WIN32)
-+# include 
-+#endif
-+
-+#include 
-+#include 
-+
-+typedef struct async_ctx_st async_ctx;
-+typedef struct async_pool_st async_pool;
-+
-+#include "arch/async_win.h"
-+#include "arch/async_posix.h"
-+#include "arch/async_null.h"
-+
-+struct async_ctx_st {
-+    async_fibre dispatcher;
-+    ASYNC_JOB *currjob;
-+    unsigned int blocked;
-+};
-+
-+struct async_job_st {
-+    async_fibre fibrectx;
-+    int (*func) (void *);
-+    void *funcargs;
-+    int ret;
-+    int status;
-+    ASYNC_WAIT_CTX *waitctx;
-+};
-+
-+struct fd_lookup_st {
-+    const void *key;
-+    OSSL_ASYNC_FD fd;
-+    void *custom_data;
-+    void (*cleanup)(ASYNC_WAIT_CTX *, const void *, OSSL_ASYNC_FD, void *);
-+    int add;
-+    int del;
-+    struct fd_lookup_st *next;
-+};
-+
-+struct async_wait_ctx_st {
-+    struct fd_lookup_st *fds;
-+    size_t numadd;
-+    size_t numdel;
-+};
-+
-+DEFINE_STACK_OF(ASYNC_JOB)
-+
-+struct async_pool_st {
-+    STACK_OF(ASYNC_JOB) *jobs;
-+    size_t curr_size;
-+    size_t max_size;
-+};
-+
-+void async_local_cleanup(void);
-+void async_start_func(void);
-+async_ctx *async_get_ctx(void);
-+
-+void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx);
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_wait.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_wait.c
-new file mode 100644
-index 0000000..e115985
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/async_wait.c
-@@ -0,0 +1,211 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* This must be the first #include file */
-+#include "async_locl.h"
-+
-+#include 
-+
-+ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void)
-+{
-+    return OPENSSL_zalloc(sizeof(ASYNC_WAIT_CTX));
-+}
-+
-+void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx)
-+{
-+    struct fd_lookup_st *curr;
-+    struct fd_lookup_st *next;
-+
-+    if (ctx == NULL)
-+        return;
-+
-+    curr = ctx->fds;
-+    while (curr != NULL) {
-+        if (!curr->del) {
-+            /* Only try and cleanup if it hasn't been marked deleted */
-+            if (curr->cleanup != NULL)
-+                curr->cleanup(ctx, curr->key, curr->fd, curr->custom_data);
-+        }
-+        /* Always free the fd_lookup_st */
-+        next = curr->next;
-+        OPENSSL_free(curr);
-+        curr = next;
-+    }
-+
-+    OPENSSL_free(ctx);
-+}
-+int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key,
-+                               OSSL_ASYNC_FD fd, void *custom_data,
-+                               void (*cleanup)(ASYNC_WAIT_CTX *, const void *,
-+                                               OSSL_ASYNC_FD, void *))
-+{
-+    struct fd_lookup_st *fdlookup;
-+
-+    fdlookup = OPENSSL_zalloc(sizeof *fdlookup);
-+    if (fdlookup == NULL)
-+        return 0;
-+
-+    fdlookup->key = key;
-+    fdlookup->fd = fd;
-+    fdlookup->custom_data = custom_data;
-+    fdlookup->cleanup = cleanup;
-+    fdlookup->add = 1;
-+    fdlookup->next = ctx->fds;
-+    ctx->fds = fdlookup;
-+    ctx->numadd++;
-+    return 1;
-+}
-+
-+int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key,
-+                          OSSL_ASYNC_FD *fd, void **custom_data)
-+{
-+    struct fd_lookup_st *curr;
-+
-+    curr = ctx->fds;
-+    while (curr != NULL) {
-+        if (curr->del) {
-+            /* This one has been marked deleted so do nothing */
-+            curr = curr->next;
-+            continue;
-+        }
-+        if (curr->key == key) {
-+            *fd = curr->fd;
-+            *custom_data = curr->custom_data;
-+            return 1;
-+        }
-+        curr = curr->next;
-+    }
-+    return 0;
-+}
-+
-+int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd,
-+                               size_t *numfds)
-+{
-+    struct fd_lookup_st *curr;
-+
-+    curr = ctx->fds;
-+    *numfds = 0;
-+    while (curr != NULL) {
-+        if (curr->del) {
-+            /* This one has been marked deleted so do nothing */
-+            curr = curr->next;
-+            continue;
-+        }
-+        if (fd != NULL) {
-+            *fd = curr->fd;
-+            fd++;
-+        }
-+        (*numfds)++;
-+        curr = curr->next;
-+    }
-+    return 1;
-+}
-+
-+int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd,
-+                                   size_t *numaddfds, OSSL_ASYNC_FD *delfd,
-+                                   size_t *numdelfds)
-+{
-+    struct fd_lookup_st *curr;
-+
-+    *numaddfds = ctx->numadd;
-+    *numdelfds = ctx->numdel;
-+    if (addfd == NULL && delfd == NULL)
-+        return 1;
-+
-+    curr = ctx->fds;
-+
-+    while (curr != NULL) {
-+        /* We ignore fds that have been marked as both added and deleted */
-+        if (curr->del && !curr->add && (delfd != NULL)) {
-+            *delfd = curr->fd;
-+            delfd++;
-+        }
-+        if (curr->add && !curr->del && (addfd != NULL)) {
-+            *addfd = curr->fd;
-+            addfd++;
-+        }
-+        curr = curr->next;
-+    }
-+
-+    return 1;
-+}
-+
-+int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key)
-+{
-+    struct fd_lookup_st *curr, *prev;
-+
-+    curr = ctx->fds;
-+    prev = NULL;
-+    while (curr != NULL) {
-+        if (curr->del == 1) {
-+            /* This one has been marked deleted already so do nothing */
-+            curr = curr->next;
-+            continue;
-+        }
-+        if (curr->key == key) {
-+            /* If fd has just been added, remove it from the list */
-+            if (curr->add == 1) {
-+                if (ctx->fds == curr) {
-+                    ctx->fds = curr->next;
-+                } else {
-+                    prev->next = curr->next;
-+                }
-+
-+                /* It is responsibility of the caller to cleanup before calling
-+                 * ASYNC_WAIT_CTX_clear_fd
-+                 */
-+                OPENSSL_free(curr);
-+                ctx->numadd--;
-+                return 1;
-+            }
-+
-+            /*
-+             * Mark it as deleted. We don't call cleanup if explicitly asked
-+             * to clear an fd. We assume the caller is going to do that (if
-+             * appropriate).
-+             */
-+            curr->del = 1;
-+            ctx->numdel++;
-+            return 1;
-+        }
-+        prev = curr;
-+        curr = curr->next;
-+    }
-+    return 0;
-+}
-+
-+void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx)
-+{
-+    struct fd_lookup_st *curr, *prev = NULL;
-+
-+    ctx->numadd = 0;
-+    ctx->numdel = 0;
-+
-+    curr = ctx->fds;
-+
-+    while (curr != NULL) {
-+        if (curr->del) {
-+            if (prev == NULL)
-+                ctx->fds = curr->next;
-+            else
-+                prev->next = curr->next;
-+            OPENSSL_free(curr);
-+            if (prev == NULL)
-+                curr = ctx->fds;
-+            else
-+                curr = prev->next;
-+            continue;
-+        }
-+        if (curr->add) {
-+            curr->add = 0;
-+        }
-+        prev = curr;
-+        curr = curr->next;
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/async/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/build.info
-new file mode 100644
-index 0000000..278e3e9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/async/build.info
-@@ -0,0 +1,4 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        async.c async_wait.c async_err.c arch/async_posix.c arch/async_win.c \
-+        arch/async_null.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/asm/bf-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/asm/bf-586.pl
-new file mode 100644
-index 0000000..ebc24f4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/asm/bf-586.pl
-@@ -0,0 +1,149 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+require "cbc.pl";
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"bf-586.pl",$ARGV[$#ARGV] eq "386");
-+
-+$BF_ROUNDS=16;
-+$BF_OFF=($BF_ROUNDS+2)*4;
-+$L="edi";
-+$R="esi";
-+$P="ebp";
-+$tmp1="eax";
-+$tmp2="ebx";
-+$tmp3="ecx";
-+$tmp4="edx";
-+
-+&BF_encrypt("BF_encrypt",1);
-+&BF_encrypt("BF_decrypt",0);
-+&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1);
-+&asm_finish();
-+
-+close STDOUT;
-+
-+sub BF_encrypt
-+	{
-+	local($name,$enc)=@_;
-+
-+	&function_begin_B($name,"");
-+
-+	&comment("");
-+
-+	&push("ebp");
-+	&push("ebx");
-+	&mov($tmp2,&wparam(0));
-+	&mov($P,&wparam(1));
-+	&push("esi");
-+	&push("edi");
-+
-+	&comment("Load the 2 words");
-+	&mov($L,&DWP(0,$tmp2,"",0));
-+	&mov($R,&DWP(4,$tmp2,"",0));
-+
-+	&xor(	$tmp1,	$tmp1);
-+
-+	# encrypting part
-+
-+	if ($enc)
-+		{
-+		 &mov($tmp2,&DWP(0,$P,"",0));
-+		&xor(	$tmp3,	$tmp3);
-+
-+		&xor($L,$tmp2);
-+		for ($i=0; $i<$BF_ROUNDS; $i+=2)
-+			{
-+			&comment("");
-+			&comment("Round $i");
-+			&BF_ENCRYPT($i+1,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
-+
-+			&comment("");
-+			&comment("Round ".sprintf("%d",$i+1));
-+			&BF_ENCRYPT($i+2,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
-+			}
-+		# &mov($tmp1,&wparam(0)); In last loop
-+		&mov($tmp4,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
-+		}
-+	else
-+		{
-+		 &mov($tmp2,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
-+		&xor(	$tmp3,	$tmp3);
-+
-+		&xor($L,$tmp2);
-+		for ($i=$BF_ROUNDS; $i>0; $i-=2)
-+			{
-+			&comment("");
-+			&comment("Round $i");
-+			&BF_ENCRYPT($i,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
-+			&comment("");
-+			&comment("Round ".sprintf("%d",$i-1));
-+			&BF_ENCRYPT($i-1,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
-+			}
-+		# &mov($tmp1,&wparam(0)); In last loop
-+		&mov($tmp4,&DWP(0,$P,"",0));
-+		}
-+
-+	&xor($R,$tmp4);
-+	&mov(&DWP(4,$tmp1,"",0),$L);
-+
-+	&mov(&DWP(0,$tmp1,"",0),$R);
-+	&function_end($name);
-+	}
-+
-+sub BF_ENCRYPT
-+	{
-+	local($i,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,$enc)=@_;
-+
-+	&mov(	$tmp4,		&DWP(&n2a($i*4),$P,"",0)); # for next round
-+
-+	&mov(	$tmp2,		$R);
-+	&xor(	$L,		$tmp4);
-+
-+	&shr(	$tmp2,		16);
-+	&mov(	$tmp4,		$R);
-+
-+	&movb(	&LB($tmp1),	&HB($tmp2));	# A
-+	&and(	$tmp2,		0xff);		# B
-+
-+	&movb(	&LB($tmp3),	&HB($tmp4));	# C
-+	&and(	$tmp4,		0xff);		# D
-+
-+	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4));
-+	&mov(	$tmp2,		&DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4));
-+
-+	&add(	$tmp2,		$tmp1);
-+	&mov(	$tmp1,		&DWP(&n2a($BF_OFF+0x0800),$P,$tmp3,4));
-+
-+	&xor(	$tmp2,		$tmp1);
-+	&mov(	$tmp4,		&DWP(&n2a($BF_OFF+0x0C00),$P,$tmp4,4));
-+
-+	&add(	$tmp2,		$tmp4);
-+	if (($enc && ($i != 16)) || ((!$enc) && ($i != 1)))
-+		{ &xor(	$tmp1,		$tmp1); }
-+	else
-+		{
-+		&comment("Load parameter 0 ($i) enc=$enc");
-+		&mov($tmp1,&wparam(0));
-+		} # In last loop
-+
-+	&xor(	$L,		$tmp2);
-+	# delay
-+	}
-+
-+sub n2a
-+	{
-+	sprintf("%d",$_[0]);
-+	}
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_cbc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_cbc.c
-new file mode 100644
-index 0000000..6ed6257
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_cbc.c
-@@ -0,0 +1,86 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "bf_locl.h"
-+
-+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
-+                    const BF_KEY *schedule, unsigned char *ivec, int encrypt)
-+{
-+    register BF_LONG tin0, tin1;
-+    register BF_LONG tout0, tout1, xor0, xor1;
-+    register long l = length;
-+    BF_LONG tin[2];
-+
-+    if (encrypt) {
-+        n2l(ivec, tout0);
-+        n2l(ivec, tout1);
-+        ivec -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            n2l(in, tin0);
-+            n2l(in, tin1);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            BF_encrypt(tin, schedule);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+            l2n(tout0, out);
-+            l2n(tout1, out);
-+        }
-+        if (l != -8) {
-+            n2ln(in, tin0, tin1, l + 8);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            BF_encrypt(tin, schedule);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+            l2n(tout0, out);
-+            l2n(tout1, out);
-+        }
-+        l2n(tout0, ivec);
-+        l2n(tout1, ivec);
-+    } else {
-+        n2l(ivec, xor0);
-+        n2l(ivec, xor1);
-+        ivec -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            n2l(in, tin0);
-+            n2l(in, tin1);
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            BF_decrypt(tin, schedule);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2n(tout0, out);
-+            l2n(tout1, out);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        if (l != -8) {
-+            n2l(in, tin0);
-+            n2l(in, tin1);
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            BF_decrypt(tin, schedule);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2nn(tout0, tout1, out, l + 8);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        l2n(xor0, ivec);
-+        l2n(xor1, ivec);
-+    }
-+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
-+    tin[0] = tin[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_cfb64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_cfb64.c
-new file mode 100644
-index 0000000..ce6e13b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_cfb64.c
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "bf_locl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit cfb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+
-+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out,
-+                      long length, const BF_KEY *schedule,
-+                      unsigned char *ivec, int *num, int encrypt)
-+{
-+    register BF_LONG v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    BF_LONG ti[2];
-+    unsigned char *iv, c, cc;
-+
-+    iv = (unsigned char *)ivec;
-+    if (encrypt) {
-+        while (l--) {
-+            if (n == 0) {
-+                n2l(iv, v0);
-+                ti[0] = v0;
-+                n2l(iv, v1);
-+                ti[1] = v1;
-+                BF_encrypt((BF_LONG *)ti, schedule);
-+                iv = (unsigned char *)ivec;
-+                t = ti[0];
-+                l2n(t, iv);
-+                t = ti[1];
-+                l2n(t, iv);
-+                iv = (unsigned char *)ivec;
-+            }
-+            c = *(in++) ^ iv[n];
-+            *(out++) = c;
-+            iv[n] = c;
-+            n = (n + 1) & 0x07;
-+        }
-+    } else {
-+        while (l--) {
-+            if (n == 0) {
-+                n2l(iv, v0);
-+                ti[0] = v0;
-+                n2l(iv, v1);
-+                ti[1] = v1;
-+                BF_encrypt((BF_LONG *)ti, schedule);
-+                iv = (unsigned char *)ivec;
-+                t = ti[0];
-+                l2n(t, iv);
-+                t = ti[1];
-+                l2n(t, iv);
-+                iv = (unsigned char *)ivec;
-+            }
-+            cc = *(in++);
-+            c = iv[n];
-+            iv[n] = cc;
-+            *(out++) = c ^ cc;
-+            n = (n + 1) & 0x07;
-+        }
-+    }
-+    v0 = v1 = ti[0] = ti[1] = t = c = cc = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_ecb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_ecb.c
-new file mode 100644
-index 0000000..aa73540
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_ecb.c
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "bf_locl.h"
-+#include 
-+
-+/*
-+ * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From
-+ * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE
-+ * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
-+ */
-+
-+const char *BF_options(void)
-+{
-+    return ("blowfish(ptr)");
-+}
-+
-+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
-+                    const BF_KEY *key, int encrypt)
-+{
-+    BF_LONG l, d[2];
-+
-+    n2l(in, l);
-+    d[0] = l;
-+    n2l(in, l);
-+    d[1] = l;
-+    if (encrypt)
-+        BF_encrypt(d, key);
-+    else
-+        BF_decrypt(d, key);
-+    l = d[0];
-+    l2n(l, out);
-+    l = d[1];
-+    l2n(l, out);
-+    l = d[0] = d[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_enc.c
-new file mode 100644
-index 0000000..9f80c56
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_enc.c
-@@ -0,0 +1,179 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "bf_locl.h"
-+
-+/*
-+ * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From
-+ * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE
-+ * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
-+ */
-+
-+#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
-+# error If you set BF_ROUNDS to some value other than 16 or 20, you will have \
-+to modify the code.
-+#endif
-+
-+void BF_encrypt(BF_LONG *data, const BF_KEY *key)
-+{
-+    register BF_LONG l, r;
-+    register const BF_LONG *p, *s;
-+
-+    p = key->P;
-+    s = &(key->S[0]);
-+    l = data[0];
-+    r = data[1];
-+
-+    l ^= p[0];
-+    BF_ENC(r, l, s, p[1]);
-+    BF_ENC(l, r, s, p[2]);
-+    BF_ENC(r, l, s, p[3]);
-+    BF_ENC(l, r, s, p[4]);
-+    BF_ENC(r, l, s, p[5]);
-+    BF_ENC(l, r, s, p[6]);
-+    BF_ENC(r, l, s, p[7]);
-+    BF_ENC(l, r, s, p[8]);
-+    BF_ENC(r, l, s, p[9]);
-+    BF_ENC(l, r, s, p[10]);
-+    BF_ENC(r, l, s, p[11]);
-+    BF_ENC(l, r, s, p[12]);
-+    BF_ENC(r, l, s, p[13]);
-+    BF_ENC(l, r, s, p[14]);
-+    BF_ENC(r, l, s, p[15]);
-+    BF_ENC(l, r, s, p[16]);
-+# if BF_ROUNDS == 20
-+    BF_ENC(r, l, s, p[17]);
-+    BF_ENC(l, r, s, p[18]);
-+    BF_ENC(r, l, s, p[19]);
-+    BF_ENC(l, r, s, p[20]);
-+# endif
-+    r ^= p[BF_ROUNDS + 1];
-+
-+    data[1] = l & 0xffffffffU;
-+    data[0] = r & 0xffffffffU;
-+}
-+
-+#ifndef BF_DEFAULT_OPTIONS
-+
-+void BF_decrypt(BF_LONG *data, const BF_KEY *key)
-+{
-+    register BF_LONG l, r;
-+    register const BF_LONG *p, *s;
-+
-+    p = key->P;
-+    s = &(key->S[0]);
-+    l = data[0];
-+    r = data[1];
-+
-+    l ^= p[BF_ROUNDS + 1];
-+#  if BF_ROUNDS == 20
-+    BF_ENC(r, l, s, p[20]);
-+    BF_ENC(l, r, s, p[19]);
-+    BF_ENC(r, l, s, p[18]);
-+    BF_ENC(l, r, s, p[17]);
-+#  endif
-+    BF_ENC(r, l, s, p[16]);
-+    BF_ENC(l, r, s, p[15]);
-+    BF_ENC(r, l, s, p[14]);
-+    BF_ENC(l, r, s, p[13]);
-+    BF_ENC(r, l, s, p[12]);
-+    BF_ENC(l, r, s, p[11]);
-+    BF_ENC(r, l, s, p[10]);
-+    BF_ENC(l, r, s, p[9]);
-+    BF_ENC(r, l, s, p[8]);
-+    BF_ENC(l, r, s, p[7]);
-+    BF_ENC(r, l, s, p[6]);
-+    BF_ENC(l, r, s, p[5]);
-+    BF_ENC(r, l, s, p[4]);
-+    BF_ENC(l, r, s, p[3]);
-+    BF_ENC(r, l, s, p[2]);
-+    BF_ENC(l, r, s, p[1]);
-+    r ^= p[0];
-+
-+    data[1] = l & 0xffffffffU;
-+    data[0] = r & 0xffffffffU;
-+}
-+
-+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
-+                    const BF_KEY *schedule, unsigned char *ivec, int encrypt)
-+{
-+    register BF_LONG tin0, tin1;
-+    register BF_LONG tout0, tout1, xor0, xor1;
-+    register long l = length;
-+    BF_LONG tin[2];
-+
-+    if (encrypt) {
-+        n2l(ivec, tout0);
-+        n2l(ivec, tout1);
-+        ivec -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            n2l(in, tin0);
-+            n2l(in, tin1);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            BF_encrypt(tin, schedule);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+            l2n(tout0, out);
-+            l2n(tout1, out);
-+        }
-+        if (l != -8) {
-+            n2ln(in, tin0, tin1, l + 8);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            BF_encrypt(tin, schedule);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+            l2n(tout0, out);
-+            l2n(tout1, out);
-+        }
-+        l2n(tout0, ivec);
-+        l2n(tout1, ivec);
-+    } else {
-+        n2l(ivec, xor0);
-+        n2l(ivec, xor1);
-+        ivec -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            n2l(in, tin0);
-+            n2l(in, tin1);
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            BF_decrypt(tin, schedule);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2n(tout0, out);
-+            l2n(tout1, out);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        if (l != -8) {
-+            n2l(in, tin0);
-+            n2l(in, tin1);
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            BF_decrypt(tin, schedule);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2nn(tout0, tout1, out, l + 8);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        l2n(xor0, ivec);
-+        l2n(xor1, ivec);
-+    }
-+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
-+    tin[0] = tin[1] = 0;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_locl.h
-new file mode 100644
-index 0000000..7e5f92c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_locl.h
-@@ -0,0 +1,70 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_BF_LOCL_H
-+# define HEADER_BF_LOCL_H
-+# include 
-+
-+/* NOTE - c is not incremented as per n2l */
-+# define n2ln(c,l1,l2,n) { \
-+                        c+=n; \
-+                        l1=l2=0; \
-+                        switch (n) { \
-+                        case 8: l2 =((unsigned long)(*(--(c))))    ; \
-+                        case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
-+                        case 6: l2|=((unsigned long)(*(--(c))))<<16; \
-+                        case 5: l2|=((unsigned long)(*(--(c))))<<24; \
-+                        case 4: l1 =((unsigned long)(*(--(c))))    ; \
-+                        case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
-+                        case 2: l1|=((unsigned long)(*(--(c))))<<16; \
-+                        case 1: l1|=((unsigned long)(*(--(c))))<<24; \
-+                                } \
-+                        }
-+
-+/* NOTE - c is not incremented as per l2n */
-+# define l2nn(l1,l2,c,n) { \
-+                        c+=n; \
-+                        switch (n) { \
-+                        case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
-+                        case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
-+                        case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
-+                        case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
-+                        case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
-+                        case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
-+                        case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
-+                        case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
-+                                } \
-+                        }
-+
-+# undef n2l
-+# define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
-+                         l|=((unsigned long)(*((c)++)))<<16L, \
-+                         l|=((unsigned long)(*((c)++)))<< 8L, \
-+                         l|=((unsigned long)(*((c)++))))
-+
-+# undef l2n
-+# define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)     )&0xff))
-+
-+/*
-+ * This is actually a big endian algorithm, the most significant byte is used
-+ * to lookup array 0
-+ */
-+
-+# define BF_ENC(LL,R,S,P) ( \
-+        LL^=P, \
-+        LL^=((( S[       ((R>>24)&0xff)] + \
-+                S[0x0100+((R>>16)&0xff)])^ \
-+                S[0x0200+((R>> 8)&0xff)])+ \
-+                S[0x0300+((R    )&0xff)])&0xffffffffU \
-+        )
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_ofb64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_ofb64.c
-new file mode 100644
-index 0000000..6418217
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_ofb64.c
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "bf_locl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit ofb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out,
-+                      long length, const BF_KEY *schedule,
-+                      unsigned char *ivec, int *num)
-+{
-+    register BF_LONG v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    unsigned char d[8];
-+    register char *dp;
-+    BF_LONG ti[2];
-+    unsigned char *iv;
-+    int save = 0;
-+
-+    iv = (unsigned char *)ivec;
-+    n2l(iv, v0);
-+    n2l(iv, v1);
-+    ti[0] = v0;
-+    ti[1] = v1;
-+    dp = (char *)d;
-+    l2n(v0, dp);
-+    l2n(v1, dp);
-+    while (l--) {
-+        if (n == 0) {
-+            BF_encrypt((BF_LONG *)ti, schedule);
-+            dp = (char *)d;
-+            t = ti[0];
-+            l2n(t, dp);
-+            t = ti[1];
-+            l2n(t, dp);
-+            save++;
-+        }
-+        *(out++) = *(in++) ^ d[n];
-+        n = (n + 1) & 0x07;
-+    }
-+    if (save) {
-+        v0 = ti[0];
-+        v1 = ti[1];
-+        iv = (unsigned char *)ivec;
-+        l2n(v0, iv);
-+        l2n(v1, iv);
-+    }
-+    t = v0 = v1 = ti[0] = ti[1] = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_pi.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_pi.h
-new file mode 100644
-index 0000000..a054b03
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_pi.h
-@@ -0,0 +1,530 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+static const BF_KEY bf_init = {
-+    {
-+     0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L,
-+     0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L,
-+     0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL,
-+     0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L,
-+     0x9216d5d9L, 0x8979fb1b}, {
-+                                0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL,
-+                                0xd01adfb7L,
-+                                0xb8e1afedL, 0x6a267e96L, 0xba7c9045L,
-+                                0xf12c7f99L,
-+                                0x24a19947L, 0xb3916cf7L, 0x0801f2e2L,
-+                                0x858efc16L,
-+                                0x636920d8L, 0x71574e69L, 0xa458fea3L,
-+                                0xf4933d7eL,
-+                                0x0d95748fL, 0x728eb658L, 0x718bcd58L,
-+                                0x82154aeeL,
-+                                0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L,
-+                                0x2af26013L,
-+                                0xc5d1b023L, 0x286085f0L, 0xca417918L,
-+                                0xb8db38efL,
-+                                0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL,
-+                                0xb01e8a3eL,
-+                                0xd71577c1L, 0xbd314b27L, 0x78af2fdaL,
-+                                0x55605c60L,
-+                                0xe65525f3L, 0xaa55ab94L, 0x57489862L,
-+                                0x63e81440L,
-+                                0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L,
-+                                0x1141e8ceL,
-+                                0xa15486afL, 0x7c72e993L, 0xb3ee1411L,
-+                                0x636fbc2aL,
-+                                0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L,
-+                                0x9b87931eL,
-+                                0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L,
-+                                0x28958677L,
-+                                0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL,
-+                                0x66282193L,
-+                                0x61d809ccL, 0xfb21a991L, 0x487cac60L,
-+                                0x5dec8032L,
-+                                0xef845d5dL, 0xe98575b1L, 0xdc262302L,
-+                                0xeb651b88L,
-+                                0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L,
-+                                0x83f44239L,
-+                                0x2e0b4482L, 0xa4842004L, 0x69c8f04aL,
-+                                0x9e1f9b5eL,
-+                                0x21c66842L, 0xf6e96c9aL, 0x670c9c61L,
-+                                0xabd388f0L,
-+                                0x6a51a0d2L, 0xd8542f68L, 0x960fa728L,
-+                                0xab5133a3L,
-+                                0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L,
-+                                0x7efb2a98L,
-+                                0xa1f1651dL, 0x39af0176L, 0x66ca593eL,
-+                                0x82430e88L,
-+                                0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L,
-+                                0x3b8b5ebeL,
-+                                0xe06f75d8L, 0x85c12073L, 0x401a449fL,
-+                                0x56c16aa6L,
-+                                0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L,
-+                                0x429b023dL,
-+                                0x37d0d724L, 0xd00a1248L, 0xdb0fead3L,
-+                                0x49f1c09bL,
-+                                0x075372c9L, 0x80991b7bL, 0x25d479d8L,
-+                                0xf6e8def7L,
-+                                0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL,
-+                                0x04c006baL,
-+                                0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L,
-+                                0x196a2463L,
-+                                0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL,
-+                                0x3b52ec6fL,
-+                                0x6dfc511fL, 0x9b30952cL, 0xcc814544L,
-+                                0xaf5ebd09L,
-+                                0xbee3d004L, 0xde334afdL, 0x660f2807L,
-+                                0x192e4bb3L,
-+                                0xc0cba857L, 0x45c8740fL, 0xd20b5f39L,
-+                                0xb9d3fbdbL,
-+                                0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L,
-+                                0x402c7279L,
-+                                0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L,
-+                                0xdb3222f8L,
-+                                0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L,
-+                                0xad0552abL,
-+                                0x323db5faL, 0xfd238760L, 0x53317b48L,
-+                                0x3e00df82L,
-+                                0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL,
-+                                0xdf1769dbL,
-+                                0xd542a8f6L, 0x287effc3L, 0xac6732c6L,
-+                                0x8c4f5573L,
-+                                0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL,
-+                                0xb8f011a0L,
-+                                0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL,
-+                                0x2dd1d35bL,
-+                                0x9a53e479L, 0xb6f84565L, 0xd28e49bcL,
-+                                0x4bfb9790L,
-+                                0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L,
-+                                0xcee4c6e8L,
-+                                0xef20cadaL, 0x36774c01L, 0xd07e9efeL,
-+                                0x2bf11fb4L,
-+                                0x95dbda4dL, 0xae909198L, 0xeaad8e71L,
-+                                0x6b93d5a0L,
-+                                0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL,
-+                                0x8e7594b7L,
-+                                0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L,
-+                                0x900df01cL,
-+                                0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L,
-+                                0xb3a8c1adL,
-+                                0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL,
-+                                0x8b021fa1L,
-+                                0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L,
-+                                0xce89e299L,
-+                                0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L,
-+                                0xd2ada8d9L,
-+                                0x165fa266L, 0x80957705L, 0x93cc7314L,
-+                                0x211a1477L,
-+                                0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L,
-+                                0xfb9d35cfL,
-+                                0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L,
-+                                0xae1e7e49L,
-+                                0x00250e2dL, 0x2071b35eL, 0x226800bbL,
-+                                0x57b8e0afL,
-+                                0x2464369bL, 0xf009b91eL, 0x5563911dL,
-+                                0x59dfa6aaL,
-+                                0x78c14389L, 0xd95a537fL, 0x207d5ba2L,
-+                                0x02e5b9c5L,
-+                                0x83260376L, 0x6295cfa9L, 0x11c81968L,
-+                                0x4e734a41L,
-+                                0xb3472dcaL, 0x7b14a94aL, 0x1b510052L,
-+                                0x9a532915L,
-+                                0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L,
-+                                0x81e67400L,
-+                                0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL,
-+                                0x2a0dd915L,
-+                                0xb6636521L, 0xe7b9f9b6L, 0xff34052eL,
-+                                0xc5855664L,
-+                                0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L,
-+                                0x6e85076aL,
-+                                0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL,
-+                                0xc4192623L,
-+                                0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L,
-+                                0x8fedb266L,
-+                                0xecaa8c71L, 0x699a17ffL, 0x5664526cL,
-+                                0xc2b19ee1L,
-+                                0x193602a5L, 0x75094c29L, 0xa0591340L,
-+                                0xe4183a3eL,
-+                                0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L,
-+                                0x99f73fd6L,
-+                                0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L,
-+                                0xf0255dc1L,
-+                                0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L,
-+                                0x021ecc5eL,
-+                                0x09686b3fL, 0x3ebaefc9L, 0x3c971814L,
-+                                0x6b6a70a1L,
-+                                0x687f3584L, 0x52a0e286L, 0xb79c5305L,
-+                                0xaa500737L,
-+                                0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL,
-+                                0x5716f2b8L,
-+                                0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L,
-+                                0x0200b3ffL,
-+                                0xae0cf51aL, 0x3cb574b2L, 0x25837a58L,
-+                                0xdc0921bdL,
-+                                0xd19113f9L, 0x7ca92ff6L, 0x94324773L,
-+                                0x22f54701L,
-+                                0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L,
-+                                0x9af3dda7L,
-+                                0xa9446146L, 0x0fd0030eL, 0xecc8c73eL,
-+                                0xa4751e41L,
-+                                0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L,
-+                                0x183eb331L,
-+                                0x4e548b38L, 0x4f6db908L, 0x6f420d03L,
-+                                0xf60a04bfL,
-+                                0x2cb81290L, 0x24977c79L, 0x5679b072L,
-+                                0xbcaf89afL,
-+                                0xde9a771fL, 0xd9930810L, 0xb38bae12L,
-+                                0xdccf3f2eL,
-+                                0x5512721fL, 0x2e6b7124L, 0x501adde6L,
-+                                0x9f84cd87L,
-+                                0x7a584718L, 0x7408da17L, 0xbc9f9abcL,
-+                                0xe94b7d8cL,
-+                                0xec7aec3aL, 0xdb851dfaL, 0x63094366L,
-+                                0xc464c3d2L,
-+                                0xef1c1847L, 0x3215d908L, 0xdd433b37L,
-+                                0x24c2ba16L,
-+                                0x12a14d43L, 0x2a65c451L, 0x50940002L,
-+                                0x133ae4ddL,
-+                                0x71dff89eL, 0x10314e55L, 0x81ac77d6L,
-+                                0x5f11199bL,
-+                                0x043556f1L, 0xd7a3c76bL, 0x3c11183bL,
-+                                0x5924a509L,
-+                                0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL,
-+                                0x1e153c6eL,
-+                                0x86e34570L, 0xeae96fb1L, 0x860e5e0aL,
-+                                0x5a3e2ab3L,
-+                                0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L,
-+                                0x99e71d0fL,
-+                                0x803e89d6L, 0x5266c825L, 0x2e4cc978L,
-+                                0x9c10b36aL,
-+                                0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L,
-+                                0x1e0a2df4L,
-+                                0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL,
-+                                0x19c27960L,
-+                                0x5223a708L, 0xf71312b6L, 0xebadfe6eL,
-+                                0xeac31f66L,
-+                                0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L,
-+                                0x018cff28L,
-+                                0xc332ddefL, 0xbe6c5aa5L, 0x65582185L,
-+                                0x68ab9802L,
-+                                0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL,
-+                                0x5b6e2f84L,
-+                                0x1521b628L, 0x29076170L, 0xecdd4775L,
-+                                0x619f1510L,
-+                                0x13cca830L, 0xeb61bd96L, 0x0334fe1eL,
-+                                0xaa0363cfL,
-+                                0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL,
-+                                0xcbaade14L,
-+                                0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL,
-+                                0xb2f3846eL,
-+                                0x648b1eafL, 0x19bdf0caL, 0xa02369b9L,
-+                                0x655abb50L,
-+                                0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L,
-+                                0xc021b8f7L,
-+                                0x9b540b19L, 0x875fa099L, 0x95f7997eL,
-+                                0x623d7da8L,
-+                                0xf837889aL, 0x97e32d77L, 0x11ed935fL,
-+                                0x16681281L,
-+                                0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L,
-+                                0x7858ba99L,
-+                                0x57f584a5L, 0x1b227263L, 0x9b83c3ffL,
-+                                0x1ac24696L,
-+                                0xcdb30aebL, 0x532e3054L, 0x8fd948e4L,
-+                                0x6dbc3128L,
-+                                0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L,
-+                                0xee7c3c73L,
-+                                0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L,
-+                                0x203e13e0L,
-+                                0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L,
-+                                0xfacb4fd0L,
-+                                0xc742f442L, 0xef6abbb5L, 0x654f3b1dL,
-+                                0x41cd2105L,
-+                                0xd81e799eL, 0x86854dc7L, 0xe44b476aL,
-+                                0x3d816250L,
-+                                0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L,
-+                                0xc1c7b6a3L,
-+                                0x7f1524c3L, 0x69cb7492L, 0x47848a0bL,
-+                                0x5692b285L,
-+                                0x095bbf00L, 0xad19489dL, 0x1462b174L,
-+                                0x23820e00L,
-+                                0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL,
-+                                0x233f7061L,
-+                                0x3372f092L, 0x8d937e41L, 0xd65fecf1L,
-+                                0x6c223bdbL,
-+                                0x7cde3759L, 0xcbee7460L, 0x4085f2a7L,
-+                                0xce77326eL,
-+                                0xa6078084L, 0x19f8509eL, 0xe8efd855L,
-+                                0x61d99735L,
-+                                0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL,
-+                                0x800bcadcL,
-+                                0x9e447a2eL, 0xc3453484L, 0xfdd56705L,
-+                                0x0e1e9ec9L,
-+                                0xdb73dbd3L, 0x105588cdL, 0x675fda79L,
-+                                0xe3674340L,
-+                                0xc5c43465L, 0x713e38d8L, 0x3d28f89eL,
-+                                0xf16dff20L,
-+                                0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL,
-+                                0xdb83adf7L,
-+                                0xe93d5a68L, 0x948140f7L, 0xf64c261cL,
-+                                0x94692934L,
-+                                0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL,
-+                                0xd4a20068L,
-+                                0xd4082471L, 0x3320f46aL, 0x43b7d4b7L,
-+                                0x500061afL,
-+                                0x1e39f62eL, 0x97244546L, 0x14214f74L,
-+                                0xbf8b8840L,
-+                                0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L,
-+                                0x66a02f45L,
-+                                0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L,
-+                                0x31cb8504L,
-+                                0x96eb27b3L, 0x55fd3941L, 0xda2547e6L,
-+                                0xabca0a9aL,
-+                                0x28507825L, 0x530429f4L, 0x0a2c86daL,
-+                                0xe9b66dfbL,
-+                                0x68dc1462L, 0xd7486900L, 0x680ec0a4L,
-+                                0x27a18deeL,
-+                                0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L,
-+                                0x7af4d6b6L,
-+                                0xaace1e7cL, 0xd3375fecL, 0xce78a399L,
-+                                0x406b2a42L,
-+                                0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL,
-+                                0x3b124e8bL,
-+                                0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L,
-+                                0xeae397b2L,
-+                                0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L,
-+                                0xca7820fbL,
-+                                0xfb0af54eL, 0xd8feb397L, 0x454056acL,
-+                                0xba489527L,
-+                                0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L,
-+                                0xd096954bL,
-+                                0x55a867bcL, 0xa1159a58L, 0xcca92963L,
-+                                0x99e1db33L,
-+                                0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL,
-+                                0x9029317cL,
-+                                0xfdf8e802L, 0x04272f70L, 0x80bb155cL,
-+                                0x05282ce3L,
-+                                0x95c11548L, 0xe4c66d22L, 0x48c1133fL,
-+                                0xc70f86dcL,
-+                                0x07f9c9eeL, 0x41041f0fL, 0x404779a4L,
-+                                0x5d886e17L,
-+                                0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL,
-+                                0x41113564L,
-+                                0x257b7834L, 0x602a9c60L, 0xdff8e8a3L,
-+                                0x1f636c1bL,
-+                                0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L,
-+                                0xcad18115L,
-+                                0x6b2395e0L, 0x333e92e1L, 0x3b240b62L,
-+                                0xeebeb922L,
-+                                0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL,
-+                                0x2da2f728L,
-+                                0xd0127845L, 0x95b794fdL, 0x647d0862L,
-+                                0xe7ccf5f0L,
-+                                0x5449a36fL, 0x877d48faL, 0xc39dfd27L,
-+                                0xf33e8d1eL,
-+                                0x0a476341L, 0x992eff74L, 0x3a6f6eabL,
-+                                0xf4f8fd37L,
-+                                0xa812dc60L, 0xa1ebddf8L, 0x991be14cL,
-+                                0xdb6e6b0dL,
-+                                0xc67b5510L, 0x6d672c37L, 0x2765d43bL,
-+                                0xdcd0e804L,
-+                                0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L,
-+                                0x690fed0bL,
-+                                0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL,
-+                                0xd9155ea3L,
-+                                0xbb132f88L, 0x515bad24L, 0x7b9479bfL,
-+                                0x763bd6ebL,
-+                                0x37392eb3L, 0xcc115979L, 0x8026e297L,
-+                                0xf42e312dL,
-+                                0x6842ada7L, 0xc66a2b3bL, 0x12754cccL,
-+                                0x782ef11cL,
-+                                0x6a124237L, 0xb79251e7L, 0x06a1bbe6L,
-+                                0x4bfb6350L,
-+                                0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L,
-+                                0xe2e1c3c9L,
-+                                0x44421659L, 0x0a121386L, 0xd90cec6eL,
-+                                0xd5abea2aL,
-+                                0x64af674eL, 0xda86a85fL, 0xbebfe988L,
-+                                0x64e4c3feL,
-+                                0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L,
-+                                0x6003604dL,
-+                                0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L,
-+                                0xd736fcccL,
-+                                0x83426b33L, 0xf01eab71L, 0xb0804187L,
-+                                0x3c005e5fL,
-+                                0x77a057beL, 0xbde8ae24L, 0x55464299L,
-+                                0xbf582e61L,
-+                                0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L,
-+                                0x8789bdc2L,
-+                                0x5366f9c3L, 0xc8b38e74L, 0xb475f255L,
-+                                0x46fcd9b9L,
-+                                0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L,
-+                                0x915f95e2L,
-+                                0x466e598eL, 0x20b45770L, 0x8cd55591L,
-+                                0xc902de4cL,
-+                                0xb90bace1L, 0xbb8205d0L, 0x11a86248L,
-+                                0x7574a99eL,
-+                                0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L,
-+                                0xc4324633L,
-+                                0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L,
-+                                0x1d6efe10L,
-+                                0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL,
-+                                0x2868f169L,
-+                                0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL,
-+                                0x4fcd7f52L,
-+                                0x50115e01L, 0xa70683faL, 0xa002b5c4L,
-+                                0x0de6d027L,
-+                                0x9af88c27L, 0x773f8641L, 0xc3604c06L,
-+                                0x61a806b5L,
-+                                0xf0177a28L, 0xc0f586e0L, 0x006058aaL,
-+                                0x30dc7d62L,
-+                                0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L,
-+                                0xc2c21634L,
-+                                0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L,
-+                                0xce591d76L,
-+                                0x6f05e409L, 0x4b7c0188L, 0x39720a3dL,
-+                                0x7c927c24L,
-+                                0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L,
-+                                0xd39eb8fcL,
-+                                0xed545578L, 0x08fca5b5L, 0xd83d7cd3L,
-+                                0x4dad0fc4L,
-+                                0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L,
-+                                0x6c51133cL,
-+                                0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL,
-+                                0xddc6c837L,
-+                                0xd79a3234L, 0x92638212L, 0x670efa8eL,
-+                                0x406000e0L,
-+                                0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L,
-+                                0x5ac52d1bL,
-+                                0x5cb0679eL, 0x4fa33742L, 0xd3822740L,
-+                                0x99bc9bbeL,
-+                                0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL,
-+                                0xc700c47bL,
-+                                0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL,
-+                                0x6a366eb4L,
-+                                0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L,
-+                                0x6549c2c8L,
-+                                0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL,
-+                                0x4cd04dc6L,
-+                                0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L,
-+                                0xbe5ee304L,
-+                                0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L,
-+                                0x9a86ee22L,
-+                                0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL,
-+                                0x9cf2d0a4L,
-+                                0x83c061baL, 0x9be96a4dL, 0x8fe51550L,
-+                                0xba645bd6L,
-+                                0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L,
-+                                0xef5562e9L,
-+                                0xc72fefd3L, 0xf752f7daL, 0x3f046f69L,
-+                                0x77fa0a59L,
-+                                0x80e4a915L, 0x87b08601L, 0x9b09e6adL,
-+                                0x3b3ee593L,
-+                                0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L,
-+                                0x022b8b51L,
-+                                0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L,
-+                                0x7c7d2d28L,
-+                                0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L,
-+                                0x5a88f54cL,
-+                                0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL,
-+                                0xed93fa9bL,
-+                                0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L,
-+                                0x79132e28L,
-+                                0x785f0191L, 0xed756055L, 0xf7960e44L,
-+                                0xe3d35e8cL,
-+                                0x15056dd4L, 0x88f46dbaL, 0x03a16125L,
-+                                0x0564f0bdL,
-+                                0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL,
-+                                0xa93a072aL,
-+                                0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL,
-+                                0x26dcf319L,
-+                                0x7533d928L, 0xb155fdf5L, 0x03563482L,
-+                                0x8aba3cbbL,
-+                                0x28517711L, 0xc20ad9f8L, 0xabcc5167L,
-+                                0xccad925fL,
-+                                0x4de81751L, 0x3830dc8eL, 0x379d5862L,
-+                                0x9320f991L,
-+                                0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L,
-+                                0x774fbe32L,
-+                                0xa8b6e37eL, 0xc3293d46L, 0x48de5369L,
-+                                0x6413e680L,
-+                                0xa2ae0810L, 0xdd6db224L, 0x69852dfdL,
-+                                0x09072166L,
-+                                0xb39a460aL, 0x6445c0ddL, 0x586cdecfL,
-+                                0x1c20c8aeL,
-+                                0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL,
-+                                0x6bb4e3bbL,
-+                                0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L,
-+                                0xbcb4cdd5L,
-+                                0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL,
-+                                0xbf3c6f47L,
-+                                0xd29be463L, 0x542f5d9eL, 0xaec2771bL,
-+                                0xf64e6370L,
-+                                0x740e0d8dL, 0xe75b1357L, 0xf8721671L,
-+                                0xaf537d5dL,
-+                                0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL,
-+                                0x0115af84L,
-+                                0xe1b00428L, 0x95983a1dL, 0x06b89fb4L,
-+                                0xce6ea048L,
-+                                0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL,
-+                                0x277227f8L,
-+                                0x611560b1L, 0xe7933fdcL, 0xbb3a792bL,
-+                                0x344525bdL,
-+                                0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L,
-+                                0xa01fbac9L,
-+                                0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L,
-+                                0xa1e8aac7L,
-+                                0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL,
-+                                0xd50ada38L,
-+                                0x0339c32aL, 0xc6913667L, 0x8df9317cL,
-+                                0xe0b12b4fL,
-+                                0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL,
-+                                0x27d9459cL,
-+                                0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L,
-+                                0x9b941525L,
-+                                0xfae59361L, 0xceb69cebL, 0xc2a86459L,
-+                                0x12baa8d1L,
-+                                0xb6c1075eL, 0xe3056a0cL, 0x10d25065L,
-+                                0xcb03a442L,
-+                                0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL,
-+                                0x3278e964L,
-+                                0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL,
-+                                0x8971f21eL,
-+                                0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L,
-+                                0xc37632d8L,
-+                                0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L,
-+                                0x0fe3f11dL,
-+                                0xe54cda54L, 0x1edad891L, 0xce6279cfL,
-+                                0xcd3e7e6fL,
-+                                0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L,
-+                                0xf6fb2299L,
-+                                0xf523f357L, 0xa6327623L, 0x93a83531L,
-+                                0x56cccd02L,
-+                                0xacf08162L, 0x5a75ebb5L, 0x6e163697L,
-+                                0x88d273ccL,
-+                                0xde966292L, 0x81b949d0L, 0x4c50901bL,
-+                                0x71c65614L,
-+                                0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L,
-+                                0xc3f27b9aL,
-+                                0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L,
-+                                0x35bdd2f6L,
-+                                0x71126905L, 0xb2040222L, 0xb6cbcf7cL,
-+                                0xcd769c2bL,
-+                                0x53113ec0L, 0x1640e3d3L, 0x38abbd60L,
-+                                0x2547adf0L,
-+                                0xba38209cL, 0xf746ce76L, 0x77afa1c5L,
-+                                0x20756060L,
-+                                0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L,
-+                                0x4cf9aa7eL,
-+                                0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L,
-+                                0xd6ebe1f9L,
-+                                0x90d4f869L, 0xa65cdea0L, 0x3f09252dL,
-+                                0xc208e69fL,
-+                                0xb74e6132L, 0xce77e25bL, 0x578fdfe3L,
-+                                0x3ac372e6L,
-+                                }
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_skey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_skey.c
-new file mode 100644
-index 0000000..a4903a2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/bf_skey.c
-@@ -0,0 +1,67 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "bf_locl.h"
-+#include "bf_pi.h"
-+
-+void BF_set_key(BF_KEY *key, int len, const unsigned char *data)
-+{
-+    int i;
-+    BF_LONG *p, ri, in[2];
-+    const unsigned char *d, *end;
-+
-+    memcpy(key, &bf_init, sizeof(BF_KEY));
-+    p = key->P;
-+
-+    if (len > ((BF_ROUNDS + 2) * 4))
-+        len = (BF_ROUNDS + 2) * 4;
-+
-+    d = data;
-+    end = &(data[len]);
-+    for (i = 0; i < (BF_ROUNDS + 2); i++) {
-+        ri = *(d++);
-+        if (d >= end)
-+            d = data;
-+
-+        ri <<= 8;
-+        ri |= *(d++);
-+        if (d >= end)
-+            d = data;
-+
-+        ri <<= 8;
-+        ri |= *(d++);
-+        if (d >= end)
-+            d = data;
-+
-+        ri <<= 8;
-+        ri |= *(d++);
-+        if (d >= end)
-+            d = data;
-+
-+        p[i] ^= ri;
-+    }
-+
-+    in[0] = 0L;
-+    in[1] = 0L;
-+    for (i = 0; i < (BF_ROUNDS + 2); i += 2) {
-+        BF_encrypt(in, key);
-+        p[i] = in[0];
-+        p[i + 1] = in[1];
-+    }
-+
-+    p = key->S;
-+    for (i = 0; i < 4 * 256; i += 2) {
-+        BF_encrypt(in, key);
-+        p[i] = in[0];
-+        p[i + 1] = in[1];
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/build.info
-new file mode 100644
-index 0000000..37a004e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bf/build.info
-@@ -0,0 +1,6 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c \
-+        {- $target{bf_asm_src} -}
-+
-+GENERATE[bf-586.s]=asm/bf-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[bf-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_addr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_addr.c
-new file mode 100644
-index 0000000..0f1900d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_addr.c
-@@ -0,0 +1,897 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#include "bio_lcl.h"
-+#include 
-+
-+#ifndef OPENSSL_NO_SOCK
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifdef _HPUX_SOURCE
-+static const char *ossl_hstrerror(int herr)
-+{
-+    switch (herr) {
-+    case -1:
-+        return strerror(errno);
-+    case 0:
-+        return "No error";
-+    case HOST_NOT_FOUND:
-+        return "Host not found";
-+    case NO_DATA:                /* NO_ADDRESS is a synonym */
-+        return "No data";
-+    case NO_RECOVERY:
-+        return "Non recoverable error";
-+    case TRY_AGAIN:
-+        return "Try again";
-+    default:
-+        break;
-+    }
-+    return "unknown error";
-+}
-+# define hstrerror(e) ossl_hstrerror(e)
-+#endif
-+
-+CRYPTO_RWLOCK *bio_lookup_lock;
-+static CRYPTO_ONCE bio_lookup_init = CRYPTO_ONCE_STATIC_INIT;
-+
-+/*
-+ * Throughout this file and bio_lcl.h, the existence of the macro
-+ * AI_PASSIVE is used to detect the availability of struct addrinfo,
-+ * getnameinfo() and getaddrinfo().  If that macro doesn't exist,
-+ * we use our own implementation instead, using gethostbyname,
-+ * getservbyname and a few other.
-+ */
-+
-+/**********************************************************************
-+ *
-+ * Address structure
-+ *
-+ */
-+
-+BIO_ADDR *BIO_ADDR_new(void)
-+{
-+    BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        BIOerr(BIO_F_BIO_ADDR_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->sa.sa_family = AF_UNSPEC;
-+    return ret;
-+}
-+
-+void BIO_ADDR_free(BIO_ADDR *ap)
-+{
-+    OPENSSL_free(ap);
-+}
-+
-+void BIO_ADDR_clear(BIO_ADDR *ap)
-+{
-+    memset(ap, 0, sizeof(*ap));
-+    ap->sa.sa_family = AF_UNSPEC;
-+}
-+
-+/*
-+ * BIO_ADDR_make - non-public routine to fill a BIO_ADDR with the contents
-+ * of a struct sockaddr.
-+ */
-+int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa)
-+{
-+    if (sa->sa_family == AF_INET) {
-+        ap->s_in = *(const struct sockaddr_in *)sa;
-+        return 1;
-+    }
-+#ifdef AF_INET6
-+    if (sa->sa_family == AF_INET6) {
-+        ap->s_in6 = *(const struct sockaddr_in6 *)sa;
-+        return 1;
-+    }
-+#endif
-+#ifdef AF_UNIX
-+    if (ap->sa.sa_family == AF_UNIX) {
-+        ap->s_un = *(const struct sockaddr_un *)sa;
-+        return 1;
-+    }
-+#endif
-+
-+    return 0;
-+}
-+
-+int BIO_ADDR_rawmake(BIO_ADDR *ap, int family,
-+                     const void *where, size_t wherelen,
-+                     unsigned short port)
-+{
-+#ifdef AF_UNIX
-+    if (family == AF_UNIX) {
-+        if (wherelen + 1 > sizeof(ap->s_un.sun_path))
-+            return 0;
-+        memset(&ap->s_un, 0, sizeof(ap->s_un));
-+        ap->s_un.sun_family = family;
-+        strncpy(ap->s_un.sun_path, where, sizeof(ap->s_un.sun_path) - 1);
-+        return 1;
-+    }
-+#endif
-+    if (family == AF_INET) {
-+        if (wherelen != sizeof(struct in_addr))
-+            return 0;
-+        memset(&ap->s_in, 0, sizeof(ap->s_in));
-+        ap->s_in.sin_family = family;
-+        ap->s_in.sin_port = port;
-+        ap->s_in.sin_addr = *(struct in_addr *)where;
-+        return 1;
-+    }
-+#ifdef AF_INET6
-+    if (family == AF_INET6) {
-+        if (wherelen != sizeof(struct in6_addr))
-+            return 0;
-+        memset(&ap->s_in6, 0, sizeof(ap->s_in6));
-+        ap->s_in6.sin6_family = family;
-+        ap->s_in6.sin6_port = port;
-+        ap->s_in6.sin6_addr = *(struct in6_addr *)where;
-+        return 1;
-+    }
-+#endif
-+
-+    return 0;
-+}
-+
-+int BIO_ADDR_family(const BIO_ADDR *ap)
-+{
-+    return ap->sa.sa_family;
-+}
-+
-+int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l)
-+{
-+    size_t len = 0;
-+    const void *addrptr = NULL;
-+
-+    if (ap->sa.sa_family == AF_INET) {
-+        len = sizeof(ap->s_in.sin_addr);
-+        addrptr = &ap->s_in.sin_addr;
-+    }
-+#ifdef AF_INET6
-+    else if (ap->sa.sa_family == AF_INET6) {
-+        len = sizeof(ap->s_in6.sin6_addr);
-+        addrptr = &ap->s_in6.sin6_addr;
-+    }
-+#endif
-+#ifdef AF_UNIX
-+    else if (ap->sa.sa_family == AF_UNIX) {
-+        len = strlen(ap->s_un.sun_path);
-+        addrptr = &ap->s_un.sun_path;
-+    }
-+#endif
-+
-+    if (addrptr == NULL)
-+        return 0;
-+
-+    if (p != NULL) {
-+        memcpy(p, addrptr, len);
-+    }
-+    if (l != NULL)
-+        *l = len;
-+
-+    return 1;
-+}
-+
-+unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap)
-+{
-+    if (ap->sa.sa_family == AF_INET)
-+        return ap->s_in.sin_port;
-+#ifdef AF_INET6
-+    if (ap->sa.sa_family == AF_INET6)
-+        return ap->s_in6.sin6_port;
-+#endif
-+    return 0;
-+}
-+
-+/*-
-+ * addr_strings - helper function to get host and service names
-+ * @ap: the BIO_ADDR that has the input info
-+ * @numeric: 0 if actual names should be returned, 1 if the numeric
-+ * representation should be returned.
-+ * @hostname: a pointer to a pointer to a memory area to store the
-+ * host name or numeric representation.  Unused if NULL.
-+ * @service: a pointer to a pointer to a memory area to store the
-+ * service name or numeric representation.  Unused if NULL.
-+ *
-+ * The return value is 0 on failure, with the error code in the error
-+ * stack, and 1 on success.
-+ */
-+static int addr_strings(const BIO_ADDR *ap, int numeric,
-+                        char **hostname, char **service)
-+{
-+    if (BIO_sock_init() != 1)
-+        return 0;
-+
-+    if (1) {
-+#ifdef AI_PASSIVE
-+        int ret = 0;
-+        char host[NI_MAXHOST] = "", serv[NI_MAXSERV] = "";
-+        int flags = 0;
-+
-+        if (numeric)
-+            flags |= NI_NUMERICHOST | NI_NUMERICSERV;
-+
-+        if ((ret = getnameinfo(BIO_ADDR_sockaddr(ap),
-+                               BIO_ADDR_sockaddr_size(ap),
-+                               host, sizeof(host), serv, sizeof(serv),
-+                               flags)) != 0) {
-+# ifdef EAI_SYSTEM
-+            if (ret == EAI_SYSTEM) {
-+                SYSerr(SYS_F_GETNAMEINFO, get_last_socket_error());
-+                BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
-+            } else
-+# endif
-+            {
-+                BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
-+                ERR_add_error_data(1, gai_strerror(ret));
-+            }
-+            return 0;
-+        }
-+
-+        /* VMS getnameinfo() has a bug, it doesn't fill in serv, which
-+         * leaves it with whatever garbage that happens to be there.
-+         * However, we initialise serv with the empty string (serv[0]
-+         * is therefore NUL), so it gets real easy to detect when things
-+         * didn't go the way one might expect.
-+         */
-+        if (serv[0] == '\0') {
-+            BIO_snprintf(serv, sizeof(serv), "%d",
-+                         ntohs(BIO_ADDR_rawport(ap)));
-+        }
-+
-+        if (hostname != NULL)
-+            *hostname = OPENSSL_strdup(host);
-+        if (service != NULL)
-+            *service = OPENSSL_strdup(serv);
-+    } else {
-+#endif
-+        if (hostname != NULL)
-+            *hostname = OPENSSL_strdup(inet_ntoa(ap->s_in.sin_addr));
-+        if (service != NULL) {
-+            char serv[6];        /* port is 16 bits => max 5 decimal digits */
-+            BIO_snprintf(serv, sizeof(serv), "%d", ntohs(ap->s_in.sin_port));
-+            *service = OPENSSL_strdup(serv);
-+        }
-+    }
-+
-+    if ((hostname != NULL && *hostname == NULL)
-+            || (service != NULL && *service == NULL)) {
-+        if (hostname != NULL) {
-+            OPENSSL_free(*hostname);
-+            *hostname = NULL;
-+        }
-+        if (service != NULL) {
-+            OPENSSL_free(*service);
-+            *service = NULL;
-+        }
-+        BIOerr(BIO_F_ADDR_STRINGS, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric)
-+{
-+    char *hostname = NULL;
-+
-+    if (addr_strings(ap, numeric, &hostname, NULL))
-+        return hostname;
-+
-+    return NULL;
-+}
-+
-+char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric)
-+{
-+    char *service = NULL;
-+
-+    if (addr_strings(ap, numeric, NULL, &service))
-+        return service;
-+
-+    return NULL;
-+}
-+
-+char *BIO_ADDR_path_string(const BIO_ADDR *ap)
-+{
-+#ifdef AF_UNIX
-+    if (ap->sa.sa_family == AF_UNIX)
-+        return OPENSSL_strdup(ap->s_un.sun_path);
-+#endif
-+    return NULL;
-+}
-+
-+/*
-+ * BIO_ADDR_sockaddr - non-public routine to return the struct sockaddr
-+ * for a given BIO_ADDR.  In reality, this is simply a type safe cast.
-+ * The returned struct sockaddr is const, so it can't be tampered with.
-+ */
-+const struct sockaddr *BIO_ADDR_sockaddr(const BIO_ADDR *ap)
-+{
-+    return &(ap->sa);
-+}
-+
-+/*
-+ * BIO_ADDR_sockaddr_noconst - non-public function that does the same
-+ * as BIO_ADDR_sockaddr, but returns a non-const.  USE WITH CARE, as
-+ * it allows you to tamper with the data (and thereby the contents
-+ * of the input BIO_ADDR).
-+ */
-+struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap)
-+{
-+    return &(ap->sa);
-+}
-+
-+/*
-+ * BIO_ADDR_sockaddr_size - non-public function that returns the size
-+ * of the struct sockaddr the BIO_ADDR is using.  If the protocol family
-+ * isn't set or is something other than AF_INET, AF_INET6 or AF_UNIX,
-+ * the size of the BIO_ADDR type is returned.
-+ */
-+socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap)
-+{
-+    if (ap->sa.sa_family == AF_INET)
-+        return sizeof(ap->s_in);
-+#ifdef AF_INET6
-+    if (ap->sa.sa_family == AF_INET6)
-+        return sizeof(ap->s_in6);
-+#endif
-+#ifdef AF_UNIX
-+    if (ap->sa.sa_family == AF_UNIX)
-+        return sizeof(ap->s_un);
-+#endif
-+    return sizeof(*ap);
-+}
-+
-+/**********************************************************************
-+ *
-+ * Address info database
-+ *
-+ */
-+
-+const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai)
-+{
-+    if (bai != NULL)
-+        return bai->bai_next;
-+    return NULL;
-+}
-+
-+int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai)
-+{
-+    if (bai != NULL)
-+        return bai->bai_family;
-+    return 0;
-+}
-+
-+int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai)
-+{
-+    if (bai != NULL)
-+        return bai->bai_socktype;
-+    return 0;
-+}
-+
-+int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai)
-+{
-+    if (bai != NULL) {
-+        if (bai->bai_protocol != 0)
-+            return bai->bai_protocol;
-+
-+#ifdef AF_UNIX
-+        if (bai->bai_family == AF_UNIX)
-+            return 0;
-+#endif
-+
-+        switch (bai->bai_socktype) {
-+        case SOCK_STREAM:
-+            return IPPROTO_TCP;
-+        case SOCK_DGRAM:
-+            return IPPROTO_UDP;
-+        default:
-+            break;
-+        }
-+    }
-+    return 0;
-+}
-+
-+/*
-+ * BIO_ADDRINFO_sockaddr_size - non-public function that returns the size
-+ * of the struct sockaddr inside the BIO_ADDRINFO.
-+ */
-+socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai)
-+{
-+    if (bai != NULL)
-+        return bai->bai_addrlen;
-+    return 0;
-+}
-+
-+/*
-+ * BIO_ADDRINFO_sockaddr - non-public function that returns bai_addr
-+ * as the struct sockaddr it is.
-+ */
-+const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai)
-+{
-+    if (bai != NULL)
-+        return bai->bai_addr;
-+    return NULL;
-+}
-+
-+const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai)
-+{
-+    if (bai != NULL)
-+        return (BIO_ADDR *)bai->bai_addr;
-+    return NULL;
-+}
-+
-+void BIO_ADDRINFO_free(BIO_ADDRINFO *bai)
-+{
-+    if (bai == NULL)
-+        return;
-+
-+#ifdef AI_PASSIVE
-+# ifdef AF_UNIX
-+#  define _cond bai->bai_family != AF_UNIX
-+# else
-+#  define _cond 1
-+# endif
-+    if (_cond) {
-+        freeaddrinfo(bai);
-+        return;
-+    }
-+#endif
-+
-+    /* Free manually when we know that addrinfo_wrap() was used.
-+     * See further comment above addrinfo_wrap()
-+     */
-+    while (bai != NULL) {
-+        BIO_ADDRINFO *next = bai->bai_next;
-+        OPENSSL_free(bai->bai_addr);
-+        OPENSSL_free(bai);
-+        bai = next;
-+    }
-+}
-+
-+/**********************************************************************
-+ *
-+ * Service functions
-+ *
-+ */
-+
-+/*-
-+ * The specs in hostserv can take these forms:
-+ *
-+ * host:service         => *host = "host", *service = "service"
-+ * host:*               => *host = "host", *service = NULL
-+ * host:                => *host = "host", *service = NULL
-+ * :service             => *host = NULL, *service = "service"
-+ * *:service            => *host = NULL, *service = "service"
-+ *
-+ * in case no : is present in the string, the result depends on
-+ * hostserv_prio, as follows:
-+ *
-+ * when hostserv_prio == BIO_PARSE_PRIO_HOST
-+ * host                 => *host = "host", *service untouched
-+ *
-+ * when hostserv_prio == BIO_PARSE_PRIO_SERV
-+ * service              => *host untouched, *service = "service"
-+ *
-+ */
-+int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
-+                       enum BIO_hostserv_priorities hostserv_prio)
-+{
-+    const char *h = NULL; size_t hl = 0;
-+    const char *p = NULL; size_t pl = 0;
-+
-+    if (*hostserv == '[') {
-+        if ((p = strchr(hostserv, ']')) == NULL)
-+            goto spec_err;
-+        h = hostserv + 1;
-+        hl = p - h;
-+        p++;
-+        if (*p == '\0')
-+            p = NULL;
-+        else if (*p != ':')
-+            goto spec_err;
-+        else {
-+            p++;
-+            pl = strlen(p);
-+        }
-+    } else {
-+        const char *p2 = strrchr(hostserv, ':');
-+        p = strchr(hostserv, ':');
-+
-+        /*-
-+         * Check for more than one colon.  There are three possible
-+         * interpretations:
-+         * 1. IPv6 address with port number, last colon being separator.
-+         * 2. IPv6 address only.
-+         * 3. IPv6 address only if hostserv_prio == BIO_PARSE_PRIO_HOST,
-+         *    IPv6 address and port number if hostserv_prio == BIO_PARSE_PRIO_SERV
-+         * Because of this ambiguity, we currently choose to make it an
-+         * error.
-+         */
-+        if (p != p2)
-+            goto amb_err;
-+
-+        if (p != NULL) {
-+            h = hostserv;
-+            hl = p - h;
-+            p++;
-+            pl = strlen(p);
-+        } else if (hostserv_prio == BIO_PARSE_PRIO_HOST) {
-+            h = hostserv;
-+            hl = strlen(h);
-+        } else {
-+            p = hostserv;
-+            pl = strlen(p);
-+        }
-+    }
-+
-+    if (p != NULL && strchr(p, ':'))
-+        goto spec_err;
-+
-+    if (h != NULL && host != NULL) {
-+        if (hl == 0
-+            || (hl == 1 && h[0] == '*')) {
-+            *host = NULL;
-+        } else {
-+            *host = OPENSSL_strndup(h, hl);
-+            if (*host == NULL)
-+                goto memerr;
-+        }
-+    }
-+    if (p != NULL && service != NULL) {
-+        if (pl == 0
-+            || (pl == 1 && p[0] == '*')) {
-+            *service = NULL;
-+        } else {
-+            *service = OPENSSL_strndup(p, pl);
-+            if (*service == NULL)
-+                goto memerr;
-+        }
-+    }
-+
-+    return 1;
-+ amb_err:
-+    BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_AMBIGUOUS_HOST_OR_SERVICE);
-+    return 0;
-+ spec_err:
-+    BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_MALFORMED_HOST_OR_SERVICE);
-+    return 0;
-+ memerr:
-+    BIOerr(BIO_F_BIO_PARSE_HOSTSERV, ERR_R_MALLOC_FAILURE);
-+    return 0;
-+}
-+
-+/* addrinfo_wrap is used to build our own addrinfo "chain".
-+ * (it has only one entry, so calling it a chain may be a stretch)
-+ * It should ONLY be called when getaddrinfo() and friends
-+ * aren't available, OR when dealing with a non IP protocol
-+ * family, such as AF_UNIX
-+ *
-+ * the return value is 1 on success, or 0 on failure, which
-+ * only happens if a memory allocation error occurred.
-+ */
-+static int addrinfo_wrap(int family, int socktype,
-+                         const void *where, size_t wherelen,
-+                         unsigned short port,
-+                         BIO_ADDRINFO **bai)
-+{
-+    OPENSSL_assert(bai != NULL);
-+
-+    *bai = OPENSSL_zalloc(sizeof(**bai));
-+    if (*bai == NULL)
-+        return 0;
-+
-+    (*bai)->bai_family = family;
-+    (*bai)->bai_socktype = socktype;
-+    if (socktype == SOCK_STREAM)
-+        (*bai)->bai_protocol = IPPROTO_TCP;
-+    if (socktype == SOCK_DGRAM)
-+        (*bai)->bai_protocol = IPPROTO_UDP;
-+#ifdef AF_UNIX
-+    if (family == AF_UNIX)
-+        (*bai)->bai_protocol = 0;
-+#endif
-+    {
-+        /* Magic: We know that BIO_ADDR_sockaddr_noconst is really
-+           just an advanced cast of BIO_ADDR* to struct sockaddr *
-+           by the power of union, so while it may seem that we're
-+           creating a memory leak here, we are not.  It will be
-+           all right. */
-+        BIO_ADDR *addr = BIO_ADDR_new();
-+        if (addr != NULL) {
-+            BIO_ADDR_rawmake(addr, family, where, wherelen, port);
-+            (*bai)->bai_addr = BIO_ADDR_sockaddr_noconst(addr);
-+        }
-+    }
-+    (*bai)->bai_next = NULL;
-+    if ((*bai)->bai_addr == NULL) {
-+        BIO_ADDRINFO_free(*bai);
-+        *bai = NULL;
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init)
-+{
-+    OPENSSL_init_crypto(0, NULL);
-+    bio_lookup_lock = CRYPTO_THREAD_lock_new();
-+    return bio_lookup_lock != NULL;
-+}
-+
-+/*-
-+ * BIO_lookup - look up the node and service you want to connect to.
-+ * @node: the node you want to connect to.
-+ * @service: the service you want to connect to.
-+ * @lookup_type: declare intent with the result, client or server.
-+ * @family: the address family you want to use.  Use AF_UNSPEC for any, or
-+ *  AF_INET, AF_INET6 or AF_UNIX.
-+ * @socktype: The socket type you want to use.  Can be SOCK_STREAM, SOCK_DGRAM
-+ *  or 0 for all.
-+ * @res: Storage place for the resulting list of returned addresses
-+ *
-+ * This will do a lookup of the node and service that you want to connect to.
-+ * It returns a linked list of different addresses you can try to connect to.
-+ *
-+ * When no longer needed you should call BIO_ADDRINFO_free() to free the result.
-+ *
-+ * The return value is 1 on success or 0 in case of error.
-+ */
-+int BIO_lookup(const char *host, const char *service,
-+               enum BIO_lookup_type lookup_type,
-+               int family, int socktype, BIO_ADDRINFO **res)
-+{
-+    int ret = 0;                 /* Assume failure */
-+
-+    switch(family) {
-+    case AF_INET:
-+#ifdef AF_INET6
-+    case AF_INET6:
-+#endif
-+#ifdef AF_UNIX
-+    case AF_UNIX:
-+#endif
-+#ifdef AF_UNSPEC
-+    case AF_UNSPEC:
-+#endif
-+        break;
-+    default:
-+        BIOerr(BIO_F_BIO_LOOKUP, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
-+        return 0;
-+    }
-+
-+#ifdef AF_UNIX
-+    if (family == AF_UNIX) {
-+        if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
-+            return 1;
-+        else
-+            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+#endif
-+
-+    if (BIO_sock_init() != 1)
-+        return 0;
-+
-+    if (1) {
-+        int gai_ret = 0;
-+#ifdef AI_PASSIVE
-+        struct addrinfo hints;
-+        memset(&hints, 0, sizeof hints);
-+
-+        hints.ai_family = family;
-+        hints.ai_socktype = socktype;
-+
-+        if (lookup_type == BIO_LOOKUP_SERVER)
-+            hints.ai_flags |= AI_PASSIVE;
-+
-+        /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
-+         * macro magic in bio_lcl.h
-+         */
-+        switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
-+# ifdef EAI_SYSTEM
-+        case EAI_SYSTEM:
-+            SYSerr(SYS_F_GETADDRINFO, get_last_socket_error());
-+            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
-+            break;
-+# endif
-+        case 0:
-+            ret = 1;             /* Success */
-+            break;
-+        default:
-+            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
-+            ERR_add_error_data(1, gai_strerror(gai_ret));
-+            break;
-+        }
-+    } else {
-+#endif
-+        const struct hostent *he;
-+/*
-+ * Because struct hostent is defined for 32-bit pointers only with
-+ * VMS C, we need to make sure that '&he_fallback_address' and
-+ * '&he_fallback_addresses' are 32-bit pointers
-+ */
-+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-+# pragma pointer_size save
-+# pragma pointer_size 32
-+#endif
-+        /* Windows doesn't seem to have in_addr_t */
-+#ifdef OPENSSL_SYS_WINDOWS
-+        static uint32_t he_fallback_address;
-+        static const char *he_fallback_addresses[] =
-+            { (char *)&he_fallback_address, NULL };
-+#else
-+        static in_addr_t he_fallback_address;
-+        static const char *he_fallback_addresses[] =
-+            { (char *)&he_fallback_address, NULL };
-+#endif
-+        static const struct hostent he_fallback =
-+            { NULL, NULL, AF_INET, sizeof(he_fallback_address),
-+              (char **)&he_fallback_addresses };
-+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-+# pragma pointer_size restore
-+#endif
-+
-+        struct servent *se;
-+        /* Apparently, on WIN64, s_proto and s_port have traded places... */
-+#ifdef _WIN64
-+        struct servent se_fallback = { NULL, NULL, NULL, 0 };
-+#else
-+        struct servent se_fallback = { NULL, NULL, 0, NULL };
-+#endif
-+
-+        if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) {
-+            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
-+            ret = 0;
-+            goto err;
-+        }
-+
-+        CRYPTO_THREAD_write_lock(bio_lookup_lock);
-+        he_fallback_address = INADDR_ANY;
-+        if (host == NULL) {
-+            he = &he_fallback;
-+            switch(lookup_type) {
-+            case BIO_LOOKUP_CLIENT:
-+                he_fallback_address = INADDR_LOOPBACK;
-+                break;
-+            case BIO_LOOKUP_SERVER:
-+                he_fallback_address = INADDR_ANY;
-+                break;
-+            default:
-+                OPENSSL_assert(("We forgot to handle a lookup type!" == 0));
-+                break;
-+            }
-+        } else {
-+            he = gethostbyname(host);
-+
-+            if (he == NULL) {
-+#ifndef OPENSSL_SYS_WINDOWS
-+                BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
-+                ERR_add_error_data(1, hstrerror(h_errno));
-+#else
-+                SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError());
-+#endif
-+                ret = 0;
-+                goto err;
-+            }
-+        }
-+
-+        if (service == NULL) {
-+            se_fallback.s_port = 0;
-+            se_fallback.s_proto = NULL;
-+            se = &se_fallback;
-+        } else {
-+            char *endp = NULL;
-+            long portnum = strtol(service, &endp, 10);
-+
-+/*
-+ * Because struct servent is defined for 32-bit pointers only with
-+ * VMS C, we need to make sure that 'proto' is a 32-bit pointer.
-+ */
-+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-+# pragma pointer_size save
-+# pragma pointer_size 32
-+#endif
-+            char *proto = NULL;
-+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-+# pragma pointer_size restore
-+#endif
-+
-+            switch (socktype) {
-+            case SOCK_STREAM:
-+                proto = "tcp";
-+                break;
-+            case SOCK_DGRAM:
-+                proto = "udp";
-+                break;
-+            }
-+
-+            if (endp != service && *endp == '\0'
-+                    && portnum > 0 && portnum < 65536) {
-+                se_fallback.s_port = htons(portnum);
-+                se_fallback.s_proto = proto;
-+                se = &se_fallback;
-+            } else if (endp == service) {
-+                se = getservbyname(service, proto);
-+
-+                if (se == NULL) {
-+#ifndef OPENSSL_SYS_WINDOWS
-+                    BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
-+                    ERR_add_error_data(1, hstrerror(h_errno));
-+#else
-+                    SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError());
-+#endif
-+                    goto err;
-+                }
-+            } else {
-+                BIOerr(BIO_F_BIO_LOOKUP, BIO_R_MALFORMED_HOST_OR_SERVICE);
-+                goto err;
-+            }
-+        }
-+
-+        *res = NULL;
-+
-+        {
-+/*
-+ * Because hostent::h_addr_list is an array of 32-bit pointers with VMS C,
-+ * we must make sure our iterator designates the same element type, hence
-+ * the pointer size dance.
-+ */
-+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-+# pragma pointer_size save
-+# pragma pointer_size 32
-+#endif
-+            char **addrlistp;
-+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
-+# pragma pointer_size restore
-+#endif
-+            size_t addresses;
-+            BIO_ADDRINFO *tmp_bai = NULL;
-+
-+            /* The easiest way to create a linked list from an
-+               array is to start from the back */
-+            for(addrlistp = he->h_addr_list; *addrlistp != NULL;
-+                addrlistp++)
-+                ;
-+
-+            for(addresses = addrlistp - he->h_addr_list;
-+                addrlistp--, addresses-- > 0; ) {
-+                if (!addrinfo_wrap(he->h_addrtype, socktype,
-+                                   *addrlistp, he->h_length,
-+                                   se->s_port, &tmp_bai))
-+                    goto addrinfo_malloc_err;
-+                tmp_bai->bai_next = *res;
-+                *res = tmp_bai;
-+                continue;
-+             addrinfo_malloc_err:
-+                BIO_ADDRINFO_free(*res);
-+                *res = NULL;
-+                BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
-+                ret = 0;
-+                goto err;
-+            }
-+
-+            ret = 1;
-+        }
-+     err:
-+        CRYPTO_THREAD_unlock(bio_lookup_lock);
-+    }
-+
-+    return ret;
-+}
-+
-+#endif /* OPENSSL_NO_SOCK */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_dump.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_dump.c
-new file mode 100644
-index 0000000..a27954f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_dump.c
-@@ -0,0 +1,158 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Stolen from tjh's ssl/ssl_trc.c stuff.
-+ */
-+
-+#include 
-+#include "bio_lcl.h"
-+
-+#define TRUNCATE
-+#define DUMP_WIDTH      16
-+#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4))
-+
-+int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
-+                void *u, const char *s, int len)
-+{
-+    return BIO_dump_indent_cb(cb, u, s, len, 0);
-+}
-+
-+int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
-+                       void *u, const char *s, int len, int indent)
-+{
-+    int ret = 0;
-+    char buf[288 + 1], tmp[20], str[128 + 1];
-+    int i, j, rows, trc;
-+    unsigned char ch;
-+    int dump_width;
-+
-+    trc = 0;
-+
-+#ifdef TRUNCATE
-+    for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
-+        trc++;
-+#endif
-+
-+    if (indent < 0)
-+        indent = 0;
-+    if (indent) {
-+        if (indent > 128)
-+            indent = 128;
-+        memset(str, ' ', indent);
-+    }
-+    str[indent] = '\0';
-+
-+    dump_width = DUMP_WIDTH_LESS_INDENT(indent);
-+    rows = (len / dump_width);
-+    if ((rows * dump_width) < len)
-+        rows++;
-+    for (i = 0; i < rows; i++) {
-+        OPENSSL_strlcpy(buf, str, sizeof buf);
-+        BIO_snprintf(tmp, sizeof tmp, "%04x - ", i * dump_width);
-+        OPENSSL_strlcat(buf, tmp, sizeof buf);
-+        for (j = 0; j < dump_width; j++) {
-+            if (((i * dump_width) + j) >= len) {
-+                OPENSSL_strlcat(buf, "   ", sizeof buf);
-+            } else {
-+                ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
-+                BIO_snprintf(tmp, sizeof tmp, "%02x%c", ch,
-+                             j == 7 ? '-' : ' ');
-+                OPENSSL_strlcat(buf, tmp, sizeof buf);
-+            }
-+        }
-+        OPENSSL_strlcat(buf, "  ", sizeof buf);
-+        for (j = 0; j < dump_width; j++) {
-+            if (((i * dump_width) + j) >= len)
-+                break;
-+            ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
-+#ifndef CHARSET_EBCDIC
-+            BIO_snprintf(tmp, sizeof tmp, "%c",
-+                         ((ch >= ' ') && (ch <= '~')) ? ch : '.');
-+#else
-+            BIO_snprintf(tmp, sizeof tmp, "%c",
-+                         ((ch >= os_toascii[' ']) && (ch <= os_toascii['~']))
-+                         ? os_toebcdic[ch]
-+                         : '.');
-+#endif
-+            OPENSSL_strlcat(buf, tmp, sizeof buf);
-+        }
-+        OPENSSL_strlcat(buf, "\n", sizeof buf);
-+        /*
-+         * if this is the last call then update the ddt_dump thing so that we
-+         * will move the selection point in the debug window
-+         */
-+        ret += cb((void *)buf, strlen(buf), u);
-+    }
-+#ifdef TRUNCATE
-+    if (trc > 0) {
-+        BIO_snprintf(buf, sizeof buf, "%s%04x - \n", str,
-+                     len + trc);
-+        ret += cb((void *)buf, strlen(buf), u);
-+    }
-+#endif
-+    return (ret);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+static int write_fp(const void *data, size_t len, void *fp)
-+{
-+    return UP_fwrite(data, len, 1, fp);
-+}
-+
-+int BIO_dump_fp(FILE *fp, const char *s, int len)
-+{
-+    return BIO_dump_cb(write_fp, fp, s, len);
-+}
-+
-+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
-+{
-+    return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
-+}
-+#endif
-+
-+static int write_bio(const void *data, size_t len, void *bp)
-+{
-+    return BIO_write((BIO *)bp, (const char *)data, len);
-+}
-+
-+int BIO_dump(BIO *bp, const char *s, int len)
-+{
-+    return BIO_dump_cb(write_bio, bp, s, len);
-+}
-+
-+int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
-+{
-+    return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
-+}
-+
-+int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
-+                   int datalen)
-+{
-+    int i, j = 0;
-+
-+    if (datalen < 1)
-+        return 1;
-+
-+    for (i = 0; i < datalen - 1; i++) {
-+        if (i && !j)
-+            BIO_printf(out, "%*s", indent, "");
-+
-+        BIO_printf(out, "%02X:", data[i]);
-+
-+        j = (j + 1) % width;
-+        if (!j)
-+            BIO_printf(out, "\n");
-+    }
-+
-+    if (i && !j)
-+        BIO_printf(out, "%*s", indent, "");
-+    BIO_printf(out, "%02X", data[datalen - 1]);
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_print.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_print.c
-new file mode 100644
-index 0000000..e91ab6d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_print.c
-@@ -0,0 +1,944 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/numbers.h"
-+#include "internal/cryptlib.h"
-+#ifndef NO_SYS_TYPES_H
-+# include 
-+#endif
-+#include          /* To get BN_LLONG properly defined */
-+#include 
-+
-+#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
-+# ifndef HAVE_LONG_LONG
-+#  define HAVE_LONG_LONG 1
-+# endif
-+#endif
-+
-+/*
-+ * Copyright Patrick Powell 1995
-+ * This code is based on code written by Patrick Powell 
-+ * It may be used for any purpose as long as this notice remains intact
-+ * on all source code distributions.
-+ */
-+
-+#ifdef HAVE_LONG_DOUBLE
-+# define LDOUBLE long double
-+#else
-+# define LDOUBLE double
-+#endif
-+
-+#ifdef HAVE_LONG_LONG
-+# if defined(_WIN32) && !defined(__GNUC__)
-+#  define LLONG __int64
-+# else
-+#  define LLONG long long
-+# endif
-+#else
-+# define LLONG long
-+#endif
-+
-+static int fmtstr(char **, char **, size_t *, size_t *,
-+                  const char *, int, int, int);
-+static int fmtint(char **, char **, size_t *, size_t *,
-+                  LLONG, int, int, int, int);
-+static int fmtfp(char **, char **, size_t *, size_t *,
-+                 LDOUBLE, int, int, int, int);
-+static int doapr_outch(char **, char **, size_t *, size_t *, int);
-+static int _dopr(char **sbuffer, char **buffer,
-+                 size_t *maxlen, size_t *retlen, int *truncated,
-+                 const char *format, va_list args);
-+
-+/* format read states */
-+#define DP_S_DEFAULT    0
-+#define DP_S_FLAGS      1
-+#define DP_S_MIN        2
-+#define DP_S_DOT        3
-+#define DP_S_MAX        4
-+#define DP_S_MOD        5
-+#define DP_S_CONV       6
-+#define DP_S_DONE       7
-+
-+/* format flags - Bits */
-+/* left-aligned padding */
-+#define DP_F_MINUS      (1 << 0)
-+/* print an explicit '+' for a value with positive sign */
-+#define DP_F_PLUS       (1 << 1)
-+/* print an explicit ' ' for a value with positive sign */
-+#define DP_F_SPACE      (1 << 2)
-+/* print 0/0x prefix for octal/hex and decimal point for floating point */
-+#define DP_F_NUM        (1 << 3)
-+/* print leading zeroes */
-+#define DP_F_ZERO       (1 << 4)
-+/* print HEX in UPPPERcase */
-+#define DP_F_UP         (1 << 5)
-+/* treat value as unsigned */
-+#define DP_F_UNSIGNED   (1 << 6)
-+
-+/* conversion flags */
-+#define DP_C_SHORT      1
-+#define DP_C_LONG       2
-+#define DP_C_LDOUBLE    3
-+#define DP_C_LLONG      4
-+
-+/* Floating point formats */
-+#define F_FORMAT        0
-+#define E_FORMAT        1
-+#define G_FORMAT        2
-+
-+/* some handy macros */
-+#define char_to_int(p) (p - '0')
-+#define OSSL_MAX(p,q) ((p >= q) ? p : q)
-+
-+static int
-+_dopr(char **sbuffer,
-+      char **buffer,
-+      size_t *maxlen,
-+      size_t *retlen, int *truncated, const char *format, va_list args)
-+{
-+    char ch;
-+    LLONG value;
-+    LDOUBLE fvalue;
-+    char *strvalue;
-+    int min;
-+    int max;
-+    int state;
-+    int flags;
-+    int cflags;
-+    size_t currlen;
-+
-+    state = DP_S_DEFAULT;
-+    flags = currlen = cflags = min = 0;
-+    max = -1;
-+    ch = *format++;
-+
-+    while (state != DP_S_DONE) {
-+        if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
-+            state = DP_S_DONE;
-+
-+        switch (state) {
-+        case DP_S_DEFAULT:
-+            if (ch == '%')
-+                state = DP_S_FLAGS;
-+            else
-+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
-+                    return 0;
-+            ch = *format++;
-+            break;
-+        case DP_S_FLAGS:
-+            switch (ch) {
-+            case '-':
-+                flags |= DP_F_MINUS;
-+                ch = *format++;
-+                break;
-+            case '+':
-+                flags |= DP_F_PLUS;
-+                ch = *format++;
-+                break;
-+            case ' ':
-+                flags |= DP_F_SPACE;
-+                ch = *format++;
-+                break;
-+            case '#':
-+                flags |= DP_F_NUM;
-+                ch = *format++;
-+                break;
-+            case '0':
-+                flags |= DP_F_ZERO;
-+                ch = *format++;
-+                break;
-+            default:
-+                state = DP_S_MIN;
-+                break;
-+            }
-+            break;
-+        case DP_S_MIN:
-+            if (isdigit((unsigned char)ch)) {
-+                min = 10 * min + char_to_int(ch);
-+                ch = *format++;
-+            } else if (ch == '*') {
-+                min = va_arg(args, int);
-+                ch = *format++;
-+                state = DP_S_DOT;
-+            } else
-+                state = DP_S_DOT;
-+            break;
-+        case DP_S_DOT:
-+            if (ch == '.') {
-+                state = DP_S_MAX;
-+                ch = *format++;
-+            } else
-+                state = DP_S_MOD;
-+            break;
-+        case DP_S_MAX:
-+            if (isdigit((unsigned char)ch)) {
-+                if (max < 0)
-+                    max = 0;
-+                max = 10 * max + char_to_int(ch);
-+                ch = *format++;
-+            } else if (ch == '*') {
-+                max = va_arg(args, int);
-+                ch = *format++;
-+                state = DP_S_MOD;
-+            } else
-+                state = DP_S_MOD;
-+            break;
-+        case DP_S_MOD:
-+            switch (ch) {
-+            case 'h':
-+                cflags = DP_C_SHORT;
-+                ch = *format++;
-+                break;
-+            case 'l':
-+                if (*format == 'l') {
-+                    cflags = DP_C_LLONG;
-+                    format++;
-+                } else
-+                    cflags = DP_C_LONG;
-+                ch = *format++;
-+                break;
-+            case 'q':
-+                cflags = DP_C_LLONG;
-+                ch = *format++;
-+                break;
-+            case 'L':
-+                cflags = DP_C_LDOUBLE;
-+                ch = *format++;
-+                break;
-+            default:
-+                break;
-+            }
-+            state = DP_S_CONV;
-+            break;
-+        case DP_S_CONV:
-+            switch (ch) {
-+            case 'd':
-+            case 'i':
-+                switch (cflags) {
-+                case DP_C_SHORT:
-+                    value = (short int)va_arg(args, int);
-+                    break;
-+                case DP_C_LONG:
-+                    value = va_arg(args, long int);
-+                    break;
-+                case DP_C_LLONG:
-+                    value = va_arg(args, LLONG);
-+                    break;
-+                default:
-+                    value = va_arg(args, int);
-+                    break;
-+                }
-+                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
-+                            max, flags))
-+                    return 0;
-+                break;
-+            case 'X':
-+                flags |= DP_F_UP;
-+                /* FALLTHROUGH */
-+            case 'x':
-+            case 'o':
-+            case 'u':
-+                flags |= DP_F_UNSIGNED;
-+                switch (cflags) {
-+                case DP_C_SHORT:
-+                    value = (unsigned short int)va_arg(args, unsigned int);
-+                    break;
-+                case DP_C_LONG:
-+                    value = (LLONG) va_arg(args, unsigned long int);
-+                    break;
-+                case DP_C_LLONG:
-+                    value = va_arg(args, unsigned LLONG);
-+                    break;
-+                default:
-+                    value = (LLONG) va_arg(args, unsigned int);
-+                    break;
-+                }
-+                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
-+                            ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
-+                            min, max, flags))
-+                    return 0;
-+                break;
-+            case 'f':
-+                if (cflags == DP_C_LDOUBLE)
-+                    fvalue = va_arg(args, LDOUBLE);
-+                else
-+                    fvalue = va_arg(args, double);
-+                if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
-+                           flags, F_FORMAT))
-+                    return 0;
-+                break;
-+            case 'E':
-+                flags |= DP_F_UP;
-+            case 'e':
-+                if (cflags == DP_C_LDOUBLE)
-+                    fvalue = va_arg(args, LDOUBLE);
-+                else
-+                    fvalue = va_arg(args, double);
-+                if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
-+                           flags, E_FORMAT))
-+                    return 0;
-+                break;
-+            case 'G':
-+                flags |= DP_F_UP;
-+            case 'g':
-+                if (cflags == DP_C_LDOUBLE)
-+                    fvalue = va_arg(args, LDOUBLE);
-+                else
-+                    fvalue = va_arg(args, double);
-+                if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
-+                           flags, G_FORMAT))
-+                    return 0;
-+                break;
-+            case 'c':
-+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
-+                            va_arg(args, int)))
-+                    return 0;
-+                break;
-+            case 's':
-+                strvalue = va_arg(args, char *);
-+                if (max < 0) {
-+                    if (buffer)
-+                        max = INT_MAX;
-+                    else
-+                        max = *maxlen;
-+                }
-+                if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
-+                            flags, min, max))
-+                    return 0;
-+                break;
-+            case 'p':
-+                value = (size_t)va_arg(args, void *);
-+                if (!fmtint(sbuffer, buffer, &currlen, maxlen,
-+                            value, 16, min, max, flags | DP_F_NUM))
-+                    return 0;
-+                break;
-+            case 'n':          /* XXX */
-+                if (cflags == DP_C_SHORT) {
-+                    short int *num;
-+                    num = va_arg(args, short int *);
-+                    *num = currlen;
-+                } else if (cflags == DP_C_LONG) { /* XXX */
-+                    long int *num;
-+                    num = va_arg(args, long int *);
-+                    *num = (long int)currlen;
-+                } else if (cflags == DP_C_LLONG) { /* XXX */
-+                    LLONG *num;
-+                    num = va_arg(args, LLONG *);
-+                    *num = (LLONG) currlen;
-+                } else {
-+                    int *num;
-+                    num = va_arg(args, int *);
-+                    *num = currlen;
-+                }
-+                break;
-+            case '%':
-+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
-+                    return 0;
-+                break;
-+            case 'w':
-+                /* not supported yet, treat as next char */
-+                ch = *format++;
-+                break;
-+            default:
-+                /* unknown, skip */
-+                break;
-+            }
-+            ch = *format++;
-+            state = DP_S_DEFAULT;
-+            flags = cflags = min = 0;
-+            max = -1;
-+            break;
-+        case DP_S_DONE:
-+            break;
-+        default:
-+            break;
-+        }
-+    }
-+    /*
-+     * We have to truncate if there is no dynamic buffer and we have filled the
-+     * static buffer.
-+     */
-+    if (buffer == NULL) {
-+        *truncated = (currlen > *maxlen - 1);
-+        if (*truncated)
-+            currlen = *maxlen - 1;
-+    }
-+    if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
-+        return 0;
-+    *retlen = currlen - 1;
-+    return 1;
-+}
-+
-+static int
-+fmtstr(char **sbuffer,
-+       char **buffer,
-+       size_t *currlen,
-+       size_t *maxlen, const char *value, int flags, int min, int max)
-+{
-+    int padlen;
-+    size_t strln;
-+    int cnt = 0;
-+
-+    if (value == 0)
-+        value = "";
-+
-+    strln = OPENSSL_strnlen(value, max < 0 ? SIZE_MAX : (size_t)max);
-+
-+    padlen = min - strln;
-+    if (min < 0 || padlen < 0)
-+        padlen = 0;
-+    if (max >= 0) {
-+        /*
-+         * Calculate the maximum output including padding.
-+         * Make sure max doesn't overflow into negativity
-+         */
-+        if (max < INT_MAX - padlen)
-+            max += padlen;
-+        else
-+            max = INT_MAX;
-+    }
-+    if (flags & DP_F_MINUS)
-+        padlen = -padlen;
-+
-+    while ((padlen > 0) && (max < 0 || cnt < max)) {
-+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
-+            return 0;
-+        --padlen;
-+        ++cnt;
-+    }
-+    while (strln > 0 && (max < 0 || cnt < max)) {
-+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
-+            return 0;
-+        --strln;
-+        ++cnt;
-+    }
-+    while ((padlen < 0) && (max < 0 || cnt < max)) {
-+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
-+            return 0;
-+        ++padlen;
-+        ++cnt;
-+    }
-+    return 1;
-+}
-+
-+static int
-+fmtint(char **sbuffer,
-+       char **buffer,
-+       size_t *currlen,
-+       size_t *maxlen, LLONG value, int base, int min, int max, int flags)
-+{
-+    int signvalue = 0;
-+    const char *prefix = "";
-+    unsigned LLONG uvalue;
-+    char convert[DECIMAL_SIZE(value) + 3];
-+    int place = 0;
-+    int spadlen = 0;
-+    int zpadlen = 0;
-+    int caps = 0;
-+
-+    if (max < 0)
-+        max = 0;
-+    uvalue = value;
-+    if (!(flags & DP_F_UNSIGNED)) {
-+        if (value < 0) {
-+            signvalue = '-';
-+            uvalue = 0 - (unsigned LLONG)value;
-+        } else if (flags & DP_F_PLUS)
-+            signvalue = '+';
-+        else if (flags & DP_F_SPACE)
-+            signvalue = ' ';
-+    }
-+    if (flags & DP_F_NUM) {
-+        if (base == 8)
-+            prefix = "0";
-+        if (base == 16)
-+            prefix = "0x";
-+    }
-+    if (flags & DP_F_UP)
-+        caps = 1;
-+    do {
-+        convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
-+            [uvalue % (unsigned)base];
-+        uvalue = (uvalue / (unsigned)base);
-+    } while (uvalue && (place < (int)sizeof(convert)));
-+    if (place == sizeof(convert))
-+        place--;
-+    convert[place] = 0;
-+
-+    zpadlen = max - place;
-+    spadlen =
-+        min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
-+    if (zpadlen < 0)
-+        zpadlen = 0;
-+    if (spadlen < 0)
-+        spadlen = 0;
-+    if (flags & DP_F_ZERO) {
-+        zpadlen = OSSL_MAX(zpadlen, spadlen);
-+        spadlen = 0;
-+    }
-+    if (flags & DP_F_MINUS)
-+        spadlen = -spadlen;
-+
-+    /* spaces */
-+    while (spadlen > 0) {
-+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
-+            return 0;
-+        --spadlen;
-+    }
-+
-+    /* sign */
-+    if (signvalue)
-+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
-+            return 0;
-+
-+    /* prefix */
-+    while (*prefix) {
-+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
-+            return 0;
-+        prefix++;
-+    }
-+
-+    /* zeros */
-+    if (zpadlen > 0) {
-+        while (zpadlen > 0) {
-+            if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
-+                return 0;
-+            --zpadlen;
-+        }
-+    }
-+    /* digits */
-+    while (place > 0) {
-+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
-+            return 0;
-+    }
-+
-+    /* left justified spaces */
-+    while (spadlen < 0) {
-+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
-+            return 0;
-+        ++spadlen;
-+    }
-+    return 1;
-+}
-+
-+static LDOUBLE abs_val(LDOUBLE value)
-+{
-+    LDOUBLE result = value;
-+    if (value < 0)
-+        result = -value;
-+    return result;
-+}
-+
-+static LDOUBLE pow_10(int in_exp)
-+{
-+    LDOUBLE result = 1;
-+    while (in_exp) {
-+        result *= 10;
-+        in_exp--;
-+    }
-+    return result;
-+}
-+
-+static long roundv(LDOUBLE value)
-+{
-+    long intpart;
-+    intpart = (long)value;
-+    value = value - intpart;
-+    if (value >= 0.5)
-+        intpart++;
-+    return intpart;
-+}
-+
-+static int
-+fmtfp(char **sbuffer,
-+      char **buffer,
-+      size_t *currlen,
-+      size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags, int style)
-+{
-+    int signvalue = 0;
-+    LDOUBLE ufvalue;
-+    LDOUBLE tmpvalue;
-+    char iconvert[20];
-+    char fconvert[20];
-+    char econvert[20];
-+    int iplace = 0;
-+    int fplace = 0;
-+    int eplace = 0;
-+    int padlen = 0;
-+    int zpadlen = 0;
-+    long exp = 0;
-+    unsigned long intpart;
-+    unsigned long fracpart;
-+    unsigned long max10;
-+    int realstyle;
-+
-+    if (max < 0)
-+        max = 6;
-+
-+    if (fvalue < 0)
-+        signvalue = '-';
-+    else if (flags & DP_F_PLUS)
-+        signvalue = '+';
-+    else if (flags & DP_F_SPACE)
-+        signvalue = ' ';
-+
-+    /*
-+     * G_FORMAT sometimes prints like E_FORMAT and sometimes like F_FORMAT
-+     * depending on the number to be printed. Work out which one it is and use
-+     * that from here on.
-+     */
-+    if (style == G_FORMAT) {
-+        if (fvalue == 0.0) {
-+            realstyle = F_FORMAT;
-+        } else if (fvalue < 0.0001) {
-+            realstyle = E_FORMAT;
-+        } else if ((max == 0 && fvalue >= 10)
-+                    || (max > 0 && fvalue >= pow_10(max))) {
-+            realstyle = E_FORMAT;
-+        } else {
-+            realstyle = F_FORMAT;
-+        }
-+    } else {
-+        realstyle = style;
-+    }
-+
-+    if (style != F_FORMAT) {
-+        tmpvalue = fvalue;
-+        /* Calculate the exponent */
-+        if (fvalue != 0.0) {
-+            while (tmpvalue < 1) {
-+                tmpvalue *= 10;
-+                exp--;
-+            }
-+            while (tmpvalue > 10) {
-+                tmpvalue /= 10;
-+                exp++;
-+            }
-+        }
-+        if (style == G_FORMAT) {
-+            /*
-+             * In G_FORMAT the "precision" represents significant digits. We
-+             * always have at least 1 significant digit.
-+             */
-+            if (max == 0)
-+                max = 1;
-+            /* Now convert significant digits to decimal places */
-+            if (realstyle == F_FORMAT) {
-+                max -= (exp + 1);
-+                if (max < 0) {
-+                    /*
-+                     * Should not happen. If we're in F_FORMAT then exp < max?
-+                     */
-+                    return 0;
-+                }
-+            } else {
-+                /*
-+                 * In E_FORMAT there is always one significant digit in front
-+                 * of the decimal point, so:
-+                 * significant digits == 1 + decimal places
-+                 */
-+                max--;
-+            }
-+        }
-+        if (realstyle == E_FORMAT)
-+            fvalue = tmpvalue;
-+    }
-+    ufvalue = abs_val(fvalue);
-+    if (ufvalue > ULONG_MAX) {
-+        /* Number too big */
-+        return 0;
-+    }
-+    intpart = (unsigned long)ufvalue;
-+
-+    /*
-+     * sorry, we only support 9 digits past the decimal because of our
-+     * conversion method
-+     */
-+    if (max > 9)
-+        max = 9;
-+
-+    /*
-+     * we "cheat" by converting the fractional part to integer by multiplying
-+     * by a factor of 10
-+     */
-+    max10 = roundv(pow_10(max));
-+    fracpart = roundv(pow_10(max) * (ufvalue - intpart));
-+
-+    if (fracpart >= max10) {
-+        intpart++;
-+        fracpart -= max10;
-+    }
-+
-+    /* convert integer part */
-+    do {
-+        iconvert[iplace++] = "0123456789"[intpart % 10];
-+        intpart = (intpart / 10);
-+    } while (intpart && (iplace < (int)sizeof(iconvert)));
-+    if (iplace == sizeof iconvert)
-+        iplace--;
-+    iconvert[iplace] = 0;
-+
-+    /* convert fractional part */
-+    while (fplace < max) {
-+        if (style == G_FORMAT && fplace == 0 && (fracpart % 10) == 0) {
-+            /* We strip trailing zeros in G_FORMAT */
-+            max--;
-+            fracpart = fracpart / 10;
-+            if (fplace < max)
-+                continue;
-+            break;
-+        }
-+        fconvert[fplace++] = "0123456789"[fracpart % 10];
-+        fracpart = (fracpart / 10);
-+    }
-+
-+    if (fplace == sizeof fconvert)
-+        fplace--;
-+    fconvert[fplace] = 0;
-+
-+    /* convert exponent part */
-+    if (realstyle == E_FORMAT) {
-+        int tmpexp;
-+        if (exp < 0)
-+            tmpexp = -exp;
-+        else
-+            tmpexp = exp;
-+
-+        do {
-+            econvert[eplace++] = "0123456789"[tmpexp % 10];
-+            tmpexp = (tmpexp / 10);
-+        } while (tmpexp > 0 && eplace < (int)sizeof(econvert));
-+        /* Exponent is huge!! Too big to print */
-+        if (tmpexp > 0)
-+            return 0;
-+        /* Add a leading 0 for single digit exponents */
-+        if (eplace == 1)
-+            econvert[eplace++] = '0';
-+    }
-+
-+    /*
-+     * -1 for decimal point (if we have one, i.e. max > 0),
-+     * another -1 if we are printing a sign
-+     */
-+    padlen = min - iplace - max - (max > 0 ? 1 : 0) - ((signvalue) ? 1 : 0);
-+    /* Take some off for exponent prefix "+e" and exponent */
-+    if (realstyle == E_FORMAT)
-+        padlen -= 2 + eplace;
-+    zpadlen = max - fplace;
-+    if (zpadlen < 0)
-+        zpadlen = 0;
-+    if (padlen < 0)
-+        padlen = 0;
-+    if (flags & DP_F_MINUS)
-+        padlen = -padlen;
-+
-+    if ((flags & DP_F_ZERO) && (padlen > 0)) {
-+        if (signvalue) {
-+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
-+                return 0;
-+            --padlen;
-+            signvalue = 0;
-+        }
-+        while (padlen > 0) {
-+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
-+                return 0;
-+            --padlen;
-+        }
-+    }
-+    while (padlen > 0) {
-+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
-+            return 0;
-+        --padlen;
-+    }
-+    if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
-+        return 0;
-+
-+    while (iplace > 0) {
-+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
-+            return 0;
-+    }
-+
-+    /*
-+     * Decimal point. This should probably use locale to find the correct
-+     * char to print out.
-+     */
-+    if (max > 0 || (flags & DP_F_NUM)) {
-+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
-+            return 0;
-+
-+        while (fplace > 0) {
-+            if(!doapr_outch(sbuffer, buffer, currlen, maxlen,
-+                            fconvert[--fplace]))
-+                return 0;
-+        }
-+    }
-+    while (zpadlen > 0) {
-+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
-+            return 0;
-+        --zpadlen;
-+    }
-+    if (realstyle == E_FORMAT) {
-+        char ech;
-+
-+        if ((flags & DP_F_UP) == 0)
-+            ech = 'e';
-+        else
-+            ech = 'E';
-+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ech))
-+                return 0;
-+        if (exp < 0) {
-+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '-'))
-+                    return 0;
-+        } else {
-+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '+'))
-+                    return 0;
-+        }
-+        while (eplace > 0) {
-+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen,
-+                             econvert[--eplace]))
-+                return 0;
-+        }
-+    }
-+
-+    while (padlen < 0) {
-+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
-+            return 0;
-+        ++padlen;
-+    }
-+    return 1;
-+}
-+
-+#define BUFFER_INC  1024
-+
-+static int
-+doapr_outch(char **sbuffer,
-+            char **buffer, size_t *currlen, size_t *maxlen, int c)
-+{
-+    /* If we haven't at least one buffer, someone has doe a big booboo */
-+    OPENSSL_assert(*sbuffer != NULL || buffer != NULL);
-+
-+    /* |currlen| must always be <= |*maxlen| */
-+    OPENSSL_assert(*currlen <= *maxlen);
-+
-+    if (buffer && *currlen == *maxlen) {
-+        if (*maxlen > INT_MAX - BUFFER_INC)
-+            return 0;
-+
-+        *maxlen += BUFFER_INC;
-+        if (*buffer == NULL) {
-+            *buffer = OPENSSL_malloc(*maxlen);
-+            if (*buffer == NULL)
-+                return 0;
-+            if (*currlen > 0) {
-+                OPENSSL_assert(*sbuffer != NULL);
-+                memcpy(*buffer, *sbuffer, *currlen);
-+            }
-+            *sbuffer = NULL;
-+        } else {
-+            char *tmpbuf;
-+            tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
-+            if (tmpbuf == NULL)
-+                return 0;
-+            *buffer = tmpbuf;
-+        }
-+    }
-+
-+    if (*currlen < *maxlen) {
-+        if (*sbuffer)
-+            (*sbuffer)[(*currlen)++] = (char)c;
-+        else
-+            (*buffer)[(*currlen)++] = (char)c;
-+    }
-+
-+    return 1;
-+}
-+
-+/***************************************************************************/
-+
-+int BIO_printf(BIO *bio, const char *format, ...)
-+{
-+    va_list args;
-+    int ret;
-+
-+    va_start(args, format);
-+
-+    ret = BIO_vprintf(bio, format, args);
-+
-+    va_end(args);
-+    return (ret);
-+}
-+
-+int BIO_vprintf(BIO *bio, const char *format, va_list args)
-+{
-+    int ret;
-+    size_t retlen;
-+    char hugebuf[1024 * 2];     /* Was previously 10k, which is unreasonable
-+                                 * in small-stack environments, like threads
-+                                 * or DOS programs. */
-+    char *hugebufp = hugebuf;
-+    size_t hugebufsize = sizeof(hugebuf);
-+    char *dynbuf = NULL;
-+    int ignored;
-+
-+    dynbuf = NULL;
-+    if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format,
-+                args)) {
-+        OPENSSL_free(dynbuf);
-+        return -1;
-+    }
-+    if (dynbuf) {
-+        ret = BIO_write(bio, dynbuf, (int)retlen);
-+        OPENSSL_free(dynbuf);
-+    } else {
-+        ret = BIO_write(bio, hugebuf, (int)retlen);
-+    }
-+    return (ret);
-+}
-+
-+/*
-+ * As snprintf is not available everywhere, we provide our own
-+ * implementation. This function has nothing to do with BIOs, but it's
-+ * closely related to BIO_printf, and we need *some* name prefix ... (XXX the
-+ * function should be renamed, but to what?)
-+ */
-+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
-+{
-+    va_list args;
-+    int ret;
-+
-+    va_start(args, format);
-+
-+    ret = BIO_vsnprintf(buf, n, format, args);
-+
-+    va_end(args);
-+    return (ret);
-+}
-+
-+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
-+{
-+    size_t retlen;
-+    int truncated;
-+
-+    if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
-+        return -1;
-+
-+    if (truncated)
-+        /*
-+         * In case of truncation, return -1 like traditional snprintf.
-+         * (Current drafts for ISO/IEC 9899 say snprintf should return the
-+         * number of characters that would have been written, had the buffer
-+         * been large enough.)
-+         */
-+        return -1;
-+    else
-+        return (retlen <= INT_MAX) ? (int)retlen : -1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_sock.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_sock.c
-new file mode 100644
-index 0000000..ac2c2d1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_sock.c
-@@ -0,0 +1,381 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "bio_lcl.h"
-+#if defined(NETWARE_CLIB)
-+# include 
-+NETDB_DEFINE_CONTEXT
-+#endif
-+#ifndef OPENSSL_NO_SOCK
-+# define SOCKET_PROTOCOL IPPROTO_TCP
-+# ifdef SO_MAXCONN
-+#  define MAX_LISTEN  SO_MAXCONN
-+# elif defined(SOMAXCONN)
-+#  define MAX_LISTEN  SOMAXCONN
-+# else
-+#  define MAX_LISTEN  32
-+# endif
-+# if defined(OPENSSL_SYS_WINDOWS)
-+static int wsa_init_done = 0;
-+# endif
-+
-+# if OPENSSL_API_COMPAT < 0x10100000L
-+int BIO_get_host_ip(const char *str, unsigned char *ip)
-+{
-+    BIO_ADDRINFO *res = NULL;
-+    int ret = 0;
-+
-+    if (BIO_sock_init() != 1)
-+        return 0;               /* don't generate another error code here */
-+
-+    if (BIO_lookup(str, NULL, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
-+        size_t l;
-+
-+        if (BIO_ADDRINFO_family(res) != AF_INET) {
-+            BIOerr(BIO_F_BIO_GET_HOST_IP,
-+                   BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
-+        } else {
-+            BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), NULL, &l);
-+            /* Because only AF_INET addresses will reach this far,
-+               we can assert that l should be 4 */
-+            OPENSSL_assert(l == 4);
-+
-+            BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), ip, &l);
-+            ret = 1;
-+        }
-+        BIO_ADDRINFO_free(res);
-+    } else {
-+        ERR_add_error_data(2, "host=", str);
-+    }
-+
-+    return ret;
-+}
-+
-+int BIO_get_port(const char *str, unsigned short *port_ptr)
-+{
-+    BIO_ADDRINFO *res = NULL;
-+    int ret = 0;
-+
-+    if (str == NULL) {
-+        BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
-+        return (0);
-+    }
-+
-+    if (BIO_sock_init() != 1)
-+        return 0;               /* don't generate another error code here */
-+
-+    if (BIO_lookup(NULL, str, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
-+        if (BIO_ADDRINFO_family(res) != AF_INET) {
-+            BIOerr(BIO_F_BIO_GET_PORT,
-+                   BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET);
-+        } else {
-+            *port_ptr = ntohs(BIO_ADDR_rawport(BIO_ADDRINFO_address(res)));
-+            ret = 1;
-+        }
-+        BIO_ADDRINFO_free(res);
-+    } else {
-+        ERR_add_error_data(2, "host=", str);
-+    }
-+
-+    return ret;
-+}
-+# endif
-+
-+int BIO_sock_error(int sock)
-+{
-+    int j = 0, i;
-+    socklen_t size = sizeof(j);
-+
-+    /*
-+     * Note: under Windows the third parameter is of type (char *) whereas
-+     * under other systems it is (void *) if you don't have a cast it will
-+     * choke the compiler: if you do have a cast then you can either go for
-+     * (char *) or (void *).
-+     */
-+    i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, &size);
-+    if (i < 0)
-+        return (get_last_socket_error());
-+    else
-+        return (j);
-+}
-+
-+# if OPENSSL_API_COMPAT < 0x10100000L
-+struct hostent *BIO_gethostbyname(const char *name)
-+{
-+    /*
-+     * Caching gethostbyname() results forever is wrong, so we have to let
-+     * the true gethostbyname() worry about this
-+     */
-+#  if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
-+    return gethostbyname((char *)name);
-+#  else
-+    return gethostbyname(name);
-+#  endif
-+}
-+# endif
-+
-+int BIO_sock_init(void)
-+{
-+# ifdef OPENSSL_SYS_WINDOWS
-+    static struct WSAData wsa_state;
-+
-+    if (!wsa_init_done) {
-+        int err;
-+
-+        wsa_init_done = 1;
-+        memset(&wsa_state, 0, sizeof(wsa_state));
-+        /*
-+         * Not making wsa_state available to the rest of the code is formally
-+         * wrong. But the structures we use are [believed to be] invariable
-+         * among Winsock DLLs, while API availability is [expected to be]
-+         * probed at run-time with DSO_global_lookup.
-+         */
-+        if (WSAStartup(0x0202, &wsa_state) != 0) {
-+            err = WSAGetLastError();
-+            SYSerr(SYS_F_WSASTARTUP, err);
-+            BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
-+            return (-1);
-+        }
-+    }
-+# endif                         /* OPENSSL_SYS_WINDOWS */
-+# ifdef WATT32
-+    extern int _watt_do_exit;
-+    _watt_do_exit = 0;          /* don't make sock_init() call exit() */
-+    if (sock_init())
-+        return (-1);
-+# endif
-+
-+    return (1);
-+}
-+
-+void bio_sock_cleanup_int(void)
-+{
-+# ifdef OPENSSL_SYS_WINDOWS
-+    if (wsa_init_done) {
-+        wsa_init_done = 0;
-+        WSACleanup();
-+    }
-+# endif
-+}
-+
-+# if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
-+
-+int BIO_socket_ioctl(int fd, long type, void *arg)
-+{
-+    int i;
-+
-+#  ifdef __DJGPP__
-+    i = ioctlsocket(fd, type, (char *)arg);
-+#  else
-+#   if defined(OPENSSL_SYS_VMS)
-+    /*-
-+     * 2011-02-18 SMS.
-+     * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
-+     * observe that all the consumers pass in an "unsigned long *",
-+     * so we arrange a local copy with a short pointer, and use
-+     * that, instead.
-+     */
-+#    if __INITIAL_POINTER_SIZE == 64
-+#     define ARG arg_32p
-+#     pragma pointer_size save
-+#     pragma pointer_size 32
-+    unsigned long arg_32;
-+    unsigned long *arg_32p;
-+#     pragma pointer_size restore
-+    arg_32p = &arg_32;
-+    arg_32 = *((unsigned long *)arg);
-+#    else                       /* __INITIAL_POINTER_SIZE == 64 */
-+#     define ARG arg
-+#    endif                      /* __INITIAL_POINTER_SIZE == 64 [else] */
-+#   else                        /* defined(OPENSSL_SYS_VMS) */
-+#    define ARG arg
-+#   endif                       /* defined(OPENSSL_SYS_VMS) [else] */
-+
-+    i = ioctlsocket(fd, type, ARG);
-+#  endif                        /* __DJGPP__ */
-+    if (i < 0)
-+        SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
-+    return (i);
-+}
-+# endif                         /* __VMS_VER */
-+
-+# if OPENSSL_API_COMPAT < 0x10100000L
-+int BIO_get_accept_socket(char *host, int bind_mode)
-+{
-+    int s = INVALID_SOCKET;
-+    char *h = NULL, *p = NULL;
-+    BIO_ADDRINFO *res = NULL;
-+
-+    if (!BIO_parse_hostserv(host, &h, &p, BIO_PARSE_PRIO_SERV))
-+        return INVALID_SOCKET;
-+
-+    if (BIO_sock_init() != 1)
-+        return INVALID_SOCKET;
-+
-+    if (BIO_lookup(h, p, BIO_LOOKUP_SERVER, AF_UNSPEC, SOCK_STREAM, &res) != 0)
-+        goto err;
-+
-+    if ((s = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
-+                        BIO_ADDRINFO_protocol(res), 0)) == INVALID_SOCKET) {
-+        s = INVALID_SOCKET;
-+        goto err;
-+    }
-+
-+    if (!BIO_listen(s, BIO_ADDRINFO_address(res),
-+                    bind_mode ? BIO_SOCK_REUSEADDR : 0)) {
-+        BIO_closesocket(s);
-+        s = INVALID_SOCKET;
-+    }
-+
-+ err:
-+    BIO_ADDRINFO_free(res);
-+    OPENSSL_free(h);
-+    OPENSSL_free(p);
-+
-+    return s;
-+}
-+
-+int BIO_accept(int sock, char **ip_port)
-+{
-+    BIO_ADDR res;
-+    int ret = -1;
-+
-+    ret = BIO_accept_ex(sock, &res, 0);
-+    if (ret == (int)INVALID_SOCKET) {
-+        if (BIO_sock_should_retry(ret)) {
-+            ret = -2;
-+            goto end;
-+        }
-+        SYSerr(SYS_F_ACCEPT, get_last_socket_error());
-+        BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
-+        goto end;
-+    }
-+
-+    if (ip_port != NULL) {
-+        char *host = BIO_ADDR_hostname_string(&res, 1);
-+        char *port = BIO_ADDR_service_string(&res, 1);
-+        if (host != NULL && port != NULL)
-+            *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2);
-+        else
-+            *ip_port = NULL;
-+
-+        if (*ip_port == NULL) {
-+            BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
-+            BIO_closesocket(ret);
-+            ret = (int)INVALID_SOCKET;
-+        } else {
-+            strcpy(*ip_port, host);
-+            strcat(*ip_port, ":");
-+            strcat(*ip_port, port);
-+        }
-+        OPENSSL_free(host);
-+        OPENSSL_free(port);
-+    }
-+
-+ end:
-+    return ret;
-+}
-+# endif
-+
-+int BIO_set_tcp_ndelay(int s, int on)
-+{
-+    int ret = 0;
-+# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
-+    int opt;
-+
-+#  ifdef SOL_TCP
-+    opt = SOL_TCP;
-+#  else
-+#   ifdef IPPROTO_TCP
-+    opt = IPPROTO_TCP;
-+#   endif
-+#  endif
-+
-+    ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
-+# endif
-+    return (ret == 0);
-+}
-+
-+int BIO_socket_nbio(int s, int mode)
-+{
-+    int ret = -1;
-+    int l;
-+
-+    l = mode;
-+# ifdef FIONBIO
-+    l = mode;
-+
-+    ret = BIO_socket_ioctl(s, FIONBIO, &l);
-+# elif defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(FNDELAY))
-+    /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
-+
-+    l = fcntl(s, F_GETFL, 0);
-+    if (l == -1) {
-+        SYSerr(SYS_F_FCNTL, get_last_rtl_error());
-+        ret = -1;
-+    } else {
-+#  if defined(O_NONBLOCK)
-+        l &= ~O_NONBLOCK;
-+#  else
-+        l &= ~FNDELAY; /* BSD4.x */
-+#  endif
-+        if (mode) {
-+#  if defined(O_NONBLOCK)
-+            l |= O_NONBLOCK;
-+#  else
-+            l |= FNDELAY; /* BSD4.x */
-+#  endif
-+        }
-+        ret = fcntl(s, F_SETFL, l);
-+
-+        if (ret < 0) {
-+            SYSerr(SYS_F_FCNTL, get_last_rtl_error());
-+        }
-+    }
-+# else
-+    /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
-+    BIOerr(BIO_F_BIO_SOCKET_NBIO, ERR_R_PASSED_INVALID_ARGUMENT);
-+# endif
-+
-+    return (ret == 0);
-+}
-+
-+int BIO_sock_info(int sock,
-+                  enum BIO_sock_info_type type, union BIO_sock_info_u *info)
-+{
-+    switch (type) {
-+    case BIO_SOCK_INFO_ADDRESS:
-+        {
-+            socklen_t addr_len;
-+            int ret = 0;
-+            addr_len = sizeof(*info->addr);
-+            ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr),
-+                              &addr_len);
-+            if (ret == -1) {
-+                SYSerr(SYS_F_GETSOCKNAME, get_last_socket_error());
-+                BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_ERROR);
-+                return 0;
-+            }
-+            if ((size_t)addr_len > sizeof(*info->addr)) {
-+                BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS);
-+                return 0;
-+            }
-+        }
-+        break;
-+    default:
-+        BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_UNKNOWN_INFO_TYPE);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_sock2.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_sock2.c
-new file mode 100644
-index 0000000..7f4d89e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/b_sock2.c
-@@ -0,0 +1,270 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+#include "bio_lcl.h"
-+
-+#include 
-+
-+#ifndef OPENSSL_NO_SOCK
-+# ifdef SO_MAXCONN
-+#  define MAX_LISTEN  SO_MAXCONN
-+# elif defined(SOMAXCONN)
-+#  define MAX_LISTEN  SOMAXCONN
-+# else
-+#  define MAX_LISTEN  32
-+# endif
-+
-+/*-
-+ * BIO_socket - create a socket
-+ * @domain: the socket domain (AF_INET, AF_INET6, AF_UNIX, ...)
-+ * @socktype: the socket type (SOCK_STEAM, SOCK_DGRAM)
-+ * @protocol: the protocol to use (IPPROTO_TCP, IPPROTO_UDP)
-+ * @options: BIO socket options (currently unused)
-+ *
-+ * Creates a socket.  This should be called before calling any
-+ * of BIO_connect and BIO_listen.
-+ *
-+ * Returns the file descriptor on success or INVALID_SOCKET on failure.  On
-+ * failure errno is set, and a status is added to the OpenSSL error stack.
-+ */
-+int BIO_socket(int domain, int socktype, int protocol, int options)
-+{
-+    int sock = -1;
-+
-+    if (BIO_sock_init() != 1)
-+        return INVALID_SOCKET;
-+
-+    sock = socket(domain, socktype, protocol);
-+    if (sock == -1) {
-+        SYSerr(SYS_F_SOCKET, get_last_socket_error());
-+        BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
-+        return INVALID_SOCKET;
-+    }
-+
-+    return sock;
-+}
-+
-+/*-
-+ * BIO_connect - connect to an address
-+ * @sock: the socket to connect with
-+ * @addr: the address to connect to
-+ * @options: BIO socket options
-+ *
-+ * Connects to the address using the given socket and options.
-+ *
-+ * Options can be a combination of the following:
-+ * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
-+ * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
-+ * - BIO_SOCK_NODELAY: don't delay small messages.
-+ *
-+ * options holds BIO socket options that can be used
-+ * You should call this for every address returned by BIO_lookup
-+ * until the connection is successful.
-+ *
-+ * Returns 1 on success or 0 on failure.  On failure errno is set
-+ * and an error status is added to the OpenSSL error stack.
-+ */
-+int BIO_connect(int sock, const BIO_ADDR *addr, int options)
-+{
-+    int on = 1;
-+
-+    if (sock == -1) {
-+        BIOerr(BIO_F_BIO_CONNECT, BIO_R_INVALID_SOCKET);
-+        return 0;
-+    }
-+
-+    if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
-+        return 0;
-+
-+    if (options & BIO_SOCK_KEEPALIVE) {
-+        if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) != 0) {
-+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
-+            BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_KEEPALIVE);
-+            return 0;
-+        }
-+    }
-+
-+    if (options & BIO_SOCK_NODELAY) {
-+        if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) {
-+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
-+            BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_NODELAY);
-+            return 0;
-+        }
-+    }
-+
-+    if (connect(sock, BIO_ADDR_sockaddr(addr),
-+                BIO_ADDR_sockaddr_size(addr)) == -1) {
-+        if (!BIO_sock_should_retry(-1)) {
-+            SYSerr(SYS_F_CONNECT, get_last_socket_error());
-+            BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR);
-+        }
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+/*-
-+ * BIO_listen - Creates a listen socket
-+ * @sock: the socket to listen with
-+ * @addr: local address to bind to
-+ * @options: BIO socket options
-+ *
-+ * Binds to the address using the given socket and options, then
-+ * starts listening for incoming connections.
-+ *
-+ * Options can be a combination of the following:
-+ * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
-+ * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
-+ * - BIO_SOCK_NODELAY: don't delay small messages.
-+ * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
-+ *   for a recently closed port.
-+ * - BIO_SOCK_V6_ONLY: When creating an IPv6 socket, make it listen only
-+ *   for IPv6 addresses and not IPv4 addresses mapped to IPv6.
-+ *
-+ * It's recommended that you set up both an IPv6 and IPv4 listen socket, and
-+ * then check both for new clients that connect to it.  You want to set up
-+ * the socket as non-blocking in that case since else it could hang.
-+ *
-+ * Not all operating systems support IPv4 addresses on an IPv6 socket, and for
-+ * others it's an option.  If you pass the BIO_LISTEN_V6_ONLY it will try to
-+ * create the IPv6 sockets to only listen for IPv6 connection.
-+ *
-+ * It could be that the first BIO_listen() call will listen to all the IPv6
-+ * and IPv4 addresses and that then trying to bind to the IPv4 address will
-+ * fail.  We can't tell the difference between already listening ourself to
-+ * it and someone else listening to it when failing and errno is EADDRINUSE, so
-+ * it's recommended to not give an error in that case if the first call was
-+ * successful.
-+ *
-+ * When restarting the program it could be that the port is still in use.  If
-+ * you set to BIO_SOCK_REUSEADDR option it will try to reuse the port anyway.
-+ * It's recommended that you use this.
-+ */
-+int BIO_listen(int sock, const BIO_ADDR *addr, int options)
-+{
-+    int on = 1;
-+    int socktype;
-+    socklen_t socktype_len = sizeof(socktype);
-+
-+    if (sock == -1) {
-+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_INVALID_SOCKET);
-+        return 0;
-+    }
-+
-+    if (getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &socktype_len) != 0
-+        || socktype_len != sizeof(socktype)) {
-+        SYSerr(SYS_F_GETSOCKOPT, get_last_socket_error());
-+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_GETTING_SOCKTYPE);
-+        return 0;
-+    }
-+
-+    if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
-+        return 0;
-+
-+# ifndef OPENSSL_SYS_WINDOWS
-+    /* SO_REUSEADDR has different behavior on Windows than on
-+     * other operating systems, don't set it there. */
-+    if (options & BIO_SOCK_REUSEADDR) {
-+        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) {
-+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
-+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_REUSEADDR);
-+            return 0;
-+        }
-+    }
-+# endif
-+
-+    if (options & BIO_SOCK_KEEPALIVE) {
-+        if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) != 0) {
-+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
-+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_KEEPALIVE);
-+            return 0;
-+        }
-+    }
-+
-+    if (options & BIO_SOCK_NODELAY) {
-+        if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) {
-+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
-+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY);
-+            return 0;
-+        }
-+    }
-+
-+# ifdef IPV6_V6ONLY
-+    if ((options & BIO_SOCK_V6_ONLY) && BIO_ADDR_family(addr) == AF_INET6) {
-+        if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) != 0) {
-+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
-+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_LISTEN_V6_ONLY);
-+            return 0;
-+        }
-+    }
-+# endif
-+
-+    if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) {
-+        SYSerr(SYS_F_BIND, get_last_socket_error());
-+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_BIND_SOCKET);
-+        return 0;
-+    }
-+
-+    if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) {
-+        SYSerr(SYS_F_LISTEN, get_last_socket_error());
-+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_LISTEN_SOCKET);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+/*-
-+ * BIO_accept_ex - Accept new incoming connections
-+ * @sock: the listening socket
-+ * @addr: the BIO_ADDR to store the peer address in
-+ * @options: BIO socket options, applied on the accepted socket.
-+ *
-+ */
-+int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options)
-+{
-+    socklen_t len;
-+    int accepted_sock;
-+    BIO_ADDR locaddr;
-+    BIO_ADDR *addr = addr_ == NULL ? &locaddr : addr_;
-+
-+    len = sizeof(*addr);
-+    accepted_sock = accept(accept_sock,
-+                           BIO_ADDR_sockaddr_noconst(addr), &len);
-+    if (accepted_sock == -1) {
-+        if (!BIO_sock_should_retry(accepted_sock)) {
-+            SYSerr(SYS_F_ACCEPT, get_last_socket_error());
-+            BIOerr(BIO_F_BIO_ACCEPT_EX, BIO_R_ACCEPT_ERROR);
-+        }
-+        return INVALID_SOCKET;
-+    }
-+
-+    if (!BIO_socket_nbio(accepted_sock, (options & BIO_SOCK_NONBLOCK) != 0)) {
-+        closesocket(accepted_sock);
-+        return INVALID_SOCKET;
-+    }
-+
-+    return accepted_sock;
-+}
-+
-+/*-
-+ * BIO_closesocket - Close a socket
-+ * @sock: the socket to close
-+ */
-+int BIO_closesocket(int sock)
-+{
-+    if (closesocket(sock) < 0)
-+        return 0;
-+    return 1;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_buff.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_buff.c
-new file mode 100644
-index 0000000..b2a387b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_buff.c
-@@ -0,0 +1,455 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "bio_lcl.h"
-+#include "internal/cryptlib.h"
-+
-+static int buffer_write(BIO *h, const char *buf, int num);
-+static int buffer_read(BIO *h, char *buf, int size);
-+static int buffer_puts(BIO *h, const char *str);
-+static int buffer_gets(BIO *h, char *str, int size);
-+static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int buffer_new(BIO *h);
-+static int buffer_free(BIO *data);
-+static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-+#define DEFAULT_BUFFER_SIZE     4096
-+
-+static const BIO_METHOD methods_buffer = {
-+    BIO_TYPE_BUFFER,
-+    "buffer",
-+    buffer_write,
-+    buffer_read,
-+    buffer_puts,
-+    buffer_gets,
-+    buffer_ctrl,
-+    buffer_new,
-+    buffer_free,
-+    buffer_callback_ctrl,
-+};
-+
-+const BIO_METHOD *BIO_f_buffer(void)
-+{
-+    return (&methods_buffer);
-+}
-+
-+static int buffer_new(BIO *bi)
-+{
-+    BIO_F_BUFFER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
-+
-+    if (ctx == NULL)
-+        return (0);
-+    ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
-+    ctx->ibuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
-+    if (ctx->ibuf == NULL) {
-+        OPENSSL_free(ctx);
-+        return (0);
-+    }
-+    ctx->obuf_size = DEFAULT_BUFFER_SIZE;
-+    ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
-+    if (ctx->obuf == NULL) {
-+        OPENSSL_free(ctx->ibuf);
-+        OPENSSL_free(ctx);
-+        return (0);
-+    }
-+
-+    bi->init = 1;
-+    bi->ptr = (char *)ctx;
-+    bi->flags = 0;
-+    return (1);
-+}
-+
-+static int buffer_free(BIO *a)
-+{
-+    BIO_F_BUFFER_CTX *b;
-+
-+    if (a == NULL)
-+        return (0);
-+    b = (BIO_F_BUFFER_CTX *)a->ptr;
-+    OPENSSL_free(b->ibuf);
-+    OPENSSL_free(b->obuf);
-+    OPENSSL_free(a->ptr);
-+    a->ptr = NULL;
-+    a->init = 0;
-+    a->flags = 0;
-+    return (1);
-+}
-+
-+static int buffer_read(BIO *b, char *out, int outl)
-+{
-+    int i, num = 0;
-+    BIO_F_BUFFER_CTX *ctx;
-+
-+    if (out == NULL)
-+        return (0);
-+    ctx = (BIO_F_BUFFER_CTX *)b->ptr;
-+
-+    if ((ctx == NULL) || (b->next_bio == NULL))
-+        return (0);
-+    num = 0;
-+    BIO_clear_retry_flags(b);
-+
-+ start:
-+    i = ctx->ibuf_len;
-+    /* If there is stuff left over, grab it */
-+    if (i != 0) {
-+        if (i > outl)
-+            i = outl;
-+        memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i);
-+        ctx->ibuf_off += i;
-+        ctx->ibuf_len -= i;
-+        num += i;
-+        if (outl == i)
-+            return (num);
-+        outl -= i;
-+        out += i;
-+    }
-+
-+    /*
-+     * We may have done a partial read. try to do more. We have nothing in
-+     * the buffer. If we get an error and have read some data, just return it
-+     * and let them retry to get the error again. copy direct to parent
-+     * address space
-+     */
-+    if (outl > ctx->ibuf_size) {
-+        for (;;) {
-+            i = BIO_read(b->next_bio, out, outl);
-+            if (i <= 0) {
-+                BIO_copy_next_retry(b);
-+                if (i < 0)
-+                    return ((num > 0) ? num : i);
-+                if (i == 0)
-+                    return (num);
-+            }
-+            num += i;
-+            if (outl == i)
-+                return (num);
-+            out += i;
-+            outl -= i;
-+        }
-+    }
-+    /* else */
-+
-+    /* we are going to be doing some buffering */
-+    i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
-+    if (i <= 0) {
-+        BIO_copy_next_retry(b);
-+        if (i < 0)
-+            return ((num > 0) ? num : i);
-+        if (i == 0)
-+            return (num);
-+    }
-+    ctx->ibuf_off = 0;
-+    ctx->ibuf_len = i;
-+
-+    /* Lets re-read using ourselves :-) */
-+    goto start;
-+}
-+
-+static int buffer_write(BIO *b, const char *in, int inl)
-+{
-+    int i, num = 0;
-+    BIO_F_BUFFER_CTX *ctx;
-+
-+    if ((in == NULL) || (inl <= 0))
-+        return (0);
-+    ctx = (BIO_F_BUFFER_CTX *)b->ptr;
-+    if ((ctx == NULL) || (b->next_bio == NULL))
-+        return (0);
-+
-+    BIO_clear_retry_flags(b);
-+ start:
-+    i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off);
-+    /* add to buffer and return */
-+    if (i >= inl) {
-+        memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl);
-+        ctx->obuf_len += inl;
-+        return (num + inl);
-+    }
-+    /* else */
-+    /* stuff already in buffer, so add to it first, then flush */
-+    if (ctx->obuf_len != 0) {
-+        if (i > 0) {            /* lets fill it up if we can */
-+            memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i);
-+            in += i;
-+            inl -= i;
-+            num += i;
-+            ctx->obuf_len += i;
-+        }
-+        /* we now have a full buffer needing flushing */
-+        for (;;) {
-+            i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
-+                          ctx->obuf_len);
-+            if (i <= 0) {
-+                BIO_copy_next_retry(b);
-+
-+                if (i < 0)
-+                    return ((num > 0) ? num : i);
-+                if (i == 0)
-+                    return (num);
-+            }
-+            ctx->obuf_off += i;
-+            ctx->obuf_len -= i;
-+            if (ctx->obuf_len == 0)
-+                break;
-+        }
-+    }
-+    /*
-+     * we only get here if the buffer has been flushed and we still have
-+     * stuff to write
-+     */
-+    ctx->obuf_off = 0;
-+
-+    /* we now have inl bytes to write */
-+    while (inl >= ctx->obuf_size) {
-+        i = BIO_write(b->next_bio, in, inl);
-+        if (i <= 0) {
-+            BIO_copy_next_retry(b);
-+            if (i < 0)
-+                return ((num > 0) ? num : i);
-+            if (i == 0)
-+                return (num);
-+        }
-+        num += i;
-+        in += i;
-+        inl -= i;
-+        if (inl == 0)
-+            return (num);
-+    }
-+
-+    /*
-+     * copy the rest into the buffer since we have only a small amount left
-+     */
-+    goto start;
-+}
-+
-+static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    BIO *dbio;
-+    BIO_F_BUFFER_CTX *ctx;
-+    long ret = 1;
-+    char *p1, *p2;
-+    int r, i, *ip;
-+    int ibs, obs;
-+
-+    ctx = (BIO_F_BUFFER_CTX *)b->ptr;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        ctx->ibuf_off = 0;
-+        ctx->ibuf_len = 0;
-+        ctx->obuf_off = 0;
-+        ctx->obuf_len = 0;
-+        if (b->next_bio == NULL)
-+            return (0);
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_INFO:
-+        ret = (long)ctx->obuf_len;
-+        break;
-+    case BIO_C_GET_BUFF_NUM_LINES:
-+        ret = 0;
-+        p1 = ctx->ibuf;
-+        for (i = 0; i < ctx->ibuf_len; i++) {
-+            if (p1[ctx->ibuf_off + i] == '\n')
-+                ret++;
-+        }
-+        break;
-+    case BIO_CTRL_WPENDING:
-+        ret = (long)ctx->obuf_len;
-+        if (ret == 0) {
-+            if (b->next_bio == NULL)
-+                return (0);
-+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        }
-+        break;
-+    case BIO_CTRL_PENDING:
-+        ret = (long)ctx->ibuf_len;
-+        if (ret == 0) {
-+            if (b->next_bio == NULL)
-+                return (0);
-+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        }
-+        break;
-+    case BIO_C_SET_BUFF_READ_DATA:
-+        if (num > ctx->ibuf_size) {
-+            p1 = OPENSSL_malloc((int)num);
-+            if (p1 == NULL)
-+                goto malloc_error;
-+            OPENSSL_free(ctx->ibuf);
-+            ctx->ibuf = p1;
-+        }
-+        ctx->ibuf_off = 0;
-+        ctx->ibuf_len = (int)num;
-+        memcpy(ctx->ibuf, ptr, (int)num);
-+        ret = 1;
-+        break;
-+    case BIO_C_SET_BUFF_SIZE:
-+        if (ptr != NULL) {
-+            ip = (int *)ptr;
-+            if (*ip == 0) {
-+                ibs = (int)num;
-+                obs = ctx->obuf_size;
-+            } else {            /* if (*ip == 1) */
-+
-+                ibs = ctx->ibuf_size;
-+                obs = (int)num;
-+            }
-+        } else {
-+            ibs = (int)num;
-+            obs = (int)num;
-+        }
-+        p1 = ctx->ibuf;
-+        p2 = ctx->obuf;
-+        if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
-+            p1 = OPENSSL_malloc((int)num);
-+            if (p1 == NULL)
-+                goto malloc_error;
-+        }
-+        if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
-+            p2 = OPENSSL_malloc((int)num);
-+            if (p2 == NULL) {
-+                if (p1 != ctx->ibuf)
-+                    OPENSSL_free(p1);
-+                goto malloc_error;
-+            }
-+        }
-+        if (ctx->ibuf != p1) {
-+            OPENSSL_free(ctx->ibuf);
-+            ctx->ibuf = p1;
-+            ctx->ibuf_off = 0;
-+            ctx->ibuf_len = 0;
-+            ctx->ibuf_size = ibs;
-+        }
-+        if (ctx->obuf != p2) {
-+            OPENSSL_free(ctx->obuf);
-+            ctx->obuf = p2;
-+            ctx->obuf_off = 0;
-+            ctx->obuf_len = 0;
-+            ctx->obuf_size = obs;
-+        }
-+        break;
-+    case BIO_C_DO_STATE_MACHINE:
-+        if (b->next_bio == NULL)
-+            return (0);
-+        BIO_clear_retry_flags(b);
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        BIO_copy_next_retry(b);
-+        break;
-+
-+    case BIO_CTRL_FLUSH:
-+        if (b->next_bio == NULL)
-+            return (0);
-+        if (ctx->obuf_len <= 0) {
-+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+            break;
-+        }
-+
-+        for (;;) {
-+            BIO_clear_retry_flags(b);
-+            if (ctx->obuf_len > 0) {
-+                r = BIO_write(b->next_bio,
-+                              &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len);
-+                BIO_copy_next_retry(b);
-+                if (r <= 0)
-+                    return ((long)r);
-+                ctx->obuf_off += r;
-+                ctx->obuf_len -= r;
-+            } else {
-+                ctx->obuf_len = 0;
-+                ctx->obuf_off = 0;
-+                break;
-+            }
-+        }
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_DUP:
-+        dbio = (BIO *)ptr;
-+        if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
-+            !BIO_set_write_buffer_size(dbio, ctx->obuf_size))
-+            ret = 0;
-+        break;
-+    default:
-+        if (b->next_bio == NULL)
-+            return (0);
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        break;
-+    }
-+    return (ret);
-+ malloc_error:
-+    BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE);
-+    return (0);
-+}
-+
-+static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    long ret = 1;
-+
-+    if (b->next_bio == NULL)
-+        return (0);
-+    switch (cmd) {
-+    default:
-+        ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int buffer_gets(BIO *b, char *buf, int size)
-+{
-+    BIO_F_BUFFER_CTX *ctx;
-+    int num = 0, i, flag;
-+    char *p;
-+
-+    ctx = (BIO_F_BUFFER_CTX *)b->ptr;
-+    size--;                     /* reserve space for a '\0' */
-+    BIO_clear_retry_flags(b);
-+
-+    for (;;) {
-+        if (ctx->ibuf_len > 0) {
-+            p = &(ctx->ibuf[ctx->ibuf_off]);
-+            flag = 0;
-+            for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
-+                *(buf++) = p[i];
-+                if (p[i] == '\n') {
-+                    flag = 1;
-+                    i++;
-+                    break;
-+                }
-+            }
-+            num += i;
-+            size -= i;
-+            ctx->ibuf_len -= i;
-+            ctx->ibuf_off += i;
-+            if (flag || size == 0) {
-+                *buf = '\0';
-+                return (num);
-+            }
-+        } else {                /* read another chunk */
-+
-+            i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
-+            if (i <= 0) {
-+                BIO_copy_next_retry(b);
-+                *buf = '\0';
-+                if (i < 0)
-+                    return ((num > 0) ? num : i);
-+                if (i == 0)
-+                    return (num);
-+            }
-+            ctx->ibuf_len = i;
-+            ctx->ibuf_off = 0;
-+        }
-+    }
-+}
-+
-+static int buffer_puts(BIO *b, const char *str)
-+{
-+    return (buffer_write(b, str, strlen(str)));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_lbuf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_lbuf.c
-new file mode 100644
-index 0000000..b3c2b5e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_lbuf.c
-@@ -0,0 +1,319 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "bio_lcl.h"
-+#include "internal/cryptlib.h"
-+#include 
-+
-+static int linebuffer_write(BIO *h, const char *buf, int num);
-+static int linebuffer_read(BIO *h, char *buf, int size);
-+static int linebuffer_puts(BIO *h, const char *str);
-+static int linebuffer_gets(BIO *h, char *str, int size);
-+static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int linebuffer_new(BIO *h);
-+static int linebuffer_free(BIO *data);
-+static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-+
-+/* A 10k maximum should be enough for most purposes */
-+#define DEFAULT_LINEBUFFER_SIZE 1024*10
-+
-+/* #define DEBUG */
-+
-+static const BIO_METHOD methods_linebuffer = {
-+    BIO_TYPE_LINEBUFFER,
-+    "linebuffer",
-+    linebuffer_write,
-+    linebuffer_read,
-+    linebuffer_puts,
-+    linebuffer_gets,
-+    linebuffer_ctrl,
-+    linebuffer_new,
-+    linebuffer_free,
-+    linebuffer_callback_ctrl,
-+};
-+
-+const BIO_METHOD *BIO_f_linebuffer(void)
-+{
-+    return (&methods_linebuffer);
-+}
-+
-+typedef struct bio_linebuffer_ctx_struct {
-+    char *obuf;                 /* the output char array */
-+    int obuf_size;              /* how big is the output buffer */
-+    int obuf_len;               /* how many bytes are in it */
-+} BIO_LINEBUFFER_CTX;
-+
-+static int linebuffer_new(BIO *bi)
-+{
-+    BIO_LINEBUFFER_CTX *ctx;
-+
-+    ctx = OPENSSL_malloc(sizeof(*ctx));
-+    if (ctx == NULL)
-+        return (0);
-+    ctx->obuf = OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE);
-+    if (ctx->obuf == NULL) {
-+        OPENSSL_free(ctx);
-+        return (0);
-+    }
-+    ctx->obuf_size = DEFAULT_LINEBUFFER_SIZE;
-+    ctx->obuf_len = 0;
-+
-+    bi->init = 1;
-+    bi->ptr = (char *)ctx;
-+    bi->flags = 0;
-+    return (1);
-+}
-+
-+static int linebuffer_free(BIO *a)
-+{
-+    BIO_LINEBUFFER_CTX *b;
-+
-+    if (a == NULL)
-+        return (0);
-+    b = (BIO_LINEBUFFER_CTX *)a->ptr;
-+    OPENSSL_free(b->obuf);
-+    OPENSSL_free(a->ptr);
-+    a->ptr = NULL;
-+    a->init = 0;
-+    a->flags = 0;
-+    return (1);
-+}
-+
-+static int linebuffer_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0;
-+
-+    if (out == NULL)
-+        return (0);
-+    if (b->next_bio == NULL)
-+        return (0);
-+    ret = BIO_read(b->next_bio, out, outl);
-+    BIO_clear_retry_flags(b);
-+    BIO_copy_next_retry(b);
-+    return (ret);
-+}
-+
-+static int linebuffer_write(BIO *b, const char *in, int inl)
-+{
-+    int i, num = 0, foundnl;
-+    BIO_LINEBUFFER_CTX *ctx;
-+
-+    if ((in == NULL) || (inl <= 0))
-+        return (0);
-+    ctx = (BIO_LINEBUFFER_CTX *)b->ptr;
-+    if ((ctx == NULL) || (b->next_bio == NULL))
-+        return (0);
-+
-+    BIO_clear_retry_flags(b);
-+
-+    do {
-+        const char *p;
-+
-+        for (p = in; p < in + inl && *p != '\n'; p++) ;
-+        if (*p == '\n') {
-+            p++;
-+            foundnl = 1;
-+        } else
-+            foundnl = 0;
-+
-+        /*
-+         * If a NL was found and we already have text in the save buffer,
-+         * concatenate them and write
-+         */
-+        while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len)
-+               && ctx->obuf_len > 0) {
-+            int orig_olen = ctx->obuf_len;
-+
-+            i = ctx->obuf_size - ctx->obuf_len;
-+            if (p - in > 0) {
-+                if (i >= p - in) {
-+                    memcpy(&(ctx->obuf[ctx->obuf_len]), in, p - in);
-+                    ctx->obuf_len += p - in;
-+                    inl -= p - in;
-+                    num += p - in;
-+                    in = p;
-+                } else {
-+                    memcpy(&(ctx->obuf[ctx->obuf_len]), in, i);
-+                    ctx->obuf_len += i;
-+                    inl -= i;
-+                    in += i;
-+                    num += i;
-+                }
-+            }
-+            i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
-+            if (i <= 0) {
-+                ctx->obuf_len = orig_olen;
-+                BIO_copy_next_retry(b);
-+
-+                if (i < 0)
-+                    return ((num > 0) ? num : i);
-+                if (i == 0)
-+                    return (num);
-+            }
-+            if (i < ctx->obuf_len)
-+                memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i);
-+            ctx->obuf_len -= i;
-+        }
-+
-+        /*
-+         * Now that the save buffer is emptied, let's write the input buffer
-+         * if a NL was found and there is anything to write.
-+         */
-+        if ((foundnl || p - in > ctx->obuf_size) && p - in > 0) {
-+            i = BIO_write(b->next_bio, in, p - in);
-+            if (i <= 0) {
-+                BIO_copy_next_retry(b);
-+                if (i < 0)
-+                    return ((num > 0) ? num : i);
-+                if (i == 0)
-+                    return (num);
-+            }
-+            num += i;
-+            in += i;
-+            inl -= i;
-+        }
-+    }
-+    while (foundnl && inl > 0);
-+    /*
-+     * We've written as much as we can.  The rest of the input buffer, if
-+     * any, is text that doesn't and with a NL and therefore needs to be
-+     * saved for the next trip.
-+     */
-+    if (inl > 0) {
-+        memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
-+        ctx->obuf_len += inl;
-+        num += inl;
-+    }
-+    return num;
-+}
-+
-+static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    BIO *dbio;
-+    BIO_LINEBUFFER_CTX *ctx;
-+    long ret = 1;
-+    char *p;
-+    int r;
-+    int obs;
-+
-+    ctx = (BIO_LINEBUFFER_CTX *)b->ptr;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        ctx->obuf_len = 0;
-+        if (b->next_bio == NULL)
-+            return (0);
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_INFO:
-+        ret = (long)ctx->obuf_len;
-+        break;
-+    case BIO_CTRL_WPENDING:
-+        ret = (long)ctx->obuf_len;
-+        if (ret == 0) {
-+            if (b->next_bio == NULL)
-+                return (0);
-+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        }
-+        break;
-+    case BIO_C_SET_BUFF_SIZE:
-+        obs = (int)num;
-+        p = ctx->obuf;
-+        if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) {
-+            p = OPENSSL_malloc((int)num);
-+            if (p == NULL)
-+                goto malloc_error;
-+        }
-+        if (ctx->obuf != p) {
-+            if (ctx->obuf_len > obs) {
-+                ctx->obuf_len = obs;
-+            }
-+            memcpy(p, ctx->obuf, ctx->obuf_len);
-+            OPENSSL_free(ctx->obuf);
-+            ctx->obuf = p;
-+            ctx->obuf_size = obs;
-+        }
-+        break;
-+    case BIO_C_DO_STATE_MACHINE:
-+        if (b->next_bio == NULL)
-+            return (0);
-+        BIO_clear_retry_flags(b);
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        BIO_copy_next_retry(b);
-+        break;
-+
-+    case BIO_CTRL_FLUSH:
-+        if (b->next_bio == NULL)
-+            return (0);
-+        if (ctx->obuf_len <= 0) {
-+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+            break;
-+        }
-+
-+        for (;;) {
-+            BIO_clear_retry_flags(b);
-+            if (ctx->obuf_len > 0) {
-+                r = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
-+                BIO_copy_next_retry(b);
-+                if (r <= 0)
-+                    return ((long)r);
-+                if (r < ctx->obuf_len)
-+                    memmove(ctx->obuf, ctx->obuf + r, ctx->obuf_len - r);
-+                ctx->obuf_len -= r;
-+            } else {
-+                ctx->obuf_len = 0;
-+                break;
-+            }
-+        }
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_DUP:
-+        dbio = (BIO *)ptr;
-+        if (!BIO_set_write_buffer_size(dbio, ctx->obuf_size))
-+            ret = 0;
-+        break;
-+    default:
-+        if (b->next_bio == NULL)
-+            return (0);
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        break;
-+    }
-+    return (ret);
-+ malloc_error:
-+    BIOerr(BIO_F_LINEBUFFER_CTRL, ERR_R_MALLOC_FAILURE);
-+    return (0);
-+}
-+
-+static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    long ret = 1;
-+
-+    if (b->next_bio == NULL)
-+        return (0);
-+    switch (cmd) {
-+    default:
-+        ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int linebuffer_gets(BIO *b, char *buf, int size)
-+{
-+    if (b->next_bio == NULL)
-+        return (0);
-+    return (BIO_gets(b->next_bio, buf, size));
-+}
-+
-+static int linebuffer_puts(BIO *b, const char *str)
-+{
-+    return (linebuffer_write(b, str, strlen(str)));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_nbio.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_nbio.c
-new file mode 100644
-index 0000000..364d9fb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_nbio.c
-@@ -0,0 +1,194 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "bio_lcl.h"
-+#include "internal/cryptlib.h"
-+#include 
-+
-+/*
-+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
-+ */
-+
-+static int nbiof_write(BIO *h, const char *buf, int num);
-+static int nbiof_read(BIO *h, char *buf, int size);
-+static int nbiof_puts(BIO *h, const char *str);
-+static int nbiof_gets(BIO *h, char *str, int size);
-+static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int nbiof_new(BIO *h);
-+static int nbiof_free(BIO *data);
-+static long nbiof_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-+typedef struct nbio_test_st {
-+    /* only set if we sent a 'should retry' error */
-+    int lrn;
-+    int lwn;
-+} NBIO_TEST;
-+
-+static const BIO_METHOD methods_nbiof = {
-+    BIO_TYPE_NBIO_TEST,
-+    "non-blocking IO test filter",
-+    nbiof_write,
-+    nbiof_read,
-+    nbiof_puts,
-+    nbiof_gets,
-+    nbiof_ctrl,
-+    nbiof_new,
-+    nbiof_free,
-+    nbiof_callback_ctrl,
-+};
-+
-+const BIO_METHOD *BIO_f_nbio_test(void)
-+{
-+    return (&methods_nbiof);
-+}
-+
-+static int nbiof_new(BIO *bi)
-+{
-+    NBIO_TEST *nt;
-+
-+    if ((nt = OPENSSL_zalloc(sizeof(*nt))) == NULL)
-+        return (0);
-+    nt->lrn = -1;
-+    nt->lwn = -1;
-+    bi->ptr = (char *)nt;
-+    bi->init = 1;
-+    return (1);
-+}
-+
-+static int nbiof_free(BIO *a)
-+{
-+    if (a == NULL)
-+        return (0);
-+    OPENSSL_free(a->ptr);
-+    a->ptr = NULL;
-+    a->init = 0;
-+    a->flags = 0;
-+    return (1);
-+}
-+
-+static int nbiof_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0;
-+    int num;
-+    unsigned char n;
-+
-+    if (out == NULL)
-+        return (0);
-+    if (b->next_bio == NULL)
-+        return (0);
-+
-+    BIO_clear_retry_flags(b);
-+    if (RAND_bytes(&n, 1) <= 0)
-+        return -1;
-+    num = (n & 0x07);
-+
-+    if (outl > num)
-+        outl = num;
-+
-+    if (num == 0) {
-+        ret = -1;
-+        BIO_set_retry_read(b);
-+    } else {
-+        ret = BIO_read(b->next_bio, out, outl);
-+        if (ret < 0)
-+            BIO_copy_next_retry(b);
-+    }
-+    return (ret);
-+}
-+
-+static int nbiof_write(BIO *b, const char *in, int inl)
-+{
-+    NBIO_TEST *nt;
-+    int ret = 0;
-+    int num;
-+    unsigned char n;
-+
-+    if ((in == NULL) || (inl <= 0))
-+        return (0);
-+    if (b->next_bio == NULL)
-+        return (0);
-+    nt = (NBIO_TEST *)b->ptr;
-+
-+    BIO_clear_retry_flags(b);
-+
-+    if (nt->lwn > 0) {
-+        num = nt->lwn;
-+        nt->lwn = 0;
-+    } else {
-+        if (RAND_bytes(&n, 1) <= 0)
-+            return -1;
-+        num = (n & 7);
-+    }
-+
-+    if (inl > num)
-+        inl = num;
-+
-+    if (num == 0) {
-+        ret = -1;
-+        BIO_set_retry_write(b);
-+    } else {
-+        ret = BIO_write(b->next_bio, in, inl);
-+        if (ret < 0) {
-+            BIO_copy_next_retry(b);
-+            nt->lwn = inl;
-+        }
-+    }
-+    return (ret);
-+}
-+
-+static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    long ret;
-+
-+    if (b->next_bio == NULL)
-+        return (0);
-+    switch (cmd) {
-+    case BIO_C_DO_STATE_MACHINE:
-+        BIO_clear_retry_flags(b);
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        BIO_copy_next_retry(b);
-+        break;
-+    case BIO_CTRL_DUP:
-+        ret = 0L;
-+        break;
-+    default:
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static long nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    long ret = 1;
-+
-+    if (b->next_bio == NULL)
-+        return (0);
-+    switch (cmd) {
-+    default:
-+        ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int nbiof_gets(BIO *bp, char *buf, int size)
-+{
-+    if (bp->next_bio == NULL)
-+        return (0);
-+    return (BIO_gets(bp->next_bio, buf, size));
-+}
-+
-+static int nbiof_puts(BIO *bp, const char *str)
-+{
-+    if (bp->next_bio == NULL)
-+        return (0);
-+    return (BIO_puts(bp->next_bio, str));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_null.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_null.c
-new file mode 100644
-index 0000000..0736b3f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bf_null.c
-@@ -0,0 +1,140 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "bio_lcl.h"
-+#include "internal/cryptlib.h"
-+
-+/*
-+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
-+ */
-+
-+static int nullf_write(BIO *h, const char *buf, int num);
-+static int nullf_read(BIO *h, char *buf, int size);
-+static int nullf_puts(BIO *h, const char *str);
-+static int nullf_gets(BIO *h, char *str, int size);
-+static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int nullf_new(BIO *h);
-+static int nullf_free(BIO *data);
-+static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-+static const BIO_METHOD methods_nullf = {
-+    BIO_TYPE_NULL_FILTER,
-+    "NULL filter",
-+    nullf_write,
-+    nullf_read,
-+    nullf_puts,
-+    nullf_gets,
-+    nullf_ctrl,
-+    nullf_new,
-+    nullf_free,
-+    nullf_callback_ctrl,
-+};
-+
-+const BIO_METHOD *BIO_f_null(void)
-+{
-+    return (&methods_nullf);
-+}
-+
-+static int nullf_new(BIO *bi)
-+{
-+    bi->init = 1;
-+    bi->ptr = NULL;
-+    bi->flags = 0;
-+    return (1);
-+}
-+
-+static int nullf_free(BIO *a)
-+{
-+    if (a == NULL)
-+        return (0);
-+    /*-
-+    a->ptr=NULL;
-+    a->init=0;
-+    a->flags=0;
-+    */
-+    return (1);
-+}
-+
-+static int nullf_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0;
-+
-+    if (out == NULL)
-+        return (0);
-+    if (b->next_bio == NULL)
-+        return (0);
-+    ret = BIO_read(b->next_bio, out, outl);
-+    BIO_clear_retry_flags(b);
-+    BIO_copy_next_retry(b);
-+    return (ret);
-+}
-+
-+static int nullf_write(BIO *b, const char *in, int inl)
-+{
-+    int ret = 0;
-+
-+    if ((in == NULL) || (inl <= 0))
-+        return (0);
-+    if (b->next_bio == NULL)
-+        return (0);
-+    ret = BIO_write(b->next_bio, in, inl);
-+    BIO_clear_retry_flags(b);
-+    BIO_copy_next_retry(b);
-+    return (ret);
-+}
-+
-+static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    long ret;
-+
-+    if (b->next_bio == NULL)
-+        return (0);
-+    switch (cmd) {
-+    case BIO_C_DO_STATE_MACHINE:
-+        BIO_clear_retry_flags(b);
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+        BIO_copy_next_retry(b);
-+        break;
-+    case BIO_CTRL_DUP:
-+        ret = 0L;
-+        break;
-+    default:
-+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
-+    }
-+    return (ret);
-+}
-+
-+static long nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    long ret = 1;
-+
-+    if (b->next_bio == NULL)
-+        return (0);
-+    switch (cmd) {
-+    default:
-+        ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int nullf_gets(BIO *bp, char *buf, int size)
-+{
-+    if (bp->next_bio == NULL)
-+        return (0);
-+    return (BIO_gets(bp->next_bio, buf, size));
-+}
-+
-+static int nullf_puts(BIO *bp, const char *str)
-+{
-+    if (bp->next_bio == NULL)
-+        return (0);
-+    return (BIO_puts(bp->next_bio, str));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_cb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_cb.c
-new file mode 100644
-index 0000000..69ea3d0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_cb.c
-@@ -0,0 +1,99 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "bio_lcl.h"
-+#include "internal/cryptlib.h"
-+#include 
-+
-+long BIO_debug_callback(BIO *bio, int cmd, const char *argp,
-+                        int argi, long argl, long ret)
-+{
-+    BIO *b;
-+    char buf[256];
-+    char *p;
-+    long r = 1;
-+    int len;
-+    size_t p_maxlen;
-+
-+    if (BIO_CB_RETURN & cmd)
-+        r = ret;
-+
-+    len = BIO_snprintf(buf, sizeof buf, "BIO[%p]: ", (void *)bio);
-+
-+    /* Ignore errors and continue printing the other information. */
-+    if (len < 0)
-+        len = 0;
-+    p = buf + len;
-+    p_maxlen = sizeof(buf) - len;
-+
-+    switch (cmd) {
-+    case BIO_CB_FREE:
-+        BIO_snprintf(p, p_maxlen, "Free - %s\n", bio->method->name);
-+        break;
-+    case BIO_CB_READ:
-+        if (bio->method->type & BIO_TYPE_DESCRIPTOR)
-+            BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s fd=%d\n",
-+                         bio->num, (unsigned long)argi,
-+                         bio->method->name, bio->num);
-+        else
-+            BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s\n",
-+                         bio->num, (unsigned long)argi, bio->method->name);
-+        break;
-+    case BIO_CB_WRITE:
-+        if (bio->method->type & BIO_TYPE_DESCRIPTOR)
-+            BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s fd=%d\n",
-+                         bio->num, (unsigned long)argi,
-+                         bio->method->name, bio->num);
-+        else
-+            BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s\n",
-+                         bio->num, (unsigned long)argi, bio->method->name);
-+        break;
-+    case BIO_CB_PUTS:
-+        BIO_snprintf(p, p_maxlen, "puts() - %s\n", bio->method->name);
-+        break;
-+    case BIO_CB_GETS:
-+        BIO_snprintf(p, p_maxlen, "gets(%lu) - %s\n", (unsigned long)argi,
-+                     bio->method->name);
-+        break;
-+    case BIO_CB_CTRL:
-+        BIO_snprintf(p, p_maxlen, "ctrl(%lu) - %s\n", (unsigned long)argi,
-+                     bio->method->name);
-+        break;
-+    case BIO_CB_RETURN | BIO_CB_READ:
-+        BIO_snprintf(p, p_maxlen, "read return %ld\n", ret);
-+        break;
-+    case BIO_CB_RETURN | BIO_CB_WRITE:
-+        BIO_snprintf(p, p_maxlen, "write return %ld\n", ret);
-+        break;
-+    case BIO_CB_RETURN | BIO_CB_GETS:
-+        BIO_snprintf(p, p_maxlen, "gets return %ld\n", ret);
-+        break;
-+    case BIO_CB_RETURN | BIO_CB_PUTS:
-+        BIO_snprintf(p, p_maxlen, "puts return %ld\n", ret);
-+        break;
-+    case BIO_CB_RETURN | BIO_CB_CTRL:
-+        BIO_snprintf(p, p_maxlen, "ctrl return %ld\n", ret);
-+        break;
-+    default:
-+        BIO_snprintf(p, p_maxlen, "bio callback - unknown type (%d)\n", cmd);
-+        break;
-+    }
-+
-+    b = (BIO *)bio->cb_arg;
-+    if (b != NULL)
-+        BIO_write(b, buf, strlen(buf));
-+#if !defined(OPENSSL_NO_STDIO)
-+    else
-+        fputs(buf, stderr);
-+#endif
-+    return (r);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_err.c
-new file mode 100644
-index 0000000..98c90d6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_err.c
-@@ -0,0 +1,125 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason)
-+
-+static ERR_STRING_DATA BIO_str_functs[] = {
-+    {ERR_FUNC(BIO_F_ACPT_STATE), "acpt_state"},
-+    {ERR_FUNC(BIO_F_ADDR_STRINGS), "addr_strings"},
-+    {ERR_FUNC(BIO_F_BIO_ACCEPT), "BIO_accept"},
-+    {ERR_FUNC(BIO_F_BIO_ACCEPT_EX), "BIO_accept_ex"},
-+    {ERR_FUNC(BIO_F_BIO_ADDR_NEW), "BIO_ADDR_new"},
-+    {ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL), "BIO_callback_ctrl"},
-+    {ERR_FUNC(BIO_F_BIO_CONNECT), "BIO_connect"},
-+    {ERR_FUNC(BIO_F_BIO_CTRL), "BIO_ctrl"},
-+    {ERR_FUNC(BIO_F_BIO_GETS), "BIO_gets"},
-+    {ERR_FUNC(BIO_F_BIO_GET_HOST_IP), "BIO_get_host_ip"},
-+    {ERR_FUNC(BIO_F_BIO_GET_NEW_INDEX), "BIO_get_new_index"},
-+    {ERR_FUNC(BIO_F_BIO_GET_PORT), "BIO_get_port"},
-+    {ERR_FUNC(BIO_F_BIO_LISTEN), "BIO_listen"},
-+    {ERR_FUNC(BIO_F_BIO_LOOKUP), "BIO_lookup"},
-+    {ERR_FUNC(BIO_F_BIO_MAKE_PAIR), "bio_make_pair"},
-+    {ERR_FUNC(BIO_F_BIO_NEW), "BIO_new"},
-+    {ERR_FUNC(BIO_F_BIO_NEW_FILE), "BIO_new_file"},
-+    {ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF), "BIO_new_mem_buf"},
-+    {ERR_FUNC(BIO_F_BIO_NREAD), "BIO_nread"},
-+    {ERR_FUNC(BIO_F_BIO_NREAD0), "BIO_nread0"},
-+    {ERR_FUNC(BIO_F_BIO_NWRITE), "BIO_nwrite"},
-+    {ERR_FUNC(BIO_F_BIO_NWRITE0), "BIO_nwrite0"},
-+    {ERR_FUNC(BIO_F_BIO_PARSE_HOSTSERV), "BIO_parse_hostserv"},
-+    {ERR_FUNC(BIO_F_BIO_PUTS), "BIO_puts"},
-+    {ERR_FUNC(BIO_F_BIO_READ), "BIO_read"},
-+    {ERR_FUNC(BIO_F_BIO_SOCKET), "BIO_socket"},
-+    {ERR_FUNC(BIO_F_BIO_SOCKET_NBIO), "BIO_socket_nbio"},
-+    {ERR_FUNC(BIO_F_BIO_SOCK_INFO), "BIO_sock_info"},
-+    {ERR_FUNC(BIO_F_BIO_SOCK_INIT), "BIO_sock_init"},
-+    {ERR_FUNC(BIO_F_BIO_WRITE), "BIO_write"},
-+    {ERR_FUNC(BIO_F_BUFFER_CTRL), "buffer_ctrl"},
-+    {ERR_FUNC(BIO_F_CONN_CTRL), "conn_ctrl"},
-+    {ERR_FUNC(BIO_F_CONN_STATE), "conn_state"},
-+    {ERR_FUNC(BIO_F_DGRAM_SCTP_READ), "dgram_sctp_read"},
-+    {ERR_FUNC(BIO_F_DGRAM_SCTP_WRITE), "dgram_sctp_write"},
-+    {ERR_FUNC(BIO_F_FILE_CTRL), "file_ctrl"},
-+    {ERR_FUNC(BIO_F_FILE_READ), "file_read"},
-+    {ERR_FUNC(BIO_F_LINEBUFFER_CTRL), "linebuffer_ctrl"},
-+    {ERR_FUNC(BIO_F_MEM_WRITE), "mem_write"},
-+    {ERR_FUNC(BIO_F_SSL_NEW), "SSL_new"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA BIO_str_reasons[] = {
-+    {ERR_REASON(BIO_R_ACCEPT_ERROR), "accept error"},
-+    {ERR_REASON(BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET),
-+     "addrinfo addr is not af inet"},
-+    {ERR_REASON(BIO_R_AMBIGUOUS_HOST_OR_SERVICE),
-+     "ambiguous host or service"},
-+    {ERR_REASON(BIO_R_BAD_FOPEN_MODE), "bad fopen mode"},
-+    {ERR_REASON(BIO_R_BROKEN_PIPE), "broken pipe"},
-+    {ERR_REASON(BIO_R_CONNECT_ERROR), "connect error"},
-+    {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),
-+     "gethostbyname addr is not af inet"},
-+    {ERR_REASON(BIO_R_GETSOCKNAME_ERROR), "getsockname error"},
-+    {ERR_REASON(BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS),
-+     "getsockname truncated address"},
-+    {ERR_REASON(BIO_R_GETTING_SOCKTYPE), "getting socktype"},
-+    {ERR_REASON(BIO_R_INVALID_ARGUMENT), "invalid argument"},
-+    {ERR_REASON(BIO_R_INVALID_SOCKET), "invalid socket"},
-+    {ERR_REASON(BIO_R_IN_USE), "in use"},
-+    {ERR_REASON(BIO_R_LISTEN_V6_ONLY), "listen v6 only"},
-+    {ERR_REASON(BIO_R_LOOKUP_RETURNED_NOTHING), "lookup returned nothing"},
-+    {ERR_REASON(BIO_R_MALFORMED_HOST_OR_SERVICE),
-+     "malformed host or service"},
-+    {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR), "nbio connect error"},
-+    {ERR_REASON(BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED),
-+     "no accept addr or service specified"},
-+    {ERR_REASON(BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED),
-+     "no hostname or service specified"},
-+    {ERR_REASON(BIO_R_NO_PORT_DEFINED), "no port defined"},
-+    {ERR_REASON(BIO_R_NO_SUCH_FILE), "no such file"},
-+    {ERR_REASON(BIO_R_NULL_PARAMETER), "null parameter"},
-+    {ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET), "unable to bind socket"},
-+    {ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET), "unable to create socket"},
-+    {ERR_REASON(BIO_R_UNABLE_TO_KEEPALIVE), "unable to keepalive"},
-+    {ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET), "unable to listen socket"},
-+    {ERR_REASON(BIO_R_UNABLE_TO_NODELAY), "unable to nodelay"},
-+    {ERR_REASON(BIO_R_UNABLE_TO_REUSEADDR), "unable to reuseaddr"},
-+    {ERR_REASON(BIO_R_UNAVAILABLE_IP_FAMILY), "unavailable ip family"},
-+    {ERR_REASON(BIO_R_UNINITIALIZED), "uninitialized"},
-+    {ERR_REASON(BIO_R_UNKNOWN_INFO_TYPE), "unknown info type"},
-+    {ERR_REASON(BIO_R_UNSUPPORTED_IP_FAMILY), "unsupported ip family"},
-+    {ERR_REASON(BIO_R_UNSUPPORTED_METHOD), "unsupported method"},
-+    {ERR_REASON(BIO_R_UNSUPPORTED_PROTOCOL_FAMILY),
-+     "unsupported protocol family"},
-+    {ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"},
-+    {ERR_REASON(BIO_R_WSASTARTUP), "WSAStartup"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_BIO_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, BIO_str_functs);
-+        ERR_load_strings(0, BIO_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_lcl.h
-new file mode 100644
-index 0000000..39178cf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_lcl.h
-@@ -0,0 +1,188 @@
-+/*
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#define USE_SOCKETS
-+#include "e_os.h"
-+
-+/* BEGIN BIO_ADDRINFO/BIO_ADDR stuff. */
-+
-+#ifndef OPENSSL_NO_SOCK
-+/*
-+ * Throughout this file and b_addr.c, the existence of the macro
-+ * AI_PASSIVE is used to detect the availability of struct addrinfo,
-+ * getnameinfo() and getaddrinfo().  If that macro doesn't exist,
-+ * we use our own implementation instead.
-+ */
-+
-+/*
-+ * It's imperative that these macros get defined before openssl/bio.h gets
-+ * included.  Otherwise, the AI_PASSIVE hack will not work properly.
-+ * For clarity, we check for internal/cryptlib.h since it's a common header
-+ * that also includes bio.h.
-+ */
-+# ifdef HEADER_CRYPTLIB_H
-+#  error internal/cryptlib.h included before bio_lcl.h
-+# endif
-+# ifdef HEADER_BIO_H
-+#  error openssl/bio.h included before bio_lcl.h
-+# endif
-+
-+/*
-+ * Undefine AF_UNIX on systems that define it but don't support it.
-+ */
-+# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VMS)
-+#  undef AF_UNIX
-+# endif
-+
-+# ifdef AI_PASSIVE
-+
-+/*
-+ * There's a bug in VMS C header file netdb.h, where struct addrinfo
-+ * always is the P32 variant, but the functions that handle that structure,
-+ * such as getaddrinfo() and freeaddrinfo() adapt to the initial pointer
-+ * size.  The easiest workaround is to force struct addrinfo to be the
-+ * 64-bit variant when compiling in P64 mode.
-+ */
-+#  if defined(OPENSSL_SYS_VMS) && __INITIAL_POINTER_SIZE == 64
-+#   define addrinfo __addrinfo64
-+#  endif
-+
-+#  define bio_addrinfo_st addrinfo
-+#  define bai_family      ai_family
-+#  define bai_socktype    ai_socktype
-+#  define bai_protocol    ai_protocol
-+#  define bai_addrlen     ai_addrlen
-+#  define bai_addr        ai_addr
-+#  define bai_next        ai_next
-+# else
-+struct bio_addrinfo_st {
-+    int bai_family;
-+    int bai_socktype;
-+    int bai_protocol;
-+    size_t bai_addrlen;
-+    struct sockaddr *bai_addr;
-+    struct bio_addrinfo_st *bai_next;
-+};
-+# endif
-+
-+union bio_addr_st {
-+    struct sockaddr sa;
-+# ifdef AF_INET6
-+    struct sockaddr_in6 s_in6;
-+# endif
-+    struct sockaddr_in s_in;
-+# ifdef AF_UNIX
-+    struct sockaddr_un s_un;
-+# endif
-+};
-+#endif
-+
-+/* END BIO_ADDRINFO/BIO_ADDR stuff. */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+
-+typedef struct bio_f_buffer_ctx_struct {
-+    /*-
-+     * Buffers are setup like this:
-+     *
-+     * <---------------------- size ----------------------->
-+     * +---------------------------------------------------+
-+     * | consumed | remaining          | free space        |
-+     * +---------------------------------------------------+
-+     * <-- off --><------- len ------->
-+     */
-+    /*- BIO *bio; *//*
-+     * this is now in the BIO struct
-+     */
-+    int ibuf_size;              /* how big is the input buffer */
-+    int obuf_size;              /* how big is the output buffer */
-+    char *ibuf;                 /* the char array */
-+    int ibuf_len;               /* how many bytes are in it */
-+    int ibuf_off;               /* write/read offset */
-+    char *obuf;                 /* the char array */
-+    int obuf_len;               /* how many bytes are in it */
-+    int obuf_off;               /* write/read offset */
-+} BIO_F_BUFFER_CTX;
-+
-+struct bio_st {
-+    const BIO_METHOD *method;
-+    /* bio, mode, argp, argi, argl, ret */
-+    long (*callback) (struct bio_st *, int, const char *, int, long, long);
-+    char *cb_arg;               /* first argument for the callback */
-+    int init;
-+    int shutdown;
-+    int flags;                  /* extra storage */
-+    int retry_reason;
-+    int num;
-+    void *ptr;
-+    struct bio_st *next_bio;    /* used by filter BIOs */
-+    struct bio_st *prev_bio;    /* used by filter BIOs */
-+    int references;
-+    uint64_t num_read;
-+    uint64_t num_write;
-+    CRYPTO_EX_DATA ex_data;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+#ifndef OPENSSL_NO_SOCK
-+# ifdef OPENSSL_SYS_VMS
-+typedef unsigned int socklen_t;
-+# endif
-+
-+extern CRYPTO_RWLOCK *bio_lookup_lock;
-+
-+int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa);
-+const struct sockaddr *BIO_ADDR_sockaddr(const BIO_ADDR *ap);
-+struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap);
-+socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap);
-+socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai);
-+const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai);
-+#endif
-+
-+extern CRYPTO_RWLOCK *bio_type_lock;
-+
-+void bio_sock_cleanup_int(void);
-+
-+#if BIO_FLAGS_UPLINK==0
-+/* Shortcut UPLINK calls on most platforms... */
-+# define UP_stdin        stdin
-+# define UP_stdout       stdout
-+# define UP_stderr       stderr
-+# define UP_fprintf      fprintf
-+# define UP_fgets        fgets
-+# define UP_fread        fread
-+# define UP_fwrite       fwrite
-+# undef  UP_fsetmod
-+# define UP_feof         feof
-+# define UP_fclose       fclose
-+
-+# define UP_fopen        fopen
-+# define UP_fseek        fseek
-+# define UP_ftell        ftell
-+# define UP_fflush       fflush
-+# define UP_ferror       ferror
-+# ifdef _WIN32
-+#  define UP_fileno       _fileno
-+#  define UP_open         _open
-+#  define UP_read         _read
-+#  define UP_write        _write
-+#  define UP_lseek        _lseek
-+#  define UP_close        _close
-+# else
-+#  define UP_fileno       fileno
-+#  define UP_open         open
-+#  define UP_read         read
-+#  define UP_write        write
-+#  define UP_lseek        lseek
-+#  define UP_close        close
-+# endif
-+
-+#endif
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_lib.c
-new file mode 100644
-index 0000000..62392c3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_lib.c
-@@ -0,0 +1,600 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "bio_lcl.h"
-+#include "internal/cryptlib.h"
-+
-+BIO *BIO_new(const BIO_METHOD *method)
-+{
-+    BIO *bio = OPENSSL_zalloc(sizeof(*bio));
-+
-+    if (bio == NULL) {
-+        BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+
-+    bio->method = method;
-+    bio->shutdown = 1;
-+    bio->references = 1;
-+
-+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data))
-+        goto err;
-+
-+    bio->lock = CRYPTO_THREAD_lock_new();
-+    if (bio->lock == NULL) {
-+        BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
-+        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
-+        goto err;
-+    }
-+
-+    if (method->create != NULL && !method->create(bio)) {
-+        BIOerr(BIO_F_BIO_NEW, ERR_R_INIT_FAIL);
-+        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
-+        CRYPTO_THREAD_lock_free(bio->lock);
-+        goto err;
-+    }
-+
-+    return bio;
-+
-+err:
-+    OPENSSL_free(bio);
-+    return NULL;
-+}
-+
-+int BIO_free(BIO *a)
-+{
-+    int i;
-+
-+    if (a == NULL)
-+        return 0;
-+
-+    if (CRYPTO_atomic_add(&a->references, -1, &i, a->lock) <= 0)
-+        return 0;
-+
-+    REF_PRINT_COUNT("BIO", a);
-+    if (i > 0)
-+        return 1;
-+    REF_ASSERT_ISNT(i < 0);
-+    if ((a->callback != NULL) &&
-+        ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0))
-+        return i;
-+
-+    if ((a->method != NULL) && (a->method->destroy != NULL))
-+        a->method->destroy(a);
-+
-+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
-+
-+    CRYPTO_THREAD_lock_free(a->lock);
-+
-+    OPENSSL_free(a);
-+
-+    return 1;
-+}
-+
-+void BIO_set_data(BIO *a, void *ptr)
-+{
-+    a->ptr = ptr;
-+}
-+
-+void *BIO_get_data(BIO *a)
-+{
-+    return a->ptr;
-+}
-+
-+void BIO_set_init(BIO *a, int init)
-+{
-+    a->init = init;
-+}
-+
-+int BIO_get_init(BIO *a)
-+{
-+    return a->init;
-+}
-+
-+void BIO_set_shutdown(BIO *a, int shut)
-+{
-+    a->shutdown = shut;
-+}
-+
-+int BIO_get_shutdown(BIO *a)
-+{
-+    return a->shutdown;
-+}
-+
-+void BIO_vfree(BIO *a)
-+{
-+    BIO_free(a);
-+}
-+
-+int BIO_up_ref(BIO *a)
-+{
-+    int i;
-+
-+    if (CRYPTO_atomic_add(&a->references, 1, &i, a->lock) <= 0)
-+        return 0;
-+
-+    REF_PRINT_COUNT("BIO", a);
-+    REF_ASSERT_ISNT(i < 2);
-+    return ((i > 1) ? 1 : 0);
-+}
-+
-+void BIO_clear_flags(BIO *b, int flags)
-+{
-+    b->flags &= ~flags;
-+}
-+
-+int BIO_test_flags(const BIO *b, int flags)
-+{
-+    return (b->flags & flags);
-+}
-+
-+void BIO_set_flags(BIO *b, int flags)
-+{
-+    b->flags |= flags;
-+}
-+
-+long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *,
-+                                        int, long, long) {
-+    return b->callback;
-+}
-+
-+void BIO_set_callback(BIO *b,
-+                      long (*cb) (struct bio_st *, int, const char *, int,
-+                                  long, long))
-+{
-+    b->callback = cb;
-+}
-+
-+void BIO_set_callback_arg(BIO *b, char *arg)
-+{
-+    b->cb_arg = arg;
-+}
-+
-+char *BIO_get_callback_arg(const BIO *b)
-+{
-+    return b->cb_arg;
-+}
-+
-+const char *BIO_method_name(const BIO *b)
-+{
-+    return b->method->name;
-+}
-+
-+int BIO_method_type(const BIO *b)
-+{
-+    return b->method->type;
-+}
-+
-+int BIO_read(BIO *b, void *out, int outl)
-+{
-+    int i;
-+    long (*cb) (BIO *, int, const char *, int, long, long);
-+
-+    if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
-+        BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD);
-+        return (-2);
-+    }
-+
-+    cb = b->callback;
-+    if ((cb != NULL) &&
-+        ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0))
-+        return (i);
-+
-+    if (!b->init) {
-+        BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED);
-+        return (-2);
-+    }
-+
-+    i = b->method->bread(b, out, outl);
-+
-+    if (i > 0)
-+        b->num_read += (uint64_t)i;
-+
-+    if (cb != NULL)
-+        i = (int)cb(b, BIO_CB_READ | BIO_CB_RETURN, out, outl, 0L, (long)i);
-+    return (i);
-+}
-+
-+int BIO_write(BIO *b, const void *in, int inl)
-+{
-+    int i;
-+    long (*cb) (BIO *, int, const char *, int, long, long);
-+
-+    if (b == NULL)
-+        return (0);
-+
-+    cb = b->callback;
-+    if ((b->method == NULL) || (b->method->bwrite == NULL)) {
-+        BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD);
-+        return (-2);
-+    }
-+
-+    if ((cb != NULL) &&
-+        ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0))
-+        return (i);
-+
-+    if (!b->init) {
-+        BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED);
-+        return (-2);
-+    }
-+
-+    i = b->method->bwrite(b, in, inl);
-+
-+    if (i > 0)
-+        b->num_write += (uint64_t)i;
-+
-+    if (cb != NULL)
-+        i = (int)cb(b, BIO_CB_WRITE | BIO_CB_RETURN, in, inl, 0L, (long)i);
-+    return (i);
-+}
-+
-+int BIO_puts(BIO *b, const char *in)
-+{
-+    int i;
-+    long (*cb) (BIO *, int, const char *, int, long, long);
-+
-+    if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
-+        BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD);
-+        return (-2);
-+    }
-+
-+    cb = b->callback;
-+
-+    if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0))
-+        return (i);
-+
-+    if (!b->init) {
-+        BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
-+        return (-2);
-+    }
-+
-+    i = b->method->bputs(b, in);
-+
-+    if (i > 0)
-+        b->num_write += (uint64_t)i;
-+
-+    if (cb != NULL)
-+        i = (int)cb(b, BIO_CB_PUTS | BIO_CB_RETURN, in, 0, 0L, (long)i);
-+    return (i);
-+}
-+
-+int BIO_gets(BIO *b, char *in, int inl)
-+{
-+    int i;
-+    long (*cb) (BIO *, int, const char *, int, long, long);
-+
-+    if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
-+        BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
-+        return (-2);
-+    }
-+
-+    cb = b->callback;
-+
-+    if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0))
-+        return (i);
-+
-+    if (!b->init) {
-+        BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
-+        return (-2);
-+    }
-+
-+    i = b->method->bgets(b, in, inl);
-+
-+    if (cb != NULL)
-+        i = (int)cb(b, BIO_CB_GETS | BIO_CB_RETURN, in, inl, 0L, (long)i);
-+    return (i);
-+}
-+
-+int BIO_indent(BIO *b, int indent, int max)
-+{
-+    if (indent < 0)
-+        indent = 0;
-+    if (indent > max)
-+        indent = max;
-+    while (indent--)
-+        if (BIO_puts(b, " ") != 1)
-+            return 0;
-+    return 1;
-+}
-+
-+long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
-+{
-+    int i;
-+
-+    i = iarg;
-+    return (BIO_ctrl(b, cmd, larg, (char *)&i));
-+}
-+
-+void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
-+{
-+    void *p = NULL;
-+
-+    if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
-+        return (NULL);
-+    else
-+        return (p);
-+}
-+
-+long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
-+{
-+    long ret;
-+    long (*cb) (BIO *, int, const char *, int, long, long);
-+
-+    if (b == NULL)
-+        return (0);
-+
-+    if ((b->method == NULL) || (b->method->ctrl == NULL)) {
-+        BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
-+        return (-2);
-+    }
-+
-+    cb = b->callback;
-+
-+    if ((cb != NULL) &&
-+        ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0))
-+        return (ret);
-+
-+    ret = b->method->ctrl(b, cmd, larg, parg);
-+
-+    if (cb != NULL)
-+        ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, cmd, larg, ret);
-+    return (ret);
-+}
-+
-+long BIO_callback_ctrl(BIO *b, int cmd,
-+                       void (*fp) (struct bio_st *, int, const char *, int,
-+                                   long, long))
-+{
-+    long ret;
-+    long (*cb) (BIO *, int, const char *, int, long, long);
-+
-+    if (b == NULL)
-+        return (0);
-+
-+    if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) {
-+        BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
-+        return (-2);
-+    }
-+
-+    cb = b->callback;
-+
-+    if ((cb != NULL) &&
-+        ((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0))
-+        return (ret);
-+
-+    ret = b->method->callback_ctrl(b, cmd, fp);
-+
-+    if (cb != NULL)
-+        ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, cmd, 0, ret);
-+    return (ret);
-+}
-+
-+/*
-+ * It is unfortunate to duplicate in functions what the BIO_(w)pending macros
-+ * do; but those macros have inappropriate return type, and for interfacing
-+ * from other programming languages, C macros aren't much of a help anyway.
-+ */
-+size_t BIO_ctrl_pending(BIO *bio)
-+{
-+    return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
-+}
-+
-+size_t BIO_ctrl_wpending(BIO *bio)
-+{
-+    return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
-+}
-+
-+/* put the 'bio' on the end of b's list of operators */
-+BIO *BIO_push(BIO *b, BIO *bio)
-+{
-+    BIO *lb;
-+
-+    if (b == NULL)
-+        return (bio);
-+    lb = b;
-+    while (lb->next_bio != NULL)
-+        lb = lb->next_bio;
-+    lb->next_bio = bio;
-+    if (bio != NULL)
-+        bio->prev_bio = lb;
-+    /* called to do internal processing */
-+    BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
-+    return (b);
-+}
-+
-+/* Remove the first and return the rest */
-+BIO *BIO_pop(BIO *b)
-+{
-+    BIO *ret;
-+
-+    if (b == NULL)
-+        return (NULL);
-+    ret = b->next_bio;
-+
-+    BIO_ctrl(b, BIO_CTRL_POP, 0, b);
-+
-+    if (b->prev_bio != NULL)
-+        b->prev_bio->next_bio = b->next_bio;
-+    if (b->next_bio != NULL)
-+        b->next_bio->prev_bio = b->prev_bio;
-+
-+    b->next_bio = NULL;
-+    b->prev_bio = NULL;
-+    return (ret);
-+}
-+
-+BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
-+{
-+    BIO *b, *last;
-+
-+    b = last = bio;
-+    for (;;) {
-+        if (!BIO_should_retry(b))
-+            break;
-+        last = b;
-+        b = b->next_bio;
-+        if (b == NULL)
-+            break;
-+    }
-+    if (reason != NULL)
-+        *reason = last->retry_reason;
-+    return (last);
-+}
-+
-+int BIO_get_retry_reason(BIO *bio)
-+{
-+    return (bio->retry_reason);
-+}
-+
-+void BIO_set_retry_reason(BIO *bio, int reason)
-+{
-+    bio->retry_reason = reason;
-+}
-+
-+BIO *BIO_find_type(BIO *bio, int type)
-+{
-+    int mt, mask;
-+
-+    if (bio == NULL)
-+        return NULL;
-+    mask = type & 0xff;
-+    do {
-+        if (bio->method != NULL) {
-+            mt = bio->method->type;
-+
-+            if (!mask) {
-+                if (mt & type)
-+                    return (bio);
-+            } else if (mt == type)
-+                return (bio);
-+        }
-+        bio = bio->next_bio;
-+    } while (bio != NULL);
-+    return (NULL);
-+}
-+
-+BIO *BIO_next(BIO *b)
-+{
-+    if (b == NULL)
-+        return NULL;
-+    return b->next_bio;
-+}
-+
-+void BIO_set_next(BIO *b, BIO *next)
-+{
-+    b->next_bio = next;
-+}
-+
-+void BIO_free_all(BIO *bio)
-+{
-+    BIO *b;
-+    int ref;
-+
-+    while (bio != NULL) {
-+        b = bio;
-+        ref = b->references;
-+        bio = bio->next_bio;
-+        BIO_free(b);
-+        /* Since ref count > 1, don't free anyone else. */
-+        if (ref > 1)
-+            break;
-+    }
-+}
-+
-+BIO *BIO_dup_chain(BIO *in)
-+{
-+    BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;
-+
-+    for (bio = in; bio != NULL; bio = bio->next_bio) {
-+        if ((new_bio = BIO_new(bio->method)) == NULL)
-+            goto err;
-+        new_bio->callback = bio->callback;
-+        new_bio->cb_arg = bio->cb_arg;
-+        new_bio->init = bio->init;
-+        new_bio->shutdown = bio->shutdown;
-+        new_bio->flags = bio->flags;
-+
-+        /* This will let SSL_s_sock() work with stdin/stdout */
-+        new_bio->num = bio->num;
-+
-+        if (!BIO_dup_state(bio, (char *)new_bio)) {
-+            BIO_free(new_bio);
-+            goto err;
-+        }
-+
-+        /* copy app data */
-+        if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
-+                                &bio->ex_data)) {
-+            BIO_free(new_bio);
-+            goto err;
-+        }
-+
-+        if (ret == NULL) {
-+            eoc = new_bio;
-+            ret = eoc;
-+        } else {
-+            BIO_push(eoc, new_bio);
-+            eoc = new_bio;
-+        }
-+    }
-+    return (ret);
-+ err:
-+    BIO_free_all(ret);
-+
-+    return (NULL);
-+}
-+
-+void BIO_copy_next_retry(BIO *b)
-+{
-+    BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
-+    b->retry_reason = b->next_bio->retry_reason;
-+}
-+
-+int BIO_set_ex_data(BIO *bio, int idx, void *data)
-+{
-+    return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data));
-+}
-+
-+void *BIO_get_ex_data(BIO *bio, int idx)
-+{
-+    return (CRYPTO_get_ex_data(&(bio->ex_data), idx));
-+}
-+
-+uint64_t BIO_number_read(BIO *bio)
-+{
-+    if (bio)
-+        return bio->num_read;
-+    return 0;
-+}
-+
-+uint64_t BIO_number_written(BIO *bio)
-+{
-+    if (bio)
-+        return bio->num_write;
-+    return 0;
-+}
-+
-+void bio_free_ex_data(BIO *bio)
-+{
-+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
-+}
-+
-+void bio_cleanup(void)
-+{
-+#ifndef OPENSSL_NO_SOCK
-+    bio_sock_cleanup_int();
-+    CRYPTO_THREAD_lock_free(bio_lookup_lock);
-+    bio_lookup_lock = NULL;
-+#endif
-+    CRYPTO_THREAD_lock_free(bio_type_lock);
-+    bio_type_lock = NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_meth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_meth.c
-new file mode 100644
-index 0000000..c5f9f7e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bio_meth.c
-@@ -0,0 +1,145 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "bio_lcl.h"
-+#include 
-+
-+CRYPTO_RWLOCK *bio_type_lock = NULL;
-+static CRYPTO_ONCE bio_type_init = CRYPTO_ONCE_STATIC_INIT;
-+
-+DEFINE_RUN_ONCE_STATIC(do_bio_type_init)
-+{
-+    bio_type_lock = CRYPTO_THREAD_lock_new();
-+    return bio_type_lock != NULL;
-+}
-+
-+int BIO_get_new_index()
-+{
-+    static int bio_count = BIO_TYPE_START;
-+    int newval;
-+
-+    if (!RUN_ONCE(&bio_type_init, do_bio_type_init)) {
-+        BIOerr(BIO_F_BIO_GET_NEW_INDEX, ERR_R_MALLOC_FAILURE);
-+        return -1;
-+    }
-+    if (!CRYPTO_atomic_add(&bio_count, 1, &newval, bio_type_lock))
-+        return -1;
-+    return newval;
-+}
-+
-+BIO_METHOD *BIO_meth_new(int type, const char *name)
-+{
-+    BIO_METHOD *biom = OPENSSL_zalloc(sizeof(BIO_METHOD));
-+
-+    if (biom != NULL) {
-+        biom->type = type;
-+        biom->name = name;
-+    }
-+    return biom;
-+}
-+
-+void BIO_meth_free(BIO_METHOD *biom)
-+{
-+    OPENSSL_free(biom);
-+}
-+
-+int (*BIO_meth_get_write(BIO_METHOD *biom)) (BIO *, const char *, int)
-+{
-+    return biom->bwrite;
-+}
-+
-+int BIO_meth_set_write(BIO_METHOD *biom,
-+                       int (*bwrite) (BIO *, const char *, int))
-+{
-+    biom->bwrite = bwrite;
-+    return 1;
-+}
-+
-+int (*BIO_meth_get_read(BIO_METHOD *biom)) (BIO *, char *, int)
-+{
-+    return biom->bread;
-+}
-+
-+int BIO_meth_set_read(BIO_METHOD *biom,
-+                      int (*bread) (BIO *, char *, int))
-+{
-+    biom->bread = bread;
-+    return 1;
-+}
-+
-+int (*BIO_meth_get_puts(BIO_METHOD *biom)) (BIO *, const char *)
-+{
-+    return biom->bputs;
-+}
-+
-+int BIO_meth_set_puts(BIO_METHOD *biom,
-+                      int (*bputs) (BIO *, const char *))
-+{
-+    biom->bputs = bputs;
-+    return 1;
-+}
-+
-+int (*BIO_meth_get_gets(BIO_METHOD *biom)) (BIO *, char *, int)
-+{
-+    return biom->bgets;
-+}
-+
-+int BIO_meth_set_gets(BIO_METHOD *biom,
-+                      int (*bgets) (BIO *, char *, int))
-+{
-+    biom->bgets = bgets;
-+    return 1;
-+}
-+
-+long (*BIO_meth_get_ctrl(BIO_METHOD *biom)) (BIO *, int, long, void *)
-+{
-+    return biom->ctrl;
-+}
-+
-+int BIO_meth_set_ctrl(BIO_METHOD *biom,
-+                      long (*ctrl) (BIO *, int, long, void *))
-+{
-+    biom->ctrl = ctrl;
-+    return 1;
-+}
-+
-+int (*BIO_meth_get_create(BIO_METHOD *biom)) (BIO *)
-+{
-+    return biom->create;
-+}
-+
-+int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
-+{
-+    biom->create = create;
-+    return 1;
-+}
-+
-+int (*BIO_meth_get_destroy(BIO_METHOD *biom)) (BIO *)
-+{
-+    return biom->destroy;
-+}
-+
-+int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
-+{
-+    biom->destroy = destroy;
-+    return 1;
-+}
-+
-+long (*BIO_meth_get_callback_ctrl(BIO_METHOD *biom)) (BIO *, int, bio_info_cb *)
-+{
-+    return biom->callback_ctrl;
-+}
-+
-+int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
-+                               long (*callback_ctrl) (BIO *, int,
-+                                                      bio_info_cb *))
-+{
-+    biom->callback_ctrl = callback_ctrl;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_acpt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_acpt.c
-new file mode 100644
-index 0000000..6fb971a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_acpt.c
-@@ -0,0 +1,557 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "bio_lcl.h"
-+
-+#ifndef OPENSSL_NO_SOCK
-+
-+typedef struct bio_accept_st {
-+    int state;
-+    int accept_family;
-+    int bind_mode;     /* Socket mode for BIO_listen */
-+    int accepted_mode; /* Socket mode for BIO_accept (set on accepted sock) */
-+    char *param_addr;
-+    char *param_serv;
-+
-+    int accept_sock;
-+
-+    BIO_ADDRINFO *addr_first;
-+    const BIO_ADDRINFO *addr_iter;
-+    BIO_ADDR cache_accepting_addr;   /* Useful if we asked for port 0 */
-+    char *cache_accepting_name, *cache_accepting_serv;
-+    BIO_ADDR cache_peer_addr;
-+    char *cache_peer_name, *cache_peer_serv;
-+
-+    BIO *bio_chain;
-+} BIO_ACCEPT;
-+
-+static int acpt_write(BIO *h, const char *buf, int num);
-+static int acpt_read(BIO *h, char *buf, int size);
-+static int acpt_puts(BIO *h, const char *str);
-+static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int acpt_new(BIO *h);
-+static int acpt_free(BIO *data);
-+static int acpt_state(BIO *b, BIO_ACCEPT *c);
-+static void acpt_close_socket(BIO *data);
-+static BIO_ACCEPT *BIO_ACCEPT_new(void);
-+static void BIO_ACCEPT_free(BIO_ACCEPT *a);
-+
-+# define ACPT_S_BEFORE                   1
-+# define ACPT_S_GET_ADDR                 2
-+# define ACPT_S_CREATE_SOCKET            3
-+# define ACPT_S_LISTEN                   4
-+# define ACPT_S_ACCEPT                   5
-+# define ACPT_S_OK                       6
-+
-+static const BIO_METHOD methods_acceptp = {
-+    BIO_TYPE_ACCEPT,
-+    "socket accept",
-+    acpt_write,
-+    acpt_read,
-+    acpt_puts,
-+    NULL,                       /* connect_gets, */
-+    acpt_ctrl,
-+    acpt_new,
-+    acpt_free,
-+    NULL,
-+};
-+
-+const BIO_METHOD *BIO_s_accept(void)
-+{
-+    return (&methods_acceptp);
-+}
-+
-+static int acpt_new(BIO *bi)
-+{
-+    BIO_ACCEPT *ba;
-+
-+    bi->init = 0;
-+    bi->num = (int)INVALID_SOCKET;
-+    bi->flags = 0;
-+    if ((ba = BIO_ACCEPT_new()) == NULL)
-+        return (0);
-+    bi->ptr = (char *)ba;
-+    ba->state = ACPT_S_BEFORE;
-+    bi->shutdown = 1;
-+    return (1);
-+}
-+
-+static BIO_ACCEPT *BIO_ACCEPT_new(void)
-+{
-+    BIO_ACCEPT *ret;
-+
-+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
-+        return (NULL);
-+    ret->accept_family = BIO_FAMILY_IPANY;
-+    ret->accept_sock = (int)INVALID_SOCKET;
-+    return (ret);
-+}
-+
-+static void BIO_ACCEPT_free(BIO_ACCEPT *a)
-+{
-+    if (a == NULL)
-+        return;
-+
-+    OPENSSL_free(a->param_addr);
-+    OPENSSL_free(a->param_serv);
-+    BIO_ADDRINFO_free(a->addr_first);
-+    OPENSSL_free(a->cache_accepting_name);
-+    OPENSSL_free(a->cache_accepting_serv);
-+    OPENSSL_free(a->cache_peer_name);
-+    OPENSSL_free(a->cache_peer_serv);
-+    BIO_free(a->bio_chain);
-+    OPENSSL_free(a);
-+}
-+
-+static void acpt_close_socket(BIO *bio)
-+{
-+    BIO_ACCEPT *c;
-+
-+    c = (BIO_ACCEPT *)bio->ptr;
-+    if (c->accept_sock != (int)INVALID_SOCKET) {
-+        shutdown(c->accept_sock, 2);
-+        closesocket(c->accept_sock);
-+        c->accept_sock = (int)INVALID_SOCKET;
-+        bio->num = (int)INVALID_SOCKET;
-+    }
-+}
-+
-+static int acpt_free(BIO *a)
-+{
-+    BIO_ACCEPT *data;
-+
-+    if (a == NULL)
-+        return (0);
-+    data = (BIO_ACCEPT *)a->ptr;
-+
-+    if (a->shutdown) {
-+        acpt_close_socket(a);
-+        BIO_ACCEPT_free(data);
-+        a->ptr = NULL;
-+        a->flags = 0;
-+        a->init = 0;
-+    }
-+    return (1);
-+}
-+
-+static int acpt_state(BIO *b, BIO_ACCEPT *c)
-+{
-+    BIO *bio = NULL, *dbio;
-+    int s = -1, ret = -1;
-+
-+    for (;;) {
-+        switch (c->state) {
-+        case ACPT_S_BEFORE:
-+            if (c->param_addr == NULL && c->param_serv == NULL) {
-+                BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED);
-+                ERR_add_error_data(4,
-+                                   "hostname=", c->param_addr,
-+                                   " service=", c->param_serv);
-+                goto exit_loop;
-+            }
-+
-+            /* Because we're starting a new bind, any cached name and serv
-+             * are now obsolete and need to be cleaned out.
-+             * QUESTION: should this be done in acpt_close_socket() instead?
-+             */
-+            OPENSSL_free(c->cache_accepting_name);
-+            c->cache_accepting_name = NULL;
-+            OPENSSL_free(c->cache_accepting_serv);
-+            c->cache_accepting_serv = NULL;
-+            OPENSSL_free(c->cache_peer_name);
-+            c->cache_peer_name = NULL;
-+            OPENSSL_free(c->cache_peer_serv);
-+            c->cache_peer_serv = NULL;
-+
-+            c->state = ACPT_S_GET_ADDR;
-+            break;
-+
-+        case ACPT_S_GET_ADDR:
-+            {
-+                int family = AF_UNSPEC;
-+                switch (c->accept_family) {
-+                case BIO_FAMILY_IPV6:
-+                    if (1) { /* This is a trick we use to avoid bit rot.
-+                              * at least the "else" part will always be
-+                              * compiled.
-+                              */
-+#ifdef AF_INET6
-+                        family = AF_INET6;
-+                    } else {
-+#endif
-+                        BIOerr(BIO_F_ACPT_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
-+                        goto exit_loop;
-+                    }
-+                    break;
-+                case BIO_FAMILY_IPV4:
-+                    family = AF_INET;
-+                    break;
-+                case BIO_FAMILY_IPANY:
-+                    family = AF_UNSPEC;
-+                    break;
-+                default:
-+                    BIOerr(BIO_F_ACPT_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
-+                    goto exit_loop;
-+                }
-+                if (BIO_lookup(c->param_addr, c->param_serv, BIO_LOOKUP_SERVER,
-+                               family, SOCK_STREAM, &c->addr_first) == 0)
-+                    goto exit_loop;
-+            }
-+            if (c->addr_first == NULL) {
-+                BIOerr(BIO_F_ACPT_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
-+                goto exit_loop;
-+            }
-+            /* We're currently not iterating, but set this as preparation
-+             * for possible future development in that regard
-+             */
-+            c->addr_iter = c->addr_first;
-+            c->state = ACPT_S_CREATE_SOCKET;
-+            break;
-+
-+        case ACPT_S_CREATE_SOCKET:
-+            ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
-+                             BIO_ADDRINFO_socktype(c->addr_iter),
-+                             BIO_ADDRINFO_protocol(c->addr_iter), 0);
-+            if (ret == (int)INVALID_SOCKET) {
-+                SYSerr(SYS_F_SOCKET, get_last_socket_error());
-+                ERR_add_error_data(4,
-+                                   "hostname=", c->param_addr,
-+                                   " service=", c->param_serv);
-+                BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
-+                goto exit_loop;
-+            }
-+            c->accept_sock = ret;
-+            b->num = ret;
-+            c->state = ACPT_S_LISTEN;
-+            break;
-+
-+        case ACPT_S_LISTEN:
-+            {
-+                if (!BIO_listen(c->accept_sock,
-+                                BIO_ADDRINFO_address(c->addr_iter),
-+                                c->bind_mode)) {
-+                    BIO_closesocket(c->accept_sock);
-+                    goto exit_loop;
-+                }
-+            }
-+
-+            {
-+                union BIO_sock_info_u info;
-+
-+                info.addr = &c->cache_accepting_addr;
-+                if (!BIO_sock_info(c->accept_sock, BIO_SOCK_INFO_ADDRESS,
-+                                   &info)) {
-+                    BIO_closesocket(c->accept_sock);
-+                    goto exit_loop;
-+                }
-+            }
-+
-+            c->cache_accepting_name =
-+                BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1);
-+            c->cache_accepting_serv =
-+                BIO_ADDR_service_string(&c->cache_accepting_addr, 1);
-+            c->state = ACPT_S_ACCEPT;
-+            s = -1;
-+            ret = 1;
-+            goto end;
-+
-+        case ACPT_S_ACCEPT:
-+            if (b->next_bio != NULL) {
-+                c->state = ACPT_S_OK;
-+                break;
-+            }
-+            BIO_clear_retry_flags(b);
-+            b->retry_reason = 0;
-+
-+            s = BIO_accept_ex(c->accept_sock, &c->cache_peer_addr,
-+                              c->accepted_mode);
-+
-+            /* If the returned socket is invalid, this might still be
-+             * retryable
-+             */
-+            if (s < 0) {
-+                if (BIO_sock_should_retry(s)) {
-+                    BIO_set_retry_special(b);
-+                    b->retry_reason = BIO_RR_ACCEPT;
-+                    goto end;
-+                }
-+            }
-+
-+            /* If it wasn't retryable, we fail */
-+            if (s < 0) {
-+                ret = s;
-+                goto exit_loop;
-+            }
-+
-+            bio = BIO_new_socket(s, BIO_CLOSE);
-+            if (bio == NULL)
-+                goto exit_loop;
-+
-+            BIO_set_callback(bio, BIO_get_callback(b));
-+            BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
-+
-+            /*
-+             * If the accept BIO has an bio_chain, we dup it and put the new
-+             * socket at the end.
-+             */
-+            if (c->bio_chain != NULL) {
-+                if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
-+                    goto exit_loop;
-+                if (!BIO_push(dbio, bio))
-+                    goto exit_loop;
-+                bio = dbio;
-+            }
-+            if (BIO_push(b, bio) == NULL)
-+                goto exit_loop;
-+
-+            c->cache_peer_name =
-+                BIO_ADDR_hostname_string(&c->cache_peer_addr, 1);
-+            c->cache_peer_serv =
-+                BIO_ADDR_service_string(&c->cache_peer_addr, 1);
-+            c->state = ACPT_S_OK;
-+            bio = NULL;
-+            ret = 1;
-+            goto end;
-+
-+        case ACPT_S_OK:
-+            if (b->next_bio == NULL) {
-+                c->state = ACPT_S_ACCEPT;
-+                break;
-+            }
-+            ret = 1;
-+            goto end;
-+
-+        default:
-+            ret = 0;
-+            goto end;
-+        }
-+    }
-+
-+  exit_loop:
-+    if (bio != NULL)
-+        BIO_free(bio);
-+    else if (s >= 0)
-+        BIO_closesocket(s);
-+  end:
-+    return ret;
-+}
-+
-+static int acpt_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0;
-+    BIO_ACCEPT *data;
-+
-+    BIO_clear_retry_flags(b);
-+    data = (BIO_ACCEPT *)b->ptr;
-+
-+    while (b->next_bio == NULL) {
-+        ret = acpt_state(b, data);
-+        if (ret <= 0)
-+            return (ret);
-+    }
-+
-+    ret = BIO_read(b->next_bio, out, outl);
-+    BIO_copy_next_retry(b);
-+    return (ret);
-+}
-+
-+static int acpt_write(BIO *b, const char *in, int inl)
-+{
-+    int ret;
-+    BIO_ACCEPT *data;
-+
-+    BIO_clear_retry_flags(b);
-+    data = (BIO_ACCEPT *)b->ptr;
-+
-+    while (b->next_bio == NULL) {
-+        ret = acpt_state(b, data);
-+        if (ret <= 0)
-+            return (ret);
-+    }
-+
-+    ret = BIO_write(b->next_bio, in, inl);
-+    BIO_copy_next_retry(b);
-+    return (ret);
-+}
-+
-+static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    int *ip;
-+    long ret = 1;
-+    BIO_ACCEPT *data;
-+    char **pp;
-+
-+    data = (BIO_ACCEPT *)b->ptr;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        ret = 0;
-+        data->state = ACPT_S_BEFORE;
-+        acpt_close_socket(b);
-+        BIO_ADDRINFO_free(data->addr_first);
-+        data->addr_first = NULL;
-+        b->flags = 0;
-+        break;
-+    case BIO_C_DO_STATE_MACHINE:
-+        /* use this one to start the connection */
-+        ret = (long)acpt_state(b, data);
-+        break;
-+    case BIO_C_SET_ACCEPT:
-+        if (ptr != NULL) {
-+            if (num == 0) {
-+                char *hold_serv = data->param_serv;
-+                /* We affect the hostname regardless.  However, the input
-+                 * string might contain a host:service spec, so we must
-+                 * parse it, which might or might not affect the service
-+                 */
-+                OPENSSL_free(data->param_addr);
-+                data->param_addr = NULL;
-+                ret = BIO_parse_hostserv(ptr,
-+                                         &data->param_addr,
-+                                         &data->param_serv,
-+                                         BIO_PARSE_PRIO_SERV);
-+                if (hold_serv != data->param_serv)
-+                    OPENSSL_free(hold_serv);
-+                b->init = 1;
-+            } else if (num == 1) {
-+                OPENSSL_free(data->param_serv);
-+                data->param_serv = BUF_strdup(ptr);
-+                b->init = 1;
-+            } else if (num == 2) {
-+                data->bind_mode |= BIO_SOCK_NONBLOCK;
-+            } else if (num == 3) {
-+                BIO_free(data->bio_chain);
-+                data->bio_chain = (BIO *)ptr;
-+            } else if (num == 4) {
-+                data->accept_family = *(int *)ptr;
-+            }
-+        } else {
-+            if (num == 2) {
-+                data->bind_mode &= ~BIO_SOCK_NONBLOCK;
-+            }
-+        }
-+        break;
-+    case BIO_C_SET_NBIO:
-+        if (num != 0)
-+            data->accepted_mode |= BIO_SOCK_NONBLOCK;
-+        else
-+            data->accepted_mode &= ~BIO_SOCK_NONBLOCK;
-+        break;
-+    case BIO_C_SET_FD:
-+        b->init = 1;
-+        b->num = *((int *)ptr);
-+        data->accept_sock = b->num;
-+        data->state = ACPT_S_ACCEPT;
-+        b->shutdown = (int)num;
-+        b->init = 1;
-+        break;
-+    case BIO_C_GET_FD:
-+        if (b->init) {
-+            ip = (int *)ptr;
-+            if (ip != NULL)
-+                *ip = data->accept_sock;
-+            ret = data->accept_sock;
-+        } else
-+            ret = -1;
-+        break;
-+    case BIO_C_GET_ACCEPT:
-+        if (b->init) {
-+            if (num == 0 && ptr != NULL) {
-+                pp = (char **)ptr;
-+                *pp = data->cache_accepting_name;
-+            } else if (num == 1 && ptr != NULL) {
-+                pp = (char **)ptr;
-+                *pp = data->cache_accepting_serv;
-+            } else if (num == 2 && ptr != NULL) {
-+                pp = (char **)ptr;
-+                *pp = data->cache_peer_name;
-+            } else if (num == 3 && ptr != NULL) {
-+                pp = (char **)ptr;
-+                *pp = data->cache_peer_serv;
-+            } else if (num == 4) {
-+                switch (BIO_ADDRINFO_family(data->addr_iter)) {
-+#ifdef AF_INET6
-+                case AF_INET6:
-+                    ret = BIO_FAMILY_IPV6;
-+                    break;
-+#endif
-+                case AF_INET:
-+                    ret = BIO_FAMILY_IPV4;
-+                    break;
-+                case 0:
-+                    ret = data->accept_family;
-+                    break;
-+                default:
-+                    ret = -1;
-+                    break;
-+                }
-+            } else
-+                ret = -1;
-+        } else
-+            ret = -1;
-+        break;
-+    case BIO_CTRL_GET_CLOSE:
-+        ret = b->shutdown;
-+        break;
-+    case BIO_CTRL_SET_CLOSE:
-+        b->shutdown = (int)num;
-+        break;
-+    case BIO_CTRL_PENDING:
-+    case BIO_CTRL_WPENDING:
-+        ret = 0;
-+        break;
-+    case BIO_CTRL_FLUSH:
-+        break;
-+    case BIO_C_SET_BIND_MODE:
-+        data->bind_mode = (int)num;
-+        break;
-+    case BIO_C_GET_BIND_MODE:
-+        ret = (long)data->bind_mode;
-+        break;
-+    case BIO_CTRL_DUP:
-+/*-     dbio=(BIO *)ptr;
-+        if (data->param_port) EAY EAY
-+                BIO_set_port(dbio,data->param_port);
-+        if (data->param_hostname)
-+                BIO_set_hostname(dbio,data->param_hostname);
-+        BIO_set_nbio(dbio,data->nbio); */
-+        break;
-+
-+    default:
-+        ret = 0;
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int acpt_puts(BIO *bp, const char *str)
-+{
-+    int n, ret;
-+
-+    n = strlen(str);
-+    ret = acpt_write(bp, str, n);
-+    return (ret);
-+}
-+
-+BIO *BIO_new_accept(const char *str)
-+{
-+    BIO *ret;
-+
-+    ret = BIO_new(BIO_s_accept());
-+    if (ret == NULL)
-+        return (NULL);
-+    if (BIO_set_accept_name(ret, str))
-+        return (ret);
-+    BIO_free(ret);
-+    return (NULL);
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_bio.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_bio.c
-new file mode 100644
-index 0000000..de34f6b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_bio.c
-@@ -0,0 +1,805 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Special method for a BIO where the other endpoint is also a BIO of this
-+ * kind, handled by the same thread (i.e. the "peer" is actually ourselves,
-+ * wearing a different hat). Such "BIO pairs" are mainly for using the SSL
-+ * library with I/O interfaces for which no specific BIO method is available.
-+ * See ssl/ssltest.c for some hints on how this can be used.
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include "bio_lcl.h"
-+#include 
-+#include 
-+
-+#include "e_os.h"
-+
-+static int bio_new(BIO *bio);
-+static int bio_free(BIO *bio);
-+static int bio_read(BIO *bio, char *buf, int size);
-+static int bio_write(BIO *bio, const char *buf, int num);
-+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
-+static int bio_puts(BIO *bio, const char *str);
-+
-+static int bio_make_pair(BIO *bio1, BIO *bio2);
-+static void bio_destroy_pair(BIO *bio);
-+
-+static const BIO_METHOD methods_biop = {
-+    BIO_TYPE_BIO,
-+    "BIO pair",
-+    bio_write,
-+    bio_read,
-+    bio_puts,
-+    NULL /* no bio_gets */ ,
-+    bio_ctrl,
-+    bio_new,
-+    bio_free,
-+    NULL                        /* no bio_callback_ctrl */
-+};
-+
-+const BIO_METHOD *BIO_s_bio(void)
-+{
-+    return &methods_biop;
-+}
-+
-+struct bio_bio_st {
-+    BIO *peer;                  /* NULL if buf == NULL. If peer != NULL, then
-+                                 * peer->ptr is also a bio_bio_st, and its
-+                                 * "peer" member points back to us. peer !=
-+                                 * NULL iff init != 0 in the BIO. */
-+    /* This is for what we write (i.e. reading uses peer's struct): */
-+    int closed;                 /* valid iff peer != NULL */
-+    size_t len;                 /* valid iff buf != NULL; 0 if peer == NULL */
-+    size_t offset;              /* valid iff buf != NULL; 0 if len == 0 */
-+    size_t size;
-+    char *buf;                  /* "size" elements (if != NULL) */
-+    size_t request;             /* valid iff peer != NULL; 0 if len != 0,
-+                                 * otherwise set by peer to number of bytes
-+                                 * it (unsuccessfully) tried to read, never
-+                                 * more than buffer space (size-len)
-+                                 * warrants. */
-+};
-+
-+static int bio_new(BIO *bio)
-+{
-+    struct bio_bio_st *b = OPENSSL_zalloc(sizeof(*b));
-+
-+    if (b == NULL)
-+        return 0;
-+
-+    /* enough for one TLS record (just a default) */
-+    b->size = 17 * 1024;
-+
-+    bio->ptr = b;
-+    return 1;
-+}
-+
-+static int bio_free(BIO *bio)
-+{
-+    struct bio_bio_st *b;
-+
-+    if (bio == NULL)
-+        return 0;
-+    b = bio->ptr;
-+
-+    assert(b != NULL);
-+
-+    if (b->peer)
-+        bio_destroy_pair(bio);
-+
-+    OPENSSL_free(b->buf);
-+    OPENSSL_free(b);
-+
-+    return 1;
-+}
-+
-+static int bio_read(BIO *bio, char *buf, int size_)
-+{
-+    size_t size = size_;
-+    size_t rest;
-+    struct bio_bio_st *b, *peer_b;
-+
-+    BIO_clear_retry_flags(bio);
-+
-+    if (!bio->init)
-+        return 0;
-+
-+    b = bio->ptr;
-+    assert(b != NULL);
-+    assert(b->peer != NULL);
-+    peer_b = b->peer->ptr;
-+    assert(peer_b != NULL);
-+    assert(peer_b->buf != NULL);
-+
-+    peer_b->request = 0;        /* will be set in "retry_read" situation */
-+
-+    if (buf == NULL || size == 0)
-+        return 0;
-+
-+    if (peer_b->len == 0) {
-+        if (peer_b->closed)
-+            return 0;           /* writer has closed, and no data is left */
-+        else {
-+            BIO_set_retry_read(bio); /* buffer is empty */
-+            if (size <= peer_b->size)
-+                peer_b->request = size;
-+            else
-+                /*
-+                 * don't ask for more than the peer can deliver in one write
-+                 */
-+                peer_b->request = peer_b->size;
-+            return -1;
-+        }
-+    }
-+
-+    /* we can read */
-+    if (peer_b->len < size)
-+        size = peer_b->len;
-+
-+    /* now read "size" bytes */
-+
-+    rest = size;
-+
-+    assert(rest > 0);
-+    do {                        /* one or two iterations */
-+        size_t chunk;
-+
-+        assert(rest <= peer_b->len);
-+        if (peer_b->offset + rest <= peer_b->size)
-+            chunk = rest;
-+        else
-+            /* wrap around ring buffer */
-+            chunk = peer_b->size - peer_b->offset;
-+        assert(peer_b->offset + chunk <= peer_b->size);
-+
-+        memcpy(buf, peer_b->buf + peer_b->offset, chunk);
-+
-+        peer_b->len -= chunk;
-+        if (peer_b->len) {
-+            peer_b->offset += chunk;
-+            assert(peer_b->offset <= peer_b->size);
-+            if (peer_b->offset == peer_b->size)
-+                peer_b->offset = 0;
-+            buf += chunk;
-+        } else {
-+            /* buffer now empty, no need to advance "buf" */
-+            assert(chunk == rest);
-+            peer_b->offset = 0;
-+        }
-+        rest -= chunk;
-+    }
-+    while (rest);
-+
-+    return size;
-+}
-+
-+/*-
-+ * non-copying interface: provide pointer to available data in buffer
-+ *    bio_nread0:  return number of available bytes
-+ *    bio_nread:   also advance index
-+ * (example usage:  bio_nread0(), read from buffer, bio_nread()
-+ *  or just         bio_nread(), read from buffer)
-+ */
-+/*
-+ * WARNING: The non-copying interface is largely untested as of yet and may
-+ * contain bugs.
-+ */
-+static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
-+{
-+    struct bio_bio_st *b, *peer_b;
-+    ossl_ssize_t num;
-+
-+    BIO_clear_retry_flags(bio);
-+
-+    if (!bio->init)
-+        return 0;
-+
-+    b = bio->ptr;
-+    assert(b != NULL);
-+    assert(b->peer != NULL);
-+    peer_b = b->peer->ptr;
-+    assert(peer_b != NULL);
-+    assert(peer_b->buf != NULL);
-+
-+    peer_b->request = 0;
-+
-+    if (peer_b->len == 0) {
-+        char dummy;
-+
-+        /* avoid code duplication -- nothing available for reading */
-+        return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
-+    }
-+
-+    num = peer_b->len;
-+    if (peer_b->size < peer_b->offset + num)
-+        /* no ring buffer wrap-around for non-copying interface */
-+        num = peer_b->size - peer_b->offset;
-+    assert(num > 0);
-+
-+    if (buf != NULL)
-+        *buf = peer_b->buf + peer_b->offset;
-+    return num;
-+}
-+
-+static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
-+{
-+    struct bio_bio_st *b, *peer_b;
-+    ossl_ssize_t num, available;
-+
-+    if (num_ > OSSL_SSIZE_MAX)
-+        num = OSSL_SSIZE_MAX;
-+    else
-+        num = (ossl_ssize_t) num_;
-+
-+    available = bio_nread0(bio, buf);
-+    if (num > available)
-+        num = available;
-+    if (num <= 0)
-+        return num;
-+
-+    b = bio->ptr;
-+    peer_b = b->peer->ptr;
-+
-+    peer_b->len -= num;
-+    if (peer_b->len) {
-+        peer_b->offset += num;
-+        assert(peer_b->offset <= peer_b->size);
-+        if (peer_b->offset == peer_b->size)
-+            peer_b->offset = 0;
-+    } else
-+        peer_b->offset = 0;
-+
-+    return num;
-+}
-+
-+static int bio_write(BIO *bio, const char *buf, int num_)
-+{
-+    size_t num = num_;
-+    size_t rest;
-+    struct bio_bio_st *b;
-+
-+    BIO_clear_retry_flags(bio);
-+
-+    if (!bio->init || buf == NULL || num == 0)
-+        return 0;
-+
-+    b = bio->ptr;
-+    assert(b != NULL);
-+    assert(b->peer != NULL);
-+    assert(b->buf != NULL);
-+
-+    b->request = 0;
-+    if (b->closed) {
-+        /* we already closed */
-+        BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
-+        return -1;
-+    }
-+
-+    assert(b->len <= b->size);
-+
-+    if (b->len == b->size) {
-+        BIO_set_retry_write(bio); /* buffer is full */
-+        return -1;
-+    }
-+
-+    /* we can write */
-+    if (num > b->size - b->len)
-+        num = b->size - b->len;
-+
-+    /* now write "num" bytes */
-+
-+    rest = num;
-+
-+    assert(rest > 0);
-+    do {                        /* one or two iterations */
-+        size_t write_offset;
-+        size_t chunk;
-+
-+        assert(b->len + rest <= b->size);
-+
-+        write_offset = b->offset + b->len;
-+        if (write_offset >= b->size)
-+            write_offset -= b->size;
-+        /* b->buf[write_offset] is the first byte we can write to. */
-+
-+        if (write_offset + rest <= b->size)
-+            chunk = rest;
-+        else
-+            /* wrap around ring buffer */
-+            chunk = b->size - write_offset;
-+
-+        memcpy(b->buf + write_offset, buf, chunk);
-+
-+        b->len += chunk;
-+
-+        assert(b->len <= b->size);
-+
-+        rest -= chunk;
-+        buf += chunk;
-+    }
-+    while (rest);
-+
-+    return num;
-+}
-+
-+/*-
-+ * non-copying interface: provide pointer to region to write to
-+ *   bio_nwrite0:  check how much space is available
-+ *   bio_nwrite:   also increase length
-+ * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
-+ *  or just         bio_nwrite(), write to buffer)
-+ */
-+static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
-+{
-+    struct bio_bio_st *b;
-+    size_t num;
-+    size_t write_offset;
-+
-+    BIO_clear_retry_flags(bio);
-+
-+    if (!bio->init)
-+        return 0;
-+
-+    b = bio->ptr;
-+    assert(b != NULL);
-+    assert(b->peer != NULL);
-+    assert(b->buf != NULL);
-+
-+    b->request = 0;
-+    if (b->closed) {
-+        BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
-+        return -1;
-+    }
-+
-+    assert(b->len <= b->size);
-+
-+    if (b->len == b->size) {
-+        BIO_set_retry_write(bio);
-+        return -1;
-+    }
-+
-+    num = b->size - b->len;
-+    write_offset = b->offset + b->len;
-+    if (write_offset >= b->size)
-+        write_offset -= b->size;
-+    if (write_offset + num > b->size)
-+        /*
-+         * no ring buffer wrap-around for non-copying interface (to fulfil
-+         * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have
-+         * to be called twice)
-+         */
-+        num = b->size - write_offset;
-+
-+    if (buf != NULL)
-+        *buf = b->buf + write_offset;
-+    assert(write_offset + num <= b->size);
-+
-+    return num;
-+}
-+
-+static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
-+{
-+    struct bio_bio_st *b;
-+    ossl_ssize_t num, space;
-+
-+    if (num_ > OSSL_SSIZE_MAX)
-+        num = OSSL_SSIZE_MAX;
-+    else
-+        num = (ossl_ssize_t) num_;
-+
-+    space = bio_nwrite0(bio, buf);
-+    if (num > space)
-+        num = space;
-+    if (num <= 0)
-+        return num;
-+    b = bio->ptr;
-+    assert(b != NULL);
-+    b->len += num;
-+    assert(b->len <= b->size);
-+
-+    return num;
-+}
-+
-+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
-+{
-+    long ret;
-+    struct bio_bio_st *b = bio->ptr;
-+
-+    assert(b != NULL);
-+
-+    switch (cmd) {
-+        /* specific CTRL codes */
-+
-+    case BIO_C_SET_WRITE_BUF_SIZE:
-+        if (b->peer) {
-+            BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
-+            ret = 0;
-+        } else if (num == 0) {
-+            BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
-+            ret = 0;
-+        } else {
-+            size_t new_size = num;
-+
-+            if (b->size != new_size) {
-+                OPENSSL_free(b->buf);
-+                b->buf = NULL;
-+                b->size = new_size;
-+            }
-+            ret = 1;
-+        }
-+        break;
-+
-+    case BIO_C_GET_WRITE_BUF_SIZE:
-+        ret = (long)b->size;
-+        break;
-+
-+    case BIO_C_MAKE_BIO_PAIR:
-+        {
-+            BIO *other_bio = ptr;
-+
-+            if (bio_make_pair(bio, other_bio))
-+                ret = 1;
-+            else
-+                ret = 0;
-+        }
-+        break;
-+
-+    case BIO_C_DESTROY_BIO_PAIR:
-+        /*
-+         * Affects both BIOs in the pair -- call just once! Or let
-+         * BIO_free(bio1); BIO_free(bio2); do the job.
-+         */
-+        bio_destroy_pair(bio);
-+        ret = 1;
-+        break;
-+
-+    case BIO_C_GET_WRITE_GUARANTEE:
-+        /*
-+         * How many bytes can the caller feed to the next write without
-+         * having to keep any?
-+         */
-+        if (b->peer == NULL || b->closed)
-+            ret = 0;
-+        else
-+            ret = (long)b->size - b->len;
-+        break;
-+
-+    case BIO_C_GET_READ_REQUEST:
-+        /*
-+         * If the peer unsuccessfully tried to read, how many bytes were
-+         * requested? (As with BIO_CTRL_PENDING, that number can usually be
-+         * treated as boolean.)
-+         */
-+        ret = (long)b->request;
-+        break;
-+
-+    case BIO_C_RESET_READ_REQUEST:
-+        /*
-+         * Reset request.  (Can be useful after read attempts at the other
-+         * side that are meant to be non-blocking, e.g. when probing SSL_read
-+         * to see if any data is available.)
-+         */
-+        b->request = 0;
-+        ret = 1;
-+        break;
-+
-+    case BIO_C_SHUTDOWN_WR:
-+        /* similar to shutdown(..., SHUT_WR) */
-+        b->closed = 1;
-+        ret = 1;
-+        break;
-+
-+    case BIO_C_NREAD0:
-+        /* prepare for non-copying read */
-+        ret = (long)bio_nread0(bio, ptr);
-+        break;
-+
-+    case BIO_C_NREAD:
-+        /* non-copying read */
-+        ret = (long)bio_nread(bio, ptr, (size_t)num);
-+        break;
-+
-+    case BIO_C_NWRITE0:
-+        /* prepare for non-copying write */
-+        ret = (long)bio_nwrite0(bio, ptr);
-+        break;
-+
-+    case BIO_C_NWRITE:
-+        /* non-copying write */
-+        ret = (long)bio_nwrite(bio, ptr, (size_t)num);
-+        break;
-+
-+        /* standard CTRL codes follow */
-+
-+    case BIO_CTRL_RESET:
-+        if (b->buf != NULL) {
-+            b->len = 0;
-+            b->offset = 0;
-+        }
-+        ret = 0;
-+        break;
-+
-+    case BIO_CTRL_GET_CLOSE:
-+        ret = bio->shutdown;
-+        break;
-+
-+    case BIO_CTRL_SET_CLOSE:
-+        bio->shutdown = (int)num;
-+        ret = 1;
-+        break;
-+
-+    case BIO_CTRL_PENDING:
-+        if (b->peer != NULL) {
-+            struct bio_bio_st *peer_b = b->peer->ptr;
-+
-+            ret = (long)peer_b->len;
-+        } else
-+            ret = 0;
-+        break;
-+
-+    case BIO_CTRL_WPENDING:
-+        if (b->buf != NULL)
-+            ret = (long)b->len;
-+        else
-+            ret = 0;
-+        break;
-+
-+    case BIO_CTRL_DUP:
-+        /* See BIO_dup_chain for circumstances we have to expect. */
-+        {
-+            BIO *other_bio = ptr;
-+            struct bio_bio_st *other_b;
-+
-+            assert(other_bio != NULL);
-+            other_b = other_bio->ptr;
-+            assert(other_b != NULL);
-+
-+            assert(other_b->buf == NULL); /* other_bio is always fresh */
-+
-+            other_b->size = b->size;
-+        }
-+
-+        ret = 1;
-+        break;
-+
-+    case BIO_CTRL_FLUSH:
-+        ret = 1;
-+        break;
-+
-+    case BIO_CTRL_EOF:
-+        if (b->peer != NULL) {
-+            struct bio_bio_st *peer_b = b->peer->ptr;
-+
-+            if (peer_b->len == 0 && peer_b->closed)
-+                ret = 1;
-+            else
-+                ret = 0;
-+        } else {
-+            ret = 1;
-+        }
-+        break;
-+
-+    default:
-+        ret = 0;
-+    }
-+    return ret;
-+}
-+
-+static int bio_puts(BIO *bio, const char *str)
-+{
-+    return bio_write(bio, str, strlen(str));
-+}
-+
-+static int bio_make_pair(BIO *bio1, BIO *bio2)
-+{
-+    struct bio_bio_st *b1, *b2;
-+
-+    assert(bio1 != NULL);
-+    assert(bio2 != NULL);
-+
-+    b1 = bio1->ptr;
-+    b2 = bio2->ptr;
-+
-+    if (b1->peer != NULL || b2->peer != NULL) {
-+        BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
-+        return 0;
-+    }
-+
-+    if (b1->buf == NULL) {
-+        b1->buf = OPENSSL_malloc(b1->size);
-+        if (b1->buf == NULL) {
-+            BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        b1->len = 0;
-+        b1->offset = 0;
-+    }
-+
-+    if (b2->buf == NULL) {
-+        b2->buf = OPENSSL_malloc(b2->size);
-+        if (b2->buf == NULL) {
-+            BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        b2->len = 0;
-+        b2->offset = 0;
-+    }
-+
-+    b1->peer = bio2;
-+    b1->closed = 0;
-+    b1->request = 0;
-+    b2->peer = bio1;
-+    b2->closed = 0;
-+    b2->request = 0;
-+
-+    bio1->init = 1;
-+    bio2->init = 1;
-+
-+    return 1;
-+}
-+
-+static void bio_destroy_pair(BIO *bio)
-+{
-+    struct bio_bio_st *b = bio->ptr;
-+
-+    if (b != NULL) {
-+        BIO *peer_bio = b->peer;
-+
-+        if (peer_bio != NULL) {
-+            struct bio_bio_st *peer_b = peer_bio->ptr;
-+
-+            assert(peer_b != NULL);
-+            assert(peer_b->peer == bio);
-+
-+            peer_b->peer = NULL;
-+            peer_bio->init = 0;
-+            assert(peer_b->buf != NULL);
-+            peer_b->len = 0;
-+            peer_b->offset = 0;
-+
-+            b->peer = NULL;
-+            bio->init = 0;
-+            assert(b->buf != NULL);
-+            b->len = 0;
-+            b->offset = 0;
-+        }
-+    }
-+}
-+
-+/* Exported convenience functions */
-+int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
-+                     BIO **bio2_p, size_t writebuf2)
-+{
-+    BIO *bio1 = NULL, *bio2 = NULL;
-+    long r;
-+    int ret = 0;
-+
-+    bio1 = BIO_new(BIO_s_bio());
-+    if (bio1 == NULL)
-+        goto err;
-+    bio2 = BIO_new(BIO_s_bio());
-+    if (bio2 == NULL)
-+        goto err;
-+
-+    if (writebuf1) {
-+        r = BIO_set_write_buf_size(bio1, writebuf1);
-+        if (!r)
-+            goto err;
-+    }
-+    if (writebuf2) {
-+        r = BIO_set_write_buf_size(bio2, writebuf2);
-+        if (!r)
-+            goto err;
-+    }
-+
-+    r = BIO_make_bio_pair(bio1, bio2);
-+    if (!r)
-+        goto err;
-+    ret = 1;
-+
-+ err:
-+    if (ret == 0) {
-+        BIO_free(bio1);
-+        bio1 = NULL;
-+        BIO_free(bio2);
-+        bio2 = NULL;
-+    }
-+
-+    *bio1_p = bio1;
-+    *bio2_p = bio2;
-+    return ret;
-+}
-+
-+size_t BIO_ctrl_get_write_guarantee(BIO *bio)
-+{
-+    return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
-+}
-+
-+size_t BIO_ctrl_get_read_request(BIO *bio)
-+{
-+    return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
-+}
-+
-+int BIO_ctrl_reset_read_request(BIO *bio)
-+{
-+    return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
-+}
-+
-+/*
-+ * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
-+ * (conceivably some other BIOs could allow non-copying reads and writes
-+ * too.)
-+ */
-+int BIO_nread0(BIO *bio, char **buf)
-+{
-+    long ret;
-+
-+    if (!bio->init) {
-+        BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
-+        return -2;
-+    }
-+
-+    ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
-+    if (ret > INT_MAX)
-+        return INT_MAX;
-+    else
-+        return (int)ret;
-+}
-+
-+int BIO_nread(BIO *bio, char **buf, int num)
-+{
-+    int ret;
-+
-+    if (!bio->init) {
-+        BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
-+        return -2;
-+    }
-+
-+    ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf);
-+    if (ret > 0)
-+        bio->num_read += ret;
-+    return ret;
-+}
-+
-+int BIO_nwrite0(BIO *bio, char **buf)
-+{
-+    long ret;
-+
-+    if (!bio->init) {
-+        BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
-+        return -2;
-+    }
-+
-+    ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
-+    if (ret > INT_MAX)
-+        return INT_MAX;
-+    else
-+        return (int)ret;
-+}
-+
-+int BIO_nwrite(BIO *bio, char **buf, int num)
-+{
-+    int ret;
-+
-+    if (!bio->init) {
-+        BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
-+        return -2;
-+    }
-+
-+    ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
-+    if (ret > 0)
-+        bio->num_write += ret;
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_conn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_conn.c
-new file mode 100644
-index 0000000..dfd0988
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_conn.c
-@@ -0,0 +1,545 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+#include "bio_lcl.h"
-+
-+#ifndef OPENSSL_NO_SOCK
-+
-+typedef struct bio_connect_st {
-+    int state;
-+    int connect_family;
-+    char *param_hostname;
-+    char *param_service;
-+    int connect_mode;
-+
-+    BIO_ADDRINFO *addr_first;
-+    const BIO_ADDRINFO *addr_iter;
-+    /*
-+     * int socket; this will be kept in bio->num so that it is compatible
-+     * with the bss_sock bio
-+     */
-+    /*
-+     * called when the connection is initially made callback(BIO,state,ret);
-+     * The callback should return 'ret'.  state is for compatibility with the
-+     * ssl info_callback
-+     */
-+    int (*info_callback) (const BIO *bio, int state, int ret);
-+} BIO_CONNECT;
-+
-+static int conn_write(BIO *h, const char *buf, int num);
-+static int conn_read(BIO *h, char *buf, int size);
-+static int conn_puts(BIO *h, const char *str);
-+static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int conn_new(BIO *h);
-+static int conn_free(BIO *data);
-+static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *);
-+
-+static int conn_state(BIO *b, BIO_CONNECT *c);
-+static void conn_close_socket(BIO *data);
-+BIO_CONNECT *BIO_CONNECT_new(void);
-+void BIO_CONNECT_free(BIO_CONNECT *a);
-+
-+#define BIO_CONN_S_BEFORE                1
-+#define BIO_CONN_S_GET_ADDR              2
-+#define BIO_CONN_S_CREATE_SOCKET         3
-+#define BIO_CONN_S_CONNECT               4
-+#define BIO_CONN_S_OK                    5
-+#define BIO_CONN_S_BLOCKED_CONNECT       6
-+
-+static const BIO_METHOD methods_connectp = {
-+    BIO_TYPE_CONNECT,
-+    "socket connect",
-+    conn_write,
-+    conn_read,
-+    conn_puts,
-+    NULL,                       /* connect_gets, */
-+    conn_ctrl,
-+    conn_new,
-+    conn_free,
-+    conn_callback_ctrl,
-+};
-+
-+static int conn_state(BIO *b, BIO_CONNECT *c)
-+{
-+    int ret = -1, i;
-+    int (*cb) (const BIO *, int, int) = NULL;
-+
-+    if (c->info_callback != NULL)
-+        cb = c->info_callback;
-+
-+    for (;;) {
-+        switch (c->state) {
-+        case BIO_CONN_S_BEFORE:
-+            if (c->param_hostname == NULL && c->param_service == NULL) {
-+                BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED);
-+                ERR_add_error_data(4,
-+                                   "hostname=", c->param_hostname,
-+                                   " service=", c->param_service);
-+                goto exit_loop;
-+            }
-+            c->state = BIO_CONN_S_GET_ADDR;
-+            break;
-+
-+        case BIO_CONN_S_GET_ADDR:
-+            {
-+                int family = AF_UNSPEC;
-+                switch (c->connect_family) {
-+                case BIO_FAMILY_IPV6:
-+                    if (1) { /* This is a trick we use to avoid bit rot.
-+                              * at least the "else" part will always be
-+                              * compiled.
-+                              */
-+#ifdef AF_INET6
-+                        family = AF_INET6;
-+                    } else {
-+#endif
-+                        BIOerr(BIO_F_CONN_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
-+                        goto exit_loop;
-+                    }
-+                    break;
-+                case BIO_FAMILY_IPV4:
-+                    family = AF_INET;
-+                    break;
-+                case BIO_FAMILY_IPANY:
-+                    family = AF_UNSPEC;
-+                    break;
-+                default:
-+                    BIOerr(BIO_F_CONN_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
-+                    goto exit_loop;
-+                }
-+                if (BIO_lookup(c->param_hostname, c->param_service,
-+                               BIO_LOOKUP_CLIENT,
-+                               family, SOCK_STREAM, &c->addr_first) == 0)
-+                    goto exit_loop;
-+            }
-+            if (c->addr_first == NULL) {
-+                BIOerr(BIO_F_CONN_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
-+                goto exit_loop;
-+            }
-+            c->addr_iter = c->addr_first;
-+            c->state = BIO_CONN_S_CREATE_SOCKET;
-+            break;
-+
-+        case BIO_CONN_S_CREATE_SOCKET:
-+            ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
-+                             BIO_ADDRINFO_socktype(c->addr_iter),
-+                             BIO_ADDRINFO_protocol(c->addr_iter), 0);
-+            if (ret == (int)INVALID_SOCKET) {
-+                SYSerr(SYS_F_SOCKET, get_last_socket_error());
-+                ERR_add_error_data(4,
-+                                   "hostname=", c->param_hostname,
-+                                   " service=", c->param_service);
-+                BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
-+                goto exit_loop;
-+            }
-+            b->num = ret;
-+            c->state = BIO_CONN_S_CONNECT;
-+            break;
-+
-+        case BIO_CONN_S_CONNECT:
-+            BIO_clear_retry_flags(b);
-+            ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter),
-+                              BIO_SOCK_KEEPALIVE | c->connect_mode);
-+            b->retry_reason = 0;
-+            if (ret == 0) {
-+                if (BIO_sock_should_retry(ret)) {
-+                    BIO_set_retry_special(b);
-+                    c->state = BIO_CONN_S_BLOCKED_CONNECT;
-+                    b->retry_reason = BIO_RR_CONNECT;
-+                    ERR_clear_error();
-+                } else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter))
-+                           != NULL) {
-+                    /*
-+                     * if there are more addresses to try, do that first
-+                     */
-+                    BIO_closesocket(b->num);
-+                    c->state = BIO_CONN_S_CREATE_SOCKET;
-+                    ERR_clear_error();
-+                    break;
-+                } else {
-+                    SYSerr(SYS_F_CONNECT, get_last_socket_error());
-+                    ERR_add_error_data(4,
-+                                       "hostname=", c->param_hostname,
-+                                       " service=", c->param_service);
-+                    BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR);
-+                }
-+                goto exit_loop;
-+            } else {
-+                c->state = BIO_CONN_S_OK;
-+            }
-+            break;
-+
-+        case BIO_CONN_S_BLOCKED_CONNECT:
-+            i = BIO_sock_error(b->num);
-+            if (i) {
-+                BIO_clear_retry_flags(b);
-+                SYSerr(SYS_F_CONNECT, i);
-+                ERR_add_error_data(4,
-+                                   "hostname=", c->param_hostname,
-+                                   " service=", c->param_service);
-+                BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR);
-+                ret = 0;
-+                goto exit_loop;
-+            } else
-+                c->state = BIO_CONN_S_OK;
-+            break;
-+
-+        case BIO_CONN_S_OK:
-+            ret = 1;
-+            goto exit_loop;
-+        default:
-+            /* abort(); */
-+            goto exit_loop;
-+        }
-+
-+        if (cb != NULL) {
-+            if ((ret = cb((BIO *)b, c->state, ret)) == 0)
-+                goto end;
-+        }
-+    }
-+
-+    /* Loop does not exit */
-+ exit_loop:
-+    if (cb != NULL)
-+        ret = cb((BIO *)b, c->state, ret);
-+ end:
-+    return (ret);
-+}
-+
-+BIO_CONNECT *BIO_CONNECT_new(void)
-+{
-+    BIO_CONNECT *ret;
-+
-+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
-+        return (NULL);
-+    ret->state = BIO_CONN_S_BEFORE;
-+    ret->connect_family = BIO_FAMILY_IPANY;
-+    return (ret);
-+}
-+
-+void BIO_CONNECT_free(BIO_CONNECT *a)
-+{
-+    if (a == NULL)
-+        return;
-+
-+    OPENSSL_free(a->param_hostname);
-+    OPENSSL_free(a->param_service);
-+    BIO_ADDRINFO_free(a->addr_first);
-+    OPENSSL_free(a);
-+}
-+
-+const BIO_METHOD *BIO_s_connect(void)
-+{
-+    return (&methods_connectp);
-+}
-+
-+static int conn_new(BIO *bi)
-+{
-+    bi->init = 0;
-+    bi->num = (int)INVALID_SOCKET;
-+    bi->flags = 0;
-+    if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL)
-+        return (0);
-+    else
-+        return (1);
-+}
-+
-+static void conn_close_socket(BIO *bio)
-+{
-+    BIO_CONNECT *c;
-+
-+    c = (BIO_CONNECT *)bio->ptr;
-+    if (bio->num != (int)INVALID_SOCKET) {
-+        /* Only do a shutdown if things were established */
-+        if (c->state == BIO_CONN_S_OK)
-+            shutdown(bio->num, 2);
-+        BIO_closesocket(bio->num);
-+        bio->num = (int)INVALID_SOCKET;
-+    }
-+}
-+
-+static int conn_free(BIO *a)
-+{
-+    BIO_CONNECT *data;
-+
-+    if (a == NULL)
-+        return (0);
-+    data = (BIO_CONNECT *)a->ptr;
-+
-+    if (a->shutdown) {
-+        conn_close_socket(a);
-+        BIO_CONNECT_free(data);
-+        a->ptr = NULL;
-+        a->flags = 0;
-+        a->init = 0;
-+    }
-+    return (1);
-+}
-+
-+static int conn_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0;
-+    BIO_CONNECT *data;
-+
-+    data = (BIO_CONNECT *)b->ptr;
-+    if (data->state != BIO_CONN_S_OK) {
-+        ret = conn_state(b, data);
-+        if (ret <= 0)
-+            return (ret);
-+    }
-+
-+    if (out != NULL) {
-+        clear_socket_error();
-+        ret = readsocket(b->num, out, outl);
-+        BIO_clear_retry_flags(b);
-+        if (ret <= 0) {
-+            if (BIO_sock_should_retry(ret))
-+                BIO_set_retry_read(b);
-+        }
-+    }
-+    return (ret);
-+}
-+
-+static int conn_write(BIO *b, const char *in, int inl)
-+{
-+    int ret;
-+    BIO_CONNECT *data;
-+
-+    data = (BIO_CONNECT *)b->ptr;
-+    if (data->state != BIO_CONN_S_OK) {
-+        ret = conn_state(b, data);
-+        if (ret <= 0)
-+            return (ret);
-+    }
-+
-+    clear_socket_error();
-+    ret = writesocket(b->num, in, inl);
-+    BIO_clear_retry_flags(b);
-+    if (ret <= 0) {
-+        if (BIO_sock_should_retry(ret))
-+            BIO_set_retry_write(b);
-+    }
-+    return (ret);
-+}
-+
-+static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    BIO *dbio;
-+    int *ip;
-+    const char **pptr = NULL;
-+    long ret = 1;
-+    BIO_CONNECT *data;
-+
-+    data = (BIO_CONNECT *)b->ptr;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        ret = 0;
-+        data->state = BIO_CONN_S_BEFORE;
-+        conn_close_socket(b);
-+        BIO_ADDRINFO_free(data->addr_first);
-+        data->addr_first = NULL;
-+        b->flags = 0;
-+        break;
-+    case BIO_C_DO_STATE_MACHINE:
-+        /* use this one to start the connection */
-+        if (data->state != BIO_CONN_S_OK)
-+            ret = (long)conn_state(b, data);
-+        else
-+            ret = 1;
-+        break;
-+    case BIO_C_GET_CONNECT:
-+        if (ptr != NULL) {
-+            pptr = (const char **)ptr;
-+            if (num == 0) {
-+                *pptr = data->param_hostname;
-+            } else if (num == 1) {
-+                *pptr = data->param_service;
-+            } else if (num == 2) {
-+                *pptr = (const char *)BIO_ADDRINFO_address(data->addr_iter);
-+            } else if (num == 3) {
-+                switch (BIO_ADDRINFO_family(data->addr_iter)) {
-+# ifdef AF_INET6
-+                case AF_INET6:
-+                    ret = BIO_FAMILY_IPV6;
-+                    break;
-+# endif
-+                case AF_INET:
-+                    ret = BIO_FAMILY_IPV4;
-+                    break;
-+                case 0:
-+                    ret = data->connect_family;
-+                    break;
-+                default:
-+                    ret = -1;
-+                    break;
-+                }
-+            } else {
-+                ret = 0;
-+            }
-+        } else {
-+            ret = 0;
-+        }
-+        break;
-+    case BIO_C_SET_CONNECT:
-+        if (ptr != NULL) {
-+            b->init = 1;
-+            if (num == 0) {
-+                char *hold_service = data->param_service;
-+                /* We affect the hostname regardless.  However, the input
-+                 * string might contain a host:service spec, so we must
-+                 * parse it, which might or might not affect the service
-+                 */
-+                OPENSSL_free(data->param_hostname);
-+                data->param_hostname = NULL;
-+                ret = BIO_parse_hostserv(ptr,
-+                                         &data->param_hostname,
-+                                         &data->param_service,
-+                                         BIO_PARSE_PRIO_HOST);
-+                if (hold_service != data->param_service)
-+                    OPENSSL_free(hold_service);
-+            } else if (num == 1) {
-+                OPENSSL_free(data->param_service);
-+                data->param_service = BUF_strdup(ptr);
-+            } else if (num == 2) {
-+                const BIO_ADDR *addr = (const BIO_ADDR *)ptr;
-+                if (ret) {
-+                    data->param_hostname = BIO_ADDR_hostname_string(addr, 1);
-+                    data->param_service = BIO_ADDR_service_string(addr, 1);
-+                    BIO_ADDRINFO_free(data->addr_first);
-+                    data->addr_first = NULL;
-+                    data->addr_iter = NULL;
-+                }
-+            } else if (num == 3) {
-+                data->connect_family = *(int *)ptr;
-+            } else {
-+                ret = 0;
-+            }
-+        }
-+        break;
-+    case BIO_C_SET_NBIO:
-+        if (num != 0)
-+            data->connect_mode |= BIO_SOCK_NONBLOCK;
-+        else
-+            data->connect_mode &= ~BIO_SOCK_NONBLOCK;
-+        break;
-+    case BIO_C_SET_CONNECT_MODE:
-+        data->connect_mode = (int)num;
-+        break;
-+    case BIO_C_GET_FD:
-+        if (b->init) {
-+            ip = (int *)ptr;
-+            if (ip != NULL)
-+                *ip = b->num;
-+            ret = b->num;
-+        } else
-+            ret = -1;
-+        break;
-+    case BIO_CTRL_GET_CLOSE:
-+        ret = b->shutdown;
-+        break;
-+    case BIO_CTRL_SET_CLOSE:
-+        b->shutdown = (int)num;
-+        break;
-+    case BIO_CTRL_PENDING:
-+    case BIO_CTRL_WPENDING:
-+        ret = 0;
-+        break;
-+    case BIO_CTRL_FLUSH:
-+        break;
-+    case BIO_CTRL_DUP:
-+        {
-+            dbio = (BIO *)ptr;
-+            if (data->param_hostname)
-+                BIO_set_conn_hostname(dbio, data->param_hostname);
-+            if (data->param_service)
-+                BIO_set_conn_port(dbio, data->param_service);
-+            BIO_set_conn_ip_family(dbio, data->connect_family);
-+            BIO_set_conn_mode(dbio, data->connect_mode);
-+            /*
-+             * FIXME: the cast of the function seems unlikely to be a good
-+             * idea
-+             */
-+            (void)BIO_set_info_callback(dbio,
-+                                        (bio_info_cb *)data->info_callback);
-+        }
-+        break;
-+    case BIO_CTRL_SET_CALLBACK:
-+        {
-+# if 0                          /* FIXME: Should this be used? -- Richard
-+                                 * Levitte */
-+            BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+            ret = -1;
-+# else
-+            ret = 0;
-+# endif
-+        }
-+        break;
-+    case BIO_CTRL_GET_CALLBACK:
-+        {
-+            int (**fptr) (const BIO *bio, int state, int xret);
-+
-+            fptr = (int (**)(const BIO *bio, int state, int xret))ptr;
-+            *fptr = data->info_callback;
-+        }
-+        break;
-+    default:
-+        ret = 0;
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    long ret = 1;
-+    BIO_CONNECT *data;
-+
-+    data = (BIO_CONNECT *)b->ptr;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_SET_CALLBACK:
-+        {
-+            data->info_callback =
-+                (int (*)(const struct bio_st *, int, int))fp;
-+        }
-+        break;
-+    default:
-+        ret = 0;
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int conn_puts(BIO *bp, const char *str)
-+{
-+    int n, ret;
-+
-+    n = strlen(str);
-+    ret = conn_write(bp, str, n);
-+    return (ret);
-+}
-+
-+BIO *BIO_new_connect(const char *str)
-+{
-+    BIO *ret;
-+
-+    ret = BIO_new(BIO_s_connect());
-+    if (ret == NULL)
-+        return (NULL);
-+    if (BIO_set_conn_hostname(ret, str))
-+        return (ret);
-+    BIO_free(ret);
-+    return (NULL);
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_dgram.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_dgram.c
-new file mode 100644
-index 0000000..6dfcc9b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_dgram.c
-@@ -0,0 +1,1944 @@
-+/*
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+#include "bio_lcl.h"
-+#ifndef OPENSSL_NO_DGRAM
-+
-+# if !(defined(_WIN32) || defined(OPENSSL_SYS_VMS))
-+#  include 
-+# endif
-+# if defined(OPENSSL_SYS_VMS)
-+#  include 
-+# endif
-+
-+# ifndef OPENSSL_NO_SCTP
-+#  include 
-+#  include 
-+#  define OPENSSL_SCTP_DATA_CHUNK_TYPE            0x00
-+#  define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
-+# endif
-+
-+# if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
-+#  define IP_MTU      14        /* linux is lame */
-+# endif
-+
-+# if OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6)
-+#  define IPPROTO_IPV6 41       /* windows is lame */
-+# endif
-+
-+# if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
-+/* Standard definition causes type-punning problems. */
-+#  undef IN6_IS_ADDR_V4MAPPED
-+#  define s6_addr32 __u6_addr.__u6_addr32
-+#  define IN6_IS_ADDR_V4MAPPED(a)               \
-+        (((a)->s6_addr32[0] == 0) &&          \
-+         ((a)->s6_addr32[1] == 0) &&          \
-+         ((a)->s6_addr32[2] == htonl(0x0000ffff)))
-+# endif
-+
-+static int dgram_write(BIO *h, const char *buf, int num);
-+static int dgram_read(BIO *h, char *buf, int size);
-+static int dgram_puts(BIO *h, const char *str);
-+static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int dgram_new(BIO *h);
-+static int dgram_free(BIO *data);
-+static int dgram_clear(BIO *bio);
-+
-+# ifndef OPENSSL_NO_SCTP
-+static int dgram_sctp_write(BIO *h, const char *buf, int num);
-+static int dgram_sctp_read(BIO *h, char *buf, int size);
-+static int dgram_sctp_puts(BIO *h, const char *str);
-+static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int dgram_sctp_new(BIO *h);
-+static int dgram_sctp_free(BIO *data);
-+#  ifdef SCTP_AUTHENTICATION_EVENT
-+static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
-+                                                  *snp);
-+#  endif
-+# endif
-+
-+static int BIO_dgram_should_retry(int s);
-+
-+static void get_current_time(struct timeval *t);
-+
-+static const BIO_METHOD methods_dgramp = {
-+    BIO_TYPE_DGRAM,
-+    "datagram socket",
-+    dgram_write,
-+    dgram_read,
-+    dgram_puts,
-+    NULL,                       /* dgram_gets, */
-+    dgram_ctrl,
-+    dgram_new,
-+    dgram_free,
-+    NULL,
-+};
-+
-+# ifndef OPENSSL_NO_SCTP
-+static const BIO_METHOD methods_dgramp_sctp = {
-+    BIO_TYPE_DGRAM_SCTP,
-+    "datagram sctp socket",
-+    dgram_sctp_write,
-+    dgram_sctp_read,
-+    dgram_sctp_puts,
-+    NULL,                       /* dgram_gets, */
-+    dgram_sctp_ctrl,
-+    dgram_sctp_new,
-+    dgram_sctp_free,
-+    NULL,
-+};
-+# endif
-+
-+typedef struct bio_dgram_data_st {
-+    BIO_ADDR peer;
-+    unsigned int connected;
-+    unsigned int _errno;
-+    unsigned int mtu;
-+    struct timeval next_timeout;
-+    struct timeval socket_timeout;
-+    unsigned int peekmode;
-+} bio_dgram_data;
-+
-+# ifndef OPENSSL_NO_SCTP
-+typedef struct bio_dgram_sctp_save_message_st {
-+    BIO *bio;
-+    char *data;
-+    int length;
-+} bio_dgram_sctp_save_message;
-+
-+typedef struct bio_dgram_sctp_data_st {
-+    BIO_ADDR peer;
-+    unsigned int connected;
-+    unsigned int _errno;
-+    unsigned int mtu;
-+    struct bio_dgram_sctp_sndinfo sndinfo;
-+    struct bio_dgram_sctp_rcvinfo rcvinfo;
-+    struct bio_dgram_sctp_prinfo prinfo;
-+    void (*handle_notifications) (BIO *bio, void *context, void *buf);
-+    void *notification_context;
-+    int in_handshake;
-+    int ccs_rcvd;
-+    int ccs_sent;
-+    int save_shutdown;
-+    int peer_auth_tested;
-+    bio_dgram_sctp_save_message saved_message;
-+} bio_dgram_sctp_data;
-+# endif
-+
-+const BIO_METHOD *BIO_s_datagram(void)
-+{
-+    return (&methods_dgramp);
-+}
-+
-+BIO *BIO_new_dgram(int fd, int close_flag)
-+{
-+    BIO *ret;
-+
-+    ret = BIO_new(BIO_s_datagram());
-+    if (ret == NULL)
-+        return (NULL);
-+    BIO_set_fd(ret, fd, close_flag);
-+    return (ret);
-+}
-+
-+static int dgram_new(BIO *bi)
-+{
-+    bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data));
-+
-+    if (data == NULL)
-+        return 0;
-+    bi->ptr = data;
-+    return (1);
-+}
-+
-+static int dgram_free(BIO *a)
-+{
-+    bio_dgram_data *data;
-+
-+    if (a == NULL)
-+        return (0);
-+    if (!dgram_clear(a))
-+        return 0;
-+
-+    data = (bio_dgram_data *)a->ptr;
-+    OPENSSL_free(data);
-+
-+    return (1);
-+}
-+
-+static int dgram_clear(BIO *a)
-+{
-+    if (a == NULL)
-+        return (0);
-+    if (a->shutdown) {
-+        if (a->init) {
-+            BIO_closesocket(a->num);
-+        }
-+        a->init = 0;
-+        a->flags = 0;
-+    }
-+    return (1);
-+}
-+
-+static void dgram_adjust_rcv_timeout(BIO *b)
-+{
-+# if defined(SO_RCVTIMEO)
-+    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
-+    union {
-+        size_t s;
-+        int i;
-+    } sz = {
-+        0
-+    };
-+
-+    /* Is a timer active? */
-+    if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
-+        struct timeval timenow, timeleft;
-+
-+        /* Read current socket timeout */
-+#  ifdef OPENSSL_SYS_WINDOWS
-+        int timeout;
-+
-+        sz.i = sizeof(timeout);
-+        if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-+                       (void *)&timeout, &sz.i) < 0) {
-+            perror("getsockopt");
-+        } else {
-+            data->socket_timeout.tv_sec = timeout / 1000;
-+            data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
-+        }
-+#  else
-+        sz.i = sizeof(data->socket_timeout);
-+        if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-+                       &(data->socket_timeout), (void *)&sz) < 0) {
-+            perror("getsockopt");
-+        } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0)
-+            OPENSSL_assert(sz.s <= sizeof(data->socket_timeout));
-+#  endif
-+
-+        /* Get current time */
-+        get_current_time(&timenow);
-+
-+        /* Calculate time left until timer expires */
-+        memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
-+        if (timeleft.tv_usec < timenow.tv_usec) {
-+            timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
-+            timeleft.tv_sec--;
-+        } else {
-+            timeleft.tv_usec -= timenow.tv_usec;
-+        }
-+        if (timeleft.tv_sec < timenow.tv_sec) {
-+            timeleft.tv_sec = 0;
-+            timeleft.tv_usec = 1;
-+        } else {
-+            timeleft.tv_sec -= timenow.tv_sec;
-+        }
-+
-+        /*
-+         * Adjust socket timeout if next handshake message timer will expire
-+         * earlier.
-+         */
-+        if ((data->socket_timeout.tv_sec == 0
-+             && data->socket_timeout.tv_usec == 0)
-+            || (data->socket_timeout.tv_sec > timeleft.tv_sec)
-+            || (data->socket_timeout.tv_sec == timeleft.tv_sec
-+                && data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
-+#  ifdef OPENSSL_SYS_WINDOWS
-+            timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
-+            if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-+                           (void *)&timeout, sizeof(timeout)) < 0) {
-+                perror("setsockopt");
-+            }
-+#  else
-+            if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
-+                           sizeof(struct timeval)) < 0) {
-+                perror("setsockopt");
-+            }
-+#  endif
-+        }
-+    }
-+# endif
-+}
-+
-+static void dgram_reset_rcv_timeout(BIO *b)
-+{
-+# if defined(SO_RCVTIMEO)
-+    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
-+
-+    /* Is a timer active? */
-+    if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
-+#  ifdef OPENSSL_SYS_WINDOWS
-+        int timeout = data->socket_timeout.tv_sec * 1000 +
-+            data->socket_timeout.tv_usec / 1000;
-+        if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-+                       (void *)&timeout, sizeof(timeout)) < 0) {
-+            perror("setsockopt");
-+        }
-+#  else
-+        if (setsockopt
-+            (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
-+             sizeof(struct timeval)) < 0) {
-+            perror("setsockopt");
-+        }
-+#  endif
-+    }
-+# endif
-+}
-+
-+static int dgram_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0;
-+    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
-+    int flags = 0;
-+
-+    BIO_ADDR peer;
-+    socklen_t len = sizeof(peer);
-+
-+    if (out != NULL) {
-+        clear_socket_error();
-+        memset(&peer, 0, sizeof(peer));
-+        dgram_adjust_rcv_timeout(b);
-+        if (data->peekmode)
-+            flags = MSG_PEEK;
-+        ret = recvfrom(b->num, out, outl, flags,
-+                       BIO_ADDR_sockaddr_noconst(&peer), &len);
-+
-+        if (!data->connected && ret >= 0)
-+            BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
-+
-+        BIO_clear_retry_flags(b);
-+        if (ret < 0) {
-+            if (BIO_dgram_should_retry(ret)) {
-+                BIO_set_retry_read(b);
-+                data->_errno = get_last_socket_error();
-+            }
-+        }
-+
-+        dgram_reset_rcv_timeout(b);
-+    }
-+    return (ret);
-+}
-+
-+static int dgram_write(BIO *b, const char *in, int inl)
-+{
-+    int ret;
-+    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
-+    clear_socket_error();
-+
-+    if (data->connected)
-+        ret = writesocket(b->num, in, inl);
-+    else {
-+        int peerlen = BIO_ADDR_sockaddr_size(&data->peer);
-+
-+# if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
-+        ret = sendto(b->num, (char *)in, inl, 0,
-+                     BIO_ADDR_sockaddr(&data->peer), peerlen);
-+# else
-+        ret = sendto(b->num, in, inl, 0,
-+                     BIO_ADDR_sockaddr(&data->peer), peerlen);
-+# endif
-+    }
-+
-+    BIO_clear_retry_flags(b);
-+    if (ret <= 0) {
-+        if (BIO_dgram_should_retry(ret)) {
-+            BIO_set_retry_write(b);
-+            data->_errno = get_last_socket_error();
-+        }
-+    }
-+    return (ret);
-+}
-+
-+static long dgram_get_mtu_overhead(bio_dgram_data *data)
-+{
-+    long ret;
-+
-+    switch (BIO_ADDR_family(&data->peer)) {
-+    case AF_INET:
-+        /*
-+         * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
-+         */
-+        ret = 28;
-+        break;
-+# ifdef AF_INET6
-+    case AF_INET6:
-+        {
-+#  ifdef IN6_IS_ADDR_V4MAPPED
-+            struct in6_addr tmp_addr;
-+            if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
-+                && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
-+                /*
-+                 * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
-+                 */
-+                ret = 28;
-+            else
-+#  endif
-+            /*
-+             * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP
-+             */
-+            ret = 48;
-+        }
-+        break;
-+# endif
-+    default:
-+        /* We don't know. Go with the historical default */
-+        ret = 28;
-+        break;
-+    }
-+    return ret;
-+}
-+
-+static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    long ret = 1;
-+    int *ip;
-+    bio_dgram_data *data = NULL;
-+    int sockopt_val = 0;
-+    int d_errno;
-+# if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
-+    socklen_t sockopt_len;      /* assume that system supporting IP_MTU is
-+                                 * modern enough to define socklen_t */
-+    socklen_t addr_len;
-+    BIO_ADDR addr;
-+# endif
-+
-+    data = (bio_dgram_data *)b->ptr;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        num = 0;
-+        ret = 0;
-+        break;
-+    case BIO_CTRL_INFO:
-+        ret = 0;
-+        break;
-+    case BIO_C_SET_FD:
-+        dgram_clear(b);
-+        b->num = *((int *)ptr);
-+        b->shutdown = (int)num;
-+        b->init = 1;
-+        break;
-+    case BIO_C_GET_FD:
-+        if (b->init) {
-+            ip = (int *)ptr;
-+            if (ip != NULL)
-+                *ip = b->num;
-+            ret = b->num;
-+        } else
-+            ret = -1;
-+        break;
-+    case BIO_CTRL_GET_CLOSE:
-+        ret = b->shutdown;
-+        break;
-+    case BIO_CTRL_SET_CLOSE:
-+        b->shutdown = (int)num;
-+        break;
-+    case BIO_CTRL_PENDING:
-+    case BIO_CTRL_WPENDING:
-+        ret = 0;
-+        break;
-+    case BIO_CTRL_DUP:
-+    case BIO_CTRL_FLUSH:
-+        ret = 1;
-+        break;
-+    case BIO_CTRL_DGRAM_CONNECT:
-+        BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
-+        break;
-+        /* (Linux)kernel sets DF bit on outgoing IP packets */
-+    case BIO_CTRL_DGRAM_MTU_DISCOVER:
-+# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
-+        addr_len = (socklen_t) sizeof(addr);
-+        memset(&addr, 0, sizeof(addr));
-+        if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
-+            ret = 0;
-+            break;
-+        }
-+        switch (addr.sa.sa_family) {
-+        case AF_INET:
-+            sockopt_val = IP_PMTUDISC_DO;
-+            if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
-+                                  &sockopt_val, sizeof(sockopt_val))) < 0)
-+                perror("setsockopt");
-+            break;
-+#  if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
-+        case AF_INET6:
-+            sockopt_val = IPV6_PMTUDISC_DO;
-+            if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
-+                                  &sockopt_val, sizeof(sockopt_val))) < 0)
-+                perror("setsockopt");
-+            break;
-+#  endif
-+        default:
-+            ret = -1;
-+            break;
-+        }
-+# else
-+        ret = -1;
-+# endif
-+        break;
-+    case BIO_CTRL_DGRAM_QUERY_MTU:
-+# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
-+        addr_len = (socklen_t) sizeof(addr);
-+        memset(&addr, 0, sizeof(addr));
-+        if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
-+            ret = 0;
-+            break;
-+        }
-+        sockopt_len = sizeof(sockopt_val);
-+        switch (addr.sa.sa_family) {
-+        case AF_INET:
-+            if ((ret =
-+                 getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
-+                            &sockopt_len)) < 0 || sockopt_val < 0) {
-+                ret = 0;
-+            } else {
-+                /*
-+                 * we assume that the transport protocol is UDP and no IP
-+                 * options are used.
-+                 */
-+                data->mtu = sockopt_val - 8 - 20;
-+                ret = data->mtu;
-+            }
-+            break;
-+#  if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
-+        case AF_INET6:
-+            if ((ret =
-+                 getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
-+                            (void *)&sockopt_val, &sockopt_len)) < 0
-+                || sockopt_val < 0) {
-+                ret = 0;
-+            } else {
-+                /*
-+                 * we assume that the transport protocol is UDP and no IPV6
-+                 * options are used.
-+                 */
-+                data->mtu = sockopt_val - 8 - 40;
-+                ret = data->mtu;
-+            }
-+            break;
-+#  endif
-+        default:
-+            ret = 0;
-+            break;
-+        }
-+# else
-+        ret = 0;
-+# endif
-+        break;
-+    case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
-+        ret = -dgram_get_mtu_overhead(data);
-+        switch (BIO_ADDR_family(&data->peer)) {
-+        case AF_INET:
-+            ret += 576;
-+            break;
-+# if OPENSSL_USE_IPV6
-+        case AF_INET6:
-+            {
-+#  ifdef IN6_IS_ADDR_V4MAPPED
-+                struct in6_addr tmp_addr;
-+                if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
-+                    && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
-+                    ret += 576;
-+                else
-+#  endif
-+                    ret += 1280;
-+            }
-+            break;
-+# endif
-+        default:
-+            ret += 576;
-+            break;
-+        }
-+        break;
-+    case BIO_CTRL_DGRAM_GET_MTU:
-+        return data->mtu;
-+    case BIO_CTRL_DGRAM_SET_MTU:
-+        data->mtu = num;
-+        ret = num;
-+        break;
-+    case BIO_CTRL_DGRAM_SET_CONNECTED:
-+        if (ptr != NULL) {
-+            data->connected = 1;
-+            BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
-+        } else {
-+            data->connected = 0;
-+            memset(&data->peer, 0, sizeof(data->peer));
-+        }
-+        break;
-+    case BIO_CTRL_DGRAM_GET_PEER:
-+        ret = BIO_ADDR_sockaddr_size(&data->peer);
-+        /* FIXME: if num < ret, we will only return part of an address.
-+           That should bee an error, no? */
-+        if (num == 0 || num > ret)
-+            num = ret;
-+        memcpy(ptr, &data->peer, (ret = num));
-+        break;
-+    case BIO_CTRL_DGRAM_SET_PEER:
-+        BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
-+        break;
-+    case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
-+        memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
-+        break;
-+# if defined(SO_RCVTIMEO)
-+    case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
-+#  ifdef OPENSSL_SYS_WINDOWS
-+        {
-+            struct timeval *tv = (struct timeval *)ptr;
-+            int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
-+            if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-+                           (void *)&timeout, sizeof(timeout)) < 0) {
-+                perror("setsockopt");
-+                ret = -1;
-+            }
-+        }
-+#  else
-+        if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
-+                       sizeof(struct timeval)) < 0) {
-+            perror("setsockopt");
-+            ret = -1;
-+        }
-+#  endif
-+        break;
-+    case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
-+        {
-+            union {
-+                size_t s;
-+                int i;
-+            } sz = {
-+                0
-+            };
-+#  ifdef OPENSSL_SYS_WINDOWS
-+            int timeout;
-+            struct timeval *tv = (struct timeval *)ptr;
-+
-+            sz.i = sizeof(timeout);
-+            if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-+                           (void *)&timeout, &sz.i) < 0) {
-+                perror("getsockopt");
-+                ret = -1;
-+            } else {
-+                tv->tv_sec = timeout / 1000;
-+                tv->tv_usec = (timeout % 1000) * 1000;
-+                ret = sizeof(*tv);
-+            }
-+#  else
-+            sz.i = sizeof(struct timeval);
-+            if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-+                           ptr, (void *)&sz) < 0) {
-+                perror("getsockopt");
-+                ret = -1;
-+            } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
-+                OPENSSL_assert(sz.s <= sizeof(struct timeval));
-+                ret = (int)sz.s;
-+            } else
-+                ret = sz.i;
-+#  endif
-+        }
-+        break;
-+# endif
-+# if defined(SO_SNDTIMEO)
-+    case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
-+#  ifdef OPENSSL_SYS_WINDOWS
-+        {
-+            struct timeval *tv = (struct timeval *)ptr;
-+            int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
-+            if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
-+                           (void *)&timeout, sizeof(timeout)) < 0) {
-+                perror("setsockopt");
-+                ret = -1;
-+            }
-+        }
-+#  else
-+        if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
-+                       sizeof(struct timeval)) < 0) {
-+            perror("setsockopt");
-+            ret = -1;
-+        }
-+#  endif
-+        break;
-+    case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
-+        {
-+            union {
-+                size_t s;
-+                int i;
-+            } sz = {
-+                0
-+            };
-+#  ifdef OPENSSL_SYS_WINDOWS
-+            int timeout;
-+            struct timeval *tv = (struct timeval *)ptr;
-+
-+            sz.i = sizeof(timeout);
-+            if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
-+                           (void *)&timeout, &sz.i) < 0) {
-+                perror("getsockopt");
-+                ret = -1;
-+            } else {
-+                tv->tv_sec = timeout / 1000;
-+                tv->tv_usec = (timeout % 1000) * 1000;
-+                ret = sizeof(*tv);
-+            }
-+#  else
-+            sz.i = sizeof(struct timeval);
-+            if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
-+                           ptr, (void *)&sz) < 0) {
-+                perror("getsockopt");
-+                ret = -1;
-+            } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
-+                OPENSSL_assert(sz.s <= sizeof(struct timeval));
-+                ret = (int)sz.s;
-+            } else
-+                ret = sz.i;
-+#  endif
-+        }
-+        break;
-+# endif
-+    case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
-+        /* fall-through */
-+    case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
-+# ifdef OPENSSL_SYS_WINDOWS
-+        d_errno = (data->_errno == WSAETIMEDOUT);
-+# else
-+        d_errno = (data->_errno == EAGAIN);
-+# endif
-+        if (d_errno) {
-+            ret = 1;
-+            data->_errno = 0;
-+        } else
-+            ret = 0;
-+        break;
-+# ifdef EMSGSIZE
-+    case BIO_CTRL_DGRAM_MTU_EXCEEDED:
-+        if (data->_errno == EMSGSIZE) {
-+            ret = 1;
-+            data->_errno = 0;
-+        } else
-+            ret = 0;
-+        break;
-+# endif
-+    case BIO_CTRL_DGRAM_SET_DONT_FRAG:
-+        sockopt_val = num ? 1 : 0;
-+
-+        switch (data->peer.sa.sa_family) {
-+        case AF_INET:
-+# if defined(IP_DONTFRAG)
-+            if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG,
-+                                  &sockopt_val, sizeof(sockopt_val))) < 0) {
-+                perror("setsockopt");
-+                ret = -1;
-+            }
-+# elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE)
-+            if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
-+                (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
-+                                  &sockopt_val, sizeof(sockopt_val))) < 0) {
-+                perror("setsockopt");
-+                ret = -1;
-+            }
-+# elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
-+            if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT,
-+                                  (const char *)&sockopt_val,
-+                                  sizeof(sockopt_val))) < 0) {
-+                perror("setsockopt");
-+                ret = -1;
-+            }
-+# else
-+            ret = -1;
-+# endif
-+            break;
-+# if OPENSSL_USE_IPV6
-+        case AF_INET6:
-+#  if defined(IPV6_DONTFRAG)
-+            if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
-+                                  (const void *)&sockopt_val,
-+                                  sizeof(sockopt_val))) < 0) {
-+                perror("setsockopt");
-+                ret = -1;
-+            }
-+#  elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER)
-+            if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
-+                (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
-+                                  &sockopt_val, sizeof(sockopt_val))) < 0) {
-+                perror("setsockopt");
-+                ret = -1;
-+            }
-+#  else
-+            ret = -1;
-+#  endif
-+            break;
-+# endif
-+        default:
-+            ret = -1;
-+            break;
-+        }
-+        break;
-+    case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
-+        ret = dgram_get_mtu_overhead(data);
-+        break;
-+    case BIO_CTRL_DGRAM_SET_PEEK_MODE:
-+        data->peekmode = (unsigned int)num;
-+        break;
-+    default:
-+        ret = 0;
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int dgram_puts(BIO *bp, const char *str)
-+{
-+    int n, ret;
-+
-+    n = strlen(str);
-+    ret = dgram_write(bp, str, n);
-+    return (ret);
-+}
-+
-+# ifndef OPENSSL_NO_SCTP
-+const BIO_METHOD *BIO_s_datagram_sctp(void)
-+{
-+    return (&methods_dgramp_sctp);
-+}
-+
-+BIO *BIO_new_dgram_sctp(int fd, int close_flag)
-+{
-+    BIO *bio;
-+    int ret, optval = 20000;
-+    int auth_data = 0, auth_forward = 0;
-+    unsigned char *p;
-+    struct sctp_authchunk auth;
-+    struct sctp_authchunks *authchunks;
-+    socklen_t sockopt_len;
-+#  ifdef SCTP_AUTHENTICATION_EVENT
-+#   ifdef SCTP_EVENT
-+    struct sctp_event event;
-+#   else
-+    struct sctp_event_subscribe event;
-+#   endif
-+#  endif
-+
-+    bio = BIO_new(BIO_s_datagram_sctp());
-+    if (bio == NULL)
-+        return (NULL);
-+    BIO_set_fd(bio, fd, close_flag);
-+
-+    /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
-+    auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
-+    ret =
-+        setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
-+                   sizeof(struct sctp_authchunk));
-+    if (ret < 0) {
-+        BIO_vfree(bio);
-+        return (NULL);
-+    }
-+    auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
-+    ret =
-+        setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
-+                   sizeof(struct sctp_authchunk));
-+    if (ret < 0) {
-+        BIO_vfree(bio);
-+        return (NULL);
-+    }
-+
-+    /*
-+     * Test if activation was successful. When using accept(), SCTP-AUTH has
-+     * to be activated for the listening socket already, otherwise the
-+     * connected socket won't use it.
-+     */
-+    sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
-+    authchunks = OPENSSL_zalloc(sockopt_len);
-+    if (authchunks == NULL) {
-+        BIO_vfree(bio);
-+        return (NULL);
-+    }
-+    ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks,
-+                   &sockopt_len);
-+    if (ret < 0) {
-+        OPENSSL_free(authchunks);
-+        BIO_vfree(bio);
-+        return (NULL);
-+    }
-+
-+    for (p = (unsigned char *)authchunks->gauth_chunks;
-+         p < (unsigned char *)authchunks + sockopt_len;
-+         p += sizeof(uint8_t)) {
-+        if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
-+            auth_data = 1;
-+        if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
-+            auth_forward = 1;
-+    }
-+
-+    OPENSSL_free(authchunks);
-+
-+    OPENSSL_assert(auth_data);
-+    OPENSSL_assert(auth_forward);
-+
-+#  ifdef SCTP_AUTHENTICATION_EVENT
-+#   ifdef SCTP_EVENT
-+    memset(&event, 0, sizeof(event));
-+    event.se_assoc_id = 0;
-+    event.se_type = SCTP_AUTHENTICATION_EVENT;
-+    event.se_on = 1;
-+    ret =
-+        setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event,
-+                   sizeof(struct sctp_event));
-+    if (ret < 0) {
-+        BIO_vfree(bio);
-+        return (NULL);
-+    }
-+#   else
-+    sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
-+    ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
-+    if (ret < 0) {
-+        BIO_vfree(bio);
-+        return (NULL);
-+    }
-+
-+    event.sctp_authentication_event = 1;
-+
-+    ret =
-+        setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event,
-+                   sizeof(struct sctp_event_subscribe));
-+    if (ret < 0) {
-+        BIO_vfree(bio);
-+        return (NULL);
-+    }
-+#   endif
-+#  endif
-+
-+    /*
-+     * Disable partial delivery by setting the min size larger than the max
-+     * record size of 2^14 + 2048 + 13
-+     */
-+    ret =
-+        setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval,
-+                   sizeof(optval));
-+    if (ret < 0) {
-+        BIO_vfree(bio);
-+        return (NULL);
-+    }
-+
-+    return (bio);
-+}
-+
-+int BIO_dgram_is_sctp(BIO *bio)
-+{
-+    return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
-+}
-+
-+static int dgram_sctp_new(BIO *bi)
-+{
-+    bio_dgram_sctp_data *data = NULL;
-+
-+    bi->init = 0;
-+    bi->num = 0;
-+    data = OPENSSL_zalloc(sizeof(*data));
-+    if (data == NULL)
-+        return 0;
-+#  ifdef SCTP_PR_SCTP_NONE
-+    data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
-+#  endif
-+    bi->ptr = data;
-+
-+    bi->flags = 0;
-+    return (1);
-+}
-+
-+static int dgram_sctp_free(BIO *a)
-+{
-+    bio_dgram_sctp_data *data;
-+
-+    if (a == NULL)
-+        return (0);
-+    if (!dgram_clear(a))
-+        return 0;
-+
-+    data = (bio_dgram_sctp_data *) a->ptr;
-+    if (data != NULL) {
-+        OPENSSL_free(data->saved_message.data);
-+        OPENSSL_free(data);
-+    }
-+
-+    return (1);
-+}
-+
-+#  ifdef SCTP_AUTHENTICATION_EVENT
-+void dgram_sctp_handle_auth_free_key_event(BIO *b,
-+                                           union sctp_notification *snp)
-+{
-+    int ret;
-+    struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event;
-+
-+    if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) {
-+        struct sctp_authkeyid authkeyid;
-+
-+        /* delete key */
-+        authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
-+        ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
-+                         &authkeyid, sizeof(struct sctp_authkeyid));
-+    }
-+}
-+#  endif
-+
-+static int dgram_sctp_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0, n = 0, i, optval;
-+    socklen_t optlen;
-+    bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
-+    union sctp_notification *snp;
-+    struct msghdr msg;
-+    struct iovec iov;
-+    struct cmsghdr *cmsg;
-+    char cmsgbuf[512];
-+
-+    if (out != NULL) {
-+        clear_socket_error();
-+
-+        do {
-+            memset(&data->rcvinfo, 0, sizeof(data->rcvinfo));
-+            iov.iov_base = out;
-+            iov.iov_len = outl;
-+            msg.msg_name = NULL;
-+            msg.msg_namelen = 0;
-+            msg.msg_iov = &iov;
-+            msg.msg_iovlen = 1;
-+            msg.msg_control = cmsgbuf;
-+            msg.msg_controllen = 512;
-+            msg.msg_flags = 0;
-+            n = recvmsg(b->num, &msg, 0);
-+
-+            if (n <= 0) {
-+                if (n < 0)
-+                    ret = n;
-+                break;
-+            }
-+
-+            if (msg.msg_controllen > 0) {
-+                for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
-+                     cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-+                    if (cmsg->cmsg_level != IPPROTO_SCTP)
-+                        continue;
-+#  ifdef SCTP_RCVINFO
-+                    if (cmsg->cmsg_type == SCTP_RCVINFO) {
-+                        struct sctp_rcvinfo *rcvinfo;
-+
-+                        rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
-+                        data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
-+                        data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
-+                        data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
-+                        data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
-+                        data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
-+                        data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
-+                        data->rcvinfo.rcv_context = rcvinfo->rcv_context;
-+                    }
-+#  endif
-+#  ifdef SCTP_SNDRCV
-+                    if (cmsg->cmsg_type == SCTP_SNDRCV) {
-+                        struct sctp_sndrcvinfo *sndrcvinfo;
-+
-+                        sndrcvinfo =
-+                            (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
-+                        data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
-+                        data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
-+                        data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
-+                        data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
-+                        data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
-+                        data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
-+                        data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
-+                    }
-+#  endif
-+                }
-+            }
-+
-+            if (msg.msg_flags & MSG_NOTIFICATION) {
-+                snp = (union sctp_notification *)out;
-+                if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
-+#  ifdef SCTP_EVENT
-+                    struct sctp_event event;
-+#  else
-+                    struct sctp_event_subscribe event;
-+                    socklen_t eventsize;
-+#  endif
-+                    /*
-+                     * If a message has been delayed until the socket is dry,
-+                     * it can be sent now.
-+                     */
-+                    if (data->saved_message.length > 0) {
-+                        i = dgram_sctp_write(data->saved_message.bio,
-+                                         data->saved_message.data,
-+                                         data->saved_message.length);
-+                        if (i < 0) {
-+                            ret = i;
-+                            break;
-+                        }
-+                        OPENSSL_free(data->saved_message.data);
-+                        data->saved_message.data = NULL;
-+                        data->saved_message.length = 0;
-+                    }
-+
-+                    /* disable sender dry event */
-+#  ifdef SCTP_EVENT
-+                    memset(&event, 0, sizeof(event));
-+                    event.se_assoc_id = 0;
-+                    event.se_type = SCTP_SENDER_DRY_EVENT;
-+                    event.se_on = 0;
-+                    i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
-+                                   sizeof(struct sctp_event));
-+                    if (i < 0) {
-+                        ret = i;
-+                        break;
-+                    }
-+#  else
-+                    eventsize = sizeof(struct sctp_event_subscribe);
-+                    i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
-+                                   &eventsize);
-+                    if (i < 0) {
-+                        ret = i;
-+                        break;
-+                    }
-+
-+                    event.sctp_sender_dry_event = 0;
-+
-+                    i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
-+                                   sizeof(struct sctp_event_subscribe));
-+                    if (i < 0) {
-+                        ret = i;
-+                        break;
-+                    }
-+#  endif
-+                }
-+#  ifdef SCTP_AUTHENTICATION_EVENT
-+                if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
-+                    dgram_sctp_handle_auth_free_key_event(b, snp);
-+#  endif
-+
-+                if (data->handle_notifications != NULL)
-+                    data->handle_notifications(b, data->notification_context,
-+                                               (void *)out);
-+
-+                memset(out, 0, outl);
-+            } else
-+                ret += n;
-+        }
-+        while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR)
-+               && (ret < outl));
-+
-+        if (ret > 0 && !(msg.msg_flags & MSG_EOR)) {
-+            /* Partial message read, this should never happen! */
-+
-+            /*
-+             * The buffer was too small, this means the peer sent a message
-+             * that was larger than allowed.
-+             */
-+            if (ret == outl)
-+                return -1;
-+
-+            /*
-+             * Test if socket buffer can handle max record size (2^14 + 2048
-+             * + 13)
-+             */
-+            optlen = (socklen_t) sizeof(int);
-+            ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
-+            if (ret >= 0)
-+                OPENSSL_assert(optval >= 18445);
-+
-+            /*
-+             * Test if SCTP doesn't partially deliver below max record size
-+             * (2^14 + 2048 + 13)
-+             */
-+            optlen = (socklen_t) sizeof(int);
-+            ret =
-+                getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
-+                           &optval, &optlen);
-+            if (ret >= 0)
-+                OPENSSL_assert(optval >= 18445);
-+
-+            /*
-+             * Partially delivered notification??? Probably a bug....
-+             */
-+            OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
-+
-+            /*
-+             * Everything seems ok till now, so it's most likely a message
-+             * dropped by PR-SCTP.
-+             */
-+            memset(out, 0, outl);
-+            BIO_set_retry_read(b);
-+            return -1;
-+        }
-+
-+        BIO_clear_retry_flags(b);
-+        if (ret < 0) {
-+            if (BIO_dgram_should_retry(ret)) {
-+                BIO_set_retry_read(b);
-+                data->_errno = get_last_socket_error();
-+            }
-+        }
-+
-+        /* Test if peer uses SCTP-AUTH before continuing */
-+        if (!data->peer_auth_tested) {
-+            int ii, auth_data = 0, auth_forward = 0;
-+            unsigned char *p;
-+            struct sctp_authchunks *authchunks;
-+
-+            optlen =
-+                (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
-+            authchunks = OPENSSL_malloc(optlen);
-+            if (authchunks == NULL) {
-+                BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE);
-+                return -1;
-+            }
-+            memset(authchunks, 0, optlen);
-+            ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS,
-+                            authchunks, &optlen);
-+
-+            if (ii >= 0)
-+                for (p = (unsigned char *)authchunks->gauth_chunks;
-+                     p < (unsigned char *)authchunks + optlen;
-+                     p += sizeof(uint8_t)) {
-+                    if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
-+                        auth_data = 1;
-+                    if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
-+                        auth_forward = 1;
-+                }
-+
-+            OPENSSL_free(authchunks);
-+
-+            if (!auth_data || !auth_forward) {
-+                BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR);
-+                return -1;
-+            }
-+
-+            data->peer_auth_tested = 1;
-+        }
-+    }
-+    return (ret);
-+}
-+
-+/*
-+ * dgram_sctp_write - send message on SCTP socket
-+ * @b: BIO to write to
-+ * @in: data to send
-+ * @inl: amount of bytes in @in to send
-+ *
-+ * Returns -1 on error or the sent amount of bytes on success
-+ */
-+static int dgram_sctp_write(BIO *b, const char *in, int inl)
-+{
-+    int ret;
-+    bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
-+    struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
-+    struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
-+    struct bio_dgram_sctp_sndinfo handshake_sinfo;
-+    struct iovec iov[1];
-+    struct msghdr msg;
-+    struct cmsghdr *cmsg;
-+#  if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
-+    char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) +
-+                 CMSG_SPACE(sizeof(struct sctp_prinfo))];
-+    struct sctp_sndinfo *sndinfo;
-+    struct sctp_prinfo *prinfo;
-+#  else
-+    char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
-+    struct sctp_sndrcvinfo *sndrcvinfo;
-+#  endif
-+
-+    clear_socket_error();
-+
-+    /*
-+     * If we're send anything else than application data, disable all user
-+     * parameters and flags.
-+     */
-+    if (in[0] != 23) {
-+        memset(&handshake_sinfo, 0, sizeof(handshake_sinfo));
-+#  ifdef SCTP_SACK_IMMEDIATELY
-+        handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
-+#  endif
-+        sinfo = &handshake_sinfo;
-+    }
-+
-+    /*
-+     * If we have to send a shutdown alert message and the socket is not dry
-+     * yet, we have to save it and send it as soon as the socket gets dry.
-+     */
-+    if (data->save_shutdown) {
-+        ret = BIO_dgram_sctp_wait_for_dry(b);
-+        if (ret < 0) {
-+            return -1;
-+        }
-+        if (ret == 0) {
-+            char *tmp;
-+            data->saved_message.bio = b;
-+            if ((tmp = OPENSSL_malloc(inl)) == NULL) {
-+                BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_FAILURE);
-+                return -1;
-+            }
-+            OPENSSL_free(data->saved_message.data);
-+            data->saved_message.data = tmp;
-+            memcpy(data->saved_message.data, in, inl);
-+            data->saved_message.length = inl;
-+            return inl;
-+        }
-+    }
-+
-+    iov[0].iov_base = (char *)in;
-+    iov[0].iov_len = inl;
-+    msg.msg_name = NULL;
-+    msg.msg_namelen = 0;
-+    msg.msg_iov = iov;
-+    msg.msg_iovlen = 1;
-+    msg.msg_control = (caddr_t) cmsgbuf;
-+    msg.msg_controllen = 0;
-+    msg.msg_flags = 0;
-+#  if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
-+    cmsg = (struct cmsghdr *)cmsgbuf;
-+    cmsg->cmsg_level = IPPROTO_SCTP;
-+    cmsg->cmsg_type = SCTP_SNDINFO;
-+    cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
-+    sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
-+    memset(sndinfo, 0, sizeof(*sndinfo));
-+    sndinfo->snd_sid = sinfo->snd_sid;
-+    sndinfo->snd_flags = sinfo->snd_flags;
-+    sndinfo->snd_ppid = sinfo->snd_ppid;
-+    sndinfo->snd_context = sinfo->snd_context;
-+    msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
-+
-+    cmsg =
-+        (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
-+    cmsg->cmsg_level = IPPROTO_SCTP;
-+    cmsg->cmsg_type = SCTP_PRINFO;
-+    cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
-+    prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
-+    memset(prinfo, 0, sizeof(*prinfo));
-+    prinfo->pr_policy = pinfo->pr_policy;
-+    prinfo->pr_value = pinfo->pr_value;
-+    msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
-+#  else
-+    cmsg = (struct cmsghdr *)cmsgbuf;
-+    cmsg->cmsg_level = IPPROTO_SCTP;
-+    cmsg->cmsg_type = SCTP_SNDRCV;
-+    cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
-+    sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
-+    memset(sndrcvinfo, 0, sizeof(*sndrcvinfo));
-+    sndrcvinfo->sinfo_stream = sinfo->snd_sid;
-+    sndrcvinfo->sinfo_flags = sinfo->snd_flags;
-+#   ifdef __FreeBSD__
-+    sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
-+#   endif
-+    sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
-+    sndrcvinfo->sinfo_context = sinfo->snd_context;
-+    sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
-+    msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
-+#  endif
-+
-+    ret = sendmsg(b->num, &msg, 0);
-+
-+    BIO_clear_retry_flags(b);
-+    if (ret <= 0) {
-+        if (BIO_dgram_should_retry(ret)) {
-+            BIO_set_retry_write(b);
-+            data->_errno = get_last_socket_error();
-+        }
-+    }
-+    return (ret);
-+}
-+
-+static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    long ret = 1;
-+    bio_dgram_sctp_data *data = NULL;
-+    socklen_t sockopt_len = 0;
-+    struct sctp_authkeyid authkeyid;
-+    struct sctp_authkey *authkey = NULL;
-+
-+    data = (bio_dgram_sctp_data *) b->ptr;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_DGRAM_QUERY_MTU:
-+        /*
-+         * Set to maximum (2^14) and ignore user input to enable transport
-+         * protocol fragmentation. Returns always 2^14.
-+         */
-+        data->mtu = 16384;
-+        ret = data->mtu;
-+        break;
-+    case BIO_CTRL_DGRAM_SET_MTU:
-+        /*
-+         * Set to maximum (2^14) and ignore input to enable transport
-+         * protocol fragmentation. Returns always 2^14.
-+         */
-+        data->mtu = 16384;
-+        ret = data->mtu;
-+        break;
-+    case BIO_CTRL_DGRAM_SET_CONNECTED:
-+    case BIO_CTRL_DGRAM_CONNECT:
-+        /* Returns always -1. */
-+        ret = -1;
-+        break;
-+    case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
-+        /*
-+         * SCTP doesn't need the DTLS timer Returns always 1.
-+         */
-+        break;
-+    case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
-+        /*
-+         * We allow transport protocol fragmentation so this is irrelevant
-+         */
-+        ret = 0;
-+        break;
-+    case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
-+        if (num > 0)
-+            data->in_handshake = 1;
-+        else
-+            data->in_handshake = 0;
-+
-+        ret =
-+            setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY,
-+                       &data->in_handshake, sizeof(int));
-+        break;
-+    case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
-+        /*
-+         * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise.
-+         */
-+
-+        /* Get active key */
-+        sockopt_len = sizeof(struct sctp_authkeyid);
-+        ret =
-+            getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
-+                       &sockopt_len);
-+        if (ret < 0)
-+            break;
-+
-+        /* Add new key */
-+        sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
-+        authkey = OPENSSL_malloc(sockopt_len);
-+        if (authkey == NULL) {
-+            ret = -1;
-+            break;
-+        }
-+        memset(authkey, 0, sockopt_len);
-+        authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
-+#  ifndef __FreeBSD__
-+        /*
-+         * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3
-+         * and higher work without it.
-+         */
-+        authkey->sca_keylength = 64;
-+#  endif
-+        memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
-+
-+        ret =
-+            setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey,
-+                       sockopt_len);
-+        OPENSSL_free(authkey);
-+        authkey = NULL;
-+        if (ret < 0)
-+            break;
-+
-+        /* Reset active key */
-+        ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
-+                         &authkeyid, sizeof(struct sctp_authkeyid));
-+        if (ret < 0)
-+            break;
-+
-+        break;
-+    case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
-+        /* Returns 0 on success, -1 otherwise. */
-+
-+        /* Get active key */
-+        sockopt_len = sizeof(struct sctp_authkeyid);
-+        ret =
-+            getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
-+                       &sockopt_len);
-+        if (ret < 0)
-+            break;
-+
-+        /* Set active key */
-+        authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
-+        ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
-+                         &authkeyid, sizeof(struct sctp_authkeyid));
-+        if (ret < 0)
-+            break;
-+
-+        /*
-+         * CCS has been sent, so remember that and fall through to check if
-+         * we need to deactivate an old key
-+         */
-+        data->ccs_sent = 1;
-+
-+    case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
-+        /* Returns 0 on success, -1 otherwise. */
-+
-+        /*
-+         * Has this command really been called or is this just a
-+         * fall-through?
-+         */
-+        if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
-+            data->ccs_rcvd = 1;
-+
-+        /*
-+         * CSS has been both, received and sent, so deactivate an old key
-+         */
-+        if (data->ccs_rcvd == 1 && data->ccs_sent == 1) {
-+            /* Get active key */
-+            sockopt_len = sizeof(struct sctp_authkeyid);
-+            ret =
-+                getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
-+                           &authkeyid, &sockopt_len);
-+            if (ret < 0)
-+                break;
-+
-+            /*
-+             * Deactivate key or delete second last key if
-+             * SCTP_AUTHENTICATION_EVENT is not available.
-+             */
-+            authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
-+#  ifdef SCTP_AUTH_DEACTIVATE_KEY
-+            sockopt_len = sizeof(struct sctp_authkeyid);
-+            ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
-+                             &authkeyid, sockopt_len);
-+            if (ret < 0)
-+                break;
-+#  endif
-+#  ifndef SCTP_AUTHENTICATION_EVENT
-+            if (authkeyid.scact_keynumber > 0) {
-+                authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
-+                ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
-+                                 &authkeyid, sizeof(struct sctp_authkeyid));
-+                if (ret < 0)
-+                    break;
-+            }
-+#  endif
-+
-+            data->ccs_rcvd = 0;
-+            data->ccs_sent = 0;
-+        }
-+        break;
-+    case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
-+        /* Returns the size of the copied struct. */
-+        if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
-+            num = sizeof(struct bio_dgram_sctp_sndinfo);
-+
-+        memcpy(ptr, &(data->sndinfo), num);
-+        ret = num;
-+        break;
-+    case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
-+        /* Returns the size of the copied struct. */
-+        if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
-+            num = sizeof(struct bio_dgram_sctp_sndinfo);
-+
-+        memcpy(&(data->sndinfo), ptr, num);
-+        break;
-+    case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
-+        /* Returns the size of the copied struct. */
-+        if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
-+            num = sizeof(struct bio_dgram_sctp_rcvinfo);
-+
-+        memcpy(ptr, &data->rcvinfo, num);
-+
-+        ret = num;
-+        break;
-+    case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
-+        /* Returns the size of the copied struct. */
-+        if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
-+            num = sizeof(struct bio_dgram_sctp_rcvinfo);
-+
-+        memcpy(&(data->rcvinfo), ptr, num);
-+        break;
-+    case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
-+        /* Returns the size of the copied struct. */
-+        if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
-+            num = sizeof(struct bio_dgram_sctp_prinfo);
-+
-+        memcpy(ptr, &(data->prinfo), num);
-+        ret = num;
-+        break;
-+    case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
-+        /* Returns the size of the copied struct. */
-+        if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
-+            num = sizeof(struct bio_dgram_sctp_prinfo);
-+
-+        memcpy(&(data->prinfo), ptr, num);
-+        break;
-+    case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
-+        /* Returns always 1. */
-+        if (num > 0)
-+            data->save_shutdown = 1;
-+        else
-+            data->save_shutdown = 0;
-+        break;
-+
-+    default:
-+        /*
-+         * Pass to default ctrl function to process SCTP unspecific commands
-+         */
-+        ret = dgram_ctrl(b, cmd, num, ptr);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+int BIO_dgram_sctp_notification_cb(BIO *b,
-+                                   void (*handle_notifications) (BIO *bio,
-+                                                                 void
-+                                                                 *context,
-+                                                                 void *buf),
-+                                   void *context)
-+{
-+    bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
-+
-+    if (handle_notifications != NULL) {
-+        data->handle_notifications = handle_notifications;
-+        data->notification_context = context;
-+    } else
-+        return -1;
-+
-+    return 0;
-+}
-+
-+/*
-+ * BIO_dgram_sctp_wait_for_dry - Wait for SCTP SENDER_DRY event
-+ * @b: The BIO to check for the dry event
-+ *
-+ * Wait until the peer confirms all packets have been received, and so that
-+ * our kernel doesn't have anything to send anymore.  This is only received by
-+ * the peer's kernel, not the application.
-+ *
-+ * Returns:
-+ * -1 on error
-+ *  0 when not dry yet
-+ *  1 when dry
-+ */
-+int BIO_dgram_sctp_wait_for_dry(BIO *b)
-+{
-+    int is_dry = 0;
-+    int sockflags = 0;
-+    int n, ret;
-+    union sctp_notification snp;
-+    struct msghdr msg;
-+    struct iovec iov;
-+#  ifdef SCTP_EVENT
-+    struct sctp_event event;
-+#  else
-+    struct sctp_event_subscribe event;
-+    socklen_t eventsize;
-+#  endif
-+    bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
-+
-+    /* set sender dry event */
-+#  ifdef SCTP_EVENT
-+    memset(&event, 0, sizeof(event));
-+    event.se_assoc_id = 0;
-+    event.se_type = SCTP_SENDER_DRY_EVENT;
-+    event.se_on = 1;
-+    ret =
-+        setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
-+                   sizeof(struct sctp_event));
-+#  else
-+    eventsize = sizeof(struct sctp_event_subscribe);
-+    ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
-+    if (ret < 0)
-+        return -1;
-+
-+    event.sctp_sender_dry_event = 1;
-+
-+    ret =
-+        setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
-+                   sizeof(struct sctp_event_subscribe));
-+#  endif
-+    if (ret < 0)
-+        return -1;
-+
-+    /* peek for notification */
-+    memset(&snp, 0, sizeof(snp));
-+    iov.iov_base = (char *)&snp;
-+    iov.iov_len = sizeof(union sctp_notification);
-+    msg.msg_name = NULL;
-+    msg.msg_namelen = 0;
-+    msg.msg_iov = &iov;
-+    msg.msg_iovlen = 1;
-+    msg.msg_control = NULL;
-+    msg.msg_controllen = 0;
-+    msg.msg_flags = 0;
-+
-+    n = recvmsg(b->num, &msg, MSG_PEEK);
-+    if (n <= 0) {
-+        if ((n < 0) && (get_last_socket_error() != EAGAIN)
-+            && (get_last_socket_error() != EWOULDBLOCK))
-+            return -1;
-+        else
-+            return 0;
-+    }
-+
-+    /* if we find a notification, process it and try again if necessary */
-+    while (msg.msg_flags & MSG_NOTIFICATION) {
-+        memset(&snp, 0, sizeof(snp));
-+        iov.iov_base = (char *)&snp;
-+        iov.iov_len = sizeof(union sctp_notification);
-+        msg.msg_name = NULL;
-+        msg.msg_namelen = 0;
-+        msg.msg_iov = &iov;
-+        msg.msg_iovlen = 1;
-+        msg.msg_control = NULL;
-+        msg.msg_controllen = 0;
-+        msg.msg_flags = 0;
-+
-+        n = recvmsg(b->num, &msg, 0);
-+        if (n <= 0) {
-+            if ((n < 0) && (get_last_socket_error() != EAGAIN)
-+                && (get_last_socket_error() != EWOULDBLOCK))
-+                return -1;
-+            else
-+                return is_dry;
-+        }
-+
-+        if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
-+            is_dry = 1;
-+
-+            /* disable sender dry event */
-+#  ifdef SCTP_EVENT
-+            memset(&event, 0, sizeof(event));
-+            event.se_assoc_id = 0;
-+            event.se_type = SCTP_SENDER_DRY_EVENT;
-+            event.se_on = 0;
-+            ret =
-+                setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
-+                           sizeof(struct sctp_event));
-+#  else
-+            eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
-+            ret =
-+                getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
-+                           &eventsize);
-+            if (ret < 0)
-+                return -1;
-+
-+            event.sctp_sender_dry_event = 0;
-+
-+            ret =
-+                setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
-+                           sizeof(struct sctp_event_subscribe));
-+#  endif
-+            if (ret < 0)
-+                return -1;
-+        }
-+#  ifdef SCTP_AUTHENTICATION_EVENT
-+        if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
-+            dgram_sctp_handle_auth_free_key_event(b, &snp);
-+#  endif
-+
-+        if (data->handle_notifications != NULL)
-+            data->handle_notifications(b, data->notification_context,
-+                                       (void *)&snp);
-+
-+        /* found notification, peek again */
-+        memset(&snp, 0, sizeof(snp));
-+        iov.iov_base = (char *)&snp;
-+        iov.iov_len = sizeof(union sctp_notification);
-+        msg.msg_name = NULL;
-+        msg.msg_namelen = 0;
-+        msg.msg_iov = &iov;
-+        msg.msg_iovlen = 1;
-+        msg.msg_control = NULL;
-+        msg.msg_controllen = 0;
-+        msg.msg_flags = 0;
-+
-+        /* if we have seen the dry already, don't wait */
-+        if (is_dry) {
-+            sockflags = fcntl(b->num, F_GETFL, 0);
-+            fcntl(b->num, F_SETFL, O_NONBLOCK);
-+        }
-+
-+        n = recvmsg(b->num, &msg, MSG_PEEK);
-+
-+        if (is_dry) {
-+            fcntl(b->num, F_SETFL, sockflags);
-+        }
-+
-+        if (n <= 0) {
-+            if ((n < 0) && (get_last_socket_error() != EAGAIN)
-+                && (get_last_socket_error() != EWOULDBLOCK))
-+                return -1;
-+            else
-+                return is_dry;
-+        }
-+    }
-+
-+    /* read anything else */
-+    return is_dry;
-+}
-+
-+int BIO_dgram_sctp_msg_waiting(BIO *b)
-+{
-+    int n, sockflags;
-+    union sctp_notification snp;
-+    struct msghdr msg;
-+    struct iovec iov;
-+    bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
-+
-+    /* Check if there are any messages waiting to be read */
-+    do {
-+        memset(&snp, 0, sizeof(snp));
-+        iov.iov_base = (char *)&snp;
-+        iov.iov_len = sizeof(union sctp_notification);
-+        msg.msg_name = NULL;
-+        msg.msg_namelen = 0;
-+        msg.msg_iov = &iov;
-+        msg.msg_iovlen = 1;
-+        msg.msg_control = NULL;
-+        msg.msg_controllen = 0;
-+        msg.msg_flags = 0;
-+
-+        sockflags = fcntl(b->num, F_GETFL, 0);
-+        fcntl(b->num, F_SETFL, O_NONBLOCK);
-+        n = recvmsg(b->num, &msg, MSG_PEEK);
-+        fcntl(b->num, F_SETFL, sockflags);
-+
-+        /* if notification, process and try again */
-+        if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
-+#  ifdef SCTP_AUTHENTICATION_EVENT
-+            if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
-+                dgram_sctp_handle_auth_free_key_event(b, &snp);
-+#  endif
-+
-+            memset(&snp, 0, sizeof(snp));
-+            iov.iov_base = (char *)&snp;
-+            iov.iov_len = sizeof(union sctp_notification);
-+            msg.msg_name = NULL;
-+            msg.msg_namelen = 0;
-+            msg.msg_iov = &iov;
-+            msg.msg_iovlen = 1;
-+            msg.msg_control = NULL;
-+            msg.msg_controllen = 0;
-+            msg.msg_flags = 0;
-+            n = recvmsg(b->num, &msg, 0);
-+
-+            if (data->handle_notifications != NULL)
-+                data->handle_notifications(b, data->notification_context,
-+                                           (void *)&snp);
-+        }
-+
-+    } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
-+
-+    /* Return 1 if there is a message to be read, return 0 otherwise. */
-+    if (n > 0)
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+static int dgram_sctp_puts(BIO *bp, const char *str)
-+{
-+    int n, ret;
-+
-+    n = strlen(str);
-+    ret = dgram_sctp_write(bp, str, n);
-+    return (ret);
-+}
-+# endif
-+
-+static int BIO_dgram_should_retry(int i)
-+{
-+    int err;
-+
-+    if ((i == 0) || (i == -1)) {
-+        err = get_last_socket_error();
-+
-+# if defined(OPENSSL_SYS_WINDOWS)
-+        /*
-+         * If the socket return value (i) is -1 and err is unexpectedly 0 at
-+         * this point, the error code was overwritten by another system call
-+         * before this error handling is called.
-+         */
-+# endif
-+
-+        return (BIO_dgram_non_fatal_error(err));
-+    }
-+    return (0);
-+}
-+
-+int BIO_dgram_non_fatal_error(int err)
-+{
-+    switch (err) {
-+# if defined(OPENSSL_SYS_WINDOWS)
-+#  if defined(WSAEWOULDBLOCK)
-+    case WSAEWOULDBLOCK:
-+#  endif
-+# endif
-+
-+# ifdef EWOULDBLOCK
-+#  ifdef WSAEWOULDBLOCK
-+#   if WSAEWOULDBLOCK != EWOULDBLOCK
-+    case EWOULDBLOCK:
-+#   endif
-+#  else
-+    case EWOULDBLOCK:
-+#  endif
-+# endif
-+
-+# ifdef EINTR
-+    case EINTR:
-+# endif
-+
-+# ifdef EAGAIN
-+#  if EWOULDBLOCK != EAGAIN
-+    case EAGAIN:
-+#  endif
-+# endif
-+
-+# ifdef EPROTO
-+    case EPROTO:
-+# endif
-+
-+# ifdef EINPROGRESS
-+    case EINPROGRESS:
-+# endif
-+
-+# ifdef EALREADY
-+    case EALREADY:
-+# endif
-+
-+        return (1);
-+        /* break; */
-+    default:
-+        break;
-+    }
-+    return (0);
-+}
-+
-+static void get_current_time(struct timeval *t)
-+{
-+# if defined(_WIN32)
-+    SYSTEMTIME st;
-+    union {
-+        unsigned __int64 ul;
-+        FILETIME ft;
-+    } now;
-+
-+    GetSystemTime(&st);
-+    SystemTimeToFileTime(&st, &now.ft);
-+#  ifdef  __MINGW32__
-+    now.ul -= 116444736000000000ULL;
-+#  else
-+    now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
-+#  endif
-+    t->tv_sec = (long)(now.ul / 10000000);
-+    t->tv_usec = ((int)(now.ul % 10000000)) / 10;
-+# elif defined(OPENSSL_SYS_VMS)
-+    struct timeb tb;
-+    ftime(&tb);
-+    t->tv_sec = (long)tb.time;
-+    t->tv_usec = (long)tb.millitm * 1000;
-+# else
-+    gettimeofday(t, NULL);
-+# endif
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_fd.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_fd.c
-new file mode 100644
-index 0000000..1e56cb6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_fd.c
-@@ -0,0 +1,273 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+#include "bio_lcl.h"
-+
-+#if defined(OPENSSL_NO_POSIX_IO)
-+/*
-+ * Dummy placeholder for BIO_s_fd...
-+ */
-+BIO *BIO_new_fd(int fd, int close_flag)
-+{
-+    return NULL;
-+}
-+
-+int BIO_fd_non_fatal_error(int err)
-+{
-+    return 0;
-+}
-+
-+int BIO_fd_should_retry(int i)
-+{
-+    return 0;
-+}
-+
-+const BIO_METHOD *BIO_s_fd(void)
-+{
-+    return NULL;
-+}
-+#else
-+/*
-+ * As for unconditional usage of "UPLINK" interface in this module.
-+ * Trouble is that unlike Unix file descriptors [which are indexes
-+ * in kernel-side per-process table], corresponding descriptors on
-+ * platforms which require "UPLINK" interface seem to be indexes
-+ * in a user-land, non-global table. Well, in fact they are indexes
-+ * in stdio _iob[], and recall that _iob[] was the very reason why
-+ * "UPLINK" interface was introduced in first place. But one way on
-+ * another. Neither libcrypto or libssl use this BIO meaning that
-+ * file descriptors can only be provided by application. Therefore
-+ * "UPLINK" calls are due...
-+ */
-+static int fd_write(BIO *h, const char *buf, int num);
-+static int fd_read(BIO *h, char *buf, int size);
-+static int fd_puts(BIO *h, const char *str);
-+static int fd_gets(BIO *h, char *buf, int size);
-+static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int fd_new(BIO *h);
-+static int fd_free(BIO *data);
-+int BIO_fd_should_retry(int s);
-+
-+static const BIO_METHOD methods_fdp = {
-+    BIO_TYPE_FD, "file descriptor",
-+    fd_write,
-+    fd_read,
-+    fd_puts,
-+    fd_gets,
-+    fd_ctrl,
-+    fd_new,
-+    fd_free,
-+    NULL,
-+};
-+
-+const BIO_METHOD *BIO_s_fd(void)
-+{
-+    return (&methods_fdp);
-+}
-+
-+BIO *BIO_new_fd(int fd, int close_flag)
-+{
-+    BIO *ret;
-+    ret = BIO_new(BIO_s_fd());
-+    if (ret == NULL)
-+        return (NULL);
-+    BIO_set_fd(ret, fd, close_flag);
-+    return (ret);
-+}
-+
-+static int fd_new(BIO *bi)
-+{
-+    bi->init = 0;
-+    bi->num = -1;
-+    bi->ptr = NULL;
-+    bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */
-+    return (1);
-+}
-+
-+static int fd_free(BIO *a)
-+{
-+    if (a == NULL)
-+        return (0);
-+    if (a->shutdown) {
-+        if (a->init) {
-+            UP_close(a->num);
-+        }
-+        a->init = 0;
-+        a->flags = BIO_FLAGS_UPLINK;
-+    }
-+    return (1);
-+}
-+
-+static int fd_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0;
-+
-+    if (out != NULL) {
-+        clear_sys_error();
-+        ret = UP_read(b->num, out, outl);
-+        BIO_clear_retry_flags(b);
-+        if (ret <= 0) {
-+            if (BIO_fd_should_retry(ret))
-+                BIO_set_retry_read(b);
-+        }
-+    }
-+    return (ret);
-+}
-+
-+static int fd_write(BIO *b, const char *in, int inl)
-+{
-+    int ret;
-+    clear_sys_error();
-+    ret = UP_write(b->num, in, inl);
-+    BIO_clear_retry_flags(b);
-+    if (ret <= 0) {
-+        if (BIO_fd_should_retry(ret))
-+            BIO_set_retry_write(b);
-+    }
-+    return (ret);
-+}
-+
-+static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    long ret = 1;
-+    int *ip;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        num = 0;
-+    case BIO_C_FILE_SEEK:
-+        ret = (long)UP_lseek(b->num, num, 0);
-+        break;
-+    case BIO_C_FILE_TELL:
-+    case BIO_CTRL_INFO:
-+        ret = (long)UP_lseek(b->num, 0, 1);
-+        break;
-+    case BIO_C_SET_FD:
-+        fd_free(b);
-+        b->num = *((int *)ptr);
-+        b->shutdown = (int)num;
-+        b->init = 1;
-+        break;
-+    case BIO_C_GET_FD:
-+        if (b->init) {
-+            ip = (int *)ptr;
-+            if (ip != NULL)
-+                *ip = b->num;
-+            ret = b->num;
-+        } else
-+            ret = -1;
-+        break;
-+    case BIO_CTRL_GET_CLOSE:
-+        ret = b->shutdown;
-+        break;
-+    case BIO_CTRL_SET_CLOSE:
-+        b->shutdown = (int)num;
-+        break;
-+    case BIO_CTRL_PENDING:
-+    case BIO_CTRL_WPENDING:
-+        ret = 0;
-+        break;
-+    case BIO_CTRL_DUP:
-+    case BIO_CTRL_FLUSH:
-+        ret = 1;
-+        break;
-+    default:
-+        ret = 0;
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int fd_puts(BIO *bp, const char *str)
-+{
-+    int n, ret;
-+
-+    n = strlen(str);
-+    ret = fd_write(bp, str, n);
-+    return (ret);
-+}
-+
-+static int fd_gets(BIO *bp, char *buf, int size)
-+{
-+    int ret = 0;
-+    char *ptr = buf;
-+    char *end = buf + size - 1;
-+
-+    while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n'))
-+        ptr++;
-+
-+    ptr[0] = '\0';
-+
-+    if (buf[0] != '\0')
-+        ret = strlen(buf);
-+    return (ret);
-+}
-+
-+int BIO_fd_should_retry(int i)
-+{
-+    int err;
-+
-+    if ((i == 0) || (i == -1)) {
-+        err = get_last_sys_error();
-+
-+        return (BIO_fd_non_fatal_error(err));
-+    }
-+    return (0);
-+}
-+
-+int BIO_fd_non_fatal_error(int err)
-+{
-+    switch (err) {
-+
-+# ifdef EWOULDBLOCK
-+#  ifdef WSAEWOULDBLOCK
-+#   if WSAEWOULDBLOCK != EWOULDBLOCK
-+    case EWOULDBLOCK:
-+#   endif
-+#  else
-+    case EWOULDBLOCK:
-+#  endif
-+# endif
-+
-+# if defined(ENOTCONN)
-+    case ENOTCONN:
-+# endif
-+
-+# ifdef EINTR
-+    case EINTR:
-+# endif
-+
-+# ifdef EAGAIN
-+#  if EWOULDBLOCK != EAGAIN
-+    case EAGAIN:
-+#  endif
-+# endif
-+
-+# ifdef EPROTO
-+    case EPROTO:
-+# endif
-+
-+# ifdef EINPROGRESS
-+    case EINPROGRESS:
-+# endif
-+
-+# ifdef EALREADY
-+    case EALREADY:
-+# endif
-+        return (1);
-+        /* break; */
-+    default:
-+        break;
-+    }
-+    return (0);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_file.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_file.c
-new file mode 100644
-index 0000000..6af2d9c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_file.c
-@@ -0,0 +1,419 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*-
-+ * 03-Dec-1997  rdenny@dc3.com  Fix bug preventing use of stdin/stdout
-+ *              with binary data (e.g. asn1parse -inform DER < xxx) under
-+ *              Windows
-+ */
-+
-+#ifndef HEADER_BSS_FILE_C
-+# define HEADER_BSS_FILE_C
-+
-+# if defined(__linux) || defined(__sun) || defined(__hpux)
-+/*
-+ * Following definition aliases fopen to fopen64 on above mentioned
-+ * platforms. This makes it possible to open and sequentially access files
-+ * larger than 2GB from 32-bit application. It does not allow to traverse
-+ * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit
-+ * platform permits that, not with fseek/ftell. Not to mention that breaking
-+ * 2GB limit for seeking would require surgery to *our* API. But sequential
-+ * access suffices for practical cases when you can run into large files,
-+ * such as fingerprinting, so we can let API alone. For reference, the list
-+ * of 32-bit platforms which allow for sequential access of large files
-+ * without extra "magic" comprise *BSD, Darwin, IRIX...
-+ */
-+#  ifndef _FILE_OFFSET_BITS
-+#   define _FILE_OFFSET_BITS 64
-+#  endif
-+# endif
-+
-+# include 
-+# include 
-+# include "bio_lcl.h"
-+# include 
-+
-+# if !defined(OPENSSL_NO_STDIO)
-+
-+static int file_write(BIO *h, const char *buf, int num);
-+static int file_read(BIO *h, char *buf, int size);
-+static int file_puts(BIO *h, const char *str);
-+static int file_gets(BIO *h, char *str, int size);
-+static long file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int file_new(BIO *h);
-+static int file_free(BIO *data);
-+static const BIO_METHOD methods_filep = {
-+    BIO_TYPE_FILE,
-+    "FILE pointer",
-+    file_write,
-+    file_read,
-+    file_puts,
-+    file_gets,
-+    file_ctrl,
-+    file_new,
-+    file_free,
-+    NULL,
-+};
-+
-+BIO *BIO_new_file(const char *filename, const char *mode)
-+{
-+    BIO  *ret;
-+    FILE *file = openssl_fopen(filename, mode);
-+    int fp_flags = BIO_CLOSE;
-+
-+    if (strchr(mode, 'b') == NULL)
-+        fp_flags |= BIO_FP_TEXT;
-+
-+    if (file == NULL) {
-+        SYSerr(SYS_F_FOPEN, get_last_sys_error());
-+        ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
-+        if (errno == ENOENT
-+# ifdef ENXIO
-+            || errno == ENXIO
-+# endif
-+            )
-+            BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
-+        else
-+            BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
-+        return (NULL);
-+    }
-+    if ((ret = BIO_new(BIO_s_file())) == NULL) {
-+        fclose(file);
-+        return (NULL);
-+    }
-+
-+    BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
-+                                             * UPLINK */
-+    BIO_set_fp(ret, file, fp_flags);
-+    return (ret);
-+}
-+
-+BIO *BIO_new_fp(FILE *stream, int close_flag)
-+{
-+    BIO *ret;
-+
-+    if ((ret = BIO_new(BIO_s_file())) == NULL)
-+        return (NULL);
-+
-+    /* redundant flag, left for documentation purposes */
-+    BIO_set_flags(ret, BIO_FLAGS_UPLINK);
-+    BIO_set_fp(ret, stream, close_flag);
-+    return (ret);
-+}
-+
-+const BIO_METHOD *BIO_s_file(void)
-+{
-+    return (&methods_filep);
-+}
-+
-+static int file_new(BIO *bi)
-+{
-+    bi->init = 0;
-+    bi->num = 0;
-+    bi->ptr = NULL;
-+    bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */
-+    return (1);
-+}
-+
-+static int file_free(BIO *a)
-+{
-+    if (a == NULL)
-+        return (0);
-+    if (a->shutdown) {
-+        if ((a->init) && (a->ptr != NULL)) {
-+            if (a->flags & BIO_FLAGS_UPLINK)
-+                UP_fclose(a->ptr);
-+            else
-+                fclose(a->ptr);
-+            a->ptr = NULL;
-+            a->flags = BIO_FLAGS_UPLINK;
-+        }
-+        a->init = 0;
-+    }
-+    return (1);
-+}
-+
-+static int file_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0;
-+
-+    if (b->init && (out != NULL)) {
-+        if (b->flags & BIO_FLAGS_UPLINK)
-+            ret = UP_fread(out, 1, (int)outl, b->ptr);
-+        else
-+            ret = fread(out, 1, (int)outl, (FILE *)b->ptr);
-+        if (ret == 0
-+            && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) :
-+                                               ferror((FILE *)b->ptr)) {
-+            SYSerr(SYS_F_FREAD, get_last_sys_error());
-+            BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB);
-+            ret = -1;
-+        }
-+    }
-+    return (ret);
-+}
-+
-+static int file_write(BIO *b, const char *in, int inl)
-+{
-+    int ret = 0;
-+
-+    if (b->init && (in != NULL)) {
-+        if (b->flags & BIO_FLAGS_UPLINK)
-+            ret = UP_fwrite(in, (int)inl, 1, b->ptr);
-+        else
-+            ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr);
-+        if (ret)
-+            ret = inl;
-+        /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
-+        /*
-+         * according to Tim Hudson , the commented out
-+         * version above can cause 'inl' write calls under some stupid stdio
-+         * implementations (VMS)
-+         */
-+    }
-+    return (ret);
-+}
-+
-+static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    long ret = 1;
-+    FILE *fp = (FILE *)b->ptr;
-+    FILE **fpp;
-+    char p[4];
-+
-+    switch (cmd) {
-+    case BIO_C_FILE_SEEK:
-+    case BIO_CTRL_RESET:
-+        if (b->flags & BIO_FLAGS_UPLINK)
-+            ret = (long)UP_fseek(b->ptr, num, 0);
-+        else
-+            ret = (long)fseek(fp, num, 0);
-+        break;
-+    case BIO_CTRL_EOF:
-+        if (b->flags & BIO_FLAGS_UPLINK)
-+            ret = (long)UP_feof(fp);
-+        else
-+            ret = (long)feof(fp);
-+        break;
-+    case BIO_C_FILE_TELL:
-+    case BIO_CTRL_INFO:
-+        if (b->flags & BIO_FLAGS_UPLINK)
-+            ret = UP_ftell(b->ptr);
-+        else
-+            ret = ftell(fp);
-+        break;
-+    case BIO_C_SET_FILE_PTR:
-+        file_free(b);
-+        b->shutdown = (int)num & BIO_CLOSE;
-+        b->ptr = ptr;
-+        b->init = 1;
-+#  if BIO_FLAGS_UPLINK!=0
-+#   if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
-+#    define _IOB_ENTRIES 20
-+#   endif
-+        /* Safety net to catch purely internal BIO_set_fp calls */
-+#   if defined(_MSC_VER) && _MSC_VER>=1900
-+        if (ptr == stdin || ptr == stdout || ptr == stderr)
-+            BIO_clear_flags(b, BIO_FLAGS_UPLINK);
-+#   elif defined(_IOB_ENTRIES)
-+        if ((size_t)ptr >= (size_t)stdin &&
-+            (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES))
-+            BIO_clear_flags(b, BIO_FLAGS_UPLINK);
-+#   endif
-+#  endif
-+#  ifdef UP_fsetmod
-+        if (b->flags & BIO_FLAGS_UPLINK)
-+            UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b'));
-+        else
-+#  endif
-+        {
-+#  if defined(OPENSSL_SYS_WINDOWS)
-+            int fd = _fileno((FILE *)ptr);
-+            if (num & BIO_FP_TEXT)
-+                _setmode(fd, _O_TEXT);
-+            else
-+                _setmode(fd, _O_BINARY);
-+#  elif defined(OPENSSL_SYS_MSDOS)
-+            int fd = fileno((FILE *)ptr);
-+            /* Set correct text/binary mode */
-+            if (num & BIO_FP_TEXT)
-+                _setmode(fd, _O_TEXT);
-+            /* Dangerous to set stdin/stdout to raw (unless redirected) */
-+            else {
-+                if (fd == STDIN_FILENO || fd == STDOUT_FILENO) {
-+                    if (isatty(fd) <= 0)
-+                        _setmode(fd, _O_BINARY);
-+                } else
-+                    _setmode(fd, _O_BINARY);
-+            }
-+#  elif defined(OPENSSL_SYS_WIN32_CYGWIN)
-+            int fd = fileno((FILE *)ptr);
-+            if (num & BIO_FP_TEXT)
-+                setmode(fd, O_TEXT);
-+            else
-+                setmode(fd, O_BINARY);
-+#  endif
-+        }
-+        break;
-+    case BIO_C_SET_FILENAME:
-+        file_free(b);
-+        b->shutdown = (int)num & BIO_CLOSE;
-+        if (num & BIO_FP_APPEND) {
-+            if (num & BIO_FP_READ)
-+                OPENSSL_strlcpy(p, "a+", sizeof p);
-+            else
-+                OPENSSL_strlcpy(p, "a", sizeof p);
-+        } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
-+            OPENSSL_strlcpy(p, "r+", sizeof p);
-+        else if (num & BIO_FP_WRITE)
-+            OPENSSL_strlcpy(p, "w", sizeof p);
-+        else if (num & BIO_FP_READ)
-+            OPENSSL_strlcpy(p, "r", sizeof p);
-+        else {
-+            BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE);
-+            ret = 0;
-+            break;
-+        }
-+#  if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32_CYGWIN)
-+        if (!(num & BIO_FP_TEXT))
-+            strcat(p, "b");
-+        else
-+            strcat(p, "t");
-+#  endif
-+        fp = openssl_fopen(ptr, p);
-+        if (fp == NULL) {
-+            SYSerr(SYS_F_FOPEN, get_last_sys_error());
-+            ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
-+            BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
-+            ret = 0;
-+            break;
-+        }
-+        b->ptr = fp;
-+        b->init = 1;
-+        BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
-+                                               * UPLINK */
-+        break;
-+    case BIO_C_GET_FILE_PTR:
-+        /* the ptr parameter is actually a FILE ** in this case. */
-+        if (ptr != NULL) {
-+            fpp = (FILE **)ptr;
-+            *fpp = (FILE *)b->ptr;
-+        }
-+        break;
-+    case BIO_CTRL_GET_CLOSE:
-+        ret = (long)b->shutdown;
-+        break;
-+    case BIO_CTRL_SET_CLOSE:
-+        b->shutdown = (int)num;
-+        break;
-+    case BIO_CTRL_FLUSH:
-+        if (b->flags & BIO_FLAGS_UPLINK)
-+            UP_fflush(b->ptr);
-+        else
-+            fflush((FILE *)b->ptr);
-+        break;
-+    case BIO_CTRL_DUP:
-+        ret = 1;
-+        break;
-+
-+    case BIO_CTRL_WPENDING:
-+    case BIO_CTRL_PENDING:
-+    case BIO_CTRL_PUSH:
-+    case BIO_CTRL_POP:
-+    default:
-+        ret = 0;
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int file_gets(BIO *bp, char *buf, int size)
-+{
-+    int ret = 0;
-+
-+    buf[0] = '\0';
-+    if (bp->flags & BIO_FLAGS_UPLINK) {
-+        if (!UP_fgets(buf, size, bp->ptr))
-+            goto err;
-+    } else {
-+        if (!fgets(buf, size, (FILE *)bp->ptr))
-+            goto err;
-+    }
-+    if (buf[0] != '\0')
-+        ret = strlen(buf);
-+ err:
-+    return (ret);
-+}
-+
-+static int file_puts(BIO *bp, const char *str)
-+{
-+    int n, ret;
-+
-+    n = strlen(str);
-+    ret = file_write(bp, str, n);
-+    return (ret);
-+}
-+
-+#else
-+
-+static int file_write(BIO *b, const char *in, int inl)
-+{
-+    return -1;
-+}
-+static int file_read(BIO *b, char *out, int outl)
-+{
-+    return -1;
-+}
-+static int file_puts(BIO *bp, const char *str)
-+{
-+    return -1;
-+}
-+static int file_gets(BIO *bp, char *buf, int size)
-+{
-+    return 0;
-+}
-+static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    return 0;
-+}
-+static int file_new(BIO *bi)
-+{
-+    return 0;
-+}
-+static int file_free(BIO *a)
-+{
-+    return 0;
-+}
-+
-+static const BIO_METHOD methods_filep = {
-+    BIO_TYPE_FILE,
-+    "FILE pointer",
-+    file_write,
-+    file_read,
-+    file_puts,
-+    file_gets,
-+    file_ctrl,
-+    file_new,
-+    file_free,
-+    NULL,
-+};
-+
-+const BIO_METHOD *BIO_s_file(void)
-+{
-+    return (&methods_filep);
-+}
-+
-+BIO *BIO_new_file(const char *filename, const char *mode)
-+{
-+    return NULL;
-+}
-+
-+# endif                         /* OPENSSL_NO_STDIO */
-+
-+#endif                          /* HEADER_BSS_FILE_C */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_log.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_log.c
-new file mode 100644
-index 0000000..6cbde4d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_log.c
-@@ -0,0 +1,406 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Why BIO_s_log?
-+ *
-+ * BIO_s_log is useful for system daemons (or services under NT). It is
-+ * one-way BIO, it sends all stuff to syslogd (on system that commonly use
-+ * that), or event log (on NT), or OPCOM (on OpenVMS).
-+ *
-+ */
-+
-+#include 
-+#include 
-+
-+#include "bio_lcl.h"
-+#include "internal/cryptlib.h"
-+
-+#if defined(OPENSSL_SYS_WINCE)
-+#elif defined(OPENSSL_SYS_WIN32)
-+#elif defined(OPENSSL_SYS_VMS)
-+# include 
-+# include 
-+# include 
-+# include 
-+/* Some compiler options may mask the declaration of "_malloc32". */
-+# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
-+#  if __INITIAL_POINTER_SIZE == 64
-+#   pragma pointer_size save
-+#   pragma pointer_size 32
-+void *_malloc32(__size_t);
-+#   pragma pointer_size restore
-+#  endif                        /* __INITIAL_POINTER_SIZE == 64 */
-+# endif                         /* __INITIAL_POINTER_SIZE && defined
-+                                 * _ANSI_C_SOURCE */
-+#elif defined(OPENSSL_SYS_NETWARE)
-+# define NO_SYSLOG
-+#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
-+# include 
-+#endif
-+
-+#include 
-+#include 
-+
-+#ifndef NO_SYSLOG
-+
-+# if defined(OPENSSL_SYS_WIN32)
-+#  define LOG_EMERG       0
-+#  define LOG_ALERT       1
-+#  define LOG_CRIT        2
-+#  define LOG_ERR         3
-+#  define LOG_WARNING     4
-+#  define LOG_NOTICE      5
-+#  define LOG_INFO        6
-+#  define LOG_DEBUG       7
-+
-+#  define LOG_DAEMON      (3<<3)
-+# elif defined(OPENSSL_SYS_VMS)
-+/* On VMS, we don't really care about these, but we need them to compile */
-+#  define LOG_EMERG       0
-+#  define LOG_ALERT       1
-+#  define LOG_CRIT        2
-+#  define LOG_ERR         3
-+#  define LOG_WARNING     4
-+#  define LOG_NOTICE      5
-+#  define LOG_INFO        6
-+#  define LOG_DEBUG       7
-+
-+#  define LOG_DAEMON      OPC$M_NM_NTWORK
-+# endif
-+
-+static int slg_write(BIO *h, const char *buf, int num);
-+static int slg_puts(BIO *h, const char *str);
-+static long slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int slg_new(BIO *h);
-+static int slg_free(BIO *data);
-+static void xopenlog(BIO *bp, char *name, int level);
-+static void xsyslog(BIO *bp, int priority, const char *string);
-+static void xcloselog(BIO *bp);
-+
-+static const BIO_METHOD methods_slg = {
-+    BIO_TYPE_MEM, "syslog",
-+    slg_write,
-+    NULL,
-+    slg_puts,
-+    NULL,
-+    slg_ctrl,
-+    slg_new,
-+    slg_free,
-+    NULL,
-+};
-+
-+const BIO_METHOD *BIO_s_log(void)
-+{
-+    return (&methods_slg);
-+}
-+
-+static int slg_new(BIO *bi)
-+{
-+    bi->init = 1;
-+    bi->num = 0;
-+    bi->ptr = NULL;
-+    xopenlog(bi, "application", LOG_DAEMON);
-+    return (1);
-+}
-+
-+static int slg_free(BIO *a)
-+{
-+    if (a == NULL)
-+        return (0);
-+    xcloselog(a);
-+    return (1);
-+}
-+
-+static int slg_write(BIO *b, const char *in, int inl)
-+{
-+    int ret = inl;
-+    char *buf;
-+    char *pp;
-+    int priority, i;
-+    static const struct {
-+        int strl;
-+        char str[10];
-+        int log_level;
-+    } mapping[] = {
-+        {
-+            6, "PANIC ", LOG_EMERG
-+        },
-+        {
-+            6, "EMERG ", LOG_EMERG
-+        },
-+        {
-+            4, "EMR ", LOG_EMERG
-+        },
-+        {
-+            6, "ALERT ", LOG_ALERT
-+        },
-+        {
-+            4, "ALR ", LOG_ALERT
-+        },
-+        {
-+            5, "CRIT ", LOG_CRIT
-+        },
-+        {
-+            4, "CRI ", LOG_CRIT
-+        },
-+        {
-+            6, "ERROR ", LOG_ERR
-+        },
-+        {
-+            4, "ERR ", LOG_ERR
-+        },
-+        {
-+            8, "WARNING ", LOG_WARNING
-+        },
-+        {
-+            5, "WARN ", LOG_WARNING
-+        },
-+        {
-+            4, "WAR ", LOG_WARNING
-+        },
-+        {
-+            7, "NOTICE ", LOG_NOTICE
-+        },
-+        {
-+            5, "NOTE ", LOG_NOTICE
-+        },
-+        {
-+            4, "NOT ", LOG_NOTICE
-+        },
-+        {
-+            5, "INFO ", LOG_INFO
-+        },
-+        {
-+            4, "INF ", LOG_INFO
-+        },
-+        {
-+            6, "DEBUG ", LOG_DEBUG
-+        },
-+        {
-+            4, "DBG ", LOG_DEBUG
-+        },
-+        {
-+            0, "", LOG_ERR
-+        }
-+        /* The default */
-+    };
-+
-+    if ((buf = OPENSSL_malloc(inl + 1)) == NULL) {
-+        return (0);
-+    }
-+    strncpy(buf, in, inl);
-+    buf[inl] = '\0';
-+
-+    i = 0;
-+    while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0)
-+        i++;
-+    priority = mapping[i].log_level;
-+    pp = buf + mapping[i].strl;
-+
-+    xsyslog(b, priority, pp);
-+
-+    OPENSSL_free(buf);
-+    return (ret);
-+}
-+
-+static long slg_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    switch (cmd) {
-+    case BIO_CTRL_SET:
-+        xcloselog(b);
-+        xopenlog(b, ptr, num);
-+        break;
-+    default:
-+        break;
-+    }
-+    return (0);
-+}
-+
-+static int slg_puts(BIO *bp, const char *str)
-+{
-+    int n, ret;
-+
-+    n = strlen(str);
-+    ret = slg_write(bp, str, n);
-+    return (ret);
-+}
-+
-+# if defined(OPENSSL_SYS_WIN32)
-+
-+static void xopenlog(BIO *bp, char *name, int level)
-+{
-+    if (check_winnt())
-+        bp->ptr = RegisterEventSourceA(NULL, name);
-+    else
-+        bp->ptr = NULL;
-+}
-+
-+static void xsyslog(BIO *bp, int priority, const char *string)
-+{
-+    LPCSTR lpszStrings[2];
-+    WORD evtype = EVENTLOG_ERROR_TYPE;
-+    char pidbuf[DECIMAL_SIZE(DWORD) + 4];
-+
-+    if (bp->ptr == NULL)
-+        return;
-+
-+    switch (priority) {
-+    case LOG_EMERG:
-+    case LOG_ALERT:
-+    case LOG_CRIT:
-+    case LOG_ERR:
-+        evtype = EVENTLOG_ERROR_TYPE;
-+        break;
-+    case LOG_WARNING:
-+        evtype = EVENTLOG_WARNING_TYPE;
-+        break;
-+    case LOG_NOTICE:
-+    case LOG_INFO:
-+    case LOG_DEBUG:
-+        evtype = EVENTLOG_INFORMATION_TYPE;
-+        break;
-+    default:
-+        /*
-+         * Should never happen, but set it
-+         * as error anyway.
-+         */
-+        evtype = EVENTLOG_ERROR_TYPE;
-+        break;
-+    }
-+
-+    sprintf(pidbuf, "[%lu] ", GetCurrentProcessId());
-+    lpszStrings[0] = pidbuf;
-+    lpszStrings[1] = string;
-+
-+    ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL);
-+}
-+
-+static void xcloselog(BIO *bp)
-+{
-+    if (bp->ptr)
-+        DeregisterEventSource((HANDLE) (bp->ptr));
-+    bp->ptr = NULL;
-+}
-+
-+# elif defined(OPENSSL_SYS_VMS)
-+
-+static int VMS_OPC_target = LOG_DAEMON;
-+
-+static void xopenlog(BIO *bp, char *name, int level)
-+{
-+    VMS_OPC_target = level;
-+}
-+
-+static void xsyslog(BIO *bp, int priority, const char *string)
-+{
-+    struct dsc$descriptor_s opc_dsc;
-+
-+/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */
-+#  if __INITIAL_POINTER_SIZE == 64
-+#   pragma pointer_size save
-+#   pragma pointer_size 32
-+#   define OPCDEF_TYPE __char_ptr32
-+#   define OPCDEF_MALLOC _malloc32
-+#  else                         /* __INITIAL_POINTER_SIZE == 64 */
-+#   define OPCDEF_TYPE char *
-+#   define OPCDEF_MALLOC OPENSSL_malloc
-+#  endif                        /* __INITIAL_POINTER_SIZE == 64 [else] */
-+
-+    struct opcdef *opcdef_p;
-+
-+#  if __INITIAL_POINTER_SIZE == 64
-+#   pragma pointer_size restore
-+#  endif                        /* __INITIAL_POINTER_SIZE == 64 */
-+
-+    char buf[10240];
-+    unsigned int len;
-+    struct dsc$descriptor_s buf_dsc;
-+    $DESCRIPTOR(fao_cmd, "!AZ: !AZ");
-+    char *priority_tag;
-+
-+    switch (priority) {
-+    case LOG_EMERG:
-+        priority_tag = "Emergency";
-+        break;
-+    case LOG_ALERT:
-+        priority_tag = "Alert";
-+        break;
-+    case LOG_CRIT:
-+        priority_tag = "Critical";
-+        break;
-+    case LOG_ERR:
-+        priority_tag = "Error";
-+        break;
-+    case LOG_WARNING:
-+        priority_tag = "Warning";
-+        break;
-+    case LOG_NOTICE:
-+        priority_tag = "Notice";
-+        break;
-+    case LOG_INFO:
-+        priority_tag = "Info";
-+        break;
-+    case LOG_DEBUG:
-+        priority_tag = "DEBUG";
-+        break;
-+    }
-+
-+    buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
-+    buf_dsc.dsc$b_class = DSC$K_CLASS_S;
-+    buf_dsc.dsc$a_pointer = buf;
-+    buf_dsc.dsc$w_length = sizeof(buf) - 1;
-+
-+    lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string);
-+
-+    /* We know there's an 8-byte header.  That's documented. */
-+    opcdef_p = OPCDEF_MALLOC(8 + len);
-+    opcdef_p->opc$b_ms_type = OPC$_RQ_RQST;
-+    memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3);
-+    opcdef_p->opc$l_ms_rqstid = 0;
-+    memcpy(&opcdef_p->opc$l_ms_text, buf, len);
-+
-+    opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
-+    opc_dsc.dsc$b_class = DSC$K_CLASS_S;
-+    opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p;
-+    opc_dsc.dsc$w_length = len + 8;
-+
-+    sys$sndopr(opc_dsc, 0);
-+
-+    OPENSSL_free(opcdef_p);
-+}
-+
-+static void xcloselog(BIO *bp)
-+{
-+}
-+
-+# else                          /* Unix/Watt32 */
-+
-+static void xopenlog(BIO *bp, char *name, int level)
-+{
-+#  ifdef WATT32                 /* djgpp/DOS */
-+    openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level);
-+#  else
-+    openlog(name, LOG_PID | LOG_CONS, level);
-+#  endif
-+}
-+
-+static void xsyslog(BIO *bp, int priority, const char *string)
-+{
-+    syslog(priority, "%s", string);
-+}
-+
-+static void xcloselog(BIO *bp)
-+{
-+    closelog();
-+}
-+
-+# endif                         /* Unix */
-+
-+#endif                          /* NO_SYSLOG */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_mem.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_mem.c
-new file mode 100644
-index 0000000..6dc075d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_mem.c
-@@ -0,0 +1,347 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "bio_lcl.h"
-+#include "internal/cryptlib.h"
-+
-+static int mem_write(BIO *h, const char *buf, int num);
-+static int mem_read(BIO *h, char *buf, int size);
-+static int mem_puts(BIO *h, const char *str);
-+static int mem_gets(BIO *h, char *str, int size);
-+static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int mem_new(BIO *h);
-+static int secmem_new(BIO *h);
-+static int mem_free(BIO *data);
-+static int mem_buf_free(BIO *data, int free_all);
-+static int mem_buf_sync(BIO *h);
-+
-+static const BIO_METHOD mem_method = {
-+    BIO_TYPE_MEM,
-+    "memory buffer",
-+    mem_write,
-+    mem_read,
-+    mem_puts,
-+    mem_gets,
-+    mem_ctrl,
-+    mem_new,
-+    mem_free,
-+    NULL,
-+};
-+
-+static const BIO_METHOD secmem_method = {
-+    BIO_TYPE_MEM,
-+    "secure memory buffer",
-+    mem_write,
-+    mem_read,
-+    mem_puts,
-+    mem_gets,
-+    mem_ctrl,
-+    secmem_new,
-+    mem_free,
-+    NULL,
-+};
-+
-+/* BIO memory stores buffer and read pointer  */
-+typedef struct bio_buf_mem_st {
-+    struct buf_mem_st *buf;   /* allocated buffer */
-+    struct buf_mem_st *readp; /* read pointer */
-+} BIO_BUF_MEM;
-+
-+/*
-+ * bio->num is used to hold the value to return on 'empty', if it is 0,
-+ * should_retry is not set
-+ */
-+
-+const BIO_METHOD *BIO_s_mem(void)
-+{
-+    return (&mem_method);
-+}
-+
-+const BIO_METHOD *BIO_s_secmem(void)
-+{
-+    return(&secmem_method);
-+}
-+
-+BIO *BIO_new_mem_buf(const void *buf, int len)
-+{
-+    BIO *ret;
-+    BUF_MEM *b;
-+    BIO_BUF_MEM *bb;
-+    size_t sz;
-+
-+    if (buf == NULL) {
-+        BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER);
-+        return NULL;
-+    }
-+    sz = (len < 0) ? strlen(buf) : (size_t)len;
-+    if ((ret = BIO_new(BIO_s_mem())) == NULL)
-+        return NULL;
-+    bb = (BIO_BUF_MEM *)ret->ptr;
-+    b = bb->buf;
-+    /* Cast away const and trust in the MEM_RDONLY flag. */
-+    b->data = (void *)buf;
-+    b->length = sz;
-+    b->max = sz;
-+    *bb->readp = *bb->buf;
-+    ret->flags |= BIO_FLAGS_MEM_RDONLY;
-+    /* Since this is static data retrying won't help */
-+    ret->num = 0;
-+    return ret;
-+}
-+
-+static int mem_init(BIO *bi, unsigned long flags)
-+{
-+    BIO_BUF_MEM *bb = OPENSSL_zalloc(sizeof(*bb));
-+
-+    if (bb == NULL)
-+        return 0;
-+    if ((bb->buf = BUF_MEM_new_ex(flags)) == NULL) {
-+        OPENSSL_free(bb);
-+        return 0;
-+    }
-+    if ((bb->readp = OPENSSL_zalloc(sizeof(*bb->readp))) == NULL) {
-+        BUF_MEM_free(bb->buf);
-+        OPENSSL_free(bb);
-+        return 0;
-+    }
-+    *bb->readp = *bb->buf;
-+    bi->shutdown = 1;
-+    bi->init = 1;
-+    bi->num = -1;
-+    bi->ptr = (char *)bb;
-+    return 1;
-+}
-+
-+static int mem_new(BIO *bi)
-+{
-+    return (mem_init(bi, 0L));
-+}
-+
-+static int secmem_new(BIO *bi)
-+{
-+    return (mem_init(bi, BUF_MEM_FLAG_SECURE));
-+}
-+
-+static int mem_free(BIO *a)
-+{
-+    return (mem_buf_free(a, 1));
-+}
-+
-+static int mem_buf_free(BIO *a, int free_all)
-+{
-+    if (a == NULL)
-+        return (0);
-+    if (a->shutdown) {
-+        if ((a->init) && (a->ptr != NULL)) {
-+            BUF_MEM *b;
-+            BIO_BUF_MEM *bb = (BIO_BUF_MEM *)a->ptr;
-+
-+            if (bb != NULL) {
-+                b = bb->buf;
-+                if (a->flags & BIO_FLAGS_MEM_RDONLY)
-+                    b->data = NULL;
-+                BUF_MEM_free(b);
-+                if (free_all) {
-+                    OPENSSL_free(bb->readp);
-+                    OPENSSL_free(bb);
-+                }
-+            }
-+            a->ptr = NULL;
-+        }
-+    }
-+    return (1);
-+}
-+
-+/*
-+ * Reallocate memory buffer if read pointer differs
-+ */
-+static int mem_buf_sync(BIO *b)
-+{
-+    if (b != NULL && b->init != 0 && b->ptr != NULL) {
-+        BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
-+
-+        if (bbm->readp->data != bbm->buf->data) {
-+            memmove(bbm->buf->data, bbm->readp->data, bbm->readp->length);
-+            bbm->buf->length = bbm->readp->length;
-+            bbm->readp->data = bbm->buf->data;
-+        }
-+    }
-+    return (0);
-+}
-+
-+static int mem_read(BIO *b, char *out, int outl)
-+{
-+    int ret = -1;
-+    BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
-+    BUF_MEM *bm = bbm->readp;
-+
-+    BIO_clear_retry_flags(b);
-+    ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
-+    if ((out != NULL) && (ret > 0)) {
-+        memcpy(out, bm->data, ret);
-+        bm->length -= ret;
-+        bm->data += ret;
-+    } else if (bm->length == 0) {
-+        ret = b->num;
-+        if (ret != 0)
-+            BIO_set_retry_read(b);
-+    }
-+    return (ret);
-+}
-+
-+static int mem_write(BIO *b, const char *in, int inl)
-+{
-+    int ret = -1;
-+    int blen;
-+    BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
-+
-+    if (in == NULL) {
-+        BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER);
-+        goto end;
-+    }
-+    if (b->flags & BIO_FLAGS_MEM_RDONLY) {
-+        BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO);
-+        goto end;
-+    }
-+    BIO_clear_retry_flags(b);
-+    blen = bbm->readp->length;
-+    mem_buf_sync(b);
-+    if (BUF_MEM_grow_clean(bbm->buf, blen + inl) == 0)
-+        goto end;
-+    memcpy(bbm->buf->data + blen, in, inl);
-+    *bbm->readp = *bbm->buf;
-+    ret = inl;
-+ end:
-+    return (ret);
-+}
-+
-+static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    long ret = 1;
-+    char **pptr;
-+    BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
-+    BUF_MEM *bm;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        bm = bbm->buf;
-+        if (bm->data != NULL) {
-+            /* For read only case reset to the start again */
-+            if ((b->flags & BIO_FLAGS_MEM_RDONLY) || (b->flags & BIO_FLAGS_NONCLEAR_RST)) {
-+                bm->length = bm->max;
-+            } else {
-+                memset(bm->data, 0, bm->max);
-+                bm->length = 0;
-+            }
-+            *bbm->readp = *bbm->buf;
-+        }
-+        break;
-+    case BIO_CTRL_EOF:
-+        bm = bbm->readp;
-+        ret = (long)(bm->length == 0);
-+        break;
-+    case BIO_C_SET_BUF_MEM_EOF_RETURN:
-+        b->num = (int)num;
-+        break;
-+    case BIO_CTRL_INFO:
-+        bm = bbm->readp;
-+        ret = (long)bm->length;
-+        if (ptr != NULL) {
-+            pptr = (char **)ptr;
-+            *pptr = (char *)&(bm->data[0]);
-+        }
-+        break;
-+    case BIO_C_SET_BUF_MEM:
-+        mem_buf_free(b, 0);
-+        b->shutdown = (int)num;
-+        bbm->buf = ptr;
-+        *bbm->readp = *bbm->buf;
-+        b->ptr = bbm;
-+        break;
-+    case BIO_C_GET_BUF_MEM_PTR:
-+        if (ptr != NULL) {
-+            mem_buf_sync(b);
-+            bm = bbm->readp;
-+            pptr = (char **)ptr;
-+            *pptr = (char *)bm;
-+        }
-+        break;
-+    case BIO_CTRL_GET_CLOSE:
-+        ret = (long)b->shutdown;
-+        break;
-+    case BIO_CTRL_SET_CLOSE:
-+        b->shutdown = (int)num;
-+        break;
-+    case BIO_CTRL_WPENDING:
-+        ret = 0L;
-+        break;
-+    case BIO_CTRL_PENDING:
-+        bm = bbm->readp;
-+        ret = (long)bm->length;
-+        break;
-+    case BIO_CTRL_DUP:
-+    case BIO_CTRL_FLUSH:
-+        ret = 1;
-+        break;
-+    case BIO_CTRL_PUSH:
-+    case BIO_CTRL_POP:
-+    default:
-+        ret = 0;
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int mem_gets(BIO *bp, char *buf, int size)
-+{
-+    int i, j;
-+    int ret = -1;
-+    char *p;
-+    BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr;
-+    BUF_MEM *bm = bbm->readp;
-+
-+    BIO_clear_retry_flags(bp);
-+    j = bm->length;
-+    if ((size - 1) < j)
-+        j = size - 1;
-+    if (j <= 0) {
-+        *buf = '\0';
-+        return 0;
-+    }
-+    p = bm->data;
-+    for (i = 0; i < j; i++) {
-+        if (p[i] == '\n') {
-+            i++;
-+            break;
-+        }
-+    }
-+
-+    /*
-+     * i is now the max num of bytes to copy, either j or up to
-+     * and including the first newline
-+     */
-+
-+    i = mem_read(bp, buf, i);
-+    if (i > 0)
-+        buf[i] = '\0';
-+    ret = i;
-+    return (ret);
-+}
-+
-+static int mem_puts(BIO *bp, const char *str)
-+{
-+    int n, ret;
-+
-+    n = strlen(str);
-+    ret = mem_write(bp, str, n);
-+    /* memory semantics is that it will always work */
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_null.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_null.c
-new file mode 100644
-index 0000000..e5c4adc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_null.c
-@@ -0,0 +1,100 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "bio_lcl.h"
-+#include "internal/cryptlib.h"
-+
-+static int null_write(BIO *h, const char *buf, int num);
-+static int null_read(BIO *h, char *buf, int size);
-+static int null_puts(BIO *h, const char *str);
-+static int null_gets(BIO *h, char *str, int size);
-+static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int null_new(BIO *h);
-+static int null_free(BIO *data);
-+static const BIO_METHOD null_method = {
-+    BIO_TYPE_NULL,
-+    "NULL",
-+    null_write,
-+    null_read,
-+    null_puts,
-+    null_gets,
-+    null_ctrl,
-+    null_new,
-+    null_free,
-+    NULL,
-+};
-+
-+const BIO_METHOD *BIO_s_null(void)
-+{
-+    return (&null_method);
-+}
-+
-+static int null_new(BIO *bi)
-+{
-+    bi->init = 1;
-+    bi->num = 0;
-+    bi->ptr = (NULL);
-+    return (1);
-+}
-+
-+static int null_free(BIO *a)
-+{
-+    if (a == NULL)
-+        return (0);
-+    return (1);
-+}
-+
-+static int null_read(BIO *b, char *out, int outl)
-+{
-+    return (0);
-+}
-+
-+static int null_write(BIO *b, const char *in, int inl)
-+{
-+    return (inl);
-+}
-+
-+static long null_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    long ret = 1;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+    case BIO_CTRL_EOF:
-+    case BIO_CTRL_SET:
-+    case BIO_CTRL_SET_CLOSE:
-+    case BIO_CTRL_FLUSH:
-+    case BIO_CTRL_DUP:
-+        ret = 1;
-+        break;
-+    case BIO_CTRL_GET_CLOSE:
-+    case BIO_CTRL_INFO:
-+    case BIO_CTRL_GET:
-+    case BIO_CTRL_PENDING:
-+    case BIO_CTRL_WPENDING:
-+    default:
-+        ret = 0;
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int null_gets(BIO *bp, char *buf, int size)
-+{
-+    return (0);
-+}
-+
-+static int null_puts(BIO *bp, const char *str)
-+{
-+    if (str == NULL)
-+        return (0);
-+    return (strlen(str));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_sock.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_sock.c
-new file mode 100644
-index 0000000..570e898
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/bss_sock.c
-@@ -0,0 +1,231 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#define USE_SOCKETS
-+#include "bio_lcl.h"
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_SOCK
-+
-+# include 
-+
-+# ifdef WATT32
-+/* Watt-32 uses same names */
-+#  undef sock_write
-+#  undef sock_read
-+#  undef sock_puts
-+#  define sock_write SockWrite
-+#  define sock_read  SockRead
-+#  define sock_puts  SockPuts
-+# endif
-+
-+static int sock_write(BIO *h, const char *buf, int num);
-+static int sock_read(BIO *h, char *buf, int size);
-+static int sock_puts(BIO *h, const char *str);
-+static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int sock_new(BIO *h);
-+static int sock_free(BIO *data);
-+int BIO_sock_should_retry(int s);
-+
-+static const BIO_METHOD methods_sockp = {
-+    BIO_TYPE_SOCKET,
-+    "socket",
-+    sock_write,
-+    sock_read,
-+    sock_puts,
-+    NULL,                       /* sock_gets, */
-+    sock_ctrl,
-+    sock_new,
-+    sock_free,
-+    NULL,
-+};
-+
-+const BIO_METHOD *BIO_s_socket(void)
-+{
-+    return (&methods_sockp);
-+}
-+
-+BIO *BIO_new_socket(int fd, int close_flag)
-+{
-+    BIO *ret;
-+
-+    ret = BIO_new(BIO_s_socket());
-+    if (ret == NULL)
-+        return (NULL);
-+    BIO_set_fd(ret, fd, close_flag);
-+    return (ret);
-+}
-+
-+static int sock_new(BIO *bi)
-+{
-+    bi->init = 0;
-+    bi->num = 0;
-+    bi->ptr = NULL;
-+    bi->flags = 0;
-+    return (1);
-+}
-+
-+static int sock_free(BIO *a)
-+{
-+    if (a == NULL)
-+        return (0);
-+    if (a->shutdown) {
-+        if (a->init) {
-+            BIO_closesocket(a->num);
-+        }
-+        a->init = 0;
-+        a->flags = 0;
-+    }
-+    return (1);
-+}
-+
-+static int sock_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0;
-+
-+    if (out != NULL) {
-+        clear_socket_error();
-+        ret = readsocket(b->num, out, outl);
-+        BIO_clear_retry_flags(b);
-+        if (ret <= 0) {
-+            if (BIO_sock_should_retry(ret))
-+                BIO_set_retry_read(b);
-+        }
-+    }
-+    return (ret);
-+}
-+
-+static int sock_write(BIO *b, const char *in, int inl)
-+{
-+    int ret;
-+
-+    clear_socket_error();
-+    ret = writesocket(b->num, in, inl);
-+    BIO_clear_retry_flags(b);
-+    if (ret <= 0) {
-+        if (BIO_sock_should_retry(ret))
-+            BIO_set_retry_write(b);
-+    }
-+    return (ret);
-+}
-+
-+static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    long ret = 1;
-+    int *ip;
-+
-+    switch (cmd) {
-+    case BIO_C_SET_FD:
-+        sock_free(b);
-+        b->num = *((int *)ptr);
-+        b->shutdown = (int)num;
-+        b->init = 1;
-+        break;
-+    case BIO_C_GET_FD:
-+        if (b->init) {
-+            ip = (int *)ptr;
-+            if (ip != NULL)
-+                *ip = b->num;
-+            ret = b->num;
-+        } else
-+            ret = -1;
-+        break;
-+    case BIO_CTRL_GET_CLOSE:
-+        ret = b->shutdown;
-+        break;
-+    case BIO_CTRL_SET_CLOSE:
-+        b->shutdown = (int)num;
-+        break;
-+    case BIO_CTRL_DUP:
-+    case BIO_CTRL_FLUSH:
-+        ret = 1;
-+        break;
-+    default:
-+        ret = 0;
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int sock_puts(BIO *bp, const char *str)
-+{
-+    int n, ret;
-+
-+    n = strlen(str);
-+    ret = sock_write(bp, str, n);
-+    return (ret);
-+}
-+
-+int BIO_sock_should_retry(int i)
-+{
-+    int err;
-+
-+    if ((i == 0) || (i == -1)) {
-+        err = get_last_socket_error();
-+
-+        return (BIO_sock_non_fatal_error(err));
-+    }
-+    return (0);
-+}
-+
-+int BIO_sock_non_fatal_error(int err)
-+{
-+    switch (err) {
-+# if defined(OPENSSL_SYS_WINDOWS)
-+#  if defined(WSAEWOULDBLOCK)
-+    case WSAEWOULDBLOCK:
-+#  endif
-+# endif
-+
-+# ifdef EWOULDBLOCK
-+#  ifdef WSAEWOULDBLOCK
-+#   if WSAEWOULDBLOCK != EWOULDBLOCK
-+    case EWOULDBLOCK:
-+#   endif
-+#  else
-+    case EWOULDBLOCK:
-+#  endif
-+# endif
-+
-+# if defined(ENOTCONN)
-+    case ENOTCONN:
-+# endif
-+
-+# ifdef EINTR
-+    case EINTR:
-+# endif
-+
-+# ifdef EAGAIN
-+#  if EWOULDBLOCK != EAGAIN
-+    case EAGAIN:
-+#  endif
-+# endif
-+
-+# ifdef EPROTO
-+    case EPROTO:
-+# endif
-+
-+# ifdef EINPROGRESS
-+    case EINPROGRESS:
-+# endif
-+
-+# ifdef EALREADY
-+    case EALREADY:
-+# endif
-+        return (1);
-+        /* break; */
-+    default:
-+        break;
-+    }
-+    return (0);
-+}
-+
-+#endif                          /* #ifndef OPENSSL_NO_SOCK */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/build.info
-new file mode 100644
-index 0000000..d1e7d73
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bio/build.info
-@@ -0,0 +1,8 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        bio_lib.c bio_cb.c bio_err.c \
-+        bss_mem.c bss_null.c bss_fd.c \
-+        bss_file.c bss_sock.c bss_conn.c \
-+        bf_null.c bf_buff.c b_print.c b_dump.c b_addr.c \
-+        b_sock.c b_sock2.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c \
-+        bss_dgram.c bio_meth.c bf_lbuf.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2_impl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2_impl.h
-new file mode 100644
-index 0000000..8fe5c95
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2_impl.h
-@@ -0,0 +1,130 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
-+ * Copyright 2012, Samuel Neves 
-+ * More information about the BLAKE2 hash function and its implementations
-+ * can be found at https://blake2.net.
-+ */
-+
-+#include 
-+#include "e_os.h"
-+
-+static ossl_inline uint32_t load32(const uint8_t *src)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+
-+    if (is_endian.little) {
-+        uint32_t w;
-+        memcpy(&w, src, sizeof(w));
-+        return w;
-+    } else {
-+        uint32_t w = ((uint32_t)src[0])
-+                   | ((uint32_t)src[1] <<  8)
-+                   | ((uint32_t)src[2] << 16)
-+                   | ((uint32_t)src[3] << 24);
-+        return w;
-+    }
-+}
-+
-+static ossl_inline uint64_t load64(const uint8_t *src)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+
-+    if (is_endian.little) {
-+        uint64_t w;
-+        memcpy(&w, src, sizeof(w));
-+        return w;
-+    } else {
-+        uint64_t w = ((uint64_t)src[0])
-+                   | ((uint64_t)src[1] <<  8)
-+                   | ((uint64_t)src[2] << 16)
-+                   | ((uint64_t)src[3] << 24)
-+                   | ((uint64_t)src[4] << 32)
-+                   | ((uint64_t)src[5] << 40)
-+                   | ((uint64_t)src[6] << 48)
-+                   | ((uint64_t)src[7] << 56);
-+        return w;
-+    }
-+}
-+
-+static ossl_inline void store32(uint8_t *dst, uint32_t w)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+
-+    if (is_endian.little) {
-+        memcpy(dst, &w, sizeof(w));
-+    } else {
-+        uint8_t *p = (uint8_t *)dst;
-+        int i;
-+
-+        for (i = 0; i < 4; i++)
-+            p[i] = (uint8_t)(w >> (8 * i));
-+    }
-+}
-+
-+static ossl_inline void store64(uint8_t *dst, uint64_t w)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+
-+    if (is_endian.little) {
-+        memcpy(dst, &w, sizeof(w));
-+    } else {
-+        uint8_t *p = (uint8_t *)dst;
-+        int i;
-+
-+        for (i = 0; i < 8; i++)
-+            p[i] = (uint8_t)(w >> (8 * i));
-+    }
-+}
-+
-+static ossl_inline uint64_t load48(const uint8_t *src)
-+{
-+    uint64_t w = ((uint64_t)src[0])
-+               | ((uint64_t)src[1] <<  8)
-+               | ((uint64_t)src[2] << 16)
-+               | ((uint64_t)src[3] << 24)
-+               | ((uint64_t)src[4] << 32)
-+               | ((uint64_t)src[5] << 40);
-+    return w;
-+}
-+
-+static ossl_inline void store48(uint8_t *dst, uint64_t w)
-+{
-+    uint8_t *p = (uint8_t *)dst;
-+    p[0] = (uint8_t)w;
-+    p[1] = (uint8_t)(w>>8);
-+    p[2] = (uint8_t)(w>>16);
-+    p[3] = (uint8_t)(w>>24);
-+    p[4] = (uint8_t)(w>>32);
-+    p[5] = (uint8_t)(w>>40);
-+}
-+
-+static ossl_inline uint32_t rotr32(const uint32_t w, const unsigned int c)
-+{
-+    return (w >> c) | (w << (32 - c));
-+}
-+
-+static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c)
-+{
-+    return (w >> c) | (w << (64 - c));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2_locl.h
-new file mode 100644
-index 0000000..fb7beb9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2_locl.h
-@@ -0,0 +1,91 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
-+ * Copyright 2012, Samuel Neves 
-+ * More information about the BLAKE2 hash function and its implementations
-+ * can be found at https://blake2.net.
-+ */
-+
-+#include 
-+#include "e_os.h"
-+
-+#define BLAKE2S_BLOCKBYTES    64
-+#define BLAKE2S_OUTBYTES      32
-+#define BLAKE2S_KEYBYTES      32
-+#define BLAKE2S_SALTBYTES     8
-+#define BLAKE2S_PERSONALBYTES 8
-+
-+#define BLAKE2B_BLOCKBYTES    128
-+#define BLAKE2B_OUTBYTES      64
-+#define BLAKE2B_KEYBYTES      64
-+#define BLAKE2B_SALTBYTES     16
-+#define BLAKE2B_PERSONALBYTES 16
-+
-+struct blake2s_param_st {
-+    uint8_t  digest_length; /* 1 */
-+    uint8_t  key_length;    /* 2 */
-+    uint8_t  fanout;        /* 3 */
-+    uint8_t  depth;         /* 4 */
-+    uint8_t  leaf_length[4];/* 8 */
-+    uint8_t  node_offset[6];/* 14 */
-+    uint8_t  node_depth;    /* 15 */
-+    uint8_t  inner_length;  /* 16 */
-+    uint8_t  salt[BLAKE2S_SALTBYTES]; /* 24 */
-+    uint8_t  personal[BLAKE2S_PERSONALBYTES];  /* 32 */
-+};
-+
-+typedef struct blake2s_param_st BLAKE2S_PARAM;
-+
-+struct blake2s_ctx_st {
-+    uint32_t h[8];
-+    uint32_t t[2];
-+    uint32_t f[2];
-+    uint8_t  buf[BLAKE2S_BLOCKBYTES];
-+    size_t   buflen;
-+};
-+
-+struct blake2b_param_st {
-+    uint8_t  digest_length; /* 1 */
-+    uint8_t  key_length;    /* 2 */
-+    uint8_t  fanout;        /* 3 */
-+    uint8_t  depth;         /* 4 */
-+    uint8_t  leaf_length[4];/* 8 */
-+    uint8_t  node_offset[8];/* 16 */
-+    uint8_t  node_depth;    /* 17 */
-+    uint8_t  inner_length;  /* 18 */
-+    uint8_t  reserved[14];  /* 32 */
-+    uint8_t  salt[BLAKE2B_SALTBYTES]; /* 48 */
-+    uint8_t  personal[BLAKE2B_PERSONALBYTES];  /* 64 */
-+};
-+
-+typedef struct blake2b_param_st BLAKE2B_PARAM;
-+
-+struct blake2b_ctx_st {
-+    uint64_t h[8];
-+    uint64_t t[2];
-+    uint64_t f[2];
-+    uint8_t  buf[BLAKE2B_BLOCKBYTES];
-+    size_t   buflen;
-+};
-+
-+#define BLAKE2B_DIGEST_LENGTH 64
-+#define BLAKE2S_DIGEST_LENGTH 32
-+
-+typedef struct blake2s_ctx_st BLAKE2S_CTX;
-+typedef struct blake2b_ctx_st BLAKE2B_CTX;
-+
-+int BLAKE2b_Init(BLAKE2B_CTX *c);
-+int BLAKE2b_Update(BLAKE2B_CTX *c, const void *data, size_t datalen);
-+int BLAKE2b_Final(unsigned char *md, BLAKE2B_CTX *c);
-+
-+int BLAKE2s_Init(BLAKE2S_CTX *c);
-+int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen);
-+int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2b.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2b.c
-new file mode 100644
-index 0000000..e77bd9a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2b.c
-@@ -0,0 +1,270 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
-+ * Copyright 2012, Samuel Neves 
-+ * More information about the BLAKE2 hash function and its implementations
-+ * can be found at https://blake2.net.
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "e_os.h"
-+
-+#include "blake2_locl.h"
-+#include "blake2_impl.h"
-+
-+static const uint64_t blake2b_IV[8] =
-+{
-+    0x6a09e667f3bcc908U, 0xbb67ae8584caa73bU,
-+    0x3c6ef372fe94f82bU, 0xa54ff53a5f1d36f1U,
-+    0x510e527fade682d1U, 0x9b05688c2b3e6c1fU,
-+    0x1f83d9abfb41bd6bU, 0x5be0cd19137e2179U
-+};
-+
-+static const uint8_t blake2b_sigma[12][16] =
-+{
-+    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
-+    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
-+    { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
-+    {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
-+    {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
-+    {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
-+    { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
-+    { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
-+    {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
-+    { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
-+    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
-+    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 }
-+};
-+
-+/* Set that it's the last block we'll compress */
-+static ossl_inline void blake2b_set_lastblock(BLAKE2B_CTX *S)
-+{
-+    S->f[0] = -1;
-+}
-+
-+/* Initialize the hashing state. */
-+static ossl_inline void blake2b_init0(BLAKE2B_CTX *S)
-+{
-+    int i;
-+
-+    memset(S, 0, sizeof(BLAKE2B_CTX));
-+    for (i = 0; i < 8; ++i) {
-+        S->h[i] = blake2b_IV[i];
-+    }
-+}
-+
-+/* init xors IV with input parameter block */
-+static void blake2b_init_param(BLAKE2B_CTX *S, const BLAKE2B_PARAM *P)
-+{
-+    size_t i;
-+    const uint8_t *p = (const uint8_t *)(P);
-+    blake2b_init0(S);
-+
-+    /* The param struct is carefully hand packed, and should be 64 bytes on
-+     * every platform. */
-+    assert(sizeof(BLAKE2B_PARAM) == 64);
-+    /* IV XOR ParamBlock */
-+    for (i = 0; i < 8; ++i) {
-+        S->h[i] ^= load64(p + sizeof(S->h[i]) * i);
-+    }
-+}
-+
-+/* Initialize the hashing context.  Always returns 1. */
-+int BLAKE2b_Init(BLAKE2B_CTX *c)
-+{
-+    BLAKE2B_PARAM P[1];
-+    P->digest_length = BLAKE2B_DIGEST_LENGTH;
-+    P->key_length    = 0;
-+    P->fanout        = 1;
-+    P->depth         = 1;
-+    store32(P->leaf_length, 0);
-+    store64(P->node_offset, 0);
-+    P->node_depth    = 0;
-+    P->inner_length  = 0;
-+    memset(P->reserved, 0, sizeof(P->reserved));
-+    memset(P->salt,     0, sizeof(P->salt));
-+    memset(P->personal, 0, sizeof(P->personal));
-+    blake2b_init_param(c, P);
-+    return 1;
-+}
-+
-+/* Permute the state while xoring in the block of data. */
-+static void blake2b_compress(BLAKE2B_CTX *S,
-+                            const uint8_t *blocks,
-+                            size_t len)
-+{
-+    uint64_t m[16];
-+    uint64_t v[16];
-+    int i;
-+    size_t increment;
-+
-+    /*
-+     * There are two distinct usage vectors for this function:
-+     *
-+     * a) BLAKE2b_Update uses it to process complete blocks,
-+     *    possibly more than one at a time;
-+     *
-+     * b) BLAK2b_Final uses it to process last block, always
-+     *    single but possibly incomplete, in which case caller
-+     *    pads input with zeros.
-+     */
-+    assert(len < BLAKE2B_BLOCKBYTES || len % BLAKE2B_BLOCKBYTES == 0);
-+
-+    /*
-+     * Since last block is always processed with separate call,
-+     * |len| not being multiple of complete blocks can be observed
-+     * only with |len| being less than BLAKE2B_BLOCKBYTES ("less"
-+     * including even zero), which is why following assignment doesn't
-+     * have to reside inside the main loop below.
-+     */
-+    increment = len < BLAKE2B_BLOCKBYTES ? len : BLAKE2B_BLOCKBYTES;
-+
-+    for (i = 0; i < 8; ++i) {
-+        v[i] = S->h[i];
-+    }
-+
-+    do {
-+        for (i = 0; i < 16; ++i) {
-+            m[i] = load64(blocks + i * sizeof(m[i]));
-+        }
-+
-+        /* blake2b_increment_counter */
-+        S->t[0] += increment;
-+        S->t[1] += (S->t[0] < increment);
-+
-+        v[8]  = blake2b_IV[0];
-+        v[9]  = blake2b_IV[1];
-+        v[10] = blake2b_IV[2];
-+        v[11] = blake2b_IV[3];
-+        v[12] = S->t[0] ^ blake2b_IV[4];
-+        v[13] = S->t[1] ^ blake2b_IV[5];
-+        v[14] = S->f[0] ^ blake2b_IV[6];
-+        v[15] = S->f[1] ^ blake2b_IV[7];
-+#define G(r,i,a,b,c,d) \
-+        do { \
-+            a = a + b + m[blake2b_sigma[r][2*i+0]]; \
-+            d = rotr64(d ^ a, 32); \
-+            c = c + d; \
-+            b = rotr64(b ^ c, 24); \
-+            a = a + b + m[blake2b_sigma[r][2*i+1]]; \
-+            d = rotr64(d ^ a, 16); \
-+            c = c + d; \
-+            b = rotr64(b ^ c, 63); \
-+        } while (0)
-+#define ROUND(r)  \
-+        do { \
-+            G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
-+            G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
-+            G(r,2,v[ 2],v[ 6],v[10],v[14]); \
-+            G(r,3,v[ 3],v[ 7],v[11],v[15]); \
-+            G(r,4,v[ 0],v[ 5],v[10],v[15]); \
-+            G(r,5,v[ 1],v[ 6],v[11],v[12]); \
-+            G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
-+            G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
-+        } while (0)
-+#if defined(OPENSSL_SMALL_FOOTPRINT)
-+        /* 3x size reduction on x86_64, almost 7x on ARMv8, 9x on ARMv4 */
-+        for (i = 0; i < 12; i++) {
-+            ROUND(i);
-+        }
-+#else
-+        ROUND(0);
-+        ROUND(1);
-+        ROUND(2);
-+        ROUND(3);
-+        ROUND(4);
-+        ROUND(5);
-+        ROUND(6);
-+        ROUND(7);
-+        ROUND(8);
-+        ROUND(9);
-+        ROUND(10);
-+        ROUND(11);
-+#endif
-+
-+        for (i = 0; i < 8; ++i) {
-+            S->h[i] = v[i] ^= v[i + 8] ^ S->h[i];
-+        }
-+#undef G
-+#undef ROUND
-+        blocks += increment;
-+        len -= increment;
-+    } while (len);
-+}
-+
-+/* Absorb the input data into the hash state.  Always returns 1. */
-+int BLAKE2b_Update(BLAKE2B_CTX *c, const void *data, size_t datalen)
-+{
-+    const uint8_t *in = data;
-+    size_t fill;
-+
-+    /*
-+     * Intuitively one would expect intermediate buffer, c->buf, to
-+     * store incomplete blocks. But in this case we are interested to
-+     * temporarily stash even complete blocks, because last one in the
-+     * stream has to be treated in special way, and at this point we
-+     * don't know if last block in *this* call is last one "ever". This
-+     * is the reason for why |datalen| is compared as >, and not >=.
-+     */
-+    fill = sizeof(c->buf) - c->buflen;
-+    if (datalen > fill) {
-+        if (c->buflen) {
-+            memcpy(c->buf + c->buflen, in, fill); /* Fill buffer */
-+            blake2b_compress(c, c->buf, BLAKE2B_BLOCKBYTES);
-+            c->buflen = 0;
-+            in += fill;
-+            datalen -= fill;
-+        }
-+        if (datalen > BLAKE2B_BLOCKBYTES) {
-+            size_t stashlen = datalen % BLAKE2B_BLOCKBYTES;
-+            /*
-+             * If |datalen| is a multiple of the blocksize, stash
-+             * last complete block, it can be final one...
-+             */
-+            stashlen = stashlen ? stashlen : BLAKE2B_BLOCKBYTES;
-+            datalen -= stashlen;
-+            blake2b_compress(c, in, datalen);
-+            in += datalen;
-+            datalen = stashlen;
-+        }
-+    }
-+
-+    assert(datalen <= BLAKE2B_BLOCKBYTES);
-+
-+    memcpy(c->buf + c->buflen, in, datalen);
-+    c->buflen += datalen; /* Be lazy, do not compress */
-+
-+    return 1;
-+}
-+
-+/*
-+ * Calculate the final hash and save it in md.
-+ * Always returns 1.
-+ */
-+int BLAKE2b_Final(unsigned char *md, BLAKE2B_CTX *c)
-+{
-+    int i;
-+
-+    blake2b_set_lastblock(c);
-+    /* Padding */
-+    memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen);
-+    blake2b_compress(c, c->buf, c->buflen);
-+
-+    /* Output full hash to message digest */
-+    for (i = 0; i < 8; ++i) {
-+        store64(md + sizeof(c->h[i]) * i, c->h[i]);
-+    }
-+
-+    OPENSSL_cleanse(c, sizeof(BLAKE2B_CTX));
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2s.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2s.c
-new file mode 100644
-index 0000000..0b3503e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/blake2s.c
-@@ -0,0 +1,264 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
-+ * Copyright 2012, Samuel Neves 
-+ * More information about the BLAKE2 hash function and its implementations
-+ * can be found at https://blake2.net.
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "e_os.h"
-+
-+#include "blake2_locl.h"
-+#include "blake2_impl.h"
-+
-+static const uint32_t blake2s_IV[8] =
-+{
-+    0x6A09E667U, 0xBB67AE85U, 0x3C6EF372U, 0xA54FF53AU,
-+    0x510E527FU, 0x9B05688CU, 0x1F83D9ABU, 0x5BE0CD19U
-+};
-+
-+static const uint8_t blake2s_sigma[10][16] =
-+{
-+    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
-+    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
-+    { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
-+    {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
-+    {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
-+    {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
-+    { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
-+    { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
-+    {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
-+    { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
-+};
-+
-+/* Set that it's the last block we'll compress */
-+static ossl_inline void blake2s_set_lastblock(BLAKE2S_CTX *S)
-+{
-+    S->f[0] = -1;
-+}
-+
-+/* Initialize the hashing state. */
-+static ossl_inline void blake2s_init0(BLAKE2S_CTX *S)
-+{
-+    int i;
-+
-+    memset(S, 0, sizeof(BLAKE2S_CTX));
-+    for (i = 0; i < 8; ++i) {
-+        S->h[i] = blake2s_IV[i];
-+    }
-+}
-+
-+/* init2 xors IV with input parameter block */
-+static void blake2s_init_param(BLAKE2S_CTX *S, const BLAKE2S_PARAM *P)
-+{
-+    const uint8_t *p = (const uint8_t *)(P);
-+    size_t i;
-+
-+    /* The param struct is carefully hand packed, and should be 32 bytes on
-+     * every platform. */
-+    assert(sizeof(BLAKE2S_PARAM) == 32);
-+    blake2s_init0(S);
-+    /* IV XOR ParamBlock */
-+    for (i = 0; i < 8; ++i) {
-+        S->h[i] ^= load32(&p[i*4]);
-+    }
-+}
-+
-+/* Initialize the hashing context.  Always returns 1. */
-+int BLAKE2s_Init(BLAKE2S_CTX *c)
-+{
-+    BLAKE2S_PARAM P[1];
-+
-+    P->digest_length = BLAKE2S_DIGEST_LENGTH;
-+    P->key_length    = 0;
-+    P->fanout        = 1;
-+    P->depth         = 1;
-+    store32(P->leaf_length, 0);
-+    store48(P->node_offset, 0);
-+    P->node_depth    = 0;
-+    P->inner_length  = 0;
-+    memset(P->salt,     0, sizeof(P->salt));
-+    memset(P->personal, 0, sizeof(P->personal));
-+    blake2s_init_param(c, P);
-+    return 1;
-+}
-+
-+/* Permute the state while xoring in the block of data. */
-+static void blake2s_compress(BLAKE2S_CTX *S,
-+                            const uint8_t *blocks,
-+                            size_t len)
-+{
-+    uint32_t m[16];
-+    uint32_t v[16];
-+    size_t i;
-+    size_t increment;
-+
-+    /*
-+     * There are two distinct usage vectors for this function:
-+     *
-+     * a) BLAKE2s_Update uses it to process complete blocks,
-+     *    possibly more than one at a time;
-+     *
-+     * b) BLAK2s_Final uses it to process last block, always
-+     *    single but possibly incomplete, in which case caller
-+     *    pads input with zeros.
-+     */
-+    assert(len < BLAKE2S_BLOCKBYTES || len % BLAKE2S_BLOCKBYTES == 0);
-+
-+    /*
-+     * Since last block is always processed with separate call,
-+     * |len| not being multiple of complete blocks can be observed
-+     * only with |len| being less than BLAKE2S_BLOCKBYTES ("less"
-+     * including even zero), which is why following assignment doesn't
-+     * have to reside inside the main loop below.
-+     */
-+    increment = len < BLAKE2S_BLOCKBYTES ? len : BLAKE2S_BLOCKBYTES;
-+
-+    for (i = 0; i < 8; ++i) {
-+        v[i] = S->h[i];
-+    }
-+
-+    do {
-+        for (i = 0; i < 16; ++i) {
-+            m[i] = load32(blocks + i * sizeof(m[i]));
-+        }
-+
-+        /* blake2s_increment_counter */
-+        S->t[0] += increment;
-+        S->t[1] += (S->t[0] < increment);
-+
-+        v[ 8] = blake2s_IV[0];
-+        v[ 9] = blake2s_IV[1];
-+        v[10] = blake2s_IV[2];
-+        v[11] = blake2s_IV[3];
-+        v[12] = S->t[0] ^ blake2s_IV[4];
-+        v[13] = S->t[1] ^ blake2s_IV[5];
-+        v[14] = S->f[0] ^ blake2s_IV[6];
-+        v[15] = S->f[1] ^ blake2s_IV[7];
-+#define G(r,i,a,b,c,d) \
-+        do { \
-+            a = a + b + m[blake2s_sigma[r][2*i+0]]; \
-+            d = rotr32(d ^ a, 16); \
-+            c = c + d; \
-+            b = rotr32(b ^ c, 12); \
-+            a = a + b + m[blake2s_sigma[r][2*i+1]]; \
-+            d = rotr32(d ^ a, 8); \
-+            c = c + d; \
-+            b = rotr32(b ^ c, 7); \
-+        } while (0)
-+#define ROUND(r)  \
-+        do { \
-+            G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
-+            G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
-+            G(r,2,v[ 2],v[ 6],v[10],v[14]); \
-+            G(r,3,v[ 3],v[ 7],v[11],v[15]); \
-+            G(r,4,v[ 0],v[ 5],v[10],v[15]); \
-+            G(r,5,v[ 1],v[ 6],v[11],v[12]); \
-+            G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
-+            G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
-+        } while (0)
-+#if defined(OPENSSL_SMALL_FOOTPRINT)
-+        /* almost 3x reduction on x86_64, 4.5x on ARMv8, 4x on ARMv4 */
-+        for (i = 0; i < 10; i++) {
-+            ROUND(i);
-+        }
-+#else
-+        ROUND(0);
-+        ROUND(1);
-+        ROUND(2);
-+        ROUND(3);
-+        ROUND(4);
-+        ROUND(5);
-+        ROUND(6);
-+        ROUND(7);
-+        ROUND(8);
-+        ROUND(9);
-+#endif
-+
-+        for (i = 0; i < 8; ++i) {
-+            S->h[i] = v[i] ^= v[i + 8] ^ S->h[i];
-+        }
-+#undef G
-+#undef ROUND
-+        blocks += increment;
-+        len -= increment;
-+    } while (len);
-+}
-+
-+/* Absorb the input data into the hash state.  Always returns 1. */
-+int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen)
-+{
-+    const uint8_t *in = data;
-+    size_t fill;
-+
-+    /*
-+     * Intuitively one would expect intermediate buffer, c->buf, to
-+     * store incomplete blocks. But in this case we are interested to
-+     * temporarily stash even complete blocks, because last one in the
-+     * stream has to be treated in special way, and at this point we
-+     * don't know if last block in *this* call is last one "ever". This
-+     * is the reason for why |datalen| is compared as >, and not >=.
-+     */
-+    fill = sizeof(c->buf) - c->buflen;
-+    if (datalen > fill) {
-+        if (c->buflen) {
-+            memcpy(c->buf + c->buflen, in, fill); /* Fill buffer */
-+            blake2s_compress(c, c->buf, BLAKE2S_BLOCKBYTES);
-+            c->buflen = 0;
-+            in += fill;
-+            datalen -= fill;
-+        }
-+        if (datalen > BLAKE2S_BLOCKBYTES)  {
-+            size_t stashlen = datalen % BLAKE2S_BLOCKBYTES;
-+            /*
-+             * If |datalen| is a multiple of the blocksize, stash
-+             * last complete block, it can be final one...
-+             */
-+            stashlen = stashlen ? stashlen : BLAKE2S_BLOCKBYTES;
-+            datalen -= stashlen;
-+            blake2s_compress(c, in, datalen);
-+            in += datalen;
-+            datalen = stashlen;
-+        }
-+    }
-+
-+    assert(datalen <= BLAKE2S_BLOCKBYTES);
-+
-+    memcpy(c->buf + c->buflen, in, datalen);
-+    c->buflen += datalen; /* Be lazy, do not compress */
-+
-+    return 1;
-+}
-+
-+/*
-+ * Calculate the final hash and save it in md.
-+ * Always returns 1.
-+ */
-+int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c)
-+{
-+    int i;
-+
-+    blake2s_set_lastblock(c);
-+    /* Padding */
-+    memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen);
-+    blake2s_compress(c, c->buf, c->buflen);
-+
-+    /* Output full hash to temp buffer */
-+    for (i = 0; i < 8; ++i) {
-+        store32(md + sizeof(c->h[i]) * i, c->h[i]);
-+    }
-+
-+    OPENSSL_cleanse(c, sizeof(BLAKE2S_CTX));
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/build.info
-new file mode 100644
-index 0000000..0036f08
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        blake2b.c blake2s.c m_blake2b.c m_blake2s.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/m_blake2b.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/m_blake2b.c
-new file mode 100644
-index 0000000..82c6f6b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/m_blake2b.c
-@@ -0,0 +1,59 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
-+ * Copyright 2012, Samuel Neves 
-+ * More information about the BLAKE2 hash function and its implementations
-+ * can be found at https://blake2.net.
-+ */
-+
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_BLAKE2
-+
-+# include 
-+# include 
-+# include "blake2_locl.h"
-+# include "internal/evp_int.h"
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    return BLAKE2b_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return BLAKE2b_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return BLAKE2b_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static const EVP_MD blake2b_md = {
-+    NID_blake2b512,
-+    0,
-+    BLAKE2B_DIGEST_LENGTH,
-+    0,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    BLAKE2B_BLOCKBYTES,
-+    sizeof(EVP_MD *) + sizeof(BLAKE2B_CTX),
-+};
-+
-+const EVP_MD *EVP_blake2b512(void)
-+{
-+    return (&blake2b_md);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/m_blake2s.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/m_blake2s.c
-new file mode 100644
-index 0000000..467e91a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/blake2/m_blake2s.c
-@@ -0,0 +1,59 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
-+ * Copyright 2012, Samuel Neves 
-+ * More information about the BLAKE2 hash function and its implementations
-+ * can be found at https://blake2.net.
-+ */
-+
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_BLAKE2
-+
-+# include 
-+# include 
-+# include "blake2_locl.h"
-+# include "internal/evp_int.h"
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    return BLAKE2s_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return BLAKE2s_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return BLAKE2s_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static const EVP_MD blake2s_md = {
-+    NID_blake2s256,
-+    0,
-+    BLAKE2S_DIGEST_LENGTH,
-+    0,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    BLAKE2S_BLOCKBYTES,
-+    sizeof(EVP_MD *) + sizeof(BLAKE2S_CTX),
-+};
-+
-+const EVP_MD *EVP_blake2s256(void)
-+{
-+    return (&blake2s_md);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/README.pod b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/README.pod
-new file mode 100644
-index 0000000..109ab0d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/README.pod
-@@ -0,0 +1,247 @@
-+=pod
-+
-+=head1 NAME
-+
-+bn_mul_words, bn_mul_add_words, bn_sqr_words, bn_div_words,
-+bn_add_words, bn_sub_words, bn_mul_comba4, bn_mul_comba8,
-+bn_sqr_comba4, bn_sqr_comba8, bn_cmp_words, bn_mul_normal,
-+bn_mul_low_normal, bn_mul_recursive, bn_mul_part_recursive,
-+bn_mul_low_recursive, bn_mul_high, bn_sqr_normal, bn_sqr_recursive,
-+bn_expand, bn_wexpand, bn_expand2, bn_fix_top, bn_check_top,
-+bn_print, bn_dump, bn_set_max, bn_set_high, bn_set_low - BIGNUM
-+library internal functions
-+
-+=head1 SYNOPSIS
-+
-+ #include 
-+
-+ BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
-+ BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num,
-+   BN_ULONG w);
-+ void     bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
-+ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
-+ BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,
-+   int num);
-+ BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,
-+   int num);
-+
-+ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
-+ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
-+ void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a);
-+ void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a);
-+
-+ int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n);
-+
-+ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b,
-+   int nb);
-+ void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n);
-+ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
-+   int dna, int dnb, BN_ULONG *tmp);
-+ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
-+   int n, int tna, int tnb, BN_ULONG *tmp);
-+ void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
-+   int n2, BN_ULONG *tmp);
-+ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l,
-+   int n2, BN_ULONG *tmp);
-+
-+ void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
-+ void bn_sqr_recursive(BN_ULONG *r, BN_ULONG *a, int n2, BN_ULONG *tmp);
-+
-+ void mul(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c);
-+ void mul_add(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c);
-+ void sqr(BN_ULONG r0, BN_ULONG r1, BN_ULONG a);
-+
-+ BIGNUM *bn_expand(BIGNUM *a, int bits);
-+ BIGNUM *bn_wexpand(BIGNUM *a, int n);
-+ BIGNUM *bn_expand2(BIGNUM *a, int n);
-+ void bn_fix_top(BIGNUM *a);
-+
-+ void bn_check_top(BIGNUM *a);
-+ void bn_print(BIGNUM *a);
-+ void bn_dump(BN_ULONG *d, int n);
-+ void bn_set_max(BIGNUM *a);
-+ void bn_set_high(BIGNUM *r, BIGNUM *a, int n);
-+ void bn_set_low(BIGNUM *r, BIGNUM *a, int n);
-+
-+=head1 DESCRIPTION
-+
-+This page documents the internal functions used by the OpenSSL
-+B implementation. They are described here to facilitate
-+debugging and extending the library. They are I to be used by
-+applications.
-+
-+=head2 The BIGNUM structure
-+
-+ typedef struct bignum_st BIGNUM;
-+
-+ struct bignum_st
-+        {
-+        BN_ULONG *d;    /* Pointer to an array of 'BN_BITS2' bit chunks. */
-+        int top;        /* Index of last used d +1. */
-+        /* The next are internal book keeping for bn_expand. */
-+        int dmax;       /* Size of the d array. */
-+        int neg;        /* one if the number is negative */
-+        int flags;
-+        };
-+
-+
-+The integer value is stored in B, a malloc()ed array of words (B),
-+least significant word first. A B can be either 16, 32 or 64 bits
-+in size, depending on the 'number of bits' (B) specified in
-+C.
-+
-+B is the size of the B array that has been allocated.  B
-+is the number of words being used, so for a value of 4, bn.d[0]=4 and
-+bn.top=1.  B is 1 if the number is negative.  When a B is
-+B<0>, the B field can be B and B == B<0>.
-+
-+B is a bit field of flags which are defined in C. The
-+flags begin with B. The macros BN_set_flags(b, n) and
-+BN_get_flags(b, n) exist to enable or fetch flag(s) B from B
-+structure B.
-+
-+Various routines in this library require the use of temporary
-+B variables during their execution.  Since dynamic memory
-+allocation to create Bs is rather expensive when used in
-+conjunction with repeated subroutine calls, the B structure is
-+used.  This structure contains B Bs, see
-+L.
-+
-+=head2 Low-level arithmetic operations
-+
-+These functions are implemented in C and for several platforms in
-+assembly language:
-+
-+bn_mul_words(B, B, B, B) operates on the B word
-+arrays B and B.  It computes B * B, places the result
-+in B, and returns the high word (carry).
-+
-+bn_mul_add_words(B, B, B, B) operates on the B
-+word arrays B and B.  It computes B * B + B, places
-+the result in B, and returns the high word (carry).
-+
-+bn_sqr_words(B, B, B) operates on the B word array
-+B and the 2*B word array B.  It computes B * B
-+word-wise, and places the low and high bytes of the result in B.
-+
-+bn_div_words(B, B, B) divides the two word number (B, B)
-+by B and returns the result.
-+
-+bn_add_words(B, B, B, B) operates on the B word
-+arrays B, B and B.  It computes B + B, places the
-+result in B, and returns the high word (carry).
-+
-+bn_sub_words(B, B, B, B) operates on the B word
-+arrays B, B and B.  It computes B - B, places the
-+result in B, and returns the carry (1 if B E B, 0
-+otherwise).
-+
-+bn_mul_comba4(B, B, B) operates on the 4 word arrays B and
-+B and the 8 word array B.  It computes B*B and places the
-+result in B.
-+
-+bn_mul_comba8(B, B, B) operates on the 8 word arrays B and
-+B and the 16 word array B.  It computes B*B and places the
-+result in B.
-+
-+bn_sqr_comba4(B, B, B) operates on the 4 word arrays B and
-+B and the 8 word array B.
-+
-+bn_sqr_comba8(B, B, B) operates on the 8 word arrays B and
-+B and the 16 word array B.
-+
-+The following functions are implemented in C:
-+
-+bn_cmp_words(B, B, B) operates on the B word arrays B
-+and B.  It returns 1, 0 and -1 if B is greater than, equal and
-+less than B.
-+
-+bn_mul_normal(B, B, B, B, B) operates on the B
-+word array B, the B word array B and the B+B word
-+array B.  It computes B*B and places the result in B.
-+
-+bn_mul_low_normal(B, B, B, B) operates on the B word
-+arrays B, B and B.  It computes the B low words of
-+B*B and places the result in B.
-+
-+bn_mul_recursive(B, B, B, B, B, B, B) operates
-+on the word arrays B and B of length B+B and B+B
-+(B and B are currently allowed to be 0 or negative) and the 2*B
-+word arrays B and B.  B must be a power of 2.  It computes
-+B*B and places the result in B.
-+
-+bn_mul_part_recursive(B, B, B, B, B, B, B)
-+operates on the word arrays B and B of length B+B and
-+B+B and the 4*B word arrays B and B.
-+
-+bn_mul_low_recursive(B, B, B, B, B) operates on the
-+B word arrays B and B and the B/2 word arrays B
-+and B.
-+
-+bn_mul_high(B, B, B, B, B, B) operates on the
-+B word arrays B, B, B and B (?) and the 3*B word
-+array B.
-+
-+BN_mul() calls bn_mul_normal(), or an optimized implementation if the
-+factors have the same size: bn_mul_comba8() is used if they are 8
-+words long, bn_mul_recursive() if they are larger than
-+B and the size is an exact multiple of the word
-+size, and bn_mul_part_recursive() for others that are larger than
-+B.
-+
-+bn_sqr_normal(B, B, B, B) operates on the B word array
-+B and the 2*B word arrays B and B.
-+
-+The implementations use the following macros which, depending on the
-+architecture, may use "long long" C operations or inline assembler.
-+They are defined in C.
-+
-+mul(B, B, B, B) computes B*B+B and places the
-+low word of the result in B and the high word in B.
-+
-+mul_add(B, B, B, B) computes B*B+B+B and
-+places the low word of the result in B and the high word in B.
-+
-+sqr(B, B, B) computes B*B and places the low word
-+of the result in B and the high word in B.
-+
-+=head2 Size changes
-+
-+bn_expand() ensures that B has enough space for a B bit
-+number.  bn_wexpand() ensures that B has enough space for an
-+B word number.  If the number has to be expanded, both macros
-+call bn_expand2(), which allocates a new B array and copies the
-+data.  They return B on error, B otherwise.
-+
-+The bn_fix_top() macro reduces Btop> to point to the most
-+significant non-zero word plus one when B has shrunk.
-+
-+=head2 Debugging
-+
-+bn_check_top() verifies that C<((a)-Etop E= 0 && (a)-Etop
-+E= (a)-Edmax)>.  A violation will cause the program to abort.
-+
-+bn_print() prints B to stderr. bn_dump() prints B words at B
-+(in reverse order, i.e. most significant word first) to stderr.
-+
-+bn_set_max() makes B a static number with a B of its current size.
-+This is used by bn_set_low() and bn_set_high() to make B a read-only
-+B that contains the B low or high words of B.
-+
-+If B is not defined, bn_check_top(), bn_print(), bn_dump()
-+and bn_set_max() are defined as empty macros.
-+
-+=head1 SEE ALSO
-+
-+L
-+
-+=head1 COPYRIGHT
-+
-+Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+
-+Licensed under the OpenSSL license (the "License").  You may not use
-+this file except in compliance with the License.  You can obtain a copy
-+in the file LICENSE in the source distribution or at
-+L.
-+
-+=cut
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/alpha-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/alpha-mont.pl
-new file mode 100644
-index 0000000..1d68d6d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/alpha-mont.pl
-@@ -0,0 +1,331 @@
-+#! /usr/bin/env perl
-+# Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# On 21264 RSA sign performance improves by 70/35/20/15 percent for
-+# 512/1024/2048/4096 bit key lengths. This is against vendor compiler
-+# instructed to '-tune host' code with in-line assembler. Other
-+# benchmarks improve by 15-20%. To anchor it to something else, the
-+# code provides approximately the same performance per GHz as AMD64.
-+# I.e. if you compare 1GHz 21264 and 2GHz Opteron, you'll observe ~2x
-+# difference.
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+# int bn_mul_mont(
-+$rp="a0";	# BN_ULONG *rp,
-+$ap="a1";	# const BN_ULONG *ap,
-+$bp="a2";	# const BN_ULONG *bp,
-+$np="a3";	# const BN_ULONG *np,
-+$n0="a4";	# const BN_ULONG *n0,
-+$num="a5";	# int num);
-+
-+$lo0="t0";
-+$hi0="t1";
-+$lo1="t2";
-+$hi1="t3";
-+$aj="t4";
-+$bi="t5";
-+$nj="t6";
-+$tp="t7";
-+$alo="t8";
-+$ahi="t9";
-+$nlo="t10";
-+$nhi="t11";
-+$tj="t12";
-+$i="s3";
-+$j="s4";
-+$m1="s5";
-+
-+$code=<<___;
-+#ifdef __linux__
-+#include 
-+#else
-+#include 
-+#include 
-+#endif
-+
-+.text
-+
-+.set	noat
-+.set	noreorder
-+
-+.globl	bn_mul_mont
-+.align	5
-+.ent	bn_mul_mont
-+bn_mul_mont:
-+	lda	sp,-48(sp)
-+	stq	ra,0(sp)
-+	stq	s3,8(sp)
-+	stq	s4,16(sp)
-+	stq	s5,24(sp)
-+	stq	fp,32(sp)
-+	mov	sp,fp
-+	.mask	0x0400f000,-48
-+	.frame	fp,48,ra
-+	.prologue 0
-+
-+	.align	4
-+	.set	reorder
-+	sextl	$num,$num
-+	mov	0,v0
-+	cmplt	$num,4,AT
-+	bne	AT,.Lexit
-+
-+	ldq	$hi0,0($ap)	# ap[0]
-+	s8addq	$num,16,AT
-+	ldq	$aj,8($ap)
-+	subq	sp,AT,sp
-+	ldq	$bi,0($bp)	# bp[0]
-+	lda	AT,-4096(zero)	# mov	-4096,AT
-+	ldq	$n0,0($n0)
-+	and	sp,AT,sp
-+
-+	mulq	$hi0,$bi,$lo0
-+	ldq	$hi1,0($np)	# np[0]
-+	umulh	$hi0,$bi,$hi0
-+	ldq	$nj,8($np)
-+
-+	mulq	$lo0,$n0,$m1
-+
-+	mulq	$hi1,$m1,$lo1
-+	umulh	$hi1,$m1,$hi1
-+
-+	addq	$lo1,$lo0,$lo1
-+	cmpult	$lo1,$lo0,AT
-+	addq	$hi1,AT,$hi1
-+
-+	mulq	$aj,$bi,$alo
-+	mov	2,$j
-+	umulh	$aj,$bi,$ahi
-+	mov	sp,$tp
-+
-+	mulq	$nj,$m1,$nlo
-+	s8addq	$j,$ap,$aj
-+	umulh	$nj,$m1,$nhi
-+	s8addq	$j,$np,$nj
-+.align	4
-+.L1st:
-+	.set	noreorder
-+	ldq	$aj,0($aj)
-+	addl	$j,1,$j
-+	ldq	$nj,0($nj)
-+	lda	$tp,8($tp)
-+
-+	addq	$alo,$hi0,$lo0
-+	mulq	$aj,$bi,$alo
-+	cmpult	$lo0,$hi0,AT
-+	addq	$nlo,$hi1,$lo1
-+
-+	mulq	$nj,$m1,$nlo
-+	addq	$ahi,AT,$hi0
-+	cmpult	$lo1,$hi1,v0
-+	cmplt	$j,$num,$tj
-+
-+	umulh	$aj,$bi,$ahi
-+	addq	$nhi,v0,$hi1
-+	addq	$lo1,$lo0,$lo1
-+	s8addq	$j,$ap,$aj
-+
-+	umulh	$nj,$m1,$nhi
-+	cmpult	$lo1,$lo0,v0
-+	addq	$hi1,v0,$hi1
-+	s8addq	$j,$np,$nj
-+
-+	stq	$lo1,-8($tp)
-+	nop
-+	unop
-+	bne	$tj,.L1st
-+	.set	reorder
-+
-+	addq	$alo,$hi0,$lo0
-+	addq	$nlo,$hi1,$lo1
-+	cmpult	$lo0,$hi0,AT
-+	cmpult	$lo1,$hi1,v0
-+	addq	$ahi,AT,$hi0
-+	addq	$nhi,v0,$hi1
-+
-+	addq	$lo1,$lo0,$lo1
-+	cmpult	$lo1,$lo0,v0
-+	addq	$hi1,v0,$hi1
-+
-+	stq	$lo1,0($tp)
-+
-+	addq	$hi1,$hi0,$hi1
-+	cmpult	$hi1,$hi0,AT
-+	stq	$hi1,8($tp)
-+	stq	AT,16($tp)
-+
-+	mov	1,$i
-+.align	4
-+.Louter:
-+	s8addq	$i,$bp,$bi
-+	ldq	$hi0,0($ap)
-+	ldq	$aj,8($ap)
-+	ldq	$bi,0($bi)
-+	ldq	$hi1,0($np)
-+	ldq	$nj,8($np)
-+	ldq	$tj,0(sp)
-+
-+	mulq	$hi0,$bi,$lo0
-+	umulh	$hi0,$bi,$hi0
-+
-+	addq	$lo0,$tj,$lo0
-+	cmpult	$lo0,$tj,AT
-+	addq	$hi0,AT,$hi0
-+
-+	mulq	$lo0,$n0,$m1
-+
-+	mulq	$hi1,$m1,$lo1
-+	umulh	$hi1,$m1,$hi1
-+
-+	addq	$lo1,$lo0,$lo1
-+	cmpult	$lo1,$lo0,AT
-+	mov	2,$j
-+	addq	$hi1,AT,$hi1
-+
-+	mulq	$aj,$bi,$alo
-+	mov	sp,$tp
-+	umulh	$aj,$bi,$ahi
-+
-+	mulq	$nj,$m1,$nlo
-+	s8addq	$j,$ap,$aj
-+	umulh	$nj,$m1,$nhi
-+.align	4
-+.Linner:
-+	.set	noreorder
-+	ldq	$tj,8($tp)	#L0
-+	nop			#U1
-+	ldq	$aj,0($aj)	#L1
-+	s8addq	$j,$np,$nj	#U0
-+
-+	ldq	$nj,0($nj)	#L0
-+	nop			#U1
-+	addq	$alo,$hi0,$lo0	#L1
-+	lda	$tp,8($tp)
-+
-+	mulq	$aj,$bi,$alo	#U1
-+	cmpult	$lo0,$hi0,AT	#L0
-+	addq	$nlo,$hi1,$lo1	#L1
-+	addl	$j,1,$j
-+
-+	mulq	$nj,$m1,$nlo	#U1
-+	addq	$ahi,AT,$hi0	#L0
-+	addq	$lo0,$tj,$lo0	#L1
-+	cmpult	$lo1,$hi1,v0	#U0
-+
-+	umulh	$aj,$bi,$ahi	#U1
-+	cmpult	$lo0,$tj,AT	#L0
-+	addq	$lo1,$lo0,$lo1	#L1
-+	addq	$nhi,v0,$hi1	#U0
-+
-+	umulh	$nj,$m1,$nhi	#U1
-+	s8addq	$j,$ap,$aj	#L0
-+	cmpult	$lo1,$lo0,v0	#L1
-+	cmplt	$j,$num,$tj	#U0	# borrow $tj
-+
-+	addq	$hi0,AT,$hi0	#L0
-+	addq	$hi1,v0,$hi1	#U1
-+	stq	$lo1,-8($tp)	#L1
-+	bne	$tj,.Linner	#U0
-+	.set	reorder
-+
-+	ldq	$tj,8($tp)
-+	addq	$alo,$hi0,$lo0
-+	addq	$nlo,$hi1,$lo1
-+	cmpult	$lo0,$hi0,AT
-+	cmpult	$lo1,$hi1,v0
-+	addq	$ahi,AT,$hi0
-+	addq	$nhi,v0,$hi1
-+
-+	addq	$lo0,$tj,$lo0
-+	cmpult	$lo0,$tj,AT
-+	addq	$hi0,AT,$hi0
-+
-+	ldq	$tj,16($tp)
-+	addq	$lo1,$lo0,$j
-+	cmpult	$j,$lo0,v0
-+	addq	$hi1,v0,$hi1
-+
-+	addq	$hi1,$hi0,$lo1
-+	stq	$j,0($tp)
-+	cmpult	$lo1,$hi0,$hi1
-+	addq	$lo1,$tj,$lo1
-+	cmpult	$lo1,$tj,AT
-+	addl	$i,1,$i
-+	addq	$hi1,AT,$hi1
-+	stq	$lo1,8($tp)
-+	cmplt	$i,$num,$tj	# borrow $tj
-+	stq	$hi1,16($tp)
-+	bne	$tj,.Louter
-+
-+	s8addq	$num,sp,$tj	# &tp[num]
-+	mov	$rp,$bp		# put rp aside
-+	mov	sp,$tp
-+	mov	sp,$ap
-+	mov	0,$hi0		# clear borrow bit
-+
-+.align	4
-+.Lsub:	ldq	$lo0,0($tp)
-+	ldq	$lo1,0($np)
-+	lda	$tp,8($tp)
-+	lda	$np,8($np)
-+	subq	$lo0,$lo1,$lo1	# tp[i]-np[i]
-+	cmpult	$lo0,$lo1,AT
-+	subq	$lo1,$hi0,$lo0
-+	cmpult	$lo1,$lo0,$hi0
-+	or	$hi0,AT,$hi0
-+	stq	$lo0,0($rp)
-+	cmpult	$tp,$tj,v0
-+	lda	$rp,8($rp)
-+	bne	v0,.Lsub
-+
-+	subq	$hi1,$hi0,$hi0	# handle upmost overflow bit
-+	mov	sp,$tp
-+	mov	$bp,$rp		# restore rp
-+
-+	and	sp,$hi0,$ap
-+	bic	$bp,$hi0,$bp
-+	bis	$bp,$ap,$ap	# ap=borrow?tp:rp
-+
-+.align	4
-+.Lcopy:	ldq	$aj,0($ap)	# copy or in-place refresh
-+	lda	$tp,8($tp)
-+	lda	$rp,8($rp)
-+	lda	$ap,8($ap)
-+	stq	zero,-8($tp)	# zap tp
-+	cmpult	$tp,$tj,AT
-+	stq	$aj,-8($rp)
-+	bne	AT,.Lcopy
-+	mov	1,v0
-+
-+.Lexit:
-+	.set	noreorder
-+	mov	fp,sp
-+	/*ldq	ra,0(sp)*/
-+	ldq	s3,8(sp)
-+	ldq	s4,16(sp)
-+	ldq	s5,24(sp)
-+	ldq	fp,32(sp)
-+	lda	sp,48(sp)
-+	ret	(ra)
-+.end	bn_mul_mont
-+.ascii	"Montgomery Multiplication for Alpha, CRYPTOGAMS by "
-+.align	2
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv4-gf2m.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv4-gf2m.pl
-new file mode 100644
-index 0000000..0bb5433
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv4-gf2m.pl
-@@ -0,0 +1,332 @@
-+#! /usr/bin/env perl
-+# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# May 2011
-+#
-+# The module implements bn_GF2m_mul_2x2 polynomial multiplication
-+# used in bn_gf2m.c. It's kind of low-hanging mechanical port from
-+# C for the time being... Except that it has two code paths: pure
-+# integer code suitable for any ARMv4 and later CPU and NEON code
-+# suitable for ARMv7. Pure integer 1x1 multiplication subroutine runs
-+# in ~45 cycles on dual-issue core such as Cortex A8, which is ~50%
-+# faster than compiler-generated code. For ECDH and ECDSA verify (but
-+# not for ECDSA sign) it means 25%-45% improvement depending on key
-+# length, more for longer keys. Even though NEON 1x1 multiplication
-+# runs in even less cycles, ~30, improvement is measurable only on
-+# longer keys. One has to optimize code elsewhere to get NEON glow...
-+#
-+# April 2014
-+#
-+# Double bn_GF2m_mul_2x2 performance by using algorithm from paper
-+# referred below, which improves ECDH and ECDSA verify benchmarks
-+# by 18-40%.
-+#
-+# Câmara, D.; Gouvêa, C. P. L.; López, J. & Dahab, R.: Fast Software
-+# Polynomial Multiplication on ARM Processors using the NEON Engine.
-+# 
-+# http://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+$code=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+#if defined(__thumb2__)
-+.syntax	unified
-+.thumb
-+#else
-+.code	32
-+#endif
-+___
-+################
-+# private interface to mul_1x1_ialu
-+#
-+$a="r1";
-+$b="r0";
-+
-+($a0,$a1,$a2,$a12,$a4,$a14)=
-+($hi,$lo,$t0,$t1, $i0,$i1 )=map("r$_",(4..9),12);
-+
-+$mask="r12";
-+
-+$code.=<<___;
-+.type	mul_1x1_ialu,%function
-+.align	5
-+mul_1x1_ialu:
-+	mov	$a0,#0
-+	bic	$a1,$a,#3<<30		@ a1=a&0x3fffffff
-+	str	$a0,[sp,#0]		@ tab[0]=0
-+	add	$a2,$a1,$a1		@ a2=a1<<1
-+	str	$a1,[sp,#4]		@ tab[1]=a1
-+	eor	$a12,$a1,$a2		@ a1^a2
-+	str	$a2,[sp,#8]		@ tab[2]=a2
-+	mov	$a4,$a1,lsl#2		@ a4=a1<<2
-+	str	$a12,[sp,#12]		@ tab[3]=a1^a2
-+	eor	$a14,$a1,$a4		@ a1^a4
-+	str	$a4,[sp,#16]		@ tab[4]=a4
-+	eor	$a0,$a2,$a4		@ a2^a4
-+	str	$a14,[sp,#20]		@ tab[5]=a1^a4
-+	eor	$a12,$a12,$a4		@ a1^a2^a4
-+	str	$a0,[sp,#24]		@ tab[6]=a2^a4
-+	and	$i0,$mask,$b,lsl#2
-+	str	$a12,[sp,#28]		@ tab[7]=a1^a2^a4
-+
-+	and	$i1,$mask,$b,lsr#1
-+	ldr	$lo,[sp,$i0]		@ tab[b       & 0x7]
-+	and	$i0,$mask,$b,lsr#4
-+	ldr	$t1,[sp,$i1]		@ tab[b >>  3 & 0x7]
-+	and	$i1,$mask,$b,lsr#7
-+	ldr	$t0,[sp,$i0]		@ tab[b >>  6 & 0x7]
-+	eor	$lo,$lo,$t1,lsl#3	@ stall
-+	mov	$hi,$t1,lsr#29
-+	ldr	$t1,[sp,$i1]		@ tab[b >>  9 & 0x7]
-+
-+	and	$i0,$mask,$b,lsr#10
-+	eor	$lo,$lo,$t0,lsl#6
-+	eor	$hi,$hi,$t0,lsr#26
-+	ldr	$t0,[sp,$i0]		@ tab[b >> 12 & 0x7]
-+
-+	and	$i1,$mask,$b,lsr#13
-+	eor	$lo,$lo,$t1,lsl#9
-+	eor	$hi,$hi,$t1,lsr#23
-+	ldr	$t1,[sp,$i1]		@ tab[b >> 15 & 0x7]
-+
-+	and	$i0,$mask,$b,lsr#16
-+	eor	$lo,$lo,$t0,lsl#12
-+	eor	$hi,$hi,$t0,lsr#20
-+	ldr	$t0,[sp,$i0]		@ tab[b >> 18 & 0x7]
-+
-+	and	$i1,$mask,$b,lsr#19
-+	eor	$lo,$lo,$t1,lsl#15
-+	eor	$hi,$hi,$t1,lsr#17
-+	ldr	$t1,[sp,$i1]		@ tab[b >> 21 & 0x7]
-+
-+	and	$i0,$mask,$b,lsr#22
-+	eor	$lo,$lo,$t0,lsl#18
-+	eor	$hi,$hi,$t0,lsr#14
-+	ldr	$t0,[sp,$i0]		@ tab[b >> 24 & 0x7]
-+
-+	and	$i1,$mask,$b,lsr#25
-+	eor	$lo,$lo,$t1,lsl#21
-+	eor	$hi,$hi,$t1,lsr#11
-+	ldr	$t1,[sp,$i1]		@ tab[b >> 27 & 0x7]
-+
-+	tst	$a,#1<<30
-+	and	$i0,$mask,$b,lsr#28
-+	eor	$lo,$lo,$t0,lsl#24
-+	eor	$hi,$hi,$t0,lsr#8
-+	ldr	$t0,[sp,$i0]		@ tab[b >> 30      ]
-+
-+#ifdef	__thumb2__
-+	itt	ne
-+#endif
-+	eorne	$lo,$lo,$b,lsl#30
-+	eorne	$hi,$hi,$b,lsr#2
-+	tst	$a,#1<<31
-+	eor	$lo,$lo,$t1,lsl#27
-+	eor	$hi,$hi,$t1,lsr#5
-+#ifdef	__thumb2__
-+	itt	ne
-+#endif
-+	eorne	$lo,$lo,$b,lsl#31
-+	eorne	$hi,$hi,$b,lsr#1
-+	eor	$lo,$lo,$t0,lsl#30
-+	eor	$hi,$hi,$t0,lsr#2
-+
-+	mov	pc,lr
-+.size	mul_1x1_ialu,.-mul_1x1_ialu
-+___
-+################
-+# void	bn_GF2m_mul_2x2(BN_ULONG *r,
-+#	BN_ULONG a1,BN_ULONG a0,
-+#	BN_ULONG b1,BN_ULONG b0);	# r[3..0]=a1a0·b1b0
-+{
-+$code.=<<___;
-+.global	bn_GF2m_mul_2x2
-+.type	bn_GF2m_mul_2x2,%function
-+.align	5
-+bn_GF2m_mul_2x2:
-+#if __ARM_MAX_ARCH__>=7
-+	stmdb	sp!,{r10,lr}
-+	ldr	r12,.LOPENSSL_armcap
-+	adr	r10,.LOPENSSL_armcap
-+	ldr	r12,[r12,r10]
-+#ifdef	__APPLE__
-+	ldr	r12,[r12]
-+#endif
-+	tst	r12,#ARMV7_NEON
-+	itt	ne
-+	ldrne	r10,[sp],#8
-+	bne	.LNEON
-+	stmdb	sp!,{r4-r9}
-+#else
-+	stmdb	sp!,{r4-r10,lr}
-+#endif
-+___
-+$ret="r10";	# reassigned 1st argument
-+$code.=<<___;
-+	mov	$ret,r0			@ reassign 1st argument
-+	mov	$b,r3			@ $b=b1
-+	sub	r7,sp,#36
-+	mov	r8,sp
-+	and	r7,r7,#-32
-+	ldr	r3,[sp,#32]		@ load b0
-+	mov	$mask,#7<<2
-+	mov	sp,r7			@ allocate tab[8]
-+	str	r8,[r7,#32]
-+
-+	bl	mul_1x1_ialu		@ a1·b1
-+	str	$lo,[$ret,#8]
-+	str	$hi,[$ret,#12]
-+
-+	eor	$b,$b,r3		@ flip b0 and b1
-+	 eor	$a,$a,r2		@ flip a0 and a1
-+	eor	r3,r3,$b
-+	 eor	r2,r2,$a
-+	eor	$b,$b,r3
-+	 eor	$a,$a,r2
-+	bl	mul_1x1_ialu		@ a0·b0
-+	str	$lo,[$ret]
-+	str	$hi,[$ret,#4]
-+
-+	eor	$a,$a,r2
-+	eor	$b,$b,r3
-+	bl	mul_1x1_ialu		@ (a1+a0)·(b1+b0)
-+___
-+@r=map("r$_",(6..9));
-+$code.=<<___;
-+	ldmia	$ret,{@r[0]-@r[3]}
-+	eor	$lo,$lo,$hi
-+	ldr	sp,[sp,#32]		@ destroy tab[8]
-+	eor	$hi,$hi,@r[1]
-+	eor	$lo,$lo,@r[0]
-+	eor	$hi,$hi,@r[2]
-+	eor	$lo,$lo,@r[3]
-+	eor	$hi,$hi,@r[3]
-+	str	$hi,[$ret,#8]
-+	eor	$lo,$lo,$hi
-+	str	$lo,[$ret,#4]
-+
-+#if __ARM_ARCH__>=5
-+	ldmia	sp!,{r4-r10,pc}
-+#else
-+	ldmia	sp!,{r4-r10,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+___
-+}
-+{
-+my ($r,$t0,$t1,$t2,$t3)=map("q$_",(0..3,8..12));
-+my ($a,$b,$k48,$k32,$k16)=map("d$_",(26..31));
-+
-+$code.=<<___;
-+#if __ARM_MAX_ARCH__>=7
-+.arch	armv7-a
-+.fpu	neon
-+
-+.align	5
-+.LNEON:
-+	ldr		r12, [sp]		@ 5th argument
-+	vmov		$a, r2, r1
-+	vmov		$b, r12, r3
-+	vmov.i64	$k48, #0x0000ffffffffffff
-+	vmov.i64	$k32, #0x00000000ffffffff
-+	vmov.i64	$k16, #0x000000000000ffff
-+
-+	vext.8		$t0#lo, $a, $a, #1	@ A1
-+	vmull.p8	$t0, $t0#lo, $b		@ F = A1*B
-+	vext.8		$r#lo, $b, $b, #1	@ B1
-+	vmull.p8	$r, $a, $r#lo		@ E = A*B1
-+	vext.8		$t1#lo, $a, $a, #2	@ A2
-+	vmull.p8	$t1, $t1#lo, $b		@ H = A2*B
-+	vext.8		$t3#lo, $b, $b, #2	@ B2
-+	vmull.p8	$t3, $a, $t3#lo		@ G = A*B2
-+	vext.8		$t2#lo, $a, $a, #3	@ A3
-+	veor		$t0, $t0, $r		@ L = E + F
-+	vmull.p8	$t2, $t2#lo, $b		@ J = A3*B
-+	vext.8		$r#lo, $b, $b, #3	@ B3
-+	veor		$t1, $t1, $t3		@ M = G + H
-+	vmull.p8	$r, $a, $r#lo		@ I = A*B3
-+	veor		$t0#lo, $t0#lo, $t0#hi	@ t0 = (L) (P0 + P1) << 8
-+	vand		$t0#hi, $t0#hi, $k48
-+	vext.8		$t3#lo, $b, $b, #4	@ B4
-+	veor		$t1#lo, $t1#lo, $t1#hi	@ t1 = (M) (P2 + P3) << 16
-+	vand		$t1#hi, $t1#hi, $k32
-+	vmull.p8	$t3, $a, $t3#lo		@ K = A*B4
-+	veor		$t2, $t2, $r		@ N = I + J
-+	veor		$t0#lo, $t0#lo, $t0#hi
-+	veor		$t1#lo, $t1#lo, $t1#hi
-+	veor		$t2#lo, $t2#lo, $t2#hi	@ t2 = (N) (P4 + P5) << 24
-+	vand		$t2#hi, $t2#hi, $k16
-+	vext.8		$t0, $t0, $t0, #15
-+	veor		$t3#lo, $t3#lo, $t3#hi	@ t3 = (K) (P6 + P7) << 32
-+	vmov.i64	$t3#hi, #0
-+	vext.8		$t1, $t1, $t1, #14
-+	veor		$t2#lo, $t2#lo, $t2#hi
-+	vmull.p8	$r, $a, $b		@ D = A*B
-+	vext.8		$t3, $t3, $t3, #12
-+	vext.8		$t2, $t2, $t2, #13
-+	veor		$t0, $t0, $t1
-+	veor		$t2, $t2, $t3
-+	veor		$r, $r, $t0
-+	veor		$r, $r, $t2
-+
-+	vst1.32		{$r}, [r0]
-+	ret		@ bx lr
-+#endif
-+___
-+}
-+$code.=<<___;
-+.size	bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
-+#if __ARM_MAX_ARCH__>=7
-+.align	5
-+.LOPENSSL_armcap:
-+.word	OPENSSL_armcap_P-.
-+#endif
-+.asciz	"GF(2^m) Multiplication for ARMv4/NEON, CRYPTOGAMS by "
-+.align	5
-+
-+#if __ARM_MAX_ARCH__>=7
-+.comm	OPENSSL_armcap_P,4,4
-+#endif
-+___
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo	or
-+	s/\bret\b/bx	lr/go		or
-+	s/\bbx\s+lr\b/.word\t0xe12fff1e/go;    # make it possible to compile with -march=armv4
-+
-+	print $_,"\n";
-+}
-+close STDOUT;   # enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv4-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv4-mont.pl
-new file mode 100644
-index 0000000..0dc4fe9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv4-mont.pl
-@@ -0,0 +1,756 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# January 2007.
-+
-+# Montgomery multiplication for ARMv4.
-+#
-+# Performance improvement naturally varies among CPU implementations
-+# and compilers. The code was observed to provide +65-35% improvement
-+# [depending on key length, less for longer keys] on ARM920T, and
-+# +115-80% on Intel IXP425. This is compared to pre-bn_mul_mont code
-+# base and compiler generated code with in-lined umull and even umlal
-+# instructions. The latter means that this code didn't really have an 
-+# "advantage" of utilizing some "secret" instruction.
-+#
-+# The code is interoperable with Thumb ISA and is rather compact, less
-+# than 1/2KB. Windows CE port would be trivial, as it's exclusively
-+# about decorations, ABI and instruction syntax are identical.
-+
-+# November 2013
-+#
-+# Add NEON code path, which handles lengths divisible by 8. RSA/DSA
-+# performance improvement on Cortex-A8 is ~45-100% depending on key
-+# length, more for longer keys. On Cortex-A15 the span is ~10-105%.
-+# On Snapdragon S4 improvement was measured to vary from ~70% to
-+# incredible ~380%, yes, 4.8x faster, for RSA4096 sign. But this is
-+# rather because original integer-only code seems to perform
-+# suboptimally on S4. Situation on Cortex-A9 is unfortunately
-+# different. It's being looked into, but the trouble is that
-+# performance for vectors longer than 256 bits is actually couple
-+# of percent worse than for integer-only code. The code is chosen
-+# for execution on all NEON-capable processors, because gain on
-+# others outweighs the marginal loss on Cortex-A9.
-+
-+# September 2015
-+#
-+# Align Cortex-A9 performance with November 2013 improvements, i.e.
-+# NEON code is now ~20-105% faster than integer-only one on this
-+# processor. But this optimization further improved performance even
-+# on other processors: NEON code path is ~45-180% faster than original
-+# integer-only on Cortex-A8, ~10-210% on Cortex-A15, ~70-450% on
-+# Snapdragon S4.
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+$num="r0";	# starts as num argument, but holds &tp[num-1]
-+$ap="r1";
-+$bp="r2"; $bi="r2"; $rp="r2";
-+$np="r3";
-+$tp="r4";
-+$aj="r5";
-+$nj="r6";
-+$tj="r7";
-+$n0="r8";
-+###########	# r9 is reserved by ELF as platform specific, e.g. TLS pointer
-+$alo="r10";	# sl, gcc uses it to keep @GOT
-+$ahi="r11";	# fp
-+$nlo="r12";	# ip
-+###########	# r13 is stack pointer
-+$nhi="r14";	# lr
-+###########	# r15 is program counter
-+
-+#### argument block layout relative to &tp[num-1], a.k.a. $num
-+$_rp="$num,#12*4";
-+# ap permanently resides in r1
-+$_bp="$num,#13*4";
-+# np permanently resides in r3
-+$_n0="$num,#14*4";
-+$_num="$num,#15*4";	$_bpend=$_num;
-+
-+$code=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+#if defined(__thumb2__)
-+.syntax	unified
-+.thumb
-+#else
-+.code	32
-+#endif
-+
-+#if __ARM_MAX_ARCH__>=7
-+.align	5
-+.LOPENSSL_armcap:
-+.word	OPENSSL_armcap_P-.Lbn_mul_mont
-+#endif
-+
-+.global	bn_mul_mont
-+.type	bn_mul_mont,%function
-+
-+.align	5
-+bn_mul_mont:
-+.Lbn_mul_mont:
-+	ldr	ip,[sp,#4]		@ load num
-+	stmdb	sp!,{r0,r2}		@ sp points at argument block
-+#if __ARM_MAX_ARCH__>=7
-+	tst	ip,#7
-+	bne	.Lialu
-+	adr	r0,.Lbn_mul_mont
-+	ldr	r2,.LOPENSSL_armcap
-+	ldr	r0,[r0,r2]
-+#ifdef	__APPLE__
-+	ldr	r0,[r0]
-+#endif
-+	tst	r0,#ARMV7_NEON		@ NEON available?
-+	ldmia	sp, {r0,r2}
-+	beq	.Lialu
-+	add	sp,sp,#8
-+	b	bn_mul8x_mont_neon
-+.align	4
-+.Lialu:
-+#endif
-+	cmp	ip,#2
-+	mov	$num,ip			@ load num
-+#ifdef	__thumb2__
-+	ittt	lt
-+#endif
-+	movlt	r0,#0
-+	addlt	sp,sp,#2*4
-+	blt	.Labrt
-+
-+	stmdb	sp!,{r4-r12,lr}		@ save 10 registers
-+
-+	mov	$num,$num,lsl#2		@ rescale $num for byte count
-+	sub	sp,sp,$num		@ alloca(4*num)
-+	sub	sp,sp,#4		@ +extra dword
-+	sub	$num,$num,#4		@ "num=num-1"
-+	add	$tp,$bp,$num		@ &bp[num-1]
-+
-+	add	$num,sp,$num		@ $num to point at &tp[num-1]
-+	ldr	$n0,[$_n0]		@ &n0
-+	ldr	$bi,[$bp]		@ bp[0]
-+	ldr	$aj,[$ap],#4		@ ap[0],ap++
-+	ldr	$nj,[$np],#4		@ np[0],np++
-+	ldr	$n0,[$n0]		@ *n0
-+	str	$tp,[$_bpend]		@ save &bp[num]
-+
-+	umull	$alo,$ahi,$aj,$bi	@ ap[0]*bp[0]
-+	str	$n0,[$_n0]		@ save n0 value
-+	mul	$n0,$alo,$n0		@ "tp[0]"*n0
-+	mov	$nlo,#0
-+	umlal	$alo,$nlo,$nj,$n0	@ np[0]*n0+"t[0]"
-+	mov	$tp,sp
-+
-+.L1st:
-+	ldr	$aj,[$ap],#4		@ ap[j],ap++
-+	mov	$alo,$ahi
-+	ldr	$nj,[$np],#4		@ np[j],np++
-+	mov	$ahi,#0
-+	umlal	$alo,$ahi,$aj,$bi	@ ap[j]*bp[0]
-+	mov	$nhi,#0
-+	umlal	$nlo,$nhi,$nj,$n0	@ np[j]*n0
-+	adds	$nlo,$nlo,$alo
-+	str	$nlo,[$tp],#4		@ tp[j-1]=,tp++
-+	adc	$nlo,$nhi,#0
-+	cmp	$tp,$num
-+	bne	.L1st
-+
-+	adds	$nlo,$nlo,$ahi
-+	ldr	$tp,[$_bp]		@ restore bp
-+	mov	$nhi,#0
-+	ldr	$n0,[$_n0]		@ restore n0
-+	adc	$nhi,$nhi,#0
-+	str	$nlo,[$num]		@ tp[num-1]=
-+	mov	$tj,sp
-+	str	$nhi,[$num,#4]		@ tp[num]=
-+
-+.Louter:
-+	sub	$tj,$num,$tj		@ "original" $num-1 value
-+	sub	$ap,$ap,$tj		@ "rewind" ap to &ap[1]
-+	ldr	$bi,[$tp,#4]!		@ *(++bp)
-+	sub	$np,$np,$tj		@ "rewind" np to &np[1]
-+	ldr	$aj,[$ap,#-4]		@ ap[0]
-+	ldr	$alo,[sp]		@ tp[0]
-+	ldr	$nj,[$np,#-4]		@ np[0]
-+	ldr	$tj,[sp,#4]		@ tp[1]
-+
-+	mov	$ahi,#0
-+	umlal	$alo,$ahi,$aj,$bi	@ ap[0]*bp[i]+tp[0]
-+	str	$tp,[$_bp]		@ save bp
-+	mul	$n0,$alo,$n0
-+	mov	$nlo,#0
-+	umlal	$alo,$nlo,$nj,$n0	@ np[0]*n0+"tp[0]"
-+	mov	$tp,sp
-+
-+.Linner:
-+	ldr	$aj,[$ap],#4		@ ap[j],ap++
-+	adds	$alo,$ahi,$tj		@ +=tp[j]
-+	ldr	$nj,[$np],#4		@ np[j],np++
-+	mov	$ahi,#0
-+	umlal	$alo,$ahi,$aj,$bi	@ ap[j]*bp[i]
-+	mov	$nhi,#0
-+	umlal	$nlo,$nhi,$nj,$n0	@ np[j]*n0
-+	adc	$ahi,$ahi,#0
-+	ldr	$tj,[$tp,#8]		@ tp[j+1]
-+	adds	$nlo,$nlo,$alo
-+	str	$nlo,[$tp],#4		@ tp[j-1]=,tp++
-+	adc	$nlo,$nhi,#0
-+	cmp	$tp,$num
-+	bne	.Linner
-+
-+	adds	$nlo,$nlo,$ahi
-+	mov	$nhi,#0
-+	ldr	$tp,[$_bp]		@ restore bp
-+	adc	$nhi,$nhi,#0
-+	ldr	$n0,[$_n0]		@ restore n0
-+	adds	$nlo,$nlo,$tj
-+	ldr	$tj,[$_bpend]		@ restore &bp[num]
-+	adc	$nhi,$nhi,#0
-+	str	$nlo,[$num]		@ tp[num-1]=
-+	str	$nhi,[$num,#4]		@ tp[num]=
-+
-+	cmp	$tp,$tj
-+#ifdef	__thumb2__
-+	itt	ne
-+#endif
-+	movne	$tj,sp
-+	bne	.Louter
-+
-+	ldr	$rp,[$_rp]		@ pull rp
-+	mov	$aj,sp
-+	add	$num,$num,#4		@ $num to point at &tp[num]
-+	sub	$aj,$num,$aj		@ "original" num value
-+	mov	$tp,sp			@ "rewind" $tp
-+	mov	$ap,$tp			@ "borrow" $ap
-+	sub	$np,$np,$aj		@ "rewind" $np to &np[0]
-+
-+	subs	$tj,$tj,$tj		@ "clear" carry flag
-+.Lsub:	ldr	$tj,[$tp],#4
-+	ldr	$nj,[$np],#4
-+	sbcs	$tj,$tj,$nj		@ tp[j]-np[j]
-+	str	$tj,[$rp],#4		@ rp[j]=
-+	teq	$tp,$num		@ preserve carry
-+	bne	.Lsub
-+	sbcs	$nhi,$nhi,#0		@ upmost carry
-+	mov	$tp,sp			@ "rewind" $tp
-+	sub	$rp,$rp,$aj		@ "rewind" $rp
-+
-+	and	$ap,$tp,$nhi
-+	bic	$np,$rp,$nhi
-+	orr	$ap,$ap,$np		@ ap=borrow?tp:rp
-+
-+.Lcopy:	ldr	$tj,[$ap],#4		@ copy or in-place refresh
-+	str	sp,[$tp],#4		@ zap tp
-+	str	$tj,[$rp],#4
-+	cmp	$tp,$num
-+	bne	.Lcopy
-+
-+	mov	sp,$num
-+	add	sp,sp,#4		@ skip over tp[num+1]
-+	ldmia	sp!,{r4-r12,lr}		@ restore registers
-+	add	sp,sp,#2*4		@ skip over {r0,r2}
-+	mov	r0,#1
-+.Labrt:
-+#if __ARM_ARCH__>=5
-+	ret				@ bx lr
-+#else
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	bn_mul_mont,.-bn_mul_mont
-+___
-+{
-+my ($A0,$A1,$A2,$A3)=map("d$_",(0..3));
-+my ($N0,$N1,$N2,$N3)=map("d$_",(4..7));
-+my ($Z,$Temp)=("q4","q5");
-+my @ACC=map("q$_",(6..13));
-+my ($Bi,$Ni,$M0)=map("d$_",(28..31));
-+my $zero="$Z#lo";
-+my $temp="$Temp#lo";
-+
-+my ($rptr,$aptr,$bptr,$nptr,$n0,$num)=map("r$_",(0..5));
-+my ($tinptr,$toutptr,$inner,$outer,$bnptr)=map("r$_",(6..11));
-+
-+$code.=<<___;
-+#if __ARM_MAX_ARCH__>=7
-+.arch	armv7-a
-+.fpu	neon
-+
-+.type	bn_mul8x_mont_neon,%function
-+.align	5
-+bn_mul8x_mont_neon:
-+	mov	ip,sp
-+	stmdb	sp!,{r4-r11}
-+	vstmdb	sp!,{d8-d15}		@ ABI specification says so
-+	ldmia	ip,{r4-r5}		@ load rest of parameter block
-+	mov	ip,sp
-+
-+	cmp	$num,#8
-+	bhi	.LNEON_8n
-+
-+	@ special case for $num==8, everything is in register bank...
-+
-+	vld1.32		{${Bi}[0]}, [$bptr,:32]!
-+	veor		$zero,$zero,$zero
-+	sub		$toutptr,sp,$num,lsl#4
-+	vld1.32		{$A0-$A3},  [$aptr]!		@ can't specify :32 :-(
-+	and		$toutptr,$toutptr,#-64
-+	vld1.32		{${M0}[0]}, [$n0,:32]
-+	mov		sp,$toutptr			@ alloca
-+	vzip.16		$Bi,$zero
-+
-+	vmull.u32	@ACC[0],$Bi,${A0}[0]
-+	vmull.u32	@ACC[1],$Bi,${A0}[1]
-+	vmull.u32	@ACC[2],$Bi,${A1}[0]
-+	vshl.i64	$Ni,@ACC[0]#hi,#16
-+	vmull.u32	@ACC[3],$Bi,${A1}[1]
-+
-+	vadd.u64	$Ni,$Ni,@ACC[0]#lo
-+	veor		$zero,$zero,$zero
-+	vmul.u32	$Ni,$Ni,$M0
-+
-+	vmull.u32	@ACC[4],$Bi,${A2}[0]
-+	 vld1.32	{$N0-$N3}, [$nptr]!
-+	vmull.u32	@ACC[5],$Bi,${A2}[1]
-+	vmull.u32	@ACC[6],$Bi,${A3}[0]
-+	vzip.16		$Ni,$zero
-+	vmull.u32	@ACC[7],$Bi,${A3}[1]
-+
-+	vmlal.u32	@ACC[0],$Ni,${N0}[0]
-+	sub		$outer,$num,#1
-+	vmlal.u32	@ACC[1],$Ni,${N0}[1]
-+	vmlal.u32	@ACC[2],$Ni,${N1}[0]
-+	vmlal.u32	@ACC[3],$Ni,${N1}[1]
-+
-+	vmlal.u32	@ACC[4],$Ni,${N2}[0]
-+	vmov		$Temp,@ACC[0]
-+	vmlal.u32	@ACC[5],$Ni,${N2}[1]
-+	vmov		@ACC[0],@ACC[1]
-+	vmlal.u32	@ACC[6],$Ni,${N3}[0]
-+	vmov		@ACC[1],@ACC[2]
-+	vmlal.u32	@ACC[7],$Ni,${N3}[1]
-+	vmov		@ACC[2],@ACC[3]
-+	vmov		@ACC[3],@ACC[4]
-+	vshr.u64	$temp,$temp,#16
-+	vmov		@ACC[4],@ACC[5]
-+	vmov		@ACC[5],@ACC[6]
-+	vadd.u64	$temp,$temp,$Temp#hi
-+	vmov		@ACC[6],@ACC[7]
-+	veor		@ACC[7],@ACC[7]
-+	vshr.u64	$temp,$temp,#16
-+
-+	b	.LNEON_outer8
-+
-+.align	4
-+.LNEON_outer8:
-+	vld1.32		{${Bi}[0]}, [$bptr,:32]!
-+	veor		$zero,$zero,$zero
-+	vzip.16		$Bi,$zero
-+	vadd.u64	@ACC[0]#lo,@ACC[0]#lo,$temp
-+
-+	vmlal.u32	@ACC[0],$Bi,${A0}[0]
-+	vmlal.u32	@ACC[1],$Bi,${A0}[1]
-+	vmlal.u32	@ACC[2],$Bi,${A1}[0]
-+	vshl.i64	$Ni,@ACC[0]#hi,#16
-+	vmlal.u32	@ACC[3],$Bi,${A1}[1]
-+
-+	vadd.u64	$Ni,$Ni,@ACC[0]#lo
-+	veor		$zero,$zero,$zero
-+	subs		$outer,$outer,#1
-+	vmul.u32	$Ni,$Ni,$M0
-+
-+	vmlal.u32	@ACC[4],$Bi,${A2}[0]
-+	vmlal.u32	@ACC[5],$Bi,${A2}[1]
-+	vmlal.u32	@ACC[6],$Bi,${A3}[0]
-+	vzip.16		$Ni,$zero
-+	vmlal.u32	@ACC[7],$Bi,${A3}[1]
-+
-+	vmlal.u32	@ACC[0],$Ni,${N0}[0]
-+	vmlal.u32	@ACC[1],$Ni,${N0}[1]
-+	vmlal.u32	@ACC[2],$Ni,${N1}[0]
-+	vmlal.u32	@ACC[3],$Ni,${N1}[1]
-+
-+	vmlal.u32	@ACC[4],$Ni,${N2}[0]
-+	vmov		$Temp,@ACC[0]
-+	vmlal.u32	@ACC[5],$Ni,${N2}[1]
-+	vmov		@ACC[0],@ACC[1]
-+	vmlal.u32	@ACC[6],$Ni,${N3}[0]
-+	vmov		@ACC[1],@ACC[2]
-+	vmlal.u32	@ACC[7],$Ni,${N3}[1]
-+	vmov		@ACC[2],@ACC[3]
-+	vmov		@ACC[3],@ACC[4]
-+	vshr.u64	$temp,$temp,#16
-+	vmov		@ACC[4],@ACC[5]
-+	vmov		@ACC[5],@ACC[6]
-+	vadd.u64	$temp,$temp,$Temp#hi
-+	vmov		@ACC[6],@ACC[7]
-+	veor		@ACC[7],@ACC[7]
-+	vshr.u64	$temp,$temp,#16
-+
-+	bne	.LNEON_outer8
-+
-+	vadd.u64	@ACC[0]#lo,@ACC[0]#lo,$temp
-+	mov		$toutptr,sp
-+	vshr.u64	$temp,@ACC[0]#lo,#16
-+	mov		$inner,$num
-+	vadd.u64	@ACC[0]#hi,@ACC[0]#hi,$temp
-+	add		$tinptr,sp,#96
-+	vshr.u64	$temp,@ACC[0]#hi,#16
-+	vzip.16		@ACC[0]#lo,@ACC[0]#hi
-+
-+	b	.LNEON_tail_entry
-+
-+.align	4
-+.LNEON_8n:
-+	veor		@ACC[0],@ACC[0],@ACC[0]
-+	 sub		$toutptr,sp,#128
-+	veor		@ACC[1],@ACC[1],@ACC[1]
-+	 sub		$toutptr,$toutptr,$num,lsl#4
-+	veor		@ACC[2],@ACC[2],@ACC[2]
-+	 and		$toutptr,$toutptr,#-64
-+	veor		@ACC[3],@ACC[3],@ACC[3]
-+	 mov		sp,$toutptr			@ alloca
-+	veor		@ACC[4],@ACC[4],@ACC[4]
-+	 add		$toutptr,$toutptr,#256
-+	veor		@ACC[5],@ACC[5],@ACC[5]
-+	 sub		$inner,$num,#8
-+	veor		@ACC[6],@ACC[6],@ACC[6]
-+	veor		@ACC[7],@ACC[7],@ACC[7]
-+
-+.LNEON_8n_init:
-+	vst1.64		{@ACC[0]-@ACC[1]},[$toutptr,:256]!
-+	subs		$inner,$inner,#8
-+	vst1.64		{@ACC[2]-@ACC[3]},[$toutptr,:256]!
-+	vst1.64		{@ACC[4]-@ACC[5]},[$toutptr,:256]!
-+	vst1.64		{@ACC[6]-@ACC[7]},[$toutptr,:256]!
-+	bne		.LNEON_8n_init
-+
-+	add		$tinptr,sp,#256
-+	vld1.32		{$A0-$A3},[$aptr]!
-+	add		$bnptr,sp,#8
-+	vld1.32		{${M0}[0]},[$n0,:32]
-+	mov		$outer,$num
-+	b		.LNEON_8n_outer
-+
-+.align	4
-+.LNEON_8n_outer:
-+	vld1.32		{${Bi}[0]},[$bptr,:32]!	@ *b++
-+	veor		$zero,$zero,$zero
-+	vzip.16		$Bi,$zero
-+	add		$toutptr,sp,#128
-+	vld1.32		{$N0-$N3},[$nptr]!
-+
-+	vmlal.u32	@ACC[0],$Bi,${A0}[0]
-+	vmlal.u32	@ACC[1],$Bi,${A0}[1]
-+	 veor		$zero,$zero,$zero
-+	vmlal.u32	@ACC[2],$Bi,${A1}[0]
-+	 vshl.i64	$Ni,@ACC[0]#hi,#16
-+	vmlal.u32	@ACC[3],$Bi,${A1}[1]
-+	 vadd.u64	$Ni,$Ni,@ACC[0]#lo
-+	vmlal.u32	@ACC[4],$Bi,${A2}[0]
-+	 vmul.u32	$Ni,$Ni,$M0
-+	vmlal.u32	@ACC[5],$Bi,${A2}[1]
-+	vst1.32		{$Bi},[sp,:64]		@ put aside smashed b[8*i+0]
-+	vmlal.u32	@ACC[6],$Bi,${A3}[0]
-+	 vzip.16	$Ni,$zero
-+	vmlal.u32	@ACC[7],$Bi,${A3}[1]
-+___
-+for ($i=0; $i<7;) {
-+$code.=<<___;
-+	vld1.32		{${Bi}[0]},[$bptr,:32]!	@ *b++
-+	vmlal.u32	@ACC[0],$Ni,${N0}[0]
-+	veor		$temp,$temp,$temp
-+	vmlal.u32	@ACC[1],$Ni,${N0}[1]
-+	vzip.16		$Bi,$temp
-+	vmlal.u32	@ACC[2],$Ni,${N1}[0]
-+	 vshr.u64	@ACC[0]#lo,@ACC[0]#lo,#16
-+	vmlal.u32	@ACC[3],$Ni,${N1}[1]
-+	vmlal.u32	@ACC[4],$Ni,${N2}[0]
-+	 vadd.u64	@ACC[0]#lo,@ACC[0]#lo,@ACC[0]#hi
-+	vmlal.u32	@ACC[5],$Ni,${N2}[1]
-+	 vshr.u64	@ACC[0]#lo,@ACC[0]#lo,#16
-+	vmlal.u32	@ACC[6],$Ni,${N3}[0]
-+	vmlal.u32	@ACC[7],$Ni,${N3}[1]
-+	 vadd.u64	@ACC[1]#lo,@ACC[1]#lo,@ACC[0]#lo
-+	vst1.32		{$Ni},[$bnptr,:64]!	@ put aside smashed m[8*i+$i]
-+___
-+	push(@ACC,shift(@ACC));	$i++;
-+$code.=<<___;
-+	vmlal.u32	@ACC[0],$Bi,${A0}[0]
-+	vld1.64		{@ACC[7]},[$tinptr,:128]!
-+	vmlal.u32	@ACC[1],$Bi,${A0}[1]
-+	 veor		$zero,$zero,$zero
-+	vmlal.u32	@ACC[2],$Bi,${A1}[0]
-+	 vshl.i64	$Ni,@ACC[0]#hi,#16
-+	vmlal.u32	@ACC[3],$Bi,${A1}[1]
-+	 vadd.u64	$Ni,$Ni,@ACC[0]#lo
-+	vmlal.u32	@ACC[4],$Bi,${A2}[0]
-+	 vmul.u32	$Ni,$Ni,$M0
-+	vmlal.u32	@ACC[5],$Bi,${A2}[1]
-+	vst1.32		{$Bi},[$bnptr,:64]!	@ put aside smashed b[8*i+$i]
-+	vmlal.u32	@ACC[6],$Bi,${A3}[0]
-+	 vzip.16	$Ni,$zero
-+	vmlal.u32	@ACC[7],$Bi,${A3}[1]
-+___
-+}
-+$code.=<<___;
-+	vld1.32		{$Bi},[sp,:64]		@ pull smashed b[8*i+0]
-+	vmlal.u32	@ACC[0],$Ni,${N0}[0]
-+	vld1.32		{$A0-$A3},[$aptr]!
-+	vmlal.u32	@ACC[1],$Ni,${N0}[1]
-+	vmlal.u32	@ACC[2],$Ni,${N1}[0]
-+	 vshr.u64	@ACC[0]#lo,@ACC[0]#lo,#16
-+	vmlal.u32	@ACC[3],$Ni,${N1}[1]
-+	vmlal.u32	@ACC[4],$Ni,${N2}[0]
-+	 vadd.u64	@ACC[0]#lo,@ACC[0]#lo,@ACC[0]#hi
-+	vmlal.u32	@ACC[5],$Ni,${N2}[1]
-+	 vshr.u64	@ACC[0]#lo,@ACC[0]#lo,#16
-+	vmlal.u32	@ACC[6],$Ni,${N3}[0]
-+	vmlal.u32	@ACC[7],$Ni,${N3}[1]
-+	 vadd.u64	@ACC[1]#lo,@ACC[1]#lo,@ACC[0]#lo
-+	vst1.32		{$Ni},[$bnptr,:64]	@ put aside smashed m[8*i+$i]
-+	add		$bnptr,sp,#8		@ rewind
-+___
-+	push(@ACC,shift(@ACC));
-+$code.=<<___;
-+	sub		$inner,$num,#8
-+	b		.LNEON_8n_inner
-+
-+.align	4
-+.LNEON_8n_inner:
-+	subs		$inner,$inner,#8
-+	vmlal.u32	@ACC[0],$Bi,${A0}[0]
-+	vld1.64		{@ACC[7]},[$tinptr,:128]
-+	vmlal.u32	@ACC[1],$Bi,${A0}[1]
-+	vld1.32		{$Ni},[$bnptr,:64]!	@ pull smashed m[8*i+0]
-+	vmlal.u32	@ACC[2],$Bi,${A1}[0]
-+	vld1.32		{$N0-$N3},[$nptr]!
-+	vmlal.u32	@ACC[3],$Bi,${A1}[1]
-+	it		ne
-+	addne		$tinptr,$tinptr,#16	@ don't advance in last iteration
-+	vmlal.u32	@ACC[4],$Bi,${A2}[0]
-+	vmlal.u32	@ACC[5],$Bi,${A2}[1]
-+	vmlal.u32	@ACC[6],$Bi,${A3}[0]
-+	vmlal.u32	@ACC[7],$Bi,${A3}[1]
-+___
-+for ($i=1; $i<8; $i++) {
-+$code.=<<___;
-+	vld1.32		{$Bi},[$bnptr,:64]!	@ pull smashed b[8*i+$i]
-+	vmlal.u32	@ACC[0],$Ni,${N0}[0]
-+	vmlal.u32	@ACC[1],$Ni,${N0}[1]
-+	vmlal.u32	@ACC[2],$Ni,${N1}[0]
-+	vmlal.u32	@ACC[3],$Ni,${N1}[1]
-+	vmlal.u32	@ACC[4],$Ni,${N2}[0]
-+	vmlal.u32	@ACC[5],$Ni,${N2}[1]
-+	vmlal.u32	@ACC[6],$Ni,${N3}[0]
-+	vmlal.u32	@ACC[7],$Ni,${N3}[1]
-+	vst1.64		{@ACC[0]},[$toutptr,:128]!
-+___
-+	push(@ACC,shift(@ACC));
-+$code.=<<___;
-+	vmlal.u32	@ACC[0],$Bi,${A0}[0]
-+	vld1.64		{@ACC[7]},[$tinptr,:128]
-+	vmlal.u32	@ACC[1],$Bi,${A0}[1]
-+	vld1.32		{$Ni},[$bnptr,:64]!	@ pull smashed m[8*i+$i]
-+	vmlal.u32	@ACC[2],$Bi,${A1}[0]
-+	it		ne
-+	addne		$tinptr,$tinptr,#16	@ don't advance in last iteration
-+	vmlal.u32	@ACC[3],$Bi,${A1}[1]
-+	vmlal.u32	@ACC[4],$Bi,${A2}[0]
-+	vmlal.u32	@ACC[5],$Bi,${A2}[1]
-+	vmlal.u32	@ACC[6],$Bi,${A3}[0]
-+	vmlal.u32	@ACC[7],$Bi,${A3}[1]
-+___
-+}
-+$code.=<<___;
-+	it		eq
-+	subeq		$aptr,$aptr,$num,lsl#2	@ rewind
-+	vmlal.u32	@ACC[0],$Ni,${N0}[0]
-+	vld1.32		{$Bi},[sp,:64]		@ pull smashed b[8*i+0]
-+	vmlal.u32	@ACC[1],$Ni,${N0}[1]
-+	vld1.32		{$A0-$A3},[$aptr]!
-+	vmlal.u32	@ACC[2],$Ni,${N1}[0]
-+	add		$bnptr,sp,#8		@ rewind
-+	vmlal.u32	@ACC[3],$Ni,${N1}[1]
-+	vmlal.u32	@ACC[4],$Ni,${N2}[0]
-+	vmlal.u32	@ACC[5],$Ni,${N2}[1]
-+	vmlal.u32	@ACC[6],$Ni,${N3}[0]
-+	vst1.64		{@ACC[0]},[$toutptr,:128]!
-+	vmlal.u32	@ACC[7],$Ni,${N3}[1]
-+
-+	bne		.LNEON_8n_inner
-+___
-+	push(@ACC,shift(@ACC));
-+$code.=<<___;
-+	add		$tinptr,sp,#128
-+	vst1.64		{@ACC[0]-@ACC[1]},[$toutptr,:256]!
-+	veor		q2,q2,q2		@ $N0-$N1
-+	vst1.64		{@ACC[2]-@ACC[3]},[$toutptr,:256]!
-+	veor		q3,q3,q3		@ $N2-$N3
-+	vst1.64		{@ACC[4]-@ACC[5]},[$toutptr,:256]!
-+	vst1.64		{@ACC[6]},[$toutptr,:128]
-+
-+	subs		$outer,$outer,#8
-+	vld1.64		{@ACC[0]-@ACC[1]},[$tinptr,:256]!
-+	vld1.64		{@ACC[2]-@ACC[3]},[$tinptr,:256]!
-+	vld1.64		{@ACC[4]-@ACC[5]},[$tinptr,:256]!
-+	vld1.64		{@ACC[6]-@ACC[7]},[$tinptr,:256]!
-+
-+	itt		ne
-+	subne		$nptr,$nptr,$num,lsl#2	@ rewind
-+	bne		.LNEON_8n_outer
-+
-+	add		$toutptr,sp,#128
-+	vst1.64		{q2-q3}, [sp,:256]!	@ start wiping stack frame
-+	vshr.u64	$temp,@ACC[0]#lo,#16
-+	vst1.64		{q2-q3},[sp,:256]!
-+	vadd.u64	@ACC[0]#hi,@ACC[0]#hi,$temp
-+	vst1.64		{q2-q3}, [sp,:256]!
-+	vshr.u64	$temp,@ACC[0]#hi,#16
-+	vst1.64		{q2-q3}, [sp,:256]!
-+	vzip.16		@ACC[0]#lo,@ACC[0]#hi
-+
-+	mov		$inner,$num
-+	b		.LNEON_tail_entry
-+
-+.align	4
-+.LNEON_tail:
-+	vadd.u64	@ACC[0]#lo,@ACC[0]#lo,$temp
-+	vshr.u64	$temp,@ACC[0]#lo,#16
-+	vld1.64		{@ACC[2]-@ACC[3]}, [$tinptr, :256]!
-+	vadd.u64	@ACC[0]#hi,@ACC[0]#hi,$temp
-+	vld1.64		{@ACC[4]-@ACC[5]}, [$tinptr, :256]!
-+	vshr.u64	$temp,@ACC[0]#hi,#16
-+	vld1.64		{@ACC[6]-@ACC[7]}, [$tinptr, :256]!
-+	vzip.16		@ACC[0]#lo,@ACC[0]#hi
-+
-+.LNEON_tail_entry:
-+___
-+for ($i=1; $i<8; $i++) {
-+$code.=<<___;
-+	vadd.u64	@ACC[1]#lo,@ACC[1]#lo,$temp
-+	vst1.32		{@ACC[0]#lo[0]}, [$toutptr, :32]!
-+	vshr.u64	$temp,@ACC[1]#lo,#16
-+	vadd.u64	@ACC[1]#hi,@ACC[1]#hi,$temp
-+	vshr.u64	$temp,@ACC[1]#hi,#16
-+	vzip.16		@ACC[1]#lo,@ACC[1]#hi
-+___
-+	push(@ACC,shift(@ACC));
-+}
-+	push(@ACC,shift(@ACC));
-+$code.=<<___;
-+	vld1.64		{@ACC[0]-@ACC[1]}, [$tinptr, :256]!
-+	subs		$inner,$inner,#8
-+	vst1.32		{@ACC[7]#lo[0]},   [$toutptr, :32]!
-+	bne	.LNEON_tail
-+
-+	vst1.32	{${temp}[0]}, [$toutptr, :32]		@ top-most bit
-+	sub	$nptr,$nptr,$num,lsl#2			@ rewind $nptr
-+	subs	$aptr,sp,#0				@ clear carry flag
-+	add	$bptr,sp,$num,lsl#2
-+
-+.LNEON_sub:
-+	ldmia	$aptr!, {r4-r7}
-+	ldmia	$nptr!, {r8-r11}
-+	sbcs	r8, r4,r8
-+	sbcs	r9, r5,r9
-+	sbcs	r10,r6,r10
-+	sbcs	r11,r7,r11
-+	teq	$aptr,$bptr				@ preserves carry
-+	stmia	$rptr!, {r8-r11}
-+	bne	.LNEON_sub
-+
-+	ldr	r10, [$aptr]				@ load top-most bit
-+	mov	r11,sp
-+	veor	q0,q0,q0
-+	sub	r11,$bptr,r11				@ this is num*4
-+	veor	q1,q1,q1
-+	mov	$aptr,sp
-+	sub	$rptr,$rptr,r11				@ rewind $rptr
-+	mov	$nptr,$bptr				@ second 3/4th of frame
-+	sbcs	r10,r10,#0				@ result is carry flag
-+
-+.LNEON_copy_n_zap:
-+	ldmia	$aptr!, {r4-r7}
-+	ldmia	$rptr,  {r8-r11}
-+	it	cc
-+	movcc	r8, r4
-+	vst1.64	{q0-q1}, [$nptr,:256]!			@ wipe
-+	itt	cc
-+	movcc	r9, r5
-+	movcc	r10,r6
-+	vst1.64	{q0-q1}, [$nptr,:256]!			@ wipe
-+	it	cc
-+	movcc	r11,r7
-+	ldmia	$aptr, {r4-r7}
-+	stmia	$rptr!, {r8-r11}
-+	sub	$aptr,$aptr,#16
-+	ldmia	$rptr, {r8-r11}
-+	it	cc
-+	movcc	r8, r4
-+	vst1.64	{q0-q1}, [$aptr,:256]!			@ wipe
-+	itt	cc
-+	movcc	r9, r5
-+	movcc	r10,r6
-+	vst1.64	{q0-q1}, [$nptr,:256]!			@ wipe
-+	it	cc
-+	movcc	r11,r7
-+	teq	$aptr,$bptr				@ preserves carry
-+	stmia	$rptr!, {r8-r11}
-+	bne	.LNEON_copy_n_zap
-+
-+	mov	sp,ip
-+        vldmia  sp!,{d8-d15}
-+        ldmia   sp!,{r4-r11}
-+	ret						@ bx lr
-+.size	bn_mul8x_mont_neon,.-bn_mul8x_mont_neon
-+#endif
-+___
-+}
-+$code.=<<___;
-+.asciz	"Montgomery multiplication for ARMv4/NEON, CRYPTOGAMS by "
-+.align	2
-+#if __ARM_MAX_ARCH__>=7
-+.comm	OPENSSL_armcap_P,4,4
-+#endif
-+___
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/ge	or
-+	s/\bret\b/bx    lr/g						or
-+	s/\bbx\s+lr\b/.word\t0xe12fff1e/g;	# make it possible to compile with -march=armv4
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv8-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv8-mont.pl
-new file mode 100755
-index 0000000..5d5af1b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/armv8-mont.pl
-@@ -0,0 +1,1510 @@
-+#! /usr/bin/env perl
-+# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# March 2015
-+#
-+# "Teaser" Montgomery multiplication module for ARMv8. Needs more
-+# work. While it does improve RSA sign performance by 20-30% (less for
-+# longer keys) on most processors, for some reason RSA2048 is not
-+# faster and RSA4096 goes 15-20% slower on Cortex-A57. Multiplication
-+# instruction issue rate is limited on processor in question, meaning
-+# that dedicated squaring procedure is a must. Well, actually all
-+# contemporary AArch64 processors seem to have limited multiplication
-+# issue rate, i.e. they can't issue multiplication every cycle, which
-+# explains moderate improvement coefficients in comparison to
-+# compiler-generated code. Recall that compiler is instructed to use
-+# umulh and therefore uses same amount of multiplication instructions
-+# to do the job. Assembly's edge is to minimize number of "collateral"
-+# instructions and of course instruction scheduling.
-+#
-+# April 2015
-+#
-+# Squaring procedure that handles lengths divisible by 8 improves
-+# RSA/DSA performance by 25-40-60% depending on processor and key
-+# length. Overall improvement coefficients are always positive in
-+# comparison to compiler-generated code. On Cortex-A57 improvement
-+# is still modest on longest key lengths, while others exhibit e.g.
-+# 50-70% improvement for RSA4096 sign. RSA2048 sign is ~25% faster
-+# on Cortex-A57 and ~60-100% faster on others.
-+
-+$flavour = shift;
-+$output  = shift;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+($lo0,$hi0,$aj,$m0,$alo,$ahi,
-+ $lo1,$hi1,$nj,$m1,$nlo,$nhi,
-+ $ovf, $i,$j,$tp,$tj) = map("x$_",6..17,19..24);
-+
-+# int bn_mul_mont(
-+$rp="x0";	# BN_ULONG *rp,
-+$ap="x1";	# const BN_ULONG *ap,
-+$bp="x2";	# const BN_ULONG *bp,
-+$np="x3";	# const BN_ULONG *np,
-+$n0="x4";	# const BN_ULONG *n0,
-+$num="x5";	# int num);
-+
-+$code.=<<___;
-+.text
-+
-+.globl	bn_mul_mont
-+.type	bn_mul_mont,%function
-+.align	5
-+bn_mul_mont:
-+	tst	$num,#7
-+	b.eq	__bn_sqr8x_mont
-+	tst	$num,#3
-+	b.eq	__bn_mul4x_mont
-+.Lmul_mont:
-+	stp	x29,x30,[sp,#-64]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	stp	x23,x24,[sp,#48]
-+
-+	ldr	$m0,[$bp],#8		// bp[0]
-+	sub	$tp,sp,$num,lsl#3
-+	ldp	$hi0,$aj,[$ap],#16	// ap[0..1]
-+	lsl	$num,$num,#3
-+	ldr	$n0,[$n0]		// *n0
-+	and	$tp,$tp,#-16		// ABI says so
-+	ldp	$hi1,$nj,[$np],#16	// np[0..1]
-+
-+	mul	$lo0,$hi0,$m0		// ap[0]*bp[0]
-+	sub	$j,$num,#16		// j=num-2
-+	umulh	$hi0,$hi0,$m0
-+	mul	$alo,$aj,$m0		// ap[1]*bp[0]
-+	umulh	$ahi,$aj,$m0
-+
-+	mul	$m1,$lo0,$n0		// "tp[0]"*n0
-+	mov	sp,$tp			// alloca
-+
-+	// (*)	mul	$lo1,$hi1,$m1	// np[0]*m1
-+	umulh	$hi1,$hi1,$m1
-+	mul	$nlo,$nj,$m1		// np[1]*m1
-+	// (*)	adds	$lo1,$lo1,$lo0	// discarded
-+	// (*)	As for removal of first multiplication and addition
-+	//	instructions. The outcome of first addition is
-+	//	guaranteed to be zero, which leaves two computationally
-+	//	significant outcomes: it either carries or not. Then
-+	//	question is when does it carry? Is there alternative
-+	//	way to deduce it? If you follow operations, you can
-+	//	observe that condition for carry is quite simple:
-+	//	$lo0 being non-zero. So that carry can be calculated
-+	//	by adding -1 to $lo0. That's what next instruction does.
-+	subs	xzr,$lo0,#1		// (*)
-+	umulh	$nhi,$nj,$m1
-+	adc	$hi1,$hi1,xzr
-+	cbz	$j,.L1st_skip
-+
-+.L1st:
-+	ldr	$aj,[$ap],#8
-+	adds	$lo0,$alo,$hi0
-+	sub	$j,$j,#8		// j--
-+	adc	$hi0,$ahi,xzr
-+
-+	ldr	$nj,[$np],#8
-+	adds	$lo1,$nlo,$hi1
-+	mul	$alo,$aj,$m0		// ap[j]*bp[0]
-+	adc	$hi1,$nhi,xzr
-+	umulh	$ahi,$aj,$m0
-+
-+	adds	$lo1,$lo1,$lo0
-+	mul	$nlo,$nj,$m1		// np[j]*m1
-+	adc	$hi1,$hi1,xzr
-+	umulh	$nhi,$nj,$m1
-+	str	$lo1,[$tp],#8		// tp[j-1]
-+	cbnz	$j,.L1st
-+
-+.L1st_skip:
-+	adds	$lo0,$alo,$hi0
-+	sub	$ap,$ap,$num		// rewind $ap
-+	adc	$hi0,$ahi,xzr
-+
-+	adds	$lo1,$nlo,$hi1
-+	sub	$np,$np,$num		// rewind $np
-+	adc	$hi1,$nhi,xzr
-+
-+	adds	$lo1,$lo1,$lo0
-+	sub	$i,$num,#8		// i=num-1
-+	adcs	$hi1,$hi1,$hi0
-+
-+	adc	$ovf,xzr,xzr		// upmost overflow bit
-+	stp	$lo1,$hi1,[$tp]
-+
-+.Louter:
-+	ldr	$m0,[$bp],#8		// bp[i]
-+	ldp	$hi0,$aj,[$ap],#16
-+	ldr	$tj,[sp]		// tp[0]
-+	add	$tp,sp,#8
-+
-+	mul	$lo0,$hi0,$m0		// ap[0]*bp[i]
-+	sub	$j,$num,#16		// j=num-2
-+	umulh	$hi0,$hi0,$m0
-+	ldp	$hi1,$nj,[$np],#16
-+	mul	$alo,$aj,$m0		// ap[1]*bp[i]
-+	adds	$lo0,$lo0,$tj
-+	umulh	$ahi,$aj,$m0
-+	adc	$hi0,$hi0,xzr
-+
-+	mul	$m1,$lo0,$n0
-+	sub	$i,$i,#8		// i--
-+
-+	// (*)	mul	$lo1,$hi1,$m1	// np[0]*m1
-+	umulh	$hi1,$hi1,$m1
-+	mul	$nlo,$nj,$m1		// np[1]*m1
-+	// (*)	adds	$lo1,$lo1,$lo0
-+	subs	xzr,$lo0,#1		// (*)
-+	umulh	$nhi,$nj,$m1
-+	cbz	$j,.Linner_skip
-+
-+.Linner:
-+	ldr	$aj,[$ap],#8
-+	adc	$hi1,$hi1,xzr
-+	ldr	$tj,[$tp],#8		// tp[j]
-+	adds	$lo0,$alo,$hi0
-+	sub	$j,$j,#8		// j--
-+	adc	$hi0,$ahi,xzr
-+
-+	adds	$lo1,$nlo,$hi1
-+	ldr	$nj,[$np],#8
-+	adc	$hi1,$nhi,xzr
-+
-+	mul	$alo,$aj,$m0		// ap[j]*bp[i]
-+	adds	$lo0,$lo0,$tj
-+	umulh	$ahi,$aj,$m0
-+	adc	$hi0,$hi0,xzr
-+
-+	mul	$nlo,$nj,$m1		// np[j]*m1
-+	adds	$lo1,$lo1,$lo0
-+	umulh	$nhi,$nj,$m1
-+	str	$lo1,[$tp,#-16]		// tp[j-1]
-+	cbnz	$j,.Linner
-+
-+.Linner_skip:
-+	ldr	$tj,[$tp],#8		// tp[j]
-+	adc	$hi1,$hi1,xzr
-+	adds	$lo0,$alo,$hi0
-+	sub	$ap,$ap,$num		// rewind $ap
-+	adc	$hi0,$ahi,xzr
-+
-+	adds	$lo1,$nlo,$hi1
-+	sub	$np,$np,$num		// rewind $np
-+	adcs	$hi1,$nhi,$ovf
-+	adc	$ovf,xzr,xzr
-+
-+	adds	$lo0,$lo0,$tj
-+	adc	$hi0,$hi0,xzr
-+
-+	adds	$lo1,$lo1,$lo0
-+	adcs	$hi1,$hi1,$hi0
-+	adc	$ovf,$ovf,xzr		// upmost overflow bit
-+	stp	$lo1,$hi1,[$tp,#-16]
-+
-+	cbnz	$i,.Louter
-+
-+	// Final step. We see if result is larger than modulus, and
-+	// if it is, subtract the modulus. But comparison implies
-+	// subtraction. So we subtract modulus, see if it borrowed,
-+	// and conditionally copy original value.
-+	ldr	$tj,[sp]		// tp[0]
-+	add	$tp,sp,#8
-+	ldr	$nj,[$np],#8		// np[0]
-+	subs	$j,$num,#8		// j=num-1 and clear borrow
-+	mov	$ap,$rp
-+.Lsub:
-+	sbcs	$aj,$tj,$nj		// tp[j]-np[j]
-+	ldr	$tj,[$tp],#8
-+	sub	$j,$j,#8		// j--
-+	ldr	$nj,[$np],#8
-+	str	$aj,[$ap],#8		// rp[j]=tp[j]-np[j]
-+	cbnz	$j,.Lsub
-+
-+	sbcs	$aj,$tj,$nj
-+	sbcs	$ovf,$ovf,xzr		// did it borrow?
-+	str	$aj,[$ap],#8		// rp[num-1]
-+
-+	ldr	$tj,[sp]		// tp[0]
-+	add	$tp,sp,#8
-+	ldr	$aj,[$rp],#8		// rp[0]
-+	sub	$num,$num,#8		// num--
-+	nop
-+.Lcond_copy:
-+	sub	$num,$num,#8		// num--
-+	csel	$nj,$tj,$aj,lo		// did it borrow?
-+	ldr	$tj,[$tp],#8
-+	ldr	$aj,[$rp],#8
-+	str	xzr,[$tp,#-16]		// wipe tp
-+	str	$nj,[$rp,#-16]
-+	cbnz	$num,.Lcond_copy
-+
-+	csel	$nj,$tj,$aj,lo
-+	str	xzr,[$tp,#-8]		// wipe tp
-+	str	$nj,[$rp,#-8]
-+
-+	ldp	x19,x20,[x29,#16]
-+	mov	sp,x29
-+	ldp	x21,x22,[x29,#32]
-+	mov	x0,#1
-+	ldp	x23,x24,[x29,#48]
-+	ldr	x29,[sp],#64
-+	ret
-+.size	bn_mul_mont,.-bn_mul_mont
-+___
-+{
-+########################################################################
-+# Following is ARMv8 adaptation of sqrx8x_mont from x86_64-mont5 module.
-+
-+my ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("x$_",(6..13));
-+my ($t0,$t1,$t2,$t3)=map("x$_",(14..17));
-+my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7)=map("x$_",(19..26));
-+my ($cnt,$carry,$topmost)=("x27","x28","x30");
-+my ($tp,$ap_end,$na0)=($bp,$np,$carry);
-+
-+$code.=<<___;
-+.type	__bn_sqr8x_mont,%function
-+.align	5
-+__bn_sqr8x_mont:
-+	cmp	$ap,$bp
-+	b.ne	__bn_mul4x_mont
-+.Lsqr8x_mont:
-+	stp	x29,x30,[sp,#-128]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	stp	x23,x24,[sp,#48]
-+	stp	x25,x26,[sp,#64]
-+	stp	x27,x28,[sp,#80]
-+	stp	$rp,$np,[sp,#96]	// offload rp and np
-+
-+	ldp	$a0,$a1,[$ap,#8*0]
-+	ldp	$a2,$a3,[$ap,#8*2]
-+	ldp	$a4,$a5,[$ap,#8*4]
-+	ldp	$a6,$a7,[$ap,#8*6]
-+
-+	sub	$tp,sp,$num,lsl#4
-+	lsl	$num,$num,#3
-+	ldr	$n0,[$n0]		// *n0
-+	mov	sp,$tp			// alloca
-+	sub	$cnt,$num,#8*8
-+	b	.Lsqr8x_zero_start
-+
-+.Lsqr8x_zero:
-+	sub	$cnt,$cnt,#8*8
-+	stp	xzr,xzr,[$tp,#8*0]
-+	stp	xzr,xzr,[$tp,#8*2]
-+	stp	xzr,xzr,[$tp,#8*4]
-+	stp	xzr,xzr,[$tp,#8*6]
-+.Lsqr8x_zero_start:
-+	stp	xzr,xzr,[$tp,#8*8]
-+	stp	xzr,xzr,[$tp,#8*10]
-+	stp	xzr,xzr,[$tp,#8*12]
-+	stp	xzr,xzr,[$tp,#8*14]
-+	add	$tp,$tp,#8*16
-+	cbnz	$cnt,.Lsqr8x_zero
-+
-+	add	$ap_end,$ap,$num
-+	add	$ap,$ap,#8*8
-+	mov	$acc0,xzr
-+	mov	$acc1,xzr
-+	mov	$acc2,xzr
-+	mov	$acc3,xzr
-+	mov	$acc4,xzr
-+	mov	$acc5,xzr
-+	mov	$acc6,xzr
-+	mov	$acc7,xzr
-+	mov	$tp,sp
-+	str	$n0,[x29,#112]		// offload n0
-+
-+	// Multiply everything but a[i]*a[i]
-+.align	4
-+.Lsqr8x_outer_loop:
-+        //                                                 a[1]a[0]	(i)
-+        //                                             a[2]a[0]
-+        //                                         a[3]a[0]
-+        //                                     a[4]a[0]
-+        //                                 a[5]a[0]
-+        //                             a[6]a[0]
-+        //                         a[7]a[0]
-+        //                                         a[2]a[1]		(ii)
-+        //                                     a[3]a[1]
-+        //                                 a[4]a[1]
-+        //                             a[5]a[1]
-+        //                         a[6]a[1]
-+        //                     a[7]a[1]
-+        //                                 a[3]a[2]			(iii)
-+        //                             a[4]a[2]
-+        //                         a[5]a[2]
-+        //                     a[6]a[2]
-+        //                 a[7]a[2]
-+        //                         a[4]a[3]				(iv)
-+        //                     a[5]a[3]
-+        //                 a[6]a[3]
-+        //             a[7]a[3]
-+        //                 a[5]a[4]					(v)
-+        //             a[6]a[4]
-+        //         a[7]a[4]
-+        //         a[6]a[5]						(vi)
-+        //     a[7]a[5]
-+        // a[7]a[6]							(vii)
-+
-+	mul	$t0,$a1,$a0		// lo(a[1..7]*a[0])		(i)
-+	mul	$t1,$a2,$a0
-+	mul	$t2,$a3,$a0
-+	mul	$t3,$a4,$a0
-+	adds	$acc1,$acc1,$t0		// t[1]+lo(a[1]*a[0])
-+	mul	$t0,$a5,$a0
-+	adcs	$acc2,$acc2,$t1
-+	mul	$t1,$a6,$a0
-+	adcs	$acc3,$acc3,$t2
-+	mul	$t2,$a7,$a0
-+	adcs	$acc4,$acc4,$t3
-+	umulh	$t3,$a1,$a0		// hi(a[1..7]*a[0])
-+	adcs	$acc5,$acc5,$t0
-+	umulh	$t0,$a2,$a0
-+	adcs	$acc6,$acc6,$t1
-+	umulh	$t1,$a3,$a0
-+	adcs	$acc7,$acc7,$t2
-+	umulh	$t2,$a4,$a0
-+	stp	$acc0,$acc1,[$tp],#8*2	// t[0..1]
-+	adc	$acc0,xzr,xzr		// t[8]
-+	adds	$acc2,$acc2,$t3		// t[2]+lo(a[1]*a[0])
-+	umulh	$t3,$a5,$a0
-+	adcs	$acc3,$acc3,$t0
-+	umulh	$t0,$a6,$a0
-+	adcs	$acc4,$acc4,$t1
-+	umulh	$t1,$a7,$a0
-+	adcs	$acc5,$acc5,$t2
-+	 mul	$t2,$a2,$a1		// lo(a[2..7]*a[1])		(ii)
-+	adcs	$acc6,$acc6,$t3
-+	 mul	$t3,$a3,$a1
-+	adcs	$acc7,$acc7,$t0
-+	 mul	$t0,$a4,$a1
-+	adc	$acc0,$acc0,$t1
-+
-+	mul	$t1,$a5,$a1
-+	adds	$acc3,$acc3,$t2
-+	mul	$t2,$a6,$a1
-+	adcs	$acc4,$acc4,$t3
-+	mul	$t3,$a7,$a1
-+	adcs	$acc5,$acc5,$t0
-+	umulh	$t0,$a2,$a1		// hi(a[2..7]*a[1])
-+	adcs	$acc6,$acc6,$t1
-+	umulh	$t1,$a3,$a1
-+	adcs	$acc7,$acc7,$t2
-+	umulh	$t2,$a4,$a1
-+	adcs	$acc0,$acc0,$t3
-+	umulh	$t3,$a5,$a1
-+	stp	$acc2,$acc3,[$tp],#8*2	// t[2..3]
-+	adc	$acc1,xzr,xzr		// t[9]
-+	adds	$acc4,$acc4,$t0
-+	umulh	$t0,$a6,$a1
-+	adcs	$acc5,$acc5,$t1
-+	umulh	$t1,$a7,$a1
-+	adcs	$acc6,$acc6,$t2
-+	 mul	$t2,$a3,$a2		// lo(a[3..7]*a[2])		(iii)
-+	adcs	$acc7,$acc7,$t3
-+	 mul	$t3,$a4,$a2
-+	adcs	$acc0,$acc0,$t0
-+	 mul	$t0,$a5,$a2
-+	adc	$acc1,$acc1,$t1
-+
-+	mul	$t1,$a6,$a2
-+	adds	$acc5,$acc5,$t2
-+	mul	$t2,$a7,$a2
-+	adcs	$acc6,$acc6,$t3
-+	umulh	$t3,$a3,$a2		// hi(a[3..7]*a[2])
-+	adcs	$acc7,$acc7,$t0
-+	umulh	$t0,$a4,$a2
-+	adcs	$acc0,$acc0,$t1
-+	umulh	$t1,$a5,$a2
-+	adcs	$acc1,$acc1,$t2
-+	umulh	$t2,$a6,$a2
-+	stp	$acc4,$acc5,[$tp],#8*2	// t[4..5]
-+	adc	$acc2,xzr,xzr		// t[10]
-+	adds	$acc6,$acc6,$t3
-+	umulh	$t3,$a7,$a2
-+	adcs	$acc7,$acc7,$t0
-+	 mul	$t0,$a4,$a3		// lo(a[4..7]*a[3])		(iv)
-+	adcs	$acc0,$acc0,$t1
-+	 mul	$t1,$a5,$a3
-+	adcs	$acc1,$acc1,$t2
-+	 mul	$t2,$a6,$a3
-+	adc	$acc2,$acc2,$t3
-+
-+	mul	$t3,$a7,$a3
-+	adds	$acc7,$acc7,$t0
-+	umulh	$t0,$a4,$a3		// hi(a[4..7]*a[3])
-+	adcs	$acc0,$acc0,$t1
-+	umulh	$t1,$a5,$a3
-+	adcs	$acc1,$acc1,$t2
-+	umulh	$t2,$a6,$a3
-+	adcs	$acc2,$acc2,$t3
-+	umulh	$t3,$a7,$a3
-+	stp	$acc6,$acc7,[$tp],#8*2	// t[6..7]
-+	adc	$acc3,xzr,xzr		// t[11]
-+	adds	$acc0,$acc0,$t0
-+	 mul	$t0,$a5,$a4		// lo(a[5..7]*a[4])		(v)
-+	adcs	$acc1,$acc1,$t1
-+	 mul	$t1,$a6,$a4
-+	adcs	$acc2,$acc2,$t2
-+	 mul	$t2,$a7,$a4
-+	adc	$acc3,$acc3,$t3
-+
-+	umulh	$t3,$a5,$a4		// hi(a[5..7]*a[4])
-+	adds	$acc1,$acc1,$t0
-+	umulh	$t0,$a6,$a4
-+	adcs	$acc2,$acc2,$t1
-+	umulh	$t1,$a7,$a4
-+	adcs	$acc3,$acc3,$t2
-+	 mul	$t2,$a6,$a5		// lo(a[6..7]*a[5])		(vi)
-+	adc	$acc4,xzr,xzr		// t[12]
-+	adds	$acc2,$acc2,$t3
-+	 mul	$t3,$a7,$a5
-+	adcs	$acc3,$acc3,$t0
-+	 umulh	$t0,$a6,$a5		// hi(a[6..7]*a[5])
-+	adc	$acc4,$acc4,$t1
-+
-+	umulh	$t1,$a7,$a5
-+	adds	$acc3,$acc3,$t2
-+	 mul	$t2,$a7,$a6		// lo(a[7]*a[6])		(vii)
-+	adcs	$acc4,$acc4,$t3
-+	 umulh	$t3,$a7,$a6		// hi(a[7]*a[6])
-+	adc	$acc5,xzr,xzr		// t[13]
-+	adds	$acc4,$acc4,$t0
-+	sub	$cnt,$ap_end,$ap	// done yet?
-+	adc	$acc5,$acc5,$t1
-+
-+	adds	$acc5,$acc5,$t2
-+	sub	$t0,$ap_end,$num	// rewinded ap
-+	adc	$acc6,xzr,xzr		// t[14]
-+	add	$acc6,$acc6,$t3
-+
-+	cbz	$cnt,.Lsqr8x_outer_break
-+
-+	mov	$n0,$a0
-+	ldp	$a0,$a1,[$tp,#8*0]
-+	ldp	$a2,$a3,[$tp,#8*2]
-+	ldp	$a4,$a5,[$tp,#8*4]
-+	ldp	$a6,$a7,[$tp,#8*6]
-+	adds	$acc0,$acc0,$a0
-+	adcs	$acc1,$acc1,$a1
-+	ldp	$a0,$a1,[$ap,#8*0]
-+	adcs	$acc2,$acc2,$a2
-+	adcs	$acc3,$acc3,$a3
-+	ldp	$a2,$a3,[$ap,#8*2]
-+	adcs	$acc4,$acc4,$a4
-+	adcs	$acc5,$acc5,$a5
-+	ldp	$a4,$a5,[$ap,#8*4]
-+	adcs	$acc6,$acc6,$a6
-+	mov	$rp,$ap
-+	adcs	$acc7,xzr,$a7
-+	ldp	$a6,$a7,[$ap,#8*6]
-+	add	$ap,$ap,#8*8
-+	//adc	$carry,xzr,xzr		// moved below
-+	mov	$cnt,#-8*8
-+
-+	//                                                         a[8]a[0]
-+	//                                                     a[9]a[0]
-+	//                                                 a[a]a[0]
-+	//                                             a[b]a[0]
-+	//                                         a[c]a[0]
-+	//                                     a[d]a[0]
-+	//                                 a[e]a[0]
-+	//                             a[f]a[0]
-+	//                                                     a[8]a[1]
-+	//                         a[f]a[1]........................
-+	//                                                 a[8]a[2]
-+	//                     a[f]a[2]........................
-+	//                                             a[8]a[3]
-+	//                 a[f]a[3]........................
-+	//                                         a[8]a[4]
-+	//             a[f]a[4]........................
-+	//                                     a[8]a[5]
-+	//         a[f]a[5]........................
-+	//                                 a[8]a[6]
-+	//     a[f]a[6]........................
-+	//                             a[8]a[7]
-+	// a[f]a[7]........................
-+.Lsqr8x_mul:
-+	mul	$t0,$a0,$n0
-+	adc	$carry,xzr,xzr		// carry bit, modulo-scheduled
-+	mul	$t1,$a1,$n0
-+	add	$cnt,$cnt,#8
-+	mul	$t2,$a2,$n0
-+	mul	$t3,$a3,$n0
-+	adds	$acc0,$acc0,$t0
-+	mul	$t0,$a4,$n0
-+	adcs	$acc1,$acc1,$t1
-+	mul	$t1,$a5,$n0
-+	adcs	$acc2,$acc2,$t2
-+	mul	$t2,$a6,$n0
-+	adcs	$acc3,$acc3,$t3
-+	mul	$t3,$a7,$n0
-+	adcs	$acc4,$acc4,$t0
-+	umulh	$t0,$a0,$n0
-+	adcs	$acc5,$acc5,$t1
-+	umulh	$t1,$a1,$n0
-+	adcs	$acc6,$acc6,$t2
-+	umulh	$t2,$a2,$n0
-+	adcs	$acc7,$acc7,$t3
-+	umulh	$t3,$a3,$n0
-+	adc	$carry,$carry,xzr
-+	str	$acc0,[$tp],#8
-+	adds	$acc0,$acc1,$t0
-+	umulh	$t0,$a4,$n0
-+	adcs	$acc1,$acc2,$t1
-+	umulh	$t1,$a5,$n0
-+	adcs	$acc2,$acc3,$t2
-+	umulh	$t2,$a6,$n0
-+	adcs	$acc3,$acc4,$t3
-+	umulh	$t3,$a7,$n0
-+	ldr	$n0,[$rp,$cnt]
-+	adcs	$acc4,$acc5,$t0
-+	adcs	$acc5,$acc6,$t1
-+	adcs	$acc6,$acc7,$t2
-+	adcs	$acc7,$carry,$t3
-+	//adc	$carry,xzr,xzr		// moved above
-+	cbnz	$cnt,.Lsqr8x_mul
-+					// note that carry flag is guaranteed
-+					// to be zero at this point
-+	cmp	$ap,$ap_end		// done yet?
-+	b.eq	.Lsqr8x_break
-+
-+	ldp	$a0,$a1,[$tp,#8*0]
-+	ldp	$a2,$a3,[$tp,#8*2]
-+	ldp	$a4,$a5,[$tp,#8*4]
-+	ldp	$a6,$a7,[$tp,#8*6]
-+	adds	$acc0,$acc0,$a0
-+	ldr	$n0,[$rp,#-8*8]
-+	adcs	$acc1,$acc1,$a1
-+	ldp	$a0,$a1,[$ap,#8*0]
-+	adcs	$acc2,$acc2,$a2
-+	adcs	$acc3,$acc3,$a3
-+	ldp	$a2,$a3,[$ap,#8*2]
-+	adcs	$acc4,$acc4,$a4
-+	adcs	$acc5,$acc5,$a5
-+	ldp	$a4,$a5,[$ap,#8*4]
-+	adcs	$acc6,$acc6,$a6
-+	mov	$cnt,#-8*8
-+	adcs	$acc7,$acc7,$a7
-+	ldp	$a6,$a7,[$ap,#8*6]
-+	add	$ap,$ap,#8*8
-+	//adc	$carry,xzr,xzr		// moved above
-+	b	.Lsqr8x_mul
-+
-+.align	4
-+.Lsqr8x_break:
-+	ldp	$a0,$a1,[$rp,#8*0]
-+	add	$ap,$rp,#8*8
-+	ldp	$a2,$a3,[$rp,#8*2]
-+	sub	$t0,$ap_end,$ap		// is it last iteration?
-+	ldp	$a4,$a5,[$rp,#8*4]
-+	sub	$t1,$tp,$t0
-+	ldp	$a6,$a7,[$rp,#8*6]
-+	cbz	$t0,.Lsqr8x_outer_loop
-+
-+	stp	$acc0,$acc1,[$tp,#8*0]
-+	ldp	$acc0,$acc1,[$t1,#8*0]
-+	stp	$acc2,$acc3,[$tp,#8*2]
-+	ldp	$acc2,$acc3,[$t1,#8*2]
-+	stp	$acc4,$acc5,[$tp,#8*4]
-+	ldp	$acc4,$acc5,[$t1,#8*4]
-+	stp	$acc6,$acc7,[$tp,#8*6]
-+	mov	$tp,$t1
-+	ldp	$acc6,$acc7,[$t1,#8*6]
-+	b	.Lsqr8x_outer_loop
-+
-+.align	4
-+.Lsqr8x_outer_break:
-+	// Now multiply above result by 2 and add a[n-1]*a[n-1]|...|a[0]*a[0]
-+	ldp	$a1,$a3,[$t0,#8*0]	// recall that $t0 is &a[0]
-+	ldp	$t1,$t2,[sp,#8*1]
-+	ldp	$a5,$a7,[$t0,#8*2]
-+	add	$ap,$t0,#8*4
-+	ldp	$t3,$t0,[sp,#8*3]
-+
-+	stp	$acc0,$acc1,[$tp,#8*0]
-+	mul	$acc0,$a1,$a1
-+	stp	$acc2,$acc3,[$tp,#8*2]
-+	umulh	$a1,$a1,$a1
-+	stp	$acc4,$acc5,[$tp,#8*4]
-+	mul	$a2,$a3,$a3
-+	stp	$acc6,$acc7,[$tp,#8*6]
-+	mov	$tp,sp
-+	umulh	$a3,$a3,$a3
-+	adds	$acc1,$a1,$t1,lsl#1
-+	extr	$t1,$t2,$t1,#63
-+	sub	$cnt,$num,#8*4
-+
-+.Lsqr4x_shift_n_add:
-+	adcs	$acc2,$a2,$t1
-+	extr	$t2,$t3,$t2,#63
-+	sub	$cnt,$cnt,#8*4
-+	adcs	$acc3,$a3,$t2
-+	ldp	$t1,$t2,[$tp,#8*5]
-+	mul	$a4,$a5,$a5
-+	ldp	$a1,$a3,[$ap],#8*2
-+	umulh	$a5,$a5,$a5
-+	mul	$a6,$a7,$a7
-+	umulh	$a7,$a7,$a7
-+	extr	$t3,$t0,$t3,#63
-+	stp	$acc0,$acc1,[$tp,#8*0]
-+	adcs	$acc4,$a4,$t3
-+	extr	$t0,$t1,$t0,#63
-+	stp	$acc2,$acc3,[$tp,#8*2]
-+	adcs	$acc5,$a5,$t0
-+	ldp	$t3,$t0,[$tp,#8*7]
-+	extr	$t1,$t2,$t1,#63
-+	adcs	$acc6,$a6,$t1
-+	extr	$t2,$t3,$t2,#63
-+	adcs	$acc7,$a7,$t2
-+	ldp	$t1,$t2,[$tp,#8*9]
-+	mul	$a0,$a1,$a1
-+	ldp	$a5,$a7,[$ap],#8*2
-+	umulh	$a1,$a1,$a1
-+	mul	$a2,$a3,$a3
-+	umulh	$a3,$a3,$a3
-+	stp	$acc4,$acc5,[$tp,#8*4]
-+	extr	$t3,$t0,$t3,#63
-+	stp	$acc6,$acc7,[$tp,#8*6]
-+	add	$tp,$tp,#8*8
-+	adcs	$acc0,$a0,$t3
-+	extr	$t0,$t1,$t0,#63
-+	adcs	$acc1,$a1,$t0
-+	ldp	$t3,$t0,[$tp,#8*3]
-+	extr	$t1,$t2,$t1,#63
-+	cbnz	$cnt,.Lsqr4x_shift_n_add
-+___
-+my ($np,$np_end)=($ap,$ap_end);
-+$code.=<<___;
-+	 ldp	$np,$n0,[x29,#104]	// pull np and n0
-+
-+	adcs	$acc2,$a2,$t1
-+	extr	$t2,$t3,$t2,#63
-+	adcs	$acc3,$a3,$t2
-+	ldp	$t1,$t2,[$tp,#8*5]
-+	mul	$a4,$a5,$a5
-+	umulh	$a5,$a5,$a5
-+	stp	$acc0,$acc1,[$tp,#8*0]
-+	mul	$a6,$a7,$a7
-+	umulh	$a7,$a7,$a7
-+	stp	$acc2,$acc3,[$tp,#8*2]
-+	extr	$t3,$t0,$t3,#63
-+	adcs	$acc4,$a4,$t3
-+	extr	$t0,$t1,$t0,#63
-+	 ldp	$acc0,$acc1,[sp,#8*0]
-+	adcs	$acc5,$a5,$t0
-+	extr	$t1,$t2,$t1,#63
-+	 ldp	$a0,$a1,[$np,#8*0]
-+	adcs	$acc6,$a6,$t1
-+	extr	$t2,xzr,$t2,#63
-+	 ldp	$a2,$a3,[$np,#8*2]
-+	adc	$acc7,$a7,$t2
-+	 ldp	$a4,$a5,[$np,#8*4]
-+
-+	// Reduce by 512 bits per iteration
-+	mul	$na0,$n0,$acc0		// t[0]*n0
-+	ldp	$a6,$a7,[$np,#8*6]
-+	add	$np_end,$np,$num
-+	ldp	$acc2,$acc3,[sp,#8*2]
-+	stp	$acc4,$acc5,[$tp,#8*4]
-+	ldp	$acc4,$acc5,[sp,#8*4]
-+	stp	$acc6,$acc7,[$tp,#8*6]
-+	ldp	$acc6,$acc7,[sp,#8*6]
-+	add	$np,$np,#8*8
-+	mov	$topmost,xzr		// initial top-most carry
-+	mov	$tp,sp
-+	mov	$cnt,#8
-+
-+.Lsqr8x_reduction:
-+	// (*)	mul	$t0,$a0,$na0	// lo(n[0-7])*lo(t[0]*n0)
-+	mul	$t1,$a1,$na0
-+	sub	$cnt,$cnt,#1
-+	mul	$t2,$a2,$na0
-+	str	$na0,[$tp],#8		// put aside t[0]*n0 for tail processing
-+	mul	$t3,$a3,$na0
-+	// (*)	adds	xzr,$acc0,$t0
-+	subs	xzr,$acc0,#1		// (*)
-+	mul	$t0,$a4,$na0
-+	adcs	$acc0,$acc1,$t1
-+	mul	$t1,$a5,$na0
-+	adcs	$acc1,$acc2,$t2
-+	mul	$t2,$a6,$na0
-+	adcs	$acc2,$acc3,$t3
-+	mul	$t3,$a7,$na0
-+	adcs	$acc3,$acc4,$t0
-+	umulh	$t0,$a0,$na0		// hi(n[0-7])*lo(t[0]*n0)
-+	adcs	$acc4,$acc5,$t1
-+	umulh	$t1,$a1,$na0
-+	adcs	$acc5,$acc6,$t2
-+	umulh	$t2,$a2,$na0
-+	adcs	$acc6,$acc7,$t3
-+	umulh	$t3,$a3,$na0
-+	adc	$acc7,xzr,xzr
-+	adds	$acc0,$acc0,$t0
-+	umulh	$t0,$a4,$na0
-+	adcs	$acc1,$acc1,$t1
-+	umulh	$t1,$a5,$na0
-+	adcs	$acc2,$acc2,$t2
-+	umulh	$t2,$a6,$na0
-+	adcs	$acc3,$acc3,$t3
-+	umulh	$t3,$a7,$na0
-+	mul	$na0,$n0,$acc0		// next t[0]*n0
-+	adcs	$acc4,$acc4,$t0
-+	adcs	$acc5,$acc5,$t1
-+	adcs	$acc6,$acc6,$t2
-+	adc	$acc7,$acc7,$t3
-+	cbnz	$cnt,.Lsqr8x_reduction
-+
-+	ldp	$t0,$t1,[$tp,#8*0]
-+	ldp	$t2,$t3,[$tp,#8*2]
-+	mov	$rp,$tp
-+	sub	$cnt,$np_end,$np	// done yet?
-+	adds	$acc0,$acc0,$t0
-+	adcs	$acc1,$acc1,$t1
-+	ldp	$t0,$t1,[$tp,#8*4]
-+	adcs	$acc2,$acc2,$t2
-+	adcs	$acc3,$acc3,$t3
-+	ldp	$t2,$t3,[$tp,#8*6]
-+	adcs	$acc4,$acc4,$t0
-+	adcs	$acc5,$acc5,$t1
-+	adcs	$acc6,$acc6,$t2
-+	adcs	$acc7,$acc7,$t3
-+	//adc	$carry,xzr,xzr		// moved below
-+	cbz	$cnt,.Lsqr8x8_post_condition
-+
-+	ldr	$n0,[$tp,#-8*8]
-+	ldp	$a0,$a1,[$np,#8*0]
-+	ldp	$a2,$a3,[$np,#8*2]
-+	ldp	$a4,$a5,[$np,#8*4]
-+	mov	$cnt,#-8*8
-+	ldp	$a6,$a7,[$np,#8*6]
-+	add	$np,$np,#8*8
-+
-+.Lsqr8x_tail:
-+	mul	$t0,$a0,$n0
-+	adc	$carry,xzr,xzr		// carry bit, modulo-scheduled
-+	mul	$t1,$a1,$n0
-+	add	$cnt,$cnt,#8
-+	mul	$t2,$a2,$n0
-+	mul	$t3,$a3,$n0
-+	adds	$acc0,$acc0,$t0
-+	mul	$t0,$a4,$n0
-+	adcs	$acc1,$acc1,$t1
-+	mul	$t1,$a5,$n0
-+	adcs	$acc2,$acc2,$t2
-+	mul	$t2,$a6,$n0
-+	adcs	$acc3,$acc3,$t3
-+	mul	$t3,$a7,$n0
-+	adcs	$acc4,$acc4,$t0
-+	umulh	$t0,$a0,$n0
-+	adcs	$acc5,$acc5,$t1
-+	umulh	$t1,$a1,$n0
-+	adcs	$acc6,$acc6,$t2
-+	umulh	$t2,$a2,$n0
-+	adcs	$acc7,$acc7,$t3
-+	umulh	$t3,$a3,$n0
-+	adc	$carry,$carry,xzr
-+	str	$acc0,[$tp],#8
-+	adds	$acc0,$acc1,$t0
-+	umulh	$t0,$a4,$n0
-+	adcs	$acc1,$acc2,$t1
-+	umulh	$t1,$a5,$n0
-+	adcs	$acc2,$acc3,$t2
-+	umulh	$t2,$a6,$n0
-+	adcs	$acc3,$acc4,$t3
-+	umulh	$t3,$a7,$n0
-+	ldr	$n0,[$rp,$cnt]
-+	adcs	$acc4,$acc5,$t0
-+	adcs	$acc5,$acc6,$t1
-+	adcs	$acc6,$acc7,$t2
-+	adcs	$acc7,$carry,$t3
-+	//adc	$carry,xzr,xzr		// moved above
-+	cbnz	$cnt,.Lsqr8x_tail
-+					// note that carry flag is guaranteed
-+					// to be zero at this point
-+	ldp	$a0,$a1,[$tp,#8*0]
-+	sub	$cnt,$np_end,$np	// done yet?
-+	sub	$t2,$np_end,$num	// rewinded np
-+	ldp	$a2,$a3,[$tp,#8*2]
-+	ldp	$a4,$a5,[$tp,#8*4]
-+	ldp	$a6,$a7,[$tp,#8*6]
-+	cbz	$cnt,.Lsqr8x_tail_break
-+
-+	ldr	$n0,[$rp,#-8*8]
-+	adds	$acc0,$acc0,$a0
-+	adcs	$acc1,$acc1,$a1
-+	ldp	$a0,$a1,[$np,#8*0]
-+	adcs	$acc2,$acc2,$a2
-+	adcs	$acc3,$acc3,$a3
-+	ldp	$a2,$a3,[$np,#8*2]
-+	adcs	$acc4,$acc4,$a4
-+	adcs	$acc5,$acc5,$a5
-+	ldp	$a4,$a5,[$np,#8*4]
-+	adcs	$acc6,$acc6,$a6
-+	mov	$cnt,#-8*8
-+	adcs	$acc7,$acc7,$a7
-+	ldp	$a6,$a7,[$np,#8*6]
-+	add	$np,$np,#8*8
-+	//adc	$carry,xzr,xzr		// moved above
-+	b	.Lsqr8x_tail
-+
-+.align	4
-+.Lsqr8x_tail_break:
-+	ldr	$n0,[x29,#112]		// pull n0
-+	add	$cnt,$tp,#8*8		// end of current t[num] window
-+
-+	subs	xzr,$topmost,#1		// "move" top-most carry to carry bit
-+	adcs	$t0,$acc0,$a0
-+	adcs	$t1,$acc1,$a1
-+	ldp	$acc0,$acc1,[$rp,#8*0]
-+	adcs	$acc2,$acc2,$a2
-+	ldp	$a0,$a1,[$t2,#8*0]	// recall that $t2 is &n[0]
-+	adcs	$acc3,$acc3,$a3
-+	ldp	$a2,$a3,[$t2,#8*2]
-+	adcs	$acc4,$acc4,$a4
-+	adcs	$acc5,$acc5,$a5
-+	ldp	$a4,$a5,[$t2,#8*4]
-+	adcs	$acc6,$acc6,$a6
-+	adcs	$acc7,$acc7,$a7
-+	ldp	$a6,$a7,[$t2,#8*6]
-+	add	$np,$t2,#8*8
-+	adc	$topmost,xzr,xzr	// top-most carry
-+	mul	$na0,$n0,$acc0
-+	stp	$t0,$t1,[$tp,#8*0]
-+	stp	$acc2,$acc3,[$tp,#8*2]
-+	ldp	$acc2,$acc3,[$rp,#8*2]
-+	stp	$acc4,$acc5,[$tp,#8*4]
-+	ldp	$acc4,$acc5,[$rp,#8*4]
-+	cmp	$cnt,x29		// did we hit the bottom?
-+	stp	$acc6,$acc7,[$tp,#8*6]
-+	mov	$tp,$rp			// slide the window
-+	ldp	$acc6,$acc7,[$rp,#8*6]
-+	mov	$cnt,#8
-+	b.ne	.Lsqr8x_reduction
-+
-+	// Final step. We see if result is larger than modulus, and
-+	// if it is, subtract the modulus. But comparison implies
-+	// subtraction. So we subtract modulus, see if it borrowed,
-+	// and conditionally copy original value.
-+	ldr	$rp,[x29,#96]		// pull rp
-+	add	$tp,$tp,#8*8
-+	subs	$t0,$acc0,$a0
-+	sbcs	$t1,$acc1,$a1
-+	sub	$cnt,$num,#8*8
-+	mov	$ap_end,$rp		// $rp copy
-+
-+.Lsqr8x_sub:
-+	sbcs	$t2,$acc2,$a2
-+	ldp	$a0,$a1,[$np,#8*0]
-+	sbcs	$t3,$acc3,$a3
-+	stp	$t0,$t1,[$rp,#8*0]
-+	sbcs	$t0,$acc4,$a4
-+	ldp	$a2,$a3,[$np,#8*2]
-+	sbcs	$t1,$acc5,$a5
-+	stp	$t2,$t3,[$rp,#8*2]
-+	sbcs	$t2,$acc6,$a6
-+	ldp	$a4,$a5,[$np,#8*4]
-+	sbcs	$t3,$acc7,$a7
-+	ldp	$a6,$a7,[$np,#8*6]
-+	add	$np,$np,#8*8
-+	ldp	$acc0,$acc1,[$tp,#8*0]
-+	sub	$cnt,$cnt,#8*8
-+	ldp	$acc2,$acc3,[$tp,#8*2]
-+	ldp	$acc4,$acc5,[$tp,#8*4]
-+	ldp	$acc6,$acc7,[$tp,#8*6]
-+	add	$tp,$tp,#8*8
-+	stp	$t0,$t1,[$rp,#8*4]
-+	sbcs	$t0,$acc0,$a0
-+	stp	$t2,$t3,[$rp,#8*6]
-+	add	$rp,$rp,#8*8
-+	sbcs	$t1,$acc1,$a1
-+	cbnz	$cnt,.Lsqr8x_sub
-+
-+	sbcs	$t2,$acc2,$a2
-+	 mov	$tp,sp
-+	 add	$ap,sp,$num
-+	 ldp	$a0,$a1,[$ap_end,#8*0]
-+	sbcs	$t3,$acc3,$a3
-+	stp	$t0,$t1,[$rp,#8*0]
-+	sbcs	$t0,$acc4,$a4
-+	 ldp	$a2,$a3,[$ap_end,#8*2]
-+	sbcs	$t1,$acc5,$a5
-+	stp	$t2,$t3,[$rp,#8*2]
-+	sbcs	$t2,$acc6,$a6
-+	 ldp	$acc0,$acc1,[$ap,#8*0]
-+	sbcs	$t3,$acc7,$a7
-+	 ldp	$acc2,$acc3,[$ap,#8*2]
-+	sbcs	xzr,$topmost,xzr	// did it borrow?
-+	ldr	x30,[x29,#8]		// pull return address
-+	stp	$t0,$t1,[$rp,#8*4]
-+	stp	$t2,$t3,[$rp,#8*6]
-+
-+	sub	$cnt,$num,#8*4
-+.Lsqr4x_cond_copy:
-+	sub	$cnt,$cnt,#8*4
-+	csel	$t0,$acc0,$a0,lo
-+	 stp	xzr,xzr,[$tp,#8*0]
-+	csel	$t1,$acc1,$a1,lo
-+	ldp	$a0,$a1,[$ap_end,#8*4]
-+	ldp	$acc0,$acc1,[$ap,#8*4]
-+	csel	$t2,$acc2,$a2,lo
-+	 stp	xzr,xzr,[$tp,#8*2]
-+	 add	$tp,$tp,#8*4
-+	csel	$t3,$acc3,$a3,lo
-+	ldp	$a2,$a3,[$ap_end,#8*6]
-+	ldp	$acc2,$acc3,[$ap,#8*6]
-+	add	$ap,$ap,#8*4
-+	stp	$t0,$t1,[$ap_end,#8*0]
-+	stp	$t2,$t3,[$ap_end,#8*2]
-+	add	$ap_end,$ap_end,#8*4
-+	 stp	xzr,xzr,[$ap,#8*0]
-+	 stp	xzr,xzr,[$ap,#8*2]
-+	cbnz	$cnt,.Lsqr4x_cond_copy
-+
-+	csel	$t0,$acc0,$a0,lo
-+	 stp	xzr,xzr,[$tp,#8*0]
-+	csel	$t1,$acc1,$a1,lo
-+	 stp	xzr,xzr,[$tp,#8*2]
-+	csel	$t2,$acc2,$a2,lo
-+	csel	$t3,$acc3,$a3,lo
-+	stp	$t0,$t1,[$ap_end,#8*0]
-+	stp	$t2,$t3,[$ap_end,#8*2]
-+
-+	b	.Lsqr8x_done
-+
-+.align	4
-+.Lsqr8x8_post_condition:
-+	adc	$carry,xzr,xzr
-+	ldr	x30,[x29,#8]		// pull return address
-+	// $acc0-7,$carry hold result, $a0-7 hold modulus
-+	subs	$a0,$acc0,$a0
-+	ldr	$ap,[x29,#96]		// pull rp
-+	sbcs	$a1,$acc1,$a1
-+	 stp	xzr,xzr,[sp,#8*0]
-+	sbcs	$a2,$acc2,$a2
-+	 stp	xzr,xzr,[sp,#8*2]
-+	sbcs	$a3,$acc3,$a3
-+	 stp	xzr,xzr,[sp,#8*4]
-+	sbcs	$a4,$acc4,$a4
-+	 stp	xzr,xzr,[sp,#8*6]
-+	sbcs	$a5,$acc5,$a5
-+	 stp	xzr,xzr,[sp,#8*8]
-+	sbcs	$a6,$acc6,$a6
-+	 stp	xzr,xzr,[sp,#8*10]
-+	sbcs	$a7,$acc7,$a7
-+	 stp	xzr,xzr,[sp,#8*12]
-+	sbcs	$carry,$carry,xzr	// did it borrow?
-+	 stp	xzr,xzr,[sp,#8*14]
-+
-+	// $a0-7 hold result-modulus
-+	csel	$a0,$acc0,$a0,lo
-+	csel	$a1,$acc1,$a1,lo
-+	csel	$a2,$acc2,$a2,lo
-+	csel	$a3,$acc3,$a3,lo
-+	stp	$a0,$a1,[$ap,#8*0]
-+	csel	$a4,$acc4,$a4,lo
-+	csel	$a5,$acc5,$a5,lo
-+	stp	$a2,$a3,[$ap,#8*2]
-+	csel	$a6,$acc6,$a6,lo
-+	csel	$a7,$acc7,$a7,lo
-+	stp	$a4,$a5,[$ap,#8*4]
-+	stp	$a6,$a7,[$ap,#8*6]
-+
-+.Lsqr8x_done:
-+	ldp	x19,x20,[x29,#16]
-+	mov	sp,x29
-+	ldp	x21,x22,[x29,#32]
-+	mov	x0,#1
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	ldp	x27,x28,[x29,#80]
-+	ldr	x29,[sp],#128
-+	ret
-+.size	__bn_sqr8x_mont,.-__bn_sqr8x_mont
-+___
-+}
-+
-+{
-+########################################################################
-+# Even though this might look as ARMv8 adaptation of mulx4x_mont from
-+# x86_64-mont5 module, it's different in sense that it performs
-+# reduction 256 bits at a time.
-+
-+my ($a0,$a1,$a2,$a3,
-+    $t0,$t1,$t2,$t3,
-+    $m0,$m1,$m2,$m3,
-+    $acc0,$acc1,$acc2,$acc3,$acc4,
-+    $bi,$mi,$tp,$ap_end,$cnt) = map("x$_",(6..17,19..28));
-+my  $bp_end=$rp;
-+my  ($carry,$topmost) = ($rp,"x30");
-+
-+$code.=<<___;
-+.type	__bn_mul4x_mont,%function
-+.align	5
-+__bn_mul4x_mont:
-+	stp	x29,x30,[sp,#-128]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	stp	x23,x24,[sp,#48]
-+	stp	x25,x26,[sp,#64]
-+	stp	x27,x28,[sp,#80]
-+
-+	sub	$tp,sp,$num,lsl#3
-+	lsl	$num,$num,#3
-+	ldr	$n0,[$n0]		// *n0
-+	sub	sp,$tp,#8*4		// alloca
-+
-+	add	$t0,$bp,$num
-+	add	$ap_end,$ap,$num
-+	stp	$rp,$t0,[x29,#96]	// offload rp and &b[num]
-+
-+	ldr	$bi,[$bp,#8*0]		// b[0]
-+	ldp	$a0,$a1,[$ap,#8*0]	// a[0..3]
-+	ldp	$a2,$a3,[$ap,#8*2]
-+	add	$ap,$ap,#8*4
-+	mov	$acc0,xzr
-+	mov	$acc1,xzr
-+	mov	$acc2,xzr
-+	mov	$acc3,xzr
-+	ldp	$m0,$m1,[$np,#8*0]	// n[0..3]
-+	ldp	$m2,$m3,[$np,#8*2]
-+	adds	$np,$np,#8*4		// clear carry bit
-+	mov	$carry,xzr
-+	mov	$cnt,#0
-+	mov	$tp,sp
-+
-+.Loop_mul4x_1st_reduction:
-+	mul	$t0,$a0,$bi		// lo(a[0..3]*b[0])
-+	adc	$carry,$carry,xzr	// modulo-scheduled
-+	mul	$t1,$a1,$bi
-+	add	$cnt,$cnt,#8
-+	mul	$t2,$a2,$bi
-+	and	$cnt,$cnt,#31
-+	mul	$t3,$a3,$bi
-+	adds	$acc0,$acc0,$t0
-+	umulh	$t0,$a0,$bi		// hi(a[0..3]*b[0])
-+	adcs	$acc1,$acc1,$t1
-+	mul	$mi,$acc0,$n0		// t[0]*n0
-+	adcs	$acc2,$acc2,$t2
-+	umulh	$t1,$a1,$bi
-+	adcs	$acc3,$acc3,$t3
-+	umulh	$t2,$a2,$bi
-+	adc	$acc4,xzr,xzr
-+	umulh	$t3,$a3,$bi
-+	ldr	$bi,[$bp,$cnt]		// next b[i] (or b[0])
-+	adds	$acc1,$acc1,$t0
-+	// (*)	mul	$t0,$m0,$mi	// lo(n[0..3]*t[0]*n0)
-+	str	$mi,[$tp],#8		// put aside t[0]*n0 for tail processing
-+	adcs	$acc2,$acc2,$t1
-+	mul	$t1,$m1,$mi
-+	adcs	$acc3,$acc3,$t2
-+	mul	$t2,$m2,$mi
-+	adc	$acc4,$acc4,$t3		// can't overflow
-+	mul	$t3,$m3,$mi
-+	// (*)	adds	xzr,$acc0,$t0
-+	subs	xzr,$acc0,#1		// (*)
-+	umulh	$t0,$m0,$mi		// hi(n[0..3]*t[0]*n0)
-+	adcs	$acc0,$acc1,$t1
-+	umulh	$t1,$m1,$mi
-+	adcs	$acc1,$acc2,$t2
-+	umulh	$t2,$m2,$mi
-+	adcs	$acc2,$acc3,$t3
-+	umulh	$t3,$m3,$mi
-+	adcs	$acc3,$acc4,$carry
-+	adc	$carry,xzr,xzr
-+	adds	$acc0,$acc0,$t0
-+	sub	$t0,$ap_end,$ap
-+	adcs	$acc1,$acc1,$t1
-+	adcs	$acc2,$acc2,$t2
-+	adcs	$acc3,$acc3,$t3
-+	//adc	$carry,$carry,xzr
-+	cbnz	$cnt,.Loop_mul4x_1st_reduction
-+
-+	cbz	$t0,.Lmul4x4_post_condition
-+
-+	ldp	$a0,$a1,[$ap,#8*0]	// a[4..7]
-+	ldp	$a2,$a3,[$ap,#8*2]
-+	add	$ap,$ap,#8*4
-+	ldr	$mi,[sp]		// a[0]*n0
-+	ldp	$m0,$m1,[$np,#8*0]	// n[4..7]
-+	ldp	$m2,$m3,[$np,#8*2]
-+	add	$np,$np,#8*4
-+
-+.Loop_mul4x_1st_tail:
-+	mul	$t0,$a0,$bi		// lo(a[4..7]*b[i])
-+	adc	$carry,$carry,xzr	// modulo-scheduled
-+	mul	$t1,$a1,$bi
-+	add	$cnt,$cnt,#8
-+	mul	$t2,$a2,$bi
-+	and	$cnt,$cnt,#31
-+	mul	$t3,$a3,$bi
-+	adds	$acc0,$acc0,$t0
-+	umulh	$t0,$a0,$bi		// hi(a[4..7]*b[i])
-+	adcs	$acc1,$acc1,$t1
-+	umulh	$t1,$a1,$bi
-+	adcs	$acc2,$acc2,$t2
-+	umulh	$t2,$a2,$bi
-+	adcs	$acc3,$acc3,$t3
-+	umulh	$t3,$a3,$bi
-+	adc	$acc4,xzr,xzr
-+	ldr	$bi,[$bp,$cnt]		// next b[i] (or b[0])
-+	adds	$acc1,$acc1,$t0
-+	mul	$t0,$m0,$mi		// lo(n[4..7]*a[0]*n0)
-+	adcs	$acc2,$acc2,$t1
-+	mul	$t1,$m1,$mi
-+	adcs	$acc3,$acc3,$t2
-+	mul	$t2,$m2,$mi
-+	adc	$acc4,$acc4,$t3		// can't overflow
-+	mul	$t3,$m3,$mi
-+	adds	$acc0,$acc0,$t0
-+	umulh	$t0,$m0,$mi		// hi(n[4..7]*a[0]*n0)
-+	adcs	$acc1,$acc1,$t1
-+	umulh	$t1,$m1,$mi
-+	adcs	$acc2,$acc2,$t2
-+	umulh	$t2,$m2,$mi
-+	adcs	$acc3,$acc3,$t3
-+	adcs	$acc4,$acc4,$carry
-+	umulh	$t3,$m3,$mi
-+	adc	$carry,xzr,xzr
-+	ldr	$mi,[sp,$cnt]		// next t[0]*n0
-+	str	$acc0,[$tp],#8		// result!!!
-+	adds	$acc0,$acc1,$t0
-+	sub	$t0,$ap_end,$ap		// done yet?
-+	adcs	$acc1,$acc2,$t1
-+	adcs	$acc2,$acc3,$t2
-+	adcs	$acc3,$acc4,$t3
-+	//adc	$carry,$carry,xzr
-+	cbnz	$cnt,.Loop_mul4x_1st_tail
-+
-+	sub	$t1,$ap_end,$num	// rewinded $ap
-+	cbz	$t0,.Lmul4x_proceed
-+
-+	ldp	$a0,$a1,[$ap,#8*0]
-+	ldp	$a2,$a3,[$ap,#8*2]
-+	add	$ap,$ap,#8*4
-+	ldp	$m0,$m1,[$np,#8*0]
-+	ldp	$m2,$m3,[$np,#8*2]
-+	add	$np,$np,#8*4
-+	b	.Loop_mul4x_1st_tail
-+
-+.align	5
-+.Lmul4x_proceed:
-+	ldr	$bi,[$bp,#8*4]!		// *++b
-+	adc	$topmost,$carry,xzr
-+	ldp	$a0,$a1,[$t1,#8*0]	// a[0..3]
-+	sub	$np,$np,$num		// rewind np
-+	ldp	$a2,$a3,[$t1,#8*2]
-+	add	$ap,$t1,#8*4
-+
-+	stp	$acc0,$acc1,[$tp,#8*0]	// result!!!
-+	ldp	$acc0,$acc1,[sp,#8*4]	// t[0..3]
-+	stp	$acc2,$acc3,[$tp,#8*2]	// result!!!
-+	ldp	$acc2,$acc3,[sp,#8*6]
-+
-+	ldp	$m0,$m1,[$np,#8*0]	// n[0..3]
-+	mov	$tp,sp
-+	ldp	$m2,$m3,[$np,#8*2]
-+	adds	$np,$np,#8*4		// clear carry bit
-+	mov	$carry,xzr
-+
-+.align	4
-+.Loop_mul4x_reduction:
-+	mul	$t0,$a0,$bi		// lo(a[0..3]*b[4])
-+	adc	$carry,$carry,xzr	// modulo-scheduled
-+	mul	$t1,$a1,$bi
-+	add	$cnt,$cnt,#8
-+	mul	$t2,$a2,$bi
-+	and	$cnt,$cnt,#31
-+	mul	$t3,$a3,$bi
-+	adds	$acc0,$acc0,$t0
-+	umulh	$t0,$a0,$bi		// hi(a[0..3]*b[4])
-+	adcs	$acc1,$acc1,$t1
-+	mul	$mi,$acc0,$n0		// t[0]*n0
-+	adcs	$acc2,$acc2,$t2
-+	umulh	$t1,$a1,$bi
-+	adcs	$acc3,$acc3,$t3
-+	umulh	$t2,$a2,$bi
-+	adc	$acc4,xzr,xzr
-+	umulh	$t3,$a3,$bi
-+	ldr	$bi,[$bp,$cnt]		// next b[i]
-+	adds	$acc1,$acc1,$t0
-+	// (*)	mul	$t0,$m0,$mi
-+	str	$mi,[$tp],#8		// put aside t[0]*n0 for tail processing
-+	adcs	$acc2,$acc2,$t1
-+	mul	$t1,$m1,$mi		// lo(n[0..3]*t[0]*n0
-+	adcs	$acc3,$acc3,$t2
-+	mul	$t2,$m2,$mi
-+	adc	$acc4,$acc4,$t3		// can't overflow
-+	mul	$t3,$m3,$mi
-+	// (*)	adds	xzr,$acc0,$t0
-+	subs	xzr,$acc0,#1		// (*)
-+	umulh	$t0,$m0,$mi		// hi(n[0..3]*t[0]*n0
-+	adcs	$acc0,$acc1,$t1
-+	umulh	$t1,$m1,$mi
-+	adcs	$acc1,$acc2,$t2
-+	umulh	$t2,$m2,$mi
-+	adcs	$acc2,$acc3,$t3
-+	umulh	$t3,$m3,$mi
-+	adcs	$acc3,$acc4,$carry
-+	adc	$carry,xzr,xzr
-+	adds	$acc0,$acc0,$t0
-+	adcs	$acc1,$acc1,$t1
-+	adcs	$acc2,$acc2,$t2
-+	adcs	$acc3,$acc3,$t3
-+	//adc	$carry,$carry,xzr
-+	cbnz	$cnt,.Loop_mul4x_reduction
-+
-+	adc	$carry,$carry,xzr
-+	ldp	$t0,$t1,[$tp,#8*4]	// t[4..7]
-+	ldp	$t2,$t3,[$tp,#8*6]
-+	ldp	$a0,$a1,[$ap,#8*0]	// a[4..7]
-+	ldp	$a2,$a3,[$ap,#8*2]
-+	add	$ap,$ap,#8*4
-+	adds	$acc0,$acc0,$t0
-+	adcs	$acc1,$acc1,$t1
-+	adcs	$acc2,$acc2,$t2
-+	adcs	$acc3,$acc3,$t3
-+	//adc	$carry,$carry,xzr
-+
-+	ldr	$mi,[sp]		// t[0]*n0
-+	ldp	$m0,$m1,[$np,#8*0]	// n[4..7]
-+	ldp	$m2,$m3,[$np,#8*2]
-+	add	$np,$np,#8*4
-+
-+.align	4
-+.Loop_mul4x_tail:
-+	mul	$t0,$a0,$bi		// lo(a[4..7]*b[4])
-+	adc	$carry,$carry,xzr	// modulo-scheduled
-+	mul	$t1,$a1,$bi
-+	add	$cnt,$cnt,#8
-+	mul	$t2,$a2,$bi
-+	and	$cnt,$cnt,#31
-+	mul	$t3,$a3,$bi
-+	adds	$acc0,$acc0,$t0
-+	umulh	$t0,$a0,$bi		// hi(a[4..7]*b[4])
-+	adcs	$acc1,$acc1,$t1
-+	umulh	$t1,$a1,$bi
-+	adcs	$acc2,$acc2,$t2
-+	umulh	$t2,$a2,$bi
-+	adcs	$acc3,$acc3,$t3
-+	umulh	$t3,$a3,$bi
-+	adc	$acc4,xzr,xzr
-+	ldr	$bi,[$bp,$cnt]		// next b[i]
-+	adds	$acc1,$acc1,$t0
-+	mul	$t0,$m0,$mi		// lo(n[4..7]*t[0]*n0)
-+	adcs	$acc2,$acc2,$t1
-+	mul	$t1,$m1,$mi
-+	adcs	$acc3,$acc3,$t2
-+	mul	$t2,$m2,$mi
-+	adc	$acc4,$acc4,$t3		// can't overflow
-+	mul	$t3,$m3,$mi
-+	adds	$acc0,$acc0,$t0
-+	umulh	$t0,$m0,$mi		// hi(n[4..7]*t[0]*n0)
-+	adcs	$acc1,$acc1,$t1
-+	umulh	$t1,$m1,$mi
-+	adcs	$acc2,$acc2,$t2
-+	umulh	$t2,$m2,$mi
-+	adcs	$acc3,$acc3,$t3
-+	umulh	$t3,$m3,$mi
-+	adcs	$acc4,$acc4,$carry
-+	ldr	$mi,[sp,$cnt]		// next a[0]*n0
-+	adc	$carry,xzr,xzr
-+	str	$acc0,[$tp],#8		// result!!!
-+	adds	$acc0,$acc1,$t0
-+	sub	$t0,$ap_end,$ap		// done yet?
-+	adcs	$acc1,$acc2,$t1
-+	adcs	$acc2,$acc3,$t2
-+	adcs	$acc3,$acc4,$t3
-+	//adc	$carry,$carry,xzr
-+	cbnz	$cnt,.Loop_mul4x_tail
-+
-+	sub	$t1,$np,$num		// rewinded np?
-+	adc	$carry,$carry,xzr
-+	cbz	$t0,.Loop_mul4x_break
-+
-+	ldp	$t0,$t1,[$tp,#8*4]
-+	ldp	$t2,$t3,[$tp,#8*6]
-+	ldp	$a0,$a1,[$ap,#8*0]
-+	ldp	$a2,$a3,[$ap,#8*2]
-+	add	$ap,$ap,#8*4
-+	adds	$acc0,$acc0,$t0
-+	adcs	$acc1,$acc1,$t1
-+	adcs	$acc2,$acc2,$t2
-+	adcs	$acc3,$acc3,$t3
-+	//adc	$carry,$carry,xzr
-+	ldp	$m0,$m1,[$np,#8*0]
-+	ldp	$m2,$m3,[$np,#8*2]
-+	add	$np,$np,#8*4
-+	b	.Loop_mul4x_tail
-+
-+.align	4
-+.Loop_mul4x_break:
-+	ldp	$t2,$t3,[x29,#96]	// pull rp and &b[num]
-+	adds	$acc0,$acc0,$topmost
-+	add	$bp,$bp,#8*4		// bp++
-+	adcs	$acc1,$acc1,xzr
-+	sub	$ap,$ap,$num		// rewind ap
-+	adcs	$acc2,$acc2,xzr
-+	stp	$acc0,$acc1,[$tp,#8*0]	// result!!!
-+	adcs	$acc3,$acc3,xzr
-+	ldp	$acc0,$acc1,[sp,#8*4]	// t[0..3]
-+	adc	$topmost,$carry,xzr
-+	stp	$acc2,$acc3,[$tp,#8*2]	// result!!!
-+	cmp	$bp,$t3			// done yet?
-+	ldp	$acc2,$acc3,[sp,#8*6]
-+	ldp	$m0,$m1,[$t1,#8*0]	// n[0..3]
-+	ldp	$m2,$m3,[$t1,#8*2]
-+	add	$np,$t1,#8*4
-+	b.eq	.Lmul4x_post
-+
-+	ldr	$bi,[$bp]
-+	ldp	$a0,$a1,[$ap,#8*0]	// a[0..3]
-+	ldp	$a2,$a3,[$ap,#8*2]
-+	adds	$ap,$ap,#8*4		// clear carry bit
-+	mov	$carry,xzr
-+	mov	$tp,sp
-+	b	.Loop_mul4x_reduction
-+
-+.align	4
-+.Lmul4x_post:
-+	// Final step. We see if result is larger than modulus, and
-+	// if it is, subtract the modulus. But comparison implies
-+	// subtraction. So we subtract modulus, see if it borrowed,
-+	// and conditionally copy original value.
-+	mov	$rp,$t2
-+	mov	$ap_end,$t2		// $rp copy
-+	subs	$t0,$acc0,$m0
-+	add	$tp,sp,#8*8
-+	sbcs	$t1,$acc1,$m1
-+	sub	$cnt,$num,#8*4
-+
-+.Lmul4x_sub:
-+	sbcs	$t2,$acc2,$m2
-+	ldp	$m0,$m1,[$np,#8*0]
-+	sub	$cnt,$cnt,#8*4
-+	ldp	$acc0,$acc1,[$tp,#8*0]
-+	sbcs	$t3,$acc3,$m3
-+	ldp	$m2,$m3,[$np,#8*2]
-+	add	$np,$np,#8*4
-+	ldp	$acc2,$acc3,[$tp,#8*2]
-+	add	$tp,$tp,#8*4
-+	stp	$t0,$t1,[$rp,#8*0]
-+	sbcs	$t0,$acc0,$m0
-+	stp	$t2,$t3,[$rp,#8*2]
-+	add	$rp,$rp,#8*4
-+	sbcs	$t1,$acc1,$m1
-+	cbnz	$cnt,.Lmul4x_sub
-+
-+	sbcs	$t2,$acc2,$m2
-+	 mov	$tp,sp
-+	 add	$ap,sp,#8*4
-+	 ldp	$a0,$a1,[$ap_end,#8*0]
-+	sbcs	$t3,$acc3,$m3
-+	stp	$t0,$t1,[$rp,#8*0]
-+	 ldp	$a2,$a3,[$ap_end,#8*2]
-+	stp	$t2,$t3,[$rp,#8*2]
-+	 ldp	$acc0,$acc1,[$ap,#8*0]
-+	 ldp	$acc2,$acc3,[$ap,#8*2]
-+	sbcs	xzr,$topmost,xzr	// did it borrow?
-+	ldr	x30,[x29,#8]		// pull return address
-+
-+	sub	$cnt,$num,#8*4
-+.Lmul4x_cond_copy:
-+	sub	$cnt,$cnt,#8*4
-+	csel	$t0,$acc0,$a0,lo
-+	 stp	xzr,xzr,[$tp,#8*0]
-+	csel	$t1,$acc1,$a1,lo
-+	ldp	$a0,$a1,[$ap_end,#8*4]
-+	ldp	$acc0,$acc1,[$ap,#8*4]
-+	csel	$t2,$acc2,$a2,lo
-+	 stp	xzr,xzr,[$tp,#8*2]
-+	 add	$tp,$tp,#8*4
-+	csel	$t3,$acc3,$a3,lo
-+	ldp	$a2,$a3,[$ap_end,#8*6]
-+	ldp	$acc2,$acc3,[$ap,#8*6]
-+	add	$ap,$ap,#8*4
-+	stp	$t0,$t1,[$ap_end,#8*0]
-+	stp	$t2,$t3,[$ap_end,#8*2]
-+	add	$ap_end,$ap_end,#8*4
-+	cbnz	$cnt,.Lmul4x_cond_copy
-+
-+	csel	$t0,$acc0,$a0,lo
-+	 stp	xzr,xzr,[$tp,#8*0]
-+	csel	$t1,$acc1,$a1,lo
-+	 stp	xzr,xzr,[$tp,#8*2]
-+	csel	$t2,$acc2,$a2,lo
-+	 stp	xzr,xzr,[$tp,#8*3]
-+	csel	$t3,$acc3,$a3,lo
-+	 stp	xzr,xzr,[$tp,#8*4]
-+	stp	$t0,$t1,[$ap_end,#8*0]
-+	stp	$t2,$t3,[$ap_end,#8*2]
-+
-+	b	.Lmul4x_done
-+
-+.align	4
-+.Lmul4x4_post_condition:
-+	adc	$carry,$carry,xzr
-+	ldr	$ap,[x29,#96]		// pull rp
-+	// $acc0-3,$carry hold result, $m0-7 hold modulus
-+	subs	$a0,$acc0,$m0
-+	ldr	x30,[x29,#8]		// pull return address
-+	sbcs	$a1,$acc1,$m1
-+	 stp	xzr,xzr,[sp,#8*0]
-+	sbcs	$a2,$acc2,$m2
-+	 stp	xzr,xzr,[sp,#8*2]
-+	sbcs	$a3,$acc3,$m3
-+	 stp	xzr,xzr,[sp,#8*4]
-+	sbcs	xzr,$carry,xzr		// did it borrow?
-+	 stp	xzr,xzr,[sp,#8*6]
-+
-+	// $a0-3 hold result-modulus
-+	csel	$a0,$acc0,$a0,lo
-+	csel	$a1,$acc1,$a1,lo
-+	csel	$a2,$acc2,$a2,lo
-+	csel	$a3,$acc3,$a3,lo
-+	stp	$a0,$a1,[$ap,#8*0]
-+	stp	$a2,$a3,[$ap,#8*2]
-+
-+.Lmul4x_done:
-+	ldp	x19,x20,[x29,#16]
-+	mov	sp,x29
-+	ldp	x21,x22,[x29,#32]
-+	mov	x0,#1
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	ldp	x27,x28,[x29,#80]
-+	ldr	x29,[sp],#128
-+	ret
-+.size	__bn_mul4x_mont,.-__bn_mul4x_mont
-+___
-+}
-+$code.=<<___;
-+.asciz	"Montgomery Multiplication for ARMv8, CRYPTOGAMS by "
-+.align	4
-+___
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/bn-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/bn-586.pl
-new file mode 100644
-index 0000000..1ca1bbf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/bn-586.pl
-@@ -0,0 +1,785 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],$0);
-+
-+$sse2=0;
-+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-+
-+&external_label("OPENSSL_ia32cap_P") if ($sse2);
-+
-+&bn_mul_add_words("bn_mul_add_words");
-+&bn_mul_words("bn_mul_words");
-+&bn_sqr_words("bn_sqr_words");
-+&bn_div_words("bn_div_words");
-+&bn_add_words("bn_add_words");
-+&bn_sub_words("bn_sub_words");
-+&bn_sub_part_words("bn_sub_part_words");
-+
-+&asm_finish();
-+
-+close STDOUT;
-+
-+sub bn_mul_add_words
-+	{
-+	local($name)=@_;
-+
-+	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
-+
-+	$r="eax";
-+	$a="edx";
-+	$c="ecx";
-+
-+	if ($sse2) {
-+		&picmeup("eax","OPENSSL_ia32cap_P");
-+		&bt(&DWP(0,"eax"),26);
-+		&jnc(&label("maw_non_sse2"));
-+
-+		&mov($r,&wparam(0));
-+		&mov($a,&wparam(1));
-+		&mov($c,&wparam(2));
-+		&movd("mm0",&wparam(3));	# mm0 = w
-+		&pxor("mm1","mm1");		# mm1 = carry_in
-+		&jmp(&label("maw_sse2_entry"));
-+		
-+	&set_label("maw_sse2_unrolled",16);
-+		&movd("mm3",&DWP(0,$r,"",0));	# mm3 = r[0]
-+		&paddq("mm1","mm3");		# mm1 = carry_in + r[0]
-+		&movd("mm2",&DWP(0,$a,"",0));	# mm2 = a[0]
-+		&pmuludq("mm2","mm0");		# mm2 = w*a[0]
-+		&movd("mm4",&DWP(4,$a,"",0));	# mm4 = a[1]
-+		&pmuludq("mm4","mm0");		# mm4 = w*a[1]
-+		&movd("mm6",&DWP(8,$a,"",0));	# mm6 = a[2]
-+		&pmuludq("mm6","mm0");		# mm6 = w*a[2]
-+		&movd("mm7",&DWP(12,$a,"",0));	# mm7 = a[3]
-+		&pmuludq("mm7","mm0");		# mm7 = w*a[3]
-+		&paddq("mm1","mm2");		# mm1 = carry_in + r[0] + w*a[0]
-+		&movd("mm3",&DWP(4,$r,"",0));	# mm3 = r[1]
-+		&paddq("mm3","mm4");		# mm3 = r[1] + w*a[1]
-+		&movd("mm5",&DWP(8,$r,"",0));	# mm5 = r[2]
-+		&paddq("mm5","mm6");		# mm5 = r[2] + w*a[2]
-+		&movd("mm4",&DWP(12,$r,"",0));	# mm4 = r[3]
-+		&paddq("mm7","mm4");		# mm7 = r[3] + w*a[3]
-+		&movd(&DWP(0,$r,"",0),"mm1");
-+		&movd("mm2",&DWP(16,$a,"",0));	# mm2 = a[4]
-+		&pmuludq("mm2","mm0");		# mm2 = w*a[4]
-+		&psrlq("mm1",32);		# mm1 = carry0
-+		&movd("mm4",&DWP(20,$a,"",0));	# mm4 = a[5]
-+		&pmuludq("mm4","mm0");		# mm4 = w*a[5]
-+		&paddq("mm1","mm3");		# mm1 = carry0 + r[1] + w*a[1]
-+		&movd("mm6",&DWP(24,$a,"",0));	# mm6 = a[6]
-+		&pmuludq("mm6","mm0");		# mm6 = w*a[6]
-+		&movd(&DWP(4,$r,"",0),"mm1");
-+		&psrlq("mm1",32);		# mm1 = carry1
-+		&movd("mm3",&DWP(28,$a,"",0));	# mm3 = a[7]
-+		&add($a,32);
-+		&pmuludq("mm3","mm0");		# mm3 = w*a[7]
-+		&paddq("mm1","mm5");		# mm1 = carry1 + r[2] + w*a[2]
-+		&movd("mm5",&DWP(16,$r,"",0));	# mm5 = r[4]
-+		&paddq("mm2","mm5");		# mm2 = r[4] + w*a[4]
-+		&movd(&DWP(8,$r,"",0),"mm1");
-+		&psrlq("mm1",32);		# mm1 = carry2
-+		&paddq("mm1","mm7");		# mm1 = carry2 + r[3] + w*a[3]
-+		&movd("mm5",&DWP(20,$r,"",0));	# mm5 = r[5]
-+		&paddq("mm4","mm5");		# mm4 = r[5] + w*a[5]
-+		&movd(&DWP(12,$r,"",0),"mm1");
-+		&psrlq("mm1",32);		# mm1 = carry3
-+		&paddq("mm1","mm2");		# mm1 = carry3 + r[4] + w*a[4]
-+		&movd("mm5",&DWP(24,$r,"",0));	# mm5 = r[6]
-+		&paddq("mm6","mm5");		# mm6 = r[6] + w*a[6]
-+		&movd(&DWP(16,$r,"",0),"mm1");
-+		&psrlq("mm1",32);		# mm1 = carry4
-+		&paddq("mm1","mm4");		# mm1 = carry4 + r[5] + w*a[5]
-+		&movd("mm5",&DWP(28,$r,"",0));	# mm5 = r[7]
-+		&paddq("mm3","mm5");		# mm3 = r[7] + w*a[7]
-+		&movd(&DWP(20,$r,"",0),"mm1");
-+		&psrlq("mm1",32);		# mm1 = carry5
-+		&paddq("mm1","mm6");		# mm1 = carry5 + r[6] + w*a[6]
-+		&movd(&DWP(24,$r,"",0),"mm1");
-+		&psrlq("mm1",32);		# mm1 = carry6
-+		&paddq("mm1","mm3");		# mm1 = carry6 + r[7] + w*a[7]
-+		&movd(&DWP(28,$r,"",0),"mm1");
-+		&lea($r,&DWP(32,$r));
-+		&psrlq("mm1",32);		# mm1 = carry_out
-+
-+		&sub($c,8);
-+		&jz(&label("maw_sse2_exit"));
-+	&set_label("maw_sse2_entry");
-+		&test($c,0xfffffff8);
-+		&jnz(&label("maw_sse2_unrolled"));
-+
-+	&set_label("maw_sse2_loop",4);
-+		&movd("mm2",&DWP(0,$a));	# mm2 = a[i]
-+		&movd("mm3",&DWP(0,$r));	# mm3 = r[i]
-+		&pmuludq("mm2","mm0");		# a[i] *= w
-+		&lea($a,&DWP(4,$a));
-+		&paddq("mm1","mm3");		# carry += r[i]
-+		&paddq("mm1","mm2");		# carry += a[i]*w
-+		&movd(&DWP(0,$r),"mm1");	# r[i] = carry_low
-+		&sub($c,1);
-+		&psrlq("mm1",32);		# carry = carry_high
-+		&lea($r,&DWP(4,$r));
-+		&jnz(&label("maw_sse2_loop"));
-+	&set_label("maw_sse2_exit");
-+		&movd("eax","mm1");		# c = carry_out
-+		&emms();
-+		&ret();
-+
-+	&set_label("maw_non_sse2",16);
-+	}
-+
-+	# function_begin prologue
-+	&push("ebp");
-+	&push("ebx");
-+	&push("esi");
-+	&push("edi");
-+
-+	&comment("");
-+	$Low="eax";
-+	$High="edx";
-+	$a="ebx";
-+	$w="ebp";
-+	$r="edi";
-+	$c="esi";
-+
-+	&xor($c,$c);		# clear carry
-+	&mov($r,&wparam(0));	#
-+
-+	&mov("ecx",&wparam(2));	#
-+	&mov($a,&wparam(1));	#
-+
-+	&and("ecx",0xfffffff8);	# num / 8
-+	&mov($w,&wparam(3));	#
-+
-+	&push("ecx");		# Up the stack for a tmp variable
-+
-+	&jz(&label("maw_finish"));
-+
-+	&set_label("maw_loop",16);
-+
-+	for ($i=0; $i<32; $i+=4)
-+		{
-+		&comment("Round $i");
-+
-+		 &mov("eax",&DWP($i,$a)); 	# *a
-+		&mul($w);			# *a * w
-+		&add("eax",$c);			# L(t)+= c
-+		&adc("edx",0);			# H(t)+=carry
-+		 &add("eax",&DWP($i,$r));	# L(t)+= *r
-+		&adc("edx",0);			# H(t)+=carry
-+		 &mov(&DWP($i,$r),"eax");	# *r= L(t);
-+		&mov($c,"edx");			# c=  H(t);
-+		}
-+
-+	&comment("");
-+	&sub("ecx",8);
-+	&lea($a,&DWP(32,$a));
-+	&lea($r,&DWP(32,$r));
-+	&jnz(&label("maw_loop"));
-+
-+	&set_label("maw_finish",0);
-+	&mov("ecx",&wparam(2));	# get num
-+	&and("ecx",7);
-+	&jnz(&label("maw_finish2"));	# helps branch prediction
-+	&jmp(&label("maw_end"));
-+
-+	&set_label("maw_finish2",1);
-+	for ($i=0; $i<7; $i++)
-+		{
-+		&comment("Tail Round $i");
-+		 &mov("eax",&DWP($i*4,$a));	# *a
-+		&mul($w);			# *a * w
-+		&add("eax",$c);			# L(t)+=c
-+		&adc("edx",0);			# H(t)+=carry
-+		 &add("eax",&DWP($i*4,$r));	# L(t)+= *r
-+		&adc("edx",0);			# H(t)+=carry
-+		 &dec("ecx") if ($i != 7-1);
-+		&mov(&DWP($i*4,$r),"eax");	# *r= L(t);
-+		 &mov($c,"edx");		# c=  H(t);
-+		&jz(&label("maw_end")) if ($i != 7-1);
-+		}
-+	&set_label("maw_end",0);
-+	&mov("eax",$c);
-+
-+	&pop("ecx");	# clear variable from
-+
-+	&function_end($name);
-+	}
-+
-+sub bn_mul_words
-+	{
-+	local($name)=@_;
-+
-+	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
-+
-+	$r="eax";
-+	$a="edx";
-+	$c="ecx";
-+
-+	if ($sse2) {
-+		&picmeup("eax","OPENSSL_ia32cap_P");
-+		&bt(&DWP(0,"eax"),26);
-+		&jnc(&label("mw_non_sse2"));
-+
-+		&mov($r,&wparam(0));
-+		&mov($a,&wparam(1));
-+		&mov($c,&wparam(2));
-+		&movd("mm0",&wparam(3));	# mm0 = w
-+		&pxor("mm1","mm1");		# mm1 = carry = 0
-+
-+	&set_label("mw_sse2_loop",16);
-+		&movd("mm2",&DWP(0,$a));	# mm2 = a[i]
-+		&pmuludq("mm2","mm0");		# a[i] *= w
-+		&lea($a,&DWP(4,$a));
-+		&paddq("mm1","mm2");		# carry += a[i]*w
-+		&movd(&DWP(0,$r),"mm1");	# r[i] = carry_low
-+		&sub($c,1);
-+		&psrlq("mm1",32);		# carry = carry_high
-+		&lea($r,&DWP(4,$r));
-+		&jnz(&label("mw_sse2_loop"));
-+
-+		&movd("eax","mm1");		# return carry
-+		&emms();
-+		&ret();
-+	&set_label("mw_non_sse2",16);
-+	}
-+
-+	# function_begin prologue
-+	&push("ebp");
-+	&push("ebx");
-+	&push("esi");
-+	&push("edi");
-+
-+	&comment("");
-+	$Low="eax";
-+	$High="edx";
-+	$a="ebx";
-+	$w="ecx";
-+	$r="edi";
-+	$c="esi";
-+	$num="ebp";
-+
-+	&xor($c,$c);		# clear carry
-+	&mov($r,&wparam(0));	#
-+	&mov($a,&wparam(1));	#
-+	&mov($num,&wparam(2));	#
-+	&mov($w,&wparam(3));	#
-+
-+	&and($num,0xfffffff8);	# num / 8
-+	&jz(&label("mw_finish"));
-+
-+	&set_label("mw_loop",0);
-+	for ($i=0; $i<32; $i+=4)
-+		{
-+		&comment("Round $i");
-+
-+		 &mov("eax",&DWP($i,$a,"",0)); 	# *a
-+		&mul($w);			# *a * w
-+		&add("eax",$c);			# L(t)+=c
-+		 # XXX
-+
-+		&adc("edx",0);			# H(t)+=carry
-+		 &mov(&DWP($i,$r,"",0),"eax");	# *r= L(t);
-+
-+		&mov($c,"edx");			# c=  H(t);
-+		}
-+
-+	&comment("");
-+	&add($a,32);
-+	&add($r,32);
-+	&sub($num,8);
-+	&jz(&label("mw_finish"));
-+	&jmp(&label("mw_loop"));
-+
-+	&set_label("mw_finish",0);
-+	&mov($num,&wparam(2));	# get num
-+	&and($num,7);
-+	&jnz(&label("mw_finish2"));
-+	&jmp(&label("mw_end"));
-+
-+	&set_label("mw_finish2",1);
-+	for ($i=0; $i<7; $i++)
-+		{
-+		&comment("Tail Round $i");
-+		 &mov("eax",&DWP($i*4,$a,"",0));# *a
-+		&mul($w);			# *a * w
-+		&add("eax",$c);			# L(t)+=c
-+		 # XXX
-+		&adc("edx",0);			# H(t)+=carry
-+		 &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t);
-+		&mov($c,"edx");			# c=  H(t);
-+		 &dec($num) if ($i != 7-1);
-+		&jz(&label("mw_end")) if ($i != 7-1);
-+		}
-+	&set_label("mw_end",0);
-+	&mov("eax",$c);
-+
-+	&function_end($name);
-+	}
-+
-+sub bn_sqr_words
-+	{
-+	local($name)=@_;
-+
-+	&function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
-+
-+	$r="eax";
-+	$a="edx";
-+	$c="ecx";
-+
-+	if ($sse2) {
-+		&picmeup("eax","OPENSSL_ia32cap_P");
-+		&bt(&DWP(0,"eax"),26);
-+		&jnc(&label("sqr_non_sse2"));
-+
-+		&mov($r,&wparam(0));
-+		&mov($a,&wparam(1));
-+		&mov($c,&wparam(2));
-+
-+	&set_label("sqr_sse2_loop",16);
-+		&movd("mm0",&DWP(0,$a));	# mm0 = a[i]
-+		&pmuludq("mm0","mm0");		# a[i] *= a[i]
-+		&lea($a,&DWP(4,$a));		# a++
-+		&movq(&QWP(0,$r),"mm0");	# r[i] = a[i]*a[i]
-+		&sub($c,1);
-+		&lea($r,&DWP(8,$r));		# r += 2
-+		&jnz(&label("sqr_sse2_loop"));
-+
-+		&emms();
-+		&ret();
-+	&set_label("sqr_non_sse2",16);
-+	}
-+
-+	# function_begin prologue
-+	&push("ebp");
-+	&push("ebx");
-+	&push("esi");
-+	&push("edi");
-+
-+	&comment("");
-+	$r="esi";
-+	$a="edi";
-+	$num="ebx";
-+
-+	&mov($r,&wparam(0));	#
-+	&mov($a,&wparam(1));	#
-+	&mov($num,&wparam(2));	#
-+
-+	&and($num,0xfffffff8);	# num / 8
-+	&jz(&label("sw_finish"));
-+
-+	&set_label("sw_loop",0);
-+	for ($i=0; $i<32; $i+=4)
-+		{
-+		&comment("Round $i");
-+		&mov("eax",&DWP($i,$a,"",0)); 	# *a
-+		 # XXX
-+		&mul("eax");			# *a * *a
-+		&mov(&DWP($i*2,$r,"",0),"eax");	#
-+		 &mov(&DWP($i*2+4,$r,"",0),"edx");#
-+		}
-+
-+	&comment("");
-+	&add($a,32);
-+	&add($r,64);
-+	&sub($num,8);
-+	&jnz(&label("sw_loop"));
-+
-+	&set_label("sw_finish",0);
-+	&mov($num,&wparam(2));	# get num
-+	&and($num,7);
-+	&jz(&label("sw_end"));
-+
-+	for ($i=0; $i<7; $i++)
-+		{
-+		&comment("Tail Round $i");
-+		&mov("eax",&DWP($i*4,$a,"",0));	# *a
-+		 # XXX
-+		&mul("eax");			# *a * *a
-+		&mov(&DWP($i*8,$r,"",0),"eax");	#
-+		 &dec($num) if ($i != 7-1);
-+		&mov(&DWP($i*8+4,$r,"",0),"edx");
-+		 &jz(&label("sw_end")) if ($i != 7-1);
-+		}
-+	&set_label("sw_end",0);
-+
-+	&function_end($name);
-+	}
-+
-+sub bn_div_words
-+	{
-+	local($name)=@_;
-+
-+	&function_begin_B($name,"");
-+	&mov("edx",&wparam(0));	#
-+	&mov("eax",&wparam(1));	#
-+	&mov("ecx",&wparam(2));	#
-+	&div("ecx");
-+	&ret();
-+	&function_end_B($name);
-+	}
-+
-+sub bn_add_words
-+	{
-+	local($name)=@_;
-+
-+	&function_begin($name,"");
-+
-+	&comment("");
-+	$a="esi";
-+	$b="edi";
-+	$c="eax";
-+	$r="ebx";
-+	$tmp1="ecx";
-+	$tmp2="edx";
-+	$num="ebp";
-+
-+	&mov($r,&wparam(0));	# get r
-+	 &mov($a,&wparam(1));	# get a
-+	&mov($b,&wparam(2));	# get b
-+	 &mov($num,&wparam(3));	# get num
-+	&xor($c,$c);		# clear carry
-+	 &and($num,0xfffffff8);	# num / 8
-+
-+	&jz(&label("aw_finish"));
-+
-+	&set_label("aw_loop",0);
-+	for ($i=0; $i<8; $i++)
-+		{
-+		&comment("Round $i");
-+
-+		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
-+		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
-+		&add($tmp1,$c);
-+		 &mov($c,0);
-+		&adc($c,$c);
-+		 &add($tmp1,$tmp2);
-+		&adc($c,0);
-+		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
-+		}
-+
-+	&comment("");
-+	&add($a,32);
-+	 &add($b,32);
-+	&add($r,32);
-+	 &sub($num,8);
-+	&jnz(&label("aw_loop"));
-+
-+	&set_label("aw_finish",0);
-+	&mov($num,&wparam(3));	# get num
-+	&and($num,7);
-+	 &jz(&label("aw_end"));
-+
-+	for ($i=0; $i<7; $i++)
-+		{
-+		&comment("Tail Round $i");
-+		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
-+		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
-+		&add($tmp1,$c);
-+		 &mov($c,0);
-+		&adc($c,$c);
-+		 &add($tmp1,$tmp2);
-+		&adc($c,0);
-+		 &dec($num) if ($i != 6);
-+		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
-+		 &jz(&label("aw_end")) if ($i != 6);
-+		}
-+	&set_label("aw_end",0);
-+
-+#	&mov("eax",$c);		# $c is "eax"
-+
-+	&function_end($name);
-+	}
-+
-+sub bn_sub_words
-+	{
-+	local($name)=@_;
-+
-+	&function_begin($name,"");
-+
-+	&comment("");
-+	$a="esi";
-+	$b="edi";
-+	$c="eax";
-+	$r="ebx";
-+	$tmp1="ecx";
-+	$tmp2="edx";
-+	$num="ebp";
-+
-+	&mov($r,&wparam(0));	# get r
-+	 &mov($a,&wparam(1));	# get a
-+	&mov($b,&wparam(2));	# get b
-+	 &mov($num,&wparam(3));	# get num
-+	&xor($c,$c);		# clear carry
-+	 &and($num,0xfffffff8);	# num / 8
-+
-+	&jz(&label("aw_finish"));
-+
-+	&set_label("aw_loop",0);
-+	for ($i=0; $i<8; $i++)
-+		{
-+		&comment("Round $i");
-+
-+		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
-+		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
-+		&sub($tmp1,$c);
-+		 &mov($c,0);
-+		&adc($c,$c);
-+		 &sub($tmp1,$tmp2);
-+		&adc($c,0);
-+		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
-+		}
-+
-+	&comment("");
-+	&add($a,32);
-+	 &add($b,32);
-+	&add($r,32);
-+	 &sub($num,8);
-+	&jnz(&label("aw_loop"));
-+
-+	&set_label("aw_finish",0);
-+	&mov($num,&wparam(3));	# get num
-+	&and($num,7);
-+	 &jz(&label("aw_end"));
-+
-+	for ($i=0; $i<7; $i++)
-+		{
-+		&comment("Tail Round $i");
-+		&mov($tmp1,&DWP($i*4,$a,"",0));	# *a
-+		 &mov($tmp2,&DWP($i*4,$b,"",0));# *b
-+		&sub($tmp1,$c);
-+		 &mov($c,0);
-+		&adc($c,$c);
-+		 &sub($tmp1,$tmp2);
-+		&adc($c,0);
-+		 &dec($num) if ($i != 6);
-+		&mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
-+		 &jz(&label("aw_end")) if ($i != 6);
-+		}
-+	&set_label("aw_end",0);
-+
-+#	&mov("eax",$c);		# $c is "eax"
-+
-+	&function_end($name);
-+	}
-+
-+sub bn_sub_part_words
-+	{
-+	local($name)=@_;
-+
-+	&function_begin($name,"");
-+
-+	&comment("");
-+	$a="esi";
-+	$b="edi";
-+	$c="eax";
-+	$r="ebx";
-+	$tmp1="ecx";
-+	$tmp2="edx";
-+	$num="ebp";
-+
-+	&mov($r,&wparam(0));	# get r
-+	 &mov($a,&wparam(1));	# get a
-+	&mov($b,&wparam(2));	# get b
-+	 &mov($num,&wparam(3));	# get num
-+	&xor($c,$c);		# clear carry
-+	 &and($num,0xfffffff8);	# num / 8
-+
-+	&jz(&label("aw_finish"));
-+
-+	&set_label("aw_loop",0);
-+	for ($i=0; $i<8; $i++)
-+		{
-+		&comment("Round $i");
-+
-+		&mov($tmp1,&DWP($i*4,$a,"",0)); 	# *a
-+		 &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
-+		&sub($tmp1,$c);
-+		 &mov($c,0);
-+		&adc($c,$c);
-+		 &sub($tmp1,$tmp2);
-+		&adc($c,0);
-+		 &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
-+		}
-+
-+	&comment("");
-+	&add($a,32);
-+	 &add($b,32);
-+	&add($r,32);
-+	 &sub($num,8);
-+	&jnz(&label("aw_loop"));
-+
-+	&set_label("aw_finish",0);
-+	&mov($num,&wparam(3));	# get num
-+	&and($num,7);
-+	 &jz(&label("aw_end"));
-+
-+	for ($i=0; $i<7; $i++)
-+		{
-+		&comment("Tail Round $i");
-+		&mov($tmp1,&DWP(0,$a,"",0));	# *a
-+		 &mov($tmp2,&DWP(0,$b,"",0));# *b
-+		&sub($tmp1,$c);
-+		 &mov($c,0);
-+		&adc($c,$c);
-+		 &sub($tmp1,$tmp2);
-+		&adc($c,0);
-+		&mov(&DWP(0,$r,"",0),$tmp1);	# *r
-+		&add($a, 4);
-+		&add($b, 4);
-+		&add($r, 4);
-+		 &dec($num) if ($i != 6);
-+		 &jz(&label("aw_end")) if ($i != 6);
-+		}
-+	&set_label("aw_end",0);
-+
-+	&cmp(&wparam(4),0);
-+	&je(&label("pw_end"));
-+
-+	&mov($num,&wparam(4));	# get dl
-+	&cmp($num,0);
-+	&je(&label("pw_end"));
-+	&jge(&label("pw_pos"));
-+
-+	&comment("pw_neg");
-+	&mov($tmp2,0);
-+	&sub($tmp2,$num);
-+	&mov($num,$tmp2);
-+	&and($num,0xfffffff8);	# num / 8
-+	&jz(&label("pw_neg_finish"));
-+
-+	&set_label("pw_neg_loop",0);
-+	for ($i=0; $i<8; $i++)
-+	{
-+	    &comment("dl<0 Round $i");
-+
-+	    &mov($tmp1,0);
-+	    &mov($tmp2,&DWP($i*4,$b,"",0)); 	# *b
-+	    &sub($tmp1,$c);
-+	    &mov($c,0);
-+	    &adc($c,$c);
-+	    &sub($tmp1,$tmp2);
-+	    &adc($c,0);
-+	    &mov(&DWP($i*4,$r,"",0),$tmp1); 	# *r
-+	}
-+	    
-+	&comment("");
-+	&add($b,32);
-+	&add($r,32);
-+	&sub($num,8);
-+	&jnz(&label("pw_neg_loop"));
-+	    
-+	&set_label("pw_neg_finish",0);
-+	&mov($tmp2,&wparam(4));	# get dl
-+	&mov($num,0);
-+	&sub($num,$tmp2);
-+	&and($num,7);
-+	&jz(&label("pw_end"));
-+	    
-+	for ($i=0; $i<7; $i++)
-+	{
-+	    &comment("dl<0 Tail Round $i");
-+	    &mov($tmp1,0);
-+	    &mov($tmp2,&DWP($i*4,$b,"",0));# *b
-+	    &sub($tmp1,$c);
-+	    &mov($c,0);
-+	    &adc($c,$c);
-+	    &sub($tmp1,$tmp2);
-+	    &adc($c,0);
-+	    &dec($num) if ($i != 6);
-+	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
-+	    &jz(&label("pw_end")) if ($i != 6);
-+	}
-+
-+	&jmp(&label("pw_end"));
-+	
-+	&set_label("pw_pos",0);
-+	
-+	&and($num,0xfffffff8);	# num / 8
-+	&jz(&label("pw_pos_finish"));
-+
-+	&set_label("pw_pos_loop",0);
-+
-+	for ($i=0; $i<8; $i++)
-+	{
-+	    &comment("dl>0 Round $i");
-+
-+	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
-+	    &sub($tmp1,$c);
-+	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
-+	    &jnc(&label("pw_nc".$i));
-+	}
-+	    
-+	&comment("");
-+	&add($a,32);
-+	&add($r,32);
-+	&sub($num,8);
-+	&jnz(&label("pw_pos_loop"));
-+	    
-+	&set_label("pw_pos_finish",0);
-+	&mov($num,&wparam(4));	# get dl
-+	&and($num,7);
-+	&jz(&label("pw_end"));
-+	    
-+	for ($i=0; $i<7; $i++)
-+	{
-+	    &comment("dl>0 Tail Round $i");
-+	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
-+	    &sub($tmp1,$c);
-+	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
-+	    &jnc(&label("pw_tail_nc".$i));
-+	    &dec($num) if ($i != 6);
-+	    &jz(&label("pw_end")) if ($i != 6);
-+	}
-+	&mov($c,1);
-+	&jmp(&label("pw_end"));
-+
-+	&set_label("pw_nc_loop",0);
-+	for ($i=0; $i<8; $i++)
-+	{
-+	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
-+	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
-+	    &set_label("pw_nc".$i,0);
-+	}
-+	    
-+	&comment("");
-+	&add($a,32);
-+	&add($r,32);
-+	&sub($num,8);
-+	&jnz(&label("pw_nc_loop"));
-+	    
-+	&mov($num,&wparam(4));	# get dl
-+	&and($num,7);
-+	&jz(&label("pw_nc_end"));
-+	    
-+	for ($i=0; $i<7; $i++)
-+	{
-+	    &mov($tmp1,&DWP($i*4,$a,"",0));	# *a
-+	    &mov(&DWP($i*4,$r,"",0),$tmp1);	# *r
-+	    &set_label("pw_tail_nc".$i,0);
-+	    &dec($num) if ($i != 6);
-+	    &jz(&label("pw_nc_end")) if ($i != 6);
-+	}
-+
-+	&set_label("pw_nc_end",0);
-+	&mov($c,0);
-+
-+	&set_label("pw_end",0);
-+
-+#	&mov("eax",$c);		# $c is "eax"
-+
-+	&function_end($name);
-+	}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/bn-c64xplus.asm b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/bn-c64xplus.asm
-new file mode 100644
-index 0000000..de6d377
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/bn-c64xplus.asm
-@@ -0,0 +1,382 @@
-+;; Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+;;
-+;; Licensed under the OpenSSL license (the "License").  You may not use
-+;; this file except in compliance with the License.  You can obtain a copy
-+;; in the file LICENSE in the source distribution or at
-+;; https://www.openssl.org/source/license.html
-+;;
-+;;====================================================================
-+;; Written by Andy Polyakov  for the OpenSSL
-+;; project.
-+;;
-+;; Rights for redistribution and usage in source and binary forms are
-+;; granted according to the OpenSSL license. Warranty of any kind is
-+;; disclaimed.
-+;;====================================================================
-+;; Compiler-generated multiply-n-add SPLOOP runs at 12*n cycles, n
-+;; being the number of 32-bit words, addition - 8*n. Corresponding 4x
-+;; unrolled SPLOOP-free loops - at ~8*n and ~5*n. Below assembler
-+;; SPLOOPs spin at ... 2*n cycles [plus epilogue].
-+;;====================================================================
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.asg	bn_mul_add_words,_bn_mul_add_words
-+	.asg	bn_mul_words,_bn_mul_words
-+	.asg	bn_sqr_words,_bn_sqr_words
-+	.asg	bn_add_words,_bn_add_words
-+	.asg	bn_sub_words,_bn_sub_words
-+	.asg	bn_div_words,_bn_div_words
-+	.asg	bn_sqr_comba8,_bn_sqr_comba8
-+	.asg	bn_mul_comba8,_bn_mul_comba8
-+	.asg	bn_sqr_comba4,_bn_sqr_comba4
-+	.asg	bn_mul_comba4,_bn_mul_comba4
-+	.endif
-+
-+	.asg	B3,RA
-+	.asg	A4,ARG0
-+	.asg	B4,ARG1
-+	.asg	A6,ARG2
-+	.asg	B6,ARG3
-+	.asg	A8,ARG4
-+	.asg	B8,ARG5
-+	.asg	A4,RET
-+	.asg	A15,FP
-+	.asg	B14,DP
-+	.asg	B15,SP
-+
-+	.global	_bn_mul_add_words
-+_bn_mul_add_words:
-+	.asmfunc
-+	MV	ARG2,B0
-+  [!B0]	BNOP	RA
-+||[!B0]	MVK	0,RET
-+   [B0]	MVC	B0,ILC
-+   [B0]	ZERO	A19		; high part of accumulator
-+|| [B0]	MV	ARG0,A2
-+|| [B0]	MV	ARG3,A3
-+	NOP	3
-+
-+	SPLOOP	2		; 2*n+10
-+;;====================================================================
-+	LDW	*ARG1++,B7	; ap[i]
-+	NOP	3
-+	LDW	*ARG0++,A7	; rp[i]
-+	MPY32U	B7,A3,A17:A16
-+	NOP	3		; [2,0] in epilogue
-+	ADDU	A16,A7,A21:A20
-+	ADDU	A19,A21:A20,A19:A18
-+||	MV.S	A17,A23
-+	SPKERNEL 2,1		; leave slot for "return value"
-+||	STW	A18,*A2++	; rp[i]
-+||	ADD	A19,A23,A19
-+;;====================================================================
-+	BNOP	RA,4
-+	MV	A19,RET		; return value
-+	.endasmfunc
-+
-+	.global	_bn_mul_words
-+_bn_mul_words:
-+	.asmfunc
-+	MV	ARG2,B0
-+  [!B0]	BNOP	RA
-+||[!B0]	MVK	0,RET
-+   [B0]	MVC	B0,ILC
-+   [B0]	ZERO	A19		; high part of accumulator
-+	NOP	3
-+
-+	SPLOOP	2		; 2*n+10
-+;;====================================================================
-+	LDW	*ARG1++,A7	; ap[i]
-+	NOP	4
-+	MPY32U	A7,ARG3,A17:A16
-+	NOP	4		; [2,0] in epiloque
-+	ADDU	A19,A16,A19:A18
-+||	MV.S	A17,A21
-+	SPKERNEL 2,1		; leave slot for "return value"
-+||	STW	A18,*ARG0++	; rp[i]
-+||	ADD.L	A19,A21,A19
-+;;====================================================================
-+	BNOP	RA,4
-+	MV	A19,RET		; return value
-+	.endasmfunc
-+
-+	.global	_bn_sqr_words
-+_bn_sqr_words:
-+	.asmfunc
-+	MV	ARG2,B0
-+  [!B0]	BNOP	RA
-+||[!B0]	MVK	0,RET
-+   [B0]	MVC	B0,ILC
-+   [B0]	MV	ARG0,B2
-+|| [B0]	ADD	4,ARG0,ARG0
-+	NOP	3
-+
-+	SPLOOP	2		; 2*n+10
-+;;====================================================================
-+	LDW	*ARG1++,B7	; ap[i]
-+	NOP	4
-+	MPY32U	B7,B7,B1:B0
-+	NOP	3		; [2,0] in epilogue
-+	STW	B0,*B2++(8)	; rp[2*i]
-+	MV	B1,A1
-+	SPKERNEL 2,0		; fully overlap BNOP RA,5
-+||	STW	A1,*ARG0++(8)	; rp[2*i+1]
-+;;====================================================================
-+	BNOP	RA,5
-+	.endasmfunc
-+
-+	.global	_bn_add_words
-+_bn_add_words:
-+	.asmfunc
-+	MV	ARG3,B0
-+  [!B0]	BNOP	RA
-+||[!B0]	MVK	0,RET
-+   [B0]	MVC	B0,ILC
-+   [B0]	ZERO	A1		; carry flag
-+|| [B0]	MV	ARG0,A3
-+	NOP	3
-+
-+	SPLOOP	2		; 2*n+6
-+;;====================================================================
-+	LDW	*ARG2++,A7	; bp[i]
-+||	LDW	*ARG1++,B7	; ap[i]
-+	NOP	4
-+	ADDU	A7,B7,A9:A8
-+	ADDU	A1,A9:A8,A1:A0
-+	SPKERNEL 0,0		; fully overlap BNOP RA,5
-+||	STW	A0,*A3++	; write result
-+||	MV	A1,RET		; keep carry flag in RET
-+;;====================================================================
-+	BNOP	RA,5
-+	.endasmfunc
-+
-+	.global	_bn_sub_words
-+_bn_sub_words:
-+	.asmfunc
-+	MV	ARG3,B0
-+  [!B0]	BNOP	RA
-+||[!B0]	MVK	0,RET
-+   [B0]	MVC	B0,ILC
-+   [B0]	ZERO	A2		; borrow flag
-+|| [B0]	MV	ARG0,A3
-+	NOP	3
-+
-+	SPLOOP	2		; 2*n+6
-+;;====================================================================
-+	LDW	*ARG2++,A7	; bp[i]
-+||	LDW	*ARG1++,B7	; ap[i]
-+	NOP	4
-+	SUBU	B7,A7,A1:A0
-+  [A2]	SUB	A1:A0,1,A1:A0
-+	SPKERNEL 0,1		; leave slot for "return borrow flag"
-+||	STW	A0,*A3++	; write result
-+||	AND	1,A1,A2		; pass on borrow flag
-+;;====================================================================
-+	BNOP	RA,4
-+	AND	1,A1,RET	; return borrow flag
-+	.endasmfunc
-+
-+	.global	_bn_div_words
-+_bn_div_words:
-+	.asmfunc
-+	LMBD	1,A6,A0		; leading zero bits in dv
-+	LMBD	1,A4,A1		; leading zero bits in hi
-+||	MVK	32,B0
-+	CMPLTU	A1,A0,A2
-+||	ADD	A0,B0,B0
-+  [ A2]	BNOP	RA
-+||[ A2]	MVK	-1,A4		; return overflow
-+||[!A2]	MV	A4,A3		; reassign hi
-+  [!A2]	MV	B4,A4		; reassign lo, will be quotient
-+||[!A2]	MVC	B0,ILC
-+  [!A2]	SHL	A6,A0,A6	; normalize dv
-+||	MVK	1,A1
-+
-+  [!A2]	CMPLTU	A3,A6,A1	; hi>31
-+
-+	SPLOOP	3
-+  [!A1]	CMPLTU	A3,A6,A1	; hi>31
-+	SPKERNEL
-+
-+	BNOP	RA,5
-+	.endasmfunc
-+
-+;;====================================================================
-+;; Not really Comba algorithm, just straightforward NxM... Dedicated
-+;; fully unrolled real Comba implementations are asymptotically 2x
-+;; faster, but naturally larger undertaking. Purpose of this exercise
-+;; was rather to learn to master nested SPLOOPs...
-+;;====================================================================
-+	.global	_bn_sqr_comba8
-+	.global	_bn_mul_comba8
-+_bn_sqr_comba8:
-+	MV	ARG1,ARG2
-+_bn_mul_comba8:
-+	.asmfunc
-+	MVK	8,B0		; N, RILC
-+||	MVK	8,A0		; M, outer loop counter
-+||	MV	ARG1,A5		; copy ap
-+||	MV	ARG0,B4		; copy rp
-+||	ZERO	B19		; high part of accumulator
-+	MVC	B0,RILC
-+||	SUB	B0,2,B1		; N-2, initial ILC
-+||	SUB	B0,1,B2		; const B2=N-1
-+||	LDW	*A5++,B6	; ap[0]
-+||	MV	A0,A3		; const A3=M
-+sploopNxM?:			; for best performance arrange M<=N
-+   [A0]	SPLOOPD	2		; 2*n+10
-+||	MVC	B1,ILC
-+||	ADDAW	B4,B0,B5
-+||	ZERO	B7
-+||	LDW	*A5++,A9	; pre-fetch ap[1]
-+||	ZERO	A1
-+||	SUB	A0,1,A0
-+;;====================================================================
-+;; SPLOOP from bn_mul_add_words, but with flipped A<>B register files.
-+;; This is because of Advisory 15 from TI publication SPRZ247I.
-+	LDW	*ARG2++,A7	; bp[i]
-+	NOP	3
-+   [A1]	LDW	*B5++,B7	; rp[i]
-+	MPY32U	A7,B6,B17:B16
-+	NOP	3
-+	ADDU	B16,B7,B21:B20
-+	ADDU	B19,B21:B20,B19:B18
-+||	MV.S	B17,B23
-+	SPKERNEL
-+||	STW	B18,*B4++	; rp[i]
-+||	ADD.S	B19,B23,B19
-+;;====================================================================
-+outer?:				; m*2*(n+1)+10
-+	SUBAW	ARG2,A3,ARG2	; rewind bp to bp[0]
-+	SPMASKR
-+||	CMPGT	A0,1,A2		; done pre-fetching ap[i+1]?
-+	MVD	A9,B6		; move through .M unit(*)
-+   [A2]	LDW	*A5++,A9	; pre-fetch ap[i+1]
-+	SUBAW	B5,B2,B5	; rewind rp to rp[1]
-+	MVK	1,A1
-+   [A0]	BNOP.S1	outer?,4
-+|| [A0]	SUB.L	A0,1,A0
-+	STW	B19,*B4--[B2]	; rewind rp tp rp[1]
-+||	ZERO.S	B19		; high part of accumulator
-+;; end of outer?
-+	BNOP	RA,5		; return
-+	.endasmfunc
-+;; (*)	It should be noted that B6 is used as input to MPY32U in
-+;;	chronologically next cycle in *preceding* SPLOOP iteration.
-+;;	Normally such arrangement would require DINT, but at this
-+;;	point SPLOOP is draining and interrupts are disabled
-+;;	implicitly.
-+
-+	.global	_bn_sqr_comba4
-+	.global	_bn_mul_comba4
-+_bn_sqr_comba4:
-+	MV	ARG1,ARG2
-+_bn_mul_comba4:
-+	.asmfunc
-+	.if	0
-+	BNOP	sploopNxM?,3
-+	;; Above mentioned m*2*(n+1)+10 does not apply in n=m=4 case,
-+	;; because of low-counter effect, when prologue phase finishes
-+	;; before SPKERNEL instruction is reached. As result it's 25%
-+	;; slower than expected...
-+	MVK	4,B0		; N, RILC
-+||	MVK	4,A0		; M, outer loop counter
-+||	MV	ARG1,A5		; copy ap
-+||	MV	ARG0,B4		; copy rp
-+||	ZERO	B19		; high part of accumulator
-+	MVC	B0,RILC
-+||	SUB	B0,2,B1		; first ILC
-+||	SUB	B0,1,B2		; const B2=N-1
-+||	LDW	*A5++,B6	; ap[0]
-+||	MV	A0,A3		; const A3=M
-+	.else
-+	;; This alternative is an exercise in fully unrolled Comba
-+	;; algorithm implementation that operates at n*(n+1)+12, or
-+	;; as little as 32 cycles...
-+	LDW	*ARG1[0],B16	; a[0]
-+||	LDW	*ARG2[0],A16	; b[0]
-+	LDW	*ARG1[1],B17	; a[1]
-+||	LDW	*ARG2[1],A17	; b[1]
-+	LDW	*ARG1[2],B18	; a[2]
-+||	LDW	*ARG2[2],A18	; b[2]
-+	LDW	*ARG1[3],B19	; a[3]
-+||	LDW	*ARG2[3],A19	; b[3]
-+	NOP
-+	MPY32U	A16,B16,A1:A0	; a[0]*b[0]
-+	MPY32U	A17,B16,A23:A22	; a[0]*b[1]
-+	MPY32U	A16,B17,A25:A24	; a[1]*b[0]
-+	MPY32U	A16,B18,A27:A26	; a[2]*b[0]
-+	STW	A0,*ARG0[0]
-+||	MPY32U	A17,B17,A29:A28	; a[1]*b[1]
-+	MPY32U	A18,B16,A31:A30	; a[0]*b[2]
-+||	ADDU	A22,A1,A1:A0
-+	MV	A23,B0
-+||	MPY32U	A19,B16,A21:A20	; a[3]*b[0]
-+||	ADDU	A24,A1:A0,A1:A0
-+	ADDU	A25,B0,B1:B0
-+||	STW	A0,*ARG0[1]
-+||	MPY32U	A18,B17,A23:A22	; a[2]*b[1]
-+||	ADDU	A26,A1,A9:A8
-+	ADDU	A27,B1,B9:B8
-+||	MPY32U	A17,B18,A25:A24	; a[1]*b[2]
-+||	ADDU	A28,A9:A8,A9:A8
-+	ADDU	A29,B9:B8,B9:B8
-+||	MPY32U	A16,B19,A27:A26	; a[0]*b[3]
-+||	ADDU	A30,A9:A8,A9:A8
-+	ADDU	A31,B9:B8,B9:B8
-+||	ADDU	B0,A9:A8,A9:A8
-+	STW	A8,*ARG0[2]
-+||	ADDU	A20,A9,A1:A0
-+	ADDU	A21,B9,B1:B0
-+||	MPY32U	A19,B17,A21:A20	; a[3]*b[1]
-+||	ADDU	A22,A1:A0,A1:A0
-+	ADDU	A23,B1:B0,B1:B0
-+||	MPY32U	A18,B18,A23:A22	; a[2]*b[2]
-+||	ADDU	A24,A1:A0,A1:A0
-+	ADDU	A25,B1:B0,B1:B0
-+||	MPY32U	A17,B19,A25:A24	; a[1]*b[3]
-+||	ADDU	A26,A1:A0,A1:A0
-+	ADDU	A27,B1:B0,B1:B0
-+||	ADDU	B8,A1:A0,A1:A0
-+	STW	A0,*ARG0[3]
-+||	MPY32U	A19,B18,A27:A26	; a[3]*b[2]
-+||	ADDU	A20,A1,A9:A8
-+	ADDU	A21,B1,B9:B8
-+||	MPY32U	A18,B19,A29:A28	; a[2]*b[3]
-+||	ADDU	A22,A9:A8,A9:A8
-+	ADDU	A23,B9:B8,B9:B8
-+||	MPY32U	A19,B19,A31:A30	; a[3]*b[3]
-+||	ADDU	A24,A9:A8,A9:A8
-+	ADDU	A25,B9:B8,B9:B8
-+||	ADDU	B0,A9:A8,A9:A8
-+	STW	A8,*ARG0[4]
-+||	ADDU	A26,A9,A1:A0
-+	ADDU	A27,B9,B1:B0
-+||	ADDU	A28,A1:A0,A1:A0
-+	ADDU	A29,B1:B0,B1:B0
-+||	BNOP	RA
-+||	ADDU	B8,A1:A0,A1:A0
-+	STW	A0,*ARG0[5]
-+||	ADDU	A30,A1,A9:A8
-+	ADD	A31,B1,B8
-+	ADDU	B0,A9:A8,A9:A8	; removed || to avoid cross-path stall below
-+	ADD	B8,A9,A9
-+||	STW	A8,*ARG0[6]
-+	STW	A9,*ARG0[7]
-+	.endif
-+	.endasmfunc
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/c64xplus-gf2m.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/c64xplus-gf2m.pl
-new file mode 100644
-index 0000000..c0e5400
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/c64xplus-gf2m.pl
-@@ -0,0 +1,160 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# February 2012
-+#
-+# The module implements bn_GF2m_mul_2x2 polynomial multiplication
-+# used in bn_gf2m.c. It's kind of low-hanging mechanical port from
-+# C for the time being... The subroutine runs in 37 cycles, which is
-+# 4.5x faster than compiler-generated code. Though comparison is
-+# totally unfair, because this module utilizes Galois Field Multiply
-+# instruction.
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+($rp,$a1,$a0,$b1,$b0)=("A4","B4","A6","B6","A8");   # argument vector
-+
-+($Alo,$Alox0,$Alox1,$Alox2,$Alox3)=map("A$_",(16..20));
-+($Ahi,$Ahix0,$Ahix1,$Ahix2,$Ahix3)=map("B$_",(16..20));
-+($B_0,$B_1,$B_2,$B_3)=("B5","A5","A7","B7");
-+($A,$B)=($Alo,$B_1);
-+$xFF="B1";
-+
-+sub mul_1x1_upper {
-+my ($A,$B)=@_;
-+$code.=<<___;
-+	EXTU	$B,8,24,$B_2		; smash $B to 4 bytes
-+||	AND	$B,$xFF,$B_0
-+||	SHRU	$B,24,$B_3
-+	SHRU	$A,16,   $Ahi		; smash $A to two halfwords
-+||	EXTU	$A,16,16,$Alo
-+
-+	XORMPY	$Alo,$B_2,$Alox2	; 16x8 bits muliplication
-+||	XORMPY	$Ahi,$B_2,$Ahix2
-+||	EXTU	$B,16,24,$B_1
-+	XORMPY	$Alo,$B_0,$Alox0
-+||	XORMPY	$Ahi,$B_0,$Ahix0
-+	XORMPY	$Alo,$B_3,$Alox3
-+||	XORMPY	$Ahi,$B_3,$Ahix3
-+	XORMPY	$Alo,$B_1,$Alox1
-+||	XORMPY	$Ahi,$B_1,$Ahix1
-+___
-+}
-+sub mul_1x1_merged {
-+my ($OUTlo,$OUThi,$A,$B)=@_;
-+$code.=<<___;
-+	 EXTU	$B,8,24,$B_2		; smash $B to 4 bytes
-+||	 AND	$B,$xFF,$B_0
-+||	 SHRU	$B,24,$B_3
-+	 SHRU	$A,16,   $Ahi		; smash $A to two halfwords
-+||	 EXTU	$A,16,16,$Alo
-+
-+	XOR	$Ahix0,$Alox2,$Ahix0
-+||	MV	$Ahix2,$OUThi
-+||	 XORMPY	$Alo,$B_2,$Alox2
-+	 XORMPY	$Ahi,$B_2,$Ahix2
-+||	 EXTU	$B,16,24,$B_1
-+||	 XORMPY	$Alo,$B_0,A1		; $Alox0
-+	XOR	$Ahix1,$Alox3,$Ahix1
-+||	SHL	$Ahix0,16,$OUTlo
-+||	SHRU	$Ahix0,16,$Ahix0
-+	XOR	$Alox0,$OUTlo,$OUTlo
-+||	XOR	$Ahix0,$OUThi,$OUThi
-+||	 XORMPY	$Ahi,$B_0,$Ahix0
-+||	 XORMPY	$Alo,$B_3,$Alox3
-+||	SHL	$Alox1,8,$Alox1
-+||	SHL	$Ahix3,8,$Ahix3
-+	XOR	$Alox1,$OUTlo,$OUTlo
-+||	XOR	$Ahix3,$OUThi,$OUThi
-+||	 XORMPY	$Ahi,$B_3,$Ahix3
-+||	SHL	$Ahix1,24,$Alox1
-+||	SHRU	$Ahix1,8, $Ahix1
-+	XOR	$Alox1,$OUTlo,$OUTlo
-+||	XOR	$Ahix1,$OUThi,$OUThi
-+||	 XORMPY	$Alo,$B_1,$Alox1
-+||	 XORMPY	$Ahi,$B_1,$Ahix1
-+||	 MV	A1,$Alox0
-+___
-+}
-+sub mul_1x1_lower {
-+my ($OUTlo,$OUThi)=@_;
-+$code.=<<___;
-+	;NOP
-+	XOR	$Ahix0,$Alox2,$Ahix0
-+||	MV	$Ahix2,$OUThi
-+	NOP
-+	XOR	$Ahix1,$Alox3,$Ahix1
-+||	SHL	$Ahix0,16,$OUTlo
-+||	SHRU	$Ahix0,16,$Ahix0
-+	XOR	$Alox0,$OUTlo,$OUTlo
-+||	XOR	$Ahix0,$OUThi,$OUThi
-+||	SHL	$Alox1,8,$Alox1
-+||	SHL	$Ahix3,8,$Ahix3
-+	XOR	$Alox1,$OUTlo,$OUTlo
-+||	XOR	$Ahix3,$OUThi,$OUThi
-+||	SHL	$Ahix1,24,$Alox1
-+||	SHRU	$Ahix1,8, $Ahix1
-+	XOR	$Alox1,$OUTlo,$OUTlo
-+||	XOR	$Ahix1,$OUThi,$OUThi
-+___
-+}
-+$code.=<<___;
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.asg	bn_GF2m_mul_2x2,_bn_GF2m_mul_2x2
-+	.endif
-+
-+	.global	_bn_GF2m_mul_2x2
-+_bn_GF2m_mul_2x2:
-+	.asmfunc
-+	MVK	0xFF,$xFF
-+___
-+	&mul_1x1_upper($a0,$b0);		# a0·b0
-+$code.=<<___;
-+||	MV	$b1,$B
-+	MV	$a1,$A
-+___
-+	&mul_1x1_merged("A28","B28",$A,$B);	# a0·b0/a1·b1
-+$code.=<<___;
-+||	XOR	$b0,$b1,$B
-+	XOR	$a0,$a1,$A
-+___
-+	&mul_1x1_merged("A31","B31",$A,$B);	# a1·b1/(a0+a1)·(b0+b1)
-+$code.=<<___;
-+	XOR	A28,A31,A29
-+||	XOR	B28,B31,B29			; a0·b0+a1·b1
-+___
-+	&mul_1x1_lower("A30","B30");		# (a0+a1)·(b0+b1)
-+$code.=<<___;
-+||	BNOP	B3
-+	XOR	A29,A30,A30
-+||	XOR	B29,B30,B30			; (a0+a1)·(b0+b1)-a0·b0-a1·b1
-+	XOR	B28,A30,A30
-+||	STW	A28,*${rp}[0]
-+	XOR	B30,A31,A31
-+||	STW	A30,*${rp}[1]
-+	STW	A31,*${rp}[2]
-+	STW	B31,*${rp}[3]
-+	.endasmfunc
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/co-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/co-586.pl
-new file mode 100644
-index 0000000..60d0363
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/co-586.pl
-@@ -0,0 +1,298 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],$0);
-+
-+&bn_mul_comba("bn_mul_comba8",8);
-+&bn_mul_comba("bn_mul_comba4",4);
-+&bn_sqr_comba("bn_sqr_comba8",8);
-+&bn_sqr_comba("bn_sqr_comba4",4);
-+
-+&asm_finish();
-+
-+close STDOUT;
-+
-+sub mul_add_c
-+	{
-+	local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
-+
-+	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
-+	# words, and 1 if load return value
-+
-+	&comment("mul a[$ai]*b[$bi]");
-+
-+	# "eax" and "edx" will always be pre-loaded.
-+	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
-+	# &mov("edx",&DWP($bi*4,$b,"",0));
-+
-+	&mul("edx");
-+	&add($c0,"eax");
-+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# laod next a
-+	 &mov("eax",&wparam(0)) if $pos > 0;			# load r[]
-+	 ###
-+	&adc($c1,"edx");
-+	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0;	# laod next b
-+	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1;	# laod next b
-+	 ###
-+	&adc($c2,0);
-+	 # is pos > 1, it means it is the last loop 
-+	 &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0;		# save r[];
-+	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# laod next a
-+	}
-+
-+sub sqr_add_c
-+	{
-+	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
-+
-+	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
-+	# words, and 1 if load return value
-+
-+	&comment("sqr a[$ai]*a[$bi]");
-+
-+	# "eax" and "edx" will always be pre-loaded.
-+	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
-+	# &mov("edx",&DWP($bi*4,$b,"",0));
-+
-+	if ($ai == $bi)
-+		{ &mul("eax");}
-+	else
-+		{ &mul("edx");}
-+	&add($c0,"eax");
-+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
-+	 ###
-+	&adc($c1,"edx");
-+	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
-+	 ###
-+	&adc($c2,0);
-+	 # is pos > 1, it means it is the last loop 
-+	 &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
-+	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# load next b
-+	}
-+
-+sub sqr_add_c2
-+	{
-+	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
-+
-+	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
-+	# words, and 1 if load return value
-+
-+	&comment("sqr a[$ai]*a[$bi]");
-+
-+	# "eax" and "edx" will always be pre-loaded.
-+	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
-+	# &mov("edx",&DWP($bi*4,$a,"",0));
-+
-+	if ($ai == $bi)
-+		{ &mul("eax");}
-+	else
-+		{ &mul("edx");}
-+	&add("eax","eax");
-+	 ###
-+	&adc("edx","edx");
-+	 ###
-+	&adc($c2,0);
-+	 &add($c0,"eax");
-+	&adc($c1,"edx");
-+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
-+	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;	# load next b
-+	&adc($c2,0);
-+	&mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
-+	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb);
-+	 ###
-+	}
-+
-+sub bn_mul_comba
-+	{
-+	local($name,$num)=@_;
-+	local($a,$b,$c0,$c1,$c2);
-+	local($i,$as,$ae,$bs,$be,$ai,$bi);
-+	local($tot,$end);
-+
-+	&function_begin_B($name,"");
-+
-+	$c0="ebx";
-+	$c1="ecx";
-+	$c2="ebp";
-+	$a="esi";
-+	$b="edi";
-+	
-+	$as=0;
-+	$ae=0;
-+	$bs=0;
-+	$be=0;
-+	$tot=$num+$num-1;
-+
-+	&push("esi");
-+	 &mov($a,&wparam(1));
-+	&push("edi");
-+	 &mov($b,&wparam(2));
-+	&push("ebp");
-+	 &push("ebx");
-+
-+	&xor($c0,$c0);
-+	 &mov("eax",&DWP(0,$a,"",0));	# load the first word 
-+	&xor($c1,$c1);
-+	 &mov("edx",&DWP(0,$b,"",0));	# load the first second 
-+
-+	for ($i=0; $i<$tot; $i++)
-+		{
-+		$ai=$as;
-+		$bi=$bs;
-+		$end=$be+1;
-+
-+		&comment("################## Calculate word $i"); 
-+
-+		for ($j=$bs; $j<$end; $j++)
-+			{
-+			&xor($c2,$c2) if ($j == $bs);
-+			if (($j+1) == $end)
-+				{
-+				$v=1;
-+				$v=2 if (($i+1) == $tot);
-+				}
-+			else
-+				{ $v=0; }
-+			if (($j+1) != $end)
-+				{
-+				$na=($ai-1);
-+				$nb=($bi+1);
-+				}
-+			else
-+				{
-+				$na=$as+($i < ($num-1));
-+				$nb=$bs+($i >= ($num-1));
-+				}
-+#printf STDERR "[$ai,$bi] -> [$na,$nb]\n";
-+			&mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb);
-+			if ($v)
-+				{
-+				&comment("saved r[$i]");
-+				# &mov("eax",&wparam(0));
-+				# &mov(&DWP($i*4,"eax","",0),$c0);
-+				($c0,$c1,$c2)=($c1,$c2,$c0);
-+				}
-+			$ai--;
-+			$bi++;
-+			}
-+		$as++ if ($i < ($num-1));
-+		$ae++ if ($i >= ($num-1));
-+
-+		$bs++ if ($i >= ($num-1));
-+		$be++ if ($i < ($num-1));
-+		}
-+	&comment("save r[$i]");
-+	# &mov("eax",&wparam(0));
-+	&mov(&DWP($i*4,"eax","",0),$c0);
-+
-+	&pop("ebx");
-+	&pop("ebp");
-+	&pop("edi");
-+	&pop("esi");
-+	&ret();
-+	&function_end_B($name);
-+	}
-+
-+sub bn_sqr_comba
-+	{
-+	local($name,$num)=@_;
-+	local($r,$a,$c0,$c1,$c2)=@_;
-+	local($i,$as,$ae,$bs,$be,$ai,$bi);
-+	local($b,$tot,$end,$half);
-+
-+	&function_begin_B($name,"");
-+
-+	$c0="ebx";
-+	$c1="ecx";
-+	$c2="ebp";
-+	$a="esi";
-+	$r="edi";
-+
-+	&push("esi");
-+	 &push("edi");
-+	&push("ebp");
-+	 &push("ebx");
-+	&mov($r,&wparam(0));
-+	 &mov($a,&wparam(1));
-+	&xor($c0,$c0);
-+	 &xor($c1,$c1);
-+	&mov("eax",&DWP(0,$a,"",0)); # load the first word
-+
-+	$as=0;
-+	$ae=0;
-+	$bs=0;
-+	$be=0;
-+	$tot=$num+$num-1;
-+
-+	for ($i=0; $i<$tot; $i++)
-+		{
-+		$ai=$as;
-+		$bi=$bs;
-+		$end=$be+1;
-+
-+		&comment("############### Calculate word $i");
-+		for ($j=$bs; $j<$end; $j++)
-+			{
-+			&xor($c2,$c2) if ($j == $bs);
-+			if (($ai-1) < ($bi+1))
-+				{
-+				$v=1;
-+				$v=2 if ($i+1) == $tot;
-+				}
-+			else
-+				{ $v=0; }
-+			if (!$v)
-+				{
-+				$na=$ai-1;
-+				$nb=$bi+1;
-+				}
-+			else
-+				{
-+				$na=$as+($i < ($num-1));
-+				$nb=$bs+($i >= ($num-1));
-+				}
-+			if ($ai == $bi)
-+				{
-+				&sqr_add_c($r,$a,$ai,$bi,
-+					$c0,$c1,$c2,$v,$i,$na,$nb);
-+				}
-+			else
-+				{
-+				&sqr_add_c2($r,$a,$ai,$bi,
-+					$c0,$c1,$c2,$v,$i,$na,$nb);
-+				}
-+			if ($v)
-+				{
-+				&comment("saved r[$i]");
-+				#&mov(&DWP($i*4,$r,"",0),$c0);
-+				($c0,$c1,$c2)=($c1,$c2,$c0);
-+				last;
-+				}
-+			$ai--;
-+			$bi++;
-+			}
-+		$as++ if ($i < ($num-1));
-+		$ae++ if ($i >= ($num-1));
-+
-+		$bs++ if ($i >= ($num-1));
-+		$be++ if ($i < ($num-1));
-+		}
-+	&mov(&DWP($i*4,$r,"",0),$c0);
-+	&pop("ebx");
-+	&pop("ebp");
-+	&pop("edi");
-+	&pop("esi");
-+	&ret();
-+	&function_end_B($name);
-+	}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ia64-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ia64-mont.pl
-new file mode 100644
-index 0000000..5cc5c59
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ia64-mont.pl
-@@ -0,0 +1,860 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# January 2010
-+#
-+# "Teaser" Montgomery multiplication module for IA-64. There are
-+# several possibilities for improvement:
-+#
-+# - modulo-scheduling outer loop would eliminate quite a number of
-+#   stalls after ldf8, xma and getf.sig outside inner loop and
-+#   improve shorter key performance;
-+# - shorter vector support [with input vectors being fetched only
-+#   once] should be added;
-+# - 2x unroll with help of n0[1] would make the code scalable on
-+#   "wider" IA-64, "wider" than Itanium 2 that is, which is not of
-+#   acute interest, because upcoming Tukwila's individual cores are
-+#   reportedly based on Itanium 2 design;
-+# - dedicated squaring procedure(?);
-+#
-+# January 2010
-+#
-+# Shorter vector support is implemented by zero-padding ap and np
-+# vectors up to 8 elements, or 512 bits. This means that 256-bit
-+# inputs will be processed only 2 times faster than 512-bit inputs,
-+# not 4 [as one would expect, because algorithm complexity is n^2].
-+# The reason for padding is that inputs shorter than 512 bits won't
-+# be processed faster anyway, because minimal critical path of the
-+# core loop happens to match 512-bit timing. Either way, it resulted
-+# in >100% improvement of 512-bit RSA sign benchmark and 50% - of
-+# 1024-bit one [in comparison to original version of *this* module].
-+#
-+# So far 'openssl speed rsa dsa' output on 900MHz Itanium 2 *with*
-+# this module is:
-+#                   sign    verify    sign/s verify/s
-+# rsa  512 bits 0.000290s 0.000024s   3452.8  42031.4
-+# rsa 1024 bits 0.000793s 0.000058s   1261.7  17172.0
-+# rsa 2048 bits 0.005908s 0.000148s    169.3   6754.0
-+# rsa 4096 bits 0.033456s 0.000469s     29.9   2133.6
-+# dsa  512 bits 0.000253s 0.000198s   3949.9   5057.0
-+# dsa 1024 bits 0.000585s 0.000607s   1708.4   1647.4
-+# dsa 2048 bits 0.001453s 0.001703s    688.1    587.4
-+#
-+# ... and *without* (but still with ia64.S):
-+#
-+# rsa  512 bits 0.000670s 0.000041s   1491.8  24145.5
-+# rsa 1024 bits 0.001988s 0.000080s    502.9  12499.3
-+# rsa 2048 bits 0.008702s 0.000189s    114.9   5293.9
-+# rsa 4096 bits 0.043860s 0.000533s     22.8   1875.9
-+# dsa  512 bits 0.000441s 0.000427s   2265.3   2340.6
-+# dsa 1024 bits 0.000823s 0.000867s   1215.6   1153.2
-+# dsa 2048 bits 0.001894s 0.002179s    528.1    458.9
-+#
-+# As it can be seen, RSA sign performance improves by 130-30%,
-+# hereafter less for longer keys, while verify - by 74-13%.
-+# DSA performance improves by 115-30%.
-+
-+$output=pop;
-+
-+if ($^O eq "hpux") {
-+    $ADDP="addp4";
-+    for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
-+} else { $ADDP="add"; }
-+
-+$code=<<___;
-+.explicit
-+.text
-+
-+// int bn_mul_mont (BN_ULONG *rp,const BN_ULONG *ap,
-+//		    const BN_ULONG *bp,const BN_ULONG *np,
-+//		    const BN_ULONG *n0p,int num);			
-+.align	64
-+.global	bn_mul_mont#
-+.proc	bn_mul_mont#
-+bn_mul_mont:
-+	.prologue
-+	.body
-+{ .mmi;	cmp4.le		p6,p7=2,r37;;
-+(p6)	cmp4.lt.unc	p8,p9=8,r37
-+	mov		ret0=r0		};;
-+{ .bbb;
-+(p9)	br.cond.dptk.many	bn_mul_mont_8
-+(p8)	br.cond.dpnt.many	bn_mul_mont_general
-+(p7)	br.ret.spnt.many	b0	};;
-+.endp	bn_mul_mont#
-+
-+prevfs=r2;	prevpr=r3;	prevlc=r10;	prevsp=r11;
-+
-+rptr=r8;	aptr=r9;	bptr=r14;	nptr=r15;
-+tptr=r16;	// &tp[0]
-+tp_1=r17;	// &tp[-1]
-+num=r18;	len=r19;	lc=r20;
-+topbit=r21;	// carry bit from tmp[num]
-+
-+n0=f6;
-+m0=f7;
-+bi=f8;
-+
-+.align	64
-+.local	bn_mul_mont_general#
-+.proc	bn_mul_mont_general#
-+bn_mul_mont_general:
-+	.prologue
-+{ .mmi;	.save	ar.pfs,prevfs
-+	alloc	prevfs=ar.pfs,6,2,0,8
-+	$ADDP	aptr=0,in1
-+	.save	ar.lc,prevlc
-+	mov	prevlc=ar.lc		}
-+{ .mmi;	.vframe	prevsp
-+	mov	prevsp=sp
-+	$ADDP	bptr=0,in2
-+	.save	pr,prevpr
-+	mov	prevpr=pr		};;
-+
-+	.body
-+	.rotf		alo[6],nlo[4],ahi[8],nhi[6]
-+	.rotr		a[3],n[3],t[2]
-+
-+{ .mmi;	ldf8		bi=[bptr],8		// (*bp++)
-+	ldf8		alo[4]=[aptr],16	// ap[0]
-+	$ADDP		r30=8,in1	};;
-+{ .mmi;	ldf8		alo[3]=[r30],16		// ap[1]
-+	ldf8		alo[2]=[aptr],16	// ap[2]
-+	$ADDP		in4=0,in4	};;
-+{ .mmi;	ldf8		alo[1]=[r30]		// ap[3]
-+	ldf8		n0=[in4]		// n0
-+	$ADDP		rptr=0,in0		}
-+{ .mmi;	$ADDP		nptr=0,in3
-+	mov		r31=16
-+	zxt4		num=in5		};;
-+{ .mmi;	ldf8		nlo[2]=[nptr],8		// np[0]
-+	shladd		len=num,3,r0
-+	shladd		r31=num,3,r31	};;
-+{ .mmi;	ldf8		nlo[1]=[nptr],8		// np[1]
-+	add		lc=-5,num
-+	sub		r31=sp,r31	};;
-+{ .mfb;	and		sp=-16,r31		// alloca
-+	xmpy.hu		ahi[2]=alo[4],bi	// ap[0]*bp[0]
-+	nop.b		0		}
-+{ .mfb;	nop.m		0
-+	xmpy.lu		alo[4]=alo[4],bi
-+	brp.loop.imp	.L1st_ctop,.L1st_cend-16
-+					};;
-+{ .mfi;	nop.m		0
-+	xma.hu		ahi[1]=alo[3],bi,ahi[2]	// ap[1]*bp[0]
-+	add		tp_1=8,sp	}
-+{ .mfi;	nop.m		0
-+	xma.lu		alo[3]=alo[3],bi,ahi[2]
-+	mov		pr.rot=0x20001f<<16
-+			// ------^----- (p40) at first (p23)
-+			// ----------^^ p[16:20]=1
-+					};;
-+{ .mfi;	nop.m		0
-+	xmpy.lu		m0=alo[4],n0		// (ap[0]*bp[0])*n0
-+	mov		ar.lc=lc	}
-+{ .mfi;	nop.m		0
-+	fcvt.fxu.s1	nhi[1]=f0
-+	mov		ar.ec=8		};;
-+
-+.align	32
-+.L1st_ctop:
-+.pred.rel	"mutex",p40,p42
-+{ .mfi;	(p16)	ldf8		alo[0]=[aptr],8		    // *(aptr++)
-+	(p18)	xma.hu		ahi[0]=alo[2],bi,ahi[1]
-+	(p40)	add		n[2]=n[2],a[2]		}   // (p23)					}
-+{ .mfi;	(p18)	ldf8		nlo[0]=[nptr],8		    // *(nptr++)(p16)
-+	(p18)	xma.lu		alo[2]=alo[2],bi,ahi[1]
-+	(p42)	add		n[2]=n[2],a[2],1	};; // (p23)
-+{ .mfi;	(p21)	getf.sig	a[0]=alo[5]
-+	(p20)	xma.hu		nhi[0]=nlo[2],m0,nhi[1]
-+	(p42)	cmp.leu		p41,p39=n[2],a[2]   	}   // (p23)
-+{ .mfi;	(p23)	st8		[tp_1]=n[2],8
-+	(p20)	xma.lu		nlo[2]=nlo[2],m0,nhi[1]
-+	(p40)	cmp.ltu		p41,p39=n[2],a[2]	}   // (p23)
-+{ .mmb;	(p21)	getf.sig	n[0]=nlo[3]
-+	(p16)	nop.m		0
-+	br.ctop.sptk	.L1st_ctop			};;
-+.L1st_cend:
-+
-+{ .mmi;	getf.sig	a[0]=ahi[6]		// (p24)
-+	getf.sig	n[0]=nhi[4]
-+	add		num=-1,num	};;	// num--
-+{ .mmi;	.pred.rel	"mutex",p40,p42
-+(p40)	add		n[0]=n[0],a[0]
-+(p42)	add		n[0]=n[0],a[0],1
-+	sub		aptr=aptr,len	};;	// rewind
-+{ .mmi;	.pred.rel	"mutex",p40,p42
-+(p40)	cmp.ltu		p41,p39=n[0],a[0]
-+(p42)	cmp.leu		p41,p39=n[0],a[0]
-+	sub		nptr=nptr,len	};;
-+{ .mmi;	.pred.rel	"mutex",p39,p41
-+(p39)	add		topbit=r0,r0
-+(p41)	add		topbit=r0,r0,1
-+	nop.i		0		}	
-+{ .mmi;	st8		[tp_1]=n[0]
-+	add		tptr=16,sp
-+	add		tp_1=8,sp	};;
-+
-+.Louter:
-+{ .mmi;	ldf8		bi=[bptr],8		// (*bp++)
-+	ldf8		ahi[3]=[tptr]		// tp[0]
-+	add		r30=8,aptr	};;
-+{ .mmi;	ldf8		alo[4]=[aptr],16	// ap[0]
-+	ldf8		alo[3]=[r30],16		// ap[1]
-+	add		r31=8,nptr	};;
-+{ .mfb;	ldf8		alo[2]=[aptr],16	// ap[2]
-+	xma.hu		ahi[2]=alo[4],bi,ahi[3]	// ap[0]*bp[i]+tp[0]
-+	brp.loop.imp	.Linner_ctop,.Linner_cend-16
-+					}
-+{ .mfb;	ldf8		alo[1]=[r30]		// ap[3]
-+	xma.lu		alo[4]=alo[4],bi,ahi[3]
-+	clrrrb.pr			};;
-+{ .mfi;	ldf8		nlo[2]=[nptr],16	// np[0]
-+	xma.hu		ahi[1]=alo[3],bi,ahi[2]	// ap[1]*bp[i]
-+	nop.i		0		}
-+{ .mfi;	ldf8		nlo[1]=[r31]		// np[1]
-+	xma.lu		alo[3]=alo[3],bi,ahi[2]
-+	mov		pr.rot=0x20101f<<16
-+			// ------^----- (p40) at first (p23)
-+			// --------^--- (p30) at first (p22)
-+			// ----------^^ p[16:20]=1
-+					};;
-+{ .mfi;	st8		[tptr]=r0		// tp[0] is already accounted
-+	xmpy.lu		m0=alo[4],n0		// (ap[0]*bp[i]+tp[0])*n0
-+	mov		ar.lc=lc	}
-+{ .mfi;
-+	fcvt.fxu.s1	nhi[1]=f0
-+	mov		ar.ec=8		};;
-+
-+// This loop spins in 4*(n+7) ticks on Itanium 2 and should spin in
-+// 7*(n+7) ticks on Itanium (the one codenamed Merced). Factor of 7
-+// in latter case accounts for two-tick pipeline stall, which means
-+// that its performance would be ~20% lower than optimal one. No
-+// attempt was made to address this, because original Itanium is
-+// hardly represented out in the wild...
-+.align	32
-+.Linner_ctop:
-+.pred.rel	"mutex",p40,p42
-+.pred.rel	"mutex",p30,p32
-+{ .mfi;	(p16)	ldf8		alo[0]=[aptr],8		    // *(aptr++)
-+	(p18)	xma.hu		ahi[0]=alo[2],bi,ahi[1]
-+	(p40)	add		n[2]=n[2],a[2]		}   // (p23)
-+{ .mfi;	(p16)	nop.m		0
-+	(p18)	xma.lu		alo[2]=alo[2],bi,ahi[1]
-+	(p42)	add		n[2]=n[2],a[2],1	};; // (p23)
-+{ .mfi;	(p21)	getf.sig	a[0]=alo[5]
-+	(p16)	nop.f		0
-+	(p40)	cmp.ltu		p41,p39=n[2],a[2]	}   // (p23)
-+{ .mfi;	(p21)	ld8		t[0]=[tptr],8
-+	(p16)	nop.f		0
-+	(p42)	cmp.leu		p41,p39=n[2],a[2]	};; // (p23)
-+{ .mfi;	(p18)	ldf8		nlo[0]=[nptr],8		    // *(nptr++)
-+	(p20)	xma.hu		nhi[0]=nlo[2],m0,nhi[1]
-+	(p30)	add		a[1]=a[1],t[1]		}   // (p22)
-+{ .mfi;	(p16)	nop.m		0
-+	(p20)	xma.lu		nlo[2]=nlo[2],m0,nhi[1]
-+	(p32)	add		a[1]=a[1],t[1],1	};; // (p22)
-+{ .mmi;	(p21)	getf.sig	n[0]=nlo[3]
-+	(p16)	nop.m		0
-+	(p30)	cmp.ltu		p31,p29=a[1],t[1]	}   // (p22)
-+{ .mmb;	(p23)	st8		[tp_1]=n[2],8
-+	(p32)	cmp.leu		p31,p29=a[1],t[1]	    // (p22)
-+	br.ctop.sptk	.Linner_ctop			};;
-+.Linner_cend:
-+
-+{ .mmi;	getf.sig	a[0]=ahi[6]		// (p24)
-+	getf.sig	n[0]=nhi[4]
-+	nop.i		0		};;
-+
-+{ .mmi;	.pred.rel	"mutex",p31,p33
-+(p31)	add		a[0]=a[0],topbit
-+(p33)	add		a[0]=a[0],topbit,1
-+	mov		topbit=r0	};;
-+{ .mfi; .pred.rel	"mutex",p31,p33
-+(p31)	cmp.ltu		p32,p30=a[0],topbit
-+(p33)	cmp.leu		p32,p30=a[0],topbit
-+					}
-+{ .mfi;	.pred.rel	"mutex",p40,p42
-+(p40)	add		n[0]=n[0],a[0]
-+(p42)	add		n[0]=n[0],a[0],1
-+					};;
-+{ .mmi;	.pred.rel	"mutex",p44,p46
-+(p40)	cmp.ltu		p41,p39=n[0],a[0]
-+(p42)	cmp.leu		p41,p39=n[0],a[0]
-+(p32)	add		topbit=r0,r0,1	}
-+
-+{ .mmi;	st8		[tp_1]=n[0],8
-+	cmp4.ne		p6,p0=1,num
-+	sub		aptr=aptr,len	};;	// rewind
-+{ .mmi;	sub		nptr=nptr,len
-+(p41)	add		topbit=r0,r0,1
-+	add		tptr=16,sp	}
-+{ .mmb;	add		tp_1=8,sp
-+	add		num=-1,num		// num--
-+(p6)	br.cond.sptk.many	.Louter	};;
-+
-+{ .mbb;	add		lc=4,lc
-+	brp.loop.imp	.Lsub_ctop,.Lsub_cend-16
-+	clrrrb.pr			};;
-+{ .mii;	nop.m		0
-+	mov		pr.rot=0x10001<<16
-+			// ------^---- (p33) at first (p17)
-+	mov		ar.lc=lc	}
-+{ .mii;	nop.m		0
-+	mov		ar.ec=3
-+	nop.i		0		};;
-+
-+.Lsub_ctop:
-+.pred.rel	"mutex",p33,p35
-+{ .mfi;	(p16)	ld8		t[0]=[tptr],8		    // t=*(tp++)
-+	(p16)	nop.f		0
-+	(p33)	sub		n[1]=t[1],n[1]		}   // (p17)
-+{ .mfi;	(p16)	ld8		n[0]=[nptr],8		    // n=*(np++)
-+	(p16)	nop.f		0
-+	(p35)	sub		n[1]=t[1],n[1],1	};; // (p17)
-+{ .mib;	(p18)	st8		[rptr]=n[2],8		    // *(rp++)=r
-+	(p33)	cmp.gtu		p34,p32=n[1],t[1]	    // (p17)
-+	(p18)	nop.b		0			}
-+{ .mib;	(p18)	nop.m		0
-+	(p35)	cmp.geu		p34,p32=n[1],t[1]	    // (p17)
-+	br.ctop.sptk	.Lsub_ctop			};;
-+.Lsub_cend:
-+
-+{ .mmb;	.pred.rel	"mutex",p34,p36
-+(p34)	sub	topbit=topbit,r0	// (p19)
-+(p36)	sub	topbit=topbit,r0,1
-+	brp.loop.imp	.Lcopy_ctop,.Lcopy_cend-16
-+					}
-+{ .mmb;	sub	rptr=rptr,len		// rewind
-+	sub	tptr=tptr,len
-+	clrrrb.pr			};;
-+{ .mmi;	and	aptr=tptr,topbit
-+	andcm	bptr=rptr,topbit
-+	mov	pr.rot=1<<16		};;
-+{ .mii;	or	nptr=aptr,bptr
-+	mov	ar.lc=lc
-+	mov	ar.ec=3			};;
-+
-+.Lcopy_ctop:
-+{ .mmb;	(p16)	ld8	n[0]=[nptr],8
-+	(p18)	st8	[tptr]=r0,8
-+	(p16)	nop.b	0		}
-+{ .mmb;	(p16)	nop.m	0
-+	(p18)	st8	[rptr]=n[2],8
-+	br.ctop.sptk	.Lcopy_ctop	};;
-+.Lcopy_cend:
-+
-+{ .mmi;	mov		ret0=1			// signal "handled"
-+	rum		1<<5			// clear um.mfh
-+	mov		ar.lc=prevlc	}
-+{ .mib;	.restore	sp
-+	mov		sp=prevsp
-+	mov		pr=prevpr,0x1ffff
-+	br.ret.sptk.many	b0	};;
-+.endp	bn_mul_mont_general#
-+
-+a1=r16;  a2=r17;  a3=r18;  a4=r19;  a5=r20;  a6=r21;  a7=r22;  a8=r23;
-+n1=r24;  n2=r25;  n3=r26;  n4=r27;  n5=r28;  n6=r29;  n7=r30;  n8=r31;
-+t0=r15;
-+
-+ai0=f8;  ai1=f9;  ai2=f10; ai3=f11; ai4=f12; ai5=f13; ai6=f14; ai7=f15;
-+ni0=f16; ni1=f17; ni2=f18; ni3=f19; ni4=f20; ni5=f21; ni6=f22; ni7=f23;
-+
-+.align	64
-+.skip	48		// aligns loop body
-+.local	bn_mul_mont_8#
-+.proc	bn_mul_mont_8#
-+bn_mul_mont_8:
-+	.prologue
-+{ .mmi;	.save		ar.pfs,prevfs
-+	alloc		prevfs=ar.pfs,6,2,0,8
-+	.vframe		prevsp
-+	mov		prevsp=sp
-+	.save		ar.lc,prevlc
-+	mov		prevlc=ar.lc	}
-+{ .mmi;	add		r17=-6*16,sp
-+	add		sp=-7*16,sp
-+	.save		pr,prevpr
-+	mov		prevpr=pr	};;
-+
-+{ .mmi;	.save.gf	0,0x10
-+	stf.spill	[sp]=f16,-16
-+	.save.gf	0,0x20
-+	stf.spill	[r17]=f17,32
-+	add		r16=-5*16,prevsp};;
-+{ .mmi;	.save.gf	0,0x40
-+	stf.spill	[r16]=f18,32
-+	.save.gf	0,0x80
-+	stf.spill	[r17]=f19,32
-+	$ADDP		aptr=0,in1	};;
-+{ .mmi;	.save.gf	0,0x100
-+	stf.spill	[r16]=f20,32
-+	.save.gf	0,0x200
-+	stf.spill	[r17]=f21,32
-+	$ADDP		r29=8,in1	};;
-+{ .mmi;	.save.gf	0,0x400
-+	stf.spill	[r16]=f22
-+	.save.gf	0,0x800
-+	stf.spill	[r17]=f23
-+	$ADDP		rptr=0,in0	};;
-+
-+	.body
-+	.rotf		bj[8],mj[2],tf[2],alo[10],ahi[10],nlo[10],nhi[10]
-+	.rotr		t[8]
-+
-+// load input vectors padding them to 8 elements
-+{ .mmi;	ldf8		ai0=[aptr],16		// ap[0]
-+	ldf8		ai1=[r29],16		// ap[1]
-+	$ADDP		bptr=0,in2	}
-+{ .mmi;	$ADDP		r30=8,in2
-+	$ADDP		nptr=0,in3
-+	$ADDP		r31=8,in3	};;
-+{ .mmi;	ldf8		bj[7]=[bptr],16		// bp[0]
-+	ldf8		bj[6]=[r30],16		// bp[1]
-+	cmp4.le		p4,p5=3,in5	}
-+{ .mmi;	ldf8		ni0=[nptr],16		// np[0]
-+	ldf8		ni1=[r31],16		// np[1]
-+	cmp4.le		p6,p7=4,in5	};;
-+
-+{ .mfi;	(p4)ldf8	ai2=[aptr],16		// ap[2]
-+	(p5)fcvt.fxu	ai2=f0
-+	cmp4.le		p8,p9=5,in5	}
-+{ .mfi;	(p6)ldf8	ai3=[r29],16		// ap[3]
-+	(p7)fcvt.fxu	ai3=f0
-+	cmp4.le		p10,p11=6,in5	}
-+{ .mfi;	(p4)ldf8	bj[5]=[bptr],16		// bp[2]
-+	(p5)fcvt.fxu	bj[5]=f0
-+	cmp4.le		p12,p13=7,in5	}
-+{ .mfi;	(p6)ldf8	bj[4]=[r30],16		// bp[3]
-+	(p7)fcvt.fxu	bj[4]=f0
-+	cmp4.le		p14,p15=8,in5	}
-+{ .mfi;	(p4)ldf8	ni2=[nptr],16		// np[2]
-+	(p5)fcvt.fxu	ni2=f0
-+	addp4		r28=-1,in5	}
-+{ .mfi;	(p6)ldf8	ni3=[r31],16		// np[3]
-+	(p7)fcvt.fxu	ni3=f0
-+	$ADDP		in4=0,in4	};;
-+
-+{ .mfi;	ldf8		n0=[in4]
-+	fcvt.fxu	tf[1]=f0
-+	nop.i		0		}
-+
-+{ .mfi;	(p8)ldf8	ai4=[aptr],16		// ap[4]
-+	(p9)fcvt.fxu	ai4=f0
-+	mov		t[0]=r0		}
-+{ .mfi;	(p10)ldf8	ai5=[r29],16		// ap[5]
-+	(p11)fcvt.fxu	ai5=f0
-+	mov		t[1]=r0		}
-+{ .mfi;	(p8)ldf8	bj[3]=[bptr],16		// bp[4]
-+	(p9)fcvt.fxu	bj[3]=f0
-+	mov		t[2]=r0		}
-+{ .mfi;	(p10)ldf8	bj[2]=[r30],16		// bp[5]
-+	(p11)fcvt.fxu	bj[2]=f0
-+	mov		t[3]=r0		}
-+{ .mfi;	(p8)ldf8	ni4=[nptr],16		// np[4]
-+	(p9)fcvt.fxu	ni4=f0
-+	mov		t[4]=r0		}
-+{ .mfi;	(p10)ldf8	ni5=[r31],16		// np[5]
-+	(p11)fcvt.fxu	ni5=f0
-+	mov		t[5]=r0		};;
-+
-+{ .mfi;	(p12)ldf8	ai6=[aptr],16		// ap[6]
-+	(p13)fcvt.fxu	ai6=f0
-+	mov		t[6]=r0		}
-+{ .mfi;	(p14)ldf8	ai7=[r29],16		// ap[7]
-+	(p15)fcvt.fxu	ai7=f0
-+	mov		t[7]=r0		}
-+{ .mfi;	(p12)ldf8	bj[1]=[bptr],16		// bp[6]
-+	(p13)fcvt.fxu	bj[1]=f0
-+	mov		ar.lc=r28	}
-+{ .mfi;	(p14)ldf8	bj[0]=[r30],16		// bp[7]
-+	(p15)fcvt.fxu	bj[0]=f0
-+	mov		ar.ec=1		}
-+{ .mfi;	(p12)ldf8	ni6=[nptr],16		// np[6]
-+	(p13)fcvt.fxu	ni6=f0
-+	mov		pr.rot=1<<16	}
-+{ .mfb;	(p14)ldf8	ni7=[r31],16		// np[7]
-+	(p15)fcvt.fxu	ni7=f0
-+	brp.loop.imp	.Louter_8_ctop,.Louter_8_cend-16
-+					};;
-+
-+// The loop is scheduled for 32*n ticks on Itanium 2. Actual attempt
-+// to measure with help of Interval Time Counter indicated that the
-+// factor is a tad higher: 33 or 34, if not 35. Exact measurement and
-+// addressing the issue is problematic, because I don't have access
-+// to platform-specific instruction-level profiler. On Itanium it
-+// should run in 56*n ticks, because of higher xma latency...
-+.Louter_8_ctop:
-+	.pred.rel		"mutex",p40,p42
-+	.pred.rel		"mutex",p48,p50
-+{ .mfi;	(p16)	nop.m		0			// 0:
-+	(p16)	xma.hu		ahi[0]=ai0,bj[7],tf[1]	//	ap[0]*b[i]+t[0]
-+	(p40)	add		a3=a3,n3	}	//	(p17) a3+=n3
-+{ .mfi;	(p42)	add		a3=a3,n3,1
-+	(p16)	xma.lu		alo[0]=ai0,bj[7],tf[1]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p17)	getf.sig	a7=alo[8]		// 1:
-+	(p48)	add		t[6]=t[6],a3		//	(p17) t[6]+=a3
-+	(p50)	add		t[6]=t[6],a3,1	};;
-+{ .mfi;	(p17)	getf.sig	a8=ahi[8]		// 2:
-+	(p17)	xma.hu		nhi[7]=ni6,mj[1],nhi[6]	//	np[6]*m0
-+	(p40)	cmp.ltu		p43,p41=a3,n3	}
-+{ .mfi;	(p42)	cmp.leu		p43,p41=a3,n3
-+	(p17)	xma.lu		nlo[7]=ni6,mj[1],nhi[6]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p17)	getf.sig	n5=nlo[6]		// 3:
-+	(p48)	cmp.ltu		p51,p49=t[6],a3
-+	(p50)	cmp.leu		p51,p49=t[6],a3	};;
-+	.pred.rel		"mutex",p41,p43
-+	.pred.rel		"mutex",p49,p51
-+{ .mfi;	(p16)	nop.m		0			// 4:
-+	(p16)	xma.hu		ahi[1]=ai1,bj[7],ahi[0]	//	ap[1]*b[i]
-+	(p41)	add		a4=a4,n4	}	//	(p17) a4+=n4
-+{ .mfi;	(p43)	add		a4=a4,n4,1
-+	(p16)	xma.lu		alo[1]=ai1,bj[7],ahi[0]
-+	(p16)	nop.i		0		};;
-+{ .mfi;	(p49)	add		t[5]=t[5],a4		// 5:	(p17) t[5]+=a4
-+	(p16)	xmpy.lu		mj[0]=alo[0],n0		//	(ap[0]*b[i]+t[0])*n0
-+	(p51)	add		t[5]=t[5],a4,1	};;
-+{ .mfi;	(p16)	nop.m		0			// 6:
-+	(p17)	xma.hu		nhi[8]=ni7,mj[1],nhi[7]	//	np[7]*m0
-+	(p41)	cmp.ltu		p42,p40=a4,n4	}
-+{ .mfi;	(p43)	cmp.leu		p42,p40=a4,n4
-+	(p17)	xma.lu		nlo[8]=ni7,mj[1],nhi[7]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p17)	getf.sig	n6=nlo[7]		// 7:
-+	(p49)	cmp.ltu		p50,p48=t[5],a4
-+	(p51)	cmp.leu		p50,p48=t[5],a4	};;
-+	.pred.rel		"mutex",p40,p42
-+	.pred.rel		"mutex",p48,p50
-+{ .mfi;	(p16)	nop.m		0			// 8:
-+	(p16)	xma.hu		ahi[2]=ai2,bj[7],ahi[1]	//	ap[2]*b[i]
-+	(p40)	add		a5=a5,n5	}	//	(p17) a5+=n5
-+{ .mfi;	(p42)	add		a5=a5,n5,1
-+	(p16)	xma.lu		alo[2]=ai2,bj[7],ahi[1]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p16)	getf.sig	a1=alo[1]		// 9:
-+	(p48)	add		t[4]=t[4],a5		//	p(17) t[4]+=a5
-+	(p50)	add		t[4]=t[4],a5,1	};;
-+{ .mfi;	(p16)	nop.m		0			// 10:
-+	(p16)	xma.hu		nhi[0]=ni0,mj[0],alo[0]	//	np[0]*m0
-+	(p40)	cmp.ltu		p43,p41=a5,n5	}
-+{ .mfi;	(p42)	cmp.leu		p43,p41=a5,n5
-+	(p16)	xma.lu		nlo[0]=ni0,mj[0],alo[0]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p17)	getf.sig	n7=nlo[8]		// 11:
-+	(p48)	cmp.ltu		p51,p49=t[4],a5
-+	(p50)	cmp.leu		p51,p49=t[4],a5	};;
-+	.pred.rel		"mutex",p41,p43
-+	.pred.rel		"mutex",p49,p51
-+{ .mfi;	(p17)	getf.sig	n8=nhi[8]		// 12:
-+	(p16)	xma.hu		ahi[3]=ai3,bj[7],ahi[2]	//	ap[3]*b[i]
-+	(p41)	add		a6=a6,n6	}	//	(p17) a6+=n6
-+{ .mfi;	(p43)	add		a6=a6,n6,1
-+	(p16)	xma.lu		alo[3]=ai3,bj[7],ahi[2]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p16)	getf.sig	a2=alo[2]		// 13:
-+	(p49)	add		t[3]=t[3],a6		//	(p17) t[3]+=a6
-+	(p51)	add		t[3]=t[3],a6,1	};;
-+{ .mfi;	(p16)	nop.m		0			// 14:
-+	(p16)	xma.hu		nhi[1]=ni1,mj[0],nhi[0]	//	np[1]*m0
-+	(p41)	cmp.ltu		p42,p40=a6,n6	}
-+{ .mfi;	(p43)	cmp.leu		p42,p40=a6,n6
-+	(p16)	xma.lu		nlo[1]=ni1,mj[0],nhi[0]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p16)	nop.m		0			// 15:
-+	(p49)	cmp.ltu		p50,p48=t[3],a6
-+	(p51)	cmp.leu		p50,p48=t[3],a6	};;
-+	.pred.rel		"mutex",p40,p42
-+	.pred.rel		"mutex",p48,p50
-+{ .mfi;	(p16)	nop.m		0			// 16:
-+	(p16)	xma.hu		ahi[4]=ai4,bj[7],ahi[3]	//	ap[4]*b[i]
-+	(p40)	add		a7=a7,n7	}	//	(p17) a7+=n7
-+{ .mfi;	(p42)	add		a7=a7,n7,1
-+	(p16)	xma.lu		alo[4]=ai4,bj[7],ahi[3]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p16)	getf.sig	a3=alo[3]		// 17:
-+	(p48)	add		t[2]=t[2],a7		//	(p17) t[2]+=a7
-+	(p50)	add		t[2]=t[2],a7,1	};;
-+{ .mfi;	(p16)	nop.m		0			// 18:
-+	(p16)	xma.hu		nhi[2]=ni2,mj[0],nhi[1]	//	np[2]*m0
-+	(p40)	cmp.ltu		p43,p41=a7,n7	}
-+{ .mfi;	(p42)	cmp.leu		p43,p41=a7,n7
-+	(p16)	xma.lu		nlo[2]=ni2,mj[0],nhi[1]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p16)	getf.sig	n1=nlo[1]		// 19:
-+	(p48)	cmp.ltu		p51,p49=t[2],a7
-+	(p50)	cmp.leu		p51,p49=t[2],a7	};;
-+	.pred.rel		"mutex",p41,p43
-+	.pred.rel		"mutex",p49,p51
-+{ .mfi;	(p16)	nop.m		0			// 20:
-+	(p16)	xma.hu		ahi[5]=ai5,bj[7],ahi[4]	//	ap[5]*b[i]
-+	(p41)	add		a8=a8,n8	}	//	(p17) a8+=n8
-+{ .mfi;	(p43)	add		a8=a8,n8,1
-+	(p16)	xma.lu		alo[5]=ai5,bj[7],ahi[4]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p16)	getf.sig	a4=alo[4]		// 21:
-+	(p49)	add		t[1]=t[1],a8		//	(p17) t[1]+=a8
-+	(p51)	add		t[1]=t[1],a8,1	};;
-+{ .mfi;	(p16)	nop.m		0			// 22:
-+	(p16)	xma.hu		nhi[3]=ni3,mj[0],nhi[2]	//	np[3]*m0
-+	(p41)	cmp.ltu		p42,p40=a8,n8	}
-+{ .mfi;	(p43)	cmp.leu		p42,p40=a8,n8
-+	(p16)	xma.lu		nlo[3]=ni3,mj[0],nhi[2]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p16)	getf.sig	n2=nlo[2]		// 23:
-+	(p49)	cmp.ltu		p50,p48=t[1],a8
-+	(p51)	cmp.leu		p50,p48=t[1],a8	};;
-+{ .mfi;	(p16)	nop.m		0			// 24:
-+	(p16)	xma.hu		ahi[6]=ai6,bj[7],ahi[5]	//	ap[6]*b[i]
-+	(p16)	add		a1=a1,n1	}	//	(p16) a1+=n1
-+{ .mfi;	(p16)	nop.m		0
-+	(p16)	xma.lu		alo[6]=ai6,bj[7],ahi[5]
-+	(p17)	mov		t[0]=r0		};;
-+{ .mii;	(p16)	getf.sig	a5=alo[5]		// 25:
-+	(p16)	add		t0=t[7],a1		//	(p16) t[7]+=a1
-+	(p42)	add		t[0]=t[0],r0,1	};;
-+{ .mfi;	(p16)	setf.sig	tf[0]=t0		// 26:
-+	(p16)	xma.hu		nhi[4]=ni4,mj[0],nhi[3]	//	np[4]*m0
-+	(p50)	add		t[0]=t[0],r0,1	}
-+{ .mfi;	(p16)	cmp.ltu.unc	p42,p40=a1,n1
-+	(p16)	xma.lu		nlo[4]=ni4,mj[0],nhi[3]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p16)	getf.sig	n3=nlo[3]		// 27:
-+	(p16)	cmp.ltu.unc	p50,p48=t0,a1
-+	(p16)	nop.i		0		};;
-+	.pred.rel		"mutex",p40,p42
-+	.pred.rel		"mutex",p48,p50
-+{ .mfi;	(p16)	nop.m		0			// 28:
-+	(p16)	xma.hu		ahi[7]=ai7,bj[7],ahi[6]	//	ap[7]*b[i]
-+	(p40)	add		a2=a2,n2	}	//	(p16) a2+=n2
-+{ .mfi;	(p42)	add		a2=a2,n2,1
-+	(p16)	xma.lu		alo[7]=ai7,bj[7],ahi[6]
-+	(p16)	nop.i		0		};;
-+{ .mii;	(p16)	getf.sig	a6=alo[6]		// 29:
-+	(p48)	add		t[6]=t[6],a2		//	(p16) t[6]+=a2
-+	(p50)	add		t[6]=t[6],a2,1	};;
-+{ .mfi;	(p16)	nop.m		0			// 30:
-+	(p16)	xma.hu		nhi[5]=ni5,mj[0],nhi[4]	//	np[5]*m0
-+	(p40)	cmp.ltu		p41,p39=a2,n2	}
-+{ .mfi;	(p42)	cmp.leu		p41,p39=a2,n2
-+	(p16)	xma.lu		nlo[5]=ni5,mj[0],nhi[4]
-+	(p16)	nop.i		0		};;
-+{ .mfi;	(p16)	getf.sig	n4=nlo[4]		// 31:
-+	(p16)	nop.f		0
-+	(p48)	cmp.ltu		p49,p47=t[6],a2	}
-+{ .mfb;	(p50)	cmp.leu		p49,p47=t[6],a2
-+	(p16)	nop.f		0
-+	br.ctop.sptk.many	.Louter_8_ctop	};;
-+.Louter_8_cend:
-+
-+// above loop has to execute one more time, without (p16), which is
-+// replaced with merged move of np[8] to GPR bank
-+	.pred.rel		"mutex",p40,p42
-+	.pred.rel		"mutex",p48,p50
-+{ .mmi;	(p0)	getf.sig	n1=ni0			// 0:
-+	(p40)	add		a3=a3,n3		//	(p17) a3+=n3
-+	(p42)	add		a3=a3,n3,1	};;
-+{ .mii;	(p17)	getf.sig	a7=alo[8]		// 1:
-+	(p48)	add		t[6]=t[6],a3		//	(p17) t[6]+=a3
-+	(p50)	add		t[6]=t[6],a3,1	};;
-+{ .mfi;	(p17)	getf.sig	a8=ahi[8]		// 2:
-+	(p17)	xma.hu		nhi[7]=ni6,mj[1],nhi[6]	//	np[6]*m0
-+	(p40)	cmp.ltu		p43,p41=a3,n3	}
-+{ .mfi;	(p42)	cmp.leu		p43,p41=a3,n3
-+	(p17)	xma.lu		nlo[7]=ni6,mj[1],nhi[6]
-+	(p0)	nop.i		0		};;
-+{ .mii;	(p17)	getf.sig	n5=nlo[6]		// 3:
-+	(p48)	cmp.ltu		p51,p49=t[6],a3
-+	(p50)	cmp.leu		p51,p49=t[6],a3	};;
-+	.pred.rel		"mutex",p41,p43
-+	.pred.rel		"mutex",p49,p51
-+{ .mmi;	(p0)	getf.sig	n2=ni1			// 4:
-+	(p41)	add		a4=a4,n4		//	(p17) a4+=n4
-+	(p43)	add		a4=a4,n4,1	};;
-+{ .mfi;	(p49)	add		t[5]=t[5],a4		// 5:	(p17) t[5]+=a4
-+	(p0)	nop.f		0
-+	(p51)	add		t[5]=t[5],a4,1	};;
-+{ .mfi;	(p0)	getf.sig	n3=ni2			// 6:
-+	(p17)	xma.hu		nhi[8]=ni7,mj[1],nhi[7]	//	np[7]*m0
-+	(p41)	cmp.ltu		p42,p40=a4,n4	}
-+{ .mfi;	(p43)	cmp.leu		p42,p40=a4,n4
-+	(p17)	xma.lu		nlo[8]=ni7,mj[1],nhi[7]
-+	(p0)	nop.i		0		};;
-+{ .mii;	(p17)	getf.sig	n6=nlo[7]		// 7:
-+	(p49)	cmp.ltu		p50,p48=t[5],a4
-+	(p51)	cmp.leu		p50,p48=t[5],a4	};;
-+	.pred.rel		"mutex",p40,p42
-+	.pred.rel		"mutex",p48,p50
-+{ .mii;	(p0)	getf.sig	n4=ni3			// 8:
-+	(p40)	add		a5=a5,n5		//	(p17) a5+=n5
-+	(p42)	add		a5=a5,n5,1	};;
-+{ .mii;	(p0)	nop.m		0			// 9:
-+	(p48)	add		t[4]=t[4],a5		//	p(17) t[4]+=a5
-+	(p50)	add		t[4]=t[4],a5,1	};;
-+{ .mii;	(p0)	nop.m		0			// 10:
-+	(p40)	cmp.ltu		p43,p41=a5,n5
-+	(p42)	cmp.leu		p43,p41=a5,n5	};;
-+{ .mii;	(p17)	getf.sig	n7=nlo[8]		// 11:
-+	(p48)	cmp.ltu		p51,p49=t[4],a5
-+	(p50)	cmp.leu		p51,p49=t[4],a5	};;
-+	.pred.rel		"mutex",p41,p43
-+	.pred.rel		"mutex",p49,p51
-+{ .mii;	(p17)	getf.sig	n8=nhi[8]		// 12:
-+	(p41)	add		a6=a6,n6		//	(p17) a6+=n6
-+	(p43)	add		a6=a6,n6,1	};;
-+{ .mii;	(p0)	getf.sig	n5=ni4			// 13:
-+	(p49)	add		t[3]=t[3],a6		//	(p17) t[3]+=a6
-+	(p51)	add		t[3]=t[3],a6,1	};;
-+{ .mii;	(p0)	nop.m		0			// 14:
-+	(p41)	cmp.ltu		p42,p40=a6,n6
-+	(p43)	cmp.leu		p42,p40=a6,n6	};;
-+{ .mii;	(p0)	getf.sig	n6=ni5			// 15:
-+	(p49)	cmp.ltu		p50,p48=t[3],a6
-+	(p51)	cmp.leu		p50,p48=t[3],a6	};;
-+	.pred.rel		"mutex",p40,p42
-+	.pred.rel		"mutex",p48,p50
-+{ .mii;	(p0)	nop.m		0			// 16:
-+	(p40)	add		a7=a7,n7		//	(p17) a7+=n7
-+	(p42)	add		a7=a7,n7,1	};;
-+{ .mii;	(p0)	nop.m		0			// 17:
-+	(p48)	add		t[2]=t[2],a7		//	(p17) t[2]+=a7
-+	(p50)	add		t[2]=t[2],a7,1	};;
-+{ .mii;	(p0)	nop.m		0			// 18:
-+	(p40)	cmp.ltu		p43,p41=a7,n7
-+	(p42)	cmp.leu		p43,p41=a7,n7	};;
-+{ .mii;	(p0)	getf.sig	n7=ni6			// 19:
-+	(p48)	cmp.ltu		p51,p49=t[2],a7
-+	(p50)	cmp.leu		p51,p49=t[2],a7	};;
-+	.pred.rel		"mutex",p41,p43
-+	.pred.rel		"mutex",p49,p51
-+{ .mii;	(p0)	nop.m		0			// 20:
-+	(p41)	add		a8=a8,n8		//	(p17) a8+=n8
-+	(p43)	add		a8=a8,n8,1	};;
-+{ .mmi;	(p0)	nop.m		0			// 21:
-+	(p49)	add		t[1]=t[1],a8		//	(p17) t[1]+=a8
-+	(p51)	add		t[1]=t[1],a8,1	}
-+{ .mmi;	(p17)	mov		t[0]=r0
-+	(p41)	cmp.ltu		p42,p40=a8,n8
-+	(p43)	cmp.leu		p42,p40=a8,n8	};;
-+{ .mmi;	(p0)	getf.sig	n8=ni7			// 22:
-+	(p49)	cmp.ltu		p50,p48=t[1],a8
-+	(p51)	cmp.leu		p50,p48=t[1],a8	}
-+{ .mmi;	(p42)	add		t[0]=t[0],r0,1
-+	(p0)	add		r16=-7*16,prevsp
-+	(p0)	add		r17=-6*16,prevsp	};;
-+
-+// subtract np[8] from carrybit|tmp[8]
-+// carrybit|tmp[8] layout upon exit from above loop is:
-+//	t[0]|t[1]|t[2]|t[3]|t[4]|t[5]|t[6]|t[7]|t0 (least significant)
-+{ .mmi;	(p50)add	t[0]=t[0],r0,1
-+	add		r18=-5*16,prevsp
-+	sub		n1=t0,n1	};;
-+{ .mmi;	cmp.gtu		p34,p32=n1,t0;;
-+	.pred.rel	"mutex",p32,p34
-+	(p32)sub	n2=t[7],n2
-+	(p34)sub	n2=t[7],n2,1	};;
-+{ .mii;	(p32)cmp.gtu	p35,p33=n2,t[7]
-+	(p34)cmp.geu	p35,p33=n2,t[7];;
-+	.pred.rel	"mutex",p33,p35
-+	(p33)sub	n3=t[6],n3	}
-+{ .mmi;	(p35)sub	n3=t[6],n3,1;;
-+	(p33)cmp.gtu	p34,p32=n3,t[6]
-+	(p35)cmp.geu	p34,p32=n3,t[6]	};;
-+	.pred.rel	"mutex",p32,p34
-+{ .mii;	(p32)sub	n4=t[5],n4
-+	(p34)sub	n4=t[5],n4,1;;
-+	(p32)cmp.gtu	p35,p33=n4,t[5]	}
-+{ .mmi;	(p34)cmp.geu	p35,p33=n4,t[5];;
-+	.pred.rel	"mutex",p33,p35
-+	(p33)sub	n5=t[4],n5
-+	(p35)sub	n5=t[4],n5,1	};;
-+{ .mii;	(p33)cmp.gtu	p34,p32=n5,t[4]
-+	(p35)cmp.geu	p34,p32=n5,t[4];;
-+	.pred.rel	"mutex",p32,p34
-+	(p32)sub	n6=t[3],n6	}
-+{ .mmi;	(p34)sub	n6=t[3],n6,1;;
-+	(p32)cmp.gtu	p35,p33=n6,t[3]
-+	(p34)cmp.geu	p35,p33=n6,t[3]	};;
-+	.pred.rel	"mutex",p33,p35
-+{ .mii;	(p33)sub	n7=t[2],n7
-+	(p35)sub	n7=t[2],n7,1;;
-+	(p33)cmp.gtu	p34,p32=n7,t[2]	}
-+{ .mmi;	(p35)cmp.geu	p34,p32=n7,t[2];;
-+	.pred.rel	"mutex",p32,p34
-+	(p32)sub	n8=t[1],n8
-+	(p34)sub	n8=t[1],n8,1	};;
-+{ .mii;	(p32)cmp.gtu	p35,p33=n8,t[1]
-+	(p34)cmp.geu	p35,p33=n8,t[1];;
-+	.pred.rel	"mutex",p33,p35
-+	(p33)sub	a8=t[0],r0	}
-+{ .mmi;	(p35)sub	a8=t[0],r0,1;;
-+	(p33)cmp.gtu	p34,p32=a8,t[0]
-+	(p35)cmp.geu	p34,p32=a8,t[0]	};;
-+
-+// save the result, either tmp[num] or tmp[num]-np[num]
-+	.pred.rel	"mutex",p32,p34
-+{ .mmi;	(p32)st8	[rptr]=n1,8
-+	(p34)st8	[rptr]=t0,8
-+	add		r19=-4*16,prevsp};;
-+{ .mmb;	(p32)st8	[rptr]=n2,8
-+	(p34)st8	[rptr]=t[7],8
-+	(p5)br.cond.dpnt.few	.Ldone	};;
-+{ .mmb;	(p32)st8	[rptr]=n3,8
-+	(p34)st8	[rptr]=t[6],8
-+	(p7)br.cond.dpnt.few	.Ldone	};;
-+{ .mmb;	(p32)st8	[rptr]=n4,8
-+	(p34)st8	[rptr]=t[5],8
-+	(p9)br.cond.dpnt.few	.Ldone	};;
-+{ .mmb;	(p32)st8	[rptr]=n5,8
-+	(p34)st8	[rptr]=t[4],8
-+	(p11)br.cond.dpnt.few	.Ldone	};;
-+{ .mmb;	(p32)st8	[rptr]=n6,8
-+	(p34)st8	[rptr]=t[3],8
-+	(p13)br.cond.dpnt.few	.Ldone	};;
-+{ .mmb;	(p32)st8	[rptr]=n7,8
-+	(p34)st8	[rptr]=t[2],8
-+	(p15)br.cond.dpnt.few	.Ldone	};;
-+{ .mmb;	(p32)st8	[rptr]=n8,8
-+	(p34)st8	[rptr]=t[1],8
-+	nop.b		0		};;
-+.Ldone:						// epilogue
-+{ .mmi;	ldf.fill	f16=[r16],64
-+	ldf.fill	f17=[r17],64
-+	nop.i		0		}
-+{ .mmi;	ldf.fill	f18=[r18],64
-+	ldf.fill	f19=[r19],64
-+	mov		pr=prevpr,0x1ffff	};;
-+{ .mmi;	ldf.fill	f20=[r16]
-+	ldf.fill	f21=[r17]
-+	mov		ar.lc=prevlc	}
-+{ .mmi;	ldf.fill	f22=[r18]
-+	ldf.fill	f23=[r19]
-+	mov		ret0=1		}	// signal "handled"
-+{ .mib;	rum		1<<5
-+	.restore	sp
-+	mov		sp=prevsp
-+	br.ret.sptk.many	b0	};;
-+.endp	bn_mul_mont_8#
-+
-+.type	copyright#,\@object
-+copyright:
-+stringz	"Montgomery multiplication for IA-64, CRYPTOGAMS by "
-+___
-+
-+open STDOUT,">$output" if $output;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ia64.S b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ia64.S
-new file mode 100644
-index 0000000..f2404a3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ia64.S
-@@ -0,0 +1,1562 @@
-+.explicit
-+.text
-+.ident	"ia64.S, Version 2.1"
-+.ident	"IA-64 ISA artwork by Andy Polyakov "
-+
-+// Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+//
-+// Licensed under the OpenSSL license (the "License").  You may not use
-+// this file except in compliance with the License.  You can obtain a copy
-+// in the file LICENSE in the source distribution or at
-+// https://www.openssl.org/source/license.html
-+
-+//
-+// ====================================================================
-+// Written by Andy Polyakov  for the OpenSSL
-+// project.
-+//
-+// Rights for redistribution and usage in source and binary forms are
-+// granted according to the OpenSSL license. Warranty of any kind is
-+// disclaimed.
-+// ====================================================================
-+//
-+// Version 2.x is Itanium2 re-tune. Few words about how Itanum2 is
-+// different from Itanium to this module viewpoint. Most notably, is it
-+// "wider" than Itanium? Can you experience loop scalability as
-+// discussed in commentary sections? Not really:-( Itanium2 has 6
-+// integer ALU ports, i.e. it's 2 ports wider, but it's not enough to
-+// spin twice as fast, as I need 8 IALU ports. Amount of floating point
-+// ports is the same, i.e. 2, while I need 4. In other words, to this
-+// module Itanium2 remains effectively as "wide" as Itanium. Yet it's
-+// essentially different in respect to this module, and a re-tune was
-+// required. Well, because some instruction latencies has changed. Most
-+// noticeably those intensively used:
-+//
-+//			Itanium	Itanium2
-+//	ldf8		9	6		L2 hit
-+//	ld8		2	1		L1 hit
-+//	getf		2	5
-+//	xma[->getf]	7[+1]	4[+0]
-+//	add[->st8]	1[+1]	1[+0]
-+//
-+// What does it mean? You might ratiocinate that the original code
-+// should run just faster... Because sum of latencies is smaller...
-+// Wrong! Note that getf latency increased. This means that if a loop is
-+// scheduled for lower latency (as they were), then it will suffer from
-+// stall condition and the code will therefore turn anti-scalable, e.g.
-+// original bn_mul_words spun at 5*n or 2.5 times slower than expected
-+// on Itanium2! What to do? Reschedule loops for Itanium2? But then
-+// Itanium would exhibit anti-scalability. So I've chosen to reschedule
-+// for worst latency for every instruction aiming for best *all-round*
-+// performance.  
-+
-+// Q.	How much faster does it get?
-+// A.	Here is the output from 'openssl speed rsa dsa' for vanilla
-+//	0.9.6a compiled with gcc version 2.96 20000731 (Red Hat
-+//	Linux 7.1 2.96-81):
-+//
-+//	                  sign    verify    sign/s verify/s
-+//	rsa  512 bits   0.0036s   0.0003s    275.3   2999.2
-+//	rsa 1024 bits   0.0203s   0.0011s     49.3    894.1
-+//	rsa 2048 bits   0.1331s   0.0040s      7.5    250.9
-+//	rsa 4096 bits   0.9270s   0.0147s      1.1     68.1
-+//	                  sign    verify    sign/s verify/s
-+//	dsa  512 bits   0.0035s   0.0043s    288.3    234.8
-+//	dsa 1024 bits   0.0111s   0.0135s     90.0     74.2
-+//
-+//	And here is similar output but for this assembler
-+//	implementation:-)
-+//
-+//	                  sign    verify    sign/s verify/s
-+//	rsa  512 bits   0.0021s   0.0001s    549.4   9638.5
-+//	rsa 1024 bits   0.0055s   0.0002s    183.8   4481.1
-+//	rsa 2048 bits   0.0244s   0.0006s     41.4   1726.3
-+//	rsa 4096 bits   0.1295s   0.0018s      7.7    561.5
-+//	                  sign    verify    sign/s verify/s
-+//	dsa  512 bits   0.0012s   0.0013s    891.9    756.6
-+//	dsa 1024 bits   0.0023s   0.0028s    440.4    376.2
-+//	
-+//	Yes, you may argue that it's not fair comparison as it's
-+//	possible to craft the C implementation with BN_UMULT_HIGH
-+//	inline assembler macro. But of course! Here is the output
-+//	with the macro:
-+//
-+//	                  sign    verify    sign/s verify/s
-+//	rsa  512 bits   0.0020s   0.0002s    495.0   6561.0
-+//	rsa 1024 bits   0.0086s   0.0004s    116.2   2235.7
-+//	rsa 2048 bits   0.0519s   0.0015s     19.3    667.3
-+//	rsa 4096 bits   0.3464s   0.0053s      2.9    187.7
-+//	                  sign    verify    sign/s verify/s
-+//	dsa  512 bits   0.0016s   0.0020s    613.1    510.5
-+//	dsa 1024 bits   0.0045s   0.0054s    221.0    183.9
-+//
-+//	My code is still way faster, huh:-) And I believe that even
-+//	higher performance can be achieved. Note that as keys get
-+//	longer, performance gain is larger. Why? According to the
-+//	profiler there is another player in the field, namely
-+//	BN_from_montgomery consuming larger and larger portion of CPU
-+//	time as keysize decreases. I therefore consider putting effort
-+//	to assembler implementation of the following routine:
-+//
-+//	void bn_mul_add_mont (BN_ULONG *rp,BN_ULONG *np,int nl,BN_ULONG n0)
-+//	{
-+//	int      i,j;
-+//	BN_ULONG v;
-+//
-+//	for (i=0; i for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# This module doesn't present direct interest for OpenSSL, because it
-+# doesn't provide better performance for longer keys, at least not on
-+# in-order-execution cores. While 512-bit RSA sign operations can be
-+# 65% faster in 64-bit mode, 1024-bit ones are only 15% faster, and
-+# 4096-bit ones are up to 15% slower. In 32-bit mode it varies from
-+# 16% improvement for 512-bit RSA sign to -33% for 4096-bit RSA
-+# verify:-( All comparisons are against bn_mul_mont-free assembler.
-+# The module might be of interest to embedded system developers, as
-+# the code is smaller than 1KB, yet offers >3x improvement on MIPS64
-+# and 75-30% [less for longer keys] on MIPS32 over compiler-generated
-+# code.
-+
-+######################################################################
-+# There is a number of MIPS ABI in use, O32 and N32/64 are most
-+# widely used. Then there is a new contender: NUBI. It appears that if
-+# one picks the latter, it's possible to arrange code in ABI neutral
-+# manner. Therefore let's stick to NUBI register layout:
-+#
-+($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
-+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
-+($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
-+#
-+# The return value is placed in $a0. Following coding rules facilitate
-+# interoperability:
-+#
-+# - never ever touch $tp, "thread pointer", former $gp;
-+# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
-+#   old code];
-+# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
-+#
-+# For reference here is register layout for N32/64 MIPS ABIs:
-+#
-+# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
-+# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
-+# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
-+# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
-+#
-+$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64
-+
-+if ($flavour =~ /64|n32/i) {
-+	$PTR_ADD="dadd";	# incidentally works even on n32
-+	$PTR_SUB="dsub";	# incidentally works even on n32
-+	$REG_S="sd";
-+	$REG_L="ld";
-+	$SZREG=8;
-+} else {
-+	$PTR_ADD="add";
-+	$PTR_SUB="sub";
-+	$REG_S="sw";
-+	$REG_L="lw";
-+	$SZREG=4;
-+}
-+$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0x00fff000 : 0x00ff0000;
-+#
-+# 
-+#
-+######################################################################
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+if ($flavour =~ /64|n32/i) {
-+	$LD="ld";
-+	$ST="sd";
-+	$MULTU="dmultu";
-+	$ADDU="daddu";
-+	$SUBU="dsubu";
-+	$BNSZ=8;
-+} else {
-+	$LD="lw";
-+	$ST="sw";
-+	$MULTU="multu";
-+	$ADDU="addu";
-+	$SUBU="subu";
-+	$BNSZ=4;
-+}
-+
-+# int bn_mul_mont(
-+$rp=$a0;	# BN_ULONG *rp,
-+$ap=$a1;	# const BN_ULONG *ap,
-+$bp=$a2;	# const BN_ULONG *bp,
-+$np=$a3;	# const BN_ULONG *np,
-+$n0=$a4;	# const BN_ULONG *n0,
-+$num=$a5;	# int num);
-+
-+$lo0=$a6;
-+$hi0=$a7;
-+$lo1=$t1;
-+$hi1=$t2;
-+$aj=$s0;
-+$bi=$s1;
-+$nj=$s2;
-+$tp=$s3;
-+$alo=$s4;
-+$ahi=$s5;
-+$nlo=$s6;
-+$nhi=$s7;
-+$tj=$s8;
-+$i=$s9;
-+$j=$s10;
-+$m1=$s11;
-+
-+$FRAMESIZE=14;
-+
-+$code=<<___;
-+.text
-+
-+.set	noat
-+.set	noreorder
-+
-+.align	5
-+.globl	bn_mul_mont
-+.ent	bn_mul_mont
-+bn_mul_mont:
-+___
-+$code.=<<___ if ($flavour =~ /o32/i);
-+	lw	$n0,16($sp)
-+	lw	$num,20($sp)
-+___
-+$code.=<<___;
-+	slt	$at,$num,4
-+	bnez	$at,1f
-+	li	$t0,0
-+	slt	$at,$num,17	# on in-order CPU
-+	bnez	$at,bn_mul_mont_internal
-+	nop
-+1:	jr	$ra
-+	li	$a0,0
-+.end	bn_mul_mont
-+
-+.align	5
-+.ent	bn_mul_mont_internal
-+bn_mul_mont_internal:
-+	.frame	$fp,$FRAMESIZE*$SZREG,$ra
-+	.mask	0x40000000|$SAVED_REGS_MASK,-$SZREG
-+	$PTR_SUB $sp,$FRAMESIZE*$SZREG
-+	$REG_S	$fp,($FRAMESIZE-1)*$SZREG($sp)
-+	$REG_S	$s11,($FRAMESIZE-2)*$SZREG($sp)
-+	$REG_S	$s10,($FRAMESIZE-3)*$SZREG($sp)
-+	$REG_S	$s9,($FRAMESIZE-4)*$SZREG($sp)
-+	$REG_S	$s8,($FRAMESIZE-5)*$SZREG($sp)
-+	$REG_S	$s7,($FRAMESIZE-6)*$SZREG($sp)
-+	$REG_S	$s6,($FRAMESIZE-7)*$SZREG($sp)
-+	$REG_S	$s5,($FRAMESIZE-8)*$SZREG($sp)
-+	$REG_S	$s4,($FRAMESIZE-9)*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_S	$s3,($FRAMESIZE-10)*$SZREG($sp)
-+	$REG_S	$s2,($FRAMESIZE-11)*$SZREG($sp)
-+	$REG_S	$s1,($FRAMESIZE-12)*$SZREG($sp)
-+	$REG_S	$s0,($FRAMESIZE-13)*$SZREG($sp)
-+___
-+$code.=<<___;
-+	move	$fp,$sp
-+
-+	.set	reorder
-+	$LD	$n0,0($n0)
-+	$LD	$bi,0($bp)	# bp[0]
-+	$LD	$aj,0($ap)	# ap[0]
-+	$LD	$nj,0($np)	# np[0]
-+
-+	$PTR_SUB $sp,2*$BNSZ	# place for two extra words
-+	sll	$num,`log($BNSZ)/log(2)`
-+	li	$at,-4096
-+	$PTR_SUB $sp,$num
-+	and	$sp,$at
-+
-+	$MULTU	$aj,$bi
-+	$LD	$alo,$BNSZ($ap)
-+	$LD	$nlo,$BNSZ($np)
-+	mflo	$lo0
-+	mfhi	$hi0
-+	$MULTU	$lo0,$n0
-+	mflo	$m1
-+
-+	$MULTU	$alo,$bi
-+	mflo	$alo
-+	mfhi	$ahi
-+
-+	$MULTU	$nj,$m1
-+	mflo	$lo1
-+	mfhi	$hi1
-+	$MULTU	$nlo,$m1
-+	$ADDU	$lo1,$lo0
-+	sltu	$at,$lo1,$lo0
-+	$ADDU	$hi1,$at
-+	mflo	$nlo
-+	mfhi	$nhi
-+
-+	move	$tp,$sp
-+	li	$j,2*$BNSZ
-+.align	4
-+.L1st:
-+	.set	noreorder
-+	$PTR_ADD $aj,$ap,$j
-+	$PTR_ADD $nj,$np,$j
-+	$LD	$aj,($aj)
-+	$LD	$nj,($nj)
-+
-+	$MULTU	$aj,$bi
-+	$ADDU	$lo0,$alo,$hi0
-+	$ADDU	$lo1,$nlo,$hi1
-+	sltu	$at,$lo0,$hi0
-+	sltu	$t0,$lo1,$hi1
-+	$ADDU	$hi0,$ahi,$at
-+	$ADDU	$hi1,$nhi,$t0
-+	mflo	$alo
-+	mfhi	$ahi
-+
-+	$ADDU	$lo1,$lo0
-+	sltu	$at,$lo1,$lo0
-+	$MULTU	$nj,$m1
-+	$ADDU	$hi1,$at
-+	addu	$j,$BNSZ
-+	$ST	$lo1,($tp)
-+	sltu	$t0,$j,$num
-+	mflo	$nlo
-+	mfhi	$nhi
-+
-+	bnez	$t0,.L1st
-+	$PTR_ADD $tp,$BNSZ
-+	.set	reorder
-+
-+	$ADDU	$lo0,$alo,$hi0
-+	sltu	$at,$lo0,$hi0
-+	$ADDU	$hi0,$ahi,$at
-+
-+	$ADDU	$lo1,$nlo,$hi1
-+	sltu	$t0,$lo1,$hi1
-+	$ADDU	$hi1,$nhi,$t0
-+	$ADDU	$lo1,$lo0
-+	sltu	$at,$lo1,$lo0
-+	$ADDU	$hi1,$at
-+
-+	$ST	$lo1,($tp)
-+
-+	$ADDU	$hi1,$hi0
-+	sltu	$at,$hi1,$hi0
-+	$ST	$hi1,$BNSZ($tp)
-+	$ST	$at,2*$BNSZ($tp)
-+
-+	li	$i,$BNSZ
-+.align	4
-+.Louter:
-+	$PTR_ADD $bi,$bp,$i
-+	$LD	$bi,($bi)
-+	$LD	$aj,($ap)
-+	$LD	$alo,$BNSZ($ap)
-+	$LD	$tj,($sp)
-+
-+	$MULTU	$aj,$bi
-+	$LD	$nj,($np)
-+	$LD	$nlo,$BNSZ($np)
-+	mflo	$lo0
-+	mfhi	$hi0
-+	$ADDU	$lo0,$tj
-+	$MULTU	$lo0,$n0
-+	sltu	$at,$lo0,$tj
-+	$ADDU	$hi0,$at
-+	mflo	$m1
-+
-+	$MULTU	$alo,$bi
-+	mflo	$alo
-+	mfhi	$ahi
-+
-+	$MULTU	$nj,$m1
-+	mflo	$lo1
-+	mfhi	$hi1
-+
-+	$MULTU	$nlo,$m1
-+	$ADDU	$lo1,$lo0
-+	sltu	$at,$lo1,$lo0
-+	$ADDU	$hi1,$at
-+	mflo	$nlo
-+	mfhi	$nhi
-+
-+	move	$tp,$sp
-+	li	$j,2*$BNSZ
-+	$LD	$tj,$BNSZ($tp)
-+.align	4
-+.Linner:
-+	.set	noreorder
-+	$PTR_ADD $aj,$ap,$j
-+	$PTR_ADD $nj,$np,$j
-+	$LD	$aj,($aj)
-+	$LD	$nj,($nj)
-+
-+	$MULTU	$aj,$bi
-+	$ADDU	$lo0,$alo,$hi0
-+	$ADDU	$lo1,$nlo,$hi1
-+	sltu	$at,$lo0,$hi0
-+	sltu	$t0,$lo1,$hi1
-+	$ADDU	$hi0,$ahi,$at
-+	$ADDU	$hi1,$nhi,$t0
-+	mflo	$alo
-+	mfhi	$ahi
-+
-+	$ADDU	$lo0,$tj
-+	addu	$j,$BNSZ
-+	$MULTU	$nj,$m1
-+	sltu	$at,$lo0,$tj
-+	$ADDU	$lo1,$lo0
-+	$ADDU	$hi0,$at
-+	sltu	$t0,$lo1,$lo0
-+	$LD	$tj,2*$BNSZ($tp)
-+	$ADDU	$hi1,$t0
-+	sltu	$at,$j,$num
-+	mflo	$nlo
-+	mfhi	$nhi
-+	$ST	$lo1,($tp)
-+	bnez	$at,.Linner
-+	$PTR_ADD $tp,$BNSZ
-+	.set	reorder
-+
-+	$ADDU	$lo0,$alo,$hi0
-+	sltu	$at,$lo0,$hi0
-+	$ADDU	$hi0,$ahi,$at
-+	$ADDU	$lo0,$tj
-+	sltu	$t0,$lo0,$tj
-+	$ADDU	$hi0,$t0
-+
-+	$LD	$tj,2*$BNSZ($tp)
-+	$ADDU	$lo1,$nlo,$hi1
-+	sltu	$at,$lo1,$hi1
-+	$ADDU	$hi1,$nhi,$at
-+	$ADDU	$lo1,$lo0
-+	sltu	$t0,$lo1,$lo0
-+	$ADDU	$hi1,$t0
-+	$ST	$lo1,($tp)
-+
-+	$ADDU	$lo1,$hi1,$hi0
-+	sltu	$hi1,$lo1,$hi0
-+	$ADDU	$lo1,$tj
-+	sltu	$at,$lo1,$tj
-+	$ADDU	$hi1,$at
-+	$ST	$lo1,$BNSZ($tp)
-+	$ST	$hi1,2*$BNSZ($tp)
-+
-+	addu	$i,$BNSZ
-+	sltu	$t0,$i,$num
-+	bnez	$t0,.Louter
-+
-+	.set	noreorder
-+	$PTR_ADD $tj,$sp,$num	# &tp[num]
-+	move	$tp,$sp
-+	move	$ap,$sp
-+	li	$hi0,0		# clear borrow bit
-+
-+.align	4
-+.Lsub:	$LD	$lo0,($tp)
-+	$LD	$lo1,($np)
-+	$PTR_ADD $tp,$BNSZ
-+	$PTR_ADD $np,$BNSZ
-+	$SUBU	$lo1,$lo0,$lo1	# tp[i]-np[i]
-+	sgtu	$at,$lo1,$lo0
-+	$SUBU	$lo0,$lo1,$hi0
-+	sgtu	$hi0,$lo0,$lo1
-+	$ST	$lo0,($rp)
-+	or	$hi0,$at
-+	sltu	$at,$tp,$tj
-+	bnez	$at,.Lsub
-+	$PTR_ADD $rp,$BNSZ
-+
-+	$SUBU	$hi0,$hi1,$hi0	# handle upmost overflow bit
-+	move	$tp,$sp
-+	$PTR_SUB $rp,$num	# restore rp
-+	not	$hi1,$hi0
-+
-+	and	$ap,$hi0,$sp
-+	and	$bp,$hi1,$rp
-+	or	$ap,$ap,$bp	# ap=borrow?tp:rp
-+
-+.align	4
-+.Lcopy:	$LD	$aj,($ap)
-+	$PTR_ADD $ap,$BNSZ
-+	$ST	$zero,($tp)
-+	$PTR_ADD $tp,$BNSZ
-+	sltu	$at,$tp,$tj
-+	$ST	$aj,($rp)
-+	bnez	$at,.Lcopy
-+	$PTR_ADD $rp,$BNSZ
-+
-+	li	$a0,1
-+	li	$t0,1
-+
-+	.set	noreorder
-+	move	$sp,$fp
-+	$REG_L	$fp,($FRAMESIZE-1)*$SZREG($sp)
-+	$REG_L	$s11,($FRAMESIZE-2)*$SZREG($sp)
-+	$REG_L	$s10,($FRAMESIZE-3)*$SZREG($sp)
-+	$REG_L	$s9,($FRAMESIZE-4)*$SZREG($sp)
-+	$REG_L	$s8,($FRAMESIZE-5)*$SZREG($sp)
-+	$REG_L	$s7,($FRAMESIZE-6)*$SZREG($sp)
-+	$REG_L	$s6,($FRAMESIZE-7)*$SZREG($sp)
-+	$REG_L	$s5,($FRAMESIZE-8)*$SZREG($sp)
-+	$REG_L	$s4,($FRAMESIZE-9)*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$s3,($FRAMESIZE-10)*$SZREG($sp)
-+	$REG_L	$s2,($FRAMESIZE-11)*$SZREG($sp)
-+	$REG_L	$s1,($FRAMESIZE-12)*$SZREG($sp)
-+	$REG_L	$s0,($FRAMESIZE-13)*$SZREG($sp)
-+___
-+$code.=<<___;
-+	jr	$ra
-+	$PTR_ADD $sp,$FRAMESIZE*$SZREG
-+.end	bn_mul_mont_internal
-+.rdata
-+.asciiz	"Montgomery Multiplication for MIPS, CRYPTOGAMS by "
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/mips.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/mips.pl
-new file mode 100644
-index 0000000..420f01f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/mips.pl
-@@ -0,0 +1,2241 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project.
-+#
-+# Rights for redistribution and usage in source and binary forms are
-+# granted according to the OpenSSL license. Warranty of any kind is
-+# disclaimed.
-+# ====================================================================
-+
-+
-+# July 1999
-+#
-+# This is drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c.
-+#
-+# The module is designed to work with either of the "new" MIPS ABI(5),
-+# namely N32 or N64, offered by IRIX 6.x. It's not meant to work under
-+# IRIX 5.x not only because it doesn't support new ABIs but also
-+# because 5.x kernels put R4x00 CPU into 32-bit mode and all those
-+# 64-bit instructions (daddu, dmultu, etc.) found below gonna only
-+# cause illegal instruction exception:-(
-+#
-+# In addition the code depends on preprocessor flags set up by MIPSpro
-+# compiler driver (either as or cc) and therefore (probably?) can't be
-+# compiled by the GNU assembler. GNU C driver manages fine though...
-+# I mean as long as -mmips-as is specified or is the default option,
-+# because then it simply invokes /usr/bin/as which in turn takes
-+# perfect care of the preprocessor definitions. Another neat feature
-+# offered by the MIPSpro assembler is an optimization pass. This gave
-+# me the opportunity to have the code looking more regular as all those
-+# architecture dependent instruction rescheduling details were left to
-+# the assembler. Cool, huh?
-+#
-+# Performance improvement is astonishing! 'apps/openssl speed rsa dsa'
-+# goes way over 3 times faster!
-+#
-+#					
-+
-+# October 2010
-+#
-+# Adapt the module even for 32-bit ABIs and other OSes. The former was
-+# achieved by mechanical replacement of 64-bit arithmetic instructions
-+# such as dmultu, daddu, etc. with their 32-bit counterparts and
-+# adjusting offsets denoting multiples of BN_ULONG. Above mentioned
-+# >3x performance improvement naturally does not apply to 32-bit code
-+# [because there is no instruction 32-bit compiler can't use], one
-+# has to content with 40-85% improvement depending on benchmark and
-+# key length, more for longer keys.
-+
-+$flavour = shift || "o32";
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+if ($flavour =~ /64|n32/i) {
-+	$LD="ld";
-+	$ST="sd";
-+	$MULTU="dmultu";
-+	$DIVU="ddivu";
-+	$ADDU="daddu";
-+	$SUBU="dsubu";
-+	$SRL="dsrl";
-+	$SLL="dsll";
-+	$BNSZ=8;
-+	$PTR_ADD="daddu";
-+	$PTR_SUB="dsubu";
-+	$SZREG=8;
-+	$REG_S="sd";
-+	$REG_L="ld";
-+} else {
-+	$LD="lw";
-+	$ST="sw";
-+	$MULTU="multu";
-+	$DIVU="divu";
-+	$ADDU="addu";
-+	$SUBU="subu";
-+	$SRL="srl";
-+	$SLL="sll";
-+	$BNSZ=4;
-+	$PTR_ADD="addu";
-+	$PTR_SUB="subu";
-+	$SZREG=4;
-+	$REG_S="sw";
-+	$REG_L="lw";
-+	$code=".set	mips2\n";
-+}
-+
-+# Below is N32/64 register layout used in the original module.
-+#
-+($zero,$at,$v0,$v1)=map("\$$_",(0..3));
-+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
-+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
-+($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
-+($ta0,$ta1,$ta2,$ta3)=($a4,$a5,$a6,$a7);
-+#
-+# No special adaptation is required for O32. NUBI on the other hand
-+# is treated by saving/restoring ($v1,$t0..$t3).
-+
-+$gp=$v1 if ($flavour =~ /nubi/i);
-+
-+$minus4=$v1;
-+
-+$code.=<<___;
-+.rdata
-+.asciiz	"mips3.s, Version 1.2"
-+.asciiz	"MIPS II/III/IV ISA artwork by Andy Polyakov "
-+
-+.text
-+.set	noat
-+
-+.align	5
-+.globl	bn_mul_add_words
-+.ent	bn_mul_add_words
-+bn_mul_add_words:
-+	.set	noreorder
-+	bgtz	$a2,bn_mul_add_words_internal
-+	move	$v0,$zero
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_mul_add_words
-+
-+.align	5
-+.ent	bn_mul_add_words_internal
-+bn_mul_add_words_internal:
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x8000f008,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$ra,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+	.set	reorder
-+	li	$minus4,-4
-+	and	$ta0,$a2,$minus4
-+	beqz	$ta0,.L_bn_mul_add_words_tail
-+
-+.L_bn_mul_add_words_loop:
-+	$LD	$t0,0($a1)
-+	$MULTU	$t0,$a3
-+	$LD	$t1,0($a0)
-+	$LD	$t2,$BNSZ($a1)
-+	$LD	$t3,$BNSZ($a0)
-+	$LD	$ta0,2*$BNSZ($a1)
-+	$LD	$ta1,2*$BNSZ($a0)
-+	$ADDU	$t1,$v0
-+	sltu	$v0,$t1,$v0	# All manuals say it "compares 32-bit
-+				# values", but it seems to work fine
-+				# even on 64-bit registers.
-+	mflo	$at
-+	mfhi	$t0
-+	$ADDU	$t1,$at
-+	$ADDU	$v0,$t0
-+	 $MULTU	$t2,$a3
-+	sltu	$at,$t1,$at
-+	$ST	$t1,0($a0)
-+	$ADDU	$v0,$at
-+
-+	$LD	$ta2,3*$BNSZ($a1)
-+	$LD	$ta3,3*$BNSZ($a0)
-+	$ADDU	$t3,$v0
-+	sltu	$v0,$t3,$v0
-+	mflo	$at
-+	mfhi	$t2
-+	$ADDU	$t3,$at
-+	$ADDU	$v0,$t2
-+	 $MULTU	$ta0,$a3
-+	sltu	$at,$t3,$at
-+	$ST	$t3,$BNSZ($a0)
-+	$ADDU	$v0,$at
-+
-+	subu	$a2,4
-+	$PTR_ADD $a0,4*$BNSZ
-+	$PTR_ADD $a1,4*$BNSZ
-+	$ADDU	$ta1,$v0
-+	sltu	$v0,$ta1,$v0
-+	mflo	$at
-+	mfhi	$ta0
-+	$ADDU	$ta1,$at
-+	$ADDU	$v0,$ta0
-+	 $MULTU	$ta2,$a3
-+	sltu	$at,$ta1,$at
-+	$ST	$ta1,-2*$BNSZ($a0)
-+	$ADDU	$v0,$at
-+
-+
-+	and	$ta0,$a2,$minus4
-+	$ADDU	$ta3,$v0
-+	sltu	$v0,$ta3,$v0
-+	mflo	$at
-+	mfhi	$ta2
-+	$ADDU	$ta3,$at
-+	$ADDU	$v0,$ta2
-+	sltu	$at,$ta3,$at
-+	$ST	$ta3,-$BNSZ($a0)
-+	.set	noreorder
-+	bgtz	$ta0,.L_bn_mul_add_words_loop
-+	$ADDU	$v0,$at
-+
-+	beqz	$a2,.L_bn_mul_add_words_return
-+	nop
-+
-+.L_bn_mul_add_words_tail:
-+	.set	reorder
-+	$LD	$t0,0($a1)
-+	$MULTU	$t0,$a3
-+	$LD	$t1,0($a0)
-+	subu	$a2,1
-+	$ADDU	$t1,$v0
-+	sltu	$v0,$t1,$v0
-+	mflo	$at
-+	mfhi	$t0
-+	$ADDU	$t1,$at
-+	$ADDU	$v0,$t0
-+	sltu	$at,$t1,$at
-+	$ST	$t1,0($a0)
-+	$ADDU	$v0,$at
-+	beqz	$a2,.L_bn_mul_add_words_return
-+
-+	$LD	$t0,$BNSZ($a1)
-+	$MULTU	$t0,$a3
-+	$LD	$t1,$BNSZ($a0)
-+	subu	$a2,1
-+	$ADDU	$t1,$v0
-+	sltu	$v0,$t1,$v0
-+	mflo	$at
-+	mfhi	$t0
-+	$ADDU	$t1,$at
-+	$ADDU	$v0,$t0
-+	sltu	$at,$t1,$at
-+	$ST	$t1,$BNSZ($a0)
-+	$ADDU	$v0,$at
-+	beqz	$a2,.L_bn_mul_add_words_return
-+
-+	$LD	$t0,2*$BNSZ($a1)
-+	$MULTU	$t0,$a3
-+	$LD	$t1,2*$BNSZ($a0)
-+	$ADDU	$t1,$v0
-+	sltu	$v0,$t1,$v0
-+	mflo	$at
-+	mfhi	$t0
-+	$ADDU	$t1,$at
-+	$ADDU	$v0,$t0
-+	sltu	$at,$t1,$at
-+	$ST	$t1,2*$BNSZ($a0)
-+	$ADDU	$v0,$at
-+
-+.L_bn_mul_add_words_return:
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_mul_add_words_internal
-+
-+.align	5
-+.globl	bn_mul_words
-+.ent	bn_mul_words
-+bn_mul_words:
-+	.set	noreorder
-+	bgtz	$a2,bn_mul_words_internal
-+	move	$v0,$zero
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_mul_words
-+
-+.align	5
-+.ent	bn_mul_words_internal
-+bn_mul_words_internal:
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x8000f008,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$ra,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+	.set	reorder
-+	li	$minus4,-4
-+	and	$ta0,$a2,$minus4
-+	beqz	$ta0,.L_bn_mul_words_tail
-+
-+.L_bn_mul_words_loop:
-+	$LD	$t0,0($a1)
-+	$MULTU	$t0,$a3
-+	$LD	$t2,$BNSZ($a1)
-+	$LD	$ta0,2*$BNSZ($a1)
-+	$LD	$ta2,3*$BNSZ($a1)
-+	mflo	$at
-+	mfhi	$t0
-+	$ADDU	$v0,$at
-+	sltu	$t1,$v0,$at
-+	 $MULTU	$t2,$a3
-+	$ST	$v0,0($a0)
-+	$ADDU	$v0,$t1,$t0
-+
-+	subu	$a2,4
-+	$PTR_ADD $a0,4*$BNSZ
-+	$PTR_ADD $a1,4*$BNSZ
-+	mflo	$at
-+	mfhi	$t2
-+	$ADDU	$v0,$at
-+	sltu	$t3,$v0,$at
-+	 $MULTU	$ta0,$a3
-+	$ST	$v0,-3*$BNSZ($a0)
-+	$ADDU	$v0,$t3,$t2
-+
-+	mflo	$at
-+	mfhi	$ta0
-+	$ADDU	$v0,$at
-+	sltu	$ta1,$v0,$at
-+	 $MULTU	$ta2,$a3
-+	$ST	$v0,-2*$BNSZ($a0)
-+	$ADDU	$v0,$ta1,$ta0
-+
-+	and	$ta0,$a2,$minus4
-+	mflo	$at
-+	mfhi	$ta2
-+	$ADDU	$v0,$at
-+	sltu	$ta3,$v0,$at
-+	$ST	$v0,-$BNSZ($a0)
-+	.set	noreorder
-+	bgtz	$ta0,.L_bn_mul_words_loop
-+	$ADDU	$v0,$ta3,$ta2
-+
-+	beqz	$a2,.L_bn_mul_words_return
-+	nop
-+
-+.L_bn_mul_words_tail:
-+	.set	reorder
-+	$LD	$t0,0($a1)
-+	$MULTU	$t0,$a3
-+	subu	$a2,1
-+	mflo	$at
-+	mfhi	$t0
-+	$ADDU	$v0,$at
-+	sltu	$t1,$v0,$at
-+	$ST	$v0,0($a0)
-+	$ADDU	$v0,$t1,$t0
-+	beqz	$a2,.L_bn_mul_words_return
-+
-+	$LD	$t0,$BNSZ($a1)
-+	$MULTU	$t0,$a3
-+	subu	$a2,1
-+	mflo	$at
-+	mfhi	$t0
-+	$ADDU	$v0,$at
-+	sltu	$t1,$v0,$at
-+	$ST	$v0,$BNSZ($a0)
-+	$ADDU	$v0,$t1,$t0
-+	beqz	$a2,.L_bn_mul_words_return
-+
-+	$LD	$t0,2*$BNSZ($a1)
-+	$MULTU	$t0,$a3
-+	mflo	$at
-+	mfhi	$t0
-+	$ADDU	$v0,$at
-+	sltu	$t1,$v0,$at
-+	$ST	$v0,2*$BNSZ($a0)
-+	$ADDU	$v0,$t1,$t0
-+
-+.L_bn_mul_words_return:
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_mul_words_internal
-+
-+.align	5
-+.globl	bn_sqr_words
-+.ent	bn_sqr_words
-+bn_sqr_words:
-+	.set	noreorder
-+	bgtz	$a2,bn_sqr_words_internal
-+	move	$v0,$zero
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_sqr_words
-+
-+.align	5
-+.ent	bn_sqr_words_internal
-+bn_sqr_words_internal:
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x8000f008,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$ra,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+	.set	reorder
-+	li	$minus4,-4
-+	and	$ta0,$a2,$minus4
-+	beqz	$ta0,.L_bn_sqr_words_tail
-+
-+.L_bn_sqr_words_loop:
-+	$LD	$t0,0($a1)
-+	$MULTU	$t0,$t0
-+	$LD	$t2,$BNSZ($a1)
-+	$LD	$ta0,2*$BNSZ($a1)
-+	$LD	$ta2,3*$BNSZ($a1)
-+	mflo	$t1
-+	mfhi	$t0
-+	$ST	$t1,0($a0)
-+	$ST	$t0,$BNSZ($a0)
-+
-+	$MULTU	$t2,$t2
-+	subu	$a2,4
-+	$PTR_ADD $a0,8*$BNSZ
-+	$PTR_ADD $a1,4*$BNSZ
-+	mflo	$t3
-+	mfhi	$t2
-+	$ST	$t3,-6*$BNSZ($a0)
-+	$ST	$t2,-5*$BNSZ($a0)
-+
-+	$MULTU	$ta0,$ta0
-+	mflo	$ta1
-+	mfhi	$ta0
-+	$ST	$ta1,-4*$BNSZ($a0)
-+	$ST	$ta0,-3*$BNSZ($a0)
-+
-+
-+	$MULTU	$ta2,$ta2
-+	and	$ta0,$a2,$minus4
-+	mflo	$ta3
-+	mfhi	$ta2
-+	$ST	$ta3,-2*$BNSZ($a0)
-+
-+	.set	noreorder
-+	bgtz	$ta0,.L_bn_sqr_words_loop
-+	$ST	$ta2,-$BNSZ($a0)
-+
-+	beqz	$a2,.L_bn_sqr_words_return
-+	nop
-+
-+.L_bn_sqr_words_tail:
-+	.set	reorder
-+	$LD	$t0,0($a1)
-+	$MULTU	$t0,$t0
-+	subu	$a2,1
-+	mflo	$t1
-+	mfhi	$t0
-+	$ST	$t1,0($a0)
-+	$ST	$t0,$BNSZ($a0)
-+	beqz	$a2,.L_bn_sqr_words_return
-+
-+	$LD	$t0,$BNSZ($a1)
-+	$MULTU	$t0,$t0
-+	subu	$a2,1
-+	mflo	$t1
-+	mfhi	$t0
-+	$ST	$t1,2*$BNSZ($a0)
-+	$ST	$t0,3*$BNSZ($a0)
-+	beqz	$a2,.L_bn_sqr_words_return
-+
-+	$LD	$t0,2*$BNSZ($a1)
-+	$MULTU	$t0,$t0
-+	mflo	$t1
-+	mfhi	$t0
-+	$ST	$t1,4*$BNSZ($a0)
-+	$ST	$t0,5*$BNSZ($a0)
-+
-+.L_bn_sqr_words_return:
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+	jr	$ra
-+	move	$a0,$v0
-+
-+.end	bn_sqr_words_internal
-+
-+.align	5
-+.globl	bn_add_words
-+.ent	bn_add_words
-+bn_add_words:
-+	.set	noreorder
-+	bgtz	$a3,bn_add_words_internal
-+	move	$v0,$zero
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_add_words
-+
-+.align	5
-+.ent	bn_add_words_internal
-+bn_add_words_internal:
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x8000f008,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$ra,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+	.set	reorder
-+	li	$minus4,-4
-+	and	$at,$a3,$minus4
-+	beqz	$at,.L_bn_add_words_tail
-+
-+.L_bn_add_words_loop:
-+	$LD	$t0,0($a1)
-+	$LD	$ta0,0($a2)
-+	subu	$a3,4
-+	$LD	$t1,$BNSZ($a1)
-+	and	$at,$a3,$minus4
-+	$LD	$t2,2*$BNSZ($a1)
-+	$PTR_ADD $a2,4*$BNSZ
-+	$LD	$t3,3*$BNSZ($a1)
-+	$PTR_ADD $a0,4*$BNSZ
-+	$LD	$ta1,-3*$BNSZ($a2)
-+	$PTR_ADD $a1,4*$BNSZ
-+	$LD	$ta2,-2*$BNSZ($a2)
-+	$LD	$ta3,-$BNSZ($a2)
-+	$ADDU	$ta0,$t0
-+	sltu	$t8,$ta0,$t0
-+	$ADDU	$t0,$ta0,$v0
-+	sltu	$v0,$t0,$ta0
-+	$ST	$t0,-4*$BNSZ($a0)
-+	$ADDU	$v0,$t8
-+
-+	$ADDU	$ta1,$t1
-+	sltu	$t9,$ta1,$t1
-+	$ADDU	$t1,$ta1,$v0
-+	sltu	$v0,$t1,$ta1
-+	$ST	$t1,-3*$BNSZ($a0)
-+	$ADDU	$v0,$t9
-+
-+	$ADDU	$ta2,$t2
-+	sltu	$t8,$ta2,$t2
-+	$ADDU	$t2,$ta2,$v0
-+	sltu	$v0,$t2,$ta2
-+	$ST	$t2,-2*$BNSZ($a0)
-+	$ADDU	$v0,$t8
-+	
-+	$ADDU	$ta3,$t3
-+	sltu	$t9,$ta3,$t3
-+	$ADDU	$t3,$ta3,$v0
-+	sltu	$v0,$t3,$ta3
-+	$ST	$t3,-$BNSZ($a0)
-+	
-+	.set	noreorder
-+	bgtz	$at,.L_bn_add_words_loop
-+	$ADDU	$v0,$t9
-+
-+	beqz	$a3,.L_bn_add_words_return
-+	nop
-+
-+.L_bn_add_words_tail:
-+	.set	reorder
-+	$LD	$t0,0($a1)
-+	$LD	$ta0,0($a2)
-+	$ADDU	$ta0,$t0
-+	subu	$a3,1
-+	sltu	$t8,$ta0,$t0
-+	$ADDU	$t0,$ta0,$v0
-+	sltu	$v0,$t0,$ta0
-+	$ST	$t0,0($a0)
-+	$ADDU	$v0,$t8
-+	beqz	$a3,.L_bn_add_words_return
-+
-+	$LD	$t1,$BNSZ($a1)
-+	$LD	$ta1,$BNSZ($a2)
-+	$ADDU	$ta1,$t1
-+	subu	$a3,1
-+	sltu	$t9,$ta1,$t1
-+	$ADDU	$t1,$ta1,$v0
-+	sltu	$v0,$t1,$ta1
-+	$ST	$t1,$BNSZ($a0)
-+	$ADDU	$v0,$t9
-+	beqz	$a3,.L_bn_add_words_return
-+
-+	$LD	$t2,2*$BNSZ($a1)
-+	$LD	$ta2,2*$BNSZ($a2)
-+	$ADDU	$ta2,$t2
-+	sltu	$t8,$ta2,$t2
-+	$ADDU	$t2,$ta2,$v0
-+	sltu	$v0,$t2,$ta2
-+	$ST	$t2,2*$BNSZ($a0)
-+	$ADDU	$v0,$t8
-+
-+.L_bn_add_words_return:
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+	jr	$ra
-+	move	$a0,$v0
-+
-+.end	bn_add_words_internal
-+
-+.align	5
-+.globl	bn_sub_words
-+.ent	bn_sub_words
-+bn_sub_words:
-+	.set	noreorder
-+	bgtz	$a3,bn_sub_words_internal
-+	move	$v0,$zero
-+	jr	$ra
-+	move	$a0,$zero
-+.end	bn_sub_words
-+
-+.align	5
-+.ent	bn_sub_words_internal
-+bn_sub_words_internal:
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x8000f008,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$ra,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+	.set	reorder
-+	li	$minus4,-4
-+	and	$at,$a3,$minus4
-+	beqz	$at,.L_bn_sub_words_tail
-+
-+.L_bn_sub_words_loop:
-+	$LD	$t0,0($a1)
-+	$LD	$ta0,0($a2)
-+	subu	$a3,4
-+	$LD	$t1,$BNSZ($a1)
-+	and	$at,$a3,$minus4
-+	$LD	$t2,2*$BNSZ($a1)
-+	$PTR_ADD $a2,4*$BNSZ
-+	$LD	$t3,3*$BNSZ($a1)
-+	$PTR_ADD $a0,4*$BNSZ
-+	$LD	$ta1,-3*$BNSZ($a2)
-+	$PTR_ADD $a1,4*$BNSZ
-+	$LD	$ta2,-2*$BNSZ($a2)
-+	$LD	$ta3,-$BNSZ($a2)
-+	sltu	$t8,$t0,$ta0
-+	$SUBU	$ta0,$t0,$ta0
-+	$SUBU	$t0,$ta0,$v0
-+	sgtu	$v0,$t0,$ta0
-+	$ST	$t0,-4*$BNSZ($a0)
-+	$ADDU	$v0,$t8
-+
-+	sltu	$t9,$t1,$ta1
-+	$SUBU	$ta1,$t1,$ta1
-+	$SUBU	$t1,$ta1,$v0
-+	sgtu	$v0,$t1,$ta1
-+	$ST	$t1,-3*$BNSZ($a0)
-+	$ADDU	$v0,$t9
-+
-+
-+	sltu	$t8,$t2,$ta2
-+	$SUBU	$ta2,$t2,$ta2
-+	$SUBU	$t2,$ta2,$v0
-+	sgtu	$v0,$t2,$ta2
-+	$ST	$t2,-2*$BNSZ($a0)
-+	$ADDU	$v0,$t8
-+
-+	sltu	$t9,$t3,$ta3
-+	$SUBU	$ta3,$t3,$ta3
-+	$SUBU	$t3,$ta3,$v0
-+	sgtu	$v0,$t3,$ta3
-+	$ST	$t3,-$BNSZ($a0)
-+
-+	.set	noreorder
-+	bgtz	$at,.L_bn_sub_words_loop
-+	$ADDU	$v0,$t9
-+
-+	beqz	$a3,.L_bn_sub_words_return
-+	nop
-+
-+.L_bn_sub_words_tail:
-+	.set	reorder
-+	$LD	$t0,0($a1)
-+	$LD	$ta0,0($a2)
-+	subu	$a3,1
-+	sltu	$t8,$t0,$ta0
-+	$SUBU	$ta0,$t0,$ta0
-+	$SUBU	$t0,$ta0,$v0
-+	sgtu	$v0,$t0,$ta0
-+	$ST	$t0,0($a0)
-+	$ADDU	$v0,$t8
-+	beqz	$a3,.L_bn_sub_words_return
-+
-+	$LD	$t1,$BNSZ($a1)
-+	subu	$a3,1
-+	$LD	$ta1,$BNSZ($a2)
-+	sltu	$t9,$t1,$ta1
-+	$SUBU	$ta1,$t1,$ta1
-+	$SUBU	$t1,$ta1,$v0
-+	sgtu	$v0,$t1,$ta1
-+	$ST	$t1,$BNSZ($a0)
-+	$ADDU	$v0,$t9
-+	beqz	$a3,.L_bn_sub_words_return
-+
-+	$LD	$t2,2*$BNSZ($a1)
-+	$LD	$ta2,2*$BNSZ($a2)
-+	sltu	$t8,$t2,$ta2
-+	$SUBU	$ta2,$t2,$ta2
-+	$SUBU	$t2,$ta2,$v0
-+	sgtu	$v0,$t2,$ta2
-+	$ST	$t2,2*$BNSZ($a0)
-+	$ADDU	$v0,$t8
-+
-+.L_bn_sub_words_return:
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_sub_words_internal
-+
-+.align 5
-+.globl	bn_div_3_words
-+.ent	bn_div_3_words
-+bn_div_3_words:
-+	.set	noreorder
-+	move	$a3,$a0		# we know that bn_div_words does not
-+				# touch $a3, $ta2, $ta3 and preserves $a2
-+				# so that we can save two arguments
-+				# and return address in registers
-+				# instead of stack:-)
-+				
-+	$LD	$a0,($a3)
-+	move	$ta2,$a1
-+	bne	$a0,$a2,bn_div_3_words_internal
-+	$LD	$a1,-$BNSZ($a3)
-+	li	$v0,-1
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_div_3_words
-+
-+.align	5
-+.ent	bn_div_3_words_internal
-+bn_div_3_words_internal:
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x8000f008,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$ra,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+	.set	reorder
-+	move	$ta3,$ra
-+	bal	bn_div_words_internal
-+	move	$ra,$ta3
-+	$MULTU	$ta2,$v0
-+	$LD	$t2,-2*$BNSZ($a3)
-+	move	$ta0,$zero
-+	mfhi	$t1
-+	mflo	$t0
-+	sltu	$t8,$t1,$a1
-+.L_bn_div_3_words_inner_loop:
-+	bnez	$t8,.L_bn_div_3_words_inner_loop_done
-+	sgeu	$at,$t2,$t0
-+	seq	$t9,$t1,$a1
-+	and	$at,$t9
-+	sltu	$t3,$t0,$ta2
-+	$ADDU	$a1,$a2
-+	$SUBU	$t1,$t3
-+	$SUBU	$t0,$ta2
-+	sltu	$t8,$t1,$a1
-+	sltu	$ta0,$a1,$a2
-+	or	$t8,$ta0
-+	.set	noreorder
-+	beqz	$at,.L_bn_div_3_words_inner_loop
-+	$SUBU	$v0,1
-+	$ADDU	$v0,1
-+	.set	reorder
-+.L_bn_div_3_words_inner_loop_done:
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_div_3_words_internal
-+
-+.align	5
-+.globl	bn_div_words
-+.ent	bn_div_words
-+bn_div_words:
-+	.set	noreorder
-+	bnez	$a2,bn_div_words_internal
-+	li	$v0,-1		# I would rather signal div-by-zero
-+				# which can be done with 'break 7'
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_div_words
-+
-+.align	5
-+.ent	bn_div_words_internal
-+bn_div_words_internal:
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x8000f008,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$ra,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+	move	$v1,$zero
-+	bltz	$a2,.L_bn_div_words_body
-+	move	$t9,$v1
-+	$SLL	$a2,1
-+	bgtz	$a2,.-4
-+	addu	$t9,1
-+
-+	.set	reorder
-+	negu	$t1,$t9
-+	li	$t2,-1
-+	$SLL	$t2,$t1
-+	and	$t2,$a0
-+	$SRL	$at,$a1,$t1
-+	.set	noreorder
-+	beqz	$t2,.+12
-+	nop
-+	break	6		# signal overflow
-+	.set	reorder
-+	$SLL	$a0,$t9
-+	$SLL	$a1,$t9
-+	or	$a0,$at
-+___
-+$QT=$ta0;
-+$HH=$ta1;
-+$DH=$v1;
-+$code.=<<___;
-+.L_bn_div_words_body:
-+	$SRL	$DH,$a2,4*$BNSZ	# bits
-+	sgeu	$at,$a0,$a2
-+	.set	noreorder
-+	beqz	$at,.+12
-+	nop
-+	$SUBU	$a0,$a2
-+	.set	reorder
-+
-+	li	$QT,-1
-+	$SRL	$HH,$a0,4*$BNSZ	# bits
-+	$SRL	$QT,4*$BNSZ	# q=0xffffffff
-+	beq	$DH,$HH,.L_bn_div_words_skip_div1
-+	$DIVU	$zero,$a0,$DH
-+	mflo	$QT
-+.L_bn_div_words_skip_div1:
-+	$MULTU	$a2,$QT
-+	$SLL	$t3,$a0,4*$BNSZ	# bits
-+	$SRL	$at,$a1,4*$BNSZ	# bits
-+	or	$t3,$at
-+	mflo	$t0
-+	mfhi	$t1
-+.L_bn_div_words_inner_loop1:
-+	sltu	$t2,$t3,$t0
-+	seq	$t8,$HH,$t1
-+	sltu	$at,$HH,$t1
-+	and	$t2,$t8
-+	sltu	$v0,$t0,$a2
-+	or	$at,$t2
-+	.set	noreorder
-+	beqz	$at,.L_bn_div_words_inner_loop1_done
-+	$SUBU	$t1,$v0
-+	$SUBU	$t0,$a2
-+	b	.L_bn_div_words_inner_loop1
-+	$SUBU	$QT,1
-+	.set	reorder
-+.L_bn_div_words_inner_loop1_done:
-+
-+	$SLL	$a1,4*$BNSZ	# bits
-+	$SUBU	$a0,$t3,$t0
-+	$SLL	$v0,$QT,4*$BNSZ	# bits
-+
-+	li	$QT,-1
-+	$SRL	$HH,$a0,4*$BNSZ	# bits
-+	$SRL	$QT,4*$BNSZ	# q=0xffffffff
-+	beq	$DH,$HH,.L_bn_div_words_skip_div2
-+	$DIVU	$zero,$a0,$DH
-+	mflo	$QT
-+.L_bn_div_words_skip_div2:
-+	$MULTU	$a2,$QT
-+	$SLL	$t3,$a0,4*$BNSZ	# bits
-+	$SRL	$at,$a1,4*$BNSZ	# bits
-+	or	$t3,$at
-+	mflo	$t0
-+	mfhi	$t1
-+.L_bn_div_words_inner_loop2:
-+	sltu	$t2,$t3,$t0
-+	seq	$t8,$HH,$t1
-+	sltu	$at,$HH,$t1
-+	and	$t2,$t8
-+	sltu	$v1,$t0,$a2
-+	or	$at,$t2
-+	.set	noreorder
-+	beqz	$at,.L_bn_div_words_inner_loop2_done
-+	$SUBU	$t1,$v1
-+	$SUBU	$t0,$a2
-+	b	.L_bn_div_words_inner_loop2
-+	$SUBU	$QT,1
-+	.set	reorder
-+.L_bn_div_words_inner_loop2_done:
-+
-+	$SUBU	$a0,$t3,$t0
-+	or	$v0,$QT
-+	$SRL	$v1,$a0,$t9	# $v1 contains remainder if anybody wants it
-+	$SRL	$a2,$t9		# restore $a2
-+
-+	.set	noreorder
-+	move	$a1,$v1
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+	jr	$ra
-+	move	$a0,$v0
-+.end	bn_div_words_internal
-+___
-+undef $HH; undef $QT; undef $DH;
-+
-+($a_0,$a_1,$a_2,$a_3)=($t0,$t1,$t2,$t3);
-+($b_0,$b_1,$b_2,$b_3)=($ta0,$ta1,$ta2,$ta3);
-+
-+($a_4,$a_5,$a_6,$a_7)=($s0,$s2,$s4,$a1); # once we load a[7], no use for $a1
-+($b_4,$b_5,$b_6,$b_7)=($s1,$s3,$s5,$a2); # once we load b[7], no use for $a2
-+
-+($t_1,$t_2,$c_1,$c_2,$c_3)=($t8,$t9,$v0,$v1,$a3);
-+
-+$code.=<<___;
-+
-+.align	5
-+.globl	bn_mul_comba8
-+.ent	bn_mul_comba8
-+bn_mul_comba8:
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,12*$SZREG,$ra
-+	.mask	0x803ff008,-$SZREG
-+	$PTR_SUB $sp,12*$SZREG
-+	$REG_S	$ra,11*$SZREG($sp)
-+	$REG_S	$s5,10*$SZREG($sp)
-+	$REG_S	$s4,9*$SZREG($sp)
-+	$REG_S	$s3,8*$SZREG($sp)
-+	$REG_S	$s2,7*$SZREG($sp)
-+	$REG_S	$s1,6*$SZREG($sp)
-+	$REG_S	$s0,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour !~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x003f0000,-$SZREG
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$s5,5*$SZREG($sp)
-+	$REG_S	$s4,4*$SZREG($sp)
-+	$REG_S	$s3,3*$SZREG($sp)
-+	$REG_S	$s2,2*$SZREG($sp)
-+	$REG_S	$s1,1*$SZREG($sp)
-+	$REG_S	$s0,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+
-+	.set	reorder
-+	$LD	$a_0,0($a1)	# If compiled with -mips3 option on
-+				# R5000 box assembler barks on this
-+				# 1ine with "should not have mult/div
-+				# as last instruction in bb (R10K
-+				# bug)" warning. If anybody out there
-+				# has a clue about how to circumvent
-+				# this do send me a note.
-+				#		
-+
-+	$LD	$b_0,0($a2)
-+	$LD	$a_1,$BNSZ($a1)
-+	$LD	$a_2,2*$BNSZ($a1)
-+	$MULTU	$a_0,$b_0		# mul_add_c(a[0],b[0],c1,c2,c3);
-+	$LD	$a_3,3*$BNSZ($a1)
-+	$LD	$b_1,$BNSZ($a2)
-+	$LD	$b_2,2*$BNSZ($a2)
-+	$LD	$b_3,3*$BNSZ($a2)
-+	mflo	$c_1
-+	mfhi	$c_2
-+
-+	$LD	$a_4,4*$BNSZ($a1)
-+	$LD	$a_5,5*$BNSZ($a1)
-+	$MULTU	$a_0,$b_1		# mul_add_c(a[0],b[1],c2,c3,c1);
-+	$LD	$a_6,6*$BNSZ($a1)
-+	$LD	$a_7,7*$BNSZ($a1)
-+	$LD	$b_4,4*$BNSZ($a2)
-+	$LD	$b_5,5*$BNSZ($a2)
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_1,$b_0		# mul_add_c(a[1],b[0],c2,c3,c1);
-+	$ADDU	$c_3,$t_2,$at
-+	$LD	$b_6,6*$BNSZ($a2)
-+	$LD	$b_7,7*$BNSZ($a2)
-+	$ST	$c_1,0($a0)	# r[0]=c1;
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	 $MULTU	$a_2,$b_0		# mul_add_c(a[2],b[0],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$c_1,$c_3,$t_2
-+	$ST	$c_2,$BNSZ($a0)	# r[1]=c2;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_1,$b_1		# mul_add_c(a[1],b[1],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_0,$b_2		# mul_add_c(a[0],b[2],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$c_2,$c_1,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	 $MULTU	$a_0,$b_3		# mul_add_c(a[0],b[3],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	$ST	$c_3,2*$BNSZ($a0)	# r[2]=c3;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_1,$b_2		# mul_add_c(a[1],b[2],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$c_3,$c_2,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_2,$b_1		# mul_add_c(a[2],b[1],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_3,$b_0		# mul_add_c(a[3],b[0],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	 $MULTU	$a_4,$b_0		# mul_add_c(a[4],b[0],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	$ST	$c_1,3*$BNSZ($a0)	# r[3]=c1;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_3,$b_1		# mul_add_c(a[3],b[1],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$c_1,$c_3,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_2,$b_2		# mul_add_c(a[2],b[2],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_1,$b_3		# mul_add_c(a[1],b[3],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_0,$b_4		# mul_add_c(a[0],b[4],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	 $MULTU	$a_0,$b_5		# mul_add_c(a[0],b[5],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	$ST	$c_2,4*$BNSZ($a0)	# r[4]=c2;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_1,$b_4		# mul_add_c(a[1],b[4],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$c_2,$c_1,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_2,$b_3		# mul_add_c(a[2],b[3],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_3,$b_2		# mul_add_c(a[3],b[2],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_4,$b_1		# mul_add_c(a[4],b[1],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_5,$b_0		# mul_add_c(a[5],b[0],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	 $MULTU	$a_6,$b_0		# mul_add_c(a[6],b[0],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	$ST	$c_3,5*$BNSZ($a0)	# r[5]=c3;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_5,$b_1		# mul_add_c(a[5],b[1],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$c_3,$c_2,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_4,$b_2		# mul_add_c(a[4],b[2],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_3,$b_3		# mul_add_c(a[3],b[3],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_2,$b_4		# mul_add_c(a[2],b[4],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_1,$b_5		# mul_add_c(a[1],b[5],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_0,$b_6		# mul_add_c(a[0],b[6],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	 $MULTU	$a_0,$b_7		# mul_add_c(a[0],b[7],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	$ST	$c_1,6*$BNSZ($a0)	# r[6]=c1;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_1,$b_6		# mul_add_c(a[1],b[6],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$c_1,$c_3,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_2,$b_5		# mul_add_c(a[2],b[5],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_3,$b_4		# mul_add_c(a[3],b[4],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_4,$b_3		# mul_add_c(a[4],b[3],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_5,$b_2		# mul_add_c(a[5],b[2],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_6,$b_1		# mul_add_c(a[6],b[1],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_7,$b_0		# mul_add_c(a[7],b[0],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	 $MULTU	$a_7,$b_1		# mul_add_c(a[7],b[1],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	$ST	$c_2,7*$BNSZ($a0)	# r[7]=c2;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_6,$b_2		# mul_add_c(a[6],b[2],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$c_2,$c_1,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_5,$b_3		# mul_add_c(a[5],b[3],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_4,$b_4		# mul_add_c(a[4],b[4],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_3,$b_5		# mul_add_c(a[3],b[5],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_2,$b_6		# mul_add_c(a[2],b[6],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_1,$b_7		# mul_add_c(a[1],b[7],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	 $MULTU	$a_2,$b_7		# mul_add_c(a[2],b[7],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	$ST	$c_3,8*$BNSZ($a0)	# r[8]=c3;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_3,$b_6		# mul_add_c(a[3],b[6],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$c_3,$c_2,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_4,$b_5		# mul_add_c(a[4],b[5],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_5,$b_4		# mul_add_c(a[5],b[4],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_6,$b_3		# mul_add_c(a[6],b[3],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_7,$b_2		# mul_add_c(a[7],b[2],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	 $MULTU	$a_7,$b_3		# mul_add_c(a[7],b[3],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	$ST	$c_1,9*$BNSZ($a0)	# r[9]=c1;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_6,$b_4		# mul_add_c(a[6],b[4],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$c_1,$c_3,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_5,$b_5		# mul_add_c(a[5],b[5],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_4,$b_6		# mul_add_c(a[4],b[6],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_3,$b_7		# mul_add_c(a[3],b[7],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_4,$b_7		# mul_add_c(a[4],b[7],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	$ST	$c_2,10*$BNSZ($a0)	# r[10]=c2;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_5,$b_6		# mul_add_c(a[5],b[6],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$c_2,$c_1,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_6,$b_5		# mul_add_c(a[6],b[5],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_7,$b_4		# mul_add_c(a[7],b[4],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	 $MULTU	$a_7,$b_5		# mul_add_c(a[7],b[5],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	$ST	$c_3,11*$BNSZ($a0)	# r[11]=c3;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_6,$b_6		# mul_add_c(a[6],b[6],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$c_3,$c_2,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_5,$b_7		# mul_add_c(a[5],b[7],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	 $MULTU	$a_6,$b_7		# mul_add_c(a[6],b[7],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	$ST	$c_1,12*$BNSZ($a0)	# r[12]=c1;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_7,$b_6		# mul_add_c(a[7],b[6],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$c_1,$c_3,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_7,$b_7		# mul_add_c(a[7],b[7],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	$ST	$c_2,13*$BNSZ($a0)	# r[13]=c2;
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	$ST	$c_3,14*$BNSZ($a0)	# r[14]=c3;
-+	$ST	$c_1,15*$BNSZ($a0)	# r[15]=c1;
-+
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$s5,10*$SZREG($sp)
-+	$REG_L	$s4,9*$SZREG($sp)
-+	$REG_L	$s3,8*$SZREG($sp)
-+	$REG_L	$s2,7*$SZREG($sp)
-+	$REG_L	$s1,6*$SZREG($sp)
-+	$REG_L	$s0,5*$SZREG($sp)
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	jr	$ra
-+	$PTR_ADD $sp,12*$SZREG
-+___
-+$code.=<<___ if ($flavour !~ /nubi/i);
-+	$REG_L	$s5,5*$SZREG($sp)
-+	$REG_L	$s4,4*$SZREG($sp)
-+	$REG_L	$s3,3*$SZREG($sp)
-+	$REG_L	$s2,2*$SZREG($sp)
-+	$REG_L	$s1,1*$SZREG($sp)
-+	$REG_L	$s0,0*$SZREG($sp)
-+	jr	$ra
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+.end	bn_mul_comba8
-+
-+.align	5
-+.globl	bn_mul_comba4
-+.ent	bn_mul_comba4
-+bn_mul_comba4:
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x8000f008,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$ra,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+	.set	reorder
-+	$LD	$a_0,0($a1)
-+	$LD	$b_0,0($a2)
-+	$LD	$a_1,$BNSZ($a1)
-+	$LD	$a_2,2*$BNSZ($a1)
-+	$MULTU	$a_0,$b_0		# mul_add_c(a[0],b[0],c1,c2,c3);
-+	$LD	$a_3,3*$BNSZ($a1)
-+	$LD	$b_1,$BNSZ($a2)
-+	$LD	$b_2,2*$BNSZ($a2)
-+	$LD	$b_3,3*$BNSZ($a2)
-+	mflo	$c_1
-+	mfhi	$c_2
-+	$ST	$c_1,0($a0)
-+
-+	$MULTU	$a_0,$b_1		# mul_add_c(a[0],b[1],c2,c3,c1);
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_1,$b_0		# mul_add_c(a[1],b[0],c2,c3,c1);
-+	$ADDU	$c_3,$t_2,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	 $MULTU	$a_2,$b_0		# mul_add_c(a[2],b[0],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$c_1,$c_3,$t_2
-+	$ST	$c_2,$BNSZ($a0)
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_1,$b_1		# mul_add_c(a[1],b[1],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_0,$b_2		# mul_add_c(a[0],b[2],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$c_2,$c_1,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	 $MULTU	$a_0,$b_3		# mul_add_c(a[0],b[3],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	$ST	$c_3,2*$BNSZ($a0)
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_1,$b_2		# mul_add_c(a[1],b[2],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$c_3,$c_2,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_2,$b_1		# mul_add_c(a[2],b[1],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$MULTU	$a_3,$b_0		# mul_add_c(a[3],b[0],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	 $MULTU	$a_3,$b_1		# mul_add_c(a[3],b[1],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	$ST	$c_1,3*$BNSZ($a0)
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_2,$b_2		# mul_add_c(a[2],b[2],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$c_1,$c_3,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$MULTU	$a_1,$b_3		# mul_add_c(a[1],b[3],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	 $MULTU	$a_2,$b_3		# mul_add_c(a[2],b[3],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	$ST	$c_2,4*$BNSZ($a0)
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$MULTU	$a_3,$b_2		# mul_add_c(a[3],b[2],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$c_2,$c_1,$t_2
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	 $MULTU	$a_3,$b_3		# mul_add_c(a[3],b[3],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	$ST	$c_3,5*$BNSZ($a0)
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	$ST	$c_1,6*$BNSZ($a0)
-+	$ST	$c_2,7*$BNSZ($a0)
-+
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+	jr	$ra
-+	nop
-+.end	bn_mul_comba4
-+___
-+
-+($a_4,$a_5,$a_6,$a_7)=($b_0,$b_1,$b_2,$b_3);
-+
-+sub add_c2 () {
-+my ($hi,$lo,$c0,$c1,$c2,
-+    $warm,      # !$warm denotes first call with specific sequence of
-+                # $c_[XYZ] when there is no Z-carry to accumulate yet;
-+    $an,$bn     # these two are arguments for multiplication which
-+                # result is used in *next* step [which is why it's
-+                # commented as "forward multiplication" below];
-+    )=@_;
-+$code.=<<___;
-+	mflo	$lo
-+	mfhi	$hi
-+	$ADDU	$c0,$lo
-+	sltu	$at,$c0,$lo
-+	 $MULTU	$an,$bn			# forward multiplication
-+	$ADDU	$c0,$lo
-+	$ADDU	$at,$hi
-+	sltu	$lo,$c0,$lo
-+	$ADDU	$c1,$at
-+	$ADDU	$hi,$lo
-+___
-+$code.=<<___	if (!$warm);
-+	sltu	$c2,$c1,$at
-+	$ADDU	$c1,$hi
-+	sltu	$hi,$c1,$hi
-+	$ADDU	$c2,$hi
-+___
-+$code.=<<___	if ($warm);
-+	sltu	$at,$c1,$at
-+	$ADDU	$c1,$hi
-+	$ADDU	$c2,$at
-+	sltu	$hi,$c1,$hi
-+	$ADDU	$c2,$hi
-+___
-+}
-+
-+$code.=<<___;
-+
-+.align	5
-+.globl	bn_sqr_comba8
-+.ent	bn_sqr_comba8
-+bn_sqr_comba8:
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x8000f008,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$ra,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+	.set	reorder
-+	$LD	$a_0,0($a1)
-+	$LD	$a_1,$BNSZ($a1)
-+	$LD	$a_2,2*$BNSZ($a1)
-+	$LD	$a_3,3*$BNSZ($a1)
-+
-+	$MULTU	$a_0,$a_0		# mul_add_c(a[0],b[0],c1,c2,c3);
-+	$LD	$a_4,4*$BNSZ($a1)
-+	$LD	$a_5,5*$BNSZ($a1)
-+	$LD	$a_6,6*$BNSZ($a1)
-+	$LD	$a_7,7*$BNSZ($a1)
-+	mflo	$c_1
-+	mfhi	$c_2
-+	$ST	$c_1,0($a0)
-+
-+	$MULTU	$a_0,$a_1		# mul_add_c2(a[0],b[1],c2,c3,c1);
-+	mflo	$t_1
-+	mfhi	$t_2
-+	slt	$c_1,$t_2,$zero
-+	$SLL	$t_2,1
-+	 $MULTU	$a_2,$a_0		# mul_add_c2(a[2],b[0],c3,c1,c2);
-+	slt	$a2,$t_1,$zero
-+	$ADDU	$t_2,$a2
-+	$SLL	$t_1,1
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$ADDU	$c_3,$t_2,$at
-+	$ST	$c_2,$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
-+		$a_1,$a_1);		# mul_add_c(a[1],b[1],c3,c1,c2);
-+$code.=<<___;
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	 $MULTU	$a_0,$a_3		# mul_add_c2(a[0],b[3],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	$ST	$c_3,2*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
-+		$a_1,$a_2);		# mul_add_c2(a[1],b[2],c1,c2,c3);
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
-+		$a_4,$a_0);		# mul_add_c2(a[4],b[0],c2,c3,c1);
-+$code.=<<___;
-+	$ST	$c_1,3*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
-+		$a_3,$a_1);		# mul_add_c2(a[3],b[1],c2,c3,c1);
-+	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
-+		$a_2,$a_2);		# mul_add_c(a[2],b[2],c2,c3,c1);
-+$code.=<<___;
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	 $MULTU	$a_0,$a_5		# mul_add_c2(a[0],b[5],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	$ST	$c_2,4*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
-+		$a_1,$a_4);		# mul_add_c2(a[1],b[4],c3,c1,c2);
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
-+		$a_2,$a_3);		# mul_add_c2(a[2],b[3],c3,c1,c2);
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
-+		$a_6,$a_0);		# mul_add_c2(a[6],b[0],c1,c2,c3);
-+$code.=<<___;
-+	$ST	$c_3,5*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
-+		$a_5,$a_1);		# mul_add_c2(a[5],b[1],c1,c2,c3);
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
-+		$a_4,$a_2);		# mul_add_c2(a[4],b[2],c1,c2,c3);
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
-+		$a_3,$a_3);		# mul_add_c(a[3],b[3],c1,c2,c3);
-+$code.=<<___;
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	 $MULTU	$a_0,$a_7		# mul_add_c2(a[0],b[7],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	$ST	$c_1,6*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
-+		$a_1,$a_6);		# mul_add_c2(a[1],b[6],c2,c3,c1);
-+	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
-+		$a_2,$a_5);		# mul_add_c2(a[2],b[5],c2,c3,c1);
-+	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
-+		$a_3,$a_4);		# mul_add_c2(a[3],b[4],c2,c3,c1);
-+	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
-+		$a_7,$a_1);		# mul_add_c2(a[7],b[1],c3,c1,c2);
-+$code.=<<___;
-+	$ST	$c_2,7*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
-+		$a_6,$a_2);		# mul_add_c2(a[6],b[2],c3,c1,c2);
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
-+		$a_5,$a_3);		# mul_add_c2(a[5],b[3],c3,c1,c2);
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
-+		$a_4,$a_4);		# mul_add_c(a[4],b[4],c3,c1,c2);
-+$code.=<<___;
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	 $MULTU	$a_2,$a_7		# mul_add_c2(a[2],b[7],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	$ST	$c_3,8*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
-+		$a_3,$a_6);		# mul_add_c2(a[3],b[6],c1,c2,c3);
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
-+		$a_4,$a_5);		# mul_add_c2(a[4],b[5],c1,c2,c3);
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
-+		$a_7,$a_3);		# mul_add_c2(a[7],b[3],c2,c3,c1);
-+$code.=<<___;
-+	$ST	$c_1,9*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
-+		$a_6,$a_4);		# mul_add_c2(a[6],b[4],c2,c3,c1);
-+	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1,
-+		$a_5,$a_5);		# mul_add_c(a[5],b[5],c2,c3,c1);
-+$code.=<<___;
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	 $MULTU	$a_4,$a_7		# mul_add_c2(a[4],b[7],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	$ST	$c_2,10*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
-+		$a_5,$a_6);		# mul_add_c2(a[5],b[6],c3,c1,c2);
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1,
-+		$a_7,$a_5);		# mul_add_c2(a[7],b[5],c1,c2,c3);
-+$code.=<<___;
-+	$ST	$c_3,11*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
-+		$a_6,$a_6);		# mul_add_c(a[6],b[6],c1,c2,c3);
-+$code.=<<___;
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	 $MULTU	$a_6,$a_7		# mul_add_c2(a[6],b[7],c2,c3,c1);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	sltu	$at,$c_2,$t_2
-+	$ADDU	$c_3,$at
-+	$ST	$c_1,12*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
-+		$a_7,$a_7);		# mul_add_c(a[7],b[7],c3,c1,c2);
-+$code.=<<___;
-+	$ST	$c_2,13*$BNSZ($a0)
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	$ST	$c_3,14*$BNSZ($a0)
-+	$ST	$c_1,15*$BNSZ($a0)
-+
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+	jr	$ra
-+	nop
-+.end	bn_sqr_comba8
-+
-+.align	5
-+.globl	bn_sqr_comba4
-+.ent	bn_sqr_comba4
-+bn_sqr_comba4:
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	.frame	$sp,6*$SZREG,$ra
-+	.mask	0x8000f008,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,6*$SZREG
-+	$REG_S	$ra,5*$SZREG($sp)
-+	$REG_S	$t3,4*$SZREG($sp)
-+	$REG_S	$t2,3*$SZREG($sp)
-+	$REG_S	$t1,2*$SZREG($sp)
-+	$REG_S	$t0,1*$SZREG($sp)
-+	$REG_S	$gp,0*$SZREG($sp)
-+___
-+$code.=<<___;
-+	.set	reorder
-+	$LD	$a_0,0($a1)
-+	$LD	$a_1,$BNSZ($a1)
-+	$MULTU	$a_0,$a_0		# mul_add_c(a[0],b[0],c1,c2,c3);
-+	$LD	$a_2,2*$BNSZ($a1)
-+	$LD	$a_3,3*$BNSZ($a1)
-+	mflo	$c_1
-+	mfhi	$c_2
-+	$ST	$c_1,0($a0)
-+
-+	$MULTU	$a_0,$a_1		# mul_add_c2(a[0],b[1],c2,c3,c1);
-+	mflo	$t_1
-+	mfhi	$t_2
-+	slt	$c_1,$t_2,$zero
-+	$SLL	$t_2,1
-+	 $MULTU	$a_2,$a_0		# mul_add_c2(a[2],b[0],c3,c1,c2);
-+	slt	$a2,$t_1,$zero
-+	$ADDU	$t_2,$a2
-+	$SLL	$t_1,1
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	$ADDU	$c_3,$t_2,$at
-+	$ST	$c_2,$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
-+		$a_1,$a_1);		# mul_add_c(a[1],b[1],c3,c1,c2);
-+$code.=<<___;
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_3,$t_1
-+	sltu	$at,$c_3,$t_1
-+	 $MULTU	$a_0,$a_3		# mul_add_c2(a[0],b[3],c1,c2,c3);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_1,$t_2
-+	sltu	$at,$c_1,$t_2
-+	$ADDU	$c_2,$at
-+	$ST	$c_3,2*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0,
-+		$a_1,$a_2);		# mul_add_c2(a2[1],b[2],c1,c2,c3);
-+	&add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1,
-+		$a_3,$a_1);		# mul_add_c2(a[3],b[1],c2,c3,c1);
-+$code.=<<___;
-+	$ST	$c_1,3*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0,
-+		$a_2,$a_2);		# mul_add_c(a[2],b[2],c2,c3,c1);
-+$code.=<<___;
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_2,$t_1
-+	sltu	$at,$c_2,$t_1
-+	 $MULTU	$a_2,$a_3		# mul_add_c2(a[2],b[3],c3,c1,c2);
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_3,$t_2
-+	sltu	$at,$c_3,$t_2
-+	$ADDU	$c_1,$at
-+	$ST	$c_2,4*$BNSZ($a0)
-+___
-+	&add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0,
-+		$a_3,$a_3);		# mul_add_c(a[3],b[3],c1,c2,c3);
-+$code.=<<___;
-+	$ST	$c_3,5*$BNSZ($a0)
-+
-+	mflo	$t_1
-+	mfhi	$t_2
-+	$ADDU	$c_1,$t_1
-+	sltu	$at,$c_1,$t_1
-+	$ADDU	$t_2,$at
-+	$ADDU	$c_2,$t_2
-+	$ST	$c_1,6*$BNSZ($a0)
-+	$ST	$c_2,7*$BNSZ($a0)
-+
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$t3,4*$SZREG($sp)
-+	$REG_L	$t2,3*$SZREG($sp)
-+	$REG_L	$t1,2*$SZREG($sp)
-+	$REG_L	$t0,1*$SZREG($sp)
-+	$REG_L	$gp,0*$SZREG($sp)
-+	$PTR_ADD $sp,6*$SZREG
-+___
-+$code.=<<___;
-+	jr	$ra
-+	nop
-+.end	bn_sqr_comba4
-+___
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/pa-risc2.s b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/pa-risc2.s
-new file mode 100644
-index 0000000..413eac7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/pa-risc2.s
-@@ -0,0 +1,1624 @@
-+; Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+;
-+; Licensed under the OpenSSL license (the "License").  You may not use
-+; this file except in compliance with the License.  You can obtain a copy
-+; in the file LICENSE in the source distribution or at
-+; https://www.openssl.org/source/license.html
-+;
-+; PA-RISC 2.0 implementation of bn_asm code, based on the
-+; 64-bit version of the code.  This code is effectively the
-+; same as the 64-bit version except the register model is
-+; slightly different given all values must be 32-bit between
-+; function calls.  Thus the 64-bit return values are returned
-+; in %ret0 and %ret1 vs just %ret0 as is done in 64-bit
-+;
-+;
-+; This code is approximately 2x faster than the C version
-+; for RSA/DSA.
-+;
-+; See http://devresource.hp.com/  for more details on the PA-RISC
-+; architecture.  Also see the book "PA-RISC 2.0 Architecture"
-+; by Gerry Kane for information on the instruction set architecture.
-+;
-+; Code written by Chris Ruemmler (with some help from the HP C
-+; compiler).
-+;
-+; The code compiles with HP's assembler
-+;
-+
-+	.level	2.0N
-+	.space	$TEXT$
-+	.subspa	$CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY
-+
-+;
-+; Global Register definitions used for the routines.
-+;
-+; Some information about HP's runtime architecture for 32-bits.
-+;
-+; "Caller save" means the calling function must save the register
-+; if it wants the register to be preserved.
-+; "Callee save" means if a function uses the register, it must save
-+; the value before using it.
-+;
-+; For the floating point registers 
-+;
-+;    "caller save" registers: fr4-fr11, fr22-fr31
-+;    "callee save" registers: fr12-fr21
-+;    "special" registers: fr0-fr3 (status and exception registers)
-+;
-+; For the integer registers
-+;     value zero             :  r0
-+;     "caller save" registers: r1,r19-r26
-+;     "callee save" registers: r3-r18
-+;     return register        :  r2  (rp)
-+;     return values          ; r28,r29  (ret0,ret1)
-+;     Stack pointer          ; r30  (sp) 
-+;     millicode return ptr   ; r31  (also a caller save register)
-+
-+
-+;
-+; Arguments to the routines
-+;
-+r_ptr       .reg %r26
-+a_ptr       .reg %r25
-+b_ptr       .reg %r24
-+num         .reg %r24
-+n           .reg %r23
-+
-+;
-+; Note that the "w" argument for bn_mul_add_words and bn_mul_words
-+; is passed on the stack at a delta of -56 from the top of stack
-+; as the routine is entered.
-+;
-+
-+;
-+; Globals used in some routines
-+;
-+
-+top_overflow .reg %r23
-+high_mask    .reg %r22    ; value 0xffffffff80000000L
-+
-+
-+;------------------------------------------------------------------------------
-+;
-+; bn_mul_add_words
-+;
-+;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr, 
-+;								int num, BN_ULONG w)
-+;
-+; arg0 = r_ptr
-+; arg1 = a_ptr
-+; arg3 = num
-+; -56(sp) =  w
-+;
-+; Local register definitions
-+;
-+
-+fm1          .reg %fr22
-+fm           .reg %fr23
-+ht_temp      .reg %fr24
-+ht_temp_1    .reg %fr25
-+lt_temp      .reg %fr26
-+lt_temp_1    .reg %fr27
-+fm1_1        .reg %fr28
-+fm_1         .reg %fr29
-+
-+fw_h         .reg %fr7L
-+fw_l         .reg %fr7R
-+fw           .reg %fr7
-+
-+fht_0        .reg %fr8L
-+flt_0        .reg %fr8R
-+t_float_0    .reg %fr8
-+
-+fht_1        .reg %fr9L
-+flt_1        .reg %fr9R
-+t_float_1    .reg %fr9
-+
-+tmp_0        .reg %r31
-+tmp_1        .reg %r21
-+m_0          .reg %r20 
-+m_1          .reg %r19 
-+ht_0         .reg %r1  
-+ht_1         .reg %r3
-+lt_0         .reg %r4
-+lt_1         .reg %r5
-+m1_0         .reg %r6 
-+m1_1         .reg %r7 
-+rp_val       .reg %r8
-+rp_val_1     .reg %r9
-+
-+bn_mul_add_words
-+	.export	bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN
-+	.proc
-+	.callinfo frame=128
-+    .entry
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3  
-+    STD     %r4,8(%sp)          ; save r4  
-+	NOP                         ; Needed to make the loop 16-byte aligned
-+	NOP                         ; needed to make the loop 16-byte aligned
-+
-+    STD     %r5,16(%sp)         ; save r5  
-+	NOP
-+    STD     %r6,24(%sp)         ; save r6  
-+    STD     %r7,32(%sp)         ; save r7  
-+
-+    STD     %r8,40(%sp)         ; save r8  
-+    STD     %r9,48(%sp)         ; save r9  
-+    COPY    %r0,%ret1           ; return 0 by default
-+    DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
-+
-+    CMPIB,>= 0,num,bn_mul_add_words_exit  ; if (num <= 0) then exit
-+	LDO     128(%sp),%sp        ; bump stack
-+
-+	;
-+	; The loop is unrolled twice, so if there is only 1 number
-+    ; then go straight to the cleanup code.
-+	;
-+	CMPIB,= 1,num,bn_mul_add_words_single_top
-+	FLDD    -184(%sp),fw        ; (-56-128) load up w into fw (fw_h/fw_l)
-+
-+	;
-+	; This loop is unrolled 2 times (64-byte aligned as well)
-+	;
-+	; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
-+    ; two 32-bit mutiplies can be issued per cycle.
-+    ; 
-+bn_mul_add_words_unroll2
-+
-+    FLDD    0(a_ptr),t_float_0       ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+    FLDD    8(a_ptr),t_float_1       ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+    LDD     0(r_ptr),rp_val          ; rp[0]
-+    LDD     8(r_ptr),rp_val_1        ; rp[1]
-+
-+    XMPYU   fht_0,fw_l,fm1           ; m1[0] = fht_0*fw_l
-+    XMPYU   fht_1,fw_l,fm1_1         ; m1[1] = fht_1*fw_l
-+    FSTD    fm1,-16(%sp)             ; -16(sp) = m1[0]
-+    FSTD    fm1_1,-48(%sp)           ; -48(sp) = m1[1]
-+
-+    XMPYU   flt_0,fw_h,fm            ; m[0] = flt_0*fw_h
-+    XMPYU   flt_1,fw_h,fm_1          ; m[1] = flt_1*fw_h
-+    FSTD    fm,-8(%sp)               ; -8(sp) = m[0]
-+    FSTD    fm_1,-40(%sp)            ; -40(sp) = m[1]
-+
-+    XMPYU   fht_0,fw_h,ht_temp       ; ht_temp   = fht_0*fw_h
-+    XMPYU   fht_1,fw_h,ht_temp_1     ; ht_temp_1 = fht_1*fw_h
-+    FSTD    ht_temp,-24(%sp)         ; -24(sp)   = ht_temp
-+    FSTD    ht_temp_1,-56(%sp)       ; -56(sp)   = ht_temp_1
-+
-+    XMPYU   flt_0,fw_l,lt_temp       ; lt_temp = lt*fw_l
-+    XMPYU   flt_1,fw_l,lt_temp_1     ; lt_temp = lt*fw_l
-+    FSTD    lt_temp,-32(%sp)         ; -32(sp) = lt_temp 
-+    FSTD    lt_temp_1,-64(%sp)       ; -64(sp) = lt_temp_1 
-+
-+    LDD     -8(%sp),m_0              ; m[0] 
-+    LDD     -40(%sp),m_1             ; m[1]
-+    LDD     -16(%sp),m1_0            ; m1[0]
-+    LDD     -48(%sp),m1_1            ; m1[1]
-+
-+    LDD     -24(%sp),ht_0            ; ht[0]
-+    LDD     -56(%sp),ht_1            ; ht[1]
-+    ADD,L   m1_0,m_0,tmp_0           ; tmp_0 = m[0] + m1[0]; 
-+    ADD,L   m1_1,m_1,tmp_1           ; tmp_1 = m[1] + m1[1]; 
-+
-+    LDD     -32(%sp),lt_0            
-+    LDD     -64(%sp),lt_1            
-+    CMPCLR,*>>= tmp_0,m1_0, %r0      ; if (m[0] < m1[0])
-+    ADD,L   ht_0,top_overflow,ht_0   ; ht[0] += (1<<32)
-+
-+    CMPCLR,*>>= tmp_1,m1_1,%r0       ; if (m[1] < m1[1])
-+    ADD,L   ht_1,top_overflow,ht_1   ; ht[1] += (1<<32)
-+    EXTRD,U tmp_0,31,32,m_0          ; m[0]>>32  
-+    DEPD,Z  tmp_0,31,32,m1_0         ; m1[0] = m[0]<<32 
-+
-+    EXTRD,U tmp_1,31,32,m_1          ; m[1]>>32  
-+    DEPD,Z  tmp_1,31,32,m1_1         ; m1[1] = m[1]<<32 
-+    ADD,L   ht_0,m_0,ht_0            ; ht[0]+= (m[0]>>32)
-+    ADD,L   ht_1,m_1,ht_1            ; ht[1]+= (m[1]>>32)
-+
-+    ADD     lt_0,m1_0,lt_0           ; lt[0] = lt[0]+m1[0];
-+	ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
-+    ADD     lt_1,m1_1,lt_1           ; lt[1] = lt[1]+m1[1];
-+    ADD,DC  ht_1,%r0,ht_1            ; ht[1]++
-+
-+    ADD    %ret1,lt_0,lt_0           ; lt[0] = lt[0] + c;
-+	ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
-+    ADD     lt_0,rp_val,lt_0         ; lt[0] = lt[0]+rp[0]
-+    ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
-+
-+	LDO    -2(num),num               ; num = num - 2;
-+    ADD     ht_0,lt_1,lt_1           ; lt[1] = lt[1] + ht_0 (c);
-+    ADD,DC  ht_1,%r0,ht_1            ; ht[1]++
-+    STD     lt_0,0(r_ptr)            ; rp[0] = lt[0]
-+
-+    ADD     lt_1,rp_val_1,lt_1       ; lt[1] = lt[1]+rp[1]
-+    ADD,DC  ht_1,%r0,%ret1           ; ht[1]++
-+    LDO     16(a_ptr),a_ptr          ; a_ptr += 2
-+
-+    STD     lt_1,8(r_ptr)            ; rp[1] = lt[1]
-+	CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do
-+    LDO     16(r_ptr),r_ptr          ; r_ptr += 2
-+
-+    CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one
-+
-+	;
-+	; Top of loop aligned on 64-byte boundary
-+	;
-+bn_mul_add_words_single_top
-+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+    LDD     0(r_ptr),rp_val           ; rp[0]
-+    LDO     8(a_ptr),a_ptr            ; a_ptr++
-+    XMPYU   fht_0,fw_l,fm1            ; m1 = ht*fw_l
-+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
-+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
-+    FSTD    fm,-8(%sp)                ; -8(sp) = m
-+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = ht*fw_h
-+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
-+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
-+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
-+
-+    LDD     -8(%sp),m_0               
-+    LDD    -16(%sp),m1_0              ; m1 = temp1 
-+    ADD,L   m_0,m1_0,tmp_0            ; tmp_0 = m + m1; 
-+    LDD     -24(%sp),ht_0             
-+    LDD     -32(%sp),lt_0             
-+
-+    CMPCLR,*>>= tmp_0,m1_0,%r0        ; if (m < m1)
-+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
-+
-+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
-+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
-+
-+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
-+    ADD     lt_0,m1_0,tmp_0           ; tmp_0 = lt+m1;
-+    ADD,DC  ht_0,%r0,ht_0             ; ht++
-+    ADD     %ret1,tmp_0,lt_0          ; lt = lt + c;
-+    ADD,DC  ht_0,%r0,ht_0             ; ht++
-+    ADD     lt_0,rp_val,lt_0          ; lt = lt+rp[0]
-+    ADD,DC  ht_0,%r0,%ret1            ; ht++
-+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
-+
-+bn_mul_add_words_exit
-+    .EXIT
-+	
-+    EXTRD,U %ret1,31,32,%ret0         ; for 32-bit, return in ret0/ret1
-+    LDD     -80(%sp),%r9              ; restore r9  
-+    LDD     -88(%sp),%r8              ; restore r8  
-+    LDD     -96(%sp),%r7              ; restore r7  
-+    LDD     -104(%sp),%r6             ; restore r6  
-+    LDD     -112(%sp),%r5             ; restore r5  
-+    LDD     -120(%sp),%r4             ; restore r4  
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3             ; restore r3
-+	.PROCEND	;in=23,24,25,26,29;out=28;
-+
-+;----------------------------------------------------------------------------
-+;
-+;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
-+;
-+; arg0 = rp
-+; arg1 = ap
-+; arg3 = num
-+; w on stack at -56(sp)
-+
-+bn_mul_words
-+	.proc
-+	.callinfo frame=128
-+    .entry
-+	.EXPORT	bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3  
-+    STD     %r4,8(%sp)          ; save r4  
-+	NOP
-+    STD     %r5,16(%sp)         ; save r5  
-+
-+    STD     %r6,24(%sp)         ; save r6  
-+    STD     %r7,32(%sp)         ; save r7  
-+    COPY    %r0,%ret1           ; return 0 by default
-+    DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
-+
-+    CMPIB,>= 0,num,bn_mul_words_exit
-+	LDO     128(%sp),%sp    ; bump stack
-+
-+	;
-+	; See if only 1 word to do, thus just do cleanup
-+	;
-+	CMPIB,= 1,num,bn_mul_words_single_top
-+	FLDD    -184(%sp),fw        ; (-56-128) load up w into fw (fw_h/fw_l)
-+
-+	;
-+	; This loop is unrolled 2 times (64-byte aligned as well)
-+	;
-+	; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
-+    ; two 32-bit mutiplies can be issued per cycle.
-+    ; 
-+bn_mul_words_unroll2
-+
-+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+    FLDD    8(a_ptr),t_float_1        ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+    XMPYU   fht_0,fw_l,fm1            ; m1[0] = fht_0*fw_l
-+    XMPYU   fht_1,fw_l,fm1_1          ; m1[1] = ht*fw_l
-+
-+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
-+    FSTD    fm1_1,-48(%sp)            ; -48(sp) = m1
-+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
-+    XMPYU   flt_1,fw_h,fm_1           ; m = lt*fw_h
-+
-+    FSTD    fm,-8(%sp)                ; -8(sp) = m
-+    FSTD    fm_1,-40(%sp)             ; -40(sp) = m
-+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = fht_0*fw_h
-+    XMPYU   fht_1,fw_h,ht_temp_1      ; ht_temp = ht*fw_h
-+
-+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
-+    FSTD    ht_temp_1,-56(%sp)        ; -56(sp) = ht
-+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
-+    XMPYU   flt_1,fw_l,lt_temp_1      ; lt_temp = lt*fw_l
-+
-+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
-+    FSTD    lt_temp_1,-64(%sp)        ; -64(sp) = lt 
-+    LDD     -8(%sp),m_0               
-+    LDD     -40(%sp),m_1              
-+
-+    LDD    -16(%sp),m1_0              
-+    LDD    -48(%sp),m1_1              
-+    LDD     -24(%sp),ht_0             
-+    LDD     -56(%sp),ht_1             
-+
-+    ADD,L   m1_0,m_0,tmp_0            ; tmp_0 = m + m1; 
-+    ADD,L   m1_1,m_1,tmp_1            ; tmp_1 = m + m1; 
-+    LDD     -32(%sp),lt_0             
-+    LDD     -64(%sp),lt_1             
-+
-+    CMPCLR,*>>= tmp_0,m1_0, %r0       ; if (m < m1)
-+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
-+    CMPCLR,*>>= tmp_1,m1_1,%r0        ; if (m < m1)
-+    ADD,L   ht_1,top_overflow,ht_1    ; ht += (1<<32)
-+
-+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
-+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
-+    EXTRD,U tmp_1,31,32,m_1           ; m>>32  
-+    DEPD,Z  tmp_1,31,32,m1_1          ; m1 = m<<32 
-+
-+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
-+    ADD,L   ht_1,m_1,ht_1             ; ht+= (m>>32)
-+    ADD     lt_0,m1_0,lt_0            ; lt = lt+m1;
-+	ADD,DC  ht_0,%r0,ht_0             ; ht++
-+
-+    ADD     lt_1,m1_1,lt_1            ; lt = lt+m1;
-+    ADD,DC  ht_1,%r0,ht_1             ; ht++
-+    ADD    %ret1,lt_0,lt_0            ; lt = lt + c (ret1);
-+	ADD,DC  ht_0,%r0,ht_0             ; ht++
-+
-+    ADD     ht_0,lt_1,lt_1            ; lt = lt + c (ht_0)
-+    ADD,DC  ht_1,%r0,ht_1             ; ht++
-+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
-+    STD     lt_1,8(r_ptr)             ; rp[1] = lt
-+
-+	COPY    ht_1,%ret1                ; carry = ht
-+	LDO    -2(num),num                ; num = num - 2;
-+    LDO     16(a_ptr),a_ptr           ; ap += 2
-+	CMPIB,<= 2,num,bn_mul_words_unroll2
-+    LDO     16(r_ptr),r_ptr           ; rp++
-+
-+    CMPIB,=,N 0,num,bn_mul_words_exit ; are we done?
-+
-+	;
-+	; Top of loop aligned on 64-byte boundary
-+	;
-+bn_mul_words_single_top
-+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+
-+    XMPYU   fht_0,fw_l,fm1            ; m1 = ht*fw_l
-+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
-+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
-+    FSTD    fm,-8(%sp)                ; -8(sp) = m
-+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = ht*fw_h
-+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
-+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
-+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
-+
-+    LDD     -8(%sp),m_0               
-+    LDD    -16(%sp),m1_0              
-+    ADD,L   m_0,m1_0,tmp_0            ; tmp_0 = m + m1; 
-+    LDD     -24(%sp),ht_0             
-+    LDD     -32(%sp),lt_0             
-+
-+    CMPCLR,*>>= tmp_0,m1_0,%r0        ; if (m < m1)
-+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
-+
-+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
-+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
-+
-+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
-+    ADD     lt_0,m1_0,lt_0            ; lt= lt+m1;
-+    ADD,DC  ht_0,%r0,ht_0             ; ht++
-+
-+    ADD     %ret1,lt_0,lt_0           ; lt = lt + c;
-+    ADD,DC  ht_0,%r0,ht_0             ; ht++
-+
-+    COPY    ht_0,%ret1                ; copy carry
-+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
-+
-+bn_mul_words_exit
-+    .EXIT
-+    EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
-+    LDD     -96(%sp),%r7              ; restore r7  
-+    LDD     -104(%sp),%r6             ; restore r6  
-+    LDD     -112(%sp),%r5             ; restore r5  
-+    LDD     -120(%sp),%r4             ; restore r4  
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3             ; restore r3
-+	.PROCEND	
-+
-+;----------------------------------------------------------------------------
-+;
-+;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
-+;
-+; arg0 = rp
-+; arg1 = ap
-+; arg2 = num
-+;
-+
-+bn_sqr_words
-+	.proc
-+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .entry
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3  
-+    STD     %r4,8(%sp)          ; save r4  
-+	NOP
-+    STD     %r5,16(%sp)         ; save r5  
-+
-+    CMPIB,>= 0,num,bn_sqr_words_exit
-+	LDO     128(%sp),%sp       ; bump stack
-+
-+	;
-+	; If only 1, the goto straight to cleanup
-+	;
-+	CMPIB,= 1,num,bn_sqr_words_single_top
-+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
-+
-+	;
-+	; This loop is unrolled 2 times (64-byte aligned as well)
-+	;
-+
-+bn_sqr_words_unroll2
-+    FLDD    0(a_ptr),t_float_0        ; a[0]
-+    FLDD    8(a_ptr),t_float_1        ; a[1]
-+    XMPYU   fht_0,flt_0,fm            ; m[0]
-+    XMPYU   fht_1,flt_1,fm_1          ; m[1]
-+
-+    FSTD    fm,-24(%sp)               ; store m[0]
-+    FSTD    fm_1,-56(%sp)             ; store m[1]
-+    XMPYU   flt_0,flt_0,lt_temp       ; lt[0]
-+    XMPYU   flt_1,flt_1,lt_temp_1     ; lt[1]
-+
-+    FSTD    lt_temp,-16(%sp)          ; store lt[0]
-+    FSTD    lt_temp_1,-48(%sp)        ; store lt[1]
-+    XMPYU   fht_0,fht_0,ht_temp       ; ht[0]
-+    XMPYU   fht_1,fht_1,ht_temp_1     ; ht[1]
-+
-+    FSTD    ht_temp,-8(%sp)           ; store ht[0]
-+    FSTD    ht_temp_1,-40(%sp)        ; store ht[1]
-+    LDD     -24(%sp),m_0             
-+    LDD     -56(%sp),m_1              
-+
-+    AND     m_0,high_mask,tmp_0       ; m[0] & Mask
-+    AND     m_1,high_mask,tmp_1       ; m[1] & Mask
-+    DEPD,Z  m_0,30,31,m_0             ; m[0] << 32+1
-+    DEPD,Z  m_1,30,31,m_1             ; m[1] << 32+1
-+
-+    LDD     -16(%sp),lt_0        
-+    LDD     -48(%sp),lt_1        
-+    EXTRD,U tmp_0,32,33,tmp_0         ; tmp_0 = m[0]&Mask >> 32-1
-+    EXTRD,U tmp_1,32,33,tmp_1         ; tmp_1 = m[1]&Mask >> 32-1
-+
-+    LDD     -8(%sp),ht_0            
-+    LDD     -40(%sp),ht_1           
-+    ADD,L   ht_0,tmp_0,ht_0           ; ht[0] += tmp_0
-+    ADD,L   ht_1,tmp_1,ht_1           ; ht[1] += tmp_1
-+
-+    ADD     lt_0,m_0,lt_0             ; lt = lt+m
-+    ADD,DC  ht_0,%r0,ht_0             ; ht[0]++
-+    STD     lt_0,0(r_ptr)             ; rp[0] = lt[0]
-+    STD     ht_0,8(r_ptr)             ; rp[1] = ht[1]
-+
-+    ADD     lt_1,m_1,lt_1             ; lt = lt+m
-+    ADD,DC  ht_1,%r0,ht_1             ; ht[1]++
-+    STD     lt_1,16(r_ptr)            ; rp[2] = lt[1]
-+    STD     ht_1,24(r_ptr)            ; rp[3] = ht[1]
-+
-+	LDO    -2(num),num                ; num = num - 2;
-+    LDO     16(a_ptr),a_ptr           ; ap += 2
-+	CMPIB,<= 2,num,bn_sqr_words_unroll2
-+    LDO     32(r_ptr),r_ptr           ; rp += 4
-+
-+    CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done?
-+
-+	;
-+	; Top of loop aligned on 64-byte boundary
-+	;
-+bn_sqr_words_single_top
-+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+
-+    XMPYU   fht_0,flt_0,fm            ; m
-+    FSTD    fm,-24(%sp)               ; store m
-+
-+    XMPYU   flt_0,flt_0,lt_temp       ; lt
-+    FSTD    lt_temp,-16(%sp)          ; store lt
-+
-+    XMPYU   fht_0,fht_0,ht_temp       ; ht
-+    FSTD    ht_temp,-8(%sp)           ; store ht
-+
-+    LDD     -24(%sp),m_0              ; load m
-+    AND     m_0,high_mask,tmp_0       ; m & Mask
-+    DEPD,Z  m_0,30,31,m_0             ; m << 32+1
-+    LDD     -16(%sp),lt_0             ; lt
-+
-+    LDD     -8(%sp),ht_0              ; ht
-+    EXTRD,U tmp_0,32,33,tmp_0         ; tmp_0 = m&Mask >> 32-1
-+    ADD     m_0,lt_0,lt_0             ; lt = lt+m
-+    ADD,L   ht_0,tmp_0,ht_0           ; ht += tmp_0
-+    ADD,DC  ht_0,%r0,ht_0             ; ht++
-+
-+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
-+    STD     ht_0,8(r_ptr)             ; rp[1] = ht
-+
-+bn_sqr_words_exit
-+    .EXIT
-+    LDD     -112(%sp),%r5       ; restore r5  
-+    LDD     -120(%sp),%r4       ; restore r4  
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3 
-+	.PROCEND	;in=23,24,25,26,29;out=28;
-+
-+
-+;----------------------------------------------------------------------------
-+;
-+;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
-+;
-+; arg0 = rp 
-+; arg1 = ap
-+; arg2 = bp 
-+; arg3 = n
-+
-+t  .reg %r22
-+b  .reg %r21
-+l  .reg %r20
-+
-+bn_add_words
-+	.proc
-+    .entry
-+	.callinfo
-+	.EXPORT	bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+	.align 64
-+
-+    CMPIB,>= 0,n,bn_add_words_exit
-+    COPY    %r0,%ret1           ; return 0 by default
-+
-+	;
-+	; If 2 or more numbers do the loop
-+	;
-+	CMPIB,= 1,n,bn_add_words_single_top
-+	NOP
-+
-+	;
-+	; This loop is unrolled 2 times (64-byte aligned as well)
-+	;
-+bn_add_words_unroll2
-+	LDD     0(a_ptr),t
-+	LDD     0(b_ptr),b
-+	ADD     t,%ret1,t                    ; t = t+c;
-+	ADD,DC  %r0,%r0,%ret1                ; set c to carry
-+	ADD     t,b,l                        ; l = t + b[0]
-+	ADD,DC  %ret1,%r0,%ret1              ; c+= carry
-+	STD     l,0(r_ptr)
-+
-+	LDD     8(a_ptr),t
-+	LDD     8(b_ptr),b
-+	ADD     t,%ret1,t                     ; t = t+c;
-+	ADD,DC  %r0,%r0,%ret1                 ; set c to carry
-+	ADD     t,b,l                         ; l = t + b[0]
-+	ADD,DC  %ret1,%r0,%ret1               ; c+= carry
-+	STD     l,8(r_ptr)
-+
-+	LDO     -2(n),n
-+	LDO     16(a_ptr),a_ptr
-+	LDO     16(b_ptr),b_ptr
-+
-+	CMPIB,<= 2,n,bn_add_words_unroll2
-+	LDO     16(r_ptr),r_ptr
-+
-+    CMPIB,=,N 0,n,bn_add_words_exit ; are we done?
-+
-+bn_add_words_single_top
-+	LDD     0(a_ptr),t
-+	LDD     0(b_ptr),b
-+
-+	ADD     t,%ret1,t                 ; t = t+c;
-+	ADD,DC  %r0,%r0,%ret1             ; set c to carry (could use CMPCLR??)
-+	ADD     t,b,l                     ; l = t + b[0]
-+	ADD,DC  %ret1,%r0,%ret1           ; c+= carry
-+	STD     l,0(r_ptr)
-+
-+bn_add_words_exit
-+    .EXIT
-+    BVE     (%rp)
-+    EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
-+	.PROCEND	;in=23,24,25,26,29;out=28;
-+
-+;----------------------------------------------------------------------------
-+;
-+;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
-+;
-+; arg0 = rp 
-+; arg1 = ap
-+; arg2 = bp 
-+; arg3 = n
-+
-+t1       .reg %r22
-+t2       .reg %r21
-+sub_tmp1 .reg %r20
-+sub_tmp2 .reg %r19
-+
-+
-+bn_sub_words
-+	.proc
-+	.callinfo 
-+	.EXPORT	bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .entry
-+	.align 64
-+
-+    CMPIB,>=  0,n,bn_sub_words_exit
-+    COPY    %r0,%ret1           ; return 0 by default
-+
-+	;
-+	; If 2 or more numbers do the loop
-+	;
-+	CMPIB,= 1,n,bn_sub_words_single_top
-+	NOP
-+
-+	;
-+	; This loop is unrolled 2 times (64-byte aligned as well)
-+	;
-+bn_sub_words_unroll2
-+	LDD     0(a_ptr),t1
-+	LDD     0(b_ptr),t2
-+	SUB     t1,t2,sub_tmp1           ; t3 = t1-t2; 
-+	SUB     sub_tmp1,%ret1,sub_tmp1  ; t3 = t3- c; 
-+
-+	CMPCLR,*>> t1,t2,sub_tmp2        ; clear if t1 > t2
-+	LDO      1(%r0),sub_tmp2
-+	
-+	CMPCLR,*= t1,t2,%r0
-+	COPY    sub_tmp2,%ret1
-+	STD     sub_tmp1,0(r_ptr)
-+
-+	LDD     8(a_ptr),t1
-+	LDD     8(b_ptr),t2
-+	SUB     t1,t2,sub_tmp1            ; t3 = t1-t2; 
-+	SUB     sub_tmp1,%ret1,sub_tmp1   ; t3 = t3- c; 
-+	CMPCLR,*>> t1,t2,sub_tmp2         ; clear if t1 > t2
-+	LDO      1(%r0),sub_tmp2
-+	
-+	CMPCLR,*= t1,t2,%r0
-+	COPY    sub_tmp2,%ret1
-+	STD     sub_tmp1,8(r_ptr)
-+
-+	LDO     -2(n),n
-+	LDO     16(a_ptr),a_ptr
-+	LDO     16(b_ptr),b_ptr
-+
-+	CMPIB,<= 2,n,bn_sub_words_unroll2
-+	LDO     16(r_ptr),r_ptr
-+
-+    CMPIB,=,N 0,n,bn_sub_words_exit ; are we done?
-+
-+bn_sub_words_single_top
-+	LDD     0(a_ptr),t1
-+	LDD     0(b_ptr),t2
-+	SUB     t1,t2,sub_tmp1            ; t3 = t1-t2; 
-+	SUB     sub_tmp1,%ret1,sub_tmp1   ; t3 = t3- c; 
-+	CMPCLR,*>> t1,t2,sub_tmp2         ; clear if t1 > t2
-+	LDO      1(%r0),sub_tmp2
-+	
-+	CMPCLR,*= t1,t2,%r0
-+	COPY    sub_tmp2,%ret1
-+
-+	STD     sub_tmp1,0(r_ptr)
-+
-+bn_sub_words_exit
-+    .EXIT
-+    BVE     (%rp)
-+    EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
-+	.PROCEND	;in=23,24,25,26,29;out=28;
-+
-+;------------------------------------------------------------------------------
-+;
-+; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d)
-+;
-+; arg0 = h
-+; arg1 = l
-+; arg2 = d
-+;
-+; This is mainly just output from the HP C compiler.  
-+;
-+;------------------------------------------------------------------------------
-+bn_div_words
-+	.PROC
-+	.EXPORT	bn_div_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR,LONG_RETURN
-+	.IMPORT	BN_num_bits_word,CODE
-+	;--- not PIC	.IMPORT	__iob,DATA
-+	;--- not PIC	.IMPORT	fprintf,CODE
-+	.IMPORT	abort,CODE
-+	.IMPORT	$$div2U,MILLICODE
-+	.CALLINFO CALLER,FRAME=144,ENTRY_GR=%r9,SAVE_RP,ARGS_SAVED,ORDERING_AWARE
-+        .ENTRY
-+        STW     %r2,-20(%r30)   ;offset 0x8ec
-+        STW,MA  %r3,192(%r30)   ;offset 0x8f0
-+        STW     %r4,-188(%r30)  ;offset 0x8f4
-+        DEPD    %r5,31,32,%r6   ;offset 0x8f8
-+        STD     %r6,-184(%r30)  ;offset 0x8fc
-+        DEPD    %r7,31,32,%r8   ;offset 0x900
-+        STD     %r8,-176(%r30)  ;offset 0x904
-+        STW     %r9,-168(%r30)  ;offset 0x908
-+        LDD     -248(%r30),%r3  ;offset 0x90c
-+        COPY    %r26,%r4        ;offset 0x910
-+        COPY    %r24,%r5        ;offset 0x914
-+        DEPD    %r25,31,32,%r4  ;offset 0x918
-+        CMPB,*<>        %r3,%r0,$0006000C       ;offset 0x91c
-+        DEPD    %r23,31,32,%r5  ;offset 0x920
-+        MOVIB,TR        -1,%r29,$00060002       ;offset 0x924
-+        EXTRD,U %r29,31,32,%r28 ;offset 0x928
-+$0006002A
-+        LDO     -1(%r29),%r29   ;offset 0x92c
-+        SUB     %r23,%r7,%r23   ;offset 0x930
-+$00060024
-+        SUB     %r4,%r31,%r25   ;offset 0x934
-+        AND     %r25,%r19,%r26  ;offset 0x938
-+        CMPB,*<>,N      %r0,%r26,$00060046      ;offset 0x93c
-+        DEPD,Z  %r25,31,32,%r20 ;offset 0x940
-+        OR      %r20,%r24,%r21  ;offset 0x944
-+        CMPB,*<<,N      %r21,%r23,$0006002A     ;offset 0x948
-+        SUB     %r31,%r2,%r31   ;offset 0x94c
-+$00060046
-+$0006002E
-+        DEPD,Z  %r23,31,32,%r25 ;offset 0x950
-+        EXTRD,U %r23,31,32,%r26 ;offset 0x954
-+        AND     %r25,%r19,%r24  ;offset 0x958
-+        ADD,L   %r31,%r26,%r31  ;offset 0x95c
-+        CMPCLR,*>>=     %r5,%r24,%r0    ;offset 0x960
-+        LDO     1(%r31),%r31    ;offset 0x964
-+$00060032
-+        CMPB,*<<=,N     %r31,%r4,$00060036      ;offset 0x968
-+        LDO     -1(%r29),%r29   ;offset 0x96c
-+        ADD,L   %r4,%r3,%r4     ;offset 0x970
-+$00060036
-+        ADDIB,=,N       -1,%r8,$D0      ;offset 0x974
-+        SUB     %r5,%r24,%r28   ;offset 0x978
-+$0006003A
-+        SUB     %r4,%r31,%r24   ;offset 0x97c
-+        SHRPD   %r24,%r28,32,%r4        ;offset 0x980
-+        DEPD,Z  %r29,31,32,%r9  ;offset 0x984
-+        DEPD,Z  %r28,31,32,%r5  ;offset 0x988
-+$0006001C
-+        EXTRD,U %r4,31,32,%r31  ;offset 0x98c
-+        CMPB,*<>,N      %r31,%r2,$00060020      ;offset 0x990
-+        MOVB,TR %r6,%r29,$D1    ;offset 0x994
-+        STD     %r29,-152(%r30) ;offset 0x998
-+$0006000C
-+        EXTRD,U %r3,31,32,%r25  ;offset 0x99c
-+        COPY    %r3,%r26        ;offset 0x9a0
-+        EXTRD,U %r3,31,32,%r9   ;offset 0x9a4
-+        EXTRD,U %r4,31,32,%r8   ;offset 0x9a8
-+        .CALL   ARGW0=GR,ARGW1=GR,RTNVAL=GR     ;in=25,26;out=28;
-+        B,L     BN_num_bits_word,%r2    ;offset 0x9ac
-+        EXTRD,U %r5,31,32,%r7   ;offset 0x9b0
-+        LDI     64,%r20 ;offset 0x9b4
-+        DEPD    %r7,31,32,%r5   ;offset 0x9b8
-+        DEPD    %r8,31,32,%r4   ;offset 0x9bc
-+        DEPD    %r9,31,32,%r3   ;offset 0x9c0
-+        CMPB,=  %r28,%r20,$00060012     ;offset 0x9c4
-+        COPY    %r28,%r24       ;offset 0x9c8
-+        MTSARCM %r24    ;offset 0x9cc
-+        DEPDI,Z -1,%sar,1,%r19  ;offset 0x9d0
-+        CMPB,*>>,N      %r4,%r19,$D2    ;offset 0x9d4
-+$00060012
-+        SUBI    64,%r24,%r31    ;offset 0x9d8
-+        CMPCLR,*<<      %r4,%r3,%r0     ;offset 0x9dc
-+        SUB     %r4,%r3,%r4     ;offset 0x9e0
-+$00060016
-+        CMPB,=  %r31,%r0,$0006001A      ;offset 0x9e4
-+        COPY    %r0,%r9 ;offset 0x9e8
-+        MTSARCM %r31    ;offset 0x9ec
-+        DEPD,Z  %r3,%sar,64,%r3 ;offset 0x9f0
-+        SUBI    64,%r31,%r26    ;offset 0x9f4
-+        MTSAR   %r26    ;offset 0x9f8
-+        SHRPD   %r4,%r5,%sar,%r4        ;offset 0x9fc
-+        MTSARCM %r31    ;offset 0xa00
-+        DEPD,Z  %r5,%sar,64,%r5 ;offset 0xa04
-+$0006001A
-+        DEPDI,Z -1,31,32,%r19   ;offset 0xa08
-+        AND     %r3,%r19,%r29   ;offset 0xa0c
-+        EXTRD,U %r29,31,32,%r2  ;offset 0xa10
-+        DEPDI,Z -1,63,32,%r6    ;offset 0xa14
-+        MOVIB,TR        2,%r8,$0006001C ;offset 0xa18
-+        EXTRD,U %r3,63,32,%r7   ;offset 0xa1c
-+$D2
-+        ;--- not PIC	ADDIL   LR'__iob-$global$,%r27,%r1      ;offset 0xa20
-+        ;--- not PIC	LDIL    LR'C$7,%r21     ;offset 0xa24
-+        ;--- not PIC	LDO     RR'__iob-$global$+32(%r1),%r26  ;offset 0xa28
-+        ;--- not PIC	.CALL   ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR    ;in=24,25,26;out=28;
-+        ;--- not PIC	B,L     fprintf,%r2     ;offset 0xa2c
-+        ;--- not PIC	LDO     RR'C$7(%r21),%r25       ;offset 0xa30
-+        .CALL           ;
-+        B,L     abort,%r2       ;offset 0xa34
-+        NOP             ;offset 0xa38
-+        B       $D3     ;offset 0xa3c
-+        LDW     -212(%r30),%r2  ;offset 0xa40
-+$00060020
-+        COPY    %r4,%r26        ;offset 0xa44
-+        EXTRD,U %r4,31,32,%r25  ;offset 0xa48
-+        COPY    %r2,%r24        ;offset 0xa4c
-+        .CALL   ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL)
-+        B,L     $$div2U,%r31    ;offset 0xa50
-+        EXTRD,U %r2,31,32,%r23  ;offset 0xa54
-+        DEPD    %r28,31,32,%r29 ;offset 0xa58
-+$00060022
-+        STD     %r29,-152(%r30) ;offset 0xa5c
-+$D1
-+        AND     %r5,%r19,%r24   ;offset 0xa60
-+        EXTRD,U %r24,31,32,%r24 ;offset 0xa64
-+        STW     %r2,-160(%r30)  ;offset 0xa68
-+        STW     %r7,-128(%r30)  ;offset 0xa6c
-+        FLDD    -152(%r30),%fr4 ;offset 0xa70
-+        FLDD    -152(%r30),%fr7 ;offset 0xa74
-+        FLDW    -160(%r30),%fr8L        ;offset 0xa78
-+        FLDW    -128(%r30),%fr5L        ;offset 0xa7c
-+        XMPYU   %fr8L,%fr7L,%fr10       ;offset 0xa80
-+        FSTD    %fr10,-136(%r30)        ;offset 0xa84
-+        XMPYU   %fr8L,%fr7R,%fr22       ;offset 0xa88
-+        FSTD    %fr22,-144(%r30)        ;offset 0xa8c
-+        XMPYU   %fr5L,%fr4L,%fr11       ;offset 0xa90
-+        XMPYU   %fr5L,%fr4R,%fr23       ;offset 0xa94
-+        FSTD    %fr11,-112(%r30)        ;offset 0xa98
-+        FSTD    %fr23,-120(%r30)        ;offset 0xa9c
-+        LDD     -136(%r30),%r28 ;offset 0xaa0
-+        DEPD,Z  %r28,31,32,%r31 ;offset 0xaa4
-+        LDD     -144(%r30),%r20 ;offset 0xaa8
-+        ADD,L   %r20,%r31,%r31  ;offset 0xaac
-+        LDD     -112(%r30),%r22 ;offset 0xab0
-+        DEPD,Z  %r22,31,32,%r22 ;offset 0xab4
-+        LDD     -120(%r30),%r21 ;offset 0xab8
-+        B       $00060024       ;offset 0xabc
-+        ADD,L   %r21,%r22,%r23  ;offset 0xac0
-+$D0
-+        OR      %r9,%r29,%r29   ;offset 0xac4
-+$00060040
-+        EXTRD,U %r29,31,32,%r28 ;offset 0xac8
-+$00060002
-+$L2
-+        LDW     -212(%r30),%r2  ;offset 0xacc
-+$D3
-+        LDW     -168(%r30),%r9  ;offset 0xad0
-+        LDD     -176(%r30),%r8  ;offset 0xad4
-+        EXTRD,U %r8,31,32,%r7   ;offset 0xad8
-+        LDD     -184(%r30),%r6  ;offset 0xadc
-+        EXTRD,U %r6,31,32,%r5   ;offset 0xae0
-+        LDW     -188(%r30),%r4  ;offset 0xae4
-+        BVE     (%r2)   ;offset 0xae8
-+        .EXIT
-+        LDW,MB  -192(%r30),%r3  ;offset 0xaec
-+	.PROCEND	;in=23,25;out=28,29;fpin=105,107;
-+
-+
-+
-+
-+;----------------------------------------------------------------------------
-+;
-+; Registers to hold 64-bit values to manipulate.  The "L" part
-+; of the register corresponds to the upper 32-bits, while the "R"
-+; part corresponds to the lower 32-bits
-+; 
-+; Note, that when using b6 and b7, the code must save these before
-+; using them because they are callee save registers 
-+; 
-+;
-+; Floating point registers to use to save values that
-+; are manipulated.  These don't collide with ftemp1-6 and
-+; are all caller save registers
-+;
-+a0        .reg %fr22
-+a0L       .reg %fr22L
-+a0R       .reg %fr22R
-+
-+a1        .reg %fr23
-+a1L       .reg %fr23L
-+a1R       .reg %fr23R
-+
-+a2        .reg %fr24
-+a2L       .reg %fr24L
-+a2R       .reg %fr24R
-+
-+a3        .reg %fr25
-+a3L       .reg %fr25L
-+a3R       .reg %fr25R
-+
-+a4        .reg %fr26
-+a4L       .reg %fr26L
-+a4R       .reg %fr26R
-+
-+a5        .reg %fr27
-+a5L       .reg %fr27L
-+a5R       .reg %fr27R
-+
-+a6        .reg %fr28
-+a6L       .reg %fr28L
-+a6R       .reg %fr28R
-+
-+a7        .reg %fr29
-+a7L       .reg %fr29L
-+a7R       .reg %fr29R
-+
-+b0        .reg %fr30
-+b0L       .reg %fr30L
-+b0R       .reg %fr30R
-+
-+b1        .reg %fr31
-+b1L       .reg %fr31L
-+b1R       .reg %fr31R
-+
-+;
-+; Temporary floating point variables, these are all caller save
-+; registers
-+;
-+ftemp1    .reg %fr4
-+ftemp2    .reg %fr5
-+ftemp3    .reg %fr6
-+ftemp4    .reg %fr7
-+
-+;
-+; The B set of registers when used.
-+;
-+
-+b2        .reg %fr8
-+b2L       .reg %fr8L
-+b2R       .reg %fr8R
-+
-+b3        .reg %fr9
-+b3L       .reg %fr9L
-+b3R       .reg %fr9R
-+
-+b4        .reg %fr10
-+b4L       .reg %fr10L
-+b4R       .reg %fr10R
-+
-+b5        .reg %fr11
-+b5L       .reg %fr11L
-+b5R       .reg %fr11R
-+
-+b6        .reg %fr12
-+b6L       .reg %fr12L
-+b6R       .reg %fr12R
-+
-+b7        .reg %fr13
-+b7L       .reg %fr13L
-+b7R       .reg %fr13R
-+
-+c1           .reg %r21   ; only reg
-+temp1        .reg %r20   ; only reg
-+temp2        .reg %r19   ; only reg
-+temp3        .reg %r31   ; only reg
-+
-+m1           .reg %r28   
-+c2           .reg %r23   
-+high_one     .reg %r1
-+ht           .reg %r6
-+lt           .reg %r5
-+m            .reg %r4
-+c3           .reg %r3
-+
-+SQR_ADD_C  .macro  A0L,A0R,C1,C2,C3
-+    XMPYU   A0L,A0R,ftemp1       ; m
-+    FSTD    ftemp1,-24(%sp)      ; store m
-+
-+    XMPYU   A0R,A0R,ftemp2       ; lt
-+    FSTD    ftemp2,-16(%sp)      ; store lt
-+
-+    XMPYU   A0L,A0L,ftemp3       ; ht
-+    FSTD    ftemp3,-8(%sp)       ; store ht
-+
-+    LDD     -24(%sp),m           ; load m
-+    AND     m,high_mask,temp2    ; m & Mask
-+    DEPD,Z  m,30,31,temp3        ; m << 32+1
-+    LDD     -16(%sp),lt          ; lt
-+
-+    LDD     -8(%sp),ht           ; ht
-+    EXTRD,U temp2,32,33,temp1    ; temp1 = m&Mask >> 32-1
-+    ADD     temp3,lt,lt          ; lt = lt+m
-+    ADD,L   ht,temp1,ht          ; ht += temp1
-+    ADD,DC  ht,%r0,ht            ; ht++
-+
-+    ADD     C1,lt,C1             ; c1=c1+lt
-+    ADD,DC  ht,%r0,ht            ; ht++
-+
-+    ADD     C2,ht,C2             ; c2=c2+ht
-+    ADD,DC  C3,%r0,C3            ; c3++
-+.endm
-+
-+SQR_ADD_C2 .macro  A0L,A0R,A1L,A1R,C1,C2,C3
-+    XMPYU   A0L,A1R,ftemp1          ; m1 = bl*ht
-+    FSTD    ftemp1,-16(%sp)         ;
-+    XMPYU   A0R,A1L,ftemp2          ; m = bh*lt
-+    FSTD    ftemp2,-8(%sp)          ;
-+    XMPYU   A0R,A1R,ftemp3          ; lt = bl*lt
-+    FSTD    ftemp3,-32(%sp)
-+    XMPYU   A0L,A1L,ftemp4          ; ht = bh*ht
-+    FSTD    ftemp4,-24(%sp)         ;
-+
-+    LDD     -8(%sp),m               ; r21 = m
-+    LDD     -16(%sp),m1             ; r19 = m1
-+    ADD,L   m,m1,m                  ; m+m1
-+
-+    DEPD,Z  m,31,32,temp3           ; (m+m1<<32)
-+    LDD     -24(%sp),ht             ; r24 = ht
-+
-+    CMPCLR,*>>= m,m1,%r0            ; if (m < m1)
-+    ADD,L   ht,high_one,ht          ; ht+=high_one
-+
-+    EXTRD,U m,31,32,temp1           ; m >> 32
-+    LDD     -32(%sp),lt             ; lt
-+    ADD,L   ht,temp1,ht             ; ht+= m>>32
-+    ADD     lt,temp3,lt             ; lt = lt+m1
-+    ADD,DC  ht,%r0,ht               ; ht++
-+
-+    ADD     ht,ht,ht                ; ht=ht+ht;
-+    ADD,DC  C3,%r0,C3               ; add in carry (c3++)
-+
-+    ADD     lt,lt,lt                ; lt=lt+lt;
-+    ADD,DC  ht,%r0,ht               ; add in carry (ht++)
-+
-+    ADD     C1,lt,C1                ; c1=c1+lt
-+    ADD,DC,*NUV ht,%r0,ht           ; add in carry (ht++)
-+    LDO     1(C3),C3              ; bump c3 if overflow,nullify otherwise
-+
-+    ADD     C2,ht,C2                ; c2 = c2 + ht
-+    ADD,DC  C3,%r0,C3             ; add in carry (c3++)
-+.endm
-+
-+;
-+;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
-+; arg0 = r_ptr
-+; arg1 = a_ptr
-+;
-+
-+bn_sqr_comba8
-+	.PROC
-+	.CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .ENTRY
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3
-+    STD     %r4,8(%sp)          ; save r4
-+    STD     %r5,16(%sp)         ; save r5
-+    STD     %r6,24(%sp)         ; save r6
-+
-+	;
-+	; Zero out carries
-+	;
-+	COPY     %r0,c1
-+	COPY     %r0,c2
-+	COPY     %r0,c3
-+
-+	LDO      128(%sp),%sp       ; bump stack
-+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
-+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
-+
-+	;
-+	; Load up all of the values we are going to use
-+	;
-+    FLDD     0(a_ptr),a0       
-+    FLDD     8(a_ptr),a1       
-+    FLDD    16(a_ptr),a2       
-+    FLDD    24(a_ptr),a3       
-+    FLDD    32(a_ptr),a4       
-+    FLDD    40(a_ptr),a5       
-+    FLDD    48(a_ptr),a6       
-+    FLDD    56(a_ptr),a7       
-+
-+	SQR_ADD_C a0L,a0R,c1,c2,c3
-+	STD     c1,0(r_ptr)          ; r[0] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
-+	STD     c2,8(r_ptr)          ; r[1] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C a1L,a1R,c3,c1,c2
-+	SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
-+	STD     c3,16(r_ptr)            ; r[2] = c3;
-+	COPY    %r0,c3
-+
-+	SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
-+	SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
-+	STD     c1,24(r_ptr)           ; r[3] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C a2L,a2R,c2,c3,c1
-+	SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
-+	SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1
-+	STD     c2,32(r_ptr)          ; r[4] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2
-+	SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2
-+	SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
-+	STD     c3,40(r_ptr)          ; r[5] = c3;
-+	COPY    %r0,c3
-+
-+	SQR_ADD_C a3L,a3R,c1,c2,c3
-+	SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3
-+	SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3
-+	SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3
-+	STD     c1,48(r_ptr)          ; r[6] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1
-+	SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1
-+	SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1
-+	SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1
-+	STD     c2,56(r_ptr)          ; r[7] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C a4L,a4R,c3,c1,c2
-+	SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2
-+	SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2
-+	SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2
-+	STD     c3,64(r_ptr)          ; r[8] = c3;
-+	COPY    %r0,c3
-+
-+	SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3
-+	SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3
-+	SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3
-+	STD     c1,72(r_ptr)          ; r[9] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C a5L,a5R,c2,c3,c1
-+	SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1
-+	SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1
-+	STD     c2,80(r_ptr)          ; r[10] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2
-+	SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2
-+	STD     c3,88(r_ptr)          ; r[11] = c3;
-+	COPY    %r0,c3
-+	
-+	SQR_ADD_C a6L,a6R,c1,c2,c3
-+	SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3
-+	STD     c1,96(r_ptr)          ; r[12] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1
-+	STD     c2,104(r_ptr)         ; r[13] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C a7L,a7R,c3,c1,c2
-+	STD     c3, 112(r_ptr)       ; r[14] = c3
-+	STD     c1, 120(r_ptr)       ; r[15] = c1
-+
-+    .EXIT
-+    LDD     -104(%sp),%r6        ; restore r6
-+    LDD     -112(%sp),%r5        ; restore r5
-+    LDD     -120(%sp),%r4        ; restore r4
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3
-+
-+	.PROCEND	
-+
-+;-----------------------------------------------------------------------------
-+;
-+;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
-+; arg0 = r_ptr
-+; arg1 = a_ptr
-+;
-+
-+bn_sqr_comba4
-+	.proc
-+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .entry
-+	.align 64
-+    STD     %r3,0(%sp)          ; save r3
-+    STD     %r4,8(%sp)          ; save r4
-+    STD     %r5,16(%sp)         ; save r5
-+    STD     %r6,24(%sp)         ; save r6
-+
-+	;
-+	; Zero out carries
-+	;
-+	COPY     %r0,c1
-+	COPY     %r0,c2
-+	COPY     %r0,c3
-+
-+	LDO      128(%sp),%sp       ; bump stack
-+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
-+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
-+
-+	;
-+	; Load up all of the values we are going to use
-+	;
-+    FLDD     0(a_ptr),a0       
-+    FLDD     8(a_ptr),a1       
-+    FLDD    16(a_ptr),a2       
-+    FLDD    24(a_ptr),a3       
-+    FLDD    32(a_ptr),a4       
-+    FLDD    40(a_ptr),a5       
-+    FLDD    48(a_ptr),a6       
-+    FLDD    56(a_ptr),a7       
-+
-+	SQR_ADD_C a0L,a0R,c1,c2,c3
-+
-+	STD     c1,0(r_ptr)          ; r[0] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
-+
-+	STD     c2,8(r_ptr)          ; r[1] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C a1L,a1R,c3,c1,c2
-+	SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
-+
-+	STD     c3,16(r_ptr)            ; r[2] = c3;
-+	COPY    %r0,c3
-+
-+	SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
-+	SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
-+
-+	STD     c1,24(r_ptr)           ; r[3] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C a2L,a2R,c2,c3,c1
-+	SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
-+
-+	STD     c2,32(r_ptr)           ; r[4] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
-+	STD     c3,40(r_ptr)           ; r[5] = c3;
-+	COPY    %r0,c3
-+
-+	SQR_ADD_C a3L,a3R,c1,c2,c3
-+	STD     c1,48(r_ptr)           ; r[6] = c1;
-+	STD     c2,56(r_ptr)           ; r[7] = c2;
-+
-+    .EXIT
-+    LDD     -104(%sp),%r6        ; restore r6
-+    LDD     -112(%sp),%r5        ; restore r5
-+    LDD     -120(%sp),%r4        ; restore r4
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3
-+
-+	.PROCEND	
-+
-+
-+;---------------------------------------------------------------------------
-+
-+MUL_ADD_C  .macro  A0L,A0R,B0L,B0R,C1,C2,C3
-+    XMPYU   A0L,B0R,ftemp1        ; m1 = bl*ht
-+    FSTD    ftemp1,-16(%sp)       ;
-+    XMPYU   A0R,B0L,ftemp2        ; m = bh*lt
-+    FSTD    ftemp2,-8(%sp)        ;
-+    XMPYU   A0R,B0R,ftemp3        ; lt = bl*lt
-+    FSTD    ftemp3,-32(%sp)
-+    XMPYU   A0L,B0L,ftemp4        ; ht = bh*ht
-+    FSTD    ftemp4,-24(%sp)       ;
-+
-+    LDD     -8(%sp),m             ; r21 = m
-+    LDD     -16(%sp),m1           ; r19 = m1
-+    ADD,L   m,m1,m                ; m+m1
-+
-+    DEPD,Z  m,31,32,temp3         ; (m+m1<<32)
-+    LDD     -24(%sp),ht           ; r24 = ht
-+
-+    CMPCLR,*>>= m,m1,%r0          ; if (m < m1)
-+    ADD,L   ht,high_one,ht        ; ht+=high_one
-+
-+    EXTRD,U m,31,32,temp1         ; m >> 32
-+    LDD     -32(%sp),lt           ; lt
-+    ADD,L   ht,temp1,ht           ; ht+= m>>32
-+    ADD     lt,temp3,lt           ; lt = lt+m1
-+    ADD,DC  ht,%r0,ht             ; ht++
-+
-+    ADD     C1,lt,C1              ; c1=c1+lt
-+    ADD,DC  ht,%r0,ht             ; bump c3 if overflow,nullify otherwise
-+
-+    ADD     C2,ht,C2              ; c2 = c2 + ht
-+    ADD,DC  C3,%r0,C3             ; add in carry (c3++)
-+.endm
-+
-+
-+;
-+;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
-+; arg0 = r_ptr
-+; arg1 = a_ptr
-+; arg2 = b_ptr
-+;
-+
-+bn_mul_comba8
-+	.proc
-+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .entry
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3
-+    STD     %r4,8(%sp)          ; save r4
-+    STD     %r5,16(%sp)         ; save r5
-+    STD     %r6,24(%sp)         ; save r6
-+    FSTD    %fr12,32(%sp)       ; save r6
-+    FSTD    %fr13,40(%sp)       ; save r7
-+
-+	;
-+	; Zero out carries
-+	;
-+	COPY     %r0,c1
-+	COPY     %r0,c2
-+	COPY     %r0,c3
-+
-+	LDO      128(%sp),%sp       ; bump stack
-+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
-+
-+	;
-+	; Load up all of the values we are going to use
-+	;
-+    FLDD      0(a_ptr),a0       
-+    FLDD      8(a_ptr),a1       
-+    FLDD     16(a_ptr),a2       
-+    FLDD     24(a_ptr),a3       
-+    FLDD     32(a_ptr),a4       
-+    FLDD     40(a_ptr),a5       
-+    FLDD     48(a_ptr),a6       
-+    FLDD     56(a_ptr),a7       
-+
-+    FLDD      0(b_ptr),b0       
-+    FLDD      8(b_ptr),b1       
-+    FLDD     16(b_ptr),b2       
-+    FLDD     24(b_ptr),b3       
-+    FLDD     32(b_ptr),b4       
-+    FLDD     40(b_ptr),b5       
-+    FLDD     48(b_ptr),b6       
-+    FLDD     56(b_ptr),b7       
-+
-+	MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
-+	STD       c1,0(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
-+	MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
-+	STD       c2,8(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
-+	MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
-+	MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
-+	STD       c3,16(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
-+	MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
-+	MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
-+	MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
-+	STD       c1,24(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1
-+	MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
-+	MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
-+	MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
-+	MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1
-+	STD       c2,32(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2
-+	MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2
-+	MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
-+	MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
-+	MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2
-+	MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2
-+	STD       c3,40(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3
-+	MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3
-+	MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3
-+	MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
-+	MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3
-+	MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3
-+	MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3
-+	STD       c1,48(r_ptr)
-+	COPY      %r0,c1
-+	
-+	MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1
-+	MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1
-+	MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1
-+	MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1
-+	MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1
-+	MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1
-+	MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1
-+	MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1
-+	STD       c2,56(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2
-+	MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2
-+	MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2
-+	MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2
-+	MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2
-+	MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2
-+	MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2
-+	STD       c3,64(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3
-+	MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3
-+	MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3
-+	MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3
-+	MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3
-+	MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3
-+	STD       c1,72(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1
-+	MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1
-+	MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1
-+	MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1
-+	MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1
-+	STD       c2,80(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2
-+	MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2
-+	MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2
-+	MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2
-+	STD       c3,88(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3
-+	MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3
-+	MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3
-+	STD       c1,96(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1
-+	MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1
-+	STD       c2,104(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2
-+	STD       c3,112(r_ptr)
-+	STD       c1,120(r_ptr)
-+
-+    .EXIT
-+    FLDD    -88(%sp),%fr13 
-+    FLDD    -96(%sp),%fr12 
-+    LDD     -104(%sp),%r6        ; restore r6
-+    LDD     -112(%sp),%r5        ; restore r5
-+    LDD     -120(%sp),%r4        ; restore r4
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3
-+
-+	.PROCEND	
-+
-+;-----------------------------------------------------------------------------
-+;
-+;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
-+; arg0 = r_ptr
-+; arg1 = a_ptr
-+; arg2 = b_ptr
-+;
-+
-+bn_mul_comba4
-+	.proc
-+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .entry
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3
-+    STD     %r4,8(%sp)          ; save r4
-+    STD     %r5,16(%sp)         ; save r5
-+    STD     %r6,24(%sp)         ; save r6
-+    FSTD    %fr12,32(%sp)       ; save r6
-+    FSTD    %fr13,40(%sp)       ; save r7
-+
-+	;
-+	; Zero out carries
-+	;
-+	COPY     %r0,c1
-+	COPY     %r0,c2
-+	COPY     %r0,c3
-+
-+	LDO      128(%sp),%sp       ; bump stack
-+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
-+
-+	;
-+	; Load up all of the values we are going to use
-+	;
-+    FLDD      0(a_ptr),a0       
-+    FLDD      8(a_ptr),a1       
-+    FLDD     16(a_ptr),a2       
-+    FLDD     24(a_ptr),a3       
-+
-+    FLDD      0(b_ptr),b0       
-+    FLDD      8(b_ptr),b1       
-+    FLDD     16(b_ptr),b2       
-+    FLDD     24(b_ptr),b3       
-+
-+	MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
-+	STD       c1,0(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
-+	MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
-+	STD       c2,8(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
-+	MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
-+	MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
-+	STD       c3,16(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
-+	MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
-+	MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
-+	MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
-+	STD       c1,24(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
-+	MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
-+	MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
-+	STD       c2,32(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
-+	MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
-+	STD       c3,40(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
-+	STD       c1,48(r_ptr)
-+	STD       c2,56(r_ptr)
-+
-+    .EXIT
-+    FLDD    -88(%sp),%fr13 
-+    FLDD    -96(%sp),%fr12 
-+    LDD     -104(%sp),%r6        ; restore r6
-+    LDD     -112(%sp),%r5        ; restore r5
-+    LDD     -120(%sp),%r4        ; restore r4
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3
-+
-+	.PROCEND	
-+
-+
-+;--- not PIC	.SPACE	$TEXT$
-+;--- not PIC	.SUBSPA	$CODE$
-+;--- not PIC	.SPACE	$PRIVATE$,SORT=16
-+;--- not PIC	.IMPORT	$global$,DATA
-+;--- not PIC	.SPACE	$TEXT$
-+;--- not PIC	.SUBSPA	$CODE$
-+;--- not PIC	.SUBSPA	$LIT$,ACCESS=0x2c
-+;--- not PIC	C$7
-+;--- not PIC	.ALIGN	8
-+;--- not PIC	.STRINGZ	"Division would overflow (%d)\n"
-+	.END
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/pa-risc2W.s b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/pa-risc2W.s
-new file mode 100644
-index 0000000..9738117
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/pa-risc2W.s
-@@ -0,0 +1,1612 @@
-+; Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+;
-+; Licensed under the OpenSSL license (the "License").  You may not use
-+; this file except in compliance with the License.  You can obtain a copy
-+; in the file LICENSE in the source distribution or at
-+; https://www.openssl.org/source/license.html
-+
-+;
-+; PA-RISC 64-bit implementation of bn_asm code
-+;
-+; This code is approximately 2x faster than the C version
-+; for RSA/DSA.
-+;
-+; See http://devresource.hp.com/  for more details on the PA-RISC
-+; architecture.  Also see the book "PA-RISC 2.0 Architecture"
-+; by Gerry Kane for information on the instruction set architecture.
-+;
-+; Code written by Chris Ruemmler (with some help from the HP C
-+; compiler).
-+;
-+; The code compiles with HP's assembler
-+;
-+
-+	.level	2.0W
-+	.space	$TEXT$
-+	.subspa	$CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY
-+
-+;
-+; Global Register definitions used for the routines.
-+;
-+; Some information about HP's runtime architecture for 64-bits.
-+;
-+; "Caller save" means the calling function must save the register
-+; if it wants the register to be preserved.
-+; "Callee save" means if a function uses the register, it must save
-+; the value before using it.
-+;
-+; For the floating point registers 
-+;
-+;    "caller save" registers: fr4-fr11, fr22-fr31
-+;    "callee save" registers: fr12-fr21
-+;    "special" registers: fr0-fr3 (status and exception registers)
-+;
-+; For the integer registers
-+;     value zero             :  r0
-+;     "caller save" registers: r1,r19-r26
-+;     "callee save" registers: r3-r18
-+;     return register        :  r2  (rp)
-+;     return values          ; r28  (ret0,ret1)
-+;     Stack pointer          ; r30  (sp) 
-+;     global data pointer    ; r27  (dp)
-+;     argument pointer       ; r29  (ap)
-+;     millicode return ptr   ; r31  (also a caller save register)
-+
-+
-+;
-+; Arguments to the routines
-+;
-+r_ptr       .reg %r26
-+a_ptr       .reg %r25
-+b_ptr       .reg %r24
-+num         .reg %r24
-+w           .reg %r23
-+n           .reg %r23
-+
-+
-+;
-+; Globals used in some routines
-+;
-+
-+top_overflow .reg %r29
-+high_mask    .reg %r22    ; value 0xffffffff80000000L
-+
-+
-+;------------------------------------------------------------------------------
-+;
-+; bn_mul_add_words
-+;
-+;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr, 
-+;								int num, BN_ULONG w)
-+;
-+; arg0 = r_ptr
-+; arg1 = a_ptr
-+; arg2 = num
-+; arg3 = w
-+;
-+; Local register definitions
-+;
-+
-+fm1          .reg %fr22
-+fm           .reg %fr23
-+ht_temp      .reg %fr24
-+ht_temp_1    .reg %fr25
-+lt_temp      .reg %fr26
-+lt_temp_1    .reg %fr27
-+fm1_1        .reg %fr28
-+fm_1         .reg %fr29
-+
-+fw_h         .reg %fr7L
-+fw_l         .reg %fr7R
-+fw           .reg %fr7
-+
-+fht_0        .reg %fr8L
-+flt_0        .reg %fr8R
-+t_float_0    .reg %fr8
-+
-+fht_1        .reg %fr9L
-+flt_1        .reg %fr9R
-+t_float_1    .reg %fr9
-+
-+tmp_0        .reg %r31
-+tmp_1        .reg %r21
-+m_0          .reg %r20 
-+m_1          .reg %r19 
-+ht_0         .reg %r1  
-+ht_1         .reg %r3
-+lt_0         .reg %r4
-+lt_1         .reg %r5
-+m1_0         .reg %r6 
-+m1_1         .reg %r7 
-+rp_val       .reg %r8
-+rp_val_1     .reg %r9
-+
-+bn_mul_add_words
-+	.export	bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN
-+	.proc
-+	.callinfo frame=128
-+    .entry
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3  
-+    STD     %r4,8(%sp)          ; save r4  
-+	NOP                         ; Needed to make the loop 16-byte aligned
-+	NOP                         ; Needed to make the loop 16-byte aligned
-+
-+    STD     %r5,16(%sp)         ; save r5  
-+    STD     %r6,24(%sp)         ; save r6  
-+    STD     %r7,32(%sp)         ; save r7  
-+    STD     %r8,40(%sp)         ; save r8  
-+
-+    STD     %r9,48(%sp)         ; save r9  
-+    COPY    %r0,%ret0           ; return 0 by default
-+    DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
-+	STD     w,56(%sp)           ; store w on stack
-+
-+    CMPIB,>= 0,num,bn_mul_add_words_exit  ; if (num <= 0) then exit
-+	LDO     128(%sp),%sp       ; bump stack
-+
-+	;
-+	; The loop is unrolled twice, so if there is only 1 number
-+    ; then go straight to the cleanup code.
-+	;
-+	CMPIB,= 1,num,bn_mul_add_words_single_top
-+	FLDD    -72(%sp),fw     ; load up w into fp register fw (fw_h/fw_l)
-+
-+	;
-+	; This loop is unrolled 2 times (64-byte aligned as well)
-+	;
-+	; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
-+    ; two 32-bit mutiplies can be issued per cycle.
-+    ; 
-+bn_mul_add_words_unroll2
-+
-+    FLDD    0(a_ptr),t_float_0       ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+    FLDD    8(a_ptr),t_float_1       ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+    LDD     0(r_ptr),rp_val          ; rp[0]
-+    LDD     8(r_ptr),rp_val_1        ; rp[1]
-+
-+    XMPYU   fht_0,fw_l,fm1           ; m1[0] = fht_0*fw_l
-+    XMPYU   fht_1,fw_l,fm1_1         ; m1[1] = fht_1*fw_l
-+    FSTD    fm1,-16(%sp)             ; -16(sp) = m1[0]
-+    FSTD    fm1_1,-48(%sp)           ; -48(sp) = m1[1]
-+
-+    XMPYU   flt_0,fw_h,fm            ; m[0] = flt_0*fw_h
-+    XMPYU   flt_1,fw_h,fm_1          ; m[1] = flt_1*fw_h
-+    FSTD    fm,-8(%sp)               ; -8(sp) = m[0]
-+    FSTD    fm_1,-40(%sp)            ; -40(sp) = m[1]
-+
-+    XMPYU   fht_0,fw_h,ht_temp       ; ht_temp   = fht_0*fw_h
-+    XMPYU   fht_1,fw_h,ht_temp_1     ; ht_temp_1 = fht_1*fw_h
-+    FSTD    ht_temp,-24(%sp)         ; -24(sp)   = ht_temp
-+    FSTD    ht_temp_1,-56(%sp)       ; -56(sp)   = ht_temp_1
-+
-+    XMPYU   flt_0,fw_l,lt_temp       ; lt_temp = lt*fw_l
-+    XMPYU   flt_1,fw_l,lt_temp_1     ; lt_temp = lt*fw_l
-+    FSTD    lt_temp,-32(%sp)         ; -32(sp) = lt_temp 
-+    FSTD    lt_temp_1,-64(%sp)       ; -64(sp) = lt_temp_1 
-+
-+    LDD     -8(%sp),m_0              ; m[0] 
-+    LDD     -40(%sp),m_1             ; m[1]
-+    LDD     -16(%sp),m1_0            ; m1[0]
-+    LDD     -48(%sp),m1_1            ; m1[1]
-+
-+    LDD     -24(%sp),ht_0            ; ht[0]
-+    LDD     -56(%sp),ht_1            ; ht[1]
-+    ADD,L   m1_0,m_0,tmp_0           ; tmp_0 = m[0] + m1[0]; 
-+    ADD,L   m1_1,m_1,tmp_1           ; tmp_1 = m[1] + m1[1]; 
-+
-+    LDD     -32(%sp),lt_0            
-+    LDD     -64(%sp),lt_1            
-+    CMPCLR,*>>= tmp_0,m1_0, %r0      ; if (m[0] < m1[0])
-+    ADD,L   ht_0,top_overflow,ht_0   ; ht[0] += (1<<32)
-+
-+    CMPCLR,*>>= tmp_1,m1_1,%r0       ; if (m[1] < m1[1])
-+    ADD,L   ht_1,top_overflow,ht_1   ; ht[1] += (1<<32)
-+    EXTRD,U tmp_0,31,32,m_0          ; m[0]>>32  
-+    DEPD,Z  tmp_0,31,32,m1_0         ; m1[0] = m[0]<<32 
-+
-+    EXTRD,U tmp_1,31,32,m_1          ; m[1]>>32  
-+    DEPD,Z  tmp_1,31,32,m1_1         ; m1[1] = m[1]<<32 
-+    ADD,L   ht_0,m_0,ht_0            ; ht[0]+= (m[0]>>32)
-+    ADD,L   ht_1,m_1,ht_1            ; ht[1]+= (m[1]>>32)
-+
-+    ADD     lt_0,m1_0,lt_0           ; lt[0] = lt[0]+m1[0];
-+	ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
-+    ADD     lt_1,m1_1,lt_1           ; lt[1] = lt[1]+m1[1];
-+    ADD,DC  ht_1,%r0,ht_1            ; ht[1]++
-+
-+    ADD    %ret0,lt_0,lt_0           ; lt[0] = lt[0] + c;
-+	ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
-+    ADD     lt_0,rp_val,lt_0         ; lt[0] = lt[0]+rp[0]
-+    ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
-+
-+	LDO    -2(num),num               ; num = num - 2;
-+    ADD     ht_0,lt_1,lt_1           ; lt[1] = lt[1] + ht_0 (c);
-+    ADD,DC  ht_1,%r0,ht_1            ; ht[1]++
-+    STD     lt_0,0(r_ptr)            ; rp[0] = lt[0]
-+
-+    ADD     lt_1,rp_val_1,lt_1       ; lt[1] = lt[1]+rp[1]
-+    ADD,DC  ht_1,%r0,%ret0           ; ht[1]++
-+    LDO     16(a_ptr),a_ptr          ; a_ptr += 2
-+
-+    STD     lt_1,8(r_ptr)            ; rp[1] = lt[1]
-+	CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do
-+    LDO     16(r_ptr),r_ptr          ; r_ptr += 2
-+
-+    CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one
-+
-+	;
-+	; Top of loop aligned on 64-byte boundary
-+	;
-+bn_mul_add_words_single_top
-+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+    LDD     0(r_ptr),rp_val           ; rp[0]
-+    LDO     8(a_ptr),a_ptr            ; a_ptr++
-+    XMPYU   fht_0,fw_l,fm1            ; m1 = ht*fw_l
-+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
-+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
-+    FSTD    fm,-8(%sp)                ; -8(sp) = m
-+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = ht*fw_h
-+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
-+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
-+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
-+
-+    LDD     -8(%sp),m_0               
-+    LDD    -16(%sp),m1_0              ; m1 = temp1 
-+    ADD,L   m_0,m1_0,tmp_0            ; tmp_0 = m + m1; 
-+    LDD     -24(%sp),ht_0             
-+    LDD     -32(%sp),lt_0             
-+
-+    CMPCLR,*>>= tmp_0,m1_0,%r0        ; if (m < m1)
-+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
-+
-+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
-+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
-+
-+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
-+    ADD     lt_0,m1_0,tmp_0           ; tmp_0 = lt+m1;
-+    ADD,DC  ht_0,%r0,ht_0             ; ht++
-+    ADD     %ret0,tmp_0,lt_0          ; lt = lt + c;
-+    ADD,DC  ht_0,%r0,ht_0             ; ht++
-+    ADD     lt_0,rp_val,lt_0          ; lt = lt+rp[0]
-+    ADD,DC  ht_0,%r0,%ret0            ; ht++
-+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
-+
-+bn_mul_add_words_exit
-+    .EXIT
-+    LDD     -80(%sp),%r9              ; restore r9  
-+    LDD     -88(%sp),%r8              ; restore r8  
-+    LDD     -96(%sp),%r7              ; restore r7  
-+    LDD     -104(%sp),%r6             ; restore r6  
-+    LDD     -112(%sp),%r5             ; restore r5  
-+    LDD     -120(%sp),%r4             ; restore r4  
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3             ; restore r3
-+	.PROCEND	;in=23,24,25,26,29;out=28;
-+
-+;----------------------------------------------------------------------------
-+;
-+;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
-+;
-+; arg0 = rp
-+; arg1 = ap
-+; arg2 = num
-+; arg3 = w
-+
-+bn_mul_words
-+	.proc
-+	.callinfo frame=128
-+    .entry
-+	.EXPORT	bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3  
-+    STD     %r4,8(%sp)          ; save r4  
-+    STD     %r5,16(%sp)         ; save r5  
-+    STD     %r6,24(%sp)         ; save r6  
-+
-+    STD     %r7,32(%sp)         ; save r7  
-+    COPY    %r0,%ret0           ; return 0 by default
-+    DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
-+	STD     w,56(%sp)           ; w on stack
-+
-+    CMPIB,>= 0,num,bn_mul_words_exit
-+	LDO     128(%sp),%sp       ; bump stack
-+
-+	;
-+	; See if only 1 word to do, thus just do cleanup
-+	;
-+	CMPIB,= 1,num,bn_mul_words_single_top
-+	FLDD    -72(%sp),fw     ; load up w into fp register fw (fw_h/fw_l)
-+
-+	;
-+	; This loop is unrolled 2 times (64-byte aligned as well)
-+	;
-+	; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
-+    ; two 32-bit mutiplies can be issued per cycle.
-+    ; 
-+bn_mul_words_unroll2
-+
-+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+    FLDD    8(a_ptr),t_float_1        ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+    XMPYU   fht_0,fw_l,fm1            ; m1[0] = fht_0*fw_l
-+    XMPYU   fht_1,fw_l,fm1_1          ; m1[1] = ht*fw_l
-+
-+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
-+    FSTD    fm1_1,-48(%sp)            ; -48(sp) = m1
-+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
-+    XMPYU   flt_1,fw_h,fm_1           ; m = lt*fw_h
-+
-+    FSTD    fm,-8(%sp)                ; -8(sp) = m
-+    FSTD    fm_1,-40(%sp)             ; -40(sp) = m
-+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = fht_0*fw_h
-+    XMPYU   fht_1,fw_h,ht_temp_1      ; ht_temp = ht*fw_h
-+
-+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
-+    FSTD    ht_temp_1,-56(%sp)        ; -56(sp) = ht
-+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
-+    XMPYU   flt_1,fw_l,lt_temp_1      ; lt_temp = lt*fw_l
-+
-+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
-+    FSTD    lt_temp_1,-64(%sp)        ; -64(sp) = lt 
-+    LDD     -8(%sp),m_0               
-+    LDD     -40(%sp),m_1              
-+
-+    LDD    -16(%sp),m1_0              
-+    LDD    -48(%sp),m1_1              
-+    LDD     -24(%sp),ht_0             
-+    LDD     -56(%sp),ht_1             
-+
-+    ADD,L   m1_0,m_0,tmp_0            ; tmp_0 = m + m1; 
-+    ADD,L   m1_1,m_1,tmp_1            ; tmp_1 = m + m1; 
-+    LDD     -32(%sp),lt_0             
-+    LDD     -64(%sp),lt_1             
-+
-+    CMPCLR,*>>= tmp_0,m1_0, %r0       ; if (m < m1)
-+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
-+    CMPCLR,*>>= tmp_1,m1_1,%r0        ; if (m < m1)
-+    ADD,L   ht_1,top_overflow,ht_1    ; ht += (1<<32)
-+
-+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
-+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
-+    EXTRD,U tmp_1,31,32,m_1           ; m>>32  
-+    DEPD,Z  tmp_1,31,32,m1_1          ; m1 = m<<32 
-+
-+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
-+    ADD,L   ht_1,m_1,ht_1             ; ht+= (m>>32)
-+    ADD     lt_0,m1_0,lt_0            ; lt = lt+m1;
-+	ADD,DC  ht_0,%r0,ht_0             ; ht++
-+
-+    ADD     lt_1,m1_1,lt_1            ; lt = lt+m1;
-+    ADD,DC  ht_1,%r0,ht_1             ; ht++
-+    ADD    %ret0,lt_0,lt_0            ; lt = lt + c (ret0);
-+	ADD,DC  ht_0,%r0,ht_0             ; ht++
-+
-+    ADD     ht_0,lt_1,lt_1            ; lt = lt + c (ht_0)
-+    ADD,DC  ht_1,%r0,ht_1             ; ht++
-+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
-+    STD     lt_1,8(r_ptr)             ; rp[1] = lt
-+
-+	COPY    ht_1,%ret0                ; carry = ht
-+	LDO    -2(num),num                ; num = num - 2;
-+    LDO     16(a_ptr),a_ptr           ; ap += 2
-+	CMPIB,<= 2,num,bn_mul_words_unroll2
-+    LDO     16(r_ptr),r_ptr           ; rp++
-+
-+    CMPIB,=,N 0,num,bn_mul_words_exit ; are we done?
-+
-+	;
-+	; Top of loop aligned on 64-byte boundary
-+	;
-+bn_mul_words_single_top
-+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+
-+    XMPYU   fht_0,fw_l,fm1            ; m1 = ht*fw_l
-+    FSTD    fm1,-16(%sp)              ; -16(sp) = m1
-+    XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
-+    FSTD    fm,-8(%sp)                ; -8(sp) = m
-+    XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = ht*fw_h
-+    FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
-+    XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
-+    FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
-+
-+    LDD     -8(%sp),m_0               
-+    LDD    -16(%sp),m1_0              
-+    ADD,L   m_0,m1_0,tmp_0            ; tmp_0 = m + m1; 
-+    LDD     -24(%sp),ht_0             
-+    LDD     -32(%sp),lt_0             
-+
-+    CMPCLR,*>>= tmp_0,m1_0,%r0        ; if (m < m1)
-+    ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
-+
-+    EXTRD,U tmp_0,31,32,m_0           ; m>>32  
-+    DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
-+
-+    ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
-+    ADD     lt_0,m1_0,lt_0            ; lt= lt+m1;
-+    ADD,DC  ht_0,%r0,ht_0             ; ht++
-+
-+    ADD     %ret0,lt_0,lt_0           ; lt = lt + c;
-+    ADD,DC  ht_0,%r0,ht_0             ; ht++
-+
-+    COPY    ht_0,%ret0                ; copy carry
-+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
-+
-+bn_mul_words_exit
-+    .EXIT
-+    LDD     -96(%sp),%r7              ; restore r7  
-+    LDD     -104(%sp),%r6             ; restore r6  
-+    LDD     -112(%sp),%r5             ; restore r5  
-+    LDD     -120(%sp),%r4             ; restore r4  
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3             ; restore r3
-+	.PROCEND	;in=23,24,25,26,29;out=28;
-+
-+;----------------------------------------------------------------------------
-+;
-+;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
-+;
-+; arg0 = rp
-+; arg1 = ap
-+; arg2 = num
-+;
-+
-+bn_sqr_words
-+	.proc
-+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .entry
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3  
-+    STD     %r4,8(%sp)          ; save r4  
-+	NOP
-+    STD     %r5,16(%sp)         ; save r5  
-+
-+    CMPIB,>= 0,num,bn_sqr_words_exit
-+	LDO     128(%sp),%sp       ; bump stack
-+
-+	;
-+	; If only 1, the goto straight to cleanup
-+	;
-+	CMPIB,= 1,num,bn_sqr_words_single_top
-+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
-+
-+	;
-+	; This loop is unrolled 2 times (64-byte aligned as well)
-+	;
-+
-+bn_sqr_words_unroll2
-+    FLDD    0(a_ptr),t_float_0        ; a[0]
-+    FLDD    8(a_ptr),t_float_1        ; a[1]
-+    XMPYU   fht_0,flt_0,fm            ; m[0]
-+    XMPYU   fht_1,flt_1,fm_1          ; m[1]
-+
-+    FSTD    fm,-24(%sp)               ; store m[0]
-+    FSTD    fm_1,-56(%sp)             ; store m[1]
-+    XMPYU   flt_0,flt_0,lt_temp       ; lt[0]
-+    XMPYU   flt_1,flt_1,lt_temp_1     ; lt[1]
-+
-+    FSTD    lt_temp,-16(%sp)          ; store lt[0]
-+    FSTD    lt_temp_1,-48(%sp)        ; store lt[1]
-+    XMPYU   fht_0,fht_0,ht_temp       ; ht[0]
-+    XMPYU   fht_1,fht_1,ht_temp_1     ; ht[1]
-+
-+    FSTD    ht_temp,-8(%sp)           ; store ht[0]
-+    FSTD    ht_temp_1,-40(%sp)        ; store ht[1]
-+    LDD     -24(%sp),m_0             
-+    LDD     -56(%sp),m_1              
-+
-+    AND     m_0,high_mask,tmp_0       ; m[0] & Mask
-+    AND     m_1,high_mask,tmp_1       ; m[1] & Mask
-+    DEPD,Z  m_0,30,31,m_0             ; m[0] << 32+1
-+    DEPD,Z  m_1,30,31,m_1             ; m[1] << 32+1
-+
-+    LDD     -16(%sp),lt_0        
-+    LDD     -48(%sp),lt_1        
-+    EXTRD,U tmp_0,32,33,tmp_0         ; tmp_0 = m[0]&Mask >> 32-1
-+    EXTRD,U tmp_1,32,33,tmp_1         ; tmp_1 = m[1]&Mask >> 32-1
-+
-+    LDD     -8(%sp),ht_0            
-+    LDD     -40(%sp),ht_1           
-+    ADD,L   ht_0,tmp_0,ht_0           ; ht[0] += tmp_0
-+    ADD,L   ht_1,tmp_1,ht_1           ; ht[1] += tmp_1
-+
-+    ADD     lt_0,m_0,lt_0             ; lt = lt+m
-+    ADD,DC  ht_0,%r0,ht_0             ; ht[0]++
-+    STD     lt_0,0(r_ptr)             ; rp[0] = lt[0]
-+    STD     ht_0,8(r_ptr)             ; rp[1] = ht[1]
-+
-+    ADD     lt_1,m_1,lt_1             ; lt = lt+m
-+    ADD,DC  ht_1,%r0,ht_1             ; ht[1]++
-+    STD     lt_1,16(r_ptr)            ; rp[2] = lt[1]
-+    STD     ht_1,24(r_ptr)            ; rp[3] = ht[1]
-+
-+	LDO    -2(num),num                ; num = num - 2;
-+    LDO     16(a_ptr),a_ptr           ; ap += 2
-+	CMPIB,<= 2,num,bn_sqr_words_unroll2
-+    LDO     32(r_ptr),r_ptr           ; rp += 4
-+
-+    CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done?
-+
-+	;
-+	; Top of loop aligned on 64-byte boundary
-+	;
-+bn_sqr_words_single_top
-+    FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
-+
-+    XMPYU   fht_0,flt_0,fm            ; m
-+    FSTD    fm,-24(%sp)               ; store m
-+
-+    XMPYU   flt_0,flt_0,lt_temp       ; lt
-+    FSTD    lt_temp,-16(%sp)          ; store lt
-+
-+    XMPYU   fht_0,fht_0,ht_temp       ; ht
-+    FSTD    ht_temp,-8(%sp)           ; store ht
-+
-+    LDD     -24(%sp),m_0              ; load m
-+    AND     m_0,high_mask,tmp_0       ; m & Mask
-+    DEPD,Z  m_0,30,31,m_0             ; m << 32+1
-+    LDD     -16(%sp),lt_0             ; lt
-+
-+    LDD     -8(%sp),ht_0              ; ht
-+    EXTRD,U tmp_0,32,33,tmp_0         ; tmp_0 = m&Mask >> 32-1
-+    ADD     m_0,lt_0,lt_0             ; lt = lt+m
-+    ADD,L   ht_0,tmp_0,ht_0           ; ht += tmp_0
-+    ADD,DC  ht_0,%r0,ht_0             ; ht++
-+
-+    STD     lt_0,0(r_ptr)             ; rp[0] = lt
-+    STD     ht_0,8(r_ptr)             ; rp[1] = ht
-+
-+bn_sqr_words_exit
-+    .EXIT
-+    LDD     -112(%sp),%r5       ; restore r5  
-+    LDD     -120(%sp),%r4       ; restore r4  
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3 
-+	.PROCEND	;in=23,24,25,26,29;out=28;
-+
-+
-+;----------------------------------------------------------------------------
-+;
-+;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
-+;
-+; arg0 = rp 
-+; arg1 = ap
-+; arg2 = bp 
-+; arg3 = n
-+
-+t  .reg %r22
-+b  .reg %r21
-+l  .reg %r20
-+
-+bn_add_words
-+	.proc
-+    .entry
-+	.callinfo
-+	.EXPORT	bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+	.align 64
-+
-+    CMPIB,>= 0,n,bn_add_words_exit
-+    COPY    %r0,%ret0           ; return 0 by default
-+
-+	;
-+	; If 2 or more numbers do the loop
-+	;
-+	CMPIB,= 1,n,bn_add_words_single_top
-+	NOP
-+
-+	;
-+	; This loop is unrolled 2 times (64-byte aligned as well)
-+	;
-+bn_add_words_unroll2
-+	LDD     0(a_ptr),t
-+	LDD     0(b_ptr),b
-+	ADD     t,%ret0,t                    ; t = t+c;
-+	ADD,DC  %r0,%r0,%ret0                ; set c to carry
-+	ADD     t,b,l                        ; l = t + b[0]
-+	ADD,DC  %ret0,%r0,%ret0              ; c+= carry
-+	STD     l,0(r_ptr)
-+
-+	LDD     8(a_ptr),t
-+	LDD     8(b_ptr),b
-+	ADD     t,%ret0,t                     ; t = t+c;
-+	ADD,DC  %r0,%r0,%ret0                 ; set c to carry
-+	ADD     t,b,l                         ; l = t + b[0]
-+	ADD,DC  %ret0,%r0,%ret0               ; c+= carry
-+	STD     l,8(r_ptr)
-+
-+	LDO     -2(n),n
-+	LDO     16(a_ptr),a_ptr
-+	LDO     16(b_ptr),b_ptr
-+
-+	CMPIB,<= 2,n,bn_add_words_unroll2
-+	LDO     16(r_ptr),r_ptr
-+
-+    CMPIB,=,N 0,n,bn_add_words_exit ; are we done?
-+
-+bn_add_words_single_top
-+	LDD     0(a_ptr),t
-+	LDD     0(b_ptr),b
-+
-+	ADD     t,%ret0,t                 ; t = t+c;
-+	ADD,DC  %r0,%r0,%ret0             ; set c to carry (could use CMPCLR??)
-+	ADD     t,b,l                     ; l = t + b[0]
-+	ADD,DC  %ret0,%r0,%ret0           ; c+= carry
-+	STD     l,0(r_ptr)
-+
-+bn_add_words_exit
-+    .EXIT
-+    BVE     (%rp)
-+	NOP
-+	.PROCEND	;in=23,24,25,26,29;out=28;
-+
-+;----------------------------------------------------------------------------
-+;
-+;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
-+;
-+; arg0 = rp 
-+; arg1 = ap
-+; arg2 = bp 
-+; arg3 = n
-+
-+t1       .reg %r22
-+t2       .reg %r21
-+sub_tmp1 .reg %r20
-+sub_tmp2 .reg %r19
-+
-+
-+bn_sub_words
-+	.proc
-+	.callinfo 
-+	.EXPORT	bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .entry
-+	.align 64
-+
-+    CMPIB,>=  0,n,bn_sub_words_exit
-+    COPY    %r0,%ret0           ; return 0 by default
-+
-+	;
-+	; If 2 or more numbers do the loop
-+	;
-+	CMPIB,= 1,n,bn_sub_words_single_top
-+	NOP
-+
-+	;
-+	; This loop is unrolled 2 times (64-byte aligned as well)
-+	;
-+bn_sub_words_unroll2
-+	LDD     0(a_ptr),t1
-+	LDD     0(b_ptr),t2
-+	SUB     t1,t2,sub_tmp1           ; t3 = t1-t2; 
-+	SUB     sub_tmp1,%ret0,sub_tmp1  ; t3 = t3- c; 
-+
-+	CMPCLR,*>> t1,t2,sub_tmp2        ; clear if t1 > t2
-+	LDO      1(%r0),sub_tmp2
-+	
-+	CMPCLR,*= t1,t2,%r0
-+	COPY    sub_tmp2,%ret0
-+	STD     sub_tmp1,0(r_ptr)
-+
-+	LDD     8(a_ptr),t1
-+	LDD     8(b_ptr),t2
-+	SUB     t1,t2,sub_tmp1            ; t3 = t1-t2; 
-+	SUB     sub_tmp1,%ret0,sub_tmp1   ; t3 = t3- c; 
-+	CMPCLR,*>> t1,t2,sub_tmp2         ; clear if t1 > t2
-+	LDO      1(%r0),sub_tmp2
-+	
-+	CMPCLR,*= t1,t2,%r0
-+	COPY    sub_tmp2,%ret0
-+	STD     sub_tmp1,8(r_ptr)
-+
-+	LDO     -2(n),n
-+	LDO     16(a_ptr),a_ptr
-+	LDO     16(b_ptr),b_ptr
-+
-+	CMPIB,<= 2,n,bn_sub_words_unroll2
-+	LDO     16(r_ptr),r_ptr
-+
-+    CMPIB,=,N 0,n,bn_sub_words_exit ; are we done?
-+
-+bn_sub_words_single_top
-+	LDD     0(a_ptr),t1
-+	LDD     0(b_ptr),t2
-+	SUB     t1,t2,sub_tmp1            ; t3 = t1-t2; 
-+	SUB     sub_tmp1,%ret0,sub_tmp1   ; t3 = t3- c; 
-+	CMPCLR,*>> t1,t2,sub_tmp2         ; clear if t1 > t2
-+	LDO      1(%r0),sub_tmp2
-+	
-+	CMPCLR,*= t1,t2,%r0
-+	COPY    sub_tmp2,%ret0
-+
-+	STD     sub_tmp1,0(r_ptr)
-+
-+bn_sub_words_exit
-+    .EXIT
-+    BVE     (%rp)
-+	NOP
-+	.PROCEND	;in=23,24,25,26,29;out=28;
-+
-+;------------------------------------------------------------------------------
-+;
-+; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d)
-+;
-+; arg0 = h
-+; arg1 = l
-+; arg2 = d
-+;
-+; This is mainly just modified assembly from the compiler, thus the
-+; lack of variable names.
-+;
-+;------------------------------------------------------------------------------
-+bn_div_words
-+	.proc
-+	.callinfo CALLER,FRAME=272,ENTRY_GR=%r10,SAVE_RP,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_div_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+	.IMPORT	BN_num_bits_word,CODE,NO_RELOCATION
-+	.IMPORT	__iob,DATA
-+	.IMPORT	fprintf,CODE,NO_RELOCATION
-+	.IMPORT	abort,CODE,NO_RELOCATION
-+	.IMPORT	$$div2U,MILLICODE
-+    .entry
-+    STD     %r2,-16(%r30)   
-+    STD,MA  %r3,352(%r30)   
-+    STD     %r4,-344(%r30)  
-+    STD     %r5,-336(%r30)  
-+    STD     %r6,-328(%r30)  
-+    STD     %r7,-320(%r30)  
-+    STD     %r8,-312(%r30)  
-+    STD     %r9,-304(%r30)  
-+    STD     %r10,-296(%r30)
-+
-+    STD     %r27,-288(%r30)             ; save gp
-+
-+    COPY    %r24,%r3           ; save d 
-+    COPY    %r26,%r4           ; save h (high 64-bits)
-+    LDO      -1(%r0),%ret0     ; return -1 by default	
-+
-+    CMPB,*=  %r0,%arg2,$D3     ; if (d == 0)
-+    COPY    %r25,%r5           ; save l (low 64-bits)
-+
-+    LDO     -48(%r30),%r29     ; create ap 
-+    .CALL   ;in=26,29;out=28;
-+    B,L     BN_num_bits_word,%r2 
-+    COPY    %r3,%r26        
-+    LDD     -288(%r30),%r27    ; restore gp 
-+    LDI     64,%r21 
-+
-+    CMPB,=  %r21,%ret0,$00000012   ;if (i == 64) (forward) 
-+    COPY    %ret0,%r24             ; i   
-+    MTSARCM %r24    
-+    DEPDI,Z -1,%sar,1,%r29  
-+    CMPB,*<<,N %r29,%r4,bn_div_err_case ; if (h > 1<= d)
-+    SUB     %r4,%r3,%r4                        ; h -= d
-+    CMPB,=  %r31,%r0,$0000001A                 ; if (i)
-+    COPY    %r0,%r10                           ; ret = 0
-+    MTSARCM %r31                               ; i to shift
-+    DEPD,Z  %r3,%sar,64,%r3                    ; d <<= i;
-+    SUBI    64,%r31,%r19                       ; 64 - i; redundent
-+    MTSAR   %r19                               ; (64 -i) to shift
-+    SHRPD   %r4,%r5,%sar,%r4                   ; l>> (64-i)
-+    MTSARCM %r31                               ; i to shift
-+    DEPD,Z  %r5,%sar,64,%r5                    ; l <<= i;
-+
-+$0000001A
-+    DEPDI,Z -1,31,32,%r19                      
-+    EXTRD,U %r3,31,32,%r6                      ; dh=(d&0xfff)>>32
-+    EXTRD,U %r3,63,32,%r8                      ; dl = d&0xffffff
-+    LDO     2(%r0),%r9
-+    STD    %r3,-280(%r30)                      ; "d" to stack
-+
-+$0000001C
-+    DEPDI,Z -1,63,32,%r29                      ; 
-+    EXTRD,U %r4,31,32,%r31                     ; h >> 32
-+    CMPB,*=,N  %r31,%r6,$D2     	       ; if ((h>>32) != dh)(forward) div
-+    COPY    %r4,%r26       
-+    EXTRD,U %r4,31,32,%r25 
-+    COPY    %r6,%r24      
-+    .CALL   ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL)
-+    B,L     $$div2U,%r2     
-+    EXTRD,U %r6,31,32,%r23  
-+    DEPD    %r28,31,32,%r29 
-+$D2
-+    STD     %r29,-272(%r30)                   ; q
-+    AND     %r5,%r19,%r24                   ; t & 0xffffffff00000000;
-+    EXTRD,U %r24,31,32,%r24                 ; ??? 
-+    FLDD    -272(%r30),%fr7                 ; q
-+    FLDD    -280(%r30),%fr8                 ; d
-+    XMPYU   %fr8L,%fr7L,%fr10  
-+    FSTD    %fr10,-256(%r30)   
-+    XMPYU   %fr8L,%fr7R,%fr22  
-+    FSTD    %fr22,-264(%r30)   
-+    XMPYU   %fr8R,%fr7L,%fr11 
-+    XMPYU   %fr8R,%fr7R,%fr23
-+    FSTD    %fr11,-232(%r30)
-+    FSTD    %fr23,-240(%r30)
-+    LDD     -256(%r30),%r28
-+    DEPD,Z  %r28,31,32,%r2 
-+    LDD     -264(%r30),%r20
-+    ADD,L   %r20,%r2,%r31   
-+    LDD     -232(%r30),%r22 
-+    DEPD,Z  %r22,31,32,%r22 
-+    LDD     -240(%r30),%r21 
-+    B       $00000024       ; enter loop  
-+    ADD,L   %r21,%r22,%r23 
-+
-+$0000002A
-+    LDO     -1(%r29),%r29   
-+    SUB     %r23,%r8,%r23   
-+$00000024
-+    SUB     %r4,%r31,%r25   
-+    AND     %r25,%r19,%r26  
-+    CMPB,*<>,N      %r0,%r26,$00000046  ; (forward)
-+    DEPD,Z  %r25,31,32,%r20 
-+    OR      %r20,%r24,%r21  
-+    CMPB,*<<,N  %r21,%r23,$0000002A ;(backward) 
-+    SUB     %r31,%r6,%r31   
-+;-------------Break path---------------------
-+
-+$00000046
-+    DEPD,Z  %r23,31,32,%r25              ;tl
-+    EXTRD,U %r23,31,32,%r26              ;t
-+    AND     %r25,%r19,%r24               ;tl = (tl<<32)&0xfffffff0000000L
-+    ADD,L   %r31,%r26,%r31               ;th += t; 
-+    CMPCLR,*>>=     %r5,%r24,%r0         ;if (l>32));
-+    DEPD,Z  %r29,31,32,%r10              ; ret = q<<32
-+    b      $0000001C
-+    DEPD,Z  %r28,31,32,%r5               ; l = l << 32 
-+
-+$D1
-+    OR      %r10,%r29,%r28           ; ret |= q
-+$D3
-+    LDD     -368(%r30),%r2  
-+$D0
-+    LDD     -296(%r30),%r10 
-+    LDD     -304(%r30),%r9  
-+    LDD     -312(%r30),%r8  
-+    LDD     -320(%r30),%r7  
-+    LDD     -328(%r30),%r6  
-+    LDD     -336(%r30),%r5  
-+    LDD     -344(%r30),%r4  
-+    BVE     (%r2)   
-+        .EXIT
-+    LDD,MB  -352(%r30),%r3 
-+
-+bn_div_err_case
-+    MFIA    %r6     
-+    ADDIL   L'bn_div_words-bn_div_err_case,%r6,%r1 
-+    LDO     R'bn_div_words-bn_div_err_case(%r1),%r6  
-+    ADDIL   LT'__iob,%r27,%r1       
-+    LDD     RT'__iob(%r1),%r26      
-+    ADDIL   L'C$4-bn_div_words,%r6,%r1    
-+    LDO     R'C$4-bn_div_words(%r1),%r25  
-+    LDO     64(%r26),%r26   
-+    .CALL           ;in=24,25,26,29;out=28;
-+    B,L     fprintf,%r2    
-+    LDO     -48(%r30),%r29 
-+    LDD     -288(%r30),%r27
-+    .CALL           ;in=29;
-+    B,L     abort,%r2      
-+    LDO     -48(%r30),%r29 
-+    LDD     -288(%r30),%r27
-+    B       $D0         
-+    LDD     -368(%r30),%r2  
-+	.PROCEND	;in=24,25,26,29;out=28;
-+
-+;----------------------------------------------------------------------------
-+;
-+; Registers to hold 64-bit values to manipulate.  The "L" part
-+; of the register corresponds to the upper 32-bits, while the "R"
-+; part corresponds to the lower 32-bits
-+; 
-+; Note, that when using b6 and b7, the code must save these before
-+; using them because they are callee save registers 
-+; 
-+;
-+; Floating point registers to use to save values that
-+; are manipulated.  These don't collide with ftemp1-6 and
-+; are all caller save registers
-+;
-+a0        .reg %fr22
-+a0L       .reg %fr22L
-+a0R       .reg %fr22R
-+
-+a1        .reg %fr23
-+a1L       .reg %fr23L
-+a1R       .reg %fr23R
-+
-+a2        .reg %fr24
-+a2L       .reg %fr24L
-+a2R       .reg %fr24R
-+
-+a3        .reg %fr25
-+a3L       .reg %fr25L
-+a3R       .reg %fr25R
-+
-+a4        .reg %fr26
-+a4L       .reg %fr26L
-+a4R       .reg %fr26R
-+
-+a5        .reg %fr27
-+a5L       .reg %fr27L
-+a5R       .reg %fr27R
-+
-+a6        .reg %fr28
-+a6L       .reg %fr28L
-+a6R       .reg %fr28R
-+
-+a7        .reg %fr29
-+a7L       .reg %fr29L
-+a7R       .reg %fr29R
-+
-+b0        .reg %fr30
-+b0L       .reg %fr30L
-+b0R       .reg %fr30R
-+
-+b1        .reg %fr31
-+b1L       .reg %fr31L
-+b1R       .reg %fr31R
-+
-+;
-+; Temporary floating point variables, these are all caller save
-+; registers
-+;
-+ftemp1    .reg %fr4
-+ftemp2    .reg %fr5
-+ftemp3    .reg %fr6
-+ftemp4    .reg %fr7
-+
-+;
-+; The B set of registers when used.
-+;
-+
-+b2        .reg %fr8
-+b2L       .reg %fr8L
-+b2R       .reg %fr8R
-+
-+b3        .reg %fr9
-+b3L       .reg %fr9L
-+b3R       .reg %fr9R
-+
-+b4        .reg %fr10
-+b4L       .reg %fr10L
-+b4R       .reg %fr10R
-+
-+b5        .reg %fr11
-+b5L       .reg %fr11L
-+b5R       .reg %fr11R
-+
-+b6        .reg %fr12
-+b6L       .reg %fr12L
-+b6R       .reg %fr12R
-+
-+b7        .reg %fr13
-+b7L       .reg %fr13L
-+b7R       .reg %fr13R
-+
-+c1           .reg %r21   ; only reg
-+temp1        .reg %r20   ; only reg
-+temp2        .reg %r19   ; only reg
-+temp3        .reg %r31   ; only reg
-+
-+m1           .reg %r28   
-+c2           .reg %r23   
-+high_one     .reg %r1
-+ht           .reg %r6
-+lt           .reg %r5
-+m            .reg %r4
-+c3           .reg %r3
-+
-+SQR_ADD_C  .macro  A0L,A0R,C1,C2,C3
-+    XMPYU   A0L,A0R,ftemp1       ; m
-+    FSTD    ftemp1,-24(%sp)      ; store m
-+
-+    XMPYU   A0R,A0R,ftemp2       ; lt
-+    FSTD    ftemp2,-16(%sp)      ; store lt
-+
-+    XMPYU   A0L,A0L,ftemp3       ; ht
-+    FSTD    ftemp3,-8(%sp)       ; store ht
-+
-+    LDD     -24(%sp),m           ; load m
-+    AND     m,high_mask,temp2    ; m & Mask
-+    DEPD,Z  m,30,31,temp3        ; m << 32+1
-+    LDD     -16(%sp),lt          ; lt
-+
-+    LDD     -8(%sp),ht           ; ht
-+    EXTRD,U temp2,32,33,temp1    ; temp1 = m&Mask >> 32-1
-+    ADD     temp3,lt,lt          ; lt = lt+m
-+    ADD,L   ht,temp1,ht          ; ht += temp1
-+    ADD,DC  ht,%r0,ht            ; ht++
-+
-+    ADD     C1,lt,C1             ; c1=c1+lt
-+    ADD,DC  ht,%r0,ht            ; ht++
-+
-+    ADD     C2,ht,C2             ; c2=c2+ht
-+    ADD,DC  C3,%r0,C3            ; c3++
-+.endm
-+
-+SQR_ADD_C2 .macro  A0L,A0R,A1L,A1R,C1,C2,C3
-+    XMPYU   A0L,A1R,ftemp1          ; m1 = bl*ht
-+    FSTD    ftemp1,-16(%sp)         ;
-+    XMPYU   A0R,A1L,ftemp2          ; m = bh*lt
-+    FSTD    ftemp2,-8(%sp)          ;
-+    XMPYU   A0R,A1R,ftemp3          ; lt = bl*lt
-+    FSTD    ftemp3,-32(%sp)
-+    XMPYU   A0L,A1L,ftemp4          ; ht = bh*ht
-+    FSTD    ftemp4,-24(%sp)         ;
-+
-+    LDD     -8(%sp),m               ; r21 = m
-+    LDD     -16(%sp),m1             ; r19 = m1
-+    ADD,L   m,m1,m                  ; m+m1
-+
-+    DEPD,Z  m,31,32,temp3           ; (m+m1<<32)
-+    LDD     -24(%sp),ht             ; r24 = ht
-+
-+    CMPCLR,*>>= m,m1,%r0            ; if (m < m1)
-+    ADD,L   ht,high_one,ht          ; ht+=high_one
-+
-+    EXTRD,U m,31,32,temp1           ; m >> 32
-+    LDD     -32(%sp),lt             ; lt
-+    ADD,L   ht,temp1,ht             ; ht+= m>>32
-+    ADD     lt,temp3,lt             ; lt = lt+m1
-+    ADD,DC  ht,%r0,ht               ; ht++
-+
-+    ADD     ht,ht,ht                ; ht=ht+ht;
-+    ADD,DC  C3,%r0,C3               ; add in carry (c3++)
-+
-+    ADD     lt,lt,lt                ; lt=lt+lt;
-+    ADD,DC  ht,%r0,ht               ; add in carry (ht++)
-+
-+    ADD     C1,lt,C1                ; c1=c1+lt
-+    ADD,DC,*NUV ht,%r0,ht           ; add in carry (ht++)
-+    LDO     1(C3),C3              ; bump c3 if overflow,nullify otherwise
-+
-+    ADD     C2,ht,C2                ; c2 = c2 + ht
-+    ADD,DC  C3,%r0,C3             ; add in carry (c3++)
-+.endm
-+
-+;
-+;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
-+; arg0 = r_ptr
-+; arg1 = a_ptr
-+;
-+
-+bn_sqr_comba8
-+	.PROC
-+	.CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .ENTRY
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3
-+    STD     %r4,8(%sp)          ; save r4
-+    STD     %r5,16(%sp)         ; save r5
-+    STD     %r6,24(%sp)         ; save r6
-+
-+	;
-+	; Zero out carries
-+	;
-+	COPY     %r0,c1
-+	COPY     %r0,c2
-+	COPY     %r0,c3
-+
-+	LDO      128(%sp),%sp       ; bump stack
-+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
-+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
-+
-+	;
-+	; Load up all of the values we are going to use
-+	;
-+    FLDD     0(a_ptr),a0       
-+    FLDD     8(a_ptr),a1       
-+    FLDD    16(a_ptr),a2       
-+    FLDD    24(a_ptr),a3       
-+    FLDD    32(a_ptr),a4       
-+    FLDD    40(a_ptr),a5       
-+    FLDD    48(a_ptr),a6       
-+    FLDD    56(a_ptr),a7       
-+
-+	SQR_ADD_C a0L,a0R,c1,c2,c3
-+	STD     c1,0(r_ptr)          ; r[0] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
-+	STD     c2,8(r_ptr)          ; r[1] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C a1L,a1R,c3,c1,c2
-+	SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
-+	STD     c3,16(r_ptr)            ; r[2] = c3;
-+	COPY    %r0,c3
-+
-+	SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
-+	SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
-+	STD     c1,24(r_ptr)           ; r[3] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C a2L,a2R,c2,c3,c1
-+	SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
-+	SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1
-+	STD     c2,32(r_ptr)          ; r[4] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2
-+	SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2
-+	SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
-+	STD     c3,40(r_ptr)          ; r[5] = c3;
-+	COPY    %r0,c3
-+
-+	SQR_ADD_C a3L,a3R,c1,c2,c3
-+	SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3
-+	SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3
-+	SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3
-+	STD     c1,48(r_ptr)          ; r[6] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1
-+	SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1
-+	SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1
-+	SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1
-+	STD     c2,56(r_ptr)          ; r[7] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C a4L,a4R,c3,c1,c2
-+	SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2
-+	SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2
-+	SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2
-+	STD     c3,64(r_ptr)          ; r[8] = c3;
-+	COPY    %r0,c3
-+
-+	SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3
-+	SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3
-+	SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3
-+	STD     c1,72(r_ptr)          ; r[9] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C a5L,a5R,c2,c3,c1
-+	SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1
-+	SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1
-+	STD     c2,80(r_ptr)          ; r[10] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2
-+	SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2
-+	STD     c3,88(r_ptr)          ; r[11] = c3;
-+	COPY    %r0,c3
-+	
-+	SQR_ADD_C a6L,a6R,c1,c2,c3
-+	SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3
-+	STD     c1,96(r_ptr)          ; r[12] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1
-+	STD     c2,104(r_ptr)         ; r[13] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C a7L,a7R,c3,c1,c2
-+	STD     c3, 112(r_ptr)       ; r[14] = c3
-+	STD     c1, 120(r_ptr)       ; r[15] = c1
-+
-+    .EXIT
-+    LDD     -104(%sp),%r6        ; restore r6
-+    LDD     -112(%sp),%r5        ; restore r5
-+    LDD     -120(%sp),%r4        ; restore r4
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3
-+
-+	.PROCEND	
-+
-+;-----------------------------------------------------------------------------
-+;
-+;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
-+; arg0 = r_ptr
-+; arg1 = a_ptr
-+;
-+
-+bn_sqr_comba4
-+	.proc
-+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .entry
-+	.align 64
-+    STD     %r3,0(%sp)          ; save r3
-+    STD     %r4,8(%sp)          ; save r4
-+    STD     %r5,16(%sp)         ; save r5
-+    STD     %r6,24(%sp)         ; save r6
-+
-+	;
-+	; Zero out carries
-+	;
-+	COPY     %r0,c1
-+	COPY     %r0,c2
-+	COPY     %r0,c3
-+
-+	LDO      128(%sp),%sp       ; bump stack
-+    DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
-+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
-+
-+	;
-+	; Load up all of the values we are going to use
-+	;
-+    FLDD     0(a_ptr),a0       
-+    FLDD     8(a_ptr),a1       
-+    FLDD    16(a_ptr),a2       
-+    FLDD    24(a_ptr),a3       
-+    FLDD    32(a_ptr),a4       
-+    FLDD    40(a_ptr),a5       
-+    FLDD    48(a_ptr),a6       
-+    FLDD    56(a_ptr),a7       
-+
-+	SQR_ADD_C a0L,a0R,c1,c2,c3
-+
-+	STD     c1,0(r_ptr)          ; r[0] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
-+
-+	STD     c2,8(r_ptr)          ; r[1] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C a1L,a1R,c3,c1,c2
-+	SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
-+
-+	STD     c3,16(r_ptr)            ; r[2] = c3;
-+	COPY    %r0,c3
-+
-+	SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
-+	SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
-+
-+	STD     c1,24(r_ptr)           ; r[3] = c1;
-+	COPY    %r0,c1
-+
-+	SQR_ADD_C a2L,a2R,c2,c3,c1
-+	SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
-+
-+	STD     c2,32(r_ptr)           ; r[4] = c2;
-+	COPY    %r0,c2
-+
-+	SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
-+	STD     c3,40(r_ptr)           ; r[5] = c3;
-+	COPY    %r0,c3
-+
-+	SQR_ADD_C a3L,a3R,c1,c2,c3
-+	STD     c1,48(r_ptr)           ; r[6] = c1;
-+	STD     c2,56(r_ptr)           ; r[7] = c2;
-+
-+    .EXIT
-+    LDD     -104(%sp),%r6        ; restore r6
-+    LDD     -112(%sp),%r5        ; restore r5
-+    LDD     -120(%sp),%r4        ; restore r4
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3
-+
-+	.PROCEND	
-+
-+
-+;---------------------------------------------------------------------------
-+
-+MUL_ADD_C  .macro  A0L,A0R,B0L,B0R,C1,C2,C3
-+    XMPYU   A0L,B0R,ftemp1        ; m1 = bl*ht
-+    FSTD    ftemp1,-16(%sp)       ;
-+    XMPYU   A0R,B0L,ftemp2        ; m = bh*lt
-+    FSTD    ftemp2,-8(%sp)        ;
-+    XMPYU   A0R,B0R,ftemp3        ; lt = bl*lt
-+    FSTD    ftemp3,-32(%sp)
-+    XMPYU   A0L,B0L,ftemp4        ; ht = bh*ht
-+    FSTD    ftemp4,-24(%sp)       ;
-+
-+    LDD     -8(%sp),m             ; r21 = m
-+    LDD     -16(%sp),m1           ; r19 = m1
-+    ADD,L   m,m1,m                ; m+m1
-+
-+    DEPD,Z  m,31,32,temp3         ; (m+m1<<32)
-+    LDD     -24(%sp),ht           ; r24 = ht
-+
-+    CMPCLR,*>>= m,m1,%r0          ; if (m < m1)
-+    ADD,L   ht,high_one,ht        ; ht+=high_one
-+
-+    EXTRD,U m,31,32,temp1         ; m >> 32
-+    LDD     -32(%sp),lt           ; lt
-+    ADD,L   ht,temp1,ht           ; ht+= m>>32
-+    ADD     lt,temp3,lt           ; lt = lt+m1
-+    ADD,DC  ht,%r0,ht             ; ht++
-+
-+    ADD     C1,lt,C1              ; c1=c1+lt
-+    ADD,DC  ht,%r0,ht             ; bump c3 if overflow,nullify otherwise
-+
-+    ADD     C2,ht,C2              ; c2 = c2 + ht
-+    ADD,DC  C3,%r0,C3             ; add in carry (c3++)
-+.endm
-+
-+
-+;
-+;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
-+; arg0 = r_ptr
-+; arg1 = a_ptr
-+; arg2 = b_ptr
-+;
-+
-+bn_mul_comba8
-+	.proc
-+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .entry
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3
-+    STD     %r4,8(%sp)          ; save r4
-+    STD     %r5,16(%sp)         ; save r5
-+    STD     %r6,24(%sp)         ; save r6
-+    FSTD    %fr12,32(%sp)       ; save r6
-+    FSTD    %fr13,40(%sp)       ; save r7
-+
-+	;
-+	; Zero out carries
-+	;
-+	COPY     %r0,c1
-+	COPY     %r0,c2
-+	COPY     %r0,c3
-+
-+	LDO      128(%sp),%sp       ; bump stack
-+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
-+
-+	;
-+	; Load up all of the values we are going to use
-+	;
-+    FLDD      0(a_ptr),a0       
-+    FLDD      8(a_ptr),a1       
-+    FLDD     16(a_ptr),a2       
-+    FLDD     24(a_ptr),a3       
-+    FLDD     32(a_ptr),a4       
-+    FLDD     40(a_ptr),a5       
-+    FLDD     48(a_ptr),a6       
-+    FLDD     56(a_ptr),a7       
-+
-+    FLDD      0(b_ptr),b0       
-+    FLDD      8(b_ptr),b1       
-+    FLDD     16(b_ptr),b2       
-+    FLDD     24(b_ptr),b3       
-+    FLDD     32(b_ptr),b4       
-+    FLDD     40(b_ptr),b5       
-+    FLDD     48(b_ptr),b6       
-+    FLDD     56(b_ptr),b7       
-+
-+	MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
-+	STD       c1,0(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
-+	MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
-+	STD       c2,8(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
-+	MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
-+	MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
-+	STD       c3,16(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
-+	MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
-+	MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
-+	MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
-+	STD       c1,24(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1
-+	MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
-+	MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
-+	MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
-+	MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1
-+	STD       c2,32(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2
-+	MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2
-+	MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
-+	MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
-+	MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2
-+	MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2
-+	STD       c3,40(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3
-+	MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3
-+	MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3
-+	MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
-+	MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3
-+	MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3
-+	MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3
-+	STD       c1,48(r_ptr)
-+	COPY      %r0,c1
-+	
-+	MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1
-+	MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1
-+	MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1
-+	MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1
-+	MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1
-+	MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1
-+	MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1
-+	MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1
-+	STD       c2,56(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2
-+	MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2
-+	MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2
-+	MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2
-+	MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2
-+	MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2
-+	MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2
-+	STD       c3,64(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3
-+	MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3
-+	MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3
-+	MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3
-+	MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3
-+	MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3
-+	STD       c1,72(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1
-+	MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1
-+	MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1
-+	MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1
-+	MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1
-+	STD       c2,80(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2
-+	MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2
-+	MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2
-+	MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2
-+	STD       c3,88(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3
-+	MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3
-+	MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3
-+	STD       c1,96(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1
-+	MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1
-+	STD       c2,104(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2
-+	STD       c3,112(r_ptr)
-+	STD       c1,120(r_ptr)
-+
-+    .EXIT
-+    FLDD    -88(%sp),%fr13 
-+    FLDD    -96(%sp),%fr12 
-+    LDD     -104(%sp),%r6        ; restore r6
-+    LDD     -112(%sp),%r5        ; restore r5
-+    LDD     -120(%sp),%r4        ; restore r4
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3
-+
-+	.PROCEND	
-+
-+;-----------------------------------------------------------------------------
-+;
-+;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
-+; arg0 = r_ptr
-+; arg1 = a_ptr
-+; arg2 = b_ptr
-+;
-+
-+bn_mul_comba4
-+	.proc
-+	.callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
-+	.EXPORT	bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
-+    .entry
-+	.align 64
-+
-+    STD     %r3,0(%sp)          ; save r3
-+    STD     %r4,8(%sp)          ; save r4
-+    STD     %r5,16(%sp)         ; save r5
-+    STD     %r6,24(%sp)         ; save r6
-+    FSTD    %fr12,32(%sp)       ; save r6
-+    FSTD    %fr13,40(%sp)       ; save r7
-+
-+	;
-+	; Zero out carries
-+	;
-+	COPY     %r0,c1
-+	COPY     %r0,c2
-+	COPY     %r0,c3
-+
-+	LDO      128(%sp),%sp       ; bump stack
-+    DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
-+
-+	;
-+	; Load up all of the values we are going to use
-+	;
-+    FLDD      0(a_ptr),a0       
-+    FLDD      8(a_ptr),a1       
-+    FLDD     16(a_ptr),a2       
-+    FLDD     24(a_ptr),a3       
-+
-+    FLDD      0(b_ptr),b0       
-+    FLDD      8(b_ptr),b1       
-+    FLDD     16(b_ptr),b2       
-+    FLDD     24(b_ptr),b3       
-+
-+	MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
-+	STD       c1,0(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
-+	MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
-+	STD       c2,8(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
-+	MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
-+	MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
-+	STD       c3,16(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
-+	MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
-+	MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
-+	MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
-+	STD       c1,24(r_ptr)
-+	COPY      %r0,c1
-+
-+	MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
-+	MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
-+	MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
-+	STD       c2,32(r_ptr)
-+	COPY      %r0,c2
-+
-+	MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
-+	MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
-+	STD       c3,40(r_ptr)
-+	COPY      %r0,c3
-+
-+	MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
-+	STD       c1,48(r_ptr)
-+	STD       c2,56(r_ptr)
-+
-+    .EXIT
-+    FLDD    -88(%sp),%fr13 
-+    FLDD    -96(%sp),%fr12 
-+    LDD     -104(%sp),%r6        ; restore r6
-+    LDD     -112(%sp),%r5        ; restore r5
-+    LDD     -120(%sp),%r4        ; restore r4
-+    BVE     (%rp)
-+    LDD,MB  -128(%sp),%r3
-+
-+	.PROCEND	
-+
-+
-+	.SPACE	$TEXT$
-+	.SUBSPA	$CODE$
-+	.SPACE	$PRIVATE$,SORT=16
-+	.IMPORT	$global$,DATA
-+	.SPACE	$TEXT$
-+	.SUBSPA	$CODE$
-+	.SUBSPA	$LIT$,ACCESS=0x2c
-+C$4
-+	.ALIGN	8
-+	.STRINGZ	"Division would overflow (%d)\n"
-+	.END
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/parisc-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/parisc-mont.pl
-new file mode 100644
-index 0000000..8aa94e8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/parisc-mont.pl
-@@ -0,0 +1,1002 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# On PA-7100LC this module performs ~90-50% better, less for longer
-+# keys, than code generated by gcc 3.2 for PA-RISC 1.1. Latter means
-+# that compiler utilized xmpyu instruction to perform 32x32=64-bit
-+# multiplication, which in turn means that "baseline" performance was
-+# optimal in respect to instruction set capabilities. Fair comparison
-+# with vendor compiler is problematic, because OpenSSL doesn't define
-+# BN_LLONG [presumably] for historical reasons, which drives compiler
-+# toward 4 times 16x16=32-bit multiplicatons [plus complementary
-+# shifts and additions] instead. This means that you should observe
-+# several times improvement over code generated by vendor compiler
-+# for PA-RISC 1.1, but the "baseline" is far from optimal. The actual
-+# improvement coefficient was never collected on PA-7100LC, or any
-+# other 1.1 CPU, because I don't have access to such machine with
-+# vendor compiler. But to give you a taste, PA-RISC 1.1 code path
-+# reportedly outperformed code generated by cc +DA1.1 +O3 by factor
-+# of ~5x on PA-8600.
-+#
-+# On PA-RISC 2.0 it has to compete with pa-risc2[W].s, which is
-+# reportedly ~2x faster than vendor compiler generated code [according
-+# to comment in pa-risc2[W].s]. Here comes a catch. Execution core of
-+# this implementation is actually 32-bit one, in the sense that it
-+# operates on 32-bit values. But pa-risc2[W].s operates on arrays of
-+# 64-bit BN_LONGs... How do they interoperate then? No problem. This
-+# module picks halves of 64-bit values in reverse order and pretends
-+# they were 32-bit BN_LONGs. But can 32-bit core compete with "pure"
-+# 64-bit code such as pa-risc2[W].s then? Well, the thing is that
-+# 32x32=64-bit multiplication is the best even PA-RISC 2.0 can do,
-+# i.e. there is no "wider" multiplication like on most other 64-bit
-+# platforms. This means that even being effectively 32-bit, this
-+# implementation performs "64-bit" computational task in same amount
-+# of arithmetic operations, most notably multiplications. It requires
-+# more memory references, most notably to tp[num], but this doesn't
-+# seem to exhaust memory port capacity. And indeed, dedicated PA-RISC
-+# 2.0 code path provides virtually same performance as pa-risc2[W].s:
-+# it's ~10% better for shortest key length and ~10% worse for longest
-+# one.
-+#
-+# In case it wasn't clear. The module has two distinct code paths:
-+# PA-RISC 1.1 and PA-RISC 2.0 ones. Latter features carry-free 64-bit
-+# additions and 64-bit integer loads, not to mention specific
-+# instruction scheduling. In 64-bit build naturally only 2.0 code path
-+# is assembled. In 32-bit application context both code paths are
-+# assembled, PA-RISC 2.0 CPU is detected at run-time and proper path
-+# is taken automatically. Also, in 32-bit build the module imposes
-+# couple of limitations: vector lengths has to be even and vector
-+# addresses has to be 64-bit aligned. Normally neither is a problem:
-+# most common key lengths are even and vectors are commonly malloc-ed,
-+# which ensures alignment.
-+#
-+# Special thanks to polarhome.com for providing HP-UX account on
-+# PA-RISC 1.1 machine, and to correspondent who chose to remain
-+# anonymous for testing the code on PA-RISC 2.0 machine.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+
-+$flavour = shift;
-+$output = shift;
-+
-+open STDOUT,">$output";
-+
-+if ($flavour =~ /64/) {
-+	$LEVEL		="2.0W";
-+	$SIZE_T		=8;
-+	$FRAME_MARKER	=80;
-+	$SAVED_RP	=16;
-+	$PUSH		="std";
-+	$PUSHMA		="std,ma";
-+	$POP		="ldd";
-+	$POPMB		="ldd,mb";
-+	$BN_SZ		=$SIZE_T;
-+} else {
-+	$LEVEL		="1.1";	#$LEVEL.="\n\t.ALLOW\t2.0";
-+	$SIZE_T		=4;
-+	$FRAME_MARKER	=48;
-+	$SAVED_RP	=20;
-+	$PUSH		="stw";
-+	$PUSHMA		="stwm";
-+	$POP		="ldw";
-+	$POPMB		="ldwm";
-+	$BN_SZ		=$SIZE_T;
-+	if (open CONF,"<${dir}../../opensslconf.h") {
-+	    while() {
-+		if (m/#\s*define\s+SIXTY_FOUR_BIT/) {
-+		    $BN_SZ=8;
-+		    $LEVEL="2.0";
-+		    last;
-+		}
-+	    }
-+	    close CONF;
-+	}
-+}
-+
-+$FRAME=8*$SIZE_T+$FRAME_MARKER;	# 8 saved regs + frame marker
-+				#                [+ argument transfer]
-+$LOCALS=$FRAME-$FRAME_MARKER;
-+$FRAME+=32;			# local variables
-+
-+$tp="%r31";
-+$ti1="%r29";
-+$ti0="%r28";
-+
-+$rp="%r26";
-+$ap="%r25";
-+$bp="%r24";
-+$np="%r23";
-+$n0="%r22";	# passed through stack in 32-bit
-+$num="%r21";	# passed through stack in 32-bit
-+$idx="%r20";
-+$arrsz="%r19";
-+
-+$nm1="%r7";
-+$nm0="%r6";
-+$ab1="%r5";
-+$ab0="%r4";
-+
-+$fp="%r3";
-+$hi1="%r2";
-+$hi0="%r1";
-+
-+$xfer=$n0;	# accommodates [-16..15] offset in fld[dw]s
-+
-+$fm0="%fr4";	$fti=$fm0;
-+$fbi="%fr5L";
-+$fn0="%fr5R";
-+$fai="%fr6";	$fab0="%fr7";	$fab1="%fr8";
-+$fni="%fr9";	$fnm0="%fr10";	$fnm1="%fr11";
-+
-+$code=<<___;
-+	.LEVEL	$LEVEL
-+	.SPACE	\$TEXT\$
-+	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
-+
-+	.EXPORT	bn_mul_mont,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
-+	.ALIGN	64
-+bn_mul_mont
-+	.PROC
-+	.CALLINFO	FRAME=`$FRAME-8*$SIZE_T`,NO_CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=6
-+	.ENTRY
-+	$PUSH	%r2,-$SAVED_RP(%sp)		; standard prologue
-+	$PUSHMA	%r3,$FRAME(%sp)
-+	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
-+	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
-+	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
-+	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
-+	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
-+	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
-+	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
-+	ldo	-$FRAME(%sp),$fp
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	ldw	`-$FRAME_MARKER-4`($fp),$n0
-+	ldw	`-$FRAME_MARKER-8`($fp),$num
-+	nop
-+	nop					; alignment
-+___
-+$code.=<<___ if ($BN_SZ==4);
-+	comiclr,<=	6,$num,%r0		; are vectors long enough?
-+	b		L\$abort
-+	ldi		0,%r28			; signal "unhandled"
-+	add,ev		%r0,$num,$num		; is $num even?
-+	b		L\$abort
-+	nop
-+	or		$ap,$np,$ti1
-+	extru,=		$ti1,31,3,%r0		; are ap and np 64-bit aligned?
-+	b		L\$abort
-+	nop
-+	nop					; alignment
-+	nop
-+
-+	fldws		0($n0),${fn0}
-+	fldws,ma	4($bp),${fbi}		; bp[0]
-+___
-+$code.=<<___ if ($BN_SZ==8);
-+	comib,>		3,$num,L\$abort		; are vectors long enough?
-+	ldi		0,%r28			; signal "unhandled"
-+	addl		$num,$num,$num		; I operate on 32-bit values
-+
-+	fldws		4($n0),${fn0}		; only low part of n0
-+	fldws		4($bp),${fbi}		; bp[0] in flipped word order
-+___
-+$code.=<<___;
-+	fldds		0($ap),${fai}		; ap[0,1]
-+	fldds		0($np),${fni}		; np[0,1]
-+
-+	sh2addl		$num,%r0,$arrsz
-+	ldi		31,$hi0
-+	ldo		36($arrsz),$hi1		; space for tp[num+1]
-+	andcm		$hi1,$hi0,$hi1		; align
-+	addl		$hi1,%sp,%sp
-+	$PUSH		$fp,-$SIZE_T(%sp)
-+
-+	ldo		`$LOCALS+16`($fp),$xfer
-+	ldo		`$LOCALS+32+4`($fp),$tp
-+
-+	xmpyu		${fai}L,${fbi},${fab0}	; ap[0]*bp[0]
-+	xmpyu		${fai}R,${fbi},${fab1}	; ap[1]*bp[0]
-+	xmpyu		${fn0},${fab0}R,${fm0}
-+
-+	addl		$arrsz,$ap,$ap		; point at the end
-+	addl		$arrsz,$np,$np
-+	subi		0,$arrsz,$idx		; j=0
-+	ldo		8($idx),$idx		; j++++
-+
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[0]*m
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[1]*m
-+	fstds		${fab0},-16($xfer)
-+	fstds		${fnm0},-8($xfer)
-+	fstds		${fab1},0($xfer)
-+	fstds		${fnm1},8($xfer)
-+	 flddx		$idx($ap),${fai}	; ap[2,3]
-+	 flddx		$idx($np),${fni}	; np[2,3]
-+___
-+$code.=<<___ if ($BN_SZ==4);
-+	mtctl		$hi0,%cr11		; $hi0 still holds 31
-+	extrd,u,*=	$hi0,%sar,1,$hi0	; executes on PA-RISC 1.0
-+	b		L\$parisc11
-+	nop
-+___
-+$code.=<<___;					# PA-RISC 2.0 code-path
-+	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[0]
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
-+	ldd		-16($xfer),$ab0
-+	fstds		${fab0},-16($xfer)
-+
-+	extrd,u		$ab0,31,32,$hi0
-+	extrd,u		$ab0,63,32,$ab0
-+	ldd		-8($xfer),$nm0
-+	fstds		${fnm0},-8($xfer)
-+	 ldo		8($idx),$idx		; j++++
-+	 addl		$ab0,$nm0,$nm0		; low part is discarded
-+	 extrd,u	$nm0,31,32,$hi1
-+
-+L\$1st
-+	xmpyu		${fai}R,${fbi},${fab1}	; ap[j+1]*bp[0]
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j+1]*m
-+	ldd		0($xfer),$ab1
-+	fstds		${fab1},0($xfer)
-+	 addl		$hi0,$ab1,$ab1
-+	 extrd,u	$ab1,31,32,$hi0
-+	ldd		8($xfer),$nm1
-+	fstds		${fnm1},8($xfer)
-+	 extrd,u	$ab1,63,32,$ab1
-+	 addl		$hi1,$nm1,$nm1
-+	flddx		$idx($ap),${fai}	; ap[j,j+1]
-+	flddx		$idx($np),${fni}	; np[j,j+1]
-+	 addl		$ab1,$nm1,$nm1
-+	 extrd,u	$nm1,31,32,$hi1
-+
-+	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[0]
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
-+	ldd		-16($xfer),$ab0
-+	fstds		${fab0},-16($xfer)
-+	 addl		$hi0,$ab0,$ab0
-+	 extrd,u	$ab0,31,32,$hi0
-+	ldd		-8($xfer),$nm0
-+	fstds		${fnm0},-8($xfer)
-+	 extrd,u	$ab0,63,32,$ab0
-+	 addl		$hi1,$nm0,$nm0
-+	stw		$nm1,-4($tp)		; tp[j-1]
-+	 addl		$ab0,$nm0,$nm0
-+	 stw,ma		$nm0,8($tp)		; tp[j-1]
-+	addib,<>	8,$idx,L\$1st		; j++++
-+	 extrd,u	$nm0,31,32,$hi1
-+
-+	xmpyu		${fai}R,${fbi},${fab1}	; ap[j]*bp[0]
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j]*m
-+	ldd		0($xfer),$ab1
-+	fstds		${fab1},0($xfer)
-+	 addl		$hi0,$ab1,$ab1
-+	 extrd,u	$ab1,31,32,$hi0
-+	ldd		8($xfer),$nm1
-+	fstds		${fnm1},8($xfer)
-+	 extrd,u	$ab1,63,32,$ab1
-+	 addl		$hi1,$nm1,$nm1
-+	ldd		-16($xfer),$ab0
-+	 addl		$ab1,$nm1,$nm1
-+	ldd		-8($xfer),$nm0
-+	 extrd,u	$nm1,31,32,$hi1
-+
-+	 addl		$hi0,$ab0,$ab0
-+	 extrd,u	$ab0,31,32,$hi0
-+	stw		$nm1,-4($tp)		; tp[j-1]
-+	 extrd,u	$ab0,63,32,$ab0
-+	 addl		$hi1,$nm0,$nm0
-+	ldd		0($xfer),$ab1
-+	 addl		$ab0,$nm0,$nm0
-+	ldd,mb		8($xfer),$nm1
-+	 extrd,u	$nm0,31,32,$hi1
-+	stw,ma		$nm0,8($tp)		; tp[j-1]
-+
-+	ldo		-1($num),$num		; i--
-+	subi		0,$arrsz,$idx		; j=0
-+___
-+$code.=<<___ if ($BN_SZ==4);
-+	fldws,ma	4($bp),${fbi}		; bp[1]
-+___
-+$code.=<<___ if ($BN_SZ==8);
-+	fldws		0($bp),${fbi}		; bp[1] in flipped word order
-+___
-+$code.=<<___;
-+	 flddx		$idx($ap),${fai}	; ap[0,1]
-+	 flddx		$idx($np),${fni}	; np[0,1]
-+	 fldws		8($xfer),${fti}R	; tp[0]
-+	addl		$hi0,$ab1,$ab1
-+	 extrd,u	$ab1,31,32,$hi0
-+	 extrd,u	$ab1,63,32,$ab1
-+	 ldo		8($idx),$idx		; j++++
-+	 xmpyu		${fai}L,${fbi},${fab0}	; ap[0]*bp[1]
-+	 xmpyu		${fai}R,${fbi},${fab1}	; ap[1]*bp[1]
-+	addl		$hi1,$nm1,$nm1
-+	addl		$ab1,$nm1,$nm1
-+	extrd,u		$nm1,31,32,$hi1
-+	 fstws,mb	${fab0}L,-8($xfer)	; save high part
-+	stw		$nm1,-4($tp)		; tp[j-1]
-+
-+	 fcpy,sgl	%fr0,${fti}L		; zero high part
-+	 fcpy,sgl	%fr0,${fab0}L
-+	addl		$hi1,$hi0,$hi0
-+	extrd,u		$hi0,31,32,$hi1
-+	 fcnvxf,dbl,dbl	${fti},${fti}		; 32-bit unsigned int -> double
-+	 fcnvxf,dbl,dbl	${fab0},${fab0}
-+	stw		$hi0,0($tp)
-+	stw		$hi1,4($tp)
-+
-+	fadd,dbl	${fti},${fab0},${fab0}	; add tp[0]
-+	fcnvfx,dbl,dbl	${fab0},${fab0}		; double -> 33-bit unsigned int
-+	xmpyu		${fn0},${fab0}R,${fm0}
-+	ldo		`$LOCALS+32+4`($fp),$tp
-+L\$outer
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[0]*m
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[1]*m
-+	fstds		${fab0},-16($xfer)	; 33-bit value
-+	fstds		${fnm0},-8($xfer)
-+	 flddx		$idx($ap),${fai}	; ap[2]
-+	 flddx		$idx($np),${fni}	; np[2]
-+	 ldo		8($idx),$idx		; j++++
-+	ldd		-16($xfer),$ab0		; 33-bit value
-+	ldd		-8($xfer),$nm0
-+	ldw		0($xfer),$hi0		; high part
-+
-+	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[i]
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
-+	 extrd,u	$ab0,31,32,$ti0		; carry bit
-+	 extrd,u	$ab0,63,32,$ab0
-+	fstds		${fab1},0($xfer)
-+	 addl		$ti0,$hi0,$hi0		; account carry bit
-+	fstds		${fnm1},8($xfer)
-+	 addl		$ab0,$nm0,$nm0		; low part is discarded
-+	ldw		0($tp),$ti1		; tp[1]
-+	 extrd,u	$nm0,31,32,$hi1
-+	fstds		${fab0},-16($xfer)
-+	fstds		${fnm0},-8($xfer)
-+
-+L\$inner
-+	xmpyu		${fai}R,${fbi},${fab1}	; ap[j+1]*bp[i]
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j+1]*m
-+	ldd		0($xfer),$ab1
-+	fstds		${fab1},0($xfer)
-+	 addl		$hi0,$ti1,$ti1
-+	 addl		$ti1,$ab1,$ab1
-+	ldd		8($xfer),$nm1
-+	fstds		${fnm1},8($xfer)
-+	 extrd,u	$ab1,31,32,$hi0
-+	 extrd,u	$ab1,63,32,$ab1
-+	flddx		$idx($ap),${fai}	; ap[j,j+1]
-+	flddx		$idx($np),${fni}	; np[j,j+1]
-+	 addl		$hi1,$nm1,$nm1
-+	 addl		$ab1,$nm1,$nm1
-+	ldw		4($tp),$ti0		; tp[j]
-+	stw		$nm1,-4($tp)		; tp[j-1]
-+
-+	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[i]
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
-+	ldd		-16($xfer),$ab0
-+	fstds		${fab0},-16($xfer)
-+	 addl		$hi0,$ti0,$ti0
-+	 addl		$ti0,$ab0,$ab0
-+	ldd		-8($xfer),$nm0
-+	fstds		${fnm0},-8($xfer)
-+	 extrd,u	$ab0,31,32,$hi0
-+	 extrd,u	$nm1,31,32,$hi1
-+	ldw		8($tp),$ti1		; tp[j]
-+	 extrd,u	$ab0,63,32,$ab0
-+	 addl		$hi1,$nm0,$nm0
-+	 addl		$ab0,$nm0,$nm0
-+	 stw,ma		$nm0,8($tp)		; tp[j-1]
-+	addib,<>	8,$idx,L\$inner		; j++++
-+	 extrd,u	$nm0,31,32,$hi1
-+
-+	xmpyu		${fai}R,${fbi},${fab1}	; ap[j]*bp[i]
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j]*m
-+	ldd		0($xfer),$ab1
-+	fstds		${fab1},0($xfer)
-+	 addl		$hi0,$ti1,$ti1
-+	 addl		$ti1,$ab1,$ab1
-+	ldd		8($xfer),$nm1
-+	fstds		${fnm1},8($xfer)
-+	 extrd,u	$ab1,31,32,$hi0
-+	 extrd,u	$ab1,63,32,$ab1
-+	ldw		4($tp),$ti0		; tp[j]
-+	 addl		$hi1,$nm1,$nm1
-+	 addl		$ab1,$nm1,$nm1
-+	ldd		-16($xfer),$ab0
-+	ldd		-8($xfer),$nm0
-+	 extrd,u	$nm1,31,32,$hi1
-+
-+	addl		$hi0,$ab0,$ab0
-+	 addl		$ti0,$ab0,$ab0
-+	 stw		$nm1,-4($tp)		; tp[j-1]
-+	 extrd,u	$ab0,31,32,$hi0
-+	ldw		8($tp),$ti1		; tp[j]
-+	 extrd,u	$ab0,63,32,$ab0
-+	 addl		$hi1,$nm0,$nm0
-+	ldd		0($xfer),$ab1
-+	 addl		$ab0,$nm0,$nm0
-+	ldd,mb		8($xfer),$nm1
-+	 extrd,u	$nm0,31,32,$hi1
-+	 stw,ma		$nm0,8($tp)		; tp[j-1]
-+
-+	addib,=		-1,$num,L\$outerdone	; i--
-+	subi		0,$arrsz,$idx		; j=0
-+___
-+$code.=<<___ if ($BN_SZ==4);
-+	fldws,ma	4($bp),${fbi}		; bp[i]
-+___
-+$code.=<<___ if ($BN_SZ==8);
-+	ldi		12,$ti0			; bp[i] in flipped word order
-+	addl,ev		%r0,$num,$num
-+	ldi		-4,$ti0
-+	addl		$ti0,$bp,$bp
-+	fldws		0($bp),${fbi}
-+___
-+$code.=<<___;
-+	 flddx		$idx($ap),${fai}	; ap[0]
-+	addl		$hi0,$ab1,$ab1
-+	 flddx		$idx($np),${fni}	; np[0]
-+	 fldws		8($xfer),${fti}R	; tp[0]
-+	addl		$ti1,$ab1,$ab1
-+	extrd,u		$ab1,31,32,$hi0
-+	extrd,u		$ab1,63,32,$ab1
-+
-+	 ldo		8($idx),$idx		; j++++
-+	 xmpyu		${fai}L,${fbi},${fab0}	; ap[0]*bp[i]
-+	 xmpyu		${fai}R,${fbi},${fab1}	; ap[1]*bp[i]
-+	ldw		4($tp),$ti0		; tp[j]
-+
-+	addl		$hi1,$nm1,$nm1
-+	 fstws,mb	${fab0}L,-8($xfer)	; save high part
-+	addl		$ab1,$nm1,$nm1
-+	extrd,u		$nm1,31,32,$hi1
-+	 fcpy,sgl	%fr0,${fti}L		; zero high part
-+	 fcpy,sgl	%fr0,${fab0}L
-+	stw		$nm1,-4($tp)		; tp[j-1]
-+
-+	 fcnvxf,dbl,dbl	${fti},${fti}		; 32-bit unsigned int -> double
-+	 fcnvxf,dbl,dbl	${fab0},${fab0}
-+	addl		$hi1,$hi0,$hi0
-+	 fadd,dbl	${fti},${fab0},${fab0}	; add tp[0]
-+	addl		$ti0,$hi0,$hi0
-+	extrd,u		$hi0,31,32,$hi1
-+	 fcnvfx,dbl,dbl	${fab0},${fab0}		; double -> 33-bit unsigned int
-+	stw		$hi0,0($tp)
-+	stw		$hi1,4($tp)
-+	 xmpyu		${fn0},${fab0}R,${fm0}
-+
-+	b		L\$outer
-+	ldo		`$LOCALS+32+4`($fp),$tp
-+
-+L\$outerdone
-+	addl		$hi0,$ab1,$ab1
-+	addl		$ti1,$ab1,$ab1
-+	extrd,u		$ab1,31,32,$hi0
-+	extrd,u		$ab1,63,32,$ab1
-+
-+	ldw		4($tp),$ti0		; tp[j]
-+
-+	addl		$hi1,$nm1,$nm1
-+	addl		$ab1,$nm1,$nm1
-+	extrd,u		$nm1,31,32,$hi1
-+	stw		$nm1,-4($tp)		; tp[j-1]
-+
-+	addl		$hi1,$hi0,$hi0
-+	addl		$ti0,$hi0,$hi0
-+	extrd,u		$hi0,31,32,$hi1
-+	stw		$hi0,0($tp)
-+	stw		$hi1,4($tp)
-+
-+	ldo		`$LOCALS+32`($fp),$tp
-+	sub		%r0,%r0,%r0		; clear borrow
-+___
-+$code.=<<___ if ($BN_SZ==4);
-+	ldws,ma		4($tp),$ti0
-+	extru,=		$rp,31,3,%r0		; is rp 64-bit aligned?
-+	b		L\$sub_pa11
-+	addl		$tp,$arrsz,$tp
-+L\$sub
-+	ldwx		$idx($np),$hi0
-+	subb		$ti0,$hi0,$hi1
-+	ldwx		$idx($tp),$ti0
-+	addib,<>	4,$idx,L\$sub
-+	stws,ma		$hi1,4($rp)
-+
-+	subb		$ti0,%r0,$hi1
-+	ldo		-4($tp),$tp
-+___
-+$code.=<<___ if ($BN_SZ==8);
-+	ldd,ma		8($tp),$ti0
-+L\$sub
-+	ldd		$idx($np),$hi0
-+	shrpd		$ti0,$ti0,32,$ti0	; flip word order
-+	std		$ti0,-8($tp)		; save flipped value
-+	sub,db		$ti0,$hi0,$hi1
-+	ldd,ma		8($tp),$ti0
-+	addib,<>	8,$idx,L\$sub
-+	std,ma		$hi1,8($rp)
-+
-+	extrd,u		$ti0,31,32,$ti0		; carry in flipped word order
-+	sub,db		$ti0,%r0,$hi1
-+	ldo		-8($tp),$tp
-+___
-+$code.=<<___;
-+	and		$tp,$hi1,$ap
-+	andcm		$rp,$hi1,$bp
-+	or		$ap,$bp,$np
-+
-+	sub		$rp,$arrsz,$rp		; rewind rp
-+	subi		0,$arrsz,$idx
-+	ldo		`$LOCALS+32`($fp),$tp
-+L\$copy
-+	ldd		$idx($np),$hi0
-+	std,ma		%r0,8($tp)
-+	addib,<>	8,$idx,.-8		; L\$copy
-+	std,ma		$hi0,8($rp)	
-+___
-+
-+if ($BN_SZ==4) {				# PA-RISC 1.1 code-path
-+$ablo=$ab0;
-+$abhi=$ab1;
-+$nmlo0=$nm0;
-+$nmhi0=$nm1;
-+$nmlo1="%r9";
-+$nmhi1="%r8";
-+
-+$code.=<<___;
-+	b		L\$done
-+	nop
-+
-+	.ALIGN		8
-+L\$parisc11
-+	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[0]
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
-+	ldw		-12($xfer),$ablo
-+	ldw		-16($xfer),$hi0
-+	ldw		-4($xfer),$nmlo0
-+	ldw		-8($xfer),$nmhi0
-+	fstds		${fab0},-16($xfer)
-+	fstds		${fnm0},-8($xfer)
-+
-+	 ldo		8($idx),$idx		; j++++
-+	 add		$ablo,$nmlo0,$nmlo0	; discarded
-+	 addc		%r0,$nmhi0,$hi1
-+	ldw		4($xfer),$ablo
-+	ldw		0($xfer),$abhi
-+	nop
-+
-+L\$1st_pa11
-+	xmpyu		${fai}R,${fbi},${fab1}	; ap[j+1]*bp[0]
-+	flddx		$idx($ap),${fai}	; ap[j,j+1]
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j+1]*m
-+	flddx		$idx($np),${fni}	; np[j,j+1]
-+	 add		$hi0,$ablo,$ablo
-+	ldw		12($xfer),$nmlo1
-+	 addc		%r0,$abhi,$hi0
-+	ldw		8($xfer),$nmhi1
-+	 add		$ablo,$nmlo1,$nmlo1
-+	fstds		${fab1},0($xfer)
-+	 addc		%r0,$nmhi1,$nmhi1
-+	fstds		${fnm1},8($xfer)
-+	 add		$hi1,$nmlo1,$nmlo1
-+	ldw		-12($xfer),$ablo
-+	 addc		%r0,$nmhi1,$hi1
-+	ldw		-16($xfer),$abhi
-+
-+	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[0]
-+	ldw		-4($xfer),$nmlo0
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
-+	ldw		-8($xfer),$nmhi0
-+	 add		$hi0,$ablo,$ablo
-+	stw		$nmlo1,-4($tp)		; tp[j-1]
-+	 addc		%r0,$abhi,$hi0
-+	fstds		${fab0},-16($xfer)
-+	 add		$ablo,$nmlo0,$nmlo0
-+	fstds		${fnm0},-8($xfer)
-+	 addc		%r0,$nmhi0,$nmhi0
-+	ldw		0($xfer),$abhi
-+	 add		$hi1,$nmlo0,$nmlo0
-+	ldw		4($xfer),$ablo
-+	 stws,ma	$nmlo0,8($tp)		; tp[j-1]
-+	addib,<>	8,$idx,L\$1st_pa11	; j++++
-+	 addc		%r0,$nmhi0,$hi1
-+
-+	 ldw		8($xfer),$nmhi1
-+	 ldw		12($xfer),$nmlo1
-+	xmpyu		${fai}R,${fbi},${fab1}	; ap[j]*bp[0]
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j]*m
-+	 add		$hi0,$ablo,$ablo
-+	fstds		${fab1},0($xfer)
-+	 addc		%r0,$abhi,$hi0
-+	fstds		${fnm1},8($xfer)
-+	 add		$ablo,$nmlo1,$nmlo1
-+	ldw		-16($xfer),$abhi
-+	 addc		%r0,$nmhi1,$nmhi1
-+	ldw		-12($xfer),$ablo
-+	 add		$hi1,$nmlo1,$nmlo1
-+	ldw		-8($xfer),$nmhi0
-+	 addc		%r0,$nmhi1,$hi1
-+	ldw		-4($xfer),$nmlo0
-+
-+	 add		$hi0,$ablo,$ablo
-+	stw		$nmlo1,-4($tp)		; tp[j-1]
-+	 addc		%r0,$abhi,$hi0
-+	ldw		0($xfer),$abhi
-+	 add		$ablo,$nmlo0,$nmlo0
-+	ldw		4($xfer),$ablo
-+	 addc		%r0,$nmhi0,$nmhi0
-+	ldws,mb		8($xfer),$nmhi1
-+	 add		$hi1,$nmlo0,$nmlo0
-+	ldw		4($xfer),$nmlo1
-+	 addc		%r0,$nmhi0,$hi1
-+	stws,ma		$nmlo0,8($tp)		; tp[j-1]
-+
-+	ldo		-1($num),$num		; i--
-+	subi		0,$arrsz,$idx		; j=0
-+
-+	 fldws,ma	4($bp),${fbi}		; bp[1]
-+	 flddx		$idx($ap),${fai}	; ap[0,1]
-+	 flddx		$idx($np),${fni}	; np[0,1]
-+	 fldws		8($xfer),${fti}R	; tp[0]
-+	add		$hi0,$ablo,$ablo
-+	addc		%r0,$abhi,$hi0
-+	 ldo		8($idx),$idx		; j++++
-+	 xmpyu		${fai}L,${fbi},${fab0}	; ap[0]*bp[1]
-+	 xmpyu		${fai}R,${fbi},${fab1}	; ap[1]*bp[1]
-+	add		$hi1,$nmlo1,$nmlo1
-+	addc		%r0,$nmhi1,$nmhi1
-+	add		$ablo,$nmlo1,$nmlo1
-+	addc		%r0,$nmhi1,$hi1
-+	 fstws,mb	${fab0}L,-8($xfer)	; save high part
-+	stw		$nmlo1,-4($tp)		; tp[j-1]
-+
-+	 fcpy,sgl	%fr0,${fti}L		; zero high part
-+	 fcpy,sgl	%fr0,${fab0}L
-+	add		$hi1,$hi0,$hi0
-+	addc		%r0,%r0,$hi1
-+	 fcnvxf,dbl,dbl	${fti},${fti}		; 32-bit unsigned int -> double
-+	 fcnvxf,dbl,dbl	${fab0},${fab0}
-+	stw		$hi0,0($tp)
-+	stw		$hi1,4($tp)
-+
-+	fadd,dbl	${fti},${fab0},${fab0}	; add tp[0]
-+	fcnvfx,dbl,dbl	${fab0},${fab0}		; double -> 33-bit unsigned int
-+	xmpyu		${fn0},${fab0}R,${fm0}
-+	ldo		`$LOCALS+32+4`($fp),$tp
-+L\$outer_pa11
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[0]*m
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[1]*m
-+	fstds		${fab0},-16($xfer)	; 33-bit value
-+	fstds		${fnm0},-8($xfer)
-+	 flddx		$idx($ap),${fai}	; ap[2,3]
-+	 flddx		$idx($np),${fni}	; np[2,3]
-+	ldw		-16($xfer),$abhi	; carry bit actually
-+	 ldo		8($idx),$idx		; j++++
-+	ldw		-12($xfer),$ablo
-+	ldw		-8($xfer),$nmhi0
-+	ldw		-4($xfer),$nmlo0
-+	ldw		0($xfer),$hi0		; high part
-+
-+	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[i]
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
-+	fstds		${fab1},0($xfer)
-+	 addl		$abhi,$hi0,$hi0		; account carry bit
-+	fstds		${fnm1},8($xfer)
-+	 add		$ablo,$nmlo0,$nmlo0	; discarded
-+	ldw		0($tp),$ti1		; tp[1]
-+	 addc		%r0,$nmhi0,$hi1
-+	fstds		${fab0},-16($xfer)
-+	fstds		${fnm0},-8($xfer)
-+	ldw		4($xfer),$ablo
-+	ldw		0($xfer),$abhi
-+
-+L\$inner_pa11
-+	xmpyu		${fai}R,${fbi},${fab1}	; ap[j+1]*bp[i]
-+	flddx		$idx($ap),${fai}	; ap[j,j+1]
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j+1]*m
-+	flddx		$idx($np),${fni}	; np[j,j+1]
-+	 add		$hi0,$ablo,$ablo
-+	ldw		4($tp),$ti0		; tp[j]
-+	 addc		%r0,$abhi,$abhi
-+	ldw		12($xfer),$nmlo1
-+	 add		$ti1,$ablo,$ablo
-+	ldw		8($xfer),$nmhi1
-+	 addc		%r0,$abhi,$hi0
-+	fstds		${fab1},0($xfer)
-+	 add		$ablo,$nmlo1,$nmlo1
-+	fstds		${fnm1},8($xfer)
-+	 addc		%r0,$nmhi1,$nmhi1
-+	ldw		-12($xfer),$ablo
-+	 add		$hi1,$nmlo1,$nmlo1
-+	ldw		-16($xfer),$abhi
-+	 addc		%r0,$nmhi1,$hi1
-+
-+	xmpyu		${fai}L,${fbi},${fab0}	; ap[j]*bp[i]
-+	ldw		8($tp),$ti1		; tp[j]
-+	xmpyu		${fni}L,${fm0}R,${fnm0}	; np[j]*m
-+	ldw		-4($xfer),$nmlo0
-+	 add		$hi0,$ablo,$ablo
-+	ldw		-8($xfer),$nmhi0
-+	 addc		%r0,$abhi,$abhi
-+	stw		$nmlo1,-4($tp)		; tp[j-1]
-+	 add		$ti0,$ablo,$ablo
-+	fstds		${fab0},-16($xfer)
-+	 addc		%r0,$abhi,$hi0
-+	fstds		${fnm0},-8($xfer)
-+	 add		$ablo,$nmlo0,$nmlo0
-+	ldw		4($xfer),$ablo
-+	 addc		%r0,$nmhi0,$nmhi0
-+	ldw		0($xfer),$abhi
-+	 add		$hi1,$nmlo0,$nmlo0
-+	 stws,ma	$nmlo0,8($tp)		; tp[j-1]
-+	addib,<>	8,$idx,L\$inner_pa11	; j++++
-+	 addc		%r0,$nmhi0,$hi1
-+
-+	xmpyu		${fai}R,${fbi},${fab1}	; ap[j]*bp[i]
-+	ldw		12($xfer),$nmlo1
-+	xmpyu		${fni}R,${fm0}R,${fnm1}	; np[j]*m
-+	ldw		8($xfer),$nmhi1
-+	 add		$hi0,$ablo,$ablo
-+	ldw		4($tp),$ti0		; tp[j]
-+	 addc		%r0,$abhi,$abhi
-+	fstds		${fab1},0($xfer)
-+	 add		$ti1,$ablo,$ablo
-+	fstds		${fnm1},8($xfer)
-+	 addc		%r0,$abhi,$hi0
-+	ldw		-16($xfer),$abhi
-+	 add		$ablo,$nmlo1,$nmlo1
-+	ldw		-12($xfer),$ablo
-+	 addc		%r0,$nmhi1,$nmhi1
-+	ldw		-8($xfer),$nmhi0
-+	 add		$hi1,$nmlo1,$nmlo1
-+	ldw		-4($xfer),$nmlo0
-+	 addc		%r0,$nmhi1,$hi1
-+
-+	add		$hi0,$ablo,$ablo
-+	 stw		$nmlo1,-4($tp)		; tp[j-1]
-+	addc		%r0,$abhi,$abhi
-+	 add		$ti0,$ablo,$ablo
-+	ldw		8($tp),$ti1		; tp[j]
-+	 addc		%r0,$abhi,$hi0
-+	ldw		0($xfer),$abhi
-+	 add		$ablo,$nmlo0,$nmlo0
-+	ldw		4($xfer),$ablo
-+	 addc		%r0,$nmhi0,$nmhi0
-+	ldws,mb		8($xfer),$nmhi1
-+	 add		$hi1,$nmlo0,$nmlo0
-+	ldw		4($xfer),$nmlo1
-+	 addc		%r0,$nmhi0,$hi1
-+	 stws,ma	$nmlo0,8($tp)		; tp[j-1]
-+
-+	addib,=		-1,$num,L\$outerdone_pa11; i--
-+	subi		0,$arrsz,$idx		; j=0
-+
-+	 fldws,ma	4($bp),${fbi}		; bp[i]
-+	 flddx		$idx($ap),${fai}	; ap[0]
-+	add		$hi0,$ablo,$ablo
-+	addc		%r0,$abhi,$abhi
-+	 flddx		$idx($np),${fni}	; np[0]
-+	 fldws		8($xfer),${fti}R	; tp[0]
-+	add		$ti1,$ablo,$ablo
-+	addc		%r0,$abhi,$hi0
-+
-+	 ldo		8($idx),$idx		; j++++
-+	 xmpyu		${fai}L,${fbi},${fab0}	; ap[0]*bp[i]
-+	 xmpyu		${fai}R,${fbi},${fab1}	; ap[1]*bp[i]
-+	ldw		4($tp),$ti0		; tp[j]
-+
-+	add		$hi1,$nmlo1,$nmlo1
-+	addc		%r0,$nmhi1,$nmhi1
-+	 fstws,mb	${fab0}L,-8($xfer)	; save high part
-+	add		$ablo,$nmlo1,$nmlo1
-+	addc		%r0,$nmhi1,$hi1
-+	 fcpy,sgl	%fr0,${fti}L		; zero high part
-+	 fcpy,sgl	%fr0,${fab0}L
-+	stw		$nmlo1,-4($tp)		; tp[j-1]
-+
-+	 fcnvxf,dbl,dbl	${fti},${fti}		; 32-bit unsigned int -> double
-+	 fcnvxf,dbl,dbl	${fab0},${fab0}
-+	add		$hi1,$hi0,$hi0
-+	addc		%r0,%r0,$hi1
-+	 fadd,dbl	${fti},${fab0},${fab0}	; add tp[0]
-+	add		$ti0,$hi0,$hi0
-+	addc		%r0,$hi1,$hi1
-+	 fcnvfx,dbl,dbl	${fab0},${fab0}		; double -> 33-bit unsigned int
-+	stw		$hi0,0($tp)
-+	stw		$hi1,4($tp)
-+	 xmpyu		${fn0},${fab0}R,${fm0}
-+
-+	b		L\$outer_pa11
-+	ldo		`$LOCALS+32+4`($fp),$tp
-+
-+L\$outerdone_pa11
-+	add		$hi0,$ablo,$ablo
-+	addc		%r0,$abhi,$abhi
-+	add		$ti1,$ablo,$ablo
-+	addc		%r0,$abhi,$hi0
-+
-+	ldw		4($tp),$ti0		; tp[j]
-+
-+	add		$hi1,$nmlo1,$nmlo1
-+	addc		%r0,$nmhi1,$nmhi1
-+	add		$ablo,$nmlo1,$nmlo1
-+	addc		%r0,$nmhi1,$hi1
-+	stw		$nmlo1,-4($tp)		; tp[j-1]
-+
-+	add		$hi1,$hi0,$hi0
-+	addc		%r0,%r0,$hi1
-+	add		$ti0,$hi0,$hi0
-+	addc		%r0,$hi1,$hi1
-+	stw		$hi0,0($tp)
-+	stw		$hi1,4($tp)
-+
-+	ldo		`$LOCALS+32+4`($fp),$tp
-+	sub		%r0,%r0,%r0		; clear borrow
-+	ldw		-4($tp),$ti0
-+	addl		$tp,$arrsz,$tp
-+L\$sub_pa11
-+	ldwx		$idx($np),$hi0
-+	subb		$ti0,$hi0,$hi1
-+	ldwx		$idx($tp),$ti0
-+	addib,<>	4,$idx,L\$sub_pa11
-+	stws,ma		$hi1,4($rp)
-+
-+	subb		$ti0,%r0,$hi1
-+	ldo		-4($tp),$tp
-+	and		$tp,$hi1,$ap
-+	andcm		$rp,$hi1,$bp
-+	or		$ap,$bp,$np
-+
-+	sub		$rp,$arrsz,$rp		; rewind rp
-+	subi		0,$arrsz,$idx
-+	ldo		`$LOCALS+32`($fp),$tp
-+L\$copy_pa11
-+	ldwx		$idx($np),$hi0
-+	stws,ma		%r0,4($tp)
-+	addib,<>	4,$idx,L\$copy_pa11
-+	stws,ma		$hi0,4($rp)	
-+
-+	nop					; alignment
-+L\$done
-+___
-+}
-+
-+$code.=<<___;
-+	ldi		1,%r28			; signal "handled"
-+	ldo		$FRAME($fp),%sp		; destroy tp[num+1]
-+
-+	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2	; standard epilogue
-+	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
-+	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
-+	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
-+	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
-+	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
-+	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
-+	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
-+L\$abort
-+	bv	(%r2)
-+	.EXIT
-+	$POPMB	-$FRAME(%sp),%r3
-+	.PROCEND
-+	.STRINGZ "Montgomery Multiplication for PA-RISC, CRYPTOGAMS by "
-+___
-+
-+# Explicitly encode PA-RISC 2.0 instructions used in this module, so
-+# that it can be compiled with .LEVEL 1.0. It should be noted that I
-+# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0
-+# directive...
-+
-+my $ldd = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "ldd$mod\t$args";
-+
-+    if ($args =~ /%r([0-9]+)\(%r([0-9]+)\),%r([0-9]+)/)		# format 4
-+    {	my $opcode=(0x03<<26)|($2<<21)|($1<<16)|(3<<6)|$3;
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    elsif ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/)	# format 5
-+    {	my $opcode=(0x03<<26)|($2<<21)|(1<<12)|(3<<6)|$3;
-+	$opcode|=(($1&0xF)<<17)|(($1&0x10)<<12);		# encode offset
-+	$opcode|=(1<<5)  if ($mod =~ /^,m/);
-+	$opcode|=(1<<13) if ($mod =~ /^,mb/);
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $std = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "std$mod\t$args";
-+
-+    if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/)	# format 6
-+    {	my $opcode=(0x03<<26)|($3<<21)|($1<<16)|(1<<12)|(0xB<<6);
-+	$opcode|=(($2&0xF)<<1)|(($2&0x10)>>4);			# encode offset
-+	$opcode|=(1<<5)  if ($mod =~ /^,m/);
-+	$opcode|=(1<<13) if ($mod =~ /^,mb/);
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $extrd = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "extrd$mod\t$args";
-+
-+    # I only have ",u" completer, it's implicitly encoded...
-+    if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/)	# format 15
-+    {	my $opcode=(0x36<<26)|($1<<21)|($4<<16);
-+	my $len=32-$3;
-+	$opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5);		# encode pos
-+	$opcode |= (($len&0x20)<<7)|($len&0x1f);		# encode len
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/)	# format 12
-+    {	my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9);
-+	my $len=32-$2;
-+	$opcode |= (($len&0x20)<<3)|($len&0x1f);		# encode len
-+	$opcode |= (1<<13) if ($mod =~ /,\**=/);
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $shrpd = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "shrpd$mod\t$args";
-+
-+    if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/)	# format 14
-+    {	my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4;
-+	my $cpos=63-$3;
-+	$opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5);		# encode sa
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $sub = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "sub$mod\t$args";
-+
-+    if ($mod eq ",db" && $args =~ /%r([0-9]+),%r([0-9]+),%r([0-9]+)/) {
-+	my $opcode=(0x02<<26)|($2<<21)|($1<<16)|$3;
-+	$opcode|=(1<<10);	# e1
-+	$opcode|=(1<<8);	# e2
-+	$opcode|=(1<<5);	# d
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+sub assemble {
-+  my ($mnemonic,$mod,$args)=@_;
-+  my $opcode = eval("\$$mnemonic");
-+
-+    ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args";
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+	# flip word order in 64-bit mode...
-+	s/(xmpyu\s+)($fai|$fni)([LR])/$1.$2.($3 eq "L"?"R":"L")/e if ($BN_SZ==8);
-+	# assemble 2.0 instructions in 32-bit mode...
-+	s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e if ($BN_SZ==4);
-+
-+	s/\bbv\b/bve/gm	if ($SIZE_T==8);
-+
-+	print $_,"\n";
-+}
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc-mont.pl
-new file mode 100644
-index 0000000..5802260
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc-mont.pl
-@@ -0,0 +1,342 @@
-+#! /usr/bin/env perl
-+# Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# April 2006
-+
-+# "Teaser" Montgomery multiplication module for PowerPC. It's possible
-+# to gain a bit more by modulo-scheduling outer loop, then dedicated
-+# squaring procedure should give further 20% and code can be adapted
-+# for 32-bit application running on 64-bit CPU. As for the latter.
-+# It won't be able to achieve "native" 64-bit performance, because in
-+# 32-bit application context every addc instruction will have to be
-+# expanded as addc, twice right shift by 32 and finally adde, etc.
-+# So far RSA *sign* performance improvement over pre-bn_mul_mont asm
-+# for 64-bit application running on PPC970/G5 is:
-+#
-+# 512-bit	+65%	
-+# 1024-bit	+35%
-+# 2048-bit	+18%
-+# 4096-bit	+4%
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /32/) {
-+	$BITS=	32;
-+	$BNSZ=	$BITS/8;
-+	$SIZE_T=4;
-+	$RZONE=	224;
-+
-+	$LD=	"lwz";		# load
-+	$LDU=	"lwzu";		# load and update
-+	$LDX=	"lwzx";		# load indexed
-+	$ST=	"stw";		# store
-+	$STU=	"stwu";		# store and update
-+	$STX=	"stwx";		# store indexed
-+	$STUX=	"stwux";	# store indexed and update
-+	$UMULL=	"mullw";	# unsigned multiply low
-+	$UMULH=	"mulhwu";	# unsigned multiply high
-+	$UCMP=	"cmplw";	# unsigned compare
-+	$SHRI=	"srwi";		# unsigned shift right by immediate	
-+	$PUSH=	$ST;
-+	$POP=	$LD;
-+} elsif ($flavour =~ /64/) {
-+	$BITS=	64;
-+	$BNSZ=	$BITS/8;
-+	$SIZE_T=8;
-+	$RZONE=	288;
-+
-+	# same as above, but 64-bit mnemonics...
-+	$LD=	"ld";		# load
-+	$LDU=	"ldu";		# load and update
-+	$LDX=	"ldx";		# load indexed
-+	$ST=	"std";		# store
-+	$STU=	"stdu";		# store and update
-+	$STX=	"stdx";		# store indexed
-+	$STUX=	"stdux";	# store indexed and update
-+	$UMULL=	"mulld";	# unsigned multiply low
-+	$UMULH=	"mulhdu";	# unsigned multiply high
-+	$UCMP=	"cmpld";	# unsigned compare
-+	$SHRI=	"srdi";		# unsigned shift right by immediate	
-+	$PUSH=	$ST;
-+	$POP=	$LD;
-+} else { die "nonsense $flavour"; }
-+
-+$FRAME=8*$SIZE_T+$RZONE;
-+$LOCALS=8*$SIZE_T;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-+
-+$sp="r1";
-+$toc="r2";
-+$rp="r3";	$ovf="r3";
-+$ap="r4";
-+$bp="r5";
-+$np="r6";
-+$n0="r7";
-+$num="r8";
-+$rp="r9";	# $rp is reassigned
-+$aj="r10";
-+$nj="r11";
-+$tj="r12";
-+# non-volatile registers
-+$i="r20";
-+$j="r21";
-+$tp="r22";
-+$m0="r23";
-+$m1="r24";
-+$lo0="r25";
-+$hi0="r26";
-+$lo1="r27";
-+$hi1="r28";
-+$alo="r29";
-+$ahi="r30";
-+$nlo="r31";
-+#
-+$nhi="r0";
-+
-+$code=<<___;
-+.machine "any"
-+.text
-+
-+.globl	.bn_mul_mont_int
-+.align	4
-+.bn_mul_mont_int:
-+	cmpwi	$num,4
-+	mr	$rp,r3		; $rp is reassigned
-+	li	r3,0
-+	bltlr
-+___
-+$code.=<<___ if ($BNSZ==4);
-+	cmpwi	$num,32		; longer key performance is not better
-+	bgelr
-+___
-+$code.=<<___;
-+	slwi	$num,$num,`log($BNSZ)/log(2)`
-+	li	$tj,-4096
-+	addi	$ovf,$num,$FRAME
-+	subf	$ovf,$ovf,$sp	; $sp-$ovf
-+	and	$ovf,$ovf,$tj	; minimize TLB usage
-+	subf	$ovf,$sp,$ovf	; $ovf-$sp
-+	mr	$tj,$sp
-+	srwi	$num,$num,`log($BNSZ)/log(2)`
-+	$STUX	$sp,$sp,$ovf
-+
-+	$PUSH	r20,`-12*$SIZE_T`($tj)
-+	$PUSH	r21,`-11*$SIZE_T`($tj)
-+	$PUSH	r22,`-10*$SIZE_T`($tj)
-+	$PUSH	r23,`-9*$SIZE_T`($tj)
-+	$PUSH	r24,`-8*$SIZE_T`($tj)
-+	$PUSH	r25,`-7*$SIZE_T`($tj)
-+	$PUSH	r26,`-6*$SIZE_T`($tj)
-+	$PUSH	r27,`-5*$SIZE_T`($tj)
-+	$PUSH	r28,`-4*$SIZE_T`($tj)
-+	$PUSH	r29,`-3*$SIZE_T`($tj)
-+	$PUSH	r30,`-2*$SIZE_T`($tj)
-+	$PUSH	r31,`-1*$SIZE_T`($tj)
-+
-+	$LD	$n0,0($n0)	; pull n0[0] value
-+	addi	$num,$num,-2	; adjust $num for counter register
-+
-+	$LD	$m0,0($bp)	; m0=bp[0]
-+	$LD	$aj,0($ap)	; ap[0]
-+	addi	$tp,$sp,$LOCALS
-+	$UMULL	$lo0,$aj,$m0	; ap[0]*bp[0]
-+	$UMULH	$hi0,$aj,$m0
-+
-+	$LD	$aj,$BNSZ($ap)	; ap[1]
-+	$LD	$nj,0($np)	; np[0]
-+
-+	$UMULL	$m1,$lo0,$n0	; "tp[0]"*n0
-+
-+	$UMULL	$alo,$aj,$m0	; ap[1]*bp[0]
-+	$UMULH	$ahi,$aj,$m0
-+
-+	$UMULL	$lo1,$nj,$m1	; np[0]*m1
-+	$UMULH	$hi1,$nj,$m1
-+	$LD	$nj,$BNSZ($np)	; np[1]
-+	addc	$lo1,$lo1,$lo0
-+	addze	$hi1,$hi1
-+
-+	$UMULL	$nlo,$nj,$m1	; np[1]*m1
-+	$UMULH	$nhi,$nj,$m1
-+
-+	mtctr	$num
-+	li	$j,`2*$BNSZ`
-+.align	4
-+L1st:
-+	$LDX	$aj,$ap,$j	; ap[j]
-+	addc	$lo0,$alo,$hi0
-+	$LDX	$nj,$np,$j	; np[j]
-+	addze	$hi0,$ahi
-+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[0]
-+	addc	$lo1,$nlo,$hi1
-+	$UMULH	$ahi,$aj,$m0
-+	addze	$hi1,$nhi
-+	$UMULL	$nlo,$nj,$m1	; np[j]*m1
-+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[0]
-+	$UMULH	$nhi,$nj,$m1
-+	addze	$hi1,$hi1
-+	$ST	$lo1,0($tp)	; tp[j-1]
-+
-+	addi	$j,$j,$BNSZ	; j++
-+	addi	$tp,$tp,$BNSZ	; tp++
-+	bdnz	L1st
-+;L1st
-+	addc	$lo0,$alo,$hi0
-+	addze	$hi0,$ahi
-+
-+	addc	$lo1,$nlo,$hi1
-+	addze	$hi1,$nhi
-+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[0]
-+	addze	$hi1,$hi1
-+	$ST	$lo1,0($tp)	; tp[j-1]
-+
-+	li	$ovf,0
-+	addc	$hi1,$hi1,$hi0
-+	addze	$ovf,$ovf	; upmost overflow bit
-+	$ST	$hi1,$BNSZ($tp)
-+
-+	li	$i,$BNSZ
-+.align	4
-+Louter:
-+	$LDX	$m0,$bp,$i	; m0=bp[i]
-+	$LD	$aj,0($ap)	; ap[0]
-+	addi	$tp,$sp,$LOCALS
-+	$LD	$tj,$LOCALS($sp); tp[0]
-+	$UMULL	$lo0,$aj,$m0	; ap[0]*bp[i]
-+	$UMULH	$hi0,$aj,$m0
-+	$LD	$aj,$BNSZ($ap)	; ap[1]
-+	$LD	$nj,0($np)	; np[0]
-+	addc	$lo0,$lo0,$tj	; ap[0]*bp[i]+tp[0]
-+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[i]
-+	addze	$hi0,$hi0
-+	$UMULL	$m1,$lo0,$n0	; tp[0]*n0
-+	$UMULH	$ahi,$aj,$m0
-+	$UMULL	$lo1,$nj,$m1	; np[0]*m1
-+	$UMULH	$hi1,$nj,$m1
-+	$LD	$nj,$BNSZ($np)	; np[1]
-+	addc	$lo1,$lo1,$lo0
-+	$UMULL	$nlo,$nj,$m1	; np[1]*m1
-+	addze	$hi1,$hi1
-+	$UMULH	$nhi,$nj,$m1
-+
-+	mtctr	$num
-+	li	$j,`2*$BNSZ`
-+.align	4
-+Linner:
-+	$LDX	$aj,$ap,$j	; ap[j]
-+	addc	$lo0,$alo,$hi0
-+	$LD	$tj,$BNSZ($tp)	; tp[j]
-+	addze	$hi0,$ahi
-+	$LDX	$nj,$np,$j	; np[j]
-+	addc	$lo1,$nlo,$hi1
-+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[i]
-+	addze	$hi1,$nhi
-+	$UMULH	$ahi,$aj,$m0
-+	addc	$lo0,$lo0,$tj	; ap[j]*bp[i]+tp[j]
-+	$UMULL	$nlo,$nj,$m1	; np[j]*m1
-+	addze	$hi0,$hi0
-+	$UMULH	$nhi,$nj,$m1
-+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[i]+tp[j]
-+	addi	$j,$j,$BNSZ	; j++
-+	addze	$hi1,$hi1
-+	$ST	$lo1,0($tp)	; tp[j-1]
-+	addi	$tp,$tp,$BNSZ	; tp++
-+	bdnz	Linner
-+;Linner
-+	$LD	$tj,$BNSZ($tp)	; tp[j]
-+	addc	$lo0,$alo,$hi0
-+	addze	$hi0,$ahi
-+	addc	$lo0,$lo0,$tj	; ap[j]*bp[i]+tp[j]
-+	addze	$hi0,$hi0
-+
-+	addc	$lo1,$nlo,$hi1
-+	addze	$hi1,$nhi
-+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[i]+tp[j]
-+	addze	$hi1,$hi1
-+	$ST	$lo1,0($tp)	; tp[j-1]
-+
-+	addic	$ovf,$ovf,-1	; move upmost overflow to XER[CA]
-+	li	$ovf,0
-+	adde	$hi1,$hi1,$hi0
-+	addze	$ovf,$ovf
-+	$ST	$hi1,$BNSZ($tp)
-+;
-+	slwi	$tj,$num,`log($BNSZ)/log(2)`
-+	$UCMP	$i,$tj
-+	addi	$i,$i,$BNSZ
-+	ble	Louter
-+
-+	addi	$num,$num,2	; restore $num
-+	subfc	$j,$j,$j	; j=0 and "clear" XER[CA]
-+	addi	$tp,$sp,$LOCALS
-+	mtctr	$num
-+
-+.align	4
-+Lsub:	$LDX	$tj,$tp,$j
-+	$LDX	$nj,$np,$j
-+	subfe	$aj,$nj,$tj	; tp[j]-np[j]
-+	$STX	$aj,$rp,$j
-+	addi	$j,$j,$BNSZ
-+	bdnz	Lsub
-+
-+	li	$j,0
-+	mtctr	$num
-+	subfe	$ovf,$j,$ovf	; handle upmost overflow bit
-+	and	$ap,$tp,$ovf
-+	andc	$np,$rp,$ovf
-+	or	$ap,$ap,$np	; ap=borrow?tp:rp
-+
-+.align	4
-+Lcopy:				; copy or in-place refresh
-+	$LDX	$tj,$ap,$j
-+	$STX	$tj,$rp,$j
-+	$STX	$j,$tp,$j	; zap at once
-+	addi	$j,$j,$BNSZ
-+	bdnz	Lcopy
-+
-+	$POP	$tj,0($sp)
-+	li	r3,1
-+	$POP	r20,`-12*$SIZE_T`($tj)
-+	$POP	r21,`-11*$SIZE_T`($tj)
-+	$POP	r22,`-10*$SIZE_T`($tj)
-+	$POP	r23,`-9*$SIZE_T`($tj)
-+	$POP	r24,`-8*$SIZE_T`($tj)
-+	$POP	r25,`-7*$SIZE_T`($tj)
-+	$POP	r26,`-6*$SIZE_T`($tj)
-+	$POP	r27,`-5*$SIZE_T`($tj)
-+	$POP	r28,`-4*$SIZE_T`($tj)
-+	$POP	r29,`-3*$SIZE_T`($tj)
-+	$POP	r30,`-2*$SIZE_T`($tj)
-+	$POP	r31,`-1*$SIZE_T`($tj)
-+	mr	$sp,$tj
-+	blr
-+	.long	0
-+	.byte	0,12,4,0,0x80,12,6,0
-+	.long	0
-+.size	.bn_mul_mont_int,.-.bn_mul_mont_int
-+
-+.asciz  "Montgomery Multiplication for PPC, CRYPTOGAMS by "
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc.pl
-new file mode 100644
-index 0000000..4ea534a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc.pl
-@@ -0,0 +1,2014 @@
-+#! /usr/bin/env perl
-+# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+# Implemented as a Perl wrapper as we want to support several different
-+# architectures with single file. We pick up the target based on the
-+# file name we are asked to generate.
-+#
-+# It should be noted though that this perl code is nothing like
-+# /crypto/perlasm/x86*. In this case perl is used pretty much
-+# as pre-processor to cover for platform differences in name decoration,
-+# linker tables, 32-/64-bit instruction sets...
-+#
-+# As you might know there're several PowerPC ABI in use. Most notably
-+# Linux and AIX use different 32-bit ABIs. Good news are that these ABIs
-+# are similar enough to implement leaf(!) functions, which would be ABI
-+# neutral. And that's what you find here: ABI neutral leaf functions.
-+# In case you wonder what that is...
-+#
-+#       AIX performance
-+#
-+#	MEASUREMENTS WITH cc ON a 200 MhZ PowerPC 604e.
-+#
-+#	The following is the performance of 32-bit compiler
-+#	generated code:
-+#
-+#	OpenSSL 0.9.6c 21 dec 2001
-+#	built on: Tue Jun 11 11:06:51 EDT 2002
-+#	options:bn(64,32) ...
-+#compiler: cc -DTHREADS  -DAIX -DB_ENDIAN -DBN_LLONG -O3
-+#                  sign    verify    sign/s verify/s
-+#rsa  512 bits   0.0098s   0.0009s    102.0   1170.6
-+#rsa 1024 bits   0.0507s   0.0026s     19.7    387.5
-+#rsa 2048 bits   0.3036s   0.0085s      3.3    117.1
-+#rsa 4096 bits   2.0040s   0.0299s      0.5     33.4
-+#dsa  512 bits   0.0087s   0.0106s    114.3     94.5
-+#dsa 1024 bits   0.0256s   0.0313s     39.0     32.0	
-+#
-+#	Same bechmark with this assembler code:
-+#
-+#rsa  512 bits   0.0056s   0.0005s    178.6   2049.2
-+#rsa 1024 bits   0.0283s   0.0015s     35.3    674.1
-+#rsa 2048 bits   0.1744s   0.0050s      5.7    201.2
-+#rsa 4096 bits   1.1644s   0.0179s      0.9     55.7
-+#dsa  512 bits   0.0052s   0.0062s    191.6    162.0
-+#dsa 1024 bits   0.0149s   0.0180s     67.0     55.5
-+#
-+#	Number of operations increases by at almost 75%
-+#
-+#	Here are performance numbers for 64-bit compiler
-+#	generated code:
-+#
-+#	OpenSSL 0.9.6g [engine] 9 Aug 2002
-+#	built on: Fri Apr 18 16:59:20 EDT 2003
-+#	options:bn(64,64) ...
-+#	compiler: cc -DTHREADS -D_REENTRANT -q64 -DB_ENDIAN -O3
-+#                  sign    verify    sign/s verify/s
-+#rsa  512 bits   0.0028s   0.0003s    357.1   3844.4
-+#rsa 1024 bits   0.0148s   0.0008s     67.5   1239.7
-+#rsa 2048 bits   0.0963s   0.0028s     10.4    353.0
-+#rsa 4096 bits   0.6538s   0.0102s      1.5     98.1
-+#dsa  512 bits   0.0026s   0.0032s    382.5    313.7
-+#dsa 1024 bits   0.0081s   0.0099s    122.8    100.6
-+#
-+#	Same benchmark with this assembler code:
-+#
-+#rsa  512 bits   0.0020s   0.0002s    510.4   6273.7
-+#rsa 1024 bits   0.0088s   0.0005s    114.1   2128.3
-+#rsa 2048 bits   0.0540s   0.0016s     18.5    622.5
-+#rsa 4096 bits   0.3700s   0.0058s      2.7    171.0
-+#dsa  512 bits   0.0016s   0.0020s    610.7    507.1
-+#dsa 1024 bits   0.0047s   0.0058s    212.5    173.2
-+#	
-+#	Again, performance increases by at about 75%
-+#
-+#       Mac OS X, Apple G5 1.8GHz (Note this is 32 bit code)
-+#       OpenSSL 0.9.7c 30 Sep 2003
-+#
-+#       Original code.
-+#
-+#rsa  512 bits   0.0011s   0.0001s    906.1  11012.5
-+#rsa 1024 bits   0.0060s   0.0003s    166.6   3363.1
-+#rsa 2048 bits   0.0370s   0.0010s     27.1    982.4
-+#rsa 4096 bits   0.2426s   0.0036s      4.1    280.4
-+#dsa  512 bits   0.0010s   0.0012s   1038.1    841.5
-+#dsa 1024 bits   0.0030s   0.0037s    329.6    269.7
-+#dsa 2048 bits   0.0101s   0.0127s     98.9     78.6
-+#
-+#       Same benchmark with this assembler code:
-+#
-+#rsa  512 bits   0.0007s   0.0001s   1416.2  16645.9
-+#rsa 1024 bits   0.0036s   0.0002s    274.4   5380.6
-+#rsa 2048 bits   0.0222s   0.0006s     45.1   1589.5
-+#rsa 4096 bits   0.1469s   0.0022s      6.8    449.6
-+#dsa  512 bits   0.0006s   0.0007s   1664.2   1376.2
-+#dsa 1024 bits   0.0018s   0.0023s    545.0    442.2
-+#dsa 2048 bits   0.0061s   0.0075s    163.5    132.8
-+#
-+#        Performance increase of ~60%
-+#
-+#	If you have comments or suggestions to improve code send
-+#	me a note at schari@us.ibm.com
-+#
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /32/) {
-+	$BITS=	32;
-+	$BNSZ=	$BITS/8;
-+	$ISA=	"\"ppc\"";
-+
-+	$LD=	"lwz";		# load
-+	$LDU=	"lwzu";		# load and update
-+	$ST=	"stw";		# store
-+	$STU=	"stwu";		# store and update
-+	$UMULL=	"mullw";	# unsigned multiply low
-+	$UMULH=	"mulhwu";	# unsigned multiply high
-+	$UDIV=	"divwu";	# unsigned divide
-+	$UCMPI=	"cmplwi";	# unsigned compare with immediate
-+	$UCMP=	"cmplw";	# unsigned compare
-+	$CNTLZ=	"cntlzw";	# count leading zeros
-+	$SHL=	"slw";		# shift left
-+	$SHR=	"srw";		# unsigned shift right
-+	$SHRI=	"srwi";		# unsigned shift right by immediate	
-+	$SHLI=	"slwi";		# shift left by immediate
-+	$CLRU=	"clrlwi";	# clear upper bits
-+	$INSR=	"insrwi";	# insert right
-+	$ROTL=	"rotlwi";	# rotate left by immediate
-+	$TR=	"tw";		# conditional trap
-+} elsif ($flavour =~ /64/) {
-+	$BITS=	64;
-+	$BNSZ=	$BITS/8;
-+	$ISA=	"\"ppc64\"";
-+
-+	# same as above, but 64-bit mnemonics...
-+	$LD=	"ld";		# load
-+	$LDU=	"ldu";		# load and update
-+	$ST=	"std";		# store
-+	$STU=	"stdu";		# store and update
-+	$UMULL=	"mulld";	# unsigned multiply low
-+	$UMULH=	"mulhdu";	# unsigned multiply high
-+	$UDIV=	"divdu";	# unsigned divide
-+	$UCMPI=	"cmpldi";	# unsigned compare with immediate
-+	$UCMP=	"cmpld";	# unsigned compare
-+	$CNTLZ=	"cntlzd";	# count leading zeros
-+	$SHL=	"sld";		# shift left
-+	$SHR=	"srd";		# unsigned shift right
-+	$SHRI=	"srdi";		# unsigned shift right by immediate	
-+	$SHLI=	"sldi";		# shift left by immediate
-+	$CLRU=	"clrldi";	# clear upper bits
-+	$INSR=	"insrdi";	# insert right 
-+	$ROTL=	"rotldi";	# rotate left by immediate
-+	$TR=	"td";		# conditional trap
-+} else { die "nonsense $flavour"; }
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-+
-+$data=< 0 then result !=0
-+				# In either case carry bit is set.
-+	beq	Lppcasm_sub_adios
-+	addi	r4,r4,-$BNSZ
-+	addi	r3,r3,-$BNSZ
-+	addi	r5,r5,-$BNSZ
-+	mtctr	r6
-+Lppcasm_sub_mainloop:	
-+	$LDU	r7,$BNSZ(r4)
-+	$LDU	r8,$BNSZ(r5)
-+	subfe	r6,r8,r7	# r6 = r7+carry bit + onescomplement(r8)
-+				# if carry = 1 this is r7-r8. Else it
-+				# is r7-r8 -1 as we need.
-+	$STU	r6,$BNSZ(r3)
-+	bdnz	Lppcasm_sub_mainloop
-+Lppcasm_sub_adios:	
-+	subfze	r3,r0		# if carry bit is set then r3 = 0 else -1
-+	andi.	r3,r3,1         # keep only last bit.
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,4,0
-+	.long	0
-+.size	.bn_sub_words,.-.bn_sub_words
-+
-+#
-+#	NOTE:	The following label name should be changed to
-+#		"bn_add_words" i.e. remove the first dot
-+#		for the gcc compiler. This should be automatically
-+#		done in the build
-+#
-+
-+.align	4
-+.bn_add_words:
-+#
-+#	Handcoded version of bn_add_words
-+#
-+#BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
-+#
-+#	r3 = r
-+#	r4 = a
-+#	r5 = b
-+#	r6 = n
-+#
-+#       Note:	No loop unrolling done since this is not a performance
-+#               critical loop.
-+
-+	xor	r0,r0,r0
-+#
-+#	check for r6 = 0. Is this needed?
-+#
-+	addic.	r6,r6,0		#test r6 and clear carry bit.
-+	beq	Lppcasm_add_adios
-+	addi	r4,r4,-$BNSZ
-+	addi	r3,r3,-$BNSZ
-+	addi	r5,r5,-$BNSZ
-+	mtctr	r6
-+Lppcasm_add_mainloop:	
-+	$LDU	r7,$BNSZ(r4)
-+	$LDU	r8,$BNSZ(r5)
-+	adde	r8,r7,r8
-+	$STU	r8,$BNSZ(r3)
-+	bdnz	Lppcasm_add_mainloop
-+Lppcasm_add_adios:	
-+	addze	r3,r0			#return carry bit.
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,4,0
-+	.long	0
-+.size	.bn_add_words,.-.bn_add_words
-+
-+#
-+#	NOTE:	The following label name should be changed to
-+#		"bn_div_words" i.e. remove the first dot
-+#		for the gcc compiler. This should be automatically
-+#		done in the build
-+#
-+
-+.align	4
-+.bn_div_words:
-+#
-+#	This is a cleaned up version of code generated by
-+#	the AIX compiler. The only optimization is to use
-+#	the PPC instruction to count leading zeros instead
-+#	of call to num_bits_word. Since this was compiled
-+#	only at level -O2 we can possibly squeeze it more?
-+#	
-+#	r3 = h
-+#	r4 = l
-+#	r5 = d
-+	
-+	$UCMPI	0,r5,0			# compare r5 and 0
-+	bne	Lppcasm_div1		# proceed if d!=0
-+	li	r3,-1			# d=0 return -1
-+	blr
-+Lppcasm_div1:
-+	xor	r0,r0,r0		#r0=0
-+	li	r8,$BITS
-+	$CNTLZ.	r7,r5			#r7 = num leading 0s in d.
-+	beq	Lppcasm_div2		#proceed if no leading zeros
-+	subf	r8,r7,r8		#r8 = BN_num_bits_word(d)
-+	$SHR.	r9,r3,r8		#are there any bits above r8'th?
-+	$TR	16,r9,r0		#if there're, signal to dump core...
-+Lppcasm_div2:
-+	$UCMP	0,r3,r5			#h>=d?
-+	blt	Lppcasm_div3		#goto Lppcasm_div3 if not
-+	subf	r3,r5,r3		#h-=d ; 
-+Lppcasm_div3:				#r7 = BN_BITS2-i. so r7=i
-+	cmpi	0,0,r7,0		# is (i == 0)?
-+	beq	Lppcasm_div4
-+	$SHL	r3,r3,r7		# h = (h<< i)
-+	$SHR	r8,r4,r8		# r8 = (l >> BN_BITS2 -i)
-+	$SHL	r5,r5,r7		# d<<=i
-+	or	r3,r3,r8		# h = (h<>(BN_BITS2-i))
-+	$SHL	r4,r4,r7		# l <<=i
-+Lppcasm_div4:
-+	$SHRI	r9,r5,`$BITS/2`		# r9 = dh
-+					# dl will be computed when needed
-+					# as it saves registers.
-+	li	r6,2			#r6=2
-+	mtctr	r6			#counter will be in count.
-+Lppcasm_divouterloop: 
-+	$SHRI	r8,r3,`$BITS/2`		#r8 = (h>>BN_BITS4)
-+	$SHRI	r11,r4,`$BITS/2`	#r11= (l&BN_MASK2h)>>BN_BITS4
-+					# compute here for innerloop.
-+	$UCMP	0,r8,r9			# is (h>>BN_BITS4)==dh
-+	bne	Lppcasm_div5		# goto Lppcasm_div5 if not
-+
-+	li	r8,-1
-+	$CLRU	r8,r8,`$BITS/2`		#q = BN_MASK2l 
-+	b	Lppcasm_div6
-+Lppcasm_div5:
-+	$UDIV	r8,r3,r9		#q = h/dh
-+Lppcasm_div6:
-+	$UMULL	r12,r9,r8		#th = q*dh
-+	$CLRU	r10,r5,`$BITS/2`	#r10=dl
-+	$UMULL	r6,r8,r10		#tl = q*dl
-+	
-+Lppcasm_divinnerloop:
-+	subf	r10,r12,r3		#t = h -th
-+	$SHRI	r7,r10,`$BITS/2`	#r7= (t &BN_MASK2H), sort of...
-+	addic.	r7,r7,0			#test if r7 == 0. used below.
-+					# now want to compute
-+					# r7 = (t<>BN_BITS4)
-+					# the following 2 instructions do that
-+	$SHLI	r7,r10,`$BITS/2`	# r7 = (t<>BN_BITS4)
-+	$UCMP	cr1,r6,r7		# compare (tl <= r7)
-+	bne	Lppcasm_divinnerexit
-+	ble	cr1,Lppcasm_divinnerexit
-+	addi	r8,r8,-1		#q--
-+	subf	r12,r9,r12		#th -=dh
-+	$CLRU	r10,r5,`$BITS/2`	#r10=dl. t is no longer needed in loop.
-+	subf	r6,r10,r6		#tl -=dl
-+	b	Lppcasm_divinnerloop
-+Lppcasm_divinnerexit:
-+	$SHRI	r10,r6,`$BITS/2`	#t=(tl>>BN_BITS4)
-+	$SHLI	r11,r6,`$BITS/2`	#tl=(tl<=tl) goto Lppcasm_div7
-+	addi	r12,r12,1		# th++
-+Lppcasm_div7:
-+	subf	r11,r11,r4		#r11=l-tl
-+	$UCMP	cr1,r3,r12		#compare h and th
-+	bge	cr1,Lppcasm_div8	#if (h>=th) goto Lppcasm_div8
-+	addi	r8,r8,-1		# q--
-+	add	r3,r5,r3		# h+=d
-+Lppcasm_div8:
-+	subf	r12,r12,r3		#r12 = h-th
-+	$SHLI	r4,r11,`$BITS/2`	#l=(l&BN_MASK2l)<>BN_BITS4))&BN_MASK2
-+					# the following 2 instructions will do this.
-+	$INSR	r11,r12,`$BITS/2`,`$BITS/2`	# r11 is the value we want rotated $BITS/2.
-+	$ROTL	r3,r11,`$BITS/2`	# rotate by $BITS/2 and store in r3
-+	bdz	Lppcasm_div9		#if (count==0) break ;
-+	$SHLI	r0,r8,`$BITS/2`		#ret =q<> 2
-+	beq	Lppcasm_mw_REM
-+	mtctr	r7
-+Lppcasm_mw_LOOP:	
-+					#mul(rp[0],ap[0],w,c1);
-+	$LD	r8,`0*$BNSZ`(r4)
-+	$UMULL	r9,r6,r8
-+	$UMULH  r10,r6,r8
-+	addc	r9,r9,r12
-+	#addze	r10,r10			#carry is NOT ignored.
-+					#will be taken care of
-+					#in second spin below
-+					#using adde.
-+	$ST	r9,`0*$BNSZ`(r3)
-+					#mul(rp[1],ap[1],w,c1);
-+	$LD	r8,`1*$BNSZ`(r4)	
-+	$UMULL	r11,r6,r8
-+	$UMULH  r12,r6,r8
-+	adde	r11,r11,r10
-+	#addze	r12,r12
-+	$ST	r11,`1*$BNSZ`(r3)
-+					#mul(rp[2],ap[2],w,c1);
-+	$LD	r8,`2*$BNSZ`(r4)
-+	$UMULL	r9,r6,r8
-+	$UMULH  r10,r6,r8
-+	adde	r9,r9,r12
-+	#addze	r10,r10
-+	$ST	r9,`2*$BNSZ`(r3)
-+					#mul_add(rp[3],ap[3],w,c1);
-+	$LD	r8,`3*$BNSZ`(r4)
-+	$UMULL	r11,r6,r8
-+	$UMULH  r12,r6,r8
-+	adde	r11,r11,r10
-+	addze	r12,r12			#this spin we collect carry into
-+					#r12
-+	$ST	r11,`3*$BNSZ`(r3)
-+	
-+	addi	r3,r3,`4*$BNSZ`
-+	addi	r4,r4,`4*$BNSZ`
-+	bdnz	Lppcasm_mw_LOOP
-+
-+Lppcasm_mw_REM:
-+	andi.	r5,r5,0x3
-+	beq	Lppcasm_mw_OVER
-+					#mul(rp[0],ap[0],w,c1);
-+	$LD	r8,`0*$BNSZ`(r4)
-+	$UMULL	r9,r6,r8
-+	$UMULH  r10,r6,r8
-+	addc	r9,r9,r12
-+	addze	r10,r10
-+	$ST	r9,`0*$BNSZ`(r3)
-+	addi	r12,r10,0
-+	
-+	addi	r5,r5,-1
-+	cmpli	0,0,r5,0
-+	beq	Lppcasm_mw_OVER
-+
-+	
-+					#mul(rp[1],ap[1],w,c1);
-+	$LD	r8,`1*$BNSZ`(r4)	
-+	$UMULL	r9,r6,r8
-+	$UMULH  r10,r6,r8
-+	addc	r9,r9,r12
-+	addze	r10,r10
-+	$ST	r9,`1*$BNSZ`(r3)
-+	addi	r12,r10,0
-+	
-+	addi	r5,r5,-1
-+	cmpli	0,0,r5,0
-+	beq	Lppcasm_mw_OVER
-+	
-+					#mul_add(rp[2],ap[2],w,c1);
-+	$LD	r8,`2*$BNSZ`(r4)
-+	$UMULL	r9,r6,r8
-+	$UMULH  r10,r6,r8
-+	addc	r9,r9,r12
-+	addze	r10,r10
-+	$ST	r9,`2*$BNSZ`(r3)
-+	addi	r12,r10,0
-+		
-+Lppcasm_mw_OVER:	
-+	addi	r3,r12,0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,4,0
-+	.long	0
-+.size	bn_mul_words,.-bn_mul_words
-+
-+#
-+#	NOTE:	The following label name should be changed to
-+#		"bn_mul_add_words" i.e. remove the first dot
-+#		for the gcc compiler. This should be automatically
-+#		done in the build
-+#
-+
-+.align	4
-+.bn_mul_add_words:
-+#
-+# BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
-+#
-+# r3 = rp
-+# r4 = ap
-+# r5 = num
-+# r6 = w
-+#
-+# empirical evidence suggests that unrolled version performs best!!
-+#
-+	xor	r0,r0,r0		#r0 = 0
-+	xor	r12,r12,r12  		#r12 = 0 . used for carry		
-+	rlwinm.	r7,r5,30,2,31		# num >> 2
-+	beq	Lppcasm_maw_leftover	# if (num < 4) go LPPCASM_maw_leftover
-+	mtctr	r7
-+Lppcasm_maw_mainloop:	
-+					#mul_add(rp[0],ap[0],w,c1);
-+	$LD	r8,`0*$BNSZ`(r4)
-+	$LD	r11,`0*$BNSZ`(r3)
-+	$UMULL	r9,r6,r8
-+	$UMULH  r10,r6,r8
-+	addc	r9,r9,r12		#r12 is carry.
-+	addze	r10,r10
-+	addc	r9,r9,r11
-+	#addze	r10,r10
-+					#the above instruction addze
-+					#is NOT needed. Carry will NOT
-+					#be ignored. It's not affected
-+					#by multiply and will be collected
-+					#in the next spin
-+	$ST	r9,`0*$BNSZ`(r3)
-+	
-+					#mul_add(rp[1],ap[1],w,c1);
-+	$LD	r8,`1*$BNSZ`(r4)	
-+	$LD	r9,`1*$BNSZ`(r3)
-+	$UMULL	r11,r6,r8
-+	$UMULH  r12,r6,r8
-+	adde	r11,r11,r10		#r10 is carry.
-+	addze	r12,r12
-+	addc	r11,r11,r9
-+	#addze	r12,r12
-+	$ST	r11,`1*$BNSZ`(r3)
-+	
-+					#mul_add(rp[2],ap[2],w,c1);
-+	$LD	r8,`2*$BNSZ`(r4)
-+	$UMULL	r9,r6,r8
-+	$LD	r11,`2*$BNSZ`(r3)
-+	$UMULH  r10,r6,r8
-+	adde	r9,r9,r12
-+	addze	r10,r10
-+	addc	r9,r9,r11
-+	#addze	r10,r10
-+	$ST	r9,`2*$BNSZ`(r3)
-+	
-+					#mul_add(rp[3],ap[3],w,c1);
-+	$LD	r8,`3*$BNSZ`(r4)
-+	$UMULL	r11,r6,r8
-+	$LD	r9,`3*$BNSZ`(r3)
-+	$UMULH  r12,r6,r8
-+	adde	r11,r11,r10
-+	addze	r12,r12
-+	addc	r11,r11,r9
-+	addze	r12,r12
-+	$ST	r11,`3*$BNSZ`(r3)
-+	addi	r3,r3,`4*$BNSZ`
-+	addi	r4,r4,`4*$BNSZ`
-+	bdnz	Lppcasm_maw_mainloop
-+	
-+Lppcasm_maw_leftover:
-+	andi.	r5,r5,0x3
-+	beq	Lppcasm_maw_adios
-+	addi	r3,r3,-$BNSZ
-+	addi	r4,r4,-$BNSZ
-+					#mul_add(rp[0],ap[0],w,c1);
-+	mtctr	r5
-+	$LDU	r8,$BNSZ(r4)
-+	$UMULL	r9,r6,r8
-+	$UMULH  r10,r6,r8
-+	$LDU	r11,$BNSZ(r3)
-+	addc	r9,r9,r11
-+	addze	r10,r10
-+	addc	r9,r9,r12
-+	addze	r12,r10
-+	$ST	r9,0(r3)
-+	
-+	bdz	Lppcasm_maw_adios
-+					#mul_add(rp[1],ap[1],w,c1);
-+	$LDU	r8,$BNSZ(r4)	
-+	$UMULL	r9,r6,r8
-+	$UMULH  r10,r6,r8
-+	$LDU	r11,$BNSZ(r3)
-+	addc	r9,r9,r11
-+	addze	r10,r10
-+	addc	r9,r9,r12
-+	addze	r12,r10
-+	$ST	r9,0(r3)
-+	
-+	bdz	Lppcasm_maw_adios
-+					#mul_add(rp[2],ap[2],w,c1);
-+	$LDU	r8,$BNSZ(r4)
-+	$UMULL	r9,r6,r8
-+	$UMULH  r10,r6,r8
-+	$LDU	r11,$BNSZ(r3)
-+	addc	r9,r9,r11
-+	addze	r10,r10
-+	addc	r9,r9,r12
-+	addze	r12,r10
-+	$ST	r9,0(r3)
-+		
-+Lppcasm_maw_adios:	
-+	addi	r3,r12,0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,4,0
-+	.long	0
-+.size	.bn_mul_add_words,.-.bn_mul_add_words
-+	.align	4
-+EOF
-+$data =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $data;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc64-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc64-mont.pl
-new file mode 100644
-index 0000000..1e19c95
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/ppc64-mont.pl
-@@ -0,0 +1,1635 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# December 2007
-+
-+# The reason for undertaken effort is basically following. Even though
-+# Power 6 CPU operates at incredible 4.7GHz clock frequency, its PKI
-+# performance was observed to be less than impressive, essentially as
-+# fast as 1.8GHz PPC970, or 2.6 times(!) slower than one would hope.
-+# Well, it's not surprising that IBM had to make some sacrifices to
-+# boost the clock frequency that much, but no overall improvement?
-+# Having observed how much difference did switching to FPU make on
-+# UltraSPARC, playing same stunt on Power 6 appeared appropriate...
-+# Unfortunately the resulting performance improvement is not as
-+# impressive, ~30%, and in absolute terms is still very far from what
-+# one would expect from 4.7GHz CPU. There is a chance that I'm doing
-+# something wrong, but in the lack of assembler level micro-profiling
-+# data or at least decent platform guide I can't tell... Or better
-+# results might be achieved with VMX... Anyway, this module provides
-+# *worse* performance on other PowerPC implementations, ~40-15% slower
-+# on PPC970 depending on key length and ~40% slower on Power 5 for all
-+# key lengths. As it's obviously inappropriate as "best all-round"
-+# alternative, it has to be complemented with run-time CPU family
-+# detection. Oh! It should also be noted that unlike other PowerPC
-+# implementation IALU ppc-mont.pl module performs *suboptimaly* on
-+# >=1024-bit key lengths on Power 6. It should also be noted that
-+# *everything* said so far applies to 64-bit builds! As far as 32-bit
-+# application executed on 64-bit CPU goes, this module is likely to
-+# become preferred choice, because it's easy to adapt it for such
-+# case and *is* faster than 32-bit ppc-mont.pl on *all* processors.
-+
-+# February 2008
-+
-+# Micro-profiling assisted optimization results in ~15% improvement
-+# over original ppc64-mont.pl version, or overall ~50% improvement
-+# over ppc.pl module on Power 6. If compared to ppc-mont.pl on same
-+# Power 6 CPU, this module is 5-150% faster depending on key length,
-+# [hereafter] more for longer keys. But if compared to ppc-mont.pl
-+# on 1.8GHz PPC970, it's only 5-55% faster. Still far from impressive
-+# in absolute terms, but it's apparently the way Power 6 is...
-+
-+# December 2009
-+
-+# Adapted for 32-bit build this module delivers 25-120%, yes, more
-+# than *twice* for longer keys, performance improvement over 32-bit
-+# ppc-mont.pl on 1.8GHz PPC970. However! This implementation utilizes
-+# even 64-bit integer operations and the trouble is that most PPC
-+# operating systems don't preserve upper halves of general purpose
-+# registers upon 32-bit signal delivery. They do preserve them upon
-+# context switch, but not signalling:-( This means that asynchronous
-+# signals have to be blocked upon entry to this subroutine. Signal
-+# masking (and of course complementary unmasking) has quite an impact
-+# on performance, naturally larger for shorter keys. It's so severe
-+# that 512-bit key performance can be as low as 1/3 of expected one.
-+# This is why this routine can be engaged for longer key operations
-+# only on these OSes, see crypto/ppccap.c for further details. MacOS X
-+# is an exception from this and doesn't require signal masking, and
-+# that's where above improvement coefficients were collected. For
-+# others alternative would be to break dependence on upper halves of
-+# GPRs by sticking to 32-bit integer operations...
-+
-+# December 2012
-+
-+# Remove above mentioned dependence on GPRs' upper halves in 32-bit
-+# build. No signal masking overhead, but integer instructions are
-+# *more* numerous... It's still "universally" faster than 32-bit
-+# ppc-mont.pl, but improvement coefficient is not as impressive
-+# for longer keys...
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /32/) {
-+	$SIZE_T=4;
-+	$RZONE=	224;
-+	$fname=	"bn_mul_mont_fpu64";
-+
-+	$STUX=	"stwux";	# store indexed and update
-+	$PUSH=	"stw";
-+	$POP=	"lwz";
-+} elsif ($flavour =~ /64/) {
-+	$SIZE_T=8;
-+	$RZONE=	288;
-+	$fname=	"bn_mul_mont_fpu64";
-+
-+	# same as above, but 64-bit mnemonics...
-+	$STUX=	"stdux";	# store indexed and update
-+	$PUSH=	"std";
-+	$POP=	"ld";
-+} else { die "nonsense $flavour"; }
-+
-+$LITTLE_ENDIAN = ($flavour=~/le$/) ? 4 : 0;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-+
-+$FRAME=64;	# padded frame header
-+$TRANSFER=16*8;
-+
-+$carry="r0";
-+$sp="r1";
-+$toc="r2";
-+$rp="r3";	$ovf="r3";
-+$ap="r4";
-+$bp="r5";
-+$np="r6";
-+$n0="r7";
-+$num="r8";
-+$rp="r9";	# $rp is reassigned
-+$tp="r10";
-+$j="r11";
-+$i="r12";
-+# non-volatile registers
-+$c1="r19";
-+$n1="r20";
-+$a1="r21";
-+$nap_d="r22";	# interleaved ap and np in double format
-+$a0="r23";	# ap[0]
-+$t0="r24";	# temporary registers
-+$t1="r25";
-+$t2="r26";
-+$t3="r27";
-+$t4="r28";
-+$t5="r29";
-+$t6="r30";
-+$t7="r31";
-+
-+# PPC offers enough register bank capacity to unroll inner loops twice
-+#
-+#     ..A3A2A1A0
-+#           dcba
-+#    -----------
-+#            A0a
-+#           A0b
-+#          A0c
-+#         A0d
-+#          A1a
-+#         A1b
-+#        A1c
-+#       A1d
-+#        A2a
-+#       A2b
-+#      A2c
-+#     A2d
-+#      A3a
-+#     A3b
-+#    A3c
-+#   A3d
-+#    ..a
-+#   ..b
-+#
-+$ba="f0";	$bb="f1";	$bc="f2";	$bd="f3";
-+$na="f4";	$nb="f5";	$nc="f6";	$nd="f7";
-+$dota="f8";	$dotb="f9";
-+$A0="f10";	$A1="f11";	$A2="f12";	$A3="f13";
-+$N0="f20";	$N1="f21";	$N2="f22";	$N3="f23";
-+$T0a="f24";	$T0b="f25";
-+$T1a="f26";	$T1b="f27";
-+$T2a="f28";	$T2b="f29";
-+$T3a="f30";	$T3b="f31";
-+
-+# sp----------->+-------------------------------+
-+#		| saved sp			|
-+#		+-------------------------------+
-+#		.				.
-+#   +64		+-------------------------------+
-+#		| 16 gpr<->fpr transfer zone	|
-+#		.				.
-+#		.				.
-+#   +16*8	+-------------------------------+
-+#		| __int64 tmp[-1]		|
-+#		+-------------------------------+
-+#		| __int64 tmp[num]		|
-+#		.				.
-+#		.				.
-+#		.				.
-+#   +(num+1)*8	+-------------------------------+
-+#		| padding to 64 byte boundary	|
-+#		.				.
-+#   +X		+-------------------------------+
-+#		| double nap_d[4*num]		|
-+#		.				.
-+#		.				.
-+#		.				.
-+#		+-------------------------------+
-+#		.				.
-+#   -13*size_t	+-------------------------------+
-+#		| 13 saved gpr, r19-r31		|
-+#		.				.
-+#		.				.
-+#   -12*8	+-------------------------------+
-+#		| 12 saved fpr, f20-f31		|
-+#		.				.
-+#		.				.
-+#		+-------------------------------+
-+
-+$code=<<___;
-+.machine "any"
-+.text
-+
-+.globl	.$fname
-+.align	5
-+.$fname:
-+	cmpwi	$num,`3*8/$SIZE_T`
-+	mr	$rp,r3		; $rp is reassigned
-+	li	r3,0		; possible "not handled" return code
-+	bltlr-
-+	andi.	r0,$num,`16/$SIZE_T-1`		; $num has to be "even"
-+	bnelr-
-+
-+	slwi	$num,$num,`log($SIZE_T)/log(2)`	; num*=sizeof(BN_LONG)
-+	li	$i,-4096
-+	slwi	$tp,$num,2	; place for {an}p_{lh}[num], i.e. 4*num
-+	add	$tp,$tp,$num	; place for tp[num+1]
-+	addi	$tp,$tp,`$FRAME+$TRANSFER+8+64+$RZONE`
-+	subf	$tp,$tp,$sp	; $sp-$tp
-+	and	$tp,$tp,$i	; minimize TLB usage
-+	subf	$tp,$sp,$tp	; $tp-$sp
-+	mr	$i,$sp
-+	$STUX	$sp,$sp,$tp	; alloca
-+
-+	$PUSH	r19,`-12*8-13*$SIZE_T`($i)
-+	$PUSH	r20,`-12*8-12*$SIZE_T`($i)
-+	$PUSH	r21,`-12*8-11*$SIZE_T`($i)
-+	$PUSH	r22,`-12*8-10*$SIZE_T`($i)
-+	$PUSH	r23,`-12*8-9*$SIZE_T`($i)
-+	$PUSH	r24,`-12*8-8*$SIZE_T`($i)
-+	$PUSH	r25,`-12*8-7*$SIZE_T`($i)
-+	$PUSH	r26,`-12*8-6*$SIZE_T`($i)
-+	$PUSH	r27,`-12*8-5*$SIZE_T`($i)
-+	$PUSH	r28,`-12*8-4*$SIZE_T`($i)
-+	$PUSH	r29,`-12*8-3*$SIZE_T`($i)
-+	$PUSH	r30,`-12*8-2*$SIZE_T`($i)
-+	$PUSH	r31,`-12*8-1*$SIZE_T`($i)
-+	stfd	f20,`-12*8`($i)
-+	stfd	f21,`-11*8`($i)
-+	stfd	f22,`-10*8`($i)
-+	stfd	f23,`-9*8`($i)
-+	stfd	f24,`-8*8`($i)
-+	stfd	f25,`-7*8`($i)
-+	stfd	f26,`-6*8`($i)
-+	stfd	f27,`-5*8`($i)
-+	stfd	f28,`-4*8`($i)
-+	stfd	f29,`-3*8`($i)
-+	stfd	f30,`-2*8`($i)
-+	stfd	f31,`-1*8`($i)
-+
-+	addi	$tp,$sp,`$FRAME+$TRANSFER+8+64`
-+	li	$i,-64
-+	add	$nap_d,$tp,$num
-+	and	$nap_d,$nap_d,$i	; align to 64 bytes
-+	; nap_d is off by 1, because it's used with stfdu/lfdu
-+	addi	$nap_d,$nap_d,-8
-+	srwi	$j,$num,`3+1`	; counter register, num/2
-+	addi	$j,$j,-1
-+	addi	$tp,$sp,`$FRAME+$TRANSFER-8`
-+	li	$carry,0
-+	mtctr	$j
-+___
-+
-+$code.=<<___ if ($SIZE_T==8);
-+	ld	$a0,0($ap)		; pull ap[0] value
-+	ld	$t3,0($bp)		; bp[0]
-+	ld	$n0,0($n0)		; pull n0[0] value
-+
-+	mulld	$t7,$a0,$t3		; ap[0]*bp[0]
-+	; transfer bp[0] to FPU as 4x16-bit values
-+	extrdi	$t0,$t3,16,48
-+	extrdi	$t1,$t3,16,32
-+	extrdi	$t2,$t3,16,16
-+	extrdi	$t3,$t3,16,0
-+	std	$t0,`$FRAME+0`($sp)
-+	std	$t1,`$FRAME+8`($sp)
-+	std	$t2,`$FRAME+16`($sp)
-+	std	$t3,`$FRAME+24`($sp)
-+
-+	mulld	$t7,$t7,$n0		; tp[0]*n0
-+	; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values
-+	extrdi	$t4,$t7,16,48
-+	extrdi	$t5,$t7,16,32
-+	extrdi	$t6,$t7,16,16
-+	extrdi	$t7,$t7,16,0
-+	std	$t4,`$FRAME+32`($sp)
-+	std	$t5,`$FRAME+40`($sp)
-+	std	$t6,`$FRAME+48`($sp)
-+	std	$t7,`$FRAME+56`($sp)
-+
-+	extrdi	$t0,$a0,32,32		; lwz	$t0,4($ap)
-+	extrdi	$t1,$a0,32,0		; lwz	$t1,0($ap)
-+	lwz	$t2,`12^$LITTLE_ENDIAN`($ap)	; load a[1] as 32-bit word pair
-+	lwz	$t3,`8^$LITTLE_ENDIAN`($ap)
-+	lwz	$t4,`4^$LITTLE_ENDIAN`($np)	; load n[0] as 32-bit word pair
-+	lwz	$t5,`0^$LITTLE_ENDIAN`($np)
-+	lwz	$t6,`12^$LITTLE_ENDIAN`($np)	; load n[1] as 32-bit word pair
-+	lwz	$t7,`8^$LITTLE_ENDIAN`($np)
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	lwz	$a0,0($ap)		; pull ap[0,1] value
-+	mr	$n1,$n0
-+	lwz	$a1,4($ap)
-+	li	$c1,0
-+	lwz	$t1,0($bp)		; bp[0,1]
-+	lwz	$t3,4($bp)
-+	lwz	$n0,0($n1)		; pull n0[0,1] value
-+	lwz	$n1,4($n1)
-+
-+	mullw	$t4,$a0,$t1		; mulld ap[0]*bp[0]
-+	mulhwu	$t5,$a0,$t1
-+	mullw	$t6,$a1,$t1
-+	mullw	$t7,$a0,$t3
-+	add	$t5,$t5,$t6
-+	add	$t5,$t5,$t7
-+	; transfer bp[0] to FPU as 4x16-bit values
-+	extrwi	$t0,$t1,16,16
-+	extrwi	$t1,$t1,16,0
-+	extrwi	$t2,$t3,16,16
-+	extrwi	$t3,$t3,16,0
-+	std	$t0,`$FRAME+0`($sp)	; yes, std in 32-bit build
-+	std	$t1,`$FRAME+8`($sp)
-+	std	$t2,`$FRAME+16`($sp)
-+	std	$t3,`$FRAME+24`($sp)
-+
-+	mullw	$t0,$t4,$n0		; mulld tp[0]*n0
-+	mulhwu	$t1,$t4,$n0
-+	mullw	$t2,$t5,$n0
-+	mullw	$t3,$t4,$n1
-+	add	$t1,$t1,$t2
-+	add	$t1,$t1,$t3
-+	; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values
-+	extrwi	$t4,$t0,16,16
-+	extrwi	$t5,$t0,16,0
-+	extrwi	$t6,$t1,16,16
-+	extrwi	$t7,$t1,16,0
-+	std	$t4,`$FRAME+32`($sp)	; yes, std in 32-bit build
-+	std	$t5,`$FRAME+40`($sp)
-+	std	$t6,`$FRAME+48`($sp)
-+	std	$t7,`$FRAME+56`($sp)
-+
-+	mr	$t0,$a0			; lwz	$t0,0($ap)
-+	mr	$t1,$a1			; lwz	$t1,4($ap)
-+	lwz	$t2,8($ap)		; load a[j..j+3] as 32-bit word pairs
-+	lwz	$t3,12($ap)
-+	lwz	$t4,0($np)		; load n[j..j+3] as 32-bit word pairs
-+	lwz	$t5,4($np)
-+	lwz	$t6,8($np)
-+	lwz	$t7,12($np)
-+___
-+$code.=<<___;
-+	lfd	$ba,`$FRAME+0`($sp)
-+	lfd	$bb,`$FRAME+8`($sp)
-+	lfd	$bc,`$FRAME+16`($sp)
-+	lfd	$bd,`$FRAME+24`($sp)
-+	lfd	$na,`$FRAME+32`($sp)
-+	lfd	$nb,`$FRAME+40`($sp)
-+	lfd	$nc,`$FRAME+48`($sp)
-+	lfd	$nd,`$FRAME+56`($sp)
-+	std	$t0,`$FRAME+64`($sp)	; yes, std even in 32-bit build
-+	std	$t1,`$FRAME+72`($sp)
-+	std	$t2,`$FRAME+80`($sp)
-+	std	$t3,`$FRAME+88`($sp)
-+	std	$t4,`$FRAME+96`($sp)
-+	std	$t5,`$FRAME+104`($sp)
-+	std	$t6,`$FRAME+112`($sp)
-+	std	$t7,`$FRAME+120`($sp)
-+	fcfid	$ba,$ba
-+	fcfid	$bb,$bb
-+	fcfid	$bc,$bc
-+	fcfid	$bd,$bd
-+	fcfid	$na,$na
-+	fcfid	$nb,$nb
-+	fcfid	$nc,$nc
-+	fcfid	$nd,$nd
-+
-+	lfd	$A0,`$FRAME+64`($sp)
-+	lfd	$A1,`$FRAME+72`($sp)
-+	lfd	$A2,`$FRAME+80`($sp)
-+	lfd	$A3,`$FRAME+88`($sp)
-+	lfd	$N0,`$FRAME+96`($sp)
-+	lfd	$N1,`$FRAME+104`($sp)
-+	lfd	$N2,`$FRAME+112`($sp)
-+	lfd	$N3,`$FRAME+120`($sp)
-+	fcfid	$A0,$A0
-+	fcfid	$A1,$A1
-+	fcfid	$A2,$A2
-+	fcfid	$A3,$A3
-+	fcfid	$N0,$N0
-+	fcfid	$N1,$N1
-+	fcfid	$N2,$N2
-+	fcfid	$N3,$N3
-+	addi	$ap,$ap,16
-+	addi	$np,$np,16
-+
-+	fmul	$T1a,$A1,$ba
-+	fmul	$T1b,$A1,$bb
-+	stfd	$A0,8($nap_d)		; save a[j] in double format
-+	stfd	$A1,16($nap_d)
-+	fmul	$T2a,$A2,$ba
-+	fmul	$T2b,$A2,$bb
-+	stfd	$A2,24($nap_d)		; save a[j+1] in double format
-+	stfd	$A3,32($nap_d)
-+	fmul	$T3a,$A3,$ba
-+	fmul	$T3b,$A3,$bb
-+	stfd	$N0,40($nap_d)		; save n[j] in double format
-+	stfd	$N1,48($nap_d)
-+	fmul	$T0a,$A0,$ba
-+	fmul	$T0b,$A0,$bb
-+	stfd	$N2,56($nap_d)		; save n[j+1] in double format
-+	stfdu	$N3,64($nap_d)
-+
-+	fmadd	$T1a,$A0,$bc,$T1a
-+	fmadd	$T1b,$A0,$bd,$T1b
-+	fmadd	$T2a,$A1,$bc,$T2a
-+	fmadd	$T2b,$A1,$bd,$T2b
-+	fmadd	$T3a,$A2,$bc,$T3a
-+	fmadd	$T3b,$A2,$bd,$T3b
-+	fmul	$dota,$A3,$bc
-+	fmul	$dotb,$A3,$bd
-+
-+	fmadd	$T1a,$N1,$na,$T1a
-+	fmadd	$T1b,$N1,$nb,$T1b
-+	fmadd	$T2a,$N2,$na,$T2a
-+	fmadd	$T2b,$N2,$nb,$T2b
-+	fmadd	$T3a,$N3,$na,$T3a
-+	fmadd	$T3b,$N3,$nb,$T3b
-+	fmadd	$T0a,$N0,$na,$T0a
-+	fmadd	$T0b,$N0,$nb,$T0b
-+
-+	fmadd	$T1a,$N0,$nc,$T1a
-+	fmadd	$T1b,$N0,$nd,$T1b
-+	fmadd	$T2a,$N1,$nc,$T2a
-+	fmadd	$T2b,$N1,$nd,$T2b
-+	fmadd	$T3a,$N2,$nc,$T3a
-+	fmadd	$T3b,$N2,$nd,$T3b
-+	fmadd	$dota,$N3,$nc,$dota
-+	fmadd	$dotb,$N3,$nd,$dotb
-+
-+	fctid	$T0a,$T0a
-+	fctid	$T0b,$T0b
-+	fctid	$T1a,$T1a
-+	fctid	$T1b,$T1b
-+	fctid	$T2a,$T2a
-+	fctid	$T2b,$T2b
-+	fctid	$T3a,$T3a
-+	fctid	$T3b,$T3b
-+
-+	stfd	$T0a,`$FRAME+0`($sp)
-+	stfd	$T0b,`$FRAME+8`($sp)
-+	stfd	$T1a,`$FRAME+16`($sp)
-+	stfd	$T1b,`$FRAME+24`($sp)
-+	stfd	$T2a,`$FRAME+32`($sp)
-+	stfd	$T2b,`$FRAME+40`($sp)
-+	stfd	$T3a,`$FRAME+48`($sp)
-+	stfd	$T3b,`$FRAME+56`($sp)
-+
-+.align	5
-+L1st:
-+___
-+$code.=<<___ if ($SIZE_T==8);
-+	lwz	$t0,`4^$LITTLE_ENDIAN`($ap)	; load a[j] as 32-bit word pair
-+	lwz	$t1,`0^$LITTLE_ENDIAN`($ap)
-+	lwz	$t2,`12^$LITTLE_ENDIAN`($ap)	; load a[j+1] as 32-bit word pair
-+	lwz	$t3,`8^$LITTLE_ENDIAN`($ap)
-+	lwz	$t4,`4^$LITTLE_ENDIAN`($np)	; load n[j] as 32-bit word pair
-+	lwz	$t5,`0^$LITTLE_ENDIAN`($np)
-+	lwz	$t6,`12^$LITTLE_ENDIAN`($np)	; load n[j+1] as 32-bit word pair
-+	lwz	$t7,`8^$LITTLE_ENDIAN`($np)
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	lwz	$t0,0($ap)		; load a[j..j+3] as 32-bit word pairs
-+	lwz	$t1,4($ap)
-+	lwz	$t2,8($ap)
-+	lwz	$t3,12($ap)
-+	lwz	$t4,0($np)		; load n[j..j+3] as 32-bit word pairs
-+	lwz	$t5,4($np)
-+	lwz	$t6,8($np)
-+	lwz	$t7,12($np)
-+___
-+$code.=<<___;
-+	std	$t0,`$FRAME+64`($sp)	; yes, std even in 32-bit build
-+	std	$t1,`$FRAME+72`($sp)
-+	std	$t2,`$FRAME+80`($sp)
-+	std	$t3,`$FRAME+88`($sp)
-+	std	$t4,`$FRAME+96`($sp)
-+	std	$t5,`$FRAME+104`($sp)
-+	std	$t6,`$FRAME+112`($sp)
-+	std	$t7,`$FRAME+120`($sp)
-+___
-+if ($SIZE_T==8 or $flavour =~ /osx/) {
-+$code.=<<___;
-+	ld	$t0,`$FRAME+0`($sp)
-+	ld	$t1,`$FRAME+8`($sp)
-+	ld	$t2,`$FRAME+16`($sp)
-+	ld	$t3,`$FRAME+24`($sp)
-+	ld	$t4,`$FRAME+32`($sp)
-+	ld	$t5,`$FRAME+40`($sp)
-+	ld	$t6,`$FRAME+48`($sp)
-+	ld	$t7,`$FRAME+56`($sp)
-+___
-+} else {
-+$code.=<<___;
-+	lwz	$t1,`$FRAME+0^$LITTLE_ENDIAN`($sp)
-+	lwz	$t0,`$FRAME+4^$LITTLE_ENDIAN`($sp)
-+	lwz	$t3,`$FRAME+8^$LITTLE_ENDIAN`($sp)
-+	lwz	$t2,`$FRAME+12^$LITTLE_ENDIAN`($sp)
-+	lwz	$t5,`$FRAME+16^$LITTLE_ENDIAN`($sp)
-+	lwz	$t4,`$FRAME+20^$LITTLE_ENDIAN`($sp)
-+	lwz	$t7,`$FRAME+24^$LITTLE_ENDIAN`($sp)
-+	lwz	$t6,`$FRAME+28^$LITTLE_ENDIAN`($sp)
-+___
-+}
-+$code.=<<___;
-+	lfd	$A0,`$FRAME+64`($sp)
-+	lfd	$A1,`$FRAME+72`($sp)
-+	lfd	$A2,`$FRAME+80`($sp)
-+	lfd	$A3,`$FRAME+88`($sp)
-+	lfd	$N0,`$FRAME+96`($sp)
-+	lfd	$N1,`$FRAME+104`($sp)
-+	lfd	$N2,`$FRAME+112`($sp)
-+	lfd	$N3,`$FRAME+120`($sp)
-+	fcfid	$A0,$A0
-+	fcfid	$A1,$A1
-+	fcfid	$A2,$A2
-+	fcfid	$A3,$A3
-+	fcfid	$N0,$N0
-+	fcfid	$N1,$N1
-+	fcfid	$N2,$N2
-+	fcfid	$N3,$N3
-+	addi	$ap,$ap,16
-+	addi	$np,$np,16
-+
-+	fmul	$T1a,$A1,$ba
-+	fmul	$T1b,$A1,$bb
-+	fmul	$T2a,$A2,$ba
-+	fmul	$T2b,$A2,$bb
-+	stfd	$A0,8($nap_d)		; save a[j] in double format
-+	stfd	$A1,16($nap_d)
-+	fmul	$T3a,$A3,$ba
-+	fmul	$T3b,$A3,$bb
-+	fmadd	$T0a,$A0,$ba,$dota
-+	fmadd	$T0b,$A0,$bb,$dotb
-+	stfd	$A2,24($nap_d)		; save a[j+1] in double format
-+	stfd	$A3,32($nap_d)
-+___
-+if ($SIZE_T==8 or $flavour =~ /osx/) {
-+$code.=<<___;
-+	fmadd	$T1a,$A0,$bc,$T1a
-+	fmadd	$T1b,$A0,$bd,$T1b
-+	fmadd	$T2a,$A1,$bc,$T2a
-+	fmadd	$T2b,$A1,$bd,$T2b
-+	stfd	$N0,40($nap_d)		; save n[j] in double format
-+	stfd	$N1,48($nap_d)
-+	fmadd	$T3a,$A2,$bc,$T3a
-+	fmadd	$T3b,$A2,$bd,$T3b
-+	 add	$t0,$t0,$carry		; can not overflow
-+	fmul	$dota,$A3,$bc
-+	fmul	$dotb,$A3,$bd
-+	stfd	$N2,56($nap_d)		; save n[j+1] in double format
-+	stfdu	$N3,64($nap_d)
-+	 srdi	$carry,$t0,16
-+	 add	$t1,$t1,$carry
-+	 srdi	$carry,$t1,16
-+
-+	fmadd	$T1a,$N1,$na,$T1a
-+	fmadd	$T1b,$N1,$nb,$T1b
-+	 insrdi	$t0,$t1,16,32
-+	fmadd	$T2a,$N2,$na,$T2a
-+	fmadd	$T2b,$N2,$nb,$T2b
-+	 add	$t2,$t2,$carry
-+	fmadd	$T3a,$N3,$na,$T3a
-+	fmadd	$T3b,$N3,$nb,$T3b
-+	 srdi	$carry,$t2,16
-+	fmadd	$T0a,$N0,$na,$T0a
-+	fmadd	$T0b,$N0,$nb,$T0b
-+	 insrdi	$t0,$t2,16,16
-+	 add	$t3,$t3,$carry
-+	 srdi	$carry,$t3,16
-+
-+	fmadd	$T1a,$N0,$nc,$T1a
-+	fmadd	$T1b,$N0,$nd,$T1b
-+	 insrdi	$t0,$t3,16,0		; 0..63 bits
-+	fmadd	$T2a,$N1,$nc,$T2a
-+	fmadd	$T2b,$N1,$nd,$T2b
-+	 add	$t4,$t4,$carry
-+	fmadd	$T3a,$N2,$nc,$T3a
-+	fmadd	$T3b,$N2,$nd,$T3b
-+	 srdi	$carry,$t4,16
-+	fmadd	$dota,$N3,$nc,$dota
-+	fmadd	$dotb,$N3,$nd,$dotb
-+	 add	$t5,$t5,$carry
-+	 srdi	$carry,$t5,16
-+	 insrdi	$t4,$t5,16,32
-+
-+	fctid	$T0a,$T0a
-+	fctid	$T0b,$T0b
-+	 add	$t6,$t6,$carry
-+	fctid	$T1a,$T1a
-+	fctid	$T1b,$T1b
-+	 srdi	$carry,$t6,16
-+	fctid	$T2a,$T2a
-+	fctid	$T2b,$T2b
-+	 insrdi	$t4,$t6,16,16
-+	fctid	$T3a,$T3a
-+	fctid	$T3b,$T3b
-+	 add	$t7,$t7,$carry
-+	 insrdi	$t4,$t7,16,0		; 64..127 bits
-+	 srdi	$carry,$t7,16		; upper 33 bits
-+
-+	stfd	$T0a,`$FRAME+0`($sp)
-+	stfd	$T0b,`$FRAME+8`($sp)
-+	stfd	$T1a,`$FRAME+16`($sp)
-+	stfd	$T1b,`$FRAME+24`($sp)
-+	stfd	$T2a,`$FRAME+32`($sp)
-+	stfd	$T2b,`$FRAME+40`($sp)
-+	stfd	$T3a,`$FRAME+48`($sp)
-+	stfd	$T3b,`$FRAME+56`($sp)
-+	 std	$t0,8($tp)		; tp[j-1]
-+	 stdu	$t4,16($tp)		; tp[j]
-+___
-+} else {
-+$code.=<<___;
-+	fmadd	$T1a,$A0,$bc,$T1a
-+	fmadd	$T1b,$A0,$bd,$T1b
-+	 addc	$t0,$t0,$carry
-+	 adde	$t1,$t1,$c1
-+	 srwi	$carry,$t0,16
-+	fmadd	$T2a,$A1,$bc,$T2a
-+	fmadd	$T2b,$A1,$bd,$T2b
-+	stfd	$N0,40($nap_d)		; save n[j] in double format
-+	stfd	$N1,48($nap_d)
-+	 srwi	$c1,$t1,16
-+	 insrwi	$carry,$t1,16,0
-+	fmadd	$T3a,$A2,$bc,$T3a
-+	fmadd	$T3b,$A2,$bd,$T3b
-+	 addc	$t2,$t2,$carry
-+	 adde	$t3,$t3,$c1
-+	 srwi	$carry,$t2,16
-+	fmul	$dota,$A3,$bc
-+	fmul	$dotb,$A3,$bd
-+	stfd	$N2,56($nap_d)		; save n[j+1] in double format
-+	stfdu	$N3,64($nap_d)
-+	 insrwi	$t0,$t2,16,0		; 0..31 bits
-+	 srwi	$c1,$t3,16
-+	 insrwi	$carry,$t3,16,0
-+
-+	fmadd	$T1a,$N1,$na,$T1a
-+	fmadd	$T1b,$N1,$nb,$T1b
-+	 lwz	$t3,`$FRAME+32^$LITTLE_ENDIAN`($sp)	; permuted $t1
-+	 lwz	$t2,`$FRAME+36^$LITTLE_ENDIAN`($sp)	; permuted $t0
-+	 addc	$t4,$t4,$carry
-+	 adde	$t5,$t5,$c1
-+	 srwi	$carry,$t4,16
-+	fmadd	$T2a,$N2,$na,$T2a
-+	fmadd	$T2b,$N2,$nb,$T2b
-+	 srwi	$c1,$t5,16
-+	 insrwi	$carry,$t5,16,0
-+	fmadd	$T3a,$N3,$na,$T3a
-+	fmadd	$T3b,$N3,$nb,$T3b
-+	 addc	$t6,$t6,$carry
-+	 adde	$t7,$t7,$c1
-+	 srwi	$carry,$t6,16
-+	fmadd	$T0a,$N0,$na,$T0a
-+	fmadd	$T0b,$N0,$nb,$T0b
-+	 insrwi	$t4,$t6,16,0		; 32..63 bits
-+	 srwi	$c1,$t7,16
-+	 insrwi	$carry,$t7,16,0
-+
-+	fmadd	$T1a,$N0,$nc,$T1a
-+	fmadd	$T1b,$N0,$nd,$T1b
-+	 lwz	$t7,`$FRAME+40^$LITTLE_ENDIAN`($sp)	; permuted $t3
-+	 lwz	$t6,`$FRAME+44^$LITTLE_ENDIAN`($sp)	; permuted $t2
-+	 addc	$t2,$t2,$carry
-+	 adde	$t3,$t3,$c1
-+	 srwi	$carry,$t2,16
-+	fmadd	$T2a,$N1,$nc,$T2a
-+	fmadd	$T2b,$N1,$nd,$T2b
-+	 stw	$t0,12($tp)		; tp[j-1]
-+	 stw	$t4,8($tp)
-+	 srwi	$c1,$t3,16
-+	 insrwi	$carry,$t3,16,0
-+	fmadd	$T3a,$N2,$nc,$T3a
-+	fmadd	$T3b,$N2,$nd,$T3b
-+	 lwz	$t1,`$FRAME+48^$LITTLE_ENDIAN`($sp)	; permuted $t5
-+	 lwz	$t0,`$FRAME+52^$LITTLE_ENDIAN`($sp)	; permuted $t4
-+	 addc	$t6,$t6,$carry
-+	 adde	$t7,$t7,$c1
-+	 srwi	$carry,$t6,16
-+	fmadd	$dota,$N3,$nc,$dota
-+	fmadd	$dotb,$N3,$nd,$dotb
-+	 insrwi	$t2,$t6,16,0		; 64..95 bits
-+	 srwi	$c1,$t7,16
-+	 insrwi	$carry,$t7,16,0
-+
-+	fctid	$T0a,$T0a
-+	fctid	$T0b,$T0b
-+	 lwz	$t5,`$FRAME+56^$LITTLE_ENDIAN`($sp)	; permuted $t7
-+	 lwz	$t4,`$FRAME+60^$LITTLE_ENDIAN`($sp)	; permuted $t6
-+	 addc	$t0,$t0,$carry
-+	 adde	$t1,$t1,$c1
-+	 srwi	$carry,$t0,16
-+	fctid	$T1a,$T1a
-+	fctid	$T1b,$T1b
-+	 srwi	$c1,$t1,16
-+	 insrwi	$carry,$t1,16,0
-+	fctid	$T2a,$T2a
-+	fctid	$T2b,$T2b
-+	 addc	$t4,$t4,$carry
-+	 adde	$t5,$t5,$c1
-+	 srwi	$carry,$t4,16
-+	fctid	$T3a,$T3a
-+	fctid	$T3b,$T3b
-+	 insrwi	$t0,$t4,16,0		; 96..127 bits
-+	 srwi	$c1,$t5,16
-+	 insrwi	$carry,$t5,16,0
-+
-+	stfd	$T0a,`$FRAME+0`($sp)
-+	stfd	$T0b,`$FRAME+8`($sp)
-+	stfd	$T1a,`$FRAME+16`($sp)
-+	stfd	$T1b,`$FRAME+24`($sp)
-+	stfd	$T2a,`$FRAME+32`($sp)
-+	stfd	$T2b,`$FRAME+40`($sp)
-+	stfd	$T3a,`$FRAME+48`($sp)
-+	stfd	$T3b,`$FRAME+56`($sp)
-+	 stw	$t2,20($tp)		; tp[j]
-+	 stwu	$t0,16($tp)
-+___
-+}
-+$code.=<<___;
-+	bdnz	L1st
-+
-+	fctid	$dota,$dota
-+	fctid	$dotb,$dotb
-+___
-+if ($SIZE_T==8 or $flavour =~ /osx/) {
-+$code.=<<___;
-+	ld	$t0,`$FRAME+0`($sp)
-+	ld	$t1,`$FRAME+8`($sp)
-+	ld	$t2,`$FRAME+16`($sp)
-+	ld	$t3,`$FRAME+24`($sp)
-+	ld	$t4,`$FRAME+32`($sp)
-+	ld	$t5,`$FRAME+40`($sp)
-+	ld	$t6,`$FRAME+48`($sp)
-+	ld	$t7,`$FRAME+56`($sp)
-+	stfd	$dota,`$FRAME+64`($sp)
-+	stfd	$dotb,`$FRAME+72`($sp)
-+
-+	add	$t0,$t0,$carry		; can not overflow
-+	srdi	$carry,$t0,16
-+	add	$t1,$t1,$carry
-+	srdi	$carry,$t1,16
-+	insrdi	$t0,$t1,16,32
-+	add	$t2,$t2,$carry
-+	srdi	$carry,$t2,16
-+	insrdi	$t0,$t2,16,16
-+	add	$t3,$t3,$carry
-+	srdi	$carry,$t3,16
-+	insrdi	$t0,$t3,16,0		; 0..63 bits
-+	add	$t4,$t4,$carry
-+	srdi	$carry,$t4,16
-+	add	$t5,$t5,$carry
-+	srdi	$carry,$t5,16
-+	insrdi	$t4,$t5,16,32
-+	add	$t6,$t6,$carry
-+	srdi	$carry,$t6,16
-+	insrdi	$t4,$t6,16,16
-+	add	$t7,$t7,$carry
-+	insrdi	$t4,$t7,16,0		; 64..127 bits
-+	srdi	$carry,$t7,16		; upper 33 bits
-+	ld	$t6,`$FRAME+64`($sp)
-+	ld	$t7,`$FRAME+72`($sp)
-+
-+	std	$t0,8($tp)		; tp[j-1]
-+	stdu	$t4,16($tp)		; tp[j]
-+
-+	add	$t6,$t6,$carry		; can not overflow
-+	srdi	$carry,$t6,16
-+	add	$t7,$t7,$carry
-+	insrdi	$t6,$t7,48,0
-+	srdi	$ovf,$t7,48
-+	std	$t6,8($tp)		; tp[num-1]
-+___
-+} else {
-+$code.=<<___;
-+	lwz	$t1,`$FRAME+0^$LITTLE_ENDIAN`($sp)
-+	lwz	$t0,`$FRAME+4^$LITTLE_ENDIAN`($sp)
-+	lwz	$t3,`$FRAME+8^$LITTLE_ENDIAN`($sp)
-+	lwz	$t2,`$FRAME+12^$LITTLE_ENDIAN`($sp)
-+	lwz	$t5,`$FRAME+16^$LITTLE_ENDIAN`($sp)
-+	lwz	$t4,`$FRAME+20^$LITTLE_ENDIAN`($sp)
-+	lwz	$t7,`$FRAME+24^$LITTLE_ENDIAN`($sp)
-+	lwz	$t6,`$FRAME+28^$LITTLE_ENDIAN`($sp)
-+	stfd	$dota,`$FRAME+64`($sp)
-+	stfd	$dotb,`$FRAME+72`($sp)
-+
-+	addc	$t0,$t0,$carry
-+	adde	$t1,$t1,$c1
-+	srwi	$carry,$t0,16
-+	insrwi	$carry,$t1,16,0
-+	srwi	$c1,$t1,16
-+	addc	$t2,$t2,$carry
-+	adde	$t3,$t3,$c1
-+	srwi	$carry,$t2,16
-+	 insrwi	$t0,$t2,16,0		; 0..31 bits
-+	insrwi	$carry,$t3,16,0
-+	srwi	$c1,$t3,16
-+	addc	$t4,$t4,$carry
-+	adde	$t5,$t5,$c1
-+	srwi	$carry,$t4,16
-+	insrwi	$carry,$t5,16,0
-+	srwi	$c1,$t5,16
-+	addc	$t6,$t6,$carry
-+	adde	$t7,$t7,$c1
-+	srwi	$carry,$t6,16
-+	 insrwi	$t4,$t6,16,0		; 32..63 bits
-+	insrwi	$carry,$t7,16,0
-+	srwi	$c1,$t7,16
-+	 stw	$t0,12($tp)		; tp[j-1]
-+	 stw	$t4,8($tp)
-+
-+	lwz	$t3,`$FRAME+32^$LITTLE_ENDIAN`($sp)	; permuted $t1
-+	lwz	$t2,`$FRAME+36^$LITTLE_ENDIAN`($sp)	; permuted $t0
-+	lwz	$t7,`$FRAME+40^$LITTLE_ENDIAN`($sp)	; permuted $t3
-+	lwz	$t6,`$FRAME+44^$LITTLE_ENDIAN`($sp)	; permuted $t2
-+	lwz	$t1,`$FRAME+48^$LITTLE_ENDIAN`($sp)	; permuted $t5
-+	lwz	$t0,`$FRAME+52^$LITTLE_ENDIAN`($sp)	; permuted $t4
-+	lwz	$t5,`$FRAME+56^$LITTLE_ENDIAN`($sp)	; permuted $t7
-+	lwz	$t4,`$FRAME+60^$LITTLE_ENDIAN`($sp)	; permuted $t6
-+
-+	addc	$t2,$t2,$carry
-+	adde	$t3,$t3,$c1
-+	srwi	$carry,$t2,16
-+	insrwi	$carry,$t3,16,0
-+	srwi	$c1,$t3,16
-+	addc	$t6,$t6,$carry
-+	adde	$t7,$t7,$c1
-+	srwi	$carry,$t6,16
-+	 insrwi	$t2,$t6,16,0		; 64..95 bits
-+	insrwi	$carry,$t7,16,0
-+	srwi	$c1,$t7,16
-+	addc	$t0,$t0,$carry
-+	adde	$t1,$t1,$c1
-+	srwi	$carry,$t0,16
-+	insrwi	$carry,$t1,16,0
-+	srwi	$c1,$t1,16
-+	addc	$t4,$t4,$carry
-+	adde	$t5,$t5,$c1
-+	srwi	$carry,$t4,16
-+	 insrwi	$t0,$t4,16,0		; 96..127 bits
-+	insrwi	$carry,$t5,16,0
-+	srwi	$c1,$t5,16
-+	 stw	$t2,20($tp)		; tp[j]
-+	 stwu	$t0,16($tp)
-+
-+	lwz	$t7,`$FRAME+64^$LITTLE_ENDIAN`($sp)
-+	lwz	$t6,`$FRAME+68^$LITTLE_ENDIAN`($sp)
-+	lwz	$t5,`$FRAME+72^$LITTLE_ENDIAN`($sp)
-+	lwz	$t4,`$FRAME+76^$LITTLE_ENDIAN`($sp)
-+
-+	addc	$t6,$t6,$carry
-+	adde	$t7,$t7,$c1
-+	srwi	$carry,$t6,16
-+	insrwi	$carry,$t7,16,0
-+	srwi	$c1,$t7,16
-+	addc	$t4,$t4,$carry
-+	adde	$t5,$t5,$c1
-+
-+	insrwi	$t6,$t4,16,0
-+	srwi	$t4,$t4,16
-+	insrwi	$t4,$t5,16,0
-+	srwi	$ovf,$t5,16
-+	stw	$t6,12($tp)		; tp[num-1]
-+	stw	$t4,8($tp)
-+___
-+}
-+$code.=<<___;
-+	slwi	$t7,$num,2
-+	subf	$nap_d,$t7,$nap_d	; rewind pointer
-+
-+	li	$i,8			; i=1
-+.align	5
-+Louter:
-+	addi	$tp,$sp,`$FRAME+$TRANSFER`
-+	li	$carry,0
-+	mtctr	$j
-+___
-+$code.=<<___ if ($SIZE_T==8);
-+	ldx	$t3,$bp,$i		; bp[i]
-+
-+	ld	$t6,`$FRAME+$TRANSFER+8`($sp)	; tp[0]
-+	mulld	$t7,$a0,$t3		; ap[0]*bp[i]
-+	add	$t7,$t7,$t6		; ap[0]*bp[i]+tp[0]
-+	; transfer bp[i] to FPU as 4x16-bit values
-+	extrdi	$t0,$t3,16,48
-+	extrdi	$t1,$t3,16,32
-+	extrdi	$t2,$t3,16,16
-+	extrdi	$t3,$t3,16,0
-+	std	$t0,`$FRAME+0`($sp)
-+	std	$t1,`$FRAME+8`($sp)
-+	std	$t2,`$FRAME+16`($sp)
-+	std	$t3,`$FRAME+24`($sp)
-+
-+	mulld	$t7,$t7,$n0		; tp[0]*n0
-+	; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values
-+	extrdi	$t4,$t7,16,48
-+	extrdi	$t5,$t7,16,32
-+	extrdi	$t6,$t7,16,16
-+	extrdi	$t7,$t7,16,0
-+	std	$t4,`$FRAME+32`($sp)
-+	std	$t5,`$FRAME+40`($sp)
-+	std	$t6,`$FRAME+48`($sp)
-+	std	$t7,`$FRAME+56`($sp)
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	add	$t0,$bp,$i
-+	li	$c1,0
-+	lwz	$t1,0($t0)		; bp[i,i+1]
-+	lwz	$t3,4($t0)
-+
-+	mullw	$t4,$a0,$t1		; ap[0]*bp[i]
-+	lwz	$t0,`$FRAME+$TRANSFER+8+4`($sp)	; tp[0]
-+	mulhwu	$t5,$a0,$t1
-+	lwz	$t2,`$FRAME+$TRANSFER+8`($sp)	; tp[0]
-+	mullw	$t6,$a1,$t1
-+	mullw	$t7,$a0,$t3
-+	add	$t5,$t5,$t6
-+	add	$t5,$t5,$t7
-+	addc	$t4,$t4,$t0		; ap[0]*bp[i]+tp[0]
-+	adde	$t5,$t5,$t2
-+	; transfer bp[i] to FPU as 4x16-bit values
-+	extrwi	$t0,$t1,16,16
-+	extrwi	$t1,$t1,16,0
-+	extrwi	$t2,$t3,16,16
-+	extrwi	$t3,$t3,16,0
-+	std	$t0,`$FRAME+0`($sp)	; yes, std in 32-bit build
-+	std	$t1,`$FRAME+8`($sp)
-+	std	$t2,`$FRAME+16`($sp)
-+	std	$t3,`$FRAME+24`($sp)
-+
-+	mullw	$t0,$t4,$n0		; mulld tp[0]*n0
-+	mulhwu	$t1,$t4,$n0
-+	mullw	$t2,$t5,$n0
-+	mullw	$t3,$t4,$n1
-+	add	$t1,$t1,$t2
-+	add	$t1,$t1,$t3
-+	; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values
-+	extrwi	$t4,$t0,16,16
-+	extrwi	$t5,$t0,16,0
-+	extrwi	$t6,$t1,16,16
-+	extrwi	$t7,$t1,16,0
-+	std	$t4,`$FRAME+32`($sp)	; yes, std in 32-bit build
-+	std	$t5,`$FRAME+40`($sp)
-+	std	$t6,`$FRAME+48`($sp)
-+	std	$t7,`$FRAME+56`($sp)
-+___
-+$code.=<<___;
-+	lfd	$A0,8($nap_d)		; load a[j] in double format
-+	lfd	$A1,16($nap_d)
-+	lfd	$A2,24($nap_d)		; load a[j+1] in double format
-+	lfd	$A3,32($nap_d)
-+	lfd	$N0,40($nap_d)		; load n[j] in double format
-+	lfd	$N1,48($nap_d)
-+	lfd	$N2,56($nap_d)		; load n[j+1] in double format
-+	lfdu	$N3,64($nap_d)
-+
-+	lfd	$ba,`$FRAME+0`($sp)
-+	lfd	$bb,`$FRAME+8`($sp)
-+	lfd	$bc,`$FRAME+16`($sp)
-+	lfd	$bd,`$FRAME+24`($sp)
-+	lfd	$na,`$FRAME+32`($sp)
-+	lfd	$nb,`$FRAME+40`($sp)
-+	lfd	$nc,`$FRAME+48`($sp)
-+	lfd	$nd,`$FRAME+56`($sp)
-+
-+	fcfid	$ba,$ba
-+	fcfid	$bb,$bb
-+	fcfid	$bc,$bc
-+	fcfid	$bd,$bd
-+	fcfid	$na,$na
-+	fcfid	$nb,$nb
-+	fcfid	$nc,$nc
-+	fcfid	$nd,$nd
-+
-+	fmul	$T1a,$A1,$ba
-+	fmul	$T1b,$A1,$bb
-+	fmul	$T2a,$A2,$ba
-+	fmul	$T2b,$A2,$bb
-+	fmul	$T3a,$A3,$ba
-+	fmul	$T3b,$A3,$bb
-+	fmul	$T0a,$A0,$ba
-+	fmul	$T0b,$A0,$bb
-+
-+	fmadd	$T1a,$A0,$bc,$T1a
-+	fmadd	$T1b,$A0,$bd,$T1b
-+	fmadd	$T2a,$A1,$bc,$T2a
-+	fmadd	$T2b,$A1,$bd,$T2b
-+	fmadd	$T3a,$A2,$bc,$T3a
-+	fmadd	$T3b,$A2,$bd,$T3b
-+	fmul	$dota,$A3,$bc
-+	fmul	$dotb,$A3,$bd
-+
-+	fmadd	$T1a,$N1,$na,$T1a
-+	fmadd	$T1b,$N1,$nb,$T1b
-+	 lfd	$A0,8($nap_d)		; load a[j] in double format
-+	 lfd	$A1,16($nap_d)
-+	fmadd	$T2a,$N2,$na,$T2a
-+	fmadd	$T2b,$N2,$nb,$T2b
-+	 lfd	$A2,24($nap_d)		; load a[j+1] in double format
-+	 lfd	$A3,32($nap_d)
-+	fmadd	$T3a,$N3,$na,$T3a
-+	fmadd	$T3b,$N3,$nb,$T3b
-+	fmadd	$T0a,$N0,$na,$T0a
-+	fmadd	$T0b,$N0,$nb,$T0b
-+
-+	fmadd	$T1a,$N0,$nc,$T1a
-+	fmadd	$T1b,$N0,$nd,$T1b
-+	fmadd	$T2a,$N1,$nc,$T2a
-+	fmadd	$T2b,$N1,$nd,$T2b
-+	fmadd	$T3a,$N2,$nc,$T3a
-+	fmadd	$T3b,$N2,$nd,$T3b
-+	fmadd	$dota,$N3,$nc,$dota
-+	fmadd	$dotb,$N3,$nd,$dotb
-+
-+	fctid	$T0a,$T0a
-+	fctid	$T0b,$T0b
-+	fctid	$T1a,$T1a
-+	fctid	$T1b,$T1b
-+	fctid	$T2a,$T2a
-+	fctid	$T2b,$T2b
-+	fctid	$T3a,$T3a
-+	fctid	$T3b,$T3b
-+
-+	stfd	$T0a,`$FRAME+0`($sp)
-+	stfd	$T0b,`$FRAME+8`($sp)
-+	stfd	$T1a,`$FRAME+16`($sp)
-+	stfd	$T1b,`$FRAME+24`($sp)
-+	stfd	$T2a,`$FRAME+32`($sp)
-+	stfd	$T2b,`$FRAME+40`($sp)
-+	stfd	$T3a,`$FRAME+48`($sp)
-+	stfd	$T3b,`$FRAME+56`($sp)
-+
-+.align	5
-+Linner:
-+	fmul	$T1a,$A1,$ba
-+	fmul	$T1b,$A1,$bb
-+	fmul	$T2a,$A2,$ba
-+	fmul	$T2b,$A2,$bb
-+	lfd	$N0,40($nap_d)		; load n[j] in double format
-+	lfd	$N1,48($nap_d)
-+	fmul	$T3a,$A3,$ba
-+	fmul	$T3b,$A3,$bb
-+	fmadd	$T0a,$A0,$ba,$dota
-+	fmadd	$T0b,$A0,$bb,$dotb
-+	lfd	$N2,56($nap_d)		; load n[j+1] in double format
-+	lfdu	$N3,64($nap_d)
-+
-+	fmadd	$T1a,$A0,$bc,$T1a
-+	fmadd	$T1b,$A0,$bd,$T1b
-+	fmadd	$T2a,$A1,$bc,$T2a
-+	fmadd	$T2b,$A1,$bd,$T2b
-+	 lfd	$A0,8($nap_d)		; load a[j] in double format
-+	 lfd	$A1,16($nap_d)
-+	fmadd	$T3a,$A2,$bc,$T3a
-+	fmadd	$T3b,$A2,$bd,$T3b
-+	fmul	$dota,$A3,$bc
-+	fmul	$dotb,$A3,$bd
-+	 lfd	$A2,24($nap_d)		; load a[j+1] in double format
-+	 lfd	$A3,32($nap_d)
-+___
-+if ($SIZE_T==8 or $flavour =~ /osx/) {
-+$code.=<<___;
-+	fmadd	$T1a,$N1,$na,$T1a
-+	fmadd	$T1b,$N1,$nb,$T1b
-+	 ld	$t0,`$FRAME+0`($sp)
-+	 ld	$t1,`$FRAME+8`($sp)
-+	fmadd	$T2a,$N2,$na,$T2a
-+	fmadd	$T2b,$N2,$nb,$T2b
-+	 ld	$t2,`$FRAME+16`($sp)
-+	 ld	$t3,`$FRAME+24`($sp)
-+	fmadd	$T3a,$N3,$na,$T3a
-+	fmadd	$T3b,$N3,$nb,$T3b
-+	 add	$t0,$t0,$carry		; can not overflow
-+	 ld	$t4,`$FRAME+32`($sp)
-+	 ld	$t5,`$FRAME+40`($sp)
-+	fmadd	$T0a,$N0,$na,$T0a
-+	fmadd	$T0b,$N0,$nb,$T0b
-+	 srdi	$carry,$t0,16
-+	 add	$t1,$t1,$carry
-+	 srdi	$carry,$t1,16
-+	 ld	$t6,`$FRAME+48`($sp)
-+	 ld	$t7,`$FRAME+56`($sp)
-+
-+	fmadd	$T1a,$N0,$nc,$T1a
-+	fmadd	$T1b,$N0,$nd,$T1b
-+	 insrdi	$t0,$t1,16,32
-+	 ld	$t1,8($tp)		; tp[j]
-+	fmadd	$T2a,$N1,$nc,$T2a
-+	fmadd	$T2b,$N1,$nd,$T2b
-+	 add	$t2,$t2,$carry
-+	fmadd	$T3a,$N2,$nc,$T3a
-+	fmadd	$T3b,$N2,$nd,$T3b
-+	 srdi	$carry,$t2,16
-+	 insrdi	$t0,$t2,16,16
-+	fmadd	$dota,$N3,$nc,$dota
-+	fmadd	$dotb,$N3,$nd,$dotb
-+	 add	$t3,$t3,$carry
-+	 ldu	$t2,16($tp)		; tp[j+1]
-+	 srdi	$carry,$t3,16
-+	 insrdi	$t0,$t3,16,0		; 0..63 bits
-+	 add	$t4,$t4,$carry
-+
-+	fctid	$T0a,$T0a
-+	fctid	$T0b,$T0b
-+	 srdi	$carry,$t4,16
-+	fctid	$T1a,$T1a
-+	fctid	$T1b,$T1b
-+	 add	$t5,$t5,$carry
-+	fctid	$T2a,$T2a
-+	fctid	$T2b,$T2b
-+	 srdi	$carry,$t5,16
-+	 insrdi	$t4,$t5,16,32
-+	fctid	$T3a,$T3a
-+	fctid	$T3b,$T3b
-+	 add	$t6,$t6,$carry
-+	 srdi	$carry,$t6,16
-+	 insrdi	$t4,$t6,16,16
-+
-+	stfd	$T0a,`$FRAME+0`($sp)
-+	stfd	$T0b,`$FRAME+8`($sp)
-+	 add	$t7,$t7,$carry
-+	 addc	$t3,$t0,$t1
-+___
-+$code.=<<___ if ($SIZE_T==4);		# adjust XER[CA]
-+	extrdi	$t0,$t0,32,0
-+	extrdi	$t1,$t1,32,0
-+	adde	$t0,$t0,$t1
-+___
-+$code.=<<___;
-+	stfd	$T1a,`$FRAME+16`($sp)
-+	stfd	$T1b,`$FRAME+24`($sp)
-+	 insrdi	$t4,$t7,16,0		; 64..127 bits
-+	 srdi	$carry,$t7,16		; upper 33 bits
-+	stfd	$T2a,`$FRAME+32`($sp)
-+	stfd	$T2b,`$FRAME+40`($sp)
-+	 adde	$t5,$t4,$t2
-+___
-+$code.=<<___ if ($SIZE_T==4);		# adjust XER[CA]
-+	extrdi	$t4,$t4,32,0
-+	extrdi	$t2,$t2,32,0
-+	adde	$t4,$t4,$t2
-+___
-+$code.=<<___;
-+	stfd	$T3a,`$FRAME+48`($sp)
-+	stfd	$T3b,`$FRAME+56`($sp)
-+	 addze	$carry,$carry
-+	 std	$t3,-16($tp)		; tp[j-1]
-+	 std	$t5,-8($tp)		; tp[j]
-+___
-+} else {
-+$code.=<<___;
-+	fmadd	$T1a,$N1,$na,$T1a
-+	fmadd	$T1b,$N1,$nb,$T1b
-+	 lwz	$t1,`$FRAME+0^$LITTLE_ENDIAN`($sp)
-+	 lwz	$t0,`$FRAME+4^$LITTLE_ENDIAN`($sp)
-+	fmadd	$T2a,$N2,$na,$T2a
-+	fmadd	$T2b,$N2,$nb,$T2b
-+	 lwz	$t3,`$FRAME+8^$LITTLE_ENDIAN`($sp)
-+	 lwz	$t2,`$FRAME+12^$LITTLE_ENDIAN`($sp)
-+	fmadd	$T3a,$N3,$na,$T3a
-+	fmadd	$T3b,$N3,$nb,$T3b
-+	 lwz	$t5,`$FRAME+16^$LITTLE_ENDIAN`($sp)
-+	 lwz	$t4,`$FRAME+20^$LITTLE_ENDIAN`($sp)
-+	 addc	$t0,$t0,$carry
-+	 adde	$t1,$t1,$c1
-+	 srwi	$carry,$t0,16
-+	fmadd	$T0a,$N0,$na,$T0a
-+	fmadd	$T0b,$N0,$nb,$T0b
-+	 lwz	$t7,`$FRAME+24^$LITTLE_ENDIAN`($sp)
-+	 lwz	$t6,`$FRAME+28^$LITTLE_ENDIAN`($sp)
-+	 srwi	$c1,$t1,16
-+	 insrwi	$carry,$t1,16,0
-+
-+	fmadd	$T1a,$N0,$nc,$T1a
-+	fmadd	$T1b,$N0,$nd,$T1b
-+	 addc	$t2,$t2,$carry
-+	 adde	$t3,$t3,$c1
-+	 srwi	$carry,$t2,16
-+	fmadd	$T2a,$N1,$nc,$T2a
-+	fmadd	$T2b,$N1,$nd,$T2b
-+	 insrwi	$t0,$t2,16,0		; 0..31 bits
-+	 srwi	$c1,$t3,16
-+	 insrwi	$carry,$t3,16,0
-+	fmadd	$T3a,$N2,$nc,$T3a
-+	fmadd	$T3b,$N2,$nd,$T3b
-+	 lwz	$t2,12($tp)		; tp[j]
-+	 lwz	$t3,8($tp)
-+	 addc	$t4,$t4,$carry
-+	 adde	$t5,$t5,$c1
-+	 srwi	$carry,$t4,16
-+	fmadd	$dota,$N3,$nc,$dota
-+	fmadd	$dotb,$N3,$nd,$dotb
-+	 srwi	$c1,$t5,16
-+	 insrwi	$carry,$t5,16,0
-+
-+	fctid	$T0a,$T0a
-+	 addc	$t6,$t6,$carry
-+	 adde	$t7,$t7,$c1
-+	 srwi	$carry,$t6,16
-+	fctid	$T0b,$T0b
-+	 insrwi	$t4,$t6,16,0		; 32..63 bits
-+	 srwi	$c1,$t7,16
-+	 insrwi	$carry,$t7,16,0
-+	fctid	$T1a,$T1a
-+	 addc	$t0,$t0,$t2
-+	 adde	$t4,$t4,$t3
-+	 lwz	$t3,`$FRAME+32^$LITTLE_ENDIAN`($sp)	; permuted $t1
-+	 lwz	$t2,`$FRAME+36^$LITTLE_ENDIAN`($sp)	; permuted $t0
-+	fctid	$T1b,$T1b
-+	 addze	$carry,$carry
-+	 addze	$c1,$c1
-+	 stw	$t0,4($tp)		; tp[j-1]
-+	 stw	$t4,0($tp)
-+	fctid	$T2a,$T2a
-+	 addc	$t2,$t2,$carry
-+	 adde	$t3,$t3,$c1
-+	 srwi	$carry,$t2,16
-+	 lwz	$t7,`$FRAME+40^$LITTLE_ENDIAN`($sp)	; permuted $t3
-+	 lwz	$t6,`$FRAME+44^$LITTLE_ENDIAN`($sp)	; permuted $t2
-+	fctid	$T2b,$T2b
-+	 srwi	$c1,$t3,16
-+	 insrwi	$carry,$t3,16,0
-+	 lwz	$t1,`$FRAME+48^$LITTLE_ENDIAN`($sp)	; permuted $t5
-+	 lwz	$t0,`$FRAME+52^$LITTLE_ENDIAN`($sp)	; permuted $t4
-+	fctid	$T3a,$T3a
-+	 addc	$t6,$t6,$carry
-+	 adde	$t7,$t7,$c1
-+	 srwi	$carry,$t6,16
-+	 lwz	$t5,`$FRAME+56^$LITTLE_ENDIAN`($sp)	; permuted $t7
-+	 lwz	$t4,`$FRAME+60^$LITTLE_ENDIAN`($sp)	; permuted $t6
-+	fctid	$T3b,$T3b
-+
-+	 insrwi	$t2,$t6,16,0		; 64..95 bits
-+	insrwi	$carry,$t7,16,0
-+	srwi	$c1,$t7,16
-+	 lwz	$t6,20($tp)
-+	 lwzu	$t7,16($tp)
-+	addc	$t0,$t0,$carry
-+	 stfd	$T0a,`$FRAME+0`($sp)
-+	adde	$t1,$t1,$c1
-+	srwi	$carry,$t0,16
-+	 stfd	$T0b,`$FRAME+8`($sp)
-+	insrwi	$carry,$t1,16,0
-+	srwi	$c1,$t1,16
-+	addc	$t4,$t4,$carry
-+	 stfd	$T1a,`$FRAME+16`($sp)
-+	adde	$t5,$t5,$c1
-+	srwi	$carry,$t4,16
-+	 insrwi	$t0,$t4,16,0		; 96..127 bits
-+	 stfd	$T1b,`$FRAME+24`($sp)
-+	insrwi	$carry,$t5,16,0
-+	srwi	$c1,$t5,16
-+
-+	addc	$t2,$t2,$t6
-+	 stfd	$T2a,`$FRAME+32`($sp)
-+	adde	$t0,$t0,$t7
-+	 stfd	$T2b,`$FRAME+40`($sp)
-+	addze	$carry,$carry
-+	 stfd	$T3a,`$FRAME+48`($sp)
-+	addze	$c1,$c1
-+	 stfd	$T3b,`$FRAME+56`($sp)
-+	 stw	$t2,-4($tp)		; tp[j]
-+	 stw	$t0,-8($tp)
-+___
-+}
-+$code.=<<___;
-+	bdnz	Linner
-+
-+	fctid	$dota,$dota
-+	fctid	$dotb,$dotb
-+___
-+if ($SIZE_T==8 or $flavour =~ /osx/) {
-+$code.=<<___;
-+	ld	$t0,`$FRAME+0`($sp)
-+	ld	$t1,`$FRAME+8`($sp)
-+	ld	$t2,`$FRAME+16`($sp)
-+	ld	$t3,`$FRAME+24`($sp)
-+	ld	$t4,`$FRAME+32`($sp)
-+	ld	$t5,`$FRAME+40`($sp)
-+	ld	$t6,`$FRAME+48`($sp)
-+	ld	$t7,`$FRAME+56`($sp)
-+	stfd	$dota,`$FRAME+64`($sp)
-+	stfd	$dotb,`$FRAME+72`($sp)
-+
-+	add	$t0,$t0,$carry		; can not overflow
-+	srdi	$carry,$t0,16
-+	add	$t1,$t1,$carry
-+	srdi	$carry,$t1,16
-+	insrdi	$t0,$t1,16,32
-+	add	$t2,$t2,$carry
-+	ld	$t1,8($tp)		; tp[j]
-+	srdi	$carry,$t2,16
-+	insrdi	$t0,$t2,16,16
-+	add	$t3,$t3,$carry
-+	ldu	$t2,16($tp)		; tp[j+1]
-+	srdi	$carry,$t3,16
-+	insrdi	$t0,$t3,16,0		; 0..63 bits
-+	add	$t4,$t4,$carry
-+	srdi	$carry,$t4,16
-+	add	$t5,$t5,$carry
-+	srdi	$carry,$t5,16
-+	insrdi	$t4,$t5,16,32
-+	add	$t6,$t6,$carry
-+	srdi	$carry,$t6,16
-+	insrdi	$t4,$t6,16,16
-+	add	$t7,$t7,$carry
-+	insrdi	$t4,$t7,16,0		; 64..127 bits
-+	srdi	$carry,$t7,16		; upper 33 bits
-+	ld	$t6,`$FRAME+64`($sp)
-+	ld	$t7,`$FRAME+72`($sp)
-+
-+	addc	$t3,$t0,$t1
-+___
-+$code.=<<___ if ($SIZE_T==4);		# adjust XER[CA]
-+	extrdi	$t0,$t0,32,0
-+	extrdi	$t1,$t1,32,0
-+	adde	$t0,$t0,$t1
-+___
-+$code.=<<___;
-+	adde	$t5,$t4,$t2
-+___
-+$code.=<<___ if ($SIZE_T==4);		# adjust XER[CA]
-+	extrdi	$t4,$t4,32,0
-+	extrdi	$t2,$t2,32,0
-+	adde	$t4,$t4,$t2
-+___
-+$code.=<<___;
-+	addze	$carry,$carry
-+
-+	std	$t3,-16($tp)		; tp[j-1]
-+	std	$t5,-8($tp)		; tp[j]
-+
-+	add	$carry,$carry,$ovf	; comsume upmost overflow
-+	add	$t6,$t6,$carry		; can not overflow
-+	srdi	$carry,$t6,16
-+	add	$t7,$t7,$carry
-+	insrdi	$t6,$t7,48,0
-+	srdi	$ovf,$t7,48
-+	std	$t6,0($tp)		; tp[num-1]
-+___
-+} else {
-+$code.=<<___;
-+	lwz	$t1,`$FRAME+0^$LITTLE_ENDIAN`($sp)
-+	lwz	$t0,`$FRAME+4^$LITTLE_ENDIAN`($sp)
-+	lwz	$t3,`$FRAME+8^$LITTLE_ENDIAN`($sp)
-+	lwz	$t2,`$FRAME+12^$LITTLE_ENDIAN`($sp)
-+	lwz	$t5,`$FRAME+16^$LITTLE_ENDIAN`($sp)
-+	lwz	$t4,`$FRAME+20^$LITTLE_ENDIAN`($sp)
-+	lwz	$t7,`$FRAME+24^$LITTLE_ENDIAN`($sp)
-+	lwz	$t6,`$FRAME+28^$LITTLE_ENDIAN`($sp)
-+	stfd	$dota,`$FRAME+64`($sp)
-+	stfd	$dotb,`$FRAME+72`($sp)
-+
-+	addc	$t0,$t0,$carry
-+	adde	$t1,$t1,$c1
-+	srwi	$carry,$t0,16
-+	insrwi	$carry,$t1,16,0
-+	srwi	$c1,$t1,16
-+	addc	$t2,$t2,$carry
-+	adde	$t3,$t3,$c1
-+	srwi	$carry,$t2,16
-+	 insrwi	$t0,$t2,16,0		; 0..31 bits
-+	 lwz	$t2,12($tp)		; tp[j]
-+	insrwi	$carry,$t3,16,0
-+	srwi	$c1,$t3,16
-+	 lwz	$t3,8($tp)
-+	addc	$t4,$t4,$carry
-+	adde	$t5,$t5,$c1
-+	srwi	$carry,$t4,16
-+	insrwi	$carry,$t5,16,0
-+	srwi	$c1,$t5,16
-+	addc	$t6,$t6,$carry
-+	adde	$t7,$t7,$c1
-+	srwi	$carry,$t6,16
-+	 insrwi	$t4,$t6,16,0		; 32..63 bits
-+	insrwi	$carry,$t7,16,0
-+	srwi	$c1,$t7,16
-+
-+	addc	$t0,$t0,$t2
-+	adde	$t4,$t4,$t3
-+	addze	$carry,$carry
-+	addze	$c1,$c1
-+	 stw	$t0,4($tp)		; tp[j-1]
-+	 stw	$t4,0($tp)
-+
-+	lwz	$t3,`$FRAME+32^$LITTLE_ENDIAN`($sp)	; permuted $t1
-+	lwz	$t2,`$FRAME+36^$LITTLE_ENDIAN`($sp)	; permuted $t0
-+	lwz	$t7,`$FRAME+40^$LITTLE_ENDIAN`($sp)	; permuted $t3
-+	lwz	$t6,`$FRAME+44^$LITTLE_ENDIAN`($sp)	; permuted $t2
-+	lwz	$t1,`$FRAME+48^$LITTLE_ENDIAN`($sp)	; permuted $t5
-+	lwz	$t0,`$FRAME+52^$LITTLE_ENDIAN`($sp)	; permuted $t4
-+	lwz	$t5,`$FRAME+56^$LITTLE_ENDIAN`($sp)	; permuted $t7
-+	lwz	$t4,`$FRAME+60^$LITTLE_ENDIAN`($sp)	; permuted $t6
-+
-+	addc	$t2,$t2,$carry
-+	adde	$t3,$t3,$c1
-+	srwi	$carry,$t2,16
-+	insrwi	$carry,$t3,16,0
-+	srwi	$c1,$t3,16
-+	addc	$t6,$t6,$carry
-+	adde	$t7,$t7,$c1
-+	srwi	$carry,$t6,16
-+	 insrwi	$t2,$t6,16,0		; 64..95 bits
-+	 lwz	$t6,20($tp)
-+	insrwi	$carry,$t7,16,0
-+	srwi	$c1,$t7,16
-+	 lwzu	$t7,16($tp)
-+	addc	$t0,$t0,$carry
-+	adde	$t1,$t1,$c1
-+	srwi	$carry,$t0,16
-+	insrwi	$carry,$t1,16,0
-+	srwi	$c1,$t1,16
-+	addc	$t4,$t4,$carry
-+	adde	$t5,$t5,$c1
-+	srwi	$carry,$t4,16
-+	 insrwi	$t0,$t4,16,0		; 96..127 bits
-+	insrwi	$carry,$t5,16,0
-+	srwi	$c1,$t5,16
-+
-+	addc	$t2,$t2,$t6
-+	adde	$t0,$t0,$t7
-+	 lwz	$t7,`$FRAME+64^$LITTLE_ENDIAN`($sp)
-+	 lwz	$t6,`$FRAME+68^$LITTLE_ENDIAN`($sp)
-+	addze	$carry,$carry
-+	addze	$c1,$c1
-+	 lwz	$t5,`$FRAME+72^$LITTLE_ENDIAN`($sp)
-+	 lwz	$t4,`$FRAME+76^$LITTLE_ENDIAN`($sp)
-+
-+	addc	$t6,$t6,$carry
-+	adde	$t7,$t7,$c1
-+	 stw	$t2,-4($tp)		; tp[j]
-+	 stw	$t0,-8($tp)
-+	addc	$t6,$t6,$ovf
-+	addze	$t7,$t7
-+	srwi	$carry,$t6,16
-+	insrwi	$carry,$t7,16,0
-+	srwi	$c1,$t7,16
-+	addc	$t4,$t4,$carry
-+	adde	$t5,$t5,$c1
-+
-+	insrwi	$t6,$t4,16,0
-+	srwi	$t4,$t4,16
-+	insrwi	$t4,$t5,16,0
-+	srwi	$ovf,$t5,16
-+	stw	$t6,4($tp)		; tp[num-1]
-+	stw	$t4,0($tp)
-+___
-+}
-+$code.=<<___;
-+	slwi	$t7,$num,2
-+	addi	$i,$i,8
-+	subf	$nap_d,$t7,$nap_d	; rewind pointer
-+	cmpw	$i,$num
-+	blt-	Louter
-+___
-+
-+$code.=<<___ if ($SIZE_T==8);
-+	subf	$np,$num,$np	; rewind np
-+	addi	$j,$j,1		; restore counter
-+	subfc	$i,$i,$i	; j=0 and "clear" XER[CA]
-+	addi	$tp,$sp,`$FRAME+$TRANSFER+8`
-+	addi	$t4,$sp,`$FRAME+$TRANSFER+16`
-+	addi	$t5,$np,8
-+	addi	$t6,$rp,8
-+	mtctr	$j
-+
-+.align	4
-+Lsub:	ldx	$t0,$tp,$i
-+	ldx	$t1,$np,$i
-+	ldx	$t2,$t4,$i
-+	ldx	$t3,$t5,$i
-+	subfe	$t0,$t1,$t0	; tp[j]-np[j]
-+	subfe	$t2,$t3,$t2	; tp[j+1]-np[j+1]
-+	stdx	$t0,$rp,$i
-+	stdx	$t2,$t6,$i
-+	addi	$i,$i,16
-+	bdnz	Lsub
-+
-+	li	$i,0
-+	subfe	$ovf,$i,$ovf	; handle upmost overflow bit
-+	and	$ap,$tp,$ovf
-+	andc	$np,$rp,$ovf
-+	or	$ap,$ap,$np	; ap=borrow?tp:rp
-+	addi	$t7,$ap,8
-+	mtctr	$j
-+
-+.align	4
-+Lcopy:				; copy or in-place refresh
-+	ldx	$t0,$ap,$i
-+	ldx	$t1,$t7,$i
-+	std	$i,8($nap_d)	; zap nap_d
-+	std	$i,16($nap_d)
-+	std	$i,24($nap_d)
-+	std	$i,32($nap_d)
-+	std	$i,40($nap_d)
-+	std	$i,48($nap_d)
-+	std	$i,56($nap_d)
-+	stdu	$i,64($nap_d)
-+	stdx	$t0,$rp,$i
-+	stdx	$t1,$t6,$i
-+	stdx	$i,$tp,$i	; zap tp at once
-+	stdx	$i,$t4,$i
-+	addi	$i,$i,16
-+	bdnz	Lcopy
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	subf	$np,$num,$np	; rewind np
-+	addi	$j,$j,1		; restore counter
-+	subfc	$i,$i,$i	; j=0 and "clear" XER[CA]
-+	addi	$tp,$sp,`$FRAME+$TRANSFER`
-+	addi	$np,$np,-4
-+	addi	$rp,$rp,-4
-+	addi	$ap,$sp,`$FRAME+$TRANSFER+4`
-+	mtctr	$j
-+
-+.align	4
-+Lsub:	lwz	$t0,12($tp)	; load tp[j..j+3] in 64-bit word order
-+	lwz	$t1,8($tp)
-+	lwz	$t2,20($tp)
-+	lwzu	$t3,16($tp)
-+	lwz	$t4,4($np)	; load np[j..j+3] in 32-bit word order
-+	lwz	$t5,8($np)
-+	lwz	$t6,12($np)
-+	lwzu	$t7,16($np)
-+	subfe	$t4,$t4,$t0	; tp[j]-np[j]
-+	 stw	$t0,4($ap)	; save tp[j..j+3] in 32-bit word order
-+	subfe	$t5,$t5,$t1	; tp[j+1]-np[j+1]
-+	 stw	$t1,8($ap)
-+	subfe	$t6,$t6,$t2	; tp[j+2]-np[j+2]
-+	 stw	$t2,12($ap)
-+	subfe	$t7,$t7,$t3	; tp[j+3]-np[j+3]
-+	 stwu	$t3,16($ap)
-+	stw	$t4,4($rp)
-+	stw	$t5,8($rp)
-+	stw	$t6,12($rp)
-+	stwu	$t7,16($rp)
-+	bdnz	Lsub
-+
-+	li	$i,0
-+	subfe	$ovf,$i,$ovf	; handle upmost overflow bit
-+	addi	$tp,$sp,`$FRAME+$TRANSFER+4`
-+	subf	$rp,$num,$rp	; rewind rp
-+	and	$ap,$tp,$ovf
-+	andc	$np,$rp,$ovf
-+	or	$ap,$ap,$np	; ap=borrow?tp:rp
-+	addi	$tp,$sp,`$FRAME+$TRANSFER`
-+	mtctr	$j
-+
-+.align	4
-+Lcopy:				; copy or in-place refresh
-+	lwz	$t0,4($ap)
-+	lwz	$t1,8($ap)
-+	lwz	$t2,12($ap)
-+	lwzu	$t3,16($ap)
-+	std	$i,8($nap_d)	; zap nap_d
-+	std	$i,16($nap_d)
-+	std	$i,24($nap_d)
-+	std	$i,32($nap_d)
-+	std	$i,40($nap_d)
-+	std	$i,48($nap_d)
-+	std	$i,56($nap_d)
-+	stdu	$i,64($nap_d)
-+	stw	$t0,4($rp)
-+	stw	$t1,8($rp)
-+	stw	$t2,12($rp)
-+	stwu	$t3,16($rp)
-+	std	$i,8($tp)	; zap tp at once
-+	stdu	$i,16($tp)
-+	bdnz	Lcopy
-+___
-+
-+$code.=<<___;
-+	$POP	$i,0($sp)
-+	li	r3,1	; signal "handled"
-+	$POP	r19,`-12*8-13*$SIZE_T`($i)
-+	$POP	r20,`-12*8-12*$SIZE_T`($i)
-+	$POP	r21,`-12*8-11*$SIZE_T`($i)
-+	$POP	r22,`-12*8-10*$SIZE_T`($i)
-+	$POP	r23,`-12*8-9*$SIZE_T`($i)
-+	$POP	r24,`-12*8-8*$SIZE_T`($i)
-+	$POP	r25,`-12*8-7*$SIZE_T`($i)
-+	$POP	r26,`-12*8-6*$SIZE_T`($i)
-+	$POP	r27,`-12*8-5*$SIZE_T`($i)
-+	$POP	r28,`-12*8-4*$SIZE_T`($i)
-+	$POP	r29,`-12*8-3*$SIZE_T`($i)
-+	$POP	r30,`-12*8-2*$SIZE_T`($i)
-+	$POP	r31,`-12*8-1*$SIZE_T`($i)
-+	lfd	f20,`-12*8`($i)
-+	lfd	f21,`-11*8`($i)
-+	lfd	f22,`-10*8`($i)
-+	lfd	f23,`-9*8`($i)
-+	lfd	f24,`-8*8`($i)
-+	lfd	f25,`-7*8`($i)
-+	lfd	f26,`-6*8`($i)
-+	lfd	f27,`-5*8`($i)
-+	lfd	f28,`-4*8`($i)
-+	lfd	f29,`-3*8`($i)
-+	lfd	f30,`-2*8`($i)
-+	lfd	f31,`-1*8`($i)
-+	mr	$sp,$i
-+	blr
-+	.long	0
-+	.byte	0,12,4,0,0x8c,13,6,0
-+	.long	0
-+.size	.$fname,.-.$fname
-+
-+.asciz  "Montgomery Multiplication for PPC64, CRYPTOGAMS by "
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/rsaz-avx2.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/rsaz-avx2.pl
-new file mode 100755
-index 0000000..0c1b236
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/rsaz-avx2.pl
-@@ -0,0 +1,1968 @@
-+#! /usr/bin/env perl
-+# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+##############################################################################
-+#                                                                            #
-+#  Copyright (c) 2012, Intel Corporation                                     #
-+#                                                                            #
-+#  All rights reserved.                                                      #
-+#                                                                            #
-+#  Redistribution and use in source and binary forms, with or without        #
-+#  modification, are permitted provided that the following conditions are    #
-+#  met:                                                                      #
-+#                                                                            #
-+#  *  Redistributions of source code must retain the above copyright         #
-+#     notice, this list of conditions and the following disclaimer.          #
-+#                                                                            #
-+#  *  Redistributions in binary form must reproduce the above copyright      #
-+#     notice, this list of conditions and the following disclaimer in the    #
-+#     documentation and/or other materials provided with the                 #
-+#     distribution.                                                          #
-+#                                                                            #
-+#  *  Neither the name of the Intel Corporation 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 INTEL CORPORATION ""AS IS"" AND ANY          #
-+#  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE         #
-+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        #
-+#  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR            #
-+#  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
-+#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       #
-+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        #
-+#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    #
-+#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      #
-+#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        #
-+#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              #
-+#                                                                            #
-+##############################################################################
-+# Developers and authors:                                                    #
-+# Shay Gueron (1, 2), and Vlad Krasnov (1)                                   #
-+# (1) Intel Corporation, Israel Development Center, Haifa, Israel            #
-+# (2) University of Haifa, Israel                                            #
-+##############################################################################
-+# Reference:                                                                 #
-+# [1] S. Gueron, V. Krasnov: "Software Implementation of Modular             #
-+#     Exponentiation,  Using Advanced Vector Instructions Architectures",    #
-+#     F. Ozbudak and F. Rodriguez-Henriquez (Eds.): WAIFI 2012, LNCS 7369,   #
-+#     pp. 119?135, 2012. Springer-Verlag Berlin Heidelberg 2012              #
-+# [2] S. Gueron: "Efficient Software Implementations of Modular              #
-+#     Exponentiation", Journal of Cryptographic Engineering 2:31-43 (2012).  #
-+# [3] S. Gueron, V. Krasnov: "Speeding up Big-numbers Squaring",IEEE         #
-+#     Proceedings of 9th International Conference on Information Technology: #
-+#     New Generations (ITNG 2012), pp.821-823 (2012)                         #
-+# [4] S. Gueron, V. Krasnov: "[PATCH] Efficient and side channel analysis    #
-+#     resistant 1024-bit modular exponentiation, for optimizing RSA2048      #
-+#     on AVX2 capable x86_64 platforms",                                     #
-+#     http://rt.openssl.org/Ticket/Display.html?id=2850&user=guest&pass=guest#
-+##############################################################################
-+#
-+# +13% improvement over original submission by 
-+#
-+# rsa2048 sign/sec	OpenSSL 1.0.1	scalar(*)	this
-+# 2.3GHz Haswell	621		765/+23%	1113/+79%
-+# 2.3GHz Broadwell(**)	688		1200(***)/+74%	1120/+63%
-+#
-+# (*)	if system doesn't support AVX2, for reference purposes;
-+# (**)	scaled to 2.3GHz to simplify comparison;
-+# (***)	scalar AD*X code is faster than AVX2 and is preferred code
-+#	path for Broadwell;
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+	$addx = ($1>=2.23);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	    `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+	$addx = ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	    `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+	$addx = ($1>=11);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
-+	my $ver = $2 + $3/100.0;	# 3.1->3.01, 3.10->3.10
-+	$avx = ($ver>=3.0) + ($ver>=3.01);
-+	$addx = ($ver>=3.03);
-+}
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT = *OUT;
-+
-+if ($avx>1) {{{
-+{ # void AMS_WW(
-+my $rp="%rdi";	# BN_ULONG *rp,
-+my $ap="%rsi";	# const BN_ULONG *ap,
-+my $np="%rdx";	# const BN_ULONG *np,
-+my $n0="%ecx";	# const BN_ULONG n0,
-+my $rep="%r8d";	# int repeat);
-+
-+# The registers that hold the accumulated redundant result
-+# The AMM works on 1024 bit operands, and redundant word size is 29
-+# Therefore: ceil(1024/29)/4 = 9
-+my $ACC0="%ymm0";
-+my $ACC1="%ymm1";
-+my $ACC2="%ymm2";
-+my $ACC3="%ymm3";
-+my $ACC4="%ymm4";
-+my $ACC5="%ymm5";
-+my $ACC6="%ymm6";
-+my $ACC7="%ymm7";
-+my $ACC8="%ymm8";
-+my $ACC9="%ymm9";
-+# Registers that hold the broadcasted words of bp, currently used
-+my $B1="%ymm10";
-+my $B2="%ymm11";
-+# Registers that hold the broadcasted words of Y, currently used
-+my $Y1="%ymm12";
-+my $Y2="%ymm13";
-+# Helper registers
-+my $TEMP1="%ymm14";
-+my $AND_MASK="%ymm15";
-+# alu registers that hold the first words of the ACC
-+my $r0="%r9";
-+my $r1="%r10";
-+my $r2="%r11";
-+my $r3="%r12";
-+
-+my $i="%r14d";			# loop counter
-+my $tmp = "%r15";
-+
-+my $FrameSize=32*18+32*8;	# place for A^2 and 2*A
-+
-+my $aap=$r0;
-+my $tp0="%rbx";
-+my $tp1=$r3;
-+my $tpa=$tmp;
-+
-+$np="%r13";			# reassigned argument
-+
-+$code.=<<___;
-+.text
-+
-+.globl	rsaz_1024_sqr_avx2
-+.type	rsaz_1024_sqr_avx2,\@function,5
-+.align	64
-+rsaz_1024_sqr_avx2:		# 702 cycles, 14% faster than rsaz_1024_mul_avx2
-+	lea	(%rsp), %rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	vmovaps	%xmm6,-0xd8(%rax)
-+	vmovaps	%xmm7,-0xc8(%rax)
-+	vmovaps	%xmm8,-0xb8(%rax)
-+	vmovaps	%xmm9,-0xa8(%rax)
-+	vmovaps	%xmm10,-0x98(%rax)
-+	vmovaps	%xmm11,-0x88(%rax)
-+	vmovaps	%xmm12,-0x78(%rax)
-+	vmovaps	%xmm13,-0x68(%rax)
-+	vmovaps	%xmm14,-0x58(%rax)
-+	vmovaps	%xmm15,-0x48(%rax)
-+.Lsqr_1024_body:
-+___
-+$code.=<<___;
-+	mov	%rax,%rbp
-+	mov	%rdx, $np			# reassigned argument
-+	sub	\$$FrameSize, %rsp
-+	mov	$np, $tmp
-+	sub	\$-128, $rp			# size optimization
-+	sub	\$-128, $ap
-+	sub	\$-128, $np
-+
-+	and	\$4095, $tmp			# see if $np crosses page
-+	add	\$32*10, $tmp
-+	shr	\$12, $tmp
-+	vpxor	$ACC9,$ACC9,$ACC9
-+	jz	.Lsqr_1024_no_n_copy
-+
-+	# unaligned 256-bit load that crosses page boundary can
-+	# cause >2x performance degradation here, so if $np does
-+	# cross page boundary, copy it to stack and make sure stack
-+	# frame doesn't...
-+	sub		\$32*10,%rsp
-+	vmovdqu		32*0-128($np), $ACC0
-+	and		\$-2048, %rsp
-+	vmovdqu		32*1-128($np), $ACC1
-+	vmovdqu		32*2-128($np), $ACC2
-+	vmovdqu		32*3-128($np), $ACC3
-+	vmovdqu		32*4-128($np), $ACC4
-+	vmovdqu		32*5-128($np), $ACC5
-+	vmovdqu		32*6-128($np), $ACC6
-+	vmovdqu		32*7-128($np), $ACC7
-+	vmovdqu		32*8-128($np), $ACC8
-+	lea		$FrameSize+128(%rsp),$np
-+	vmovdqu		$ACC0, 32*0-128($np)
-+	vmovdqu		$ACC1, 32*1-128($np)
-+	vmovdqu		$ACC2, 32*2-128($np)
-+	vmovdqu		$ACC3, 32*3-128($np)
-+	vmovdqu		$ACC4, 32*4-128($np)
-+	vmovdqu		$ACC5, 32*5-128($np)
-+	vmovdqu		$ACC6, 32*6-128($np)
-+	vmovdqu		$ACC7, 32*7-128($np)
-+	vmovdqu		$ACC8, 32*8-128($np)
-+	vmovdqu		$ACC9, 32*9-128($np)	# $ACC9 is zero
-+
-+.Lsqr_1024_no_n_copy:
-+	and		\$-1024, %rsp
-+
-+	vmovdqu		32*1-128($ap), $ACC1
-+	vmovdqu		32*2-128($ap), $ACC2
-+	vmovdqu		32*3-128($ap), $ACC3
-+	vmovdqu		32*4-128($ap), $ACC4
-+	vmovdqu		32*5-128($ap), $ACC5
-+	vmovdqu		32*6-128($ap), $ACC6
-+	vmovdqu		32*7-128($ap), $ACC7
-+	vmovdqu		32*8-128($ap), $ACC8
-+
-+	lea	192(%rsp), $tp0			# 64+128=192
-+	vpbroadcastq	.Land_mask(%rip), $AND_MASK
-+	jmp	.LOOP_GRANDE_SQR_1024
-+
-+.align	32
-+.LOOP_GRANDE_SQR_1024:
-+	lea	32*18+128(%rsp), $aap		# size optimization
-+	lea	448(%rsp), $tp1			# 64+128+256=448
-+
-+	# the squaring is performed as described in Variant B of
-+	# "Speeding up Big-Number Squaring", so start by calculating
-+	# the A*2=A+A vector
-+	vpaddq		$ACC1, $ACC1, $ACC1
-+	 vpbroadcastq	32*0-128($ap), $B1
-+	vpaddq		$ACC2, $ACC2, $ACC2
-+	vmovdqa		$ACC1, 32*0-128($aap)
-+	vpaddq		$ACC3, $ACC3, $ACC3
-+	vmovdqa		$ACC2, 32*1-128($aap)
-+	vpaddq		$ACC4, $ACC4, $ACC4
-+	vmovdqa		$ACC3, 32*2-128($aap)
-+	vpaddq		$ACC5, $ACC5, $ACC5
-+	vmovdqa		$ACC4, 32*3-128($aap)
-+	vpaddq		$ACC6, $ACC6, $ACC6
-+	vmovdqa		$ACC5, 32*4-128($aap)
-+	vpaddq		$ACC7, $ACC7, $ACC7
-+	vmovdqa		$ACC6, 32*5-128($aap)
-+	vpaddq		$ACC8, $ACC8, $ACC8
-+	vmovdqa		$ACC7, 32*6-128($aap)
-+	vpxor		$ACC9, $ACC9, $ACC9
-+	vmovdqa		$ACC8, 32*7-128($aap)
-+
-+	vpmuludq	32*0-128($ap), $B1, $ACC0
-+	 vpbroadcastq	32*1-128($ap), $B2
-+	 vmovdqu	$ACC9, 32*9-192($tp0)	# zero upper half
-+	vpmuludq	$B1, $ACC1, $ACC1
-+	 vmovdqu	$ACC9, 32*10-448($tp1)
-+	vpmuludq	$B1, $ACC2, $ACC2
-+	 vmovdqu	$ACC9, 32*11-448($tp1)
-+	vpmuludq	$B1, $ACC3, $ACC3
-+	 vmovdqu	$ACC9, 32*12-448($tp1)
-+	vpmuludq	$B1, $ACC4, $ACC4
-+	 vmovdqu	$ACC9, 32*13-448($tp1)
-+	vpmuludq	$B1, $ACC5, $ACC5
-+	 vmovdqu	$ACC9, 32*14-448($tp1)
-+	vpmuludq	$B1, $ACC6, $ACC6
-+	 vmovdqu	$ACC9, 32*15-448($tp1)
-+	vpmuludq	$B1, $ACC7, $ACC7
-+	 vmovdqu	$ACC9, 32*16-448($tp1)
-+	vpmuludq	$B1, $ACC8, $ACC8
-+	 vpbroadcastq	32*2-128($ap), $B1
-+	 vmovdqu	$ACC9, 32*17-448($tp1)
-+
-+	mov	$ap, $tpa
-+	mov 	\$4, $i
-+	jmp	.Lsqr_entry_1024
-+___
-+$TEMP0=$Y1;
-+$TEMP2=$Y2;
-+$code.=<<___;
-+.align	32
-+.LOOP_SQR_1024:
-+	 vpbroadcastq	32*1-128($tpa), $B2
-+	vpmuludq	32*0-128($ap), $B1, $ACC0
-+	vpaddq		32*0-192($tp0), $ACC0, $ACC0
-+	vpmuludq	32*0-128($aap), $B1, $ACC1
-+	vpaddq		32*1-192($tp0), $ACC1, $ACC1
-+	vpmuludq	32*1-128($aap), $B1, $ACC2
-+	vpaddq		32*2-192($tp0), $ACC2, $ACC2
-+	vpmuludq	32*2-128($aap), $B1, $ACC3
-+	vpaddq		32*3-192($tp0), $ACC3, $ACC3
-+	vpmuludq	32*3-128($aap), $B1, $ACC4
-+	vpaddq		32*4-192($tp0), $ACC4, $ACC4
-+	vpmuludq	32*4-128($aap), $B1, $ACC5
-+	vpaddq		32*5-192($tp0), $ACC5, $ACC5
-+	vpmuludq	32*5-128($aap), $B1, $ACC6
-+	vpaddq		32*6-192($tp0), $ACC6, $ACC6
-+	vpmuludq	32*6-128($aap), $B1, $ACC7
-+	vpaddq		32*7-192($tp0), $ACC7, $ACC7
-+	vpmuludq	32*7-128($aap), $B1, $ACC8
-+	 vpbroadcastq	32*2-128($tpa), $B1
-+	vpaddq		32*8-192($tp0), $ACC8, $ACC8
-+.Lsqr_entry_1024:
-+	vmovdqu		$ACC0, 32*0-192($tp0)
-+	vmovdqu		$ACC1, 32*1-192($tp0)
-+
-+	vpmuludq	32*1-128($ap), $B2, $TEMP0
-+	vpaddq		$TEMP0, $ACC2, $ACC2
-+	vpmuludq	32*1-128($aap), $B2, $TEMP1
-+	vpaddq		$TEMP1, $ACC3, $ACC3
-+	vpmuludq	32*2-128($aap), $B2, $TEMP2
-+	vpaddq		$TEMP2, $ACC4, $ACC4
-+	vpmuludq	32*3-128($aap), $B2, $TEMP0
-+	vpaddq		$TEMP0, $ACC5, $ACC5
-+	vpmuludq	32*4-128($aap), $B2, $TEMP1
-+	vpaddq		$TEMP1, $ACC6, $ACC6
-+	vpmuludq	32*5-128($aap), $B2, $TEMP2
-+	vpaddq		$TEMP2, $ACC7, $ACC7
-+	vpmuludq	32*6-128($aap), $B2, $TEMP0
-+	vpaddq		$TEMP0, $ACC8, $ACC8
-+	vpmuludq	32*7-128($aap), $B2, $ACC0
-+	 vpbroadcastq	32*3-128($tpa), $B2
-+	vpaddq		32*9-192($tp0), $ACC0, $ACC0
-+
-+	vmovdqu		$ACC2, 32*2-192($tp0)
-+	vmovdqu		$ACC3, 32*3-192($tp0)
-+
-+	vpmuludq	32*2-128($ap), $B1, $TEMP2
-+	vpaddq		$TEMP2, $ACC4, $ACC4
-+	vpmuludq	32*2-128($aap), $B1, $TEMP0
-+	vpaddq		$TEMP0, $ACC5, $ACC5
-+	vpmuludq	32*3-128($aap), $B1, $TEMP1
-+	vpaddq		$TEMP1, $ACC6, $ACC6
-+	vpmuludq	32*4-128($aap), $B1, $TEMP2
-+	vpaddq		$TEMP2, $ACC7, $ACC7
-+	vpmuludq	32*5-128($aap), $B1, $TEMP0
-+	vpaddq		$TEMP0, $ACC8, $ACC8
-+	vpmuludq	32*6-128($aap), $B1, $TEMP1
-+	vpaddq		$TEMP1, $ACC0, $ACC0
-+	vpmuludq	32*7-128($aap), $B1, $ACC1
-+	 vpbroadcastq	32*4-128($tpa), $B1
-+	vpaddq		32*10-448($tp1), $ACC1, $ACC1
-+
-+	vmovdqu		$ACC4, 32*4-192($tp0)
-+	vmovdqu		$ACC5, 32*5-192($tp0)
-+
-+	vpmuludq	32*3-128($ap), $B2, $TEMP0
-+	vpaddq		$TEMP0, $ACC6, $ACC6
-+	vpmuludq	32*3-128($aap), $B2, $TEMP1
-+	vpaddq		$TEMP1, $ACC7, $ACC7
-+	vpmuludq	32*4-128($aap), $B2, $TEMP2
-+	vpaddq		$TEMP2, $ACC8, $ACC8
-+	vpmuludq	32*5-128($aap), $B2, $TEMP0
-+	vpaddq		$TEMP0, $ACC0, $ACC0
-+	vpmuludq	32*6-128($aap), $B2, $TEMP1
-+	vpaddq		$TEMP1, $ACC1, $ACC1
-+	vpmuludq	32*7-128($aap), $B2, $ACC2
-+	 vpbroadcastq	32*5-128($tpa), $B2
-+	vpaddq		32*11-448($tp1), $ACC2, $ACC2	
-+
-+	vmovdqu		$ACC6, 32*6-192($tp0)
-+	vmovdqu		$ACC7, 32*7-192($tp0)
-+
-+	vpmuludq	32*4-128($ap), $B1, $TEMP0
-+	vpaddq		$TEMP0, $ACC8, $ACC8
-+	vpmuludq	32*4-128($aap), $B1, $TEMP1
-+	vpaddq		$TEMP1, $ACC0, $ACC0
-+	vpmuludq	32*5-128($aap), $B1, $TEMP2
-+	vpaddq		$TEMP2, $ACC1, $ACC1
-+	vpmuludq	32*6-128($aap), $B1, $TEMP0
-+	vpaddq		$TEMP0, $ACC2, $ACC2
-+	vpmuludq	32*7-128($aap), $B1, $ACC3
-+	 vpbroadcastq	32*6-128($tpa), $B1
-+	vpaddq		32*12-448($tp1), $ACC3, $ACC3
-+
-+	vmovdqu		$ACC8, 32*8-192($tp0)
-+	vmovdqu		$ACC0, 32*9-192($tp0)
-+	lea		8($tp0), $tp0
-+
-+	vpmuludq	32*5-128($ap), $B2, $TEMP2
-+	vpaddq		$TEMP2, $ACC1, $ACC1
-+	vpmuludq	32*5-128($aap), $B2, $TEMP0
-+	vpaddq		$TEMP0, $ACC2, $ACC2
-+	vpmuludq	32*6-128($aap), $B2, $TEMP1
-+	vpaddq		$TEMP1, $ACC3, $ACC3
-+	vpmuludq	32*7-128($aap), $B2, $ACC4
-+	 vpbroadcastq	32*7-128($tpa), $B2
-+	vpaddq		32*13-448($tp1), $ACC4, $ACC4
-+
-+	vmovdqu		$ACC1, 32*10-448($tp1)
-+	vmovdqu		$ACC2, 32*11-448($tp1)
-+
-+	vpmuludq	32*6-128($ap), $B1, $TEMP0
-+	vpaddq		$TEMP0, $ACC3, $ACC3
-+	vpmuludq	32*6-128($aap), $B1, $TEMP1
-+	 vpbroadcastq	32*8-128($tpa), $ACC0		# borrow $ACC0 for $B1
-+	vpaddq		$TEMP1, $ACC4, $ACC4
-+	vpmuludq	32*7-128($aap), $B1, $ACC5
-+	 vpbroadcastq	32*0+8-128($tpa), $B1		# for next iteration
-+	vpaddq		32*14-448($tp1), $ACC5, $ACC5
-+
-+	vmovdqu		$ACC3, 32*12-448($tp1)
-+	vmovdqu		$ACC4, 32*13-448($tp1)
-+	lea		8($tpa), $tpa
-+
-+	vpmuludq	32*7-128($ap), $B2, $TEMP0
-+	vpaddq		$TEMP0, $ACC5, $ACC5
-+	vpmuludq	32*7-128($aap), $B2, $ACC6
-+	vpaddq		32*15-448($tp1), $ACC6, $ACC6
-+
-+	vpmuludq	32*8-128($ap), $ACC0, $ACC7
-+	vmovdqu		$ACC5, 32*14-448($tp1)
-+	vpaddq		32*16-448($tp1), $ACC7, $ACC7
-+	vmovdqu		$ACC6, 32*15-448($tp1)
-+	vmovdqu		$ACC7, 32*16-448($tp1)
-+	lea		8($tp1), $tp1
-+
-+	dec	$i        
-+	jnz	.LOOP_SQR_1024
-+___
-+$ZERO = $ACC9;
-+$TEMP0 = $B1;
-+$TEMP2 = $B2;
-+$TEMP3 = $Y1;
-+$TEMP4 = $Y2;
-+$code.=<<___;
-+	# we need to fix indices 32-39 to avoid overflow
-+	vmovdqu		32*8(%rsp), $ACC8		# 32*8-192($tp0),
-+	vmovdqu		32*9(%rsp), $ACC1		# 32*9-192($tp0)
-+	vmovdqu		32*10(%rsp), $ACC2		# 32*10-192($tp0)
-+	lea		192(%rsp), $tp0			# 64+128=192
-+
-+	vpsrlq		\$29, $ACC8, $TEMP1
-+	vpand		$AND_MASK, $ACC8, $ACC8
-+	vpsrlq		\$29, $ACC1, $TEMP2
-+	vpand		$AND_MASK, $ACC1, $ACC1
-+
-+	vpermq		\$0x93, $TEMP1, $TEMP1
-+	vpxor		$ZERO, $ZERO, $ZERO
-+	vpermq		\$0x93, $TEMP2, $TEMP2
-+
-+	vpblendd	\$3, $ZERO, $TEMP1, $TEMP0
-+	vpblendd	\$3, $TEMP1, $TEMP2, $TEMP1
-+	vpaddq		$TEMP0, $ACC8, $ACC8
-+	vpblendd	\$3, $TEMP2, $ZERO, $TEMP2
-+	vpaddq		$TEMP1, $ACC1, $ACC1
-+	vpaddq		$TEMP2, $ACC2, $ACC2
-+	vmovdqu		$ACC1, 32*9-192($tp0)
-+	vmovdqu		$ACC2, 32*10-192($tp0)
-+
-+	mov	(%rsp), %rax
-+	mov	8(%rsp), $r1
-+	mov	16(%rsp), $r2
-+	mov	24(%rsp), $r3
-+	vmovdqu	32*1(%rsp), $ACC1
-+	vmovdqu	32*2-192($tp0), $ACC2
-+	vmovdqu	32*3-192($tp0), $ACC3
-+	vmovdqu	32*4-192($tp0), $ACC4
-+	vmovdqu	32*5-192($tp0), $ACC5
-+	vmovdqu	32*6-192($tp0), $ACC6
-+	vmovdqu	32*7-192($tp0), $ACC7
-+
-+	mov	%rax, $r0
-+	imull	$n0, %eax
-+	and	\$0x1fffffff, %eax
-+	vmovd	%eax, $Y1
-+
-+	mov	%rax, %rdx
-+	imulq	-128($np), %rax
-+	 vpbroadcastq	$Y1, $Y1
-+	add	%rax, $r0
-+	mov	%rdx, %rax
-+	imulq	8-128($np), %rax
-+	shr	\$29, $r0
-+	add	%rax, $r1
-+	mov	%rdx, %rax
-+	imulq	16-128($np), %rax
-+	add	$r0, $r1
-+	add	%rax, $r2
-+	imulq	24-128($np), %rdx
-+	add	%rdx, $r3
-+
-+	mov	$r1, %rax
-+	imull	$n0, %eax
-+	and	\$0x1fffffff, %eax
-+
-+	mov \$9, $i
-+	jmp .LOOP_REDUCE_1024
-+
-+.align	32
-+.LOOP_REDUCE_1024:
-+	vmovd	%eax, $Y2
-+	vpbroadcastq	$Y2, $Y2
-+
-+	vpmuludq	32*1-128($np), $Y1, $TEMP0
-+	 mov	%rax, %rdx
-+	 imulq	-128($np), %rax
-+	vpaddq		$TEMP0, $ACC1, $ACC1
-+	 add	%rax, $r1
-+	vpmuludq	32*2-128($np), $Y1, $TEMP1
-+	 mov	%rdx, %rax
-+	 imulq	8-128($np), %rax
-+	vpaddq		$TEMP1, $ACC2, $ACC2
-+	vpmuludq	32*3-128($np), $Y1, $TEMP2
-+	 .byte	0x67
-+	 add	%rax, $r2
-+	 .byte	0x67
-+	 mov	%rdx, %rax
-+	 imulq	16-128($np), %rax
-+	 shr	\$29, $r1
-+	vpaddq		$TEMP2, $ACC3, $ACC3
-+	vpmuludq	32*4-128($np), $Y1, $TEMP0
-+	 add	%rax, $r3
-+	 add	$r1, $r2
-+	vpaddq		$TEMP0, $ACC4, $ACC4
-+	vpmuludq	32*5-128($np), $Y1, $TEMP1
-+	 mov	$r2, %rax
-+	 imull	$n0, %eax
-+	vpaddq		$TEMP1, $ACC5, $ACC5
-+	vpmuludq	32*6-128($np), $Y1, $TEMP2
-+	 and	\$0x1fffffff, %eax
-+	vpaddq		$TEMP2, $ACC6, $ACC6
-+	vpmuludq	32*7-128($np), $Y1, $TEMP0
-+	vpaddq		$TEMP0, $ACC7, $ACC7
-+	vpmuludq	32*8-128($np), $Y1, $TEMP1
-+	 vmovd	%eax, $Y1
-+	 #vmovdqu	32*1-8-128($np), $TEMP2		# moved below
-+	vpaddq		$TEMP1, $ACC8, $ACC8
-+	 #vmovdqu	32*2-8-128($np), $TEMP0		# moved below
-+	 vpbroadcastq	$Y1, $Y1
-+
-+	vpmuludq	32*1-8-128($np), $Y2, $TEMP2	# see above
-+	vmovdqu		32*3-8-128($np), $TEMP1
-+	 mov	%rax, %rdx
-+	 imulq	-128($np), %rax
-+	vpaddq		$TEMP2, $ACC1, $ACC1
-+	vpmuludq	32*2-8-128($np), $Y2, $TEMP0	# see above
-+	vmovdqu		32*4-8-128($np), $TEMP2
-+	 add	%rax, $r2
-+	 mov	%rdx, %rax
-+	 imulq	8-128($np), %rax
-+	vpaddq		$TEMP0, $ACC2, $ACC2
-+	 add	$r3, %rax
-+	 shr	\$29, $r2
-+	vpmuludq	$Y2, $TEMP1, $TEMP1
-+	vmovdqu		32*5-8-128($np), $TEMP0
-+	 add	$r2, %rax
-+	vpaddq		$TEMP1, $ACC3, $ACC3
-+	vpmuludq	$Y2, $TEMP2, $TEMP2
-+	vmovdqu		32*6-8-128($np), $TEMP1
-+	 .byte	0x67
-+	 mov	%rax, $r3
-+	 imull	$n0, %eax
-+	vpaddq		$TEMP2, $ACC4, $ACC4
-+	vpmuludq	$Y2, $TEMP0, $TEMP0
-+	.byte	0xc4,0x41,0x7e,0x6f,0x9d,0x58,0x00,0x00,0x00	# vmovdqu		32*7-8-128($np), $TEMP2
-+	 and	\$0x1fffffff, %eax
-+	vpaddq		$TEMP0, $ACC5, $ACC5
-+	vpmuludq	$Y2, $TEMP1, $TEMP1
-+	vmovdqu		32*8-8-128($np), $TEMP0
-+	vpaddq		$TEMP1, $ACC6, $ACC6
-+	vpmuludq	$Y2, $TEMP2, $TEMP2
-+	vmovdqu		32*9-8-128($np), $ACC9
-+	 vmovd	%eax, $ACC0			# borrow ACC0 for Y2
-+	 imulq	-128($np), %rax
-+	vpaddq		$TEMP2, $ACC7, $ACC7
-+	vpmuludq	$Y2, $TEMP0, $TEMP0
-+	 vmovdqu	32*1-16-128($np), $TEMP1
-+	 vpbroadcastq	$ACC0, $ACC0
-+	vpaddq		$TEMP0, $ACC8, $ACC8
-+	vpmuludq	$Y2, $ACC9, $ACC9
-+	 vmovdqu	32*2-16-128($np), $TEMP2
-+	 add	%rax, $r3
-+
-+___
-+($ACC0,$Y2)=($Y2,$ACC0);
-+$code.=<<___;
-+	 vmovdqu	32*1-24-128($np), $ACC0
-+	vpmuludq	$Y1, $TEMP1, $TEMP1
-+	vmovdqu		32*3-16-128($np), $TEMP0
-+	vpaddq		$TEMP1, $ACC1, $ACC1
-+	 vpmuludq	$Y2, $ACC0, $ACC0
-+	vpmuludq	$Y1, $TEMP2, $TEMP2
-+	.byte	0xc4,0x41,0x7e,0x6f,0xb5,0xf0,0xff,0xff,0xff	# vmovdqu		32*4-16-128($np), $TEMP1
-+	 vpaddq		$ACC1, $ACC0, $ACC0
-+	vpaddq		$TEMP2, $ACC2, $ACC2
-+	vpmuludq	$Y1, $TEMP0, $TEMP0
-+	vmovdqu		32*5-16-128($np), $TEMP2
-+	 .byte	0x67
-+	 vmovq		$ACC0, %rax
-+	 vmovdqu	$ACC0, (%rsp)		# transfer $r0-$r3
-+	vpaddq		$TEMP0, $ACC3, $ACC3
-+	vpmuludq	$Y1, $TEMP1, $TEMP1
-+	vmovdqu		32*6-16-128($np), $TEMP0
-+	vpaddq		$TEMP1, $ACC4, $ACC4
-+	vpmuludq	$Y1, $TEMP2, $TEMP2
-+	vmovdqu		32*7-16-128($np), $TEMP1
-+	vpaddq		$TEMP2, $ACC5, $ACC5
-+	vpmuludq	$Y1, $TEMP0, $TEMP0
-+	vmovdqu		32*8-16-128($np), $TEMP2
-+	vpaddq		$TEMP0, $ACC6, $ACC6
-+	vpmuludq	$Y1, $TEMP1, $TEMP1
-+	 shr	\$29, $r3
-+	vmovdqu		32*9-16-128($np), $TEMP0
-+	 add	$r3, %rax
-+	vpaddq		$TEMP1, $ACC7, $ACC7
-+	vpmuludq	$Y1, $TEMP2, $TEMP2
-+	 #vmovdqu	32*2-24-128($np), $TEMP1	# moved below
-+	 mov	%rax, $r0
-+	 imull	$n0, %eax
-+	vpaddq		$TEMP2, $ACC8, $ACC8
-+	vpmuludq	$Y1, $TEMP0, $TEMP0
-+	 and	\$0x1fffffff, %eax
-+	 vmovd	%eax, $Y1
-+	 vmovdqu	32*3-24-128($np), $TEMP2
-+	.byte	0x67
-+	vpaddq		$TEMP0, $ACC9, $ACC9
-+	 vpbroadcastq	$Y1, $Y1
-+
-+	vpmuludq	32*2-24-128($np), $Y2, $TEMP1	# see above
-+	vmovdqu		32*4-24-128($np), $TEMP0
-+	 mov	%rax, %rdx
-+	 imulq	-128($np), %rax
-+	 mov	8(%rsp), $r1
-+	vpaddq		$TEMP1, $ACC2, $ACC1
-+	vpmuludq	$Y2, $TEMP2, $TEMP2
-+	vmovdqu		32*5-24-128($np), $TEMP1
-+	 add	%rax, $r0
-+	 mov	%rdx, %rax
-+	 imulq	8-128($np), %rax
-+	 .byte	0x67
-+	 shr	\$29, $r0
-+	 mov	16(%rsp), $r2
-+	vpaddq		$TEMP2, $ACC3, $ACC2
-+	vpmuludq	$Y2, $TEMP0, $TEMP0
-+	vmovdqu		32*6-24-128($np), $TEMP2
-+	 add	%rax, $r1
-+	 mov	%rdx, %rax
-+	 imulq	16-128($np), %rax
-+	vpaddq		$TEMP0, $ACC4, $ACC3
-+	vpmuludq	$Y2, $TEMP1, $TEMP1
-+	vmovdqu		32*7-24-128($np), $TEMP0
-+	 imulq	24-128($np), %rdx		# future $r3
-+	 add	%rax, $r2
-+	 lea	($r0,$r1), %rax
-+	vpaddq		$TEMP1, $ACC5, $ACC4
-+	vpmuludq	$Y2, $TEMP2, $TEMP2
-+	vmovdqu		32*8-24-128($np), $TEMP1
-+	 mov	%rax, $r1
-+	 imull	$n0, %eax
-+	vpmuludq	$Y2, $TEMP0, $TEMP0
-+	vpaddq		$TEMP2, $ACC6, $ACC5
-+	vmovdqu		32*9-24-128($np), $TEMP2
-+	 and	\$0x1fffffff, %eax
-+	vpaddq		$TEMP0, $ACC7, $ACC6
-+	vpmuludq	$Y2, $TEMP1, $TEMP1
-+	 add	24(%rsp), %rdx
-+	vpaddq		$TEMP1, $ACC8, $ACC7
-+	vpmuludq	$Y2, $TEMP2, $TEMP2
-+	vpaddq		$TEMP2, $ACC9, $ACC8
-+	 vmovq	$r3, $ACC9
-+	 mov	%rdx, $r3
-+
-+	dec	$i
-+	jnz	.LOOP_REDUCE_1024
-+___
-+($ACC0,$Y2)=($Y2,$ACC0);
-+$code.=<<___;
-+	lea	448(%rsp), $tp1			# size optimization
-+	vpaddq	$ACC9, $Y2, $ACC0
-+	vpxor	$ZERO, $ZERO, $ZERO
-+
-+	vpaddq		32*9-192($tp0), $ACC0, $ACC0
-+	vpaddq		32*10-448($tp1), $ACC1, $ACC1
-+	vpaddq		32*11-448($tp1), $ACC2, $ACC2
-+	vpaddq		32*12-448($tp1), $ACC3, $ACC3
-+	vpaddq		32*13-448($tp1), $ACC4, $ACC4
-+	vpaddq		32*14-448($tp1), $ACC5, $ACC5
-+	vpaddq		32*15-448($tp1), $ACC6, $ACC6
-+	vpaddq		32*16-448($tp1), $ACC7, $ACC7
-+	vpaddq		32*17-448($tp1), $ACC8, $ACC8
-+
-+	vpsrlq		\$29, $ACC0, $TEMP1
-+	vpand		$AND_MASK, $ACC0, $ACC0
-+	vpsrlq		\$29, $ACC1, $TEMP2
-+	vpand		$AND_MASK, $ACC1, $ACC1
-+	vpsrlq		\$29, $ACC2, $TEMP3
-+	vpermq		\$0x93, $TEMP1, $TEMP1
-+	vpand		$AND_MASK, $ACC2, $ACC2
-+	vpsrlq		\$29, $ACC3, $TEMP4
-+	vpermq		\$0x93, $TEMP2, $TEMP2
-+	vpand		$AND_MASK, $ACC3, $ACC3
-+	vpermq		\$0x93, $TEMP3, $TEMP3
-+
-+	vpblendd	\$3, $ZERO, $TEMP1, $TEMP0
-+	vpermq		\$0x93, $TEMP4, $TEMP4
-+	vpblendd	\$3, $TEMP1, $TEMP2, $TEMP1
-+	vpaddq		$TEMP0, $ACC0, $ACC0
-+	vpblendd	\$3, $TEMP2, $TEMP3, $TEMP2
-+	vpaddq		$TEMP1, $ACC1, $ACC1
-+	vpblendd	\$3, $TEMP3, $TEMP4, $TEMP3
-+	vpaddq		$TEMP2, $ACC2, $ACC2
-+	vpblendd	\$3, $TEMP4, $ZERO, $TEMP4
-+	vpaddq		$TEMP3, $ACC3, $ACC3
-+	vpaddq		$TEMP4, $ACC4, $ACC4
-+
-+	vpsrlq		\$29, $ACC0, $TEMP1
-+	vpand		$AND_MASK, $ACC0, $ACC0
-+	vpsrlq		\$29, $ACC1, $TEMP2
-+	vpand		$AND_MASK, $ACC1, $ACC1
-+	vpsrlq		\$29, $ACC2, $TEMP3
-+	vpermq		\$0x93, $TEMP1, $TEMP1
-+	vpand		$AND_MASK, $ACC2, $ACC2
-+	vpsrlq		\$29, $ACC3, $TEMP4
-+	vpermq		\$0x93, $TEMP2, $TEMP2
-+	vpand		$AND_MASK, $ACC3, $ACC3
-+	vpermq		\$0x93, $TEMP3, $TEMP3
-+
-+	vpblendd	\$3, $ZERO, $TEMP1, $TEMP0
-+	vpermq		\$0x93, $TEMP4, $TEMP4
-+	vpblendd	\$3, $TEMP1, $TEMP2, $TEMP1
-+	vpaddq		$TEMP0, $ACC0, $ACC0
-+	vpblendd	\$3, $TEMP2, $TEMP3, $TEMP2
-+	vpaddq		$TEMP1, $ACC1, $ACC1
-+	vmovdqu		$ACC0, 32*0-128($rp)
-+	vpblendd	\$3, $TEMP3, $TEMP4, $TEMP3
-+	vpaddq		$TEMP2, $ACC2, $ACC2
-+	vmovdqu		$ACC1, 32*1-128($rp)
-+	vpblendd	\$3, $TEMP4, $ZERO, $TEMP4
-+	vpaddq		$TEMP3, $ACC3, $ACC3
-+	vmovdqu		$ACC2, 32*2-128($rp)
-+	vpaddq		$TEMP4, $ACC4, $ACC4
-+	vmovdqu		$ACC3, 32*3-128($rp)
-+___
-+$TEMP5=$ACC0;
-+$code.=<<___;
-+	vpsrlq		\$29, $ACC4, $TEMP1
-+	vpand		$AND_MASK, $ACC4, $ACC4
-+	vpsrlq		\$29, $ACC5, $TEMP2
-+	vpand		$AND_MASK, $ACC5, $ACC5
-+	vpsrlq		\$29, $ACC6, $TEMP3
-+	vpermq		\$0x93, $TEMP1, $TEMP1
-+	vpand		$AND_MASK, $ACC6, $ACC6
-+	vpsrlq		\$29, $ACC7, $TEMP4
-+	vpermq		\$0x93, $TEMP2, $TEMP2
-+	vpand		$AND_MASK, $ACC7, $ACC7
-+	vpsrlq		\$29, $ACC8, $TEMP5
-+	vpermq		\$0x93, $TEMP3, $TEMP3
-+	vpand		$AND_MASK, $ACC8, $ACC8
-+	vpermq		\$0x93, $TEMP4, $TEMP4
-+
-+	vpblendd	\$3, $ZERO, $TEMP1, $TEMP0
-+	vpermq		\$0x93, $TEMP5, $TEMP5
-+	vpblendd	\$3, $TEMP1, $TEMP2, $TEMP1
-+	vpaddq		$TEMP0, $ACC4, $ACC4
-+	vpblendd	\$3, $TEMP2, $TEMP3, $TEMP2
-+	vpaddq		$TEMP1, $ACC5, $ACC5
-+	vpblendd	\$3, $TEMP3, $TEMP4, $TEMP3
-+	vpaddq		$TEMP2, $ACC6, $ACC6
-+	vpblendd	\$3, $TEMP4, $TEMP5, $TEMP4
-+	vpaddq		$TEMP3, $ACC7, $ACC7
-+	vpaddq		$TEMP4, $ACC8, $ACC8
-+     
-+	vpsrlq		\$29, $ACC4, $TEMP1
-+	vpand		$AND_MASK, $ACC4, $ACC4
-+	vpsrlq		\$29, $ACC5, $TEMP2
-+	vpand		$AND_MASK, $ACC5, $ACC5
-+	vpsrlq		\$29, $ACC6, $TEMP3
-+	vpermq		\$0x93, $TEMP1, $TEMP1
-+	vpand		$AND_MASK, $ACC6, $ACC6
-+	vpsrlq		\$29, $ACC7, $TEMP4
-+	vpermq		\$0x93, $TEMP2, $TEMP2
-+	vpand		$AND_MASK, $ACC7, $ACC7
-+	vpsrlq		\$29, $ACC8, $TEMP5
-+	vpermq		\$0x93, $TEMP3, $TEMP3
-+	vpand		$AND_MASK, $ACC8, $ACC8
-+	vpermq		\$0x93, $TEMP4, $TEMP4
-+
-+	vpblendd	\$3, $ZERO, $TEMP1, $TEMP0
-+	vpermq		\$0x93, $TEMP5, $TEMP5
-+	vpblendd	\$3, $TEMP1, $TEMP2, $TEMP1
-+	vpaddq		$TEMP0, $ACC4, $ACC4
-+	vpblendd	\$3, $TEMP2, $TEMP3, $TEMP2
-+	vpaddq		$TEMP1, $ACC5, $ACC5
-+	vmovdqu		$ACC4, 32*4-128($rp)
-+	vpblendd	\$3, $TEMP3, $TEMP4, $TEMP3
-+	vpaddq		$TEMP2, $ACC6, $ACC6
-+	vmovdqu		$ACC5, 32*5-128($rp)
-+	vpblendd	\$3, $TEMP4, $TEMP5, $TEMP4
-+	vpaddq		$TEMP3, $ACC7, $ACC7
-+	vmovdqu		$ACC6, 32*6-128($rp)
-+	vpaddq		$TEMP4, $ACC8, $ACC8
-+	vmovdqu		$ACC7, 32*7-128($rp)
-+	vmovdqu		$ACC8, 32*8-128($rp)
-+
-+	mov	$rp, $ap
-+	dec	$rep
-+	jne	.LOOP_GRANDE_SQR_1024
-+
-+	vzeroall
-+	mov	%rbp, %rax
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xd8(%rax),%xmm6
-+	movaps	-0xc8(%rax),%xmm7
-+	movaps	-0xb8(%rax),%xmm8
-+	movaps	-0xa8(%rax),%xmm9
-+	movaps	-0x98(%rax),%xmm10
-+	movaps	-0x88(%rax),%xmm11
-+	movaps	-0x78(%rax),%xmm12
-+	movaps	-0x68(%rax),%xmm13
-+	movaps	-0x58(%rax),%xmm14
-+	movaps	-0x48(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp		# restore %rsp
-+.Lsqr_1024_epilogue:
-+	ret
-+.size	rsaz_1024_sqr_avx2,.-rsaz_1024_sqr_avx2
-+___
-+}
-+
-+{ # void AMM_WW(
-+my $rp="%rdi";	# BN_ULONG *rp,
-+my $ap="%rsi";	# const BN_ULONG *ap,
-+my $bp="%rdx";	# const BN_ULONG *bp,
-+my $np="%rcx";	# const BN_ULONG *np,
-+my $n0="%r8d";	# unsigned int n0);
-+
-+# The registers that hold the accumulated redundant result
-+# The AMM works on 1024 bit operands, and redundant word size is 29
-+# Therefore: ceil(1024/29)/4 = 9
-+my $ACC0="%ymm0";
-+my $ACC1="%ymm1";
-+my $ACC2="%ymm2";
-+my $ACC3="%ymm3";
-+my $ACC4="%ymm4";
-+my $ACC5="%ymm5";
-+my $ACC6="%ymm6";
-+my $ACC7="%ymm7";
-+my $ACC8="%ymm8";
-+my $ACC9="%ymm9";
-+
-+# Registers that hold the broadcasted words of multiplier, currently used
-+my $Bi="%ymm10";
-+my $Yi="%ymm11";
-+
-+# Helper registers
-+my $TEMP0=$ACC0;
-+my $TEMP1="%ymm12";
-+my $TEMP2="%ymm13";
-+my $ZERO="%ymm14";
-+my $AND_MASK="%ymm15";
-+
-+# alu registers that hold the first words of the ACC
-+my $r0="%r9";
-+my $r1="%r10";
-+my $r2="%r11";
-+my $r3="%r12";
-+
-+my $i="%r14d";
-+my $tmp="%r15";
-+
-+$bp="%r13";	# reassigned argument
-+
-+$code.=<<___;
-+.globl	rsaz_1024_mul_avx2
-+.type	rsaz_1024_mul_avx2,\@function,5
-+.align	64
-+rsaz_1024_mul_avx2:
-+	lea	(%rsp), %rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___ if ($win64);
-+	vzeroupper
-+	lea	-0xa8(%rsp),%rsp
-+	vmovaps	%xmm6,-0xd8(%rax)
-+	vmovaps	%xmm7,-0xc8(%rax)
-+	vmovaps	%xmm8,-0xb8(%rax)
-+	vmovaps	%xmm9,-0xa8(%rax)
-+	vmovaps	%xmm10,-0x98(%rax)
-+	vmovaps	%xmm11,-0x88(%rax)
-+	vmovaps	%xmm12,-0x78(%rax)
-+	vmovaps	%xmm13,-0x68(%rax)
-+	vmovaps	%xmm14,-0x58(%rax)
-+	vmovaps	%xmm15,-0x48(%rax)
-+.Lmul_1024_body:
-+___
-+$code.=<<___;
-+	mov	%rax,%rbp
-+	vzeroall
-+	mov	%rdx, $bp	# reassigned argument
-+	sub	\$64,%rsp
-+
-+	# unaligned 256-bit load that crosses page boundary can
-+	# cause severe performance degradation here, so if $ap does
-+	# cross page boundary, swap it with $bp [meaning that caller
-+	# is advised to lay down $ap and $bp next to each other, so
-+	# that only one can cross page boundary].
-+	.byte	0x67,0x67
-+	mov	$ap, $tmp
-+	and	\$4095, $tmp
-+	add	\$32*10, $tmp
-+	shr	\$12, $tmp
-+	mov	$ap, $tmp
-+	cmovnz	$bp, $ap
-+	cmovnz	$tmp, $bp
-+
-+	mov	$np, $tmp
-+	sub	\$-128,$ap	# size optimization
-+	sub	\$-128,$np
-+	sub	\$-128,$rp
-+
-+	and	\$4095, $tmp	# see if $np crosses page
-+	add	\$32*10, $tmp
-+	.byte	0x67,0x67
-+	shr	\$12, $tmp
-+	jz	.Lmul_1024_no_n_copy
-+
-+	# unaligned 256-bit load that crosses page boundary can
-+	# cause severe performance degradation here, so if $np does
-+	# cross page boundary, copy it to stack and make sure stack
-+	# frame doesn't...
-+	sub		\$32*10,%rsp
-+	vmovdqu		32*0-128($np), $ACC0
-+	and		\$-512, %rsp
-+	vmovdqu		32*1-128($np), $ACC1
-+	vmovdqu		32*2-128($np), $ACC2
-+	vmovdqu		32*3-128($np), $ACC3
-+	vmovdqu		32*4-128($np), $ACC4
-+	vmovdqu		32*5-128($np), $ACC5
-+	vmovdqu		32*6-128($np), $ACC6
-+	vmovdqu		32*7-128($np), $ACC7
-+	vmovdqu		32*8-128($np), $ACC8
-+	lea		64+128(%rsp),$np
-+	vmovdqu		$ACC0, 32*0-128($np)
-+	vpxor		$ACC0, $ACC0, $ACC0
-+	vmovdqu		$ACC1, 32*1-128($np)
-+	vpxor		$ACC1, $ACC1, $ACC1
-+	vmovdqu		$ACC2, 32*2-128($np)
-+	vpxor		$ACC2, $ACC2, $ACC2
-+	vmovdqu		$ACC3, 32*3-128($np)
-+	vpxor		$ACC3, $ACC3, $ACC3
-+	vmovdqu		$ACC4, 32*4-128($np)
-+	vpxor		$ACC4, $ACC4, $ACC4
-+	vmovdqu		$ACC5, 32*5-128($np)
-+	vpxor		$ACC5, $ACC5, $ACC5
-+	vmovdqu		$ACC6, 32*6-128($np)
-+	vpxor		$ACC6, $ACC6, $ACC6
-+	vmovdqu		$ACC7, 32*7-128($np)
-+	vpxor		$ACC7, $ACC7, $ACC7
-+	vmovdqu		$ACC8, 32*8-128($np)
-+	vmovdqa		$ACC0, $ACC8
-+	vmovdqu		$ACC9, 32*9-128($np)	# $ACC9 is zero after vzeroall
-+.Lmul_1024_no_n_copy:
-+	and	\$-64,%rsp
-+
-+	mov	($bp), %rbx
-+	vpbroadcastq ($bp), $Bi
-+	vmovdqu	$ACC0, (%rsp)			# clear top of stack
-+	xor	$r0, $r0
-+	.byte	0x67
-+	xor	$r1, $r1
-+	xor	$r2, $r2
-+	xor	$r3, $r3
-+
-+	vmovdqu	.Land_mask(%rip), $AND_MASK
-+	mov	\$9, $i
-+	vmovdqu	$ACC9, 32*9-128($rp)		# $ACC9 is zero after vzeroall
-+	jmp	.Loop_mul_1024
-+
-+.align	32
-+.Loop_mul_1024:
-+	 vpsrlq		\$29, $ACC3, $ACC9		# correct $ACC3(*)
-+	mov	%rbx, %rax
-+	imulq	-128($ap), %rax
-+	add	$r0, %rax
-+	mov	%rbx, $r1
-+	imulq	8-128($ap), $r1
-+	add	8(%rsp), $r1
-+
-+	mov	%rax, $r0
-+	imull	$n0, %eax
-+	and	\$0x1fffffff, %eax
-+
-+	 mov	%rbx, $r2
-+	 imulq	16-128($ap), $r2
-+	 add	16(%rsp), $r2
-+
-+	 mov	%rbx, $r3
-+	 imulq	24-128($ap), $r3
-+	 add	24(%rsp), $r3
-+	vpmuludq	32*1-128($ap),$Bi,$TEMP0
-+	 vmovd		%eax, $Yi
-+	vpaddq		$TEMP0,$ACC1,$ACC1
-+	vpmuludq	32*2-128($ap),$Bi,$TEMP1
-+	 vpbroadcastq	$Yi, $Yi
-+	vpaddq		$TEMP1,$ACC2,$ACC2
-+	vpmuludq	32*3-128($ap),$Bi,$TEMP2
-+	 vpand		$AND_MASK, $ACC3, $ACC3		# correct $ACC3
-+	vpaddq		$TEMP2,$ACC3,$ACC3
-+	vpmuludq	32*4-128($ap),$Bi,$TEMP0
-+	vpaddq		$TEMP0,$ACC4,$ACC4
-+	vpmuludq	32*5-128($ap),$Bi,$TEMP1
-+	vpaddq		$TEMP1,$ACC5,$ACC5
-+	vpmuludq	32*6-128($ap),$Bi,$TEMP2
-+	vpaddq		$TEMP2,$ACC6,$ACC6
-+	vpmuludq	32*7-128($ap),$Bi,$TEMP0
-+	 vpermq		\$0x93, $ACC9, $ACC9		# correct $ACC3
-+	vpaddq		$TEMP0,$ACC7,$ACC7
-+	vpmuludq	32*8-128($ap),$Bi,$TEMP1
-+	 vpbroadcastq	8($bp), $Bi
-+	vpaddq		$TEMP1,$ACC8,$ACC8
-+
-+	mov	%rax,%rdx
-+	imulq	-128($np),%rax
-+	add	%rax,$r0
-+	mov	%rdx,%rax
-+	imulq	8-128($np),%rax
-+	add	%rax,$r1
-+	mov	%rdx,%rax
-+	imulq	16-128($np),%rax
-+	add	%rax,$r2
-+	shr	\$29, $r0
-+	imulq	24-128($np),%rdx
-+	add	%rdx,$r3
-+	add	$r0, $r1
-+
-+	vpmuludq	32*1-128($np),$Yi,$TEMP2
-+	 vmovq		$Bi, %rbx
-+	vpaddq		$TEMP2,$ACC1,$ACC1
-+	vpmuludq	32*2-128($np),$Yi,$TEMP0
-+	vpaddq		$TEMP0,$ACC2,$ACC2
-+	vpmuludq	32*3-128($np),$Yi,$TEMP1
-+	vpaddq		$TEMP1,$ACC3,$ACC3
-+	vpmuludq	32*4-128($np),$Yi,$TEMP2
-+	vpaddq		$TEMP2,$ACC4,$ACC4
-+	vpmuludq	32*5-128($np),$Yi,$TEMP0
-+	vpaddq		$TEMP0,$ACC5,$ACC5
-+	vpmuludq	32*6-128($np),$Yi,$TEMP1
-+	vpaddq		$TEMP1,$ACC6,$ACC6
-+	vpmuludq	32*7-128($np),$Yi,$TEMP2
-+	 vpblendd	\$3, $ZERO, $ACC9, $ACC9	# correct $ACC3
-+	vpaddq		$TEMP2,$ACC7,$ACC7
-+	vpmuludq	32*8-128($np),$Yi,$TEMP0
-+	 vpaddq		$ACC9, $ACC3, $ACC3		# correct $ACC3
-+	vpaddq		$TEMP0,$ACC8,$ACC8
-+
-+	mov	%rbx, %rax
-+	imulq	-128($ap),%rax
-+	add	%rax,$r1
-+	 vmovdqu	-8+32*1-128($ap),$TEMP1
-+	mov	%rbx, %rax
-+	imulq	8-128($ap),%rax
-+	add	%rax,$r2
-+	 vmovdqu	-8+32*2-128($ap),$TEMP2
-+
-+	mov	$r1, %rax
-+	imull	$n0, %eax
-+	and	\$0x1fffffff, %eax
-+
-+	 imulq	16-128($ap),%rbx
-+	 add	%rbx,$r3
-+	vpmuludq	$Bi,$TEMP1,$TEMP1
-+	 vmovd		%eax, $Yi
-+	vmovdqu		-8+32*3-128($ap),$TEMP0
-+	vpaddq		$TEMP1,$ACC1,$ACC1
-+	vpmuludq	$Bi,$TEMP2,$TEMP2
-+	 vpbroadcastq	$Yi, $Yi
-+	vmovdqu		-8+32*4-128($ap),$TEMP1
-+	vpaddq		$TEMP2,$ACC2,$ACC2
-+	vpmuludq	$Bi,$TEMP0,$TEMP0
-+	vmovdqu		-8+32*5-128($ap),$TEMP2
-+	vpaddq		$TEMP0,$ACC3,$ACC3
-+	vpmuludq	$Bi,$TEMP1,$TEMP1
-+	vmovdqu		-8+32*6-128($ap),$TEMP0
-+	vpaddq		$TEMP1,$ACC4,$ACC4
-+	vpmuludq	$Bi,$TEMP2,$TEMP2
-+	vmovdqu		-8+32*7-128($ap),$TEMP1
-+	vpaddq		$TEMP2,$ACC5,$ACC5
-+	vpmuludq	$Bi,$TEMP0,$TEMP0
-+	vmovdqu		-8+32*8-128($ap),$TEMP2
-+	vpaddq		$TEMP0,$ACC6,$ACC6
-+	vpmuludq	$Bi,$TEMP1,$TEMP1
-+	vmovdqu		-8+32*9-128($ap),$ACC9
-+	vpaddq		$TEMP1,$ACC7,$ACC7
-+	vpmuludq	$Bi,$TEMP2,$TEMP2
-+	vpaddq		$TEMP2,$ACC8,$ACC8
-+	vpmuludq	$Bi,$ACC9,$ACC9
-+	 vpbroadcastq	16($bp), $Bi
-+
-+	mov	%rax,%rdx
-+	imulq	-128($np),%rax
-+	add	%rax,$r1
-+	 vmovdqu	-8+32*1-128($np),$TEMP0
-+	mov	%rdx,%rax
-+	imulq	8-128($np),%rax
-+	add	%rax,$r2
-+	 vmovdqu	-8+32*2-128($np),$TEMP1
-+	shr	\$29, $r1
-+	imulq	16-128($np),%rdx
-+	add	%rdx,$r3
-+	add	$r1, $r2
-+
-+	vpmuludq	$Yi,$TEMP0,$TEMP0
-+	 vmovq		$Bi, %rbx
-+	vmovdqu		-8+32*3-128($np),$TEMP2
-+	vpaddq		$TEMP0,$ACC1,$ACC1
-+	vpmuludq	$Yi,$TEMP1,$TEMP1
-+	vmovdqu		-8+32*4-128($np),$TEMP0
-+	vpaddq		$TEMP1,$ACC2,$ACC2
-+	vpmuludq	$Yi,$TEMP2,$TEMP2
-+	vmovdqu		-8+32*5-128($np),$TEMP1
-+	vpaddq		$TEMP2,$ACC3,$ACC3
-+	vpmuludq	$Yi,$TEMP0,$TEMP0
-+	vmovdqu		-8+32*6-128($np),$TEMP2
-+	vpaddq		$TEMP0,$ACC4,$ACC4
-+	vpmuludq	$Yi,$TEMP1,$TEMP1
-+	vmovdqu		-8+32*7-128($np),$TEMP0
-+	vpaddq		$TEMP1,$ACC5,$ACC5
-+	vpmuludq	$Yi,$TEMP2,$TEMP2
-+	vmovdqu		-8+32*8-128($np),$TEMP1
-+	vpaddq		$TEMP2,$ACC6,$ACC6
-+	vpmuludq	$Yi,$TEMP0,$TEMP0
-+	vmovdqu		-8+32*9-128($np),$TEMP2
-+	vpaddq		$TEMP0,$ACC7,$ACC7
-+	vpmuludq	$Yi,$TEMP1,$TEMP1
-+	vpaddq		$TEMP1,$ACC8,$ACC8
-+	vpmuludq	$Yi,$TEMP2,$TEMP2
-+	vpaddq		$TEMP2,$ACC9,$ACC9
-+
-+	 vmovdqu	-16+32*1-128($ap),$TEMP0
-+	mov	%rbx,%rax
-+	imulq	-128($ap),%rax
-+	add	$r2,%rax
-+
-+	 vmovdqu	-16+32*2-128($ap),$TEMP1
-+	mov	%rax,$r2
-+	imull	$n0, %eax
-+	and	\$0x1fffffff, %eax
-+
-+	 imulq	8-128($ap),%rbx
-+	 add	%rbx,$r3
-+	vpmuludq	$Bi,$TEMP0,$TEMP0
-+	 vmovd		%eax, $Yi
-+	vmovdqu		-16+32*3-128($ap),$TEMP2
-+	vpaddq		$TEMP0,$ACC1,$ACC1
-+	vpmuludq	$Bi,$TEMP1,$TEMP1
-+	 vpbroadcastq	$Yi, $Yi
-+	vmovdqu		-16+32*4-128($ap),$TEMP0
-+	vpaddq		$TEMP1,$ACC2,$ACC2
-+	vpmuludq	$Bi,$TEMP2,$TEMP2
-+	vmovdqu		-16+32*5-128($ap),$TEMP1
-+	vpaddq		$TEMP2,$ACC3,$ACC3
-+	vpmuludq	$Bi,$TEMP0,$TEMP0
-+	vmovdqu		-16+32*6-128($ap),$TEMP2
-+	vpaddq		$TEMP0,$ACC4,$ACC4
-+	vpmuludq	$Bi,$TEMP1,$TEMP1
-+	vmovdqu		-16+32*7-128($ap),$TEMP0
-+	vpaddq		$TEMP1,$ACC5,$ACC5
-+	vpmuludq	$Bi,$TEMP2,$TEMP2
-+	vmovdqu		-16+32*8-128($ap),$TEMP1
-+	vpaddq		$TEMP2,$ACC6,$ACC6
-+	vpmuludq	$Bi,$TEMP0,$TEMP0
-+	vmovdqu		-16+32*9-128($ap),$TEMP2
-+	vpaddq		$TEMP0,$ACC7,$ACC7
-+	vpmuludq	$Bi,$TEMP1,$TEMP1
-+	vpaddq		$TEMP1,$ACC8,$ACC8
-+	vpmuludq	$Bi,$TEMP2,$TEMP2
-+	 vpbroadcastq	24($bp), $Bi
-+	vpaddq		$TEMP2,$ACC9,$ACC9
-+
-+	 vmovdqu	-16+32*1-128($np),$TEMP0
-+	mov	%rax,%rdx
-+	imulq	-128($np),%rax
-+	add	%rax,$r2
-+	 vmovdqu	-16+32*2-128($np),$TEMP1
-+	imulq	8-128($np),%rdx
-+	add	%rdx,$r3
-+	shr	\$29, $r2
-+
-+	vpmuludq	$Yi,$TEMP0,$TEMP0
-+	 vmovq		$Bi, %rbx
-+	vmovdqu		-16+32*3-128($np),$TEMP2
-+	vpaddq		$TEMP0,$ACC1,$ACC1
-+	vpmuludq	$Yi,$TEMP1,$TEMP1
-+	vmovdqu		-16+32*4-128($np),$TEMP0
-+	vpaddq		$TEMP1,$ACC2,$ACC2
-+	vpmuludq	$Yi,$TEMP2,$TEMP2
-+	vmovdqu		-16+32*5-128($np),$TEMP1
-+	vpaddq		$TEMP2,$ACC3,$ACC3
-+	vpmuludq	$Yi,$TEMP0,$TEMP0
-+	vmovdqu		-16+32*6-128($np),$TEMP2
-+	vpaddq		$TEMP0,$ACC4,$ACC4
-+	vpmuludq	$Yi,$TEMP1,$TEMP1
-+	vmovdqu		-16+32*7-128($np),$TEMP0
-+	vpaddq		$TEMP1,$ACC5,$ACC5
-+	vpmuludq	$Yi,$TEMP2,$TEMP2
-+	vmovdqu		-16+32*8-128($np),$TEMP1
-+	vpaddq		$TEMP2,$ACC6,$ACC6
-+	vpmuludq	$Yi,$TEMP0,$TEMP0
-+	vmovdqu		-16+32*9-128($np),$TEMP2
-+	vpaddq		$TEMP0,$ACC7,$ACC7
-+	vpmuludq	$Yi,$TEMP1,$TEMP1
-+	 vmovdqu	-24+32*1-128($ap),$TEMP0
-+	vpaddq		$TEMP1,$ACC8,$ACC8
-+	vpmuludq	$Yi,$TEMP2,$TEMP2
-+	 vmovdqu	-24+32*2-128($ap),$TEMP1
-+	vpaddq		$TEMP2,$ACC9,$ACC9
-+
-+	add	$r2, $r3
-+	imulq	-128($ap),%rbx
-+	add	%rbx,$r3
-+
-+	mov	$r3, %rax
-+	imull	$n0, %eax
-+	and	\$0x1fffffff, %eax
-+
-+	vpmuludq	$Bi,$TEMP0,$TEMP0
-+	 vmovd		%eax, $Yi
-+	vmovdqu		-24+32*3-128($ap),$TEMP2
-+	vpaddq		$TEMP0,$ACC1,$ACC1
-+	vpmuludq	$Bi,$TEMP1,$TEMP1
-+	 vpbroadcastq	$Yi, $Yi
-+	vmovdqu		-24+32*4-128($ap),$TEMP0
-+	vpaddq		$TEMP1,$ACC2,$ACC2
-+	vpmuludq	$Bi,$TEMP2,$TEMP2
-+	vmovdqu		-24+32*5-128($ap),$TEMP1
-+	vpaddq		$TEMP2,$ACC3,$ACC3
-+	vpmuludq	$Bi,$TEMP0,$TEMP0
-+	vmovdqu		-24+32*6-128($ap),$TEMP2
-+	vpaddq		$TEMP0,$ACC4,$ACC4
-+	vpmuludq	$Bi,$TEMP1,$TEMP1
-+	vmovdqu		-24+32*7-128($ap),$TEMP0
-+	vpaddq		$TEMP1,$ACC5,$ACC5
-+	vpmuludq	$Bi,$TEMP2,$TEMP2
-+	vmovdqu		-24+32*8-128($ap),$TEMP1
-+	vpaddq		$TEMP2,$ACC6,$ACC6
-+	vpmuludq	$Bi,$TEMP0,$TEMP0
-+	vmovdqu		-24+32*9-128($ap),$TEMP2
-+	vpaddq		$TEMP0,$ACC7,$ACC7
-+	vpmuludq	$Bi,$TEMP1,$TEMP1
-+	vpaddq		$TEMP1,$ACC8,$ACC8
-+	vpmuludq	$Bi,$TEMP2,$TEMP2
-+	 vpbroadcastq	32($bp), $Bi
-+	vpaddq		$TEMP2,$ACC9,$ACC9
-+	 add		\$32, $bp			# $bp++
-+
-+	vmovdqu		-24+32*1-128($np),$TEMP0
-+	imulq	-128($np),%rax
-+	add	%rax,$r3
-+	shr	\$29, $r3
-+
-+	vmovdqu		-24+32*2-128($np),$TEMP1
-+	vpmuludq	$Yi,$TEMP0,$TEMP0
-+	 vmovq		$Bi, %rbx
-+	vmovdqu		-24+32*3-128($np),$TEMP2
-+	vpaddq		$TEMP0,$ACC1,$ACC0		# $ACC0==$TEMP0
-+	vpmuludq	$Yi,$TEMP1,$TEMP1
-+	 vmovdqu	$ACC0, (%rsp)			# transfer $r0-$r3
-+	vpaddq		$TEMP1,$ACC2,$ACC1
-+	vmovdqu		-24+32*4-128($np),$TEMP0
-+	vpmuludq	$Yi,$TEMP2,$TEMP2
-+	vmovdqu		-24+32*5-128($np),$TEMP1
-+	vpaddq		$TEMP2,$ACC3,$ACC2
-+	vpmuludq	$Yi,$TEMP0,$TEMP0
-+	vmovdqu		-24+32*6-128($np),$TEMP2
-+	vpaddq		$TEMP0,$ACC4,$ACC3
-+	vpmuludq	$Yi,$TEMP1,$TEMP1
-+	vmovdqu		-24+32*7-128($np),$TEMP0
-+	vpaddq		$TEMP1,$ACC5,$ACC4
-+	vpmuludq	$Yi,$TEMP2,$TEMP2
-+	vmovdqu		-24+32*8-128($np),$TEMP1
-+	vpaddq		$TEMP2,$ACC6,$ACC5
-+	vpmuludq	$Yi,$TEMP0,$TEMP0
-+	vmovdqu		-24+32*9-128($np),$TEMP2
-+	 mov	$r3, $r0
-+	vpaddq		$TEMP0,$ACC7,$ACC6
-+	vpmuludq	$Yi,$TEMP1,$TEMP1
-+	 add	(%rsp), $r0
-+	vpaddq		$TEMP1,$ACC8,$ACC7
-+	vpmuludq	$Yi,$TEMP2,$TEMP2
-+	 vmovq	$r3, $TEMP1
-+	vpaddq		$TEMP2,$ACC9,$ACC8
-+
-+	dec	$i
-+	jnz	.Loop_mul_1024
-+___
-+
-+# (*)	Original implementation was correcting ACC1-ACC3 for overflow
-+#	after 7 loop runs, or after 28 iterations, or 56 additions.
-+#	But as we underutilize resources, it's possible to correct in
-+#	each iteration with marginal performance loss. But then, as
-+#	we do it in each iteration, we can correct less digits, and
-+#	avoid performance penalties completely. Also note that we
-+#	correct only three digits out of four. This works because
-+#	most significant digit is subjected to less additions.
-+
-+$TEMP0 = $ACC9;
-+$TEMP3 = $Bi;
-+$TEMP4 = $Yi;
-+$code.=<<___;
-+	vpermq		\$0, $AND_MASK, $AND_MASK
-+	vpaddq		(%rsp), $TEMP1, $ACC0
-+
-+	vpsrlq		\$29, $ACC0, $TEMP1
-+	vpand		$AND_MASK, $ACC0, $ACC0
-+	vpsrlq		\$29, $ACC1, $TEMP2
-+	vpand		$AND_MASK, $ACC1, $ACC1
-+	vpsrlq		\$29, $ACC2, $TEMP3
-+	vpermq		\$0x93, $TEMP1, $TEMP1
-+	vpand		$AND_MASK, $ACC2, $ACC2
-+	vpsrlq		\$29, $ACC3, $TEMP4
-+	vpermq		\$0x93, $TEMP2, $TEMP2
-+	vpand		$AND_MASK, $ACC3, $ACC3
-+
-+	vpblendd	\$3, $ZERO, $TEMP1, $TEMP0
-+	vpermq		\$0x93, $TEMP3, $TEMP3
-+	vpblendd	\$3, $TEMP1, $TEMP2, $TEMP1
-+	vpermq		\$0x93, $TEMP4, $TEMP4
-+	vpaddq		$TEMP0, $ACC0, $ACC0
-+	vpblendd	\$3, $TEMP2, $TEMP3, $TEMP2
-+	vpaddq		$TEMP1, $ACC1, $ACC1
-+	vpblendd	\$3, $TEMP3, $TEMP4, $TEMP3
-+	vpaddq		$TEMP2, $ACC2, $ACC2
-+	vpblendd	\$3, $TEMP4, $ZERO, $TEMP4
-+	vpaddq		$TEMP3, $ACC3, $ACC3
-+	vpaddq		$TEMP4, $ACC4, $ACC4
-+
-+	vpsrlq		\$29, $ACC0, $TEMP1
-+	vpand		$AND_MASK, $ACC0, $ACC0
-+	vpsrlq		\$29, $ACC1, $TEMP2
-+	vpand		$AND_MASK, $ACC1, $ACC1
-+	vpsrlq		\$29, $ACC2, $TEMP3
-+	vpermq		\$0x93, $TEMP1, $TEMP1
-+	vpand		$AND_MASK, $ACC2, $ACC2
-+	vpsrlq		\$29, $ACC3, $TEMP4
-+	vpermq		\$0x93, $TEMP2, $TEMP2
-+	vpand		$AND_MASK, $ACC3, $ACC3
-+	vpermq		\$0x93, $TEMP3, $TEMP3
-+
-+	vpblendd	\$3, $ZERO, $TEMP1, $TEMP0
-+	vpermq		\$0x93, $TEMP4, $TEMP4
-+	vpblendd	\$3, $TEMP1, $TEMP2, $TEMP1
-+	vpaddq		$TEMP0, $ACC0, $ACC0
-+	vpblendd	\$3, $TEMP2, $TEMP3, $TEMP2
-+	vpaddq		$TEMP1, $ACC1, $ACC1
-+	vpblendd	\$3, $TEMP3, $TEMP4, $TEMP3
-+	vpaddq		$TEMP2, $ACC2, $ACC2
-+	vpblendd	\$3, $TEMP4, $ZERO, $TEMP4
-+	vpaddq		$TEMP3, $ACC3, $ACC3
-+	vpaddq		$TEMP4, $ACC4, $ACC4
-+
-+	vmovdqu		$ACC0, 0-128($rp)
-+	vmovdqu		$ACC1, 32-128($rp)
-+	vmovdqu		$ACC2, 64-128($rp)
-+	vmovdqu		$ACC3, 96-128($rp)
-+___
-+
-+$TEMP5=$ACC0;
-+$code.=<<___;
-+	vpsrlq		\$29, $ACC4, $TEMP1
-+	vpand		$AND_MASK, $ACC4, $ACC4
-+	vpsrlq		\$29, $ACC5, $TEMP2
-+	vpand		$AND_MASK, $ACC5, $ACC5
-+	vpsrlq		\$29, $ACC6, $TEMP3
-+	vpermq		\$0x93, $TEMP1, $TEMP1
-+	vpand		$AND_MASK, $ACC6, $ACC6
-+	vpsrlq		\$29, $ACC7, $TEMP4
-+	vpermq		\$0x93, $TEMP2, $TEMP2
-+	vpand		$AND_MASK, $ACC7, $ACC7
-+	vpsrlq		\$29, $ACC8, $TEMP5
-+	vpermq		\$0x93, $TEMP3, $TEMP3
-+	vpand		$AND_MASK, $ACC8, $ACC8
-+	vpermq		\$0x93, $TEMP4, $TEMP4
-+
-+	vpblendd	\$3, $ZERO, $TEMP1, $TEMP0
-+	vpermq		\$0x93, $TEMP5, $TEMP5
-+	vpblendd	\$3, $TEMP1, $TEMP2, $TEMP1
-+	vpaddq		$TEMP0, $ACC4, $ACC4
-+	vpblendd	\$3, $TEMP2, $TEMP3, $TEMP2
-+	vpaddq		$TEMP1, $ACC5, $ACC5
-+	vpblendd	\$3, $TEMP3, $TEMP4, $TEMP3
-+	vpaddq		$TEMP2, $ACC6, $ACC6
-+	vpblendd	\$3, $TEMP4, $TEMP5, $TEMP4
-+	vpaddq		$TEMP3, $ACC7, $ACC7
-+	vpaddq		$TEMP4, $ACC8, $ACC8
-+
-+	vpsrlq		\$29, $ACC4, $TEMP1
-+	vpand		$AND_MASK, $ACC4, $ACC4
-+	vpsrlq		\$29, $ACC5, $TEMP2
-+	vpand		$AND_MASK, $ACC5, $ACC5
-+	vpsrlq		\$29, $ACC6, $TEMP3
-+	vpermq		\$0x93, $TEMP1, $TEMP1
-+	vpand		$AND_MASK, $ACC6, $ACC6
-+	vpsrlq		\$29, $ACC7, $TEMP4
-+	vpermq		\$0x93, $TEMP2, $TEMP2
-+	vpand		$AND_MASK, $ACC7, $ACC7
-+	vpsrlq		\$29, $ACC8, $TEMP5
-+	vpermq		\$0x93, $TEMP3, $TEMP3
-+	vpand		$AND_MASK, $ACC8, $ACC8
-+	vpermq		\$0x93, $TEMP4, $TEMP4
-+
-+	vpblendd	\$3, $ZERO, $TEMP1, $TEMP0
-+	vpermq		\$0x93, $TEMP5, $TEMP5
-+	vpblendd	\$3, $TEMP1, $TEMP2, $TEMP1
-+	vpaddq		$TEMP0, $ACC4, $ACC4
-+	vpblendd	\$3, $TEMP2, $TEMP3, $TEMP2
-+	vpaddq		$TEMP1, $ACC5, $ACC5
-+	vpblendd	\$3, $TEMP3, $TEMP4, $TEMP3
-+	vpaddq		$TEMP2, $ACC6, $ACC6
-+	vpblendd	\$3, $TEMP4, $TEMP5, $TEMP4
-+	vpaddq		$TEMP3, $ACC7, $ACC7
-+	vpaddq		$TEMP4, $ACC8, $ACC8
-+
-+	vmovdqu		$ACC4, 128-128($rp)
-+	vmovdqu		$ACC5, 160-128($rp)    
-+	vmovdqu		$ACC6, 192-128($rp)
-+	vmovdqu		$ACC7, 224-128($rp)
-+	vmovdqu		$ACC8, 256-128($rp)
-+	vzeroupper
-+
-+	mov	%rbp, %rax
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xd8(%rax),%xmm6
-+	movaps	-0xc8(%rax),%xmm7
-+	movaps	-0xb8(%rax),%xmm8
-+	movaps	-0xa8(%rax),%xmm9
-+	movaps	-0x98(%rax),%xmm10
-+	movaps	-0x88(%rax),%xmm11
-+	movaps	-0x78(%rax),%xmm12
-+	movaps	-0x68(%rax),%xmm13
-+	movaps	-0x58(%rax),%xmm14
-+	movaps	-0x48(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp		# restore %rsp
-+.Lmul_1024_epilogue:
-+	ret
-+.size	rsaz_1024_mul_avx2,.-rsaz_1024_mul_avx2
-+___
-+}
-+{
-+my ($out,$inp) = $win64 ? ("%rcx","%rdx") : ("%rdi","%rsi");
-+my @T = map("%r$_",(8..11));
-+
-+$code.=<<___;
-+.globl	rsaz_1024_red2norm_avx2
-+.type	rsaz_1024_red2norm_avx2,\@abi-omnipotent
-+.align	32
-+rsaz_1024_red2norm_avx2:
-+	sub	\$-128,$inp	# size optimization
-+	xor	%rax,%rax
-+___
-+
-+for ($j=0,$i=0; $i<16; $i++) {
-+    my $k=0;
-+    while (29*$j<64*($i+1)) {	# load data till boundary
-+	$code.="	mov	`8*$j-128`($inp), @T[0]\n";
-+	$j++; $k++; push(@T,shift(@T));
-+    }
-+    $l=$k;
-+    while ($k>1) {		# shift loaded data but last value
-+	$code.="	shl	\$`29*($j-$k)`,@T[-$k]\n";
-+	$k--;
-+    }
-+    $code.=<<___;		# shift last value
-+	mov	@T[-1], @T[0]
-+	shl	\$`29*($j-1)`, @T[-1]
-+	shr	\$`-29*($j-1)`, @T[0]
-+___
-+    while ($l) {		# accumulate all values
-+	$code.="	add	@T[-$l], %rax\n";
-+	$l--;
-+    }
-+	$code.=<<___;
-+	adc	\$0, @T[0]	# consume eventual carry
-+	mov	%rax, 8*$i($out)
-+	mov	@T[0], %rax
-+___
-+    push(@T,shift(@T));
-+}
-+$code.=<<___;
-+	ret
-+.size	rsaz_1024_red2norm_avx2,.-rsaz_1024_red2norm_avx2
-+
-+.globl	rsaz_1024_norm2red_avx2
-+.type	rsaz_1024_norm2red_avx2,\@abi-omnipotent
-+.align	32
-+rsaz_1024_norm2red_avx2:
-+	sub	\$-128,$out	# size optimization
-+	mov	($inp),@T[0]
-+	mov	\$0x1fffffff,%eax
-+___
-+for ($j=0,$i=0; $i<16; $i++) {
-+    $code.="	mov	`8*($i+1)`($inp),@T[1]\n"	if ($i<15);
-+    $code.="	xor	@T[1],@T[1]\n"			if ($i==15);
-+    my $k=1;
-+    while (29*($j+1)<64*($i+1)) {
-+    	$code.=<<___;
-+	mov	@T[0],@T[-$k]
-+	shr	\$`29*$j`,@T[-$k]
-+	and	%rax,@T[-$k]				# &0x1fffffff
-+	mov	@T[-$k],`8*$j-128`($out)
-+___
-+	$j++; $k++;
-+    }
-+    $code.=<<___;
-+	shrd	\$`29*$j`,@T[1],@T[0]
-+	and	%rax,@T[0]
-+	mov	@T[0],`8*$j-128`($out)
-+___
-+    $j++;
-+    push(@T,shift(@T));
-+}
-+$code.=<<___;
-+	mov	@T[0],`8*$j-128`($out)			# zero
-+	mov	@T[0],`8*($j+1)-128`($out)
-+	mov	@T[0],`8*($j+2)-128`($out)
-+	mov	@T[0],`8*($j+3)-128`($out)
-+	ret
-+.size	rsaz_1024_norm2red_avx2,.-rsaz_1024_norm2red_avx2
-+___
-+}
-+{
-+my ($out,$inp,$power) = $win64 ? ("%rcx","%rdx","%r8d") : ("%rdi","%rsi","%edx");
-+
-+$code.=<<___;
-+.globl	rsaz_1024_scatter5_avx2
-+.type	rsaz_1024_scatter5_avx2,\@abi-omnipotent
-+.align	32
-+rsaz_1024_scatter5_avx2:
-+	vzeroupper
-+	vmovdqu	.Lscatter_permd(%rip),%ymm5
-+	shl	\$4,$power
-+	lea	($out,$power),$out
-+	mov	\$9,%eax
-+	jmp	.Loop_scatter_1024
-+
-+.align	32
-+.Loop_scatter_1024:
-+	vmovdqu		($inp),%ymm0
-+	lea		32($inp),$inp
-+	vpermd		%ymm0,%ymm5,%ymm0
-+	vmovdqu		%xmm0,($out)
-+	lea		16*32($out),$out
-+	dec	%eax
-+	jnz	.Loop_scatter_1024
-+
-+	vzeroupper
-+	ret
-+.size	rsaz_1024_scatter5_avx2,.-rsaz_1024_scatter5_avx2
-+
-+.globl	rsaz_1024_gather5_avx2
-+.type	rsaz_1024_gather5_avx2,\@abi-omnipotent
-+.align	32
-+rsaz_1024_gather5_avx2:
-+	vzeroupper
-+	mov	%rsp,%r11
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0x88(%rsp),%rax
-+.LSEH_begin_rsaz_1024_gather5:
-+	# I can't trust assembler to use specific encoding:-(
-+	.byte	0x48,0x8d,0x60,0xe0		# lea	-0x20(%rax),%rsp
-+	.byte	0xc5,0xf8,0x29,0x70,0xe0	# vmovaps %xmm6,-0x20(%rax)
-+	.byte	0xc5,0xf8,0x29,0x78,0xf0	# vmovaps %xmm7,-0x10(%rax)
-+	.byte	0xc5,0x78,0x29,0x40,0x00	# vmovaps %xmm8,0(%rax)
-+	.byte	0xc5,0x78,0x29,0x48,0x10	# vmovaps %xmm9,0x10(%rax)
-+	.byte	0xc5,0x78,0x29,0x50,0x20	# vmovaps %xmm10,0x20(%rax)
-+	.byte	0xc5,0x78,0x29,0x58,0x30	# vmovaps %xmm11,0x30(%rax)
-+	.byte	0xc5,0x78,0x29,0x60,0x40	# vmovaps %xmm12,0x40(%rax)
-+	.byte	0xc5,0x78,0x29,0x68,0x50	# vmovaps %xmm13,0x50(%rax)
-+	.byte	0xc5,0x78,0x29,0x70,0x60	# vmovaps %xmm14,0x60(%rax)
-+	.byte	0xc5,0x78,0x29,0x78,0x70	# vmovaps %xmm15,0x70(%rax)
-+___
-+$code.=<<___;
-+	lea	-0x100(%rsp),%rsp
-+	and	\$-32, %rsp
-+	lea	.Linc(%rip), %r10
-+	lea	-128(%rsp),%rax			# control u-op density
-+
-+	vmovd		$power, %xmm4
-+	vmovdqa		(%r10),%ymm0
-+	vmovdqa		32(%r10),%ymm1
-+	vmovdqa		64(%r10),%ymm5
-+	vpbroadcastd	%xmm4,%ymm4
-+
-+	vpaddd		%ymm5, %ymm0, %ymm2
-+	vpcmpeqd	%ymm4, %ymm0, %ymm0
-+	vpaddd		%ymm5, %ymm1, %ymm3
-+	vpcmpeqd	%ymm4, %ymm1, %ymm1
-+	vmovdqa		%ymm0, 32*0+128(%rax)
-+	vpaddd		%ymm5, %ymm2, %ymm0
-+	vpcmpeqd	%ymm4, %ymm2, %ymm2
-+	vmovdqa		%ymm1, 32*1+128(%rax)
-+	vpaddd		%ymm5, %ymm3, %ymm1
-+	vpcmpeqd	%ymm4, %ymm3, %ymm3
-+	vmovdqa		%ymm2, 32*2+128(%rax)
-+	vpaddd		%ymm5, %ymm0, %ymm2
-+	vpcmpeqd	%ymm4, %ymm0, %ymm0
-+	vmovdqa		%ymm3, 32*3+128(%rax)
-+	vpaddd		%ymm5, %ymm1, %ymm3
-+	vpcmpeqd	%ymm4, %ymm1, %ymm1
-+	vmovdqa		%ymm0, 32*4+128(%rax)
-+	vpaddd		%ymm5, %ymm2, %ymm8
-+	vpcmpeqd	%ymm4, %ymm2, %ymm2
-+	vmovdqa		%ymm1, 32*5+128(%rax)
-+	vpaddd		%ymm5, %ymm3, %ymm9
-+	vpcmpeqd	%ymm4, %ymm3, %ymm3
-+	vmovdqa		%ymm2, 32*6+128(%rax)
-+	vpaddd		%ymm5, %ymm8, %ymm10
-+	vpcmpeqd	%ymm4, %ymm8, %ymm8
-+	vmovdqa		%ymm3, 32*7+128(%rax)
-+	vpaddd		%ymm5, %ymm9, %ymm11
-+	vpcmpeqd	%ymm4, %ymm9, %ymm9
-+	vpaddd		%ymm5, %ymm10, %ymm12
-+	vpcmpeqd	%ymm4, %ymm10, %ymm10
-+	vpaddd		%ymm5, %ymm11, %ymm13
-+	vpcmpeqd	%ymm4, %ymm11, %ymm11
-+	vpaddd		%ymm5, %ymm12, %ymm14
-+	vpcmpeqd	%ymm4, %ymm12, %ymm12
-+	vpaddd		%ymm5, %ymm13, %ymm15
-+	vpcmpeqd	%ymm4, %ymm13, %ymm13
-+	vpcmpeqd	%ymm4, %ymm14, %ymm14
-+	vpcmpeqd	%ymm4, %ymm15, %ymm15
-+
-+	vmovdqa	-32(%r10),%ymm7			# .Lgather_permd
-+	lea	128($inp), $inp
-+	mov	\$9,$power
-+
-+.Loop_gather_1024:
-+	vmovdqa		32*0-128($inp),	%ymm0
-+	vmovdqa		32*1-128($inp),	%ymm1
-+	vmovdqa		32*2-128($inp),	%ymm2
-+	vmovdqa		32*3-128($inp),	%ymm3
-+	vpand		32*0+128(%rax),	%ymm0,	%ymm0
-+	vpand		32*1+128(%rax),	%ymm1,	%ymm1
-+	vpand		32*2+128(%rax),	%ymm2,	%ymm2
-+	vpor		%ymm0, %ymm1, %ymm4
-+	vpand		32*3+128(%rax),	%ymm3,	%ymm3
-+	vmovdqa		32*4-128($inp),	%ymm0
-+	vmovdqa		32*5-128($inp),	%ymm1
-+	vpor		%ymm2, %ymm3, %ymm5
-+	vmovdqa		32*6-128($inp),	%ymm2
-+	vmovdqa		32*7-128($inp),	%ymm3
-+	vpand		32*4+128(%rax),	%ymm0,	%ymm0
-+	vpand		32*5+128(%rax),	%ymm1,	%ymm1
-+	vpand		32*6+128(%rax),	%ymm2,	%ymm2
-+	vpor		%ymm0, %ymm4, %ymm4
-+	vpand		32*7+128(%rax),	%ymm3,	%ymm3
-+	vpand		32*8-128($inp),	%ymm8,	%ymm0
-+	vpor		%ymm1, %ymm5, %ymm5
-+	vpand		32*9-128($inp),	%ymm9,	%ymm1
-+	vpor		%ymm2, %ymm4, %ymm4
-+	vpand		32*10-128($inp),%ymm10,	%ymm2
-+	vpor		%ymm3, %ymm5, %ymm5
-+	vpand		32*11-128($inp),%ymm11,	%ymm3
-+	vpor		%ymm0, %ymm4, %ymm4
-+	vpand		32*12-128($inp),%ymm12,	%ymm0
-+	vpor		%ymm1, %ymm5, %ymm5
-+	vpand		32*13-128($inp),%ymm13,	%ymm1
-+	vpor		%ymm2, %ymm4, %ymm4
-+	vpand		32*14-128($inp),%ymm14,	%ymm2
-+	vpor		%ymm3, %ymm5, %ymm5
-+	vpand		32*15-128($inp),%ymm15,	%ymm3
-+	lea		32*16($inp), $inp
-+	vpor		%ymm0, %ymm4, %ymm4
-+	vpor		%ymm1, %ymm5, %ymm5
-+	vpor		%ymm2, %ymm4, %ymm4
-+	vpor		%ymm3, %ymm5, %ymm5
-+
-+	vpor		%ymm5, %ymm4, %ymm4
-+	vextracti128	\$1, %ymm4, %xmm5	# upper half is cleared
-+	vpor		%xmm4, %xmm5, %xmm5
-+	vpermd		%ymm5,%ymm7,%ymm5
-+	vmovdqu		%ymm5,($out)
-+	lea		32($out),$out
-+	dec	$power
-+	jnz	.Loop_gather_1024
-+
-+	vpxor	%ymm0,%ymm0,%ymm0
-+	vmovdqu	%ymm0,($out)
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xa8(%r11),%xmm6
-+	movaps	-0x98(%r11),%xmm7
-+	movaps	-0x88(%r11),%xmm8
-+	movaps	-0x78(%r11),%xmm9
-+	movaps	-0x68(%r11),%xmm10
-+	movaps	-0x58(%r11),%xmm11
-+	movaps	-0x48(%r11),%xmm12
-+	movaps	-0x38(%r11),%xmm13
-+	movaps	-0x28(%r11),%xmm14
-+	movaps	-0x18(%r11),%xmm15
-+.LSEH_end_rsaz_1024_gather5:
-+___
-+$code.=<<___;
-+	lea	(%r11),%rsp
-+	ret
-+.size	rsaz_1024_gather5_avx2,.-rsaz_1024_gather5_avx2
-+___
-+}
-+
-+$code.=<<___;
-+.extern	OPENSSL_ia32cap_P
-+.globl	rsaz_avx2_eligible
-+.type	rsaz_avx2_eligible,\@abi-omnipotent
-+.align	32
-+rsaz_avx2_eligible:
-+	mov	OPENSSL_ia32cap_P+8(%rip),%eax
-+___
-+$code.=<<___	if ($addx);
-+	mov	\$`1<<8|1<<19`,%ecx
-+	mov	\$0,%edx
-+	and	%eax,%ecx
-+	cmp	\$`1<<8|1<<19`,%ecx	# check for BMI2+AD*X
-+	cmove	%edx,%eax
-+___
-+$code.=<<___;
-+	and	\$`1<<5`,%eax
-+	shr	\$5,%eax
-+	ret
-+.size	rsaz_avx2_eligible,.-rsaz_avx2_eligible
-+
-+.align	64
-+.Land_mask:
-+	.quad	0x1fffffff,0x1fffffff,0x1fffffff,-1
-+.Lscatter_permd:
-+	.long	0,2,4,6,7,7,7,7
-+.Lgather_permd:
-+	.long	0,7,1,7,2,7,3,7
-+.Linc:
-+	.long	0,0,0,0, 1,1,1,1
-+	.long	2,2,2,2, 3,3,3,3
-+	.long	4,4,4,4, 4,4,4,4
-+.align	64
-+___
-+
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___
-+.extern	__imp_RtlVirtualUnwind
-+.type	rsaz_se_handler,\@abi-omnipotent
-+.align	16
-+rsaz_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+
-+	mov	160($context),%rax	# pull context->Rbp
-+
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	mov	%r15,240($context)
-+	mov	%r14,232($context)
-+	mov	%r13,224($context)
-+	mov	%r12,216($context)
-+	mov	%rbp,160($context)
-+	mov	%rbx,144($context)
-+
-+	lea	-0xd8(%rax),%rsi	# %xmm save area
-+	lea	512($context),%rdi	# & context.Xmm6
-+	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+.Lcommon_seh_tail:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	rsaz_se_handler,.-rsaz_se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_rsaz_1024_sqr_avx2
-+	.rva	.LSEH_end_rsaz_1024_sqr_avx2
-+	.rva	.LSEH_info_rsaz_1024_sqr_avx2
-+
-+	.rva	.LSEH_begin_rsaz_1024_mul_avx2
-+	.rva	.LSEH_end_rsaz_1024_mul_avx2
-+	.rva	.LSEH_info_rsaz_1024_mul_avx2
-+
-+	.rva	.LSEH_begin_rsaz_1024_gather5
-+	.rva	.LSEH_end_rsaz_1024_gather5
-+	.rva	.LSEH_info_rsaz_1024_gather5
-+.section	.xdata
-+.align	8
-+.LSEH_info_rsaz_1024_sqr_avx2:
-+	.byte	9,0,0,0
-+	.rva	rsaz_se_handler
-+	.rva	.Lsqr_1024_body,.Lsqr_1024_epilogue
-+.LSEH_info_rsaz_1024_mul_avx2:
-+	.byte	9,0,0,0
-+	.rva	rsaz_se_handler
-+	.rva	.Lmul_1024_body,.Lmul_1024_epilogue
-+.LSEH_info_rsaz_1024_gather5:
-+	.byte	0x01,0x36,0x17,0x0b
-+	.byte	0x36,0xf8,0x09,0x00	# vmovaps 0x90(rsp),xmm15
-+	.byte	0x31,0xe8,0x08,0x00	# vmovaps 0x80(rsp),xmm14
-+	.byte	0x2c,0xd8,0x07,0x00	# vmovaps 0x70(rsp),xmm13
-+	.byte	0x27,0xc8,0x06,0x00	# vmovaps 0x60(rsp),xmm12
-+	.byte	0x22,0xb8,0x05,0x00	# vmovaps 0x50(rsp),xmm11
-+	.byte	0x1d,0xa8,0x04,0x00	# vmovaps 0x40(rsp),xmm10
-+	.byte	0x18,0x98,0x03,0x00	# vmovaps 0x30(rsp),xmm9
-+	.byte	0x13,0x88,0x02,0x00	# vmovaps 0x20(rsp),xmm8
-+	.byte	0x0e,0x78,0x01,0x00	# vmovaps 0x10(rsp),xmm7
-+	.byte	0x09,0x68,0x00,0x00	# vmovaps 0x00(rsp),xmm6
-+	.byte	0x04,0x01,0x15,0x00	# sub	  rsp,0xa8
-+	.byte	0x00,0xb3,0x00,0x00	# set_frame r11
-+___
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval($1)/ge;
-+
-+	s/\b(sh[rl]d?\s+\$)(-?[0-9]+)/$1.$2%64/ge		or
-+
-+	s/\b(vmov[dq])\b(.+)%ymm([0-9]+)/$1$2%xmm$3/go		or
-+	s/\b(vmovdqu)\b(.+)%x%ymm([0-9]+)/$1$2%xmm$3/go		or
-+	s/\b(vpinsr[qd])\b(.+)%ymm([0-9]+)/$1$2%xmm$3/go	or
-+	s/\b(vpextr[qd])\b(.+)%ymm([0-9]+)/$1$2%xmm$3/go	or
-+	s/\b(vpbroadcast[qd]\s+)%ymm([0-9]+)/$1%xmm$2/go;
-+	print $_,"\n";
-+}
-+
-+}}} else {{{
-+print <<___;	# assembler is too old
-+.text
-+
-+.globl	rsaz_avx2_eligible
-+.type	rsaz_avx2_eligible,\@abi-omnipotent
-+rsaz_avx2_eligible:
-+	xor	%eax,%eax
-+	ret
-+.size	rsaz_avx2_eligible,.-rsaz_avx2_eligible
-+
-+.globl	rsaz_1024_sqr_avx2
-+.globl	rsaz_1024_mul_avx2
-+.globl	rsaz_1024_norm2red_avx2
-+.globl	rsaz_1024_red2norm_avx2
-+.globl	rsaz_1024_scatter5_avx2
-+.globl	rsaz_1024_gather5_avx2
-+.type	rsaz_1024_sqr_avx2,\@abi-omnipotent
-+rsaz_1024_sqr_avx2:
-+rsaz_1024_mul_avx2:
-+rsaz_1024_norm2red_avx2:
-+rsaz_1024_red2norm_avx2:
-+rsaz_1024_scatter5_avx2:
-+rsaz_1024_gather5_avx2:
-+	.byte	0x0f,0x0b	# ud2
-+	ret
-+.size	rsaz_1024_sqr_avx2,.-rsaz_1024_sqr_avx2
-+___
-+}}}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/rsaz-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/rsaz-x86_64.pl
-new file mode 100755
-index 0000000..6f3b664
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/rsaz-x86_64.pl
-@@ -0,0 +1,2358 @@
-+#! /usr/bin/env perl
-+# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+##############################################################################
-+#                                                                            #
-+#  Copyright (c) 2012, Intel Corporation                                     #
-+#                                                                            #
-+#  All rights reserved.                                                      #
-+#                                                                            #
-+#  Redistribution and use in source and binary forms, with or without        #
-+#  modification, are permitted provided that the following conditions are    #
-+#  met:                                                                      #
-+#                                                                            #
-+#  *  Redistributions of source code must retain the above copyright         #
-+#     notice, this list of conditions and the following disclaimer.          #
-+#                                                                            #
-+#  *  Redistributions in binary form must reproduce the above copyright      #
-+#     notice, this list of conditions and the following disclaimer in the    #
-+#     documentation and/or other materials provided with the                 #
-+#     distribution.                                                          #
-+#                                                                            #
-+#  *  Neither the name of the Intel Corporation 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 INTEL CORPORATION ""AS IS"" AND ANY          #
-+#  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE         #
-+#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        #
-+#  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR            #
-+#  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
-+#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       #
-+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        #
-+#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    #
-+#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      #
-+#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        #
-+#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              #
-+#                                                                            #
-+##############################################################################
-+# Developers and authors:                                                    #
-+# Shay Gueron (1, 2), and Vlad Krasnov (1)                                   #
-+# (1) Intel Architecture Group, Microprocessor and Chipset Development,      #
-+#     Israel Development Center, Haifa, Israel                               #
-+# (2) University of Haifa                                                    #
-+##############################################################################
-+# Reference:                                                                 #
-+# [1] S. Gueron, "Efficient Software Implementations of Modular              #
-+#     Exponentiation", http://eprint.iacr.org/2011/239                       #
-+# [2] S. Gueron, V. Krasnov. "Speeding up Big-Numbers Squaring".             #
-+#     IEEE Proceedings of 9th International Conference on Information        #
-+#     Technology: New Generations (ITNG 2012), 821-823 (2012).               #
-+# [3] S. Gueron, Efficient Software Implementations of Modular Exponentiation#
-+#     Journal of Cryptographic Engineering 2:31-43 (2012).                   #
-+# [4] S. Gueron, V. Krasnov: "[PATCH] Efficient and side channel analysis    #
-+#     resistant 512-bit and 1024-bit modular exponentiation for optimizing   #
-+#     RSA1024 and RSA2048 on x86_64 platforms",                              #
-+#     http://rt.openssl.org/Ticket/Display.html?id=2582&user=guest&pass=guest#
-+##############################################################################
-+
-+# While original submission covers 512- and 1024-bit exponentiation,
-+# this module is limited to 512-bit version only (and as such
-+# accelerates RSA1024 sign). This is because improvement for longer
-+# keys is not high enough to justify the effort, highest measured
-+# was ~5% on Westmere. [This is relative to OpenSSL 1.0.2, upcoming
-+# for the moment of this writing!] Nor does this module implement
-+# "monolithic" complete exponentiation jumbo-subroutine, but adheres
-+# to more modular mixture of C and assembly. And it's optimized even
-+# for processors other than Intel Core family (see table below for
-+# improvement coefficients).
-+# 						
-+#
-+# RSA1024 sign/sec	this/original	|this/rsax(*)	this/fips(*)
-+#			----------------+---------------------------
-+# Opteron		+13%		|+5%		+20%
-+# Bulldozer		-0%		|-1%		+10%
-+# P4			+11%		|+7%		+8%
-+# Westmere		+5%		|+14%		+17%
-+# Sandy Bridge		+2%		|+12%		+29%
-+# Ivy Bridge		+1%		|+11%		+35%
-+# Haswell(**)		-0%		|+12%		+39%
-+# Atom			+13%		|+11%		+4%
-+# VIA Nano		+70%		|+9%		+25%
-+#
-+# (*)	rsax engine and fips numbers are presented for reference
-+#	purposes;
-+# (**)	MULX was attempted, but found to give only marginal improvement;
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$addx = ($1>=2.23);
-+}
-+
-+if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	    `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$addx = ($1>=2.10);
-+}
-+
-+if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	    `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$addx = ($1>=12);
-+}
-+
-+if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) {
-+	my $ver = $2 + $3/100.0;	# 3.1->3.01, 3.10->3.10
-+	$addx = ($ver>=3.03);
-+}
-+
-+($out, $inp, $mod) = ("%rdi", "%rsi", "%rbp");	# common internal API
-+{
-+my ($out,$inp,$mod,$n0,$times) = ("%rdi","%rsi","%rdx","%rcx","%r8d");
-+
-+$code.=<<___;
-+.text
-+
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	rsaz_512_sqr
-+.type	rsaz_512_sqr,\@function,5
-+.align	32
-+rsaz_512_sqr:				# 25-29% faster than rsaz_512_mul
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	subq	\$128+24, %rsp
-+.Lsqr_body:
-+	movq	$mod, %rbp		# common argument
-+	movq	($inp), %rdx
-+	movq	8($inp), %rax
-+	movq	$n0, 128(%rsp)
-+___
-+$code.=<<___ if ($addx);
-+	movl	\$0x80100,%r11d
-+	andl	OPENSSL_ia32cap_P+8(%rip),%r11d
-+	cmpl	\$0x80100,%r11d		# check for MULX and ADO/CX
-+	je	.Loop_sqrx
-+___
-+$code.=<<___;
-+	jmp	.Loop_sqr
-+
-+.align	32
-+.Loop_sqr:
-+	movl	$times,128+8(%rsp)
-+#first iteration
-+	movq	%rdx, %rbx
-+	mulq	%rdx
-+	movq	%rax, %r8
-+	movq	16($inp), %rax
-+	movq	%rdx, %r9
-+
-+	mulq	%rbx
-+	addq	%rax, %r9
-+	movq	24($inp), %rax
-+	movq	%rdx, %r10
-+	adcq	\$0, %r10
-+
-+	mulq	%rbx
-+	addq	%rax, %r10
-+	movq	32($inp), %rax
-+	movq	%rdx, %r11
-+	adcq	\$0, %r11
-+
-+	mulq	%rbx
-+	addq	%rax, %r11
-+	movq	40($inp), %rax
-+	movq	%rdx, %r12
-+	adcq	\$0, %r12
-+
-+	mulq	%rbx
-+	addq	%rax, %r12
-+	movq	48($inp), %rax
-+	movq	%rdx, %r13
-+	adcq	\$0, %r13
-+
-+	mulq	%rbx
-+	addq	%rax, %r13
-+	movq	56($inp), %rax
-+	movq	%rdx, %r14
-+	adcq	\$0, %r14
-+
-+	mulq	%rbx
-+	addq	%rax, %r14
-+	movq	%rbx, %rax
-+	movq	%rdx, %r15
-+	adcq	\$0, %r15
-+
-+	addq	%r8, %r8		#shlq	\$1, %r8
-+	movq	%r9, %rcx
-+	adcq	%r9, %r9		#shld	\$1, %r8, %r9
-+
-+	mulq	%rax
-+	movq	%rax, (%rsp)
-+	addq	%rdx, %r8
-+	adcq	\$0, %r9
-+
-+	movq	%r8, 8(%rsp)
-+	shrq	\$63, %rcx
-+
-+#second iteration
-+	movq	8($inp), %r8
-+	movq	16($inp), %rax
-+	mulq	%r8
-+	addq	%rax, %r10
-+	movq	24($inp), %rax
-+	movq	%rdx, %rbx
-+	adcq	\$0, %rbx
-+
-+	mulq	%r8
-+	addq	%rax, %r11
-+	movq	32($inp), %rax
-+	adcq	\$0, %rdx
-+	addq	%rbx, %r11
-+	movq	%rdx, %rbx
-+	adcq	\$0, %rbx
-+
-+	mulq	%r8
-+	addq	%rax, %r12
-+	movq	40($inp), %rax
-+	adcq	\$0, %rdx
-+	addq	%rbx, %r12
-+	movq	%rdx, %rbx
-+	adcq	\$0, %rbx
-+
-+	mulq	%r8
-+	addq	%rax, %r13
-+	movq	48($inp), %rax
-+	adcq	\$0, %rdx
-+	addq	%rbx, %r13
-+	movq	%rdx, %rbx
-+	adcq	\$0, %rbx
-+
-+	mulq	%r8
-+	addq	%rax, %r14
-+	movq	56($inp), %rax
-+	adcq	\$0, %rdx
-+	addq	%rbx, %r14
-+	movq	%rdx, %rbx
-+	adcq	\$0, %rbx
-+
-+	mulq	%r8
-+	addq	%rax, %r15
-+	movq	%r8, %rax
-+	adcq	\$0, %rdx
-+	addq	%rbx, %r15
-+	movq	%rdx, %r8
-+	movq	%r10, %rdx
-+	adcq	\$0, %r8
-+
-+	add	%rdx, %rdx
-+	lea	(%rcx,%r10,2), %r10	#shld	\$1, %rcx, %r10
-+	movq	%r11, %rbx
-+	adcq	%r11, %r11		#shld	\$1, %r10, %r11
-+
-+	mulq	%rax
-+	addq	%rax, %r9
-+	adcq	%rdx, %r10
-+	adcq	\$0, %r11
-+
-+	movq	%r9, 16(%rsp)
-+	movq	%r10, 24(%rsp)
-+	shrq	\$63, %rbx
-+	
-+#third iteration
-+	movq	16($inp), %r9	
-+	movq	24($inp), %rax
-+	mulq	%r9
-+	addq	%rax, %r12
-+	movq	32($inp), %rax
-+	movq	%rdx, %rcx
-+	adcq	\$0, %rcx
-+
-+	mulq	%r9
-+	addq	%rax, %r13
-+	movq	40($inp), %rax
-+	adcq	\$0, %rdx
-+	addq	%rcx, %r13
-+	movq	%rdx, %rcx
-+	adcq	\$0, %rcx
-+
-+	mulq	%r9
-+	addq	%rax, %r14
-+	movq	48($inp), %rax
-+	adcq	\$0, %rdx
-+	addq	%rcx, %r14
-+	movq	%rdx, %rcx
-+	adcq	\$0, %rcx
-+
-+	mulq	%r9
-+	 movq	%r12, %r10
-+	 lea	(%rbx,%r12,2), %r12	#shld	\$1, %rbx, %r12
-+	addq	%rax, %r15
-+	movq	56($inp), %rax
-+	adcq	\$0, %rdx
-+	addq	%rcx, %r15
-+	movq	%rdx, %rcx
-+	adcq	\$0, %rcx
-+
-+	mulq	%r9
-+	 shrq	\$63, %r10
-+	addq	%rax, %r8
-+	movq	%r9, %rax
-+	adcq	\$0, %rdx
-+	addq	%rcx, %r8
-+	movq	%rdx, %r9
-+	adcq	\$0, %r9
-+
-+	movq	%r13, %rcx
-+	leaq	(%r10,%r13,2), %r13	#shld	\$1, %r12, %r13
-+
-+	mulq	%rax
-+	addq	%rax, %r11
-+	adcq	%rdx, %r12
-+	adcq	\$0, %r13
-+
-+	movq	%r11, 32(%rsp)
-+	movq	%r12, 40(%rsp)
-+	shrq	\$63, %rcx
-+
-+#fourth iteration
-+	movq	24($inp), %r10
-+	movq	32($inp), %rax
-+	mulq	%r10
-+	addq	%rax, %r14
-+	movq	40($inp), %rax
-+	movq	%rdx, %rbx
-+	adcq	\$0, %rbx
-+
-+	mulq	%r10
-+	addq	%rax, %r15
-+	movq	48($inp), %rax
-+	adcq	\$0, %rdx
-+	addq	%rbx, %r15
-+	movq	%rdx, %rbx
-+	adcq	\$0, %rbx
-+
-+	mulq	%r10
-+	 movq	%r14, %r12
-+	 leaq	(%rcx,%r14,2), %r14	#shld	\$1, %rcx, %r14
-+	addq	%rax, %r8
-+	movq	56($inp), %rax
-+	adcq	\$0, %rdx
-+	addq	%rbx, %r8
-+	movq	%rdx, %rbx
-+	adcq	\$0, %rbx
-+
-+	mulq	%r10
-+	 shrq	\$63, %r12
-+	addq	%rax, %r9
-+	movq	%r10, %rax
-+	adcq	\$0, %rdx
-+	addq	%rbx, %r9
-+	movq	%rdx, %r10
-+	adcq	\$0, %r10
-+
-+	movq	%r15, %rbx
-+	leaq	(%r12,%r15,2),%r15	#shld	\$1, %r14, %r15
-+
-+	mulq	%rax
-+	addq	%rax, %r13
-+	adcq	%rdx, %r14
-+	adcq	\$0, %r15
-+
-+	movq	%r13, 48(%rsp)
-+	movq	%r14, 56(%rsp)
-+	shrq	\$63, %rbx
-+
-+#fifth iteration
-+	movq	32($inp), %r11
-+	movq	40($inp), %rax
-+	mulq	%r11
-+	addq	%rax, %r8
-+	movq	48($inp), %rax
-+	movq	%rdx, %rcx
-+	adcq	\$0, %rcx
-+
-+	mulq	%r11
-+	addq	%rax, %r9
-+	movq	56($inp), %rax
-+	adcq	\$0, %rdx
-+	 movq	%r8, %r12
-+	 leaq	(%rbx,%r8,2), %r8	#shld	\$1, %rbx, %r8
-+	addq	%rcx, %r9
-+	movq	%rdx, %rcx
-+	adcq	\$0, %rcx
-+
-+	mulq	%r11
-+	 shrq	\$63, %r12
-+	addq	%rax, %r10
-+	movq	%r11, %rax
-+	adcq	\$0, %rdx
-+	addq	%rcx, %r10
-+	movq	%rdx, %r11
-+	adcq	\$0, %r11
-+
-+	movq	%r9, %rcx
-+	leaq	(%r12,%r9,2), %r9	#shld	\$1, %r8, %r9
-+
-+	mulq	%rax
-+	addq	%rax, %r15
-+	adcq	%rdx, %r8
-+	adcq	\$0, %r9
-+
-+	movq	%r15, 64(%rsp)
-+	movq	%r8, 72(%rsp)
-+	shrq	\$63, %rcx
-+
-+#sixth iteration
-+	movq	40($inp), %r12
-+	movq	48($inp), %rax
-+	mulq	%r12
-+	addq	%rax, %r10
-+	movq	56($inp), %rax
-+	movq	%rdx, %rbx
-+	adcq	\$0, %rbx
-+
-+	mulq	%r12
-+	addq	%rax, %r11
-+	movq	%r12, %rax
-+	 movq	%r10, %r15
-+	 leaq	(%rcx,%r10,2), %r10	#shld	\$1, %rcx, %r10
-+	adcq	\$0, %rdx
-+	 shrq	\$63, %r15
-+	addq	%rbx, %r11
-+	movq	%rdx, %r12
-+	adcq	\$0, %r12
-+
-+	movq	%r11, %rbx
-+	leaq	(%r15,%r11,2), %r11	#shld	\$1, %r10, %r11
-+
-+	mulq	%rax
-+	addq	%rax, %r9
-+	adcq	%rdx, %r10
-+	adcq	\$0, %r11
-+
-+	movq	%r9, 80(%rsp)
-+	movq	%r10, 88(%rsp)
-+
-+#seventh iteration
-+	movq	48($inp), %r13
-+	movq	56($inp), %rax
-+	mulq	%r13
-+	addq	%rax, %r12
-+	movq	%r13, %rax
-+	movq	%rdx, %r13
-+	adcq	\$0, %r13
-+
-+	xorq	%r14, %r14
-+	shlq	\$1, %rbx
-+	adcq	%r12, %r12		#shld	\$1, %rbx, %r12
-+	adcq	%r13, %r13		#shld	\$1, %r12, %r13
-+	adcq	%r14, %r14		#shld	\$1, %r13, %r14
-+
-+	mulq	%rax
-+	addq	%rax, %r11
-+	adcq	%rdx, %r12
-+	adcq	\$0, %r13
-+
-+	movq	%r11, 96(%rsp)
-+	movq	%r12, 104(%rsp)
-+
-+#eighth iteration
-+	movq	56($inp), %rax
-+	mulq	%rax
-+	addq	%rax, %r13
-+	adcq	\$0, %rdx
-+
-+	addq	%rdx, %r14
-+
-+	movq	%r13, 112(%rsp)
-+	movq	%r14, 120(%rsp)
-+
-+	movq	(%rsp), %r8
-+	movq	8(%rsp), %r9
-+	movq	16(%rsp), %r10
-+	movq	24(%rsp), %r11
-+	movq	32(%rsp), %r12
-+	movq	40(%rsp), %r13
-+	movq	48(%rsp), %r14
-+	movq	56(%rsp), %r15
-+
-+	call	__rsaz_512_reduce
-+
-+	addq	64(%rsp), %r8
-+	adcq	72(%rsp), %r9
-+	adcq	80(%rsp), %r10
-+	adcq	88(%rsp), %r11
-+	adcq	96(%rsp), %r12
-+	adcq	104(%rsp), %r13
-+	adcq	112(%rsp), %r14
-+	adcq	120(%rsp), %r15
-+	sbbq	%rcx, %rcx
-+
-+	call	__rsaz_512_subtract
-+
-+	movq	%r8, %rdx
-+	movq	%r9, %rax
-+	movl	128+8(%rsp), $times
-+	movq	$out, $inp
-+
-+	decl	$times
-+	jnz	.Loop_sqr
-+___
-+if ($addx) {
-+$code.=<<___;
-+	jmp	.Lsqr_tail
-+
-+.align	32
-+.Loop_sqrx:
-+	movl	$times,128+8(%rsp)
-+	movq	$out, %xmm0		# off-load
-+	movq	%rbp, %xmm1		# off-load
-+#first iteration	
-+	mulx	%rax, %r8, %r9
-+
-+	mulx	16($inp), %rcx, %r10
-+	xor	%rbp, %rbp		# cf=0, of=0
-+
-+	mulx	24($inp), %rax, %r11
-+	adcx	%rcx, %r9
-+
-+	mulx	32($inp), %rcx, %r12
-+	adcx	%rax, %r10
-+
-+	mulx	40($inp), %rax, %r13
-+	adcx	%rcx, %r11
-+
-+	.byte	0xc4,0x62,0xf3,0xf6,0xb6,0x30,0x00,0x00,0x00	# mulx	48($inp), %rcx, %r14
-+	adcx	%rax, %r12
-+	adcx	%rcx, %r13
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0xbe,0x38,0x00,0x00,0x00	# mulx	56($inp), %rax, %r15
-+	adcx	%rax, %r14
-+	adcx	%rbp, %r15		# %rbp is 0
-+
-+	mov	%r9, %rcx
-+	shld	\$1, %r8, %r9
-+	shl	\$1, %r8
-+
-+	xor	%ebp, %ebp
-+	mulx	%rdx, %rax, %rdx
-+	adcx	%rdx, %r8
-+	 mov	8($inp), %rdx
-+	adcx	%rbp, %r9
-+
-+	mov	%rax, (%rsp)
-+	mov	%r8, 8(%rsp)
-+
-+#second iteration	
-+	mulx	16($inp), %rax, %rbx
-+	adox	%rax, %r10
-+	adcx	%rbx, %r11
-+
-+	.byte	0xc4,0x62,0xc3,0xf6,0x86,0x18,0x00,0x00,0x00	# mulx	24($inp), $out, %r8
-+	adox	$out, %r11
-+	adcx	%r8, %r12
-+
-+	mulx	32($inp), %rax, %rbx
-+	adox	%rax, %r12
-+	adcx	%rbx, %r13
-+
-+	mulx	40($inp), $out, %r8
-+	adox	$out, %r13
-+	adcx	%r8, %r14
-+
-+	.byte	0xc4,0xe2,0xfb,0xf6,0x9e,0x30,0x00,0x00,0x00	# mulx	48($inp), %rax, %rbx
-+	adox	%rax, %r14
-+	adcx	%rbx, %r15
-+
-+	.byte	0xc4,0x62,0xc3,0xf6,0x86,0x38,0x00,0x00,0x00	# mulx	56($inp), $out, %r8
-+	adox	$out, %r15
-+	adcx	%rbp, %r8
-+	adox	%rbp, %r8
-+
-+	mov	%r11, %rbx
-+	shld	\$1, %r10, %r11
-+	shld	\$1, %rcx, %r10
-+
-+	xor	%ebp,%ebp
-+	mulx	%rdx, %rax, %rcx
-+	 mov	16($inp), %rdx
-+	adcx	%rax, %r9
-+	adcx	%rcx, %r10
-+	adcx	%rbp, %r11
-+
-+	mov	%r9, 16(%rsp)
-+	.byte	0x4c,0x89,0x94,0x24,0x18,0x00,0x00,0x00		# mov	%r10, 24(%rsp)
-+	
-+#third iteration	
-+	.byte	0xc4,0x62,0xc3,0xf6,0x8e,0x18,0x00,0x00,0x00	# mulx	24($inp), $out, %r9
-+	adox	$out, %r12
-+	adcx	%r9, %r13
-+
-+	mulx	32($inp), %rax, %rcx
-+	adox	%rax, %r13
-+	adcx	%rcx, %r14
-+
-+	mulx	40($inp), $out, %r9
-+	adox	$out, %r14
-+	adcx	%r9, %r15
-+
-+	.byte	0xc4,0xe2,0xfb,0xf6,0x8e,0x30,0x00,0x00,0x00	# mulx	48($inp), %rax, %rcx
-+	adox	%rax, %r15
-+	adcx	%rcx, %r8
-+
-+	.byte	0xc4,0x62,0xc3,0xf6,0x8e,0x38,0x00,0x00,0x00	# mulx	56($inp), $out, %r9
-+	adox	$out, %r8
-+	adcx	%rbp, %r9
-+	adox	%rbp, %r9
-+
-+	mov	%r13, %rcx
-+	shld	\$1, %r12, %r13
-+	shld	\$1, %rbx, %r12
-+
-+	xor	%ebp, %ebp
-+	mulx	%rdx, %rax, %rdx
-+	adcx	%rax, %r11
-+	adcx	%rdx, %r12
-+	 mov	24($inp), %rdx
-+	adcx	%rbp, %r13
-+
-+	mov	%r11, 32(%rsp)
-+	.byte	0x4c,0x89,0xa4,0x24,0x28,0x00,0x00,0x00		# mov	%r12, 40(%rsp)
-+	
-+#fourth iteration	
-+	.byte	0xc4,0xe2,0xfb,0xf6,0x9e,0x20,0x00,0x00,0x00	# mulx	32($inp), %rax, %rbx
-+	adox	%rax, %r14
-+	adcx	%rbx, %r15
-+
-+	mulx	40($inp), $out, %r10
-+	adox	$out, %r15
-+	adcx	%r10, %r8
-+
-+	mulx	48($inp), %rax, %rbx
-+	adox	%rax, %r8
-+	adcx	%rbx, %r9
-+
-+	mulx	56($inp), $out, %r10
-+	adox	$out, %r9
-+	adcx	%rbp, %r10
-+	adox	%rbp, %r10
-+
-+	.byte	0x66
-+	mov	%r15, %rbx
-+	shld	\$1, %r14, %r15
-+	shld	\$1, %rcx, %r14
-+
-+	xor	%ebp, %ebp
-+	mulx	%rdx, %rax, %rdx
-+	adcx	%rax, %r13
-+	adcx	%rdx, %r14
-+	 mov	32($inp), %rdx
-+	adcx	%rbp, %r15
-+
-+	mov	%r13, 48(%rsp)
-+	mov	%r14, 56(%rsp)
-+	
-+#fifth iteration	
-+	.byte	0xc4,0x62,0xc3,0xf6,0x9e,0x28,0x00,0x00,0x00	# mulx	40($inp), $out, %r11
-+	adox	$out, %r8
-+	adcx	%r11, %r9
-+
-+	mulx	48($inp), %rax, %rcx
-+	adox	%rax, %r9
-+	adcx	%rcx, %r10
-+
-+	mulx	56($inp), $out, %r11
-+	adox	$out, %r10
-+	adcx	%rbp, %r11
-+	adox	%rbp, %r11
-+
-+	mov	%r9, %rcx
-+	shld	\$1, %r8, %r9
-+	shld	\$1, %rbx, %r8
-+
-+	xor	%ebp, %ebp
-+	mulx	%rdx, %rax, %rdx
-+	adcx	%rax, %r15
-+	adcx	%rdx, %r8
-+	 mov	40($inp), %rdx
-+	adcx	%rbp, %r9
-+
-+	mov	%r15, 64(%rsp)
-+	mov	%r8, 72(%rsp)
-+	
-+#sixth iteration	
-+	.byte	0xc4,0xe2,0xfb,0xf6,0x9e,0x30,0x00,0x00,0x00	# mulx	48($inp), %rax, %rbx
-+	adox	%rax, %r10
-+	adcx	%rbx, %r11
-+
-+	.byte	0xc4,0x62,0xc3,0xf6,0xa6,0x38,0x00,0x00,0x00	# mulx	56($inp), $out, %r12
-+	adox	$out, %r11
-+	adcx	%rbp, %r12
-+	adox	%rbp, %r12
-+
-+	mov	%r11, %rbx
-+	shld	\$1, %r10, %r11
-+	shld	\$1, %rcx, %r10
-+
-+	xor	%ebp, %ebp
-+	mulx	%rdx, %rax, %rdx
-+	adcx	%rax, %r9
-+	adcx	%rdx, %r10
-+	 mov	48($inp), %rdx
-+	adcx	%rbp, %r11
-+
-+	mov	%r9, 80(%rsp)
-+	mov	%r10, 88(%rsp)
-+
-+#seventh iteration
-+	.byte	0xc4,0x62,0xfb,0xf6,0xae,0x38,0x00,0x00,0x00	# mulx	56($inp), %rax, %r13
-+	adox	%rax, %r12
-+	adox	%rbp, %r13
-+
-+	xor	%r14, %r14
-+	shld	\$1, %r13, %r14
-+	shld	\$1, %r12, %r13
-+	shld	\$1, %rbx, %r12
-+
-+	xor	%ebp, %ebp
-+	mulx	%rdx, %rax, %rdx
-+	adcx	%rax, %r11
-+	adcx	%rdx, %r12
-+	 mov	56($inp), %rdx
-+	adcx	%rbp, %r13
-+
-+	.byte	0x4c,0x89,0x9c,0x24,0x60,0x00,0x00,0x00		# mov	%r11, 96(%rsp)
-+	.byte	0x4c,0x89,0xa4,0x24,0x68,0x00,0x00,0x00		# mov	%r12, 104(%rsp)
-+
-+#eighth iteration
-+	mulx	%rdx, %rax, %rdx
-+	adox	%rax, %r13
-+	adox	%rbp, %rdx
-+
-+	.byte	0x66
-+	add	%rdx, %r14
-+
-+	movq	%r13, 112(%rsp)
-+	movq	%r14, 120(%rsp)
-+	movq	%xmm0, $out
-+	movq	%xmm1, %rbp
-+
-+	movq	128(%rsp), %rdx		# pull $n0
-+	movq	(%rsp), %r8
-+	movq	8(%rsp), %r9
-+	movq	16(%rsp), %r10
-+	movq	24(%rsp), %r11
-+	movq	32(%rsp), %r12
-+	movq	40(%rsp), %r13
-+	movq	48(%rsp), %r14
-+	movq	56(%rsp), %r15
-+
-+	call	__rsaz_512_reducex
-+
-+	addq	64(%rsp), %r8
-+	adcq	72(%rsp), %r9
-+	adcq	80(%rsp), %r10
-+	adcq	88(%rsp), %r11
-+	adcq	96(%rsp), %r12
-+	adcq	104(%rsp), %r13
-+	adcq	112(%rsp), %r14
-+	adcq	120(%rsp), %r15
-+	sbbq	%rcx, %rcx
-+
-+	call	__rsaz_512_subtract
-+
-+	movq	%r8, %rdx
-+	movq	%r9, %rax
-+	movl	128+8(%rsp), $times
-+	movq	$out, $inp
-+
-+	decl	$times
-+	jnz	.Loop_sqrx
-+
-+.Lsqr_tail:
-+___
-+}
-+$code.=<<___;
-+
-+	leaq	128+24+48(%rsp), %rax
-+	movq	-48(%rax), %r15
-+	movq	-40(%rax), %r14
-+	movq	-32(%rax), %r13
-+	movq	-24(%rax), %r12
-+	movq	-16(%rax), %rbp
-+	movq	-8(%rax), %rbx
-+	leaq	(%rax), %rsp
-+.Lsqr_epilogue:
-+	ret
-+.size	rsaz_512_sqr,.-rsaz_512_sqr
-+___
-+}
-+{
-+my ($out,$ap,$bp,$mod,$n0) = ("%rdi","%rsi","%rdx","%rcx","%r8");
-+$code.=<<___;
-+.globl	rsaz_512_mul
-+.type	rsaz_512_mul,\@function,5
-+.align	32
-+rsaz_512_mul:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	subq	\$128+24, %rsp
-+.Lmul_body:
-+	movq	$out, %xmm0		# off-load arguments
-+	movq	$mod, %xmm1
-+	movq	$n0, 128(%rsp)
-+___
-+$code.=<<___ if ($addx);
-+	movl	\$0x80100,%r11d
-+	andl	OPENSSL_ia32cap_P+8(%rip),%r11d
-+	cmpl	\$0x80100,%r11d		# check for MULX and ADO/CX
-+	je	.Lmulx
-+___
-+$code.=<<___;
-+	movq	($bp), %rbx		# pass b[0]
-+	movq	$bp, %rbp		# pass argument
-+	call	__rsaz_512_mul
-+
-+	movq	%xmm0, $out
-+	movq	%xmm1, %rbp
-+
-+	movq	(%rsp), %r8
-+	movq	8(%rsp), %r9
-+	movq	16(%rsp), %r10
-+	movq	24(%rsp), %r11
-+	movq	32(%rsp), %r12
-+	movq	40(%rsp), %r13
-+	movq	48(%rsp), %r14
-+	movq	56(%rsp), %r15
-+
-+	call	__rsaz_512_reduce
-+___
-+$code.=<<___ if ($addx);
-+	jmp	.Lmul_tail
-+
-+.align	32
-+.Lmulx:
-+	movq	$bp, %rbp		# pass argument
-+	movq	($bp), %rdx		# pass b[0]
-+	call	__rsaz_512_mulx
-+
-+	movq	%xmm0, $out
-+	movq	%xmm1, %rbp
-+
-+	movq	128(%rsp), %rdx		# pull $n0
-+	movq	(%rsp), %r8
-+	movq	8(%rsp), %r9
-+	movq	16(%rsp), %r10
-+	movq	24(%rsp), %r11
-+	movq	32(%rsp), %r12
-+	movq	40(%rsp), %r13
-+	movq	48(%rsp), %r14
-+	movq	56(%rsp), %r15
-+
-+	call	__rsaz_512_reducex
-+.Lmul_tail:
-+___
-+$code.=<<___;
-+	addq	64(%rsp), %r8
-+	adcq	72(%rsp), %r9
-+	adcq	80(%rsp), %r10
-+	adcq	88(%rsp), %r11
-+	adcq	96(%rsp), %r12
-+	adcq	104(%rsp), %r13
-+	adcq	112(%rsp), %r14
-+	adcq	120(%rsp), %r15
-+	sbbq	%rcx, %rcx
-+
-+	call	__rsaz_512_subtract
-+
-+	leaq	128+24+48(%rsp), %rax
-+	movq	-48(%rax), %r15
-+	movq	-40(%rax), %r14
-+	movq	-32(%rax), %r13
-+	movq	-24(%rax), %r12
-+	movq	-16(%rax), %rbp
-+	movq	-8(%rax), %rbx
-+	leaq	(%rax), %rsp
-+.Lmul_epilogue:
-+	ret
-+.size	rsaz_512_mul,.-rsaz_512_mul
-+___
-+}
-+{
-+my ($out,$ap,$bp,$mod,$n0,$pwr) = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9d");
-+$code.=<<___;
-+.globl	rsaz_512_mul_gather4
-+.type	rsaz_512_mul_gather4,\@function,6
-+.align	32
-+rsaz_512_mul_gather4:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	subq	\$`128+24+($win64?0xb0:0)`, %rsp
-+___
-+$code.=<<___	if ($win64);
-+	movaps	%xmm6,0xa0(%rsp)
-+	movaps	%xmm7,0xb0(%rsp)
-+	movaps	%xmm8,0xc0(%rsp)
-+	movaps	%xmm9,0xd0(%rsp)
-+	movaps	%xmm10,0xe0(%rsp)
-+	movaps	%xmm11,0xf0(%rsp)
-+	movaps	%xmm12,0x100(%rsp)
-+	movaps	%xmm13,0x110(%rsp)
-+	movaps	%xmm14,0x120(%rsp)
-+	movaps	%xmm15,0x130(%rsp)
-+___
-+$code.=<<___;
-+.Lmul_gather4_body:
-+	movd	$pwr,%xmm8
-+	movdqa	.Linc+16(%rip),%xmm1	# 00000002000000020000000200000002
-+	movdqa	.Linc(%rip),%xmm0	# 00000001000000010000000000000000
-+
-+	pshufd	\$0,%xmm8,%xmm8		# broadcast $power
-+	movdqa	%xmm1,%xmm7
-+	movdqa	%xmm1,%xmm2
-+___
-+########################################################################
-+# calculate mask by comparing 0..15 to $power
-+#
-+for($i=0;$i<4;$i++) {
-+$code.=<<___;
-+	paddd	%xmm`$i`,%xmm`$i+1`
-+	pcmpeqd	%xmm8,%xmm`$i`
-+	movdqa	%xmm7,%xmm`$i+3`
-+___
-+}
-+for(;$i<7;$i++) {
-+$code.=<<___;
-+	paddd	%xmm`$i`,%xmm`$i+1`
-+	pcmpeqd	%xmm8,%xmm`$i`
-+___
-+}
-+$code.=<<___;
-+	pcmpeqd	%xmm8,%xmm7
-+
-+	movdqa	16*0($bp),%xmm8
-+	movdqa	16*1($bp),%xmm9
-+	movdqa	16*2($bp),%xmm10
-+	movdqa	16*3($bp),%xmm11
-+	pand	%xmm0,%xmm8
-+	movdqa	16*4($bp),%xmm12
-+	pand	%xmm1,%xmm9
-+	movdqa	16*5($bp),%xmm13
-+	pand	%xmm2,%xmm10
-+	movdqa	16*6($bp),%xmm14
-+	pand	%xmm3,%xmm11
-+	movdqa	16*7($bp),%xmm15
-+	leaq	128($bp), %rbp
-+	pand	%xmm4,%xmm12
-+	pand	%xmm5,%xmm13
-+	pand	%xmm6,%xmm14
-+	pand	%xmm7,%xmm15
-+	por	%xmm10,%xmm8
-+	por	%xmm11,%xmm9
-+	por	%xmm12,%xmm8
-+	por	%xmm13,%xmm9
-+	por	%xmm14,%xmm8
-+	por	%xmm15,%xmm9
-+
-+	por	%xmm9,%xmm8
-+	pshufd	\$0x4e,%xmm8,%xmm9
-+	por	%xmm9,%xmm8
-+___
-+$code.=<<___ if ($addx);
-+	movl	\$0x80100,%r11d
-+	andl	OPENSSL_ia32cap_P+8(%rip),%r11d
-+	cmpl	\$0x80100,%r11d		# check for MULX and ADO/CX
-+	je	.Lmulx_gather
-+___
-+$code.=<<___;
-+	movq	%xmm8,%rbx
-+
-+	movq	$n0, 128(%rsp)		# off-load arguments
-+	movq	$out, 128+8(%rsp)
-+	movq	$mod, 128+16(%rsp)
-+
-+	movq	($ap), %rax
-+	 movq	8($ap), %rcx
-+	mulq	%rbx			# 0 iteration
-+	movq	%rax, (%rsp)
-+	movq	%rcx, %rax
-+	movq	%rdx, %r8
-+
-+	mulq	%rbx
-+	addq	%rax, %r8
-+	movq	16($ap), %rax
-+	movq	%rdx, %r9
-+	adcq	\$0, %r9
-+
-+	mulq	%rbx
-+	addq	%rax, %r9
-+	movq	24($ap), %rax
-+	movq	%rdx, %r10
-+	adcq	\$0, %r10
-+
-+	mulq	%rbx
-+	addq	%rax, %r10
-+	movq	32($ap), %rax
-+	movq	%rdx, %r11
-+	adcq	\$0, %r11
-+
-+	mulq	%rbx
-+	addq	%rax, %r11
-+	movq	40($ap), %rax
-+	movq	%rdx, %r12
-+	adcq	\$0, %r12
-+
-+	mulq	%rbx
-+	addq	%rax, %r12
-+	movq	48($ap), %rax
-+	movq	%rdx, %r13
-+	adcq	\$0, %r13
-+
-+	mulq	%rbx
-+	addq	%rax, %r13
-+	movq	56($ap), %rax
-+	movq	%rdx, %r14
-+	adcq	\$0, %r14
-+	
-+	mulq	%rbx
-+	addq	%rax, %r14
-+	 movq	($ap), %rax
-+	movq	%rdx, %r15
-+	adcq	\$0, %r15
-+
-+	leaq	8(%rsp), %rdi
-+	movl	\$7, %ecx
-+	jmp	.Loop_mul_gather
-+
-+.align	32
-+.Loop_mul_gather:
-+	movdqa	16*0(%rbp),%xmm8
-+	movdqa	16*1(%rbp),%xmm9
-+	movdqa	16*2(%rbp),%xmm10
-+	movdqa	16*3(%rbp),%xmm11
-+	pand	%xmm0,%xmm8
-+	movdqa	16*4(%rbp),%xmm12
-+	pand	%xmm1,%xmm9
-+	movdqa	16*5(%rbp),%xmm13
-+	pand	%xmm2,%xmm10
-+	movdqa	16*6(%rbp),%xmm14
-+	pand	%xmm3,%xmm11
-+	movdqa	16*7(%rbp),%xmm15
-+	leaq	128(%rbp), %rbp
-+	pand	%xmm4,%xmm12
-+	pand	%xmm5,%xmm13
-+	pand	%xmm6,%xmm14
-+	pand	%xmm7,%xmm15
-+	por	%xmm10,%xmm8
-+	por	%xmm11,%xmm9
-+	por	%xmm12,%xmm8
-+	por	%xmm13,%xmm9
-+	por	%xmm14,%xmm8
-+	por	%xmm15,%xmm9
-+
-+	por	%xmm9,%xmm8
-+	pshufd	\$0x4e,%xmm8,%xmm9
-+	por	%xmm9,%xmm8
-+	movq	%xmm8,%rbx
-+
-+	mulq	%rbx
-+	addq	%rax, %r8
-+	movq	8($ap), %rax
-+	movq	%r8, (%rdi)
-+	movq	%rdx, %r8
-+	adcq	\$0, %r8
-+
-+	mulq	%rbx
-+	addq	%rax, %r9
-+	movq	16($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r9, %r8
-+	movq	%rdx, %r9
-+	adcq	\$0, %r9
-+
-+	mulq	%rbx
-+	addq	%rax, %r10
-+	movq	24($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r10, %r9
-+	movq	%rdx, %r10
-+	adcq	\$0, %r10
-+
-+	mulq	%rbx
-+	addq	%rax, %r11
-+	movq	32($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r11, %r10
-+	movq	%rdx, %r11
-+	adcq	\$0, %r11
-+
-+	mulq	%rbx
-+	addq	%rax, %r12
-+	movq	40($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r12, %r11
-+	movq	%rdx, %r12
-+	adcq	\$0, %r12
-+
-+	mulq	%rbx
-+	addq	%rax, %r13
-+	movq	48($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r13, %r12
-+	movq	%rdx, %r13
-+	adcq	\$0, %r13
-+
-+	mulq	%rbx
-+	addq	%rax, %r14
-+	movq	56($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r14, %r13
-+	movq	%rdx, %r14
-+	adcq	\$0, %r14
-+
-+	mulq	%rbx
-+	addq	%rax, %r15
-+	 movq	($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r15, %r14
-+	movq	%rdx, %r15	
-+	adcq	\$0, %r15
-+
-+	leaq	8(%rdi), %rdi
-+
-+	decl	%ecx
-+	jnz	.Loop_mul_gather
-+
-+	movq	%r8, (%rdi)
-+	movq	%r9, 8(%rdi)
-+	movq	%r10, 16(%rdi)
-+	movq	%r11, 24(%rdi)
-+	movq	%r12, 32(%rdi)
-+	movq	%r13, 40(%rdi)
-+	movq	%r14, 48(%rdi)
-+	movq	%r15, 56(%rdi)
-+
-+	movq	128+8(%rsp), $out
-+	movq	128+16(%rsp), %rbp
-+
-+	movq	(%rsp), %r8
-+	movq	8(%rsp), %r9
-+	movq	16(%rsp), %r10
-+	movq	24(%rsp), %r11
-+	movq	32(%rsp), %r12
-+	movq	40(%rsp), %r13
-+	movq	48(%rsp), %r14
-+	movq	56(%rsp), %r15
-+
-+	call	__rsaz_512_reduce
-+___
-+$code.=<<___ if ($addx);
-+	jmp	.Lmul_gather_tail
-+
-+.align	32
-+.Lmulx_gather:
-+	movq	%xmm8,%rdx
-+
-+	mov	$n0, 128(%rsp)		# off-load arguments
-+	mov	$out, 128+8(%rsp)
-+	mov	$mod, 128+16(%rsp)
-+
-+	mulx	($ap), %rbx, %r8	# 0 iteration
-+	mov	%rbx, (%rsp)
-+	xor	%edi, %edi		# cf=0, of=0
-+
-+	mulx	8($ap), %rax, %r9
-+
-+	mulx	16($ap), %rbx, %r10
-+	adcx	%rax, %r8
-+
-+	mulx	24($ap), %rax, %r11
-+	adcx	%rbx, %r9
-+
-+	mulx	32($ap), %rbx, %r12
-+	adcx	%rax, %r10
-+
-+	mulx	40($ap), %rax, %r13
-+	adcx	%rbx, %r11
-+
-+	mulx	48($ap), %rbx, %r14
-+	adcx	%rax, %r12
-+	
-+	mulx	56($ap), %rax, %r15
-+	adcx	%rbx, %r13
-+	adcx	%rax, %r14
-+	.byte	0x67
-+	mov	%r8, %rbx
-+	adcx	%rdi, %r15		# %rdi is 0
-+
-+	mov	\$-7, %rcx
-+	jmp	.Loop_mulx_gather
-+
-+.align	32
-+.Loop_mulx_gather:
-+	movdqa	16*0(%rbp),%xmm8
-+	movdqa	16*1(%rbp),%xmm9
-+	movdqa	16*2(%rbp),%xmm10
-+	movdqa	16*3(%rbp),%xmm11
-+	pand	%xmm0,%xmm8
-+	movdqa	16*4(%rbp),%xmm12
-+	pand	%xmm1,%xmm9
-+	movdqa	16*5(%rbp),%xmm13
-+	pand	%xmm2,%xmm10
-+	movdqa	16*6(%rbp),%xmm14
-+	pand	%xmm3,%xmm11
-+	movdqa	16*7(%rbp),%xmm15
-+	leaq	128(%rbp), %rbp
-+	pand	%xmm4,%xmm12
-+	pand	%xmm5,%xmm13
-+	pand	%xmm6,%xmm14
-+	pand	%xmm7,%xmm15
-+	por	%xmm10,%xmm8
-+	por	%xmm11,%xmm9
-+	por	%xmm12,%xmm8
-+	por	%xmm13,%xmm9
-+	por	%xmm14,%xmm8
-+	por	%xmm15,%xmm9
-+
-+	por	%xmm9,%xmm8
-+	pshufd	\$0x4e,%xmm8,%xmm9
-+	por	%xmm9,%xmm8
-+	movq	%xmm8,%rdx
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0x86,0x00,0x00,0x00,0x00	# mulx	($ap), %rax, %r8
-+	adcx	%rax, %rbx
-+	adox	%r9, %r8
-+
-+	mulx	8($ap), %rax, %r9
-+	adcx	%rax, %r8
-+	adox	%r10, %r9
-+
-+	mulx	16($ap), %rax, %r10
-+	adcx	%rax, %r9
-+	adox	%r11, %r10
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0x9e,0x18,0x00,0x00,0x00	# mulx	24($ap), %rax, %r11
-+	adcx	%rax, %r10
-+	adox	%r12, %r11
-+
-+	mulx	32($ap), %rax, %r12
-+	adcx	%rax, %r11
-+	adox	%r13, %r12
-+
-+	mulx	40($ap), %rax, %r13
-+	adcx	%rax, %r12
-+	adox	%r14, %r13
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0xb6,0x30,0x00,0x00,0x00	# mulx	48($ap), %rax, %r14
-+	adcx	%rax, %r13
-+	.byte	0x67
-+	adox	%r15, %r14
-+
-+	mulx	56($ap), %rax, %r15
-+	 mov	%rbx, 64(%rsp,%rcx,8)
-+	adcx	%rax, %r14
-+	adox	%rdi, %r15
-+	mov	%r8, %rbx
-+	adcx	%rdi, %r15		# cf=0
-+
-+	inc	%rcx			# of=0
-+	jnz	.Loop_mulx_gather
-+
-+	mov	%r8, 64(%rsp)
-+	mov	%r9, 64+8(%rsp)
-+	mov	%r10, 64+16(%rsp)
-+	mov	%r11, 64+24(%rsp)
-+	mov	%r12, 64+32(%rsp)
-+	mov	%r13, 64+40(%rsp)
-+	mov	%r14, 64+48(%rsp)
-+	mov	%r15, 64+56(%rsp)
-+
-+	mov	128(%rsp), %rdx		# pull arguments
-+	mov	128+8(%rsp), $out
-+	mov	128+16(%rsp), %rbp
-+
-+	mov	(%rsp), %r8
-+	mov	8(%rsp), %r9
-+	mov	16(%rsp), %r10
-+	mov	24(%rsp), %r11
-+	mov	32(%rsp), %r12
-+	mov	40(%rsp), %r13
-+	mov	48(%rsp), %r14
-+	mov	56(%rsp), %r15
-+
-+	call	__rsaz_512_reducex
-+
-+.Lmul_gather_tail:
-+___
-+$code.=<<___;
-+	addq	64(%rsp), %r8
-+	adcq	72(%rsp), %r9
-+	adcq	80(%rsp), %r10
-+	adcq	88(%rsp), %r11
-+	adcq	96(%rsp), %r12
-+	adcq	104(%rsp), %r13
-+	adcq	112(%rsp), %r14
-+	adcq	120(%rsp), %r15
-+	sbbq	%rcx, %rcx
-+
-+	call	__rsaz_512_subtract
-+
-+	leaq	128+24+48(%rsp), %rax
-+___
-+$code.=<<___	if ($win64);
-+	movaps	0xa0-0xc8(%rax),%xmm6
-+	movaps	0xb0-0xc8(%rax),%xmm7
-+	movaps	0xc0-0xc8(%rax),%xmm8
-+	movaps	0xd0-0xc8(%rax),%xmm9
-+	movaps	0xe0-0xc8(%rax),%xmm10
-+	movaps	0xf0-0xc8(%rax),%xmm11
-+	movaps	0x100-0xc8(%rax),%xmm12
-+	movaps	0x110-0xc8(%rax),%xmm13
-+	movaps	0x120-0xc8(%rax),%xmm14
-+	movaps	0x130-0xc8(%rax),%xmm15
-+	lea	0xb0(%rax),%rax
-+___
-+$code.=<<___;
-+	movq	-48(%rax), %r15
-+	movq	-40(%rax), %r14
-+	movq	-32(%rax), %r13
-+	movq	-24(%rax), %r12
-+	movq	-16(%rax), %rbp
-+	movq	-8(%rax), %rbx
-+	leaq	(%rax), %rsp
-+.Lmul_gather4_epilogue:
-+	ret
-+.size	rsaz_512_mul_gather4,.-rsaz_512_mul_gather4
-+___
-+}
-+{
-+my ($out,$ap,$mod,$n0,$tbl,$pwr) = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9d");
-+$code.=<<___;
-+.globl	rsaz_512_mul_scatter4
-+.type	rsaz_512_mul_scatter4,\@function,6
-+.align	32
-+rsaz_512_mul_scatter4:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	mov	$pwr, $pwr
-+	subq	\$128+24, %rsp
-+.Lmul_scatter4_body:
-+	leaq	($tbl,$pwr,8), $tbl
-+	movq	$out, %xmm0		# off-load arguments
-+	movq	$mod, %xmm1
-+	movq	$tbl, %xmm2
-+	movq	$n0, 128(%rsp)
-+
-+	movq	$out, %rbp
-+___
-+$code.=<<___ if ($addx);
-+	movl	\$0x80100,%r11d
-+	andl	OPENSSL_ia32cap_P+8(%rip),%r11d
-+	cmpl	\$0x80100,%r11d		# check for MULX and ADO/CX
-+	je	.Lmulx_scatter
-+___
-+$code.=<<___;
-+	movq	($out),%rbx		# pass b[0]
-+	call	__rsaz_512_mul
-+
-+	movq	%xmm0, $out
-+	movq	%xmm1, %rbp
-+
-+	movq	(%rsp), %r8
-+	movq	8(%rsp), %r9
-+	movq	16(%rsp), %r10
-+	movq	24(%rsp), %r11
-+	movq	32(%rsp), %r12
-+	movq	40(%rsp), %r13
-+	movq	48(%rsp), %r14
-+	movq	56(%rsp), %r15
-+
-+	call	__rsaz_512_reduce
-+___
-+$code.=<<___ if ($addx);
-+	jmp	.Lmul_scatter_tail
-+	
-+.align	32
-+.Lmulx_scatter:
-+	movq	($out), %rdx		# pass b[0]
-+	call	__rsaz_512_mulx
-+
-+	movq	%xmm0, $out
-+	movq	%xmm1, %rbp
-+
-+	movq	128(%rsp), %rdx		# pull $n0
-+	movq	(%rsp), %r8
-+	movq	8(%rsp), %r9
-+	movq	16(%rsp), %r10
-+	movq	24(%rsp), %r11
-+	movq	32(%rsp), %r12
-+	movq	40(%rsp), %r13
-+	movq	48(%rsp), %r14
-+	movq	56(%rsp), %r15
-+
-+	call	__rsaz_512_reducex
-+
-+.Lmul_scatter_tail:
-+___
-+$code.=<<___;
-+	addq	64(%rsp), %r8
-+	adcq	72(%rsp), %r9
-+	adcq	80(%rsp), %r10
-+	adcq	88(%rsp), %r11
-+	adcq	96(%rsp), %r12
-+	adcq	104(%rsp), %r13
-+	adcq	112(%rsp), %r14
-+	adcq	120(%rsp), %r15
-+	movq	%xmm2, $inp
-+	sbbq	%rcx, %rcx
-+
-+	call	__rsaz_512_subtract
-+
-+	movq	%r8, 128*0($inp)	# scatter
-+	movq	%r9, 128*1($inp)
-+	movq	%r10, 128*2($inp)
-+	movq	%r11, 128*3($inp)
-+	movq	%r12, 128*4($inp)
-+	movq	%r13, 128*5($inp)
-+	movq	%r14, 128*6($inp)
-+	movq	%r15, 128*7($inp)
-+
-+	leaq	128+24+48(%rsp), %rax
-+	movq	-48(%rax), %r15
-+	movq	-40(%rax), %r14
-+	movq	-32(%rax), %r13
-+	movq	-24(%rax), %r12
-+	movq	-16(%rax), %rbp
-+	movq	-8(%rax), %rbx
-+	leaq	(%rax), %rsp
-+.Lmul_scatter4_epilogue:
-+	ret
-+.size	rsaz_512_mul_scatter4,.-rsaz_512_mul_scatter4
-+___
-+}
-+{
-+my ($out,$inp,$mod,$n0) = ("%rdi","%rsi","%rdx","%rcx");
-+$code.=<<___;
-+.globl	rsaz_512_mul_by_one
-+.type	rsaz_512_mul_by_one,\@function,4
-+.align	32
-+rsaz_512_mul_by_one:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	subq	\$128+24, %rsp
-+.Lmul_by_one_body:
-+___
-+$code.=<<___ if ($addx);
-+	movl	OPENSSL_ia32cap_P+8(%rip),%eax
-+___
-+$code.=<<___;
-+	movq	$mod, %rbp	# reassign argument
-+	movq	$n0, 128(%rsp)
-+
-+	movq	($inp), %r8
-+	pxor	%xmm0, %xmm0
-+	movq	8($inp), %r9
-+	movq	16($inp), %r10
-+	movq	24($inp), %r11
-+	movq	32($inp), %r12
-+	movq	40($inp), %r13
-+	movq	48($inp), %r14
-+	movq	56($inp), %r15
-+
-+	movdqa	%xmm0, (%rsp)
-+	movdqa	%xmm0, 16(%rsp)
-+	movdqa	%xmm0, 32(%rsp)
-+	movdqa	%xmm0, 48(%rsp)
-+	movdqa	%xmm0, 64(%rsp)
-+	movdqa	%xmm0, 80(%rsp)
-+	movdqa	%xmm0, 96(%rsp)
-+___
-+$code.=<<___ if ($addx);
-+	andl	\$0x80100,%eax
-+	cmpl	\$0x80100,%eax		# check for MULX and ADO/CX
-+	je	.Lby_one_callx
-+___
-+$code.=<<___;
-+	call	__rsaz_512_reduce
-+___
-+$code.=<<___ if ($addx);
-+	jmp	.Lby_one_tail
-+.align	32
-+.Lby_one_callx:
-+	movq	128(%rsp), %rdx		# pull $n0
-+	call	__rsaz_512_reducex
-+.Lby_one_tail:
-+___
-+$code.=<<___;
-+	movq	%r8, ($out)
-+	movq	%r9, 8($out)
-+	movq	%r10, 16($out)
-+	movq	%r11, 24($out)
-+	movq	%r12, 32($out)
-+	movq	%r13, 40($out)
-+	movq	%r14, 48($out)
-+	movq	%r15, 56($out)
-+
-+	leaq	128+24+48(%rsp), %rax
-+	movq	-48(%rax), %r15
-+	movq	-40(%rax), %r14
-+	movq	-32(%rax), %r13
-+	movq	-24(%rax), %r12
-+	movq	-16(%rax), %rbp
-+	movq	-8(%rax), %rbx
-+	leaq	(%rax), %rsp
-+.Lmul_by_one_epilogue:
-+	ret
-+.size	rsaz_512_mul_by_one,.-rsaz_512_mul_by_one
-+___
-+}
-+{	# __rsaz_512_reduce
-+	#
-+	# input:	%r8-%r15, %rbp - mod, 128(%rsp) - n0
-+	# output:	%r8-%r15
-+	# clobbers:	everything except %rbp and %rdi
-+$code.=<<___;
-+.type	__rsaz_512_reduce,\@abi-omnipotent
-+.align	32
-+__rsaz_512_reduce:
-+	movq	%r8, %rbx
-+	imulq	128+8(%rsp), %rbx
-+	movq	0(%rbp), %rax
-+	movl	\$8, %ecx
-+	jmp	.Lreduction_loop
-+
-+.align	32
-+.Lreduction_loop:
-+	mulq	%rbx
-+	movq	8(%rbp), %rax
-+	negq	%r8
-+	movq	%rdx, %r8
-+	adcq	\$0, %r8
-+
-+	mulq	%rbx
-+	addq	%rax, %r9
-+	movq	16(%rbp), %rax
-+	adcq	\$0, %rdx
-+	addq	%r9, %r8
-+	movq	%rdx, %r9
-+	adcq	\$0, %r9
-+
-+	mulq	%rbx
-+	addq	%rax, %r10
-+	movq	24(%rbp), %rax
-+	adcq	\$0, %rdx
-+	addq	%r10, %r9
-+	movq	%rdx, %r10
-+	adcq	\$0, %r10
-+
-+	mulq	%rbx
-+	addq	%rax, %r11
-+	movq	32(%rbp), %rax
-+	adcq	\$0, %rdx
-+	addq	%r11, %r10
-+	 movq	128+8(%rsp), %rsi
-+	#movq	%rdx, %r11
-+	#adcq	\$0, %r11
-+	adcq	\$0, %rdx
-+	movq	%rdx, %r11
-+
-+	mulq	%rbx
-+	addq	%rax, %r12
-+	movq	40(%rbp), %rax
-+	adcq	\$0, %rdx
-+	 imulq	%r8, %rsi
-+	addq	%r12, %r11
-+	movq	%rdx, %r12
-+	adcq	\$0, %r12
-+
-+	mulq	%rbx
-+	addq	%rax, %r13
-+	movq	48(%rbp), %rax
-+	adcq	\$0, %rdx
-+	addq	%r13, %r12
-+	movq	%rdx, %r13
-+	adcq	\$0, %r13
-+
-+	mulq	%rbx
-+	addq	%rax, %r14
-+	movq	56(%rbp), %rax
-+	adcq	\$0, %rdx
-+	addq	%r14, %r13
-+	movq	%rdx, %r14
-+	adcq	\$0, %r14
-+
-+	mulq	%rbx
-+	 movq	%rsi, %rbx
-+	addq	%rax, %r15
-+	 movq	0(%rbp), %rax
-+	adcq	\$0, %rdx
-+	addq	%r15, %r14
-+	movq	%rdx, %r15
-+	adcq	\$0, %r15
-+
-+	decl	%ecx
-+	jne	.Lreduction_loop
-+
-+	ret
-+.size	__rsaz_512_reduce,.-__rsaz_512_reduce
-+___
-+}
-+if ($addx) {
-+	# __rsaz_512_reducex
-+	#
-+	# input:	%r8-%r15, %rbp - mod, 128(%rsp) - n0
-+	# output:	%r8-%r15
-+	# clobbers:	everything except %rbp and %rdi
-+$code.=<<___;
-+.type	__rsaz_512_reducex,\@abi-omnipotent
-+.align	32
-+__rsaz_512_reducex:
-+	#movq	128+8(%rsp), %rdx		# pull $n0
-+	imulq	%r8, %rdx
-+	xorq	%rsi, %rsi			# cf=0,of=0
-+	movl	\$8, %ecx
-+	jmp	.Lreduction_loopx
-+
-+.align	32
-+.Lreduction_loopx:
-+	mov	%r8, %rbx
-+	mulx	0(%rbp), %rax, %r8
-+	adcx	%rbx, %rax
-+	adox	%r9, %r8
-+
-+	mulx	8(%rbp), %rax, %r9
-+	adcx	%rax, %r8
-+	adox	%r10, %r9
-+
-+	mulx	16(%rbp), %rbx, %r10
-+	adcx	%rbx, %r9
-+	adox	%r11, %r10
-+
-+	mulx	24(%rbp), %rbx, %r11
-+	adcx	%rbx, %r10
-+	adox	%r12, %r11
-+
-+	.byte	0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00	# mulx	32(%rbp), %rbx, %r12
-+	 mov	%rdx, %rax
-+	 mov	%r8, %rdx
-+	adcx	%rbx, %r11
-+	adox	%r13, %r12
-+
-+	 mulx	128+8(%rsp), %rbx, %rdx
-+	 mov	%rax, %rdx
-+
-+	mulx	40(%rbp), %rax, %r13
-+	adcx	%rax, %r12
-+	adox	%r14, %r13
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0xb5,0x30,0x00,0x00,0x00	# mulx	48(%rbp), %rax, %r14
-+	adcx	%rax, %r13
-+	adox	%r15, %r14
-+
-+	mulx	56(%rbp), %rax, %r15
-+	 mov	%rbx, %rdx
-+	adcx	%rax, %r14
-+	adox	%rsi, %r15			# %rsi is 0
-+	adcx	%rsi, %r15			# cf=0
-+
-+	decl	%ecx				# of=0
-+	jne	.Lreduction_loopx
-+
-+	ret
-+.size	__rsaz_512_reducex,.-__rsaz_512_reducex
-+___
-+}
-+{	# __rsaz_512_subtract
-+	# input: %r8-%r15, %rdi - $out, %rbp - $mod, %rcx - mask
-+	# output:
-+	# clobbers: everything but %rdi, %rsi and %rbp
-+$code.=<<___;
-+.type	__rsaz_512_subtract,\@abi-omnipotent
-+.align	32
-+__rsaz_512_subtract:
-+	movq	%r8, ($out)
-+	movq	%r9, 8($out)
-+	movq	%r10, 16($out)
-+	movq	%r11, 24($out)
-+	movq	%r12, 32($out)
-+	movq	%r13, 40($out)
-+	movq	%r14, 48($out)
-+	movq	%r15, 56($out)
-+
-+	movq	0($mod), %r8
-+	movq	8($mod), %r9
-+	negq	%r8
-+	notq	%r9
-+	andq	%rcx, %r8
-+	movq	16($mod), %r10
-+	andq	%rcx, %r9
-+	notq	%r10
-+	movq	24($mod), %r11
-+	andq	%rcx, %r10
-+	notq	%r11
-+	movq	32($mod), %r12
-+	andq	%rcx, %r11
-+	notq	%r12
-+	movq	40($mod), %r13
-+	andq	%rcx, %r12
-+	notq	%r13
-+	movq	48($mod), %r14
-+	andq	%rcx, %r13
-+	notq	%r14
-+	movq	56($mod), %r15
-+	andq	%rcx, %r14
-+	notq	%r15
-+	andq	%rcx, %r15
-+
-+	addq	($out), %r8
-+	adcq	8($out), %r9
-+	adcq	16($out), %r10
-+	adcq	24($out), %r11
-+	adcq	32($out), %r12
-+	adcq	40($out), %r13
-+	adcq	48($out), %r14
-+	adcq	56($out), %r15
-+
-+	movq	%r8, ($out)
-+	movq	%r9, 8($out)
-+	movq	%r10, 16($out)
-+	movq	%r11, 24($out)
-+	movq	%r12, 32($out)
-+	movq	%r13, 40($out)
-+	movq	%r14, 48($out)
-+	movq	%r15, 56($out)
-+
-+	ret
-+.size	__rsaz_512_subtract,.-__rsaz_512_subtract
-+___
-+}
-+{	# __rsaz_512_mul
-+	#
-+	# input: %rsi - ap, %rbp - bp
-+	# output:
-+	# clobbers: everything
-+my ($ap,$bp) = ("%rsi","%rbp");
-+$code.=<<___;
-+.type	__rsaz_512_mul,\@abi-omnipotent
-+.align	32
-+__rsaz_512_mul:
-+	leaq	8(%rsp), %rdi
-+
-+	movq	($ap), %rax
-+	mulq	%rbx
-+	movq	%rax, (%rdi)
-+	movq	8($ap), %rax
-+	movq	%rdx, %r8
-+
-+	mulq	%rbx
-+	addq	%rax, %r8
-+	movq	16($ap), %rax
-+	movq	%rdx, %r9
-+	adcq	\$0, %r9
-+
-+	mulq	%rbx
-+	addq	%rax, %r9
-+	movq	24($ap), %rax
-+	movq	%rdx, %r10
-+	adcq	\$0, %r10
-+
-+	mulq	%rbx
-+	addq	%rax, %r10
-+	movq	32($ap), %rax
-+	movq	%rdx, %r11
-+	adcq	\$0, %r11
-+
-+	mulq	%rbx
-+	addq	%rax, %r11
-+	movq	40($ap), %rax
-+	movq	%rdx, %r12
-+	adcq	\$0, %r12
-+
-+	mulq	%rbx
-+	addq	%rax, %r12
-+	movq	48($ap), %rax
-+	movq	%rdx, %r13
-+	adcq	\$0, %r13
-+
-+	mulq	%rbx
-+	addq	%rax, %r13
-+	movq	56($ap), %rax
-+	movq	%rdx, %r14
-+	adcq	\$0, %r14
-+	
-+	mulq	%rbx
-+	addq	%rax, %r14
-+	 movq	($ap), %rax
-+	movq	%rdx, %r15
-+	adcq	\$0, %r15
-+
-+	leaq	8($bp), $bp
-+	leaq	8(%rdi), %rdi
-+
-+	movl	\$7, %ecx
-+	jmp	.Loop_mul
-+
-+.align	32
-+.Loop_mul:
-+	movq	($bp), %rbx
-+	mulq	%rbx
-+	addq	%rax, %r8
-+	movq	8($ap), %rax
-+	movq	%r8, (%rdi)
-+	movq	%rdx, %r8
-+	adcq	\$0, %r8
-+
-+	mulq	%rbx
-+	addq	%rax, %r9
-+	movq	16($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r9, %r8
-+	movq	%rdx, %r9
-+	adcq	\$0, %r9
-+
-+	mulq	%rbx
-+	addq	%rax, %r10
-+	movq	24($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r10, %r9
-+	movq	%rdx, %r10
-+	adcq	\$0, %r10
-+
-+	mulq	%rbx
-+	addq	%rax, %r11
-+	movq	32($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r11, %r10
-+	movq	%rdx, %r11
-+	adcq	\$0, %r11
-+
-+	mulq	%rbx
-+	addq	%rax, %r12
-+	movq	40($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r12, %r11
-+	movq	%rdx, %r12
-+	adcq	\$0, %r12
-+
-+	mulq	%rbx
-+	addq	%rax, %r13
-+	movq	48($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r13, %r12
-+	movq	%rdx, %r13
-+	adcq	\$0, %r13
-+
-+	mulq	%rbx
-+	addq	%rax, %r14
-+	movq	56($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r14, %r13
-+	movq	%rdx, %r14
-+	 leaq	8($bp), $bp
-+	adcq	\$0, %r14
-+
-+	mulq	%rbx
-+	addq	%rax, %r15
-+	 movq	($ap), %rax
-+	adcq	\$0, %rdx
-+	addq	%r15, %r14
-+	movq	%rdx, %r15	
-+	adcq	\$0, %r15
-+
-+	leaq	8(%rdi), %rdi
-+
-+	decl	%ecx
-+	jnz	.Loop_mul
-+
-+	movq	%r8, (%rdi)
-+	movq	%r9, 8(%rdi)
-+	movq	%r10, 16(%rdi)
-+	movq	%r11, 24(%rdi)
-+	movq	%r12, 32(%rdi)
-+	movq	%r13, 40(%rdi)
-+	movq	%r14, 48(%rdi)
-+	movq	%r15, 56(%rdi)
-+
-+	ret
-+.size	__rsaz_512_mul,.-__rsaz_512_mul
-+___
-+}
-+if ($addx) {
-+	# __rsaz_512_mulx
-+	#
-+	# input: %rsi - ap, %rbp - bp
-+	# output:
-+	# clobbers: everything
-+my ($ap,$bp,$zero) = ("%rsi","%rbp","%rdi");
-+$code.=<<___;
-+.type	__rsaz_512_mulx,\@abi-omnipotent
-+.align	32
-+__rsaz_512_mulx:
-+	mulx	($ap), %rbx, %r8	# initial %rdx preloaded by caller
-+	mov	\$-6, %rcx
-+
-+	mulx	8($ap), %rax, %r9
-+	movq	%rbx, 8(%rsp)
-+
-+	mulx	16($ap), %rbx, %r10
-+	adc	%rax, %r8
-+
-+	mulx	24($ap), %rax, %r11
-+	adc	%rbx, %r9
-+
-+	mulx	32($ap), %rbx, %r12
-+	adc	%rax, %r10
-+
-+	mulx	40($ap), %rax, %r13
-+	adc	%rbx, %r11
-+
-+	mulx	48($ap), %rbx, %r14
-+	adc	%rax, %r12
-+
-+	mulx	56($ap), %rax, %r15
-+	 mov	8($bp), %rdx
-+	adc	%rbx, %r13
-+	adc	%rax, %r14
-+	adc	\$0, %r15
-+
-+	xor	$zero, $zero		# cf=0,of=0
-+	jmp	.Loop_mulx
-+
-+.align	32
-+.Loop_mulx:
-+	movq	%r8, %rbx
-+	mulx	($ap), %rax, %r8
-+	adcx	%rax, %rbx
-+	adox	%r9, %r8
-+
-+	mulx	8($ap), %rax, %r9
-+	adcx	%rax, %r8
-+	adox	%r10, %r9
-+
-+	mulx	16($ap), %rax, %r10
-+	adcx	%rax, %r9
-+	adox	%r11, %r10
-+
-+	mulx	24($ap), %rax, %r11
-+	adcx	%rax, %r10
-+	adox	%r12, %r11
-+
-+	.byte	0x3e,0xc4,0x62,0xfb,0xf6,0xa6,0x20,0x00,0x00,0x00	# mulx	32($ap), %rax, %r12
-+	adcx	%rax, %r11
-+	adox	%r13, %r12
-+
-+	mulx	40($ap), %rax, %r13
-+	adcx	%rax, %r12
-+	adox	%r14, %r13
-+
-+	mulx	48($ap), %rax, %r14
-+	adcx	%rax, %r13
-+	adox	%r15, %r14
-+
-+	mulx	56($ap), %rax, %r15
-+	 movq	64($bp,%rcx,8), %rdx
-+	 movq	%rbx, 8+64-8(%rsp,%rcx,8)
-+	adcx	%rax, %r14
-+	adox	$zero, %r15
-+	adcx	$zero, %r15		# cf=0
-+
-+	inc	%rcx			# of=0
-+	jnz	.Loop_mulx
-+
-+	movq	%r8, %rbx
-+	mulx	($ap), %rax, %r8
-+	adcx	%rax, %rbx
-+	adox	%r9, %r8
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0x8e,0x08,0x00,0x00,0x00	# mulx	8($ap), %rax, %r9
-+	adcx	%rax, %r8
-+	adox	%r10, %r9
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0x96,0x10,0x00,0x00,0x00	# mulx	16($ap), %rax, %r10
-+	adcx	%rax, %r9
-+	adox	%r11, %r10
-+
-+	mulx	24($ap), %rax, %r11
-+	adcx	%rax, %r10
-+	adox	%r12, %r11
-+
-+	mulx	32($ap), %rax, %r12
-+	adcx	%rax, %r11
-+	adox	%r13, %r12
-+
-+	mulx	40($ap), %rax, %r13
-+	adcx	%rax, %r12
-+	adox	%r14, %r13
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0xb6,0x30,0x00,0x00,0x00	# mulx	48($ap), %rax, %r14
-+	adcx	%rax, %r13
-+	adox	%r15, %r14
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0xbe,0x38,0x00,0x00,0x00	# mulx	56($ap), %rax, %r15
-+	adcx	%rax, %r14
-+	adox	$zero, %r15
-+	adcx	$zero, %r15
-+
-+	mov	%rbx, 8+64-8(%rsp)
-+	mov	%r8, 8+64(%rsp)
-+	mov	%r9, 8+64+8(%rsp)
-+	mov	%r10, 8+64+16(%rsp)
-+	mov	%r11, 8+64+24(%rsp)
-+	mov	%r12, 8+64+32(%rsp)
-+	mov	%r13, 8+64+40(%rsp)
-+	mov	%r14, 8+64+48(%rsp)
-+	mov	%r15, 8+64+56(%rsp)
-+
-+	ret
-+.size	__rsaz_512_mulx,.-__rsaz_512_mulx
-+___
-+}
-+{
-+my ($out,$inp,$power)= $win64 ? ("%rcx","%rdx","%r8d") : ("%rdi","%rsi","%edx");
-+$code.=<<___;
-+.globl	rsaz_512_scatter4
-+.type	rsaz_512_scatter4,\@abi-omnipotent
-+.align	16
-+rsaz_512_scatter4:
-+	leaq	($out,$power,8), $out
-+	movl	\$8, %r9d
-+	jmp	.Loop_scatter
-+.align	16
-+.Loop_scatter:
-+	movq	($inp), %rax
-+	leaq	8($inp), $inp
-+	movq	%rax, ($out)
-+	leaq	128($out), $out
-+	decl	%r9d
-+	jnz	.Loop_scatter
-+	ret
-+.size	rsaz_512_scatter4,.-rsaz_512_scatter4
-+
-+.globl	rsaz_512_gather4
-+.type	rsaz_512_gather4,\@abi-omnipotent
-+.align	16
-+rsaz_512_gather4:
-+___
-+$code.=<<___	if ($win64);
-+.LSEH_begin_rsaz_512_gather4:
-+	.byte	0x48,0x81,0xec,0xa8,0x00,0x00,0x00	# sub    $0xa8,%rsp
-+	.byte	0x0f,0x29,0x34,0x24			# movaps %xmm6,(%rsp)
-+	.byte	0x0f,0x29,0x7c,0x24,0x10		# movaps %xmm7,0x10(%rsp)
-+	.byte	0x44,0x0f,0x29,0x44,0x24,0x20		# movaps %xmm8,0x20(%rsp)
-+	.byte	0x44,0x0f,0x29,0x4c,0x24,0x30		# movaps %xmm9,0x30(%rsp)
-+	.byte	0x44,0x0f,0x29,0x54,0x24,0x40		# movaps %xmm10,0x40(%rsp)
-+	.byte	0x44,0x0f,0x29,0x5c,0x24,0x50		# movaps %xmm11,0x50(%rsp)
-+	.byte	0x44,0x0f,0x29,0x64,0x24,0x60		# movaps %xmm12,0x60(%rsp)
-+	.byte	0x44,0x0f,0x29,0x6c,0x24,0x70		# movaps %xmm13,0x70(%rsp)
-+	.byte	0x44,0x0f,0x29,0xb4,0x24,0x80,0,0,0	# movaps %xmm14,0x80(%rsp)
-+	.byte	0x44,0x0f,0x29,0xbc,0x24,0x90,0,0,0	# movaps %xmm15,0x90(%rsp)
-+___
-+$code.=<<___;
-+	movd	$power,%xmm8
-+	movdqa	.Linc+16(%rip),%xmm1	# 00000002000000020000000200000002
-+	movdqa	.Linc(%rip),%xmm0	# 00000001000000010000000000000000
-+
-+	pshufd	\$0,%xmm8,%xmm8		# broadcast $power
-+	movdqa	%xmm1,%xmm7
-+	movdqa	%xmm1,%xmm2
-+___
-+########################################################################
-+# calculate mask by comparing 0..15 to $power
-+#
-+for($i=0;$i<4;$i++) {
-+$code.=<<___;
-+	paddd	%xmm`$i`,%xmm`$i+1`
-+	pcmpeqd	%xmm8,%xmm`$i`
-+	movdqa	%xmm7,%xmm`$i+3`
-+___
-+}
-+for(;$i<7;$i++) {
-+$code.=<<___;
-+	paddd	%xmm`$i`,%xmm`$i+1`
-+	pcmpeqd	%xmm8,%xmm`$i`
-+___
-+}
-+$code.=<<___;
-+	pcmpeqd	%xmm8,%xmm7
-+	movl	\$8, %r9d
-+	jmp	.Loop_gather
-+.align	16
-+.Loop_gather:
-+	movdqa	16*0($inp),%xmm8
-+	movdqa	16*1($inp),%xmm9
-+	movdqa	16*2($inp),%xmm10
-+	movdqa	16*3($inp),%xmm11
-+	pand	%xmm0,%xmm8
-+	movdqa	16*4($inp),%xmm12
-+	pand	%xmm1,%xmm9
-+	movdqa	16*5($inp),%xmm13
-+	pand	%xmm2,%xmm10
-+	movdqa	16*6($inp),%xmm14
-+	pand	%xmm3,%xmm11
-+	movdqa	16*7($inp),%xmm15
-+	leaq	128($inp), $inp
-+	pand	%xmm4,%xmm12
-+	pand	%xmm5,%xmm13
-+	pand	%xmm6,%xmm14
-+	pand	%xmm7,%xmm15
-+	por	%xmm10,%xmm8
-+	por	%xmm11,%xmm9
-+	por	%xmm12,%xmm8
-+	por	%xmm13,%xmm9
-+	por	%xmm14,%xmm8
-+	por	%xmm15,%xmm9
-+
-+	por	%xmm9,%xmm8
-+	pshufd	\$0x4e,%xmm8,%xmm9
-+	por	%xmm9,%xmm8
-+	movq	%xmm8,($out)
-+	leaq	8($out), $out
-+	decl	%r9d
-+	jnz	.Loop_gather
-+___
-+$code.=<<___	if ($win64);
-+	movaps	0x00(%rsp),%xmm6
-+	movaps	0x10(%rsp),%xmm7
-+	movaps	0x20(%rsp),%xmm8
-+	movaps	0x30(%rsp),%xmm9
-+	movaps	0x40(%rsp),%xmm10
-+	movaps	0x50(%rsp),%xmm11
-+	movaps	0x60(%rsp),%xmm12
-+	movaps	0x70(%rsp),%xmm13
-+	movaps	0x80(%rsp),%xmm14
-+	movaps	0x90(%rsp),%xmm15
-+	add	\$0xa8,%rsp
-+___
-+$code.=<<___;
-+	ret
-+.LSEH_end_rsaz_512_gather4:
-+.size	rsaz_512_gather4,.-rsaz_512_gather4
-+
-+.align	64
-+.Linc:
-+	.long	0,0, 1,1
-+	.long	2,2, 2,2
-+___
-+}
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# end of prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+
-+	lea	128+24+48(%rax),%rax
-+
-+	lea	.Lmul_gather4_epilogue(%rip),%rbx
-+	cmp	%r10,%rbx
-+	jne	.Lse_not_in_mul_gather4
-+
-+	lea	0xb0(%rax),%rax
-+
-+	lea	-48-0xa8(%rax),%rsi
-+	lea	512($context),%rdi
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+.Lse_not_in_mul_gather4:
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lcommon_seh_tail:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_rsaz_512_sqr
-+	.rva	.LSEH_end_rsaz_512_sqr
-+	.rva	.LSEH_info_rsaz_512_sqr
-+
-+	.rva	.LSEH_begin_rsaz_512_mul
-+	.rva	.LSEH_end_rsaz_512_mul
-+	.rva	.LSEH_info_rsaz_512_mul
-+
-+	.rva	.LSEH_begin_rsaz_512_mul_gather4
-+	.rva	.LSEH_end_rsaz_512_mul_gather4
-+	.rva	.LSEH_info_rsaz_512_mul_gather4
-+
-+	.rva	.LSEH_begin_rsaz_512_mul_scatter4
-+	.rva	.LSEH_end_rsaz_512_mul_scatter4
-+	.rva	.LSEH_info_rsaz_512_mul_scatter4
-+
-+	.rva	.LSEH_begin_rsaz_512_mul_by_one
-+	.rva	.LSEH_end_rsaz_512_mul_by_one
-+	.rva	.LSEH_info_rsaz_512_mul_by_one
-+
-+	.rva	.LSEH_begin_rsaz_512_gather4
-+	.rva	.LSEH_end_rsaz_512_gather4
-+	.rva	.LSEH_info_rsaz_512_gather4
-+
-+.section	.xdata
-+.align	8
-+.LSEH_info_rsaz_512_sqr:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lsqr_body,.Lsqr_epilogue			# HandlerData[]
-+.LSEH_info_rsaz_512_mul:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lmul_body,.Lmul_epilogue			# HandlerData[]
-+.LSEH_info_rsaz_512_mul_gather4:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lmul_gather4_body,.Lmul_gather4_epilogue	# HandlerData[]
-+.LSEH_info_rsaz_512_mul_scatter4:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lmul_scatter4_body,.Lmul_scatter4_epilogue	# HandlerData[]
-+.LSEH_info_rsaz_512_mul_by_one:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lmul_by_one_body,.Lmul_by_one_epilogue		# HandlerData[]
-+.LSEH_info_rsaz_512_gather4:
-+	.byte	0x01,0x46,0x16,0x00
-+	.byte	0x46,0xf8,0x09,0x00	# vmovaps 0x90(rsp),xmm15
-+	.byte	0x3d,0xe8,0x08,0x00	# vmovaps 0x80(rsp),xmm14
-+	.byte	0x34,0xd8,0x07,0x00	# vmovaps 0x70(rsp),xmm13
-+	.byte	0x2e,0xc8,0x06,0x00	# vmovaps 0x60(rsp),xmm12
-+	.byte	0x28,0xb8,0x05,0x00	# vmovaps 0x50(rsp),xmm11
-+	.byte	0x22,0xa8,0x04,0x00	# vmovaps 0x40(rsp),xmm10
-+	.byte	0x1c,0x98,0x03,0x00	# vmovaps 0x30(rsp),xmm9
-+	.byte	0x16,0x88,0x02,0x00	# vmovaps 0x20(rsp),xmm8
-+	.byte	0x10,0x78,0x01,0x00	# vmovaps 0x10(rsp),xmm7
-+	.byte	0x0b,0x68,0x00,0x00	# vmovaps 0x00(rsp),xmm6
-+	.byte	0x07,0x01,0x15,0x00	# sub     rsp,0xa8
-+___
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x-gf2m.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x-gf2m.pl
-new file mode 100644
-index 0000000..cbd16f4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x-gf2m.pl
-@@ -0,0 +1,228 @@
-+#! /usr/bin/env perl
-+# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# May 2011
-+#
-+# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
-+# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
-+# the time being... gcc 4.3 appeared to generate poor code, therefore
-+# the effort. And indeed, the module delivers 55%-90%(*) improvement
-+# on haviest ECDSA verify and ECDH benchmarks for 163- and 571-bit
-+# key lengths on z990, 30%-55%(*) - on z10, and 70%-110%(*) - on z196.
-+# This is for 64-bit build. In 32-bit "highgprs" case improvement is
-+# even higher, for example on z990 it was measured 80%-150%. ECDSA
-+# sign is modest 9%-12% faster. Keep in mind that these coefficients
-+# are not ones for bn_GF2m_mul_2x2 itself, as not all CPU time is
-+# burnt in it...
-+#
-+# (*)	gcc 4.1 was observed to deliver better results than gcc 4.3,
-+#	so that improvement coefficients can vary from one specific
-+#	setup to another.
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /3[12]/) {
-+        $SIZE_T=4;
-+        $g="";
-+} else {
-+        $SIZE_T=8;
-+        $g="g";
-+}
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+$stdframe=16*$SIZE_T+4*8;
-+
-+$rp="%r2";
-+$a1="%r3";
-+$a0="%r4";
-+$b1="%r5";
-+$b0="%r6";
-+
-+$ra="%r14";
-+$sp="%r15";
-+
-+@T=("%r0","%r1");
-+@i=("%r12","%r13");
-+
-+($a1,$a2,$a4,$a8,$a12,$a48)=map("%r$_",(6..11));
-+($lo,$hi,$b)=map("%r$_",(3..5)); $a=$lo; $mask=$a8;
-+
-+$code.=<<___;
-+.text
-+
-+.type	_mul_1x1,\@function
-+.align	16
-+_mul_1x1:
-+	lgr	$a1,$a
-+	sllg	$a2,$a,1
-+	sllg	$a4,$a,2
-+	sllg	$a8,$a,3
-+
-+	srag	$lo,$a1,63			# broadcast 63rd bit
-+	nihh	$a1,0x1fff
-+	srag	@i[0],$a2,63			# broadcast 62nd bit
-+	nihh	$a2,0x3fff
-+	srag	@i[1],$a4,63			# broadcast 61st bit
-+	nihh	$a4,0x7fff
-+	ngr	$lo,$b
-+	ngr	@i[0],$b
-+	ngr	@i[1],$b
-+
-+	lghi	@T[0],0
-+	lgr	$a12,$a1
-+	stg	@T[0],`$stdframe+0*8`($sp)	# tab[0]=0
-+	xgr	$a12,$a2
-+	stg	$a1,`$stdframe+1*8`($sp)	# tab[1]=a1
-+	 lgr	$a48,$a4
-+	stg	$a2,`$stdframe+2*8`($sp)	# tab[2]=a2
-+	 xgr	$a48,$a8
-+	stg	$a12,`$stdframe+3*8`($sp)	# tab[3]=a1^a2
-+	 xgr	$a1,$a4
-+
-+	stg	$a4,`$stdframe+4*8`($sp)	# tab[4]=a4
-+	xgr	$a2,$a4
-+	stg	$a1,`$stdframe+5*8`($sp)	# tab[5]=a1^a4
-+	xgr	$a12,$a4
-+	stg	$a2,`$stdframe+6*8`($sp)	# tab[6]=a2^a4
-+	 xgr	$a1,$a48
-+	stg	$a12,`$stdframe+7*8`($sp)	# tab[7]=a1^a2^a4
-+	 xgr	$a2,$a48
-+
-+	stg	$a8,`$stdframe+8*8`($sp)	# tab[8]=a8
-+	xgr	$a12,$a48
-+	stg	$a1,`$stdframe+9*8`($sp)	# tab[9]=a1^a8
-+	 xgr	$a1,$a4
-+	stg	$a2,`$stdframe+10*8`($sp)	# tab[10]=a2^a8
-+	 xgr	$a2,$a4
-+	stg	$a12,`$stdframe+11*8`($sp)	# tab[11]=a1^a2^a8
-+
-+	xgr	$a12,$a4
-+	stg	$a48,`$stdframe+12*8`($sp)	# tab[12]=a4^a8
-+	 srlg	$hi,$lo,1
-+	stg	$a1,`$stdframe+13*8`($sp)	# tab[13]=a1^a4^a8
-+	 sllg	$lo,$lo,63
-+	stg	$a2,`$stdframe+14*8`($sp)	# tab[14]=a2^a4^a8
-+	 srlg	@T[0],@i[0],2
-+	stg	$a12,`$stdframe+15*8`($sp)	# tab[15]=a1^a2^a4^a8
-+
-+	lghi	$mask,`0xf<<3`
-+	sllg	$a1,@i[0],62
-+	 sllg	@i[0],$b,3
-+	srlg	@T[1],@i[1],3
-+	 ngr	@i[0],$mask
-+	sllg	$a2,@i[1],61
-+	 srlg	@i[1],$b,4-3
-+	xgr	$hi,@T[0]
-+	 ngr	@i[1],$mask
-+	xgr	$lo,$a1
-+	xgr	$hi,@T[1]
-+	xgr	$lo,$a2
-+
-+	xg	$lo,$stdframe(@i[0],$sp)
-+	srlg	@i[0],$b,8-3
-+	ngr	@i[0],$mask
-+___
-+for($n=1;$n<14;$n++) {
-+$code.=<<___;
-+	lg	@T[1],$stdframe(@i[1],$sp)
-+	srlg	@i[1],$b,`($n+2)*4`-3
-+	sllg	@T[0],@T[1],`$n*4`
-+	ngr	@i[1],$mask
-+	srlg	@T[1],@T[1],`64-$n*4`
-+	xgr	$lo,@T[0]
-+	xgr	$hi,@T[1]
-+___
-+	push(@i,shift(@i)); push(@T,shift(@T));
-+}
-+$code.=<<___;
-+	lg	@T[1],$stdframe(@i[1],$sp)
-+	sllg	@T[0],@T[1],`$n*4`
-+	srlg	@T[1],@T[1],`64-$n*4`
-+	xgr	$lo,@T[0]
-+	xgr	$hi,@T[1]
-+
-+	lg	@T[0],$stdframe(@i[0],$sp)
-+	sllg	@T[1],@T[0],`($n+1)*4`
-+	srlg	@T[0],@T[0],`64-($n+1)*4`
-+	xgr	$lo,@T[1]
-+	xgr	$hi,@T[0]
-+
-+	br	$ra
-+.size	_mul_1x1,.-_mul_1x1
-+
-+.globl	bn_GF2m_mul_2x2
-+.type	bn_GF2m_mul_2x2,\@function
-+.align	16
-+bn_GF2m_mul_2x2:
-+	stm${g}	%r3,%r15,3*$SIZE_T($sp)
-+
-+	lghi	%r1,-$stdframe-128
-+	la	%r0,0($sp)
-+	la	$sp,0(%r1,$sp)			# alloca
-+	st${g}	%r0,0($sp)			# back chain
-+___
-+if ($SIZE_T==8) {
-+my @r=map("%r$_",(6..9));
-+$code.=<<___;
-+	bras	$ra,_mul_1x1			# a1·b1
-+	stmg	$lo,$hi,16($rp)
-+
-+	lg	$a,`$stdframe+128+4*$SIZE_T`($sp)
-+	lg	$b,`$stdframe+128+6*$SIZE_T`($sp)
-+	bras	$ra,_mul_1x1			# a0·b0
-+	stmg	$lo,$hi,0($rp)
-+
-+	lg	$a,`$stdframe+128+3*$SIZE_T`($sp)
-+	lg	$b,`$stdframe+128+5*$SIZE_T`($sp)
-+	xg	$a,`$stdframe+128+4*$SIZE_T`($sp)
-+	xg	$b,`$stdframe+128+6*$SIZE_T`($sp)
-+	bras	$ra,_mul_1x1			# (a0+a1)·(b0+b1)
-+	lmg	@r[0],@r[3],0($rp)
-+
-+	xgr	$lo,$hi
-+	xgr	$hi,@r[1]
-+	xgr	$lo,@r[0]
-+	xgr	$hi,@r[2]
-+	xgr	$lo,@r[3]	
-+	xgr	$hi,@r[3]
-+	xgr	$lo,$hi
-+	stg	$hi,16($rp)
-+	stg	$lo,8($rp)
-+___
-+} else {
-+$code.=<<___;
-+	sllg	%r3,%r3,32
-+	sllg	%r5,%r5,32
-+	or	%r3,%r4
-+	or	%r5,%r6
-+	bras	$ra,_mul_1x1
-+	rllg	$lo,$lo,32
-+	rllg	$hi,$hi,32
-+	stmg	$lo,$hi,0($rp)
-+___
-+}
-+$code.=<<___;
-+	lm${g}	%r6,%r15,`$stdframe+128+6*$SIZE_T`($sp)
-+	br	$ra
-+.size	bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
-+.string	"GF(2^m) Multiplication for s390x, CRYPTOGAMS by "
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x-mont.pl
-new file mode 100644
-index 0000000..2205bc2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x-mont.pl
-@@ -0,0 +1,284 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# April 2007.
-+#
-+# Performance improvement over vanilla C code varies from 85% to 45%
-+# depending on key length and benchmark. Unfortunately in this context
-+# these are not very impressive results [for code that utilizes "wide"
-+# 64x64=128-bit multiplication, which is not commonly available to C
-+# programmers], at least hand-coded bn_asm.c replacement is known to
-+# provide 30-40% better results for longest keys. Well, on a second
-+# thought it's not very surprising, because z-CPUs are single-issue
-+# and _strictly_ in-order execution, while bn_mul_mont is more or less
-+# dependent on CPU ability to pipe-line instructions and have several
-+# of them "in-flight" at the same time. I mean while other methods,
-+# for example Karatsuba, aim to minimize amount of multiplications at
-+# the cost of other operations increase, bn_mul_mont aim to neatly
-+# "overlap" multiplications and the other operations [and on most
-+# platforms even minimize the amount of the other operations, in
-+# particular references to memory]. But it's possible to improve this
-+# module performance by implementing dedicated squaring code-path and
-+# possibly by unrolling loops...
-+
-+# January 2009.
-+#
-+# Reschedule to minimize/avoid Address Generation Interlock hazard,
-+# make inner loops counter-based.
-+
-+# November 2010.
-+#
-+# Adapt for -m31 build. If kernel supports what's called "highgprs"
-+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
-+# instructions and achieve "64-bit" performance even in 31-bit legacy
-+# application context. The feature is not specific to any particular
-+# processor, as long as it's "z-CPU". Latter implies that the code
-+# remains z/Architecture specific. Compatibility with 32-bit BN_ULONG
-+# is achieved by swapping words after 64-bit loads, follow _dswap-s.
-+# On z990 it was measured to perform 2.6-2.2 times better than
-+# compiler-generated code, less for longer keys...
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /3[12]/) {
-+	$SIZE_T=4;
-+	$g="";
-+} else {
-+	$SIZE_T=8;
-+	$g="g";
-+}
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+$stdframe=16*$SIZE_T+4*8;
-+
-+$mn0="%r0";
-+$num="%r1";
-+
-+# int bn_mul_mont(
-+$rp="%r2";		# BN_ULONG *rp,
-+$ap="%r3";		# const BN_ULONG *ap,
-+$bp="%r4";		# const BN_ULONG *bp,
-+$np="%r5";		# const BN_ULONG *np,
-+$n0="%r6";		# const BN_ULONG *n0,
-+#$num="160(%r15)"	# int num);
-+
-+$bi="%r2";	# zaps rp
-+$j="%r7";
-+
-+$ahi="%r8";
-+$alo="%r9";
-+$nhi="%r10";
-+$nlo="%r11";
-+$AHI="%r12";
-+$NHI="%r13";
-+$count="%r14";
-+$sp="%r15";
-+
-+$code.=<<___;
-+.text
-+.globl	bn_mul_mont
-+.type	bn_mul_mont,\@function
-+bn_mul_mont:
-+	lgf	$num,`$stdframe+$SIZE_T-4`($sp)	# pull $num
-+	sla	$num,`log($SIZE_T)/log(2)`	# $num to enumerate bytes
-+	la	$bp,0($num,$bp)
-+
-+	st${g}	%r2,2*$SIZE_T($sp)
-+
-+	cghi	$num,16		#
-+	lghi	%r2,0		#
-+	blr	%r14		# if($num<16) return 0;
-+___
-+$code.=<<___ if ($flavour =~ /3[12]/);
-+	tmll	$num,4
-+	bnzr	%r14		# if ($num&1) return 0;
-+___
-+$code.=<<___ if ($flavour !~ /3[12]/);
-+	cghi	$num,96		#
-+	bhr	%r14		# if($num>96) return 0;
-+___
-+$code.=<<___;
-+	stm${g}	%r3,%r15,3*$SIZE_T($sp)
-+
-+	lghi	$rp,-$stdframe-8	# leave room for carry bit
-+	lcgr	$j,$num		# -$num
-+	lgr	%r0,$sp
-+	la	$rp,0($rp,$sp)
-+	la	$sp,0($j,$rp)	# alloca
-+	st${g}	%r0,0($sp)	# back chain
-+
-+	sra	$num,3		# restore $num
-+	la	$bp,0($j,$bp)	# restore $bp
-+	ahi	$num,-1		# adjust $num for inner loop
-+	lg	$n0,0($n0)	# pull n0
-+	_dswap	$n0
-+
-+	lg	$bi,0($bp)
-+	_dswap	$bi
-+	lg	$alo,0($ap)
-+	_dswap	$alo
-+	mlgr	$ahi,$bi	# ap[0]*bp[0]
-+	lgr	$AHI,$ahi
-+
-+	lgr	$mn0,$alo	# "tp[0]"*n0
-+	msgr	$mn0,$n0
-+
-+	lg	$nlo,0($np)	#
-+	_dswap	$nlo
-+	mlgr	$nhi,$mn0	# np[0]*m1
-+	algr	$nlo,$alo	# +="tp[0]"
-+	lghi	$NHI,0
-+	alcgr	$NHI,$nhi
-+
-+	la	$j,8(%r0)	# j=1
-+	lr	$count,$num
-+
-+.align	16
-+.L1st:
-+	lg	$alo,0($j,$ap)
-+	_dswap	$alo
-+	mlgr	$ahi,$bi	# ap[j]*bp[0]
-+	algr	$alo,$AHI
-+	lghi	$AHI,0
-+	alcgr	$AHI,$ahi
-+
-+	lg	$nlo,0($j,$np)
-+	_dswap	$nlo
-+	mlgr	$nhi,$mn0	# np[j]*m1
-+	algr	$nlo,$NHI
-+	lghi	$NHI,0
-+	alcgr	$nhi,$NHI	# +="tp[j]"
-+	algr	$nlo,$alo
-+	alcgr	$NHI,$nhi
-+
-+	stg	$nlo,$stdframe-8($j,$sp)	# tp[j-1]=
-+	la	$j,8($j)	# j++
-+	brct	$count,.L1st
-+
-+	algr	$NHI,$AHI
-+	lghi	$AHI,0
-+	alcgr	$AHI,$AHI	# upmost overflow bit
-+	stg	$NHI,$stdframe-8($j,$sp)
-+	stg	$AHI,$stdframe($j,$sp)
-+	la	$bp,8($bp)	# bp++
-+
-+.Louter:
-+	lg	$bi,0($bp)	# bp[i]
-+	_dswap	$bi
-+	lg	$alo,0($ap)
-+	_dswap	$alo
-+	mlgr	$ahi,$bi	# ap[0]*bp[i]
-+	alg	$alo,$stdframe($sp)	# +=tp[0]
-+	lghi	$AHI,0
-+	alcgr	$AHI,$ahi
-+
-+	lgr	$mn0,$alo
-+	msgr	$mn0,$n0	# tp[0]*n0
-+
-+	lg	$nlo,0($np)	# np[0]
-+	_dswap	$nlo
-+	mlgr	$nhi,$mn0	# np[0]*m1
-+	algr	$nlo,$alo	# +="tp[0]"
-+	lghi	$NHI,0
-+	alcgr	$NHI,$nhi
-+
-+	la	$j,8(%r0)	# j=1
-+	lr	$count,$num
-+
-+.align	16
-+.Linner:
-+	lg	$alo,0($j,$ap)
-+	_dswap	$alo
-+	mlgr	$ahi,$bi	# ap[j]*bp[i]
-+	algr	$alo,$AHI
-+	lghi	$AHI,0
-+	alcgr	$ahi,$AHI
-+	alg	$alo,$stdframe($j,$sp)# +=tp[j]
-+	alcgr	$AHI,$ahi
-+
-+	lg	$nlo,0($j,$np)
-+	_dswap	$nlo
-+	mlgr	$nhi,$mn0	# np[j]*m1
-+	algr	$nlo,$NHI
-+	lghi	$NHI,0
-+	alcgr	$nhi,$NHI
-+	algr	$nlo,$alo	# +="tp[j]"
-+	alcgr	$NHI,$nhi
-+
-+	stg	$nlo,$stdframe-8($j,$sp)	# tp[j-1]=
-+	la	$j,8($j)	# j++
-+	brct	$count,.Linner
-+
-+	algr	$NHI,$AHI
-+	lghi	$AHI,0
-+	alcgr	$AHI,$AHI
-+	alg	$NHI,$stdframe($j,$sp)# accumulate previous upmost overflow bit
-+	lghi	$ahi,0
-+	alcgr	$AHI,$ahi	# new upmost overflow bit
-+	stg	$NHI,$stdframe-8($j,$sp)
-+	stg	$AHI,$stdframe($j,$sp)
-+
-+	la	$bp,8($bp)	# bp++
-+	cl${g}	$bp,`$stdframe+8+4*$SIZE_T`($j,$sp)	# compare to &bp[num]
-+	jne	.Louter
-+
-+	l${g}	$rp,`$stdframe+8+2*$SIZE_T`($j,$sp)	# reincarnate rp
-+	la	$ap,$stdframe($sp)
-+	ahi	$num,1		# restore $num, incidentally clears "borrow"
-+
-+	la	$j,0(%r0)
-+	lr	$count,$num
-+.Lsub:	lg	$alo,0($j,$ap)
-+	lg	$nlo,0($j,$np)
-+	_dswap	$nlo
-+	slbgr	$alo,$nlo
-+	stg	$alo,0($j,$rp)
-+	la	$j,8($j)
-+	brct	$count,.Lsub
-+	lghi	$ahi,0
-+	slbgr	$AHI,$ahi	# handle upmost carry
-+
-+	ngr	$ap,$AHI
-+	lghi	$np,-1
-+	xgr	$np,$AHI
-+	ngr	$np,$rp
-+	ogr	$ap,$np		# ap=borrow?tp:rp
-+
-+	la	$j,0(%r0)
-+	lgr	$count,$num
-+.Lcopy:	lg	$alo,0($j,$ap)		# copy or in-place refresh
-+	_dswap	$alo
-+	stg	$j,$stdframe($j,$sp)	# zap tp
-+	stg	$alo,0($j,$rp)
-+	la	$j,8($j)
-+	brct	$count,.Lcopy
-+
-+	la	%r1,`$stdframe+8+6*$SIZE_T`($j,$sp)
-+	lm${g}	%r6,%r15,0(%r1)
-+	lghi	%r2,1		# signal "processed"
-+	br	%r14
-+.size	bn_mul_mont,.-bn_mul_mont
-+.string	"Montgomery Multiplication for s390x, CRYPTOGAMS by "
-+___
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+	s/_dswap\s+(%r[0-9]+)/sprintf("rllg\t%s,%s,32",$1,$1) if($SIZE_T==4)/e;
-+	print $_,"\n";
-+}
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x.S b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x.S
-new file mode 100755
-index 0000000..292a7a9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/s390x.S
-@@ -0,0 +1,713 @@
-+.ident "s390x.S, version 1.1"
-+// ====================================================================
-+// Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+//
-+// Licensed under the OpenSSL license (the "License").  You may not use
-+// this file except in compliance with the License.  You can obtain a copy
-+// in the file LICENSE in the source distribution or at
-+// https://www.openssl.org/source/license.html
-+// ====================================================================
-+
-+.text
-+
-+#define zero	%r0
-+
-+// BN_ULONG bn_mul_add_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
-+.globl	bn_mul_add_words
-+.type	bn_mul_add_words,@function
-+.align	4
-+bn_mul_add_words:
-+	lghi	zero,0		// zero = 0
-+	la	%r1,0(%r2)	// put rp aside [to give way to]
-+	lghi	%r2,0		// return value
-+	ltgfr	%r4,%r4
-+	bler	%r14		// if (len<=0) return 0;
-+
-+	stmg	%r6,%r13,48(%r15)
-+	lghi	%r2,3
-+	lghi	%r12,0		// carry = 0
-+	slgr	%r1,%r3		// rp-=ap
-+	nr	%r2,%r4		// len%4
-+	sra	%r4,2		// cnt=len/4
-+	jz	.Loop1_madd	// carry is incidentally cleared if branch taken
-+	algr	zero,zero	// clear carry
-+
-+	lg	%r7,0(%r3)	// ap[0]
-+	lg	%r9,8(%r3)	// ap[1]
-+	mlgr	%r6,%r5		// *=w
-+	brct	%r4,.Loop4_madd
-+	j	.Loop4_madd_tail
-+
-+.Loop4_madd:
-+	mlgr	%r8,%r5
-+	lg	%r11,16(%r3)	// ap[i+2]
-+	alcgr	%r7,%r12	// +=carry
-+	alcgr	%r6,zero
-+	alg	%r7,0(%r3,%r1)	// +=rp[i]
-+	stg	%r7,0(%r3,%r1)	// rp[i]=
-+
-+	mlgr	%r10,%r5
-+	lg	%r13,24(%r3)
-+	alcgr	%r9,%r6
-+	alcgr	%r8,zero
-+	alg	%r9,8(%r3,%r1)
-+	stg	%r9,8(%r3,%r1)
-+
-+	mlgr	%r12,%r5
-+	lg	%r7,32(%r3)
-+	alcgr	%r11,%r8
-+	alcgr	%r10,zero
-+	alg	%r11,16(%r3,%r1)
-+	stg	%r11,16(%r3,%r1)
-+
-+	mlgr	%r6,%r5
-+	lg	%r9,40(%r3)
-+	alcgr	%r13,%r10
-+	alcgr	%r12,zero
-+	alg	%r13,24(%r3,%r1)
-+	stg	%r13,24(%r3,%r1)
-+
-+	la	%r3,32(%r3)	// i+=4
-+	brct	%r4,.Loop4_madd
-+
-+.Loop4_madd_tail:
-+	mlgr	%r8,%r5
-+	lg	%r11,16(%r3)
-+	alcgr	%r7,%r12	// +=carry
-+	alcgr	%r6,zero
-+	alg	%r7,0(%r3,%r1)	// +=rp[i]
-+	stg	%r7,0(%r3,%r1)	// rp[i]=
-+
-+	mlgr	%r10,%r5
-+	lg	%r13,24(%r3)
-+	alcgr	%r9,%r6
-+	alcgr	%r8,zero
-+	alg	%r9,8(%r3,%r1)
-+	stg	%r9,8(%r3,%r1)
-+
-+	mlgr	%r12,%r5
-+	alcgr	%r11,%r8
-+	alcgr	%r10,zero
-+	alg	%r11,16(%r3,%r1)
-+	stg	%r11,16(%r3,%r1)
-+
-+	alcgr	%r13,%r10
-+	alcgr	%r12,zero
-+	alg	%r13,24(%r3,%r1)
-+	stg	%r13,24(%r3,%r1)
-+
-+	la	%r3,32(%r3)	// i+=4
-+
-+	la	%r2,1(%r2)	// see if len%4 is zero ...
-+	brct	%r2,.Loop1_madd	// without touching condition code:-)
-+
-+.Lend_madd:
-+	lgr	%r2,zero	// return value
-+	alcgr	%r2,%r12	// collect even carry bit
-+	lmg	%r6,%r13,48(%r15)
-+	br	%r14
-+
-+.Loop1_madd:
-+	lg	%r7,0(%r3)	// ap[i]
-+	mlgr	%r6,%r5		// *=w
-+	alcgr	%r7,%r12	// +=carry
-+	alcgr	%r6,zero
-+	alg	%r7,0(%r3,%r1)	// +=rp[i]
-+	stg	%r7,0(%r3,%r1)	// rp[i]=
-+
-+	lgr	%r12,%r6
-+	la	%r3,8(%r3)	// i++
-+	brct	%r2,.Loop1_madd
-+
-+	j	.Lend_madd
-+.size	bn_mul_add_words,.-bn_mul_add_words
-+
-+// BN_ULONG bn_mul_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
-+.globl	bn_mul_words
-+.type	bn_mul_words,@function
-+.align	4
-+bn_mul_words:
-+	lghi	zero,0		// zero = 0
-+	la	%r1,0(%r2)	// put rp aside
-+	lghi	%r2,0		// i=0;
-+	ltgfr	%r4,%r4
-+	bler	%r14		// if (len<=0) return 0;
-+
-+	stmg	%r6,%r10,48(%r15)
-+	lghi	%r10,3
-+	lghi	%r8,0		// carry = 0
-+	nr	%r10,%r4	// len%4
-+	sra	%r4,2		// cnt=len/4
-+	jz	.Loop1_mul	// carry is incidentally cleared if branch taken
-+	algr	zero,zero	// clear carry
-+
-+.Loop4_mul:
-+	lg	%r7,0(%r2,%r3)	// ap[i]
-+	mlgr	%r6,%r5		// *=w
-+	alcgr	%r7,%r8		// +=carry
-+	stg	%r7,0(%r2,%r1)	// rp[i]=
-+
-+	lg	%r9,8(%r2,%r3)
-+	mlgr	%r8,%r5
-+	alcgr	%r9,%r6
-+	stg	%r9,8(%r2,%r1)
-+
-+	lg	%r7,16(%r2,%r3)
-+	mlgr	%r6,%r5
-+	alcgr	%r7,%r8
-+	stg	%r7,16(%r2,%r1)
-+
-+	lg	%r9,24(%r2,%r3)
-+	mlgr	%r8,%r5
-+	alcgr	%r9,%r6
-+	stg	%r9,24(%r2,%r1)
-+
-+	la	%r2,32(%r2)	// i+=4
-+	brct	%r4,.Loop4_mul
-+
-+	la	%r10,1(%r10)		// see if len%4 is zero ...
-+	brct	%r10,.Loop1_mul		// without touching condition code:-)
-+
-+.Lend_mul:
-+	alcgr	%r8,zero	// collect carry bit
-+	lgr	%r2,%r8
-+	lmg	%r6,%r10,48(%r15)
-+	br	%r14
-+
-+.Loop1_mul:
-+	lg	%r7,0(%r2,%r3)	// ap[i]
-+	mlgr	%r6,%r5		// *=w
-+	alcgr	%r7,%r8		// +=carry
-+	stg	%r7,0(%r2,%r1)	// rp[i]=
-+
-+	lgr	%r8,%r6
-+	la	%r2,8(%r2)	// i++
-+	brct	%r10,.Loop1_mul
-+
-+	j	.Lend_mul
-+.size	bn_mul_words,.-bn_mul_words
-+
-+// void bn_sqr_words(BN_ULONG *r2,BN_ULONG *r2,int r4)
-+.globl	bn_sqr_words
-+.type	bn_sqr_words,@function
-+.align	4
-+bn_sqr_words:
-+	ltgfr	%r4,%r4
-+	bler	%r14
-+
-+	stmg	%r6,%r7,48(%r15)
-+	srag	%r1,%r4,2	// cnt=len/4
-+	jz	.Loop1_sqr
-+
-+.Loop4_sqr:
-+	lg	%r7,0(%r3)
-+	mlgr	%r6,%r7
-+	stg	%r7,0(%r2)
-+	stg	%r6,8(%r2)
-+
-+	lg	%r7,8(%r3)
-+	mlgr	%r6,%r7
-+	stg	%r7,16(%r2)
-+	stg	%r6,24(%r2)
-+
-+	lg	%r7,16(%r3)
-+	mlgr	%r6,%r7
-+	stg	%r7,32(%r2)
-+	stg	%r6,40(%r2)
-+
-+	lg	%r7,24(%r3)
-+	mlgr	%r6,%r7
-+	stg	%r7,48(%r2)
-+	stg	%r6,56(%r2)
-+
-+	la	%r3,32(%r3)
-+	la	%r2,64(%r2)
-+	brct	%r1,.Loop4_sqr
-+
-+	lghi	%r1,3
-+	nr	%r4,%r1		// cnt=len%4
-+	jz	.Lend_sqr
-+
-+.Loop1_sqr:
-+	lg	%r7,0(%r3)
-+	mlgr	%r6,%r7
-+	stg	%r7,0(%r2)
-+	stg	%r6,8(%r2)
-+
-+	la	%r3,8(%r3)
-+	la	%r2,16(%r2)
-+	brct	%r4,.Loop1_sqr
-+
-+.Lend_sqr:
-+	lmg	%r6,%r7,48(%r15)
-+	br	%r14
-+.size	bn_sqr_words,.-bn_sqr_words
-+
-+// BN_ULONG bn_div_words(BN_ULONG h,BN_ULONG l,BN_ULONG d);
-+.globl	bn_div_words
-+.type	bn_div_words,@function
-+.align	4
-+bn_div_words:
-+	dlgr	%r2,%r4
-+	lgr	%r2,%r3
-+	br	%r14
-+.size	bn_div_words,.-bn_div_words
-+
-+// BN_ULONG bn_add_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
-+.globl	bn_add_words
-+.type	bn_add_words,@function
-+.align	4
-+bn_add_words:
-+	la	%r1,0(%r2)	// put rp aside
-+	lghi	%r2,0		// i=0
-+	ltgfr	%r5,%r5
-+	bler	%r14		// if (len<=0) return 0;
-+
-+	stg	%r6,48(%r15)
-+	lghi	%r6,3
-+	nr	%r6,%r5		// len%4
-+	sra	%r5,2		// len/4, use sra because it sets condition code
-+	jz	.Loop1_add	// carry is incidentally cleared if branch taken
-+	algr	%r2,%r2		// clear carry
-+
-+.Loop4_add:
-+	lg	%r0,0(%r2,%r3)
-+	alcg	%r0,0(%r2,%r4)
-+	stg	%r0,0(%r2,%r1)
-+	lg	%r0,8(%r2,%r3)
-+	alcg	%r0,8(%r2,%r4)
-+	stg	%r0,8(%r2,%r1)
-+	lg	%r0,16(%r2,%r3)
-+	alcg	%r0,16(%r2,%r4)
-+	stg	%r0,16(%r2,%r1)
-+	lg	%r0,24(%r2,%r3)
-+	alcg	%r0,24(%r2,%r4)
-+	stg	%r0,24(%r2,%r1)
-+
-+	la	%r2,32(%r2)	// i+=4
-+	brct	%r5,.Loop4_add
-+
-+	la	%r6,1(%r6)	// see if len%4 is zero ...
-+	brct	%r6,.Loop1_add	// without touching condition code:-)
-+
-+.Lexit_add:
-+	lghi	%r2,0
-+	alcgr	%r2,%r2
-+	lg	%r6,48(%r15)
-+	br	%r14
-+
-+.Loop1_add:
-+	lg	%r0,0(%r2,%r3)
-+	alcg	%r0,0(%r2,%r4)
-+	stg	%r0,0(%r2,%r1)
-+
-+	la	%r2,8(%r2)	// i++
-+	brct	%r6,.Loop1_add
-+
-+	j	.Lexit_add
-+.size	bn_add_words,.-bn_add_words
-+
-+// BN_ULONG bn_sub_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
-+.globl	bn_sub_words
-+.type	bn_sub_words,@function
-+.align	4
-+bn_sub_words:
-+	la	%r1,0(%r2)	// put rp aside
-+	lghi	%r2,0		// i=0
-+	ltgfr	%r5,%r5
-+	bler	%r14		// if (len<=0) return 0;
-+
-+	stg	%r6,48(%r15)
-+	lghi	%r6,3
-+	nr	%r6,%r5		// len%4
-+	sra	%r5,2		// len/4, use sra because it sets condition code
-+	jnz	.Loop4_sub	// borrow is incidentally cleared if branch taken
-+	slgr	%r2,%r2		// clear borrow
-+
-+.Loop1_sub:
-+	lg	%r0,0(%r2,%r3)
-+	slbg	%r0,0(%r2,%r4)
-+	stg	%r0,0(%r2,%r1)
-+
-+	la	%r2,8(%r2)	// i++
-+	brct	%r6,.Loop1_sub
-+	j	.Lexit_sub
-+
-+.Loop4_sub:
-+	lg	%r0,0(%r2,%r3)
-+	slbg	%r0,0(%r2,%r4)
-+	stg	%r0,0(%r2,%r1)
-+	lg	%r0,8(%r2,%r3)
-+	slbg	%r0,8(%r2,%r4)
-+	stg	%r0,8(%r2,%r1)
-+	lg	%r0,16(%r2,%r3)
-+	slbg	%r0,16(%r2,%r4)
-+	stg	%r0,16(%r2,%r1)
-+	lg	%r0,24(%r2,%r3)
-+	slbg	%r0,24(%r2,%r4)
-+	stg	%r0,24(%r2,%r1)
-+
-+	la	%r2,32(%r2)	// i+=4
-+	brct	%r5,.Loop4_sub
-+
-+	la	%r6,1(%r6)	// see if len%4 is zero ...
-+	brct	%r6,.Loop1_sub	// without touching condition code:-)
-+
-+.Lexit_sub:
-+	lghi	%r2,0
-+	slbgr	%r2,%r2
-+	lcgr	%r2,%r2
-+	lg	%r6,48(%r15)
-+	br	%r14
-+.size	bn_sub_words,.-bn_sub_words
-+
-+#define c1	%r1
-+#define c2	%r5
-+#define c3	%r8
-+
-+#define mul_add_c(ai,bi,c1,c2,c3)	\
-+	lg	%r7,ai*8(%r3);		\
-+	mlg	%r6,bi*8(%r4);		\
-+	algr	c1,%r7;			\
-+	alcgr	c2,%r6;			\
-+	alcgr	c3,zero
-+
-+// void bn_mul_comba8(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
-+.globl	bn_mul_comba8
-+.type	bn_mul_comba8,@function
-+.align	4
-+bn_mul_comba8:
-+	stmg	%r6,%r8,48(%r15)
-+
-+	lghi	c1,0
-+	lghi	c2,0
-+	lghi	c3,0
-+	lghi	zero,0
-+
-+	mul_add_c(0,0,c1,c2,c3);
-+	stg	c1,0*8(%r2)
-+	lghi	c1,0
-+
-+	mul_add_c(0,1,c2,c3,c1);
-+	mul_add_c(1,0,c2,c3,c1);
-+	stg	c2,1*8(%r2)
-+	lghi	c2,0
-+
-+	mul_add_c(2,0,c3,c1,c2);
-+	mul_add_c(1,1,c3,c1,c2);
-+	mul_add_c(0,2,c3,c1,c2);
-+	stg	c3,2*8(%r2)
-+	lghi	c3,0
-+
-+	mul_add_c(0,3,c1,c2,c3);
-+	mul_add_c(1,2,c1,c2,c3);
-+	mul_add_c(2,1,c1,c2,c3);
-+	mul_add_c(3,0,c1,c2,c3);
-+	stg	c1,3*8(%r2)
-+	lghi	c1,0
-+
-+	mul_add_c(4,0,c2,c3,c1);
-+	mul_add_c(3,1,c2,c3,c1);
-+	mul_add_c(2,2,c2,c3,c1);
-+	mul_add_c(1,3,c2,c3,c1);
-+	mul_add_c(0,4,c2,c3,c1);
-+	stg	c2,4*8(%r2)
-+	lghi	c2,0
-+
-+	mul_add_c(0,5,c3,c1,c2);
-+	mul_add_c(1,4,c3,c1,c2);
-+	mul_add_c(2,3,c3,c1,c2);
-+	mul_add_c(3,2,c3,c1,c2);
-+	mul_add_c(4,1,c3,c1,c2);
-+	mul_add_c(5,0,c3,c1,c2);
-+	stg	c3,5*8(%r2)
-+	lghi	c3,0
-+
-+	mul_add_c(6,0,c1,c2,c3);
-+	mul_add_c(5,1,c1,c2,c3);
-+	mul_add_c(4,2,c1,c2,c3);
-+	mul_add_c(3,3,c1,c2,c3);
-+	mul_add_c(2,4,c1,c2,c3);
-+	mul_add_c(1,5,c1,c2,c3);
-+	mul_add_c(0,6,c1,c2,c3);
-+	stg	c1,6*8(%r2)
-+	lghi	c1,0
-+
-+	mul_add_c(0,7,c2,c3,c1);
-+	mul_add_c(1,6,c2,c3,c1);
-+	mul_add_c(2,5,c2,c3,c1);
-+	mul_add_c(3,4,c2,c3,c1);
-+	mul_add_c(4,3,c2,c3,c1);
-+	mul_add_c(5,2,c2,c3,c1);
-+	mul_add_c(6,1,c2,c3,c1);
-+	mul_add_c(7,0,c2,c3,c1);
-+	stg	c2,7*8(%r2)
-+	lghi	c2,0
-+
-+	mul_add_c(7,1,c3,c1,c2);
-+	mul_add_c(6,2,c3,c1,c2);
-+	mul_add_c(5,3,c3,c1,c2);
-+	mul_add_c(4,4,c3,c1,c2);
-+	mul_add_c(3,5,c3,c1,c2);
-+	mul_add_c(2,6,c3,c1,c2);
-+	mul_add_c(1,7,c3,c1,c2);
-+	stg	c3,8*8(%r2)
-+	lghi	c3,0
-+
-+	mul_add_c(2,7,c1,c2,c3);
-+	mul_add_c(3,6,c1,c2,c3);
-+	mul_add_c(4,5,c1,c2,c3);
-+	mul_add_c(5,4,c1,c2,c3);
-+	mul_add_c(6,3,c1,c2,c3);
-+	mul_add_c(7,2,c1,c2,c3);
-+	stg	c1,9*8(%r2)
-+	lghi	c1,0
-+
-+	mul_add_c(7,3,c2,c3,c1);
-+	mul_add_c(6,4,c2,c3,c1);
-+	mul_add_c(5,5,c2,c3,c1);
-+	mul_add_c(4,6,c2,c3,c1);
-+	mul_add_c(3,7,c2,c3,c1);
-+	stg	c2,10*8(%r2)
-+	lghi	c2,0
-+
-+	mul_add_c(4,7,c3,c1,c2);
-+	mul_add_c(5,6,c3,c1,c2);
-+	mul_add_c(6,5,c3,c1,c2);
-+	mul_add_c(7,4,c3,c1,c2);
-+	stg	c3,11*8(%r2)
-+	lghi	c3,0
-+
-+	mul_add_c(7,5,c1,c2,c3);
-+	mul_add_c(6,6,c1,c2,c3);
-+	mul_add_c(5,7,c1,c2,c3);
-+	stg	c1,12*8(%r2)
-+	lghi	c1,0
-+
-+
-+	mul_add_c(6,7,c2,c3,c1);
-+	mul_add_c(7,6,c2,c3,c1);
-+	stg	c2,13*8(%r2)
-+	lghi	c2,0
-+
-+	mul_add_c(7,7,c3,c1,c2);
-+	stg	c3,14*8(%r2)
-+	stg	c1,15*8(%r2)
-+
-+	lmg	%r6,%r8,48(%r15)
-+	br	%r14
-+.size	bn_mul_comba8,.-bn_mul_comba8
-+
-+// void bn_mul_comba4(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
-+.globl	bn_mul_comba4
-+.type	bn_mul_comba4,@function
-+.align	4
-+bn_mul_comba4:
-+	stmg	%r6,%r8,48(%r15)
-+
-+	lghi	c1,0
-+	lghi	c2,0
-+	lghi	c3,0
-+	lghi	zero,0
-+
-+	mul_add_c(0,0,c1,c2,c3);
-+	stg	c1,0*8(%r3)
-+	lghi	c1,0
-+
-+	mul_add_c(0,1,c2,c3,c1);
-+	mul_add_c(1,0,c2,c3,c1);
-+	stg	c2,1*8(%r2)
-+	lghi	c2,0
-+
-+	mul_add_c(2,0,c3,c1,c2);
-+	mul_add_c(1,1,c3,c1,c2);
-+	mul_add_c(0,2,c3,c1,c2);
-+	stg	c3,2*8(%r2)
-+	lghi	c3,0
-+
-+	mul_add_c(0,3,c1,c2,c3);
-+	mul_add_c(1,2,c1,c2,c3);
-+	mul_add_c(2,1,c1,c2,c3);
-+	mul_add_c(3,0,c1,c2,c3);
-+	stg	c1,3*8(%r2)
-+	lghi	c1,0
-+
-+	mul_add_c(3,1,c2,c3,c1);
-+	mul_add_c(2,2,c2,c3,c1);
-+	mul_add_c(1,3,c2,c3,c1);
-+	stg	c2,4*8(%r2)
-+	lghi	c2,0
-+
-+	mul_add_c(2,3,c3,c1,c2);
-+	mul_add_c(3,2,c3,c1,c2);
-+	stg	c3,5*8(%r2)
-+	lghi	c3,0
-+
-+	mul_add_c(3,3,c1,c2,c3);
-+	stg	c1,6*8(%r2)
-+	stg	c2,7*8(%r2)
-+
-+	stmg	%r6,%r8,48(%r15)
-+	br	%r14
-+.size	bn_mul_comba4,.-bn_mul_comba4
-+
-+#define sqr_add_c(ai,c1,c2,c3)		\
-+	lg	%r7,ai*8(%r3);		\
-+	mlgr	%r6,%r7;		\
-+	algr	c1,%r7;			\
-+	alcgr	c2,%r6;			\
-+	alcgr	c3,zero
-+
-+#define sqr_add_c2(ai,aj,c1,c2,c3)	\
-+	lg	%r7,ai*8(%r3);		\
-+	mlg	%r6,aj*8(%r3);		\
-+	algr	c1,%r7;			\
-+	alcgr	c2,%r6;			\
-+	alcgr	c3,zero;		\
-+	algr	c1,%r7;			\
-+	alcgr	c2,%r6;			\
-+	alcgr	c3,zero
-+
-+// void bn_sqr_comba8(BN_ULONG *r2,BN_ULONG *r3);
-+.globl	bn_sqr_comba8
-+.type	bn_sqr_comba8,@function
-+.align	4
-+bn_sqr_comba8:
-+	stmg	%r6,%r8,48(%r15)
-+
-+	lghi	c1,0
-+	lghi	c2,0
-+	lghi	c3,0
-+	lghi	zero,0
-+
-+	sqr_add_c(0,c1,c2,c3);
-+	stg	c1,0*8(%r2)
-+	lghi	c1,0
-+
-+	sqr_add_c2(1,0,c2,c3,c1);
-+	stg	c2,1*8(%r2)
-+	lghi	c2,0
-+
-+	sqr_add_c(1,c3,c1,c2);
-+	sqr_add_c2(2,0,c3,c1,c2);
-+	stg	c3,2*8(%r2)
-+	lghi	c3,0
-+
-+	sqr_add_c2(3,0,c1,c2,c3);
-+	sqr_add_c2(2,1,c1,c2,c3);
-+	stg	c1,3*8(%r2)
-+	lghi	c1,0
-+
-+	sqr_add_c(2,c2,c3,c1);
-+	sqr_add_c2(3,1,c2,c3,c1);
-+	sqr_add_c2(4,0,c2,c3,c1);
-+	stg	c2,4*8(%r2)
-+	lghi	c2,0
-+
-+	sqr_add_c2(5,0,c3,c1,c2);
-+	sqr_add_c2(4,1,c3,c1,c2);
-+	sqr_add_c2(3,2,c3,c1,c2);
-+	stg	c3,5*8(%r2)
-+	lghi	c3,0
-+
-+	sqr_add_c(3,c1,c2,c3);
-+	sqr_add_c2(4,2,c1,c2,c3);
-+	sqr_add_c2(5,1,c1,c2,c3);
-+	sqr_add_c2(6,0,c1,c2,c3);
-+	stg	c1,6*8(%r2)
-+	lghi	c1,0
-+
-+	sqr_add_c2(7,0,c2,c3,c1);
-+	sqr_add_c2(6,1,c2,c3,c1);
-+	sqr_add_c2(5,2,c2,c3,c1);
-+	sqr_add_c2(4,3,c2,c3,c1);
-+	stg	c2,7*8(%r2)
-+	lghi	c2,0
-+
-+	sqr_add_c(4,c3,c1,c2);
-+	sqr_add_c2(5,3,c3,c1,c2);
-+	sqr_add_c2(6,2,c3,c1,c2);
-+	sqr_add_c2(7,1,c3,c1,c2);
-+	stg	c3,8*8(%r2)
-+	lghi	c3,0
-+
-+	sqr_add_c2(7,2,c1,c2,c3);
-+	sqr_add_c2(6,3,c1,c2,c3);
-+	sqr_add_c2(5,4,c1,c2,c3);
-+	stg	c1,9*8(%r2)
-+	lghi	c1,0
-+
-+	sqr_add_c(5,c2,c3,c1);
-+	sqr_add_c2(6,4,c2,c3,c1);
-+	sqr_add_c2(7,3,c2,c3,c1);
-+	stg	c2,10*8(%r2)
-+	lghi	c2,0
-+
-+	sqr_add_c2(7,4,c3,c1,c2);
-+	sqr_add_c2(6,5,c3,c1,c2);
-+	stg	c3,11*8(%r2)
-+	lghi	c3,0
-+
-+	sqr_add_c(6,c1,c2,c3);
-+	sqr_add_c2(7,5,c1,c2,c3);
-+	stg	c1,12*8(%r2)
-+	lghi	c1,0
-+
-+	sqr_add_c2(7,6,c2,c3,c1);
-+	stg	c2,13*8(%r2)
-+	lghi	c2,0
-+
-+	sqr_add_c(7,c3,c1,c2);
-+	stg	c3,14*8(%r2)
-+	stg	c1,15*8(%r2)
-+
-+	lmg	%r6,%r8,48(%r15)
-+	br	%r14
-+.size	bn_sqr_comba8,.-bn_sqr_comba8
-+
-+// void bn_sqr_comba4(BN_ULONG *r2,BN_ULONG *r3);
-+.globl bn_sqr_comba4
-+.type	bn_sqr_comba4,@function
-+.align	4
-+bn_sqr_comba4:
-+	stmg	%r6,%r8,48(%r15)
-+
-+	lghi	c1,0
-+	lghi	c2,0
-+	lghi	c3,0
-+	lghi	zero,0
-+
-+	sqr_add_c(0,c1,c2,c3);
-+	stg	c1,0*8(%r2)
-+	lghi	c1,0
-+
-+	sqr_add_c2(1,0,c2,c3,c1);
-+	stg	c2,1*8(%r2)
-+	lghi	c2,0
-+
-+	sqr_add_c(1,c3,c1,c2);
-+	sqr_add_c2(2,0,c3,c1,c2);
-+	stg	c3,2*8(%r2)
-+	lghi	c3,0
-+
-+	sqr_add_c2(3,0,c1,c2,c3);
-+	sqr_add_c2(2,1,c1,c2,c3);
-+	stg	c1,3*8(%r2)
-+	lghi	c1,0
-+
-+	sqr_add_c(2,c2,c3,c1);
-+	sqr_add_c2(3,1,c2,c3,c1);
-+	stg	c2,4*8(%r2)
-+	lghi	c2,0
-+
-+	sqr_add_c2(3,2,c3,c1,c2);
-+	stg	c3,5*8(%r2)
-+	lghi	c3,0
-+
-+	sqr_add_c(3,c1,c2,c3);
-+	stg	c1,6*8(%r2)
-+	stg	c2,7*8(%r2)
-+
-+	lmg	%r6,%r8,48(%r15)
-+	br	%r14
-+.size	bn_sqr_comba4,.-bn_sqr_comba4
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparct4-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparct4-mont.pl
-new file mode 100755
-index 0000000..4faf66f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparct4-mont.pl
-@@ -0,0 +1,1232 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by David S. Miller  and Andy Polyakov
-+# . The module is licensed under 2-clause BSD
-+# license. November 2012. All rights reserved.
-+# ====================================================================
-+
-+######################################################################
-+# Montgomery squaring-n-multiplication module for SPARC T4.
-+#
-+# The module consists of three parts:
-+#
-+# 1) collection of "single-op" subroutines that perform single
-+#    operation, Montgomery squaring or multiplication, on 512-,
-+#    1024-, 1536- and 2048-bit operands;
-+# 2) collection of "multi-op" subroutines that perform 5 squaring and
-+#    1 multiplication operations on operands of above lengths;
-+# 3) fall-back and helper VIS3 subroutines.
-+#
-+# RSA sign is dominated by multi-op subroutine, while RSA verify and
-+# DSA - by single-op. Special note about 4096-bit RSA verify result.
-+# Operands are too long for dedicated hardware and it's handled by
-+# VIS3 code, which is why you don't see any improvement. It's surely
-+# possible to improve it [by deploying 'mpmul' instruction], maybe in
-+# the future...
-+#
-+# Performance improvement.
-+#
-+# 64-bit process, VIS3:
-+#                   sign    verify    sign/s verify/s
-+# rsa 1024 bits 0.000628s 0.000028s   1592.4  35434.4
-+# rsa 2048 bits 0.003282s 0.000106s    304.7   9438.3
-+# rsa 4096 bits 0.025866s 0.000340s     38.7   2940.9
-+# dsa 1024 bits 0.000301s 0.000332s   3323.7   3013.9
-+# dsa 2048 bits 0.001056s 0.001233s    946.9    810.8
-+#
-+# 64-bit process, this module:
-+#                   sign    verify    sign/s verify/s
-+# rsa 1024 bits 0.000256s 0.000016s   3904.4  61411.9
-+# rsa 2048 bits 0.000946s 0.000029s   1056.8  34292.7
-+# rsa 4096 bits 0.005061s 0.000340s    197.6   2940.5
-+# dsa 1024 bits 0.000176s 0.000195s   5674.7   5130.5
-+# dsa 2048 bits 0.000296s 0.000354s   3383.2   2827.6
-+#
-+######################################################################
-+# 32-bit process, VIS3:
-+#                   sign    verify    sign/s verify/s
-+# rsa 1024 bits 0.000665s 0.000028s   1504.8  35233.3
-+# rsa 2048 bits 0.003349s 0.000106s    298.6   9433.4
-+# rsa 4096 bits 0.025959s 0.000341s     38.5   2934.8
-+# dsa 1024 bits 0.000320s 0.000341s   3123.3   2929.6
-+# dsa 2048 bits 0.001101s 0.001260s    908.2    793.4
-+#
-+# 32-bit process, this module:
-+#                   sign    verify    sign/s verify/s
-+# rsa 1024 bits 0.000301s 0.000017s   3317.1  60240.0
-+# rsa 2048 bits 0.001034s 0.000030s    966.9  33812.7
-+# rsa 4096 bits 0.005244s 0.000341s    190.7   2935.4
-+# dsa 1024 bits 0.000201s 0.000205s   4976.1   4879.2
-+# dsa 2048 bits 0.000328s 0.000360s   3051.1   2774.2
-+#
-+# 32-bit code is prone to performance degradation as interrupt rate
-+# dispatched to CPU executing the code grows. This is because in
-+# standard process of handling interrupt in 32-bit process context
-+# upper halves of most integer registers used as input or output are
-+# zeroed. This renders result invalid, and operation has to be re-run.
-+# If CPU is "bothered" with timer interrupts only, the penalty is
-+# hardly measurable. But in order to mitigate this problem for higher
-+# interrupt rates contemporary Linux kernel recognizes biased stack
-+# even in 32-bit process context and preserves full register contents.
-+# See http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=517ffce4e1a03aea979fe3a18a3dd1761a24fafb
-+# for details.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "sparcv9_modes.pl";
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#ifdef	__arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+#endif
-+
-+.section	".text",#alloc,#execinstr
-+
-+#ifdef	__PIC__
-+SPARC_PIC_THUNK(%g1)
-+#endif
-+___
-+
-+########################################################################
-+# Register layout for mont[mul|sqr] instructions.
-+# For details see "Oracle SPARC Architecture 2011" manual at
-+# http://www.oracle.com/technetwork/server-storage/sun-sparc-enterprise/documentation/.
-+#
-+my @R=map("%f".2*$_,(0..11,30,31,12..29));
-+my @N=(map("%l$_",(0..7)),map("%o$_",(0..5))); @N=(@N,@N,@N[0..3]);
-+my @A=(@N[0..13],@R[14..31]);
-+my @B=(map("%i$_",(0..5)),map("%l$_",(0..7))); @B=(@B,@B,map("%o$_",(0..3)));
-+
-+########################################################################
-+# int bn_mul_mont_t4_$NUM(u64 *rp,const u64 *ap,const u64 *bp,
-+#			  const u64 *np,const BN_ULONG *n0);
-+#
-+sub generate_bn_mul_mont_t4() {
-+my $NUM=shift;
-+my ($rp,$ap,$bp,$np,$sentinel)=map("%g$_",(1..5));
-+
-+$code.=<<___;
-+.globl	bn_mul_mont_t4_$NUM
-+.align	32
-+bn_mul_mont_t4_$NUM:
-+#ifdef	__arch64__
-+	mov	0,$sentinel
-+	mov	-128,%g4
-+#elif defined(SPARCV9_64BIT_STACK)
-+	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+	ld	[%g1+0],%g1	! OPENSSL_sparcv9_P[0]
-+	mov	-2047,%g4
-+	and	%g1,SPARCV9_64BIT_STACK,%g1
-+	movrz	%g1,0,%g4
-+	mov	-1,$sentinel
-+	add	%g4,-128,%g4
-+#else
-+	mov	-1,$sentinel
-+	mov	-128,%g4
-+#endif
-+	sllx	$sentinel,32,$sentinel
-+	save	%sp,%g4,%sp
-+#ifndef	__arch64__
-+	save	%sp,-128,%sp	! warm it up
-+	save	%sp,-128,%sp
-+	save	%sp,-128,%sp
-+	save	%sp,-128,%sp
-+	save	%sp,-128,%sp
-+	save	%sp,-128,%sp
-+	restore
-+	restore
-+	restore
-+	restore
-+	restore
-+	restore
-+#endif
-+	and	%sp,1,%g4
-+	or	$sentinel,%fp,%fp
-+	or	%g4,$sentinel,$sentinel
-+
-+	! copy arguments to global registers
-+	mov	%i0,$rp
-+	mov	%i1,$ap
-+	mov	%i2,$bp
-+	mov	%i3,$np
-+	ld	[%i4+0],%f1	! load *n0
-+	ld	[%i4+4],%f0
-+	fsrc2	%f0,%f60
-+___
-+
-+# load ap[$NUM] ########################################################
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for($i=0; $i<14 && $i<$NUM; $i++) {
-+my $lo=$i<13?@A[$i+1]:"%o7";
-+$code.=<<___;
-+	ld	[$ap+$i*8+0],$lo
-+	ld	[$ap+$i*8+4],@A[$i]
-+	sllx	@A[$i],32,@A[$i]
-+	or	$lo,@A[$i],@A[$i]
-+___
-+}
-+for(; $i<$NUM; $i++) {
-+my ($hi,$lo)=("%f".2*($i%4),"%f".(2*($i%4)+1));
-+$code.=<<___;
-+	ld	[$ap+$i*8+0],$lo
-+	ld	[$ap+$i*8+4],$hi
-+	fsrc2	$hi,@A[$i]
-+___
-+}
-+# load np[$NUM] ########################################################
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for($i=0; $i<14 && $i<$NUM; $i++) {
-+my $lo=$i<13?@N[$i+1]:"%o7";
-+$code.=<<___;
-+	ld	[$np+$i*8+0],$lo
-+	ld	[$np+$i*8+4],@N[$i]
-+	sllx	@N[$i],32,@N[$i]
-+	or	$lo,@N[$i],@N[$i]
-+___
-+}
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for(; $i<28 && $i<$NUM; $i++) {
-+my $lo=$i<27?@N[$i+1]:"%o7";
-+$code.=<<___;
-+	ld	[$np+$i*8+0],$lo
-+	ld	[$np+$i*8+4],@N[$i]
-+	sllx	@N[$i],32,@N[$i]
-+	or	$lo,@N[$i],@N[$i]
-+___
-+}
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for(; $i<$NUM; $i++) {
-+my $lo=($i<$NUM-1)?@N[$i+1]:"%o7";
-+$code.=<<___;
-+	ld	[$np+$i*8+0],$lo
-+	ld	[$np+$i*8+4],@N[$i]
-+	sllx	@N[$i],32,@N[$i]
-+	or	$lo,@N[$i],@N[$i]
-+___
-+}
-+$code.=<<___;
-+	cmp	$ap,$bp
-+	be	SIZE_T_CC,.Lmsquare_$NUM
-+	nop
-+___
-+
-+# load bp[$NUM] ########################################################
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for($i=0; $i<14 && $i<$NUM; $i++) {
-+my $lo=$i<13?@B[$i+1]:"%o7";
-+$code.=<<___;
-+	ld	[$bp+$i*8+0],$lo
-+	ld	[$bp+$i*8+4],@B[$i]
-+	sllx	@B[$i],32,@B[$i]
-+	or	$lo,@B[$i],@B[$i]
-+___
-+}
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for(; $i<$NUM; $i++) {
-+my $lo=($i<$NUM-1)?@B[$i+1]:"%o7";
-+$code.=<<___;
-+	ld	[$bp+$i*8+0],$lo
-+	ld	[$bp+$i*8+4],@B[$i]
-+	sllx	@B[$i],32,@B[$i]
-+	or	$lo,@B[$i],@B[$i]
-+___
-+}
-+# magic ################################################################
-+$code.=<<___;
-+	.word	0x81b02920+$NUM-1	! montmul	$NUM-1
-+.Lmresume_$NUM:
-+	fbu,pn	%fcc3,.Lmabort_$NUM
-+#ifndef	__arch64__
-+	and	%fp,$sentinel,$sentinel
-+	brz,pn	$sentinel,.Lmabort_$NUM
-+#endif
-+	nop
-+#ifdef	__arch64__
-+	restore
-+	restore
-+	restore
-+	restore
-+	restore
-+#else
-+	restore;		and	%fp,$sentinel,$sentinel
-+	restore;		and	%fp,$sentinel,$sentinel
-+	restore;		and	%fp,$sentinel,$sentinel
-+	restore;		and	%fp,$sentinel,$sentinel
-+	 brz,pn	$sentinel,.Lmabort1_$NUM
-+	restore
-+#endif
-+___
-+
-+# save tp[$NUM] ########################################################
-+for($i=0; $i<14 && $i<$NUM; $i++) {
-+$code.=<<___;
-+	movxtod	@A[$i],@R[$i]
-+___
-+}
-+$code.=<<___;
-+#ifdef	__arch64__
-+	restore
-+#else
-+	 and	%fp,$sentinel,$sentinel
-+	restore
-+	 and	$sentinel,1,%o7
-+	 and	%fp,$sentinel,$sentinel
-+	 srl	%fp,0,%fp		! just in case?
-+	 or	%o7,$sentinel,$sentinel
-+	brz,a,pn $sentinel,.Lmdone_$NUM
-+	mov	0,%i0		! return failure
-+#endif
-+___
-+for($i=0; $i<12 && $i<$NUM; $i++) {
-+@R[$i] =~ /%f([0-9]+)/;
-+my $lo = "%f".($1+1);
-+$code.=<<___;
-+	st	$lo,[$rp+$i*8+0]
-+	st	@R[$i],[$rp+$i*8+4]
-+___
-+}
-+for(; $i<$NUM; $i++) {
-+my ($hi,$lo)=("%f".2*($i%4),"%f".(2*($i%4)+1));
-+$code.=<<___;
-+	fsrc2	@R[$i],$hi
-+	st	$lo,[$rp+$i*8+0]
-+	st	$hi,[$rp+$i*8+4]
-+___
-+}
-+$code.=<<___;
-+	mov	1,%i0		! return success
-+.Lmdone_$NUM:
-+	ret
-+	restore
-+
-+.Lmabort_$NUM:
-+	restore
-+	restore
-+	restore
-+	restore
-+	restore
-+.Lmabort1_$NUM:
-+	restore
-+
-+	mov	0,%i0		! return failure
-+	ret
-+	restore
-+
-+.align	32
-+.Lmsquare_$NUM:
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+	.word   0x81b02940+$NUM-1	! montsqr	$NUM-1
-+	ba	.Lmresume_$NUM
-+	nop
-+.type	bn_mul_mont_t4_$NUM, #function
-+.size	bn_mul_mont_t4_$NUM, .-bn_mul_mont_t4_$NUM
-+___
-+}
-+
-+for ($i=8;$i<=32;$i+=8) {
-+	&generate_bn_mul_mont_t4($i);
-+}
-+
-+########################################################################
-+#
-+sub load_ccr {
-+my ($ptbl,$pwr,$ccr,$skip_wr)=@_;
-+$code.=<<___;
-+	srl	$pwr,	2,	%o4
-+	and	$pwr,	3,	%o5
-+	and	%o4,	7,	%o4
-+	sll	%o5,	3,	%o5	! offset within first cache line
-+	add	%o5,	$ptbl,	$ptbl	! of the pwrtbl
-+	or	%g0,	1,	%o5
-+	sll	%o5,	%o4,	$ccr
-+___
-+$code.=<<___	if (!$skip_wr);
-+	wr	$ccr,	%g0,	%ccr
-+___
-+}
-+sub load_b_pair {
-+my ($pwrtbl,$B0,$B1)=@_;
-+
-+$code.=<<___;
-+	ldx	[$pwrtbl+0*32],	$B0
-+	ldx	[$pwrtbl+8*32],	$B1
-+	ldx	[$pwrtbl+1*32],	%o4
-+	ldx	[$pwrtbl+9*32],	%o5
-+	movvs	%icc,	%o4,	$B0
-+	ldx	[$pwrtbl+2*32],	%o4
-+	movvs	%icc,	%o5,	$B1
-+	ldx	[$pwrtbl+10*32],%o5
-+	move	%icc,	%o4,	$B0
-+	ldx	[$pwrtbl+3*32],	%o4
-+	move	%icc,	%o5,	$B1
-+	ldx	[$pwrtbl+11*32],%o5
-+	movneg	%icc,	%o4,	$B0
-+	ldx	[$pwrtbl+4*32],	%o4
-+	movneg	%icc,	%o5,	$B1
-+	ldx	[$pwrtbl+12*32],%o5
-+	movcs	%xcc,	%o4,	$B0
-+	ldx	[$pwrtbl+5*32],%o4
-+	movcs	%xcc,	%o5,	$B1
-+	ldx	[$pwrtbl+13*32],%o5
-+	movvs	%xcc,	%o4,	$B0
-+	ldx	[$pwrtbl+6*32],	%o4
-+	movvs	%xcc,	%o5,	$B1
-+	ldx	[$pwrtbl+14*32],%o5
-+	move	%xcc,	%o4,	$B0
-+	ldx	[$pwrtbl+7*32],	%o4
-+	move	%xcc,	%o5,	$B1
-+	ldx	[$pwrtbl+15*32],%o5
-+	movneg	%xcc,	%o4,	$B0
-+	add	$pwrtbl,16*32,	$pwrtbl
-+	movneg	%xcc,	%o5,	$B1
-+___
-+}
-+sub load_b {
-+my ($pwrtbl,$Bi)=@_;
-+
-+$code.=<<___;
-+	ldx	[$pwrtbl+0*32],	$Bi
-+	ldx	[$pwrtbl+1*32],	%o4
-+	ldx	[$pwrtbl+2*32],	%o5
-+	movvs	%icc,	%o4,	$Bi
-+	ldx	[$pwrtbl+3*32],	%o4
-+	move	%icc,	%o5,	$Bi
-+	ldx	[$pwrtbl+4*32],	%o5
-+	movneg	%icc,	%o4,	$Bi
-+	ldx	[$pwrtbl+5*32],	%o4
-+	movcs	%xcc,	%o5,	$Bi
-+	ldx	[$pwrtbl+6*32],	%o5
-+	movvs	%xcc,	%o4,	$Bi
-+	ldx	[$pwrtbl+7*32],	%o4
-+	move	%xcc,	%o5,	$Bi
-+	add	$pwrtbl,8*32,	$pwrtbl
-+	movneg	%xcc,	%o4,	$Bi
-+___
-+}
-+
-+########################################################################
-+# int bn_pwr5_mont_t4_$NUM(u64 *tp,const u64 *np,const BN_ULONG *n0,
-+#			   const u64 *pwrtbl,int pwr,int stride);
-+#
-+sub generate_bn_pwr5_mont_t4() {
-+my $NUM=shift;
-+my ($tp,$np,$pwrtbl,$pwr,$sentinel)=map("%g$_",(1..5));
-+
-+$code.=<<___;
-+.globl	bn_pwr5_mont_t4_$NUM
-+.align	32
-+bn_pwr5_mont_t4_$NUM:
-+#ifdef	__arch64__
-+	mov	0,$sentinel
-+	mov	-128,%g4
-+#elif defined(SPARCV9_64BIT_STACK)
-+	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+	ld	[%g1+0],%g1	! OPENSSL_sparcv9_P[0]
-+	mov	-2047,%g4
-+	and	%g1,SPARCV9_64BIT_STACK,%g1
-+	movrz	%g1,0,%g4
-+	mov	-1,$sentinel
-+	add	%g4,-128,%g4
-+#else
-+	mov	-1,$sentinel
-+	mov	-128,%g4
-+#endif
-+	sllx	$sentinel,32,$sentinel
-+	save	%sp,%g4,%sp
-+#ifndef	__arch64__
-+	save	%sp,-128,%sp	! warm it up
-+	save	%sp,-128,%sp
-+	save	%sp,-128,%sp
-+	save	%sp,-128,%sp
-+	save	%sp,-128,%sp
-+	save	%sp,-128,%sp
-+	restore
-+	restore
-+	restore
-+	restore
-+	restore
-+	restore
-+#endif
-+	and	%sp,1,%g4
-+	or	$sentinel,%fp,%fp
-+	or	%g4,$sentinel,$sentinel
-+
-+	! copy arguments to global registers
-+	mov	%i0,$tp
-+	mov	%i1,$np
-+	ld	[%i2+0],%f1	! load *n0
-+	ld	[%i2+4],%f0
-+	mov	%i3,$pwrtbl
-+	srl	%i4,%g0,%i4	! pack last arguments
-+	sllx	%i5,32,$pwr
-+	or	%i4,$pwr,$pwr
-+	fsrc2	%f0,%f60
-+___
-+
-+# load tp[$NUM] ########################################################
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for($i=0; $i<14 && $i<$NUM; $i++) {
-+$code.=<<___;
-+	ldx	[$tp+$i*8],@A[$i]
-+___
-+}
-+for(; $i<$NUM; $i++) {
-+$code.=<<___;
-+	ldd	[$tp+$i*8],@A[$i]
-+___
-+}
-+# load np[$NUM] ########################################################
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for($i=0; $i<14 && $i<$NUM; $i++) {
-+$code.=<<___;
-+	ldx	[$np+$i*8],@N[$i]
-+___
-+}
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for(; $i<28 && $i<$NUM; $i++) {
-+$code.=<<___;
-+	ldx	[$np+$i*8],@N[$i]
-+___
-+}
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for(; $i<$NUM; $i++) {
-+$code.=<<___;
-+	ldx	[$np+$i*8],@N[$i]
-+___
-+}
-+# load pwrtbl[pwr] ########################################################
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+
-+	srlx	$pwr,	32,	%o4		! unpack $pwr
-+	srl	$pwr,	%g0,	%o5
-+	sub	%o4,	5,	%o4
-+	mov	$pwrtbl,	%o7
-+	sllx	%o4,	32,	$pwr		! re-pack $pwr
-+	or	%o5,	$pwr,	$pwr
-+	srl	%o5,	%o4,	%o5
-+___
-+	&load_ccr("%o7","%o5","%o4");
-+$code.=<<___;
-+	b	.Lstride_$NUM
-+	nop
-+.align	16
-+.Lstride_$NUM:
-+___
-+for($i=0; $i<14 && $i<$NUM; $i+=2) {
-+	&load_b_pair("%o7",@B[$i],@B[$i+1]);
-+}
-+$code.=<<___;
-+	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-+___
-+for(; $i<$NUM; $i+=2) {
-+	&load_b_pair("%i7",@B[$i],@B[$i+1]);
-+}
-+$code.=<<___;
-+	srax	$pwr,	32,	%o4		! unpack $pwr
-+	srl	$pwr,	%g0,	%o5
-+	sub	%o4,	5,	%o4
-+	mov	$pwrtbl,	%i7
-+	sllx	%o4,	32,	$pwr		! re-pack $pwr
-+	or	%o5,	$pwr,	$pwr
-+	srl	%o5,	%o4,	%o5
-+___
-+	&load_ccr("%i7","%o5","%o4",1);
-+
-+# magic ################################################################
-+for($i=0; $i<5; $i++) {
-+$code.=<<___;
-+	.word	0x81b02940+$NUM-1	! montsqr	$NUM-1
-+	fbu,pn	%fcc3,.Labort_$NUM
-+#ifndef	__arch64__
-+	and	%fp,$sentinel,$sentinel
-+	brz,pn	$sentinel,.Labort_$NUM
-+#endif
-+	nop
-+___
-+}
-+$code.=<<___;
-+	wr	%o4,	%g0,	%ccr
-+	.word	0x81b02920+$NUM-1	! montmul	$NUM-1
-+	fbu,pn	%fcc3,.Labort_$NUM
-+#ifndef	__arch64__
-+	and	%fp,$sentinel,$sentinel
-+	brz,pn	$sentinel,.Labort_$NUM
-+#endif
-+
-+	srax	$pwr,	32,	%o4
-+#ifdef	__arch64__
-+	brgez	%o4,.Lstride_$NUM
-+	restore
-+	restore
-+	restore
-+	restore
-+	restore
-+#else
-+	brgez	%o4,.Lstride_$NUM
-+	restore;		and	%fp,$sentinel,$sentinel
-+	restore;		and	%fp,$sentinel,$sentinel
-+	restore;		and	%fp,$sentinel,$sentinel
-+	restore;		and	%fp,$sentinel,$sentinel
-+	 brz,pn	$sentinel,.Labort1_$NUM
-+	restore
-+#endif
-+___
-+
-+# save tp[$NUM] ########################################################
-+for($i=0; $i<14 && $i<$NUM; $i++) {
-+$code.=<<___;
-+	movxtod	@A[$i],@R[$i]
-+___
-+}
-+$code.=<<___;
-+#ifdef	__arch64__
-+	restore
-+#else
-+	 and	%fp,$sentinel,$sentinel
-+	restore
-+	 and	$sentinel,1,%o7
-+	 and	%fp,$sentinel,$sentinel
-+	 srl	%fp,0,%fp		! just in case?
-+	 or	%o7,$sentinel,$sentinel
-+	brz,a,pn $sentinel,.Ldone_$NUM
-+	mov	0,%i0		! return failure
-+#endif
-+___
-+for($i=0; $i<$NUM; $i++) {
-+$code.=<<___;
-+	std	@R[$i],[$tp+$i*8]
-+___
-+}
-+$code.=<<___;
-+	mov	1,%i0		! return success
-+.Ldone_$NUM:
-+	ret
-+	restore
-+
-+.Labort_$NUM:
-+	restore
-+	restore
-+	restore
-+	restore
-+	restore
-+.Labort1_$NUM:
-+	restore
-+
-+	mov	0,%i0		! return failure
-+	ret
-+	restore
-+.type	bn_pwr5_mont_t4_$NUM, #function
-+.size	bn_pwr5_mont_t4_$NUM, .-bn_pwr5_mont_t4_$NUM
-+___
-+}
-+
-+for ($i=8;$i<=32;$i+=8) {
-+	&generate_bn_pwr5_mont_t4($i);
-+}
-+
-+{
-+########################################################################
-+# Fall-back subroutines
-+#
-+# copy of bn_mul_mont_vis3 adjusted for vectors of 64-bit values
-+#
-+($n0,$m0,$m1,$lo0,$hi0, $lo1,$hi1,$aj,$alo,$nj,$nlo,$tj)=
-+	(map("%g$_",(1..5)),map("%o$_",(0..5,7)));
-+
-+# int bn_mul_mont(
-+$rp="%o0";	# u64 *rp,
-+$ap="%o1";	# const u64 *ap,
-+$bp="%o2";	# const u64 *bp,
-+$np="%o3";	# const u64 *np,
-+$n0p="%o4";	# const BN_ULONG *n0,
-+$num="%o5";	# int num);	# caller ensures that num is >=3
-+$code.=<<___;
-+.globl	bn_mul_mont_t4
-+.align	32
-+bn_mul_mont_t4:
-+	add	%sp,	STACK_BIAS,	%g4	! real top of stack
-+	sll	$num,	3,	$num		! size in bytes
-+	add	$num,	63,	%g1
-+	andn	%g1,	63,	%g1		! buffer size rounded up to 64 bytes
-+	sub	%g4,	%g1,	%g1
-+	andn	%g1,	63,	%g1		! align at 64 byte
-+	sub	%g1,	STACK_FRAME,	%g1	! new top of stack
-+	sub	%g1,	%g4,	%g1
-+
-+	save	%sp,	%g1,	%sp
-+___
-+#	+-------------------------------+<-----	%sp
-+#	.				.
-+#	+-------------------------------+<-----	aligned at 64 bytes
-+#	| __int64 tmp[0]		|
-+#	+-------------------------------+
-+#	.				.
-+#	.				.
-+#	+-------------------------------+<-----	aligned at 64 bytes
-+#	.				.
-+($rp,$ap,$bp,$np,$n0p,$num)=map("%i$_",(0..5));
-+($t0,$t1,$t2,$t3,$cnt,$tp,$bufsz)=map("%l$_",(0..7));
-+($ovf,$i)=($t0,$t1);
-+$code.=<<___;
-+	ld	[$n0p+0],	$t0	! pull n0[0..1] value
-+	ld	[$n0p+4],	$t1
-+	add	%sp, STACK_BIAS+STACK_FRAME, $tp
-+	ldx	[$bp+0],	$m0	! m0=bp[0]
-+	sllx	$t1,	32,	$n0
-+	add	$bp,	8,	$bp
-+	or	$t0,	$n0,	$n0
-+
-+	ldx	[$ap+0],	$aj	! ap[0]
-+
-+	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[0]
-+	umulxhi	$aj,	$m0,	$hi0
-+
-+	ldx	[$ap+8],	$aj	! ap[1]
-+	add	$ap,	16,	$ap
-+	ldx	[$np+0],	$nj	! np[0]
-+
-+	mulx	$lo0,	$n0,	$m1	! "tp[0]"*n0
-+
-+	mulx	$aj,	$m0,	$alo	! ap[1]*bp[0]
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+
-+	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-+	umulxhi	$nj,	$m1,	$hi1
-+
-+	ldx	[$np+8],	$nj	! np[1]
-+
-+	addcc	$lo0,	$lo1,	$lo1
-+	add	$np,	16,	$np
-+	addxc	%g0,	$hi1,	$hi1
-+
-+	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+
-+	ba	.L1st
-+	sub	$num,	24,	$cnt	! cnt=num-3
-+
-+.align	16
-+.L1st:
-+	addcc	$alo,	$hi0,	$lo0
-+	addxc	$aj,	%g0,	$hi0
-+
-+	ldx	[$ap+0],	$aj	! ap[j]
-+	addcc	$nlo,	$hi1,	$lo1
-+	add	$ap,	8,	$ap
-+	addxc	$nj,	%g0,	$hi1	! nhi=nj
-+
-+	ldx	[$np+0],	$nj	! np[j]
-+	mulx	$aj,	$m0,	$alo	! ap[j]*bp[0]
-+	add	$np,	8,	$np
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+
-+	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-+	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+	addxc	%g0,	$hi1,	$hi1
-+	stxa	$lo1,	[$tp]0xe2	! tp[j-1]
-+	add	$tp,	8,	$tp	! tp++
-+
-+	brnz,pt	$cnt,	.L1st
-+	sub	$cnt,	8,	$cnt	! j--
-+!.L1st
-+	addcc	$alo,	$hi0,	$lo0
-+	addxc	$aj,	%g0,	$hi0	! ahi=aj
-+
-+	addcc	$nlo,	$hi1,	$lo1
-+	addxc	$nj,	%g0,	$hi1
-+	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-+	addxc	%g0,	$hi1,	$hi1
-+	stxa	$lo1,	[$tp]0xe2	! tp[j-1]
-+	add	$tp,	8,	$tp
-+
-+	addcc	$hi0,	$hi1,	$hi1
-+	addxc	%g0,	%g0,	$ovf	! upmost overflow bit
-+	stxa	$hi1,	[$tp]0xe2
-+	add	$tp,	8,	$tp
-+
-+	ba	.Louter
-+	sub	$num,	16,	$i	! i=num-2
-+
-+.align	16
-+.Louter:
-+	ldx	[$bp+0],	$m0	! m0=bp[i]
-+	add	$bp,	8,	$bp
-+
-+	sub	$ap,	$num,	$ap	! rewind
-+	sub	$np,	$num,	$np
-+	sub	$tp,	$num,	$tp
-+
-+	ldx	[$ap+0],	$aj	! ap[0]
-+	ldx	[$np+0],	$nj	! np[0]
-+
-+	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[i]
-+	ldx	[$tp],		$tj	! tp[0]
-+	umulxhi	$aj,	$m0,	$hi0
-+	ldx	[$ap+8],	$aj	! ap[1]
-+	addcc	$lo0,	$tj,	$lo0	! ap[0]*bp[i]+tp[0]
-+	mulx	$aj,	$m0,	$alo	! ap[1]*bp[i]
-+	addxc	%g0,	$hi0,	$hi0
-+	mulx	$lo0,	$n0,	$m1	! tp[0]*n0
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-+	add	$ap,	16,	$ap
-+	umulxhi	$nj,	$m1,	$hi1
-+	ldx	[$np+8],	$nj	! np[1]
-+	add	$np,	16,	$np
-+	addcc	$lo1,	$lo0,	$lo1
-+	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-+	addxc	%g0,	$hi1,	$hi1
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+
-+	ba	.Linner
-+	sub	$num,	24,	$cnt	! cnt=num-3
-+.align	16
-+.Linner:
-+	addcc	$alo,	$hi0,	$lo0
-+	ldx	[$tp+8],	$tj	! tp[j]
-+	addxc	$aj,	%g0,	$hi0	! ahi=aj
-+	ldx	[$ap+0],	$aj	! ap[j]
-+	add	$ap,	8,	$ap
-+	addcc	$nlo,	$hi1,	$lo1
-+	mulx	$aj,	$m0,	$alo	! ap[j]*bp[i]
-+	addxc	$nj,	%g0,	$hi1	! nhi=nj
-+	ldx	[$np+0],	$nj	! np[j]
-+	add	$np,	8,	$np
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-+	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-+	addxc	%g0,	$hi0,	$hi0
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-+	addxc	%g0,	$hi1,	$hi1
-+	stx	$lo1,	[$tp]		! tp[j-1]
-+	add	$tp,	8,	$tp
-+	brnz,pt	$cnt,	.Linner
-+	sub	$cnt,	8,	$cnt
-+!.Linner
-+	ldx	[$tp+8],	$tj	! tp[j]
-+	addcc	$alo,	$hi0,	$lo0
-+	addxc	$aj,	%g0,	$hi0	! ahi=aj
-+	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-+	addxc	%g0,	$hi0,	$hi0
-+
-+	addcc	$nlo,	$hi1,	$lo1
-+	addxc	$nj,	%g0,	$hi1	! nhi=nj
-+	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-+	addxc	%g0,	$hi1,	$hi1
-+	stx	$lo1,	[$tp]		! tp[j-1]
-+
-+	subcc	%g0,	$ovf,	%g0	! move upmost overflow to CCR.xcc
-+	addxccc	$hi1,	$hi0,	$hi1
-+	addxc	%g0,	%g0,	$ovf
-+	stx	$hi1,	[$tp+8]
-+	add	$tp,	16,	$tp
-+
-+	brnz,pt	$i,	.Louter
-+	sub	$i,	8,	$i
-+
-+	sub	$ap,	$num,	$ap	! rewind
-+	sub	$np,	$num,	$np
-+	sub	$tp,	$num,	$tp
-+	ba	.Lsub
-+	subcc	$num,	8,	$cnt	! cnt=num-1 and clear CCR.xcc
-+
-+.align	16
-+.Lsub:
-+	ldx	[$tp],		$tj
-+	add	$tp,	8,	$tp
-+	ldx	[$np+0],	$nj
-+	add	$np,	8,	$np
-+	subccc	$tj,	$nj,	$t2	! tp[j]-np[j]
-+	srlx	$tj,	32,	$tj
-+	srlx	$nj,	32,	$nj
-+	subccc	$tj,	$nj,	$t3
-+	add	$rp,	8,	$rp
-+	st	$t2,	[$rp-4]		! reverse order
-+	st	$t3,	[$rp-8]
-+	brnz,pt	$cnt,	.Lsub
-+	sub	$cnt,	8,	$cnt
-+
-+	sub	$np,	$num,	$np	! rewind
-+	sub	$tp,	$num,	$tp
-+	sub	$rp,	$num,	$rp
-+
-+	subc	$ovf,	%g0,	$ovf	! handle upmost overflow bit
-+	and	$tp,	$ovf,	$ap
-+	andn	$rp,	$ovf,	$np
-+	or	$np,	$ap,	$ap	! ap=borrow?tp:rp
-+	ba	.Lcopy
-+	sub	$num,	8,	$cnt
-+
-+.align	16
-+.Lcopy:					! copy or in-place refresh
-+	ldx	[$ap+0],	$t2
-+	add	$ap,	8,	$ap
-+	stx	%g0,	[$tp]		! zap
-+	add	$tp,	8,	$tp
-+	stx	$t2,	[$rp+0]
-+	add	$rp,	8,	$rp
-+	brnz	$cnt,	.Lcopy
-+	sub	$cnt,	8,	$cnt
-+
-+	mov	1,	%o0
-+	ret
-+	restore
-+.type	bn_mul_mont_t4, #function
-+.size	bn_mul_mont_t4, .-bn_mul_mont_t4
-+___
-+
-+# int bn_mul_mont_gather5(
-+$rp="%o0";	# u64 *rp,
-+$ap="%o1";	# const u64 *ap,
-+$bp="%o2";	# const u64 *pwrtbl,
-+$np="%o3";	# const u64 *np,
-+$n0p="%o4";	# const BN_ULONG *n0,
-+$num="%o5";	# int num,	# caller ensures that num is >=3
-+		# int power);
-+$code.=<<___;
-+.globl	bn_mul_mont_gather5_t4
-+.align	32
-+bn_mul_mont_gather5_t4:
-+	add	%sp,	STACK_BIAS,	%g4	! real top of stack
-+	sll	$num,	3,	$num		! size in bytes
-+	add	$num,	63,	%g1
-+	andn	%g1,	63,	%g1		! buffer size rounded up to 64 bytes
-+	sub	%g4,	%g1,	%g1
-+	andn	%g1,	63,	%g1		! align at 64 byte
-+	sub	%g1,	STACK_FRAME,	%g1	! new top of stack
-+	sub	%g1,	%g4,	%g1
-+	LDPTR	[%sp+STACK_7thARG],	%g4	! load power, 7th argument
-+
-+	save	%sp,	%g1,	%sp
-+___
-+#	+-------------------------------+<-----	%sp
-+#	.				.
-+#	+-------------------------------+<-----	aligned at 64 bytes
-+#	| __int64 tmp[0]		|
-+#	+-------------------------------+
-+#	.				.
-+#	.				.
-+#	+-------------------------------+<-----	aligned at 64 bytes
-+#	.				.
-+($rp,$ap,$bp,$np,$n0p,$num)=map("%i$_",(0..5));
-+($t0,$t1,$t2,$t3,$cnt,$tp,$bufsz,$ccr)=map("%l$_",(0..7));
-+($ovf,$i)=($t0,$t1);
-+	&load_ccr($bp,"%g4",$ccr);
-+	&load_b($bp,$m0,"%o7");		# m0=bp[0]
-+
-+$code.=<<___;
-+	ld	[$n0p+0],	$t0	! pull n0[0..1] value
-+	ld	[$n0p+4],	$t1
-+	add	%sp, STACK_BIAS+STACK_FRAME, $tp
-+	sllx	$t1,	32,	$n0
-+	or	$t0,	$n0,	$n0
-+
-+	ldx	[$ap+0],	$aj	! ap[0]
-+
-+	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[0]
-+	umulxhi	$aj,	$m0,	$hi0
-+
-+	ldx	[$ap+8],	$aj	! ap[1]
-+	add	$ap,	16,	$ap
-+	ldx	[$np+0],	$nj	! np[0]
-+
-+	mulx	$lo0,	$n0,	$m1	! "tp[0]"*n0
-+
-+	mulx	$aj,	$m0,	$alo	! ap[1]*bp[0]
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+
-+	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-+	umulxhi	$nj,	$m1,	$hi1
-+
-+	ldx	[$np+8],	$nj	! np[1]
-+
-+	addcc	$lo0,	$lo1,	$lo1
-+	add	$np,	16,	$np
-+	addxc	%g0,	$hi1,	$hi1
-+
-+	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+
-+	ba	.L1st_g5
-+	sub	$num,	24,	$cnt	! cnt=num-3
-+
-+.align	16
-+.L1st_g5:
-+	addcc	$alo,	$hi0,	$lo0
-+	addxc	$aj,	%g0,	$hi0
-+
-+	ldx	[$ap+0],	$aj	! ap[j]
-+	addcc	$nlo,	$hi1,	$lo1
-+	add	$ap,	8,	$ap
-+	addxc	$nj,	%g0,	$hi1	! nhi=nj
-+
-+	ldx	[$np+0],	$nj	! np[j]
-+	mulx	$aj,	$m0,	$alo	! ap[j]*bp[0]
-+	add	$np,	8,	$np
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+
-+	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-+	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+	addxc	%g0,	$hi1,	$hi1
-+	stxa	$lo1,	[$tp]0xe2	! tp[j-1]
-+	add	$tp,	8,	$tp	! tp++
-+
-+	brnz,pt	$cnt,	.L1st_g5
-+	sub	$cnt,	8,	$cnt	! j--
-+!.L1st_g5
-+	addcc	$alo,	$hi0,	$lo0
-+	addxc	$aj,	%g0,	$hi0	! ahi=aj
-+
-+	addcc	$nlo,	$hi1,	$lo1
-+	addxc	$nj,	%g0,	$hi1
-+	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-+	addxc	%g0,	$hi1,	$hi1
-+	stxa	$lo1,	[$tp]0xe2	! tp[j-1]
-+	add	$tp,	8,	$tp
-+
-+	addcc	$hi0,	$hi1,	$hi1
-+	addxc	%g0,	%g0,	$ovf	! upmost overflow bit
-+	stxa	$hi1,	[$tp]0xe2
-+	add	$tp,	8,	$tp
-+
-+	ba	.Louter_g5
-+	sub	$num,	16,	$i	! i=num-2
-+
-+.align	16
-+.Louter_g5:
-+	wr	$ccr,	%g0,	%ccr
-+___
-+	&load_b($bp,$m0);		# m0=bp[i]
-+$code.=<<___;
-+	sub	$ap,	$num,	$ap	! rewind
-+	sub	$np,	$num,	$np
-+	sub	$tp,	$num,	$tp
-+
-+	ldx	[$ap+0],	$aj	! ap[0]
-+	ldx	[$np+0],	$nj	! np[0]
-+
-+	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[i]
-+	ldx	[$tp],		$tj	! tp[0]
-+	umulxhi	$aj,	$m0,	$hi0
-+	ldx	[$ap+8],	$aj	! ap[1]
-+	addcc	$lo0,	$tj,	$lo0	! ap[0]*bp[i]+tp[0]
-+	mulx	$aj,	$m0,	$alo	! ap[1]*bp[i]
-+	addxc	%g0,	$hi0,	$hi0
-+	mulx	$lo0,	$n0,	$m1	! tp[0]*n0
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-+	add	$ap,	16,	$ap
-+	umulxhi	$nj,	$m1,	$hi1
-+	ldx	[$np+8],	$nj	! np[1]
-+	add	$np,	16,	$np
-+	addcc	$lo1,	$lo0,	$lo1
-+	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-+	addxc	%g0,	$hi1,	$hi1
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+
-+	ba	.Linner_g5
-+	sub	$num,	24,	$cnt	! cnt=num-3
-+.align	16
-+.Linner_g5:
-+	addcc	$alo,	$hi0,	$lo0
-+	ldx	[$tp+8],	$tj	! tp[j]
-+	addxc	$aj,	%g0,	$hi0	! ahi=aj
-+	ldx	[$ap+0],	$aj	! ap[j]
-+	add	$ap,	8,	$ap
-+	addcc	$nlo,	$hi1,	$lo1
-+	mulx	$aj,	$m0,	$alo	! ap[j]*bp[i]
-+	addxc	$nj,	%g0,	$hi1	! nhi=nj
-+	ldx	[$np+0],	$nj	! np[j]
-+	add	$np,	8,	$np
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-+	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-+	addxc	%g0,	$hi0,	$hi0
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-+	addxc	%g0,	$hi1,	$hi1
-+	stx	$lo1,	[$tp]		! tp[j-1]
-+	add	$tp,	8,	$tp
-+	brnz,pt	$cnt,	.Linner_g5
-+	sub	$cnt,	8,	$cnt
-+!.Linner_g5
-+	ldx	[$tp+8],	$tj	! tp[j]
-+	addcc	$alo,	$hi0,	$lo0
-+	addxc	$aj,	%g0,	$hi0	! ahi=aj
-+	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-+	addxc	%g0,	$hi0,	$hi0
-+
-+	addcc	$nlo,	$hi1,	$lo1
-+	addxc	$nj,	%g0,	$hi1	! nhi=nj
-+	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-+	addxc	%g0,	$hi1,	$hi1
-+	stx	$lo1,	[$tp]		! tp[j-1]
-+
-+	subcc	%g0,	$ovf,	%g0	! move upmost overflow to CCR.xcc
-+	addxccc	$hi1,	$hi0,	$hi1
-+	addxc	%g0,	%g0,	$ovf
-+	stx	$hi1,	[$tp+8]
-+	add	$tp,	16,	$tp
-+
-+	brnz,pt	$i,	.Louter_g5
-+	sub	$i,	8,	$i
-+
-+	sub	$ap,	$num,	$ap	! rewind
-+	sub	$np,	$num,	$np
-+	sub	$tp,	$num,	$tp
-+	ba	.Lsub_g5
-+	subcc	$num,	8,	$cnt	! cnt=num-1 and clear CCR.xcc
-+
-+.align	16
-+.Lsub_g5:
-+	ldx	[$tp],		$tj
-+	add	$tp,	8,	$tp
-+	ldx	[$np+0],	$nj
-+	add	$np,	8,	$np
-+	subccc	$tj,	$nj,	$t2	! tp[j]-np[j]
-+	srlx	$tj,	32,	$tj
-+	srlx	$nj,	32,	$nj
-+	subccc	$tj,	$nj,	$t3
-+	add	$rp,	8,	$rp
-+	st	$t2,	[$rp-4]		! reverse order
-+	st	$t3,	[$rp-8]
-+	brnz,pt	$cnt,	.Lsub_g5
-+	sub	$cnt,	8,	$cnt
-+
-+	sub	$np,	$num,	$np	! rewind
-+	sub	$tp,	$num,	$tp
-+	sub	$rp,	$num,	$rp
-+
-+	subc	$ovf,	%g0,	$ovf	! handle upmost overflow bit
-+	and	$tp,	$ovf,	$ap
-+	andn	$rp,	$ovf,	$np
-+	or	$np,	$ap,	$ap	! ap=borrow?tp:rp
-+	ba	.Lcopy_g5
-+	sub	$num,	8,	$cnt
-+
-+.align	16
-+.Lcopy_g5:				! copy or in-place refresh
-+	ldx	[$ap+0],	$t2
-+	add	$ap,	8,	$ap
-+	stx	%g0,	[$tp]		! zap
-+	add	$tp,	8,	$tp
-+	stx	$t2,	[$rp+0]
-+	add	$rp,	8,	$rp
-+	brnz	$cnt,	.Lcopy_g5
-+	sub	$cnt,	8,	$cnt
-+
-+	mov	1,	%o0
-+	ret
-+	restore
-+.type	bn_mul_mont_gather5_t4, #function
-+.size	bn_mul_mont_gather5_t4, .-bn_mul_mont_gather5_t4
-+___
-+}
-+
-+$code.=<<___;
-+.globl	bn_flip_t4
-+.align	32
-+bn_flip_t4:
-+.Loop_flip:
-+	ld	[%o1+0],	%o4
-+	sub	%o2,	1,	%o2
-+	ld	[%o1+4],	%o5
-+	add	%o1,	8,	%o1
-+	st	%o5,	[%o0+0]
-+	st	%o4,	[%o0+4]
-+	brnz	%o2,	.Loop_flip
-+	add	%o0,	8,	%o0
-+	retl
-+	nop
-+.type	bn_flip_t4, #function
-+.size	bn_flip_t4, .-bn_flip_t4
-+
-+.globl	bn_flip_n_scatter5_t4
-+.align	32
-+bn_flip_n_scatter5_t4:
-+	sll	%o3,	3,	%o3
-+	srl	%o1,	1,	%o1
-+	add	%o3,	%o2,	%o2	! &pwrtbl[pwr]
-+	sub	%o1,	1,	%o1
-+.Loop_flip_n_scatter5:
-+	ld	[%o0+0],	%o4	! inp[i]
-+	ld	[%o0+4],	%o5
-+	add	%o0,	8,	%o0
-+	sllx	%o5,	32,	%o5
-+	or	%o4,	%o5,	%o5
-+	stx	%o5,	[%o2]
-+	add	%o2,	32*8,	%o2
-+	brnz	%o1,	.Loop_flip_n_scatter5
-+	sub	%o1,	1,	%o1
-+	retl
-+	nop
-+.type	bn_flip_n_scatter5_t4, #function
-+.size	bn_flip_n_scatter5_t4, .-bn_flip_n_scatter5_t4
-+
-+.globl	bn_gather5_t4
-+.align	32
-+bn_gather5_t4:
-+___
-+	&load_ccr("%o2","%o3","%g1");
-+$code.=<<___;
-+	sub	%o1,	1,	%o1
-+.Loop_gather5:
-+___
-+	&load_b("%o2","%g1");
-+$code.=<<___;
-+	stx	%g1,	[%o0]
-+	add	%o0,	8,	%o0
-+	brnz	%o1,	.Loop_gather5
-+	sub	%o1,	1,	%o1
-+
-+	retl
-+	nop
-+.type	bn_gather5_t4, #function
-+.size	bn_gather5_t4, .-bn_gather5_t4
-+
-+.asciz	"Montgomery Multiplication for SPARC T4, David S. Miller, Andy Polyakov"
-+.align	4
-+___
-+
-+&emit_assembler();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv8.S b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv8.S
-new file mode 100644
-index 0000000..9c31073
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv8.S
-@@ -0,0 +1,1458 @@
-+.ident	"sparcv8.s, Version 1.4"
-+.ident	"SPARC v8 ISA artwork by Andy Polyakov "
-+
-+/*
-+ * ====================================================================
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ * ====================================================================
-+ */
-+
-+/*
-+ * This is my modest contributon to OpenSSL project (see
-+ * http://www.openssl.org/ for more information about it) and is
-+ * a drop-in SuperSPARC ISA replacement for crypto/bn/bn_asm.c
-+ * module. For updates see http://fy.chalmers.se/~appro/hpe/.
-+ *
-+ * See bn_asm.sparc.v8plus.S for more details.
-+ */
-+
-+/*
-+ * Revision history.
-+ *
-+ * 1.1	- new loop unrolling model(*);
-+ * 1.2	- made gas friendly;
-+ * 1.3	- fixed problem with /usr/ccs/lib/cpp;
-+ * 1.4	- some retunes;
-+ *
-+ * (*)	see bn_asm.sparc.v8plus.S for details
-+ */
-+
-+.section	".text",#alloc,#execinstr
-+.file		"bn_asm.sparc.v8.S"
-+
-+.align	32
-+
-+.global bn_mul_add_words
-+/*
-+ * BN_ULONG bn_mul_add_words(rp,ap,num,w)
-+ * BN_ULONG *rp,*ap;
-+ * int num;
-+ * BN_ULONG w;
-+ */
-+bn_mul_add_words:
-+	cmp	%o2,0
-+	bg,a	.L_bn_mul_add_words_proceed
-+	ld	[%o1],%g2
-+	retl
-+	clr	%o0
-+
-+.L_bn_mul_add_words_proceed:
-+	andcc	%o2,-4,%g0
-+	bz	.L_bn_mul_add_words_tail
-+	clr	%o5
-+
-+.L_bn_mul_add_words_loop:
-+	ld	[%o0],%o4
-+	ld	[%o1+4],%g3
-+	umul	%o3,%g2,%g2
-+	rd	%y,%g1
-+	addcc	%o4,%o5,%o4
-+	addx	%g1,0,%g1
-+	addcc	%o4,%g2,%o4
-+	st	%o4,[%o0]
-+	addx	%g1,0,%o5
-+
-+	ld	[%o0+4],%o4
-+	ld	[%o1+8],%g2
-+	umul	%o3,%g3,%g3
-+	dec	4,%o2
-+	rd	%y,%g1
-+	addcc	%o4,%o5,%o4
-+	addx	%g1,0,%g1
-+	addcc	%o4,%g3,%o4
-+	st	%o4,[%o0+4]
-+	addx	%g1,0,%o5
-+
-+	ld	[%o0+8],%o4
-+	ld	[%o1+12],%g3
-+	umul	%o3,%g2,%g2
-+	inc	16,%o1
-+	rd	%y,%g1
-+	addcc	%o4,%o5,%o4
-+	addx	%g1,0,%g1
-+	addcc	%o4,%g2,%o4
-+	st	%o4,[%o0+8]
-+	addx	%g1,0,%o5
-+
-+	ld	[%o0+12],%o4
-+	umul	%o3,%g3,%g3
-+	inc	16,%o0
-+	rd	%y,%g1
-+	addcc	%o4,%o5,%o4
-+	addx	%g1,0,%g1
-+	addcc	%o4,%g3,%o4
-+	st	%o4,[%o0-4]
-+	addx	%g1,0,%o5
-+	andcc	%o2,-4,%g0
-+	bnz,a	.L_bn_mul_add_words_loop
-+	ld	[%o1],%g2
-+
-+	tst	%o2
-+	bnz,a	.L_bn_mul_add_words_tail
-+	ld	[%o1],%g2
-+.L_bn_mul_add_words_return:
-+	retl
-+	mov	%o5,%o0
-+	nop
-+
-+.L_bn_mul_add_words_tail:
-+	ld	[%o0],%o4
-+	umul	%o3,%g2,%g2
-+	addcc	%o4,%o5,%o4
-+	rd	%y,%g1
-+	addx	%g1,0,%g1
-+	addcc	%o4,%g2,%o4
-+	addx	%g1,0,%o5
-+	deccc	%o2
-+	bz	.L_bn_mul_add_words_return
-+	st	%o4,[%o0]
-+
-+	ld	[%o1+4],%g2
-+	ld	[%o0+4],%o4
-+	umul	%o3,%g2,%g2
-+	rd	%y,%g1
-+	addcc	%o4,%o5,%o4
-+	addx	%g1,0,%g1
-+	addcc	%o4,%g2,%o4
-+	addx	%g1,0,%o5
-+	deccc	%o2
-+	bz	.L_bn_mul_add_words_return
-+	st	%o4,[%o0+4]
-+
-+	ld	[%o1+8],%g2
-+	ld	[%o0+8],%o4
-+	umul	%o3,%g2,%g2
-+	rd	%y,%g1
-+	addcc	%o4,%o5,%o4
-+	addx	%g1,0,%g1
-+	addcc	%o4,%g2,%o4
-+	st	%o4,[%o0+8]
-+	retl
-+	addx	%g1,0,%o0
-+
-+.type	bn_mul_add_words,#function
-+.size	bn_mul_add_words,(.-bn_mul_add_words)
-+
-+.align	32
-+
-+.global bn_mul_words
-+/*
-+ * BN_ULONG bn_mul_words(rp,ap,num,w)
-+ * BN_ULONG *rp,*ap;
-+ * int num;
-+ * BN_ULONG w;
-+ */
-+bn_mul_words:
-+	cmp	%o2,0
-+	bg,a	.L_bn_mul_words_proceeed
-+	ld	[%o1],%g2
-+	retl
-+	clr	%o0
-+
-+.L_bn_mul_words_proceeed:
-+	andcc	%o2,-4,%g0
-+	bz	.L_bn_mul_words_tail
-+	clr	%o5
-+
-+.L_bn_mul_words_loop:
-+	ld	[%o1+4],%g3
-+	umul	%o3,%g2,%g2
-+	addcc	%g2,%o5,%g2
-+	rd	%y,%g1
-+	addx	%g1,0,%o5
-+	st	%g2,[%o0]
-+
-+	ld	[%o1+8],%g2
-+	umul	%o3,%g3,%g3
-+	addcc	%g3,%o5,%g3
-+	rd	%y,%g1
-+	dec	4,%o2
-+	addx	%g1,0,%o5
-+	st	%g3,[%o0+4]
-+
-+	ld	[%o1+12],%g3
-+	umul	%o3,%g2,%g2
-+	addcc	%g2,%o5,%g2
-+	rd	%y,%g1
-+	inc	16,%o1
-+	st	%g2,[%o0+8]
-+	addx	%g1,0,%o5
-+
-+	umul	%o3,%g3,%g3
-+	addcc	%g3,%o5,%g3
-+	rd	%y,%g1
-+	inc	16,%o0
-+	addx	%g1,0,%o5
-+	st	%g3,[%o0-4]
-+	andcc	%o2,-4,%g0
-+	nop
-+	bnz,a	.L_bn_mul_words_loop
-+	ld	[%o1],%g2
-+
-+	tst	%o2
-+	bnz,a	.L_bn_mul_words_tail
-+	ld	[%o1],%g2
-+.L_bn_mul_words_return:
-+	retl
-+	mov	%o5,%o0
-+	nop
-+
-+.L_bn_mul_words_tail:
-+	umul	%o3,%g2,%g2
-+	addcc	%g2,%o5,%g2
-+	rd	%y,%g1
-+	addx	%g1,0,%o5
-+	deccc	%o2
-+	bz	.L_bn_mul_words_return
-+	st	%g2,[%o0]
-+	nop
-+
-+	ld	[%o1+4],%g2
-+	umul	%o3,%g2,%g2
-+	addcc	%g2,%o5,%g2
-+	rd	%y,%g1
-+	addx	%g1,0,%o5
-+	deccc	%o2
-+	bz	.L_bn_mul_words_return
-+	st	%g2,[%o0+4]
-+
-+	ld	[%o1+8],%g2
-+	umul	%o3,%g2,%g2
-+	addcc	%g2,%o5,%g2
-+	rd	%y,%g1
-+	st	%g2,[%o0+8]
-+	retl
-+	addx	%g1,0,%o0
-+
-+.type	bn_mul_words,#function
-+.size	bn_mul_words,(.-bn_mul_words)
-+
-+.align  32
-+.global	bn_sqr_words
-+/*
-+ * void bn_sqr_words(r,a,n)
-+ * BN_ULONG *r,*a;
-+ * int n;
-+ */
-+bn_sqr_words:
-+	cmp	%o2,0
-+	bg,a	.L_bn_sqr_words_proceeed
-+	ld	[%o1],%g2
-+	retl
-+	clr	%o0
-+
-+.L_bn_sqr_words_proceeed:
-+	andcc	%o2,-4,%g0
-+	bz	.L_bn_sqr_words_tail
-+	clr	%o5
-+
-+.L_bn_sqr_words_loop:
-+	ld	[%o1+4],%g3
-+	umul	%g2,%g2,%o4
-+	st	%o4,[%o0]
-+	rd	%y,%o5
-+	st	%o5,[%o0+4]
-+
-+	ld	[%o1+8],%g2
-+	umul	%g3,%g3,%o4
-+	dec	4,%o2
-+	st	%o4,[%o0+8]
-+	rd	%y,%o5
-+	st	%o5,[%o0+12]
-+	nop
-+
-+	ld	[%o1+12],%g3
-+	umul	%g2,%g2,%o4
-+	st	%o4,[%o0+16]
-+	rd	%y,%o5
-+	inc	16,%o1
-+	st	%o5,[%o0+20]
-+
-+	umul	%g3,%g3,%o4
-+	inc	32,%o0
-+	st	%o4,[%o0-8]
-+	rd	%y,%o5
-+	st	%o5,[%o0-4]
-+	andcc	%o2,-4,%g2
-+	bnz,a	.L_bn_sqr_words_loop
-+	ld	[%o1],%g2
-+
-+	tst	%o2
-+	nop
-+	bnz,a	.L_bn_sqr_words_tail
-+	ld	[%o1],%g2
-+.L_bn_sqr_words_return:
-+	retl
-+	clr	%o0
-+
-+.L_bn_sqr_words_tail:
-+	umul	%g2,%g2,%o4
-+	st	%o4,[%o0]
-+	deccc	%o2
-+	rd	%y,%o5
-+	bz	.L_bn_sqr_words_return
-+	st	%o5,[%o0+4]
-+
-+	ld	[%o1+4],%g2
-+	umul	%g2,%g2,%o4
-+	st	%o4,[%o0+8]
-+	deccc	%o2
-+	rd	%y,%o5
-+	nop
-+	bz	.L_bn_sqr_words_return
-+	st	%o5,[%o0+12]
-+
-+	ld	[%o1+8],%g2
-+	umul	%g2,%g2,%o4
-+	st	%o4,[%o0+16]
-+	rd	%y,%o5
-+	st	%o5,[%o0+20]
-+	retl
-+	clr	%o0
-+
-+.type	bn_sqr_words,#function
-+.size	bn_sqr_words,(.-bn_sqr_words)
-+
-+.align	32
-+
-+.global bn_div_words
-+/*
-+ * BN_ULONG bn_div_words(h,l,d)
-+ * BN_ULONG h,l,d;
-+ */
-+bn_div_words:
-+	wr	%o0,%y
-+	udiv	%o1,%o2,%o0
-+	retl
-+	nop
-+
-+.type	bn_div_words,#function
-+.size	bn_div_words,(.-bn_div_words)
-+
-+.align	32
-+
-+.global bn_add_words
-+/*
-+ * BN_ULONG bn_add_words(rp,ap,bp,n)
-+ * BN_ULONG *rp,*ap,*bp;
-+ * int n;
-+ */
-+bn_add_words:
-+	cmp	%o3,0
-+	bg,a	.L_bn_add_words_proceed
-+	ld	[%o1],%o4
-+	retl
-+	clr	%o0
-+
-+.L_bn_add_words_proceed:
-+	andcc	%o3,-4,%g0
-+	bz	.L_bn_add_words_tail
-+	clr	%g1
-+	ba	.L_bn_add_words_warn_loop
-+	addcc	%g0,0,%g0	! clear carry flag
-+
-+.L_bn_add_words_loop:
-+	ld	[%o1],%o4
-+.L_bn_add_words_warn_loop:
-+	ld	[%o2],%o5
-+	ld	[%o1+4],%g3
-+	ld	[%o2+4],%g4
-+	dec	4,%o3
-+	addxcc	%o5,%o4,%o5
-+	st	%o5,[%o0]
-+
-+	ld	[%o1+8],%o4
-+	ld	[%o2+8],%o5
-+	inc	16,%o1
-+	addxcc	%g3,%g4,%g3
-+	st	%g3,[%o0+4]
-+	
-+	ld	[%o1-4],%g3
-+	ld	[%o2+12],%g4
-+	inc	16,%o2
-+	addxcc	%o5,%o4,%o5
-+	st	%o5,[%o0+8]
-+
-+	inc	16,%o0
-+	addxcc	%g3,%g4,%g3
-+	st	%g3,[%o0-4]
-+	addx	%g0,0,%g1
-+	andcc	%o3,-4,%g0
-+	bnz,a	.L_bn_add_words_loop
-+	addcc	%g1,-1,%g0
-+
-+	tst	%o3
-+	bnz,a	.L_bn_add_words_tail
-+	ld	[%o1],%o4
-+.L_bn_add_words_return:
-+	retl
-+	mov	%g1,%o0
-+
-+.L_bn_add_words_tail:
-+	addcc	%g1,-1,%g0
-+	ld	[%o2],%o5
-+	addxcc	%o5,%o4,%o5
-+	addx	%g0,0,%g1
-+	deccc	%o3
-+	bz	.L_bn_add_words_return
-+	st	%o5,[%o0]
-+
-+	ld	[%o1+4],%o4
-+	addcc	%g1,-1,%g0
-+	ld	[%o2+4],%o5
-+	addxcc	%o5,%o4,%o5
-+	addx	%g0,0,%g1
-+	deccc	%o3
-+	bz	.L_bn_add_words_return
-+	st	%o5,[%o0+4]
-+
-+	ld	[%o1+8],%o4
-+	addcc	%g1,-1,%g0
-+	ld	[%o2+8],%o5
-+	addxcc	%o5,%o4,%o5
-+	st	%o5,[%o0+8]
-+	retl
-+	addx	%g0,0,%o0
-+
-+.type	bn_add_words,#function
-+.size	bn_add_words,(.-bn_add_words)
-+
-+.align	32
-+
-+.global bn_sub_words
-+/*
-+ * BN_ULONG bn_sub_words(rp,ap,bp,n)
-+ * BN_ULONG *rp,*ap,*bp;
-+ * int n;
-+ */
-+bn_sub_words:
-+	cmp	%o3,0
-+	bg,a	.L_bn_sub_words_proceed
-+	ld	[%o1],%o4
-+	retl
-+	clr	%o0
-+
-+.L_bn_sub_words_proceed:
-+	andcc	%o3,-4,%g0
-+	bz	.L_bn_sub_words_tail
-+	clr	%g1
-+	ba	.L_bn_sub_words_warm_loop
-+	addcc	%g0,0,%g0	! clear carry flag
-+
-+.L_bn_sub_words_loop:
-+	ld	[%o1],%o4
-+.L_bn_sub_words_warm_loop:
-+	ld	[%o2],%o5
-+	ld	[%o1+4],%g3
-+	ld	[%o2+4],%g4
-+	dec	4,%o3
-+	subxcc	%o4,%o5,%o5
-+	st	%o5,[%o0]
-+
-+	ld	[%o1+8],%o4
-+	ld	[%o2+8],%o5
-+	inc	16,%o1
-+	subxcc	%g3,%g4,%g4
-+	st	%g4,[%o0+4]
-+	
-+	ld	[%o1-4],%g3
-+	ld	[%o2+12],%g4
-+	inc	16,%o2
-+	subxcc	%o4,%o5,%o5
-+	st	%o5,[%o0+8]
-+
-+	inc	16,%o0
-+	subxcc	%g3,%g4,%g4
-+	st	%g4,[%o0-4]
-+	addx	%g0,0,%g1
-+	andcc	%o3,-4,%g0
-+	bnz,a	.L_bn_sub_words_loop
-+	addcc	%g1,-1,%g0
-+
-+	tst	%o3
-+	nop
-+	bnz,a	.L_bn_sub_words_tail
-+	ld	[%o1],%o4
-+.L_bn_sub_words_return:
-+	retl
-+	mov	%g1,%o0
-+
-+.L_bn_sub_words_tail:
-+	addcc	%g1,-1,%g0
-+	ld	[%o2],%o5
-+	subxcc	%o4,%o5,%o5
-+	addx	%g0,0,%g1
-+	deccc	%o3
-+	bz	.L_bn_sub_words_return
-+	st	%o5,[%o0]
-+	nop
-+
-+	ld	[%o1+4],%o4
-+	addcc	%g1,-1,%g0
-+	ld	[%o2+4],%o5
-+	subxcc	%o4,%o5,%o5
-+	addx	%g0,0,%g1
-+	deccc	%o3
-+	bz	.L_bn_sub_words_return
-+	st	%o5,[%o0+4]
-+
-+	ld	[%o1+8],%o4
-+	addcc	%g1,-1,%g0
-+	ld	[%o2+8],%o5
-+	subxcc	%o4,%o5,%o5
-+	st	%o5,[%o0+8]
-+	retl
-+	addx	%g0,0,%o0
-+
-+.type	bn_sub_words,#function
-+.size	bn_sub_words,(.-bn_sub_words)
-+
-+#define FRAME_SIZE	-96
-+
-+/*
-+ * Here is register usage map for *all* routines below.
-+ */
-+#define t_1	%o0
-+#define	t_2	%o1
-+#define c_1	%o2
-+#define c_2	%o3
-+#define c_3	%o4
-+
-+#define ap(I)	[%i1+4*I]
-+#define bp(I)	[%i2+4*I]
-+#define rp(I)	[%i0+4*I]
-+
-+#define	a_0	%l0
-+#define	a_1	%l1
-+#define	a_2	%l2
-+#define	a_3	%l3
-+#define	a_4	%l4
-+#define	a_5	%l5
-+#define	a_6	%l6
-+#define	a_7	%l7
-+
-+#define	b_0	%i3
-+#define	b_1	%i4
-+#define	b_2	%i5
-+#define	b_3	%o5
-+#define	b_4	%g1
-+#define	b_5	%g2
-+#define	b_6	%g3
-+#define	b_7	%g4
-+
-+.align	32
-+.global bn_mul_comba8
-+/*
-+ * void bn_mul_comba8(r,a,b)
-+ * BN_ULONG *r,*a,*b;
-+ */
-+bn_mul_comba8:
-+	save	%sp,FRAME_SIZE,%sp
-+	ld	ap(0),a_0
-+	ld	bp(0),b_0
-+	umul	a_0,b_0,c_1	!=!mul_add_c(a[0],b[0],c1,c2,c3);
-+	ld	bp(1),b_1
-+	rd	%y,c_2
-+	st	c_1,rp(0)	!r[0]=c1;
-+
-+	umul	a_0,b_1,t_1	!=!mul_add_c(a[0],b[1],c2,c3,c1);
-+	ld	ap(1),a_1
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	%g0,t_2,c_3	!=
-+	addx	%g0,%g0,c_1
-+	ld	ap(2),a_2
-+	umul	a_1,b_0,t_1	!mul_add_c(a[1],b[0],c2,c3,c1);
-+	addcc	c_2,t_1,c_2	!=
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	st	c_2,rp(1)	!r[1]=c2;
-+	addx	c_1,%g0,c_1	!=
-+
-+	umul	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	%g0,%g0,c_2
-+	ld	bp(2),b_2
-+	umul	a_1,b_1,t_1	!mul_add_c(a[1],b[1],c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	ld	bp(3),b_3
-+	addx	c_2,%g0,c_2	!=
-+	umul	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	c_2,%g0,c_2
-+	st	c_3,rp(2)	!r[2]=c3;
-+
-+	umul	a_0,b_3,t_1	!mul_add_c(a[0],b[3],c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	%g0,%g0,c_3
-+	umul	a_1,b_2,t_1	!=!mul_add_c(a[1],b[2],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	ld	ap(3),a_3
-+	umul	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2		!=
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	ld	ap(4),a_4
-+	umul	a_3,b_0,t_1	!mul_add_c(a[3],b[0],c1,c2,c3);!=
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	st	c_1,rp(3)	!r[3]=c1;
-+
-+	umul	a_4,b_0,t_1	!mul_add_c(a[4],b[0],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	%g0,%g0,c_1
-+	umul	a_3,b_1,t_1	!mul_add_c(a[3],b[1],c2,c3,c1);
-+	addcc	c_2,t_1,c_2	!=
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	umul	a_2,b_2,t_1	!=!mul_add_c(a[2],b[2],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1	!=
-+	ld	bp(4),b_4
-+	umul	a_1,b_3,t_1	!mul_add_c(a[1],b[3],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	ld	bp(5),b_5
-+	umul	a_0,b_4,t_1	!=!mul_add_c(a[0],b[4],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1	!=
-+	st	c_2,rp(4)	!r[4]=c2;
-+
-+	umul	a_0,b_5,t_1	!mul_add_c(a[0],b[5],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2		!=
-+	addxcc	c_1,t_2,c_1
-+	addx	%g0,%g0,c_2
-+	umul	a_1,b_4,t_1	!mul_add_c(a[1],b[4],c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	umul	a_2,b_3,t_1	!=!mul_add_c(a[2],b[3],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2	!=
-+	umul	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	c_2,%g0,c_2
-+	ld	ap(5),a_5
-+	umul	a_4,b_1,t_1	!mul_add_c(a[4],b[1],c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	ld	ap(6),a_6
-+	addx	c_2,%g0,c_2	!=
-+	umul	a_5,b_0,t_1	!mul_add_c(a[5],b[0],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	c_2,%g0,c_2
-+	st	c_3,rp(5)	!r[5]=c3;
-+
-+	umul	a_6,b_0,t_1	!mul_add_c(a[6],b[0],c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	%g0,%g0,c_3
-+	umul	a_5,b_1,t_1	!=!mul_add_c(a[5],b[1],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	umul	a_4,b_2,t_1	!mul_add_c(a[4],b[2],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	c_3,%g0,c_3
-+	umul	a_3,b_3,t_1	!mul_add_c(a[3],b[3],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2		!=
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	umul	a_2,b_4,t_1	!mul_add_c(a[2],b[4],c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	ld	bp(6),b_6
-+	addx	c_3,%g0,c_3	!=
-+	umul	a_1,b_5,t_1	!mul_add_c(a[1],b[5],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	c_3,%g0,c_3
-+	ld	bp(7),b_7
-+	umul	a_0,b_6,t_1	!mul_add_c(a[0],b[6],c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	st	c_1,rp(6)	!r[6]=c1;
-+	addx	c_3,%g0,c_3	!=
-+
-+	umul	a_0,b_7,t_1	!mul_add_c(a[0],b[7],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	%g0,%g0,c_1
-+	umul	a_1,b_6,t_1	!mul_add_c(a[1],b[6],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	umul	a_2,b_5,t_1	!mul_add_c(a[2],b[5],c2,c3,c1);
-+	addcc	c_2,t_1,c_2	!=
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	umul	a_3,b_4,t_1	!=!mul_add_c(a[3],b[4],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1	!=
-+	umul	a_4,b_3,t_1	!mul_add_c(a[4],b[3],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	umul	a_5,b_2,t_1	!mul_add_c(a[5],b[2],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	ld	ap(7),a_7
-+	umul	a_6,b_1,t_1	!=!mul_add_c(a[6],b[1],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1	!=
-+	umul	a_7,b_0,t_1	!mul_add_c(a[7],b[0],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	st	c_2,rp(7)	!r[7]=c2;
-+
-+	umul	a_7,b_1,t_1	!mul_add_c(a[7],b[1],c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	%g0,%g0,c_2
-+	umul	a_6,b_2,t_1	!=!mul_add_c(a[6],b[2],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2	!=
-+	umul	a_5,b_3,t_1	!mul_add_c(a[5],b[3],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	c_2,%g0,c_2
-+	umul	a_4,b_4,t_1	!mul_add_c(a[4],b[4],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2		!=
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	umul	a_3,b_5,t_1	!mul_add_c(a[3],b[5],c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	umul	a_2,b_6,t_1	!=!mul_add_c(a[2],b[6],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2	!=
-+	umul	a_1,b_7,t_1	!mul_add_c(a[1],b[7],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!
-+	addx	c_2,%g0,c_2
-+	st	c_3,rp(8)	!r[8]=c3;
-+
-+	umul	a_2,b_7,t_1	!mul_add_c(a[2],b[7],c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	%g0,%g0,c_3
-+	umul	a_3,b_6,t_1	!=!mul_add_c(a[3],b[6],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	umul	a_4,b_5,t_1	!mul_add_c(a[4],b[5],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	c_3,%g0,c_3
-+	umul	a_5,b_4,t_1	!mul_add_c(a[5],b[4],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2		!=
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	umul	a_6,b_3,t_1	!mul_add_c(a[6],b[3],c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	umul	a_7,b_2,t_1	!=!mul_add_c(a[7],b[2],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	st	c_1,rp(9)	!r[9]=c1;
-+
-+	umul	a_7,b_3,t_1	!mul_add_c(a[7],b[3],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	%g0,%g0,c_1
-+	umul	a_6,b_4,t_1	!mul_add_c(a[6],b[4],c2,c3,c1);
-+	addcc	c_2,t_1,c_2	!=
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	umul	a_5,b_5,t_1	!=!mul_add_c(a[5],b[5],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1	!=
-+	umul	a_4,b_6,t_1	!mul_add_c(a[4],b[6],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	umul	a_3,b_7,t_1	!mul_add_c(a[3],b[7],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	st	c_2,rp(10)	!r[10]=c2;
-+
-+	umul	a_4,b_7,t_1	!=!mul_add_c(a[4],b[7],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	%g0,%g0,c_2	!=
-+	umul	a_5,b_6,t_1	!mul_add_c(a[5],b[6],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	c_2,%g0,c_2
-+	umul	a_6,b_5,t_1	!mul_add_c(a[6],b[5],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2		!=
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	umul	a_7,b_4,t_1	!mul_add_c(a[7],b[4],c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	st	c_3,rp(11)	!r[11]=c3;
-+	addx	c_2,%g0,c_2	!=
-+
-+	umul	a_7,b_5,t_1	!mul_add_c(a[7],b[5],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	%g0,%g0,c_3
-+	umul	a_6,b_6,t_1	!mul_add_c(a[6],b[6],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2		!=
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	umul	a_5,b_7,t_1	!mul_add_c(a[5],b[7],c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	st	c_1,rp(12)	!r[12]=c1;
-+	addx	c_3,%g0,c_3	!=
-+
-+	umul	a_6,b_7,t_1	!mul_add_c(a[6],b[7],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	%g0,%g0,c_1
-+	umul	a_7,b_6,t_1	!mul_add_c(a[7],b[6],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	st	c_2,rp(13)	!r[13]=c2;
-+
-+	umul	a_7,b_7,t_1	!=!mul_add_c(a[7],b[7],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	nop			!=
-+	st	c_3,rp(14)	!r[14]=c3;
-+	st	c_1,rp(15)	!r[15]=c1;
-+
-+	ret
-+	restore	%g0,%g0,%o0
-+
-+.type	bn_mul_comba8,#function
-+.size	bn_mul_comba8,(.-bn_mul_comba8)
-+
-+.align	32
-+
-+.global bn_mul_comba4
-+/*
-+ * void bn_mul_comba4(r,a,b)
-+ * BN_ULONG *r,*a,*b;
-+ */
-+bn_mul_comba4:
-+	save	%sp,FRAME_SIZE,%sp
-+	ld	ap(0),a_0
-+	ld	bp(0),b_0
-+	umul	a_0,b_0,c_1	!=!mul_add_c(a[0],b[0],c1,c2,c3);
-+	ld	bp(1),b_1
-+	rd	%y,c_2
-+	st	c_1,rp(0)	!r[0]=c1;
-+
-+	umul	a_0,b_1,t_1	!=!mul_add_c(a[0],b[1],c2,c3,c1);
-+	ld	ap(1),a_1
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	%g0,t_2,c_3
-+	addx	%g0,%g0,c_1
-+	ld	ap(2),a_2
-+	umul	a_1,b_0,t_1	!=!mul_add_c(a[1],b[0],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1	!=
-+	st	c_2,rp(1)	!r[1]=c2;
-+
-+	umul	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2		!=
-+	addxcc	c_1,t_2,c_1
-+	addx	%g0,%g0,c_2
-+	ld	bp(2),b_2
-+	umul	a_1,b_1,t_1	!=!mul_add_c(a[1],b[1],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2	!=
-+	ld	bp(3),b_3
-+	umul	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2		!=
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	st	c_3,rp(2)	!r[2]=c3;
-+
-+	umul	a_0,b_3,t_1	!=!mul_add_c(a[0],b[3],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	%g0,%g0,c_3	!=
-+	umul	a_1,b_2,t_1	!mul_add_c(a[1],b[2],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	c_3,%g0,c_3
-+	ld	ap(3),a_3
-+	umul	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	umul	a_3,b_0,t_1	!=!mul_add_c(a[3],b[0],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	st	c_1,rp(3)	!r[3]=c1;
-+
-+	umul	a_3,b_1,t_1	!mul_add_c(a[3],b[1],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	%g0,%g0,c_1
-+	umul	a_2,b_2,t_1	!mul_add_c(a[2],b[2],c2,c3,c1);
-+	addcc	c_2,t_1,c_2	!=
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	umul	a_1,b_3,t_1	!=!mul_add_c(a[1],b[3],c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1	!=
-+	st	c_2,rp(4)	!r[4]=c2;
-+
-+	umul	a_2,b_3,t_1	!mul_add_c(a[2],b[3],c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2		!=
-+	addxcc	c_1,t_2,c_1
-+	addx	%g0,%g0,c_2
-+	umul	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	st	c_3,rp(5)	!r[5]=c3;
-+	addx	c_2,%g0,c_2	!=
-+
-+	umul	a_3,b_3,t_1	!mul_add_c(a[3],b[3],c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	st	c_1,rp(6)	!r[6]=c1;
-+	st	c_2,rp(7)	!r[7]=c2;
-+	
-+	ret
-+	restore	%g0,%g0,%o0
-+
-+.type	bn_mul_comba4,#function
-+.size	bn_mul_comba4,(.-bn_mul_comba4)
-+
-+.align	32
-+
-+.global bn_sqr_comba8
-+bn_sqr_comba8:
-+	save	%sp,FRAME_SIZE,%sp
-+	ld	ap(0),a_0
-+	ld	ap(1),a_1
-+	umul	a_0,a_0,c_1	!=!sqr_add_c(a,0,c1,c2,c3);
-+	rd	%y,c_2
-+	st	c_1,rp(0)	!r[0]=c1;
-+
-+	ld	ap(2),a_2
-+	umul	a_0,a_1,t_1	!=!sqr_add_c2(a,1,0,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	%g0,t_2,c_3
-+	addx	%g0,%g0,c_1	!=
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3
-+	st	c_2,rp(1)	!r[1]=c2;
-+	addx	c_1,%g0,c_1	!=
-+
-+	umul	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	%g0,%g0,c_2
-+	addcc	c_3,t_1,c_3
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2	!=
-+	ld	ap(3),a_3
-+	umul	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2		!=
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	st	c_3,rp(2)	!r[2]=c3;
-+
-+	umul	a_0,a_3,t_1	!=!sqr_add_c2(a,3,0,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	%g0,%g0,c_3	!=
-+	addcc	c_1,t_1,c_1
-+	addxcc	c_2,t_2,c_2
-+	ld	ap(4),a_4
-+	addx	c_3,%g0,c_3	!=
-+	umul	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	c_3,%g0,c_3
-+	addcc	c_1,t_1,c_1
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	st	c_1,rp(3)	!r[3]=c1;
-+
-+	umul	a_4,a_0,t_1	!sqr_add_c2(a,4,0,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	%g0,%g0,c_1
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	umul	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	ld	ap(5),a_5
-+	umul	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
-+	addcc	c_2,t_1,c_2	!=
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	st	c_2,rp(4)	!r[4]=c2;
-+	addx	c_1,%g0,c_1	!=
-+
-+	umul	a_0,a_5,t_1	!sqr_add_c2(a,5,0,c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	%g0,%g0,c_2
-+	addcc	c_3,t_1,c_3
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2	!=
-+	umul	a_1,a_4,t_1	!sqr_add_c2(a,4,1,c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	c_2,%g0,c_2
-+	addcc	c_3,t_1,c_3
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2	!=
-+	ld	ap(6),a_6
-+	umul	a_2,a_3,t_1	!sqr_add_c2(a,3,2,c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2		!=
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	addcc	c_3,t_1,c_3
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	c_2,%g0,c_2
-+	st	c_3,rp(5)	!r[5]=c3;
-+
-+	umul	a_6,a_0,t_1	!sqr_add_c2(a,6,0,c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	%g0,%g0,c_3
-+	addcc	c_1,t_1,c_1	!=
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	umul	a_5,a_1,t_1	!sqr_add_c2(a,5,1,c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	addcc	c_1,t_1,c_1	!=
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	umul	a_4,a_2,t_1	!sqr_add_c2(a,4,2,c1,c2,c3);
-+	addcc	c_1,t_1,c_1	!=
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	addcc	c_1,t_1,c_1	!=
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3
-+	ld	ap(7),a_7
-+	umul	a_3,a_3,t_1	!=!sqr_add_c(a,3,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	st	c_1,rp(6)	!r[6]=c1;
-+
-+	umul	a_0,a_7,t_1	!sqr_add_c2(a,7,0,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	%g0,%g0,c_1
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	umul	a_1,a_6,t_1	!sqr_add_c2(a,6,1,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	umul	a_2,a_5,t_1	!sqr_add_c2(a,5,2,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	umul	a_3,a_4,t_1	!sqr_add_c2(a,4,3,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	st	c_2,rp(7)	!r[7]=c2;
-+
-+	umul	a_7,a_1,t_1	!sqr_add_c2(a,7,1,c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	%g0,%g0,c_2
-+	addcc	c_3,t_1,c_3	!=
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	umul	a_6,a_2,t_1	!sqr_add_c2(a,6,2,c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	addcc	c_3,t_1,c_3	!=
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	umul	a_5,a_3,t_1	!sqr_add_c2(a,5,3,c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	addcc	c_3,t_1,c_3	!=
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	umul	a_4,a_4,t_1	!sqr_add_c(a,4,c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	st	c_3,rp(8)	!r[8]=c3;
-+	addx	c_2,%g0,c_2	!=
-+
-+	umul	a_2,a_7,t_1	!sqr_add_c2(a,7,2,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	%g0,%g0,c_3
-+	addcc	c_1,t_1,c_1
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	umul	a_3,a_6,t_1	!sqr_add_c2(a,6,3,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	c_3,%g0,c_3
-+	addcc	c_1,t_1,c_1
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	umul	a_4,a_5,t_1	!sqr_add_c2(a,5,4,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	c_3,%g0,c_3
-+	addcc	c_1,t_1,c_1
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	st	c_1,rp(9)	!r[9]=c1;
-+
-+	umul	a_7,a_3,t_1	!sqr_add_c2(a,7,3,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	%g0,%g0,c_1
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	umul	a_6,a_4,t_1	!sqr_add_c2(a,6,4,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	umul	a_5,a_5,t_1	!sqr_add_c(a,5,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	st	c_2,rp(10)	!r[10]=c2;
-+
-+	umul	a_4,a_7,t_1	!=!sqr_add_c2(a,7,4,c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	%g0,%g0,c_2	!=
-+	addcc	c_3,t_1,c_3
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2
-+	umul	a_5,a_6,t_1	!=!sqr_add_c2(a,6,5,c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	c_2,%g0,c_2	!=
-+	addcc	c_3,t_1,c_3
-+	addxcc	c_1,t_2,c_1
-+	st	c_3,rp(11)	!r[11]=c3;
-+	addx	c_2,%g0,c_2	!=
-+
-+	umul	a_7,a_5,t_1	!sqr_add_c2(a,7,5,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	%g0,%g0,c_3
-+	addcc	c_1,t_1,c_1
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	umul	a_6,a_6,t_1	!sqr_add_c(a,6,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	c_3,%g0,c_3
-+	st	c_1,rp(12)	!r[12]=c1;
-+
-+	umul	a_6,a_7,t_1	!sqr_add_c2(a,7,6,c2,c3,c1);
-+	addcc	c_2,t_1,c_2	!=
-+	rd	%y,t_2
-+	addxcc	c_3,t_2,c_3
-+	addx	%g0,%g0,c_1
-+	addcc	c_2,t_1,c_2	!=
-+	addxcc	c_3,t_2,c_3
-+	st	c_2,rp(13)	!r[13]=c2;
-+	addx	c_1,%g0,c_1	!=
-+
-+	umul	a_7,a_7,t_1	!sqr_add_c(a,7,c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1	!=
-+	st	c_3,rp(14)	!r[14]=c3;
-+	st	c_1,rp(15)	!r[15]=c1;
-+
-+	ret
-+	restore	%g0,%g0,%o0
-+
-+.type	bn_sqr_comba8,#function
-+.size	bn_sqr_comba8,(.-bn_sqr_comba8)
-+
-+.align	32
-+
-+.global bn_sqr_comba4
-+/*
-+ * void bn_sqr_comba4(r,a)
-+ * BN_ULONG *r,*a;
-+ */
-+bn_sqr_comba4:
-+	save	%sp,FRAME_SIZE,%sp
-+	ld	ap(0),a_0
-+	umul	a_0,a_0,c_1	!sqr_add_c(a,0,c1,c2,c3);
-+	ld	ap(1),a_1	!=
-+	rd	%y,c_2
-+	st	c_1,rp(0)	!r[0]=c1;
-+
-+	ld	ap(2),a_2
-+	umul	a_0,a_1,t_1	!=!sqr_add_c2(a,1,0,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2
-+	addxcc	%g0,t_2,c_3
-+	addx	%g0,%g0,c_1	!=
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1	!=
-+	st	c_2,rp(1)	!r[1]=c2;
-+
-+	umul	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2		!=
-+	addxcc	c_1,t_2,c_1
-+	addx	%g0,%g0,c_2
-+	addcc	c_3,t_1,c_3
-+	addxcc	c_1,t_2,c_1	!=
-+	addx	c_2,%g0,c_2
-+	ld	ap(3),a_3
-+	umul	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
-+	addcc	c_3,t_1,c_3	!=
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	st	c_3,rp(2)	!r[2]=c3;
-+	addx	c_2,%g0,c_2	!=
-+
-+	umul	a_0,a_3,t_1	!sqr_add_c2(a,3,0,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	%g0,%g0,c_3
-+	addcc	c_1,t_1,c_1
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	umul	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	addx	c_3,%g0,c_3
-+	addcc	c_1,t_1,c_1
-+	addxcc	c_2,t_2,c_2
-+	addx	c_3,%g0,c_3	!=
-+	st	c_1,rp(3)	!r[3]=c1;
-+
-+	umul	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	%g0,%g0,c_1
-+	addcc	c_2,t_1,c_2
-+	addxcc	c_3,t_2,c_3	!=
-+	addx	c_1,%g0,c_1
-+	umul	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
-+	addcc	c_2,t_1,c_2
-+	rd	%y,t_2		!=
-+	addxcc	c_3,t_2,c_3
-+	addx	c_1,%g0,c_1
-+	st	c_2,rp(4)	!r[4]=c2;
-+
-+	umul	a_2,a_3,t_1	!=!sqr_add_c2(a,3,2,c3,c1,c2);
-+	addcc	c_3,t_1,c_3
-+	rd	%y,t_2
-+	addxcc	c_1,t_2,c_1
-+	addx	%g0,%g0,c_2	!=
-+	addcc	c_3,t_1,c_3
-+	addxcc	c_1,t_2,c_1
-+	st	c_3,rp(5)	!r[5]=c3;
-+	addx	c_2,%g0,c_2	!=
-+
-+	umul	a_3,a_3,t_1	!sqr_add_c(a,3,c1,c2,c3);
-+	addcc	c_1,t_1,c_1
-+	rd	%y,t_2
-+	addxcc	c_2,t_2,c_2	!=
-+	st	c_1,rp(6)	!r[6]=c1;
-+	st	c_2,rp(7)	!r[7]=c2;
-+	
-+	ret
-+	restore	%g0,%g0,%o0
-+
-+.type	bn_sqr_comba4,#function
-+.size	bn_sqr_comba4,(.-bn_sqr_comba4)
-+
-+.align	32
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv8plus.S b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv8plus.S
-new file mode 100644
-index 0000000..714a136
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv8plus.S
-@@ -0,0 +1,1562 @@
-+.ident	"sparcv8plus.s, Version 1.4"
-+.ident	"SPARC v9 ISA artwork by Andy Polyakov "
-+
-+/*
-+ * ====================================================================
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ * ====================================================================
-+ */
-+
-+/*
-+ * This is my modest contributon to OpenSSL project (see
-+ * http://www.openssl.org/ for more information about it) and is
-+ * a drop-in UltraSPARC ISA replacement for crypto/bn/bn_asm.c
-+ * module. For updates see http://fy.chalmers.se/~appro/hpe/.
-+ *
-+ * Questions-n-answers.
-+ *
-+ * Q. How to compile?
-+ * A. With SC4.x/SC5.x:
-+ *
-+ *	cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o
-+ *
-+ *    and with gcc:
-+ *
-+ *	gcc -mcpu=ultrasparc -c bn_asm.sparc.v8plus.S -o bn_asm.o
-+ *
-+ *    or if above fails (it does if you have gas installed):
-+ *
-+ *	gcc -E bn_asm.sparc.v8plus.S | as -xarch=v8plus /dev/fd/0 -o bn_asm.o
-+ *
-+ *    Quick-n-dirty way to fuse the module into the library.
-+ *    Provided that the library is already configured and built
-+ *    (in 0.9.2 case with no-asm option):
-+ *
-+ *	# cd crypto/bn
-+ *	# cp /some/place/bn_asm.sparc.v8plus.S .
-+ *	# cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o
-+ *	# make
-+ *	# cd ../..
-+ *	# make; make test
-+ *
-+ *    Quick-n-dirty way to get rid of it:
-+ *
-+ *	# cd crypto/bn
-+ *	# touch bn_asm.c
-+ *	# make
-+ *	# cd ../..
-+ *	# make; make test
-+ *
-+ * Q. V8plus architecture? What kind of beast is that?
-+ * A. Well, it's rather a programming model than an architecture...
-+ *    It's actually v9-compliant, i.e. *any* UltraSPARC, CPU under
-+ *    special conditions, namely when kernel doesn't preserve upper
-+ *    32 bits of otherwise 64-bit registers during a context switch.
-+ *
-+ * Q. Why just UltraSPARC? What about SuperSPARC?
-+ * A. Original release did target UltraSPARC only. Now SuperSPARC
-+ *    version is provided along. Both version share bn_*comba[48]
-+ *    implementations (see comment later in code for explanation).
-+ *    But what's so special about this UltraSPARC implementation?
-+ *    Why didn't I let compiler do the job? Trouble is that most of
-+ *    available compilers (well, SC5.0 is the only exception) don't
-+ *    attempt to take advantage of UltraSPARC's 64-bitness under
-+ *    32-bit kernels even though it's perfectly possible (see next
-+ *    question).
-+ *
-+ * Q. 64-bit registers under 32-bit kernels? Didn't you just say it
-+ *    doesn't work?
-+ * A. You can't address *all* registers as 64-bit wide:-( The catch is
-+ *    that you actually may rely upon %o0-%o5 and %g1-%g4 being fully
-+ *    preserved if you're in a leaf function, i.e. such never calling
-+ *    any other functions. All functions in this module are leaf and
-+ *    10 registers is a handful. And as a matter of fact none-"comba"
-+ *    routines don't require even that much and I could even afford to
-+ *    not allocate own stack frame for 'em:-)
-+ *
-+ * Q. What about 64-bit kernels?
-+ * A. What about 'em? Just kidding:-) Pure 64-bit version is currently
-+ *    under evaluation and development...
-+ *
-+ * Q. What about shared libraries?
-+ * A. What about 'em? Kidding again:-) Code does *not* contain any
-+ *    code position dependencies and it's safe to include it into
-+ *    shared library as is.
-+ *
-+ * Q. How much faster does it go?
-+ * A. Do you have a good benchmark? In either case below is what I
-+ *    experience with crypto/bn/expspeed.c test program:
-+ *
-+ *	v8plus module on U10/300MHz against bn_asm.c compiled with:
-+ *
-+ *	cc-5.0 -xarch=v8plus -xO5 -xdepend	+7-12%
-+ *	cc-4.2 -xarch=v8plus -xO5 -xdepend	+25-35%
-+ *	egcs-1.1.2 -mcpu=ultrasparc -O3		+35-45%
-+ *
-+ *	v8 module on SS10/60MHz against bn_asm.c compiled with:
-+ *
-+ *	cc-5.0 -xarch=v8 -xO5 -xdepend		+7-10%
-+ *	cc-4.2 -xarch=v8 -xO5 -xdepend		+10%
-+ *	egcs-1.1.2 -mv8 -O3			+35-45%
-+ *
-+ *    As you can see it's damn hard to beat the new Sun C compiler
-+ *    and it's in first place GNU C users who will appreciate this
-+ *    assembler implementation:-)	
-+ */
-+
-+/*
-+ * Revision history.
-+ *
-+ * 1.0	- initial release;
-+ * 1.1	- new loop unrolling model(*);
-+ *	- some more fine tuning;
-+ * 1.2	- made gas friendly;
-+ *	- updates to documentation concerning v9;
-+ *	- new performance comparison matrix;
-+ * 1.3	- fixed problem with /usr/ccs/lib/cpp;
-+ * 1.4	- native V9 bn_*_comba[48] implementation (15% more efficient)
-+ *	  resulting in slight overall performance kick;
-+ *	- some retunes;
-+ *	- support for GNU as added;
-+ *
-+ * (*)	Originally unrolled loop looked like this:
-+ *	    for (;;) {
-+ *		op(p+0); if (--n==0) break;
-+ *		op(p+1); if (--n==0) break;
-+ *		op(p+2); if (--n==0) break;
-+ *		op(p+3); if (--n==0) break;
-+ *		p+=4;
-+ *	    }
-+ *	I unroll according to following:
-+ *	    while (n&~3) {
-+ *		op(p+0); op(p+1); op(p+2); op(p+3);
-+ *		p+=4; n=-4;
-+ *	    }
-+ *	    if (n) {
-+ *		op(p+0); if (--n==0) return;
-+ *		op(p+2); if (--n==0) return;
-+ *		op(p+3); return;
-+ *	    }
-+ */
-+
-+#ifdef OPENSSL_FIPSCANISTER
-+#include 
-+#endif
-+
-+#if defined(__SUNPRO_C) && defined(__sparcv9)
-+  /* They've said -xarch=v9 at command line */
-+  .register	%g2,#scratch
-+  .register	%g3,#scratch
-+# define	FRAME_SIZE	-192
-+#elif defined(__GNUC__) && defined(__arch64__)
-+  /* They've said -m64 at command line */
-+  .register	%g2,#scratch
-+  .register	%g3,#scratch
-+# define	FRAME_SIZE	-192
-+#else 
-+# define	FRAME_SIZE	-96
-+#endif 
-+/*
-+ * GNU assembler can't stand stuw:-(
-+ */
-+#define stuw st
-+
-+.section	".text",#alloc,#execinstr
-+.file		"bn_asm.sparc.v8plus.S"
-+
-+.align	32
-+
-+.global bn_mul_add_words
-+/*
-+ * BN_ULONG bn_mul_add_words(rp,ap,num,w)
-+ * BN_ULONG *rp,*ap;
-+ * int num;
-+ * BN_ULONG w;
-+ */
-+bn_mul_add_words:
-+	sra	%o2,%g0,%o2	! signx %o2
-+	brgz,a	%o2,.L_bn_mul_add_words_proceed
-+	lduw	[%o1],%g2
-+	retl
-+	clr	%o0
-+	nop
-+	nop
-+	nop
-+
-+.L_bn_mul_add_words_proceed:
-+	srl	%o3,%g0,%o3	! clruw	%o3
-+	andcc	%o2,-4,%g0
-+	bz,pn	%icc,.L_bn_mul_add_words_tail
-+	clr	%o5
-+
-+.L_bn_mul_add_words_loop:	! wow! 32 aligned!
-+	lduw	[%o0],%g1
-+	lduw	[%o1+4],%g3
-+	mulx	%o3,%g2,%g2
-+	add	%g1,%o5,%o4
-+	nop
-+	add	%o4,%g2,%o4
-+	stuw	%o4,[%o0]
-+	srlx	%o4,32,%o5
-+
-+	lduw	[%o0+4],%g1
-+	lduw	[%o1+8],%g2
-+	mulx	%o3,%g3,%g3
-+	add	%g1,%o5,%o4
-+	dec	4,%o2
-+	add	%o4,%g3,%o4
-+	stuw	%o4,[%o0+4]
-+	srlx	%o4,32,%o5
-+
-+	lduw	[%o0+8],%g1
-+	lduw	[%o1+12],%g3
-+	mulx	%o3,%g2,%g2
-+	add	%g1,%o5,%o4
-+	inc	16,%o1
-+	add	%o4,%g2,%o4
-+	stuw	%o4,[%o0+8]
-+	srlx	%o4,32,%o5
-+
-+	lduw	[%o0+12],%g1
-+	mulx	%o3,%g3,%g3
-+	add	%g1,%o5,%o4
-+	inc	16,%o0
-+	add	%o4,%g3,%o4
-+	andcc	%o2,-4,%g0
-+	stuw	%o4,[%o0-4]
-+	srlx	%o4,32,%o5
-+	bnz,a,pt	%icc,.L_bn_mul_add_words_loop
-+	lduw	[%o1],%g2
-+
-+	brnz,a,pn	%o2,.L_bn_mul_add_words_tail
-+	lduw	[%o1],%g2
-+.L_bn_mul_add_words_return:
-+	retl
-+	mov	%o5,%o0
-+
-+.L_bn_mul_add_words_tail:
-+	lduw	[%o0],%g1
-+	mulx	%o3,%g2,%g2
-+	add	%g1,%o5,%o4
-+	dec	%o2
-+	add	%o4,%g2,%o4
-+	srlx	%o4,32,%o5
-+	brz,pt	%o2,.L_bn_mul_add_words_return
-+	stuw	%o4,[%o0]
-+
-+	lduw	[%o1+4],%g2
-+	lduw	[%o0+4],%g1
-+	mulx	%o3,%g2,%g2
-+	add	%g1,%o5,%o4
-+	dec	%o2
-+	add	%o4,%g2,%o4
-+	srlx	%o4,32,%o5
-+	brz,pt	%o2,.L_bn_mul_add_words_return
-+	stuw	%o4,[%o0+4]
-+
-+	lduw	[%o1+8],%g2
-+	lduw	[%o0+8],%g1
-+	mulx	%o3,%g2,%g2
-+	add	%g1,%o5,%o4
-+	add	%o4,%g2,%o4
-+	stuw	%o4,[%o0+8]
-+	retl
-+	srlx	%o4,32,%o0
-+
-+.type	bn_mul_add_words,#function
-+.size	bn_mul_add_words,(.-bn_mul_add_words)
-+
-+.align	32
-+
-+.global bn_mul_words
-+/*
-+ * BN_ULONG bn_mul_words(rp,ap,num,w)
-+ * BN_ULONG *rp,*ap;
-+ * int num;
-+ * BN_ULONG w;
-+ */
-+bn_mul_words:
-+	sra	%o2,%g0,%o2	! signx %o2
-+	brgz,a	%o2,.L_bn_mul_words_proceeed
-+	lduw	[%o1],%g2
-+	retl
-+	clr	%o0
-+	nop
-+	nop
-+	nop
-+
-+.L_bn_mul_words_proceeed:
-+	srl	%o3,%g0,%o3	! clruw	%o3
-+	andcc	%o2,-4,%g0
-+	bz,pn	%icc,.L_bn_mul_words_tail
-+	clr	%o5
-+
-+.L_bn_mul_words_loop:		! wow! 32 aligned!
-+	lduw	[%o1+4],%g3
-+	mulx	%o3,%g2,%g2
-+	add	%g2,%o5,%o4
-+	nop
-+	stuw	%o4,[%o0]
-+	srlx	%o4,32,%o5
-+
-+	lduw	[%o1+8],%g2
-+	mulx	%o3,%g3,%g3
-+	add	%g3,%o5,%o4
-+	dec	4,%o2
-+	stuw	%o4,[%o0+4]
-+	srlx	%o4,32,%o5
-+
-+	lduw	[%o1+12],%g3
-+	mulx	%o3,%g2,%g2
-+	add	%g2,%o5,%o4
-+	inc	16,%o1
-+	stuw	%o4,[%o0+8]
-+	srlx	%o4,32,%o5
-+
-+	mulx	%o3,%g3,%g3
-+	add	%g3,%o5,%o4
-+	inc	16,%o0
-+	stuw	%o4,[%o0-4]
-+	srlx	%o4,32,%o5
-+	andcc	%o2,-4,%g0
-+	bnz,a,pt	%icc,.L_bn_mul_words_loop
-+	lduw	[%o1],%g2
-+	nop
-+	nop
-+
-+	brnz,a,pn	%o2,.L_bn_mul_words_tail
-+	lduw	[%o1],%g2
-+.L_bn_mul_words_return:
-+	retl
-+	mov	%o5,%o0
-+
-+.L_bn_mul_words_tail:
-+	mulx	%o3,%g2,%g2
-+	add	%g2,%o5,%o4
-+	dec	%o2
-+	srlx	%o4,32,%o5
-+	brz,pt	%o2,.L_bn_mul_words_return
-+	stuw	%o4,[%o0]
-+
-+	lduw	[%o1+4],%g2
-+	mulx	%o3,%g2,%g2
-+	add	%g2,%o5,%o4
-+	dec	%o2
-+	srlx	%o4,32,%o5
-+	brz,pt	%o2,.L_bn_mul_words_return
-+	stuw	%o4,[%o0+4]
-+
-+	lduw	[%o1+8],%g2
-+	mulx	%o3,%g2,%g2
-+	add	%g2,%o5,%o4
-+	stuw	%o4,[%o0+8]
-+	retl
-+	srlx	%o4,32,%o0
-+
-+.type	bn_mul_words,#function
-+.size	bn_mul_words,(.-bn_mul_words)
-+
-+.align  32
-+.global	bn_sqr_words
-+/*
-+ * void bn_sqr_words(r,a,n)
-+ * BN_ULONG *r,*a;
-+ * int n;
-+ */
-+bn_sqr_words:
-+	sra	%o2,%g0,%o2	! signx %o2
-+	brgz,a	%o2,.L_bn_sqr_words_proceeed
-+	lduw	[%o1],%g2
-+	retl
-+	clr	%o0
-+	nop
-+	nop
-+	nop
-+
-+.L_bn_sqr_words_proceeed:
-+	andcc	%o2,-4,%g0
-+	nop
-+	bz,pn	%icc,.L_bn_sqr_words_tail
-+	nop
-+
-+.L_bn_sqr_words_loop:		! wow! 32 aligned!
-+	lduw	[%o1+4],%g3
-+	mulx	%g2,%g2,%o4
-+	stuw	%o4,[%o0]
-+	srlx	%o4,32,%o5
-+	stuw	%o5,[%o0+4]
-+	nop
-+
-+	lduw	[%o1+8],%g2
-+	mulx	%g3,%g3,%o4
-+	dec	4,%o2
-+	stuw	%o4,[%o0+8]
-+	srlx	%o4,32,%o5
-+	stuw	%o5,[%o0+12]
-+
-+	lduw	[%o1+12],%g3
-+	mulx	%g2,%g2,%o4
-+	srlx	%o4,32,%o5
-+	stuw	%o4,[%o0+16]
-+	inc	16,%o1
-+	stuw	%o5,[%o0+20]
-+
-+	mulx	%g3,%g3,%o4
-+	inc	32,%o0
-+	stuw	%o4,[%o0-8]
-+	srlx	%o4,32,%o5
-+	andcc	%o2,-4,%g2
-+	stuw	%o5,[%o0-4]
-+	bnz,a,pt	%icc,.L_bn_sqr_words_loop
-+	lduw	[%o1],%g2
-+	nop
-+
-+	brnz,a,pn	%o2,.L_bn_sqr_words_tail
-+	lduw	[%o1],%g2
-+.L_bn_sqr_words_return:
-+	retl
-+	clr	%o0
-+
-+.L_bn_sqr_words_tail:
-+	mulx	%g2,%g2,%o4
-+	dec	%o2
-+	stuw	%o4,[%o0]
-+	srlx	%o4,32,%o5
-+	brz,pt	%o2,.L_bn_sqr_words_return
-+	stuw	%o5,[%o0+4]
-+
-+	lduw	[%o1+4],%g2
-+	mulx	%g2,%g2,%o4
-+	dec	%o2
-+	stuw	%o4,[%o0+8]
-+	srlx	%o4,32,%o5
-+	brz,pt	%o2,.L_bn_sqr_words_return
-+	stuw	%o5,[%o0+12]
-+
-+	lduw	[%o1+8],%g2
-+	mulx	%g2,%g2,%o4
-+	srlx	%o4,32,%o5
-+	stuw	%o4,[%o0+16]
-+	stuw	%o5,[%o0+20]
-+	retl
-+	clr	%o0
-+
-+.type	bn_sqr_words,#function
-+.size	bn_sqr_words,(.-bn_sqr_words)
-+
-+.align	32
-+.global bn_div_words
-+/*
-+ * BN_ULONG bn_div_words(h,l,d)
-+ * BN_ULONG h,l,d;
-+ */
-+bn_div_words:
-+	sllx	%o0,32,%o0
-+	or	%o0,%o1,%o0
-+	udivx	%o0,%o2,%o0
-+	retl
-+	srl	%o0,%g0,%o0	! clruw	%o0
-+
-+.type	bn_div_words,#function
-+.size	bn_div_words,(.-bn_div_words)
-+
-+.align	32
-+
-+.global bn_add_words
-+/*
-+ * BN_ULONG bn_add_words(rp,ap,bp,n)
-+ * BN_ULONG *rp,*ap,*bp;
-+ * int n;
-+ */
-+bn_add_words:
-+	sra	%o3,%g0,%o3	! signx %o3
-+	brgz,a	%o3,.L_bn_add_words_proceed
-+	lduw	[%o1],%o4
-+	retl
-+	clr	%o0
-+
-+.L_bn_add_words_proceed:
-+	andcc	%o3,-4,%g0
-+	bz,pn	%icc,.L_bn_add_words_tail
-+	addcc	%g0,0,%g0	! clear carry flag
-+
-+.L_bn_add_words_loop:		! wow! 32 aligned!
-+	dec	4,%o3
-+	lduw	[%o2],%o5
-+	lduw	[%o1+4],%g1
-+	lduw	[%o2+4],%g2
-+	lduw	[%o1+8],%g3
-+	lduw	[%o2+8],%g4
-+	addccc	%o5,%o4,%o5
-+	stuw	%o5,[%o0]
-+
-+	lduw	[%o1+12],%o4
-+	lduw	[%o2+12],%o5
-+	inc	16,%o1
-+	addccc	%g1,%g2,%g1
-+	stuw	%g1,[%o0+4]
-+	
-+	inc	16,%o2
-+	addccc	%g3,%g4,%g3
-+	stuw	%g3,[%o0+8]
-+
-+	inc	16,%o0
-+	addccc	%o5,%o4,%o5
-+	stuw	%o5,[%o0-4]
-+	and	%o3,-4,%g1
-+	brnz,a,pt	%g1,.L_bn_add_words_loop
-+	lduw	[%o1],%o4
-+
-+	brnz,a,pn	%o3,.L_bn_add_words_tail
-+	lduw	[%o1],%o4
-+.L_bn_add_words_return:
-+	clr	%o0
-+	retl
-+	movcs	%icc,1,%o0
-+	nop
-+
-+.L_bn_add_words_tail:
-+	lduw	[%o2],%o5
-+	dec	%o3
-+	addccc	%o5,%o4,%o5
-+	brz,pt	%o3,.L_bn_add_words_return
-+	stuw	%o5,[%o0]
-+
-+	lduw	[%o1+4],%o4
-+	lduw	[%o2+4],%o5
-+	dec	%o3
-+	addccc	%o5,%o4,%o5
-+	brz,pt	%o3,.L_bn_add_words_return
-+	stuw	%o5,[%o0+4]
-+
-+	lduw	[%o1+8],%o4
-+	lduw	[%o2+8],%o5
-+	addccc	%o5,%o4,%o5
-+	stuw	%o5,[%o0+8]
-+	clr	%o0
-+	retl
-+	movcs	%icc,1,%o0
-+
-+.type	bn_add_words,#function
-+.size	bn_add_words,(.-bn_add_words)
-+
-+.global bn_sub_words
-+/*
-+ * BN_ULONG bn_sub_words(rp,ap,bp,n)
-+ * BN_ULONG *rp,*ap,*bp;
-+ * int n;
-+ */
-+bn_sub_words:
-+	sra	%o3,%g0,%o3	! signx %o3
-+	brgz,a	%o3,.L_bn_sub_words_proceed
-+	lduw	[%o1],%o4
-+	retl
-+	clr	%o0
-+
-+.L_bn_sub_words_proceed:
-+	andcc	%o3,-4,%g0
-+	bz,pn	%icc,.L_bn_sub_words_tail
-+	addcc	%g0,0,%g0	! clear carry flag
-+
-+.L_bn_sub_words_loop:		! wow! 32 aligned!
-+	dec	4,%o3
-+	lduw	[%o2],%o5
-+	lduw	[%o1+4],%g1
-+	lduw	[%o2+4],%g2
-+	lduw	[%o1+8],%g3
-+	lduw	[%o2+8],%g4
-+	subccc	%o4,%o5,%o5
-+	stuw	%o5,[%o0]
-+
-+	lduw	[%o1+12],%o4
-+	lduw	[%o2+12],%o5
-+	inc	16,%o1
-+	subccc	%g1,%g2,%g2
-+	stuw	%g2,[%o0+4]
-+
-+	inc	16,%o2
-+	subccc	%g3,%g4,%g4
-+	stuw	%g4,[%o0+8]
-+
-+	inc	16,%o0
-+	subccc	%o4,%o5,%o5
-+	stuw	%o5,[%o0-4]
-+	and	%o3,-4,%g1
-+	brnz,a,pt	%g1,.L_bn_sub_words_loop
-+	lduw	[%o1],%o4
-+
-+	brnz,a,pn	%o3,.L_bn_sub_words_tail
-+	lduw	[%o1],%o4
-+.L_bn_sub_words_return:
-+	clr	%o0
-+	retl
-+	movcs	%icc,1,%o0
-+	nop
-+
-+.L_bn_sub_words_tail:		! wow! 32 aligned!
-+	lduw	[%o2],%o5
-+	dec	%o3
-+	subccc	%o4,%o5,%o5
-+	brz,pt	%o3,.L_bn_sub_words_return
-+	stuw	%o5,[%o0]
-+
-+	lduw	[%o1+4],%o4
-+	lduw	[%o2+4],%o5
-+	dec	%o3
-+	subccc	%o4,%o5,%o5
-+	brz,pt	%o3,.L_bn_sub_words_return
-+	stuw	%o5,[%o0+4]
-+
-+	lduw	[%o1+8],%o4
-+	lduw	[%o2+8],%o5
-+	subccc	%o4,%o5,%o5
-+	stuw	%o5,[%o0+8]
-+	clr	%o0
-+	retl
-+	movcs	%icc,1,%o0
-+
-+.type	bn_sub_words,#function
-+.size	bn_sub_words,(.-bn_sub_words)
-+
-+/*
-+ * Code below depends on the fact that upper parts of the %l0-%l7
-+ * and %i0-%i7 are zeroed by kernel after context switch. In
-+ * previous versions this comment stated that "the trouble is that
-+ * it's not feasible to implement the mumbo-jumbo in less V9
-+ * instructions:-(" which apparently isn't true thanks to
-+ * 'bcs,a %xcc,.+8; inc %rd' pair. But the performance improvement
-+ * results not from the shorter code, but from elimination of
-+ * multicycle none-pairable 'rd %y,%rd' instructions.
-+ *
-+ *							Andy.
-+ */
-+
-+/*
-+ * Here is register usage map for *all* routines below.
-+ */
-+#define t_1	%o0
-+#define	t_2	%o1
-+#define c_12	%o2
-+#define c_3	%o3
-+
-+#define ap(I)	[%i1+4*I]
-+#define bp(I)	[%i2+4*I]
-+#define rp(I)	[%i0+4*I]
-+
-+#define	a_0	%l0
-+#define	a_1	%l1
-+#define	a_2	%l2
-+#define	a_3	%l3
-+#define	a_4	%l4
-+#define	a_5	%l5
-+#define	a_6	%l6
-+#define	a_7	%l7
-+
-+#define	b_0	%i3
-+#define	b_1	%i4
-+#define	b_2	%i5
-+#define	b_3	%o4
-+#define	b_4	%o5
-+#define	b_5	%o7
-+#define	b_6	%g1
-+#define	b_7	%g4
-+
-+.align	32
-+.global bn_mul_comba8
-+/*
-+ * void bn_mul_comba8(r,a,b)
-+ * BN_ULONG *r,*a,*b;
-+ */
-+bn_mul_comba8:
-+	save	%sp,FRAME_SIZE,%sp
-+	mov	1,t_2
-+	lduw	ap(0),a_0
-+	sllx	t_2,32,t_2
-+	lduw	bp(0),b_0	!=
-+	lduw	bp(1),b_1
-+	mulx	a_0,b_0,t_1	!mul_add_c(a[0],b[0],c1,c2,c3);
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(0)	!=!r[0]=c1;
-+
-+	lduw	ap(1),a_1
-+	mulx	a_0,b_1,t_1	!mul_add_c(a[0],b[1],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3		!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	ap(2),a_2
-+	mulx	a_1,b_0,t_1	!=!mul_add_c(a[1],b[0],c2,c3,c1);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12	!=
-+	stuw	t_1,rp(1)	!r[1]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
-+	addcc	c_12,t_1,c_12	!=
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	bp(2),b_2	!=
-+	mulx	a_1,b_1,t_1	!mul_add_c(a[1],b[1],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	lduw	bp(3),b_3
-+	mulx	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(2)	!r[2]=c3;
-+	or	c_12,c_3,c_12	!=
-+
-+	mulx	a_0,b_3,t_1	!mul_add_c(a[0],b[3],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_1,b_2,t_1	!=!mul_add_c(a[1],b[2],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	lduw	ap(3),a_3
-+	mulx	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
-+	addcc	c_12,t_1,c_12	!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	ap(4),a_4
-+	mulx	a_3,b_0,t_1	!=!mul_add_c(a[3],b[0],c1,c2,c3);!=
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12	!=
-+	stuw	t_1,rp(3)	!r[3]=c1;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_4,b_0,t_1	!mul_add_c(a[4],b[0],c2,c3,c1);
-+	addcc	c_12,t_1,c_12	!=
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_3,b_1,t_1	!=!mul_add_c(a[3],b[1],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_2,b_2,t_1	!=!mul_add_c(a[2],b[2],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	bp(4),b_4	!=
-+	mulx	a_1,b_3,t_1	!mul_add_c(a[1],b[3],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	lduw	bp(5),b_5
-+	mulx	a_0,b_4,t_1	!mul_add_c(a[0],b[4],c2,c3,c1);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(4)	!r[4]=c2;
-+	or	c_12,c_3,c_12	!=
-+
-+	mulx	a_0,b_5,t_1	!mul_add_c(a[0],b[5],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_1,b_4,t_1	!mul_add_c(a[1],b[4],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_2,b_3,t_1	!mul_add_c(a[2],b[3],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	lduw	ap(5),a_5
-+	mulx	a_4,b_1,t_1	!mul_add_c(a[4],b[1],c3,c1,c2);
-+	addcc	c_12,t_1,c_12	!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	ap(6),a_6
-+	mulx	a_5,b_0,t_1	!=!mul_add_c(a[5],b[0],c3,c1,c2);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12	!=
-+	stuw	t_1,rp(5)	!r[5]=c3;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_6,b_0,t_1	!mul_add_c(a[6],b[0],c1,c2,c3);
-+	addcc	c_12,t_1,c_12	!=
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_5,b_1,t_1	!=!mul_add_c(a[5],b[1],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_4,b_2,t_1	!=!mul_add_c(a[4],b[2],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_3,b_3,t_1	!=!mul_add_c(a[3],b[3],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_2,b_4,t_1	!=!mul_add_c(a[2],b[4],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	bp(6),b_6	!=
-+	mulx	a_1,b_5,t_1	!mul_add_c(a[1],b[5],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	lduw	bp(7),b_7
-+	mulx	a_0,b_6,t_1	!mul_add_c(a[0],b[6],c1,c2,c3);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(6)	!r[6]=c1;
-+	or	c_12,c_3,c_12	!=
-+
-+	mulx	a_0,b_7,t_1	!mul_add_c(a[0],b[7],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_1,b_6,t_1	!mul_add_c(a[1],b[6],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_2,b_5,t_1	!mul_add_c(a[2],b[5],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_3,b_4,t_1	!mul_add_c(a[3],b[4],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_4,b_3,t_1	!mul_add_c(a[4],b[3],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_5,b_2,t_1	!mul_add_c(a[5],b[2],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	lduw	ap(7),a_7
-+	mulx	a_6,b_1,t_1	!=!mul_add_c(a[6],b[1],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_7,b_0,t_1	!=!mul_add_c(a[7],b[0],c2,c3,c1);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12	!=
-+	stuw	t_1,rp(7)	!r[7]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_7,b_1,t_1	!=!mul_add_c(a[7],b[1],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	mulx	a_6,b_2,t_1	!mul_add_c(a[6],b[2],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	mulx	a_5,b_3,t_1	!mul_add_c(a[5],b[3],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	mulx	a_4,b_4,t_1	!mul_add_c(a[4],b[4],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	mulx	a_3,b_5,t_1	!mul_add_c(a[3],b[5],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	mulx	a_2,b_6,t_1	!mul_add_c(a[2],b[6],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	mulx	a_1,b_7,t_1	!mul_add_c(a[1],b[7],c3,c1,c2);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(8)	!r[8]=c3;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_2,b_7,t_1	!=!mul_add_c(a[2],b[7],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	mulx	a_3,b_6,t_1	!mul_add_c(a[3],b[6],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_4,b_5,t_1	!mul_add_c(a[4],b[5],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_5,b_4,t_1	!mul_add_c(a[5],b[4],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_6,b_3,t_1	!mul_add_c(a[6],b[3],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_7,b_2,t_1	!mul_add_c(a[7],b[2],c1,c2,c3);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(9)	!r[9]=c1;
-+	or	c_12,c_3,c_12	!=
-+
-+	mulx	a_7,b_3,t_1	!mul_add_c(a[7],b[3],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_6,b_4,t_1	!mul_add_c(a[6],b[4],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_5,b_5,t_1	!mul_add_c(a[5],b[5],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_4,b_6,t_1	!mul_add_c(a[4],b[6],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_3,b_7,t_1	!mul_add_c(a[3],b[7],c2,c3,c1);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(10)	!r[10]=c2;
-+	or	c_12,c_3,c_12	!=
-+
-+	mulx	a_4,b_7,t_1	!mul_add_c(a[4],b[7],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_5,b_6,t_1	!mul_add_c(a[5],b[6],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_6,b_5,t_1	!mul_add_c(a[6],b[5],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_7,b_4,t_1	!mul_add_c(a[7],b[4],c3,c1,c2);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(11)	!r[11]=c3;
-+	or	c_12,c_3,c_12	!=
-+
-+	mulx	a_7,b_5,t_1	!mul_add_c(a[7],b[5],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_6,b_6,t_1	!mul_add_c(a[6],b[6],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_5,b_7,t_1	!mul_add_c(a[5],b[7],c1,c2,c3);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(12)	!r[12]=c1;
-+	or	c_12,c_3,c_12	!=
-+
-+	mulx	a_6,b_7,t_1	!mul_add_c(a[6],b[7],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_7,b_6,t_1	!mul_add_c(a[7],b[6],c2,c3,c1);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	st	t_1,rp(13)	!r[13]=c2;
-+	or	c_12,c_3,c_12	!=
-+
-+	mulx	a_7,b_7,t_1	!mul_add_c(a[7],b[7],c3,c1,c2);
-+	addcc	c_12,t_1,t_1
-+	srlx	t_1,32,c_12	!=
-+	stuw	t_1,rp(14)	!r[14]=c3;
-+	stuw	c_12,rp(15)	!r[15]=c1;
-+
-+	ret
-+	restore	%g0,%g0,%o0	!=
-+
-+.type	bn_mul_comba8,#function
-+.size	bn_mul_comba8,(.-bn_mul_comba8)
-+
-+.align	32
-+
-+.global bn_mul_comba4
-+/*
-+ * void bn_mul_comba4(r,a,b)
-+ * BN_ULONG *r,*a,*b;
-+ */
-+bn_mul_comba4:
-+	save	%sp,FRAME_SIZE,%sp
-+	lduw	ap(0),a_0
-+	mov	1,t_2
-+	lduw	bp(0),b_0
-+	sllx	t_2,32,t_2	!=
-+	lduw	bp(1),b_1
-+	mulx	a_0,b_0,t_1	!mul_add_c(a[0],b[0],c1,c2,c3);
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(0)	!=!r[0]=c1;
-+
-+	lduw	ap(1),a_1
-+	mulx	a_0,b_1,t_1	!mul_add_c(a[0],b[1],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3		!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	ap(2),a_2
-+	mulx	a_1,b_0,t_1	!=!mul_add_c(a[1],b[0],c2,c3,c1);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12	!=
-+	stuw	t_1,rp(1)	!r[1]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_2,b_0,t_1	!mul_add_c(a[2],b[0],c3,c1,c2);
-+	addcc	c_12,t_1,c_12	!=
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	bp(2),b_2	!=
-+	mulx	a_1,b_1,t_1	!mul_add_c(a[1],b[1],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3	!=
-+	lduw	bp(3),b_3
-+	mulx	a_0,b_2,t_1	!mul_add_c(a[0],b[2],c3,c1,c2);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(2)	!r[2]=c3;
-+	or	c_12,c_3,c_12	!=
-+
-+	mulx	a_0,b_3,t_1	!mul_add_c(a[0],b[3],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	mulx	a_1,b_2,t_1	!mul_add_c(a[1],b[2],c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8	!=
-+	add	c_3,t_2,c_3
-+	lduw	ap(3),a_3
-+	mulx	a_2,b_1,t_1	!mul_add_c(a[2],b[1],c1,c2,c3);
-+	addcc	c_12,t_1,c_12	!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_3,b_0,t_1	!mul_add_c(a[3],b[0],c1,c2,c3);!=
-+	addcc	c_12,t_1,t_1	!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(3)	!=!r[3]=c1;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_3,b_1,t_1	!mul_add_c(a[3],b[1],c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3		!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_2,b_2,t_1	!mul_add_c(a[2],b[2],c2,c3,c1);
-+	addcc	c_12,t_1,c_12	!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_1,b_3,t_1	!mul_add_c(a[1],b[3],c2,c3,c1);
-+	addcc	c_12,t_1,t_1	!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(4)	!=!r[4]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_2,b_3,t_1	!mul_add_c(a[2],b[3],c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3		!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_3,b_2,t_1	!mul_add_c(a[3],b[2],c3,c1,c2);
-+	addcc	c_12,t_1,t_1	!=
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(5)	!=!r[5]=c3;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_3,b_3,t_1	!mul_add_c(a[3],b[3],c1,c2,c3);
-+	addcc	c_12,t_1,t_1
-+	srlx	t_1,32,c_12	!=
-+	stuw	t_1,rp(6)	!r[6]=c1;
-+	stuw	c_12,rp(7)	!r[7]=c2;
-+	
-+	ret
-+	restore	%g0,%g0,%o0
-+
-+.type	bn_mul_comba4,#function
-+.size	bn_mul_comba4,(.-bn_mul_comba4)
-+
-+.align	32
-+
-+.global bn_sqr_comba8
-+bn_sqr_comba8:
-+	save	%sp,FRAME_SIZE,%sp
-+	mov	1,t_2
-+	lduw	ap(0),a_0
-+	sllx	t_2,32,t_2
-+	lduw	ap(1),a_1
-+	mulx	a_0,a_0,t_1	!sqr_add_c(a,0,c1,c2,c3);
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(0)	!r[0]=c1;
-+
-+	lduw	ap(2),a_2
-+	mulx	a_0,a_1,t_1	!=!sqr_add_c2(a,1,0,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(1)	!r[1]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	ap(3),a_3
-+	mulx	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(2)	!r[2]=c3;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_0,a_3,t_1	!sqr_add_c2(a,3,0,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	ap(4),a_4
-+	mulx	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	st	t_1,rp(3)	!r[3]=c1;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_4,a_0,t_1	!sqr_add_c2(a,4,0,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	ap(5),a_5
-+	mulx	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(4)	!r[4]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_0,a_5,t_1	!sqr_add_c2(a,5,0,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_1,a_4,t_1	!sqr_add_c2(a,4,1,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	ap(6),a_6
-+	mulx	a_2,a_3,t_1	!sqr_add_c2(a,3,2,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(5)	!r[5]=c3;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_6,a_0,t_1	!sqr_add_c2(a,6,0,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_5,a_1,t_1	!sqr_add_c2(a,5,1,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_4,a_2,t_1	!sqr_add_c2(a,4,2,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	ap(7),a_7
-+	mulx	a_3,a_3,t_1	!=!sqr_add_c(a,3,c1,c2,c3);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(6)	!r[6]=c1;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_0,a_7,t_1	!sqr_add_c2(a,7,0,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_1,a_6,t_1	!sqr_add_c2(a,6,1,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_2,a_5,t_1	!sqr_add_c2(a,5,2,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_3,a_4,t_1	!sqr_add_c2(a,4,3,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(7)	!r[7]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_7,a_1,t_1	!sqr_add_c2(a,7,1,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_6,a_2,t_1	!sqr_add_c2(a,6,2,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_5,a_3,t_1	!sqr_add_c2(a,5,3,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_4,a_4,t_1	!sqr_add_c(a,4,c3,c1,c2);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(8)	!r[8]=c3;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_2,a_7,t_1	!sqr_add_c2(a,7,2,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_3,a_6,t_1	!sqr_add_c2(a,6,3,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_4,a_5,t_1	!sqr_add_c2(a,5,4,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(9)	!r[9]=c1;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_7,a_3,t_1	!sqr_add_c2(a,7,3,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_6,a_4,t_1	!sqr_add_c2(a,6,4,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_5,a_5,t_1	!sqr_add_c(a,5,c2,c3,c1);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(10)	!r[10]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_4,a_7,t_1	!sqr_add_c2(a,7,4,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_5,a_6,t_1	!sqr_add_c2(a,6,5,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(11)	!r[11]=c3;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_7,a_5,t_1	!sqr_add_c2(a,7,5,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_6,a_6,t_1	!sqr_add_c(a,6,c1,c2,c3);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(12)	!r[12]=c1;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_6,a_7,t_1	!sqr_add_c2(a,7,6,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(13)	!r[13]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_7,a_7,t_1	!sqr_add_c(a,7,c3,c1,c2);
-+	addcc	c_12,t_1,t_1
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(14)	!r[14]=c3;
-+	stuw	c_12,rp(15)	!r[15]=c1;
-+
-+	ret
-+	restore	%g0,%g0,%o0
-+
-+.type	bn_sqr_comba8,#function
-+.size	bn_sqr_comba8,(.-bn_sqr_comba8)
-+
-+.align	32
-+
-+.global bn_sqr_comba4
-+/*
-+ * void bn_sqr_comba4(r,a)
-+ * BN_ULONG *r,*a;
-+ */
-+bn_sqr_comba4:
-+	save	%sp,FRAME_SIZE,%sp
-+	mov	1,t_2
-+	lduw	ap(0),a_0
-+	sllx	t_2,32,t_2
-+	lduw	ap(1),a_1
-+	mulx	a_0,a_0,t_1	!sqr_add_c(a,0,c1,c2,c3);
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(0)	!r[0]=c1;
-+
-+	lduw	ap(2),a_2
-+	mulx	a_0,a_1,t_1	!sqr_add_c2(a,1,0,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(1)	!r[1]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_2,a_0,t_1	!sqr_add_c2(a,2,0,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	lduw	ap(3),a_3
-+	mulx	a_1,a_1,t_1	!sqr_add_c(a,1,c3,c1,c2);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(2)	!r[2]=c3;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_0,a_3,t_1	!sqr_add_c2(a,3,0,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_1,a_2,t_1	!sqr_add_c2(a,2,1,c1,c2,c3);
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(3)	!r[3]=c1;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_3,a_1,t_1	!sqr_add_c2(a,3,1,c2,c3,c1);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,c_12
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	mulx	a_2,a_2,t_1	!sqr_add_c(a,2,c2,c3,c1);
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(4)	!r[4]=c2;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_2,a_3,t_1	!sqr_add_c2(a,3,2,c3,c1,c2);
-+	addcc	c_12,t_1,c_12
-+	clr	c_3
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	addcc	c_12,t_1,t_1
-+	bcs,a	%xcc,.+8
-+	add	c_3,t_2,c_3
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(5)	!r[5]=c3;
-+	or	c_12,c_3,c_12
-+
-+	mulx	a_3,a_3,t_1	!sqr_add_c(a,3,c1,c2,c3);
-+	addcc	c_12,t_1,t_1
-+	srlx	t_1,32,c_12
-+	stuw	t_1,rp(6)	!r[6]=c1;
-+	stuw	c_12,rp(7)	!r[7]=c2;
-+	
-+	ret
-+	restore	%g0,%g0,%o0
-+
-+.type	bn_sqr_comba4,#function
-+.size	bn_sqr_comba4,(.-bn_sqr_comba4)
-+
-+.align	32
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9-gf2m.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9-gf2m.pl
-new file mode 100644
-index 0000000..dcf11a8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9-gf2m.pl
-@@ -0,0 +1,200 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# October 2012
-+#
-+# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
-+# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
-+# the time being... Except that it has two code paths: one suitable
-+# for all SPARCv9 processors and one for VIS3-capable ones. Former
-+# delivers ~25-45% more, more for longer keys, heaviest DH and DSA
-+# verify operations on venerable UltraSPARC II. On T4 VIS3 code is
-+# ~100-230% faster than gcc-generated code and ~35-90% faster than
-+# the pure SPARCv9 code path.
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+$locals=16*8;
-+
-+$tab="%l0";
-+
-+@T=("%g2","%g3");
-+@i=("%g4","%g5");
-+
-+($a1,$a2,$a4,$a8,$a12,$a48)=map("%o$_",(0..5));
-+($lo,$hi,$b)=("%g1",$a8,"%o7"); $a=$lo;
-+
-+$code.=<<___;
-+#include 
-+
-+#ifdef __arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+#endif
-+
-+#ifdef __PIC__
-+SPARC_PIC_THUNK(%g1)
-+#endif
-+
-+.globl	bn_GF2m_mul_2x2
-+.align	16
-+bn_GF2m_mul_2x2:
-+        SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+        ld	[%g1+0],%g1             	! OPENSSL_sparcv9cap_P[0]
-+
-+        andcc	%g1, SPARCV9_VIS3, %g0
-+        bz,pn	%icc,.Lsoftware
-+        nop
-+
-+	sllx	%o1, 32, %o1
-+	sllx	%o3, 32, %o3
-+	or	%o2, %o1, %o1
-+	or	%o4, %o3, %o3
-+	.word	0x95b262ab			! xmulx   %o1, %o3, %o2
-+	.word	0x99b262cb			! xmulxhi %o1, %o3, %o4
-+	srlx	%o2, 32, %o1			! 13 cycles later
-+	st	%o2, [%o0+0]
-+	st	%o1, [%o0+4]
-+	srlx	%o4, 32, %o3
-+	st	%o4, [%o0+8]
-+	retl
-+	st	%o3, [%o0+12]
-+
-+.align	16
-+.Lsoftware:
-+	save	%sp,-STACK_FRAME-$locals,%sp
-+
-+	sllx	%i1,32,$a
-+	mov	-1,$a12
-+	sllx	%i3,32,$b
-+	or	%i2,$a,$a
-+	srlx	$a12,1,$a48			! 0x7fff...
-+	or	%i4,$b,$b
-+	srlx	$a12,2,$a12			! 0x3fff...
-+	add	%sp,STACK_BIAS+STACK_FRAME,$tab
-+
-+	sllx	$a,2,$a4
-+	mov	$a,$a1
-+	sllx	$a,1,$a2
-+
-+	srax	$a4,63,@i[1]			! broadcast 61st bit
-+	and	$a48,$a4,$a4			! (a<<2)&0x7fff...
-+	srlx	$a48,2,$a48
-+	srax	$a2,63,@i[0]			! broadcast 62nd bit
-+	and	$a12,$a2,$a2			! (a<<1)&0x3fff...
-+	srax	$a1,63,$lo			! broadcast 63rd bit
-+	and	$a48,$a1,$a1			! (a<<0)&0x1fff...
-+
-+	sllx	$a1,3,$a8
-+	and	$b,$lo,$lo
-+	and	$b,@i[0],@i[0]
-+	and	$b,@i[1],@i[1]
-+
-+	stx	%g0,[$tab+0*8]			! tab[0]=0
-+	xor	$a1,$a2,$a12
-+	stx	$a1,[$tab+1*8]			! tab[1]=a1
-+	stx	$a2,[$tab+2*8]			! tab[2]=a2
-+	 xor	$a4,$a8,$a48
-+	stx	$a12,[$tab+3*8]			! tab[3]=a1^a2
-+	 xor	$a4,$a1,$a1
-+
-+	stx	$a4,[$tab+4*8]			! tab[4]=a4
-+	xor	$a4,$a2,$a2
-+	stx	$a1,[$tab+5*8]			! tab[5]=a1^a4
-+	xor	$a4,$a12,$a12
-+	stx	$a2,[$tab+6*8]			! tab[6]=a2^a4
-+	 xor	$a48,$a1,$a1
-+	stx	$a12,[$tab+7*8]			! tab[7]=a1^a2^a4
-+	 xor	$a48,$a2,$a2
-+
-+	stx	$a8,[$tab+8*8]			! tab[8]=a8
-+	xor	$a48,$a12,$a12
-+	stx	$a1,[$tab+9*8]			! tab[9]=a1^a8
-+	 xor	$a4,$a1,$a1
-+	stx	$a2,[$tab+10*8]			! tab[10]=a2^a8
-+	 xor	$a4,$a2,$a2
-+	stx	$a12,[$tab+11*8]		! tab[11]=a1^a2^a8
-+
-+	xor	$a4,$a12,$a12
-+	stx	$a48,[$tab+12*8]		! tab[12]=a4^a8
-+	 srlx	$lo,1,$hi
-+	stx	$a1,[$tab+13*8]			! tab[13]=a1^a4^a8
-+	 sllx	$lo,63,$lo
-+	stx	$a2,[$tab+14*8]			! tab[14]=a2^a4^a8
-+	 srlx	@i[0],2,@T[0]
-+	stx	$a12,[$tab+15*8]		! tab[15]=a1^a2^a4^a8
-+
-+	sllx	@i[0],62,$a1
-+	 sllx	$b,3,@i[0]
-+	srlx	@i[1],3,@T[1]
-+	 and	@i[0],`0xf<<3`,@i[0]
-+	sllx	@i[1],61,$a2
-+	 ldx	[$tab+@i[0]],@i[0]
-+	 srlx	$b,4-3,@i[1]
-+	xor	@T[0],$hi,$hi
-+	 and	@i[1],`0xf<<3`,@i[1]
-+	xor	$a1,$lo,$lo
-+	 ldx	[$tab+@i[1]],@i[1]
-+	xor	@T[1],$hi,$hi
-+
-+	xor	@i[0],$lo,$lo
-+	srlx	$b,8-3,@i[0]
-+	 xor	$a2,$lo,$lo
-+	and	@i[0],`0xf<<3`,@i[0]
-+___
-+for($n=1;$n<14;$n++) {
-+$code.=<<___;
-+	sllx	@i[1],`$n*4`,@T[0]
-+	ldx	[$tab+@i[0]],@i[0]
-+	srlx	@i[1],`64-$n*4`,@T[1]
-+	xor	@T[0],$lo,$lo
-+	srlx	$b,`($n+2)*4`-3,@i[1]
-+	xor	@T[1],$hi,$hi
-+	and	@i[1],`0xf<<3`,@i[1]
-+___
-+	push(@i,shift(@i)); push(@T,shift(@T));
-+}
-+$code.=<<___;
-+	sllx	@i[1],`$n*4`,@T[0]
-+	ldx	[$tab+@i[0]],@i[0]
-+	srlx	@i[1],`64-$n*4`,@T[1]
-+	xor	@T[0],$lo,$lo
-+
-+	sllx	@i[0],`($n+1)*4`,@T[0]
-+	 xor	@T[1],$hi,$hi
-+	srlx	@i[0],`64-($n+1)*4`,@T[1]
-+	xor	@T[0],$lo,$lo
-+	xor	@T[1],$hi,$hi
-+
-+	srlx	$lo,32,%i1
-+	st	$lo,[%i0+0]
-+	st	%i1,[%i0+4]
-+	srlx	$hi,32,%i2
-+	st	$hi,[%i0+8]
-+	st	%i2,[%i0+12]
-+
-+	ret
-+	restore
-+.type	bn_GF2m_mul_2x2,#function
-+.size	bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
-+.asciz	"GF(2^m) Multiplication for SPARCv9, CRYPTOGAMS by "
-+.align	4
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9-mont.pl
-new file mode 100644
-index 0000000..c36ce36
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9-mont.pl
-@@ -0,0 +1,616 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# December 2005
-+#
-+# Pure SPARCv9/8+ and IALU-only bn_mul_mont implementation. The reasons
-+# for undertaken effort are multiple. First of all, UltraSPARC is not
-+# the whole SPARCv9 universe and other VIS-free implementations deserve
-+# optimized code as much. Secondly, newly introduced UltraSPARC T1,
-+# a.k.a. Niagara, has shared FPU and concurrent FPU-intensive paths,
-+# such as sparcv9a-mont, will simply sink it. Yes, T1 is equipped with
-+# several integrated RSA/DSA accelerator circuits accessible through
-+# kernel driver [only(*)], but having decent user-land software
-+# implementation is important too. Finally, reasons like desire to
-+# experiment with dedicated squaring procedure. Yes, this module
-+# implements one, because it was easiest to draft it in SPARCv9
-+# instructions...
-+
-+# (*)	Engine accessing the driver in question is on my TODO list.
-+#	For reference, acceleator is estimated to give 6 to 10 times
-+#	improvement on single-threaded RSA sign. It should be noted
-+#	that 6-10x improvement coefficient does not actually mean
-+#	something extraordinary in terms of absolute [single-threaded]
-+#	performance, as SPARCv9 instruction set is by all means least
-+#	suitable for high performance crypto among other 64 bit
-+#	platforms. 6-10x factor simply places T1 in same performance
-+#	domain as say AMD64 and IA-64. Improvement of RSA verify don't
-+#	appear impressive at all, but it's the sign operation which is
-+#	far more critical/interesting.
-+
-+# You might notice that inner loops are modulo-scheduled:-) This has
-+# essentially negligible impact on UltraSPARC performance, it's
-+# Fujitsu SPARC64 V users who should notice and hopefully appreciate
-+# the advantage... Currently this module surpasses sparcv9a-mont.pl
-+# by ~20% on UltraSPARC-III and later cores, but recall that sparcv9a
-+# module still have hidden potential [see TODO list there], which is
-+# estimated to be larger than 20%...
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+# int bn_mul_mont(
-+$rp="%i0";	# BN_ULONG *rp,
-+$ap="%i1";	# const BN_ULONG *ap,
-+$bp="%i2";	# const BN_ULONG *bp,
-+$np="%i3";	# const BN_ULONG *np,
-+$n0="%i4";	# const BN_ULONG *n0,
-+$num="%i5";	# int num);
-+
-+$frame="STACK_FRAME";
-+$bias="STACK_BIAS";
-+
-+$car0="%o0";
-+$car1="%o1";
-+$car2="%o2";	# 1 bit
-+$acc0="%o3";
-+$acc1="%o4";
-+$mask="%g1";	# 32 bits, what a waste...
-+$tmp0="%g4";
-+$tmp1="%g5";
-+
-+$i="%l0";
-+$j="%l1";
-+$mul0="%l2";
-+$mul1="%l3";
-+$tp="%l4";
-+$apj="%l5";
-+$npj="%l6";
-+$tpj="%l7";
-+
-+$fname="bn_mul_mont_int";
-+
-+$code=<<___;
-+#include "sparc_arch.h"
-+
-+.section	".text",#alloc,#execinstr
-+
-+.global	$fname
-+.align	32
-+$fname:
-+	cmp	%o5,4			! 128 bits minimum
-+	bge,pt	%icc,.Lenter
-+	sethi	%hi(0xffffffff),$mask
-+	retl
-+	clr	%o0
-+.align	32
-+.Lenter:
-+	save	%sp,-$frame,%sp
-+	sll	$num,2,$num		! num*=4
-+	or	$mask,%lo(0xffffffff),$mask
-+	ld	[$n0],$n0
-+	cmp	$ap,$bp
-+	and	$num,$mask,$num
-+	ld	[$bp],$mul0		! bp[0]
-+	nop
-+
-+	add	%sp,$bias,%o7		! real top of stack
-+	ld	[$ap],$car0		! ap[0] ! redundant in squaring context
-+	sub	%o7,$num,%o7
-+	ld	[$ap+4],$apj		! ap[1]
-+	and	%o7,-1024,%o7
-+	ld	[$np],$car1		! np[0]
-+	sub	%o7,$bias,%sp		! alloca
-+	ld	[$np+4],$npj		! np[1]
-+	be,pt	SIZE_T_CC,.Lbn_sqr_mont
-+	mov	12,$j
-+
-+	mulx	$car0,$mul0,$car0	! ap[0]*bp[0]
-+	mulx	$apj,$mul0,$tmp0	!prologue! ap[1]*bp[0]
-+	and	$car0,$mask,$acc0
-+	add	%sp,$bias+$frame,$tp
-+	ld	[$ap+8],$apj		!prologue!
-+
-+	mulx	$n0,$acc0,$mul1		! "t[0]"*n0
-+	and	$mul1,$mask,$mul1
-+
-+	mulx	$car1,$mul1,$car1	! np[0]*"t[0]"*n0
-+	mulx	$npj,$mul1,$acc1	!prologue! np[1]*"t[0]"*n0
-+	srlx	$car0,32,$car0
-+	add	$acc0,$car1,$car1
-+	ld	[$np+8],$npj		!prologue!
-+	srlx	$car1,32,$car1
-+	mov	$tmp0,$acc0		!prologue!
-+
-+.L1st:
-+	mulx	$apj,$mul0,$tmp0
-+	mulx	$npj,$mul1,$tmp1
-+	add	$acc0,$car0,$car0
-+	ld	[$ap+$j],$apj		! ap[j]
-+	and	$car0,$mask,$acc0
-+	add	$acc1,$car1,$car1
-+	ld	[$np+$j],$npj		! np[j]
-+	srlx	$car0,32,$car0
-+	add	$acc0,$car1,$car1
-+	add	$j,4,$j			! j++
-+	mov	$tmp0,$acc0
-+	st	$car1,[$tp]
-+	cmp	$j,$num
-+	mov	$tmp1,$acc1
-+	srlx	$car1,32,$car1
-+	bl	%icc,.L1st
-+	add	$tp,4,$tp		! tp++
-+!.L1st
-+
-+	mulx	$apj,$mul0,$tmp0	!epilogue!
-+	mulx	$npj,$mul1,$tmp1
-+	add	$acc0,$car0,$car0
-+	and	$car0,$mask,$acc0
-+	add	$acc1,$car1,$car1
-+	srlx	$car0,32,$car0
-+	add	$acc0,$car1,$car1
-+	st	$car1,[$tp]
-+	srlx	$car1,32,$car1
-+
-+	add	$tmp0,$car0,$car0
-+	and	$car0,$mask,$acc0
-+	add	$tmp1,$car1,$car1
-+	srlx	$car0,32,$car0
-+	add	$acc0,$car1,$car1
-+	st	$car1,[$tp+4]
-+	srlx	$car1,32,$car1
-+
-+	add	$car0,$car1,$car1
-+	st	$car1,[$tp+8]
-+	srlx	$car1,32,$car2
-+
-+	mov	4,$i			! i++
-+	ld	[$bp+4],$mul0		! bp[1]
-+.Louter:
-+	add	%sp,$bias+$frame,$tp
-+	ld	[$ap],$car0		! ap[0]
-+	ld	[$ap+4],$apj		! ap[1]
-+	ld	[$np],$car1		! np[0]
-+	ld	[$np+4],$npj		! np[1]
-+	ld	[$tp],$tmp1		! tp[0]
-+	ld	[$tp+4],$tpj		! tp[1]
-+	mov	12,$j
-+
-+	mulx	$car0,$mul0,$car0
-+	mulx	$apj,$mul0,$tmp0	!prologue!
-+	add	$tmp1,$car0,$car0
-+	ld	[$ap+8],$apj		!prologue!
-+	and	$car0,$mask,$acc0
-+
-+	mulx	$n0,$acc0,$mul1
-+	and	$mul1,$mask,$mul1
-+
-+	mulx	$car1,$mul1,$car1
-+	mulx	$npj,$mul1,$acc1	!prologue!
-+	srlx	$car0,32,$car0
-+	add	$acc0,$car1,$car1
-+	ld	[$np+8],$npj		!prologue!
-+	srlx	$car1,32,$car1
-+	mov	$tmp0,$acc0		!prologue!
-+
-+.Linner:
-+	mulx	$apj,$mul0,$tmp0
-+	mulx	$npj,$mul1,$tmp1
-+	add	$tpj,$car0,$car0
-+	ld	[$ap+$j],$apj		! ap[j]
-+	add	$acc0,$car0,$car0
-+	add	$acc1,$car1,$car1
-+	ld	[$np+$j],$npj		! np[j]
-+	and	$car0,$mask,$acc0
-+	ld	[$tp+8],$tpj		! tp[j]
-+	srlx	$car0,32,$car0
-+	add	$acc0,$car1,$car1
-+	add	$j,4,$j			! j++
-+	mov	$tmp0,$acc0
-+	st	$car1,[$tp]		! tp[j-1]
-+	srlx	$car1,32,$car1
-+	mov	$tmp1,$acc1
-+	cmp	$j,$num
-+	bl	%icc,.Linner
-+	add	$tp,4,$tp		! tp++
-+!.Linner
-+
-+	mulx	$apj,$mul0,$tmp0	!epilogue!
-+	mulx	$npj,$mul1,$tmp1
-+	add	$tpj,$car0,$car0
-+	add	$acc0,$car0,$car0
-+	ld	[$tp+8],$tpj		! tp[j]
-+	and	$car0,$mask,$acc0
-+	add	$acc1,$car1,$car1
-+	srlx	$car0,32,$car0
-+	add	$acc0,$car1,$car1
-+	st	$car1,[$tp]		! tp[j-1]
-+	srlx	$car1,32,$car1
-+
-+	add	$tpj,$car0,$car0
-+	add	$tmp0,$car0,$car0
-+	and	$car0,$mask,$acc0
-+	add	$tmp1,$car1,$car1
-+	add	$acc0,$car1,$car1
-+	st	$car1,[$tp+4]		! tp[j-1]
-+	srlx	$car0,32,$car0
-+	add	$i,4,$i			! i++
-+	srlx	$car1,32,$car1
-+
-+	add	$car0,$car1,$car1
-+	cmp	$i,$num
-+	add	$car2,$car1,$car1
-+	st	$car1,[$tp+8]
-+
-+	srlx	$car1,32,$car2
-+	bl,a	%icc,.Louter
-+	ld	[$bp+$i],$mul0		! bp[i]
-+!.Louter
-+
-+	add	$tp,12,$tp
-+
-+.Ltail:
-+	add	$np,$num,$np
-+	add	$rp,$num,$rp
-+	mov	$tp,$ap
-+	sub	%g0,$num,%o7		! k=-num
-+	ba	.Lsub
-+	subcc	%g0,%g0,%g0		! clear %icc.c
-+.align	16
-+.Lsub:
-+	ld	[$tp+%o7],%o0
-+	ld	[$np+%o7],%o1
-+	subccc	%o0,%o1,%o1		! tp[j]-np[j]
-+	add	$rp,%o7,$i
-+	add	%o7,4,%o7
-+	brnz	%o7,.Lsub
-+	st	%o1,[$i]
-+	subc	$car2,0,$car2		! handle upmost overflow bit
-+	and	$tp,$car2,$ap
-+	andn	$rp,$car2,$np
-+	or	$ap,$np,$ap
-+	sub	%g0,$num,%o7
-+
-+.Lcopy:
-+	ld	[$ap+%o7],%o0		! copy or in-place refresh
-+	st	%g0,[$tp+%o7]		! zap tp
-+	st	%o0,[$rp+%o7]
-+	add	%o7,4,%o7
-+	brnz	%o7,.Lcopy
-+	nop
-+	mov	1,%i0
-+	ret
-+	restore
-+___
-+
-+########
-+######## .Lbn_sqr_mont gives up to 20% *overall* improvement over
-+######## code without following dedicated squaring procedure.
-+########
-+$sbit="%i2";		# re-use $bp!
-+
-+$code.=<<___;
-+.align	32
-+.Lbn_sqr_mont:
-+	mulx	$mul0,$mul0,$car0		! ap[0]*ap[0]
-+	mulx	$apj,$mul0,$tmp0		!prologue!
-+	and	$car0,$mask,$acc0
-+	add	%sp,$bias+$frame,$tp
-+	ld	[$ap+8],$apj			!prologue!
-+
-+	mulx	$n0,$acc0,$mul1			! "t[0]"*n0
-+	srlx	$car0,32,$car0
-+	and	$mul1,$mask,$mul1
-+
-+	mulx	$car1,$mul1,$car1		! np[0]*"t[0]"*n0
-+	mulx	$npj,$mul1,$acc1		!prologue!
-+	and	$car0,1,$sbit
-+	ld	[$np+8],$npj			!prologue!
-+	srlx	$car0,1,$car0
-+	add	$acc0,$car1,$car1
-+	srlx	$car1,32,$car1
-+	mov	$tmp0,$acc0			!prologue!
-+
-+.Lsqr_1st:
-+	mulx	$apj,$mul0,$tmp0
-+	mulx	$npj,$mul1,$tmp1
-+	add	$acc0,$car0,$car0		! ap[j]*a0+c0
-+	add	$acc1,$car1,$car1
-+	ld	[$ap+$j],$apj			! ap[j]
-+	and	$car0,$mask,$acc0
-+	ld	[$np+$j],$npj			! np[j]
-+	srlx	$car0,32,$car0
-+	add	$acc0,$acc0,$acc0
-+	or	$sbit,$acc0,$acc0
-+	mov	$tmp1,$acc1
-+	srlx	$acc0,32,$sbit
-+	add	$j,4,$j				! j++
-+	and	$acc0,$mask,$acc0
-+	cmp	$j,$num
-+	add	$acc0,$car1,$car1
-+	st	$car1,[$tp]
-+	mov	$tmp0,$acc0
-+	srlx	$car1,32,$car1
-+	bl	%icc,.Lsqr_1st
-+	add	$tp,4,$tp			! tp++
-+!.Lsqr_1st
-+
-+	mulx	$apj,$mul0,$tmp0		! epilogue
-+	mulx	$npj,$mul1,$tmp1
-+	add	$acc0,$car0,$car0		! ap[j]*a0+c0
-+	add	$acc1,$car1,$car1
-+	and	$car0,$mask,$acc0
-+	srlx	$car0,32,$car0
-+	add	$acc0,$acc0,$acc0
-+	or	$sbit,$acc0,$acc0
-+	srlx	$acc0,32,$sbit
-+	and	$acc0,$mask,$acc0
-+	add	$acc0,$car1,$car1
-+	st	$car1,[$tp]
-+	srlx	$car1,32,$car1
-+
-+	add	$tmp0,$car0,$car0		! ap[j]*a0+c0
-+	add	$tmp1,$car1,$car1
-+	and	$car0,$mask,$acc0
-+	srlx	$car0,32,$car0
-+	add	$acc0,$acc0,$acc0
-+	or	$sbit,$acc0,$acc0
-+	srlx	$acc0,32,$sbit
-+	and	$acc0,$mask,$acc0
-+	add	$acc0,$car1,$car1
-+	st	$car1,[$tp+4]
-+	srlx	$car1,32,$car1
-+
-+	add	$car0,$car0,$car0
-+	or	$sbit,$car0,$car0
-+	add	$car0,$car1,$car1
-+	st	$car1,[$tp+8]
-+	srlx	$car1,32,$car2
-+
-+	ld	[%sp+$bias+$frame],$tmp0	! tp[0]
-+	ld	[%sp+$bias+$frame+4],$tmp1	! tp[1]
-+	ld	[%sp+$bias+$frame+8],$tpj	! tp[2]
-+	ld	[$ap+4],$mul0			! ap[1]
-+	ld	[$ap+8],$apj			! ap[2]
-+	ld	[$np],$car1			! np[0]
-+	ld	[$np+4],$npj			! np[1]
-+	mulx	$n0,$tmp0,$mul1
-+
-+	mulx	$mul0,$mul0,$car0
-+	and	$mul1,$mask,$mul1
-+
-+	mulx	$car1,$mul1,$car1
-+	mulx	$npj,$mul1,$acc1
-+	add	$tmp0,$car1,$car1
-+	and	$car0,$mask,$acc0
-+	ld	[$np+8],$npj			! np[2]
-+	srlx	$car1,32,$car1
-+	add	$tmp1,$car1,$car1
-+	srlx	$car0,32,$car0
-+	add	$acc0,$car1,$car1
-+	and	$car0,1,$sbit
-+	add	$acc1,$car1,$car1
-+	srlx	$car0,1,$car0
-+	mov	12,$j
-+	st	$car1,[%sp+$bias+$frame]	! tp[0]=
-+	srlx	$car1,32,$car1
-+	add	%sp,$bias+$frame+4,$tp
-+
-+.Lsqr_2nd:
-+	mulx	$apj,$mul0,$acc0
-+	mulx	$npj,$mul1,$acc1
-+	add	$acc0,$car0,$car0
-+	add	$tpj,$car1,$car1
-+	ld	[$ap+$j],$apj			! ap[j]
-+	and	$car0,$mask,$acc0
-+	ld	[$np+$j],$npj			! np[j]
-+	srlx	$car0,32,$car0
-+	add	$acc1,$car1,$car1
-+	ld	[$tp+8],$tpj			! tp[j]
-+	add	$acc0,$acc0,$acc0
-+	add	$j,4,$j				! j++
-+	or	$sbit,$acc0,$acc0
-+	srlx	$acc0,32,$sbit
-+	and	$acc0,$mask,$acc0
-+	cmp	$j,$num
-+	add	$acc0,$car1,$car1
-+	st	$car1,[$tp]			! tp[j-1]
-+	srlx	$car1,32,$car1
-+	bl	%icc,.Lsqr_2nd
-+	add	$tp,4,$tp			! tp++
-+!.Lsqr_2nd
-+
-+	mulx	$apj,$mul0,$acc0
-+	mulx	$npj,$mul1,$acc1
-+	add	$acc0,$car0,$car0
-+	add	$tpj,$car1,$car1
-+	and	$car0,$mask,$acc0
-+	srlx	$car0,32,$car0
-+	add	$acc1,$car1,$car1
-+	add	$acc0,$acc0,$acc0
-+	or	$sbit,$acc0,$acc0
-+	srlx	$acc0,32,$sbit
-+	and	$acc0,$mask,$acc0
-+	add	$acc0,$car1,$car1
-+	st	$car1,[$tp]			! tp[j-1]
-+	srlx	$car1,32,$car1
-+
-+	add	$car0,$car0,$car0
-+	or	$sbit,$car0,$car0
-+	add	$car0,$car1,$car1
-+	add	$car2,$car1,$car1
-+	st	$car1,[$tp+4]
-+	srlx	$car1,32,$car2
-+
-+	ld	[%sp+$bias+$frame],$tmp1	! tp[0]
-+	ld	[%sp+$bias+$frame+4],$tpj	! tp[1]
-+	ld	[$ap+8],$mul0			! ap[2]
-+	ld	[$np],$car1			! np[0]
-+	ld	[$np+4],$npj			! np[1]
-+	mulx	$n0,$tmp1,$mul1
-+	and	$mul1,$mask,$mul1
-+	mov	8,$i
-+
-+	mulx	$mul0,$mul0,$car0
-+	mulx	$car1,$mul1,$car1
-+	and	$car0,$mask,$acc0
-+	add	$tmp1,$car1,$car1
-+	srlx	$car0,32,$car0
-+	add	%sp,$bias+$frame,$tp
-+	srlx	$car1,32,$car1
-+	and	$car0,1,$sbit
-+	srlx	$car0,1,$car0
-+	mov	4,$j
-+
-+.Lsqr_outer:
-+.Lsqr_inner1:
-+	mulx	$npj,$mul1,$acc1
-+	add	$tpj,$car1,$car1
-+	add	$j,4,$j
-+	ld	[$tp+8],$tpj
-+	cmp	$j,$i
-+	add	$acc1,$car1,$car1
-+	ld	[$np+$j],$npj
-+	st	$car1,[$tp]
-+	srlx	$car1,32,$car1
-+	bl	%icc,.Lsqr_inner1
-+	add	$tp,4,$tp
-+!.Lsqr_inner1
-+
-+	add	$j,4,$j
-+	ld	[$ap+$j],$apj			! ap[j]
-+	mulx	$npj,$mul1,$acc1
-+	add	$tpj,$car1,$car1
-+	ld	[$np+$j],$npj			! np[j]
-+	add	$acc0,$car1,$car1
-+	ld	[$tp+8],$tpj			! tp[j]
-+	add	$acc1,$car1,$car1
-+	st	$car1,[$tp]
-+	srlx	$car1,32,$car1
-+
-+	add	$j,4,$j
-+	cmp	$j,$num
-+	be,pn	%icc,.Lsqr_no_inner2
-+	add	$tp,4,$tp
-+
-+.Lsqr_inner2:
-+	mulx	$apj,$mul0,$acc0
-+	mulx	$npj,$mul1,$acc1
-+	add	$tpj,$car1,$car1
-+	add	$acc0,$car0,$car0
-+	ld	[$ap+$j],$apj			! ap[j]
-+	and	$car0,$mask,$acc0
-+	ld	[$np+$j],$npj			! np[j]
-+	srlx	$car0,32,$car0
-+	add	$acc0,$acc0,$acc0
-+	ld	[$tp+8],$tpj			! tp[j]
-+	or	$sbit,$acc0,$acc0
-+	add	$j,4,$j				! j++
-+	srlx	$acc0,32,$sbit
-+	and	$acc0,$mask,$acc0
-+	cmp	$j,$num
-+	add	$acc0,$car1,$car1
-+	add	$acc1,$car1,$car1
-+	st	$car1,[$tp]			! tp[j-1]
-+	srlx	$car1,32,$car1
-+	bl	%icc,.Lsqr_inner2
-+	add	$tp,4,$tp			! tp++
-+
-+.Lsqr_no_inner2:
-+	mulx	$apj,$mul0,$acc0
-+	mulx	$npj,$mul1,$acc1
-+	add	$tpj,$car1,$car1
-+	add	$acc0,$car0,$car0
-+	and	$car0,$mask,$acc0
-+	srlx	$car0,32,$car0
-+	add	$acc0,$acc0,$acc0
-+	or	$sbit,$acc0,$acc0
-+	srlx	$acc0,32,$sbit
-+	and	$acc0,$mask,$acc0
-+	add	$acc0,$car1,$car1
-+	add	$acc1,$car1,$car1
-+	st	$car1,[$tp]			! tp[j-1]
-+	srlx	$car1,32,$car1
-+
-+	add	$car0,$car0,$car0
-+	or	$sbit,$car0,$car0
-+	add	$car0,$car1,$car1
-+	add	$car2,$car1,$car1
-+	st	$car1,[$tp+4]
-+	srlx	$car1,32,$car2
-+
-+	add	$i,4,$i				! i++
-+	ld	[%sp+$bias+$frame],$tmp1	! tp[0]
-+	ld	[%sp+$bias+$frame+4],$tpj	! tp[1]
-+	ld	[$ap+$i],$mul0			! ap[j]
-+	ld	[$np],$car1			! np[0]
-+	ld	[$np+4],$npj			! np[1]
-+	mulx	$n0,$tmp1,$mul1
-+	and	$mul1,$mask,$mul1
-+	add	$i,4,$tmp0
-+
-+	mulx	$mul0,$mul0,$car0
-+	mulx	$car1,$mul1,$car1
-+	and	$car0,$mask,$acc0
-+	add	$tmp1,$car1,$car1
-+	srlx	$car0,32,$car0
-+	add	%sp,$bias+$frame,$tp
-+	srlx	$car1,32,$car1
-+	and	$car0,1,$sbit
-+	srlx	$car0,1,$car0
-+
-+	cmp	$tmp0,$num			! i"
-+.align	32
-+___
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9a-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9a-mont.pl
-new file mode 100755
-index 0000000..50b6906
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/sparcv9a-mont.pl
-@@ -0,0 +1,887 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# October 2005
-+#
-+# "Teaser" Montgomery multiplication module for UltraSPARC. Why FPU?
-+# Because unlike integer multiplier, which simply stalls whole CPU,
-+# FPU is fully pipelined and can effectively emit 48 bit partial
-+# product every cycle. Why not blended SPARC v9? One can argue that
-+# making this module dependent on UltraSPARC VIS extension limits its
-+# binary compatibility. Well yes, it does exclude SPARC64 prior-V(!)
-+# implementations from compatibility matrix. But the rest, whole Sun
-+# UltraSPARC family and brand new Fujitsu's SPARC64 V, all support
-+# VIS extension instructions used in this module. This is considered
-+# good enough to not care about HAL SPARC64 users [if any] who have
-+# integer-only pure SPARCv9 module to "fall down" to.
-+
-+# USI&II cores currently exhibit uniform 2x improvement [over pre-
-+# bn_mul_mont codebase] for all key lengths and benchmarks. On USIII
-+# performance improves few percents for shorter keys and worsens few
-+# percents for longer keys. This is because USIII integer multiplier
-+# is >3x faster than USI&II one, which is harder to match [but see
-+# TODO list below]. It should also be noted that SPARC64 V features
-+# out-of-order execution, which *might* mean that integer multiplier
-+# is pipelined, which in turn *might* be impossible to match... On
-+# additional note, SPARC64 V implements FP Multiply-Add instruction,
-+# which is perfectly usable in this context... In other words, as far
-+# as Fujitsu SPARC64 V goes, talk to the author:-)
-+
-+# The implementation implies following "non-natural" limitations on
-+# input arguments:
-+# - num may not be less than 4;
-+# - num has to be even;
-+# Failure to meet either condition has no fatal effects, simply
-+# doesn't give any performance gain.
-+
-+# TODO:
-+# - modulo-schedule inner loop for better performance (on in-order
-+#   execution core such as UltraSPARC this shall result in further
-+#   noticeable(!) improvement);
-+# - dedicated squaring procedure[?];
-+
-+######################################################################
-+# November 2006
-+#
-+# Modulo-scheduled inner loops allow to interleave floating point and
-+# integer instructions and minimize Read-After-Write penalties. This
-+# results in *further* 20-50% performance improvement [depending on
-+# key length, more for longer keys] on USI&II cores and 30-80% - on
-+# USIII&IV.
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+$fname="bn_mul_mont_fpu";
-+
-+$frame="STACK_FRAME";
-+$bias="STACK_BIAS";
-+$locals=64;
-+
-+# In order to provide for 32-/64-bit ABI duality, I keep integers wider
-+# than 32 bit in %g1-%g4 and %o0-%o5. %l0-%l7 and %i0-%i5 are used
-+# exclusively for pointers, indexes and other small values...
-+# int bn_mul_mont(
-+$rp="%i0";	# BN_ULONG *rp,
-+$ap="%i1";	# const BN_ULONG *ap,
-+$bp="%i2";	# const BN_ULONG *bp,
-+$np="%i3";	# const BN_ULONG *np,
-+$n0="%i4";	# const BN_ULONG *n0,
-+$num="%i5";	# int num);
-+
-+$tp="%l0";	# t[num]
-+$ap_l="%l1";	# a[num],n[num] are smashed to 32-bit words and saved
-+$ap_h="%l2";	# to these four vectors as double-precision FP values.
-+$np_l="%l3";	# This way a bunch of fxtods are eliminated in second
-+$np_h="%l4";	# loop and L1-cache aliasing is minimized...
-+$i="%l5";
-+$j="%l6";
-+$mask="%l7";	# 16-bit mask, 0xffff
-+
-+$n0="%g4";	# reassigned(!) to "64-bit" register
-+$carry="%i4";	# %i4 reused(!) for a carry bit
-+
-+# FP register naming chart
-+#
-+#     ..HILO
-+#       dcba
-+#   --------
-+#        LOa
-+#       LOb
-+#      LOc
-+#     LOd
-+#      HIa
-+#     HIb
-+#    HIc
-+#   HId
-+#    ..a
-+#   ..b
-+$ba="%f0";    $bb="%f2";    $bc="%f4";    $bd="%f6";
-+$na="%f8";    $nb="%f10";   $nc="%f12";   $nd="%f14";
-+$alo="%f16";  $alo_="%f17"; $ahi="%f18";  $ahi_="%f19";
-+$nlo="%f20";  $nlo_="%f21"; $nhi="%f22";  $nhi_="%f23";
-+
-+$dota="%f24"; $dotb="%f26";
-+
-+$aloa="%f32"; $alob="%f34"; $aloc="%f36"; $alod="%f38";
-+$ahia="%f40"; $ahib="%f42"; $ahic="%f44"; $ahid="%f46";
-+$nloa="%f48"; $nlob="%f50"; $nloc="%f52"; $nlod="%f54";
-+$nhia="%f56"; $nhib="%f58"; $nhic="%f60"; $nhid="%f62";
-+
-+$ASI_FL16_P=0xD2;	# magic ASI value to engage 16-bit FP load
-+
-+$code=<<___;
-+#include "sparc_arch.h"
-+
-+.section	".text",#alloc,#execinstr
-+
-+.global $fname
-+.align  32
-+$fname:
-+	save	%sp,-$frame-$locals,%sp
-+
-+	cmp	$num,4
-+	bl,a,pn %icc,.Lret
-+	clr	%i0
-+	andcc	$num,1,%g0		! $num has to be even...
-+	bnz,a,pn %icc,.Lret
-+	clr	%i0			! signal "unsupported input value"
-+
-+	srl	$num,1,$num
-+	sethi	%hi(0xffff),$mask
-+	ld	[%i4+0],$n0		! $n0 reassigned, remember?
-+	or	$mask,%lo(0xffff),$mask
-+	ld	[%i4+4],%o0
-+	sllx	%o0,32,%o0
-+	or	%o0,$n0,$n0		! $n0=n0[1].n0[0]
-+
-+	sll	$num,3,$num		! num*=8
-+
-+	add	%sp,$bias,%o0		! real top of stack
-+	sll	$num,2,%o1
-+	add	%o1,$num,%o1		! %o1=num*5
-+	sub	%o0,%o1,%o0
-+	and	%o0,-2048,%o0		! optimize TLB utilization
-+	sub	%o0,$bias,%sp		! alloca(5*num*8)
-+
-+	rd	%asi,%o7		! save %asi
-+	add	%sp,$bias+$frame+$locals,$tp
-+	add	$tp,$num,$ap_l
-+	add	$ap_l,$num,$ap_l	! [an]p_[lh] point at the vectors' ends !
-+	add	$ap_l,$num,$ap_h
-+	add	$ap_h,$num,$np_l
-+	add	$np_l,$num,$np_h
-+
-+	wr	%g0,$ASI_FL16_P,%asi	! setup %asi for 16-bit FP loads
-+
-+	add	$rp,$num,$rp		! readjust input pointers to point
-+	add	$ap,$num,$ap		! at the ends too...
-+	add	$bp,$num,$bp
-+	add	$np,$num,$np
-+
-+	stx	%o7,[%sp+$bias+$frame+48]	! save %asi
-+
-+	sub	%g0,$num,$i		! i=-num
-+	sub	%g0,$num,$j		! j=-num
-+
-+	add	$ap,$j,%o3
-+	add	$bp,$i,%o4
-+
-+	ld	[%o3+4],%g1		! bp[0]
-+	ld	[%o3+0],%o0
-+	ld	[%o4+4],%g5		! ap[0]
-+	sllx	%g1,32,%g1
-+	ld	[%o4+0],%o1
-+	sllx	%g5,32,%g5
-+	or	%g1,%o0,%o0
-+	or	%g5,%o1,%o1
-+
-+	add	$np,$j,%o5
-+
-+	mulx	%o1,%o0,%o0		! ap[0]*bp[0]
-+	mulx	$n0,%o0,%o0		! ap[0]*bp[0]*n0
-+	stx	%o0,[%sp+$bias+$frame+0]
-+
-+	ld	[%o3+0],$alo_	! load a[j] as pair of 32-bit words
-+	fzeros	$alo
-+	ld	[%o3+4],$ahi_
-+	fzeros	$ahi
-+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
-+	fzeros	$nlo
-+	ld	[%o5+4],$nhi_
-+	fzeros	$nhi
-+
-+	! transfer b[i] to FPU as 4x16-bit values
-+	ldda	[%o4+2]%asi,$ba
-+	fxtod	$alo,$alo
-+	ldda	[%o4+0]%asi,$bb
-+	fxtod	$ahi,$ahi
-+	ldda	[%o4+6]%asi,$bc
-+	fxtod	$nlo,$nlo
-+	ldda	[%o4+4]%asi,$bd
-+	fxtod	$nhi,$nhi
-+
-+	! transfer ap[0]*b[0]*n0 to FPU as 4x16-bit values
-+	ldda	[%sp+$bias+$frame+6]%asi,$na
-+	fxtod	$ba,$ba
-+	ldda	[%sp+$bias+$frame+4]%asi,$nb
-+	fxtod	$bb,$bb
-+	ldda	[%sp+$bias+$frame+2]%asi,$nc
-+	fxtod	$bc,$bc
-+	ldda	[%sp+$bias+$frame+0]%asi,$nd
-+	fxtod	$bd,$bd
-+
-+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
-+	fxtod	$na,$na
-+	std	$ahi,[$ap_h+$j]
-+	fxtod	$nb,$nb
-+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
-+	fxtod	$nc,$nc
-+	std	$nhi,[$np_h+$j]
-+	fxtod	$nd,$nd
-+
-+		fmuld	$alo,$ba,$aloa
-+		fmuld	$nlo,$na,$nloa
-+		fmuld	$alo,$bb,$alob
-+		fmuld	$nlo,$nb,$nlob
-+		fmuld	$alo,$bc,$aloc
-+	faddd	$aloa,$nloa,$nloa
-+		fmuld	$nlo,$nc,$nloc
-+		fmuld	$alo,$bd,$alod
-+	faddd	$alob,$nlob,$nlob
-+		fmuld	$nlo,$nd,$nlod
-+		fmuld	$ahi,$ba,$ahia
-+	faddd	$aloc,$nloc,$nloc
-+		fmuld	$nhi,$na,$nhia
-+		fmuld	$ahi,$bb,$ahib
-+	faddd	$alod,$nlod,$nlod
-+		fmuld	$nhi,$nb,$nhib
-+		fmuld	$ahi,$bc,$ahic
-+	faddd	$ahia,$nhia,$nhia
-+		fmuld	$nhi,$nc,$nhic
-+		fmuld	$ahi,$bd,$ahid
-+	faddd	$ahib,$nhib,$nhib
-+		fmuld	$nhi,$nd,$nhid
-+
-+	faddd	$ahic,$nhic,$dota	! $nhic
-+	faddd	$ahid,$nhid,$dotb	! $nhid
-+
-+	faddd	$nloc,$nhia,$nloc
-+	faddd	$nlod,$nhib,$nlod
-+
-+	fdtox	$nloa,$nloa
-+	fdtox	$nlob,$nlob
-+	fdtox	$nloc,$nloc
-+	fdtox	$nlod,$nlod
-+
-+	std	$nloa,[%sp+$bias+$frame+0]
-+	add	$j,8,$j
-+	std	$nlob,[%sp+$bias+$frame+8]
-+	add	$ap,$j,%o4
-+	std	$nloc,[%sp+$bias+$frame+16]
-+	add	$np,$j,%o5
-+	std	$nlod,[%sp+$bias+$frame+24]
-+
-+	ld	[%o4+0],$alo_	! load a[j] as pair of 32-bit words
-+	fzeros	$alo
-+	ld	[%o4+4],$ahi_
-+	fzeros	$ahi
-+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
-+	fzeros	$nlo
-+	ld	[%o5+4],$nhi_
-+	fzeros	$nhi
-+
-+	fxtod	$alo,$alo
-+	fxtod	$ahi,$ahi
-+	fxtod	$nlo,$nlo
-+	fxtod	$nhi,$nhi
-+
-+	ldx	[%sp+$bias+$frame+0],%o0
-+		fmuld	$alo,$ba,$aloa
-+	ldx	[%sp+$bias+$frame+8],%o1
-+		fmuld	$nlo,$na,$nloa
-+	ldx	[%sp+$bias+$frame+16],%o2
-+		fmuld	$alo,$bb,$alob
-+	ldx	[%sp+$bias+$frame+24],%o3
-+		fmuld	$nlo,$nb,$nlob
-+
-+	srlx	%o0,16,%o7
-+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
-+		fmuld	$alo,$bc,$aloc
-+	add	%o7,%o1,%o1
-+	std	$ahi,[$ap_h+$j]
-+		faddd	$aloa,$nloa,$nloa
-+		fmuld	$nlo,$nc,$nloc
-+	srlx	%o1,16,%o7
-+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
-+		fmuld	$alo,$bd,$alod
-+	add	%o7,%o2,%o2
-+	std	$nhi,[$np_h+$j]
-+		faddd	$alob,$nlob,$nlob
-+		fmuld	$nlo,$nd,$nlod
-+	srlx	%o2,16,%o7
-+		fmuld	$ahi,$ba,$ahia
-+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
-+		faddd	$aloc,$nloc,$nloc
-+		fmuld	$nhi,$na,$nhia
-+	!and	%o0,$mask,%o0
-+	!and	%o1,$mask,%o1
-+	!and	%o2,$mask,%o2
-+	!sllx	%o1,16,%o1
-+	!sllx	%o2,32,%o2
-+	!sllx	%o3,48,%o7
-+	!or	%o1,%o0,%o0
-+	!or	%o2,%o0,%o0
-+	!or	%o7,%o0,%o0		! 64-bit result
-+	srlx	%o3,16,%g1		! 34-bit carry
-+		fmuld	$ahi,$bb,$ahib
-+
-+	faddd	$alod,$nlod,$nlod
-+		fmuld	$nhi,$nb,$nhib
-+		fmuld	$ahi,$bc,$ahic
-+	faddd	$ahia,$nhia,$nhia
-+		fmuld	$nhi,$nc,$nhic
-+		fmuld	$ahi,$bd,$ahid
-+	faddd	$ahib,$nhib,$nhib
-+		fmuld	$nhi,$nd,$nhid
-+
-+	faddd	$dota,$nloa,$nloa
-+	faddd	$dotb,$nlob,$nlob
-+	faddd	$ahic,$nhic,$dota	! $nhic
-+	faddd	$ahid,$nhid,$dotb	! $nhid
-+
-+	faddd	$nloc,$nhia,$nloc
-+	faddd	$nlod,$nhib,$nlod
-+
-+	fdtox	$nloa,$nloa
-+	fdtox	$nlob,$nlob
-+	fdtox	$nloc,$nloc
-+	fdtox	$nlod,$nlod
-+
-+	std	$nloa,[%sp+$bias+$frame+0]
-+	std	$nlob,[%sp+$bias+$frame+8]
-+	addcc	$j,8,$j
-+	std	$nloc,[%sp+$bias+$frame+16]
-+	bz,pn	%icc,.L1stskip
-+	std	$nlod,[%sp+$bias+$frame+24]
-+
-+.align	32			! incidentally already aligned !
-+.L1st:
-+	add	$ap,$j,%o4
-+	add	$np,$j,%o5
-+	ld	[%o4+0],$alo_	! load a[j] as pair of 32-bit words
-+	fzeros	$alo
-+	ld	[%o4+4],$ahi_
-+	fzeros	$ahi
-+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
-+	fzeros	$nlo
-+	ld	[%o5+4],$nhi_
-+	fzeros	$nhi
-+
-+	fxtod	$alo,$alo
-+	fxtod	$ahi,$ahi
-+	fxtod	$nlo,$nlo
-+	fxtod	$nhi,$nhi
-+
-+	ldx	[%sp+$bias+$frame+0],%o0
-+		fmuld	$alo,$ba,$aloa
-+	ldx	[%sp+$bias+$frame+8],%o1
-+		fmuld	$nlo,$na,$nloa
-+	ldx	[%sp+$bias+$frame+16],%o2
-+		fmuld	$alo,$bb,$alob
-+	ldx	[%sp+$bias+$frame+24],%o3
-+		fmuld	$nlo,$nb,$nlob
-+
-+	srlx	%o0,16,%o7
-+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
-+		fmuld	$alo,$bc,$aloc
-+	add	%o7,%o1,%o1
-+	std	$ahi,[$ap_h+$j]
-+		faddd	$aloa,$nloa,$nloa
-+		fmuld	$nlo,$nc,$nloc
-+	srlx	%o1,16,%o7
-+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
-+		fmuld	$alo,$bd,$alod
-+	add	%o7,%o2,%o2
-+	std	$nhi,[$np_h+$j]
-+		faddd	$alob,$nlob,$nlob
-+		fmuld	$nlo,$nd,$nlod
-+	srlx	%o2,16,%o7
-+		fmuld	$ahi,$ba,$ahia
-+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
-+	and	%o0,$mask,%o0
-+		faddd	$aloc,$nloc,$nloc
-+		fmuld	$nhi,$na,$nhia
-+	and	%o1,$mask,%o1
-+	and	%o2,$mask,%o2
-+		fmuld	$ahi,$bb,$ahib
-+	sllx	%o1,16,%o1
-+		faddd	$alod,$nlod,$nlod
-+		fmuld	$nhi,$nb,$nhib
-+	sllx	%o2,32,%o2
-+		fmuld	$ahi,$bc,$ahic
-+	sllx	%o3,48,%o7
-+	or	%o1,%o0,%o0
-+		faddd	$ahia,$nhia,$nhia
-+		fmuld	$nhi,$nc,$nhic
-+	or	%o2,%o0,%o0
-+		fmuld	$ahi,$bd,$ahid
-+	or	%o7,%o0,%o0		! 64-bit result
-+		faddd	$ahib,$nhib,$nhib
-+		fmuld	$nhi,$nd,$nhid
-+	addcc	%g1,%o0,%o0
-+		faddd	$dota,$nloa,$nloa
-+	srlx	%o3,16,%g1		! 34-bit carry
-+		faddd	$dotb,$nlob,$nlob
-+	bcs,a	%xcc,.+8
-+	add	%g1,1,%g1
-+
-+	stx	%o0,[$tp]		! tp[j-1]=
-+
-+	faddd	$ahic,$nhic,$dota	! $nhic
-+	faddd	$ahid,$nhid,$dotb	! $nhid
-+
-+	faddd	$nloc,$nhia,$nloc
-+	faddd	$nlod,$nhib,$nlod
-+
-+	fdtox	$nloa,$nloa
-+	fdtox	$nlob,$nlob
-+	fdtox	$nloc,$nloc
-+	fdtox	$nlod,$nlod
-+
-+	std	$nloa,[%sp+$bias+$frame+0]
-+	std	$nlob,[%sp+$bias+$frame+8]
-+	std	$nloc,[%sp+$bias+$frame+16]
-+	std	$nlod,[%sp+$bias+$frame+24]
-+
-+	addcc	$j,8,$j
-+	bnz,pt	%icc,.L1st
-+	add	$tp,8,$tp
-+
-+.L1stskip:
-+	fdtox	$dota,$dota
-+	fdtox	$dotb,$dotb
-+
-+	ldx	[%sp+$bias+$frame+0],%o0
-+	ldx	[%sp+$bias+$frame+8],%o1
-+	ldx	[%sp+$bias+$frame+16],%o2
-+	ldx	[%sp+$bias+$frame+24],%o3
-+
-+	srlx	%o0,16,%o7
-+	std	$dota,[%sp+$bias+$frame+32]
-+	add	%o7,%o1,%o1
-+	std	$dotb,[%sp+$bias+$frame+40]
-+	srlx	%o1,16,%o7
-+	add	%o7,%o2,%o2
-+	srlx	%o2,16,%o7
-+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
-+	and	%o0,$mask,%o0
-+	and	%o1,$mask,%o1
-+	and	%o2,$mask,%o2
-+	sllx	%o1,16,%o1
-+	sllx	%o2,32,%o2
-+	sllx	%o3,48,%o7
-+	or	%o1,%o0,%o0
-+	or	%o2,%o0,%o0
-+	or	%o7,%o0,%o0		! 64-bit result
-+	ldx	[%sp+$bias+$frame+32],%o4
-+	addcc	%g1,%o0,%o0
-+	ldx	[%sp+$bias+$frame+40],%o5
-+	srlx	%o3,16,%g1		! 34-bit carry
-+	bcs,a	%xcc,.+8
-+	add	%g1,1,%g1
-+
-+	stx	%o0,[$tp]		! tp[j-1]=
-+	add	$tp,8,$tp
-+
-+	srlx	%o4,16,%o7
-+	add	%o7,%o5,%o5
-+	and	%o4,$mask,%o4
-+	sllx	%o5,16,%o7
-+	or	%o7,%o4,%o4
-+	addcc	%g1,%o4,%o4
-+	srlx	%o5,48,%g1
-+	bcs,a	%xcc,.+8
-+	add	%g1,1,%g1
-+
-+	mov	%g1,$carry
-+	stx	%o4,[$tp]		! tp[num-1]=
-+
-+	ba	.Louter
-+	add	$i,8,$i
-+.align	32
-+.Louter:
-+	sub	%g0,$num,$j		! j=-num
-+	add	%sp,$bias+$frame+$locals,$tp
-+
-+	add	$ap,$j,%o3
-+	add	$bp,$i,%o4
-+
-+	ld	[%o3+4],%g1		! bp[i]
-+	ld	[%o3+0],%o0
-+	ld	[%o4+4],%g5		! ap[0]
-+	sllx	%g1,32,%g1
-+	ld	[%o4+0],%o1
-+	sllx	%g5,32,%g5
-+	or	%g1,%o0,%o0
-+	or	%g5,%o1,%o1
-+
-+	ldx	[$tp],%o2		! tp[0]
-+	mulx	%o1,%o0,%o0
-+	addcc	%o2,%o0,%o0
-+	mulx	$n0,%o0,%o0		! (ap[0]*bp[i]+t[0])*n0
-+	stx	%o0,[%sp+$bias+$frame+0]
-+
-+	! transfer b[i] to FPU as 4x16-bit values
-+	ldda	[%o4+2]%asi,$ba
-+	ldda	[%o4+0]%asi,$bb
-+	ldda	[%o4+6]%asi,$bc
-+	ldda	[%o4+4]%asi,$bd
-+
-+	! transfer (ap[0]*b[i]+t[0])*n0 to FPU as 4x16-bit values
-+	ldda	[%sp+$bias+$frame+6]%asi,$na
-+	fxtod	$ba,$ba
-+	ldda	[%sp+$bias+$frame+4]%asi,$nb
-+	fxtod	$bb,$bb
-+	ldda	[%sp+$bias+$frame+2]%asi,$nc
-+	fxtod	$bc,$bc
-+	ldda	[%sp+$bias+$frame+0]%asi,$nd
-+	fxtod	$bd,$bd
-+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
-+	fxtod	$na,$na
-+	ldd	[$ap_h+$j],$ahi
-+	fxtod	$nb,$nb
-+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
-+	fxtod	$nc,$nc
-+	ldd	[$np_h+$j],$nhi
-+	fxtod	$nd,$nd
-+
-+		fmuld	$alo,$ba,$aloa
-+		fmuld	$nlo,$na,$nloa
-+		fmuld	$alo,$bb,$alob
-+		fmuld	$nlo,$nb,$nlob
-+		fmuld	$alo,$bc,$aloc
-+	faddd	$aloa,$nloa,$nloa
-+		fmuld	$nlo,$nc,$nloc
-+		fmuld	$alo,$bd,$alod
-+	faddd	$alob,$nlob,$nlob
-+		fmuld	$nlo,$nd,$nlod
-+		fmuld	$ahi,$ba,$ahia
-+	faddd	$aloc,$nloc,$nloc
-+		fmuld	$nhi,$na,$nhia
-+		fmuld	$ahi,$bb,$ahib
-+	faddd	$alod,$nlod,$nlod
-+		fmuld	$nhi,$nb,$nhib
-+		fmuld	$ahi,$bc,$ahic
-+	faddd	$ahia,$nhia,$nhia
-+		fmuld	$nhi,$nc,$nhic
-+		fmuld	$ahi,$bd,$ahid
-+	faddd	$ahib,$nhib,$nhib
-+		fmuld	$nhi,$nd,$nhid
-+
-+	faddd	$ahic,$nhic,$dota	! $nhic
-+	faddd	$ahid,$nhid,$dotb	! $nhid
-+
-+	faddd	$nloc,$nhia,$nloc
-+	faddd	$nlod,$nhib,$nlod
-+
-+	fdtox	$nloa,$nloa
-+	fdtox	$nlob,$nlob
-+	fdtox	$nloc,$nloc
-+	fdtox	$nlod,$nlod
-+
-+	std	$nloa,[%sp+$bias+$frame+0]
-+	std	$nlob,[%sp+$bias+$frame+8]
-+	std	$nloc,[%sp+$bias+$frame+16]
-+	add	$j,8,$j
-+	std	$nlod,[%sp+$bias+$frame+24]
-+
-+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
-+	ldd	[$ap_h+$j],$ahi
-+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
-+	ldd	[$np_h+$j],$nhi
-+
-+		fmuld	$alo,$ba,$aloa
-+		fmuld	$nlo,$na,$nloa
-+		fmuld	$alo,$bb,$alob
-+		fmuld	$nlo,$nb,$nlob
-+		fmuld	$alo,$bc,$aloc
-+	ldx	[%sp+$bias+$frame+0],%o0
-+		faddd	$aloa,$nloa,$nloa
-+		fmuld	$nlo,$nc,$nloc
-+	ldx	[%sp+$bias+$frame+8],%o1
-+		fmuld	$alo,$bd,$alod
-+	ldx	[%sp+$bias+$frame+16],%o2
-+		faddd	$alob,$nlob,$nlob
-+		fmuld	$nlo,$nd,$nlod
-+	ldx	[%sp+$bias+$frame+24],%o3
-+		fmuld	$ahi,$ba,$ahia
-+
-+	srlx	%o0,16,%o7
-+		faddd	$aloc,$nloc,$nloc
-+		fmuld	$nhi,$na,$nhia
-+	add	%o7,%o1,%o1
-+		fmuld	$ahi,$bb,$ahib
-+	srlx	%o1,16,%o7
-+		faddd	$alod,$nlod,$nlod
-+		fmuld	$nhi,$nb,$nhib
-+	add	%o7,%o2,%o2
-+		fmuld	$ahi,$bc,$ahic
-+	srlx	%o2,16,%o7
-+		faddd	$ahia,$nhia,$nhia
-+		fmuld	$nhi,$nc,$nhic
-+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
-+	! why?
-+	and	%o0,$mask,%o0
-+		fmuld	$ahi,$bd,$ahid
-+	and	%o1,$mask,%o1
-+	and	%o2,$mask,%o2
-+		faddd	$ahib,$nhib,$nhib
-+		fmuld	$nhi,$nd,$nhid
-+	sllx	%o1,16,%o1
-+		faddd	$dota,$nloa,$nloa
-+	sllx	%o2,32,%o2
-+		faddd	$dotb,$nlob,$nlob
-+	sllx	%o3,48,%o7
-+	or	%o1,%o0,%o0
-+		faddd	$ahic,$nhic,$dota	! $nhic
-+	or	%o2,%o0,%o0
-+		faddd	$ahid,$nhid,$dotb	! $nhid
-+	or	%o7,%o0,%o0		! 64-bit result
-+	ldx	[$tp],%o7
-+		faddd	$nloc,$nhia,$nloc
-+	addcc	%o7,%o0,%o0
-+	! end-of-why?
-+		faddd	$nlod,$nhib,$nlod
-+	srlx	%o3,16,%g1		! 34-bit carry
-+		fdtox	$nloa,$nloa
-+	bcs,a	%xcc,.+8
-+	add	%g1,1,%g1
-+
-+	fdtox	$nlob,$nlob
-+	fdtox	$nloc,$nloc
-+	fdtox	$nlod,$nlod
-+
-+	std	$nloa,[%sp+$bias+$frame+0]
-+	std	$nlob,[%sp+$bias+$frame+8]
-+	addcc	$j,8,$j
-+	std	$nloc,[%sp+$bias+$frame+16]
-+	bz,pn	%icc,.Linnerskip
-+	std	$nlod,[%sp+$bias+$frame+24]
-+
-+	ba	.Linner
-+	nop
-+.align	32
-+.Linner:
-+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
-+	ldd	[$ap_h+$j],$ahi
-+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
-+	ldd	[$np_h+$j],$nhi
-+
-+		fmuld	$alo,$ba,$aloa
-+		fmuld	$nlo,$na,$nloa
-+		fmuld	$alo,$bb,$alob
-+		fmuld	$nlo,$nb,$nlob
-+		fmuld	$alo,$bc,$aloc
-+	ldx	[%sp+$bias+$frame+0],%o0
-+		faddd	$aloa,$nloa,$nloa
-+		fmuld	$nlo,$nc,$nloc
-+	ldx	[%sp+$bias+$frame+8],%o1
-+		fmuld	$alo,$bd,$alod
-+	ldx	[%sp+$bias+$frame+16],%o2
-+		faddd	$alob,$nlob,$nlob
-+		fmuld	$nlo,$nd,$nlod
-+	ldx	[%sp+$bias+$frame+24],%o3
-+		fmuld	$ahi,$ba,$ahia
-+
-+	srlx	%o0,16,%o7
-+		faddd	$aloc,$nloc,$nloc
-+		fmuld	$nhi,$na,$nhia
-+	add	%o7,%o1,%o1
-+		fmuld	$ahi,$bb,$ahib
-+	srlx	%o1,16,%o7
-+		faddd	$alod,$nlod,$nlod
-+		fmuld	$nhi,$nb,$nhib
-+	add	%o7,%o2,%o2
-+		fmuld	$ahi,$bc,$ahic
-+	srlx	%o2,16,%o7
-+		faddd	$ahia,$nhia,$nhia
-+		fmuld	$nhi,$nc,$nhic
-+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
-+	and	%o0,$mask,%o0
-+		fmuld	$ahi,$bd,$ahid
-+	and	%o1,$mask,%o1
-+	and	%o2,$mask,%o2
-+		faddd	$ahib,$nhib,$nhib
-+		fmuld	$nhi,$nd,$nhid
-+	sllx	%o1,16,%o1
-+		faddd	$dota,$nloa,$nloa
-+	sllx	%o2,32,%o2
-+		faddd	$dotb,$nlob,$nlob
-+	sllx	%o3,48,%o7
-+	or	%o1,%o0,%o0
-+		faddd	$ahic,$nhic,$dota	! $nhic
-+	or	%o2,%o0,%o0
-+		faddd	$ahid,$nhid,$dotb	! $nhid
-+	or	%o7,%o0,%o0		! 64-bit result
-+		faddd	$nloc,$nhia,$nloc
-+	addcc	%g1,%o0,%o0
-+	ldx	[$tp+8],%o7		! tp[j]
-+		faddd	$nlod,$nhib,$nlod
-+	srlx	%o3,16,%g1		! 34-bit carry
-+		fdtox	$nloa,$nloa
-+	bcs,a	%xcc,.+8
-+	add	%g1,1,%g1
-+		fdtox	$nlob,$nlob
-+	addcc	%o7,%o0,%o0
-+		fdtox	$nloc,$nloc
-+	bcs,a	%xcc,.+8
-+	add	%g1,1,%g1
-+
-+	stx	%o0,[$tp]		! tp[j-1]
-+		fdtox	$nlod,$nlod
-+
-+	std	$nloa,[%sp+$bias+$frame+0]
-+	std	$nlob,[%sp+$bias+$frame+8]
-+	std	$nloc,[%sp+$bias+$frame+16]
-+	addcc	$j,8,$j
-+	std	$nlod,[%sp+$bias+$frame+24]
-+	bnz,pt	%icc,.Linner
-+	add	$tp,8,$tp
-+
-+.Linnerskip:
-+	fdtox	$dota,$dota
-+	fdtox	$dotb,$dotb
-+
-+	ldx	[%sp+$bias+$frame+0],%o0
-+	ldx	[%sp+$bias+$frame+8],%o1
-+	ldx	[%sp+$bias+$frame+16],%o2
-+	ldx	[%sp+$bias+$frame+24],%o3
-+
-+	srlx	%o0,16,%o7
-+	std	$dota,[%sp+$bias+$frame+32]
-+	add	%o7,%o1,%o1
-+	std	$dotb,[%sp+$bias+$frame+40]
-+	srlx	%o1,16,%o7
-+	add	%o7,%o2,%o2
-+	srlx	%o2,16,%o7
-+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
-+	and	%o0,$mask,%o0
-+	and	%o1,$mask,%o1
-+	and	%o2,$mask,%o2
-+	sllx	%o1,16,%o1
-+	sllx	%o2,32,%o2
-+	sllx	%o3,48,%o7
-+	or	%o1,%o0,%o0
-+	or	%o2,%o0,%o0
-+	ldx	[%sp+$bias+$frame+32],%o4
-+	or	%o7,%o0,%o0		! 64-bit result
-+	ldx	[%sp+$bias+$frame+40],%o5
-+	addcc	%g1,%o0,%o0
-+	ldx	[$tp+8],%o7		! tp[j]
-+	srlx	%o3,16,%g1		! 34-bit carry
-+	bcs,a	%xcc,.+8
-+	add	%g1,1,%g1
-+
-+	addcc	%o7,%o0,%o0
-+	bcs,a	%xcc,.+8
-+	add	%g1,1,%g1
-+
-+	stx	%o0,[$tp]		! tp[j-1]
-+	add	$tp,8,$tp
-+
-+	srlx	%o4,16,%o7
-+	add	%o7,%o5,%o5
-+	and	%o4,$mask,%o4
-+	sllx	%o5,16,%o7
-+	or	%o7,%o4,%o4
-+	addcc	%g1,%o4,%o4
-+	srlx	%o5,48,%g1
-+	bcs,a	%xcc,.+8
-+	add	%g1,1,%g1
-+
-+	addcc	$carry,%o4,%o4
-+	stx	%o4,[$tp]		! tp[num-1]
-+	mov	%g1,$carry
-+	bcs,a	%xcc,.+8
-+	add	$carry,1,$carry
-+
-+	addcc	$i,8,$i
-+	bnz	%icc,.Louter
-+	nop
-+
-+	add	$tp,8,$tp		! adjust tp to point at the end
-+	orn	%g0,%g0,%g4
-+	sub	%g0,$num,%o7		! n=-num
-+	ba	.Lsub
-+	subcc	%g0,%g0,%g0		! clear %icc.c
-+
-+.align	32
-+.Lsub:
-+	ldx	[$tp+%o7],%o0
-+	add	$np,%o7,%g1
-+	ld	[%g1+0],%o2
-+	ld	[%g1+4],%o3
-+	srlx	%o0,32,%o1
-+	subccc	%o0,%o2,%o2
-+	add	$rp,%o7,%g1
-+	subccc	%o1,%o3,%o3
-+	st	%o2,[%g1+0]
-+	add	%o7,8,%o7
-+	brnz,pt	%o7,.Lsub
-+	st	%o3,[%g1+4]
-+	subc	$carry,0,%g4
-+	sub	%g0,$num,%o7		! n=-num
-+	ba	.Lcopy
-+	nop
-+
-+.align	32
-+.Lcopy:
-+	ldx	[$tp+%o7],%o0
-+	add	$rp,%o7,%g1
-+	ld	[%g1+0],%o2
-+	ld	[%g1+4],%o3
-+	stx	%g0,[$tp+%o7]
-+	and	%o0,%g4,%o0
-+	srlx	%o0,32,%o1
-+	andn	%o2,%g4,%o2
-+	andn	%o3,%g4,%o3
-+	or	%o2,%o0,%o0
-+	or	%o3,%o1,%o1
-+	st	%o0,[%g1+0]
-+	add	%o7,8,%o7
-+	brnz,pt	%o7,.Lcopy
-+	st	%o1,[%g1+4]
-+	sub	%g0,$num,%o7		! n=-num
-+
-+.Lzap:
-+	stx	%g0,[$ap_l+%o7]
-+	stx	%g0,[$ap_h+%o7]
-+	stx	%g0,[$np_l+%o7]
-+	stx	%g0,[$np_h+%o7]
-+	add	%o7,8,%o7
-+	brnz,pt	%o7,.Lzap
-+	nop
-+
-+	ldx	[%sp+$bias+$frame+48],%o7
-+	wr	%g0,%o7,%asi		! restore %asi
-+
-+	mov	1,%i0
-+.Lret:
-+	ret
-+	restore
-+.type   $fname,#function
-+.size	$fname,(.-$fname)
-+.asciz	"Montgomery Multipltication for UltraSPARC, CRYPTOGAMS by "
-+.align	32
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+
-+# Below substitution makes it possible to compile without demanding
-+# VIS extensions on command line, e.g. -xarch=v9 vs. -xarch=v9a. I
-+# dare to do this, because VIS capability is detected at run-time now
-+# and this routine is not called on CPU not capable to execute it. Do
-+# note that fzeros is not the only VIS dependency! Another dependency
-+# is implicit and is just _a_ numerical value loaded to %asi register,
-+# which assembler can't recognize as VIS specific...
-+$code =~ s/fzeros\s+%f([0-9]+)/
-+	   sprintf(".word\t0x%x\t! fzeros %%f%d",0x81b00c20|($1<<25),$1)
-+	  /gem;
-+
-+print $code;
-+# flush
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/via-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/via-mont.pl
-new file mode 100644
-index 0000000..9f81bc8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/via-mont.pl
-@@ -0,0 +1,254 @@
-+#! /usr/bin/env perl
-+# Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# Wrapper around 'rep montmul', VIA-specific instruction accessing
-+# PadLock Montgomery Multiplier. The wrapper is designed as drop-in
-+# replacement for OpenSSL bn_mul_mont [first implemented in 0.9.9].
-+#
-+# Below are interleaved outputs from 'openssl speed rsa dsa' for 4
-+# different software configurations on 1.5GHz VIA Esther processor.
-+# Lines marked with "software integer" denote performance of hand-
-+# coded integer-only assembler found in OpenSSL 0.9.7. "Software SSE2"
-+# refers to hand-coded SSE2 Montgomery multiplication procedure found
-+# OpenSSL 0.9.9. "Hardware VIA SDK" refers to padlock_pmm routine from
-+# Padlock SDK 2.0.1 available for download from VIA, which naturally
-+# utilizes the magic 'repz montmul' instruction. And finally "hardware
-+# this" refers to *this* implementation which also uses 'repz montmul'
-+#
-+#                   sign    verify    sign/s verify/s
-+# rsa  512 bits 0.001720s 0.000140s    581.4   7149.7	software integer
-+# rsa  512 bits 0.000690s 0.000086s   1450.3  11606.0	software SSE2
-+# rsa  512 bits 0.006136s 0.000201s    163.0   4974.5	hardware VIA SDK
-+# rsa  512 bits 0.000712s 0.000050s   1404.9  19858.5	hardware this
-+#
-+# rsa 1024 bits 0.008518s 0.000413s    117.4   2420.8	software integer
-+# rsa 1024 bits 0.004275s 0.000277s    233.9   3609.7	software SSE2
-+# rsa 1024 bits 0.012136s 0.000260s     82.4   3844.5	hardware VIA SDK
-+# rsa 1024 bits 0.002522s 0.000116s    396.5   8650.9	hardware this
-+#
-+# rsa 2048 bits 0.050101s 0.001371s     20.0    729.6	software integer
-+# rsa 2048 bits 0.030273s 0.001008s     33.0    991.9	software SSE2
-+# rsa 2048 bits 0.030833s 0.000976s     32.4   1025.1	hardware VIA SDK
-+# rsa 2048 bits 0.011879s 0.000342s     84.2   2921.7	hardware this
-+#
-+# rsa 4096 bits 0.327097s 0.004859s      3.1    205.8	software integer
-+# rsa 4096 bits 0.229318s 0.003859s      4.4    259.2	software SSE2
-+# rsa 4096 bits 0.233953s 0.003274s      4.3    305.4	hardware VIA SDK
-+# rsa 4096 bits 0.070493s 0.001166s     14.2    857.6	hardware this
-+#
-+# dsa  512 bits 0.001342s 0.001651s    745.2    605.7	software integer
-+# dsa  512 bits 0.000844s 0.000987s   1185.3   1013.1	software SSE2
-+# dsa  512 bits 0.001902s 0.002247s    525.6    444.9	hardware VIA SDK
-+# dsa  512 bits 0.000458s 0.000524s   2182.2   1909.1	hardware this
-+#
-+# dsa 1024 bits 0.003964s 0.004926s    252.3    203.0	software integer
-+# dsa 1024 bits 0.002686s 0.003166s    372.3    315.8	software SSE2
-+# dsa 1024 bits 0.002397s 0.002823s    417.1    354.3	hardware VIA SDK
-+# dsa 1024 bits 0.000978s 0.001170s   1022.2    855.0	hardware this
-+#
-+# dsa 2048 bits 0.013280s 0.016518s     75.3     60.5	software integer
-+# dsa 2048 bits 0.009911s 0.011522s    100.9     86.8	software SSE2
-+# dsa 2048 bits 0.009542s 0.011763s    104.8     85.0	hardware VIA SDK
-+# dsa 2048 bits 0.002884s 0.003352s    346.8    298.3	hardware this
-+#
-+# To give you some other reference point here is output for 2.4GHz P4
-+# running hand-coded SSE2 bn_mul_mont found in 0.9.9, i.e. "software
-+# SSE2" in above terms.
-+#
-+# rsa  512 bits 0.000407s 0.000047s   2454.2  21137.0
-+# rsa 1024 bits 0.002426s 0.000141s    412.1   7100.0
-+# rsa 2048 bits 0.015046s 0.000491s     66.5   2034.9
-+# rsa 4096 bits 0.109770s 0.002379s      9.1    420.3
-+# dsa  512 bits 0.000438s 0.000525s   2281.1   1904.1
-+# dsa 1024 bits 0.001346s 0.001595s    742.7    627.0
-+# dsa 2048 bits 0.004745s 0.005582s    210.7    179.1
-+#
-+# Conclusions: 
-+# - VIA SDK leaves a *lot* of room for improvement (which this
-+#   implementation successfully fills:-);
-+# - 'rep montmul' gives up to >3x performance improvement depending on
-+#   key length;
-+# - in terms of absolute performance it delivers approximately as much
-+#   as modern out-of-order 32-bit cores [again, for longer keys].
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"via-mont.pl");
-+
-+# int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
-+$func="bn_mul_mont_padlock";
-+
-+$pad=16*1;	# amount of reserved bytes on top of every vector
-+
-+# stack layout
-+$mZeroPrime=&DWP(0,"esp");		# these are specified by VIA
-+$A=&DWP(4,"esp");
-+$B=&DWP(8,"esp");
-+$T=&DWP(12,"esp");
-+$M=&DWP(16,"esp");
-+$scratch=&DWP(20,"esp");
-+$rp=&DWP(24,"esp");			# these are mine
-+$sp=&DWP(28,"esp");
-+# &DWP(32,"esp")			# 32 byte scratch area
-+# &DWP(64+(4*$num+$pad)*0,"esp")	# padded tp[num]
-+# &DWP(64+(4*$num+$pad)*1,"esp")	# padded copy of ap[num]
-+# &DWP(64+(4*$num+$pad)*2,"esp")	# padded copy of bp[num]
-+# &DWP(64+(4*$num+$pad)*3,"esp")	# padded copy of np[num]
-+# Note that SDK suggests to unconditionally allocate 2K per vector. This
-+# has quite an impact on performance. It naturally depends on key length,
-+# but to give an example 1024 bit private RSA key operations suffer >30%
-+# penalty. I allocate only as much as actually required...
-+
-+&function_begin($func);
-+	&xor	("eax","eax");
-+	&mov	("ecx",&wparam(5));	# num
-+	# meet VIA's limitations for num [note that the specification
-+	# expresses them in bits, while we work with amount of 32-bit words]
-+	&test	("ecx",3);
-+	&jnz	(&label("leave"));	# num % 4 != 0
-+	&cmp	("ecx",8);
-+	&jb	(&label("leave"));	# num < 8
-+	&cmp	("ecx",1024);
-+	&ja	(&label("leave"));	# num > 1024
-+
-+	&pushf	();
-+	&cld	();
-+
-+	&mov	("edi",&wparam(0));	# rp
-+	&mov	("eax",&wparam(1));	# ap
-+	&mov	("ebx",&wparam(2));	# bp
-+	&mov	("edx",&wparam(3));	# np
-+	&mov	("esi",&wparam(4));	# n0
-+	&mov	("esi",&DWP(0,"esi"));	# *n0
-+
-+	&lea	("ecx",&DWP($pad,"","ecx",4));	# ecx becomes vector size in bytes
-+	&lea	("ebp",&DWP(64,"","ecx",4));	# allocate 4 vectors + 64 bytes
-+	&neg	("ebp");
-+	&add	("ebp","esp");
-+	&and	("ebp",-64);		# align to cache-line
-+	&xchg	("ebp","esp");		# alloca
-+
-+	&mov	($rp,"edi");		# save rp
-+	&mov	($sp,"ebp");		# save esp
-+
-+	&mov	($mZeroPrime,"esi");
-+	&lea	("esi",&DWP(64,"esp"));	# tp
-+	&mov	($T,"esi");
-+	&lea	("edi",&DWP(32,"esp"));	# scratch area
-+	&mov	($scratch,"edi");
-+	&mov	("esi","eax");
-+
-+	&lea	("ebp",&DWP(-$pad,"ecx"));
-+	&shr	("ebp",2);		# restore original num value in ebp
-+
-+	&xor	("eax","eax");
-+
-+	&mov	("ecx","ebp");
-+	&lea	("ecx",&DWP((32+$pad)/4,"ecx"));# padded tp + scratch
-+	&data_byte(0xf3,0xab);		# rep stosl, bzero
-+
-+	&mov	("ecx","ebp");
-+	&lea	("edi",&DWP(64+$pad,"esp","ecx",4));# pointer to ap copy
-+	&mov	($A,"edi");
-+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
-+	&mov	("ecx",$pad/4);
-+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
-+	# edi points at the end of padded ap copy...
-+
-+	&mov	("ecx","ebp");
-+	&mov	("esi","ebx");
-+	&mov	($B,"edi");
-+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
-+	&mov	("ecx",$pad/4);
-+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
-+	# edi points at the end of padded bp copy...
-+
-+	&mov	("ecx","ebp");
-+	&mov	("esi","edx");
-+	&mov	($M,"edi");
-+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
-+	&mov	("ecx",$pad/4);
-+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
-+	# edi points at the end of padded np copy...
-+
-+	# let magic happen...
-+	&mov	("ecx","ebp");
-+	&mov	("esi","esp");
-+	&shl	("ecx",5);		# convert word counter to bit counter
-+	&align	(4);
-+	&data_byte(0xf3,0x0f,0xa6,0xc0);# rep montmul
-+
-+	&mov	("ecx","ebp");
-+	&lea	("esi",&DWP(64,"esp"));		# tp
-+	# edi still points at the end of padded np copy...
-+	&neg	("ebp");
-+	&lea	("ebp",&DWP(-$pad,"edi","ebp",4));	# so just "rewind"
-+	&mov	("edi",$rp);			# restore rp
-+	&xor	("edx","edx");			# i=0 and clear CF
-+
-+&set_label("sub",8);
-+	&mov	("eax",&DWP(0,"esi","edx",4));
-+	&sbb	("eax",&DWP(0,"ebp","edx",4));
-+	&mov	(&DWP(0,"edi","edx",4),"eax");	# rp[i]=tp[i]-np[i]
-+	&lea	("edx",&DWP(1,"edx"));		# i++
-+	&loop	(&label("sub"));		# doesn't affect CF!
-+
-+	&mov	("eax",&DWP(0,"esi","edx",4));	# upmost overflow bit
-+	&sbb	("eax",0);
-+	&and	("esi","eax");
-+	¬	("eax");
-+	&mov	("ebp","edi");
-+	&and	("ebp","eax");
-+	&or	("esi","ebp");			# tp=carry?tp:rp
-+
-+	&mov	("ecx","edx");			# num
-+	&xor	("edx","edx");			# i=0
-+
-+&set_label("copy",8);
-+	&mov	("eax",&DWP(0,"esi","edx",4));
-+	&mov	(&DWP(64,"esp","edx",4),"ecx");	# zap tp
-+	&mov	(&DWP(0,"edi","edx",4),"eax");
-+	&lea	("edx",&DWP(1,"edx"));		# i++
-+	&loop	(&label("copy"));
-+
-+	&mov	("ebp",$sp);
-+	&xor	("eax","eax");
-+
-+	&mov	("ecx",64/4);
-+	&mov	("edi","esp");		# zap frame including scratch area
-+	&data_byte(0xf3,0xab);		# rep stosl, bzero
-+
-+	# zap copies of ap, bp and np
-+	&lea	("edi",&DWP(64+$pad,"esp","edx",4));# pointer to ap
-+	&lea	("ecx",&DWP(3*$pad/4,"edx","edx",2));
-+	&data_byte(0xf3,0xab);		# rep stosl, bzero
-+
-+	&mov	("esp","ebp");
-+	&inc	("eax");		# signal "done"
-+	&popf	();
-+&set_label("leave");
-+&function_end($func);
-+
-+&asciz("Padlock Montgomery Multiplication, CRYPTOGAMS by ");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/vis3-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/vis3-mont.pl
-new file mode 100644
-index 0000000..64dba44
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/vis3-mont.pl
-@@ -0,0 +1,384 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# October 2012.
-+#
-+# SPARCv9 VIS3 Montgomery multiplicaion procedure suitable for T3 and
-+# onward. There are three new instructions used here: umulxhi,
-+# addxc[cc] and initializing store. On T3 RSA private key operations
-+# are 1.54/1.87/2.11/2.26 times faster for 512/1024/2048/4096-bit key
-+# lengths. This is without dedicated squaring procedure. On T4
-+# corresponding coefficients are 1.47/2.10/2.80/2.90x, which is mostly
-+# for reference purposes, because T4 has dedicated Montgomery
-+# multiplication and squaring *instructions* that deliver even more.
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+$frame = "STACK_FRAME";
-+$bias = "STACK_BIAS";
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#ifdef	__arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+#endif
-+
-+.section	".text",#alloc,#execinstr
-+___
-+
-+($n0,$m0,$m1,$lo0,$hi0, $lo1,$hi1,$aj,$alo,$nj,$nlo,$tj)=
-+	(map("%g$_",(1..5)),map("%o$_",(0..5,7)));
-+
-+# int bn_mul_mont(
-+$rp="%o0";	# BN_ULONG *rp,
-+$ap="%o1";	# const BN_ULONG *ap,
-+$bp="%o2";	# const BN_ULONG *bp,
-+$np="%o3";	# const BN_ULONG *np,
-+$n0p="%o4";	# const BN_ULONG *n0,
-+$num="%o5";	# int num);	# caller ensures that num is even
-+				# and >=6
-+$code.=<<___;
-+.globl	bn_mul_mont_vis3
-+.align	32
-+bn_mul_mont_vis3:
-+	add	%sp,	$bias,	%g4	! real top of stack
-+	sll	$num,	2,	$num	! size in bytes
-+	add	$num,	63,	%g5
-+	andn	%g5,	63,	%g5	! buffer size rounded up to 64 bytes
-+	add	%g5,	%g5,	%g1
-+	add	%g5,	%g1,	%g1	! 3*buffer size
-+	sub	%g4,	%g1,	%g1
-+	andn	%g1,	63,	%g1	! align at 64 byte
-+	sub	%g1,	$frame,	%g1	! new top of stack
-+	sub	%g1,	%g4,	%g1
-+
-+	save	%sp,	%g1,	%sp
-+___
-+
-+#	+-------------------------------+<-----	%sp
-+#	.				.
-+#	+-------------------------------+<-----	aligned at 64 bytes
-+#	| __int64 tmp[0]		|
-+#	+-------------------------------+
-+#	.				.
-+#	.				.
-+#	+-------------------------------+<----- aligned at 64 bytes
-+#	| __int64 ap[1..0]		|	converted ap[]
-+#	+-------------------------------+
-+#	| __int64 np[1..0]		|	converted np[]
-+#	+-------------------------------+
-+#	| __int64 ap[3..2]		|
-+#	.				.
-+#	.				.
-+#	+-------------------------------+
-+($rp,$ap,$bp,$np,$n0p,$num)=map("%i$_",(0..5));
-+($t0,$t1,$t2,$t3,$cnt,$tp,$bufsz,$anp)=map("%l$_",(0..7));
-+($ovf,$i)=($t0,$t1);
-+$code.=<<___;
-+	ld	[$n0p+0],	$t0	! pull n0[0..1] value
-+	add	%sp, $bias+$frame, $tp
-+	ld	[$n0p+4],	$t1
-+	add	$tp,	%g5,	$anp
-+	ld	[$bp+0],	$t2	! m0=bp[0]
-+	sllx	$t1,	32,	$n0
-+	ld	[$bp+4],	$t3
-+	or	$t0,	$n0,	$n0
-+	add	$bp,	8,	$bp
-+
-+	ld	[$ap+0],	$t0	! ap[0]
-+	sllx	$t3,	32,	$m0
-+	ld	[$ap+4],	$t1
-+	or	$t2,	$m0,	$m0
-+
-+	ld	[$ap+8],	$t2	! ap[1]
-+	sllx	$t1,	32,	$aj
-+	ld	[$ap+12],	$t3
-+	or	$t0,	$aj,	$aj
-+	add	$ap,	16,	$ap
-+	stx	$aj,	[$anp]		! converted ap[0]
-+
-+	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[0]
-+	umulxhi	$aj,	$m0,	$hi0
-+
-+	ld	[$np+0],	$t0	! np[0]
-+	sllx	$t3,	32,	$aj
-+	ld	[$np+4],	$t1
-+	or	$t2,	$aj,	$aj
-+
-+	ld	[$np+8],	$t2	! np[1]
-+	sllx	$t1,	32,	$nj
-+	ld	[$np+12],	$t3
-+	or	$t0, $nj,	$nj
-+	add	$np,	16,	$np
-+	stx	$nj,	[$anp+8]	! converted np[0]
-+
-+	mulx	$lo0,	$n0,	$m1	! "tp[0]"*n0
-+	stx	$aj,	[$anp+16]	! converted ap[1]
-+
-+	mulx	$aj,	$m0,	$alo	! ap[1]*bp[0]
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+
-+	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-+	umulxhi	$nj,	$m1,	$hi1
-+
-+	sllx	$t3,	32,	$nj
-+	or	$t2,	$nj,	$nj
-+	stx	$nj,	[$anp+24]	! converted np[1]
-+	add	$anp,	32,	$anp
-+
-+	addcc	$lo0,	$lo1,	$lo1
-+	addxc	%g0,	$hi1,	$hi1
-+
-+	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+
-+	ba	.L1st
-+	sub	$num,	24,	$cnt	! cnt=num-3
-+
-+.align	16
-+.L1st:
-+	ld	[$ap+0],	$t0	! ap[j]
-+	addcc	$alo,	$hi0,	$lo0
-+	ld	[$ap+4],	$t1
-+	addxc	$aj,	%g0,	$hi0
-+
-+	sllx	$t1,	32,	$aj
-+	add	$ap,	8,	$ap
-+	or	$t0,	$aj,	$aj
-+	stx	$aj,	[$anp]		! converted ap[j]
-+
-+	ld	[$np+0],	$t2	! np[j]
-+	addcc	$nlo,	$hi1,	$lo1
-+	ld	[$np+4],	$t3
-+	addxc	$nj,	%g0,	$hi1	! nhi=nj
-+
-+	sllx	$t3,	32,	$nj
-+	add	$np,	8,	$np
-+	mulx	$aj,	$m0,	$alo	! ap[j]*bp[0]
-+	or	$t2,	$nj,	$nj
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+	stx	$nj,	[$anp+8]	! converted np[j]
-+	add	$anp,	16,	$anp	! anp++
-+
-+	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-+	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+	addxc	%g0,	$hi1,	$hi1
-+	stx	$lo1,	[$tp]		! tp[j-1]
-+	add	$tp,	8,	$tp	! tp++
-+
-+	brnz,pt	$cnt,	.L1st
-+	sub	$cnt,	8,	$cnt	! j--
-+!.L1st
-+	addcc	$alo,	$hi0,	$lo0
-+	addxc	$aj,	%g0,	$hi0	! ahi=aj
-+
-+	addcc	$nlo,	$hi1,	$lo1
-+	addxc	$nj,	%g0,	$hi1
-+	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-+	addxc	%g0,	$hi1,	$hi1
-+	stx	$lo1,	[$tp]		! tp[j-1]
-+	add	$tp,	8,	$tp
-+
-+	addcc	$hi0,	$hi1,	$hi1
-+	addxc	%g0,	%g0,	$ovf	! upmost overflow bit
-+	stx	$hi1,	[$tp]
-+	add	$tp,	8,	$tp
-+
-+	ba	.Louter
-+	sub	$num,	16,	$i	! i=num-2
-+
-+.align	16
-+.Louter:
-+	ld	[$bp+0],	$t2	! m0=bp[i]
-+	ld	[$bp+4],	$t3
-+
-+	sub	$anp,	$num,	$anp	! rewind
-+	sub	$tp,	$num,	$tp
-+	sub	$anp,	$num,	$anp
-+
-+	add	$bp,	8,	$bp
-+	sllx	$t3,	32,	$m0
-+	ldx	[$anp+0],	$aj	! ap[0]
-+	or	$t2,	$m0,	$m0
-+	ldx	[$anp+8],	$nj	! np[0]
-+
-+	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[i]
-+	ldx	[$tp],		$tj	! tp[0]
-+	umulxhi	$aj,	$m0,	$hi0
-+	ldx	[$anp+16],	$aj	! ap[1]
-+	addcc	$lo0,	$tj,	$lo0	! ap[0]*bp[i]+tp[0]
-+	mulx	$aj,	$m0,	$alo	! ap[1]*bp[i]
-+	addxc	%g0,	$hi0,	$hi0
-+	mulx	$lo0,	$n0,	$m1	! tp[0]*n0
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-+	umulxhi	$nj,	$m1,	$hi1
-+	ldx	[$anp+24],	$nj	! np[1]
-+	add	$anp,	32,	$anp
-+	addcc	$lo1,	$lo0,	$lo1
-+	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-+	addxc	%g0,	$hi1,	$hi1
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+
-+	ba	.Linner
-+	sub	$num,	24,	$cnt	! cnt=num-3
-+.align	16
-+.Linner:
-+	addcc	$alo,	$hi0,	$lo0
-+	ldx	[$tp+8],	$tj	! tp[j]
-+	addxc	$aj,	%g0,	$hi0	! ahi=aj
-+	ldx	[$anp+0],	$aj	! ap[j]
-+	addcc	$nlo,	$hi1,	$lo1
-+	mulx	$aj,	$m0,	$alo	! ap[j]*bp[i]
-+	addxc	$nj,	%g0,	$hi1	! nhi=nj
-+	ldx	[$anp+8],	$nj	! np[j]
-+	add	$anp,	16,	$anp
-+	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-+	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-+	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-+	addxc	%g0,	$hi0,	$hi0
-+	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-+	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-+	addxc	%g0,	$hi1,	$hi1
-+	stx	$lo1,	[$tp]		! tp[j-1]
-+	add	$tp,	8,	$tp
-+	brnz,pt	$cnt,	.Linner
-+	sub	$cnt,	8,	$cnt
-+!.Linner
-+	ldx	[$tp+8],	$tj	! tp[j]
-+	addcc	$alo,	$hi0,	$lo0
-+	addxc	$aj,	%g0,	$hi0	! ahi=aj
-+	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-+	addxc	%g0,	$hi0,	$hi0
-+
-+	addcc	$nlo,	$hi1,	$lo1
-+	addxc	$nj,	%g0,	$hi1	! nhi=nj
-+	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-+	addxc	%g0,	$hi1,	$hi1
-+	stx	$lo1,	[$tp]		! tp[j-1]
-+
-+	subcc	%g0,	$ovf,	%g0	! move upmost overflow to CCR.xcc
-+	addxccc	$hi1,	$hi0,	$hi1
-+	addxc	%g0,	%g0,	$ovf
-+	stx	$hi1,	[$tp+8]
-+	add	$tp,	16,	$tp
-+
-+	brnz,pt	$i,	.Louter
-+	sub	$i,	8,	$i
-+
-+	sub	$anp,	$num,	$anp	! rewind
-+	sub	$tp,	$num,	$tp
-+	sub	$anp,	$num,	$anp
-+	ba	.Lsub
-+	subcc	$num,	8,	$cnt	! cnt=num-1 and clear CCR.xcc
-+
-+.align	16
-+.Lsub:
-+	ldx	[$tp],		$tj
-+	add	$tp,	8,	$tp
-+	ldx	[$anp+8],	$nj
-+	add	$anp,	16,	$anp
-+	subccc	$tj,	$nj,	$t2	! tp[j]-np[j]
-+	srlx	$tj,	32,	$tj
-+	srlx	$nj,	32,	$nj
-+	subccc	$tj,	$nj,	$t3
-+	add	$rp,	8,	$rp
-+	st	$t2,	[$rp-4]		! reverse order
-+	st	$t3,	[$rp-8]
-+	brnz,pt	$cnt,	.Lsub
-+	sub	$cnt,	8,	$cnt
-+
-+	sub	$anp,	$num,	$anp	! rewind
-+	sub	$tp,	$num,	$tp
-+	sub	$anp,	$num,	$anp
-+	sub	$rp,	$num,	$rp
-+
-+	subc	$ovf,	%g0,	$ovf	! handle upmost overflow bit
-+	and	$tp,	$ovf,	$ap
-+	andn	$rp,	$ovf,	$np
-+	or	$np,	$ap,	$ap	! ap=borrow?tp:rp
-+	ba	.Lcopy
-+	sub	$num,	8,	$cnt
-+
-+.align	16
-+.Lcopy:					! copy or in-place refresh
-+	ld	[$ap+0],	$t2
-+	ld	[$ap+4],	$t3
-+	add	$ap,	8,	$ap
-+	stx	%g0,	[$tp]		! zap
-+	add	$tp,	8,	$tp
-+	stx	%g0,	[$anp]		! zap
-+	stx	%g0,	[$anp+8]
-+	add	$anp,	16,	$anp
-+	st	$t3,	[$rp+0]		! flip order
-+	st	$t2,	[$rp+4]
-+	add	$rp,	8,	$rp
-+	brnz	$cnt,	.Lcopy
-+	sub	$cnt,	8,	$cnt
-+
-+	mov	1,	%o0
-+	ret
-+	restore
-+.type	bn_mul_mont_vis3, #function
-+.size	bn_mul_mont_vis3, .-bn_mul_mont_vis3
-+.asciz  "Montgomery Multiplication for SPARCv9 VIS3, CRYPTOGAMS by "
-+.align	4
-+___
-+
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis3 {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my ($ref,$opf);
-+my %visopf = (	"addxc"		=> 0x011,
-+		"addxccc"	=> 0x013,
-+		"umulxhi"	=> 0x016	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%([goli])([0-9])/);
-+	    $_=$bias{$1}+$2;
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	s/\b(umulxhi|addxc[c]{0,2})\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+		&unvis3($1,$2,$3,$4)
-+	 /ge;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86-gf2m.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86-gf2m.pl
-new file mode 100644
-index 0000000..f464368
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86-gf2m.pl
-@@ -0,0 +1,325 @@
-+#! /usr/bin/env perl
-+# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# May 2011
-+#
-+# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
-+# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
-+# the time being... Except that it has three code paths: pure integer
-+# code suitable for any x86 CPU, MMX code suitable for PIII and later
-+# and PCLMULQDQ suitable for Westmere and later. Improvement varies
-+# from one benchmark and µ-arch to another. Below are interval values
-+# for 163- and 571-bit ECDH benchmarks relative to compiler-generated
-+# code:
-+#
-+# PIII		16%-30%
-+# P4		12%-12%
-+# Opteron	18%-40%
-+# Core2		19%-44%
-+# Atom		38%-64%
-+# Westmere	53%-121%(PCLMULQDQ)/20%-32%(MMX)
-+# Sandy Bridge	72%-127%(PCLMULQDQ)/27%-23%(MMX)
-+#
-+# Note that above improvement coefficients are not coefficients for
-+# bn_GF2m_mul_2x2 itself. For example 120% ECDH improvement is result
-+# of bn_GF2m_mul_2x2 being >4x faster. As it gets faster, benchmark
-+# is more and more dominated by other subroutines, most notably by
-+# BN_GF2m_mod[_mul]_arr...
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],$0,$x86only = $ARGV[$#ARGV] eq "386");
-+
-+$sse2=0;
-+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-+
-+&external_label("OPENSSL_ia32cap_P") if ($sse2);
-+
-+$a="eax";
-+$b="ebx";
-+($a1,$a2,$a4)=("ecx","edx","ebp");
-+
-+$R="mm0";
-+@T=("mm1","mm2");
-+($A,$B,$B30,$B31)=("mm2","mm3","mm4","mm5");
-+@i=("esi","edi");
-+
-+					if (!$x86only) {
-+&function_begin_B("_mul_1x1_mmx");
-+	&sub	("esp",32+4);
-+	 &mov	($a1,$a);
-+	 &lea	($a2,&DWP(0,$a,$a));
-+	 &and	($a1,0x3fffffff);
-+	 &lea	($a4,&DWP(0,$a2,$a2));
-+	 &mov	(&DWP(0*4,"esp"),0);
-+	 &and	($a2,0x7fffffff);
-+	&movd	($A,$a);
-+	&movd	($B,$b);
-+	 &mov	(&DWP(1*4,"esp"),$a1);	# a1
-+	 &xor	($a1,$a2);		# a1^a2
-+	&pxor	($B31,$B31);
-+	&pxor	($B30,$B30);
-+	 &mov	(&DWP(2*4,"esp"),$a2);	# a2
-+	 &xor	($a2,$a4);		# a2^a4
-+	 &mov	(&DWP(3*4,"esp"),$a1);	# a1^a2
-+	&pcmpgtd($B31,$A);		# broadcast 31st bit
-+	&paddd	($A,$A);		# $A<<=1
-+	 &xor	($a1,$a2);		# a1^a4=a1^a2^a2^a4
-+	 &mov	(&DWP(4*4,"esp"),$a4);	# a4
-+	 &xor	($a4,$a2);		# a2=a4^a2^a4
-+	&pand	($B31,$B);
-+	&pcmpgtd($B30,$A);		# broadcast 30th bit
-+	 &mov	(&DWP(5*4,"esp"),$a1);	# a1^a4
-+	 &xor	($a4,$a1);		# a1^a2^a4
-+	&psllq	($B31,31);
-+	&pand	($B30,$B);
-+	 &mov	(&DWP(6*4,"esp"),$a2);	# a2^a4
-+	&mov	(@i[0],0x7);
-+	 &mov	(&DWP(7*4,"esp"),$a4);	# a1^a2^a4
-+	 &mov	($a4,@i[0]);
-+	&and	(@i[0],$b);
-+	&shr	($b,3);
-+	&mov	(@i[1],$a4);
-+	&psllq	($B30,30);
-+	&and	(@i[1],$b);
-+	&shr	($b,3);
-+	&movd	($R,&DWP(0,"esp",@i[0],4));
-+	&mov	(@i[0],$a4);
-+	&and	(@i[0],$b);
-+	&shr	($b,3);
-+	for($n=1;$n<9;$n++) {
-+		&movd	(@T[1],&DWP(0,"esp",@i[1],4));
-+		&mov	(@i[1],$a4);
-+		&psllq	(@T[1],3*$n);
-+		&and	(@i[1],$b);
-+		&shr	($b,3);
-+		&pxor	($R,@T[1]);
-+
-+		push(@i,shift(@i)); push(@T,shift(@T));
-+	}
-+	&movd	(@T[1],&DWP(0,"esp",@i[1],4));
-+	&pxor	($R,$B30);
-+	&psllq	(@T[1],3*$n++);
-+	&pxor	($R,@T[1]);
-+
-+	&movd	(@T[0],&DWP(0,"esp",@i[0],4));
-+	&pxor	($R,$B31);
-+	&psllq	(@T[0],3*$n);
-+	&add	("esp",32+4);
-+	&pxor	($R,@T[0]);
-+	&ret	();
-+&function_end_B("_mul_1x1_mmx");
-+					}
-+
-+($lo,$hi)=("eax","edx");
-+@T=("ecx","ebp");
-+
-+&function_begin_B("_mul_1x1_ialu");
-+	&sub	("esp",32+4);
-+	 &mov	($a1,$a);
-+	 &lea	($a2,&DWP(0,$a,$a));
-+	 &lea	($a4,&DWP(0,"",$a,4));
-+	 &and	($a1,0x3fffffff);
-+	&lea	(@i[1],&DWP(0,$lo,$lo));
-+	&sar	($lo,31);		# broadcast 31st bit
-+	 &mov	(&DWP(0*4,"esp"),0);
-+	 &and	($a2,0x7fffffff);
-+	 &mov	(&DWP(1*4,"esp"),$a1);	# a1
-+	 &xor	($a1,$a2);		# a1^a2
-+	 &mov	(&DWP(2*4,"esp"),$a2);	# a2
-+	 &xor	($a2,$a4);		# a2^a4
-+	 &mov	(&DWP(3*4,"esp"),$a1);	# a1^a2
-+	 &xor	($a1,$a2);		# a1^a4=a1^a2^a2^a4
-+	 &mov	(&DWP(4*4,"esp"),$a4);	# a4
-+	 &xor	($a4,$a2);		# a2=a4^a2^a4
-+	 &mov	(&DWP(5*4,"esp"),$a1);	# a1^a4
-+	 &xor	($a4,$a1);		# a1^a2^a4
-+	&sar	(@i[1],31);		# broardcast 30th bit
-+	&and	($lo,$b);
-+	 &mov	(&DWP(6*4,"esp"),$a2);	# a2^a4
-+	&and	(@i[1],$b);
-+	 &mov	(&DWP(7*4,"esp"),$a4);	# a1^a2^a4
-+	&mov	($hi,$lo);
-+	&shl	($lo,31);
-+	&mov	(@T[0],@i[1]);
-+	&shr	($hi,1);
-+
-+	 &mov	(@i[0],0x7);
-+	&shl	(@i[1],30);
-+	 &and	(@i[0],$b);
-+	&shr	(@T[0],2);
-+	&xor	($lo,@i[1]);
-+
-+	&shr	($b,3);
-+	&mov	(@i[1],0x7);		# 5-byte instruction!?
-+	&and	(@i[1],$b);
-+	&shr	($b,3);
-+	 &xor	($hi,@T[0]);
-+	&xor	($lo,&DWP(0,"esp",@i[0],4));
-+	&mov	(@i[0],0x7);
-+	&and	(@i[0],$b);
-+	&shr	($b,3);
-+	for($n=1;$n<9;$n++) {
-+		&mov	(@T[1],&DWP(0,"esp",@i[1],4));
-+		&mov	(@i[1],0x7);
-+		&mov	(@T[0],@T[1]);
-+		&shl	(@T[1],3*$n);
-+		&and	(@i[1],$b);
-+		&shr	(@T[0],32-3*$n);
-+		&xor	($lo,@T[1]);
-+		&shr	($b,3);
-+		&xor	($hi,@T[0]);
-+
-+		push(@i,shift(@i)); push(@T,shift(@T));
-+	}
-+	&mov	(@T[1],&DWP(0,"esp",@i[1],4));
-+	&mov	(@T[0],@T[1]);
-+	&shl	(@T[1],3*$n);
-+	&mov	(@i[1],&DWP(0,"esp",@i[0],4));
-+	&shr	(@T[0],32-3*$n);	$n++;
-+	&mov	(@i[0],@i[1]);
-+	&xor	($lo,@T[1]);
-+	&shl	(@i[1],3*$n);
-+	&xor	($hi,@T[0]);
-+	&shr	(@i[0],32-3*$n);
-+	&xor	($lo,@i[1]);
-+	&xor	($hi,@i[0]);
-+
-+	&add	("esp",32+4);
-+	&ret	();
-+&function_end_B("_mul_1x1_ialu");
-+
-+# void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, BN_ULONG b0);
-+&function_begin_B("bn_GF2m_mul_2x2");
-+if (!$x86only) {
-+	&picmeup("edx","OPENSSL_ia32cap_P");
-+	&mov	("eax",&DWP(0,"edx"));
-+	&mov	("edx",&DWP(4,"edx"));
-+	&test	("eax",1<<23);		# check MMX bit
-+	&jz	(&label("ialu"));
-+if ($sse2) {
-+	&test	("eax",1<<24);		# check FXSR bit
-+	&jz	(&label("mmx"));
-+	&test	("edx",1<<1);		# check PCLMULQDQ bit
-+	&jz	(&label("mmx"));
-+
-+	&movups		("xmm0",&QWP(8,"esp"));
-+	&shufps		("xmm0","xmm0",0b10110001);
-+	&pclmulqdq	("xmm0","xmm0",1);
-+	&mov		("eax",&DWP(4,"esp"));
-+	&movups		(&QWP(0,"eax"),"xmm0");
-+	&ret	();
-+
-+&set_label("mmx",16);
-+}
-+	&push	("ebp");
-+	&push	("ebx");
-+	&push	("esi");
-+	&push	("edi");
-+	&mov	($a,&wparam(1));
-+	&mov	($b,&wparam(3));
-+	&call	("_mul_1x1_mmx");	# a1·b1
-+	&movq	("mm7",$R);
-+
-+	&mov	($a,&wparam(2));
-+	&mov	($b,&wparam(4));
-+	&call	("_mul_1x1_mmx");	# a0·b0
-+	&movq	("mm6",$R);
-+
-+	&mov	($a,&wparam(1));
-+	&mov	($b,&wparam(3));
-+	&xor	($a,&wparam(2));
-+	&xor	($b,&wparam(4));
-+	&call	("_mul_1x1_mmx");	# (a0+a1)·(b0+b1)
-+	&pxor	($R,"mm7");
-+	&mov	($a,&wparam(0));
-+	&pxor	($R,"mm6");		# (a0+a1)·(b0+b1)-a1·b1-a0·b0
-+
-+	&movq	($A,$R);
-+	&psllq	($R,32);
-+	&pop	("edi");
-+	&psrlq	($A,32);
-+	&pop	("esi");
-+	&pxor	($R,"mm6");
-+	&pop	("ebx");
-+	&pxor	($A,"mm7");
-+	&movq	(&QWP(0,$a),$R);
-+	&pop	("ebp");
-+	&movq	(&QWP(8,$a),$A);
-+	&emms	();
-+	&ret	();
-+&set_label("ialu",16);
-+}
-+	&push	("ebp");
-+	&push	("ebx");
-+	&push	("esi");
-+	&push	("edi");
-+	&stack_push(4+1);
-+
-+	&mov	($a,&wparam(1));
-+	&mov	($b,&wparam(3));
-+	&call	("_mul_1x1_ialu");	# a1·b1
-+	&mov	(&DWP(8,"esp"),$lo);
-+	&mov	(&DWP(12,"esp"),$hi);
-+
-+	&mov	($a,&wparam(2));
-+	&mov	($b,&wparam(4));
-+	&call	("_mul_1x1_ialu");	# a0·b0
-+	&mov	(&DWP(0,"esp"),$lo);
-+	&mov	(&DWP(4,"esp"),$hi);
-+
-+	&mov	($a,&wparam(1));
-+	&mov	($b,&wparam(3));
-+	&xor	($a,&wparam(2));
-+	&xor	($b,&wparam(4));
-+	&call	("_mul_1x1_ialu");	# (a0+a1)·(b0+b1)
-+
-+	&mov	("ebp",&wparam(0));
-+		 @r=("ebx","ecx","edi","esi");
-+	&mov	(@r[0],&DWP(0,"esp"));
-+	&mov	(@r[1],&DWP(4,"esp"));
-+	&mov	(@r[2],&DWP(8,"esp"));
-+	&mov	(@r[3],&DWP(12,"esp"));
-+
-+	&xor	($lo,$hi);
-+	&xor	($hi,@r[1]);
-+	&xor	($lo,@r[0]);
-+	&mov	(&DWP(0,"ebp"),@r[0]);
-+	&xor	($hi,@r[2]);
-+	&mov	(&DWP(12,"ebp"),@r[3]);
-+	&xor	($lo,@r[3]);
-+	&stack_pop(4+1);
-+	&xor	($hi,@r[3]);
-+	&pop	("edi");
-+	&xor	($lo,$hi);
-+	&pop	("esi");
-+	&mov	(&DWP(8,"ebp"),$hi);
-+	&pop	("ebx");
-+	&mov	(&DWP(4,"ebp"),$lo);
-+	&pop	("ebp");
-+	&ret	();
-+&function_end_B("bn_GF2m_mul_2x2");
-+
-+&asciz	("GF(2^m) Multiplication for x86, CRYPTOGAMS by ");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86-mont.pl
-new file mode 100755
-index 0000000..6787503
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86-mont.pl
-@@ -0,0 +1,629 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# October 2005
-+#
-+# This is a "teaser" code, as it can be improved in several ways...
-+# First of all non-SSE2 path should be implemented (yes, for now it
-+# performs Montgomery multiplication/convolution only on SSE2-capable
-+# CPUs such as P4, others fall down to original code). Then inner loop
-+# can be unrolled and modulo-scheduled to improve ILP and possibly
-+# moved to 128-bit XMM register bank (though it would require input
-+# rearrangement and/or increase bus bandwidth utilization). Dedicated
-+# squaring procedure should give further performance improvement...
-+# Yet, for being draft, the code improves rsa512 *sign* benchmark by
-+# 110%(!), rsa1024 one - by 70% and rsa4096 - by 20%:-)
-+
-+# December 2006
-+#
-+# Modulo-scheduling SSE2 loops results in further 15-20% improvement.
-+# Integer-only code [being equipped with dedicated squaring procedure]
-+# gives ~40% on rsa512 sign benchmark...
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output = pop;
-+open STDOUT,">$output";
-+ 
-+&asm_init($ARGV[0],$0);
-+
-+$sse2=0;
-+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-+
-+&external_label("OPENSSL_ia32cap_P") if ($sse2);
-+
-+&function_begin("bn_mul_mont");
-+
-+$i="edx";
-+$j="ecx";
-+$ap="esi";	$tp="esi";		# overlapping variables!!!
-+$rp="edi";	$bp="edi";		# overlapping variables!!!
-+$np="ebp";
-+$num="ebx";
-+
-+$_num=&DWP(4*0,"esp");			# stack top layout
-+$_rp=&DWP(4*1,"esp");
-+$_ap=&DWP(4*2,"esp");
-+$_bp=&DWP(4*3,"esp");
-+$_np=&DWP(4*4,"esp");
-+$_n0=&DWP(4*5,"esp");	$_n0q=&QWP(4*5,"esp");
-+$_sp=&DWP(4*6,"esp");
-+$_bpend=&DWP(4*7,"esp");
-+$frame=32;				# size of above frame rounded up to 16n
-+
-+	&xor	("eax","eax");
-+	&mov	("edi",&wparam(5));	# int num
-+	&cmp	("edi",4);
-+	&jl	(&label("just_leave"));
-+
-+	&lea	("esi",&wparam(0));	# put aside pointer to argument block
-+	&lea	("edx",&wparam(1));	# load ap
-+	&add	("edi",2);		# extra two words on top of tp
-+	&neg	("edi");
-+	&lea	("ebp",&DWP(-$frame,"esp","edi",4));	# future alloca($frame+4*(num+2))
-+	&neg	("edi");
-+
-+	# minimize cache contention by arraning 2K window between stack
-+	# pointer and ap argument [np is also position sensitive vector,
-+	# but it's assumed to be near ap, as it's allocated at ~same
-+	# time].
-+	&mov	("eax","ebp");
-+	&sub	("eax","edx");
-+	&and	("eax",2047);
-+	&sub	("ebp","eax");		# this aligns sp and ap modulo 2048
-+
-+	&xor	("edx","ebp");
-+	&and	("edx",2048);
-+	&xor	("edx",2048);
-+	&sub	("ebp","edx");		# this splits them apart modulo 4096
-+
-+	&and	("ebp",-64);		# align to cache line
-+
-+	# An OS-agnostic version of __chkstk.
-+	#
-+	# Some OSes (Windows) insist on stack being "wired" to
-+	# physical memory in strictly sequential manner, i.e. if stack
-+	# allocation spans two pages, then reference to farmost one can
-+	# be punishable by SEGV. But page walking can do good even on
-+	# other OSes, because it guarantees that villain thread hits
-+	# the guard page before it can make damage to innocent one...
-+	&mov	("eax","esp");
-+	&sub	("eax","ebp");
-+	&and	("eax",-4096);
-+	&mov	("edx","esp");		# saved stack pointer!
-+	&lea	("esp",&DWP(0,"ebp","eax"));
-+	&mov	("eax",&DWP(0,"esp"));
-+	&cmp	("esp","ebp");
-+	&ja	(&label("page_walk"));
-+	&jmp	(&label("page_walk_done"));
-+
-+&set_label("page_walk",16);
-+	&lea	("esp",&DWP(-4096,"esp"));
-+	&mov	("eax",&DWP(0,"esp"));
-+	&cmp	("esp","ebp");
-+	&ja	(&label("page_walk"));
-+&set_label("page_walk_done");
-+
-+	################################# load argument block...
-+	&mov	("eax",&DWP(0*4,"esi"));# BN_ULONG *rp
-+	&mov	("ebx",&DWP(1*4,"esi"));# const BN_ULONG *ap
-+	&mov	("ecx",&DWP(2*4,"esi"));# const BN_ULONG *bp
-+	&mov	("ebp",&DWP(3*4,"esi"));# const BN_ULONG *np
-+	&mov	("esi",&DWP(4*4,"esi"));# const BN_ULONG *n0
-+	#&mov	("edi",&DWP(5*4,"esi"));# int num
-+
-+	&mov	("esi",&DWP(0,"esi"));	# pull n0[0]
-+	&mov	($_rp,"eax");		# ... save a copy of argument block
-+	&mov	($_ap,"ebx");
-+	&mov	($_bp,"ecx");
-+	&mov	($_np,"ebp");
-+	&mov	($_n0,"esi");
-+	&lea	($num,&DWP(-3,"edi"));	# num=num-1 to assist modulo-scheduling
-+	#&mov	($_num,$num);		# redundant as $num is not reused
-+	&mov	($_sp,"edx");		# saved stack pointer!
-+
-+if($sse2) {
-+$acc0="mm0";	# mmx register bank layout
-+$acc1="mm1";
-+$car0="mm2";
-+$car1="mm3";
-+$mul0="mm4";
-+$mul1="mm5";
-+$temp="mm6";
-+$mask="mm7";
-+
-+	&picmeup("eax","OPENSSL_ia32cap_P");
-+	&bt	(&DWP(0,"eax"),26);
-+	&jnc	(&label("non_sse2"));
-+
-+	&mov	("eax",-1);
-+	&movd	($mask,"eax");		# mask 32 lower bits
-+
-+	&mov	($ap,$_ap);		# load input pointers
-+	&mov	($bp,$_bp);
-+	&mov	($np,$_np);
-+
-+	&xor	($i,$i);		# i=0
-+	&xor	($j,$j);		# j=0
-+
-+	&movd	($mul0,&DWP(0,$bp));		# bp[0]
-+	&movd	($mul1,&DWP(0,$ap));		# ap[0]
-+	&movd	($car1,&DWP(0,$np));		# np[0]
-+
-+	&pmuludq($mul1,$mul0);			# ap[0]*bp[0]
-+	&movq	($car0,$mul1);
-+	&movq	($acc0,$mul1);			# I wish movd worked for
-+	&pand	($acc0,$mask);			# inter-register transfers
-+
-+	&pmuludq($mul1,$_n0q);			# *=n0
-+
-+	&pmuludq($car1,$mul1);			# "t[0]"*np[0]*n0
-+	&paddq	($car1,$acc0);
-+
-+	&movd	($acc1,&DWP(4,$np));		# np[1]
-+	&movd	($acc0,&DWP(4,$ap));		# ap[1]
-+
-+	&psrlq	($car0,32);
-+	&psrlq	($car1,32);
-+
-+	&inc	($j);				# j++
-+&set_label("1st",16);
-+	&pmuludq($acc0,$mul0);			# ap[j]*bp[0]
-+	&pmuludq($acc1,$mul1);			# np[j]*m1
-+	&paddq	($car0,$acc0);			# +=c0
-+	&paddq	($car1,$acc1);			# +=c1
-+
-+	&movq	($acc0,$car0);
-+	&pand	($acc0,$mask);
-+	&movd	($acc1,&DWP(4,$np,$j,4));	# np[j+1]
-+	&paddq	($car1,$acc0);			# +=ap[j]*bp[0];
-+	&movd	($acc0,&DWP(4,$ap,$j,4));	# ap[j+1]
-+	&psrlq	($car0,32);
-+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[j-1]=
-+	&psrlq	($car1,32);
-+
-+	&lea	($j,&DWP(1,$j));
-+	&cmp	($j,$num);
-+	&jl	(&label("1st"));
-+
-+	&pmuludq($acc0,$mul0);			# ap[num-1]*bp[0]
-+	&pmuludq($acc1,$mul1);			# np[num-1]*m1
-+	&paddq	($car0,$acc0);			# +=c0
-+	&paddq	($car1,$acc1);			# +=c1
-+
-+	&movq	($acc0,$car0);
-+	&pand	($acc0,$mask);
-+	&paddq	($car1,$acc0);			# +=ap[num-1]*bp[0];
-+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[num-2]=
-+
-+	&psrlq	($car0,32);
-+	&psrlq	($car1,32);
-+
-+	&paddq	($car1,$car0);
-+	&movq	(&QWP($frame,"esp",$num,4),$car1);	# tp[num].tp[num-1]
-+
-+	&inc	($i);				# i++
-+&set_label("outer");
-+	&xor	($j,$j);			# j=0
-+
-+	&movd	($mul0,&DWP(0,$bp,$i,4));	# bp[i]
-+	&movd	($mul1,&DWP(0,$ap));		# ap[0]
-+	&movd	($temp,&DWP($frame,"esp"));	# tp[0]
-+	&movd	($car1,&DWP(0,$np));		# np[0]
-+	&pmuludq($mul1,$mul0);			# ap[0]*bp[i]
-+
-+	&paddq	($mul1,$temp);			# +=tp[0]
-+	&movq	($acc0,$mul1);
-+	&movq	($car0,$mul1);
-+	&pand	($acc0,$mask);
-+
-+	&pmuludq($mul1,$_n0q);			# *=n0
-+
-+	&pmuludq($car1,$mul1);
-+	&paddq	($car1,$acc0);
-+
-+	&movd	($temp,&DWP($frame+4,"esp"));	# tp[1]
-+	&movd	($acc1,&DWP(4,$np));		# np[1]
-+	&movd	($acc0,&DWP(4,$ap));		# ap[1]
-+
-+	&psrlq	($car0,32);
-+	&psrlq	($car1,32);
-+	&paddq	($car0,$temp);			# +=tp[1]
-+
-+	&inc	($j);				# j++
-+	&dec	($num);
-+&set_label("inner");
-+	&pmuludq($acc0,$mul0);			# ap[j]*bp[i]
-+	&pmuludq($acc1,$mul1);			# np[j]*m1
-+	&paddq	($car0,$acc0);			# +=c0
-+	&paddq	($car1,$acc1);			# +=c1
-+
-+	&movq	($acc0,$car0);
-+	&movd	($temp,&DWP($frame+4,"esp",$j,4));# tp[j+1]
-+	&pand	($acc0,$mask);
-+	&movd	($acc1,&DWP(4,$np,$j,4));	# np[j+1]
-+	&paddq	($car1,$acc0);			# +=ap[j]*bp[i]+tp[j]
-+	&movd	($acc0,&DWP(4,$ap,$j,4));	# ap[j+1]
-+	&psrlq	($car0,32);
-+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);# tp[j-1]=
-+	&psrlq	($car1,32);
-+	&paddq	($car0,$temp);			# +=tp[j+1]
-+
-+	&dec	($num);
-+	&lea	($j,&DWP(1,$j));		# j++
-+	&jnz	(&label("inner"));
-+
-+	&mov	($num,$j);
-+	&pmuludq($acc0,$mul0);			# ap[num-1]*bp[i]
-+	&pmuludq($acc1,$mul1);			# np[num-1]*m1
-+	&paddq	($car0,$acc0);			# +=c0
-+	&paddq	($car1,$acc1);			# +=c1
-+
-+	&movq	($acc0,$car0);
-+	&pand	($acc0,$mask);
-+	&paddq	($car1,$acc0);			# +=ap[num-1]*bp[i]+tp[num-1]
-+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[num-2]=
-+	&psrlq	($car0,32);
-+	&psrlq	($car1,32);
-+
-+	&movd	($temp,&DWP($frame+4,"esp",$num,4));	# += tp[num]
-+	&paddq	($car1,$car0);
-+	&paddq	($car1,$temp);
-+	&movq	(&QWP($frame,"esp",$num,4),$car1);	# tp[num].tp[num-1]
-+
-+	&lea	($i,&DWP(1,$i));		# i++
-+	&cmp	($i,$num);
-+	&jle	(&label("outer"));
-+
-+	&emms	();				# done with mmx bank
-+	&jmp	(&label("common_tail"));
-+
-+&set_label("non_sse2",16);
-+}
-+
-+if (0) {
-+	&mov	("esp",$_sp);
-+	&xor	("eax","eax");	# signal "not fast enough [yet]"
-+	&jmp	(&label("just_leave"));
-+	# While the below code provides competitive performance for
-+	# all key lengths on modern Intel cores, it's still more
-+	# than 10% slower for 4096-bit key elsewhere:-( "Competitive"
-+	# means compared to the original integer-only assembler.
-+	# 512-bit RSA sign is better by ~40%, but that's about all
-+	# one can say about all CPUs...
-+} else {
-+$inp="esi";	# integer path uses these registers differently
-+$word="edi";
-+$carry="ebp";
-+
-+	&mov	($inp,$_ap);
-+	&lea	($carry,&DWP(1,$num));
-+	&mov	($word,$_bp);
-+	&xor	($j,$j);				# j=0
-+	&mov	("edx",$inp);
-+	&and	($carry,1);				# see if num is even
-+	&sub	("edx",$word);				# see if ap==bp
-+	&lea	("eax",&DWP(4,$word,$num,4));		# &bp[num]
-+	&or	($carry,"edx");
-+	&mov	($word,&DWP(0,$word));			# bp[0]
-+	&jz	(&label("bn_sqr_mont"));
-+	&mov	($_bpend,"eax");
-+	&mov	("eax",&DWP(0,$inp));
-+	&xor	("edx","edx");
-+
-+&set_label("mull",16);
-+	&mov	($carry,"edx");
-+	&mul	($word);				# ap[j]*bp[0]
-+	&add	($carry,"eax");
-+	&lea	($j,&DWP(1,$j));
-+	&adc	("edx",0);
-+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j+1]
-+	&cmp	($j,$num);
-+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
-+	&jl	(&label("mull"));
-+
-+	&mov	($carry,"edx");
-+	&mul	($word);				# ap[num-1]*bp[0]
-+	 &mov	($word,$_n0);
-+	&add	("eax",$carry);
-+	 &mov	($inp,$_np);
-+	&adc	("edx",0);
-+	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
-+
-+	&mov	(&DWP($frame,"esp",$num,4),"eax");	# tp[num-1]=
-+	&xor	($j,$j);
-+	&mov	(&DWP($frame+4,"esp",$num,4),"edx");	# tp[num]=
-+	&mov	(&DWP($frame+8,"esp",$num,4),$j);	# tp[num+1]=
-+
-+	&mov	("eax",&DWP(0,$inp));			# np[0]
-+	&mul	($word);				# np[0]*m
-+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
-+	&mov	("eax",&DWP(4,$inp));			# np[1]
-+	&adc	("edx",0);
-+	&inc	($j);
-+
-+	&jmp	(&label("2ndmadd"));
-+
-+&set_label("1stmadd",16);
-+	&mov	($carry,"edx");
-+	&mul	($word);				# ap[j]*bp[i]
-+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
-+	&lea	($j,&DWP(1,$j));
-+	&adc	("edx",0);
-+	&add	($carry,"eax");
-+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j+1]
-+	&adc	("edx",0);
-+	&cmp	($j,$num);
-+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
-+	&jl	(&label("1stmadd"));
-+
-+	&mov	($carry,"edx");
-+	&mul	($word);				# ap[num-1]*bp[i]
-+	&add	("eax",&DWP($frame,"esp",$num,4));	# +=tp[num-1]
-+	 &mov	($word,$_n0);
-+	&adc	("edx",0);
-+	 &mov	($inp,$_np);
-+	&add	($carry,"eax");
-+	&adc	("edx",0);
-+	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
-+
-+	&xor	($j,$j);
-+	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
-+	&mov	(&DWP($frame,"esp",$num,4),$carry);	# tp[num-1]=
-+	&adc	($j,0);
-+	 &mov	("eax",&DWP(0,$inp));			# np[0]
-+	&mov	(&DWP($frame+4,"esp",$num,4),"edx");	# tp[num]=
-+	&mov	(&DWP($frame+8,"esp",$num,4),$j);	# tp[num+1]=
-+
-+	&mul	($word);				# np[0]*m
-+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
-+	&mov	("eax",&DWP(4,$inp));			# np[1]
-+	&adc	("edx",0);
-+	&mov	($j,1);
-+
-+&set_label("2ndmadd",16);
-+	&mov	($carry,"edx");
-+	&mul	($word);				# np[j]*m
-+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
-+	&lea	($j,&DWP(1,$j));
-+	&adc	("edx",0);
-+	&add	($carry,"eax");
-+	&mov	("eax",&DWP(0,$inp,$j,4));		# np[j+1]
-+	&adc	("edx",0);
-+	&cmp	($j,$num);
-+	&mov	(&DWP($frame-8,"esp",$j,4),$carry);	# tp[j-1]=
-+	&jl	(&label("2ndmadd"));
-+
-+	&mov	($carry,"edx");
-+	&mul	($word);				# np[j]*m
-+	&add	($carry,&DWP($frame,"esp",$num,4));	# +=tp[num-1]
-+	&adc	("edx",0);
-+	&add	($carry,"eax");
-+	&adc	("edx",0);
-+	&mov	(&DWP($frame-4,"esp",$num,4),$carry);	# tp[num-2]=
-+
-+	&xor	("eax","eax");
-+	 &mov	($j,$_bp);				# &bp[i]
-+	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
-+	&adc	("eax",&DWP($frame+8,"esp",$num,4));	# +=tp[num+1]
-+	 &lea	($j,&DWP(4,$j));
-+	&mov	(&DWP($frame,"esp",$num,4),"edx");	# tp[num-1]=
-+	 &cmp	($j,$_bpend);
-+	&mov	(&DWP($frame+4,"esp",$num,4),"eax");	# tp[num]=
-+	&je	(&label("common_tail"));
-+
-+	&mov	($word,&DWP(0,$j));			# bp[i+1]
-+	&mov	($inp,$_ap);
-+	&mov	($_bp,$j);				# &bp[++i]
-+	&xor	($j,$j);
-+	&xor	("edx","edx");
-+	&mov	("eax",&DWP(0,$inp));
-+	&jmp	(&label("1stmadd"));
-+
-+&set_label("bn_sqr_mont",16);
-+$sbit=$num;
-+	&mov	($_num,$num);
-+	&mov	($_bp,$j);				# i=0
-+
-+	&mov	("eax",$word);				# ap[0]
-+	&mul	($word);				# ap[0]*ap[0]
-+	&mov	(&DWP($frame,"esp"),"eax");		# tp[0]=
-+	&mov	($sbit,"edx");
-+	&shr	("edx",1);
-+	&and	($sbit,1);
-+	&inc	($j);
-+&set_label("sqr",16);
-+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j]
-+	&mov	($carry,"edx");
-+	&mul	($word);				# ap[j]*ap[0]
-+	&add	("eax",$carry);
-+	&lea	($j,&DWP(1,$j));
-+	&adc	("edx",0);
-+	&lea	($carry,&DWP(0,$sbit,"eax",2));
-+	&shr	("eax",31);
-+	&cmp	($j,$_num);
-+	&mov	($sbit,"eax");
-+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
-+	&jl	(&label("sqr"));
-+
-+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[num-1]
-+	&mov	($carry,"edx");
-+	&mul	($word);				# ap[num-1]*ap[0]
-+	&add	("eax",$carry);
-+	 &mov	($word,$_n0);
-+	&adc	("edx",0);
-+	 &mov	($inp,$_np);
-+	&lea	($carry,&DWP(0,$sbit,"eax",2));
-+	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
-+	&shr	("eax",31);
-+	&mov	(&DWP($frame,"esp",$j,4),$carry);	# tp[num-1]=
-+
-+	&lea	($carry,&DWP(0,"eax","edx",2));
-+	 &mov	("eax",&DWP(0,$inp));			# np[0]
-+	&shr	("edx",31);
-+	&mov	(&DWP($frame+4,"esp",$j,4),$carry);	# tp[num]=
-+	&mov	(&DWP($frame+8,"esp",$j,4),"edx");	# tp[num+1]=
-+
-+	&mul	($word);				# np[0]*m
-+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
-+	&mov	($num,$j);
-+	&adc	("edx",0);
-+	&mov	("eax",&DWP(4,$inp));			# np[1]
-+	&mov	($j,1);
-+
-+&set_label("3rdmadd",16);
-+	&mov	($carry,"edx");
-+	&mul	($word);				# np[j]*m
-+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
-+	&adc	("edx",0);
-+	&add	($carry,"eax");
-+	&mov	("eax",&DWP(4,$inp,$j,4));		# np[j+1]
-+	&adc	("edx",0);
-+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j-1]=
-+
-+	&mov	($carry,"edx");
-+	&mul	($word);				# np[j+1]*m
-+	&add	($carry,&DWP($frame+4,"esp",$j,4));	# +=tp[j+1]
-+	&lea	($j,&DWP(2,$j));
-+	&adc	("edx",0);
-+	&add	($carry,"eax");
-+	&mov	("eax",&DWP(0,$inp,$j,4));		# np[j+2]
-+	&adc	("edx",0);
-+	&cmp	($j,$num);
-+	&mov	(&DWP($frame-8,"esp",$j,4),$carry);	# tp[j]=
-+	&jl	(&label("3rdmadd"));
-+
-+	&mov	($carry,"edx");
-+	&mul	($word);				# np[j]*m
-+	&add	($carry,&DWP($frame,"esp",$num,4));	# +=tp[num-1]
-+	&adc	("edx",0);
-+	&add	($carry,"eax");
-+	&adc	("edx",0);
-+	&mov	(&DWP($frame-4,"esp",$num,4),$carry);	# tp[num-2]=
-+
-+	&mov	($j,$_bp);				# i
-+	&xor	("eax","eax");
-+	&mov	($inp,$_ap);
-+	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
-+	&adc	("eax",&DWP($frame+8,"esp",$num,4));	# +=tp[num+1]
-+	&mov	(&DWP($frame,"esp",$num,4),"edx");	# tp[num-1]=
-+	&cmp	($j,$num);
-+	&mov	(&DWP($frame+4,"esp",$num,4),"eax");	# tp[num]=
-+	&je	(&label("common_tail"));
-+
-+	&mov	($word,&DWP(4,$inp,$j,4));		# ap[i]
-+	&lea	($j,&DWP(1,$j));
-+	&mov	("eax",$word);
-+	&mov	($_bp,$j);				# ++i
-+	&mul	($word);				# ap[i]*ap[i]
-+	&add	("eax",&DWP($frame,"esp",$j,4));	# +=tp[i]
-+	&adc	("edx",0);
-+	&mov	(&DWP($frame,"esp",$j,4),"eax");	# tp[i]=
-+	&xor	($carry,$carry);
-+	&cmp	($j,$num);
-+	&lea	($j,&DWP(1,$j));
-+	&je	(&label("sqrlast"));
-+
-+	&mov	($sbit,"edx");				# zaps $num
-+	&shr	("edx",1);
-+	&and	($sbit,1);
-+&set_label("sqradd",16);
-+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j]
-+	&mov	($carry,"edx");
-+	&mul	($word);				# ap[j]*ap[i]
-+	&add	("eax",$carry);
-+	&lea	($carry,&DWP(0,"eax","eax"));
-+	&adc	("edx",0);
-+	&shr	("eax",31);
-+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
-+	&lea	($j,&DWP(1,$j));
-+	&adc	("eax",0);
-+	&add	($carry,$sbit);
-+	&adc	("eax",0);
-+	&cmp	($j,$_num);
-+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
-+	&mov	($sbit,"eax");
-+	&jle	(&label("sqradd"));
-+
-+	&mov	($carry,"edx");
-+	&add	("edx","edx");
-+	&shr	($carry,31);
-+	&add	("edx",$sbit);
-+	&adc	($carry,0);
-+&set_label("sqrlast");
-+	&mov	($word,$_n0);
-+	&mov	($inp,$_np);
-+	&imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
-+
-+	&add	("edx",&DWP($frame,"esp",$j,4));	# +=tp[num]
-+	&mov	("eax",&DWP(0,$inp));			# np[0]
-+	&adc	($carry,0);
-+	&mov	(&DWP($frame,"esp",$j,4),"edx");	# tp[num]=
-+	&mov	(&DWP($frame+4,"esp",$j,4),$carry);	# tp[num+1]=
-+
-+	&mul	($word);				# np[0]*m
-+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
-+	&lea	($num,&DWP(-1,$j));
-+	&adc	("edx",0);
-+	&mov	($j,1);
-+	&mov	("eax",&DWP(4,$inp));			# np[1]
-+
-+	&jmp	(&label("3rdmadd"));
-+}
-+
-+&set_label("common_tail",16);
-+	&mov	($np,$_np);			# load modulus pointer
-+	&mov	($rp,$_rp);			# load result pointer
-+	&lea	($tp,&DWP($frame,"esp"));	# [$ap and $bp are zapped]
-+
-+	&mov	("eax",&DWP(0,$tp));		# tp[0]
-+	&mov	($j,$num);			# j=num-1
-+	&xor	($i,$i);			# i=0 and clear CF!
-+
-+&set_label("sub",16);
-+	&sbb	("eax",&DWP(0,$np,$i,4));
-+	&mov	(&DWP(0,$rp,$i,4),"eax");	# rp[i]=tp[i]-np[i]
-+	&dec	($j);				# doesn't affect CF!
-+	&mov	("eax",&DWP(4,$tp,$i,4));	# tp[i+1]
-+	&lea	($i,&DWP(1,$i));		# i++
-+	&jge	(&label("sub"));
-+
-+	&sbb	("eax",0);			# handle upmost overflow bit
-+	&and	($tp,"eax");
-+	¬	("eax");
-+	&mov	($np,$rp);
-+	&and	($np,"eax");
-+	&or	($tp,$np);			# tp=carry?tp:rp
-+
-+&set_label("copy",16);				# copy or in-place refresh
-+	&mov	("eax",&DWP(0,$tp,$num,4));
-+	&mov	(&DWP(0,$rp,$num,4),"eax");	# rp[i]=tp[i]
-+	&mov	(&DWP($frame,"esp",$num,4),$j);	# zap temporary vector
-+	&dec	($num);
-+	&jge	(&label("copy"));
-+
-+	&mov	("esp",$_sp);		# pull saved stack pointer
-+	&mov	("eax",1);
-+&set_label("just_leave");
-+&function_end("bn_mul_mont");
-+
-+&asciz("Montgomery Multiplication for x86, CRYPTOGAMS by ");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86.pl
-new file mode 100644
-index 0000000..d57571d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86.pl
-@@ -0,0 +1,38 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+push(@INC,"perlasm","../../perlasm");
-+require "x86asm.pl";
-+
-+require("x86/mul_add.pl");
-+require("x86/mul.pl");
-+require("x86/sqr.pl");
-+require("x86/div.pl");
-+require("x86/add.pl");
-+require("x86/sub.pl");
-+require("x86/comba.pl");
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],$0);
-+
-+&bn_mul_add_words("bn_mul_add_words");
-+&bn_mul_words("bn_mul_words");
-+&bn_sqr_words("bn_sqr_words");
-+&bn_div_words("bn_div_words");
-+&bn_add_words("bn_add_words");
-+&bn_sub_words("bn_sub_words");
-+&bn_mul_comba("bn_mul_comba8",8);
-+&bn_mul_comba("bn_mul_comba4",4);
-+&bn_sqr_comba("bn_sqr_comba8",8);
-+&bn_sqr_comba("bn_sqr_comba4",4);
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-gcc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-gcc.c
-new file mode 100644
-index 0000000..4f19abe
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-gcc.c
-@@ -0,0 +1,647 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "../bn_lcl.h"
-+#if !(defined(__GNUC__) && __GNUC__>=2)
-+# include "../bn_asm.c"         /* kind of dirty hack for Sun Studio */
-+#else
-+/*-
-+ * x86_64 BIGNUM accelerator version 0.1, December 2002.
-+ *
-+ * Implemented by Andy Polyakov  for the OpenSSL
-+ * project.
-+ *
-+ * Rights for redistribution and usage in source and binary forms are
-+ * granted according to the OpenSSL license. Warranty of any kind is
-+ * disclaimed.
-+ *
-+ * Q. Version 0.1? It doesn't sound like Andy, he used to assign real
-+ *    versions, like 1.0...
-+ * A. Well, that's because this code is basically a quick-n-dirty
-+ *    proof-of-concept hack. As you can see it's implemented with
-+ *    inline assembler, which means that you're bound to GCC and that
-+ *    there might be enough room for further improvement.
-+ *
-+ * Q. Why inline assembler?
-+ * A. x86_64 features own ABI which I'm not familiar with. This is
-+ *    why I decided to let the compiler take care of subroutine
-+ *    prologue/epilogue as well as register allocation. For reference.
-+ *    Win64 implements different ABI for AMD64, different from Linux.
-+ *
-+ * Q. How much faster does it get?
-+ * A. 'apps/openssl speed rsa dsa' output with no-asm:
-+ *
-+ *                        sign    verify    sign/s verify/s
-+ *      rsa  512 bits   0.0006s   0.0001s   1683.8  18456.2
-+ *      rsa 1024 bits   0.0028s   0.0002s    356.0   6407.0
-+ *      rsa 2048 bits   0.0172s   0.0005s     58.0   1957.8
-+ *      rsa 4096 bits   0.1155s   0.0018s      8.7    555.6
-+ *                        sign    verify    sign/s verify/s
-+ *      dsa  512 bits   0.0005s   0.0006s   2100.8   1768.3
-+ *      dsa 1024 bits   0.0014s   0.0018s    692.3    559.2
-+ *      dsa 2048 bits   0.0049s   0.0061s    204.7    165.0
-+ *
-+ *    'apps/openssl speed rsa dsa' output with this module:
-+ *
-+ *                        sign    verify    sign/s verify/s
-+ *      rsa  512 bits   0.0004s   0.0000s   2767.1  33297.9
-+ *      rsa 1024 bits   0.0012s   0.0001s    867.4  14674.7
-+ *      rsa 2048 bits   0.0061s   0.0002s    164.0   5270.0
-+ *      rsa 4096 bits   0.0384s   0.0006s     26.1   1650.8
-+ *                        sign    verify    sign/s verify/s
-+ *      dsa  512 bits   0.0002s   0.0003s   4442.2   3786.3
-+ *      dsa 1024 bits   0.0005s   0.0007s   1835.1   1497.4
-+ *      dsa 2048 bits   0.0016s   0.0020s    620.4    504.6
-+ *
-+ *    For the reference. IA-32 assembler implementation performs
-+ *    very much like 64-bit code compiled with no-asm on the same
-+ *    machine.
-+ */
-+
-+# if defined(_WIN64) || !defined(__LP64__)
-+#  define BN_ULONG unsigned long long
-+# else
-+#  define BN_ULONG unsigned long
-+# endif
-+
-+# undef mul
-+# undef mul_add
-+
-+/*-
-+ * "m"(a), "+m"(r)      is the way to favor DirectPath µ-code;
-+ * "g"(0)               let the compiler to decide where does it
-+ *                      want to keep the value of zero;
-+ */
-+# define mul_add(r,a,word,carry) do {   \
-+        register BN_ULONG high,low;     \
-+        asm ("mulq %3"                  \
-+                : "=a"(low),"=d"(high)  \
-+                : "a"(word),"m"(a)      \
-+                : "cc");                \
-+        asm ("addq %2,%0; adcq %3,%1"   \
-+                : "+r"(carry),"+d"(high)\
-+                : "a"(low),"g"(0)       \
-+                : "cc");                \
-+        asm ("addq %2,%0; adcq %3,%1"   \
-+                : "+m"(r),"+d"(high)    \
-+                : "r"(carry),"g"(0)     \
-+                : "cc");                \
-+        carry=high;                     \
-+        } while (0)
-+
-+# define mul(r,a,word,carry) do {       \
-+        register BN_ULONG high,low;     \
-+        asm ("mulq %3"                  \
-+                : "=a"(low),"=d"(high)  \
-+                : "a"(word),"g"(a)      \
-+                : "cc");                \
-+        asm ("addq %2,%0; adcq %3,%1"   \
-+                : "+r"(carry),"+d"(high)\
-+                : "a"(low),"g"(0)       \
-+                : "cc");                \
-+        (r)=carry, carry=high;          \
-+        } while (0)
-+# undef sqr
-+# define sqr(r0,r1,a)                   \
-+        asm ("mulq %2"                  \
-+                : "=a"(r0),"=d"(r1)     \
-+                : "a"(a)                \
-+                : "cc");
-+
-+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
-+                          BN_ULONG w)
-+{
-+    BN_ULONG c1 = 0;
-+
-+    if (num <= 0)
-+        return (c1);
-+
-+    while (num & ~3) {
-+        mul_add(rp[0], ap[0], w, c1);
-+        mul_add(rp[1], ap[1], w, c1);
-+        mul_add(rp[2], ap[2], w, c1);
-+        mul_add(rp[3], ap[3], w, c1);
-+        ap += 4;
-+        rp += 4;
-+        num -= 4;
-+    }
-+    if (num) {
-+        mul_add(rp[0], ap[0], w, c1);
-+        if (--num == 0)
-+            return c1;
-+        mul_add(rp[1], ap[1], w, c1);
-+        if (--num == 0)
-+            return c1;
-+        mul_add(rp[2], ap[2], w, c1);
-+        return c1;
-+    }
-+
-+    return (c1);
-+}
-+
-+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
-+{
-+    BN_ULONG c1 = 0;
-+
-+    if (num <= 0)
-+        return (c1);
-+
-+    while (num & ~3) {
-+        mul(rp[0], ap[0], w, c1);
-+        mul(rp[1], ap[1], w, c1);
-+        mul(rp[2], ap[2], w, c1);
-+        mul(rp[3], ap[3], w, c1);
-+        ap += 4;
-+        rp += 4;
-+        num -= 4;
-+    }
-+    if (num) {
-+        mul(rp[0], ap[0], w, c1);
-+        if (--num == 0)
-+            return c1;
-+        mul(rp[1], ap[1], w, c1);
-+        if (--num == 0)
-+            return c1;
-+        mul(rp[2], ap[2], w, c1);
-+    }
-+    return (c1);
-+}
-+
-+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
-+{
-+    if (n <= 0)
-+        return;
-+
-+    while (n & ~3) {
-+        sqr(r[0], r[1], a[0]);
-+        sqr(r[2], r[3], a[1]);
-+        sqr(r[4], r[5], a[2]);
-+        sqr(r[6], r[7], a[3]);
-+        a += 4;
-+        r += 8;
-+        n -= 4;
-+    }
-+    if (n) {
-+        sqr(r[0], r[1], a[0]);
-+        if (--n == 0)
-+            return;
-+        sqr(r[2], r[3], a[1]);
-+        if (--n == 0)
-+            return;
-+        sqr(r[4], r[5], a[2]);
-+    }
-+}
-+
-+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
-+{
-+    BN_ULONG ret, waste;
-+
-+ asm("divq      %4":"=a"(ret), "=d"(waste)
-+ :     "a"(l), "d"(h), "r"(d)
-+ :     "cc");
-+
-+    return ret;
-+}
-+
-+BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                      int n)
-+{
-+    BN_ULONG ret;
-+    size_t i = 0;
-+
-+    if (n <= 0)
-+        return 0;
-+
-+    asm volatile ("       subq    %0,%0           \n" /* clear carry */
-+                  "       jmp     1f              \n"
-+                  ".p2align 4                     \n"
-+                  "1:     movq    (%4,%2,8),%0    \n"
-+                  "       adcq    (%5,%2,8),%0    \n"
-+                  "       movq    %0,(%3,%2,8)    \n"
-+                  "       lea     1(%2),%2        \n"
-+                  "       loop    1b              \n"
-+                  "       sbbq    %0,%0           \n":"=&r" (ret), "+c"(n),
-+                  "+r"(i)
-+                  :"r"(rp), "r"(ap), "r"(bp)
-+                  :"cc", "memory");
-+
-+    return ret & 1;
-+}
-+
-+# ifndef SIMICS
-+BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                      int n)
-+{
-+    BN_ULONG ret;
-+    size_t i = 0;
-+
-+    if (n <= 0)
-+        return 0;
-+
-+    asm volatile ("       subq    %0,%0           \n" /* clear borrow */
-+                  "       jmp     1f              \n"
-+                  ".p2align 4                     \n"
-+                  "1:     movq    (%4,%2,8),%0    \n"
-+                  "       sbbq    (%5,%2,8),%0    \n"
-+                  "       movq    %0,(%3,%2,8)    \n"
-+                  "       lea     1(%2),%2        \n"
-+                  "       loop    1b              \n"
-+                  "       sbbq    %0,%0           \n":"=&r" (ret), "+c"(n),
-+                  "+r"(i)
-+                  :"r"(rp), "r"(ap), "r"(bp)
-+                  :"cc", "memory");
-+
-+    return ret & 1;
-+}
-+# else
-+/* Simics 1.4<7 has buggy sbbq:-( */
-+#  define BN_MASK2 0xffffffffffffffffL
-+BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
-+{
-+    BN_ULONG t1, t2;
-+    int c = 0;
-+
-+    if (n <= 0)
-+        return ((BN_ULONG)0);
-+
-+    for (;;) {
-+        t1 = a[0];
-+        t2 = b[0];
-+        r[0] = (t1 - t2 - c) & BN_MASK2;
-+        if (t1 != t2)
-+            c = (t1 < t2);
-+        if (--n <= 0)
-+            break;
-+
-+        t1 = a[1];
-+        t2 = b[1];
-+        r[1] = (t1 - t2 - c) & BN_MASK2;
-+        if (t1 != t2)
-+            c = (t1 < t2);
-+        if (--n <= 0)
-+            break;
-+
-+        t1 = a[2];
-+        t2 = b[2];
-+        r[2] = (t1 - t2 - c) & BN_MASK2;
-+        if (t1 != t2)
-+            c = (t1 < t2);
-+        if (--n <= 0)
-+            break;
-+
-+        t1 = a[3];
-+        t2 = b[3];
-+        r[3] = (t1 - t2 - c) & BN_MASK2;
-+        if (t1 != t2)
-+            c = (t1 < t2);
-+        if (--n <= 0)
-+            break;
-+
-+        a += 4;
-+        b += 4;
-+        r += 4;
-+    }
-+    return (c);
-+}
-+# endif
-+
-+/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
-+/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
-+/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
-+/*
-+ * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number
-+ * c=(c2,c1,c0)
-+ */
-+
-+/*
-+ * Keep in mind that carrying into high part of multiplication result
-+ * can not overflow, because it cannot be all-ones.
-+ */
-+# if 0
-+/* original macros are kept for reference purposes */
-+#  define mul_add_c(a,b,c0,c1,c2)       do {    \
-+        BN_ULONG ta = (a), tb = (b);            \
-+        BN_ULONG lo, hi;                        \
-+        BN_UMULT_LOHI(lo,hi,ta,tb);             \
-+        c0 += lo; hi += (c0 for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# May 2011
-+#
-+# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
-+# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
-+# the time being... Except that it has two code paths: code suitable
-+# for any x86_64 CPU and PCLMULQDQ one suitable for Westmere and
-+# later. Improvement varies from one benchmark and µ-arch to another.
-+# Vanilla code path is at most 20% faster than compiler-generated code
-+# [not very impressive], while PCLMULQDQ - whole 85%-160% better on
-+# 163- and 571-bit ECDH benchmarks on Intel CPUs. Keep in mind that
-+# these coefficients are not ones for bn_GF2m_mul_2x2 itself, as not
-+# all CPU time is burnt in it...
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+($lo,$hi)=("%rax","%rdx");	$a=$lo;
-+($i0,$i1)=("%rsi","%rdi");
-+($t0,$t1)=("%rbx","%rcx");
-+($b,$mask)=("%rbp","%r8");
-+($a1,$a2,$a4,$a8,$a12,$a48)=map("%r$_",(9..15));
-+($R,$Tx)=("%xmm0","%xmm1");
-+
-+$code.=<<___;
-+.text
-+
-+.type	_mul_1x1,\@abi-omnipotent
-+.align	16
-+_mul_1x1:
-+	sub	\$128+8,%rsp
-+	mov	\$-1,$a1
-+	lea	($a,$a),$i0
-+	shr	\$3,$a1
-+	lea	(,$a,4),$i1
-+	and	$a,$a1			# a1=a&0x1fffffffffffffff
-+	lea	(,$a,8),$a8
-+	sar	\$63,$a			# broadcast 63rd bit
-+	lea	($a1,$a1),$a2
-+	sar	\$63,$i0		# broadcast 62nd bit
-+	lea	(,$a1,4),$a4
-+	and	$b,$a
-+	sar	\$63,$i1		# boardcast 61st bit
-+	mov	$a,$hi			# $a is $lo
-+	shl	\$63,$lo
-+	and	$b,$i0
-+	shr	\$1,$hi
-+	mov	$i0,$t1
-+	shl	\$62,$i0
-+	and	$b,$i1
-+	shr	\$2,$t1
-+	xor	$i0,$lo
-+	mov	$i1,$t0
-+	shl	\$61,$i1
-+	xor	$t1,$hi
-+	shr	\$3,$t0
-+	xor	$i1,$lo
-+	xor	$t0,$hi
-+
-+	mov	$a1,$a12
-+	movq	\$0,0(%rsp)		# tab[0]=0
-+	xor	$a2,$a12		# a1^a2
-+	mov	$a1,8(%rsp)		# tab[1]=a1
-+	 mov	$a4,$a48
-+	mov	$a2,16(%rsp)		# tab[2]=a2
-+	 xor	$a8,$a48		# a4^a8
-+	mov	$a12,24(%rsp)		# tab[3]=a1^a2
-+
-+	xor	$a4,$a1
-+	mov	$a4,32(%rsp)		# tab[4]=a4
-+	xor	$a4,$a2
-+	mov	$a1,40(%rsp)		# tab[5]=a1^a4
-+	xor	$a4,$a12
-+	mov	$a2,48(%rsp)		# tab[6]=a2^a4
-+	 xor	$a48,$a1		# a1^a4^a4^a8=a1^a8
-+	mov	$a12,56(%rsp)		# tab[7]=a1^a2^a4
-+	 xor	$a48,$a2		# a2^a4^a4^a8=a1^a8
-+
-+	mov	$a8,64(%rsp)		# tab[8]=a8
-+	xor	$a48,$a12		# a1^a2^a4^a4^a8=a1^a2^a8
-+	mov	$a1,72(%rsp)		# tab[9]=a1^a8
-+	 xor	$a4,$a1			# a1^a8^a4
-+	mov	$a2,80(%rsp)		# tab[10]=a2^a8
-+	 xor	$a4,$a2			# a2^a8^a4
-+	mov	$a12,88(%rsp)		# tab[11]=a1^a2^a8
-+
-+	xor	$a4,$a12		# a1^a2^a8^a4
-+	mov	$a48,96(%rsp)		# tab[12]=a4^a8
-+	 mov	$mask,$i0
-+	mov	$a1,104(%rsp)		# tab[13]=a1^a4^a8
-+	 and	$b,$i0
-+	mov	$a2,112(%rsp)		# tab[14]=a2^a4^a8
-+	 shr	\$4,$b
-+	mov	$a12,120(%rsp)		# tab[15]=a1^a2^a4^a8
-+	 mov	$mask,$i1
-+	 and	$b,$i1
-+	 shr	\$4,$b
-+
-+	movq	(%rsp,$i0,8),$R		# half of calculations is done in SSE2
-+	mov	$mask,$i0
-+	and	$b,$i0
-+	shr	\$4,$b
-+___
-+    for ($n=1;$n<8;$n++) {
-+	$code.=<<___;
-+	mov	(%rsp,$i1,8),$t1
-+	mov	$mask,$i1
-+	mov	$t1,$t0
-+	shl	\$`8*$n-4`,$t1
-+	and	$b,$i1
-+	 movq	(%rsp,$i0,8),$Tx
-+	shr	\$`64-(8*$n-4)`,$t0
-+	xor	$t1,$lo
-+	 pslldq	\$$n,$Tx
-+	 mov	$mask,$i0
-+	shr	\$4,$b
-+	xor	$t0,$hi
-+	 and	$b,$i0
-+	 shr	\$4,$b
-+	 pxor	$Tx,$R
-+___
-+    }
-+$code.=<<___;
-+	mov	(%rsp,$i1,8),$t1
-+	mov	$t1,$t0
-+	shl	\$`8*$n-4`,$t1
-+	movq	$R,$i0
-+	shr	\$`64-(8*$n-4)`,$t0
-+	xor	$t1,$lo
-+	psrldq	\$8,$R
-+	xor	$t0,$hi
-+	movq	$R,$i1
-+	xor	$i0,$lo
-+	xor	$i1,$hi
-+
-+	add	\$128+8,%rsp
-+	ret
-+.Lend_mul_1x1:
-+.size	_mul_1x1,.-_mul_1x1
-+___
-+
-+($rp,$a1,$a0,$b1,$b0) = $win64?	("%rcx","%rdx","%r8", "%r9","%r10") :	# Win64 order
-+				("%rdi","%rsi","%rdx","%rcx","%r8");	# Unix order
-+
-+$code.=<<___;
-+.extern	OPENSSL_ia32cap_P
-+.globl	bn_GF2m_mul_2x2
-+.type	bn_GF2m_mul_2x2,\@abi-omnipotent
-+.align	16
-+bn_GF2m_mul_2x2:
-+	mov	OPENSSL_ia32cap_P(%rip),%rax
-+	bt	\$33,%rax
-+	jnc	.Lvanilla_mul_2x2
-+
-+	movq		$a1,%xmm0
-+	movq		$b1,%xmm1
-+	movq		$a0,%xmm2
-+___
-+$code.=<<___ if ($win64);
-+	movq		40(%rsp),%xmm3
-+___
-+$code.=<<___ if (!$win64);
-+	movq		$b0,%xmm3
-+___
-+$code.=<<___;
-+	movdqa		%xmm0,%xmm4
-+	movdqa		%xmm1,%xmm5
-+	pclmulqdq	\$0,%xmm1,%xmm0	# a1·b1
-+	pxor		%xmm2,%xmm4
-+	pxor		%xmm3,%xmm5
-+	pclmulqdq	\$0,%xmm3,%xmm2	# a0·b0
-+	pclmulqdq	\$0,%xmm5,%xmm4	# (a0+a1)·(b0+b1)
-+	xorps		%xmm0,%xmm4
-+	xorps		%xmm2,%xmm4	# (a0+a1)·(b0+b1)-a0·b0-a1·b1
-+	movdqa		%xmm4,%xmm5
-+	pslldq		\$8,%xmm4
-+	psrldq		\$8,%xmm5
-+	pxor		%xmm4,%xmm2
-+	pxor		%xmm5,%xmm0
-+	movdqu		%xmm2,0($rp)
-+	movdqu		%xmm0,16($rp)
-+	ret
-+
-+.align	16
-+.Lvanilla_mul_2x2:
-+	lea	-8*17(%rsp),%rsp
-+___
-+$code.=<<___ if ($win64);
-+	mov	`8*17+40`(%rsp),$b0
-+	mov	%rdi,8*15(%rsp)
-+	mov	%rsi,8*16(%rsp)
-+___
-+$code.=<<___;
-+	mov	%r14,8*10(%rsp)
-+	mov	%r13,8*11(%rsp)
-+	mov	%r12,8*12(%rsp)
-+	mov	%rbp,8*13(%rsp)
-+	mov	%rbx,8*14(%rsp)
-+.Lbody_mul_2x2:
-+	mov	$rp,32(%rsp)		# save the arguments
-+	mov	$a1,40(%rsp)
-+	mov	$a0,48(%rsp)
-+	mov	$b1,56(%rsp)
-+	mov	$b0,64(%rsp)
-+
-+	mov	\$0xf,$mask
-+	mov	$a1,$a
-+	mov	$b1,$b
-+	call	_mul_1x1		# a1·b1
-+	mov	$lo,16(%rsp)
-+	mov	$hi,24(%rsp)
-+
-+	mov	48(%rsp),$a
-+	mov	64(%rsp),$b
-+	call	_mul_1x1		# a0·b0
-+	mov	$lo,0(%rsp)
-+	mov	$hi,8(%rsp)
-+
-+	mov	40(%rsp),$a
-+	mov	56(%rsp),$b
-+	xor	48(%rsp),$a
-+	xor	64(%rsp),$b
-+	call	_mul_1x1		# (a0+a1)·(b0+b1)
-+___
-+	@r=("%rbx","%rcx","%rdi","%rsi");
-+$code.=<<___;
-+	mov	0(%rsp),@r[0]
-+	mov	8(%rsp),@r[1]
-+	mov	16(%rsp),@r[2]
-+	mov	24(%rsp),@r[3]
-+	mov	32(%rsp),%rbp
-+
-+	xor	$hi,$lo
-+	xor	@r[1],$hi
-+	xor	@r[0],$lo
-+	mov	@r[0],0(%rbp)
-+	xor	@r[2],$hi
-+	mov	@r[3],24(%rbp)
-+	xor	@r[3],$lo
-+	xor	@r[3],$hi
-+	xor	$hi,$lo
-+	mov	$hi,16(%rbp)
-+	mov	$lo,8(%rbp)
-+
-+	mov	8*10(%rsp),%r14
-+	mov	8*11(%rsp),%r13
-+	mov	8*12(%rsp),%r12
-+	mov	8*13(%rsp),%rbp
-+	mov	8*14(%rsp),%rbx
-+___
-+$code.=<<___ if ($win64);
-+	mov	8*15(%rsp),%rdi
-+	mov	8*16(%rsp),%rsi
-+___
-+$code.=<<___;
-+	lea	8*17(%rsp),%rsp
-+	ret
-+.Lend_mul_2x2:
-+.size	bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
-+.asciz	"GF(2^m) Multiplication for x86_64, CRYPTOGAMS by "
-+.align	16
-+___
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#               CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern __imp_RtlVirtualUnwind
-+
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lbody_mul_2x2(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<"prologue" label
-+	jb	.Lin_prologue
-+
-+	mov	8*10(%rax),%r14		# mimic epilogue
-+	mov	8*11(%rax),%r13
-+	mov	8*12(%rax),%r12
-+	mov	8*13(%rax),%rbp
-+	mov	8*14(%rax),%rbx
-+	mov	8*15(%rax),%rdi
-+	mov	8*16(%rax),%rsi
-+
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+
-+.Lin_prologue:
-+	lea	8*17(%rax),%rax
-+	mov	%rax,152($context)	# restore context->Rsp
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	_mul_1x1
-+	.rva	.Lend_mul_1x1
-+	.rva	.LSEH_info_1x1
-+
-+	.rva	.Lvanilla_mul_2x2
-+	.rva	.Lend_mul_2x2
-+	.rva	.LSEH_info_2x2
-+.section	.xdata
-+.align	8
-+.LSEH_info_1x1:
-+	.byte	0x01,0x07,0x02,0x00
-+	.byte	0x07,0x01,0x11,0x00	# sub rsp,128+8
-+.LSEH_info_2x2:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+___
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-mont.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-mont.pl
-new file mode 100755
-index 0000000..df4cca5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-mont.pl
-@@ -0,0 +1,1521 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# October 2005.
-+#
-+# Montgomery multiplication routine for x86_64. While it gives modest
-+# 9% improvement of rsa4096 sign on Opteron, rsa512 sign runs more
-+# than twice, >2x, as fast. Most common rsa1024 sign is improved by
-+# respectful 50%. It remains to be seen if loop unrolling and
-+# dedicated squaring routine can provide further improvement...
-+
-+# July 2011.
-+#
-+# Add dedicated squaring procedure. Performance improvement varies
-+# from platform to platform, but in average it's ~5%/15%/25%/33%
-+# for 512-/1024-/2048-/4096-bit RSA *sign* benchmarks respectively.
-+
-+# August 2011.
-+#
-+# Unroll and modulo-schedule inner loops in such manner that they
-+# are "fallen through" for input lengths of 8, which is critical for
-+# 1024-bit RSA *sign*. Average performance improvement in comparison
-+# to *initial* version of this module from 2005 is ~0%/30%/40%/45%
-+# for 512-/1024-/2048-/4096-bit RSA *sign* benchmarks respectively.
-+
-+# June 2013.
-+#
-+# Optimize reduction in squaring procedure and improve 1024+-bit RSA
-+# sign performance by 10-16% on Intel Sandy Bridge and later
-+# (virtually same on non-Intel processors).
-+
-+# August 2013.
-+#
-+# Add MULX/ADOX/ADCX code path.
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$addx = ($1>=2.23);
-+}
-+
-+if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	    `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$addx = ($1>=2.10);
-+}
-+
-+if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	    `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$addx = ($1>=12);
-+}
-+
-+if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) {
-+	my $ver = $2 + $3/100.0;	# 3.1->3.01, 3.10->3.10
-+	$addx = ($ver>=3.03);
-+}
-+
-+# int bn_mul_mont(
-+$rp="%rdi";	# BN_ULONG *rp,
-+$ap="%rsi";	# const BN_ULONG *ap,
-+$bp="%rdx";	# const BN_ULONG *bp,
-+$np="%rcx";	# const BN_ULONG *np,
-+$n0="%r8";	# const BN_ULONG *n0,
-+$num="%r9";	# int num);
-+$lo0="%r10";
-+$hi0="%r11";
-+$hi1="%r13";
-+$i="%r14";
-+$j="%r15";
-+$m0="%rbx";
-+$m1="%rbp";
-+
-+$code=<<___;
-+.text
-+
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	bn_mul_mont
-+.type	bn_mul_mont,\@function,6
-+.align	16
-+bn_mul_mont:
-+	mov	${num}d,${num}d
-+	mov	%rsp,%rax
-+	test	\$3,${num}d
-+	jnz	.Lmul_enter
-+	cmp	\$8,${num}d
-+	jb	.Lmul_enter
-+___
-+$code.=<<___ if ($addx);
-+	mov	OPENSSL_ia32cap_P+8(%rip),%r11d
-+___
-+$code.=<<___;
-+	cmp	$ap,$bp
-+	jne	.Lmul4x_enter
-+	test	\$7,${num}d
-+	jz	.Lsqr8x_enter
-+	jmp	.Lmul4x_enter
-+
-+.align	16
-+.Lmul_enter:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	neg	$num
-+	mov	%rsp,%r11
-+	lea	-16(%rsp,$num,8),%r10	# future alloca(8*(num+2))
-+	neg	$num			# restore $num
-+	and	\$-1024,%r10		# minimize TLB usage
-+
-+	# An OS-agnostic version of __chkstk.
-+	#
-+	# Some OSes (Windows) insist on stack being "wired" to
-+	# physical memory in strictly sequential manner, i.e. if stack
-+	# allocation spans two pages, then reference to farmost one can
-+	# be punishable by SEGV. But page walking can do good even on
-+	# other OSes, because it guarantees that villain thread hits
-+	# the guard page before it can make damage to innocent one...
-+	sub	%r10,%r11
-+	and	\$-4096,%r11
-+	lea	(%r10,%r11),%rsp
-+	mov	(%rsp),%r11
-+	cmp	%r10,%rsp
-+	ja	.Lmul_page_walk
-+	jmp	.Lmul_page_walk_done
-+
-+.align	16
-+.Lmul_page_walk:
-+	lea	-4096(%rsp),%rsp
-+	mov	(%rsp),%r11
-+	cmp	%r10,%rsp
-+	ja	.Lmul_page_walk
-+.Lmul_page_walk_done:
-+
-+	mov	%rax,8(%rsp,$num,8)	# tp[num+1]=%rsp
-+.Lmul_body:
-+	mov	$bp,%r12		# reassign $bp
-+___
-+		$bp="%r12";
-+$code.=<<___;
-+	mov	($n0),$n0		# pull n0[0] value
-+	mov	($bp),$m0		# m0=bp[0]
-+	mov	($ap),%rax
-+
-+	xor	$i,$i			# i=0
-+	xor	$j,$j			# j=0
-+
-+	mov	$n0,$m1
-+	mulq	$m0			# ap[0]*bp[0]
-+	mov	%rax,$lo0
-+	mov	($np),%rax
-+
-+	imulq	$lo0,$m1		# "tp[0]"*n0
-+	mov	%rdx,$hi0
-+
-+	mulq	$m1			# np[0]*m1
-+	add	%rax,$lo0		# discarded
-+	mov	8($ap),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$hi1
-+
-+	lea	1($j),$j		# j++
-+	jmp	.L1st_enter
-+
-+.align	16
-+.L1st:
-+	add	%rax,$hi1
-+	mov	($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$hi0,$hi1		# np[j]*m1+ap[j]*bp[0]
-+	mov	$lo0,$hi0
-+	adc	\$0,%rdx
-+	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$hi1
-+
-+.L1st_enter:
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$hi0
-+	mov	($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	lea	1($j),$j		# j++
-+	mov	%rdx,$lo0
-+
-+	mulq	$m1			# np[j]*m1
-+	cmp	$num,$j
-+	jne	.L1st
-+
-+	add	%rax,$hi1
-+	mov	($ap),%rax		# ap[0]
-+	adc	\$0,%rdx
-+	add	$hi0,$hi1		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$hi1
-+	mov	$lo0,$hi0
-+
-+	xor	%rdx,%rdx
-+	add	$hi0,$hi1
-+	adc	\$0,%rdx
-+	mov	$hi1,-8(%rsp,$num,8)
-+	mov	%rdx,(%rsp,$num,8)	# store upmost overflow bit
-+
-+	lea	1($i),$i		# i++
-+	jmp	.Louter
-+.align	16
-+.Louter:
-+	mov	($bp,$i,8),$m0		# m0=bp[i]
-+	xor	$j,$j			# j=0
-+	mov	$n0,$m1
-+	mov	(%rsp),$lo0
-+	mulq	$m0			# ap[0]*bp[i]
-+	add	%rax,$lo0		# ap[0]*bp[i]+tp[0]
-+	mov	($np),%rax
-+	adc	\$0,%rdx
-+
-+	imulq	$lo0,$m1		# tp[0]*n0
-+	mov	%rdx,$hi0
-+
-+	mulq	$m1			# np[0]*m1
-+	add	%rax,$lo0		# discarded
-+	mov	8($ap),%rax
-+	adc	\$0,%rdx
-+	mov	8(%rsp),$lo0		# tp[1]
-+	mov	%rdx,$hi1
-+
-+	lea	1($j),$j		# j++
-+	jmp	.Linner_enter
-+
-+.align	16
-+.Linner:
-+	add	%rax,$hi1
-+	mov	($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$lo0,$hi1		# np[j]*m1+ap[j]*bp[i]+tp[j]
-+	mov	(%rsp,$j,8),$lo0
-+	adc	\$0,%rdx
-+	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$hi1
-+
-+.Linner_enter:
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$hi0
-+	mov	($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$hi0,$lo0		# ap[j]*bp[i]+tp[j]
-+	mov	%rdx,$hi0
-+	adc	\$0,$hi0
-+	lea	1($j),$j		# j++
-+
-+	mulq	$m1			# np[j]*m1
-+	cmp	$num,$j
-+	jne	.Linner
-+
-+	add	%rax,$hi1
-+	mov	($ap),%rax		# ap[0]
-+	adc	\$0,%rdx
-+	add	$lo0,$hi1		# np[j]*m1+ap[j]*bp[i]+tp[j]
-+	mov	(%rsp,$j,8),$lo0
-+	adc	\$0,%rdx
-+	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$hi1
-+
-+	xor	%rdx,%rdx
-+	add	$hi0,$hi1
-+	adc	\$0,%rdx
-+	add	$lo0,$hi1		# pull upmost overflow bit
-+	adc	\$0,%rdx
-+	mov	$hi1,-8(%rsp,$num,8)
-+	mov	%rdx,(%rsp,$num,8)	# store upmost overflow bit
-+
-+	lea	1($i),$i		# i++
-+	cmp	$num,$i
-+	jb	.Louter
-+
-+	xor	$i,$i			# i=0 and clear CF!
-+	mov	(%rsp),%rax		# tp[0]
-+	lea	(%rsp),$ap		# borrow ap for tp
-+	mov	$num,$j			# j=num
-+	jmp	.Lsub
-+.align	16
-+.Lsub:	sbb	($np,$i,8),%rax
-+	mov	%rax,($rp,$i,8)		# rp[i]=tp[i]-np[i]
-+	mov	8($ap,$i,8),%rax	# tp[i+1]
-+	lea	1($i),$i		# i++
-+	dec	$j			# doesnn't affect CF!
-+	jnz	.Lsub
-+
-+	sbb	\$0,%rax		# handle upmost overflow bit
-+	xor	$i,$i
-+	and	%rax,$ap
-+	not	%rax
-+	mov	$rp,$np
-+	and	%rax,$np
-+	mov	$num,$j			# j=num
-+	or	$np,$ap			# ap=borrow?tp:rp
-+.align	16
-+.Lcopy:					# copy or in-place refresh
-+	mov	($ap,$i,8),%rax
-+	mov	$i,(%rsp,$i,8)		# zap temporary vector
-+	mov	%rax,($rp,$i,8)		# rp[i]=tp[i]
-+	lea	1($i),$i
-+	sub	\$1,$j
-+	jnz	.Lcopy
-+
-+	mov	8(%rsp,$num,8),%rsi	# restore %rsp
-+	mov	\$1,%rax
-+	mov	-48(%rsi),%r15
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lmul_epilogue:
-+	ret
-+.size	bn_mul_mont,.-bn_mul_mont
-+___
-+{{{
-+my @A=("%r10","%r11");
-+my @N=("%r13","%rdi");
-+$code.=<<___;
-+.type	bn_mul4x_mont,\@function,6
-+.align	16
-+bn_mul4x_mont:
-+	mov	${num}d,${num}d
-+	mov	%rsp,%rax
-+.Lmul4x_enter:
-+___
-+$code.=<<___ if ($addx);
-+	and	\$0x80100,%r11d
-+	cmp	\$0x80100,%r11d
-+	je	.Lmulx4x_enter
-+___
-+$code.=<<___;
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	neg	$num
-+	mov	%rsp,%r11
-+	lea	-32(%rsp,$num,8),%r10	# future alloca(8*(num+4))
-+	neg	$num			# restore
-+	and	\$-1024,%r10		# minimize TLB usage
-+
-+	sub	%r10,%r11
-+	and	\$-4096,%r11
-+	lea	(%r10,%r11),%rsp
-+	mov	(%rsp),%r11
-+	cmp	%r10,%rsp
-+	ja	.Lmul4x_page_walk
-+	jmp	.Lmul4x_page_walk_done
-+
-+.Lmul4x_page_walk:
-+	lea	-4096(%rsp),%rsp
-+	mov	(%rsp),%r11
-+	cmp	%r10,%rsp
-+	ja	.Lmul4x_page_walk
-+.Lmul4x_page_walk_done:
-+
-+	mov	%rax,8(%rsp,$num,8)	# tp[num+1]=%rsp
-+.Lmul4x_body:
-+	mov	$rp,16(%rsp,$num,8)	# tp[num+2]=$rp
-+	mov	%rdx,%r12		# reassign $bp
-+___
-+		$bp="%r12";
-+$code.=<<___;
-+	mov	($n0),$n0		# pull n0[0] value
-+	mov	($bp),$m0		# m0=bp[0]
-+	mov	($ap),%rax
-+
-+	xor	$i,$i			# i=0
-+	xor	$j,$j			# j=0
-+
-+	mov	$n0,$m1
-+	mulq	$m0			# ap[0]*bp[0]
-+	mov	%rax,$A[0]
-+	mov	($np),%rax
-+
-+	imulq	$A[0],$m1		# "tp[0]"*n0
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[0]*m1
-+	add	%rax,$A[0]		# discarded
-+	mov	8($ap),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0
-+	add	%rax,$A[1]
-+	mov	8($np),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1
-+	add	%rax,$N[1]
-+	mov	16($ap),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]
-+	lea	4($j),$j		# j++
-+	adc	\$0,%rdx
-+	mov	$N[1],(%rsp)
-+	mov	%rdx,$N[0]
-+	jmp	.L1st4x
-+.align	16
-+.L1st4x:
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[0]
-+	mov	-16($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	-8($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[1]
-+	mov	-8($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[0]
-+
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[0]
-+	mov	($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	8($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[0],-8(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[1]
-+	mov	8($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	lea	4($j),$j		# j++
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	-16($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[1],-32(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[0]
-+	cmp	$num,$j
-+	jb	.L1st4x
-+
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[0]
-+	mov	-16($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	-8($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[1]
-+	mov	-8($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	($ap),%rax		# ap[0]
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[0]
-+
-+	xor	$N[1],$N[1]
-+	add	$A[0],$N[0]
-+	adc	\$0,$N[1]
-+	mov	$N[0],-8(%rsp,$j,8)
-+	mov	$N[1],(%rsp,$j,8)	# store upmost overflow bit
-+
-+	lea	1($i),$i		# i++
-+.align	4
-+.Louter4x:
-+	mov	($bp,$i,8),$m0		# m0=bp[i]
-+	xor	$j,$j			# j=0
-+	mov	(%rsp),$A[0]
-+	mov	$n0,$m1
-+	mulq	$m0			# ap[0]*bp[i]
-+	add	%rax,$A[0]		# ap[0]*bp[i]+tp[0]
-+	mov	($np),%rax
-+	adc	\$0,%rdx
-+
-+	imulq	$A[0],$m1		# tp[0]*n0
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[0]*m1
-+	add	%rax,$A[0]		# "$N[0]", discarded
-+	mov	8($ap),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[1]
-+	mov	8($np),%rax
-+	adc	\$0,%rdx
-+	add	8(%rsp),$A[1]		# +tp[1]
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	16($ap),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[i]+tp[j]
-+	lea	4($j),$j		# j+=2
-+	adc	\$0,%rdx
-+	mov	$N[1],(%rsp)		# tp[j-1]
-+	mov	%rdx,$N[0]
-+	jmp	.Linner4x
-+.align	16
-+.Linner4x:
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[0]
-+	mov	-16($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	-16(%rsp,$j,8),$A[0]	# ap[j]*bp[i]+tp[j]
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	-8($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]
-+	adc	\$0,%rdx
-+	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[1]
-+	mov	-8($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	-8(%rsp,$j,8),$A[1]
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]
-+	adc	\$0,%rdx
-+	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[0]
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[0]
-+	mov	($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	(%rsp,$j,8),$A[0]	# ap[j]*bp[i]+tp[j]
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	8($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]
-+	adc	\$0,%rdx
-+	mov	$N[0],-8(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[1]
-+	mov	8($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	8(%rsp,$j,8),$A[1]
-+	adc	\$0,%rdx
-+	lea	4($j),$j		# j++
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	-16($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]
-+	adc	\$0,%rdx
-+	mov	$N[1],-32(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[0]
-+	cmp	$num,$j
-+	jb	.Linner4x
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[0]
-+	mov	-16($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	-16(%rsp,$j,8),$A[0]	# ap[j]*bp[i]+tp[j]
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	-8($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]
-+	adc	\$0,%rdx
-+	mov	$N[0],-24(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[1]
-+	mov	-8($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	-8(%rsp,$j,8),$A[1]
-+	adc	\$0,%rdx
-+	lea	1($i),$i		# i++
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	($ap),%rax		# ap[0]
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]
-+	adc	\$0,%rdx
-+	mov	$N[1],-16(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$N[0]
-+
-+	xor	$N[1],$N[1]
-+	add	$A[0],$N[0]
-+	adc	\$0,$N[1]
-+	add	(%rsp,$num,8),$N[0]	# pull upmost overflow bit
-+	adc	\$0,$N[1]
-+	mov	$N[0],-8(%rsp,$j,8)
-+	mov	$N[1],(%rsp,$j,8)	# store upmost overflow bit
-+
-+	cmp	$num,$i
-+	jb	.Louter4x
-+___
-+{
-+my @ri=("%rax","%rdx",$m0,$m1);
-+$code.=<<___;
-+	mov	16(%rsp,$num,8),$rp	# restore $rp
-+	mov	0(%rsp),@ri[0]		# tp[0]
-+	pxor	%xmm0,%xmm0
-+	mov	8(%rsp),@ri[1]		# tp[1]
-+	shr	\$2,$num		# num/=4
-+	lea	(%rsp),$ap		# borrow ap for tp
-+	xor	$i,$i			# i=0 and clear CF!
-+
-+	sub	0($np),@ri[0]
-+	mov	16($ap),@ri[2]		# tp[2]
-+	mov	24($ap),@ri[3]		# tp[3]
-+	sbb	8($np),@ri[1]
-+	lea	-1($num),$j		# j=num/4-1
-+	jmp	.Lsub4x
-+.align	16
-+.Lsub4x:
-+	mov	@ri[0],0($rp,$i,8)	# rp[i]=tp[i]-np[i]
-+	mov	@ri[1],8($rp,$i,8)	# rp[i]=tp[i]-np[i]
-+	sbb	16($np,$i,8),@ri[2]
-+	mov	32($ap,$i,8),@ri[0]	# tp[i+1]
-+	mov	40($ap,$i,8),@ri[1]
-+	sbb	24($np,$i,8),@ri[3]
-+	mov	@ri[2],16($rp,$i,8)	# rp[i]=tp[i]-np[i]
-+	mov	@ri[3],24($rp,$i,8)	# rp[i]=tp[i]-np[i]
-+	sbb	32($np,$i,8),@ri[0]
-+	mov	48($ap,$i,8),@ri[2]
-+	mov	56($ap,$i,8),@ri[3]
-+	sbb	40($np,$i,8),@ri[1]
-+	lea	4($i),$i		# i++
-+	dec	$j			# doesnn't affect CF!
-+	jnz	.Lsub4x
-+
-+	mov	@ri[0],0($rp,$i,8)	# rp[i]=tp[i]-np[i]
-+	mov	32($ap,$i,8),@ri[0]	# load overflow bit
-+	sbb	16($np,$i,8),@ri[2]
-+	mov	@ri[1],8($rp,$i,8)	# rp[i]=tp[i]-np[i]
-+	sbb	24($np,$i,8),@ri[3]
-+	mov	@ri[2],16($rp,$i,8)	# rp[i]=tp[i]-np[i]
-+
-+	sbb	\$0,@ri[0]		# handle upmost overflow bit
-+	mov	@ri[3],24($rp,$i,8)	# rp[i]=tp[i]-np[i]
-+	xor	$i,$i			# i=0
-+	and	@ri[0],$ap
-+	not	@ri[0]
-+	mov	$rp,$np
-+	and	@ri[0],$np
-+	lea	-1($num),$j
-+	or	$np,$ap			# ap=borrow?tp:rp
-+
-+	movdqu	($ap),%xmm1
-+	movdqa	%xmm0,(%rsp)
-+	movdqu	%xmm1,($rp)
-+	jmp	.Lcopy4x
-+.align	16
-+.Lcopy4x:					# copy or in-place refresh
-+	movdqu	16($ap,$i),%xmm2
-+	movdqu	32($ap,$i),%xmm1
-+	movdqa	%xmm0,16(%rsp,$i)
-+	movdqu	%xmm2,16($rp,$i)
-+	movdqa	%xmm0,32(%rsp,$i)
-+	movdqu	%xmm1,32($rp,$i)
-+	lea	32($i),$i
-+	dec	$j
-+	jnz	.Lcopy4x
-+
-+	shl	\$2,$num
-+	movdqu	16($ap,$i),%xmm2
-+	movdqa	%xmm0,16(%rsp,$i)
-+	movdqu	%xmm2,16($rp,$i)
-+___
-+}
-+$code.=<<___;
-+	mov	8(%rsp,$num,8),%rsi	# restore %rsp
-+	mov	\$1,%rax
-+	mov	-48(%rsi),%r15
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lmul4x_epilogue:
-+	ret
-+.size	bn_mul4x_mont,.-bn_mul4x_mont
-+___
-+}}}
-+{{{
-+######################################################################
-+# void bn_sqr8x_mont(
-+my $rptr="%rdi";	# const BN_ULONG *rptr,
-+my $aptr="%rsi";	# const BN_ULONG *aptr,
-+my $bptr="%rdx";	# not used
-+my $nptr="%rcx";	# const BN_ULONG *nptr,
-+my $n0  ="%r8";		# const BN_ULONG *n0);
-+my $num ="%r9";		# int num, has to be divisible by 8
-+
-+my ($i,$j,$tptr)=("%rbp","%rcx",$rptr);
-+my @A0=("%r10","%r11");
-+my @A1=("%r12","%r13");
-+my ($a0,$a1,$ai)=("%r14","%r15","%rbx");
-+
-+$code.=<<___	if ($addx);
-+.extern	bn_sqrx8x_internal		# see x86_64-mont5 module
-+___
-+$code.=<<___;
-+.extern	bn_sqr8x_internal		# see x86_64-mont5 module
-+
-+.type	bn_sqr8x_mont,\@function,6
-+.align	32
-+bn_sqr8x_mont:
-+	mov	%rsp,%rax
-+.Lsqr8x_enter:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lsqr8x_prologue:
-+
-+	mov	${num}d,%r10d
-+	shl	\$3,${num}d		# convert $num to bytes
-+	shl	\$3+2,%r10		# 4*$num
-+	neg	$num
-+
-+	##############################################################
-+	# ensure that stack frame doesn't alias with $aptr modulo
-+	# 4096. this is done to allow memory disambiguation logic
-+	# do its job.
-+	#
-+	lea	-64(%rsp,$num,2),%r11
-+	mov	%rsp,%rbp
-+	mov	($n0),$n0		# *n0
-+	sub	$aptr,%r11
-+	and	\$4095,%r11
-+	cmp	%r11,%r10
-+	jb	.Lsqr8x_sp_alt
-+	sub	%r11,%rbp		# align with $aptr
-+	lea	-64(%rbp,$num,2),%rbp	# future alloca(frame+2*$num)
-+	jmp	.Lsqr8x_sp_done
-+
-+.align	32
-+.Lsqr8x_sp_alt:
-+	lea	4096-64(,$num,2),%r10	# 4096-frame-2*$num
-+	lea	-64(%rbp,$num,2),%rbp	# future alloca(frame+2*$num)
-+	sub	%r10,%r11
-+	mov	\$0,%r10
-+	cmovc	%r10,%r11
-+	sub	%r11,%rbp
-+.Lsqr8x_sp_done:
-+	and	\$-64,%rbp
-+	mov	%rsp,%r11
-+	sub	%rbp,%r11
-+	and	\$-4096,%r11
-+	lea	(%rbp,%r11),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lsqr8x_page_walk
-+	jmp	.Lsqr8x_page_walk_done
-+
-+.align	16
-+.Lsqr8x_page_walk:
-+	lea	-4096(%rsp),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lsqr8x_page_walk
-+.Lsqr8x_page_walk_done:
-+
-+	mov	$num,%r10
-+	neg	$num
-+
-+	mov	$n0,  32(%rsp)
-+	mov	%rax, 40(%rsp)		# save original %rsp
-+.Lsqr8x_body:
-+
-+	movq	$nptr, %xmm2		# save pointer to modulus
-+	pxor	%xmm0,%xmm0
-+	movq	$rptr,%xmm1		# save $rptr
-+	movq	%r10, %xmm3		# -$num
-+___
-+$code.=<<___ if ($addx);
-+	mov	OPENSSL_ia32cap_P+8(%rip),%eax
-+	and	\$0x80100,%eax
-+	cmp	\$0x80100,%eax
-+	jne	.Lsqr8x_nox
-+
-+	call	bn_sqrx8x_internal	# see x86_64-mont5 module
-+					# %rax	top-most carry
-+					# %rbp	nptr
-+					# %rcx	-8*num
-+					# %r8	end of tp[2*num]
-+	lea	(%r8,%rcx),%rbx
-+	mov	%rcx,$num
-+	mov	%rcx,%rdx
-+	movq	%xmm1,$rptr
-+	sar	\$3+2,%rcx		# %cf=0
-+	jmp	.Lsqr8x_sub
-+
-+.align	32
-+.Lsqr8x_nox:
-+___
-+$code.=<<___;
-+	call	bn_sqr8x_internal	# see x86_64-mont5 module
-+					# %rax	top-most carry
-+					# %rbp	nptr
-+					# %r8	-8*num
-+					# %rdi	end of tp[2*num]
-+	lea	(%rdi,$num),%rbx
-+	mov	$num,%rcx
-+	mov	$num,%rdx
-+	movq	%xmm1,$rptr
-+	sar	\$3+2,%rcx		# %cf=0
-+	jmp	.Lsqr8x_sub
-+
-+.align	32
-+.Lsqr8x_sub:
-+	mov	8*0(%rbx),%r12
-+	mov	8*1(%rbx),%r13
-+	mov	8*2(%rbx),%r14
-+	mov	8*3(%rbx),%r15
-+	lea	8*4(%rbx),%rbx
-+	sbb	8*0(%rbp),%r12
-+	sbb	8*1(%rbp),%r13
-+	sbb	8*2(%rbp),%r14
-+	sbb	8*3(%rbp),%r15
-+	lea	8*4(%rbp),%rbp
-+	mov	%r12,8*0($rptr)
-+	mov	%r13,8*1($rptr)
-+	mov	%r14,8*2($rptr)
-+	mov	%r15,8*3($rptr)
-+	lea	8*4($rptr),$rptr
-+	inc	%rcx			# preserves %cf
-+	jnz	.Lsqr8x_sub
-+
-+	sbb	\$0,%rax		# top-most carry
-+	lea	(%rbx,$num),%rbx	# rewind
-+	lea	($rptr,$num),$rptr	# rewind
-+
-+	movq	%rax,%xmm1
-+	pxor	%xmm0,%xmm0
-+	pshufd	\$0,%xmm1,%xmm1
-+	mov	40(%rsp),%rsi		# restore %rsp
-+	jmp	.Lsqr8x_cond_copy
-+
-+.align	32
-+.Lsqr8x_cond_copy:
-+	movdqa	16*0(%rbx),%xmm2
-+	movdqa	16*1(%rbx),%xmm3
-+	lea	16*2(%rbx),%rbx
-+	movdqu	16*0($rptr),%xmm4
-+	movdqu	16*1($rptr),%xmm5
-+	lea	16*2($rptr),$rptr
-+	movdqa	%xmm0,-16*2(%rbx)	# zero tp
-+	movdqa	%xmm0,-16*1(%rbx)
-+	movdqa	%xmm0,-16*2(%rbx,%rdx)
-+	movdqa	%xmm0,-16*1(%rbx,%rdx)
-+	pcmpeqd	%xmm1,%xmm0
-+	pand	%xmm1,%xmm2
-+	pand	%xmm1,%xmm3
-+	pand	%xmm0,%xmm4
-+	pand	%xmm0,%xmm5
-+	pxor	%xmm0,%xmm0
-+	por	%xmm2,%xmm4
-+	por	%xmm3,%xmm5
-+	movdqu	%xmm4,-16*2($rptr)
-+	movdqu	%xmm5,-16*1($rptr)
-+	add	\$32,$num
-+	jnz	.Lsqr8x_cond_copy
-+
-+	mov	\$1,%rax
-+	mov	-48(%rsi),%r15
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lsqr8x_epilogue:
-+	ret
-+.size	bn_sqr8x_mont,.-bn_sqr8x_mont
-+___
-+}}}
-+
-+if ($addx) {{{
-+my $bp="%rdx";	# original value
-+
-+$code.=<<___;
-+.type	bn_mulx4x_mont,\@function,6
-+.align	32
-+bn_mulx4x_mont:
-+	mov	%rsp,%rax
-+.Lmulx4x_enter:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lmulx4x_prologue:
-+
-+	shl	\$3,${num}d		# convert $num to bytes
-+	xor	%r10,%r10
-+	sub	$num,%r10		# -$num
-+	mov	($n0),$n0		# *n0
-+	lea	-72(%rsp,%r10),%rbp	# future alloca(frame+$num+8)
-+	and	\$-128,%rbp
-+	mov	%rsp,%r11
-+	sub	%rbp,%r11
-+	and	\$-4096,%r11
-+	lea	(%rbp,%r11),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lmulx4x_page_walk
-+	jmp	.Lmulx4x_page_walk_done
-+
-+.align	16
-+.Lmulx4x_page_walk:
-+	lea	-4096(%rsp),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lmulx4x_page_walk
-+.Lmulx4x_page_walk_done:
-+
-+	lea	($bp,$num),%r10
-+	##############################################################
-+	# Stack layout
-+	# +0	num
-+	# +8	off-loaded &b[i]
-+	# +16	end of b[num]
-+	# +24	saved n0
-+	# +32	saved rp
-+	# +40	saved %rsp
-+	# +48	inner counter
-+	# +56
-+	# +64	tmp[num+1]
-+	#
-+	mov	$num,0(%rsp)		# save $num
-+	shr	\$5,$num
-+	mov	%r10,16(%rsp)		# end of b[num]
-+	sub	\$1,$num
-+	mov	$n0, 24(%rsp)		# save *n0
-+	mov	$rp, 32(%rsp)		# save $rp
-+	mov	%rax,40(%rsp)		# save original %rsp
-+	mov	$num,48(%rsp)		# inner counter
-+	jmp	.Lmulx4x_body
-+
-+.align	32
-+.Lmulx4x_body:
-+___
-+my ($aptr, $bptr, $nptr, $tptr, $mi,  $bi,  $zero, $num)=
-+   ("%rsi","%rdi","%rcx","%rbx","%r8","%r9","%rbp","%rax");
-+my $rptr=$bptr;
-+$code.=<<___;
-+	lea	8($bp),$bptr
-+	mov	($bp),%rdx		# b[0], $bp==%rdx actually
-+	lea	64+32(%rsp),$tptr
-+	mov	%rdx,$bi
-+
-+	mulx	0*8($aptr),$mi,%rax	# a[0]*b[0]
-+	mulx	1*8($aptr),%r11,%r14	# a[1]*b[0]
-+	add	%rax,%r11
-+	mov	$bptr,8(%rsp)		# off-load &b[i]
-+	mulx	2*8($aptr),%r12,%r13	# ...
-+	adc	%r14,%r12
-+	adc	\$0,%r13
-+
-+	mov	$mi,$bptr		# borrow $bptr
-+	imulq	24(%rsp),$mi		# "t[0]"*n0
-+	xor	$zero,$zero		# cf=0, of=0
-+
-+	mulx	3*8($aptr),%rax,%r14
-+	 mov	$mi,%rdx
-+	lea	4*8($aptr),$aptr
-+	adcx	%rax,%r13
-+	adcx	$zero,%r14		# cf=0
-+
-+	mulx	0*8($nptr),%rax,%r10
-+	adcx	%rax,$bptr		# discarded
-+	adox	%r11,%r10
-+	mulx	1*8($nptr),%rax,%r11
-+	adcx	%rax,%r10
-+	adox	%r12,%r11
-+	.byte	0xc4,0x62,0xfb,0xf6,0xa1,0x10,0x00,0x00,0x00	# mulx	2*8($nptr),%rax,%r12
-+	mov	48(%rsp),$bptr		# counter value
-+	mov	%r10,-4*8($tptr)
-+	adcx	%rax,%r11
-+	adox	%r13,%r12
-+	mulx	3*8($nptr),%rax,%r15
-+	 mov	$bi,%rdx
-+	mov	%r11,-3*8($tptr)
-+	adcx	%rax,%r12
-+	adox	$zero,%r15		# of=0
-+	lea	4*8($nptr),$nptr
-+	mov	%r12,-2*8($tptr)
-+
-+	jmp	.Lmulx4x_1st
-+
-+.align	32
-+.Lmulx4x_1st:
-+	adcx	$zero,%r15		# cf=0, modulo-scheduled
-+	mulx	0*8($aptr),%r10,%rax	# a[4]*b[0]
-+	adcx	%r14,%r10
-+	mulx	1*8($aptr),%r11,%r14	# a[5]*b[0]
-+	adcx	%rax,%r11
-+	mulx	2*8($aptr),%r12,%rax	# ...
-+	adcx	%r14,%r12
-+	mulx	3*8($aptr),%r13,%r14
-+	 .byte	0x67,0x67
-+	 mov	$mi,%rdx
-+	adcx	%rax,%r13
-+	adcx	$zero,%r14		# cf=0
-+	lea	4*8($aptr),$aptr
-+	lea	4*8($tptr),$tptr
-+
-+	adox	%r15,%r10
-+	mulx	0*8($nptr),%rax,%r15
-+	adcx	%rax,%r10
-+	adox	%r15,%r11
-+	mulx	1*8($nptr),%rax,%r15
-+	adcx	%rax,%r11
-+	adox	%r15,%r12
-+	mulx	2*8($nptr),%rax,%r15
-+	mov	%r10,-5*8($tptr)
-+	adcx	%rax,%r12
-+	mov	%r11,-4*8($tptr)
-+	adox	%r15,%r13
-+	mulx	3*8($nptr),%rax,%r15
-+	 mov	$bi,%rdx
-+	mov	%r12,-3*8($tptr)
-+	adcx	%rax,%r13
-+	adox	$zero,%r15
-+	lea	4*8($nptr),$nptr
-+	mov	%r13,-2*8($tptr)
-+
-+	dec	$bptr			# of=0, pass cf
-+	jnz	.Lmulx4x_1st
-+
-+	mov	0(%rsp),$num		# load num
-+	mov	8(%rsp),$bptr		# re-load &b[i]
-+	adc	$zero,%r15		# modulo-scheduled
-+	add	%r15,%r14
-+	sbb	%r15,%r15		# top-most carry
-+	mov	%r14,-1*8($tptr)
-+	jmp	.Lmulx4x_outer
-+
-+.align	32
-+.Lmulx4x_outer:
-+	mov	($bptr),%rdx		# b[i]
-+	lea	8($bptr),$bptr		# b++
-+	sub	$num,$aptr		# rewind $aptr
-+	mov	%r15,($tptr)		# save top-most carry
-+	lea	64+4*8(%rsp),$tptr
-+	sub	$num,$nptr		# rewind $nptr
-+
-+	mulx	0*8($aptr),$mi,%r11	# a[0]*b[i]
-+	xor	%ebp,%ebp		# xor	$zero,$zero	# cf=0, of=0
-+	mov	%rdx,$bi
-+	mulx	1*8($aptr),%r14,%r12	# a[1]*b[i]
-+	adox	-4*8($tptr),$mi
-+	adcx	%r14,%r11
-+	mulx	2*8($aptr),%r15,%r13	# ...
-+	adox	-3*8($tptr),%r11
-+	adcx	%r15,%r12
-+	adox	-2*8($tptr),%r12
-+	adcx	$zero,%r13
-+	adox	$zero,%r13
-+
-+	mov	$bptr,8(%rsp)		# off-load &b[i]
-+	mov	$mi,%r15
-+	imulq	24(%rsp),$mi		# "t[0]"*n0
-+	xor	%ebp,%ebp		# xor	$zero,$zero	# cf=0, of=0
-+
-+	mulx	3*8($aptr),%rax,%r14
-+	 mov	$mi,%rdx
-+	adcx	%rax,%r13
-+	adox	-1*8($tptr),%r13
-+	adcx	$zero,%r14
-+	lea	4*8($aptr),$aptr
-+	adox	$zero,%r14
-+
-+	mulx	0*8($nptr),%rax,%r10
-+	adcx	%rax,%r15		# discarded
-+	adox	%r11,%r10
-+	mulx	1*8($nptr),%rax,%r11
-+	adcx	%rax,%r10
-+	adox	%r12,%r11
-+	mulx	2*8($nptr),%rax,%r12
-+	mov	%r10,-4*8($tptr)
-+	adcx	%rax,%r11
-+	adox	%r13,%r12
-+	mulx	3*8($nptr),%rax,%r15
-+	 mov	$bi,%rdx
-+	mov	%r11,-3*8($tptr)
-+	lea	4*8($nptr),$nptr
-+	adcx	%rax,%r12
-+	adox	$zero,%r15		# of=0
-+	mov	48(%rsp),$bptr		# counter value
-+	mov	%r12,-2*8($tptr)
-+
-+	jmp	.Lmulx4x_inner
-+
-+.align	32
-+.Lmulx4x_inner:
-+	mulx	0*8($aptr),%r10,%rax	# a[4]*b[i]
-+	adcx	$zero,%r15		# cf=0, modulo-scheduled
-+	adox	%r14,%r10
-+	mulx	1*8($aptr),%r11,%r14	# a[5]*b[i]
-+	adcx	0*8($tptr),%r10
-+	adox	%rax,%r11
-+	mulx	2*8($aptr),%r12,%rax	# ...
-+	adcx	1*8($tptr),%r11
-+	adox	%r14,%r12
-+	mulx	3*8($aptr),%r13,%r14
-+	 mov	$mi,%rdx
-+	adcx	2*8($tptr),%r12
-+	adox	%rax,%r13
-+	adcx	3*8($tptr),%r13
-+	adox	$zero,%r14		# of=0
-+	lea	4*8($aptr),$aptr
-+	lea	4*8($tptr),$tptr
-+	adcx	$zero,%r14		# cf=0
-+
-+	adox	%r15,%r10
-+	mulx	0*8($nptr),%rax,%r15
-+	adcx	%rax,%r10
-+	adox	%r15,%r11
-+	mulx	1*8($nptr),%rax,%r15
-+	adcx	%rax,%r11
-+	adox	%r15,%r12
-+	mulx	2*8($nptr),%rax,%r15
-+	mov	%r10,-5*8($tptr)
-+	adcx	%rax,%r12
-+	adox	%r15,%r13
-+	mulx	3*8($nptr),%rax,%r15
-+	 mov	$bi,%rdx
-+	mov	%r11,-4*8($tptr)
-+	mov	%r12,-3*8($tptr)
-+	adcx	%rax,%r13
-+	adox	$zero,%r15
-+	lea	4*8($nptr),$nptr
-+	mov	%r13,-2*8($tptr)
-+
-+	dec	$bptr			# of=0, pass cf
-+	jnz	.Lmulx4x_inner
-+
-+	mov	0(%rsp),$num		# load num
-+	mov	8(%rsp),$bptr		# re-load &b[i]
-+	adc	$zero,%r15		# modulo-scheduled
-+	sub	0*8($tptr),$zero	# pull top-most carry
-+	adc	%r15,%r14
-+	sbb	%r15,%r15		# top-most carry
-+	mov	%r14,-1*8($tptr)
-+
-+	cmp	16(%rsp),$bptr
-+	jne	.Lmulx4x_outer
-+
-+	lea	64(%rsp),$tptr
-+	sub	$num,$nptr		# rewind $nptr
-+	neg	%r15
-+	mov	$num,%rdx
-+	shr	\$3+2,$num		# %cf=0
-+	mov	32(%rsp),$rptr		# restore rp
-+	jmp	.Lmulx4x_sub
-+
-+.align	32
-+.Lmulx4x_sub:
-+	mov	8*0($tptr),%r11
-+	mov	8*1($tptr),%r12
-+	mov	8*2($tptr),%r13
-+	mov	8*3($tptr),%r14
-+	lea	8*4($tptr),$tptr
-+	sbb	8*0($nptr),%r11
-+	sbb	8*1($nptr),%r12
-+	sbb	8*2($nptr),%r13
-+	sbb	8*3($nptr),%r14
-+	lea	8*4($nptr),$nptr
-+	mov	%r11,8*0($rptr)
-+	mov	%r12,8*1($rptr)
-+	mov	%r13,8*2($rptr)
-+	mov	%r14,8*3($rptr)
-+	lea	8*4($rptr),$rptr
-+	dec	$num			# preserves %cf
-+	jnz	.Lmulx4x_sub
-+
-+	sbb	\$0,%r15		# top-most carry
-+	lea	64(%rsp),$tptr
-+	sub	%rdx,$rptr		# rewind
-+
-+	movq	%r15,%xmm1
-+	pxor	%xmm0,%xmm0
-+	pshufd	\$0,%xmm1,%xmm1
-+	mov	40(%rsp),%rsi		# restore %rsp
-+	jmp	.Lmulx4x_cond_copy
-+
-+.align	32
-+.Lmulx4x_cond_copy:
-+	movdqa	16*0($tptr),%xmm2
-+	movdqa	16*1($tptr),%xmm3
-+	lea	16*2($tptr),$tptr
-+	movdqu	16*0($rptr),%xmm4
-+	movdqu	16*1($rptr),%xmm5
-+	lea	16*2($rptr),$rptr
-+	movdqa	%xmm0,-16*2($tptr)	# zero tp
-+	movdqa	%xmm0,-16*1($tptr)
-+	pcmpeqd	%xmm1,%xmm0
-+	pand	%xmm1,%xmm2
-+	pand	%xmm1,%xmm3
-+	pand	%xmm0,%xmm4
-+	pand	%xmm0,%xmm5
-+	pxor	%xmm0,%xmm0
-+	por	%xmm2,%xmm4
-+	por	%xmm3,%xmm5
-+	movdqu	%xmm4,-16*2($rptr)
-+	movdqu	%xmm5,-16*1($rptr)
-+	sub	\$32,%rdx
-+	jnz	.Lmulx4x_cond_copy
-+
-+	mov	%rdx,($tptr)
-+
-+	mov	\$1,%rax
-+	mov	-48(%rsi),%r15
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lmulx4x_epilogue:
-+	ret
-+.size	bn_mulx4x_mont,.-bn_mulx4x_mont
-+___
-+}}}
-+$code.=<<___;
-+.asciz	"Montgomery Multiplication for x86_64, CRYPTOGAMS by "
-+.align	16
-+___
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	mul_handler,\@abi-omnipotent
-+.align	16
-+mul_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# end of prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+
-+	mov	192($context),%r10	# pull $num
-+	mov	8(%rax,%r10,8),%rax	# pull saved stack pointer
-+
-+	jmp	.Lcommon_pop_regs
-+.size	mul_handler,.-mul_handler
-+
-+.type	sqr_handler,\@abi-omnipotent
-+.align	16
-+sqr_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# end of prologue label
-+	cmp	%r10,%rbx		# context->Rip<.Lsqr_body
-+	jb	.Lcommon_seh_tail
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# body label
-+	cmp	%r10,%rbx		# context->Rip>=.Lsqr_epilogue
-+	jb	.Lcommon_pop_regs
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	mov	8(%r11),%r10d		# HandlerData[2]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=.Lsqr_epilogue
-+	jae	.Lcommon_seh_tail
-+
-+	mov	40(%rax),%rax		# pull saved stack pointer
-+
-+.Lcommon_pop_regs:
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lcommon_seh_tail:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	sqr_handler,.-sqr_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_bn_mul_mont
-+	.rva	.LSEH_end_bn_mul_mont
-+	.rva	.LSEH_info_bn_mul_mont
-+
-+	.rva	.LSEH_begin_bn_mul4x_mont
-+	.rva	.LSEH_end_bn_mul4x_mont
-+	.rva	.LSEH_info_bn_mul4x_mont
-+
-+	.rva	.LSEH_begin_bn_sqr8x_mont
-+	.rva	.LSEH_end_bn_sqr8x_mont
-+	.rva	.LSEH_info_bn_sqr8x_mont
-+___
-+$code.=<<___ if ($addx);
-+	.rva	.LSEH_begin_bn_mulx4x_mont
-+	.rva	.LSEH_end_bn_mulx4x_mont
-+	.rva	.LSEH_info_bn_mulx4x_mont
-+___
-+$code.=<<___;
-+.section	.xdata
-+.align	8
-+.LSEH_info_bn_mul_mont:
-+	.byte	9,0,0,0
-+	.rva	mul_handler
-+	.rva	.Lmul_body,.Lmul_epilogue	# HandlerData[]
-+.LSEH_info_bn_mul4x_mont:
-+	.byte	9,0,0,0
-+	.rva	mul_handler
-+	.rva	.Lmul4x_body,.Lmul4x_epilogue	# HandlerData[]
-+.LSEH_info_bn_sqr8x_mont:
-+	.byte	9,0,0,0
-+	.rva	sqr_handler
-+	.rva	.Lsqr8x_prologue,.Lsqr8x_body,.Lsqr8x_epilogue		# HandlerData[]
-+.align	8
-+___
-+$code.=<<___ if ($addx);
-+.LSEH_info_bn_mulx4x_mont:
-+	.byte	9,0,0,0
-+	.rva	sqr_handler
-+	.rva	.Lmulx4x_prologue,.Lmulx4x_body,.Lmulx4x_epilogue	# HandlerData[]
-+.align	8
-+___
-+}
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-mont5.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-mont5.pl
-new file mode 100755
-index 0000000..6807ab5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/asm/x86_64-mont5.pl
-@@ -0,0 +1,3827 @@
-+#! /usr/bin/env perl
-+# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# August 2011.
-+#
-+# Companion to x86_64-mont.pl that optimizes cache-timing attack
-+# countermeasures. The subroutines are produced by replacing bp[i]
-+# references in their x86_64-mont.pl counterparts with cache-neutral
-+# references to powers table computed in BN_mod_exp_mont_consttime.
-+# In addition subroutine that scatters elements of the powers table
-+# is implemented, so that scatter-/gathering can be tuned without
-+# bn_exp.c modifications.
-+
-+# August 2013.
-+#
-+# Add MULX/AD*X code paths and additional interfaces to optimize for
-+# branch prediction unit. For input lengths that are multiples of 8
-+# the np argument is not just modulus value, but one interleaved
-+# with 0. This is to optimize post-condition...
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$addx = ($1>=2.23);
-+}
-+
-+if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	    `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$addx = ($1>=2.10);
-+}
-+
-+if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	    `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$addx = ($1>=12);
-+}
-+
-+if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) {
-+	my $ver = $2 + $3/100.0;	# 3.1->3.01, 3.10->3.10
-+	$addx = ($ver>=3.03);
-+}
-+
-+# int bn_mul_mont_gather5(
-+$rp="%rdi";	# BN_ULONG *rp,
-+$ap="%rsi";	# const BN_ULONG *ap,
-+$bp="%rdx";	# const BN_ULONG *bp,
-+$np="%rcx";	# const BN_ULONG *np,
-+$n0="%r8";	# const BN_ULONG *n0,
-+$num="%r9";	# int num,
-+		# int idx);	# 0 to 2^5-1, "index" in $bp holding
-+				# pre-computed powers of a', interlaced
-+				# in such manner that b[0] is $bp[idx],
-+				# b[1] is [2^5+idx], etc.
-+$lo0="%r10";
-+$hi0="%r11";
-+$hi1="%r13";
-+$i="%r14";
-+$j="%r15";
-+$m0="%rbx";
-+$m1="%rbp";
-+
-+$code=<<___;
-+.text
-+
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	bn_mul_mont_gather5
-+.type	bn_mul_mont_gather5,\@function,6
-+.align	64
-+bn_mul_mont_gather5:
-+	mov	${num}d,${num}d
-+	mov	%rsp,%rax
-+	test	\$7,${num}d
-+	jnz	.Lmul_enter
-+___
-+$code.=<<___ if ($addx);
-+	mov	OPENSSL_ia32cap_P+8(%rip),%r11d
-+___
-+$code.=<<___;
-+	jmp	.Lmul4x_enter
-+
-+.align	16
-+.Lmul_enter:
-+	movd	`($win64?56:8)`(%rsp),%xmm5	# load 7th argument
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	neg	$num
-+	mov	%rsp,%r11
-+	lea	-280(%rsp,$num,8),%r10	# future alloca(8*(num+2)+256+8)
-+	neg	$num			# restore $num
-+	and	\$-1024,%r10		# minimize TLB usage
-+
-+	# An OS-agnostic version of __chkstk.
-+	#
-+	# Some OSes (Windows) insist on stack being "wired" to
-+	# physical memory in strictly sequential manner, i.e. if stack
-+	# allocation spans two pages, then reference to farmost one can
-+	# be punishable by SEGV. But page walking can do good even on
-+	# other OSes, because it guarantees that villain thread hits
-+	# the guard page before it can make damage to innocent one...
-+	sub	%r10,%r11
-+	and	\$-4096,%r11
-+	lea	(%r10,%r11),%rsp
-+	mov	(%rsp),%r11
-+	cmp	%r10,%rsp
-+	ja	.Lmul_page_walk
-+	jmp	.Lmul_page_walk_done
-+
-+.Lmul_page_walk:
-+	lea	-4096(%rsp),%rsp
-+	mov	(%rsp),%r11
-+	cmp	%r10,%rsp
-+	ja	.Lmul_page_walk
-+.Lmul_page_walk_done:
-+
-+	lea	.Linc(%rip),%r10
-+	mov	%rax,8(%rsp,$num,8)	# tp[num+1]=%rsp
-+.Lmul_body:
-+
-+	lea	128($bp),%r12		# reassign $bp (+size optimization)
-+___
-+		$bp="%r12";
-+		$STRIDE=2**5*8;		# 5 is "window size"
-+		$N=$STRIDE/4;		# should match cache line size
-+$code.=<<___;
-+	movdqa	0(%r10),%xmm0		# 00000001000000010000000000000000
-+	movdqa	16(%r10),%xmm1		# 00000002000000020000000200000002
-+	lea	24-112(%rsp,$num,8),%r10# place the mask after tp[num+3] (+ICache optimization)
-+	and	\$-16,%r10
-+
-+	pshufd	\$0,%xmm5,%xmm5		# broadcast index
-+	movdqa	%xmm1,%xmm4
-+	movdqa	%xmm1,%xmm2
-+___
-+########################################################################
-+# calculate mask by comparing 0..31 to index and save result to stack
-+#
-+$code.=<<___;
-+	paddd	%xmm0,%xmm1
-+	pcmpeqd	%xmm5,%xmm0		# compare to 1,0
-+	.byte	0x67
-+	movdqa	%xmm4,%xmm3
-+___
-+for($k=0;$k<$STRIDE/16-4;$k+=4) {
-+$code.=<<___;
-+	paddd	%xmm1,%xmm2
-+	pcmpeqd	%xmm5,%xmm1		# compare to 3,2
-+	movdqa	%xmm0,`16*($k+0)+112`(%r10)
-+	movdqa	%xmm4,%xmm0
-+
-+	paddd	%xmm2,%xmm3
-+	pcmpeqd	%xmm5,%xmm2		# compare to 5,4
-+	movdqa	%xmm1,`16*($k+1)+112`(%r10)
-+	movdqa	%xmm4,%xmm1
-+
-+	paddd	%xmm3,%xmm0
-+	pcmpeqd	%xmm5,%xmm3		# compare to 7,6
-+	movdqa	%xmm2,`16*($k+2)+112`(%r10)
-+	movdqa	%xmm4,%xmm2
-+
-+	paddd	%xmm0,%xmm1
-+	pcmpeqd	%xmm5,%xmm0
-+	movdqa	%xmm3,`16*($k+3)+112`(%r10)
-+	movdqa	%xmm4,%xmm3
-+___
-+}
-+$code.=<<___;				# last iteration can be optimized
-+	paddd	%xmm1,%xmm2
-+	pcmpeqd	%xmm5,%xmm1
-+	movdqa	%xmm0,`16*($k+0)+112`(%r10)
-+
-+	paddd	%xmm2,%xmm3
-+	.byte	0x67
-+	pcmpeqd	%xmm5,%xmm2
-+	movdqa	%xmm1,`16*($k+1)+112`(%r10)
-+
-+	pcmpeqd	%xmm5,%xmm3
-+	movdqa	%xmm2,`16*($k+2)+112`(%r10)
-+	pand	`16*($k+0)-128`($bp),%xmm0	# while it's still in register
-+
-+	pand	`16*($k+1)-128`($bp),%xmm1
-+	pand	`16*($k+2)-128`($bp),%xmm2
-+	movdqa	%xmm3,`16*($k+3)+112`(%r10)
-+	pand	`16*($k+3)-128`($bp),%xmm3
-+	por	%xmm2,%xmm0
-+	por	%xmm3,%xmm1
-+___
-+for($k=0;$k<$STRIDE/16-4;$k+=4) {
-+$code.=<<___;
-+	movdqa	`16*($k+0)-128`($bp),%xmm4
-+	movdqa	`16*($k+1)-128`($bp),%xmm5
-+	movdqa	`16*($k+2)-128`($bp),%xmm2
-+	pand	`16*($k+0)+112`(%r10),%xmm4
-+	movdqa	`16*($k+3)-128`($bp),%xmm3
-+	pand	`16*($k+1)+112`(%r10),%xmm5
-+	por	%xmm4,%xmm0
-+	pand	`16*($k+2)+112`(%r10),%xmm2
-+	por	%xmm5,%xmm1
-+	pand	`16*($k+3)+112`(%r10),%xmm3
-+	por	%xmm2,%xmm0
-+	por	%xmm3,%xmm1
-+___
-+}
-+$code.=<<___;
-+	por	%xmm1,%xmm0
-+	pshufd	\$0x4e,%xmm0,%xmm1
-+	por	%xmm1,%xmm0
-+	lea	$STRIDE($bp),$bp
-+	movq	%xmm0,$m0		# m0=bp[0]
-+
-+	mov	($n0),$n0		# pull n0[0] value
-+	mov	($ap),%rax
-+
-+	xor	$i,$i			# i=0
-+	xor	$j,$j			# j=0
-+
-+	mov	$n0,$m1
-+	mulq	$m0			# ap[0]*bp[0]
-+	mov	%rax,$lo0
-+	mov	($np),%rax
-+
-+	imulq	$lo0,$m1		# "tp[0]"*n0
-+	mov	%rdx,$hi0
-+
-+	mulq	$m1			# np[0]*m1
-+	add	%rax,$lo0		# discarded
-+	mov	8($ap),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$hi1
-+
-+	lea	1($j),$j		# j++
-+	jmp	.L1st_enter
-+
-+.align	16
-+.L1st:
-+	add	%rax,$hi1
-+	mov	($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$hi0,$hi1		# np[j]*m1+ap[j]*bp[0]
-+	mov	$lo0,$hi0
-+	adc	\$0,%rdx
-+	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$hi1
-+
-+.L1st_enter:
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$hi0
-+	mov	($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	lea	1($j),$j		# j++
-+	mov	%rdx,$lo0
-+
-+	mulq	$m1			# np[j]*m1
-+	cmp	$num,$j
-+	jne	.L1st			# note that upon exit $j==$num, so
-+					# they can be used interchangeably
-+
-+	add	%rax,$hi1
-+	adc	\$0,%rdx
-+	add	$hi0,$hi1		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$hi1,-16(%rsp,$num,8)	# tp[num-1]
-+	mov	%rdx,$hi1
-+	mov	$lo0,$hi0
-+
-+	xor	%rdx,%rdx
-+	add	$hi0,$hi1
-+	adc	\$0,%rdx
-+	mov	$hi1,-8(%rsp,$num,8)
-+	mov	%rdx,(%rsp,$num,8)	# store upmost overflow bit
-+
-+	lea	1($i),$i		# i++
-+	jmp	.Louter
-+.align	16
-+.Louter:
-+	lea	24+128(%rsp,$num,8),%rdx	# where 256-byte mask is (+size optimization)
-+	and	\$-16,%rdx
-+	pxor	%xmm4,%xmm4
-+	pxor	%xmm5,%xmm5
-+___
-+for($k=0;$k<$STRIDE/16;$k+=4) {
-+$code.=<<___;
-+	movdqa	`16*($k+0)-128`($bp),%xmm0
-+	movdqa	`16*($k+1)-128`($bp),%xmm1
-+	movdqa	`16*($k+2)-128`($bp),%xmm2
-+	movdqa	`16*($k+3)-128`($bp),%xmm3
-+	pand	`16*($k+0)-128`(%rdx),%xmm0
-+	pand	`16*($k+1)-128`(%rdx),%xmm1
-+	por	%xmm0,%xmm4
-+	pand	`16*($k+2)-128`(%rdx),%xmm2
-+	por	%xmm1,%xmm5
-+	pand	`16*($k+3)-128`(%rdx),%xmm3
-+	por	%xmm2,%xmm4
-+	por	%xmm3,%xmm5
-+___
-+}
-+$code.=<<___;
-+	por	%xmm5,%xmm4
-+	pshufd	\$0x4e,%xmm4,%xmm0
-+	por	%xmm4,%xmm0
-+	lea	$STRIDE($bp),$bp
-+
-+	mov	($ap),%rax		# ap[0]
-+	movq	%xmm0,$m0		# m0=bp[i]
-+
-+	xor	$j,$j			# j=0
-+	mov	$n0,$m1
-+	mov	(%rsp),$lo0
-+
-+	mulq	$m0			# ap[0]*bp[i]
-+	add	%rax,$lo0		# ap[0]*bp[i]+tp[0]
-+	mov	($np),%rax
-+	adc	\$0,%rdx
-+
-+	imulq	$lo0,$m1		# tp[0]*n0
-+	mov	%rdx,$hi0
-+
-+	mulq	$m1			# np[0]*m1
-+	add	%rax,$lo0		# discarded
-+	mov	8($ap),%rax
-+	adc	\$0,%rdx
-+	mov	8(%rsp),$lo0		# tp[1]
-+	mov	%rdx,$hi1
-+
-+	lea	1($j),$j		# j++
-+	jmp	.Linner_enter
-+
-+.align	16
-+.Linner:
-+	add	%rax,$hi1
-+	mov	($ap,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$lo0,$hi1		# np[j]*m1+ap[j]*bp[i]+tp[j]
-+	mov	(%rsp,$j,8),$lo0
-+	adc	\$0,%rdx
-+	mov	$hi1,-16(%rsp,$j,8)	# tp[j-1]
-+	mov	%rdx,$hi1
-+
-+.Linner_enter:
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$hi0
-+	mov	($np,$j,8),%rax
-+	adc	\$0,%rdx
-+	add	$hi0,$lo0		# ap[j]*bp[i]+tp[j]
-+	mov	%rdx,$hi0
-+	adc	\$0,$hi0
-+	lea	1($j),$j		# j++
-+
-+	mulq	$m1			# np[j]*m1
-+	cmp	$num,$j
-+	jne	.Linner			# note that upon exit $j==$num, so
-+					# they can be used interchangeably
-+	add	%rax,$hi1
-+	adc	\$0,%rdx
-+	add	$lo0,$hi1		# np[j]*m1+ap[j]*bp[i]+tp[j]
-+	mov	(%rsp,$num,8),$lo0
-+	adc	\$0,%rdx
-+	mov	$hi1,-16(%rsp,$num,8)	# tp[num-1]
-+	mov	%rdx,$hi1
-+
-+	xor	%rdx,%rdx
-+	add	$hi0,$hi1
-+	adc	\$0,%rdx
-+	add	$lo0,$hi1		# pull upmost overflow bit
-+	adc	\$0,%rdx
-+	mov	$hi1,-8(%rsp,$num,8)
-+	mov	%rdx,(%rsp,$num,8)	# store upmost overflow bit
-+
-+	lea	1($i),$i		# i++
-+	cmp	$num,$i
-+	jb	.Louter
-+
-+	xor	$i,$i			# i=0 and clear CF!
-+	mov	(%rsp),%rax		# tp[0]
-+	lea	(%rsp),$ap		# borrow ap for tp
-+	mov	$num,$j			# j=num
-+	jmp	.Lsub
-+.align	16
-+.Lsub:	sbb	($np,$i,8),%rax
-+	mov	%rax,($rp,$i,8)		# rp[i]=tp[i]-np[i]
-+	mov	8($ap,$i,8),%rax	# tp[i+1]
-+	lea	1($i),$i		# i++
-+	dec	$j			# doesnn't affect CF!
-+	jnz	.Lsub
-+
-+	sbb	\$0,%rax		# handle upmost overflow bit
-+	xor	$i,$i
-+	and	%rax,$ap
-+	not	%rax
-+	mov	$rp,$np
-+	and	%rax,$np
-+	mov	$num,$j			# j=num
-+	or	$np,$ap			# ap=borrow?tp:rp
-+.align	16
-+.Lcopy:					# copy or in-place refresh
-+	mov	($ap,$i,8),%rax
-+	mov	$i,(%rsp,$i,8)		# zap temporary vector
-+	mov	%rax,($rp,$i,8)		# rp[i]=tp[i]
-+	lea	1($i),$i
-+	sub	\$1,$j
-+	jnz	.Lcopy
-+
-+	mov	8(%rsp,$num,8),%rsi	# restore %rsp
-+	mov	\$1,%rax
-+
-+	mov	-48(%rsi),%r15
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lmul_epilogue:
-+	ret
-+.size	bn_mul_mont_gather5,.-bn_mul_mont_gather5
-+___
-+{{{
-+my @A=("%r10","%r11");
-+my @N=("%r13","%rdi");
-+$code.=<<___;
-+.type	bn_mul4x_mont_gather5,\@function,6
-+.align	32
-+bn_mul4x_mont_gather5:
-+	.byte	0x67
-+	mov	%rsp,%rax
-+.Lmul4x_enter:
-+___
-+$code.=<<___ if ($addx);
-+	and	\$0x80108,%r11d
-+	cmp	\$0x80108,%r11d		# check for AD*X+BMI2+BMI1
-+	je	.Lmulx4x_enter
-+___
-+$code.=<<___;
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lmul4x_prologue:
-+
-+	.byte	0x67
-+	shl	\$3,${num}d		# convert $num to bytes
-+	lea	($num,$num,2),%r10	# 3*$num in bytes
-+	neg	$num			# -$num
-+
-+	##############################################################
-+	# Ensure that stack frame doesn't alias with $rptr+3*$num
-+	# modulo 4096, which covers ret[num], am[num] and n[num]
-+	# (see bn_exp.c). This is done to allow memory disambiguation
-+	# logic do its magic. [Extra [num] is allocated in order
-+	# to align with bn_power5's frame, which is cleansed after
-+	# completing exponentiation. Extra 256 bytes is for power mask
-+	# calculated from 7th argument, the index.]
-+	#
-+	lea	-320(%rsp,$num,2),%r11
-+	mov	%rsp,%rbp
-+	sub	$rp,%r11
-+	and	\$4095,%r11
-+	cmp	%r11,%r10
-+	jb	.Lmul4xsp_alt
-+	sub	%r11,%rbp		# align with $rp
-+	lea	-320(%rbp,$num,2),%rbp	# future alloca(frame+2*num*8+256)
-+	jmp	.Lmul4xsp_done
-+
-+.align	32
-+.Lmul4xsp_alt:
-+	lea	4096-320(,$num,2),%r10
-+	lea	-320(%rbp,$num,2),%rbp	# future alloca(frame+2*num*8+256)
-+	sub	%r10,%r11
-+	mov	\$0,%r10
-+	cmovc	%r10,%r11
-+	sub	%r11,%rbp
-+.Lmul4xsp_done:
-+	and	\$-64,%rbp
-+	mov	%rsp,%r11
-+	sub	%rbp,%r11
-+	and	\$-4096,%r11
-+	lea	(%rbp,%r11),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lmul4x_page_walk
-+	jmp	.Lmul4x_page_walk_done
-+
-+.Lmul4x_page_walk:
-+	lea	-4096(%rsp),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lmul4x_page_walk
-+.Lmul4x_page_walk_done:
-+
-+	neg	$num
-+
-+	mov	%rax,40(%rsp)
-+.Lmul4x_body:
-+
-+	call	mul4x_internal
-+
-+	mov	40(%rsp),%rsi		# restore %rsp
-+	mov	\$1,%rax
-+
-+	mov	-48(%rsi),%r15
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lmul4x_epilogue:
-+	ret
-+.size	bn_mul4x_mont_gather5,.-bn_mul4x_mont_gather5
-+
-+.type	mul4x_internal,\@abi-omnipotent
-+.align	32
-+mul4x_internal:
-+	shl	\$5,$num		# $num was in bytes
-+	movd	`($win64?56:8)`(%rax),%xmm5	# load 7th argument, index
-+	lea	.Linc(%rip),%rax
-+	lea	128(%rdx,$num),%r13	# end of powers table (+size optimization)
-+	shr	\$5,$num		# restore $num
-+___
-+		$bp="%r12";
-+		$STRIDE=2**5*8;		# 5 is "window size"
-+		$N=$STRIDE/4;		# should match cache line size
-+		$tp=$i;
-+$code.=<<___;
-+	movdqa	0(%rax),%xmm0		# 00000001000000010000000000000000
-+	movdqa	16(%rax),%xmm1		# 00000002000000020000000200000002
-+	lea	88-112(%rsp,$num),%r10	# place the mask after tp[num+1] (+ICache optimization)
-+	lea	128(%rdx),$bp		# size optimization
-+
-+	pshufd	\$0,%xmm5,%xmm5		# broadcast index
-+	movdqa	%xmm1,%xmm4
-+	.byte	0x67,0x67
-+	movdqa	%xmm1,%xmm2
-+___
-+########################################################################
-+# calculate mask by comparing 0..31 to index and save result to stack
-+#
-+$code.=<<___;
-+	paddd	%xmm0,%xmm1
-+	pcmpeqd	%xmm5,%xmm0		# compare to 1,0
-+	.byte	0x67
-+	movdqa	%xmm4,%xmm3
-+___
-+for($i=0;$i<$STRIDE/16-4;$i+=4) {
-+$code.=<<___;
-+	paddd	%xmm1,%xmm2
-+	pcmpeqd	%xmm5,%xmm1		# compare to 3,2
-+	movdqa	%xmm0,`16*($i+0)+112`(%r10)
-+	movdqa	%xmm4,%xmm0
-+
-+	paddd	%xmm2,%xmm3
-+	pcmpeqd	%xmm5,%xmm2		# compare to 5,4
-+	movdqa	%xmm1,`16*($i+1)+112`(%r10)
-+	movdqa	%xmm4,%xmm1
-+
-+	paddd	%xmm3,%xmm0
-+	pcmpeqd	%xmm5,%xmm3		# compare to 7,6
-+	movdqa	%xmm2,`16*($i+2)+112`(%r10)
-+	movdqa	%xmm4,%xmm2
-+
-+	paddd	%xmm0,%xmm1
-+	pcmpeqd	%xmm5,%xmm0
-+	movdqa	%xmm3,`16*($i+3)+112`(%r10)
-+	movdqa	%xmm4,%xmm3
-+___
-+}
-+$code.=<<___;				# last iteration can be optimized
-+	paddd	%xmm1,%xmm2
-+	pcmpeqd	%xmm5,%xmm1
-+	movdqa	%xmm0,`16*($i+0)+112`(%r10)
-+
-+	paddd	%xmm2,%xmm3
-+	.byte	0x67
-+	pcmpeqd	%xmm5,%xmm2
-+	movdqa	%xmm1,`16*($i+1)+112`(%r10)
-+
-+	pcmpeqd	%xmm5,%xmm3
-+	movdqa	%xmm2,`16*($i+2)+112`(%r10)
-+	pand	`16*($i+0)-128`($bp),%xmm0	# while it's still in register
-+
-+	pand	`16*($i+1)-128`($bp),%xmm1
-+	pand	`16*($i+2)-128`($bp),%xmm2
-+	movdqa	%xmm3,`16*($i+3)+112`(%r10)
-+	pand	`16*($i+3)-128`($bp),%xmm3
-+	por	%xmm2,%xmm0
-+	por	%xmm3,%xmm1
-+___
-+for($i=0;$i<$STRIDE/16-4;$i+=4) {
-+$code.=<<___;
-+	movdqa	`16*($i+0)-128`($bp),%xmm4
-+	movdqa	`16*($i+1)-128`($bp),%xmm5
-+	movdqa	`16*($i+2)-128`($bp),%xmm2
-+	pand	`16*($i+0)+112`(%r10),%xmm4
-+	movdqa	`16*($i+3)-128`($bp),%xmm3
-+	pand	`16*($i+1)+112`(%r10),%xmm5
-+	por	%xmm4,%xmm0
-+	pand	`16*($i+2)+112`(%r10),%xmm2
-+	por	%xmm5,%xmm1
-+	pand	`16*($i+3)+112`(%r10),%xmm3
-+	por	%xmm2,%xmm0
-+	por	%xmm3,%xmm1
-+___
-+}
-+$code.=<<___;
-+	por	%xmm1,%xmm0
-+	pshufd	\$0x4e,%xmm0,%xmm1
-+	por	%xmm1,%xmm0
-+	lea	$STRIDE($bp),$bp
-+	movq	%xmm0,$m0		# m0=bp[0]
-+
-+	mov	%r13,16+8(%rsp)		# save end of b[num]
-+	mov	$rp, 56+8(%rsp)		# save $rp
-+
-+	mov	($n0),$n0		# pull n0[0] value
-+	mov	($ap),%rax
-+	lea	($ap,$num),$ap		# end of a[num]
-+	neg	$num
-+
-+	mov	$n0,$m1
-+	mulq	$m0			# ap[0]*bp[0]
-+	mov	%rax,$A[0]
-+	mov	($np),%rax
-+
-+	imulq	$A[0],$m1		# "tp[0]"*n0
-+	lea	64+8(%rsp),$tp
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[0]*m1
-+	add	%rax,$A[0]		# discarded
-+	mov	8($ap,$num),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0
-+	add	%rax,$A[1]
-+	mov	8*1($np),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1
-+	add	%rax,$N[1]
-+	mov	16($ap,$num),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]
-+	lea	4*8($num),$j		# j=4
-+	lea	8*4($np),$np
-+	adc	\$0,%rdx
-+	mov	$N[1],($tp)
-+	mov	%rdx,$N[0]
-+	jmp	.L1st4x
-+
-+.align	32
-+.L1st4x:
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[0]
-+	mov	-8*2($np),%rax
-+	lea	32($tp),$tp
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	-8($ap,$j),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[0],-24($tp)		# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[1]
-+	mov	-8*1($np),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	($ap,$j),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[1],-16($tp)		# tp[j-1]
-+	mov	%rdx,$N[0]
-+
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[0]
-+	mov	8*0($np),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	8($ap,$j),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[0],-8($tp)		# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[1]
-+	mov	8*1($np),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	16($ap,$j),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
-+	lea	8*4($np),$np
-+	adc	\$0,%rdx
-+	mov	$N[1],($tp)		# tp[j-1]
-+	mov	%rdx,$N[0]
-+
-+	add	\$32,$j			# j+=4
-+	jnz	.L1st4x
-+
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[0]
-+	mov	-8*2($np),%rax
-+	lea	32($tp),$tp
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	-8($ap),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[0],-24($tp)		# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[0]
-+	add	%rax,$A[1]
-+	mov	-8*1($np),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	($ap,$num),%rax		# ap[0]
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[0]
-+	adc	\$0,%rdx
-+	mov	$N[1],-16($tp)		# tp[j-1]
-+	mov	%rdx,$N[0]
-+
-+	lea	($np,$num),$np		# rewind $np
-+
-+	xor	$N[1],$N[1]
-+	add	$A[0],$N[0]
-+	adc	\$0,$N[1]
-+	mov	$N[0],-8($tp)
-+
-+	jmp	.Louter4x
-+
-+.align	32
-+.Louter4x:
-+	lea	16+128($tp),%rdx	# where 256-byte mask is (+size optimization)
-+	pxor	%xmm4,%xmm4
-+	pxor	%xmm5,%xmm5
-+___
-+for($i=0;$i<$STRIDE/16;$i+=4) {
-+$code.=<<___;
-+	movdqa	`16*($i+0)-128`($bp),%xmm0
-+	movdqa	`16*($i+1)-128`($bp),%xmm1
-+	movdqa	`16*($i+2)-128`($bp),%xmm2
-+	movdqa	`16*($i+3)-128`($bp),%xmm3
-+	pand	`16*($i+0)-128`(%rdx),%xmm0
-+	pand	`16*($i+1)-128`(%rdx),%xmm1
-+	por	%xmm0,%xmm4
-+	pand	`16*($i+2)-128`(%rdx),%xmm2
-+	por	%xmm1,%xmm5
-+	pand	`16*($i+3)-128`(%rdx),%xmm3
-+	por	%xmm2,%xmm4
-+	por	%xmm3,%xmm5
-+___
-+}
-+$code.=<<___;
-+	por	%xmm5,%xmm4
-+	pshufd	\$0x4e,%xmm4,%xmm0
-+	por	%xmm4,%xmm0
-+	lea	$STRIDE($bp),$bp
-+	movq	%xmm0,$m0		# m0=bp[i]
-+
-+	mov	($tp,$num),$A[0]
-+	mov	$n0,$m1
-+	mulq	$m0			# ap[0]*bp[i]
-+	add	%rax,$A[0]		# ap[0]*bp[i]+tp[0]
-+	mov	($np),%rax
-+	adc	\$0,%rdx
-+
-+	imulq	$A[0],$m1		# tp[0]*n0
-+	mov	%rdx,$A[1]
-+	mov	$N[1],($tp)		# store upmost overflow bit
-+
-+	lea	($tp,$num),$tp		# rewind $tp
-+
-+	mulq	$m1			# np[0]*m1
-+	add	%rax,$A[0]		# "$N[0]", discarded
-+	mov	8($ap,$num),%rax
-+	adc	\$0,%rdx
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[1]
-+	mov	8*1($np),%rax
-+	adc	\$0,%rdx
-+	add	8($tp),$A[1]		# +tp[1]
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	16($ap,$num),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]		# np[j]*m1+ap[j]*bp[i]+tp[j]
-+	lea	4*8($num),$j		# j=4
-+	lea	8*4($np),$np
-+	adc	\$0,%rdx
-+	mov	%rdx,$N[0]
-+	jmp	.Linner4x
-+
-+.align	32
-+.Linner4x:
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[0]
-+	mov	-8*2($np),%rax
-+	adc	\$0,%rdx
-+	add	16($tp),$A[0]		# ap[j]*bp[i]+tp[j]
-+	lea	32($tp),$tp
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	-8($ap,$j),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]
-+	adc	\$0,%rdx
-+	mov	$N[1],-32($tp)		# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[1]
-+	mov	-8*1($np),%rax
-+	adc	\$0,%rdx
-+	add	-8($tp),$A[1]
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	($ap,$j),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]
-+	adc	\$0,%rdx
-+	mov	$N[0],-24($tp)		# tp[j-1]
-+	mov	%rdx,$N[0]
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[0]
-+	mov	8*0($np),%rax
-+	adc	\$0,%rdx
-+	add	($tp),$A[0]		# ap[j]*bp[i]+tp[j]
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	8($ap,$j),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]
-+	adc	\$0,%rdx
-+	mov	$N[1],-16($tp)		# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[1]
-+	mov	8*1($np),%rax
-+	adc	\$0,%rdx
-+	add	8($tp),$A[1]
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	16($ap,$j),%rax
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]
-+	lea	8*4($np),$np
-+	adc	\$0,%rdx
-+	mov	$N[0],-8($tp)		# tp[j-1]
-+	mov	%rdx,$N[0]
-+
-+	add	\$32,$j			# j+=4
-+	jnz	.Linner4x
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[0]
-+	mov	-8*2($np),%rax
-+	adc	\$0,%rdx
-+	add	16($tp),$A[0]		# ap[j]*bp[i]+tp[j]
-+	lea	32($tp),$tp
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[1]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[0]
-+	mov	-8($ap),%rax
-+	adc	\$0,%rdx
-+	add	$A[0],$N[0]
-+	adc	\$0,%rdx
-+	mov	$N[1],-32($tp)		# tp[j-1]
-+	mov	%rdx,$N[1]
-+
-+	mulq	$m0			# ap[j]*bp[i]
-+	add	%rax,$A[1]
-+	mov	$m1,%rax
-+	mov	-8*1($np),$m1
-+	adc	\$0,%rdx
-+	add	-8($tp),$A[1]
-+	adc	\$0,%rdx
-+	mov	%rdx,$A[0]
-+
-+	mulq	$m1			# np[j]*m1
-+	add	%rax,$N[1]
-+	mov	($ap,$num),%rax		# ap[0]
-+	adc	\$0,%rdx
-+	add	$A[1],$N[1]
-+	adc	\$0,%rdx
-+	mov	$N[0],-24($tp)		# tp[j-1]
-+	mov	%rdx,$N[0]
-+
-+	mov	$N[1],-16($tp)		# tp[j-1]
-+	lea	($np,$num),$np		# rewind $np
-+
-+	xor	$N[1],$N[1]
-+	add	$A[0],$N[0]
-+	adc	\$0,$N[1]
-+	add	($tp),$N[0]		# pull upmost overflow bit
-+	adc	\$0,$N[1]		# upmost overflow bit
-+	mov	$N[0],-8($tp)
-+
-+	cmp	16+8(%rsp),$bp
-+	jb	.Louter4x
-+___
-+if (1) {
-+$code.=<<___;
-+	xor	%rax,%rax
-+	sub	$N[0],$m1		# compare top-most words
-+	adc	$j,$j			# $j is zero
-+	or	$j,$N[1]
-+	sub	$N[1],%rax		# %rax=-$N[1]
-+	lea	($tp,$num),%rbx		# tptr in .sqr4x_sub
-+	mov	($np),%r12
-+	lea	($np),%rbp		# nptr in .sqr4x_sub
-+	mov	%r9,%rcx
-+	sar	\$3+2,%rcx
-+	mov	56+8(%rsp),%rdi		# rptr in .sqr4x_sub
-+	dec	%r12			# so that after 'not' we get -n[0]
-+	xor	%r10,%r10
-+	mov	8*1(%rbp),%r13
-+	mov	8*2(%rbp),%r14
-+	mov	8*3(%rbp),%r15
-+	jmp	.Lsqr4x_sub_entry
-+___
-+} else {
-+my @ri=("%rax",$bp,$m0,$m1);
-+my $rp="%rdx";
-+$code.=<<___
-+	xor	\$1,$N[1]
-+	lea	($tp,$num),$tp		# rewind $tp
-+	sar	\$5,$num		# cf=0
-+	lea	($np,$N[1],8),$np
-+	mov	56+8(%rsp),$rp		# restore $rp
-+	jmp	.Lsub4x
-+
-+.align	32
-+.Lsub4x:
-+	.byte	0x66
-+	mov	8*0($tp),@ri[0]
-+	mov	8*1($tp),@ri[1]
-+	.byte	0x66
-+	sbb	16*0($np),@ri[0]
-+	mov	8*2($tp),@ri[2]
-+	sbb	16*1($np),@ri[1]
-+	mov	3*8($tp),@ri[3]
-+	lea	4*8($tp),$tp
-+	sbb	16*2($np),@ri[2]
-+	mov	@ri[0],8*0($rp)
-+	sbb	16*3($np),@ri[3]
-+	lea	16*4($np),$np
-+	mov	@ri[1],8*1($rp)
-+	mov	@ri[2],8*2($rp)
-+	mov	@ri[3],8*3($rp)
-+	lea	8*4($rp),$rp
-+
-+	inc	$num
-+	jnz	.Lsub4x
-+
-+	ret
-+___
-+}
-+$code.=<<___;
-+.size	mul4x_internal,.-mul4x_internal
-+___
-+}}}
-+{{{
-+######################################################################
-+# void bn_power5(
-+my $rptr="%rdi";	# BN_ULONG *rptr,
-+my $aptr="%rsi";	# const BN_ULONG *aptr,
-+my $bptr="%rdx";	# const void *table,
-+my $nptr="%rcx";	# const BN_ULONG *nptr,
-+my $n0  ="%r8";		# const BN_ULONG *n0);
-+my $num ="%r9";		# int num, has to be divisible by 8
-+			# int pwr 
-+
-+my ($i,$j,$tptr)=("%rbp","%rcx",$rptr);
-+my @A0=("%r10","%r11");
-+my @A1=("%r12","%r13");
-+my ($a0,$a1,$ai)=("%r14","%r15","%rbx");
-+
-+$code.=<<___;
-+.globl	bn_power5
-+.type	bn_power5,\@function,6
-+.align	32
-+bn_power5:
-+	mov	%rsp,%rax
-+___
-+$code.=<<___ if ($addx);
-+	mov	OPENSSL_ia32cap_P+8(%rip),%r11d
-+	and	\$0x80108,%r11d
-+	cmp	\$0x80108,%r11d		# check for AD*X+BMI2+BMI1
-+	je	.Lpowerx5_enter
-+___
-+$code.=<<___;
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lpower5_prologue:
-+
-+	shl	\$3,${num}d		# convert $num to bytes
-+	lea	($num,$num,2),%r10d	# 3*$num
-+	neg	$num
-+	mov	($n0),$n0		# *n0
-+
-+	##############################################################
-+	# Ensure that stack frame doesn't alias with $rptr+3*$num
-+	# modulo 4096, which covers ret[num], am[num] and n[num]
-+	# (see bn_exp.c). This is done to allow memory disambiguation
-+	# logic do its magic. [Extra 256 bytes is for power mask
-+	# calculated from 7th argument, the index.]
-+	#
-+	lea	-320(%rsp,$num,2),%r11
-+	mov	%rsp,%rbp
-+	sub	$rptr,%r11
-+	and	\$4095,%r11
-+	cmp	%r11,%r10
-+	jb	.Lpwr_sp_alt
-+	sub	%r11,%rbp		# align with $aptr
-+	lea	-320(%rbp,$num,2),%rbp	# future alloca(frame+2*num*8+256)
-+	jmp	.Lpwr_sp_done
-+
-+.align	32
-+.Lpwr_sp_alt:
-+	lea	4096-320(,$num,2),%r10
-+	lea	-320(%rbp,$num,2),%rbp	# future alloca(frame+2*num*8+256)
-+	sub	%r10,%r11
-+	mov	\$0,%r10
-+	cmovc	%r10,%r11
-+	sub	%r11,%rbp
-+.Lpwr_sp_done:
-+	and	\$-64,%rbp
-+	mov	%rsp,%r11
-+	sub	%rbp,%r11
-+	and	\$-4096,%r11
-+	lea	(%rbp,%r11),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lpwr_page_walk
-+	jmp	.Lpwr_page_walk_done
-+
-+.Lpwr_page_walk:
-+	lea	-4096(%rsp),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lpwr_page_walk
-+.Lpwr_page_walk_done:
-+
-+	mov	$num,%r10	
-+	neg	$num
-+
-+	##############################################################
-+	# Stack layout
-+	#
-+	# +0	saved $num, used in reduction section
-+	# +8	&t[2*$num], used in reduction section
-+	# +32	saved *n0
-+	# +40	saved %rsp
-+	# +48	t[2*$num]
-+	#
-+	mov	$n0,  32(%rsp)
-+	mov	%rax, 40(%rsp)		# save original %rsp
-+.Lpower5_body:
-+	movq	$rptr,%xmm1		# save $rptr, used in sqr8x
-+	movq	$nptr,%xmm2		# save $nptr
-+	movq	%r10, %xmm3		# -$num, used in sqr8x
-+	movq	$bptr,%xmm4
-+
-+	call	__bn_sqr8x_internal
-+	call	__bn_post4x_internal
-+	call	__bn_sqr8x_internal
-+	call	__bn_post4x_internal
-+	call	__bn_sqr8x_internal
-+	call	__bn_post4x_internal
-+	call	__bn_sqr8x_internal
-+	call	__bn_post4x_internal
-+	call	__bn_sqr8x_internal
-+	call	__bn_post4x_internal
-+
-+	movq	%xmm2,$nptr
-+	movq	%xmm4,$bptr
-+	mov	$aptr,$rptr
-+	mov	40(%rsp),%rax
-+	lea	32(%rsp),$n0
-+
-+	call	mul4x_internal
-+
-+	mov	40(%rsp),%rsi		# restore %rsp
-+	mov	\$1,%rax
-+	mov	-48(%rsi),%r15
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lpower5_epilogue:
-+	ret
-+.size	bn_power5,.-bn_power5
-+
-+.globl	bn_sqr8x_internal
-+.hidden	bn_sqr8x_internal
-+.type	bn_sqr8x_internal,\@abi-omnipotent
-+.align	32
-+bn_sqr8x_internal:
-+__bn_sqr8x_internal:
-+	##############################################################
-+	# Squaring part:
-+	#
-+	# a) multiply-n-add everything but a[i]*a[i];
-+	# b) shift result of a) by 1 to the left and accumulate
-+	#    a[i]*a[i] products;
-+	#
-+	##############################################################
-+	#                                                     a[1]a[0]
-+	#                                                 a[2]a[0]
-+	#                                             a[3]a[0]
-+	#                                             a[2]a[1]
-+	#                                         a[4]a[0]
-+	#                                         a[3]a[1]
-+	#                                     a[5]a[0]
-+	#                                     a[4]a[1]
-+	#                                     a[3]a[2]
-+	#                                 a[6]a[0]
-+	#                                 a[5]a[1]
-+	#                                 a[4]a[2]
-+	#                             a[7]a[0]
-+	#                             a[6]a[1]
-+	#                             a[5]a[2]
-+	#                             a[4]a[3]
-+	#                         a[7]a[1]
-+	#                         a[6]a[2]
-+	#                         a[5]a[3]
-+	#                     a[7]a[2]
-+	#                     a[6]a[3]
-+	#                     a[5]a[4]
-+	#                 a[7]a[3]
-+	#                 a[6]a[4]
-+	#             a[7]a[4]
-+	#             a[6]a[5]
-+	#         a[7]a[5]
-+	#     a[7]a[6]
-+	#                                                     a[1]a[0]
-+	#                                                 a[2]a[0]
-+	#                                             a[3]a[0]
-+	#                                         a[4]a[0]
-+	#                                     a[5]a[0]
-+	#                                 a[6]a[0]
-+	#                             a[7]a[0]
-+	#                                             a[2]a[1]
-+	#                                         a[3]a[1]
-+	#                                     a[4]a[1]
-+	#                                 a[5]a[1]
-+	#                             a[6]a[1]
-+	#                         a[7]a[1]
-+	#                                     a[3]a[2]
-+	#                                 a[4]a[2]
-+	#                             a[5]a[2]
-+	#                         a[6]a[2]
-+	#                     a[7]a[2]
-+	#                             a[4]a[3]
-+	#                         a[5]a[3]
-+	#                     a[6]a[3]
-+	#                 a[7]a[3]
-+	#                     a[5]a[4]
-+	#                 a[6]a[4]
-+	#             a[7]a[4]
-+	#             a[6]a[5]
-+	#         a[7]a[5]
-+	#     a[7]a[6]
-+	#                                                         a[0]a[0]
-+	#                                                 a[1]a[1]
-+	#                                         a[2]a[2]
-+	#                                 a[3]a[3]
-+	#                         a[4]a[4]
-+	#                 a[5]a[5]
-+	#         a[6]a[6]
-+	# a[7]a[7]
-+
-+	lea	32(%r10),$i		# $i=-($num-32)
-+	lea	($aptr,$num),$aptr	# end of a[] buffer, ($aptr,$i)=&ap[2]
-+
-+	mov	$num,$j			# $j=$num
-+
-+					# comments apply to $num==8 case
-+	mov	-32($aptr,$i),$a0	# a[0]
-+	lea	48+8(%rsp,$num,2),$tptr	# end of tp[] buffer, &tp[2*$num]
-+	mov	-24($aptr,$i),%rax	# a[1]
-+	lea	-32($tptr,$i),$tptr	# end of tp[] window, &tp[2*$num-"$i"]
-+	mov	-16($aptr,$i),$ai	# a[2]
-+	mov	%rax,$a1
-+
-+	mul	$a0			# a[1]*a[0]
-+	mov	%rax,$A0[0]		# a[1]*a[0]
-+	 mov	$ai,%rax		# a[2]
-+	mov	%rdx,$A0[1]
-+	mov	$A0[0],-24($tptr,$i)	# t[1]
-+
-+	mul	$a0			# a[2]*a[0]
-+	add	%rax,$A0[1]
-+	 mov	$ai,%rax
-+	adc	\$0,%rdx
-+	mov	$A0[1],-16($tptr,$i)	# t[2]
-+	mov	%rdx,$A0[0]
-+
-+
-+	 mov	-8($aptr,$i),$ai	# a[3]
-+	mul	$a1			# a[2]*a[1]
-+	mov	%rax,$A1[0]		# a[2]*a[1]+t[3]
-+	 mov	$ai,%rax
-+	mov	%rdx,$A1[1]
-+
-+	 lea	($i),$j
-+	mul	$a0			# a[3]*a[0]
-+	add	%rax,$A0[0]		# a[3]*a[0]+a[2]*a[1]+t[3]
-+	 mov	$ai,%rax
-+	mov	%rdx,$A0[1]
-+	adc	\$0,$A0[1]
-+	add	$A1[0],$A0[0]
-+	adc	\$0,$A0[1]
-+	mov	$A0[0],-8($tptr,$j)	# t[3]
-+	jmp	.Lsqr4x_1st
-+
-+.align	32
-+.Lsqr4x_1st:
-+	 mov	($aptr,$j),$ai		# a[4]
-+	mul	$a1			# a[3]*a[1]
-+	add	%rax,$A1[1]		# a[3]*a[1]+t[4]
-+	 mov	$ai,%rax
-+	mov	%rdx,$A1[0]
-+	adc	\$0,$A1[0]
-+
-+	mul	$a0			# a[4]*a[0]
-+	add	%rax,$A0[1]		# a[4]*a[0]+a[3]*a[1]+t[4]
-+	 mov	$ai,%rax		# a[3]
-+	 mov	8($aptr,$j),$ai		# a[5]
-+	mov	%rdx,$A0[0]
-+	adc	\$0,$A0[0]
-+	add	$A1[1],$A0[1]
-+	adc	\$0,$A0[0]
-+
-+
-+	mul	$a1			# a[4]*a[3]
-+	add	%rax,$A1[0]		# a[4]*a[3]+t[5]
-+	 mov	$ai,%rax
-+	 mov	$A0[1],($tptr,$j)	# t[4]
-+	mov	%rdx,$A1[1]
-+	adc	\$0,$A1[1]
-+
-+	mul	$a0			# a[5]*a[2]
-+	add	%rax,$A0[0]		# a[5]*a[2]+a[4]*a[3]+t[5]
-+	 mov	$ai,%rax
-+	 mov	16($aptr,$j),$ai	# a[6]
-+	mov	%rdx,$A0[1]
-+	adc	\$0,$A0[1]
-+	add	$A1[0],$A0[0]
-+	adc	\$0,$A0[1]
-+
-+	mul	$a1			# a[5]*a[3]
-+	add	%rax,$A1[1]		# a[5]*a[3]+t[6]
-+	 mov	$ai,%rax
-+	 mov	$A0[0],8($tptr,$j)	# t[5]
-+	mov	%rdx,$A1[0]
-+	adc	\$0,$A1[0]
-+
-+	mul	$a0			# a[6]*a[2]
-+	add	%rax,$A0[1]		# a[6]*a[2]+a[5]*a[3]+t[6]
-+	 mov	$ai,%rax		# a[3]
-+	 mov	24($aptr,$j),$ai	# a[7]
-+	mov	%rdx,$A0[0]
-+	adc	\$0,$A0[0]
-+	add	$A1[1],$A0[1]
-+	adc	\$0,$A0[0]
-+
-+
-+	mul	$a1			# a[6]*a[5]
-+	add	%rax,$A1[0]		# a[6]*a[5]+t[7]
-+	 mov	$ai,%rax
-+	 mov	$A0[1],16($tptr,$j)	# t[6]
-+	mov	%rdx,$A1[1]
-+	adc	\$0,$A1[1]
-+	 lea	32($j),$j
-+
-+	mul	$a0			# a[7]*a[4]
-+	add	%rax,$A0[0]		# a[7]*a[4]+a[6]*a[5]+t[6]
-+	 mov	$ai,%rax
-+	mov	%rdx,$A0[1]
-+	adc	\$0,$A0[1]
-+	add	$A1[0],$A0[0]
-+	adc	\$0,$A0[1]
-+	mov	$A0[0],-8($tptr,$j)	# t[7]
-+
-+	cmp	\$0,$j
-+	jne	.Lsqr4x_1st
-+
-+	mul	$a1			# a[7]*a[5]
-+	add	%rax,$A1[1]
-+	lea	16($i),$i
-+	adc	\$0,%rdx
-+	add	$A0[1],$A1[1]
-+	adc	\$0,%rdx
-+
-+	mov	$A1[1],($tptr)		# t[8]
-+	mov	%rdx,$A1[0]
-+	mov	%rdx,8($tptr)		# t[9]
-+	jmp	.Lsqr4x_outer
-+
-+.align	32
-+.Lsqr4x_outer:				# comments apply to $num==6 case
-+	mov	-32($aptr,$i),$a0	# a[0]
-+	lea	48+8(%rsp,$num,2),$tptr	# end of tp[] buffer, &tp[2*$num]
-+	mov	-24($aptr,$i),%rax	# a[1]
-+	lea	-32($tptr,$i),$tptr	# end of tp[] window, &tp[2*$num-"$i"]
-+	mov	-16($aptr,$i),$ai	# a[2]
-+	mov	%rax,$a1
-+
-+	mul	$a0			# a[1]*a[0]
-+	mov	-24($tptr,$i),$A0[0]	# t[1]
-+	add	%rax,$A0[0]		# a[1]*a[0]+t[1]
-+	 mov	$ai,%rax		# a[2]
-+	adc	\$0,%rdx
-+	mov	$A0[0],-24($tptr,$i)	# t[1]
-+	mov	%rdx,$A0[1]
-+
-+	mul	$a0			# a[2]*a[0]
-+	add	%rax,$A0[1]
-+	 mov	$ai,%rax
-+	adc	\$0,%rdx
-+	add	-16($tptr,$i),$A0[1]	# a[2]*a[0]+t[2]
-+	mov	%rdx,$A0[0]
-+	adc	\$0,$A0[0]
-+	mov	$A0[1],-16($tptr,$i)	# t[2]
-+
-+	xor	$A1[0],$A1[0]
-+
-+	 mov	-8($aptr,$i),$ai	# a[3]
-+	mul	$a1			# a[2]*a[1]
-+	add	%rax,$A1[0]		# a[2]*a[1]+t[3]
-+	 mov	$ai,%rax
-+	adc	\$0,%rdx
-+	add	-8($tptr,$i),$A1[0]
-+	mov	%rdx,$A1[1]
-+	adc	\$0,$A1[1]
-+
-+	mul	$a0			# a[3]*a[0]
-+	add	%rax,$A0[0]		# a[3]*a[0]+a[2]*a[1]+t[3]
-+	 mov	$ai,%rax
-+	adc	\$0,%rdx
-+	add	$A1[0],$A0[0]
-+	mov	%rdx,$A0[1]
-+	adc	\$0,$A0[1]
-+	mov	$A0[0],-8($tptr,$i)	# t[3]
-+
-+	lea	($i),$j
-+	jmp	.Lsqr4x_inner
-+
-+.align	32
-+.Lsqr4x_inner:
-+	 mov	($aptr,$j),$ai		# a[4]
-+	mul	$a1			# a[3]*a[1]
-+	add	%rax,$A1[1]		# a[3]*a[1]+t[4]
-+	 mov	$ai,%rax
-+	mov	%rdx,$A1[0]
-+	adc	\$0,$A1[0]
-+	add	($tptr,$j),$A1[1]
-+	adc	\$0,$A1[0]
-+
-+	.byte	0x67
-+	mul	$a0			# a[4]*a[0]
-+	add	%rax,$A0[1]		# a[4]*a[0]+a[3]*a[1]+t[4]
-+	 mov	$ai,%rax		# a[3]
-+	 mov	8($aptr,$j),$ai		# a[5]
-+	mov	%rdx,$A0[0]
-+	adc	\$0,$A0[0]
-+	add	$A1[1],$A0[1]
-+	adc	\$0,$A0[0]
-+
-+	mul	$a1			# a[4]*a[3]
-+	add	%rax,$A1[0]		# a[4]*a[3]+t[5]
-+	mov	$A0[1],($tptr,$j)	# t[4]
-+	 mov	$ai,%rax
-+	mov	%rdx,$A1[1]
-+	adc	\$0,$A1[1]
-+	add	8($tptr,$j),$A1[0]
-+	lea	16($j),$j		# j++
-+	adc	\$0,$A1[1]
-+
-+	mul	$a0			# a[5]*a[2]
-+	add	%rax,$A0[0]		# a[5]*a[2]+a[4]*a[3]+t[5]
-+	 mov	$ai,%rax
-+	adc	\$0,%rdx
-+	add	$A1[0],$A0[0]
-+	mov	%rdx,$A0[1]
-+	adc	\$0,$A0[1]
-+	mov	$A0[0],-8($tptr,$j)	# t[5], "preloaded t[1]" below
-+
-+	cmp	\$0,$j
-+	jne	.Lsqr4x_inner
-+
-+	.byte	0x67
-+	mul	$a1			# a[5]*a[3]
-+	add	%rax,$A1[1]
-+	adc	\$0,%rdx
-+	add	$A0[1],$A1[1]
-+	adc	\$0,%rdx
-+
-+	mov	$A1[1],($tptr)		# t[6], "preloaded t[2]" below
-+	mov	%rdx,$A1[0]
-+	mov	%rdx,8($tptr)		# t[7], "preloaded t[3]" below
-+
-+	add	\$16,$i
-+	jnz	.Lsqr4x_outer
-+
-+					# comments apply to $num==4 case
-+	mov	-32($aptr),$a0		# a[0]
-+	lea	48+8(%rsp,$num,2),$tptr	# end of tp[] buffer, &tp[2*$num]
-+	mov	-24($aptr),%rax		# a[1]
-+	lea	-32($tptr,$i),$tptr	# end of tp[] window, &tp[2*$num-"$i"]
-+	mov	-16($aptr),$ai		# a[2]
-+	mov	%rax,$a1
-+
-+	mul	$a0			# a[1]*a[0]
-+	add	%rax,$A0[0]		# a[1]*a[0]+t[1], preloaded t[1]
-+	 mov	$ai,%rax		# a[2]
-+	mov	%rdx,$A0[1]
-+	adc	\$0,$A0[1]
-+
-+	mul	$a0			# a[2]*a[0]
-+	add	%rax,$A0[1]
-+	 mov	$ai,%rax
-+	 mov	$A0[0],-24($tptr)	# t[1]
-+	mov	%rdx,$A0[0]
-+	adc	\$0,$A0[0]
-+	add	$A1[1],$A0[1]		# a[2]*a[0]+t[2], preloaded t[2]
-+	 mov	-8($aptr),$ai		# a[3]
-+	adc	\$0,$A0[0]
-+
-+	mul	$a1			# a[2]*a[1]
-+	add	%rax,$A1[0]		# a[2]*a[1]+t[3], preloaded t[3]
-+	 mov	$ai,%rax
-+	 mov	$A0[1],-16($tptr)	# t[2]
-+	mov	%rdx,$A1[1]
-+	adc	\$0,$A1[1]
-+
-+	mul	$a0			# a[3]*a[0]
-+	add	%rax,$A0[0]		# a[3]*a[0]+a[2]*a[1]+t[3]
-+	 mov	$ai,%rax
-+	mov	%rdx,$A0[1]
-+	adc	\$0,$A0[1]
-+	add	$A1[0],$A0[0]
-+	adc	\$0,$A0[1]
-+	mov	$A0[0],-8($tptr)	# t[3]
-+
-+	mul	$a1			# a[3]*a[1]
-+	add	%rax,$A1[1]
-+	 mov	-16($aptr),%rax		# a[2]
-+	adc	\$0,%rdx
-+	add	$A0[1],$A1[1]
-+	adc	\$0,%rdx
-+
-+	mov	$A1[1],($tptr)		# t[4]
-+	mov	%rdx,$A1[0]
-+	mov	%rdx,8($tptr)		# t[5]
-+
-+	mul	$ai			# a[2]*a[3]
-+___
-+{
-+my ($shift,$carry)=($a0,$a1);
-+my @S=(@A1,$ai,$n0);
-+$code.=<<___;
-+	 add	\$16,$i
-+	 xor	$shift,$shift
-+	 sub	$num,$i			# $i=16-$num
-+	 xor	$carry,$carry
-+
-+	add	$A1[0],%rax		# t[5]
-+	adc	\$0,%rdx
-+	mov	%rax,8($tptr)		# t[5]
-+	mov	%rdx,16($tptr)		# t[6]
-+	mov	$carry,24($tptr)	# t[7]
-+
-+	 mov	-16($aptr,$i),%rax	# a[0]
-+	lea	48+8(%rsp),$tptr
-+	 xor	$A0[0],$A0[0]		# t[0]
-+	 mov	8($tptr),$A0[1]		# t[1]
-+
-+	lea	($shift,$A0[0],2),$S[0]	# t[2*i]<<1 | shift
-+	shr	\$63,$A0[0]
-+	lea	($j,$A0[1],2),$S[1]	# t[2*i+1]<<1 |
-+	shr	\$63,$A0[1]
-+	or	$A0[0],$S[1]		# | t[2*i]>>63
-+	 mov	16($tptr),$A0[0]	# t[2*i+2]	# prefetch
-+	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
-+	mul	%rax			# a[i]*a[i]
-+	neg	$carry			# mov $carry,cf
-+	 mov	24($tptr),$A0[1]	# t[2*i+2+1]	# prefetch
-+	adc	%rax,$S[0]
-+	 mov	-8($aptr,$i),%rax	# a[i+1]	# prefetch
-+	mov	$S[0],($tptr)
-+	adc	%rdx,$S[1]
-+
-+	lea	($shift,$A0[0],2),$S[2]	# t[2*i]<<1 | shift
-+	 mov	$S[1],8($tptr)
-+	 sbb	$carry,$carry		# mov cf,$carry
-+	shr	\$63,$A0[0]
-+	lea	($j,$A0[1],2),$S[3]	# t[2*i+1]<<1 |
-+	shr	\$63,$A0[1]
-+	or	$A0[0],$S[3]		# | t[2*i]>>63
-+	 mov	32($tptr),$A0[0]	# t[2*i+2]	# prefetch
-+	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
-+	mul	%rax			# a[i]*a[i]
-+	neg	$carry			# mov $carry,cf
-+	 mov	40($tptr),$A0[1]	# t[2*i+2+1]	# prefetch
-+	adc	%rax,$S[2]
-+	 mov	0($aptr,$i),%rax	# a[i+1]	# prefetch
-+	mov	$S[2],16($tptr)
-+	adc	%rdx,$S[3]
-+	lea	16($i),$i
-+	mov	$S[3],24($tptr)
-+	sbb	$carry,$carry		# mov cf,$carry
-+	lea	64($tptr),$tptr
-+	jmp	.Lsqr4x_shift_n_add
-+
-+.align	32
-+.Lsqr4x_shift_n_add:
-+	lea	($shift,$A0[0],2),$S[0]	# t[2*i]<<1 | shift
-+	shr	\$63,$A0[0]
-+	lea	($j,$A0[1],2),$S[1]	# t[2*i+1]<<1 |
-+	shr	\$63,$A0[1]
-+	or	$A0[0],$S[1]		# | t[2*i]>>63
-+	 mov	-16($tptr),$A0[0]	# t[2*i+2]	# prefetch
-+	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
-+	mul	%rax			# a[i]*a[i]
-+	neg	$carry			# mov $carry,cf
-+	 mov	-8($tptr),$A0[1]	# t[2*i+2+1]	# prefetch
-+	adc	%rax,$S[0]
-+	 mov	-8($aptr,$i),%rax	# a[i+1]	# prefetch
-+	mov	$S[0],-32($tptr)
-+	adc	%rdx,$S[1]
-+
-+	lea	($shift,$A0[0],2),$S[2]	# t[2*i]<<1 | shift
-+	 mov	$S[1],-24($tptr)
-+	 sbb	$carry,$carry		# mov cf,$carry
-+	shr	\$63,$A0[0]
-+	lea	($j,$A0[1],2),$S[3]	# t[2*i+1]<<1 |
-+	shr	\$63,$A0[1]
-+	or	$A0[0],$S[3]		# | t[2*i]>>63
-+	 mov	0($tptr),$A0[0]		# t[2*i+2]	# prefetch
-+	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
-+	mul	%rax			# a[i]*a[i]
-+	neg	$carry			# mov $carry,cf
-+	 mov	8($tptr),$A0[1]		# t[2*i+2+1]	# prefetch
-+	adc	%rax,$S[2]
-+	 mov	0($aptr,$i),%rax	# a[i+1]	# prefetch
-+	mov	$S[2],-16($tptr)
-+	adc	%rdx,$S[3]
-+
-+	lea	($shift,$A0[0],2),$S[0]	# t[2*i]<<1 | shift
-+	 mov	$S[3],-8($tptr)
-+	 sbb	$carry,$carry		# mov cf,$carry
-+	shr	\$63,$A0[0]
-+	lea	($j,$A0[1],2),$S[1]	# t[2*i+1]<<1 |
-+	shr	\$63,$A0[1]
-+	or	$A0[0],$S[1]		# | t[2*i]>>63
-+	 mov	16($tptr),$A0[0]	# t[2*i+2]	# prefetch
-+	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
-+	mul	%rax			# a[i]*a[i]
-+	neg	$carry			# mov $carry,cf
-+	 mov	24($tptr),$A0[1]	# t[2*i+2+1]	# prefetch
-+	adc	%rax,$S[0]
-+	 mov	8($aptr,$i),%rax	# a[i+1]	# prefetch
-+	mov	$S[0],0($tptr)
-+	adc	%rdx,$S[1]
-+
-+	lea	($shift,$A0[0],2),$S[2]	# t[2*i]<<1 | shift
-+	 mov	$S[1],8($tptr)
-+	 sbb	$carry,$carry		# mov cf,$carry
-+	shr	\$63,$A0[0]
-+	lea	($j,$A0[1],2),$S[3]	# t[2*i+1]<<1 |
-+	shr	\$63,$A0[1]
-+	or	$A0[0],$S[3]		# | t[2*i]>>63
-+	 mov	32($tptr),$A0[0]	# t[2*i+2]	# prefetch
-+	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
-+	mul	%rax			# a[i]*a[i]
-+	neg	$carry			# mov $carry,cf
-+	 mov	40($tptr),$A0[1]	# t[2*i+2+1]	# prefetch
-+	adc	%rax,$S[2]
-+	 mov	16($aptr,$i),%rax	# a[i+1]	# prefetch
-+	mov	$S[2],16($tptr)
-+	adc	%rdx,$S[3]
-+	mov	$S[3],24($tptr)
-+	sbb	$carry,$carry		# mov cf,$carry
-+	lea	64($tptr),$tptr
-+	add	\$32,$i
-+	jnz	.Lsqr4x_shift_n_add
-+
-+	lea	($shift,$A0[0],2),$S[0]	# t[2*i]<<1 | shift
-+	.byte	0x67
-+	shr	\$63,$A0[0]
-+	lea	($j,$A0[1],2),$S[1]	# t[2*i+1]<<1 |
-+	shr	\$63,$A0[1]
-+	or	$A0[0],$S[1]		# | t[2*i]>>63
-+	 mov	-16($tptr),$A0[0]	# t[2*i+2]	# prefetch
-+	mov	$A0[1],$shift		# shift=t[2*i+1]>>63
-+	mul	%rax			# a[i]*a[i]
-+	neg	$carry			# mov $carry,cf
-+	 mov	-8($tptr),$A0[1]	# t[2*i+2+1]	# prefetch
-+	adc	%rax,$S[0]
-+	 mov	-8($aptr),%rax		# a[i+1]	# prefetch
-+	mov	$S[0],-32($tptr)
-+	adc	%rdx,$S[1]
-+
-+	lea	($shift,$A0[0],2),$S[2]	# t[2*i]<<1|shift
-+	 mov	$S[1],-24($tptr)
-+	 sbb	$carry,$carry		# mov cf,$carry
-+	shr	\$63,$A0[0]
-+	lea	($j,$A0[1],2),$S[3]	# t[2*i+1]<<1 |
-+	shr	\$63,$A0[1]
-+	or	$A0[0],$S[3]		# | t[2*i]>>63
-+	mul	%rax			# a[i]*a[i]
-+	neg	$carry			# mov $carry,cf
-+	adc	%rax,$S[2]
-+	adc	%rdx,$S[3]
-+	mov	$S[2],-16($tptr)
-+	mov	$S[3],-8($tptr)
-+___
-+}
-+######################################################################
-+# Montgomery reduction part, "word-by-word" algorithm.
-+#
-+# This new path is inspired by multiple submissions from Intel, by
-+# Shay Gueron, Vlad Krasnov, Erdinc Ozturk, James Guilford,
-+# Vinodh Gopal...
-+{
-+my ($nptr,$tptr,$carry,$m0)=("%rbp","%rdi","%rsi","%rbx");
-+
-+$code.=<<___;
-+	movq	%xmm2,$nptr
-+__bn_sqr8x_reduction:
-+	xor	%rax,%rax
-+	lea	($nptr,$num),%rcx	# end of n[]
-+	lea	48+8(%rsp,$num,2),%rdx	# end of t[] buffer
-+	mov	%rcx,0+8(%rsp)
-+	lea	48+8(%rsp,$num),$tptr	# end of initial t[] window
-+	mov	%rdx,8+8(%rsp)
-+	neg	$num
-+	jmp	.L8x_reduction_loop
-+
-+.align	32
-+.L8x_reduction_loop:
-+	lea	($tptr,$num),$tptr	# start of current t[] window
-+	.byte	0x66
-+	mov	8*0($tptr),$m0
-+	mov	8*1($tptr),%r9
-+	mov	8*2($tptr),%r10
-+	mov	8*3($tptr),%r11
-+	mov	8*4($tptr),%r12
-+	mov	8*5($tptr),%r13
-+	mov	8*6($tptr),%r14
-+	mov	8*7($tptr),%r15
-+	mov	%rax,(%rdx)		# store top-most carry bit
-+	lea	8*8($tptr),$tptr
-+
-+	.byte	0x67
-+	mov	$m0,%r8
-+	imulq	32+8(%rsp),$m0		# n0*a[0]
-+	mov	8*0($nptr),%rax		# n[0]
-+	mov	\$8,%ecx
-+	jmp	.L8x_reduce
-+
-+.align	32
-+.L8x_reduce:
-+	mulq	$m0
-+	 mov	8*1($nptr),%rax		# n[1]
-+	neg	%r8
-+	mov	%rdx,%r8
-+	adc	\$0,%r8
-+
-+	mulq	$m0
-+	add	%rax,%r9
-+	 mov	8*2($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r9,%r8
-+	 mov	$m0,48-8+8(%rsp,%rcx,8)	# put aside n0*a[i]
-+	mov	%rdx,%r9
-+	adc	\$0,%r9
-+
-+	mulq	$m0
-+	add	%rax,%r10
-+	 mov	8*3($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r10,%r9
-+	 mov	32+8(%rsp),$carry	# pull n0, borrow $carry
-+	mov	%rdx,%r10
-+	adc	\$0,%r10
-+
-+	mulq	$m0
-+	add	%rax,%r11
-+	 mov	8*4($nptr),%rax
-+	adc	\$0,%rdx
-+	 imulq	%r8,$carry		# modulo-scheduled
-+	add	%r11,%r10
-+	mov	%rdx,%r11
-+	adc	\$0,%r11
-+
-+	mulq	$m0
-+	add	%rax,%r12
-+	 mov	8*5($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r12,%r11
-+	mov	%rdx,%r12
-+	adc	\$0,%r12
-+
-+	mulq	$m0
-+	add	%rax,%r13
-+	 mov	8*6($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r13,%r12
-+	mov	%rdx,%r13
-+	adc	\$0,%r13
-+
-+	mulq	$m0
-+	add	%rax,%r14
-+	 mov	8*7($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r14,%r13
-+	mov	%rdx,%r14
-+	adc	\$0,%r14
-+
-+	mulq	$m0
-+	 mov	$carry,$m0		# n0*a[i]
-+	add	%rax,%r15
-+	 mov	8*0($nptr),%rax		# n[0]
-+	adc	\$0,%rdx
-+	add	%r15,%r14
-+	mov	%rdx,%r15
-+	adc	\$0,%r15
-+
-+	dec	%ecx
-+	jnz	.L8x_reduce
-+
-+	lea	8*8($nptr),$nptr
-+	xor	%rax,%rax
-+	mov	8+8(%rsp),%rdx		# pull end of t[]
-+	cmp	0+8(%rsp),$nptr		# end of n[]?
-+	jae	.L8x_no_tail
-+
-+	.byte	0x66
-+	add	8*0($tptr),%r8
-+	adc	8*1($tptr),%r9
-+	adc	8*2($tptr),%r10
-+	adc	8*3($tptr),%r11
-+	adc	8*4($tptr),%r12
-+	adc	8*5($tptr),%r13
-+	adc	8*6($tptr),%r14
-+	adc	8*7($tptr),%r15
-+	sbb	$carry,$carry		# top carry
-+
-+	mov	48+56+8(%rsp),$m0	# pull n0*a[0]
-+	mov	\$8,%ecx
-+	mov	8*0($nptr),%rax
-+	jmp	.L8x_tail
-+
-+.align	32
-+.L8x_tail:
-+	mulq	$m0
-+	add	%rax,%r8
-+	 mov	8*1($nptr),%rax
-+	 mov	%r8,($tptr)		# save result
-+	mov	%rdx,%r8
-+	adc	\$0,%r8
-+
-+	mulq	$m0
-+	add	%rax,%r9
-+	 mov	8*2($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r9,%r8
-+	 lea	8($tptr),$tptr		# $tptr++
-+	mov	%rdx,%r9
-+	adc	\$0,%r9
-+
-+	mulq	$m0
-+	add	%rax,%r10
-+	 mov	8*3($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r10,%r9
-+	mov	%rdx,%r10
-+	adc	\$0,%r10
-+
-+	mulq	$m0
-+	add	%rax,%r11
-+	 mov	8*4($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r11,%r10
-+	mov	%rdx,%r11
-+	adc	\$0,%r11
-+
-+	mulq	$m0
-+	add	%rax,%r12
-+	 mov	8*5($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r12,%r11
-+	mov	%rdx,%r12
-+	adc	\$0,%r12
-+
-+	mulq	$m0
-+	add	%rax,%r13
-+	 mov	8*6($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r13,%r12
-+	mov	%rdx,%r13
-+	adc	\$0,%r13
-+
-+	mulq	$m0
-+	add	%rax,%r14
-+	 mov	8*7($nptr),%rax
-+	adc	\$0,%rdx
-+	add	%r14,%r13
-+	mov	%rdx,%r14
-+	adc	\$0,%r14
-+
-+	mulq	$m0
-+	 mov	48-16+8(%rsp,%rcx,8),$m0# pull n0*a[i]
-+	add	%rax,%r15
-+	adc	\$0,%rdx
-+	add	%r15,%r14
-+	 mov	8*0($nptr),%rax		# pull n[0]
-+	mov	%rdx,%r15
-+	adc	\$0,%r15
-+
-+	dec	%ecx
-+	jnz	.L8x_tail
-+
-+	lea	8*8($nptr),$nptr
-+	mov	8+8(%rsp),%rdx		# pull end of t[]
-+	cmp	0+8(%rsp),$nptr		# end of n[]?
-+	jae	.L8x_tail_done		# break out of loop
-+
-+	 mov	48+56+8(%rsp),$m0	# pull n0*a[0]
-+	neg	$carry
-+	 mov	8*0($nptr),%rax		# pull n[0]
-+	adc	8*0($tptr),%r8
-+	adc	8*1($tptr),%r9
-+	adc	8*2($tptr),%r10
-+	adc	8*3($tptr),%r11
-+	adc	8*4($tptr),%r12
-+	adc	8*5($tptr),%r13
-+	adc	8*6($tptr),%r14
-+	adc	8*7($tptr),%r15
-+	sbb	$carry,$carry		# top carry
-+
-+	mov	\$8,%ecx
-+	jmp	.L8x_tail
-+
-+.align	32
-+.L8x_tail_done:
-+	xor	%rax,%rax
-+	add	(%rdx),%r8		# can this overflow?
-+	adc	\$0,%r9
-+	adc	\$0,%r10
-+	adc	\$0,%r11
-+	adc	\$0,%r12
-+	adc	\$0,%r13
-+	adc	\$0,%r14
-+	adc	\$0,%r15
-+	adc	\$0,%rax
-+
-+	neg	$carry
-+.L8x_no_tail:
-+	adc	8*0($tptr),%r8
-+	adc	8*1($tptr),%r9
-+	adc	8*2($tptr),%r10
-+	adc	8*3($tptr),%r11
-+	adc	8*4($tptr),%r12
-+	adc	8*5($tptr),%r13
-+	adc	8*6($tptr),%r14
-+	adc	8*7($tptr),%r15
-+	adc	\$0,%rax		# top-most carry
-+	 mov	-8($nptr),%rcx		# np[num-1]
-+	 xor	$carry,$carry
-+
-+	movq	%xmm2,$nptr		# restore $nptr
-+
-+	mov	%r8,8*0($tptr)		# store top 512 bits
-+	mov	%r9,8*1($tptr)
-+	 movq	%xmm3,$num		# $num is %r9, can't be moved upwards
-+	mov	%r10,8*2($tptr)
-+	mov	%r11,8*3($tptr)
-+	mov	%r12,8*4($tptr)
-+	mov	%r13,8*5($tptr)
-+	mov	%r14,8*6($tptr)
-+	mov	%r15,8*7($tptr)
-+	lea	8*8($tptr),$tptr
-+
-+	cmp	%rdx,$tptr		# end of t[]?
-+	jb	.L8x_reduction_loop
-+	ret
-+.size	bn_sqr8x_internal,.-bn_sqr8x_internal
-+___
-+}
-+##############################################################
-+# Post-condition, 4x unrolled
-+#
-+{
-+my ($tptr,$nptr)=("%rbx","%rbp");
-+$code.=<<___;
-+.type	__bn_post4x_internal,\@abi-omnipotent
-+.align	32
-+__bn_post4x_internal:
-+	mov	8*0($nptr),%r12
-+	lea	(%rdi,$num),$tptr	# %rdi was $tptr above
-+	mov	$num,%rcx
-+	movq	%xmm1,$rptr		# restore $rptr
-+	neg	%rax
-+	movq	%xmm1,$aptr		# prepare for back-to-back call
-+	sar	\$3+2,%rcx
-+	dec	%r12			# so that after 'not' we get -n[0]
-+	xor	%r10,%r10
-+	mov	8*1($nptr),%r13
-+	mov	8*2($nptr),%r14
-+	mov	8*3($nptr),%r15
-+	jmp	.Lsqr4x_sub_entry
-+
-+.align	16
-+.Lsqr4x_sub:
-+	mov	8*0($nptr),%r12
-+	mov	8*1($nptr),%r13
-+	mov	8*2($nptr),%r14
-+	mov	8*3($nptr),%r15
-+.Lsqr4x_sub_entry:
-+	lea	8*4($nptr),$nptr
-+	not	%r12
-+	not	%r13
-+	not	%r14
-+	not	%r15
-+	and	%rax,%r12
-+	and	%rax,%r13
-+	and	%rax,%r14
-+	and	%rax,%r15
-+
-+	neg	%r10			# mov %r10,%cf
-+	adc	8*0($tptr),%r12
-+	adc	8*1($tptr),%r13
-+	adc	8*2($tptr),%r14
-+	adc	8*3($tptr),%r15
-+	mov	%r12,8*0($rptr)
-+	lea	8*4($tptr),$tptr
-+	mov	%r13,8*1($rptr)
-+	sbb	%r10,%r10		# mov %cf,%r10
-+	mov	%r14,8*2($rptr)
-+	mov	%r15,8*3($rptr)
-+	lea	8*4($rptr),$rptr
-+
-+	inc	%rcx			# pass %cf
-+	jnz	.Lsqr4x_sub
-+
-+	mov	$num,%r10		# prepare for back-to-back call
-+	neg	$num			# restore $num	
-+	ret
-+.size	__bn_post4x_internal,.-__bn_post4x_internal
-+___
-+}
-+{
-+$code.=<<___;
-+.globl	bn_from_montgomery
-+.type	bn_from_montgomery,\@abi-omnipotent
-+.align	32
-+bn_from_montgomery:
-+	testl	\$7,`($win64?"48(%rsp)":"%r9d")`
-+	jz	bn_from_mont8x
-+	xor	%eax,%eax
-+	ret
-+.size	bn_from_montgomery,.-bn_from_montgomery
-+
-+.type	bn_from_mont8x,\@function,6
-+.align	32
-+bn_from_mont8x:
-+	.byte	0x67
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lfrom_prologue:
-+
-+	shl	\$3,${num}d		# convert $num to bytes
-+	lea	($num,$num,2),%r10	# 3*$num in bytes
-+	neg	$num
-+	mov	($n0),$n0		# *n0
-+
-+	##############################################################
-+	# Ensure that stack frame doesn't alias with $rptr+3*$num
-+	# modulo 4096, which covers ret[num], am[num] and n[num]
-+	# (see bn_exp.c). The stack is allocated to aligned with
-+	# bn_power5's frame, and as bn_from_montgomery happens to be
-+	# last operation, we use the opportunity to cleanse it.
-+	#
-+	lea	-320(%rsp,$num,2),%r11
-+	mov	%rsp,%rbp
-+	sub	$rptr,%r11
-+	and	\$4095,%r11
-+	cmp	%r11,%r10
-+	jb	.Lfrom_sp_alt
-+	sub	%r11,%rbp		# align with $aptr
-+	lea	-320(%rbp,$num,2),%rbp	# future alloca(frame+2*$num*8+256)
-+	jmp	.Lfrom_sp_done
-+
-+.align	32
-+.Lfrom_sp_alt:
-+	lea	4096-320(,$num,2),%r10
-+	lea	-320(%rbp,$num,2),%rbp	# future alloca(frame+2*$num*8+256)
-+	sub	%r10,%r11
-+	mov	\$0,%r10
-+	cmovc	%r10,%r11
-+	sub	%r11,%rbp
-+.Lfrom_sp_done:
-+	and	\$-64,%rbp
-+	mov	%rsp,%r11
-+	sub	%rbp,%r11
-+	and	\$-4096,%r11
-+	lea	(%rbp,%r11),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lfrom_page_walk
-+	jmp	.Lfrom_page_walk_done
-+
-+.Lfrom_page_walk:
-+	lea	-4096(%rsp),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lfrom_page_walk
-+.Lfrom_page_walk_done:
-+
-+	mov	$num,%r10
-+	neg	$num
-+
-+	##############################################################
-+	# Stack layout
-+	#
-+	# +0	saved $num, used in reduction section
-+	# +8	&t[2*$num], used in reduction section
-+	# +32	saved *n0
-+	# +40	saved %rsp
-+	# +48	t[2*$num]
-+	#
-+	mov	$n0,  32(%rsp)
-+	mov	%rax, 40(%rsp)		# save original %rsp
-+.Lfrom_body:
-+	mov	$num,%r11
-+	lea	48(%rsp),%rax
-+	pxor	%xmm0,%xmm0
-+	jmp	.Lmul_by_1
-+
-+.align	32
-+.Lmul_by_1:
-+	movdqu	($aptr),%xmm1
-+	movdqu	16($aptr),%xmm2
-+	movdqu	32($aptr),%xmm3
-+	movdqa	%xmm0,(%rax,$num)
-+	movdqu	48($aptr),%xmm4
-+	movdqa	%xmm0,16(%rax,$num)
-+	.byte	0x48,0x8d,0xb6,0x40,0x00,0x00,0x00	# lea	64($aptr),$aptr
-+	movdqa	%xmm1,(%rax)
-+	movdqa	%xmm0,32(%rax,$num)
-+	movdqa	%xmm2,16(%rax)
-+	movdqa	%xmm0,48(%rax,$num)
-+	movdqa	%xmm3,32(%rax)
-+	movdqa	%xmm4,48(%rax)
-+	lea	64(%rax),%rax
-+	sub	\$64,%r11
-+	jnz	.Lmul_by_1
-+
-+	movq	$rptr,%xmm1
-+	movq	$nptr,%xmm2
-+	.byte	0x67
-+	mov	$nptr,%rbp
-+	movq	%r10, %xmm3		# -num
-+___
-+$code.=<<___ if ($addx);
-+	mov	OPENSSL_ia32cap_P+8(%rip),%r11d
-+	and	\$0x80108,%r11d
-+	cmp	\$0x80108,%r11d		# check for AD*X+BMI2+BMI1
-+	jne	.Lfrom_mont_nox
-+
-+	lea	(%rax,$num),$rptr
-+	call	__bn_sqrx8x_reduction
-+	call	__bn_postx4x_internal
-+
-+	pxor	%xmm0,%xmm0
-+	lea	48(%rsp),%rax
-+	mov	40(%rsp),%rsi		# restore %rsp
-+	jmp	.Lfrom_mont_zero
-+
-+.align	32
-+.Lfrom_mont_nox:
-+___
-+$code.=<<___;
-+	call	__bn_sqr8x_reduction
-+	call	__bn_post4x_internal
-+
-+	pxor	%xmm0,%xmm0
-+	lea	48(%rsp),%rax
-+	mov	40(%rsp),%rsi		# restore %rsp
-+	jmp	.Lfrom_mont_zero
-+
-+.align	32
-+.Lfrom_mont_zero:
-+	movdqa	%xmm0,16*0(%rax)
-+	movdqa	%xmm0,16*1(%rax)
-+	movdqa	%xmm0,16*2(%rax)
-+	movdqa	%xmm0,16*3(%rax)
-+	lea	16*4(%rax),%rax
-+	sub	\$32,$num
-+	jnz	.Lfrom_mont_zero
-+
-+	mov	\$1,%rax
-+	mov	-48(%rsi),%r15
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lfrom_epilogue:
-+	ret
-+.size	bn_from_mont8x,.-bn_from_mont8x
-+___
-+}
-+}}}
-+
-+if ($addx) {{{
-+my $bp="%rdx";	# restore original value
-+
-+$code.=<<___;
-+.type	bn_mulx4x_mont_gather5,\@function,6
-+.align	32
-+bn_mulx4x_mont_gather5:
-+	mov	%rsp,%rax
-+.Lmulx4x_enter:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lmulx4x_prologue:
-+
-+	shl	\$3,${num}d		# convert $num to bytes
-+	lea	($num,$num,2),%r10	# 3*$num in bytes
-+	neg	$num			# -$num
-+	mov	($n0),$n0		# *n0
-+
-+	##############################################################
-+	# Ensure that stack frame doesn't alias with $rptr+3*$num
-+	# modulo 4096, which covers ret[num], am[num] and n[num]
-+	# (see bn_exp.c). This is done to allow memory disambiguation
-+	# logic do its magic. [Extra [num] is allocated in order
-+	# to align with bn_power5's frame, which is cleansed after
-+	# completing exponentiation. Extra 256 bytes is for power mask
-+	# calculated from 7th argument, the index.]
-+	#
-+	lea	-320(%rsp,$num,2),%r11
-+	mov	%rsp,%rbp
-+	sub	$rp,%r11
-+	and	\$4095,%r11
-+	cmp	%r11,%r10
-+	jb	.Lmulx4xsp_alt
-+	sub	%r11,%rbp		# align with $aptr
-+	lea	-320(%rbp,$num,2),%rbp	# future alloca(frame+2*$num*8+256)
-+	jmp	.Lmulx4xsp_done
-+
-+.Lmulx4xsp_alt:
-+	lea	4096-320(,$num,2),%r10
-+	lea	-320(%rbp,$num,2),%rbp	# future alloca(frame+2*$num*8+256)
-+	sub	%r10,%r11
-+	mov	\$0,%r10
-+	cmovc	%r10,%r11
-+	sub	%r11,%rbp
-+.Lmulx4xsp_done:	
-+	and	\$-64,%rbp		# ensure alignment
-+	mov	%rsp,%r11
-+	sub	%rbp,%r11
-+	and	\$-4096,%r11
-+	lea	(%rbp,%r11),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lmulx4x_page_walk
-+	jmp	.Lmulx4x_page_walk_done
-+
-+.Lmulx4x_page_walk:
-+	lea	-4096(%rsp),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lmulx4x_page_walk
-+.Lmulx4x_page_walk_done:
-+
-+	##############################################################
-+	# Stack layout
-+	# +0	-num
-+	# +8	off-loaded &b[i]
-+	# +16	end of b[num]
-+	# +24	inner counter
-+	# +32	saved n0
-+	# +40	saved %rsp
-+	# +48
-+	# +56	saved rp
-+	# +64	tmp[num+1]
-+	#
-+	mov	$n0, 32(%rsp)		# save *n0
-+	mov	%rax,40(%rsp)		# save original %rsp
-+.Lmulx4x_body:
-+	call	mulx4x_internal
-+
-+	mov	40(%rsp),%rsi		# restore %rsp
-+	mov	\$1,%rax
-+
-+	mov	-48(%rsi),%r15
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lmulx4x_epilogue:
-+	ret
-+.size	bn_mulx4x_mont_gather5,.-bn_mulx4x_mont_gather5
-+
-+.type	mulx4x_internal,\@abi-omnipotent
-+.align	32
-+mulx4x_internal:
-+	mov	$num,8(%rsp)		# save -$num (it was in bytes)
-+	mov	$num,%r10
-+	neg	$num			# restore $num
-+	shl	\$5,$num
-+	neg	%r10			# restore $num
-+	lea	128($bp,$num),%r13	# end of powers table (+size optimization)
-+	shr	\$5+5,$num
-+	movd	`($win64?56:8)`(%rax),%xmm5	# load 7th argument
-+	sub	\$1,$num
-+	lea	.Linc(%rip),%rax
-+	mov	%r13,16+8(%rsp)		# end of b[num]
-+	mov	$num,24+8(%rsp)		# inner counter
-+	mov	$rp, 56+8(%rsp)		# save $rp
-+___
-+my ($aptr, $bptr, $nptr, $tptr, $mi,  $bi,  $zero, $num)=
-+   ("%rsi","%rdi","%rcx","%rbx","%r8","%r9","%rbp","%rax");
-+my $rptr=$bptr;
-+my $STRIDE=2**5*8;		# 5 is "window size"
-+my $N=$STRIDE/4;		# should match cache line size
-+$code.=<<___;
-+	movdqa	0(%rax),%xmm0		# 00000001000000010000000000000000
-+	movdqa	16(%rax),%xmm1		# 00000002000000020000000200000002
-+	lea	88-112(%rsp,%r10),%r10	# place the mask after tp[num+1] (+ICache optimizaton)
-+	lea	128($bp),$bptr		# size optimization
-+
-+	pshufd	\$0,%xmm5,%xmm5		# broadcast index
-+	movdqa	%xmm1,%xmm4
-+	.byte	0x67
-+	movdqa	%xmm1,%xmm2
-+___
-+########################################################################
-+# calculate mask by comparing 0..31 to index and save result to stack
-+#
-+$code.=<<___;
-+	.byte	0x67
-+	paddd	%xmm0,%xmm1
-+	pcmpeqd	%xmm5,%xmm0		# compare to 1,0
-+	movdqa	%xmm4,%xmm3
-+___
-+for($i=0;$i<$STRIDE/16-4;$i+=4) {
-+$code.=<<___;
-+	paddd	%xmm1,%xmm2
-+	pcmpeqd	%xmm5,%xmm1		# compare to 3,2
-+	movdqa	%xmm0,`16*($i+0)+112`(%r10)
-+	movdqa	%xmm4,%xmm0
-+
-+	paddd	%xmm2,%xmm3
-+	pcmpeqd	%xmm5,%xmm2		# compare to 5,4
-+	movdqa	%xmm1,`16*($i+1)+112`(%r10)
-+	movdqa	%xmm4,%xmm1
-+
-+	paddd	%xmm3,%xmm0
-+	pcmpeqd	%xmm5,%xmm3		# compare to 7,6
-+	movdqa	%xmm2,`16*($i+2)+112`(%r10)
-+	movdqa	%xmm4,%xmm2
-+
-+	paddd	%xmm0,%xmm1
-+	pcmpeqd	%xmm5,%xmm0
-+	movdqa	%xmm3,`16*($i+3)+112`(%r10)
-+	movdqa	%xmm4,%xmm3
-+___
-+}
-+$code.=<<___;				# last iteration can be optimized
-+	.byte	0x67
-+	paddd	%xmm1,%xmm2
-+	pcmpeqd	%xmm5,%xmm1
-+	movdqa	%xmm0,`16*($i+0)+112`(%r10)
-+
-+	paddd	%xmm2,%xmm3
-+	pcmpeqd	%xmm5,%xmm2
-+	movdqa	%xmm1,`16*($i+1)+112`(%r10)
-+
-+	pcmpeqd	%xmm5,%xmm3
-+	movdqa	%xmm2,`16*($i+2)+112`(%r10)
-+
-+	pand	`16*($i+0)-128`($bptr),%xmm0	# while it's still in register
-+	pand	`16*($i+1)-128`($bptr),%xmm1
-+	pand	`16*($i+2)-128`($bptr),%xmm2
-+	movdqa	%xmm3,`16*($i+3)+112`(%r10)
-+	pand	`16*($i+3)-128`($bptr),%xmm3
-+	por	%xmm2,%xmm0
-+	por	%xmm3,%xmm1
-+___
-+for($i=0;$i<$STRIDE/16-4;$i+=4) {
-+$code.=<<___;
-+	movdqa	`16*($i+0)-128`($bptr),%xmm4
-+	movdqa	`16*($i+1)-128`($bptr),%xmm5
-+	movdqa	`16*($i+2)-128`($bptr),%xmm2
-+	pand	`16*($i+0)+112`(%r10),%xmm4
-+	movdqa	`16*($i+3)-128`($bptr),%xmm3
-+	pand	`16*($i+1)+112`(%r10),%xmm5
-+	por	%xmm4,%xmm0
-+	pand	`16*($i+2)+112`(%r10),%xmm2
-+	por	%xmm5,%xmm1
-+	pand	`16*($i+3)+112`(%r10),%xmm3
-+	por	%xmm2,%xmm0
-+	por	%xmm3,%xmm1
-+___
-+}
-+$code.=<<___;
-+	pxor	%xmm1,%xmm0
-+	pshufd	\$0x4e,%xmm0,%xmm1
-+	por	%xmm1,%xmm0
-+	lea	$STRIDE($bptr),$bptr
-+	movq	%xmm0,%rdx		# bp[0]
-+	lea	64+8*4+8(%rsp),$tptr
-+
-+	mov	%rdx,$bi
-+	mulx	0*8($aptr),$mi,%rax	# a[0]*b[0]
-+	mulx	1*8($aptr),%r11,%r12	# a[1]*b[0]
-+	add	%rax,%r11
-+	mulx	2*8($aptr),%rax,%r13	# ...
-+	adc	%rax,%r12
-+	adc	\$0,%r13
-+	mulx	3*8($aptr),%rax,%r14
-+
-+	mov	$mi,%r15
-+	imulq	32+8(%rsp),$mi		# "t[0]"*n0
-+	xor	$zero,$zero		# cf=0, of=0
-+	mov	$mi,%rdx
-+
-+	mov	$bptr,8+8(%rsp)		# off-load &b[i]
-+
-+	lea	4*8($aptr),$aptr
-+	adcx	%rax,%r13
-+	adcx	$zero,%r14		# cf=0
-+
-+	mulx	0*8($nptr),%rax,%r10
-+	adcx	%rax,%r15		# discarded
-+	adox	%r11,%r10
-+	mulx	1*8($nptr),%rax,%r11
-+	adcx	%rax,%r10
-+	adox	%r12,%r11
-+	mulx	2*8($nptr),%rax,%r12
-+	mov	24+8(%rsp),$bptr	# counter value
-+	mov	%r10,-8*4($tptr)
-+	adcx	%rax,%r11
-+	adox	%r13,%r12
-+	mulx	3*8($nptr),%rax,%r15
-+	 mov	$bi,%rdx
-+	mov	%r11,-8*3($tptr)
-+	adcx	%rax,%r12
-+	adox	$zero,%r15		# of=0
-+	lea	4*8($nptr),$nptr
-+	mov	%r12,-8*2($tptr)
-+	jmp	.Lmulx4x_1st
-+
-+.align	32
-+.Lmulx4x_1st:
-+	adcx	$zero,%r15		# cf=0, modulo-scheduled
-+	mulx	0*8($aptr),%r10,%rax	# a[4]*b[0]
-+	adcx	%r14,%r10
-+	mulx	1*8($aptr),%r11,%r14	# a[5]*b[0]
-+	adcx	%rax,%r11
-+	mulx	2*8($aptr),%r12,%rax	# ...
-+	adcx	%r14,%r12
-+	mulx	3*8($aptr),%r13,%r14
-+	 .byte	0x67,0x67
-+	 mov	$mi,%rdx
-+	adcx	%rax,%r13
-+	adcx	$zero,%r14		# cf=0
-+	lea	4*8($aptr),$aptr
-+	lea	4*8($tptr),$tptr
-+
-+	adox	%r15,%r10
-+	mulx	0*8($nptr),%rax,%r15
-+	adcx	%rax,%r10
-+	adox	%r15,%r11
-+	mulx	1*8($nptr),%rax,%r15
-+	adcx	%rax,%r11
-+	adox	%r15,%r12
-+	mulx	2*8($nptr),%rax,%r15
-+	mov	%r10,-5*8($tptr)
-+	adcx	%rax,%r12
-+	mov	%r11,-4*8($tptr)
-+	adox	%r15,%r13
-+	mulx	3*8($nptr),%rax,%r15
-+	 mov	$bi,%rdx
-+	mov	%r12,-3*8($tptr)
-+	adcx	%rax,%r13
-+	adox	$zero,%r15
-+	lea	4*8($nptr),$nptr
-+	mov	%r13,-2*8($tptr)
-+
-+	dec	$bptr			# of=0, pass cf
-+	jnz	.Lmulx4x_1st
-+
-+	mov	8(%rsp),$num		# load -num
-+	adc	$zero,%r15		# modulo-scheduled
-+	lea	($aptr,$num),$aptr	# rewind $aptr
-+	add	%r15,%r14
-+	mov	8+8(%rsp),$bptr		# re-load &b[i]
-+	adc	$zero,$zero		# top-most carry
-+	mov	%r14,-1*8($tptr)
-+	jmp	.Lmulx4x_outer
-+
-+.align	32
-+.Lmulx4x_outer:
-+	lea	16-256($tptr),%r10	# where 256-byte mask is (+density control)
-+	pxor	%xmm4,%xmm4
-+	.byte	0x67,0x67
-+	pxor	%xmm5,%xmm5
-+___
-+for($i=0;$i<$STRIDE/16;$i+=4) {
-+$code.=<<___;
-+	movdqa	`16*($i+0)-128`($bptr),%xmm0
-+	movdqa	`16*($i+1)-128`($bptr),%xmm1
-+	movdqa	`16*($i+2)-128`($bptr),%xmm2
-+	pand	`16*($i+0)+256`(%r10),%xmm0
-+	movdqa	`16*($i+3)-128`($bptr),%xmm3
-+	pand	`16*($i+1)+256`(%r10),%xmm1
-+	por	%xmm0,%xmm4
-+	pand	`16*($i+2)+256`(%r10),%xmm2
-+	por	%xmm1,%xmm5
-+	pand	`16*($i+3)+256`(%r10),%xmm3
-+	por	%xmm2,%xmm4
-+	por	%xmm3,%xmm5
-+___
-+}
-+$code.=<<___;
-+	por	%xmm5,%xmm4
-+	pshufd	\$0x4e,%xmm4,%xmm0
-+	por	%xmm4,%xmm0
-+	lea	$STRIDE($bptr),$bptr
-+	movq	%xmm0,%rdx		# m0=bp[i]
-+
-+	mov	$zero,($tptr)		# save top-most carry
-+	lea	4*8($tptr,$num),$tptr	# rewind $tptr
-+	mulx	0*8($aptr),$mi,%r11	# a[0]*b[i]
-+	xor	$zero,$zero		# cf=0, of=0
-+	mov	%rdx,$bi
-+	mulx	1*8($aptr),%r14,%r12	# a[1]*b[i]
-+	adox	-4*8($tptr),$mi		# +t[0]
-+	adcx	%r14,%r11
-+	mulx	2*8($aptr),%r15,%r13	# ...
-+	adox	-3*8($tptr),%r11
-+	adcx	%r15,%r12
-+	mulx	3*8($aptr),%rdx,%r14
-+	adox	-2*8($tptr),%r12
-+	adcx	%rdx,%r13
-+	lea	($nptr,$num),$nptr	# rewind $nptr
-+	lea	4*8($aptr),$aptr
-+	adox	-1*8($tptr),%r13
-+	adcx	$zero,%r14
-+	adox	$zero,%r14
-+
-+	mov	$mi,%r15
-+	imulq	32+8(%rsp),$mi		# "t[0]"*n0
-+
-+	mov	$mi,%rdx
-+	xor	$zero,$zero		# cf=0, of=0
-+	mov	$bptr,8+8(%rsp)		# off-load &b[i]
-+
-+	mulx	0*8($nptr),%rax,%r10
-+	adcx	%rax,%r15		# discarded
-+	adox	%r11,%r10
-+	mulx	1*8($nptr),%rax,%r11
-+	adcx	%rax,%r10
-+	adox	%r12,%r11
-+	mulx	2*8($nptr),%rax,%r12
-+	adcx	%rax,%r11
-+	adox	%r13,%r12
-+	mulx	3*8($nptr),%rax,%r15
-+	 mov	$bi,%rdx
-+	mov	24+8(%rsp),$bptr	# counter value
-+	mov	%r10,-8*4($tptr)
-+	adcx	%rax,%r12
-+	mov	%r11,-8*3($tptr)
-+	adox	$zero,%r15		# of=0
-+	mov	%r12,-8*2($tptr)
-+	lea	4*8($nptr),$nptr
-+	jmp	.Lmulx4x_inner
-+
-+.align	32
-+.Lmulx4x_inner:
-+	mulx	0*8($aptr),%r10,%rax	# a[4]*b[i]
-+	adcx	$zero,%r15		# cf=0, modulo-scheduled
-+	adox	%r14,%r10
-+	mulx	1*8($aptr),%r11,%r14	# a[5]*b[i]
-+	adcx	0*8($tptr),%r10
-+	adox	%rax,%r11
-+	mulx	2*8($aptr),%r12,%rax	# ...
-+	adcx	1*8($tptr),%r11
-+	adox	%r14,%r12
-+	mulx	3*8($aptr),%r13,%r14
-+	 mov	$mi,%rdx
-+	adcx	2*8($tptr),%r12
-+	adox	%rax,%r13
-+	adcx	3*8($tptr),%r13
-+	adox	$zero,%r14		# of=0
-+	lea	4*8($aptr),$aptr
-+	lea	4*8($tptr),$tptr
-+	adcx	$zero,%r14		# cf=0
-+
-+	adox	%r15,%r10
-+	mulx	0*8($nptr),%rax,%r15
-+	adcx	%rax,%r10
-+	adox	%r15,%r11
-+	mulx	1*8($nptr),%rax,%r15
-+	adcx	%rax,%r11
-+	adox	%r15,%r12
-+	mulx	2*8($nptr),%rax,%r15
-+	mov	%r10,-5*8($tptr)
-+	adcx	%rax,%r12
-+	adox	%r15,%r13
-+	mov	%r11,-4*8($tptr)
-+	mulx	3*8($nptr),%rax,%r15
-+	 mov	$bi,%rdx
-+	lea	4*8($nptr),$nptr
-+	mov	%r12,-3*8($tptr)
-+	adcx	%rax,%r13
-+	adox	$zero,%r15
-+	mov	%r13,-2*8($tptr)
-+
-+	dec	$bptr			# of=0, pass cf
-+	jnz	.Lmulx4x_inner
-+
-+	mov	0+8(%rsp),$num		# load -num
-+	adc	$zero,%r15		# modulo-scheduled
-+	sub	0*8($tptr),$bptr	# pull top-most carry to %cf
-+	mov	8+8(%rsp),$bptr		# re-load &b[i]
-+	mov	16+8(%rsp),%r10
-+	adc	%r15,%r14
-+	lea	($aptr,$num),$aptr	# rewind $aptr
-+	adc	$zero,$zero		# top-most carry
-+	mov	%r14,-1*8($tptr)
-+
-+	cmp	%r10,$bptr
-+	jb	.Lmulx4x_outer
-+
-+	mov	-8($nptr),%r10
-+	mov	$zero,%r8
-+	mov	($nptr,$num),%r12
-+	lea	($nptr,$num),%rbp	# rewind $nptr
-+	mov	$num,%rcx
-+	lea	($tptr,$num),%rdi	# rewind $tptr
-+	xor	%eax,%eax
-+	xor	%r15,%r15
-+	sub	%r14,%r10		# compare top-most words
-+	adc	%r15,%r15
-+	or	%r15,%r8
-+	sar	\$3+2,%rcx
-+	sub	%r8,%rax		# %rax=-%r8
-+	mov	56+8(%rsp),%rdx		# restore rp
-+	dec	%r12			# so that after 'not' we get -n[0]
-+	mov	8*1(%rbp),%r13
-+	xor	%r8,%r8
-+	mov	8*2(%rbp),%r14
-+	mov	8*3(%rbp),%r15
-+	jmp	.Lsqrx4x_sub_entry	# common post-condition
-+.size	mulx4x_internal,.-mulx4x_internal
-+___
-+}{
-+######################################################################
-+# void bn_power5(
-+my $rptr="%rdi";	# BN_ULONG *rptr,
-+my $aptr="%rsi";	# const BN_ULONG *aptr,
-+my $bptr="%rdx";	# const void *table,
-+my $nptr="%rcx";	# const BN_ULONG *nptr,
-+my $n0  ="%r8";		# const BN_ULONG *n0);
-+my $num ="%r9";		# int num, has to be divisible by 8
-+			# int pwr);
-+
-+my ($i,$j,$tptr)=("%rbp","%rcx",$rptr);
-+my @A0=("%r10","%r11");
-+my @A1=("%r12","%r13");
-+my ($a0,$a1,$ai)=("%r14","%r15","%rbx");
-+
-+$code.=<<___;
-+.type	bn_powerx5,\@function,6
-+.align	32
-+bn_powerx5:
-+	mov	%rsp,%rax
-+.Lpowerx5_enter:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lpowerx5_prologue:
-+
-+	shl	\$3,${num}d		# convert $num to bytes
-+	lea	($num,$num,2),%r10	# 3*$num in bytes
-+	neg	$num
-+	mov	($n0),$n0		# *n0
-+
-+	##############################################################
-+	# Ensure that stack frame doesn't alias with $rptr+3*$num
-+	# modulo 4096, which covers ret[num], am[num] and n[num]
-+	# (see bn_exp.c). This is done to allow memory disambiguation
-+	# logic do its magic. [Extra 256 bytes is for power mask
-+	# calculated from 7th argument, the index.]
-+	#
-+	lea	-320(%rsp,$num,2),%r11
-+	mov	%rsp,%rbp
-+	sub	$rptr,%r11
-+	and	\$4095,%r11
-+	cmp	%r11,%r10
-+	jb	.Lpwrx_sp_alt
-+	sub	%r11,%rbp		# align with $aptr
-+	lea	-320(%rbp,$num,2),%rbp	# future alloca(frame+2*$num*8+256)
-+	jmp	.Lpwrx_sp_done
-+
-+.align	32
-+.Lpwrx_sp_alt:
-+	lea	4096-320(,$num,2),%r10
-+	lea	-320(%rbp,$num,2),%rbp	# alloca(frame+2*$num*8+256)
-+	sub	%r10,%r11
-+	mov	\$0,%r10
-+	cmovc	%r10,%r11
-+	sub	%r11,%rbp
-+.Lpwrx_sp_done:
-+	and	\$-64,%rbp
-+	mov	%rsp,%r11
-+	sub	%rbp,%r11
-+	and	\$-4096,%r11
-+	lea	(%rbp,%r11),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lpwrx_page_walk
-+	jmp	.Lpwrx_page_walk_done
-+
-+.Lpwrx_page_walk:
-+	lea	-4096(%rsp),%rsp
-+	mov	(%rsp),%r10
-+	cmp	%rbp,%rsp
-+	ja	.Lpwrx_page_walk
-+.Lpwrx_page_walk_done:
-+
-+	mov	$num,%r10	
-+	neg	$num
-+
-+	##############################################################
-+	# Stack layout
-+	#
-+	# +0	saved $num, used in reduction section
-+	# +8	&t[2*$num], used in reduction section
-+	# +16	intermediate carry bit
-+	# +24	top-most carry bit, used in reduction section
-+	# +32	saved *n0
-+	# +40	saved %rsp
-+	# +48	t[2*$num]
-+	#
-+	pxor	%xmm0,%xmm0
-+	movq	$rptr,%xmm1		# save $rptr
-+	movq	$nptr,%xmm2		# save $nptr
-+	movq	%r10, %xmm3		# -$num
-+	movq	$bptr,%xmm4
-+	mov	$n0,  32(%rsp)
-+	mov	%rax, 40(%rsp)		# save original %rsp
-+.Lpowerx5_body:
-+
-+	call	__bn_sqrx8x_internal
-+	call	__bn_postx4x_internal
-+	call	__bn_sqrx8x_internal
-+	call	__bn_postx4x_internal
-+	call	__bn_sqrx8x_internal
-+	call	__bn_postx4x_internal
-+	call	__bn_sqrx8x_internal
-+	call	__bn_postx4x_internal
-+	call	__bn_sqrx8x_internal
-+	call	__bn_postx4x_internal
-+
-+	mov	%r10,$num		# -num
-+	mov	$aptr,$rptr
-+	movq	%xmm2,$nptr
-+	movq	%xmm4,$bptr
-+	mov	40(%rsp),%rax
-+
-+	call	mulx4x_internal
-+
-+	mov	40(%rsp),%rsi		# restore %rsp
-+	mov	\$1,%rax
-+
-+	mov	-48(%rsi),%r15
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lpowerx5_epilogue:
-+	ret
-+.size	bn_powerx5,.-bn_powerx5
-+
-+.globl	bn_sqrx8x_internal
-+.hidden	bn_sqrx8x_internal
-+.type	bn_sqrx8x_internal,\@abi-omnipotent
-+.align	32
-+bn_sqrx8x_internal:
-+__bn_sqrx8x_internal:
-+	##################################################################
-+	# Squaring part:
-+	#
-+	# a) multiply-n-add everything but a[i]*a[i];
-+	# b) shift result of a) by 1 to the left and accumulate
-+	#    a[i]*a[i] products;
-+	#
-+	##################################################################
-+	# a[7]a[7]a[6]a[6]a[5]a[5]a[4]a[4]a[3]a[3]a[2]a[2]a[1]a[1]a[0]a[0]
-+	#                                                     a[1]a[0]
-+	#                                                 a[2]a[0]
-+	#                                             a[3]a[0]
-+	#                                             a[2]a[1]
-+	#                                         a[3]a[1]
-+	#                                     a[3]a[2]
-+	#
-+	#                                         a[4]a[0]
-+	#                                     a[5]a[0]
-+	#                                 a[6]a[0]
-+	#                             a[7]a[0]
-+	#                                     a[4]a[1]
-+	#                                 a[5]a[1]
-+	#                             a[6]a[1]
-+	#                         a[7]a[1]
-+	#                                 a[4]a[2]
-+	#                             a[5]a[2]
-+	#                         a[6]a[2]
-+	#                     a[7]a[2]
-+	#                             a[4]a[3]
-+	#                         a[5]a[3]
-+	#                     a[6]a[3]
-+	#                 a[7]a[3]
-+	#
-+	#                     a[5]a[4]
-+	#                 a[6]a[4]
-+	#             a[7]a[4]
-+	#             a[6]a[5]
-+	#         a[7]a[5]
-+	#     a[7]a[6]
-+	# a[7]a[7]a[6]a[6]a[5]a[5]a[4]a[4]a[3]a[3]a[2]a[2]a[1]a[1]a[0]a[0]
-+___
-+{
-+my ($zero,$carry)=("%rbp","%rcx");
-+my $aaptr=$zero;
-+$code.=<<___;
-+	lea	48+8(%rsp),$tptr
-+	lea	($aptr,$num),$aaptr
-+	mov	$num,0+8(%rsp)			# save $num
-+	mov	$aaptr,8+8(%rsp)		# save end of $aptr
-+	jmp	.Lsqr8x_zero_start
-+
-+.align	32
-+.byte	0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00
-+.Lsqrx8x_zero:
-+	.byte	0x3e
-+	movdqa	%xmm0,0*8($tptr)
-+	movdqa	%xmm0,2*8($tptr)
-+	movdqa	%xmm0,4*8($tptr)
-+	movdqa	%xmm0,6*8($tptr)
-+.Lsqr8x_zero_start:			# aligned at 32
-+	movdqa	%xmm0,8*8($tptr)
-+	movdqa	%xmm0,10*8($tptr)
-+	movdqa	%xmm0,12*8($tptr)
-+	movdqa	%xmm0,14*8($tptr)
-+	lea	16*8($tptr),$tptr
-+	sub	\$64,$num
-+	jnz	.Lsqrx8x_zero
-+
-+	mov	0*8($aptr),%rdx		# a[0], modulo-scheduled
-+	#xor	%r9,%r9			# t[1], ex-$num, zero already
-+	xor	%r10,%r10
-+	xor	%r11,%r11
-+	xor	%r12,%r12
-+	xor	%r13,%r13
-+	xor	%r14,%r14
-+	xor	%r15,%r15
-+	lea	48+8(%rsp),$tptr
-+	xor	$zero,$zero		# cf=0, cf=0
-+	jmp	.Lsqrx8x_outer_loop
-+
-+.align	32
-+.Lsqrx8x_outer_loop:
-+	mulx	1*8($aptr),%r8,%rax	# a[1]*a[0]
-+	adcx	%r9,%r8			# a[1]*a[0]+=t[1]
-+	adox	%rax,%r10
-+	mulx	2*8($aptr),%r9,%rax	# a[2]*a[0]
-+	adcx	%r10,%r9
-+	adox	%rax,%r11
-+	.byte	0xc4,0xe2,0xab,0xf6,0x86,0x18,0x00,0x00,0x00	# mulx	3*8($aptr),%r10,%rax	# ...
-+	adcx	%r11,%r10
-+	adox	%rax,%r12
-+	.byte	0xc4,0xe2,0xa3,0xf6,0x86,0x20,0x00,0x00,0x00	# mulx	4*8($aptr),%r11,%rax
-+	adcx	%r12,%r11
-+	adox	%rax,%r13
-+	mulx	5*8($aptr),%r12,%rax
-+	adcx	%r13,%r12
-+	adox	%rax,%r14
-+	mulx	6*8($aptr),%r13,%rax
-+	adcx	%r14,%r13
-+	adox	%r15,%rax
-+	mulx	7*8($aptr),%r14,%r15
-+	 mov	1*8($aptr),%rdx		# a[1]
-+	adcx	%rax,%r14
-+	adox	$zero,%r15
-+	adc	8*8($tptr),%r15
-+	mov	%r8,1*8($tptr)		# t[1]
-+	mov	%r9,2*8($tptr)		# t[2]
-+	sbb	$carry,$carry		# mov %cf,$carry
-+	xor	$zero,$zero		# cf=0, of=0
-+
-+
-+	mulx	2*8($aptr),%r8,%rbx	# a[2]*a[1]
-+	mulx	3*8($aptr),%r9,%rax	# a[3]*a[1]
-+	adcx	%r10,%r8
-+	adox	%rbx,%r9
-+	mulx	4*8($aptr),%r10,%rbx	# ...
-+	adcx	%r11,%r9
-+	adox	%rax,%r10
-+	.byte	0xc4,0xe2,0xa3,0xf6,0x86,0x28,0x00,0x00,0x00	# mulx	5*8($aptr),%r11,%rax
-+	adcx	%r12,%r10
-+	adox	%rbx,%r11
-+	.byte	0xc4,0xe2,0x9b,0xf6,0x9e,0x30,0x00,0x00,0x00	# mulx	6*8($aptr),%r12,%rbx
-+	adcx	%r13,%r11
-+	adox	%r14,%r12
-+	.byte	0xc4,0x62,0x93,0xf6,0xb6,0x38,0x00,0x00,0x00	# mulx	7*8($aptr),%r13,%r14
-+	 mov	2*8($aptr),%rdx		# a[2]
-+	adcx	%rax,%r12
-+	adox	%rbx,%r13
-+	adcx	%r15,%r13
-+	adox	$zero,%r14		# of=0
-+	adcx	$zero,%r14		# cf=0
-+
-+	mov	%r8,3*8($tptr)		# t[3]
-+	mov	%r9,4*8($tptr)		# t[4]
-+
-+	mulx	3*8($aptr),%r8,%rbx	# a[3]*a[2]
-+	mulx	4*8($aptr),%r9,%rax	# a[4]*a[2]
-+	adcx	%r10,%r8
-+	adox	%rbx,%r9
-+	mulx	5*8($aptr),%r10,%rbx	# ...
-+	adcx	%r11,%r9
-+	adox	%rax,%r10
-+	.byte	0xc4,0xe2,0xa3,0xf6,0x86,0x30,0x00,0x00,0x00	# mulx	6*8($aptr),%r11,%rax
-+	adcx	%r12,%r10
-+	adox	%r13,%r11
-+	.byte	0xc4,0x62,0x9b,0xf6,0xae,0x38,0x00,0x00,0x00	# mulx	7*8($aptr),%r12,%r13
-+	.byte	0x3e
-+	 mov	3*8($aptr),%rdx		# a[3]
-+	adcx	%rbx,%r11
-+	adox	%rax,%r12
-+	adcx	%r14,%r12
-+	mov	%r8,5*8($tptr)		# t[5]
-+	mov	%r9,6*8($tptr)		# t[6]
-+	 mulx	4*8($aptr),%r8,%rax	# a[4]*a[3]
-+	adox	$zero,%r13		# of=0
-+	adcx	$zero,%r13		# cf=0
-+
-+	mulx	5*8($aptr),%r9,%rbx	# a[5]*a[3]
-+	adcx	%r10,%r8
-+	adox	%rax,%r9
-+	mulx	6*8($aptr),%r10,%rax	# ...
-+	adcx	%r11,%r9
-+	adox	%r12,%r10
-+	mulx	7*8($aptr),%r11,%r12
-+	 mov	4*8($aptr),%rdx		# a[4]
-+	 mov	5*8($aptr),%r14		# a[5]
-+	adcx	%rbx,%r10
-+	adox	%rax,%r11
-+	 mov	6*8($aptr),%r15		# a[6]
-+	adcx	%r13,%r11
-+	adox	$zero,%r12		# of=0
-+	adcx	$zero,%r12		# cf=0
-+
-+	mov	%r8,7*8($tptr)		# t[7]
-+	mov	%r9,8*8($tptr)		# t[8]
-+
-+	mulx	%r14,%r9,%rax		# a[5]*a[4]
-+	 mov	7*8($aptr),%r8		# a[7]
-+	adcx	%r10,%r9
-+	mulx	%r15,%r10,%rbx		# a[6]*a[4]
-+	adox	%rax,%r10
-+	adcx	%r11,%r10
-+	mulx	%r8,%r11,%rax		# a[7]*a[4]
-+	 mov	%r14,%rdx		# a[5]
-+	adox	%rbx,%r11
-+	adcx	%r12,%r11
-+	#adox	$zero,%rax		# of=0
-+	adcx	$zero,%rax		# cf=0
-+
-+	mulx	%r15,%r14,%rbx		# a[6]*a[5]
-+	mulx	%r8,%r12,%r13		# a[7]*a[5]
-+	 mov	%r15,%rdx		# a[6]
-+	 lea	8*8($aptr),$aptr
-+	adcx	%r14,%r11
-+	adox	%rbx,%r12
-+	adcx	%rax,%r12
-+	adox	$zero,%r13
-+
-+	.byte	0x67,0x67
-+	mulx	%r8,%r8,%r14		# a[7]*a[6]
-+	adcx	%r8,%r13
-+	adcx	$zero,%r14
-+
-+	cmp	8+8(%rsp),$aptr
-+	je	.Lsqrx8x_outer_break
-+
-+	neg	$carry			# mov $carry,%cf
-+	mov	\$-8,%rcx
-+	mov	$zero,%r15
-+	mov	8*8($tptr),%r8
-+	adcx	9*8($tptr),%r9		# +=t[9]
-+	adcx	10*8($tptr),%r10	# ...
-+	adcx	11*8($tptr),%r11
-+	adc	12*8($tptr),%r12
-+	adc	13*8($tptr),%r13
-+	adc	14*8($tptr),%r14
-+	adc	15*8($tptr),%r15
-+	lea	($aptr),$aaptr
-+	lea	2*64($tptr),$tptr
-+	sbb	%rax,%rax		# mov %cf,$carry
-+
-+	mov	-64($aptr),%rdx		# a[0]
-+	mov	%rax,16+8(%rsp)		# offload $carry
-+	mov	$tptr,24+8(%rsp)
-+
-+	#lea	8*8($tptr),$tptr	# see 2*8*8($tptr) above
-+	xor	%eax,%eax		# cf=0, of=0
-+	jmp	.Lsqrx8x_loop
-+
-+.align	32
-+.Lsqrx8x_loop:
-+	mov	%r8,%rbx
-+	mulx	0*8($aaptr),%rax,%r8	# a[8]*a[i]
-+	adcx	%rax,%rbx		# +=t[8]
-+	adox	%r9,%r8
-+
-+	mulx	1*8($aaptr),%rax,%r9	# ...
-+	adcx	%rax,%r8
-+	adox	%r10,%r9
-+
-+	mulx	2*8($aaptr),%rax,%r10
-+	adcx	%rax,%r9
-+	adox	%r11,%r10
-+
-+	mulx	3*8($aaptr),%rax,%r11
-+	adcx	%rax,%r10
-+	adox	%r12,%r11
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00	# mulx	4*8($aaptr),%rax,%r12
-+	adcx	%rax,%r11
-+	adox	%r13,%r12
-+
-+	mulx	5*8($aaptr),%rax,%r13
-+	adcx	%rax,%r12
-+	adox	%r14,%r13
-+
-+	mulx	6*8($aaptr),%rax,%r14
-+	 mov	%rbx,($tptr,%rcx,8)	# store t[8+i]
-+	 mov	\$0,%ebx
-+	adcx	%rax,%r13
-+	adox	%r15,%r14
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0xbd,0x38,0x00,0x00,0x00	# mulx	7*8($aaptr),%rax,%r15
-+	 mov	8($aptr,%rcx,8),%rdx	# a[i]
-+	adcx	%rax,%r14
-+	adox	%rbx,%r15		# %rbx is 0, of=0
-+	adcx	%rbx,%r15		# cf=0
-+
-+	.byte	0x67
-+	inc	%rcx			# of=0
-+	jnz	.Lsqrx8x_loop
-+
-+	lea	8*8($aaptr),$aaptr
-+	mov	\$-8,%rcx
-+	cmp	8+8(%rsp),$aaptr	# done?
-+	je	.Lsqrx8x_break
-+
-+	sub	16+8(%rsp),%rbx		# mov 16(%rsp),%cf
-+	.byte	0x66
-+	mov	-64($aptr),%rdx
-+	adcx	0*8($tptr),%r8
-+	adcx	1*8($tptr),%r9
-+	adc	2*8($tptr),%r10
-+	adc	3*8($tptr),%r11
-+	adc	4*8($tptr),%r12
-+	adc	5*8($tptr),%r13
-+	adc	6*8($tptr),%r14
-+	adc	7*8($tptr),%r15
-+	lea	8*8($tptr),$tptr
-+	.byte	0x67
-+	sbb	%rax,%rax		# mov %cf,%rax
-+	xor	%ebx,%ebx		# cf=0, of=0
-+	mov	%rax,16+8(%rsp)		# offload carry
-+	jmp	.Lsqrx8x_loop
-+
-+.align	32
-+.Lsqrx8x_break:
-+	sub	16+8(%rsp),%r8		# consume last carry
-+	mov	24+8(%rsp),$carry	# initial $tptr, borrow $carry
-+	mov	0*8($aptr),%rdx		# a[8], modulo-scheduled
-+	xor	%ebp,%ebp		# xor	$zero,$zero
-+	mov	%r8,0*8($tptr)
-+	cmp	$carry,$tptr		# cf=0, of=0
-+	je	.Lsqrx8x_outer_loop
-+
-+	mov	%r9,1*8($tptr)
-+	 mov	1*8($carry),%r9
-+	mov	%r10,2*8($tptr)
-+	 mov	2*8($carry),%r10
-+	mov	%r11,3*8($tptr)
-+	 mov	3*8($carry),%r11
-+	mov	%r12,4*8($tptr)
-+	 mov	4*8($carry),%r12
-+	mov	%r13,5*8($tptr)
-+	 mov	5*8($carry),%r13
-+	mov	%r14,6*8($tptr)
-+	 mov	6*8($carry),%r14
-+	mov	%r15,7*8($tptr)
-+	 mov	7*8($carry),%r15
-+	mov	$carry,$tptr
-+	jmp	.Lsqrx8x_outer_loop
-+
-+.align	32
-+.Lsqrx8x_outer_break:
-+	mov	%r9,9*8($tptr)		# t[9]
-+	 movq	%xmm3,%rcx		# -$num
-+	mov	%r10,10*8($tptr)	# ...
-+	mov	%r11,11*8($tptr)
-+	mov	%r12,12*8($tptr)
-+	mov	%r13,13*8($tptr)
-+	mov	%r14,14*8($tptr)
-+___
-+}{
-+my $i="%rcx";
-+$code.=<<___;
-+	lea	48+8(%rsp),$tptr
-+	mov	($aptr,$i),%rdx		# a[0]
-+
-+	mov	8($tptr),$A0[1]		# t[1]
-+	xor	$A0[0],$A0[0]		# t[0], of=0, cf=0
-+	mov	0+8(%rsp),$num		# restore $num
-+	adox	$A0[1],$A0[1]
-+	 mov	16($tptr),$A1[0]	# t[2]	# prefetch
-+	 mov	24($tptr),$A1[1]	# t[3]	# prefetch
-+	#jmp	.Lsqrx4x_shift_n_add	# happens to be aligned
-+
-+.align	32
-+.Lsqrx4x_shift_n_add:
-+	mulx	%rdx,%rax,%rbx
-+	 adox	$A1[0],$A1[0]
-+	adcx	$A0[0],%rax
-+	 .byte	0x48,0x8b,0x94,0x0e,0x08,0x00,0x00,0x00	# mov	8($aptr,$i),%rdx	# a[i+1]	# prefetch
-+	 .byte	0x4c,0x8b,0x97,0x20,0x00,0x00,0x00	# mov	32($tptr),$A0[0]	# t[2*i+4]	# prefetch
-+	 adox	$A1[1],$A1[1]
-+	adcx	$A0[1],%rbx
-+	 mov	40($tptr),$A0[1]		# t[2*i+4+1]	# prefetch
-+	mov	%rax,0($tptr)
-+	mov	%rbx,8($tptr)
-+
-+	mulx	%rdx,%rax,%rbx
-+	 adox	$A0[0],$A0[0]
-+	adcx	$A1[0],%rax
-+	 mov	16($aptr,$i),%rdx	# a[i+2]	# prefetch
-+	 mov	48($tptr),$A1[0]	# t[2*i+6]	# prefetch
-+	 adox	$A0[1],$A0[1]
-+	adcx	$A1[1],%rbx
-+	 mov	56($tptr),$A1[1]	# t[2*i+6+1]	# prefetch
-+	mov	%rax,16($tptr)
-+	mov	%rbx,24($tptr)
-+
-+	mulx	%rdx,%rax,%rbx
-+	 adox	$A1[0],$A1[0]
-+	adcx	$A0[0],%rax
-+	 mov	24($aptr,$i),%rdx	# a[i+3]	# prefetch
-+	 lea	32($i),$i
-+	 mov	64($tptr),$A0[0]	# t[2*i+8]	# prefetch
-+	 adox	$A1[1],$A1[1]
-+	adcx	$A0[1],%rbx
-+	 mov	72($tptr),$A0[1]	# t[2*i+8+1]	# prefetch
-+	mov	%rax,32($tptr)
-+	mov	%rbx,40($tptr)
-+
-+	mulx	%rdx,%rax,%rbx
-+	 adox	$A0[0],$A0[0]
-+	adcx	$A1[0],%rax
-+	jrcxz	.Lsqrx4x_shift_n_add_break
-+	 .byte	0x48,0x8b,0x94,0x0e,0x00,0x00,0x00,0x00	# mov	0($aptr,$i),%rdx	# a[i+4]	# prefetch
-+	 adox	$A0[1],$A0[1]
-+	adcx	$A1[1],%rbx
-+	 mov	80($tptr),$A1[0]	# t[2*i+10]	# prefetch
-+	 mov	88($tptr),$A1[1]	# t[2*i+10+1]	# prefetch
-+	mov	%rax,48($tptr)
-+	mov	%rbx,56($tptr)
-+	lea	64($tptr),$tptr
-+	nop
-+	jmp	.Lsqrx4x_shift_n_add
-+
-+.align	32
-+.Lsqrx4x_shift_n_add_break:
-+	adcx	$A1[1],%rbx
-+	mov	%rax,48($tptr)
-+	mov	%rbx,56($tptr)
-+	lea	64($tptr),$tptr		# end of t[] buffer
-+___
-+}
-+######################################################################
-+# Montgomery reduction part, "word-by-word" algorithm.
-+#
-+# This new path is inspired by multiple submissions from Intel, by
-+# Shay Gueron, Vlad Krasnov, Erdinc Ozturk, James Guilford,
-+# Vinodh Gopal...
-+{
-+my ($nptr,$carry,$m0)=("%rbp","%rsi","%rdx");
-+
-+$code.=<<___;
-+	movq	%xmm2,$nptr
-+__bn_sqrx8x_reduction:
-+	xor	%eax,%eax		# initial top-most carry bit
-+	mov	32+8(%rsp),%rbx		# n0
-+	mov	48+8(%rsp),%rdx		# "%r8", 8*0($tptr)
-+	lea	-8*8($nptr,$num),%rcx	# end of n[]
-+	#lea	48+8(%rsp,$num,2),$tptr	# end of t[] buffer
-+	mov	%rcx, 0+8(%rsp)		# save end of n[]
-+	mov	$tptr,8+8(%rsp)		# save end of t[]
-+
-+	lea	48+8(%rsp),$tptr		# initial t[] window
-+	jmp	.Lsqrx8x_reduction_loop
-+
-+.align	32
-+.Lsqrx8x_reduction_loop:
-+	mov	8*1($tptr),%r9
-+	mov	8*2($tptr),%r10
-+	mov	8*3($tptr),%r11
-+	mov	8*4($tptr),%r12
-+	mov	%rdx,%r8
-+	imulq	%rbx,%rdx		# n0*a[i]
-+	mov	8*5($tptr),%r13
-+	mov	8*6($tptr),%r14
-+	mov	8*7($tptr),%r15
-+	mov	%rax,24+8(%rsp)		# store top-most carry bit
-+
-+	lea	8*8($tptr),$tptr
-+	xor	$carry,$carry		# cf=0,of=0
-+	mov	\$-8,%rcx
-+	jmp	.Lsqrx8x_reduce
-+
-+.align	32
-+.Lsqrx8x_reduce:
-+	mov	%r8, %rbx
-+	mulx	8*0($nptr),%rax,%r8	# n[0]
-+	adcx	%rbx,%rax		# discarded
-+	adox	%r9,%r8
-+
-+	mulx	8*1($nptr),%rbx,%r9	# n[1]
-+	adcx	%rbx,%r8
-+	adox	%r10,%r9
-+
-+	mulx	8*2($nptr),%rbx,%r10
-+	adcx	%rbx,%r9
-+	adox	%r11,%r10
-+
-+	mulx	8*3($nptr),%rbx,%r11
-+	adcx	%rbx,%r10
-+	adox	%r12,%r11
-+
-+	.byte	0xc4,0x62,0xe3,0xf6,0xa5,0x20,0x00,0x00,0x00	# mulx	8*4($nptr),%rbx,%r12
-+	 mov	%rdx,%rax
-+	 mov	%r8,%rdx
-+	adcx	%rbx,%r11
-+	adox	%r13,%r12
-+
-+	 mulx	32+8(%rsp),%rbx,%rdx	# %rdx discarded
-+	 mov	%rax,%rdx
-+	 mov	%rax,64+48+8(%rsp,%rcx,8)	# put aside n0*a[i]
-+
-+	mulx	8*5($nptr),%rax,%r13
-+	adcx	%rax,%r12
-+	adox	%r14,%r13
-+
-+	mulx	8*6($nptr),%rax,%r14
-+	adcx	%rax,%r13
-+	adox	%r15,%r14
-+
-+	mulx	8*7($nptr),%rax,%r15
-+	 mov	%rbx,%rdx
-+	adcx	%rax,%r14
-+	adox	$carry,%r15		# $carry is 0
-+	adcx	$carry,%r15		# cf=0
-+
-+	.byte	0x67,0x67,0x67
-+	inc	%rcx			# of=0
-+	jnz	.Lsqrx8x_reduce
-+
-+	mov	$carry,%rax		# xor	%rax,%rax
-+	cmp	0+8(%rsp),$nptr		# end of n[]?
-+	jae	.Lsqrx8x_no_tail
-+
-+	mov	48+8(%rsp),%rdx		# pull n0*a[0]
-+	add	8*0($tptr),%r8
-+	lea	8*8($nptr),$nptr
-+	mov	\$-8,%rcx
-+	adcx	8*1($tptr),%r9
-+	adcx	8*2($tptr),%r10
-+	adc	8*3($tptr),%r11
-+	adc	8*4($tptr),%r12
-+	adc	8*5($tptr),%r13
-+	adc	8*6($tptr),%r14
-+	adc	8*7($tptr),%r15
-+	lea	8*8($tptr),$tptr
-+	sbb	%rax,%rax		# top carry
-+
-+	xor	$carry,$carry		# of=0, cf=0
-+	mov	%rax,16+8(%rsp)
-+	jmp	.Lsqrx8x_tail
-+
-+.align	32
-+.Lsqrx8x_tail:
-+	mov	%r8,%rbx
-+	mulx	8*0($nptr),%rax,%r8
-+	adcx	%rax,%rbx
-+	adox	%r9,%r8
-+
-+	mulx	8*1($nptr),%rax,%r9
-+	adcx	%rax,%r8
-+	adox	%r10,%r9
-+
-+	mulx	8*2($nptr),%rax,%r10
-+	adcx	%rax,%r9
-+	adox	%r11,%r10
-+
-+	mulx	8*3($nptr),%rax,%r11
-+	adcx	%rax,%r10
-+	adox	%r12,%r11
-+
-+	.byte	0xc4,0x62,0xfb,0xf6,0xa5,0x20,0x00,0x00,0x00	# mulx	8*4($nptr),%rax,%r12
-+	adcx	%rax,%r11
-+	adox	%r13,%r12
-+
-+	mulx	8*5($nptr),%rax,%r13
-+	adcx	%rax,%r12
-+	adox	%r14,%r13
-+
-+	mulx	8*6($nptr),%rax,%r14
-+	adcx	%rax,%r13
-+	adox	%r15,%r14
-+
-+	mulx	8*7($nptr),%rax,%r15
-+	 mov	72+48+8(%rsp,%rcx,8),%rdx	# pull n0*a[i]
-+	adcx	%rax,%r14
-+	adox	$carry,%r15
-+	 mov	%rbx,($tptr,%rcx,8)	# save result
-+	 mov	%r8,%rbx
-+	adcx	$carry,%r15		# cf=0
-+
-+	inc	%rcx			# of=0
-+	jnz	.Lsqrx8x_tail
-+
-+	cmp	0+8(%rsp),$nptr		# end of n[]?
-+	jae	.Lsqrx8x_tail_done	# break out of loop
-+
-+	sub	16+8(%rsp),$carry	# mov 16(%rsp),%cf
-+	 mov	48+8(%rsp),%rdx		# pull n0*a[0]
-+	 lea	8*8($nptr),$nptr
-+	adc	8*0($tptr),%r8
-+	adc	8*1($tptr),%r9
-+	adc	8*2($tptr),%r10
-+	adc	8*3($tptr),%r11
-+	adc	8*4($tptr),%r12
-+	adc	8*5($tptr),%r13
-+	adc	8*6($tptr),%r14
-+	adc	8*7($tptr),%r15
-+	lea	8*8($tptr),$tptr
-+	sbb	%rax,%rax
-+	sub	\$8,%rcx		# mov	\$-8,%rcx
-+
-+	xor	$carry,$carry		# of=0, cf=0
-+	mov	%rax,16+8(%rsp)
-+	jmp	.Lsqrx8x_tail
-+
-+.align	32
-+.Lsqrx8x_tail_done:
-+	xor	%rax,%rax
-+	add	24+8(%rsp),%r8		# can this overflow?
-+	adc	\$0,%r9
-+	adc	\$0,%r10
-+	adc	\$0,%r11
-+	adc	\$0,%r12
-+	adc	\$0,%r13
-+	adc	\$0,%r14
-+	adc	\$0,%r15
-+	adc	\$0,%rax
-+
-+	sub	16+8(%rsp),$carry	# mov 16(%rsp),%cf
-+.Lsqrx8x_no_tail:			# %cf is 0 if jumped here
-+	adc	8*0($tptr),%r8
-+	 movq	%xmm3,%rcx
-+	adc	8*1($tptr),%r9
-+	 mov	8*7($nptr),$carry
-+	 movq	%xmm2,$nptr		# restore $nptr
-+	adc	8*2($tptr),%r10
-+	adc	8*3($tptr),%r11
-+	adc	8*4($tptr),%r12
-+	adc	8*5($tptr),%r13
-+	adc	8*6($tptr),%r14
-+	adc	8*7($tptr),%r15
-+	adc	\$0,%rax		# top-most carry
-+
-+	mov	32+8(%rsp),%rbx		# n0
-+	mov	8*8($tptr,%rcx),%rdx	# modulo-scheduled "%r8"
-+
-+	mov	%r8,8*0($tptr)		# store top 512 bits
-+	 lea	8*8($tptr),%r8		# borrow %r8
-+	mov	%r9,8*1($tptr)
-+	mov	%r10,8*2($tptr)
-+	mov	%r11,8*3($tptr)
-+	mov	%r12,8*4($tptr)
-+	mov	%r13,8*5($tptr)
-+	mov	%r14,8*6($tptr)
-+	mov	%r15,8*7($tptr)
-+
-+	lea	8*8($tptr,%rcx),$tptr	# start of current t[] window
-+	cmp	8+8(%rsp),%r8		# end of t[]?
-+	jb	.Lsqrx8x_reduction_loop
-+	ret
-+.size	bn_sqrx8x_internal,.-bn_sqrx8x_internal
-+___
-+}
-+##############################################################
-+# Post-condition, 4x unrolled
-+#
-+{
-+my ($rptr,$nptr)=("%rdx","%rbp");
-+$code.=<<___;
-+.align	32
-+__bn_postx4x_internal:
-+	mov	8*0($nptr),%r12
-+	mov	%rcx,%r10		# -$num
-+	mov	%rcx,%r9		# -$num
-+	neg	%rax
-+	sar	\$3+2,%rcx
-+	#lea	48+8(%rsp,%r9),$tptr
-+	movq	%xmm1,$rptr		# restore $rptr
-+	movq	%xmm1,$aptr		# prepare for back-to-back call
-+	dec	%r12			# so that after 'not' we get -n[0]
-+	mov	8*1($nptr),%r13
-+	xor	%r8,%r8
-+	mov	8*2($nptr),%r14
-+	mov	8*3($nptr),%r15
-+	jmp	.Lsqrx4x_sub_entry
-+
-+.align	16
-+.Lsqrx4x_sub:
-+	mov	8*0($nptr),%r12
-+	mov	8*1($nptr),%r13
-+	mov	8*2($nptr),%r14
-+	mov	8*3($nptr),%r15
-+.Lsqrx4x_sub_entry:
-+	andn	%rax,%r12,%r12
-+	lea	8*4($nptr),$nptr
-+	andn	%rax,%r13,%r13
-+	andn	%rax,%r14,%r14
-+	andn	%rax,%r15,%r15
-+
-+	neg	%r8			# mov %r8,%cf
-+	adc	8*0($tptr),%r12
-+	adc	8*1($tptr),%r13
-+	adc	8*2($tptr),%r14
-+	adc	8*3($tptr),%r15
-+	mov	%r12,8*0($rptr)
-+	lea	8*4($tptr),$tptr
-+	mov	%r13,8*1($rptr)
-+	sbb	%r8,%r8			# mov %cf,%r8
-+	mov	%r14,8*2($rptr)
-+	mov	%r15,8*3($rptr)
-+	lea	8*4($rptr),$rptr
-+
-+	inc	%rcx
-+	jnz	.Lsqrx4x_sub
-+
-+	neg	%r9			# restore $num
-+
-+	ret
-+.size	__bn_postx4x_internal,.-__bn_postx4x_internal
-+___
-+}
-+}}}
-+{
-+my ($inp,$num,$tbl,$idx)=$win64?("%rcx","%edx","%r8", "%r9d") : # Win64 order
-+				("%rdi","%esi","%rdx","%ecx");  # Unix order
-+my $out=$inp;
-+my $STRIDE=2**5*8;
-+my $N=$STRIDE/4;
-+
-+$code.=<<___;
-+.globl	bn_get_bits5
-+.type	bn_get_bits5,\@abi-omnipotent
-+.align	16
-+bn_get_bits5:
-+	lea	0($inp),%r10
-+	lea	1($inp),%r11
-+	mov	$num,%ecx
-+	shr	\$4,$num
-+	and	\$15,%ecx
-+	lea	-8(%ecx),%eax
-+	cmp	\$11,%ecx
-+	cmova	%r11,%r10
-+	cmova	%eax,%ecx
-+	movzw	(%r10,$num,2),%eax
-+	shrl	%cl,%eax
-+	and	\$31,%eax
-+	ret
-+.size	bn_get_bits5,.-bn_get_bits5
-+
-+.globl	bn_scatter5
-+.type	bn_scatter5,\@abi-omnipotent
-+.align	16
-+bn_scatter5:
-+	cmp	\$0, $num
-+	jz	.Lscatter_epilogue
-+	lea	($tbl,$idx,8),$tbl
-+.Lscatter:
-+	mov	($inp),%rax
-+	lea	8($inp),$inp
-+	mov	%rax,($tbl)
-+	lea	32*8($tbl),$tbl
-+	sub	\$1,$num
-+	jnz	.Lscatter
-+.Lscatter_epilogue:
-+	ret
-+.size	bn_scatter5,.-bn_scatter5
-+
-+.globl	bn_gather5
-+.type	bn_gather5,\@abi-omnipotent
-+.align	32
-+bn_gather5:
-+.LSEH_begin_bn_gather5:			# Win64 thing, but harmless in other cases
-+	# I can't trust assembler to use specific encoding:-(
-+	.byte	0x4c,0x8d,0x14,0x24			#lea    (%rsp),%r10
-+	.byte	0x48,0x81,0xec,0x08,0x01,0x00,0x00	#sub	$0x108,%rsp
-+	lea	.Linc(%rip),%rax
-+	and	\$-16,%rsp		# shouldn't be formally required
-+
-+	movd	$idx,%xmm5
-+	movdqa	0(%rax),%xmm0		# 00000001000000010000000000000000
-+	movdqa	16(%rax),%xmm1		# 00000002000000020000000200000002
-+	lea	128($tbl),%r11		# size optimization
-+	lea	128(%rsp),%rax		# size optimization
-+
-+	pshufd	\$0,%xmm5,%xmm5		# broadcast $idx
-+	movdqa	%xmm1,%xmm4
-+	movdqa	%xmm1,%xmm2
-+___
-+########################################################################
-+# calculate mask by comparing 0..31 to $idx and save result to stack
-+#
-+for($i=0;$i<$STRIDE/16;$i+=4) {
-+$code.=<<___;
-+	paddd	%xmm0,%xmm1
-+	pcmpeqd	%xmm5,%xmm0		# compare to 1,0
-+___
-+$code.=<<___	if ($i);
-+	movdqa	%xmm3,`16*($i-1)-128`(%rax)
-+___
-+$code.=<<___;
-+	movdqa	%xmm4,%xmm3
-+
-+	paddd	%xmm1,%xmm2
-+	pcmpeqd	%xmm5,%xmm1		# compare to 3,2
-+	movdqa	%xmm0,`16*($i+0)-128`(%rax)
-+	movdqa	%xmm4,%xmm0
-+
-+	paddd	%xmm2,%xmm3
-+	pcmpeqd	%xmm5,%xmm2		# compare to 5,4
-+	movdqa	%xmm1,`16*($i+1)-128`(%rax)
-+	movdqa	%xmm4,%xmm1
-+
-+	paddd	%xmm3,%xmm0
-+	pcmpeqd	%xmm5,%xmm3		# compare to 7,6
-+	movdqa	%xmm2,`16*($i+2)-128`(%rax)
-+	movdqa	%xmm4,%xmm2
-+___
-+}
-+$code.=<<___;
-+	movdqa	%xmm3,`16*($i-1)-128`(%rax)
-+	jmp	.Lgather
-+
-+.align	32
-+.Lgather:
-+	pxor	%xmm4,%xmm4
-+	pxor	%xmm5,%xmm5
-+___
-+for($i=0;$i<$STRIDE/16;$i+=4) {
-+$code.=<<___;
-+	movdqa	`16*($i+0)-128`(%r11),%xmm0
-+	movdqa	`16*($i+1)-128`(%r11),%xmm1
-+	movdqa	`16*($i+2)-128`(%r11),%xmm2
-+	pand	`16*($i+0)-128`(%rax),%xmm0
-+	movdqa	`16*($i+3)-128`(%r11),%xmm3
-+	pand	`16*($i+1)-128`(%rax),%xmm1
-+	por	%xmm0,%xmm4
-+	pand	`16*($i+2)-128`(%rax),%xmm2
-+	por	%xmm1,%xmm5
-+	pand	`16*($i+3)-128`(%rax),%xmm3
-+	por	%xmm2,%xmm4
-+	por	%xmm3,%xmm5
-+___
-+}
-+$code.=<<___;
-+	por	%xmm5,%xmm4
-+	lea	$STRIDE(%r11),%r11
-+	pshufd	\$0x4e,%xmm4,%xmm0
-+	por	%xmm4,%xmm0
-+	movq	%xmm0,($out)		# m0=bp[0]
-+	lea	8($out),$out
-+	sub	\$1,$num
-+	jnz	.Lgather
-+
-+	lea	(%r10),%rsp
-+	ret
-+.LSEH_end_bn_gather5:
-+.size	bn_gather5,.-bn_gather5
-+___
-+}
-+$code.=<<___;
-+.align	64
-+.Linc:
-+	.long	0,0, 1,1
-+	.long	2,2, 2,2
-+.asciz	"Montgomery Multiplication with scatter/gather for x86_64, CRYPTOGAMS by "
-+___
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	mul_handler,\@abi-omnipotent
-+.align	16
-+mul_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# end of prologue label
-+	cmp	%r10,%rbx		# context->RipRip>=epilogue label
-+	jb	.Lcommon_pop_regs
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	mov	8(%r11),%r10d		# HandlerData[2]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+
-+	lea	.Lmul_epilogue(%rip),%r10
-+	cmp	%r10,%rbx
-+	ja	.Lbody_40
-+
-+	mov	192($context),%r10	# pull $num
-+	mov	8(%rax,%r10,8),%rax	# pull saved stack pointer
-+
-+	jmp	.Lcommon_pop_regs
-+
-+.Lbody_40:
-+	mov	40(%rax),%rax		# pull saved stack pointer
-+.Lcommon_pop_regs:
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lcommon_seh_tail:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	mul_handler,.-mul_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_bn_mul_mont_gather5
-+	.rva	.LSEH_end_bn_mul_mont_gather5
-+	.rva	.LSEH_info_bn_mul_mont_gather5
-+
-+	.rva	.LSEH_begin_bn_mul4x_mont_gather5
-+	.rva	.LSEH_end_bn_mul4x_mont_gather5
-+	.rva	.LSEH_info_bn_mul4x_mont_gather5
-+
-+	.rva	.LSEH_begin_bn_power5
-+	.rva	.LSEH_end_bn_power5
-+	.rva	.LSEH_info_bn_power5
-+
-+	.rva	.LSEH_begin_bn_from_mont8x
-+	.rva	.LSEH_end_bn_from_mont8x
-+	.rva	.LSEH_info_bn_from_mont8x
-+___
-+$code.=<<___ if ($addx);
-+	.rva	.LSEH_begin_bn_mulx4x_mont_gather5
-+	.rva	.LSEH_end_bn_mulx4x_mont_gather5
-+	.rva	.LSEH_info_bn_mulx4x_mont_gather5
-+
-+	.rva	.LSEH_begin_bn_powerx5
-+	.rva	.LSEH_end_bn_powerx5
-+	.rva	.LSEH_info_bn_powerx5
-+___
-+$code.=<<___;
-+	.rva	.LSEH_begin_bn_gather5
-+	.rva	.LSEH_end_bn_gather5
-+	.rva	.LSEH_info_bn_gather5
-+
-+.section	.xdata
-+.align	8
-+.LSEH_info_bn_mul_mont_gather5:
-+	.byte	9,0,0,0
-+	.rva	mul_handler
-+	.rva	.Lmul_body,.Lmul_body,.Lmul_epilogue		# HandlerData[]
-+.align	8
-+.LSEH_info_bn_mul4x_mont_gather5:
-+	.byte	9,0,0,0
-+	.rva	mul_handler
-+	.rva	.Lmul4x_prologue,.Lmul4x_body,.Lmul4x_epilogue		# HandlerData[]
-+.align	8
-+.LSEH_info_bn_power5:
-+	.byte	9,0,0,0
-+	.rva	mul_handler
-+	.rva	.Lpower5_prologue,.Lpower5_body,.Lpower5_epilogue	# HandlerData[]
-+.align	8
-+.LSEH_info_bn_from_mont8x:
-+	.byte	9,0,0,0
-+	.rva	mul_handler
-+	.rva	.Lfrom_prologue,.Lfrom_body,.Lfrom_epilogue		# HandlerData[]
-+___
-+$code.=<<___ if ($addx);
-+.align	8
-+.LSEH_info_bn_mulx4x_mont_gather5:
-+	.byte	9,0,0,0
-+	.rva	mul_handler
-+	.rva	.Lmulx4x_prologue,.Lmulx4x_body,.Lmulx4x_epilogue	# HandlerData[]
-+.align	8
-+.LSEH_info_bn_powerx5:
-+	.byte	9,0,0,0
-+	.rva	mul_handler
-+	.rva	.Lpowerx5_prologue,.Lpowerx5_body,.Lpowerx5_epilogue	# HandlerData[]
-+___
-+$code.=<<___;
-+.align	8
-+.LSEH_info_bn_gather5:
-+	.byte	0x01,0x0b,0x03,0x0a
-+	.byte	0x0b,0x01,0x21,0x00	# sub	rsp,0x108
-+	.byte	0x04,0xa3,0x00,0x00	# lea	r10,(rsp)
-+.align	8
-+___
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_add.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_add.c
-new file mode 100644
-index 0000000..6479650
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_add.c
-@@ -0,0 +1,205 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+/* r can == a or b */
-+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
-+{
-+    int a_neg = a->neg, ret;
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+
-+    /*-
-+     *  a +  b      a+b
-+     *  a + -b      a-b
-+     * -a +  b      b-a
-+     * -a + -b      -(a+b)
-+     */
-+    if (a_neg ^ b->neg) {
-+        /* only one is negative */
-+        if (a_neg) {
-+            const BIGNUM *tmp;
-+
-+            tmp = a;
-+            a = b;
-+            b = tmp;
-+        }
-+
-+        /* we are now a - b */
-+
-+        if (BN_ucmp(a, b) < 0) {
-+            if (!BN_usub(r, b, a))
-+                return 0;
-+            r->neg = 1;
-+        } else {
-+            if (!BN_usub(r, a, b))
-+                return 0;
-+            r->neg = 0;
-+        }
-+        return 1;
-+    }
-+
-+    ret = BN_uadd(r, a, b);
-+    r->neg = a_neg;
-+    bn_check_top(r);
-+    return ret;
-+}
-+
-+/* unsigned add of b to a */
-+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
-+{
-+    int max, min, dif;
-+    const BN_ULONG *ap, *bp;
-+    BN_ULONG *rp, carry, t1, t2;
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+
-+    if (a->top < b->top) {
-+        const BIGNUM *tmp;
-+
-+        tmp = a;
-+        a = b;
-+        b = tmp;
-+    }
-+    max = a->top;
-+    min = b->top;
-+    dif = max - min;
-+
-+    if (bn_wexpand(r, max + 1) == NULL)
-+        return 0;
-+
-+    r->top = max;
-+
-+    ap = a->d;
-+    bp = b->d;
-+    rp = r->d;
-+
-+    carry = bn_add_words(rp, ap, bp, min);
-+    rp += min;
-+    ap += min;
-+
-+    while (dif) {
-+        dif--;
-+        t1 = *(ap++);
-+        t2 = (t1 + carry) & BN_MASK2;
-+        *(rp++) = t2;
-+        carry &= (t2 == 0);
-+    }
-+    *rp = carry;
-+    r->top += carry;
-+
-+    r->neg = 0;
-+    bn_check_top(r);
-+    return 1;
-+}
-+
-+/* unsigned subtraction of b from a, a must be larger than b. */
-+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
-+{
-+    int max, min, dif;
-+    BN_ULONG t1, t2, borrow, *rp;
-+    const BN_ULONG *ap, *bp;
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+
-+    max = a->top;
-+    min = b->top;
-+    dif = max - min;
-+
-+    if (dif < 0) {              /* hmm... should not be happening */
-+        BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3);
-+        return 0;
-+    }
-+
-+    if (bn_wexpand(r, max) == NULL)
-+        return 0;
-+
-+    ap = a->d;
-+    bp = b->d;
-+    rp = r->d;
-+
-+    borrow = bn_sub_words(rp, ap, bp, min);
-+    ap += min;
-+    rp += min;
-+
-+    while (dif) {
-+        dif--;
-+        t1 = *(ap++);
-+        t2 = (t1 - borrow) & BN_MASK2;
-+        *(rp++) = t2;
-+        borrow &= (t1 == 0);
-+    }
-+
-+    r->top = max;
-+    r->neg = 0;
-+    bn_correct_top(r);
-+    return 1;
-+}
-+
-+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
-+{
-+    int max;
-+    int add = 0, neg = 0;
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+
-+    /*-
-+     *  a -  b      a-b
-+     *  a - -b      a+b
-+     * -a -  b      -(a+b)
-+     * -a - -b      b-a
-+     */
-+    if (a->neg) {
-+        if (b->neg) {
-+            const BIGNUM *tmp;
-+
-+            tmp = a;
-+            a = b;
-+            b = tmp;
-+        } else {
-+            add = 1;
-+            neg = 1;
-+        }
-+    } else {
-+        if (b->neg) {
-+            add = 1;
-+            neg = 0;
-+        }
-+    }
-+
-+    if (add) {
-+        if (!BN_uadd(r, a, b))
-+            return 0;
-+        r->neg = neg;
-+        return 1;
-+    }
-+
-+    /* We are actually doing a - b :-) */
-+
-+    max = (a->top > b->top) ? a->top : b->top;
-+    if (bn_wexpand(r, max) == NULL)
-+        return 0;
-+    if (BN_ucmp(a, b) < 0) {
-+        if (!BN_usub(r, b, a))
-+            return 0;
-+        r->neg = 1;
-+    } else {
-+        if (!BN_usub(r, a, b))
-+            return 0;
-+        r->neg = 0;
-+    }
-+    bn_check_top(r);
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_asm.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_asm.c
-new file mode 100644
-index 0000000..39c6c21
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_asm.c
-@@ -0,0 +1,1039 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
-+
-+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
-+                          BN_ULONG w)
-+{
-+    BN_ULONG c1 = 0;
-+
-+    assert(num >= 0);
-+    if (num <= 0)
-+        return (c1);
-+
-+# ifndef OPENSSL_SMALL_FOOTPRINT
-+    while (num & ~3) {
-+        mul_add(rp[0], ap[0], w, c1);
-+        mul_add(rp[1], ap[1], w, c1);
-+        mul_add(rp[2], ap[2], w, c1);
-+        mul_add(rp[3], ap[3], w, c1);
-+        ap += 4;
-+        rp += 4;
-+        num -= 4;
-+    }
-+# endif
-+    while (num) {
-+        mul_add(rp[0], ap[0], w, c1);
-+        ap++;
-+        rp++;
-+        num--;
-+    }
-+
-+    return (c1);
-+}
-+
-+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
-+{
-+    BN_ULONG c1 = 0;
-+
-+    assert(num >= 0);
-+    if (num <= 0)
-+        return (c1);
-+
-+# ifndef OPENSSL_SMALL_FOOTPRINT
-+    while (num & ~3) {
-+        mul(rp[0], ap[0], w, c1);
-+        mul(rp[1], ap[1], w, c1);
-+        mul(rp[2], ap[2], w, c1);
-+        mul(rp[3], ap[3], w, c1);
-+        ap += 4;
-+        rp += 4;
-+        num -= 4;
-+    }
-+# endif
-+    while (num) {
-+        mul(rp[0], ap[0], w, c1);
-+        ap++;
-+        rp++;
-+        num--;
-+    }
-+    return (c1);
-+}
-+
-+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
-+{
-+    assert(n >= 0);
-+    if (n <= 0)
-+        return;
-+
-+# ifndef OPENSSL_SMALL_FOOTPRINT
-+    while (n & ~3) {
-+        sqr(r[0], r[1], a[0]);
-+        sqr(r[2], r[3], a[1]);
-+        sqr(r[4], r[5], a[2]);
-+        sqr(r[6], r[7], a[3]);
-+        a += 4;
-+        r += 8;
-+        n -= 4;
-+    }
-+# endif
-+    while (n) {
-+        sqr(r[0], r[1], a[0]);
-+        a++;
-+        r += 2;
-+        n--;
-+    }
-+}
-+
-+#else                           /* !(defined(BN_LLONG) ||
-+                                 * defined(BN_UMULT_HIGH)) */
-+
-+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
-+                          BN_ULONG w)
-+{
-+    BN_ULONG c = 0;
-+    BN_ULONG bl, bh;
-+
-+    assert(num >= 0);
-+    if (num <= 0)
-+        return ((BN_ULONG)0);
-+
-+    bl = LBITS(w);
-+    bh = HBITS(w);
-+
-+# ifndef OPENSSL_SMALL_FOOTPRINT
-+    while (num & ~3) {
-+        mul_add(rp[0], ap[0], bl, bh, c);
-+        mul_add(rp[1], ap[1], bl, bh, c);
-+        mul_add(rp[2], ap[2], bl, bh, c);
-+        mul_add(rp[3], ap[3], bl, bh, c);
-+        ap += 4;
-+        rp += 4;
-+        num -= 4;
-+    }
-+# endif
-+    while (num) {
-+        mul_add(rp[0], ap[0], bl, bh, c);
-+        ap++;
-+        rp++;
-+        num--;
-+    }
-+    return (c);
-+}
-+
-+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
-+{
-+    BN_ULONG carry = 0;
-+    BN_ULONG bl, bh;
-+
-+    assert(num >= 0);
-+    if (num <= 0)
-+        return ((BN_ULONG)0);
-+
-+    bl = LBITS(w);
-+    bh = HBITS(w);
-+
-+# ifndef OPENSSL_SMALL_FOOTPRINT
-+    while (num & ~3) {
-+        mul(rp[0], ap[0], bl, bh, carry);
-+        mul(rp[1], ap[1], bl, bh, carry);
-+        mul(rp[2], ap[2], bl, bh, carry);
-+        mul(rp[3], ap[3], bl, bh, carry);
-+        ap += 4;
-+        rp += 4;
-+        num -= 4;
-+    }
-+# endif
-+    while (num) {
-+        mul(rp[0], ap[0], bl, bh, carry);
-+        ap++;
-+        rp++;
-+        num--;
-+    }
-+    return (carry);
-+}
-+
-+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
-+{
-+    assert(n >= 0);
-+    if (n <= 0)
-+        return;
-+
-+# ifndef OPENSSL_SMALL_FOOTPRINT
-+    while (n & ~3) {
-+        sqr64(r[0], r[1], a[0]);
-+        sqr64(r[2], r[3], a[1]);
-+        sqr64(r[4], r[5], a[2]);
-+        sqr64(r[6], r[7], a[3]);
-+        a += 4;
-+        r += 8;
-+        n -= 4;
-+    }
-+# endif
-+    while (n) {
-+        sqr64(r[0], r[1], a[0]);
-+        a++;
-+        r += 2;
-+        n--;
-+    }
-+}
-+
-+#endif                          /* !(defined(BN_LLONG) ||
-+                                 * defined(BN_UMULT_HIGH)) */
-+
-+#if defined(BN_LLONG) && defined(BN_DIV2W)
-+
-+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
-+{
-+    return ((BN_ULONG)(((((BN_ULLONG) h) << BN_BITS2) | l) / (BN_ULLONG) d));
-+}
-+
-+#else
-+
-+/* Divide h,l by d and return the result. */
-+/* I need to test this some more :-( */
-+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
-+{
-+    BN_ULONG dh, dl, q, ret = 0, th, tl, t;
-+    int i, count = 2;
-+
-+    if (d == 0)
-+        return (BN_MASK2);
-+
-+    i = BN_num_bits_word(d);
-+    assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
-+
-+    i = BN_BITS2 - i;
-+    if (h >= d)
-+        h -= d;
-+
-+    if (i) {
-+        d <<= i;
-+        h = (h << i) | (l >> (BN_BITS2 - i));
-+        l <<= i;
-+    }
-+    dh = (d & BN_MASK2h) >> BN_BITS4;
-+    dl = (d & BN_MASK2l);
-+    for (;;) {
-+        if ((h >> BN_BITS4) == dh)
-+            q = BN_MASK2l;
-+        else
-+            q = h / dh;
-+
-+        th = q * dh;
-+        tl = dl * q;
-+        for (;;) {
-+            t = h - th;
-+            if ((t & BN_MASK2h) ||
-+                ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4))))
-+                break;
-+            q--;
-+            th -= dh;
-+            tl -= dl;
-+        }
-+        t = (tl >> BN_BITS4);
-+        tl = (tl << BN_BITS4) & BN_MASK2h;
-+        th += t;
-+
-+        if (l < tl)
-+            th++;
-+        l -= tl;
-+        if (h < th) {
-+            h += d;
-+            q--;
-+        }
-+        h -= th;
-+
-+        if (--count == 0)
-+            break;
-+
-+        ret = q << BN_BITS4;
-+        h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
-+        l = (l & BN_MASK2l) << BN_BITS4;
-+    }
-+    ret |= q;
-+    return (ret);
-+}
-+#endif                          /* !defined(BN_LLONG) && defined(BN_DIV2W) */
-+
-+#ifdef BN_LLONG
-+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
-+                      int n)
-+{
-+    BN_ULLONG ll = 0;
-+
-+    assert(n >= 0);
-+    if (n <= 0)
-+        return ((BN_ULONG)0);
-+
-+# ifndef OPENSSL_SMALL_FOOTPRINT
-+    while (n & ~3) {
-+        ll += (BN_ULLONG) a[0] + b[0];
-+        r[0] = (BN_ULONG)ll & BN_MASK2;
-+        ll >>= BN_BITS2;
-+        ll += (BN_ULLONG) a[1] + b[1];
-+        r[1] = (BN_ULONG)ll & BN_MASK2;
-+        ll >>= BN_BITS2;
-+        ll += (BN_ULLONG) a[2] + b[2];
-+        r[2] = (BN_ULONG)ll & BN_MASK2;
-+        ll >>= BN_BITS2;
-+        ll += (BN_ULLONG) a[3] + b[3];
-+        r[3] = (BN_ULONG)ll & BN_MASK2;
-+        ll >>= BN_BITS2;
-+        a += 4;
-+        b += 4;
-+        r += 4;
-+        n -= 4;
-+    }
-+# endif
-+    while (n) {
-+        ll += (BN_ULLONG) a[0] + b[0];
-+        r[0] = (BN_ULONG)ll & BN_MASK2;
-+        ll >>= BN_BITS2;
-+        a++;
-+        b++;
-+        r++;
-+        n--;
-+    }
-+    return ((BN_ULONG)ll);
-+}
-+#else                           /* !BN_LLONG */
-+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
-+                      int n)
-+{
-+    BN_ULONG c, l, t;
-+
-+    assert(n >= 0);
-+    if (n <= 0)
-+        return ((BN_ULONG)0);
-+
-+    c = 0;
-+# ifndef OPENSSL_SMALL_FOOTPRINT
-+    while (n & ~3) {
-+        t = a[0];
-+        t = (t + c) & BN_MASK2;
-+        c = (t < c);
-+        l = (t + b[0]) & BN_MASK2;
-+        c += (l < t);
-+        r[0] = l;
-+        t = a[1];
-+        t = (t + c) & BN_MASK2;
-+        c = (t < c);
-+        l = (t + b[1]) & BN_MASK2;
-+        c += (l < t);
-+        r[1] = l;
-+        t = a[2];
-+        t = (t + c) & BN_MASK2;
-+        c = (t < c);
-+        l = (t + b[2]) & BN_MASK2;
-+        c += (l < t);
-+        r[2] = l;
-+        t = a[3];
-+        t = (t + c) & BN_MASK2;
-+        c = (t < c);
-+        l = (t + b[3]) & BN_MASK2;
-+        c += (l < t);
-+        r[3] = l;
-+        a += 4;
-+        b += 4;
-+        r += 4;
-+        n -= 4;
-+    }
-+# endif
-+    while (n) {
-+        t = a[0];
-+        t = (t + c) & BN_MASK2;
-+        c = (t < c);
-+        l = (t + b[0]) & BN_MASK2;
-+        c += (l < t);
-+        r[0] = l;
-+        a++;
-+        b++;
-+        r++;
-+        n--;
-+    }
-+    return ((BN_ULONG)c);
-+}
-+#endif                          /* !BN_LLONG */
-+
-+BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
-+                      int n)
-+{
-+    BN_ULONG t1, t2;
-+    int c = 0;
-+
-+    assert(n >= 0);
-+    if (n <= 0)
-+        return ((BN_ULONG)0);
-+
-+#ifndef OPENSSL_SMALL_FOOTPRINT
-+    while (n & ~3) {
-+        t1 = a[0];
-+        t2 = b[0];
-+        r[0] = (t1 - t2 - c) & BN_MASK2;
-+        if (t1 != t2)
-+            c = (t1 < t2);
-+        t1 = a[1];
-+        t2 = b[1];
-+        r[1] = (t1 - t2 - c) & BN_MASK2;
-+        if (t1 != t2)
-+            c = (t1 < t2);
-+        t1 = a[2];
-+        t2 = b[2];
-+        r[2] = (t1 - t2 - c) & BN_MASK2;
-+        if (t1 != t2)
-+            c = (t1 < t2);
-+        t1 = a[3];
-+        t2 = b[3];
-+        r[3] = (t1 - t2 - c) & BN_MASK2;
-+        if (t1 != t2)
-+            c = (t1 < t2);
-+        a += 4;
-+        b += 4;
-+        r += 4;
-+        n -= 4;
-+    }
-+#endif
-+    while (n) {
-+        t1 = a[0];
-+        t2 = b[0];
-+        r[0] = (t1 - t2 - c) & BN_MASK2;
-+        if (t1 != t2)
-+            c = (t1 < t2);
-+        a++;
-+        b++;
-+        r++;
-+        n--;
-+    }
-+    return (c);
-+}
-+
-+#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT)
-+
-+# undef bn_mul_comba8
-+# undef bn_mul_comba4
-+# undef bn_sqr_comba8
-+# undef bn_sqr_comba4
-+
-+/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
-+/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
-+/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
-+/*
-+ * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number
-+ * c=(c2,c1,c0)
-+ */
-+
-+# ifdef BN_LLONG
-+/*
-+ * Keep in mind that additions to multiplication result can not
-+ * overflow, because its high half cannot be all-ones.
-+ */
-+#  define mul_add_c(a,b,c0,c1,c2)       do {    \
-+        BN_ULONG hi;                            \
-+        BN_ULLONG t = (BN_ULLONG)(a)*(b);       \
-+        t += c0;                /* no carry */  \
-+        c0 = (BN_ULONG)Lw(t);                   \
-+        hi = (BN_ULONG)Hw(t);                   \
-+        c1 = (c1+hi)&BN_MASK2; if (c1
-+/*
-+ * This is essentially reference implementation, which may or may not
-+ * result in performance improvement. E.g. on IA-32 this routine was
-+ * observed to give 40% faster rsa1024 private key operations and 10%
-+ * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only
-+ * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a
-+ * reference implementation, one to be used as starting point for
-+ * platform-specific assembler. Mentioned numbers apply to compiler
-+ * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and
-+ * can vary not only from platform to platform, but even for compiler
-+ * versions. Assembler vs. assembler improvement coefficients can
-+ * [and are known to] differ and are to be documented elsewhere.
-+ */
-+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                const BN_ULONG *np, const BN_ULONG *n0p, int num)
-+{
-+    BN_ULONG c0, c1, ml, *tp, n0;
-+#   ifdef mul64
-+    BN_ULONG mh;
-+#   endif
-+    volatile BN_ULONG *vp;
-+    int i = 0, j;
-+
-+#   if 0                        /* template for platform-specific
-+                                 * implementation */
-+    if (ap == bp)
-+        return bn_sqr_mont(rp, ap, np, n0p, num);
-+#   endif
-+    vp = tp = alloca((num + 2) * sizeof(BN_ULONG));
-+
-+    n0 = *n0p;
-+
-+    c0 = 0;
-+    ml = bp[0];
-+#   ifdef mul64
-+    mh = HBITS(ml);
-+    ml = LBITS(ml);
-+    for (j = 0; j < num; ++j)
-+        mul(tp[j], ap[j], ml, mh, c0);
-+#   else
-+    for (j = 0; j < num; ++j)
-+        mul(tp[j], ap[j], ml, c0);
-+#   endif
-+
-+    tp[num] = c0;
-+    tp[num + 1] = 0;
-+    goto enter;
-+
-+    for (i = 0; i < num; i++) {
-+        c0 = 0;
-+        ml = bp[i];
-+#   ifdef mul64
-+        mh = HBITS(ml);
-+        ml = LBITS(ml);
-+        for (j = 0; j < num; ++j)
-+            mul_add(tp[j], ap[j], ml, mh, c0);
-+#   else
-+        for (j = 0; j < num; ++j)
-+            mul_add(tp[j], ap[j], ml, c0);
-+#   endif
-+        c1 = (tp[num] + c0) & BN_MASK2;
-+        tp[num] = c1;
-+        tp[num + 1] = (c1 < c0 ? 1 : 0);
-+ enter:
-+        c1 = tp[0];
-+        ml = (c1 * n0) & BN_MASK2;
-+        c0 = 0;
-+#   ifdef mul64
-+        mh = HBITS(ml);
-+        ml = LBITS(ml);
-+        mul_add(c1, np[0], ml, mh, c0);
-+#   else
-+        mul_add(c1, ml, np[0], c0);
-+#   endif
-+        for (j = 1; j < num; j++) {
-+            c1 = tp[j];
-+#   ifdef mul64
-+            mul_add(c1, np[j], ml, mh, c0);
-+#   else
-+            mul_add(c1, ml, np[j], c0);
-+#   endif
-+            tp[j - 1] = c1 & BN_MASK2;
-+        }
-+        c1 = (tp[num] + c0) & BN_MASK2;
-+        tp[num - 1] = c1;
-+        tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0);
-+    }
-+
-+    if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
-+        c0 = bn_sub_words(rp, tp, np, num);
-+        if (tp[num] != 0 || c0 == 0) {
-+            for (i = 0; i < num + 2; i++)
-+                vp[i] = 0;
-+            return 1;
-+        }
-+    }
-+    for (i = 0; i < num; i++)
-+        rp[i] = tp[i], vp[i] = 0;
-+    vp[num] = 0;
-+    vp[num + 1] = 0;
-+    return 1;
-+}
-+#  else
-+/*
-+ * Return value of 0 indicates that multiplication/convolution was not
-+ * performed to signal the caller to fall down to alternative/original
-+ * code-path.
-+ */
-+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                const BN_ULONG *np, const BN_ULONG *n0, int num)
-+{
-+    return 0;
-+}
-+#  endif                        /* OPENSSL_BN_ASM_MONT */
-+# endif
-+
-+#else                           /* !BN_MUL_COMBA */
-+
-+/* hmm... is it faster just to do a multiply? */
-+# undef bn_sqr_comba4
-+# undef bn_sqr_comba8
-+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
-+{
-+    BN_ULONG t[8];
-+    bn_sqr_normal(r, a, 4, t);
-+}
-+
-+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
-+{
-+    BN_ULONG t[16];
-+    bn_sqr_normal(r, a, 8, t);
-+}
-+
-+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
-+{
-+    r[4] = bn_mul_words(&(r[0]), a, 4, b[0]);
-+    r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]);
-+    r[6] = bn_mul_add_words(&(r[2]), a, 4, b[2]);
-+    r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]);
-+}
-+
-+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
-+{
-+    r[8] = bn_mul_words(&(r[0]), a, 8, b[0]);
-+    r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]);
-+    r[10] = bn_mul_add_words(&(r[2]), a, 8, b[2]);
-+    r[11] = bn_mul_add_words(&(r[3]), a, 8, b[3]);
-+    r[12] = bn_mul_add_words(&(r[4]), a, 8, b[4]);
-+    r[13] = bn_mul_add_words(&(r[5]), a, 8, b[5]);
-+    r[14] = bn_mul_add_words(&(r[6]), a, 8, b[6]);
-+    r[15] = bn_mul_add_words(&(r[7]), a, 8, b[7]);
-+}
-+
-+# ifdef OPENSSL_NO_ASM
-+#  ifdef OPENSSL_BN_ASM_MONT
-+#   include 
-+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                const BN_ULONG *np, const BN_ULONG *n0p, int num)
-+{
-+    BN_ULONG c0, c1, *tp, n0 = *n0p;
-+    volatile BN_ULONG *vp;
-+    int i = 0, j;
-+
-+    vp = tp = alloca((num + 2) * sizeof(BN_ULONG));
-+
-+    for (i = 0; i <= num; i++)
-+        tp[i] = 0;
-+
-+    for (i = 0; i < num; i++) {
-+        c0 = bn_mul_add_words(tp, ap, num, bp[i]);
-+        c1 = (tp[num] + c0) & BN_MASK2;
-+        tp[num] = c1;
-+        tp[num + 1] = (c1 < c0 ? 1 : 0);
-+
-+        c0 = bn_mul_add_words(tp, np, num, tp[0] * n0);
-+        c1 = (tp[num] + c0) & BN_MASK2;
-+        tp[num] = c1;
-+        tp[num + 1] += (c1 < c0 ? 1 : 0);
-+        for (j = 0; j <= num; j++)
-+            tp[j] = tp[j + 1];
-+    }
-+
-+    if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
-+        c0 = bn_sub_words(rp, tp, np, num);
-+        if (tp[num] != 0 || c0 == 0) {
-+            for (i = 0; i < num + 2; i++)
-+                vp[i] = 0;
-+            return 1;
-+        }
-+    }
-+    for (i = 0; i < num; i++)
-+        rp[i] = tp[i], vp[i] = 0;
-+    vp[num] = 0;
-+    vp[num + 1] = 0;
-+    return 1;
-+}
-+#  else
-+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                const BN_ULONG *np, const BN_ULONG *n0, int num)
-+{
-+    return 0;
-+}
-+#  endif                        /* OPENSSL_BN_ASM_MONT */
-+# endif
-+
-+#endif                          /* !BN_MUL_COMBA */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_blind.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_blind.c
-new file mode 100644
-index 0000000..24d1383
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_blind.c
-@@ -0,0 +1,289 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+#define BN_BLINDING_COUNTER     32
-+
-+struct bn_blinding_st {
-+    BIGNUM *A;
-+    BIGNUM *Ai;
-+    BIGNUM *e;
-+    BIGNUM *mod;                /* just a reference */
-+    CRYPTO_THREAD_ID tid;
-+    int counter;
-+    unsigned long flags;
-+    BN_MONT_CTX *m_ctx;
-+    int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-+                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
-+{
-+    BN_BLINDING *ret = NULL;
-+
-+    bn_check_top(mod);
-+
-+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
-+        BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+
-+    BN_BLINDING_set_current_thread(ret);
-+
-+    if (A != NULL) {
-+        if ((ret->A = BN_dup(A)) == NULL)
-+            goto err;
-+    }
-+
-+    if (Ai != NULL) {
-+        if ((ret->Ai = BN_dup(Ai)) == NULL)
-+            goto err;
-+    }
-+
-+    /* save a copy of mod in the BN_BLINDING structure */
-+    if ((ret->mod = BN_dup(mod)) == NULL)
-+        goto err;
-+
-+    if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
-+        BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
-+
-+    /*
-+     * Set the counter to the special value -1 to indicate that this is
-+     * never-used fresh blinding that does not need updating before first
-+     * use.
-+     */
-+    ret->counter = -1;
-+
-+    return ret;
-+
-+ err:
-+    BN_BLINDING_free(ret);
-+    return NULL;
-+}
-+
-+void BN_BLINDING_free(BN_BLINDING *r)
-+{
-+    if (r == NULL)
-+        return;
-+
-+    BN_free(r->A);
-+    BN_free(r->Ai);
-+    BN_free(r->e);
-+    BN_free(r->mod);
-+    CRYPTO_THREAD_lock_free(r->lock);
-+    OPENSSL_free(r);
-+}
-+
-+int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+
-+    if ((b->A == NULL) || (b->Ai == NULL)) {
-+        BNerr(BN_F_BN_BLINDING_UPDATE, BN_R_NOT_INITIALIZED);
-+        goto err;
-+    }
-+
-+    if (b->counter == -1)
-+        b->counter = 0;
-+
-+    if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
-+        !(b->flags & BN_BLINDING_NO_RECREATE)) {
-+        /* re-create blinding parameters */
-+        if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
-+            goto err;
-+    } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) {
-+        if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx))
-+            goto err;
-+        if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx))
-+            goto err;
-+    }
-+
-+    ret = 1;
-+ err:
-+    if (b->counter == BN_BLINDING_COUNTER)
-+        b->counter = 0;
-+    return (ret);
-+}
-+
-+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
-+{
-+    return BN_BLINDING_convert_ex(n, NULL, b, ctx);
-+}
-+
-+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
-+{
-+    int ret = 1;
-+
-+    bn_check_top(n);
-+
-+    if ((b->A == NULL) || (b->Ai == NULL)) {
-+        BNerr(BN_F_BN_BLINDING_CONVERT_EX, BN_R_NOT_INITIALIZED);
-+        return (0);
-+    }
-+
-+    if (b->counter == -1)
-+        /* Fresh blinding, doesn't need updating. */
-+        b->counter = 0;
-+    else if (!BN_BLINDING_update(b, ctx))
-+        return (0);
-+
-+    if (r != NULL) {
-+        if (!BN_copy(r, b->Ai))
-+            ret = 0;
-+    }
-+
-+    if (!BN_mod_mul(n, n, b->A, b->mod, ctx))
-+        ret = 0;
-+
-+    return ret;
-+}
-+
-+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
-+{
-+    return BN_BLINDING_invert_ex(n, NULL, b, ctx);
-+}
-+
-+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
-+                          BN_CTX *ctx)
-+{
-+    int ret;
-+
-+    bn_check_top(n);
-+
-+    if (r != NULL)
-+        ret = BN_mod_mul(n, n, r, b->mod, ctx);
-+    else {
-+        if (b->Ai == NULL) {
-+            BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED);
-+            return (0);
-+        }
-+        ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
-+    }
-+
-+    bn_check_top(n);
-+    return (ret);
-+}
-+
-+int BN_BLINDING_is_current_thread(BN_BLINDING *b)
-+{
-+    return CRYPTO_THREAD_compare_id(CRYPTO_THREAD_get_current_id(), b->tid);
-+}
-+
-+void BN_BLINDING_set_current_thread(BN_BLINDING *b)
-+{
-+    b->tid = CRYPTO_THREAD_get_current_id();
-+}
-+
-+int BN_BLINDING_lock(BN_BLINDING *b)
-+{
-+    return CRYPTO_THREAD_write_lock(b->lock);
-+}
-+
-+int BN_BLINDING_unlock(BN_BLINDING *b)
-+{
-+    return CRYPTO_THREAD_unlock(b->lock);
-+}
-+
-+unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
-+{
-+    return b->flags;
-+}
-+
-+void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
-+{
-+    b->flags = flags;
-+}
-+
-+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
-+                                      const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
-+                                      int (*bn_mod_exp) (BIGNUM *r,
-+                                                         const BIGNUM *a,
-+                                                         const BIGNUM *p,
-+                                                         const BIGNUM *m,
-+                                                         BN_CTX *ctx,
-+                                                         BN_MONT_CTX *m_ctx),
-+                                      BN_MONT_CTX *m_ctx)
-+{
-+    int retry_counter = 32;
-+    BN_BLINDING *ret = NULL;
-+
-+    if (b == NULL)
-+        ret = BN_BLINDING_new(NULL, NULL, m);
-+    else
-+        ret = b;
-+
-+    if (ret == NULL)
-+        goto err;
-+
-+    if (ret->A == NULL && (ret->A = BN_new()) == NULL)
-+        goto err;
-+    if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL)
-+        goto err;
-+
-+    if (e != NULL) {
-+        BN_free(ret->e);
-+        ret->e = BN_dup(e);
-+    }
-+    if (ret->e == NULL)
-+        goto err;
-+
-+    if (bn_mod_exp != NULL)
-+        ret->bn_mod_exp = bn_mod_exp;
-+    if (m_ctx != NULL)
-+        ret->m_ctx = m_ctx;
-+
-+    do {
-+        int rv;
-+        if (!BN_rand_range(ret->A, ret->mod))
-+            goto err;
-+        if (!int_bn_mod_inverse(ret->Ai, ret->A, ret->mod, ctx, &rv)) {
-+            /*
-+             * this should almost never happen for good RSA keys
-+             */
-+            if (rv) {
-+                if (retry_counter-- == 0) {
-+                    BNerr(BN_F_BN_BLINDING_CREATE_PARAM,
-+                          BN_R_TOO_MANY_ITERATIONS);
-+                    goto err;
-+                }
-+            } else
-+                goto err;
-+        } else
-+            break;
-+    } while (1);
-+
-+    if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) {
-+        if (!ret->bn_mod_exp
-+            (ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
-+            goto err;
-+    } else {
-+        if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
-+            goto err;
-+    }
-+
-+    return ret;
-+ err:
-+    if (b == NULL) {
-+        BN_BLINDING_free(ret);
-+        ret = NULL;
-+    }
-+
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_const.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_const.c
-new file mode 100644
-index 0000000..39dd612
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_const.c
-@@ -0,0 +1,553 @@
-+/*
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+/*-
-+ * "First Oakley Default Group" from RFC2409, section 6.1.
-+ *
-+ * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
-+ *
-+ * RFC2409 specifies a generator of 2.
-+ * RFC2412 specifies a generator of of 22.
-+ */
-+
-+BIGNUM *BN_get_rfc2409_prime_768(BIGNUM *bn)
-+{
-+    static const unsigned char RFC2409_PRIME_768[] = {
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20,
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    };
-+    return BN_bin2bn(RFC2409_PRIME_768, sizeof(RFC2409_PRIME_768), bn);
-+}
-+
-+/*-
-+ * "Second Oakley Default Group" from RFC2409, section 6.2.
-+ *
-+ * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
-+ *
-+ * RFC2409 specifies a generator of 2.
-+ * RFC2412 specifies a generator of 22.
-+ */
-+
-+BIGNUM *BN_get_rfc2409_prime_1024(BIGNUM *bn)
-+{
-+    static const unsigned char RFC2409_PRIME_1024[] = {
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
-+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
-+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
-+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    };
-+    return BN_bin2bn(RFC2409_PRIME_1024, sizeof(RFC2409_PRIME_1024), bn);
-+}
-+
-+/*-
-+ * "1536-bit MODP Group" from RFC3526, Section 2.
-+ *
-+ * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
-+ *
-+ * RFC3526 specifies a generator of 2.
-+ * RFC2312 specifies a generator of 22.
-+ */
-+
-+BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *bn)
-+{
-+    static const unsigned char RFC3526_PRIME_1536[] = {
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
-+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
-+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
-+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
-+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
-+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
-+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
-+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
-+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    };
-+    return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn);
-+}
-+
-+/*-
-+ * "2048-bit MODP Group" from RFC3526, Section 3.
-+ *
-+ * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
-+ *
-+ * RFC3526 specifies a generator of 2.
-+ */
-+
-+BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *bn)
-+{
-+    static const unsigned char RFC3526_PRIME_2048[] = {
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
-+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
-+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
-+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
-+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
-+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
-+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
-+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
-+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
-+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
-+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
-+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
-+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
-+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
-+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
-+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
-+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    };
-+    return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn);
-+}
-+
-+/*-
-+ * "3072-bit MODP Group" from RFC3526, Section 4.
-+ *
-+ * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }
-+ *
-+ * RFC3526 specifies a generator of 2.
-+ */
-+
-+BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *bn)
-+{
-+    static const unsigned char RFC3526_PRIME_3072[] = {
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
-+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
-+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
-+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
-+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
-+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
-+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
-+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
-+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
-+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
-+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
-+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
-+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
-+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
-+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
-+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
-+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
-+        0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
-+        0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
-+        0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
-+        0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
-+        0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
-+        0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
-+        0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
-+        0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
-+        0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
-+        0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
-+        0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
-+        0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
-+        0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
-+        0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
-+        0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
-+        0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA,
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    };
-+    return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn);
-+}
-+
-+/*-
-+ * "4096-bit MODP Group" from RFC3526, Section 5.
-+ *
-+ * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
-+ *
-+ * RFC3526 specifies a generator of 2.
-+ */
-+
-+BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *bn)
-+{
-+    static const unsigned char RFC3526_PRIME_4096[] = {
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
-+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
-+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
-+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
-+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
-+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
-+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
-+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
-+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
-+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
-+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
-+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
-+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
-+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
-+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
-+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
-+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
-+        0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
-+        0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
-+        0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
-+        0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
-+        0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
-+        0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
-+        0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
-+        0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
-+        0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
-+        0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
-+        0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
-+        0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
-+        0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
-+        0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
-+        0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
-+        0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
-+        0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
-+        0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
-+        0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
-+        0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
-+        0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
-+        0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
-+        0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
-+        0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
-+        0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
-+        0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
-+        0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
-+        0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
-+        0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
-+        0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
-+        0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
-+        0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    };
-+    return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn);
-+}
-+
-+/*-
-+ * "6144-bit MODP Group" from RFC3526, Section 6.
-+ *
-+ * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 }
-+ *
-+ * RFC3526 specifies a generator of 2.
-+ */
-+
-+BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *bn)
-+{
-+    static const unsigned char RFC3526_PRIME_6144[] = {
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
-+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
-+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
-+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
-+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
-+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
-+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
-+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
-+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
-+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
-+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
-+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
-+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
-+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
-+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
-+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
-+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
-+        0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
-+        0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
-+        0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
-+        0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
-+        0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
-+        0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
-+        0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
-+        0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
-+        0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
-+        0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
-+        0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
-+        0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
-+        0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
-+        0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
-+        0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
-+        0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
-+        0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
-+        0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
-+        0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
-+        0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
-+        0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
-+        0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
-+        0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
-+        0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
-+        0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
-+        0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
-+        0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
-+        0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
-+        0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
-+        0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
-+        0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
-+        0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
-+        0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
-+        0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE,
-+        0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
-+        0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E,
-+        0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
-+        0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
-+        0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
-+        0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED,
-+        0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
-+        0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B,
-+        0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
-+        0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
-+        0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
-+        0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03,
-+        0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
-+        0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82,
-+        0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
-+        0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
-+        0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
-+        0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5,
-+        0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
-+        0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8,
-+        0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
-+        0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
-+        0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
-+        0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0,
-+        0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
-+        0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32,
-+        0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
-+        0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
-+        0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
-+        0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24,
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    };
-+    return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn);
-+}
-+
-+/*-
-+ * "8192-bit MODP Group" from RFC3526, Section 7.
-+ *
-+ * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }
-+ *
-+ * RFC3526 specifies a generator of 2.
-+ */
-+
-+BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *bn)
-+{
-+    static const unsigned char RFC3526_PRIME_8192[] = {
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
-+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
-+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
-+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
-+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
-+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
-+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
-+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
-+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
-+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
-+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
-+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
-+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
-+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
-+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
-+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
-+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
-+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
-+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
-+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
-+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
-+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
-+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
-+        0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
-+        0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
-+        0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
-+        0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
-+        0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
-+        0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
-+        0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
-+        0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
-+        0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
-+        0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
-+        0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
-+        0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
-+        0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
-+        0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
-+        0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
-+        0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
-+        0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
-+        0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
-+        0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
-+        0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
-+        0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
-+        0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
-+        0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
-+        0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
-+        0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
-+        0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
-+        0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
-+        0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
-+        0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
-+        0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
-+        0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
-+        0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
-+        0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
-+        0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE,
-+        0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
-+        0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E,
-+        0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
-+        0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
-+        0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
-+        0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED,
-+        0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
-+        0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B,
-+        0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
-+        0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
-+        0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
-+        0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03,
-+        0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
-+        0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82,
-+        0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
-+        0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
-+        0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
-+        0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5,
-+        0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
-+        0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8,
-+        0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
-+        0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
-+        0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
-+        0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0,
-+        0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
-+        0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32,
-+        0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
-+        0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
-+        0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
-+        0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59,
-+        0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
-+        0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C,
-+        0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA,
-+        0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00,
-+        0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED,
-+        0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66,
-+        0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
-+        0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78,
-+        0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D,
-+        0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9,
-+        0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07,
-+        0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7,
-+        0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
-+        0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD,
-+        0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8,
-+        0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A,
-+        0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6,
-+        0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D,
-+        0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
-+        0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1,
-+        0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D,
-+        0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1,
-+        0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73,
-+        0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68,
-+        0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
-+        0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7,
-+        0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B,
-+        0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47,
-+        0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA,
-+        0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF,
-+        0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
-+        0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF,
-+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    };
-+    return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_ctx.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_ctx.c
-new file mode 100644
-index 0000000..68c0468
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_ctx.c
-@@ -0,0 +1,353 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+/*-
-+ * TODO list
-+ *
-+ * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
-+ * check they can be safely removed.
-+ *  - Check +1 and other ugliness in BN_from_montgomery()
-+ *
-+ * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
-+ * appropriate 'block' size that will be honoured by bn_expand_internal() to
-+ * prevent piddly little reallocations. OTOH, profiling bignum expansions in
-+ * BN_CTX doesn't show this to be a big issue.
-+ */
-+
-+/* How many bignums are in each "pool item"; */
-+#define BN_CTX_POOL_SIZE        16
-+/* The stack frame info is resizing, set a first-time expansion size; */
-+#define BN_CTX_START_FRAMES     32
-+
-+/***********/
-+/* BN_POOL */
-+/***********/
-+
-+/* A bundle of bignums that can be linked with other bundles */
-+typedef struct bignum_pool_item {
-+    /* The bignum values */
-+    BIGNUM vals[BN_CTX_POOL_SIZE];
-+    /* Linked-list admin */
-+    struct bignum_pool_item *prev, *next;
-+} BN_POOL_ITEM;
-+/* A linked-list of bignums grouped in bundles */
-+typedef struct bignum_pool {
-+    /* Linked-list admin */
-+    BN_POOL_ITEM *head, *current, *tail;
-+    /* Stack depth and allocation size */
-+    unsigned used, size;
-+} BN_POOL;
-+static void BN_POOL_init(BN_POOL *);
-+static void BN_POOL_finish(BN_POOL *);
-+static BIGNUM *BN_POOL_get(BN_POOL *, int);
-+static void BN_POOL_release(BN_POOL *, unsigned int);
-+
-+/************/
-+/* BN_STACK */
-+/************/
-+
-+/* A wrapper to manage the "stack frames" */
-+typedef struct bignum_ctx_stack {
-+    /* Array of indexes into the bignum stack */
-+    unsigned int *indexes;
-+    /* Number of stack frames, and the size of the allocated array */
-+    unsigned int depth, size;
-+} BN_STACK;
-+static void BN_STACK_init(BN_STACK *);
-+static void BN_STACK_finish(BN_STACK *);
-+static int BN_STACK_push(BN_STACK *, unsigned int);
-+static unsigned int BN_STACK_pop(BN_STACK *);
-+
-+/**********/
-+/* BN_CTX */
-+/**********/
-+
-+/* The opaque BN_CTX type */
-+struct bignum_ctx {
-+    /* The bignum bundles */
-+    BN_POOL pool;
-+    /* The "stack frames", if you will */
-+    BN_STACK stack;
-+    /* The number of bignums currently assigned */
-+    unsigned int used;
-+    /* Depth of stack overflow */
-+    int err_stack;
-+    /* Block "gets" until an "end" (compatibility behaviour) */
-+    int too_many;
-+    /* Flags. */
-+    int flags;
-+};
-+
-+/* Enable this to find BN_CTX bugs */
-+#ifdef BN_CTX_DEBUG
-+static const char *ctxdbg_cur = NULL;
-+static void ctxdbg(BN_CTX *ctx)
-+{
-+    unsigned int bnidx = 0, fpidx = 0;
-+    BN_POOL_ITEM *item = ctx->pool.head;
-+    BN_STACK *stack = &ctx->stack;
-+    fprintf(stderr, "(%16p): ", ctx);
-+    while (bnidx < ctx->used) {
-+        fprintf(stderr, "%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
-+        if (!(bnidx % BN_CTX_POOL_SIZE))
-+            item = item->next;
-+    }
-+    fprintf(stderr, "\n");
-+    bnidx = 0;
-+    fprintf(stderr, "          : ");
-+    while (fpidx < stack->depth) {
-+        while (bnidx++ < stack->indexes[fpidx])
-+            fprintf(stderr, "    ");
-+        fprintf(stderr, "^^^ ");
-+        bnidx++;
-+        fpidx++;
-+    }
-+    fprintf(stderr, "\n");
-+}
-+
-+# define CTXDBG_ENTRY(str, ctx)  do { \
-+                                ctxdbg_cur = (str); \
-+                                fprintf(stderr,"Starting %s\n", ctxdbg_cur); \
-+                                ctxdbg(ctx); \
-+                                } while(0)
-+# define CTXDBG_EXIT(ctx)        do { \
-+                                fprintf(stderr,"Ending %s\n", ctxdbg_cur); \
-+                                ctxdbg(ctx); \
-+                                } while(0)
-+# define CTXDBG_RET(ctx,ret)
-+#else
-+# define CTXDBG_ENTRY(str, ctx)
-+# define CTXDBG_EXIT(ctx)
-+# define CTXDBG_RET(ctx,ret)
-+#endif
-+
-+
-+BN_CTX *BN_CTX_new(void)
-+{
-+    BN_CTX *ret;
-+
-+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
-+        BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    /* Initialise the structure */
-+    BN_POOL_init(&ret->pool);
-+    BN_STACK_init(&ret->stack);
-+    return ret;
-+}
-+
-+BN_CTX *BN_CTX_secure_new(void)
-+{
-+    BN_CTX *ret = BN_CTX_new();
-+
-+    if (ret != NULL)
-+        ret->flags = BN_FLG_SECURE;
-+    return ret;
-+}
-+
-+void BN_CTX_free(BN_CTX *ctx)
-+{
-+    if (ctx == NULL)
-+        return;
-+#ifdef BN_CTX_DEBUG
-+    {
-+        BN_POOL_ITEM *pool = ctx->pool.head;
-+        fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
-+                ctx->stack.size, ctx->pool.size);
-+        fprintf(stderr, "dmaxs: ");
-+        while (pool) {
-+            unsigned loop = 0;
-+            while (loop < BN_CTX_POOL_SIZE)
-+                fprintf(stderr, "%02x ", pool->vals[loop++].dmax);
-+            pool = pool->next;
-+        }
-+        fprintf(stderr, "\n");
-+    }
-+#endif
-+    BN_STACK_finish(&ctx->stack);
-+    BN_POOL_finish(&ctx->pool);
-+    OPENSSL_free(ctx);
-+}
-+
-+void BN_CTX_start(BN_CTX *ctx)
-+{
-+    CTXDBG_ENTRY("BN_CTX_start", ctx);
-+    /* If we're already overflowing ... */
-+    if (ctx->err_stack || ctx->too_many)
-+        ctx->err_stack++;
-+    /* (Try to) get a new frame pointer */
-+    else if (!BN_STACK_push(&ctx->stack, ctx->used)) {
-+        BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
-+        ctx->err_stack++;
-+    }
-+    CTXDBG_EXIT(ctx);
-+}
-+
-+void BN_CTX_end(BN_CTX *ctx)
-+{
-+    CTXDBG_ENTRY("BN_CTX_end", ctx);
-+    if (ctx->err_stack)
-+        ctx->err_stack--;
-+    else {
-+        unsigned int fp = BN_STACK_pop(&ctx->stack);
-+        /* Does this stack frame have anything to release? */
-+        if (fp < ctx->used)
-+            BN_POOL_release(&ctx->pool, ctx->used - fp);
-+        ctx->used = fp;
-+        /* Unjam "too_many" in case "get" had failed */
-+        ctx->too_many = 0;
-+    }
-+    CTXDBG_EXIT(ctx);
-+}
-+
-+BIGNUM *BN_CTX_get(BN_CTX *ctx)
-+{
-+    BIGNUM *ret;
-+
-+    CTXDBG_ENTRY("BN_CTX_get", ctx);
-+    if (ctx->err_stack || ctx->too_many)
-+        return NULL;
-+    if ((ret = BN_POOL_get(&ctx->pool, ctx->flags)) == NULL) {
-+        /*
-+         * Setting too_many prevents repeated "get" attempts from cluttering
-+         * the error stack.
-+         */
-+        ctx->too_many = 1;
-+        BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
-+        return NULL;
-+    }
-+    /* OK, make sure the returned bignum is "zero" */
-+    BN_zero(ret);
-+    ctx->used++;
-+    CTXDBG_RET(ctx, ret);
-+    return ret;
-+}
-+
-+/************/
-+/* BN_STACK */
-+/************/
-+
-+static void BN_STACK_init(BN_STACK *st)
-+{
-+    st->indexes = NULL;
-+    st->depth = st->size = 0;
-+}
-+
-+static void BN_STACK_finish(BN_STACK *st)
-+{
-+    OPENSSL_free(st->indexes);
-+    st->indexes = NULL;
-+}
-+
-+
-+static int BN_STACK_push(BN_STACK *st, unsigned int idx)
-+{
-+    if (st->depth == st->size) {
-+        /* Need to expand */
-+        unsigned int newsize =
-+            st->size ? (st->size * 3 / 2) : BN_CTX_START_FRAMES;
-+        unsigned int *newitems = OPENSSL_malloc(sizeof(*newitems) * newsize);
-+        if (newitems == NULL)
-+            return 0;
-+        if (st->depth)
-+            memcpy(newitems, st->indexes, sizeof(*newitems) * st->depth);
-+        OPENSSL_free(st->indexes);
-+        st->indexes = newitems;
-+        st->size = newsize;
-+    }
-+    st->indexes[(st->depth)++] = idx;
-+    return 1;
-+}
-+
-+static unsigned int BN_STACK_pop(BN_STACK *st)
-+{
-+    return st->indexes[--(st->depth)];
-+}
-+
-+/***********/
-+/* BN_POOL */
-+/***********/
-+
-+static void BN_POOL_init(BN_POOL *p)
-+{
-+    p->head = p->current = p->tail = NULL;
-+    p->used = p->size = 0;
-+}
-+
-+static void BN_POOL_finish(BN_POOL *p)
-+{
-+    unsigned int loop;
-+    BIGNUM *bn;
-+
-+    while (p->head) {
-+        for (loop = 0, bn = p->head->vals; loop++ < BN_CTX_POOL_SIZE; bn++)
-+            if (bn->d)
-+                BN_clear_free(bn);
-+        p->current = p->head->next;
-+        OPENSSL_free(p->head);
-+        p->head = p->current;
-+    }
-+}
-+
-+
-+static BIGNUM *BN_POOL_get(BN_POOL *p, int flag)
-+{
-+    BIGNUM *bn;
-+    unsigned int loop;
-+
-+    /* Full; allocate a new pool item and link it in. */
-+    if (p->used == p->size) {
-+        BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(*item));
-+        if (item == NULL)
-+            return NULL;
-+        for (loop = 0, bn = item->vals; loop++ < BN_CTX_POOL_SIZE; bn++) {
-+            bn_init(bn);
-+            if ((flag & BN_FLG_SECURE) != 0)
-+                BN_set_flags(bn, BN_FLG_SECURE);
-+        }
-+        item->prev = p->tail;
-+        item->next = NULL;
-+
-+        if (p->head == NULL)
-+            p->head = p->current = p->tail = item;
-+        else {
-+            p->tail->next = item;
-+            p->tail = item;
-+            p->current = item;
-+        }
-+        p->size += BN_CTX_POOL_SIZE;
-+        p->used++;
-+        /* Return the first bignum from the new pool */
-+        return item->vals;
-+    }
-+
-+    if (!p->used)
-+        p->current = p->head;
-+    else if ((p->used % BN_CTX_POOL_SIZE) == 0)
-+        p->current = p->current->next;
-+    return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
-+}
-+
-+static void BN_POOL_release(BN_POOL *p, unsigned int num)
-+{
-+    unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
-+
-+    p->used -= num;
-+    while (num--) {
-+        bn_check_top(p->current->vals + offset);
-+        if (offset == 0) {
-+            offset = BN_CTX_POOL_SIZE - 1;
-+            p->current = p->current->prev;
-+        } else
-+            offset--;
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_depr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_depr.c
-new file mode 100644
-index 0000000..7d89214
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_depr.c
-@@ -0,0 +1,68 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Support for deprecated functions goes here - static linkage will only
-+ * slurp this code if applications are using them directly.
-+ */
-+
-+#include 
-+#if OPENSSL_API_COMPAT >= 0x00908000L
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+# include 
-+# include "internal/cryptlib.h"
-+# include "bn_lcl.h"
-+
-+BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
-+                          const BIGNUM *add, const BIGNUM *rem,
-+                          void (*callback) (int, int, void *), void *cb_arg)
-+{
-+    BN_GENCB cb;
-+    BIGNUM *rnd = NULL;
-+
-+    BN_GENCB_set_old(&cb, callback, cb_arg);
-+
-+    if (ret == NULL) {
-+        if ((rnd = BN_new()) == NULL)
-+            goto err;
-+    } else
-+        rnd = ret;
-+    if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb))
-+        goto err;
-+
-+    /* we have a prime :-) */
-+    return ret;
-+ err:
-+    BN_free(rnd);
-+    return NULL;
-+}
-+
-+int BN_is_prime(const BIGNUM *a, int checks,
-+                void (*callback) (int, int, void *), BN_CTX *ctx_passed,
-+                void *cb_arg)
-+{
-+    BN_GENCB cb;
-+    BN_GENCB_set_old(&cb, callback, cb_arg);
-+    return BN_is_prime_ex(a, checks, ctx_passed, &cb);
-+}
-+
-+int BN_is_prime_fasttest(const BIGNUM *a, int checks,
-+                         void (*callback) (int, int, void *),
-+                         BN_CTX *ctx_passed, void *cb_arg,
-+                         int do_trial_division)
-+{
-+    BN_GENCB cb;
-+    BN_GENCB_set_old(&cb, callback, cb_arg);
-+    return BN_is_prime_fasttest_ex(a, checks, ctx_passed,
-+                                   do_trial_division, &cb);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_dh.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_dh.c
-new file mode 100644
-index 0000000..17d0559
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_dh.c
-@@ -0,0 +1,220 @@
-+/*
-+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "bn_lcl.h"
-+#include "e_os.h"
-+
-+#ifndef OPENSSL_NO_DH
-+#include 
-+#include "internal/bn_dh.h"
-+/* DH parameters from RFC5114 */
-+
-+# if BN_BITS2 == 64
-+static const BN_ULONG dh1024_160_p[] = {
-+    0xDF1FB2BC2E4A4371ULL, 0xE68CFDA76D4DA708ULL, 0x45BF37DF365C1A65ULL,
-+    0xA151AF5F0DC8B4BDULL, 0xFAA31A4FF55BCCC0ULL, 0x4EFFD6FAE5644738ULL,
-+    0x98488E9C219A7372ULL, 0xACCBDD7D90C4BD70ULL, 0x24975C3CD49B83BFULL,
-+    0x13ECB4AEA9061123ULL, 0x9838EF1E2EE652C0ULL, 0x6073E28675A23D18ULL,
-+    0x9A6A9DCA52D23B61ULL, 0x52C99FBCFB06A3C6ULL, 0xDE92DE5EAE5D54ECULL,
-+    0xB10B8F96A080E01DULL
-+};
-+
-+static const BN_ULONG dh1024_160_g[] = {
-+    0x855E6EEB22B3B2E5ULL, 0x858F4DCEF97C2A24ULL, 0x2D779D5918D08BC8ULL,
-+    0xD662A4D18E73AFA3ULL, 0x1DBF0A0169B6A28AULL, 0xA6A24C087A091F53ULL,
-+    0x909D0D2263F80A76ULL, 0xD7FBD7D3B9A92EE1ULL, 0x5E91547F9E2749F4ULL,
-+    0x160217B4B01B886AULL, 0x777E690F5504F213ULL, 0x266FEA1E5C41564BULL,
-+    0xD6406CFF14266D31ULL, 0xF8104DD258AC507FULL, 0x6765A442EFB99905ULL,
-+    0xA4D1CBD5C3FD3412ULL
-+};
-+
-+static const BN_ULONG dh1024_160_q[] = {
-+    0x64B7CB9D49462353ULL, 0x81A8DF278ABA4E7DULL, 0x00000000F518AA87ULL
-+};
-+
-+static const BN_ULONG dh2048_224_p[] = {
-+    0x0AC4DFFE0C10E64FULL, 0xCF9DE5384E71B81CULL, 0x7EF363E2FFA31F71ULL,
-+    0xE3FB73C16B8E75B9ULL, 0xC9B53DCF4BA80A29ULL, 0x23F10B0E16E79763ULL,
-+    0xC52172E413042E9BULL, 0xBE60E69CC928B2B9ULL, 0x80CD86A1B9E587E8ULL,
-+    0x315D75E198C641A4ULL, 0xCDF93ACC44328387ULL, 0x15987D9ADC0A486DULL,
-+    0x7310F7121FD5A074ULL, 0x278273C7DE31EFDCULL, 0x1602E714415D9330ULL,
-+    0x81286130BC8985DBULL, 0xB3BF8A3170918836ULL, 0x6A00E0A0B9C49708ULL,
-+    0xC6BA0B2C8BBC27BEULL, 0xC9F98D11ED34DBF6ULL, 0x7AD5B7D0B6C12207ULL,
-+    0xD91E8FEF55B7394BULL, 0x9037C9EDEFDA4DF8ULL, 0x6D3F8152AD6AC212ULL,
-+    0x1DE6B85A1274A0A6ULL, 0xEB3D688A309C180EULL, 0xAF9A3C407BA1DF15ULL,
-+    0xE6FA141DF95A56DBULL, 0xB54B1597B61D0A75ULL, 0xA20D64E5683B9FD1ULL,
-+    0xD660FAA79559C51FULL, 0xAD107E1E9123A9D0ULL
-+};
-+
-+static const BN_ULONG dh2048_224_g[] = {
-+    0x84B890D3191F2BFAULL, 0x81BC087F2A7065B3ULL, 0x19C418E1F6EC0179ULL,
-+    0x7B5A0F1C71CFFF4CULL, 0xEDFE72FE9B6AA4BDULL, 0x81E1BCFE94B30269ULL,
-+    0x566AFBB48D6C0191ULL, 0xB539CCE3409D13CDULL, 0x6AA21E7F5F2FF381ULL,
-+    0xD9E263E4770589EFULL, 0x10E183EDD19963DDULL, 0xB70A8137150B8EEBULL,
-+    0x051AE3D428C8F8ACULL, 0xBB77A86F0C1AB15BULL, 0x6E3025E316A330EFULL,
-+    0x19529A45D6F83456ULL, 0xF180EB34118E98D1ULL, 0xB5F6C6B250717CBEULL,
-+    0x09939D54DA7460CDULL, 0xE247150422EA1ED4ULL, 0xB8A762D0521BC98AULL,
-+    0xF4D027275AC1348BULL, 0xC17669101999024AULL, 0xBE5E9001A8D66AD7ULL,
-+    0xC57DB17C620A8652ULL, 0xAB739D7700C29F52ULL, 0xDD921F01A70C4AFAULL,
-+    0xA6824A4E10B9A6F0ULL, 0x74866A08CFE4FFE3ULL, 0x6CDEBE7B89998CAFULL,
-+    0x9DF30B5C8FFDAC50ULL, 0xAC4032EF4F2D9AE3ULL
-+};
-+
-+static const BN_ULONG dh2048_224_q[] = {
-+    0xBF389A99B36371EBULL, 0x1F80535A4738CEBCULL, 0xC58D93FE99717710ULL,
-+    0x00000000801C0D34ULL
-+};
-+
-+static const BN_ULONG dh2048_256_p[] = {
-+    0xDB094AE91E1A1597ULL, 0x693877FAD7EF09CAULL, 0x6116D2276E11715FULL,
-+    0xA4B54330C198AF12ULL, 0x75F26375D7014103ULL, 0xC3A3960A54E710C3ULL,
-+    0xDED4010ABD0BE621ULL, 0xC0B857F689962856ULL, 0xB3CA3F7971506026ULL,
-+    0x1CCACB83E6B486F6ULL, 0x67E144E514056425ULL, 0xF6A167B5A41825D9ULL,
-+    0x3AD8347796524D8EULL, 0xF13C6D9A51BFA4ABULL, 0x2D52526735488A0EULL,
-+    0xB63ACAE1CAA6B790ULL, 0x4FDB70C581B23F76ULL, 0xBC39A0BF12307F5CULL,
-+    0xB941F54EB1E59BB8ULL, 0x6C5BFC11D45F9088ULL, 0x22E0B1EF4275BF7BULL,
-+    0x91F9E6725B4758C0ULL, 0x5A8A9D306BCF67EDULL, 0x209E0C6497517ABDULL,
-+    0x3BF4296D830E9A7CULL, 0x16C3D91134096FAAULL, 0xFAF7DF4561B2AA30ULL,
-+    0xE00DF8F1D61957D4ULL, 0x5D2CEED4435E3B00ULL, 0x8CEEF608660DD0F2ULL,
-+    0xFFBBD19C65195999ULL, 0x87A8E61DB4B6663CULL
-+};
-+
-+static const BN_ULONG dh2048_256_g[] = {
-+    0x664B4C0F6CC41659ULL, 0x5E2327CFEF98C582ULL, 0xD647D148D4795451ULL,
-+    0x2F63078490F00EF8ULL, 0x184B523D1DB246C3ULL, 0xC7891428CDC67EB6ULL,
-+    0x7FD028370DF92B52ULL, 0xB3353BBB64E0EC37ULL, 0xECD06E1557CD0915ULL,
-+    0xB7D2BBD2DF016199ULL, 0xC8484B1E052588B9ULL, 0xDB2A3B7313D3FE14ULL,
-+    0xD052B985D182EA0AULL, 0xA4BD1BFFE83B9C80ULL, 0xDFC967C1FB3F2E55ULL,
-+    0xB5045AF2767164E1ULL, 0x1D14348F6F2F9193ULL, 0x64E67982428EBC83ULL,
-+    0x8AC376D282D6ED38ULL, 0x777DE62AAAB8A862ULL, 0xDDF463E5E9EC144BULL,
-+    0x0196F931C77A57F2ULL, 0xA55AE31341000A65ULL, 0x901228F8C28CBB18ULL,
-+    0xBC3773BF7E8C6F62ULL, 0xBE3A6C1B0C6B47B1ULL, 0xFF4FED4AAC0BB555ULL,
-+    0x10DBC15077BE463FULL, 0x07F4793A1A0BA125ULL, 0x4CA7B18F21EF2054ULL,
-+    0x2E77506660EDBD48ULL, 0x3FB32C9B73134D0BULL
-+};
-+
-+static const BN_ULONG dh2048_256_q[] = {
-+    0xA308B0FE64F5FBD3ULL, 0x99B1A47D1EB3750BULL, 0xB447997640129DA2ULL,
-+    0x8CF83642A709A097ULL
-+};
-+
-+# elif BN_BITS2 == 32
-+
-+static const BN_ULONG dh1024_160_p[] = {
-+    0x2E4A4371, 0xDF1FB2BC, 0x6D4DA708, 0xE68CFDA7, 0x365C1A65, 0x45BF37DF,
-+    0x0DC8B4BD, 0xA151AF5F, 0xF55BCCC0, 0xFAA31A4F, 0xE5644738, 0x4EFFD6FA,
-+    0x219A7372, 0x98488E9C, 0x90C4BD70, 0xACCBDD7D, 0xD49B83BF, 0x24975C3C,
-+    0xA9061123, 0x13ECB4AE, 0x2EE652C0, 0x9838EF1E, 0x75A23D18, 0x6073E286,
-+    0x52D23B61, 0x9A6A9DCA, 0xFB06A3C6, 0x52C99FBC, 0xAE5D54EC, 0xDE92DE5E,
-+    0xA080E01D, 0xB10B8F96
-+};
-+
-+static const BN_ULONG dh1024_160_g[] = {
-+    0x22B3B2E5, 0x855E6EEB, 0xF97C2A24, 0x858F4DCE, 0x18D08BC8, 0x2D779D59,
-+    0x8E73AFA3, 0xD662A4D1, 0x69B6A28A, 0x1DBF0A01, 0x7A091F53, 0xA6A24C08,
-+    0x63F80A76, 0x909D0D22, 0xB9A92EE1, 0xD7FBD7D3, 0x9E2749F4, 0x5E91547F,
-+    0xB01B886A, 0x160217B4, 0x5504F213, 0x777E690F, 0x5C41564B, 0x266FEA1E,
-+    0x14266D31, 0xD6406CFF, 0x58AC507F, 0xF8104DD2, 0xEFB99905, 0x6765A442,
-+    0xC3FD3412, 0xA4D1CBD5
-+};
-+
-+static const BN_ULONG dh1024_160_q[] = {
-+    0x49462353, 0x64B7CB9D, 0x8ABA4E7D, 0x81A8DF27, 0xF518AA87
-+};
-+
-+static const BN_ULONG dh2048_224_p[] = {
-+    0x0C10E64F, 0x0AC4DFFE, 0x4E71B81C, 0xCF9DE538, 0xFFA31F71, 0x7EF363E2,
-+    0x6B8E75B9, 0xE3FB73C1, 0x4BA80A29, 0xC9B53DCF, 0x16E79763, 0x23F10B0E,
-+    0x13042E9B, 0xC52172E4, 0xC928B2B9, 0xBE60E69C, 0xB9E587E8, 0x80CD86A1,
-+    0x98C641A4, 0x315D75E1, 0x44328387, 0xCDF93ACC, 0xDC0A486D, 0x15987D9A,
-+    0x1FD5A074, 0x7310F712, 0xDE31EFDC, 0x278273C7, 0x415D9330, 0x1602E714,
-+    0xBC8985DB, 0x81286130, 0x70918836, 0xB3BF8A31, 0xB9C49708, 0x6A00E0A0,
-+    0x8BBC27BE, 0xC6BA0B2C, 0xED34DBF6, 0xC9F98D11, 0xB6C12207, 0x7AD5B7D0,
-+    0x55B7394B, 0xD91E8FEF, 0xEFDA4DF8, 0x9037C9ED, 0xAD6AC212, 0x6D3F8152,
-+    0x1274A0A6, 0x1DE6B85A, 0x309C180E, 0xEB3D688A, 0x7BA1DF15, 0xAF9A3C40,
-+    0xF95A56DB, 0xE6FA141D, 0xB61D0A75, 0xB54B1597, 0x683B9FD1, 0xA20D64E5,
-+    0x9559C51F, 0xD660FAA7, 0x9123A9D0, 0xAD107E1E
-+};
-+
-+static const BN_ULONG dh2048_224_g[] = {
-+    0x191F2BFA, 0x84B890D3, 0x2A7065B3, 0x81BC087F, 0xF6EC0179, 0x19C418E1,
-+    0x71CFFF4C, 0x7B5A0F1C, 0x9B6AA4BD, 0xEDFE72FE, 0x94B30269, 0x81E1BCFE,
-+    0x8D6C0191, 0x566AFBB4, 0x409D13CD, 0xB539CCE3, 0x5F2FF381, 0x6AA21E7F,
-+    0x770589EF, 0xD9E263E4, 0xD19963DD, 0x10E183ED, 0x150B8EEB, 0xB70A8137,
-+    0x28C8F8AC, 0x051AE3D4, 0x0C1AB15B, 0xBB77A86F, 0x16A330EF, 0x6E3025E3,
-+    0xD6F83456, 0x19529A45, 0x118E98D1, 0xF180EB34, 0x50717CBE, 0xB5F6C6B2,
-+    0xDA7460CD, 0x09939D54, 0x22EA1ED4, 0xE2471504, 0x521BC98A, 0xB8A762D0,
-+    0x5AC1348B, 0xF4D02727, 0x1999024A, 0xC1766910, 0xA8D66AD7, 0xBE5E9001,
-+    0x620A8652, 0xC57DB17C, 0x00C29F52, 0xAB739D77, 0xA70C4AFA, 0xDD921F01,
-+    0x10B9A6F0, 0xA6824A4E, 0xCFE4FFE3, 0x74866A08, 0x89998CAF, 0x6CDEBE7B,
-+    0x8FFDAC50, 0x9DF30B5C, 0x4F2D9AE3, 0xAC4032EF
-+};
-+
-+static const BN_ULONG dh2048_224_q[] = {
-+    0xB36371EB, 0xBF389A99, 0x4738CEBC, 0x1F80535A, 0x99717710, 0xC58D93FE,
-+    0x801C0D34
-+};
-+
-+static const BN_ULONG dh2048_256_p[] = {
-+    0x1E1A1597, 0xDB094AE9, 0xD7EF09CA, 0x693877FA, 0x6E11715F, 0x6116D227,
-+    0xC198AF12, 0xA4B54330, 0xD7014103, 0x75F26375, 0x54E710C3, 0xC3A3960A,
-+    0xBD0BE621, 0xDED4010A, 0x89962856, 0xC0B857F6, 0x71506026, 0xB3CA3F79,
-+    0xE6B486F6, 0x1CCACB83, 0x14056425, 0x67E144E5, 0xA41825D9, 0xF6A167B5,
-+    0x96524D8E, 0x3AD83477, 0x51BFA4AB, 0xF13C6D9A, 0x35488A0E, 0x2D525267,
-+    0xCAA6B790, 0xB63ACAE1, 0x81B23F76, 0x4FDB70C5, 0x12307F5C, 0xBC39A0BF,
-+    0xB1E59BB8, 0xB941F54E, 0xD45F9088, 0x6C5BFC11, 0x4275BF7B, 0x22E0B1EF,
-+    0x5B4758C0, 0x91F9E672, 0x6BCF67ED, 0x5A8A9D30, 0x97517ABD, 0x209E0C64,
-+    0x830E9A7C, 0x3BF4296D, 0x34096FAA, 0x16C3D911, 0x61B2AA30, 0xFAF7DF45,
-+    0xD61957D4, 0xE00DF8F1, 0x435E3B00, 0x5D2CEED4, 0x660DD0F2, 0x8CEEF608,
-+    0x65195999, 0xFFBBD19C, 0xB4B6663C, 0x87A8E61D
-+};
-+
-+static const BN_ULONG dh2048_256_g[] = {
-+    0x6CC41659, 0x664B4C0F, 0xEF98C582, 0x5E2327CF, 0xD4795451, 0xD647D148,
-+    0x90F00EF8, 0x2F630784, 0x1DB246C3, 0x184B523D, 0xCDC67EB6, 0xC7891428,
-+    0x0DF92B52, 0x7FD02837, 0x64E0EC37, 0xB3353BBB, 0x57CD0915, 0xECD06E15,
-+    0xDF016199, 0xB7D2BBD2, 0x052588B9, 0xC8484B1E, 0x13D3FE14, 0xDB2A3B73,
-+    0xD182EA0A, 0xD052B985, 0xE83B9C80, 0xA4BD1BFF, 0xFB3F2E55, 0xDFC967C1,
-+    0x767164E1, 0xB5045AF2, 0x6F2F9193, 0x1D14348F, 0x428EBC83, 0x64E67982,
-+    0x82D6ED38, 0x8AC376D2, 0xAAB8A862, 0x777DE62A, 0xE9EC144B, 0xDDF463E5,
-+    0xC77A57F2, 0x0196F931, 0x41000A65, 0xA55AE313, 0xC28CBB18, 0x901228F8,
-+    0x7E8C6F62, 0xBC3773BF, 0x0C6B47B1, 0xBE3A6C1B, 0xAC0BB555, 0xFF4FED4A,
-+    0x77BE463F, 0x10DBC150, 0x1A0BA125, 0x07F4793A, 0x21EF2054, 0x4CA7B18F,
-+    0x60EDBD48, 0x2E775066, 0x73134D0B, 0x3FB32C9B
-+};
-+
-+static const BN_ULONG dh2048_256_q[] = {
-+    0x64F5FBD3, 0xA308B0FE, 0x1EB3750B, 0x99B1A47D, 0x40129DA2, 0xB4479976,
-+    0xA709A097, 0x8CF83642
-+};
-+
-+# else
-+#  error "unsupported BN_BITS2"
-+# endif
-+
-+/* Macro to make a BIGNUM from static data */
-+
-+# define make_dh_bn(x) extern const BIGNUM _bignum_##x; \
-+                       const BIGNUM _bignum_##x = { (BN_ULONG *) x, \
-+                        OSSL_NELEM(x),\
-+                        OSSL_NELEM(x),\
-+                        0, BN_FLG_STATIC_DATA };
-+
-+
-+make_dh_bn(dh1024_160_p)
-+make_dh_bn(dh1024_160_g)
-+make_dh_bn(dh1024_160_q)
-+make_dh_bn(dh2048_224_p)
-+make_dh_bn(dh2048_224_g)
-+make_dh_bn(dh2048_224_q)
-+make_dh_bn(dh2048_256_p)
-+make_dh_bn(dh2048_256_g)
-+make_dh_bn(dh2048_256_q)
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_div.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_div.c
-new file mode 100644
-index 0000000..5e620b2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_div.c
-@@ -0,0 +1,423 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+/* The old slow way */
-+#if 0
-+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
-+           BN_CTX *ctx)
-+{
-+    int i, nm, nd;
-+    int ret = 0;
-+    BIGNUM *D;
-+
-+    bn_check_top(m);
-+    bn_check_top(d);
-+    if (BN_is_zero(d)) {
-+        BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
-+        return (0);
-+    }
-+
-+    if (BN_ucmp(m, d) < 0) {
-+        if (rem != NULL) {
-+            if (BN_copy(rem, m) == NULL)
-+                return (0);
-+        }
-+        if (dv != NULL)
-+            BN_zero(dv);
-+        return (1);
-+    }
-+
-+    BN_CTX_start(ctx);
-+    D = BN_CTX_get(ctx);
-+    if (dv == NULL)
-+        dv = BN_CTX_get(ctx);
-+    if (rem == NULL)
-+        rem = BN_CTX_get(ctx);
-+    if (D == NULL || dv == NULL || rem == NULL)
-+        goto end;
-+
-+    nd = BN_num_bits(d);
-+    nm = BN_num_bits(m);
-+    if (BN_copy(D, d) == NULL)
-+        goto end;
-+    if (BN_copy(rem, m) == NULL)
-+        goto end;
-+
-+    /*
-+     * The next 2 are needed so we can do a dv->d[0]|=1 later since
-+     * BN_lshift1 will only work once there is a value :-)
-+     */
-+    BN_zero(dv);
-+    if (bn_wexpand(dv, 1) == NULL)
-+        goto end;
-+    dv->top = 1;
-+
-+    if (!BN_lshift(D, D, nm - nd))
-+        goto end;
-+    for (i = nm - nd; i >= 0; i--) {
-+        if (!BN_lshift1(dv, dv))
-+            goto end;
-+        if (BN_ucmp(rem, D) >= 0) {
-+            dv->d[0] |= 1;
-+            if (!BN_usub(rem, rem, D))
-+                goto end;
-+        }
-+/* CAN IMPROVE (and have now :=) */
-+        if (!BN_rshift1(D, D))
-+            goto end;
-+    }
-+    rem->neg = BN_is_zero(rem) ? 0 : m->neg;
-+    dv->neg = m->neg ^ d->neg;
-+    ret = 1;
-+ end:
-+    BN_CTX_end(ctx);
-+    return (ret);
-+}
-+
-+#else
-+
-+# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
-+    && !defined(PEDANTIC) && !defined(BN_DIV3W)
-+#  if defined(__GNUC__) && __GNUC__>=2
-+#   if defined(__i386) || defined (__i386__)
-+   /*-
-+    * There were two reasons for implementing this template:
-+    * - GNU C generates a call to a function (__udivdi3 to be exact)
-+    *   in reply to ((((BN_ULLONG)n0)<
-+    */
-+#    undef bn_div_words
-+#    define bn_div_words(n0,n1,d0)                \
-+        ({  asm volatile (                      \
-+                "divl   %4"                     \
-+                : "=a"(q), "=d"(rem)            \
-+                : "a"(n1), "d"(n0), "r"(d0)     \
-+                : "cc");                        \
-+            q;                                  \
-+        })
-+#    define REMAINDER_IS_ALREADY_CALCULATED
-+#   elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
-+   /*
-+    * Same story here, but it's 128-bit by 64-bit division. Wow!
-+    *                                   
-+    */
-+#    undef bn_div_words
-+#    define bn_div_words(n0,n1,d0)                \
-+        ({  asm volatile (                      \
-+                "divq   %4"                     \
-+                : "=a"(q), "=d"(rem)            \
-+                : "a"(n1), "d"(n0), "r"(d0)     \
-+                : "cc");                        \
-+            q;                                  \
-+        })
-+#    define REMAINDER_IS_ALREADY_CALCULATED
-+#   endif                       /* __ */
-+#  endif                        /* __GNUC__ */
-+# endif                         /* OPENSSL_NO_ASM */
-+
-+/*-
-+ * BN_div computes  dv := num / divisor, rounding towards
-+ * zero, and sets up rm  such that  dv*divisor + rm = num  holds.
-+ * Thus:
-+ *     dv->neg == num->neg ^ divisor->neg  (unless the result is zero)
-+ *     rm->neg == num->neg                 (unless the remainder is zero)
-+ * If 'dv' or 'rm' is NULL, the respective value is not returned.
-+ */
-+int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
-+           BN_CTX *ctx)
-+{
-+    int norm_shift, i, loop;
-+    BIGNUM *tmp, wnum, *snum, *sdiv, *res;
-+    BN_ULONG *resp, *wnump;
-+    BN_ULONG d0, d1;
-+    int num_n, div_n;
-+    int no_branch = 0;
-+
-+    /*
-+     * Invalid zero-padding would have particularly bad consequences so don't
-+     * just rely on bn_check_top() here (bn_check_top() works only for
-+     * BN_DEBUG builds)
-+     */
-+    if ((num->top > 0 && num->d[num->top - 1] == 0) ||
-+        (divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
-+        BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED);
-+        return 0;
-+    }
-+
-+    bn_check_top(num);
-+    bn_check_top(divisor);
-+
-+    if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0)
-+        || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) {
-+        no_branch = 1;
-+    }
-+
-+    bn_check_top(dv);
-+    bn_check_top(rm);
-+    /*- bn_check_top(num); *//*
-+     * 'num' has been checked already
-+     */
-+    /*- bn_check_top(divisor); *//*
-+     * 'divisor' has been checked already
-+     */
-+
-+    if (BN_is_zero(divisor)) {
-+        BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
-+        return (0);
-+    }
-+
-+    if (!no_branch && BN_ucmp(num, divisor) < 0) {
-+        if (rm != NULL) {
-+            if (BN_copy(rm, num) == NULL)
-+                return (0);
-+        }
-+        if (dv != NULL)
-+            BN_zero(dv);
-+        return (1);
-+    }
-+
-+    BN_CTX_start(ctx);
-+    tmp = BN_CTX_get(ctx);
-+    snum = BN_CTX_get(ctx);
-+    sdiv = BN_CTX_get(ctx);
-+    if (dv == NULL)
-+        res = BN_CTX_get(ctx);
-+    else
-+        res = dv;
-+    if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL)
-+        goto err;
-+
-+    /* First we normalise the numbers */
-+    norm_shift = BN_BITS2 - ((BN_num_bits(divisor)) % BN_BITS2);
-+    if (!(BN_lshift(sdiv, divisor, norm_shift)))
-+        goto err;
-+    sdiv->neg = 0;
-+    norm_shift += BN_BITS2;
-+    if (!(BN_lshift(snum, num, norm_shift)))
-+        goto err;
-+    snum->neg = 0;
-+
-+    if (no_branch) {
-+        /*
-+         * Since we don't know whether snum is larger than sdiv, we pad snum
-+         * with enough zeroes without changing its value.
-+         */
-+        if (snum->top <= sdiv->top + 1) {
-+            if (bn_wexpand(snum, sdiv->top + 2) == NULL)
-+                goto err;
-+            for (i = snum->top; i < sdiv->top + 2; i++)
-+                snum->d[i] = 0;
-+            snum->top = sdiv->top + 2;
-+        } else {
-+            if (bn_wexpand(snum, snum->top + 1) == NULL)
-+                goto err;
-+            snum->d[snum->top] = 0;
-+            snum->top++;
-+        }
-+    }
-+
-+    div_n = sdiv->top;
-+    num_n = snum->top;
-+    loop = num_n - div_n;
-+    /*
-+     * Lets setup a 'window' into snum This is the part that corresponds to
-+     * the current 'area' being divided
-+     */
-+    wnum.neg = 0;
-+    wnum.d = &(snum->d[loop]);
-+    wnum.top = div_n;
-+    /*
-+     * only needed when BN_ucmp messes up the values between top and max
-+     */
-+    wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
-+
-+    /* Get the top 2 words of sdiv */
-+    /* div_n=sdiv->top; */
-+    d0 = sdiv->d[div_n - 1];
-+    d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];
-+
-+    /* pointer to the 'top' of snum */
-+    wnump = &(snum->d[num_n - 1]);
-+
-+    /* Setup to 'res' */
-+    if (!bn_wexpand(res, (loop + 1)))
-+        goto err;
-+    res->neg = (num->neg ^ divisor->neg);
-+    res->top = loop - no_branch;
-+    resp = &(res->d[loop - 1]);
-+
-+    /* space for temp */
-+    if (!bn_wexpand(tmp, (div_n + 1)))
-+        goto err;
-+
-+    if (!no_branch) {
-+        if (BN_ucmp(&wnum, sdiv) >= 0) {
-+            /*
-+             * If BN_DEBUG_RAND is defined BN_ucmp changes (via bn_pollute)
-+             * the const bignum arguments => clean the values between top and
-+             * max again
-+             */
-+            bn_clear_top2max(&wnum);
-+            bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
-+            *resp = 1;
-+        } else
-+            res->top--;
-+    }
-+
-+    /* Increase the resp pointer so that we never create an invalid pointer. */
-+    resp++;
-+
-+    /*
-+     * if res->top == 0 then clear the neg value otherwise decrease the resp
-+     * pointer
-+     */
-+    if (res->top == 0)
-+        res->neg = 0;
-+    else
-+        resp--;
-+
-+    for (i = 0; i < loop - 1; i++, wnump--) {
-+        BN_ULONG q, l0;
-+        /*
-+         * the first part of the loop uses the top two words of snum and sdiv
-+         * to calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv
-+         */
-+# if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
-+        BN_ULONG bn_div_3_words(BN_ULONG *, BN_ULONG, BN_ULONG);
-+        q = bn_div_3_words(wnump, d1, d0);
-+# else
-+        BN_ULONG n0, n1, rem = 0;
-+
-+        n0 = wnump[0];
-+        n1 = wnump[-1];
-+        if (n0 == d0)
-+            q = BN_MASK2;
-+        else {                  /* n0 < d0 */
-+
-+#  ifdef BN_LLONG
-+            BN_ULLONG t2;
-+
-+#   if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
-+            q = (BN_ULONG)(((((BN_ULLONG) n0) << BN_BITS2) | n1) / d0);
-+#   else
-+            q = bn_div_words(n0, n1, d0);
-+#   endif
-+
-+#   ifndef REMAINDER_IS_ALREADY_CALCULATED
-+            /*
-+             * rem doesn't have to be BN_ULLONG. The least we
-+             * know it's less that d0, isn't it?
-+             */
-+            rem = (n1 - q * d0) & BN_MASK2;
-+#   endif
-+            t2 = (BN_ULLONG) d1 *q;
-+
-+            for (;;) {
-+                if (t2 <= ((((BN_ULLONG) rem) << BN_BITS2) | wnump[-2]))
-+                    break;
-+                q--;
-+                rem += d0;
-+                if (rem < d0)
-+                    break;      /* don't let rem overflow */
-+                t2 -= d1;
-+            }
-+#  else                         /* !BN_LLONG */
-+            BN_ULONG t2l, t2h;
-+
-+            q = bn_div_words(n0, n1, d0);
-+#   ifndef REMAINDER_IS_ALREADY_CALCULATED
-+            rem = (n1 - q * d0) & BN_MASK2;
-+#   endif
-+
-+#   if defined(BN_UMULT_LOHI)
-+            BN_UMULT_LOHI(t2l, t2h, d1, q);
-+#   elif defined(BN_UMULT_HIGH)
-+            t2l = d1 * q;
-+            t2h = BN_UMULT_HIGH(d1, q);
-+#   else
-+            {
-+                BN_ULONG ql, qh;
-+                t2l = LBITS(d1);
-+                t2h = HBITS(d1);
-+                ql = LBITS(q);
-+                qh = HBITS(q);
-+                mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */
-+            }
-+#   endif
-+
-+            for (;;) {
-+                if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2])))
-+                    break;
-+                q--;
-+                rem += d0;
-+                if (rem < d0)
-+                    break;      /* don't let rem overflow */
-+                if (t2l < d1)
-+                    t2h--;
-+                t2l -= d1;
-+            }
-+#  endif                        /* !BN_LLONG */
-+        }
-+# endif                         /* !BN_DIV3W */
-+
-+        l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
-+        tmp->d[div_n] = l0;
-+        wnum.d--;
-+        /*
-+         * ingore top values of the bignums just sub the two BN_ULONG arrays
-+         * with bn_sub_words
-+         */
-+        if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) {
-+            /*
-+             * Note: As we have considered only the leading two BN_ULONGs in
-+             * the calculation of q, sdiv * q might be greater than wnum (but
-+             * then (q-1) * sdiv is less or equal than wnum)
-+             */
-+            q--;
-+            if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
-+                /*
-+                 * we can't have an overflow here (assuming that q != 0, but
-+                 * if q == 0 then tmp is zero anyway)
-+                 */
-+                (*wnump)++;
-+        }
-+        /* store part of the result */
-+        resp--;
-+        *resp = q;
-+    }
-+    bn_correct_top(snum);
-+    if (rm != NULL) {
-+        /*
-+         * Keep a copy of the neg flag in num because if rm==num BN_rshift()
-+         * will overwrite it.
-+         */
-+        int neg = num->neg;
-+        BN_rshift(rm, snum, norm_shift);
-+        if (!BN_is_zero(rm))
-+            rm->neg = neg;
-+        bn_check_top(rm);
-+    }
-+    if (no_branch)
-+        bn_correct_top(res);
-+    BN_CTX_end(ctx);
-+    return (1);
-+ err:
-+    bn_check_top(rm);
-+    BN_CTX_end(ctx);
-+    return (0);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_err.c
-new file mode 100644
-index 0000000..5fe9db9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_err.c
-@@ -0,0 +1,107 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason)
-+
-+static ERR_STRING_DATA BN_str_functs[] = {
-+    {ERR_FUNC(BN_F_BNRAND), "bnrand"},
-+    {ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX), "BN_BLINDING_convert_ex"},
-+    {ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM), "BN_BLINDING_create_param"},
-+    {ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX), "BN_BLINDING_invert_ex"},
-+    {ERR_FUNC(BN_F_BN_BLINDING_NEW), "BN_BLINDING_new"},
-+    {ERR_FUNC(BN_F_BN_BLINDING_UPDATE), "BN_BLINDING_update"},
-+    {ERR_FUNC(BN_F_BN_BN2DEC), "BN_bn2dec"},
-+    {ERR_FUNC(BN_F_BN_BN2HEX), "BN_bn2hex"},
-+    {ERR_FUNC(BN_F_BN_COMPUTE_WNAF), "bn_compute_wNAF"},
-+    {ERR_FUNC(BN_F_BN_CTX_GET), "BN_CTX_get"},
-+    {ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"},
-+    {ERR_FUNC(BN_F_BN_CTX_START), "BN_CTX_start"},
-+    {ERR_FUNC(BN_F_BN_DIV), "BN_div"},
-+    {ERR_FUNC(BN_F_BN_DIV_RECP), "BN_div_recp"},
-+    {ERR_FUNC(BN_F_BN_EXP), "BN_exp"},
-+    {ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "bn_expand_internal"},
-+    {ERR_FUNC(BN_F_BN_GENCB_NEW), "BN_GENCB_new"},
-+    {ERR_FUNC(BN_F_BN_GENERATE_DSA_NONCE), "BN_generate_dsa_nonce"},
-+    {ERR_FUNC(BN_F_BN_GENERATE_PRIME_EX), "BN_generate_prime_ex"},
-+    {ERR_FUNC(BN_F_BN_GF2M_MOD), "BN_GF2m_mod"},
-+    {ERR_FUNC(BN_F_BN_GF2M_MOD_EXP), "BN_GF2m_mod_exp"},
-+    {ERR_FUNC(BN_F_BN_GF2M_MOD_MUL), "BN_GF2m_mod_mul"},
-+    {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD), "BN_GF2m_mod_solve_quad"},
-+    {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"},
-+    {ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"},
-+    {ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"},
-+    {ERR_FUNC(BN_F_BN_LSHIFT), "BN_lshift"},
-+    {ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"},
-+    {ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"},
-+    {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"},
-+    {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD), "BN_mod_exp_mont_word"},
-+    {ERR_FUNC(BN_F_BN_MOD_EXP_RECP), "BN_mod_exp_recp"},
-+    {ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE), "BN_mod_exp_simple"},
-+    {ERR_FUNC(BN_F_BN_MOD_INVERSE), "BN_mod_inverse"},
-+    {ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH), "BN_mod_inverse_no_branch"},
-+    {ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK), "BN_mod_lshift_quick"},
-+    {ERR_FUNC(BN_F_BN_MOD_SQRT), "BN_mod_sqrt"},
-+    {ERR_FUNC(BN_F_BN_MPI2BN), "BN_mpi2bn"},
-+    {ERR_FUNC(BN_F_BN_NEW), "BN_new"},
-+    {ERR_FUNC(BN_F_BN_RAND), "BN_rand"},
-+    {ERR_FUNC(BN_F_BN_RAND_RANGE), "BN_rand_range"},
-+    {ERR_FUNC(BN_F_BN_RSHIFT), "BN_rshift"},
-+    {ERR_FUNC(BN_F_BN_SET_WORDS), "bn_set_words"},
-+    {ERR_FUNC(BN_F_BN_USUB), "BN_usub"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA BN_str_reasons[] = {
-+    {ERR_REASON(BN_R_ARG2_LT_ARG3), "arg2 lt arg3"},
-+    {ERR_REASON(BN_R_BAD_RECIPROCAL), "bad reciprocal"},
-+    {ERR_REASON(BN_R_BIGNUM_TOO_LONG), "bignum too long"},
-+    {ERR_REASON(BN_R_BITS_TOO_SMALL), "bits too small"},
-+    {ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"},
-+    {ERR_REASON(BN_R_DIV_BY_ZERO), "div by zero"},
-+    {ERR_REASON(BN_R_ENCODING_ERROR), "encoding error"},
-+    {ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA),
-+     "expand on static bignum data"},
-+    {ERR_REASON(BN_R_INPUT_NOT_REDUCED), "input not reduced"},
-+    {ERR_REASON(BN_R_INVALID_LENGTH), "invalid length"},
-+    {ERR_REASON(BN_R_INVALID_RANGE), "invalid range"},
-+    {ERR_REASON(BN_R_INVALID_SHIFT), "invalid shift"},
-+    {ERR_REASON(BN_R_NOT_A_SQUARE), "not a square"},
-+    {ERR_REASON(BN_R_NOT_INITIALIZED), "not initialized"},
-+    {ERR_REASON(BN_R_NO_INVERSE), "no inverse"},
-+    {ERR_REASON(BN_R_NO_SOLUTION), "no solution"},
-+    {ERR_REASON(BN_R_PRIVATE_KEY_TOO_LARGE), "private key too large"},
-+    {ERR_REASON(BN_R_P_IS_NOT_PRIME), "p is not prime"},
-+    {ERR_REASON(BN_R_TOO_MANY_ITERATIONS), "too many iterations"},
-+    {ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES),
-+     "too many temporary variables"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_BN_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(BN_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, BN_str_functs);
-+        ERR_load_strings(0, BN_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp.c
-new file mode 100644
-index 0000000..feeb764
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp.c
-@@ -0,0 +1,1362 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "internal/constant_time_locl.h"
-+#include "bn_lcl.h"
-+
-+#include 
-+#ifdef _WIN32
-+# include 
-+# ifndef alloca
-+#  define alloca _alloca
-+# endif
-+#elif defined(__GNUC__)
-+# ifndef alloca
-+#  define alloca(s) __builtin_alloca((s))
-+# endif
-+#elif defined(__sun)
-+# include 
-+#endif
-+
-+#include "rsaz_exp.h"
-+
-+#undef SPARC_T4_MONT
-+#if defined(OPENSSL_BN_ASM_MONT) && (defined(__sparc__) || defined(__sparc))
-+# include "sparc_arch.h"
-+extern unsigned int OPENSSL_sparcv9cap_P[];
-+# define SPARC_T4_MONT
-+#endif
-+
-+/* maximum precomputation table size for *variable* sliding windows */
-+#define TABLE_SIZE      32
-+
-+/* this one works - simple but works */
-+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
-+{
-+    int i, bits, ret = 0;
-+    BIGNUM *v, *rr;
-+
-+    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
-+        /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
-+        BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    if ((r == a) || (r == p))
-+        rr = BN_CTX_get(ctx);
-+    else
-+        rr = r;
-+    v = BN_CTX_get(ctx);
-+    if (rr == NULL || v == NULL)
-+        goto err;
-+
-+    if (BN_copy(v, a) == NULL)
-+        goto err;
-+    bits = BN_num_bits(p);
-+
-+    if (BN_is_odd(p)) {
-+        if (BN_copy(rr, a) == NULL)
-+            goto err;
-+    } else {
-+        if (!BN_one(rr))
-+            goto err;
-+    }
-+
-+    for (i = 1; i < bits; i++) {
-+        if (!BN_sqr(v, v, ctx))
-+            goto err;
-+        if (BN_is_bit_set(p, i)) {
-+            if (!BN_mul(rr, rr, v, ctx))
-+                goto err;
-+        }
-+    }
-+    if (r != rr && BN_copy(r, rr) == NULL)
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    BN_CTX_end(ctx);
-+    bn_check_top(r);
-+    return (ret);
-+}
-+
-+int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
-+               BN_CTX *ctx)
-+{
-+    int ret;
-+
-+    bn_check_top(a);
-+    bn_check_top(p);
-+    bn_check_top(m);
-+
-+    /*-
-+     * For even modulus  m = 2^k*m_odd, it might make sense to compute
-+     * a^p mod m_odd  and  a^p mod 2^k  separately (with Montgomery
-+     * exponentiation for the odd part), using appropriate exponent
-+     * reductions, and combine the results using the CRT.
-+     *
-+     * For now, we use Montgomery only if the modulus is odd; otherwise,
-+     * exponentiation using the reciprocal-based quick remaindering
-+     * algorithm is used.
-+     *
-+     * (Timing obtained with expspeed.c [computations  a^p mod m
-+     * where  a, p, m  are of the same length: 256, 512, 1024, 2048,
-+     * 4096, 8192 bits], compared to the running time of the
-+     * standard algorithm:
-+     *
-+     *   BN_mod_exp_mont   33 .. 40 %  [AMD K6-2, Linux, debug configuration]
-+     *                     55 .. 77 %  [UltraSparc processor, but
-+     *                                  debug-solaris-sparcv8-gcc conf.]
-+     *
-+     *   BN_mod_exp_recp   50 .. 70 %  [AMD K6-2, Linux, debug configuration]
-+     *                     62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
-+     *
-+     * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
-+     * at 2048 and more bits, but at 512 and 1024 bits, it was
-+     * slower even than the standard algorithm!
-+     *
-+     * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
-+     * should be obtained when the new Montgomery reduction code
-+     * has been integrated into OpenSSL.)
-+     */
-+
-+#define MONT_MUL_MOD
-+#define MONT_EXP_WORD
-+#define RECP_MUL_MOD
-+
-+#ifdef MONT_MUL_MOD
-+    /*
-+     * I have finally been able to take out this pre-condition of the top bit
-+     * being set.  It was caused by an error in BN_div with negatives.  There
-+     * was also another problem when for a^b%m a >= m.  eay 07-May-97
-+     */
-+    /* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
-+
-+    if (BN_is_odd(m)) {
-+# ifdef MONT_EXP_WORD
-+        if (a->top == 1 && !a->neg
-+            && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) {
-+            BN_ULONG A = a->d[0];
-+            ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL);
-+        } else
-+# endif
-+            ret = BN_mod_exp_mont(r, a, p, m, ctx, NULL);
-+    } else
-+#endif
-+#ifdef RECP_MUL_MOD
-+    {
-+        ret = BN_mod_exp_recp(r, a, p, m, ctx);
-+    }
-+#else
-+    {
-+        ret = BN_mod_exp_simple(r, a, p, m, ctx);
-+    }
-+#endif
-+
-+    bn_check_top(r);
-+    return (ret);
-+}
-+
-+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-+                    const BIGNUM *m, BN_CTX *ctx)
-+{
-+    int i, j, bits, ret = 0, wstart, wend, window, wvalue;
-+    int start = 1;
-+    BIGNUM *aa;
-+    /* Table of variables obtained from 'ctx' */
-+    BIGNUM *val[TABLE_SIZE];
-+    BN_RECP_CTX recp;
-+
-+    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
-+        /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
-+        BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+
-+    bits = BN_num_bits(p);
-+    if (bits == 0) {
-+        /* x**0 mod 1 is still zero. */
-+        if (BN_is_one(m)) {
-+            ret = 1;
-+            BN_zero(r);
-+        } else {
-+            ret = BN_one(r);
-+        }
-+        return ret;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    aa = BN_CTX_get(ctx);
-+    val[0] = BN_CTX_get(ctx);
-+    if (!aa || !val[0])
-+        goto err;
-+
-+    BN_RECP_CTX_init(&recp);
-+    if (m->neg) {
-+        /* ignore sign of 'm' */
-+        if (!BN_copy(aa, m))
-+            goto err;
-+        aa->neg = 0;
-+        if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0)
-+            goto err;
-+    } else {
-+        if (BN_RECP_CTX_set(&recp, m, ctx) <= 0)
-+            goto err;
-+    }
-+
-+    if (!BN_nnmod(val[0], a, m, ctx))
-+        goto err;               /* 1 */
-+    if (BN_is_zero(val[0])) {
-+        BN_zero(r);
-+        ret = 1;
-+        goto err;
-+    }
-+
-+    window = BN_window_bits_for_exponent_size(bits);
-+    if (window > 1) {
-+        if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx))
-+            goto err;           /* 2 */
-+        j = 1 << (window - 1);
-+        for (i = 1; i < j; i++) {
-+            if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
-+                !BN_mod_mul_reciprocal(val[i], val[i - 1], aa, &recp, ctx))
-+                goto err;
-+        }
-+    }
-+
-+    start = 1;                  /* This is used to avoid multiplication etc
-+                                 * when there is only the value '1' in the
-+                                 * buffer. */
-+    wvalue = 0;                 /* The 'value' of the window */
-+    wstart = bits - 1;          /* The top bit of the window */
-+    wend = 0;                   /* The bottom bit of the window */
-+
-+    if (!BN_one(r))
-+        goto err;
-+
-+    for (;;) {
-+        if (BN_is_bit_set(p, wstart) == 0) {
-+            if (!start)
-+                if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx))
-+                    goto err;
-+            if (wstart == 0)
-+                break;
-+            wstart--;
-+            continue;
-+        }
-+        /*
-+         * We now have wstart on a 'set' bit, we now need to work out how bit
-+         * a window to do.  To do this we need to scan forward until the last
-+         * set bit before the end of the window
-+         */
-+        j = wstart;
-+        wvalue = 1;
-+        wend = 0;
-+        for (i = 1; i < window; i++) {
-+            if (wstart - i < 0)
-+                break;
-+            if (BN_is_bit_set(p, wstart - i)) {
-+                wvalue <<= (i - wend);
-+                wvalue |= 1;
-+                wend = i;
-+            }
-+        }
-+
-+        /* wend is the size of the current window */
-+        j = wend + 1;
-+        /* add the 'bytes above' */
-+        if (!start)
-+            for (i = 0; i < j; i++) {
-+                if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx))
-+                    goto err;
-+            }
-+
-+        /* wvalue will be an odd number < 2^window */
-+        if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], &recp, ctx))
-+            goto err;
-+
-+        /* move the 'window' down further */
-+        wstart -= wend + 1;
-+        wvalue = 0;
-+        start = 0;
-+        if (wstart < 0)
-+            break;
-+    }
-+    ret = 1;
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_RECP_CTX_free(&recp);
-+    bn_check_top(r);
-+    return (ret);
-+}
-+
-+int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
-+                    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
-+{
-+    int i, j, bits, ret = 0, wstart, wend, window, wvalue;
-+    int start = 1;
-+    BIGNUM *d, *r;
-+    const BIGNUM *aa;
-+    /* Table of variables obtained from 'ctx' */
-+    BIGNUM *val[TABLE_SIZE];
-+    BN_MONT_CTX *mont = NULL;
-+
-+    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
-+        return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
-+    }
-+
-+    bn_check_top(a);
-+    bn_check_top(p);
-+    bn_check_top(m);
-+
-+    if (!BN_is_odd(m)) {
-+        BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
-+        return (0);
-+    }
-+    bits = BN_num_bits(p);
-+    if (bits == 0) {
-+        /* x**0 mod 1 is still zero. */
-+        if (BN_is_one(m)) {
-+            ret = 1;
-+            BN_zero(rr);
-+        } else {
-+            ret = BN_one(rr);
-+        }
-+        return ret;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    d = BN_CTX_get(ctx);
-+    r = BN_CTX_get(ctx);
-+    val[0] = BN_CTX_get(ctx);
-+    if (!d || !r || !val[0])
-+        goto err;
-+
-+    /*
-+     * If this is not done, things will break in the montgomery part
-+     */
-+
-+    if (in_mont != NULL)
-+        mont = in_mont;
-+    else {
-+        if ((mont = BN_MONT_CTX_new()) == NULL)
-+            goto err;
-+        if (!BN_MONT_CTX_set(mont, m, ctx))
-+            goto err;
-+    }
-+
-+    if (a->neg || BN_ucmp(a, m) >= 0) {
-+        if (!BN_nnmod(val[0], a, m, ctx))
-+            goto err;
-+        aa = val[0];
-+    } else
-+        aa = a;
-+    if (BN_is_zero(aa)) {
-+        BN_zero(rr);
-+        ret = 1;
-+        goto err;
-+    }
-+    if (!BN_to_montgomery(val[0], aa, mont, ctx))
-+        goto err;               /* 1 */
-+
-+    window = BN_window_bits_for_exponent_size(bits);
-+    if (window > 1) {
-+        if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))
-+            goto err;           /* 2 */
-+        j = 1 << (window - 1);
-+        for (i = 1; i < j; i++) {
-+            if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
-+                !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx))
-+                goto err;
-+        }
-+    }
-+
-+    start = 1;                  /* This is used to avoid multiplication etc
-+                                 * when there is only the value '1' in the
-+                                 * buffer. */
-+    wvalue = 0;                 /* The 'value' of the window */
-+    wstart = bits - 1;          /* The top bit of the window */
-+    wend = 0;                   /* The bottom bit of the window */
-+
-+#if 1                           /* by Shay Gueron's suggestion */
-+    j = m->top;                 /* borrow j */
-+    if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
-+        if (bn_wexpand(r, j) == NULL)
-+            goto err;
-+        /* 2^(top*BN_BITS2) - m */
-+        r->d[0] = (0 - m->d[0]) & BN_MASK2;
-+        for (i = 1; i < j; i++)
-+            r->d[i] = (~m->d[i]) & BN_MASK2;
-+        r->top = j;
-+        /*
-+         * Upper words will be zero if the corresponding words of 'm' were
-+         * 0xfff[...], so decrement r->top accordingly.
-+         */
-+        bn_correct_top(r);
-+    } else
-+#endif
-+    if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
-+        goto err;
-+    for (;;) {
-+        if (BN_is_bit_set(p, wstart) == 0) {
-+            if (!start) {
-+                if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
-+                    goto err;
-+            }
-+            if (wstart == 0)
-+                break;
-+            wstart--;
-+            continue;
-+        }
-+        /*
-+         * We now have wstart on a 'set' bit, we now need to work out how bit
-+         * a window to do.  To do this we need to scan forward until the last
-+         * set bit before the end of the window
-+         */
-+        j = wstart;
-+        wvalue = 1;
-+        wend = 0;
-+        for (i = 1; i < window; i++) {
-+            if (wstart - i < 0)
-+                break;
-+            if (BN_is_bit_set(p, wstart - i)) {
-+                wvalue <<= (i - wend);
-+                wvalue |= 1;
-+                wend = i;
-+            }
-+        }
-+
-+        /* wend is the size of the current window */
-+        j = wend + 1;
-+        /* add the 'bytes above' */
-+        if (!start)
-+            for (i = 0; i < j; i++) {
-+                if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
-+                    goto err;
-+            }
-+
-+        /* wvalue will be an odd number < 2^window */
-+        if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))
-+            goto err;
-+
-+        /* move the 'window' down further */
-+        wstart -= wend + 1;
-+        wvalue = 0;
-+        start = 0;
-+        if (wstart < 0)
-+            break;
-+    }
-+#if defined(SPARC_T4_MONT)
-+    if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
-+        j = mont->N.top;        /* borrow j */
-+        val[0]->d[0] = 1;       /* borrow val[0] */
-+        for (i = 1; i < j; i++)
-+            val[0]->d[i] = 0;
-+        val[0]->top = j;
-+        if (!BN_mod_mul_montgomery(rr, r, val[0], mont, ctx))
-+            goto err;
-+    } else
-+#endif
-+    if (!BN_from_montgomery(rr, r, mont, ctx))
-+        goto err;
-+    ret = 1;
-+ err:
-+    if (in_mont == NULL)
-+        BN_MONT_CTX_free(mont);
-+    BN_CTX_end(ctx);
-+    bn_check_top(rr);
-+    return (ret);
-+}
-+
-+#if defined(SPARC_T4_MONT)
-+static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos)
-+{
-+    BN_ULONG ret = 0;
-+    int wordpos;
-+
-+    wordpos = bitpos / BN_BITS2;
-+    bitpos %= BN_BITS2;
-+    if (wordpos >= 0 && wordpos < a->top) {
-+        ret = a->d[wordpos] & BN_MASK2;
-+        if (bitpos) {
-+            ret >>= bitpos;
-+            if (++wordpos < a->top)
-+                ret |= a->d[wordpos] << (BN_BITS2 - bitpos);
-+        }
-+    }
-+
-+    return ret & BN_MASK2;
-+}
-+#endif
-+
-+/*
-+ * BN_mod_exp_mont_consttime() stores the precomputed powers in a specific
-+ * layout so that accessing any of these table values shows the same access
-+ * pattern as far as cache lines are concerned.  The following functions are
-+ * used to transfer a BIGNUM from/to that table.
-+ */
-+
-+static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top,
-+                                        unsigned char *buf, int idx,
-+                                        int window)
-+{
-+    int i, j;
-+    int width = 1 << window;
-+    BN_ULONG *table = (BN_ULONG *)buf;
-+
-+    if (top > b->top)
-+        top = b->top;           /* this works because 'buf' is explicitly
-+                                 * zeroed */
-+    for (i = 0, j = idx; i < top; i++, j += width) {
-+        table[j] = b->d[i];
-+    }
-+
-+    return 1;
-+}
-+
-+static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
-+                                          unsigned char *buf, int idx,
-+                                          int window)
-+{
-+    int i, j;
-+    int width = 1 << window;
-+    /*
-+     * We declare table 'volatile' in order to discourage compiler
-+     * from reordering loads from the table. Concern is that if
-+     * reordered in specific manner loads might give away the
-+     * information we are trying to conceal. Some would argue that
-+     * compiler can reorder them anyway, but it can as well be
-+     * argued that doing so would be violation of standard...
-+     */
-+    volatile BN_ULONG *table = (volatile BN_ULONG *)buf;
-+
-+    if (bn_wexpand(b, top) == NULL)
-+        return 0;
-+
-+    if (window <= 3) {
-+        for (i = 0; i < top; i++, table += width) {
-+            BN_ULONG acc = 0;
-+
-+            for (j = 0; j < width; j++) {
-+                acc |= table[j] &
-+                       ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
-+            }
-+
-+            b->d[i] = acc;
-+        }
-+    } else {
-+        int xstride = 1 << (window - 2);
-+        BN_ULONG y0, y1, y2, y3;
-+
-+        i = idx >> (window - 2);        /* equivalent of idx / xstride */
-+        idx &= xstride - 1;             /* equivalent of idx % xstride */
-+
-+        y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1);
-+        y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1);
-+        y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1);
-+        y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1);
-+
-+        for (i = 0; i < top; i++, table += width) {
-+            BN_ULONG acc = 0;
-+
-+            for (j = 0; j < xstride; j++) {
-+                acc |= ( (table[j + 0 * xstride] & y0) |
-+                         (table[j + 1 * xstride] & y1) |
-+                         (table[j + 2 * xstride] & y2) |
-+                         (table[j + 3 * xstride] & y3) )
-+                       & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
-+            }
-+
-+            b->d[i] = acc;
-+        }
-+    }
-+
-+    b->top = top;
-+    bn_correct_top(b);
-+    return 1;
-+}
-+
-+/*
-+ * Given a pointer value, compute the next address that is a cache line
-+ * multiple.
-+ */
-+#define MOD_EXP_CTIME_ALIGN(x_) \
-+        ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
-+
-+/*
-+ * This variant of BN_mod_exp_mont() uses fixed windows and the special
-+ * precomputation memory layout to limit data-dependency to a minimum to
-+ * protect secret exponents (cf. the hyper-threading timing attacks pointed
-+ * out by Colin Percival,
-+ * http://www.daemonology.net/hyperthreading-considered-harmful/)
-+ */
-+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
-+                              const BIGNUM *m, BN_CTX *ctx,
-+                              BN_MONT_CTX *in_mont)
-+{
-+    int i, bits, ret = 0, window, wvalue;
-+    int top;
-+    BN_MONT_CTX *mont = NULL;
-+
-+    int numPowers;
-+    unsigned char *powerbufFree = NULL;
-+    int powerbufLen = 0;
-+    unsigned char *powerbuf = NULL;
-+    BIGNUM tmp, am;
-+#if defined(SPARC_T4_MONT)
-+    unsigned int t4 = 0;
-+#endif
-+
-+    bn_check_top(a);
-+    bn_check_top(p);
-+    bn_check_top(m);
-+
-+    if (!BN_is_odd(m)) {
-+        BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS);
-+        return (0);
-+    }
-+
-+    top = m->top;
-+
-+    bits = BN_num_bits(p);
-+    if (bits == 0) {
-+        /* x**0 mod 1 is still zero. */
-+        if (BN_is_one(m)) {
-+            ret = 1;
-+            BN_zero(rr);
-+        } else {
-+            ret = BN_one(rr);
-+        }
-+        return ret;
-+    }
-+
-+    BN_CTX_start(ctx);
-+
-+    /*
-+     * Allocate a montgomery context if it was not supplied by the caller. If
-+     * this is not done, things will break in the montgomery part.
-+     */
-+    if (in_mont != NULL)
-+        mont = in_mont;
-+    else {
-+        if ((mont = BN_MONT_CTX_new()) == NULL)
-+            goto err;
-+        if (!BN_MONT_CTX_set(mont, m, ctx))
-+            goto err;
-+    }
-+
-+#ifdef RSAZ_ENABLED
-+    /*
-+     * If the size of the operands allow it, perform the optimized
-+     * RSAZ exponentiation. For further information see
-+     * crypto/bn/rsaz_exp.c and accompanying assembly modules.
-+     */
-+    if ((16 == a->top) && (16 == p->top) && (BN_num_bits(m) == 1024)
-+        && rsaz_avx2_eligible()) {
-+        if (NULL == bn_wexpand(rr, 16))
-+            goto err;
-+        RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d,
-+                               mont->n0[0]);
-+        rr->top = 16;
-+        rr->neg = 0;
-+        bn_correct_top(rr);
-+        ret = 1;
-+        goto err;
-+    } else if ((8 == a->top) && (8 == p->top) && (BN_num_bits(m) == 512)) {
-+        if (NULL == bn_wexpand(rr, 8))
-+            goto err;
-+        RSAZ_512_mod_exp(rr->d, a->d, p->d, m->d, mont->n0[0], mont->RR.d);
-+        rr->top = 8;
-+        rr->neg = 0;
-+        bn_correct_top(rr);
-+        ret = 1;
-+        goto err;
-+    }
-+#endif
-+
-+    /* Get the window size to use with size of p. */
-+    window = BN_window_bits_for_ctime_exponent_size(bits);
-+#if defined(SPARC_T4_MONT)
-+    if (window >= 5 && (top & 15) == 0 && top <= 64 &&
-+        (OPENSSL_sparcv9cap_P[1] & (CFR_MONTMUL | CFR_MONTSQR)) ==
-+        (CFR_MONTMUL | CFR_MONTSQR) && (t4 = OPENSSL_sparcv9cap_P[0]))
-+        window = 5;
-+    else
-+#endif
-+#if defined(OPENSSL_BN_ASM_MONT5)
-+    if (window >= 5) {
-+        window = 5;             /* ~5% improvement for RSA2048 sign, and even
-+                                 * for RSA4096 */
-+        /* reserve space for mont->N.d[] copy */
-+        powerbufLen += top * sizeof(mont->N.d[0]);
-+    }
-+#endif
-+    (void)0;
-+
-+    /*
-+     * Allocate a buffer large enough to hold all of the pre-computed powers
-+     * of am, am itself and tmp.
-+     */
-+    numPowers = 1 << window;
-+    powerbufLen += sizeof(m->d[0]) * (top * numPowers +
-+                                      ((2 * top) >
-+                                       numPowers ? (2 * top) : numPowers));
-+#ifdef alloca
-+    if (powerbufLen < 3072)
-+        powerbufFree =
-+            alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
-+    else
-+#endif
-+        if ((powerbufFree =
-+             OPENSSL_malloc(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH))
-+            == NULL)
-+        goto err;
-+
-+    powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
-+    memset(powerbuf, 0, powerbufLen);
-+
-+#ifdef alloca
-+    if (powerbufLen < 3072)
-+        powerbufFree = NULL;
-+#endif
-+
-+    /* lay down tmp and am right after powers table */
-+    tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers);
-+    am.d = tmp.d + top;
-+    tmp.top = am.top = 0;
-+    tmp.dmax = am.dmax = top;
-+    tmp.neg = am.neg = 0;
-+    tmp.flags = am.flags = BN_FLG_STATIC_DATA;
-+
-+    /* prepare a^0 in Montgomery domain */
-+#if 1                           /* by Shay Gueron's suggestion */
-+    if (m->d[top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
-+        /* 2^(top*BN_BITS2) - m */
-+        tmp.d[0] = (0 - m->d[0]) & BN_MASK2;
-+        for (i = 1; i < top; i++)
-+            tmp.d[i] = (~m->d[i]) & BN_MASK2;
-+        tmp.top = top;
-+    } else
-+#endif
-+    if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
-+        goto err;
-+
-+    /* prepare a^1 in Montgomery domain */
-+    if (a->neg || BN_ucmp(a, m) >= 0) {
-+        if (!BN_mod(&am, a, m, ctx))
-+            goto err;
-+        if (!BN_to_montgomery(&am, &am, mont, ctx))
-+            goto err;
-+    } else if (!BN_to_montgomery(&am, a, mont, ctx))
-+        goto err;
-+
-+#if defined(SPARC_T4_MONT)
-+    if (t4) {
-+        typedef int (*bn_pwr5_mont_f) (BN_ULONG *tp, const BN_ULONG *np,
-+                                       const BN_ULONG *n0, const void *table,
-+                                       int power, int bits);
-+        int bn_pwr5_mont_t4_8(BN_ULONG *tp, const BN_ULONG *np,
-+                              const BN_ULONG *n0, const void *table,
-+                              int power, int bits);
-+        int bn_pwr5_mont_t4_16(BN_ULONG *tp, const BN_ULONG *np,
-+                               const BN_ULONG *n0, const void *table,
-+                               int power, int bits);
-+        int bn_pwr5_mont_t4_24(BN_ULONG *tp, const BN_ULONG *np,
-+                               const BN_ULONG *n0, const void *table,
-+                               int power, int bits);
-+        int bn_pwr5_mont_t4_32(BN_ULONG *tp, const BN_ULONG *np,
-+                               const BN_ULONG *n0, const void *table,
-+                               int power, int bits);
-+        static const bn_pwr5_mont_f pwr5_funcs[4] = {
-+            bn_pwr5_mont_t4_8, bn_pwr5_mont_t4_16,
-+            bn_pwr5_mont_t4_24, bn_pwr5_mont_t4_32
-+        };
-+        bn_pwr5_mont_f pwr5_worker = pwr5_funcs[top / 16 - 1];
-+
-+        typedef int (*bn_mul_mont_f) (BN_ULONG *rp, const BN_ULONG *ap,
-+                                      const void *bp, const BN_ULONG *np,
-+                                      const BN_ULONG *n0);
-+        int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap, const void *bp,
-+                             const BN_ULONG *np, const BN_ULONG *n0);
-+        int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap,
-+                              const void *bp, const BN_ULONG *np,
-+                              const BN_ULONG *n0);
-+        int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap,
-+                              const void *bp, const BN_ULONG *np,
-+                              const BN_ULONG *n0);
-+        int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap,
-+                              const void *bp, const BN_ULONG *np,
-+                              const BN_ULONG *n0);
-+        static const bn_mul_mont_f mul_funcs[4] = {
-+            bn_mul_mont_t4_8, bn_mul_mont_t4_16,
-+            bn_mul_mont_t4_24, bn_mul_mont_t4_32
-+        };
-+        bn_mul_mont_f mul_worker = mul_funcs[top / 16 - 1];
-+
-+        void bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap,
-+                              const void *bp, const BN_ULONG *np,
-+                              const BN_ULONG *n0, int num);
-+        void bn_mul_mont_t4(BN_ULONG *rp, const BN_ULONG *ap,
-+                            const void *bp, const BN_ULONG *np,
-+                            const BN_ULONG *n0, int num);
-+        void bn_mul_mont_gather5_t4(BN_ULONG *rp, const BN_ULONG *ap,
-+                                    const void *table, const BN_ULONG *np,
-+                                    const BN_ULONG *n0, int num, int power);
-+        void bn_flip_n_scatter5_t4(const BN_ULONG *inp, size_t num,
-+                                   void *table, size_t power);
-+        void bn_gather5_t4(BN_ULONG *out, size_t num,
-+                           void *table, size_t power);
-+        void bn_flip_t4(BN_ULONG *dst, BN_ULONG *src, size_t num);
-+
-+        BN_ULONG *np = mont->N.d, *n0 = mont->n0;
-+        int stride = 5 * (6 - (top / 16 - 1)); /* multiple of 5, but less
-+                                                * than 32 */
-+
-+        /*
-+         * BN_to_montgomery can contaminate words above .top [in
-+         * BN_DEBUG[_DEBUG] build]...
-+         */
-+        for (i = am.top; i < top; i++)
-+            am.d[i] = 0;
-+        for (i = tmp.top; i < top; i++)
-+            tmp.d[i] = 0;
-+
-+        bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 0);
-+        bn_flip_n_scatter5_t4(am.d, top, powerbuf, 1);
-+        if (!(*mul_worker) (tmp.d, am.d, am.d, np, n0) &&
-+            !(*mul_worker) (tmp.d, am.d, am.d, np, n0))
-+            bn_mul_mont_vis3(tmp.d, am.d, am.d, np, n0, top);
-+        bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 2);
-+
-+        for (i = 3; i < 32; i++) {
-+            /* Calculate a^i = a^(i-1) * a */
-+            if (!(*mul_worker) (tmp.d, tmp.d, am.d, np, n0) &&
-+                !(*mul_worker) (tmp.d, tmp.d, am.d, np, n0))
-+                bn_mul_mont_vis3(tmp.d, tmp.d, am.d, np, n0, top);
-+            bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, i);
-+        }
-+
-+        /* switch to 64-bit domain */
-+        np = alloca(top * sizeof(BN_ULONG));
-+        top /= 2;
-+        bn_flip_t4(np, mont->N.d, top);
-+
-+        bits--;
-+        for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
-+            wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
-+        bn_gather5_t4(tmp.d, top, powerbuf, wvalue);
-+
-+        /*
-+         * Scan the exponent one window at a time starting from the most
-+         * significant bits.
-+         */
-+        while (bits >= 0) {
-+            if (bits < stride)
-+                stride = bits + 1;
-+            bits -= stride;
-+            wvalue = bn_get_bits(p, bits + 1);
-+
-+            if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))
-+                continue;
-+            /* retry once and fall back */
-+            if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))
-+                continue;
-+
-+            bits += stride - 5;
-+            wvalue >>= stride - 5;
-+            wvalue &= 31;
-+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
-+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
-+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
-+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
-+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
-+            bn_mul_mont_gather5_t4(tmp.d, tmp.d, powerbuf, np, n0, top,
-+                                   wvalue);
-+        }
-+
-+        bn_flip_t4(tmp.d, tmp.d, top);
-+        top *= 2;
-+        /* back to 32-bit domain */
-+        tmp.top = top;
-+        bn_correct_top(&tmp);
-+        OPENSSL_cleanse(np, top * sizeof(BN_ULONG));
-+    } else
-+#endif
-+#if defined(OPENSSL_BN_ASM_MONT5)
-+    if (window == 5 && top > 1) {
-+        /*
-+         * This optimization uses ideas from http://eprint.iacr.org/2011/239,
-+         * specifically optimization of cache-timing attack countermeasures
-+         * and pre-computation optimization.
-+         */
-+
-+        /*
-+         * Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
-+         * 512-bit RSA is hardly relevant, we omit it to spare size...
-+         */
-+        void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap,
-+                                 const void *table, const BN_ULONG *np,
-+                                 const BN_ULONG *n0, int num, int power);
-+        void bn_scatter5(const BN_ULONG *inp, size_t num,
-+                         void *table, size_t power);
-+        void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);
-+        void bn_power5(BN_ULONG *rp, const BN_ULONG *ap,
-+                       const void *table, const BN_ULONG *np,
-+                       const BN_ULONG *n0, int num, int power);
-+        int bn_get_bits5(const BN_ULONG *ap, int off);
-+        int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap,
-+                               const BN_ULONG *not_used, const BN_ULONG *np,
-+                               const BN_ULONG *n0, int num);
-+
-+        BN_ULONG *n0 = mont->n0, *np;
-+
-+        /*
-+         * BN_to_montgomery can contaminate words above .top [in
-+         * BN_DEBUG[_DEBUG] build]...
-+         */
-+        for (i = am.top; i < top; i++)
-+            am.d[i] = 0;
-+        for (i = tmp.top; i < top; i++)
-+            tmp.d[i] = 0;
-+
-+        /*
-+         * copy mont->N.d[] to improve cache locality
-+         */
-+        for (np = am.d + top, i = 0; i < top; i++)
-+            np[i] = mont->N.d[i];
-+
-+        bn_scatter5(tmp.d, top, powerbuf, 0);
-+        bn_scatter5(am.d, am.top, powerbuf, 1);
-+        bn_mul_mont(tmp.d, am.d, am.d, np, n0, top);
-+        bn_scatter5(tmp.d, top, powerbuf, 2);
-+
-+# if 0
-+        for (i = 3; i < 32; i++) {
-+            /* Calculate a^i = a^(i-1) * a */
-+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
-+            bn_scatter5(tmp.d, top, powerbuf, i);
-+        }
-+# else
-+        /* same as above, but uses squaring for 1/2 of operations */
-+        for (i = 4; i < 32; i *= 2) {
-+            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-+            bn_scatter5(tmp.d, top, powerbuf, i);
-+        }
-+        for (i = 3; i < 8; i += 2) {
-+            int j;
-+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
-+            bn_scatter5(tmp.d, top, powerbuf, i);
-+            for (j = 2 * i; j < 32; j *= 2) {
-+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-+                bn_scatter5(tmp.d, top, powerbuf, j);
-+            }
-+        }
-+        for (; i < 16; i += 2) {
-+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
-+            bn_scatter5(tmp.d, top, powerbuf, i);
-+            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-+            bn_scatter5(tmp.d, top, powerbuf, 2 * i);
-+        }
-+        for (; i < 32; i += 2) {
-+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
-+            bn_scatter5(tmp.d, top, powerbuf, i);
-+        }
-+# endif
-+        bits--;
-+        for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
-+            wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
-+        bn_gather5(tmp.d, top, powerbuf, wvalue);
-+
-+        /*
-+         * Scan the exponent one window at a time starting from the most
-+         * significant bits.
-+         */
-+        if (top & 7)
-+            while (bits >= 0) {
-+                for (wvalue = 0, i = 0; i < 5; i++, bits--)
-+                    wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
-+
-+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-+                bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top,
-+                                    wvalue);
-+        } else {
-+            while (bits >= 0) {
-+                wvalue = bn_get_bits5(p->d, bits - 4);
-+                bits -= 5;
-+                bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
-+            }
-+        }
-+
-+        ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top);
-+        tmp.top = top;
-+        bn_correct_top(&tmp);
-+        if (ret) {
-+            if (!BN_copy(rr, &tmp))
-+                ret = 0;
-+            goto err;           /* non-zero ret means it's not error */
-+        }
-+    } else
-+#endif
-+    {
-+        if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, window))
-+            goto err;
-+        if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, window))
-+            goto err;
-+
-+        /*
-+         * If the window size is greater than 1, then calculate
-+         * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) (even
-+         * powers could instead be computed as (a^(i/2))^2 to use the slight
-+         * performance advantage of sqr over mul).
-+         */
-+        if (window > 1) {
-+            if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
-+                goto err;
-+            if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2,
-+                                              window))
-+                goto err;
-+            for (i = 3; i < numPowers; i++) {
-+                /* Calculate a^i = a^(i-1) * a */
-+                if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
-+                    goto err;
-+                if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i,
-+                                                  window))
-+                    goto err;
-+            }
-+        }
-+
-+        bits--;
-+        for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)
-+            wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
-+        if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue,
-+                                            window))
-+            goto err;
-+
-+        /*
-+         * Scan the exponent one window at a time starting from the most
-+         * significant bits.
-+         */
-+        while (bits >= 0) {
-+            wvalue = 0;         /* The 'value' of the window */
-+
-+            /* Scan the window, squaring the result as we go */
-+            for (i = 0; i < window; i++, bits--) {
-+                if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))
-+                    goto err;
-+                wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
-+            }
-+
-+            /*
-+             * Fetch the appropriate pre-computed value from the pre-buf
-+             */
-+            if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue,
-+                                                window))
-+                goto err;
-+
-+            /* Multiply the result into the intermediate result */
-+            if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
-+                goto err;
-+        }
-+    }
-+
-+    /* Convert the final result from montgomery to standard format */
-+#if defined(SPARC_T4_MONT)
-+    if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
-+        am.d[0] = 1;            /* borrow am */
-+        for (i = 1; i < top; i++)
-+            am.d[i] = 0;
-+        if (!BN_mod_mul_montgomery(rr, &tmp, &am, mont, ctx))
-+            goto err;
-+    } else
-+#endif
-+    if (!BN_from_montgomery(rr, &tmp, mont, ctx))
-+        goto err;
-+    ret = 1;
-+ err:
-+    if (in_mont == NULL)
-+        BN_MONT_CTX_free(mont);
-+    if (powerbuf != NULL) {
-+        OPENSSL_cleanse(powerbuf, powerbufLen);
-+        OPENSSL_free(powerbufFree);
-+    }
-+    BN_CTX_end(ctx);
-+    return (ret);
-+}
-+
-+int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
-+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
-+{
-+    BN_MONT_CTX *mont = NULL;
-+    int b, bits, ret = 0;
-+    int r_is_one;
-+    BN_ULONG w, next_w;
-+    BIGNUM *d, *r, *t;
-+    BIGNUM *swap_tmp;
-+#define BN_MOD_MUL_WORD(r, w, m) \
-+                (BN_mul_word(r, (w)) && \
-+                (/* BN_ucmp(r, (m)) < 0 ? 1 :*/  \
-+                        (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
-+    /*
-+     * BN_MOD_MUL_WORD is only used with 'w' large, so the BN_ucmp test is
-+     * probably more overhead than always using BN_mod (which uses BN_copy if
-+     * a similar test returns true).
-+     */
-+    /*
-+     * We can use BN_mod and do not need BN_nnmod because our accumulator is
-+     * never negative (the result of BN_mod does not depend on the sign of
-+     * the modulus).
-+     */
-+#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
-+                (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
-+
-+    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
-+        /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
-+        BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+
-+    bn_check_top(p);
-+    bn_check_top(m);
-+
-+    if (!BN_is_odd(m)) {
-+        BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS);
-+        return (0);
-+    }
-+    if (m->top == 1)
-+        a %= m->d[0];           /* make sure that 'a' is reduced */
-+
-+    bits = BN_num_bits(p);
-+    if (bits == 0) {
-+        /* x**0 mod 1 is still zero. */
-+        if (BN_is_one(m)) {
-+            ret = 1;
-+            BN_zero(rr);
-+        } else {
-+            ret = BN_one(rr);
-+        }
-+        return ret;
-+    }
-+    if (a == 0) {
-+        BN_zero(rr);
-+        ret = 1;
-+        return ret;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    d = BN_CTX_get(ctx);
-+    r = BN_CTX_get(ctx);
-+    t = BN_CTX_get(ctx);
-+    if (d == NULL || r == NULL || t == NULL)
-+        goto err;
-+
-+    if (in_mont != NULL)
-+        mont = in_mont;
-+    else {
-+        if ((mont = BN_MONT_CTX_new()) == NULL)
-+            goto err;
-+        if (!BN_MONT_CTX_set(mont, m, ctx))
-+            goto err;
-+    }
-+
-+    r_is_one = 1;               /* except for Montgomery factor */
-+
-+    /* bits-1 >= 0 */
-+
-+    /* The result is accumulated in the product r*w. */
-+    w = a;                      /* bit 'bits-1' of 'p' is always set */
-+    for (b = bits - 2; b >= 0; b--) {
-+        /* First, square r*w. */
-+        next_w = w * w;
-+        if ((next_w / w) != w) { /* overflow */
-+            if (r_is_one) {
-+                if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
-+                    goto err;
-+                r_is_one = 0;
-+            } else {
-+                if (!BN_MOD_MUL_WORD(r, w, m))
-+                    goto err;
-+            }
-+            next_w = 1;
-+        }
-+        w = next_w;
-+        if (!r_is_one) {
-+            if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
-+                goto err;
-+        }
-+
-+        /* Second, multiply r*w by 'a' if exponent bit is set. */
-+        if (BN_is_bit_set(p, b)) {
-+            next_w = w * a;
-+            if ((next_w / a) != w) { /* overflow */
-+                if (r_is_one) {
-+                    if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
-+                        goto err;
-+                    r_is_one = 0;
-+                } else {
-+                    if (!BN_MOD_MUL_WORD(r, w, m))
-+                        goto err;
-+                }
-+                next_w = a;
-+            }
-+            w = next_w;
-+        }
-+    }
-+
-+    /* Finally, set r:=r*w. */
-+    if (w != 1) {
-+        if (r_is_one) {
-+            if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
-+                goto err;
-+            r_is_one = 0;
-+        } else {
-+            if (!BN_MOD_MUL_WORD(r, w, m))
-+                goto err;
-+        }
-+    }
-+
-+    if (r_is_one) {             /* can happen only if a == 1 */
-+        if (!BN_one(rr))
-+            goto err;
-+    } else {
-+        if (!BN_from_montgomery(rr, r, mont, ctx))
-+            goto err;
-+    }
-+    ret = 1;
-+ err:
-+    if (in_mont == NULL)
-+        BN_MONT_CTX_free(mont);
-+    BN_CTX_end(ctx);
-+    bn_check_top(rr);
-+    return (ret);
-+}
-+
-+/* The old fallback, simple version :-) */
-+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-+                      const BIGNUM *m, BN_CTX *ctx)
-+{
-+    int i, j, bits, ret = 0, wstart, wend, window, wvalue;
-+    int start = 1;
-+    BIGNUM *d;
-+    /* Table of variables obtained from 'ctx' */
-+    BIGNUM *val[TABLE_SIZE];
-+
-+    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
-+        /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
-+        BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+
-+    bits = BN_num_bits(p);
-+   if (bits == 0) {
-+        /* x**0 mod 1 is still zero. */
-+        if (BN_is_one(m)) {
-+            ret = 1;
-+            BN_zero(r);
-+        } else {
-+            ret = BN_one(r);
-+        }
-+        return ret;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    d = BN_CTX_get(ctx);
-+    val[0] = BN_CTX_get(ctx);
-+    if (!d || !val[0])
-+        goto err;
-+
-+    if (!BN_nnmod(val[0], a, m, ctx))
-+        goto err;               /* 1 */
-+    if (BN_is_zero(val[0])) {
-+        BN_zero(r);
-+        ret = 1;
-+        goto err;
-+    }
-+
-+    window = BN_window_bits_for_exponent_size(bits);
-+    if (window > 1) {
-+        if (!BN_mod_mul(d, val[0], val[0], m, ctx))
-+            goto err;           /* 2 */
-+        j = 1 << (window - 1);
-+        for (i = 1; i < j; i++) {
-+            if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
-+                !BN_mod_mul(val[i], val[i - 1], d, m, ctx))
-+                goto err;
-+        }
-+    }
-+
-+    start = 1;                  /* This is used to avoid multiplication etc
-+                                 * when there is only the value '1' in the
-+                                 * buffer. */
-+    wvalue = 0;                 /* The 'value' of the window */
-+    wstart = bits - 1;          /* The top bit of the window */
-+    wend = 0;                   /* The bottom bit of the window */
-+
-+    if (!BN_one(r))
-+        goto err;
-+
-+    for (;;) {
-+        if (BN_is_bit_set(p, wstart) == 0) {
-+            if (!start)
-+                if (!BN_mod_mul(r, r, r, m, ctx))
-+                    goto err;
-+            if (wstart == 0)
-+                break;
-+            wstart--;
-+            continue;
-+        }
-+        /*
-+         * We now have wstart on a 'set' bit, we now need to work out how bit
-+         * a window to do.  To do this we need to scan forward until the last
-+         * set bit before the end of the window
-+         */
-+        j = wstart;
-+        wvalue = 1;
-+        wend = 0;
-+        for (i = 1; i < window; i++) {
-+            if (wstart - i < 0)
-+                break;
-+            if (BN_is_bit_set(p, wstart - i)) {
-+                wvalue <<= (i - wend);
-+                wvalue |= 1;
-+                wend = i;
-+            }
-+        }
-+
-+        /* wend is the size of the current window */
-+        j = wend + 1;
-+        /* add the 'bytes above' */
-+        if (!start)
-+            for (i = 0; i < j; i++) {
-+                if (!BN_mod_mul(r, r, r, m, ctx))
-+                    goto err;
-+            }
-+
-+        /* wvalue will be an odd number < 2^window */
-+        if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx))
-+            goto err;
-+
-+        /* move the 'window' down further */
-+        wstart -= wend + 1;
-+        wvalue = 0;
-+        start = 0;
-+        if (wstart < 0)
-+            break;
-+    }
-+    ret = 1;
-+ err:
-+    BN_CTX_end(ctx);
-+    bn_check_top(r);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp2.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp2.c
-new file mode 100644
-index 0000000..5141c21
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_exp2.c
-@@ -0,0 +1,201 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+#define TABLE_SIZE      32
-+
-+int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
-+                     const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
-+                     BN_CTX *ctx, BN_MONT_CTX *in_mont)
-+{
-+    int i, j, bits, b, bits1, bits2, ret =
-+        0, wpos1, wpos2, window1, window2, wvalue1, wvalue2;
-+    int r_is_one = 1;
-+    BIGNUM *d, *r;
-+    const BIGNUM *a_mod_m;
-+    /* Tables of variables obtained from 'ctx' */
-+    BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
-+    BN_MONT_CTX *mont = NULL;
-+
-+    bn_check_top(a1);
-+    bn_check_top(p1);
-+    bn_check_top(a2);
-+    bn_check_top(p2);
-+    bn_check_top(m);
-+
-+    if (!(m->d[0] & 1)) {
-+        BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
-+        return (0);
-+    }
-+    bits1 = BN_num_bits(p1);
-+    bits2 = BN_num_bits(p2);
-+    if ((bits1 == 0) && (bits2 == 0)) {
-+        ret = BN_one(rr);
-+        return ret;
-+    }
-+
-+    bits = (bits1 > bits2) ? bits1 : bits2;
-+
-+    BN_CTX_start(ctx);
-+    d = BN_CTX_get(ctx);
-+    r = BN_CTX_get(ctx);
-+    val1[0] = BN_CTX_get(ctx);
-+    val2[0] = BN_CTX_get(ctx);
-+    if (!d || !r || !val1[0] || !val2[0])
-+        goto err;
-+
-+    if (in_mont != NULL)
-+        mont = in_mont;
-+    else {
-+        if ((mont = BN_MONT_CTX_new()) == NULL)
-+            goto err;
-+        if (!BN_MONT_CTX_set(mont, m, ctx))
-+            goto err;
-+    }
-+
-+    window1 = BN_window_bits_for_exponent_size(bits1);
-+    window2 = BN_window_bits_for_exponent_size(bits2);
-+
-+    /*
-+     * Build table for a1:   val1[i] := a1^(2*i + 1) mod m  for i = 0 .. 2^(window1-1)
-+     */
-+    if (a1->neg || BN_ucmp(a1, m) >= 0) {
-+        if (!BN_mod(val1[0], a1, m, ctx))
-+            goto err;
-+        a_mod_m = val1[0];
-+    } else
-+        a_mod_m = a1;
-+    if (BN_is_zero(a_mod_m)) {
-+        BN_zero(rr);
-+        ret = 1;
-+        goto err;
-+    }
-+
-+    if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx))
-+        goto err;
-+    if (window1 > 1) {
-+        if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx))
-+            goto err;
-+
-+        j = 1 << (window1 - 1);
-+        for (i = 1; i < j; i++) {
-+            if (((val1[i] = BN_CTX_get(ctx)) == NULL) ||
-+                !BN_mod_mul_montgomery(val1[i], val1[i - 1], d, mont, ctx))
-+                goto err;
-+        }
-+    }
-+
-+    /*
-+     * Build table for a2:   val2[i] := a2^(2*i + 1) mod m  for i = 0 .. 2^(window2-1)
-+     */
-+    if (a2->neg || BN_ucmp(a2, m) >= 0) {
-+        if (!BN_mod(val2[0], a2, m, ctx))
-+            goto err;
-+        a_mod_m = val2[0];
-+    } else
-+        a_mod_m = a2;
-+    if (BN_is_zero(a_mod_m)) {
-+        BN_zero(rr);
-+        ret = 1;
-+        goto err;
-+    }
-+    if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx))
-+        goto err;
-+    if (window2 > 1) {
-+        if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx))
-+            goto err;
-+
-+        j = 1 << (window2 - 1);
-+        for (i = 1; i < j; i++) {
-+            if (((val2[i] = BN_CTX_get(ctx)) == NULL) ||
-+                !BN_mod_mul_montgomery(val2[i], val2[i - 1], d, mont, ctx))
-+                goto err;
-+        }
-+    }
-+
-+    /* Now compute the power product, using independent windows. */
-+    r_is_one = 1;
-+    wvalue1 = 0;                /* The 'value' of the first window */
-+    wvalue2 = 0;                /* The 'value' of the second window */
-+    wpos1 = 0;                  /* If wvalue1 > 0, the bottom bit of the
-+                                 * first window */
-+    wpos2 = 0;                  /* If wvalue2 > 0, the bottom bit of the
-+                                 * second window */
-+
-+    if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
-+        goto err;
-+    for (b = bits - 1; b >= 0; b--) {
-+        if (!r_is_one) {
-+            if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
-+                goto err;
-+        }
-+
-+        if (!wvalue1)
-+            if (BN_is_bit_set(p1, b)) {
-+                /*
-+                 * consider bits b-window1+1 .. b for this window
-+                 */
-+                i = b - window1 + 1;
-+                while (!BN_is_bit_set(p1, i)) /* works for i<0 */
-+                    i++;
-+                wpos1 = i;
-+                wvalue1 = 1;
-+                for (i = b - 1; i >= wpos1; i--) {
-+                    wvalue1 <<= 1;
-+                    if (BN_is_bit_set(p1, i))
-+                        wvalue1++;
-+                }
-+            }
-+
-+        if (!wvalue2)
-+            if (BN_is_bit_set(p2, b)) {
-+                /*
-+                 * consider bits b-window2+1 .. b for this window
-+                 */
-+                i = b - window2 + 1;
-+                while (!BN_is_bit_set(p2, i))
-+                    i++;
-+                wpos2 = i;
-+                wvalue2 = 1;
-+                for (i = b - 1; i >= wpos2; i--) {
-+                    wvalue2 <<= 1;
-+                    if (BN_is_bit_set(p2, i))
-+                        wvalue2++;
-+                }
-+            }
-+
-+        if (wvalue1 && b == wpos1) {
-+            /* wvalue1 is odd and < 2^window1 */
-+            if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1], mont, ctx))
-+                goto err;
-+            wvalue1 = 0;
-+            r_is_one = 0;
-+        }
-+
-+        if (wvalue2 && b == wpos2) {
-+            /* wvalue2 is odd and < 2^window2 */
-+            if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1], mont, ctx))
-+                goto err;
-+            wvalue2 = 0;
-+            r_is_one = 0;
-+        }
-+    }
-+    if (!BN_from_montgomery(rr, r, mont, ctx))
-+        goto err;
-+    ret = 1;
-+ err:
-+    if (in_mont == NULL)
-+        BN_MONT_CTX_free(mont);
-+    BN_CTX_end(ctx);
-+    bn_check_top(rr);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gcd.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gcd.c
-new file mode 100644
-index 0000000..e1aac13
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gcd.c
-@@ -0,0 +1,620 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
-+
-+int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
-+{
-+    BIGNUM *a, *b, *t;
-+    int ret = 0;
-+
-+    bn_check_top(in_a);
-+    bn_check_top(in_b);
-+
-+    BN_CTX_start(ctx);
-+    a = BN_CTX_get(ctx);
-+    b = BN_CTX_get(ctx);
-+    if (a == NULL || b == NULL)
-+        goto err;
-+
-+    if (BN_copy(a, in_a) == NULL)
-+        goto err;
-+    if (BN_copy(b, in_b) == NULL)
-+        goto err;
-+    a->neg = 0;
-+    b->neg = 0;
-+
-+    if (BN_cmp(a, b) < 0) {
-+        t = a;
-+        a = b;
-+        b = t;
-+    }
-+    t = euclid(a, b);
-+    if (t == NULL)
-+        goto err;
-+
-+    if (BN_copy(r, t) == NULL)
-+        goto err;
-+    ret = 1;
-+ err:
-+    BN_CTX_end(ctx);
-+    bn_check_top(r);
-+    return (ret);
-+}
-+
-+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
-+{
-+    BIGNUM *t;
-+    int shifts = 0;
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+
-+    /* 0 <= b <= a */
-+    while (!BN_is_zero(b)) {
-+        /* 0 < b <= a */
-+
-+        if (BN_is_odd(a)) {
-+            if (BN_is_odd(b)) {
-+                if (!BN_sub(a, a, b))
-+                    goto err;
-+                if (!BN_rshift1(a, a))
-+                    goto err;
-+                if (BN_cmp(a, b) < 0) {
-+                    t = a;
-+                    a = b;
-+                    b = t;
-+                }
-+            } else {            /* a odd - b even */
-+
-+                if (!BN_rshift1(b, b))
-+                    goto err;
-+                if (BN_cmp(a, b) < 0) {
-+                    t = a;
-+                    a = b;
-+                    b = t;
-+                }
-+            }
-+        } else {                /* a is even */
-+
-+            if (BN_is_odd(b)) {
-+                if (!BN_rshift1(a, a))
-+                    goto err;
-+                if (BN_cmp(a, b) < 0) {
-+                    t = a;
-+                    a = b;
-+                    b = t;
-+                }
-+            } else {            /* a even - b even */
-+
-+                if (!BN_rshift1(a, a))
-+                    goto err;
-+                if (!BN_rshift1(b, b))
-+                    goto err;
-+                shifts++;
-+            }
-+        }
-+        /* 0 <= b <= a */
-+    }
-+
-+    if (shifts) {
-+        if (!BN_lshift(a, a, shifts))
-+            goto err;
-+    }
-+    bn_check_top(a);
-+    return (a);
-+ err:
-+    return (NULL);
-+}
-+
-+/* solves ax == 1 (mod n) */
-+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
-+                                        const BIGNUM *a, const BIGNUM *n,
-+                                        BN_CTX *ctx);
-+
-+BIGNUM *BN_mod_inverse(BIGNUM *in,
-+                       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
-+{
-+    BIGNUM *rv;
-+    int noinv;
-+    rv = int_bn_mod_inverse(in, a, n, ctx, &noinv);
-+    if (noinv)
-+        BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE);
-+    return rv;
-+}
-+
-+BIGNUM *int_bn_mod_inverse(BIGNUM *in,
-+                           const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx,
-+                           int *pnoinv)
-+{
-+    BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
-+    BIGNUM *ret = NULL;
-+    int sign;
-+
-+    if (pnoinv)
-+        *pnoinv = 0;
-+
-+    if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0)
-+        || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) {
-+        return BN_mod_inverse_no_branch(in, a, n, ctx);
-+    }
-+
-+    bn_check_top(a);
-+    bn_check_top(n);
-+
-+    BN_CTX_start(ctx);
-+    A = BN_CTX_get(ctx);
-+    B = BN_CTX_get(ctx);
-+    X = BN_CTX_get(ctx);
-+    D = BN_CTX_get(ctx);
-+    M = BN_CTX_get(ctx);
-+    Y = BN_CTX_get(ctx);
-+    T = BN_CTX_get(ctx);
-+    if (T == NULL)
-+        goto err;
-+
-+    if (in == NULL)
-+        R = BN_new();
-+    else
-+        R = in;
-+    if (R == NULL)
-+        goto err;
-+
-+    BN_one(X);
-+    BN_zero(Y);
-+    if (BN_copy(B, a) == NULL)
-+        goto err;
-+    if (BN_copy(A, n) == NULL)
-+        goto err;
-+    A->neg = 0;
-+    if (B->neg || (BN_ucmp(B, A) >= 0)) {
-+        if (!BN_nnmod(B, B, A, ctx))
-+            goto err;
-+    }
-+    sign = -1;
-+    /*-
-+     * From  B = a mod |n|,  A = |n|  it follows that
-+     *
-+     *      0 <= B < A,
-+     *     -sign*X*a  ==  B   (mod |n|),
-+     *      sign*Y*a  ==  A   (mod |n|).
-+     */
-+
-+    if (BN_is_odd(n) && (BN_num_bits(n) <= 2048)) {
-+        /*
-+         * Binary inversion algorithm; requires odd modulus. This is faster
-+         * than the general algorithm if the modulus is sufficiently small
-+         * (about 400 .. 500 bits on 32-bit systems, but much more on 64-bit
-+         * systems)
-+         */
-+        int shift;
-+
-+        while (!BN_is_zero(B)) {
-+            /*-
-+             *      0 < B < |n|,
-+             *      0 < A <= |n|,
-+             * (1) -sign*X*a  ==  B   (mod |n|),
-+             * (2)  sign*Y*a  ==  A   (mod |n|)
-+             */
-+
-+            /*
-+             * Now divide B by the maximum possible power of two in the
-+             * integers, and divide X by the same value mod |n|. When we're
-+             * done, (1) still holds.
-+             */
-+            shift = 0;
-+            while (!BN_is_bit_set(B, shift)) { /* note that 0 < B */
-+                shift++;
-+
-+                if (BN_is_odd(X)) {
-+                    if (!BN_uadd(X, X, n))
-+                        goto err;
-+                }
-+                /*
-+                 * now X is even, so we can easily divide it by two
-+                 */
-+                if (!BN_rshift1(X, X))
-+                    goto err;
-+            }
-+            if (shift > 0) {
-+                if (!BN_rshift(B, B, shift))
-+                    goto err;
-+            }
-+
-+            /*
-+             * Same for A and Y.  Afterwards, (2) still holds.
-+             */
-+            shift = 0;
-+            while (!BN_is_bit_set(A, shift)) { /* note that 0 < A */
-+                shift++;
-+
-+                if (BN_is_odd(Y)) {
-+                    if (!BN_uadd(Y, Y, n))
-+                        goto err;
-+                }
-+                /* now Y is even */
-+                if (!BN_rshift1(Y, Y))
-+                    goto err;
-+            }
-+            if (shift > 0) {
-+                if (!BN_rshift(A, A, shift))
-+                    goto err;
-+            }
-+
-+            /*-
-+             * We still have (1) and (2).
-+             * Both  A  and  B  are odd.
-+             * The following computations ensure that
-+             *
-+             *     0 <= B < |n|,
-+             *      0 < A < |n|,
-+             * (1) -sign*X*a  ==  B   (mod |n|),
-+             * (2)  sign*Y*a  ==  A   (mod |n|),
-+             *
-+             * and that either  A  or  B  is even in the next iteration.
-+             */
-+            if (BN_ucmp(B, A) >= 0) {
-+                /* -sign*(X + Y)*a == B - A  (mod |n|) */
-+                if (!BN_uadd(X, X, Y))
-+                    goto err;
-+                /*
-+                 * NB: we could use BN_mod_add_quick(X, X, Y, n), but that
-+                 * actually makes the algorithm slower
-+                 */
-+                if (!BN_usub(B, B, A))
-+                    goto err;
-+            } else {
-+                /*  sign*(X + Y)*a == A - B  (mod |n|) */
-+                if (!BN_uadd(Y, Y, X))
-+                    goto err;
-+                /*
-+                 * as above, BN_mod_add_quick(Y, Y, X, n) would slow things
-+                 * down
-+                 */
-+                if (!BN_usub(A, A, B))
-+                    goto err;
-+            }
-+        }
-+    } else {
-+        /* general inversion algorithm */
-+
-+        while (!BN_is_zero(B)) {
-+            BIGNUM *tmp;
-+
-+            /*-
-+             *      0 < B < A,
-+             * (*) -sign*X*a  ==  B   (mod |n|),
-+             *      sign*Y*a  ==  A   (mod |n|)
-+             */
-+
-+            /* (D, M) := (A/B, A%B) ... */
-+            if (BN_num_bits(A) == BN_num_bits(B)) {
-+                if (!BN_one(D))
-+                    goto err;
-+                if (!BN_sub(M, A, B))
-+                    goto err;
-+            } else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
-+                /* A/B is 1, 2, or 3 */
-+                if (!BN_lshift1(T, B))
-+                    goto err;
-+                if (BN_ucmp(A, T) < 0) {
-+                    /* A < 2*B, so D=1 */
-+                    if (!BN_one(D))
-+                        goto err;
-+                    if (!BN_sub(M, A, B))
-+                        goto err;
-+                } else {
-+                    /* A >= 2*B, so D=2 or D=3 */
-+                    if (!BN_sub(M, A, T))
-+                        goto err;
-+                    if (!BN_add(D, T, B))
-+                        goto err; /* use D (:= 3*B) as temp */
-+                    if (BN_ucmp(A, D) < 0) {
-+                        /* A < 3*B, so D=2 */
-+                        if (!BN_set_word(D, 2))
-+                            goto err;
-+                        /*
-+                         * M (= A - 2*B) already has the correct value
-+                         */
-+                    } else {
-+                        /* only D=3 remains */
-+                        if (!BN_set_word(D, 3))
-+                            goto err;
-+                        /*
-+                         * currently M = A - 2*B, but we need M = A - 3*B
-+                         */
-+                        if (!BN_sub(M, M, B))
-+                            goto err;
-+                    }
-+                }
-+            } else {
-+                if (!BN_div(D, M, A, B, ctx))
-+                    goto err;
-+            }
-+
-+            /*-
-+             * Now
-+             *      A = D*B + M;
-+             * thus we have
-+             * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
-+             */
-+
-+            tmp = A;            /* keep the BIGNUM object, the value does not
-+                                 * matter */
-+
-+            /* (A, B) := (B, A mod B) ... */
-+            A = B;
-+            B = M;
-+            /* ... so we have  0 <= B < A  again */
-+
-+            /*-
-+             * Since the former  M  is now  B  and the former  B  is now  A,
-+             * (**) translates into
-+             *       sign*Y*a  ==  D*A + B    (mod |n|),
-+             * i.e.
-+             *       sign*Y*a - D*A  ==  B    (mod |n|).
-+             * Similarly, (*) translates into
-+             *      -sign*X*a  ==  A          (mod |n|).
-+             *
-+             * Thus,
-+             *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
-+             * i.e.
-+             *        sign*(Y + D*X)*a  ==  B  (mod |n|).
-+             *
-+             * So if we set  (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
-+             *      -sign*X*a  ==  B   (mod |n|),
-+             *       sign*Y*a  ==  A   (mod |n|).
-+             * Note that  X  and  Y  stay non-negative all the time.
-+             */
-+
-+            /*
-+             * most of the time D is very small, so we can optimize tmp :=
-+             * D*X+Y
-+             */
-+            if (BN_is_one(D)) {
-+                if (!BN_add(tmp, X, Y))
-+                    goto err;
-+            } else {
-+                if (BN_is_word(D, 2)) {
-+                    if (!BN_lshift1(tmp, X))
-+                        goto err;
-+                } else if (BN_is_word(D, 4)) {
-+                    if (!BN_lshift(tmp, X, 2))
-+                        goto err;
-+                } else if (D->top == 1) {
-+                    if (!BN_copy(tmp, X))
-+                        goto err;
-+                    if (!BN_mul_word(tmp, D->d[0]))
-+                        goto err;
-+                } else {
-+                    if (!BN_mul(tmp, D, X, ctx))
-+                        goto err;
-+                }
-+                if (!BN_add(tmp, tmp, Y))
-+                    goto err;
-+            }
-+
-+            M = Y;              /* keep the BIGNUM object, the value does not
-+                                 * matter */
-+            Y = X;
-+            X = tmp;
-+            sign = -sign;
-+        }
-+    }
-+
-+    /*-
-+     * The while loop (Euclid's algorithm) ends when
-+     *      A == gcd(a,n);
-+     * we have
-+     *       sign*Y*a  ==  A  (mod |n|),
-+     * where  Y  is non-negative.
-+     */
-+
-+    if (sign < 0) {
-+        if (!BN_sub(Y, n, Y))
-+            goto err;
-+    }
-+    /* Now  Y*a  ==  A  (mod |n|).  */
-+
-+    if (BN_is_one(A)) {
-+        /* Y*a == 1  (mod |n|) */
-+        if (!Y->neg && BN_ucmp(Y, n) < 0) {
-+            if (!BN_copy(R, Y))
-+                goto err;
-+        } else {
-+            if (!BN_nnmod(R, Y, n, ctx))
-+                goto err;
-+        }
-+    } else {
-+        if (pnoinv)
-+            *pnoinv = 1;
-+        goto err;
-+    }
-+    ret = R;
-+ err:
-+    if ((ret == NULL) && (in == NULL))
-+        BN_free(R);
-+    BN_CTX_end(ctx);
-+    bn_check_top(ret);
-+    return (ret);
-+}
-+
-+/*
-+ * BN_mod_inverse_no_branch is a special version of BN_mod_inverse. It does
-+ * not contain branches that may leak sensitive information.
-+ */
-+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
-+                                        const BIGNUM *a, const BIGNUM *n,
-+                                        BN_CTX *ctx)
-+{
-+    BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
-+    BIGNUM *ret = NULL;
-+    int sign;
-+
-+    bn_check_top(a);
-+    bn_check_top(n);
-+
-+    BN_CTX_start(ctx);
-+    A = BN_CTX_get(ctx);
-+    B = BN_CTX_get(ctx);
-+    X = BN_CTX_get(ctx);
-+    D = BN_CTX_get(ctx);
-+    M = BN_CTX_get(ctx);
-+    Y = BN_CTX_get(ctx);
-+    T = BN_CTX_get(ctx);
-+    if (T == NULL)
-+        goto err;
-+
-+    if (in == NULL)
-+        R = BN_new();
-+    else
-+        R = in;
-+    if (R == NULL)
-+        goto err;
-+
-+    BN_one(X);
-+    BN_zero(Y);
-+    if (BN_copy(B, a) == NULL)
-+        goto err;
-+    if (BN_copy(A, n) == NULL)
-+        goto err;
-+    A->neg = 0;
-+
-+    if (B->neg || (BN_ucmp(B, A) >= 0)) {
-+        /*
-+         * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
-+         * BN_div_no_branch will be called eventually.
-+         */
-+         {
-+            BIGNUM local_B;
-+            bn_init(&local_B);
-+            BN_with_flags(&local_B, B, BN_FLG_CONSTTIME);
-+            if (!BN_nnmod(B, &local_B, A, ctx))
-+                goto err;
-+            /* Ensure local_B goes out of scope before any further use of B */
-+        }
-+    }
-+    sign = -1;
-+    /*-
-+     * From  B = a mod |n|,  A = |n|  it follows that
-+     *
-+     *      0 <= B < A,
-+     *     -sign*X*a  ==  B   (mod |n|),
-+     *      sign*Y*a  ==  A   (mod |n|).
-+     */
-+
-+    while (!BN_is_zero(B)) {
-+        BIGNUM *tmp;
-+
-+        /*-
-+         *      0 < B < A,
-+         * (*) -sign*X*a  ==  B   (mod |n|),
-+         *      sign*Y*a  ==  A   (mod |n|)
-+         */
-+
-+        /*
-+         * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
-+         * BN_div_no_branch will be called eventually.
-+         */
-+        {
-+            BIGNUM local_A;
-+            bn_init(&local_A);
-+            BN_with_flags(&local_A, A, BN_FLG_CONSTTIME);
-+
-+            /* (D, M) := (A/B, A%B) ... */
-+            if (!BN_div(D, M, &local_A, B, ctx))
-+                goto err;
-+            /* Ensure local_A goes out of scope before any further use of A */
-+        }
-+
-+        /*-
-+         * Now
-+         *      A = D*B + M;
-+         * thus we have
-+         * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
-+         */
-+
-+        tmp = A;                /* keep the BIGNUM object, the value does not
-+                                 * matter */
-+
-+        /* (A, B) := (B, A mod B) ... */
-+        A = B;
-+        B = M;
-+        /* ... so we have  0 <= B < A  again */
-+
-+        /*-
-+         * Since the former  M  is now  B  and the former  B  is now  A,
-+         * (**) translates into
-+         *       sign*Y*a  ==  D*A + B    (mod |n|),
-+         * i.e.
-+         *       sign*Y*a - D*A  ==  B    (mod |n|).
-+         * Similarly, (*) translates into
-+         *      -sign*X*a  ==  A          (mod |n|).
-+         *
-+         * Thus,
-+         *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
-+         * i.e.
-+         *        sign*(Y + D*X)*a  ==  B  (mod |n|).
-+         *
-+         * So if we set  (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
-+         *      -sign*X*a  ==  B   (mod |n|),
-+         *       sign*Y*a  ==  A   (mod |n|).
-+         * Note that  X  and  Y  stay non-negative all the time.
-+         */
-+
-+        if (!BN_mul(tmp, D, X, ctx))
-+            goto err;
-+        if (!BN_add(tmp, tmp, Y))
-+            goto err;
-+
-+        M = Y;                  /* keep the BIGNUM object, the value does not
-+                                 * matter */
-+        Y = X;
-+        X = tmp;
-+        sign = -sign;
-+    }
-+
-+    /*-
-+     * The while loop (Euclid's algorithm) ends when
-+     *      A == gcd(a,n);
-+     * we have
-+     *       sign*Y*a  ==  A  (mod |n|),
-+     * where  Y  is non-negative.
-+     */
-+
-+    if (sign < 0) {
-+        if (!BN_sub(Y, n, Y))
-+            goto err;
-+    }
-+    /* Now  Y*a  ==  A  (mod |n|).  */
-+
-+    if (BN_is_one(A)) {
-+        /* Y*a == 1  (mod |n|) */
-+        if (!Y->neg && BN_ucmp(Y, n) < 0) {
-+            if (!BN_copy(R, Y))
-+                goto err;
-+        } else {
-+            if (!BN_nnmod(R, Y, n, ctx))
-+                goto err;
-+        }
-+    } else {
-+        BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE);
-+        goto err;
-+    }
-+    ret = R;
-+ err:
-+    if ((ret == NULL) && (in == NULL))
-+        BN_free(R);
-+    BN_CTX_end(ctx);
-+    bn_check_top(ret);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gf2m.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_gf2m.c
-new file mode 100644
-index 0000000..e69de29
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_intern.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_intern.c
-new file mode 100644
-index 0000000..2c97064
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_intern.c
-@@ -0,0 +1,210 @@
-+/*
-+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+/*
-+ * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
-+ * This is an array  r[]  of values that are either zero or odd with an
-+ * absolute value less than  2^w  satisfying
-+ *     scalar = \sum_j r[j]*2^j
-+ * where at most one of any  w+1  consecutive digits is non-zero
-+ * with the exception that the most significant digit may be only
-+ * w-1 zeros away from that next non-zero digit.
-+ */
-+signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
-+{
-+    int window_val;
-+    signed char *r = NULL;
-+    int sign = 1;
-+    int bit, next_bit, mask;
-+    size_t len = 0, j;
-+
-+    if (BN_is_zero(scalar)) {
-+        r = OPENSSL_malloc(1);
-+        if (r == NULL) {
-+            BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        r[0] = 0;
-+        *ret_len = 1;
-+        return r;
-+    }
-+
-+    if (w <= 0 || w > 7) {      /* 'signed char' can represent integers with
-+                                 * absolute values less than 2^7 */
-+        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
-+        goto err;
-+    }
-+    bit = 1 << w;               /* at most 128 */
-+    next_bit = bit << 1;        /* at most 256 */
-+    mask = next_bit - 1;        /* at most 255 */
-+
-+    if (BN_is_negative(scalar)) {
-+        sign = -1;
-+    }
-+
-+    if (scalar->d == NULL || scalar->top == 0) {
-+        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
-+        goto err;
-+    }
-+
-+    len = BN_num_bits(scalar);
-+    r = OPENSSL_malloc(len + 1); /*
-+                                  * Modified wNAF may be one digit longer than binary representation
-+                                  * (*ret_len will be set to the actual length, i.e. at most
-+                                  * BN_num_bits(scalar) + 1)
-+                                  */
-+    if (r == NULL) {
-+        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    window_val = scalar->d[0] & mask;
-+    j = 0;
-+    while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len,
-+                                                      * window_val will not
-+                                                      * increase */
-+        int digit = 0;
-+
-+        /* 0 <= window_val <= 2^(w+1) */
-+
-+        if (window_val & 1) {
-+            /* 0 < window_val < 2^(w+1) */
-+
-+            if (window_val & bit) {
-+                digit = window_val - next_bit; /* -2^w < digit < 0 */
-+
-+#if 1                           /* modified wNAF */
-+                if (j + w + 1 >= len) {
-+                    /*
-+                     * Special case for generating modified wNAFs:
-+                     * no new bits will be added into window_val,
-+                     * so using a positive digit here will decrease
-+                     * the total length of the representation
-+                     */
-+
-+                    digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
-+                }
-+#endif
-+            } else {
-+                digit = window_val; /* 0 < digit < 2^w */
-+            }
-+
-+            if (digit <= -bit || digit >= bit || !(digit & 1)) {
-+                BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
-+                goto err;
-+            }
-+
-+            window_val -= digit;
-+
-+            /*
-+             * now window_val is 0 or 2^(w+1) in standard wNAF generation;
-+             * for modified window NAFs, it may also be 2^w
-+             */
-+            if (window_val != 0 && window_val != next_bit
-+                && window_val != bit) {
-+                BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
-+                goto err;
-+            }
-+        }
-+
-+        r[j++] = sign * digit;
-+
-+        window_val >>= 1;
-+        window_val += bit * BN_is_bit_set(scalar, j + w);
-+
-+        if (window_val > next_bit) {
-+            BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
-+            goto err;
-+        }
-+    }
-+
-+    if (j > len + 1) {
-+        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
-+        goto err;
-+    }
-+    *ret_len = j;
-+    return r;
-+
-+ err:
-+    OPENSSL_free(r);
-+    return NULL;
-+}
-+
-+int bn_get_top(const BIGNUM *a)
-+{
-+    return a->top;
-+}
-+
-+void bn_set_top(BIGNUM *a, int top)
-+{
-+    a->top = top;
-+}
-+
-+int bn_get_dmax(const BIGNUM *a)
-+{
-+    return a->dmax;
-+}
-+
-+void bn_set_all_zero(BIGNUM *a)
-+{
-+    int i;
-+
-+    for (i = a->top; i < a->dmax; i++)
-+        a->d[i] = 0;
-+}
-+
-+int bn_copy_words(BN_ULONG *out, const BIGNUM *in, int size)
-+{
-+    if (in->top > size)
-+        return 0;
-+
-+    memset(out, 0, sizeof(*out) * size);
-+    if (in->d != NULL)
-+        memcpy(out, in->d, sizeof(*out) * in->top);
-+    return 1;
-+}
-+
-+BN_ULONG *bn_get_words(const BIGNUM *a)
-+{
-+    return a->d;
-+}
-+
-+void bn_set_static_words(BIGNUM *a, BN_ULONG *words, int size)
-+{
-+    a->d = words;
-+    a->dmax = a->top = size;
-+    a->neg = 0;
-+    a->flags |= BN_FLG_STATIC_DATA;
-+    bn_correct_top(a);
-+}
-+
-+int bn_set_words(BIGNUM *a, BN_ULONG *words, int num_words)
-+{
-+    if (bn_wexpand(a, num_words) == NULL) {
-+        BNerr(BN_F_BN_SET_WORDS, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    memcpy(a->d, words, sizeof(BN_ULONG) * num_words);
-+    a->top = num_words;
-+    bn_correct_top(a);
-+    return 1;
-+}
-+
-+size_t bn_sizeof_BIGNUM(void)
-+{
-+    return sizeof(BIGNUM);
-+}
-+
-+BIGNUM *bn_array_el(BIGNUM *base, int el)
-+{
-+    return &base[el];
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_kron.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_kron.c
-new file mode 100644
-index 0000000..b9bc6cc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_kron.c
-@@ -0,0 +1,140 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+/* least significant word */
-+#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0])
-+
-+/* Returns -2 for errors because both -1 and 0 are valid results. */
-+int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
-+{
-+    int i;
-+    int ret = -2;               /* avoid 'uninitialized' warning */
-+    int err = 0;
-+    BIGNUM *A, *B, *tmp;
-+    /*-
-+     * In 'tab', only odd-indexed entries are relevant:
-+     * For any odd BIGNUM n,
-+     *     tab[BN_lsw(n) & 7]
-+     * is $(-1)^{(n^2-1)/8}$ (using TeX notation).
-+     * Note that the sign of n does not matter.
-+     */
-+    static const int tab[8] = { 0, 1, 0, -1, 0, -1, 0, 1 };
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+
-+    BN_CTX_start(ctx);
-+    A = BN_CTX_get(ctx);
-+    B = BN_CTX_get(ctx);
-+    if (B == NULL)
-+        goto end;
-+
-+    err = !BN_copy(A, a);
-+    if (err)
-+        goto end;
-+    err = !BN_copy(B, b);
-+    if (err)
-+        goto end;
-+
-+    /*
-+     * Kronecker symbol, implemented according to Henri Cohen,
-+     * "A Course in Computational Algebraic Number Theory"
-+     * (algorithm 1.4.10).
-+     */
-+
-+    /* Cohen's step 1: */
-+
-+    if (BN_is_zero(B)) {
-+        ret = BN_abs_is_word(A, 1);
-+        goto end;
-+    }
-+
-+    /* Cohen's step 2: */
-+
-+    if (!BN_is_odd(A) && !BN_is_odd(B)) {
-+        ret = 0;
-+        goto end;
-+    }
-+
-+    /* now  B  is non-zero */
-+    i = 0;
-+    while (!BN_is_bit_set(B, i))
-+        i++;
-+    err = !BN_rshift(B, B, i);
-+    if (err)
-+        goto end;
-+    if (i & 1) {
-+        /* i is odd */
-+        /* (thus  B  was even, thus  A  must be odd!)  */
-+
-+        /* set 'ret' to $(-1)^{(A^2-1)/8}$ */
-+        ret = tab[BN_lsw(A) & 7];
-+    } else {
-+        /* i is even */
-+        ret = 1;
-+    }
-+
-+    if (B->neg) {
-+        B->neg = 0;
-+        if (A->neg)
-+            ret = -ret;
-+    }
-+
-+    /*
-+     * now B is positive and odd, so what remains to be done is to compute
-+     * the Jacobi symbol (A/B) and multiply it by 'ret'
-+     */
-+
-+    while (1) {
-+        /* Cohen's step 3: */
-+
-+        /*  B  is positive and odd */
-+
-+        if (BN_is_zero(A)) {
-+            ret = BN_is_one(B) ? ret : 0;
-+            goto end;
-+        }
-+
-+        /* now  A  is non-zero */
-+        i = 0;
-+        while (!BN_is_bit_set(A, i))
-+            i++;
-+        err = !BN_rshift(A, A, i);
-+        if (err)
-+            goto end;
-+        if (i & 1) {
-+            /* i is odd */
-+            /* multiply 'ret' by  $(-1)^{(B^2-1)/8}$ */
-+            ret = ret * tab[BN_lsw(B) & 7];
-+        }
-+
-+        /* Cohen's step 4: */
-+        /* multiply 'ret' by  $(-1)^{(A-1)(B-1)/4}$ */
-+        if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2)
-+            ret = -ret;
-+
-+        /* (A, B) := (B mod |A|, |A|) */
-+        err = !BN_nnmod(B, B, A, ctx);
-+        if (err)
-+            goto end;
-+        tmp = A;
-+        A = B;
-+        B = tmp;
-+        tmp->neg = 0;
-+    }
-+ end:
-+    BN_CTX_end(ctx);
-+    if (err)
-+        return -2;
-+    else
-+        return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_lcl.h
-new file mode 100644
-index 0000000..5fb3814
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_lcl.h
-@@ -0,0 +1,689 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_BN_LCL_H
-+# define HEADER_BN_LCL_H
-+
-+/*
-+ * The EDK2 build doesn't use bn_conf.h; it sets THIRTY_TWO_BIT or
-+ * SIXTY_FOUR_BIT in its own environment since it doesn't re-run our
-+ * Configure script and needs to support both 32-bit and 64-bit.
-+ */
-+# include 
-+
-+# if !defined(OPENSSL_SYS_UEFI)
-+#  include "internal/bn_conf.h"
-+# endif
-+
-+# include "internal/bn_int.h"
-+
-+#ifdef  __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * These preprocessor symbols control various aspects of the bignum headers
-+ * and library code. They're not defined by any "normal" configuration, as
-+ * they are intended for development and testing purposes. NB: defining all
-+ * three can be useful for debugging application code as well as openssl
-+ * itself. BN_DEBUG - turn on various debugging alterations to the bignum
-+ * code BN_DEBUG_RAND - uses random poisoning of unused words to trip up
-+ * mismanagement of bignum internals. You must also define BN_DEBUG.
-+ */
-+/* #define BN_DEBUG */
-+/* #define BN_DEBUG_RAND */
-+
-+# ifndef OPENSSL_SMALL_FOOTPRINT
-+#  define BN_MUL_COMBA
-+#  define BN_SQR_COMBA
-+#  define BN_RECURSION
-+# endif
-+
-+/*
-+ * This next option uses the C libraries (2 word)/(1 word) function. If it is
-+ * not defined, I use my C version (which is slower). The reason for this
-+ * flag is that when the particular C compiler library routine is used, and
-+ * the library is linked with a different compiler, the library is missing.
-+ * This mostly happens when the library is built with gcc and then linked
-+ * using normal cc.  This would be a common occurrence because gcc normally
-+ * produces code that is 2 times faster than system compilers for the big
-+ * number stuff. For machines with only one compiler (or shared libraries),
-+ * this should be on.  Again this in only really a problem on machines using
-+ * "long long's", are 32bit, and are not using my assembler code.
-+ */
-+# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
-+    defined(OPENSSL_SYS_WIN32) || defined(linux)
-+#  define BN_DIV2W
-+# endif
-+
-+/*
-+ * 64-bit processor with LP64 ABI
-+ */
-+# ifdef SIXTY_FOUR_BIT_LONG
-+#  define BN_ULLONG       unsigned long long
-+#  define BN_BITS4        32
-+#  define BN_MASK2        (0xffffffffffffffffL)
-+#  define BN_MASK2l       (0xffffffffL)
-+#  define BN_MASK2h       (0xffffffff00000000L)
-+#  define BN_MASK2h1      (0xffffffff80000000L)
-+#  define BN_DEC_CONV     (10000000000000000000UL)
-+#  define BN_DEC_NUM      19
-+#  define BN_DEC_FMT1     "%lu"
-+#  define BN_DEC_FMT2     "%019lu"
-+# endif
-+
-+/*
-+ * 64-bit processor other than LP64 ABI
-+ */
-+# ifdef SIXTY_FOUR_BIT
-+#  undef BN_LLONG
-+#  undef BN_ULLONG
-+#  define BN_BITS4        32
-+#  define BN_MASK2        (0xffffffffffffffffLL)
-+#  define BN_MASK2l       (0xffffffffL)
-+#  define BN_MASK2h       (0xffffffff00000000LL)
-+#  define BN_MASK2h1      (0xffffffff80000000LL)
-+#  define BN_DEC_CONV     (10000000000000000000ULL)
-+#  define BN_DEC_NUM      19
-+#  define BN_DEC_FMT1     "%llu"
-+#  define BN_DEC_FMT2     "%019llu"
-+# endif
-+
-+# ifdef THIRTY_TWO_BIT
-+#  ifdef BN_LLONG
-+#   if defined(_WIN32) && !defined(__GNUC__)
-+#    define BN_ULLONG     unsigned __int64
-+#   else
-+#    define BN_ULLONG     unsigned long long
-+#   endif
-+#  endif
-+#  define BN_BITS4        16
-+#  define BN_MASK2        (0xffffffffL)
-+#  define BN_MASK2l       (0xffff)
-+#  define BN_MASK2h1      (0xffff8000L)
-+#  define BN_MASK2h       (0xffff0000L)
-+#  define BN_DEC_CONV     (1000000000L)
-+#  define BN_DEC_NUM      9
-+#  define BN_DEC_FMT1     "%u"
-+#  define BN_DEC_FMT2     "%09u"
-+# endif
-+
-+
-+/*-
-+ * Bignum consistency macros
-+ * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
-+ * bignum data after direct manipulations on the data. There is also an
-+ * "internal" macro, bn_check_top(), for verifying that there are no leading
-+ * zeroes. Unfortunately, some auditing is required due to the fact that
-+ * bn_fix_top() has become an overabused duct-tape because bignum data is
-+ * occasionally passed around in an inconsistent state. So the following
-+ * changes have been made to sort this out;
-+ * - bn_fix_top()s implementation has been moved to bn_correct_top()
-+ * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
-+ *   bn_check_top() is as before.
-+ * - if BN_DEBUG *is* defined;
-+ *   - bn_check_top() tries to pollute unused words even if the bignum 'top' is
-+ *     consistent. (ed: only if BN_DEBUG_RAND is defined)
-+ *   - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
-+ * The idea is to have debug builds flag up inconsistent bignums when they
-+ * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
-+ * the use of bn_fix_top() was appropriate (ie. it follows directly after code
-+ * that manipulates the bignum) it is converted to bn_correct_top(), and if it
-+ * was not appropriate, we convert it permanently to bn_check_top() and track
-+ * down the cause of the bug. Eventually, no internal code should be using the
-+ * bn_fix_top() macro. External applications and libraries should try this with
-+ * their own code too, both in terms of building against the openssl headers
-+ * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
-+ * defined. This not only improves external code, it provides more test
-+ * coverage for openssl's own code.
-+ */
-+
-+# ifdef BN_DEBUG
-+
-+#  ifdef BN_DEBUG_RAND
-+/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
-+#   ifndef RAND_bytes
-+int RAND_bytes(unsigned char *buf, int num);
-+#    define BN_DEBUG_TRIX
-+#   endif
-+#   define bn_pollute(a) \
-+        do { \
-+            const BIGNUM *_bnum1 = (a); \
-+            if (_bnum1->top < _bnum1->dmax) { \
-+                unsigned char _tmp_char; \
-+                /* We cast away const without the compiler knowing, any \
-+                 * *genuinely* constant variables that aren't mutable \
-+                 * wouldn't be constructed with top!=dmax. */ \
-+                BN_ULONG *_not_const; \
-+                memcpy(&_not_const, &_bnum1->d, sizeof(_not_const)); \
-+                RAND_bytes(&_tmp_char, 1); /* Debug only - safe to ignore error return */\
-+                memset(_not_const + _bnum1->top, _tmp_char, \
-+                       sizeof(*_not_const) * (_bnum1->dmax - _bnum1->top)); \
-+            } \
-+        } while(0)
-+#   ifdef BN_DEBUG_TRIX
-+#    undef RAND_bytes
-+#   endif
-+#  else
-+#   define bn_pollute(a)
-+#  endif
-+#  define bn_check_top(a) \
-+        do { \
-+                const BIGNUM *_bnum2 = (a); \
-+                if (_bnum2 != NULL) { \
-+                        OPENSSL_assert(((_bnum2->top == 0) && !_bnum2->neg) || \
-+                                (_bnum2->top && (_bnum2->d[_bnum2->top - 1] != 0))); \
-+                        bn_pollute(_bnum2); \
-+                } \
-+        } while(0)
-+
-+#  define bn_fix_top(a)           bn_check_top(a)
-+
-+#  define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2)
-+#  define bn_wcheck_size(bn, words) \
-+        do { \
-+                const BIGNUM *_bnum2 = (bn); \
-+                OPENSSL_assert((words) <= (_bnum2)->dmax && \
-+                        (words) >= (_bnum2)->top); \
-+                /* avoid unused variable warning with NDEBUG */ \
-+                (void)(_bnum2); \
-+        } while(0)
-+
-+# else                          /* !BN_DEBUG */
-+
-+#  define bn_pollute(a)
-+#  define bn_check_top(a)
-+#  define bn_fix_top(a)           bn_correct_top(a)
-+#  define bn_check_size(bn, bits)
-+#  define bn_wcheck_size(bn, words)
-+
-+# endif
-+
-+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
-+                          BN_ULONG w);
-+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
-+void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
-+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
-+BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                      int num);
-+BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                      int num);
-+
-+struct bignum_st {
-+    BN_ULONG *d;                /* Pointer to an array of 'BN_BITS2' bit
-+                                 * chunks. */
-+    int top;                    /* Index of last used d +1. */
-+    /* The next are internal book keeping for bn_expand. */
-+    int dmax;                   /* Size of the d array. */
-+    int neg;                    /* one if the number is negative */
-+    int flags;
-+};
-+
-+/* Used for montgomery multiplication */
-+struct bn_mont_ctx_st {
-+    int ri;                     /* number of bits in R */
-+    BIGNUM RR;                  /* used to convert to montgomery form */
-+    BIGNUM N;                   /* The modulus */
-+    BIGNUM Ni;                  /* R*(1/R mod N) - N*Ni = 1 (Ni is only
-+                                 * stored for bignum algorithm) */
-+    BN_ULONG n0[2];             /* least significant word(s) of Ni; (type
-+                                 * changed with 0.9.9, was "BN_ULONG n0;"
-+                                 * before) */
-+    int flags;
-+};
-+
-+/*
-+ * Used for reciprocal division/mod functions It cannot be shared between
-+ * threads
-+ */
-+struct bn_recp_ctx_st {
-+    BIGNUM N;                   /* the divisor */
-+    BIGNUM Nr;                  /* the reciprocal */
-+    int num_bits;
-+    int shift;
-+    int flags;
-+};
-+
-+/* Used for slow "generation" functions. */
-+struct bn_gencb_st {
-+    unsigned int ver;           /* To handle binary (in)compatibility */
-+    void *arg;                  /* callback-specific data */
-+    union {
-+        /* if (ver==1) - handles old style callbacks */
-+        void (*cb_1) (int, int, void *);
-+        /* if (ver==2) - new callback style */
-+        int (*cb_2) (int, int, BN_GENCB *);
-+    } cb;
-+};
-+
-+/*-
-+ * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
-+ *
-+ *
-+ * For window size 'w' (w >= 2) and a random 'b' bits exponent,
-+ * the number of multiplications is a constant plus on average
-+ *
-+ *    2^(w-1) + (b-w)/(w+1);
-+ *
-+ * here  2^(w-1)  is for precomputing the table (we actually need
-+ * entries only for windows that have the lowest bit set), and
-+ * (b-w)/(w+1)  is an approximation for the expected number of
-+ * w-bit windows, not counting the first one.
-+ *
-+ * Thus we should use
-+ *
-+ *    w >= 6  if        b > 671
-+ *     w = 5  if  671 > b > 239
-+ *     w = 4  if  239 > b >  79
-+ *     w = 3  if   79 > b >  23
-+ *    w <= 2  if   23 > b
-+ *
-+ * (with draws in between).  Very small exponents are often selected
-+ * with low Hamming weight, so we use  w = 1  for b <= 23.
-+ */
-+# define BN_window_bits_for_exponent_size(b) \
-+                ((b) > 671 ? 6 : \
-+                 (b) > 239 ? 5 : \
-+                 (b) >  79 ? 4 : \
-+                 (b) >  23 ? 3 : 1)
-+
-+/*
-+ * BN_mod_exp_mont_conttime is based on the assumption that the L1 data cache
-+ * line width of the target processor is at least the following value.
-+ */
-+# define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH      ( 64 )
-+# define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK       (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1)
-+
-+/*
-+ * Window sizes optimized for fixed window size modular exponentiation
-+ * algorithm (BN_mod_exp_mont_consttime). To achieve the security goals of
-+ * BN_mode_exp_mont_consttime, the maximum size of the window must not exceed
-+ * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). Window size thresholds are
-+ * defined for cache line sizes of 32 and 64, cache line sizes where
-+ * log_2(32)=5 and log_2(64)=6 respectively. A window size of 7 should only be
-+ * used on processors that have a 128 byte or greater cache line size.
-+ */
-+# if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64
-+
-+#  define BN_window_bits_for_ctime_exponent_size(b) \
-+                ((b) > 937 ? 6 : \
-+                 (b) > 306 ? 5 : \
-+                 (b) >  89 ? 4 : \
-+                 (b) >  22 ? 3 : 1)
-+#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE    (6)
-+
-+# elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32
-+
-+#  define BN_window_bits_for_ctime_exponent_size(b) \
-+                ((b) > 306 ? 5 : \
-+                 (b) >  89 ? 4 : \
-+                 (b) >  22 ? 3 : 1)
-+#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE    (5)
-+
-+# endif
-+
-+/* Pentium pro 16,16,16,32,64 */
-+/* Alpha       16,16,16,16.64 */
-+# define BN_MULL_SIZE_NORMAL                     (16)/* 32 */
-+# define BN_MUL_RECURSIVE_SIZE_NORMAL            (16)/* 32 less than */
-+# define BN_SQR_RECURSIVE_SIZE_NORMAL            (16)/* 32 */
-+# define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL        (32)/* 32 */
-+# define BN_MONT_CTX_SET_SIZE_WORD               (64)/* 32 */
-+
-+/*
-+ * 2011-02-22 SMS. In various places, a size_t variable or a type cast to
-+ * size_t was used to perform integer-only operations on pointers.  This
-+ * failed on VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t
-+ * is still only 32 bits.  What's needed in these cases is an integer type
-+ * with the same size as a pointer, which size_t is not certain to be. The
-+ * only fix here is VMS-specific.
-+ */
-+# if defined(OPENSSL_SYS_VMS)
-+#  if __INITIAL_POINTER_SIZE == 64
-+#   define PTR_SIZE_INT long long
-+#  else                         /* __INITIAL_POINTER_SIZE == 64 */
-+#   define PTR_SIZE_INT int
-+#  endif                        /* __INITIAL_POINTER_SIZE == 64 [else] */
-+# elif !defined(PTR_SIZE_INT)   /* defined(OPENSSL_SYS_VMS) */
-+#  define PTR_SIZE_INT size_t
-+# endif                         /* defined(OPENSSL_SYS_VMS) [else] */
-+
-+# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
-+/*
-+ * BN_UMULT_HIGH section.
-+ *
-+ * No, I'm not trying to overwhelm you when stating that the
-+ * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
-+ * you to be impressed when I say that if the compiler doesn't
-+ * support 2*N integer type, then you have to replace every N*N
-+ * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
-+ * and additions which unavoidably results in severe performance
-+ * penalties. Of course provided that the hardware is capable of
-+ * producing 2*N result... That's when you normally start
-+ * considering assembler implementation. However! It should be
-+ * pointed out that some CPUs (most notably Alpha, PowerPC and
-+ * upcoming IA-64 family:-) provide *separate* instruction
-+ * calculating the upper half of the product placing the result
-+ * into a general purpose register. Now *if* the compiler supports
-+ * inline assembler, then it's not impossible to implement the
-+ * "bignum" routines (and have the compiler optimize 'em)
-+ * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
-+ * macro is about:-)
-+ *
-+ *                                      
-+ */
-+#  if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
-+#   if defined(__DECC)
-+#    include 
-+#    define BN_UMULT_HIGH(a,b)   (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
-+#   elif defined(__GNUC__) && __GNUC__>=2
-+#    define BN_UMULT_HIGH(a,b)   ({      \
-+        register BN_ULONG ret;          \
-+        asm ("umulh     %1,%2,%0"       \
-+             : "=r"(ret)                \
-+             : "r"(a), "r"(b));         \
-+        ret;                    })
-+#   endif                       /* compiler */
-+#  elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
-+#   if defined(__GNUC__) && __GNUC__>=2
-+#    define BN_UMULT_HIGH(a,b)   ({      \
-+        register BN_ULONG ret;          \
-+        asm ("mulhdu    %0,%1,%2"       \
-+             : "=r"(ret)                \
-+             : "r"(a), "r"(b));         \
-+        ret;                    })
-+#   endif                       /* compiler */
-+#  elif (defined(__x86_64) || defined(__x86_64__)) && \
-+       (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
-+#   if defined(__GNUC__) && __GNUC__>=2
-+#    define BN_UMULT_HIGH(a,b)   ({      \
-+        register BN_ULONG ret,discard;  \
-+        asm ("mulq      %3"             \
-+             : "=a"(discard),"=d"(ret)  \
-+             : "a"(a), "g"(b)           \
-+             : "cc");                   \
-+        ret;                    })
-+#    define BN_UMULT_LOHI(low,high,a,b)  \
-+        asm ("mulq      %3"             \
-+                : "=a"(low),"=d"(high)  \
-+                : "a"(a),"g"(b)         \
-+                : "cc");
-+#   endif
-+#  elif (defined(_M_AMD64) || defined(_M_X64)) && defined(SIXTY_FOUR_BIT)
-+#   if defined(_MSC_VER) && _MSC_VER>=1400
-+unsigned __int64 __umulh(unsigned __int64 a, unsigned __int64 b);
-+unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b,
-+                          unsigned __int64 *h);
-+#    pragma intrinsic(__umulh,_umul128)
-+#    define BN_UMULT_HIGH(a,b)           __umulh((a),(b))
-+#    define BN_UMULT_LOHI(low,high,a,b)  ((low)=_umul128((a),(b),&(high)))
-+#   endif
-+#  elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
-+#   if defined(__GNUC__) && __GNUC__>=2
-+#    if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
-+      /* "h" constraint is not an option on R6 and was removed in 4.4 */
-+#     define BN_UMULT_HIGH(a,b)          (((__uint128_t)(a)*(b))>>64)
-+#     define BN_UMULT_LOHI(low,high,a,b) ({     \
-+        __uint128_t ret=(__uint128_t)(a)*(b);   \
-+        (high)=ret>>64; (low)=ret;       })
-+#    else
-+#     define BN_UMULT_HIGH(a,b) ({      \
-+        register BN_ULONG ret;          \
-+        asm ("dmultu    %1,%2"          \
-+             : "=h"(ret)                \
-+             : "r"(a), "r"(b) : "l");   \
-+        ret;                    })
-+#     define BN_UMULT_LOHI(low,high,a,b)\
-+        asm ("dmultu    %2,%3"          \
-+             : "=l"(low),"=h"(high)     \
-+             : "r"(a), "r"(b));
-+#    endif
-+#   endif
-+#  elif defined(__aarch64__) && defined(SIXTY_FOUR_BIT_LONG)
-+#   if defined(__GNUC__) && __GNUC__>=2
-+#    define BN_UMULT_HIGH(a,b)   ({      \
-+        register BN_ULONG ret;          \
-+        asm ("umulh     %0,%1,%2"       \
-+             : "=r"(ret)                \
-+             : "r"(a), "r"(b));         \
-+        ret;                    })
-+#   endif
-+#  endif                        /* cpu */
-+# endif                         /* OPENSSL_NO_ASM */
-+
-+/*************************************************************
-+ * Using the long long type
-+ */
-+# define Lw(t)    (((BN_ULONG)(t))&BN_MASK2)
-+# define Hw(t)    (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
-+
-+# ifdef BN_DEBUG_RAND
-+#  define bn_clear_top2max(a) \
-+        { \
-+        int      ind = (a)->dmax - (a)->top; \
-+        BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
-+        for (; ind != 0; ind--) \
-+                *(++ftl) = 0x0; \
-+        }
-+# else
-+#  define bn_clear_top2max(a)
-+# endif
-+
-+# ifdef BN_LLONG
-+#  define mul_add(r,a,w,c) { \
-+        BN_ULLONG t; \
-+        t=(BN_ULLONG)w * (a) + (r) + (c); \
-+        (r)= Lw(t); \
-+        (c)= Hw(t); \
-+        }
-+
-+#  define mul(r,a,w,c) { \
-+        BN_ULLONG t; \
-+        t=(BN_ULLONG)w * (a) + (c); \
-+        (r)= Lw(t); \
-+        (c)= Hw(t); \
-+        }
-+
-+#  define sqr(r0,r1,a) { \
-+        BN_ULLONG t; \
-+        t=(BN_ULLONG)(a)*(a); \
-+        (r0)=Lw(t); \
-+        (r1)=Hw(t); \
-+        }
-+
-+# elif defined(BN_UMULT_LOHI)
-+#  define mul_add(r,a,w,c) {              \
-+        BN_ULONG high,low,ret,tmp=(a);  \
-+        ret =  (r);                     \
-+        BN_UMULT_LOHI(low,high,w,tmp);  \
-+        ret += (c);                     \
-+        (c) =  (ret<(c))?1:0;           \
-+        (c) += high;                    \
-+        ret += low;                     \
-+        (c) += (ret>BN_BITS4)&BN_MASK2l)
-+#  define L2HBITS(a)      (((a)<>BN_BITS2)&BN_MASKl)
-+#  define LL2HBITS(a)     ((BN_ULLONG)((a)&BN_MASKl)<>(BN_BITS4-1); \
-+        m =(m&BN_MASK2l)<<(BN_BITS4+1); \
-+        l=(l+m)&BN_MASK2; if (l < m) h++; \
-+        (lo)=l; \
-+        (ho)=h; \
-+        }
-+
-+#  define mul_add(r,a,bl,bh,c) { \
-+        BN_ULONG l,h; \
-+ \
-+        h= (a); \
-+        l=LBITS(h); \
-+        h=HBITS(h); \
-+        mul64(l,h,(bl),(bh)); \
-+ \
-+        /* non-multiply part */ \
-+        l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
-+        (c)=(r); \
-+        l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
-+        (c)=h&BN_MASK2; \
-+        (r)=l; \
-+        }
-+
-+#  define mul(r,a,bl,bh,c) { \
-+        BN_ULONG l,h; \
-+ \
-+        h= (a); \
-+        l=LBITS(h); \
-+        h=HBITS(h); \
-+        mul64(l,h,(bl),(bh)); \
-+ \
-+        /* non-multiply part */ \
-+        l+=(c); if ((l&BN_MASK2) < (c)) h++; \
-+        (c)=h&BN_MASK2; \
-+        (r)=l&BN_MASK2; \
-+        }
-+# endif                         /* !BN_LLONG */
-+
-+void BN_RECP_CTX_init(BN_RECP_CTX *recp);
-+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
-+
-+void bn_init(BIGNUM *a);
-+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb);
-+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
-+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
-+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
-+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a);
-+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a);
-+int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n);
-+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl);
-+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
-+                      int dna, int dnb, BN_ULONG *t);
-+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
-+                           int n, int tna, int tnb, BN_ULONG *t);
-+void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t);
-+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n);
-+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
-+                          BN_ULONG *t);
-+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
-+                 BN_ULONG *t);
-+BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
-+                           int cl, int dl);
-+BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
-+                           int cl, int dl);
-+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                const BN_ULONG *np, const BN_ULONG *n0, int num);
-+
-+BIGNUM *int_bn_mod_inverse(BIGNUM *in,
-+                           const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx,
-+                           int *noinv);
-+
-+int bn_probable_prime_dh(BIGNUM *rnd, int bits,
-+                         const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
-+int bn_probable_prime_dh_retry(BIGNUM *rnd, int bits, BN_CTX *ctx);
-+int bn_probable_prime_dh_coprime(BIGNUM *rnd, int bits, BN_CTX *ctx);
-+
-+static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits)
-+{
-+    if (bits > (INT_MAX - BN_BITS2 + 1))
-+        return NULL;
-+
-+    if (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax)
-+        return a;
-+
-+    return bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2);
-+}
-+
-+#ifdef  __cplusplus
-+}
-+#endif
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_lib.c
-new file mode 100644
-index 0000000..17d34c3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_lib.c
-@@ -0,0 +1,1037 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+#include 
-+
-+/* This stuff appears to be completely unused, so is deprecated */
-+#if OPENSSL_API_COMPAT < 0x00908000L
-+/*-
-+ * For a 32 bit machine
-+ * 2 -   4 ==  128
-+ * 3 -   8 ==  256
-+ * 4 -  16 ==  512
-+ * 5 -  32 == 1024
-+ * 6 -  64 == 2048
-+ * 7 - 128 == 4096
-+ * 8 - 256 == 8192
-+ */
-+static int bn_limit_bits = 0;
-+static int bn_limit_num = 8;    /* (1<= 0) {
-+        if (mult > (int)(sizeof(int) * 8) - 1)
-+            mult = sizeof(int) * 8 - 1;
-+        bn_limit_bits = mult;
-+        bn_limit_num = 1 << mult;
-+    }
-+    if (high >= 0) {
-+        if (high > (int)(sizeof(int) * 8) - 1)
-+            high = sizeof(int) * 8 - 1;
-+        bn_limit_bits_high = high;
-+        bn_limit_num_high = 1 << high;
-+    }
-+    if (low >= 0) {
-+        if (low > (int)(sizeof(int) * 8) - 1)
-+            low = sizeof(int) * 8 - 1;
-+        bn_limit_bits_low = low;
-+        bn_limit_num_low = 1 << low;
-+    }
-+    if (mont >= 0) {
-+        if (mont > (int)(sizeof(int) * 8) - 1)
-+            mont = sizeof(int) * 8 - 1;
-+        bn_limit_bits_mont = mont;
-+        bn_limit_num_mont = 1 << mont;
-+    }
-+}
-+
-+int BN_get_params(int which)
-+{
-+    if (which == 0)
-+        return (bn_limit_bits);
-+    else if (which == 1)
-+        return (bn_limit_bits_high);
-+    else if (which == 2)
-+        return (bn_limit_bits_low);
-+    else if (which == 3)
-+        return (bn_limit_bits_mont);
-+    else
-+        return (0);
-+}
-+#endif
-+
-+const BIGNUM *BN_value_one(void)
-+{
-+    static const BN_ULONG data_one = 1L;
-+    static const BIGNUM const_one =
-+        { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA };
-+
-+    return (&const_one);
-+}
-+
-+int BN_num_bits_word(BN_ULONG l)
-+{
-+    static const unsigned char bits[256] = {
-+        0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
-+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-+    };
-+
-+#if defined(SIXTY_FOUR_BIT_LONG)
-+    if (l & 0xffffffff00000000L) {
-+        if (l & 0xffff000000000000L) {
-+            if (l & 0xff00000000000000L) {
-+                return (bits[(int)(l >> 56)] + 56);
-+            } else
-+                return (bits[(int)(l >> 48)] + 48);
-+        } else {
-+            if (l & 0x0000ff0000000000L) {
-+                return (bits[(int)(l >> 40)] + 40);
-+            } else
-+                return (bits[(int)(l >> 32)] + 32);
-+        }
-+    } else
-+#else
-+# ifdef SIXTY_FOUR_BIT
-+    if (l & 0xffffffff00000000LL) {
-+        if (l & 0xffff000000000000LL) {
-+            if (l & 0xff00000000000000LL) {
-+                return (bits[(int)(l >> 56)] + 56);
-+            } else
-+                return (bits[(int)(l >> 48)] + 48);
-+        } else {
-+            if (l & 0x0000ff0000000000LL) {
-+                return (bits[(int)(l >> 40)] + 40);
-+            } else
-+                return (bits[(int)(l >> 32)] + 32);
-+        }
-+    } else
-+# endif
-+#endif
-+    {
-+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
-+        if (l & 0xffff0000L) {
-+            if (l & 0xff000000L)
-+                return (bits[(int)(l >> 24L)] + 24);
-+            else
-+                return (bits[(int)(l >> 16L)] + 16);
-+        } else
-+#endif
-+        {
-+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
-+            if (l & 0xff00L)
-+                return (bits[(int)(l >> 8)] + 8);
-+            else
-+#endif
-+                return (bits[(int)(l)]);
-+        }
-+    }
-+}
-+
-+int BN_num_bits(const BIGNUM *a)
-+{
-+    int i = a->top - 1;
-+    bn_check_top(a);
-+
-+    if (BN_is_zero(a))
-+        return 0;
-+    return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
-+}
-+
-+static void bn_free_d(BIGNUM *a)
-+{
-+    if (BN_get_flags(a, BN_FLG_SECURE))
-+        OPENSSL_secure_free(a->d);
-+    else
-+        OPENSSL_free(a->d);
-+}
-+
-+
-+void BN_clear_free(BIGNUM *a)
-+{
-+    int i;
-+
-+    if (a == NULL)
-+        return;
-+    bn_check_top(a);
-+    if (a->d != NULL) {
-+        OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
-+        if (!BN_get_flags(a, BN_FLG_STATIC_DATA))
-+            bn_free_d(a);
-+    }
-+    i = BN_get_flags(a, BN_FLG_MALLOCED);
-+    OPENSSL_cleanse(a, sizeof(*a));
-+    if (i)
-+        OPENSSL_free(a);
-+}
-+
-+void BN_free(BIGNUM *a)
-+{
-+    if (a == NULL)
-+        return;
-+    bn_check_top(a);
-+    if (!BN_get_flags(a, BN_FLG_STATIC_DATA))
-+        bn_free_d(a);
-+    if (a->flags & BN_FLG_MALLOCED)
-+        OPENSSL_free(a);
-+    else {
-+#if OPENSSL_API_COMPAT < 0x00908000L
-+        a->flags |= BN_FLG_FREE;
-+#endif
-+        a->d = NULL;
-+    }
-+}
-+
-+void bn_init(BIGNUM *a)
-+{
-+    static BIGNUM nilbn;
-+
-+    *a = nilbn;
-+    bn_check_top(a);
-+}
-+
-+BIGNUM *BN_new(void)
-+{
-+    BIGNUM *ret;
-+
-+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
-+        BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+    ret->flags = BN_FLG_MALLOCED;
-+    bn_check_top(ret);
-+    return (ret);
-+}
-+
-+ BIGNUM *BN_secure_new(void)
-+ {
-+     BIGNUM *ret = BN_new();
-+     if (ret != NULL)
-+         ret->flags |= BN_FLG_SECURE;
-+     return (ret);
-+ }
-+
-+/* This is used by bn_expand2() */
-+/* The caller MUST check that words > b->dmax before calling this */
-+static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
-+{
-+    BN_ULONG *A, *a = NULL;
-+    const BN_ULONG *B;
-+    int i;
-+
-+    bn_check_top(b);
-+
-+    if (words > (INT_MAX / (4 * BN_BITS2))) {
-+        BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
-+        return NULL;
-+    }
-+    if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
-+        BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
-+        return (NULL);
-+    }
-+    if (BN_get_flags(b, BN_FLG_SECURE))
-+        a = A = OPENSSL_secure_zalloc(words * sizeof(*a));
-+    else
-+        a = A = OPENSSL_zalloc(words * sizeof(*a));
-+    if (A == NULL) {
-+        BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+
-+#if 1
-+    B = b->d;
-+    /* Check if the previous number needs to be copied */
-+    if (B != NULL) {
-+        for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
-+            /*
-+             * The fact that the loop is unrolled
-+             * 4-wise is a tribute to Intel. It's
-+             * the one that doesn't have enough
-+             * registers to accommodate more data.
-+             * I'd unroll it 8-wise otherwise:-)
-+             *
-+             *              
-+             */
-+            BN_ULONG a0, a1, a2, a3;
-+            a0 = B[0];
-+            a1 = B[1];
-+            a2 = B[2];
-+            a3 = B[3];
-+            A[0] = a0;
-+            A[1] = a1;
-+            A[2] = a2;
-+            A[3] = a3;
-+        }
-+        switch (b->top & 3) {
-+        case 3:
-+            A[2] = B[2];
-+        case 2:
-+            A[1] = B[1];
-+        case 1:
-+            A[0] = B[0];
-+        case 0:
-+            /* Without the "case 0" some old optimizers got this wrong. */
-+            ;
-+        }
-+    }
-+#else
-+    memset(A, 0, sizeof(*A) * words);
-+    memcpy(A, b->d, sizeof(b->d[0]) * b->top);
-+#endif
-+
-+    return (a);
-+}
-+
-+/*
-+ * This is an internal function that should not be used in applications. It
-+ * ensures that 'b' has enough room for a 'words' word number and initialises
-+ * any unused part of b->d with leading zeros. It is mostly used by the
-+ * various BIGNUM routines. If there is an error, NULL is returned. If not,
-+ * 'b' is returned.
-+ */
-+
-+BIGNUM *bn_expand2(BIGNUM *b, int words)
-+{
-+    bn_check_top(b);
-+
-+    if (words > b->dmax) {
-+        BN_ULONG *a = bn_expand_internal(b, words);
-+        if (!a)
-+            return NULL;
-+        if (b->d) {
-+            OPENSSL_cleanse(b->d, b->dmax * sizeof(b->d[0]));
-+            bn_free_d(b);
-+        }
-+        b->d = a;
-+        b->dmax = words;
-+    }
-+
-+    bn_check_top(b);
-+    return b;
-+}
-+
-+BIGNUM *BN_dup(const BIGNUM *a)
-+{
-+    BIGNUM *t;
-+
-+    if (a == NULL)
-+        return NULL;
-+    bn_check_top(a);
-+
-+    t = BN_get_flags(a, BN_FLG_SECURE) ? BN_secure_new() : BN_new();
-+    if (t == NULL)
-+        return NULL;
-+    if (!BN_copy(t, a)) {
-+        BN_free(t);
-+        return NULL;
-+    }
-+    bn_check_top(t);
-+    return t;
-+}
-+
-+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
-+{
-+    int i;
-+    BN_ULONG *A;
-+    const BN_ULONG *B;
-+
-+    bn_check_top(b);
-+
-+    if (a == b)
-+        return (a);
-+    if (bn_wexpand(a, b->top) == NULL)
-+        return (NULL);
-+
-+#if 1
-+    A = a->d;
-+    B = b->d;
-+    for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
-+        BN_ULONG a0, a1, a2, a3;
-+        a0 = B[0];
-+        a1 = B[1];
-+        a2 = B[2];
-+        a3 = B[3];
-+        A[0] = a0;
-+        A[1] = a1;
-+        A[2] = a2;
-+        A[3] = a3;
-+    }
-+    /* ultrix cc workaround, see comments in bn_expand_internal */
-+    switch (b->top & 3) {
-+    case 3:
-+        A[2] = B[2];
-+    case 2:
-+        A[1] = B[1];
-+    case 1:
-+        A[0] = B[0];
-+    case 0:;
-+    }
-+#else
-+    memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
-+#endif
-+
-+    a->top = b->top;
-+    a->neg = b->neg;
-+    bn_check_top(a);
-+    return (a);
-+}
-+
-+void BN_swap(BIGNUM *a, BIGNUM *b)
-+{
-+    int flags_old_a, flags_old_b;
-+    BN_ULONG *tmp_d;
-+    int tmp_top, tmp_dmax, tmp_neg;
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+
-+    flags_old_a = a->flags;
-+    flags_old_b = b->flags;
-+
-+    tmp_d = a->d;
-+    tmp_top = a->top;
-+    tmp_dmax = a->dmax;
-+    tmp_neg = a->neg;
-+
-+    a->d = b->d;
-+    a->top = b->top;
-+    a->dmax = b->dmax;
-+    a->neg = b->neg;
-+
-+    b->d = tmp_d;
-+    b->top = tmp_top;
-+    b->dmax = tmp_dmax;
-+    b->neg = tmp_neg;
-+
-+    a->flags =
-+        (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
-+    b->flags =
-+        (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
-+    bn_check_top(a);
-+    bn_check_top(b);
-+}
-+
-+void BN_clear(BIGNUM *a)
-+{
-+    bn_check_top(a);
-+    if (a->d != NULL)
-+        OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax);
-+    a->top = 0;
-+    a->neg = 0;
-+}
-+
-+BN_ULONG BN_get_word(const BIGNUM *a)
-+{
-+    if (a->top > 1)
-+        return BN_MASK2;
-+    else if (a->top == 1)
-+        return a->d[0];
-+    /* a->top == 0 */
-+    return 0;
-+}
-+
-+int BN_set_word(BIGNUM *a, BN_ULONG w)
-+{
-+    bn_check_top(a);
-+    if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
-+        return (0);
-+    a->neg = 0;
-+    a->d[0] = w;
-+    a->top = (w ? 1 : 0);
-+    bn_check_top(a);
-+    return (1);
-+}
-+
-+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
-+{
-+    unsigned int i, m;
-+    unsigned int n;
-+    BN_ULONG l;
-+    BIGNUM *bn = NULL;
-+
-+    if (ret == NULL)
-+        ret = bn = BN_new();
-+    if (ret == NULL)
-+        return (NULL);
-+    bn_check_top(ret);
-+    /* Skip leading zero's. */
-+    for ( ; len > 0 && *s == 0; s++, len--)
-+        continue;
-+    n = len;
-+    if (n == 0) {
-+        ret->top = 0;
-+        return (ret);
-+    }
-+    i = ((n - 1) / BN_BYTES) + 1;
-+    m = ((n - 1) % (BN_BYTES));
-+    if (bn_wexpand(ret, (int)i) == NULL) {
-+        BN_free(bn);
-+        return NULL;
-+    }
-+    ret->top = i;
-+    ret->neg = 0;
-+    l = 0;
-+    while (n--) {
-+        l = (l << 8L) | *(s++);
-+        if (m-- == 0) {
-+            ret->d[--i] = l;
-+            l = 0;
-+            m = BN_BYTES - 1;
-+        }
-+    }
-+    /*
-+     * need to call this due to clear byte at top if avoiding having the top
-+     * bit set (-ve number)
-+     */
-+    bn_correct_top(ret);
-+    return (ret);
-+}
-+
-+/* ignore negative */
-+static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
-+{
-+    int i;
-+    BN_ULONG l;
-+
-+    bn_check_top(a);
-+    i = BN_num_bytes(a);
-+    if (tolen == -1)
-+        tolen = i;
-+    else if (tolen < i)
-+        return -1;
-+    /* Add leading zeroes if necessary */
-+    if (tolen > i) {
-+        memset(to, 0, tolen - i);
-+        to += tolen - i;
-+    }
-+    while (i--) {
-+        l = a->d[i / BN_BYTES];
-+        *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
-+    }
-+    return tolen;
-+}
-+
-+int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
-+{
-+    if (tolen < 0)
-+        return -1;
-+    return bn2binpad(a, to, tolen);
-+}
-+
-+int BN_bn2bin(const BIGNUM *a, unsigned char *to)
-+{
-+    return bn2binpad(a, to, -1);
-+}
-+
-+BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
-+{
-+    unsigned int i, m;
-+    unsigned int n;
-+    BN_ULONG l;
-+    BIGNUM *bn = NULL;
-+
-+    if (ret == NULL)
-+        ret = bn = BN_new();
-+    if (ret == NULL)
-+        return (NULL);
-+    bn_check_top(ret);
-+    s += len;
-+    /* Skip trailing zeroes. */
-+    for ( ; len > 0 && s[-1] == 0; s--, len--)
-+        continue;
-+    n = len;
-+    if (n == 0) {
-+        ret->top = 0;
-+        return ret;
-+    }
-+    i = ((n - 1) / BN_BYTES) + 1;
-+    m = ((n - 1) % (BN_BYTES));
-+    if (bn_wexpand(ret, (int)i) == NULL) {
-+        BN_free(bn);
-+        return NULL;
-+    }
-+    ret->top = i;
-+    ret->neg = 0;
-+    l = 0;
-+    while (n--) {
-+        s--;
-+        l = (l << 8L) | *s;
-+        if (m-- == 0) {
-+            ret->d[--i] = l;
-+            l = 0;
-+            m = BN_BYTES - 1;
-+        }
-+    }
-+    /*
-+     * need to call this due to clear byte at top if avoiding having the top
-+     * bit set (-ve number)
-+     */
-+    bn_correct_top(ret);
-+    return ret;
-+}
-+
-+int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
-+{
-+    int i;
-+    BN_ULONG l;
-+    bn_check_top(a);
-+    i = BN_num_bytes(a);
-+    if (tolen < i)
-+        return -1;
-+    /* Add trailing zeroes if necessary */
-+    if (tolen > i)
-+        memset(to + i, 0, tolen - i);
-+    to += i;
-+    while (i--) {
-+        l = a->d[i / BN_BYTES];
-+        to--;
-+        *to = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
-+    }
-+    return tolen;
-+}
-+
-+int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
-+{
-+    int i;
-+    BN_ULONG t1, t2, *ap, *bp;
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+
-+    i = a->top - b->top;
-+    if (i != 0)
-+        return (i);
-+    ap = a->d;
-+    bp = b->d;
-+    for (i = a->top - 1; i >= 0; i--) {
-+        t1 = ap[i];
-+        t2 = bp[i];
-+        if (t1 != t2)
-+            return ((t1 > t2) ? 1 : -1);
-+    }
-+    return (0);
-+}
-+
-+int BN_cmp(const BIGNUM *a, const BIGNUM *b)
-+{
-+    int i;
-+    int gt, lt;
-+    BN_ULONG t1, t2;
-+
-+    if ((a == NULL) || (b == NULL)) {
-+        if (a != NULL)
-+            return (-1);
-+        else if (b != NULL)
-+            return (1);
-+        else
-+            return (0);
-+    }
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+
-+    if (a->neg != b->neg) {
-+        if (a->neg)
-+            return (-1);
-+        else
-+            return (1);
-+    }
-+    if (a->neg == 0) {
-+        gt = 1;
-+        lt = -1;
-+    } else {
-+        gt = -1;
-+        lt = 1;
-+    }
-+
-+    if (a->top > b->top)
-+        return (gt);
-+    if (a->top < b->top)
-+        return (lt);
-+    for (i = a->top - 1; i >= 0; i--) {
-+        t1 = a->d[i];
-+        t2 = b->d[i];
-+        if (t1 > t2)
-+            return (gt);
-+        if (t1 < t2)
-+            return (lt);
-+    }
-+    return (0);
-+}
-+
-+int BN_set_bit(BIGNUM *a, int n)
-+{
-+    int i, j, k;
-+
-+    if (n < 0)
-+        return 0;
-+
-+    i = n / BN_BITS2;
-+    j = n % BN_BITS2;
-+    if (a->top <= i) {
-+        if (bn_wexpand(a, i + 1) == NULL)
-+            return (0);
-+        for (k = a->top; k < i + 1; k++)
-+            a->d[k] = 0;
-+        a->top = i + 1;
-+    }
-+
-+    a->d[i] |= (((BN_ULONG)1) << j);
-+    bn_check_top(a);
-+    return (1);
-+}
-+
-+int BN_clear_bit(BIGNUM *a, int n)
-+{
-+    int i, j;
-+
-+    bn_check_top(a);
-+    if (n < 0)
-+        return 0;
-+
-+    i = n / BN_BITS2;
-+    j = n % BN_BITS2;
-+    if (a->top <= i)
-+        return (0);
-+
-+    a->d[i] &= (~(((BN_ULONG)1) << j));
-+    bn_correct_top(a);
-+    return (1);
-+}
-+
-+int BN_is_bit_set(const BIGNUM *a, int n)
-+{
-+    int i, j;
-+
-+    bn_check_top(a);
-+    if (n < 0)
-+        return 0;
-+    i = n / BN_BITS2;
-+    j = n % BN_BITS2;
-+    if (a->top <= i)
-+        return 0;
-+    return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
-+}
-+
-+int BN_mask_bits(BIGNUM *a, int n)
-+{
-+    int b, w;
-+
-+    bn_check_top(a);
-+    if (n < 0)
-+        return 0;
-+
-+    w = n / BN_BITS2;
-+    b = n % BN_BITS2;
-+    if (w >= a->top)
-+        return 0;
-+    if (b == 0)
-+        a->top = w;
-+    else {
-+        a->top = w + 1;
-+        a->d[w] &= ~(BN_MASK2 << b);
-+    }
-+    bn_correct_top(a);
-+    return (1);
-+}
-+
-+void BN_set_negative(BIGNUM *a, int b)
-+{
-+    if (b && !BN_is_zero(a))
-+        a->neg = 1;
-+    else
-+        a->neg = 0;
-+}
-+
-+int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
-+{
-+    int i;
-+    BN_ULONG aa, bb;
-+
-+    aa = a[n - 1];
-+    bb = b[n - 1];
-+    if (aa != bb)
-+        return ((aa > bb) ? 1 : -1);
-+    for (i = n - 2; i >= 0; i--) {
-+        aa = a[i];
-+        bb = b[i];
-+        if (aa != bb)
-+            return ((aa > bb) ? 1 : -1);
-+    }
-+    return (0);
-+}
-+
-+/*
-+ * Here follows a specialised variants of bn_cmp_words().  It has the
-+ * capability of performing the operation on arrays of different sizes. The
-+ * sizes of those arrays is expressed through cl, which is the common length
-+ * ( basically, min(len(a),len(b)) ), and dl, which is the delta between the
-+ * two lengths, calculated as len(a)-len(b). All lengths are the number of
-+ * BN_ULONGs...
-+ */
-+
-+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
-+{
-+    int n, i;
-+    n = cl - 1;
-+
-+    if (dl < 0) {
-+        for (i = dl; i < 0; i++) {
-+            if (b[n - i] != 0)
-+                return -1;      /* a < b */
-+        }
-+    }
-+    if (dl > 0) {
-+        for (i = dl; i > 0; i--) {
-+            if (a[n + i] != 0)
-+                return 1;       /* a > b */
-+        }
-+    }
-+    return bn_cmp_words(a, b, cl);
-+}
-+
-+/*
-+ * Constant-time conditional swap of a and b.
-+ * a and b are swapped if condition is not 0.  The code assumes that at most one bit of condition is set.
-+ * nwords is the number of words to swap.  The code assumes that at least nwords are allocated in both a and b,
-+ * and that no more than nwords are used by either a or b.
-+ * a and b cannot be the same number
-+ */
-+void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
-+{
-+    BN_ULONG t;
-+    int i;
-+
-+    bn_wcheck_size(a, nwords);
-+    bn_wcheck_size(b, nwords);
-+
-+    assert(a != b);
-+    assert((condition & (condition - 1)) == 0);
-+    assert(sizeof(BN_ULONG) >= sizeof(int));
-+
-+    condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
-+
-+    t = (a->top ^ b->top) & condition;
-+    a->top ^= t;
-+    b->top ^= t;
-+
-+#define BN_CONSTTIME_SWAP(ind) \
-+        do { \
-+                t = (a->d[ind] ^ b->d[ind]) & condition; \
-+                a->d[ind] ^= t; \
-+                b->d[ind] ^= t; \
-+        } while (0)
-+
-+    switch (nwords) {
-+    default:
-+        for (i = 10; i < nwords; i++)
-+            BN_CONSTTIME_SWAP(i);
-+        /* Fallthrough */
-+    case 10:
-+        BN_CONSTTIME_SWAP(9);   /* Fallthrough */
-+    case 9:
-+        BN_CONSTTIME_SWAP(8);   /* Fallthrough */
-+    case 8:
-+        BN_CONSTTIME_SWAP(7);   /* Fallthrough */
-+    case 7:
-+        BN_CONSTTIME_SWAP(6);   /* Fallthrough */
-+    case 6:
-+        BN_CONSTTIME_SWAP(5);   /* Fallthrough */
-+    case 5:
-+        BN_CONSTTIME_SWAP(4);   /* Fallthrough */
-+    case 4:
-+        BN_CONSTTIME_SWAP(3);   /* Fallthrough */
-+    case 3:
-+        BN_CONSTTIME_SWAP(2);   /* Fallthrough */
-+    case 2:
-+        BN_CONSTTIME_SWAP(1);   /* Fallthrough */
-+    case 1:
-+        BN_CONSTTIME_SWAP(0);
-+    }
-+#undef BN_CONSTTIME_SWAP
-+}
-+
-+/* Bits of security, see SP800-57 */
-+
-+int BN_security_bits(int L, int N)
-+{
-+    int secbits, bits;
-+    if (L >= 15360)
-+        secbits = 256;
-+    else if (L >= 7690)
-+        secbits = 192;
-+    else if (L >= 3072)
-+        secbits = 128;
-+    else if (L >= 2048)
-+        secbits = 112;
-+    else if (L >= 1024)
-+        secbits = 80;
-+    else
-+        return 0;
-+    if (N == -1)
-+        return secbits;
-+    bits = N / 2;
-+    if (bits < 80)
-+        return 0;
-+    return bits >= secbits ? secbits : bits;
-+}
-+
-+void BN_zero_ex(BIGNUM *a)
-+{
-+    a->top = 0;
-+    a->neg = 0;
-+}
-+
-+int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
-+{
-+    return ((a->top == 1) && (a->d[0] == w)) || ((w == 0) && (a->top == 0));
-+}
-+
-+int BN_is_zero(const BIGNUM *a)
-+{
-+    return a->top == 0;
-+}
-+
-+int BN_is_one(const BIGNUM *a)
-+{
-+    return BN_abs_is_word(a, 1) && !a->neg;
-+}
-+
-+int BN_is_word(const BIGNUM *a, const BN_ULONG w)
-+{
-+    return BN_abs_is_word(a, w) && (!w || !a->neg);
-+}
-+
-+int BN_is_odd(const BIGNUM *a)
-+{
-+    return (a->top > 0) && (a->d[0] & 1);
-+}
-+
-+int BN_is_negative(const BIGNUM *a)
-+{
-+    return (a->neg != 0);
-+}
-+
-+int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
-+                     BN_CTX *ctx)
-+{
-+    return BN_mod_mul_montgomery(r, a, &(mont->RR), mont, ctx);
-+}
-+
-+void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
-+{
-+    dest->d = b->d;
-+    dest->top = b->top;
-+    dest->dmax = b->dmax;
-+    dest->neg = b->neg;
-+    dest->flags = ((dest->flags & BN_FLG_MALLOCED)
-+                   | (b->flags & ~BN_FLG_MALLOCED)
-+                   | BN_FLG_STATIC_DATA | flags);
-+}
-+
-+BN_GENCB *BN_GENCB_new(void)
-+{
-+    BN_GENCB *ret;
-+
-+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
-+        BNerr(BN_F_BN_GENCB_NEW, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+
-+    return ret;
-+}
-+
-+void BN_GENCB_free(BN_GENCB *cb)
-+{
-+    if (cb == NULL)
-+        return;
-+    OPENSSL_free(cb);
-+}
-+
-+void BN_set_flags(BIGNUM *b, int n)
-+{
-+    b->flags |= n;
-+}
-+
-+int BN_get_flags(const BIGNUM *b, int n)
-+{
-+    return b->flags & n;
-+}
-+
-+/* Populate a BN_GENCB structure with an "old"-style callback */
-+void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback) (int, int, void *),
-+                      void *cb_arg)
-+{
-+    BN_GENCB *tmp_gencb = gencb;
-+    tmp_gencb->ver = 1;
-+    tmp_gencb->arg = cb_arg;
-+    tmp_gencb->cb.cb_1 = callback;
-+}
-+
-+/* Populate a BN_GENCB structure with a "new"-style callback */
-+void BN_GENCB_set(BN_GENCB *gencb, int (*callback) (int, int, BN_GENCB *),
-+                  void *cb_arg)
-+{
-+    BN_GENCB *tmp_gencb = gencb;
-+    tmp_gencb->ver = 2;
-+    tmp_gencb->arg = cb_arg;
-+    tmp_gencb->cb.cb_2 = callback;
-+}
-+
-+void *BN_GENCB_get_arg(BN_GENCB *cb)
-+{
-+    return cb->arg;
-+}
-+
-+BIGNUM *bn_wexpand(BIGNUM *a, int words)
-+{
-+    return (words <= a->dmax) ? a : bn_expand2(a, words);
-+}
-+
-+void bn_correct_top(BIGNUM *a)
-+{
-+    BN_ULONG *ftl;
-+    int tmp_top = a->top;
-+
-+    if (tmp_top > 0) {
-+        for (ftl = &(a->d[tmp_top]); tmp_top > 0; tmp_top--) {
-+            ftl--;
-+            if (*ftl != 0)
-+                break;
-+        }
-+        a->top = tmp_top;
-+    }
-+    if (a->top == 0)
-+        a->neg = 0;
-+    bn_pollute(a);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mod.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mod.c
-new file mode 100644
-index 0000000..13b583f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mod.c
-@@ -0,0 +1,201 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
-+{
-+    /*
-+     * like BN_mod, but returns non-negative remainder (i.e., 0 <= r < |d|
-+     * always holds)
-+     */
-+
-+    if (!(BN_mod(r, m, d, ctx)))
-+        return 0;
-+    if (!r->neg)
-+        return 1;
-+    /* now   -|d| < r < 0,  so we have to set  r := r + |d| */
-+    return (d->neg ? BN_sub : BN_add) (r, r, d);
-+}
-+
-+int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
-+               BN_CTX *ctx)
-+{
-+    if (!BN_add(r, a, b))
-+        return 0;
-+    return BN_nnmod(r, r, m, ctx);
-+}
-+
-+/*
-+ * BN_mod_add variant that may be used if both a and b are non-negative and
-+ * less than m
-+ */
-+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-+                     const BIGNUM *m)
-+{
-+    if (!BN_uadd(r, a, b))
-+        return 0;
-+    if (BN_ucmp(r, m) >= 0)
-+        return BN_usub(r, r, m);
-+    return 1;
-+}
-+
-+int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
-+               BN_CTX *ctx)
-+{
-+    if (!BN_sub(r, a, b))
-+        return 0;
-+    return BN_nnmod(r, r, m, ctx);
-+}
-+
-+/*
-+ * BN_mod_sub variant that may be used if both a and b are non-negative and
-+ * less than m
-+ */
-+int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-+                     const BIGNUM *m)
-+{
-+    if (!BN_sub(r, a, b))
-+        return 0;
-+    if (r->neg)
-+        return BN_add(r, r, m);
-+    return 1;
-+}
-+
-+/* slow but works */
-+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
-+               BN_CTX *ctx)
-+{
-+    BIGNUM *t;
-+    int ret = 0;
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+    bn_check_top(m);
-+
-+    BN_CTX_start(ctx);
-+    if ((t = BN_CTX_get(ctx)) == NULL)
-+        goto err;
-+    if (a == b) {
-+        if (!BN_sqr(t, a, ctx))
-+            goto err;
-+    } else {
-+        if (!BN_mul(t, a, b, ctx))
-+            goto err;
-+    }
-+    if (!BN_nnmod(r, t, m, ctx))
-+        goto err;
-+    bn_check_top(r);
-+    ret = 1;
-+ err:
-+    BN_CTX_end(ctx);
-+    return (ret);
-+}
-+
-+int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
-+{
-+    if (!BN_sqr(r, a, ctx))
-+        return 0;
-+    /* r->neg == 0,  thus we don't need BN_nnmod */
-+    return BN_mod(r, r, m, ctx);
-+}
-+
-+int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
-+{
-+    if (!BN_lshift1(r, a))
-+        return 0;
-+    bn_check_top(r);
-+    return BN_nnmod(r, r, m, ctx);
-+}
-+
-+/*
-+ * BN_mod_lshift1 variant that may be used if a is non-negative and less than
-+ * m
-+ */
-+int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
-+{
-+    if (!BN_lshift1(r, a))
-+        return 0;
-+    bn_check_top(r);
-+    if (BN_cmp(r, m) >= 0)
-+        return BN_sub(r, r, m);
-+    return 1;
-+}
-+
-+int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
-+                  BN_CTX *ctx)
-+{
-+    BIGNUM *abs_m = NULL;
-+    int ret;
-+
-+    if (!BN_nnmod(r, a, m, ctx))
-+        return 0;
-+
-+    if (m->neg) {
-+        abs_m = BN_dup(m);
-+        if (abs_m == NULL)
-+            return 0;
-+        abs_m->neg = 0;
-+    }
-+
-+    ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
-+    bn_check_top(r);
-+
-+    BN_free(abs_m);
-+    return ret;
-+}
-+
-+/*
-+ * BN_mod_lshift variant that may be used if a is non-negative and less than
-+ * m
-+ */
-+int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
-+{
-+    if (r != a) {
-+        if (BN_copy(r, a) == NULL)
-+            return 0;
-+    }
-+
-+    while (n > 0) {
-+        int max_shift;
-+
-+        /* 0 < r < m */
-+        max_shift = BN_num_bits(m) - BN_num_bits(r);
-+        /* max_shift >= 0 */
-+
-+        if (max_shift < 0) {
-+            BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED);
-+            return 0;
-+        }
-+
-+        if (max_shift > n)
-+            max_shift = n;
-+
-+        if (max_shift) {
-+            if (!BN_lshift(r, r, max_shift))
-+                return 0;
-+            n -= max_shift;
-+        } else {
-+            if (!BN_lshift1(r, r))
-+                return 0;
-+            --n;
-+        }
-+
-+        /* BN_num_bits(r) <= BN_num_bits(m) */
-+
-+        if (BN_cmp(r, m) >= 0) {
-+            if (!BN_sub(r, r, m))
-+                return 0;
-+        }
-+    }
-+    bn_check_top(r);
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mont.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mont.c
-new file mode 100644
-index 0000000..6d37279
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mont.c
-@@ -0,0 +1,434 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Details about Montgomery multiplication algorithms can be found at
-+ * http://security.ece.orst.edu/publications.html, e.g.
-+ * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
-+ * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+#define MONT_WORD               /* use the faster word-based algorithm */
-+
-+#ifdef MONT_WORD
-+static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
-+#endif
-+
-+int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
-+                          BN_MONT_CTX *mont, BN_CTX *ctx)
-+{
-+    BIGNUM *tmp;
-+    int ret = 0;
-+#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
-+    int num = mont->N.top;
-+
-+    if (num > 1 && a->top == num && b->top == num) {
-+        if (bn_wexpand(r, num) == NULL)
-+            return (0);
-+        if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
-+            r->neg = a->neg ^ b->neg;
-+            r->top = num;
-+            bn_correct_top(r);
-+            return (1);
-+        }
-+    }
-+#endif
-+
-+    BN_CTX_start(ctx);
-+    tmp = BN_CTX_get(ctx);
-+    if (tmp == NULL)
-+        goto err;
-+
-+    bn_check_top(tmp);
-+    if (a == b) {
-+        if (!BN_sqr(tmp, a, ctx))
-+            goto err;
-+    } else {
-+        if (!BN_mul(tmp, a, b, ctx))
-+            goto err;
-+    }
-+    /* reduce from aRR to aR */
-+#ifdef MONT_WORD
-+    if (!BN_from_montgomery_word(r, tmp, mont))
-+        goto err;
-+#else
-+    if (!BN_from_montgomery(r, tmp, mont, ctx))
-+        goto err;
-+#endif
-+    bn_check_top(r);
-+    ret = 1;
-+ err:
-+    BN_CTX_end(ctx);
-+    return (ret);
-+}
-+
-+#ifdef MONT_WORD
-+static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
-+{
-+    BIGNUM *n;
-+    BN_ULONG *ap, *np, *rp, n0, v, carry;
-+    int nl, max, i;
-+
-+    n = &(mont->N);
-+    nl = n->top;
-+    if (nl == 0) {
-+        ret->top = 0;
-+        return (1);
-+    }
-+
-+    max = (2 * nl);             /* carry is stored separately */
-+    if (bn_wexpand(r, max) == NULL)
-+        return (0);
-+
-+    r->neg ^= n->neg;
-+    np = n->d;
-+    rp = r->d;
-+
-+    /* clear the top words of T */
-+    i = max - r->top;
-+    if (i)
-+        memset(&rp[r->top], 0, sizeof(*rp) * i);
-+
-+    r->top = max;
-+    n0 = mont->n0[0];
-+
-+    for (carry = 0, i = 0; i < nl; i++, rp++) {
-+        v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2);
-+        v = (v + carry + rp[nl]) & BN_MASK2;
-+        carry |= (v != rp[nl]);
-+        carry &= (v <= rp[nl]);
-+        rp[nl] = v;
-+    }
-+
-+    if (bn_wexpand(ret, nl) == NULL)
-+        return (0);
-+    ret->top = nl;
-+    ret->neg = r->neg;
-+
-+    rp = ret->d;
-+    ap = &(r->d[nl]);
-+
-+# define BRANCH_FREE 1
-+# if BRANCH_FREE
-+    {
-+        BN_ULONG *nrp;
-+        size_t m;
-+
-+        v = bn_sub_words(rp, ap, np, nl) - carry;
-+        /*
-+         * if subtraction result is real, then trick unconditional memcpy
-+         * below to perform in-place "refresh" instead of actual copy.
-+         */
-+        m = (0 - (size_t)v);
-+        nrp =
-+            (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));
-+
-+        for (i = 0, nl -= 4; i < nl; i += 4) {
-+            BN_ULONG t1, t2, t3, t4;
-+
-+            t1 = nrp[i + 0];
-+            t2 = nrp[i + 1];
-+            t3 = nrp[i + 2];
-+            ap[i + 0] = 0;
-+            t4 = nrp[i + 3];
-+            ap[i + 1] = 0;
-+            rp[i + 0] = t1;
-+            ap[i + 2] = 0;
-+            rp[i + 1] = t2;
-+            ap[i + 3] = 0;
-+            rp[i + 2] = t3;
-+            rp[i + 3] = t4;
-+        }
-+        for (nl += 4; i < nl; i++)
-+            rp[i] = nrp[i], ap[i] = 0;
-+    }
-+# else
-+    if (bn_sub_words(rp, ap, np, nl) - carry)
-+        memcpy(rp, ap, nl * sizeof(BN_ULONG));
-+# endif
-+    bn_correct_top(r);
-+    bn_correct_top(ret);
-+    bn_check_top(ret);
-+
-+    return (1);
-+}
-+#endif                          /* MONT_WORD */
-+
-+int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
-+                       BN_CTX *ctx)
-+{
-+    int retn = 0;
-+#ifdef MONT_WORD
-+    BIGNUM *t;
-+
-+    BN_CTX_start(ctx);
-+    if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))
-+        retn = BN_from_montgomery_word(ret, t, mont);
-+    BN_CTX_end(ctx);
-+#else                           /* !MONT_WORD */
-+    BIGNUM *t1, *t2;
-+
-+    BN_CTX_start(ctx);
-+    t1 = BN_CTX_get(ctx);
-+    t2 = BN_CTX_get(ctx);
-+    if (t1 == NULL || t2 == NULL)
-+        goto err;
-+
-+    if (!BN_copy(t1, a))
-+        goto err;
-+    BN_mask_bits(t1, mont->ri);
-+
-+    if (!BN_mul(t2, t1, &mont->Ni, ctx))
-+        goto err;
-+    BN_mask_bits(t2, mont->ri);
-+
-+    if (!BN_mul(t1, t2, &mont->N, ctx))
-+        goto err;
-+    if (!BN_add(t2, a, t1))
-+        goto err;
-+    if (!BN_rshift(ret, t2, mont->ri))
-+        goto err;
-+
-+    if (BN_ucmp(ret, &(mont->N)) >= 0) {
-+        if (!BN_usub(ret, ret, &(mont->N)))
-+            goto err;
-+    }
-+    retn = 1;
-+    bn_check_top(ret);
-+ err:
-+    BN_CTX_end(ctx);
-+#endif                          /* MONT_WORD */
-+    return (retn);
-+}
-+
-+BN_MONT_CTX *BN_MONT_CTX_new(void)
-+{
-+    BN_MONT_CTX *ret;
-+
-+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
-+        return (NULL);
-+
-+    BN_MONT_CTX_init(ret);
-+    ret->flags = BN_FLG_MALLOCED;
-+    return (ret);
-+}
-+
-+void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
-+{
-+    ctx->ri = 0;
-+    bn_init(&(ctx->RR));
-+    bn_init(&(ctx->N));
-+    bn_init(&(ctx->Ni));
-+    ctx->n0[0] = ctx->n0[1] = 0;
-+    ctx->flags = 0;
-+}
-+
-+void BN_MONT_CTX_free(BN_MONT_CTX *mont)
-+{
-+    if (mont == NULL)
-+        return;
-+
-+    BN_clear_free(&(mont->RR));
-+    BN_clear_free(&(mont->N));
-+    BN_clear_free(&(mont->Ni));
-+    if (mont->flags & BN_FLG_MALLOCED)
-+        OPENSSL_free(mont);
-+}
-+
-+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BIGNUM *Ri, *R;
-+
-+    if (BN_is_zero(mod))
-+        return 0;
-+
-+    BN_CTX_start(ctx);
-+    if ((Ri = BN_CTX_get(ctx)) == NULL)
-+        goto err;
-+    R = &(mont->RR);            /* grab RR as a temp */
-+    if (!BN_copy(&(mont->N), mod))
-+        goto err;               /* Set N */
-+    mont->N.neg = 0;
-+
-+#ifdef MONT_WORD
-+    {
-+        BIGNUM tmod;
-+        BN_ULONG buf[2];
-+
-+        bn_init(&tmod);
-+        tmod.d = buf;
-+        tmod.dmax = 2;
-+        tmod.neg = 0;
-+
-+        mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
-+
-+# if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
-+        /*
-+         * Only certain BN_BITS2<=32 platforms actually make use of n0[1],
-+         * and we could use the #else case (with a shorter R value) for the
-+         * others.  However, currently only the assembler files do know which
-+         * is which.
-+         */
-+
-+        BN_zero(R);
-+        if (!(BN_set_bit(R, 2 * BN_BITS2)))
-+            goto err;
-+
-+        tmod.top = 0;
-+        if ((buf[0] = mod->d[0]))
-+            tmod.top = 1;
-+        if ((buf[1] = mod->top > 1 ? mod->d[1] : 0))
-+            tmod.top = 2;
-+
-+        if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
-+            goto err;
-+        if (!BN_lshift(Ri, Ri, 2 * BN_BITS2))
-+            goto err;           /* R*Ri */
-+        if (!BN_is_zero(Ri)) {
-+            if (!BN_sub_word(Ri, 1))
-+                goto err;
-+        } else {                /* if N mod word size == 1 */
-+
-+            if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL)
-+                goto err;
-+            /* Ri-- (mod double word size) */
-+            Ri->neg = 0;
-+            Ri->d[0] = BN_MASK2;
-+            Ri->d[1] = BN_MASK2;
-+            Ri->top = 2;
-+        }
-+        if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
-+            goto err;
-+        /*
-+         * Ni = (R*Ri-1)/N, keep only couple of least significant words:
-+         */
-+        mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
-+        mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
-+# else
-+        BN_zero(R);
-+        if (!(BN_set_bit(R, BN_BITS2)))
-+            goto err;           /* R */
-+
-+        buf[0] = mod->d[0];     /* tmod = N mod word size */
-+        buf[1] = 0;
-+        tmod.top = buf[0] != 0 ? 1 : 0;
-+        /* Ri = R^-1 mod N */
-+        if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
-+            goto err;
-+        if (!BN_lshift(Ri, Ri, BN_BITS2))
-+            goto err;           /* R*Ri */
-+        if (!BN_is_zero(Ri)) {
-+            if (!BN_sub_word(Ri, 1))
-+                goto err;
-+        } else {                /* if N mod word size == 1 */
-+
-+            if (!BN_set_word(Ri, BN_MASK2))
-+                goto err;       /* Ri-- (mod word size) */
-+        }
-+        if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
-+            goto err;
-+        /*
-+         * Ni = (R*Ri-1)/N, keep only least significant word:
-+         */
-+        mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
-+        mont->n0[1] = 0;
-+# endif
-+    }
-+#else                           /* !MONT_WORD */
-+    {                           /* bignum version */
-+        mont->ri = BN_num_bits(&mont->N);
-+        BN_zero(R);
-+        if (!BN_set_bit(R, mont->ri))
-+            goto err;           /* R = 2^ri */
-+        /* Ri = R^-1 mod N */
-+        if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL)
-+            goto err;
-+        if (!BN_lshift(Ri, Ri, mont->ri))
-+            goto err;           /* R*Ri */
-+        if (!BN_sub_word(Ri, 1))
-+            goto err;
-+        /*
-+         * Ni = (R*Ri-1) / N
-+         */
-+        if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx))
-+            goto err;
-+    }
-+#endif
-+
-+    /* setup RR for conversions */
-+    BN_zero(&(mont->RR));
-+    if (!BN_set_bit(&(mont->RR), mont->ri * 2))
-+        goto err;
-+    if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    BN_CTX_end(ctx);
-+    return ret;
-+}
-+
-+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
-+{
-+    if (to == from)
-+        return (to);
-+
-+    if (!BN_copy(&(to->RR), &(from->RR)))
-+        return NULL;
-+    if (!BN_copy(&(to->N), &(from->N)))
-+        return NULL;
-+    if (!BN_copy(&(to->Ni), &(from->Ni)))
-+        return NULL;
-+    to->ri = from->ri;
-+    to->n0[0] = from->n0[0];
-+    to->n0[1] = from->n0[1];
-+    return (to);
-+}
-+
-+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock,
-+                                    const BIGNUM *mod, BN_CTX *ctx)
-+{
-+    BN_MONT_CTX *ret;
-+
-+    CRYPTO_THREAD_read_lock(lock);
-+    ret = *pmont;
-+    CRYPTO_THREAD_unlock(lock);
-+    if (ret)
-+        return ret;
-+
-+    /*
-+     * We don't want to serialise globally while doing our lazy-init math in
-+     * BN_MONT_CTX_set. That punishes threads that are doing independent
-+     * things. Instead, punish the case where more than one thread tries to
-+     * lazy-init the same 'pmont', by having each do the lazy-init math work
-+     * independently and only use the one from the thread that wins the race
-+     * (the losers throw away the work they've done).
-+     */
-+    ret = BN_MONT_CTX_new();
-+    if (ret == NULL)
-+        return NULL;
-+    if (!BN_MONT_CTX_set(ret, mod, ctx)) {
-+        BN_MONT_CTX_free(ret);
-+        return NULL;
-+    }
-+
-+    /* The locked compare-and-set, after the local work is done. */
-+    CRYPTO_THREAD_write_lock(lock);
-+    if (*pmont) {
-+        BN_MONT_CTX_free(ret);
-+        ret = *pmont;
-+    } else
-+        *pmont = ret;
-+    CRYPTO_THREAD_unlock(lock);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mpi.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mpi.c
-new file mode 100644
-index 0000000..043e21d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mpi.c
-@@ -0,0 +1,86 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+int BN_bn2mpi(const BIGNUM *a, unsigned char *d)
-+{
-+    int bits;
-+    int num = 0;
-+    int ext = 0;
-+    long l;
-+
-+    bits = BN_num_bits(a);
-+    num = (bits + 7) / 8;
-+    if (bits > 0) {
-+        ext = ((bits & 0x07) == 0);
-+    }
-+    if (d == NULL)
-+        return (num + 4 + ext);
-+
-+    l = num + ext;
-+    d[0] = (unsigned char)(l >> 24) & 0xff;
-+    d[1] = (unsigned char)(l >> 16) & 0xff;
-+    d[2] = (unsigned char)(l >> 8) & 0xff;
-+    d[3] = (unsigned char)(l) & 0xff;
-+    if (ext)
-+        d[4] = 0;
-+    num = BN_bn2bin(a, &(d[4 + ext]));
-+    if (a->neg)
-+        d[4] |= 0x80;
-+    return (num + 4 + ext);
-+}
-+
-+BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain)
-+{
-+    long len;
-+    int neg = 0;
-+    BIGNUM *a = NULL;
-+
-+    if (n < 4) {
-+        BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH);
-+        return NULL;
-+    }
-+    len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int)
-+        d[3];
-+    if ((len + 4) != n) {
-+        BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR);
-+        return NULL;
-+    }
-+
-+    if (ain == NULL)
-+        a = BN_new();
-+    else
-+        a = ain;
-+
-+    if (a == NULL)
-+        return NULL;
-+
-+    if (len == 0) {
-+        a->neg = 0;
-+        a->top = 0;
-+        return a;
-+    }
-+    d += 4;
-+    if ((*d) & 0x80)
-+        neg = 1;
-+    if (BN_bin2bn(d, (int)len, a) == NULL) {
-+        if (ain == NULL)
-+            BN_free(a);
-+        return NULL;
-+    }
-+    a->neg = neg;
-+    if (neg) {
-+        BN_clear_bit(a, BN_num_bits(a) - 1);
-+    }
-+    bn_check_top(a);
-+    return a;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mul.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mul.c
-new file mode 100644
-index 0000000..4a0a950
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_mul.c
-@@ -0,0 +1,1045 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
-+/*
-+ * Here follows specialised variants of bn_add_words() and bn_sub_words().
-+ * They have the property performing operations on arrays of different sizes.
-+ * The sizes of those arrays is expressed through cl, which is the common
-+ * length ( basically, min(len(a),len(b)) ), and dl, which is the delta
-+ * between the two lengths, calculated as len(a)-len(b). All lengths are the
-+ * number of BN_ULONGs...  For the operations that require a result array as
-+ * parameter, it must have the length cl+abs(dl). These functions should
-+ * probably end up in bn_asm.c as soon as there are assembler counterparts
-+ * for the systems that use assembler files.
-+ */
-+
-+BN_ULONG bn_sub_part_words(BN_ULONG *r,
-+                           const BN_ULONG *a, const BN_ULONG *b,
-+                           int cl, int dl)
-+{
-+    BN_ULONG c, t;
-+
-+    assert(cl >= 0);
-+    c = bn_sub_words(r, a, b, cl);
-+
-+    if (dl == 0)
-+        return c;
-+
-+    r += cl;
-+    a += cl;
-+    b += cl;
-+
-+    if (dl < 0) {
-+        for (;;) {
-+            t = b[0];
-+            r[0] = (0 - t - c) & BN_MASK2;
-+            if (t != 0)
-+                c = 1;
-+            if (++dl >= 0)
-+                break;
-+
-+            t = b[1];
-+            r[1] = (0 - t - c) & BN_MASK2;
-+            if (t != 0)
-+                c = 1;
-+            if (++dl >= 0)
-+                break;
-+
-+            t = b[2];
-+            r[2] = (0 - t - c) & BN_MASK2;
-+            if (t != 0)
-+                c = 1;
-+            if (++dl >= 0)
-+                break;
-+
-+            t = b[3];
-+            r[3] = (0 - t - c) & BN_MASK2;
-+            if (t != 0)
-+                c = 1;
-+            if (++dl >= 0)
-+                break;
-+
-+            b += 4;
-+            r += 4;
-+        }
-+    } else {
-+        int save_dl = dl;
-+        while (c) {
-+            t = a[0];
-+            r[0] = (t - c) & BN_MASK2;
-+            if (t != 0)
-+                c = 0;
-+            if (--dl <= 0)
-+                break;
-+
-+            t = a[1];
-+            r[1] = (t - c) & BN_MASK2;
-+            if (t != 0)
-+                c = 0;
-+            if (--dl <= 0)
-+                break;
-+
-+            t = a[2];
-+            r[2] = (t - c) & BN_MASK2;
-+            if (t != 0)
-+                c = 0;
-+            if (--dl <= 0)
-+                break;
-+
-+            t = a[3];
-+            r[3] = (t - c) & BN_MASK2;
-+            if (t != 0)
-+                c = 0;
-+            if (--dl <= 0)
-+                break;
-+
-+            save_dl = dl;
-+            a += 4;
-+            r += 4;
-+        }
-+        if (dl > 0) {
-+            if (save_dl > dl) {
-+                switch (save_dl - dl) {
-+                case 1:
-+                    r[1] = a[1];
-+                    if (--dl <= 0)
-+                        break;
-+                case 2:
-+                    r[2] = a[2];
-+                    if (--dl <= 0)
-+                        break;
-+                case 3:
-+                    r[3] = a[3];
-+                    if (--dl <= 0)
-+                        break;
-+                }
-+                a += 4;
-+                r += 4;
-+            }
-+        }
-+        if (dl > 0) {
-+            for (;;) {
-+                r[0] = a[0];
-+                if (--dl <= 0)
-+                    break;
-+                r[1] = a[1];
-+                if (--dl <= 0)
-+                    break;
-+                r[2] = a[2];
-+                if (--dl <= 0)
-+                    break;
-+                r[3] = a[3];
-+                if (--dl <= 0)
-+                    break;
-+
-+                a += 4;
-+                r += 4;
-+            }
-+        }
-+    }
-+    return c;
-+}
-+#endif
-+
-+BN_ULONG bn_add_part_words(BN_ULONG *r,
-+                           const BN_ULONG *a, const BN_ULONG *b,
-+                           int cl, int dl)
-+{
-+    BN_ULONG c, l, t;
-+
-+    assert(cl >= 0);
-+    c = bn_add_words(r, a, b, cl);
-+
-+    if (dl == 0)
-+        return c;
-+
-+    r += cl;
-+    a += cl;
-+    b += cl;
-+
-+    if (dl < 0) {
-+        int save_dl = dl;
-+        while (c) {
-+            l = (c + b[0]) & BN_MASK2;
-+            c = (l < c);
-+            r[0] = l;
-+            if (++dl >= 0)
-+                break;
-+
-+            l = (c + b[1]) & BN_MASK2;
-+            c = (l < c);
-+            r[1] = l;
-+            if (++dl >= 0)
-+                break;
-+
-+            l = (c + b[2]) & BN_MASK2;
-+            c = (l < c);
-+            r[2] = l;
-+            if (++dl >= 0)
-+                break;
-+
-+            l = (c + b[3]) & BN_MASK2;
-+            c = (l < c);
-+            r[3] = l;
-+            if (++dl >= 0)
-+                break;
-+
-+            save_dl = dl;
-+            b += 4;
-+            r += 4;
-+        }
-+        if (dl < 0) {
-+            if (save_dl < dl) {
-+                switch (dl - save_dl) {
-+                case 1:
-+                    r[1] = b[1];
-+                    if (++dl >= 0)
-+                        break;
-+                case 2:
-+                    r[2] = b[2];
-+                    if (++dl >= 0)
-+                        break;
-+                case 3:
-+                    r[3] = b[3];
-+                    if (++dl >= 0)
-+                        break;
-+                }
-+                b += 4;
-+                r += 4;
-+            }
-+        }
-+        if (dl < 0) {
-+            for (;;) {
-+                r[0] = b[0];
-+                if (++dl >= 0)
-+                    break;
-+                r[1] = b[1];
-+                if (++dl >= 0)
-+                    break;
-+                r[2] = b[2];
-+                if (++dl >= 0)
-+                    break;
-+                r[3] = b[3];
-+                if (++dl >= 0)
-+                    break;
-+
-+                b += 4;
-+                r += 4;
-+            }
-+        }
-+    } else {
-+        int save_dl = dl;
-+        while (c) {
-+            t = (a[0] + c) & BN_MASK2;
-+            c = (t < c);
-+            r[0] = t;
-+            if (--dl <= 0)
-+                break;
-+
-+            t = (a[1] + c) & BN_MASK2;
-+            c = (t < c);
-+            r[1] = t;
-+            if (--dl <= 0)
-+                break;
-+
-+            t = (a[2] + c) & BN_MASK2;
-+            c = (t < c);
-+            r[2] = t;
-+            if (--dl <= 0)
-+                break;
-+
-+            t = (a[3] + c) & BN_MASK2;
-+            c = (t < c);
-+            r[3] = t;
-+            if (--dl <= 0)
-+                break;
-+
-+            save_dl = dl;
-+            a += 4;
-+            r += 4;
-+        }
-+        if (dl > 0) {
-+            if (save_dl > dl) {
-+                switch (save_dl - dl) {
-+                case 1:
-+                    r[1] = a[1];
-+                    if (--dl <= 0)
-+                        break;
-+                case 2:
-+                    r[2] = a[2];
-+                    if (--dl <= 0)
-+                        break;
-+                case 3:
-+                    r[3] = a[3];
-+                    if (--dl <= 0)
-+                        break;
-+                }
-+                a += 4;
-+                r += 4;
-+            }
-+        }
-+        if (dl > 0) {
-+            for (;;) {
-+                r[0] = a[0];
-+                if (--dl <= 0)
-+                    break;
-+                r[1] = a[1];
-+                if (--dl <= 0)
-+                    break;
-+                r[2] = a[2];
-+                if (--dl <= 0)
-+                    break;
-+                r[3] = a[3];
-+                if (--dl <= 0)
-+                    break;
-+
-+                a += 4;
-+                r += 4;
-+            }
-+        }
-+    }
-+    return c;
-+}
-+
-+#ifdef BN_RECURSION
-+/*
-+ * Karatsuba recursive multiplication algorithm (cf. Knuth, The Art of
-+ * Computer Programming, Vol. 2)
-+ */
-+
-+/*-
-+ * r is 2*n2 words in size,
-+ * a and b are both n2 words in size.
-+ * n2 must be a power of 2.
-+ * We multiply and return the result.
-+ * t must be 2*n2 words in size
-+ * We calculate
-+ * a[0]*b[0]
-+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
-+ * a[1]*b[1]
-+ */
-+/* dnX may not be positive, but n2/2+dnX has to be */
-+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
-+                      int dna, int dnb, BN_ULONG *t)
-+{
-+    int n = n2 / 2, c1, c2;
-+    int tna = n + dna, tnb = n + dnb;
-+    unsigned int neg, zero;
-+    BN_ULONG ln, lo, *p;
-+
-+# ifdef BN_MUL_COMBA
-+#  if 0
-+    if (n2 == 4) {
-+        bn_mul_comba4(r, a, b);
-+        return;
-+    }
-+#  endif
-+    /*
-+     * Only call bn_mul_comba 8 if n2 == 8 and the two arrays are complete
-+     * [steve]
-+     */
-+    if (n2 == 8 && dna == 0 && dnb == 0) {
-+        bn_mul_comba8(r, a, b);
-+        return;
-+    }
-+# endif                         /* BN_MUL_COMBA */
-+    /* Else do normal multiply */
-+    if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
-+        bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
-+        if ((dna + dnb) < 0)
-+            memset(&r[2 * n2 + dna + dnb], 0,
-+                   sizeof(BN_ULONG) * -(dna + dnb));
-+        return;
-+    }
-+    /* r=(a[0]-a[1])*(b[1]-b[0]) */
-+    c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
-+    c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
-+    zero = neg = 0;
-+    switch (c1 * 3 + c2) {
-+    case -4:
-+        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
-+        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
-+        break;
-+    case -3:
-+        zero = 1;
-+        break;
-+    case -2:
-+        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
-+        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
-+        neg = 1;
-+        break;
-+    case -1:
-+    case 0:
-+    case 1:
-+        zero = 1;
-+        break;
-+    case 2:
-+        bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
-+        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
-+        neg = 1;
-+        break;
-+    case 3:
-+        zero = 1;
-+        break;
-+    case 4:
-+        bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
-+        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
-+        break;
-+    }
-+
-+# ifdef BN_MUL_COMBA
-+    if (n == 4 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba4 could take
-+                                           * extra args to do this well */
-+        if (!zero)
-+            bn_mul_comba4(&(t[n2]), t, &(t[n]));
-+        else
-+            memset(&t[n2], 0, sizeof(*t) * 8);
-+
-+        bn_mul_comba4(r, a, b);
-+        bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n]));
-+    } else if (n == 8 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba8 could
-+                                                  * take extra args to do
-+                                                  * this well */
-+        if (!zero)
-+            bn_mul_comba8(&(t[n2]), t, &(t[n]));
-+        else
-+            memset(&t[n2], 0, sizeof(*t) * 16);
-+
-+        bn_mul_comba8(r, a, b);
-+        bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n]));
-+    } else
-+# endif                         /* BN_MUL_COMBA */
-+    {
-+        p = &(t[n2 * 2]);
-+        if (!zero)
-+            bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
-+        else
-+            memset(&t[n2], 0, sizeof(*t) * n2);
-+        bn_mul_recursive(r, a, b, n, 0, 0, p);
-+        bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p);
-+    }
-+
-+    /*-
-+     * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
-+     * r[10] holds (a[0]*b[0])
-+     * r[32] holds (b[1]*b[1])
-+     */
-+
-+    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
-+
-+    if (neg) {                  /* if t[32] is negative */
-+        c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
-+    } else {
-+        /* Might have a carry */
-+        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
-+    }
-+
-+    /*-
-+     * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
-+     * r[10] holds (a[0]*b[0])
-+     * r[32] holds (b[1]*b[1])
-+     * c1 holds the carry bits
-+     */
-+    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
-+    if (c1) {
-+        p = &(r[n + n2]);
-+        lo = *p;
-+        ln = (lo + c1) & BN_MASK2;
-+        *p = ln;
-+
-+        /*
-+         * The overflow will stop before we over write words we should not
-+         * overwrite
-+         */
-+        if (ln < (BN_ULONG)c1) {
-+            do {
-+                p++;
-+                lo = *p;
-+                ln = (lo + 1) & BN_MASK2;
-+                *p = ln;
-+            } while (ln == 0);
-+        }
-+    }
-+}
-+
-+/*
-+ * n+tn is the word length t needs to be n*4 is size, as does r
-+ */
-+/* tnX may not be negative but less than n */
-+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
-+                           int tna, int tnb, BN_ULONG *t)
-+{
-+    int i, j, n2 = n * 2;
-+    int c1, c2, neg;
-+    BN_ULONG ln, lo, *p;
-+
-+    if (n < 8) {
-+        bn_mul_normal(r, a, n + tna, b, n + tnb);
-+        return;
-+    }
-+
-+    /* r=(a[0]-a[1])*(b[1]-b[0]) */
-+    c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
-+    c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
-+    neg = 0;
-+    switch (c1 * 3 + c2) {
-+    case -4:
-+        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
-+        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
-+        break;
-+    case -3:
-+        /* break; */
-+    case -2:
-+        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
-+        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
-+        neg = 1;
-+        break;
-+    case -1:
-+    case 0:
-+    case 1:
-+        /* break; */
-+    case 2:
-+        bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
-+        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
-+        neg = 1;
-+        break;
-+    case 3:
-+        /* break; */
-+    case 4:
-+        bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
-+        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
-+        break;
-+    }
-+    /*
-+     * The zero case isn't yet implemented here. The speedup would probably
-+     * be negligible.
-+     */
-+# if 0
-+    if (n == 4) {
-+        bn_mul_comba4(&(t[n2]), t, &(t[n]));
-+        bn_mul_comba4(r, a, b);
-+        bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn);
-+        memset(&r[n2 + tn * 2], 0, sizeof(*r) * (n2 - tn * 2));
-+    } else
-+# endif
-+    if (n == 8) {
-+        bn_mul_comba8(&(t[n2]), t, &(t[n]));
-+        bn_mul_comba8(r, a, b);
-+        bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
-+        memset(&r[n2 + tna + tnb], 0, sizeof(*r) * (n2 - tna - tnb));
-+    } else {
-+        p = &(t[n2 * 2]);
-+        bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
-+        bn_mul_recursive(r, a, b, n, 0, 0, p);
-+        i = n / 2;
-+        /*
-+         * If there is only a bottom half to the number, just do it
-+         */
-+        if (tna > tnb)
-+            j = tna - i;
-+        else
-+            j = tnb - i;
-+        if (j == 0) {
-+            bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]),
-+                             i, tna - i, tnb - i, p);
-+            memset(&r[n2 + i * 2], 0, sizeof(*r) * (n2 - i * 2));
-+        } else if (j > 0) {     /* eg, n == 16, i == 8 and tn == 11 */
-+            bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]),
-+                                  i, tna - i, tnb - i, p);
-+            memset(&(r[n2 + tna + tnb]), 0,
-+                   sizeof(BN_ULONG) * (n2 - tna - tnb));
-+        } else {                /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
-+
-+            memset(&r[n2], 0, sizeof(*r) * n2);
-+            if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
-+                && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
-+                bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
-+            } else {
-+                for (;;) {
-+                    i /= 2;
-+                    /*
-+                     * these simplified conditions work exclusively because
-+                     * difference between tna and tnb is 1 or 0
-+                     */
-+                    if (i < tna || i < tnb) {
-+                        bn_mul_part_recursive(&(r[n2]),
-+                                              &(a[n]), &(b[n]),
-+                                              i, tna - i, tnb - i, p);
-+                        break;
-+                    } else if (i == tna || i == tnb) {
-+                        bn_mul_recursive(&(r[n2]),
-+                                         &(a[n]), &(b[n]),
-+                                         i, tna - i, tnb - i, p);
-+                        break;
-+                    }
-+                }
-+            }
-+        }
-+    }
-+
-+    /*-
-+     * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
-+     * r[10] holds (a[0]*b[0])
-+     * r[32] holds (b[1]*b[1])
-+     */
-+
-+    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
-+
-+    if (neg) {                  /* if t[32] is negative */
-+        c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
-+    } else {
-+        /* Might have a carry */
-+        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
-+    }
-+
-+    /*-
-+     * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
-+     * r[10] holds (a[0]*b[0])
-+     * r[32] holds (b[1]*b[1])
-+     * c1 holds the carry bits
-+     */
-+    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
-+    if (c1) {
-+        p = &(r[n + n2]);
-+        lo = *p;
-+        ln = (lo + c1) & BN_MASK2;
-+        *p = ln;
-+
-+        /*
-+         * The overflow will stop before we over write words we should not
-+         * overwrite
-+         */
-+        if (ln < (BN_ULONG)c1) {
-+            do {
-+                p++;
-+                lo = *p;
-+                ln = (lo + 1) & BN_MASK2;
-+                *p = ln;
-+            } while (ln == 0);
-+        }
-+    }
-+}
-+
-+/*-
-+ * a and b must be the same size, which is n2.
-+ * r needs to be n2 words and t needs to be n2*2
-+ */
-+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
-+                          BN_ULONG *t)
-+{
-+    int n = n2 / 2;
-+
-+    bn_mul_recursive(r, a, b, n, 0, 0, &(t[0]));
-+    if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) {
-+        bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2]));
-+        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
-+        bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2]));
-+        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
-+    } else {
-+        bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n);
-+        bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n);
-+        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
-+        bn_add_words(&(r[n]), &(r[n]), &(t[n]), n);
-+    }
-+}
-+
-+/*-
-+ * a and b must be the same size, which is n2.
-+ * r needs to be n2 words and t needs to be n2*2
-+ * l is the low words of the output.
-+ * t needs to be n2*3
-+ */
-+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
-+                 BN_ULONG *t)
-+{
-+    int i, n;
-+    int c1, c2;
-+    int neg, oneg, zero;
-+    BN_ULONG ll, lc, *lp, *mp;
-+
-+    n = n2 / 2;
-+
-+    /* Calculate (al-ah)*(bh-bl) */
-+    neg = zero = 0;
-+    c1 = bn_cmp_words(&(a[0]), &(a[n]), n);
-+    c2 = bn_cmp_words(&(b[n]), &(b[0]), n);
-+    switch (c1 * 3 + c2) {
-+    case -4:
-+        bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
-+        bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
-+        break;
-+    case -3:
-+        zero = 1;
-+        break;
-+    case -2:
-+        bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
-+        bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
-+        neg = 1;
-+        break;
-+    case -1:
-+    case 0:
-+    case 1:
-+        zero = 1;
-+        break;
-+    case 2:
-+        bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
-+        bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
-+        neg = 1;
-+        break;
-+    case 3:
-+        zero = 1;
-+        break;
-+    case 4:
-+        bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
-+        bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
-+        break;
-+    }
-+
-+    oneg = neg;
-+    /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
-+    /* r[10] = (a[1]*b[1]) */
-+# ifdef BN_MUL_COMBA
-+    if (n == 8) {
-+        bn_mul_comba8(&(t[0]), &(r[0]), &(r[n]));
-+        bn_mul_comba8(r, &(a[n]), &(b[n]));
-+    } else
-+# endif
-+    {
-+        bn_mul_recursive(&(t[0]), &(r[0]), &(r[n]), n, 0, 0, &(t[n2]));
-+        bn_mul_recursive(r, &(a[n]), &(b[n]), n, 0, 0, &(t[n2]));
-+    }
-+
-+    /*-
-+     * s0 == low(al*bl)
-+     * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
-+     * We know s0 and s1 so the only unknown is high(al*bl)
-+     * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
-+     * high(al*bl) == s1 - (r[0]+l[0]+t[0])
-+     */
-+    if (l != NULL) {
-+        lp = &(t[n2 + n]);
-+        bn_add_words(lp, &(r[0]), &(l[0]), n);
-+    } else {
-+        lp = &(r[0]);
-+    }
-+
-+    if (neg)
-+        neg = (int)(bn_sub_words(&(t[n2]), lp, &(t[0]), n));
-+    else {
-+        bn_add_words(&(t[n2]), lp, &(t[0]), n);
-+        neg = 0;
-+    }
-+
-+    if (l != NULL) {
-+        bn_sub_words(&(t[n2 + n]), &(l[n]), &(t[n2]), n);
-+    } else {
-+        lp = &(t[n2 + n]);
-+        mp = &(t[n2]);
-+        for (i = 0; i < n; i++)
-+            lp[i] = ((~mp[i]) + 1) & BN_MASK2;
-+    }
-+
-+    /*-
-+     * s[0] = low(al*bl)
-+     * t[3] = high(al*bl)
-+     * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
-+     * r[10] = (a[1]*b[1])
-+     */
-+    /*-
-+     * R[10] = al*bl
-+     * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
-+     * R[32] = ah*bh
-+     */
-+    /*-
-+     * R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
-+     * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
-+     * R[3]=r[1]+(carry/borrow)
-+     */
-+    if (l != NULL) {
-+        lp = &(t[n2]);
-+        c1 = (int)(bn_add_words(lp, &(t[n2 + n]), &(l[0]), n));
-+    } else {
-+        lp = &(t[n2 + n]);
-+        c1 = 0;
-+    }
-+    c1 += (int)(bn_add_words(&(t[n2]), lp, &(r[0]), n));
-+    if (oneg)
-+        c1 -= (int)(bn_sub_words(&(t[n2]), &(t[n2]), &(t[0]), n));
-+    else
-+        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), &(t[0]), n));
-+
-+    c2 = (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n2 + n]), n));
-+    c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(r[n]), n));
-+    if (oneg)
-+        c2 -= (int)(bn_sub_words(&(r[0]), &(r[0]), &(t[n]), n));
-+    else
-+        c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n]), n));
-+
-+    if (c1 != 0) {              /* Add starting at r[0], could be +ve or -ve */
-+        i = 0;
-+        if (c1 > 0) {
-+            lc = c1;
-+            do {
-+                ll = (r[i] + lc) & BN_MASK2;
-+                r[i++] = ll;
-+                lc = (lc > ll);
-+            } while (lc);
-+        } else {
-+            lc = -c1;
-+            do {
-+                ll = r[i];
-+                r[i++] = (ll - lc) & BN_MASK2;
-+                lc = (lc > ll);
-+            } while (lc);
-+        }
-+    }
-+    if (c2 != 0) {              /* Add starting at r[1] */
-+        i = n;
-+        if (c2 > 0) {
-+            lc = c2;
-+            do {
-+                ll = (r[i] + lc) & BN_MASK2;
-+                r[i++] = ll;
-+                lc = (lc > ll);
-+            } while (lc);
-+        } else {
-+            lc = -c2;
-+            do {
-+                ll = r[i];
-+                r[i++] = (ll - lc) & BN_MASK2;
-+                lc = (lc > ll);
-+            } while (lc);
-+        }
-+    }
-+}
-+#endif                          /* BN_RECURSION */
-+
-+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    int top, al, bl;
-+    BIGNUM *rr;
-+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
-+    int i;
-+#endif
-+#ifdef BN_RECURSION
-+    BIGNUM *t = NULL;
-+    int j = 0, k;
-+#endif
-+
-+    bn_check_top(a);
-+    bn_check_top(b);
-+    bn_check_top(r);
-+
-+    al = a->top;
-+    bl = b->top;
-+
-+    if ((al == 0) || (bl == 0)) {
-+        BN_zero(r);
-+        return (1);
-+    }
-+    top = al + bl;
-+
-+    BN_CTX_start(ctx);
-+    if ((r == a) || (r == b)) {
-+        if ((rr = BN_CTX_get(ctx)) == NULL)
-+            goto err;
-+    } else
-+        rr = r;
-+
-+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
-+    i = al - bl;
-+#endif
-+#ifdef BN_MUL_COMBA
-+    if (i == 0) {
-+# if 0
-+        if (al == 4) {
-+            if (bn_wexpand(rr, 8) == NULL)
-+                goto err;
-+            rr->top = 8;
-+            bn_mul_comba4(rr->d, a->d, b->d);
-+            goto end;
-+        }
-+# endif
-+        if (al == 8) {
-+            if (bn_wexpand(rr, 16) == NULL)
-+                goto err;
-+            rr->top = 16;
-+            bn_mul_comba8(rr->d, a->d, b->d);
-+            goto end;
-+        }
-+    }
-+#endif                          /* BN_MUL_COMBA */
-+#ifdef BN_RECURSION
-+    if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
-+        if (i >= -1 && i <= 1) {
-+            /*
-+             * Find out the power of two lower or equal to the longest of the
-+             * two numbers
-+             */
-+            if (i >= 0) {
-+                j = BN_num_bits_word((BN_ULONG)al);
-+            }
-+            if (i == -1) {
-+                j = BN_num_bits_word((BN_ULONG)bl);
-+            }
-+            j = 1 << (j - 1);
-+            assert(j <= al || j <= bl);
-+            k = j + j;
-+            t = BN_CTX_get(ctx);
-+            if (t == NULL)
-+                goto err;
-+            if (al > j || bl > j) {
-+                if (bn_wexpand(t, k * 4) == NULL)
-+                    goto err;
-+                if (bn_wexpand(rr, k * 4) == NULL)
-+                    goto err;
-+                bn_mul_part_recursive(rr->d, a->d, b->d,
-+                                      j, al - j, bl - j, t->d);
-+            } else {            /* al <= j || bl <= j */
-+
-+                if (bn_wexpand(t, k * 2) == NULL)
-+                    goto err;
-+                if (bn_wexpand(rr, k * 2) == NULL)
-+                    goto err;
-+                bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
-+            }
-+            rr->top = top;
-+            goto end;
-+        }
-+# if 0
-+        if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) {
-+            BIGNUM *tmp_bn = (BIGNUM *)b;
-+            if (bn_wexpand(tmp_bn, al) == NULL)
-+                goto err;
-+            tmp_bn->d[bl] = 0;
-+            bl++;
-+            i--;
-+        } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) {
-+            BIGNUM *tmp_bn = (BIGNUM *)a;
-+            if (bn_wexpand(tmp_bn, bl) == NULL)
-+                goto err;
-+            tmp_bn->d[al] = 0;
-+            al++;
-+            i++;
-+        }
-+        if (i == 0) {
-+            /* symmetric and > 4 */
-+            /* 16 or larger */
-+            j = BN_num_bits_word((BN_ULONG)al);
-+            j = 1 << (j - 1);
-+            k = j + j;
-+            t = BN_CTX_get(ctx);
-+            if (al == j) {      /* exact multiple */
-+                if (bn_wexpand(t, k * 2) == NULL)
-+                    goto err;
-+                if (bn_wexpand(rr, k * 2) == NULL)
-+                    goto err;
-+                bn_mul_recursive(rr->d, a->d, b->d, al, t->d);
-+            } else {
-+                if (bn_wexpand(t, k * 4) == NULL)
-+                    goto err;
-+                if (bn_wexpand(rr, k * 4) == NULL)
-+                    goto err;
-+                bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d);
-+            }
-+            rr->top = top;
-+            goto end;
-+        }
-+# endif
-+    }
-+#endif                          /* BN_RECURSION */
-+    if (bn_wexpand(rr, top) == NULL)
-+        goto err;
-+    rr->top = top;
-+    bn_mul_normal(rr->d, a->d, al, b->d, bl);
-+
-+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
-+ end:
-+#endif
-+    rr->neg = a->neg ^ b->neg;
-+    bn_correct_top(rr);
-+    if (r != rr && BN_copy(r, rr) == NULL)
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    bn_check_top(r);
-+    BN_CTX_end(ctx);
-+    return (ret);
-+}
-+
-+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
-+{
-+    BN_ULONG *rr;
-+
-+    if (na < nb) {
-+        int itmp;
-+        BN_ULONG *ltmp;
-+
-+        itmp = na;
-+        na = nb;
-+        nb = itmp;
-+        ltmp = a;
-+        a = b;
-+        b = ltmp;
-+
-+    }
-+    rr = &(r[na]);
-+    if (nb <= 0) {
-+        (void)bn_mul_words(r, a, na, 0);
-+        return;
-+    } else
-+        rr[0] = bn_mul_words(r, a, na, b[0]);
-+
-+    for (;;) {
-+        if (--nb <= 0)
-+            return;
-+        rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]);
-+        if (--nb <= 0)
-+            return;
-+        rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]);
-+        if (--nb <= 0)
-+            return;
-+        rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]);
-+        if (--nb <= 0)
-+            return;
-+        rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]);
-+        rr += 4;
-+        r += 4;
-+        b += 4;
-+    }
-+}
-+
-+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
-+{
-+    bn_mul_words(r, a, n, b[0]);
-+
-+    for (;;) {
-+        if (--n <= 0)
-+            return;
-+        bn_mul_add_words(&(r[1]), a, n, b[1]);
-+        if (--n <= 0)
-+            return;
-+        bn_mul_add_words(&(r[2]), a, n, b[2]);
-+        if (--n <= 0)
-+            return;
-+        bn_mul_add_words(&(r[3]), a, n, b[3]);
-+        if (--n <= 0)
-+            return;
-+        bn_mul_add_words(&(r[4]), a, n, b[4]);
-+        r += 4;
-+        b += 4;
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_nist.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_nist.c
-new file mode 100644
-index 0000000..53598f9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_nist.c
-@@ -0,0 +1,1239 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "bn_lcl.h"
-+#include "internal/cryptlib.h"
-+
-+#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2
-+#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2
-+#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2
-+#define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2
-+#define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2
-+
-+/* pre-computed tables are "carry-less" values of modulus*(i+1) */
-+#if BN_BITS2 == 64
-+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
-+    {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL},
-+    {0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL},
-+    {0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL}
-+};
-+
-+static const BN_ULONG _nist_p_192_sqr[] = {
-+    0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000001ULL,
-+    0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL
-+};
-+
-+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
-+    {0x0000000000000001ULL, 0xFFFFFFFF00000000ULL,
-+     0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL},
-+    {0x0000000000000002ULL, 0xFFFFFFFE00000000ULL,
-+     0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFFULL} /* this one is
-+                                                    * "carry-full" */
-+};
-+
-+static const BN_ULONG _nist_p_224_sqr[] = {
-+    0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
-+    0xFFFFFFFFFFFFFFFFULL, 0x0000000200000000ULL,
-+    0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFEULL,
-+    0xFFFFFFFFFFFFFFFFULL
-+};
-+
-+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
-+    {0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL,
-+     0x0000000000000000ULL, 0xFFFFFFFF00000001ULL},
-+    {0xFFFFFFFFFFFFFFFEULL, 0x00000001FFFFFFFFULL,
-+     0x0000000000000000ULL, 0xFFFFFFFE00000002ULL},
-+    {0xFFFFFFFFFFFFFFFDULL, 0x00000002FFFFFFFFULL,
-+     0x0000000000000000ULL, 0xFFFFFFFD00000003ULL},
-+    {0xFFFFFFFFFFFFFFFCULL, 0x00000003FFFFFFFFULL,
-+     0x0000000000000000ULL, 0xFFFFFFFC00000004ULL},
-+    {0xFFFFFFFFFFFFFFFBULL, 0x00000004FFFFFFFFULL,
-+     0x0000000000000000ULL, 0xFFFFFFFB00000005ULL},
-+};
-+
-+static const BN_ULONG _nist_p_256_sqr[] = {
-+    0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
-+    0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFEULL,
-+    0x00000001FFFFFFFEULL, 0x00000001FFFFFFFEULL,
-+    0xFFFFFFFE00000001ULL, 0xFFFFFFFE00000002ULL
-+};
-+
-+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
-+    {0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL, 0xFFFFFFFFFFFFFFFEULL,
-+     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
-+    {0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
-+     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
-+    {0x00000002FFFFFFFDULL, 0xFFFFFFFD00000000ULL, 0xFFFFFFFFFFFFFFFCULL,
-+     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
-+    {0x00000003FFFFFFFCULL, 0xFFFFFFFC00000000ULL, 0xFFFFFFFFFFFFFFFBULL,
-+     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
-+    {0x00000004FFFFFFFBULL, 0xFFFFFFFB00000000ULL, 0xFFFFFFFFFFFFFFFAULL,
-+     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
-+};
-+
-+static const BN_ULONG _nist_p_384_sqr[] = {
-+    0xFFFFFFFE00000001ULL, 0x0000000200000000ULL, 0xFFFFFFFE00000000ULL,
-+    0x0000000200000000ULL, 0x0000000000000001ULL, 0x0000000000000000ULL,
-+    0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
-+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
-+};
-+
-+static const BN_ULONG _nist_p_521[] =
-+    { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
-+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
-+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
-+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
-+    0x00000000000001FFULL
-+};
-+
-+static const BN_ULONG _nist_p_521_sqr[] = {
-+    0x0000000000000001ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
-+    0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
-+    0x0000000000000000ULL, 0x0000000000000000ULL, 0xFFFFFFFFFFFFFC00ULL,
-+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
-+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
-+    0xFFFFFFFFFFFFFFFFULL, 0x000000000003FFFFULL
-+};
-+#elif BN_BITS2 == 32
-+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
-+    {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
-+    {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
-+    {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
-+};
-+
-+static const BN_ULONG _nist_p_192_sqr[] = {
-+    0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
-+    0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
-+};
-+
-+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
-+    {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF,
-+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
-+    {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE,
-+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
-+};
-+
-+static const BN_ULONG _nist_p_224_sqr[] = {
-+    0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
-+    0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002,
-+    0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
-+    0xFFFFFFFF, 0xFFFFFFFF
-+};
-+
-+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
-+    {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
-+     0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
-+    {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001,
-+     0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE},
-+    {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002,
-+     0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD},
-+    {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
-+     0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC},
-+    {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004,
-+     0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB},
-+};
-+
-+static const BN_ULONG _nist_p_256_sqr[] = {
-+    0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
-+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001,
-+    0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001,
-+    0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE
-+};
-+
-+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
-+    {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
-+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
-+    {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
-+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
-+    {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF,
-+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
-+    {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF,
-+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
-+    {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF,
-+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
-+};
-+
-+static const BN_ULONG _nist_p_384_sqr[] = {
-+    0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
-+    0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
-+    0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
-+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
-+};
-+
-+static const BN_ULONG _nist_p_521[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-+    0xFFFFFFFF, 0x000001FF
-+};
-+
-+static const BN_ULONG _nist_p_521_sqr[] = {
-+    0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF,
-+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-+    0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF
-+};
-+#else
-+# error "unsupported BN_BITS2"
-+#endif
-+
-+static const BIGNUM _bignum_nist_p_192 = {
-+    (BN_ULONG *)_nist_p_192[0],
-+    BN_NIST_192_TOP,
-+    BN_NIST_192_TOP,
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BIGNUM _bignum_nist_p_224 = {
-+    (BN_ULONG *)_nist_p_224[0],
-+    BN_NIST_224_TOP,
-+    BN_NIST_224_TOP,
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BIGNUM _bignum_nist_p_256 = {
-+    (BN_ULONG *)_nist_p_256[0],
-+    BN_NIST_256_TOP,
-+    BN_NIST_256_TOP,
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BIGNUM _bignum_nist_p_384 = {
-+    (BN_ULONG *)_nist_p_384[0],
-+    BN_NIST_384_TOP,
-+    BN_NIST_384_TOP,
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BIGNUM _bignum_nist_p_521 = {
-+    (BN_ULONG *)_nist_p_521,
-+    BN_NIST_521_TOP,
-+    BN_NIST_521_TOP,
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+const BIGNUM *BN_get0_nist_prime_192(void)
-+{
-+    return &_bignum_nist_p_192;
-+}
-+
-+const BIGNUM *BN_get0_nist_prime_224(void)
-+{
-+    return &_bignum_nist_p_224;
-+}
-+
-+const BIGNUM *BN_get0_nist_prime_256(void)
-+{
-+    return &_bignum_nist_p_256;
-+}
-+
-+const BIGNUM *BN_get0_nist_prime_384(void)
-+{
-+    return &_bignum_nist_p_384;
-+}
-+
-+const BIGNUM *BN_get0_nist_prime_521(void)
-+{
-+    return &_bignum_nist_p_521;
-+}
-+
-+static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max)
-+{
-+    int i;
-+
-+#ifdef BN_DEBUG
-+    OPENSSL_assert(top <= max);
-+#endif
-+    for (i = 0; i < top; i++)
-+        dst[i] = src[i];
-+    for (; i < max; i++)
-+        dst[i] = 0;
-+}
-+
-+static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top)
-+{
-+    int i;
-+
-+    for (i = 0; i < top; i++)
-+        dst[i] = src[i];
-+}
-+
-+#if BN_BITS2 == 64
-+# define bn_cp_64(to, n, from, m)        (to)[n] = (m>=0)?((from)[m]):0;
-+# define bn_64_set_0(to, n)              (to)[n] = (BN_ULONG)0;
-+/*
-+ * two following macros are implemented under assumption that they
-+ * are called in a sequence with *ascending* n, i.e. as they are...
-+ */
-+# define bn_cp_32_naked(to, n, from, m)  (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\
-+                                                :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
-+# define bn_32_set_0(to, n)              (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
-+# define bn_cp_32(to,n,from,m)           ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
-+# if defined(L_ENDIAN)
-+#  if defined(__arch64__)
-+#   define NIST_INT64 long
-+#  else
-+#   define NIST_INT64 long long
-+#  endif
-+# endif
-+#else
-+# define bn_cp_64(to, n, from, m) \
-+        { \
-+        bn_cp_32(to, (n)*2, from, (m)*2); \
-+        bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
-+        }
-+# define bn_64_set_0(to, n) \
-+        { \
-+        bn_32_set_0(to, (n)*2); \
-+        bn_32_set_0(to, (n)*2+1); \
-+        }
-+# define bn_cp_32(to, n, from, m)        (to)[n] = (m>=0)?((from)[m]):0;
-+# define bn_32_set_0(to, n)              (to)[n] = (BN_ULONG)0;
-+# if defined(_WIN32) && !defined(__GNUC__)
-+#  define NIST_INT64 __int64
-+# elif defined(BN_LLONG)
-+#  define NIST_INT64 long long
-+# endif
-+#endif                          /* BN_BITS2 != 64 */
-+
-+#define nist_set_192(to, from, a1, a2, a3) \
-+        { \
-+        bn_cp_64(to, 0, from, (a3) - 3) \
-+        bn_cp_64(to, 1, from, (a2) - 3) \
-+        bn_cp_64(to, 2, from, (a1) - 3) \
-+        }
-+
-+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
-+                    BN_CTX *ctx)
-+{
-+    int top = a->top, i;
-+    int carry;
-+    register BN_ULONG *r_d, *a_d = a->d;
-+    union {
-+        BN_ULONG bn[BN_NIST_192_TOP];
-+        unsigned int ui[BN_NIST_192_TOP * sizeof(BN_ULONG) /
-+                        sizeof(unsigned int)];
-+    } buf;
-+    BN_ULONG c_d[BN_NIST_192_TOP], *res;
-+    PTR_SIZE_INT mask;
-+    static const BIGNUM _bignum_nist_p_192_sqr = {
-+        (BN_ULONG *)_nist_p_192_sqr,
-+        OSSL_NELEM(_nist_p_192_sqr),
-+        OSSL_NELEM(_nist_p_192_sqr),
-+        0, BN_FLG_STATIC_DATA
-+    };
-+
-+    field = &_bignum_nist_p_192; /* just to make sure */
-+
-+    if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_192_sqr) >= 0)
-+        return BN_nnmod(r, a, field, ctx);
-+
-+    i = BN_ucmp(field, a);
-+    if (i == 0) {
-+        BN_zero(r);
-+        return 1;
-+    } else if (i > 0)
-+        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
-+
-+    if (r != a) {
-+        if (!bn_wexpand(r, BN_NIST_192_TOP))
-+            return 0;
-+        r_d = r->d;
-+        nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
-+    } else
-+        r_d = a_d;
-+
-+    nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP,
-+                 BN_NIST_192_TOP);
-+
-+#if defined(NIST_INT64)
-+    {
-+        NIST_INT64 acc;         /* accumulator */
-+        unsigned int *rp = (unsigned int *)r_d;
-+        const unsigned int *bp = (const unsigned int *)buf.ui;
-+
-+        acc = rp[0];
-+        acc += bp[3 * 2 - 6];
-+        acc += bp[5 * 2 - 6];
-+        rp[0] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[1];
-+        acc += bp[3 * 2 - 5];
-+        acc += bp[5 * 2 - 5];
-+        rp[1] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[2];
-+        acc += bp[3 * 2 - 6];
-+        acc += bp[4 * 2 - 6];
-+        acc += bp[5 * 2 - 6];
-+        rp[2] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[3];
-+        acc += bp[3 * 2 - 5];
-+        acc += bp[4 * 2 - 5];
-+        acc += bp[5 * 2 - 5];
-+        rp[3] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[4];
-+        acc += bp[4 * 2 - 6];
-+        acc += bp[5 * 2 - 6];
-+        rp[4] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[5];
-+        acc += bp[4 * 2 - 5];
-+        acc += bp[5 * 2 - 5];
-+        rp[5] = (unsigned int)acc;
-+
-+        carry = (int)(acc >> 32);
-+    }
-+#else
-+    {
-+        BN_ULONG t_d[BN_NIST_192_TOP];
-+
-+        nist_set_192(t_d, buf.bn, 0, 3, 3);
-+        carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
-+        nist_set_192(t_d, buf.bn, 4, 4, 0);
-+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
-+        nist_set_192(t_d, buf.bn, 5, 5, 5)
-+            carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
-+    }
-+#endif
-+    if (carry > 0)
-+        carry =
-+            (int)bn_sub_words(r_d, r_d, _nist_p_192[carry - 1],
-+                              BN_NIST_192_TOP);
-+    else
-+        carry = 1;
-+
-+    /*
-+     * we need 'if (carry==0 || result>=modulus) result-=modulus;'
-+     * as comparison implies subtraction, we can write
-+     * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
-+     * this is what happens below, but without explicit if:-) a.
-+     */
-+    mask =
-+        0 - (PTR_SIZE_INT) bn_sub_words(c_d, r_d, _nist_p_192[0],
-+                                        BN_NIST_192_TOP);
-+    mask &= 0 - (PTR_SIZE_INT) carry;
-+    res = c_d;
-+    res = (BN_ULONG *)
-+        (((PTR_SIZE_INT) res & ~mask) | ((PTR_SIZE_INT) r_d & mask));
-+    nist_cp_bn(r_d, res, BN_NIST_192_TOP);
-+    r->top = BN_NIST_192_TOP;
-+    bn_correct_top(r);
-+
-+    return 1;
-+}
-+
-+typedef BN_ULONG (*bn_addsub_f) (BN_ULONG *, const BN_ULONG *,
-+                                 const BN_ULONG *, int);
-+
-+#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
-+        { \
-+        bn_cp_32(to, 0, from, (a7) - 7) \
-+        bn_cp_32(to, 1, from, (a6) - 7) \
-+        bn_cp_32(to, 2, from, (a5) - 7) \
-+        bn_cp_32(to, 3, from, (a4) - 7) \
-+        bn_cp_32(to, 4, from, (a3) - 7) \
-+        bn_cp_32(to, 5, from, (a2) - 7) \
-+        bn_cp_32(to, 6, from, (a1) - 7) \
-+        }
-+
-+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
-+                    BN_CTX *ctx)
-+{
-+    int top = a->top, i;
-+    int carry;
-+    BN_ULONG *r_d, *a_d = a->d;
-+    union {
-+        BN_ULONG bn[BN_NIST_224_TOP];
-+        unsigned int ui[BN_NIST_224_TOP * sizeof(BN_ULONG) /
-+                        sizeof(unsigned int)];
-+    } buf;
-+    BN_ULONG c_d[BN_NIST_224_TOP], *res;
-+    PTR_SIZE_INT mask;
-+    union {
-+        bn_addsub_f f;
-+        PTR_SIZE_INT p;
-+    } u;
-+    static const BIGNUM _bignum_nist_p_224_sqr = {
-+        (BN_ULONG *)_nist_p_224_sqr,
-+        OSSL_NELEM(_nist_p_224_sqr),
-+        OSSL_NELEM(_nist_p_224_sqr),
-+        0, BN_FLG_STATIC_DATA
-+    };
-+
-+    field = &_bignum_nist_p_224; /* just to make sure */
-+
-+    if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_224_sqr) >= 0)
-+        return BN_nnmod(r, a, field, ctx);
-+
-+    i = BN_ucmp(field, a);
-+    if (i == 0) {
-+        BN_zero(r);
-+        return 1;
-+    } else if (i > 0)
-+        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
-+
-+    if (r != a) {
-+        if (!bn_wexpand(r, BN_NIST_224_TOP))
-+            return 0;
-+        r_d = r->d;
-+        nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
-+    } else
-+        r_d = a_d;
-+
-+#if BN_BITS2==64
-+    /* copy upper 256 bits of 448 bit number ... */
-+    nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1),
-+                 top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP);
-+    /* ... and right shift by 32 to obtain upper 224 bits */
-+    nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8);
-+    /* truncate lower part to 224 bits too */
-+    r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l;
-+#else
-+    nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP,
-+                 BN_NIST_224_TOP);
-+#endif
-+
-+#if defined(NIST_INT64) && BN_BITS2!=64
-+    {
-+        NIST_INT64 acc;         /* accumulator */
-+        unsigned int *rp = (unsigned int *)r_d;
-+        const unsigned int *bp = (const unsigned int *)buf.ui;
-+
-+        acc = rp[0];
-+        acc -= bp[7 - 7];
-+        acc -= bp[11 - 7];
-+        rp[0] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[1];
-+        acc -= bp[8 - 7];
-+        acc -= bp[12 - 7];
-+        rp[1] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[2];
-+        acc -= bp[9 - 7];
-+        acc -= bp[13 - 7];
-+        rp[2] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[3];
-+        acc += bp[7 - 7];
-+        acc += bp[11 - 7];
-+        acc -= bp[10 - 7];
-+        rp[3] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[4];
-+        acc += bp[8 - 7];
-+        acc += bp[12 - 7];
-+        acc -= bp[11 - 7];
-+        rp[4] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[5];
-+        acc += bp[9 - 7];
-+        acc += bp[13 - 7];
-+        acc -= bp[12 - 7];
-+        rp[5] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[6];
-+        acc += bp[10 - 7];
-+        acc -= bp[13 - 7];
-+        rp[6] = (unsigned int)acc;
-+
-+        carry = (int)(acc >> 32);
-+# if BN_BITS2==64
-+        rp[7] = carry;
-+# endif
-+    }
-+#else
-+    {
-+        BN_ULONG t_d[BN_NIST_224_TOP];
-+
-+        nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0);
-+        carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
-+        nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0);
-+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
-+        nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7);
-+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
-+        nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11);
-+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
-+
-+# if BN_BITS2==64
-+        carry = (int)(r_d[BN_NIST_224_TOP - 1] >> 32);
-+# endif
-+    }
-+#endif
-+    u.f = bn_sub_words;
-+    if (carry > 0) {
-+        carry =
-+            (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1],
-+                              BN_NIST_224_TOP);
-+#if BN_BITS2==64
-+        carry = (int)(~(r_d[BN_NIST_224_TOP - 1] >> 32)) & 1;
-+#endif
-+    } else if (carry < 0) {
-+        /*
-+         * it's a bit more complicated logic in this case. if bn_add_words
-+         * yields no carry, then result has to be adjusted by unconditionally
-+         * *adding* the modulus. but if it does, then result has to be
-+         * compared to the modulus and conditionally adjusted by
-+         * *subtracting* the latter.
-+         */
-+        carry =
-+            (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1],
-+                              BN_NIST_224_TOP);
-+        mask = 0 - (PTR_SIZE_INT) carry;
-+        u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
-+            ((PTR_SIZE_INT) bn_add_words & ~mask);
-+    } else
-+        carry = 1;
-+
-+    /* otherwise it's effectively same as in BN_nist_mod_192... */
-+    mask =
-+        0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP);
-+    mask &= 0 - (PTR_SIZE_INT) carry;
-+    res = c_d;
-+    res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
-+                       ((PTR_SIZE_INT) r_d & mask));
-+    nist_cp_bn(r_d, res, BN_NIST_224_TOP);
-+    r->top = BN_NIST_224_TOP;
-+    bn_correct_top(r);
-+
-+    return 1;
-+}
-+
-+#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
-+        { \
-+        bn_cp_32(to, 0, from, (a8) - 8) \
-+        bn_cp_32(to, 1, from, (a7) - 8) \
-+        bn_cp_32(to, 2, from, (a6) - 8) \
-+        bn_cp_32(to, 3, from, (a5) - 8) \
-+        bn_cp_32(to, 4, from, (a4) - 8) \
-+        bn_cp_32(to, 5, from, (a3) - 8) \
-+        bn_cp_32(to, 6, from, (a2) - 8) \
-+        bn_cp_32(to, 7, from, (a1) - 8) \
-+        }
-+
-+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
-+                    BN_CTX *ctx)
-+{
-+    int i, top = a->top;
-+    int carry = 0;
-+    register BN_ULONG *a_d = a->d, *r_d;
-+    union {
-+        BN_ULONG bn[BN_NIST_256_TOP];
-+        unsigned int ui[BN_NIST_256_TOP * sizeof(BN_ULONG) /
-+                        sizeof(unsigned int)];
-+    } buf;
-+    BN_ULONG c_d[BN_NIST_256_TOP], *res;
-+    PTR_SIZE_INT mask;
-+    union {
-+        bn_addsub_f f;
-+        PTR_SIZE_INT p;
-+    } u;
-+    static const BIGNUM _bignum_nist_p_256_sqr = {
-+        (BN_ULONG *)_nist_p_256_sqr,
-+        OSSL_NELEM(_nist_p_256_sqr),
-+        OSSL_NELEM(_nist_p_256_sqr),
-+        0, BN_FLG_STATIC_DATA
-+    };
-+
-+    field = &_bignum_nist_p_256; /* just to make sure */
-+
-+    if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_256_sqr) >= 0)
-+        return BN_nnmod(r, a, field, ctx);
-+
-+    i = BN_ucmp(field, a);
-+    if (i == 0) {
-+        BN_zero(r);
-+        return 1;
-+    } else if (i > 0)
-+        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
-+
-+    if (r != a) {
-+        if (!bn_wexpand(r, BN_NIST_256_TOP))
-+            return 0;
-+        r_d = r->d;
-+        nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
-+    } else
-+        r_d = a_d;
-+
-+    nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP,
-+                 BN_NIST_256_TOP);
-+
-+#if defined(NIST_INT64)
-+    {
-+        NIST_INT64 acc;         /* accumulator */
-+        unsigned int *rp = (unsigned int *)r_d;
-+        const unsigned int *bp = (const unsigned int *)buf.ui;
-+
-+        acc = rp[0];
-+        acc += bp[8 - 8];
-+        acc += bp[9 - 8];
-+        acc -= bp[11 - 8];
-+        acc -= bp[12 - 8];
-+        acc -= bp[13 - 8];
-+        acc -= bp[14 - 8];
-+        rp[0] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[1];
-+        acc += bp[9 - 8];
-+        acc += bp[10 - 8];
-+        acc -= bp[12 - 8];
-+        acc -= bp[13 - 8];
-+        acc -= bp[14 - 8];
-+        acc -= bp[15 - 8];
-+        rp[1] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[2];
-+        acc += bp[10 - 8];
-+        acc += bp[11 - 8];
-+        acc -= bp[13 - 8];
-+        acc -= bp[14 - 8];
-+        acc -= bp[15 - 8];
-+        rp[2] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[3];
-+        acc += bp[11 - 8];
-+        acc += bp[11 - 8];
-+        acc += bp[12 - 8];
-+        acc += bp[12 - 8];
-+        acc += bp[13 - 8];
-+        acc -= bp[15 - 8];
-+        acc -= bp[8 - 8];
-+        acc -= bp[9 - 8];
-+        rp[3] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[4];
-+        acc += bp[12 - 8];
-+        acc += bp[12 - 8];
-+        acc += bp[13 - 8];
-+        acc += bp[13 - 8];
-+        acc += bp[14 - 8];
-+        acc -= bp[9 - 8];
-+        acc -= bp[10 - 8];
-+        rp[4] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[5];
-+        acc += bp[13 - 8];
-+        acc += bp[13 - 8];
-+        acc += bp[14 - 8];
-+        acc += bp[14 - 8];
-+        acc += bp[15 - 8];
-+        acc -= bp[10 - 8];
-+        acc -= bp[11 - 8];
-+        rp[5] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[6];
-+        acc += bp[14 - 8];
-+        acc += bp[14 - 8];
-+        acc += bp[15 - 8];
-+        acc += bp[15 - 8];
-+        acc += bp[14 - 8];
-+        acc += bp[13 - 8];
-+        acc -= bp[8 - 8];
-+        acc -= bp[9 - 8];
-+        rp[6] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[7];
-+        acc += bp[15 - 8];
-+        acc += bp[15 - 8];
-+        acc += bp[15 - 8];
-+        acc += bp[8 - 8];
-+        acc -= bp[10 - 8];
-+        acc -= bp[11 - 8];
-+        acc -= bp[12 - 8];
-+        acc -= bp[13 - 8];
-+        rp[7] = (unsigned int)acc;
-+
-+        carry = (int)(acc >> 32);
-+    }
-+#else
-+    {
-+        BN_ULONG t_d[BN_NIST_256_TOP];
-+
-+        /*
-+         * S1
-+         */
-+        nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0);
-+        /*
-+         * S2
-+         */
-+        nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0);
-+        carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
-+        /* left shift */
-+        {
-+            register BN_ULONG *ap, t, c;
-+            ap = t_d;
-+            c = 0;
-+            for (i = BN_NIST_256_TOP; i != 0; --i) {
-+                t = *ap;
-+                *(ap++) = ((t << 1) | c) & BN_MASK2;
-+                c = (t & BN_TBIT) ? 1 : 0;
-+            }
-+            carry <<= 1;
-+            carry |= c;
-+        }
-+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
-+        /*
-+         * S3
-+         */
-+        nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8);
-+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
-+        /*
-+         * S4
-+         */
-+        nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9);
-+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
-+        /*
-+         * D1
-+         */
-+        nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11);
-+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
-+        /*
-+         * D2
-+         */
-+        nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12);
-+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
-+        /*
-+         * D3
-+         */
-+        nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13);
-+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
-+        /*
-+         * D4
-+         */
-+        nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14);
-+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
-+
-+    }
-+#endif
-+    /* see BN_nist_mod_224 for explanation */
-+    u.f = bn_sub_words;
-+    if (carry > 0)
-+        carry =
-+            (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1],
-+                              BN_NIST_256_TOP);
-+    else if (carry < 0) {
-+        carry =
-+            (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1],
-+                              BN_NIST_256_TOP);
-+        mask = 0 - (PTR_SIZE_INT) carry;
-+        u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
-+            ((PTR_SIZE_INT) bn_add_words & ~mask);
-+    } else
-+        carry = 1;
-+
-+    mask =
-+        0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP);
-+    mask &= 0 - (PTR_SIZE_INT) carry;
-+    res = c_d;
-+    res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
-+                       ((PTR_SIZE_INT) r_d & mask));
-+    nist_cp_bn(r_d, res, BN_NIST_256_TOP);
-+    r->top = BN_NIST_256_TOP;
-+    bn_correct_top(r);
-+
-+    return 1;
-+}
-+
-+#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
-+        { \
-+        bn_cp_32(to, 0, from,  (a12) - 12) \
-+        bn_cp_32(to, 1, from,  (a11) - 12) \
-+        bn_cp_32(to, 2, from,  (a10) - 12) \
-+        bn_cp_32(to, 3, from,  (a9) - 12)  \
-+        bn_cp_32(to, 4, from,  (a8) - 12)  \
-+        bn_cp_32(to, 5, from,  (a7) - 12)  \
-+        bn_cp_32(to, 6, from,  (a6) - 12)  \
-+        bn_cp_32(to, 7, from,  (a5) - 12)  \
-+        bn_cp_32(to, 8, from,  (a4) - 12)  \
-+        bn_cp_32(to, 9, from,  (a3) - 12)  \
-+        bn_cp_32(to, 10, from, (a2) - 12)  \
-+        bn_cp_32(to, 11, from, (a1) - 12)  \
-+        }
-+
-+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
-+                    BN_CTX *ctx)
-+{
-+    int i, top = a->top;
-+    int carry = 0;
-+    register BN_ULONG *r_d, *a_d = a->d;
-+    union {
-+        BN_ULONG bn[BN_NIST_384_TOP];
-+        unsigned int ui[BN_NIST_384_TOP * sizeof(BN_ULONG) /
-+                        sizeof(unsigned int)];
-+    } buf;
-+    BN_ULONG c_d[BN_NIST_384_TOP], *res;
-+    PTR_SIZE_INT mask;
-+    union {
-+        bn_addsub_f f;
-+        PTR_SIZE_INT p;
-+    } u;
-+    static const BIGNUM _bignum_nist_p_384_sqr = {
-+        (BN_ULONG *)_nist_p_384_sqr,
-+        OSSL_NELEM(_nist_p_384_sqr),
-+        OSSL_NELEM(_nist_p_384_sqr),
-+        0, BN_FLG_STATIC_DATA
-+    };
-+
-+    field = &_bignum_nist_p_384; /* just to make sure */
-+
-+    if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_384_sqr) >= 0)
-+        return BN_nnmod(r, a, field, ctx);
-+
-+    i = BN_ucmp(field, a);
-+    if (i == 0) {
-+        BN_zero(r);
-+        return 1;
-+    } else if (i > 0)
-+        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
-+
-+    if (r != a) {
-+        if (!bn_wexpand(r, BN_NIST_384_TOP))
-+            return 0;
-+        r_d = r->d;
-+        nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
-+    } else
-+        r_d = a_d;
-+
-+    nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP,
-+                 BN_NIST_384_TOP);
-+
-+#if defined(NIST_INT64)
-+    {
-+        NIST_INT64 acc;         /* accumulator */
-+        unsigned int *rp = (unsigned int *)r_d;
-+        const unsigned int *bp = (const unsigned int *)buf.ui;
-+
-+        acc = rp[0];
-+        acc += bp[12 - 12];
-+        acc += bp[21 - 12];
-+        acc += bp[20 - 12];
-+        acc -= bp[23 - 12];
-+        rp[0] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[1];
-+        acc += bp[13 - 12];
-+        acc += bp[22 - 12];
-+        acc += bp[23 - 12];
-+        acc -= bp[12 - 12];
-+        acc -= bp[20 - 12];
-+        rp[1] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[2];
-+        acc += bp[14 - 12];
-+        acc += bp[23 - 12];
-+        acc -= bp[13 - 12];
-+        acc -= bp[21 - 12];
-+        rp[2] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[3];
-+        acc += bp[15 - 12];
-+        acc += bp[12 - 12];
-+        acc += bp[20 - 12];
-+        acc += bp[21 - 12];
-+        acc -= bp[14 - 12];
-+        acc -= bp[22 - 12];
-+        acc -= bp[23 - 12];
-+        rp[3] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[4];
-+        acc += bp[21 - 12];
-+        acc += bp[21 - 12];
-+        acc += bp[16 - 12];
-+        acc += bp[13 - 12];
-+        acc += bp[12 - 12];
-+        acc += bp[20 - 12];
-+        acc += bp[22 - 12];
-+        acc -= bp[15 - 12];
-+        acc -= bp[23 - 12];
-+        acc -= bp[23 - 12];
-+        rp[4] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[5];
-+        acc += bp[22 - 12];
-+        acc += bp[22 - 12];
-+        acc += bp[17 - 12];
-+        acc += bp[14 - 12];
-+        acc += bp[13 - 12];
-+        acc += bp[21 - 12];
-+        acc += bp[23 - 12];
-+        acc -= bp[16 - 12];
-+        rp[5] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[6];
-+        acc += bp[23 - 12];
-+        acc += bp[23 - 12];
-+        acc += bp[18 - 12];
-+        acc += bp[15 - 12];
-+        acc += bp[14 - 12];
-+        acc += bp[22 - 12];
-+        acc -= bp[17 - 12];
-+        rp[6] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[7];
-+        acc += bp[19 - 12];
-+        acc += bp[16 - 12];
-+        acc += bp[15 - 12];
-+        acc += bp[23 - 12];
-+        acc -= bp[18 - 12];
-+        rp[7] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[8];
-+        acc += bp[20 - 12];
-+        acc += bp[17 - 12];
-+        acc += bp[16 - 12];
-+        acc -= bp[19 - 12];
-+        rp[8] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[9];
-+        acc += bp[21 - 12];
-+        acc += bp[18 - 12];
-+        acc += bp[17 - 12];
-+        acc -= bp[20 - 12];
-+        rp[9] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[10];
-+        acc += bp[22 - 12];
-+        acc += bp[19 - 12];
-+        acc += bp[18 - 12];
-+        acc -= bp[21 - 12];
-+        rp[10] = (unsigned int)acc;
-+        acc >>= 32;
-+
-+        acc += rp[11];
-+        acc += bp[23 - 12];
-+        acc += bp[20 - 12];
-+        acc += bp[19 - 12];
-+        acc -= bp[22 - 12];
-+        rp[11] = (unsigned int)acc;
-+
-+        carry = (int)(acc >> 32);
-+    }
-+#else
-+    {
-+        BN_ULONG t_d[BN_NIST_384_TOP];
-+
-+        /*
-+         * S1
-+         */
-+        nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4, 21 - 4);
-+        /* left shift */
-+        {
-+            register BN_ULONG *ap, t, c;
-+            ap = t_d;
-+            c = 0;
-+            for (i = 3; i != 0; --i) {
-+                t = *ap;
-+                *(ap++) = ((t << 1) | c) & BN_MASK2;
-+                c = (t & BN_TBIT) ? 1 : 0;
-+            }
-+            *ap = c;
-+        }
-+        carry =
-+            (int)bn_add_words(r_d + (128 / BN_BITS2), r_d + (128 / BN_BITS2),
-+                              t_d, BN_NIST_256_TOP);
-+        /*
-+         * S2
-+         */
-+        carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP);
-+        /*
-+         * S3
-+         */
-+        nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,
-+                     21);
-+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
-+        /*
-+         * S4
-+         */
-+        nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20, 0, 23,
-+                     0);
-+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
-+        /*
-+         * S5
-+         */
-+        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 23, 22, 21, 20, 0, 0, 0, 0);
-+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
-+        /*
-+         * S6
-+         */
-+        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 23, 22, 21, 0, 0, 20);
-+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
-+        /*
-+         * D1
-+         */
-+        nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
-+                     23);
-+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
-+        /*
-+         * D2
-+         */
-+        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 22, 21, 20, 0);
-+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
-+        /*
-+         * D3
-+         */
-+        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0);
-+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
-+
-+    }
-+#endif
-+    /* see BN_nist_mod_224 for explanation */
-+    u.f = bn_sub_words;
-+    if (carry > 0)
-+        carry =
-+            (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1],
-+                              BN_NIST_384_TOP);
-+    else if (carry < 0) {
-+        carry =
-+            (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1],
-+                              BN_NIST_384_TOP);
-+        mask = 0 - (PTR_SIZE_INT) carry;
-+        u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
-+            ((PTR_SIZE_INT) bn_add_words & ~mask);
-+    } else
-+        carry = 1;
-+
-+    mask =
-+        0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP);
-+    mask &= 0 - (PTR_SIZE_INT) carry;
-+    res = c_d;
-+    res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
-+                       ((PTR_SIZE_INT) r_d & mask));
-+    nist_cp_bn(r_d, res, BN_NIST_384_TOP);
-+    r->top = BN_NIST_384_TOP;
-+    bn_correct_top(r);
-+
-+    return 1;
-+}
-+
-+#define BN_NIST_521_RSHIFT      (521%BN_BITS2)
-+#define BN_NIST_521_LSHIFT      (BN_BITS2-BN_NIST_521_RSHIFT)
-+#define BN_NIST_521_TOP_MASK    ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
-+
-+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
-+                    BN_CTX *ctx)
-+{
-+    int top = a->top, i;
-+    BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res;
-+    PTR_SIZE_INT mask;
-+    static const BIGNUM _bignum_nist_p_521_sqr = {
-+        (BN_ULONG *)_nist_p_521_sqr,
-+        OSSL_NELEM(_nist_p_521_sqr),
-+        OSSL_NELEM(_nist_p_521_sqr),
-+        0, BN_FLG_STATIC_DATA
-+    };
-+
-+    field = &_bignum_nist_p_521; /* just to make sure */
-+
-+    if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_521_sqr) >= 0)
-+        return BN_nnmod(r, a, field, ctx);
-+
-+    i = BN_ucmp(field, a);
-+    if (i == 0) {
-+        BN_zero(r);
-+        return 1;
-+    } else if (i > 0)
-+        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
-+
-+    if (r != a) {
-+        if (!bn_wexpand(r, BN_NIST_521_TOP))
-+            return 0;
-+        r_d = r->d;
-+        nist_cp_bn(r_d, a_d, BN_NIST_521_TOP);
-+    } else
-+        r_d = a_d;
-+
-+    /* upper 521 bits, copy ... */
-+    nist_cp_bn_0(t_d, a_d + (BN_NIST_521_TOP - 1),
-+                 top - (BN_NIST_521_TOP - 1), BN_NIST_521_TOP);
-+    /* ... and right shift */
-+    for (val = t_d[0], i = 0; i < BN_NIST_521_TOP - 1; i++) {
-+#if 0
-+        /*
-+         * MSC ARM compiler [version 2013, presumably even earlier,
-+         * much earlier] miscompiles this code, but not one in
-+         * #else section. See RT#3541.
-+         */
-+        tmp = val >> BN_NIST_521_RSHIFT;
-+        val = t_d[i + 1];
-+        t_d[i] = (tmp | val << BN_NIST_521_LSHIFT) & BN_MASK2;
-+#else
-+        t_d[i] = (val >> BN_NIST_521_RSHIFT |
-+                  (tmp = t_d[i + 1]) << BN_NIST_521_LSHIFT) & BN_MASK2;
-+        val = tmp;
-+#endif
-+    }
-+    t_d[i] = val >> BN_NIST_521_RSHIFT;
-+    /* lower 521 bits */
-+    r_d[i] &= BN_NIST_521_TOP_MASK;
-+
-+    bn_add_words(r_d, r_d, t_d, BN_NIST_521_TOP);
-+    mask =
-+        0 - (PTR_SIZE_INT) bn_sub_words(t_d, r_d, _nist_p_521,
-+                                        BN_NIST_521_TOP);
-+    res = t_d;
-+    res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
-+                       ((PTR_SIZE_INT) r_d & mask));
-+    nist_cp_bn(r_d, res, BN_NIST_521_TOP);
-+    r->top = BN_NIST_521_TOP;
-+    bn_correct_top(r);
-+
-+    return 1;
-+}
-+
-+int (*BN_nist_mod_func(const BIGNUM *p)) (BIGNUM *r, const BIGNUM *a,
-+                                          const BIGNUM *field, BN_CTX *ctx) {
-+    if (BN_ucmp(&_bignum_nist_p_192, p) == 0)
-+        return BN_nist_mod_192;
-+    if (BN_ucmp(&_bignum_nist_p_224, p) == 0)
-+        return BN_nist_mod_224;
-+    if (BN_ucmp(&_bignum_nist_p_256, p) == 0)
-+        return BN_nist_mod_256;
-+    if (BN_ucmp(&_bignum_nist_p_384, p) == 0)
-+        return BN_nist_mod_384;
-+    if (BN_ucmp(&_bignum_nist_p_521, p) == 0)
-+        return BN_nist_mod_521;
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.c
-new file mode 100644
-index 0000000..7103acf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.c
-@@ -0,0 +1,608 @@
-+/*
-+ * WARNING: do not edit!
-+ * Generated by crypto/bn/bn_prime.pl
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+/*
-+ * The quick sieve algorithm approach to weeding out primes is Philip
-+ * Zimmermann's, as implemented in PGP.  I have had a read of his comments
-+ * and implemented my own version.
-+ */
-+#include "bn_prime.h"
-+
-+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
-+                   const BIGNUM *a1_odd, int k, BN_CTX *ctx,
-+                   BN_MONT_CTX *mont);
-+static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods);
-+static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
-+                                  const BIGNUM *add, const BIGNUM *rem,
-+                                  BN_CTX *ctx);
-+
-+static const int prime_offsets[480] = {
-+    13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83,
-+    89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
-+    167, 169, 173, 179, 181, 191, 193, 197, 199, 211, 221, 223, 227, 229,
-+    233, 239, 241, 247, 251, 257, 263, 269, 271, 277, 281, 283, 289, 293,
-+    299, 307, 311, 313, 317, 323, 331, 337, 347, 349, 353, 359, 361, 367,
-+    373, 377, 379, 383, 389, 391, 397, 401, 403, 409, 419, 421, 431, 433,
-+    437, 439, 443, 449, 457, 461, 463, 467, 479, 481, 487, 491, 493, 499,
-+    503, 509, 521, 523, 527, 529, 533, 541, 547, 551, 557, 559, 563, 569,
-+    571, 577, 587, 589, 593, 599, 601, 607, 611, 613, 617, 619, 629, 631,
-+    641, 643, 647, 653, 659, 661, 667, 673, 677, 683, 689, 691, 697, 701,
-+    703, 709, 713, 719, 727, 731, 733, 739, 743, 751, 757, 761, 767, 769,
-+    773, 779, 787, 793, 797, 799, 809, 811, 817, 821, 823, 827, 829, 839,
-+    841, 851, 853, 857, 859, 863, 871, 877, 881, 883, 887, 893, 899, 901,
-+    907, 911, 919, 923, 929, 937, 941, 943, 947, 949, 953, 961, 967, 971,
-+    977, 983, 989, 991, 997, 1003, 1007, 1009, 1013, 1019, 1021, 1027, 1031,
-+    1033, 1037, 1039, 1049, 1051, 1061, 1063, 1069, 1073, 1079, 1081, 1087,
-+    1091, 1093, 1097, 1103, 1109, 1117, 1121, 1123, 1129, 1139, 1147, 1151,
-+    1153, 1157, 1159, 1163, 1171, 1181, 1187, 1189, 1193, 1201, 1207, 1213,
-+    1217, 1219, 1223, 1229, 1231, 1237, 1241, 1247, 1249, 1259, 1261, 1271,
-+    1273, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1313, 1319,
-+    1321, 1327, 1333, 1339, 1343, 1349, 1357, 1361, 1363, 1367, 1369, 1373,
-+    1381, 1387, 1391, 1399, 1403, 1409, 1411, 1417, 1423, 1427, 1429, 1433,
-+    1439, 1447, 1451, 1453, 1457, 1459, 1469, 1471, 1481, 1483, 1487, 1489,
-+    1493, 1499, 1501, 1511, 1513, 1517, 1523, 1531, 1537, 1541, 1543, 1549,
-+    1553, 1559, 1567, 1571, 1577, 1579, 1583, 1591, 1597, 1601, 1607, 1609,
-+    1613, 1619, 1621, 1627, 1633, 1637, 1643, 1649, 1651, 1657, 1663, 1667,
-+    1669, 1679, 1681, 1691, 1693, 1697, 1699, 1703, 1709, 1711, 1717, 1721,
-+    1723, 1733, 1739, 1741, 1747, 1751, 1753, 1759, 1763, 1769, 1777, 1781,
-+    1783, 1787, 1789, 1801, 1807, 1811, 1817, 1819, 1823, 1829, 1831, 1843,
-+    1847, 1849, 1853, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1891, 1901,
-+    1907, 1909, 1913, 1919, 1921, 1927, 1931, 1933, 1937, 1943, 1949, 1951,
-+    1957, 1961, 1963, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017,
-+    2021, 2027, 2029, 2033, 2039, 2041, 2047, 2053, 2059, 2063, 2069, 2071,
-+    2077, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2117, 2119, 2129, 2131,
-+    2137, 2141, 2143, 2147, 2153, 2159, 2161, 2171, 2173, 2179, 2183, 2197,
-+    2201, 2203, 2207, 2209, 2213, 2221, 2227, 2231, 2237, 2239, 2243, 2249,
-+    2251, 2257, 2263, 2267, 2269, 2273, 2279, 2281, 2287, 2291, 2293, 2297,
-+    2309, 2311
-+};
-+
-+static const int prime_offset_count = 480;
-+static const int prime_multiplier = 2310;
-+static const int prime_multiplier_bits = 11; /* 2^|prime_multiplier_bits| <=
-+                                              * |prime_multiplier| */
-+static const int first_prime_index = 5;
-+
-+int BN_GENCB_call(BN_GENCB *cb, int a, int b)
-+{
-+    /* No callback means continue */
-+    if (!cb)
-+        return 1;
-+    switch (cb->ver) {
-+    case 1:
-+        /* Deprecated-style callbacks */
-+        if (!cb->cb.cb_1)
-+            return 1;
-+        cb->cb.cb_1(a, b, cb->arg);
-+        return 1;
-+    case 2:
-+        /* New-style callbacks */
-+        return cb->cb.cb_2(a, b, cb);
-+    default:
-+        break;
-+    }
-+    /* Unrecognised callback type */
-+    return 0;
-+}
-+
-+int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
-+                         const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
-+{
-+    BIGNUM *t;
-+    int found = 0;
-+    int i, j, c1 = 0;
-+    BN_CTX *ctx = NULL;
-+    prime_t *mods = NULL;
-+    int checks = BN_prime_checks_for_size(bits);
-+
-+    if (bits < 2) {
-+        /* There are no prime numbers this small. */
-+        BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
-+        return 0;
-+    } else if (bits == 2 && safe) {
-+        /* The smallest safe prime (7) is three bits. */
-+        BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
-+        return 0;
-+    }
-+
-+    mods = OPENSSL_zalloc(sizeof(*mods) * NUMPRIMES);
-+    if (mods == NULL)
-+        goto err;
-+
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    t = BN_CTX_get(ctx);
-+    if (!t)
-+        goto err;
-+ loop:
-+    /* make a random number and set the top and bottom bits */
-+    if (add == NULL) {
-+        if (!probable_prime(ret, bits, mods))
-+            goto err;
-+    } else {
-+        if (safe) {
-+            if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
-+                goto err;
-+        } else {
-+            if (!bn_probable_prime_dh(ret, bits, add, rem, ctx))
-+                goto err;
-+        }
-+    }
-+
-+    if (!BN_GENCB_call(cb, 0, c1++))
-+        /* aborted */
-+        goto err;
-+
-+    if (!safe) {
-+        i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
-+        if (i == -1)
-+            goto err;
-+        if (i == 0)
-+            goto loop;
-+    } else {
-+        /*
-+         * for "safe prime" generation, check that (p-1)/2 is prime. Since a
-+         * prime is odd, We just need to divide by 2
-+         */
-+        if (!BN_rshift1(t, ret))
-+            goto err;
-+
-+        for (i = 0; i < checks; i++) {
-+            j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
-+            if (j == -1)
-+                goto err;
-+            if (j == 0)
-+                goto loop;
-+
-+            j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
-+            if (j == -1)
-+                goto err;
-+            if (j == 0)
-+                goto loop;
-+
-+            if (!BN_GENCB_call(cb, 2, c1 - 1))
-+                goto err;
-+            /* We have a safe prime test pass */
-+        }
-+    }
-+    /* we have a prime :-) */
-+    found = 1;
-+ err:
-+    OPENSSL_free(mods);
-+    if (ctx != NULL)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    bn_check_top(ret);
-+    return found;
-+}
-+
-+int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
-+                   BN_GENCB *cb)
-+{
-+    return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
-+}
-+
-+int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
-+                            int do_trial_division, BN_GENCB *cb)
-+{
-+    int i, j, ret = -1;
-+    int k;
-+    BN_CTX *ctx = NULL;
-+    BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
-+    BN_MONT_CTX *mont = NULL;
-+    const BIGNUM *A = NULL;
-+
-+    if (BN_cmp(a, BN_value_one()) <= 0)
-+        return 0;
-+
-+    if (checks == BN_prime_checks)
-+        checks = BN_prime_checks_for_size(BN_num_bits(a));
-+
-+    /* first look for small factors */
-+    if (!BN_is_odd(a))
-+        /* a is even => a is prime if and only if a == 2 */
-+        return BN_is_word(a, 2);
-+    if (do_trial_division) {
-+        for (i = 1; i < NUMPRIMES; i++) {
-+            BN_ULONG mod = BN_mod_word(a, primes[i]);
-+            if (mod == (BN_ULONG)-1)
-+                goto err;
-+            if (mod == 0)
-+                return 0;
-+        }
-+        if (!BN_GENCB_call(cb, 1, -1))
-+            goto err;
-+    }
-+
-+    if (ctx_passed != NULL)
-+        ctx = ctx_passed;
-+    else if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+
-+    /* A := abs(a) */
-+    if (a->neg) {
-+        BIGNUM *t;
-+        if ((t = BN_CTX_get(ctx)) == NULL)
-+            goto err;
-+        if (BN_copy(t, a) == NULL)
-+            goto err;
-+        t->neg = 0;
-+        A = t;
-+    } else
-+        A = a;
-+    A1 = BN_CTX_get(ctx);
-+    A1_odd = BN_CTX_get(ctx);
-+    check = BN_CTX_get(ctx);
-+    if (check == NULL)
-+        goto err;
-+
-+    /* compute A1 := A - 1 */
-+    if (!BN_copy(A1, A))
-+        goto err;
-+    if (!BN_sub_word(A1, 1))
-+        goto err;
-+    if (BN_is_zero(A1)) {
-+        ret = 0;
-+        goto err;
-+    }
-+
-+    /* write  A1  as  A1_odd * 2^k */
-+    k = 1;
-+    while (!BN_is_bit_set(A1, k))
-+        k++;
-+    if (!BN_rshift(A1_odd, A1, k))
-+        goto err;
-+
-+    /* Montgomery setup for computations mod A */
-+    mont = BN_MONT_CTX_new();
-+    if (mont == NULL)
-+        goto err;
-+    if (!BN_MONT_CTX_set(mont, A, ctx))
-+        goto err;
-+
-+    for (i = 0; i < checks; i++) {
-+        if (!BN_pseudo_rand_range(check, A1))
-+            goto err;
-+        if (!BN_add_word(check, 1))
-+            goto err;
-+        /* now 1 <= check < A */
-+
-+        j = witness(check, A, A1, A1_odd, k, ctx, mont);
-+        if (j == -1)
-+            goto err;
-+        if (j) {
-+            ret = 0;
-+            goto err;
-+        }
-+        if (!BN_GENCB_call(cb, 1, i))
-+            goto err;
-+    }
-+    ret = 1;
-+ err:
-+    if (ctx != NULL) {
-+        BN_CTX_end(ctx);
-+        if (ctx_passed == NULL)
-+            BN_CTX_free(ctx);
-+    }
-+    BN_MONT_CTX_free(mont);
-+
-+    return (ret);
-+}
-+
-+int bn_probable_prime_dh_retry(BIGNUM *rnd, int bits, BN_CTX *ctx)
-+{
-+    int i;
-+    int ret = 0;
-+
-+ loop:
-+    if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD))
-+        goto err;
-+
-+    /* we now have a random number 'rand' to test. */
-+
-+    for (i = 1; i < NUMPRIMES; i++) {
-+        /* check that rnd is a prime */
-+        BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
-+        if (mod == (BN_ULONG)-1)
-+            goto err;
-+        if (mod <= 1) {
-+            goto loop;
-+        }
-+    }
-+    ret = 1;
-+
-+ err:
-+    bn_check_top(rnd);
-+    return (ret);
-+}
-+
-+int bn_probable_prime_dh_coprime(BIGNUM *rnd, int bits, BN_CTX *ctx)
-+{
-+    int i;
-+    BIGNUM *offset_index;
-+    BIGNUM *offset_count;
-+    int ret = 0;
-+
-+    OPENSSL_assert(bits > prime_multiplier_bits);
-+
-+    BN_CTX_start(ctx);
-+    if ((offset_index = BN_CTX_get(ctx)) == NULL)
-+        goto err;
-+    if ((offset_count = BN_CTX_get(ctx)) == NULL)
-+        goto err;
-+
-+    if (!BN_add_word(offset_count, prime_offset_count))
-+        goto err;
-+
-+ loop:
-+    if (!BN_rand(rnd, bits - prime_multiplier_bits,
-+                 BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD))
-+        goto err;
-+    if (BN_is_bit_set(rnd, bits))
-+        goto loop;
-+    if (!BN_rand_range(offset_index, offset_count))
-+        goto err;
-+
-+    if (!BN_mul_word(rnd, prime_multiplier)
-+        || !BN_add_word(rnd, prime_offsets[BN_get_word(offset_index)]))
-+        goto err;
-+
-+    /* we now have a random number 'rand' to test. */
-+
-+    /* skip coprimes */
-+    for (i = first_prime_index; i < NUMPRIMES; i++) {
-+        /* check that rnd is a prime */
-+        BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
-+        if (mod == (BN_ULONG)-1)
-+            goto err;
-+        if (mod <= 1)
-+            goto loop;
-+    }
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    bn_check_top(rnd);
-+    return ret;
-+}
-+
-+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
-+                   const BIGNUM *a1_odd, int k, BN_CTX *ctx,
-+                   BN_MONT_CTX *mont)
-+{
-+    if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
-+        return -1;
-+    if (BN_is_one(w))
-+        return 0;               /* probably prime */
-+    if (BN_cmp(w, a1) == 0)
-+        return 0;               /* w == -1 (mod a), 'a' is probably prime */
-+    while (--k) {
-+        if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
-+            return -1;
-+        if (BN_is_one(w))
-+            return 1;           /* 'a' is composite, otherwise a previous 'w'
-+                                 * would have been == -1 (mod 'a') */
-+        if (BN_cmp(w, a1) == 0)
-+            return 0;           /* w == -1 (mod a), 'a' is probably prime */
-+    }
-+    /*
-+     * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and
-+     * it is neither -1 nor +1 -- so 'a' cannot be prime
-+     */
-+    bn_check_top(w);
-+    return 1;
-+}
-+
-+static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods)
-+{
-+    int i;
-+    BN_ULONG delta;
-+    BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
-+    char is_single_word = bits <= BN_BITS2;
-+
-+ again:
-+    if (!BN_rand(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD))
-+        return (0);
-+    /* we now have a random number 'rnd' to test. */
-+    for (i = 1; i < NUMPRIMES; i++) {
-+        BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
-+        if (mod == (BN_ULONG)-1)
-+            return 0;
-+        mods[i] = (prime_t) mod;
-+    }
-+    /*
-+     * If bits is so small that it fits into a single word then we
-+     * additionally don't want to exceed that many bits.
-+     */
-+    if (is_single_word) {
-+        BN_ULONG size_limit;
-+
-+        if (bits == BN_BITS2) {
-+            /*
-+             * Shifting by this much has undefined behaviour so we do it a
-+             * different way
-+             */
-+            size_limit = ~((BN_ULONG)0) - BN_get_word(rnd);
-+        } else {
-+            size_limit = (((BN_ULONG)1) << bits) - BN_get_word(rnd) - 1;
-+        }
-+        if (size_limit < maxdelta)
-+            maxdelta = size_limit;
-+    }
-+    delta = 0;
-+ loop:
-+    if (is_single_word) {
-+        BN_ULONG rnd_word = BN_get_word(rnd);
-+
-+        /*-
-+         * In the case that the candidate prime is a single word then
-+         * we check that:
-+         *   1) It's greater than primes[i] because we shouldn't reject
-+         *      3 as being a prime number because it's a multiple of
-+         *      three.
-+         *   2) That it's not a multiple of a known prime. We don't
-+         *      check that rnd-1 is also coprime to all the known
-+         *      primes because there aren't many small primes where
-+         *      that's true.
-+         */
-+        for (i = 1; i < NUMPRIMES && primes[i] < rnd_word; i++) {
-+            if ((mods[i] + delta) % primes[i] == 0) {
-+                delta += 2;
-+                if (delta > maxdelta)
-+                    goto again;
-+                goto loop;
-+            }
-+        }
-+    } else {
-+        for (i = 1; i < NUMPRIMES; i++) {
-+            /*
-+             * check that rnd is not a prime and also that gcd(rnd-1,primes)
-+             * == 1 (except for 2)
-+             */
-+            if (((mods[i] + delta) % primes[i]) <= 1) {
-+                delta += 2;
-+                if (delta > maxdelta)
-+                    goto again;
-+                goto loop;
-+            }
-+        }
-+    }
-+    if (!BN_add_word(rnd, delta))
-+        return (0);
-+    if (BN_num_bits(rnd) != bits)
-+        goto again;
-+    bn_check_top(rnd);
-+    return (1);
-+}
-+
-+int bn_probable_prime_dh(BIGNUM *rnd, int bits,
-+                         const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx)
-+{
-+    int i, ret = 0;
-+    BIGNUM *t1;
-+
-+    BN_CTX_start(ctx);
-+    if ((t1 = BN_CTX_get(ctx)) == NULL)
-+        goto err;
-+
-+    if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD))
-+        goto err;
-+
-+    /* we need ((rnd-rem) % add) == 0 */
-+
-+    if (!BN_mod(t1, rnd, add, ctx))
-+        goto err;
-+    if (!BN_sub(rnd, rnd, t1))
-+        goto err;
-+    if (rem == NULL) {
-+        if (!BN_add_word(rnd, 1))
-+            goto err;
-+    } else {
-+        if (!BN_add(rnd, rnd, rem))
-+            goto err;
-+    }
-+
-+    /* we now have a random number 'rand' to test. */
-+
-+ loop:
-+    for (i = 1; i < NUMPRIMES; i++) {
-+        /* check that rnd is a prime */
-+        BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
-+        if (mod == (BN_ULONG)-1)
-+            goto err;
-+        if (mod <= 1) {
-+            if (!BN_add(rnd, rnd, add))
-+                goto err;
-+            goto loop;
-+        }
-+    }
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    bn_check_top(rnd);
-+    return (ret);
-+}
-+
-+static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
-+                                  const BIGNUM *rem, BN_CTX *ctx)
-+{
-+    int i, ret = 0;
-+    BIGNUM *t1, *qadd, *q;
-+
-+    bits--;
-+    BN_CTX_start(ctx);
-+    t1 = BN_CTX_get(ctx);
-+    q = BN_CTX_get(ctx);
-+    qadd = BN_CTX_get(ctx);
-+    if (qadd == NULL)
-+        goto err;
-+
-+    if (!BN_rshift1(qadd, padd))
-+        goto err;
-+
-+    if (!BN_rand(q, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD))
-+        goto err;
-+
-+    /* we need ((rnd-rem) % add) == 0 */
-+    if (!BN_mod(t1, q, qadd, ctx))
-+        goto err;
-+    if (!BN_sub(q, q, t1))
-+        goto err;
-+    if (rem == NULL) {
-+        if (!BN_add_word(q, 1))
-+            goto err;
-+    } else {
-+        if (!BN_rshift1(t1, rem))
-+            goto err;
-+        if (!BN_add(q, q, t1))
-+            goto err;
-+    }
-+
-+    /* we now have a random number 'rand' to test. */
-+    if (!BN_lshift1(p, q))
-+        goto err;
-+    if (!BN_add_word(p, 1))
-+        goto err;
-+
-+ loop:
-+    for (i = 1; i < NUMPRIMES; i++) {
-+        /* check that p and q are prime */
-+        /*
-+         * check that for p and q gcd(p-1,primes) == 1 (except for 2)
-+         */
-+        BN_ULONG pmod = BN_mod_word(p, (BN_ULONG)primes[i]);
-+        BN_ULONG qmod = BN_mod_word(q, (BN_ULONG)primes[i]);
-+        if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1)
-+            goto err;
-+        if (pmod == 0 || qmod == 0) {
-+            if (!BN_add(p, p, padd))
-+                goto err;
-+            if (!BN_add(q, q, qadd))
-+                goto err;
-+            goto loop;
-+        }
-+    }
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    bn_check_top(p);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.h
-new file mode 100644
-index 0000000..41440fa
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.h
-@@ -0,0 +1,274 @@
-+/*
-+ * WARNING: do not edit!
-+ * Generated by crypto/bn/bn_prime.pl
-+ *
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+typedef unsigned short prime_t;
-+# define NUMPRIMES 2048
-+
-+static const prime_t primes[2048] = {
-+
-+       2,    3,    5,    7,   11,   13,   17,   19, 
-+      23,   29,   31,   37,   41,   43,   47,   53, 
-+      59,   61,   67,   71,   73,   79,   83,   89, 
-+      97,  101,  103,  107,  109,  113,  127,  131, 
-+     137,  139,  149,  151,  157,  163,  167,  173, 
-+     179,  181,  191,  193,  197,  199,  211,  223, 
-+     227,  229,  233,  239,  241,  251,  257,  263, 
-+     269,  271,  277,  281,  283,  293,  307,  311, 
-+     313,  317,  331,  337,  347,  349,  353,  359, 
-+     367,  373,  379,  383,  389,  397,  401,  409, 
-+     419,  421,  431,  433,  439,  443,  449,  457, 
-+     461,  463,  467,  479,  487,  491,  499,  503, 
-+     509,  521,  523,  541,  547,  557,  563,  569, 
-+     571,  577,  587,  593,  599,  601,  607,  613, 
-+     617,  619,  631,  641,  643,  647,  653,  659, 
-+     661,  673,  677,  683,  691,  701,  709,  719, 
-+     727,  733,  739,  743,  751,  757,  761,  769, 
-+     773,  787,  797,  809,  811,  821,  823,  827, 
-+     829,  839,  853,  857,  859,  863,  877,  881, 
-+     883,  887,  907,  911,  919,  929,  937,  941, 
-+     947,  953,  967,  971,  977,  983,  991,  997, 
-+    1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 
-+    1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 
-+    1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 
-+    1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 
-+    1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 
-+    1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 
-+    1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 
-+    1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 
-+    1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 
-+    1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 
-+    1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 
-+    1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 
-+    1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 
-+    1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 
-+    1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 
-+    1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 
-+    1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 
-+    2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 
-+    2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 
-+    2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 
-+    2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 
-+    2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 
-+    2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 
-+    2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 
-+    2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 
-+    2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 
-+    2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 
-+    2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 
-+    2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 
-+    2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 
-+    2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 
-+    2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 
-+    2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 
-+    3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 
-+    3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 
-+    3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 
-+    3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 
-+    3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 
-+    3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 
-+    3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 
-+    3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 
-+    3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 
-+    3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 
-+    3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 
-+    3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 
-+    3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 
-+    3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 
-+    3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 
-+    4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 
-+    4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 
-+    4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 
-+    4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 
-+    4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 
-+    4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 
-+    4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 
-+    4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 
-+    4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 
-+    4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 
-+    4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 
-+    4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 
-+    4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 
-+    4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 
-+    4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 
-+    5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 
-+    5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 
-+    5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 
-+    5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 
-+    5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 
-+    5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 
-+    5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 
-+    5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 
-+    5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 
-+    5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 
-+    5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 
-+    5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 
-+    5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 
-+    5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 
-+    6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 
-+    6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 
-+    6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 
-+    6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 
-+    6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 
-+    6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 
-+    6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 
-+    6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 
-+    6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 
-+    6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 
-+    6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 
-+    6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 
-+    6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 
-+    6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 
-+    6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 
-+    7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 
-+    7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 
-+    7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 
-+    7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 
-+    7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 
-+    7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 
-+    7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 
-+    7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 
-+    7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 
-+    7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 
-+    7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 
-+    7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 
-+    7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 
-+    8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 
-+    8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 
-+    8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 
-+    8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 
-+    8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 
-+    8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 
-+    8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 
-+    8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, 
-+    8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 
-+    8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 
-+    8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 
-+    8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 
-+    8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 
-+    8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 
-+    9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 
-+    9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 
-+    9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 
-+    9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 
-+    9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 
-+    9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 
-+    9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 
-+    9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 
-+    9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 
-+    9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 
-+    9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 
-+    9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, 
-+    9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 
-+    9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, 
-+    10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 
-+    10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, 
-+    10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, 
-+    10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 
-+    10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, 
-+    10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, 
-+    10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, 
-+    10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 
-+    10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, 
-+    10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, 
-+    10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, 
-+    10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, 
-+    10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, 
-+    11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, 
-+    11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 
-+    11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, 
-+    11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, 
-+    11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, 
-+    11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 
-+    11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, 
-+    11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, 
-+    11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, 
-+    11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, 
-+    11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, 
-+    11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, 
-+    11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 
-+    12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, 
-+    12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, 
-+    12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, 
-+    12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 
-+    12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, 
-+    12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, 
-+    12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, 
-+    12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, 
-+    12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, 
-+    12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, 
-+    12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 
-+    12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, 
-+    12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, 
-+    12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, 
-+    13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 
-+    13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, 
-+    13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, 
-+    13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, 
-+    13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, 
-+    13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, 
-+    13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, 
-+    13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 
-+    13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, 
-+    13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, 
-+    13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, 
-+    13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 
-+    13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, 
-+    14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, 
-+    14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, 
-+    14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, 
-+    14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, 
-+    14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, 
-+    14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, 
-+    14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, 
-+    14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, 
-+    14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, 
-+    14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 
-+    14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, 
-+    14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, 
-+    14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, 
-+    15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, 
-+    15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, 
-+    15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, 
-+    15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 
-+    15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, 
-+    15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, 
-+    15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, 
-+    15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 
-+    15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, 
-+    15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, 
-+    15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, 
-+    15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, 
-+    15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, 
-+    16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, 
-+    16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 
-+    16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, 
-+    16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, 
-+    16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, 
-+    16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, 
-+    16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, 
-+    16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, 
-+    16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, 
-+    16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, 
-+    16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, 
-+    16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, 
-+    17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 
-+    17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, 
-+    17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, 
-+    17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, 
-+    17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 
-+    17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, 
-+    17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, 
-+    17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, 
-+    17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, 
-+    17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, 
-+    17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, 
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.pl
-new file mode 100644
-index 0000000..163d4a9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_prime.pl
-@@ -0,0 +1,46 @@
-+#! /usr/bin/env perl
-+# Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+print <<"EOF";
-+/*
-+ * WARNING: do not edit!
-+ * Generated by crypto/bn/bn_prime.pl
-+ *
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+EOF
-+
-+
-+my $num = shift || 2048;
-+my @primes = ( 2 );
-+my $p = 1;
-+loop: while ($#primes < $num-1) {
-+    $p += 2;
-+    my $s = int(sqrt($p));
-+
-+    for (my $i = 0; defined($primes[$i]) && $primes[$i] <= $s; $i++) {
-+        next loop if ($p % $primes[$i]) == 0;
-+    }
-+    push(@primes, $p);
-+}
-+
-+print "typedef unsigned short prime_t;\n";
-+printf "# define NUMPRIMES %d\n\n", $num;
-+
-+printf "static const prime_t primes[%d] = {\n", $num;
-+for (my $i = 0; $i <= $#primes; $i++) {
-+    printf "\n    " if ($i % 8) == 0;
-+    printf "%4d, ", $primes[$i];
-+}
-+print "\n};\n";
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_print.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_print.c
-new file mode 100644
-index 0000000..a16bde8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_print.c
-@@ -0,0 +1,345 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "bn_lcl.h"
-+
-+static const char Hex[] = "0123456789ABCDEF";
-+
-+/* Must 'OPENSSL_free' the returned data */
-+char *BN_bn2hex(const BIGNUM *a)
-+{
-+    int i, j, v, z = 0;
-+    char *buf;
-+    char *p;
-+
-+    if (BN_is_zero(a))
-+        return OPENSSL_strdup("0");
-+    buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
-+    if (buf == NULL) {
-+        BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    p = buf;
-+    if (a->neg)
-+        *(p++) = '-';
-+    if (BN_is_zero(a))
-+        *(p++) = '0';
-+    for (i = a->top - 1; i >= 0; i--) {
-+        for (j = BN_BITS2 - 8; j >= 0; j -= 8) {
-+            /* strip leading zeros */
-+            v = ((int)(a->d[i] >> (long)j)) & 0xff;
-+            if (z || (v != 0)) {
-+                *(p++) = Hex[v >> 4];
-+                *(p++) = Hex[v & 0x0f];
-+                z = 1;
-+            }
-+        }
-+    }
-+    *p = '\0';
-+ err:
-+    return (buf);
-+}
-+
-+/* Must 'OPENSSL_free' the returned data */
-+char *BN_bn2dec(const BIGNUM *a)
-+{
-+    int i = 0, num, ok = 0;
-+    char *buf = NULL;
-+    char *p;
-+    BIGNUM *t = NULL;
-+    BN_ULONG *bn_data = NULL, *lp;
-+    int bn_data_num;
-+
-+    /*-
-+     * get an upper bound for the length of the decimal integer
-+     * num <= (BN_num_bits(a) + 1) * log(2)
-+     *     <= 3 * BN_num_bits(a) * 0.101 + log(2) + 1     (rounding error)
-+     *     <= 3 * BN_num_bits(a) / 10 + 3 * BN_num_bits / 1000 + 1 + 1
-+     */
-+    i = BN_num_bits(a) * 3;
-+    num = (i / 10 + i / 1000 + 1) + 1;
-+    bn_data_num = num / BN_DEC_NUM + 1;
-+    bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG));
-+    buf = OPENSSL_malloc(num + 3);
-+    if ((buf == NULL) || (bn_data == NULL)) {
-+        BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if ((t = BN_dup(a)) == NULL)
-+        goto err;
-+
-+#define BUF_REMAIN (num+3 - (size_t)(p - buf))
-+    p = buf;
-+    lp = bn_data;
-+    if (BN_is_zero(t)) {
-+        *(p++) = '0';
-+        *(p++) = '\0';
-+    } else {
-+        if (BN_is_negative(t))
-+            *p++ = '-';
-+
-+        while (!BN_is_zero(t)) {
-+            if (lp - bn_data >= bn_data_num)
-+                goto err;
-+            *lp = BN_div_word(t, BN_DEC_CONV);
-+            if (*lp == (BN_ULONG)-1)
-+                goto err;
-+            lp++;
-+        }
-+        lp--;
-+        /*
-+         * We now have a series of blocks, BN_DEC_NUM chars in length, where
-+         * the last one needs truncation. The blocks need to be reversed in
-+         * order.
-+         */
-+        BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT1, *lp);
-+        while (*p)
-+            p++;
-+        while (lp != bn_data) {
-+            lp--;
-+            BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT2, *lp);
-+            while (*p)
-+                p++;
-+        }
-+    }
-+    ok = 1;
-+ err:
-+    OPENSSL_free(bn_data);
-+    BN_free(t);
-+    if (ok)
-+        return buf;
-+    OPENSSL_free(buf);
-+    return NULL;
-+}
-+
-+int BN_hex2bn(BIGNUM **bn, const char *a)
-+{
-+    BIGNUM *ret = NULL;
-+    BN_ULONG l = 0;
-+    int neg = 0, h, m, i, j, k, c;
-+    int num;
-+
-+    if ((a == NULL) || (*a == '\0'))
-+        return (0);
-+
-+    if (*a == '-') {
-+        neg = 1;
-+        a++;
-+    }
-+
-+    for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++)
-+        continue;
-+
-+    if (i == 0 || i > INT_MAX/4)
-+        goto err;
-+
-+    num = i + neg;
-+    if (bn == NULL)
-+        return (num);
-+
-+    /* a is the start of the hex digits, and it is 'i' long */
-+    if (*bn == NULL) {
-+        if ((ret = BN_new()) == NULL)
-+            return (0);
-+    } else {
-+        ret = *bn;
-+        BN_zero(ret);
-+    }
-+
-+    /* i is the number of hex digits */
-+    if (bn_expand(ret, i * 4) == NULL)
-+        goto err;
-+
-+    j = i;                      /* least significant 'hex' */
-+    m = 0;
-+    h = 0;
-+    while (j > 0) {
-+        m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
-+        l = 0;
-+        for (;;) {
-+            c = a[j - m];
-+            k = OPENSSL_hexchar2int(c);
-+            if (k < 0)
-+                k = 0;          /* paranoia */
-+            l = (l << 4) | k;
-+
-+            if (--m <= 0) {
-+                ret->d[h++] = l;
-+                break;
-+            }
-+        }
-+        j -= (BN_BYTES * 2);
-+    }
-+    ret->top = h;
-+    bn_correct_top(ret);
-+
-+    *bn = ret;
-+    bn_check_top(ret);
-+    /* Don't set the negative flag if it's zero. */
-+    if (ret->top != 0)
-+        ret->neg = neg;
-+    return (num);
-+ err:
-+    if (*bn == NULL)
-+        BN_free(ret);
-+    return (0);
-+}
-+
-+int BN_dec2bn(BIGNUM **bn, const char *a)
-+{
-+    BIGNUM *ret = NULL;
-+    BN_ULONG l = 0;
-+    int neg = 0, i, j;
-+    int num;
-+
-+    if ((a == NULL) || (*a == '\0'))
-+        return (0);
-+    if (*a == '-') {
-+        neg = 1;
-+        a++;
-+    }
-+
-+    for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++)
-+        continue;
-+
-+    if (i == 0 || i > INT_MAX/4)
-+        goto err;
-+
-+    num = i + neg;
-+    if (bn == NULL)
-+        return (num);
-+
-+    /*
-+     * a is the start of the digits, and it is 'i' long. We chop it into
-+     * BN_DEC_NUM digits at a time
-+     */
-+    if (*bn == NULL) {
-+        if ((ret = BN_new()) == NULL)
-+            return (0);
-+    } else {
-+        ret = *bn;
-+        BN_zero(ret);
-+    }
-+
-+    /* i is the number of digits, a bit of an over expand */
-+    if (bn_expand(ret, i * 4) == NULL)
-+        goto err;
-+
-+    j = BN_DEC_NUM - (i % BN_DEC_NUM);
-+    if (j == BN_DEC_NUM)
-+        j = 0;
-+    l = 0;
-+    while (--i >= 0) {
-+        l *= 10;
-+        l += *a - '0';
-+        a++;
-+        if (++j == BN_DEC_NUM) {
-+            if (!BN_mul_word(ret, BN_DEC_CONV)
-+                || !BN_add_word(ret, l))
-+                goto err;
-+            l = 0;
-+            j = 0;
-+        }
-+    }
-+
-+    bn_correct_top(ret);
-+    *bn = ret;
-+    bn_check_top(ret);
-+    /* Don't set the negative flag if it's zero. */
-+    if (ret->top != 0)
-+        ret->neg = neg;
-+    return (num);
-+ err:
-+    if (*bn == NULL)
-+        BN_free(ret);
-+    return (0);
-+}
-+
-+int BN_asc2bn(BIGNUM **bn, const char *a)
-+{
-+    const char *p = a;
-+
-+    if (*p == '-')
-+        p++;
-+
-+    if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) {
-+        if (!BN_hex2bn(bn, p + 2))
-+            return 0;
-+    } else {
-+        if (!BN_dec2bn(bn, p))
-+            return 0;
-+    }
-+    /* Don't set the negative flag if it's zero. */
-+    if (*a == '-' && (*bn)->top != 0)
-+        (*bn)->neg = 1;
-+    return 1;
-+}
-+
-+# ifndef OPENSSL_NO_STDIO
-+int BN_print_fp(FILE *fp, const BIGNUM *a)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL)
-+        return (0);
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = BN_print(b, a);
-+    BIO_free(b);
-+    return (ret);
-+}
-+# endif
-+
-+int BN_print(BIO *bp, const BIGNUM *a)
-+{
-+    int i, j, v, z = 0;
-+    int ret = 0;
-+
-+    if ((a->neg) && (BIO_write(bp, "-", 1) != 1))
-+        goto end;
-+    if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1))
-+        goto end;
-+    for (i = a->top - 1; i >= 0; i--) {
-+        for (j = BN_BITS2 - 4; j >= 0; j -= 4) {
-+            /* strip leading zeros */
-+            v = ((int)(a->d[i] >> (long)j)) & 0x0f;
-+            if (z || (v != 0)) {
-+                if (BIO_write(bp, &(Hex[v]), 1) != 1)
-+                    goto end;
-+                z = 1;
-+            }
-+        }
-+    }
-+    ret = 1;
-+ end:
-+    return (ret);
-+}
-+
-+char *BN_options(void)
-+{
-+    static int init = 0;
-+    static char data[16];
-+
-+    if (!init) {
-+        init++;
-+#ifdef BN_LLONG
-+        BIO_snprintf(data, sizeof data, "bn(%d,%d)",
-+                     (int)sizeof(BN_ULLONG) * 8, (int)sizeof(BN_ULONG) * 8);
-+#else
-+        BIO_snprintf(data, sizeof data, "bn(%d,%d)",
-+                     (int)sizeof(BN_ULONG) * 8, (int)sizeof(BN_ULONG) * 8);
-+#endif
-+    }
-+    return (data);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_rand.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_rand.c
-new file mode 100644
-index 0000000..9ce4c5f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_rand.c
-@@ -0,0 +1,258 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+#include 
-+#include 
-+
-+static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
-+{
-+    unsigned char *buf = NULL;
-+    int ret = 0, bit, bytes, mask;
-+    time_t tim;
-+
-+    if (bits == 0) {
-+        if (top != BN_RAND_TOP_ANY || bottom != BN_RAND_BOTTOM_ANY)
-+            goto toosmall;
-+        BN_zero(rnd);
-+        return 1;
-+    }
-+    if (bits < 0 || (bits == 1 && top > 0))
-+        goto toosmall;
-+
-+    bytes = (bits + 7) / 8;
-+    bit = (bits - 1) % 8;
-+    mask = 0xff << (bit + 1);
-+
-+    buf = OPENSSL_malloc(bytes);
-+    if (buf == NULL) {
-+        BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    /* make a random number and set the top and bottom bits */
-+    time(&tim);
-+    RAND_add(&tim, sizeof(tim), 0.0);
-+
-+    if (RAND_bytes(buf, bytes) <= 0)
-+        goto err;
-+
-+    if (pseudorand == 2) {
-+        /*
-+         * generate patterns that are more likely to trigger BN library bugs
-+         */
-+        int i;
-+        unsigned char c;
-+
-+        for (i = 0; i < bytes; i++) {
-+            if (RAND_bytes(&c, 1) <= 0)
-+                goto err;
-+            if (c >= 128 && i > 0)
-+                buf[i] = buf[i - 1];
-+            else if (c < 42)
-+                buf[i] = 0;
-+            else if (c < 84)
-+                buf[i] = 255;
-+        }
-+    }
-+
-+    if (top >= 0) {
-+        if (top) {
-+            if (bit == 0) {
-+                buf[0] = 1;
-+                buf[1] |= 0x80;
-+            } else {
-+                buf[0] |= (3 << (bit - 1));
-+            }
-+        } else {
-+            buf[0] |= (1 << bit);
-+        }
-+    }
-+    buf[0] &= ~mask;
-+    if (bottom)                 /* set bottom bit if requested */
-+        buf[bytes - 1] |= 1;
-+    if (!BN_bin2bn(buf, bytes, rnd))
-+        goto err;
-+    ret = 1;
-+ err:
-+    OPENSSL_clear_free(buf, bytes);
-+    bn_check_top(rnd);
-+    return (ret);
-+
-+toosmall:
-+    BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL);
-+    return 0;
-+}
-+
-+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
-+{
-+    return bnrand(0, rnd, bits, top, bottom);
-+}
-+
-+int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
-+{
-+    return bnrand(1, rnd, bits, top, bottom);
-+}
-+
-+int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
-+{
-+    return bnrand(2, rnd, bits, top, bottom);
-+}
-+
-+/* random number r:  0 <= r < range */
-+static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range)
-+{
-+    int (*bn_rand) (BIGNUM *, int, int, int) =
-+        pseudo ? BN_pseudo_rand : BN_rand;
-+    int n;
-+    int count = 100;
-+
-+    if (range->neg || BN_is_zero(range)) {
-+        BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE);
-+        return 0;
-+    }
-+
-+    n = BN_num_bits(range);     /* n > 0 */
-+
-+    /* BN_is_bit_set(range, n - 1) always holds */
-+
-+    if (n == 1)
-+        BN_zero(r);
-+    else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) {
-+        /*
-+         * range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer
-+         * than range
-+         */
-+        do {
-+            if (!bn_rand(r, n + 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
-+                return 0;
-+            /*
-+             * If r < 3*range, use r := r MOD range (which is either r, r -
-+             * range, or r - 2*range). Otherwise, iterate once more. Since
-+             * 3*range = 11..._2, each iteration succeeds with probability >=
-+             * .75.
-+             */
-+            if (BN_cmp(r, range) >= 0) {
-+                if (!BN_sub(r, r, range))
-+                    return 0;
-+                if (BN_cmp(r, range) >= 0)
-+                    if (!BN_sub(r, r, range))
-+                        return 0;
-+            }
-+
-+            if (!--count) {
-+                BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
-+                return 0;
-+            }
-+
-+        }
-+        while (BN_cmp(r, range) >= 0);
-+    } else {
-+        do {
-+            /* range = 11..._2  or  range = 101..._2 */
-+            if (!bn_rand(r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
-+                return 0;
-+
-+            if (!--count) {
-+                BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
-+                return 0;
-+            }
-+        }
-+        while (BN_cmp(r, range) >= 0);
-+    }
-+
-+    bn_check_top(r);
-+    return 1;
-+}
-+
-+int BN_rand_range(BIGNUM *r, const BIGNUM *range)
-+{
-+    return bn_rand_range(0, r, range);
-+}
-+
-+int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
-+{
-+    return bn_rand_range(1, r, range);
-+}
-+
-+/*
-+ * BN_generate_dsa_nonce generates a random number 0 <= out < range. Unlike
-+ * BN_rand_range, it also includes the contents of |priv| and |message| in
-+ * the generation so that an RNG failure isn't fatal as long as |priv|
-+ * remains secret. This is intended for use in DSA and ECDSA where an RNG
-+ * weakness leads directly to private key exposure unless this function is
-+ * used.
-+ */
-+int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
-+                          const BIGNUM *priv, const unsigned char *message,
-+                          size_t message_len, BN_CTX *ctx)
-+{
-+    SHA512_CTX sha;
-+    /*
-+     * We use 512 bits of random data per iteration to ensure that we have at
-+     * least |range| bits of randomness.
-+     */
-+    unsigned char random_bytes[64];
-+    unsigned char digest[SHA512_DIGEST_LENGTH];
-+    unsigned done, todo;
-+    /* We generate |range|+8 bytes of random output. */
-+    const unsigned num_k_bytes = BN_num_bytes(range) + 8;
-+    unsigned char private_bytes[96];
-+    unsigned char *k_bytes;
-+    int ret = 0;
-+
-+    k_bytes = OPENSSL_malloc(num_k_bytes);
-+    if (k_bytes == NULL)
-+        goto err;
-+
-+    /* We copy |priv| into a local buffer to avoid exposing its length. */
-+    todo = sizeof(priv->d[0]) * priv->top;
-+    if (todo > sizeof(private_bytes)) {
-+        /*
-+         * No reasonable DSA or ECDSA key should have a private key this
-+         * large and we don't handle this case in order to avoid leaking the
-+         * length of the private key.
-+         */
-+        BNerr(BN_F_BN_GENERATE_DSA_NONCE, BN_R_PRIVATE_KEY_TOO_LARGE);
-+        goto err;
-+    }
-+    memcpy(private_bytes, priv->d, todo);
-+    memset(private_bytes + todo, 0, sizeof(private_bytes) - todo);
-+
-+    for (done = 0; done < num_k_bytes;) {
-+        if (RAND_bytes(random_bytes, sizeof(random_bytes)) != 1)
-+            goto err;
-+        SHA512_Init(&sha);
-+        SHA512_Update(&sha, &done, sizeof(done));
-+        SHA512_Update(&sha, private_bytes, sizeof(private_bytes));
-+        SHA512_Update(&sha, message, message_len);
-+        SHA512_Update(&sha, random_bytes, sizeof(random_bytes));
-+        SHA512_Final(digest, &sha);
-+
-+        todo = num_k_bytes - done;
-+        if (todo > SHA512_DIGEST_LENGTH)
-+            todo = SHA512_DIGEST_LENGTH;
-+        memcpy(k_bytes + done, digest, todo);
-+        done += todo;
-+    }
-+
-+    if (!BN_bin2bn(k_bytes, num_k_bytes, out))
-+        goto err;
-+    if (BN_mod(out, out, range, ctx) != 1)
-+        goto err;
-+    ret = 1;
-+
-+ err:
-+    OPENSSL_free(k_bytes);
-+    OPENSSL_cleanse(private_bytes, sizeof(private_bytes));
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_recp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_recp.c
-new file mode 100644
-index 0000000..20585b9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_recp.c
-@@ -0,0 +1,199 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+void BN_RECP_CTX_init(BN_RECP_CTX *recp)
-+{
-+    memset(recp, 0, sizeof(*recp));
-+    bn_init(&(recp->N));
-+    bn_init(&(recp->Nr));
-+}
-+
-+BN_RECP_CTX *BN_RECP_CTX_new(void)
-+{
-+    BN_RECP_CTX *ret;
-+
-+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
-+        return (NULL);
-+
-+    bn_init(&(ret->N));
-+    bn_init(&(ret->Nr));
-+    ret->flags = BN_FLG_MALLOCED;
-+    return (ret);
-+}
-+
-+void BN_RECP_CTX_free(BN_RECP_CTX *recp)
-+{
-+    if (recp == NULL)
-+        return;
-+
-+    BN_free(&(recp->N));
-+    BN_free(&(recp->Nr));
-+    if (recp->flags & BN_FLG_MALLOCED)
-+        OPENSSL_free(recp);
-+}
-+
-+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
-+{
-+    if (!BN_copy(&(recp->N), d))
-+        return 0;
-+    BN_zero(&(recp->Nr));
-+    recp->num_bits = BN_num_bits(d);
-+    recp->shift = 0;
-+    return (1);
-+}
-+
-+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
-+                          BN_RECP_CTX *recp, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BIGNUM *a;
-+    const BIGNUM *ca;
-+
-+    BN_CTX_start(ctx);
-+    if ((a = BN_CTX_get(ctx)) == NULL)
-+        goto err;
-+    if (y != NULL) {
-+        if (x == y) {
-+            if (!BN_sqr(a, x, ctx))
-+                goto err;
-+        } else {
-+            if (!BN_mul(a, x, y, ctx))
-+                goto err;
-+        }
-+        ca = a;
-+    } else
-+        ca = x;                 /* Just do the mod */
-+
-+    ret = BN_div_recp(NULL, r, ca, recp, ctx);
-+ err:
-+    BN_CTX_end(ctx);
-+    bn_check_top(r);
-+    return (ret);
-+}
-+
-+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
-+                BN_RECP_CTX *recp, BN_CTX *ctx)
-+{
-+    int i, j, ret = 0;
-+    BIGNUM *a, *b, *d, *r;
-+
-+    BN_CTX_start(ctx);
-+    a = BN_CTX_get(ctx);
-+    b = BN_CTX_get(ctx);
-+    if (dv != NULL)
-+        d = dv;
-+    else
-+        d = BN_CTX_get(ctx);
-+    if (rem != NULL)
-+        r = rem;
-+    else
-+        r = BN_CTX_get(ctx);
-+    if (a == NULL || b == NULL || d == NULL || r == NULL)
-+        goto err;
-+
-+    if (BN_ucmp(m, &(recp->N)) < 0) {
-+        BN_zero(d);
-+        if (!BN_copy(r, m)) {
-+            BN_CTX_end(ctx);
-+            return 0;
-+        }
-+        BN_CTX_end(ctx);
-+        return (1);
-+    }
-+
-+    /*
-+     * We want the remainder Given input of ABCDEF / ab we need multiply
-+     * ABCDEF by 3 digests of the reciprocal of ab
-+     */
-+
-+    /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
-+    i = BN_num_bits(m);
-+    j = recp->num_bits << 1;
-+    if (j > i)
-+        i = j;
-+
-+    /* Nr := round(2^i / N) */
-+    if (i != recp->shift)
-+        recp->shift = BN_reciprocal(&(recp->Nr), &(recp->N), i, ctx);
-+    /* BN_reciprocal could have returned -1 for an error */
-+    if (recp->shift == -1)
-+        goto err;
-+
-+    /*-
-+     * d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
-+     *    = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
-+     *   <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
-+     *    = |m/N|
-+     */
-+    if (!BN_rshift(a, m, recp->num_bits))
-+        goto err;
-+    if (!BN_mul(b, a, &(recp->Nr), ctx))
-+        goto err;
-+    if (!BN_rshift(d, b, i - recp->num_bits))
-+        goto err;
-+    d->neg = 0;
-+
-+    if (!BN_mul(b, &(recp->N), d, ctx))
-+        goto err;
-+    if (!BN_usub(r, m, b))
-+        goto err;
-+    r->neg = 0;
-+
-+    j = 0;
-+    while (BN_ucmp(r, &(recp->N)) >= 0) {
-+        if (j++ > 2) {
-+            BNerr(BN_F_BN_DIV_RECP, BN_R_BAD_RECIPROCAL);
-+            goto err;
-+        }
-+        if (!BN_usub(r, r, &(recp->N)))
-+            goto err;
-+        if (!BN_add_word(d, 1))
-+            goto err;
-+    }
-+
-+    r->neg = BN_is_zero(r) ? 0 : m->neg;
-+    d->neg = m->neg ^ recp->N.neg;
-+    ret = 1;
-+ err:
-+    BN_CTX_end(ctx);
-+    bn_check_top(dv);
-+    bn_check_top(rem);
-+    return (ret);
-+}
-+
-+/*
-+ * len is the expected size of the result We actually calculate with an extra
-+ * word of precision, so we can do faster division if the remainder is not
-+ * required.
-+ */
-+/* r := 2^len / m */
-+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
-+{
-+    int ret = -1;
-+    BIGNUM *t;
-+
-+    BN_CTX_start(ctx);
-+    if ((t = BN_CTX_get(ctx)) == NULL)
-+        goto err;
-+
-+    if (!BN_set_bit(t, len))
-+        goto err;
-+
-+    if (!BN_div(r, NULL, t, m, ctx))
-+        goto err;
-+
-+    ret = len;
-+ err:
-+    bn_check_top(r);
-+    BN_CTX_end(ctx);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_shift.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_shift.c
-new file mode 100644
-index 0000000..6a1eec8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_shift.c
-@@ -0,0 +1,175 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+int BN_lshift1(BIGNUM *r, const BIGNUM *a)
-+{
-+    register BN_ULONG *ap, *rp, t, c;
-+    int i;
-+
-+    bn_check_top(r);
-+    bn_check_top(a);
-+
-+    if (r != a) {
-+        r->neg = a->neg;
-+        if (bn_wexpand(r, a->top + 1) == NULL)
-+            return (0);
-+        r->top = a->top;
-+    } else {
-+        if (bn_wexpand(r, a->top + 1) == NULL)
-+            return (0);
-+    }
-+    ap = a->d;
-+    rp = r->d;
-+    c = 0;
-+    for (i = 0; i < a->top; i++) {
-+        t = *(ap++);
-+        *(rp++) = ((t << 1) | c) & BN_MASK2;
-+        c = (t & BN_TBIT) ? 1 : 0;
-+    }
-+    if (c) {
-+        *rp = 1;
-+        r->top++;
-+    }
-+    bn_check_top(r);
-+    return (1);
-+}
-+
-+int BN_rshift1(BIGNUM *r, const BIGNUM *a)
-+{
-+    BN_ULONG *ap, *rp, t, c;
-+    int i, j;
-+
-+    bn_check_top(r);
-+    bn_check_top(a);
-+
-+    if (BN_is_zero(a)) {
-+        BN_zero(r);
-+        return (1);
-+    }
-+    i = a->top;
-+    ap = a->d;
-+    j = i - (ap[i - 1] == 1);
-+    if (a != r) {
-+        if (bn_wexpand(r, j) == NULL)
-+            return (0);
-+        r->neg = a->neg;
-+    }
-+    rp = r->d;
-+    t = ap[--i];
-+    c = (t & 1) ? BN_TBIT : 0;
-+    if (t >>= 1)
-+        rp[i] = t;
-+    while (i > 0) {
-+        t = ap[--i];
-+        rp[i] = ((t >> 1) & BN_MASK2) | c;
-+        c = (t & 1) ? BN_TBIT : 0;
-+    }
-+    r->top = j;
-+    if (!r->top)
-+        r->neg = 0; /* don't allow negative zero */
-+    bn_check_top(r);
-+    return (1);
-+}
-+
-+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
-+{
-+    int i, nw, lb, rb;
-+    BN_ULONG *t, *f;
-+    BN_ULONG l;
-+
-+    bn_check_top(r);
-+    bn_check_top(a);
-+
-+    if (n < 0) {
-+        BNerr(BN_F_BN_LSHIFT, BN_R_INVALID_SHIFT);
-+        return 0;
-+    }
-+
-+    nw = n / BN_BITS2;
-+    if (bn_wexpand(r, a->top + nw + 1) == NULL)
-+        return (0);
-+    r->neg = a->neg;
-+    lb = n % BN_BITS2;
-+    rb = BN_BITS2 - lb;
-+    f = a->d;
-+    t = r->d;
-+    t[a->top + nw] = 0;
-+    if (lb == 0)
-+        for (i = a->top - 1; i >= 0; i--)
-+            t[nw + i] = f[i];
-+    else
-+        for (i = a->top - 1; i >= 0; i--) {
-+            l = f[i];
-+            t[nw + i + 1] |= (l >> rb) & BN_MASK2;
-+            t[nw + i] = (l << lb) & BN_MASK2;
-+        }
-+    memset(t, 0, sizeof(*t) * nw);
-+    r->top = a->top + nw + 1;
-+    bn_correct_top(r);
-+    bn_check_top(r);
-+    return (1);
-+}
-+
-+int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
-+{
-+    int i, j, nw, lb, rb;
-+    BN_ULONG *t, *f;
-+    BN_ULONG l, tmp;
-+
-+    bn_check_top(r);
-+    bn_check_top(a);
-+
-+    if (n < 0) {
-+        BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT);
-+        return 0;
-+    }
-+
-+    nw = n / BN_BITS2;
-+    rb = n % BN_BITS2;
-+    lb = BN_BITS2 - rb;
-+    if (nw >= a->top || a->top == 0) {
-+        BN_zero(r);
-+        return (1);
-+    }
-+    i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2;
-+    if (r != a) {
-+        if (bn_wexpand(r, i) == NULL)
-+            return (0);
-+        r->neg = a->neg;
-+    } else {
-+        if (n == 0)
-+            return 1;           /* or the copying loop will go berserk */
-+    }
-+
-+    f = &(a->d[nw]);
-+    t = r->d;
-+    j = a->top - nw;
-+    r->top = i;
-+
-+    if (rb == 0) {
-+        for (i = j; i != 0; i--)
-+            *(t++) = *(f++);
-+    } else {
-+        l = *(f++);
-+        for (i = j - 1; i != 0; i--) {
-+            tmp = (l >> rb) & BN_MASK2;
-+            l = *(f++);
-+            *(t++) = (tmp | (l << lb)) & BN_MASK2;
-+        }
-+        if ((l = (l >> rb) & BN_MASK2))
-+            *(t) = l;
-+    }
-+    if (!r->top)
-+        r->neg = 0; /* don't allow negative zero */
-+    bn_check_top(r);
-+    return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqr.c
-new file mode 100644
-index 0000000..44e7332
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqr.c
-@@ -0,0 +1,235 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+/* r must not be a */
-+/*
-+ * I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96
-+ */
-+int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
-+{
-+    int max, al;
-+    int ret = 0;
-+    BIGNUM *tmp, *rr;
-+
-+    bn_check_top(a);
-+
-+    al = a->top;
-+    if (al <= 0) {
-+        r->top = 0;
-+        r->neg = 0;
-+        return 1;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    rr = (a != r) ? r : BN_CTX_get(ctx);
-+    tmp = BN_CTX_get(ctx);
-+    if (!rr || !tmp)
-+        goto err;
-+
-+    max = 2 * al;               /* Non-zero (from above) */
-+    if (bn_wexpand(rr, max) == NULL)
-+        goto err;
-+
-+    if (al == 4) {
-+#ifndef BN_SQR_COMBA
-+        BN_ULONG t[8];
-+        bn_sqr_normal(rr->d, a->d, 4, t);
-+#else
-+        bn_sqr_comba4(rr->d, a->d);
-+#endif
-+    } else if (al == 8) {
-+#ifndef BN_SQR_COMBA
-+        BN_ULONG t[16];
-+        bn_sqr_normal(rr->d, a->d, 8, t);
-+#else
-+        bn_sqr_comba8(rr->d, a->d);
-+#endif
-+    } else {
-+#if defined(BN_RECURSION)
-+        if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {
-+            BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2];
-+            bn_sqr_normal(rr->d, a->d, al, t);
-+        } else {
-+            int j, k;
-+
-+            j = BN_num_bits_word((BN_ULONG)al);
-+            j = 1 << (j - 1);
-+            k = j + j;
-+            if (al == j) {
-+                if (bn_wexpand(tmp, k * 2) == NULL)
-+                    goto err;
-+                bn_sqr_recursive(rr->d, a->d, al, tmp->d);
-+            } else {
-+                if (bn_wexpand(tmp, max) == NULL)
-+                    goto err;
-+                bn_sqr_normal(rr->d, a->d, al, tmp->d);
-+            }
-+        }
-+#else
-+        if (bn_wexpand(tmp, max) == NULL)
-+            goto err;
-+        bn_sqr_normal(rr->d, a->d, al, tmp->d);
-+#endif
-+    }
-+
-+    rr->neg = 0;
-+    /*
-+     * If the most-significant half of the top word of 'a' is zero, then the
-+     * square of 'a' will max-1 words.
-+     */
-+    if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
-+        rr->top = max - 1;
-+    else
-+        rr->top = max;
-+    if (r != rr && BN_copy(r, rr) == NULL)
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    bn_check_top(rr);
-+    bn_check_top(tmp);
-+    BN_CTX_end(ctx);
-+    return (ret);
-+}
-+
-+/* tmp must have 2*n words */
-+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
-+{
-+    int i, j, max;
-+    const BN_ULONG *ap;
-+    BN_ULONG *rp;
-+
-+    max = n * 2;
-+    ap = a;
-+    rp = r;
-+    rp[0] = rp[max - 1] = 0;
-+    rp++;
-+    j = n;
-+
-+    if (--j > 0) {
-+        ap++;
-+        rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
-+        rp += 2;
-+    }
-+
-+    for (i = n - 2; i > 0; i--) {
-+        j--;
-+        ap++;
-+        rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
-+        rp += 2;
-+    }
-+
-+    bn_add_words(r, r, r, max);
-+
-+    /* There will not be a carry */
-+
-+    bn_sqr_words(tmp, a, n);
-+
-+    bn_add_words(r, r, tmp, max);
-+}
-+
-+#ifdef BN_RECURSION
-+/*-
-+ * r is 2*n words in size,
-+ * a and b are both n words in size.    (There's not actually a 'b' here ...)
-+ * n must be a power of 2.
-+ * We multiply and return the result.
-+ * t must be 2*n words in size
-+ * We calculate
-+ * a[0]*b[0]
-+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
-+ * a[1]*b[1]
-+ */
-+void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
-+{
-+    int n = n2 / 2;
-+    int zero, c1;
-+    BN_ULONG ln, lo, *p;
-+
-+    if (n2 == 4) {
-+# ifndef BN_SQR_COMBA
-+        bn_sqr_normal(r, a, 4, t);
-+# else
-+        bn_sqr_comba4(r, a);
-+# endif
-+        return;
-+    } else if (n2 == 8) {
-+# ifndef BN_SQR_COMBA
-+        bn_sqr_normal(r, a, 8, t);
-+# else
-+        bn_sqr_comba8(r, a);
-+# endif
-+        return;
-+    }
-+    if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) {
-+        bn_sqr_normal(r, a, n2, t);
-+        return;
-+    }
-+    /* r=(a[0]-a[1])*(a[1]-a[0]) */
-+    c1 = bn_cmp_words(a, &(a[n]), n);
-+    zero = 0;
-+    if (c1 > 0)
-+        bn_sub_words(t, a, &(a[n]), n);
-+    else if (c1 < 0)
-+        bn_sub_words(t, &(a[n]), a, n);
-+    else
-+        zero = 1;
-+
-+    /* The result will always be negative unless it is zero */
-+    p = &(t[n2 * 2]);
-+
-+    if (!zero)
-+        bn_sqr_recursive(&(t[n2]), t, n, p);
-+    else
-+        memset(&t[n2], 0, sizeof(*t) * n2);
-+    bn_sqr_recursive(r, a, n, p);
-+    bn_sqr_recursive(&(r[n2]), &(a[n]), n, p);
-+
-+    /*-
-+     * t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
-+     * r[10] holds (a[0]*b[0])
-+     * r[32] holds (b[1]*b[1])
-+     */
-+
-+    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
-+
-+    /* t[32] is negative */
-+    c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
-+
-+    /*-
-+     * t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
-+     * r[10] holds (a[0]*a[0])
-+     * r[32] holds (a[1]*a[1])
-+     * c1 holds the carry bits
-+     */
-+    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
-+    if (c1) {
-+        p = &(r[n + n2]);
-+        lo = *p;
-+        ln = (lo + c1) & BN_MASK2;
-+        *p = ln;
-+
-+        /*
-+         * The overflow will stop before we over write words we should not
-+         * overwrite
-+         */
-+        if (ln < (BN_ULONG)c1) {
-+            do {
-+                p++;
-+                lo = *p;
-+                ln = (lo + 1) & BN_MASK2;
-+                *p = ln;
-+            } while (ln == 0);
-+        }
-+    }
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqrt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqrt.c
-new file mode 100644
-index 0000000..84376c7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_sqrt.c
-@@ -0,0 +1,358 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
-+/*
-+ * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks
-+ * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number
-+ * Theory", algorithm 1.5.1). 'p' must be prime!
-+ */
-+{
-+    BIGNUM *ret = in;
-+    int err = 1;
-+    int r;
-+    BIGNUM *A, *b, *q, *t, *x, *y;
-+    int e, i, j;
-+
-+    if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) {
-+        if (BN_abs_is_word(p, 2)) {
-+            if (ret == NULL)
-+                ret = BN_new();
-+            if (ret == NULL)
-+                goto end;
-+            if (!BN_set_word(ret, BN_is_bit_set(a, 0))) {
-+                if (ret != in)
-+                    BN_free(ret);
-+                return NULL;
-+            }
-+            bn_check_top(ret);
-+            return ret;
-+        }
-+
-+        BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
-+        return (NULL);
-+    }
-+
-+    if (BN_is_zero(a) || BN_is_one(a)) {
-+        if (ret == NULL)
-+            ret = BN_new();
-+        if (ret == NULL)
-+            goto end;
-+        if (!BN_set_word(ret, BN_is_one(a))) {
-+            if (ret != in)
-+                BN_free(ret);
-+            return NULL;
-+        }
-+        bn_check_top(ret);
-+        return ret;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    A = BN_CTX_get(ctx);
-+    b = BN_CTX_get(ctx);
-+    q = BN_CTX_get(ctx);
-+    t = BN_CTX_get(ctx);
-+    x = BN_CTX_get(ctx);
-+    y = BN_CTX_get(ctx);
-+    if (y == NULL)
-+        goto end;
-+
-+    if (ret == NULL)
-+        ret = BN_new();
-+    if (ret == NULL)
-+        goto end;
-+
-+    /* A = a mod p */
-+    if (!BN_nnmod(A, a, p, ctx))
-+        goto end;
-+
-+    /* now write  |p| - 1  as  2^e*q  where  q  is odd */
-+    e = 1;
-+    while (!BN_is_bit_set(p, e))
-+        e++;
-+    /* we'll set  q  later (if needed) */
-+
-+    if (e == 1) {
-+        /*-
-+         * The easy case:  (|p|-1)/2  is odd, so 2 has an inverse
-+         * modulo  (|p|-1)/2,  and square roots can be computed
-+         * directly by modular exponentiation.
-+         * We have
-+         *     2 * (|p|+1)/4 == 1   (mod (|p|-1)/2),
-+         * so we can use exponent  (|p|+1)/4,  i.e.  (|p|-3)/4 + 1.
-+         */
-+        if (!BN_rshift(q, p, 2))
-+            goto end;
-+        q->neg = 0;
-+        if (!BN_add_word(q, 1))
-+            goto end;
-+        if (!BN_mod_exp(ret, A, q, p, ctx))
-+            goto end;
-+        err = 0;
-+        goto vrfy;
-+    }
-+
-+    if (e == 2) {
-+        /*-
-+         * |p| == 5  (mod 8)
-+         *
-+         * In this case  2  is always a non-square since
-+         * Legendre(2,p) = (-1)^((p^2-1)/8)  for any odd prime.
-+         * So if  a  really is a square, then  2*a  is a non-square.
-+         * Thus for
-+         *      b := (2*a)^((|p|-5)/8),
-+         *      i := (2*a)*b^2
-+         * we have
-+         *     i^2 = (2*a)^((1 + (|p|-5)/4)*2)
-+         *         = (2*a)^((p-1)/2)
-+         *         = -1;
-+         * so if we set
-+         *      x := a*b*(i-1),
-+         * then
-+         *     x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
-+         *         = a^2 * b^2 * (-2*i)
-+         *         = a*(-i)*(2*a*b^2)
-+         *         = a*(-i)*i
-+         *         = a.
-+         *
-+         * (This is due to A.O.L. Atkin,
-+         * ,
-+         * November 1992.)
-+         */
-+
-+        /* t := 2*a */
-+        if (!BN_mod_lshift1_quick(t, A, p))
-+            goto end;
-+
-+        /* b := (2*a)^((|p|-5)/8) */
-+        if (!BN_rshift(q, p, 3))
-+            goto end;
-+        q->neg = 0;
-+        if (!BN_mod_exp(b, t, q, p, ctx))
-+            goto end;
-+
-+        /* y := b^2 */
-+        if (!BN_mod_sqr(y, b, p, ctx))
-+            goto end;
-+
-+        /* t := (2*a)*b^2 - 1 */
-+        if (!BN_mod_mul(t, t, y, p, ctx))
-+            goto end;
-+        if (!BN_sub_word(t, 1))
-+            goto end;
-+
-+        /* x = a*b*t */
-+        if (!BN_mod_mul(x, A, b, p, ctx))
-+            goto end;
-+        if (!BN_mod_mul(x, x, t, p, ctx))
-+            goto end;
-+
-+        if (!BN_copy(ret, x))
-+            goto end;
-+        err = 0;
-+        goto vrfy;
-+    }
-+
-+    /*
-+     * e > 2, so we really have to use the Tonelli/Shanks algorithm. First,
-+     * find some y that is not a square.
-+     */
-+    if (!BN_copy(q, p))
-+        goto end;               /* use 'q' as temp */
-+    q->neg = 0;
-+    i = 2;
-+    do {
-+        /*
-+         * For efficiency, try small numbers first; if this fails, try random
-+         * numbers.
-+         */
-+        if (i < 22) {
-+            if (!BN_set_word(y, i))
-+                goto end;
-+        } else {
-+            if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0))
-+                goto end;
-+            if (BN_ucmp(y, p) >= 0) {
-+                if (!(p->neg ? BN_add : BN_sub) (y, y, p))
-+                    goto end;
-+            }
-+            /* now 0 <= y < |p| */
-+            if (BN_is_zero(y))
-+                if (!BN_set_word(y, i))
-+                    goto end;
-+        }
-+
-+        r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
-+        if (r < -1)
-+            goto end;
-+        if (r == 0) {
-+            /* m divides p */
-+            BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
-+            goto end;
-+        }
-+    }
-+    while (r == 1 && ++i < 82);
-+
-+    if (r != -1) {
-+        /*
-+         * Many rounds and still no non-square -- this is more likely a bug
-+         * than just bad luck. Even if p is not prime, we should have found
-+         * some y such that r == -1.
-+         */
-+        BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
-+        goto end;
-+    }
-+
-+    /* Here's our actual 'q': */
-+    if (!BN_rshift(q, q, e))
-+        goto end;
-+
-+    /*
-+     * Now that we have some non-square, we can find an element of order 2^e
-+     * by computing its q'th power.
-+     */
-+    if (!BN_mod_exp(y, y, q, p, ctx))
-+        goto end;
-+    if (BN_is_one(y)) {
-+        BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
-+        goto end;
-+    }
-+
-+    /*-
-+     * Now we know that (if  p  is indeed prime) there is an integer
-+     * k,  0 <= k < 2^e,  such that
-+     *
-+     *      a^q * y^k == 1   (mod p).
-+     *
-+     * As  a^q  is a square and  y  is not,  k  must be even.
-+     * q+1  is even, too, so there is an element
-+     *
-+     *     X := a^((q+1)/2) * y^(k/2),
-+     *
-+     * and it satisfies
-+     *
-+     *     X^2 = a^q * a     * y^k
-+     *         = a,
-+     *
-+     * so it is the square root that we are looking for.
-+     */
-+
-+    /* t := (q-1)/2  (note that  q  is odd) */
-+    if (!BN_rshift1(t, q))
-+        goto end;
-+
-+    /* x := a^((q-1)/2) */
-+    if (BN_is_zero(t)) {        /* special case: p = 2^e + 1 */
-+        if (!BN_nnmod(t, A, p, ctx))
-+            goto end;
-+        if (BN_is_zero(t)) {
-+            /* special case: a == 0  (mod p) */
-+            BN_zero(ret);
-+            err = 0;
-+            goto end;
-+        } else if (!BN_one(x))
-+            goto end;
-+    } else {
-+        if (!BN_mod_exp(x, A, t, p, ctx))
-+            goto end;
-+        if (BN_is_zero(x)) {
-+            /* special case: a == 0  (mod p) */
-+            BN_zero(ret);
-+            err = 0;
-+            goto end;
-+        }
-+    }
-+
-+    /* b := a*x^2  (= a^q) */
-+    if (!BN_mod_sqr(b, x, p, ctx))
-+        goto end;
-+    if (!BN_mod_mul(b, b, A, p, ctx))
-+        goto end;
-+
-+    /* x := a*x    (= a^((q+1)/2)) */
-+    if (!BN_mod_mul(x, x, A, p, ctx))
-+        goto end;
-+
-+    while (1) {
-+        /*-
-+         * Now  b  is  a^q * y^k  for some even  k  (0 <= k < 2^E
-+         * where  E  refers to the original value of  e,  which we
-+         * don't keep in a variable),  and  x  is  a^((q+1)/2) * y^(k/2).
-+         *
-+         * We have  a*b = x^2,
-+         *    y^2^(e-1) = -1,
-+         *    b^2^(e-1) = 1.
-+         */
-+
-+        if (BN_is_one(b)) {
-+            if (!BN_copy(ret, x))
-+                goto end;
-+            err = 0;
-+            goto vrfy;
-+        }
-+
-+        /* find smallest  i  such that  b^(2^i) = 1 */
-+        i = 1;
-+        if (!BN_mod_sqr(t, b, p, ctx))
-+            goto end;
-+        while (!BN_is_one(t)) {
-+            i++;
-+            if (i == e) {
-+                BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
-+                goto end;
-+            }
-+            if (!BN_mod_mul(t, t, t, p, ctx))
-+                goto end;
-+        }
-+
-+        /* t := y^2^(e - i - 1) */
-+        if (!BN_copy(t, y))
-+            goto end;
-+        for (j = e - i - 1; j > 0; j--) {
-+            if (!BN_mod_sqr(t, t, p, ctx))
-+                goto end;
-+        }
-+        if (!BN_mod_mul(y, t, t, p, ctx))
-+            goto end;
-+        if (!BN_mod_mul(x, x, t, p, ctx))
-+            goto end;
-+        if (!BN_mod_mul(b, b, y, p, ctx))
-+            goto end;
-+        e = i;
-+    }
-+
-+ vrfy:
-+    if (!err) {
-+        /*
-+         * verify the result -- the input might have been not a square (test
-+         * added in 0.9.8)
-+         */
-+
-+        if (!BN_mod_sqr(x, ret, p, ctx))
-+            err = 1;
-+
-+        if (!err && 0 != BN_cmp(x, A)) {
-+            BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
-+            err = 1;
-+        }
-+    }
-+
-+ end:
-+    if (err) {
-+        if (ret != in)
-+            BN_clear_free(ret);
-+        ret = NULL;
-+    }
-+    BN_CTX_end(ctx);
-+    bn_check_top(ret);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_srp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_srp.c
-new file mode 100644
-index 0000000..58b1691
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_srp.c
-@@ -0,0 +1,545 @@
-+/*
-+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "bn_lcl.h"
-+#include "e_os.h"
-+
-+#ifndef OPENSSL_NO_SRP
-+
-+#include 
-+#include 
-+
-+# if (BN_BYTES == 8)
-+#  if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
-+#   define bn_pack4(a1,a2,a3,a4) ((a1##UI64<<48)|(a2##UI64<<32)|(a3##UI64<<16)|a4##UI64)
-+#  elif defined(__arch64__)
-+#   define bn_pack4(a1,a2,a3,a4) ((a1##UL<<48)|(a2##UL<<32)|(a3##UL<<16)|a4##UL)
-+#  else
-+#   define bn_pack4(a1,a2,a3,a4) ((a1##ULL<<48)|(a2##ULL<<32)|(a3##ULL<<16)|a4##ULL)
-+#  endif
-+# elif (BN_BYTES == 4)
-+#  define bn_pack4(a1,a2,a3,a4)  ((a3##UL<<16)|a4##UL), ((a1##UL<<16)|a2##UL)
-+# else
-+#  error "unsupported BN_BYTES"
-+# endif
-+
-+static const BN_ULONG bn_group_1024_value[] = {
-+    bn_pack4(0x9FC6, 0x1D2F, 0xC0EB, 0x06E3),
-+    bn_pack4(0xFD51, 0x38FE, 0x8376, 0x435B),
-+    bn_pack4(0x2FD4, 0xCBF4, 0x976E, 0xAA9A),
-+    bn_pack4(0x68ED, 0xBC3C, 0x0572, 0x6CC0),
-+    bn_pack4(0xC529, 0xF566, 0x660E, 0x57EC),
-+    bn_pack4(0x8255, 0x9B29, 0x7BCF, 0x1885),
-+    bn_pack4(0xCE8E, 0xF4AD, 0x69B1, 0x5D49),
-+    bn_pack4(0x5DC7, 0xD7B4, 0x6154, 0xD6B6),
-+    bn_pack4(0x8E49, 0x5C1D, 0x6089, 0xDAD1),
-+    bn_pack4(0xE0D5, 0xD8E2, 0x50B9, 0x8BE4),
-+    bn_pack4(0x383B, 0x4813, 0xD692, 0xC6E0),
-+    bn_pack4(0xD674, 0xDF74, 0x96EA, 0x81D3),
-+    bn_pack4(0x9EA2, 0x314C, 0x9C25, 0x6576),
-+    bn_pack4(0x6072, 0x6187, 0x75FF, 0x3C0B),
-+    bn_pack4(0x9C33, 0xF80A, 0xFA8F, 0xC5E8),
-+    bn_pack4(0xEEAF, 0x0AB9, 0xADB3, 0x8DD6)
-+};
-+
-+const BIGNUM bn_group_1024 = {
-+    (BN_ULONG *)bn_group_1024_value,
-+    OSSL_NELEM(bn_group_1024_value),
-+    OSSL_NELEM(bn_group_1024_value),
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BN_ULONG bn_group_1536_value[] = {
-+    bn_pack4(0xCF76, 0xE3FE, 0xD135, 0xF9BB),
-+    bn_pack4(0x1518, 0x0F93, 0x499A, 0x234D),
-+    bn_pack4(0x8CE7, 0xA28C, 0x2442, 0xC6F3),
-+    bn_pack4(0x5A02, 0x1FFF, 0x5E91, 0x479E),
-+    bn_pack4(0x7F8A, 0x2FE9, 0xB8B5, 0x292E),
-+    bn_pack4(0x837C, 0x264A, 0xE3A9, 0xBEB8),
-+    bn_pack4(0xE442, 0x734A, 0xF7CC, 0xB7AE),
-+    bn_pack4(0x6577, 0x2E43, 0x7D6C, 0x7F8C),
-+    bn_pack4(0xDB2F, 0xD53D, 0x24B7, 0xC486),
-+    bn_pack4(0x6EDF, 0x0195, 0x3934, 0x9627),
-+    bn_pack4(0x158B, 0xFD3E, 0x2B9C, 0x8CF5),
-+    bn_pack4(0x764E, 0x3F4B, 0x53DD, 0x9DA1),
-+    bn_pack4(0x4754, 0x8381, 0xDBC5, 0xB1FC),
-+    bn_pack4(0x9B60, 0x9E0B, 0xE3BA, 0xB63D),
-+    bn_pack4(0x8134, 0xB1C8, 0xB979, 0x8914),
-+    bn_pack4(0xDF02, 0x8A7C, 0xEC67, 0xF0D0),
-+    bn_pack4(0x80B6, 0x55BB, 0x9A22, 0xE8DC),
-+    bn_pack4(0x1558, 0x903B, 0xA0D0, 0xF843),
-+    bn_pack4(0x51C6, 0xA94B, 0xE460, 0x7A29),
-+    bn_pack4(0x5F4F, 0x5F55, 0x6E27, 0xCBDE),
-+    bn_pack4(0xBEEE, 0xA961, 0x4B19, 0xCC4D),
-+    bn_pack4(0xDBA5, 0x1DF4, 0x99AC, 0x4C80),
-+    bn_pack4(0xB1F1, 0x2A86, 0x17A4, 0x7BBB),
-+    bn_pack4(0x9DEF, 0x3CAF, 0xB939, 0x277A)
-+};
-+
-+const BIGNUM bn_group_1536 = {
-+    (BN_ULONG *)bn_group_1536_value,
-+    OSSL_NELEM(bn_group_1536_value),
-+    OSSL_NELEM(bn_group_1536_value),
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BN_ULONG bn_group_2048_value[] = {
-+    bn_pack4(0x0FA7, 0x111F, 0x9E4A, 0xFF73),
-+    bn_pack4(0x9B65, 0xE372, 0xFCD6, 0x8EF2),
-+    bn_pack4(0x35DE, 0x236D, 0x525F, 0x5475),
-+    bn_pack4(0x94B5, 0xC803, 0xD89F, 0x7AE4),
-+    bn_pack4(0x71AE, 0x35F8, 0xE9DB, 0xFBB6),
-+    bn_pack4(0x2A56, 0x98F3, 0xA8D0, 0xC382),
-+    bn_pack4(0x9CCC, 0x041C, 0x7BC3, 0x08D8),
-+    bn_pack4(0xAF87, 0x4E73, 0x03CE, 0x5329),
-+    bn_pack4(0x6160, 0x2790, 0x04E5, 0x7AE6),
-+    bn_pack4(0x032C, 0xFBDB, 0xF52F, 0xB378),
-+    bn_pack4(0x5EA7, 0x7A27, 0x75D2, 0xECFA),
-+    bn_pack4(0x5445, 0x23B5, 0x24B0, 0xD57D),
-+    bn_pack4(0x5B9D, 0x32E6, 0x88F8, 0x7748),
-+    bn_pack4(0xF1D2, 0xB907, 0x8717, 0x461A),
-+    bn_pack4(0x76BD, 0x207A, 0x436C, 0x6481),
-+    bn_pack4(0xCA97, 0xB43A, 0x23FB, 0x8016),
-+    bn_pack4(0x1D28, 0x1E44, 0x6B14, 0x773B),
-+    bn_pack4(0x7359, 0xD041, 0xD5C3, 0x3EA7),
-+    bn_pack4(0xA80D, 0x740A, 0xDBF4, 0xFF74),
-+    bn_pack4(0x55F9, 0x7993, 0xEC97, 0x5EEA),
-+    bn_pack4(0x2918, 0xA996, 0x2F0B, 0x93B8),
-+    bn_pack4(0x661A, 0x05FB, 0xD5FA, 0xAAE8),
-+    bn_pack4(0xCF60, 0x9517, 0x9A16, 0x3AB3),
-+    bn_pack4(0xE808, 0x3969, 0xEDB7, 0x67B0),
-+    bn_pack4(0xCD7F, 0x48A9, 0xDA04, 0xFD50),
-+    bn_pack4(0xD523, 0x12AB, 0x4B03, 0x310D),
-+    bn_pack4(0x8193, 0xE075, 0x7767, 0xA13D),
-+    bn_pack4(0xA373, 0x29CB, 0xB4A0, 0x99ED),
-+    bn_pack4(0xFC31, 0x9294, 0x3DB5, 0x6050),
-+    bn_pack4(0xAF72, 0xB665, 0x1987, 0xEE07),
-+    bn_pack4(0xF166, 0xDE5E, 0x1389, 0x582F),
-+    bn_pack4(0xAC6B, 0xDB41, 0x324A, 0x9A9B)
-+};
-+
-+const BIGNUM bn_group_2048 = {
-+    (BN_ULONG *)bn_group_2048_value,
-+    OSSL_NELEM(bn_group_2048_value),
-+    OSSL_NELEM(bn_group_2048_value),
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BN_ULONG bn_group_3072_value[] = {
-+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF),
-+    bn_pack4(0x4B82, 0xD120, 0xA93A, 0xD2CA),
-+    bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E),
-+    bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31),
-+    bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2),
-+    bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C),
-+    bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C),
-+    bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64),
-+    bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864),
-+    bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B),
-+    bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D),
-+    bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7),
-+    bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7),
-+    bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D),
-+    bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A),
-+    bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64),
-+    bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33),
-+    bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D),
-+    bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510),
-+    bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5),
-+    bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718),
-+    bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9),
-+    bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F),
-+    bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603),
-+    bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B),
-+    bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C),
-+    bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804),
-+    bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D),
-+    bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB),
-+    bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96),
-+    bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F),
-+    bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A),
-+    bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05),
-+    bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D),
-+    bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6),
-+    bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5),
-+    bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED),
-+    bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B),
-+    bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6),
-+    bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245),
-+    bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437),
-+    bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B),
-+    bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD),
-+    bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22),
-+    bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74),
-+    bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1),
-+    bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234),
-+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)
-+};
-+
-+const BIGNUM bn_group_3072 = {
-+    (BN_ULONG *)bn_group_3072_value,
-+    OSSL_NELEM(bn_group_3072_value),
-+    OSSL_NELEM(bn_group_3072_value),
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BN_ULONG bn_group_4096_value[] = {
-+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF),
-+    bn_pack4(0x4DF4, 0x35C9, 0x3406, 0x3199),
-+    bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F),
-+    bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1),
-+    bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9),
-+    bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C),
-+    bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF),
-+    bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED),
-+    bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2),
-+    bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D),
-+    bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6),
-+    bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9),
-+    bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8),
-+    bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA),
-+    bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C),
-+    bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26),
-+    bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7),
-+    bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801),
-+    bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E),
-+    bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31),
-+    bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2),
-+    bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C),
-+    bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C),
-+    bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64),
-+    bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864),
-+    bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B),
-+    bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D),
-+    bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7),
-+    bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7),
-+    bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D),
-+    bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A),
-+    bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64),
-+    bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33),
-+    bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D),
-+    bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510),
-+    bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5),
-+    bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718),
-+    bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9),
-+    bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F),
-+    bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603),
-+    bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B),
-+    bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C),
-+    bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804),
-+    bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D),
-+    bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB),
-+    bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96),
-+    bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F),
-+    bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A),
-+    bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05),
-+    bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D),
-+    bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6),
-+    bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5),
-+    bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED),
-+    bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B),
-+    bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6),
-+    bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245),
-+    bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437),
-+    bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B),
-+    bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD),
-+    bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22),
-+    bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74),
-+    bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1),
-+    bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234),
-+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)
-+};
-+
-+const BIGNUM bn_group_4096 = {
-+    (BN_ULONG *)bn_group_4096_value,
-+    OSSL_NELEM(bn_group_4096_value),
-+    OSSL_NELEM(bn_group_4096_value),
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BN_ULONG bn_group_6144_value[] = {
-+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF),
-+    bn_pack4(0xE694, 0xF91E, 0x6DCC, 0x4024),
-+    bn_pack4(0x12BF, 0x2D5B, 0x0B74, 0x74D6),
-+    bn_pack4(0x043E, 0x8F66, 0x3F48, 0x60EE),
-+    bn_pack4(0x387F, 0xE8D7, 0x6E3C, 0x0468),
-+    bn_pack4(0xDA56, 0xC9EC, 0x2EF2, 0x9632),
-+    bn_pack4(0xEB19, 0xCCB1, 0xA313, 0xD55C),
-+    bn_pack4(0xF550, 0xAA3D, 0x8A1F, 0xBFF0),
-+    bn_pack4(0x06A1, 0xD58B, 0xB7C5, 0xDA76),
-+    bn_pack4(0xA797, 0x15EE, 0xF29B, 0xE328),
-+    bn_pack4(0x14CC, 0x5ED2, 0x0F80, 0x37E0),
-+    bn_pack4(0xCC8F, 0x6D7E, 0xBF48, 0xE1D8),
-+    bn_pack4(0x4BD4, 0x07B2, 0x2B41, 0x54AA),
-+    bn_pack4(0x0F1D, 0x45B7, 0xFF58, 0x5AC5),
-+    bn_pack4(0x23A9, 0x7A7E, 0x36CC, 0x88BE),
-+    bn_pack4(0x59E7, 0xC97F, 0xBEC7, 0xE8F3),
-+    bn_pack4(0xB5A8, 0x4031, 0x900B, 0x1C9E),
-+    bn_pack4(0xD55E, 0x702F, 0x4698, 0x0C82),
-+    bn_pack4(0xF482, 0xD7CE, 0x6E74, 0xFEF6),
-+    bn_pack4(0xF032, 0xEA15, 0xD172, 0x1D03),
-+    bn_pack4(0x5983, 0xCA01, 0xC64B, 0x92EC),
-+    bn_pack4(0x6FB8, 0xF401, 0x378C, 0xD2BF),
-+    bn_pack4(0x3320, 0x5151, 0x2BD7, 0xAF42),
-+    bn_pack4(0xDB7F, 0x1447, 0xE6CC, 0x254B),
-+    bn_pack4(0x44CE, 0x6CBA, 0xCED4, 0xBB1B),
-+    bn_pack4(0xDA3E, 0xDBEB, 0xCF9B, 0x14ED),
-+    bn_pack4(0x1797, 0x27B0, 0x865A, 0x8918),
-+    bn_pack4(0xB06A, 0x53ED, 0x9027, 0xD831),
-+    bn_pack4(0xE5DB, 0x382F, 0x4130, 0x01AE),
-+    bn_pack4(0xF8FF, 0x9406, 0xAD9E, 0x530E),
-+    bn_pack4(0xC975, 0x1E76, 0x3DBA, 0x37BD),
-+    bn_pack4(0xC1D4, 0xDCB2, 0x6026, 0x46DE),
-+    bn_pack4(0x36C3, 0xFAB4, 0xD27C, 0x7026),
-+    bn_pack4(0x4DF4, 0x35C9, 0x3402, 0x8492),
-+    bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F),
-+    bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1),
-+    bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9),
-+    bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C),
-+    bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF),
-+    bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED),
-+    bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2),
-+    bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D),
-+    bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6),
-+    bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9),
-+    bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8),
-+    bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA),
-+    bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C),
-+    bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26),
-+    bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7),
-+    bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801),
-+    bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E),
-+    bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31),
-+    bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2),
-+    bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C),
-+    bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C),
-+    bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64),
-+    bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864),
-+    bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B),
-+    bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D),
-+    bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7),
-+    bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7),
-+    bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D),
-+    bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A),
-+    bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64),
-+    bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33),
-+    bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D),
-+    bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510),
-+    bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5),
-+    bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718),
-+    bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9),
-+    bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F),
-+    bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603),
-+    bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B),
-+    bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C),
-+    bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804),
-+    bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D),
-+    bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB),
-+    bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96),
-+    bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F),
-+    bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A),
-+    bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05),
-+    bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D),
-+    bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6),
-+    bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5),
-+    bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED),
-+    bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B),
-+    bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6),
-+    bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245),
-+    bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437),
-+    bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B),
-+    bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD),
-+    bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22),
-+    bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74),
-+    bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1),
-+    bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234),
-+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)
-+};
-+
-+const BIGNUM bn_group_6144 = {
-+    (BN_ULONG *)bn_group_6144_value,
-+    OSSL_NELEM(bn_group_6144_value),
-+    OSSL_NELEM(bn_group_6144_value),
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BN_ULONG bn_group_8192_value[] = {
-+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF),
-+    bn_pack4(0x60C9, 0x80DD, 0x98ED, 0xD3DF),
-+    bn_pack4(0xC81F, 0x56E8, 0x80B9, 0x6E71),
-+    bn_pack4(0x9E30, 0x50E2, 0x7656, 0x94DF),
-+    bn_pack4(0x9558, 0xE447, 0x5677, 0xE9AA),
-+    bn_pack4(0xC919, 0x0DA6, 0xFC02, 0x6E47),
-+    bn_pack4(0x889A, 0x002E, 0xD5EE, 0x382B),
-+    bn_pack4(0x4009, 0x438B, 0x481C, 0x6CD7),
-+    bn_pack4(0x3590, 0x46F4, 0xEB87, 0x9F92),
-+    bn_pack4(0xFAF3, 0x6BC3, 0x1ECF, 0xA268),
-+    bn_pack4(0xB1D5, 0x10BD, 0x7EE7, 0x4D73),
-+    bn_pack4(0xF9AB, 0x4819, 0x5DED, 0x7EA1),
-+    bn_pack4(0x64F3, 0x1CC5, 0x0846, 0x851D),
-+    bn_pack4(0x4597, 0xE899, 0xA025, 0x5DC1),
-+    bn_pack4(0xDF31, 0x0EE0, 0x74AB, 0x6A36),
-+    bn_pack4(0x6D2A, 0x13F8, 0x3F44, 0xF82D),
-+    bn_pack4(0x062B, 0x3CF5, 0xB3A2, 0x78A6),
-+    bn_pack4(0x7968, 0x3303, 0xED5B, 0xDD3A),
-+    bn_pack4(0xFA9D, 0x4B7F, 0xA2C0, 0x87E8),
-+    bn_pack4(0x4BCB, 0xC886, 0x2F83, 0x85DD),
-+    bn_pack4(0x3473, 0xFC64, 0x6CEA, 0x306B),
-+    bn_pack4(0x13EB, 0x57A8, 0x1A23, 0xF0C7),
-+    bn_pack4(0x2222, 0x2E04, 0xA403, 0x7C07),
-+    bn_pack4(0xE3FD, 0xB8BE, 0xFC84, 0x8AD9),
-+    bn_pack4(0x238F, 0x16CB, 0xE39D, 0x652D),
-+    bn_pack4(0x3423, 0xB474, 0x2BF1, 0xC978),
-+    bn_pack4(0x3AAB, 0x639C, 0x5AE4, 0xF568),
-+    bn_pack4(0x2576, 0xF693, 0x6BA4, 0x2466),
-+    bn_pack4(0x741F, 0xA7BF, 0x8AFC, 0x47ED),
-+    bn_pack4(0x3BC8, 0x32B6, 0x8D9D, 0xD300),
-+    bn_pack4(0xD8BE, 0xC4D0, 0x73B9, 0x31BA),
-+    bn_pack4(0x3877, 0x7CB6, 0xA932, 0xDF8C),
-+    bn_pack4(0x74A3, 0x926F, 0x12FE, 0xE5E4),
-+    bn_pack4(0xE694, 0xF91E, 0x6DBE, 0x1159),
-+    bn_pack4(0x12BF, 0x2D5B, 0x0B74, 0x74D6),
-+    bn_pack4(0x043E, 0x8F66, 0x3F48, 0x60EE),
-+    bn_pack4(0x387F, 0xE8D7, 0x6E3C, 0x0468),
-+    bn_pack4(0xDA56, 0xC9EC, 0x2EF2, 0x9632),
-+    bn_pack4(0xEB19, 0xCCB1, 0xA313, 0xD55C),
-+    bn_pack4(0xF550, 0xAA3D, 0x8A1F, 0xBFF0),
-+    bn_pack4(0x06A1, 0xD58B, 0xB7C5, 0xDA76),
-+    bn_pack4(0xA797, 0x15EE, 0xF29B, 0xE328),
-+    bn_pack4(0x14CC, 0x5ED2, 0x0F80, 0x37E0),
-+    bn_pack4(0xCC8F, 0x6D7E, 0xBF48, 0xE1D8),
-+    bn_pack4(0x4BD4, 0x07B2, 0x2B41, 0x54AA),
-+    bn_pack4(0x0F1D, 0x45B7, 0xFF58, 0x5AC5),
-+    bn_pack4(0x23A9, 0x7A7E, 0x36CC, 0x88BE),
-+    bn_pack4(0x59E7, 0xC97F, 0xBEC7, 0xE8F3),
-+    bn_pack4(0xB5A8, 0x4031, 0x900B, 0x1C9E),
-+    bn_pack4(0xD55E, 0x702F, 0x4698, 0x0C82),
-+    bn_pack4(0xF482, 0xD7CE, 0x6E74, 0xFEF6),
-+    bn_pack4(0xF032, 0xEA15, 0xD172, 0x1D03),
-+    bn_pack4(0x5983, 0xCA01, 0xC64B, 0x92EC),
-+    bn_pack4(0x6FB8, 0xF401, 0x378C, 0xD2BF),
-+    bn_pack4(0x3320, 0x5151, 0x2BD7, 0xAF42),
-+    bn_pack4(0xDB7F, 0x1447, 0xE6CC, 0x254B),
-+    bn_pack4(0x44CE, 0x6CBA, 0xCED4, 0xBB1B),
-+    bn_pack4(0xDA3E, 0xDBEB, 0xCF9B, 0x14ED),
-+    bn_pack4(0x1797, 0x27B0, 0x865A, 0x8918),
-+    bn_pack4(0xB06A, 0x53ED, 0x9027, 0xD831),
-+    bn_pack4(0xE5DB, 0x382F, 0x4130, 0x01AE),
-+    bn_pack4(0xF8FF, 0x9406, 0xAD9E, 0x530E),
-+    bn_pack4(0xC975, 0x1E76, 0x3DBA, 0x37BD),
-+    bn_pack4(0xC1D4, 0xDCB2, 0x6026, 0x46DE),
-+    bn_pack4(0x36C3, 0xFAB4, 0xD27C, 0x7026),
-+    bn_pack4(0x4DF4, 0x35C9, 0x3402, 0x8492),
-+    bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F),
-+    bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1),
-+    bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9),
-+    bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C),
-+    bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF),
-+    bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED),
-+    bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2),
-+    bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D),
-+    bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6),
-+    bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9),
-+    bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8),
-+    bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA),
-+    bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C),
-+    bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26),
-+    bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7),
-+    bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801),
-+    bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E),
-+    bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31),
-+    bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2),
-+    bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C),
-+    bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C),
-+    bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64),
-+    bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864),
-+    bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B),
-+    bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D),
-+    bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7),
-+    bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7),
-+    bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D),
-+    bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A),
-+    bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64),
-+    bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33),
-+    bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D),
-+    bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510),
-+    bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5),
-+    bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718),
-+    bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9),
-+    bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F),
-+    bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603),
-+    bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B),
-+    bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C),
-+    bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804),
-+    bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D),
-+    bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB),
-+    bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96),
-+    bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F),
-+    bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A),
-+    bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05),
-+    bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D),
-+    bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6),
-+    bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5),
-+    bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED),
-+    bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B),
-+    bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6),
-+    bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245),
-+    bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437),
-+    bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B),
-+    bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD),
-+    bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22),
-+    bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74),
-+    bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1),
-+    bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234),
-+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)
-+};
-+
-+const BIGNUM bn_group_8192 = {
-+    (BN_ULONG *)bn_group_8192_value,
-+    OSSL_NELEM(bn_group_8192_value),
-+    OSSL_NELEM(bn_group_8192_value),
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+static const BN_ULONG bn_generator_19_value[] = { 19 };
-+
-+const BIGNUM bn_generator_19 = {
-+    (BN_ULONG *)bn_generator_19_value,
-+    1,
-+    1,
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+static const BN_ULONG bn_generator_5_value[] = { 5 };
-+
-+const BIGNUM bn_generator_5 = {
-+    (BN_ULONG *)bn_generator_5_value,
-+    1,
-+    1,
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+static const BN_ULONG bn_generator_2_value[] = { 2 };
-+
-+const BIGNUM bn_generator_2 = {
-+    (BN_ULONG *)bn_generator_2_value,
-+    1,
-+    1,
-+    0,
-+    BN_FLG_STATIC_DATA
-+};
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_word.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_word.c
-new file mode 100644
-index 0000000..1af13a5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_word.c
-@@ -0,0 +1,201 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "bn_lcl.h"
-+
-+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
-+{
-+#ifndef BN_LLONG
-+    BN_ULONG ret = 0;
-+#else
-+    BN_ULLONG ret = 0;
-+#endif
-+    int i;
-+
-+    if (w == 0)
-+        return (BN_ULONG)-1;
-+
-+#ifndef BN_LLONG
-+    /*
-+     * If |w| is too long and we don't have BN_ULLONG then we need to fall
-+     * back to using BN_div_word
-+     */
-+    if (w > ((BN_ULONG)1 << BN_BITS4)) {
-+        BIGNUM *tmp = BN_dup(a);
-+        if (tmp == NULL)
-+            return (BN_ULONG)-1;
-+
-+        ret = BN_div_word(tmp, w);
-+        BN_free(tmp);
-+
-+        return ret;
-+    }
-+#endif
-+
-+    bn_check_top(a);
-+    w &= BN_MASK2;
-+    for (i = a->top - 1; i >= 0; i--) {
-+#ifndef BN_LLONG
-+        /*
-+         * We can assume here that | w <= ((BN_ULONG)1 << BN_BITS4) | and so
-+         * | ret < ((BN_ULONG)1 << BN_BITS4) | and therefore the shifts here are
-+         * safe and will not overflow
-+         */
-+        ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
-+        ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
-+#else
-+        ret = (BN_ULLONG) (((ret << (BN_ULLONG) BN_BITS2) | a->d[i]) %
-+                           (BN_ULLONG) w);
-+#endif
-+    }
-+    return ((BN_ULONG)ret);
-+}
-+
-+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
-+{
-+    BN_ULONG ret = 0;
-+    int i, j;
-+
-+    bn_check_top(a);
-+    w &= BN_MASK2;
-+
-+    if (!w)
-+        /* actually this an error (division by zero) */
-+        return (BN_ULONG)-1;
-+    if (a->top == 0)
-+        return 0;
-+
-+    /* normalize input (so bn_div_words doesn't complain) */
-+    j = BN_BITS2 - BN_num_bits_word(w);
-+    w <<= j;
-+    if (!BN_lshift(a, a, j))
-+        return (BN_ULONG)-1;
-+
-+    for (i = a->top - 1; i >= 0; i--) {
-+        BN_ULONG l, d;
-+
-+        l = a->d[i];
-+        d = bn_div_words(ret, l, w);
-+        ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2;
-+        a->d[i] = d;
-+    }
-+    if ((a->top > 0) && (a->d[a->top - 1] == 0))
-+        a->top--;
-+    ret >>= j;
-+    if (!a->top)
-+        a->neg = 0; /* don't allow negative zero */
-+    bn_check_top(a);
-+    return (ret);
-+}
-+
-+int BN_add_word(BIGNUM *a, BN_ULONG w)
-+{
-+    BN_ULONG l;
-+    int i;
-+
-+    bn_check_top(a);
-+    w &= BN_MASK2;
-+
-+    /* degenerate case: w is zero */
-+    if (!w)
-+        return 1;
-+    /* degenerate case: a is zero */
-+    if (BN_is_zero(a))
-+        return BN_set_word(a, w);
-+    /* handle 'a' when negative */
-+    if (a->neg) {
-+        a->neg = 0;
-+        i = BN_sub_word(a, w);
-+        if (!BN_is_zero(a))
-+            a->neg = !(a->neg);
-+        return (i);
-+    }
-+    for (i = 0; w != 0 && i < a->top; i++) {
-+        a->d[i] = l = (a->d[i] + w) & BN_MASK2;
-+        w = (w > l) ? 1 : 0;
-+    }
-+    if (w && i == a->top) {
-+        if (bn_wexpand(a, a->top + 1) == NULL)
-+            return 0;
-+        a->top++;
-+        a->d[i] = w;
-+    }
-+    bn_check_top(a);
-+    return (1);
-+}
-+
-+int BN_sub_word(BIGNUM *a, BN_ULONG w)
-+{
-+    int i;
-+
-+    bn_check_top(a);
-+    w &= BN_MASK2;
-+
-+    /* degenerate case: w is zero */
-+    if (!w)
-+        return 1;
-+    /* degenerate case: a is zero */
-+    if (BN_is_zero(a)) {
-+        i = BN_set_word(a, w);
-+        if (i != 0)
-+            BN_set_negative(a, 1);
-+        return i;
-+    }
-+    /* handle 'a' when negative */
-+    if (a->neg) {
-+        a->neg = 0;
-+        i = BN_add_word(a, w);
-+        a->neg = 1;
-+        return (i);
-+    }
-+
-+    if ((a->top == 1) && (a->d[0] < w)) {
-+        a->d[0] = w - a->d[0];
-+        a->neg = 1;
-+        return (1);
-+    }
-+    i = 0;
-+    for (;;) {
-+        if (a->d[i] >= w) {
-+            a->d[i] -= w;
-+            break;
-+        } else {
-+            a->d[i] = (a->d[i] - w) & BN_MASK2;
-+            i++;
-+            w = 1;
-+        }
-+    }
-+    if ((a->d[i] == 0) && (i == (a->top - 1)))
-+        a->top--;
-+    bn_check_top(a);
-+    return (1);
-+}
-+
-+int BN_mul_word(BIGNUM *a, BN_ULONG w)
-+{
-+    BN_ULONG ll;
-+
-+    bn_check_top(a);
-+    w &= BN_MASK2;
-+    if (a->top) {
-+        if (w == 0)
-+            BN_zero(a);
-+        else {
-+            ll = bn_mul_words(a->d, a->d, a->top, w);
-+            if (ll) {
-+                if (bn_wexpand(a, a->top + 1) == NULL)
-+                    return (0);
-+                a->d[a->top++] = ll;
-+            }
-+        }
-+    }
-+    bn_check_top(a);
-+    return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_x931p.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_x931p.c
-new file mode 100644
-index 0000000..40734cb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/bn_x931p.c
-@@ -0,0 +1,238 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "bn_lcl.h"
-+
-+/* X9.31 routines for prime derivation */
-+
-+/*
-+ * X9.31 prime derivation. This is used to generate the primes pi (p1, p2,
-+ * q1, q2) from a parameter Xpi by checking successive odd integers.
-+ */
-+
-+static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx,
-+                             BN_GENCB *cb)
-+{
-+    int i = 0, is_prime;
-+    if (!BN_copy(pi, Xpi))
-+        return 0;
-+    if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
-+        return 0;
-+    for (;;) {
-+        i++;
-+        BN_GENCB_call(cb, 0, i);
-+        /* NB 27 MR is specified in X9.31 */
-+        is_prime = BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb);
-+        if (is_prime < 0)
-+            return 0;
-+        if (is_prime)
-+            break;
-+        if (!BN_add_word(pi, 2))
-+            return 0;
-+    }
-+    BN_GENCB_call(cb, 2, i);
-+    return 1;
-+}
-+
-+/*
-+ * This is the main X9.31 prime derivation function. From parameters Xp1, Xp2
-+ * and Xp derive the prime p. If the parameters p1 or p2 are not NULL they
-+ * will be returned too: this is needed for testing.
-+ */
-+
-+int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
-+                            const BIGNUM *Xp, const BIGNUM *Xp1,
-+                            const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
-+                            BN_GENCB *cb)
-+{
-+    int ret = 0;
-+
-+    BIGNUM *t, *p1p2, *pm1;
-+
-+    /* Only even e supported */
-+    if (!BN_is_odd(e))
-+        return 0;
-+
-+    BN_CTX_start(ctx);
-+    if (!p1)
-+        p1 = BN_CTX_get(ctx);
-+
-+    if (!p2)
-+        p2 = BN_CTX_get(ctx);
-+
-+    t = BN_CTX_get(ctx);
-+
-+    p1p2 = BN_CTX_get(ctx);
-+
-+    pm1 = BN_CTX_get(ctx);
-+
-+    if (pm1 == NULL)
-+        goto err;
-+
-+    if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
-+        goto err;
-+
-+    if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
-+        goto err;
-+
-+    if (!BN_mul(p1p2, p1, p2, ctx))
-+        goto err;
-+
-+    /* First set p to value of Rp */
-+
-+    if (!BN_mod_inverse(p, p2, p1, ctx))
-+        goto err;
-+
-+    if (!BN_mul(p, p, p2, ctx))
-+        goto err;
-+
-+    if (!BN_mod_inverse(t, p1, p2, ctx))
-+        goto err;
-+
-+    if (!BN_mul(t, t, p1, ctx))
-+        goto err;
-+
-+    if (!BN_sub(p, p, t))
-+        goto err;
-+
-+    if (p->neg && !BN_add(p, p, p1p2))
-+        goto err;
-+
-+    /* p now equals Rp */
-+
-+    if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
-+        goto err;
-+
-+    if (!BN_add(p, p, Xp))
-+        goto err;
-+
-+    /* p now equals Yp0 */
-+
-+    for (;;) {
-+        int i = 1;
-+        BN_GENCB_call(cb, 0, i++);
-+        if (!BN_copy(pm1, p))
-+            goto err;
-+        if (!BN_sub_word(pm1, 1))
-+            goto err;
-+        if (!BN_gcd(t, pm1, e, ctx))
-+            goto err;
-+        if (BN_is_one(t)) {
-+            /*
-+             * X9.31 specifies 8 MR and 1 Lucas test or any prime test
-+             * offering similar or better guarantees 50 MR is considerably
-+             * better.
-+             */
-+            int r = BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb);
-+            if (r < 0)
-+                goto err;
-+            if (r)
-+                break;
-+        }
-+        if (!BN_add(p, p, p1p2))
-+            goto err;
-+    }
-+
-+    BN_GENCB_call(cb, 3, 0);
-+
-+    ret = 1;
-+
-+ err:
-+
-+    BN_CTX_end(ctx);
-+
-+    return ret;
-+}
-+
-+/*
-+ * Generate pair of parameters Xp, Xq for X9.31 prime generation. Note: nbits
-+ * parameter is sum of number of bits in both.
-+ */
-+
-+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
-+{
-+    BIGNUM *t;
-+    int i;
-+    /*
-+     * Number of bits for each prime is of the form 512+128s for s = 0, 1,
-+     * ...
-+     */
-+    if ((nbits < 1024) || (nbits & 0xff))
-+        return 0;
-+    nbits >>= 1;
-+    /*
-+     * The random value Xp must be between sqrt(2) * 2^(nbits-1) and 2^nbits
-+     * - 1. By setting the top two bits we ensure that the lower bound is
-+     * exceeded.
-+     */
-+    if (!BN_rand(Xp, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY))
-+        goto err;
-+
-+    BN_CTX_start(ctx);
-+    t = BN_CTX_get(ctx);
-+
-+    for (i = 0; i < 1000; i++) {
-+        if (!BN_rand(Xq, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY))
-+            goto err;
-+        /* Check that |Xp - Xq| > 2^(nbits - 100) */
-+        BN_sub(t, Xp, Xq);
-+        if (BN_num_bits(t) > (nbits - 100))
-+            break;
-+    }
-+
-+    BN_CTX_end(ctx);
-+
-+    if (i < 1000)
-+        return 1;
-+
-+    return 0;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    return 0;
-+}
-+
-+/*
-+ * Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1 and
-+ * Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL the
-+ * relevant parameter will be stored in it. Due to the fact that |Xp - Xq| >
-+ * 2^(nbits - 100) must be satisfied Xp and Xq are generated using the
-+ * previous function and supplied as input.
-+ */
-+
-+int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
-+                              BIGNUM *Xp1, BIGNUM *Xp2,
-+                              const BIGNUM *Xp,
-+                              const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
-+{
-+    int ret = 0;
-+
-+    BN_CTX_start(ctx);
-+    if (!Xp1)
-+        Xp1 = BN_CTX_get(ctx);
-+    if (!Xp2)
-+        Xp2 = BN_CTX_get(ctx);
-+
-+    if (!BN_rand(Xp1, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
-+        goto error;
-+    if (!BN_rand(Xp2, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
-+        goto error;
-+    if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb))
-+        goto error;
-+
-+    ret = 1;
-+
-+ error:
-+    BN_CTX_end(ctx);
-+
-+    return ret;
-+
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/build.info
-new file mode 100644
-index 0000000..c608ecc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/build.info
-@@ -0,0 +1,84 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \
-+        bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
-+        bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c \
-+        {- $target{bn_asm_src} -} \
-+        bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
-+        bn_depr.c bn_const.c bn_x931p.c bn_intern.c bn_dh.c bn_srp.c
-+INCLUDE[../../libcrypto]=../../crypto/include
-+
-+INCLUDE[bn_exp.o]=..
-+
-+GENERATE[bn-586.s]=asm/bn-586.pl \
-+	$(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[bn-586.s]=../perlasm/x86asm.pl
-+GENERATE[co-586.s]=asm/co-586.pl \
-+	$(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[co-586.s]=../perlasm/x86asm.pl
-+GENERATE[x86-mont.s]=asm/x86-mont.pl \
-+	$(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[x86-mont.s]=../perlasm/x86asm.pl
-+GENERATE[x86-gf2m.s]=asm/x86-gf2m.pl \
-+	$(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[x86-gf2m.s]=../perlasm/x86asm.pl
-+
-+GENERATE[sparcv9a-mont.S]=asm/sparcv9a-mont.pl $(PERLASM_SCHEME)
-+INCLUDE[sparcv9a-mont.o]=..
-+GENERATE[sparcv9-mont.S]=asm/sparcv9-mont.pl $(PERLASM_SCHEME)
-+INCLUDE[sparcv9-mont.o]=..
-+GENERATE[vis3-mont.S]=asm/vis3-mont.pl $(PERLASM_SCHEME)
-+INCLUDE[vis3-mont.o]=..
-+GENERATE[sparct4-mont.S]=asm/sparct4-mont.pl $(PERLASM_SCHEME)
-+INCLUDE[sparct4-mont.o]=..
-+GENERATE[sparcv9-gf2m.S]=asm/sparcv9-gf2m.pl $(PERLASM_SCHEME)
-+INCLUDE[sparcv9-gf2m.o]=..
-+
-+GENERATE[bn-mips.s]=asm/mips.pl $(PERLASM_SCHEME)
-+GENERATE[mips-mont.s]=asm/mips-mont.pl $(PERLASM_SCHEME)
-+
-+GENERATE[s390x-mont.S]=asm/s390x-mont.pl $(PERLASM_SCHEME)
-+GENERATE[s390x-gf2m.s]=asm/s390x-gf2m.pl $(PERLASM_SCHEME)
-+
-+GENERATE[x86_64-mont.s]=asm/x86_64-mont.pl $(PERLASM_SCHEME)
-+GENERATE[x86_64-mont5.s]=asm/x86_64-mont5.pl $(PERLASM_SCHEME)
-+GENERATE[x86_64-gf2m.s]=asm/x86_64-gf2m.pl $(PERLASM_SCHEME)
-+GENERATE[rsaz-x86_64.s]=asm/rsaz-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[rsaz-avx2.s]=asm/rsaz-avx2.pl $(PERLASM_SCHEME)
-+
-+GENERATE[bn-ia64.s]=asm/ia64.S
-+GENERATE[ia64-mont.s]=asm/ia64-mont.pl $(CFLAGS) $(LIB_CFLAGS)
-+
-+GENERATE[parisc-mont.s]=asm/parisc-mont.pl $(PERLASM_SCHEME)
-+
-+# ppc - AIX, Linux, MacOS X...
-+GENERATE[bn-ppc.s]=asm/ppc.pl $(PERLASM_SCHEME)
-+GENERATE[ppc-mont.s]=asm/ppc-mont.pl $(PERLASM_SCHEME)
-+GENERATE[ppc64-mont.s]=asm/ppc64-mont.pl $(PERLASM_SCHEME)
-+
-+GENERATE[alpha-mont.S]=asm/alpha-mont.pl $(PERLASM_SCHEME)
-+
-+GENERATE[armv4-mont.S]=asm/armv4-mont.pl $(PERLASM_SCHEME)
-+INCLUDE[armv4-mont.o]=..
-+GENERATE[armv4-gf2m.S]=asm/armv4-gf2m.pl $(PERLASM_SCHEME)
-+INCLUDE[armv4-gf2m.o]=..
-+GENERATE[armv8-mont.S]=asm/armv8-mont.pl $(PERLASM_SCHEME)
-+
-+OVERRIDES=bn-mips3.o pa-risc2W.o pa-risc2.c
-+BEGINRAW[Makefile]
-+##### BN assembler implementations
-+
-+{- $builddir -}/bn-mips3.o:	{- $sourcedir -}/asm/mips3.s
-+	@if [ "$(CC)" = "gcc" ]; then \
-+		ABI=`expr "$(CFLAGS)" : ".*-mabi=\([n3264]*\)"` && \
-+		as -$$ABI -O -o $@ {- $sourcedir -}/asm/mips3.s; \
-+	else	$(CC) -c $(CFLAGS) $(LIB_CFLAGS) -o $@ {- $sourcedir -}/asm/mips3.s; fi
-+
-+# GNU assembler fails to compile PA-RISC2 modules, insist on calling
-+# vendor assembler...
-+{- $builddir -}/pa-risc2W.o: {- $sourcedir -}/asm/pa-risc2W.s
-+	CC="$(CC)" $(PERL) $(SRCDIR)/util/fipsas.pl $(SRCDIR) $< /usr/ccs/bin/as -o pa-risc2W.o {- $sourcedir -}/asm/pa-risc2W.s
-+{- $builddir -}/pa-risc2.o: {- $sourcedir -}/asm/pa-risc2.s
-+	CC="$(CC)" $(PERL) $(SRCDIR)/util/fipsas.pl $(SRCDIR) $< /usr/ccs/bin/as -o pa-risc2.o {- $sourcedir -}/asm/pa-risc2.s
-+
-+ENDRAW[Makefile]
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsaz_exp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsaz_exp.c
-new file mode 100644
-index 0000000..1a70f6c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsaz_exp.c
-@@ -0,0 +1,352 @@
-+/*
-+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*****************************************************************************
-+*                                                                            *
-+*  Copyright (c) 2012, Intel Corporation                                     *
-+*                                                                            *
-+*  All rights reserved.                                                      *
-+*                                                                            *
-+*  Redistribution and use in source and binary forms, with or without        *
-+*  modification, are permitted provided that the following conditions are    *
-+*  met:                                                                      *
-+*                                                                            *
-+*  *  Redistributions of source code must retain the above copyright         *
-+*     notice, this list of conditions and the following disclaimer.          *
-+*                                                                            *
-+*  *  Redistributions in binary form must reproduce the above copyright      *
-+*     notice, this list of conditions and the following disclaimer in the    *
-+*     documentation and/or other materials provided with the                 *
-+*     distribution.                                                          *
-+*                                                                            *
-+*  *  Neither the name of the Intel Corporation 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 INTEL CORPORATION ""AS IS"" AND ANY          *
-+*  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE         *
-+*  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        *
-+*  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR            *
-+*  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     *
-+*  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
-+*  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
-+*  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
-+*  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
-+*  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
-+*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
-+*                                                                            *
-+******************************************************************************
-+* Developers and authors:                                                    *
-+* Shay Gueron (1, 2), and Vlad Krasnov (1)                                   *
-+* (1) Intel Corporation, Israel Development Center, Haifa, Israel            *
-+* (2) University of Haifa, Israel                                            *
-+*****************************************************************************/
-+
-+#include 
-+#include "rsaz_exp.h"
-+
-+#ifndef RSAZ_ENABLED
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+/*
-+ * See crypto/bn/asm/rsaz-avx2.pl for further details.
-+ */
-+void rsaz_1024_norm2red_avx2(void *red, const void *norm);
-+void rsaz_1024_mul_avx2(void *ret, const void *a, const void *b,
-+                        const void *n, BN_ULONG k);
-+void rsaz_1024_sqr_avx2(void *ret, const void *a, const void *n, BN_ULONG k,
-+                        int cnt);
-+void rsaz_1024_scatter5_avx2(void *tbl, const void *val, int i);
-+void rsaz_1024_gather5_avx2(void *val, const void *tbl, int i);
-+void rsaz_1024_red2norm_avx2(void *norm, const void *red);
-+
-+#if defined(__GNUC__)
-+# define ALIGN64        __attribute__((aligned(64)))
-+#elif defined(_MSC_VER)
-+# define ALIGN64        __declspec(align(64))
-+#elif defined(__SUNPRO_C)
-+# define ALIGN64
-+# pragma align 64(one,two80)
-+#else
-+/* not fatal, might hurt performance a little */
-+# define ALIGN64
-+#endif
-+
-+ALIGN64 static const BN_ULONG one[40] = {
-+    1, 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
-+};
-+
-+ALIGN64 static const BN_ULONG two80[40] = {
-+    0, 0, 1 << 22, 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
-+};
-+
-+void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
-+                            const BN_ULONG base_norm[16],
-+                            const BN_ULONG exponent[16],
-+                            const BN_ULONG m_norm[16], const BN_ULONG RR[16],
-+                            BN_ULONG k0)
-+{
-+    unsigned char storage[320 * 3 + 32 * 9 * 16 + 64]; /* 5.5KB */
-+    unsigned char *p_str = storage + (64 - ((size_t)storage % 64));
-+    unsigned char *a_inv, *m, *result;
-+    unsigned char *table_s = p_str + 320 * 3;
-+    unsigned char *R2 = table_s; /* borrow */
-+    int index;
-+    int wvalue;
-+
-+    if ((((size_t)p_str & 4095) + 320) >> 12) {
-+        result = p_str;
-+        a_inv = p_str + 320;
-+        m = p_str + 320 * 2;    /* should not cross page */
-+    } else {
-+        m = p_str;              /* should not cross page */
-+        result = p_str + 320;
-+        a_inv = p_str + 320 * 2;
-+    }
-+
-+    rsaz_1024_norm2red_avx2(m, m_norm);
-+    rsaz_1024_norm2red_avx2(a_inv, base_norm);
-+    rsaz_1024_norm2red_avx2(R2, RR);
-+
-+    rsaz_1024_mul_avx2(R2, R2, R2, m, k0);
-+    rsaz_1024_mul_avx2(R2, R2, two80, m, k0);
-+
-+    /* table[0] = 1 */
-+    rsaz_1024_mul_avx2(result, R2, one, m, k0);
-+    /* table[1] = a_inv^1 */
-+    rsaz_1024_mul_avx2(a_inv, a_inv, R2, m, k0);
-+
-+    rsaz_1024_scatter5_avx2(table_s, result, 0);
-+    rsaz_1024_scatter5_avx2(table_s, a_inv, 1);
-+
-+    /* table[2] = a_inv^2 */
-+    rsaz_1024_sqr_avx2(result, a_inv, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 2);
-+#if 0
-+    /* this is almost 2x smaller and less than 1% slower */
-+    for (index = 3; index < 32; index++) {
-+        rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+        rsaz_1024_scatter5_avx2(table_s, result, index);
-+    }
-+#else
-+    /* table[4] = a_inv^4 */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 4);
-+    /* table[8] = a_inv^8 */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 8);
-+    /* table[16] = a_inv^16 */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 16);
-+    /* table[17] = a_inv^17 */
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 17);
-+
-+    /* table[3] */
-+    rsaz_1024_gather5_avx2(result, table_s, 2);
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 3);
-+    /* table[6] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 6);
-+    /* table[12] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 12);
-+    /* table[24] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 24);
-+    /* table[25] */
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 25);
-+
-+    /* table[5] */
-+    rsaz_1024_gather5_avx2(result, table_s, 4);
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 5);
-+    /* table[10] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 10);
-+    /* table[20] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 20);
-+    /* table[21] */
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 21);
-+
-+    /* table[7] */
-+    rsaz_1024_gather5_avx2(result, table_s, 6);
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 7);
-+    /* table[14] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 14);
-+    /* table[28] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 28);
-+    /* table[29] */
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 29);
-+
-+    /* table[9] */
-+    rsaz_1024_gather5_avx2(result, table_s, 8);
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 9);
-+    /* table[18] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 18);
-+    /* table[19] */
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 19);
-+
-+    /* table[11] */
-+    rsaz_1024_gather5_avx2(result, table_s, 10);
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 11);
-+    /* table[22] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 22);
-+    /* table[23] */
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 23);
-+
-+    /* table[13] */
-+    rsaz_1024_gather5_avx2(result, table_s, 12);
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 13);
-+    /* table[26] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 26);
-+    /* table[27] */
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 27);
-+
-+    /* table[15] */
-+    rsaz_1024_gather5_avx2(result, table_s, 14);
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 15);
-+    /* table[30] */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
-+    rsaz_1024_scatter5_avx2(table_s, result, 30);
-+    /* table[31] */
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    rsaz_1024_scatter5_avx2(table_s, result, 31);
-+#endif
-+
-+    /* load first window */
-+    p_str = (unsigned char *)exponent;
-+    wvalue = p_str[127] >> 3;
-+    rsaz_1024_gather5_avx2(result, table_s, wvalue);
-+
-+    index = 1014;
-+
-+    while (index > -1) {        /* loop for the remaining 127 windows */
-+
-+        rsaz_1024_sqr_avx2(result, result, m, k0, 5);
-+
-+        wvalue = (p_str[(index / 8) + 1] << 8) | p_str[index / 8];
-+        wvalue = (wvalue >> (index % 8)) & 31;
-+        index -= 5;
-+
-+        rsaz_1024_gather5_avx2(a_inv, table_s, wvalue); /* borrow a_inv */
-+        rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+    }
-+
-+    /* square four times */
-+    rsaz_1024_sqr_avx2(result, result, m, k0, 4);
-+
-+    wvalue = p_str[0] & 15;
-+
-+    rsaz_1024_gather5_avx2(a_inv, table_s, wvalue); /* borrow a_inv */
-+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
-+
-+    /* from Montgomery */
-+    rsaz_1024_mul_avx2(result, result, one, m, k0);
-+
-+    rsaz_1024_red2norm_avx2(result_norm, result);
-+
-+    OPENSSL_cleanse(storage, sizeof(storage));
-+}
-+
-+/*
-+ * See crypto/bn/rsaz-x86_64.pl for further details.
-+ */
-+void rsaz_512_mul(void *ret, const void *a, const void *b, const void *n,
-+                  BN_ULONG k);
-+void rsaz_512_mul_scatter4(void *ret, const void *a, const void *n,
-+                           BN_ULONG k, const void *tbl, unsigned int power);
-+void rsaz_512_mul_gather4(void *ret, const void *a, const void *tbl,
-+                          const void *n, BN_ULONG k, unsigned int power);
-+void rsaz_512_mul_by_one(void *ret, const void *a, const void *n, BN_ULONG k);
-+void rsaz_512_sqr(void *ret, const void *a, const void *n, BN_ULONG k,
-+                  int cnt);
-+void rsaz_512_scatter4(void *tbl, const BN_ULONG *val, int power);
-+void rsaz_512_gather4(BN_ULONG *val, const void *tbl, int power);
-+
-+void RSAZ_512_mod_exp(BN_ULONG result[8],
-+                      const BN_ULONG base[8], const BN_ULONG exponent[8],
-+                      const BN_ULONG m[8], BN_ULONG k0, const BN_ULONG RR[8])
-+{
-+    unsigned char storage[16 * 8 * 8 + 64 * 2 + 64]; /* 1.2KB */
-+    unsigned char *table = storage + (64 - ((size_t)storage % 64));
-+    BN_ULONG *a_inv = (BN_ULONG *)(table + 16 * 8 * 8);
-+    BN_ULONG *temp = (BN_ULONG *)(table + 16 * 8 * 8 + 8 * 8);
-+    unsigned char *p_str = (unsigned char *)exponent;
-+    int index;
-+    unsigned int wvalue;
-+
-+    /* table[0] = 1_inv */
-+    temp[0] = 0 - m[0];
-+    temp[1] = ~m[1];
-+    temp[2] = ~m[2];
-+    temp[3] = ~m[3];
-+    temp[4] = ~m[4];
-+    temp[5] = ~m[5];
-+    temp[6] = ~m[6];
-+    temp[7] = ~m[7];
-+    rsaz_512_scatter4(table, temp, 0);
-+
-+    /* table [1] = a_inv^1 */
-+    rsaz_512_mul(a_inv, base, RR, m, k0);
-+    rsaz_512_scatter4(table, a_inv, 1);
-+
-+    /* table [2] = a_inv^2 */
-+    rsaz_512_sqr(temp, a_inv, m, k0, 1);
-+    rsaz_512_scatter4(table, temp, 2);
-+
-+    for (index = 3; index < 16; index++)
-+        rsaz_512_mul_scatter4(temp, a_inv, m, k0, table, index);
-+
-+    /* load first window */
-+    wvalue = p_str[63];
-+
-+    rsaz_512_gather4(temp, table, wvalue >> 4);
-+    rsaz_512_sqr(temp, temp, m, k0, 4);
-+    rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue & 0xf);
-+
-+    for (index = 62; index >= 0; index--) {
-+        wvalue = p_str[index];
-+
-+        rsaz_512_sqr(temp, temp, m, k0, 4);
-+        rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue >> 4);
-+
-+        rsaz_512_sqr(temp, temp, m, k0, 4);
-+        rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue & 0x0f);
-+    }
-+
-+    /* from Montgomery */
-+    rsaz_512_mul_by_one(result, temp, m, k0);
-+
-+    OPENSSL_cleanse(storage, sizeof(storage));
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsaz_exp.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsaz_exp.h
-new file mode 100644
-index 0000000..9501cc8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/bn/rsaz_exp.h
-@@ -0,0 +1,77 @@
-+/*
-+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*****************************************************************************
-+*                                                                            *
-+*  Copyright (c) 2012, Intel Corporation                                     *
-+*                                                                            *
-+*  All rights reserved.                                                      *
-+*                                                                            *
-+*  Redistribution and use in source and binary forms, with or without        *
-+*  modification, are permitted provided that the following conditions are    *
-+*  met:                                                                      *
-+*                                                                            *
-+*  *  Redistributions of source code must retain the above copyright         *
-+*     notice, this list of conditions and the following disclaimer.          *
-+*                                                                            *
-+*  *  Redistributions in binary form must reproduce the above copyright      *
-+*     notice, this list of conditions and the following disclaimer in the    *
-+*     documentation and/or other materials provided with the                 *
-+*     distribution.                                                          *
-+*                                                                            *
-+*  *  Neither the name of the Intel Corporation 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 INTEL CORPORATION ""AS IS"" AND ANY          *
-+*  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE         *
-+*  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        *
-+*  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR            *
-+*  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     *
-+*  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
-+*  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
-+*  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
-+*  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
-+*  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
-+*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
-+*                                                                            *
-+******************************************************************************
-+* Developers and authors:                                                    *
-+* Shay Gueron (1, 2), and Vlad Krasnov (1)                                   *
-+* (1) Intel Corporation, Israel Development Center, Haifa, Israel            *
-+* (2) University of Haifa, Israel                                            *
-+*****************************************************************************/
-+
-+#ifndef RSAZ_EXP_H
-+# define RSAZ_EXP_H
-+
-+# undef RSAZ_ENABLED
-+# if defined(OPENSSL_BN_ASM_MONT) && \
-+        (defined(__x86_64) || defined(__x86_64__) || \
-+         defined(_M_AMD64) || defined(_M_X64))
-+#  define RSAZ_ENABLED
-+
-+#  include 
-+
-+void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16],
-+                            const BN_ULONG base_norm[16],
-+                            const BN_ULONG exponent[16],
-+                            const BN_ULONG m_norm[16], const BN_ULONG RR[16],
-+                            BN_ULONG k0);
-+int rsaz_avx2_eligible();
-+
-+void RSAZ_512_mod_exp(BN_ULONG result[8],
-+                      const BN_ULONG base_norm[8], const BN_ULONG exponent[8],
-+                      const BN_ULONG m_norm[8], BN_ULONG k0,
-+                      const BN_ULONG RR[8]);
-+
-+# endif
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/buf_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/buf_err.c
-new file mode 100644
-index 0000000..a6a2ab8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/buf_err.c
-@@ -0,0 +1,44 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BUF,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BUF,0,reason)
-+
-+static ERR_STRING_DATA BUF_str_functs[] = {
-+    {ERR_FUNC(BUF_F_BUF_MEM_GROW), "BUF_MEM_grow"},
-+    {ERR_FUNC(BUF_F_BUF_MEM_GROW_CLEAN), "BUF_MEM_grow_clean"},
-+    {ERR_FUNC(BUF_F_BUF_MEM_NEW), "BUF_MEM_new"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA BUF_str_reasons[] = {
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_BUF_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(BUF_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, BUF_str_functs);
-+        ERR_load_strings(0, BUF_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/buffer.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/buffer.c
-new file mode 100644
-index 0000000..6b0bd4a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/buffer.c
-@@ -0,0 +1,164 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+/*
-+ * LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
-+ * function is applied in several functions in this file and this limit
-+ * ensures that the result fits in an int.
-+ */
-+#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
-+
-+BUF_MEM *BUF_MEM_new_ex(unsigned long flags)
-+{
-+    BUF_MEM *ret;
-+
-+    ret = BUF_MEM_new();
-+    if (ret != NULL)
-+        ret->flags = flags;
-+    return (ret);
-+}
-+
-+BUF_MEM *BUF_MEM_new(void)
-+{
-+    BUF_MEM *ret;
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL) {
-+        BUFerr(BUF_F_BUF_MEM_NEW, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+    return (ret);
-+}
-+
-+void BUF_MEM_free(BUF_MEM *a)
-+{
-+    if (a == NULL)
-+        return;
-+
-+    if (a->data != NULL) {
-+        if (a->flags & BUF_MEM_FLAG_SECURE)
-+            OPENSSL_secure_free(a->data);
-+        else
-+            OPENSSL_clear_free(a->data, a->max);
-+    }
-+    OPENSSL_free(a);
-+}
-+
-+/* Allocate a block of secure memory; copy over old data if there
-+ * was any, and then free it. */
-+static char *sec_alloc_realloc(BUF_MEM *str, size_t len)
-+{
-+    char *ret;
-+
-+    ret = OPENSSL_secure_malloc(len);
-+    if (str->data != NULL) {
-+        if (ret != NULL)
-+            memcpy(ret, str->data, str->length);
-+        OPENSSL_secure_free(str->data);
-+    }
-+    return (ret);
-+}
-+
-+size_t BUF_MEM_grow(BUF_MEM *str, size_t len)
-+{
-+    char *ret;
-+    size_t n;
-+
-+    if (str->length >= len) {
-+        str->length = len;
-+        return (len);
-+    }
-+    if (str->max >= len) {
-+        if (str->data != NULL)
-+            memset(&str->data[str->length], 0, len - str->length);
-+        str->length = len;
-+        return (len);
-+    }
-+    /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
-+    if (len > LIMIT_BEFORE_EXPANSION) {
-+        BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    n = (len + 3) / 3 * 4;
-+    if ((str->flags & BUF_MEM_FLAG_SECURE))
-+        ret = sec_alloc_realloc(str, n);
-+    else
-+        ret = OPENSSL_realloc(str->data, n);
-+    if (ret == NULL) {
-+        BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE);
-+        len = 0;
-+    } else {
-+        str->data = ret;
-+        str->max = n;
-+        memset(&str->data[str->length], 0, len - str->length);
-+        str->length = len;
-+    }
-+    return (len);
-+}
-+
-+size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
-+{
-+    char *ret;
-+    size_t n;
-+
-+    if (str->length >= len) {
-+        if (str->data != NULL)
-+            memset(&str->data[len], 0, str->length - len);
-+        str->length = len;
-+        return (len);
-+    }
-+    if (str->max >= len) {
-+        memset(&str->data[str->length], 0, len - str->length);
-+        str->length = len;
-+        return (len);
-+    }
-+    /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
-+    if (len > LIMIT_BEFORE_EXPANSION) {
-+        BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    n = (len + 3) / 3 * 4;
-+    if ((str->flags & BUF_MEM_FLAG_SECURE))
-+        ret = sec_alloc_realloc(str, n);
-+    else
-+        ret = OPENSSL_clear_realloc(str->data, str->max, n);
-+    if (ret == NULL) {
-+        BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE);
-+        len = 0;
-+    } else {
-+        str->data = ret;
-+        str->max = n;
-+        memset(&str->data[str->length], 0, len - str->length);
-+        str->length = len;
-+    }
-+    return (len);
-+}
-+
-+void BUF_reverse(unsigned char *out, const unsigned char *in, size_t size)
-+{
-+    size_t i;
-+    if (in) {
-+        out += size - 1;
-+        for (i = 0; i < size; i++)
-+            *out-- = *in++;
-+    } else {
-+        unsigned char *q;
-+        char c;
-+        q = out + size - 1;
-+        for (i = 0; i < size / 2; i++) {
-+            c = *q;
-+            *q-- = *out;
-+            *out++ = c;
-+        }
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/build.info
-new file mode 100644
-index 0000000..54da1f9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/buffer/build.info
-@@ -0,0 +1,2 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=buffer.c buf_err.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/build.info
-new file mode 100644
-index 0000000..916d24f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/build.info
-@@ -0,0 +1,37 @@
-+{- use File::Spec::Functions qw/catdir catfile/; -}
-+LIBS=../libcrypto
-+SOURCE[../libcrypto]=\
-+        cryptlib.c mem.c mem_dbg.c cversion.c ex_data.c cpt_err.c \
-+        ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c \
-+        threads_pthread.c threads_win.c threads_none.c \
-+        o_init.c o_fips.c mem_sec.c init.c {- $target{cpuid_asm_src} -} \
-+        {- $target{uplink_aux_src} -}
-+EXTRA=  ../ms/uplink-x86.pl ../ms/uplink.c ../ms/applink.c \
-+        x86cpuid.pl x86_64cpuid.pl ia64cpuid.S \
-+        ppccpuid.pl pariscid.pl alphacpuid.pl arm64cpuid.pl armv4cpuid.pl
-+
-+DEPEND[cversion.o]=buildinf.h
-+GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(CFLAGS_Q)" "$(PLATFORM)"
-+DEPEND[buildinf.h]=../configdata.pm
-+
-+GENERATE[uplink-x86.s]=../ms/uplink-x86.pl $(PERLASM_SCHEME)
-+GENERATE[uplink-x86_64.s]=../ms/uplink-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[uplink-ia64.s]=../ms/uplink-ia64.pl $(PERLASM_SCHEME)
-+
-+GENERATE[x86cpuid.s]=x86cpuid.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[x86cpuid.s]=perlasm/x86asm.pl
-+
-+GENERATE[x86_64cpuid.s]=x86_64cpuid.pl $(PERLASM_SCHEME)
-+
-+GENERATE[ia64cpuid.s]=ia64cpuid.S
-+GENERATE[ppccpuid.s]=ppccpuid.pl $(PERLASM_SCHEME)
-+GENERATE[pariscid.s]=pariscid.pl $(PERLASM_SCHEME)
-+GENERATE[alphacpuid.s]=alphacpuid.pl
-+GENERATE[arm64cpuid.S]=arm64cpuid.pl $(PERLASM_SCHEME)
-+INCLUDE[arm64cpuid.o]=.
-+GENERATE[armv4cpuid.S]=armv4cpuid.pl $(PERLASM_SCHEME)
-+INCLUDE[armv4cpuid.o]=.
-+
-+IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}]
-+  SHARED_SOURCE[../libcrypto]=dllmain.c
-+ENDIF
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/c64xpluscpuid.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/c64xpluscpuid.pl
-new file mode 100644
-index 0000000..9efe120
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/c64xpluscpuid.pl
-@@ -0,0 +1,287 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+$code.=<<___;
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.asg	OPENSSL_rdtsc,_OPENSSL_rdtsc
-+	.asg	OPENSSL_cleanse,_OPENSSL_cleanse
-+	.asg	CRYPTO_memcmp,_CRYPTO_memcmp
-+	.asg	OPENSSL_atomic_add,_OPENSSL_atomic_add
-+	.asg	OPENSSL_wipe_cpu,_OPENSSL_wipe_cpu
-+	.asg	OPENSSL_instrument_bus,_OPENSSL_instrument_bus
-+	.asg	OPENSSL_instrument_bus2,_OPENSSL_instrument_bus2
-+	.endif
-+
-+	.asg	B3,RA
-+
-+	.global	_OPENSSL_rdtsc
-+_OPENSSL_rdtsc:
-+	.asmfunc
-+	B	RA
-+	MVC	TSCL,B0
-+	MVC	TSCH,B1
-+  [!B0]	MVC	B0,TSCL		; start TSC
-+	MV	B0,A4
-+	MV	B1,A5
-+	.endasmfunc
-+
-+	.global	_OPENSSL_cleanse
-+_OPENSSL_cleanse:
-+	.asmfunc
-+	ZERO	A3:A2
-+||	ZERO	B2
-+||	SHRU	B4,3,B0		; is length >= 8
-+||	ADD	1,A4,B6
-+  [!B0]	BNOP	RA
-+||	ZERO	A1
-+||	ZERO	B1
-+   [B0]	MVC	B0,ILC
-+||[!B0]	CMPLT	0,B4,A1
-+||[!B0]	CMPLT	1,B4,B1
-+   [A1]	STB	A2,*A4++[2]
-+|| [B1] STB	B2,*B6++[2]
-+||[!B0]	CMPLT	2,B4,A1
-+||[!B0]	CMPLT	3,B4,B1
-+   [A1]	STB	A2,*A4++[2]
-+|| [B1] STB	B2,*B6++[2]
-+||[!B0]	CMPLT	4,B4,A1
-+||[!B0]	CMPLT	5,B4,B1
-+   [A1]	STB	A2,*A4++[2]
-+|| [B1] STB	B2,*B6++[2]
-+||[!B0]	CMPLT	6,B4,A1
-+   [A1]	STB	A2,*A4++[2]
-+
-+	SPLOOP	1
-+	STNDW	A3:A2,*A4++
-+||	SUB	B4,8,B4
-+	SPKERNEL
-+
-+	MV	B4,B0		; remaining bytes
-+||	ADD	1,A4,B6
-+||	BNOP	RA
-+   [B0]	CMPLT	0,B0,A1
-+|| [B0]	CMPLT	1,B0,B1
-+   [A1]	STB	A2,*A4++[2]
-+|| [B1] STB	B2,*B6++[2]
-+|| [B0]	CMPLT	2,B0,A1
-+|| [B0]	CMPLT	3,B0,B1
-+   [A1]	STB	A2,*A4++[2]
-+|| [B1] STB	B2,*B6++[2]
-+|| [B0]	CMPLT	4,B0,A1
-+|| [B0]	CMPLT	5,B0,B1
-+   [A1]	STB	A2,*A4++[2]
-+|| [B1] STB	B2,*B6++[2]
-+|| [B0]	CMPLT	6,B0,A1
-+   [A1]	STB	A2,*A4++[2]
-+	.endasmfunc
-+
-+	.global	_CRYPTO_memcmp
-+_CRYPTO_memcmp:
-+	.asmfunc
-+	MV	A6,B0
-+  [!B0]	BNOP	RA
-+||[!B0]	ZERO	A4
-+   [B0]	MVC	B0,ILC
-+|| [B0]	ZERO	A0
-+	NOP	4
-+
-+	SPLOOP	1
-+	LDBU	*A4++,A1
-+||	LDBU	*B4++,B1
-+	NOP	4
-+	XOR.L	B1,A1,A2
-+	SPKERNEL 1,0
-+||	OR.S	A2,A0,A0
-+
-+	BNOP	RA,3
-+	ZERO.L	A4
-+  [A0]	MVK	1,A4
-+	.endasmfunc
-+
-+	.global	_OPENSSL_atomic_add
-+_OPENSSL_atomic_add:
-+	.asmfunc
-+	MV	A4,B0
-+atomic_add?:
-+	LL	*B0,B5
-+	NOP	4
-+	ADD	B4,B5,B5
-+	SL	B5,*B0
-+	CMTL	*B0,B1
-+	NOP	4
-+  [!B1]	B	atomic_add?
-+   [B1]	BNOP	RA,4
-+	MV	B5,A4
-+	.endasmfunc
-+
-+	.global	_OPENSSL_wipe_cpu
-+_OPENSSL_wipe_cpu:
-+	.asmfunc
-+	ZERO	A0
-+||	ZERO	B0
-+||	ZERO	A1
-+||	ZERO	B1
-+	ZERO	A3:A2
-+||	MVD	B0,B2
-+||	ZERO	A4
-+||	ZERO	B4
-+||	ZERO	A5
-+||	ZERO	B5
-+||	BNOP	RA
-+	ZERO	A7:A6
-+||	ZERO	B7:B6
-+||	ZERO	A8
-+||	ZERO	B8
-+||	ZERO	A9
-+||	ZERO	B9
-+	ZERO	A17:A16
-+||	ZERO	B17:B16
-+||	ZERO	A18
-+||	ZERO	B18
-+||	ZERO	A19
-+||	ZERO	B19
-+	ZERO	A21:A20
-+||	ZERO	B21:B20
-+||	ZERO	A22
-+||	ZERO	B22
-+||	ZERO	A23
-+||	ZERO	B23
-+	ZERO	A25:A24
-+||	ZERO	B25:B24
-+||	ZERO	A26
-+||	ZERO	B26
-+||	ZERO	A27
-+||	ZERO	B27
-+	ZERO	A29:A28
-+||	ZERO	B29:B28
-+||	ZERO	A30
-+||	ZERO	B30
-+||	ZERO	A31
-+||	ZERO	B31
-+	.endasmfunc
-+
-+CLFLUSH	.macro	CONTROL,ADDR,LEN
-+	B	passthrough?
-+||	STW	ADDR,*CONTROL[0]
-+	STW	LEN,*CONTROL[1]
-+spinlock?:
-+	LDW	*CONTROL[1],A0
-+	NOP	3
-+passthrough?:
-+	NOP
-+  [A0]	BNOP	spinlock?,5
-+	.endm
-+
-+	.global	_OPENSSL_instrument_bus
-+_OPENSSL_instrument_bus:
-+	.asmfunc
-+	MV	B4,B0			; reassign sizeof(output)
-+||	MV	A4,B4			; reassign output
-+||	MVK	0x00004030,A3
-+	MV	B0,A4			; return value
-+||	MVK	1,A1
-+||	MVKH	0x01840000,A3		; L1DWIBAR
-+	MVC	TSCL,B8			; collect 1st tick
-+||	MVK	0x00004010,A5
-+	MV	B8,B9			; lasttick = tick
-+||	MVK	0,B7			; lastdiff = 0
-+||	MVKH	0x01840000,A5		; L2WIBAR
-+	CLFLUSH	A3,B4,A1		; write-back and invalidate L1D line
-+	CLFLUSH	A5,B4,A1		; write-back and invalidate L2 line
-+	LL	*B4,B5
-+	NOP	4
-+	ADD	B7,B5,B5
-+	SL	B5,*B4
-+	CMTL	*B4,B1
-+	NOP	4
-+	STW	B5,*B4
-+bus_loop1?:
-+	MVC	TSCL,B8
-+|| [B0]	SUB	B0,1,B0
-+	SUB	B8,B9,B7		; lastdiff = tick - lasttick
-+||	MV	B8,B9			; lasttick = tick
-+	CLFLUSH	A3,B4,A1		; write-back and invalidate L1D line
-+	CLFLUSH	A5,B4,A1		; write-back and invalidate L2 line
-+	LL	*B4,B5
-+	NOP	4
-+	ADD	B7,B5,B5
-+	SL	B5,*B4
-+	CMTL	*B4,B1
-+	STW	B5,*B4			; [!B1] is removed to flatten samples
-+||	ADDK	4,B4
-+|| [B0]	BNOP	bus_loop1?,5
-+
-+	BNOP	RA,5
-+	.endasmfunc
-+
-+	.global	_OPENSSL_instrument_bus2
-+_OPENSSL_instrument_bus2:
-+	.asmfunc
-+	MV	A6,B0			; reassign max
-+||	MV	B4,A6			; reassing sizeof(output)
-+||	MVK	0x00004030,A3
-+	MV	A4,B4			; reassign output
-+||	MVK	0,A4			; return value
-+||	MVK	1,A1
-+||	MVKH	0x01840000,A3		; L1DWIBAR
-+
-+	MVC	TSCL,B8			; collect 1st tick
-+||	MVK	0x00004010,A5
-+	MV	B8,B9			; lasttick = tick
-+||	MVK	0,B7			; lastdiff = 0
-+||	MVKH	0x01840000,A5		; L2WIBAR
-+	CLFLUSH	A3,B4,A1		; write-back and invalidate L1D line
-+	CLFLUSH	A5,B4,A1		; write-back and invalidate L2 line
-+	LL	*B4,B5
-+	NOP	4
-+	ADD	B7,B5,B5
-+	SL	B5,*B4
-+	CMTL	*B4,B1
-+	NOP	4
-+	STW	B5,*B4
-+
-+	MVC	TSCL,B8			; collect 1st diff
-+	SUB	B8,B9,B7		; lastdiff = tick - lasttick
-+||	MV	B8,B9			; lasttick = tick
-+||	SUB	B0,1,B0
-+bus_loop2?:
-+	CLFLUSH	A3,B4,A1		; write-back and invalidate L1D line
-+	CLFLUSH	A5,B4,A1		; write-back and invalidate L2 line
-+	LL	*B4,B5
-+	NOP	4
-+	ADD	B7,B5,B5
-+	SL	B5,*B4
-+	CMTL	*B4,B1
-+	STW	B5,*B4			; [!B1] is removed to flatten samples
-+||[!B0]	BNOP	bus_loop2_done?,2
-+||	SUB	B0,1,B0
-+	MVC	TSCL,B8
-+	SUB	B8,B9,B8
-+||	MV	B8,B9
-+	CMPEQ	B8,B7,B2
-+||	MV	B8,B7
-+  [!B2]	ADDAW	B4,1,B4
-+||[!B2]	ADDK	1,A4
-+	CMPEQ	A4,A6,A2
-+  [!A2]	BNOP	bus_loop2?,5
-+
-+bus_loop2_done?:
-+	BNOP	RA,5
-+	.endasmfunc
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmll-x86.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmll-x86.pl
-new file mode 100644
-index 0000000..59f9ed9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmll-x86.pl
-@@ -0,0 +1,1150 @@
-+#! /usr/bin/env perl
-+# Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Copyright (c) 2008 Andy Polyakov 
-+#
-+# This module may be used under the terms of either the GNU General
-+# Public License version 2 or later, the GNU Lesser General Public
-+# License version 2.1 or later, the Mozilla Public License version
-+# 1.1 or the BSD License. The exact terms of either license are
-+# distributed along with this module. For further details see
-+# http://www.openssl.org/~appro/camellia/.
-+# ====================================================================
-+
-+# Performance in cycles per processed byte (less is better) in
-+# 'openssl speed ...' benchmark:
-+#
-+#			AMD K8	Core2	PIII	P4
-+# -evp camellia-128-ecb	21.5	22.8	27.0	28.9
-+# + over gcc 3.4.6	+90/11% +70/10%	+53/4%	+160/64%
-+# + over icc 8.0	+48/19% +21/15%	+21/17%	+55/37%
-+#
-+# camellia-128-cbc	17.3	21.1	23.9	25.9
-+#
-+# 128-bit key setup	196	280	256	240	cycles/key
-+# + over gcc 3.4.6	+30/0%	+17/11%	+11/0%	+63/40%
-+# + over icc 8.0	+18/3%	+10/0%	+10/3%	+21/10%
-+#
-+# Pairs of numbers in "+" rows represent performance improvement over
-+# compiler generated position-independent code, PIC, and non-PIC
-+# respectively. PIC results are of greater relevance, as this module
-+# is position-independent, i.e. suitable for a shared library or PIE.
-+# Position independence "costs" one register, which is why compilers
-+# are so close with non-PIC results, they have an extra register to
-+# spare. CBC results are better than ECB ones thanks to "zero-copy"
-+# private _x86_* interface, and are ~30-40% better than with compiler
-+# generated cmll_cbc.o, and reach ~80-90% of x86_64 performance on
-+# same CPU (where applicable).
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$OPENSSL=1;
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"cmll-586.pl",$ARGV[$#ARGV] eq "386");
-+
-+@T=("eax","ebx","ecx","edx");
-+$idx="esi";
-+$key="edi";
-+$Tbl="ebp";
-+
-+# stack frame layout in _x86_Camellia_* routines, frame is allocated
-+# by caller
-+$__ra=&DWP(0,"esp");	# return address
-+$__s0=&DWP(4,"esp");	# s0 backing store
-+$__s1=&DWP(8,"esp");	# s1 backing store
-+$__s2=&DWP(12,"esp");	# s2 backing store
-+$__s3=&DWP(16,"esp");	# s3 backing store
-+$__end=&DWP(20,"esp");	# pointer to end/start of key schedule
-+
-+# stack frame layout in Camellia_[en|crypt] routines, which differs from
-+# above by 4 and overlaps by pointer to end/start of key schedule
-+$_end=&DWP(16,"esp");
-+$_esp=&DWP(20,"esp");
-+
-+# const unsigned int Camellia_SBOX[4][256];
-+# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
-+# and [2][] - with [3][]. This is done to optimize code size.
-+$SBOX1_1110=0;		# Camellia_SBOX[0]
-+$SBOX4_4404=4;		# Camellia_SBOX[1]
-+$SBOX2_0222=2048;	# Camellia_SBOX[2]
-+$SBOX3_3033=2052;	# Camellia_SBOX[3]
-+&static_label("Camellia_SIGMA");
-+&static_label("Camellia_SBOX");
-+
-+sub Camellia_Feistel {
-+my $i=@_[0];
-+my $seed=defined(@_[1])?@_[1]:0;
-+my $scale=$seed<0?-8:8;
-+my $frame=defined(@_[2])?@_[2]:0;
-+my $j=($i&1)*2;
-+my $t0=@T[($j)%4],$t1=@T[($j+1)%4],$t2=@T[($j+2)%4],$t3=@T[($j+3)%4];
-+
-+	&xor	($t0,$idx);				# t0^=key[0]
-+	&xor	($t1,&DWP($seed+$i*$scale+4,$key));	# t1^=key[1]
-+	&movz	($idx,&HB($t0));			# (t0>>8)&0xff
-+	&mov	($t3,&DWP($SBOX3_3033,$Tbl,$idx,8));	# t3=SBOX3_3033[0]
-+	&movz	($idx,&LB($t0));			# (t0>>0)&0xff
-+	&xor	($t3,&DWP($SBOX4_4404,$Tbl,$idx,8));	# t3^=SBOX4_4404[0]
-+	&shr	($t0,16);
-+	&movz	($idx,&LB($t1));			# (t1>>0)&0xff
-+	&mov	($t2,&DWP($SBOX1_1110,$Tbl,$idx,8));	# t2=SBOX1_1110[1]
-+	&movz	($idx,&HB($t0));			# (t0>>24)&0xff
-+	&xor	($t3,&DWP($SBOX1_1110,$Tbl,$idx,8));	# t3^=SBOX1_1110[0]
-+	&movz	($idx,&HB($t1));			# (t1>>8)&0xff
-+	&xor	($t2,&DWP($SBOX4_4404,$Tbl,$idx,8));	# t2^=SBOX4_4404[1]
-+	&shr	($t1,16);
-+	&movz	($t0,&LB($t0));				# (t0>>16)&0xff
-+	&xor	($t3,&DWP($SBOX2_0222,$Tbl,$t0,8));	# t3^=SBOX2_0222[0]
-+	&movz	($idx,&HB($t1));			# (t1>>24)&0xff
-+	&mov	($t0,&DWP($frame+4*(($j+3)%4),"esp"));	# prefetch "s3"
-+	&xor	($t2,$t3);				# t2^=t3
-+	&rotr	($t3,8);				# t3=RightRotate(t3,8)
-+	&xor	($t2,&DWP($SBOX2_0222,$Tbl,$idx,8));	# t2^=SBOX2_0222[1]
-+	&movz	($idx,&LB($t1));			# (t1>>16)&0xff
-+	&mov	($t1,&DWP($frame+4*(($j+2)%4),"esp"));	# prefetch "s2"
-+	&xor	($t3,$t0);				# t3^=s3
-+	&xor	($t2,&DWP($SBOX3_3033,$Tbl,$idx,8));	# t2^=SBOX3_3033[1]
-+	&mov	($idx,&DWP($seed+($i+1)*$scale,$key));	# prefetch key[i+1]
-+	&xor	($t3,$t2);				# t3^=t2
-+	&mov	(&DWP($frame+4*(($j+3)%4),"esp"),$t3);	# s3=t3
-+	&xor	($t2,$t1);				# t2^=s2
-+	&mov	(&DWP($frame+4*(($j+2)%4),"esp"),$t2);	# s2=t2
-+}
-+
-+# void Camellia_EncryptBlock_Rounds(
-+#		int grandRounds,
-+#		const Byte plaintext[],
-+#		const KEY_TABLE_TYPE keyTable,
-+#		Byte ciphertext[])
-+&function_begin("Camellia_EncryptBlock_Rounds");
-+	&mov	("eax",&wparam(0));	# load grandRounds
-+	&mov	($idx,&wparam(1));	# load plaintext pointer
-+	&mov	($key,&wparam(2));	# load key schedule pointer
-+
-+	&mov	("ebx","esp");
-+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
-+	&and	("esp",-64);
-+
-+	# place stack frame just "above mod 1024" the key schedule
-+	# this ensures that cache associativity of 2 suffices
-+	&lea	("ecx",&DWP(-64-63,$key));
-+	&sub	("ecx","esp");
-+	&neg	("ecx");
-+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
-+	&sub	("esp","ecx");
-+	&add	("esp",4);	# 4 is reserved for callee's return address
-+
-+	&shl	("eax",6);
-+	&lea	("eax",&DWP(0,$key,"eax"));
-+	&mov	($_esp,"ebx");	# save %esp
-+	&mov	($_end,"eax");	# save keyEnd
-+
-+	&call	(&label("pic_point"));
-+	&set_label("pic_point");
-+	&blindpop($Tbl);
-+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-+
-+	&mov	(@T[0],&DWP(0,$idx));	# load plaintext
-+	&mov	(@T[1],&DWP(4,$idx));
-+	&mov	(@T[2],&DWP(8,$idx));
-+	&bswap	(@T[0]);
-+	&mov	(@T[3],&DWP(12,$idx));
-+	&bswap	(@T[1]);
-+	&bswap	(@T[2]);
-+	&bswap	(@T[3]);
-+
-+	&call	("_x86_Camellia_encrypt");
-+
-+	&mov	("esp",$_esp);
-+	&bswap	(@T[0]);
-+	&mov	($idx,&wparam(3));	# load ciphertext pointer
-+	&bswap	(@T[1]);
-+	&bswap	(@T[2]);
-+	&bswap	(@T[3]);
-+	&mov	(&DWP(0,$idx),@T[0]);	# write ciphertext
-+	&mov	(&DWP(4,$idx),@T[1]);
-+	&mov	(&DWP(8,$idx),@T[2]);
-+	&mov	(&DWP(12,$idx),@T[3]);
-+&function_end("Camellia_EncryptBlock_Rounds");
-+# V1.x API
-+&function_begin_B("Camellia_EncryptBlock");
-+	&mov	("eax",128);
-+	&sub	("eax",&wparam(0));	# load keyBitLength
-+	&mov	("eax",3);
-+	&adc	("eax",0);		# keyBitLength==128?3:4
-+	&mov	(&wparam(0),"eax");
-+	&jmp	(&label("Camellia_EncryptBlock_Rounds"));
-+&function_end_B("Camellia_EncryptBlock");
-+
-+if ($OPENSSL) {
-+# void Camellia_encrypt(
-+#		const unsigned char *in,
-+#		unsigned char *out,
-+#		const CAMELLIA_KEY *key)
-+&function_begin("Camellia_encrypt");
-+	&mov	($idx,&wparam(0));	# load plaintext pointer
-+	&mov	($key,&wparam(2));	# load key schedule pointer
-+
-+	&mov	("ebx","esp");
-+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
-+	&and	("esp",-64);
-+	&mov	("eax",&DWP(272,$key));	# load grandRounds counter
-+
-+	# place stack frame just "above mod 1024" the key schedule
-+	# this ensures that cache associativity of 2 suffices
-+	&lea	("ecx",&DWP(-64-63,$key));
-+	&sub	("ecx","esp");
-+	&neg	("ecx");
-+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
-+	&sub	("esp","ecx");
-+	&add	("esp",4);	# 4 is reserved for callee's return address
-+
-+	&shl	("eax",6);
-+	&lea	("eax",&DWP(0,$key,"eax"));
-+	&mov	($_esp,"ebx");	# save %esp
-+	&mov	($_end,"eax");	# save keyEnd
-+
-+	&call	(&label("pic_point"));
-+	&set_label("pic_point");
-+	&blindpop($Tbl);
-+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-+
-+	&mov	(@T[0],&DWP(0,$idx));	# load plaintext
-+	&mov	(@T[1],&DWP(4,$idx));
-+	&mov	(@T[2],&DWP(8,$idx));
-+	&bswap	(@T[0]);
-+	&mov	(@T[3],&DWP(12,$idx));
-+	&bswap	(@T[1]);
-+	&bswap	(@T[2]);
-+	&bswap	(@T[3]);
-+
-+	&call	("_x86_Camellia_encrypt");
-+
-+	&mov	("esp",$_esp);
-+	&bswap	(@T[0]);
-+	&mov	($idx,&wparam(1));	# load ciphertext pointer
-+	&bswap	(@T[1]);
-+	&bswap	(@T[2]);
-+	&bswap	(@T[3]);
-+	&mov	(&DWP(0,$idx),@T[0]);	# write ciphertext
-+	&mov	(&DWP(4,$idx),@T[1]);
-+	&mov	(&DWP(8,$idx),@T[2]);
-+	&mov	(&DWP(12,$idx),@T[3]);
-+&function_end("Camellia_encrypt");
-+}
-+
-+&function_begin_B("_x86_Camellia_encrypt");
-+	&xor	(@T[0],&DWP(0,$key));	# ^=key[0-3]
-+	&xor	(@T[1],&DWP(4,$key));
-+	&xor	(@T[2],&DWP(8,$key));
-+	&xor	(@T[3],&DWP(12,$key));
-+	&mov	($idx,&DWP(16,$key));	# prefetch key[4]
-+
-+	&mov	($__s0,@T[0]);		# save s[0-3]
-+	&mov	($__s1,@T[1]);
-+	&mov	($__s2,@T[2]);
-+	&mov	($__s3,@T[3]);
-+
-+&set_label("loop",16);
-+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16,4); }
-+
-+	&add	($key,16*4);
-+	&cmp	($key,$__end);
-+	&je	(&label("done"));
-+
-+	# @T[0-1] are preloaded, $idx is preloaded with key[0]
-+	&and	($idx,@T[0]);
-+	 &mov	 (@T[3],$__s3);
-+	&rotl	($idx,1);
-+	 &mov	 (@T[2],@T[3]);
-+	&xor	(@T[1],$idx);
-+	 &or	 (@T[2],&DWP(12,$key));
-+	&mov	($__s1,@T[1]);		# s1^=LeftRotate(s0&key[0],1);
-+	 &xor	 (@T[2],$__s2);
-+
-+	&mov	($idx,&DWP(4,$key));
-+	 &mov	 ($__s2,@T[2]);		# s2^=s3|key[3];
-+	&or	($idx,@T[1]);
-+	 &and	 (@T[2],&DWP(8,$key));
-+	&xor	(@T[0],$idx);
-+	 &rotl	 (@T[2],1);
-+	&mov	($__s0,@T[0]);		# s0^=s1|key[1];
-+	 &xor	 (@T[3],@T[2]);
-+	&mov	($idx,&DWP(16,$key));		# prefetch key[4]
-+	 &mov	 ($__s3,@T[3]);		# s3^=LeftRotate(s2&key[2],1);
-+	&jmp	(&label("loop"));
-+
-+&set_label("done",8);
-+	&mov	(@T[2],@T[0]);		# SwapHalf
-+	&mov	(@T[3],@T[1]);
-+	&mov	(@T[0],$__s2);
-+	&mov	(@T[1],$__s3);
-+	&xor	(@T[0],$idx);		# $idx is preloaded with key[0]
-+	&xor	(@T[1],&DWP(4,$key));
-+	&xor	(@T[2],&DWP(8,$key));
-+	&xor	(@T[3],&DWP(12,$key));
-+	&ret	();
-+&function_end_B("_x86_Camellia_encrypt");
-+
-+# void Camellia_DecryptBlock_Rounds(
-+#		int grandRounds,
-+#		const Byte ciphertext[],
-+#		const KEY_TABLE_TYPE keyTable,
-+#		Byte plaintext[])
-+&function_begin("Camellia_DecryptBlock_Rounds");
-+	&mov	("eax",&wparam(0));	# load grandRounds
-+	&mov	($idx,&wparam(1));	# load ciphertext pointer
-+	&mov	($key,&wparam(2));	# load key schedule pointer
-+
-+	&mov	("ebx","esp");
-+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
-+	&and	("esp",-64);
-+
-+	# place stack frame just "above mod 1024" the key schedule
-+	# this ensures that cache associativity of 2 suffices
-+	&lea	("ecx",&DWP(-64-63,$key));
-+	&sub	("ecx","esp");
-+	&neg	("ecx");
-+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
-+	&sub	("esp","ecx");
-+	&add	("esp",4);	# 4 is reserved for callee's return address
-+
-+	&shl	("eax",6);
-+	&mov	(&DWP(4*4,"esp"),$key);	# save keyStart
-+	&lea	($key,&DWP(0,$key,"eax"));
-+	&mov	(&DWP(5*4,"esp"),"ebx");# save %esp
-+
-+	&call	(&label("pic_point"));
-+	&set_label("pic_point");
-+	&blindpop($Tbl);
-+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-+
-+	&mov	(@T[0],&DWP(0,$idx));	# load ciphertext
-+	&mov	(@T[1],&DWP(4,$idx));
-+	&mov	(@T[2],&DWP(8,$idx));
-+	&bswap	(@T[0]);
-+	&mov	(@T[3],&DWP(12,$idx));
-+	&bswap	(@T[1]);
-+	&bswap	(@T[2]);
-+	&bswap	(@T[3]);
-+
-+	&call	("_x86_Camellia_decrypt");
-+
-+	&mov	("esp",&DWP(5*4,"esp"));
-+	&bswap	(@T[0]);
-+	&mov	($idx,&wparam(3));	# load plaintext pointer
-+	&bswap	(@T[1]);
-+	&bswap	(@T[2]);
-+	&bswap	(@T[3]);
-+	&mov	(&DWP(0,$idx),@T[0]);	# write plaintext
-+	&mov	(&DWP(4,$idx),@T[1]);
-+	&mov	(&DWP(8,$idx),@T[2]);
-+	&mov	(&DWP(12,$idx),@T[3]);
-+&function_end("Camellia_DecryptBlock_Rounds");
-+# V1.x API
-+&function_begin_B("Camellia_DecryptBlock");
-+	&mov	("eax",128);
-+	&sub	("eax",&wparam(0));	# load keyBitLength
-+	&mov	("eax",3);
-+	&adc	("eax",0);		# keyBitLength==128?3:4
-+	&mov	(&wparam(0),"eax");
-+	&jmp	(&label("Camellia_DecryptBlock_Rounds"));
-+&function_end_B("Camellia_DecryptBlock");
-+
-+if ($OPENSSL) {
-+# void Camellia_decrypt(
-+#		const unsigned char *in,
-+#		unsigned char *out,
-+#		const CAMELLIA_KEY *key)
-+&function_begin("Camellia_decrypt");
-+	&mov	($idx,&wparam(0));	# load ciphertext pointer
-+	&mov	($key,&wparam(2));	# load key schedule pointer
-+
-+	&mov	("ebx","esp");
-+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
-+	&and	("esp",-64);
-+	&mov	("eax",&DWP(272,$key));	# load grandRounds counter
-+
-+	# place stack frame just "above mod 1024" the key schedule
-+	# this ensures that cache associativity of 2 suffices
-+	&lea	("ecx",&DWP(-64-63,$key));
-+	&sub	("ecx","esp");
-+	&neg	("ecx");
-+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
-+	&sub	("esp","ecx");
-+	&add	("esp",4);	# 4 is reserved for callee's return address
-+
-+	&shl	("eax",6);
-+	&mov	(&DWP(4*4,"esp"),$key);	# save keyStart
-+	&lea	($key,&DWP(0,$key,"eax"));
-+	&mov	(&DWP(5*4,"esp"),"ebx");# save %esp
-+
-+	&call	(&label("pic_point"));
-+	&set_label("pic_point");
-+	&blindpop($Tbl);
-+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-+
-+	&mov	(@T[0],&DWP(0,$idx));	# load ciphertext
-+	&mov	(@T[1],&DWP(4,$idx));
-+	&mov	(@T[2],&DWP(8,$idx));
-+	&bswap	(@T[0]);
-+	&mov	(@T[3],&DWP(12,$idx));
-+	&bswap	(@T[1]);
-+	&bswap	(@T[2]);
-+	&bswap	(@T[3]);
-+
-+	&call	("_x86_Camellia_decrypt");
-+
-+	&mov	("esp",&DWP(5*4,"esp"));
-+	&bswap	(@T[0]);
-+	&mov	($idx,&wparam(1));	# load plaintext pointer
-+	&bswap	(@T[1]);
-+	&bswap	(@T[2]);
-+	&bswap	(@T[3]);
-+	&mov	(&DWP(0,$idx),@T[0]);	# write plaintext
-+	&mov	(&DWP(4,$idx),@T[1]);
-+	&mov	(&DWP(8,$idx),@T[2]);
-+	&mov	(&DWP(12,$idx),@T[3]);
-+&function_end("Camellia_decrypt");
-+}
-+
-+&function_begin_B("_x86_Camellia_decrypt");
-+	&xor	(@T[0],&DWP(0,$key));	# ^=key[0-3]
-+	&xor	(@T[1],&DWP(4,$key));
-+	&xor	(@T[2],&DWP(8,$key));
-+	&xor	(@T[3],&DWP(12,$key));
-+	&mov	($idx,&DWP(-8,$key));	# prefetch key[-2]
-+
-+	&mov	($__s0,@T[0]);		# save s[0-3]
-+	&mov	($__s1,@T[1]);
-+	&mov	($__s2,@T[2]);
-+	&mov	($__s3,@T[3]);
-+
-+&set_label("loop",16);
-+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8,4); }
-+
-+	&sub	($key,16*4);
-+	&cmp	($key,$__end);
-+	&je	(&label("done"));
-+
-+	# @T[0-1] are preloaded, $idx is preloaded with key[2]
-+	&and	($idx,@T[0]);
-+	 &mov	 (@T[3],$__s3);
-+	&rotl	($idx,1);
-+	 &mov	 (@T[2],@T[3]);
-+	&xor	(@T[1],$idx);
-+	 &or	 (@T[2],&DWP(4,$key));
-+	&mov	($__s1,@T[1]);		# s1^=LeftRotate(s0&key[0],1);
-+	 &xor	 (@T[2],$__s2);
-+
-+	&mov	($idx,&DWP(12,$key));
-+	 &mov	 ($__s2,@T[2]);		# s2^=s3|key[3];
-+	&or	($idx,@T[1]);
-+	 &and	 (@T[2],&DWP(0,$key));
-+	&xor	(@T[0],$idx);
-+	 &rotl	 (@T[2],1);
-+	&mov	($__s0,@T[0]);		# s0^=s1|key[1];
-+	 &xor	 (@T[3],@T[2]);
-+	&mov	($idx,&DWP(-8,$key));	# prefetch key[4]
-+	 &mov	 ($__s3,@T[3]);		# s3^=LeftRotate(s2&key[2],1);
-+	&jmp	(&label("loop"));
-+
-+&set_label("done",8);
-+	&mov	(@T[2],@T[0]);		# SwapHalf
-+	&mov	(@T[3],@T[1]);
-+	&mov	(@T[0],$__s2);
-+	&mov	(@T[1],$__s3);
-+	&xor	(@T[2],$idx);		# $idx is preloaded with key[2]
-+	&xor	(@T[3],&DWP(12,$key));
-+	&xor	(@T[0],&DWP(0,$key));
-+	&xor	(@T[1],&DWP(4,$key));
-+	&ret	();
-+&function_end_B("_x86_Camellia_decrypt");
-+
-+# shld is very slow on Intel P4 family. Even on AMD it limits
-+# instruction decode rate [because it's VectorPath] and consequently
-+# performance. PIII, PM and Core[2] seem to be the only ones which
-+# execute this code ~7% faster...
-+sub __rotl128 {
-+  my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_;
-+
-+    $rnd *= 2;
-+    if ($rot) {
-+	&mov	($idx,$i0);
-+	&shld	($i0,$i1,$rot);
-+	&shld	($i1,$i2,$rot);
-+	&shld	($i2,$i3,$rot);
-+	&shld	($i3,$idx,$rot);
-+    }
-+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
-+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
-+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
-+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
-+}
-+
-+# ... Implementing 128-bit rotate without shld gives >3x performance
-+# improvement on P4, only ~7% degradation on other Intel CPUs and
-+# not worse performance on AMD. This is therefore preferred.
-+sub _rotl128 {
-+  my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_;
-+
-+    $rnd *= 2;
-+    if ($rot) {
-+	&mov	($Tbl,$i0);
-+	&shl	($i0,$rot);
-+	&mov	($idx,$i1);
-+	&shr	($idx,32-$rot);
-+	&shl	($i1,$rot);
-+	&or	($i0,$idx);
-+	&mov	($idx,$i2);
-+	&shl	($i2,$rot);
-+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
-+	&shr	($idx,32-$rot);
-+	&or	($i1,$idx);
-+	&shr	($Tbl,32-$rot);
-+	&mov	($idx,$i3);
-+	&shr	($idx,32-$rot);
-+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
-+	&shl	($i3,$rot);
-+	&or	($i2,$idx);
-+	&or	($i3,$Tbl);
-+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
-+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
-+    } else {
-+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
-+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
-+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
-+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
-+    }
-+}
-+
-+sub _saveround {
-+my ($rnd,$key,@T)=@_;
-+my $bias=int(@T[0])?shift(@T):0;
-+
-+	&mov	(&DWP($bias+$rnd*8+0,$key),@T[0]);
-+	&mov	(&DWP($bias+$rnd*8+4,$key),@T[1])	if ($#T>=1);
-+	&mov	(&DWP($bias+$rnd*8+8,$key),@T[2])	if ($#T>=2);
-+	&mov	(&DWP($bias+$rnd*8+12,$key),@T[3])	if ($#T>=3);
-+}
-+
-+sub _loadround {
-+my ($rnd,$key,@T)=@_;
-+my $bias=int(@T[0])?shift(@T):0;
-+
-+	&mov	(@T[0],&DWP($bias+$rnd*8+0,$key));
-+	&mov	(@T[1],&DWP($bias+$rnd*8+4,$key))	if ($#T>=1);
-+	&mov	(@T[2],&DWP($bias+$rnd*8+8,$key))	if ($#T>=2);
-+	&mov	(@T[3],&DWP($bias+$rnd*8+12,$key))	if ($#T>=3);
-+}
-+
-+# void Camellia_Ekeygen(
-+#		const int keyBitLength,
-+#		const Byte *rawKey,
-+#		KEY_TABLE_TYPE keyTable)
-+&function_begin("Camellia_Ekeygen");
-+{ my $step=0;
-+
-+	&stack_push(4);				# place for s[0-3]
-+
-+	&mov	($Tbl,&wparam(0));		# load arguments
-+	&mov	($idx,&wparam(1));
-+	&mov	($key,&wparam(2));
-+
-+	&mov	(@T[0],&DWP(0,$idx));		# load 0-127 bits
-+	&mov	(@T[1],&DWP(4,$idx));
-+	&mov	(@T[2],&DWP(8,$idx));
-+	&mov	(@T[3],&DWP(12,$idx));
-+
-+	&bswap	(@T[0]);
-+	&bswap	(@T[1]);
-+	&bswap	(@T[2]);
-+	&bswap	(@T[3]);
-+
-+	&_saveround	(0,$key,@T);		# KL<<<0
-+
-+	&cmp	($Tbl,128);
-+	&je	(&label("1st128"));
-+
-+	&mov	(@T[0],&DWP(16,$idx));		# load 128-191 bits
-+	&mov	(@T[1],&DWP(20,$idx));
-+	&cmp	($Tbl,192);
-+	&je	(&label("1st192"));
-+	&mov	(@T[2],&DWP(24,$idx));		# load 192-255 bits
-+	&mov	(@T[3],&DWP(28,$idx));
-+	&jmp	(&label("1st256"));
-+&set_label("1st192",4);
-+	&mov	(@T[2],@T[0]);
-+	&mov	(@T[3],@T[1]);
-+	¬	(@T[2]);
-+	¬	(@T[3]);
-+&set_label("1st256",4);
-+	&bswap	(@T[0]);
-+	&bswap	(@T[1]);
-+	&bswap	(@T[2]);
-+	&bswap	(@T[3]);
-+
-+	&_saveround	(4,$key,@T);		# temporary storage for KR!
-+
-+	&xor	(@T[0],&DWP(0*8+0,$key));	# KR^KL
-+	&xor	(@T[1],&DWP(0*8+4,$key));
-+	&xor	(@T[2],&DWP(1*8+0,$key));
-+	&xor	(@T[3],&DWP(1*8+4,$key));
-+
-+&set_label("1st128",4);
-+	&call	(&label("pic_point"));
-+	&set_label("pic_point");
-+	&blindpop($Tbl);
-+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-+	&lea	($key,&DWP(&label("Camellia_SIGMA")."-".&label("Camellia_SBOX"),$Tbl));
-+
-+	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[0]
-+	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
-+	&mov	(&swtmp(1),@T[1]);
-+	&mov	(&swtmp(2),@T[2]);
-+	&mov	(&swtmp(3),@T[3]);
-+	&Camellia_Feistel($step++);
-+	&Camellia_Feistel($step++);
-+	&mov	(@T[2],&swtmp(2));
-+	&mov	(@T[3],&swtmp(3));
-+
-+	&mov	($idx,&wparam(2));
-+	&xor	(@T[0],&DWP(0*8+0,$idx));	# ^KL
-+	&xor	(@T[1],&DWP(0*8+4,$idx));
-+	&xor	(@T[2],&DWP(1*8+0,$idx));
-+	&xor	(@T[3],&DWP(1*8+4,$idx));
-+
-+	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[4]
-+	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
-+	&mov	(&swtmp(1),@T[1]);
-+	&mov	(&swtmp(2),@T[2]);
-+	&mov	(&swtmp(3),@T[3]);
-+	&Camellia_Feistel($step++);
-+	&Camellia_Feistel($step++);
-+	&mov	(@T[2],&swtmp(2));
-+	&mov	(@T[3],&swtmp(3));
-+
-+	&mov	($idx,&wparam(0));
-+	&cmp	($idx,128);
-+	&jne	(&label("2nd256"));
-+
-+	&mov	($key,&wparam(2));
-+	&lea	($key,&DWP(128,$key));		# size optimization
-+
-+	####### process KA
-+	&_saveround	(2,$key,-128,@T);	# KA<<<0
-+	&_rotl128	(@T,15,6,@T);		# KA<<<15
-+	&_rotl128	(@T,15,8,@T);		# KA<<<(15+15=30)
-+	&_rotl128	(@T,15,12,@T[0],@T[1]);	# KA<<<(30+15=45)
-+	&_rotl128	(@T,15,14,@T);		# KA<<<(45+15=60)
-+	push		(@T,shift(@T));		# rotl128(@T,32);
-+	&_rotl128	(@T,2,20,@T);		# KA<<<(60+32+2=94)
-+	&_rotl128	(@T,17,24,@T);		# KA<<<(94+17=111)
-+
-+	####### process KL
-+	&_loadround	(0,$key,-128,@T);	# load KL
-+	&_rotl128	(@T,15,4,@T);		# KL<<<15
-+	&_rotl128	(@T,30,10,@T);		# KL<<<(15+30=45)
-+	&_rotl128	(@T,15,13,@T[2],@T[3]);	# KL<<<(45+15=60)
-+	&_rotl128	(@T,17,16,@T);		# KL<<<(60+17=77)
-+	&_rotl128	(@T,17,18,@T);		# KL<<<(77+17=94)
-+	&_rotl128	(@T,17,22,@T);		# KL<<<(94+17=111)
-+
-+	while (@T[0] ne "eax")			# restore order
-+	{   unshift	(@T,pop(@T));   }
-+
-+	&mov	("eax",3);			# 3 grandRounds
-+	&jmp	(&label("done"));
-+
-+&set_label("2nd256",16);
-+	&mov	($idx,&wparam(2));
-+	&_saveround	(6,$idx,@T);		# temporary storage for KA!
-+
-+	&xor	(@T[0],&DWP(4*8+0,$idx));	# KA^KR
-+	&xor	(@T[1],&DWP(4*8+4,$idx));
-+	&xor	(@T[2],&DWP(5*8+0,$idx));
-+	&xor	(@T[3],&DWP(5*8+4,$idx));
-+
-+	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[8]
-+	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
-+	&mov	(&swtmp(1),@T[1]);
-+	&mov	(&swtmp(2),@T[2]);
-+	&mov	(&swtmp(3),@T[3]);
-+	&Camellia_Feistel($step++);
-+	&Camellia_Feistel($step++);
-+	&mov	(@T[2],&swtmp(2));
-+	&mov	(@T[3],&swtmp(3));
-+
-+	&mov	($key,&wparam(2));
-+	&lea	($key,&DWP(128,$key));		# size optimization
-+
-+	####### process KB
-+	&_saveround	(2,$key,-128,@T);	# KB<<<0
-+	&_rotl128	(@T,30,10,@T);		# KB<<<30
-+	&_rotl128	(@T,30,20,@T);		# KB<<<(30+30=60)
-+	push		(@T,shift(@T));		# rotl128(@T,32);
-+	&_rotl128	(@T,19,32,@T);		# KB<<<(60+32+19=111)
-+
-+	####### process KR
-+	&_loadround	(4,$key,-128,@T);	# load KR
-+	&_rotl128	(@T,15,4,@T);		# KR<<<15
-+	&_rotl128	(@T,15,8,@T);		# KR<<<(15+15=30)
-+	&_rotl128	(@T,30,18,@T);		# KR<<<(30+30=60)
-+	push		(@T,shift(@T));		# rotl128(@T,32);
-+	&_rotl128	(@T,2,26,@T);		# KR<<<(60+32+2=94)
-+
-+	####### process KA
-+	&_loadround	(6,$key,-128,@T);	# load KA
-+	&_rotl128	(@T,15,6,@T);		# KA<<<15
-+	&_rotl128	(@T,30,14,@T);		# KA<<<(15+30=45)
-+	push		(@T,shift(@T));		# rotl128(@T,32);
-+	&_rotl128	(@T,0,24,@T);		# KA<<<(45+32+0=77)
-+	&_rotl128	(@T,17,28,@T);		# KA<<<(77+17=94)
-+
-+	####### process KL
-+	&_loadround	(0,$key,-128,@T);	# load KL
-+	push		(@T,shift(@T));		# rotl128(@T,32);
-+	&_rotl128	(@T,13,12,@T);		# KL<<<(32+13=45)
-+	&_rotl128	(@T,15,16,@T);		# KL<<<(45+15=60)
-+	&_rotl128	(@T,17,22,@T);		# KL<<<(60+17=77)
-+	push		(@T,shift(@T));		# rotl128(@T,32);
-+	&_rotl128	(@T,2,30,@T);		# KL<<<(77+32+2=111)
-+
-+	while (@T[0] ne "eax")			# restore order
-+	{   unshift	(@T,pop(@T));   }
-+
-+	&mov	("eax",4);			# 4 grandRounds
-+&set_label("done");
-+	&lea	("edx",&DWP(272-128,$key));	# end of key schedule
-+	&stack_pop(4);
-+}
-+&function_end("Camellia_Ekeygen");
-+
-+if ($OPENSSL) {
-+# int Camellia_set_key (
-+#		const unsigned char *userKey,
-+#		int bits,
-+#		CAMELLIA_KEY *key)
-+&function_begin_B("Camellia_set_key");
-+	&push	("ebx");
-+	&mov	("ecx",&wparam(0));	# pull arguments
-+	&mov	("ebx",&wparam(1));
-+	&mov	("edx",&wparam(2));
-+
-+	&mov	("eax",-1);
-+	&test	("ecx","ecx");
-+	&jz	(&label("done"));	# userKey==NULL?
-+	&test	("edx","edx");
-+	&jz	(&label("done"));	# key==NULL?
-+
-+	&mov	("eax",-2);
-+	&cmp	("ebx",256);
-+	&je	(&label("arg_ok"));	# bits==256?
-+	&cmp	("ebx",192);
-+	&je	(&label("arg_ok"));	# bits==192?
-+	&cmp	("ebx",128);
-+	&jne	(&label("done"));	# bits!=128?
-+&set_label("arg_ok",4);
-+
-+	&push	("edx");		# push arguments
-+	&push	("ecx");
-+	&push	("ebx");
-+	&call	("Camellia_Ekeygen");
-+	&stack_pop(3);
-+
-+	# eax holds grandRounds and edx points at where to put it
-+	&mov	(&DWP(0,"edx"),"eax");
-+	&xor	("eax","eax");
-+&set_label("done",4);
-+	&pop	("ebx");
-+	&ret	();
-+&function_end_B("Camellia_set_key");
-+}
-+
-+@SBOX=(
-+112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
-+ 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
-+134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
-+166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77,
-+139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
-+223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215,
-+ 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
-+254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80,
-+170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
-+ 16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
-+135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226,
-+ 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
-+233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
-+120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
-+114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
-+ 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
-+
-+sub S1110 { my $i=shift; $i=@SBOX[$i]; return $i<<24|$i<<16|$i<<8; }
-+sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; return $i<<24|$i<<16|$i; }	
-+sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; return $i<<16|$i<<8|$i; }	
-+sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; return $i<<24|$i<<8|$i; }	
-+
-+&set_label("Camellia_SIGMA",64);
-+&data_word(
-+    0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2,
-+    0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c,
-+    0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd,
-+    0,          0,          0,          0);
-+&set_label("Camellia_SBOX",64);
-+# tables are interleaved, remember?
-+for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
-+for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
-+
-+# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
-+#			size_t length, const CAMELLIA_KEY *key,
-+#			unsigned char *ivp,const int enc);
-+{
-+# stack frame layout
-+#             -4(%esp)		# return address	 0(%esp)
-+#              0(%esp)		# s0			 4(%esp)
-+#              4(%esp)		# s1			 8(%esp)
-+#              8(%esp)		# s2			12(%esp)
-+#             12(%esp)		# s3			16(%esp)
-+#             16(%esp)		# end of key schedule	20(%esp)
-+#             20(%esp)		# %esp backup
-+my $_inp=&DWP(24,"esp");	#copy of wparam(0)
-+my $_out=&DWP(28,"esp");	#copy of wparam(1)
-+my $_len=&DWP(32,"esp");	#copy of wparam(2)
-+my $_key=&DWP(36,"esp");	#copy of wparam(3)
-+my $_ivp=&DWP(40,"esp");	#copy of wparam(4)
-+my $ivec=&DWP(44,"esp");	#ivec[16]
-+my $_tmp=&DWP(44,"esp");	#volatile variable [yes, aliases with ivec]
-+my ($s0,$s1,$s2,$s3) = @T;
-+
-+&function_begin("Camellia_cbc_encrypt");
-+	&mov	($s2 eq "ecx"? $s2 : "",&wparam(2));	# load len
-+	&cmp	($s2,0);
-+	&je	(&label("enc_out"));
-+
-+	&pushf	();
-+	&cld	();
-+
-+	&mov	($s0,&wparam(0));	# load inp
-+	&mov	($s1,&wparam(1));	# load out
-+	#&mov	($s2,&wparam(2));	# load len
-+	&mov	($s3,&wparam(3));	# load key
-+	&mov	($Tbl,&wparam(4));	# load ivp
-+
-+	# allocate aligned stack frame...
-+	&lea	($idx,&DWP(-64,"esp"));
-+	&and	($idx,-64);
-+
-+	# place stack frame just "above mod 1024" the key schedule
-+	# this ensures that cache associativity of 2 suffices
-+	&lea	($key,&DWP(-64-63,$s3));
-+	&sub	($key,$idx);
-+	&neg	($key);
-+	&and	($key,0x3C0);	# modulo 1024, but aligned to cache-line
-+	&sub	($idx,$key);
-+
-+	&mov	($key,&wparam(5));	# load enc
-+
-+	&exch	("esp",$idx);
-+	&add	("esp",4);		# reserve for return address!
-+	&mov	($_esp,$idx);		# save %esp
-+
-+	&mov	($_inp,$s0);		# save copy of inp
-+	&mov	($_out,$s1);		# save copy of out
-+	&mov	($_len,$s2);		# save copy of len
-+	&mov	($_key,$s3);		# save copy of key
-+	&mov	($_ivp,$Tbl);		# save copy of ivp
-+
-+	&call   (&label("pic_point"));	# make it PIC!
-+	&set_label("pic_point");
-+	&blindpop($Tbl);
-+	&lea    ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
-+
-+	&mov	($idx,32);
-+	&set_label("prefetch_sbox",4);
-+		&mov	($s0,&DWP(0,$Tbl));
-+		&mov	($s1,&DWP(32,$Tbl));
-+		&mov	($s2,&DWP(64,$Tbl));
-+		&mov	($s3,&DWP(96,$Tbl));
-+		&lea	($Tbl,&DWP(128,$Tbl));
-+		&dec	($idx);
-+	&jnz	(&label("prefetch_sbox"));
-+	&mov	($s0,$_key);
-+	&sub	($Tbl,4096);
-+	&mov	($idx,$_inp);
-+	&mov	($s3,&DWP(272,$s0));		# load grandRounds
-+
-+	&cmp	($key,0);
-+	&je	(&label("DECRYPT"));
-+
-+	&mov	($s2,$_len);
-+	&mov	($key,$_ivp);
-+	&shl	($s3,6);
-+	&lea	($s3,&DWP(0,$s0,$s3));
-+	&mov	($_end,$s3);
-+
-+	&test	($s2,0xFFFFFFF0);
-+	&jz	(&label("enc_tail"));		# short input...
-+
-+	&mov	($s0,&DWP(0,$key));		# load iv
-+	&mov	($s1,&DWP(4,$key));
-+
-+	&set_label("enc_loop",4);
-+		&mov	($s2,&DWP(8,$key));
-+		&mov	($s3,&DWP(12,$key));
-+
-+		&xor	($s0,&DWP(0,$idx));	# xor input data
-+		&xor	($s1,&DWP(4,$idx));
-+		&xor	($s2,&DWP(8,$idx));
-+		&bswap	($s0);
-+		&xor	($s3,&DWP(12,$idx));
-+		&bswap	($s1);
-+		&mov	($key,$_key);		# load key
-+		&bswap	($s2);
-+		&bswap	($s3);
-+
-+		&call	("_x86_Camellia_encrypt");
-+
-+		&mov	($idx,$_inp);		# load inp
-+		&mov	($key,$_out);		# load out
-+
-+		&bswap	($s0);
-+		&bswap	($s1);
-+		&bswap	($s2);
-+		&mov	(&DWP(0,$key),$s0);	# save output data
-+		&bswap	($s3);
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&mov	(&DWP(12,$key),$s3);
-+
-+		&mov	($s2,$_len);		# load len
-+
-+		&lea	($idx,&DWP(16,$idx));
-+		&mov	($_inp,$idx);		# save inp
-+
-+		&lea	($s3,&DWP(16,$key));
-+		&mov	($_out,$s3);		# save out
-+
-+		&sub	($s2,16);
-+		&test	($s2,0xFFFFFFF0);
-+		&mov	($_len,$s2);		# save len
-+	&jnz	(&label("enc_loop"));
-+	&test	($s2,15);
-+	&jnz	(&label("enc_tail"));
-+	&mov	($idx,$_ivp);		# load ivp
-+	&mov	($s2,&DWP(8,$key));	# restore last dwords
-+	&mov	($s3,&DWP(12,$key));
-+	&mov	(&DWP(0,$idx),$s0);	# save ivec
-+	&mov	(&DWP(4,$idx),$s1);
-+	&mov	(&DWP(8,$idx),$s2);
-+	&mov	(&DWP(12,$idx),$s3);
-+
-+	&mov	("esp",$_esp);
-+	&popf	();
-+    &set_label("enc_out");
-+	&function_end_A();
-+	&pushf	();			# kludge, never executed
-+
-+    &set_label("enc_tail",4);
-+	&mov	($s0,$key eq "edi" ? $key : "");
-+	&mov	($key,$_out);			# load out
-+	&push	($s0);				# push ivp
-+	&mov	($s1,16);
-+	&sub	($s1,$s2);
-+	&cmp	($key,$idx);			# compare with inp
-+	&je	(&label("enc_in_place"));
-+	&align	(4);
-+	&data_word(0xA4F3F689);	# rep movsb	# copy input
-+	&jmp	(&label("enc_skip_in_place"));
-+    &set_label("enc_in_place");
-+	&lea	($key,&DWP(0,$key,$s2));
-+    &set_label("enc_skip_in_place");
-+	&mov	($s2,$s1);
-+	&xor	($s0,$s0);
-+	&align	(4);
-+	&data_word(0xAAF3F689);	# rep stosb	# zero tail
-+	&pop	($key);				# pop ivp
-+
-+	&mov	($idx,$_out);			# output as input
-+	&mov	($s0,&DWP(0,$key));
-+	&mov	($s1,&DWP(4,$key));
-+	&mov	($_len,16);			# len=16
-+	&jmp	(&label("enc_loop"));		# one more spin...
-+
-+#----------------------------- DECRYPT -----------------------------#
-+&set_label("DECRYPT",16);
-+	&shl	($s3,6);
-+	&lea	($s3,&DWP(0,$s0,$s3));
-+	&mov	($_end,$s0);
-+	&mov	($_key,$s3);
-+
-+	&cmp	($idx,$_out);
-+	&je	(&label("dec_in_place"));	# in-place processing...
-+
-+	&mov	($key,$_ivp);			# load ivp
-+	&mov	($_tmp,$key);
-+
-+	&set_label("dec_loop",4);
-+		&mov	($s0,&DWP(0,$idx));	# read input
-+		&mov	($s1,&DWP(4,$idx));
-+		&mov	($s2,&DWP(8,$idx));
-+		&bswap	($s0);
-+		&mov	($s3,&DWP(12,$idx));
-+		&bswap	($s1);
-+		&mov	($key,$_key);		# load key
-+		&bswap	($s2);
-+		&bswap	($s3);
-+
-+		&call	("_x86_Camellia_decrypt");
-+
-+		&mov	($key,$_tmp);		# load ivp
-+		&mov	($idx,$_len);		# load len
-+
-+		&bswap	($s0);
-+		&bswap	($s1);
-+		&bswap	($s2);
-+		&xor	($s0,&DWP(0,$key));	# xor iv
-+		&bswap	($s3);
-+		&xor	($s1,&DWP(4,$key));
-+		&xor	($s2,&DWP(8,$key));
-+		&xor	($s3,&DWP(12,$key));
-+
-+		&sub	($idx,16);
-+		&jc	(&label("dec_partial"));
-+		&mov	($_len,$idx);		# save len
-+		&mov	($idx,$_inp);		# load inp
-+		&mov	($key,$_out);		# load out
-+
-+		&mov	(&DWP(0,$key),$s0);	# write output
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&mov	(&DWP(12,$key),$s3);
-+
-+		&mov	($_tmp,$idx);		# save ivp
-+		&lea	($idx,&DWP(16,$idx));
-+		&mov	($_inp,$idx);		# save inp
-+
-+		&lea	($key,&DWP(16,$key));
-+		&mov	($_out,$key);		# save out
-+
-+	&jnz	(&label("dec_loop"));
-+	&mov	($key,$_tmp);		# load temp ivp
-+    &set_label("dec_end");
-+	&mov	($idx,$_ivp);		# load user ivp
-+	&mov	($s0,&DWP(0,$key));	# load iv
-+	&mov	($s1,&DWP(4,$key));
-+	&mov	($s2,&DWP(8,$key));
-+	&mov	($s3,&DWP(12,$key));
-+	&mov	(&DWP(0,$idx),$s0);	# copy back to user
-+	&mov	(&DWP(4,$idx),$s1);
-+	&mov	(&DWP(8,$idx),$s2);
-+	&mov	(&DWP(12,$idx),$s3);
-+	&jmp	(&label("dec_out"));
-+
-+    &set_label("dec_partial",4);
-+	&lea	($key,$ivec);
-+	&mov	(&DWP(0,$key),$s0);	# dump output to stack
-+	&mov	(&DWP(4,$key),$s1);
-+	&mov	(&DWP(8,$key),$s2);
-+	&mov	(&DWP(12,$key),$s3);
-+	&lea	($s2 eq "ecx" ? $s2 : "",&DWP(16,$idx));
-+	&mov	($idx eq "esi" ? $idx : "",$key);
-+	&mov	($key eq "edi" ? $key : "",$_out);	# load out
-+	&data_word(0xA4F3F689);	# rep movsb		# copy output
-+	&mov	($key,$_inp);				# use inp as temp ivp
-+	&jmp	(&label("dec_end"));
-+
-+    &set_label("dec_in_place",4);
-+	&set_label("dec_in_place_loop");
-+		&lea	($key,$ivec);
-+		&mov	($s0,&DWP(0,$idx));	# read input
-+		&mov	($s1,&DWP(4,$idx));
-+		&mov	($s2,&DWP(8,$idx));
-+		&mov	($s3,&DWP(12,$idx));
-+
-+		&mov	(&DWP(0,$key),$s0);	# copy to temp
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&bswap	($s0);
-+		&mov	(&DWP(12,$key),$s3);
-+		&bswap	($s1);
-+		&mov	($key,$_key);		# load key
-+		&bswap	($s2);
-+		&bswap	($s3);
-+
-+		&call	("_x86_Camellia_decrypt");
-+
-+		&mov	($key,$_ivp);		# load ivp
-+		&mov	($idx,$_out);		# load out
-+
-+		&bswap	($s0);
-+		&bswap	($s1);
-+		&bswap	($s2);
-+		&xor	($s0,&DWP(0,$key));	# xor iv
-+		&bswap	($s3);
-+		&xor	($s1,&DWP(4,$key));
-+		&xor	($s2,&DWP(8,$key));
-+		&xor	($s3,&DWP(12,$key));
-+
-+		&mov	(&DWP(0,$idx),$s0);	# write output
-+		&mov	(&DWP(4,$idx),$s1);
-+		&mov	(&DWP(8,$idx),$s2);
-+		&mov	(&DWP(12,$idx),$s3);
-+
-+		&lea	($idx,&DWP(16,$idx));
-+		&mov	($_out,$idx);		# save out
-+
-+		&lea	($idx,$ivec);
-+		&mov	($s0,&DWP(0,$idx));	# read temp
-+		&mov	($s1,&DWP(4,$idx));
-+		&mov	($s2,&DWP(8,$idx));
-+		&mov	($s3,&DWP(12,$idx));
-+
-+		&mov	(&DWP(0,$key),$s0);	# copy iv
-+		&mov	(&DWP(4,$key),$s1);
-+		&mov	(&DWP(8,$key),$s2);
-+		&mov	(&DWP(12,$key),$s3);
-+
-+		&mov	($idx,$_inp);		# load inp
-+
-+		&lea	($idx,&DWP(16,$idx));
-+		&mov	($_inp,$idx);		# save inp
-+
-+		&mov	($s2,$_len);		# load len
-+		&sub	($s2,16);
-+		&jc	(&label("dec_in_place_partial"));
-+		&mov	($_len,$s2);		# save len
-+	&jnz	(&label("dec_in_place_loop"));
-+	&jmp	(&label("dec_out"));
-+
-+    &set_label("dec_in_place_partial",4);
-+	# one can argue if this is actually required...
-+	&mov	($key eq "edi" ? $key : "",$_out);
-+	&lea	($idx eq "esi" ? $idx : "",$ivec);
-+	&lea	($key,&DWP(0,$key,$s2));
-+	&lea	($idx,&DWP(16,$idx,$s2));
-+	&neg	($s2 eq "ecx" ? $s2 : "");
-+	&data_word(0xA4F3F689);	# rep movsb	# restore tail
-+
-+    &set_label("dec_out",4);
-+    &mov	("esp",$_esp);
-+    &popf	();
-+&function_end("Camellia_cbc_encrypt");
-+}
-+
-+&asciz("Camellia for x86 by ");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmll-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmll-x86_64.pl
-new file mode 100644
-index 0000000..da5ad7b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmll-x86_64.pl
-@@ -0,0 +1,1088 @@
-+#! /usr/bin/env perl
-+# Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Copyright (c) 2008 Andy Polyakov 
-+#
-+# This module may be used under the terms of either the GNU General
-+# Public License version 2 or later, the GNU Lesser General Public
-+# License version 2.1 or later, the Mozilla Public License version
-+# 1.1 or the BSD License. The exact terms of either license are
-+# distributed along with this module. For further details see
-+# http://www.openssl.org/~appro/camellia/.
-+# ====================================================================
-+
-+# Performance in cycles per processed byte (less is better) in
-+# 'openssl speed ...' benchmark:
-+#
-+#			AMD64	Core2	EM64T
-+# -evp camellia-128-ecb	16.7	21.0	22.7
-+# + over gcc 3.4.6	+25%	+5%	0%
-+#
-+# camellia-128-cbc	15.7	20.4	21.1
-+#
-+# 128-bit key setup	128	216	205	cycles/key
-+# + over gcc 3.4.6	+54%	+39%	+15%
-+#
-+# Numbers in "+" rows represent performance improvement over compiler
-+# generated code. Key setup timings are impressive on AMD and Core2
-+# thanks to 64-bit operations being covertly deployed. Improvement on
-+# EM64T, pre-Core2 Intel x86_64 CPU, is not as impressive, because it
-+# apparently emulates some of 64-bit operations in [32-bit] microcode.
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/;    $r; }
-+sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
-+                        $r =~ s/%[er]([sd]i)/%\1l/;
-+                        $r =~ s/%(r[0-9]+)[d]?/%\1b/;   $r; }
-+
-+$t0="%eax";$t1="%ebx";$t2="%ecx";$t3="%edx";
-+@S=("%r8d","%r9d","%r10d","%r11d");
-+$i0="%esi";
-+$i1="%edi";
-+$Tbl="%rbp";	# size optimization
-+$inp="%r12";
-+$out="%r13";
-+$key="%r14";
-+$keyend="%r15";
-+$arg0d=$win64?"%ecx":"%edi";
-+
-+# const unsigned int Camellia_SBOX[4][256];
-+# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
-+# and [2][] - with [3][]. This is done to minimize code size.
-+$SBOX1_1110=0;		# Camellia_SBOX[0]
-+$SBOX4_4404=4;		# Camellia_SBOX[1]
-+$SBOX2_0222=2048;	# Camellia_SBOX[2]
-+$SBOX3_3033=2052;	# Camellia_SBOX[3]
-+
-+sub Camellia_Feistel {
-+my $i=@_[0];
-+my $seed=defined(@_[1])?@_[1]:0;
-+my $scale=$seed<0?-8:8;
-+my $j=($i&1)*2;
-+my ($s0,$s1,$s2,$s3)=(@S[($j)%4],@S[($j+1)%4],@S[($j+2)%4],@S[($j+3)%4]);
-+
-+$code.=<<___;
-+	xor	$s0,$t0				# t0^=key[0]
-+	xor	$s1,$t1				# t1^=key[1]
-+	movz	`&hi("$t0")`,$i0		# (t0>>8)&0xff
-+	movz	`&lo("$t1")`,$i1		# (t1>>0)&0xff
-+	mov	$SBOX3_3033($Tbl,$i0,8),$t3	# t3=SBOX3_3033[0]
-+	mov	$SBOX1_1110($Tbl,$i1,8),$t2	# t2=SBOX1_1110[1]
-+	movz	`&lo("$t0")`,$i0		# (t0>>0)&0xff
-+	shr	\$16,$t0
-+	movz	`&hi("$t1")`,$i1		# (t1>>8)&0xff
-+	xor	$SBOX4_4404($Tbl,$i0,8),$t3	# t3^=SBOX4_4404[0]
-+	shr	\$16,$t1
-+	xor	$SBOX4_4404($Tbl,$i1,8),$t2	# t2^=SBOX4_4404[1]
-+	movz	`&hi("$t0")`,$i0		# (t0>>24)&0xff
-+	movz	`&lo("$t1")`,$i1		# (t1>>16)&0xff
-+	xor	$SBOX1_1110($Tbl,$i0,8),$t3	# t3^=SBOX1_1110[0]
-+	xor	$SBOX3_3033($Tbl,$i1,8),$t2	# t2^=SBOX3_3033[1]
-+	movz	`&lo("$t0")`,$i0		# (t0>>16)&0xff
-+	movz	`&hi("$t1")`,$i1		# (t1>>24)&0xff
-+	xor	$SBOX2_0222($Tbl,$i0,8),$t3	# t3^=SBOX2_0222[0]
-+	xor	$SBOX2_0222($Tbl,$i1,8),$t2	# t2^=SBOX2_0222[1]
-+	mov	`$seed+($i+1)*$scale`($key),$t1	# prefetch key[i+1]
-+	mov	`$seed+($i+1)*$scale+4`($key),$t0
-+	xor	$t3,$t2				# t2^=t3
-+	ror	\$8,$t3				# t3=RightRotate(t3,8)
-+	xor	$t2,$s2
-+	xor	$t2,$s3
-+	xor	$t3,$s3
-+___
-+}
-+
-+# void Camellia_EncryptBlock_Rounds(
-+#		int grandRounds,
-+#		const Byte plaintext[],
-+#		const KEY_TABLE_TYPE keyTable,
-+#		Byte ciphertext[])
-+$code=<<___;
-+.text
-+
-+# V1.x API
-+.globl	Camellia_EncryptBlock
-+.type	Camellia_EncryptBlock,\@abi-omnipotent
-+.align	16
-+Camellia_EncryptBlock:
-+	movl	\$128,%eax
-+	subl	$arg0d,%eax
-+	movl	\$3,$arg0d
-+	adcl	\$0,$arg0d	# keyBitLength==128?3:4
-+	jmp	.Lenc_rounds
-+.size	Camellia_EncryptBlock,.-Camellia_EncryptBlock
-+# V2
-+.globl	Camellia_EncryptBlock_Rounds
-+.type	Camellia_EncryptBlock_Rounds,\@function,4
-+.align	16
-+.Lenc_rounds:
-+Camellia_EncryptBlock_Rounds:
-+	push	%rbx
-+	push	%rbp
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lenc_prologue:
-+
-+	#mov	%rsi,$inp		# put away arguments
-+	mov	%rcx,$out
-+	mov	%rdx,$key
-+
-+	shl	\$6,%edi		# process grandRounds
-+	lea	.LCamellia_SBOX(%rip),$Tbl
-+	lea	($key,%rdi),$keyend
-+
-+	mov	0(%rsi),@S[0]		# load plaintext
-+	mov	4(%rsi),@S[1]
-+	mov	8(%rsi),@S[2]
-+	bswap	@S[0]
-+	mov	12(%rsi),@S[3]
-+	bswap	@S[1]
-+	bswap	@S[2]
-+	bswap	@S[3]
-+
-+	call	_x86_64_Camellia_encrypt
-+
-+	bswap	@S[0]
-+	bswap	@S[1]
-+	bswap	@S[2]
-+	mov	@S[0],0($out)
-+	bswap	@S[3]
-+	mov	@S[1],4($out)
-+	mov	@S[2],8($out)
-+	mov	@S[3],12($out)
-+
-+	mov	0(%rsp),%r15
-+	mov	8(%rsp),%r14
-+	mov	16(%rsp),%r13
-+	mov	24(%rsp),%rbp
-+	mov	32(%rsp),%rbx
-+	lea	40(%rsp),%rsp
-+.Lenc_epilogue:
-+	ret
-+.size	Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds
-+
-+.type	_x86_64_Camellia_encrypt,\@abi-omnipotent
-+.align	16
-+_x86_64_Camellia_encrypt:
-+	xor	0($key),@S[1]
-+	xor	4($key),@S[0]		# ^=key[0-3]
-+	xor	8($key),@S[3]
-+	xor	12($key),@S[2]
-+.align	16
-+.Leloop:
-+	mov	16($key),$t1		# prefetch key[4-5]
-+	mov	20($key),$t0
-+
-+___
-+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16); }
-+$code.=<<___;
-+	lea	16*4($key),$key
-+	cmp	$keyend,$key
-+	mov	8($key),$t3		# prefetch key[2-3]
-+	mov	12($key),$t2
-+	je	.Ledone
-+
-+	and	@S[0],$t0
-+	or	@S[3],$t3
-+	rol	\$1,$t0
-+	xor	$t3,@S[2]		# s2^=s3|key[3];
-+	xor	$t0,@S[1]		# s1^=LeftRotate(s0&key[0],1);
-+	and	@S[2],$t2
-+	or	@S[1],$t1
-+	rol	\$1,$t2
-+	xor	$t1,@S[0]		# s0^=s1|key[1];
-+	xor	$t2,@S[3]		# s3^=LeftRotate(s2&key[2],1);
-+	jmp	.Leloop
-+
-+.align	16
-+.Ledone:
-+	xor	@S[2],$t0		# SwapHalf
-+	xor	@S[3],$t1
-+	xor	@S[0],$t2
-+	xor	@S[1],$t3
-+
-+	mov	$t0,@S[0]
-+	mov	$t1,@S[1]
-+	mov	$t2,@S[2]
-+	mov	$t3,@S[3]
-+
-+	.byte	0xf3,0xc3		# rep ret
-+.size	_x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt
-+
-+# V1.x API
-+.globl	Camellia_DecryptBlock
-+.type	Camellia_DecryptBlock,\@abi-omnipotent
-+.align	16
-+Camellia_DecryptBlock:
-+	movl	\$128,%eax
-+	subl	$arg0d,%eax
-+	movl	\$3,$arg0d
-+	adcl	\$0,$arg0d	# keyBitLength==128?3:4
-+	jmp	.Ldec_rounds
-+.size	Camellia_DecryptBlock,.-Camellia_DecryptBlock
-+# V2
-+.globl	Camellia_DecryptBlock_Rounds
-+.type	Camellia_DecryptBlock_Rounds,\@function,4
-+.align	16
-+.Ldec_rounds:
-+Camellia_DecryptBlock_Rounds:
-+	push	%rbx
-+	push	%rbp
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Ldec_prologue:
-+
-+	#mov	%rsi,$inp		# put away arguments
-+	mov	%rcx,$out
-+	mov	%rdx,$keyend
-+
-+	shl	\$6,%edi		# process grandRounds
-+	lea	.LCamellia_SBOX(%rip),$Tbl
-+	lea	($keyend,%rdi),$key
-+
-+	mov	0(%rsi),@S[0]		# load plaintext
-+	mov	4(%rsi),@S[1]
-+	mov	8(%rsi),@S[2]
-+	bswap	@S[0]
-+	mov	12(%rsi),@S[3]
-+	bswap	@S[1]
-+	bswap	@S[2]
-+	bswap	@S[3]
-+
-+	call	_x86_64_Camellia_decrypt
-+
-+	bswap	@S[0]
-+	bswap	@S[1]
-+	bswap	@S[2]
-+	mov	@S[0],0($out)
-+	bswap	@S[3]
-+	mov	@S[1],4($out)
-+	mov	@S[2],8($out)
-+	mov	@S[3],12($out)
-+
-+	mov	0(%rsp),%r15
-+	mov	8(%rsp),%r14
-+	mov	16(%rsp),%r13
-+	mov	24(%rsp),%rbp
-+	mov	32(%rsp),%rbx
-+	lea	40(%rsp),%rsp
-+.Ldec_epilogue:
-+	ret
-+.size	Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds
-+
-+.type	_x86_64_Camellia_decrypt,\@abi-omnipotent
-+.align	16
-+_x86_64_Camellia_decrypt:
-+	xor	0($key),@S[1]
-+	xor	4($key),@S[0]		# ^=key[0-3]
-+	xor	8($key),@S[3]
-+	xor	12($key),@S[2]
-+.align	16
-+.Ldloop:
-+	mov	-8($key),$t1		# prefetch key[4-5]
-+	mov	-4($key),$t0
-+
-+___
-+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8); }
-+$code.=<<___;
-+	lea	-16*4($key),$key
-+	cmp	$keyend,$key
-+	mov	0($key),$t3		# prefetch key[2-3]
-+	mov	4($key),$t2
-+	je	.Lddone
-+
-+	and	@S[0],$t0
-+	or	@S[3],$t3
-+	rol	\$1,$t0
-+	xor	$t3,@S[2]		# s2^=s3|key[3];
-+	xor	$t0,@S[1]		# s1^=LeftRotate(s0&key[0],1);
-+	and	@S[2],$t2
-+	or	@S[1],$t1
-+	rol	\$1,$t2
-+	xor	$t1,@S[0]		# s0^=s1|key[1];
-+	xor	$t2,@S[3]		# s3^=LeftRotate(s2&key[2],1);
-+
-+	jmp	.Ldloop
-+
-+.align	16
-+.Lddone:
-+	xor	@S[2],$t2
-+	xor	@S[3],$t3
-+	xor	@S[0],$t0
-+	xor	@S[1],$t1
-+
-+	mov	$t2,@S[0]		# SwapHalf
-+	mov	$t3,@S[1]
-+	mov	$t0,@S[2]
-+	mov	$t1,@S[3]
-+
-+	.byte	0xf3,0xc3		# rep ret
-+.size	_x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt
-+___
-+
-+sub _saveround {
-+my ($rnd,$key,@T)=@_;
-+my $bias=int(@T[0])?shift(@T):0;
-+
-+    if ($#T==3) {
-+	$code.=<<___;
-+	mov	@T[1],`$bias+$rnd*8+0`($key)
-+	mov	@T[0],`$bias+$rnd*8+4`($key)
-+	mov	@T[3],`$bias+$rnd*8+8`($key)
-+	mov	@T[2],`$bias+$rnd*8+12`($key)
-+___
-+    } else {
-+	$code.="	mov	@T[0],`$bias+$rnd*8+0`($key)\n";
-+	$code.="	mov	@T[1],`$bias+$rnd*8+8`($key)\n"	if ($#T>=1);
-+    }
-+}
-+
-+sub _loadround {
-+my ($rnd,$key,@T)=@_;
-+my $bias=int(@T[0])?shift(@T):0;
-+
-+$code.="	mov	`$bias+$rnd*8+0`($key),@T[0]\n";
-+$code.="	mov	`$bias+$rnd*8+8`($key),@T[1]\n"	if ($#T>=1);
-+}
-+
-+# shld is very slow on Intel EM64T family. Even on AMD it limits
-+# instruction decode rate [because it's VectorPath] and consequently
-+# performance...
-+sub __rotl128 {
-+my ($i0,$i1,$rot)=@_;
-+
-+    if ($rot) {
-+	$code.=<<___;
-+	mov	$i0,%r11
-+	shld	\$$rot,$i1,$i0
-+	shld	\$$rot,%r11,$i1
-+___
-+    }
-+}
-+
-+# ... Implementing 128-bit rotate without shld gives 80% better
-+# performance EM64T, +15% on AMD64 and only ~7% degradation on
-+# Core2. This is therefore preferred.
-+sub _rotl128 {
-+my ($i0,$i1,$rot)=@_;
-+
-+    if ($rot) {
-+	$code.=<<___;
-+	mov	$i0,%r11
-+	shl	\$$rot,$i0
-+	mov	$i1,%r9
-+	shr	\$`64-$rot`,%r9
-+	shr	\$`64-$rot`,%r11
-+	or	%r9,$i0
-+	shl	\$$rot,$i1
-+	or	%r11,$i1
-+___
-+    }
-+}
-+
-+{ my $step=0;
-+
-+$code.=<<___;
-+.globl	Camellia_Ekeygen
-+.type	Camellia_Ekeygen,\@function,3
-+.align	16
-+Camellia_Ekeygen:
-+	push	%rbx
-+	push	%rbp
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lkey_prologue:
-+
-+	mov	%edi,${keyend}d		# put away arguments, keyBitLength
-+	mov	%rdx,$out		# keyTable
-+
-+	mov	0(%rsi),@S[0]		# load 0-127 bits
-+	mov	4(%rsi),@S[1]
-+	mov	8(%rsi),@S[2]
-+	mov	12(%rsi),@S[3]
-+
-+	bswap	@S[0]
-+	bswap	@S[1]
-+	bswap	@S[2]
-+	bswap	@S[3]
-+___
-+	&_saveround	(0,$out,@S);	# KL<<<0
-+$code.=<<___;
-+	cmp	\$128,$keyend		# check keyBitLength
-+	je	.L1st128
-+
-+	mov	16(%rsi),@S[0]		# load 128-191 bits
-+	mov	20(%rsi),@S[1]
-+	cmp	\$192,$keyend
-+	je	.L1st192
-+	mov	24(%rsi),@S[2]		# load 192-255 bits
-+	mov	28(%rsi),@S[3]
-+	jmp	.L1st256
-+.L1st192:
-+	mov	@S[0],@S[2]
-+	mov	@S[1],@S[3]
-+	not	@S[2]
-+	not	@S[3]
-+.L1st256:
-+	bswap	@S[0]
-+	bswap	@S[1]
-+	bswap	@S[2]
-+	bswap	@S[3]
-+___
-+	&_saveround	(4,$out,@S);	# temp storage for KR!
-+$code.=<<___;
-+	xor	0($out),@S[1]		# KR^KL
-+	xor	4($out),@S[0]
-+	xor	8($out),@S[3]
-+	xor	12($out),@S[2]
-+
-+.L1st128:
-+	lea	.LCamellia_SIGMA(%rip),$key
-+	lea	.LCamellia_SBOX(%rip),$Tbl
-+
-+	mov	0($key),$t1
-+	mov	4($key),$t0
-+___
-+	&Camellia_Feistel($step++);
-+	&Camellia_Feistel($step++);
-+$code.=<<___;
-+	xor	0($out),@S[1]		# ^KL
-+	xor	4($out),@S[0]
-+	xor	8($out),@S[3]
-+	xor	12($out),@S[2]
-+___
-+	&Camellia_Feistel($step++);
-+	&Camellia_Feistel($step++);
-+$code.=<<___;
-+	cmp	\$128,$keyend
-+	jne	.L2nd256
-+
-+	lea	128($out),$out		# size optimization
-+	shl	\$32,%r8		# @S[0]||
-+	shl	\$32,%r10		# @S[2]||
-+	or	%r9,%r8			# ||@S[1]
-+	or	%r11,%r10		# ||@S[3]
-+___
-+	&_loadround	(0,$out,-128,"%rax","%rbx");	# KL
-+	&_saveround	(2,$out,-128,"%r8","%r10");	# KA<<<0
-+	&_rotl128	("%rax","%rbx",15);
-+	&_saveround	(4,$out,-128,"%rax","%rbx");	# KL<<<15
-+	&_rotl128	("%r8","%r10",15);
-+	&_saveround	(6,$out,-128,"%r8","%r10");	# KA<<<15
-+	&_rotl128	("%r8","%r10",15);		# 15+15=30
-+	&_saveround	(8,$out,-128,"%r8","%r10");	# KA<<<30
-+	&_rotl128	("%rax","%rbx",30);		# 15+30=45
-+	&_saveround	(10,$out,-128,"%rax","%rbx");	# KL<<<45
-+	&_rotl128	("%r8","%r10",15);		# 30+15=45
-+	&_saveround	(12,$out,-128,"%r8");		# KA<<<45
-+	&_rotl128	("%rax","%rbx",15);		# 45+15=60
-+	&_saveround	(13,$out,-128,"%rbx");		# KL<<<60
-+	&_rotl128	("%r8","%r10",15);		# 45+15=60
-+	&_saveround	(14,$out,-128,"%r8","%r10");	# KA<<<60
-+	&_rotl128	("%rax","%rbx",17);		# 60+17=77
-+	&_saveround	(16,$out,-128,"%rax","%rbx");	# KL<<<77
-+	&_rotl128	("%rax","%rbx",17);		# 77+17=94
-+	&_saveround	(18,$out,-128,"%rax","%rbx");	# KL<<<94
-+	&_rotl128	("%r8","%r10",34);		# 60+34=94
-+	&_saveround	(20,$out,-128,"%r8","%r10");	# KA<<<94
-+	&_rotl128	("%rax","%rbx",17);		# 94+17=111
-+	&_saveround	(22,$out,-128,"%rax","%rbx");	# KL<<<111
-+	&_rotl128	("%r8","%r10",17);		# 94+17=111
-+	&_saveround	(24,$out,-128,"%r8","%r10");	# KA<<<111
-+$code.=<<___;
-+	mov	\$3,%eax
-+	jmp	.Ldone
-+.align	16
-+.L2nd256:
-+___
-+	&_saveround	(6,$out,@S);	# temp storage for KA!
-+$code.=<<___;
-+	xor	`4*8+0`($out),@S[1]	# KA^KR
-+	xor	`4*8+4`($out),@S[0]
-+	xor	`5*8+0`($out),@S[3]
-+	xor	`5*8+4`($out),@S[2]
-+___
-+	&Camellia_Feistel($step++);
-+	&Camellia_Feistel($step++);
-+
-+	&_loadround	(0,$out,"%rax","%rbx");	# KL
-+	&_loadround	(4,$out,"%rcx","%rdx");	# KR
-+	&_loadround	(6,$out,"%r14","%r15");	# KA
-+$code.=<<___;
-+	lea	128($out),$out		# size optimization
-+	shl	\$32,%r8		# @S[0]||
-+	shl	\$32,%r10		# @S[2]||
-+	or	%r9,%r8			# ||@S[1]
-+	or	%r11,%r10		# ||@S[3]
-+___
-+	&_saveround	(2,$out,-128,"%r8","%r10");	# KB<<<0
-+	&_rotl128	("%rcx","%rdx",15);
-+	&_saveround	(4,$out,-128,"%rcx","%rdx");	# KR<<<15
-+	&_rotl128	("%r14","%r15",15);
-+	&_saveround	(6,$out,-128,"%r14","%r15");	# KA<<<15
-+	&_rotl128	("%rcx","%rdx",15);		# 15+15=30
-+	&_saveround	(8,$out,-128,"%rcx","%rdx");	# KR<<<30
-+	&_rotl128	("%r8","%r10",30);
-+	&_saveround	(10,$out,-128,"%r8","%r10");	# KB<<<30
-+	&_rotl128	("%rax","%rbx",45);
-+	&_saveround	(12,$out,-128,"%rax","%rbx");	# KL<<<45
-+	&_rotl128	("%r14","%r15",30);		# 15+30=45
-+	&_saveround	(14,$out,-128,"%r14","%r15");	# KA<<<45
-+	&_rotl128	("%rax","%rbx",15);		# 45+15=60
-+	&_saveround	(16,$out,-128,"%rax","%rbx");	# KL<<<60
-+	&_rotl128	("%rcx","%rdx",30);		# 30+30=60
-+	&_saveround	(18,$out,-128,"%rcx","%rdx");	# KR<<<60
-+	&_rotl128	("%r8","%r10",30);		# 30+30=60
-+	&_saveround	(20,$out,-128,"%r8","%r10");	# KB<<<60
-+	&_rotl128	("%rax","%rbx",17);		# 60+17=77
-+	&_saveround	(22,$out,-128,"%rax","%rbx");	# KL<<<77
-+	&_rotl128	("%r14","%r15",32);		# 45+32=77
-+	&_saveround	(24,$out,-128,"%r14","%r15");	# KA<<<77
-+	&_rotl128	("%rcx","%rdx",34);		# 60+34=94
-+	&_saveround	(26,$out,-128,"%rcx","%rdx");	# KR<<<94
-+	&_rotl128	("%r14","%r15",17);		# 77+17=94
-+	&_saveround	(28,$out,-128,"%r14","%r15");	# KA<<<77
-+	&_rotl128	("%rax","%rbx",34);		# 77+34=111
-+	&_saveround	(30,$out,-128,"%rax","%rbx");	# KL<<<111
-+	&_rotl128	("%r8","%r10",51);		# 60+51=111
-+	&_saveround	(32,$out,-128,"%r8","%r10");	# KB<<<111
-+$code.=<<___;
-+	mov	\$4,%eax
-+.Ldone:
-+	mov	0(%rsp),%r15
-+	mov	8(%rsp),%r14
-+	mov	16(%rsp),%r13
-+	mov	24(%rsp),%rbp
-+	mov	32(%rsp),%rbx
-+	lea	40(%rsp),%rsp
-+.Lkey_epilogue:
-+	ret
-+.size	Camellia_Ekeygen,.-Camellia_Ekeygen
-+___
-+}
-+
-+@SBOX=(
-+112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
-+ 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
-+134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
-+166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77,
-+139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
-+223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215,
-+ 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
-+254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80,
-+170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
-+ 16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
-+135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226,
-+ 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
-+233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
-+120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
-+114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
-+ 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
-+
-+sub S1110 { my $i=shift; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i<<8; sprintf("0x%08x",$i); }
-+sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i; sprintf("0x%08x",$i); }
-+sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; $i=$i<<16|$i<<8|$i; sprintf("0x%08x",$i); }
-+sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; $i=$i<<24|$i<<8|$i; sprintf("0x%08x",$i); }
-+
-+$code.=<<___;
-+.align	64
-+.LCamellia_SIGMA:
-+.long	0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858
-+.long	0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5
-+.long	0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2
-+.long	0,          0,          0,          0
-+.LCamellia_SBOX:
-+___
-+# tables are interleaved, remember?
-+sub data_word { $code.=".long\t".join(',',@_)."\n"; }
-+for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
-+for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
-+
-+# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
-+#			size_t length, const CAMELLIA_KEY *key,
-+#			unsigned char *ivp,const int enc);
-+{
-+$_key="0(%rsp)";
-+$_end="8(%rsp)";	# inp+len&~15
-+$_res="16(%rsp)";	# len&15
-+$ivec="24(%rsp)";
-+$_ivp="40(%rsp)";
-+$_rsp="48(%rsp)";
-+
-+$code.=<<___;
-+.globl	Camellia_cbc_encrypt
-+.type	Camellia_cbc_encrypt,\@function,6
-+.align	16
-+Camellia_cbc_encrypt:
-+	cmp	\$0,%rdx
-+	je	.Lcbc_abort
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lcbc_prologue:
-+
-+	mov	%rsp,%rbp
-+	sub	\$64,%rsp
-+	and	\$-64,%rsp
-+
-+	# place stack frame just "above mod 1024" the key schedule,
-+	# this ensures that cache associativity suffices
-+	lea	-64-63(%rcx),%r10
-+	sub	%rsp,%r10
-+	neg	%r10
-+	and	\$0x3C0,%r10
-+	sub	%r10,%rsp
-+	#add	\$8,%rsp		# 8 is reserved for callee's ra
-+
-+	mov	%rdi,$inp		# inp argument
-+	mov	%rsi,$out		# out argument
-+	mov	%r8,%rbx		# ivp argument
-+	mov	%rcx,$key		# key argument
-+	mov	272(%rcx),${keyend}d	# grandRounds
-+
-+	mov	%r8,$_ivp
-+	mov	%rbp,$_rsp
-+
-+.Lcbc_body:
-+	lea	.LCamellia_SBOX(%rip),$Tbl
-+
-+	mov	\$32,%ecx
-+.align	4
-+.Lcbc_prefetch_sbox:
-+	mov	0($Tbl),%rax
-+	mov	32($Tbl),%rsi
-+	mov	64($Tbl),%rdi
-+	mov	96($Tbl),%r11
-+	lea	128($Tbl),$Tbl
-+	loop	.Lcbc_prefetch_sbox
-+	sub	\$4096,$Tbl
-+	shl	\$6,$keyend
-+	mov	%rdx,%rcx		# len argument
-+	lea	($key,$keyend),$keyend
-+
-+	cmp	\$0,%r9d		# enc argument
-+	je	.LCBC_DECRYPT
-+
-+	and	\$-16,%rdx
-+	and	\$15,%rcx		# length residue
-+	lea	($inp,%rdx),%rdx
-+	mov	$key,$_key
-+	mov	%rdx,$_end
-+	mov	%rcx,$_res
-+
-+	cmp	$inp,%rdx
-+	mov	0(%rbx),@S[0]		# load IV
-+	mov	4(%rbx),@S[1]
-+	mov	8(%rbx),@S[2]
-+	mov	12(%rbx),@S[3]
-+	je	.Lcbc_enc_tail
-+	jmp	.Lcbc_eloop
-+
-+.align	16
-+.Lcbc_eloop:
-+	xor	0($inp),@S[0]
-+	xor	4($inp),@S[1]
-+	xor	8($inp),@S[2]
-+	bswap	@S[0]
-+	xor	12($inp),@S[3]
-+	bswap	@S[1]
-+	bswap	@S[2]
-+	bswap	@S[3]
-+
-+	call	_x86_64_Camellia_encrypt
-+
-+	mov	$_key,$key		# "rewind" the key
-+	bswap	@S[0]
-+	mov	$_end,%rdx
-+	bswap	@S[1]
-+	mov	$_res,%rcx
-+	bswap	@S[2]
-+	mov	@S[0],0($out)
-+	bswap	@S[3]
-+	mov	@S[1],4($out)
-+	mov	@S[2],8($out)
-+	lea	16($inp),$inp
-+	mov	@S[3],12($out)
-+	cmp	%rdx,$inp
-+	lea	16($out),$out
-+	jne	.Lcbc_eloop
-+
-+	cmp	\$0,%rcx
-+	jne	.Lcbc_enc_tail
-+
-+	mov	$_ivp,$out
-+	mov	@S[0],0($out)		# write out IV residue
-+	mov	@S[1],4($out)
-+	mov	@S[2],8($out)
-+	mov	@S[3],12($out)
-+	jmp	.Lcbc_done
-+
-+.align	16
-+.Lcbc_enc_tail:
-+	xor	%rax,%rax
-+	mov	%rax,0+$ivec
-+	mov	%rax,8+$ivec
-+	mov	%rax,$_res
-+
-+.Lcbc_enc_pushf:
-+	pushfq
-+	cld
-+	mov	$inp,%rsi
-+	lea	8+$ivec,%rdi
-+	.long	0x9066A4F3		# rep movsb
-+	popfq
-+.Lcbc_enc_popf:
-+
-+	lea	$ivec,$inp
-+	lea	16+$ivec,%rax
-+	mov	%rax,$_end
-+	jmp	.Lcbc_eloop		# one more time
-+
-+.align	16
-+.LCBC_DECRYPT:
-+	xchg	$key,$keyend
-+	add	\$15,%rdx
-+	and	\$15,%rcx		# length residue
-+	and	\$-16,%rdx
-+	mov	$key,$_key
-+	lea	($inp,%rdx),%rdx
-+	mov	%rdx,$_end
-+	mov	%rcx,$_res
-+
-+	mov	(%rbx),%rax		# load IV
-+	mov	8(%rbx),%rbx
-+	jmp	.Lcbc_dloop
-+.align	16
-+.Lcbc_dloop:
-+	mov	0($inp),@S[0]
-+	mov	4($inp),@S[1]
-+	mov	8($inp),@S[2]
-+	bswap	@S[0]
-+	mov	12($inp),@S[3]
-+	bswap	@S[1]
-+	mov	%rax,0+$ivec		# save IV to temporary storage
-+	bswap	@S[2]
-+	mov	%rbx,8+$ivec
-+	bswap	@S[3]
-+
-+	call	_x86_64_Camellia_decrypt
-+
-+	mov	$_key,$key		# "rewind" the key
-+	mov	$_end,%rdx
-+	mov	$_res,%rcx
-+
-+	bswap	@S[0]
-+	mov	($inp),%rax		# load IV for next iteration
-+	bswap	@S[1]
-+	mov	8($inp),%rbx
-+	bswap	@S[2]
-+	xor	0+$ivec,@S[0]
-+	bswap	@S[3]
-+	xor	4+$ivec,@S[1]
-+	xor	8+$ivec,@S[2]
-+	lea	16($inp),$inp
-+	xor	12+$ivec,@S[3]
-+	cmp	%rdx,$inp
-+	je	.Lcbc_ddone
-+
-+	mov	@S[0],0($out)
-+	mov	@S[1],4($out)
-+	mov	@S[2],8($out)
-+	mov	@S[3],12($out)
-+
-+	lea	16($out),$out
-+	jmp	.Lcbc_dloop
-+
-+.align	16
-+.Lcbc_ddone:
-+	mov	$_ivp,%rdx
-+	cmp	\$0,%rcx
-+	jne	.Lcbc_dec_tail
-+
-+	mov	@S[0],0($out)
-+	mov	@S[1],4($out)
-+	mov	@S[2],8($out)
-+	mov	@S[3],12($out)
-+
-+	mov	%rax,(%rdx)		# write out IV residue
-+	mov	%rbx,8(%rdx)
-+	jmp	.Lcbc_done
-+.align	16
-+.Lcbc_dec_tail:
-+	mov	@S[0],0+$ivec
-+	mov	@S[1],4+$ivec
-+	mov	@S[2],8+$ivec
-+	mov	@S[3],12+$ivec
-+
-+.Lcbc_dec_pushf:
-+	pushfq
-+	cld
-+	lea	8+$ivec,%rsi
-+	lea	($out),%rdi
-+	.long	0x9066A4F3		# rep movsb
-+	popfq
-+.Lcbc_dec_popf:
-+
-+	mov	%rax,(%rdx)		# write out IV residue
-+	mov	%rbx,8(%rdx)
-+	jmp	.Lcbc_done
-+
-+.align	16
-+.Lcbc_done:
-+	mov	$_rsp,%rcx
-+	mov	0(%rcx),%r15
-+	mov	8(%rcx),%r14
-+	mov	16(%rcx),%r13
-+	mov	24(%rcx),%r12
-+	mov	32(%rcx),%rbp
-+	mov	40(%rcx),%rbx
-+	lea	48(%rcx),%rsp
-+.Lcbc_abort:
-+	ret
-+.size	Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
-+
-+.asciz	"Camellia for x86_64 by "
-+___
-+}
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	common_se_handler,\@abi-omnipotent
-+.align	16
-+common_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	lea	-64(%rsp),%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_prologue
-+
-+	lea	40(%rax),%rax
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r13
-+	mov	-32(%rax),%r14
-+	mov	-40(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	jmp	.Lcommon_seh_exit
-+.size	common_se_handler,.-common_se_handler
-+
-+.type	cbc_se_handler,\@abi-omnipotent
-+.align	16
-+cbc_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	lea	-64(%rsp),%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lcbc_prologue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lcbc_prologue
-+	jb	.Lin_cbc_prologue
-+
-+	lea	.Lcbc_body(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lcbc_body
-+	jb	.Lin_cbc_frame_setup
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	lea	.Lcbc_abort(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip>=.Lcbc_abort
-+	jae	.Lin_cbc_prologue
-+
-+	# handle pushf/popf in Camellia_cbc_encrypt
-+	lea	.Lcbc_enc_pushf(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<=.Lcbc_enc_pushf
-+	jbe	.Lin_cbc_no_flag
-+	lea	8(%rax),%rax
-+	lea	.Lcbc_enc_popf(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lcbc_enc_popf
-+	jb	.Lin_cbc_no_flag
-+	lea	-8(%rax),%rax
-+	lea	.Lcbc_dec_pushf(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<=.Lcbc_dec_pushf
-+	jbe	.Lin_cbc_no_flag
-+	lea	8(%rax),%rax
-+	lea	.Lcbc_dec_popf(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lcbc_dec_popf
-+	jb	.Lin_cbc_no_flag
-+	lea	-8(%rax),%rax
-+
-+.Lin_cbc_no_flag:
-+	mov	48(%rax),%rax		# $_rsp
-+	lea	48(%rax),%rax
-+
-+.Lin_cbc_frame_setup:
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lin_cbc_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+.align	4
-+.Lcommon_seh_exit:
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	lea	64(%rsp),%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	cbc_se_handler,.-cbc_se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_Camellia_EncryptBlock_Rounds
-+	.rva	.LSEH_end_Camellia_EncryptBlock_Rounds
-+	.rva	.LSEH_info_Camellia_EncryptBlock_Rounds
-+
-+	.rva	.LSEH_begin_Camellia_DecryptBlock_Rounds
-+	.rva	.LSEH_end_Camellia_DecryptBlock_Rounds
-+	.rva	.LSEH_info_Camellia_DecryptBlock_Rounds
-+
-+	.rva	.LSEH_begin_Camellia_Ekeygen
-+	.rva	.LSEH_end_Camellia_Ekeygen
-+	.rva	.LSEH_info_Camellia_Ekeygen
-+
-+	.rva	.LSEH_begin_Camellia_cbc_encrypt
-+	.rva	.LSEH_end_Camellia_cbc_encrypt
-+	.rva	.LSEH_info_Camellia_cbc_encrypt
-+
-+.section	.xdata
-+.align	8
-+.LSEH_info_Camellia_EncryptBlock_Rounds:
-+	.byte	9,0,0,0
-+	.rva	common_se_handler
-+	.rva	.Lenc_prologue,.Lenc_epilogue	# HandlerData[]
-+.LSEH_info_Camellia_DecryptBlock_Rounds:
-+	.byte	9,0,0,0
-+	.rva	common_se_handler
-+	.rva	.Ldec_prologue,.Ldec_epilogue	# HandlerData[]
-+.LSEH_info_Camellia_Ekeygen:
-+	.byte	9,0,0,0
-+	.rva	common_se_handler
-+	.rva	.Lkey_prologue,.Lkey_epilogue	# HandlerData[]
-+.LSEH_info_Camellia_cbc_encrypt:
-+	.byte	9,0,0,0
-+	.rva	cbc_se_handler
-+___
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmllt4-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmllt4-sparcv9.pl
-new file mode 100644
-index 0000000..ffe4a7d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/asm/cmllt4-sparcv9.pl
-@@ -0,0 +1,939 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by David S. Miller  and Andy Polyakov
-+# . The module is licensed under 2-clause BSD
-+# license. October 2012. All rights reserved.
-+# ====================================================================
-+
-+######################################################################
-+# Camellia for SPARC T4.
-+#
-+# As with AES below results [for aligned data] are virtually identical
-+# to critical path lenths for 3-cycle instruction latency:
-+#
-+#		128-bit key	192/256-
-+# CBC encrypt	4.14/4.21(*)	5.46/5.52
-+#			 (*) numbers after slash are for
-+#			     misaligned data.
-+#
-+# As with Intel AES-NI, question is if it's possible to improve
-+# performance of parallelizeable modes by interleaving round
-+# instructions. In Camellia every instruction is dependent on
-+# previous, which means that there is place for 2 additional ones
-+# in between two dependent. Can we expect 3x performance improvement?
-+# At least one can argue that it should be possible to break 2x
-+# barrier... For some reason not even 2x appears to be possible:
-+#
-+#		128-bit key	192/256-
-+# CBC decrypt	2.21/2.74	2.99/3.40
-+# CTR		2.15/2.68(*)	2.93/3.34
-+#			 (*) numbers after slash are for
-+#			     misaligned data.
-+#
-+# This is for 2x interleave. But compared to 1x interleave CBC decrypt
-+# improved by ... 0% for 128-bit key, and 11% for 192/256-bit one.
-+# So that out-of-order execution logic can take non-interleaved code
-+# to 1.87x, but can't take 2x interleaved one any further. There
-+# surely is some explanation... As result 3x interleave was not even
-+# attempted. Instead an effort was made to share specific modes
-+# implementations with AES module (therefore sparct4_modes.pl).
-+#
-+# To anchor to something else, software C implementation processes
-+# one byte in 38 cycles with 128-bit key on same processor.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "sparcv9_modes.pl";
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+$::evp=1;	# if $evp is set to 0, script generates module with
-+# Camellia_[en|de]crypt, Camellia_set_key and Camellia_cbc_encrypt
-+# entry points. These are fully compatible with openssl/camellia.h.
-+
-+######################################################################
-+# single-round subroutines
-+#
-+{
-+my ($inp,$out,$key,$rounds,$tmp,$mask)=map("%o$_",(0..5));
-+
-+$code=<<___;
-+#include "sparc_arch.h"
-+
-+.text
-+
-+.globl	cmll_t4_encrypt
-+.align	32
-+cmll_t4_encrypt:
-+	andcc		$inp, 7, %g1		! is input aligned?
-+	andn		$inp, 7, $inp
-+
-+	ldx		[$key + 0], %g4
-+	ldx		[$key + 8], %g5
-+
-+	ldx		[$inp + 0], %o4
-+	bz,pt		%icc, 1f
-+	ldx		[$inp + 8], %o5
-+	ldx		[$inp + 16], $inp
-+	sll		%g1, 3, %g1
-+	sub		%g0, %g1, %o3
-+	sllx		%o4, %g1, %o4
-+	sllx		%o5, %g1, %g1
-+	srlx		%o5, %o3, %o5
-+	srlx		$inp, %o3, %o3
-+	or		%o5, %o4, %o4
-+	or		%o3, %g1, %o5
-+1:
-+	ld		[$key + 272], $rounds	! grandRounds, 3 or 4
-+	ldd		[$key + 16], %f12
-+	ldd		[$key + 24], %f14
-+	xor		%g4, %o4, %o4
-+	xor		%g5, %o5, %o5
-+	ldd		[$key + 32], %f16
-+	ldd		[$key + 40], %f18
-+	movxtod		%o4, %f0
-+	movxtod		%o5, %f2
-+	ldd		[$key + 48], %f20
-+	ldd		[$key + 56], %f22
-+	sub		$rounds, 1, $rounds
-+	ldd		[$key + 64], %f24
-+	ldd		[$key + 72], %f26
-+	add		$key, 80, $key
-+
-+.Lenc:
-+	camellia_f	%f12, %f2, %f0, %f2
-+	ldd		[$key + 0], %f12
-+	sub		$rounds,1,$rounds
-+	camellia_f	%f14, %f0, %f2, %f0
-+	ldd		[$key + 8], %f14
-+	camellia_f	%f16, %f2, %f0, %f2
-+	ldd		[$key + 16], %f16
-+	camellia_f	%f18, %f0, %f2, %f0
-+	ldd		[$key + 24], %f18
-+	camellia_f	%f20, %f2, %f0, %f2
-+	ldd		[$key + 32], %f20
-+	camellia_f	%f22, %f0, %f2, %f0
-+	ldd		[$key + 40], %f22
-+	camellia_fl	%f24, %f0, %f0
-+	ldd		[$key + 48], %f24
-+	camellia_fli	%f26, %f2, %f2
-+	ldd		[$key + 56], %f26
-+	brnz,pt		$rounds, .Lenc
-+	add		$key, 64, $key
-+
-+	andcc		$out, 7, $tmp		! is output aligned?
-+	camellia_f	%f12, %f2, %f0, %f2
-+	camellia_f	%f14, %f0, %f2, %f0
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f18, %f0, %f2, %f0
-+	camellia_f	%f20, %f2, %f0, %f4
-+	camellia_f	%f22, %f0, %f4, %f2
-+	fxor		%f24, %f4, %f0
-+	fxor		%f26, %f2, %f2
-+
-+	bnz,pn		%icc, 2f
-+	nop
-+
-+	std		%f0, [$out + 0]
-+	retl
-+	std		%f2, [$out + 8]
-+
-+2:	alignaddrl	$out, %g0, $out
-+	mov		0xff, $mask
-+	srl		$mask, $tmp, $mask
-+
-+	faligndata	%f0, %f0, %f4
-+	faligndata	%f0, %f2, %f6
-+	faligndata	%f2, %f2, %f8
-+
-+	stda		%f4, [$out + $mask]0xc0	! partial store
-+	std		%f6, [$out + 8]
-+	add		$out, 16, $out
-+	orn		%g0, $mask, $mask
-+	retl
-+	stda		%f8, [$out + $mask]0xc0	! partial store
-+.type	cmll_t4_encrypt,#function
-+.size	cmll_t4_encrypt,.-cmll_t4_encrypt
-+
-+.globl	cmll_t4_decrypt
-+.align	32
-+cmll_t4_decrypt:
-+	ld		[$key + 272], $rounds	! grandRounds, 3 or 4
-+	andcc		$inp, 7, %g1		! is input aligned?
-+	andn		$inp, 7, $inp
-+
-+	sll		$rounds, 6, $rounds
-+	add		$rounds, $key, $key
-+
-+	ldx		[$inp + 0], %o4
-+	bz,pt		%icc, 1f
-+	ldx		[$inp + 8], %o5
-+	ldx		[$inp + 16], $inp
-+	sll		%g1, 3, %g1
-+	sub		%g0, %g1, %g4
-+	sllx		%o4, %g1, %o4
-+	sllx		%o5, %g1, %g1
-+	srlx		%o5, %g4, %o5
-+	srlx		$inp, %g4, %g4
-+	or		%o5, %o4, %o4
-+	or		%g4, %g1, %o5
-+1:
-+	ldx		[$key + 0], %g4
-+	ldx		[$key + 8], %g5
-+	ldd		[$key - 8], %f12
-+	ldd		[$key - 16], %f14
-+	xor		%g4, %o4, %o4
-+	xor		%g5, %o5, %o5
-+	ldd		[$key - 24], %f16
-+	ldd		[$key - 32], %f18
-+	movxtod		%o4, %f0
-+	movxtod		%o5, %f2
-+	ldd		[$key - 40], %f20
-+	ldd		[$key - 48], %f22
-+	sub		$rounds, 64, $rounds
-+	ldd		[$key - 56], %f24
-+	ldd		[$key - 64], %f26
-+	sub		$key, 64, $key
-+
-+.Ldec:
-+	camellia_f	%f12, %f2, %f0, %f2
-+	ldd		[$key - 8], %f12
-+	sub		$rounds, 64, $rounds
-+	camellia_f	%f14, %f0, %f2, %f0
-+	ldd		[$key - 16], %f14
-+	camellia_f	%f16, %f2, %f0, %f2
-+	ldd		[$key - 24], %f16
-+	camellia_f	%f18, %f0, %f2, %f0
-+	ldd		[$key - 32], %f18
-+	camellia_f	%f20, %f2, %f0, %f2
-+	ldd		[$key - 40], %f20
-+	camellia_f	%f22, %f0, %f2, %f0
-+	ldd		[$key - 48], %f22
-+	camellia_fl	%f24, %f0, %f0
-+	ldd		[$key - 56], %f24
-+	camellia_fli	%f26, %f2, %f2
-+	ldd		[$key - 64], %f26
-+	brnz,pt		$rounds, .Ldec
-+	sub		$key, 64, $key
-+
-+	andcc		$out, 7, $tmp		! is output aligned?
-+	camellia_f	%f12, %f2, %f0, %f2
-+	camellia_f	%f14, %f0, %f2, %f0
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f18, %f0, %f2, %f0
-+	camellia_f	%f20, %f2, %f0, %f4
-+	camellia_f	%f22, %f0, %f4, %f2
-+	fxor		%f26, %f4, %f0
-+	fxor		%f24, %f2, %f2
-+
-+	bnz,pn		%icc, 2f
-+	nop
-+
-+	std		%f0, [$out + 0]
-+	retl
-+	std		%f2, [$out + 8]
-+
-+2:	alignaddrl	$out, %g0, $out
-+	mov		0xff, $mask
-+	srl		$mask, $tmp, $mask
-+
-+	faligndata	%f0, %f0, %f4
-+	faligndata	%f0, %f2, %f6
-+	faligndata	%f2, %f2, %f8
-+
-+	stda		%f4, [$out + $mask]0xc0	! partial store
-+	std		%f6, [$out + 8]
-+	add		$out, 16, $out
-+	orn		%g0, $mask, $mask
-+	retl
-+	stda		%f8, [$out + $mask]0xc0	! partial store
-+.type	cmll_t4_decrypt,#function
-+.size	cmll_t4_decrypt,.-cmll_t4_decrypt
-+___
-+}
-+
-+######################################################################
-+# key setup subroutines
-+#
-+{
-+sub ROTL128 {
-+  my $rot = shift;
-+
-+	"srlx	%o4, 64-$rot, %g4\n\t".
-+	"sllx	%o4, $rot, %o4\n\t".
-+	"srlx	%o5, 64-$rot, %g5\n\t".
-+	"sllx	%o5, $rot, %o5\n\t".
-+	"or	%o4, %g5, %o4\n\t".
-+	"or	%o5, %g4, %o5";
-+}
-+
-+my ($inp,$bits,$out,$tmp)=map("%o$_",(0..5));
-+$code.=<<___;
-+.globl	cmll_t4_set_key
-+.align	32
-+cmll_t4_set_key:
-+	and		$inp, 7, $tmp
-+	alignaddr	$inp, %g0, $inp
-+	cmp		$bits, 192
-+	ldd		[$inp + 0], %f0
-+	bl,pt		%icc,.L128
-+	ldd		[$inp + 8], %f2
-+
-+	be,pt		%icc,.L192
-+	ldd		[$inp + 16], %f4
-+
-+	brz,pt		$tmp, .L256aligned
-+	ldd		[$inp + 24], %f6
-+
-+	ldd		[$inp + 32], %f8
-+	faligndata	%f0, %f2, %f0
-+	faligndata	%f2, %f4, %f2
-+	faligndata	%f4, %f6, %f4
-+	b		.L256aligned
-+	faligndata	%f6, %f8, %f6
-+
-+.align	16
-+.L192:
-+	brz,a,pt	$tmp, .L256aligned
-+	fnot2		%f4, %f6
-+
-+	ldd		[$inp + 24], %f6
-+	nop
-+	faligndata	%f0, %f2, %f0
-+	faligndata	%f2, %f4, %f2
-+	faligndata	%f4, %f6, %f4
-+	fnot2		%f4, %f6
-+
-+.L256aligned:
-+	std		%f0, [$out + 0]		! k[0, 1]
-+	fsrc2		%f0, %f28
-+	std		%f2, [$out + 8]		! k[2, 3]
-+	fsrc2		%f2, %f30
-+	fxor		%f4, %f0, %f0
-+	b		.L128key
-+	fxor		%f6, %f2, %f2
-+
-+.align	16
-+.L128:
-+	brz,pt		$tmp, .L128aligned
-+	nop
-+
-+	ldd		[$inp + 16], %f4
-+	nop
-+	faligndata	%f0, %f2, %f0
-+	faligndata	%f2, %f4, %f2
-+
-+.L128aligned:
-+	std		%f0, [$out + 0]		! k[0, 1]
-+	fsrc2		%f0, %f28
-+	std		%f2, [$out + 8]		! k[2, 3]
-+	fsrc2		%f2, %f30
-+
-+.L128key:
-+	mov		%o7, %o5
-+1:	call		.+8
-+	add		%o7, SIGMA-1b, %o4
-+	mov		%o5, %o7
-+
-+	ldd		[%o4 + 0], %f16
-+	ldd		[%o4 + 8], %f18
-+	ldd		[%o4 + 16], %f20
-+	ldd		[%o4 + 24], %f22
-+
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f18, %f0, %f2, %f0
-+	fxor		%f28, %f0, %f0
-+	fxor		%f30, %f2, %f2
-+	camellia_f	%f20, %f2, %f0, %f2
-+	camellia_f	%f22, %f0, %f2, %f0
-+
-+	bge,pn		%icc, .L256key
-+	nop
-+	std	%f0, [$out + 0x10]	! k[ 4,  5]
-+	std	%f2, [$out + 0x18]	! k[ 6,  7]
-+
-+	movdtox	%f0, %o4
-+	movdtox	%f2, %o5
-+	`&ROTL128(15)`
-+	stx	%o4, [$out + 0x30]	! k[12, 13]
-+	stx	%o5, [$out + 0x38]	! k[14, 15]
-+	`&ROTL128(15)`
-+	stx	%o4, [$out + 0x40]	! k[16, 17]
-+	stx	%o5, [$out + 0x48]	! k[18, 19]
-+	`&ROTL128(15)`
-+	stx	%o4, [$out + 0x60]	! k[24, 25]
-+	`&ROTL128(15)`
-+	stx	%o4, [$out + 0x70]	! k[28, 29]
-+	stx	%o5, [$out + 0x78]	! k[30, 31]
-+	`&ROTL128(34)`
-+	stx	%o4, [$out + 0xa0]	! k[40, 41]
-+	stx	%o5, [$out + 0xa8]	! k[42, 43]
-+	`&ROTL128(17)`
-+	stx	%o4, [$out + 0xc0]	! k[48, 49]
-+	stx	%o5, [$out + 0xc8]	! k[50, 51]
-+
-+	movdtox	%f28, %o4		! k[ 0,  1]
-+	movdtox	%f30, %o5		! k[ 2,  3]
-+	`&ROTL128(15)`
-+	stx	%o4, [$out + 0x20]	! k[ 8,  9]
-+	stx	%o5, [$out + 0x28]	! k[10, 11]
-+	`&ROTL128(30)`
-+	stx	%o4, [$out + 0x50]	! k[20, 21]
-+	stx	%o5, [$out + 0x58]	! k[22, 23]
-+	`&ROTL128(15)`
-+	stx	%o5, [$out + 0x68]	! k[26, 27]
-+	`&ROTL128(17)`
-+	stx	%o4, [$out + 0x80]	! k[32, 33]
-+	stx	%o5, [$out + 0x88]	! k[34, 35]
-+	`&ROTL128(17)`
-+	stx	%o4, [$out + 0x90]	! k[36, 37]
-+	stx	%o5, [$out + 0x98]	! k[38, 39]
-+	`&ROTL128(17)`
-+	stx	%o4, [$out + 0xb0]	! k[44, 45]
-+	stx	%o5, [$out + 0xb8]	! k[46, 47]
-+
-+	mov		3, $tmp
-+	st		$tmp, [$out + 0x110]
-+	retl
-+	xor		%o0, %o0, %o0
-+
-+.align	16
-+.L256key:
-+	ldd		[%o4 + 32], %f24
-+	ldd		[%o4 + 40], %f26
-+
-+	std		%f0, [$out + 0x30]	! k[12, 13]
-+	std		%f2, [$out + 0x38]	! k[14, 15]
-+
-+	fxor		%f4, %f0, %f0
-+	fxor		%f6, %f2, %f2
-+	camellia_f	%f24, %f2, %f0, %f2
-+	camellia_f	%f26, %f0, %f2, %f0
-+
-+	std	%f0, [$out + 0x10]	! k[ 4,  5]
-+	std	%f2, [$out + 0x18]	! k[ 6,  7]
-+
-+	movdtox	%f0, %o4
-+	movdtox	%f2, %o5
-+	`&ROTL128(30)`
-+	stx	%o4, [$out + 0x50]	! k[20, 21]
-+	stx	%o5, [$out + 0x58]	! k[22, 23]
-+	`&ROTL128(30)`
-+	stx	%o4, [$out + 0xa0]	! k[40, 41]
-+	stx	%o5, [$out + 0xa8]	! k[42, 43]
-+	`&ROTL128(51)`
-+	stx	%o4, [$out + 0x100]	! k[64, 65]
-+	stx	%o5, [$out + 0x108]	! k[66, 67]
-+
-+	movdtox	%f4, %o4		! k[ 8,  9]
-+	movdtox	%f6, %o5		! k[10, 11]
-+	`&ROTL128(15)`
-+	stx	%o4, [$out + 0x20]	! k[ 8,  9]
-+	stx	%o5, [$out + 0x28]	! k[10, 11]
-+	`&ROTL128(15)`
-+	stx	%o4, [$out + 0x40]	! k[16, 17]
-+	stx	%o5, [$out + 0x48]	! k[18, 19]
-+	`&ROTL128(30)`
-+	stx	%o4, [$out + 0x90]	! k[36, 37]
-+	stx	%o5, [$out + 0x98]	! k[38, 39]
-+	`&ROTL128(34)`
-+	stx	%o4, [$out + 0xd0]	! k[52, 53]
-+	stx	%o5, [$out + 0xd8]	! k[54, 55]
-+	ldx	[$out + 0x30], %o4	! k[12, 13]
-+	ldx	[$out + 0x38], %o5	! k[14, 15]
-+	`&ROTL128(15)`
-+	stx	%o4, [$out + 0x30]	! k[12, 13]
-+	stx	%o5, [$out + 0x38]	! k[14, 15]
-+	`&ROTL128(30)`
-+	stx	%o4, [$out + 0x70]	! k[28, 29]
-+	stx	%o5, [$out + 0x78]	! k[30, 31]
-+	srlx	%o4, 32, %g4
-+	srlx	%o5, 32, %g5
-+	st	%o4, [$out + 0xc0]	! k[48]
-+	st	%g5, [$out + 0xc4]	! k[49]
-+	st	%o5, [$out + 0xc8]	! k[50]
-+	st	%g4, [$out + 0xcc]	! k[51]
-+	`&ROTL128(49)`
-+	stx	%o4, [$out + 0xe0]	! k[56, 57]
-+	stx	%o5, [$out + 0xe8]	! k[58, 59]
-+
-+	movdtox	%f28, %o4		! k[ 0,  1]
-+	movdtox	%f30, %o5		! k[ 2,  3]
-+	`&ROTL128(45)`
-+	stx	%o4, [$out + 0x60]	! k[24, 25]
-+	stx	%o5, [$out + 0x68]	! k[26, 27]
-+	`&ROTL128(15)`
-+	stx	%o4, [$out + 0x80]	! k[32, 33]
-+	stx	%o5, [$out + 0x88]	! k[34, 35]
-+	`&ROTL128(17)`
-+	stx	%o4, [$out + 0xb0]	! k[44, 45]
-+	stx	%o5, [$out + 0xb8]	! k[46, 47]
-+	`&ROTL128(34)`
-+	stx	%o4, [$out + 0xf0]	! k[60, 61]
-+	stx	%o5, [$out + 0xf8]	! k[62, 63]
-+
-+	mov		4, $tmp
-+	st		$tmp, [$out + 0x110]
-+	retl
-+	xor		%o0, %o0, %o0
-+.type	cmll_t4_set_key,#function
-+.size	cmll_t4_set_key,.-cmll_t4_set_key
-+.align	32
-+SIGMA:
-+	.long	0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2
-+	.long	0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c
-+	.long	0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd
-+.type	SIGMA,#object
-+.size	SIGMA,.-SIGMA
-+.asciz	"Camellia for SPARC T4, David S. Miller, Andy Polyakov"
-+___
-+}
-+
-+{{{
-+my ($inp,$out,$len,$key,$ivec,$enc)=map("%i$_",(0..5));
-+my ($ileft,$iright,$ooff,$omask,$ivoff)=map("%l$_",(1..7));
-+
-+$code.=<<___;
-+.align	32
-+_cmll128_load_enckey:
-+	ldx		[$key + 0], %g4
-+	ldx		[$key + 8], %g5
-+___
-+for ($i=2; $i<26;$i++) {			# load key schedule
-+    $code.=<<___;
-+	ldd		[$key + `8*$i`], %f`12+2*$i`
-+___
-+}
-+$code.=<<___;
-+	retl
-+	nop
-+.type	_cmll128_load_enckey,#function
-+.size	_cmll128_load_enckey,.-_cmll128_load_enckey
-+_cmll256_load_enckey=_cmll128_load_enckey
-+
-+.align	32
-+_cmll256_load_deckey:
-+	ldd		[$key + 64], %f62
-+	ldd		[$key + 72], %f60
-+	b		.Load_deckey
-+	add		$key, 64, $key
-+_cmll128_load_deckey:
-+	ldd		[$key + 0], %f60
-+	ldd		[$key + 8], %f62
-+.Load_deckey:
-+___
-+for ($i=2; $i<24;$i++) {			# load key schedule
-+    $code.=<<___;
-+	ldd		[$key + `8*$i`], %f`62-2*$i`
-+___
-+}
-+$code.=<<___;
-+	ldx		[$key + 192], %g4
-+	retl
-+	ldx		[$key + 200], %g5
-+.type	_cmll256_load_deckey,#function
-+.size	_cmll256_load_deckey,.-_cmll256_load_deckey
-+
-+.align	32
-+_cmll128_encrypt_1x:
-+___
-+for ($i=0; $i<3; $i++) {
-+    $code.=<<___;
-+	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
-+___
-+$code.=<<___ if ($i<2);
-+	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
-+	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
-+	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
-+___
-+}
-+$code.=<<___;
-+	camellia_f	%f56, %f2, %f0, %f4
-+	camellia_f	%f58, %f0, %f4, %f2
-+	fxor		%f60, %f4, %f0
-+	retl
-+	fxor		%f62, %f2, %f2
-+.type	_cmll128_encrypt_1x,#function
-+.size	_cmll128_encrypt_1x,.-_cmll128_encrypt_1x
-+_cmll128_decrypt_1x=_cmll128_encrypt_1x
-+
-+.align	32
-+_cmll128_encrypt_2x:
-+___
-+for ($i=0; $i<3; $i++) {
-+    $code.=<<___;
-+	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+0`, %f6, %f4, %f6
-+	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+2`, %f4, %f6, %f4
-+	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+4`, %f6, %f4, %f6
-+	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+6`, %f4, %f6, %f4
-+___
-+$code.=<<___ if ($i<2);
-+	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+8`, %f6, %f4, %f6
-+	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+10`, %f4, %f6, %f4
-+	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
-+	camellia_fl	%f`16+16*$i+12`, %f4,      %f4
-+	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
-+	camellia_fli	%f`16+16*$i+14`, %f6,      %f6
-+___
-+}
-+$code.=<<___;
-+	camellia_f	%f56, %f2, %f0, %f8
-+	camellia_f	%f56, %f6, %f4, %f10
-+	camellia_f	%f58, %f0, %f8, %f2
-+	camellia_f	%f58, %f4, %f10, %f6
-+	fxor		%f60, %f8, %f0
-+	fxor		%f60, %f10, %f4
-+	fxor		%f62, %f2, %f2
-+	retl
-+	fxor		%f62, %f6, %f6
-+.type	_cmll128_encrypt_2x,#function
-+.size	_cmll128_encrypt_2x,.-_cmll128_encrypt_2x
-+_cmll128_decrypt_2x=_cmll128_encrypt_2x
-+
-+.align	32
-+_cmll256_encrypt_1x:
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f18, %f0, %f2, %f0
-+	ldd		[$key + 208], %f16
-+	ldd		[$key + 216], %f18
-+	camellia_f	%f20, %f2, %f0, %f2
-+	camellia_f	%f22, %f0, %f2, %f0
-+	ldd		[$key + 224], %f20
-+	ldd		[$key + 232], %f22
-+	camellia_f	%f24, %f2, %f0, %f2
-+	camellia_f	%f26, %f0, %f2, %f0
-+	ldd		[$key + 240], %f24
-+	ldd		[$key + 248], %f26
-+	camellia_fl	%f28, %f0, %f0
-+	camellia_fli	%f30, %f2, %f2
-+	ldd		[$key + 256], %f28
-+	ldd		[$key + 264], %f30
-+___
-+for ($i=1; $i<3; $i++) {
-+    $code.=<<___;
-+	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
-+	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
-+	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
-+___
-+}
-+$code.=<<___;
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f18, %f0, %f2, %f0
-+	ldd		[$key + 16], %f16
-+	ldd		[$key + 24], %f18
-+	camellia_f	%f20, %f2, %f0, %f2
-+	camellia_f	%f22, %f0, %f2, %f0
-+	ldd		[$key + 32], %f20
-+	ldd		[$key + 40], %f22
-+	camellia_f	%f24, %f2, %f0, %f4
-+	camellia_f	%f26, %f0, %f4, %f2
-+	ldd		[$key + 48], %f24
-+	ldd		[$key + 56], %f26
-+	fxor		%f28, %f4, %f0
-+	fxor		%f30, %f2, %f2
-+	ldd		[$key + 64], %f28
-+	retl
-+	ldd		[$key + 72], %f30
-+.type	_cmll256_encrypt_1x,#function
-+.size	_cmll256_encrypt_1x,.-_cmll256_encrypt_1x
-+
-+.align	32
-+_cmll256_encrypt_2x:
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f16, %f6, %f4, %f6
-+	camellia_f	%f18, %f0, %f2, %f0
-+	camellia_f	%f18, %f4, %f6, %f4
-+	ldd		[$key + 208], %f16
-+	ldd		[$key + 216], %f18
-+	camellia_f	%f20, %f2, %f0, %f2
-+	camellia_f	%f20, %f6, %f4, %f6
-+	camellia_f	%f22, %f0, %f2, %f0
-+	camellia_f	%f22, %f4, %f6, %f4
-+	ldd		[$key + 224], %f20
-+	ldd		[$key + 232], %f22
-+	camellia_f	%f24, %f2, %f0, %f2
-+	camellia_f	%f24, %f6, %f4, %f6
-+	camellia_f	%f26, %f0, %f2, %f0
-+	camellia_f	%f26, %f4, %f6, %f4
-+	ldd		[$key + 240], %f24
-+	ldd		[$key + 248], %f26
-+	camellia_fl	%f28, %f0, %f0
-+	camellia_fl	%f28, %f4, %f4
-+	camellia_fli	%f30, %f2, %f2
-+	camellia_fli	%f30, %f6, %f6
-+	ldd		[$key + 256], %f28
-+	ldd		[$key + 264], %f30
-+___
-+for ($i=1; $i<3; $i++) {
-+    $code.=<<___;
-+	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+0`, %f6, %f4, %f6
-+	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+2`, %f4, %f6, %f4
-+	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+4`, %f6, %f4, %f6
-+	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+6`, %f4, %f6, %f4
-+	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+8`, %f6, %f4, %f6
-+	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+10`, %f4, %f6, %f4
-+	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
-+	camellia_fl	%f`16+16*$i+12`, %f4,      %f4
-+	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
-+	camellia_fli	%f`16+16*$i+14`, %f6,      %f6
-+___
-+}
-+$code.=<<___;
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f16, %f6, %f4, %f6
-+	camellia_f	%f18, %f0, %f2, %f0
-+	camellia_f	%f18, %f4, %f6, %f4
-+	ldd		[$key + 16], %f16
-+	ldd		[$key + 24], %f18
-+	camellia_f	%f20, %f2, %f0, %f2
-+	camellia_f	%f20, %f6, %f4, %f6
-+	camellia_f	%f22, %f0, %f2, %f0
-+	camellia_f	%f22, %f4, %f6, %f4
-+	ldd		[$key + 32], %f20
-+	ldd		[$key + 40], %f22
-+	camellia_f	%f24, %f2, %f0, %f8
-+	camellia_f	%f24, %f6, %f4, %f10
-+	camellia_f	%f26, %f0, %f8, %f2
-+	camellia_f	%f26, %f4, %f10, %f6
-+	ldd		[$key + 48], %f24
-+	ldd		[$key + 56], %f26
-+	fxor		%f28, %f8, %f0
-+	fxor		%f28, %f10, %f4
-+	fxor		%f30, %f2, %f2
-+	fxor		%f30, %f6, %f6
-+	ldd		[$key + 64], %f28
-+	retl
-+	ldd		[$key + 72], %f30
-+.type	_cmll256_encrypt_2x,#function
-+.size	_cmll256_encrypt_2x,.-_cmll256_encrypt_2x
-+
-+.align	32
-+_cmll256_decrypt_1x:
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f18, %f0, %f2, %f0
-+	ldd		[$key - 8], %f16
-+	ldd		[$key - 16], %f18
-+	camellia_f	%f20, %f2, %f0, %f2
-+	camellia_f	%f22, %f0, %f2, %f0
-+	ldd		[$key - 24], %f20
-+	ldd		[$key - 32], %f22
-+	camellia_f	%f24, %f2, %f0, %f2
-+	camellia_f	%f26, %f0, %f2, %f0
-+	ldd		[$key - 40], %f24
-+	ldd		[$key - 48], %f26
-+	camellia_fl	%f28, %f0, %f0
-+	camellia_fli	%f30, %f2, %f2
-+	ldd		[$key - 56], %f28
-+	ldd		[$key - 64], %f30
-+___
-+for ($i=1; $i<3; $i++) {
-+    $code.=<<___;
-+	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
-+	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
-+	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
-+___
-+}
-+$code.=<<___;
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f18, %f0, %f2, %f0
-+	ldd		[$key + 184], %f16
-+	ldd		[$key + 176], %f18
-+	camellia_f	%f20, %f2, %f0, %f2
-+	camellia_f	%f22, %f0, %f2, %f0
-+	ldd		[$key + 168], %f20
-+	ldd		[$key + 160], %f22
-+	camellia_f	%f24, %f2, %f0, %f4
-+	camellia_f	%f26, %f0, %f4, %f2
-+	ldd		[$key + 152], %f24
-+	ldd		[$key + 144], %f26
-+	fxor		%f30, %f4, %f0
-+	fxor		%f28, %f2, %f2
-+	ldd		[$key + 136], %f28
-+	retl
-+	ldd		[$key + 128], %f30
-+.type	_cmll256_decrypt_1x,#function
-+.size	_cmll256_decrypt_1x,.-_cmll256_decrypt_1x
-+
-+.align	32
-+_cmll256_decrypt_2x:
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f16, %f6, %f4, %f6
-+	camellia_f	%f18, %f0, %f2, %f0
-+	camellia_f	%f18, %f4, %f6, %f4
-+	ldd		[$key - 8], %f16
-+	ldd		[$key - 16], %f18
-+	camellia_f	%f20, %f2, %f0, %f2
-+	camellia_f	%f20, %f6, %f4, %f6
-+	camellia_f	%f22, %f0, %f2, %f0
-+	camellia_f	%f22, %f4, %f6, %f4
-+	ldd		[$key - 24], %f20
-+	ldd		[$key - 32], %f22
-+	camellia_f	%f24, %f2, %f0, %f2
-+	camellia_f	%f24, %f6, %f4, %f6
-+	camellia_f	%f26, %f0, %f2, %f0
-+	camellia_f	%f26, %f4, %f6, %f4
-+	ldd		[$key - 40], %f24
-+	ldd		[$key - 48], %f26
-+	camellia_fl	%f28, %f0, %f0
-+	camellia_fl	%f28, %f4, %f4
-+	camellia_fli	%f30, %f2, %f2
-+	camellia_fli	%f30, %f6, %f6
-+	ldd		[$key - 56], %f28
-+	ldd		[$key - 64], %f30
-+___
-+for ($i=1; $i<3; $i++) {
-+    $code.=<<___;
-+	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+0`, %f6, %f4, %f6
-+	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+2`, %f4, %f6, %f4
-+	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+4`, %f6, %f4, %f6
-+	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+6`, %f4, %f6, %f4
-+	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
-+	camellia_f	%f`16+16*$i+8`, %f6, %f4, %f6
-+	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
-+	camellia_f	%f`16+16*$i+10`, %f4, %f6, %f4
-+	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
-+	camellia_fl	%f`16+16*$i+12`, %f4,      %f4
-+	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
-+	camellia_fli	%f`16+16*$i+14`, %f6,      %f6
-+___
-+}
-+$code.=<<___;
-+	camellia_f	%f16, %f2, %f0, %f2
-+	camellia_f	%f16, %f6, %f4, %f6
-+	camellia_f	%f18, %f0, %f2, %f0
-+	camellia_f	%f18, %f4, %f6, %f4
-+	ldd		[$key + 184], %f16
-+	ldd		[$key + 176], %f18
-+	camellia_f	%f20, %f2, %f0, %f2
-+	camellia_f	%f20, %f6, %f4, %f6
-+	camellia_f	%f22, %f0, %f2, %f0
-+	camellia_f	%f22, %f4, %f6, %f4
-+	ldd		[$key + 168], %f20
-+	ldd		[$key + 160], %f22
-+	camellia_f	%f24, %f2, %f0, %f8
-+	camellia_f	%f24, %f6, %f4, %f10
-+	camellia_f	%f26, %f0, %f8, %f2
-+	camellia_f	%f26, %f4, %f10, %f6
-+	ldd		[$key + 152], %f24
-+	ldd		[$key + 144], %f26
-+	fxor		%f30, %f8, %f0
-+	fxor		%f30, %f10, %f4
-+	fxor		%f28, %f2, %f2
-+	fxor		%f28, %f6, %f6
-+	ldd		[$key + 136], %f28
-+	retl
-+	ldd		[$key + 128], %f30
-+.type	_cmll256_decrypt_2x,#function
-+.size	_cmll256_decrypt_2x,.-_cmll256_decrypt_2x
-+___
-+
-+&alg_cbc_encrypt_implement("cmll",128);
-+&alg_cbc_encrypt_implement("cmll",256);
-+
-+&alg_cbc_decrypt_implement("cmll",128);
-+&alg_cbc_decrypt_implement("cmll",256);
-+
-+if ($::evp) {
-+    &alg_ctr32_implement("cmll",128);
-+    &alg_ctr32_implement("cmll",256);
-+}
-+}}}
-+
-+if (!$::evp) {
-+$code.=<<___;
-+.global	Camellia_encrypt
-+Camellia_encrypt=cmll_t4_encrypt
-+.global	Camellia_decrypt
-+Camellia_decrypt=cmll_t4_decrypt
-+.global	Camellia_set_key
-+.align	32
-+Camellia_set_key:
-+	andcc		%o2, 7, %g0		! double-check alignment
-+	bnz,a,pn	%icc, 1f
-+	mov		-1, %o0
-+	brz,a,pn	%o0, 1f
-+	mov		-1, %o0
-+	brz,a,pn	%o2, 1f
-+	mov		-1, %o0
-+	andncc		%o1, 0x1c0, %g0
-+	bnz,a,pn	%icc, 1f
-+	mov		-2, %o0
-+	cmp		%o1, 128
-+	bl,a,pn		%icc, 1f
-+	mov		-2, %o0
-+	b		cmll_t4_set_key
-+	nop
-+1:	retl
-+	nop
-+.type	Camellia_set_key,#function
-+.size	Camellia_set_key,.-Camellia_set_key
-+___
-+
-+my ($inp,$out,$len,$key,$ivec,$enc)=map("%o$_",(0..5));
-+
-+$code.=<<___;
-+.globl	Camellia_cbc_encrypt
-+.align	32
-+Camellia_cbc_encrypt:
-+	ld		[$key + 272], %g1
-+	nop
-+	brz		$enc, .Lcbc_decrypt
-+	cmp		%g1, 3
-+
-+	be,pt		%icc, cmll128_t4_cbc_encrypt
-+	nop
-+	ba		cmll256_t4_cbc_encrypt
-+	nop
-+
-+.Lcbc_decrypt:
-+	be,pt		%icc, cmll128_t4_cbc_decrypt
-+	nop
-+	ba		cmll256_t4_cbc_decrypt
-+	nop
-+.type	Camellia_cbc_encrypt,#function
-+.size	Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
-+___
-+}
-+
-+&emit_assembler();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/build.info
-new file mode 100644
-index 0000000..fd78272
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/build.info
-@@ -0,0 +1,11 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        cmll_ecb.c cmll_ofb.c cmll_cfb.c cmll_ctr.c \
-+        {- $target{cmll_asm_src} -}
-+
-+GENERATE[cmll-x86.s]=asm/cmll-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[cmll-x86.s]=../perlasm/x86asm.pl
-+GENERATE[cmll-x86_64.s]=asm/cmll-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[cmllt4-sparcv9.S]=asm/cmllt4-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[cmllt4-sparcv9.o]=..
-+DEPEND[cmllt4-sparcv9.S]=../perlasm/sparcv9_modes.pl
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/camellia.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/camellia.c
-new file mode 100644
-index 0000000..6641a62
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/camellia.c
-@@ -0,0 +1,541 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) .
-+ * ALL RIGHTS RESERVED.
-+ *
-+ * Intellectual Property information for Camellia:
-+ *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
-+ *
-+ * News Release for Announcement of Camellia open source:
-+ *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
-+ *
-+ * The Camellia Code included herein is developed by
-+ * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
-+ * to the OpenSSL project.
-+ */
-+
-+/*
-+ * Algorithm Specification
-+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
-+ */
-+
-+/*
-+ * This release balances code size and performance. In particular key
-+ * schedule setup is fully unrolled, because doing so *significantly*
-+ * reduces amount of instructions per setup round and code increase is
-+ * justifiable. In block functions on the other hand only inner loops
-+ * are unrolled, as full unroll gives only nominal performance boost,
-+ * while code size grows 4 or 7 times. Also, unlike previous versions
-+ * this one "encourages" compiler to keep intermediate variables in
-+ * registers, which should give better "all round" results, in other
-+ * words reasonable performance even with not so modern compilers.
-+ */
-+
-+#include 
-+#include "cmll_locl.h"
-+#include 
-+#include 
-+
-+/* 32-bit rotations */
-+#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
-+# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
-+#  define RightRotate(x, s) _lrotr(x, s)
-+#  define LeftRotate(x, s)  _lrotl(x, s)
-+#  if _MSC_VER >= 1400
-+#   define SWAP(x) _byteswap_ulong(x)
-+#  else
-+#   define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
-+#  endif
-+#  define GETU32(p)   SWAP(*((u32 *)(p)))
-+#  define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v)))
-+# elif defined(__GNUC__) && __GNUC__>=2
-+#  if defined(__i386) || defined(__x86_64)
-+#   define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
-+#   define LeftRotate(x,s)  ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
-+#   if defined(B_ENDIAN)        /* stratus.com does it */
-+#    define GETU32(p)   (*(u32 *)(p))
-+#    define PUTU32(p,v) (*(u32 *)(p)=(v))
-+#   else
-+#    define GETU32(p)   ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; })
-+#    define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; })
-+#   endif
-+#  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
-+        defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
-+#   define LeftRotate(x,s)  ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; })
-+#   define RightRotate(x,s) LeftRotate(x,(32-s))
-+#  elif defined(__s390x__)
-+#   define LeftRotate(x,s)  ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; })
-+#   define RightRotate(x,s) LeftRotate(x,(32-s))
-+#   define GETU32(p)   (*(u32 *)(p))
-+#   define PUTU32(p,v) (*(u32 *)(p)=(v))
-+#  endif
-+# endif
-+#endif
-+
-+#if !defined(RightRotate) && !defined(LeftRotate)
-+# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) )
-+# define LeftRotate(x, s)  ( ((x) << (s)) + ((x) >> (32 - s)) )
-+#endif
-+
-+#if !defined(GETU32) && !defined(PUTU32)
-+# define GETU32(p)   (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] <<  8) ^ ((u32)(p)[3]))
-+# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >>  8), (p)[3] = (u8)(v))
-+#endif
-+
-+/* S-box data */
-+#define SBOX1_1110 Camellia_SBOX[0]
-+#define SBOX4_4404 Camellia_SBOX[1]
-+#define SBOX2_0222 Camellia_SBOX[2]
-+#define SBOX3_3033 Camellia_SBOX[3]
-+static const u32 Camellia_SBOX[][256] = {
-+    {0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700,
-+     0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500,
-+     0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00,
-+     0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
-+     0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500,
-+     0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00,
-+     0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000,
-+     0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
-+     0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700,
-+     0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600,
-+     0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00,
-+     0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
-+     0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100,
-+     0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200,
-+     0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700,
-+     0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
-+     0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00,
-+     0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600,
-+     0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400,
-+     0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
-+     0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00,
-+     0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00,
-+     0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00,
-+     0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
-+     0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700,
-+     0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00,
-+     0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00,
-+     0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
-+     0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00,
-+     0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600,
-+     0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600,
-+     0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
-+     0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00,
-+     0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600,
-+     0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800,
-+     0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
-+     0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200,
-+     0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500,
-+     0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900,
-+     0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
-+     0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900,
-+     0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
-+     0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00},
-+    {0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057,
-+     0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5,
-+     0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af,
-+     0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
-+     0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a,
-+     0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0,
-+     0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb,
-+     0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
-+     0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c,
-+     0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a,
-+     0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0,
-+     0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
-+     0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6,
-+     0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090,
-+     0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8,
-+     0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
-+     0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9,
-+     0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071,
-+     0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9,
-+     0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
-+     0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad,
-+     0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5,
-+     0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093,
-+     0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
-+     0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f,
-+     0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d,
-+     0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066,
-+     0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
-+     0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031,
-+     0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c,
-+     0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2,
-+     0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
-+     0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095,
-+     0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db,
-+     0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002,
-+     0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
-+     0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b,
-+     0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e,
-+     0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a,
-+     0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
-+     0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068,
-+     0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
-+     0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e},
-+    {0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e,
-+     0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a,
-+     0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf,
-+     0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
-+     0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca,
-+     0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f,
-+     0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060,
-+     0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
-+     0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e,
-+     0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad,
-+     0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a,
-+     0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
-+     0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363,
-+     0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585,
-+     0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f,
-+     0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
-+     0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636,
-+     0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c,
-+     0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888,
-+     0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
-+     0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9,
-+     0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa,
-+     0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6,
-+     0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
-+     0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef,
-+     0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5,
-+     0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8,
-+     0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
-+     0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe,
-+     0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c,
-+     0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d,
-+     0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
-+     0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc,
-+     0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d,
-+     0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131,
-+     0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
-+     0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545,
-+     0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa,
-+     0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292,
-+     0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
-+     0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393,
-+     0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
-+     0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d},
-+    {0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393,
-+     0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a,
-+     0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7,
-+     0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
-+     0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2,
-+     0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7,
-+     0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818,
-+     0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
-+     0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3,
-+     0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b,
-+     0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686,
-+     0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
-+     0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8,
-+     0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161,
-+     0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb,
-+     0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
-+     0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d,
-+     0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b,
-+     0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222,
-+     0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
-+     0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e,
-+     0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe,
-+     0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad,
-+     0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
-+     0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb,
-+     0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d,
-+     0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e,
-+     0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
-+     0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf,
-+     0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313,
-+     0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b,
-+     0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
-+     0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737,
-+     0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b,
-+     0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c,
-+     0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
-+     0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151,
-+     0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa,
-+     0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4,
-+     0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
-+     0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4,
-+     0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
-+     0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f}
-+};
-+
-+/* Key generation constants */
-+static const u32 SIGMA[] = {
-+    0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be,
-+    0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd
-+};
-+
-+/* The phi algorithm given in C.2.7 of the Camellia spec document. */
-+/*
-+ * This version does not attempt to minimize amount of temporary
-+ * variables, but instead explicitly exposes algorithm's parallelism.
-+ * It is therefore most appropriate for platforms with not less than
-+ * ~16 registers. For platforms with less registers [well, x86 to be
-+ * specific] assembler version should be/is provided anyway...
-+ */
-+#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\
-+        register u32 _t0,_t1,_t2,_t3;\
-+\
-+        _t0  = _s0 ^ (_key)[0];\
-+        _t3  = SBOX4_4404[_t0&0xff];\
-+        _t1  = _s1 ^ (_key)[1];\
-+        _t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\
-+        _t2  = SBOX1_1110[_t1&0xff];\
-+        _t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\
-+        _t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\
-+        _t3 ^= SBOX1_1110[(_t0 >> 24)];\
-+        _t2 ^= _t3;\
-+        _t3  = RightRotate(_t3,8);\
-+        _t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\
-+        _s3 ^= _t3;\
-+        _t2 ^= SBOX2_0222[(_t1 >> 24)];\
-+        _s2 ^= _t2; \
-+        _s3 ^= _t2;\
-+} while(0)
-+
-+/*
-+ * Note that n has to be less than 32. Rotations for larger amount
-+ * of bits are achieved by "rotating" order of s-elements and
-+ * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32).
-+ */
-+#define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\
-+        u32 _t0=_s0>>(32-_n);\
-+        _s0 = (_s0<<_n) | (_s1>>(32-_n));\
-+        _s1 = (_s1<<_n) | (_s2>>(32-_n));\
-+        _s2 = (_s2<<_n) | (_s3>>(32-_n));\
-+        _s3 = (_s3<<_n) | _t0;\
-+} while (0)
-+
-+int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k)
-+{
-+    register u32 s0, s1, s2, s3;
-+
-+    k[0] = s0 = GETU32(rawKey);
-+    k[1] = s1 = GETU32(rawKey + 4);
-+    k[2] = s2 = GETU32(rawKey + 8);
-+    k[3] = s3 = GETU32(rawKey + 12);
-+
-+    if (keyBitLength != 128) {
-+        k[8] = s0 = GETU32(rawKey + 16);
-+        k[9] = s1 = GETU32(rawKey + 20);
-+        if (keyBitLength == 192) {
-+            k[10] = s2 = ~s0;
-+            k[11] = s3 = ~s1;
-+        } else {
-+            k[10] = s2 = GETU32(rawKey + 24);
-+            k[11] = s3 = GETU32(rawKey + 28);
-+        }
-+        s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
-+    }
-+
-+    /* Use the Feistel routine to scramble the key material */
-+    Camellia_Feistel(s0, s1, s2, s3, SIGMA + 0);
-+    Camellia_Feistel(s2, s3, s0, s1, SIGMA + 2);
-+
-+    s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
-+    Camellia_Feistel(s0, s1, s2, s3, SIGMA + 4);
-+    Camellia_Feistel(s2, s3, s0, s1, SIGMA + 6);
-+
-+    /* Fill the keyTable. Requires many block rotations. */
-+    if (keyBitLength == 128) {
-+        k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3;
-+        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */
-+        k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
-+        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 30 */
-+        k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
-+        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 45 */
-+        k[24] = s0, k[25] = s1;
-+        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 60 */
-+        k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
-+        RotLeft128(s1, s2, s3, s0, 2); /* KA <<< 94 */
-+        k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0;
-+        RotLeft128(s1, s2, s3, s0, 17); /* KA <<<111 */
-+        k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
-+
-+        s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3];
-+        RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 15 */
-+        k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3;
-+        RotLeft128(s0, s1, s2, s3, 30); /* KL <<< 45 */
-+        k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
-+        RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 60 */
-+        k[26] = s2, k[27] = s3;
-+        RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 77 */
-+        k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3;
-+        RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 94 */
-+        k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
-+        RotLeft128(s0, s1, s2, s3, 17); /* KL <<<111 */
-+        k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3;
-+
-+        return 3;               /* grand rounds */
-+    } else {
-+        k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
-+        s0 ^= k[8], s1 ^= k[9], s2 ^= k[10], s3 ^= k[11];
-+        Camellia_Feistel(s0, s1, s2, s3, (SIGMA + 8));
-+        Camellia_Feistel(s2, s3, s0, s1, (SIGMA + 10));
-+
-+        k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3;
-+        RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 30 */
-+        k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
-+        RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 60 */
-+        k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3;
-+        RotLeft128(s1, s2, s3, s0, 19); /* KB <<<111 */
-+        k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0;
-+
-+        s0 = k[8], s1 = k[9], s2 = k[10], s3 = k[11];
-+        RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 15 */
-+        k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3;
-+        RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 30 */
-+        k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
-+        RotLeft128(s0, s1, s2, s3, 30); /* KR <<< 60 */
-+        k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
-+        RotLeft128(s1, s2, s3, s0, 2); /* KR <<< 94 */
-+        k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0;
-+
-+        s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15];
-+        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */
-+        k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
-+        RotLeft128(s0, s1, s2, s3, 30); /* KA <<< 45 */
-+        k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
-+        /* KA <<< 77 */
-+        k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
-+        RotLeft128(s1, s2, s3, s0, 17); /* KA <<< 94 */
-+        k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0;
-+
-+        s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3];
-+        RotLeft128(s1, s2, s3, s0, 13); /* KL <<< 45 */
-+        k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0;
-+        RotLeft128(s1, s2, s3, s0, 15); /* KL <<< 60 */
-+        k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0;
-+        RotLeft128(s1, s2, s3, s0, 17); /* KL <<< 77 */
-+        k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0;
-+        RotLeft128(s2, s3, s0, s1, 2); /* KL <<<111 */
-+        k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1;
-+
-+        return 4;               /* grand rounds */
-+    }
-+    /*
-+     * It is possible to perform certain precalculations, which
-+     * would spare few cycles in block procedure. It's not done,
-+     * because it upsets the performance balance between key
-+     * setup and block procedures, negatively affecting overall
-+     * throughput in applications operating on short messages
-+     * and volatile keys.
-+     */
-+}
-+
-+void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[],
-+                                  const KEY_TABLE_TYPE keyTable,
-+                                  u8 ciphertext[])
-+{
-+    register u32 s0, s1, s2, s3;
-+    const u32 *k = keyTable, *kend = keyTable + grandRounds * 16;
-+
-+    s0 = GETU32(plaintext) ^ k[0];
-+    s1 = GETU32(plaintext + 4) ^ k[1];
-+    s2 = GETU32(plaintext + 8) ^ k[2];
-+    s3 = GETU32(plaintext + 12) ^ k[3];
-+    k += 4;
-+
-+    while (1) {
-+        /* Camellia makes 6 Feistel rounds */
-+        Camellia_Feistel(s0, s1, s2, s3, k + 0);
-+        Camellia_Feistel(s2, s3, s0, s1, k + 2);
-+        Camellia_Feistel(s0, s1, s2, s3, k + 4);
-+        Camellia_Feistel(s2, s3, s0, s1, k + 6);
-+        Camellia_Feistel(s0, s1, s2, s3, k + 8);
-+        Camellia_Feistel(s2, s3, s0, s1, k + 10);
-+        k += 12;
-+
-+        if (k == kend)
-+            break;
-+
-+        /*
-+         * This is the same function as the diffusion function D of the
-+         * accompanying documentation. See section 3.2 for properties of the
-+         * FLlayer function.
-+         */
-+        s1 ^= LeftRotate(s0 & k[0], 1);
-+        s2 ^= s3 | k[3];
-+        s0 ^= s1 | k[1];
-+        s3 ^= LeftRotate(s2 & k[2], 1);
-+        k += 4;
-+    }
-+
-+    s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
-+
-+    PUTU32(ciphertext, s2);
-+    PUTU32(ciphertext + 4, s3);
-+    PUTU32(ciphertext + 8, s0);
-+    PUTU32(ciphertext + 12, s1);
-+}
-+
-+void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[],
-+                           const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
-+{
-+    Camellia_EncryptBlock_Rounds(keyBitLength == 128 ? 3 : 4,
-+                                 plaintext, keyTable, ciphertext);
-+}
-+
-+void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[],
-+                                  const KEY_TABLE_TYPE keyTable,
-+                                  u8 plaintext[])
-+{
-+    u32 s0, s1, s2, s3;
-+    const u32 *k = keyTable + grandRounds * 16, *kend = keyTable + 4;
-+
-+    s0 = GETU32(ciphertext) ^ k[0];
-+    s1 = GETU32(ciphertext + 4) ^ k[1];
-+    s2 = GETU32(ciphertext + 8) ^ k[2];
-+    s3 = GETU32(ciphertext + 12) ^ k[3];
-+
-+    while (1) {
-+        /* Camellia makes 6 Feistel rounds */
-+        k -= 12;
-+        Camellia_Feistel(s0, s1, s2, s3, k + 10);
-+        Camellia_Feistel(s2, s3, s0, s1, k + 8);
-+        Camellia_Feistel(s0, s1, s2, s3, k + 6);
-+        Camellia_Feistel(s2, s3, s0, s1, k + 4);
-+        Camellia_Feistel(s0, s1, s2, s3, k + 2);
-+        Camellia_Feistel(s2, s3, s0, s1, k + 0);
-+
-+        if (k == kend)
-+            break;
-+
-+        /*
-+         * This is the same function as the diffusion function D of the
-+         * accompanying documentation. See section 3.2 for properties of the
-+         * FLlayer function.
-+         */
-+        k -= 4;
-+        s1 ^= LeftRotate(s0 & k[2], 1);
-+        s2 ^= s3 | k[1];
-+        s0 ^= s1 | k[3];
-+        s3 ^= LeftRotate(s2 & k[0], 1);
-+    }
-+
-+    k -= 4;
-+    s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
-+
-+    PUTU32(plaintext, s2);
-+    PUTU32(plaintext + 4, s3);
-+    PUTU32(plaintext + 8, s0);
-+    PUTU32(plaintext + 12, s1);
-+}
-+
-+void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[],
-+                           const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
-+{
-+    Camellia_DecryptBlock_Rounds(keyBitLength == 128 ? 3 : 4,
-+                                 plaintext, keyTable, ciphertext);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_cbc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_cbc.c
-new file mode 100644
-index 0000000..b19171d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_cbc.c
-@@ -0,0 +1,24 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                          size_t len, const CAMELLIA_KEY *key,
-+                          unsigned char *ivec, const int enc)
-+{
-+
-+    if (enc)
-+        CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
-+                              (block128_f) Camellia_encrypt);
-+    else
-+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
-+                              (block128_f) Camellia_decrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_cfb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_cfb.c
-new file mode 100644
-index 0000000..4f49ead
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_cfb.c
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+/*
-+ * The input and output encrypted as though 128bit cfb mode is being used.
-+ * The extra state information to record how much of the 128bit block we have
-+ * used is contained in *num;
-+ */
-+
-+void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
-+                             size_t length, const CAMELLIA_KEY *key,
-+                             unsigned char *ivec, int *num, const int enc)
-+{
-+
-+    CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
-+                          (block128_f) Camellia_encrypt);
-+}
-+
-+/* N.B. This expects the input to be packed, MS bit first */
-+void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t length, const CAMELLIA_KEY *key,
-+                           unsigned char *ivec, int *num, const int enc)
-+{
-+    CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
-+                            (block128_f) Camellia_encrypt);
-+}
-+
-+void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t length, const CAMELLIA_KEY *key,
-+                           unsigned char *ivec, int *num, const int enc)
-+{
-+    CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
-+                            (block128_f) Camellia_encrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ctr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ctr.c
-new file mode 100644
-index 0000000..161d1e1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ctr.c
-@@ -0,0 +1,22 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
-+                             size_t length, const CAMELLIA_KEY *key,
-+                             unsigned char ivec[CAMELLIA_BLOCK_SIZE],
-+                             unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
-+                             unsigned int *num)
-+{
-+
-+    CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num,
-+                          (block128_f) Camellia_encrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ecb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ecb.c
-new file mode 100644
-index 0000000..d932f1b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ecb.c
-@@ -0,0 +1,20 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "cmll_locl.h"
-+
-+void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
-+                          const CAMELLIA_KEY *key, const int enc)
-+{
-+    if (CAMELLIA_ENCRYPT == enc)
-+        Camellia_encrypt(in, out, key);
-+    else
-+        Camellia_decrypt(in, out, key);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_locl.h
-new file mode 100644
-index 0000000..6403b39
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_locl.h
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) .
-+ * ALL RIGHTS RESERVED.
-+ *
-+ * Intellectual Property information for Camellia:
-+ *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
-+ *
-+ * News Release for Announcement of Camellia open source:
-+ *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
-+ *
-+ * The Camellia Code included herein is developed by
-+ * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
-+ * to the OpenSSL project.
-+ */
-+
-+#ifndef HEADER_CAMELLIA_LOCL_H
-+# define HEADER_CAMELLIA_LOCL_H
-+
-+typedef unsigned int u32;
-+typedef unsigned char u8;
-+
-+int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey,
-+                     KEY_TABLE_TYPE keyTable);
-+void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[],
-+                                  const KEY_TABLE_TYPE keyTable,
-+                                  u8 ciphertext[]);
-+void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[],
-+                                  const KEY_TABLE_TYPE keyTable,
-+                                  u8 plaintext[]);
-+void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[],
-+                           const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
-+void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[],
-+                           const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
-+#endif                          /* #ifndef HEADER_CAMELLIA_LOCL_H */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_misc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_misc.c
-new file mode 100644
-index 0000000..e5f014b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_misc.c
-@@ -0,0 +1,35 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "cmll_locl.h"
-+
-+int Camellia_set_key(const unsigned char *userKey, const int bits,
-+                     CAMELLIA_KEY *key)
-+{
-+    if (!userKey || !key)
-+        return -1;
-+    if (bits != 128 && bits != 192 && bits != 256)
-+        return -2;
-+    key->grand_rounds = Camellia_Ekeygen(bits, userKey, key->u.rd_key);
-+    return 0;
-+}
-+
-+void Camellia_encrypt(const unsigned char *in, unsigned char *out,
-+                      const CAMELLIA_KEY *key)
-+{
-+    Camellia_EncryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out);
-+}
-+
-+void Camellia_decrypt(const unsigned char *in, unsigned char *out,
-+                      const CAMELLIA_KEY *key)
-+{
-+    Camellia_DecryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ofb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ofb.c
-new file mode 100644
-index 0000000..b43c685
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/camellia/cmll_ofb.c
-@@ -0,0 +1,24 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+/*
-+ * The input and output encrypted as though 128bit ofb mode is being used.
-+ * The extra state information to record how much of the 128bit block we have
-+ * used is contained in *num;
-+ */
-+void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
-+                             size_t length, const CAMELLIA_KEY *key,
-+                             unsigned char *ivec, int *num)
-+{
-+    CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
-+                          (block128_f) Camellia_encrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/asm/cast-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/asm/cast-586.pl
-new file mode 100644
-index 0000000..6beb9c5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/asm/cast-586.pl
-@@ -0,0 +1,192 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# This flag makes the inner loop one cycle longer, but generates 
-+# code that runs %30 faster on the pentium pro/II, 44% faster
-+# of PIII, while only %7 slower on the pentium.
-+# By default, this flag is on.
-+$ppro=1;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+require "cbc.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"cast-586.pl",$ARGV[$#ARGV] eq "386");
-+
-+$CAST_ROUNDS=16;
-+$L="edi";
-+$R="esi";
-+$K="ebp";
-+$tmp1="ecx";
-+$tmp2="ebx";
-+$tmp3="eax";
-+$tmp4="edx";
-+$S1="CAST_S_table0";
-+$S2="CAST_S_table1";
-+$S3="CAST_S_table2";
-+$S4="CAST_S_table3";
-+
-+@F1=("add","xor","sub");
-+@F2=("xor","sub","add");
-+@F3=("sub","add","xor");
-+
-+&CAST_encrypt("CAST_encrypt",1);
-+&CAST_encrypt("CAST_decrypt",0);
-+&cbc("CAST_cbc_encrypt","CAST_encrypt","CAST_decrypt",1,4,5,3,-1,-1);
-+
-+&asm_finish();
-+
-+close STDOUT;
-+
-+sub CAST_encrypt {
-+    local($name,$enc)=@_;
-+
-+    local($win_ex)=<<"EOF";
-+EXTERN	_CAST_S_table0:DWORD
-+EXTERN	_CAST_S_table1:DWORD
-+EXTERN	_CAST_S_table2:DWORD
-+EXTERN	_CAST_S_table3:DWORD
-+EOF
-+    &main::external_label(
-+			  "CAST_S_table0",
-+			  "CAST_S_table1",
-+			  "CAST_S_table2",
-+			  "CAST_S_table3",
-+			  );
-+
-+    &function_begin_B($name,$win_ex);
-+
-+    &comment("");
-+
-+    &push("ebp");
-+    &push("ebx");
-+    &mov($tmp2,&wparam(0));
-+    &mov($K,&wparam(1));
-+    &push("esi");
-+    &push("edi");
-+
-+    &comment("Load the 2 words");
-+    &mov($L,&DWP(0,$tmp2,"",0));
-+    &mov($R,&DWP(4,$tmp2,"",0));
-+
-+    &comment('Get short key flag');
-+    &mov($tmp3,&DWP(128,$K,"",0));
-+    if($enc) {
-+	&push($tmp3);
-+    } else {
-+	&or($tmp3,$tmp3);
-+	&jnz(&label('cast_dec_skip'));
-+    }
-+
-+    &xor($tmp3,	$tmp3);
-+
-+    # encrypting part
-+
-+    if ($enc) {
-+	&E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&comment('test short key flag');
-+	&pop($tmp4);
-+	&or($tmp4,$tmp4);
-+	&jnz(&label('cast_enc_done'));
-+	&E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+    } else {
-+	&E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&set_label('cast_dec_skip');
-+	&E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4);
-+	&E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4);
-+    }
-+
-+    &set_label('cast_enc_done') if $enc;
-+# Why the nop? - Ben 17/1/99
-+    &nop();
-+    &mov($tmp3,&wparam(0));
-+    &mov(&DWP(4,$tmp3,"",0),$L);
-+    &mov(&DWP(0,$tmp3,"",0),$R);
-+    &function_end($name);
-+}
-+
-+sub E_CAST {
-+    local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_;
-+    # Ri needs to have 16 pre added.
-+
-+    &comment("round $i");
-+    &mov(	$tmp4,		&DWP($i*8,$K,"",1));
-+
-+    &mov(	$tmp1,		&DWP($i*8+4,$K,"",1));
-+    &$OP1(	$tmp4,		$R);
-+
-+    &rotl(	$tmp4,		&LB($tmp1));
-+
-+    if ($ppro) {
-+	&xor(	$tmp1,		$tmp1);
-+	&mov(	$tmp2,		0xff);
-+	
-+	&movb(	&LB($tmp1),	&HB($tmp4));	# A
-+	&and(	$tmp2,		$tmp4);
-+
-+	&shr(	$tmp4,		16); 		#
-+	&xor(	$tmp3,		$tmp3);
-+    } else {
-+	&mov(	$tmp2,		$tmp4);		# B
-+	&movb(	&LB($tmp1),	&HB($tmp4));	# A	# BAD BAD BAD
-+	
-+	&shr(	$tmp4,		16); 		#
-+	&and(	$tmp2,		0xff);
-+    }
-+
-+    &movb(	&LB($tmp3),	&HB($tmp4));	# C	# BAD BAD BAD
-+    &and(	$tmp4,		0xff);		# D
-+
-+    &mov(	$tmp1,		&DWP($S1,"",$tmp1,4));
-+    &mov(	$tmp2,		&DWP($S2,"",$tmp2,4));
-+
-+    &$OP2(	$tmp1,		$tmp2);
-+    &mov(	$tmp2,		&DWP($S3,"",$tmp3,4));
-+
-+    &$OP3(	$tmp1,		$tmp2);
-+    &mov(	$tmp2,		&DWP($S4,"",$tmp4,4));
-+
-+    &$OP1(	$tmp1,		$tmp2);
-+    # XXX
-+
-+    &xor(	$L,		$tmp1);
-+    # XXX
-+}
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/build.info
-new file mode 100644
-index 0000000..f6a25c9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/build.info
-@@ -0,0 +1,6 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        c_skey.c c_ecb.c {- $target{cast_asm_src} -} c_cfb64.c c_ofb64.c
-+
-+GENERATE[cast-586.s]=asm/cast-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[cast-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_cfb64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_cfb64.c
-new file mode 100644
-index 0000000..bd7cb2f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_cfb64.c
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "cast_lcl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit cfb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+
-+void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
-+                        long length, const CAST_KEY *schedule,
-+                        unsigned char *ivec, int *num, int enc)
-+{
-+    register CAST_LONG v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    CAST_LONG ti[2];
-+    unsigned char *iv, c, cc;
-+
-+    iv = ivec;
-+    if (enc) {
-+        while (l--) {
-+            if (n == 0) {
-+                n2l(iv, v0);
-+                ti[0] = v0;
-+                n2l(iv, v1);
-+                ti[1] = v1;
-+                CAST_encrypt((CAST_LONG *)ti, schedule);
-+                iv = ivec;
-+                t = ti[0];
-+                l2n(t, iv);
-+                t = ti[1];
-+                l2n(t, iv);
-+                iv = ivec;
-+            }
-+            c = *(in++) ^ iv[n];
-+            *(out++) = c;
-+            iv[n] = c;
-+            n = (n + 1) & 0x07;
-+        }
-+    } else {
-+        while (l--) {
-+            if (n == 0) {
-+                n2l(iv, v0);
-+                ti[0] = v0;
-+                n2l(iv, v1);
-+                ti[1] = v1;
-+                CAST_encrypt((CAST_LONG *)ti, schedule);
-+                iv = ivec;
-+                t = ti[0];
-+                l2n(t, iv);
-+                t = ti[1];
-+                l2n(t, iv);
-+                iv = ivec;
-+            }
-+            cc = *(in++);
-+            c = iv[n];
-+            iv[n] = cc;
-+            *(out++) = c ^ cc;
-+            n = (n + 1) & 0x07;
-+        }
-+    }
-+    v0 = v1 = ti[0] = ti[1] = t = c = cc = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_ecb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_ecb.c
-new file mode 100644
-index 0000000..da41794
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_ecb.c
-@@ -0,0 +1,32 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "cast_lcl.h"
-+#include 
-+
-+void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
-+                      const CAST_KEY *ks, int enc)
-+{
-+    CAST_LONG l, d[2];
-+
-+    n2l(in, l);
-+    d[0] = l;
-+    n2l(in, l);
-+    d[1] = l;
-+    if (enc)
-+        CAST_encrypt(d, ks);
-+    else
-+        CAST_decrypt(d, ks);
-+    l = d[0];
-+    l2n(l, out);
-+    l = d[1];
-+    l2n(l, out);
-+    l = d[0] = d[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_enc.c
-new file mode 100644
-index 0000000..9a85812
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_enc.c
-@@ -0,0 +1,151 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "cast_lcl.h"
-+
-+void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key)
-+{
-+    register CAST_LONG l, r, t;
-+    const register CAST_LONG *k;
-+
-+    k = &(key->data[0]);
-+    l = data[0];
-+    r = data[1];
-+
-+    E_CAST(0, k, l, r, +, ^, -);
-+    E_CAST(1, k, r, l, ^, -, +);
-+    E_CAST(2, k, l, r, -, +, ^);
-+    E_CAST(3, k, r, l, +, ^, -);
-+    E_CAST(4, k, l, r, ^, -, +);
-+    E_CAST(5, k, r, l, -, +, ^);
-+    E_CAST(6, k, l, r, +, ^, -);
-+    E_CAST(7, k, r, l, ^, -, +);
-+    E_CAST(8, k, l, r, -, +, ^);
-+    E_CAST(9, k, r, l, +, ^, -);
-+    E_CAST(10, k, l, r, ^, -, +);
-+    E_CAST(11, k, r, l, -, +, ^);
-+    if (!key->short_key) {
-+        E_CAST(12, k, l, r, +, ^, -);
-+        E_CAST(13, k, r, l, ^, -, +);
-+        E_CAST(14, k, l, r, -, +, ^);
-+        E_CAST(15, k, r, l, +, ^, -);
-+    }
-+
-+    data[1] = l & 0xffffffffL;
-+    data[0] = r & 0xffffffffL;
-+}
-+
-+void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key)
-+{
-+    register CAST_LONG l, r, t;
-+    const register CAST_LONG *k;
-+
-+    k = &(key->data[0]);
-+    l = data[0];
-+    r = data[1];
-+
-+    if (!key->short_key) {
-+        E_CAST(15, k, l, r, +, ^, -);
-+        E_CAST(14, k, r, l, -, +, ^);
-+        E_CAST(13, k, l, r, ^, -, +);
-+        E_CAST(12, k, r, l, +, ^, -);
-+    }
-+    E_CAST(11, k, l, r, -, +, ^);
-+    E_CAST(10, k, r, l, ^, -, +);
-+    E_CAST(9, k, l, r, +, ^, -);
-+    E_CAST(8, k, r, l, -, +, ^);
-+    E_CAST(7, k, l, r, ^, -, +);
-+    E_CAST(6, k, r, l, +, ^, -);
-+    E_CAST(5, k, l, r, -, +, ^);
-+    E_CAST(4, k, r, l, ^, -, +);
-+    E_CAST(3, k, l, r, +, ^, -);
-+    E_CAST(2, k, r, l, -, +, ^);
-+    E_CAST(1, k, l, r, ^, -, +);
-+    E_CAST(0, k, r, l, +, ^, -);
-+
-+    data[1] = l & 0xffffffffL;
-+    data[0] = r & 0xffffffffL;
-+}
-+
-+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                      long length, const CAST_KEY *ks, unsigned char *iv,
-+                      int enc)
-+{
-+    register CAST_LONG tin0, tin1;
-+    register CAST_LONG tout0, tout1, xor0, xor1;
-+    register long l = length;
-+    CAST_LONG tin[2];
-+
-+    if (enc) {
-+        n2l(iv, tout0);
-+        n2l(iv, tout1);
-+        iv -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            n2l(in, tin0);
-+            n2l(in, tin1);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            CAST_encrypt(tin, ks);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+            l2n(tout0, out);
-+            l2n(tout1, out);
-+        }
-+        if (l != -8) {
-+            n2ln(in, tin0, tin1, l + 8);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            CAST_encrypt(tin, ks);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+            l2n(tout0, out);
-+            l2n(tout1, out);
-+        }
-+        l2n(tout0, iv);
-+        l2n(tout1, iv);
-+    } else {
-+        n2l(iv, xor0);
-+        n2l(iv, xor1);
-+        iv -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            n2l(in, tin0);
-+            n2l(in, tin1);
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            CAST_decrypt(tin, ks);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2n(tout0, out);
-+            l2n(tout1, out);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        if (l != -8) {
-+            n2l(in, tin0);
-+            n2l(in, tin1);
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            CAST_decrypt(tin, ks);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2nn(tout0, tout1, out, l + 8);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        l2n(xor0, iv);
-+        l2n(xor1, iv);
-+    }
-+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
-+    tin[0] = tin[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_ofb64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_ofb64.c
-new file mode 100644
-index 0000000..dffb074
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_ofb64.c
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "cast_lcl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit ofb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
-+                        long length, const CAST_KEY *schedule,
-+                        unsigned char *ivec, int *num)
-+{
-+    register CAST_LONG v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    unsigned char d[8];
-+    register char *dp;
-+    CAST_LONG ti[2];
-+    unsigned char *iv;
-+    int save = 0;
-+
-+    iv = ivec;
-+    n2l(iv, v0);
-+    n2l(iv, v1);
-+    ti[0] = v0;
-+    ti[1] = v1;
-+    dp = (char *)d;
-+    l2n(v0, dp);
-+    l2n(v1, dp);
-+    while (l--) {
-+        if (n == 0) {
-+            CAST_encrypt((CAST_LONG *)ti, schedule);
-+            dp = (char *)d;
-+            t = ti[0];
-+            l2n(t, dp);
-+            t = ti[1];
-+            l2n(t, dp);
-+            save++;
-+        }
-+        *(out++) = *(in++) ^ d[n];
-+        n = (n + 1) & 0x07;
-+    }
-+    if (save) {
-+        v0 = ti[0];
-+        v1 = ti[1];
-+        iv = ivec;
-+        l2n(v0, iv);
-+        l2n(v1, iv);
-+    }
-+    t = v0 = v1 = ti[0] = ti[1] = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_skey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_skey.c
-new file mode 100644
-index 0000000..962d2a6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/c_skey.c
-@@ -0,0 +1,118 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "cast_lcl.h"
-+#include "cast_s.h"
-+
-+#define CAST_exp(l,A,a,n) \
-+        A[n/4]=l; \
-+        a[n+3]=(l    )&0xff; \
-+        a[n+2]=(l>> 8)&0xff; \
-+        a[n+1]=(l>>16)&0xff; \
-+        a[n+0]=(l>>24)&0xff;
-+
-+#define S4 CAST_S_table4
-+#define S5 CAST_S_table5
-+#define S6 CAST_S_table6
-+#define S7 CAST_S_table7
-+
-+void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data)
-+{
-+    CAST_LONG x[16];
-+    CAST_LONG z[16];
-+    CAST_LONG k[32];
-+    CAST_LONG X[4], Z[4];
-+    CAST_LONG l, *K;
-+    int i;
-+
-+    for (i = 0; i < 16; i++)
-+        x[i] = 0;
-+    if (len > 16)
-+        len = 16;
-+    for (i = 0; i < len; i++)
-+        x[i] = data[i];
-+    if (len <= 10)
-+        key->short_key = 1;
-+    else
-+        key->short_key = 0;
-+
-+    K = &k[0];
-+    X[0] = ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3]) & 0xffffffffL;
-+    X[1] = ((x[4] << 24) | (x[5] << 16) | (x[6] << 8) | x[7]) & 0xffffffffL;
-+    X[2] = ((x[8] << 24) | (x[9] << 16) | (x[10] << 8) | x[11]) & 0xffffffffL;
-+    X[3] =
-+        ((x[12] << 24) | (x[13] << 16) | (x[14] << 8) | x[15]) & 0xffffffffL;
-+
-+    for (;;) {
-+        l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]];
-+        CAST_exp(l, Z, z, 0);
-+        l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]];
-+        CAST_exp(l, Z, z, 4);
-+        l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]];
-+        CAST_exp(l, Z, z, 8);
-+        l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]];
-+        CAST_exp(l, Z, z, 12);
-+
-+        K[0] = S4[z[8]] ^ S5[z[9]] ^ S6[z[7]] ^ S7[z[6]] ^ S4[z[2]];
-+        K[1] = S4[z[10]] ^ S5[z[11]] ^ S6[z[5]] ^ S7[z[4]] ^ S5[z[6]];
-+        K[2] = S4[z[12]] ^ S5[z[13]] ^ S6[z[3]] ^ S7[z[2]] ^ S6[z[9]];
-+        K[3] = S4[z[14]] ^ S5[z[15]] ^ S6[z[1]] ^ S7[z[0]] ^ S7[z[12]];
-+
-+        l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]];
-+        CAST_exp(l, X, x, 0);
-+        l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]];
-+        CAST_exp(l, X, x, 4);
-+        l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]];
-+        CAST_exp(l, X, x, 8);
-+        l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]];
-+        CAST_exp(l, X, x, 12);
-+
-+        K[4] = S4[x[3]] ^ S5[x[2]] ^ S6[x[12]] ^ S7[x[13]] ^ S4[x[8]];
-+        K[5] = S4[x[1]] ^ S5[x[0]] ^ S6[x[14]] ^ S7[x[15]] ^ S5[x[13]];
-+        K[6] = S4[x[7]] ^ S5[x[6]] ^ S6[x[8]] ^ S7[x[9]] ^ S6[x[3]];
-+        K[7] = S4[x[5]] ^ S5[x[4]] ^ S6[x[10]] ^ S7[x[11]] ^ S7[x[7]];
-+
-+        l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]];
-+        CAST_exp(l, Z, z, 0);
-+        l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]];
-+        CAST_exp(l, Z, z, 4);
-+        l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]];
-+        CAST_exp(l, Z, z, 8);
-+        l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]];
-+        CAST_exp(l, Z, z, 12);
-+
-+        K[8] = S4[z[3]] ^ S5[z[2]] ^ S6[z[12]] ^ S7[z[13]] ^ S4[z[9]];
-+        K[9] = S4[z[1]] ^ S5[z[0]] ^ S6[z[14]] ^ S7[z[15]] ^ S5[z[12]];
-+        K[10] = S4[z[7]] ^ S5[z[6]] ^ S6[z[8]] ^ S7[z[9]] ^ S6[z[2]];
-+        K[11] = S4[z[5]] ^ S5[z[4]] ^ S6[z[10]] ^ S7[z[11]] ^ S7[z[6]];
-+
-+        l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]];
-+        CAST_exp(l, X, x, 0);
-+        l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]];
-+        CAST_exp(l, X, x, 4);
-+        l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]];
-+        CAST_exp(l, X, x, 8);
-+        l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]];
-+        CAST_exp(l, X, x, 12);
-+
-+        K[12] = S4[x[8]] ^ S5[x[9]] ^ S6[x[7]] ^ S7[x[6]] ^ S4[x[3]];
-+        K[13] = S4[x[10]] ^ S5[x[11]] ^ S6[x[5]] ^ S7[x[4]] ^ S5[x[7]];
-+        K[14] = S4[x[12]] ^ S5[x[13]] ^ S6[x[3]] ^ S7[x[2]] ^ S6[x[8]];
-+        K[15] = S4[x[14]] ^ S5[x[15]] ^ S6[x[1]] ^ S7[x[0]] ^ S7[x[13]];
-+        if (K != k)
-+            break;
-+        K += 16;
-+    }
-+
-+    for (i = 0; i < 16; i++) {
-+        key->data[i * 2] = k[i];
-+        key->data[i * 2 + 1] = ((k[i + 16]) + 16) & 0x1f;
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/cast_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/cast_lcl.h
-new file mode 100644
-index 0000000..504232a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/cast_lcl.h
-@@ -0,0 +1,176 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "e_os.h"
-+
-+#ifdef OPENSSL_SYS_WIN32
-+# include 
-+#endif
-+
-+#undef c2l
-+#define c2l(c,l)        (l =((unsigned long)(*((c)++)))    , \
-+                         l|=((unsigned long)(*((c)++)))<< 8L, \
-+                         l|=((unsigned long)(*((c)++)))<<16L, \
-+                         l|=((unsigned long)(*((c)++)))<<24L)
-+
-+/* NOTE - c is not incremented as per c2l */
-+#undef c2ln
-+#define c2ln(c,l1,l2,n) { \
-+                        c+=n; \
-+                        l1=l2=0; \
-+                        switch (n) { \
-+                        case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
-+                        case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
-+                        case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
-+                        case 5: l2|=((unsigned long)(*(--(c))));     \
-+                        case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
-+                        case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
-+                        case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
-+                        case 1: l1|=((unsigned long)(*(--(c))));     \
-+                                } \
-+                        }
-+
-+#undef l2c
-+#define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
-+
-+/* NOTE - c is not incremented as per l2c */
-+#undef l2cn
-+#define l2cn(l1,l2,c,n) { \
-+                        c+=n; \
-+                        switch (n) { \
-+                        case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
-+                        case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
-+                        case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
-+                        case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
-+                        case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
-+                        case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
-+                        case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
-+                        case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
-+                                } \
-+                        }
-+
-+/* NOTE - c is not incremented as per n2l */
-+#define n2ln(c,l1,l2,n) { \
-+                        c+=n; \
-+                        l1=l2=0; \
-+                        switch (n) { \
-+                        case 8: l2 =((unsigned long)(*(--(c))))    ; \
-+                        case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
-+                        case 6: l2|=((unsigned long)(*(--(c))))<<16; \
-+                        case 5: l2|=((unsigned long)(*(--(c))))<<24; \
-+                        case 4: l1 =((unsigned long)(*(--(c))))    ; \
-+                        case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
-+                        case 2: l1|=((unsigned long)(*(--(c))))<<16; \
-+                        case 1: l1|=((unsigned long)(*(--(c))))<<24; \
-+                                } \
-+                        }
-+
-+/* NOTE - c is not incremented as per l2n */
-+#define l2nn(l1,l2,c,n) { \
-+                        c+=n; \
-+                        switch (n) { \
-+                        case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
-+                        case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
-+                        case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
-+                        case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
-+                        case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
-+                        case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
-+                        case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
-+                        case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
-+                                } \
-+                        }
-+
-+#undef n2l
-+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
-+                         l|=((unsigned long)(*((c)++)))<<16L, \
-+                         l|=((unsigned long)(*((c)++)))<< 8L, \
-+                         l|=((unsigned long)(*((c)++))))
-+
-+#undef l2n
-+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)     )&0xff))
-+
-+#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)
-+# define ROTL(a,n)     (_lrotl(a,n))
-+#else
-+# define ROTL(a,n)     ((((a)<<(n))&0xffffffffL)|((a)>>((32-(n))&31)))
-+#endif
-+
-+#define C_M    0x3fc
-+#define C_0    22L
-+#define C_1    14L
-+#define C_2     6L
-+#define C_3     2L              /* left shift */
-+
-+/* The rotate has an extra 16 added to it to help the x86 asm */
-+#if defined(CAST_PTR)
-+# define E_CAST(n,key,L,R,OP1,OP2,OP3) \
-+        { \
-+        int i; \
-+        t=(key[n*2] OP1 R)&0xffffffffL; \
-+        i=key[n*2+1]; \
-+        t=ROTL(t,i); \
-+        L^= (((((*(CAST_LONG *)((unsigned char *) \
-+                        CAST_S_table0+((t>>C_2)&C_M)) OP2 \
-+                *(CAST_LONG *)((unsigned char *) \
-+                        CAST_S_table1+((t<>C_0)&C_M)))&0xffffffffL) OP1 \
-+                *(CAST_LONG *)((unsigned char *) \
-+                        CAST_S_table3+((t>>C_1)&C_M)))&0xffffffffL; \
-+        }
-+#elif defined(CAST_PTR2)
-+# define E_CAST(n,key,L,R,OP1,OP2,OP3) \
-+        { \
-+        int i; \
-+        CAST_LONG u,v,w; \
-+        w=(key[n*2] OP1 R)&0xffffffffL; \
-+        i=key[n*2+1]; \
-+        w=ROTL(w,i); \
-+        u=w>>C_2; \
-+        v=w<>C_0; \
-+        t=(t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v))&0xffffffffL;\
-+        v=w>>C_1; \
-+        u&=C_M; \
-+        v&=C_M; \
-+        t=(t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u)&0xffffffffL);\
-+        t=(t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v)&0xffffffffL);\
-+        L^=(t&0xffffffff); \
-+        }
-+#else
-+# define E_CAST(n,key,L,R,OP1,OP2,OP3) \
-+        { \
-+        CAST_LONG a,b,c,d; \
-+        t=(key[n*2] OP1 R)&0xffffffff; \
-+        t=ROTL(t,(key[n*2+1])); \
-+        a=CAST_S_table0[(t>> 8)&0xff]; \
-+        b=CAST_S_table1[(t    )&0xff]; \
-+        c=CAST_S_table2[(t>>24)&0xff]; \
-+        d=CAST_S_table3[(t>>16)&0xff]; \
-+        L^=(((((a OP2 b)&0xffffffffL) OP3 c)&0xffffffffL) OP1 d)&0xffffffffL; \
-+        }
-+#endif
-+
-+extern const CAST_LONG CAST_S_table0[256];
-+extern const CAST_LONG CAST_S_table1[256];
-+extern const CAST_LONG CAST_S_table2[256];
-+extern const CAST_LONG CAST_S_table3[256];
-+extern const CAST_LONG CAST_S_table4[256];
-+extern const CAST_LONG CAST_S_table5[256];
-+extern const CAST_LONG CAST_S_table6[256];
-+extern const CAST_LONG CAST_S_table7[256];
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/cast_s.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/cast_s.h
-new file mode 100644
-index 0000000..d9fd6ac
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cast/cast_s.h
-@@ -0,0 +1,544 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+OPENSSL_GLOBAL const CAST_LONG CAST_S_table0[256] = {
-+    0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a,
-+    0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
-+    0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,
-+    0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
-+    0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2,
-+    0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
-+    0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f,
-+    0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
-+    0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de,
-+    0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
-+    0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f,
-+    0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
-+    0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d,
-+    0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
-+    0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,
-+    0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
-+    0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272,
-+    0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
-+    0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d,
-+    0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
-+    0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a,
-+    0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
-+    0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f,
-+    0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
-+    0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9,
-+    0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
-+    0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6,
-+    0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
-+    0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9,
-+    0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
-+    0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e,
-+    0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
-+    0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e,
-+    0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
-+    0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82,
-+    0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
-+    0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac,
-+    0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
-+    0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f,
-+    0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
-+    0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491,
-+    0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
-+    0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de,
-+    0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
-+    0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,
-+    0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
-+    0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79,
-+    0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
-+    0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779,
-+    0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
-+    0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755,
-+    0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
-+    0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb,
-+    0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
-+    0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0,
-+    0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
-+    0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79,
-+    0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
-+    0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298,
-+    0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
-+    0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571,
-+    0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
-+    0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d,
-+    0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf,
-+};
-+
-+OPENSSL_GLOBAL const CAST_LONG CAST_S_table1[256] = {
-+    0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380,
-+    0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
-+    0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba,
-+    0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
-+    0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909,
-+    0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
-+    0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b,
-+    0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
-+    0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4,
-+    0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
-+    0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f,
-+    0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
-+    0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21,
-+    0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
-+    0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d,
-+    0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
-+    0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f,
-+    0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
-+    0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d,
-+    0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
-+    0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4,
-+    0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
-+    0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801,
-+    0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
-+    0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755,
-+    0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
-+    0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709,
-+    0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
-+    0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b,
-+    0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
-+    0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c,
-+    0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
-+    0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9,
-+    0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
-+    0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3,
-+    0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
-+    0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9,
-+    0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
-+    0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab,
-+    0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
-+    0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4,
-+    0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
-+    0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43,
-+    0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
-+    0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8,
-+    0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
-+    0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171,
-+    0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
-+    0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89,
-+    0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
-+    0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b,
-+    0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
-+    0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb,
-+    0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
-+    0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e,
-+    0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
-+    0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea,
-+    0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
-+    0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea,
-+    0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
-+    0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd,
-+    0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
-+    0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef,
-+    0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1,
-+};
-+
-+OPENSSL_GLOBAL const CAST_LONG CAST_S_table2[256] = {
-+    0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907,
-+    0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
-+    0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae,
-+    0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
-+    0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e,
-+    0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
-+    0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc,
-+    0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
-+    0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e,
-+    0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
-+    0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f,
-+    0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
-+    0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99,
-+    0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
-+    0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f,
-+    0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
-+    0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380,
-+    0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
-+    0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8,
-+    0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
-+    0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504,
-+    0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
-+    0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6,
-+    0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
-+    0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e,
-+    0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
-+    0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d,
-+    0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
-+    0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1,
-+    0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
-+    0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c,
-+    0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
-+    0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15,
-+    0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
-+    0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4,
-+    0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
-+    0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b,
-+    0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
-+    0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392,
-+    0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
-+    0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231,
-+    0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
-+    0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889,
-+    0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
-+    0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67,
-+    0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
-+    0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49,
-+    0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
-+    0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d,
-+    0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
-+    0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d,
-+    0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
-+    0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e,
-+    0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
-+    0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767,
-+    0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
-+    0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce,
-+    0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
-+    0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24,
-+    0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
-+    0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0,
-+    0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
-+    0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5,
-+    0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783,
-+};
-+
-+OPENSSL_GLOBAL const CAST_LONG CAST_S_table3[256] = {
-+    0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298,
-+    0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
-+    0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120,
-+    0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
-+    0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220,
-+    0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
-+    0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe,
-+    0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
-+    0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701,
-+    0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
-+    0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b,
-+    0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
-+    0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93,
-+    0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
-+    0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,
-+    0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
-+    0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9,
-+    0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
-+    0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb,
-+    0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
-+    0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c,
-+    0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
-+    0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7,
-+    0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
-+    0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340,
-+    0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
-+    0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327,
-+    0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
-+    0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec,
-+    0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
-+    0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205,
-+    0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
-+    0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031,
-+    0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
-+    0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5,
-+    0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
-+    0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c,
-+    0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
-+    0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69,
-+    0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
-+    0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9,
-+    0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
-+    0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff,
-+    0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
-+    0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3,
-+    0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
-+    0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2,
-+    0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
-+    0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff,
-+    0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
-+    0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091,
-+    0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
-+    0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df,
-+    0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
-+    0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf,
-+    0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
-+    0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367,
-+    0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
-+    0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c,
-+    0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
-+    0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43,
-+    0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
-+    0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e,
-+    0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2,
-+};
-+
-+OPENSSL_GLOBAL const CAST_LONG CAST_S_table4[256] = {
-+    0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911,
-+    0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
-+    0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00,
-+    0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
-+    0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180,
-+    0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
-+    0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2,
-+    0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
-+    0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725,
-+    0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
-+    0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b,
-+    0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
-+    0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571,
-+    0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
-+    0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec,
-+    0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
-+    0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea,
-+    0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
-+    0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263,
-+    0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
-+    0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468,
-+    0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
-+    0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b,
-+    0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
-+    0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284,
-+    0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
-+    0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4,
-+    0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
-+    0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7,
-+    0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
-+    0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce,
-+    0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
-+    0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6,
-+    0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
-+    0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4,
-+    0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
-+    0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561,
-+    0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
-+    0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6,
-+    0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
-+    0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406,
-+    0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
-+    0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472,
-+    0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
-+    0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487,
-+    0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
-+    0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288,
-+    0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
-+    0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2,
-+    0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
-+    0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78,
-+    0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
-+    0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76,
-+    0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
-+    0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0,
-+    0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
-+    0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58,
-+    0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
-+    0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2,
-+    0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
-+    0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be,
-+    0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
-+    0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55,
-+    0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4,
-+};
-+
-+OPENSSL_GLOBAL const CAST_LONG CAST_S_table5[256] = {
-+    0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c,
-+    0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
-+    0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9,
-+    0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
-+    0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e,
-+    0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
-+    0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866,
-+    0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
-+    0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c,
-+    0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
-+    0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd,
-+    0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
-+    0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53,
-+    0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
-+    0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d,
-+    0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
-+    0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf,
-+    0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
-+    0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807,
-+    0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
-+    0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a,
-+    0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
-+    0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563,
-+    0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
-+    0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0,
-+    0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
-+    0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be,
-+    0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
-+    0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0,
-+    0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
-+    0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2,
-+    0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
-+    0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853,
-+    0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
-+    0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa,
-+    0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
-+    0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9,
-+    0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
-+    0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751,
-+    0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
-+    0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358,
-+    0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
-+    0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397,
-+    0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
-+    0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459,
-+    0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
-+    0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4,
-+    0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
-+    0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f,
-+    0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
-+    0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb,
-+    0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
-+    0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2,
-+    0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
-+    0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab,
-+    0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
-+    0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b,
-+    0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
-+    0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b,
-+    0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
-+    0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855,
-+    0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
-+    0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454,
-+    0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f,
-+};
-+
-+OPENSSL_GLOBAL const CAST_LONG CAST_S_table6[256] = {
-+    0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693,
-+    0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
-+    0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82,
-+    0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
-+    0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd,
-+    0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
-+    0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f,
-+    0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
-+    0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9,
-+    0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
-+    0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e,
-+    0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
-+    0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83,
-+    0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
-+    0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e,
-+    0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
-+    0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a,
-+    0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
-+    0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f,
-+    0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
-+    0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b,
-+    0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
-+    0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78,
-+    0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
-+    0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d,
-+    0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
-+    0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802,
-+    0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
-+    0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9,
-+    0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
-+    0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302,
-+    0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
-+    0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858,
-+    0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
-+    0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a,
-+    0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
-+    0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4,
-+    0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
-+    0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df,
-+    0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
-+    0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9,
-+    0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
-+    0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c,
-+    0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
-+    0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07,
-+    0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
-+    0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939,
-+    0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
-+    0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e,
-+    0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
-+    0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378,
-+    0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
-+    0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd,
-+    0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
-+    0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567,
-+    0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
-+    0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2,
-+    0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
-+    0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf,
-+    0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
-+    0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2,
-+    0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
-+    0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada,
-+    0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3,
-+};
-+
-+OPENSSL_GLOBAL const CAST_LONG CAST_S_table7[256] = {
-+    0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095,
-+    0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
-+    0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174,
-+    0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
-+    0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940,
-+    0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
-+    0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42,
-+    0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
-+    0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164,
-+    0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
-+    0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4,
-+    0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
-+    0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0,
-+    0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
-+    0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6,
-+    0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
-+    0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491,
-+    0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
-+    0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b,
-+    0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
-+    0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8,
-+    0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
-+    0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006,
-+    0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
-+    0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564,
-+    0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
-+    0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab,
-+    0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
-+    0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc,
-+    0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
-+    0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8,
-+    0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
-+    0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441,
-+    0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
-+    0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f,
-+    0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
-+    0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504,
-+    0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
-+    0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c,
-+    0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
-+    0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6,
-+    0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
-+    0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd,
-+    0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
-+    0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4,
-+    0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
-+    0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc,
-+    0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
-+    0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba,
-+    0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
-+    0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf,
-+    0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
-+    0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603,
-+    0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
-+    0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37,
-+    0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
-+    0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819,
-+    0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
-+    0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d,
-+    0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
-+    0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347,
-+    0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
-+    0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d,
-+    0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e,
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-armv4.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-armv4.pl
-new file mode 100755
-index 0000000..b5e21e4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-armv4.pl
-@@ -0,0 +1,1158 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# December 2014
-+# 
-+# ChaCha20 for ARMv4.
-+#
-+# Performance in cycles per byte out of large buffer.
-+#
-+#			IALU/gcc-4.4    1xNEON      3xNEON+1xIALU
-+#
-+# Cortex-A5		19.3(*)/+95%    21.8        14.1
-+# Cortex-A8		10.5(*)/+160%   13.9        6.35
-+# Cortex-A9		12.9(**)/+110%  14.3        6.50
-+# Cortex-A15		11.0/+40%       16.0        5.00
-+# Snapdragon S4		11.5/+125%      13.6        4.90
-+#
-+# (*)	most "favourable" result for aligned data on little-endian
-+#	processor, result for misaligned data is 10-15% lower;
-+# (**)	this result is a trade-off: it can be improved by 20%,
-+#	but then Snapdragon S4 and Cortex-A8 results get
-+#	20-25% worse;
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+sub AUTOLOAD()		# thunk [simplified] x86-style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
-+  my $arg = pop;
-+    $arg = "#$arg" if ($arg*1 eq $arg);
-+    $code .= "\t$opcode\t".join(',',@_,$arg)."\n";
-+}
-+
-+my @x=map("r$_",(0..7,"x","x","x","x",12,"x",14,"x"));
-+my @t=map("r$_",(8..11));
-+
-+sub ROUND {
-+my ($a0,$b0,$c0,$d0)=@_;
-+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
-+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
-+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
-+my $odd = $d0&1;
-+my ($xc,$xc_) = (@t[0..1]);
-+my ($xd,$xd_) = $odd ? (@t[2],@x[$d1]) : (@x[$d0],@t[2]);
-+my @ret;
-+
-+	# Consider order in which variables are addressed by their
-+	# index:
-+	#
-+	#       a   b   c   d
-+	#
-+	#       0   4   8  12 < even round
-+	#       1   5   9  13
-+	#       2   6  10  14
-+	#       3   7  11  15
-+	#       0   5  10  15 < odd round
-+	#       1   6  11  12
-+	#       2   7   8  13
-+	#       3   4   9  14
-+	#
-+	# 'a', 'b' are permanently allocated in registers, @x[0..7],
-+	# while 'c's and pair of 'd's are maintained in memory. If
-+	# you observe 'c' column, you'll notice that pair of 'c's is
-+	# invariant between rounds. This means that we have to reload
-+	# them once per round, in the middle. This is why you'll see
-+	# bunch of 'c' stores and loads in the middle, but none in
-+	# the beginning or end. If you observe 'd' column, you'll
-+	# notice that 15 and 13 are reused in next pair of rounds.
-+	# This is why these two are chosen for offloading to memory,
-+	# to make loads count more.
-+							push @ret,(
-+	"&add	(@x[$a0],@x[$a0],@x[$b0])",
-+	"&mov	($xd,$xd,'ror#16')",
-+	 "&add	(@x[$a1],@x[$a1],@x[$b1])",
-+	 "&mov	($xd_,$xd_,'ror#16')",
-+	"&eor	($xd,$xd,@x[$a0],'ror#16')",
-+	 "&eor	($xd_,$xd_,@x[$a1],'ror#16')",
-+
-+	"&add	($xc,$xc,$xd)",
-+	"&mov	(@x[$b0],@x[$b0],'ror#20')",
-+	 "&add	($xc_,$xc_,$xd_)",
-+	 "&mov	(@x[$b1],@x[$b1],'ror#20')",
-+	"&eor	(@x[$b0],@x[$b0],$xc,'ror#20')",
-+	 "&eor	(@x[$b1],@x[$b1],$xc_,'ror#20')",
-+
-+	"&add	(@x[$a0],@x[$a0],@x[$b0])",
-+	"&mov	($xd,$xd,'ror#24')",
-+	 "&add	(@x[$a1],@x[$a1],@x[$b1])",
-+	 "&mov	($xd_,$xd_,'ror#24')",
-+	"&eor	($xd,$xd,@x[$a0],'ror#24')",
-+	 "&eor	($xd_,$xd_,@x[$a1],'ror#24')",
-+
-+	"&add	($xc,$xc,$xd)",
-+	"&mov	(@x[$b0],@x[$b0],'ror#25')"		);
-+							push @ret,(
-+	"&str	($xd,'[sp,#4*(16+$d0)]')",
-+	"&ldr	($xd,'[sp,#4*(16+$d2)]')"		) if ($odd);
-+							push @ret,(
-+	 "&add	($xc_,$xc_,$xd_)",
-+	 "&mov	(@x[$b1],@x[$b1],'ror#25')"		);
-+							push @ret,(
-+	 "&str	($xd_,'[sp,#4*(16+$d1)]')",
-+	 "&ldr	($xd_,'[sp,#4*(16+$d3)]')"		) if (!$odd);
-+							push @ret,(
-+	"&eor	(@x[$b0],@x[$b0],$xc,'ror#25')",
-+	 "&eor	(@x[$b1],@x[$b1],$xc_,'ror#25')"	);
-+
-+	$xd=@x[$d2]					if (!$odd);
-+	$xd_=@x[$d3]					if ($odd);
-+							push @ret,(
-+	"&str	($xc,'[sp,#4*(16+$c0)]')",
-+	"&ldr	($xc,'[sp,#4*(16+$c2)]')",
-+	"&add	(@x[$a2],@x[$a2],@x[$b2])",
-+	"&mov	($xd,$xd,'ror#16')",
-+	 "&str	($xc_,'[sp,#4*(16+$c1)]')",
-+	 "&ldr	($xc_,'[sp,#4*(16+$c3)]')",
-+	 "&add	(@x[$a3],@x[$a3],@x[$b3])",
-+	 "&mov	($xd_,$xd_,'ror#16')",
-+	"&eor	($xd,$xd,@x[$a2],'ror#16')",
-+	 "&eor	($xd_,$xd_,@x[$a3],'ror#16')",
-+
-+	"&add	($xc,$xc,$xd)",
-+	"&mov	(@x[$b2],@x[$b2],'ror#20')",
-+	 "&add	($xc_,$xc_,$xd_)",
-+	 "&mov	(@x[$b3],@x[$b3],'ror#20')",
-+	"&eor	(@x[$b2],@x[$b2],$xc,'ror#20')",
-+	 "&eor	(@x[$b3],@x[$b3],$xc_,'ror#20')",
-+
-+	"&add	(@x[$a2],@x[$a2],@x[$b2])",
-+	"&mov	($xd,$xd,'ror#24')",
-+	 "&add	(@x[$a3],@x[$a3],@x[$b3])",
-+	 "&mov	($xd_,$xd_,'ror#24')",
-+	"&eor	($xd,$xd,@x[$a2],'ror#24')",
-+	 "&eor	($xd_,$xd_,@x[$a3],'ror#24')",
-+
-+	"&add	($xc,$xc,$xd)",
-+	"&mov	(@x[$b2],@x[$b2],'ror#25')",
-+	 "&add	($xc_,$xc_,$xd_)",
-+	 "&mov	(@x[$b3],@x[$b3],'ror#25')",
-+	"&eor	(@x[$b2],@x[$b2],$xc,'ror#25')",
-+	 "&eor	(@x[$b3],@x[$b3],$xc_,'ror#25')"	);
-+
-+	@ret;
-+}
-+
-+$code.=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+#if defined(__thumb2__)
-+.syntax	unified
-+.thumb
-+#else
-+.code	32
-+#endif
-+
-+#if defined(__thumb2__) || defined(__clang__)
-+#define ldrhsb	ldrbhs
-+#endif
-+
-+.align	5
-+.Lsigma:
-+.long	0x61707865,0x3320646e,0x79622d32,0x6b206574	@ endian-neutral
-+.Lone:
-+.long	1,0,0,0
-+#if __ARM_MAX_ARCH__>=7
-+.LOPENSSL_armcap:
-+.word   OPENSSL_armcap_P-.LChaCha20_ctr32
-+#else
-+.word	-1
-+#endif
-+
-+.globl	ChaCha20_ctr32
-+.type	ChaCha20_ctr32,%function
-+.align	5
-+ChaCha20_ctr32:
-+.LChaCha20_ctr32:
-+	ldr	r12,[sp,#0]		@ pull pointer to counter and nonce
-+	stmdb	sp!,{r0-r2,r4-r11,lr}
-+#if __ARM_ARCH__<7 && !defined(__thumb2__)
-+	sub	r14,pc,#16		@ ChaCha20_ctr32
-+#else
-+	adr	r14,.LChaCha20_ctr32
-+#endif
-+	cmp	r2,#0			@ len==0?
-+#ifdef	__thumb2__
-+	itt	eq
-+#endif
-+	addeq	sp,sp,#4*3
-+	beq	.Lno_data
-+#if __ARM_MAX_ARCH__>=7
-+	cmp	r2,#192			@ test len
-+	bls	.Lshort
-+	ldr	r4,[r14,#-32]
-+	ldr	r4,[r14,r4]
-+# ifdef	__APPLE__
-+	ldr	r4,[r4]
-+# endif
-+	tst	r4,#ARMV7_NEON
-+	bne	.LChaCha20_neon
-+.Lshort:
-+#endif
-+	ldmia	r12,{r4-r7}		@ load counter and nonce
-+	sub	sp,sp,#4*(16)		@ off-load area
-+	sub	r14,r14,#64		@ .Lsigma
-+	stmdb	sp!,{r4-r7}		@ copy counter and nonce
-+	ldmia	r3,{r4-r11}		@ load key
-+	ldmia	r14,{r0-r3}		@ load sigma
-+	stmdb	sp!,{r4-r11}		@ copy key
-+	stmdb	sp!,{r0-r3}		@ copy sigma
-+	str	r10,[sp,#4*(16+10)]	@ off-load "@x[10]"
-+	str	r11,[sp,#4*(16+11)]	@ off-load "@x[11]"
-+	b	.Loop_outer_enter
-+
-+.align	4
-+.Loop_outer:
-+	ldmia	sp,{r0-r9}		@ load key material
-+	str	@t[3],[sp,#4*(32+2)]	@ save len
-+	str	r12,  [sp,#4*(32+1)]	@ save inp
-+	str	r14,  [sp,#4*(32+0)]	@ save out
-+.Loop_outer_enter:
-+	ldr	@t[3], [sp,#4*(15)]
-+	ldr	@x[12],[sp,#4*(12)]	@ modulo-scheduled load
-+	ldr	@t[2], [sp,#4*(13)]
-+	ldr	@x[14],[sp,#4*(14)]
-+	str	@t[3], [sp,#4*(16+15)]
-+	mov	@t[3],#10
-+	b	.Loop
-+
-+.align	4
-+.Loop:
-+	subs	@t[3],@t[3],#1
-+___
-+	foreach (&ROUND(0, 4, 8,12)) { eval; }
-+	foreach (&ROUND(0, 5,10,15)) { eval; }
-+$code.=<<___;
-+	bne	.Loop
-+
-+	ldr	@t[3],[sp,#4*(32+2)]	@ load len
-+
-+	str	@t[0], [sp,#4*(16+8)]	@ modulo-scheduled store
-+	str	@t[1], [sp,#4*(16+9)]
-+	str	@x[12],[sp,#4*(16+12)]
-+	str	@t[2], [sp,#4*(16+13)]
-+	str	@x[14],[sp,#4*(16+14)]
-+
-+	@ at this point we have first half of 512-bit result in
-+	@ @x[0-7] and second half at sp+4*(16+8)
-+
-+	cmp	@t[3],#64		@ done yet?
-+#ifdef	__thumb2__
-+	itete	lo
-+#endif
-+	addlo	r12,sp,#4*(0)		@ shortcut or ...
-+	ldrhs	r12,[sp,#4*(32+1)]	@ ... load inp
-+	addlo	r14,sp,#4*(0)		@ shortcut or ...
-+	ldrhs	r14,[sp,#4*(32+0)]	@ ... load out
-+
-+	ldr	@t[0],[sp,#4*(0)]	@ load key material
-+	ldr	@t[1],[sp,#4*(1)]
-+
-+#if __ARM_ARCH__>=6 || !defined(__ARMEB__)
-+# if __ARM_ARCH__<7
-+	orr	@t[2],r12,r14
-+	tst	@t[2],#3		@ are input and output aligned?
-+	ldr	@t[2],[sp,#4*(2)]
-+	bne	.Lunaligned
-+	cmp	@t[3],#64		@ restore flags
-+# else
-+	ldr	@t[2],[sp,#4*(2)]
-+# endif
-+	ldr	@t[3],[sp,#4*(3)]
-+
-+	add	@x[0],@x[0],@t[0]	@ accumulate key material
-+	add	@x[1],@x[1],@t[1]
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhs	@t[0],[r12],#16		@ load input
-+	ldrhs	@t[1],[r12,#-12]
-+
-+	add	@x[2],@x[2],@t[2]
-+	add	@x[3],@x[3],@t[3]
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhs	@t[2],[r12,#-8]
-+	ldrhs	@t[3],[r12,#-4]
-+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
-+	rev	@x[0],@x[0]
-+	rev	@x[1],@x[1]
-+	rev	@x[2],@x[2]
-+	rev	@x[3],@x[3]
-+# endif
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	eorhs	@x[0],@x[0],@t[0]	@ xor with input
-+	eorhs	@x[1],@x[1],@t[1]
-+	 add	@t[0],sp,#4*(4)
-+	str	@x[0],[r14],#16		@ store output
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	eorhs	@x[2],@x[2],@t[2]
-+	eorhs	@x[3],@x[3],@t[3]
-+	 ldmia	@t[0],{@t[0]-@t[3]}	@ load key material
-+	str	@x[1],[r14,#-12]
-+	str	@x[2],[r14,#-8]
-+	str	@x[3],[r14,#-4]
-+
-+	add	@x[4],@x[4],@t[0]	@ accumulate key material
-+	add	@x[5],@x[5],@t[1]
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhs	@t[0],[r12],#16		@ load input
-+	ldrhs	@t[1],[r12,#-12]
-+	add	@x[6],@x[6],@t[2]
-+	add	@x[7],@x[7],@t[3]
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhs	@t[2],[r12,#-8]
-+	ldrhs	@t[3],[r12,#-4]
-+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
-+	rev	@x[4],@x[4]
-+	rev	@x[5],@x[5]
-+	rev	@x[6],@x[6]
-+	rev	@x[7],@x[7]
-+# endif
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	eorhs	@x[4],@x[4],@t[0]
-+	eorhs	@x[5],@x[5],@t[1]
-+	 add	@t[0],sp,#4*(8)
-+	str	@x[4],[r14],#16		@ store output
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	eorhs	@x[6],@x[6],@t[2]
-+	eorhs	@x[7],@x[7],@t[3]
-+	str	@x[5],[r14,#-12]
-+	 ldmia	@t[0],{@t[0]-@t[3]}	@ load key material
-+	str	@x[6],[r14,#-8]
-+	 add	@x[0],sp,#4*(16+8)
-+	str	@x[7],[r14,#-4]
-+
-+	ldmia	@x[0],{@x[0]-@x[7]}	@ load second half
-+
-+	add	@x[0],@x[0],@t[0]	@ accumulate key material
-+	add	@x[1],@x[1],@t[1]
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhs	@t[0],[r12],#16		@ load input
-+	ldrhs	@t[1],[r12,#-12]
-+# ifdef	__thumb2__
-+	itt	hi
-+# endif
-+	 strhi	@t[2],[sp,#4*(16+10)]	@ copy "@x[10]" while at it
-+	 strhi	@t[3],[sp,#4*(16+11)]	@ copy "@x[11]" while at it
-+	add	@x[2],@x[2],@t[2]
-+	add	@x[3],@x[3],@t[3]
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhs	@t[2],[r12,#-8]
-+	ldrhs	@t[3],[r12,#-4]
-+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
-+	rev	@x[0],@x[0]
-+	rev	@x[1],@x[1]
-+	rev	@x[2],@x[2]
-+	rev	@x[3],@x[3]
-+# endif
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	eorhs	@x[0],@x[0],@t[0]
-+	eorhs	@x[1],@x[1],@t[1]
-+	 add	@t[0],sp,#4*(12)
-+	str	@x[0],[r14],#16		@ store output
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	eorhs	@x[2],@x[2],@t[2]
-+	eorhs	@x[3],@x[3],@t[3]
-+	str	@x[1],[r14,#-12]
-+	 ldmia	@t[0],{@t[0]-@t[3]}	@ load key material
-+	str	@x[2],[r14,#-8]
-+	str	@x[3],[r14,#-4]
-+
-+	add	@x[4],@x[4],@t[0]	@ accumulate key material
-+	add	@x[5],@x[5],@t[1]
-+# ifdef	__thumb2__
-+	itt	hi
-+# endif
-+	 addhi	@t[0],@t[0],#1		@ next counter value
-+	 strhi	@t[0],[sp,#4*(12)]	@ save next counter value
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhs	@t[0],[r12],#16		@ load input
-+	ldrhs	@t[1],[r12,#-12]
-+	add	@x[6],@x[6],@t[2]
-+	add	@x[7],@x[7],@t[3]
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhs	@t[2],[r12,#-8]
-+	ldrhs	@t[3],[r12,#-4]
-+# if __ARM_ARCH__>=6 && defined(__ARMEB__)
-+	rev	@x[4],@x[4]
-+	rev	@x[5],@x[5]
-+	rev	@x[6],@x[6]
-+	rev	@x[7],@x[7]
-+# endif
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	eorhs	@x[4],@x[4],@t[0]
-+	eorhs	@x[5],@x[5],@t[1]
-+# ifdef	__thumb2__
-+	 it	ne
-+# endif
-+	 ldrne	@t[0],[sp,#4*(32+2)]	@ re-load len
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	eorhs	@x[6],@x[6],@t[2]
-+	eorhs	@x[7],@x[7],@t[3]
-+	str	@x[4],[r14],#16		@ store output
-+	str	@x[5],[r14,#-12]
-+# ifdef	__thumb2__
-+	it	hs
-+# endif
-+	 subhs	@t[3],@t[0],#64		@ len-=64
-+	str	@x[6],[r14,#-8]
-+	str	@x[7],[r14,#-4]
-+	bhi	.Loop_outer
-+
-+	beq	.Ldone
-+# if __ARM_ARCH__<7
-+	b	.Ltail
-+
-+.align	4
-+.Lunaligned:				@ unaligned endian-neutral path
-+	cmp	@t[3],#64		@ restore flags
-+# endif
-+#endif
-+#if __ARM_ARCH__<7
-+	ldr	@t[3],[sp,#4*(3)]
-+___
-+for ($i=0;$i<16;$i+=4) {
-+my $j=$i&0x7;
-+
-+$code.=<<___	if ($i==4);
-+	add	@x[0],sp,#4*(16+8)
-+___
-+$code.=<<___	if ($i==8);
-+	ldmia	@x[0],{@x[0]-@x[7]}		@ load second half
-+# ifdef	__thumb2__
-+	itt	hi
-+# endif
-+	strhi	@t[2],[sp,#4*(16+10)]		@ copy "@x[10]"
-+	strhi	@t[3],[sp,#4*(16+11)]		@ copy "@x[11]"
-+___
-+$code.=<<___;
-+	add	@x[$j+0],@x[$j+0],@t[0]		@ accumulate key material
-+___
-+$code.=<<___	if ($i==12);
-+# ifdef	__thumb2__
-+	itt	hi
-+# endif
-+	addhi	@t[0],@t[0],#1			@ next counter value
-+	strhi	@t[0],[sp,#4*(12)]		@ save next counter value
-+___
-+$code.=<<___;
-+	add	@x[$j+1],@x[$j+1],@t[1]
-+	add	@x[$j+2],@x[$j+2],@t[2]
-+# ifdef	__thumb2__
-+	itete	lo
-+# endif
-+	eorlo	@t[0],@t[0],@t[0]		@ zero or ...
-+	ldrhsb	@t[0],[r12],#16			@ ... load input
-+	eorlo	@t[1],@t[1],@t[1]
-+	ldrhsb	@t[1],[r12,#-12]
-+
-+	add	@x[$j+3],@x[$j+3],@t[3]
-+# ifdef	__thumb2__
-+	itete	lo
-+# endif
-+	eorlo	@t[2],@t[2],@t[2]
-+	ldrhsb	@t[2],[r12,#-8]
-+	eorlo	@t[3],@t[3],@t[3]
-+	ldrhsb	@t[3],[r12,#-4]
-+
-+	eor	@x[$j+0],@t[0],@x[$j+0]		@ xor with input (or zero)
-+	eor	@x[$j+1],@t[1],@x[$j+1]
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhsb	@t[0],[r12,#-15]		@ load more input
-+	ldrhsb	@t[1],[r12,#-11]
-+	eor	@x[$j+2],@t[2],@x[$j+2]
-+	 strb	@x[$j+0],[r14],#16		@ store output
-+	eor	@x[$j+3],@t[3],@x[$j+3]
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhsb	@t[2],[r12,#-7]
-+	ldrhsb	@t[3],[r12,#-3]
-+	 strb	@x[$j+1],[r14,#-12]
-+	eor	@x[$j+0],@t[0],@x[$j+0],lsr#8
-+	 strb	@x[$j+2],[r14,#-8]
-+	eor	@x[$j+1],@t[1],@x[$j+1],lsr#8
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhsb	@t[0],[r12,#-14]		@ load more input
-+	ldrhsb	@t[1],[r12,#-10]
-+	 strb	@x[$j+3],[r14,#-4]
-+	eor	@x[$j+2],@t[2],@x[$j+2],lsr#8
-+	 strb	@x[$j+0],[r14,#-15]
-+	eor	@x[$j+3],@t[3],@x[$j+3],lsr#8
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhsb	@t[2],[r12,#-6]
-+	ldrhsb	@t[3],[r12,#-2]
-+	 strb	@x[$j+1],[r14,#-11]
-+	eor	@x[$j+0],@t[0],@x[$j+0],lsr#8
-+	 strb	@x[$j+2],[r14,#-7]
-+	eor	@x[$j+1],@t[1],@x[$j+1],lsr#8
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhsb	@t[0],[r12,#-13]		@ load more input
-+	ldrhsb	@t[1],[r12,#-9]
-+	 strb	@x[$j+3],[r14,#-3]
-+	eor	@x[$j+2],@t[2],@x[$j+2],lsr#8
-+	 strb	@x[$j+0],[r14,#-14]
-+	eor	@x[$j+3],@t[3],@x[$j+3],lsr#8
-+# ifdef	__thumb2__
-+	itt	hs
-+# endif
-+	ldrhsb	@t[2],[r12,#-5]
-+	ldrhsb	@t[3],[r12,#-1]
-+	 strb	@x[$j+1],[r14,#-10]
-+	 strb	@x[$j+2],[r14,#-6]
-+	eor	@x[$j+0],@t[0],@x[$j+0],lsr#8
-+	 strb	@x[$j+3],[r14,#-2]
-+	eor	@x[$j+1],@t[1],@x[$j+1],lsr#8
-+	 strb	@x[$j+0],[r14,#-13]
-+	eor	@x[$j+2],@t[2],@x[$j+2],lsr#8
-+	 strb	@x[$j+1],[r14,#-9]
-+	eor	@x[$j+3],@t[3],@x[$j+3],lsr#8
-+	 strb	@x[$j+2],[r14,#-5]
-+	 strb	@x[$j+3],[r14,#-1]
-+___
-+$code.=<<___	if ($i<12);
-+	add	@t[0],sp,#4*(4+$i)
-+	ldmia	@t[0],{@t[0]-@t[3]}		@ load key material
-+___
-+}
-+$code.=<<___;
-+# ifdef	__thumb2__
-+	it	ne
-+# endif
-+	ldrne	@t[0],[sp,#4*(32+2)]		@ re-load len
-+# ifdef	__thumb2__
-+	it	hs
-+# endif
-+	subhs	@t[3],@t[0],#64			@ len-=64
-+	bhi	.Loop_outer
-+
-+	beq	.Ldone
-+#endif
-+
-+.Ltail:
-+	ldr	r12,[sp,#4*(32+1)]	@ load inp
-+	add	@t[1],sp,#4*(0)
-+	ldr	r14,[sp,#4*(32+0)]	@ load out
-+
-+.Loop_tail:
-+	ldrb	@t[2],[@t[1]],#1	@ read buffer on stack
-+	ldrb	@t[3],[r12],#1		@ read input
-+	subs	@t[0],@t[0],#1
-+	eor	@t[3],@t[3],@t[2]
-+	strb	@t[3],[r14],#1		@ store output
-+	bne	.Loop_tail
-+
-+.Ldone:
-+	add	sp,sp,#4*(32+3)
-+.Lno_data:
-+	ldmia	sp!,{r4-r11,pc}
-+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
-+___
-+
-+{{{
-+my ($a0,$b0,$c0,$d0,$a1,$b1,$c1,$d1,$a2,$b2,$c2,$d2,$t0,$t1,$t2,$t3) =
-+    map("q$_",(0..15));
-+
-+sub NEONROUND {
-+my $odd = pop;
-+my ($a,$b,$c,$d,$t)=@_;
-+
-+	(
-+	"&vadd_i32	($a,$a,$b)",
-+	"&veor		($d,$d,$a)",
-+	"&vrev32_16	($d,$d)",	# vrot ($d,16)
-+
-+	"&vadd_i32	($c,$c,$d)",
-+	"&veor		($t,$b,$c)",
-+	"&vshr_u32	($b,$t,20)",
-+	"&vsli_32	($b,$t,12)",
-+
-+	"&vadd_i32	($a,$a,$b)",
-+	"&veor		($t,$d,$a)",
-+	"&vshr_u32	($d,$t,24)",
-+	"&vsli_32	($d,$t,8)",
-+
-+	"&vadd_i32	($c,$c,$d)",
-+	"&veor		($t,$b,$c)",
-+	"&vshr_u32	($b,$t,25)",
-+	"&vsli_32	($b,$t,7)",
-+
-+	"&vext_8	($c,$c,$c,8)",
-+	"&vext_8	($b,$b,$b,$odd?12:4)",
-+	"&vext_8	($d,$d,$d,$odd?4:12)"
-+	);
-+}
-+
-+$code.=<<___;
-+#if __ARM_MAX_ARCH__>=7
-+.arch	armv7-a
-+.fpu	neon
-+
-+.type	ChaCha20_neon,%function
-+.align	5
-+ChaCha20_neon:
-+	ldr		r12,[sp,#0]		@ pull pointer to counter and nonce
-+	stmdb		sp!,{r0-r2,r4-r11,lr}
-+.LChaCha20_neon:
-+	adr		r14,.Lsigma
-+	vstmdb		sp!,{d8-d15}		@ ABI spec says so
-+	stmdb		sp!,{r0-r3}
-+
-+	vld1.32		{$b0-$c0},[r3]		@ load key
-+	ldmia		r3,{r4-r11}		@ load key
-+
-+	sub		sp,sp,#4*(16+16)
-+	vld1.32		{$d0},[r12]		@ load counter and nonce
-+	add		r12,sp,#4*8
-+	ldmia		r14,{r0-r3}		@ load sigma
-+	vld1.32		{$a0},[r14]!		@ load sigma
-+	vld1.32		{$t0},[r14]		@ one
-+	vst1.32		{$c0-$d0},[r12]		@ copy 1/2key|counter|nonce
-+	vst1.32		{$a0-$b0},[sp]		@ copy sigma|1/2key
-+
-+	str		r10,[sp,#4*(16+10)]	@ off-load "@x[10]"
-+	str		r11,[sp,#4*(16+11)]	@ off-load "@x[11]"
-+	vshl.i32	$t1#lo,$t0#lo,#1	@ two
-+	vstr		$t0#lo,[sp,#4*(16+0)]
-+	vshl.i32	$t2#lo,$t0#lo,#2	@ four
-+	vstr		$t1#lo,[sp,#4*(16+2)]
-+	vmov		$a1,$a0
-+	vstr		$t2#lo,[sp,#4*(16+4)]
-+	vmov		$a2,$a0
-+	vmov		$b1,$b0
-+	vmov		$b2,$b0
-+	b		.Loop_neon_enter
-+
-+.align	4
-+.Loop_neon_outer:
-+	ldmia		sp,{r0-r9}		@ load key material
-+	cmp		@t[3],#64*2		@ if len<=64*2
-+	bls		.Lbreak_neon		@ switch to integer-only
-+	vmov		$a1,$a0
-+	str		@t[3],[sp,#4*(32+2)]	@ save len
-+	vmov		$a2,$a0
-+	str		r12,  [sp,#4*(32+1)]	@ save inp
-+	vmov		$b1,$b0
-+	str		r14,  [sp,#4*(32+0)]	@ save out
-+	vmov		$b2,$b0
-+.Loop_neon_enter:
-+	ldr		@t[3], [sp,#4*(15)]
-+	vadd.i32	$d1,$d0,$t0		@ counter+1
-+	ldr		@x[12],[sp,#4*(12)]	@ modulo-scheduled load
-+	vmov		$c1,$c0
-+	ldr		@t[2], [sp,#4*(13)]
-+	vmov		$c2,$c0
-+	ldr		@x[14],[sp,#4*(14)]
-+	vadd.i32	$d2,$d1,$t0		@ counter+2
-+	str		@t[3], [sp,#4*(16+15)]
-+	mov		@t[3],#10
-+	add		@x[12],@x[12],#3	@ counter+3 
-+	b		.Loop_neon
-+
-+.align	4
-+.Loop_neon:
-+	subs		@t[3],@t[3],#1
-+___
-+	my @thread0=&NEONROUND($a0,$b0,$c0,$d0,$t0,0);
-+	my @thread1=&NEONROUND($a1,$b1,$c1,$d1,$t1,0);
-+	my @thread2=&NEONROUND($a2,$b2,$c2,$d2,$t2,0);
-+	my @thread3=&ROUND(0,4,8,12);
-+
-+	foreach (@thread0) {
-+		eval;			eval(shift(@thread3));
-+		eval(shift(@thread1));	eval(shift(@thread3));
-+		eval(shift(@thread2));	eval(shift(@thread3));
-+	}
-+
-+	@thread0=&NEONROUND($a0,$b0,$c0,$d0,$t0,1);
-+	@thread1=&NEONROUND($a1,$b1,$c1,$d1,$t1,1);
-+	@thread2=&NEONROUND($a2,$b2,$c2,$d2,$t2,1);
-+	@thread3=&ROUND(0,5,10,15);
-+
-+	foreach (@thread0) {
-+		eval;			eval(shift(@thread3));
-+		eval(shift(@thread1));	eval(shift(@thread3));
-+		eval(shift(@thread2));	eval(shift(@thread3));
-+	}
-+$code.=<<___;
-+	bne		.Loop_neon
-+
-+	add		@t[3],sp,#32
-+	vld1.32		{$t0-$t1},[sp]		@ load key material
-+	vld1.32		{$t2-$t3},[@t[3]]
-+
-+	ldr		@t[3],[sp,#4*(32+2)]	@ load len
-+
-+	str		@t[0], [sp,#4*(16+8)]	@ modulo-scheduled store
-+	str		@t[1], [sp,#4*(16+9)]
-+	str		@x[12],[sp,#4*(16+12)]
-+	str		@t[2], [sp,#4*(16+13)]
-+	str		@x[14],[sp,#4*(16+14)]
-+
-+	@ at this point we have first half of 512-bit result in
-+	@ @x[0-7] and second half at sp+4*(16+8)
-+
-+	ldr		r12,[sp,#4*(32+1)]	@ load inp
-+	ldr		r14,[sp,#4*(32+0)]	@ load out
-+
-+	vadd.i32	$a0,$a0,$t0		@ accumulate key material
-+	vadd.i32	$a1,$a1,$t0
-+	vadd.i32	$a2,$a2,$t0
-+	vldr		$t0#lo,[sp,#4*(16+0)]	@ one
-+
-+	vadd.i32	$b0,$b0,$t1
-+	vadd.i32	$b1,$b1,$t1
-+	vadd.i32	$b2,$b2,$t1
-+	vldr		$t1#lo,[sp,#4*(16+2)]	@ two
-+
-+	vadd.i32	$c0,$c0,$t2
-+	vadd.i32	$c1,$c1,$t2
-+	vadd.i32	$c2,$c2,$t2
-+	vadd.i32	$d1#lo,$d1#lo,$t0#lo	@ counter+1
-+	vadd.i32	$d2#lo,$d2#lo,$t1#lo	@ counter+2
-+
-+	vadd.i32	$d0,$d0,$t3
-+	vadd.i32	$d1,$d1,$t3
-+	vadd.i32	$d2,$d2,$t3
-+
-+	cmp		@t[3],#64*4
-+	blo		.Ltail_neon
-+
-+	vld1.8		{$t0-$t1},[r12]!	@ load input
-+	 mov		@t[3],sp
-+	vld1.8		{$t2-$t3},[r12]!
-+	veor		$a0,$a0,$t0		@ xor with input
-+	veor		$b0,$b0,$t1
-+	vld1.8		{$t0-$t1},[r12]!
-+	veor		$c0,$c0,$t2
-+	veor		$d0,$d0,$t3
-+	vld1.8		{$t2-$t3},[r12]!
-+
-+	veor		$a1,$a1,$t0
-+	 vst1.8		{$a0-$b0},[r14]!	@ store output
-+	veor		$b1,$b1,$t1
-+	vld1.8		{$t0-$t1},[r12]!
-+	veor		$c1,$c1,$t2
-+	 vst1.8		{$c0-$d0},[r14]!
-+	veor		$d1,$d1,$t3
-+	vld1.8		{$t2-$t3},[r12]!
-+
-+	veor		$a2,$a2,$t0
-+	 vld1.32	{$a0-$b0},[@t[3]]!	@ load for next iteration
-+	 veor		$t0#hi,$t0#hi,$t0#hi
-+	 vldr		$t0#lo,[sp,#4*(16+4)]	@ four
-+	veor		$b2,$b2,$t1
-+	 vld1.32	{$c0-$d0},[@t[3]]
-+	veor		$c2,$c2,$t2
-+	 vst1.8		{$a1-$b1},[r14]!
-+	veor		$d2,$d2,$t3
-+	 vst1.8		{$c1-$d1},[r14]!
-+
-+	vadd.i32	$d0#lo,$d0#lo,$t0#lo	@ next counter value
-+	vldr		$t0#lo,[sp,#4*(16+0)]	@ one
-+
-+	ldmia		sp,{@t[0]-@t[3]}	@ load key material
-+	add		@x[0],@x[0],@t[0]	@ accumulate key material
-+	ldr		@t[0],[r12],#16		@ load input
-+	 vst1.8		{$a2-$b2},[r14]!
-+	add		@x[1],@x[1],@t[1]
-+	ldr		@t[1],[r12,#-12]
-+	 vst1.8		{$c2-$d2},[r14]!
-+	add		@x[2],@x[2],@t[2]
-+	ldr		@t[2],[r12,#-8]
-+	add		@x[3],@x[3],@t[3]
-+	ldr		@t[3],[r12,#-4]
-+# ifdef	__ARMEB__
-+	rev		@x[0],@x[0]
-+	rev		@x[1],@x[1]
-+	rev		@x[2],@x[2]
-+	rev		@x[3],@x[3]
-+# endif
-+	eor		@x[0],@x[0],@t[0]	@ xor with input
-+	 add		@t[0],sp,#4*(4)
-+	eor		@x[1],@x[1],@t[1]
-+	str		@x[0],[r14],#16		@ store output
-+	eor		@x[2],@x[2],@t[2]
-+	str		@x[1],[r14,#-12]
-+	eor		@x[3],@x[3],@t[3]
-+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
-+	str		@x[2],[r14,#-8]
-+	str		@x[3],[r14,#-4]
-+
-+	add		@x[4],@x[4],@t[0]	@ accumulate key material
-+	ldr		@t[0],[r12],#16		@ load input
-+	add		@x[5],@x[5],@t[1]
-+	ldr		@t[1],[r12,#-12]
-+	add		@x[6],@x[6],@t[2]
-+	ldr		@t[2],[r12,#-8]
-+	add		@x[7],@x[7],@t[3]
-+	ldr		@t[3],[r12,#-4]
-+# ifdef	__ARMEB__
-+	rev		@x[4],@x[4]
-+	rev		@x[5],@x[5]
-+	rev		@x[6],@x[6]
-+	rev		@x[7],@x[7]
-+# endif
-+	eor		@x[4],@x[4],@t[0]
-+	 add		@t[0],sp,#4*(8)
-+	eor		@x[5],@x[5],@t[1]
-+	str		@x[4],[r14],#16		@ store output
-+	eor		@x[6],@x[6],@t[2]
-+	str		@x[5],[r14,#-12]
-+	eor		@x[7],@x[7],@t[3]
-+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
-+	str		@x[6],[r14,#-8]
-+	 add		@x[0],sp,#4*(16+8)
-+	str		@x[7],[r14,#-4]
-+
-+	ldmia		@x[0],{@x[0]-@x[7]}	@ load second half
-+
-+	add		@x[0],@x[0],@t[0]	@ accumulate key material
-+	ldr		@t[0],[r12],#16		@ load input
-+	add		@x[1],@x[1],@t[1]
-+	ldr		@t[1],[r12,#-12]
-+# ifdef	__thumb2__
-+	it	hi
-+# endif
-+	 strhi		@t[2],[sp,#4*(16+10)]	@ copy "@x[10]" while at it
-+	add		@x[2],@x[2],@t[2]
-+	ldr		@t[2],[r12,#-8]
-+# ifdef	__thumb2__
-+	it	hi
-+# endif
-+	 strhi		@t[3],[sp,#4*(16+11)]	@ copy "@x[11]" while at it
-+	add		@x[3],@x[3],@t[3]
-+	ldr		@t[3],[r12,#-4]
-+# ifdef	__ARMEB__
-+	rev		@x[0],@x[0]
-+	rev		@x[1],@x[1]
-+	rev		@x[2],@x[2]
-+	rev		@x[3],@x[3]
-+# endif
-+	eor		@x[0],@x[0],@t[0]
-+	 add		@t[0],sp,#4*(12)
-+	eor		@x[1],@x[1],@t[1]
-+	str		@x[0],[r14],#16		@ store output
-+	eor		@x[2],@x[2],@t[2]
-+	str		@x[1],[r14,#-12]
-+	eor		@x[3],@x[3],@t[3]
-+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
-+	str		@x[2],[r14,#-8]
-+	str		@x[3],[r14,#-4]
-+
-+	add		@x[4],@x[4],@t[0]	@ accumulate key material
-+	 add		@t[0],@t[0],#4		@ next counter value
-+	add		@x[5],@x[5],@t[1]
-+	 str		@t[0],[sp,#4*(12)]	@ save next counter value
-+	ldr		@t[0],[r12],#16		@ load input
-+	add		@x[6],@x[6],@t[2]
-+	 add		@x[4],@x[4],#3		@ counter+3
-+	ldr		@t[1],[r12,#-12]
-+	add		@x[7],@x[7],@t[3]
-+	ldr		@t[2],[r12,#-8]
-+	ldr		@t[3],[r12,#-4]
-+# ifdef	__ARMEB__
-+	rev		@x[4],@x[4]
-+	rev		@x[5],@x[5]
-+	rev		@x[6],@x[6]
-+	rev		@x[7],@x[7]
-+# endif
-+	eor		@x[4],@x[4],@t[0]
-+# ifdef	__thumb2__
-+	it	hi
-+# endif
-+	 ldrhi		@t[0],[sp,#4*(32+2)]	@ re-load len
-+	eor		@x[5],@x[5],@t[1]
-+	eor		@x[6],@x[6],@t[2]
-+	str		@x[4],[r14],#16		@ store output
-+	eor		@x[7],@x[7],@t[3]
-+	str		@x[5],[r14,#-12]
-+	 sub		@t[3],@t[0],#64*4	@ len-=64*4
-+	str		@x[6],[r14,#-8]
-+	str		@x[7],[r14,#-4]
-+	bhi		.Loop_neon_outer
-+
-+	b		.Ldone_neon
-+
-+.align	4
-+.Lbreak_neon:
-+	@ harmonize NEON and integer-only stack frames: load data
-+	@ from NEON frame, but save to integer-only one; distance
-+	@ between the two is 4*(32+4+16-32)=4*(20).
-+
-+	str		@t[3], [sp,#4*(20+32+2)]	@ save len
-+	 add		@t[3],sp,#4*(32+4)
-+	str		r12,   [sp,#4*(20+32+1)]	@ save inp
-+	str		r14,   [sp,#4*(20+32+0)]	@ save out
-+
-+	ldr		@x[12],[sp,#4*(16+10)]
-+	ldr		@x[14],[sp,#4*(16+11)]
-+	 vldmia		@t[3],{d8-d15}			@ fulfill ABI requirement
-+	str		@x[12],[sp,#4*(20+16+10)]	@ copy "@x[10]"
-+	str		@x[14],[sp,#4*(20+16+11)]	@ copy "@x[11]"
-+
-+	ldr		@t[3], [sp,#4*(15)]
-+	ldr		@x[12],[sp,#4*(12)]		@ modulo-scheduled load
-+	ldr		@t[2], [sp,#4*(13)]
-+	ldr		@x[14],[sp,#4*(14)]
-+	str		@t[3], [sp,#4*(20+16+15)]
-+	add		@t[3],sp,#4*(20)
-+	vst1.32		{$a0-$b0},[@t[3]]!		@ copy key
-+	add		sp,sp,#4*(20)			@ switch frame
-+	vst1.32		{$c0-$d0},[@t[3]]
-+	mov		@t[3],#10
-+	b		.Loop				@ go integer-only
-+
-+.align	4
-+.Ltail_neon:
-+	cmp		@t[3],#64*3
-+	bhs		.L192_or_more_neon
-+	cmp		@t[3],#64*2
-+	bhs		.L128_or_more_neon
-+	cmp		@t[3],#64*1
-+	bhs		.L64_or_more_neon
-+
-+	add		@t[0],sp,#4*(8)
-+	vst1.8		{$a0-$b0},[sp]
-+	add		@t[2],sp,#4*(0)
-+	vst1.8		{$c0-$d0},[@t[0]]
-+	b		.Loop_tail_neon
-+
-+.align	4
-+.L64_or_more_neon:
-+	vld1.8		{$t0-$t1},[r12]!
-+	vld1.8		{$t2-$t3},[r12]!
-+	veor		$a0,$a0,$t0
-+	veor		$b0,$b0,$t1
-+	veor		$c0,$c0,$t2
-+	veor		$d0,$d0,$t3
-+	vst1.8		{$a0-$b0},[r14]!
-+	vst1.8		{$c0-$d0},[r14]!
-+
-+	beq		.Ldone_neon
-+
-+	add		@t[0],sp,#4*(8)
-+	vst1.8		{$a1-$b1},[sp]
-+	add		@t[2],sp,#4*(0)
-+	vst1.8		{$c1-$d1},[@t[0]]
-+	sub		@t[3],@t[3],#64*1	@ len-=64*1
-+	b		.Loop_tail_neon
-+
-+.align	4
-+.L128_or_more_neon:
-+	vld1.8		{$t0-$t1},[r12]!
-+	vld1.8		{$t2-$t3},[r12]!
-+	veor		$a0,$a0,$t0
-+	veor		$b0,$b0,$t1
-+	vld1.8		{$t0-$t1},[r12]!
-+	veor		$c0,$c0,$t2
-+	veor		$d0,$d0,$t3
-+	vld1.8		{$t2-$t3},[r12]!
-+
-+	veor		$a1,$a1,$t0
-+	veor		$b1,$b1,$t1
-+	 vst1.8		{$a0-$b0},[r14]!
-+	veor		$c1,$c1,$t2
-+	 vst1.8		{$c0-$d0},[r14]!
-+	veor		$d1,$d1,$t3
-+	vst1.8		{$a1-$b1},[r14]!
-+	vst1.8		{$c1-$d1},[r14]!
-+
-+	beq		.Ldone_neon
-+
-+	add		@t[0],sp,#4*(8)
-+	vst1.8		{$a2-$b2},[sp]
-+	add		@t[2],sp,#4*(0)
-+	vst1.8		{$c2-$d2},[@t[0]]
-+	sub		@t[3],@t[3],#64*2	@ len-=64*2
-+	b		.Loop_tail_neon
-+
-+.align	4
-+.L192_or_more_neon:
-+	vld1.8		{$t0-$t1},[r12]!
-+	vld1.8		{$t2-$t3},[r12]!
-+	veor		$a0,$a0,$t0
-+	veor		$b0,$b0,$t1
-+	vld1.8		{$t0-$t1},[r12]!
-+	veor		$c0,$c0,$t2
-+	veor		$d0,$d0,$t3
-+	vld1.8		{$t2-$t3},[r12]!
-+
-+	veor		$a1,$a1,$t0
-+	veor		$b1,$b1,$t1
-+	vld1.8		{$t0-$t1},[r12]!
-+	veor		$c1,$c1,$t2
-+	 vst1.8		{$a0-$b0},[r14]!
-+	veor		$d1,$d1,$t3
-+	vld1.8		{$t2-$t3},[r12]!
-+
-+	veor		$a2,$a2,$t0
-+	 vst1.8		{$c0-$d0},[r14]!
-+	veor		$b2,$b2,$t1
-+	 vst1.8		{$a1-$b1},[r14]!
-+	veor		$c2,$c2,$t2
-+	 vst1.8		{$c1-$d1},[r14]!
-+	veor		$d2,$d2,$t3
-+	vst1.8		{$a2-$b2},[r14]!
-+	vst1.8		{$c2-$d2},[r14]!
-+
-+	beq		.Ldone_neon
-+
-+	ldmia		sp,{@t[0]-@t[3]}	@ load key material
-+	add		@x[0],@x[0],@t[0]	@ accumulate key material
-+	 add		@t[0],sp,#4*(4)
-+	add		@x[1],@x[1],@t[1]
-+	add		@x[2],@x[2],@t[2]
-+	add		@x[3],@x[3],@t[3]
-+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
-+
-+	add		@x[4],@x[4],@t[0]	@ accumulate key material
-+	 add		@t[0],sp,#4*(8)
-+	add		@x[5],@x[5],@t[1]
-+	add		@x[6],@x[6],@t[2]
-+	add		@x[7],@x[7],@t[3]
-+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
-+# ifdef	__ARMEB__
-+	rev		@x[0],@x[0]
-+	rev		@x[1],@x[1]
-+	rev		@x[2],@x[2]
-+	rev		@x[3],@x[3]
-+	rev		@x[4],@x[4]
-+	rev		@x[5],@x[5]
-+	rev		@x[6],@x[6]
-+	rev		@x[7],@x[7]
-+# endif
-+	stmia		sp,{@x[0]-@x[7]}
-+	 add		@x[0],sp,#4*(16+8)
-+
-+	ldmia		@x[0],{@x[0]-@x[7]}	@ load second half
-+
-+	add		@x[0],@x[0],@t[0]	@ accumulate key material
-+	 add		@t[0],sp,#4*(12)
-+	add		@x[1],@x[1],@t[1]
-+	add		@x[2],@x[2],@t[2]
-+	add		@x[3],@x[3],@t[3]
-+	 ldmia		@t[0],{@t[0]-@t[3]}	@ load key material
-+
-+	add		@x[4],@x[4],@t[0]	@ accumulate key material
-+	 add		@t[0],sp,#4*(8)
-+	add		@x[5],@x[5],@t[1]
-+	 add		@x[4],@x[4],#3		@ counter+3
-+	add		@x[6],@x[6],@t[2]
-+	add		@x[7],@x[7],@t[3]
-+	 ldr		@t[3],[sp,#4*(32+2)]	@ re-load len
-+# ifdef	__ARMEB__
-+	rev		@x[0],@x[0]
-+	rev		@x[1],@x[1]
-+	rev		@x[2],@x[2]
-+	rev		@x[3],@x[3]
-+	rev		@x[4],@x[4]
-+	rev		@x[5],@x[5]
-+	rev		@x[6],@x[6]
-+	rev		@x[7],@x[7]
-+# endif
-+	stmia		@t[0],{@x[0]-@x[7]}
-+	 add		@t[2],sp,#4*(0)
-+	 sub		@t[3],@t[3],#64*3	@ len-=64*3
-+
-+.Loop_tail_neon:
-+	ldrb		@t[0],[@t[2]],#1	@ read buffer on stack
-+	ldrb		@t[1],[r12],#1		@ read input
-+	subs		@t[3],@t[3],#1
-+	eor		@t[0],@t[0],@t[1]
-+	strb		@t[0],[r14],#1		@ store output
-+	bne		.Loop_tail_neon
-+
-+.Ldone_neon:
-+	add		sp,sp,#4*(32+4)
-+	vldmia		sp,{d8-d15}
-+	add		sp,sp,#4*(16+3)
-+	ldmia		sp!,{r4-r11,pc}
-+.size	ChaCha20_neon,.-ChaCha20_neon
-+.comm	OPENSSL_armcap_P,4,4
-+#endif
-+___
-+}}}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo;
-+
-+	print $_,"\n";
-+}
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-armv8.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-armv8.pl
-new file mode 100755
-index 0000000..f7e1074
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-armv8.pl
-@@ -0,0 +1,1135 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# June 2015
-+# 
-+# ChaCha20 for ARMv8.
-+#
-+# Performance in cycles per byte out of large buffer.
-+#
-+#			IALU/gcc-4.9    3xNEON+1xIALU	6xNEON+2xIALU
-+#
-+# Apple A7		5.50/+49%       3.33            1.70
-+# Cortex-A53		8.40/+80%       4.72		4.72(*)
-+# Cortex-A57		8.06/+43%       4.90            4.43(**)
-+# Denver		4.50/+82%       2.63		2.67(*)
-+# X-Gene		9.50/+46%       8.82		8.89(*)
-+# Mongoose		8.00/+44%	3.64		3.25
-+#
-+# (*)	it's expected that doubling interleave factor doesn't help
-+#	all processors, only those with higher NEON latency and
-+#	higher instruction issue rate;
-+# (**)	expected improvement was actually higher;
-+
-+$flavour=shift;
-+$output=shift;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+sub AUTOLOAD()		# thunk [simplified] x86-style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
-+  my $arg = pop;
-+    $arg = "#$arg" if ($arg*1 eq $arg);
-+    $code .= "\t$opcode\t".join(',',@_,$arg)."\n";
-+}
-+
-+my ($out,$inp,$len,$key,$ctr) = map("x$_",(0..4));
-+
-+my @x=map("x$_",(5..17,19..21));
-+my @d=map("x$_",(22..28,30));
-+
-+sub ROUND {
-+my ($a0,$b0,$c0,$d0)=@_;
-+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
-+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
-+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
-+
-+    (
-+	"&add_32	(@x[$a0],@x[$a0],@x[$b0])",
-+	 "&add_32	(@x[$a1],@x[$a1],@x[$b1])",
-+	  "&add_32	(@x[$a2],@x[$a2],@x[$b2])",
-+	   "&add_32	(@x[$a3],@x[$a3],@x[$b3])",
-+	"&eor_32	(@x[$d0],@x[$d0],@x[$a0])",
-+	 "&eor_32	(@x[$d1],@x[$d1],@x[$a1])",
-+	  "&eor_32	(@x[$d2],@x[$d2],@x[$a2])",
-+	   "&eor_32	(@x[$d3],@x[$d3],@x[$a3])",
-+	"&ror_32	(@x[$d0],@x[$d0],16)",
-+	 "&ror_32	(@x[$d1],@x[$d1],16)",
-+	  "&ror_32	(@x[$d2],@x[$d2],16)",
-+	   "&ror_32	(@x[$d3],@x[$d3],16)",
-+
-+	"&add_32	(@x[$c0],@x[$c0],@x[$d0])",
-+	 "&add_32	(@x[$c1],@x[$c1],@x[$d1])",
-+	  "&add_32	(@x[$c2],@x[$c2],@x[$d2])",
-+	   "&add_32	(@x[$c3],@x[$c3],@x[$d3])",
-+	"&eor_32	(@x[$b0],@x[$b0],@x[$c0])",
-+	 "&eor_32	(@x[$b1],@x[$b1],@x[$c1])",
-+	  "&eor_32	(@x[$b2],@x[$b2],@x[$c2])",
-+	   "&eor_32	(@x[$b3],@x[$b3],@x[$c3])",
-+	"&ror_32	(@x[$b0],@x[$b0],20)",
-+	 "&ror_32	(@x[$b1],@x[$b1],20)",
-+	  "&ror_32	(@x[$b2],@x[$b2],20)",
-+	   "&ror_32	(@x[$b3],@x[$b3],20)",
-+
-+	"&add_32	(@x[$a0],@x[$a0],@x[$b0])",
-+	 "&add_32	(@x[$a1],@x[$a1],@x[$b1])",
-+	  "&add_32	(@x[$a2],@x[$a2],@x[$b2])",
-+	   "&add_32	(@x[$a3],@x[$a3],@x[$b3])",
-+	"&eor_32	(@x[$d0],@x[$d0],@x[$a0])",
-+	 "&eor_32	(@x[$d1],@x[$d1],@x[$a1])",
-+	  "&eor_32	(@x[$d2],@x[$d2],@x[$a2])",
-+	   "&eor_32	(@x[$d3],@x[$d3],@x[$a3])",
-+	"&ror_32	(@x[$d0],@x[$d0],24)",
-+	 "&ror_32	(@x[$d1],@x[$d1],24)",
-+	  "&ror_32	(@x[$d2],@x[$d2],24)",
-+	   "&ror_32	(@x[$d3],@x[$d3],24)",
-+
-+	"&add_32	(@x[$c0],@x[$c0],@x[$d0])",
-+	 "&add_32	(@x[$c1],@x[$c1],@x[$d1])",
-+	  "&add_32	(@x[$c2],@x[$c2],@x[$d2])",
-+	   "&add_32	(@x[$c3],@x[$c3],@x[$d3])",
-+	"&eor_32	(@x[$b0],@x[$b0],@x[$c0])",
-+	 "&eor_32	(@x[$b1],@x[$b1],@x[$c1])",
-+	  "&eor_32	(@x[$b2],@x[$b2],@x[$c2])",
-+	   "&eor_32	(@x[$b3],@x[$b3],@x[$c3])",
-+	"&ror_32	(@x[$b0],@x[$b0],25)",
-+	 "&ror_32	(@x[$b1],@x[$b1],25)",
-+	  "&ror_32	(@x[$b2],@x[$b2],25)",
-+	   "&ror_32	(@x[$b3],@x[$b3],25)"
-+    );
-+}
-+
-+$code.=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+
-+.extern	OPENSSL_armcap_P
-+
-+.align	5
-+.Lsigma:
-+.quad	0x3320646e61707865,0x6b20657479622d32		// endian-neutral
-+.Lone:
-+.long	1,0,0,0
-+.LOPENSSL_armcap_P:
-+#ifdef	__ILP32__
-+.long	OPENSSL_armcap_P-.
-+#else
-+.quad	OPENSSL_armcap_P-.
-+#endif
-+.asciz	"ChaCha20 for ARMv8, CRYPTOGAMS by "
-+
-+.globl	ChaCha20_ctr32
-+.type	ChaCha20_ctr32,%function
-+.align	5
-+ChaCha20_ctr32:
-+	cbz	$len,.Labort
-+	adr	@x[0],.LOPENSSL_armcap_P
-+	cmp	$len,#192
-+	b.lo	.Lshort
-+#ifdef	__ILP32__
-+	ldrsw	@x[1],[@x[0]]
-+#else
-+	ldr	@x[1],[@x[0]]
-+#endif
-+	ldr	w17,[@x[1],@x[0]]
-+	tst	w17,#ARMV7_NEON
-+	b.ne	ChaCha20_neon
-+
-+.Lshort:
-+	stp	x29,x30,[sp,#-96]!
-+	add	x29,sp,#0
-+
-+	adr	@x[0],.Lsigma
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	stp	x23,x24,[sp,#48]
-+	stp	x25,x26,[sp,#64]
-+	stp	x27,x28,[sp,#80]
-+	sub	sp,sp,#64
-+
-+	ldp	@d[0],@d[1],[@x[0]]		// load sigma
-+	ldp	@d[2],@d[3],[$key]		// load key
-+	ldp	@d[4],@d[5],[$key,#16]
-+	ldp	@d[6],@d[7],[$ctr]		// load counter
-+#ifdef	__ARMEB__
-+	ror	@d[2],@d[2],#32
-+	ror	@d[3],@d[3],#32
-+	ror	@d[4],@d[4],#32
-+	ror	@d[5],@d[5],#32
-+	ror	@d[6],@d[6],#32
-+	ror	@d[7],@d[7],#32
-+#endif
-+
-+.Loop_outer:
-+	mov.32	@x[0],@d[0]			// unpack key block
-+	lsr	@x[1],@d[0],#32
-+	mov.32	@x[2],@d[1]
-+	lsr	@x[3],@d[1],#32
-+	mov.32	@x[4],@d[2]
-+	lsr	@x[5],@d[2],#32
-+	mov.32	@x[6],@d[3]
-+	lsr	@x[7],@d[3],#32
-+	mov.32	@x[8],@d[4]
-+	lsr	@x[9],@d[4],#32
-+	mov.32	@x[10],@d[5]
-+	lsr	@x[11],@d[5],#32
-+	mov.32	@x[12],@d[6]
-+	lsr	@x[13],@d[6],#32
-+	mov.32	@x[14],@d[7]
-+	lsr	@x[15],@d[7],#32
-+
-+	mov	$ctr,#10
-+	subs	$len,$len,#64
-+.Loop:
-+	sub	$ctr,$ctr,#1	
-+___
-+	foreach (&ROUND(0, 4, 8,12)) { eval; }
-+	foreach (&ROUND(0, 5,10,15)) { eval; }
-+$code.=<<___;
-+	cbnz	$ctr,.Loop
-+
-+	add.32	@x[0],@x[0],@d[0]		// accumulate key block
-+	add	@x[1],@x[1],@d[0],lsr#32
-+	add.32	@x[2],@x[2],@d[1]
-+	add	@x[3],@x[3],@d[1],lsr#32
-+	add.32	@x[4],@x[4],@d[2]
-+	add	@x[5],@x[5],@d[2],lsr#32
-+	add.32	@x[6],@x[6],@d[3]
-+	add	@x[7],@x[7],@d[3],lsr#32
-+	add.32	@x[8],@x[8],@d[4]
-+	add	@x[9],@x[9],@d[4],lsr#32
-+	add.32	@x[10],@x[10],@d[5]
-+	add	@x[11],@x[11],@d[5],lsr#32
-+	add.32	@x[12],@x[12],@d[6]
-+	add	@x[13],@x[13],@d[6],lsr#32
-+	add.32	@x[14],@x[14],@d[7]
-+	add	@x[15],@x[15],@d[7],lsr#32
-+
-+	b.lo	.Ltail
-+
-+	add	@x[0],@x[0],@x[1],lsl#32	// pack
-+	add	@x[2],@x[2],@x[3],lsl#32
-+	ldp	@x[1],@x[3],[$inp,#0]		// load input
-+	add	@x[4],@x[4],@x[5],lsl#32
-+	add	@x[6],@x[6],@x[7],lsl#32
-+	ldp	@x[5],@x[7],[$inp,#16]
-+	add	@x[8],@x[8],@x[9],lsl#32
-+	add	@x[10],@x[10],@x[11],lsl#32
-+	ldp	@x[9],@x[11],[$inp,#32]
-+	add	@x[12],@x[12],@x[13],lsl#32
-+	add	@x[14],@x[14],@x[15],lsl#32
-+	ldp	@x[13],@x[15],[$inp,#48]
-+	add	$inp,$inp,#64
-+#ifdef	__ARMEB__
-+	rev	@x[0],@x[0]
-+	rev	@x[2],@x[2]
-+	rev	@x[4],@x[4]
-+	rev	@x[6],@x[6]
-+	rev	@x[8],@x[8]
-+	rev	@x[10],@x[10]
-+	rev	@x[12],@x[12]
-+	rev	@x[14],@x[14]
-+#endif
-+	eor	@x[0],@x[0],@x[1]
-+	eor	@x[2],@x[2],@x[3]
-+	eor	@x[4],@x[4],@x[5]
-+	eor	@x[6],@x[6],@x[7]
-+	eor	@x[8],@x[8],@x[9]
-+	eor	@x[10],@x[10],@x[11]
-+	eor	@x[12],@x[12],@x[13]
-+	eor	@x[14],@x[14],@x[15]
-+
-+	stp	@x[0],@x[2],[$out,#0]		// store output
-+	 add	@d[6],@d[6],#1			// increment counter
-+	stp	@x[4],@x[6],[$out,#16]
-+	stp	@x[8],@x[10],[$out,#32]
-+	stp	@x[12],@x[14],[$out,#48]
-+	add	$out,$out,#64
-+
-+	b.hi	.Loop_outer
-+
-+	ldp	x19,x20,[x29,#16]
-+	add	sp,sp,#64
-+	ldp	x21,x22,[x29,#32]
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	ldp	x27,x28,[x29,#80]
-+	ldp	x29,x30,[sp],#96
-+.Labort:
-+	ret
-+
-+.align	4
-+.Ltail:
-+	add	$len,$len,#64
-+.Less_than_64:
-+	sub	$out,$out,#1
-+	add	$inp,$inp,$len
-+	add	$out,$out,$len
-+	add	$ctr,sp,$len
-+	neg	$len,$len
-+
-+	add	@x[0],@x[0],@x[1],lsl#32	// pack
-+	add	@x[2],@x[2],@x[3],lsl#32
-+	add	@x[4],@x[4],@x[5],lsl#32
-+	add	@x[6],@x[6],@x[7],lsl#32
-+	add	@x[8],@x[8],@x[9],lsl#32
-+	add	@x[10],@x[10],@x[11],lsl#32
-+	add	@x[12],@x[12],@x[13],lsl#32
-+	add	@x[14],@x[14],@x[15],lsl#32
-+#ifdef	__ARMEB__
-+	rev	@x[0],@x[0]
-+	rev	@x[2],@x[2]
-+	rev	@x[4],@x[4]
-+	rev	@x[6],@x[6]
-+	rev	@x[8],@x[8]
-+	rev	@x[10],@x[10]
-+	rev	@x[12],@x[12]
-+	rev	@x[14],@x[14]
-+#endif
-+	stp	@x[0],@x[2],[sp,#0]
-+	stp	@x[4],@x[6],[sp,#16]
-+	stp	@x[8],@x[10],[sp,#32]
-+	stp	@x[12],@x[14],[sp,#48]
-+
-+.Loop_tail:
-+	ldrb	w10,[$inp,$len]
-+	ldrb	w11,[$ctr,$len]
-+	add	$len,$len,#1
-+	eor	w10,w10,w11
-+	strb	w10,[$out,$len]
-+	cbnz	$len,.Loop_tail
-+
-+	stp	xzr,xzr,[sp,#0]
-+	stp	xzr,xzr,[sp,#16]
-+	stp	xzr,xzr,[sp,#32]
-+	stp	xzr,xzr,[sp,#48]
-+
-+	ldp	x19,x20,[x29,#16]
-+	add	sp,sp,#64
-+	ldp	x21,x22,[x29,#32]
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	ldp	x27,x28,[x29,#80]
-+	ldp	x29,x30,[sp],#96
-+	ret
-+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
-+___
-+
-+{{{
-+my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2,$T0,$T1,$T2,$T3) =
-+    map("v$_.4s",(0..7,16..23));
-+my (@K)=map("v$_.4s",(24..30));
-+my $ONE="v31.4s";
-+
-+sub NEONROUND {
-+my $odd = pop;
-+my ($a,$b,$c,$d,$t)=@_;
-+
-+	(
-+	"&add		('$a','$a','$b')",
-+	"&eor		('$d','$d','$a')",
-+	"&rev32_16	('$d','$d')",		# vrot ($d,16)
-+
-+	"&add		('$c','$c','$d')",
-+	"&eor		('$t','$b','$c')",
-+	"&ushr		('$b','$t',20)",
-+	"&sli		('$b','$t',12)",
-+
-+	"&add		('$a','$a','$b')",
-+	"&eor		('$t','$d','$a')",
-+	"&ushr		('$d','$t',24)",
-+	"&sli		('$d','$t',8)",
-+
-+	"&add		('$c','$c','$d')",
-+	"&eor		('$t','$b','$c')",
-+	"&ushr		('$b','$t',25)",
-+	"&sli		('$b','$t',7)",
-+
-+	"&ext		('$c','$c','$c',8)",
-+	"&ext		('$d','$d','$d',$odd?4:12)",
-+	"&ext		('$b','$b','$b',$odd?12:4)"
-+	);
-+}
-+
-+$code.=<<___;
-+
-+.type	ChaCha20_neon,%function
-+.align	5
-+ChaCha20_neon:
-+	stp	x29,x30,[sp,#-96]!
-+	add	x29,sp,#0
-+
-+	adr	@x[0],.Lsigma
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	stp	x23,x24,[sp,#48]
-+	stp	x25,x26,[sp,#64]
-+	stp	x27,x28,[sp,#80]
-+	cmp	$len,#512
-+	b.hs	.L512_or_more_neon
-+
-+	sub	sp,sp,#64
-+
-+	ldp	@d[0],@d[1],[@x[0]]		// load sigma
-+	ld1	{@K[0]},[@x[0]],#16
-+	ldp	@d[2],@d[3],[$key]		// load key
-+	ldp	@d[4],@d[5],[$key,#16]
-+	ld1	{@K[1],@K[2]},[$key]
-+	ldp	@d[6],@d[7],[$ctr]		// load counter
-+	ld1	{@K[3]},[$ctr]
-+	ld1	{$ONE},[@x[0]]
-+#ifdef	__ARMEB__
-+	rev64	@K[0],@K[0]
-+	ror	@d[2],@d[2],#32
-+	ror	@d[3],@d[3],#32
-+	ror	@d[4],@d[4],#32
-+	ror	@d[5],@d[5],#32
-+	ror	@d[6],@d[6],#32
-+	ror	@d[7],@d[7],#32
-+#endif
-+	add	@K[3],@K[3],$ONE		// += 1
-+	add	@K[4],@K[3],$ONE
-+	add	@K[5],@K[4],$ONE
-+	shl	$ONE,$ONE,#2			// 1 -> 4
-+
-+.Loop_outer_neon:
-+	mov.32	@x[0],@d[0]			// unpack key block
-+	lsr	@x[1],@d[0],#32
-+	 mov	$A0,@K[0]
-+	mov.32	@x[2],@d[1]
-+	lsr	@x[3],@d[1],#32
-+	 mov	$A1,@K[0]
-+	mov.32	@x[4],@d[2]
-+	lsr	@x[5],@d[2],#32
-+	 mov	$A2,@K[0]
-+	mov.32	@x[6],@d[3]
-+	 mov	$B0,@K[1]
-+	lsr	@x[7],@d[3],#32
-+	 mov	$B1,@K[1]
-+	mov.32	@x[8],@d[4]
-+	 mov	$B2,@K[1]
-+	lsr	@x[9],@d[4],#32
-+	 mov	$D0,@K[3]
-+	mov.32	@x[10],@d[5]
-+	 mov	$D1,@K[4]
-+	lsr	@x[11],@d[5],#32
-+	 mov	$D2,@K[5]
-+	mov.32	@x[12],@d[6]
-+	 mov	$C0,@K[2]
-+	lsr	@x[13],@d[6],#32
-+	 mov	$C1,@K[2]
-+	mov.32	@x[14],@d[7]
-+	 mov	$C2,@K[2]
-+	lsr	@x[15],@d[7],#32
-+
-+	mov	$ctr,#10
-+	subs	$len,$len,#256
-+.Loop_neon:
-+	sub	$ctr,$ctr,#1
-+___
-+	my @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0);
-+	my @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0);
-+	my @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0);
-+	my @thread3=&ROUND(0,4,8,12);
-+
-+	foreach (@thread0) {
-+		eval;			eval(shift(@thread3));
-+		eval(shift(@thread1));	eval(shift(@thread3));
-+		eval(shift(@thread2));	eval(shift(@thread3));
-+	}
-+
-+	@thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1);
-+	@thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1);
-+	@thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1);
-+	@thread3=&ROUND(0,5,10,15);
-+
-+	foreach (@thread0) {
-+		eval;			eval(shift(@thread3));
-+		eval(shift(@thread1));	eval(shift(@thread3));
-+		eval(shift(@thread2));	eval(shift(@thread3));
-+	}
-+$code.=<<___;
-+	cbnz	$ctr,.Loop_neon
-+
-+	add.32	@x[0],@x[0],@d[0]		// accumulate key block
-+	 add	$A0,$A0,@K[0]
-+	add	@x[1],@x[1],@d[0],lsr#32
-+	 add	$A1,$A1,@K[0]
-+	add.32	@x[2],@x[2],@d[1]
-+	 add	$A2,$A2,@K[0]
-+	add	@x[3],@x[3],@d[1],lsr#32
-+	 add	$C0,$C0,@K[2]
-+	add.32	@x[4],@x[4],@d[2]
-+	 add	$C1,$C1,@K[2]
-+	add	@x[5],@x[5],@d[2],lsr#32
-+	 add	$C2,$C2,@K[2]
-+	add.32	@x[6],@x[6],@d[3]
-+	 add	$D0,$D0,@K[3]
-+	add	@x[7],@x[7],@d[3],lsr#32
-+	add.32	@x[8],@x[8],@d[4]
-+	 add	$D1,$D1,@K[4]
-+	add	@x[9],@x[9],@d[4],lsr#32
-+	add.32	@x[10],@x[10],@d[5]
-+	 add	$D2,$D2,@K[5]
-+	add	@x[11],@x[11],@d[5],lsr#32
-+	add.32	@x[12],@x[12],@d[6]
-+	 add	$B0,$B0,@K[1]
-+	add	@x[13],@x[13],@d[6],lsr#32
-+	add.32	@x[14],@x[14],@d[7]
-+	 add	$B1,$B1,@K[1]
-+	add	@x[15],@x[15],@d[7],lsr#32
-+	 add	$B2,$B2,@K[1]
-+
-+	b.lo	.Ltail_neon
-+
-+	add	@x[0],@x[0],@x[1],lsl#32	// pack
-+	add	@x[2],@x[2],@x[3],lsl#32
-+	ldp	@x[1],@x[3],[$inp,#0]		// load input
-+	add	@x[4],@x[4],@x[5],lsl#32
-+	add	@x[6],@x[6],@x[7],lsl#32
-+	ldp	@x[5],@x[7],[$inp,#16]
-+	add	@x[8],@x[8],@x[9],lsl#32
-+	add	@x[10],@x[10],@x[11],lsl#32
-+	ldp	@x[9],@x[11],[$inp,#32]
-+	add	@x[12],@x[12],@x[13],lsl#32
-+	add	@x[14],@x[14],@x[15],lsl#32
-+	ldp	@x[13],@x[15],[$inp,#48]
-+	add	$inp,$inp,#64
-+#ifdef	__ARMEB__
-+	rev	@x[0],@x[0]
-+	rev	@x[2],@x[2]
-+	rev	@x[4],@x[4]
-+	rev	@x[6],@x[6]
-+	rev	@x[8],@x[8]
-+	rev	@x[10],@x[10]
-+	rev	@x[12],@x[12]
-+	rev	@x[14],@x[14]
-+#endif
-+	ld1.8	{$T0-$T3},[$inp],#64
-+	eor	@x[0],@x[0],@x[1]
-+	eor	@x[2],@x[2],@x[3]
-+	eor	@x[4],@x[4],@x[5]
-+	eor	@x[6],@x[6],@x[7]
-+	eor	@x[8],@x[8],@x[9]
-+	 eor	$A0,$A0,$T0
-+	eor	@x[10],@x[10],@x[11]
-+	 eor	$B0,$B0,$T1
-+	eor	@x[12],@x[12],@x[13]
-+	 eor	$C0,$C0,$T2
-+	eor	@x[14],@x[14],@x[15]
-+	 eor	$D0,$D0,$T3
-+	 ld1.8	{$T0-$T3},[$inp],#64
-+
-+	stp	@x[0],@x[2],[$out,#0]		// store output
-+	 add	@d[6],@d[6],#4			// increment counter
-+	stp	@x[4],@x[6],[$out,#16]
-+	 add	@K[3],@K[3],$ONE		// += 4
-+	stp	@x[8],@x[10],[$out,#32]
-+	 add	@K[4],@K[4],$ONE
-+	stp	@x[12],@x[14],[$out,#48]
-+	 add	@K[5],@K[5],$ONE
-+	add	$out,$out,#64
-+
-+	st1.8	{$A0-$D0},[$out],#64
-+	ld1.8	{$A0-$D0},[$inp],#64
-+
-+	eor	$A1,$A1,$T0
-+	eor	$B1,$B1,$T1
-+	eor	$C1,$C1,$T2
-+	eor	$D1,$D1,$T3
-+	st1.8	{$A1-$D1},[$out],#64
-+
-+	eor	$A2,$A2,$A0
-+	eor	$B2,$B2,$B0
-+	eor	$C2,$C2,$C0
-+	eor	$D2,$D2,$D0
-+	st1.8	{$A2-$D2},[$out],#64
-+
-+	b.hi	.Loop_outer_neon
-+
-+	ldp	x19,x20,[x29,#16]
-+	add	sp,sp,#64
-+	ldp	x21,x22,[x29,#32]
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	ldp	x27,x28,[x29,#80]
-+	ldp	x29,x30,[sp],#96
-+	ret
-+
-+.Ltail_neon:
-+	add	$len,$len,#256
-+	cmp	$len,#64
-+	b.lo	.Less_than_64
-+
-+	add	@x[0],@x[0],@x[1],lsl#32	// pack
-+	add	@x[2],@x[2],@x[3],lsl#32
-+	ldp	@x[1],@x[3],[$inp,#0]		// load input
-+	add	@x[4],@x[4],@x[5],lsl#32
-+	add	@x[6],@x[6],@x[7],lsl#32
-+	ldp	@x[5],@x[7],[$inp,#16]
-+	add	@x[8],@x[8],@x[9],lsl#32
-+	add	@x[10],@x[10],@x[11],lsl#32
-+	ldp	@x[9],@x[11],[$inp,#32]
-+	add	@x[12],@x[12],@x[13],lsl#32
-+	add	@x[14],@x[14],@x[15],lsl#32
-+	ldp	@x[13],@x[15],[$inp,#48]
-+	add	$inp,$inp,#64
-+#ifdef	__ARMEB__
-+	rev	@x[0],@x[0]
-+	rev	@x[2],@x[2]
-+	rev	@x[4],@x[4]
-+	rev	@x[6],@x[6]
-+	rev	@x[8],@x[8]
-+	rev	@x[10],@x[10]
-+	rev	@x[12],@x[12]
-+	rev	@x[14],@x[14]
-+#endif
-+	eor	@x[0],@x[0],@x[1]
-+	eor	@x[2],@x[2],@x[3]
-+	eor	@x[4],@x[4],@x[5]
-+	eor	@x[6],@x[6],@x[7]
-+	eor	@x[8],@x[8],@x[9]
-+	eor	@x[10],@x[10],@x[11]
-+	eor	@x[12],@x[12],@x[13]
-+	eor	@x[14],@x[14],@x[15]
-+
-+	stp	@x[0],@x[2],[$out,#0]		// store output
-+	 add	@d[6],@d[6],#4			// increment counter
-+	stp	@x[4],@x[6],[$out,#16]
-+	stp	@x[8],@x[10],[$out,#32]
-+	stp	@x[12],@x[14],[$out,#48]
-+	add	$out,$out,#64
-+	b.eq	.Ldone_neon
-+	sub	$len,$len,#64
-+	cmp	$len,#64
-+	b.lo	.Less_than_128
-+
-+	ld1.8	{$T0-$T3},[$inp],#64
-+	eor	$A0,$A0,$T0
-+	eor	$B0,$B0,$T1
-+	eor	$C0,$C0,$T2
-+	eor	$D0,$D0,$T3
-+	st1.8	{$A0-$D0},[$out],#64
-+	b.eq	.Ldone_neon
-+	sub	$len,$len,#64
-+	cmp	$len,#64
-+	b.lo	.Less_than_192
-+
-+	ld1.8	{$T0-$T3},[$inp],#64
-+	eor	$A1,$A1,$T0
-+	eor	$B1,$B1,$T1
-+	eor	$C1,$C1,$T2
-+	eor	$D1,$D1,$T3
-+	st1.8	{$A1-$D1},[$out],#64
-+	b.eq	.Ldone_neon
-+	sub	$len,$len,#64
-+
-+	st1.8	{$A2-$D2},[sp]
-+	b	.Last_neon
-+
-+.Less_than_128:
-+	st1.8	{$A0-$D0},[sp]
-+	b	.Last_neon
-+.Less_than_192:
-+	st1.8	{$A1-$D1},[sp]
-+	b	.Last_neon
-+
-+.align	4
-+.Last_neon:
-+	sub	$out,$out,#1
-+	add	$inp,$inp,$len
-+	add	$out,$out,$len
-+	add	$ctr,sp,$len
-+	neg	$len,$len
-+
-+.Loop_tail_neon:
-+	ldrb	w10,[$inp,$len]
-+	ldrb	w11,[$ctr,$len]
-+	add	$len,$len,#1
-+	eor	w10,w10,w11
-+	strb	w10,[$out,$len]
-+	cbnz	$len,.Loop_tail_neon
-+
-+	stp	xzr,xzr,[sp,#0]
-+	stp	xzr,xzr,[sp,#16]
-+	stp	xzr,xzr,[sp,#32]
-+	stp	xzr,xzr,[sp,#48]
-+
-+.Ldone_neon:
-+	ldp	x19,x20,[x29,#16]
-+	add	sp,sp,#64
-+	ldp	x21,x22,[x29,#32]
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	ldp	x27,x28,[x29,#80]
-+	ldp	x29,x30,[sp],#96
-+	ret
-+.size	ChaCha20_neon,.-ChaCha20_neon
-+___
-+{
-+my ($T0,$T1,$T2,$T3,$T4,$T5)=@K;
-+my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2,
-+    $A3,$B3,$C3,$D3,$A4,$B4,$C4,$D4,$A5,$B5,$C5,$D5) = map("v$_.4s",(0..23));
-+
-+$code.=<<___;
-+.type	ChaCha20_512_neon,%function
-+.align	5
-+ChaCha20_512_neon:
-+	stp	x29,x30,[sp,#-96]!
-+	add	x29,sp,#0
-+
-+	adr	@x[0],.Lsigma
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	stp	x23,x24,[sp,#48]
-+	stp	x25,x26,[sp,#64]
-+	stp	x27,x28,[sp,#80]
-+
-+.L512_or_more_neon:
-+	sub	sp,sp,#128+64
-+
-+	ldp	@d[0],@d[1],[@x[0]]		// load sigma
-+	ld1	{@K[0]},[@x[0]],#16
-+	ldp	@d[2],@d[3],[$key]		// load key
-+	ldp	@d[4],@d[5],[$key,#16]
-+	ld1	{@K[1],@K[2]},[$key]
-+	ldp	@d[6],@d[7],[$ctr]		// load counter
-+	ld1	{@K[3]},[$ctr]
-+	ld1	{$ONE},[@x[0]]
-+#ifdef	__ARMEB__
-+	rev64	@K[0],@K[0]
-+	ror	@d[2],@d[2],#32
-+	ror	@d[3],@d[3],#32
-+	ror	@d[4],@d[4],#32
-+	ror	@d[5],@d[5],#32
-+	ror	@d[6],@d[6],#32
-+	ror	@d[7],@d[7],#32
-+#endif
-+	add	@K[3],@K[3],$ONE		// += 1
-+	stp	@K[0],@K[1],[sp,#0]		// off-load key block, invariant part
-+	add	@K[3],@K[3],$ONE		// not typo
-+	str	@K[2],[sp,#32]
-+	add	@K[4],@K[3],$ONE
-+	add	@K[5],@K[4],$ONE
-+	add	@K[6],@K[5],$ONE
-+	shl	$ONE,$ONE,#2			// 1 -> 4
-+
-+	stp	d8,d9,[sp,#128+0]		// meet ABI requirements
-+	stp	d10,d11,[sp,#128+16]
-+	stp	d12,d13,[sp,#128+32]
-+	stp	d14,d15,[sp,#128+48]
-+
-+	sub	$len,$len,#512			// not typo
-+
-+.Loop_outer_512_neon:
-+	 mov	$A0,@K[0]
-+	 mov	$A1,@K[0]
-+	 mov	$A2,@K[0]
-+	 mov	$A3,@K[0]
-+	 mov	$A4,@K[0]
-+	 mov	$A5,@K[0]
-+	 mov	$B0,@K[1]
-+	mov.32	@x[0],@d[0]			// unpack key block
-+	 mov	$B1,@K[1]
-+	lsr	@x[1],@d[0],#32
-+	 mov	$B2,@K[1]
-+	mov.32	@x[2],@d[1]
-+	 mov	$B3,@K[1]
-+	lsr	@x[3],@d[1],#32
-+	 mov	$B4,@K[1]
-+	mov.32	@x[4],@d[2]
-+	 mov	$B5,@K[1]
-+	lsr	@x[5],@d[2],#32
-+	 mov	$D0,@K[3]
-+	mov.32	@x[6],@d[3]
-+	 mov	$D1,@K[4]
-+	lsr	@x[7],@d[3],#32
-+	 mov	$D2,@K[5]
-+	mov.32	@x[8],@d[4]
-+	 mov	$D3,@K[6]
-+	lsr	@x[9],@d[4],#32
-+	 mov	$C0,@K[2]
-+	mov.32	@x[10],@d[5]
-+	 mov	$C1,@K[2]
-+	lsr	@x[11],@d[5],#32
-+	 add	$D4,$D0,$ONE			// +4
-+	mov.32	@x[12],@d[6]
-+	 add	$D5,$D1,$ONE			// +4
-+	lsr	@x[13],@d[6],#32
-+	 mov	$C2,@K[2]
-+	mov.32	@x[14],@d[7]
-+	 mov	$C3,@K[2]
-+	lsr	@x[15],@d[7],#32
-+	 mov	$C4,@K[2]
-+	 stp	@K[3],@K[4],[sp,#48]		// off-load key block, variable part
-+	 mov	$C5,@K[2]
-+	 str	@K[5],[sp,#80]
-+
-+	mov	$ctr,#5
-+	subs	$len,$len,#512
-+.Loop_upper_neon:
-+	sub	$ctr,$ctr,#1
-+___
-+	my @thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0);
-+	my @thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0);
-+	my @thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0);
-+	my @thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,0);
-+	my @thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,0);
-+	my @thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,0);
-+	my @thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
-+	my $diff = ($#thread0+1)*6 - $#thread67 - 1;
-+	my $i = 0;
-+
-+	foreach (@thread0) {
-+		eval;			eval(shift(@thread67));
-+		eval(shift(@thread1));	eval(shift(@thread67));
-+		eval(shift(@thread2));	eval(shift(@thread67));
-+		eval(shift(@thread3));	eval(shift(@thread67));
-+		eval(shift(@thread4));	eval(shift(@thread67));
-+		eval(shift(@thread5));	eval(shift(@thread67));
-+	}
-+
-+	@thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1);
-+	@thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1);
-+	@thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1);
-+	@thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,1);
-+	@thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,1);
-+	@thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,1);
-+	@thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
-+
-+	foreach (@thread0) {
-+		eval;			eval(shift(@thread67));
-+		eval(shift(@thread1));	eval(shift(@thread67));
-+		eval(shift(@thread2));	eval(shift(@thread67));
-+		eval(shift(@thread3));	eval(shift(@thread67));
-+		eval(shift(@thread4));	eval(shift(@thread67));
-+		eval(shift(@thread5));	eval(shift(@thread67));
-+	}
-+$code.=<<___;
-+	cbnz	$ctr,.Loop_upper_neon
-+
-+	add.32	@x[0],@x[0],@d[0]		// accumulate key block
-+	add	@x[1],@x[1],@d[0],lsr#32
-+	add.32	@x[2],@x[2],@d[1]
-+	add	@x[3],@x[3],@d[1],lsr#32
-+	add.32	@x[4],@x[4],@d[2]
-+	add	@x[5],@x[5],@d[2],lsr#32
-+	add.32	@x[6],@x[6],@d[3]
-+	add	@x[7],@x[7],@d[3],lsr#32
-+	add.32	@x[8],@x[8],@d[4]
-+	add	@x[9],@x[9],@d[4],lsr#32
-+	add.32	@x[10],@x[10],@d[5]
-+	add	@x[11],@x[11],@d[5],lsr#32
-+	add.32	@x[12],@x[12],@d[6]
-+	add	@x[13],@x[13],@d[6],lsr#32
-+	add.32	@x[14],@x[14],@d[7]
-+	add	@x[15],@x[15],@d[7],lsr#32
-+
-+	add	@x[0],@x[0],@x[1],lsl#32	// pack
-+	add	@x[2],@x[2],@x[3],lsl#32
-+	ldp	@x[1],@x[3],[$inp,#0]		// load input
-+	add	@x[4],@x[4],@x[5],lsl#32
-+	add	@x[6],@x[6],@x[7],lsl#32
-+	ldp	@x[5],@x[7],[$inp,#16]
-+	add	@x[8],@x[8],@x[9],lsl#32
-+	add	@x[10],@x[10],@x[11],lsl#32
-+	ldp	@x[9],@x[11],[$inp,#32]
-+	add	@x[12],@x[12],@x[13],lsl#32
-+	add	@x[14],@x[14],@x[15],lsl#32
-+	ldp	@x[13],@x[15],[$inp,#48]
-+	add	$inp,$inp,#64
-+#ifdef	__ARMEB__
-+	rev	@x[0],@x[0]
-+	rev	@x[2],@x[2]
-+	rev	@x[4],@x[4]
-+	rev	@x[6],@x[6]
-+	rev	@x[8],@x[8]
-+	rev	@x[10],@x[10]
-+	rev	@x[12],@x[12]
-+	rev	@x[14],@x[14]
-+#endif
-+	eor	@x[0],@x[0],@x[1]
-+	eor	@x[2],@x[2],@x[3]
-+	eor	@x[4],@x[4],@x[5]
-+	eor	@x[6],@x[6],@x[7]
-+	eor	@x[8],@x[8],@x[9]
-+	eor	@x[10],@x[10],@x[11]
-+	eor	@x[12],@x[12],@x[13]
-+	eor	@x[14],@x[14],@x[15]
-+
-+	 stp	@x[0],@x[2],[$out,#0]		// store output
-+	 add	@d[6],@d[6],#1			// increment counter
-+	mov.32	@x[0],@d[0]			// unpack key block
-+	lsr	@x[1],@d[0],#32
-+	 stp	@x[4],@x[6],[$out,#16]
-+	mov.32	@x[2],@d[1]
-+	lsr	@x[3],@d[1],#32
-+	 stp	@x[8],@x[10],[$out,#32]
-+	mov.32	@x[4],@d[2]
-+	lsr	@x[5],@d[2],#32
-+	 stp	@x[12],@x[14],[$out,#48]
-+	 add	$out,$out,#64
-+	mov.32	@x[6],@d[3]
-+	lsr	@x[7],@d[3],#32
-+	mov.32	@x[8],@d[4]
-+	lsr	@x[9],@d[4],#32
-+	mov.32	@x[10],@d[5]
-+	lsr	@x[11],@d[5],#32
-+	mov.32	@x[12],@d[6]
-+	lsr	@x[13],@d[6],#32
-+	mov.32	@x[14],@d[7]
-+	lsr	@x[15],@d[7],#32
-+
-+	mov	$ctr,#5
-+.Loop_lower_neon:
-+	sub	$ctr,$ctr,#1
-+___
-+	@thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,0);
-+	@thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,0);
-+	@thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,0);
-+	@thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,0);
-+	@thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,0);
-+	@thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,0);
-+	@thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
-+
-+	foreach (@thread0) {
-+		eval;			eval(shift(@thread67));
-+		eval(shift(@thread1));	eval(shift(@thread67));
-+		eval(shift(@thread2));	eval(shift(@thread67));
-+		eval(shift(@thread3));	eval(shift(@thread67));
-+		eval(shift(@thread4));	eval(shift(@thread67));
-+		eval(shift(@thread5));	eval(shift(@thread67));
-+	}
-+
-+	@thread0=&NEONROUND($A0,$B0,$C0,$D0,$T0,1);
-+	@thread1=&NEONROUND($A1,$B1,$C1,$D1,$T1,1);
-+	@thread2=&NEONROUND($A2,$B2,$C2,$D2,$T2,1);
-+	@thread3=&NEONROUND($A3,$B3,$C3,$D3,$T3,1);
-+	@thread4=&NEONROUND($A4,$B4,$C4,$D4,$T4,1);
-+	@thread5=&NEONROUND($A5,$B5,$C5,$D5,$T5,1);
-+	@thread67=(&ROUND(0,4,8,12),&ROUND(0,5,10,15));
-+
-+	foreach (@thread0) {
-+		eval;			eval(shift(@thread67));
-+		eval(shift(@thread1));	eval(shift(@thread67));
-+		eval(shift(@thread2));	eval(shift(@thread67));
-+		eval(shift(@thread3));	eval(shift(@thread67));
-+		eval(shift(@thread4));	eval(shift(@thread67));
-+		eval(shift(@thread5));	eval(shift(@thread67));
-+	}
-+$code.=<<___;
-+	cbnz	$ctr,.Loop_lower_neon
-+
-+	add.32	@x[0],@x[0],@d[0]		// accumulate key block
-+	 ldp	@K[0],@K[1],[sp,#0]
-+	add	@x[1],@x[1],@d[0],lsr#32
-+	 ldp	@K[2],@K[3],[sp,#32]
-+	add.32	@x[2],@x[2],@d[1]
-+	 ldp	@K[4],@K[5],[sp,#64]
-+	add	@x[3],@x[3],@d[1],lsr#32
-+	 add	$A0,$A0,@K[0]
-+	add.32	@x[4],@x[4],@d[2]
-+	 add	$A1,$A1,@K[0]
-+	add	@x[5],@x[5],@d[2],lsr#32
-+	 add	$A2,$A2,@K[0]
-+	add.32	@x[6],@x[6],@d[3]
-+	 add	$A3,$A3,@K[0]
-+	add	@x[7],@x[7],@d[3],lsr#32
-+	 add	$A4,$A4,@K[0]
-+	add.32	@x[8],@x[8],@d[4]
-+	 add	$A5,$A5,@K[0]
-+	add	@x[9],@x[9],@d[4],lsr#32
-+	 add	$C0,$C0,@K[2]
-+	add.32	@x[10],@x[10],@d[5]
-+	 add	$C1,$C1,@K[2]
-+	add	@x[11],@x[11],@d[5],lsr#32
-+	 add	$C2,$C2,@K[2]
-+	add.32	@x[12],@x[12],@d[6]
-+	 add	$C3,$C3,@K[2]
-+	add	@x[13],@x[13],@d[6],lsr#32
-+	 add	$C4,$C4,@K[2]
-+	add.32	@x[14],@x[14],@d[7]
-+	 add	$C5,$C5,@K[2]
-+	add	@x[15],@x[15],@d[7],lsr#32
-+	 add	$D4,$D4,$ONE			// +4
-+	add	@x[0],@x[0],@x[1],lsl#32	// pack
-+	 add	$D5,$D5,$ONE			// +4
-+	add	@x[2],@x[2],@x[3],lsl#32
-+	 add	$D0,$D0,@K[3]
-+	ldp	@x[1],@x[3],[$inp,#0]		// load input
-+	 add	$D1,$D1,@K[4]
-+	add	@x[4],@x[4],@x[5],lsl#32
-+	 add	$D2,$D2,@K[5]
-+	add	@x[6],@x[6],@x[7],lsl#32
-+	 add	$D3,$D3,@K[6]
-+	ldp	@x[5],@x[7],[$inp,#16]
-+	 add	$D4,$D4,@K[3]
-+	add	@x[8],@x[8],@x[9],lsl#32
-+	 add	$D5,$D5,@K[4]
-+	add	@x[10],@x[10],@x[11],lsl#32
-+	 add	$B0,$B0,@K[1]
-+	ldp	@x[9],@x[11],[$inp,#32]
-+	 add	$B1,$B1,@K[1]
-+	add	@x[12],@x[12],@x[13],lsl#32
-+	 add	$B2,$B2,@K[1]
-+	add	@x[14],@x[14],@x[15],lsl#32
-+	 add	$B3,$B3,@K[1]
-+	ldp	@x[13],@x[15],[$inp,#48]
-+	 add	$B4,$B4,@K[1]
-+	add	$inp,$inp,#64
-+	 add	$B5,$B5,@K[1]
-+
-+#ifdef	__ARMEB__
-+	rev	@x[0],@x[0]
-+	rev	@x[2],@x[2]
-+	rev	@x[4],@x[4]
-+	rev	@x[6],@x[6]
-+	rev	@x[8],@x[8]
-+	rev	@x[10],@x[10]
-+	rev	@x[12],@x[12]
-+	rev	@x[14],@x[14]
-+#endif
-+	ld1.8	{$T0-$T3},[$inp],#64
-+	eor	@x[0],@x[0],@x[1]
-+	eor	@x[2],@x[2],@x[3]
-+	eor	@x[4],@x[4],@x[5]
-+	eor	@x[6],@x[6],@x[7]
-+	eor	@x[8],@x[8],@x[9]
-+	 eor	$A0,$A0,$T0
-+	eor	@x[10],@x[10],@x[11]
-+	 eor	$B0,$B0,$T1
-+	eor	@x[12],@x[12],@x[13]
-+	 eor	$C0,$C0,$T2
-+	eor	@x[14],@x[14],@x[15]
-+	 eor	$D0,$D0,$T3
-+	 ld1.8	{$T0-$T3},[$inp],#64
-+
-+	stp	@x[0],@x[2],[$out,#0]		// store output
-+	 add	@d[6],@d[6],#7			// increment counter
-+	stp	@x[4],@x[6],[$out,#16]
-+	stp	@x[8],@x[10],[$out,#32]
-+	stp	@x[12],@x[14],[$out,#48]
-+	add	$out,$out,#64
-+	st1.8	{$A0-$D0},[$out],#64
-+
-+	ld1.8	{$A0-$D0},[$inp],#64
-+	eor	$A1,$A1,$T0
-+	eor	$B1,$B1,$T1
-+	eor	$C1,$C1,$T2
-+	eor	$D1,$D1,$T3
-+	st1.8	{$A1-$D1},[$out],#64
-+
-+	ld1.8	{$A1-$D1},[$inp],#64
-+	eor	$A2,$A2,$A0
-+	 ldp	@K[0],@K[1],[sp,#0]
-+	eor	$B2,$B2,$B0
-+	 ldp	@K[2],@K[3],[sp,#32]
-+	eor	$C2,$C2,$C0
-+	eor	$D2,$D2,$D0
-+	st1.8	{$A2-$D2},[$out],#64
-+
-+	ld1.8	{$A2-$D2},[$inp],#64
-+	eor	$A3,$A3,$A1
-+	eor	$B3,$B3,$B1
-+	eor	$C3,$C3,$C1
-+	eor	$D3,$D3,$D1
-+	st1.8	{$A3-$D3},[$out],#64
-+
-+	ld1.8	{$A3-$D3},[$inp],#64
-+	eor	$A4,$A4,$A2
-+	eor	$B4,$B4,$B2
-+	eor	$C4,$C4,$C2
-+	eor	$D4,$D4,$D2
-+	st1.8	{$A4-$D4},[$out],#64
-+
-+	shl	$A0,$ONE,#1			// 4 -> 8
-+	eor	$A5,$A5,$A3
-+	eor	$B5,$B5,$B3
-+	eor	$C5,$C5,$C3
-+	eor	$D5,$D5,$D3
-+	st1.8	{$A5-$D5},[$out],#64
-+
-+	add	@K[3],@K[3],$A0			// += 8
-+	add	@K[4],@K[4],$A0
-+	add	@K[5],@K[5],$A0
-+	add	@K[6],@K[6],$A0
-+
-+	b.hs	.Loop_outer_512_neon
-+
-+	adds	$len,$len,#512
-+	ushr	$A0,$ONE,#2			// 4 -> 1
-+
-+	ldp	d8,d9,[sp,#128+0]		// meet ABI requirements
-+	ldp	d10,d11,[sp,#128+16]
-+	ldp	d12,d13,[sp,#128+32]
-+	ldp	d14,d15,[sp,#128+48]
-+
-+	stp	@K[0],$ONE,[sp,#0]		// wipe off-load area
-+	stp	@K[0],$ONE,[sp,#32]
-+	stp	@K[0],$ONE,[sp,#64]
-+
-+	b.eq	.Ldone_512_neon
-+
-+	cmp	$len,#192
-+	sub	@K[3],@K[3],$A0			// -= 1
-+	sub	@K[4],@K[4],$A0
-+	sub	@K[5],@K[5],$A0
-+	add	sp,sp,#128
-+	b.hs	.Loop_outer_neon
-+
-+	eor	@K[1],@K[1],@K[1]
-+	eor	@K[2],@K[2],@K[2]
-+	eor	@K[3],@K[3],@K[3]
-+	eor	@K[4],@K[4],@K[4]
-+	eor	@K[5],@K[5],@K[5]
-+	eor	@K[6],@K[6],@K[6]
-+	b	.Loop_outer
-+
-+.Ldone_512_neon:
-+	ldp	x19,x20,[x29,#16]
-+	add	sp,sp,#128+64
-+	ldp	x21,x22,[x29,#32]
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	ldp	x27,x28,[x29,#80]
-+	ldp	x29,x30,[sp],#96
-+	ret
-+.size	ChaCha20_512_neon,.-ChaCha20_512_neon
-+___
-+}
-+}}}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	(s/\b([a-z]+)\.32\b/$1/ and (s/x([0-9]+)/w$1/g or 1))	or
-+	(m/\b(eor|ext|mov)\b/ and (s/\.4s/\.16b/g or 1))	or
-+	(s/\b((?:ld|st)1)\.8\b/$1/ and (s/\.4s/\.16b/g or 1))	or
-+	(m/\b(ld|st)[rp]\b/ and (s/v([0-9]+)\.4s/q$1/g or 1))	or
-+	(s/\brev32\.16\b/rev32/ and (s/\.4s/\.8h/g or 1));
-+
-+	#s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo;
-+
-+	print $_,"\n";
-+}
-+close STDOUT;	# flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-c64xplus.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-c64xplus.pl
-new file mode 100755
-index 0000000..bdb3804
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-c64xplus.pl
-@@ -0,0 +1,926 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# ChaCha20 for C64x+.
-+#
-+# October 2015
-+#
-+# Performance is 3.54 cycles per processed byte, which is ~4.3 times
-+# faster than code generated by TI compiler. Compiler also disables
-+# interrupts for some reason, thus making interrupt response time
-+# dependent on input length. This module on the other hand is free
-+# from such limiation.
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+($OUT,$INP,$LEN,$KEYB,$COUNTERA)=("A4","B4","A6","B6","A8");
-+($KEYA,$COUNTERB,$STEP)=("A7","B7","A3");
-+
-+@X=  ("A16","B16","A17","B17","A18","B18","A19","B19",
-+      "A20","B20","A21","B21","A22","B22","A23","B23");
-+@Y=  ("A24","B24","A25","B25","A26","B26","A27","B27",
-+      "A28","B28","A29","B29","A30","B30","A31","B31");
-+@DAT=("A6", "A7", "B6", "B7", "A8", "A9", "B8", "B9",
-+      "A10","A11","B10","B11","A12","A13","B12","B13");
-+
-+# yes, overlaps with @DAT, used only in 2x interleave code path...
-+@K2x=("A6", "B6", "A7", "B7", "A8", "B8", "A9", "B9",
-+      "A10","B10","A11","B11","A2", "B2", "A13","B13");
-+
-+$code.=<<___;
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.asg	ChaCha20_ctr32,_ChaCha20_ctr32
-+	.endif
-+
-+	.asg	B3,RA
-+	.asg	A15,FP
-+	.asg	B15,SP
-+
-+	.global	_ChaCha20_ctr32
-+	.align	32
-+_ChaCha20_ctr32:
-+	.asmfunc	stack_usage(40+64)
-+	MV	$LEN,A0			; reassign
-+  [!A0]	BNOP	RA			; no data
-+|| [A0]	STW	FP,*SP--(40+64)		; save frame pointer and alloca(40+64)
-+|| [A0]	MV	SP,FP
-+   [A0]	STDW	B13:B12,*SP[4+8]	; ABI says so
-+|| [A0]	MV	$KEYB,$KEYA
-+|| [A0]	MV	$COUNTERA,$COUNTERB
-+   [A0]	STDW	B11:B10,*SP[3+8]
-+|| [A0]	STDW	A13:A12,*FP[-3]
-+   [A0]	STDW	A11:A10,*FP[-4]
-+|| [A0]	MVK	128,$STEP		; 2 * input block size
-+
-+   [A0]	LDW	*${KEYA}[0],@Y[4]	; load key
-+|| [A0]	LDW	*${KEYB}[1],@Y[5]
-+|| [A0]	MVK	0x00007865,@Y[0]	; synthesize sigma
-+|| [A0]	MVK	0x0000646e,@Y[1]
-+   [A0]	LDW	*${KEYA}[2],@Y[6]
-+|| [A0]	LDW	*${KEYB}[3],@Y[7]
-+|| [A0]	MVKH	0x61700000,@Y[0]
-+|| [A0]	MVKH	0x33200000,@Y[1]
-+	LDW	*${KEYA}[4],@Y[8]
-+||	LDW	*${KEYB}[5],@Y[9]
-+||	MVK	0x00002d32,@Y[2]
-+||	MVK	0x00006574,@Y[3]
-+	LDW	*${KEYA}[6],@Y[10]
-+||	LDW	*${KEYB}[7],@Y[11]
-+||	MVKH	0x79620000,@Y[2]
-+||	MVKH	0x6b200000,@Y[3]
-+	LDW	*${COUNTERA}[0],@Y[12]	; load counter||nonce
-+||	LDW	*${COUNTERB}[1],@Y[13]
-+||	CMPLTU	A0,$STEP,A1		; is length < 2*blocks?
-+	LDW	*${COUNTERA}[2],@Y[14]
-+||	LDW	*${COUNTERB}[3],@Y[15]
-+|| [A1]	BNOP	top1x?
-+   [A1]	MVK	64,$STEP		; input block size
-+||	MVK	10,B0			; inner loop counter
-+
-+	DMV	@Y[2],@Y[0],@X[2]:@X[0]	; copy block
-+||	DMV	@Y[3],@Y[1],@X[3]:@X[1]
-+||[!A1]	STDW	@Y[2]:@Y[0],*FP[-12]	; offload key material to stack
-+||[!A1]	STDW	@Y[3]:@Y[1],*SP[2]
-+	DMV	@Y[6],@Y[4],@X[6]:@X[4]
-+||	DMV	@Y[7],@Y[5],@X[7]:@X[5]
-+||[!A1]	STDW	@Y[6]:@Y[4],*FP[-10]
-+||[!A1]	STDW	@Y[7]:@Y[5],*SP[4]
-+	DMV	@Y[10],@Y[8],@X[10]:@X[8]
-+||	DMV	@Y[11],@Y[9],@X[11]:@X[9]
-+||[!A1]	STDW	@Y[10]:@Y[8],*FP[-8]
-+||[!A1]	STDW	@Y[11]:@Y[9],*SP[6]
-+	DMV	@Y[14],@Y[12],@X[14]:@X[12]
-+||	DMV	@Y[15],@Y[13],@X[15]:@X[13]
-+||[!A1]	MV	@Y[12],@K2x[12]		; counter
-+||[!A1]	MV	@Y[13],@K2x[13]
-+||[!A1]	STW	@Y[14],*FP[-6*2]
-+||[!A1]	STW	@Y[15],*SP[8*2]
-+___
-+{	################################################################
-+	# 2x interleave gives 50% performance improvement
-+	#
-+my ($a0,$a1,$a2,$a3) = (0..3);
-+my ($b0,$b1,$b2,$b3) = (4..7);
-+my ($c0,$c1,$c2,$c3) = (8..11);
-+my ($d0,$d1,$d2,$d3) = (12..15);
-+
-+$code.=<<___;
-+outer2x?:
-+	ADD	@X[$b1],@X[$a1],@X[$a1]
-+||	ADD	@X[$b2],@X[$a2],@X[$a2]
-+||	ADD	@X[$b0],@X[$a0],@X[$a0]
-+||	ADD	@X[$b3],@X[$a3],@X[$a3]
-+||	 DMV	@Y[2],@Y[0],@K2x[2]:@K2x[0]
-+||	 DMV	@Y[3],@Y[1],@K2x[3]:@K2x[1]
-+	XOR	@X[$a1],@X[$d1],@X[$d1]
-+||	XOR	@X[$a2],@X[$d2],@X[$d2]
-+||	XOR	@X[$a0],@X[$d0],@X[$d0]
-+||	XOR	@X[$a3],@X[$d3],@X[$d3]
-+||	 DMV	@Y[6],@Y[4],@K2x[6]:@K2x[4]
-+||	 DMV	@Y[7],@Y[5],@K2x[7]:@K2x[5]
-+	SWAP2	@X[$d1],@X[$d1]		; rotate by 16
-+||	SWAP2	@X[$d2],@X[$d2]
-+||	SWAP2	@X[$d0],@X[$d0]
-+||	SWAP2	@X[$d3],@X[$d3]
-+
-+	ADD	@X[$d1],@X[$c1],@X[$c1]
-+||	ADD	@X[$d2],@X[$c2],@X[$c2]
-+||	ADD	@X[$d0],@X[$c0],@X[$c0]
-+||	ADD	@X[$d3],@X[$c3],@X[$c3]
-+||	 DMV	@Y[10],@Y[8],@K2x[10]:@K2x[8]
-+||	 DMV	@Y[11],@Y[9],@K2x[11]:@K2x[9]
-+	XOR	@X[$c1],@X[$b1],@X[$b1]
-+||	XOR	@X[$c2],@X[$b2],@X[$b2]
-+||	XOR	@X[$c0],@X[$b0],@X[$b0]
-+||	XOR	@X[$c3],@X[$b3],@X[$b3]
-+||	 ADD	1,@Y[12],@Y[12]		; adjust counter for 2nd block
-+	ROTL	@X[$b1],12,@X[$b1]
-+||	ROTL	@X[$b2],12,@X[$b2]
-+||	 MV	@Y[14],@K2x[14]
-+||	 MV	@Y[15],@K2x[15]
-+top2x?:
-+	ROTL	@X[$b0],12,@X[$b0]
-+||	ROTL	@X[$b3],12,@X[$b3]
-+||	 ADD	@Y[$b1],@Y[$a1],@Y[$a1]
-+||	 ADD	@Y[$b2],@Y[$a2],@Y[$a2]
-+	 ADD	@Y[$b0],@Y[$a0],@Y[$a0]
-+||	 ADD	@Y[$b3],@Y[$a3],@Y[$a3]
-+
-+||	ADD	@X[$b1],@X[$a1],@X[$a1]
-+||	ADD	@X[$b2],@X[$a2],@X[$a2]
-+||	 XOR	@Y[$a1],@Y[$d1],@Y[$d1]
-+||	 XOR	@Y[$a2],@Y[$d2],@Y[$d2]
-+	 XOR	@Y[$a0],@Y[$d0],@Y[$d0]
-+||	 XOR	@Y[$a3],@Y[$d3],@Y[$d3]
-+||	ADD	@X[$b0],@X[$a0],@X[$a0]
-+||	ADD	@X[$b3],@X[$a3],@X[$a3]
-+||	XOR	@X[$a1],@X[$d1],@X[$d1]
-+||	XOR	@X[$a2],@X[$d2],@X[$d2]
-+	XOR	@X[$a0],@X[$d0],@X[$d0]
-+||	XOR	@X[$a3],@X[$d3],@X[$d3]
-+||	ROTL	@X[$d1],8,@X[$d1]
-+||	ROTL	@X[$d2],8,@X[$d2]
-+||	 SWAP2	@Y[$d1],@Y[$d1]		; rotate by 16
-+||	 SWAP2	@Y[$d2],@Y[$d2]
-+||	 SWAP2	@Y[$d0],@Y[$d0]
-+||	 SWAP2	@Y[$d3],@Y[$d3]
-+	ROTL	@X[$d0],8,@X[$d0]
-+||	ROTL	@X[$d3],8,@X[$d3]
-+||	 ADD	@Y[$d1],@Y[$c1],@Y[$c1]
-+||	 ADD	@Y[$d2],@Y[$c2],@Y[$c2]
-+||	 ADD	@Y[$d0],@Y[$c0],@Y[$c0]
-+||	 ADD	@Y[$d3],@Y[$c3],@Y[$c3]
-+||	BNOP	middle2x1?		; protect from interrupt
-+
-+	ADD	@X[$d1],@X[$c1],@X[$c1]
-+||	ADD	@X[$d2],@X[$c2],@X[$c2]
-+||	 XOR	@Y[$c1],@Y[$b1],@Y[$b1]
-+||	 XOR	@Y[$c2],@Y[$b2],@Y[$b2]
-+||	 XOR	@Y[$c0],@Y[$b0],@Y[$b0]
-+||	 XOR	@Y[$c3],@Y[$b3],@Y[$b3]
-+	ADD	@X[$d0],@X[$c0],@X[$c0]
-+||	ADD	@X[$d3],@X[$c3],@X[$c3]
-+||	XOR	@X[$c1],@X[$b1],@X[$b1]
-+||	XOR	@X[$c2],@X[$b2],@X[$b2]
-+||	ROTL	@X[$d1],0,@X[$d2]	; moved to avoid cross-path stall
-+||	ROTL	@X[$d2],0,@X[$d3]
-+	XOR	@X[$c0],@X[$b0],@X[$b0]
-+||	XOR	@X[$c3],@X[$b3],@X[$b3]
-+||	MV	@X[$d0],@X[$d1]
-+||	MV	@X[$d3],@X[$d0]
-+||	 ROTL	@Y[$b1],12,@Y[$b1]
-+||	 ROTL	@Y[$b2],12,@Y[$b2]
-+	ROTL	@X[$b1],7,@X[$b0]	; avoided cross-path stall
-+||	ROTL	@X[$b2],7,@X[$b1]
-+	ROTL	@X[$b0],7,@X[$b3]
-+||	ROTL	@X[$b3],7,@X[$b2]
-+middle2x1?:
-+
-+	 ROTL	@Y[$b0],12,@Y[$b0]
-+||	 ROTL	@Y[$b3],12,@Y[$b3]
-+||	ADD	@X[$b0],@X[$a0],@X[$a0]
-+||	ADD	@X[$b1],@X[$a1],@X[$a1]
-+	ADD	@X[$b2],@X[$a2],@X[$a2]
-+||	ADD	@X[$b3],@X[$a3],@X[$a3]
-+
-+||	 ADD	@Y[$b1],@Y[$a1],@Y[$a1]
-+||	 ADD	@Y[$b2],@Y[$a2],@Y[$a2]
-+||	XOR	@X[$a0],@X[$d0],@X[$d0]
-+||	XOR	@X[$a1],@X[$d1],@X[$d1]
-+	XOR	@X[$a2],@X[$d2],@X[$d2]
-+||	XOR	@X[$a3],@X[$d3],@X[$d3]
-+||	 ADD	@Y[$b0],@Y[$a0],@Y[$a0]
-+||	 ADD	@Y[$b3],@Y[$a3],@Y[$a3]
-+||	 XOR	@Y[$a1],@Y[$d1],@Y[$d1]
-+||	 XOR	@Y[$a2],@Y[$d2],@Y[$d2]
-+	 XOR	@Y[$a0],@Y[$d0],@Y[$d0]
-+||	 XOR	@Y[$a3],@Y[$d3],@Y[$d3]
-+||	 ROTL	@Y[$d1],8,@Y[$d1]
-+||	 ROTL	@Y[$d2],8,@Y[$d2]
-+||	SWAP2	@X[$d0],@X[$d0]		; rotate by 16
-+||	SWAP2	@X[$d1],@X[$d1]
-+||	SWAP2	@X[$d2],@X[$d2]
-+||	SWAP2	@X[$d3],@X[$d3]
-+	 ROTL	@Y[$d0],8,@Y[$d0]
-+||	 ROTL	@Y[$d3],8,@Y[$d3]
-+||	ADD	@X[$d0],@X[$c2],@X[$c2]
-+||	ADD	@X[$d1],@X[$c3],@X[$c3]
-+||	ADD	@X[$d2],@X[$c0],@X[$c0]
-+||	ADD	@X[$d3],@X[$c1],@X[$c1]
-+||	BNOP	middle2x2?		; protect from interrupt
-+
-+	 ADD	@Y[$d1],@Y[$c1],@Y[$c1]
-+||	 ADD	@Y[$d2],@Y[$c2],@Y[$c2]
-+||	XOR	@X[$c2],@X[$b0],@X[$b0]
-+||	XOR	@X[$c3],@X[$b1],@X[$b1]
-+||	XOR	@X[$c0],@X[$b2],@X[$b2]
-+||	XOR	@X[$c1],@X[$b3],@X[$b3]
-+	 ADD	@Y[$d0],@Y[$c0],@Y[$c0]
-+||	 ADD	@Y[$d3],@Y[$c3],@Y[$c3]
-+||	 XOR	@Y[$c1],@Y[$b1],@Y[$b1]
-+||	 XOR	@Y[$c2],@Y[$b2],@Y[$b2]
-+||	 ROTL	@Y[$d1],0,@Y[$d2]	; moved to avoid cross-path stall
-+||	 ROTL	@Y[$d2],0,@Y[$d3]
-+	 XOR	@Y[$c0],@Y[$b0],@Y[$b0]
-+||	 XOR	@Y[$c3],@Y[$b3],@Y[$b3]
-+||	 MV	@Y[$d0],@Y[$d1]
-+||	 MV	@Y[$d3],@Y[$d0]
-+||	ROTL	@X[$b0],12,@X[$b0]
-+||	ROTL	@X[$b1],12,@X[$b1]
-+	 ROTL	@Y[$b1],7,@Y[$b0]	; avoided cross-path stall
-+||	 ROTL	@Y[$b2],7,@Y[$b1]
-+	 ROTL	@Y[$b0],7,@Y[$b3]
-+||	 ROTL	@Y[$b3],7,@Y[$b2]
-+middle2x2?:
-+
-+	ROTL	@X[$b2],12,@X[$b2]
-+||	ROTL	@X[$b3],12,@X[$b3]
-+||	 ADD	@Y[$b0],@Y[$a0],@Y[$a0]
-+||	 ADD	@Y[$b1],@Y[$a1],@Y[$a1]
-+	 ADD	@Y[$b2],@Y[$a2],@Y[$a2]
-+||	 ADD	@Y[$b3],@Y[$a3],@Y[$a3]
-+
-+||	ADD	@X[$b0],@X[$a0],@X[$a0]
-+||	ADD	@X[$b1],@X[$a1],@X[$a1]
-+||	 XOR	@Y[$a0],@Y[$d0],@Y[$d0]
-+||	 XOR	@Y[$a1],@Y[$d1],@Y[$d1]
-+	 XOR	@Y[$a2],@Y[$d2],@Y[$d2]
-+||	 XOR	@Y[$a3],@Y[$d3],@Y[$d3]
-+||	ADD	@X[$b2],@X[$a2],@X[$a2]
-+||	ADD	@X[$b3],@X[$a3],@X[$a3]
-+||	XOR	@X[$a0],@X[$d0],@X[$d0]
-+||	XOR	@X[$a1],@X[$d1],@X[$d1]
-+	XOR	@X[$a2],@X[$d2],@X[$d2]
-+||	XOR	@X[$a3],@X[$d3],@X[$d3]
-+||	ROTL	@X[$d0],8,@X[$d0]
-+||	ROTL	@X[$d1],8,@X[$d1]
-+||	 SWAP2	@Y[$d0],@Y[$d0]		; rotate by 16
-+||	 SWAP2	@Y[$d1],@Y[$d1]
-+||	 SWAP2	@Y[$d2],@Y[$d2]
-+||	 SWAP2	@Y[$d3],@Y[$d3]
-+	ROTL	@X[$d2],8,@X[$d2]
-+||	ROTL	@X[$d3],8,@X[$d3]
-+||	 ADD	@Y[$d0],@Y[$c2],@Y[$c2]
-+||	 ADD	@Y[$d1],@Y[$c3],@Y[$c3]
-+||	 ADD	@Y[$d2],@Y[$c0],@Y[$c0]
-+||	 ADD	@Y[$d3],@Y[$c1],@Y[$c1]
-+||	BNOP	bottom2x1?		; protect from interrupt
-+
-+	ADD	@X[$d0],@X[$c2],@X[$c2]
-+||	ADD	@X[$d1],@X[$c3],@X[$c3]
-+||	 XOR	@Y[$c2],@Y[$b0],@Y[$b0]
-+||	 XOR	@Y[$c3],@Y[$b1],@Y[$b1]
-+||	 XOR	@Y[$c0],@Y[$b2],@Y[$b2]
-+||	 XOR	@Y[$c1],@Y[$b3],@Y[$b3]
-+	ADD	@X[$d2],@X[$c0],@X[$c0]
-+||	ADD	@X[$d3],@X[$c1],@X[$c1]
-+||	XOR	@X[$c2],@X[$b0],@X[$b0]
-+||	XOR	@X[$c3],@X[$b1],@X[$b1]
-+||	ROTL	@X[$d0],0,@X[$d3]	; moved to avoid cross-path stall
-+||	ROTL	@X[$d1],0,@X[$d0]
-+	XOR	@X[$c0],@X[$b2],@X[$b2]
-+||	XOR	@X[$c1],@X[$b3],@X[$b3]
-+||	MV	@X[$d2],@X[$d1]
-+||	MV	@X[$d3],@X[$d2]
-+||	 ROTL	@Y[$b0],12,@Y[$b0]
-+||	 ROTL	@Y[$b1],12,@Y[$b1]
-+	ROTL	@X[$b0],7,@X[$b1]	; avoided cross-path stall
-+||	ROTL	@X[$b1],7,@X[$b2]
-+	ROTL	@X[$b2],7,@X[$b3]
-+||	ROTL	@X[$b3],7,@X[$b0]
-+|| [B0]	SUB	B0,1,B0			; decrement inner loop counter
-+bottom2x1?:
-+
-+	 ROTL	@Y[$b2],12,@Y[$b2]
-+||	 ROTL	@Y[$b3],12,@Y[$b3]
-+|| [B0]	ADD	@X[$b1],@X[$a1],@X[$a1]	; modulo-scheduled
-+|| [B0]	ADD	@X[$b2],@X[$a2],@X[$a2]
-+   [B0]	ADD	@X[$b0],@X[$a0],@X[$a0]
-+|| [B0]	ADD	@X[$b3],@X[$a3],@X[$a3]
-+
-+||	 ADD	@Y[$b0],@Y[$a0],@Y[$a0]
-+||	 ADD	@Y[$b1],@Y[$a1],@Y[$a1]
-+|| [B0]	XOR	@X[$a1],@X[$d1],@X[$d1]
-+|| [B0]	XOR	@X[$a2],@X[$d2],@X[$d2]
-+   [B0]	XOR	@X[$a0],@X[$d0],@X[$d0]
-+|| [B0]	XOR	@X[$a3],@X[$d3],@X[$d3]
-+||	 ADD	@Y[$b2],@Y[$a2],@Y[$a2]
-+||	 ADD	@Y[$b3],@Y[$a3],@Y[$a3]
-+||	 XOR	@Y[$a0],@Y[$d0],@Y[$d0]
-+||	 XOR	@Y[$a1],@Y[$d1],@Y[$d1]
-+	 XOR	@Y[$a2],@Y[$d2],@Y[$d2]
-+||	 XOR	@Y[$a3],@Y[$d3],@Y[$d3]
-+||	 ROTL	@Y[$d0],8,@Y[$d0]
-+||	 ROTL	@Y[$d1],8,@Y[$d1]
-+|| [B0]	SWAP2	@X[$d1],@X[$d1]		; rotate by 16
-+|| [B0]	SWAP2	@X[$d2],@X[$d2]
-+|| [B0]	SWAP2	@X[$d0],@X[$d0]
-+|| [B0]	SWAP2	@X[$d3],@X[$d3]
-+	 ROTL	@Y[$d2],8,@Y[$d2]
-+||	 ROTL	@Y[$d3],8,@Y[$d3]
-+|| [B0]	ADD	@X[$d1],@X[$c1],@X[$c1]
-+|| [B0]	ADD	@X[$d2],@X[$c2],@X[$c2]
-+|| [B0]	ADD	@X[$d0],@X[$c0],@X[$c0]
-+|| [B0]	ADD	@X[$d3],@X[$c3],@X[$c3]
-+|| [B0]	BNOP	top2x?			; even protects from interrupt
-+
-+	 ADD	@Y[$d0],@Y[$c2],@Y[$c2]
-+||	 ADD	@Y[$d1],@Y[$c3],@Y[$c3]
-+|| [B0]	XOR	@X[$c1],@X[$b1],@X[$b1]
-+|| [B0]	XOR	@X[$c2],@X[$b2],@X[$b2]
-+|| [B0]	XOR	@X[$c0],@X[$b0],@X[$b0]
-+|| [B0]	XOR	@X[$c3],@X[$b3],@X[$b3]
-+	 ADD	@Y[$d2],@Y[$c0],@Y[$c0]
-+||	 ADD	@Y[$d3],@Y[$c1],@Y[$c1]
-+||	 XOR	@Y[$c2],@Y[$b0],@Y[$b0]
-+||	 XOR	@Y[$c3],@Y[$b1],@Y[$b1]
-+||	 ROTL	@Y[$d0],0,@Y[$d3]	; moved to avoid cross-path stall
-+||	 ROTL	@Y[$d1],0,@Y[$d0]
-+	 XOR	@Y[$c0],@Y[$b2],@Y[$b2]
-+||	 XOR	@Y[$c1],@Y[$b3],@Y[$b3]
-+||	 MV	@Y[$d2],@Y[$d1]
-+||	 MV	@Y[$d3],@Y[$d2]
-+|| [B0]	ROTL	@X[$b1],12,@X[$b1]
-+|| [B0]	ROTL	@X[$b2],12,@X[$b2]
-+	 ROTL	@Y[$b0],7,@Y[$b1]	; avoided cross-path stall
-+||	 ROTL	@Y[$b1],7,@Y[$b2]
-+	 ROTL	@Y[$b2],7,@Y[$b3]
-+||	 ROTL	@Y[$b3],7,@Y[$b0]
-+bottom2x2?:
-+___
-+}
-+
-+$code.=<<___;
-+	ADD	@K2x[0],@X[0],@X[0]	; accumulate key material
-+||	ADD	@K2x[1],@X[1],@X[1]
-+||	ADD	@K2x[2],@X[2],@X[2]
-+||	ADD	@K2x[3],@X[3],@X[3]
-+	 ADD	@K2x[0],@Y[0],@Y[0]
-+||	 ADD	@K2x[1],@Y[1],@Y[1]
-+||	 ADD	@K2x[2],@Y[2],@Y[2]
-+||	 ADD	@K2x[3],@Y[3],@Y[3]
-+||	LDNDW	*${INP}++[8],@DAT[1]:@DAT[0]
-+	ADD	@K2x[4],@X[4],@X[4]
-+||	ADD	@K2x[5],@X[5],@X[5]
-+||	ADD	@K2x[6],@X[6],@X[6]
-+||	ADD	@K2x[7],@X[7],@X[7]
-+||	LDNDW	*${INP}[-7],@DAT[3]:@DAT[2]
-+	 ADD	@K2x[4],@Y[4],@Y[4]
-+||	 ADD	@K2x[5],@Y[5],@Y[5]
-+||	 ADD	@K2x[6],@Y[6],@Y[6]
-+||	 ADD	@K2x[7],@Y[7],@Y[7]
-+||	LDNDW	*${INP}[-6],@DAT[5]:@DAT[4]
-+	ADD	@K2x[8],@X[8],@X[8]
-+||	ADD	@K2x[9],@X[9],@X[9]
-+||	ADD	@K2x[10],@X[10],@X[10]
-+||	ADD	@K2x[11],@X[11],@X[11]
-+||	LDNDW	*${INP}[-5],@DAT[7]:@DAT[6]
-+	 ADD	@K2x[8],@Y[8],@Y[8]
-+||	 ADD	@K2x[9],@Y[9],@Y[9]
-+||	 ADD	@K2x[10],@Y[10],@Y[10]
-+||	 ADD	@K2x[11],@Y[11],@Y[11]
-+||	LDNDW	*${INP}[-4],@DAT[9]:@DAT[8]
-+	ADD	@K2x[12],@X[12],@X[12]
-+||	ADD	@K2x[13],@X[13],@X[13]
-+||	ADD	@K2x[14],@X[14],@X[14]
-+||	ADD	@K2x[15],@X[15],@X[15]
-+||	LDNDW	*${INP}[-3],@DAT[11]:@DAT[10]
-+	 ADD	@K2x[12],@Y[12],@Y[12]
-+||	 ADD	@K2x[13],@Y[13],@Y[13]
-+||	 ADD	@K2x[14],@Y[14],@Y[14]
-+||	 ADD	@K2x[15],@Y[15],@Y[15]
-+||	LDNDW	*${INP}[-2],@DAT[13]:@DAT[12]
-+	 ADD	1,@Y[12],@Y[12]		; adjust counter for 2nd block
-+||	ADD	2,@K2x[12],@K2x[12]	; increment counter
-+||	LDNDW	*${INP}[-1],@DAT[15]:@DAT[14]
-+
-+	.if	.BIG_ENDIAN
-+	SWAP2	@X[0],@X[0]
-+||	SWAP2	@X[1],@X[1]
-+||	SWAP2	@X[2],@X[2]
-+||	SWAP2	@X[3],@X[3]
-+	SWAP2	@X[4],@X[4]
-+||	SWAP2	@X[5],@X[5]
-+||	SWAP2	@X[6],@X[6]
-+||	SWAP2	@X[7],@X[7]
-+	SWAP2	@X[8],@X[8]
-+||	SWAP2	@X[9],@X[9]
-+||	SWAP4	@X[0],@X[1]
-+||	SWAP4	@X[1],@X[0]
-+	SWAP2	@X[10],@X[10]
-+||	SWAP2	@X[11],@X[11]
-+||	SWAP4	@X[2],@X[3]
-+||	SWAP4	@X[3],@X[2]
-+	SWAP2	@X[12],@X[12]
-+||	SWAP2	@X[13],@X[13]
-+||	SWAP4	@X[4],@X[5]
-+||	SWAP4	@X[5],@X[4]
-+	SWAP2	@X[14],@X[14]
-+||	SWAP2	@X[15],@X[15]
-+||	SWAP4	@X[6],@X[7]
-+||	SWAP4	@X[7],@X[6]
-+	SWAP4	@X[8],@X[9]
-+||	SWAP4	@X[9],@X[8]
-+||	 SWAP2	@Y[0],@Y[0]
-+||	 SWAP2	@Y[1],@Y[1]
-+	SWAP4	@X[10],@X[11]
-+||	SWAP4	@X[11],@X[10]
-+||	 SWAP2	@Y[2],@Y[2]
-+||	 SWAP2	@Y[3],@Y[3]
-+	SWAP4	@X[12],@X[13]
-+||	SWAP4	@X[13],@X[12]
-+||	 SWAP2	@Y[4],@Y[4]
-+||	 SWAP2	@Y[5],@Y[5]
-+	SWAP4	@X[14],@X[15]
-+||	SWAP4	@X[15],@X[14]
-+||	 SWAP2	@Y[6],@Y[6]
-+||	 SWAP2	@Y[7],@Y[7]
-+	 SWAP2	@Y[8],@Y[8]
-+||	 SWAP2	@Y[9],@Y[9]
-+||	 SWAP4	@Y[0],@Y[1]
-+||	 SWAP4	@Y[1],@Y[0]
-+	 SWAP2	@Y[10],@Y[10]
-+||	 SWAP2	@Y[11],@Y[11]
-+||	 SWAP4	@Y[2],@Y[3]
-+||	 SWAP4	@Y[3],@Y[2]
-+	 SWAP2	@Y[12],@Y[12]
-+||	 SWAP2	@Y[13],@Y[13]
-+||	 SWAP4	@Y[4],@Y[5]
-+||	 SWAP4	@Y[5],@Y[4]
-+	 SWAP2	@Y[14],@Y[14]
-+||	 SWAP2	@Y[15],@Y[15]
-+||	 SWAP4	@Y[6],@Y[7]
-+||	 SWAP4	@Y[7],@Y[6]
-+	 SWAP4	@Y[8],@Y[9]
-+||	 SWAP4	@Y[9],@Y[8]
-+	 SWAP4	@Y[10],@Y[11]
-+||	 SWAP4	@Y[11],@Y[10]
-+	 SWAP4	@Y[12],@Y[13]
-+||	 SWAP4	@Y[13],@Y[12]
-+	 SWAP4	@Y[14],@Y[15]
-+||	 SWAP4	@Y[15],@Y[14]
-+	.endif
-+
-+	XOR	@DAT[0],@X[0],@X[0]	; xor 1st block
-+||	XOR	@DAT[3],@X[3],@X[3]
-+||	XOR	@DAT[2],@X[2],@X[1]
-+||	XOR	@DAT[1],@X[1],@X[2]
-+||	LDNDW	*${INP}++[8],@DAT[1]:@DAT[0]
-+	XOR	@DAT[4],@X[4],@X[4]
-+||	XOR	@DAT[7],@X[7],@X[7]
-+||	LDNDW	*${INP}[-7],@DAT[3]:@DAT[2]
-+	XOR	@DAT[6],@X[6],@X[5]
-+||	XOR	@DAT[5],@X[5],@X[6]
-+||	LDNDW	*${INP}[-6],@DAT[5]:@DAT[4]
-+	XOR	@DAT[8],@X[8],@X[8]
-+||	XOR	@DAT[11],@X[11],@X[11]
-+||	LDNDW	*${INP}[-5],@DAT[7]:@DAT[6]
-+	XOR	@DAT[10],@X[10],@X[9]
-+||	XOR	@DAT[9],@X[9],@X[10]
-+||	LDNDW	*${INP}[-4],@DAT[9]:@DAT[8]
-+	XOR	@DAT[12],@X[12],@X[12]
-+||	XOR	@DAT[15],@X[15],@X[15]
-+||	LDNDW	*${INP}[-3],@DAT[11]:@DAT[10]
-+	XOR	@DAT[14],@X[14],@X[13]
-+||	XOR	@DAT[13],@X[13],@X[14]
-+||	LDNDW	*${INP}[-2],@DAT[13]:@DAT[12]
-+   [A0]	SUB	A0,$STEP,A0		; SUB	A0,128,A0
-+||	LDNDW	*${INP}[-1],@DAT[15]:@DAT[14]
-+
-+	XOR	@Y[0],@DAT[0],@DAT[0]	; xor 2nd block
-+||	XOR	@Y[1],@DAT[1],@DAT[1]
-+||	STNDW	@X[2]:@X[0],*${OUT}++[8]
-+	XOR	@Y[2],@DAT[2],@DAT[2]
-+||	XOR	@Y[3],@DAT[3],@DAT[3]
-+||	STNDW	@X[3]:@X[1],*${OUT}[-7]
-+	XOR	@Y[4],@DAT[4],@DAT[4]
-+|| [A0]	LDDW	*FP[-12],@X[2]:@X[0]	; re-load key material from stack
-+|| [A0]	LDDW	*SP[2],  @X[3]:@X[1]
-+	XOR	@Y[5],@DAT[5],@DAT[5]
-+||	STNDW	@X[6]:@X[4],*${OUT}[-6]
-+	XOR	@Y[6],@DAT[6],@DAT[6]
-+||	XOR	@Y[7],@DAT[7],@DAT[7]
-+||	STNDW	@X[7]:@X[5],*${OUT}[-5]
-+	XOR	@Y[8],@DAT[8],@DAT[8]
-+|| [A0]	LDDW	*FP[-10],@X[6]:@X[4]
-+|| [A0]	LDDW	*SP[4],  @X[7]:@X[5]
-+	XOR	@Y[9],@DAT[9],@DAT[9]
-+||	STNDW	@X[10]:@X[8],*${OUT}[-4]
-+	XOR	@Y[10],@DAT[10],@DAT[10]
-+||	XOR	@Y[11],@DAT[11],@DAT[11]
-+||	STNDW	@X[11]:@X[9],*${OUT}[-3]
-+	XOR	@Y[12],@DAT[12],@DAT[12]
-+|| [A0]	LDDW	*FP[-8], @X[10]:@X[8]
-+|| [A0]	LDDW	*SP[6],  @X[11]:@X[9]
-+	XOR	@Y[13],@DAT[13],@DAT[13]
-+||	STNDW	@X[14]:@X[12],*${OUT}[-2]
-+	XOR	@Y[14],@DAT[14],@DAT[14]
-+||	XOR	@Y[15],@DAT[15],@DAT[15]
-+||	STNDW	@X[15]:@X[13],*${OUT}[-1]
-+
-+   [A0]	MV	@K2x[12],@X[12]
-+|| [A0]	MV	@K2x[13],@X[13]
-+|| [A0]	LDW	*FP[-6*2], @X[14]
-+|| [A0]	LDW	*SP[8*2],  @X[15]
-+
-+   [A0]	DMV	@X[2],@X[0],@Y[2]:@Y[0]	; duplicate key material
-+||	STNDW	@DAT[1]:@DAT[0],*${OUT}++[8]
-+   [A0]	DMV	@X[3],@X[1],@Y[3]:@Y[1]
-+||	STNDW	@DAT[3]:@DAT[2],*${OUT}[-7]
-+   [A0]	DMV	@X[6],@X[4],@Y[6]:@Y[4]
-+||	STNDW	@DAT[5]:@DAT[4],*${OUT}[-6]
-+||	CMPLTU	A0,$STEP,A1		; is remaining length < 2*blocks?
-+||[!A0]	BNOP	epilogue?
-+   [A0]	DMV	@X[7],@X[5],@Y[7]:@Y[5]
-+||	STNDW	@DAT[7]:@DAT[6],*${OUT}[-5]
-+||[!A1]	BNOP	outer2x?
-+   [A0]	DMV	@X[10],@X[8],@Y[10]:@Y[8]
-+||	STNDW	@DAT[9]:@DAT[8],*${OUT}[-4]
-+   [A0]	DMV	@X[11],@X[9],@Y[11]:@Y[9]
-+||	STNDW	@DAT[11]:@DAT[10],*${OUT}[-3]
-+   [A0]	DMV	@X[14],@X[12],@Y[14]:@Y[12]
-+||	STNDW	@DAT[13]:@DAT[12],*${OUT}[-2]
-+   [A0]	DMV	@X[15],@X[13],@Y[15]:@Y[13]
-+||	STNDW	@DAT[15]:@DAT[14],*${OUT}[-1]
-+;;===== branch to epilogue? is taken here
-+   [A1]	MVK	64,$STEP
-+|| [A0]	MVK	10,B0			; inner loop counter
-+;;===== branch to outer2x? is taken here
-+___
-+{
-+my ($a0,$a1,$a2,$a3) = (0..3);
-+my ($b0,$b1,$b2,$b3) = (4..7);
-+my ($c0,$c1,$c2,$c3) = (8..11);
-+my ($d0,$d1,$d2,$d3) = (12..15);
-+
-+$code.=<<___;
-+top1x?:
-+	ADD	@X[$b1],@X[$a1],@X[$a1]
-+||	ADD	@X[$b2],@X[$a2],@X[$a2]
-+	ADD	@X[$b0],@X[$a0],@X[$a0]
-+||	ADD	@X[$b3],@X[$a3],@X[$a3]
-+||	XOR	@X[$a1],@X[$d1],@X[$d1]
-+||	XOR	@X[$a2],@X[$d2],@X[$d2]
-+	XOR	@X[$a0],@X[$d0],@X[$d0]
-+||	XOR	@X[$a3],@X[$d3],@X[$d3]
-+||	SWAP2	@X[$d1],@X[$d1]		; rotate by 16
-+||	SWAP2	@X[$d2],@X[$d2]
-+	SWAP2	@X[$d0],@X[$d0]
-+||	SWAP2	@X[$d3],@X[$d3]
-+
-+||	ADD	@X[$d1],@X[$c1],@X[$c1]
-+||	ADD	@X[$d2],@X[$c2],@X[$c2]
-+	ADD	@X[$d0],@X[$c0],@X[$c0]
-+||	ADD	@X[$d3],@X[$c3],@X[$c3]
-+||	XOR	@X[$c1],@X[$b1],@X[$b1]
-+||	XOR	@X[$c2],@X[$b2],@X[$b2]
-+	XOR	@X[$c0],@X[$b0],@X[$b0]
-+||	XOR	@X[$c3],@X[$b3],@X[$b3]
-+||	ROTL	@X[$b1],12,@X[$b1]
-+||	ROTL	@X[$b2],12,@X[$b2]
-+	ROTL	@X[$b0],12,@X[$b0]
-+||	ROTL	@X[$b3],12,@X[$b3]
-+
-+	ADD	@X[$b1],@X[$a1],@X[$a1]
-+||	ADD	@X[$b2],@X[$a2],@X[$a2]
-+	ADD	@X[$b0],@X[$a0],@X[$a0]
-+||	ADD	@X[$b3],@X[$a3],@X[$a3]
-+||	XOR	@X[$a1],@X[$d1],@X[$d1]
-+||	XOR	@X[$a2],@X[$d2],@X[$d2]
-+	XOR	@X[$a0],@X[$d0],@X[$d0]
-+||	XOR	@X[$a3],@X[$d3],@X[$d3]
-+||	ROTL	@X[$d1],8,@X[$d1]
-+||	ROTL	@X[$d2],8,@X[$d2]
-+	ROTL	@X[$d0],8,@X[$d0]
-+||	ROTL	@X[$d3],8,@X[$d3]
-+||	BNOP	middle1x?		; protect from interrupt
-+
-+	ADD	@X[$d1],@X[$c1],@X[$c1]
-+||	ADD	@X[$d2],@X[$c2],@X[$c2]
-+	ADD	@X[$d0],@X[$c0],@X[$c0]
-+||	ADD	@X[$d3],@X[$c3],@X[$c3]
-+||	XOR	@X[$c1],@X[$b1],@X[$b1]
-+||	XOR	@X[$c2],@X[$b2],@X[$b2]
-+||	ROTL	@X[$d1],0,@X[$d2]	; moved to avoid cross-path stall
-+||	ROTL	@X[$d2],0,@X[$d3]
-+	XOR	@X[$c0],@X[$b0],@X[$b0]
-+||	XOR	@X[$c3],@X[$b3],@X[$b3]
-+||	ROTL	@X[$d0],0,@X[$d1]
-+||	ROTL	@X[$d3],0,@X[$d0]
-+	ROTL	@X[$b1],7,@X[$b0]	; avoided cross-path stall
-+||	ROTL	@X[$b2],7,@X[$b1]
-+	ROTL	@X[$b0],7,@X[$b3]
-+||	ROTL	@X[$b3],7,@X[$b2]
-+middle1x?:
-+
-+	ADD	@X[$b0],@X[$a0],@X[$a0]
-+||	ADD	@X[$b1],@X[$a1],@X[$a1]
-+	ADD	@X[$b2],@X[$a2],@X[$a2]
-+||	ADD	@X[$b3],@X[$a3],@X[$a3]
-+||	XOR	@X[$a0],@X[$d0],@X[$d0]
-+||	XOR	@X[$a1],@X[$d1],@X[$d1]
-+	XOR	@X[$a2],@X[$d2],@X[$d2]
-+||	XOR	@X[$a3],@X[$d3],@X[$d3]
-+||	SWAP2	@X[$d0],@X[$d0]		; rotate by 16
-+||	SWAP2	@X[$d1],@X[$d1]
-+	SWAP2	@X[$d2],@X[$d2]
-+||	SWAP2	@X[$d3],@X[$d3]
-+
-+||	ADD	@X[$d0],@X[$c2],@X[$c2]
-+||	ADD	@X[$d1],@X[$c3],@X[$c3]
-+	ADD	@X[$d2],@X[$c0],@X[$c0]
-+||	ADD	@X[$d3],@X[$c1],@X[$c1]
-+||	XOR	@X[$c2],@X[$b0],@X[$b0]
-+||	XOR	@X[$c3],@X[$b1],@X[$b1]
-+	XOR	@X[$c0],@X[$b2],@X[$b2]
-+||	XOR	@X[$c1],@X[$b3],@X[$b3]
-+||	ROTL	@X[$b0],12,@X[$b0]
-+||	ROTL	@X[$b1],12,@X[$b1]
-+	ROTL	@X[$b2],12,@X[$b2]
-+||	ROTL	@X[$b3],12,@X[$b3]
-+
-+	ADD	@X[$b0],@X[$a0],@X[$a0]
-+||	ADD	@X[$b1],@X[$a1],@X[$a1]
-+|| [B0]	SUB	B0,1,B0			; decrement inner loop counter
-+	ADD	@X[$b2],@X[$a2],@X[$a2]
-+||	ADD	@X[$b3],@X[$a3],@X[$a3]
-+||	XOR	@X[$a0],@X[$d0],@X[$d0]
-+||	XOR	@X[$a1],@X[$d1],@X[$d1]
-+	XOR	@X[$a2],@X[$d2],@X[$d2]
-+||	XOR	@X[$a3],@X[$d3],@X[$d3]
-+||	ROTL	@X[$d0],8,@X[$d0]
-+||	ROTL	@X[$d1],8,@X[$d1]
-+	ROTL	@X[$d2],8,@X[$d2]
-+||	ROTL	@X[$d3],8,@X[$d3]
-+|| [B0]	BNOP	top1x?			; even protects from interrupt
-+
-+	ADD	@X[$d0],@X[$c2],@X[$c2]
-+||	ADD	@X[$d1],@X[$c3],@X[$c3]
-+	ADD	@X[$d2],@X[$c0],@X[$c0]
-+||	ADD	@X[$d3],@X[$c1],@X[$c1]
-+||	XOR	@X[$c2],@X[$b0],@X[$b0]
-+||	XOR	@X[$c3],@X[$b1],@X[$b1]
-+||	ROTL	@X[$d0],0,@X[$d3]	; moved to avoid cross-path stall
-+||	ROTL	@X[$d1],0,@X[$d0]
-+	XOR	@X[$c0],@X[$b2],@X[$b2]
-+||	XOR	@X[$c1],@X[$b3],@X[$b3]
-+||	ROTL	@X[$d2],0,@X[$d1]
-+||	ROTL	@X[$d3],0,@X[$d2]
-+	ROTL	@X[$b0],7,@X[$b1]	; avoided cross-path stall
-+||	ROTL	@X[$b1],7,@X[$b2]
-+	ROTL	@X[$b2],7,@X[$b3]
-+||	ROTL	@X[$b3],7,@X[$b0]
-+||[!B0]	CMPLTU	A0,$STEP,A1		; less than 64 bytes left?
-+bottom1x?:
-+___
-+}
-+
-+$code.=<<___;
-+	ADD	@Y[0],@X[0],@X[0]	; accumulate key material
-+||	ADD	@Y[1],@X[1],@X[1]
-+||	ADD	@Y[2],@X[2],@X[2]
-+||	ADD	@Y[3],@X[3],@X[3]
-+||[!A1]	LDNDW	*${INP}++[8],@DAT[1]:@DAT[0]
-+|| [A1]	BNOP	tail?
-+	ADD	@Y[4],@X[4],@X[4]
-+||	ADD	@Y[5],@X[5],@X[5]
-+||	ADD	@Y[6],@X[6],@X[6]
-+||	ADD	@Y[7],@X[7],@X[7]
-+||[!A1]	LDNDW	*${INP}[-7],@DAT[3]:@DAT[2]
-+	ADD	@Y[8],@X[8],@X[8]
-+||	ADD	@Y[9],@X[9],@X[9]
-+||	ADD	@Y[10],@X[10],@X[10]
-+||	ADD	@Y[11],@X[11],@X[11]
-+||[!A1]	LDNDW	*${INP}[-6],@DAT[5]:@DAT[4]
-+	ADD	@Y[12],@X[12],@X[12]
-+||	ADD	@Y[13],@X[13],@X[13]
-+||	ADD	@Y[14],@X[14],@X[14]
-+||	ADD	@Y[15],@X[15],@X[15]
-+||[!A1]	LDNDW	*${INP}[-5],@DAT[7]:@DAT[6]
-+  [!A1]	LDNDW	*${INP}[-4],@DAT[9]:@DAT[8]
-+  [!A1]	LDNDW	*${INP}[-3],@DAT[11]:@DAT[10]
-+	LDNDW	*${INP}[-2],@DAT[13]:@DAT[12]
-+	LDNDW	*${INP}[-1],@DAT[15]:@DAT[14]
-+
-+	.if	.BIG_ENDIAN
-+	SWAP2	@X[0],@X[0]
-+||	SWAP2	@X[1],@X[1]
-+||	SWAP2	@X[2],@X[2]
-+||	SWAP2	@X[3],@X[3]
-+	SWAP2	@X[4],@X[4]
-+||	SWAP2	@X[5],@X[5]
-+||	SWAP2	@X[6],@X[6]
-+||	SWAP2	@X[7],@X[7]
-+	SWAP2	@X[8],@X[8]
-+||	SWAP2	@X[9],@X[9]
-+||	SWAP4	@X[0],@X[1]
-+||	SWAP4	@X[1],@X[0]
-+	SWAP2	@X[10],@X[10]
-+||	SWAP2	@X[11],@X[11]
-+||	SWAP4	@X[2],@X[3]
-+||	SWAP4	@X[3],@X[2]
-+	SWAP2	@X[12],@X[12]
-+||	SWAP2	@X[13],@X[13]
-+||	SWAP4	@X[4],@X[5]
-+||	SWAP4	@X[5],@X[4]
-+	SWAP2	@X[14],@X[14]
-+||	SWAP2	@X[15],@X[15]
-+||	SWAP4	@X[6],@X[7]
-+||	SWAP4	@X[7],@X[6]
-+	SWAP4	@X[8],@X[9]
-+||	SWAP4	@X[9],@X[8]
-+	SWAP4	@X[10],@X[11]
-+||	SWAP4	@X[11],@X[10]
-+	SWAP4	@X[12],@X[13]
-+||	SWAP4	@X[13],@X[12]
-+	SWAP4	@X[14],@X[15]
-+||	SWAP4	@X[15],@X[14]
-+	.else
-+	NOP	1
-+	.endif
-+
-+	XOR	@X[0],@DAT[0],@DAT[0]	; xor with input
-+||	XOR	@X[1],@DAT[1],@DAT[1]
-+||	XOR	@X[2],@DAT[2],@DAT[2]
-+||	XOR	@X[3],@DAT[3],@DAT[3]
-+|| [A0]	SUB	A0,$STEP,A0		; SUB	A0,64,A0
-+	XOR	@X[4],@DAT[4],@DAT[4]
-+||	XOR	@X[5],@DAT[5],@DAT[5]
-+||	XOR	@X[6],@DAT[6],@DAT[6]
-+||	XOR	@X[7],@DAT[7],@DAT[7]
-+||	STNDW	@DAT[1]:@DAT[0],*${OUT}++[8]
-+	XOR	@X[8],@DAT[8],@DAT[8]
-+||	XOR	@X[9],@DAT[9],@DAT[9]
-+||	XOR	@X[10],@DAT[10],@DAT[10]
-+||	XOR	@X[11],@DAT[11],@DAT[11]
-+||	STNDW	@DAT[3]:@DAT[2],*${OUT}[-7]
-+	XOR	@X[12],@DAT[12],@DAT[12]
-+||	XOR	@X[13],@DAT[13],@DAT[13]
-+||	XOR	@X[14],@DAT[14],@DAT[14]
-+||	XOR	@X[15],@DAT[15],@DAT[15]
-+||	STNDW	@DAT[5]:@DAT[4],*${OUT}[-6]
-+|| [A0]	BNOP	top1x?
-+   [A0]	DMV	@Y[2],@Y[0],@X[2]:@X[0]	; duplicate key material
-+|| [A0]	DMV	@Y[3],@Y[1],@X[3]:@X[1]
-+||	STNDW	@DAT[7]:@DAT[6],*${OUT}[-5]
-+   [A0]	DMV	@Y[6],@Y[4],@X[6]:@X[4]
-+|| [A0]	DMV	@Y[7],@Y[5],@X[7]:@X[5]
-+||	STNDW	@DAT[9]:@DAT[8],*${OUT}[-4]
-+   [A0]	DMV	@Y[10],@Y[8],@X[10]:@X[8]
-+|| [A0]	DMV	@Y[11],@Y[9],@X[11]:@X[9]
-+|| [A0]	ADD	1,@Y[12],@Y[12]		; increment counter
-+||	STNDW	@DAT[11]:@DAT[10],*${OUT}[-3]
-+   [A0]	DMV	@Y[14],@Y[12],@X[14]:@X[12]
-+|| [A0]	DMV	@Y[15],@Y[13],@X[15]:@X[13]
-+||	STNDW	@DAT[13]:@DAT[12],*${OUT}[-2]
-+   [A0]	MVK	10,B0			; inner loop counter
-+||	STNDW	@DAT[15]:@DAT[14],*${OUT}[-1]
-+;;===== branch to top1x? is taken here
-+
-+epilogue?:
-+	LDDW	*FP[-4],A11:A10		; ABI says so
-+	LDDW	*FP[-3],A13:A12
-+||	LDDW	*SP[3+8],B11:B10
-+	LDDW	*SP[4+8],B13:B12
-+||	BNOP	RA
-+	LDW	*++SP(40+64),FP		; restore frame pointer
-+	NOP	4
-+
-+tail?:
-+	LDBU	*${INP}++[1],B24	; load byte by byte
-+||	SUB	A0,1,A0
-+||	SUB	A0,1,B1
-+  [!B1]	BNOP	epilogue?		; interrupts are disabled for whole time
-+|| [A0] LDBU	*${INP}++[1],B24
-+|| [A0]	SUB	A0,1,A0
-+||	SUB	B1,1,B1
-+  [!B1]	BNOP	epilogue?
-+|| [A0] LDBU	*${INP}++[1],B24
-+|| [A0]	SUB	A0,1,A0
-+||	SUB	B1,1,B1
-+  [!B1]	BNOP	epilogue?
-+||	ROTL	@X[0],0,A24
-+|| [A0] LDBU	*${INP}++[1],B24
-+|| [A0]	SUB	A0,1,A0
-+||	SUB	B1,1,B1
-+  [!B1]	BNOP	epilogue?
-+||	ROTL	@X[0],24,A24
-+|| [A0] LDBU	*${INP}++[1],A24
-+|| [A0]	SUB	A0,1,A0
-+||	SUB	B1,1,B1
-+  [!B1]	BNOP	epilogue?
-+||	ROTL	@X[0],16,A24
-+|| [A0] LDBU	*${INP}++[1],A24
-+|| [A0]	SUB	A0,1,A0
-+||	SUB	B1,1,B1
-+||	XOR	A24,B24,B25
-+	STB	B25,*${OUT}++[1]	; store byte by byte
-+||[!B1]	BNOP	epilogue?
-+||	ROTL	@X[0],8,A24
-+|| [A0] LDBU	*${INP}++[1],A24
-+|| [A0]	SUB	A0,1,A0
-+||	SUB	B1,1,B1
-+||	XOR	A24,B24,B25
-+	STB	B25,*${OUT}++[1]
-+___
-+sub TAIL_STEP {
-+my $Xi= shift;
-+my $T = ($Xi=~/^B/?"B24":"A24");	# match @X[i] to avoid cross path
-+my $D = $T; $D=~tr/AB/BA/;
-+my $O = $D; $O=~s/24/25/;
-+
-+$code.=<<___;
-+||[!B1]	BNOP	epilogue?
-+||	ROTL	$Xi,0,$T
-+|| [A0] LDBU	*${INP}++[1],$D
-+|| [A0]	SUB	A0,1,A0
-+||	SUB	B1,1,B1
-+||	XOR	A24,B24,$O
-+	STB	$O,*${OUT}++[1]
-+||[!B1]	BNOP	epilogue?
-+||	ROTL	$Xi,24,$T
-+|| [A0] LDBU	*${INP}++[1],$T
-+|| [A0]	SUB	A0,1,A0
-+||	SUB	B1,1,B1
-+||	XOR	A24,B24,$O
-+	STB	$O,*${OUT}++[1]
-+||[!B1]	BNOP	epilogue?
-+||	ROTL	$Xi,16,$T
-+|| [A0] LDBU	*${INP}++[1],$T
-+|| [A0]	SUB	A0,1,A0
-+||	SUB	B1,1,B1
-+||	XOR	A24,B24,$O
-+	STB	$O,*${OUT}++[1]
-+||[!B1]	BNOP	epilogue?
-+||	ROTL	$Xi,8,$T
-+|| [A0] LDBU	*${INP}++[1],$T
-+|| [A0]	SUB	A0,1,A0
-+||	SUB	B1,1,B1
-+||	XOR	A24,B24,$O
-+	STB	$O,*${OUT}++[1]
-+___
-+}
-+	foreach (1..14) { TAIL_STEP(@X[$_]); }
-+$code.=<<___;
-+||[!B1]	BNOP	epilogue?
-+||	ROTL	@X[15],0,B24
-+||	XOR	A24,B24,A25
-+	STB	A25,*${OUT}++[1]
-+||	ROTL	@X[15],24,B24
-+||	XOR	A24,B24,A25
-+	STB	A25,*${OUT}++[1]
-+||	ROTL	@X[15],16,B24
-+||	XOR	A24,B24,A25
-+	STB	A25,*${OUT}++[1]
-+||	XOR	A24,B24,A25
-+	STB	A25,*${OUT}++[1]
-+||	XOR	A24,B24,B25
-+	STB	B25,*${OUT}++[1]
-+	.endasmfunc
-+
-+	.sect	.const
-+	.cstring "ChaCha20 for C64x+, CRYPTOGAMS by "
-+	.align	4
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-ppc.pl
-new file mode 100755
-index 0000000..181decd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-ppc.pl
-@@ -0,0 +1,953 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# October 2015
-+# 
-+# ChaCha20 for PowerPC/AltiVec.
-+#
-+# Performance in cycles per byte out of large buffer.
-+#
-+#			IALU/gcc-4.x    3xAltiVec+1xIALU
-+#
-+# Freescale e300	13.6/+115%	-
-+# PPC74x0/G4e		6.81/+310%	4.66
-+# PPC970/G5		9.29/+160%	4.60
-+# POWER7		8.62/+61%	4.27
-+# POWER8		8.70/+51%	3.96
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /64/) {
-+	$SIZE_T	=8;
-+	$LRSAVE	=2*$SIZE_T;
-+	$STU	="stdu";
-+	$POP	="ld";
-+	$PUSH	="std";
-+	$UCMP	="cmpld";
-+} elsif ($flavour =~ /32/) {
-+	$SIZE_T	=4;
-+	$LRSAVE	=$SIZE_T;
-+	$STU	="stwu";
-+	$POP	="lwz";
-+	$PUSH	="stw";
-+	$UCMP	="cmplw";
-+} else { die "nonsense $flavour"; }
-+
-+$LITTLE_ENDIAN = ($flavour=~/le$/) ? 1 : 0;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-+
-+$LOCALS=6*$SIZE_T;
-+$FRAME=$LOCALS+64+18*$SIZE_T;	# 64 is for local variables
-+
-+sub AUTOLOAD()		# thunk [simplified] x86-style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
-+    $code .= "\t$opcode\t".join(',',@_)."\n";
-+}
-+
-+my $sp = "r1";
-+
-+my ($out,$inp,$len,$key,$ctr) = map("r$_",(3..7));
-+
-+my @x=map("r$_",(16..31));
-+my @d=map("r$_",(11,12,14,15));
-+my @t=map("r$_",(7..10));
-+
-+sub ROUND {
-+my ($a0,$b0,$c0,$d0)=@_;
-+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
-+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
-+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
-+
-+    (
-+	"&add		(@x[$a0],@x[$a0],@x[$b0])",
-+	 "&add		(@x[$a1],@x[$a1],@x[$b1])",
-+	  "&add		(@x[$a2],@x[$a2],@x[$b2])",
-+	   "&add	(@x[$a3],@x[$a3],@x[$b3])",
-+	"&xor		(@x[$d0],@x[$d0],@x[$a0])",
-+	 "&xor		(@x[$d1],@x[$d1],@x[$a1])",
-+	  "&xor		(@x[$d2],@x[$d2],@x[$a2])",
-+	   "&xor	(@x[$d3],@x[$d3],@x[$a3])",
-+	"&rotlwi	(@x[$d0],@x[$d0],16)",
-+	 "&rotlwi	(@x[$d1],@x[$d1],16)",
-+	  "&rotlwi	(@x[$d2],@x[$d2],16)",
-+	   "&rotlwi	(@x[$d3],@x[$d3],16)",
-+
-+	"&add		(@x[$c0],@x[$c0],@x[$d0])",
-+	 "&add		(@x[$c1],@x[$c1],@x[$d1])",
-+	  "&add		(@x[$c2],@x[$c2],@x[$d2])",
-+	   "&add	(@x[$c3],@x[$c3],@x[$d3])",
-+	"&xor		(@x[$b0],@x[$b0],@x[$c0])",
-+	 "&xor		(@x[$b1],@x[$b1],@x[$c1])",
-+	  "&xor		(@x[$b2],@x[$b2],@x[$c2])",
-+	   "&xor	(@x[$b3],@x[$b3],@x[$c3])",
-+	"&rotlwi	(@x[$b0],@x[$b0],12)",
-+	 "&rotlwi	(@x[$b1],@x[$b1],12)",
-+	  "&rotlwi	(@x[$b2],@x[$b2],12)",
-+	   "&rotlwi	(@x[$b3],@x[$b3],12)",
-+
-+	"&add		(@x[$a0],@x[$a0],@x[$b0])",
-+	 "&add		(@x[$a1],@x[$a1],@x[$b1])",
-+	  "&add		(@x[$a2],@x[$a2],@x[$b2])",
-+	   "&add	(@x[$a3],@x[$a3],@x[$b3])",
-+	"&xor		(@x[$d0],@x[$d0],@x[$a0])",
-+	 "&xor		(@x[$d1],@x[$d1],@x[$a1])",
-+	  "&xor		(@x[$d2],@x[$d2],@x[$a2])",
-+	   "&xor	(@x[$d3],@x[$d3],@x[$a3])",
-+	"&rotlwi	(@x[$d0],@x[$d0],8)",
-+	 "&rotlwi	(@x[$d1],@x[$d1],8)",
-+	  "&rotlwi	(@x[$d2],@x[$d2],8)",
-+	   "&rotlwi	(@x[$d3],@x[$d3],8)",
-+
-+	"&add		(@x[$c0],@x[$c0],@x[$d0])",
-+	 "&add		(@x[$c1],@x[$c1],@x[$d1])",
-+	  "&add		(@x[$c2],@x[$c2],@x[$d2])",
-+	   "&add	(@x[$c3],@x[$c3],@x[$d3])",
-+	"&xor		(@x[$b0],@x[$b0],@x[$c0])",
-+	 "&xor		(@x[$b1],@x[$b1],@x[$c1])",
-+	  "&xor		(@x[$b2],@x[$b2],@x[$c2])",
-+	   "&xor	(@x[$b3],@x[$b3],@x[$c3])",
-+	"&rotlwi	(@x[$b0],@x[$b0],7)",
-+	 "&rotlwi	(@x[$b1],@x[$b1],7)",
-+	  "&rotlwi	(@x[$b2],@x[$b2],7)",
-+	   "&rotlwi	(@x[$b3],@x[$b3],7)"
-+    );
-+}
-+
-+$code.=<<___;
-+.machine	"any"
-+.text
-+
-+.globl	.ChaCha20_ctr32_int
-+.align	5
-+.ChaCha20_ctr32_int:
-+__ChaCha20_ctr32_int:
-+	${UCMP}i $len,0
-+	beqlr-
-+
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+
-+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
-+	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
-+
-+	lwz	@d[0],0($ctr)			# load counter
-+	lwz	@d[1],4($ctr)
-+	lwz	@d[2],8($ctr)
-+	lwz	@d[3],12($ctr)
-+
-+	bl	__ChaCha20_1x
-+
-+	$POP	r0,`$FRAME+$LRSAVE`($sp)
-+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
-+	mtlr	r0
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,18,5,0
-+	.long	0
-+.size	.ChaCha20_ctr32_int,.-.ChaCha20_ctr32_int
-+
-+.align	5
-+__ChaCha20_1x:
-+Loop_outer:
-+	lis	@x[0],0x6170			# synthesize sigma
-+	lis	@x[1],0x3320
-+	lis	@x[2],0x7962
-+	lis	@x[3],0x6b20
-+	ori	@x[0],@x[0],0x7865
-+	ori	@x[1],@x[1],0x646e
-+	ori	@x[2],@x[2],0x2d32
-+	ori	@x[3],@x[3],0x6574
-+
-+	li	r0,10				# inner loop counter
-+	lwz	@x[4],0($key)			# load key
-+	lwz	@x[5],4($key)
-+	lwz	@x[6],8($key)
-+	lwz	@x[7],12($key)
-+	lwz	@x[8],16($key)
-+	mr	@x[12],@d[0]			# copy counter
-+	lwz	@x[9],20($key)
-+	mr	@x[13],@d[1]
-+	lwz	@x[10],24($key)
-+	mr	@x[14],@d[2]
-+	lwz	@x[11],28($key)
-+	mr	@x[15],@d[3]
-+
-+	mr	@t[0],@x[4]
-+	mr	@t[1],@x[5]
-+	mr	@t[2],@x[6]
-+	mr	@t[3],@x[7]
-+
-+	mtctr	r0
-+Loop:
-+___
-+	foreach (&ROUND(0, 4, 8,12)) { eval; }
-+	foreach (&ROUND(0, 5,10,15)) { eval; }
-+$code.=<<___;
-+	bdnz	Loop
-+
-+	subic	$len,$len,64			# $len-=64
-+	addi	@x[0],@x[0],0x7865		# accumulate key block
-+	addi	@x[1],@x[1],0x646e
-+	addi	@x[2],@x[2],0x2d32
-+	addi	@x[3],@x[3],0x6574
-+	addis	@x[0],@x[0],0x6170
-+	addis	@x[1],@x[1],0x3320
-+	addis	@x[2],@x[2],0x7962
-+	addis	@x[3],@x[3],0x6b20
-+
-+	subfe.	r0,r0,r0			# borrow?-1:0
-+	add	@x[4],@x[4],@t[0]
-+	lwz	@t[0],16($key)
-+	add	@x[5],@x[5],@t[1]
-+	lwz	@t[1],20($key)
-+	add	@x[6],@x[6],@t[2]
-+	lwz	@t[2],24($key)
-+	add	@x[7],@x[7],@t[3]
-+	lwz	@t[3],28($key)
-+	add	@x[8],@x[8],@t[0]
-+	add	@x[9],@x[9],@t[1]
-+	add	@x[10],@x[10],@t[2]
-+	add	@x[11],@x[11],@t[3]
-+
-+	add	@x[12],@x[12],@d[0]
-+	add	@x[13],@x[13],@d[1]
-+	add	@x[14],@x[14],@d[2]
-+	add	@x[15],@x[15],@d[3]
-+	addi	@d[0],@d[0],1			# increment counter
-+___
-+if (!$LITTLE_ENDIAN) { for($i=0;$i<16;$i++) {	# flip byte order
-+$code.=<<___;
-+	mr	@t[$i&3],@x[$i]
-+	rotlwi	@x[$i],@x[$i],8
-+	rlwimi	@x[$i],@t[$i&3],24,0,7
-+	rlwimi	@x[$i],@t[$i&3],24,16,23
-+___
-+} }
-+$code.=<<___;
-+	bne	Ltail				# $len-=64 borrowed
-+
-+	lwz	@t[0],0($inp)			# load input, aligned or not
-+	lwz	@t[1],4($inp)
-+	${UCMP}i $len,0				# done already?
-+	lwz	@t[2],8($inp)
-+	lwz	@t[3],12($inp)
-+	xor	@x[0],@x[0],@t[0]		# xor with input
-+	lwz	@t[0],16($inp)
-+	xor	@x[1],@x[1],@t[1]
-+	lwz	@t[1],20($inp)
-+	xor	@x[2],@x[2],@t[2]
-+	lwz	@t[2],24($inp)
-+	xor	@x[3],@x[3],@t[3]
-+	lwz	@t[3],28($inp)
-+	xor	@x[4],@x[4],@t[0]
-+	lwz	@t[0],32($inp)
-+	xor	@x[5],@x[5],@t[1]
-+	lwz	@t[1],36($inp)
-+	xor	@x[6],@x[6],@t[2]
-+	lwz	@t[2],40($inp)
-+	xor	@x[7],@x[7],@t[3]
-+	lwz	@t[3],44($inp)
-+	xor	@x[8],@x[8],@t[0]
-+	lwz	@t[0],48($inp)
-+	xor	@x[9],@x[9],@t[1]
-+	lwz	@t[1],52($inp)
-+	xor	@x[10],@x[10],@t[2]
-+	lwz	@t[2],56($inp)
-+	xor	@x[11],@x[11],@t[3]
-+	lwz	@t[3],60($inp)
-+	xor	@x[12],@x[12],@t[0]
-+	stw	@x[0],0($out)			# store output, aligned or not
-+	xor	@x[13],@x[13],@t[1]
-+	stw	@x[1],4($out)
-+	xor	@x[14],@x[14],@t[2]
-+	stw	@x[2],8($out)
-+	xor	@x[15],@x[15],@t[3]
-+	stw	@x[3],12($out)
-+	stw	@x[4],16($out)
-+	stw	@x[5],20($out)
-+	stw	@x[6],24($out)
-+	stw	@x[7],28($out)
-+	stw	@x[8],32($out)
-+	stw	@x[9],36($out)
-+	stw	@x[10],40($out)
-+	stw	@x[11],44($out)
-+	stw	@x[12],48($out)
-+	stw	@x[13],52($out)
-+	stw	@x[14],56($out)
-+	addi	$inp,$inp,64
-+	stw	@x[15],60($out)
-+	addi	$out,$out,64
-+
-+	bne	Loop_outer
-+
-+	blr
-+
-+.align	4
-+Ltail:
-+	addi	$len,$len,64			# restore tail length
-+	subi	$inp,$inp,1			# prepare for *++ptr
-+	subi	$out,$out,1
-+	addi	@t[0],$sp,$LOCALS-1
-+	mtctr	$len
-+
-+	stw	@x[0],`$LOCALS+0`($sp)		# save whole block to stack
-+	stw	@x[1],`$LOCALS+4`($sp)
-+	stw	@x[2],`$LOCALS+8`($sp)
-+	stw	@x[3],`$LOCALS+12`($sp)
-+	stw	@x[4],`$LOCALS+16`($sp)
-+	stw	@x[5],`$LOCALS+20`($sp)
-+	stw	@x[6],`$LOCALS+24`($sp)
-+	stw	@x[7],`$LOCALS+28`($sp)
-+	stw	@x[8],`$LOCALS+32`($sp)
-+	stw	@x[9],`$LOCALS+36`($sp)
-+	stw	@x[10],`$LOCALS+40`($sp)
-+	stw	@x[11],`$LOCALS+44`($sp)
-+	stw	@x[12],`$LOCALS+48`($sp)
-+	stw	@x[13],`$LOCALS+52`($sp)
-+	stw	@x[14],`$LOCALS+56`($sp)
-+	stw	@x[15],`$LOCALS+60`($sp)
-+
-+Loop_tail:					# byte-by-byte loop
-+	lbzu	@d[0],1($inp)
-+	lbzu	@x[0],1(@t[0])
-+	xor	@d[1],@d[0],@x[0]
-+	stbu	@d[1],1($out)
-+	bdnz	Loop_tail
-+
-+	stw	$sp,`$LOCALS+0`($sp)		# wipe block on stack
-+	stw	$sp,`$LOCALS+4`($sp)
-+	stw	$sp,`$LOCALS+8`($sp)
-+	stw	$sp,`$LOCALS+12`($sp)
-+	stw	$sp,`$LOCALS+16`($sp)
-+	stw	$sp,`$LOCALS+20`($sp)
-+	stw	$sp,`$LOCALS+24`($sp)
-+	stw	$sp,`$LOCALS+28`($sp)
-+	stw	$sp,`$LOCALS+32`($sp)
-+	stw	$sp,`$LOCALS+36`($sp)
-+	stw	$sp,`$LOCALS+40`($sp)
-+	stw	$sp,`$LOCALS+44`($sp)
-+	stw	$sp,`$LOCALS+48`($sp)
-+	stw	$sp,`$LOCALS+52`($sp)
-+	stw	$sp,`$LOCALS+56`($sp)
-+	stw	$sp,`$LOCALS+60`($sp)
-+
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+___
-+
-+{{{
-+my ($A0,$B0,$C0,$D0,$A1,$B1,$C1,$D1,$A2,$B2,$C2,$D2,$T0,$T1,$T2) =
-+    map("v$_",(0..14));
-+my (@K)=map("v$_",(15..20));
-+my ($FOUR,$sixteen,$twenty4,$twenty,$twelve,$twenty5,$seven) =
-+    map("v$_",(21..27));
-+my ($inpperm,$outperm,$outmask) = map("v$_",(28..30));
-+my @D=("v31",$seven,$T0,$T1,$T2);
-+
-+my $FRAME=$LOCALS+64+13*16+18*$SIZE_T;	# 13*16 is for v20-v31 offload
-+
-+sub VMXROUND {
-+my $odd = pop;
-+my ($a,$b,$c,$d,$t)=@_;
-+
-+	(
-+	"&vadduwm	('$a','$a','$b')",
-+	"&vxor		('$d','$d','$a')",
-+	"&vperm		('$d','$d','$d','$sixteen')",
-+
-+	"&vadduwm	('$c','$c','$d')",
-+	"&vxor		('$t','$b','$c')",
-+	"&vsrw		('$b','$t','$twenty')",
-+	"&vslw		('$t','$t','$twelve')",
-+	"&vor		('$b','$b','$t')",
-+
-+	"&vadduwm	('$a','$a','$b')",
-+	"&vxor		('$d','$d','$a')",
-+	"&vperm		('$d','$d','$d','$twenty4')",
-+
-+	"&vadduwm	('$c','$c','$d')",
-+	"&vxor		('$t','$b','$c')",
-+	"&vsrw		('$b','$t','$twenty5')",
-+	"&vslw		('$t','$t','$seven')",
-+	"&vor		('$b','$b','$t')",
-+
-+	"&vsldoi	('$c','$c','$c',8)",
-+	"&vsldoi	('$b','$b','$b',$odd?4:12)",
-+	"&vsldoi	('$d','$d','$d',$odd?12:4)"
-+	);
-+}
-+
-+$code.=<<___;
-+
-+.globl	.ChaCha20_ctr32_vmx
-+.align	5
-+.ChaCha20_ctr32_vmx:
-+	${UCMP}i $len,256
-+	blt	__ChaCha20_ctr32_int
-+
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+	li	r10,`15+$LOCALS+64`
-+	li	r11,`31+$LOCALS+64`
-+	mfspr	r12,256
-+	stvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	stvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	stvx	v30,r10,$sp
-+	stvx	v31,r11,$sp
-+	stw	r12,`$FRAME-$SIZE_T*18-4`($sp)	# save vrsave
-+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
-+	li	r12,-1
-+	$PUSH	r0, `$FRAME+$LRSAVE`($sp)
-+	mtspr	256,r12				# preserve all AltiVec registers
-+
-+	bl	Lconsts				# returns pointer Lsigma in r12
-+	li	@x[0],16
-+	li	@x[1],32
-+	li	@x[2],48
-+	li	@x[3],64
-+	li	@x[4],31			# 31 is not a typo
-+	li	@x[5],15			# nor is 15
-+
-+	lvx	@K[1],0,$key			# load key
-+	?lvsr	$T0,0,$key			# prepare unaligned load
-+	lvx	@K[2],@x[0],$key
-+	lvx	@D[0],@x[4],$key
-+
-+	lvx	@K[3],0,$ctr			# load counter
-+	?lvsr	$T1,0,$ctr			# prepare unaligned load
-+	lvx	@D[1],@x[5],$ctr
-+
-+	lvx	@K[0],0,r12			# load constants
-+	lvx	@K[5],@x[0],r12			# one
-+	lvx	$FOUR,@x[1],r12
-+	lvx	$sixteen,@x[2],r12
-+	lvx	$twenty4,@x[3],r12
-+
-+	?vperm	@K[1],@K[2],@K[1],$T0		# align key
-+	?vperm	@K[2],@D[0],@K[2],$T0
-+	?vperm	@K[3],@D[1],@K[3],$T1		# align counter
-+
-+	lwz	@d[0],0($ctr)			# load counter to GPR
-+	lwz	@d[1],4($ctr)
-+	vadduwm	@K[3],@K[3],@K[5]		# adjust AltiVec counter
-+	lwz	@d[2],8($ctr)
-+	vadduwm	@K[4],@K[3],@K[5]
-+	lwz	@d[3],12($ctr)
-+	vadduwm	@K[5],@K[4],@K[5]
-+
-+	vspltisw $twenty,-12			# synthesize constants 
-+	vspltisw $twelve,12
-+	vspltisw $twenty5,-7
-+	#vspltisw $seven,7			# synthesized in the loop
-+
-+	vxor	$T0,$T0,$T0			# 0x00..00
-+	vspltisw $outmask,-1			# 0xff..ff
-+	?lvsr	$inpperm,0,$inp			# prepare for unaligned load
-+	?lvsl	$outperm,0,$out			# prepare for unaligned store
-+	?vperm	$outmask,$outmask,$T0,$outperm
-+
-+	be?lvsl	$T0,0,@x[0]			# 0x00..0f
-+	be?vspltisb $T1,3			# 0x03..03
-+	be?vxor	$T0,$T0,$T1			# swap bytes within words
-+	be?vxor	$outperm,$outperm,$T1
-+	be?vperm $inpperm,$inpperm,$inpperm,$T0
-+
-+	b	Loop_outer_vmx
-+
-+.align	4
-+Loop_outer_vmx:
-+	lis	@x[0],0x6170			# synthesize sigma
-+	lis	@x[1],0x3320
-+	 vmr	$A0,@K[0]
-+	lis	@x[2],0x7962
-+	lis	@x[3],0x6b20
-+	 vmr	$A1,@K[0]
-+	ori	@x[0],@x[0],0x7865
-+	ori	@x[1],@x[1],0x646e
-+	 vmr	$A2,@K[0]
-+	ori	@x[2],@x[2],0x2d32
-+	ori	@x[3],@x[3],0x6574
-+	 vmr	$B0,@K[1]
-+
-+	li	r0,10				# inner loop counter
-+	lwz	@x[4],0($key)			# load key to GPR
-+	 vmr	$B1,@K[1]
-+	lwz	@x[5],4($key)
-+	 vmr	$B2,@K[1]
-+	lwz	@x[6],8($key)
-+	 vmr	$C0,@K[2]
-+	lwz	@x[7],12($key)
-+	 vmr	$C1,@K[2]
-+	lwz	@x[8],16($key)
-+	 vmr	$C2,@K[2]
-+	mr	@x[12],@d[0]			# copy GPR counter
-+	lwz	@x[9],20($key)
-+	 vmr	$D0,@K[3]
-+	mr	@x[13],@d[1]
-+	lwz	@x[10],24($key)
-+	 vmr	$D1,@K[4]
-+	mr	@x[14],@d[2]
-+	lwz	@x[11],28($key)
-+	 vmr	$D2,@K[5]
-+	mr	@x[15],@d[3]
-+
-+	mr	@t[0],@x[4]
-+	mr	@t[1],@x[5]
-+	mr	@t[2],@x[6]
-+	mr	@t[3],@x[7]
-+	vspltisw $seven,7
-+
-+	mtctr	r0
-+	nop
-+Loop_vmx:
-+___
-+	my @thread0=&VMXROUND($A0,$B0,$C0,$D0,$T0,0);
-+	my @thread1=&VMXROUND($A1,$B1,$C1,$D1,$T1,0);
-+	my @thread2=&VMXROUND($A2,$B2,$C2,$D2,$T2,0);
-+	my @thread3=&ROUND(0,4,8,12);
-+
-+	foreach (@thread0) {
-+		eval;			eval(shift(@thread3));
-+		eval(shift(@thread1));	eval(shift(@thread3));
-+		eval(shift(@thread2));	eval(shift(@thread3));
-+	}
-+
-+	@thread0=&VMXROUND($A0,$B0,$C0,$D0,$T0,1);
-+	@thread1=&VMXROUND($A1,$B1,$C1,$D1,$T1,1);
-+	@thread2=&VMXROUND($A2,$B2,$C2,$D2,$T2,1);
-+	@thread3=&ROUND(0,5,10,15);
-+
-+	foreach (@thread0) {
-+		eval;			eval(shift(@thread3));
-+		eval(shift(@thread1));	eval(shift(@thread3));
-+		eval(shift(@thread2));	eval(shift(@thread3));
-+	}
-+$code.=<<___;
-+	bdnz	Loop_vmx
-+
-+	subi	$len,$len,256			# $len-=256
-+	addi	@x[0],@x[0],0x7865		# accumulate key block
-+	addi	@x[1],@x[1],0x646e
-+	addi	@x[2],@x[2],0x2d32
-+	addi	@x[3],@x[3],0x6574
-+	addis	@x[0],@x[0],0x6170
-+	addis	@x[1],@x[1],0x3320
-+	addis	@x[2],@x[2],0x7962
-+	addis	@x[3],@x[3],0x6b20
-+	add	@x[4],@x[4],@t[0]
-+	lwz	@t[0],16($key)
-+	add	@x[5],@x[5],@t[1]
-+	lwz	@t[1],20($key)
-+	add	@x[6],@x[6],@t[2]
-+	lwz	@t[2],24($key)
-+	add	@x[7],@x[7],@t[3]
-+	lwz	@t[3],28($key)
-+	add	@x[8],@x[8],@t[0]
-+	add	@x[9],@x[9],@t[1]
-+	add	@x[10],@x[10],@t[2]
-+	add	@x[11],@x[11],@t[3]
-+	add	@x[12],@x[12],@d[0]
-+	add	@x[13],@x[13],@d[1]
-+	add	@x[14],@x[14],@d[2]
-+	add	@x[15],@x[15],@d[3]
-+
-+	vadduwm	$A0,$A0,@K[0]			# accumulate key block
-+	vadduwm	$A1,$A1,@K[0]
-+	vadduwm	$A2,$A2,@K[0]
-+	vadduwm	$B0,$B0,@K[1]
-+	vadduwm	$B1,$B1,@K[1]
-+	vadduwm	$B2,$B2,@K[1]
-+	vadduwm	$C0,$C0,@K[2]
-+	vadduwm	$C1,$C1,@K[2]
-+	vadduwm	$C2,$C2,@K[2]
-+	vadduwm	$D0,$D0,@K[3]
-+	vadduwm	$D1,$D1,@K[4]
-+	vadduwm	$D2,$D2,@K[5]
-+
-+	addi	@d[0],@d[0],4			# increment counter
-+	vadduwm	@K[3],@K[3],$FOUR
-+	vadduwm	@K[4],@K[4],$FOUR
-+	vadduwm	@K[5],@K[5],$FOUR
-+
-+___
-+if (!$LITTLE_ENDIAN) { for($i=0;$i<16;$i++) {	# flip byte order
-+$code.=<<___;
-+	mr	@t[$i&3],@x[$i]
-+	rotlwi	@x[$i],@x[$i],8
-+	rlwimi	@x[$i],@t[$i&3],24,0,7
-+	rlwimi	@x[$i],@t[$i&3],24,16,23
-+___
-+} }
-+$code.=<<___;
-+	lwz	@t[0],0($inp)			# load input, aligned or not
-+	lwz	@t[1],4($inp)
-+	lwz	@t[2],8($inp)
-+	lwz	@t[3],12($inp)
-+	xor	@x[0],@x[0],@t[0]		# xor with input
-+	lwz	@t[0],16($inp)
-+	xor	@x[1],@x[1],@t[1]
-+	lwz	@t[1],20($inp)
-+	xor	@x[2],@x[2],@t[2]
-+	lwz	@t[2],24($inp)
-+	xor	@x[3],@x[3],@t[3]
-+	lwz	@t[3],28($inp)
-+	xor	@x[4],@x[4],@t[0]
-+	lwz	@t[0],32($inp)
-+	xor	@x[5],@x[5],@t[1]
-+	lwz	@t[1],36($inp)
-+	xor	@x[6],@x[6],@t[2]
-+	lwz	@t[2],40($inp)
-+	xor	@x[7],@x[7],@t[3]
-+	lwz	@t[3],44($inp)
-+	xor	@x[8],@x[8],@t[0]
-+	lwz	@t[0],48($inp)
-+	xor	@x[9],@x[9],@t[1]
-+	lwz	@t[1],52($inp)
-+	xor	@x[10],@x[10],@t[2]
-+	lwz	@t[2],56($inp)
-+	xor	@x[11],@x[11],@t[3]
-+	lwz	@t[3],60($inp)
-+	xor	@x[12],@x[12],@t[0]
-+	stw	@x[0],0($out)			# store output, aligned or not
-+	xor	@x[13],@x[13],@t[1]
-+	stw	@x[1],4($out)
-+	xor	@x[14],@x[14],@t[2]
-+	stw	@x[2],8($out)
-+	xor	@x[15],@x[15],@t[3]
-+	stw	@x[3],12($out)
-+	addi	$inp,$inp,64
-+	stw	@x[4],16($out)
-+	li	@t[0],16
-+	stw	@x[5],20($out)
-+	li	@t[1],32
-+	stw	@x[6],24($out)
-+	li	@t[2],48
-+	stw	@x[7],28($out)
-+	li	@t[3],64
-+	stw	@x[8],32($out)
-+	stw	@x[9],36($out)
-+	stw	@x[10],40($out)
-+	stw	@x[11],44($out)
-+	stw	@x[12],48($out)
-+	stw	@x[13],52($out)
-+	stw	@x[14],56($out)
-+	stw	@x[15],60($out)
-+	addi	$out,$out,64
-+
-+	lvx	@D[0],0,$inp			# load input
-+	lvx	@D[1],@t[0],$inp
-+	lvx	@D[2],@t[1],$inp
-+	lvx	@D[3],@t[2],$inp
-+	lvx	@D[4],@t[3],$inp
-+	addi	$inp,$inp,64
-+
-+	?vperm	@D[0],@D[1],@D[0],$inpperm	# align input
-+	?vperm	@D[1],@D[2],@D[1],$inpperm
-+	?vperm	@D[2],@D[3],@D[2],$inpperm
-+	?vperm	@D[3],@D[4],@D[3],$inpperm
-+	vxor	$A0,$A0,@D[0]			# xor with input
-+	vxor	$B0,$B0,@D[1]
-+	lvx	@D[1],@t[0],$inp		# keep loading input
-+	vxor	$C0,$C0,@D[2]
-+	lvx	@D[2],@t[1],$inp
-+	vxor	$D0,$D0,@D[3]
-+	lvx	@D[3],@t[2],$inp
-+	lvx	@D[0],@t[3],$inp
-+	addi	$inp,$inp,64
-+	li	@t[3],63			# 63 is not a typo
-+	vperm	$A0,$A0,$A0,$outperm		# pre-misalign output
-+	vperm	$B0,$B0,$B0,$outperm
-+	vperm	$C0,$C0,$C0,$outperm
-+	vperm	$D0,$D0,$D0,$outperm
-+
-+	?vperm	@D[4],@D[1],@D[4],$inpperm	# align input
-+	?vperm	@D[1],@D[2],@D[1],$inpperm
-+	?vperm	@D[2],@D[3],@D[2],$inpperm
-+	?vperm	@D[3],@D[0],@D[3],$inpperm
-+	vxor	$A1,$A1,@D[4]
-+	vxor	$B1,$B1,@D[1]
-+	lvx	@D[1],@t[0],$inp		# keep loading input
-+	vxor	$C1,$C1,@D[2]
-+	lvx	@D[2],@t[1],$inp
-+	vxor	$D1,$D1,@D[3]
-+	lvx	@D[3],@t[2],$inp
-+	lvx	@D[4],@t[3],$inp		# redundant in aligned case
-+	addi	$inp,$inp,64
-+	vperm	$A1,$A1,$A1,$outperm		# pre-misalign output
-+	vperm	$B1,$B1,$B1,$outperm
-+	vperm	$C1,$C1,$C1,$outperm
-+	vperm	$D1,$D1,$D1,$outperm
-+
-+	?vperm	@D[0],@D[1],@D[0],$inpperm	# align input
-+	?vperm	@D[1],@D[2],@D[1],$inpperm
-+	?vperm	@D[2],@D[3],@D[2],$inpperm
-+	?vperm	@D[3],@D[4],@D[3],$inpperm
-+	vxor	$A2,$A2,@D[0]
-+	vxor	$B2,$B2,@D[1]
-+	vxor	$C2,$C2,@D[2]
-+	vxor	$D2,$D2,@D[3]
-+	vperm	$A2,$A2,$A2,$outperm		# pre-misalign output
-+	vperm	$B2,$B2,$B2,$outperm
-+	vperm	$C2,$C2,$C2,$outperm
-+	vperm	$D2,$D2,$D2,$outperm
-+
-+	andi.	@x[1],$out,15			# is $out aligned?
-+	mr	@x[0],$out
-+
-+	vsel	@D[0],$A0,$B0,$outmask		# collect pre-misaligned output
-+	vsel	@D[1],$B0,$C0,$outmask
-+	vsel	@D[2],$C0,$D0,$outmask
-+	vsel	@D[3],$D0,$A1,$outmask
-+	vsel	$B0,$A1,$B1,$outmask
-+	vsel	$C0,$B1,$C1,$outmask
-+	vsel	$D0,$C1,$D1,$outmask
-+	vsel	$A1,$D1,$A2,$outmask
-+	vsel	$B1,$A2,$B2,$outmask
-+	vsel	$C1,$B2,$C2,$outmask
-+	vsel	$D1,$C2,$D2,$outmask
-+
-+	#stvx	$A0,0,$out			# take it easy on the edges
-+	stvx	@D[0],@t[0],$out		# store output
-+	stvx	@D[1],@t[1],$out
-+	stvx	@D[2],@t[2],$out
-+	addi	$out,$out,64
-+	stvx	@D[3],0,$out
-+	stvx	$B0,@t[0],$out
-+	stvx	$C0,@t[1],$out
-+	stvx	$D0,@t[2],$out
-+	addi	$out,$out,64
-+	stvx	$A1,0,$out
-+	stvx	$B1,@t[0],$out
-+	stvx	$C1,@t[1],$out
-+	stvx	$D1,@t[2],$out
-+	addi	$out,$out,64
-+
-+	beq	Laligned_vmx
-+
-+	sub	@x[2],$out,@x[1]		# in misaligned case edges
-+	li	@x[3],0				# are written byte-by-byte
-+Lunaligned_tail_vmx:
-+	stvebx	$D2,@x[3],@x[2]
-+	addi	@x[3],@x[3],1
-+	cmpw	@x[3],@x[1]
-+	bne	Lunaligned_tail_vmx
-+
-+	sub	@x[2],@x[0],@x[1]
-+Lunaligned_head_vmx:
-+	stvebx	$A0,@x[1],@x[2]
-+	cmpwi	@x[1],15
-+	addi	@x[1],@x[1],1
-+	bne	Lunaligned_head_vmx
-+
-+	${UCMP}i $len,255			# done with 256-byte blocks yet?
-+	bgt	Loop_outer_vmx
-+
-+	b	Ldone_vmx
-+
-+.align	4
-+Laligned_vmx:
-+	stvx	$A0,0,@x[0]			# head hexaword was not stored
-+
-+	${UCMP}i $len,255			# done with 256-byte blocks yet?
-+	bgt	Loop_outer_vmx
-+	nop
-+
-+Ldone_vmx:
-+	${UCMP}i $len,0				# done yet?
-+	bnel	__ChaCha20_1x
-+
-+	lwz	r12,`$FRAME-$SIZE_T*18-4`($sp)	# pull vrsave
-+	li	r10,`15+$LOCALS+64`
-+	li	r11,`31+$LOCALS+64`
-+	mtspr	256,r12				# restore vrsave
-+	lvx	v20,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v21,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v22,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v23,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v24,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v25,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v26,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v27,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v28,r10,$sp
-+	addi	r10,r10,32
-+	lvx	v29,r11,$sp
-+	addi	r11,r11,32
-+	lvx	v30,r10,$sp
-+	lvx	v31,r11,$sp
-+	$POP	r0, `$FRAME+$LRSAVE`($sp)
-+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
-+	mtlr	r0
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,0x04,1,0x80,18,5,0
-+	.long	0
-+.size	.ChaCha20_ctr32_vmx,.-.ChaCha20_ctr32_vmx
-+
-+.align	5
-+Lconsts:
-+	mflr	r0
-+	bcl	20,31,\$+4
-+	mflr	r12	#vvvvv "distance between . and _vpaes_consts
-+	addi	r12,r12,`64-8`
-+	mtlr	r0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+	.space	`64-9*4`
-+Lsigma:
-+	.long   0x61707865,0x3320646e,0x79622d32,0x6b206574
-+	.long	1,0,0,0
-+	.long	4,0,0,0
-+___
-+$code.=<<___ 	if ($LITTLE_ENDIAN);
-+	.long	0x0e0f0c0d,0x0a0b0809,0x06070405,0x02030001
-+	.long	0x0d0e0f0c,0x090a0b08,0x05060704,0x01020300
-+___
-+$code.=<<___ 	if (!$LITTLE_ENDIAN);	# flipped words
-+	.long	0x02030001,0x06070405,0x0a0b0809,0x0e0f0c0d
-+	.long	0x01020300,0x05060704,0x090a0b08,0x0d0e0f0c
-+___
-+$code.=<<___;
-+.asciz  "ChaCha20 for PowerPC/AltiVec, CRYPTOGAMS by "
-+.align	2
-+___
-+}}}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	# instructions prefixed with '?' are endian-specific and need
-+	# to be adjusted accordingly...
-+	if ($flavour !~ /le$/) {	# big-endian
-+	    s/be\?//		or
-+	    s/le\?/#le#/	or
-+	    s/\?lvsr/lvsl/	or
-+	    s/\?lvsl/lvsr/	or
-+	    s/\?(vperm\s+v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+)/$1$3$2$4/ or
-+	    s/(vsldoi\s+v[0-9]+,\s*)(v[0-9]+,)\s*(v[0-9]+,\s*)([0-9]+)/$1$3$2 16-$4/;
-+	} else {			# little-endian
-+	    s/le\?//		or
-+	    s/be\?/#be#/	or
-+	    s/\?([a-z]+)/$1/;
-+	}
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-s390x.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-s390x.pl
-new file mode 100755
-index 0000000..c315264
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-s390x.pl
-@@ -0,0 +1,326 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# December 2015
-+#
-+# ChaCha20 for s390x.
-+#
-+# 3 times faster than compiler-generated code.
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /3[12]/) {
-+	$SIZE_T=4;
-+	$g="";
-+} else {
-+	$SIZE_T=8;
-+	$g="g";
-+}
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+sub AUTOLOAD()		# thunk [simplified] x86-style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
-+    $code .= "\t$opcode\t".join(',',@_)."\n";
-+}
-+
-+my $sp="%r15";
-+
-+my $stdframe=16*$SIZE_T+4*8;
-+my $frame=$stdframe+4*20;
-+
-+my ($out,$inp,$len,$key,$counter)=map("%r$_",(2..6));
-+
-+my @x=map("%r$_",(0..7,"x","x","x","x",(10..13)));
-+my @t=map("%r$_",(8,9));
-+
-+sub ROUND {
-+my ($a0,$b0,$c0,$d0)=@_;
-+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
-+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
-+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
-+my ($xc,$xc_)=map("\"$_\"",@t);
-+my @x=map("\"$_\"",@x);
-+
-+	# Consider order in which variables are addressed by their
-+	# index:
-+	#
-+	#	a   b   c   d
-+	#
-+	#	0   4   8  12 < even round
-+	#	1   5   9  13
-+	#	2   6  10  14
-+	#	3   7  11  15
-+	#	0   5  10  15 < odd round
-+	#	1   6  11  12
-+	#	2   7   8  13
-+	#	3   4   9  14
-+	#
-+	# 'a', 'b' and 'd's are permanently allocated in registers,
-+	# @x[0..7,12..15], while 'c's are maintained in memory. If
-+	# you observe 'c' column, you'll notice that pair of 'c's is
-+	# invariant between rounds. This means that we have to reload
-+	# them once per round, in the middle. This is why you'll see
-+	# 'c' stores and loads in the middle, but none in the beginning
-+	# or end.
-+
-+	(
-+	"&alr	(@x[$a0],@x[$b0])",	# Q1
-+	 "&alr	(@x[$a1],@x[$b1])",	# Q2
-+	"&xr	(@x[$d0],@x[$a0])",
-+	 "&xr	(@x[$d1],@x[$a1])",
-+	"&rll	(@x[$d0],@x[$d0],16)",
-+	 "&rll	(@x[$d1],@x[$d1],16)",
-+
-+	"&alr	($xc,@x[$d0])",
-+	 "&alr	($xc_,@x[$d1])",
-+	"&xr	(@x[$b0],$xc)",
-+	 "&xr	(@x[$b1],$xc_)",
-+	"&rll	(@x[$b0],@x[$b0],12)",
-+	 "&rll	(@x[$b1],@x[$b1],12)",
-+
-+	"&alr	(@x[$a0],@x[$b0])",
-+	 "&alr	(@x[$a1],@x[$b1])",
-+	"&xr	(@x[$d0],@x[$a0])",
-+	 "&xr	(@x[$d1],@x[$a1])",
-+	"&rll	(@x[$d0],@x[$d0],8)",
-+	 "&rll	(@x[$d1],@x[$d1],8)",
-+
-+	"&alr	($xc,@x[$d0])",
-+	 "&alr	($xc_,@x[$d1])",
-+	"&xr	(@x[$b0],$xc)",
-+	 "&xr	(@x[$b1],$xc_)",
-+	"&rll	(@x[$b0],@x[$b0],7)",
-+	 "&rll	(@x[$b1],@x[$b1],7)",
-+
-+	"&stm	($xc,$xc_,'$stdframe+4*8+4*$c0($sp)')",	# reload pair of 'c's
-+	"&lm	($xc,$xc_,'$stdframe+4*8+4*$c2($sp)')",
-+
-+	"&alr	(@x[$a2],@x[$b2])",	# Q3
-+	 "&alr	(@x[$a3],@x[$b3])",	# Q4
-+	"&xr	(@x[$d2],@x[$a2])",
-+	 "&xr	(@x[$d3],@x[$a3])",
-+	"&rll	(@x[$d2],@x[$d2],16)",
-+	 "&rll	(@x[$d3],@x[$d3],16)",
-+
-+	"&alr	($xc,@x[$d2])",
-+	 "&alr	($xc_,@x[$d3])",
-+	"&xr	(@x[$b2],$xc)",
-+	 "&xr	(@x[$b3],$xc_)",
-+	"&rll	(@x[$b2],@x[$b2],12)",
-+	 "&rll	(@x[$b3],@x[$b3],12)",
-+
-+	"&alr	(@x[$a2],@x[$b2])",
-+	 "&alr	(@x[$a3],@x[$b3])",
-+	"&xr	(@x[$d2],@x[$a2])",
-+	 "&xr	(@x[$d3],@x[$a3])",
-+	"&rll	(@x[$d2],@x[$d2],8)",
-+	 "&rll	(@x[$d3],@x[$d3],8)",
-+
-+	"&alr	($xc,@x[$d2])",
-+	 "&alr	($xc_,@x[$d3])",
-+	"&xr	(@x[$b2],$xc)",
-+	 "&xr	(@x[$b3],$xc_)",
-+	"&rll	(@x[$b2],@x[$b2],7)",
-+	 "&rll	(@x[$b3],@x[$b3],7)"
-+	);
-+}
-+
-+$code.=<<___;
-+.text
-+
-+.globl	ChaCha20_ctr32
-+.type	ChaCha20_ctr32,\@function
-+.align	32
-+ChaCha20_ctr32:
-+	lt${g}r	$len,$len			# $len==0?
-+	bzr	%r14
-+	a${g}hi	$len,-64
-+	l${g}hi	%r1,-$frame
-+	stm${g}	%r6,%r15,`6*$SIZE_T`($sp)
-+	sl${g}r	$out,$inp			# difference
-+	la	$len,0($inp,$len)		# end of input minus 64
-+	larl	%r7,.Lsigma
-+	lgr	%r0,$sp
-+	la	$sp,0(%r1,$sp)
-+	st${g}	%r0,0($sp)
-+
-+	lmg	%r8,%r11,0($key)		# load key
-+	lmg	%r12,%r13,0($counter)		# load counter
-+	lmg	%r6,%r7,0(%r7)			# load sigma constant
-+
-+	la	%r14,0($inp)
-+	st${g}	$out,$frame+3*$SIZE_T($sp)
-+	st${g}	$len,$frame+4*$SIZE_T($sp)
-+	stmg	%r6,%r13,$stdframe($sp)		# copy key schedule to stack
-+	srlg	@x[12],%r12,32			# 32-bit counter value
-+	j	.Loop_outer
-+
-+.align	16
-+.Loop_outer:
-+	lm	@x[0],@x[7],$stdframe+4*0($sp)		# load x[0]-x[7]
-+	lm	@t[0],@t[1],$stdframe+4*10($sp)		# load x[10]-x[11]
-+	lm	@x[13],@x[15],$stdframe+4*13($sp)	# load x[13]-x[15]
-+	stm	@t[0],@t[1],$stdframe+4*8+4*10($sp)	# offload x[10]-x[11]
-+	lm	@t[0],@t[1],$stdframe+4*8($sp)		# load x[8]-x[9]
-+	st	@x[12],$stdframe+4*12($sp)		# save counter
-+	st${g}	%r14,$frame+2*$SIZE_T($sp)		# save input pointer
-+	lhi	%r14,10
-+	j	.Loop
-+
-+.align	4
-+.Loop:
-+___
-+	foreach (&ROUND(0, 4, 8,12)) { eval; }
-+	foreach (&ROUND(0, 5,10,15)) { eval; }
-+$code.=<<___;
-+	brct	%r14,.Loop
-+
-+	l${g}	%r14,$frame+2*$SIZE_T($sp)		# pull input pointer
-+	stm	@t[0],@t[1],$stdframe+4*8+4*8($sp)	# offload x[8]-x[9]
-+	lm${g}	@t[0],@t[1],$frame+3*$SIZE_T($sp)
-+
-+	al	@x[0],$stdframe+4*0($sp)	# accumulate key schedule
-+	al	@x[1],$stdframe+4*1($sp)
-+	al	@x[2],$stdframe+4*2($sp)
-+	al	@x[3],$stdframe+4*3($sp)
-+	al	@x[4],$stdframe+4*4($sp)
-+	al	@x[5],$stdframe+4*5($sp)
-+	al	@x[6],$stdframe+4*6($sp)
-+	al	@x[7],$stdframe+4*7($sp)
-+	lrvr	@x[0],@x[0]
-+	lrvr	@x[1],@x[1]
-+	lrvr	@x[2],@x[2]
-+	lrvr	@x[3],@x[3]
-+	lrvr	@x[4],@x[4]
-+	lrvr	@x[5],@x[5]
-+	lrvr	@x[6],@x[6]
-+	lrvr	@x[7],@x[7]
-+	al	@x[12],$stdframe+4*12($sp)
-+	al	@x[13],$stdframe+4*13($sp)
-+	al	@x[14],$stdframe+4*14($sp)
-+	al	@x[15],$stdframe+4*15($sp)
-+	lrvr	@x[12],@x[12]
-+	lrvr	@x[13],@x[13]
-+	lrvr	@x[14],@x[14]
-+	lrvr	@x[15],@x[15]
-+
-+	la	@t[0],0(@t[0],%r14)		# reconstruct output pointer
-+	cl${g}r	%r14,@t[1]
-+	jh	.Ltail
-+
-+	x	@x[0],4*0(%r14)			# xor with input
-+	x	@x[1],4*1(%r14)
-+	st	@x[0],4*0(@t[0])		# store output
-+	x	@x[2],4*2(%r14)
-+	st	@x[1],4*1(@t[0])
-+	x	@x[3],4*3(%r14)
-+	st	@x[2],4*2(@t[0])
-+	x	@x[4],4*4(%r14)
-+	st	@x[3],4*3(@t[0])
-+	 lm	@x[0],@x[3],$stdframe+4*8+4*8($sp)	# load x[8]-x[11]
-+	x	@x[5],4*5(%r14)
-+	st	@x[4],4*4(@t[0])
-+	x	@x[6],4*6(%r14)
-+	 al	@x[0],$stdframe+4*8($sp)
-+	st	@x[5],4*5(@t[0])
-+	x	@x[7],4*7(%r14)
-+	 al	@x[1],$stdframe+4*9($sp)
-+	st	@x[6],4*6(@t[0])
-+	x	@x[12],4*12(%r14)
-+	 al	@x[2],$stdframe+4*10($sp)
-+	st	@x[7],4*7(@t[0])
-+	x	@x[13],4*13(%r14)
-+	 al	@x[3],$stdframe+4*11($sp)
-+	st	@x[12],4*12(@t[0])
-+	x	@x[14],4*14(%r14)
-+	st	@x[13],4*13(@t[0])
-+	x	@x[15],4*15(%r14)
-+	st	@x[14],4*14(@t[0])
-+	 lrvr	@x[0],@x[0]
-+	st	@x[15],4*15(@t[0])
-+	 lrvr	@x[1],@x[1]
-+	 lrvr	@x[2],@x[2]
-+	 lrvr	@x[3],@x[3]
-+	lhi	@x[12],1
-+	 x	@x[0],4*8(%r14)
-+	al	@x[12],$stdframe+4*12($sp)	# increment counter
-+	 x	@x[1],4*9(%r14)
-+	 st	@x[0],4*8(@t[0])
-+	 x	@x[2],4*10(%r14)
-+	 st	@x[1],4*9(@t[0])
-+	 x	@x[3],4*11(%r14)
-+	 st	@x[2],4*10(@t[0])
-+	 st	@x[3],4*11(@t[0])
-+
-+	cl${g}r	%r14,@t[1]			# done yet?
-+	la	%r14,64(%r14)
-+	jl	.Loop_outer
-+
-+.Ldone:
-+	xgr	%r0,%r0
-+	xgr	%r1,%r1
-+	xgr	%r2,%r2
-+	xgr	%r3,%r3
-+	stmg	%r0,%r3,$stdframe+4*4($sp)	# wipe key copy
-+	stmg	%r0,%r3,$stdframe+4*12($sp)
-+
-+	lm${g}	%r6,%r15,`$frame+6*$SIZE_T`($sp)
-+	br	%r14
-+
-+.align	16
-+.Ltail:
-+	la	@t[1],64($t[1])
-+	stm	@x[0],@x[7],$stdframe+4*0($sp)
-+	sl${g}r	@t[1],%r14
-+	lm	@x[0],@x[3],$stdframe+4*8+4*8($sp)
-+	l${g}hi	@x[6],0
-+	stm	@x[12],@x[15],$stdframe+4*12($sp)
-+	al	@x[0],$stdframe+4*8($sp)
-+	al	@x[1],$stdframe+4*9($sp)
-+	al	@x[2],$stdframe+4*10($sp)
-+	al	@x[3],$stdframe+4*11($sp)
-+	lrvr	@x[0],@x[0]
-+	lrvr	@x[1],@x[1]
-+	lrvr	@x[2],@x[2]
-+	lrvr	@x[3],@x[3]
-+	stm	@x[0],@x[3],$stdframe+4*8($sp)
-+
-+.Loop_tail:
-+	llgc	@x[4],0(@x[6],%r14)
-+	llgc	@x[5],$stdframe(@x[6],$sp)
-+	xr	@x[5],@x[4]
-+	stc	@x[5],0(@x[6],@t[0])
-+	la	@x[6],1(@x[6])
-+	brct	@t[1],.Loop_tail
-+
-+	j	.Ldone
-+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
-+
-+.align	32
-+.Lsigma:
-+.long	0x61707865,0x3320646e,0x79622d32,0x6b206574	# endian-neutral
-+.asciz	"ChaCha20 for s390x, CRYPTOGAMS by "
-+.align	4
-+___
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	print $_,"\n";
-+}
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-x86.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-x86.pl
-new file mode 100755
-index 0000000..61b3286
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-x86.pl
-@@ -0,0 +1,1154 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# January 2015
-+#
-+# ChaCha20 for x86.
-+#
-+# Performance in cycles per byte out of large buffer.
-+#
-+#		1xIALU/gcc	4xSSSE3
-+# Pentium	17.5/+80%
-+# PIII		14.2/+60%
-+# P4		18.6/+84%
-+# Core2		9.56/+89%	4.83
-+# Westmere	9.50/+45%	3.35
-+# Sandy Bridge	10.5/+47%	3.20
-+# Haswell	8.15/+50%	2.83
-+# Silvermont	17.4/+36%	8.35
-+# Goldmont	13.4/+40%	4.36
-+# Sledgehammer	10.2/+54%
-+# Bulldozer	13.4/+50%	4.38(*)
-+#
-+# (*)	Bulldozer actually executes 4xXOP code path that delivers 3.55;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"chacha-x86.pl",$ARGV[$#ARGV] eq "386");
-+
-+$xmm=$ymm=0;
-+for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
-+
-+$ymm=1 if ($xmm &&
-+		`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+			=~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
-+		($gasver=$1)>=2.19);	# first version supporting AVX
-+
-+$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32n" &&
-+		`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
-+		$1>=2.03);	# first version supporting AVX
-+
-+$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32" &&
-+		`ml 2>&1` =~ /Version ([0-9]+)\./ &&
-+		$1>=10);	# first version supporting AVX
-+
-+$ymm=1 if ($xmm && !$ymm &&
-+		`$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/ &&
-+		$2>=3.0);	# first version supporting AVX
-+
-+$a="eax";
-+($b,$b_)=("ebx","ebp");
-+($c,$c_)=("ecx","esi");
-+($d,$d_)=("edx","edi");
-+
-+sub QUARTERROUND {
-+my ($ai,$bi,$ci,$di,$i)=@_;
-+my ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+1)&3),($ai,$bi,$ci,$di));	# next
-+my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di));	# previous
-+
-+	#       a   b   c   d
-+	#
-+	#       0   4   8  12 < even round
-+	#       1   5   9  13
-+	#       2   6  10  14
-+	#       3   7  11  15
-+	#       0   5  10  15 < odd round
-+	#       1   6  11  12
-+	#       2   7   8  13
-+	#       3   4   9  14
-+
-+	if ($i==0) {
-+            my $j=4;
-+	    ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-$j--)&3),($ap,$bp,$cp,$dp));
-+	} elsif ($i==3) {
-+            my $j=0;
-+	    ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+$j++)&3),($an,$bn,$cn,$dn));
-+	} elsif ($i==4) {
-+            my $j=4;
-+	    ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_+$j--)&3),($ap,$bp,$cp,$dp));
-+	} elsif ($i==7) {
-+            my $j=0;
-+	    ($an,$bn,$cn,$dn)=map(($_&~3)+(($_-$j++)&3),($an,$bn,$cn,$dn));
-+	}
-+
-+	#&add	($a,$b);			# see elsewhere
-+	&xor	($d,$a);
-+	 &mov	(&DWP(4*$cp,"esp"),$c_)		if ($ai>0 && $ai<3);
-+	&rol	($d,16);
-+	 &mov	(&DWP(4*$bp,"esp"),$b_)		if ($i!=0);
-+	&add	($c,$d);
-+	 &mov	($c_,&DWP(4*$cn,"esp"))		if ($ai>0 && $ai<3);
-+	&xor	($b,$c);
-+	 &mov	($d_,&DWP(4*$dn,"esp"))		if ($di!=$dn);
-+	&rol	($b,12);
-+	 &mov	($b_,&DWP(4*$bn,"esp"))		if ($i<7);
-+	 &mov	($b_,&DWP(128,"esp"))		if ($i==7);	# loop counter
-+	&add	($a,$b);
-+	&xor	($d,$a);
-+	&mov	(&DWP(4*$ai,"esp"),$a);
-+	&rol	($d,8);
-+	&mov	($a,&DWP(4*$an,"esp"));
-+	&add	($c,$d);
-+	&mov	(&DWP(4*$di,"esp"),$d)		if ($di!=$dn);
-+	&mov	($d_,$d)			if ($di==$dn);
-+	&xor	($b,$c);
-+	 &add	($a,$b_)			if ($i<7);	# elsewhere
-+	&rol	($b,7);
-+
-+	($b,$b_)=($b_,$b);
-+	($c,$c_)=($c_,$c);
-+	($d,$d_)=($d_,$d);
-+}
-+
-+&static_label("ssse3_shortcut");
-+&static_label("xop_shortcut");
-+&static_label("ssse3_data");
-+&static_label("pic_point");
-+
-+&function_begin("ChaCha20_ctr32");
-+	&xor	("eax","eax");
-+	&cmp	("eax",&wparam(2));		# len==0?
-+	&je	(&label("no_data"));
-+if ($xmm) {
-+	&call	(&label("pic_point"));
-+&set_label("pic_point");
-+	&blindpop("eax");
-+	&picmeup("ebp","OPENSSL_ia32cap_P","eax",&label("pic_point"));
-+	&test	(&DWP(0,"ebp"),1<<24);		# test FXSR bit
-+	&jz	(&label("x86"));
-+	&test	(&DWP(4,"ebp"),1<<9);		# test SSSE3 bit
-+	&jz	(&label("x86"));
-+	&jmp	(&label("ssse3_shortcut"));
-+&set_label("x86");
-+}
-+	&mov	("esi",&wparam(3));		# key
-+	&mov	("edi",&wparam(4));		# counter and nonce
-+
-+	&stack_push(33);
-+
-+	&mov	("eax",&DWP(4*0,"esi"));	# copy key
-+	&mov	("ebx",&DWP(4*1,"esi"));
-+	&mov	("ecx",&DWP(4*2,"esi"));
-+	&mov	("edx",&DWP(4*3,"esi"));
-+	&mov	(&DWP(64+4*4,"esp"),"eax");
-+	&mov	(&DWP(64+4*5,"esp"),"ebx");
-+	&mov	(&DWP(64+4*6,"esp"),"ecx");
-+	&mov	(&DWP(64+4*7,"esp"),"edx");
-+	&mov	("eax",&DWP(4*4,"esi"));
-+	&mov	("ebx",&DWP(4*5,"esi"));
-+	&mov	("ecx",&DWP(4*6,"esi"));
-+	&mov	("edx",&DWP(4*7,"esi"));
-+	&mov	(&DWP(64+4*8,"esp"),"eax");
-+	&mov	(&DWP(64+4*9,"esp"),"ebx");
-+	&mov	(&DWP(64+4*10,"esp"),"ecx");
-+	&mov	(&DWP(64+4*11,"esp"),"edx");
-+	&mov	("eax",&DWP(4*0,"edi"));	# copy counter and nonce
-+	&mov	("ebx",&DWP(4*1,"edi"));
-+	&mov	("ecx",&DWP(4*2,"edi"));
-+	&mov	("edx",&DWP(4*3,"edi"));
-+	&sub	("eax",1);
-+	&mov	(&DWP(64+4*12,"esp"),"eax");
-+	&mov	(&DWP(64+4*13,"esp"),"ebx");
-+	&mov	(&DWP(64+4*14,"esp"),"ecx");
-+	&mov	(&DWP(64+4*15,"esp"),"edx");
-+	&jmp	(&label("entry"));
-+
-+&set_label("outer_loop",16);
-+	&mov	(&wparam(1),$b);		# save input
-+	&mov	(&wparam(0),$a);		# save output
-+	&mov	(&wparam(2),$c);		# save len
-+&set_label("entry");
-+	&mov	($a,0x61707865);
-+	&mov	(&DWP(4*1,"esp"),0x3320646e);
-+	&mov	(&DWP(4*2,"esp"),0x79622d32);
-+	&mov	(&DWP(4*3,"esp"),0x6b206574);
-+
-+	&mov	($b, &DWP(64+4*5,"esp"));	# copy key material
-+	&mov	($b_,&DWP(64+4*6,"esp"));
-+	&mov	($c, &DWP(64+4*10,"esp"));
-+	&mov	($c_,&DWP(64+4*11,"esp"));
-+	&mov	($d, &DWP(64+4*13,"esp"));
-+	&mov	($d_,&DWP(64+4*14,"esp"));
-+	&mov	(&DWP(4*5,"esp"),$b);
-+	&mov	(&DWP(4*6,"esp"),$b_);
-+	&mov	(&DWP(4*10,"esp"),$c);
-+	&mov	(&DWP(4*11,"esp"),$c_);
-+	&mov	(&DWP(4*13,"esp"),$d);
-+	&mov	(&DWP(4*14,"esp"),$d_);
-+
-+	&mov	($b, &DWP(64+4*7,"esp"));
-+	&mov	($d_,&DWP(64+4*15,"esp"));
-+	&mov	($d, &DWP(64+4*12,"esp"));
-+	&mov	($b_,&DWP(64+4*4,"esp"));
-+	&mov	($c, &DWP(64+4*8,"esp"));
-+	&mov	($c_,&DWP(64+4*9,"esp"));
-+	&add	($d,1);				# counter value
-+	&mov	(&DWP(4*7,"esp"),$b);
-+	&mov	(&DWP(4*15,"esp"),$d_);
-+	&mov	(&DWP(64+4*12,"esp"),$d);	# save counter value
-+
-+	&mov	($b,10);			# loop counter
-+	&jmp	(&label("loop"));
-+
-+&set_label("loop",16);
-+	&add	($a,$b_);			# elsewhere
-+	&mov	(&DWP(128,"esp"),$b);		# save loop counter
-+	&mov	($b,$b_);
-+	&QUARTERROUND(0, 4, 8, 12, 0);
-+	&QUARTERROUND(1, 5, 9, 13, 1);
-+	&QUARTERROUND(2, 6,10, 14, 2);
-+	&QUARTERROUND(3, 7,11, 15, 3);
-+	&QUARTERROUND(0, 5,10, 15, 4);
-+	&QUARTERROUND(1, 6,11, 12, 5);
-+	&QUARTERROUND(2, 7, 8, 13, 6);
-+	&QUARTERROUND(3, 4, 9, 14, 7);
-+	&dec	($b);
-+	&jnz	(&label("loop"));
-+
-+	&mov	($b,&wparam(2));		# load len
-+
-+	&add	($a,0x61707865);		# accumulate key material
-+	&add	($b_,&DWP(64+4*4,"esp"));
-+	&add	($c, &DWP(64+4*8,"esp"));
-+	&add	($c_,&DWP(64+4*9,"esp"));
-+
-+	&cmp	($b,64);
-+	&jb	(&label("tail"));
-+
-+	&mov	($b,&wparam(1));		# load input pointer
-+	&add	($d, &DWP(64+4*12,"esp"));
-+	&add	($d_,&DWP(64+4*14,"esp"));
-+
-+	&xor	($a, &DWP(4*0,$b));		# xor with input
-+	&xor	($b_,&DWP(4*4,$b));
-+	&mov	(&DWP(4*0,"esp"),$a);
-+	&mov	($a,&wparam(0));		# load output pointer
-+	&xor	($c, &DWP(4*8,$b));
-+	&xor	($c_,&DWP(4*9,$b));
-+	&xor	($d, &DWP(4*12,$b));
-+	&xor	($d_,&DWP(4*14,$b));
-+	&mov	(&DWP(4*4,$a),$b_);		# write output
-+	&mov	(&DWP(4*8,$a),$c);
-+	&mov	(&DWP(4*9,$a),$c_);
-+	&mov	(&DWP(4*12,$a),$d);
-+	&mov	(&DWP(4*14,$a),$d_);
-+
-+	&mov	($b_,&DWP(4*1,"esp"));
-+	&mov	($c, &DWP(4*2,"esp"));
-+	&mov	($c_,&DWP(4*3,"esp"));
-+	&mov	($d, &DWP(4*5,"esp"));
-+	&mov	($d_,&DWP(4*6,"esp"));
-+	&add	($b_,0x3320646e);		# accumulate key material
-+	&add	($c, 0x79622d32);
-+	&add	($c_,0x6b206574);
-+	&add	($d, &DWP(64+4*5,"esp"));
-+	&add	($d_,&DWP(64+4*6,"esp"));
-+	&xor	($b_,&DWP(4*1,$b));
-+	&xor	($c, &DWP(4*2,$b));
-+	&xor	($c_,&DWP(4*3,$b));
-+	&xor	($d, &DWP(4*5,$b));
-+	&xor	($d_,&DWP(4*6,$b));
-+	&mov	(&DWP(4*1,$a),$b_);
-+	&mov	(&DWP(4*2,$a),$c);
-+	&mov	(&DWP(4*3,$a),$c_);
-+	&mov	(&DWP(4*5,$a),$d);
-+	&mov	(&DWP(4*6,$a),$d_);
-+
-+	&mov	($b_,&DWP(4*7,"esp"));
-+	&mov	($c, &DWP(4*10,"esp"));
-+	&mov	($c_,&DWP(4*11,"esp"));
-+	&mov	($d, &DWP(4*13,"esp"));
-+	&mov	($d_,&DWP(4*15,"esp"));
-+	&add	($b_,&DWP(64+4*7,"esp"));
-+	&add	($c, &DWP(64+4*10,"esp"));
-+	&add	($c_,&DWP(64+4*11,"esp"));
-+	&add	($d, &DWP(64+4*13,"esp"));
-+	&add	($d_,&DWP(64+4*15,"esp"));
-+	&xor	($b_,&DWP(4*7,$b));
-+	&xor	($c, &DWP(4*10,$b));
-+	&xor	($c_,&DWP(4*11,$b));
-+	&xor	($d, &DWP(4*13,$b));
-+	&xor	($d_,&DWP(4*15,$b));
-+	&lea	($b,&DWP(4*16,$b));
-+	&mov	(&DWP(4*7,$a),$b_);
-+	&mov	($b_,&DWP(4*0,"esp"));
-+	&mov	(&DWP(4*10,$a),$c);
-+	&mov	($c,&wparam(2));		# len
-+	&mov	(&DWP(4*11,$a),$c_);
-+	&mov	(&DWP(4*13,$a),$d);
-+	&mov	(&DWP(4*15,$a),$d_);
-+	&mov	(&DWP(4*0,$a),$b_);
-+	&lea	($a,&DWP(4*16,$a));
-+	&sub	($c,64);
-+	&jnz	(&label("outer_loop"));
-+
-+	&jmp	(&label("done"));
-+
-+&set_label("tail");
-+	&add	($d, &DWP(64+4*12,"esp"));
-+	&add	($d_,&DWP(64+4*14,"esp"));
-+	&mov	(&DWP(4*0,"esp"),$a);
-+	&mov	(&DWP(4*4,"esp"),$b_);
-+	&mov	(&DWP(4*8,"esp"),$c);
-+	&mov	(&DWP(4*9,"esp"),$c_);
-+	&mov	(&DWP(4*12,"esp"),$d);
-+	&mov	(&DWP(4*14,"esp"),$d_);
-+
-+	&mov	($b_,&DWP(4*1,"esp"));
-+	&mov	($c, &DWP(4*2,"esp"));
-+	&mov	($c_,&DWP(4*3,"esp"));
-+	&mov	($d, &DWP(4*5,"esp"));
-+	&mov	($d_,&DWP(4*6,"esp"));
-+	&add	($b_,0x3320646e);		# accumulate key material
-+	&add	($c, 0x79622d32);
-+	&add	($c_,0x6b206574);
-+	&add	($d, &DWP(64+4*5,"esp"));
-+	&add	($d_,&DWP(64+4*6,"esp"));
-+	&mov	(&DWP(4*1,"esp"),$b_);
-+	&mov	(&DWP(4*2,"esp"),$c);
-+	&mov	(&DWP(4*3,"esp"),$c_);
-+	&mov	(&DWP(4*5,"esp"),$d);
-+	&mov	(&DWP(4*6,"esp"),$d_);
-+
-+	&mov	($b_,&DWP(4*7,"esp"));
-+	&mov	($c, &DWP(4*10,"esp"));
-+	&mov	($c_,&DWP(4*11,"esp"));
-+	&mov	($d, &DWP(4*13,"esp"));
-+	&mov	($d_,&DWP(4*15,"esp"));
-+	&add	($b_,&DWP(64+4*7,"esp"));
-+	&add	($c, &DWP(64+4*10,"esp"));
-+	&add	($c_,&DWP(64+4*11,"esp"));
-+	&add	($d, &DWP(64+4*13,"esp"));
-+	&add	($d_,&DWP(64+4*15,"esp"));
-+	&mov	(&DWP(4*7,"esp"),$b_);
-+	&mov	($b_,&wparam(1));		# load input
-+	&mov	(&DWP(4*10,"esp"),$c);
-+	&mov	($c,&wparam(0));		# load output
-+	&mov	(&DWP(4*11,"esp"),$c_);
-+	&xor	($c_,$c_);
-+	&mov	(&DWP(4*13,"esp"),$d);
-+	&mov	(&DWP(4*15,"esp"),$d_);
-+
-+	&xor	("eax","eax");
-+	&xor	("edx","edx");
-+&set_label("tail_loop");
-+	&movb	("al",&BP(0,$c_,$b_));
-+	&movb	("dl",&BP(0,"esp",$c_));
-+	&lea	($c_,&DWP(1,$c_));
-+	&xor	("al","dl");
-+	&mov	(&BP(-1,$c,$c_),"al");
-+	&dec	($b);
-+	&jnz	(&label("tail_loop"));
-+
-+&set_label("done");
-+	&stack_pop(33);
-+&set_label("no_data");
-+&function_end("ChaCha20_ctr32");
-+
-+if ($xmm) {
-+my ($xa,$xa_,$xb,$xb_,$xc,$xc_,$xd,$xd_)=map("xmm$_",(0..7));
-+my ($out,$inp,$len)=("edi","esi","ecx");
-+
-+sub QUARTERROUND_SSSE3 {
-+my ($ai,$bi,$ci,$di,$i)=@_;
-+my ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+1)&3),($ai,$bi,$ci,$di));	# next
-+my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di));	# previous
-+
-+	#       a   b   c   d
-+	#
-+	#       0   4   8  12 < even round
-+	#       1   5   9  13
-+	#       2   6  10  14
-+	#       3   7  11  15
-+	#       0   5  10  15 < odd round
-+	#       1   6  11  12
-+	#       2   7   8  13
-+	#       3   4   9  14
-+
-+	if ($i==0) {
-+            my $j=4;
-+	    ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-$j--)&3),($ap,$bp,$cp,$dp));
-+	} elsif ($i==3) {
-+            my $j=0;
-+	    ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+$j++)&3),($an,$bn,$cn,$dn));
-+	} elsif ($i==4) {
-+            my $j=4;
-+	    ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_+$j--)&3),($ap,$bp,$cp,$dp));
-+	} elsif ($i==7) {
-+            my $j=0;
-+	    ($an,$bn,$cn,$dn)=map(($_&~3)+(($_-$j++)&3),($an,$bn,$cn,$dn));
-+	}
-+
-+	#&paddd	($xa,$xb);			# see elsewhere
-+	#&pxor	($xd,$xa);			# see elsewhere
-+	 &movdqa(&QWP(16*$cp-128,"ebx"),$xc_)	if ($ai>0 && $ai<3);
-+	&pshufb	($xd,&QWP(0,"eax"));		# rot16
-+	 &movdqa(&QWP(16*$bp-128,"ebx"),$xb_)	if ($i!=0);
-+	&paddd	($xc,$xd);
-+	 &movdqa($xc_,&QWP(16*$cn-128,"ebx"))	if ($ai>0 && $ai<3);
-+	&pxor	($xb,$xc);
-+	 &movdqa($xb_,&QWP(16*$bn-128,"ebx"))	if ($i<7);
-+	&movdqa	($xa_,$xb);			# borrow as temporary
-+	&pslld	($xb,12);
-+	&psrld	($xa_,20);
-+	&por	($xb,$xa_);
-+	 &movdqa($xa_,&QWP(16*$an-128,"ebx"));
-+	&paddd	($xa,$xb);
-+	 &movdqa($xd_,&QWP(16*$dn-128,"ebx"))	if ($di!=$dn);
-+	&pxor	($xd,$xa);
-+	&movdqa	(&QWP(16*$ai-128,"ebx"),$xa);
-+	&pshufb	($xd,&QWP(16,"eax"));		# rot8
-+	&paddd	($xc,$xd);
-+	&movdqa	(&QWP(16*$di-128,"ebx"),$xd)	if ($di!=$dn);
-+	&movdqa	($xd_,$xd)			if ($di==$dn);
-+	&pxor	($xb,$xc);
-+	 &paddd	($xa_,$xb_)			if ($i<7);	# elsewhere
-+	&movdqa	($xa,$xb);			# borrow as temporary
-+	&pslld	($xb,7);
-+	&psrld	($xa,25);
-+	 &pxor	($xd_,$xa_)			if ($i<7);	# elsewhere
-+	&por	($xb,$xa);
-+
-+	($xa,$xa_)=($xa_,$xa);
-+	($xb,$xb_)=($xb_,$xb);
-+	($xc,$xc_)=($xc_,$xc);
-+	($xd,$xd_)=($xd_,$xd);
-+}
-+
-+&function_begin("ChaCha20_ssse3");
-+&set_label("ssse3_shortcut");
-+if ($ymm) {
-+	&test		(&DWP(4,"ebp"),1<<11);		# test XOP bit
-+	&jnz		(&label("xop_shortcut"));
-+}
-+
-+	&mov		($out,&wparam(0));
-+	&mov		($inp,&wparam(1));
-+	&mov		($len,&wparam(2));
-+	&mov		("edx",&wparam(3));		# key
-+	&mov		("ebx",&wparam(4));		# counter and nonce
-+
-+	&mov		("ebp","esp");
-+	&stack_push	(131);
-+	&and		("esp",-64);
-+	&mov		(&DWP(512,"esp"),"ebp");
-+
-+	&lea		("eax",&DWP(&label("ssse3_data")."-".
-+				    &label("pic_point"),"eax"));
-+	&movdqu		("xmm3",&QWP(0,"ebx"));		# counter and nonce
-+
-+if (defined($gasver) && $gasver>=2.17) {		# even though we encode
-+							# pshufb manually, we
-+							# handle only register
-+							# operands, while this
-+							# segment uses memory
-+							# operand...
-+	&cmp		($len,64*4);
-+	&jb		(&label("1x"));
-+
-+	&mov		(&DWP(512+4,"esp"),"edx");	# offload pointers
-+	&mov		(&DWP(512+8,"esp"),"ebx");
-+	&sub		($len,64*4);			# bias len
-+	&lea		("ebp",&DWP(256+128,"esp"));	# size optimization
-+
-+	&movdqu		("xmm7",&QWP(0,"edx"));		# key
-+	&pshufd		("xmm0","xmm3",0x00);
-+	&pshufd		("xmm1","xmm3",0x55);
-+	&pshufd		("xmm2","xmm3",0xaa);
-+	&pshufd		("xmm3","xmm3",0xff);
-+	 &paddd		("xmm0",&QWP(16*3,"eax"));	# fix counters
-+	&pshufd		("xmm4","xmm7",0x00);
-+	&pshufd		("xmm5","xmm7",0x55);
-+	 &psubd		("xmm0",&QWP(16*4,"eax"));
-+	&pshufd		("xmm6","xmm7",0xaa);
-+	&pshufd		("xmm7","xmm7",0xff);
-+	&movdqa		(&QWP(16*12-128,"ebp"),"xmm0");
-+	&movdqa		(&QWP(16*13-128,"ebp"),"xmm1");
-+	&movdqa		(&QWP(16*14-128,"ebp"),"xmm2");
-+	&movdqa		(&QWP(16*15-128,"ebp"),"xmm3");
-+	 &movdqu	("xmm3",&QWP(16,"edx"));	# key
-+	&movdqa		(&QWP(16*4-128,"ebp"),"xmm4");
-+	&movdqa		(&QWP(16*5-128,"ebp"),"xmm5");
-+	&movdqa		(&QWP(16*6-128,"ebp"),"xmm6");
-+	&movdqa		(&QWP(16*7-128,"ebp"),"xmm7");
-+	 &movdqa	("xmm7",&QWP(16*2,"eax"));	# sigma
-+	 &lea		("ebx",&DWP(128,"esp"));	# size optimization
-+
-+	&pshufd		("xmm0","xmm3",0x00);
-+	&pshufd		("xmm1","xmm3",0x55);
-+	&pshufd		("xmm2","xmm3",0xaa);
-+	&pshufd		("xmm3","xmm3",0xff);
-+	&pshufd		("xmm4","xmm7",0x00);
-+	&pshufd		("xmm5","xmm7",0x55);
-+	&pshufd		("xmm6","xmm7",0xaa);
-+	&pshufd		("xmm7","xmm7",0xff);
-+	&movdqa		(&QWP(16*8-128,"ebp"),"xmm0");
-+	&movdqa		(&QWP(16*9-128,"ebp"),"xmm1");
-+	&movdqa		(&QWP(16*10-128,"ebp"),"xmm2");
-+	&movdqa		(&QWP(16*11-128,"ebp"),"xmm3");
-+	&movdqa		(&QWP(16*0-128,"ebp"),"xmm4");
-+	&movdqa		(&QWP(16*1-128,"ebp"),"xmm5");
-+	&movdqa		(&QWP(16*2-128,"ebp"),"xmm6");
-+	&movdqa		(&QWP(16*3-128,"ebp"),"xmm7");
-+
-+	&lea		($inp,&DWP(128,$inp));		# size optimization
-+	&lea		($out,&DWP(128,$out));		# size optimization
-+	&jmp		(&label("outer_loop"));
-+
-+&set_label("outer_loop",16);
-+	#&movdqa	("xmm0",&QWP(16*0-128,"ebp"));	# copy key material
-+	&movdqa		("xmm1",&QWP(16*1-128,"ebp"));
-+	&movdqa		("xmm2",&QWP(16*2-128,"ebp"));
-+	&movdqa		("xmm3",&QWP(16*3-128,"ebp"));
-+	#&movdqa	("xmm4",&QWP(16*4-128,"ebp"));
-+	&movdqa		("xmm5",&QWP(16*5-128,"ebp"));
-+	&movdqa		("xmm6",&QWP(16*6-128,"ebp"));
-+	&movdqa		("xmm7",&QWP(16*7-128,"ebp"));
-+	#&movdqa	(&QWP(16*0-128,"ebx"),"xmm0");
-+	&movdqa		(&QWP(16*1-128,"ebx"),"xmm1");
-+	&movdqa		(&QWP(16*2-128,"ebx"),"xmm2");
-+	&movdqa		(&QWP(16*3-128,"ebx"),"xmm3");
-+	#&movdqa	(&QWP(16*4-128,"ebx"),"xmm4");
-+	&movdqa		(&QWP(16*5-128,"ebx"),"xmm5");
-+	&movdqa		(&QWP(16*6-128,"ebx"),"xmm6");
-+	&movdqa		(&QWP(16*7-128,"ebx"),"xmm7");
-+	#&movdqa	("xmm0",&QWP(16*8-128,"ebp"));
-+	#&movdqa	("xmm1",&QWP(16*9-128,"ebp"));
-+	&movdqa		("xmm2",&QWP(16*10-128,"ebp"));
-+	&movdqa		("xmm3",&QWP(16*11-128,"ebp"));
-+	&movdqa		("xmm4",&QWP(16*12-128,"ebp"));
-+	&movdqa		("xmm5",&QWP(16*13-128,"ebp"));
-+	&movdqa		("xmm6",&QWP(16*14-128,"ebp"));
-+	&movdqa		("xmm7",&QWP(16*15-128,"ebp"));
-+	&paddd		("xmm4",&QWP(16*4,"eax"));	# counter value
-+	#&movdqa	(&QWP(16*8-128,"ebx"),"xmm0");
-+	#&movdqa	(&QWP(16*9-128,"ebx"),"xmm1");
-+	&movdqa		(&QWP(16*10-128,"ebx"),"xmm2");
-+	&movdqa		(&QWP(16*11-128,"ebx"),"xmm3");
-+	&movdqa		(&QWP(16*12-128,"ebx"),"xmm4");
-+	&movdqa		(&QWP(16*13-128,"ebx"),"xmm5");
-+	&movdqa		(&QWP(16*14-128,"ebx"),"xmm6");
-+	&movdqa		(&QWP(16*15-128,"ebx"),"xmm7");
-+	&movdqa		(&QWP(16*12-128,"ebp"),"xmm4");	# save counter value
-+
-+	&movdqa		($xa, &QWP(16*0-128,"ebp"));
-+	&movdqa		($xd, "xmm4");
-+	&movdqa		($xb_,&QWP(16*4-128,"ebp"));
-+	&movdqa		($xc, &QWP(16*8-128,"ebp"));
-+	&movdqa		($xc_,&QWP(16*9-128,"ebp"));
-+
-+	&mov		("edx",10);			# loop counter
-+	&nop		();
-+
-+&set_label("loop",16);
-+	&paddd		($xa,$xb_);			# elsewhere
-+	&movdqa		($xb,$xb_);
-+	&pxor		($xd,$xa);			# elsewhere
-+	&QUARTERROUND_SSSE3(0, 4, 8, 12, 0);
-+	&QUARTERROUND_SSSE3(1, 5, 9, 13, 1);
-+	&QUARTERROUND_SSSE3(2, 6,10, 14, 2);
-+	&QUARTERROUND_SSSE3(3, 7,11, 15, 3);
-+	&QUARTERROUND_SSSE3(0, 5,10, 15, 4);
-+	&QUARTERROUND_SSSE3(1, 6,11, 12, 5);
-+	&QUARTERROUND_SSSE3(2, 7, 8, 13, 6);
-+	&QUARTERROUND_SSSE3(3, 4, 9, 14, 7);
-+	&dec		("edx");
-+	&jnz		(&label("loop"));
-+
-+	&movdqa		(&QWP(16*4-128,"ebx"),$xb_);
-+	&movdqa		(&QWP(16*8-128,"ebx"),$xc);
-+	&movdqa		(&QWP(16*9-128,"ebx"),$xc_);
-+	&movdqa		(&QWP(16*12-128,"ebx"),$xd);
-+	&movdqa		(&QWP(16*14-128,"ebx"),$xd_);
-+
-+    my ($xa0,$xa1,$xa2,$xa3,$xt0,$xt1,$xt2,$xt3)=map("xmm$_",(0..7));
-+
-+	#&movdqa	($xa0,&QWP(16*0-128,"ebx"));	# it's there
-+	&movdqa		($xa1,&QWP(16*1-128,"ebx"));
-+	&movdqa		($xa2,&QWP(16*2-128,"ebx"));
-+	&movdqa		($xa3,&QWP(16*3-128,"ebx"));
-+
-+    for($i=0;$i<256;$i+=64) {
-+	&paddd		($xa0,&QWP($i+16*0-128,"ebp"));	# accumulate key material
-+	&paddd		($xa1,&QWP($i+16*1-128,"ebp"));
-+	&paddd		($xa2,&QWP($i+16*2-128,"ebp"));
-+	&paddd		($xa3,&QWP($i+16*3-128,"ebp"));
-+
-+	&movdqa		($xt2,$xa0);		# "de-interlace" data
-+	&punpckldq	($xa0,$xa1);
-+	&movdqa		($xt3,$xa2);
-+	&punpckldq	($xa2,$xa3);
-+	&punpckhdq	($xt2,$xa1);
-+	&punpckhdq	($xt3,$xa3);
-+	&movdqa		($xa1,$xa0);
-+	&punpcklqdq	($xa0,$xa2);		# "a0"
-+	&movdqa		($xa3,$xt2);
-+	&punpcklqdq	($xt2,$xt3);		# "a2"
-+	&punpckhqdq	($xa1,$xa2);		# "a1"
-+	&punpckhqdq	($xa3,$xt3);		# "a3"
-+
-+	#($xa2,$xt2)=($xt2,$xa2);
-+
-+	&movdqu		($xt0,&QWP(64*0-128,$inp));	# load input
-+	&movdqu		($xt1,&QWP(64*1-128,$inp));
-+	&movdqu		($xa2,&QWP(64*2-128,$inp));
-+	&movdqu		($xt3,&QWP(64*3-128,$inp));
-+	&lea		($inp,&QWP($i<192?16:(64*4-16*3),$inp));
-+	&pxor		($xt0,$xa0);
-+	&movdqa		($xa0,&QWP($i+16*4-128,"ebx"))	if ($i<192);
-+	&pxor		($xt1,$xa1);
-+	&movdqa		($xa1,&QWP($i+16*5-128,"ebx"))	if ($i<192);
-+	&pxor		($xt2,$xa2);
-+	&movdqa		($xa2,&QWP($i+16*6-128,"ebx"))	if ($i<192);
-+	&pxor		($xt3,$xa3);
-+	&movdqa		($xa3,&QWP($i+16*7-128,"ebx"))	if ($i<192);
-+	&movdqu		(&QWP(64*0-128,$out),$xt0);	# store output
-+	&movdqu		(&QWP(64*1-128,$out),$xt1);
-+	&movdqu		(&QWP(64*2-128,$out),$xt2);
-+	&movdqu		(&QWP(64*3-128,$out),$xt3);
-+	&lea		($out,&QWP($i<192?16:(64*4-16*3),$out));
-+    }
-+	&sub		($len,64*4);
-+	&jnc		(&label("outer_loop"));
-+
-+	&add		($len,64*4);
-+	&jz		(&label("done"));
-+
-+	&mov		("ebx",&DWP(512+8,"esp"));	# restore pointers
-+	&lea		($inp,&DWP(-128,$inp));
-+	&mov		("edx",&DWP(512+4,"esp"));
-+	&lea		($out,&DWP(-128,$out));
-+
-+	&movd		("xmm2",&DWP(16*12-128,"ebp"));	# counter value
-+	&movdqu		("xmm3",&QWP(0,"ebx"));
-+	&paddd		("xmm2",&QWP(16*6,"eax"));	# +four
-+	&pand		("xmm3",&QWP(16*7,"eax"));
-+	&por		("xmm3","xmm2");		# counter value
-+}
-+{
-+my ($a,$b,$c,$d,$t,$t1,$rot16,$rot24)=map("xmm$_",(0..7));
-+
-+sub SSSE3ROUND {	# critical path is 20 "SIMD ticks" per round
-+	&paddd		($a,$b);
-+	&pxor		($d,$a);
-+	&pshufb		($d,$rot16);
-+
-+	&paddd		($c,$d);
-+	&pxor		($b,$c);
-+	&movdqa		($t,$b);
-+	&psrld		($b,20);
-+	&pslld		($t,12);
-+	&por		($b,$t);
-+
-+	&paddd		($a,$b);
-+	&pxor		($d,$a);
-+	&pshufb		($d,$rot24);
-+
-+	&paddd		($c,$d);
-+	&pxor		($b,$c);
-+	&movdqa		($t,$b);
-+	&psrld		($b,25);
-+	&pslld		($t,7);
-+	&por		($b,$t);
-+}
-+
-+&set_label("1x");
-+	&movdqa		($a,&QWP(16*2,"eax"));		# sigma
-+	&movdqu		($b,&QWP(0,"edx"));
-+	&movdqu		($c,&QWP(16,"edx"));
-+	#&movdqu	($d,&QWP(0,"ebx"));		# already loaded
-+	&movdqa		($rot16,&QWP(0,"eax"));
-+	&movdqa		($rot24,&QWP(16,"eax"));
-+	&mov		(&DWP(16*3,"esp"),"ebp");
-+
-+	&movdqa		(&QWP(16*0,"esp"),$a);
-+	&movdqa		(&QWP(16*1,"esp"),$b);
-+	&movdqa		(&QWP(16*2,"esp"),$c);
-+	&movdqa		(&QWP(16*3,"esp"),$d);
-+	&mov		("edx",10);
-+	&jmp		(&label("loop1x"));
-+
-+&set_label("outer1x",16);
-+	&movdqa		($d,&QWP(16*5,"eax"));		# one
-+	&movdqa		($a,&QWP(16*0,"esp"));
-+	&movdqa		($b,&QWP(16*1,"esp"));
-+	&movdqa		($c,&QWP(16*2,"esp"));
-+	&paddd		($d,&QWP(16*3,"esp"));
-+	&mov		("edx",10);
-+	&movdqa		(&QWP(16*3,"esp"),$d);
-+	&jmp		(&label("loop1x"));
-+
-+&set_label("loop1x",16);
-+	&SSSE3ROUND();
-+	&pshufd	($c,$c,0b01001110);
-+	&pshufd	($b,$b,0b00111001);
-+	&pshufd	($d,$d,0b10010011);
-+	&nop	();
-+
-+	&SSSE3ROUND();
-+	&pshufd	($c,$c,0b01001110);
-+	&pshufd	($b,$b,0b10010011);
-+	&pshufd	($d,$d,0b00111001);
-+
-+	&dec		("edx");
-+	&jnz		(&label("loop1x"));
-+
-+	&paddd		($a,&QWP(16*0,"esp"));
-+	&paddd		($b,&QWP(16*1,"esp"));
-+	&paddd		($c,&QWP(16*2,"esp"));
-+	&paddd		($d,&QWP(16*3,"esp"));
-+
-+	&cmp		($len,64);
-+	&jb		(&label("tail"));
-+
-+	&movdqu		($t,&QWP(16*0,$inp));
-+	&movdqu		($t1,&QWP(16*1,$inp));
-+	&pxor		($a,$t);		# xor with input
-+	&movdqu		($t,&QWP(16*2,$inp));
-+	&pxor		($b,$t1);
-+	&movdqu		($t1,&QWP(16*3,$inp));
-+	&pxor		($c,$t);
-+	&pxor		($d,$t1);
-+	&lea		($inp,&DWP(16*4,$inp));	# inp+=64
-+
-+	&movdqu		(&QWP(16*0,$out),$a);	# write output
-+	&movdqu		(&QWP(16*1,$out),$b);
-+	&movdqu		(&QWP(16*2,$out),$c);
-+	&movdqu		(&QWP(16*3,$out),$d);
-+	&lea		($out,&DWP(16*4,$out));	# inp+=64
-+
-+	&sub		($len,64);
-+	&jnz		(&label("outer1x"));
-+
-+	&jmp		(&label("done"));
-+
-+&set_label("tail");
-+	&movdqa		(&QWP(16*0,"esp"),$a);
-+	&movdqa		(&QWP(16*1,"esp"),$b);
-+	&movdqa		(&QWP(16*2,"esp"),$c);
-+	&movdqa		(&QWP(16*3,"esp"),$d);
-+
-+	&xor		("eax","eax");
-+	&xor		("edx","edx");
-+	&xor		("ebp","ebp");
-+
-+&set_label("tail_loop");
-+	&movb		("al",&BP(0,"esp","ebp"));
-+	&movb		("dl",&BP(0,$inp,"ebp"));
-+	&lea		("ebp",&DWP(1,"ebp"));
-+	&xor		("al","dl");
-+	&movb		(&BP(-1,$out,"ebp"),"al");
-+	&dec		($len);
-+	&jnz		(&label("tail_loop"));
-+}
-+&set_label("done");
-+	&mov		("esp",&DWP(512,"esp"));
-+&function_end("ChaCha20_ssse3");
-+
-+&align	(64);
-+&set_label("ssse3_data");
-+&data_byte(0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd);
-+&data_byte(0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe);
-+&data_word(0x61707865,0x3320646e,0x79622d32,0x6b206574);
-+&data_word(0,1,2,3);
-+&data_word(4,4,4,4);
-+&data_word(1,0,0,0);
-+&data_word(4,0,0,0);
-+&data_word(0,-1,-1,-1);
-+&align	(64);
-+}
-+&asciz	("ChaCha20 for x86, CRYPTOGAMS by ");
-+
-+if ($ymm) {
-+my ($xa,$xa_,$xb,$xb_,$xc,$xc_,$xd,$xd_)=map("xmm$_",(0..7));
-+my ($out,$inp,$len)=("edi","esi","ecx");
-+
-+sub QUARTERROUND_XOP {
-+my ($ai,$bi,$ci,$di,$i)=@_;
-+my ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+1)&3),($ai,$bi,$ci,$di));	# next
-+my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di));	# previous
-+
-+	#       a   b   c   d
-+	#
-+	#       0   4   8  12 < even round
-+	#       1   5   9  13
-+	#       2   6  10  14
-+	#       3   7  11  15
-+	#       0   5  10  15 < odd round
-+	#       1   6  11  12
-+	#       2   7   8  13
-+	#       3   4   9  14
-+
-+	if ($i==0) {
-+            my $j=4;
-+	    ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-$j--)&3),($ap,$bp,$cp,$dp));
-+	} elsif ($i==3) {
-+            my $j=0;
-+	    ($an,$bn,$cn,$dn)=map(($_&~3)+(($_+$j++)&3),($an,$bn,$cn,$dn));
-+	} elsif ($i==4) {
-+            my $j=4;
-+	    ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_+$j--)&3),($ap,$bp,$cp,$dp));
-+	} elsif ($i==7) {
-+            my $j=0;
-+	    ($an,$bn,$cn,$dn)=map(($_&~3)+(($_-$j++)&3),($an,$bn,$cn,$dn));
-+	}
-+
-+	#&vpaddd	($xa,$xa,$xb);			# see elsewhere
-+	#&vpxor		($xd,$xd,$xa);			# see elsewhere
-+	 &vmovdqa	(&QWP(16*$cp-128,"ebx"),$xc_)	if ($ai>0 && $ai<3);
-+	&vprotd		($xd,$xd,16);
-+	 &vmovdqa	(&QWP(16*$bp-128,"ebx"),$xb_)	if ($i!=0);
-+	&vpaddd		($xc,$xc,$xd);
-+	 &vmovdqa	($xc_,&QWP(16*$cn-128,"ebx"))	if ($ai>0 && $ai<3);
-+	&vpxor		($xb,$i!=0?$xb:$xb_,$xc);
-+	 &vmovdqa	($xa_,&QWP(16*$an-128,"ebx"));
-+	&vprotd		($xb,$xb,12);
-+	 &vmovdqa	($xb_,&QWP(16*$bn-128,"ebx"))	if ($i<7);
-+	&vpaddd		($xa,$xa,$xb);
-+	 &vmovdqa	($xd_,&QWP(16*$dn-128,"ebx"))	if ($di!=$dn);
-+	&vpxor		($xd,$xd,$xa);
-+	 &vpaddd	($xa_,$xa_,$xb_)		if ($i<7);	# elsewhere
-+	&vprotd		($xd,$xd,8);
-+	&vmovdqa	(&QWP(16*$ai-128,"ebx"),$xa);
-+	&vpaddd		($xc,$xc,$xd);
-+	&vmovdqa	(&QWP(16*$di-128,"ebx"),$xd)	if ($di!=$dn);
-+	&vpxor		($xb,$xb,$xc);
-+	 &vpxor		($xd_,$di==$dn?$xd:$xd_,$xa_)	if ($i<7);	# elsewhere
-+	&vprotd		($xb,$xb,7);
-+
-+	($xa,$xa_)=($xa_,$xa);
-+	($xb,$xb_)=($xb_,$xb);
-+	($xc,$xc_)=($xc_,$xc);
-+	($xd,$xd_)=($xd_,$xd);
-+}
-+
-+&function_begin("ChaCha20_xop");
-+&set_label("xop_shortcut");
-+	&mov		($out,&wparam(0));
-+	&mov		($inp,&wparam(1));
-+	&mov		($len,&wparam(2));
-+	&mov		("edx",&wparam(3));		# key
-+	&mov		("ebx",&wparam(4));		# counter and nonce
-+	&vzeroupper	();
-+
-+	&mov		("ebp","esp");
-+	&stack_push	(131);
-+	&and		("esp",-64);
-+	&mov		(&DWP(512,"esp"),"ebp");
-+
-+	&lea		("eax",&DWP(&label("ssse3_data")."-".
-+				    &label("pic_point"),"eax"));
-+	&vmovdqu	("xmm3",&QWP(0,"ebx"));		# counter and nonce
-+
-+	&cmp		($len,64*4);
-+	&jb		(&label("1x"));
-+
-+	&mov		(&DWP(512+4,"esp"),"edx");	# offload pointers
-+	&mov		(&DWP(512+8,"esp"),"ebx");
-+	&sub		($len,64*4);			# bias len
-+	&lea		("ebp",&DWP(256+128,"esp"));	# size optimization
-+
-+	&vmovdqu	("xmm7",&QWP(0,"edx"));		# key
-+	&vpshufd	("xmm0","xmm3",0x00);
-+	&vpshufd	("xmm1","xmm3",0x55);
-+	&vpshufd	("xmm2","xmm3",0xaa);
-+	&vpshufd	("xmm3","xmm3",0xff);
-+	 &vpaddd	("xmm0","xmm0",&QWP(16*3,"eax"));	# fix counters
-+	&vpshufd	("xmm4","xmm7",0x00);
-+	&vpshufd	("xmm5","xmm7",0x55);
-+	 &vpsubd	("xmm0","xmm0",&QWP(16*4,"eax"));
-+	&vpshufd	("xmm6","xmm7",0xaa);
-+	&vpshufd	("xmm7","xmm7",0xff);
-+	&vmovdqa	(&QWP(16*12-128,"ebp"),"xmm0");
-+	&vmovdqa	(&QWP(16*13-128,"ebp"),"xmm1");
-+	&vmovdqa	(&QWP(16*14-128,"ebp"),"xmm2");
-+	&vmovdqa	(&QWP(16*15-128,"ebp"),"xmm3");
-+	 &vmovdqu	("xmm3",&QWP(16,"edx"));	# key
-+	&vmovdqa	(&QWP(16*4-128,"ebp"),"xmm4");
-+	&vmovdqa	(&QWP(16*5-128,"ebp"),"xmm5");
-+	&vmovdqa	(&QWP(16*6-128,"ebp"),"xmm6");
-+	&vmovdqa	(&QWP(16*7-128,"ebp"),"xmm7");
-+	 &vmovdqa	("xmm7",&QWP(16*2,"eax"));	# sigma
-+	 &lea		("ebx",&DWP(128,"esp"));	# size optimization
-+
-+	&vpshufd	("xmm0","xmm3",0x00);
-+	&vpshufd	("xmm1","xmm3",0x55);
-+	&vpshufd	("xmm2","xmm3",0xaa);
-+	&vpshufd	("xmm3","xmm3",0xff);
-+	&vpshufd	("xmm4","xmm7",0x00);
-+	&vpshufd	("xmm5","xmm7",0x55);
-+	&vpshufd	("xmm6","xmm7",0xaa);
-+	&vpshufd	("xmm7","xmm7",0xff);
-+	&vmovdqa	(&QWP(16*8-128,"ebp"),"xmm0");
-+	&vmovdqa	(&QWP(16*9-128,"ebp"),"xmm1");
-+	&vmovdqa	(&QWP(16*10-128,"ebp"),"xmm2");
-+	&vmovdqa	(&QWP(16*11-128,"ebp"),"xmm3");
-+	&vmovdqa	(&QWP(16*0-128,"ebp"),"xmm4");
-+	&vmovdqa	(&QWP(16*1-128,"ebp"),"xmm5");
-+	&vmovdqa	(&QWP(16*2-128,"ebp"),"xmm6");
-+	&vmovdqa	(&QWP(16*3-128,"ebp"),"xmm7");
-+
-+	&lea		($inp,&DWP(128,$inp));		# size optimization
-+	&lea		($out,&DWP(128,$out));		# size optimization
-+	&jmp		(&label("outer_loop"));
-+
-+&set_label("outer_loop",32);
-+	#&vmovdqa	("xmm0",&QWP(16*0-128,"ebp"));	# copy key material
-+	&vmovdqa	("xmm1",&QWP(16*1-128,"ebp"));
-+	&vmovdqa	("xmm2",&QWP(16*2-128,"ebp"));
-+	&vmovdqa	("xmm3",&QWP(16*3-128,"ebp"));
-+	#&vmovdqa	("xmm4",&QWP(16*4-128,"ebp"));
-+	&vmovdqa	("xmm5",&QWP(16*5-128,"ebp"));
-+	&vmovdqa	("xmm6",&QWP(16*6-128,"ebp"));
-+	&vmovdqa	("xmm7",&QWP(16*7-128,"ebp"));
-+	#&vmovdqa	(&QWP(16*0-128,"ebx"),"xmm0");
-+	&vmovdqa	(&QWP(16*1-128,"ebx"),"xmm1");
-+	&vmovdqa	(&QWP(16*2-128,"ebx"),"xmm2");
-+	&vmovdqa	(&QWP(16*3-128,"ebx"),"xmm3");
-+	#&vmovdqa	(&QWP(16*4-128,"ebx"),"xmm4");
-+	&vmovdqa	(&QWP(16*5-128,"ebx"),"xmm5");
-+	&vmovdqa	(&QWP(16*6-128,"ebx"),"xmm6");
-+	&vmovdqa	(&QWP(16*7-128,"ebx"),"xmm7");
-+	#&vmovdqa	("xmm0",&QWP(16*8-128,"ebp"));
-+	#&vmovdqa	("xmm1",&QWP(16*9-128,"ebp"));
-+	&vmovdqa	("xmm2",&QWP(16*10-128,"ebp"));
-+	&vmovdqa	("xmm3",&QWP(16*11-128,"ebp"));
-+	&vmovdqa	("xmm4",&QWP(16*12-128,"ebp"));
-+	&vmovdqa	("xmm5",&QWP(16*13-128,"ebp"));
-+	&vmovdqa	("xmm6",&QWP(16*14-128,"ebp"));
-+	&vmovdqa	("xmm7",&QWP(16*15-128,"ebp"));
-+	&vpaddd		("xmm4","xmm4",&QWP(16*4,"eax"));	# counter value
-+	#&vmovdqa	(&QWP(16*8-128,"ebx"),"xmm0");
-+	#&vmovdqa	(&QWP(16*9-128,"ebx"),"xmm1");
-+	&vmovdqa	(&QWP(16*10-128,"ebx"),"xmm2");
-+	&vmovdqa	(&QWP(16*11-128,"ebx"),"xmm3");
-+	&vmovdqa	(&QWP(16*12-128,"ebx"),"xmm4");
-+	&vmovdqa	(&QWP(16*13-128,"ebx"),"xmm5");
-+	&vmovdqa	(&QWP(16*14-128,"ebx"),"xmm6");
-+	&vmovdqa	(&QWP(16*15-128,"ebx"),"xmm7");
-+	&vmovdqa	(&QWP(16*12-128,"ebp"),"xmm4");	# save counter value
-+
-+	&vmovdqa	($xa, &QWP(16*0-128,"ebp"));
-+	&vmovdqa	($xd, "xmm4");
-+	&vmovdqa	($xb_,&QWP(16*4-128,"ebp"));
-+	&vmovdqa	($xc, &QWP(16*8-128,"ebp"));
-+	&vmovdqa	($xc_,&QWP(16*9-128,"ebp"));
-+
-+	&mov		("edx",10);			# loop counter
-+	&nop		();
-+
-+&set_label("loop",32);
-+	&vpaddd		($xa,$xa,$xb_);			# elsewhere
-+	&vpxor		($xd,$xd,$xa);			# elsewhere
-+	&QUARTERROUND_XOP(0, 4, 8, 12, 0);
-+	&QUARTERROUND_XOP(1, 5, 9, 13, 1);
-+	&QUARTERROUND_XOP(2, 6,10, 14, 2);
-+	&QUARTERROUND_XOP(3, 7,11, 15, 3);
-+	&QUARTERROUND_XOP(0, 5,10, 15, 4);
-+	&QUARTERROUND_XOP(1, 6,11, 12, 5);
-+	&QUARTERROUND_XOP(2, 7, 8, 13, 6);
-+	&QUARTERROUND_XOP(3, 4, 9, 14, 7);
-+	&dec		("edx");
-+	&jnz		(&label("loop"));
-+
-+	&vmovdqa	(&QWP(16*4-128,"ebx"),$xb_);
-+	&vmovdqa	(&QWP(16*8-128,"ebx"),$xc);
-+	&vmovdqa	(&QWP(16*9-128,"ebx"),$xc_);
-+	&vmovdqa	(&QWP(16*12-128,"ebx"),$xd);
-+	&vmovdqa	(&QWP(16*14-128,"ebx"),$xd_);
-+
-+    my ($xa0,$xa1,$xa2,$xa3,$xt0,$xt1,$xt2,$xt3)=map("xmm$_",(0..7));
-+
-+	#&vmovdqa	($xa0,&QWP(16*0-128,"ebx"));	# it's there
-+	&vmovdqa	($xa1,&QWP(16*1-128,"ebx"));
-+	&vmovdqa	($xa2,&QWP(16*2-128,"ebx"));
-+	&vmovdqa	($xa3,&QWP(16*3-128,"ebx"));
-+
-+    for($i=0;$i<256;$i+=64) {
-+	&vpaddd		($xa0,$xa0,&QWP($i+16*0-128,"ebp"));	# accumulate key material
-+	&vpaddd		($xa1,$xa1,&QWP($i+16*1-128,"ebp"));
-+	&vpaddd		($xa2,$xa2,&QWP($i+16*2-128,"ebp"));
-+	&vpaddd		($xa3,$xa3,&QWP($i+16*3-128,"ebp"));
-+
-+	&vpunpckldq	($xt2,$xa0,$xa1);	# "de-interlace" data
-+	&vpunpckldq	($xt3,$xa2,$xa3);
-+	&vpunpckhdq	($xa0,$xa0,$xa1);
-+	&vpunpckhdq	($xa2,$xa2,$xa3);
-+	&vpunpcklqdq	($xa1,$xt2,$xt3);	# "a0"
-+	&vpunpckhqdq	($xt2,$xt2,$xt3);	# "a1"
-+	&vpunpcklqdq	($xt3,$xa0,$xa2);	# "a2"
-+	&vpunpckhqdq	($xa3,$xa0,$xa2);	# "a3"
-+
-+	&vpxor		($xt0,$xa1,&QWP(64*0-128,$inp));
-+	&vpxor		($xt1,$xt2,&QWP(64*1-128,$inp));
-+	&vpxor		($xt2,$xt3,&QWP(64*2-128,$inp));
-+	&vpxor		($xt3,$xa3,&QWP(64*3-128,$inp));
-+	&lea		($inp,&QWP($i<192?16:(64*4-16*3),$inp));
-+	&vmovdqa	($xa0,&QWP($i+16*4-128,"ebx"))	if ($i<192);
-+	&vmovdqa	($xa1,&QWP($i+16*5-128,"ebx"))	if ($i<192);
-+	&vmovdqa	($xa2,&QWP($i+16*6-128,"ebx"))	if ($i<192);
-+	&vmovdqa	($xa3,&QWP($i+16*7-128,"ebx"))	if ($i<192);
-+	&vmovdqu	(&QWP(64*0-128,$out),$xt0);	# store output
-+	&vmovdqu	(&QWP(64*1-128,$out),$xt1);
-+	&vmovdqu	(&QWP(64*2-128,$out),$xt2);
-+	&vmovdqu	(&QWP(64*3-128,$out),$xt3);
-+	&lea		($out,&QWP($i<192?16:(64*4-16*3),$out));
-+    }
-+	&sub		($len,64*4);
-+	&jnc		(&label("outer_loop"));
-+
-+	&add		($len,64*4);
-+	&jz		(&label("done"));
-+
-+	&mov		("ebx",&DWP(512+8,"esp"));	# restore pointers
-+	&lea		($inp,&DWP(-128,$inp));
-+	&mov		("edx",&DWP(512+4,"esp"));
-+	&lea		($out,&DWP(-128,$out));
-+
-+	&vmovd		("xmm2",&DWP(16*12-128,"ebp"));	# counter value
-+	&vmovdqu	("xmm3",&QWP(0,"ebx"));
-+	&vpaddd		("xmm2","xmm2",&QWP(16*6,"eax"));# +four
-+	&vpand		("xmm3","xmm3",&QWP(16*7,"eax"));
-+	&vpor		("xmm3","xmm3","xmm2");		# counter value
-+{
-+my ($a,$b,$c,$d,$t,$t1,$rot16,$rot24)=map("xmm$_",(0..7));
-+
-+sub XOPROUND {
-+	&vpaddd		($a,$a,$b);
-+	&vpxor		($d,$d,$a);
-+	&vprotd		($d,$d,16);
-+
-+	&vpaddd		($c,$c,$d);
-+	&vpxor		($b,$b,$c);
-+	&vprotd		($b,$b,12);
-+
-+	&vpaddd		($a,$a,$b);
-+	&vpxor		($d,$d,$a);
-+	&vprotd		($d,$d,8);
-+
-+	&vpaddd		($c,$c,$d);
-+	&vpxor		($b,$b,$c);
-+	&vprotd		($b,$b,7);
-+}
-+
-+&set_label("1x");
-+	&vmovdqa	($a,&QWP(16*2,"eax"));		# sigma
-+	&vmovdqu	($b,&QWP(0,"edx"));
-+	&vmovdqu	($c,&QWP(16,"edx"));
-+	#&vmovdqu	($d,&QWP(0,"ebx"));		# already loaded
-+	&vmovdqa	($rot16,&QWP(0,"eax"));
-+	&vmovdqa	($rot24,&QWP(16,"eax"));
-+	&mov		(&DWP(16*3,"esp"),"ebp");
-+
-+	&vmovdqa	(&QWP(16*0,"esp"),$a);
-+	&vmovdqa	(&QWP(16*1,"esp"),$b);
-+	&vmovdqa	(&QWP(16*2,"esp"),$c);
-+	&vmovdqa	(&QWP(16*3,"esp"),$d);
-+	&mov		("edx",10);
-+	&jmp		(&label("loop1x"));
-+
-+&set_label("outer1x",16);
-+	&vmovdqa	($d,&QWP(16*5,"eax"));		# one
-+	&vmovdqa	($a,&QWP(16*0,"esp"));
-+	&vmovdqa	($b,&QWP(16*1,"esp"));
-+	&vmovdqa	($c,&QWP(16*2,"esp"));
-+	&vpaddd		($d,$d,&QWP(16*3,"esp"));
-+	&mov		("edx",10);
-+	&vmovdqa	(&QWP(16*3,"esp"),$d);
-+	&jmp		(&label("loop1x"));
-+
-+&set_label("loop1x",16);
-+	&XOPROUND();
-+	&vpshufd	($c,$c,0b01001110);
-+	&vpshufd	($b,$b,0b00111001);
-+	&vpshufd	($d,$d,0b10010011);
-+
-+	&XOPROUND();
-+	&vpshufd	($c,$c,0b01001110);
-+	&vpshufd	($b,$b,0b10010011);
-+	&vpshufd	($d,$d,0b00111001);
-+
-+	&dec		("edx");
-+	&jnz		(&label("loop1x"));
-+
-+	&vpaddd		($a,$a,&QWP(16*0,"esp"));
-+	&vpaddd		($b,$b,&QWP(16*1,"esp"));
-+	&vpaddd		($c,$c,&QWP(16*2,"esp"));
-+	&vpaddd		($d,$d,&QWP(16*3,"esp"));
-+
-+	&cmp		($len,64);
-+	&jb		(&label("tail"));
-+
-+	&vpxor		($a,$a,&QWP(16*0,$inp));	# xor with input
-+	&vpxor		($b,$b,&QWP(16*1,$inp));
-+	&vpxor		($c,$c,&QWP(16*2,$inp));
-+	&vpxor		($d,$d,&QWP(16*3,$inp));
-+	&lea		($inp,&DWP(16*4,$inp));		# inp+=64
-+
-+	&vmovdqu	(&QWP(16*0,$out),$a);		# write output
-+	&vmovdqu	(&QWP(16*1,$out),$b);
-+	&vmovdqu	(&QWP(16*2,$out),$c);
-+	&vmovdqu	(&QWP(16*3,$out),$d);
-+	&lea		($out,&DWP(16*4,$out));		# inp+=64
-+
-+	&sub		($len,64);
-+	&jnz		(&label("outer1x"));
-+
-+	&jmp		(&label("done"));
-+
-+&set_label("tail");
-+	&vmovdqa	(&QWP(16*0,"esp"),$a);
-+	&vmovdqa	(&QWP(16*1,"esp"),$b);
-+	&vmovdqa	(&QWP(16*2,"esp"),$c);
-+	&vmovdqa	(&QWP(16*3,"esp"),$d);
-+
-+	&xor		("eax","eax");
-+	&xor		("edx","edx");
-+	&xor		("ebp","ebp");
-+
-+&set_label("tail_loop");
-+	&movb		("al",&BP(0,"esp","ebp"));
-+	&movb		("dl",&BP(0,$inp,"ebp"));
-+	&lea		("ebp",&DWP(1,"ebp"));
-+	&xor		("al","dl");
-+	&movb		(&BP(-1,$out,"ebp"),"al");
-+	&dec		($len);
-+	&jnz		(&label("tail_loop"));
-+}
-+&set_label("done");
-+	&vzeroupper	();
-+	&mov		("esp",&DWP(512,"esp"));
-+&function_end("ChaCha20_xop");
-+}
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-x86_64.pl
-new file mode 100755
-index 0000000..347dfcb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/asm/chacha-x86_64.pl
-@@ -0,0 +1,2245 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# November 2014
-+#
-+# ChaCha20 for x86_64.
-+#
-+# Performance in cycles per byte out of large buffer.
-+#
-+#		IALU/gcc 4.8(i)	1xSSSE3/SSE2	4xSSSE3	    8xAVX2
-+#
-+# P4		9.48/+99%	-/22.7(ii)	-
-+# Core2		7.83/+55%	7.90/8.08	4.35
-+# Westmere	7.19/+50%	5.60/6.70	3.00
-+# Sandy Bridge	8.31/+42%	5.45/6.76	2.72
-+# Ivy Bridge	6.71/+46%	5.40/6.49	2.41
-+# Haswell	5.92/+43%	5.20/6.45	2.42	    1.23
-+# Silvermont	12.0/+33%	7.75/7.40	7.03(iii)
-+# Goldmont	10.6/+17%	5.10/-		3.28
-+# Sledgehammer	7.28/+52%	-/14.2(ii)	-
-+# Bulldozer	9.66/+28%	9.85/11.1	3.06(iv)
-+# VIA Nano	10.5/+46%	6.72/8.60	6.05
-+#
-+# (i)	compared to older gcc 3.x one can observe >2x improvement on
-+#	most platforms;
-+# (ii)	as it can be seen, SSE2 performance is too low on legacy
-+#	processors; NxSSE2 results are naturally better, but not
-+#	impressively better than IALU ones, which is why you won't
-+#	find SSE2 code below;
-+# (iii)	this is not optimal result for Atom because of MSROM
-+#	limitations, SSE2 can do better, but gain is considered too
-+#	low to justify the [maintenance] effort;
-+# (iv)	Bulldozer actually executes 4xXOP code path that delivers 2.20;
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	   `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+# input parameter block
-+($out,$inp,$len,$key,$counter)=("%rdi","%rsi","%rdx","%rcx","%r8");
-+
-+$code.=<<___;
-+.text
-+
-+.extern OPENSSL_ia32cap_P
-+
-+.align	64
-+.Lzero:
-+.long	0,0,0,0
-+.Lone:
-+.long	1,0,0,0
-+.Linc:
-+.long	0,1,2,3
-+.Lfour:
-+.long	4,4,4,4
-+.Lincy:
-+.long	0,2,4,6,1,3,5,7
-+.Leight:
-+.long	8,8,8,8,8,8,8,8
-+.Lrot16:
-+.byte	0x2,0x3,0x0,0x1, 0x6,0x7,0x4,0x5, 0xa,0xb,0x8,0x9, 0xe,0xf,0xc,0xd
-+.Lrot24:
-+.byte	0x3,0x0,0x1,0x2, 0x7,0x4,0x5,0x6, 0xb,0x8,0x9,0xa, 0xf,0xc,0xd,0xe
-+.Lsigma:
-+.asciz	"expand 32-byte k"
-+.asciz	"ChaCha20 for x86_64, CRYPTOGAMS by "
-+___
-+
-+sub AUTOLOAD()          # thunk [simplified] 32-bit style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
-+  my $arg = pop;
-+    $arg = "\$$arg" if ($arg*1 eq $arg);
-+    $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
-+}
-+
-+@x=("%eax","%ebx","%ecx","%edx",map("%r${_}d",(8..11)),
-+    "%nox","%nox","%nox","%nox",map("%r${_}d",(12..15)));
-+@t=("%esi","%edi");
-+
-+sub ROUND {			# critical path is 24 cycles per round
-+my ($a0,$b0,$c0,$d0)=@_;
-+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
-+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
-+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
-+my ($xc,$xc_)=map("\"$_\"",@t);
-+my @x=map("\"$_\"",@x);
-+
-+	# Consider order in which variables are addressed by their
-+	# index:
-+	#
-+	#	a   b   c   d
-+	#
-+	#	0   4   8  12 < even round
-+	#	1   5   9  13
-+	#	2   6  10  14
-+	#	3   7  11  15
-+	#	0   5  10  15 < odd round
-+	#	1   6  11  12
-+	#	2   7   8  13
-+	#	3   4   9  14
-+	#
-+	# 'a', 'b' and 'd's are permanently allocated in registers,
-+	# @x[0..7,12..15], while 'c's are maintained in memory. If
-+	# you observe 'c' column, you'll notice that pair of 'c's is
-+	# invariant between rounds. This means that we have to reload
-+	# them once per round, in the middle. This is why you'll see
-+	# bunch of 'c' stores and loads in the middle, but none in
-+	# the beginning or end.
-+
-+	# Normally instructions would be interleaved to favour in-order
-+	# execution. Generally out-of-order cores manage it gracefully,
-+	# but not this time for some reason. As in-order execution
-+	# cores are dying breed, old Atom is the only one around,
-+	# instructions are left uninterleaved. Besides, Atom is better
-+	# off executing 1xSSSE3 code anyway...
-+
-+	(
-+	"&add	(@x[$a0],@x[$b0])",	# Q1
-+	"&xor	(@x[$d0],@x[$a0])",
-+	"&rol	(@x[$d0],16)",
-+	 "&add	(@x[$a1],@x[$b1])",	# Q2
-+	 "&xor	(@x[$d1],@x[$a1])",
-+	 "&rol	(@x[$d1],16)",
-+
-+	"&add	($xc,@x[$d0])",
-+	"&xor	(@x[$b0],$xc)",
-+	"&rol	(@x[$b0],12)",
-+	 "&add	($xc_,@x[$d1])",
-+	 "&xor	(@x[$b1],$xc_)",
-+	 "&rol	(@x[$b1],12)",
-+
-+	"&add	(@x[$a0],@x[$b0])",
-+	"&xor	(@x[$d0],@x[$a0])",
-+	"&rol	(@x[$d0],8)",
-+	 "&add	(@x[$a1],@x[$b1])",
-+	 "&xor	(@x[$d1],@x[$a1])",
-+	 "&rol	(@x[$d1],8)",
-+
-+	"&add	($xc,@x[$d0])",
-+	"&xor	(@x[$b0],$xc)",
-+	"&rol	(@x[$b0],7)",
-+	 "&add	($xc_,@x[$d1])",
-+	 "&xor	(@x[$b1],$xc_)",
-+	 "&rol	(@x[$b1],7)",
-+
-+	"&mov	(\"4*$c0(%rsp)\",$xc)",	# reload pair of 'c's
-+	 "&mov	(\"4*$c1(%rsp)\",$xc_)",
-+	"&mov	($xc,\"4*$c2(%rsp)\")",
-+	 "&mov	($xc_,\"4*$c3(%rsp)\")",
-+
-+	"&add	(@x[$a2],@x[$b2])",	# Q3
-+	"&xor	(@x[$d2],@x[$a2])",
-+	"&rol	(@x[$d2],16)",
-+	 "&add	(@x[$a3],@x[$b3])",	# Q4
-+	 "&xor	(@x[$d3],@x[$a3])",
-+	 "&rol	(@x[$d3],16)",
-+
-+	"&add	($xc,@x[$d2])",
-+	"&xor	(@x[$b2],$xc)",
-+	"&rol	(@x[$b2],12)",
-+	 "&add	($xc_,@x[$d3])",
-+	 "&xor	(@x[$b3],$xc_)",
-+	 "&rol	(@x[$b3],12)",
-+
-+	"&add	(@x[$a2],@x[$b2])",
-+	"&xor	(@x[$d2],@x[$a2])",
-+	"&rol	(@x[$d2],8)",
-+	 "&add	(@x[$a3],@x[$b3])",
-+	 "&xor	(@x[$d3],@x[$a3])",
-+	 "&rol	(@x[$d3],8)",
-+
-+	"&add	($xc,@x[$d2])",
-+	"&xor	(@x[$b2],$xc)",
-+	"&rol	(@x[$b2],7)",
-+	 "&add	($xc_,@x[$d3])",
-+	 "&xor	(@x[$b3],$xc_)",
-+	 "&rol	(@x[$b3],7)"
-+	);
-+}
-+
-+########################################################################
-+# Generic code path that handles all lengths on pre-SSSE3 processors.
-+$code.=<<___;
-+.globl	ChaCha20_ctr32
-+.type	ChaCha20_ctr32,\@function,5
-+.align	64
-+ChaCha20_ctr32:
-+	cmp	\$0,$len
-+	je	.Lno_data
-+	mov	OPENSSL_ia32cap_P+4(%rip),%r10
-+	test	\$`1<<(41-32)`,%r10d
-+	jnz	.LChaCha20_ssse3
-+
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	sub	\$64+24,%rsp
-+
-+	#movdqa	.Lsigma(%rip),%xmm0
-+	movdqu	($key),%xmm1
-+	movdqu	16($key),%xmm2
-+	movdqu	($counter),%xmm3
-+	movdqa	.Lone(%rip),%xmm4
-+
-+	#movdqa	%xmm0,4*0(%rsp)		# key[0]
-+	movdqa	%xmm1,4*4(%rsp)		# key[1]
-+	movdqa	%xmm2,4*8(%rsp)		# key[2]
-+	movdqa	%xmm3,4*12(%rsp)	# key[3]
-+	mov	$len,%rbp		# reassign $len
-+	jmp	.Loop_outer
-+
-+.align	32
-+.Loop_outer:
-+	mov	\$0x61707865,@x[0]      # 'expa'
-+	mov	\$0x3320646e,@x[1]      # 'nd 3'
-+	mov	\$0x79622d32,@x[2]      # '2-by'
-+	mov	\$0x6b206574,@x[3]      # 'te k'
-+	mov	4*4(%rsp),@x[4]
-+	mov	4*5(%rsp),@x[5]
-+	mov	4*6(%rsp),@x[6]
-+	mov	4*7(%rsp),@x[7]
-+	movd	%xmm3,@x[12]
-+	mov	4*13(%rsp),@x[13]
-+	mov	4*14(%rsp),@x[14]
-+	mov	4*15(%rsp),@x[15]
-+
-+	mov	%rbp,64+0(%rsp)		# save len
-+	mov	\$10,%ebp
-+	mov	$inp,64+8(%rsp)		# save inp
-+	movq	%xmm2,%rsi		# "@x[8]"
-+	mov	$out,64+16(%rsp)	# save out
-+	mov	%rsi,%rdi
-+	shr	\$32,%rdi		# "@x[9]"
-+	jmp	.Loop
-+
-+.align	32
-+.Loop:
-+___
-+	foreach (&ROUND (0, 4, 8,12)) { eval; }
-+	foreach (&ROUND	(0, 5,10,15)) { eval; }
-+	&dec	("%ebp");
-+	&jnz	(".Loop");
-+
-+$code.=<<___;
-+	mov	@t[1],4*9(%rsp)		# modulo-scheduled
-+	mov	@t[0],4*8(%rsp)
-+	mov	64(%rsp),%rbp		# load len
-+	movdqa	%xmm2,%xmm1
-+	mov	64+8(%rsp),$inp		# load inp
-+	paddd	%xmm4,%xmm3		# increment counter
-+	mov	64+16(%rsp),$out	# load out
-+
-+	add	\$0x61707865,@x[0]      # 'expa'
-+	add	\$0x3320646e,@x[1]      # 'nd 3'
-+	add	\$0x79622d32,@x[2]      # '2-by'
-+	add	\$0x6b206574,@x[3]      # 'te k'
-+	add	4*4(%rsp),@x[4]
-+	add	4*5(%rsp),@x[5]
-+	add	4*6(%rsp),@x[6]
-+	add	4*7(%rsp),@x[7]
-+	add	4*12(%rsp),@x[12]
-+	add	4*13(%rsp),@x[13]
-+	add	4*14(%rsp),@x[14]
-+	add	4*15(%rsp),@x[15]
-+	paddd	4*8(%rsp),%xmm1
-+
-+	cmp	\$64,%rbp
-+	jb	.Ltail
-+
-+	xor	4*0($inp),@x[0]		# xor with input
-+	xor	4*1($inp),@x[1]
-+	xor	4*2($inp),@x[2]
-+	xor	4*3($inp),@x[3]
-+	xor	4*4($inp),@x[4]
-+	xor	4*5($inp),@x[5]
-+	xor	4*6($inp),@x[6]
-+	xor	4*7($inp),@x[7]
-+	movdqu	4*8($inp),%xmm0
-+	xor	4*12($inp),@x[12]
-+	xor	4*13($inp),@x[13]
-+	xor	4*14($inp),@x[14]
-+	xor	4*15($inp),@x[15]
-+	lea	4*16($inp),$inp		# inp+=64
-+	pxor	%xmm1,%xmm0
-+
-+	movdqa	%xmm2,4*8(%rsp)
-+	movd	%xmm3,4*12(%rsp)
-+
-+	mov	@x[0],4*0($out)		# write output
-+	mov	@x[1],4*1($out)
-+	mov	@x[2],4*2($out)
-+	mov	@x[3],4*3($out)
-+	mov	@x[4],4*4($out)
-+	mov	@x[5],4*5($out)
-+	mov	@x[6],4*6($out)
-+	mov	@x[7],4*7($out)
-+	movdqu	%xmm0,4*8($out)
-+	mov	@x[12],4*12($out)
-+	mov	@x[13],4*13($out)
-+	mov	@x[14],4*14($out)
-+	mov	@x[15],4*15($out)
-+	lea	4*16($out),$out		# out+=64
-+
-+	sub	\$64,%rbp
-+	jnz	.Loop_outer
-+
-+	jmp	.Ldone
-+
-+.align	16
-+.Ltail:
-+	mov	@x[0],4*0(%rsp)
-+	mov	@x[1],4*1(%rsp)
-+	xor	%rbx,%rbx
-+	mov	@x[2],4*2(%rsp)
-+	mov	@x[3],4*3(%rsp)
-+	mov	@x[4],4*4(%rsp)
-+	mov	@x[5],4*5(%rsp)
-+	mov	@x[6],4*6(%rsp)
-+	mov	@x[7],4*7(%rsp)
-+	movdqa	%xmm1,4*8(%rsp)
-+	mov	@x[12],4*12(%rsp)
-+	mov	@x[13],4*13(%rsp)
-+	mov	@x[14],4*14(%rsp)
-+	mov	@x[15],4*15(%rsp)
-+
-+.Loop_tail:
-+	movzb	($inp,%rbx),%eax
-+	movzb	(%rsp,%rbx),%edx
-+	lea	1(%rbx),%rbx
-+	xor	%edx,%eax
-+	mov	%al,-1($out,%rbx)
-+	dec	%rbp
-+	jnz	.Loop_tail
-+
-+.Ldone:
-+	add	\$64+24,%rsp
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+.Lno_data:
-+	ret
-+.size	ChaCha20_ctr32,.-ChaCha20_ctr32
-+___
-+
-+########################################################################
-+# SSSE3 code path that handles shorter lengths
-+{
-+my ($a,$b,$c,$d,$t,$t1,$rot16,$rot24)=map("%xmm$_",(0..7));
-+
-+sub SSSE3ROUND {	# critical path is 20 "SIMD ticks" per round
-+	&paddd	($a,$b);
-+	&pxor	($d,$a);
-+	&pshufb	($d,$rot16);
-+
-+	&paddd	($c,$d);
-+	&pxor	($b,$c);
-+	&movdqa	($t,$b);
-+	&psrld	($b,20);
-+	&pslld	($t,12);
-+	&por	($b,$t);
-+
-+	&paddd	($a,$b);
-+	&pxor	($d,$a);
-+	&pshufb	($d,$rot24);
-+
-+	&paddd	($c,$d);
-+	&pxor	($b,$c);
-+	&movdqa	($t,$b);
-+	&psrld	($b,25);
-+	&pslld	($t,7);
-+	&por	($b,$t);
-+}
-+
-+my $xframe = $win64 ? 32+32+8 : 24;
-+
-+$code.=<<___;
-+.type	ChaCha20_ssse3,\@function,5
-+.align	32
-+ChaCha20_ssse3:
-+.LChaCha20_ssse3:
-+___
-+$code.=<<___	if ($avx);
-+	test	\$`1<<(43-32)`,%r10d
-+	jnz	.LChaCha20_4xop		# XOP is fastest even if we use 1/4
-+___
-+$code.=<<___;
-+	cmp	\$128,$len		# we might throw away some data,
-+	ja	.LChaCha20_4x		# but overall it won't be slower
-+
-+.Ldo_sse3_after_all:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	sub	\$64+$xframe,%rsp
-+___
-+$code.=<<___	if ($win64);
-+	movaps	%xmm6,64+32(%rsp)
-+	movaps	%xmm7,64+48(%rsp)
-+___
-+$code.=<<___;
-+	movdqa	.Lsigma(%rip),$a
-+	movdqu	($key),$b
-+	movdqu	16($key),$c
-+	movdqu	($counter),$d
-+	movdqa	.Lrot16(%rip),$rot16
-+	movdqa	.Lrot24(%rip),$rot24
-+
-+	movdqa	$a,0x00(%rsp)
-+	movdqa	$b,0x10(%rsp)
-+	movdqa	$c,0x20(%rsp)
-+	movdqa	$d,0x30(%rsp)
-+	mov	\$10,%ebp
-+	jmp	.Loop_ssse3
-+
-+.align	32
-+.Loop_outer_ssse3:
-+	movdqa	.Lone(%rip),$d
-+	movdqa	0x00(%rsp),$a
-+	movdqa	0x10(%rsp),$b
-+	movdqa	0x20(%rsp),$c
-+	paddd	0x30(%rsp),$d
-+	mov	\$10,%ebp
-+	movdqa	$d,0x30(%rsp)
-+	jmp	.Loop_ssse3
-+
-+.align	32
-+.Loop_ssse3:
-+___
-+	&SSSE3ROUND();
-+	&pshufd	($c,$c,0b01001110);
-+	&pshufd	($b,$b,0b00111001);
-+	&pshufd	($d,$d,0b10010011);
-+	&nop	();
-+
-+	&SSSE3ROUND();
-+	&pshufd	($c,$c,0b01001110);
-+	&pshufd	($b,$b,0b10010011);
-+	&pshufd	($d,$d,0b00111001);
-+
-+	&dec	("%ebp");
-+	&jnz	(".Loop_ssse3");
-+
-+$code.=<<___;
-+	paddd	0x00(%rsp),$a
-+	paddd	0x10(%rsp),$b
-+	paddd	0x20(%rsp),$c
-+	paddd	0x30(%rsp),$d
-+
-+	cmp	\$64,$len
-+	jb	.Ltail_ssse3
-+
-+	movdqu	0x00($inp),$t
-+	movdqu	0x10($inp),$t1
-+	pxor	$t,$a			# xor with input
-+	movdqu	0x20($inp),$t
-+	pxor	$t1,$b
-+	movdqu	0x30($inp),$t1
-+	lea	0x40($inp),$inp		# inp+=64
-+	pxor	$t,$c
-+	pxor	$t1,$d
-+
-+	movdqu	$a,0x00($out)		# write output
-+	movdqu	$b,0x10($out)
-+	movdqu	$c,0x20($out)
-+	movdqu	$d,0x30($out)
-+	lea	0x40($out),$out		# out+=64
-+
-+	sub	\$64,$len
-+	jnz	.Loop_outer_ssse3
-+
-+	jmp	.Ldone_ssse3
-+
-+.align	16
-+.Ltail_ssse3:
-+	movdqa	$a,0x00(%rsp)
-+	movdqa	$b,0x10(%rsp)
-+	movdqa	$c,0x20(%rsp)
-+	movdqa	$d,0x30(%rsp)
-+	xor	%rbx,%rbx
-+
-+.Loop_tail_ssse3:
-+	movzb	($inp,%rbx),%eax
-+	movzb	(%rsp,%rbx),%ecx
-+	lea	1(%rbx),%rbx
-+	xor	%ecx,%eax
-+	mov	%al,-1($out,%rbx)
-+	dec	$len
-+	jnz	.Loop_tail_ssse3
-+
-+.Ldone_ssse3:
-+___
-+$code.=<<___	if ($win64);
-+	movaps	64+32(%rsp),%xmm6
-+	movaps	64+48(%rsp),%xmm7
-+___
-+$code.=<<___;
-+	add	\$64+$xframe,%rsp
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	ret
-+.size	ChaCha20_ssse3,.-ChaCha20_ssse3
-+___
-+}
-+
-+########################################################################
-+# SSSE3 code path that handles longer messages.
-+{
-+# assign variables to favor Atom front-end
-+my ($xd0,$xd1,$xd2,$xd3, $xt0,$xt1,$xt2,$xt3,
-+    $xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3)=map("%xmm$_",(0..15));
-+my  @xx=($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3,
-+	"%nox","%nox","%nox","%nox", $xd0,$xd1,$xd2,$xd3);
-+
-+sub SSSE3_lane_ROUND {
-+my ($a0,$b0,$c0,$d0)=@_;
-+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
-+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
-+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
-+my ($xc,$xc_,$t0,$t1)=map("\"$_\"",$xt0,$xt1,$xt2,$xt3);
-+my @x=map("\"$_\"",@xx);
-+
-+	# Consider order in which variables are addressed by their
-+	# index:
-+	#
-+	#	a   b   c   d
-+	#
-+	#	0   4   8  12 < even round
-+	#	1   5   9  13
-+	#	2   6  10  14
-+	#	3   7  11  15
-+	#	0   5  10  15 < odd round
-+	#	1   6  11  12
-+	#	2   7   8  13
-+	#	3   4   9  14
-+	#
-+	# 'a', 'b' and 'd's are permanently allocated in registers,
-+	# @x[0..7,12..15], while 'c's are maintained in memory. If
-+	# you observe 'c' column, you'll notice that pair of 'c's is
-+	# invariant between rounds. This means that we have to reload
-+	# them once per round, in the middle. This is why you'll see
-+	# bunch of 'c' stores and loads in the middle, but none in
-+	# the beginning or end.
-+
-+	(
-+	"&paddd		(@x[$a0],@x[$b0])",	# Q1
-+	 "&paddd	(@x[$a1],@x[$b1])",	# Q2
-+	"&pxor		(@x[$d0],@x[$a0])",
-+	 "&pxor		(@x[$d1],@x[$a1])",
-+	"&pshufb	(@x[$d0],$t1)",
-+	 "&pshufb	(@x[$d1],$t1)",
-+
-+	"&paddd		($xc,@x[$d0])",
-+	 "&paddd	($xc_,@x[$d1])",
-+	"&pxor		(@x[$b0],$xc)",
-+	 "&pxor		(@x[$b1],$xc_)",
-+	"&movdqa	($t0,@x[$b0])",
-+	"&pslld		(@x[$b0],12)",
-+	"&psrld		($t0,20)",
-+	 "&movdqa	($t1,@x[$b1])",
-+	 "&pslld	(@x[$b1],12)",
-+	"&por		(@x[$b0],$t0)",
-+	 "&psrld	($t1,20)",
-+	"&movdqa	($t0,'(%r11)')",	# .Lrot24(%rip)
-+	 "&por		(@x[$b1],$t1)",
-+
-+	"&paddd		(@x[$a0],@x[$b0])",
-+	 "&paddd	(@x[$a1],@x[$b1])",
-+	"&pxor		(@x[$d0],@x[$a0])",
-+	 "&pxor		(@x[$d1],@x[$a1])",
-+	"&pshufb	(@x[$d0],$t0)",
-+	 "&pshufb	(@x[$d1],$t0)",
-+
-+	"&paddd		($xc,@x[$d0])",
-+	 "&paddd	($xc_,@x[$d1])",
-+	"&pxor		(@x[$b0],$xc)",
-+	 "&pxor		(@x[$b1],$xc_)",
-+	"&movdqa	($t1,@x[$b0])",
-+	"&pslld		(@x[$b0],7)",
-+	"&psrld		($t1,25)",
-+	 "&movdqa	($t0,@x[$b1])",
-+	 "&pslld	(@x[$b1],7)",
-+	"&por		(@x[$b0],$t1)",
-+	 "&psrld	($t0,25)",
-+	"&movdqa	($t1,'(%r10)')",	# .Lrot16(%rip)
-+	 "&por		(@x[$b1],$t0)",
-+
-+	"&movdqa	(\"`16*($c0-8)`(%rsp)\",$xc)",	# reload pair of 'c's
-+	 "&movdqa	(\"`16*($c1-8)`(%rsp)\",$xc_)",
-+	"&movdqa	($xc,\"`16*($c2-8)`(%rsp)\")",
-+	 "&movdqa	($xc_,\"`16*($c3-8)`(%rsp)\")",
-+
-+	"&paddd		(@x[$a2],@x[$b2])",	# Q3
-+	 "&paddd	(@x[$a3],@x[$b3])",	# Q4
-+	"&pxor		(@x[$d2],@x[$a2])",
-+	 "&pxor		(@x[$d3],@x[$a3])",
-+	"&pshufb	(@x[$d2],$t1)",
-+	 "&pshufb	(@x[$d3],$t1)",
-+
-+	"&paddd		($xc,@x[$d2])",
-+	 "&paddd	($xc_,@x[$d3])",
-+	"&pxor		(@x[$b2],$xc)",
-+	 "&pxor		(@x[$b3],$xc_)",
-+	"&movdqa	($t0,@x[$b2])",
-+	"&pslld		(@x[$b2],12)",
-+	"&psrld		($t0,20)",
-+	 "&movdqa	($t1,@x[$b3])",
-+	 "&pslld	(@x[$b3],12)",
-+	"&por		(@x[$b2],$t0)",
-+	 "&psrld	($t1,20)",
-+	"&movdqa	($t0,'(%r11)')",	# .Lrot24(%rip)
-+	 "&por		(@x[$b3],$t1)",
-+
-+	"&paddd		(@x[$a2],@x[$b2])",
-+	 "&paddd	(@x[$a3],@x[$b3])",
-+	"&pxor		(@x[$d2],@x[$a2])",
-+	 "&pxor		(@x[$d3],@x[$a3])",
-+	"&pshufb	(@x[$d2],$t0)",
-+	 "&pshufb	(@x[$d3],$t0)",
-+
-+	"&paddd		($xc,@x[$d2])",
-+	 "&paddd	($xc_,@x[$d3])",
-+	"&pxor		(@x[$b2],$xc)",
-+	 "&pxor		(@x[$b3],$xc_)",
-+	"&movdqa	($t1,@x[$b2])",
-+	"&pslld		(@x[$b2],7)",
-+	"&psrld		($t1,25)",
-+	 "&movdqa	($t0,@x[$b3])",
-+	 "&pslld	(@x[$b3],7)",
-+	"&por		(@x[$b2],$t1)",
-+	 "&psrld	($t0,25)",
-+	"&movdqa	($t1,'(%r10)')",	# .Lrot16(%rip)
-+	 "&por		(@x[$b3],$t0)"
-+	);
-+}
-+
-+my $xframe = $win64 ? 0xa0 : 0;
-+
-+$code.=<<___;
-+.type	ChaCha20_4x,\@function,5
-+.align	32
-+ChaCha20_4x:
-+.LChaCha20_4x:
-+	mov		%r10,%r11
-+___
-+$code.=<<___	if ($avx>1);
-+	shr		\$32,%r10		# OPENSSL_ia32cap_P+8
-+	test		\$`1<<5`,%r10		# test AVX2
-+	jnz		.LChaCha20_8x
-+___
-+$code.=<<___;
-+	cmp		\$192,$len
-+	ja		.Lproceed4x
-+
-+	and		\$`1<<26|1<<22`,%r11	# isolate XSAVE+MOVBE
-+	cmp		\$`1<<22`,%r11		# check for MOVBE without XSAVE
-+	je		.Ldo_sse3_after_all	# to detect Atom
-+
-+.Lproceed4x:
-+	lea		-0x78(%rsp),%r11
-+	sub		\$0x148+$xframe,%rsp
-+___
-+	################ stack layout
-+	# +0x00		SIMD equivalent of @x[8-12]
-+	# ...
-+	# +0x40		constant copy of key[0-2] smashed by lanes
-+	# ...
-+	# +0x100	SIMD counters (with nonce smashed by lanes)
-+	# ...
-+	# +0x140
-+$code.=<<___	if ($win64);
-+	movaps		%xmm6,-0x30(%r11)
-+	movaps		%xmm7,-0x20(%r11)
-+	movaps		%xmm8,-0x10(%r11)
-+	movaps		%xmm9,0x00(%r11)
-+	movaps		%xmm10,0x10(%r11)
-+	movaps		%xmm11,0x20(%r11)
-+	movaps		%xmm12,0x30(%r11)
-+	movaps		%xmm13,0x40(%r11)
-+	movaps		%xmm14,0x50(%r11)
-+	movaps		%xmm15,0x60(%r11)
-+___
-+$code.=<<___;
-+	movdqa		.Lsigma(%rip),$xa3	# key[0]
-+	movdqu		($key),$xb3		# key[1]
-+	movdqu		16($key),$xt3		# key[2]
-+	movdqu		($counter),$xd3		# key[3]
-+	lea		0x100(%rsp),%rcx	# size optimization
-+	lea		.Lrot16(%rip),%r10
-+	lea		.Lrot24(%rip),%r11
-+
-+	pshufd		\$0x00,$xa3,$xa0	# smash key by lanes...
-+	pshufd		\$0x55,$xa3,$xa1
-+	movdqa		$xa0,0x40(%rsp)		# ... and offload
-+	pshufd		\$0xaa,$xa3,$xa2
-+	movdqa		$xa1,0x50(%rsp)
-+	pshufd		\$0xff,$xa3,$xa3
-+	movdqa		$xa2,0x60(%rsp)
-+	movdqa		$xa3,0x70(%rsp)
-+
-+	pshufd		\$0x00,$xb3,$xb0
-+	pshufd		\$0x55,$xb3,$xb1
-+	movdqa		$xb0,0x80-0x100(%rcx)
-+	pshufd		\$0xaa,$xb3,$xb2
-+	movdqa		$xb1,0x90-0x100(%rcx)
-+	pshufd		\$0xff,$xb3,$xb3
-+	movdqa		$xb2,0xa0-0x100(%rcx)
-+	movdqa		$xb3,0xb0-0x100(%rcx)
-+
-+	pshufd		\$0x00,$xt3,$xt0	# "$xc0"
-+	pshufd		\$0x55,$xt3,$xt1	# "$xc1"
-+	movdqa		$xt0,0xc0-0x100(%rcx)
-+	pshufd		\$0xaa,$xt3,$xt2	# "$xc2"
-+	movdqa		$xt1,0xd0-0x100(%rcx)
-+	pshufd		\$0xff,$xt3,$xt3	# "$xc3"
-+	movdqa		$xt2,0xe0-0x100(%rcx)
-+	movdqa		$xt3,0xf0-0x100(%rcx)
-+
-+	pshufd		\$0x00,$xd3,$xd0
-+	pshufd		\$0x55,$xd3,$xd1
-+	paddd		.Linc(%rip),$xd0	# don't save counters yet
-+	pshufd		\$0xaa,$xd3,$xd2
-+	movdqa		$xd1,0x110-0x100(%rcx)
-+	pshufd		\$0xff,$xd3,$xd3
-+	movdqa		$xd2,0x120-0x100(%rcx)
-+	movdqa		$xd3,0x130-0x100(%rcx)
-+
-+	jmp		.Loop_enter4x
-+
-+.align	32
-+.Loop_outer4x:
-+	movdqa		0x40(%rsp),$xa0		# re-load smashed key
-+	movdqa		0x50(%rsp),$xa1
-+	movdqa		0x60(%rsp),$xa2
-+	movdqa		0x70(%rsp),$xa3
-+	movdqa		0x80-0x100(%rcx),$xb0
-+	movdqa		0x90-0x100(%rcx),$xb1
-+	movdqa		0xa0-0x100(%rcx),$xb2
-+	movdqa		0xb0-0x100(%rcx),$xb3
-+	movdqa		0xc0-0x100(%rcx),$xt0	# "$xc0"
-+	movdqa		0xd0-0x100(%rcx),$xt1	# "$xc1"
-+	movdqa		0xe0-0x100(%rcx),$xt2	# "$xc2"
-+	movdqa		0xf0-0x100(%rcx),$xt3	# "$xc3"
-+	movdqa		0x100-0x100(%rcx),$xd0
-+	movdqa		0x110-0x100(%rcx),$xd1
-+	movdqa		0x120-0x100(%rcx),$xd2
-+	movdqa		0x130-0x100(%rcx),$xd3
-+	paddd		.Lfour(%rip),$xd0	# next SIMD counters
-+
-+.Loop_enter4x:
-+	movdqa		$xt2,0x20(%rsp)		# SIMD equivalent of "@x[10]"
-+	movdqa		$xt3,0x30(%rsp)		# SIMD equivalent of "@x[11]"
-+	movdqa		(%r10),$xt3		# .Lrot16(%rip)
-+	mov		\$10,%eax
-+	movdqa		$xd0,0x100-0x100(%rcx)	# save SIMD counters
-+	jmp		.Loop4x
-+
-+.align	32
-+.Loop4x:
-+___
-+	foreach (&SSSE3_lane_ROUND(0, 4, 8,12)) { eval; }
-+	foreach (&SSSE3_lane_ROUND(0, 5,10,15)) { eval; }
-+$code.=<<___;
-+	dec		%eax
-+	jnz		.Loop4x
-+
-+	paddd		0x40(%rsp),$xa0		# accumulate key material
-+	paddd		0x50(%rsp),$xa1
-+	paddd		0x60(%rsp),$xa2
-+	paddd		0x70(%rsp),$xa3
-+
-+	movdqa		$xa0,$xt2		# "de-interlace" data
-+	punpckldq	$xa1,$xa0
-+	movdqa		$xa2,$xt3
-+	punpckldq	$xa3,$xa2
-+	punpckhdq	$xa1,$xt2
-+	punpckhdq	$xa3,$xt3
-+	movdqa		$xa0,$xa1
-+	punpcklqdq	$xa2,$xa0		# "a0"
-+	movdqa		$xt2,$xa3
-+	punpcklqdq	$xt3,$xt2		# "a2"
-+	punpckhqdq	$xa2,$xa1		# "a1"
-+	punpckhqdq	$xt3,$xa3		# "a3"
-+___
-+	($xa2,$xt2)=($xt2,$xa2);
-+$code.=<<___;
-+	paddd		0x80-0x100(%rcx),$xb0
-+	paddd		0x90-0x100(%rcx),$xb1
-+	paddd		0xa0-0x100(%rcx),$xb2
-+	paddd		0xb0-0x100(%rcx),$xb3
-+
-+	movdqa		$xa0,0x00(%rsp)		# offload $xaN
-+	movdqa		$xa1,0x10(%rsp)
-+	movdqa		0x20(%rsp),$xa0		# "xc2"
-+	movdqa		0x30(%rsp),$xa1		# "xc3"
-+
-+	movdqa		$xb0,$xt2
-+	punpckldq	$xb1,$xb0
-+	movdqa		$xb2,$xt3
-+	punpckldq	$xb3,$xb2
-+	punpckhdq	$xb1,$xt2
-+	punpckhdq	$xb3,$xt3
-+	movdqa		$xb0,$xb1
-+	punpcklqdq	$xb2,$xb0		# "b0"
-+	movdqa		$xt2,$xb3
-+	punpcklqdq	$xt3,$xt2		# "b2"
-+	punpckhqdq	$xb2,$xb1		# "b1"
-+	punpckhqdq	$xt3,$xb3		# "b3"
-+___
-+	($xb2,$xt2)=($xt2,$xb2);
-+	my ($xc0,$xc1,$xc2,$xc3)=($xt0,$xt1,$xa0,$xa1);
-+$code.=<<___;
-+	paddd		0xc0-0x100(%rcx),$xc0
-+	paddd		0xd0-0x100(%rcx),$xc1
-+	paddd		0xe0-0x100(%rcx),$xc2
-+	paddd		0xf0-0x100(%rcx),$xc3
-+
-+	movdqa		$xa2,0x20(%rsp)		# keep offloading $xaN
-+	movdqa		$xa3,0x30(%rsp)
-+
-+	movdqa		$xc0,$xt2
-+	punpckldq	$xc1,$xc0
-+	movdqa		$xc2,$xt3
-+	punpckldq	$xc3,$xc2
-+	punpckhdq	$xc1,$xt2
-+	punpckhdq	$xc3,$xt3
-+	movdqa		$xc0,$xc1
-+	punpcklqdq	$xc2,$xc0		# "c0"
-+	movdqa		$xt2,$xc3
-+	punpcklqdq	$xt3,$xt2		# "c2"
-+	punpckhqdq	$xc2,$xc1		# "c1"
-+	punpckhqdq	$xt3,$xc3		# "c3"
-+___
-+	($xc2,$xt2)=($xt2,$xc2);
-+	($xt0,$xt1)=($xa2,$xa3);		# use $xaN as temporary
-+$code.=<<___;
-+	paddd		0x100-0x100(%rcx),$xd0
-+	paddd		0x110-0x100(%rcx),$xd1
-+	paddd		0x120-0x100(%rcx),$xd2
-+	paddd		0x130-0x100(%rcx),$xd3
-+
-+	movdqa		$xd0,$xt2
-+	punpckldq	$xd1,$xd0
-+	movdqa		$xd2,$xt3
-+	punpckldq	$xd3,$xd2
-+	punpckhdq	$xd1,$xt2
-+	punpckhdq	$xd3,$xt3
-+	movdqa		$xd0,$xd1
-+	punpcklqdq	$xd2,$xd0		# "d0"
-+	movdqa		$xt2,$xd3
-+	punpcklqdq	$xt3,$xt2		# "d2"
-+	punpckhqdq	$xd2,$xd1		# "d1"
-+	punpckhqdq	$xt3,$xd3		# "d3"
-+___
-+	($xd2,$xt2)=($xt2,$xd2);
-+$code.=<<___;
-+	cmp		\$64*4,$len
-+	jb		.Ltail4x
-+
-+	movdqu		0x00($inp),$xt0		# xor with input
-+	movdqu		0x10($inp),$xt1
-+	movdqu		0x20($inp),$xt2
-+	movdqu		0x30($inp),$xt3
-+	pxor		0x00(%rsp),$xt0		# $xaN is offloaded, remember?
-+	pxor		$xb0,$xt1
-+	pxor		$xc0,$xt2
-+	pxor		$xd0,$xt3
-+
-+	 movdqu		$xt0,0x00($out)
-+	movdqu		0x40($inp),$xt0
-+	 movdqu		$xt1,0x10($out)
-+	movdqu		0x50($inp),$xt1
-+	 movdqu		$xt2,0x20($out)
-+	movdqu		0x60($inp),$xt2
-+	 movdqu		$xt3,0x30($out)
-+	movdqu		0x70($inp),$xt3
-+	lea		0x80($inp),$inp		# size optimization
-+	pxor		0x10(%rsp),$xt0
-+	pxor		$xb1,$xt1
-+	pxor		$xc1,$xt2
-+	pxor		$xd1,$xt3
-+
-+	 movdqu		$xt0,0x40($out)
-+	movdqu		0x00($inp),$xt0
-+	 movdqu		$xt1,0x50($out)
-+	movdqu		0x10($inp),$xt1
-+	 movdqu		$xt2,0x60($out)
-+	movdqu		0x20($inp),$xt2
-+	 movdqu		$xt3,0x70($out)
-+	 lea		0x80($out),$out		# size optimization
-+	movdqu		0x30($inp),$xt3
-+	pxor		0x20(%rsp),$xt0
-+	pxor		$xb2,$xt1
-+	pxor		$xc2,$xt2
-+	pxor		$xd2,$xt3
-+
-+	 movdqu		$xt0,0x00($out)
-+	movdqu		0x40($inp),$xt0
-+	 movdqu		$xt1,0x10($out)
-+	movdqu		0x50($inp),$xt1
-+	 movdqu		$xt2,0x20($out)
-+	movdqu		0x60($inp),$xt2
-+	 movdqu		$xt3,0x30($out)
-+	movdqu		0x70($inp),$xt3
-+	lea		0x80($inp),$inp		# inp+=64*4
-+	pxor		0x30(%rsp),$xt0
-+	pxor		$xb3,$xt1
-+	pxor		$xc3,$xt2
-+	pxor		$xd3,$xt3
-+	movdqu		$xt0,0x40($out)
-+	movdqu		$xt1,0x50($out)
-+	movdqu		$xt2,0x60($out)
-+	movdqu		$xt3,0x70($out)
-+	lea		0x80($out),$out		# out+=64*4
-+
-+	sub		\$64*4,$len
-+	jnz		.Loop_outer4x
-+
-+	jmp		.Ldone4x
-+
-+.Ltail4x:
-+	cmp		\$192,$len
-+	jae		.L192_or_more4x
-+	cmp		\$128,$len
-+	jae		.L128_or_more4x
-+	cmp		\$64,$len
-+	jae		.L64_or_more4x
-+
-+	#movdqa		0x00(%rsp),$xt0		# $xaN is offloaded, remember?
-+	xor		%r10,%r10
-+	#movdqa		$xt0,0x00(%rsp)
-+	movdqa		$xb0,0x10(%rsp)
-+	movdqa		$xc0,0x20(%rsp)
-+	movdqa		$xd0,0x30(%rsp)
-+	jmp		.Loop_tail4x
-+
-+.align	32
-+.L64_or_more4x:
-+	movdqu		0x00($inp),$xt0		# xor with input
-+	movdqu		0x10($inp),$xt1
-+	movdqu		0x20($inp),$xt2
-+	movdqu		0x30($inp),$xt3
-+	pxor		0x00(%rsp),$xt0		# $xaxN is offloaded, remember?
-+	pxor		$xb0,$xt1
-+	pxor		$xc0,$xt2
-+	pxor		$xd0,$xt3
-+	movdqu		$xt0,0x00($out)
-+	movdqu		$xt1,0x10($out)
-+	movdqu		$xt2,0x20($out)
-+	movdqu		$xt3,0x30($out)
-+	je		.Ldone4x
-+
-+	movdqa		0x10(%rsp),$xt0		# $xaN is offloaded, remember?
-+	lea		0x40($inp),$inp		# inp+=64*1
-+	xor		%r10,%r10
-+	movdqa		$xt0,0x00(%rsp)
-+	movdqa		$xb1,0x10(%rsp)
-+	lea		0x40($out),$out		# out+=64*1
-+	movdqa		$xc1,0x20(%rsp)
-+	sub		\$64,$len		# len-=64*1
-+	movdqa		$xd1,0x30(%rsp)
-+	jmp		.Loop_tail4x
-+
-+.align	32
-+.L128_or_more4x:
-+	movdqu		0x00($inp),$xt0		# xor with input
-+	movdqu		0x10($inp),$xt1
-+	movdqu		0x20($inp),$xt2
-+	movdqu		0x30($inp),$xt3
-+	pxor		0x00(%rsp),$xt0		# $xaN is offloaded, remember?
-+	pxor		$xb0,$xt1
-+	pxor		$xc0,$xt2
-+	pxor		$xd0,$xt3
-+
-+	 movdqu		$xt0,0x00($out)
-+	movdqu		0x40($inp),$xt0
-+	 movdqu		$xt1,0x10($out)
-+	movdqu		0x50($inp),$xt1
-+	 movdqu		$xt2,0x20($out)
-+	movdqu		0x60($inp),$xt2
-+	 movdqu		$xt3,0x30($out)
-+	movdqu		0x70($inp),$xt3
-+	pxor		0x10(%rsp),$xt0
-+	pxor		$xb1,$xt1
-+	pxor		$xc1,$xt2
-+	pxor		$xd1,$xt3
-+	movdqu		$xt0,0x40($out)
-+	movdqu		$xt1,0x50($out)
-+	movdqu		$xt2,0x60($out)
-+	movdqu		$xt3,0x70($out)
-+	je		.Ldone4x
-+
-+	movdqa		0x20(%rsp),$xt0		# $xaN is offloaded, remember?
-+	lea		0x80($inp),$inp		# inp+=64*2
-+	xor		%r10,%r10
-+	movdqa		$xt0,0x00(%rsp)
-+	movdqa		$xb2,0x10(%rsp)
-+	lea		0x80($out),$out		# out+=64*2
-+	movdqa		$xc2,0x20(%rsp)
-+	sub		\$128,$len		# len-=64*2
-+	movdqa		$xd2,0x30(%rsp)
-+	jmp		.Loop_tail4x
-+
-+.align	32
-+.L192_or_more4x:
-+	movdqu		0x00($inp),$xt0		# xor with input
-+	movdqu		0x10($inp),$xt1
-+	movdqu		0x20($inp),$xt2
-+	movdqu		0x30($inp),$xt3
-+	pxor		0x00(%rsp),$xt0		# $xaN is offloaded, remember?
-+	pxor		$xb0,$xt1
-+	pxor		$xc0,$xt2
-+	pxor		$xd0,$xt3
-+
-+	 movdqu		$xt0,0x00($out)
-+	movdqu		0x40($inp),$xt0
-+	 movdqu		$xt1,0x10($out)
-+	movdqu		0x50($inp),$xt1
-+	 movdqu		$xt2,0x20($out)
-+	movdqu		0x60($inp),$xt2
-+	 movdqu		$xt3,0x30($out)
-+	movdqu		0x70($inp),$xt3
-+	lea		0x80($inp),$inp		# size optimization
-+	pxor		0x10(%rsp),$xt0
-+	pxor		$xb1,$xt1
-+	pxor		$xc1,$xt2
-+	pxor		$xd1,$xt3
-+
-+	 movdqu		$xt0,0x40($out)
-+	movdqu		0x00($inp),$xt0
-+	 movdqu		$xt1,0x50($out)
-+	movdqu		0x10($inp),$xt1
-+	 movdqu		$xt2,0x60($out)
-+	movdqu		0x20($inp),$xt2
-+	 movdqu		$xt3,0x70($out)
-+	 lea		0x80($out),$out		# size optimization
-+	movdqu		0x30($inp),$xt3
-+	pxor		0x20(%rsp),$xt0
-+	pxor		$xb2,$xt1
-+	pxor		$xc2,$xt2
-+	pxor		$xd2,$xt3
-+	movdqu		$xt0,0x00($out)
-+	movdqu		$xt1,0x10($out)
-+	movdqu		$xt2,0x20($out)
-+	movdqu		$xt3,0x30($out)
-+	je		.Ldone4x
-+
-+	movdqa		0x30(%rsp),$xt0		# $xaN is offloaded, remember?
-+	lea		0x40($inp),$inp		# inp+=64*3
-+	xor		%r10,%r10
-+	movdqa		$xt0,0x00(%rsp)
-+	movdqa		$xb3,0x10(%rsp)
-+	lea		0x40($out),$out		# out+=64*3
-+	movdqa		$xc3,0x20(%rsp)
-+	sub		\$192,$len		# len-=64*3
-+	movdqa		$xd3,0x30(%rsp)
-+
-+.Loop_tail4x:
-+	movzb		($inp,%r10),%eax
-+	movzb		(%rsp,%r10),%ecx
-+	lea		1(%r10),%r10
-+	xor		%ecx,%eax
-+	mov		%al,-1($out,%r10)
-+	dec		$len
-+	jnz		.Loop_tail4x
-+
-+.Ldone4x:
-+___
-+$code.=<<___	if ($win64);
-+	lea		0x140+0x30(%rsp),%r11
-+	movaps		-0x30(%r11),%xmm6
-+	movaps		-0x20(%r11),%xmm7
-+	movaps		-0x10(%r11),%xmm8
-+	movaps		0x00(%r11),%xmm9
-+	movaps		0x10(%r11),%xmm10
-+	movaps		0x20(%r11),%xmm11
-+	movaps		0x30(%r11),%xmm12
-+	movaps		0x40(%r11),%xmm13
-+	movaps		0x50(%r11),%xmm14
-+	movaps		0x60(%r11),%xmm15
-+___
-+$code.=<<___;
-+	add		\$0x148+$xframe,%rsp
-+	ret
-+.size	ChaCha20_4x,.-ChaCha20_4x
-+___
-+}
-+
-+########################################################################
-+# XOP code path that handles all lengths.
-+if ($avx) {
-+# There is some "anomaly" observed depending on instructions' size or
-+# alignment. If you look closely at below code you'll notice that
-+# sometimes argument order varies. The order affects instruction
-+# encoding by making it larger, and such fiddling gives 5% performance
-+# improvement. This is on FX-4100...
-+
-+my ($xb0,$xb1,$xb2,$xb3, $xd0,$xd1,$xd2,$xd3,
-+    $xa0,$xa1,$xa2,$xa3, $xt0,$xt1,$xt2,$xt3)=map("%xmm$_",(0..15));
-+my  @xx=($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3,
-+	 $xt0,$xt1,$xt2,$xt3, $xd0,$xd1,$xd2,$xd3);
-+
-+sub XOP_lane_ROUND {
-+my ($a0,$b0,$c0,$d0)=@_;
-+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
-+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
-+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
-+my @x=map("\"$_\"",@xx);
-+
-+	(
-+	"&vpaddd	(@x[$a0],@x[$a0],@x[$b0])",	# Q1
-+	 "&vpaddd	(@x[$a1],@x[$a1],@x[$b1])",	# Q2
-+	  "&vpaddd	(@x[$a2],@x[$a2],@x[$b2])",	# Q3
-+	   "&vpaddd	(@x[$a3],@x[$a3],@x[$b3])",	# Q4
-+	"&vpxor		(@x[$d0],@x[$a0],@x[$d0])",
-+	 "&vpxor	(@x[$d1],@x[$a1],@x[$d1])",
-+	  "&vpxor	(@x[$d2],@x[$a2],@x[$d2])",
-+	   "&vpxor	(@x[$d3],@x[$a3],@x[$d3])",
-+	"&vprotd	(@x[$d0],@x[$d0],16)",
-+	 "&vprotd	(@x[$d1],@x[$d1],16)",
-+	  "&vprotd	(@x[$d2],@x[$d2],16)",
-+	   "&vprotd	(@x[$d3],@x[$d3],16)",
-+
-+	"&vpaddd	(@x[$c0],@x[$c0],@x[$d0])",
-+	 "&vpaddd	(@x[$c1],@x[$c1],@x[$d1])",
-+	  "&vpaddd	(@x[$c2],@x[$c2],@x[$d2])",
-+	   "&vpaddd	(@x[$c3],@x[$c3],@x[$d3])",
-+	"&vpxor		(@x[$b0],@x[$c0],@x[$b0])",
-+	 "&vpxor	(@x[$b1],@x[$c1],@x[$b1])",
-+	  "&vpxor	(@x[$b2],@x[$b2],@x[$c2])",	# flip
-+	   "&vpxor	(@x[$b3],@x[$b3],@x[$c3])",	# flip
-+	"&vprotd	(@x[$b0],@x[$b0],12)",
-+	 "&vprotd	(@x[$b1],@x[$b1],12)",
-+	  "&vprotd	(@x[$b2],@x[$b2],12)",
-+	   "&vprotd	(@x[$b3],@x[$b3],12)",
-+
-+	"&vpaddd	(@x[$a0],@x[$b0],@x[$a0])",	# flip
-+	 "&vpaddd	(@x[$a1],@x[$b1],@x[$a1])",	# flip
-+	  "&vpaddd	(@x[$a2],@x[$a2],@x[$b2])",
-+	   "&vpaddd	(@x[$a3],@x[$a3],@x[$b3])",
-+	"&vpxor		(@x[$d0],@x[$a0],@x[$d0])",
-+	 "&vpxor	(@x[$d1],@x[$a1],@x[$d1])",
-+	  "&vpxor	(@x[$d2],@x[$a2],@x[$d2])",
-+	   "&vpxor	(@x[$d3],@x[$a3],@x[$d3])",
-+	"&vprotd	(@x[$d0],@x[$d0],8)",
-+	 "&vprotd	(@x[$d1],@x[$d1],8)",
-+	  "&vprotd	(@x[$d2],@x[$d2],8)",
-+	   "&vprotd	(@x[$d3],@x[$d3],8)",
-+
-+	"&vpaddd	(@x[$c0],@x[$c0],@x[$d0])",
-+	 "&vpaddd	(@x[$c1],@x[$c1],@x[$d1])",
-+	  "&vpaddd	(@x[$c2],@x[$c2],@x[$d2])",
-+	   "&vpaddd	(@x[$c3],@x[$c3],@x[$d3])",
-+	"&vpxor		(@x[$b0],@x[$c0],@x[$b0])",
-+	 "&vpxor	(@x[$b1],@x[$c1],@x[$b1])",
-+	  "&vpxor	(@x[$b2],@x[$b2],@x[$c2])",	# flip
-+	   "&vpxor	(@x[$b3],@x[$b3],@x[$c3])",	# flip
-+	"&vprotd	(@x[$b0],@x[$b0],7)",
-+	 "&vprotd	(@x[$b1],@x[$b1],7)",
-+	  "&vprotd	(@x[$b2],@x[$b2],7)",
-+	   "&vprotd	(@x[$b3],@x[$b3],7)"
-+	);
-+}
-+
-+my $xframe = $win64 ? 0xa0 : 0;
-+
-+$code.=<<___;
-+.type	ChaCha20_4xop,\@function,5
-+.align	32
-+ChaCha20_4xop:
-+.LChaCha20_4xop:
-+	lea		-0x78(%rsp),%r11
-+	sub		\$0x148+$xframe,%rsp
-+___
-+	################ stack layout
-+	# +0x00		SIMD equivalent of @x[8-12]
-+	# ...
-+	# +0x40		constant copy of key[0-2] smashed by lanes
-+	# ...
-+	# +0x100	SIMD counters (with nonce smashed by lanes)
-+	# ...
-+	# +0x140
-+$code.=<<___	if ($win64);
-+	movaps		%xmm6,-0x30(%r11)
-+	movaps		%xmm7,-0x20(%r11)
-+	movaps		%xmm8,-0x10(%r11)
-+	movaps		%xmm9,0x00(%r11)
-+	movaps		%xmm10,0x10(%r11)
-+	movaps		%xmm11,0x20(%r11)
-+	movaps		%xmm12,0x30(%r11)
-+	movaps		%xmm13,0x40(%r11)
-+	movaps		%xmm14,0x50(%r11)
-+	movaps		%xmm15,0x60(%r11)
-+___
-+$code.=<<___;
-+	vzeroupper
-+
-+	vmovdqa		.Lsigma(%rip),$xa3	# key[0]
-+	vmovdqu		($key),$xb3		# key[1]
-+	vmovdqu		16($key),$xt3		# key[2]
-+	vmovdqu		($counter),$xd3		# key[3]
-+	lea		0x100(%rsp),%rcx	# size optimization
-+
-+	vpshufd		\$0x00,$xa3,$xa0	# smash key by lanes...
-+	vpshufd		\$0x55,$xa3,$xa1
-+	vmovdqa		$xa0,0x40(%rsp)		# ... and offload
-+	vpshufd		\$0xaa,$xa3,$xa2
-+	vmovdqa		$xa1,0x50(%rsp)
-+	vpshufd		\$0xff,$xa3,$xa3
-+	vmovdqa		$xa2,0x60(%rsp)
-+	vmovdqa		$xa3,0x70(%rsp)
-+
-+	vpshufd		\$0x00,$xb3,$xb0
-+	vpshufd		\$0x55,$xb3,$xb1
-+	vmovdqa		$xb0,0x80-0x100(%rcx)
-+	vpshufd		\$0xaa,$xb3,$xb2
-+	vmovdqa		$xb1,0x90-0x100(%rcx)
-+	vpshufd		\$0xff,$xb3,$xb3
-+	vmovdqa		$xb2,0xa0-0x100(%rcx)
-+	vmovdqa		$xb3,0xb0-0x100(%rcx)
-+
-+	vpshufd		\$0x00,$xt3,$xt0	# "$xc0"
-+	vpshufd		\$0x55,$xt3,$xt1	# "$xc1"
-+	vmovdqa		$xt0,0xc0-0x100(%rcx)
-+	vpshufd		\$0xaa,$xt3,$xt2	# "$xc2"
-+	vmovdqa		$xt1,0xd0-0x100(%rcx)
-+	vpshufd		\$0xff,$xt3,$xt3	# "$xc3"
-+	vmovdqa		$xt2,0xe0-0x100(%rcx)
-+	vmovdqa		$xt3,0xf0-0x100(%rcx)
-+
-+	vpshufd		\$0x00,$xd3,$xd0
-+	vpshufd		\$0x55,$xd3,$xd1
-+	vpaddd		.Linc(%rip),$xd0,$xd0	# don't save counters yet
-+	vpshufd		\$0xaa,$xd3,$xd2
-+	vmovdqa		$xd1,0x110-0x100(%rcx)
-+	vpshufd		\$0xff,$xd3,$xd3
-+	vmovdqa		$xd2,0x120-0x100(%rcx)
-+	vmovdqa		$xd3,0x130-0x100(%rcx)
-+
-+	jmp		.Loop_enter4xop
-+
-+.align	32
-+.Loop_outer4xop:
-+	vmovdqa		0x40(%rsp),$xa0		# re-load smashed key
-+	vmovdqa		0x50(%rsp),$xa1
-+	vmovdqa		0x60(%rsp),$xa2
-+	vmovdqa		0x70(%rsp),$xa3
-+	vmovdqa		0x80-0x100(%rcx),$xb0
-+	vmovdqa		0x90-0x100(%rcx),$xb1
-+	vmovdqa		0xa0-0x100(%rcx),$xb2
-+	vmovdqa		0xb0-0x100(%rcx),$xb3
-+	vmovdqa		0xc0-0x100(%rcx),$xt0	# "$xc0"
-+	vmovdqa		0xd0-0x100(%rcx),$xt1	# "$xc1"
-+	vmovdqa		0xe0-0x100(%rcx),$xt2	# "$xc2"
-+	vmovdqa		0xf0-0x100(%rcx),$xt3	# "$xc3"
-+	vmovdqa		0x100-0x100(%rcx),$xd0
-+	vmovdqa		0x110-0x100(%rcx),$xd1
-+	vmovdqa		0x120-0x100(%rcx),$xd2
-+	vmovdqa		0x130-0x100(%rcx),$xd3
-+	vpaddd		.Lfour(%rip),$xd0,$xd0	# next SIMD counters
-+
-+.Loop_enter4xop:
-+	mov		\$10,%eax
-+	vmovdqa		$xd0,0x100-0x100(%rcx)	# save SIMD counters
-+	jmp		.Loop4xop
-+
-+.align	32
-+.Loop4xop:
-+___
-+	foreach (&XOP_lane_ROUND(0, 4, 8,12)) { eval; }
-+	foreach (&XOP_lane_ROUND(0, 5,10,15)) { eval; }
-+$code.=<<___;
-+	dec		%eax
-+	jnz		.Loop4xop
-+
-+	vpaddd		0x40(%rsp),$xa0,$xa0	# accumulate key material
-+	vpaddd		0x50(%rsp),$xa1,$xa1
-+	vpaddd		0x60(%rsp),$xa2,$xa2
-+	vpaddd		0x70(%rsp),$xa3,$xa3
-+
-+	vmovdqa		$xt2,0x20(%rsp)		# offload $xc2,3
-+	vmovdqa		$xt3,0x30(%rsp)
-+
-+	vpunpckldq	$xa1,$xa0,$xt2		# "de-interlace" data
-+	vpunpckldq	$xa3,$xa2,$xt3
-+	vpunpckhdq	$xa1,$xa0,$xa0
-+	vpunpckhdq	$xa3,$xa2,$xa2
-+	vpunpcklqdq	$xt3,$xt2,$xa1		# "a0"
-+	vpunpckhqdq	$xt3,$xt2,$xt2		# "a1"
-+	vpunpcklqdq	$xa2,$xa0,$xa3		# "a2"
-+	vpunpckhqdq	$xa2,$xa0,$xa0		# "a3"
-+___
-+        ($xa0,$xa1,$xa2,$xa3,$xt2)=($xa1,$xt2,$xa3,$xa0,$xa2);
-+$code.=<<___;
-+	vpaddd		0x80-0x100(%rcx),$xb0,$xb0
-+	vpaddd		0x90-0x100(%rcx),$xb1,$xb1
-+	vpaddd		0xa0-0x100(%rcx),$xb2,$xb2
-+	vpaddd		0xb0-0x100(%rcx),$xb3,$xb3
-+
-+	vmovdqa		$xa0,0x00(%rsp)		# offload $xa0,1
-+	vmovdqa		$xa1,0x10(%rsp)
-+	vmovdqa		0x20(%rsp),$xa0		# "xc2"
-+	vmovdqa		0x30(%rsp),$xa1		# "xc3"
-+
-+	vpunpckldq	$xb1,$xb0,$xt2
-+	vpunpckldq	$xb3,$xb2,$xt3
-+	vpunpckhdq	$xb1,$xb0,$xb0
-+	vpunpckhdq	$xb3,$xb2,$xb2
-+	vpunpcklqdq	$xt3,$xt2,$xb1		# "b0"
-+	vpunpckhqdq	$xt3,$xt2,$xt2		# "b1"
-+	vpunpcklqdq	$xb2,$xb0,$xb3		# "b2"
-+	vpunpckhqdq	$xb2,$xb0,$xb0		# "b3"
-+___
-+	($xb0,$xb1,$xb2,$xb3,$xt2)=($xb1,$xt2,$xb3,$xb0,$xb2);
-+	my ($xc0,$xc1,$xc2,$xc3)=($xt0,$xt1,$xa0,$xa1);
-+$code.=<<___;
-+	vpaddd		0xc0-0x100(%rcx),$xc0,$xc0
-+	vpaddd		0xd0-0x100(%rcx),$xc1,$xc1
-+	vpaddd		0xe0-0x100(%rcx),$xc2,$xc2
-+	vpaddd		0xf0-0x100(%rcx),$xc3,$xc3
-+
-+	vpunpckldq	$xc1,$xc0,$xt2
-+	vpunpckldq	$xc3,$xc2,$xt3
-+	vpunpckhdq	$xc1,$xc0,$xc0
-+	vpunpckhdq	$xc3,$xc2,$xc2
-+	vpunpcklqdq	$xt3,$xt2,$xc1		# "c0"
-+	vpunpckhqdq	$xt3,$xt2,$xt2		# "c1"
-+	vpunpcklqdq	$xc2,$xc0,$xc3		# "c2"
-+	vpunpckhqdq	$xc2,$xc0,$xc0		# "c3"
-+___
-+	($xc0,$xc1,$xc2,$xc3,$xt2)=($xc1,$xt2,$xc3,$xc0,$xc2);
-+$code.=<<___;
-+	vpaddd		0x100-0x100(%rcx),$xd0,$xd0
-+	vpaddd		0x110-0x100(%rcx),$xd1,$xd1
-+	vpaddd		0x120-0x100(%rcx),$xd2,$xd2
-+	vpaddd		0x130-0x100(%rcx),$xd3,$xd3
-+
-+	vpunpckldq	$xd1,$xd0,$xt2
-+	vpunpckldq	$xd3,$xd2,$xt3
-+	vpunpckhdq	$xd1,$xd0,$xd0
-+	vpunpckhdq	$xd3,$xd2,$xd2
-+	vpunpcklqdq	$xt3,$xt2,$xd1		# "d0"
-+	vpunpckhqdq	$xt3,$xt2,$xt2		# "d1"
-+	vpunpcklqdq	$xd2,$xd0,$xd3		# "d2"
-+	vpunpckhqdq	$xd2,$xd0,$xd0		# "d3"
-+___
-+	($xd0,$xd1,$xd2,$xd3,$xt2)=($xd1,$xt2,$xd3,$xd0,$xd2);
-+	($xa0,$xa1)=($xt2,$xt3);
-+$code.=<<___;
-+	vmovdqa		0x00(%rsp),$xa0		# restore $xa0,1
-+	vmovdqa		0x10(%rsp),$xa1
-+
-+	cmp		\$64*4,$len
-+	jb		.Ltail4xop
-+
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x10($inp),$xb0,$xb0
-+	vpxor		0x20($inp),$xc0,$xc0
-+	vpxor		0x30($inp),$xd0,$xd0
-+	vpxor		0x40($inp),$xa1,$xa1
-+	vpxor		0x50($inp),$xb1,$xb1
-+	vpxor		0x60($inp),$xc1,$xc1
-+	vpxor		0x70($inp),$xd1,$xd1
-+	lea		0x80($inp),$inp		# size optimization
-+	vpxor		0x00($inp),$xa2,$xa2
-+	vpxor		0x10($inp),$xb2,$xb2
-+	vpxor		0x20($inp),$xc2,$xc2
-+	vpxor		0x30($inp),$xd2,$xd2
-+	vpxor		0x40($inp),$xa3,$xa3
-+	vpxor		0x50($inp),$xb3,$xb3
-+	vpxor		0x60($inp),$xc3,$xc3
-+	vpxor		0x70($inp),$xd3,$xd3
-+	lea		0x80($inp),$inp		# inp+=64*4
-+
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x10($out)
-+	vmovdqu		$xc0,0x20($out)
-+	vmovdqu		$xd0,0x30($out)
-+	vmovdqu		$xa1,0x40($out)
-+	vmovdqu		$xb1,0x50($out)
-+	vmovdqu		$xc1,0x60($out)
-+	vmovdqu		$xd1,0x70($out)
-+	lea		0x80($out),$out		# size optimization
-+	vmovdqu		$xa2,0x00($out)
-+	vmovdqu		$xb2,0x10($out)
-+	vmovdqu		$xc2,0x20($out)
-+	vmovdqu		$xd2,0x30($out)
-+	vmovdqu		$xa3,0x40($out)
-+	vmovdqu		$xb3,0x50($out)
-+	vmovdqu		$xc3,0x60($out)
-+	vmovdqu		$xd3,0x70($out)
-+	lea		0x80($out),$out		# out+=64*4
-+
-+	sub		\$64*4,$len
-+	jnz		.Loop_outer4xop
-+
-+	jmp		.Ldone4xop
-+
-+.align	32
-+.Ltail4xop:
-+	cmp		\$192,$len
-+	jae		.L192_or_more4xop
-+	cmp		\$128,$len
-+	jae		.L128_or_more4xop
-+	cmp		\$64,$len
-+	jae		.L64_or_more4xop
-+
-+	xor		%r10,%r10
-+	vmovdqa		$xa0,0x00(%rsp)
-+	vmovdqa		$xb0,0x10(%rsp)
-+	vmovdqa		$xc0,0x20(%rsp)
-+	vmovdqa		$xd0,0x30(%rsp)
-+	jmp		.Loop_tail4xop
-+
-+.align	32
-+.L64_or_more4xop:
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x10($inp),$xb0,$xb0
-+	vpxor		0x20($inp),$xc0,$xc0
-+	vpxor		0x30($inp),$xd0,$xd0
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x10($out)
-+	vmovdqu		$xc0,0x20($out)
-+	vmovdqu		$xd0,0x30($out)
-+	je		.Ldone4xop
-+
-+	lea		0x40($inp),$inp		# inp+=64*1
-+	vmovdqa		$xa1,0x00(%rsp)
-+	xor		%r10,%r10
-+	vmovdqa		$xb1,0x10(%rsp)
-+	lea		0x40($out),$out		# out+=64*1
-+	vmovdqa		$xc1,0x20(%rsp)
-+	sub		\$64,$len		# len-=64*1
-+	vmovdqa		$xd1,0x30(%rsp)
-+	jmp		.Loop_tail4xop
-+
-+.align	32
-+.L128_or_more4xop:
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x10($inp),$xb0,$xb0
-+	vpxor		0x20($inp),$xc0,$xc0
-+	vpxor		0x30($inp),$xd0,$xd0
-+	vpxor		0x40($inp),$xa1,$xa1
-+	vpxor		0x50($inp),$xb1,$xb1
-+	vpxor		0x60($inp),$xc1,$xc1
-+	vpxor		0x70($inp),$xd1,$xd1
-+
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x10($out)
-+	vmovdqu		$xc0,0x20($out)
-+	vmovdqu		$xd0,0x30($out)
-+	vmovdqu		$xa1,0x40($out)
-+	vmovdqu		$xb1,0x50($out)
-+	vmovdqu		$xc1,0x60($out)
-+	vmovdqu		$xd1,0x70($out)
-+	je		.Ldone4xop
-+
-+	lea		0x80($inp),$inp		# inp+=64*2
-+	vmovdqa		$xa2,0x00(%rsp)
-+	xor		%r10,%r10
-+	vmovdqa		$xb2,0x10(%rsp)
-+	lea		0x80($out),$out		# out+=64*2
-+	vmovdqa		$xc2,0x20(%rsp)
-+	sub		\$128,$len		# len-=64*2
-+	vmovdqa		$xd2,0x30(%rsp)
-+	jmp		.Loop_tail4xop
-+
-+.align	32
-+.L192_or_more4xop:
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x10($inp),$xb0,$xb0
-+	vpxor		0x20($inp),$xc0,$xc0
-+	vpxor		0x30($inp),$xd0,$xd0
-+	vpxor		0x40($inp),$xa1,$xa1
-+	vpxor		0x50($inp),$xb1,$xb1
-+	vpxor		0x60($inp),$xc1,$xc1
-+	vpxor		0x70($inp),$xd1,$xd1
-+	lea		0x80($inp),$inp		# size optimization
-+	vpxor		0x00($inp),$xa2,$xa2
-+	vpxor		0x10($inp),$xb2,$xb2
-+	vpxor		0x20($inp),$xc2,$xc2
-+	vpxor		0x30($inp),$xd2,$xd2
-+
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x10($out)
-+	vmovdqu		$xc0,0x20($out)
-+	vmovdqu		$xd0,0x30($out)
-+	vmovdqu		$xa1,0x40($out)
-+	vmovdqu		$xb1,0x50($out)
-+	vmovdqu		$xc1,0x60($out)
-+	vmovdqu		$xd1,0x70($out)
-+	lea		0x80($out),$out		# size optimization
-+	vmovdqu		$xa2,0x00($out)
-+	vmovdqu		$xb2,0x10($out)
-+	vmovdqu		$xc2,0x20($out)
-+	vmovdqu		$xd2,0x30($out)
-+	je		.Ldone4xop
-+
-+	lea		0x40($inp),$inp		# inp+=64*3
-+	vmovdqa		$xa3,0x00(%rsp)
-+	xor		%r10,%r10
-+	vmovdqa		$xb3,0x10(%rsp)
-+	lea		0x40($out),$out		# out+=64*3
-+	vmovdqa		$xc3,0x20(%rsp)
-+	sub		\$192,$len		# len-=64*3
-+	vmovdqa		$xd3,0x30(%rsp)
-+
-+.Loop_tail4xop:
-+	movzb		($inp,%r10),%eax
-+	movzb		(%rsp,%r10),%ecx
-+	lea		1(%r10),%r10
-+	xor		%ecx,%eax
-+	mov		%al,-1($out,%r10)
-+	dec		$len
-+	jnz		.Loop_tail4xop
-+
-+.Ldone4xop:
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	lea		0x140+0x30(%rsp),%r11
-+	movaps		-0x30(%r11),%xmm6
-+	movaps		-0x20(%r11),%xmm7
-+	movaps		-0x10(%r11),%xmm8
-+	movaps		0x00(%r11),%xmm9
-+	movaps		0x10(%r11),%xmm10
-+	movaps		0x20(%r11),%xmm11
-+	movaps		0x30(%r11),%xmm12
-+	movaps		0x40(%r11),%xmm13
-+	movaps		0x50(%r11),%xmm14
-+	movaps		0x60(%r11),%xmm15
-+___
-+$code.=<<___;
-+	add		\$0x148+$xframe,%rsp
-+	ret
-+.size	ChaCha20_4xop,.-ChaCha20_4xop
-+___
-+}
-+
-+########################################################################
-+# AVX2 code path
-+if ($avx>1) {
-+my ($xb0,$xb1,$xb2,$xb3, $xd0,$xd1,$xd2,$xd3,
-+    $xa0,$xa1,$xa2,$xa3, $xt0,$xt1,$xt2,$xt3)=map("%ymm$_",(0..15));
-+my @xx=($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3,
-+	"%nox","%nox","%nox","%nox", $xd0,$xd1,$xd2,$xd3);
-+
-+sub AVX2_lane_ROUND {
-+my ($a0,$b0,$c0,$d0)=@_;
-+my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
-+my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
-+my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
-+my ($xc,$xc_,$t0,$t1)=map("\"$_\"",$xt0,$xt1,$xt2,$xt3);
-+my @x=map("\"$_\"",@xx);
-+
-+	# Consider order in which variables are addressed by their
-+	# index:
-+	#
-+	#	a   b   c   d
-+	#
-+	#	0   4   8  12 < even round
-+	#	1   5   9  13
-+	#	2   6  10  14
-+	#	3   7  11  15
-+	#	0   5  10  15 < odd round
-+	#	1   6  11  12
-+	#	2   7   8  13
-+	#	3   4   9  14
-+	#
-+	# 'a', 'b' and 'd's are permanently allocated in registers,
-+	# @x[0..7,12..15], while 'c's are maintained in memory. If
-+	# you observe 'c' column, you'll notice that pair of 'c's is
-+	# invariant between rounds. This means that we have to reload
-+	# them once per round, in the middle. This is why you'll see
-+	# bunch of 'c' stores and loads in the middle, but none in
-+	# the beginning or end.
-+
-+	(
-+	"&vpaddd	(@x[$a0],@x[$a0],@x[$b0])",	# Q1
-+	"&vpxor		(@x[$d0],@x[$a0],@x[$d0])",
-+	"&vpshufb	(@x[$d0],@x[$d0],$t1)",
-+	 "&vpaddd	(@x[$a1],@x[$a1],@x[$b1])",	# Q2
-+	 "&vpxor	(@x[$d1],@x[$a1],@x[$d1])",
-+	 "&vpshufb	(@x[$d1],@x[$d1],$t1)",
-+
-+	"&vpaddd	($xc,$xc,@x[$d0])",
-+	"&vpxor		(@x[$b0],$xc,@x[$b0])",
-+	"&vpslld	($t0,@x[$b0],12)",
-+	"&vpsrld	(@x[$b0],@x[$b0],20)",
-+	"&vpor		(@x[$b0],$t0,@x[$b0])",
-+	"&vbroadcasti128($t0,'(%r11)')",		# .Lrot24(%rip)
-+	 "&vpaddd	($xc_,$xc_,@x[$d1])",
-+	 "&vpxor	(@x[$b1],$xc_,@x[$b1])",
-+	 "&vpslld	($t1,@x[$b1],12)",
-+	 "&vpsrld	(@x[$b1],@x[$b1],20)",
-+	 "&vpor		(@x[$b1],$t1,@x[$b1])",
-+
-+	"&vpaddd	(@x[$a0],@x[$a0],@x[$b0])",
-+	"&vpxor		(@x[$d0],@x[$a0],@x[$d0])",
-+	"&vpshufb	(@x[$d0],@x[$d0],$t0)",
-+	 "&vpaddd	(@x[$a1],@x[$a1],@x[$b1])",
-+	 "&vpxor	(@x[$d1],@x[$a1],@x[$d1])",
-+	 "&vpshufb	(@x[$d1],@x[$d1],$t0)",
-+
-+	"&vpaddd	($xc,$xc,@x[$d0])",
-+	"&vpxor		(@x[$b0],$xc,@x[$b0])",
-+	"&vpslld	($t1,@x[$b0],7)",
-+	"&vpsrld	(@x[$b0],@x[$b0],25)",
-+	"&vpor		(@x[$b0],$t1,@x[$b0])",
-+	"&vbroadcasti128($t1,'(%r10)')",		# .Lrot16(%rip)
-+	 "&vpaddd	($xc_,$xc_,@x[$d1])",
-+	 "&vpxor	(@x[$b1],$xc_,@x[$b1])",
-+	 "&vpslld	($t0,@x[$b1],7)",
-+	 "&vpsrld	(@x[$b1],@x[$b1],25)",
-+	 "&vpor		(@x[$b1],$t0,@x[$b1])",
-+
-+	"&vmovdqa	(\"`32*($c0-8)`(%rsp)\",$xc)",	# reload pair of 'c's
-+	 "&vmovdqa	(\"`32*($c1-8)`(%rsp)\",$xc_)",
-+	"&vmovdqa	($xc,\"`32*($c2-8)`(%rsp)\")",
-+	 "&vmovdqa	($xc_,\"`32*($c3-8)`(%rsp)\")",
-+
-+	"&vpaddd	(@x[$a2],@x[$a2],@x[$b2])",	# Q3
-+	"&vpxor		(@x[$d2],@x[$a2],@x[$d2])",
-+	"&vpshufb	(@x[$d2],@x[$d2],$t1)",
-+	 "&vpaddd	(@x[$a3],@x[$a3],@x[$b3])",	# Q4
-+	 "&vpxor	(@x[$d3],@x[$a3],@x[$d3])",
-+	 "&vpshufb	(@x[$d3],@x[$d3],$t1)",
-+
-+	"&vpaddd	($xc,$xc,@x[$d2])",
-+	"&vpxor		(@x[$b2],$xc,@x[$b2])",
-+	"&vpslld	($t0,@x[$b2],12)",
-+	"&vpsrld	(@x[$b2],@x[$b2],20)",
-+	"&vpor		(@x[$b2],$t0,@x[$b2])",
-+	"&vbroadcasti128($t0,'(%r11)')",		# .Lrot24(%rip)
-+	 "&vpaddd	($xc_,$xc_,@x[$d3])",
-+	 "&vpxor	(@x[$b3],$xc_,@x[$b3])",
-+	 "&vpslld	($t1,@x[$b3],12)",
-+	 "&vpsrld	(@x[$b3],@x[$b3],20)",
-+	 "&vpor		(@x[$b3],$t1,@x[$b3])",
-+
-+	"&vpaddd	(@x[$a2],@x[$a2],@x[$b2])",
-+	"&vpxor		(@x[$d2],@x[$a2],@x[$d2])",
-+	"&vpshufb	(@x[$d2],@x[$d2],$t0)",
-+	 "&vpaddd	(@x[$a3],@x[$a3],@x[$b3])",
-+	 "&vpxor	(@x[$d3],@x[$a3],@x[$d3])",
-+	 "&vpshufb	(@x[$d3],@x[$d3],$t0)",
-+
-+	"&vpaddd	($xc,$xc,@x[$d2])",
-+	"&vpxor		(@x[$b2],$xc,@x[$b2])",
-+	"&vpslld	($t1,@x[$b2],7)",
-+	"&vpsrld	(@x[$b2],@x[$b2],25)",
-+	"&vpor		(@x[$b2],$t1,@x[$b2])",
-+	"&vbroadcasti128($t1,'(%r10)')",		# .Lrot16(%rip)
-+	 "&vpaddd	($xc_,$xc_,@x[$d3])",
-+	 "&vpxor	(@x[$b3],$xc_,@x[$b3])",
-+	 "&vpslld	($t0,@x[$b3],7)",
-+	 "&vpsrld	(@x[$b3],@x[$b3],25)",
-+	 "&vpor		(@x[$b3],$t0,@x[$b3])"
-+	);
-+}
-+
-+my $xframe = $win64 ? 0xb0 : 8;
-+
-+$code.=<<___;
-+.type	ChaCha20_8x,\@function,5
-+.align	32
-+ChaCha20_8x:
-+.LChaCha20_8x:
-+	mov		%rsp,%r10
-+	sub		\$0x280+$xframe,%rsp
-+	and		\$-32,%rsp
-+___
-+$code.=<<___	if ($win64);
-+	lea		0x290+0x30(%rsp),%r11
-+	movaps		%xmm6,-0x30(%r11)
-+	movaps		%xmm7,-0x20(%r11)
-+	movaps		%xmm8,-0x10(%r11)
-+	movaps		%xmm9,0x00(%r11)
-+	movaps		%xmm10,0x10(%r11)
-+	movaps		%xmm11,0x20(%r11)
-+	movaps		%xmm12,0x30(%r11)
-+	movaps		%xmm13,0x40(%r11)
-+	movaps		%xmm14,0x50(%r11)
-+	movaps		%xmm15,0x60(%r11)
-+___
-+$code.=<<___;
-+	vzeroupper
-+	mov		%r10,0x280(%rsp)
-+
-+	################ stack layout
-+	# +0x00		SIMD equivalent of @x[8-12]
-+	# ...
-+	# +0x80		constant copy of key[0-2] smashed by lanes
-+	# ...
-+	# +0x200	SIMD counters (with nonce smashed by lanes)
-+	# ...
-+	# +0x280	saved %rsp
-+
-+	vbroadcasti128	.Lsigma(%rip),$xa3	# key[0]
-+	vbroadcasti128	($key),$xb3		# key[1]
-+	vbroadcasti128	16($key),$xt3		# key[2]
-+	vbroadcasti128	($counter),$xd3		# key[3]
-+	lea		0x100(%rsp),%rcx	# size optimization
-+	lea		0x200(%rsp),%rax	# size optimization
-+	lea		.Lrot16(%rip),%r10
-+	lea		.Lrot24(%rip),%r11
-+
-+	vpshufd		\$0x00,$xa3,$xa0	# smash key by lanes...
-+	vpshufd		\$0x55,$xa3,$xa1
-+	vmovdqa		$xa0,0x80-0x100(%rcx)	# ... and offload
-+	vpshufd		\$0xaa,$xa3,$xa2
-+	vmovdqa		$xa1,0xa0-0x100(%rcx)
-+	vpshufd		\$0xff,$xa3,$xa3
-+	vmovdqa		$xa2,0xc0-0x100(%rcx)
-+	vmovdqa		$xa3,0xe0-0x100(%rcx)
-+
-+	vpshufd		\$0x00,$xb3,$xb0
-+	vpshufd		\$0x55,$xb3,$xb1
-+	vmovdqa		$xb0,0x100-0x100(%rcx)
-+	vpshufd		\$0xaa,$xb3,$xb2
-+	vmovdqa		$xb1,0x120-0x100(%rcx)
-+	vpshufd		\$0xff,$xb3,$xb3
-+	vmovdqa		$xb2,0x140-0x100(%rcx)
-+	vmovdqa		$xb3,0x160-0x100(%rcx)
-+
-+	vpshufd		\$0x00,$xt3,$xt0	# "xc0"
-+	vpshufd		\$0x55,$xt3,$xt1	# "xc1"
-+	vmovdqa		$xt0,0x180-0x200(%rax)
-+	vpshufd		\$0xaa,$xt3,$xt2	# "xc2"
-+	vmovdqa		$xt1,0x1a0-0x200(%rax)
-+	vpshufd		\$0xff,$xt3,$xt3	# "xc3"
-+	vmovdqa		$xt2,0x1c0-0x200(%rax)
-+	vmovdqa		$xt3,0x1e0-0x200(%rax)
-+
-+	vpshufd		\$0x00,$xd3,$xd0
-+	vpshufd		\$0x55,$xd3,$xd1
-+	vpaddd		.Lincy(%rip),$xd0,$xd0	# don't save counters yet
-+	vpshufd		\$0xaa,$xd3,$xd2
-+	vmovdqa		$xd1,0x220-0x200(%rax)
-+	vpshufd		\$0xff,$xd3,$xd3
-+	vmovdqa		$xd2,0x240-0x200(%rax)
-+	vmovdqa		$xd3,0x260-0x200(%rax)
-+
-+	jmp		.Loop_enter8x
-+
-+.align	32
-+.Loop_outer8x:
-+	vmovdqa		0x80-0x100(%rcx),$xa0	# re-load smashed key
-+	vmovdqa		0xa0-0x100(%rcx),$xa1
-+	vmovdqa		0xc0-0x100(%rcx),$xa2
-+	vmovdqa		0xe0-0x100(%rcx),$xa3
-+	vmovdqa		0x100-0x100(%rcx),$xb0
-+	vmovdqa		0x120-0x100(%rcx),$xb1
-+	vmovdqa		0x140-0x100(%rcx),$xb2
-+	vmovdqa		0x160-0x100(%rcx),$xb3
-+	vmovdqa		0x180-0x200(%rax),$xt0	# "xc0"
-+	vmovdqa		0x1a0-0x200(%rax),$xt1	# "xc1"
-+	vmovdqa		0x1c0-0x200(%rax),$xt2	# "xc2"
-+	vmovdqa		0x1e0-0x200(%rax),$xt3	# "xc3"
-+	vmovdqa		0x200-0x200(%rax),$xd0
-+	vmovdqa		0x220-0x200(%rax),$xd1
-+	vmovdqa		0x240-0x200(%rax),$xd2
-+	vmovdqa		0x260-0x200(%rax),$xd3
-+	vpaddd		.Leight(%rip),$xd0,$xd0	# next SIMD counters
-+
-+.Loop_enter8x:
-+	vmovdqa		$xt2,0x40(%rsp)		# SIMD equivalent of "@x[10]"
-+	vmovdqa		$xt3,0x60(%rsp)		# SIMD equivalent of "@x[11]"
-+	vbroadcasti128	(%r10),$xt3
-+	vmovdqa		$xd0,0x200-0x200(%rax)	# save SIMD counters
-+	mov		\$10,%eax
-+	jmp		.Loop8x
-+
-+.align	32
-+.Loop8x:
-+___
-+	foreach (&AVX2_lane_ROUND(0, 4, 8,12)) { eval; }
-+	foreach (&AVX2_lane_ROUND(0, 5,10,15)) { eval; }
-+$code.=<<___;
-+	dec		%eax
-+	jnz		.Loop8x
-+
-+	lea		0x200(%rsp),%rax	# size optimization
-+	vpaddd		0x80-0x100(%rcx),$xa0,$xa0	# accumulate key
-+	vpaddd		0xa0-0x100(%rcx),$xa1,$xa1
-+	vpaddd		0xc0-0x100(%rcx),$xa2,$xa2
-+	vpaddd		0xe0-0x100(%rcx),$xa3,$xa3
-+
-+	vpunpckldq	$xa1,$xa0,$xt2		# "de-interlace" data
-+	vpunpckldq	$xa3,$xa2,$xt3
-+	vpunpckhdq	$xa1,$xa0,$xa0
-+	vpunpckhdq	$xa3,$xa2,$xa2
-+	vpunpcklqdq	$xt3,$xt2,$xa1		# "a0"
-+	vpunpckhqdq	$xt3,$xt2,$xt2		# "a1"
-+	vpunpcklqdq	$xa2,$xa0,$xa3		# "a2"
-+	vpunpckhqdq	$xa2,$xa0,$xa0		# "a3"
-+___
-+	($xa0,$xa1,$xa2,$xa3,$xt2)=($xa1,$xt2,$xa3,$xa0,$xa2);
-+$code.=<<___;
-+	vpaddd		0x100-0x100(%rcx),$xb0,$xb0
-+	vpaddd		0x120-0x100(%rcx),$xb1,$xb1
-+	vpaddd		0x140-0x100(%rcx),$xb2,$xb2
-+	vpaddd		0x160-0x100(%rcx),$xb3,$xb3
-+
-+	vpunpckldq	$xb1,$xb0,$xt2
-+	vpunpckldq	$xb3,$xb2,$xt3
-+	vpunpckhdq	$xb1,$xb0,$xb0
-+	vpunpckhdq	$xb3,$xb2,$xb2
-+	vpunpcklqdq	$xt3,$xt2,$xb1		# "b0"
-+	vpunpckhqdq	$xt3,$xt2,$xt2		# "b1"
-+	vpunpcklqdq	$xb2,$xb0,$xb3		# "b2"
-+	vpunpckhqdq	$xb2,$xb0,$xb0		# "b3"
-+___
-+	($xb0,$xb1,$xb2,$xb3,$xt2)=($xb1,$xt2,$xb3,$xb0,$xb2);
-+$code.=<<___;
-+	vperm2i128	\$0x20,$xb0,$xa0,$xt3	# "de-interlace" further
-+	vperm2i128	\$0x31,$xb0,$xa0,$xb0
-+	vperm2i128	\$0x20,$xb1,$xa1,$xa0
-+	vperm2i128	\$0x31,$xb1,$xa1,$xb1
-+	vperm2i128	\$0x20,$xb2,$xa2,$xa1
-+	vperm2i128	\$0x31,$xb2,$xa2,$xb2
-+	vperm2i128	\$0x20,$xb3,$xa3,$xa2
-+	vperm2i128	\$0x31,$xb3,$xa3,$xb3
-+___
-+	($xa0,$xa1,$xa2,$xa3,$xt3)=($xt3,$xa0,$xa1,$xa2,$xa3);
-+	my ($xc0,$xc1,$xc2,$xc3)=($xt0,$xt1,$xa0,$xa1);
-+$code.=<<___;
-+	vmovdqa		$xa0,0x00(%rsp)		# offload $xaN
-+	vmovdqa		$xa1,0x20(%rsp)
-+	vmovdqa		0x40(%rsp),$xc2		# $xa0
-+	vmovdqa		0x60(%rsp),$xc3		# $xa1
-+
-+	vpaddd		0x180-0x200(%rax),$xc0,$xc0
-+	vpaddd		0x1a0-0x200(%rax),$xc1,$xc1
-+	vpaddd		0x1c0-0x200(%rax),$xc2,$xc2
-+	vpaddd		0x1e0-0x200(%rax),$xc3,$xc3
-+
-+	vpunpckldq	$xc1,$xc0,$xt2
-+	vpunpckldq	$xc3,$xc2,$xt3
-+	vpunpckhdq	$xc1,$xc0,$xc0
-+	vpunpckhdq	$xc3,$xc2,$xc2
-+	vpunpcklqdq	$xt3,$xt2,$xc1		# "c0"
-+	vpunpckhqdq	$xt3,$xt2,$xt2		# "c1"
-+	vpunpcklqdq	$xc2,$xc0,$xc3		# "c2"
-+	vpunpckhqdq	$xc2,$xc0,$xc0		# "c3"
-+___
-+	($xc0,$xc1,$xc2,$xc3,$xt2)=($xc1,$xt2,$xc3,$xc0,$xc2);
-+$code.=<<___;
-+	vpaddd		0x200-0x200(%rax),$xd0,$xd0
-+	vpaddd		0x220-0x200(%rax),$xd1,$xd1
-+	vpaddd		0x240-0x200(%rax),$xd2,$xd2
-+	vpaddd		0x260-0x200(%rax),$xd3,$xd3
-+
-+	vpunpckldq	$xd1,$xd0,$xt2
-+	vpunpckldq	$xd3,$xd2,$xt3
-+	vpunpckhdq	$xd1,$xd0,$xd0
-+	vpunpckhdq	$xd3,$xd2,$xd2
-+	vpunpcklqdq	$xt3,$xt2,$xd1		# "d0"
-+	vpunpckhqdq	$xt3,$xt2,$xt2		# "d1"
-+	vpunpcklqdq	$xd2,$xd0,$xd3		# "d2"
-+	vpunpckhqdq	$xd2,$xd0,$xd0		# "d3"
-+___
-+	($xd0,$xd1,$xd2,$xd3,$xt2)=($xd1,$xt2,$xd3,$xd0,$xd2);
-+$code.=<<___;
-+	vperm2i128	\$0x20,$xd0,$xc0,$xt3	# "de-interlace" further
-+	vperm2i128	\$0x31,$xd0,$xc0,$xd0
-+	vperm2i128	\$0x20,$xd1,$xc1,$xc0
-+	vperm2i128	\$0x31,$xd1,$xc1,$xd1
-+	vperm2i128	\$0x20,$xd2,$xc2,$xc1
-+	vperm2i128	\$0x31,$xd2,$xc2,$xd2
-+	vperm2i128	\$0x20,$xd3,$xc3,$xc2
-+	vperm2i128	\$0x31,$xd3,$xc3,$xd3
-+___
-+	($xc0,$xc1,$xc2,$xc3,$xt3)=($xt3,$xc0,$xc1,$xc2,$xc3);
-+	($xb0,$xb1,$xb2,$xb3,$xc0,$xc1,$xc2,$xc3)=
-+	($xc0,$xc1,$xc2,$xc3,$xb0,$xb1,$xb2,$xb3);
-+	($xa0,$xa1)=($xt2,$xt3);
-+$code.=<<___;
-+	vmovdqa		0x00(%rsp),$xa0		# $xaN was offloaded, remember?
-+	vmovdqa		0x20(%rsp),$xa1
-+
-+	cmp		\$64*8,$len
-+	jb		.Ltail8x
-+
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x20($inp),$xb0,$xb0
-+	vpxor		0x40($inp),$xc0,$xc0
-+	vpxor		0x60($inp),$xd0,$xd0
-+	lea		0x80($inp),$inp		# size optimization
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x20($out)
-+	vmovdqu		$xc0,0x40($out)
-+	vmovdqu		$xd0,0x60($out)
-+	lea		0x80($out),$out		# size optimization
-+
-+	vpxor		0x00($inp),$xa1,$xa1
-+	vpxor		0x20($inp),$xb1,$xb1
-+	vpxor		0x40($inp),$xc1,$xc1
-+	vpxor		0x60($inp),$xd1,$xd1
-+	lea		0x80($inp),$inp		# size optimization
-+	vmovdqu		$xa1,0x00($out)
-+	vmovdqu		$xb1,0x20($out)
-+	vmovdqu		$xc1,0x40($out)
-+	vmovdqu		$xd1,0x60($out)
-+	lea		0x80($out),$out		# size optimization
-+
-+	vpxor		0x00($inp),$xa2,$xa2
-+	vpxor		0x20($inp),$xb2,$xb2
-+	vpxor		0x40($inp),$xc2,$xc2
-+	vpxor		0x60($inp),$xd2,$xd2
-+	lea		0x80($inp),$inp		# size optimization
-+	vmovdqu		$xa2,0x00($out)
-+	vmovdqu		$xb2,0x20($out)
-+	vmovdqu		$xc2,0x40($out)
-+	vmovdqu		$xd2,0x60($out)
-+	lea		0x80($out),$out		# size optimization
-+
-+	vpxor		0x00($inp),$xa3,$xa3
-+	vpxor		0x20($inp),$xb3,$xb3
-+	vpxor		0x40($inp),$xc3,$xc3
-+	vpxor		0x60($inp),$xd3,$xd3
-+	lea		0x80($inp),$inp		# size optimization
-+	vmovdqu		$xa3,0x00($out)
-+	vmovdqu		$xb3,0x20($out)
-+	vmovdqu		$xc3,0x40($out)
-+	vmovdqu		$xd3,0x60($out)
-+	lea		0x80($out),$out		# size optimization
-+
-+	sub		\$64*8,$len
-+	jnz		.Loop_outer8x
-+
-+	jmp		.Ldone8x
-+
-+.Ltail8x:
-+	cmp		\$448,$len
-+	jae		.L448_or_more8x
-+	cmp		\$384,$len
-+	jae		.L384_or_more8x
-+	cmp		\$320,$len
-+	jae		.L320_or_more8x
-+	cmp		\$256,$len
-+	jae		.L256_or_more8x
-+	cmp		\$192,$len
-+	jae		.L192_or_more8x
-+	cmp		\$128,$len
-+	jae		.L128_or_more8x
-+	cmp		\$64,$len
-+	jae		.L64_or_more8x
-+
-+	xor		%r10,%r10
-+	vmovdqa		$xa0,0x00(%rsp)
-+	vmovdqa		$xb0,0x20(%rsp)
-+	jmp		.Loop_tail8x
-+
-+.align	32
-+.L64_or_more8x:
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x20($inp),$xb0,$xb0
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x20($out)
-+	je		.Ldone8x
-+
-+	lea		0x40($inp),$inp		# inp+=64*1
-+	xor		%r10,%r10
-+	vmovdqa		$xc0,0x00(%rsp)
-+	lea		0x40($out),$out		# out+=64*1
-+	sub		\$64,$len		# len-=64*1
-+	vmovdqa		$xd0,0x20(%rsp)
-+	jmp		.Loop_tail8x
-+
-+.align	32
-+.L128_or_more8x:
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x20($inp),$xb0,$xb0
-+	vpxor		0x40($inp),$xc0,$xc0
-+	vpxor		0x60($inp),$xd0,$xd0
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x20($out)
-+	vmovdqu		$xc0,0x40($out)
-+	vmovdqu		$xd0,0x60($out)
-+	je		.Ldone8x
-+
-+	lea		0x80($inp),$inp		# inp+=64*2
-+	xor		%r10,%r10
-+	vmovdqa		$xa1,0x00(%rsp)
-+	lea		0x80($out),$out		# out+=64*2
-+	sub		\$128,$len		# len-=64*2
-+	vmovdqa		$xb1,0x20(%rsp)
-+	jmp		.Loop_tail8x
-+
-+.align	32
-+.L192_or_more8x:
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x20($inp),$xb0,$xb0
-+	vpxor		0x40($inp),$xc0,$xc0
-+	vpxor		0x60($inp),$xd0,$xd0
-+	vpxor		0x80($inp),$xa1,$xa1
-+	vpxor		0xa0($inp),$xb1,$xb1
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x20($out)
-+	vmovdqu		$xc0,0x40($out)
-+	vmovdqu		$xd0,0x60($out)
-+	vmovdqu		$xa1,0x80($out)
-+	vmovdqu		$xb1,0xa0($out)
-+	je		.Ldone8x
-+
-+	lea		0xc0($inp),$inp		# inp+=64*3
-+	xor		%r10,%r10
-+	vmovdqa		$xc1,0x00(%rsp)
-+	lea		0xc0($out),$out		# out+=64*3
-+	sub		\$192,$len		# len-=64*3
-+	vmovdqa		$xd1,0x20(%rsp)
-+	jmp		.Loop_tail8x
-+
-+.align	32
-+.L256_or_more8x:
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x20($inp),$xb0,$xb0
-+	vpxor		0x40($inp),$xc0,$xc0
-+	vpxor		0x60($inp),$xd0,$xd0
-+	vpxor		0x80($inp),$xa1,$xa1
-+	vpxor		0xa0($inp),$xb1,$xb1
-+	vpxor		0xc0($inp),$xc1,$xc1
-+	vpxor		0xe0($inp),$xd1,$xd1
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x20($out)
-+	vmovdqu		$xc0,0x40($out)
-+	vmovdqu		$xd0,0x60($out)
-+	vmovdqu		$xa1,0x80($out)
-+	vmovdqu		$xb1,0xa0($out)
-+	vmovdqu		$xc1,0xc0($out)
-+	vmovdqu		$xd1,0xe0($out)
-+	je		.Ldone8x
-+
-+	lea		0x100($inp),$inp	# inp+=64*4
-+	xor		%r10,%r10
-+	vmovdqa		$xa2,0x00(%rsp)
-+	lea		0x100($out),$out	# out+=64*4
-+	sub		\$256,$len		# len-=64*4
-+	vmovdqa		$xb2,0x20(%rsp)
-+	jmp		.Loop_tail8x
-+
-+.align	32
-+.L320_or_more8x:
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x20($inp),$xb0,$xb0
-+	vpxor		0x40($inp),$xc0,$xc0
-+	vpxor		0x60($inp),$xd0,$xd0
-+	vpxor		0x80($inp),$xa1,$xa1
-+	vpxor		0xa0($inp),$xb1,$xb1
-+	vpxor		0xc0($inp),$xc1,$xc1
-+	vpxor		0xe0($inp),$xd1,$xd1
-+	vpxor		0x100($inp),$xa2,$xa2
-+	vpxor		0x120($inp),$xb2,$xb2
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x20($out)
-+	vmovdqu		$xc0,0x40($out)
-+	vmovdqu		$xd0,0x60($out)
-+	vmovdqu		$xa1,0x80($out)
-+	vmovdqu		$xb1,0xa0($out)
-+	vmovdqu		$xc1,0xc0($out)
-+	vmovdqu		$xd1,0xe0($out)
-+	vmovdqu		$xa2,0x100($out)
-+	vmovdqu		$xb2,0x120($out)
-+	je		.Ldone8x
-+
-+	lea		0x140($inp),$inp	# inp+=64*5
-+	xor		%r10,%r10
-+	vmovdqa		$xc2,0x00(%rsp)
-+	lea		0x140($out),$out	# out+=64*5
-+	sub		\$320,$len		# len-=64*5
-+	vmovdqa		$xd2,0x20(%rsp)
-+	jmp		.Loop_tail8x
-+
-+.align	32
-+.L384_or_more8x:
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x20($inp),$xb0,$xb0
-+	vpxor		0x40($inp),$xc0,$xc0
-+	vpxor		0x60($inp),$xd0,$xd0
-+	vpxor		0x80($inp),$xa1,$xa1
-+	vpxor		0xa0($inp),$xb1,$xb1
-+	vpxor		0xc0($inp),$xc1,$xc1
-+	vpxor		0xe0($inp),$xd1,$xd1
-+	vpxor		0x100($inp),$xa2,$xa2
-+	vpxor		0x120($inp),$xb2,$xb2
-+	vpxor		0x140($inp),$xc2,$xc2
-+	vpxor		0x160($inp),$xd2,$xd2
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x20($out)
-+	vmovdqu		$xc0,0x40($out)
-+	vmovdqu		$xd0,0x60($out)
-+	vmovdqu		$xa1,0x80($out)
-+	vmovdqu		$xb1,0xa0($out)
-+	vmovdqu		$xc1,0xc0($out)
-+	vmovdqu		$xd1,0xe0($out)
-+	vmovdqu		$xa2,0x100($out)
-+	vmovdqu		$xb2,0x120($out)
-+	vmovdqu		$xc2,0x140($out)
-+	vmovdqu		$xd2,0x160($out)
-+	je		.Ldone8x
-+
-+	lea		0x180($inp),$inp	# inp+=64*6
-+	xor		%r10,%r10
-+	vmovdqa		$xa3,0x00(%rsp)
-+	lea		0x180($out),$out	# out+=64*6
-+	sub		\$384,$len		# len-=64*6
-+	vmovdqa		$xb3,0x20(%rsp)
-+	jmp		.Loop_tail8x
-+
-+.align	32
-+.L448_or_more8x:
-+	vpxor		0x00($inp),$xa0,$xa0	# xor with input
-+	vpxor		0x20($inp),$xb0,$xb0
-+	vpxor		0x40($inp),$xc0,$xc0
-+	vpxor		0x60($inp),$xd0,$xd0
-+	vpxor		0x80($inp),$xa1,$xa1
-+	vpxor		0xa0($inp),$xb1,$xb1
-+	vpxor		0xc0($inp),$xc1,$xc1
-+	vpxor		0xe0($inp),$xd1,$xd1
-+	vpxor		0x100($inp),$xa2,$xa2
-+	vpxor		0x120($inp),$xb2,$xb2
-+	vpxor		0x140($inp),$xc2,$xc2
-+	vpxor		0x160($inp),$xd2,$xd2
-+	vpxor		0x180($inp),$xa3,$xa3
-+	vpxor		0x1a0($inp),$xb3,$xb3
-+	vmovdqu		$xa0,0x00($out)
-+	vmovdqu		$xb0,0x20($out)
-+	vmovdqu		$xc0,0x40($out)
-+	vmovdqu		$xd0,0x60($out)
-+	vmovdqu		$xa1,0x80($out)
-+	vmovdqu		$xb1,0xa0($out)
-+	vmovdqu		$xc1,0xc0($out)
-+	vmovdqu		$xd1,0xe0($out)
-+	vmovdqu		$xa2,0x100($out)
-+	vmovdqu		$xb2,0x120($out)
-+	vmovdqu		$xc2,0x140($out)
-+	vmovdqu		$xd2,0x160($out)
-+	vmovdqu		$xa3,0x180($out)
-+	vmovdqu		$xb3,0x1a0($out)
-+	je		.Ldone8x
-+
-+	lea		0x1c0($inp),$inp	# inp+=64*7
-+	xor		%r10,%r10
-+	vmovdqa		$xc3,0x00(%rsp)
-+	lea		0x1c0($out),$out	# out+=64*7
-+	sub		\$448,$len		# len-=64*7
-+	vmovdqa		$xd3,0x20(%rsp)
-+
-+.Loop_tail8x:
-+	movzb		($inp,%r10),%eax
-+	movzb		(%rsp,%r10),%ecx
-+	lea		1(%r10),%r10
-+	xor		%ecx,%eax
-+	mov		%al,-1($out,%r10)
-+	dec		$len
-+	jnz		.Loop_tail8x
-+
-+.Ldone8x:
-+	vzeroall
-+___
-+$code.=<<___	if ($win64);
-+	lea		0x290+0x30(%rsp),%r11
-+	movaps		-0x30(%r11),%xmm6
-+	movaps		-0x20(%r11),%xmm7
-+	movaps		-0x10(%r11),%xmm8
-+	movaps		0x00(%r11),%xmm9
-+	movaps		0x10(%r11),%xmm10
-+	movaps		0x20(%r11),%xmm11
-+	movaps		0x30(%r11),%xmm12
-+	movaps		0x40(%r11),%xmm13
-+	movaps		0x50(%r11),%xmm14
-+	movaps		0x60(%r11),%xmm15
-+___
-+$code.=<<___;
-+	mov		0x280(%rsp),%rsp
-+	ret
-+.size	ChaCha20_8x,.-ChaCha20_8x
-+___
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	s/%x#%y/%x/go;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/build.info
-new file mode 100644
-index 0000000..f99114c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/build.info
-@@ -0,0 +1,17 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]={- $target{chacha_asm_src} -}
-+
-+GENERATE[chacha-x86.s]=asm/chacha-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+GENERATE[chacha-x86_64.s]=asm/chacha-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[chacha-ppc.s]=asm/chacha-ppc.pl $(PERLASM_SCHEME)
-+GENERATE[chacha-armv4.S]=asm/chacha-armv4.pl $(PERLASM_SCHEME)
-+INCLUDE[chacha-armv4.o]=..
-+GENERATE[chacha-armv8.S]=asm/chacha-armv8.pl $(PERLASM_SCHEME)
-+INCLUDE[chacha-armv8.o]=..
-+
-+BEGINRAW[Makefile(unix)]
-+##### CHACHA assembler implementations
-+
-+{- $builddir -}/chacha-%.S:	{- $sourcedir -}/asm/chacha-%.pl
-+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-+ENDRAW[Makefile(unix)]
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/chacha_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/chacha_enc.c
-new file mode 100644
-index 0000000..239f68a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/chacha/chacha_enc.c
-@@ -0,0 +1,121 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Adapted from the public domain code by D. Bernstein from SUPERCOP. */
-+
-+#include 
-+
-+#include "internal/chacha.h"
-+
-+typedef unsigned int u32;
-+typedef unsigned char u8;
-+typedef union {
-+    u32 u[16];
-+    u8 c[64];
-+} chacha_buf;
-+
-+# define ROTATE(v, n) (((v) << (n)) | ((v) >> (32 - (n))))
-+
-+# define U32TO8_LITTLE(p, v) do { \
-+                                (p)[0] = (u8)(v >>  0); \
-+                                (p)[1] = (u8)(v >>  8); \
-+                                (p)[2] = (u8)(v >> 16); \
-+                                (p)[3] = (u8)(v >> 24); \
-+                                } while(0)
-+
-+/* QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. */
-+# define QUARTERROUND(a,b,c,d) ( \
-+                x[a] += x[b], x[d] = ROTATE((x[d] ^ x[a]),16), \
-+                x[c] += x[d], x[b] = ROTATE((x[b] ^ x[c]),12), \
-+                x[a] += x[b], x[d] = ROTATE((x[d] ^ x[a]), 8), \
-+                x[c] += x[d], x[b] = ROTATE((x[b] ^ x[c]), 7)  )
-+
-+/* chacha_core performs 20 rounds of ChaCha on the input words in
-+ * |input| and writes the 64 output bytes to |output|. */
-+static void chacha20_core(chacha_buf *output, const u32 input[16])
-+{
-+    u32 x[16];
-+    int i;
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+
-+    memcpy(x, input, sizeof(x));
-+
-+    for (i = 20; i > 0; i -= 2) {
-+        QUARTERROUND(0, 4, 8, 12);
-+        QUARTERROUND(1, 5, 9, 13);
-+        QUARTERROUND(2, 6, 10, 14);
-+        QUARTERROUND(3, 7, 11, 15);
-+        QUARTERROUND(0, 5, 10, 15);
-+        QUARTERROUND(1, 6, 11, 12);
-+        QUARTERROUND(2, 7, 8, 13);
-+        QUARTERROUND(3, 4, 9, 14);
-+    }
-+
-+    if (is_endian.little) {
-+        for (i = 0; i < 16; ++i)
-+            output->u[i] = x[i] + input[i];
-+    } else {
-+        for (i = 0; i < 16; ++i)
-+            U32TO8_LITTLE(output->c + 4 * i, (x[i] + input[i]));
-+    }
-+}
-+
-+void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
-+                    size_t len, const unsigned int key[8],
-+                    const unsigned int counter[4])
-+{
-+    u32 input[16];
-+    chacha_buf buf;
-+    size_t todo, i;
-+
-+    /* sigma constant "expand 32-byte k" in little-endian encoding */
-+    input[0] = ((u32)'e') | ((u32)'x'<<8) | ((u32)'p'<<16) | ((u32)'a'<<24);
-+    input[1] = ((u32)'n') | ((u32)'d'<<8) | ((u32)' '<<16) | ((u32)'3'<<24);
-+    input[2] = ((u32)'2') | ((u32)'-'<<8) | ((u32)'b'<<16) | ((u32)'y'<<24);
-+    input[3] = ((u32)'t') | ((u32)'e'<<8) | ((u32)' '<<16) | ((u32)'k'<<24);
-+
-+    input[4] = key[0];
-+    input[5] = key[1];
-+    input[6] = key[2];
-+    input[7] = key[3];
-+    input[8] = key[4];
-+    input[9] = key[5];
-+    input[10] = key[6];
-+    input[11] = key[7];
-+
-+    input[12] = counter[0];
-+    input[13] = counter[1];
-+    input[14] = counter[2];
-+    input[15] = counter[3];
-+
-+    while (len > 0) {
-+        todo = sizeof(buf);
-+        if (len < todo)
-+            todo = len;
-+
-+        chacha20_core(&buf, input);
-+
-+        for (i = 0; i < todo; i++)
-+            out[i] = inp[i] ^ buf.c[i];
-+        out += todo;
-+        inp += todo;
-+        len -= todo;
-+
-+        /*
-+         * Advance 32-bit counter. Note that as subroutine is so to
-+         * say nonce-agnostic, this limited counter width doesn't
-+         * prevent caller from implementing wider counter. It would
-+         * simply take two calls split on counter overflow...
-+         */
-+        input[12]++;
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/build.info
-new file mode 100644
-index 0000000..c8a4949
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/build.info
-@@ -0,0 +1,2 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=cmac.c cm_ameth.c cm_pmeth.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cm_ameth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cm_ameth.c
-new file mode 100644
-index 0000000..a58454a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cm_ameth.c
-@@ -0,0 +1,51 @@
-+/*
-+ * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+
-+/*
-+ * CMAC "ASN1" method. This is just here to indicate the maximum CMAC output
-+ * length and to free up a CMAC key.
-+ */
-+
-+static int cmac_size(const EVP_PKEY *pkey)
-+{
-+    return EVP_MAX_BLOCK_LENGTH;
-+}
-+
-+static void cmac_key_free(EVP_PKEY *pkey)
-+{
-+    CMAC_CTX *cmctx = EVP_PKEY_get0(pkey);
-+    CMAC_CTX_free(cmctx);
-+}
-+
-+const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = {
-+    EVP_PKEY_CMAC,
-+    EVP_PKEY_CMAC,
-+    0,
-+
-+    "CMAC",
-+    "OpenSSL CMAC method",
-+
-+    0, 0, 0, 0,
-+
-+    0, 0, 0,
-+
-+    cmac_size,
-+    0, 0,
-+    0, 0, 0, 0, 0, 0, 0,
-+
-+    cmac_key_free,
-+    0,
-+    0, 0
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cm_pmeth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cm_pmeth.c
-new file mode 100644
-index 0000000..10748f1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cm_pmeth.c
-@@ -0,0 +1,161 @@
-+/*
-+ * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+/* The context structure and "key" is simply a CMAC_CTX */
-+
-+static int pkey_cmac_init(EVP_PKEY_CTX *ctx)
-+{
-+    ctx->data = CMAC_CTX_new();
-+    if (ctx->data == NULL)
-+        return 0;
-+    ctx->keygen_info_count = 0;
-+    return 1;
-+}
-+
-+static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
-+{
-+    if (!pkey_cmac_init(dst))
-+        return 0;
-+    if (!CMAC_CTX_copy(dst->data, src->data))
-+        return 0;
-+    return 1;
-+}
-+
-+static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx)
-+{
-+    CMAC_CTX_free(ctx->data);
-+}
-+
-+static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    CMAC_CTX *cmkey = CMAC_CTX_new();
-+    CMAC_CTX *cmctx = ctx->data;
-+    if (cmkey == NULL)
-+        return 0;
-+    if (!CMAC_CTX_copy(cmkey, cmctx)) {
-+        CMAC_CTX_free(cmkey);
-+        return 0;
-+    }
-+    EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey);
-+
-+    return 1;
-+}
-+
-+static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    if (!CMAC_Update(EVP_MD_CTX_pkey_ctx(ctx)->data, data, count))
-+        return 0;
-+    return 1;
-+}
-+
-+static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
-+{
-+    EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
-+    EVP_MD_CTX_set_update_fn(mctx, int_update);
-+    return 1;
-+}
-+
-+static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
-+                        EVP_MD_CTX *mctx)
-+{
-+    return CMAC_Final(ctx->data, sig, siglen);
-+}
-+
-+static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-+{
-+    CMAC_CTX *cmctx = ctx->data;
-+    switch (type) {
-+
-+    case EVP_PKEY_CTRL_SET_MAC_KEY:
-+        if (!p2 || p1 < 0)
-+            return 0;
-+        if (!CMAC_Init(cmctx, p2, p1, NULL, NULL))
-+            return 0;
-+        break;
-+
-+    case EVP_PKEY_CTRL_CIPHER:
-+        if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine))
-+            return 0;
-+        break;
-+
-+    case EVP_PKEY_CTRL_MD:
-+        if (ctx->pkey && !CMAC_CTX_copy(ctx->data,
-+                                        (CMAC_CTX *)ctx->pkey->pkey.ptr))
-+            return 0;
-+        if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL))
-+            return 0;
-+        break;
-+
-+    default:
-+        return -2;
-+
-+    }
-+    return 1;
-+}
-+
-+static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx,
-+                              const char *type, const char *value)
-+{
-+    if (!value) {
-+        return 0;
-+    }
-+    if (strcmp(type, "cipher") == 0) {
-+        const EVP_CIPHER *c;
-+        c = EVP_get_cipherbyname(value);
-+        if (!c)
-+            return 0;
-+        return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c);
-+    }
-+    if (strcmp(type, "key") == 0)
-+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
-+    if (strcmp(type, "hexkey") == 0)
-+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
-+    return -2;
-+}
-+
-+const EVP_PKEY_METHOD cmac_pkey_meth = {
-+    EVP_PKEY_CMAC,
-+    EVP_PKEY_FLAG_SIGCTX_CUSTOM,
-+    pkey_cmac_init,
-+    pkey_cmac_copy,
-+    pkey_cmac_cleanup,
-+
-+    0, 0,
-+
-+    0,
-+    pkey_cmac_keygen,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    cmac_signctx_init,
-+    cmac_signctx,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    pkey_cmac_ctrl,
-+    pkey_cmac_ctrl_str
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cmac.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cmac.c
-new file mode 100644
-index 0000000..c4f13a0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cmac/cmac.c
-@@ -0,0 +1,223 @@
-+/*
-+ * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+struct CMAC_CTX_st {
-+    /* Cipher context to use */
-+    EVP_CIPHER_CTX *cctx;
-+    /* Keys k1 and k2 */
-+    unsigned char k1[EVP_MAX_BLOCK_LENGTH];
-+    unsigned char k2[EVP_MAX_BLOCK_LENGTH];
-+    /* Temporary block */
-+    unsigned char tbl[EVP_MAX_BLOCK_LENGTH];
-+    /* Last (possibly partial) block */
-+    unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
-+    /* Number of bytes in last block: -1 means context not initialised */
-+    int nlast_block;
-+};
-+
-+/* Make temporary keys K1 and K2 */
-+
-+static void make_kn(unsigned char *k1, const unsigned char *l, int bl)
-+{
-+    int i;
-+    unsigned char c = l[0], carry = c >> 7, cnext;
-+
-+    /* Shift block to left, including carry */
-+    for (i = 0; i < bl - 1; i++, c = cnext)
-+        k1[i] = (c << 1) | ((cnext = l[i + 1]) >> 7);
-+
-+    /* If MSB set fixup with R */
-+    k1[i] = (c << 1) ^ ((0 - carry) & (bl == 16 ? 0x87 : 0x1b));
-+}
-+
-+CMAC_CTX *CMAC_CTX_new(void)
-+{
-+    CMAC_CTX *ctx;
-+
-+    ctx = OPENSSL_malloc(sizeof(*ctx));
-+    if (ctx == NULL)
-+        return NULL;
-+    ctx->cctx = EVP_CIPHER_CTX_new();
-+    if (ctx->cctx == NULL) {
-+        OPENSSL_free(ctx);
-+        return NULL;
-+    }
-+    ctx->nlast_block = -1;
-+    return ctx;
-+}
-+
-+void CMAC_CTX_cleanup(CMAC_CTX *ctx)
-+{
-+    EVP_CIPHER_CTX_free(ctx->cctx);
-+    OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
-+    OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
-+    OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH);
-+    OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
-+    ctx->nlast_block = -1;
-+}
-+
-+EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
-+{
-+    return ctx->cctx;
-+}
-+
-+void CMAC_CTX_free(CMAC_CTX *ctx)
-+{
-+    if (!ctx)
-+        return;
-+    CMAC_CTX_cleanup(ctx);
-+    OPENSSL_free(ctx);
-+}
-+
-+int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
-+{
-+    int bl;
-+    if (in->nlast_block == -1)
-+        return 0;
-+    if (!EVP_CIPHER_CTX_copy(out->cctx, in->cctx))
-+        return 0;
-+    bl = EVP_CIPHER_CTX_block_size(in->cctx);
-+    memcpy(out->k1, in->k1, bl);
-+    memcpy(out->k2, in->k2, bl);
-+    memcpy(out->tbl, in->tbl, bl);
-+    memcpy(out->last_block, in->last_block, bl);
-+    out->nlast_block = in->nlast_block;
-+    return 1;
-+}
-+
-+int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
-+              const EVP_CIPHER *cipher, ENGINE *impl)
-+{
-+    static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = { 0 };
-+    /* All zeros means restart */
-+    if (!key && !cipher && !impl && keylen == 0) {
-+        /* Not initialised */
-+        if (ctx->nlast_block == -1)
-+            return 0;
-+        if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
-+            return 0;
-+        memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(ctx->cctx));
-+        ctx->nlast_block = 0;
-+        return 1;
-+    }
-+    /* Initialise context */
-+    if (cipher && !EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL))
-+        return 0;
-+    /* Non-NULL key means initialisation complete */
-+    if (key) {
-+        int bl;
-+        if (!EVP_CIPHER_CTX_cipher(ctx->cctx))
-+            return 0;
-+        if (!EVP_CIPHER_CTX_set_key_length(ctx->cctx, keylen))
-+            return 0;
-+        if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, key, zero_iv))
-+            return 0;
-+        bl = EVP_CIPHER_CTX_block_size(ctx->cctx);
-+        if (!EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl))
-+            return 0;
-+        make_kn(ctx->k1, ctx->tbl, bl);
-+        make_kn(ctx->k2, ctx->k1, bl);
-+        OPENSSL_cleanse(ctx->tbl, bl);
-+        /* Reset context again ready for first data block */
-+        if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
-+            return 0;
-+        /* Zero tbl so resume works */
-+        memset(ctx->tbl, 0, bl);
-+        ctx->nlast_block = 0;
-+    }
-+    return 1;
-+}
-+
-+int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
-+{
-+    const unsigned char *data = in;
-+    size_t bl;
-+    if (ctx->nlast_block == -1)
-+        return 0;
-+    if (dlen == 0)
-+        return 1;
-+    bl = EVP_CIPHER_CTX_block_size(ctx->cctx);
-+    /* Copy into partial block if we need to */
-+    if (ctx->nlast_block > 0) {
-+        size_t nleft;
-+        nleft = bl - ctx->nlast_block;
-+        if (dlen < nleft)
-+            nleft = dlen;
-+        memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
-+        dlen -= nleft;
-+        ctx->nlast_block += nleft;
-+        /* If no more to process return */
-+        if (dlen == 0)
-+            return 1;
-+        data += nleft;
-+        /* Else not final block so encrypt it */
-+        if (!EVP_Cipher(ctx->cctx, ctx->tbl, ctx->last_block, bl))
-+            return 0;
-+    }
-+    /* Encrypt all but one of the complete blocks left */
-+    while (dlen > bl) {
-+        if (!EVP_Cipher(ctx->cctx, ctx->tbl, data, bl))
-+            return 0;
-+        dlen -= bl;
-+        data += bl;
-+    }
-+    /* Copy any data left to last block buffer */
-+    memcpy(ctx->last_block, data, dlen);
-+    ctx->nlast_block = dlen;
-+    return 1;
-+
-+}
-+
-+int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
-+{
-+    int i, bl, lb;
-+    if (ctx->nlast_block == -1)
-+        return 0;
-+    bl = EVP_CIPHER_CTX_block_size(ctx->cctx);
-+    *poutlen = (size_t)bl;
-+    if (!out)
-+        return 1;
-+    lb = ctx->nlast_block;
-+    /* Is last block complete? */
-+    if (lb == bl) {
-+        for (i = 0; i < bl; i++)
-+            out[i] = ctx->last_block[i] ^ ctx->k1[i];
-+    } else {
-+        ctx->last_block[lb] = 0x80;
-+        if (bl - lb > 1)
-+            memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
-+        for (i = 0; i < bl; i++)
-+            out[i] = ctx->last_block[i] ^ ctx->k2[i];
-+    }
-+    if (!EVP_Cipher(ctx->cctx, out, out, bl)) {
-+        OPENSSL_cleanse(out, bl);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+int CMAC_resume(CMAC_CTX *ctx)
-+{
-+    if (ctx->nlast_block == -1)
-+        return 0;
-+    /*
-+     * The buffer "tbl" contains the last fully encrypted block which is the
-+     * last IV (or all zeroes if no last encrypted block). The last block has
-+     * not been modified since CMAC_final(). So reinitialising using the last
-+     * decrypted block will allow CMAC to continue after calling
-+     * CMAC_Final().
-+     */
-+    return EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, ctx->tbl);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/build.info
-new file mode 100644
-index 0000000..cb67543
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/build.info
-@@ -0,0 +1,5 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]= \
-+        cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \
-+        cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c \
-+        cms_pwri.c cms_kari.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_asn1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_asn1.c
-new file mode 100644
-index 0000000..81e9a53
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_asn1.c
-@@ -0,0 +1,402 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+
-+
-+ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = {
-+        ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME),
-+        ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER)
-+} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber)
-+
-+ASN1_SEQUENCE(CMS_OtherCertificateFormat) = {
-+        ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT),
-+        ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY)
-+} static_ASN1_SEQUENCE_END(CMS_OtherCertificateFormat)
-+
-+ASN1_CHOICE(CMS_CertificateChoices) = {
-+        ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509),
-+        ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0),
-+        ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1),
-+        ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2),
-+        ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3)
-+} ASN1_CHOICE_END(CMS_CertificateChoices)
-+
-+ASN1_CHOICE(CMS_SignerIdentifier) = {
-+        ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
-+        ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0)
-+} static_ASN1_CHOICE_END(CMS_SignerIdentifier)
-+
-+ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = {
-+        ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT),
-+        ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0)
-+} static_ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo)
-+
-+/* Minor tweak to operation: free up signer key, cert */
-+static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                     void *exarg)
-+{
-+    if (operation == ASN1_OP_FREE_POST) {
-+        CMS_SignerInfo *si = (CMS_SignerInfo *)*pval;
-+        EVP_PKEY_free(si->pkey);
-+        X509_free(si->signer);
-+        EVP_MD_CTX_free(si->mctx);
-+    }
-+    return 1;
-+}
-+
-+ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = {
-+        ASN1_SIMPLE(CMS_SignerInfo, version, LONG),
-+        ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier),
-+        ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR),
-+        ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0),
-+        ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR),
-+        ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING),
-+        ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1)
-+} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo)
-+
-+ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = {
-+        ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT),
-+        ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY)
-+} static_ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat)
-+
-+ASN1_CHOICE(CMS_RevocationInfoChoice) = {
-+        ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL),
-+        ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1)
-+} ASN1_CHOICE_END(CMS_RevocationInfoChoice)
-+
-+ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
-+        ASN1_SIMPLE(CMS_SignedData, version, LONG),
-+        ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR),
-+        ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo),
-+        ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
-+        ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1),
-+        ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo)
-+} ASN1_NDEF_SEQUENCE_END(CMS_SignedData)
-+
-+ASN1_SEQUENCE(CMS_OriginatorInfo) = {
-+        ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0),
-+        ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1)
-+} static_ASN1_SEQUENCE_END(CMS_OriginatorInfo)
-+
-+ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
-+        ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT),
-+        ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR),
-+        ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0)
-+} static_ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo)
-+
-+ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = {
-+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG),
-+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier),
-+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
-+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
-+} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo)
-+
-+ASN1_SEQUENCE(CMS_OtherKeyAttribute) = {
-+        ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT),
-+        ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY)
-+} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute)
-+
-+ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = {
-+        ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING),
-+        ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME),
-+        ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute)
-+} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier)
-+
-+ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = {
-+  ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
-+  ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0)
-+} static_ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier)
-+
-+static int cms_rek_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                      void *exarg)
-+{
-+    CMS_RecipientEncryptedKey *rek = (CMS_RecipientEncryptedKey *)*pval;
-+    if (operation == ASN1_OP_FREE_POST) {
-+        EVP_PKEY_free(rek->pkey);
-+    }
-+    return 1;
-+}
-+
-+ASN1_SEQUENCE_cb(CMS_RecipientEncryptedKey, cms_rek_cb) = {
-+        ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier),
-+        ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING)
-+} ASN1_SEQUENCE_END_cb(CMS_RecipientEncryptedKey, CMS_RecipientEncryptedKey)
-+
-+ASN1_SEQUENCE(CMS_OriginatorPublicKey) = {
-+  ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR),
-+  ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING)
-+} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey)
-+
-+ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = {
-+  ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
-+  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0),
-+  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1)
-+} static_ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey)
-+
-+static int cms_kari_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                       void *exarg)
-+{
-+    CMS_KeyAgreeRecipientInfo *kari = (CMS_KeyAgreeRecipientInfo *)*pval;
-+    if (operation == ASN1_OP_NEW_POST) {
-+        kari->ctx = EVP_CIPHER_CTX_new();
-+        if (kari->ctx == NULL)
-+            return 0;
-+        EVP_CIPHER_CTX_set_flags(kari->ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
-+        kari->pctx = NULL;
-+    } else if (operation == ASN1_OP_FREE_POST) {
-+        EVP_PKEY_CTX_free(kari->pctx);
-+        EVP_CIPHER_CTX_free(kari->ctx);
-+    }
-+    return 1;
-+}
-+
-+ASN1_SEQUENCE_cb(CMS_KeyAgreeRecipientInfo, cms_kari_cb) = {
-+        ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG),
-+        ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0),
-+        ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1),
-+        ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
-+        ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey)
-+} ASN1_SEQUENCE_END_cb(CMS_KeyAgreeRecipientInfo, CMS_KeyAgreeRecipientInfo)
-+
-+ASN1_SEQUENCE(CMS_KEKIdentifier) = {
-+        ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING),
-+        ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME),
-+        ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute)
-+} static_ASN1_SEQUENCE_END(CMS_KEKIdentifier)
-+
-+ASN1_SEQUENCE(CMS_KEKRecipientInfo) = {
-+        ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG),
-+        ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier),
-+        ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
-+        ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
-+} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo)
-+
-+ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = {
-+        ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG),
-+        ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0),
-+        ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
-+        ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
-+} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo)
-+
-+ASN1_SEQUENCE(CMS_OtherRecipientInfo) = {
-+  ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT),
-+  ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY)
-+} static_ASN1_SEQUENCE_END(CMS_OtherRecipientInfo)
-+
-+/* Free up RecipientInfo additional data */
-+static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                     void *exarg)
-+{
-+    if (operation == ASN1_OP_FREE_PRE) {
-+        CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval;
-+        if (ri->type == CMS_RECIPINFO_TRANS) {
-+            CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
-+            EVP_PKEY_free(ktri->pkey);
-+            X509_free(ktri->recip);
-+            EVP_PKEY_CTX_free(ktri->pctx);
-+        } else if (ri->type == CMS_RECIPINFO_KEK) {
-+            CMS_KEKRecipientInfo *kekri = ri->d.kekri;
-+            OPENSSL_clear_free(kekri->key, kekri->keylen);
-+        } else if (ri->type == CMS_RECIPINFO_PASS) {
-+            CMS_PasswordRecipientInfo *pwri = ri->d.pwri;
-+            OPENSSL_clear_free(pwri->pass, pwri->passlen);
-+        }
-+    }
-+    return 1;
-+}
-+
-+ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = {
-+        ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo),
-+        ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1),
-+        ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2),
-+        ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3),
-+        ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4)
-+} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type)
-+
-+ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
-+        ASN1_SIMPLE(CMS_EnvelopedData, version, LONG),
-+        ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0),
-+        ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo),
-+        ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
-+        ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
-+} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)
-+
-+ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
-+        ASN1_SIMPLE(CMS_DigestedData, version, LONG),
-+        ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR),
-+        ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo),
-+        ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING)
-+} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData)
-+
-+ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = {
-+        ASN1_SIMPLE(CMS_EncryptedData, version, LONG),
-+        ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo),
-+        ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
-+} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData)
-+
-+ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
-+        ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG),
-+        ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0),
-+        ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo),
-+        ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR),
-+        ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1),
-+        ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo),
-+        ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2),
-+        ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING),
-+        ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3)
-+} static_ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData)
-+
-+ASN1_NDEF_SEQUENCE(CMS_CompressedData) = {
-+        ASN1_SIMPLE(CMS_CompressedData, version, LONG),
-+        ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR),
-+        ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo),
-+} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData)
-+
-+/* This is the ANY DEFINED BY table for the top level ContentInfo structure */
-+
-+ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0);
-+
-+ASN1_ADB(CMS_ContentInfo) = {
-+        ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)),
-+        ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)),
-+        ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)),
-+        ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)),
-+        ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)),
-+        ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)),
-+        ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)),
-+} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL);
-+
-+/* CMS streaming support */
-+static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                  void *exarg)
-+{
-+    ASN1_STREAM_ARG *sarg = exarg;
-+    CMS_ContentInfo *cms = NULL;
-+    if (pval)
-+        cms = (CMS_ContentInfo *)*pval;
-+    else
-+        return 1;
-+    switch (operation) {
-+
-+    case ASN1_OP_STREAM_PRE:
-+        if (CMS_stream(&sarg->boundary, cms) <= 0)
-+            return 0;
-+    case ASN1_OP_DETACHED_PRE:
-+        sarg->ndef_bio = CMS_dataInit(cms, sarg->out);
-+        if (!sarg->ndef_bio)
-+            return 0;
-+        break;
-+
-+    case ASN1_OP_STREAM_POST:
-+    case ASN1_OP_DETACHED_POST:
-+        if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0)
-+            return 0;
-+        break;
-+
-+    }
-+    return 1;
-+}
-+
-+ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = {
-+        ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT),
-+        ASN1_ADB_OBJECT(CMS_ContentInfo)
-+} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo)
-+
-+/* Specials for signed attributes */
-+
-+/*
-+ * When signing attributes we want to reorder them to match the sorted
-+ * encoding.
-+ */
-+
-+ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) =
-+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE)
-+ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign)
-+
-+/*
-+ * When verifying attributes we need to use the received order. So we use
-+ * SEQUENCE OF and tag it to SET OF
-+ */
-+
-+ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) =
-+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
-+                                V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE)
-+ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify)
-+
-+
-+
-+ASN1_CHOICE(CMS_ReceiptsFrom) = {
-+  ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0),
-+  ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1)
-+} static_ASN1_CHOICE_END(CMS_ReceiptsFrom)
-+
-+ASN1_SEQUENCE(CMS_ReceiptRequest) = {
-+  ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING),
-+  ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom),
-+  ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
-+} ASN1_SEQUENCE_END(CMS_ReceiptRequest)
-+
-+ASN1_SEQUENCE(CMS_Receipt) = {
-+  ASN1_SIMPLE(CMS_Receipt, version, LONG),
-+  ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT),
-+  ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING),
-+  ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING)
-+} ASN1_SEQUENCE_END(CMS_Receipt)
-+
-+/*
-+ * Utilities to encode the CMS_SharedInfo structure used during key
-+ * derivation.
-+ */
-+
-+typedef struct {
-+    X509_ALGOR *keyInfo;
-+    ASN1_OCTET_STRING *entityUInfo;
-+    ASN1_OCTET_STRING *suppPubInfo;
-+} CMS_SharedInfo;
-+
-+ASN1_SEQUENCE(CMS_SharedInfo) = {
-+  ASN1_SIMPLE(CMS_SharedInfo, keyInfo, X509_ALGOR),
-+  ASN1_EXP_OPT(CMS_SharedInfo, entityUInfo, ASN1_OCTET_STRING, 0),
-+  ASN1_EXP_OPT(CMS_SharedInfo, suppPubInfo, ASN1_OCTET_STRING, 2),
-+} static_ASN1_SEQUENCE_END(CMS_SharedInfo)
-+
-+int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg,
-+                          ASN1_OCTET_STRING *ukm, int keylen)
-+{
-+    union {
-+        CMS_SharedInfo *pecsi;
-+        ASN1_VALUE *a;
-+    } intsi = {
-+        NULL
-+    };
-+
-+    ASN1_OCTET_STRING oklen;
-+    unsigned char kl[4];
-+    CMS_SharedInfo ecsi;
-+
-+    keylen <<= 3;
-+    kl[0] = (keylen >> 24) & 0xff;
-+    kl[1] = (keylen >> 16) & 0xff;
-+    kl[2] = (keylen >> 8) & 0xff;
-+    kl[3] = keylen & 0xff;
-+    oklen.length = 4;
-+    oklen.data = kl;
-+    oklen.type = V_ASN1_OCTET_STRING;
-+    oklen.flags = 0;
-+    ecsi.keyInfo = kekalg;
-+    ecsi.entityUInfo = ukm;
-+    ecsi.suppPubInfo = &oklen;
-+    intsi.pecsi = &ecsi;
-+    return ASN1_item_i2d(intsi.a, pder, ASN1_ITEM_rptr(CMS_SharedInfo));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_att.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_att.c
-new file mode 100644
-index 0000000..664e649
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_att.c
-@@ -0,0 +1,152 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+
-+/* CMS SignedData Attribute utilities */
-+
-+int CMS_signed_get_attr_count(const CMS_SignerInfo *si)
-+{
-+    return X509at_get_attr_count(si->signedAttrs);
-+}
-+
-+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos)
-+{
-+    return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos);
-+}
-+
-+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj,
-+                               int lastpos)
-+{
-+    return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos);
-+}
-+
-+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc)
-+{
-+    return X509at_get_attr(si->signedAttrs, loc);
-+}
-+
-+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
-+{
-+    return X509at_delete_attr(si->signedAttrs, loc);
-+}
-+
-+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
-+{
-+    if (X509at_add1_attr(&si->signedAttrs, attr))
-+        return 1;
-+    return 0;
-+}
-+
-+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
-+                                const ASN1_OBJECT *obj, int type,
-+                                const void *bytes, int len)
-+{
-+    if (X509at_add1_attr_by_OBJ(&si->signedAttrs, obj, type, bytes, len))
-+        return 1;
-+    return 0;
-+}
-+
-+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
-+                                int nid, int type, const void *bytes, int len)
-+{
-+    if (X509at_add1_attr_by_NID(&si->signedAttrs, nid, type, bytes, len))
-+        return 1;
-+    return 0;
-+}
-+
-+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
-+                                const char *attrname, int type,
-+                                const void *bytes, int len)
-+{
-+    if (X509at_add1_attr_by_txt(&si->signedAttrs, attrname, type, bytes, len))
-+        return 1;
-+    return 0;
-+}
-+
-+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid,
-+                                  int lastpos, int type)
-+{
-+    return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type);
-+}
-+
-+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si)
-+{
-+    return X509at_get_attr_count(si->unsignedAttrs);
-+}
-+
-+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
-+                                 int lastpos)
-+{
-+    return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos);
-+}
-+
-+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si,
-+                                 const ASN1_OBJECT *obj, int lastpos)
-+{
-+    return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos);
-+}
-+
-+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc)
-+{
-+    return X509at_get_attr(si->unsignedAttrs, loc);
-+}
-+
-+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
-+{
-+    return X509at_delete_attr(si->unsignedAttrs, loc);
-+}
-+
-+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
-+{
-+    if (X509at_add1_attr(&si->unsignedAttrs, attr))
-+        return 1;
-+    return 0;
-+}
-+
-+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
-+                                  const ASN1_OBJECT *obj, int type,
-+                                  const void *bytes, int len)
-+{
-+    if (X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, type, bytes, len))
-+        return 1;
-+    return 0;
-+}
-+
-+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
-+                                  int nid, int type,
-+                                  const void *bytes, int len)
-+{
-+    if (X509at_add1_attr_by_NID(&si->unsignedAttrs, nid, type, bytes, len))
-+        return 1;
-+    return 0;
-+}
-+
-+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
-+                                  const char *attrname, int type,
-+                                  const void *bytes, int len)
-+{
-+    if (X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
-+                                type, bytes, len))
-+        return 1;
-+    return 0;
-+}
-+
-+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
-+                                    int lastpos, int type)
-+{
-+    return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
-+}
-+
-+/* Specific attribute cases */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_cd.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_cd.c
-new file mode 100644
-index 0000000..f05e308
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_cd.c
-@@ -0,0 +1,82 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+
-+#ifdef ZLIB
-+
-+/* CMS CompressedData Utilities */
-+
-+CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
-+{
-+    CMS_ContentInfo *cms;
-+    CMS_CompressedData *cd;
-+    /*
-+     * Will need something cleverer if there is ever more than one
-+     * compression algorithm or parameters have some meaning...
-+     */
-+    if (comp_nid != NID_zlib_compression) {
-+        CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE,
-+               CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
-+        return NULL;
-+    }
-+    cms = CMS_ContentInfo_new();
-+    if (cms == NULL)
-+        return NULL;
-+
-+    cd = M_ASN1_new_of(CMS_CompressedData);
-+
-+    if (cd == NULL)
-+        goto err;
-+
-+    cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData);
-+    cms->d.compressedData = cd;
-+
-+    cd->version = 0;
-+
-+    X509_ALGOR_set0(cd->compressionAlgorithm,
-+                    OBJ_nid2obj(NID_zlib_compression), V_ASN1_UNDEF, NULL);
-+
-+    cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
-+
-+    return cms;
-+
-+ err:
-+    CMS_ContentInfo_free(cms);
-+    return NULL;
-+}
-+
-+BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms)
-+{
-+    CMS_CompressedData *cd;
-+    const ASN1_OBJECT *compoid;
-+    if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) {
-+        CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
-+               CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
-+        return NULL;
-+    }
-+    cd = cms->d.compressedData;
-+    X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm);
-+    if (OBJ_obj2nid(compoid) != NID_zlib_compression) {
-+        CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
-+               CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
-+        return NULL;
-+    }
-+    return BIO_new(BIO_f_zlib());
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_dd.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_dd.c
-new file mode 100644
-index 0000000..5da6802
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_dd.c
-@@ -0,0 +1,99 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+
-+/* CMS DigestedData Utilities */
-+
-+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
-+{
-+    CMS_ContentInfo *cms;
-+    CMS_DigestedData *dd;
-+    cms = CMS_ContentInfo_new();
-+    if (cms == NULL)
-+        return NULL;
-+
-+    dd = M_ASN1_new_of(CMS_DigestedData);
-+
-+    if (dd == NULL)
-+        goto err;
-+
-+    cms->contentType = OBJ_nid2obj(NID_pkcs7_digest);
-+    cms->d.digestedData = dd;
-+
-+    dd->version = 0;
-+    dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
-+
-+    X509_ALGOR_set_md(dd->digestAlgorithm, md);
-+
-+    return cms;
-+
-+ err:
-+    CMS_ContentInfo_free(cms);
-+    return NULL;
-+}
-+
-+BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
-+{
-+    CMS_DigestedData *dd;
-+    dd = cms->d.digestedData;
-+    return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
-+}
-+
-+int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
-+{
-+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-+    unsigned char md[EVP_MAX_MD_SIZE];
-+    unsigned int mdlen;
-+    int r = 0;
-+    CMS_DigestedData *dd;
-+
-+    if (mctx == NULL) {
-+        CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    dd = cms->d.digestedData;
-+
-+    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, dd->digestAlgorithm))
-+        goto err;
-+
-+    if (EVP_DigestFinal_ex(mctx, md, &mdlen) <= 0)
-+        goto err;
-+
-+    if (verify) {
-+        if (mdlen != (unsigned int)dd->digest->length) {
-+            CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
-+                   CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
-+            goto err;
-+        }
-+
-+        if (memcmp(md, dd->digest->data, mdlen))
-+            CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
-+                   CMS_R_VERIFICATION_FAILURE);
-+        else
-+            r = 1;
-+    } else {
-+        if (!ASN1_STRING_set(dd->digest, md, mdlen))
-+            goto err;
-+        r = 1;
-+    }
-+
-+ err:
-+    EVP_MD_CTX_free(mctx);
-+
-+    return r;
-+
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_enc.c
-new file mode 100644
-index 0000000..ed91342
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_enc.c
-@@ -0,0 +1,212 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+
-+/* CMS EncryptedData Utilities */
-+
-+/* Return BIO based on EncryptedContentInfo and key */
-+
-+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
-+{
-+    BIO *b;
-+    EVP_CIPHER_CTX *ctx;
-+    const EVP_CIPHER *ciph;
-+    X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
-+    unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
-+    unsigned char *tkey = NULL;
-+    size_t tkeylen = 0;
-+
-+    int ok = 0;
-+
-+    int enc, keep_key = 0;
-+
-+    enc = ec->cipher ? 1 : 0;
-+
-+    b = BIO_new(BIO_f_cipher());
-+    if (b == NULL) {
-+        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    BIO_get_cipher_ctx(b, &ctx);
-+
-+    if (enc) {
-+        ciph = ec->cipher;
-+        /*
-+         * If not keeping key set cipher to NULL so subsequent calls decrypt.
-+         */
-+        if (ec->key)
-+            ec->cipher = NULL;
-+    } else {
-+        ciph = EVP_get_cipherbyobj(calg->algorithm);
-+
-+        if (!ciph) {
-+            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER);
-+            goto err;
-+        }
-+    }
-+
-+    if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) {
-+        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
-+               CMS_R_CIPHER_INITIALISATION_ERROR);
-+        goto err;
-+    }
-+
-+    if (enc) {
-+        int ivlen;
-+        calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
-+        /* Generate a random IV if we need one */
-+        ivlen = EVP_CIPHER_CTX_iv_length(ctx);
-+        if (ivlen > 0) {
-+            if (RAND_bytes(iv, ivlen) <= 0)
-+                goto err;
-+            piv = iv;
-+        }
-+    } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) {
-+        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
-+               CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
-+        goto err;
-+    }
-+    tkeylen = EVP_CIPHER_CTX_key_length(ctx);
-+    /* Generate random session key */
-+    if (!enc || !ec->key) {
-+        tkey = OPENSSL_malloc(tkeylen);
-+        if (tkey == NULL) {
-+            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
-+            goto err;
-+    }
-+
-+    if (!ec->key) {
-+        ec->key = tkey;
-+        ec->keylen = tkeylen;
-+        tkey = NULL;
-+        if (enc)
-+            keep_key = 1;
-+        else
-+            ERR_clear_error();
-+
-+    }
-+
-+    if (ec->keylen != tkeylen) {
-+        /* If necessary set key length */
-+        if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) {
-+            /*
-+             * Only reveal failure if debugging so we don't leak information
-+             * which may be useful in MMA.
-+             */
-+            if (enc || ec->debug) {
-+                CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
-+                       CMS_R_INVALID_KEY_LENGTH);
-+                goto err;
-+            } else {
-+                /* Use random key */
-+                OPENSSL_clear_free(ec->key, ec->keylen);
-+                ec->key = tkey;
-+                ec->keylen = tkeylen;
-+                tkey = NULL;
-+                ERR_clear_error();
-+            }
-+        }
-+    }
-+
-+    if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) {
-+        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
-+               CMS_R_CIPHER_INITIALISATION_ERROR);
-+        goto err;
-+    }
-+    if (enc) {
-+        calg->parameter = ASN1_TYPE_new();
-+        if (calg->parameter == NULL) {
-+            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) {
-+            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
-+                   CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
-+            goto err;
-+        }
-+        /* If parameter type not set omit parameter */
-+        if (calg->parameter->type == V_ASN1_UNDEF) {
-+            ASN1_TYPE_free(calg->parameter);
-+            calg->parameter = NULL;
-+        }
-+    }
-+    ok = 1;
-+
-+ err:
-+    if (!keep_key || !ok) {
-+        OPENSSL_clear_free(ec->key, ec->keylen);
-+        ec->key = NULL;
-+    }
-+    OPENSSL_clear_free(tkey, tkeylen);
-+    if (ok)
-+        return b;
-+    BIO_free(b);
-+    return NULL;
-+}
-+
-+int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
-+                              const EVP_CIPHER *cipher,
-+                              const unsigned char *key, size_t keylen)
-+{
-+    ec->cipher = cipher;
-+    if (key) {
-+        ec->key = OPENSSL_malloc(keylen);
-+        if (ec->key == NULL)
-+            return 0;
-+        memcpy(ec->key, key, keylen);
-+    }
-+    ec->keylen = keylen;
-+    if (cipher)
-+        ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
-+    return 1;
-+}
-+
-+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
-+                               const unsigned char *key, size_t keylen)
-+{
-+    CMS_EncryptedContentInfo *ec;
-+    if (!key || !keylen) {
-+        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
-+        return 0;
-+    }
-+    if (ciph) {
-+        cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
-+        if (!cms->d.encryptedData) {
-+            CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
-+        cms->d.encryptedData->version = 0;
-+    } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) {
-+        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NOT_ENCRYPTED_DATA);
-+        return 0;
-+    }
-+    ec = cms->d.encryptedData->encryptedContentInfo;
-+    return cms_EncryptedContent_init(ec, ciph, key, keylen);
-+}
-+
-+BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
-+{
-+    CMS_EncryptedData *enc = cms->d.encryptedData;
-+    if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
-+        enc->version = 2;
-+    return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_env.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_env.c
-new file mode 100644
-index 0000000..8d45943
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_env.c
-@@ -0,0 +1,902 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+/* CMS EnvelopedData Utilities */
-+
-+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
-+{
-+    if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) {
-+        CMSerr(CMS_F_CMS_GET0_ENVELOPED,
-+               CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
-+        return NULL;
-+    }
-+    return cms->d.envelopedData;
-+}
-+
-+static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
-+{
-+    if (cms->d.other == NULL) {
-+        cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
-+        if (!cms->d.envelopedData) {
-+            CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE);
-+            return NULL;
-+        }
-+        cms->d.envelopedData->version = 0;
-+        cms->d.envelopedData->encryptedContentInfo->contentType =
-+            OBJ_nid2obj(NID_pkcs7_data);
-+        ASN1_OBJECT_free(cms->contentType);
-+        cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
-+        return cms->d.envelopedData;
-+    }
-+    return cms_get0_enveloped(cms);
-+}
-+
-+int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
-+{
-+    EVP_PKEY *pkey;
-+    int i;
-+    if (ri->type == CMS_RECIPINFO_TRANS)
-+        pkey = ri->d.ktri->pkey;
-+    else if (ri->type == CMS_RECIPINFO_AGREE) {
-+        EVP_PKEY_CTX *pctx = ri->d.kari->pctx;
-+        if (!pctx)
-+            return 0;
-+        pkey = EVP_PKEY_CTX_get0_pkey(pctx);
-+        if (!pkey)
-+            return 0;
-+    } else
-+        return 0;
-+    if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
-+        return 1;
-+    i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
-+    if (i == -2) {
-+        CMSerr(CMS_F_CMS_ENV_ASN1_CTRL,
-+               CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
-+        return 0;
-+    }
-+    if (i <= 0) {
-+        CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
-+{
-+    CMS_EnvelopedData *env;
-+    env = cms_get0_enveloped(cms);
-+    if (!env)
-+        return NULL;
-+    return env->recipientInfos;
-+}
-+
-+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
-+{
-+    return ri->type;
-+}
-+
-+EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
-+{
-+    if (ri->type == CMS_RECIPINFO_TRANS)
-+        return ri->d.ktri->pctx;
-+    else if (ri->type == CMS_RECIPINFO_AGREE)
-+        return ri->d.kari->pctx;
-+    return NULL;
-+}
-+
-+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
-+{
-+    CMS_ContentInfo *cms;
-+    CMS_EnvelopedData *env;
-+    cms = CMS_ContentInfo_new();
-+    if (cms == NULL)
-+        goto merr;
-+    env = cms_enveloped_data_init(cms);
-+    if (env == NULL)
-+        goto merr;
-+    if (!cms_EncryptedContent_init(env->encryptedContentInfo,
-+                                   cipher, NULL, 0))
-+        goto merr;
-+    return cms;
-+ merr:
-+    CMS_ContentInfo_free(cms);
-+    CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+/* Key Transport Recipient Info (KTRI) routines */
-+
-+/* Initialise a ktri based on passed certificate and key */
-+
-+static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
-+                                       EVP_PKEY *pk, unsigned int flags)
-+{
-+    CMS_KeyTransRecipientInfo *ktri;
-+    int idtype;
-+
-+    ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
-+    if (!ri->d.ktri)
-+        return 0;
-+    ri->type = CMS_RECIPINFO_TRANS;
-+
-+    ktri = ri->d.ktri;
-+
-+    if (flags & CMS_USE_KEYID) {
-+        ktri->version = 2;
-+        idtype = CMS_RECIPINFO_KEYIDENTIFIER;
-+    } else {
-+        ktri->version = 0;
-+        idtype = CMS_RECIPINFO_ISSUER_SERIAL;
-+    }
-+
-+    /*
-+     * Not a typo: RecipientIdentifier and SignerIdentifier are the same
-+     * structure.
-+     */
-+
-+    if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype))
-+        return 0;
-+
-+    X509_up_ref(recip);
-+    EVP_PKEY_up_ref(pk);
-+
-+    ktri->pkey = pk;
-+    ktri->recip = recip;
-+
-+    if (flags & CMS_KEY_PARAM) {
-+        ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
-+        if (ktri->pctx == NULL)
-+            return 0;
-+        if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
-+            return 0;
-+    } else if (!cms_env_asn1_ctrl(ri, 0))
-+        return 0;
-+    return 1;
-+}
-+
-+/*
-+ * Add a recipient certificate using appropriate type of RecipientInfo
-+ */
-+
-+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
-+                                           X509 *recip, unsigned int flags)
-+{
-+    CMS_RecipientInfo *ri = NULL;
-+    CMS_EnvelopedData *env;
-+    EVP_PKEY *pk = NULL;
-+    env = cms_get0_enveloped(cms);
-+    if (!env)
-+        goto err;
-+
-+    /* Initialize recipient info */
-+    ri = M_ASN1_new_of(CMS_RecipientInfo);
-+    if (!ri)
-+        goto merr;
-+
-+    pk = X509_get0_pubkey(recip);
-+    if (!pk) {
-+        CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY);
-+        goto err;
-+    }
-+
-+    switch (cms_pkey_get_ri_type(pk)) {
-+
-+    case CMS_RECIPINFO_TRANS:
-+        if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags))
-+            goto err;
-+        break;
-+
-+    case CMS_RECIPINFO_AGREE:
-+        if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags))
-+            goto err;
-+        break;
-+
-+    default:
-+        CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
-+               CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
-+        goto err;
-+
-+    }
-+
-+    if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
-+        goto merr;
-+
-+    return ri;
-+
-+ merr:
-+    CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
-+ err:
-+    M_ASN1_free_of(ri, CMS_RecipientInfo);
-+    return NULL;
-+
-+}
-+
-+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
-+                                     EVP_PKEY **pk, X509 **recip,
-+                                     X509_ALGOR **palg)
-+{
-+    CMS_KeyTransRecipientInfo *ktri;
-+    if (ri->type != CMS_RECIPINFO_TRANS) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
-+               CMS_R_NOT_KEY_TRANSPORT);
-+        return 0;
-+    }
-+
-+    ktri = ri->d.ktri;
-+
-+    if (pk)
-+        *pk = ktri->pkey;
-+    if (recip)
-+        *recip = ktri->recip;
-+    if (palg)
-+        *palg = ktri->keyEncryptionAlgorithm;
-+    return 1;
-+}
-+
-+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
-+                                          ASN1_OCTET_STRING **keyid,
-+                                          X509_NAME **issuer,
-+                                          ASN1_INTEGER **sno)
-+{
-+    CMS_KeyTransRecipientInfo *ktri;
-+    if (ri->type != CMS_RECIPINFO_TRANS) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
-+               CMS_R_NOT_KEY_TRANSPORT);
-+        return 0;
-+    }
-+    ktri = ri->d.ktri;
-+
-+    return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno);
-+}
-+
-+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
-+{
-+    if (ri->type != CMS_RECIPINFO_TRANS) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
-+               CMS_R_NOT_KEY_TRANSPORT);
-+        return -2;
-+    }
-+    return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
-+}
-+
-+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
-+{
-+    if (ri->type != CMS_RECIPINFO_TRANS) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT);
-+        return 0;
-+    }
-+    ri->d.ktri->pkey = pkey;
-+    return 1;
-+}
-+
-+/* Encrypt content key in key transport recipient info */
-+
-+static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
-+                                          CMS_RecipientInfo *ri)
-+{
-+    CMS_KeyTransRecipientInfo *ktri;
-+    CMS_EncryptedContentInfo *ec;
-+    EVP_PKEY_CTX *pctx;
-+    unsigned char *ek = NULL;
-+    size_t eklen;
-+
-+    int ret = 0;
-+
-+    if (ri->type != CMS_RECIPINFO_TRANS) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT);
-+        return 0;
-+    }
-+    ktri = ri->d.ktri;
-+    ec = cms->d.envelopedData->encryptedContentInfo;
-+
-+    pctx = ktri->pctx;
-+
-+    if (pctx) {
-+        if (!cms_env_asn1_ctrl(ri, 0))
-+            goto err;
-+    } else {
-+        pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
-+        if (pctx == NULL)
-+            return 0;
-+
-+        if (EVP_PKEY_encrypt_init(pctx) <= 0)
-+            goto err;
-+    }
-+
-+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
-+                          EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
-+        goto err;
-+    }
-+
-+    if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
-+        goto err;
-+
-+    ek = OPENSSL_malloc(eklen);
-+
-+    if (ek == NULL) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
-+        goto err;
-+
-+    ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
-+    ek = NULL;
-+
-+    ret = 1;
-+
-+ err:
-+    EVP_PKEY_CTX_free(pctx);
-+    ktri->pctx = NULL;
-+    OPENSSL_free(ek);
-+    return ret;
-+
-+}
-+
-+/* Decrypt content key from KTRI */
-+
-+static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
-+                                          CMS_RecipientInfo *ri)
-+{
-+    CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
-+    EVP_PKEY *pkey = ktri->pkey;
-+    unsigned char *ek = NULL;
-+    size_t eklen;
-+    int ret = 0;
-+    CMS_EncryptedContentInfo *ec;
-+    ec = cms->d.envelopedData->encryptedContentInfo;
-+
-+    if (ktri->pkey == NULL) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY);
-+        return 0;
-+    }
-+
-+    ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
-+    if (ktri->pctx == NULL)
-+        return 0;
-+
-+    if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
-+        goto err;
-+
-+    if (!cms_env_asn1_ctrl(ri, 1))
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT,
-+                          EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
-+        goto err;
-+    }
-+
-+    if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
-+                         ktri->encryptedKey->data,
-+                         ktri->encryptedKey->length) <= 0)
-+        goto err;
-+
-+    ek = OPENSSL_malloc(eklen);
-+
-+    if (ek == NULL) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
-+                         ktri->encryptedKey->data,
-+                         ktri->encryptedKey->length) <= 0) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
-+        goto err;
-+    }
-+
-+    ret = 1;
-+
-+    OPENSSL_clear_free(ec->key, ec->keylen);
-+    ec->key = ek;
-+    ec->keylen = eklen;
-+
-+ err:
-+    EVP_PKEY_CTX_free(ktri->pctx);
-+    ktri->pctx = NULL;
-+    if (!ret)
-+        OPENSSL_free(ek);
-+
-+    return ret;
-+}
-+
-+/* Key Encrypted Key (KEK) RecipientInfo routines */
-+
-+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
-+                                   const unsigned char *id, size_t idlen)
-+{
-+    ASN1_OCTET_STRING tmp_os;
-+    CMS_KEKRecipientInfo *kekri;
-+    if (ri->type != CMS_RECIPINFO_KEK) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
-+        return -2;
-+    }
-+    kekri = ri->d.kekri;
-+    tmp_os.type = V_ASN1_OCTET_STRING;
-+    tmp_os.flags = 0;
-+    tmp_os.data = (unsigned char *)id;
-+    tmp_os.length = (int)idlen;
-+    return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
-+}
-+
-+/* For now hard code AES key wrap info */
-+
-+static size_t aes_wrap_keylen(int nid)
-+{
-+    switch (nid) {
-+    case NID_id_aes128_wrap:
-+        return 16;
-+
-+    case NID_id_aes192_wrap:
-+        return 24;
-+
-+    case NID_id_aes256_wrap:
-+        return 32;
-+
-+    default:
-+        return 0;
-+    }
-+}
-+
-+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
-+                                          unsigned char *key, size_t keylen,
-+                                          unsigned char *id, size_t idlen,
-+                                          ASN1_GENERALIZEDTIME *date,
-+                                          ASN1_OBJECT *otherTypeId,
-+                                          ASN1_TYPE *otherType)
-+{
-+    CMS_RecipientInfo *ri = NULL;
-+    CMS_EnvelopedData *env;
-+    CMS_KEKRecipientInfo *kekri;
-+    env = cms_get0_enveloped(cms);
-+    if (!env)
-+        goto err;
-+
-+    if (nid == NID_undef) {
-+        switch (keylen) {
-+        case 16:
-+            nid = NID_id_aes128_wrap;
-+            break;
-+
-+        case 24:
-+            nid = NID_id_aes192_wrap;
-+            break;
-+
-+        case 32:
-+            nid = NID_id_aes256_wrap;
-+            break;
-+
-+        default:
-+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
-+            goto err;
-+        }
-+
-+    } else {
-+
-+        size_t exp_keylen = aes_wrap_keylen(nid);
-+
-+        if (!exp_keylen) {
-+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
-+                   CMS_R_UNSUPPORTED_KEK_ALGORITHM);
-+            goto err;
-+        }
-+
-+        if (keylen != exp_keylen) {
-+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
-+            goto err;
-+        }
-+
-+    }
-+
-+    /* Initialize recipient info */
-+    ri = M_ASN1_new_of(CMS_RecipientInfo);
-+    if (!ri)
-+        goto merr;
-+
-+    ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
-+    if (!ri->d.kekri)
-+        goto merr;
-+    ri->type = CMS_RECIPINFO_KEK;
-+
-+    kekri = ri->d.kekri;
-+
-+    if (otherTypeId) {
-+        kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
-+        if (kekri->kekid->other == NULL)
-+            goto merr;
-+    }
-+
-+    if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
-+        goto merr;
-+
-+    /* After this point no calls can fail */
-+
-+    kekri->version = 4;
-+
-+    kekri->key = key;
-+    kekri->keylen = keylen;
-+
-+    ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
-+
-+    kekri->kekid->date = date;
-+
-+    if (kekri->kekid->other) {
-+        kekri->kekid->other->keyAttrId = otherTypeId;
-+        kekri->kekid->other->keyAttr = otherType;
-+    }
-+
-+    X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
-+                    OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
-+
-+    return ri;
-+
-+ merr:
-+    CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
-+ err:
-+    M_ASN1_free_of(ri, CMS_RecipientInfo);
-+    return NULL;
-+
-+}
-+
-+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
-+                                    X509_ALGOR **palg,
-+                                    ASN1_OCTET_STRING **pid,
-+                                    ASN1_GENERALIZEDTIME **pdate,
-+                                    ASN1_OBJECT **potherid,
-+                                    ASN1_TYPE **pothertype)
-+{
-+    CMS_KEKIdentifier *rkid;
-+    if (ri->type != CMS_RECIPINFO_KEK) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
-+        return 0;
-+    }
-+    rkid = ri->d.kekri->kekid;
-+    if (palg)
-+        *palg = ri->d.kekri->keyEncryptionAlgorithm;
-+    if (pid)
-+        *pid = rkid->keyIdentifier;
-+    if (pdate)
-+        *pdate = rkid->date;
-+    if (potherid) {
-+        if (rkid->other)
-+            *potherid = rkid->other->keyAttrId;
-+        else
-+            *potherid = NULL;
-+    }
-+    if (pothertype) {
-+        if (rkid->other)
-+            *pothertype = rkid->other->keyAttr;
-+        else
-+            *pothertype = NULL;
-+    }
-+    return 1;
-+}
-+
-+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
-+                               unsigned char *key, size_t keylen)
-+{
-+    CMS_KEKRecipientInfo *kekri;
-+    if (ri->type != CMS_RECIPINFO_KEK) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
-+        return 0;
-+    }
-+
-+    kekri = ri->d.kekri;
-+    kekri->key = key;
-+    kekri->keylen = keylen;
-+    return 1;
-+}
-+
-+/* Encrypt content key in KEK recipient info */
-+
-+static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
-+                                           CMS_RecipientInfo *ri)
-+{
-+    CMS_EncryptedContentInfo *ec;
-+    CMS_KEKRecipientInfo *kekri;
-+    AES_KEY actx;
-+    unsigned char *wkey = NULL;
-+    int wkeylen;
-+    int r = 0;
-+
-+    ec = cms->d.envelopedData->encryptedContentInfo;
-+
-+    kekri = ri->d.kekri;
-+
-+    if (!kekri->key) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
-+        return 0;
-+    }
-+
-+    if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
-+               CMS_R_ERROR_SETTING_KEY);
-+        goto err;
-+    }
-+
-+    wkey = OPENSSL_malloc(ec->keylen + 8);
-+
-+    if (wkey == NULL) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
-+
-+    if (wkeylen <= 0) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
-+        goto err;
-+    }
-+
-+    ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
-+
-+    r = 1;
-+
-+ err:
-+
-+    if (!r)
-+        OPENSSL_free(wkey);
-+    OPENSSL_cleanse(&actx, sizeof(actx));
-+
-+    return r;
-+
-+}
-+
-+/* Decrypt content key in KEK recipient info */
-+
-+static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
-+                                           CMS_RecipientInfo *ri)
-+{
-+    CMS_EncryptedContentInfo *ec;
-+    CMS_KEKRecipientInfo *kekri;
-+    AES_KEY actx;
-+    unsigned char *ukey = NULL;
-+    int ukeylen;
-+    int r = 0, wrap_nid;
-+
-+    ec = cms->d.envelopedData->encryptedContentInfo;
-+
-+    kekri = ri->d.kekri;
-+
-+    if (!kekri->key) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
-+        return 0;
-+    }
-+
-+    wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
-+    if (aes_wrap_keylen(wrap_nid) != kekri->keylen) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
-+               CMS_R_INVALID_KEY_LENGTH);
-+        return 0;
-+    }
-+
-+    /* If encrypted key length is invalid don't bother */
-+
-+    if (kekri->encryptedKey->length < 16) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
-+               CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
-+        goto err;
-+    }
-+
-+    if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
-+               CMS_R_ERROR_SETTING_KEY);
-+        goto err;
-+    }
-+
-+    ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
-+
-+    if (ukey == NULL) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    ukeylen = AES_unwrap_key(&actx, NULL, ukey,
-+                             kekri->encryptedKey->data,
-+                             kekri->encryptedKey->length);
-+
-+    if (ukeylen <= 0) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR);
-+        goto err;
-+    }
-+
-+    ec->key = ukey;
-+    ec->keylen = ukeylen;
-+
-+    r = 1;
-+
-+ err:
-+
-+    if (!r)
-+        OPENSSL_free(ukey);
-+    OPENSSL_cleanse(&actx, sizeof(actx));
-+
-+    return r;
-+
-+}
-+
-+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
-+{
-+    switch (ri->type) {
-+    case CMS_RECIPINFO_TRANS:
-+        return cms_RecipientInfo_ktri_decrypt(cms, ri);
-+
-+    case CMS_RECIPINFO_KEK:
-+        return cms_RecipientInfo_kekri_decrypt(cms, ri);
-+
-+    case CMS_RECIPINFO_PASS:
-+        return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
-+
-+    default:
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
-+               CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
-+        return 0;
-+    }
-+}
-+
-+int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
-+{
-+    switch (ri->type) {
-+    case CMS_RECIPINFO_TRANS:
-+        return cms_RecipientInfo_ktri_encrypt(cms, ri);
-+
-+    case CMS_RECIPINFO_AGREE:
-+        return cms_RecipientInfo_kari_encrypt(cms, ri);
-+
-+    case CMS_RECIPINFO_KEK:
-+        return cms_RecipientInfo_kekri_encrypt(cms, ri);
-+
-+    case CMS_RECIPINFO_PASS:
-+        return cms_RecipientInfo_pwri_crypt(cms, ri, 1);
-+
-+    default:
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT,
-+               CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
-+        return 0;
-+    }
-+}
-+
-+/* Check structures and fixup version numbers (if necessary) */
-+
-+static void cms_env_set_originfo_version(CMS_EnvelopedData *env)
-+{
-+    CMS_OriginatorInfo *org = env->originatorInfo;
-+    int i;
-+    if (org == NULL)
-+        return;
-+    for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) {
-+        CMS_CertificateChoices *cch;
-+        cch = sk_CMS_CertificateChoices_value(org->certificates, i);
-+        if (cch->type == CMS_CERTCHOICE_OTHER) {
-+            env->version = 4;
-+            return;
-+        } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
-+            if (env->version < 3)
-+                env->version = 3;
-+        }
-+    }
-+
-+    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) {
-+        CMS_RevocationInfoChoice *rch;
-+        rch = sk_CMS_RevocationInfoChoice_value(org->crls, i);
-+        if (rch->type == CMS_REVCHOICE_OTHER) {
-+            env->version = 4;
-+            return;
-+        }
-+    }
-+}
-+
-+static void cms_env_set_version(CMS_EnvelopedData *env)
-+{
-+    int i;
-+    CMS_RecipientInfo *ri;
-+
-+    /*
-+     * Can't set version higher than 4 so if 4 or more already nothing to do.
-+     */
-+    if (env->version >= 4)
-+        return;
-+
-+    cms_env_set_originfo_version(env);
-+
-+    if (env->version >= 3)
-+        return;
-+
-+    for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) {
-+        ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i);
-+        if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) {
-+            env->version = 3;
-+            return;
-+        } else if (ri->type != CMS_RECIPINFO_TRANS
-+                   || ri->d.ktri->version != 0) {
-+            env->version = 2;
-+        }
-+    }
-+    if (env->originatorInfo || env->unprotectedAttrs)
-+        env->version = 2;
-+    if (env->version == 2)
-+        return;
-+    env->version = 0;
-+}
-+
-+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
-+{
-+    CMS_EncryptedContentInfo *ec;
-+    STACK_OF(CMS_RecipientInfo) *rinfos;
-+    CMS_RecipientInfo *ri;
-+    int i, ok = 0;
-+    BIO *ret;
-+
-+    /* Get BIO first to set up key */
-+
-+    ec = cms->d.envelopedData->encryptedContentInfo;
-+    ret = cms_EncryptedContent_init_bio(ec);
-+
-+    /* If error or no cipher end of processing */
-+
-+    if (!ret || !ec->cipher)
-+        return ret;
-+
-+    /* Now encrypt content key according to each RecipientInfo type */
-+
-+    rinfos = cms->d.envelopedData->recipientInfos;
-+
-+    for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
-+        ri = sk_CMS_RecipientInfo_value(rinfos, i);
-+        if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) {
-+            CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
-+                   CMS_R_ERROR_SETTING_RECIPIENTINFO);
-+            goto err;
-+        }
-+    }
-+    cms_env_set_version(cms->d.envelopedData);
-+
-+    ok = 1;
-+
-+ err:
-+    ec->cipher = NULL;
-+    OPENSSL_clear_free(ec->key, ec->keylen);
-+    ec->key = NULL;
-+    ec->keylen = 0;
-+    if (ok)
-+        return ret;
-+    BIO_free(ret);
-+    return NULL;
-+
-+}
-+
-+/*
-+ * Get RecipientInfo type (if any) supported by a key (public or private). To
-+ * retain compatibility with previous behaviour if the ctrl value isn't
-+ * supported we assume key transport.
-+ */
-+int cms_pkey_get_ri_type(EVP_PKEY *pk)
-+{
-+    if (pk->ameth && pk->ameth->pkey_ctrl) {
-+        int i, r;
-+        i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r);
-+        if (i > 0)
-+            return r;
-+    }
-+    return CMS_RECIPINFO_TRANS;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_err.c
-new file mode 100644
-index 0000000..c6df1b5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_err.c
-@@ -0,0 +1,258 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason)
-+
-+static ERR_STRING_DATA CMS_str_functs[] = {
-+    {ERR_FUNC(CMS_F_CHECK_CONTENT), "check_content"},
-+    {ERR_FUNC(CMS_F_CMS_ADD0_CERT), "CMS_add0_cert"},
-+    {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY), "CMS_add0_recipient_key"},
-+    {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD),
-+     "CMS_add0_recipient_password"},
-+    {ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST), "CMS_add1_ReceiptRequest"},
-+    {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_add1_recipient_cert"},
-+    {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"},
-+    {ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "cms_add1_signingTime"},
-+    {ERR_FUNC(CMS_F_CMS_COMPRESS), "CMS_compress"},
-+    {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE), "cms_CompressedData_create"},
-+    {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO),
-+     "cms_CompressedData_init_bio"},
-+    {ERR_FUNC(CMS_F_CMS_COPY_CONTENT), "cms_copy_content"},
-+    {ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST), "cms_copy_messageDigest"},
-+    {ERR_FUNC(CMS_F_CMS_DATA), "CMS_data"},
-+    {ERR_FUNC(CMS_F_CMS_DATAFINAL), "CMS_dataFinal"},
-+    {ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"},
-+    {ERR_FUNC(CMS_F_CMS_DECRYPT), "CMS_decrypt"},
-+    {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY), "CMS_decrypt_set1_key"},
-+    {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PASSWORD), "CMS_decrypt_set1_password"},
-+    {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY), "CMS_decrypt_set1_pkey"},
-+    {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX),
-+     "cms_DigestAlgorithm_find_ctx"},
-+    {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO),
-+     "cms_DigestAlgorithm_init_bio"},
-+    {ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "cms_DigestedData_do_final"},
-+    {ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"},
-+    {ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT), "cms_encode_Receipt"},
-+    {ERR_FUNC(CMS_F_CMS_ENCRYPT), "CMS_encrypt"},
-+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO),
-+     "cms_EncryptedContent_init_bio"},
-+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT), "CMS_EncryptedData_decrypt"},
-+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT), "CMS_EncryptedData_encrypt"},
-+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY),
-+     "CMS_EncryptedData_set1_key"},
-+    {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"},
-+    {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO),
-+     "cms_EnvelopedData_init_bio"},
-+    {ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "cms_enveloped_data_init"},
-+    {ERR_FUNC(CMS_F_CMS_ENV_ASN1_CTRL), "cms_env_asn1_ctrl"},
-+    {ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"},
-+    {ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES),
-+     "cms_get0_certificate_choices"},
-+    {ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"},
-+    {ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE), "cms_get0_econtent_type"},
-+    {ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "cms_get0_enveloped"},
-+    {ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),
-+     "cms_get0_revocation_choices"},
-+    {ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "cms_get0_signed"},
-+    {ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1), "cms_msgSigDigest_add1"},
-+    {ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0),
-+     "CMS_ReceiptRequest_create0"},
-+    {ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY), "cms_Receipt_verify"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT), "CMS_RecipientInfo_decrypt"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_ENCRYPT), "CMS_RecipientInfo_encrypt"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT),
-+     "cms_RecipientInfo_kari_encrypt"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG),
-+     "CMS_RecipientInfo_kari_get0_alg"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID),
-+     "CMS_RecipientInfo_kari_get0_orig_id"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS),
-+     "CMS_RecipientInfo_kari_get0_reks"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP),
-+     "CMS_RecipientInfo_kari_orig_id_cmp"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT),
-+     "cms_RecipientInfo_kekri_decrypt"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT),
-+     "cms_RecipientInfo_kekri_encrypt"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID),
-+     "CMS_RecipientInfo_kekri_get0_id"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP),
-+     "CMS_RecipientInfo_kekri_id_cmp"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP),
-+     "CMS_RecipientInfo_ktri_cert_cmp"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT),
-+     "cms_RecipientInfo_ktri_decrypt"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT),
-+     "cms_RecipientInfo_ktri_encrypt"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),
-+     "CMS_RecipientInfo_ktri_get0_algs"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),
-+     "CMS_RecipientInfo_ktri_get0_signer_id"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT),
-+     "cms_RecipientInfo_pwri_crypt"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY),
-+     "CMS_RecipientInfo_set0_key"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD),
-+     "CMS_RecipientInfo_set0_password"},
-+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY),
-+     "CMS_RecipientInfo_set0_pkey"},
-+    {ERR_FUNC(CMS_F_CMS_SD_ASN1_CTRL), "cms_sd_asn1_ctrl"},
-+    {ERR_FUNC(CMS_F_CMS_SET1_IAS), "cms_set1_ias"},
-+    {ERR_FUNC(CMS_F_CMS_SET1_KEYID), "cms_set1_keyid"},
-+    {ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "cms_set1_SignerIdentifier"},
-+    {ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"},
-+    {ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"},
-+    {ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT), "cms_signed_data_init"},
-+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN),
-+     "cms_SignerInfo_content_sign"},
-+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN), "CMS_SignerInfo_sign"},
-+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY), "CMS_SignerInfo_verify"},
-+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT),
-+     "cms_signerinfo_verify_cert"},
-+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT),
-+     "CMS_SignerInfo_verify_content"},
-+    {ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"},
-+    {ERR_FUNC(CMS_F_CMS_STREAM), "CMS_stream"},
-+    {ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"},
-+    {ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA CMS_str_reasons[] = {
-+    {ERR_REASON(CMS_R_ADD_SIGNER_ERROR), "add signer error"},
-+    {ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT),
-+     "certificate already present"},
-+    {ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID), "certificate has no keyid"},
-+    {ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
-+    {ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),
-+     "cipher initialisation error"},
-+    {ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),
-+     "cipher parameter initialisation error"},
-+    {ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR), "cms datafinal error"},
-+    {ERR_REASON(CMS_R_CMS_LIB), "cms lib"},
-+    {ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH),
-+     "contentidentifier mismatch"},
-+    {ERR_REASON(CMS_R_CONTENT_NOT_FOUND), "content not found"},
-+    {ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH), "content type mismatch"},
-+    {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),
-+     "content type not compressed data"},
-+    {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),
-+     "content type not enveloped data"},
-+    {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),
-+     "content type not signed data"},
-+    {ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR), "content verify error"},
-+    {ERR_REASON(CMS_R_CTRL_ERROR), "ctrl error"},
-+    {ERR_REASON(CMS_R_CTRL_FAILURE), "ctrl failure"},
-+    {ERR_REASON(CMS_R_DECRYPT_ERROR), "decrypt error"},
-+    {ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY), "error getting public key"},
-+    {ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),
-+     "error reading messagedigest attribute"},
-+    {ERR_REASON(CMS_R_ERROR_SETTING_KEY), "error setting key"},
-+    {ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),
-+     "error setting recipientinfo"},
-+    {ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),
-+     "invalid encrypted key length"},
-+    {ERR_REASON(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),
-+     "invalid key encryption parameter"},
-+    {ERR_REASON(CMS_R_INVALID_KEY_LENGTH), "invalid key length"},
-+    {ERR_REASON(CMS_R_MD_BIO_INIT_ERROR), "md bio init error"},
-+    {ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),
-+     "messagedigest attribute wrong length"},
-+    {ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),
-+     "messagedigest wrong length"},
-+    {ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR), "msgsigdigest error"},
-+    {ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),
-+     "msgsigdigest verification failure"},
-+    {ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH),
-+     "msgsigdigest wrong length"},
-+    {ERR_REASON(CMS_R_NEED_ONE_SIGNER), "need one signer"},
-+    {ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT), "not a signed receipt"},
-+    {ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA), "not encrypted data"},
-+    {ERR_REASON(CMS_R_NOT_KEK), "not kek"},
-+    {ERR_REASON(CMS_R_NOT_KEY_AGREEMENT), "not key agreement"},
-+    {ERR_REASON(CMS_R_NOT_KEY_TRANSPORT), "not key transport"},
-+    {ERR_REASON(CMS_R_NOT_PWRI), "not pwri"},
-+    {ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),
-+     "not supported for this key type"},
-+    {ERR_REASON(CMS_R_NO_CIPHER), "no cipher"},
-+    {ERR_REASON(CMS_R_NO_CONTENT), "no content"},
-+    {ERR_REASON(CMS_R_NO_CONTENT_TYPE), "no content type"},
-+    {ERR_REASON(CMS_R_NO_DEFAULT_DIGEST), "no default digest"},
-+    {ERR_REASON(CMS_R_NO_DIGEST_SET), "no digest set"},
-+    {ERR_REASON(CMS_R_NO_KEY), "no key"},
-+    {ERR_REASON(CMS_R_NO_KEY_OR_CERT), "no key or cert"},
-+    {ERR_REASON(CMS_R_NO_MATCHING_DIGEST), "no matching digest"},
-+    {ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT), "no matching recipient"},
-+    {ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE), "no matching signature"},
-+    {ERR_REASON(CMS_R_NO_MSGSIGDIGEST), "no msgsigdigest"},
-+    {ERR_REASON(CMS_R_NO_PASSWORD), "no password"},
-+    {ERR_REASON(CMS_R_NO_PRIVATE_KEY), "no private key"},
-+    {ERR_REASON(CMS_R_NO_PUBLIC_KEY), "no public key"},
-+    {ERR_REASON(CMS_R_NO_RECEIPT_REQUEST), "no receipt request"},
-+    {ERR_REASON(CMS_R_NO_SIGNERS), "no signers"},
-+    {ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
-+     "private key does not match certificate"},
-+    {ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR), "receipt decode error"},
-+    {ERR_REASON(CMS_R_RECIPIENT_ERROR), "recipient error"},
-+    {ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),
-+     "signer certificate not found"},
-+    {ERR_REASON(CMS_R_SIGNFINAL_ERROR), "signfinal error"},
-+    {ERR_REASON(CMS_R_SMIME_TEXT_ERROR), "smime text error"},
-+    {ERR_REASON(CMS_R_STORE_INIT_ERROR), "store init error"},
-+    {ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA), "type not compressed data"},
-+    {ERR_REASON(CMS_R_TYPE_NOT_DATA), "type not data"},
-+    {ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA), "type not digested data"},
-+    {ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA), "type not encrypted data"},
-+    {ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA), "type not enveloped data"},
-+    {ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),
-+     "unable to finalize context"},
-+    {ERR_REASON(CMS_R_UNKNOWN_CIPHER), "unknown cipher"},
-+    {ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM), "unknown digest algorihm"},
-+    {ERR_REASON(CMS_R_UNKNOWN_ID), "unknown id"},
-+    {ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),
-+     "unsupported compression algorithm"},
-+    {ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"},
-+    {ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),
-+     "unsupported kek algorithm"},
-+    {ERR_REASON(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM),
-+     "unsupported key encryption algorithm"},
-+    {ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),
-+     "unsupported recipient type"},
-+    {ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),
-+     "unsupported recpientinfo type"},
-+    {ERR_REASON(CMS_R_UNSUPPORTED_TYPE), "unsupported type"},
-+    {ERR_REASON(CMS_R_UNWRAP_ERROR), "unwrap error"},
-+    {ERR_REASON(CMS_R_UNWRAP_FAILURE), "unwrap failure"},
-+    {ERR_REASON(CMS_R_VERIFICATION_FAILURE), "verification failure"},
-+    {ERR_REASON(CMS_R_WRAP_ERROR), "wrap error"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_CMS_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, CMS_str_functs);
-+        ERR_load_strings(0, CMS_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_ess.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_ess.c
-new file mode 100644
-index 0000000..4780231
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_ess.c
-@@ -0,0 +1,337 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+
-+IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
-+
-+/* ESS services: for now just Signed Receipt related */
-+
-+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
-+{
-+    ASN1_STRING *str;
-+    CMS_ReceiptRequest *rr = NULL;
-+    if (prr)
-+        *prr = NULL;
-+    str = CMS_signed_get0_data_by_OBJ(si,
-+                                      OBJ_nid2obj
-+                                      (NID_id_smime_aa_receiptRequest), -3,
-+                                      V_ASN1_SEQUENCE);
-+    if (!str)
-+        return 0;
-+
-+    rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
-+    if (!rr)
-+        return -1;
-+    if (prr)
-+        *prr = rr;
-+    else
-+        CMS_ReceiptRequest_free(rr);
-+    return 1;
-+}
-+
-+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
-+                                               int allorfirst,
-+                                               STACK_OF(GENERAL_NAMES)
-+                                               *receiptList, STACK_OF(GENERAL_NAMES)
-+                                               *receiptsTo)
-+{
-+    CMS_ReceiptRequest *rr = NULL;
-+
-+    rr = CMS_ReceiptRequest_new();
-+    if (rr == NULL)
-+        goto merr;
-+    if (id)
-+        ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
-+    else {
-+        if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
-+            goto merr;
-+        if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0)
-+            goto err;
-+    }
-+
-+    sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
-+    rr->receiptsTo = receiptsTo;
-+
-+    if (receiptList) {
-+        rr->receiptsFrom->type = 1;
-+        rr->receiptsFrom->d.receiptList = receiptList;
-+    } else {
-+        rr->receiptsFrom->type = 0;
-+        rr->receiptsFrom->d.allOrFirstTier = allorfirst;
-+    }
-+
-+    return rr;
-+
-+ merr:
-+    CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);
-+
-+ err:
-+    CMS_ReceiptRequest_free(rr);
-+    return NULL;
-+
-+}
-+
-+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
-+{
-+    unsigned char *rrder = NULL;
-+    int rrderlen, r = 0;
-+
-+    rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
-+    if (rrderlen < 0)
-+        goto merr;
-+
-+    if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
-+                                     V_ASN1_SEQUENCE, rrder, rrderlen))
-+        goto merr;
-+
-+    r = 1;
-+
-+ merr:
-+    if (!r)
-+        CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE);
-+
-+    OPENSSL_free(rrder);
-+
-+    return r;
-+
-+}
-+
-+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
-+                                    ASN1_STRING **pcid,
-+                                    int *pallorfirst,
-+                                    STACK_OF(GENERAL_NAMES) **plist,
-+                                    STACK_OF(GENERAL_NAMES) **prto)
-+{
-+    if (pcid)
-+        *pcid = rr->signedContentIdentifier;
-+    if (rr->receiptsFrom->type == 0) {
-+        if (pallorfirst)
-+            *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
-+        if (plist)
-+            *plist = NULL;
-+    } else {
-+        if (pallorfirst)
-+            *pallorfirst = -1;
-+        if (plist)
-+            *plist = rr->receiptsFrom->d.receiptList;
-+    }
-+    if (prto)
-+        *prto = rr->receiptsTo;
-+}
-+
-+/* Digest a SignerInfo structure for msgSigDigest attribute processing */
-+
-+static int cms_msgSigDigest(CMS_SignerInfo *si,
-+                            unsigned char *dig, unsigned int *diglen)
-+{
-+    const EVP_MD *md;
-+    md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
-+    if (md == NULL)
-+        return 0;
-+    if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
-+                          si->signedAttrs, dig, diglen))
-+        return 0;
-+    return 1;
-+}
-+
-+/* Add a msgSigDigest attribute to a SignerInfo */
-+
-+int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
-+{
-+    unsigned char dig[EVP_MAX_MD_SIZE];
-+    unsigned int diglen;
-+    if (!cms_msgSigDigest(src, dig, &diglen)) {
-+        CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
-+        return 0;
-+    }
-+    if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
-+                                     V_ASN1_OCTET_STRING, dig, diglen)) {
-+        CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+/* Verify signed receipt after it has already passed normal CMS verify */
-+
-+int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
-+{
-+    int r = 0, i;
-+    CMS_ReceiptRequest *rr = NULL;
-+    CMS_Receipt *rct = NULL;
-+    STACK_OF(CMS_SignerInfo) *sis, *osis;
-+    CMS_SignerInfo *si, *osi = NULL;
-+    ASN1_OCTET_STRING *msig, **pcont;
-+    ASN1_OBJECT *octype;
-+    unsigned char dig[EVP_MAX_MD_SIZE];
-+    unsigned int diglen;
-+
-+    /* Get SignerInfos, also checks SignedData content type */
-+    osis = CMS_get0_SignerInfos(req_cms);
-+    sis = CMS_get0_SignerInfos(cms);
-+    if (!osis || !sis)
-+        goto err;
-+
-+    if (sk_CMS_SignerInfo_num(sis) != 1) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
-+        goto err;
-+    }
-+
-+    /* Check receipt content type */
-+    if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
-+        goto err;
-+    }
-+
-+    /* Extract and decode receipt content */
-+    pcont = CMS_get0_content(cms);
-+    if (!pcont || !*pcont) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
-+        goto err;
-+    }
-+
-+    rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));
-+
-+    if (!rct) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    /* Locate original request */
-+
-+    for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) {
-+        osi = sk_CMS_SignerInfo_value(osis, i);
-+        if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue))
-+            break;
-+    }
-+
-+    if (i == sk_CMS_SignerInfo_num(osis)) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
-+        goto err;
-+    }
-+
-+    si = sk_CMS_SignerInfo_value(sis, 0);
-+
-+    /* Get msgSigDigest value and compare */
-+
-+    msig = CMS_signed_get0_data_by_OBJ(si,
-+                                       OBJ_nid2obj
-+                                       (NID_id_smime_aa_msgSigDigest), -3,
-+                                       V_ASN1_OCTET_STRING);
-+
-+    if (!msig) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
-+        goto err;
-+    }
-+
-+    if (!cms_msgSigDigest(osi, dig, &diglen)) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
-+        goto err;
-+    }
-+
-+    if (diglen != (unsigned int)msig->length) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
-+        goto err;
-+    }
-+
-+    if (memcmp(dig, msig->data, diglen)) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
-+               CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
-+        goto err;
-+    }
-+
-+    /* Compare content types */
-+
-+    octype = CMS_signed_get0_data_by_OBJ(osi,
-+                                         OBJ_nid2obj(NID_pkcs9_contentType),
-+                                         -3, V_ASN1_OBJECT);
-+    if (!octype) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
-+        goto err;
-+    }
-+
-+    /* Compare details in receipt request */
-+
-+    if (OBJ_cmp(octype, rct->contentType)) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
-+        goto err;
-+    }
-+
-+    /* Get original receipt request details */
-+
-+    if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
-+        goto err;
-+    }
-+
-+    if (ASN1_STRING_cmp(rr->signedContentIdentifier,
-+                        rct->signedContentIdentifier)) {
-+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENTIDENTIFIER_MISMATCH);
-+        goto err;
-+    }
-+
-+    r = 1;
-+
-+ err:
-+    CMS_ReceiptRequest_free(rr);
-+    M_ASN1_free_of(rct, CMS_Receipt);
-+    return r;
-+
-+}
-+
-+/*
-+ * Encode a Receipt into an OCTET STRING read for including into content of a
-+ * SignedData ContentInfo.
-+ */
-+
-+ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
-+{
-+    CMS_Receipt rct;
-+    CMS_ReceiptRequest *rr = NULL;
-+    ASN1_OBJECT *ctype;
-+    ASN1_OCTET_STRING *os = NULL;
-+
-+    /* Get original receipt request */
-+
-+    /* Get original receipt request details */
-+
-+    if (CMS_get1_ReceiptRequest(si, &rr) <= 0) {
-+        CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
-+        goto err;
-+    }
-+
-+    /* Get original content type */
-+
-+    ctype = CMS_signed_get0_data_by_OBJ(si,
-+                                        OBJ_nid2obj(NID_pkcs9_contentType),
-+                                        -3, V_ASN1_OBJECT);
-+    if (!ctype) {
-+        CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
-+        goto err;
-+    }
-+
-+    rct.version = 1;
-+    rct.contentType = ctype;
-+    rct.signedContentIdentifier = rr->signedContentIdentifier;
-+    rct.originatorSignatureValue = si->signature;
-+
-+    os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);
-+
-+ err:
-+    CMS_ReceiptRequest_free(rr);
-+    return os;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_io.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_io.c
-new file mode 100644
-index 0000000..d18f980
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_io.c
-@@ -0,0 +1,88 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+
-+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
-+{
-+    ASN1_OCTET_STRING **pos;
-+    pos = CMS_get0_content(cms);
-+    if (pos == NULL)
-+        return 0;
-+    if (*pos == NULL)
-+        *pos = ASN1_OCTET_STRING_new();
-+    if (*pos != NULL) {
-+        (*pos)->flags |= ASN1_STRING_FLAG_NDEF;
-+        (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
-+        *boundary = &(*pos)->data;
-+        return 1;
-+    }
-+    CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE);
-+    return 0;
-+}
-+
-+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
-+{
-+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
-+}
-+
-+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
-+{
-+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
-+}
-+
-+IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
-+
-+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms)
-+{
-+    return BIO_new_NDEF(out, (ASN1_VALUE *)cms,
-+                        ASN1_ITEM_rptr(CMS_ContentInfo));
-+}
-+
-+/* CMS wrappers round generalised stream and MIME routines */
-+
-+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
-+{
-+    return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags,
-+                               ASN1_ITEM_rptr(CMS_ContentInfo));
-+}
-+
-+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
-+                             int flags)
-+{
-+    return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)cms, in, flags,
-+                                     "CMS", ASN1_ITEM_rptr(CMS_ContentInfo));
-+}
-+
-+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
-+{
-+    STACK_OF(X509_ALGOR) *mdalgs;
-+    int ctype_nid = OBJ_obj2nid(cms->contentType);
-+    int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
-+    if (ctype_nid == NID_pkcs7_signed)
-+        mdalgs = cms->d.signedData->digestAlgorithms;
-+    else
-+        mdalgs = NULL;
-+
-+    return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
-+                            ctype_nid, econt_nid, mdalgs,
-+                            ASN1_ITEM_rptr(CMS_ContentInfo));
-+}
-+
-+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
-+{
-+    return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
-+                                              ASN1_ITEM_rptr
-+                                              (CMS_ContentInfo));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_kari.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_kari.c
-new file mode 100644
-index 0000000..3bc46fe
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_kari.c
-@@ -0,0 +1,411 @@
-+/*
-+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+#include "internal/asn1_int.h"
-+
-+/* Key Agreement Recipient Info (KARI) routines */
-+
-+int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
-+                                    X509_ALGOR **palg,
-+                                    ASN1_OCTET_STRING **pukm)
-+{
-+    if (ri->type != CMS_RECIPINFO_AGREE) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG,
-+               CMS_R_NOT_KEY_AGREEMENT);
-+        return 0;
-+    }
-+    if (palg)
-+        *palg = ri->d.kari->keyEncryptionAlgorithm;
-+    if (pukm)
-+        *pukm = ri->d.kari->ukm;
-+    return 1;
-+}
-+
-+/* Retrieve recipient encrypted keys from a kari */
-+
-+STACK_OF(CMS_RecipientEncryptedKey)
-+*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri)
-+{
-+    if (ri->type != CMS_RECIPINFO_AGREE) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS,
-+               CMS_R_NOT_KEY_AGREEMENT);
-+        return NULL;
-+    }
-+    return ri->d.kari->recipientEncryptedKeys;
-+}
-+
-+int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
-+                                        X509_ALGOR **pubalg,
-+                                        ASN1_BIT_STRING **pubkey,
-+                                        ASN1_OCTET_STRING **keyid,
-+                                        X509_NAME **issuer,
-+                                        ASN1_INTEGER **sno)
-+{
-+    CMS_OriginatorIdentifierOrKey *oik;
-+    if (ri->type != CMS_RECIPINFO_AGREE) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID,
-+               CMS_R_NOT_KEY_AGREEMENT);
-+        return 0;
-+    }
-+    oik = ri->d.kari->originator;
-+    if (issuer)
-+        *issuer = NULL;
-+    if (sno)
-+        *sno = NULL;
-+    if (keyid)
-+        *keyid = NULL;
-+    if (pubalg)
-+        *pubalg = NULL;
-+    if (pubkey)
-+        *pubkey = NULL;
-+    if (oik->type == CMS_OIK_ISSUER_SERIAL) {
-+        if (issuer)
-+            *issuer = oik->d.issuerAndSerialNumber->issuer;
-+        if (sno)
-+            *sno = oik->d.issuerAndSerialNumber->serialNumber;
-+    } else if (oik->type == CMS_OIK_KEYIDENTIFIER) {
-+        if (keyid)
-+            *keyid = oik->d.subjectKeyIdentifier;
-+    } else if (oik->type == CMS_OIK_PUBKEY) {
-+        if (pubalg)
-+            *pubalg = oik->d.originatorKey->algorithm;
-+        if (pubkey)
-+            *pubkey = oik->d.originatorKey->publicKey;
-+    } else
-+        return 0;
-+    return 1;
-+}
-+
-+int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
-+{
-+    CMS_OriginatorIdentifierOrKey *oik;
-+    if (ri->type != CMS_RECIPINFO_AGREE) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP,
-+               CMS_R_NOT_KEY_AGREEMENT);
-+        return -2;
-+    }
-+    oik = ri->d.kari->originator;
-+    if (oik->type == CMS_OIK_ISSUER_SERIAL)
-+        return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert);
-+    else if (oik->type == CMS_OIK_KEYIDENTIFIER)
-+        return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert);
-+    return -1;
-+}
-+
-+int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
-+                                      ASN1_OCTET_STRING **keyid,
-+                                      ASN1_GENERALIZEDTIME **tm,
-+                                      CMS_OtherKeyAttribute **other,
-+                                      X509_NAME **issuer, ASN1_INTEGER **sno)
-+{
-+    CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
-+    if (rid->type == CMS_REK_ISSUER_SERIAL) {
-+        if (issuer)
-+            *issuer = rid->d.issuerAndSerialNumber->issuer;
-+        if (sno)
-+            *sno = rid->d.issuerAndSerialNumber->serialNumber;
-+        if (keyid)
-+            *keyid = NULL;
-+        if (tm)
-+            *tm = NULL;
-+        if (other)
-+            *other = NULL;
-+    } else if (rid->type == CMS_REK_KEYIDENTIFIER) {
-+        if (keyid)
-+            *keyid = rid->d.rKeyId->subjectKeyIdentifier;
-+        if (tm)
-+            *tm = rid->d.rKeyId->date;
-+        if (other)
-+            *other = rid->d.rKeyId->other;
-+        if (issuer)
-+            *issuer = NULL;
-+        if (sno)
-+            *sno = NULL;
-+    } else
-+        return 0;
-+    return 1;
-+}
-+
-+int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
-+                                       X509 *cert)
-+{
-+    CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
-+    if (rid->type == CMS_REK_ISSUER_SERIAL)
-+        return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
-+    else if (rid->type == CMS_REK_KEYIDENTIFIER)
-+        return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert);
-+    else
-+        return -1;
-+}
-+
-+int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
-+{
-+    EVP_PKEY_CTX *pctx;
-+    CMS_KeyAgreeRecipientInfo *kari = ri->d.kari;
-+
-+    EVP_PKEY_CTX_free(kari->pctx);
-+    kari->pctx = NULL;
-+    if (!pk)
-+        return 1;
-+    pctx = EVP_PKEY_CTX_new(pk, NULL);
-+    if (!pctx || !EVP_PKEY_derive_init(pctx))
-+        goto err;
-+    kari->pctx = pctx;
-+    return 1;
-+ err:
-+    EVP_PKEY_CTX_free(pctx);
-+    return 0;
-+}
-+
-+EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri)
-+{
-+    if (ri->type == CMS_RECIPINFO_AGREE)
-+        return ri->d.kari->ctx;
-+    return NULL;
-+}
-+
-+/*
-+ * Derive KEK and decrypt/encrypt with it to produce either the original CEK
-+ * or the encrypted CEK.
-+ */
-+
-+static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
-+                          const unsigned char *in, size_t inlen,
-+                          CMS_KeyAgreeRecipientInfo *kari, int enc)
-+{
-+    /* Key encryption key */
-+    unsigned char kek[EVP_MAX_KEY_LENGTH];
-+    size_t keklen;
-+    int rv = 0;
-+    unsigned char *out = NULL;
-+    int outlen;
-+    keklen = EVP_CIPHER_CTX_key_length(kari->ctx);
-+    if (keklen > EVP_MAX_KEY_LENGTH)
-+        return 0;
-+    /* Derive KEK */
-+    if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0)
-+        goto err;
-+    /* Set KEK in context */
-+    if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc))
-+        goto err;
-+    /* obtain output length of ciphered key */
-+    if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, inlen))
-+        goto err;
-+    out = OPENSSL_malloc(outlen);
-+    if (out == NULL)
-+        goto err;
-+    if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen))
-+        goto err;
-+    *pout = out;
-+    *poutlen = (size_t)outlen;
-+    rv = 1;
-+
-+ err:
-+    OPENSSL_cleanse(kek, keklen);
-+    if (!rv)
-+        OPENSSL_free(out);
-+    EVP_CIPHER_CTX_reset(kari->ctx);
-+    /* FIXME: WHY IS kari->pctx freed here?  /RL */
-+    EVP_PKEY_CTX_free(kari->pctx);
-+    kari->pctx = NULL;
-+    return rv;
-+}
-+
-+int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
-+                                   CMS_RecipientInfo *ri,
-+                                   CMS_RecipientEncryptedKey *rek)
-+{
-+    int rv = 0;
-+    unsigned char *enckey = NULL, *cek = NULL;
-+    size_t enckeylen;
-+    size_t ceklen;
-+    CMS_EncryptedContentInfo *ec;
-+    enckeylen = rek->encryptedKey->length;
-+    enckey = rek->encryptedKey->data;
-+    /* Setup all parameters to derive KEK */
-+    if (!cms_env_asn1_ctrl(ri, 1))
-+        goto err;
-+    /* Attempt to decrypt CEK */
-+    if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0))
-+        goto err;
-+    ec = cms->d.envelopedData->encryptedContentInfo;
-+    OPENSSL_clear_free(ec->key, ec->keylen);
-+    ec->key = cek;
-+    ec->keylen = ceklen;
-+    cek = NULL;
-+    rv = 1;
-+ err:
-+    OPENSSL_free(cek);
-+    return rv;
-+}
-+
-+/* Create ephemeral key and initialise context based on it */
-+static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
-+                                         EVP_PKEY *pk)
-+{
-+    EVP_PKEY_CTX *pctx = NULL;
-+    EVP_PKEY *ekey = NULL;
-+    int rv = 0;
-+    pctx = EVP_PKEY_CTX_new(pk, NULL);
-+    if (!pctx)
-+        goto err;
-+    if (EVP_PKEY_keygen_init(pctx) <= 0)
-+        goto err;
-+    if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
-+        goto err;
-+    EVP_PKEY_CTX_free(pctx);
-+    pctx = EVP_PKEY_CTX_new(ekey, NULL);
-+    if (!pctx)
-+        goto err;
-+    if (EVP_PKEY_derive_init(pctx) <= 0)
-+        goto err;
-+    kari->pctx = pctx;
-+    rv = 1;
-+ err:
-+    if (!rv)
-+        EVP_PKEY_CTX_free(pctx);
-+    EVP_PKEY_free(ekey);
-+    return rv;
-+}
-+
-+/* Initialise a ktri based on passed certificate and key */
-+
-+int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
-+                                EVP_PKEY *pk, unsigned int flags)
-+{
-+    CMS_KeyAgreeRecipientInfo *kari;
-+    CMS_RecipientEncryptedKey *rek = NULL;
-+
-+    ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
-+    if (!ri->d.kari)
-+        return 0;
-+    ri->type = CMS_RECIPINFO_AGREE;
-+
-+    kari = ri->d.kari;
-+    kari->version = 3;
-+
-+    rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
-+    if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) {
-+        M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
-+        return 0;
-+    }
-+
-+    if (flags & CMS_USE_KEYID) {
-+        rek->rid->type = CMS_REK_KEYIDENTIFIER;
-+        rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier);
-+        if (rek->rid->d.rKeyId == NULL)
-+            return 0;
-+        if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip))
-+            return 0;
-+    } else {
-+        rek->rid->type = CMS_REK_ISSUER_SERIAL;
-+        if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip))
-+            return 0;
-+    }
-+
-+    /* Create ephemeral key */
-+    if (!cms_kari_create_ephemeral_key(kari, pk))
-+        return 0;
-+
-+    EVP_PKEY_up_ref(pk);
-+    rek->pkey = pk;
-+    return 1;
-+}
-+
-+static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
-+                         const EVP_CIPHER *cipher)
-+{
-+    EVP_CIPHER_CTX *ctx = kari->ctx;
-+    const EVP_CIPHER *kekcipher;
-+    int keylen = EVP_CIPHER_key_length(cipher);
-+    /* If a suitable wrap algorithm is already set nothing to do */
-+    kekcipher = EVP_CIPHER_CTX_cipher(ctx);
-+
-+    if (kekcipher) {
-+        if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE)
-+            return 0;
-+        return 1;
-+    }
-+    /*
-+     * Pick a cipher based on content encryption cipher. If it is DES3 use
-+     * DES3 wrap otherwise use AES wrap similar to key size.
-+     */
-+#ifndef OPENSSL_NO_DES
-+    if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
-+        kekcipher = EVP_des_ede3_wrap();
-+    else
-+#endif
-+    if (keylen <= 16)
-+        kekcipher = EVP_aes_128_wrap();
-+    else if (keylen <= 24)
-+        kekcipher = EVP_aes_192_wrap();
-+    else
-+        kekcipher = EVP_aes_256_wrap();
-+    return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL);
-+}
-+
-+/* Encrypt content key in key agreement recipient info */
-+
-+int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
-+                                   CMS_RecipientInfo *ri)
-+{
-+    CMS_KeyAgreeRecipientInfo *kari;
-+    CMS_EncryptedContentInfo *ec;
-+    CMS_RecipientEncryptedKey *rek;
-+    STACK_OF(CMS_RecipientEncryptedKey) *reks;
-+    int i;
-+
-+    if (ri->type != CMS_RECIPINFO_AGREE) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT);
-+        return 0;
-+    }
-+    kari = ri->d.kari;
-+    reks = kari->recipientEncryptedKeys;
-+    ec = cms->d.envelopedData->encryptedContentInfo;
-+    /* Initialise wrap algorithm parameters */
-+    if (!cms_wrap_init(kari, ec->cipher))
-+        return 0;
-+    /*
-+     * If no originator key set up initialise for ephemeral key the public key
-+     * ASN1 structure will set the actual public key value.
-+     */
-+    if (kari->originator->type == -1) {
-+        CMS_OriginatorIdentifierOrKey *oik = kari->originator;
-+        oik->type = CMS_OIK_PUBKEY;
-+        oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
-+        if (!oik->d.originatorKey)
-+            return 0;
-+    }
-+    /* Initialise KDF algorithm */
-+    if (!cms_env_asn1_ctrl(ri, 0))
-+        return 0;
-+    /* For each rek, derive KEK, encrypt CEK */
-+    for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
-+        unsigned char *enckey;
-+        size_t enckeylen;
-+        rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
-+        if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0)
-+            return 0;
-+        if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen,
-+                            kari, 1))
-+            return 0;
-+        ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen);
-+    }
-+
-+    return 1;
-+
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_lcl.h
-new file mode 100644
-index 0000000..d0c0e81
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_lcl.h
-@@ -0,0 +1,444 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_CMS_LCL_H
-+# define HEADER_CMS_LCL_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+# include 
-+
-+/*
-+ * Cryptographic message syntax (CMS) structures: taken from RFC3852
-+ */
-+
-+/* Forward references */
-+
-+typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber;
-+typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo;
-+typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier;
-+typedef struct CMS_SignedData_st CMS_SignedData;
-+typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
-+typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
-+typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
-+typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
-+typedef struct CMS_DigestedData_st CMS_DigestedData;
-+typedef struct CMS_EncryptedData_st CMS_EncryptedData;
-+typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
-+typedef struct CMS_CompressedData_st CMS_CompressedData;
-+typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat;
-+typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo;
-+typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey;
-+typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey;
-+typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo;
-+typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier;
-+typedef struct CMS_KeyAgreeRecipientIdentifier_st
-+    CMS_KeyAgreeRecipientIdentifier;
-+typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
-+typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
-+typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
-+typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
-+typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
-+
-+struct CMS_ContentInfo_st {
-+    ASN1_OBJECT *contentType;
-+    union {
-+        ASN1_OCTET_STRING *data;
-+        CMS_SignedData *signedData;
-+        CMS_EnvelopedData *envelopedData;
-+        CMS_DigestedData *digestedData;
-+        CMS_EncryptedData *encryptedData;
-+        CMS_AuthenticatedData *authenticatedData;
-+        CMS_CompressedData *compressedData;
-+        ASN1_TYPE *other;
-+        /* Other types ... */
-+        void *otherData;
-+    } d;
-+};
-+
-+DEFINE_STACK_OF(CMS_CertificateChoices)
-+
-+struct CMS_SignedData_st {
-+    long version;
-+    STACK_OF(X509_ALGOR) *digestAlgorithms;
-+    CMS_EncapsulatedContentInfo *encapContentInfo;
-+    STACK_OF(CMS_CertificateChoices) *certificates;
-+    STACK_OF(CMS_RevocationInfoChoice) *crls;
-+    STACK_OF(CMS_SignerInfo) *signerInfos;
-+};
-+
-+struct CMS_EncapsulatedContentInfo_st {
-+    ASN1_OBJECT *eContentType;
-+    ASN1_OCTET_STRING *eContent;
-+    /* Set to 1 if incomplete structure only part set up */
-+    int partial;
-+};
-+
-+struct CMS_SignerInfo_st {
-+    long version;
-+    CMS_SignerIdentifier *sid;
-+    X509_ALGOR *digestAlgorithm;
-+    STACK_OF(X509_ATTRIBUTE) *signedAttrs;
-+    X509_ALGOR *signatureAlgorithm;
-+    ASN1_OCTET_STRING *signature;
-+    STACK_OF(X509_ATTRIBUTE) *unsignedAttrs;
-+    /* Signing certificate and key */
-+    X509 *signer;
-+    EVP_PKEY *pkey;
-+    /* Digest and public key context for alternative parameters */
-+    EVP_MD_CTX *mctx;
-+    EVP_PKEY_CTX *pctx;
-+};
-+
-+struct CMS_SignerIdentifier_st {
-+    int type;
-+    union {
-+        CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
-+        ASN1_OCTET_STRING *subjectKeyIdentifier;
-+    } d;
-+};
-+
-+struct CMS_EnvelopedData_st {
-+    long version;
-+    CMS_OriginatorInfo *originatorInfo;
-+    STACK_OF(CMS_RecipientInfo) *recipientInfos;
-+    CMS_EncryptedContentInfo *encryptedContentInfo;
-+    STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
-+};
-+
-+struct CMS_OriginatorInfo_st {
-+    STACK_OF(CMS_CertificateChoices) *certificates;
-+    STACK_OF(CMS_RevocationInfoChoice) *crls;
-+};
-+
-+struct CMS_EncryptedContentInfo_st {
-+    ASN1_OBJECT *contentType;
-+    X509_ALGOR *contentEncryptionAlgorithm;
-+    ASN1_OCTET_STRING *encryptedContent;
-+    /* Content encryption algorithm and key */
-+    const EVP_CIPHER *cipher;
-+    unsigned char *key;
-+    size_t keylen;
-+    /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
-+    int debug;
-+};
-+
-+struct CMS_RecipientInfo_st {
-+    int type;
-+    union {
-+        CMS_KeyTransRecipientInfo *ktri;
-+        CMS_KeyAgreeRecipientInfo *kari;
-+        CMS_KEKRecipientInfo *kekri;
-+        CMS_PasswordRecipientInfo *pwri;
-+        CMS_OtherRecipientInfo *ori;
-+    } d;
-+};
-+
-+typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
-+
-+struct CMS_KeyTransRecipientInfo_st {
-+    long version;
-+    CMS_RecipientIdentifier *rid;
-+    X509_ALGOR *keyEncryptionAlgorithm;
-+    ASN1_OCTET_STRING *encryptedKey;
-+    /* Recipient Key and cert */
-+    X509 *recip;
-+    EVP_PKEY *pkey;
-+    /* Public key context for this operation */
-+    EVP_PKEY_CTX *pctx;
-+};
-+
-+struct CMS_KeyAgreeRecipientInfo_st {
-+    long version;
-+    CMS_OriginatorIdentifierOrKey *originator;
-+    ASN1_OCTET_STRING *ukm;
-+    X509_ALGOR *keyEncryptionAlgorithm;
-+    STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys;
-+    /* Public key context associated with current operation */
-+    EVP_PKEY_CTX *pctx;
-+    /* Cipher context for CEK wrapping */
-+    EVP_CIPHER_CTX *ctx;
-+};
-+
-+struct CMS_OriginatorIdentifierOrKey_st {
-+    int type;
-+    union {
-+        CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
-+        ASN1_OCTET_STRING *subjectKeyIdentifier;
-+        CMS_OriginatorPublicKey *originatorKey;
-+    } d;
-+};
-+
-+struct CMS_OriginatorPublicKey_st {
-+    X509_ALGOR *algorithm;
-+    ASN1_BIT_STRING *publicKey;
-+};
-+
-+struct CMS_RecipientEncryptedKey_st {
-+    CMS_KeyAgreeRecipientIdentifier *rid;
-+    ASN1_OCTET_STRING *encryptedKey;
-+    /* Public key associated with this recipient */
-+    EVP_PKEY *pkey;
-+};
-+
-+struct CMS_KeyAgreeRecipientIdentifier_st {
-+    int type;
-+    union {
-+        CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
-+        CMS_RecipientKeyIdentifier *rKeyId;
-+    } d;
-+};
-+
-+struct CMS_RecipientKeyIdentifier_st {
-+    ASN1_OCTET_STRING *subjectKeyIdentifier;
-+    ASN1_GENERALIZEDTIME *date;
-+    CMS_OtherKeyAttribute *other;
-+};
-+
-+struct CMS_KEKRecipientInfo_st {
-+    long version;
-+    CMS_KEKIdentifier *kekid;
-+    X509_ALGOR *keyEncryptionAlgorithm;
-+    ASN1_OCTET_STRING *encryptedKey;
-+    /* Extra info: symmetric key to use */
-+    unsigned char *key;
-+    size_t keylen;
-+};
-+
-+struct CMS_KEKIdentifier_st {
-+    ASN1_OCTET_STRING *keyIdentifier;
-+    ASN1_GENERALIZEDTIME *date;
-+    CMS_OtherKeyAttribute *other;
-+};
-+
-+struct CMS_PasswordRecipientInfo_st {
-+    long version;
-+    X509_ALGOR *keyDerivationAlgorithm;
-+    X509_ALGOR *keyEncryptionAlgorithm;
-+    ASN1_OCTET_STRING *encryptedKey;
-+    /* Extra info: password to use */
-+    unsigned char *pass;
-+    size_t passlen;
-+};
-+
-+struct CMS_OtherRecipientInfo_st {
-+    ASN1_OBJECT *oriType;
-+    ASN1_TYPE *oriValue;
-+};
-+
-+struct CMS_DigestedData_st {
-+    long version;
-+    X509_ALGOR *digestAlgorithm;
-+    CMS_EncapsulatedContentInfo *encapContentInfo;
-+    ASN1_OCTET_STRING *digest;
-+};
-+
-+struct CMS_EncryptedData_st {
-+    long version;
-+    CMS_EncryptedContentInfo *encryptedContentInfo;
-+    STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
-+};
-+
-+struct CMS_AuthenticatedData_st {
-+    long version;
-+    CMS_OriginatorInfo *originatorInfo;
-+    STACK_OF(CMS_RecipientInfo) *recipientInfos;
-+    X509_ALGOR *macAlgorithm;
-+    X509_ALGOR *digestAlgorithm;
-+    CMS_EncapsulatedContentInfo *encapContentInfo;
-+    STACK_OF(X509_ATTRIBUTE) *authAttrs;
-+    ASN1_OCTET_STRING *mac;
-+    STACK_OF(X509_ATTRIBUTE) *unauthAttrs;
-+};
-+
-+struct CMS_CompressedData_st {
-+    long version;
-+    X509_ALGOR *compressionAlgorithm;
-+    STACK_OF(CMS_RecipientInfo) *recipientInfos;
-+    CMS_EncapsulatedContentInfo *encapContentInfo;
-+};
-+
-+struct CMS_RevocationInfoChoice_st {
-+    int type;
-+    union {
-+        X509_CRL *crl;
-+        CMS_OtherRevocationInfoFormat *other;
-+    } d;
-+};
-+
-+# define CMS_REVCHOICE_CRL               0
-+# define CMS_REVCHOICE_OTHER             1
-+
-+struct CMS_OtherRevocationInfoFormat_st {
-+    ASN1_OBJECT *otherRevInfoFormat;
-+    ASN1_TYPE *otherRevInfo;
-+};
-+
-+struct CMS_CertificateChoices {
-+    int type;
-+    union {
-+        X509 *certificate;
-+        ASN1_STRING *extendedCertificate; /* Obsolete */
-+        ASN1_STRING *v1AttrCert; /* Left encoded for now */
-+        ASN1_STRING *v2AttrCert; /* Left encoded for now */
-+        CMS_OtherCertificateFormat *other;
-+    } d;
-+};
-+
-+# define CMS_CERTCHOICE_CERT             0
-+# define CMS_CERTCHOICE_EXCERT           1
-+# define CMS_CERTCHOICE_V1ACERT          2
-+# define CMS_CERTCHOICE_V2ACERT          3
-+# define CMS_CERTCHOICE_OTHER            4
-+
-+struct CMS_OtherCertificateFormat_st {
-+    ASN1_OBJECT *otherCertFormat;
-+    ASN1_TYPE *otherCert;
-+};
-+
-+/*
-+ * This is also defined in pkcs7.h but we duplicate it to allow the CMS code
-+ * to be independent of PKCS#7
-+ */
-+
-+struct CMS_IssuerAndSerialNumber_st {
-+    X509_NAME *issuer;
-+    ASN1_INTEGER *serialNumber;
-+};
-+
-+struct CMS_OtherKeyAttribute_st {
-+    ASN1_OBJECT *keyAttrId;
-+    ASN1_TYPE *keyAttr;
-+};
-+
-+/* ESS structures */
-+
-+# ifdef HEADER_X509V3_H
-+
-+struct CMS_ReceiptRequest_st {
-+    ASN1_OCTET_STRING *signedContentIdentifier;
-+    CMS_ReceiptsFrom *receiptsFrom;
-+    STACK_OF(GENERAL_NAMES) *receiptsTo;
-+};
-+
-+struct CMS_ReceiptsFrom_st {
-+    int type;
-+    union {
-+        long allOrFirstTier;
-+        STACK_OF(GENERAL_NAMES) *receiptList;
-+    } d;
-+};
-+# endif
-+
-+struct CMS_Receipt_st {
-+    long version;
-+    ASN1_OBJECT *contentType;
-+    ASN1_OCTET_STRING *signedContentIdentifier;
-+    ASN1_OCTET_STRING *originatorSignatureValue;
-+};
-+
-+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
-+DECLARE_ASN1_ITEM(CMS_SignerInfo)
-+DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
-+DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
-+DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
-+DECLARE_ASN1_ITEM(CMS_RecipientInfo)
-+DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo)
-+DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
-+
-+# define CMS_SIGNERINFO_ISSUER_SERIAL    0
-+# define CMS_SIGNERINFO_KEYIDENTIFIER    1
-+
-+# define CMS_RECIPINFO_ISSUER_SERIAL     0
-+# define CMS_RECIPINFO_KEYIDENTIFIER     1
-+
-+# define CMS_REK_ISSUER_SERIAL           0
-+# define CMS_REK_KEYIDENTIFIER           1
-+
-+# define CMS_OIK_ISSUER_SERIAL           0
-+# define CMS_OIK_KEYIDENTIFIER           1
-+# define CMS_OIK_PUBKEY                  2
-+
-+BIO *cms_content_bio(CMS_ContentInfo *cms);
-+
-+CMS_ContentInfo *cms_Data_create(void);
-+
-+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
-+BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
-+int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);
-+
-+BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
-+int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
-+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert,
-+                              int type);
-+int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
-+                                        ASN1_OCTET_STRING **keyid,
-+                                        X509_NAME **issuer,
-+                                        ASN1_INTEGER **sno);
-+int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
-+
-+CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
-+BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);
-+
-+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
-+int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
-+                                 X509_ALGOR *mdalg);
-+
-+int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert);
-+int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert);
-+int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert);
-+int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert);
-+
-+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
-+BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
-+int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
-+                              const EVP_CIPHER *cipher,
-+                              const unsigned char *key, size_t keylen);
-+
-+int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
-+int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
-+ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
-+
-+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
-+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
-+int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd);
-+int cms_pkey_get_ri_type(EVP_PKEY *pk);
-+/* KARI routines */
-+int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
-+                                EVP_PKEY *pk, unsigned int flags);
-+int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
-+                                   CMS_RecipientInfo *ri);
-+
-+/* PWRI routines */
-+int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
-+                                 int en_de);
-+
-+DECLARE_ASN1_ITEM(CMS_CertificateChoices)
-+DECLARE_ASN1_ITEM(CMS_DigestedData)
-+DECLARE_ASN1_ITEM(CMS_EncryptedData)
-+DECLARE_ASN1_ITEM(CMS_EnvelopedData)
-+DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
-+DECLARE_ASN1_ITEM(CMS_KeyAgreeRecipientInfo)
-+DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
-+DECLARE_ASN1_ITEM(CMS_OriginatorPublicKey)
-+DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
-+DECLARE_ASN1_ITEM(CMS_Receipt)
-+DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
-+DECLARE_ASN1_ITEM(CMS_RecipientEncryptedKey)
-+DECLARE_ASN1_ITEM(CMS_RecipientKeyIdentifier)
-+DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
-+DECLARE_ASN1_ITEM(CMS_SignedData)
-+DECLARE_ASN1_ITEM(CMS_CompressedData)
-+
-+#ifdef  __cplusplus
-+}
-+#endif
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_lib.c
-new file mode 100644
-index 0000000..7395684
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_lib.c
-@@ -0,0 +1,587 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+
-+IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
-+IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
-+
-+const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms)
-+{
-+    return cms->contentType;
-+}
-+
-+CMS_ContentInfo *cms_Data_create(void)
-+{
-+    CMS_ContentInfo *cms;
-+    cms = CMS_ContentInfo_new();
-+    if (cms != NULL) {
-+        cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
-+        /* Never detached */
-+        CMS_set_detached(cms, 0);
-+    }
-+    return cms;
-+}
-+
-+BIO *cms_content_bio(CMS_ContentInfo *cms)
-+{
-+    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
-+    if (!pos)
-+        return NULL;
-+    /* If content detached data goes nowhere: create NULL BIO */
-+    if (!*pos)
-+        return BIO_new(BIO_s_null());
-+    /*
-+     * If content not detached and created return memory BIO
-+     */
-+    if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
-+        return BIO_new(BIO_s_mem());
-+    /* Else content was read in: return read only BIO for it */
-+    return BIO_new_mem_buf((*pos)->data, (*pos)->length);
-+}
-+
-+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
-+{
-+    BIO *cmsbio, *cont;
-+    if (icont)
-+        cont = icont;
-+    else
-+        cont = cms_content_bio(cms);
-+    if (!cont) {
-+        CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
-+        return NULL;
-+    }
-+    switch (OBJ_obj2nid(cms->contentType)) {
-+
-+    case NID_pkcs7_data:
-+        return cont;
-+
-+    case NID_pkcs7_signed:
-+        cmsbio = cms_SignedData_init_bio(cms);
-+        break;
-+
-+    case NID_pkcs7_digest:
-+        cmsbio = cms_DigestedData_init_bio(cms);
-+        break;
-+#ifdef ZLIB
-+    case NID_id_smime_ct_compressedData:
-+        cmsbio = cms_CompressedData_init_bio(cms);
-+        break;
-+#endif
-+
-+    case NID_pkcs7_encrypted:
-+        cmsbio = cms_EncryptedData_init_bio(cms);
-+        break;
-+
-+    case NID_pkcs7_enveloped:
-+        cmsbio = cms_EnvelopedData_init_bio(cms);
-+        break;
-+
-+    default:
-+        CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
-+        return NULL;
-+    }
-+
-+    if (cmsbio)
-+        return BIO_push(cmsbio, cont);
-+
-+    if (!icont)
-+        BIO_free(cont);
-+    return NULL;
-+
-+}
-+
-+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
-+{
-+    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
-+    if (!pos)
-+        return 0;
-+    /* If embedded content find memory BIO and set content */
-+    if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) {
-+        BIO *mbio;
-+        unsigned char *cont;
-+        long contlen;
-+        mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
-+        if (!mbio) {
-+            CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
-+            return 0;
-+        }
-+        contlen = BIO_get_mem_data(mbio, &cont);
-+        /* Set bio as read only so its content can't be clobbered */
-+        BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
-+        BIO_set_mem_eof_return(mbio, 0);
-+        ASN1_STRING_set0(*pos, cont, contlen);
-+        (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
-+    }
-+
-+    switch (OBJ_obj2nid(cms->contentType)) {
-+
-+    case NID_pkcs7_data:
-+    case NID_pkcs7_enveloped:
-+    case NID_pkcs7_encrypted:
-+    case NID_id_smime_ct_compressedData:
-+        /* Nothing to do */
-+        return 1;
-+
-+    case NID_pkcs7_signed:
-+        return cms_SignedData_final(cms, cmsbio);
-+
-+    case NID_pkcs7_digest:
-+        return cms_DigestedData_do_final(cms, cmsbio, 0);
-+
-+    default:
-+        CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
-+        return 0;
-+    }
-+}
-+
-+/*
-+ * Return an OCTET STRING pointer to content. This allows it to be accessed
-+ * or set later.
-+ */
-+
-+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
-+{
-+    switch (OBJ_obj2nid(cms->contentType)) {
-+
-+    case NID_pkcs7_data:
-+        return &cms->d.data;
-+
-+    case NID_pkcs7_signed:
-+        return &cms->d.signedData->encapContentInfo->eContent;
-+
-+    case NID_pkcs7_enveloped:
-+        return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
-+
-+    case NID_pkcs7_digest:
-+        return &cms->d.digestedData->encapContentInfo->eContent;
-+
-+    case NID_pkcs7_encrypted:
-+        return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
-+
-+    case NID_id_smime_ct_authData:
-+        return &cms->d.authenticatedData->encapContentInfo->eContent;
-+
-+    case NID_id_smime_ct_compressedData:
-+        return &cms->d.compressedData->encapContentInfo->eContent;
-+
-+    default:
-+        if (cms->d.other->type == V_ASN1_OCTET_STRING)
-+            return &cms->d.other->value.octet_string;
-+        CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
-+        return NULL;
-+
-+    }
-+}
-+
-+/*
-+ * Return an ASN1_OBJECT pointer to content type. This allows it to be
-+ * accessed or set later.
-+ */
-+
-+static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
-+{
-+    switch (OBJ_obj2nid(cms->contentType)) {
-+
-+    case NID_pkcs7_signed:
-+        return &cms->d.signedData->encapContentInfo->eContentType;
-+
-+    case NID_pkcs7_enveloped:
-+        return &cms->d.envelopedData->encryptedContentInfo->contentType;
-+
-+    case NID_pkcs7_digest:
-+        return &cms->d.digestedData->encapContentInfo->eContentType;
-+
-+    case NID_pkcs7_encrypted:
-+        return &cms->d.encryptedData->encryptedContentInfo->contentType;
-+
-+    case NID_id_smime_ct_authData:
-+        return &cms->d.authenticatedData->encapContentInfo->eContentType;
-+
-+    case NID_id_smime_ct_compressedData:
-+        return &cms->d.compressedData->encapContentInfo->eContentType;
-+
-+    default:
-+        CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, CMS_R_UNSUPPORTED_CONTENT_TYPE);
-+        return NULL;
-+
-+    }
-+}
-+
-+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
-+{
-+    ASN1_OBJECT **petype;
-+    petype = cms_get0_econtent_type(cms);
-+    if (petype)
-+        return *petype;
-+    return NULL;
-+}
-+
-+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
-+{
-+    ASN1_OBJECT **petype, *etype;
-+    petype = cms_get0_econtent_type(cms);
-+    if (!petype)
-+        return 0;
-+    if (!oid)
-+        return 1;
-+    etype = OBJ_dup(oid);
-+    if (!etype)
-+        return 0;
-+    ASN1_OBJECT_free(*petype);
-+    *petype = etype;
-+    return 1;
-+}
-+
-+int CMS_is_detached(CMS_ContentInfo *cms)
-+{
-+    ASN1_OCTET_STRING **pos;
-+    pos = CMS_get0_content(cms);
-+    if (!pos)
-+        return -1;
-+    if (*pos)
-+        return 0;
-+    return 1;
-+}
-+
-+int CMS_set_detached(CMS_ContentInfo *cms, int detached)
-+{
-+    ASN1_OCTET_STRING **pos;
-+    pos = CMS_get0_content(cms);
-+    if (!pos)
-+        return 0;
-+    if (detached) {
-+        ASN1_OCTET_STRING_free(*pos);
-+        *pos = NULL;
-+        return 1;
-+    }
-+    if (*pos == NULL)
-+        *pos = ASN1_OCTET_STRING_new();
-+    if (*pos != NULL) {
-+        /*
-+         * NB: special flag to show content is created and not read in.
-+         */
-+        (*pos)->flags |= ASN1_STRING_FLAG_CONT;
-+        return 1;
-+    }
-+    CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
-+    return 0;
-+}
-+
-+/* Create a digest BIO from an X509_ALGOR structure */
-+
-+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
-+{
-+    BIO *mdbio = NULL;
-+    const ASN1_OBJECT *digestoid;
-+    const EVP_MD *digest;
-+    X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
-+    digest = EVP_get_digestbyobj(digestoid);
-+    if (!digest) {
-+        CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
-+               CMS_R_UNKNOWN_DIGEST_ALGORIHM);
-+        goto err;
-+    }
-+    mdbio = BIO_new(BIO_f_md());
-+    if (mdbio == NULL || !BIO_set_md(mdbio, digest)) {
-+        CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR);
-+        goto err;
-+    }
-+    return mdbio;
-+ err:
-+    BIO_free(mdbio);
-+    return NULL;
-+}
-+
-+/* Locate a message digest content from a BIO chain based on SignerInfo */
-+
-+int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
-+                                 X509_ALGOR *mdalg)
-+{
-+    int nid;
-+    const ASN1_OBJECT *mdoid;
-+    X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
-+    nid = OBJ_obj2nid(mdoid);
-+    /* Look for digest type to match signature */
-+    for (;;) {
-+        EVP_MD_CTX *mtmp;
-+        chain = BIO_find_type(chain, BIO_TYPE_MD);
-+        if (chain == NULL) {
-+            CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
-+                   CMS_R_NO_MATCHING_DIGEST);
-+            return 0;
-+        }
-+        BIO_get_md_ctx(chain, &mtmp);
-+        if (EVP_MD_CTX_type(mtmp) == nid
-+            /*
-+             * Workaround for broken implementations that use signature
-+             * algorithm OID instead of digest.
-+             */
-+            || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
-+            return EVP_MD_CTX_copy_ex(mctx, mtmp);
-+        chain = BIO_next(chain);
-+    }
-+}
-+
-+static STACK_OF(CMS_CertificateChoices)
-+**cms_get0_certificate_choices(CMS_ContentInfo *cms)
-+{
-+    switch (OBJ_obj2nid(cms->contentType)) {
-+
-+    case NID_pkcs7_signed:
-+        return &cms->d.signedData->certificates;
-+
-+    case NID_pkcs7_enveloped:
-+        if (cms->d.envelopedData->originatorInfo == NULL)
-+            return NULL;
-+        return &cms->d.envelopedData->originatorInfo->certificates;
-+
-+    default:
-+        CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
-+               CMS_R_UNSUPPORTED_CONTENT_TYPE);
-+        return NULL;
-+
-+    }
-+}
-+
-+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
-+{
-+    STACK_OF(CMS_CertificateChoices) **pcerts;
-+    CMS_CertificateChoices *cch;
-+    pcerts = cms_get0_certificate_choices(cms);
-+    if (!pcerts)
-+        return NULL;
-+    if (!*pcerts)
-+        *pcerts = sk_CMS_CertificateChoices_new_null();
-+    if (!*pcerts)
-+        return NULL;
-+    cch = M_ASN1_new_of(CMS_CertificateChoices);
-+    if (!cch)
-+        return NULL;
-+    if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) {
-+        M_ASN1_free_of(cch, CMS_CertificateChoices);
-+        return NULL;
-+    }
-+    return cch;
-+}
-+
-+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
-+{
-+    CMS_CertificateChoices *cch;
-+    STACK_OF(CMS_CertificateChoices) **pcerts;
-+    int i;
-+    pcerts = cms_get0_certificate_choices(cms);
-+    if (!pcerts)
-+        return 0;
-+    for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
-+        cch = sk_CMS_CertificateChoices_value(*pcerts, i);
-+        if (cch->type == CMS_CERTCHOICE_CERT) {
-+            if (!X509_cmp(cch->d.certificate, cert)) {
-+                CMSerr(CMS_F_CMS_ADD0_CERT,
-+                       CMS_R_CERTIFICATE_ALREADY_PRESENT);
-+                return 0;
-+            }
-+        }
-+    }
-+    cch = CMS_add0_CertificateChoices(cms);
-+    if (!cch)
-+        return 0;
-+    cch->type = CMS_CERTCHOICE_CERT;
-+    cch->d.certificate = cert;
-+    return 1;
-+}
-+
-+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
-+{
-+    int r;
-+    r = CMS_add0_cert(cms, cert);
-+    if (r > 0)
-+        X509_up_ref(cert);
-+    return r;
-+}
-+
-+static STACK_OF(CMS_RevocationInfoChoice)
-+**cms_get0_revocation_choices(CMS_ContentInfo *cms)
-+{
-+    switch (OBJ_obj2nid(cms->contentType)) {
-+
-+    case NID_pkcs7_signed:
-+        return &cms->d.signedData->crls;
-+
-+    case NID_pkcs7_enveloped:
-+        if (cms->d.envelopedData->originatorInfo == NULL)
-+            return NULL;
-+        return &cms->d.envelopedData->originatorInfo->crls;
-+
-+    default:
-+        CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
-+               CMS_R_UNSUPPORTED_CONTENT_TYPE);
-+        return NULL;
-+
-+    }
-+}
-+
-+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
-+{
-+    STACK_OF(CMS_RevocationInfoChoice) **pcrls;
-+    CMS_RevocationInfoChoice *rch;
-+    pcrls = cms_get0_revocation_choices(cms);
-+    if (!pcrls)
-+        return NULL;
-+    if (!*pcrls)
-+        *pcrls = sk_CMS_RevocationInfoChoice_new_null();
-+    if (!*pcrls)
-+        return NULL;
-+    rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
-+    if (!rch)
-+        return NULL;
-+    if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) {
-+        M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
-+        return NULL;
-+    }
-+    return rch;
-+}
-+
-+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
-+{
-+    CMS_RevocationInfoChoice *rch;
-+    rch = CMS_add0_RevocationInfoChoice(cms);
-+    if (!rch)
-+        return 0;
-+    rch->type = CMS_REVCHOICE_CRL;
-+    rch->d.crl = crl;
-+    return 1;
-+}
-+
-+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
-+{
-+    int r;
-+    r = CMS_add0_crl(cms, crl);
-+    if (r > 0)
-+        X509_CRL_up_ref(crl);
-+    return r;
-+}
-+
-+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
-+{
-+    STACK_OF(X509) *certs = NULL;
-+    CMS_CertificateChoices *cch;
-+    STACK_OF(CMS_CertificateChoices) **pcerts;
-+    int i;
-+    pcerts = cms_get0_certificate_choices(cms);
-+    if (!pcerts)
-+        return NULL;
-+    for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
-+        cch = sk_CMS_CertificateChoices_value(*pcerts, i);
-+        if (cch->type == 0) {
-+            if (!certs) {
-+                certs = sk_X509_new_null();
-+                if (!certs)
-+                    return NULL;
-+            }
-+            if (!sk_X509_push(certs, cch->d.certificate)) {
-+                sk_X509_pop_free(certs, X509_free);
-+                return NULL;
-+            }
-+            X509_up_ref(cch->d.certificate);
-+        }
-+    }
-+    return certs;
-+
-+}
-+
-+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
-+{
-+    STACK_OF(X509_CRL) *crls = NULL;
-+    STACK_OF(CMS_RevocationInfoChoice) **pcrls;
-+    CMS_RevocationInfoChoice *rch;
-+    int i;
-+    pcrls = cms_get0_revocation_choices(cms);
-+    if (!pcrls)
-+        return NULL;
-+    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) {
-+        rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
-+        if (rch->type == 0) {
-+            if (!crls) {
-+                crls = sk_X509_CRL_new_null();
-+                if (!crls)
-+                    return NULL;
-+            }
-+            if (!sk_X509_CRL_push(crls, rch->d.crl)) {
-+                sk_X509_CRL_pop_free(crls, X509_CRL_free);
-+                return NULL;
-+            }
-+            X509_CRL_up_ref(rch->d.crl);
-+        }
-+    }
-+    return crls;
-+}
-+
-+int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert)
-+{
-+    int ret;
-+    ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert));
-+    if (ret)
-+        return ret;
-+    return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert));
-+}
-+
-+int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert)
-+{
-+    const ASN1_OCTET_STRING *cert_keyid = X509_get0_subject_key_id(cert);
-+
-+    if (cert_keyid == NULL)
-+        return -1;
-+    return ASN1_OCTET_STRING_cmp(keyid, cert_keyid);
-+}
-+
-+int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert)
-+{
-+    CMS_IssuerAndSerialNumber *ias;
-+    ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber);
-+    if (!ias)
-+        goto err;
-+    if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert)))
-+        goto err;
-+    if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert)))
-+        goto err;
-+    M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber);
-+    *pias = ias;
-+    return 1;
-+ err:
-+    M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber);
-+    CMSerr(CMS_F_CMS_SET1_IAS, ERR_R_MALLOC_FAILURE);
-+    return 0;
-+}
-+
-+int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert)
-+{
-+    ASN1_OCTET_STRING *keyid = NULL;
-+    const ASN1_OCTET_STRING *cert_keyid;
-+    cert_keyid = X509_get0_subject_key_id(cert);
-+    if (cert_keyid == NULL) {
-+        CMSerr(CMS_F_CMS_SET1_KEYID, CMS_R_CERTIFICATE_HAS_NO_KEYID);
-+        return 0;
-+    }
-+    keyid = ASN1_STRING_dup(cert_keyid);
-+    if (!keyid) {
-+        CMSerr(CMS_F_CMS_SET1_KEYID, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ASN1_OCTET_STRING_free(*pkeyid);
-+    *pkeyid = keyid;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_pwri.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_pwri.c
-new file mode 100644
-index 0000000..0571bb8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_pwri.c
-@@ -0,0 +1,392 @@
-+/*
-+ * Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+#include "internal/asn1_int.h"
-+
-+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
-+                                    unsigned char *pass, ossl_ssize_t passlen)
-+{
-+    CMS_PasswordRecipientInfo *pwri;
-+    if (ri->type != CMS_RECIPINFO_PASS) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI);
-+        return 0;
-+    }
-+
-+    pwri = ri->d.pwri;
-+    pwri->pass = pass;
-+    if (pass && passlen < 0)
-+        passlen = strlen((char *)pass);
-+    pwri->passlen = passlen;
-+    return 1;
-+}
-+
-+CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
-+                                               int iter, int wrap_nid,
-+                                               int pbe_nid,
-+                                               unsigned char *pass,
-+                                               ossl_ssize_t passlen,
-+                                               const EVP_CIPHER *kekciph)
-+{
-+    CMS_RecipientInfo *ri = NULL;
-+    CMS_EnvelopedData *env;
-+    CMS_PasswordRecipientInfo *pwri;
-+    EVP_CIPHER_CTX *ctx = NULL;
-+    X509_ALGOR *encalg = NULL;
-+    unsigned char iv[EVP_MAX_IV_LENGTH];
-+    int ivlen;
-+
-+    env = cms_get0_enveloped(cms);
-+    if (!env)
-+        return NULL;
-+
-+    if (wrap_nid <= 0)
-+        wrap_nid = NID_id_alg_PWRI_KEK;
-+
-+    if (pbe_nid <= 0)
-+        pbe_nid = NID_id_pbkdf2;
-+
-+    /* Get from enveloped data */
-+    if (kekciph == NULL)
-+        kekciph = env->encryptedContentInfo->cipher;
-+
-+    if (kekciph == NULL) {
-+        CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER);
-+        return NULL;
-+    }
-+    if (wrap_nid != NID_id_alg_PWRI_KEK) {
-+        CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
-+               CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
-+        return NULL;
-+    }
-+
-+    /* Setup algorithm identifier for cipher */
-+    encalg = X509_ALGOR_new();
-+    if (encalg == NULL) {
-+        goto merr;
-+    }
-+    ctx = EVP_CIPHER_CTX_new();
-+
-+    if (EVP_EncryptInit_ex(ctx, kekciph, NULL, NULL, NULL) <= 0) {
-+        CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
-+        goto err;
-+    }
-+
-+    ivlen = EVP_CIPHER_CTX_iv_length(ctx);
-+
-+    if (ivlen > 0) {
-+        if (RAND_bytes(iv, ivlen) <= 0)
-+            goto err;
-+        if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) {
-+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
-+            goto err;
-+        }
-+        encalg->parameter = ASN1_TYPE_new();
-+        if (!encalg->parameter) {
-+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) {
-+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
-+                   CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
-+            goto err;
-+        }
-+    }
-+
-+    encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
-+
-+    EVP_CIPHER_CTX_free(ctx);
-+    ctx = NULL;
-+
-+    /* Initialize recipient info */
-+    ri = M_ASN1_new_of(CMS_RecipientInfo);
-+    if (ri == NULL)
-+        goto merr;
-+
-+    ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
-+    if (ri->d.pwri == NULL)
-+        goto merr;
-+    ri->type = CMS_RECIPINFO_PASS;
-+
-+    pwri = ri->d.pwri;
-+    /* Since this is overwritten, free up empty structure already there */
-+    X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
-+    pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
-+    if (pwri->keyEncryptionAlgorithm == NULL)
-+        goto merr;
-+    pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
-+    pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
-+    if (pwri->keyEncryptionAlgorithm->parameter == NULL)
-+        goto merr;
-+
-+    if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
-+                        &pwri->keyEncryptionAlgorithm->parameter->
-+                        value.sequence))
-+         goto merr;
-+    pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
-+
-+    X509_ALGOR_free(encalg);
-+    encalg = NULL;
-+
-+    /* Setup PBE algorithm */
-+
-+    pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);
-+
-+    if (!pwri->keyDerivationAlgorithm)
-+        goto err;
-+
-+    CMS_RecipientInfo_set0_password(ri, pass, passlen);
-+    pwri->version = 0;
-+
-+    if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
-+        goto merr;
-+
-+    return ri;
-+
-+ merr:
-+    CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
-+ err:
-+    EVP_CIPHER_CTX_free(ctx);
-+    if (ri)
-+        M_ASN1_free_of(ri, CMS_RecipientInfo);
-+    X509_ALGOR_free(encalg);
-+    return NULL;
-+
-+}
-+
-+/*
-+ * This is an implementation of the key wrapping mechanism in RFC3211, at
-+ * some point this should go into EVP.
-+ */
-+
-+static int kek_unwrap_key(unsigned char *out, size_t *outlen,
-+                          const unsigned char *in, size_t inlen,
-+                          EVP_CIPHER_CTX *ctx)
-+{
-+    size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
-+    unsigned char *tmp;
-+    int outl, rv = 0;
-+    if (inlen < 2 * blocklen) {
-+        /* too small */
-+        return 0;
-+    }
-+    if (inlen % blocklen) {
-+        /* Invalid size */
-+        return 0;
-+    }
-+    tmp = OPENSSL_malloc(inlen);
-+    if (tmp == NULL)
-+        return 0;
-+    /* setup IV by decrypting last two blocks */
-+    if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
-+                           in + inlen - 2 * blocklen, blocklen * 2)
-+        /*
-+         * Do a decrypt of last decrypted block to set IV to correct value
-+         * output it to start of buffer so we don't corrupt decrypted block
-+         * this works because buffer is at least two block lengths long.
-+         */
-+        || !EVP_DecryptUpdate(ctx, tmp, &outl,
-+                              tmp + inlen - blocklen, blocklen)
-+        /* Can now decrypt first n - 1 blocks */
-+        || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen)
-+
-+        /* Reset IV to original value */
-+        || !EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL)
-+        /* Decrypt again */
-+        || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen))
-+        goto err;
-+    /* Check check bytes */
-+    if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) {
-+        /* Check byte failure */
-+        goto err;
-+    }
-+    if (inlen < (size_t)(tmp[0] - 4)) {
-+        /* Invalid length value */
-+        goto err;
-+    }
-+    *outlen = (size_t)tmp[0];
-+    memcpy(out, tmp + 4, *outlen);
-+    rv = 1;
-+ err:
-+    OPENSSL_clear_free(tmp, inlen);
-+    return rv;
-+
-+}
-+
-+static int kek_wrap_key(unsigned char *out, size_t *outlen,
-+                        const unsigned char *in, size_t inlen,
-+                        EVP_CIPHER_CTX *ctx)
-+{
-+    size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
-+    size_t olen;
-+    int dummy;
-+    /*
-+     * First decide length of output buffer: need header and round up to
-+     * multiple of block length.
-+     */
-+    olen = (inlen + 4 + blocklen - 1) / blocklen;
-+    olen *= blocklen;
-+    if (olen < 2 * blocklen) {
-+        /* Key too small */
-+        return 0;
-+    }
-+    if (inlen > 0xFF) {
-+        /* Key too large */
-+        return 0;
-+    }
-+    if (out) {
-+        /* Set header */
-+        out[0] = (unsigned char)inlen;
-+        out[1] = in[0] ^ 0xFF;
-+        out[2] = in[1] ^ 0xFF;
-+        out[3] = in[2] ^ 0xFF;
-+        memcpy(out + 4, in, inlen);
-+        /* Add random padding to end */
-+        if (olen > inlen + 4
-+            && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0)
-+            return 0;
-+        /* Encrypt twice */
-+        if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen)
-+            || !EVP_EncryptUpdate(ctx, out, &dummy, out, olen))
-+            return 0;
-+    }
-+
-+    *outlen = olen;
-+
-+    return 1;
-+}
-+
-+/* Encrypt/Decrypt content key in PWRI recipient info */
-+
-+int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
-+                                 int en_de)
-+{
-+    CMS_EncryptedContentInfo *ec;
-+    CMS_PasswordRecipientInfo *pwri;
-+    int r = 0;
-+    X509_ALGOR *algtmp, *kekalg = NULL;
-+    EVP_CIPHER_CTX *kekctx = NULL;
-+    const EVP_CIPHER *kekcipher;
-+    unsigned char *key = NULL;
-+    size_t keylen;
-+
-+    ec = cms->d.envelopedData->encryptedContentInfo;
-+
-+    pwri = ri->d.pwri;
-+
-+    if (!pwri->pass) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
-+        return 0;
-+    }
-+    algtmp = pwri->keyEncryptionAlgorithm;
-+
-+    if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
-+               CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
-+        return 0;
-+    }
-+
-+    kekalg = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
-+                                       algtmp->parameter);
-+
-+    if (kekalg == NULL) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
-+               CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
-+        return 0;
-+    }
-+
-+    kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
-+
-+    if (!kekcipher) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER);
-+        return 0;
-+    }
-+
-+    kekctx = EVP_CIPHER_CTX_new();
-+    if (kekctx == NULL) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    /* Fixup cipher based on AlgorithmIdentifier to set IV etc */
-+    if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de))
-+        goto err;
-+    EVP_CIPHER_CTX_set_padding(kekctx, 0);
-+    if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) < 0) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
-+               CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
-+        goto err;
-+    }
-+
-+    algtmp = pwri->keyDerivationAlgorithm;
-+
-+    /* Finish password based key derivation to setup key in "ctx" */
-+
-+    if (EVP_PBE_CipherInit(algtmp->algorithm,
-+                           (char *)pwri->pass, pwri->passlen,
-+                           algtmp->parameter, kekctx, en_de) < 0) {
-+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
-+        goto err;
-+    }
-+
-+    /* Finally wrap/unwrap the key */
-+
-+    if (en_de) {
-+
-+        if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx))
-+            goto err;
-+
-+        key = OPENSSL_malloc(keylen);
-+
-+        if (key == NULL)
-+            goto err;
-+
-+        if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx))
-+            goto err;
-+        pwri->encryptedKey->data = key;
-+        pwri->encryptedKey->length = keylen;
-+    } else {
-+        key = OPENSSL_malloc(pwri->encryptedKey->length);
-+
-+        if (key == NULL) {
-+            CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (!kek_unwrap_key(key, &keylen,
-+                            pwri->encryptedKey->data,
-+                            pwri->encryptedKey->length, kekctx)) {
-+            CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE);
-+            goto err;
-+        }
-+
-+        ec->key = key;
-+        ec->keylen = keylen;
-+
-+    }
-+
-+    r = 1;
-+
-+ err:
-+
-+    EVP_CIPHER_CTX_free(kekctx);
-+
-+    if (!r)
-+        OPENSSL_free(key);
-+    X509_ALGOR_free(kekalg);
-+
-+    return r;
-+
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_sd.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_sd.c
-new file mode 100644
-index 0000000..76c1f53
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_sd.c
-@@ -0,0 +1,923 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+/* CMS SignedData Utilities */
-+
-+static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
-+{
-+    if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) {
-+        CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
-+        return NULL;
-+    }
-+    return cms->d.signedData;
-+}
-+
-+static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
-+{
-+    if (cms->d.other == NULL) {
-+        cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
-+        if (!cms->d.signedData) {
-+            CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
-+            return NULL;
-+        }
-+        cms->d.signedData->version = 1;
-+        cms->d.signedData->encapContentInfo->eContentType =
-+            OBJ_nid2obj(NID_pkcs7_data);
-+        cms->d.signedData->encapContentInfo->partial = 1;
-+        ASN1_OBJECT_free(cms->contentType);
-+        cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
-+        return cms->d.signedData;
-+    }
-+    return cms_get0_signed(cms);
-+}
-+
-+/* Just initialise SignedData e.g. for certs only structure */
-+
-+int CMS_SignedData_init(CMS_ContentInfo *cms)
-+{
-+    if (cms_signed_data_init(cms))
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+/* Check structures and fixup version numbers (if necessary) */
-+
-+static void cms_sd_set_version(CMS_SignedData *sd)
-+{
-+    int i;
-+    CMS_CertificateChoices *cch;
-+    CMS_RevocationInfoChoice *rch;
-+    CMS_SignerInfo *si;
-+
-+    for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) {
-+        cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
-+        if (cch->type == CMS_CERTCHOICE_OTHER) {
-+            if (sd->version < 5)
-+                sd->version = 5;
-+        } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
-+            if (sd->version < 4)
-+                sd->version = 4;
-+        } else if (cch->type == CMS_CERTCHOICE_V1ACERT) {
-+            if (sd->version < 3)
-+                sd->version = 3;
-+        }
-+    }
-+
-+    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) {
-+        rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
-+        if (rch->type == CMS_REVCHOICE_OTHER) {
-+            if (sd->version < 5)
-+                sd->version = 5;
-+        }
-+    }
-+
-+    if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
-+        && (sd->version < 3))
-+        sd->version = 3;
-+
-+    for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
-+        si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
-+        if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
-+            if (si->version < 3)
-+                si->version = 3;
-+            if (sd->version < 3)
-+                sd->version = 3;
-+        } else if (si->version < 1)
-+            si->version = 1;
-+    }
-+
-+    if (sd->version < 1)
-+        sd->version = 1;
-+
-+}
-+
-+/* Copy an existing messageDigest value */
-+
-+static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
-+{
-+    STACK_OF(CMS_SignerInfo) *sinfos;
-+    CMS_SignerInfo *sitmp;
-+    int i;
-+    sinfos = CMS_get0_SignerInfos(cms);
-+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
-+        ASN1_OCTET_STRING *messageDigest;
-+        sitmp = sk_CMS_SignerInfo_value(sinfos, i);
-+        if (sitmp == si)
-+            continue;
-+        if (CMS_signed_get_attr_count(sitmp) < 0)
-+            continue;
-+        if (OBJ_cmp(si->digestAlgorithm->algorithm,
-+                    sitmp->digestAlgorithm->algorithm))
-+            continue;
-+        messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
-+                                                    OBJ_nid2obj
-+                                                    (NID_pkcs9_messageDigest),
-+                                                    -3, V_ASN1_OCTET_STRING);
-+        if (!messageDigest) {
-+            CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
-+                   CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
-+            return 0;
-+        }
-+
-+        if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
-+                                        V_ASN1_OCTET_STRING,
-+                                        messageDigest, -1))
-+            return 1;
-+        else
-+            return 0;
-+    }
-+    CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
-+    return 0;
-+}
-+
-+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
-+{
-+    switch (type) {
-+    case CMS_SIGNERINFO_ISSUER_SERIAL:
-+        if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert))
-+            return 0;
-+        break;
-+
-+    case CMS_SIGNERINFO_KEYIDENTIFIER:
-+        if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert))
-+            return 0;
-+        break;
-+
-+    default:
-+        CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
-+        return 0;
-+    }
-+
-+    sid->type = type;
-+
-+    return 1;
-+}
-+
-+int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
-+                                        ASN1_OCTET_STRING **keyid,
-+                                        X509_NAME **issuer,
-+                                        ASN1_INTEGER **sno)
-+{
-+    if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
-+        if (issuer)
-+            *issuer = sid->d.issuerAndSerialNumber->issuer;
-+        if (sno)
-+            *sno = sid->d.issuerAndSerialNumber->serialNumber;
-+    } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
-+        if (keyid)
-+            *keyid = sid->d.subjectKeyIdentifier;
-+    } else
-+        return 0;
-+    return 1;
-+}
-+
-+int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
-+{
-+    if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
-+        return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert);
-+    else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
-+        return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert);
-+    else
-+        return -1;
-+}
-+
-+static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
-+{
-+    EVP_PKEY *pkey = si->pkey;
-+    int i;
-+    if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
-+        return 1;
-+    i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
-+    if (i == -2) {
-+        CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
-+        return 0;
-+    }
-+    if (i <= 0) {
-+        CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_CTRL_FAILURE);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
-+                                X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
-+                                unsigned int flags)
-+{
-+    CMS_SignedData *sd;
-+    CMS_SignerInfo *si = NULL;
-+    X509_ALGOR *alg;
-+    int i, type;
-+    if (!X509_check_private_key(signer, pk)) {
-+        CMSerr(CMS_F_CMS_ADD1_SIGNER,
-+               CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
-+        return NULL;
-+    }
-+    sd = cms_signed_data_init(cms);
-+    if (!sd)
-+        goto err;
-+    si = M_ASN1_new_of(CMS_SignerInfo);
-+    if (!si)
-+        goto merr;
-+    /* Call for side-effect of computing hash and caching extensions */
-+    X509_check_purpose(signer, -1, -1);
-+
-+    X509_up_ref(signer);
-+    EVP_PKEY_up_ref(pk);
-+
-+    si->pkey = pk;
-+    si->signer = signer;
-+    si->mctx = EVP_MD_CTX_new();
-+    si->pctx = NULL;
-+
-+    if (si->mctx == NULL) {
-+        CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (flags & CMS_USE_KEYID) {
-+        si->version = 3;
-+        if (sd->version < 3)
-+            sd->version = 3;
-+        type = CMS_SIGNERINFO_KEYIDENTIFIER;
-+    } else {
-+        type = CMS_SIGNERINFO_ISSUER_SERIAL;
-+        si->version = 1;
-+    }
-+
-+    if (!cms_set1_SignerIdentifier(si->sid, signer, type))
-+        goto err;
-+
-+    if (md == NULL) {
-+        int def_nid;
-+        if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
-+            goto err;
-+        md = EVP_get_digestbynid(def_nid);
-+        if (md == NULL) {
-+            CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
-+            goto err;
-+        }
-+    }
-+
-+    if (!md) {
-+        CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
-+        goto err;
-+    }
-+
-+    X509_ALGOR_set_md(si->digestAlgorithm, md);
-+
-+    /* See if digest is present in digestAlgorithms */
-+    for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
-+        const ASN1_OBJECT *aoid;
-+        alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
-+        X509_ALGOR_get0(&aoid, NULL, NULL, alg);
-+        if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
-+            break;
-+    }
-+
-+    if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
-+        alg = X509_ALGOR_new();
-+        if (alg == NULL)
-+            goto merr;
-+        X509_ALGOR_set_md(alg, md);
-+        if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) {
-+            X509_ALGOR_free(alg);
-+            goto merr;
-+        }
-+    }
-+
-+    if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0))
-+        goto err;
-+    if (!(flags & CMS_NOATTR)) {
-+        /*
-+         * Initialize signed attributes structure so other attributes
-+         * such as signing time etc are added later even if we add none here.
-+         */
-+        if (!si->signedAttrs) {
-+            si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
-+            if (!si->signedAttrs)
-+                goto merr;
-+        }
-+
-+        if (!(flags & CMS_NOSMIMECAP)) {
-+            STACK_OF(X509_ALGOR) *smcap = NULL;
-+            i = CMS_add_standard_smimecap(&smcap);
-+            if (i)
-+                i = CMS_add_smimecap(si, smcap);
-+            sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
-+            if (!i)
-+                goto merr;
-+        }
-+        if (flags & CMS_REUSE_DIGEST) {
-+            if (!cms_copy_messageDigest(cms, si))
-+                goto err;
-+            if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
-+                !CMS_SignerInfo_sign(si))
-+                goto err;
-+        }
-+    }
-+
-+    if (!(flags & CMS_NOCERTS)) {
-+        /* NB ignore -1 return for duplicate cert */
-+        if (!CMS_add1_cert(cms, signer))
-+            goto merr;
-+    }
-+
-+    if (flags & CMS_KEY_PARAM) {
-+        if (flags & CMS_NOATTR) {
-+            si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
-+            if (si->pctx == NULL)
-+                goto err;
-+            if (EVP_PKEY_sign_init(si->pctx) <= 0)
-+                goto err;
-+            if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
-+                goto err;
-+        } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <=
-+                   0)
-+            goto err;
-+    }
-+
-+    if (!sd->signerInfos)
-+        sd->signerInfos = sk_CMS_SignerInfo_new_null();
-+    if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si))
-+        goto merr;
-+
-+    return si;
-+
-+ merr:
-+    CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
-+ err:
-+    M_ASN1_free_of(si, CMS_SignerInfo);
-+    return NULL;
-+
-+}
-+
-+static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
-+{
-+    ASN1_TIME *tt;
-+    int r = 0;
-+    if (t)
-+        tt = t;
-+    else
-+        tt = X509_gmtime_adj(NULL, 0);
-+
-+    if (!tt)
-+        goto merr;
-+
-+    if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
-+                                    tt->type, tt, -1) <= 0)
-+        goto merr;
-+
-+    r = 1;
-+
-+ merr:
-+
-+    if (!t)
-+        ASN1_TIME_free(tt);
-+
-+    if (!r)
-+        CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
-+
-+    return r;
-+
-+}
-+
-+EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si)
-+{
-+    return si->pctx;
-+}
-+
-+EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
-+{
-+    return si->mctx;
-+}
-+
-+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
-+{
-+    CMS_SignedData *sd;
-+    sd = cms_get0_signed(cms);
-+    if (!sd)
-+        return NULL;
-+    return sd->signerInfos;
-+}
-+
-+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
-+{
-+    STACK_OF(X509) *signers = NULL;
-+    STACK_OF(CMS_SignerInfo) *sinfos;
-+    CMS_SignerInfo *si;
-+    int i;
-+    sinfos = CMS_get0_SignerInfos(cms);
-+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
-+        si = sk_CMS_SignerInfo_value(sinfos, i);
-+        if (si->signer) {
-+            if (!signers) {
-+                signers = sk_X509_new_null();
-+                if (!signers)
-+                    return NULL;
-+            }
-+            if (!sk_X509_push(signers, si->signer)) {
-+                sk_X509_free(signers);
-+                return NULL;
-+            }
-+        }
-+    }
-+    return signers;
-+}
-+
-+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
-+{
-+    if (signer) {
-+        X509_up_ref(signer);
-+        EVP_PKEY_free(si->pkey);
-+        si->pkey = X509_get_pubkey(signer);
-+    }
-+    X509_free(si->signer);
-+    si->signer = signer;
-+}
-+
-+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
-+                                  ASN1_OCTET_STRING **keyid,
-+                                  X509_NAME **issuer, ASN1_INTEGER **sno)
-+{
-+    return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
-+}
-+
-+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
-+{
-+    return cms_SignerIdentifier_cert_cmp(si->sid, cert);
-+}
-+
-+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
-+                           unsigned int flags)
-+{
-+    CMS_SignedData *sd;
-+    CMS_SignerInfo *si;
-+    CMS_CertificateChoices *cch;
-+    STACK_OF(CMS_CertificateChoices) *certs;
-+    X509 *x;
-+    int i, j;
-+    int ret = 0;
-+    sd = cms_get0_signed(cms);
-+    if (!sd)
-+        return -1;
-+    certs = sd->certificates;
-+    for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
-+        si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
-+        if (si->signer)
-+            continue;
-+
-+        for (j = 0; j < sk_X509_num(scerts); j++) {
-+            x = sk_X509_value(scerts, j);
-+            if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
-+                CMS_SignerInfo_set1_signer_cert(si, x);
-+                ret++;
-+                break;
-+            }
-+        }
-+
-+        if (si->signer || (flags & CMS_NOINTERN))
-+            continue;
-+
-+        for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
-+            cch = sk_CMS_CertificateChoices_value(certs, j);
-+            if (cch->type != 0)
-+                continue;
-+            x = cch->d.certificate;
-+            if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
-+                CMS_SignerInfo_set1_signer_cert(si, x);
-+                ret++;
-+                break;
-+            }
-+        }
-+    }
-+    return ret;
-+}
-+
-+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
-+                              X509 **signer, X509_ALGOR **pdig,
-+                              X509_ALGOR **psig)
-+{
-+    if (pk)
-+        *pk = si->pkey;
-+    if (signer)
-+        *signer = si->signer;
-+    if (pdig)
-+        *pdig = si->digestAlgorithm;
-+    if (psig)
-+        *psig = si->signatureAlgorithm;
-+}
-+
-+ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si)
-+{
-+    return si->signature;
-+}
-+
-+static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
-+                                       CMS_SignerInfo *si, BIO *chain)
-+{
-+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-+    int r = 0;
-+    EVP_PKEY_CTX *pctx = NULL;
-+
-+    if (mctx == NULL) {
-+        CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    if (!si->pkey) {
-+        CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
-+        goto err;
-+    }
-+
-+    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
-+        goto err;
-+    /* Set SignerInfo algorithm details if we used custom parameter */
-+    if (si->pctx && !cms_sd_asn1_ctrl(si, 0))
-+        goto err;
-+
-+    /*
-+     * If any signed attributes calculate and add messageDigest attribute
-+     */
-+
-+    if (CMS_signed_get_attr_count(si) >= 0) {
-+        ASN1_OBJECT *ctype =
-+            cms->d.signedData->encapContentInfo->eContentType;
-+        unsigned char md[EVP_MAX_MD_SIZE];
-+        unsigned int mdlen;
-+        if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
-+            goto err;
-+        if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
-+                                         V_ASN1_OCTET_STRING, md, mdlen))
-+            goto err;
-+        /* Copy content type across */
-+        if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
-+                                        V_ASN1_OBJECT, ctype, -1) <= 0)
-+            goto err;
-+        if (!CMS_SignerInfo_sign(si))
-+            goto err;
-+    } else if (si->pctx) {
-+        unsigned char *sig;
-+        size_t siglen;
-+        unsigned char md[EVP_MAX_MD_SIZE];
-+        unsigned int mdlen;
-+        pctx = si->pctx;
-+        if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
-+            goto err;
-+        siglen = EVP_PKEY_size(si->pkey);
-+        sig = OPENSSL_malloc(siglen);
-+        if (sig == NULL) {
-+            CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) {
-+            OPENSSL_free(sig);
-+            goto err;
-+        }
-+        ASN1_STRING_set0(si->signature, sig, siglen);
-+    } else {
-+        unsigned char *sig;
-+        unsigned int siglen;
-+        sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
-+        if (sig == NULL) {
-+            CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) {
-+            CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR);
-+            OPENSSL_free(sig);
-+            goto err;
-+        }
-+        ASN1_STRING_set0(si->signature, sig, siglen);
-+    }
-+
-+    r = 1;
-+
-+ err:
-+    EVP_MD_CTX_free(mctx);
-+    EVP_PKEY_CTX_free(pctx);
-+    return r;
-+
-+}
-+
-+int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
-+{
-+    STACK_OF(CMS_SignerInfo) *sinfos;
-+    CMS_SignerInfo *si;
-+    int i;
-+    sinfos = CMS_get0_SignerInfos(cms);
-+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
-+        si = sk_CMS_SignerInfo_value(sinfos, i);
-+        if (!cms_SignerInfo_content_sign(cms, si, chain))
-+            return 0;
-+    }
-+    cms->d.signedData->encapContentInfo->partial = 0;
-+    return 1;
-+}
-+
-+int CMS_SignerInfo_sign(CMS_SignerInfo *si)
-+{
-+    EVP_MD_CTX *mctx = si->mctx;
-+    EVP_PKEY_CTX *pctx;
-+    unsigned char *abuf = NULL;
-+    int alen;
-+    size_t siglen;
-+    const EVP_MD *md = NULL;
-+
-+    md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
-+    if (md == NULL)
-+        return 0;
-+
-+    if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
-+        if (!cms_add1_signingTime(si, NULL))
-+            goto err;
-+    }
-+
-+    if (si->pctx)
-+        pctx = si->pctx;
-+    else {
-+        EVP_MD_CTX_reset(mctx);
-+        if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
-+            goto err;
-+    }
-+
-+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
-+                          EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) {
-+        CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
-+        goto err;
-+    }
-+
-+    alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
-+                         ASN1_ITEM_rptr(CMS_Attributes_Sign));
-+    if (!abuf)
-+        goto err;
-+    if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
-+        goto err;
-+    if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
-+        goto err;
-+    OPENSSL_free(abuf);
-+    abuf = OPENSSL_malloc(siglen);
-+    if (abuf == NULL)
-+        goto err;
-+    if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
-+                          EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) {
-+        CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
-+        goto err;
-+    }
-+
-+    EVP_MD_CTX_reset(mctx);
-+
-+    ASN1_STRING_set0(si->signature, abuf, siglen);
-+
-+    return 1;
-+
-+ err:
-+    OPENSSL_free(abuf);
-+    EVP_MD_CTX_reset(mctx);
-+    return 0;
-+
-+}
-+
-+int CMS_SignerInfo_verify(CMS_SignerInfo *si)
-+{
-+    EVP_MD_CTX *mctx = NULL;
-+    unsigned char *abuf = NULL;
-+    int alen, r = -1;
-+    const EVP_MD *md = NULL;
-+
-+    if (!si->pkey) {
-+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
-+        return -1;
-+    }
-+
-+    md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
-+    if (md == NULL)
-+        return -1;
-+    if (si->mctx == NULL)
-+        si->mctx = EVP_MD_CTX_new();
-+    mctx = si->mctx;
-+    if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
-+        goto err;
-+
-+    if (!cms_sd_asn1_ctrl(si, 1))
-+        goto err;
-+
-+    alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
-+                         ASN1_ITEM_rptr(CMS_Attributes_Verify));
-+    if (!abuf)
-+        goto err;
-+    r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
-+    OPENSSL_free(abuf);
-+    if (r <= 0) {
-+        r = -1;
-+        goto err;
-+    }
-+    r = EVP_DigestVerifyFinal(mctx,
-+                              si->signature->data, si->signature->length);
-+    if (r <= 0)
-+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
-+ err:
-+    EVP_MD_CTX_reset(mctx);
-+    return r;
-+}
-+
-+/* Create a chain of digest BIOs from a CMS ContentInfo */
-+
-+BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
-+{
-+    int i;
-+    CMS_SignedData *sd;
-+    BIO *chain = NULL;
-+    sd = cms_get0_signed(cms);
-+    if (!sd)
-+        return NULL;
-+    if (cms->d.signedData->encapContentInfo->partial)
-+        cms_sd_set_version(sd);
-+    for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
-+        X509_ALGOR *digestAlgorithm;
-+        BIO *mdbio;
-+        digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
-+        mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
-+        if (!mdbio)
-+            goto err;
-+        if (chain)
-+            BIO_push(chain, mdbio);
-+        else
-+            chain = mdbio;
-+    }
-+    return chain;
-+ err:
-+    BIO_free_all(chain);
-+    return NULL;
-+}
-+
-+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
-+{
-+    ASN1_OCTET_STRING *os = NULL;
-+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-+    EVP_PKEY_CTX *pkctx = NULL;
-+    int r = -1;
-+    unsigned char mval[EVP_MAX_MD_SIZE];
-+    unsigned int mlen;
-+
-+    if (mctx == NULL) {
-+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    /* If we have any signed attributes look for messageDigest value */
-+    if (CMS_signed_get_attr_count(si) >= 0) {
-+        os = CMS_signed_get0_data_by_OBJ(si,
-+                                         OBJ_nid2obj(NID_pkcs9_messageDigest),
-+                                         -3, V_ASN1_OCTET_STRING);
-+        if (!os) {
-+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
-+                   CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
-+            goto err;
-+        }
-+    }
-+
-+    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
-+        goto err;
-+
-+    if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) {
-+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
-+               CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
-+        goto err;
-+    }
-+
-+    /* If messageDigest found compare it */
-+
-+    if (os) {
-+        if (mlen != (unsigned int)os->length) {
-+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
-+                   CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
-+            goto err;
-+        }
-+
-+        if (memcmp(mval, os->data, mlen)) {
-+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
-+                   CMS_R_VERIFICATION_FAILURE);
-+            r = 0;
-+        } else
-+            r = 1;
-+    } else {
-+        const EVP_MD *md = EVP_MD_CTX_md(mctx);
-+        pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
-+        if (pkctx == NULL)
-+            goto err;
-+        if (EVP_PKEY_verify_init(pkctx) <= 0)
-+            goto err;
-+        if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
-+            goto err;
-+        si->pctx = pkctx;
-+        if (!cms_sd_asn1_ctrl(si, 1))
-+            goto err;
-+        r = EVP_PKEY_verify(pkctx, si->signature->data,
-+                            si->signature->length, mval, mlen);
-+        if (r <= 0) {
-+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
-+                   CMS_R_VERIFICATION_FAILURE);
-+            r = 0;
-+        }
-+    }
-+
-+ err:
-+    EVP_PKEY_CTX_free(pkctx);
-+    EVP_MD_CTX_free(mctx);
-+    return r;
-+
-+}
-+
-+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
-+{
-+    unsigned char *smder = NULL;
-+    int smderlen, r;
-+    smderlen = i2d_X509_ALGORS(algs, &smder);
-+    if (smderlen <= 0)
-+        return 0;
-+    r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
-+                                    V_ASN1_SEQUENCE, smder, smderlen);
-+    OPENSSL_free(smder);
-+    return r;
-+}
-+
-+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
-+                            int algnid, int keysize)
-+{
-+    X509_ALGOR *alg;
-+    ASN1_INTEGER *key = NULL;
-+    if (keysize > 0) {
-+        key = ASN1_INTEGER_new();
-+        if (key == NULL || !ASN1_INTEGER_set(key, keysize))
-+            return 0;
-+    }
-+    alg = X509_ALGOR_new();
-+    if (alg == NULL) {
-+        ASN1_INTEGER_free(key);
-+        return 0;
-+    }
-+
-+    X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
-+                    key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
-+    if (*algs == NULL)
-+        *algs = sk_X509_ALGOR_new_null();
-+    if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) {
-+        X509_ALGOR_free(alg);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+/* Check to see if a cipher exists and if so add S/MIME capabilities */
-+
-+static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
-+{
-+    if (EVP_get_cipherbynid(nid))
-+        return CMS_add_simple_smimecap(sk, nid, arg);
-+    return 1;
-+}
-+
-+static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
-+{
-+    if (EVP_get_digestbynid(nid))
-+        return CMS_add_simple_smimecap(sk, nid, arg);
-+    return 1;
-+}
-+
-+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
-+{
-+    if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
-+        || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1)
-+        || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1)
-+        || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
-+        || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
-+        || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
-+        || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
-+        || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
-+        || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
-+        || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
-+        || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
-+        || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
-+        return 0;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_smime.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_smime.c
-new file mode 100644
-index 0000000..dbf7dd3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cms/cms_smime.c
-@@ -0,0 +1,844 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "cms_lcl.h"
-+#include "internal/asn1_int.h"
-+
-+static BIO *cms_get_text_bio(BIO *out, unsigned int flags)
-+{
-+    BIO *rbio;
-+    if (out == NULL)
-+        rbio = BIO_new(BIO_s_null());
-+    else if (flags & CMS_TEXT) {
-+        rbio = BIO_new(BIO_s_mem());
-+        BIO_set_mem_eof_return(rbio, 0);
-+    } else
-+        rbio = out;
-+    return rbio;
-+}
-+
-+static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
-+{
-+    unsigned char buf[4096];
-+    int r = 0, i;
-+    BIO *tmpout;
-+
-+    tmpout = cms_get_text_bio(out, flags);
-+
-+    if (tmpout == NULL) {
-+        CMSerr(CMS_F_CMS_COPY_CONTENT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    /* Read all content through chain to process digest, decrypt etc */
-+    for (;;) {
-+        i = BIO_read(in, buf, sizeof(buf));
-+        if (i <= 0) {
-+            if (BIO_method_type(in) == BIO_TYPE_CIPHER) {
-+                if (!BIO_get_cipher_status(in))
-+                    goto err;
-+            }
-+            if (i < 0)
-+                goto err;
-+            break;
-+        }
-+
-+        if (tmpout && (BIO_write(tmpout, buf, i) != i))
-+            goto err;
-+    }
-+
-+    if (flags & CMS_TEXT) {
-+        if (!SMIME_text(tmpout, out)) {
-+            CMSerr(CMS_F_CMS_COPY_CONTENT, CMS_R_SMIME_TEXT_ERROR);
-+            goto err;
-+        }
-+    }
-+
-+    r = 1;
-+
-+ err:
-+    if (tmpout != out)
-+        BIO_free(tmpout);
-+    return r;
-+
-+}
-+
-+static int check_content(CMS_ContentInfo *cms)
-+{
-+    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
-+    if (!pos || !*pos) {
-+        CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+static void do_free_upto(BIO *f, BIO *upto)
-+{
-+    if (upto) {
-+        BIO *tbio;
-+        do {
-+            tbio = BIO_pop(f);
-+            BIO_free(f);
-+            f = tbio;
-+        }
-+        while (f && f != upto);
-+    } else
-+        BIO_free_all(f);
-+}
-+
-+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
-+{
-+    BIO *cont;
-+    int r;
-+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) {
-+        CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
-+        return 0;
-+    }
-+    cont = CMS_dataInit(cms, NULL);
-+    if (!cont)
-+        return 0;
-+    r = cms_copy_content(out, cont, flags);
-+    BIO_free_all(cont);
-+    return r;
-+}
-+
-+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
-+{
-+    CMS_ContentInfo *cms;
-+    cms = cms_Data_create();
-+    if (!cms)
-+        return NULL;
-+
-+    if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
-+        return cms;
-+
-+    CMS_ContentInfo_free(cms);
-+
-+    return NULL;
-+}
-+
-+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
-+                      unsigned int flags)
-+{
-+    BIO *cont;
-+    int r;
-+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) {
-+        CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
-+        return 0;
-+    }
-+
-+    if (!dcont && !check_content(cms))
-+        return 0;
-+
-+    cont = CMS_dataInit(cms, dcont);
-+    if (!cont)
-+        return 0;
-+    r = cms_copy_content(out, cont, flags);
-+    if (r)
-+        r = cms_DigestedData_do_final(cms, cont, 1);
-+    do_free_upto(cont, dcont);
-+    return r;
-+}
-+
-+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
-+                                   unsigned int flags)
-+{
-+    CMS_ContentInfo *cms;
-+    if (!md)
-+        md = EVP_sha1();
-+    cms = cms_DigestedData_create(md);
-+    if (!cms)
-+        return NULL;
-+
-+    if (!(flags & CMS_DETACHED))
-+        CMS_set_detached(cms, 0);
-+
-+    if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
-+        return cms;
-+
-+    CMS_ContentInfo_free(cms);
-+    return NULL;
-+}
-+
-+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
-+                              const unsigned char *key, size_t keylen,
-+                              BIO *dcont, BIO *out, unsigned int flags)
-+{
-+    BIO *cont;
-+    int r;
-+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) {
-+        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
-+               CMS_R_TYPE_NOT_ENCRYPTED_DATA);
-+        return 0;
-+    }
-+
-+    if (!dcont && !check_content(cms))
-+        return 0;
-+
-+    if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
-+        return 0;
-+    cont = CMS_dataInit(cms, dcont);
-+    if (!cont)
-+        return 0;
-+    r = cms_copy_content(out, cont, flags);
-+    do_free_upto(cont, dcont);
-+    return r;
-+}
-+
-+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
-+                                           const unsigned char *key,
-+                                           size_t keylen, unsigned int flags)
-+{
-+    CMS_ContentInfo *cms;
-+    if (!cipher) {
-+        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
-+        return NULL;
-+    }
-+    cms = CMS_ContentInfo_new();
-+    if (cms == NULL)
-+        return NULL;
-+    if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
-+        return NULL;
-+
-+    if (!(flags & CMS_DETACHED))
-+        CMS_set_detached(cms, 0);
-+
-+    if ((flags & (CMS_STREAM | CMS_PARTIAL))
-+        || CMS_final(cms, in, NULL, flags))
-+        return cms;
-+
-+    CMS_ContentInfo_free(cms);
-+    return NULL;
-+}
-+
-+static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
-+                                      X509_STORE *store,
-+                                      STACK_OF(X509) *certs,
-+                                      STACK_OF(X509_CRL) *crls)
-+{
-+    X509_STORE_CTX *ctx = X509_STORE_CTX_new();
-+    X509 *signer;
-+    int i, j, r = 0;
-+
-+    if (ctx == NULL) {
-+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
-+    if (!X509_STORE_CTX_init(ctx, store, signer, certs)) {
-+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR);
-+        goto err;
-+    }
-+    X509_STORE_CTX_set_default(ctx, "smime_sign");
-+    if (crls)
-+        X509_STORE_CTX_set0_crls(ctx, crls);
-+
-+    i = X509_verify_cert(ctx);
-+    if (i <= 0) {
-+        j = X509_STORE_CTX_get_error(ctx);
-+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
-+               CMS_R_CERTIFICATE_VERIFY_ERROR);
-+        ERR_add_error_data(2, "Verify error:",
-+                           X509_verify_cert_error_string(j));
-+        goto err;
-+    }
-+    r = 1;
-+ err:
-+    X509_STORE_CTX_free(ctx);
-+    return r;
-+
-+}
-+
-+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
-+               X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
-+{
-+    CMS_SignerInfo *si;
-+    STACK_OF(CMS_SignerInfo) *sinfos;
-+    STACK_OF(X509) *cms_certs = NULL;
-+    STACK_OF(X509_CRL) *crls = NULL;
-+    X509 *signer;
-+    int i, scount = 0, ret = 0;
-+    BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;
-+
-+    if (!dcont && !check_content(cms))
-+        return 0;
-+    if (dcont && !(flags & CMS_BINARY)) {
-+        const ASN1_OBJECT *coid = CMS_get0_eContentType(cms);
-+        if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF)
-+            flags |= CMS_ASCIICRLF;
-+    }
-+
-+    /* Attempt to find all signer certificates */
-+
-+    sinfos = CMS_get0_SignerInfos(cms);
-+
-+    if (sk_CMS_SignerInfo_num(sinfos) <= 0) {
-+        CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
-+        goto err;
-+    }
-+
-+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
-+        si = sk_CMS_SignerInfo_value(sinfos, i);
-+        CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
-+        if (signer)
-+            scount++;
-+    }
-+
-+    if (scount != sk_CMS_SignerInfo_num(sinfos))
-+        scount += CMS_set1_signers_certs(cms, certs, flags);
-+
-+    if (scount != sk_CMS_SignerInfo_num(sinfos)) {
-+        CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
-+        goto err;
-+    }
-+
-+    /* Attempt to verify all signers certs */
-+
-+    if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) {
-+        cms_certs = CMS_get1_certs(cms);
-+        if (!(flags & CMS_NOCRL))
-+            crls = CMS_get1_crls(cms);
-+        for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
-+            si = sk_CMS_SignerInfo_value(sinfos, i);
-+            if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls))
-+                goto err;
-+        }
-+    }
-+
-+    /* Attempt to verify all SignerInfo signed attribute signatures */
-+
-+    if (!(flags & CMS_NO_ATTR_VERIFY)) {
-+        for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
-+            si = sk_CMS_SignerInfo_value(sinfos, i);
-+            if (CMS_signed_get_attr_count(si) < 0)
-+                continue;
-+            if (CMS_SignerInfo_verify(si) <= 0)
-+                goto err;
-+        }
-+    }
-+
-+    /*
-+     * Performance optimization: if the content is a memory BIO then store
-+     * its contents in a temporary read only memory BIO. This avoids
-+     * potentially large numbers of slow copies of data which will occur when
-+     * reading from a read write memory BIO when signatures are calculated.
-+     */
-+
-+    if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
-+        char *ptr;
-+        long len;
-+        len = BIO_get_mem_data(dcont, &ptr);
-+        tmpin = BIO_new_mem_buf(ptr, len);
-+        if (tmpin == NULL) {
-+            CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
-+            goto err2;
-+        }
-+    } else
-+        tmpin = dcont;
-+    /*
-+     * If not binary mode and detached generate digests by *writing* through
-+     * the BIO. That makes it possible to canonicalise the input.
-+     */
-+    if (!(flags & SMIME_BINARY) && dcont) {
-+        /*
-+         * Create output BIO so we can either handle text or to ensure
-+         * included content doesn't override detached content.
-+         */
-+        tmpout = cms_get_text_bio(out, flags);
-+        if (!tmpout) {
-+            CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        cmsbio = CMS_dataInit(cms, tmpout);
-+        if (!cmsbio)
-+            goto err;
-+        /*
-+         * Don't use SMIME_TEXT for verify: it adds headers and we want to
-+         * remove them.
-+         */
-+        SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT);
-+
-+        if (flags & CMS_TEXT) {
-+            if (!SMIME_text(tmpout, out)) {
-+                CMSerr(CMS_F_CMS_VERIFY, CMS_R_SMIME_TEXT_ERROR);
-+                goto err;
-+            }
-+        }
-+    } else {
-+        cmsbio = CMS_dataInit(cms, tmpin);
-+        if (!cmsbio)
-+            goto err;
-+
-+        if (!cms_copy_content(out, cmsbio, flags))
-+            goto err;
-+
-+    }
-+    if (!(flags & CMS_NO_CONTENT_VERIFY)) {
-+        for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
-+            si = sk_CMS_SignerInfo_value(sinfos, i);
-+            if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) {
-+                CMSerr(CMS_F_CMS_VERIFY, CMS_R_CONTENT_VERIFY_ERROR);
-+                goto err;
-+            }
-+        }
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    if (!(flags & SMIME_BINARY) && dcont) {
-+        do_free_upto(cmsbio, tmpout);
-+        if (tmpin != dcont)
-+            BIO_free(tmpin);
-+    } else {
-+        if (dcont && (tmpin == dcont))
-+            do_free_upto(cmsbio, dcont);
-+        else
-+            BIO_free_all(cmsbio);
-+    }
-+
-+    if (out != tmpout)
-+        BIO_free_all(tmpout);
-+
-+ err2:
-+    sk_X509_pop_free(cms_certs, X509_free);
-+    sk_X509_CRL_pop_free(crls, X509_CRL_free);
-+
-+    return ret;
-+}
-+
-+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
-+                       STACK_OF(X509) *certs,
-+                       X509_STORE *store, unsigned int flags)
-+{
-+    int r;
-+    flags &= ~(CMS_DETACHED | CMS_TEXT);
-+    r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
-+    if (r <= 0)
-+        return r;
-+    return cms_Receipt_verify(rcms, ocms);
-+}
-+
-+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
-+                          STACK_OF(X509) *certs, BIO *data,
-+                          unsigned int flags)
-+{
-+    CMS_ContentInfo *cms;
-+    int i;
-+
-+    cms = CMS_ContentInfo_new();
-+    if (cms == NULL || !CMS_SignedData_init(cms))
-+        goto merr;
-+    if (flags & CMS_ASCIICRLF
-+        && !CMS_set1_eContentType(cms,
-+                                  OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF)))
-+        goto err;
-+
-+    if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
-+        CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
-+        goto err;
-+    }
-+
-+    for (i = 0; i < sk_X509_num(certs); i++) {
-+        X509 *x = sk_X509_value(certs, i);
-+        if (!CMS_add1_cert(cms, x))
-+            goto merr;
-+    }
-+
-+    if (!(flags & CMS_DETACHED))
-+        CMS_set_detached(cms, 0);
-+
-+    if ((flags & (CMS_STREAM | CMS_PARTIAL))
-+        || CMS_final(cms, data, NULL, flags))
-+        return cms;
-+    else
-+        goto err;
-+
-+ merr:
-+    CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
-+
-+ err:
-+    CMS_ContentInfo_free(cms);
-+    return NULL;
-+}
-+
-+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
-+                                  X509 *signcert, EVP_PKEY *pkey,
-+                                  STACK_OF(X509) *certs, unsigned int flags)
-+{
-+    CMS_SignerInfo *rct_si;
-+    CMS_ContentInfo *cms = NULL;
-+    ASN1_OCTET_STRING **pos, *os;
-+    BIO *rct_cont = NULL;
-+    int r = 0;
-+
-+    flags &= ~(CMS_STREAM | CMS_TEXT);
-+    /* Not really detached but avoids content being allocated */
-+    flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED;
-+    if (!pkey || !signcert) {
-+        CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
-+        return NULL;
-+    }
-+
-+    /* Initialize signed data */
-+
-+    cms = CMS_sign(NULL, NULL, certs, NULL, flags);
-+    if (!cms)
-+        goto err;
-+
-+    /* Set inner content type to signed receipt */
-+    if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
-+        goto err;
-+
-+    rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
-+    if (!rct_si) {
-+        CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
-+        goto err;
-+    }
-+
-+    os = cms_encode_Receipt(si);
-+
-+    if (!os)
-+        goto err;
-+
-+    /* Set content to digest */
-+    rct_cont = BIO_new_mem_buf(os->data, os->length);
-+    if (!rct_cont)
-+        goto err;
-+
-+    /* Add msgSigDigest attribute */
-+
-+    if (!cms_msgSigDigest_add1(rct_si, si))
-+        goto err;
-+
-+    /* Finalize structure */
-+    if (!CMS_final(cms, rct_cont, NULL, flags))
-+        goto err;
-+
-+    /* Set embedded content */
-+    pos = CMS_get0_content(cms);
-+    *pos = os;
-+
-+    r = 1;
-+
-+ err:
-+    BIO_free(rct_cont);
-+    if (r)
-+        return cms;
-+    CMS_ContentInfo_free(cms);
-+    return NULL;
-+
-+}
-+
-+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
-+                             const EVP_CIPHER *cipher, unsigned int flags)
-+{
-+    CMS_ContentInfo *cms;
-+    int i;
-+    X509 *recip;
-+    cms = CMS_EnvelopedData_create(cipher);
-+    if (!cms)
-+        goto merr;
-+    for (i = 0; i < sk_X509_num(certs); i++) {
-+        recip = sk_X509_value(certs, i);
-+        if (!CMS_add1_recipient_cert(cms, recip, flags)) {
-+            CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
-+            goto err;
-+        }
-+    }
-+
-+    if (!(flags & CMS_DETACHED))
-+        CMS_set_detached(cms, 0);
-+
-+    if ((flags & (CMS_STREAM | CMS_PARTIAL))
-+        || CMS_final(cms, data, NULL, flags))
-+        return cms;
-+    else
-+        goto err;
-+
-+ merr:
-+    CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+ err:
-+    CMS_ContentInfo_free(cms);
-+    return NULL;
-+}
-+
-+static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
-+                              EVP_PKEY *pk, X509 *cert)
-+{
-+    int i;
-+    STACK_OF(CMS_RecipientEncryptedKey) *reks;
-+    CMS_RecipientEncryptedKey *rek;
-+    reks = CMS_RecipientInfo_kari_get0_reks(ri);
-+    if (!cert)
-+        return 0;
-+    for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
-+        int rv;
-+        rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
-+        if (CMS_RecipientEncryptedKey_cert_cmp(rek, cert))
-+            continue;
-+        CMS_RecipientInfo_kari_set0_pkey(ri, pk);
-+        rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek);
-+        CMS_RecipientInfo_kari_set0_pkey(ri, NULL);
-+        if (rv > 0)
-+            return 1;
-+        return -1;
-+    }
-+    return 0;
-+}
-+
-+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
-+{
-+    STACK_OF(CMS_RecipientInfo) *ris;
-+    CMS_RecipientInfo *ri;
-+    int i, r, ri_type;
-+    int debug = 0, match_ri = 0;
-+    ris = CMS_get0_RecipientInfos(cms);
-+    if (ris)
-+        debug = cms->d.envelopedData->encryptedContentInfo->debug;
-+    ri_type = cms_pkey_get_ri_type(pk);
-+    if (ri_type == CMS_RECIPINFO_NONE) {
-+        CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
-+               CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
-+        return 0;
-+    }
-+
-+    for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
-+        ri = sk_CMS_RecipientInfo_value(ris, i);
-+        if (CMS_RecipientInfo_type(ri) != ri_type)
-+            continue;
-+        match_ri = 1;
-+        if (ri_type == CMS_RECIPINFO_AGREE) {
-+            r = cms_kari_set1_pkey(cms, ri, pk, cert);
-+            if (r > 0)
-+                return 1;
-+            if (r < 0)
-+                return 0;
-+        }
-+        /*
-+         * If we have a cert try matching RecipientInfo otherwise try them
-+         * all.
-+         */
-+        else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
-+            CMS_RecipientInfo_set0_pkey(ri, pk);
-+            r = CMS_RecipientInfo_decrypt(cms, ri);
-+            CMS_RecipientInfo_set0_pkey(ri, NULL);
-+            if (cert) {
-+                /*
-+                 * If not debugging clear any error and return success to
-+                 * avoid leaking of information useful to MMA
-+                 */
-+                if (!debug) {
-+                    ERR_clear_error();
-+                    return 1;
-+                }
-+                if (r > 0)
-+                    return 1;
-+                CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR);
-+                return 0;
-+            }
-+            /*
-+             * If no cert and not debugging don't leave loop after first
-+             * successful decrypt. Always attempt to decrypt all recipients
-+             * to avoid leaking timing of a successful decrypt.
-+             */
-+            else if (r > 0 && debug)
-+                return 1;
-+        }
-+    }
-+    /* If no cert and not debugging always return success */
-+    if (match_ri && !cert && !debug) {
-+        ERR_clear_error();
-+        return 1;
-+    }
-+
-+    CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
-+    return 0;
-+
-+}
-+
-+int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
-+                         unsigned char *key, size_t keylen,
-+                         const unsigned char *id, size_t idlen)
-+{
-+    STACK_OF(CMS_RecipientInfo) *ris;
-+    CMS_RecipientInfo *ri;
-+    int i, r;
-+    ris = CMS_get0_RecipientInfos(cms);
-+    for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
-+        ri = sk_CMS_RecipientInfo_value(ris, i);
-+        if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
-+            continue;
-+
-+        /*
-+         * If we have an id try matching RecipientInfo otherwise try them
-+         * all.
-+         */
-+        if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
-+            CMS_RecipientInfo_set0_key(ri, key, keylen);
-+            r = CMS_RecipientInfo_decrypt(cms, ri);
-+            CMS_RecipientInfo_set0_key(ri, NULL, 0);
-+            if (r > 0)
-+                return 1;
-+            if (id) {
-+                CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR);
-+                return 0;
-+            }
-+            ERR_clear_error();
-+        }
-+    }
-+
-+    CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
-+    return 0;
-+
-+}
-+
-+int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
-+                              unsigned char *pass, ossl_ssize_t passlen)
-+{
-+    STACK_OF(CMS_RecipientInfo) *ris;
-+    CMS_RecipientInfo *ri;
-+    int i, r;
-+    ris = CMS_get0_RecipientInfos(cms);
-+    for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
-+        ri = sk_CMS_RecipientInfo_value(ris, i);
-+        if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
-+            continue;
-+        CMS_RecipientInfo_set0_password(ri, pass, passlen);
-+        r = CMS_RecipientInfo_decrypt(cms, ri);
-+        CMS_RecipientInfo_set0_password(ri, NULL, 0);
-+        if (r > 0)
-+            return 1;
-+    }
-+
-+    CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT);
-+    return 0;
-+
-+}
-+
-+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
-+                BIO *dcont, BIO *out, unsigned int flags)
-+{
-+    int r;
-+    BIO *cont;
-+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) {
-+        CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
-+        return 0;
-+    }
-+    if (!dcont && !check_content(cms))
-+        return 0;
-+    if (flags & CMS_DEBUG_DECRYPT)
-+        cms->d.envelopedData->encryptedContentInfo->debug = 1;
-+    else
-+        cms->d.envelopedData->encryptedContentInfo->debug = 0;
-+    if (!pk && !cert && !dcont && !out)
-+        return 1;
-+    if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
-+        return 0;
-+    cont = CMS_dataInit(cms, dcont);
-+    if (!cont)
-+        return 0;
-+    r = cms_copy_content(out, cont, flags);
-+    do_free_upto(cont, dcont);
-+    return r;
-+}
-+
-+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
-+{
-+    BIO *cmsbio;
-+    int ret = 0;
-+
-+    if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) {
-+        CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_LIB);
-+        return 0;
-+    }
-+
-+    SMIME_crlf_copy(data, cmsbio, flags);
-+
-+    (void)BIO_flush(cmsbio);
-+
-+    if (!CMS_dataFinal(cms, cmsbio)) {
-+        CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR);
-+        goto err;
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    do_free_upto(cmsbio, dcont);
-+
-+    return ret;
-+
-+}
-+
-+#ifdef ZLIB
-+
-+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
-+                   unsigned int flags)
-+{
-+    BIO *cont;
-+    int r;
-+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) {
-+        CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA);
-+        return 0;
-+    }
-+
-+    if (!dcont && !check_content(cms))
-+        return 0;
-+
-+    cont = CMS_dataInit(cms, dcont);
-+    if (!cont)
-+        return 0;
-+    r = cms_copy_content(out, cont, flags);
-+    do_free_upto(cont, dcont);
-+    return r;
-+}
-+
-+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
-+{
-+    CMS_ContentInfo *cms;
-+    if (comp_nid <= 0)
-+        comp_nid = NID_zlib_compression;
-+    cms = cms_CompressedData_create(comp_nid);
-+    if (!cms)
-+        return NULL;
-+
-+    if (!(flags & CMS_DETACHED))
-+        CMS_set_detached(cms, 0);
-+
-+    if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
-+        return cms;
-+
-+    CMS_ContentInfo_free(cms);
-+    return NULL;
-+}
-+
-+#else
-+
-+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
-+                   unsigned int flags)
-+{
-+    CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
-+    return 0;
-+}
-+
-+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
-+{
-+    CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
-+    return NULL;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/build.info
-new file mode 100644
-index 0000000..65df46a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/build.info
-@@ -0,0 +1,4 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]= \
-+        comp_lib.c comp_err.c \
-+        c_zlib.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/c_zlib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/c_zlib.c
-new file mode 100644
-index 0000000..2f38c2e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/c_zlib.c
-@@ -0,0 +1,615 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/comp.h"
-+#include 
-+#include "internal/cryptlib_int.h"
-+#include "internal/bio.h"
-+#include "comp_lcl.h"
-+
-+COMP_METHOD *COMP_zlib(void);
-+
-+static COMP_METHOD zlib_method_nozlib = {
-+    NID_undef,
-+    "(undef)",
-+    NULL,
-+    NULL,
-+    NULL,
-+    NULL,
-+};
-+
-+#ifndef ZLIB
-+# undef ZLIB_SHARED
-+#else
-+
-+# include 
-+
-+static int zlib_stateful_init(COMP_CTX *ctx);
-+static void zlib_stateful_finish(COMP_CTX *ctx);
-+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
-+                                        unsigned int olen, unsigned char *in,
-+                                        unsigned int ilen);
-+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
-+                                      unsigned int olen, unsigned char *in,
-+                                      unsigned int ilen);
-+
-+/* memory allocations functions for zlib initialisation */
-+static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size)
-+{
-+    void *p;
-+
-+    p = OPENSSL_zalloc(no * size);
-+    return p;
-+}
-+
-+static void zlib_zfree(void *opaque, void *address)
-+{
-+    OPENSSL_free(address);
-+}
-+
-+
-+static COMP_METHOD zlib_stateful_method = {
-+    NID_zlib_compression,
-+    LN_zlib_compression,
-+    zlib_stateful_init,
-+    zlib_stateful_finish,
-+    zlib_stateful_compress_block,
-+    zlib_stateful_expand_block
-+};
-+
-+/*
-+ * When OpenSSL is built on Windows, we do not want to require that
-+ * the ZLIB.DLL be available in order for the OpenSSL DLLs to
-+ * work.  Therefore, all ZLIB routines are loaded at run time
-+ * and we do not link to a .LIB file when ZLIB_SHARED is set.
-+ */
-+# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
-+#  include 
-+# endif                         /* !(OPENSSL_SYS_WINDOWS ||
-+                                 * OPENSSL_SYS_WIN32) */
-+
-+# ifdef ZLIB_SHARED
-+#  include "internal/dso.h"
-+
-+/* Function pointers */
-+typedef int (*compress_ft) (Bytef *dest, uLongf * destLen,
-+                            const Bytef *source, uLong sourceLen);
-+typedef int (*inflateEnd_ft) (z_streamp strm);
-+typedef int (*inflate_ft) (z_streamp strm, int flush);
-+typedef int (*inflateInit__ft) (z_streamp strm,
-+                                const char *version, int stream_size);
-+typedef int (*deflateEnd_ft) (z_streamp strm);
-+typedef int (*deflate_ft) (z_streamp strm, int flush);
-+typedef int (*deflateInit__ft) (z_streamp strm, int level,
-+                                const char *version, int stream_size);
-+typedef const char *(*zError__ft) (int err);
-+static compress_ft p_compress = NULL;
-+static inflateEnd_ft p_inflateEnd = NULL;
-+static inflate_ft p_inflate = NULL;
-+static inflateInit__ft p_inflateInit_ = NULL;
-+static deflateEnd_ft p_deflateEnd = NULL;
-+static deflate_ft p_deflate = NULL;
-+static deflateInit__ft p_deflateInit_ = NULL;
-+static zError__ft p_zError = NULL;
-+
-+static int zlib_loaded = 0;     /* only attempt to init func pts once */
-+static DSO *zlib_dso = NULL;
-+
-+#  define compress                p_compress
-+#  define inflateEnd              p_inflateEnd
-+#  define inflate                 p_inflate
-+#  define inflateInit_            p_inflateInit_
-+#  define deflateEnd              p_deflateEnd
-+#  define deflate                 p_deflate
-+#  define deflateInit_            p_deflateInit_
-+#  define zError                  p_zError
-+# endif                         /* ZLIB_SHARED */
-+
-+struct zlib_state {
-+    z_stream istream;
-+    z_stream ostream;
-+};
-+
-+static int zlib_stateful_init(COMP_CTX *ctx)
-+{
-+    int err;
-+    struct zlib_state *state = OPENSSL_zalloc(sizeof(*state));
-+
-+    if (state == NULL)
-+        goto err;
-+
-+    state->istream.zalloc = zlib_zalloc;
-+    state->istream.zfree = zlib_zfree;
-+    state->istream.opaque = Z_NULL;
-+    state->istream.next_in = Z_NULL;
-+    state->istream.next_out = Z_NULL;
-+    err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream));
-+    if (err != Z_OK)
-+        goto err;
-+
-+    state->ostream.zalloc = zlib_zalloc;
-+    state->ostream.zfree = zlib_zfree;
-+    state->ostream.opaque = Z_NULL;
-+    state->ostream.next_in = Z_NULL;
-+    state->ostream.next_out = Z_NULL;
-+    err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION,
-+                       ZLIB_VERSION, sizeof(z_stream));
-+    if (err != Z_OK)
-+        goto err;
-+
-+    ctx->data = state;
-+    return 1;
-+ err:
-+    OPENSSL_free(state);
-+    return 0;
-+}
-+
-+static void zlib_stateful_finish(COMP_CTX *ctx)
-+{
-+    struct zlib_state *state = ctx->data;
-+    inflateEnd(&state->istream);
-+    deflateEnd(&state->ostream);
-+    OPENSSL_free(state);
-+}
-+
-+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
-+                                        unsigned int olen, unsigned char *in,
-+                                        unsigned int ilen)
-+{
-+    int err = Z_OK;
-+    struct zlib_state *state = ctx->data;
-+
-+    if (state == NULL)
-+        return -1;
-+
-+    state->ostream.next_in = in;
-+    state->ostream.avail_in = ilen;
-+    state->ostream.next_out = out;
-+    state->ostream.avail_out = olen;
-+    if (ilen > 0)
-+        err = deflate(&state->ostream, Z_SYNC_FLUSH);
-+    if (err != Z_OK)
-+        return -1;
-+    return olen - state->ostream.avail_out;
-+}
-+
-+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
-+                                      unsigned int olen, unsigned char *in,
-+                                      unsigned int ilen)
-+{
-+    int err = Z_OK;
-+    struct zlib_state *state = ctx->data;
-+
-+    if (state == NULL)
-+        return 0;
-+
-+    state->istream.next_in = in;
-+    state->istream.avail_in = ilen;
-+    state->istream.next_out = out;
-+    state->istream.avail_out = olen;
-+    if (ilen > 0)
-+        err = inflate(&state->istream, Z_SYNC_FLUSH);
-+    if (err != Z_OK)
-+        return -1;
-+    return olen - state->istream.avail_out;
-+}
-+
-+#endif
-+
-+COMP_METHOD *COMP_zlib(void)
-+{
-+    COMP_METHOD *meth = &zlib_method_nozlib;
-+
-+#ifdef ZLIB_SHARED
-+    /* LIBZ may be externally defined, and we should respect that value */
-+# ifndef LIBZ
-+#  if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
-+#   define LIBZ "ZLIB1"
-+#  elif defined(OPENSSL_SYS_VMS)
-+#   define LIBZ "LIBZ"
-+#  else
-+#   define LIBZ "z"
-+#  endif
-+# endif
-+
-+    if (!zlib_loaded) {
-+        zlib_dso = DSO_load(NULL, LIBZ, NULL, 0);
-+        if (zlib_dso != NULL) {
-+            p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");
-+            p_inflateEnd
-+                = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");
-+            p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");
-+            p_inflateInit_
-+                = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");
-+            p_deflateEnd
-+                = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd");
-+            p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate");
-+            p_deflateInit_
-+                = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");
-+            p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");
-+
-+            if (p_compress && p_inflateEnd && p_inflate
-+                && p_inflateInit_ && p_deflateEnd
-+                && p_deflate && p_deflateInit_ && p_zError)
-+                zlib_loaded++;
-+
-+            if (!OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL)) {
-+                comp_zlib_cleanup_int();
-+                return meth;
-+            }
-+            if (zlib_loaded)
-+                meth = &zlib_stateful_method;
-+        }
-+    }
-+#endif
-+#if defined(ZLIB)
-+    meth = &zlib_stateful_method;
-+#endif
-+
-+    return (meth);
-+}
-+
-+void comp_zlib_cleanup_int(void)
-+{
-+#ifdef ZLIB_SHARED
-+    if (zlib_dso != NULL)
-+        DSO_free(zlib_dso);
-+    zlib_dso = NULL;
-+#endif
-+}
-+
-+#ifdef ZLIB
-+
-+/* Zlib based compression/decompression filter BIO */
-+
-+typedef struct {
-+    unsigned char *ibuf;        /* Input buffer */
-+    int ibufsize;               /* Buffer size */
-+    z_stream zin;               /* Input decompress context */
-+    unsigned char *obuf;        /* Output buffer */
-+    int obufsize;               /* Output buffer size */
-+    unsigned char *optr;        /* Position in output buffer */
-+    int ocount;                 /* Amount of data in output buffer */
-+    int odone;                  /* deflate EOF */
-+    int comp_level;             /* Compression level to use */
-+    z_stream zout;              /* Output compression context */
-+} BIO_ZLIB_CTX;
-+
-+# define ZLIB_DEFAULT_BUFSIZE 1024
-+
-+static int bio_zlib_new(BIO *bi);
-+static int bio_zlib_free(BIO *bi);
-+static int bio_zlib_read(BIO *b, char *out, int outl);
-+static int bio_zlib_write(BIO *b, const char *in, int inl);
-+static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
-+static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
-+
-+static const BIO_METHOD bio_meth_zlib = {
-+    BIO_TYPE_COMP,
-+    "zlib",
-+    bio_zlib_write,
-+    bio_zlib_read,
-+    NULL,
-+    NULL,
-+    bio_zlib_ctrl,
-+    bio_zlib_new,
-+    bio_zlib_free,
-+    bio_zlib_callback_ctrl
-+};
-+
-+const BIO_METHOD *BIO_f_zlib(void)
-+{
-+    return &bio_meth_zlib;
-+}
-+
-+static int bio_zlib_new(BIO *bi)
-+{
-+    BIO_ZLIB_CTX *ctx;
-+# ifdef ZLIB_SHARED
-+    (void)COMP_zlib();
-+    if (!zlib_loaded) {
-+        COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);
-+        return 0;
-+    }
-+# endif
-+    ctx = OPENSSL_zalloc(sizeof(*ctx));
-+    if (ctx == NULL) {
-+        COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
-+    ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
-+    ctx->zin.zalloc = Z_NULL;
-+    ctx->zin.zfree = Z_NULL;
-+    ctx->zout.zalloc = Z_NULL;
-+    ctx->zout.zfree = Z_NULL;
-+    ctx->comp_level = Z_DEFAULT_COMPRESSION;
-+    BIO_set_init(bi, 1);
-+    BIO_set_data(bi, ctx);
-+
-+    return 1;
-+}
-+
-+static int bio_zlib_free(BIO *bi)
-+{
-+    BIO_ZLIB_CTX *ctx;
-+    if (!bi)
-+        return 0;
-+    ctx = BIO_get_data(bi);
-+    if (ctx->ibuf) {
-+        /* Destroy decompress context */
-+        inflateEnd(&ctx->zin);
-+        OPENSSL_free(ctx->ibuf);
-+    }
-+    if (ctx->obuf) {
-+        /* Destroy compress context */
-+        deflateEnd(&ctx->zout);
-+        OPENSSL_free(ctx->obuf);
-+    }
-+    OPENSSL_free(ctx);
-+    BIO_set_data(bi, NULL);
-+    BIO_set_init(bi, 0);
-+
-+    return 1;
-+}
-+
-+static int bio_zlib_read(BIO *b, char *out, int outl)
-+{
-+    BIO_ZLIB_CTX *ctx;
-+    int ret;
-+    z_stream *zin;
-+    BIO *next = BIO_next(b);
-+
-+    if (!out || !outl)
-+        return 0;
-+    ctx = BIO_get_data(b);
-+    zin = &ctx->zin;
-+    BIO_clear_retry_flags(b);
-+    if (!ctx->ibuf) {
-+        ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
-+        if (ctx->ibuf == NULL) {
-+            COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        inflateInit(zin);
-+        zin->next_in = ctx->ibuf;
-+        zin->avail_in = 0;
-+    }
-+
-+    /* Copy output data directly to supplied buffer */
-+    zin->next_out = (unsigned char *)out;
-+    zin->avail_out = (unsigned int)outl;
-+    for (;;) {
-+        /* Decompress while data available */
-+        while (zin->avail_in) {
-+            ret = inflate(zin, 0);
-+            if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
-+                COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR);
-+                ERR_add_error_data(2, "zlib error:", zError(ret));
-+                return 0;
-+            }
-+            /* If EOF or we've read everything then return */
-+            if ((ret == Z_STREAM_END) || !zin->avail_out)
-+                return outl - zin->avail_out;
-+        }
-+
-+        /*
-+         * No data in input buffer try to read some in, if an error then
-+         * return the total data read.
-+         */
-+        ret = BIO_read(next, ctx->ibuf, ctx->ibufsize);
-+        if (ret <= 0) {
-+            /* Total data read */
-+            int tot = outl - zin->avail_out;
-+            BIO_copy_next_retry(b);
-+            if (ret < 0)
-+                return (tot > 0) ? tot : ret;
-+            return tot;
-+        }
-+        zin->avail_in = ret;
-+        zin->next_in = ctx->ibuf;
-+    }
-+}
-+
-+static int bio_zlib_write(BIO *b, const char *in, int inl)
-+{
-+    BIO_ZLIB_CTX *ctx;
-+    int ret;
-+    z_stream *zout;
-+    BIO *next = BIO_next(b);
-+
-+    if (!in || !inl)
-+        return 0;
-+    ctx = BIO_get_data(b);
-+    if (ctx->odone)
-+        return 0;
-+    zout = &ctx->zout;
-+    BIO_clear_retry_flags(b);
-+    if (!ctx->obuf) {
-+        ctx->obuf = OPENSSL_malloc(ctx->obufsize);
-+        /* Need error here */
-+        if (ctx->obuf == NULL) {
-+            COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        ctx->optr = ctx->obuf;
-+        ctx->ocount = 0;
-+        deflateInit(zout, ctx->comp_level);
-+        zout->next_out = ctx->obuf;
-+        zout->avail_out = ctx->obufsize;
-+    }
-+    /* Obtain input data directly from supplied buffer */
-+    zout->next_in = (void *)in;
-+    zout->avail_in = inl;
-+    for (;;) {
-+        /* If data in output buffer write it first */
-+        while (ctx->ocount) {
-+            ret = BIO_write(next, ctx->optr, ctx->ocount);
-+            if (ret <= 0) {
-+                /* Total data written */
-+                int tot = inl - zout->avail_in;
-+                BIO_copy_next_retry(b);
-+                if (ret < 0)
-+                    return (tot > 0) ? tot : ret;
-+                return tot;
-+            }
-+            ctx->optr += ret;
-+            ctx->ocount -= ret;
-+        }
-+
-+        /* Have we consumed all supplied data? */
-+        if (!zout->avail_in)
-+            return inl;
-+
-+        /* Compress some more */
-+
-+        /* Reset buffer */
-+        ctx->optr = ctx->obuf;
-+        zout->next_out = ctx->obuf;
-+        zout->avail_out = ctx->obufsize;
-+        /* Compress some more */
-+        ret = deflate(zout, 0);
-+        if (ret != Z_OK) {
-+            COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR);
-+            ERR_add_error_data(2, "zlib error:", zError(ret));
-+            return 0;
-+        }
-+        ctx->ocount = ctx->obufsize - zout->avail_out;
-+    }
-+}
-+
-+static int bio_zlib_flush(BIO *b)
-+{
-+    BIO_ZLIB_CTX *ctx;
-+    int ret;
-+    z_stream *zout;
-+    BIO *next = BIO_next(b);
-+
-+    ctx = BIO_get_data(b);
-+    /* If no data written or already flush show success */
-+    if (!ctx->obuf || (ctx->odone && !ctx->ocount))
-+        return 1;
-+    zout = &ctx->zout;
-+    BIO_clear_retry_flags(b);
-+    /* No more input data */
-+    zout->next_in = NULL;
-+    zout->avail_in = 0;
-+    for (;;) {
-+        /* If data in output buffer write it first */
-+        while (ctx->ocount) {
-+            ret = BIO_write(next, ctx->optr, ctx->ocount);
-+            if (ret <= 0) {
-+                BIO_copy_next_retry(b);
-+                return ret;
-+            }
-+            ctx->optr += ret;
-+            ctx->ocount -= ret;
-+        }
-+        if (ctx->odone)
-+            return 1;
-+
-+        /* Compress some more */
-+
-+        /* Reset buffer */
-+        ctx->optr = ctx->obuf;
-+        zout->next_out = ctx->obuf;
-+        zout->avail_out = ctx->obufsize;
-+        /* Compress some more */
-+        ret = deflate(zout, Z_FINISH);
-+        if (ret == Z_STREAM_END)
-+            ctx->odone = 1;
-+        else if (ret != Z_OK) {
-+            COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR);
-+            ERR_add_error_data(2, "zlib error:", zError(ret));
-+            return 0;
-+        }
-+        ctx->ocount = ctx->obufsize - zout->avail_out;
-+    }
-+}
-+
-+static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    BIO_ZLIB_CTX *ctx;
-+    int ret, *ip;
-+    int ibs, obs;
-+    BIO *next = BIO_next(b);
-+
-+    if (next == NULL)
-+        return 0;
-+    ctx = BIO_get_data(b);
-+    switch (cmd) {
-+
-+    case BIO_CTRL_RESET:
-+        ctx->ocount = 0;
-+        ctx->odone = 0;
-+        ret = 1;
-+        break;
-+
-+    case BIO_CTRL_FLUSH:
-+        ret = bio_zlib_flush(b);
-+        if (ret > 0)
-+            ret = BIO_flush(next);
-+        break;
-+
-+    case BIO_C_SET_BUFF_SIZE:
-+        ibs = -1;
-+        obs = -1;
-+        if (ptr != NULL) {
-+            ip = ptr;
-+            if (*ip == 0)
-+                ibs = (int)num;
-+            else
-+                obs = (int)num;
-+        } else {
-+            ibs = (int)num;
-+            obs = ibs;
-+        }
-+
-+        if (ibs != -1) {
-+            OPENSSL_free(ctx->ibuf);
-+            ctx->ibuf = NULL;
-+            ctx->ibufsize = ibs;
-+        }
-+
-+        if (obs != -1) {
-+            OPENSSL_free(ctx->obuf);
-+            ctx->obuf = NULL;
-+            ctx->obufsize = obs;
-+        }
-+        ret = 1;
-+        break;
-+
-+    case BIO_C_DO_STATE_MACHINE:
-+        BIO_clear_retry_flags(b);
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        BIO_copy_next_retry(b);
-+        break;
-+
-+    default:
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+
-+    }
-+
-+    return ret;
-+}
-+
-+static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    BIO *next = BIO_next(b);
-+    if (next == NULL)
-+        return 0;
-+    return BIO_callback_ctrl(next, cmd, fp);
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_err.c
-new file mode 100644
-index 0000000..8e2e695
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_err.c
-@@ -0,0 +1,48 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_COMP,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_COMP,0,reason)
-+
-+static ERR_STRING_DATA COMP_str_functs[] = {
-+    {ERR_FUNC(COMP_F_BIO_ZLIB_FLUSH), "bio_zlib_flush"},
-+    {ERR_FUNC(COMP_F_BIO_ZLIB_NEW), "bio_zlib_new"},
-+    {ERR_FUNC(COMP_F_BIO_ZLIB_READ), "bio_zlib_read"},
-+    {ERR_FUNC(COMP_F_BIO_ZLIB_WRITE), "bio_zlib_write"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA COMP_str_reasons[] = {
-+    {ERR_REASON(COMP_R_ZLIB_DEFLATE_ERROR), "zlib deflate error"},
-+    {ERR_REASON(COMP_R_ZLIB_INFLATE_ERROR), "zlib inflate error"},
-+    {ERR_REASON(COMP_R_ZLIB_NOT_SUPPORTED), "zlib not supported"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_COMP_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(COMP_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, COMP_str_functs);
-+        ERR_load_strings(0, COMP_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_lcl.h
-new file mode 100644
-index 0000000..aa45fca
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_lcl.h
-@@ -0,0 +1,30 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+struct comp_method_st {
-+    int type;                   /* NID for compression library */
-+    const char *name;           /* A text string to identify the library */
-+    int (*init) (COMP_CTX *ctx);
-+    void (*finish) (COMP_CTX *ctx);
-+    int (*compress) (COMP_CTX *ctx,
-+                     unsigned char *out, unsigned int olen,
-+                     unsigned char *in, unsigned int ilen);
-+    int (*expand) (COMP_CTX *ctx,
-+                   unsigned char *out, unsigned int olen,
-+                   unsigned char *in, unsigned int ilen);
-+};
-+
-+struct comp_ctx_st {
-+    struct comp_method_st *meth;
-+    unsigned long compress_in;
-+    unsigned long compress_out;
-+    unsigned long expand_in;
-+    unsigned long expand_out;
-+    void* data;
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_lib.c
-new file mode 100644
-index 0000000..32afd0d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/comp/comp_lib.c
-@@ -0,0 +1,91 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "comp_lcl.h"
-+
-+COMP_CTX *COMP_CTX_new(COMP_METHOD *meth)
-+{
-+    COMP_CTX *ret;
-+
-+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
-+        return (NULL);
-+    ret->meth = meth;
-+    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
-+        OPENSSL_free(ret);
-+        ret = NULL;
-+    }
-+    return (ret);
-+}
-+
-+const COMP_METHOD *COMP_CTX_get_method(const COMP_CTX *ctx)
-+{
-+    return ctx->meth;
-+}
-+
-+int COMP_get_type(const COMP_METHOD *meth)
-+{
-+    return meth->type;
-+}
-+
-+const char *COMP_get_name(const COMP_METHOD *meth)
-+{
-+    return meth->name;
-+}
-+
-+void COMP_CTX_free(COMP_CTX *ctx)
-+{
-+    if (ctx == NULL)
-+        return;
-+
-+    if (ctx->meth->finish != NULL)
-+        ctx->meth->finish(ctx);
-+
-+    OPENSSL_free(ctx);
-+}
-+
-+int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
-+                        unsigned char *in, int ilen)
-+{
-+    int ret;
-+    if (ctx->meth->compress == NULL) {
-+        return (-1);
-+    }
-+    ret = ctx->meth->compress(ctx, out, olen, in, ilen);
-+    if (ret > 0) {
-+        ctx->compress_in += ilen;
-+        ctx->compress_out += ret;
-+    }
-+    return (ret);
-+}
-+
-+int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
-+                      unsigned char *in, int ilen)
-+{
-+    int ret;
-+
-+    if (ctx->meth->expand == NULL) {
-+        return (-1);
-+    }
-+    ret = ctx->meth->expand(ctx, out, olen, in, ilen);
-+    if (ret > 0) {
-+        ctx->expand_in += ilen;
-+        ctx->expand_out += ret;
-+    }
-+    return (ret);
-+}
-+
-+int COMP_CTX_get_type(const COMP_CTX* comp)
-+{
-+    return comp->meth ? comp->meth->type : NID_undef;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/build.info
-new file mode 100644
-index 0000000..4438eb4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/build.info
-@@ -0,0 +1,4 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]= \
-+        conf_err.c conf_lib.c conf_api.c conf_def.c conf_mod.c \
-+        conf_mall.c conf_sap.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_api.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_api.c
-new file mode 100644
-index 0000000..5535416
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_api.c
-@@ -0,0 +1,214 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Part of the code in here was originally in conf.c, which is now removed */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "e_os.h"
-+
-+static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf);
-+static void value_free_stack_doall(CONF_VALUE *a);
-+
-+/* Up until OpenSSL 0.9.5a, this was get_section */
-+CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
-+{
-+    CONF_VALUE *v, vv;
-+
-+    if ((conf == NULL) || (section == NULL))
-+        return (NULL);
-+    vv.name = NULL;
-+    vv.section = (char *)section;
-+    v = lh_CONF_VALUE_retrieve(conf->data, &vv);
-+    return (v);
-+}
-+
-+/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
-+STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
-+                                               const char *section)
-+{
-+    CONF_VALUE *v;
-+
-+    v = _CONF_get_section(conf, section);
-+    if (v != NULL)
-+        return ((STACK_OF(CONF_VALUE) *)v->value);
-+    else
-+        return (NULL);
-+}
-+
-+int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
-+{
-+    CONF_VALUE *v = NULL;
-+    STACK_OF(CONF_VALUE) *ts;
-+
-+    ts = (STACK_OF(CONF_VALUE) *)section->value;
-+
-+    value->section = section->section;
-+    if (!sk_CONF_VALUE_push(ts, value)) {
-+        return 0;
-+    }
-+
-+    v = lh_CONF_VALUE_insert(conf->data, value);
-+    if (v != NULL) {
-+        (void)sk_CONF_VALUE_delete_ptr(ts, v);
-+        OPENSSL_free(v->name);
-+        OPENSSL_free(v->value);
-+        OPENSSL_free(v);
-+    }
-+    return 1;
-+}
-+
-+char *_CONF_get_string(const CONF *conf, const char *section,
-+                       const char *name)
-+{
-+    CONF_VALUE *v, vv;
-+    char *p;
-+
-+    if (name == NULL)
-+        return (NULL);
-+    if (conf != NULL) {
-+        if (section != NULL) {
-+            vv.name = (char *)name;
-+            vv.section = (char *)section;
-+            v = lh_CONF_VALUE_retrieve(conf->data, &vv);
-+            if (v != NULL)
-+                return (v->value);
-+            if (strcmp(section, "ENV") == 0) {
-+                p = getenv(name);
-+                if (p != NULL)
-+                    return (p);
-+            }
-+        }
-+        vv.section = "default";
-+        vv.name = (char *)name;
-+        v = lh_CONF_VALUE_retrieve(conf->data, &vv);
-+        if (v != NULL)
-+            return (v->value);
-+        else
-+            return (NULL);
-+    } else
-+        return (getenv(name));
-+}
-+
-+static unsigned long conf_value_hash(const CONF_VALUE *v)
-+{
-+    return (OPENSSL_LH_strhash(v->section) << 2) ^ OPENSSL_LH_strhash(v->name);
-+}
-+
-+static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
-+{
-+    int i;
-+
-+    if (a->section != b->section) {
-+        i = strcmp(a->section, b->section);
-+        if (i)
-+            return (i);
-+    }
-+
-+    if ((a->name != NULL) && (b->name != NULL)) {
-+        i = strcmp(a->name, b->name);
-+        return (i);
-+    } else if (a->name == b->name)
-+        return (0);
-+    else
-+        return ((a->name == NULL) ? -1 : 1);
-+}
-+
-+int _CONF_new_data(CONF *conf)
-+{
-+    if (conf == NULL) {
-+        return 0;
-+    }
-+    if (conf->data == NULL) {
-+        conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp);
-+        if (conf->data == NULL)
-+            return 0;
-+    }
-+    return 1;
-+}
-+
-+typedef LHASH_OF(CONF_VALUE) LH_CONF_VALUE;
-+
-+IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, LH_CONF_VALUE);
-+
-+void _CONF_free_data(CONF *conf)
-+{
-+    if (conf == NULL || conf->data == NULL)
-+        return;
-+
-+    /* evil thing to make sure the 'OPENSSL_free()' works as expected */
-+    lh_CONF_VALUE_set_down_load(conf->data, 0);
-+    lh_CONF_VALUE_doall_LH_CONF_VALUE(conf->data, value_free_hash, conf->data);
-+
-+    /*
-+     * We now have only 'section' entries in the hash table. Due to problems
-+     * with
-+     */
-+
-+    lh_CONF_VALUE_doall(conf->data, value_free_stack_doall);
-+    lh_CONF_VALUE_free(conf->data);
-+}
-+
-+static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
-+{
-+    if (a->name != NULL)
-+        (void)lh_CONF_VALUE_delete(conf, a);
-+}
-+
-+static void value_free_stack_doall(CONF_VALUE *a)
-+{
-+    CONF_VALUE *vv;
-+    STACK_OF(CONF_VALUE) *sk;
-+    int i;
-+
-+    if (a->name != NULL)
-+        return;
-+
-+    sk = (STACK_OF(CONF_VALUE) *)a->value;
-+    for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) {
-+        vv = sk_CONF_VALUE_value(sk, i);
-+        OPENSSL_free(vv->value);
-+        OPENSSL_free(vv->name);
-+        OPENSSL_free(vv);
-+    }
-+    sk_CONF_VALUE_free(sk);
-+    OPENSSL_free(a->section);
-+    OPENSSL_free(a);
-+}
-+
-+/* Up until OpenSSL 0.9.5a, this was new_section */
-+CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
-+{
-+    STACK_OF(CONF_VALUE) *sk = NULL;
-+    int i;
-+    CONF_VALUE *v = NULL, *vv;
-+
-+    if ((sk = sk_CONF_VALUE_new_null()) == NULL)
-+        goto err;
-+    if ((v = OPENSSL_malloc(sizeof(*v))) == NULL)
-+        goto err;
-+    i = strlen(section) + 1;
-+    if ((v->section = OPENSSL_malloc(i)) == NULL)
-+        goto err;
-+
-+    memcpy(v->section, section, i);
-+    v->name = NULL;
-+    v->value = (char *)sk;
-+
-+    vv = lh_CONF_VALUE_insert(conf->data, v);
-+    OPENSSL_assert(vv == NULL);
-+    return v;
-+
-+ err:
-+    sk_CONF_VALUE_free(sk);
-+    OPENSSL_free(v);
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_def.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_def.c
-new file mode 100644
-index 0000000..8861b3a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_def.c
-@@ -0,0 +1,630 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Part of the code in here was originally in conf.c, which is now removed */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "conf_def.h"
-+#include 
-+#include 
-+
-+static char *eat_ws(CONF *conf, char *p);
-+static char *eat_alpha_numeric(CONF *conf, char *p);
-+static void clear_comments(CONF *conf, char *p);
-+static int str_copy(CONF *conf, char *section, char **to, char *from);
-+static char *scan_quote(CONF *conf, char *p);
-+static char *scan_dquote(CONF *conf, char *p);
-+#define scan_esc(conf,p)        (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
-+
-+static CONF *def_create(CONF_METHOD *meth);
-+static int def_init_default(CONF *conf);
-+static int def_init_WIN32(CONF *conf);
-+static int def_destroy(CONF *conf);
-+static int def_destroy_data(CONF *conf);
-+static int def_load(CONF *conf, const char *name, long *eline);
-+static int def_load_bio(CONF *conf, BIO *bp, long *eline);
-+static int def_dump(const CONF *conf, BIO *bp);
-+static int def_is_number(const CONF *conf, char c);
-+static int def_to_int(const CONF *conf, char c);
-+
-+static CONF_METHOD default_method = {
-+    "OpenSSL default",
-+    def_create,
-+    def_init_default,
-+    def_destroy,
-+    def_destroy_data,
-+    def_load_bio,
-+    def_dump,
-+    def_is_number,
-+    def_to_int,
-+    def_load
-+};
-+
-+static CONF_METHOD WIN32_method = {
-+    "WIN32",
-+    def_create,
-+    def_init_WIN32,
-+    def_destroy,
-+    def_destroy_data,
-+    def_load_bio,
-+    def_dump,
-+    def_is_number,
-+    def_to_int,
-+    def_load
-+};
-+
-+CONF_METHOD *NCONF_default()
-+{
-+    return &default_method;
-+}
-+
-+CONF_METHOD *NCONF_WIN32()
-+{
-+    return &WIN32_method;
-+}
-+
-+static CONF *def_create(CONF_METHOD *meth)
-+{
-+    CONF *ret;
-+
-+    ret = OPENSSL_malloc(sizeof(*ret));
-+    if (ret != NULL)
-+        if (meth->init(ret) == 0) {
-+            OPENSSL_free(ret);
-+            ret = NULL;
-+        }
-+    return ret;
-+}
-+
-+static int def_init_default(CONF *conf)
-+{
-+    if (conf == NULL)
-+        return 0;
-+
-+    conf->meth = &default_method;
-+    conf->meth_data = (void *)CONF_type_default;
-+    conf->data = NULL;
-+
-+    return 1;
-+}
-+
-+static int def_init_WIN32(CONF *conf)
-+{
-+    if (conf == NULL)
-+        return 0;
-+
-+    conf->meth = &WIN32_method;
-+    conf->meth_data = (void *)CONF_type_win32;
-+    conf->data = NULL;
-+
-+    return 1;
-+}
-+
-+static int def_destroy(CONF *conf)
-+{
-+    if (def_destroy_data(conf)) {
-+        OPENSSL_free(conf);
-+        return 1;
-+    }
-+    return 0;
-+}
-+
-+static int def_destroy_data(CONF *conf)
-+{
-+    if (conf == NULL)
-+        return 0;
-+    _CONF_free_data(conf);
-+    return 1;
-+}
-+
-+static int def_load(CONF *conf, const char *name, long *line)
-+{
-+    int ret;
-+    BIO *in = NULL;
-+
-+#ifdef OPENSSL_SYS_VMS
-+    in = BIO_new_file(name, "r");
-+#else
-+    in = BIO_new_file(name, "rb");
-+#endif
-+    if (in == NULL) {
-+        if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
-+            CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE);
-+        else
-+            CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB);
-+        return 0;
-+    }
-+
-+    ret = def_load_bio(conf, in, line);
-+    BIO_free(in);
-+
-+    return ret;
-+}
-+
-+static int def_load_bio(CONF *conf, BIO *in, long *line)
-+{
-+/* The macro BUFSIZE conflicts with a system macro in VxWorks */
-+#define CONFBUFSIZE     512
-+    int bufnum = 0, i, ii;
-+    BUF_MEM *buff = NULL;
-+    char *s, *p, *end;
-+    int again;
-+    long eline = 0;
-+    char btmp[DECIMAL_SIZE(eline) + 1];
-+    CONF_VALUE *v = NULL, *tv;
-+    CONF_VALUE *sv = NULL;
-+    char *section = NULL, *buf;
-+    char *start, *psection, *pname;
-+    void *h = (void *)(conf->data);
-+
-+    if ((buff = BUF_MEM_new()) == NULL) {
-+        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
-+        goto err;
-+    }
-+
-+    section = OPENSSL_strdup("default");
-+    if (section == NULL) {
-+        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (_CONF_new_data(conf) == 0) {
-+        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    sv = _CONF_new_section(conf, section);
-+    if (sv == NULL) {
-+        CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
-+        goto err;
-+    }
-+
-+    bufnum = 0;
-+    again = 0;
-+    for (;;) {
-+        if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
-+            CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
-+            goto err;
-+        }
-+        p = &(buff->data[bufnum]);
-+        *p = '\0';
-+        BIO_gets(in, p, CONFBUFSIZE - 1);
-+        p[CONFBUFSIZE - 1] = '\0';
-+        ii = i = strlen(p);
-+        if (i == 0 && !again)
-+            break;
-+        again = 0;
-+        while (i > 0) {
-+            if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
-+                break;
-+            else
-+                i--;
-+        }
-+        /*
-+         * we removed some trailing stuff so there is a new line on the end.
-+         */
-+        if (ii && i == ii)
-+            again = 1;          /* long line */
-+        else {
-+            p[i] = '\0';
-+            eline++;            /* another input line */
-+        }
-+
-+        /* we now have a line with trailing \r\n removed */
-+
-+        /* i is the number of bytes */
-+        bufnum += i;
-+
-+        v = NULL;
-+        /* check for line continuation */
-+        if (bufnum >= 1) {
-+            /*
-+             * If we have bytes and the last char '\\' and second last char
-+             * is not '\\'
-+             */
-+            p = &(buff->data[bufnum - 1]);
-+            if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
-+                bufnum--;
-+                again = 1;
-+            }
-+        }
-+        if (again)
-+            continue;
-+        bufnum = 0;
-+        buf = buff->data;
-+
-+        clear_comments(conf, buf);
-+        s = eat_ws(conf, buf);
-+        if (IS_EOF(conf, *s))
-+            continue;           /* blank line */
-+        if (*s == '[') {
-+            char *ss;
-+
-+            s++;
-+            start = eat_ws(conf, s);
-+            ss = start;
-+ again:
-+            end = eat_alpha_numeric(conf, ss);
-+            p = eat_ws(conf, end);
-+            if (*p != ']') {
-+                if (*p != '\0' && ss != p) {
-+                    ss = p;
-+                    goto again;
-+                }
-+                CONFerr(CONF_F_DEF_LOAD_BIO,
-+                        CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
-+                goto err;
-+            }
-+            *end = '\0';
-+            if (!str_copy(conf, NULL, §ion, start))
-+                goto err;
-+            if ((sv = _CONF_get_section(conf, section)) == NULL)
-+                sv = _CONF_new_section(conf, section);
-+            if (sv == NULL) {
-+                CONFerr(CONF_F_DEF_LOAD_BIO,
-+                        CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
-+                goto err;
-+            }
-+            continue;
-+        } else {
-+            pname = s;
-+            psection = NULL;
-+            end = eat_alpha_numeric(conf, s);
-+            if ((end[0] == ':') && (end[1] == ':')) {
-+                *end = '\0';
-+                end += 2;
-+                psection = pname;
-+                pname = end;
-+                end = eat_alpha_numeric(conf, end);
-+            }
-+            p = eat_ws(conf, end);
-+            if (*p != '=') {
-+                CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN);
-+                goto err;
-+            }
-+            *end = '\0';
-+            p++;
-+            start = eat_ws(conf, p);
-+            while (!IS_EOF(conf, *p))
-+                p++;
-+            p--;
-+            while ((p != start) && (IS_WS(conf, *p)))
-+                p--;
-+            p++;
-+            *p = '\0';
-+
-+            if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) {
-+                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            if (psection == NULL)
-+                psection = section;
-+            v->name = OPENSSL_malloc(strlen(pname) + 1);
-+            v->value = NULL;
-+            if (v->name == NULL) {
-+                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            OPENSSL_strlcpy(v->name, pname, strlen(pname) + 1);
-+            if (!str_copy(conf, psection, &(v->value), start))
-+                goto err;
-+
-+            if (strcmp(psection, section) != 0) {
-+                if ((tv = _CONF_get_section(conf, psection))
-+                    == NULL)
-+                    tv = _CONF_new_section(conf, psection);
-+                if (tv == NULL) {
-+                    CONFerr(CONF_F_DEF_LOAD_BIO,
-+                            CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
-+                    goto err;
-+                }
-+            } else
-+                tv = sv;
-+            if (_CONF_add_string(conf, tv, v) == 0) {
-+                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            v = NULL;
-+        }
-+    }
-+    BUF_MEM_free(buff);
-+    OPENSSL_free(section);
-+    return (1);
-+ err:
-+    BUF_MEM_free(buff);
-+    OPENSSL_free(section);
-+    if (line != NULL)
-+        *line = eline;
-+    BIO_snprintf(btmp, sizeof btmp, "%ld", eline);
-+    ERR_add_error_data(2, "line ", btmp);
-+    if (h != conf->data) {
-+        CONF_free(conf->data);
-+        conf->data = NULL;
-+    }
-+    if (v != NULL) {
-+        OPENSSL_free(v->name);
-+        OPENSSL_free(v->value);
-+        OPENSSL_free(v);
-+    }
-+    return (0);
-+}
-+
-+static void clear_comments(CONF *conf, char *p)
-+{
-+    for (;;) {
-+        if (IS_FCOMMENT(conf, *p)) {
-+            *p = '\0';
-+            return;
-+        }
-+        if (!IS_WS(conf, *p)) {
-+            break;
-+        }
-+        p++;
-+    }
-+
-+    for (;;) {
-+        if (IS_COMMENT(conf, *p)) {
-+            *p = '\0';
-+            return;
-+        }
-+        if (IS_DQUOTE(conf, *p)) {
-+            p = scan_dquote(conf, p);
-+            continue;
-+        }
-+        if (IS_QUOTE(conf, *p)) {
-+            p = scan_quote(conf, p);
-+            continue;
-+        }
-+        if (IS_ESC(conf, *p)) {
-+            p = scan_esc(conf, p);
-+            continue;
-+        }
-+        if (IS_EOF(conf, *p))
-+            return;
-+        else
-+            p++;
-+    }
-+}
-+
-+static int str_copy(CONF *conf, char *section, char **pto, char *from)
-+{
-+    int q, r, rr = 0, to = 0, len = 0;
-+    char *s, *e, *rp, *p, *rrp, *np, *cp, v;
-+    BUF_MEM *buf;
-+
-+    if ((buf = BUF_MEM_new()) == NULL)
-+        return (0);
-+
-+    len = strlen(from) + 1;
-+    if (!BUF_MEM_grow(buf, len))
-+        goto err;
-+
-+    for (;;) {
-+        if (IS_QUOTE(conf, *from)) {
-+            q = *from;
-+            from++;
-+            while (!IS_EOF(conf, *from) && (*from != q)) {
-+                if (IS_ESC(conf, *from)) {
-+                    from++;
-+                    if (IS_EOF(conf, *from))
-+                        break;
-+                }
-+                buf->data[to++] = *(from++);
-+            }
-+            if (*from == q)
-+                from++;
-+        } else if (IS_DQUOTE(conf, *from)) {
-+            q = *from;
-+            from++;
-+            while (!IS_EOF(conf, *from)) {
-+                if (*from == q) {
-+                    if (*(from + 1) == q) {
-+                        from++;
-+                    } else {
-+                        break;
-+                    }
-+                }
-+                buf->data[to++] = *(from++);
-+            }
-+            if (*from == q)
-+                from++;
-+        } else if (IS_ESC(conf, *from)) {
-+            from++;
-+            v = *(from++);
-+            if (IS_EOF(conf, v))
-+                break;
-+            else if (v == 'r')
-+                v = '\r';
-+            else if (v == 'n')
-+                v = '\n';
-+            else if (v == 'b')
-+                v = '\b';
-+            else if (v == 't')
-+                v = '\t';
-+            buf->data[to++] = v;
-+        } else if (IS_EOF(conf, *from))
-+            break;
-+        else if (*from == '$') {
-+            /* try to expand it */
-+            rrp = NULL;
-+            s = &(from[1]);
-+            if (*s == '{')
-+                q = '}';
-+            else if (*s == '(')
-+                q = ')';
-+            else
-+                q = 0;
-+
-+            if (q)
-+                s++;
-+            cp = section;
-+            e = np = s;
-+            while (IS_ALPHA_NUMERIC(conf, *e))
-+                e++;
-+            if ((e[0] == ':') && (e[1] == ':')) {
-+                cp = np;
-+                rrp = e;
-+                rr = *e;
-+                *rrp = '\0';
-+                e += 2;
-+                np = e;
-+                while (IS_ALPHA_NUMERIC(conf, *e))
-+                    e++;
-+            }
-+            r = *e;
-+            *e = '\0';
-+            rp = e;
-+            if (q) {
-+                if (r != q) {
-+                    CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE);
-+                    goto err;
-+                }
-+                e++;
-+            }
-+            /*-
-+             * So at this point we have
-+             * np which is the start of the name string which is
-+             *   '\0' terminated.
-+             * cp which is the start of the section string which is
-+             *   '\0' terminated.
-+             * e is the 'next point after'.
-+             * r and rr are the chars replaced by the '\0'
-+             * rp and rrp is where 'r' and 'rr' came from.
-+             */
-+            p = _CONF_get_string(conf, cp, np);
-+            if (rrp != NULL)
-+                *rrp = rr;
-+            *rp = r;
-+            if (p == NULL) {
-+                CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE);
-+                goto err;
-+            }
-+            if (!BUF_MEM_grow_clean(buf,
-+                        (strlen(p) + buf->length - (e - from)))) {
-+                CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            while (*p)
-+                buf->data[to++] = *(p++);
-+
-+            /*
-+             * Since we change the pointer 'from', we also have to change the
-+             * perceived length of the string it points at.  /RL
-+             */
-+            len -= e - from;
-+            from = e;
-+
-+            /*
-+             * In case there were no braces or parenthesis around the
-+             * variable reference, we have to put back the character that was
-+             * replaced with a '\0'.  /RL
-+             */
-+            *rp = r;
-+        } else
-+            buf->data[to++] = *(from++);
-+    }
-+    buf->data[to] = '\0';
-+    OPENSSL_free(*pto);
-+    *pto = buf->data;
-+    OPENSSL_free(buf);
-+    return (1);
-+ err:
-+    BUF_MEM_free(buf);
-+    return (0);
-+}
-+
-+static char *eat_ws(CONF *conf, char *p)
-+{
-+    while (IS_WS(conf, *p) && (!IS_EOF(conf, *p)))
-+        p++;
-+    return (p);
-+}
-+
-+static char *eat_alpha_numeric(CONF *conf, char *p)
-+{
-+    for (;;) {
-+        if (IS_ESC(conf, *p)) {
-+            p = scan_esc(conf, p);
-+            continue;
-+        }
-+        if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p))
-+            return (p);
-+        p++;
-+    }
-+}
-+
-+static char *scan_quote(CONF *conf, char *p)
-+{
-+    int q = *p;
-+
-+    p++;
-+    while (!(IS_EOF(conf, *p)) && (*p != q)) {
-+        if (IS_ESC(conf, *p)) {
-+            p++;
-+            if (IS_EOF(conf, *p))
-+                return (p);
-+        }
-+        p++;
-+    }
-+    if (*p == q)
-+        p++;
-+    return (p);
-+}
-+
-+static char *scan_dquote(CONF *conf, char *p)
-+{
-+    int q = *p;
-+
-+    p++;
-+    while (!(IS_EOF(conf, *p))) {
-+        if (*p == q) {
-+            if (*(p + 1) == q) {
-+                p++;
-+            } else {
-+                break;
-+            }
-+        }
-+        p++;
-+    }
-+    if (*p == q)
-+        p++;
-+    return (p);
-+}
-+
-+static void dump_value_doall_arg(const CONF_VALUE *a, BIO *out)
-+{
-+    if (a->name)
-+        BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
-+    else
-+        BIO_printf(out, "[[%s]]\n", a->section);
-+}
-+
-+IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, BIO);
-+
-+static int def_dump(const CONF *conf, BIO *out)
-+{
-+    lh_CONF_VALUE_doall_BIO(conf->data, dump_value_doall_arg, out);
-+    return 1;
-+}
-+
-+static int def_is_number(const CONF *conf, char c)
-+{
-+    return IS_NUMBER(conf, c);
-+}
-+
-+static int def_to_int(const CONF *conf, char c)
-+{
-+    return c - '0';
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_def.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_def.h
-new file mode 100644
-index 0000000..da4767e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_def.h
-@@ -0,0 +1,129 @@
-+/*
-+ * WARNING: do not edit!
-+ * Generated by crypto/conf/keysets.pl
-+ *
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#define CONF_NUMBER             1
-+#define CONF_UPPER              2
-+#define CONF_LOWER              4
-+#define CONF_UNDER              256
-+#define CONF_PUNCTUATION        512
-+#define CONF_WS                 16
-+#define CONF_ESC                32
-+#define CONF_QUOTE              64
-+#define CONF_DQUOTE             1024
-+#define CONF_COMMENT            128
-+#define CONF_FCOMMENT           2048
-+#define CONF_EOF                8
-+#define CONF_HIGHBIT            4096
-+#define CONF_ALPHA              (CONF_UPPER|CONF_LOWER)
-+#define CONF_ALPHA_NUMERIC      (CONF_ALPHA|CONF_NUMBER|CONF_UNDER)
-+#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \
-+                                        CONF_PUNCTUATION)
-+
-+#define KEYTYPES(c)             ((const unsigned short *)((c)->meth_data))
-+#ifndef CHARSET_EBCDIC
-+# define IS_COMMENT(c,a)         (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT)
-+# define IS_FCOMMENT(c,a)        (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
-+# define IS_EOF(c,a)             (KEYTYPES(c)[(a)&0xff]&CONF_EOF)
-+# define IS_ESC(c,a)             (KEYTYPES(c)[(a)&0xff]&CONF_ESC)
-+# define IS_NUMBER(c,a)          (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
-+# define IS_WS(c,a)              (KEYTYPES(c)[(a)&0xff]&CONF_WS)
-+# define IS_ALPHA_NUMERIC(c,a)   (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
-+# define IS_ALPHA_NUMERIC_PUNCT(c,a) \
-+                                (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
-+# define IS_QUOTE(c,a)           (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
-+# define IS_DQUOTE(c,a)          (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
-+# define IS_HIGHBIT(c,a)         (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
-+
-+#else                           /* CHARSET_EBCDIC */
-+
-+# define IS_COMMENT(c,a)         (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_COMMENT)
-+# define IS_FCOMMENT(c,a)        (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_FCOMMENT)
-+# define IS_EOF(c,a)             (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_EOF)
-+# define IS_ESC(c,a)             (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_ESC)
-+# define IS_NUMBER(c,a)          (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_NUMBER)
-+# define IS_WS(c,a)              (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_WS)
-+# define IS_ALPHA_NUMERIC(c,a)   (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_ALPHA_NUMERIC)
-+# define IS_ALPHA_NUMERIC_PUNCT(c,a) \
-+                                (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_ALPHA_NUMERIC_PUNCT)
-+# define IS_QUOTE(c,a)           (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_QUOTE)
-+# define IS_DQUOTE(c,a)          (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_DQUOTE)
-+# define IS_HIGHBIT(c,a)         (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_HIGHBIT)
-+#endif                          /* CHARSET_EBCDIC */
-+
-+static const unsigned short CONF_type_default[256] = {
-+    0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+    0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000,
-+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+    0x0010, 0x0200, 0x0040, 0x0080, 0x0000, 0x0200, 0x0200, 0x0040,
-+    0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200,
-+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
-+    0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200,
-+    0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
-+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
-+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
-+    0x0002, 0x0002, 0x0002, 0x0000, 0x0020, 0x0000, 0x0200, 0x0100,
-+    0x0040, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
-+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
-+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
-+    0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+};
-+
-+static const unsigned short CONF_type_win32[256] = {
-+    0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+    0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000,
-+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+    0x0010, 0x0200, 0x0400, 0x0000, 0x0000, 0x0200, 0x0200, 0x0000,
-+    0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200,
-+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
-+    0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200,
-+    0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
-+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
-+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
-+    0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0200, 0x0100,
-+    0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
-+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
-+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
-+    0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_err.c
-new file mode 100644
-index 0000000..b583c05
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_err.c
-@@ -0,0 +1,79 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CONF,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CONF,0,reason)
-+
-+static ERR_STRING_DATA CONF_str_functs[] = {
-+    {ERR_FUNC(CONF_F_CONF_DUMP_FP), "CONF_dump_fp"},
-+    {ERR_FUNC(CONF_F_CONF_LOAD), "CONF_load"},
-+    {ERR_FUNC(CONF_F_CONF_LOAD_FP), "CONF_load_fp"},
-+    {ERR_FUNC(CONF_F_CONF_PARSE_LIST), "CONF_parse_list"},
-+    {ERR_FUNC(CONF_F_DEF_LOAD), "def_load"},
-+    {ERR_FUNC(CONF_F_DEF_LOAD_BIO), "def_load_bio"},
-+    {ERR_FUNC(CONF_F_MODULE_INIT), "module_init"},
-+    {ERR_FUNC(CONF_F_MODULE_LOAD_DSO), "module_load_dso"},
-+    {ERR_FUNC(CONF_F_MODULE_RUN), "module_run"},
-+    {ERR_FUNC(CONF_F_NCONF_DUMP_BIO), "NCONF_dump_bio"},
-+    {ERR_FUNC(CONF_F_NCONF_DUMP_FP), "NCONF_dump_fp"},
-+    {ERR_FUNC(CONF_F_NCONF_GET_NUMBER_E), "NCONF_get_number_e"},
-+    {ERR_FUNC(CONF_F_NCONF_GET_SECTION), "NCONF_get_section"},
-+    {ERR_FUNC(CONF_F_NCONF_GET_STRING), "NCONF_get_string"},
-+    {ERR_FUNC(CONF_F_NCONF_LOAD), "NCONF_load"},
-+    {ERR_FUNC(CONF_F_NCONF_LOAD_BIO), "NCONF_load_bio"},
-+    {ERR_FUNC(CONF_F_NCONF_LOAD_FP), "NCONF_load_fp"},
-+    {ERR_FUNC(CONF_F_NCONF_NEW), "NCONF_new"},
-+    {ERR_FUNC(CONF_F_STR_COPY), "str_copy"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA CONF_str_reasons[] = {
-+    {ERR_REASON(CONF_R_ERROR_LOADING_DSO), "error loading dso"},
-+    {ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL), "list cannot be null"},
-+    {ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET),
-+     "missing close square bracket"},
-+    {ERR_REASON(CONF_R_MISSING_EQUAL_SIGN), "missing equal sign"},
-+    {ERR_REASON(CONF_R_MISSING_INIT_FUNCTION), "missing init function"},
-+    {ERR_REASON(CONF_R_MODULE_INITIALIZATION_ERROR),
-+     "module initialization error"},
-+    {ERR_REASON(CONF_R_NO_CLOSE_BRACE), "no close brace"},
-+    {ERR_REASON(CONF_R_NO_CONF), "no conf"},
-+    {ERR_REASON(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE),
-+     "no conf or environment variable"},
-+    {ERR_REASON(CONF_R_NO_SECTION), "no section"},
-+    {ERR_REASON(CONF_R_NO_SUCH_FILE), "no such file"},
-+    {ERR_REASON(CONF_R_NO_VALUE), "no value"},
-+    {ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION),
-+     "unable to create new section"},
-+    {ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME), "unknown module name"},
-+    {ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_CONF_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(CONF_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, CONF_str_functs);
-+        ERR_load_strings(0, CONF_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_lib.c
-new file mode 100644
-index 0000000..3532114
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_lib.c
-@@ -0,0 +1,365 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "e_os.h"
-+
-+static CONF_METHOD *default_CONF_method = NULL;
-+
-+/* Init a 'CONF' structure from an old LHASH */
-+
-+void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
-+{
-+    if (default_CONF_method == NULL)
-+        default_CONF_method = NCONF_default();
-+
-+    default_CONF_method->init(conf);
-+    conf->data = hash;
-+}
-+
-+/*
-+ * The following section contains the "CONF classic" functions, rewritten in
-+ * terms of the new CONF interface.
-+ */
-+
-+int CONF_set_default_method(CONF_METHOD *meth)
-+{
-+    default_CONF_method = meth;
-+    return 1;
-+}
-+
-+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
-+                                long *eline)
-+{
-+    LHASH_OF(CONF_VALUE) *ltmp;
-+    BIO *in = NULL;
-+
-+#ifdef OPENSSL_SYS_VMS
-+    in = BIO_new_file(file, "r");
-+#else
-+    in = BIO_new_file(file, "rb");
-+#endif
-+    if (in == NULL) {
-+        CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB);
-+        return NULL;
-+    }
-+
-+    ltmp = CONF_load_bio(conf, in, eline);
-+    BIO_free(in);
-+
-+    return ltmp;
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
-+                                   long *eline)
-+{
-+    BIO *btmp;
-+    LHASH_OF(CONF_VALUE) *ltmp;
-+    if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
-+        CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB);
-+        return NULL;
-+    }
-+    ltmp = CONF_load_bio(conf, btmp, eline);
-+    BIO_free(btmp);
-+    return ltmp;
-+}
-+#endif
-+
-+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
-+                                    long *eline)
-+{
-+    CONF ctmp;
-+    int ret;
-+
-+    CONF_set_nconf(&ctmp, conf);
-+
-+    ret = NCONF_load_bio(&ctmp, bp, eline);
-+    if (ret)
-+        return ctmp.data;
-+    return NULL;
-+}
-+
-+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
-+                                       const char *section)
-+{
-+    if (conf == NULL) {
-+        return NULL;
-+    } else {
-+        CONF ctmp;
-+        CONF_set_nconf(&ctmp, conf);
-+        return NCONF_get_section(&ctmp, section);
-+    }
-+}
-+
-+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
-+                      const char *name)
-+{
-+    if (conf == NULL) {
-+        return NCONF_get_string(NULL, group, name);
-+    } else {
-+        CONF ctmp;
-+        CONF_set_nconf(&ctmp, conf);
-+        return NCONF_get_string(&ctmp, group, name);
-+    }
-+}
-+
-+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
-+                     const char *name)
-+{
-+    int status;
-+    long result = 0;
-+
-+    if (conf == NULL) {
-+        status = NCONF_get_number_e(NULL, group, name, &result);
-+    } else {
-+        CONF ctmp;
-+        CONF_set_nconf(&ctmp, conf);
-+        status = NCONF_get_number_e(&ctmp, group, name, &result);
-+    }
-+
-+    if (status == 0) {
-+        /* This function does not believe in errors... */
-+        ERR_clear_error();
-+    }
-+    return result;
-+}
-+
-+void CONF_free(LHASH_OF(CONF_VALUE) *conf)
-+{
-+    CONF ctmp;
-+    CONF_set_nconf(&ctmp, conf);
-+    NCONF_free_data(&ctmp);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out)
-+{
-+    BIO *btmp;
-+    int ret;
-+
-+    if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) {
-+        CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB);
-+        return 0;
-+    }
-+    ret = CONF_dump_bio(conf, btmp);
-+    BIO_free(btmp);
-+    return ret;
-+}
-+#endif
-+
-+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
-+{
-+    CONF ctmp;
-+    CONF_set_nconf(&ctmp, conf);
-+    return NCONF_dump_bio(&ctmp, out);
-+}
-+
-+/*
-+ * The following section contains the "New CONF" functions.  They are
-+ * completely centralised around a new CONF structure that may contain
-+ * basically anything, but at least a method pointer and a table of data.
-+ * These functions are also written in terms of the bridge functions used by
-+ * the "CONF classic" functions, for consistency.
-+ */
-+
-+CONF *NCONF_new(CONF_METHOD *meth)
-+{
-+    CONF *ret;
-+
-+    if (meth == NULL)
-+        meth = NCONF_default();
-+
-+    ret = meth->create(meth);
-+    if (ret == NULL) {
-+        CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+
-+    return ret;
-+}
-+
-+void NCONF_free(CONF *conf)
-+{
-+    if (conf == NULL)
-+        return;
-+    conf->meth->destroy(conf);
-+}
-+
-+void NCONF_free_data(CONF *conf)
-+{
-+    if (conf == NULL)
-+        return;
-+    conf->meth->destroy_data(conf);
-+}
-+
-+int NCONF_load(CONF *conf, const char *file, long *eline)
-+{
-+    if (conf == NULL) {
-+        CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF);
-+        return 0;
-+    }
-+
-+    return conf->meth->load(conf, file, eline);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+int NCONF_load_fp(CONF *conf, FILE *fp, long *eline)
-+{
-+    BIO *btmp;
-+    int ret;
-+    if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
-+        CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB);
-+        return 0;
-+    }
-+    ret = NCONF_load_bio(conf, btmp, eline);
-+    BIO_free(btmp);
-+    return ret;
-+}
-+#endif
-+
-+int NCONF_load_bio(CONF *conf, BIO *bp, long *eline)
-+{
-+    if (conf == NULL) {
-+        CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF);
-+        return 0;
-+    }
-+
-+    return conf->meth->load_bio(conf, bp, eline);
-+}
-+
-+STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section)
-+{
-+    if (conf == NULL) {
-+        CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF);
-+        return NULL;
-+    }
-+
-+    if (section == NULL) {
-+        CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION);
-+        return NULL;
-+    }
-+
-+    return _CONF_get_section_values(conf, section);
-+}
-+
-+char *NCONF_get_string(const CONF *conf, const char *group, const char *name)
-+{
-+    char *s = _CONF_get_string(conf, group, name);
-+
-+    /*
-+     * Since we may get a value from an environment variable even if conf is
-+     * NULL, let's check the value first
-+     */
-+    if (s)
-+        return s;
-+
-+    if (conf == NULL) {
-+        CONFerr(CONF_F_NCONF_GET_STRING,
-+                CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE);
-+        return NULL;
-+    }
-+    CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE);
-+    ERR_add_error_data(4, "group=", group, " name=", name);
-+    return NULL;
-+}
-+
-+int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
-+                       long *result)
-+{
-+    char *str;
-+
-+    if (result == NULL) {
-+        CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+
-+    str = NCONF_get_string(conf, group, name);
-+
-+    if (str == NULL)
-+        return 0;
-+
-+    for (*result = 0; conf->meth->is_number(conf, *str);) {
-+        *result = (*result) * 10 + conf->meth->to_int(conf, *str);
-+        str++;
-+    }
-+
-+    return 1;
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+int NCONF_dump_fp(const CONF *conf, FILE *out)
-+{
-+    BIO *btmp;
-+    int ret;
-+    if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) {
-+        CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB);
-+        return 0;
-+    }
-+    ret = NCONF_dump_bio(conf, btmp);
-+    BIO_free(btmp);
-+    return ret;
-+}
-+#endif
-+
-+int NCONF_dump_bio(const CONF *conf, BIO *out)
-+{
-+    if (conf == NULL) {
-+        CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF);
-+        return 0;
-+    }
-+
-+    return conf->meth->dump(conf, out);
-+}
-+
-+/*
-+ * These routines call the C malloc/free, to avoid intermixing with
-+ * OpenSSL function pointers before the library is initialized.
-+ */
-+OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void)
-+{
-+    OPENSSL_INIT_SETTINGS *ret = malloc(sizeof(*ret));
-+
-+    if (ret != NULL)
-+        memset(ret, 0, sizeof(*ret));
-+    return ret;
-+}
-+
-+
-+#ifndef OPENSSL_NO_STDIO
-+int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings,
-+                                    const char *appname)
-+{
-+    char *newappname = NULL;
-+
-+    if (appname != NULL) {
-+        newappname = strdup(appname);
-+        if (newappname == NULL)
-+            return 0;
-+    }
-+
-+    free(settings->appname);
-+    settings->appname = newappname;
-+
-+    return 1;
-+}
-+#endif
-+
-+void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings)
-+{
-+    free(settings->appname);
-+    free(settings);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_mall.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_mall.c
-new file mode 100644
-index 0000000..4e7a434
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_mall.c
-@@ -0,0 +1,29 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+/* Load all OpenSSL builtin modules */
-+
-+void OPENSSL_load_builtin_modules(void)
-+{
-+    /* Add builtin modules here */
-+    ASN1_add_oid_module();
-+    ASN1_add_stable_module();
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_add_conf_module();
-+#endif
-+    EVP_add_alg_module();
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_mod.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_mod.c
-new file mode 100644
-index 0000000..31f838e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_mod.c
-@@ -0,0 +1,549 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include "internal/conf.h"
-+#include "internal/dso.h"
-+#include 
-+
-+#define DSO_mod_init_name "OPENSSL_init"
-+#define DSO_mod_finish_name "OPENSSL_finish"
-+
-+/*
-+ * This structure contains a data about supported modules. entries in this
-+ * table correspond to either dynamic or static modules.
-+ */
-+
-+struct conf_module_st {
-+    /* DSO of this module or NULL if static */
-+    DSO *dso;
-+    /* Name of the module */
-+    char *name;
-+    /* Init function */
-+    conf_init_func *init;
-+    /* Finish function */
-+    conf_finish_func *finish;
-+    /* Number of successfully initialized modules */
-+    int links;
-+    void *usr_data;
-+};
-+
-+/*
-+ * This structure contains information about modules that have been
-+ * successfully initialized. There may be more than one entry for a given
-+ * module.
-+ */
-+
-+struct conf_imodule_st {
-+    CONF_MODULE *pmod;
-+    char *name;
-+    char *value;
-+    unsigned long flags;
-+    void *usr_data;
-+};
-+
-+static STACK_OF(CONF_MODULE) *supported_modules = NULL;
-+static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
-+
-+static void module_free(CONF_MODULE *md);
-+static void module_finish(CONF_IMODULE *imod);
-+static int module_run(const CONF *cnf, const char *name, const char *value,
-+                      unsigned long flags);
-+static CONF_MODULE *module_add(DSO *dso, const char *name,
-+                               conf_init_func *ifunc,
-+                               conf_finish_func *ffunc);
-+static CONF_MODULE *module_find(const char *name);
-+static int module_init(CONF_MODULE *pmod, const char *name, const char *value,
-+                       const CONF *cnf);
-+static CONF_MODULE *module_load_dso(const CONF *cnf, const char *name,
-+                                    const char *value);
-+
-+/* Main function: load modules from a CONF structure */
-+
-+int CONF_modules_load(const CONF *cnf, const char *appname,
-+                      unsigned long flags)
-+{
-+    STACK_OF(CONF_VALUE) *values;
-+    CONF_VALUE *vl;
-+    char *vsection = NULL;
-+
-+    int ret, i;
-+
-+    if (!cnf)
-+        return 1;
-+
-+    if (appname)
-+        vsection = NCONF_get_string(cnf, NULL, appname);
-+
-+    if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
-+        vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
-+
-+    if (!vsection) {
-+        ERR_clear_error();
-+        return 1;
-+    }
-+
-+    values = NCONF_get_section(cnf, vsection);
-+
-+    if (!values)
-+        return 0;
-+
-+    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
-+        vl = sk_CONF_VALUE_value(values, i);
-+        ret = module_run(cnf, vl->name, vl->value, flags);
-+        if (ret <= 0)
-+            if (!(flags & CONF_MFLAGS_IGNORE_ERRORS))
-+                return ret;
-+    }
-+
-+    return 1;
-+
-+}
-+
-+int CONF_modules_load_file(const char *filename, const char *appname,
-+                           unsigned long flags)
-+{
-+    char *file = NULL;
-+    CONF *conf = NULL;
-+    int ret = 0;
-+    conf = NCONF_new(NULL);
-+    if (conf == NULL)
-+        goto err;
-+
-+    if (filename == NULL) {
-+        file = CONF_get1_default_config_file();
-+        if (!file)
-+            goto err;
-+    } else
-+        file = (char *)filename;
-+
-+    if (NCONF_load(conf, file, NULL) <= 0) {
-+        if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
-+            (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) {
-+            ERR_clear_error();
-+            ret = 1;
-+        }
-+        goto err;
-+    }
-+
-+    ret = CONF_modules_load(conf, appname, flags);
-+
-+ err:
-+    if (filename == NULL)
-+        OPENSSL_free(file);
-+    NCONF_free(conf);
-+
-+    return ret;
-+}
-+
-+static int module_run(const CONF *cnf, const char *name, const char *value,
-+                      unsigned long flags)
-+{
-+    CONF_MODULE *md;
-+    int ret;
-+
-+    md = module_find(name);
-+
-+    /* Module not found: try to load DSO */
-+    if (!md && !(flags & CONF_MFLAGS_NO_DSO))
-+        md = module_load_dso(cnf, name, value);
-+
-+    if (!md) {
-+        if (!(flags & CONF_MFLAGS_SILENT)) {
-+            CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);
-+            ERR_add_error_data(2, "module=", name);
-+        }
-+        return -1;
-+    }
-+
-+    ret = module_init(md, name, value, cnf);
-+
-+    if (ret <= 0) {
-+        if (!(flags & CONF_MFLAGS_SILENT)) {
-+            char rcode[DECIMAL_SIZE(ret) + 1];
-+            CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);
-+            BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);
-+            ERR_add_error_data(6, "module=", name, ", value=", value,
-+                               ", retcode=", rcode);
-+        }
-+    }
-+
-+    return ret;
-+}
-+
-+/* Load a module from a DSO */
-+static CONF_MODULE *module_load_dso(const CONF *cnf,
-+                                    const char *name, const char *value)
-+{
-+    DSO *dso = NULL;
-+    conf_init_func *ifunc;
-+    conf_finish_func *ffunc;
-+    const char *path = NULL;
-+    int errcode = 0;
-+    CONF_MODULE *md;
-+    /* Look for alternative path in module section */
-+    path = NCONF_get_string(cnf, value, "path");
-+    if (!path) {
-+        ERR_clear_error();
-+        path = name;
-+    }
-+    dso = DSO_load(NULL, path, NULL, 0);
-+    if (!dso) {
-+        errcode = CONF_R_ERROR_LOADING_DSO;
-+        goto err;
-+    }
-+    ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
-+    if (!ifunc) {
-+        errcode = CONF_R_MISSING_INIT_FUNCTION;
-+        goto err;
-+    }
-+    ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
-+    /* All OK, add module */
-+    md = module_add(dso, name, ifunc, ffunc);
-+
-+    if (!md)
-+        goto err;
-+
-+    return md;
-+
-+ err:
-+    DSO_free(dso);
-+    CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);
-+    ERR_add_error_data(4, "module=", name, ", path=", path);
-+    return NULL;
-+}
-+
-+/* add module to list */
-+static CONF_MODULE *module_add(DSO *dso, const char *name,
-+                               conf_init_func *ifunc, conf_finish_func *ffunc)
-+{
-+    CONF_MODULE *tmod = NULL;
-+    if (supported_modules == NULL)
-+        supported_modules = sk_CONF_MODULE_new_null();
-+    if (supported_modules == NULL)
-+        return NULL;
-+    tmod = OPENSSL_zalloc(sizeof(*tmod));
-+    if (tmod == NULL)
-+        return NULL;
-+
-+    tmod->dso = dso;
-+    tmod->name = OPENSSL_strdup(name);
-+    tmod->init = ifunc;
-+    tmod->finish = ffunc;
-+    if (tmod->name == NULL) {
-+        OPENSSL_free(tmod);
-+        return NULL;
-+    }
-+
-+    if (!sk_CONF_MODULE_push(supported_modules, tmod)) {
-+        OPENSSL_free(tmod->name);
-+        OPENSSL_free(tmod);
-+        return NULL;
-+    }
-+
-+    return tmod;
-+}
-+
-+/*
-+ * Find a module from the list. We allow module names of the form
-+ * modname.XXXX to just search for modname to allow the same module to be
-+ * initialized more than once.
-+ */
-+
-+static CONF_MODULE *module_find(const char *name)
-+{
-+    CONF_MODULE *tmod;
-+    int i, nchar;
-+    char *p;
-+    p = strrchr(name, '.');
-+
-+    if (p)
-+        nchar = p - name;
-+    else
-+        nchar = strlen(name);
-+
-+    for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) {
-+        tmod = sk_CONF_MODULE_value(supported_modules, i);
-+        if (strncmp(tmod->name, name, nchar) == 0)
-+            return tmod;
-+    }
-+
-+    return NULL;
-+
-+}
-+
-+/* initialize a module */
-+static int module_init(CONF_MODULE *pmod, const char *name, const char *value,
-+                       const CONF *cnf)
-+{
-+    int ret = 1;
-+    int init_called = 0;
-+    CONF_IMODULE *imod = NULL;
-+
-+    /* Otherwise add initialized module to list */
-+    imod = OPENSSL_malloc(sizeof(*imod));
-+    if (imod == NULL)
-+        goto err;
-+
-+    imod->pmod = pmod;
-+    imod->name = OPENSSL_strdup(name);
-+    imod->value = OPENSSL_strdup(value);
-+    imod->usr_data = NULL;
-+
-+    if (!imod->name || !imod->value)
-+        goto memerr;
-+
-+    /* Try to initialize module */
-+    if (pmod->init) {
-+        ret = pmod->init(imod, cnf);
-+        init_called = 1;
-+        /* Error occurred, exit */
-+        if (ret <= 0)
-+            goto err;
-+    }
-+
-+    if (initialized_modules == NULL) {
-+        initialized_modules = sk_CONF_IMODULE_new_null();
-+        if (!initialized_modules) {
-+            CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    }
-+
-+    if (!sk_CONF_IMODULE_push(initialized_modules, imod)) {
-+        CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    pmod->links++;
-+
-+    return ret;
-+
-+ err:
-+
-+    /* We've started the module so we'd better finish it */
-+    if (pmod->finish && init_called)
-+        pmod->finish(imod);
-+
-+ memerr:
-+    if (imod) {
-+        OPENSSL_free(imod->name);
-+        OPENSSL_free(imod->value);
-+        OPENSSL_free(imod);
-+    }
-+
-+    return -1;
-+
-+}
-+
-+/*
-+ * Unload any dynamic modules that have a link count of zero: i.e. have no
-+ * active initialized modules. If 'all' is set then all modules are unloaded
-+ * including static ones.
-+ */
-+
-+void CONF_modules_unload(int all)
-+{
-+    int i;
-+    CONF_MODULE *md;
-+    CONF_modules_finish();
-+    /* unload modules in reverse order */
-+    for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) {
-+        md = sk_CONF_MODULE_value(supported_modules, i);
-+        /* If static or in use and 'all' not set ignore it */
-+        if (((md->links > 0) || !md->dso) && !all)
-+            continue;
-+        /* Since we're working in reverse this is OK */
-+        (void)sk_CONF_MODULE_delete(supported_modules, i);
-+        module_free(md);
-+    }
-+    if (sk_CONF_MODULE_num(supported_modules) == 0) {
-+        sk_CONF_MODULE_free(supported_modules);
-+        supported_modules = NULL;
-+    }
-+}
-+
-+/* unload a single module */
-+static void module_free(CONF_MODULE *md)
-+{
-+    DSO_free(md->dso);
-+    OPENSSL_free(md->name);
-+    OPENSSL_free(md);
-+}
-+
-+/* finish and free up all modules instances */
-+
-+void CONF_modules_finish(void)
-+{
-+    CONF_IMODULE *imod;
-+    while (sk_CONF_IMODULE_num(initialized_modules) > 0) {
-+        imod = sk_CONF_IMODULE_pop(initialized_modules);
-+        module_finish(imod);
-+    }
-+    sk_CONF_IMODULE_free(initialized_modules);
-+    initialized_modules = NULL;
-+}
-+
-+/* finish a module instance */
-+
-+static void module_finish(CONF_IMODULE *imod)
-+{
-+    if (!imod)
-+        return;
-+    if (imod->pmod->finish)
-+        imod->pmod->finish(imod);
-+    imod->pmod->links--;
-+    OPENSSL_free(imod->name);
-+    OPENSSL_free(imod->value);
-+    OPENSSL_free(imod);
-+}
-+
-+/* Add a static module to OpenSSL */
-+
-+int CONF_module_add(const char *name, conf_init_func *ifunc,
-+                    conf_finish_func *ffunc)
-+{
-+    if (module_add(NULL, name, ifunc, ffunc))
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+void conf_modules_free_int(void)
-+{
-+    CONF_modules_finish();
-+    CONF_modules_unload(1);
-+}
-+
-+/* Utility functions */
-+
-+const char *CONF_imodule_get_name(const CONF_IMODULE *md)
-+{
-+    return md->name;
-+}
-+
-+const char *CONF_imodule_get_value(const CONF_IMODULE *md)
-+{
-+    return md->value;
-+}
-+
-+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
-+{
-+    return md->usr_data;
-+}
-+
-+void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
-+{
-+    md->usr_data = usr_data;
-+}
-+
-+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
-+{
-+    return md->pmod;
-+}
-+
-+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
-+{
-+    return md->flags;
-+}
-+
-+void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
-+{
-+    md->flags = flags;
-+}
-+
-+void *CONF_module_get_usr_data(CONF_MODULE *pmod)
-+{
-+    return pmod->usr_data;
-+}
-+
-+void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
-+{
-+    pmod->usr_data = usr_data;
-+}
-+
-+/* Return default config file name */
-+
-+char *CONF_get1_default_config_file(void)
-+{
-+    char *file;
-+    int len;
-+
-+    file = getenv("OPENSSL_CONF");
-+    if (file)
-+        return OPENSSL_strdup(file);
-+
-+    len = strlen(X509_get_default_cert_area());
-+#ifndef OPENSSL_SYS_VMS
-+    len++;
-+#endif
-+    len += strlen(OPENSSL_CONF);
-+
-+    file = OPENSSL_malloc(len + 1);
-+
-+    if (file == NULL)
-+        return NULL;
-+    OPENSSL_strlcpy(file, X509_get_default_cert_area(), len + 1);
-+#ifndef OPENSSL_SYS_VMS
-+    OPENSSL_strlcat(file, "/", len + 1);
-+#endif
-+    OPENSSL_strlcat(file, OPENSSL_CONF, len + 1);
-+
-+    return file;
-+}
-+
-+/*
-+ * This function takes a list separated by 'sep' and calls the callback
-+ * function giving the start and length of each member optionally stripping
-+ * leading and trailing whitespace. This can be used to parse comma separated
-+ * lists for example.
-+ */
-+
-+int CONF_parse_list(const char *list_, int sep, int nospc,
-+                    int (*list_cb) (const char *elem, int len, void *usr),
-+                    void *arg)
-+{
-+    int ret;
-+    const char *lstart, *tmpend, *p;
-+
-+    if (list_ == NULL) {
-+        CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
-+        return 0;
-+    }
-+
-+    lstart = list_;
-+    for (;;) {
-+        if (nospc) {
-+            while (*lstart && isspace((unsigned char)*lstart))
-+                lstart++;
-+        }
-+        p = strchr(lstart, sep);
-+        if (p == lstart || !*lstart)
-+            ret = list_cb(NULL, 0, arg);
-+        else {
-+            if (p)
-+                tmpend = p - 1;
-+            else
-+                tmpend = lstart + strlen(lstart) - 1;
-+            if (nospc) {
-+                while (isspace((unsigned char)*tmpend))
-+                    tmpend--;
-+            }
-+            ret = list_cb(lstart, tmpend - lstart + 1, arg);
-+        }
-+        if (ret <= 0)
-+            return ret;
-+        if (p == NULL)
-+            return 1;
-+        lstart = p + 1;
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_sap.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_sap.c
-new file mode 100644
-index 0000000..bed95ab
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/conf_sap.c
-@@ -0,0 +1,60 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+/*
-+ * This is the automatic configuration loader: it is called automatically by
-+ * OpenSSL when any of a number of standard initialisation functions are
-+ * called, unless this is overridden by calling OPENSSL_no_config()
-+ */
-+
-+static int openssl_configured = 0;
-+
-+#if OPENSSL_API_COMPAT < 0x10100000L
-+void OPENSSL_config(const char *appname)
-+{
-+    OPENSSL_INIT_SETTINGS settings;
-+
-+    memset(&settings, 0, sizeof(settings));
-+    if (appname != NULL)
-+        settings.appname = strdup(appname);
-+    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, &settings);
-+}
-+#endif
-+
-+void openssl_config_int(const char *appname)
-+{
-+    if (openssl_configured)
-+        return;
-+
-+    OPENSSL_load_builtin_modules();
-+#ifndef OPENSSL_NO_ENGINE
-+    /* Need to load ENGINEs */
-+    ENGINE_load_builtin_engines();
-+#endif
-+    ERR_clear_error();
-+#ifndef OPENSSL_SYS_UEFI
-+    CONF_modules_load_file(NULL, appname,
-+                               CONF_MFLAGS_DEFAULT_SECTION |
-+                               CONF_MFLAGS_IGNORE_MISSING_FILE);
-+#endif
-+    openssl_configured = 1;
-+}
-+
-+void openssl_no_config_int(void)
-+{
-+    openssl_configured = 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/keysets.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/keysets.pl
-new file mode 100644
-index 0000000..5af08ae
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/conf/keysets.pl
-@@ -0,0 +1,141 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+$NUMBER=0x01;
-+$UPPER=0x02;
-+$LOWER=0x04;
-+$UNDER=0x100;
-+$PUNCTUATION=0x200;
-+$WS=0x10;
-+$ESC=0x20;
-+$QUOTE=0x40;
-+$DQUOTE=0x400;
-+$COMMENT=0x80;
-+$FCOMMENT=0x800;
-+$EOF=0x08;
-+$HIGHBIT=0x1000;
-+
-+foreach (0 .. 255)
-+	{
-+	$v=0;
-+	$c=sprintf("%c",$_);
-+	$v|=$NUMBER	if ($c =~ /[0-9]/);
-+	$v|=$UPPER	if ($c =~ /[A-Z]/);
-+	$v|=$LOWER	if ($c =~ /[a-z]/);
-+	$v|=$UNDER	if ($c =~ /_/);
-+	$v|=$PUNCTUATION if ($c =~ /[!\.%&\*\+,\/;\?\@\^\~\|-]/);
-+	$v|=$WS		if ($c =~ /[ \t\r\n]/);
-+	$v|=$ESC	if ($c =~ /\\/);
-+	$v|=$QUOTE	if ($c =~ /['`"]/); # for emacs: "`'}/)
-+	$v|=$COMMENT	if ($c =~ /\#/);
-+	$v|=$EOF	if ($c =~ /\0/);
-+	$v|=$HIGHBIT	if ($c =~/[\x80-\xff]/);
-+
-+	push(@V_def,$v);
-+	}
-+
-+foreach (0 .. 255)
-+	{
-+	$v=0;
-+	$c=sprintf("%c",$_);
-+	$v|=$NUMBER	if ($c =~ /[0-9]/);
-+	$v|=$UPPER	if ($c =~ /[A-Z]/);
-+	$v|=$LOWER	if ($c =~ /[a-z]/);
-+	$v|=$UNDER	if ($c =~ /_/);
-+	$v|=$PUNCTUATION if ($c =~ /[!\.%&\*\+,\/;\?\@\^\~\|-]/);
-+	$v|=$WS		if ($c =~ /[ \t\r\n]/);
-+	$v|=$DQUOTE	if ($c =~ /["]/); # for emacs: "}/)
-+	$v|=$FCOMMENT	if ($c =~ /;/);
-+	$v|=$EOF	if ($c =~ /\0/);
-+	$v|=$HIGHBIT	if ($c =~/[\x80-\xff]/);
-+
-+	push(@V_w32,$v);
-+	}
-+
-+print <<"EOF";
-+/*
-+ * WARNING: do not edit!
-+ * Generated by crypto/conf/keysets.pl
-+ *
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#define CONF_NUMBER             $NUMBER
-+#define CONF_UPPER              $UPPER
-+#define CONF_LOWER              $LOWER
-+#define CONF_UNDER              $UNDER
-+#define CONF_PUNCTUATION        $PUNCTUATION
-+#define CONF_WS                 $WS
-+#define CONF_ESC                $ESC
-+#define CONF_QUOTE              $QUOTE
-+#define CONF_DQUOTE             $DQUOTE
-+#define CONF_COMMENT            $COMMENT
-+#define CONF_FCOMMENT           $FCOMMENT
-+#define CONF_EOF                $EOF
-+#define CONF_HIGHBIT            $HIGHBIT
-+#define CONF_ALPHA              (CONF_UPPER|CONF_LOWER)
-+#define CONF_ALPHA_NUMERIC      (CONF_ALPHA|CONF_NUMBER|CONF_UNDER)
-+#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \\
-+                                        CONF_PUNCTUATION)
-+
-+#define KEYTYPES(c)             ((const unsigned short *)((c)->meth_data))
-+#ifndef CHARSET_EBCDIC
-+# define IS_COMMENT(c,a)         (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT)
-+# define IS_FCOMMENT(c,a)        (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
-+# define IS_EOF(c,a)             (KEYTYPES(c)[(a)&0xff]&CONF_EOF)
-+# define IS_ESC(c,a)             (KEYTYPES(c)[(a)&0xff]&CONF_ESC)
-+# define IS_NUMBER(c,a)          (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
-+# define IS_WS(c,a)              (KEYTYPES(c)[(a)&0xff]&CONF_WS)
-+# define IS_ALPHA_NUMERIC(c,a)   (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
-+# define IS_ALPHA_NUMERIC_PUNCT(c,a) \\
-+                                (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
-+# define IS_QUOTE(c,a)           (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
-+# define IS_DQUOTE(c,a)          (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
-+# define IS_HIGHBIT(c,a)         (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
-+
-+#else                           /* CHARSET_EBCDIC */
-+
-+# define IS_COMMENT(c,a)         (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_COMMENT)
-+# define IS_FCOMMENT(c,a)        (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_FCOMMENT)
-+# define IS_EOF(c,a)             (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_EOF)
-+# define IS_ESC(c,a)             (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_ESC)
-+# define IS_NUMBER(c,a)          (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_NUMBER)
-+# define IS_WS(c,a)              (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_WS)
-+# define IS_ALPHA_NUMERIC(c,a)   (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_ALPHA_NUMERIC)
-+# define IS_ALPHA_NUMERIC_PUNCT(c,a) \\
-+                                (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_ALPHA_NUMERIC_PUNCT)
-+# define IS_QUOTE(c,a)           (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_QUOTE)
-+# define IS_DQUOTE(c,a)          (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_DQUOTE)
-+# define IS_HIGHBIT(c,a)         (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_HIGHBIT)
-+#endif                          /* CHARSET_EBCDIC */
-+
-+EOF
-+
-+print "static const unsigned short CONF_type_default[256] = {";
-+
-+for ($i=0; $i<256; $i++)
-+	{
-+	print "\n   " if ($i % 8) == 0;
-+	printf " 0x%04X,",$V_def[$i];
-+	}
-+
-+print "\n};\n\n";
-+
-+print "static const unsigned short CONF_type_win32[256] = {";
-+
-+for ($i=0; $i<256; $i++)
-+	{
-+	print "\n   " if ($i % 8) == 0;
-+	printf " 0x%04X,",$V_w32[$i];
-+	}
-+
-+print "\n};\n";
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cpt_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cpt_err.c
-new file mode 100644
-index 0000000..c28dcf1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cpt_err.c
-@@ -0,0 +1,55 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CRYPTO,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CRYPTO,0,reason)
-+
-+static ERR_STRING_DATA CRYPTO_str_functs[] = {
-+    {ERR_FUNC(CRYPTO_F_CRYPTO_DUP_EX_DATA), "CRYPTO_dup_ex_data"},
-+    {ERR_FUNC(CRYPTO_F_CRYPTO_FREE_EX_DATA), "CRYPTO_free_ex_data"},
-+    {ERR_FUNC(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX), "CRYPTO_get_ex_new_index"},
-+    {ERR_FUNC(CRYPTO_F_CRYPTO_MEMDUP), "CRYPTO_memdup"},
-+    {ERR_FUNC(CRYPTO_F_CRYPTO_NEW_EX_DATA), "CRYPTO_new_ex_data"},
-+    {ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA), "CRYPTO_set_ex_data"},
-+    {ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"},
-+    {ERR_FUNC(CRYPTO_F_GET_AND_LOCK), "get_and_lock"},
-+    {ERR_FUNC(CRYPTO_F_OPENSSL_BUF2HEXSTR), "OPENSSL_buf2hexstr"},
-+    {ERR_FUNC(CRYPTO_F_OPENSSL_HEXSTR2BUF), "OPENSSL_hexstr2buf"},
-+    {ERR_FUNC(CRYPTO_F_OPENSSL_INIT_CRYPTO), "OPENSSL_init_crypto"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA CRYPTO_str_reasons[] = {
-+    {ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"},
-+    {ERR_REASON(CRYPTO_R_ILLEGAL_HEX_DIGIT), "illegal hex digit"},
-+    {ERR_REASON(CRYPTO_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_CRYPTO_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, CRYPTO_str_functs);
-+        ERR_load_strings(0, CRYPTO_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cryptlib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cryptlib.c
-new file mode 100644
-index 0000000..01b8ce5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cryptlib.c
-@@ -0,0 +1,341 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * ECDH support in OpenSSL originally developed by
-+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
-+ */
-+
-+#include "internal/cryptlib_int.h"
-+#include 
-+
-+#if     defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
-+        defined(__x86_64) || defined(__x86_64__) || \
-+        defined(_M_AMD64) || defined(_M_X64)
-+
-+extern unsigned int OPENSSL_ia32cap_P[4];
-+
-+# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
-+#include 
-+#  define OPENSSL_CPUID_SETUP
-+typedef uint64_t IA32CAP;
-+void OPENSSL_cpuid_setup(void)
-+{
-+    static int trigger = 0;
-+    IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
-+    IA32CAP vec;
-+    char *env;
-+
-+    if (trigger)
-+        return;
-+
-+    trigger = 1;
-+    if ((env = getenv("OPENSSL_ia32cap"))) {
-+        int off = (env[0] == '~') ? 1 : 0;
-+#  if defined(_WIN32)
-+        if (!sscanf(env + off, "%I64i", &vec))
-+            vec = strtoul(env + off, NULL, 0);
-+#  else
-+        if (!sscanf(env + off, "%lli", (long long *)&vec))
-+            vec = strtoul(env + off, NULL, 0);
-+#  endif
-+        if (off)
-+            vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
-+        else if (env[0] == ':')
-+            vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
-+
-+        OPENSSL_ia32cap_P[2] = 0;
-+        if ((env = strchr(env, ':'))) {
-+            unsigned int vecx;
-+            env++;
-+            off = (env[0] == '~') ? 1 : 0;
-+            vecx = strtoul(env + off, NULL, 0);
-+            if (off)
-+                OPENSSL_ia32cap_P[2] &= ~vecx;
-+            else
-+                OPENSSL_ia32cap_P[2] = vecx;
-+        }
-+    } else
-+        vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
-+
-+    /*
-+     * |(1<<10) sets a reserved bit to signal that variable
-+     * was initialized already... This is to avoid interference
-+     * with cpuid snippets in ELF .init segment.
-+     */
-+    OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
-+    OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
-+}
-+# else
-+unsigned int OPENSSL_ia32cap_P[4];
-+# endif
-+#endif
-+int OPENSSL_NONPIC_relocated = 0;
-+#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
-+void OPENSSL_cpuid_setup(void)
-+{
-+}
-+#endif
-+
-+#if defined(_WIN32) && !defined(__CYGWIN__)
-+# include 
-+# include 
-+# ifdef __WATCOMC__
-+#  if defined(_UNICODE) || defined(__UNICODE__)
-+#   define _vsntprintf _vsnwprintf
-+#  else
-+#   define _vsntprintf _vsnprintf
-+#  endif
-+# endif
-+# ifdef _MSC_VER
-+#  define alloca _alloca
-+# endif
-+
-+# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
-+int OPENSSL_isservice(void)
-+{
-+    HWINSTA h;
-+    DWORD len;
-+    WCHAR *name;
-+    static union {
-+        void *p;
-+        FARPROC f;
-+    } _OPENSSL_isservice = {
-+        NULL
-+    };
-+
-+    if (_OPENSSL_isservice.p == NULL) {
-+        HANDLE mod = GetModuleHandle(NULL);
-+        if (mod != NULL)
-+            _OPENSSL_isservice.f = GetProcAddress(mod, "_OPENSSL_isservice");
-+        if (_OPENSSL_isservice.p == NULL)
-+            _OPENSSL_isservice.p = (void *)-1;
-+    }
-+
-+    if (_OPENSSL_isservice.p != (void *)-1)
-+        return (*_OPENSSL_isservice.f) ();
-+
-+    h = GetProcessWindowStation();
-+    if (h == NULL)
-+        return -1;
-+
-+    if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||
-+        GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-+        return -1;
-+
-+    if (len > 512)
-+        return -1;              /* paranoia */
-+    len++, len &= ~1;           /* paranoia */
-+    name = (WCHAR *)alloca(len + sizeof(WCHAR));
-+    if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
-+        return -1;
-+
-+    len++, len &= ~1;           /* paranoia */
-+    name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
-+#  if 1
-+    /*
-+     * This doesn't cover "interactive" services [working with real
-+     * WinSta0's] nor programs started non-interactively by Task Scheduler
-+     * [those are working with SAWinSta].
-+     */
-+    if (wcsstr(name, L"Service-0x"))
-+        return 1;
-+#  else
-+    /* This covers all non-interactive programs such as services. */
-+    if (!wcsstr(name, L"WinSta0"))
-+        return 1;
-+#  endif
-+    else
-+        return 0;
-+}
-+# else
-+int OPENSSL_isservice(void)
-+{
-+    return 0;
-+}
-+# endif
-+
-+void OPENSSL_showfatal(const char *fmta, ...)
-+{
-+    va_list ap;
-+    TCHAR buf[256];
-+    const TCHAR *fmt;
-+# ifdef STD_ERROR_HANDLE        /* what a dirty trick! */
-+    HANDLE h;
-+
-+    if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
-+        GetFileType(h) != FILE_TYPE_UNKNOWN) {
-+        /* must be console application */
-+        int len;
-+        DWORD out;
-+
-+        va_start(ap, fmta);
-+        len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
-+        WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);
-+        va_end(ap);
-+        return;
-+    }
-+# endif
-+
-+    if (sizeof(TCHAR) == sizeof(char))
-+        fmt = (const TCHAR *)fmta;
-+    else
-+        do {
-+            int keepgoing;
-+            size_t len_0 = strlen(fmta) + 1, i;
-+            WCHAR *fmtw;
-+
-+            fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
-+            if (fmtw == NULL) {
-+                fmt = (const TCHAR *)L"no stack?";
-+                break;
-+            }
-+            if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))
-+                for (i = 0; i < len_0; i++)
-+                    fmtw[i] = (WCHAR)fmta[i];
-+            for (i = 0; i < len_0; i++) {
-+                if (fmtw[i] == L'%')
-+                    do {
-+                        keepgoing = 0;
-+                        switch (fmtw[i + 1]) {
-+                        case L'0':
-+                        case L'1':
-+                        case L'2':
-+                        case L'3':
-+                        case L'4':
-+                        case L'5':
-+                        case L'6':
-+                        case L'7':
-+                        case L'8':
-+                        case L'9':
-+                        case L'.':
-+                        case L'*':
-+                        case L'-':
-+                            i++;
-+                            keepgoing = 1;
-+                            break;
-+                        case L's':
-+                            fmtw[i + 1] = L'S';
-+                            break;
-+                        case L'S':
-+                            fmtw[i + 1] = L's';
-+                            break;
-+                        case L'c':
-+                            fmtw[i + 1] = L'C';
-+                            break;
-+                        case L'C':
-+                            fmtw[i + 1] = L'c';
-+                            break;
-+                        }
-+                    } while (keepgoing);
-+            }
-+            fmt = (const TCHAR *)fmtw;
-+        } while (0);
-+
-+    va_start(ap, fmta);
-+    _vsntprintf(buf, OSSL_NELEM(buf) - 1, fmt, ap);
-+    buf[OSSL_NELEM(buf) - 1] = _T('\0');
-+    va_end(ap);
-+
-+# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
-+    /* this -------------v--- guards NT-specific calls */
-+    if (check_winnt() && OPENSSL_isservice() > 0) {
-+        HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));
-+
-+        if (hEventLog != NULL) {
-+            const TCHAR *pmsg = buf;
-+
-+            if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,
-+                             1, 0, &pmsg, NULL)) {
-+#if defined(DEBUG)
-+                /*
-+                 * We are in a situation where we tried to report a critical
-+                 * error and this failed for some reason. As a last resort,
-+                 * in debug builds, send output to the debugger or any other
-+                 * tool like DebugView which can monitor the output.
-+                 */
-+                OutputDebugString(pmsg);
-+#endif
-+            }
-+
-+            (void)DeregisterEventSource(hEventLog);
-+        }
-+    } else
-+# endif
-+        MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
-+}
-+#else
-+void OPENSSL_showfatal(const char *fmta, ...)
-+{
-+#ifndef OPENSSL_NO_STDIO
-+    va_list ap;
-+
-+    va_start(ap, fmta);
-+    vfprintf(stderr, fmta, ap);
-+    va_end(ap);
-+#endif
-+}
-+
-+int OPENSSL_isservice(void)
-+{
-+    return 0;
-+}
-+#endif
-+
-+void OPENSSL_die(const char *message, const char *file, int line)
-+{
-+    OPENSSL_showfatal("%s:%d: OpenSSL internal error: %s\n",
-+                      file, line, message);
-+#if !defined(_WIN32) || defined(__CYGWIN__)
-+    abort();
-+#else
-+    /*
-+     * Win32 abort() customarily shows a dialog, but we just did that...
-+     */
-+# if !defined(_WIN32_WCE)
-+    raise(SIGABRT);
-+# endif
-+    _exit(3);
-+#endif
-+}
-+
-+#if !defined(OPENSSL_CPUID_OBJ)
-+/* volatile unsigned char* pointers are there because
-+ * 1. Accessing a variable declared volatile via a pointer
-+ *    that lacks a volatile qualifier causes undefined behavior.
-+ * 2. When the variable itself is not volatile the compiler is
-+ *    not required to keep all those reads and can convert
-+ *    this into canonical memcmp() which doesn't read the whole block.
-+ * Pointers to volatile resolve the first problem fully. The second
-+ * problem cannot be resolved in any Standard-compliant way but this
-+ * works the problem around. Compilers typically react to
-+ * pointers to volatile by preserving the reads and writes through them.
-+ * The latter is not required by the Standard if the memory pointed to
-+ * is not volatile.
-+ * Pointers themselves are volatile in the function signature to work
-+ * around a subtle bug in gcc 4.6+ which causes writes through
-+ * pointers to volatile to not be emitted in some rare,
-+ * never needed in real life, pieces of code.
-+ */
-+int CRYPTO_memcmp(const volatile void * volatile in_a,
-+                  const volatile void * volatile in_b,
-+                  size_t len)
-+{
-+    size_t i;
-+    const volatile unsigned char *a = in_a;
-+    const volatile unsigned char *b = in_b;
-+    unsigned char x = 0;
-+
-+    for (i = 0; i < len; i++)
-+        x |= a[i] ^ b[i];
-+
-+    return x;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/build.info
-new file mode 100644
-index 0000000..3ca0e31
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]= ct_b64.c ct_err.c ct_log.c ct_oct.c ct_policy.c \
-+                         ct_prn.c ct_sct.c ct_sct_ctx.c ct_vfy.c ct_x509v3.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_b64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_b64.c
-new file mode 100644
-index 0000000..f0bf3af
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_b64.c
-@@ -0,0 +1,164 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+
-+#include "ct_locl.h"
-+
-+/*
-+ * Decodes the base64 string |in| into |out|.
-+ * A new string will be malloc'd and assigned to |out|. This will be owned by
-+ * the caller. Do not provide a pre-allocated string in |out|.
-+ */
-+static int ct_base64_decode(const char *in, unsigned char **out)
-+{
-+    size_t inlen = strlen(in);
-+    int outlen;
-+    unsigned char *outbuf = NULL;
-+
-+    if (inlen == 0) {
-+        *out = NULL;
-+        return 0;
-+    }
-+
-+    outlen = (inlen / 4) * 3;
-+    outbuf = OPENSSL_malloc(outlen);
-+    if (outbuf == NULL) {
-+        CTerr(CT_F_CT_BASE64_DECODE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen);
-+    if (outlen < 0) {
-+        CTerr(CT_F_CT_BASE64_DECODE, CT_R_BASE64_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    /* Subtract padding bytes from |outlen| */
-+    while (in[--inlen] == '=') {
-+        --outlen;
-+    }
-+
-+    *out = outbuf;
-+    return outlen;
-+err:
-+    OPENSSL_free(outbuf);
-+    return -1;
-+}
-+
-+SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
-+                         ct_log_entry_type_t entry_type, uint64_t timestamp,
-+                         const char *extensions_base64,
-+                         const char *signature_base64)
-+{
-+    SCT *sct = SCT_new();
-+    unsigned char *dec = NULL;
-+    const unsigned char* p = NULL;
-+    int declen;
-+
-+    if (sct == NULL) {
-+        CTerr(CT_F_SCT_NEW_FROM_BASE64, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    /*
-+     * RFC6962 section 4.1 says we "MUST NOT expect this to be 0", but we
-+     * can only construct SCT versions that have been defined.
-+     */
-+    if (!SCT_set_version(sct, version)) {
-+        CTerr(CT_F_SCT_NEW_FROM_BASE64, CT_R_SCT_UNSUPPORTED_VERSION);
-+        goto err;
-+    }
-+
-+    declen = ct_base64_decode(logid_base64, &dec);
-+    if (declen < 0) {
-+        CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
-+        goto err;
-+    }
-+    if (!SCT_set0_log_id(sct, dec, declen))
-+        goto err;
-+    dec = NULL;
-+
-+    declen = ct_base64_decode(extensions_base64, &dec);
-+    if (declen < 0) {
-+        CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
-+        goto err;
-+    }
-+    SCT_set0_extensions(sct, dec, declen);
-+    dec = NULL;
-+
-+    declen = ct_base64_decode(signature_base64, &dec);
-+    if (declen < 0) {
-+        CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    p = dec;
-+    if (o2i_SCT_signature(sct, &p, declen) <= 0)
-+        goto err;
-+    OPENSSL_free(dec);
-+    dec = NULL;
-+
-+    SCT_set_timestamp(sct, timestamp);
-+
-+    if (!SCT_set_log_entry_type(sct, entry_type))
-+        goto err;
-+
-+    return sct;
-+
-+ err:
-+    OPENSSL_free(dec);
-+    SCT_free(sct);
-+    return NULL;
-+}
-+
-+/*
-+ * Allocate, build and returns a new |ct_log| from input |pkey_base64|
-+ * It returns 1 on success,
-+ * 0 on decoding failure, or invalid parameter if any
-+ * -1 on internal (malloc) failure
-+ */
-+int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name)
-+{
-+    unsigned char *pkey_der = NULL;
-+    int pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der);
-+    const unsigned char *p;
-+    EVP_PKEY *pkey = NULL;
-+
-+    if (ct_log == NULL) {
-+        CTerr(CT_F_CTLOG_NEW_FROM_BASE64, ERR_R_PASSED_INVALID_ARGUMENT);
-+        return 0;
-+    }
-+
-+    if (pkey_der_len <= 0) {
-+        CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
-+        return 0;
-+    }
-+
-+    p = pkey_der;
-+    pkey = d2i_PUBKEY(NULL, &p, pkey_der_len);
-+    OPENSSL_free(pkey_der);
-+    if (pkey == NULL) {
-+        CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
-+        return 0;
-+    }
-+
-+    *ct_log = CTLOG_new(pkey, name);
-+    if (*ct_log == NULL) {
-+        EVP_PKEY_free(pkey);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_err.c
-new file mode 100644
-index 0000000..fe0778b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_err.c
-@@ -0,0 +1,87 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CT,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CT,0,reason)
-+
-+static ERR_STRING_DATA CT_str_functs[] = {
-+    {ERR_FUNC(CT_F_CTLOG_NEW), "CTLOG_new"},
-+    {ERR_FUNC(CT_F_CTLOG_NEW_FROM_BASE64), "CTLOG_new_from_base64"},
-+    {ERR_FUNC(CT_F_CTLOG_NEW_FROM_CONF), "ctlog_new_from_conf"},
-+    {ERR_FUNC(CT_F_CTLOG_STORE_LOAD_CTX_NEW), "ctlog_store_load_ctx_new"},
-+    {ERR_FUNC(CT_F_CTLOG_STORE_LOAD_FILE), "CTLOG_STORE_load_file"},
-+    {ERR_FUNC(CT_F_CTLOG_STORE_LOAD_LOG), "ctlog_store_load_log"},
-+    {ERR_FUNC(CT_F_CTLOG_STORE_NEW), "CTLOG_STORE_new"},
-+    {ERR_FUNC(CT_F_CT_BASE64_DECODE), "ct_base64_decode"},
-+    {ERR_FUNC(CT_F_CT_POLICY_EVAL_CTX_NEW), "CT_POLICY_EVAL_CTX_new"},
-+    {ERR_FUNC(CT_F_CT_V1_LOG_ID_FROM_PKEY), "ct_v1_log_id_from_pkey"},
-+    {ERR_FUNC(CT_F_I2O_SCT), "i2o_SCT"},
-+    {ERR_FUNC(CT_F_I2O_SCT_LIST), "i2o_SCT_LIST"},
-+    {ERR_FUNC(CT_F_I2O_SCT_SIGNATURE), "i2o_SCT_signature"},
-+    {ERR_FUNC(CT_F_O2I_SCT), "o2i_SCT"},
-+    {ERR_FUNC(CT_F_O2I_SCT_LIST), "o2i_SCT_LIST"},
-+    {ERR_FUNC(CT_F_O2I_SCT_SIGNATURE), "o2i_SCT_signature"},
-+    {ERR_FUNC(CT_F_SCT_CTX_NEW), "SCT_CTX_new"},
-+    {ERR_FUNC(CT_F_SCT_CTX_VERIFY), "SCT_CTX_verify"},
-+    {ERR_FUNC(CT_F_SCT_NEW), "SCT_new"},
-+    {ERR_FUNC(CT_F_SCT_NEW_FROM_BASE64), "SCT_new_from_base64"},
-+    {ERR_FUNC(CT_F_SCT_SET0_LOG_ID), "SCT_set0_log_id"},
-+    {ERR_FUNC(CT_F_SCT_SET1_EXTENSIONS), "SCT_set1_extensions"},
-+    {ERR_FUNC(CT_F_SCT_SET1_LOG_ID), "SCT_set1_log_id"},
-+    {ERR_FUNC(CT_F_SCT_SET1_SIGNATURE), "SCT_set1_signature"},
-+    {ERR_FUNC(CT_F_SCT_SET_LOG_ENTRY_TYPE), "SCT_set_log_entry_type"},
-+    {ERR_FUNC(CT_F_SCT_SET_SIGNATURE_NID), "SCT_set_signature_nid"},
-+    {ERR_FUNC(CT_F_SCT_SET_VERSION), "SCT_set_version"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA CT_str_reasons[] = {
-+    {ERR_REASON(CT_R_BASE64_DECODE_ERROR), "base64 decode error"},
-+    {ERR_REASON(CT_R_INVALID_LOG_ID_LENGTH), "invalid log id length"},
-+    {ERR_REASON(CT_R_LOG_CONF_INVALID), "log conf invalid"},
-+    {ERR_REASON(CT_R_LOG_CONF_INVALID_KEY), "log conf invalid key"},
-+    {ERR_REASON(CT_R_LOG_CONF_MISSING_DESCRIPTION),
-+     "log conf missing description"},
-+    {ERR_REASON(CT_R_LOG_CONF_MISSING_KEY), "log conf missing key"},
-+    {ERR_REASON(CT_R_LOG_KEY_INVALID), "log key invalid"},
-+    {ERR_REASON(CT_R_SCT_FUTURE_TIMESTAMP), "sct future timestamp"},
-+    {ERR_REASON(CT_R_SCT_INVALID), "sct invalid"},
-+    {ERR_REASON(CT_R_SCT_INVALID_SIGNATURE), "sct invalid signature"},
-+    {ERR_REASON(CT_R_SCT_LIST_INVALID), "sct list invalid"},
-+    {ERR_REASON(CT_R_SCT_LOG_ID_MISMATCH), "sct log id mismatch"},
-+    {ERR_REASON(CT_R_SCT_NOT_SET), "sct not set"},
-+    {ERR_REASON(CT_R_SCT_UNSUPPORTED_VERSION), "sct unsupported version"},
-+    {ERR_REASON(CT_R_UNRECOGNIZED_SIGNATURE_NID),
-+     "unrecognized signature nid"},
-+    {ERR_REASON(CT_R_UNSUPPORTED_ENTRY_TYPE), "unsupported entry type"},
-+    {ERR_REASON(CT_R_UNSUPPORTED_VERSION), "unsupported version"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_CT_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(CT_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, CT_str_functs);
-+        ERR_load_strings(0, CT_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_locl.h
-new file mode 100644
-index 0000000..9f983c9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_locl.h
-@@ -0,0 +1,216 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+/*
-+ * From RFC6962: opaque SerializedSCT<1..2^16-1>; struct { SerializedSCT
-+ * sct_list <1..2^16-1>; } SignedCertificateTimestampList;
-+ */
-+# define MAX_SCT_SIZE            65535
-+# define MAX_SCT_LIST_SIZE       MAX_SCT_SIZE
-+
-+/*
-+ * Macros to read and write integers in network-byte order.
-+ */
-+
-+#define n2s(c,s)        ((s=(((unsigned int)((c)[0]))<< 8)| \
-+                            (((unsigned int)((c)[1]))    )),c+=2)
-+
-+#define s2n(s,c)        ((c[0]=(unsigned char)(((s)>> 8)&0xff), \
-+                          c[1]=(unsigned char)(((s)    )&0xff)),c+=2)
-+
-+#define l2n3(l,c)       ((c[0]=(unsigned char)(((l)>>16)&0xff), \
-+                          c[1]=(unsigned char)(((l)>> 8)&0xff), \
-+                          c[2]=(unsigned char)(((l)    )&0xff)),c+=3)
-+
-+#define n2l8(c,l)       (l =((uint64_t)(*((c)++)))<<56, \
-+                         l|=((uint64_t)(*((c)++)))<<48, \
-+                         l|=((uint64_t)(*((c)++)))<<40, \
-+                         l|=((uint64_t)(*((c)++)))<<32, \
-+                         l|=((uint64_t)(*((c)++)))<<24, \
-+                         l|=((uint64_t)(*((c)++)))<<16, \
-+                         l|=((uint64_t)(*((c)++)))<< 8, \
-+                         l|=((uint64_t)(*((c)++))))
-+
-+#define l2n8(l,c)       (*((c)++)=(unsigned char)(((l)>>56)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>48)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>40)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>32)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>24)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)    )&0xff))
-+
-+/* Signed Certificate Timestamp */
-+struct sct_st {
-+    sct_version_t version;
-+    /* If version is not SCT_VERSION_V1, this contains the encoded SCT */
-+    unsigned char *sct;
-+    size_t sct_len;
-+    /* If version is SCT_VERSION_V1, fields below contain components of the SCT */
-+    unsigned char *log_id;
-+    size_t log_id_len;
-+    /*
-+    * Note, we cannot distinguish between an unset timestamp, and one
-+    * that is set to 0.  However since CT didn't exist in 1970, no real
-+    * SCT should ever be set as such.
-+    */
-+    uint64_t timestamp;
-+    unsigned char *ext;
-+    size_t ext_len;
-+    unsigned char hash_alg;
-+    unsigned char sig_alg;
-+    unsigned char *sig;
-+    size_t sig_len;
-+    /* Log entry type */
-+    ct_log_entry_type_t entry_type;
-+    /* Where this SCT was found, e.g. certificate, OCSP response, etc. */
-+    sct_source_t source;
-+    /* The result of the last attempt to validate this SCT. */
-+    sct_validation_status_t validation_status;
-+};
-+
-+/* Miscellaneous data that is useful when verifying an SCT  */
-+struct sct_ctx_st {
-+    /* Public key */
-+    EVP_PKEY *pkey;
-+    /* Hash of public key */
-+    unsigned char *pkeyhash;
-+    size_t pkeyhashlen;
-+    /* For pre-certificate: issuer public key hash */
-+    unsigned char *ihash;
-+    size_t ihashlen;
-+    /* certificate encoding */
-+    unsigned char *certder;
-+    size_t certderlen;
-+    /* pre-certificate encoding */
-+    unsigned char *preder;
-+    size_t prederlen;
-+    /* milliseconds since epoch (to check that the SCT isn't from the future) */
-+    uint64_t epoch_time_in_ms;
-+};
-+
-+/* Context when evaluating whether a Certificate Transparency policy is met */
-+struct ct_policy_eval_ctx_st {
-+    X509 *cert;
-+    X509 *issuer;
-+    CTLOG_STORE *log_store;
-+    /* milliseconds since epoch (to check that SCTs aren't from the future) */
-+    uint64_t epoch_time_in_ms;
-+};
-+
-+/*
-+ * Creates a new context for verifying an SCT.
-+ */
-+SCT_CTX *SCT_CTX_new(void);
-+/*
-+ * Deletes an SCT verification context.
-+ */
-+void SCT_CTX_free(SCT_CTX *sctx);
-+
-+/*
-+ * Sets the certificate that the SCT was created for.
-+ * If *cert does not have a poison extension, presigner must be NULL.
-+ * If *cert does not have a poison extension, it may have a single SCT
-+ * (NID_ct_precert_scts) extension.
-+ * If either *cert or *presigner have an AKID (NID_authority_key_identifier)
-+ * extension, both must have one.
-+ * Returns 1 on success, 0 on failure.
-+ */
-+__owur int SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner);
-+
-+/*
-+ * Sets the issuer of the certificate that the SCT was created for.
-+ * This is just a convenience method to save extracting the public key and
-+ * calling SCT_CTX_set1_issuer_pubkey().
-+ * Issuer must not be NULL.
-+ * Returns 1 on success, 0 on failure.
-+ */
-+__owur int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer);
-+
-+/*
-+ * Sets the public key of the issuer of the certificate that the SCT was created
-+ * for.
-+ * The public key must not be NULL.
-+ * Returns 1 on success, 0 on failure.
-+ */
-+__owur int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey);
-+
-+/*
-+ * Sets the public key of the CT log that the SCT is from.
-+ * Returns 1 on success, 0 on failure.
-+ */
-+__owur int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey);
-+
-+/*
-+ * Sets the time to evaluate the SCT against, in milliseconds since the Unix
-+ * epoch. If the SCT's timestamp is after this time, it will be interpreted as
-+ * having been issued in the future. RFC6962 states that "TLS clients MUST
-+ * reject SCTs whose timestamp is in the future", so an SCT will not validate
-+ * in this case.
-+ */
-+void SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms);
-+
-+/*
-+ * Verifies an SCT with the given context.
-+ * Returns 1 if the SCT verifies successfully; any other value indicates
-+ * failure. See EVP_DigestVerifyFinal() for the meaning of those values.
-+ */
-+__owur int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct);
-+
-+/*
-+ * Does this SCT have the minimum fields populated to be usable?
-+ * Returns 1 if so, 0 otherwise.
-+ */
-+__owur int SCT_is_complete(const SCT *sct);
-+
-+/*
-+ * Does this SCT have the signature-related fields populated?
-+ * Returns 1 if so, 0 otherwise.
-+ * This checks that the signature and hash algorithms are set to supported
-+ * values and that the signature field is set.
-+ */
-+__owur int SCT_signature_is_complete(const SCT *sct);
-+
-+/*
-+ * TODO(RJPercival): Create an SCT_signature struct and make i2o_SCT_signature
-+ * and o2i_SCT_signature conform to the i2d/d2i conventions.
-+ */
-+
-+/*
-+* Serialize (to TLS format) an |sct| signature and write it to |out|.
-+* If |out| is null, no signature will be output but the length will be returned.
-+* If |out| points to a null pointer, a string will be allocated to hold the
-+* TLS-format signature. It is the responsibility of the caller to free it.
-+* If |out| points to an allocated string, the signature will be written to it.
-+* The length of the signature in TLS format will be returned.
-+*/
-+__owur int i2o_SCT_signature(const SCT *sct, unsigned char **out);
-+
-+/*
-+* Parses an SCT signature in TLS format and populates the |sct| with it.
-+* |in| should be a pointer to a string containing the TLS-format signature.
-+* |in| will be advanced to the end of the signature if parsing succeeds.
-+* |len| should be the length of the signature in |in|.
-+* Returns the number of bytes parsed, or a negative integer if an error occurs.
-+* If an error occurs, the SCT's signature NID may be updated whilst the
-+* signature field itself remains unset.
-+*/
-+__owur int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len);
-+
-+/*
-+ * Handlers for Certificate Transparency X509v3/OCSP extensions
-+ */
-+extern const X509V3_EXT_METHOD v3_ct_scts[3];
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_log.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_log.c
-new file mode 100644
-index 0000000..6db4c3e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_log.c
-@@ -0,0 +1,304 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include "internal/cryptlib.h"
-+
-+/*
-+ * Information about a CT log server.
-+ */
-+struct ctlog_st {
-+    char *name;
-+    uint8_t log_id[CT_V1_HASHLEN];
-+    EVP_PKEY *public_key;
-+};
-+
-+/*
-+ * A store for multiple CTLOG instances.
-+ * It takes ownership of any CTLOG instances added to it.
-+ */
-+struct ctlog_store_st {
-+    STACK_OF(CTLOG) *logs;
-+};
-+
-+/* The context when loading a CT log list from a CONF file. */
-+typedef struct ctlog_store_load_ctx_st {
-+    CTLOG_STORE *log_store;
-+    CONF *conf;
-+    size_t invalid_log_entries;
-+} CTLOG_STORE_LOAD_CTX;
-+
-+/*
-+ * Creates an empty context for loading a CT log store.
-+ * It should be populated before use.
-+ */
-+static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new();
-+
-+/*
-+ * Deletes a CT log store load context.
-+ * Does not delete any of the fields.
-+ */
-+static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx);
-+
-+static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new()
-+{
-+    CTLOG_STORE_LOAD_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
-+
-+    if (ctx == NULL)
-+        CTerr(CT_F_CTLOG_STORE_LOAD_CTX_NEW, ERR_R_MALLOC_FAILURE);
-+
-+    return ctx;
-+}
-+
-+static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx)
-+{
-+    OPENSSL_free(ctx);
-+}
-+
-+/* Converts a log's public key into a SHA256 log ID */
-+static int ct_v1_log_id_from_pkey(EVP_PKEY *pkey,
-+                                  unsigned char log_id[CT_V1_HASHLEN])
-+{
-+    int ret = 0;
-+    unsigned char *pkey_der = NULL;
-+    int pkey_der_len = i2d_PUBKEY(pkey, &pkey_der);
-+
-+    if (pkey_der_len <= 0) {
-+        CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, CT_R_LOG_KEY_INVALID);
-+        goto err;
-+    }
-+
-+    SHA256(pkey_der, pkey_der_len, log_id);
-+    ret = 1;
-+err:
-+    OPENSSL_free(pkey_der);
-+    return ret;
-+}
-+
-+CTLOG_STORE *CTLOG_STORE_new(void)
-+{
-+    CTLOG_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        CTerr(CT_F_CTLOG_STORE_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->logs = sk_CTLOG_new_null();
-+    if (ret->logs == NULL)
-+        goto err;
-+
-+    return ret;
-+err:
-+    OPENSSL_free(ret);
-+    return NULL;
-+}
-+
-+void CTLOG_STORE_free(CTLOG_STORE *store)
-+{
-+    if (store != NULL) {
-+        sk_CTLOG_pop_free(store->logs, CTLOG_free);
-+        OPENSSL_free(store);
-+    }
-+}
-+
-+static int ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *section)
-+{
-+    const char *description = NCONF_get_string(conf, section, "description");
-+    char *pkey_base64;
-+
-+    if (description == NULL) {
-+        CTerr(CT_F_CTLOG_NEW_FROM_CONF, CT_R_LOG_CONF_MISSING_DESCRIPTION);
-+        return 0;
-+    }
-+
-+    pkey_base64 = NCONF_get_string(conf, section, "key");
-+    if (pkey_base64 == NULL) {
-+        CTerr(CT_F_CTLOG_NEW_FROM_CONF, CT_R_LOG_CONF_MISSING_KEY);
-+        return 0;
-+    }
-+
-+    return CTLOG_new_from_base64(ct_log, pkey_base64, description);
-+}
-+
-+int CTLOG_STORE_load_default_file(CTLOG_STORE *store)
-+{
-+    const char *fpath = getenv(CTLOG_FILE_EVP);
-+
-+    if (fpath == NULL)
-+      fpath = CTLOG_FILE;
-+
-+    return CTLOG_STORE_load_file(store, fpath);
-+}
-+
-+/*
-+ * Called by CONF_parse_list, which stops if this returns <= 0,
-+ * Otherwise, one bad log entry would stop loading of any of
-+ * the following log entries.
-+ * It may stop parsing and returns -1 on any internal (malloc) error.
-+ */
-+static int ctlog_store_load_log(const char *log_name, int log_name_len,
-+                                void *arg)
-+{
-+    CTLOG_STORE_LOAD_CTX *load_ctx = arg;
-+    CTLOG *ct_log = NULL;
-+    /* log_name may not be null-terminated, so fix that before using it */
-+    char *tmp;
-+    int ret = 0;
-+
-+    /* log_name will be NULL for empty list entries */
-+    if (log_name == NULL)
-+        return 1;
-+
-+    tmp = OPENSSL_strndup(log_name, log_name_len);
-+    if (tmp == NULL)
-+        goto mem_err;
-+
-+    ret = ctlog_new_from_conf(&ct_log, load_ctx->conf, tmp);
-+    OPENSSL_free(tmp);
-+
-+    if (ret < 0) {
-+        /* Propagate any internal error */
-+        return ret;
-+    }
-+    if (ret == 0) {
-+        /* If we can't load this log, record that fact and skip it */
-+        ++load_ctx->invalid_log_entries;
-+        return 1;
-+    }
-+
-+    if (!sk_CTLOG_push(load_ctx->log_store->logs, ct_log)) {
-+        goto mem_err;
-+    }
-+    return 1;
-+
-+mem_err:
-+    CTLOG_free(ct_log);
-+    CTerr(CT_F_CTLOG_STORE_LOAD_LOG, ERR_R_MALLOC_FAILURE);
-+    return -1;
-+}
-+
-+int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file)
-+{
-+    int ret = 0;
-+    char *enabled_logs;
-+    CTLOG_STORE_LOAD_CTX* load_ctx = ctlog_store_load_ctx_new();
-+
-+    load_ctx->log_store = store;
-+    load_ctx->conf = NCONF_new(NULL);
-+    if (load_ctx->conf == NULL)
-+        goto end;
-+
-+    if (NCONF_load(load_ctx->conf, file, NULL) <= 0) {
-+        CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
-+        goto end;
-+    }
-+
-+    enabled_logs = NCONF_get_string(load_ctx->conf, NULL, "enabled_logs");
-+    if (enabled_logs == NULL) {
-+        CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
-+        goto end;
-+    }
-+
-+    if (!CONF_parse_list(enabled_logs, ',', 1, ctlog_store_load_log, load_ctx) ||
-+        load_ctx->invalid_log_entries > 0) {
-+        CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
-+        goto end;
-+    }
-+
-+    ret = 1;
-+end:
-+    NCONF_free(load_ctx->conf);
-+    ctlog_store_load_ctx_free(load_ctx);
-+    return ret;
-+}
-+
-+/*
-+ * Initialize a new CTLOG object.
-+ * Takes ownership of the public key.
-+ * Copies the name.
-+ */
-+CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name)
-+{
-+    CTLOG *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->name = OPENSSL_strdup(name);
-+    if (ret->name == NULL) {
-+        CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (ct_v1_log_id_from_pkey(public_key, ret->log_id) != 1)
-+        goto err;
-+
-+    ret->public_key = public_key;
-+    return ret;
-+err:
-+    CTLOG_free(ret);
-+    return NULL;
-+}
-+
-+/* Frees CT log and associated structures */
-+void CTLOG_free(CTLOG *log)
-+{
-+    if (log != NULL) {
-+        OPENSSL_free(log->name);
-+        EVP_PKEY_free(log->public_key);
-+        OPENSSL_free(log);
-+    }
-+}
-+
-+const char *CTLOG_get0_name(const CTLOG *log)
-+{
-+    return log->name;
-+}
-+
-+void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id,
-+                       size_t *log_id_len)
-+{
-+    *log_id = log->log_id;
-+    *log_id_len = CT_V1_HASHLEN;
-+}
-+
-+EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log)
-+{
-+    return log->public_key;
-+}
-+
-+/*
-+ * Given a log ID, finds the matching log.
-+ * Returns NULL if no match found.
-+ */
-+const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store,
-+                                        const uint8_t *log_id,
-+                                        size_t log_id_len)
-+{
-+    int i;
-+
-+    for (i = 0; i < sk_CTLOG_num(store->logs); ++i) {
-+        const CTLOG *log = sk_CTLOG_value(store->logs, i);
-+        if (memcmp(log->log_id, log_id, log_id_len) == 0)
-+            return log;
-+    }
-+
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_oct.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_oct.c
-new file mode 100644
-index 0000000..0dd691c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_oct.c
-@@ -0,0 +1,407 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifdef OPENSSL_NO_CT
-+# error "CT is disabled"
-+#endif
-+
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include "ct_locl.h"
-+
-+int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len)
-+{
-+    size_t siglen;
-+    size_t len_remaining = len;
-+    const unsigned char *p;
-+
-+    if (sct->version != SCT_VERSION_V1) {
-+        CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION);
-+        return -1;
-+    }
-+    /*
-+     * digitally-signed struct header: (1 byte) Hash algorithm (1 byte)
-+     * Signature algorithm (2 bytes + ?) Signature
-+     *
-+     * This explicitly rejects empty signatures: they're invalid for
-+     * all supported algorithms.
-+     */
-+    if (len <= 4) {
-+        CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
-+        return -1;
-+    }
-+
-+    p = *in;
-+    /* Get hash and signature algorithm */
-+    sct->hash_alg = *p++;
-+    sct->sig_alg = *p++;
-+    if (SCT_get_signature_nid(sct) == NID_undef) {
-+        CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
-+        return -1;
-+    }
-+    /* Retrieve signature and check it is consistent with the buffer length */
-+    n2s(p, siglen);
-+    len_remaining -= (p - *in);
-+    if (siglen > len_remaining) {
-+        CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
-+        return -1;
-+    }
-+
-+    if (SCT_set1_signature(sct, p, siglen) != 1)
-+        return -1;
-+    len_remaining -= siglen;
-+    *in = p + siglen;
-+
-+    return len - len_remaining;
-+}
-+
-+SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len)
-+{
-+    SCT *sct = NULL;
-+    const unsigned char *p;
-+
-+    if (len == 0 || len > MAX_SCT_SIZE) {
-+        CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
-+        goto err;
-+    }
-+
-+    if ((sct = SCT_new()) == NULL)
-+        goto err;
-+
-+    p = *in;
-+
-+    sct->version = *p;
-+    if (sct->version == SCT_VERSION_V1) {
-+        int sig_len;
-+        size_t len2;
-+        /*-
-+         * Fixed-length header:
-+         *   struct {
-+         *     Version sct_version;     (1 byte)
-+         *     log_id id;               (32 bytes)
-+         *     uint64 timestamp;        (8 bytes)
-+         *     CtExtensions extensions; (2 bytes + ?)
-+         *   }
-+         */
-+        if (len < 43) {
-+            CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
-+            goto err;
-+        }
-+        len -= 43;
-+        p++;
-+        sct->log_id = BUF_memdup(p, CT_V1_HASHLEN);
-+        if (sct->log_id == NULL)
-+            goto err;
-+        sct->log_id_len = CT_V1_HASHLEN;
-+        p += CT_V1_HASHLEN;
-+
-+        n2l8(p, sct->timestamp);
-+
-+        n2s(p, len2);
-+        if (len < len2) {
-+            CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
-+            goto err;
-+        }
-+        if (len2 > 0) {
-+            sct->ext = BUF_memdup(p, len2);
-+            if (sct->ext == NULL)
-+                goto err;
-+        }
-+        sct->ext_len = len2;
-+        p += len2;
-+        len -= len2;
-+
-+        sig_len = o2i_SCT_signature(sct, &p, len);
-+        if (sig_len <= 0) {
-+            CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
-+            goto err;
-+        }
-+        len -= sig_len;
-+        *in = p + len;
-+    } else {
-+        /* If not V1 just cache encoding */
-+        sct->sct = BUF_memdup(p, len);
-+        if (sct->sct == NULL)
-+            goto err;
-+        sct->sct_len = len;
-+        *in = p + len;
-+    }
-+
-+    if (psct != NULL) {
-+        SCT_free(*psct);
-+        *psct = sct;
-+    }
-+
-+    return sct;
-+err:
-+    SCT_free(sct);
-+    return NULL;
-+}
-+
-+int i2o_SCT_signature(const SCT *sct, unsigned char **out)
-+{
-+    size_t len;
-+    unsigned char *p = NULL, *pstart = NULL;
-+
-+    if (!SCT_signature_is_complete(sct)) {
-+        CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
-+        goto err;
-+    }
-+
-+    if (sct->version != SCT_VERSION_V1) {
-+        CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION);
-+        goto err;
-+    }
-+
-+    /*
-+    * (1 byte) Hash algorithm
-+    * (1 byte) Signature algorithm
-+    * (2 bytes + ?) Signature
-+    */
-+    len = 4 + sct->sig_len;
-+
-+    if (out != NULL) {
-+        if (*out != NULL) {
-+            p = *out;
-+            *out += len;
-+        } else {
-+            pstart = p = OPENSSL_malloc(len);
-+            if (p == NULL) {
-+                CTerr(CT_F_I2O_SCT_SIGNATURE, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            *out = p;
-+        }
-+
-+        *p++ = sct->hash_alg;
-+        *p++ = sct->sig_alg;
-+        s2n(sct->sig_len, p);
-+        memcpy(p, sct->sig, sct->sig_len);
-+    }
-+
-+    return len;
-+err:
-+    OPENSSL_free(pstart);
-+    return -1;
-+}
-+
-+int i2o_SCT(const SCT *sct, unsigned char **out)
-+{
-+    size_t len;
-+    unsigned char *p = NULL, *pstart = NULL;
-+
-+    if (!SCT_is_complete(sct)) {
-+        CTerr(CT_F_I2O_SCT, CT_R_SCT_NOT_SET);
-+        goto err;
-+    }
-+    /*
-+     * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes)
-+     * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions
-+     * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2
-+     * bytes + ?) Signature
-+     */
-+    if (sct->version == SCT_VERSION_V1)
-+        len = 43 + sct->ext_len + 4 + sct->sig_len;
-+    else
-+        len = sct->sct_len;
-+
-+    if (out == NULL)
-+        return len;
-+
-+    if (*out != NULL) {
-+        p = *out;
-+        *out += len;
-+    } else {
-+        pstart = p = OPENSSL_malloc(len);
-+        if (p == NULL) {
-+            CTerr(CT_F_I2O_SCT, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        *out = p;
-+    }
-+
-+    if (sct->version == SCT_VERSION_V1) {
-+        *p++ = sct->version;
-+        memcpy(p, sct->log_id, CT_V1_HASHLEN);
-+        p += CT_V1_HASHLEN;
-+        l2n8(sct->timestamp, p);
-+        s2n(sct->ext_len, p);
-+        if (sct->ext_len > 0) {
-+            memcpy(p, sct->ext, sct->ext_len);
-+            p += sct->ext_len;
-+        }
-+        if (i2o_SCT_signature(sct, &p) <= 0)
-+            goto err;
-+    } else {
-+        memcpy(p, sct->sct, len);
-+    }
-+
-+    return len;
-+err:
-+    OPENSSL_free(pstart);
-+    return -1;
-+}
-+
-+STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
-+                            size_t len)
-+{
-+    STACK_OF(SCT) *sk = NULL;
-+    size_t list_len, sct_len;
-+
-+    if (len < 2 || len > MAX_SCT_LIST_SIZE) {
-+        CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
-+        return NULL;
-+    }
-+
-+    n2s(*pp, list_len);
-+    if (list_len != len - 2) {
-+        CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
-+        return NULL;
-+    }
-+
-+    if (a == NULL || *a == NULL) {
-+        sk = sk_SCT_new_null();
-+        if (sk == NULL)
-+            return NULL;
-+    } else {
-+        SCT *sct;
-+
-+        /* Use the given stack, but empty it first. */
-+        sk = *a;
-+        while ((sct = sk_SCT_pop(sk)) != NULL)
-+            SCT_free(sct);
-+    }
-+
-+    while (list_len > 0) {
-+        SCT *sct;
-+
-+        if (list_len < 2) {
-+            CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
-+            goto err;
-+        }
-+        n2s(*pp, sct_len);
-+        list_len -= 2;
-+
-+        if (sct_len == 0 || sct_len > list_len) {
-+            CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
-+            goto err;
-+        }
-+        list_len -= sct_len;
-+
-+        if ((sct = o2i_SCT(NULL, pp, sct_len)) == NULL)
-+            goto err;
-+        if (!sk_SCT_push(sk, sct)) {
-+            SCT_free(sct);
-+            goto err;
-+        }
-+    }
-+
-+    if (a != NULL && *a == NULL)
-+        *a = sk;
-+    return sk;
-+
-+ err:
-+    if (a == NULL || *a == NULL)
-+        SCT_LIST_free(sk);
-+    return NULL;
-+}
-+
-+int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp)
-+{
-+    int len, sct_len, i, is_pp_new = 0;
-+    size_t len2;
-+    unsigned char *p = NULL, *p2;
-+
-+    if (pp != NULL) {
-+        if (*pp == NULL) {
-+            if ((len = i2o_SCT_LIST(a, NULL)) == -1) {
-+                CTerr(CT_F_I2O_SCT_LIST, CT_R_SCT_LIST_INVALID);
-+                return -1;
-+            }
-+            if ((*pp = OPENSSL_malloc(len)) == NULL) {
-+                CTerr(CT_F_I2O_SCT_LIST, ERR_R_MALLOC_FAILURE);
-+                return -1;
-+            }
-+            is_pp_new = 1;
-+        }
-+        p = *pp + 2;
-+    }
-+
-+    len2 = 2;
-+    for (i = 0; i < sk_SCT_num(a); i++) {
-+        if (pp != NULL) {
-+            p2 = p;
-+            p += 2;
-+            if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1)
-+                goto err;
-+            s2n(sct_len, p2);
-+        } else {
-+          if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1)
-+              goto err;
-+        }
-+        len2 += 2 + sct_len;
-+    }
-+
-+    if (len2 > MAX_SCT_LIST_SIZE)
-+        goto err;
-+
-+    if (pp != NULL) {
-+        p = *pp;
-+        s2n(len2 - 2, p);
-+        if (!is_pp_new)
-+            *pp += len2;
-+    }
-+    return len2;
-+
-+ err:
-+    if (is_pp_new) {
-+        OPENSSL_free(*pp);
-+        *pp = NULL;
-+    }
-+    return -1;
-+}
-+
-+STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
-+                            long len)
-+{
-+    ASN1_OCTET_STRING *oct = NULL;
-+    STACK_OF(SCT) *sk = NULL;
-+    const unsigned char *p;
-+
-+    p = *pp;
-+    if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL)
-+        return NULL;
-+
-+    p = oct->data;
-+    if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL)
-+        *pp += len;
-+
-+    ASN1_OCTET_STRING_free(oct);
-+    return sk;
-+}
-+
-+int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out)
-+{
-+    ASN1_OCTET_STRING oct;
-+    int len;
-+
-+    oct.data = NULL;
-+    if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1)
-+        return -1;
-+
-+    len = i2d_ASN1_OCTET_STRING(&oct, out);
-+    OPENSSL_free(oct.data);
-+    return len;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_policy.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_policy.c
-new file mode 100644
-index 0000000..0d7b346
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_policy.c
-@@ -0,0 +1,98 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifdef OPENSSL_NO_CT
-+# error "CT is disabled"
-+#endif
-+
-+#include 
-+#include 
-+#include 
-+
-+#include "ct_locl.h"
-+
-+/*
-+ * Number of seconds in the future that an SCT timestamp can be, by default,
-+ * without being considered invalid. This is added to time() when setting a
-+ * default value for CT_POLICY_EVAL_CTX.epoch_time_in_ms.
-+ * It can be overridden by calling CT_POLICY_EVAL_CTX_set_time().
-+ */
-+static const time_t SCT_CLOCK_DRIFT_TOLERANCE = 300;
-+
-+CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
-+{
-+    CT_POLICY_EVAL_CTX *ctx = OPENSSL_zalloc(sizeof(CT_POLICY_EVAL_CTX));
-+
-+    if (ctx == NULL) {
-+        CTerr(CT_F_CT_POLICY_EVAL_CTX_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    /* time(NULL) shouldn't ever fail, so don't bother checking for -1. */
-+    ctx->epoch_time_in_ms = (uint64_t)(time(NULL) + SCT_CLOCK_DRIFT_TOLERANCE) *
-+            1000;
-+
-+    return ctx;
-+}
-+
-+void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx)
-+{
-+    if (ctx == NULL)
-+        return;
-+    X509_free(ctx->cert);
-+    X509_free(ctx->issuer);
-+    OPENSSL_free(ctx);
-+}
-+
-+int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert)
-+{
-+    if (!X509_up_ref(cert))
-+        return 0;
-+    ctx->cert = cert;
-+    return 1;
-+}
-+
-+int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer)
-+{
-+    if (!X509_up_ref(issuer))
-+        return 0;
-+    ctx->issuer = issuer;
-+    return 1;
-+}
-+
-+void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx,
-+                                               CTLOG_STORE *log_store)
-+{
-+    ctx->log_store = log_store;
-+}
-+
-+void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms)
-+{
-+    ctx->epoch_time_in_ms = time_in_ms;
-+}
-+
-+X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx)
-+{
-+    return ctx->cert;
-+}
-+
-+X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx)
-+{
-+    return ctx->issuer;
-+}
-+
-+const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx)
-+{
-+    return ctx->log_store;
-+}
-+
-+uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx)
-+{
-+    return ctx->epoch_time_in_ms;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_prn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_prn.c
-new file mode 100644
-index 0000000..376e045
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_prn.c
-@@ -0,0 +1,127 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifdef OPENSSL_NO_CT
-+# error "CT is disabled"
-+#endif
-+
-+#include 
-+#include 
-+
-+#include "ct_locl.h"
-+
-+static void SCT_signature_algorithms_print(const SCT *sct, BIO *out)
-+{
-+    int nid = SCT_get_signature_nid(sct);
-+
-+    if (nid == NID_undef)
-+        BIO_printf(out, "%02X%02X", sct->hash_alg, sct->sig_alg);
-+    else
-+        BIO_printf(out, "%s", OBJ_nid2ln(nid));
-+}
-+
-+static void timestamp_print(uint64_t timestamp, BIO *out)
-+{
-+    ASN1_GENERALIZEDTIME *gen = ASN1_GENERALIZEDTIME_new();
-+    char genstr[20];
-+
-+    if (gen == NULL)
-+        return;
-+    ASN1_GENERALIZEDTIME_adj(gen, (time_t)0,
-+                             (int)(timestamp / 86400000),
-+                             (timestamp % 86400000) / 1000);
-+    /*
-+     * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15
-+     * characters long with a final Z. Update it with fractional seconds.
-+     */
-+    BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ",
-+                 ASN1_STRING_get0_data(gen), (unsigned int)(timestamp % 1000));
-+    if (ASN1_GENERALIZEDTIME_set_string(gen, genstr))
-+        ASN1_GENERALIZEDTIME_print(out, gen);
-+    ASN1_GENERALIZEDTIME_free(gen);
-+}
-+
-+const char *SCT_validation_status_string(const SCT *sct)
-+{
-+
-+    switch (SCT_get_validation_status(sct)) {
-+    case SCT_VALIDATION_STATUS_NOT_SET:
-+        return "not set";
-+    case SCT_VALIDATION_STATUS_UNKNOWN_VERSION:
-+        return "unknown version";
-+    case SCT_VALIDATION_STATUS_UNKNOWN_LOG:
-+        return "unknown log";
-+    case SCT_VALIDATION_STATUS_UNVERIFIED:
-+        return "unverified";
-+    case SCT_VALIDATION_STATUS_INVALID:
-+        return "invalid";
-+    case SCT_VALIDATION_STATUS_VALID:
-+        return "valid";
-+    }
-+    return "unknown status";
-+}
-+
-+void SCT_print(const SCT *sct, BIO *out, int indent,
-+               const CTLOG_STORE *log_store)
-+{
-+    const CTLOG *log = NULL;
-+
-+    if (log_store != NULL) {
-+        log = CTLOG_STORE_get0_log_by_id(log_store, sct->log_id,
-+                                         sct->log_id_len);
-+    }
-+
-+    BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, "");
-+    BIO_printf(out, "\n%*sVersion   : ", indent + 4, "");
-+
-+    if (sct->version != SCT_VERSION_V1) {
-+        BIO_printf(out, "unknown\n%*s", indent + 16, "");
-+        BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sct_len);
-+        return;
-+    }
-+
-+    BIO_printf(out, "v1 (0x0)");
-+
-+    if (log != NULL) {
-+        BIO_printf(out, "\n%*sLog       : %s", indent + 4, "",
-+                   CTLOG_get0_name(log));
-+    }
-+
-+    BIO_printf(out, "\n%*sLog ID    : ", indent + 4, "");
-+    BIO_hex_string(out, indent + 16, 16, sct->log_id, sct->log_id_len);
-+
-+    BIO_printf(out, "\n%*sTimestamp : ", indent + 4, "");
-+    timestamp_print(sct->timestamp, out);
-+
-+    BIO_printf(out, "\n%*sExtensions: ", indent + 4, "");
-+    if (sct->ext_len == 0)
-+        BIO_printf(out, "none");
-+    else
-+        BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len);
-+
-+    BIO_printf(out, "\n%*sSignature : ", indent + 4, "");
-+    SCT_signature_algorithms_print(sct, out);
-+    BIO_printf(out, "\n%*s            ", indent + 4, "");
-+    BIO_hex_string(out, indent + 16, 16, sct->sig, sct->sig_len);
-+}
-+
-+void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent,
-+                    const char *separator, const CTLOG_STORE *log_store)
-+{
-+    int sct_count = sk_SCT_num(sct_list);
-+    int i;
-+
-+    for (i = 0; i < sct_count; ++i) {
-+        SCT *sct = sk_SCT_value(sct_list, i);
-+
-+        SCT_print(sct, out, indent, log_store);
-+        if (i < sk_SCT_num(sct_list) - 1)
-+            BIO_printf(out, "%s", separator);
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_sct.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_sct.c
-new file mode 100644
-index 0000000..cd2cf60
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_sct.c
-@@ -0,0 +1,393 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifdef OPENSSL_NO_CT
-+# error "CT disabled"
-+#endif
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include "ct_locl.h"
-+
-+SCT *SCT_new(void)
-+{
-+    SCT *sct = OPENSSL_zalloc(sizeof(*sct));
-+
-+    if (sct == NULL) {
-+        CTerr(CT_F_SCT_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    sct->entry_type = CT_LOG_ENTRY_TYPE_NOT_SET;
-+    sct->version = SCT_VERSION_NOT_SET;
-+    return sct;
-+}
-+
-+void SCT_free(SCT *sct)
-+{
-+    if (sct == NULL)
-+        return;
-+
-+    OPENSSL_free(sct->log_id);
-+    OPENSSL_free(sct->ext);
-+    OPENSSL_free(sct->sig);
-+    OPENSSL_free(sct->sct);
-+    OPENSSL_free(sct);
-+}
-+
-+void SCT_LIST_free(STACK_OF(SCT) *a)
-+{
-+    sk_SCT_pop_free(a, SCT_free);
-+}
-+
-+int SCT_set_version(SCT *sct, sct_version_t version)
-+{
-+    if (version != SCT_VERSION_V1) {
-+        CTerr(CT_F_SCT_SET_VERSION, CT_R_UNSUPPORTED_VERSION);
-+        return 0;
-+    }
-+    sct->version = version;
-+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+    return 1;
-+}
-+
-+int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type)
-+{
-+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+
-+    switch (entry_type) {
-+    case CT_LOG_ENTRY_TYPE_X509:
-+    case CT_LOG_ENTRY_TYPE_PRECERT:
-+        sct->entry_type = entry_type;
-+        return 1;
-+    default:
-+        CTerr(CT_F_SCT_SET_LOG_ENTRY_TYPE, CT_R_UNSUPPORTED_ENTRY_TYPE);
-+        return 0;
-+    }
-+}
-+
-+int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len)
-+{
-+    if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) {
-+        CTerr(CT_F_SCT_SET0_LOG_ID, CT_R_INVALID_LOG_ID_LENGTH);
-+        return 0;
-+    }
-+
-+    OPENSSL_free(sct->log_id);
-+    sct->log_id = log_id;
-+    sct->log_id_len = log_id_len;
-+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+    return 1;
-+}
-+
-+int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, size_t log_id_len)
-+{
-+    if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) {
-+        CTerr(CT_F_SCT_SET1_LOG_ID, CT_R_INVALID_LOG_ID_LENGTH);
-+        return 0;
-+    }
-+
-+    OPENSSL_free(sct->log_id);
-+    sct->log_id = NULL;
-+    sct->log_id_len = 0;
-+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+
-+    if (log_id != NULL && log_id_len > 0) {
-+        sct->log_id = OPENSSL_memdup(log_id, log_id_len);
-+        if (sct->log_id == NULL) {
-+            CTerr(CT_F_SCT_SET1_LOG_ID, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        sct->log_id_len = log_id_len;
-+    }
-+    return 1;
-+}
-+
-+
-+void SCT_set_timestamp(SCT *sct, uint64_t timestamp)
-+{
-+    sct->timestamp = timestamp;
-+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+}
-+
-+int SCT_set_signature_nid(SCT *sct, int nid)
-+{
-+    switch (nid) {
-+    case NID_sha256WithRSAEncryption:
-+        sct->hash_alg = TLSEXT_hash_sha256;
-+        sct->sig_alg = TLSEXT_signature_rsa;
-+        sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+        return 1;
-+    case NID_ecdsa_with_SHA256:
-+        sct->hash_alg = TLSEXT_hash_sha256;
-+        sct->sig_alg = TLSEXT_signature_ecdsa;
-+        sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+        return 1;
-+    default:
-+        CTerr(CT_F_SCT_SET_SIGNATURE_NID, CT_R_UNRECOGNIZED_SIGNATURE_NID);
-+        return 0;
-+    }
-+}
-+
-+void SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len)
-+{
-+    OPENSSL_free(sct->ext);
-+    sct->ext = ext;
-+    sct->ext_len = ext_len;
-+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+}
-+
-+int SCT_set1_extensions(SCT *sct, const unsigned char *ext, size_t ext_len)
-+{
-+    OPENSSL_free(sct->ext);
-+    sct->ext = NULL;
-+    sct->ext_len = 0;
-+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+
-+    if (ext != NULL && ext_len > 0) {
-+        sct->ext = OPENSSL_memdup(ext, ext_len);
-+        if (sct->ext == NULL) {
-+            CTerr(CT_F_SCT_SET1_EXTENSIONS, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        sct->ext_len = ext_len;
-+    }
-+    return 1;
-+}
-+
-+void SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len)
-+{
-+    OPENSSL_free(sct->sig);
-+    sct->sig = sig;
-+    sct->sig_len = sig_len;
-+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+}
-+
-+int SCT_set1_signature(SCT *sct, const unsigned char *sig, size_t sig_len)
-+{
-+    OPENSSL_free(sct->sig);
-+    sct->sig = NULL;
-+    sct->sig_len = 0;
-+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+
-+    if (sig != NULL && sig_len > 0) {
-+        sct->sig = OPENSSL_memdup(sig, sig_len);
-+        if (sct->sig == NULL) {
-+            CTerr(CT_F_SCT_SET1_SIGNATURE, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        sct->sig_len = sig_len;
-+    }
-+    return 1;
-+}
-+
-+sct_version_t SCT_get_version(const SCT *sct)
-+{
-+    return sct->version;
-+}
-+
-+ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct)
-+{
-+    return sct->entry_type;
-+}
-+
-+size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id)
-+{
-+    *log_id = sct->log_id;
-+    return sct->log_id_len;
-+}
-+
-+uint64_t SCT_get_timestamp(const SCT *sct)
-+{
-+    return sct->timestamp;
-+}
-+
-+int SCT_get_signature_nid(const SCT *sct)
-+{
-+    if (sct->version == SCT_VERSION_V1) {
-+        if (sct->hash_alg == TLSEXT_hash_sha256) {
-+            switch (sct->sig_alg) {
-+            case TLSEXT_signature_ecdsa:
-+                return NID_ecdsa_with_SHA256;
-+            case TLSEXT_signature_rsa:
-+                return NID_sha256WithRSAEncryption;
-+            default:
-+                return NID_undef;
-+            }
-+        }
-+    }
-+    return NID_undef;
-+}
-+
-+size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext)
-+{
-+    *ext = sct->ext;
-+    return sct->ext_len;
-+}
-+
-+size_t SCT_get0_signature(const SCT *sct, unsigned char **sig)
-+{
-+    *sig = sct->sig;
-+    return sct->sig_len;
-+}
-+
-+int SCT_is_complete(const SCT *sct)
-+{
-+    switch (sct->version) {
-+    case SCT_VERSION_NOT_SET:
-+        return 0;
-+    case SCT_VERSION_V1:
-+        return sct->log_id != NULL && SCT_signature_is_complete(sct);
-+    default:
-+        return sct->sct != NULL; /* Just need cached encoding */
-+    }
-+}
-+
-+int SCT_signature_is_complete(const SCT *sct)
-+{
-+    return SCT_get_signature_nid(sct) != NID_undef &&
-+        sct->sig != NULL && sct->sig_len > 0;
-+}
-+
-+sct_source_t SCT_get_source(const SCT *sct)
-+{
-+    return sct->source;
-+}
-+
-+int SCT_set_source(SCT *sct, sct_source_t source)
-+{
-+    sct->source = source;
-+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
-+    switch (source) {
-+    case SCT_SOURCE_TLS_EXTENSION:
-+    case SCT_SOURCE_OCSP_STAPLED_RESPONSE:
-+        return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_X509);
-+    case SCT_SOURCE_X509V3_EXTENSION:
-+        return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_PRECERT);
-+    default: /* if we aren't sure, leave the log entry type alone */
-+        return 1;
-+    }
-+}
-+
-+sct_validation_status_t SCT_get_validation_status(const SCT *sct)
-+{
-+    return sct->validation_status;
-+}
-+
-+int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx)
-+{
-+    int is_sct_valid = -1;
-+    SCT_CTX *sctx = NULL;
-+    X509_PUBKEY *pub = NULL, *log_pkey = NULL;
-+    const CTLOG *log;
-+
-+    /*
-+     * With an unrecognized SCT version we don't know what such an SCT means,
-+     * let alone validate one.  So we return validation failure (0).
-+     */
-+    if (sct->version != SCT_VERSION_V1) {
-+        sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_VERSION;
-+        return 0;
-+    }
-+
-+    log = CTLOG_STORE_get0_log_by_id(ctx->log_store,
-+                                     sct->log_id, sct->log_id_len);
-+
-+    /* Similarly, an SCT from an unknown log also cannot be validated. */
-+    if (log == NULL) {
-+        sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_LOG;
-+        return 0;
-+    }
-+
-+    sctx = SCT_CTX_new();
-+    if (sctx == NULL)
-+        goto err;
-+
-+    if (X509_PUBKEY_set(&log_pkey, CTLOG_get0_public_key(log)) != 1)
-+        goto err;
-+    if (SCT_CTX_set1_pubkey(sctx, log_pkey) != 1)
-+        goto err;
-+
-+    if (SCT_get_log_entry_type(sct) == CT_LOG_ENTRY_TYPE_PRECERT) {
-+        EVP_PKEY *issuer_pkey;
-+
-+        if (ctx->issuer == NULL) {
-+            sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
-+            goto end;
-+        }
-+
-+        issuer_pkey = X509_get0_pubkey(ctx->issuer);
-+
-+        if (X509_PUBKEY_set(&pub, issuer_pkey) != 1)
-+            goto err;
-+        if (SCT_CTX_set1_issuer_pubkey(sctx, pub) != 1)
-+            goto err;
-+    }
-+
-+    SCT_CTX_set_time(sctx, ctx->epoch_time_in_ms);
-+
-+    /*
-+     * XXX: Potential for optimization.  This repeats some idempotent heavy
-+     * lifting on the certificate for each candidate SCT, and appears to not
-+     * use any information in the SCT itself, only the certificate is
-+     * processed.  So it may make more sense to to do this just once, perhaps
-+     * associated with the shared (by all SCTs) policy eval ctx.
-+     *
-+     * XXX: Failure here is global (SCT independent) and represents either an
-+     * issue with the certificate (e.g. duplicate extensions) or an out of
-+     * memory condition.  When the certificate is incompatible with CT, we just
-+     * mark the SCTs invalid, rather than report a failure to determine the
-+     * validation status.  That way, callbacks that want to do "soft" SCT
-+     * processing will not abort handshakes with false positive internal
-+     * errors.  Since the function does not distinguish between certificate
-+     * issues (peer's fault) and internal problems (out fault) the safe thing
-+     * to do is to report a validation failure and let the callback or
-+     * application decide what to do.
-+     */
-+    if (SCT_CTX_set1_cert(sctx, ctx->cert, NULL) != 1)
-+        sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
-+    else
-+        sct->validation_status = SCT_CTX_verify(sctx, sct) == 1 ?
-+            SCT_VALIDATION_STATUS_VALID : SCT_VALIDATION_STATUS_INVALID;
-+
-+end:
-+    is_sct_valid = sct->validation_status == SCT_VALIDATION_STATUS_VALID;
-+err:
-+    X509_PUBKEY_free(pub);
-+    X509_PUBKEY_free(log_pkey);
-+    SCT_CTX_free(sctx);
-+
-+    return is_sct_valid;
-+}
-+
-+int SCT_LIST_validate(const STACK_OF(SCT) *scts, CT_POLICY_EVAL_CTX *ctx)
-+{
-+    int are_scts_valid = 1;
-+    int sct_count = scts != NULL ? sk_SCT_num(scts) : 0;
-+    int i;
-+
-+    for (i = 0; i < sct_count; ++i) {
-+        int is_sct_valid = -1;
-+        SCT *sct = sk_SCT_value(scts, i);
-+
-+        if (sct == NULL)
-+            continue;
-+
-+        is_sct_valid = SCT_validate(sct, ctx);
-+        if (is_sct_valid < 0)
-+            return is_sct_valid;
-+        are_scts_valid &= is_sct_valid;
-+    }
-+
-+    return are_scts_valid;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_sct_ctx.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_sct_ctx.c
-new file mode 100644
-index 0000000..75a5027
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_sct_ctx.c
-@@ -0,0 +1,263 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifdef OPENSSL_NO_CT
-+# error "CT is disabled"
-+#endif
-+
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+
-+#include "ct_locl.h"
-+
-+SCT_CTX *SCT_CTX_new(void)
-+{
-+    SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx));
-+
-+    if (sctx == NULL)
-+        CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE);
-+
-+    return sctx;
-+}
-+
-+void SCT_CTX_free(SCT_CTX *sctx)
-+{
-+    if (sctx == NULL)
-+        return;
-+    EVP_PKEY_free(sctx->pkey);
-+    OPENSSL_free(sctx->pkeyhash);
-+    OPENSSL_free(sctx->ihash);
-+    OPENSSL_free(sctx->certder);
-+    OPENSSL_free(sctx->preder);
-+    OPENSSL_free(sctx);
-+}
-+
-+/*
-+ * Finds the index of the first extension with the given NID in cert.
-+ * If there is more than one extension with that NID, *is_duplicated is set to
-+ * 1, otherwise 0 (unless it is NULL).
-+ */
-+static int ct_x509_get_ext(X509 *cert, int nid, int *is_duplicated)
-+{
-+    int ret = X509_get_ext_by_NID(cert, nid, -1);
-+
-+    if (is_duplicated != NULL)
-+        *is_duplicated = ret >= 0 && X509_get_ext_by_NID(cert, nid, ret) >= 0;
-+
-+    return ret;
-+}
-+
-+/*
-+ * Modifies a certificate by deleting extensions and copying the issuer and
-+ * AKID from the presigner certificate, if necessary.
-+ * Returns 1 on success, 0 otherwise.
-+ */
-+__owur static int ct_x509_cert_fixup(X509 *cert, X509 *presigner)
-+{
-+    int preidx, certidx;
-+    int pre_akid_ext_is_dup, cert_akid_ext_is_dup;
-+
-+    if (presigner == NULL)
-+        return 1;
-+
-+    preidx = ct_x509_get_ext(presigner, NID_authority_key_identifier,
-+                             &pre_akid_ext_is_dup);
-+    certidx = ct_x509_get_ext(cert, NID_authority_key_identifier,
-+                              &cert_akid_ext_is_dup);
-+
-+    /* An error occurred whilst searching for the extension */
-+    if (preidx < -1 || certidx < -1)
-+        return 0;
-+    /* Invalid certificate if they contain duplicate extensions */
-+    if (pre_akid_ext_is_dup || cert_akid_ext_is_dup)
-+        return 0;
-+    /* AKID must be present in both certificate or absent in both */
-+    if (preidx >= 0 && certidx == -1)
-+        return 0;
-+    if (preidx == -1 && certidx >= 0)
-+        return 0;
-+    /* Copy issuer name */
-+    if (!X509_set_issuer_name(cert, X509_get_issuer_name(presigner)))
-+        return 0;
-+    if (preidx != -1) {
-+        /* Retrieve and copy AKID encoding */
-+        X509_EXTENSION *preext = X509_get_ext(presigner, preidx);
-+        X509_EXTENSION *certext = X509_get_ext(cert, certidx);
-+        ASN1_OCTET_STRING *preextdata;
-+
-+        /* Should never happen */
-+        if (preext == NULL || certext == NULL)
-+            return 0;
-+        preextdata = X509_EXTENSION_get_data(preext);
-+        if (preextdata == NULL ||
-+            !X509_EXTENSION_set_data(certext, preextdata))
-+            return 0;
-+    }
-+    return 1;
-+}
-+
-+int SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner)
-+{
-+    unsigned char *certder = NULL, *preder = NULL;
-+    X509 *pretmp = NULL;
-+    int certderlen = 0, prederlen = 0;
-+    int idx = -1;
-+    int poison_ext_is_dup, sct_ext_is_dup;
-+    int poison_idx = ct_x509_get_ext(cert, NID_ct_precert_poison, &poison_ext_is_dup);
-+
-+    /* Duplicate poison extensions are present - error */
-+    if (poison_ext_is_dup)
-+        goto err;
-+
-+    /* If *cert doesn't have a poison extension, it isn't a precert */
-+    if (poison_idx == -1) {
-+        /* cert isn't a precert, so we shouldn't have a presigner */
-+        if (presigner != NULL)
-+            goto err;
-+
-+        certderlen = i2d_X509(cert, &certder);
-+        if (certderlen < 0)
-+            goto err;
-+    }
-+
-+    /* See if cert has a precert SCTs extension */
-+    idx = ct_x509_get_ext(cert, NID_ct_precert_scts, &sct_ext_is_dup);
-+    /* Duplicate SCT extensions are present - error */
-+    if (sct_ext_is_dup)
-+        goto err;
-+
-+    if (idx >= 0 && poison_idx >= 0) {
-+        /*
-+         * cert can't both contain SCTs (i.e. have an SCT extension) and be a
-+         * precert (i.e. have a poison extension).
-+         */
-+        goto err;
-+    }
-+
-+    if (idx == -1) {
-+        idx = poison_idx;
-+    }
-+
-+    /*
-+     * If either a poison or SCT extension is present, remove it before encoding
-+     * cert. This, along with ct_x509_cert_fixup(), gets a TBSCertificate (see
-+     * RFC5280) from cert, which is what the CT log signed when it produced the
-+     * SCT.
-+     */
-+    if (idx >= 0) {
-+        X509_EXTENSION *ext;
-+
-+        /* Take a copy of certificate so we don't modify passed version */
-+        pretmp = X509_dup(cert);
-+        if (pretmp == NULL)
-+            goto err;
-+
-+        ext = X509_delete_ext(pretmp, idx);
-+        X509_EXTENSION_free(ext);
-+
-+        if (!ct_x509_cert_fixup(pretmp, presigner))
-+            goto err;
-+
-+        prederlen = i2d_re_X509_tbs(pretmp, &preder);
-+        if (prederlen <= 0)
-+            goto err;
-+    }
-+
-+    X509_free(pretmp);
-+
-+    OPENSSL_free(sctx->certder);
-+    sctx->certder = certder;
-+    sctx->certderlen = certderlen;
-+
-+    OPENSSL_free(sctx->preder);
-+    sctx->preder = preder;
-+    sctx->prederlen = prederlen;
-+
-+    return 1;
-+err:
-+    OPENSSL_free(certder);
-+    OPENSSL_free(preder);
-+    X509_free(pretmp);
-+    return 0;
-+}
-+
-+__owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
-+                                     size_t *hash_len)
-+{
-+    int ret = 0;
-+    unsigned char *md = NULL, *der = NULL;
-+    int der_len;
-+    unsigned int md_len;
-+
-+    /* Reuse buffer if possible */
-+    if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) {
-+        md = *hash;
-+    } else {
-+        md = OPENSSL_malloc(SHA256_DIGEST_LENGTH);
-+        if (md == NULL)
-+            goto err;
-+    }
-+
-+    /* Calculate key hash */
-+    der_len = i2d_X509_PUBKEY(pkey, &der);
-+    if (der_len <= 0)
-+        goto err;
-+
-+    if (!EVP_Digest(der, der_len, md, &md_len, EVP_sha256(), NULL))
-+        goto err;
-+
-+    if (md != *hash) {
-+        OPENSSL_free(*hash);
-+        *hash = md;
-+        *hash_len = SHA256_DIGEST_LENGTH;
-+    }
-+
-+    md = NULL;
-+    ret = 1;
-+ err:
-+    OPENSSL_free(md);
-+    OPENSSL_free(der);
-+    return ret;
-+}
-+
-+int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer)
-+{
-+    return SCT_CTX_set1_issuer_pubkey(sctx, X509_get_X509_PUBKEY(issuer));
-+}
-+
-+int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
-+{
-+    return ct_public_key_hash(pubkey, &sctx->ihash, &sctx->ihashlen);
-+}
-+
-+int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
-+{
-+    EVP_PKEY *pkey = X509_PUBKEY_get(pubkey);
-+
-+    if (pkey == NULL)
-+        return 0;
-+
-+    if (!ct_public_key_hash(pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
-+        EVP_PKEY_free(pkey);
-+        return 0;
-+    }
-+
-+    EVP_PKEY_free(sctx->pkey);
-+    sctx->pkey = pkey;
-+    return 1;
-+}
-+
-+void SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms)
-+{
-+    sctx->epoch_time_in_ms = time_in_ms;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_vfy.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_vfy.c
-new file mode 100644
-index 0000000..cabcf57
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_vfy.c
-@@ -0,0 +1,140 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include "ct_locl.h"
-+
-+typedef enum sct_signature_type_t {
-+    SIGNATURE_TYPE_NOT_SET = -1,
-+    SIGNATURE_TYPE_CERT_TIMESTAMP,
-+    SIGNATURE_TYPE_TREE_HASH
-+} SCT_SIGNATURE_TYPE;
-+
-+/*
-+ * Update encoding for SCT signature verification/generation to supplied
-+ * EVP_MD_CTX.
-+ */
-+static int sct_ctx_update(EVP_MD_CTX *ctx, const SCT_CTX *sctx, const SCT *sct)
-+{
-+    unsigned char tmpbuf[12];
-+    unsigned char *p, *der;
-+    size_t derlen;
-+    /*+
-+     * digitally-signed struct {
-+     *   (1 byte) Version sct_version;
-+     *   (1 byte) SignatureType signature_type = certificate_timestamp;
-+     *   (8 bytes) uint64 timestamp;
-+     *   (2 bytes) LogEntryType entry_type;
-+     *   (? bytes) select(entry_type) {
-+     *     case x509_entry: ASN.1Cert;
-+     *     case precert_entry: PreCert;
-+     *   } signed_entry;
-+     *   (2 bytes + sct->ext_len) CtExtensions extensions;
-+     * }
-+     */
-+    if (sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET)
-+        return 0;
-+    if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)
-+        return 0;
-+
-+    p = tmpbuf;
-+    *p++ = sct->version;
-+    *p++ = SIGNATURE_TYPE_CERT_TIMESTAMP;
-+    l2n8(sct->timestamp, p);
-+    s2n(sct->entry_type, p);
-+
-+    if (!EVP_DigestUpdate(ctx, tmpbuf, p - tmpbuf))
-+        return 0;
-+
-+    if (sct->entry_type == CT_LOG_ENTRY_TYPE_X509) {
-+        der = sctx->certder;
-+        derlen = sctx->certderlen;
-+    } else {
-+        if (!EVP_DigestUpdate(ctx, sctx->ihash, sctx->ihashlen))
-+            return 0;
-+        der = sctx->preder;
-+        derlen = sctx->prederlen;
-+    }
-+
-+    /* If no encoding available, fatal error */
-+    if (der == NULL)
-+        return 0;
-+
-+    /* Include length first */
-+    p = tmpbuf;
-+    l2n3(derlen, p);
-+
-+    if (!EVP_DigestUpdate(ctx, tmpbuf, 3))
-+        return 0;
-+    if (!EVP_DigestUpdate(ctx, der, derlen))
-+        return 0;
-+
-+    /* Add any extensions */
-+    p = tmpbuf;
-+    s2n(sct->ext_len, p);
-+    if (!EVP_DigestUpdate(ctx, tmpbuf, 2))
-+        return 0;
-+
-+    if (sct->ext_len && !EVP_DigestUpdate(ctx, sct->ext, sct->ext_len))
-+        return 0;
-+
-+    return 1;
-+}
-+
-+int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct)
-+{
-+    EVP_MD_CTX *ctx = NULL;
-+    int ret = 0;
-+
-+    if (!SCT_is_complete(sct) || sctx->pkey == NULL ||
-+        sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET ||
-+        (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)) {
-+        CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_NOT_SET);
-+        return 0;
-+    }
-+    if (sct->version != SCT_VERSION_V1) {
-+        CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_UNSUPPORTED_VERSION);
-+        return 0;
-+    }
-+    if (sct->log_id_len != sctx->pkeyhashlen ||
-+        memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) {
-+        CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_LOG_ID_MISMATCH);
-+        return 0;
-+    }
-+    if (sct->timestamp > sctx->epoch_time_in_ms) {
-+        CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_FUTURE_TIMESTAMP);
-+        return 0;
-+    }
-+
-+    ctx = EVP_MD_CTX_new();
-+    if (ctx == NULL)
-+        goto end;
-+
-+    if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey))
-+        goto end;
-+
-+    if (!sct_ctx_update(ctx, sctx, sct))
-+        goto end;
-+
-+    /* Verify signature */
-+    ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len);
-+    /* If ret < 0 some other error: fall through without setting error */
-+    if (ret == 0)
-+        CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_INVALID_SIGNATURE);
-+
-+end:
-+    EVP_MD_CTX_free(ctx);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_x509v3.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_x509v3.c
-new file mode 100644
-index 0000000..805ada0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ct/ct_x509v3.c
-@@ -0,0 +1,60 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifdef OPENSSL_NO_CT
-+# error "CT is disabled"
-+#endif
-+
-+#include "ct_locl.h"
-+
-+static char *i2s_poison(const X509V3_EXT_METHOD *method, void *val)
-+{
-+    return OPENSSL_strdup("NULL");
-+}
-+
-+static void *s2i_poison(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str)
-+{
-+   return ASN1_NULL_new();
-+}
-+
-+static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list,
-+                 BIO *out, int indent)
-+{
-+    SCT_LIST_print(sct_list, out, indent, "\n", NULL);
-+    return 1;
-+}
-+
-+/* Handlers for X509v3/OCSP Certificate Transparency extensions */
-+const X509V3_EXT_METHOD v3_ct_scts[3] = {
-+    /* X509v3 extension in certificates that contains SCTs */
-+    { NID_ct_precert_scts, 0, NULL,
-+    NULL, (X509V3_EXT_FREE)SCT_LIST_free,
-+    (X509V3_EXT_D2I)d2i_SCT_LIST, (X509V3_EXT_I2D)i2d_SCT_LIST,
-+    NULL, NULL,
-+    NULL, NULL,
-+    (X509V3_EXT_I2R)i2r_SCT_LIST, NULL,
-+    NULL },
-+
-+    /* X509v3 extension to mark a certificate as a pre-certificate */
-+    { NID_ct_precert_poison, 0, ASN1_ITEM_ref(ASN1_NULL),
-+    NULL, NULL, NULL, NULL,
-+    i2s_poison, s2i_poison,
-+    NULL, NULL,
-+    NULL, NULL,
-+    NULL },
-+
-+    /* OCSP extension that contains SCTs */
-+    { NID_ct_cert_scts, 0, NULL,
-+    0, (X509V3_EXT_FREE)SCT_LIST_free,
-+    (X509V3_EXT_D2I)d2i_SCT_LIST, (X509V3_EXT_I2D)i2d_SCT_LIST,
-+    NULL, NULL,
-+    NULL, NULL,
-+    (X509V3_EXT_I2R)i2r_SCT_LIST, NULL,
-+    NULL },
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/cversion.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/cversion.c
-new file mode 100644
-index 0000000..96d8a5b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/cversion.c
-@@ -0,0 +1,65 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+
-+#ifndef NO_WINDOWS_BRAINDEATH
-+# include "buildinf.h"
-+#endif
-+
-+unsigned long OpenSSL_version_num(void)
-+{
-+    return OPENSSL_VERSION_NUMBER;
-+}
-+
-+const char *OpenSSL_version(int t)
-+{
-+    if (t == OPENSSL_VERSION)
-+        return OPENSSL_VERSION_TEXT;
-+    if (t == OPENSSL_BUILT_ON) {
-+#ifdef DATE
-+# ifdef OPENSSL_USE_BUILD_DATE
-+        return (DATE);
-+# else
-+        return ("built on: reproducible build, date unspecified");
-+# endif
-+#else
-+        return ("built on: date not available");
-+#endif
-+    }
-+    if (t == OPENSSL_CFLAGS) {
-+#ifdef CFLAGS
-+        return (CFLAGS);
-+#else
-+        return ("compiler: information not available");
-+#endif
-+    }
-+    if (t == OPENSSL_PLATFORM) {
-+#ifdef PLATFORM
-+        return (PLATFORM);
-+#else
-+        return ("platform: information not available");
-+#endif
-+    }
-+    if (t == OPENSSL_DIR) {
-+#ifdef OPENSSLDIR
-+        return "OPENSSLDIR: \"" OPENSSLDIR "\"";
-+#else
-+        return "OPENSSLDIR: N/A";
-+#endif
-+    }
-+    if (t == OPENSSL_ENGINES_DIR) {
-+#ifdef ENGINESDIR
-+        return "ENGINESDIR: \"" ENGINESDIR "\"";
-+#else
-+        return "ENGINESDIR: N/A";
-+#endif
-+    }
-+    return ("not available");
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/crypt586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/crypt586.pl
-new file mode 100644
-index 0000000..d5911a1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/crypt586.pl
-@@ -0,0 +1,217 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+# The inner loop instruction sequence and the IP/FP modifications are from
-+# Svend Olaf Mikkelsen 
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"crypt586.pl");
-+
-+$L="edi";
-+$R="esi";
-+
-+&external_label("DES_SPtrans");
-+&fcrypt_body("fcrypt_body");
-+&asm_finish();
-+
-+close STDOUT;
-+
-+sub fcrypt_body
-+	{
-+	local($name,$do_ip)=@_;
-+
-+	&function_begin($name);
-+
-+	&comment("");
-+	&comment("Load the 2 words");
-+	$trans="ebp";
-+
-+	&xor(	$L,	$L);
-+	&xor(	$R,	$R);
-+
-+	# PIC-ification:-)
-+	&picmeup("edx","DES_SPtrans");
-+	#if ($cpp)	{ &picmeup("edx","DES_SPtrans");   }
-+	#else		{ &lea("edx",&DWP("DES_SPtrans")); }
-+	&push("edx");	# becomes &swtmp(1)
-+	#
-+	&mov($trans,&wparam(1)); # reloaded with DES_SPtrans in D_ENCRYPT
-+
-+	&push(&DWC(25)); # add a variable
-+
-+	&set_label("start");
-+	for ($i=0; $i<16; $i+=2)
-+		{
-+		&comment("");
-+		&comment("Round $i");
-+		&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
-+
-+		&comment("");
-+		&comment("Round ".sprintf("%d",$i+1));
-+		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx");
-+		}
-+	 &mov("ebx",	&swtmp(0));
-+	&mov("eax",	$L);
-+	 &dec("ebx");
-+	&mov($L,	$R);
-+	 &mov($R,	"eax");
-+	&mov(&swtmp(0),	"ebx");
-+	 &jnz(&label("start"));
-+
-+	&comment("");
-+	&comment("FP");
-+	&mov("edx",&wparam(0));
-+
-+	&FP_new($R,$L,"eax",3);
-+	&mov(&DWP(0,"edx","",0),"eax");
-+	&mov(&DWP(4,"edx","",0),$L);
-+
-+	&add("esp",8);	# remove variables
-+
-+	&function_end($name);
-+	}
-+
-+sub D_ENCRYPT
-+	{
-+	local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_;
-+
-+	&mov(	$u,		&wparam(2));			# 2
-+	&mov(	$t,		$R);
-+	&shr(	$t,		16);				# 1
-+	&mov(	$tmp2,		&wparam(3));			# 2
-+	&xor(	$t,		$R);				# 1
-+
-+	&and(	$u,		$t);				# 2
-+	&and(	$t,		$tmp2);				# 2
-+
-+	&mov(	$tmp1,		$u);
-+	&shl(	$tmp1,		16); 				# 1
-+	&mov(	$tmp2,		$t);
-+	&shl(	$tmp2,		16); 				# 1
-+	&xor(	$u,		$tmp1);				# 2
-+	&xor(	$t,		$tmp2);				# 2
-+	&mov(	$tmp1,		&DWP(&n2a($S*4),$trans,"",0));	# 2
-+	&xor(	$u,		$tmp1);
-+	&mov(	$tmp2,		&DWP(&n2a(($S+1)*4),$trans,"",0));	# 2
-+	&xor(	$u,		$R);
-+	&xor(	$t,		$R);
-+	&xor(	$t,		$tmp2);
-+
-+	&and(	$u,		"0xfcfcfcfc"	);		# 2
-+	&xor(	$tmp1,		$tmp1);				# 1
-+	&and(	$t,		"0xcfcfcfcf"	);		# 2
-+	&xor(	$tmp2,		$tmp2);	
-+	&movb(	&LB($tmp1),	&LB($u)	);
-+	&movb(	&LB($tmp2),	&HB($u)	);
-+	&rotr(	$t,		4		);
-+	&mov(	$trans,		&swtmp(1));
-+	&xor(	$L,		&DWP("     ",$trans,$tmp1,0));
-+	&movb(	&LB($tmp1),	&LB($t)	);
-+	&xor(	$L,		&DWP("0x200",$trans,$tmp2,0));
-+	&movb(	&LB($tmp2),	&HB($t)	);
-+	&shr(	$u,		16);
-+	&xor(	$L,		&DWP("0x100",$trans,$tmp1,0));
-+	&movb(	&LB($tmp1),	&HB($u)	);
-+	&shr(	$t,		16);
-+	&xor(	$L,		&DWP("0x300",$trans,$tmp2,0));
-+	&movb(	&LB($tmp2),	&HB($t)	);
-+	&and(	$u,		"0xff"	);
-+	&and(	$t,		"0xff"	);
-+	&mov(	$tmp1,		&DWP("0x600",$trans,$tmp1,0));
-+	&xor(	$L,		$tmp1);
-+	&mov(	$tmp1,		&DWP("0x700",$trans,$tmp2,0));
-+	&xor(	$L,		$tmp1);
-+	&mov(	$tmp1,		&DWP("0x400",$trans,$u,0));
-+	&xor(	$L,		$tmp1);
-+	&mov(	$tmp1,		&DWP("0x500",$trans,$t,0));
-+	&xor(	$L,		$tmp1);
-+	&mov(	$trans,		&wparam(1));
-+	}
-+
-+sub n2a
-+	{
-+	sprintf("%d",$_[0]);
-+	}
-+
-+# now has a side affect of rotating $a by $shift
-+sub R_PERM_OP
-+	{
-+	local($a,$b,$tt,$shift,$mask,$last)=@_;
-+
-+	&rotl(	$a,		$shift		) if ($shift != 0);
-+	&mov(	$tt,		$a		);
-+	&xor(	$a,		$b		);
-+	&and(	$a,		$mask		);
-+	if ($notlast eq $b)
-+		{
-+		&xor(	$b,		$a		);
-+		&xor(	$tt,		$a		);
-+		}
-+	else
-+		{
-+		&xor(	$tt,		$a		);
-+		&xor(	$b,		$a		);
-+		}
-+	&comment("");
-+	}
-+
-+sub IP_new
-+	{
-+	local($l,$r,$tt,$lr)=@_;
-+
-+	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
-+	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
-+	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
-+	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
-+	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
-+	
-+	if ($lr != 3)
-+		{
-+		if (($lr-3) < 0)
-+			{ &rotr($tt,	3-$lr); }
-+		else	{ &rotl($tt,	$lr-3); }
-+		}
-+	if ($lr != 2)
-+		{
-+		if (($lr-2) < 0)
-+			{ &rotr($r,	2-$lr); }
-+		else	{ &rotl($r,	$lr-2); }
-+		}
-+	}
-+
-+sub FP_new
-+	{
-+	local($l,$r,$tt,$lr)=@_;
-+
-+	if ($lr != 2)
-+		{
-+		if (($lr-2) < 0)
-+			{ &rotl($r,	2-$lr); }
-+		else	{ &rotr($r,	$lr-2); }
-+		}
-+	if ($lr != 3)
-+		{
-+		if (($lr-3) < 0)
-+			{ &rotl($l,	3-$lr); }
-+		else	{ &rotr($l,	$lr-3); }
-+		}
-+
-+	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
-+	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
-+	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
-+	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
-+	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
-+	&rotr($tt	, 4);
-+	}
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/des-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/des-586.pl
-new file mode 100644
-index 0000000..3d7c7f1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/des-586.pl
-@@ -0,0 +1,465 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+# The inner loop instruction sequence and the IP/FP modifications are from
-+# Svend Olaf Mikkelsen 
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+require "cbc.pl";
-+require "desboth.pl";
-+
-+# base code is in microsft
-+# op dest, source
-+# format.
-+#
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"des-586.pl");
-+
-+$L="edi";
-+$R="esi";
-+$trans="ebp";
-+$small_footprint=1 if (grep(/\-DOPENSSL_SMALL_FOOTPRINT/,@ARGV));
-+# one can discuss setting this variable to 1 unconditionally, as
-+# the folded loop is only 3% slower than unrolled, but >7 times smaller
-+
-+&public_label("DES_SPtrans");
-+&static_label("des_sptrans");
-+
-+&DES_encrypt_internal();
-+&DES_decrypt_internal();
-+&DES_encrypt("DES_encrypt1",1);
-+&DES_encrypt("DES_encrypt2",0);
-+&DES_encrypt3("DES_encrypt3",1);
-+&DES_encrypt3("DES_decrypt3",0);
-+&cbc("DES_ncbc_encrypt","DES_encrypt1","DES_encrypt1",0,4,5,3,5,-1);
-+&cbc("DES_ede3_cbc_encrypt","DES_encrypt3","DES_decrypt3",0,6,7,3,4,5);
-+&DES_SPtrans();
-+
-+&asm_finish();
-+
-+close STDOUT;
-+
-+sub DES_encrypt_internal()
-+	{
-+	&function_begin_B("_x86_DES_encrypt");
-+
-+	if ($small_footprint)
-+	    {
-+	    &lea("edx",&DWP(128,"ecx"));
-+	    &push("edx");
-+	    &push("ecx");
-+	    &set_label("eloop");
-+		&D_ENCRYPT(0,$L,$R,0,$trans,"eax","ebx","ecx","edx",&swtmp(0));
-+		&comment("");
-+		&D_ENCRYPT(1,$R,$L,2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
-+		&comment("");
-+		&add("ecx",16);
-+		&cmp("ecx",&swtmp(1));
-+		&mov(&swtmp(0),"ecx");
-+		&jb(&label("eloop"));
-+	    &add("esp",8);
-+	    }
-+	else
-+	    {
-+	    &push("ecx");
-+	    for ($i=0; $i<16; $i+=2)
-+		{
-+		&comment("Round $i");
-+		&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
-+		&comment("Round ".sprintf("%d",$i+1));
-+		&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
-+		}
-+	    &add("esp",4);
-+	}
-+	&ret();
-+
-+	&function_end_B("_x86_DES_encrypt");
-+	}
-+	
-+sub DES_decrypt_internal()
-+	{
-+	&function_begin_B("_x86_DES_decrypt");
-+
-+	if ($small_footprint)
-+	    {
-+	    &push("ecx");
-+	    &lea("ecx",&DWP(128,"ecx"));
-+	    &push("ecx");
-+	    &set_label("dloop");
-+		&D_ENCRYPT(0,$L,$R,-2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
-+		&comment("");
-+		&D_ENCRYPT(1,$R,$L,-4,$trans,"eax","ebx","ecx","edx",&swtmp(0));
-+		&comment("");
-+		&sub("ecx",16);
-+		&cmp("ecx",&swtmp(1));
-+		&mov(&swtmp(0),"ecx");
-+		&ja(&label("dloop"));
-+	    &add("esp",8);
-+	    }
-+	else
-+	    {
-+	    &push("ecx");
-+	    for ($i=15; $i>0; $i-=2)
-+		{
-+		&comment("Round $i");
-+		&D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
-+		&comment("Round ".sprintf("%d",$i-1));
-+		&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0));
-+		}
-+	    &add("esp",4);
-+	    }
-+	&ret();
-+
-+	&function_end_B("_x86_DES_decrypt");
-+	}
-+	
-+sub DES_encrypt
-+	{
-+	local($name,$do_ip)=@_;
-+
-+	&function_begin_B($name);
-+
-+	&push("esi");
-+	&push("edi");
-+
-+	&comment("");
-+	&comment("Load the 2 words");
-+
-+	if ($do_ip)
-+		{
-+		&mov($R,&wparam(0));
-+		 &xor(	"ecx",		"ecx"		);
-+
-+		&push("ebx");
-+		&push("ebp");
-+
-+		&mov("eax",&DWP(0,$R,"",0));
-+		 &mov("ebx",&wparam(2));	# get encrypt flag
-+		&mov($L,&DWP(4,$R,"",0));
-+		&comment("");
-+		&comment("IP");
-+		&IP_new("eax",$L,$R,3);
-+		}
-+	else
-+		{
-+		&mov("eax",&wparam(0));
-+		 &xor(	"ecx",		"ecx"		);
-+
-+		&push("ebx");
-+		&push("ebp");
-+
-+		&mov($R,&DWP(0,"eax","",0));
-+		 &mov("ebx",&wparam(2));	# get encrypt flag
-+		&rotl($R,3);
-+		&mov($L,&DWP(4,"eax","",0));
-+		&rotl($L,3);
-+		}
-+
-+	# PIC-ification:-)
-+	&call	(&label("pic_point"));
-+	&set_label("pic_point");
-+	&blindpop($trans);
-+	&lea	($trans,&DWP(&label("des_sptrans")."-".&label("pic_point"),$trans));
-+
-+	&mov(	"ecx",	&wparam(1)	);
-+
-+	&cmp("ebx","0");
-+	&je(&label("decrypt"));
-+	&call("_x86_DES_encrypt");
-+	&jmp(&label("done"));
-+	&set_label("decrypt");
-+	&call("_x86_DES_decrypt");
-+	&set_label("done");
-+
-+	if ($do_ip)
-+		{
-+		&comment("");
-+		&comment("FP");
-+		&mov("edx",&wparam(0));
-+		&FP_new($L,$R,"eax",3);
-+
-+		&mov(&DWP(0,"edx","",0),"eax");
-+		&mov(&DWP(4,"edx","",0),$R);
-+		}
-+	else
-+		{
-+		&comment("");
-+		&comment("Fixup");
-+		&rotr($L,3);		# r
-+		 &mov("eax",&wparam(0));
-+		&rotr($R,3);		# l
-+		 &mov(&DWP(0,"eax","",0),$L);
-+		 &mov(&DWP(4,"eax","",0),$R);
-+		}
-+
-+	&pop("ebp");
-+	&pop("ebx");
-+	&pop("edi");
-+	&pop("esi");
-+	&ret();
-+
-+	&function_end_B($name);
-+	}
-+
-+sub D_ENCRYPT
-+	{
-+	local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t,$wp1)=@_;
-+
-+	 &mov(	$u,		&DWP(&n2a($S*4),$tmp2,"",0));
-+	&xor(	$tmp1,		$tmp1);
-+	 &mov(	$t,		&DWP(&n2a(($S+1)*4),$tmp2,"",0));
-+	&xor(	$u,		$R);
-+	&xor(	$tmp2,		$tmp2);
-+	 &xor(	$t,		$R);
-+	&and(	$u,		"0xfcfcfcfc"	);
-+	 &and(	$t,		"0xcfcfcfcf"	);
-+	&movb(	&LB($tmp1),	&LB($u)	);
-+	 &movb(	&LB($tmp2),	&HB($u)	);
-+	&rotr(	$t,		4		);
-+	&xor(	$L,		&DWP("     ",$trans,$tmp1,0));
-+	 &movb(	&LB($tmp1),	&LB($t)	);
-+	 &xor(	$L,		&DWP("0x200",$trans,$tmp2,0));
-+	 &movb(	&LB($tmp2),	&HB($t)	);
-+	&shr(	$u,		16);
-+	 &xor(	$L,		&DWP("0x100",$trans,$tmp1,0));
-+	 &movb(	&LB($tmp1),	&HB($u)	);
-+	&shr(	$t,		16);
-+	 &xor(	$L,		&DWP("0x300",$trans,$tmp2,0));
-+	&movb(	&LB($tmp2),	&HB($t)	);
-+	 &and(	$u,		"0xff"	);
-+	&and(	$t,		"0xff"	);
-+	 &xor(	$L,		&DWP("0x600",$trans,$tmp1,0));
-+	 &xor(	$L,		&DWP("0x700",$trans,$tmp2,0));
-+	&mov(	$tmp2,		$wp1	);
-+	 &xor(	$L,		&DWP("0x400",$trans,$u,0));
-+	 &xor(	$L,		&DWP("0x500",$trans,$t,0));
-+	}
-+
-+sub n2a
-+	{
-+	sprintf("%d",$_[0]);
-+	}
-+
-+# now has a side affect of rotating $a by $shift
-+sub R_PERM_OP
-+	{
-+	local($a,$b,$tt,$shift,$mask,$last)=@_;
-+
-+	&rotl(	$a,		$shift		) if ($shift != 0);
-+	&mov(	$tt,		$a		);
-+	&xor(	$a,		$b		);
-+	&and(	$a,		$mask		);
-+	# This can never succeed, and besides it is difficult to see what the
-+	# idea was - Ben 13 Feb 99
-+	if (!$last eq $b)
-+		{
-+		&xor(	$b,		$a		);
-+		&xor(	$tt,		$a		);
-+		}
-+	else
-+		{
-+		&xor(	$tt,		$a		);
-+		&xor(	$b,		$a		);
-+		}
-+	&comment("");
-+	}
-+
-+sub IP_new
-+	{
-+	local($l,$r,$tt,$lr)=@_;
-+
-+	&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
-+	&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
-+	&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
-+	&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
-+	&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
-+	
-+	if ($lr != 3)
-+		{
-+		if (($lr-3) < 0)
-+			{ &rotr($tt,	3-$lr); }
-+		else	{ &rotl($tt,	$lr-3); }
-+		}
-+	if ($lr != 2)
-+		{
-+		if (($lr-2) < 0)
-+			{ &rotr($r,	2-$lr); }
-+		else	{ &rotl($r,	$lr-2); }
-+		}
-+	}
-+
-+sub FP_new
-+	{
-+	local($l,$r,$tt,$lr)=@_;
-+
-+	if ($lr != 2)
-+		{
-+		if (($lr-2) < 0)
-+			{ &rotl($r,	2-$lr); }
-+		else	{ &rotr($r,	$lr-2); }
-+		}
-+	if ($lr != 3)
-+		{
-+		if (($lr-3) < 0)
-+			{ &rotl($l,	3-$lr); }
-+		else	{ &rotr($l,	$lr-3); }
-+		}
-+
-+	&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
-+	&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
-+	&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
-+	&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
-+	&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
-+	&rotr($tt	, 4);
-+	}
-+
-+sub DES_SPtrans
-+	{
-+	&set_label("DES_SPtrans",64);
-+	&set_label("des_sptrans");
-+	&data_word(0x02080800, 0x00080000, 0x02000002, 0x02080802);
-+	&data_word(0x02000000, 0x00080802, 0x00080002, 0x02000002);
-+	&data_word(0x00080802, 0x02080800, 0x02080000, 0x00000802);
-+	&data_word(0x02000802, 0x02000000, 0x00000000, 0x00080002);
-+	&data_word(0x00080000, 0x00000002, 0x02000800, 0x00080800);
-+	&data_word(0x02080802, 0x02080000, 0x00000802, 0x02000800);
-+	&data_word(0x00000002, 0x00000800, 0x00080800, 0x02080002);
-+	&data_word(0x00000800, 0x02000802, 0x02080002, 0x00000000);
-+	&data_word(0x00000000, 0x02080802, 0x02000800, 0x00080002);
-+	&data_word(0x02080800, 0x00080000, 0x00000802, 0x02000800);
-+	&data_word(0x02080002, 0x00000800, 0x00080800, 0x02000002);
-+	&data_word(0x00080802, 0x00000002, 0x02000002, 0x02080000);
-+	&data_word(0x02080802, 0x00080800, 0x02080000, 0x02000802);
-+	&data_word(0x02000000, 0x00000802, 0x00080002, 0x00000000);
-+	&data_word(0x00080000, 0x02000000, 0x02000802, 0x02080800);
-+	&data_word(0x00000002, 0x02080002, 0x00000800, 0x00080802);
-+	# nibble 1
-+	&data_word(0x40108010, 0x00000000, 0x00108000, 0x40100000);
-+	&data_word(0x40000010, 0x00008010, 0x40008000, 0x00108000);
-+	&data_word(0x00008000, 0x40100010, 0x00000010, 0x40008000);
-+	&data_word(0x00100010, 0x40108000, 0x40100000, 0x00000010);
-+	&data_word(0x00100000, 0x40008010, 0x40100010, 0x00008000);
-+	&data_word(0x00108010, 0x40000000, 0x00000000, 0x00100010);
-+	&data_word(0x40008010, 0x00108010, 0x40108000, 0x40000010);
-+	&data_word(0x40000000, 0x00100000, 0x00008010, 0x40108010);
-+	&data_word(0x00100010, 0x40108000, 0x40008000, 0x00108010);
-+	&data_word(0x40108010, 0x00100010, 0x40000010, 0x00000000);
-+	&data_word(0x40000000, 0x00008010, 0x00100000, 0x40100010);
-+	&data_word(0x00008000, 0x40000000, 0x00108010, 0x40008010);
-+	&data_word(0x40108000, 0x00008000, 0x00000000, 0x40000010);
-+	&data_word(0x00000010, 0x40108010, 0x00108000, 0x40100000);
-+	&data_word(0x40100010, 0x00100000, 0x00008010, 0x40008000);
-+	&data_word(0x40008010, 0x00000010, 0x40100000, 0x00108000);
-+	# nibble 2
-+	&data_word(0x04000001, 0x04040100, 0x00000100, 0x04000101);
-+	&data_word(0x00040001, 0x04000000, 0x04000101, 0x00040100);
-+	&data_word(0x04000100, 0x00040000, 0x04040000, 0x00000001);
-+	&data_word(0x04040101, 0x00000101, 0x00000001, 0x04040001);
-+	&data_word(0x00000000, 0x00040001, 0x04040100, 0x00000100);
-+	&data_word(0x00000101, 0x04040101, 0x00040000, 0x04000001);
-+	&data_word(0x04040001, 0x04000100, 0x00040101, 0x04040000);
-+	&data_word(0x00040100, 0x00000000, 0x04000000, 0x00040101);
-+	&data_word(0x04040100, 0x00000100, 0x00000001, 0x00040000);
-+	&data_word(0x00000101, 0x00040001, 0x04040000, 0x04000101);
-+	&data_word(0x00000000, 0x04040100, 0x00040100, 0x04040001);
-+	&data_word(0x00040001, 0x04000000, 0x04040101, 0x00000001);
-+	&data_word(0x00040101, 0x04000001, 0x04000000, 0x04040101);
-+	&data_word(0x00040000, 0x04000100, 0x04000101, 0x00040100);
-+	&data_word(0x04000100, 0x00000000, 0x04040001, 0x00000101);
-+	&data_word(0x04000001, 0x00040101, 0x00000100, 0x04040000);
-+	# nibble 3
-+	&data_word(0x00401008, 0x10001000, 0x00000008, 0x10401008);
-+	&data_word(0x00000000, 0x10400000, 0x10001008, 0x00400008);
-+	&data_word(0x10401000, 0x10000008, 0x10000000, 0x00001008);
-+	&data_word(0x10000008, 0x00401008, 0x00400000, 0x10000000);
-+	&data_word(0x10400008, 0x00401000, 0x00001000, 0x00000008);
-+	&data_word(0x00401000, 0x10001008, 0x10400000, 0x00001000);
-+	&data_word(0x00001008, 0x00000000, 0x00400008, 0x10401000);
-+	&data_word(0x10001000, 0x10400008, 0x10401008, 0x00400000);
-+	&data_word(0x10400008, 0x00001008, 0x00400000, 0x10000008);
-+	&data_word(0x00401000, 0x10001000, 0x00000008, 0x10400000);
-+	&data_word(0x10001008, 0x00000000, 0x00001000, 0x00400008);
-+	&data_word(0x00000000, 0x10400008, 0x10401000, 0x00001000);
-+	&data_word(0x10000000, 0x10401008, 0x00401008, 0x00400000);
-+	&data_word(0x10401008, 0x00000008, 0x10001000, 0x00401008);
-+	&data_word(0x00400008, 0x00401000, 0x10400000, 0x10001008);
-+	&data_word(0x00001008, 0x10000000, 0x10000008, 0x10401000);
-+	# nibble 4
-+	&data_word(0x08000000, 0x00010000, 0x00000400, 0x08010420);
-+	&data_word(0x08010020, 0x08000400, 0x00010420, 0x08010000);
-+	&data_word(0x00010000, 0x00000020, 0x08000020, 0x00010400);
-+	&data_word(0x08000420, 0x08010020, 0x08010400, 0x00000000);
-+	&data_word(0x00010400, 0x08000000, 0x00010020, 0x00000420);
-+	&data_word(0x08000400, 0x00010420, 0x00000000, 0x08000020);
-+	&data_word(0x00000020, 0x08000420, 0x08010420, 0x00010020);
-+	&data_word(0x08010000, 0x00000400, 0x00000420, 0x08010400);
-+	&data_word(0x08010400, 0x08000420, 0x00010020, 0x08010000);
-+	&data_word(0x00010000, 0x00000020, 0x08000020, 0x08000400);
-+	&data_word(0x08000000, 0x00010400, 0x08010420, 0x00000000);
-+	&data_word(0x00010420, 0x08000000, 0x00000400, 0x00010020);
-+	&data_word(0x08000420, 0x00000400, 0x00000000, 0x08010420);
-+	&data_word(0x08010020, 0x08010400, 0x00000420, 0x00010000);
-+	&data_word(0x00010400, 0x08010020, 0x08000400, 0x00000420);
-+	&data_word(0x00000020, 0x00010420, 0x08010000, 0x08000020);
-+	# nibble 5
-+	&data_word(0x80000040, 0x00200040, 0x00000000, 0x80202000);
-+	&data_word(0x00200040, 0x00002000, 0x80002040, 0x00200000);
-+	&data_word(0x00002040, 0x80202040, 0x00202000, 0x80000000);
-+	&data_word(0x80002000, 0x80000040, 0x80200000, 0x00202040);
-+	&data_word(0x00200000, 0x80002040, 0x80200040, 0x00000000);
-+	&data_word(0x00002000, 0x00000040, 0x80202000, 0x80200040);
-+	&data_word(0x80202040, 0x80200000, 0x80000000, 0x00002040);
-+	&data_word(0x00000040, 0x00202000, 0x00202040, 0x80002000);
-+	&data_word(0x00002040, 0x80000000, 0x80002000, 0x00202040);
-+	&data_word(0x80202000, 0x00200040, 0x00000000, 0x80002000);
-+	&data_word(0x80000000, 0x00002000, 0x80200040, 0x00200000);
-+	&data_word(0x00200040, 0x80202040, 0x00202000, 0x00000040);
-+	&data_word(0x80202040, 0x00202000, 0x00200000, 0x80002040);
-+	&data_word(0x80000040, 0x80200000, 0x00202040, 0x00000000);
-+	&data_word(0x00002000, 0x80000040, 0x80002040, 0x80202000);
-+	&data_word(0x80200000, 0x00002040, 0x00000040, 0x80200040);
-+	# nibble 6
-+	&data_word(0x00004000, 0x00000200, 0x01000200, 0x01000004);
-+	&data_word(0x01004204, 0x00004004, 0x00004200, 0x00000000);
-+	&data_word(0x01000000, 0x01000204, 0x00000204, 0x01004000);
-+	&data_word(0x00000004, 0x01004200, 0x01004000, 0x00000204);
-+	&data_word(0x01000204, 0x00004000, 0x00004004, 0x01004204);
-+	&data_word(0x00000000, 0x01000200, 0x01000004, 0x00004200);
-+	&data_word(0x01004004, 0x00004204, 0x01004200, 0x00000004);
-+	&data_word(0x00004204, 0x01004004, 0x00000200, 0x01000000);
-+	&data_word(0x00004204, 0x01004000, 0x01004004, 0x00000204);
-+	&data_word(0x00004000, 0x00000200, 0x01000000, 0x01004004);
-+	&data_word(0x01000204, 0x00004204, 0x00004200, 0x00000000);
-+	&data_word(0x00000200, 0x01000004, 0x00000004, 0x01000200);
-+	&data_word(0x00000000, 0x01000204, 0x01000200, 0x00004200);
-+	&data_word(0x00000204, 0x00004000, 0x01004204, 0x01000000);
-+	&data_word(0x01004200, 0x00000004, 0x00004004, 0x01004204);
-+	&data_word(0x01000004, 0x01004200, 0x01004000, 0x00004004);
-+	# nibble 7
-+	&data_word(0x20800080, 0x20820000, 0x00020080, 0x00000000);
-+	&data_word(0x20020000, 0x00800080, 0x20800000, 0x20820080);
-+	&data_word(0x00000080, 0x20000000, 0x00820000, 0x00020080);
-+	&data_word(0x00820080, 0x20020080, 0x20000080, 0x20800000);
-+	&data_word(0x00020000, 0x00820080, 0x00800080, 0x20020000);
-+	&data_word(0x20820080, 0x20000080, 0x00000000, 0x00820000);
-+	&data_word(0x20000000, 0x00800000, 0x20020080, 0x20800080);
-+	&data_word(0x00800000, 0x00020000, 0x20820000, 0x00000080);
-+	&data_word(0x00800000, 0x00020000, 0x20000080, 0x20820080);
-+	&data_word(0x00020080, 0x20000000, 0x00000000, 0x00820000);
-+	&data_word(0x20800080, 0x20020080, 0x20020000, 0x00800080);
-+	&data_word(0x20820000, 0x00000080, 0x00800080, 0x20020000);
-+	&data_word(0x20820080, 0x00800000, 0x20800000, 0x20000080);
-+	&data_word(0x00820000, 0x00020080, 0x20020080, 0x20800000);
-+	&data_word(0x00000080, 0x20820000, 0x00820080, 0x00000000);
-+	&data_word(0x20000000, 0x20800080, 0x00020000, 0x00820080);
-+	}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/des_enc.m4 b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/des_enc.m4
-new file mode 100644
-index 0000000..2d794d3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/des_enc.m4
-@@ -0,0 +1,1972 @@
-+! Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+!
-+! Licensed under the OpenSSL license (the "License").  You may not use
-+! this file except in compliance with the License.  You can obtain a copy
-+! in the file LICENSE in the source distribution or at
-+! https://www.openssl.org/source/license.html
-+!
-+!  To expand the m4 macros: m4 -B 8192 des_enc.m4 > des_enc.S
-+!
-+!  Global registers 1 to 5 are used. This is the same as done by the
-+!  cc compiler. The UltraSPARC load/store little endian feature is used.
-+!
-+!  Instruction grouping often refers to one CPU cycle.
-+!
-+!  Assemble through gcc: gcc -c -mcpu=ultrasparc -o des_enc.o des_enc.S
-+!
-+!  Assemble through cc:  cc -c -xarch=v8plusa -o des_enc.o des_enc.S
-+!
-+!  Performance improvement according to './apps/openssl speed des'
-+!
-+!	32-bit build:
-+!		23%  faster than cc-5.2 -xarch=v8plus -xO5
-+!		115% faster than gcc-3.2.1 -m32 -mcpu=ultrasparc -O5
-+!	64-bit build:
-+!		50%  faster than cc-5.2 -xarch=v9 -xO5
-+!		100% faster than gcc-3.2.1 -m64 -mcpu=ultrasparc -O5
-+!
-+
-+.ident "des_enc.m4 2.1"
-+.file  "des_enc-sparc.S"
-+
-+#include 
-+
-+#ifdef OPENSSL_FIPSCANISTER
-+#include 
-+#endif
-+
-+#if defined(__SUNPRO_C) && defined(__sparcv9)
-+# define ABI64  /* They've said -xarch=v9 at command line */
-+#elif defined(__GNUC__) && defined(__arch64__)
-+# define ABI64  /* They've said -m64 at command line */
-+#endif
-+
-+#ifdef ABI64
-+  .register	%g2,#scratch
-+  .register	%g3,#scratch
-+# define	FRAME	-192
-+# define	BIAS	2047
-+# define	LDPTR	ldx
-+# define	STPTR	stx
-+# define	ARG0	128
-+# define	ARGSZ	8
-+#else
-+# define	FRAME	-96
-+# define	BIAS	0
-+# define	LDPTR	ld
-+# define	STPTR	st
-+# define	ARG0	68
-+# define	ARGSZ	4
-+#endif
-+
-+#define LOOPS 7
-+
-+#define global0 %g0
-+#define global1 %g1
-+#define global2 %g2
-+#define global3 %g3
-+#define global4 %g4
-+#define global5 %g5
-+
-+#define local0 %l0
-+#define local1 %l1
-+#define local2 %l2
-+#define local3 %l3
-+#define local4 %l4
-+#define local5 %l5
-+#define local7 %l6
-+#define local6 %l7
-+
-+#define in0 %i0
-+#define in1 %i1
-+#define in2 %i2
-+#define in3 %i3
-+#define in4 %i4
-+#define in5 %i5
-+#define in6 %i6
-+#define in7 %i7
-+
-+#define out0 %o0
-+#define out1 %o1
-+#define out2 %o2
-+#define out3 %o3
-+#define out4 %o4
-+#define out5 %o5
-+#define out6 %o6
-+#define out7 %o7
-+
-+#define stub stb
-+
-+changequote({,})
-+
-+
-+! Macro definitions:
-+
-+
-+! {ip_macro}
-+!
-+! The logic used in initial and final permutations is the same as in
-+! the C code. The permutations are done with a clever shift, xor, and
-+! technique.
-+!
-+! The macro also loads address sbox 1 to 5 to global 1 to 5, address
-+! sbox 6 to local6, and addres sbox 8 to out3.
-+!
-+! Rotates the halfs 3 left to bring the sbox bits in convenient positions.
-+!
-+! Loads key first round from address in parameter 5 to out0, out1.
-+!
-+! After the the original LibDES initial permutation, the resulting left
-+! is in the variable initially used for right and vice versa. The macro
-+! implements the possibility to keep the halfs in the original registers.
-+!
-+! parameter 1  left
-+! parameter 2  right
-+! parameter 3  result left (modify in first round)
-+! parameter 4  result right (use in first round)
-+! parameter 5  key address
-+! parameter 6  1/2 for include encryption/decryption
-+! parameter 7  1 for move in1 to in3
-+! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
-+! parameter 9  1 for load ks3 and ks2 to in4 and in3
-+
-+define(ip_macro, {
-+
-+! {ip_macro}
-+! $1 $2 $4 $3 $5 $6 $7 $8 $9
-+
-+	ld	[out2+256], local1
-+	srl	$2, 4, local4
-+
-+	xor	local4, $1, local4
-+	ifelse($7,1,{mov in1, in3},{nop})
-+
-+	ld	[out2+260], local2
-+	and	local4, local1, local4
-+	ifelse($8,1,{mov in3, in4},{})
-+	ifelse($8,2,{mov in4, in3},{})
-+
-+	ld	[out2+280], out4          ! loop counter
-+	sll	local4, 4, local1
-+	xor	$1, local4, $1
-+
-+	ld	[out2+264], local3
-+	srl	$1, 16, local4
-+	xor	$2, local1, $2
-+
-+	ifelse($9,1,{LDPTR	KS3, in4},{})
-+	xor	local4, $2, local4
-+	nop	!sethi	%hi(DES_SPtrans), global1 ! sbox addr
-+
-+	ifelse($9,1,{LDPTR	KS2, in3},{})
-+	and	local4, local2, local4
-+	nop	!or	global1, %lo(DES_SPtrans), global1   ! sbox addr
-+
-+	sll	local4, 16, local1
-+	xor	$2, local4, $2
-+
-+	srl	$2, 2, local4
-+	xor	$1, local1, $1
-+
-+	sethi	%hi(16711680), local5
-+	xor	local4, $1, local4
-+
-+	and	local4, local3, local4
-+	or	local5, 255, local5
-+
-+	sll	local4, 2, local2
-+	xor	$1, local4, $1
-+
-+	srl	$1, 8, local4
-+	xor	$2, local2, $2
-+
-+	xor	local4, $2, local4
-+	add	global1, 768, global4
-+
-+	and	local4, local5, local4
-+	add	global1, 1024, global5
-+
-+	ld	[out2+272], local7
-+	sll	local4, 8, local1
-+	xor	$2, local4, $2
-+
-+	srl	$2, 1, local4
-+	xor	$1, local1, $1
-+
-+	ld	[$5], out0                ! key 7531
-+	xor	local4, $1, local4
-+	add	global1, 256, global2
-+
-+	ld	[$5+4], out1              ! key 8642
-+	and	local4, local7, local4
-+	add	global1, 512, global3
-+
-+	sll	local4, 1, local1
-+	xor	$1, local4, $1
-+
-+	sll	$1, 3, local3
-+	xor	$2, local1, $2
-+
-+	sll	$2, 3, local2
-+	add	global1, 1280, local6     ! address sbox 8
-+
-+	srl	$1, 29, local4
-+	add	global1, 1792, out3       ! address sbox 8
-+
-+	srl	$2, 29, local1
-+	or	local4, local3, $4
-+
-+	or	local2, local1, $3
-+
-+	ifelse($6, 1, {
-+
-+		ld	[out2+284], local5     ! 0x0000FC00 used in the rounds
-+		or	local2, local1, $3
-+		xor	$4, out0, local1
-+
-+		call .des_enc.1
-+		and	local1, 252, local1
-+
-+	},{})
-+
-+	ifelse($6, 2, {
-+
-+		ld	[out2+284], local5     ! 0x0000FC00 used in the rounds
-+		or	local2, local1, $3
-+		xor	$4, out0, local1
-+
-+		call .des_dec.1
-+		and	local1, 252, local1
-+
-+	},{})
-+})
-+
-+
-+! {rounds_macro}
-+!
-+! The logic used in the DES rounds is the same as in the C code,
-+! except that calculations for sbox 1 and sbox 5 begin before
-+! the previous round is finished.
-+!
-+! In each round one half (work) is modified based on key and the
-+! other half (use).
-+!
-+! In this version we do two rounds in a loop repeated 7 times
-+! and two rounds separately.
-+!
-+! One half has the bits for the sboxes in the following positions:
-+!
-+!	777777xx555555xx333333xx111111xx
-+!
-+!	88xx666666xx444444xx222222xx8888
-+!
-+! The bits for each sbox are xor-ed with the key bits for that box.
-+! The above xx bits are cleared, and the result used for lookup in
-+! the sbox table. Each sbox entry contains the 4 output bits permuted
-+! into 32 bits according to the P permutation.
-+!
-+! In the description of DES, left and right are switched after
-+! each round, except after last round. In this code the original
-+! left and right are kept in the same register in all rounds, meaning
-+! that after the 16 rounds the result for right is in the register
-+! originally used for left.
-+!
-+! parameter 1  first work (left in first round)
-+! parameter 2  first use (right in first round)
-+! parameter 3  enc/dec  1/-1
-+! parameter 4  loop label
-+! parameter 5  key address register
-+! parameter 6  optional address for key next encryption/decryption
-+! parameter 7  not empty for include retl
-+!
-+! also compares in2 to 8
-+
-+define(rounds_macro, {
-+
-+! {rounds_macro}
-+! $1 $2 $3 $4 $5 $6 $7 $8 $9
-+
-+	xor	$2, out0, local1
-+
-+	ld	[out2+284], local5        ! 0x0000FC00
-+	ba	$4
-+	and	local1, 252, local1
-+
-+	.align 32
-+
-+$4:
-+	! local6 is address sbox 6
-+	! out3   is address sbox 8
-+	! out4   is loop counter
-+
-+	ld	[global1+local1], local1
-+	xor	$2, out1, out1            ! 8642
-+	xor	$2, out0, out0            ! 7531
-+	! fmovs	%f0, %f0                  ! fxor used for alignment
-+
-+	srl	out1, 4, local0           ! rotate 4 right
-+	and	out0, local5, local3      ! 3
-+	! fmovs	%f0, %f0
-+
-+	ld	[$5+$3*8], local7         ! key 7531 next round
-+	srl	local3, 8, local3         ! 3
-+	and	local0, 252, local2       ! 2
-+	! fmovs	%f0, %f0
-+
-+	ld	[global3+local3],local3   ! 3
-+	sll	out1, 28, out1            ! rotate
-+	xor	$1, local1, $1            ! 1 finished, local1 now sbox 7
-+
-+	ld	[global2+local2], local2  ! 2 
-+	srl	out0, 24, local1          ! 7
-+	or	out1, local0, out1        ! rotate
-+
-+	ldub	[out2+local1], local1     ! 7 (and 0xFC)
-+	srl	out1, 24, local0          ! 8
-+	and	out1, local5, local4      ! 4
-+
-+	ldub	[out2+local0], local0     ! 8 (and 0xFC)
-+	srl	local4, 8, local4         ! 4
-+	xor	$1, local2, $1            ! 2 finished local2 now sbox 6
-+
-+	ld	[global4+local4],local4   ! 4
-+	srl	out1, 16, local2          ! 6
-+	xor	$1, local3, $1            ! 3 finished local3 now sbox 5
-+
-+	ld	[out3+local0],local0      ! 8
-+	and	local2, 252, local2       ! 6
-+	add	global1, 1536, local5     ! address sbox 7
-+
-+	ld	[local6+local2], local2   ! 6
-+	srl	out0, 16, local3          ! 5
-+	xor	$1, local4, $1            ! 4 finished
-+
-+	ld	[local5+local1],local1    ! 7
-+	and	local3, 252, local3       ! 5
-+	xor	$1, local0, $1            ! 8 finished
-+
-+	ld	[global5+local3],local3   ! 5
-+	xor	$1, local2, $1            ! 6 finished
-+	subcc	out4, 1, out4
-+
-+	ld	[$5+$3*8+4], out0         ! key 8642 next round
-+	xor	$1, local7, local2        ! sbox 5 next round
-+	xor	$1, local1, $1            ! 7 finished
-+
-+	srl	local2, 16, local2        ! sbox 5 next round
-+	xor	$1, local3, $1            ! 5 finished
-+
-+	ld	[$5+$3*16+4], out1        ! key 8642 next round again
-+	and	local2, 252, local2       ! sbox5 next round
-+! next round
-+	xor	$1, local7, local7        ! 7531
-+
-+	ld	[global5+local2], local2  ! 5
-+	srl	local7, 24, local3        ! 7
-+	xor	$1, out0, out0            ! 8642
-+
-+	ldub	[out2+local3], local3     ! 7 (and 0xFC)
-+	srl	out0, 4, local0           ! rotate 4 right
-+	and	local7, 252, local1       ! 1
-+
-+	sll	out0, 28, out0            ! rotate
-+	xor	$2, local2, $2            ! 5 finished local2 used
-+
-+	srl	local0, 8, local4         ! 4
-+	and	local0, 252, local2       ! 2
-+	ld	[local5+local3], local3   ! 7
-+
-+	srl	local0, 16, local5        ! 6
-+	or	out0, local0, out0        ! rotate
-+	ld	[global2+local2], local2  ! 2
-+
-+	srl	out0, 24, local0
-+	ld	[$5+$3*16], out0          ! key 7531 next round
-+	and	local4, 252, local4	  ! 4
-+
-+	and	local5, 252, local5       ! 6
-+	ld	[global4+local4], local4  ! 4
-+	xor	$2, local3, $2            ! 7 finished local3 used
-+
-+	and	local0, 252, local0       ! 8
-+	ld	[local6+local5], local5   ! 6
-+	xor	$2, local2, $2            ! 2 finished local2 now sbox 3
-+
-+	srl	local7, 8, local2         ! 3 start
-+	ld	[out3+local0], local0     ! 8
-+	xor	$2, local4, $2            ! 4 finished
-+
-+	and	local2, 252, local2       ! 3
-+	ld	[global1+local1], local1  ! 1
-+	xor	$2, local5, $2            ! 6 finished local5 used
-+
-+	ld	[global3+local2], local2  ! 3
-+	xor	$2, local0, $2            ! 8 finished
-+	add	$5, $3*16, $5             ! enc add 8, dec add -8 to key pointer
-+
-+	ld	[out2+284], local5        ! 0x0000FC00
-+	xor	$2, out0, local4          ! sbox 1 next round
-+	xor	$2, local1, $2            ! 1 finished
-+
-+	xor	$2, local2, $2            ! 3 finished
-+	bne	$4
-+	and	local4, 252, local1       ! sbox 1 next round
-+
-+! two rounds more:
-+
-+	ld	[global1+local1], local1
-+	xor	$2, out1, out1
-+	xor	$2, out0, out0
-+
-+	srl	out1, 4, local0           ! rotate
-+	and	out0, local5, local3
-+
-+	ld	[$5+$3*8], local7         ! key 7531
-+	srl	local3, 8, local3
-+	and	local0, 252, local2
-+
-+	ld	[global3+local3],local3
-+	sll	out1, 28, out1            ! rotate
-+	xor	$1, local1, $1            ! 1 finished, local1 now sbox 7
-+
-+	ld	[global2+local2], local2
-+	srl	out0, 24, local1
-+	or	out1, local0, out1        ! rotate
-+
-+	ldub	[out2+local1], local1
-+	srl	out1, 24, local0
-+	and	out1, local5, local4
-+
-+	ldub	[out2+local0], local0
-+	srl	local4, 8, local4
-+	xor	$1, local2, $1            ! 2 finished local2 now sbox 6
-+
-+	ld	[global4+local4],local4
-+	srl	out1, 16, local2
-+	xor	$1, local3, $1            ! 3 finished local3 now sbox 5
-+
-+	ld	[out3+local0],local0
-+	and	local2, 252, local2
-+	add	global1, 1536, local5     ! address sbox 7
-+
-+	ld	[local6+local2], local2
-+	srl	out0, 16, local3
-+	xor	$1, local4, $1            ! 4 finished
-+
-+	ld	[local5+local1],local1
-+	and	local3, 252, local3
-+	xor	$1, local0, $1
-+
-+	ld	[global5+local3],local3
-+	xor	$1, local2, $1            ! 6 finished
-+	cmp	in2, 8
-+
-+	ifelse($6,{}, {}, {ld	[out2+280], out4})  ! loop counter
-+	xor	$1, local7, local2        ! sbox 5 next round
-+	xor	$1, local1, $1            ! 7 finished
-+
-+	ld	[$5+$3*8+4], out0
-+	srl	local2, 16, local2        ! sbox 5 next round
-+	xor	$1, local3, $1            ! 5 finished
-+
-+	and	local2, 252, local2
-+! next round (two rounds more)
-+	xor	$1, local7, local7        ! 7531
-+
-+	ld	[global5+local2], local2
-+	srl	local7, 24, local3
-+	xor	$1, out0, out0            ! 8642
-+
-+	ldub	[out2+local3], local3
-+	srl	out0, 4, local0           ! rotate
-+	and	local7, 252, local1
-+
-+	sll	out0, 28, out0            ! rotate
-+	xor	$2, local2, $2            ! 5 finished local2 used
-+
-+	srl	local0, 8, local4
-+	and	local0, 252, local2
-+	ld	[local5+local3], local3
-+
-+	srl	local0, 16, local5
-+	or	out0, local0, out0        ! rotate
-+	ld	[global2+local2], local2
-+
-+	srl	out0, 24, local0
-+	ifelse($6,{}, {}, {ld	[$6], out0})   ! key next encryption/decryption
-+	and	local4, 252, local4
-+
-+	and	local5, 252, local5
-+	ld	[global4+local4], local4
-+	xor	$2, local3, $2            ! 7 finished local3 used
-+
-+	and	local0, 252, local0
-+	ld	[local6+local5], local5
-+	xor	$2, local2, $2            ! 2 finished local2 now sbox 3
-+
-+	srl	local7, 8, local2         ! 3 start
-+	ld	[out3+local0], local0
-+	xor	$2, local4, $2
-+
-+	and	local2, 252, local2
-+	ld	[global1+local1], local1
-+	xor	$2, local5, $2            ! 6 finished local5 used
-+
-+	ld	[global3+local2], local2
-+	srl	$1, 3, local3
-+	xor	$2, local0, $2
-+
-+	ifelse($6,{}, {}, {ld	[$6+4], out1}) ! key next encryption/decryption
-+	sll	$1, 29, local4
-+	xor	$2, local1, $2
-+
-+	ifelse($7,{}, {}, {retl})
-+	xor	$2, local2, $2
-+})
-+
-+
-+! {fp_macro}
-+!
-+!  parameter 1   right (original left)
-+!  parameter 2   left (original right)
-+!  parameter 3   1 for optional store to [in0]
-+!  parameter 4   1 for load input/output address to local5/7
-+!
-+!  The final permutation logic switches the halfes, meaning that
-+!  left and right ends up the the registers originally used.
-+
-+define(fp_macro, {
-+
-+! {fp_macro}
-+! $1 $2 $3 $4 $5 $6 $7 $8 $9
-+
-+	! initially undo the rotate 3 left done after initial permutation
-+	! original left is received shifted 3 right and 29 left in local3/4
-+
-+	sll	$2, 29, local1
-+	or	local3, local4, $1
-+
-+	srl	$2, 3, $2
-+	sethi	%hi(0x55555555), local2
-+
-+	or	$2, local1, $2
-+	or	local2, %lo(0x55555555), local2
-+
-+	srl	$2, 1, local3
-+	sethi	%hi(0x00ff00ff), local1
-+	xor	local3, $1, local3
-+	or	local1, %lo(0x00ff00ff), local1
-+	and	local3, local2, local3
-+	sethi	%hi(0x33333333), local4
-+	sll	local3, 1, local2
-+
-+	xor	$1, local3, $1
-+
-+	srl	$1, 8, local3
-+	xor	$2, local2, $2
-+	xor	local3, $2, local3
-+	or	local4, %lo(0x33333333), local4
-+	and	local3, local1, local3
-+	sethi	%hi(0x0000ffff), local1
-+	sll	local3, 8, local2
-+
-+	xor	$2, local3, $2
-+
-+	srl	$2, 2, local3
-+	xor	$1, local2, $1
-+	xor	local3, $1, local3
-+	or	local1, %lo(0x0000ffff), local1
-+	and	local3, local4, local3
-+	sethi	%hi(0x0f0f0f0f), local4
-+	sll	local3, 2, local2
-+
-+	ifelse($4,1, {LDPTR INPUT, local5})
-+	xor	$1, local3, $1
-+
-+	ifelse($4,1, {LDPTR OUTPUT, local7})
-+	srl	$1, 16, local3
-+	xor	$2, local2, $2
-+	xor	local3, $2, local3
-+	or	local4, %lo(0x0f0f0f0f), local4
-+	and	local3, local1, local3
-+	sll	local3, 16, local2
-+
-+	xor	$2, local3, local1
-+
-+	srl	local1, 4, local3
-+	xor	$1, local2, $1
-+	xor	local3, $1, local3
-+	and	local3, local4, local3
-+	sll	local3, 4, local2
-+
-+	xor	$1, local3, $1
-+
-+	! optional store:
-+
-+	ifelse($3,1, {st $1, [in0]})
-+
-+	xor	local1, local2, $2
-+
-+	ifelse($3,1, {st $2, [in0+4]})
-+
-+})
-+
-+
-+! {fp_ip_macro}
-+!
-+! Does initial permutation for next block mixed with
-+! final permutation for current block.
-+!
-+! parameter 1   original left
-+! parameter 2   original right
-+! parameter 3   left ip
-+! parameter 4   right ip
-+! parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
-+!                2: mov in4 to in3
-+!
-+! also adds -8 to length in2 and loads loop counter to out4
-+
-+define(fp_ip_macro, {
-+
-+! {fp_ip_macro}
-+! $1 $2 $3 $4 $5 $6 $7 $8 $9
-+
-+	define({temp1},{out4})
-+	define({temp2},{local3})
-+
-+	define({ip1},{local1})
-+	define({ip2},{local2})
-+	define({ip4},{local4})
-+	define({ip5},{local5})
-+
-+	! $1 in local3, local4
-+
-+	ld	[out2+256], ip1
-+	sll	out5, 29, temp1
-+	or	local3, local4, $1
-+
-+	srl	out5, 3, $2
-+	ifelse($5,2,{mov in4, in3})
-+
-+	ld	[out2+272], ip5
-+	srl	$4, 4, local0
-+	or	$2, temp1, $2
-+
-+	srl	$2, 1, temp1
-+	xor	temp1, $1, temp1
-+
-+	and	temp1, ip5, temp1
-+	xor	local0, $3, local0
-+
-+	sll	temp1, 1, temp2
-+	xor	$1, temp1, $1
-+
-+	and	local0, ip1, local0
-+	add	in2, -8, in2
-+
-+	sll	local0, 4, local7
-+	xor	$3, local0, $3
-+
-+	ld	[out2+268], ip4
-+	srl	$1, 8, temp1
-+	xor	$2, temp2, $2
-+	ld	[out2+260], ip2
-+	srl	$3, 16, local0
-+	xor	$4, local7, $4
-+	xor	temp1, $2, temp1
-+	xor	local0, $4, local0
-+	and	temp1, ip4, temp1
-+	and	local0, ip2, local0
-+	sll	temp1, 8, temp2
-+	xor	$2, temp1, $2
-+	sll	local0, 16, local7
-+	xor	$4, local0, $4
-+
-+	srl	$2, 2, temp1
-+	xor	$1, temp2, $1
-+
-+	ld	[out2+264], temp2         ! ip3
-+	srl	$4, 2, local0
-+	xor	$3, local7, $3
-+	xor	temp1, $1, temp1
-+	xor	local0, $3, local0
-+	and	temp1, temp2, temp1
-+	and	local0, temp2, local0
-+	sll	temp1, 2, temp2
-+	xor	$1, temp1, $1
-+	sll	local0, 2, local7
-+	xor	$3, local0, $3
-+
-+	srl	$1, 16, temp1
-+	xor	$2, temp2, $2
-+	srl	$3, 8, local0
-+	xor	$4, local7, $4
-+	xor	temp1, $2, temp1
-+	xor	local0, $4, local0
-+	and	temp1, ip2, temp1
-+	and	local0, ip4, local0
-+	sll	temp1, 16, temp2
-+	xor	$2, temp1, local4
-+	sll	local0, 8, local7
-+	xor	$4, local0, $4
-+
-+	srl	$4, 1, local0
-+	xor	$3, local7, $3
-+
-+	srl	local4, 4, temp1
-+	xor	local0, $3, local0
-+
-+	xor	$1, temp2, $1
-+	and	local0, ip5, local0
-+
-+	sll	local0, 1, local7
-+	xor	temp1, $1, temp1
-+
-+	xor	$3, local0, $3
-+	xor	$4, local7, $4
-+
-+	sll	$3, 3, local5
-+	and	temp1, ip1, temp1
-+
-+	sll	temp1, 4, temp2
-+	xor	$1, temp1, $1
-+
-+	ifelse($5,1,{LDPTR	KS2, in4})
-+	sll	$4, 3, local2
-+	xor	local4, temp2, $2
-+
-+	! reload since used as temporar:
-+
-+	ld	[out2+280], out4          ! loop counter
-+
-+	srl	$3, 29, local0
-+	ifelse($5,1,{add in4, 120, in4})
-+
-+	ifelse($5,1,{LDPTR	KS1, in3})
-+	srl	$4, 29, local7
-+
-+	or	local0, local5, $4
-+	or	local2, local7, $3
-+
-+})
-+
-+
-+
-+! {load_little_endian}
-+!
-+! parameter 1  address
-+! parameter 2  destination left
-+! parameter 3  destination right
-+! parameter 4  temporar
-+! parameter 5  label
-+
-+define(load_little_endian, {
-+
-+! {load_little_endian}
-+! $1 $2 $3 $4 $5 $6 $7 $8 $9
-+
-+	! first in memory to rightmost in register
-+
-+$5:
-+	ldub	[$1+3], $2
-+
-+	ldub	[$1+2], $4
-+	sll	$2, 8, $2
-+	or	$2, $4, $2
-+
-+	ldub	[$1+1], $4
-+	sll	$2, 8, $2
-+	or	$2, $4, $2
-+
-+	ldub	[$1+0], $4
-+	sll	$2, 8, $2
-+	or	$2, $4, $2
-+
-+
-+	ldub	[$1+3+4], $3
-+
-+	ldub	[$1+2+4], $4
-+	sll	$3, 8, $3
-+	or	$3, $4, $3
-+
-+	ldub	[$1+1+4], $4
-+	sll	$3, 8, $3
-+	or	$3, $4, $3
-+
-+	ldub	[$1+0+4], $4
-+	sll	$3, 8, $3
-+	or	$3, $4, $3
-+$5a:
-+
-+})
-+
-+
-+! {load_little_endian_inc}
-+!
-+! parameter 1  address
-+! parameter 2  destination left
-+! parameter 3  destination right
-+! parameter 4  temporar
-+! parameter 4  label
-+!
-+! adds 8 to address
-+
-+define(load_little_endian_inc, {
-+
-+! {load_little_endian_inc}
-+! $1 $2 $3 $4 $5 $6 $7 $8 $9
-+
-+	! first in memory to rightmost in register
-+
-+$5:
-+	ldub	[$1+3], $2
-+
-+	ldub	[$1+2], $4
-+	sll	$2, 8, $2
-+	or	$2, $4, $2
-+
-+	ldub	[$1+1], $4
-+	sll	$2, 8, $2
-+	or	$2, $4, $2
-+
-+	ldub	[$1+0], $4
-+	sll	$2, 8, $2
-+	or	$2, $4, $2
-+
-+	ldub	[$1+3+4], $3
-+	add	$1, 8, $1
-+
-+	ldub	[$1+2+4-8], $4
-+	sll	$3, 8, $3
-+	or	$3, $4, $3
-+
-+	ldub	[$1+1+4-8], $4
-+	sll	$3, 8, $3
-+	or	$3, $4, $3
-+
-+	ldub	[$1+0+4-8], $4
-+	sll	$3, 8, $3
-+	or	$3, $4, $3
-+$5a:
-+
-+})
-+
-+
-+! {load_n_bytes}
-+!
-+! Loads 1 to 7 bytes little endian
-+! Remaining bytes are zeroed.
-+!
-+! parameter 1  address
-+! parameter 2  length
-+! parameter 3  destination register left
-+! parameter 4  destination register right
-+! parameter 5  temp
-+! parameter 6  temp2
-+! parameter 7  label
-+! parameter 8  return label
-+
-+define(load_n_bytes, {
-+
-+! {load_n_bytes}
-+! $1 $2 $5 $6 $7 $8 $7 $8 $9
-+
-+$7.0:	call	.+8
-+	sll	$2, 2, $6
-+
-+	add	%o7,$7.jmp.table-$7.0,$5
-+
-+	add	$5, $6, $5
-+	mov	0, $4
-+
-+	ld	[$5], $5
-+
-+	jmp	%o7+$5
-+	mov	0, $3
-+
-+$7.7:
-+	ldub	[$1+6], $5
-+	sll	$5, 16, $5
-+	or	$3, $5, $3
-+$7.6:
-+	ldub	[$1+5], $5
-+	sll	$5, 8, $5
-+	or	$3, $5, $3
-+$7.5:
-+	ldub	[$1+4], $5
-+	or	$3, $5, $3
-+$7.4:
-+	ldub	[$1+3], $5
-+	sll	$5, 24, $5
-+	or	$4, $5, $4
-+$7.3:
-+	ldub	[$1+2], $5
-+	sll	$5, 16, $5
-+	or	$4, $5, $4
-+$7.2:
-+	ldub	[$1+1], $5
-+	sll	$5, 8, $5
-+	or	$4, $5, $4
-+$7.1:
-+	ldub	[$1+0], $5
-+	ba	$8
-+	or	$4, $5, $4
-+
-+	.align 4
-+
-+$7.jmp.table:
-+	.word	0
-+	.word	$7.1-$7.0
-+	.word	$7.2-$7.0
-+	.word	$7.3-$7.0
-+	.word	$7.4-$7.0
-+	.word	$7.5-$7.0
-+	.word	$7.6-$7.0
-+	.word	$7.7-$7.0
-+})
-+
-+
-+! {store_little_endian}
-+!
-+! parameter 1  address
-+! parameter 2  source left
-+! parameter 3  source right
-+! parameter 4  temporar
-+
-+define(store_little_endian, {
-+
-+! {store_little_endian}
-+! $1 $2 $3 $4 $5 $6 $7 $8 $9
-+
-+	! rightmost in register to first in memory
-+
-+$5:
-+	and	$2, 255, $4
-+	stub	$4, [$1+0]
-+
-+	srl	$2, 8, $4
-+	and	$4, 255, $4
-+	stub	$4, [$1+1]
-+
-+	srl	$2, 16, $4
-+	and	$4, 255, $4
-+	stub	$4, [$1+2]
-+
-+	srl	$2, 24, $4
-+	stub	$4, [$1+3]
-+
-+
-+	and	$3, 255, $4
-+	stub	$4, [$1+0+4]
-+
-+	srl	$3, 8, $4
-+	and	$4, 255, $4
-+	stub	$4, [$1+1+4]
-+
-+	srl	$3, 16, $4
-+	and	$4, 255, $4
-+	stub	$4, [$1+2+4]
-+
-+	srl	$3, 24, $4
-+	stub	$4, [$1+3+4]
-+
-+$5a:
-+
-+})
-+
-+
-+! {store_n_bytes}
-+!
-+! Stores 1 to 7 bytes little endian
-+!
-+! parameter 1  address
-+! parameter 2  length
-+! parameter 3  source register left
-+! parameter 4  source register right
-+! parameter 5  temp
-+! parameter 6  temp2
-+! parameter 7  label
-+! parameter 8  return label
-+
-+define(store_n_bytes, {
-+
-+! {store_n_bytes}
-+! $1 $2 $5 $6 $7 $8 $7 $8 $9
-+
-+$7.0:	call	.+8
-+	sll	$2, 2, $6
-+
-+	add	%o7,$7.jmp.table-$7.0,$5
-+
-+	add	$5, $6, $5
-+
-+	ld	[$5], $5
-+
-+	jmp	%o7+$5
-+	nop
-+
-+$7.7:
-+	srl	$3, 16, $5
-+	and	$5, 0xff, $5
-+	stub	$5, [$1+6]
-+$7.6:
-+	srl	$3, 8, $5
-+	and	$5, 0xff, $5
-+	stub	$5, [$1+5]
-+$7.5:
-+	and	$3, 0xff, $5
-+	stub	$5, [$1+4]
-+$7.4:
-+	srl	$4, 24, $5
-+	stub	$5, [$1+3]
-+$7.3:
-+	srl	$4, 16, $5
-+	and	$5, 0xff, $5
-+	stub	$5, [$1+2]
-+$7.2:
-+	srl	$4, 8, $5
-+	and	$5, 0xff, $5
-+	stub	$5, [$1+1]
-+$7.1:
-+	and	$4, 0xff, $5
-+
-+
-+	ba	$8
-+	stub	$5, [$1]
-+
-+	.align 4
-+
-+$7.jmp.table:
-+
-+	.word	0
-+	.word	$7.1-$7.0
-+	.word	$7.2-$7.0
-+	.word	$7.3-$7.0
-+	.word	$7.4-$7.0
-+	.word	$7.5-$7.0
-+	.word	$7.6-$7.0
-+	.word	$7.7-$7.0
-+})
-+
-+
-+define(testvalue,{1})
-+
-+define(register_init, {
-+
-+! For test purposes:
-+
-+	sethi	%hi(testvalue), local0
-+	or	local0, %lo(testvalue), local0
-+
-+	ifelse($1,{},{}, {mov	local0, $1})
-+	ifelse($2,{},{}, {mov	local0, $2})
-+	ifelse($3,{},{}, {mov	local0, $3})
-+	ifelse($4,{},{}, {mov	local0, $4})
-+	ifelse($5,{},{}, {mov	local0, $5})
-+	ifelse($6,{},{}, {mov	local0, $6})
-+	ifelse($7,{},{}, {mov	local0, $7})
-+	ifelse($8,{},{}, {mov	local0, $8})
-+
-+	mov	local0, local1
-+	mov	local0, local2
-+	mov	local0, local3
-+	mov	local0, local4
-+	mov	local0, local5
-+	mov	local0, local7
-+	mov	local0, local6
-+	mov	local0, out0
-+	mov	local0, out1
-+	mov	local0, out2
-+	mov	local0, out3
-+	mov	local0, out4
-+	mov	local0, out5
-+	mov	local0, global1
-+	mov	local0, global2
-+	mov	local0, global3
-+	mov	local0, global4
-+	mov	local0, global5
-+
-+})
-+
-+.section	".text"
-+
-+	.align 32
-+
-+.des_enc:
-+
-+	! key address in3
-+	! loads key next encryption/decryption first round from [in4]
-+
-+	rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl)
-+
-+
-+	.align 32
-+
-+.des_dec:
-+
-+	! implemented with out5 as first parameter to avoid
-+	! register exchange in ede modes
-+
-+	! key address in4
-+	! loads key next encryption/decryption first round from [in3]
-+
-+	rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl)
-+
-+
-+
-+! void DES_encrypt1(data, ks, enc)
-+! *******************************
-+
-+	.align 32
-+	.global DES_encrypt1
-+	.type	 DES_encrypt1,#function
-+
-+DES_encrypt1:
-+
-+	save	%sp, FRAME, %sp
-+
-+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
-+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
-+1:	call	.+8
-+	add	%o7,global1,global1
-+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
-+
-+	ld	[in0], in5                ! left
-+	cmp	in2, 0                    ! enc
-+
-+	be	.encrypt.dec
-+	ld	[in0+4], out5             ! right
-+
-+	! parameter 6  1/2 for include encryption/decryption
-+	! parameter 7  1 for move in1 to in3
-+	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
-+
-+	ip_macro(in5, out5, in5, out5, in3, 0, 1, 1)
-+
-+	rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used
-+
-+	fp_macro(in5, out5, 1)            ! 1 for store to [in0]
-+
-+	ret
-+	restore
-+
-+.encrypt.dec:
-+
-+	add	in1, 120, in3             ! use last subkey for first round
-+
-+	! parameter 6  1/2 for include encryption/decryption
-+	! parameter 7  1 for move in1 to in3
-+	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
-+
-+	ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec,  ks in4
-+
-+	fp_macro(out5, in5, 1)            ! 1 for store to [in0]
-+
-+	ret
-+	restore
-+
-+.DES_encrypt1.end:
-+	.size	 DES_encrypt1,.DES_encrypt1.end-DES_encrypt1
-+
-+
-+! void DES_encrypt2(data, ks, enc)
-+!*********************************
-+
-+	! encrypts/decrypts without initial/final permutation
-+
-+	.align 32
-+	.global DES_encrypt2
-+	.type	 DES_encrypt2,#function
-+
-+DES_encrypt2:
-+
-+	save	%sp, FRAME, %sp
-+
-+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
-+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
-+1:	call	.+8
-+	add	%o7,global1,global1
-+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
-+
-+	! Set sbox address 1 to 6 and rotate halfs 3 left
-+	! Errors caught by destest? Yes. Still? *NO*
-+
-+	!sethi	%hi(DES_SPtrans), global1 ! address sbox 1
-+
-+	!or	global1, %lo(DES_SPtrans), global1  ! sbox 1
-+
-+	add	global1, 256, global2     ! sbox 2
-+	add	global1, 512, global3     ! sbox 3
-+
-+	ld	[in0], out5               ! right
-+	add	global1, 768, global4     ! sbox 4
-+	add	global1, 1024, global5    ! sbox 5
-+
-+	ld	[in0+4], in5              ! left
-+	add	global1, 1280, local6     ! sbox 6
-+	add	global1, 1792, out3       ! sbox 8
-+
-+	! rotate
-+
-+	sll	in5, 3, local5
-+	mov	in1, in3                  ! key address to in3
-+
-+	sll	out5, 3, local7
-+	srl	in5, 29, in5
-+
-+	srl	out5, 29, out5
-+	add	in5, local5, in5
-+
-+	add	out5, local7, out5
-+	cmp	in2, 0
-+
-+	! we use our own stackframe
-+
-+	be	.encrypt2.dec
-+	STPTR	in0, [%sp+BIAS+ARG0+0*ARGSZ]
-+
-+	ld	[in3], out0               ! key 7531 first round
-+	mov	LOOPS, out4               ! loop counter
-+
-+	ld	[in3+4], out1             ! key 8642 first round
-+	sethi	%hi(0x0000FC00), local5
-+
-+	call .des_enc
-+	mov	in3, in4
-+
-+	! rotate
-+	sll	in5, 29, in0
-+	srl	in5, 3, in5
-+	sll	out5, 29, in1
-+	add	in5, in0, in5
-+	srl	out5, 3, out5
-+	LDPTR	[%sp+BIAS+ARG0+0*ARGSZ], in0
-+	add	out5, in1, out5
-+	st	in5, [in0]
-+	st	out5, [in0+4]
-+
-+	ret
-+	restore
-+
-+
-+.encrypt2.dec:
-+
-+	add in3, 120, in4
-+
-+	ld	[in4], out0               ! key 7531 first round
-+	mov	LOOPS, out4               ! loop counter
-+
-+	ld	[in4+4], out1             ! key 8642 first round
-+	sethi	%hi(0x0000FC00), local5
-+
-+	mov	in5, local1               ! left expected in out5
-+	mov	out5, in5
-+
-+	call .des_dec
-+	mov	local1, out5
-+
-+.encrypt2.finish:
-+
-+	! rotate
-+	sll	in5, 29, in0
-+	srl	in5, 3, in5
-+	sll	out5, 29, in1
-+	add	in5, in0, in5
-+	srl	out5, 3, out5
-+	LDPTR	[%sp+BIAS+ARG0+0*ARGSZ], in0
-+	add	out5, in1, out5
-+	st	out5, [in0]
-+	st	in5, [in0+4]
-+
-+	ret
-+	restore
-+
-+.DES_encrypt2.end:
-+	.size	 DES_encrypt2, .DES_encrypt2.end-DES_encrypt2
-+
-+
-+! void DES_encrypt3(data, ks1, ks2, ks3)
-+! **************************************
-+
-+	.align 32
-+	.global DES_encrypt3
-+	.type	 DES_encrypt3,#function
-+
-+DES_encrypt3:
-+
-+	save	%sp, FRAME, %sp
-+	
-+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
-+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
-+1:	call	.+8
-+	add	%o7,global1,global1
-+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
-+
-+	ld	[in0], in5                ! left
-+	add	in2, 120, in4             ! ks2
-+
-+	ld	[in0+4], out5             ! right
-+	mov	in3, in2                  ! save ks3
-+
-+	! parameter 6  1/2 for include encryption/decryption
-+	! parameter 7  1 for mov in1 to in3
-+	! parameter 8  1 for mov in3 to in4
-+	! parameter 9  1 for load ks3 and ks2 to in4 and in3
-+
-+	ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0)
-+
-+	call	.des_dec
-+	mov	in2, in3                  ! preload ks3
-+
-+	call	.des_enc
-+	nop
-+
-+	fp_macro(in5, out5, 1)
-+
-+	ret
-+	restore
-+
-+.DES_encrypt3.end:
-+	.size	 DES_encrypt3,.DES_encrypt3.end-DES_encrypt3
-+
-+
-+! void DES_decrypt3(data, ks1, ks2, ks3)
-+! **************************************
-+
-+	.align 32
-+	.global DES_decrypt3
-+	.type	 DES_decrypt3,#function
-+
-+DES_decrypt3:
-+
-+	save	%sp, FRAME, %sp
-+	
-+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
-+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
-+1:	call	.+8
-+	add	%o7,global1,global1
-+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
-+
-+	ld	[in0], in5                ! left
-+	add	in3, 120, in4             ! ks3
-+
-+	ld	[in0+4], out5             ! right
-+	mov	in2, in3                  ! ks2
-+
-+	! parameter 6  1/2 for include encryption/decryption
-+	! parameter 7  1 for mov in1 to in3
-+	! parameter 8  1 for mov in3 to in4
-+	! parameter 9  1 for load ks3 and ks2 to in4 and in3
-+
-+	ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0)
-+
-+	call	.des_enc
-+	add	in1, 120, in4             ! preload ks1
-+
-+	call	.des_dec
-+	nop
-+
-+	fp_macro(out5, in5, 1)
-+
-+	ret
-+	restore
-+
-+.DES_decrypt3.end:
-+	.size	 DES_decrypt3,.DES_decrypt3.end-DES_decrypt3
-+
-+! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
-+! *****************************************************************
-+
-+
-+	.align 32
-+	.global DES_ncbc_encrypt
-+	.type	 DES_ncbc_encrypt,#function
-+
-+DES_ncbc_encrypt:
-+
-+	save	%sp, FRAME, %sp
-+	
-+	define({INPUT},  { [%sp+BIAS+ARG0+0*ARGSZ] })
-+	define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
-+	define({IVEC},   { [%sp+BIAS+ARG0+4*ARGSZ] })
-+
-+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
-+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
-+1:	call	.+8
-+	add	%o7,global1,global1
-+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
-+
-+	cmp	in5, 0                    ! enc   
-+
-+	be	.ncbc.dec
-+	STPTR	in4, IVEC
-+
-+	! addr  left  right  temp  label
-+	load_little_endian(in4, in5, out5, local3, .LLE1)  ! iv
-+
-+	addcc	in2, -8, in2              ! bytes missing when first block done
-+
-+	bl	.ncbc.enc.seven.or.less
-+	mov	in3, in4                  ! schedule
-+
-+.ncbc.enc.next.block:
-+
-+	load_little_endian(in0, out4, global4, local3, .LLE2)  ! block
-+
-+.ncbc.enc.next.block_1:
-+
-+	xor	in5, out4, in5            ! iv xor
-+	xor	out5, global4, out5       ! iv xor
-+
-+	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
-+	ip_macro(in5, out5, in5, out5, in3, 0, 0, 2)
-+
-+.ncbc.enc.next.block_2:
-+
-+!//	call .des_enc                     ! compares in2 to 8
-+!	rounds inlined for alignment purposes
-+
-+	add	global1, 768, global4     ! address sbox 4 since register used below
-+
-+	rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption  ks in3
-+
-+	bl	.ncbc.enc.next.block_fp
-+	add	in0, 8, in0               ! input address
-+
-+	! If 8 or more bytes are to be encrypted after this block,
-+	! we combine final permutation for this block with initial
-+	! permutation for next block. Load next block:
-+
-+	load_little_endian(in0, global3, global4, local5, .LLE12)
-+
-+	!  parameter 1   original left
-+	!  parameter 2   original right
-+	!  parameter 3   left ip
-+	!  parameter 4   right ip
-+	!  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
-+	!                2: mov in4 to in3
-+	!
-+	! also adds -8 to length in2 and loads loop counter to out4
-+
-+	fp_ip_macro(out0, out1, global3, global4, 2)
-+
-+	store_little_endian(in1, out0, out1, local3, .SLE10)  ! block
-+
-+	ld	[in3], out0               ! key 7531 first round next block
-+	mov 	in5, local1
-+	xor	global3, out5, in5        ! iv xor next block
-+
-+	ld	[in3+4], out1             ! key 8642
-+	add	global1, 512, global3     ! address sbox 3 since register used
-+	xor	global4, local1, out5     ! iv xor next block
-+
-+	ba	.ncbc.enc.next.block_2
-+	add	in1, 8, in1               ! output address
-+
-+.ncbc.enc.next.block_fp:
-+
-+	fp_macro(in5, out5)
-+
-+	store_little_endian(in1, in5, out5, local3, .SLE1)  ! block
-+
-+	addcc   in2, -8, in2              ! bytes missing when next block done
-+
-+	bpos	.ncbc.enc.next.block
-+	add	in1, 8, in1
-+
-+.ncbc.enc.seven.or.less:
-+
-+	cmp	in2, -8
-+
-+	ble	.ncbc.enc.finish
-+	nop
-+
-+	add	in2, 8, local1            ! bytes to load
-+
-+	! addr, length, dest left, dest right, temp, temp2, label, ret label
-+	load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1)
-+
-+	! Loads 1 to 7 bytes little endian to global4, out4
-+
-+
-+.ncbc.enc.finish:
-+
-+	LDPTR	IVEC, local4
-+	store_little_endian(local4, in5, out5, local5, .SLE2)  ! ivec
-+
-+	ret
-+	restore
-+
-+
-+.ncbc.dec:
-+
-+	STPTR	in0, INPUT
-+	cmp	in2, 0                    ! length
-+	add	in3, 120, in3
-+
-+	LDPTR	IVEC, local7              ! ivec
-+	ble	.ncbc.dec.finish
-+	mov	in3, in4                  ! schedule
-+
-+	STPTR	in1, OUTPUT
-+	mov	in0, local5               ! input
-+
-+	load_little_endian(local7, in0, in1, local3, .LLE3)   ! ivec
-+
-+.ncbc.dec.next.block:
-+
-+	load_little_endian(local5, in5, out5, local3, .LLE4)  ! block
-+
-+	! parameter 6  1/2 for include encryption/decryption
-+	! parameter 7  1 for mov in1 to in3
-+	! parameter 8  1 for mov in3 to in4
-+
-+	ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion  ks in4
-+
-+	fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7
-+
-+	! in2 is bytes left to be stored
-+	! in2 is compared to 8 in the rounds
-+
-+	xor	out5, in0, out4           ! iv xor
-+	bl	.ncbc.dec.seven.or.less
-+	xor	in5, in1, global4         ! iv xor
-+
-+	! Load ivec next block now, since input and output address might be the same.
-+
-+	load_little_endian_inc(local5, in0, in1, local3, .LLE5)  ! iv
-+
-+	store_little_endian(local7, out4, global4, local3, .SLE3)
-+
-+	STPTR	local5, INPUT
-+	add	local7, 8, local7
-+	addcc   in2, -8, in2
-+
-+	bg	.ncbc.dec.next.block
-+	STPTR	local7, OUTPUT
-+
-+
-+.ncbc.dec.store.iv:
-+
-+	LDPTR	IVEC, local4              ! ivec
-+	store_little_endian(local4, in0, in1, local5, .SLE4)
-+
-+.ncbc.dec.finish:
-+
-+	ret
-+	restore
-+
-+.ncbc.dec.seven.or.less:
-+
-+	load_little_endian_inc(local5, in0, in1, local3, .LLE13)     ! ivec
-+
-+	store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv)
-+
-+
-+.DES_ncbc_encrypt.end:
-+	.size	 DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt
-+
-+
-+! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc)
-+! **************************************************************************
-+
-+
-+	.align 32
-+	.global DES_ede3_cbc_encrypt
-+	.type	 DES_ede3_cbc_encrypt,#function
-+
-+DES_ede3_cbc_encrypt:
-+
-+	save	%sp, FRAME, %sp
-+
-+	define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] })
-+	define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
-+	define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
-+
-+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
-+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
-+1:	call	.+8
-+	add	%o7,global1,global1
-+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
-+
-+	LDPTR	[%fp+BIAS+ARG0+7*ARGSZ], local3          ! enc
-+	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
-+	cmp	local3, 0                 ! enc
-+
-+	be	.ede3.dec
-+	STPTR	in4, KS2
-+
-+	STPTR	in5, KS3
-+
-+	load_little_endian(local4, in5, out5, local3, .LLE6)  ! ivec
-+
-+	addcc	in2, -8, in2              ! bytes missing after next block
-+
-+	bl	.ede3.enc.seven.or.less
-+	STPTR	in3, KS1
-+
-+.ede3.enc.next.block:
-+
-+	load_little_endian(in0, out4, global4, local3, .LLE7)
-+
-+.ede3.enc.next.block_1:
-+
-+	LDPTR	KS2, in4
-+	xor	in5, out4, in5            ! iv xor
-+	xor	out5, global4, out5       ! iv xor
-+
-+	LDPTR	KS1, in3
-+	add	in4, 120, in4             ! for decryption we use last subkey first
-+	nop
-+
-+	ip_macro(in5, out5, in5, out5, in3)
-+
-+.ede3.enc.next.block_2:
-+
-+	call .des_enc                     ! ks1 in3
-+	nop
-+
-+	call .des_dec                     ! ks2 in4
-+	LDPTR	KS3, in3
-+
-+	call .des_enc                     ! ks3 in3  compares in2 to 8
-+	nop
-+
-+	bl	.ede3.enc.next.block_fp
-+	add	in0, 8, in0
-+
-+	! If 8 or more bytes are to be encrypted after this block,
-+	! we combine final permutation for this block with initial
-+	! permutation for next block. Load next block:
-+
-+	load_little_endian(in0, global3, global4, local5, .LLE11)
-+
-+	!  parameter 1   original left
-+	!  parameter 2   original right
-+	!  parameter 3   left ip
-+	!  parameter 4   right ip
-+	!  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
-+	!                2: mov in4 to in3
-+	!
-+	! also adds -8 to length in2 and loads loop counter to out4
-+
-+	fp_ip_macro(out0, out1, global3, global4, 1)
-+
-+	store_little_endian(in1, out0, out1, local3, .SLE9)  ! block
-+
-+	mov 	in5, local1
-+	xor	global3, out5, in5        ! iv xor next block
-+
-+	ld	[in3], out0               ! key 7531
-+	add	global1, 512, global3     ! address sbox 3
-+	xor	global4, local1, out5     ! iv xor next block
-+
-+	ld	[in3+4], out1             ! key 8642
-+	add	global1, 768, global4     ! address sbox 4
-+	ba	.ede3.enc.next.block_2
-+	add	in1, 8, in1
-+
-+.ede3.enc.next.block_fp:
-+
-+	fp_macro(in5, out5)
-+
-+	store_little_endian(in1, in5, out5, local3, .SLE5)  ! block
-+
-+	addcc   in2, -8, in2              ! bytes missing when next block done
-+
-+	bpos	.ede3.enc.next.block
-+	add	in1, 8, in1
-+
-+.ede3.enc.seven.or.less:
-+
-+	cmp	in2, -8
-+
-+	ble	.ede3.enc.finish
-+	nop
-+
-+	add	in2, 8, local1            ! bytes to load
-+
-+	! addr, length, dest left, dest right, temp, temp2, label, ret label
-+	load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1)
-+
-+.ede3.enc.finish:
-+
-+	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
-+	store_little_endian(local4, in5, out5, local5, .SLE6)  ! ivec
-+
-+	ret
-+	restore
-+
-+.ede3.dec:
-+
-+	STPTR	in0, INPUT
-+	add	in5, 120, in5
-+
-+	STPTR	in1, OUTPUT
-+	mov	in0, local5
-+	add	in3, 120, in3
-+
-+	STPTR	in3, KS1
-+	cmp	in2, 0
-+
-+	ble	.ede3.dec.finish
-+	STPTR	in5, KS3
-+
-+	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local7          ! iv
-+	load_little_endian(local7, in0, in1, local3, .LLE8)
-+
-+.ede3.dec.next.block:
-+
-+	load_little_endian(local5, in5, out5, local3, .LLE9)
-+
-+	! parameter 6  1/2 for include encryption/decryption
-+	! parameter 7  1 for mov in1 to in3
-+	! parameter 8  1 for mov in3 to in4
-+	! parameter 9  1 for load ks3 and ks2 to in4 and in3
-+
-+	ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4
-+
-+	call .des_enc                     ! ks2 in3
-+	LDPTR	KS1, in4
-+
-+	call .des_dec                     ! ks1 in4
-+	nop
-+
-+	fp_macro(out5, in5, 0, 1)   ! 1 for input and output address local5/7
-+
-+	! in2 is bytes left to be stored
-+	! in2 is compared to 8 in the rounds
-+
-+	xor	out5, in0, out4
-+	bl	.ede3.dec.seven.or.less
-+	xor	in5, in1, global4
-+
-+	load_little_endian_inc(local5, in0, in1, local3, .LLE10)   ! iv next block
-+
-+	store_little_endian(local7, out4, global4, local3, .SLE7)  ! block
-+
-+	STPTR	local5, INPUT
-+	addcc   in2, -8, in2
-+	add	local7, 8, local7
-+
-+	bg	.ede3.dec.next.block
-+	STPTR	local7, OUTPUT
-+
-+.ede3.dec.store.iv:
-+
-+	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
-+	store_little_endian(local4, in0, in1, local5, .SLE8)  ! ivec
-+
-+.ede3.dec.finish:
-+
-+	ret
-+	restore
-+
-+.ede3.dec.seven.or.less:
-+
-+	load_little_endian_inc(local5, in0, in1, local3, .LLE14)     ! iv
-+
-+	store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv)
-+
-+
-+.DES_ede3_cbc_encrypt.end:
-+	.size	 DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt
-+
-+	.align	256
-+	.type	 .des_and,#object
-+	.size	 .des_and,284
-+
-+.des_and:
-+
-+! This table is used for AND 0xFC when it is known that register
-+! bits 8-31 are zero. Makes it possible to do three arithmetic
-+! operations in one cycle.
-+
-+	.byte  0, 0, 0, 0, 4, 4, 4, 4
-+	.byte  8, 8, 8, 8, 12, 12, 12, 12
-+	.byte  16, 16, 16, 16, 20, 20, 20, 20
-+	.byte  24, 24, 24, 24, 28, 28, 28, 28
-+	.byte  32, 32, 32, 32, 36, 36, 36, 36
-+	.byte  40, 40, 40, 40, 44, 44, 44, 44
-+	.byte  48, 48, 48, 48, 52, 52, 52, 52
-+	.byte  56, 56, 56, 56, 60, 60, 60, 60
-+	.byte  64, 64, 64, 64, 68, 68, 68, 68
-+	.byte  72, 72, 72, 72, 76, 76, 76, 76
-+	.byte  80, 80, 80, 80, 84, 84, 84, 84
-+	.byte  88, 88, 88, 88, 92, 92, 92, 92
-+	.byte  96, 96, 96, 96, 100, 100, 100, 100
-+	.byte  104, 104, 104, 104, 108, 108, 108, 108
-+	.byte  112, 112, 112, 112, 116, 116, 116, 116
-+	.byte  120, 120, 120, 120, 124, 124, 124, 124
-+	.byte  128, 128, 128, 128, 132, 132, 132, 132
-+	.byte  136, 136, 136, 136, 140, 140, 140, 140
-+	.byte  144, 144, 144, 144, 148, 148, 148, 148
-+	.byte  152, 152, 152, 152, 156, 156, 156, 156
-+	.byte  160, 160, 160, 160, 164, 164, 164, 164
-+	.byte  168, 168, 168, 168, 172, 172, 172, 172
-+	.byte  176, 176, 176, 176, 180, 180, 180, 180
-+	.byte  184, 184, 184, 184, 188, 188, 188, 188
-+	.byte  192, 192, 192, 192, 196, 196, 196, 196
-+	.byte  200, 200, 200, 200, 204, 204, 204, 204
-+	.byte  208, 208, 208, 208, 212, 212, 212, 212
-+	.byte  216, 216, 216, 216, 220, 220, 220, 220
-+	.byte  224, 224, 224, 224, 228, 228, 228, 228
-+	.byte  232, 232, 232, 232, 236, 236, 236, 236
-+	.byte  240, 240, 240, 240, 244, 244, 244, 244
-+	.byte  248, 248, 248, 248, 252, 252, 252, 252
-+
-+	! 5 numbers for initil/final permutation
-+
-+	.word   0x0f0f0f0f                ! offset 256
-+	.word	0x0000ffff                ! 260
-+	.word	0x33333333                ! 264
-+	.word	0x00ff00ff                ! 268
-+	.word	0x55555555                ! 272
-+
-+	.word	0                         ! 276
-+	.word	LOOPS                     ! 280
-+	.word	0x0000FC00                ! 284
-+
-+	.global	DES_SPtrans
-+	.type	DES_SPtrans,#object
-+	.size	DES_SPtrans,2048
-+.align	64
-+DES_SPtrans:
-+.PIC.DES_SPtrans:
-+	! nibble 0
-+	.word	0x02080800, 0x00080000, 0x02000002, 0x02080802
-+	.word	0x02000000, 0x00080802, 0x00080002, 0x02000002
-+	.word	0x00080802, 0x02080800, 0x02080000, 0x00000802
-+	.word	0x02000802, 0x02000000, 0x00000000, 0x00080002
-+	.word	0x00080000, 0x00000002, 0x02000800, 0x00080800
-+	.word	0x02080802, 0x02080000, 0x00000802, 0x02000800
-+	.word	0x00000002, 0x00000800, 0x00080800, 0x02080002
-+	.word	0x00000800, 0x02000802, 0x02080002, 0x00000000
-+	.word	0x00000000, 0x02080802, 0x02000800, 0x00080002
-+	.word	0x02080800, 0x00080000, 0x00000802, 0x02000800
-+	.word	0x02080002, 0x00000800, 0x00080800, 0x02000002
-+	.word	0x00080802, 0x00000002, 0x02000002, 0x02080000
-+	.word	0x02080802, 0x00080800, 0x02080000, 0x02000802
-+	.word	0x02000000, 0x00000802, 0x00080002, 0x00000000
-+	.word	0x00080000, 0x02000000, 0x02000802, 0x02080800
-+	.word	0x00000002, 0x02080002, 0x00000800, 0x00080802
-+	! nibble 1
-+	.word	0x40108010, 0x00000000, 0x00108000, 0x40100000
-+	.word	0x40000010, 0x00008010, 0x40008000, 0x00108000
-+	.word	0x00008000, 0x40100010, 0x00000010, 0x40008000
-+	.word	0x00100010, 0x40108000, 0x40100000, 0x00000010
-+	.word	0x00100000, 0x40008010, 0x40100010, 0x00008000
-+	.word	0x00108010, 0x40000000, 0x00000000, 0x00100010
-+	.word	0x40008010, 0x00108010, 0x40108000, 0x40000010
-+	.word	0x40000000, 0x00100000, 0x00008010, 0x40108010
-+	.word	0x00100010, 0x40108000, 0x40008000, 0x00108010
-+	.word	0x40108010, 0x00100010, 0x40000010, 0x00000000
-+	.word	0x40000000, 0x00008010, 0x00100000, 0x40100010
-+	.word	0x00008000, 0x40000000, 0x00108010, 0x40008010
-+	.word	0x40108000, 0x00008000, 0x00000000, 0x40000010
-+	.word	0x00000010, 0x40108010, 0x00108000, 0x40100000
-+	.word	0x40100010, 0x00100000, 0x00008010, 0x40008000
-+	.word	0x40008010, 0x00000010, 0x40100000, 0x00108000
-+	! nibble 2
-+	.word	0x04000001, 0x04040100, 0x00000100, 0x04000101
-+	.word	0x00040001, 0x04000000, 0x04000101, 0x00040100
-+	.word	0x04000100, 0x00040000, 0x04040000, 0x00000001
-+	.word	0x04040101, 0x00000101, 0x00000001, 0x04040001
-+	.word	0x00000000, 0x00040001, 0x04040100, 0x00000100
-+	.word	0x00000101, 0x04040101, 0x00040000, 0x04000001
-+	.word	0x04040001, 0x04000100, 0x00040101, 0x04040000
-+	.word	0x00040100, 0x00000000, 0x04000000, 0x00040101
-+	.word	0x04040100, 0x00000100, 0x00000001, 0x00040000
-+	.word	0x00000101, 0x00040001, 0x04040000, 0x04000101
-+	.word	0x00000000, 0x04040100, 0x00040100, 0x04040001
-+	.word	0x00040001, 0x04000000, 0x04040101, 0x00000001
-+	.word	0x00040101, 0x04000001, 0x04000000, 0x04040101
-+	.word	0x00040000, 0x04000100, 0x04000101, 0x00040100
-+	.word	0x04000100, 0x00000000, 0x04040001, 0x00000101
-+	.word	0x04000001, 0x00040101, 0x00000100, 0x04040000
-+	! nibble 3
-+	.word	0x00401008, 0x10001000, 0x00000008, 0x10401008
-+	.word	0x00000000, 0x10400000, 0x10001008, 0x00400008
-+	.word	0x10401000, 0x10000008, 0x10000000, 0x00001008
-+	.word	0x10000008, 0x00401008, 0x00400000, 0x10000000
-+	.word	0x10400008, 0x00401000, 0x00001000, 0x00000008
-+	.word	0x00401000, 0x10001008, 0x10400000, 0x00001000
-+	.word	0x00001008, 0x00000000, 0x00400008, 0x10401000
-+	.word	0x10001000, 0x10400008, 0x10401008, 0x00400000
-+	.word	0x10400008, 0x00001008, 0x00400000, 0x10000008
-+	.word	0x00401000, 0x10001000, 0x00000008, 0x10400000
-+	.word	0x10001008, 0x00000000, 0x00001000, 0x00400008
-+	.word	0x00000000, 0x10400008, 0x10401000, 0x00001000
-+	.word	0x10000000, 0x10401008, 0x00401008, 0x00400000
-+	.word	0x10401008, 0x00000008, 0x10001000, 0x00401008
-+	.word	0x00400008, 0x00401000, 0x10400000, 0x10001008
-+	.word	0x00001008, 0x10000000, 0x10000008, 0x10401000
-+	! nibble 4
-+	.word	0x08000000, 0x00010000, 0x00000400, 0x08010420
-+	.word	0x08010020, 0x08000400, 0x00010420, 0x08010000
-+	.word	0x00010000, 0x00000020, 0x08000020, 0x00010400
-+	.word	0x08000420, 0x08010020, 0x08010400, 0x00000000
-+	.word	0x00010400, 0x08000000, 0x00010020, 0x00000420
-+	.word	0x08000400, 0x00010420, 0x00000000, 0x08000020
-+	.word	0x00000020, 0x08000420, 0x08010420, 0x00010020
-+	.word	0x08010000, 0x00000400, 0x00000420, 0x08010400
-+	.word	0x08010400, 0x08000420, 0x00010020, 0x08010000
-+	.word	0x00010000, 0x00000020, 0x08000020, 0x08000400
-+	.word	0x08000000, 0x00010400, 0x08010420, 0x00000000
-+	.word	0x00010420, 0x08000000, 0x00000400, 0x00010020
-+	.word	0x08000420, 0x00000400, 0x00000000, 0x08010420
-+	.word	0x08010020, 0x08010400, 0x00000420, 0x00010000
-+	.word	0x00010400, 0x08010020, 0x08000400, 0x00000420
-+	.word	0x00000020, 0x00010420, 0x08010000, 0x08000020
-+	! nibble 5
-+	.word	0x80000040, 0x00200040, 0x00000000, 0x80202000
-+	.word	0x00200040, 0x00002000, 0x80002040, 0x00200000
-+	.word	0x00002040, 0x80202040, 0x00202000, 0x80000000
-+	.word	0x80002000, 0x80000040, 0x80200000, 0x00202040
-+	.word	0x00200000, 0x80002040, 0x80200040, 0x00000000
-+	.word	0x00002000, 0x00000040, 0x80202000, 0x80200040
-+	.word	0x80202040, 0x80200000, 0x80000000, 0x00002040
-+	.word	0x00000040, 0x00202000, 0x00202040, 0x80002000
-+	.word	0x00002040, 0x80000000, 0x80002000, 0x00202040
-+	.word	0x80202000, 0x00200040, 0x00000000, 0x80002000
-+	.word	0x80000000, 0x00002000, 0x80200040, 0x00200000
-+	.word	0x00200040, 0x80202040, 0x00202000, 0x00000040
-+	.word	0x80202040, 0x00202000, 0x00200000, 0x80002040
-+	.word	0x80000040, 0x80200000, 0x00202040, 0x00000000
-+	.word	0x00002000, 0x80000040, 0x80002040, 0x80202000
-+	.word	0x80200000, 0x00002040, 0x00000040, 0x80200040
-+	! nibble 6
-+	.word	0x00004000, 0x00000200, 0x01000200, 0x01000004
-+	.word	0x01004204, 0x00004004, 0x00004200, 0x00000000
-+	.word	0x01000000, 0x01000204, 0x00000204, 0x01004000
-+	.word	0x00000004, 0x01004200, 0x01004000, 0x00000204
-+	.word	0x01000204, 0x00004000, 0x00004004, 0x01004204
-+	.word	0x00000000, 0x01000200, 0x01000004, 0x00004200
-+	.word	0x01004004, 0x00004204, 0x01004200, 0x00000004
-+	.word	0x00004204, 0x01004004, 0x00000200, 0x01000000
-+	.word	0x00004204, 0x01004000, 0x01004004, 0x00000204
-+	.word	0x00004000, 0x00000200, 0x01000000, 0x01004004
-+	.word	0x01000204, 0x00004204, 0x00004200, 0x00000000
-+	.word	0x00000200, 0x01000004, 0x00000004, 0x01000200
-+	.word	0x00000000, 0x01000204, 0x01000200, 0x00004200
-+	.word	0x00000204, 0x00004000, 0x01004204, 0x01000000
-+	.word	0x01004200, 0x00000004, 0x00004004, 0x01004204
-+	.word	0x01000004, 0x01004200, 0x01004000, 0x00004004
-+	! nibble 7
-+	.word	0x20800080, 0x20820000, 0x00020080, 0x00000000
-+	.word	0x20020000, 0x00800080, 0x20800000, 0x20820080
-+	.word	0x00000080, 0x20000000, 0x00820000, 0x00020080
-+	.word	0x00820080, 0x20020080, 0x20000080, 0x20800000
-+	.word	0x00020000, 0x00820080, 0x00800080, 0x20020000
-+	.word	0x20820080, 0x20000080, 0x00000000, 0x00820000
-+	.word	0x20000000, 0x00800000, 0x20020080, 0x20800080
-+	.word	0x00800000, 0x00020000, 0x20820000, 0x00000080
-+	.word	0x00800000, 0x00020000, 0x20000080, 0x20820080
-+	.word	0x00020080, 0x20000000, 0x00000000, 0x00820000
-+	.word	0x20800080, 0x20020080, 0x20020000, 0x00800080
-+	.word	0x20820000, 0x00000080, 0x00800080, 0x20020000
-+	.word	0x20820080, 0x00800000, 0x20800000, 0x20000080
-+	.word	0x00820000, 0x00020080, 0x20020080, 0x20800000
-+	.word	0x00000080, 0x20820000, 0x00820080, 0x00000000
-+	.word	0x20000000, 0x20800080, 0x00020000, 0x00820080
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/desboth.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/desboth.pl
-new file mode 100644
-index 0000000..76759fb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/desboth.pl
-@@ -0,0 +1,86 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+$L="edi";
-+$R="esi";
-+
-+sub DES_encrypt3
-+	{
-+	local($name,$enc)=@_;
-+
-+	&function_begin_B($name,"");
-+	&push("ebx");
-+	&mov("ebx",&wparam(0));
-+
-+	&push("ebp");
-+	&push("esi");
-+
-+	&push("edi");
-+
-+	&comment("");
-+	&comment("Load the data words");
-+	&mov($L,&DWP(0,"ebx","",0));
-+	&mov($R,&DWP(4,"ebx","",0));
-+	&stack_push(3);
-+
-+	&comment("");
-+	&comment("IP");
-+	&IP_new($L,$R,"edx",0);
-+
-+	# put them back
-+	
-+	if ($enc)
-+		{
-+		&mov(&DWP(4,"ebx","",0),$R);
-+		 &mov("eax",&wparam(1));
-+		&mov(&DWP(0,"ebx","",0),"edx");
-+		 &mov("edi",&wparam(2));
-+		 &mov("esi",&wparam(3));
-+		}
-+	else
-+		{
-+		&mov(&DWP(4,"ebx","",0),$R);
-+		 &mov("esi",&wparam(1));
-+		&mov(&DWP(0,"ebx","",0),"edx");
-+		 &mov("edi",&wparam(2));
-+		 &mov("eax",&wparam(3));
-+		}
-+	&mov(&swtmp(2),	(DWC(($enc)?"1":"0")));
-+	&mov(&swtmp(1),	"eax");
-+	&mov(&swtmp(0),	"ebx");
-+	&call("DES_encrypt2");
-+	&mov(&swtmp(2),	(DWC(($enc)?"0":"1")));
-+	&mov(&swtmp(1),	"edi");
-+	&mov(&swtmp(0),	"ebx");
-+	&call("DES_encrypt2");
-+	&mov(&swtmp(2),	(DWC(($enc)?"1":"0")));
-+	&mov(&swtmp(1),	"esi");
-+	&mov(&swtmp(0),	"ebx");
-+	&call("DES_encrypt2");
-+
-+	&stack_pop(3);
-+	&mov($L,&DWP(0,"ebx","",0));
-+	&mov($R,&DWP(4,"ebx","",0));
-+
-+	&comment("");
-+	&comment("FP");
-+	&FP_new($L,$R,"eax",0);
-+
-+	&mov(&DWP(0,"ebx","",0),"eax");
-+	&mov(&DWP(4,"ebx","",0),$R);
-+
-+	&pop("edi");
-+	&pop("esi");
-+	&pop("ebp");
-+	&pop("ebx");
-+	&ret();
-+	&function_end_B($name);
-+	}
-+
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/dest4-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/dest4-sparcv9.pl
-new file mode 100644
-index 0000000..4a6e29f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/asm/dest4-sparcv9.pl
-@@ -0,0 +1,627 @@
-+#! /usr/bin/env perl
-+# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by David S. Miller  and Andy Polyakov
-+# . The module is licensed under 2-clause BSD
-+# license. March 2013. All rights reserved.
-+# ====================================================================
-+
-+######################################################################
-+# DES for SPARC T4.
-+#
-+# As with other hardware-assisted ciphers CBC encrypt results [for
-+# aligned data] are virtually identical to critical path lengths:
-+#
-+#		DES		Triple-DES
-+# CBC encrypt	4.14/4.15(*)	11.7/11.7
-+# CBC decrypt	1.77/4.11(**)	6.42/7.47
-+#
-+#			 (*)	numbers after slash are for
-+#				misaligned data;
-+#			 (**)	this is result for largest
-+#				block size, unlike all other
-+#				cases smaller blocks results
-+#				are better[?];
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "sparcv9_modes.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#ifdef	__arch64__
-+.register       %g2,#scratch
-+.register       %g3,#scratch
-+#endif
-+
-+.text
-+___
-+
-+{ my ($inp,$out)=("%o0","%o1");
-+
-+$code.=<<___;
-+.align	32
-+.globl	des_t4_key_expand
-+.type	des_t4_key_expand,#function
-+des_t4_key_expand:
-+	andcc		$inp, 0x7, %g0
-+	alignaddr	$inp, %g0, $inp
-+	bz,pt		%icc, 1f
-+	ldd		[$inp + 0x00], %f0
-+	ldd		[$inp + 0x08], %f2
-+	faligndata	%f0, %f2, %f0
-+1:	des_kexpand	%f0, 0, %f0
-+	des_kexpand	%f0, 1, %f2
-+	std		%f0, [$out + 0x00]
-+	des_kexpand	%f2, 3, %f6
-+	std		%f2, [$out + 0x08]
-+	des_kexpand	%f2, 2, %f4
-+	des_kexpand	%f6, 3, %f10
-+	std		%f6, [$out + 0x18]
-+	des_kexpand	%f6, 2, %f8
-+	std		%f4, [$out + 0x10]
-+	des_kexpand	%f10, 3, %f14
-+	std		%f10, [$out + 0x28]
-+	des_kexpand	%f10, 2, %f12
-+	std		%f8, [$out + 0x20]
-+	des_kexpand	%f14, 1, %f16
-+	std		%f14, [$out + 0x38]
-+	des_kexpand	%f16, 3, %f20
-+	std		%f12, [$out + 0x30]
-+	des_kexpand	%f16, 2, %f18
-+	std		%f16, [$out + 0x40]
-+	des_kexpand	%f20, 3, %f24
-+	std		%f20, [$out + 0x50]
-+	des_kexpand	%f20, 2, %f22
-+	std		%f18, [$out + 0x48]
-+	des_kexpand	%f24, 3, %f28
-+	std		%f24, [$out + 0x60]
-+	des_kexpand	%f24, 2, %f26
-+	std		%f22, [$out + 0x58]
-+	des_kexpand	%f28, 1, %f30
-+	std		%f28, [$out + 0x70]
-+	std		%f26, [$out + 0x68]
-+	retl
-+	std		%f30, [$out + 0x78]
-+.size	des_t4_key_expand,.-des_t4_key_expand
-+___
-+}
-+{ my ($inp,$out,$len,$key,$ivec) = map("%o$_",(0..4));
-+  my ($ileft,$iright,$omask) = map("%g$_",(1..3));
-+
-+$code.=<<___;
-+.globl	des_t4_cbc_encrypt
-+.align	32
-+des_t4_cbc_encrypt:
-+	cmp		$len, 0
-+	be,pn		$::size_t_cc, .Lcbc_abort
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
-+	ld		[$ivec + 0], %f0	! load ivec
-+	ld		[$ivec + 4], %f1
-+
-+	and		$inp, 7, $ileft
-+	andn		$inp, 7, $inp
-+	sll		$ileft, 3, $ileft
-+	mov		0xff, $omask
-+	prefetch	[$inp], 20
-+	prefetch	[$inp + 63], 20
-+	sub		%g0, $ileft, $iright
-+	and		$out, 7, %g4
-+	alignaddrl	$out, %g0, $out
-+	srl		$omask, %g4, $omask
-+	srlx		$len, 3, $len
-+	movrz		%g4, 0, $omask
-+	prefetch	[$out], 22
-+
-+	ldd		[$key + 0x00], %f4	! load key schedule
-+	ldd		[$key + 0x08], %f6
-+	ldd		[$key + 0x10], %f8
-+	ldd		[$key + 0x18], %f10
-+	ldd		[$key + 0x20], %f12
-+	ldd		[$key + 0x28], %f14
-+	ldd		[$key + 0x30], %f16
-+	ldd		[$key + 0x38], %f18
-+	ldd		[$key + 0x40], %f20
-+	ldd		[$key + 0x48], %f22
-+	ldd		[$key + 0x50], %f24
-+	ldd		[$key + 0x58], %f26
-+	ldd		[$key + 0x60], %f28
-+	ldd		[$key + 0x68], %f30
-+	ldd		[$key + 0x70], %f32
-+	ldd		[$key + 0x78], %f34
-+
-+.Ldes_cbc_enc_loop:
-+	ldx		[$inp + 0], %g4
-+	brz,pt		$ileft, 4f
-+	nop
-+
-+	ldx		[$inp + 8], %g5
-+	sllx		%g4, $ileft, %g4
-+	srlx		%g5, $iright, %g5
-+	or		%g5, %g4, %g4
-+4:
-+	movxtod		%g4, %f2
-+	prefetch	[$inp + 8+63], 20
-+	add		$inp, 8, $inp
-+	fxor		%f2, %f0, %f0		! ^= ivec
-+	prefetch	[$out + 63], 22
-+
-+	des_ip		%f0, %f0
-+	des_round	%f4, %f6, %f0, %f0
-+	des_round	%f8, %f10, %f0, %f0
-+	des_round	%f12, %f14, %f0, %f0
-+	des_round	%f16, %f18, %f0, %f0
-+	des_round	%f20, %f22, %f0, %f0
-+	des_round	%f24, %f26, %f0, %f0
-+	des_round	%f28, %f30, %f0, %f0
-+	des_round	%f32, %f34, %f0, %f0
-+	des_iip		%f0, %f0
-+
-+	brnz,pn		$omask, 2f
-+	sub		$len, 1, $len
-+
-+	std		%f0, [$out + 0]
-+	brnz,pt		$len, .Ldes_cbc_enc_loop
-+	add		$out, 8, $out
-+
-+	st		%f0, [$ivec + 0]	! write out ivec
-+	retl
-+	st		%f1, [$ivec + 4]
-+.Lcbc_abort:
-+	retl
-+	nop
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %g4		! avoid read-after-write hazard
-+						! and ~4x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f2		! handle unaligned output
-+
-+	stda		%f2, [$out + $omask]0xc0	! partial store
-+	add		$out, 8, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f2, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .Ldes_cbc_enc_loop+4
-+	orn		%g0, $omask, $omask
-+
-+	st		%f0, [$ivec + 0]	! write out ivec
-+	retl
-+	st		%f1, [$ivec + 4]
-+.type	des_t4_cbc_encrypt,#function
-+.size	des_t4_cbc_encrypt,.-des_t4_cbc_encrypt
-+
-+.globl	des_t4_cbc_decrypt
-+.align	32
-+des_t4_cbc_decrypt:
-+	cmp		$len, 0
-+	be,pn		$::size_t_cc, .Lcbc_abort
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
-+	ld		[$ivec + 0], %f2	! load ivec
-+	ld		[$ivec + 4], %f3
-+
-+	and		$inp, 7, $ileft
-+	andn		$inp, 7, $inp
-+	sll		$ileft, 3, $ileft
-+	mov		0xff, $omask
-+	prefetch	[$inp], 20
-+	prefetch	[$inp + 63], 20
-+	sub		%g0, $ileft, $iright
-+	and		$out, 7, %g4
-+	alignaddrl	$out, %g0, $out
-+	srl		$omask, %g4, $omask
-+	srlx		$len, 3, $len
-+	movrz		%g4, 0, $omask
-+	prefetch	[$out], 22
-+
-+	ldd		[$key + 0x78], %f4	! load key schedule
-+	ldd		[$key + 0x70], %f6
-+	ldd		[$key + 0x68], %f8
-+	ldd		[$key + 0x60], %f10
-+	ldd		[$key + 0x58], %f12
-+	ldd		[$key + 0x50], %f14
-+	ldd		[$key + 0x48], %f16
-+	ldd		[$key + 0x40], %f18
-+	ldd		[$key + 0x38], %f20
-+	ldd		[$key + 0x30], %f22
-+	ldd		[$key + 0x28], %f24
-+	ldd		[$key + 0x20], %f26
-+	ldd		[$key + 0x18], %f28
-+	ldd		[$key + 0x10], %f30
-+	ldd		[$key + 0x08], %f32
-+	ldd		[$key + 0x00], %f34
-+
-+.Ldes_cbc_dec_loop:
-+	ldx		[$inp + 0], %g4
-+	brz,pt		$ileft, 4f
-+	nop
-+
-+	ldx		[$inp + 8], %g5
-+	sllx		%g4, $ileft, %g4
-+	srlx		%g5, $iright, %g5
-+	or		%g5, %g4, %g4
-+4:
-+	movxtod		%g4, %f0
-+	prefetch	[$inp + 8+63], 20
-+	add		$inp, 8, $inp
-+	prefetch	[$out + 63], 22
-+
-+	des_ip		%f0, %f0
-+	des_round	%f4, %f6, %f0, %f0
-+	des_round	%f8, %f10, %f0, %f0
-+	des_round	%f12, %f14, %f0, %f0
-+	des_round	%f16, %f18, %f0, %f0
-+	des_round	%f20, %f22, %f0, %f0
-+	des_round	%f24, %f26, %f0, %f0
-+	des_round	%f28, %f30, %f0, %f0
-+	des_round	%f32, %f34, %f0, %f0
-+	des_iip		%f0, %f0
-+
-+	fxor		%f2, %f0, %f0		! ^= ivec
-+	movxtod		%g4, %f2
-+
-+	brnz,pn		$omask, 2f
-+	sub		$len, 1, $len
-+
-+	std		%f0, [$out + 0]
-+	brnz,pt		$len, .Ldes_cbc_dec_loop
-+	add		$out, 8, $out
-+
-+	st		%f2, [$ivec + 0]	! write out ivec
-+	retl
-+	st		%f3, [$ivec + 4]
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %g4		! avoid read-after-write hazard
-+						! and ~4x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f0		! handle unaligned output
-+
-+	stda		%f0, [$out + $omask]0xc0	! partial store
-+	add		$out, 8, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f0, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .Ldes_cbc_dec_loop+4
-+	orn		%g0, $omask, $omask
-+
-+	st		%f2, [$ivec + 0]	! write out ivec
-+	retl
-+	st		%f3, [$ivec + 4]
-+.type	des_t4_cbc_decrypt,#function
-+.size	des_t4_cbc_decrypt,.-des_t4_cbc_decrypt
-+___
-+
-+# One might wonder why does one have back-to-back des_iip/des_ip
-+# pairs between EDE passes. Indeed, aren't they inverse of each other?
-+# They almost are. Outcome of the pair is 32-bit words being swapped
-+# in target register. Consider pair of des_iip/des_ip as a way to
-+# perform the due swap, it's actually fastest way in this case.
-+
-+$code.=<<___;
-+.globl	des_t4_ede3_cbc_encrypt
-+.align	32
-+des_t4_ede3_cbc_encrypt:
-+	cmp		$len, 0
-+	be,pn		$::size_t_cc, .Lcbc_abort
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
-+	ld		[$ivec + 0], %f0	! load ivec
-+	ld		[$ivec + 4], %f1
-+
-+	and		$inp, 7, $ileft
-+	andn		$inp, 7, $inp
-+	sll		$ileft, 3, $ileft
-+	mov		0xff, $omask
-+	prefetch	[$inp], 20
-+	prefetch	[$inp + 63], 20
-+	sub		%g0, $ileft, $iright
-+	and		$out, 7, %g4
-+	alignaddrl	$out, %g0, $out
-+	srl		$omask, %g4, $omask
-+	srlx		$len, 3, $len
-+	movrz		%g4, 0, $omask
-+	prefetch	[$out], 22
-+
-+	ldd		[$key + 0x00], %f4	! load key schedule
-+	ldd		[$key + 0x08], %f6
-+	ldd		[$key + 0x10], %f8
-+	ldd		[$key + 0x18], %f10
-+	ldd		[$key + 0x20], %f12
-+	ldd		[$key + 0x28], %f14
-+	ldd		[$key + 0x30], %f16
-+	ldd		[$key + 0x38], %f18
-+	ldd		[$key + 0x40], %f20
-+	ldd		[$key + 0x48], %f22
-+	ldd		[$key + 0x50], %f24
-+	ldd		[$key + 0x58], %f26
-+	ldd		[$key + 0x60], %f28
-+	ldd		[$key + 0x68], %f30
-+	ldd		[$key + 0x70], %f32
-+	ldd		[$key + 0x78], %f34
-+
-+.Ldes_ede3_cbc_enc_loop:
-+	ldx		[$inp + 0], %g4
-+	brz,pt		$ileft, 4f
-+	nop
-+
-+	ldx		[$inp + 8], %g5
-+	sllx		%g4, $ileft, %g4
-+	srlx		%g5, $iright, %g5
-+	or		%g5, %g4, %g4
-+4:
-+	movxtod		%g4, %f2
-+	prefetch	[$inp + 8+63], 20
-+	add		$inp, 8, $inp
-+	fxor		%f2, %f0, %f0		! ^= ivec
-+	prefetch	[$out + 63], 22
-+
-+	des_ip		%f0, %f0
-+	des_round	%f4, %f6, %f0, %f0
-+	des_round	%f8, %f10, %f0, %f0
-+	des_round	%f12, %f14, %f0, %f0
-+	des_round	%f16, %f18, %f0, %f0
-+	ldd		[$key + 0x100-0x08], %f36
-+	ldd		[$key + 0x100-0x10], %f38
-+	des_round	%f20, %f22, %f0, %f0
-+	ldd		[$key + 0x100-0x18], %f40
-+	ldd		[$key + 0x100-0x20], %f42
-+	des_round	%f24, %f26, %f0, %f0
-+	ldd		[$key + 0x100-0x28], %f44
-+	ldd		[$key + 0x100-0x30], %f46
-+	des_round	%f28, %f30, %f0, %f0
-+	ldd		[$key + 0x100-0x38], %f48
-+	ldd		[$key + 0x100-0x40], %f50
-+	des_round	%f32, %f34, %f0, %f0
-+	ldd		[$key + 0x100-0x48], %f52
-+	ldd		[$key + 0x100-0x50], %f54
-+	des_iip		%f0, %f0
-+
-+	ldd		[$key + 0x100-0x58], %f56
-+	ldd		[$key + 0x100-0x60], %f58
-+	des_ip		%f0, %f0
-+	ldd		[$key + 0x100-0x68], %f60
-+	ldd		[$key + 0x100-0x70], %f62
-+	des_round	%f36, %f38, %f0, %f0
-+	ldd		[$key + 0x100-0x78], %f36
-+	ldd		[$key + 0x100-0x80], %f38
-+	des_round	%f40, %f42, %f0, %f0
-+	des_round	%f44, %f46, %f0, %f0
-+	des_round	%f48, %f50, %f0, %f0
-+	ldd		[$key + 0x100+0x00], %f40
-+	ldd		[$key + 0x100+0x08], %f42
-+	des_round	%f52, %f54, %f0, %f0
-+	ldd		[$key + 0x100+0x10], %f44
-+	ldd		[$key + 0x100+0x18], %f46
-+	des_round	%f56, %f58, %f0, %f0
-+	ldd		[$key + 0x100+0x20], %f48
-+	ldd		[$key + 0x100+0x28], %f50
-+	des_round	%f60, %f62, %f0, %f0
-+	ldd		[$key + 0x100+0x30], %f52
-+	ldd		[$key + 0x100+0x38], %f54
-+	des_round	%f36, %f38, %f0, %f0
-+	ldd		[$key + 0x100+0x40], %f56
-+	ldd		[$key + 0x100+0x48], %f58
-+	des_iip		%f0, %f0
-+
-+	ldd		[$key + 0x100+0x50], %f60
-+	ldd		[$key + 0x100+0x58], %f62
-+	des_ip		%f0, %f0
-+	ldd		[$key + 0x100+0x60], %f36
-+	ldd		[$key + 0x100+0x68], %f38
-+	des_round	%f40, %f42, %f0, %f0
-+	ldd		[$key + 0x100+0x70], %f40
-+	ldd		[$key + 0x100+0x78], %f42
-+	des_round	%f44, %f46, %f0, %f0
-+	des_round	%f48, %f50, %f0, %f0
-+	des_round	%f52, %f54, %f0, %f0
-+	des_round	%f56, %f58, %f0, %f0
-+	des_round	%f60, %f62, %f0, %f0
-+	des_round	%f36, %f38, %f0, %f0
-+	des_round	%f40, %f42, %f0, %f0
-+	des_iip		%f0, %f0
-+
-+	brnz,pn		$omask, 2f
-+	sub		$len, 1, $len
-+
-+	std		%f0, [$out + 0]
-+	brnz,pt		$len, .Ldes_ede3_cbc_enc_loop
-+	add		$out, 8, $out
-+
-+	st		%f0, [$ivec + 0]	! write out ivec
-+	retl
-+	st		%f1, [$ivec + 4]
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %g4		! avoid read-after-write hazard
-+						! and ~2x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f2		! handle unaligned output
-+
-+	stda		%f2, [$out + $omask]0xc0	! partial store
-+	add		$out, 8, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f2, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .Ldes_ede3_cbc_enc_loop+4
-+	orn		%g0, $omask, $omask
-+
-+	st		%f0, [$ivec + 0]	! write out ivec
-+	retl
-+	st		%f1, [$ivec + 4]
-+.type	des_t4_ede3_cbc_encrypt,#function
-+.size	des_t4_ede3_cbc_encrypt,.-des_t4_ede3_cbc_encrypt
-+
-+.globl	des_t4_ede3_cbc_decrypt
-+.align	32
-+des_t4_ede3_cbc_decrypt:
-+	cmp		$len, 0
-+	be,pn		$::size_t_cc, .Lcbc_abort
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
-+	ld		[$ivec + 0], %f2	! load ivec
-+	ld		[$ivec + 4], %f3
-+
-+	and		$inp, 7, $ileft
-+	andn		$inp, 7, $inp
-+	sll		$ileft, 3, $ileft
-+	mov		0xff, $omask
-+	prefetch	[$inp], 20
-+	prefetch	[$inp + 63], 20
-+	sub		%g0, $ileft, $iright
-+	and		$out, 7, %g4
-+	alignaddrl	$out, %g0, $out
-+	srl		$omask, %g4, $omask
-+	srlx		$len, 3, $len
-+	movrz		%g4, 0, $omask
-+	prefetch	[$out], 22
-+
-+	ldd		[$key + 0x100+0x78], %f4	! load key schedule
-+	ldd		[$key + 0x100+0x70], %f6
-+	ldd		[$key + 0x100+0x68], %f8
-+	ldd		[$key + 0x100+0x60], %f10
-+	ldd		[$key + 0x100+0x58], %f12
-+	ldd		[$key + 0x100+0x50], %f14
-+	ldd		[$key + 0x100+0x48], %f16
-+	ldd		[$key + 0x100+0x40], %f18
-+	ldd		[$key + 0x100+0x38], %f20
-+	ldd		[$key + 0x100+0x30], %f22
-+	ldd		[$key + 0x100+0x28], %f24
-+	ldd		[$key + 0x100+0x20], %f26
-+	ldd		[$key + 0x100+0x18], %f28
-+	ldd		[$key + 0x100+0x10], %f30
-+	ldd		[$key + 0x100+0x08], %f32
-+	ldd		[$key + 0x100+0x00], %f34
-+
-+.Ldes_ede3_cbc_dec_loop:
-+	ldx		[$inp + 0], %g4
-+	brz,pt		$ileft, 4f
-+	nop
-+
-+	ldx		[$inp + 8], %g5
-+	sllx		%g4, $ileft, %g4
-+	srlx		%g5, $iright, %g5
-+	or		%g5, %g4, %g4
-+4:
-+	movxtod		%g4, %f0
-+	prefetch	[$inp + 8+63], 20
-+	add		$inp, 8, $inp
-+	prefetch	[$out + 63], 22
-+
-+	des_ip		%f0, %f0
-+	des_round	%f4, %f6, %f0, %f0
-+	des_round	%f8, %f10, %f0, %f0
-+	des_round	%f12, %f14, %f0, %f0
-+	des_round	%f16, %f18, %f0, %f0
-+	ldd		[$key + 0x80+0x00], %f36
-+	ldd		[$key + 0x80+0x08], %f38
-+	des_round	%f20, %f22, %f0, %f0
-+	ldd		[$key + 0x80+0x10], %f40
-+	ldd		[$key + 0x80+0x18], %f42
-+	des_round	%f24, %f26, %f0, %f0
-+	ldd		[$key + 0x80+0x20], %f44
-+	ldd		[$key + 0x80+0x28], %f46
-+	des_round	%f28, %f30, %f0, %f0
-+	ldd		[$key + 0x80+0x30], %f48
-+	ldd		[$key + 0x80+0x38], %f50
-+	des_round	%f32, %f34, %f0, %f0
-+	ldd		[$key + 0x80+0x40], %f52
-+	ldd		[$key + 0x80+0x48], %f54
-+	des_iip		%f0, %f0
-+
-+	ldd		[$key + 0x80+0x50], %f56
-+	ldd		[$key + 0x80+0x58], %f58
-+	des_ip		%f0, %f0
-+	ldd		[$key + 0x80+0x60], %f60
-+	ldd		[$key + 0x80+0x68], %f62
-+	des_round	%f36, %f38, %f0, %f0
-+	ldd		[$key + 0x80+0x70], %f36
-+	ldd		[$key + 0x80+0x78], %f38
-+	des_round	%f40, %f42, %f0, %f0
-+	des_round	%f44, %f46, %f0, %f0
-+	des_round	%f48, %f50, %f0, %f0
-+	ldd		[$key + 0x80-0x08], %f40
-+	ldd		[$key + 0x80-0x10], %f42
-+	des_round	%f52, %f54, %f0, %f0
-+	ldd		[$key + 0x80-0x18], %f44
-+	ldd		[$key + 0x80-0x20], %f46
-+	des_round	%f56, %f58, %f0, %f0
-+	ldd		[$key + 0x80-0x28], %f48
-+	ldd		[$key + 0x80-0x30], %f50
-+	des_round	%f60, %f62, %f0, %f0
-+	ldd		[$key + 0x80-0x38], %f52
-+	ldd		[$key + 0x80-0x40], %f54
-+	des_round	%f36, %f38, %f0, %f0
-+	ldd		[$key + 0x80-0x48], %f56
-+	ldd		[$key + 0x80-0x50], %f58
-+	des_iip		%f0, %f0
-+
-+	ldd		[$key + 0x80-0x58], %f60
-+	ldd		[$key + 0x80-0x60], %f62
-+	des_ip		%f0, %f0
-+	ldd		[$key + 0x80-0x68], %f36
-+	ldd		[$key + 0x80-0x70], %f38
-+	des_round	%f40, %f42, %f0, %f0
-+	ldd		[$key + 0x80-0x78], %f40
-+	ldd		[$key + 0x80-0x80], %f42
-+	des_round	%f44, %f46, %f0, %f0
-+	des_round	%f48, %f50, %f0, %f0
-+	des_round	%f52, %f54, %f0, %f0
-+	des_round	%f56, %f58, %f0, %f0
-+	des_round	%f60, %f62, %f0, %f0
-+	des_round	%f36, %f38, %f0, %f0
-+	des_round	%f40, %f42, %f0, %f0
-+	des_iip		%f0, %f0
-+
-+	fxor		%f2, %f0, %f0		! ^= ivec
-+	movxtod		%g4, %f2
-+
-+	brnz,pn		$omask, 2f
-+	sub		$len, 1, $len
-+
-+	std		%f0, [$out + 0]
-+	brnz,pt		$len, .Ldes_ede3_cbc_dec_loop
-+	add		$out, 8, $out
-+
-+	st		%f2, [$ivec + 0]	! write out ivec
-+	retl
-+	st		%f3, [$ivec + 4]
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %g4		! avoid read-after-write hazard
-+						! and ~3x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f0		! handle unaligned output
-+
-+	stda		%f0, [$out + $omask]0xc0	! partial store
-+	add		$out, 8, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f0, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .Ldes_ede3_cbc_dec_loop+4
-+	orn		%g0, $omask, $omask
-+
-+	st		%f2, [$ivec + 0]	! write out ivec
-+	retl
-+	st		%f3, [$ivec + 4]
-+.type	des_t4_ede3_cbc_decrypt,#function
-+.size	des_t4_ede3_cbc_decrypt,.-des_t4_ede3_cbc_decrypt
-+___
-+}
-+$code.=<<___;
-+.asciz  "DES for SPARC T4, David S. Miller, Andy Polyakov"
-+.align  4
-+___
-+
-+&emit_assembler();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/build.info
-new file mode 100644
-index 0000000..c0306cf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/build.info
-@@ -0,0 +1,17 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        set_key.c  ecb_enc.c  cbc_enc.c \
-+        ecb3_enc.c cfb64enc.c cfb64ede.c cfb_enc.c \
-+        ofb64ede.c ofb64enc.c ofb_enc.c \
-+        str2key.c  pcbc_enc.c qud_cksm.c rand_key.c \
-+        {- $target{des_asm_src} -} \
-+        fcrypt.c xcbc_enc.c rpc_enc.c  cbc_cksm.c
-+
-+GENERATE[des_enc-sparc.S]=asm/des_enc.m4
-+GENERATE[dest4-sparcv9.S]=asm/dest4-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[dest4-sparcv9.o]=..
-+
-+GENERATE[des-586.s]=asm/des-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS)
-+DEPEND[des-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
-+GENERATE[crypt586.s]=asm/crypt586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS)
-+DEPEND[crypt586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cbc_cksm.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cbc_cksm.c
-new file mode 100644
-index 0000000..a7bf068
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cbc_cksm.c
-@@ -0,0 +1,54 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "des_locl.h"
-+
-+DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output,
-+                       long length, DES_key_schedule *schedule,
-+                       const_DES_cblock *ivec)
-+{
-+    register DES_LONG tout0, tout1, tin0, tin1;
-+    register long l = length;
-+    DES_LONG tin[2];
-+    unsigned char *out = &(*output)[0];
-+    const unsigned char *iv = &(*ivec)[0];
-+
-+    c2l(iv, tout0);
-+    c2l(iv, tout1);
-+    for (; l > 0; l -= 8) {
-+        if (l >= 8) {
-+            c2l(in, tin0);
-+            c2l(in, tin1);
-+        } else
-+            c2ln(in, tin0, tin1, l);
-+
-+        tin0 ^= tout0;
-+        tin[0] = tin0;
-+        tin1 ^= tout1;
-+        tin[1] = tin1;
-+        DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT);
-+        /* fix 15/10/91 eay - thanks to keithr@sco.COM */
-+        tout0 = tin[0];
-+        tout1 = tin[1];
-+    }
-+    if (out != NULL) {
-+        l2c(tout0, out);
-+        l2c(tout1, out);
-+    }
-+    tout0 = tin0 = tin1 = tin[0] = tin[1] = 0;
-+    /*
-+     * Transform the data in tout1 so that it will match the return value
-+     * that the MIT Kerberos mit_des_cbc_cksum API returns.
-+     */
-+    tout1 = ((tout1 >> 24L) & 0x000000FF)
-+        | ((tout1 >> 8L) & 0x0000FF00)
-+        | ((tout1 << 8L) & 0x00FF0000)
-+        | ((tout1 << 24L) & 0xFF000000);
-+    return (tout1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cbc_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cbc_enc.c
-new file mode 100644
-index 0000000..92e773f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cbc_enc.c
-@@ -0,0 +1,12 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#define CBC_ENC_C__DONT_UPDATE_IV
-+
-+#include "ncbc_enc.c"           /* des_cbc_encrypt */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb64ede.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb64ede.c
-new file mode 100644
-index 0000000..5edb979
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb64ede.c
-@@ -0,0 +1,190 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "des_locl.h"
-+#include "e_os.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit cfb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+
-+void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
-+                            long length, DES_key_schedule *ks1,
-+                            DES_key_schedule *ks2, DES_key_schedule *ks3,
-+                            DES_cblock *ivec, int *num, int enc)
-+{
-+    register DES_LONG v0, v1;
-+    register long l = length;
-+    register int n = *num;
-+    DES_LONG ti[2];
-+    unsigned char *iv, c, cc;
-+
-+    iv = &(*ivec)[0];
-+    if (enc) {
-+        while (l--) {
-+            if (n == 0) {
-+                c2l(iv, v0);
-+                c2l(iv, v1);
-+
-+                ti[0] = v0;
-+                ti[1] = v1;
-+                DES_encrypt3(ti, ks1, ks2, ks3);
-+                v0 = ti[0];
-+                v1 = ti[1];
-+
-+                iv = &(*ivec)[0];
-+                l2c(v0, iv);
-+                l2c(v1, iv);
-+                iv = &(*ivec)[0];
-+            }
-+            c = *(in++) ^ iv[n];
-+            *(out++) = c;
-+            iv[n] = c;
-+            n = (n + 1) & 0x07;
-+        }
-+    } else {
-+        while (l--) {
-+            if (n == 0) {
-+                c2l(iv, v0);
-+                c2l(iv, v1);
-+
-+                ti[0] = v0;
-+                ti[1] = v1;
-+                DES_encrypt3(ti, ks1, ks2, ks3);
-+                v0 = ti[0];
-+                v1 = ti[1];
-+
-+                iv = &(*ivec)[0];
-+                l2c(v0, iv);
-+                l2c(v1, iv);
-+                iv = &(*ivec)[0];
-+            }
-+            cc = *(in++);
-+            c = iv[n];
-+            iv[n] = cc;
-+            *(out++) = c ^ cc;
-+            n = (n + 1) & 0x07;
-+        }
-+    }
-+    v0 = v1 = ti[0] = ti[1] = c = cc = 0;
-+    *num = n;
-+}
-+
-+/*
-+ * This is compatible with the single key CFB-r for DES, even thought that's
-+ * not what EVP needs.
-+ */
-+
-+void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out,
-+                          int numbits, long length, DES_key_schedule *ks1,
-+                          DES_key_schedule *ks2, DES_key_schedule *ks3,
-+                          DES_cblock *ivec, int enc)
-+{
-+    register DES_LONG d0, d1, v0, v1;
-+    register unsigned long l = length, n = ((unsigned int)numbits + 7) / 8;
-+    register int num = numbits, i;
-+    DES_LONG ti[2];
-+    unsigned char *iv;
-+    unsigned char ovec[16];
-+
-+    if (num > 64)
-+        return;
-+    iv = &(*ivec)[0];
-+    c2l(iv, v0);
-+    c2l(iv, v1);
-+    if (enc) {
-+        while (l >= n) {
-+            l -= n;
-+            ti[0] = v0;
-+            ti[1] = v1;
-+            DES_encrypt3(ti, ks1, ks2, ks3);
-+            c2ln(in, d0, d1, n);
-+            in += n;
-+            d0 ^= ti[0];
-+            d1 ^= ti[1];
-+            l2cn(d0, d1, out, n);
-+            out += n;
-+            /*
-+             * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
-+             * gcc :-(
-+             */
-+            if (num == 32) {
-+                v0 = v1;
-+                v1 = d0;
-+            } else if (num == 64) {
-+                v0 = d0;
-+                v1 = d1;
-+            } else {
-+                iv = &ovec[0];
-+                l2c(v0, iv);
-+                l2c(v1, iv);
-+                l2c(d0, iv);
-+                l2c(d1, iv);
-+                /* shift ovec left most of the bits... */
-+                memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
-+                /* now the remaining bits */
-+                if (num % 8 != 0)
-+                    for (i = 0; i < 8; ++i) {
-+                        ovec[i] <<= num % 8;
-+                        ovec[i] |= ovec[i + 1] >> (8 - num % 8);
-+                    }
-+                iv = &ovec[0];
-+                c2l(iv, v0);
-+                c2l(iv, v1);
-+            }
-+        }
-+    } else {
-+        while (l >= n) {
-+            l -= n;
-+            ti[0] = v0;
-+            ti[1] = v1;
-+            DES_encrypt3(ti, ks1, ks2, ks3);
-+            c2ln(in, d0, d1, n);
-+            in += n;
-+            /*
-+             * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
-+             * gcc :-(
-+             */
-+            if (num == 32) {
-+                v0 = v1;
-+                v1 = d0;
-+            } else if (num == 64) {
-+                v0 = d0;
-+                v1 = d1;
-+            } else {
-+                iv = &ovec[0];
-+                l2c(v0, iv);
-+                l2c(v1, iv);
-+                l2c(d0, iv);
-+                l2c(d1, iv);
-+                /* shift ovec left most of the bits... */
-+                memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
-+                /* now the remaining bits */
-+                if (num % 8 != 0)
-+                    for (i = 0; i < 8; ++i) {
-+                        ovec[i] <<= num % 8;
-+                        ovec[i] |= ovec[i + 1] >> (8 - num % 8);
-+                    }
-+                iv = &ovec[0];
-+                c2l(iv, v0);
-+                c2l(iv, v1);
-+            }
-+            d0 ^= ti[0];
-+            d1 ^= ti[1];
-+            l2cn(d0, d1, out, n);
-+            out += n;
-+        }
-+    }
-+    iv = &(*ivec)[0];
-+    l2c(v0, iv);
-+    l2c(v1, iv);
-+    v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb64enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb64enc.c
-new file mode 100644
-index 0000000..96de51b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb64enc.c
-@@ -0,0 +1,73 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "des_locl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit cfb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+
-+void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
-+                       long length, DES_key_schedule *schedule,
-+                       DES_cblock *ivec, int *num, int enc)
-+{
-+    register DES_LONG v0, v1;
-+    register long l = length;
-+    register int n = *num;
-+    DES_LONG ti[2];
-+    unsigned char *iv, c, cc;
-+
-+    iv = &(*ivec)[0];
-+    if (enc) {
-+        while (l--) {
-+            if (n == 0) {
-+                c2l(iv, v0);
-+                ti[0] = v0;
-+                c2l(iv, v1);
-+                ti[1] = v1;
-+                DES_encrypt1(ti, schedule, DES_ENCRYPT);
-+                iv = &(*ivec)[0];
-+                v0 = ti[0];
-+                l2c(v0, iv);
-+                v0 = ti[1];
-+                l2c(v0, iv);
-+                iv = &(*ivec)[0];
-+            }
-+            c = *(in++) ^ iv[n];
-+            *(out++) = c;
-+            iv[n] = c;
-+            n = (n + 1) & 0x07;
-+        }
-+    } else {
-+        while (l--) {
-+            if (n == 0) {
-+                c2l(iv, v0);
-+                ti[0] = v0;
-+                c2l(iv, v1);
-+                ti[1] = v1;
-+                DES_encrypt1(ti, schedule, DES_ENCRYPT);
-+                iv = &(*ivec)[0];
-+                v0 = ti[0];
-+                l2c(v0, iv);
-+                v0 = ti[1];
-+                l2c(v0, iv);
-+                iv = &(*ivec)[0];
-+            }
-+            cc = *(in++);
-+            c = iv[n];
-+            iv[n] = cc;
-+            *(out++) = c ^ cc;
-+            n = (n + 1) & 0x07;
-+        }
-+    }
-+    v0 = v1 = ti[0] = ti[1] = c = cc = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb_enc.c
-new file mode 100644
-index 0000000..6c428ba
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/cfb_enc.c
-@@ -0,0 +1,150 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "e_os.h"
-+#include "des_locl.h"
-+#include 
-+
-+/*
-+ * The input and output are loaded in multiples of 8 bits. What this means is
-+ * that if you hame numbits=12 and length=2 the first 12 bits will be
-+ * retrieved from the first byte and half the second.  The second 12 bits
-+ * will come from the 3rd and half the 4th byte.
-+ */
-+/*
-+ * Until Aug 1 2003 this function did not correctly implement CFB-r, so it
-+ * will not be compatible with any encryption prior to that date. Ben.
-+ */
-+void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
-+                     long length, DES_key_schedule *schedule,
-+                     DES_cblock *ivec, int enc)
-+{
-+    register DES_LONG d0, d1, v0, v1;
-+    register unsigned long l = length;
-+    register int num = numbits / 8, n = (numbits + 7) / 8, i, rem =
-+        numbits % 8;
-+    DES_LONG ti[2];
-+    unsigned char *iv;
-+#ifndef L_ENDIAN
-+    unsigned char ovec[16];
-+#else
-+    unsigned int sh[4];
-+    unsigned char *ovec = (unsigned char *)sh;
-+
-+    /* I kind of count that compiler optimizes away this assertioni, */
-+    assert(sizeof(sh[0]) == 4); /* as this holds true for all, */
-+    /* but 16-bit platforms...      */
-+
-+#endif
-+
-+    if (numbits <= 0 || numbits > 64)
-+        return;
-+    iv = &(*ivec)[0];
-+    c2l(iv, v0);
-+    c2l(iv, v1);
-+    if (enc) {
-+        while (l >= (unsigned long)n) {
-+            l -= n;
-+            ti[0] = v0;
-+            ti[1] = v1;
-+            DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT);
-+            c2ln(in, d0, d1, n);
-+            in += n;
-+            d0 ^= ti[0];
-+            d1 ^= ti[1];
-+            l2cn(d0, d1, out, n);
-+            out += n;
-+            /*
-+             * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
-+             * gcc :-(
-+             */
-+            if (numbits == 32) {
-+                v0 = v1;
-+                v1 = d0;
-+            } else if (numbits == 64) {
-+                v0 = d0;
-+                v1 = d1;
-+            } else {
-+#ifndef L_ENDIAN
-+                iv = &ovec[0];
-+                l2c(v0, iv);
-+                l2c(v1, iv);
-+                l2c(d0, iv);
-+                l2c(d1, iv);
-+#else
-+                sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1;
-+#endif
-+                if (rem == 0)
-+                    memmove(ovec, ovec + num, 8);
-+                else
-+                    for (i = 0; i < 8; ++i)
-+                        ovec[i] = ovec[i + num] << rem |
-+                            ovec[i + num + 1] >> (8 - rem);
-+#ifdef L_ENDIAN
-+                v0 = sh[0], v1 = sh[1];
-+#else
-+                iv = &ovec[0];
-+                c2l(iv, v0);
-+                c2l(iv, v1);
-+#endif
-+            }
-+        }
-+    } else {
-+        while (l >= (unsigned long)n) {
-+            l -= n;
-+            ti[0] = v0;
-+            ti[1] = v1;
-+            DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT);
-+            c2ln(in, d0, d1, n);
-+            in += n;
-+            /*
-+             * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
-+             * gcc :-(
-+             */
-+            if (numbits == 32) {
-+                v0 = v1;
-+                v1 = d0;
-+            } else if (numbits == 64) {
-+                v0 = d0;
-+                v1 = d1;
-+            } else {
-+#ifndef L_ENDIAN
-+                iv = &ovec[0];
-+                l2c(v0, iv);
-+                l2c(v1, iv);
-+                l2c(d0, iv);
-+                l2c(d1, iv);
-+#else
-+                sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1;
-+#endif
-+                if (rem == 0)
-+                    memmove(ovec, ovec + num, 8);
-+                else
-+                    for (i = 0; i < 8; ++i)
-+                        ovec[i] = ovec[i + num] << rem |
-+                            ovec[i + num + 1] >> (8 - rem);
-+#ifdef L_ENDIAN
-+                v0 = sh[0], v1 = sh[1];
-+#else
-+                iv = &ovec[0];
-+                c2l(iv, v0);
-+                c2l(iv, v1);
-+#endif
-+            }
-+            d0 ^= ti[0];
-+            d1 ^= ti[1];
-+            l2cn(d0, d1, out, n);
-+            out += n;
-+        }
-+    }
-+    iv = &(*ivec)[0];
-+    l2c(v0, iv);
-+    l2c(v1, iv);
-+    v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/des_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/des_enc.c
-new file mode 100644
-index 0000000..600f6df
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/des_enc.c
-@@ -0,0 +1,301 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "des_locl.h"
-+#include "spr.h"
-+
-+void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
-+{
-+    register DES_LONG l, r, t, u;
-+    register DES_LONG *s;
-+
-+    r = data[0];
-+    l = data[1];
-+
-+    IP(r, l);
-+    /*
-+     * Things have been modified so that the initial rotate is done outside
-+     * the loop.  This required the DES_SPtrans values in sp.h to be rotated
-+     * 1 bit to the right. One perl script later and things have a 5% speed
-+     * up on a sparc2. Thanks to Richard Outerbridge
-+     * <71755.204@CompuServe.COM> for pointing this out.
-+     */
-+    /* clear the top bits on machines with 8byte longs */
-+    /* shift left by 2 */
-+    r = ROTATE(r, 29) & 0xffffffffL;
-+    l = ROTATE(l, 29) & 0xffffffffL;
-+
-+    s = ks->ks->deslong;
-+    /*
-+     * I don't know if it is worth the effort of loop unrolling the inner
-+     * loop
-+     */
-+    if (enc) {
-+        D_ENCRYPT(l, r, 0);     /* 1 */
-+        D_ENCRYPT(r, l, 2);     /* 2 */
-+        D_ENCRYPT(l, r, 4);     /* 3 */
-+        D_ENCRYPT(r, l, 6);     /* 4 */
-+        D_ENCRYPT(l, r, 8);     /* 5 */
-+        D_ENCRYPT(r, l, 10);    /* 6 */
-+        D_ENCRYPT(l, r, 12);    /* 7 */
-+        D_ENCRYPT(r, l, 14);    /* 8 */
-+        D_ENCRYPT(l, r, 16);    /* 9 */
-+        D_ENCRYPT(r, l, 18);    /* 10 */
-+        D_ENCRYPT(l, r, 20);    /* 11 */
-+        D_ENCRYPT(r, l, 22);    /* 12 */
-+        D_ENCRYPT(l, r, 24);    /* 13 */
-+        D_ENCRYPT(r, l, 26);    /* 14 */
-+        D_ENCRYPT(l, r, 28);    /* 15 */
-+        D_ENCRYPT(r, l, 30);    /* 16 */
-+    } else {
-+        D_ENCRYPT(l, r, 30);    /* 16 */
-+        D_ENCRYPT(r, l, 28);    /* 15 */
-+        D_ENCRYPT(l, r, 26);    /* 14 */
-+        D_ENCRYPT(r, l, 24);    /* 13 */
-+        D_ENCRYPT(l, r, 22);    /* 12 */
-+        D_ENCRYPT(r, l, 20);    /* 11 */
-+        D_ENCRYPT(l, r, 18);    /* 10 */
-+        D_ENCRYPT(r, l, 16);    /* 9 */
-+        D_ENCRYPT(l, r, 14);    /* 8 */
-+        D_ENCRYPT(r, l, 12);    /* 7 */
-+        D_ENCRYPT(l, r, 10);    /* 6 */
-+        D_ENCRYPT(r, l, 8);     /* 5 */
-+        D_ENCRYPT(l, r, 6);     /* 4 */
-+        D_ENCRYPT(r, l, 4);     /* 3 */
-+        D_ENCRYPT(l, r, 2);     /* 2 */
-+        D_ENCRYPT(r, l, 0);     /* 1 */
-+    }
-+
-+    /* rotate and clear the top bits on machines with 8byte longs */
-+    l = ROTATE(l, 3) & 0xffffffffL;
-+    r = ROTATE(r, 3) & 0xffffffffL;
-+
-+    FP(r, l);
-+    data[0] = l;
-+    data[1] = r;
-+    l = r = t = u = 0;
-+}
-+
-+void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
-+{
-+    register DES_LONG l, r, t, u;
-+    register DES_LONG *s;
-+
-+    r = data[0];
-+    l = data[1];
-+
-+    /*
-+     * Things have been modified so that the initial rotate is done outside
-+     * the loop.  This required the DES_SPtrans values in sp.h to be rotated
-+     * 1 bit to the right. One perl script later and things have a 5% speed
-+     * up on a sparc2. Thanks to Richard Outerbridge
-+     * <71755.204@CompuServe.COM> for pointing this out.
-+     */
-+    /* clear the top bits on machines with 8byte longs */
-+    r = ROTATE(r, 29) & 0xffffffffL;
-+    l = ROTATE(l, 29) & 0xffffffffL;
-+
-+    s = ks->ks->deslong;
-+    /*
-+     * I don't know if it is worth the effort of loop unrolling the inner
-+     * loop
-+     */
-+    if (enc) {
-+        D_ENCRYPT(l, r, 0);     /* 1 */
-+        D_ENCRYPT(r, l, 2);     /* 2 */
-+        D_ENCRYPT(l, r, 4);     /* 3 */
-+        D_ENCRYPT(r, l, 6);     /* 4 */
-+        D_ENCRYPT(l, r, 8);     /* 5 */
-+        D_ENCRYPT(r, l, 10);    /* 6 */
-+        D_ENCRYPT(l, r, 12);    /* 7 */
-+        D_ENCRYPT(r, l, 14);    /* 8 */
-+        D_ENCRYPT(l, r, 16);    /* 9 */
-+        D_ENCRYPT(r, l, 18);    /* 10 */
-+        D_ENCRYPT(l, r, 20);    /* 11 */
-+        D_ENCRYPT(r, l, 22);    /* 12 */
-+        D_ENCRYPT(l, r, 24);    /* 13 */
-+        D_ENCRYPT(r, l, 26);    /* 14 */
-+        D_ENCRYPT(l, r, 28);    /* 15 */
-+        D_ENCRYPT(r, l, 30);    /* 16 */
-+    } else {
-+        D_ENCRYPT(l, r, 30);    /* 16 */
-+        D_ENCRYPT(r, l, 28);    /* 15 */
-+        D_ENCRYPT(l, r, 26);    /* 14 */
-+        D_ENCRYPT(r, l, 24);    /* 13 */
-+        D_ENCRYPT(l, r, 22);    /* 12 */
-+        D_ENCRYPT(r, l, 20);    /* 11 */
-+        D_ENCRYPT(l, r, 18);    /* 10 */
-+        D_ENCRYPT(r, l, 16);    /* 9 */
-+        D_ENCRYPT(l, r, 14);    /* 8 */
-+        D_ENCRYPT(r, l, 12);    /* 7 */
-+        D_ENCRYPT(l, r, 10);    /* 6 */
-+        D_ENCRYPT(r, l, 8);     /* 5 */
-+        D_ENCRYPT(l, r, 6);     /* 4 */
-+        D_ENCRYPT(r, l, 4);     /* 3 */
-+        D_ENCRYPT(l, r, 2);     /* 2 */
-+        D_ENCRYPT(r, l, 0);     /* 1 */
-+    }
-+    /* rotate and clear the top bits on machines with 8byte longs */
-+    data[0] = ROTATE(l, 3) & 0xffffffffL;
-+    data[1] = ROTATE(r, 3) & 0xffffffffL;
-+    l = r = t = u = 0;
-+}
-+
-+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
-+                  DES_key_schedule *ks2, DES_key_schedule *ks3)
-+{
-+    register DES_LONG l, r;
-+
-+    l = data[0];
-+    r = data[1];
-+    IP(l, r);
-+    data[0] = l;
-+    data[1] = r;
-+    DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT);
-+    DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT);
-+    DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT);
-+    l = data[0];
-+    r = data[1];
-+    FP(r, l);
-+    data[0] = l;
-+    data[1] = r;
-+}
-+
-+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
-+                  DES_key_schedule *ks2, DES_key_schedule *ks3)
-+{
-+    register DES_LONG l, r;
-+
-+    l = data[0];
-+    r = data[1];
-+    IP(l, r);
-+    data[0] = l;
-+    data[1] = r;
-+    DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT);
-+    DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT);
-+    DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT);
-+    l = data[0];
-+    r = data[1];
-+    FP(r, l);
-+    data[0] = l;
-+    data[1] = r;
-+}
-+
-+#ifndef DES_DEFAULT_OPTIONS
-+
-+# undef CBC_ENC_C__DONT_UPDATE_IV
-+# include "ncbc_enc.c"          /* DES_ncbc_encrypt */
-+
-+void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
-+                          long length, DES_key_schedule *ks1,
-+                          DES_key_schedule *ks2, DES_key_schedule *ks3,
-+                          DES_cblock *ivec, int enc)
-+{
-+    register DES_LONG tin0, tin1;
-+    register DES_LONG tout0, tout1, xor0, xor1;
-+    register const unsigned char *in;
-+    unsigned char *out;
-+    register long l = length;
-+    DES_LONG tin[2];
-+    unsigned char *iv;
-+
-+    in = input;
-+    out = output;
-+    iv = &(*ivec)[0];
-+
-+    if (enc) {
-+        c2l(iv, tout0);
-+        c2l(iv, tout1);
-+        for (l -= 8; l >= 0; l -= 8) {
-+            c2l(in, tin0);
-+            c2l(in, tin1);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+
-+            l2c(tout0, out);
-+            l2c(tout1, out);
-+        }
-+        if (l != -8) {
-+            c2ln(in, tin0, tin1, l + 8);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+
-+            l2c(tout0, out);
-+            l2c(tout1, out);
-+        }
-+        iv = &(*ivec)[0];
-+        l2c(tout0, iv);
-+        l2c(tout1, iv);
-+    } else {
-+        register DES_LONG t0, t1;
-+
-+        c2l(iv, xor0);
-+        c2l(iv, xor1);
-+        for (l -= 8; l >= 0; l -= 8) {
-+            c2l(in, tin0);
-+            c2l(in, tin1);
-+
-+            t0 = tin0;
-+            t1 = tin1;
-+
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+
-+            tout0 ^= xor0;
-+            tout1 ^= xor1;
-+            l2c(tout0, out);
-+            l2c(tout1, out);
-+            xor0 = t0;
-+            xor1 = t1;
-+        }
-+        if (l != -8) {
-+            c2l(in, tin0);
-+            c2l(in, tin1);
-+
-+            t0 = tin0;
-+            t1 = tin1;
-+
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+
-+            tout0 ^= xor0;
-+            tout1 ^= xor1;
-+            l2cn(tout0, tout1, out, l + 8);
-+            xor0 = t0;
-+            xor1 = t1;
-+        }
-+
-+        iv = &(*ivec)[0];
-+        l2c(xor0, iv);
-+        l2c(xor1, iv);
-+    }
-+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
-+    tin[0] = tin[1] = 0;
-+}
-+
-+#endif                          /* DES_DEFAULT_OPTIONS */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/des_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/des_locl.h
-new file mode 100644
-index 0000000..53881d4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/des_locl.h
-@@ -0,0 +1,217 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_DES_LOCL_H
-+# define HEADER_DES_LOCL_H
-+
-+# include 
-+
-+# include 
-+# include 
-+# include 
-+
-+# include 
-+
-+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
-+#  undef OPENSSL_EXTERN
-+#  define OPENSSL_EXTERN OPENSSL_EXPORT
-+# endif
-+
-+# define ITERATIONS 16
-+# define HALF_ITERATIONS 8
-+
-+/* used in des_read and des_write */
-+# define MAXWRITE        (1024*16)
-+# define BSIZE           (MAXWRITE+4)
-+
-+# define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
-+                         l|=((DES_LONG)(*((c)++)))<< 8L, \
-+                         l|=((DES_LONG)(*((c)++)))<<16L, \
-+                         l|=((DES_LONG)(*((c)++)))<<24L)
-+
-+/* NOTE - c is not incremented as per c2l */
-+# define c2ln(c,l1,l2,n) { \
-+                        c+=n; \
-+                        l1=l2=0; \
-+                        switch (n) { \
-+                        case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
-+                        case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
-+                        case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
-+                        case 5: l2|=((DES_LONG)(*(--(c))));     \
-+                        case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
-+                        case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
-+                        case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
-+                        case 1: l1|=((DES_LONG)(*(--(c))));     \
-+                                } \
-+                        }
-+
-+# define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
-+
-+/*
-+ * replacements for htonl and ntohl since I have no idea what to do when
-+ * faced with machines with 8 byte longs.
-+ */
-+# define HDRSIZE 4
-+
-+# define n2l(c,l)        (l =((DES_LONG)(*((c)++)))<<24L, \
-+                         l|=((DES_LONG)(*((c)++)))<<16L, \
-+                         l|=((DES_LONG)(*((c)++)))<< 8L, \
-+                         l|=((DES_LONG)(*((c)++))))
-+
-+# define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)     )&0xff))
-+
-+/* NOTE - c is not incremented as per l2c */
-+# define l2cn(l1,l2,c,n) { \
-+                        c+=n; \
-+                        switch (n) { \
-+                        case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
-+                        case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
-+                        case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
-+                        case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
-+                        case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
-+                        case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
-+                        case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
-+                        case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
-+                                } \
-+                        }
-+
-+# if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER))
-+#  define ROTATE(a,n)     (_lrotr(a,n))
-+# elif defined(__ICC)
-+#  define ROTATE(a,n)     (_rotr(a,n))
-+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
-+#  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
-+#   define ROTATE(a,n)   ({ register unsigned int ret;   \
-+                                asm ("rorl %1,%0"       \
-+                                        : "=r"(ret)     \
-+                                        : "I"(n),"0"(a) \
-+                                        : "cc");        \
-+                           ret;                         \
-+                        })
-+#  endif
-+# endif
-+# ifndef ROTATE
-+#  define ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))
-+# endif
-+
-+/*
-+ * Don't worry about the LOAD_DATA() stuff, that is used by fcrypt() to add
-+ * it's little bit to the front
-+ */
-+
-+# ifdef DES_FCRYPT
-+
-+#  define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
-+        { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
-+
-+#  define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
-+        t=R^(R>>16L); \
-+        u=t&E0; t&=E1; \
-+        tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
-+        tmp=(t<<16); t^=R^s[S+1]; t^=tmp
-+# else
-+#  define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
-+#  define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
-+        u=R^s[S  ]; \
-+        t=R^s[S+1]
-+# endif
-+
-+/*
-+ * It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there is no reason
-+ * to not xor all the sub items together.  This potentially saves a register
-+ * since things can be xored directly into L
-+ */
-+
-+# define D_ENCRYPT(LL,R,S) { \
-+        LOAD_DATA_tmp(R,S,u,t,E0,E1); \
-+        t=ROTATE(t,4); \
-+        LL^= \
-+            DES_SPtrans[0][(u>> 2L)&0x3f]^ \
-+            DES_SPtrans[2][(u>>10L)&0x3f]^ \
-+            DES_SPtrans[4][(u>>18L)&0x3f]^ \
-+            DES_SPtrans[6][(u>>26L)&0x3f]^ \
-+            DES_SPtrans[1][(t>> 2L)&0x3f]^ \
-+            DES_SPtrans[3][(t>>10L)&0x3f]^ \
-+            DES_SPtrans[5][(t>>18L)&0x3f]^ \
-+            DES_SPtrans[7][(t>>26L)&0x3f]; }
-+
-+        /*-
-+         * IP and FP
-+         * The problem is more of a geometric problem that random bit fiddling.
-+         0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
-+         8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
-+        16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
-+        24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
-+
-+        32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
-+        40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
-+        48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
-+        56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
-+
-+        The output has been subject to swaps of the form
-+        0 1 -> 3 1 but the odd and even bits have been put into
-+        2 3    2 0
-+        different words.  The main trick is to remember that
-+        t=((l>>size)^r)&(mask);
-+        r^=t;
-+        l^=(t<>(n))^(b))&(m)),\
-+        (b)^=(t),\
-+        (a)^=((t)<<(n)))
-+
-+# define IP(l,r) \
-+        { \
-+        register DES_LONG tt; \
-+        PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
-+        PERM_OP(l,r,tt,16,0x0000ffffL); \
-+        PERM_OP(r,l,tt, 2,0x33333333L); \
-+        PERM_OP(l,r,tt, 8,0x00ff00ffL); \
-+        PERM_OP(r,l,tt, 1,0x55555555L); \
-+        }
-+
-+# define FP(l,r) \
-+        { \
-+        register DES_LONG tt; \
-+        PERM_OP(l,r,tt, 1,0x55555555L); \
-+        PERM_OP(r,l,tt, 8,0x00ff00ffL); \
-+        PERM_OP(l,r,tt, 2,0x33333333L); \
-+        PERM_OP(r,l,tt,16,0x0000ffffL); \
-+        PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
-+        }
-+
-+extern const DES_LONG DES_SPtrans[8][64];
-+
-+void fcrypt_body(DES_LONG *out, DES_key_schedule *ks,
-+                 DES_LONG Eswap0, DES_LONG Eswap1);
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ecb3_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ecb3_enc.c
-new file mode 100644
-index 0000000..6ac89d4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ecb3_enc.c
-@@ -0,0 +1,33 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "des_locl.h"
-+
-+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
-+                      DES_key_schedule *ks1, DES_key_schedule *ks2,
-+                      DES_key_schedule *ks3, int enc)
-+{
-+    register DES_LONG l0, l1;
-+    DES_LONG ll[2];
-+    const unsigned char *in = &(*input)[0];
-+    unsigned char *out = &(*output)[0];
-+
-+    c2l(in, l0);
-+    c2l(in, l1);
-+    ll[0] = l0;
-+    ll[1] = l1;
-+    if (enc)
-+        DES_encrypt3(ll, ks1, ks2, ks3);
-+    else
-+        DES_decrypt3(ll, ks1, ks2, ks3);
-+    l0 = ll[0];
-+    l1 = ll[1];
-+    l2c(l0, out);
-+    l2c(l1, out);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ecb_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ecb_enc.c
-new file mode 100644
-index 0000000..bd130c6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ecb_enc.c
-@@ -0,0 +1,51 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "des_locl.h"
-+#include 
-+#include 
-+
-+
-+const char *DES_options(void)
-+{
-+    static int init = 1;
-+    static char buf[32];
-+
-+    if (init) {
-+        const char *size;
-+
-+        if (sizeof(DES_LONG) != sizeof(long))
-+            size = "int";
-+        else
-+            size = "long";
-+        BIO_snprintf(buf, sizeof buf, "des(%s)", size);
-+        init = 0;
-+    }
-+    return (buf);
-+}
-+
-+void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
-+                     DES_key_schedule *ks, int enc)
-+{
-+    register DES_LONG l;
-+    DES_LONG ll[2];
-+    const unsigned char *in = &(*input)[0];
-+    unsigned char *out = &(*output)[0];
-+
-+    c2l(in, l);
-+    ll[0] = l;
-+    c2l(in, l);
-+    ll[1] = l;
-+    DES_encrypt1(ll, ks, enc);
-+    l = ll[0];
-+    l2c(l, out);
-+    l = ll[1];
-+    l2c(l, out);
-+    l = ll[0] = ll[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/fcrypt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/fcrypt.c
-new file mode 100644
-index 0000000..5215ad3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/fcrypt.c
-@@ -0,0 +1,149 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* NOCW */
-+#include 
-+#ifdef _OSD_POSIX
-+# ifndef CHARSET_EBCDIC
-+#  define CHARSET_EBCDIC 1
-+# endif
-+#endif
-+#ifdef CHARSET_EBCDIC
-+# include 
-+#endif
-+
-+#include 
-+#include "des_locl.h"
-+
-+/*
-+ * Added more values to handle illegal salt values the way normal crypt()
-+ * implementations do.  The patch was sent by Bjorn Gronvall 
-+ */
-+static unsigned const char con_salt[128] = {
-+    0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
-+    0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1,
-+    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
-+    0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1,
-+    0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
-+    0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01,
-+    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
-+    0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
-+    0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
-+    0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
-+    0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
-+    0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24,
-+    0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,
-+    0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34,
-+    0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
-+    0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44,
-+};
-+
-+static unsigned const char cov_2char[64] = {
-+    0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-+    0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
-+    0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
-+    0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
-+    0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
-+    0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
-+    0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
-+    0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
-+};
-+
-+char *DES_crypt(const char *buf, const char *salt)
-+{
-+    static char buff[14];
-+
-+#ifndef CHARSET_EBCDIC
-+    return (DES_fcrypt(buf, salt, buff));
-+#else
-+    char e_salt[2 + 1];
-+    char e_buf[32 + 1];         /* replace 32 by 8 ? */
-+    char *ret;
-+
-+    if (salt[0] == '\0' || salt[1] == '\0')
-+        return NULL;
-+
-+    /* Copy salt, convert to ASCII. */
-+    e_salt[0] = salt[0];
-+    e_salt[1] = salt[1];
-+    e_salt[2] = '\0';
-+    ebcdic2ascii(e_salt, e_salt, sizeof(e_salt));
-+
-+    /* Convert password to ASCII. */
-+    OPENSSL_strlcpy(e_buf, buf, sizeof(e_buf));
-+    ebcdic2ascii(e_buf, e_buf, sizeof e_buf);
-+
-+    /* Encrypt it (from/to ASCII); if it worked, convert back. */
-+    ret = DES_fcrypt(e_buf, e_salt, buff);
-+    if (ret != NULL)
-+        ascii2ebcdic(ret, ret, strlen(ret));
-+
-+    return ret;
-+#endif
-+}
-+
-+char *DES_fcrypt(const char *buf, const char *salt, char *ret)
-+{
-+    unsigned int i, j, x, y;
-+    DES_LONG Eswap0, Eswap1;
-+    DES_LONG out[2], ll;
-+    DES_cblock key;
-+    DES_key_schedule ks;
-+    unsigned char bb[9];
-+    unsigned char *b = bb;
-+    unsigned char c, u;
-+
-+    x = ret[0] = salt[0];
-+    if (x == 0 || x >= sizeof(con_salt))
-+        return NULL;
-+    Eswap0 = con_salt[x] << 2;
-+    x = ret[1] = salt[1];
-+    if (x == 0 || x >= sizeof(con_salt))
-+        return NULL;
-+    Eswap1 = con_salt[x] << 6;
-+
-+    /*
-+     * EAY r=strlen(buf); r=(r+7)/8;
-+     */
-+    for (i = 0; i < 8; i++) {
-+        c = *(buf++);
-+        if (!c)
-+            break;
-+        key[i] = (c << 1);
-+    }
-+    for (; i < 8; i++)
-+        key[i] = 0;
-+
-+    DES_set_key_unchecked(&key, &ks);
-+    fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1);
-+
-+    ll = out[0];
-+    l2c(ll, b);
-+    ll = out[1];
-+    l2c(ll, b);
-+    y = 0;
-+    u = 0x80;
-+    bb[8] = 0;
-+    for (i = 2; i < 13; i++) {
-+        c = 0;
-+        for (j = 0; j < 6; j++) {
-+            c <<= 1;
-+            if (bb[y] & u)
-+                c |= 1;
-+            u >>= 1;
-+            if (!u) {
-+                y++;
-+                u = 0x80;
-+            }
-+        }
-+        ret[i] = cov_2char[c];
-+    }
-+    ret[13] = '\0';
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/fcrypt_b.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/fcrypt_b.c
-new file mode 100644
-index 0000000..fe2369a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/fcrypt_b.c
-@@ -0,0 +1,72 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#define DES_FCRYPT
-+#include "des_locl.h"
-+#undef DES_FCRYPT
-+
-+#undef PERM_OP
-+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
-+        (b)^=(t),\
-+        (a)^=((t)<<(n)))
-+
-+#undef HPERM_OP
-+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
-+        (a)=(a)^(t)^(t>>(16-(n))))\
-+
-+void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0,
-+                 DES_LONG Eswap1)
-+{
-+    register DES_LONG l, r, t, u;
-+    register DES_LONG *s;
-+    register int j;
-+    register DES_LONG E0, E1;
-+
-+    l = 0;
-+    r = 0;
-+
-+    s = (DES_LONG *)ks;
-+    E0 = Eswap0;
-+    E1 = Eswap1;
-+
-+    for (j = 0; j < 25; j++) {
-+        D_ENCRYPT(l, r, 0);     /* 1 */
-+        D_ENCRYPT(r, l, 2);     /* 2 */
-+        D_ENCRYPT(l, r, 4);     /* 3 */
-+        D_ENCRYPT(r, l, 6);     /* 4 */
-+        D_ENCRYPT(l, r, 8);     /* 5 */
-+        D_ENCRYPT(r, l, 10);    /* 6 */
-+        D_ENCRYPT(l, r, 12);    /* 7 */
-+        D_ENCRYPT(r, l, 14);    /* 8 */
-+        D_ENCRYPT(l, r, 16);    /* 9 */
-+        D_ENCRYPT(r, l, 18);    /* 10 */
-+        D_ENCRYPT(l, r, 20);    /* 11 */
-+        D_ENCRYPT(r, l, 22);    /* 12 */
-+        D_ENCRYPT(l, r, 24);    /* 13 */
-+        D_ENCRYPT(r, l, 26);    /* 14 */
-+        D_ENCRYPT(l, r, 28);    /* 15 */
-+        D_ENCRYPT(r, l, 30);    /* 16 */
-+        t = l;
-+        l = r;
-+        r = t;
-+    }
-+    l = ROTATE(l, 3) & 0xffffffffL;
-+    r = ROTATE(r, 3) & 0xffffffffL;
-+
-+    PERM_OP(l, r, t,  1, 0x55555555L);
-+    PERM_OP(r, l, t,  8, 0x00ff00ffL);
-+    PERM_OP(l, r, t,  2, 0x33333333L);
-+    PERM_OP(r, l, t, 16, 0x0000ffffL);
-+    PERM_OP(l, r, t,  4, 0x0f0f0f0fL);
-+
-+    out[0] = r;
-+    out[1] = l;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ncbc_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ncbc_enc.c
-new file mode 100644
-index 0000000..244f15c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ncbc_enc.c
-@@ -0,0 +1,106 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*-
-+ * #included by:
-+ *    cbc_enc.c  (DES_cbc_encrypt)
-+ *    des_enc.c  (DES_ncbc_encrypt)
-+ */
-+
-+#include "des_locl.h"
-+
-+#ifdef CBC_ENC_C__DONT_UPDATE_IV
-+void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
-+                     DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
-+#else
-+void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out,
-+                      long length, DES_key_schedule *_schedule,
-+                      DES_cblock *ivec, int enc)
-+#endif
-+{
-+    register DES_LONG tin0, tin1;
-+    register DES_LONG tout0, tout1, xor0, xor1;
-+    register long l = length;
-+    DES_LONG tin[2];
-+    unsigned char *iv;
-+
-+    iv = &(*ivec)[0];
-+
-+    if (enc) {
-+        c2l(iv, tout0);
-+        c2l(iv, tout1);
-+        for (l -= 8; l >= 0; l -= 8) {
-+            c2l(in, tin0);
-+            c2l(in, tin1);
-+            tin0 ^= tout0;
-+            tin[0] = tin0;
-+            tin1 ^= tout1;
-+            tin[1] = tin1;
-+            DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT);
-+            tout0 = tin[0];
-+            l2c(tout0, out);
-+            tout1 = tin[1];
-+            l2c(tout1, out);
-+        }
-+        if (l != -8) {
-+            c2ln(in, tin0, tin1, l + 8);
-+            tin0 ^= tout0;
-+            tin[0] = tin0;
-+            tin1 ^= tout1;
-+            tin[1] = tin1;
-+            DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT);
-+            tout0 = tin[0];
-+            l2c(tout0, out);
-+            tout1 = tin[1];
-+            l2c(tout1, out);
-+        }
-+#ifndef CBC_ENC_C__DONT_UPDATE_IV
-+        iv = &(*ivec)[0];
-+        l2c(tout0, iv);
-+        l2c(tout1, iv);
-+#endif
-+    } else {
-+        c2l(iv, xor0);
-+        c2l(iv, xor1);
-+        for (l -= 8; l >= 0; l -= 8) {
-+            c2l(in, tin0);
-+            tin[0] = tin0;
-+            c2l(in, tin1);
-+            tin[1] = tin1;
-+            DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2c(tout0, out);
-+            l2c(tout1, out);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        if (l != -8) {
-+            c2l(in, tin0);
-+            tin[0] = tin0;
-+            c2l(in, tin1);
-+            tin[1] = tin1;
-+            DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2cn(tout0, tout1, out, l + 8);
-+#ifndef CBC_ENC_C__DONT_UPDATE_IV
-+            xor0 = tin0;
-+            xor1 = tin1;
-+#endif
-+        }
-+#ifndef CBC_ENC_C__DONT_UPDATE_IV
-+        iv = &(*ivec)[0];
-+        l2c(xor0, iv);
-+        l2c(xor1, iv);
-+#endif
-+    }
-+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
-+    tin[0] = tin[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb64ede.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb64ede.c
-new file mode 100644
-index 0000000..a551a07
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb64ede.c
-@@ -0,0 +1,62 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "des_locl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit ofb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+void DES_ede3_ofb64_encrypt(register const unsigned char *in,
-+                            register unsigned char *out, long length,
-+                            DES_key_schedule *k1, DES_key_schedule *k2,
-+                            DES_key_schedule *k3, DES_cblock *ivec, int *num)
-+{
-+    register DES_LONG v0, v1;
-+    register int n = *num;
-+    register long l = length;
-+    DES_cblock d;
-+    register char *dp;
-+    DES_LONG ti[2];
-+    unsigned char *iv;
-+    int save = 0;
-+
-+    iv = &(*ivec)[0];
-+    c2l(iv, v0);
-+    c2l(iv, v1);
-+    ti[0] = v0;
-+    ti[1] = v1;
-+    dp = (char *)d;
-+    l2c(v0, dp);
-+    l2c(v1, dp);
-+    while (l--) {
-+        if (n == 0) {
-+            /* ti[0]=v0; */
-+            /* ti[1]=v1; */
-+            DES_encrypt3(ti, k1, k2, k3);
-+            v0 = ti[0];
-+            v1 = ti[1];
-+
-+            dp = (char *)d;
-+            l2c(v0, dp);
-+            l2c(v1, dp);
-+            save++;
-+        }
-+        *(out++) = *(in++) ^ d[n];
-+        n = (n + 1) & 0x07;
-+    }
-+    if (save) {
-+        iv = &(*ivec)[0];
-+        l2c(v0, iv);
-+        l2c(v1, iv);
-+    }
-+    v0 = v1 = ti[0] = ti[1] = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb64enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb64enc.c
-new file mode 100644
-index 0000000..30976c8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb64enc.c
-@@ -0,0 +1,60 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "des_locl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit ofb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+void DES_ofb64_encrypt(register const unsigned char *in,
-+                       register unsigned char *out, long length,
-+                       DES_key_schedule *schedule, DES_cblock *ivec, int *num)
-+{
-+    register DES_LONG v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    DES_cblock d;
-+    register unsigned char *dp;
-+    DES_LONG ti[2];
-+    unsigned char *iv;
-+    int save = 0;
-+
-+    iv = &(*ivec)[0];
-+    c2l(iv, v0);
-+    c2l(iv, v1);
-+    ti[0] = v0;
-+    ti[1] = v1;
-+    dp = d;
-+    l2c(v0, dp);
-+    l2c(v1, dp);
-+    while (l--) {
-+        if (n == 0) {
-+            DES_encrypt1(ti, schedule, DES_ENCRYPT);
-+            dp = d;
-+            t = ti[0];
-+            l2c(t, dp);
-+            t = ti[1];
-+            l2c(t, dp);
-+            save++;
-+        }
-+        *(out++) = *(in++) ^ d[n];
-+        n = (n + 1) & 0x07;
-+    }
-+    if (save) {
-+        v0 = ti[0];
-+        v1 = ti[1];
-+        iv = &(*ivec)[0];
-+        l2c(v0, iv);
-+        l2c(v1, iv);
-+    }
-+    t = v0 = v1 = ti[0] = ti[1] = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb_enc.c
-new file mode 100644
-index 0000000..65a9b86
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/ofb_enc.c
-@@ -0,0 +1,82 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "des_locl.h"
-+
-+/*
-+ * The input and output are loaded in multiples of 8 bits. What this means is
-+ * that if you have numbits=12 and length=2 the first 12 bits will be
-+ * retrieved from the first byte and half the second.  The second 12 bits
-+ * will come from the 3rd and half the 4th byte.
-+ */
-+void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
-+                     long length, DES_key_schedule *schedule,
-+                     DES_cblock *ivec)
-+{
-+    register DES_LONG d0, d1, vv0, vv1, v0, v1, n = (numbits + 7) / 8;
-+    register DES_LONG mask0, mask1;
-+    register long l = length;
-+    register int num = numbits;
-+    DES_LONG ti[2];
-+    unsigned char *iv;
-+
-+    if (num > 64)
-+        return;
-+    if (num > 32) {
-+        mask0 = 0xffffffffL;
-+        if (num >= 64)
-+            mask1 = mask0;
-+        else
-+            mask1 = (1L << (num - 32)) - 1;
-+    } else {
-+        if (num == 32)
-+            mask0 = 0xffffffffL;
-+        else
-+            mask0 = (1L << num) - 1;
-+        mask1 = 0x00000000L;
-+    }
-+
-+    iv = &(*ivec)[0];
-+    c2l(iv, v0);
-+    c2l(iv, v1);
-+    ti[0] = v0;
-+    ti[1] = v1;
-+    while (l-- > 0) {
-+        ti[0] = v0;
-+        ti[1] = v1;
-+        DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT);
-+        vv0 = ti[0];
-+        vv1 = ti[1];
-+        c2ln(in, d0, d1, n);
-+        in += n;
-+        d0 = (d0 ^ vv0) & mask0;
-+        d1 = (d1 ^ vv1) & mask1;
-+        l2cn(d0, d1, out, n);
-+        out += n;
-+
-+        if (num == 32) {
-+            v0 = v1;
-+            v1 = vv0;
-+        } else if (num == 64) {
-+            v0 = vv0;
-+            v1 = vv1;
-+        } else if (num > 32) {  /* && num != 64 */
-+            v0 = ((v1 >> (num - 32)) | (vv0 << (64 - num))) & 0xffffffffL;
-+            v1 = ((vv0 >> (num - 32)) | (vv1 << (64 - num))) & 0xffffffffL;
-+        } else {                /* num < 32 */
-+
-+            v0 = ((v0 >> num) | (v1 << (32 - num))) & 0xffffffffL;
-+            v1 = ((v1 >> num) | (vv0 << (32 - num))) & 0xffffffffL;
-+        }
-+    }
-+    iv = &(*ivec)[0];
-+    l2c(v0, iv);
-+    l2c(v1, iv);
-+    v0 = v1 = d0 = d1 = ti[0] = ti[1] = vv0 = vv1 = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/pcbc_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/pcbc_enc.c
-new file mode 100644
-index 0000000..0fa058f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/pcbc_enc.c
-@@ -0,0 +1,66 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "des_locl.h"
-+
-+void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,
-+                      long length, DES_key_schedule *schedule,
-+                      DES_cblock *ivec, int enc)
-+{
-+    register DES_LONG sin0, sin1, xor0, xor1, tout0, tout1;
-+    DES_LONG tin[2];
-+    const unsigned char *in;
-+    unsigned char *out, *iv;
-+
-+    in = input;
-+    out = output;
-+    iv = &(*ivec)[0];
-+
-+    if (enc) {
-+        c2l(iv, xor0);
-+        c2l(iv, xor1);
-+        for (; length > 0; length -= 8) {
-+            if (length >= 8) {
-+                c2l(in, sin0);
-+                c2l(in, sin1);
-+            } else
-+                c2ln(in, sin0, sin1, length);
-+            tin[0] = sin0 ^ xor0;
-+            tin[1] = sin1 ^ xor1;
-+            DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT);
-+            tout0 = tin[0];
-+            tout1 = tin[1];
-+            xor0 = sin0 ^ tout0;
-+            xor1 = sin1 ^ tout1;
-+            l2c(tout0, out);
-+            l2c(tout1, out);
-+        }
-+    } else {
-+        c2l(iv, xor0);
-+        c2l(iv, xor1);
-+        for (; length > 0; length -= 8) {
-+            c2l(in, sin0);
-+            c2l(in, sin1);
-+            tin[0] = sin0;
-+            tin[1] = sin1;
-+            DES_encrypt1((DES_LONG *)tin, schedule, DES_DECRYPT);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            if (length >= 8) {
-+                l2c(tout0, out);
-+                l2c(tout1, out);
-+            } else
-+                l2cn(tout0, tout1, out, length);
-+            xor0 = tout0 ^ sin0;
-+            xor1 = tout1 ^ sin1;
-+        }
-+    }
-+    tin[0] = tin[1] = 0;
-+    sin0 = sin1 = xor0 = xor1 = tout0 = tout1 = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/qud_cksm.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/qud_cksm.c
-new file mode 100644
-index 0000000..8710cec
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/qud_cksm.c
-@@ -0,0 +1,77 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * From "Message Authentication" R.R. Jueneman, S.M. Matyas, C.H. Meyer IEEE
-+ * Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40 This module in
-+ * only based on the code in this paper and is almost definitely not the same
-+ * as the MIT implementation.
-+ */
-+#include "des_locl.h"
-+
-+/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */
-+#define Q_B0(a) (((DES_LONG)(a)))
-+#define Q_B1(a) (((DES_LONG)(a))<<8)
-+#define Q_B2(a) (((DES_LONG)(a))<<16)
-+#define Q_B3(a) (((DES_LONG)(a))<<24)
-+
-+/* used to scramble things a bit */
-+/* Got the value MIT uses via brute force :-) 2/10/90 eay */
-+#define NOISE   ((DES_LONG)83653421L)
-+
-+DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
-+                        long length, int out_count, DES_cblock *seed)
-+{
-+    DES_LONG z0, z1, t0, t1;
-+    int i;
-+    long l;
-+    const unsigned char *cp;
-+    DES_LONG *lp;
-+
-+    if (out_count < 1)
-+        out_count = 1;
-+    lp = (DES_LONG *)&(output[0])[0];
-+
-+    z0 = Q_B0((*seed)[0]) | Q_B1((*seed)[1]) | Q_B2((*seed)[2]) |
-+        Q_B3((*seed)[3]);
-+    z1 = Q_B0((*seed)[4]) | Q_B1((*seed)[5]) | Q_B2((*seed)[6]) |
-+        Q_B3((*seed)[7]);
-+
-+    for (i = 0; ((i < 4) && (i < out_count)); i++) {
-+        cp = input;
-+        l = length;
-+        while (l > 0) {
-+            if (l > 1) {
-+                t0 = (DES_LONG)(*(cp++));
-+                t0 |= (DES_LONG)Q_B1(*(cp++));
-+                l--;
-+            } else
-+                t0 = (DES_LONG)(*(cp++));
-+            l--;
-+            /* add */
-+            t0 += z0;
-+            t0 &= 0xffffffffL;
-+            t1 = z1;
-+            /* square, well sort of square */
-+            z0 = ((((t0 * t0) & 0xffffffffL) + ((t1 * t1) & 0xffffffffL))
-+                  & 0xffffffffL) % 0x7fffffffL;
-+            z1 = ((t0 * ((t1 + NOISE) & 0xffffffffL)) & 0xffffffffL) %
-+                0x7fffffffL;
-+        }
-+        if (lp != NULL) {
-+            /*
-+             * The MIT library assumes that the checksum is composed of
-+             * 2*out_count 32 bit ints
-+             */
-+            *lp++ = z0;
-+            *lp++ = z1;
-+        }
-+    }
-+    return (z0);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/rand_key.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/rand_key.c
-new file mode 100644
-index 0000000..61e4f9d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/rand_key.c
-@@ -0,0 +1,21 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+int DES_random_key(DES_cblock *ret)
-+{
-+    do {
-+        if (RAND_bytes((unsigned char *)ret, sizeof(DES_cblock)) != 1)
-+            return (0);
-+    } while (DES_is_weak_key(ret));
-+    DES_set_odd_parity(ret);
-+    return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/rpc_des.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/rpc_des.h
-new file mode 100644
-index 0000000..fe59e22
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/rpc_des.h
-@@ -0,0 +1,76 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*  @(#)des.h   2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI  */
-+/*-
-+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
-+ * unrestricted use provided that this legend is included on all tape
-+ * media and as a part of the software program in whole or part.  Users
-+ * may copy or modify Sun RPC without charge, but are not authorized
-+ * to license or distribute it to anyone else except as part of a product or
-+ * program developed by the user.
-+ *
-+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
-+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
-+ *
-+ * Sun RPC is provided with no support and without any obligation on the
-+ * part of Sun Microsystems, Inc. to assist in its use, correction,
-+ * modification or enhancement.
-+ *
-+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
-+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
-+ * OR ANY PART THEREOF.
-+ *
-+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
-+ * or profits or other special, indirect and consequential damages, even if
-+ * Sun has been advised of the possibility of such damages.
-+ *
-+ * Sun Microsystems, Inc.
-+ * 2550 Garcia Avenue
-+ * Mountain View, California  94043
-+ */
-+/*
-+ * Generic DES driver interface
-+ * Keep this file hardware independent!
-+ * Copyright (c) 1986 by Sun Microsystems, Inc.
-+ */
-+
-+#define DES_MAXLEN      65536   /* maximum # of bytes to encrypt */
-+#define DES_QUICKLEN    16      /* maximum # of bytes to encrypt quickly */
-+
-+enum desdir { ENCRYPT, DECRYPT };
-+enum desmode { CBC, ECB };
-+
-+/*
-+ * parameters to ioctl call
-+ */
-+struct desparams {
-+    unsigned char des_key[8];   /* key (with low bit parity) */
-+    enum desdir des_dir;        /* direction */
-+    enum desmode des_mode;      /* mode */
-+    unsigned char des_ivec[8];  /* input vector */
-+    unsigned des_len;           /* number of bytes to crypt */
-+    union {
-+        unsigned char UDES_data[DES_QUICKLEN];
-+        unsigned char *UDES_buf;
-+    } UDES;
-+#define des_data UDES.UDES_data /* direct data here if quick */
-+#define des_buf  UDES.UDES_buf  /* otherwise, pointer to data */
-+};
-+
-+/*
-+ * Encrypt an arbitrary sized buffer
-+ */
-+#define DESIOCBLOCK     _IOWR('d', 6, struct desparams)
-+
-+/*
-+ * Encrypt of small amount of data, quickly
-+ */
-+#define DESIOCQUICK     _IOWR('d', 7, struct desparams)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/rpc_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/rpc_enc.c
-new file mode 100644
-index 0000000..bfa8511
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/rpc_enc.c
-@@ -0,0 +1,30 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "rpc_des.h"
-+#include "des_locl.h"
-+
-+int _des_crypt(char *buf, int len, struct desparams *desp);
-+int _des_crypt(char *buf, int len, struct desparams *desp)
-+{
-+    DES_key_schedule ks;
-+    int enc;
-+
-+    DES_set_key_unchecked(&desp->des_key, &ks);
-+    enc = (desp->des_dir == ENCRYPT) ? DES_ENCRYPT : DES_DECRYPT;
-+
-+    if (desp->des_mode == CBC)
-+        DES_ecb_encrypt((const_DES_cblock *)desp->UDES.UDES_buf,
-+                        (DES_cblock *)desp->UDES.UDES_buf, &ks, enc);
-+    else {
-+        DES_ncbc_encrypt(desp->UDES.UDES_buf, desp->UDES.UDES_buf,
-+                         len, &ks, &desp->des_ivec, enc);
-+    }
-+    return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/set_key.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/set_key.c
-new file mode 100644
-index 0000000..795d954
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/set_key.c
-@@ -0,0 +1,389 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*-
-+ * set_key.c v 1.4 eay 24/9/91
-+ * 1.4 Speed up by 400% :-)
-+ * 1.3 added register declarations.
-+ * 1.2 unrolled make_key_sched a bit more
-+ * 1.1 added norm_expand_bits
-+ * 1.0 First working version
-+ */
-+#include 
-+#include "des_locl.h"
-+
-+OPENSSL_IMPLEMENT_GLOBAL(int, DES_check_key, 0)
-+                                                    /*
-+                                                     * defaults to false
-+                                                     */
-+static const unsigned char odd_parity[256] = {
-+    1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
-+    16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
-+    32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
-+    49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
-+    64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
-+    81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
-+    97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110,
-+    110,
-+    112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127,
-+    127,
-+    128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143,
-+    143,
-+    145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158,
-+    158,
-+    161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174,
-+    174,
-+    176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191,
-+    191,
-+    193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206,
-+    206,
-+    208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223,
-+    223,
-+    224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239,
-+    239,
-+    241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254,
-+    254
-+};
-+
-+void DES_set_odd_parity(DES_cblock *key)
-+{
-+    unsigned int i;
-+
-+    for (i = 0; i < DES_KEY_SZ; i++)
-+        (*key)[i] = odd_parity[(*key)[i]];
-+}
-+
-+int DES_check_key_parity(const_DES_cblock *key)
-+{
-+    unsigned int i;
-+
-+    for (i = 0; i < DES_KEY_SZ; i++) {
-+        if ((*key)[i] != odd_parity[(*key)[i]])
-+            return (0);
-+    }
-+    return (1);
-+}
-+
-+/*-
-+ * Weak and semi weak keys as taken from
-+ * %A D.W. Davies
-+ * %A W.L. Price
-+ * %T Security for Computer Networks
-+ * %I John Wiley & Sons
-+ * %D 1984
-+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
-+ * (and actual cblock values).
-+ */
-+#define NUM_WEAK_KEY    16
-+static const DES_cblock weak_keys[NUM_WEAK_KEY] = {
-+    /* weak keys */
-+    {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
-+    {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE},
-+    {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E},
-+    {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1},
-+    /* semi-weak keys */
-+    {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE},
-+    {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01},
-+    {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1},
-+    {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E},
-+    {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1},
-+    {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01},
-+    {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE},
-+    {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E},
-+    {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E},
-+    {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01},
-+    {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE},
-+    {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1}
-+};
-+
-+int DES_is_weak_key(const_DES_cblock *key)
-+{
-+    int i;
-+
-+    for (i = 0; i < NUM_WEAK_KEY; i++)
-+        /*
-+         * Added == 0 to comparison, I obviously don't run this section very
-+         * often :-(, thanks to engineering@MorningStar.Com for the fix eay
-+         * 93/06/29 Another problem, I was comparing only the first 4 bytes,
-+         * 97/03/18
-+         */
-+        if (memcmp(weak_keys[i], key, sizeof(DES_cblock)) == 0)
-+            return (1);
-+    return (0);
-+}
-+
-+/*-
-+ * NOW DEFINED IN des_local.h
-+ * See ecb_encrypt.c for a pseudo description of these macros.
-+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
-+ *      (b)^=(t),\
-+ *      (a)=((a)^((t)<<(n))))
-+ */
-+
-+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
-+        (a)=(a)^(t)^(t>>(16-(n))))
-+
-+static const DES_LONG des_skb[8][64] = {
-+    {
-+     /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-+     0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L,
-+     0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L,
-+     0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L,
-+     0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L,
-+     0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L,
-+     0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L,
-+     0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L,
-+     0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L,
-+     0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L,
-+     0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L,
-+     0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L,
-+     0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L,
-+     0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L,
-+     0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L,
-+     0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L,
-+     0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L,
-+     },
-+    {
-+     /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
-+     0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L,
-+     0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L,
-+     0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L,
-+     0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L,
-+     0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L,
-+     0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L,
-+     0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L,
-+     0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L,
-+     0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L,
-+     0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L,
-+     0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L,
-+     0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L,
-+     0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L,
-+     0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L,
-+     0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L,
-+     0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L,
-+     },
-+    {
-+     /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
-+     0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L,
-+     0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L,
-+     0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L,
-+     0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L,
-+     0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L,
-+     0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L,
-+     0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L,
-+     0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L,
-+     0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L,
-+     0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L,
-+     0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L,
-+     0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L,
-+     0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L,
-+     0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L,
-+     0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L,
-+     0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L,
-+     },
-+    {
-+     /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
-+     0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L,
-+     0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L,
-+     0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L,
-+     0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L,
-+     0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L,
-+     0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L,
-+     0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L,
-+     0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L,
-+     0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L,
-+     0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L,
-+     0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L,
-+     0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L,
-+     0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L,
-+     0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L,
-+     0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L,
-+     0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L,
-+     },
-+    {
-+     /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-+     0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L,
-+     0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L,
-+     0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L,
-+     0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L,
-+     0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L,
-+     0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L,
-+     0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L,
-+     0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L,
-+     0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L,
-+     0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L,
-+     0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L,
-+     0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L,
-+     0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L,
-+     0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L,
-+     0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L,
-+     0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L,
-+     },
-+    {
-+     /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
-+     0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L,
-+     0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L,
-+     0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L,
-+     0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L,
-+     0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L,
-+     0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L,
-+     0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L,
-+     0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L,
-+     0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L,
-+     0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L,
-+     0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L,
-+     0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L,
-+     0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L,
-+     0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L,
-+     0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L,
-+     0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L,
-+     },
-+    {
-+     /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
-+     0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L,
-+     0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L,
-+     0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L,
-+     0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L,
-+     0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L,
-+     0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L,
-+     0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L,
-+     0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L,
-+     0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L,
-+     0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L,
-+     0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L,
-+     0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L,
-+     0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L,
-+     0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L,
-+     0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L,
-+     0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L,
-+     },
-+    {
-+     /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
-+     0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L,
-+     0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L,
-+     0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L,
-+     0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L,
-+     0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L,
-+     0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L,
-+     0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L,
-+     0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L,
-+     0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L,
-+     0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L,
-+     0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L,
-+     0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L,
-+     0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L,
-+     0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L,
-+     0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L,
-+     0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L,
-+     }
-+};
-+
-+int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
-+{
-+    if (DES_check_key) {
-+        return DES_set_key_checked(key, schedule);
-+    } else {
-+        DES_set_key_unchecked(key, schedule);
-+        return 0;
-+    }
-+}
-+
-+/*-
-+ * return 0 if key parity is odd (correct),
-+ * return -1 if key parity error,
-+ * return -2 if illegal weak key.
-+ */
-+int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
-+{
-+    if (!DES_check_key_parity(key))
-+        return (-1);
-+    if (DES_is_weak_key(key))
-+        return (-2);
-+    DES_set_key_unchecked(key, schedule);
-+    return 0;
-+}
-+
-+void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
-+{
-+    static const int shifts2[16] =
-+        { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 };
-+    register DES_LONG c, d, t, s, t2;
-+    register const unsigned char *in;
-+    register DES_LONG *k;
-+    register int i;
-+
-+#ifdef OPENBSD_DEV_CRYPTO
-+    memcpy(schedule->key, key, sizeof schedule->key);
-+    schedule->session = NULL;
-+#endif
-+    k = &schedule->ks->deslong[0];
-+    in = &(*key)[0];
-+
-+    c2l(in, c);
-+    c2l(in, d);
-+
-+    /*
-+     * do PC1 in 47 simple operations :-) Thanks to John Fletcher
-+     * (john_fletcher@lccmail.ocf.llnl.gov) for the inspiration. :-)
-+     */
-+    PERM_OP(d, c, t, 4, 0x0f0f0f0fL);
-+    HPERM_OP(c, t, -2, 0xcccc0000L);
-+    HPERM_OP(d, t, -2, 0xcccc0000L);
-+    PERM_OP(d, c, t, 1, 0x55555555L);
-+    PERM_OP(c, d, t, 8, 0x00ff00ffL);
-+    PERM_OP(d, c, t, 1, 0x55555555L);
-+    d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) |
-+         ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L));
-+    c &= 0x0fffffffL;
-+
-+    for (i = 0; i < ITERATIONS; i++) {
-+        if (shifts2[i]) {
-+            c = ((c >> 2L) | (c << 26L));
-+            d = ((d >> 2L) | (d << 26L));
-+        } else {
-+            c = ((c >> 1L) | (c << 27L));
-+            d = ((d >> 1L) | (d << 27L));
-+        }
-+        c &= 0x0fffffffL;
-+        d &= 0x0fffffffL;
-+        /*
-+         * could be a few less shifts but I am to lazy at this point in time
-+         * to investigate
-+         */
-+        s = des_skb[0][(c) & 0x3f] |
-+            des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] |
-+            des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] |
-+            des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) |
-+                       ((c >> 22L) & 0x38)];
-+        t = des_skb[4][(d) & 0x3f] |
-+            des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] |
-+            des_skb[6][(d >> 15L) & 0x3f] |
-+            des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)];
-+
-+        /* table contained 0213 4657 */
-+        t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
-+        *(k++) = ROTATE(t2, 30) & 0xffffffffL;
-+
-+        t2 = ((s >> 16L) | (t & 0xffff0000L));
-+        *(k++) = ROTATE(t2, 26) & 0xffffffffL;
-+    }
-+}
-+
-+int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
-+{
-+    return (DES_set_key(key, schedule));
-+}
-+
-+/*-
-+#undef des_fixup_key_parity
-+void des_fixup_key_parity(des_cblock *key)
-+        {
-+        des_set_odd_parity(key);
-+        }
-+*/
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/spr.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/spr.h
-new file mode 100644
-index 0000000..42adfbf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/spr.h
-@@ -0,0 +1,163 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+OPENSSL_GLOBAL const DES_LONG DES_SPtrans[8][64] = {
-+    {
-+        /* nibble 0 */
-+        0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
-+        0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
-+        0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
-+        0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
-+        0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
-+        0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
-+        0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
-+        0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
-+        0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
-+        0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
-+        0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
-+        0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
-+        0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
-+        0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
-+        0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
-+        0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
-+    },
-+    {
-+        /* nibble 1 */
-+        0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
-+        0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
-+        0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
-+        0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
-+        0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
-+        0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
-+        0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
-+        0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
-+        0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
-+        0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
-+        0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
-+        0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
-+        0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
-+        0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
-+        0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
-+        0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
-+    },
-+    {
-+        /* nibble 2 */
-+        0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
-+        0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
-+        0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
-+        0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
-+        0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
-+        0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
-+        0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
-+        0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
-+        0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
-+        0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
-+        0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
-+        0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
-+        0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
-+        0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
-+        0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
-+        0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
-+    },
-+    {
-+        /* nibble 3 */
-+        0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
-+        0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
-+        0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
-+        0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
-+        0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
-+        0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
-+        0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
-+        0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
-+        0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
-+        0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
-+        0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
-+        0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
-+        0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
-+        0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
-+        0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
-+        0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
-+    },
-+    {
-+        /* nibble 4 */
-+        0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
-+        0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
-+        0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
-+        0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
-+        0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
-+        0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
-+        0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
-+        0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
-+        0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
-+        0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
-+        0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
-+        0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
-+        0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
-+        0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
-+        0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
-+        0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
-+    },
-+    {
-+        /* nibble 5 */
-+        0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
-+        0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
-+        0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
-+        0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
-+        0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
-+        0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
-+        0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
-+        0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
-+        0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
-+        0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
-+        0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
-+        0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
-+        0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
-+        0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
-+        0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
-+        0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
-+    },
-+    {
-+        /* nibble 6 */
-+        0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
-+        0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
-+        0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
-+        0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
-+        0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
-+        0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
-+        0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
-+        0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
-+        0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
-+        0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
-+        0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
-+        0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
-+        0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
-+        0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
-+        0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
-+        0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
-+    },
-+    {
-+        /* nibble 7 */
-+        0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
-+        0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
-+        0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
-+        0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
-+        0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
-+        0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
-+        0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
-+        0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
-+        0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
-+        0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
-+        0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
-+        0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
-+        0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
-+        0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
-+        0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
-+        0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
-+    }
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/str2key.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/str2key.c
-new file mode 100644
-index 0000000..78998a1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/str2key.c
-@@ -0,0 +1,97 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "des_locl.h"
-+
-+void DES_string_to_key(const char *str, DES_cblock *key)
-+{
-+    DES_key_schedule ks;
-+    int i, length;
-+
-+    memset(key, 0, 8);
-+    length = strlen(str);
-+#ifdef OLD_STR_TO_KEY
-+    for (i = 0; i < length; i++)
-+        (*key)[i % 8] ^= (str[i] << 1);
-+#else                           /* MIT COMPATIBLE */
-+    for (i = 0; i < length; i++) {
-+        register unsigned char j = str[i];
-+
-+        if ((i % 16) < 8)
-+            (*key)[i % 8] ^= (j << 1);
-+        else {
-+            /* Reverse the bit order 05/05/92 eay */
-+            j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f);
-+            j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33);
-+            j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55);
-+            (*key)[7 - (i % 8)] ^= j;
-+        }
-+    }
-+#endif
-+    DES_set_odd_parity(key);
-+    DES_set_key_unchecked(key, &ks);
-+    DES_cbc_cksum((const unsigned char *)str, key, length, &ks, key);
-+    OPENSSL_cleanse(&ks, sizeof(ks));
-+    DES_set_odd_parity(key);
-+}
-+
-+void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2)
-+{
-+    DES_key_schedule ks;
-+    int i, length;
-+
-+    memset(key1, 0, 8);
-+    memset(key2, 0, 8);
-+    length = strlen(str);
-+#ifdef OLD_STR_TO_KEY
-+    if (length <= 8) {
-+        for (i = 0; i < length; i++) {
-+            (*key2)[i] = (*key1)[i] = (str[i] << 1);
-+        }
-+    } else {
-+        for (i = 0; i < length; i++) {
-+            if ((i / 8) & 1)
-+                (*key2)[i % 8] ^= (str[i] << 1);
-+            else
-+                (*key1)[i % 8] ^= (str[i] << 1);
-+        }
-+    }
-+#else                           /* MIT COMPATIBLE */
-+    for (i = 0; i < length; i++) {
-+        register unsigned char j = str[i];
-+
-+        if ((i % 32) < 16) {
-+            if ((i % 16) < 8)
-+                (*key1)[i % 8] ^= (j << 1);
-+            else
-+                (*key2)[i % 8] ^= (j << 1);
-+        } else {
-+            j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f);
-+            j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33);
-+            j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55);
-+            if ((i % 16) < 8)
-+                (*key1)[7 - (i % 8)] ^= j;
-+            else
-+                (*key2)[7 - (i % 8)] ^= j;
-+        }
-+    }
-+    if (length <= 8)
-+        memcpy(key2, key1, 8);
-+#endif
-+    DES_set_odd_parity(key1);
-+    DES_set_odd_parity(key2);
-+    DES_set_key_unchecked(key1, &ks);
-+    DES_cbc_cksum((const unsigned char *)str, key1, length, &ks, key1);
-+    DES_set_key_unchecked(key2, &ks);
-+    DES_cbc_cksum((const unsigned char *)str, key2, length, &ks, key2);
-+    OPENSSL_cleanse(&ks, sizeof(ks));
-+    DES_set_odd_parity(key1);
-+    DES_set_odd_parity(key2);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/des/xcbc_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/xcbc_enc.c
-new file mode 100644
-index 0000000..c4e455d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/des/xcbc_enc.c
-@@ -0,0 +1,103 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "des_locl.h"
-+
-+/* RSA's DESX */
-+
-+void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out,
-+                      long length, DES_key_schedule *schedule,
-+                      DES_cblock *ivec, const_DES_cblock *inw,
-+                      const_DES_cblock *outw, int enc)
-+{
-+    register DES_LONG tin0, tin1;
-+    register DES_LONG tout0, tout1, xor0, xor1;
-+    register DES_LONG inW0, inW1, outW0, outW1;
-+    register const unsigned char *in2;
-+    register long l = length;
-+    DES_LONG tin[2];
-+    unsigned char *iv;
-+
-+    in2 = &(*inw)[0];
-+    c2l(in2, inW0);
-+    c2l(in2, inW1);
-+    in2 = &(*outw)[0];
-+    c2l(in2, outW0);
-+    c2l(in2, outW1);
-+
-+    iv = &(*ivec)[0];
-+
-+    if (enc) {
-+        c2l(iv, tout0);
-+        c2l(iv, tout1);
-+        for (l -= 8; l >= 0; l -= 8) {
-+            c2l(in, tin0);
-+            c2l(in, tin1);
-+            tin0 ^= tout0 ^ inW0;
-+            tin[0] = tin0;
-+            tin1 ^= tout1 ^ inW1;
-+            tin[1] = tin1;
-+            DES_encrypt1(tin, schedule, DES_ENCRYPT);
-+            tout0 = tin[0] ^ outW0;
-+            l2c(tout0, out);
-+            tout1 = tin[1] ^ outW1;
-+            l2c(tout1, out);
-+        }
-+        if (l != -8) {
-+            c2ln(in, tin0, tin1, l + 8);
-+            tin0 ^= tout0 ^ inW0;
-+            tin[0] = tin0;
-+            tin1 ^= tout1 ^ inW1;
-+            tin[1] = tin1;
-+            DES_encrypt1(tin, schedule, DES_ENCRYPT);
-+            tout0 = tin[0] ^ outW0;
-+            l2c(tout0, out);
-+            tout1 = tin[1] ^ outW1;
-+            l2c(tout1, out);
-+        }
-+        iv = &(*ivec)[0];
-+        l2c(tout0, iv);
-+        l2c(tout1, iv);
-+    } else {
-+        c2l(iv, xor0);
-+        c2l(iv, xor1);
-+        for (l -= 8; l > 0; l -= 8) {
-+            c2l(in, tin0);
-+            tin[0] = tin0 ^ outW0;
-+            c2l(in, tin1);
-+            tin[1] = tin1 ^ outW1;
-+            DES_encrypt1(tin, schedule, DES_DECRYPT);
-+            tout0 = tin[0] ^ xor0 ^ inW0;
-+            tout1 = tin[1] ^ xor1 ^ inW1;
-+            l2c(tout0, out);
-+            l2c(tout1, out);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        if (l != -8) {
-+            c2l(in, tin0);
-+            tin[0] = tin0 ^ outW0;
-+            c2l(in, tin1);
-+            tin[1] = tin1 ^ outW1;
-+            DES_encrypt1(tin, schedule, DES_DECRYPT);
-+            tout0 = tin[0] ^ xor0 ^ inW0;
-+            tout1 = tin[1] ^ xor1 ^ inW1;
-+            l2cn(tout0, tout1, out, l + 8);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+
-+        iv = &(*ivec)[0];
-+        l2c(xor0, iv);
-+        l2c(xor1, iv);
-+    }
-+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
-+    inW0 = inW1 = outW0 = outW1 = 0;
-+    tin[0] = tin[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/build.info
-new file mode 100644
-index 0000000..dba9306
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/build.info
-@@ -0,0 +1,4 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c \
-+        dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh1024.pem b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh1024.pem
-new file mode 100644
-index 0000000..81d43f6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh1024.pem
-@@ -0,0 +1,5 @@
-+-----BEGIN DH PARAMETERS-----
-+MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
-+/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
-+/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
-+-----END DH PARAMETERS-----
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh192.pem b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh192.pem
-new file mode 100644
-index 0000000..521c072
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh192.pem
-@@ -0,0 +1,3 @@
-+-----BEGIN DH PARAMETERS-----
-+MB4CGQDUoLoCULb9LsYm5+/WN992xxbiLQlEuIsCAQM=
-+-----END DH PARAMETERS-----
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh2048.pem b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh2048.pem
-new file mode 100644
-index 0000000..295460f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh2048.pem
-@@ -0,0 +1,16 @@
-+-----BEGIN DH PARAMETERS-----
-+MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o
-+AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh
-+z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo
-+pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW
-+aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA
-+Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==
-+-----END DH PARAMETERS-----
-+-----BEGIN DH PARAMETERS-----
-+MIIBCAKCAQEArtA3w73zP6Lu3EOQtwogiXt3AXXpuS6yD4BhzNS1pZFyPHk0/an5
-+8ydEkPhQZHKDW+BZJxxPLANaTudWo2YT8TgtvUdN6KSgMiEi6McwqDw+SADuvW+F
-+SKUYFxG6VFIxyEP6xBdf+vhJxEDbRG2EYsHDRRtJ76gp9cSKTHusf2R+4AAVGqnt
-+gRAbNqtcOar/7FSj+Pl8G3v0Bty0LcCSpbqgYlnv6z+rErQmmC6PPvSz97TDMCok
-+yKpCE9hFA1zkqK3TH4FmFvGeIaXJUIBZf4mArWuBTjWFW3nmhESRUn1VK3K3x42N
-+a5k6c2+EhrMFiLjxuH6JZoqL0/E93FF9SwIBAg==
-+-----END DH PARAMETERS-----
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh4096.pem b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh4096.pem
-new file mode 100644
-index 0000000..390943a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh4096.pem
-@@ -0,0 +1,14 @@
-+-----BEGIN DH PARAMETERS-----
-+MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7
-+vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H
-+TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF
-+bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1
-+rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE
-+EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9
-+bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3
-+W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH
-+ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb
-+NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR
-+jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=
-+-----END DH PARAMETERS-----
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh512.pem b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh512.pem
-new file mode 100644
-index 0000000..0a4d863
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh512.pem
-@@ -0,0 +1,4 @@
-+-----BEGIN DH PARAMETERS-----
-+MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn
-+a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC
-+-----END DH PARAMETERS-----
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_ameth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_ameth.c
-new file mode 100644
-index 0000000..cd77867
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_ameth.c
-@@ -0,0 +1,870 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "dh_locl.h"
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+#include 
-+
-+/*
-+ * i2d/d2i like DH parameter functions which use the appropriate routine for
-+ * PKCS#3 DH or X9.42 DH.
-+ */
-+
-+static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp,
-+                   long length)
-+{
-+    if (pkey->ameth == &dhx_asn1_meth)
-+        return d2i_DHxparams(NULL, pp, length);
-+    return d2i_DHparams(NULL, pp, length);
-+}
-+
-+static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp)
-+{
-+    if (pkey->ameth == &dhx_asn1_meth)
-+        return i2d_DHxparams(a, pp);
-+    return i2d_DHparams(a, pp);
-+}
-+
-+static void int_dh_free(EVP_PKEY *pkey)
-+{
-+    DH_free(pkey->pkey.dh);
-+}
-+
-+static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
-+{
-+    const unsigned char *p, *pm;
-+    int pklen, pmlen;
-+    int ptype;
-+    const void *pval;
-+    const ASN1_STRING *pstr;
-+    X509_ALGOR *palg;
-+    ASN1_INTEGER *public_key = NULL;
-+
-+    DH *dh = NULL;
-+
-+    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
-+        return 0;
-+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-+
-+    if (ptype != V_ASN1_SEQUENCE) {
-+        DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
-+        goto err;
-+    }
-+
-+    pstr = pval;
-+    pm = pstr->data;
-+    pmlen = pstr->length;
-+
-+    if ((dh = d2i_dhp(pkey, &pm, pmlen)) == NULL) {
-+        DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) {
-+        DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    /* We have parameters now set public key */
-+    if ((dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
-+        DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    ASN1_INTEGER_free(public_key);
-+    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
-+    return 1;
-+
-+ err:
-+    ASN1_INTEGER_free(public_key);
-+    DH_free(dh);
-+    return 0;
-+
-+}
-+
-+static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
-+{
-+    DH *dh;
-+    int ptype;
-+    unsigned char *penc = NULL;
-+    int penclen;
-+    ASN1_STRING *str;
-+    ASN1_INTEGER *pub_key = NULL;
-+
-+    dh = pkey->pkey.dh;
-+
-+    str = ASN1_STRING_new();
-+    if (str == NULL) {
-+        DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    str->length = i2d_dhp(pkey, dh, &str->data);
-+    if (str->length <= 0) {
-+        DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    ptype = V_ASN1_SEQUENCE;
-+
-+    pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
-+    if (!pub_key)
-+        goto err;
-+
-+    penclen = i2d_ASN1_INTEGER(pub_key, &penc);
-+
-+    ASN1_INTEGER_free(pub_key);
-+
-+    if (penclen <= 0) {
-+        DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
-+                               ptype, str, penc, penclen))
-+        return 1;
-+
-+ err:
-+    OPENSSL_free(penc);
-+    ASN1_STRING_free(str);
-+
-+    return 0;
-+}
-+
-+/*
-+ * PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in that
-+ * the AlgorithmIdentifier contains the parameters, the private key is
-+ * explicitly included and the pubkey must be recalculated.
-+ */
-+
-+static int dh_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
-+{
-+    const unsigned char *p, *pm;
-+    int pklen, pmlen;
-+    int ptype;
-+    const void *pval;
-+    const ASN1_STRING *pstr;
-+    const X509_ALGOR *palg;
-+    ASN1_INTEGER *privkey = NULL;
-+
-+    DH *dh = NULL;
-+
-+    if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
-+        return 0;
-+
-+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-+
-+    if (ptype != V_ASN1_SEQUENCE)
-+        goto decerr;
-+    if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL)
-+        goto decerr;
-+
-+    pstr = pval;
-+    pm = pstr->data;
-+    pmlen = pstr->length;
-+    if ((dh = d2i_dhp(pkey, &pm, pmlen)) == NULL)
-+        goto decerr;
-+
-+    /* We have parameters now set private key */
-+    if ((dh->priv_key = BN_secure_new()) == NULL
-+        || !ASN1_INTEGER_to_BN(privkey, dh->priv_key)) {
-+        DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR);
-+        goto dherr;
-+    }
-+    /* Calculate public key */
-+    if (!DH_generate_key(dh))
-+        goto dherr;
-+
-+    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
-+
-+    ASN1_STRING_clear_free(privkey);
-+
-+    return 1;
-+
-+ decerr:
-+    DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
-+ dherr:
-+    DH_free(dh);
-+    ASN1_STRING_clear_free(privkey);
-+    return 0;
-+}
-+
-+static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
-+{
-+    ASN1_STRING *params = NULL;
-+    ASN1_INTEGER *prkey = NULL;
-+    unsigned char *dp = NULL;
-+    int dplen;
-+
-+    params = ASN1_STRING_new();
-+
-+    if (params == NULL) {
-+        DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    params->length = i2d_dhp(pkey, pkey->pkey.dh, ¶ms->data);
-+    if (params->length <= 0) {
-+        DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    params->type = V_ASN1_SEQUENCE;
-+
-+    /* Get private key into integer */
-+    prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
-+
-+    if (!prkey) {
-+        DHerr(DH_F_DH_PRIV_ENCODE, DH_R_BN_ERROR);
-+        goto err;
-+    }
-+
-+    dplen = i2d_ASN1_INTEGER(prkey, &dp);
-+
-+    ASN1_STRING_clear_free(prkey);
-+    prkey = NULL;
-+
-+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
-+                         V_ASN1_SEQUENCE, params, dp, dplen))
-+        goto err;
-+
-+    return 1;
-+
-+ err:
-+    OPENSSL_free(dp);
-+    ASN1_STRING_free(params);
-+    ASN1_STRING_clear_free(prkey);
-+    return 0;
-+}
-+
-+static int dh_param_decode(EVP_PKEY *pkey,
-+                           const unsigned char **pder, int derlen)
-+{
-+    DH *dh;
-+
-+    if ((dh = d2i_dhp(pkey, pder, derlen)) == NULL) {
-+        DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
-+        return 0;
-+    }
-+    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
-+    return 1;
-+}
-+
-+static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
-+{
-+    return i2d_dhp(pkey, pkey->pkey.dh, pder);
-+}
-+
-+static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype)
-+{
-+    int reason = ERR_R_BUF_LIB;
-+    const char *ktype = NULL;
-+    BIGNUM *priv_key, *pub_key;
-+
-+    if (ptype == 2)
-+        priv_key = x->priv_key;
-+    else
-+        priv_key = NULL;
-+
-+    if (ptype > 0)
-+        pub_key = x->pub_key;
-+    else
-+        pub_key = NULL;
-+
-+    if (x->p == NULL || (ptype == 2 && priv_key == NULL)
-+            || (ptype > 0 && pub_key == NULL)) {
-+        reason = ERR_R_PASSED_NULL_PARAMETER;
-+        goto err;
-+    }
-+
-+    if (ptype == 2)
-+        ktype = "DH Private-Key";
-+    else if (ptype == 1)
-+        ktype = "DH Public-Key";
-+    else
-+        ktype = "DH Parameters";
-+
-+    BIO_indent(bp, indent, 128);
-+    if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
-+        goto err;
-+    indent += 4;
-+
-+    if (!ASN1_bn_print(bp, "private-key:", priv_key, NULL, indent))
-+        goto err;
-+    if (!ASN1_bn_print(bp, "public-key:", pub_key, NULL, indent))
-+        goto err;
-+
-+    if (!ASN1_bn_print(bp, "prime:", x->p, NULL, indent))
-+        goto err;
-+    if (!ASN1_bn_print(bp, "generator:", x->g, NULL, indent))
-+        goto err;
-+    if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, NULL, indent))
-+        goto err;
-+    if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, NULL, indent))
-+        goto err;
-+    if (x->seed) {
-+        int i;
-+        BIO_indent(bp, indent, 128);
-+        BIO_puts(bp, "seed:");
-+        for (i = 0; i < x->seedlen; i++) {
-+            if ((i % 15) == 0) {
-+                if (BIO_puts(bp, "\n") <= 0
-+                    || !BIO_indent(bp, indent + 4, 128))
-+                    goto err;
-+            }
-+            if (BIO_printf(bp, "%02x%s", x->seed[i],
-+                           ((i + 1) == x->seedlen) ? "" : ":") <= 0)
-+                goto err;
-+        }
-+        if (BIO_write(bp, "\n", 1) <= 0)
-+            return (0);
-+    }
-+    if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, NULL, indent))
-+        goto err;
-+    if (x->length != 0) {
-+        BIO_indent(bp, indent, 128);
-+        if (BIO_printf(bp, "recommended-private-length: %d bits\n",
-+                       (int)x->length) <= 0)
-+            goto err;
-+    }
-+
-+    return 1;
-+
-+ err:
-+    DHerr(DH_F_DO_DH_PRINT, reason);
-+    return 0;
-+}
-+
-+static int int_dh_size(const EVP_PKEY *pkey)
-+{
-+    return (DH_size(pkey->pkey.dh));
-+}
-+
-+static int dh_bits(const EVP_PKEY *pkey)
-+{
-+    return BN_num_bits(pkey->pkey.dh->p);
-+}
-+
-+static int dh_security_bits(const EVP_PKEY *pkey)
-+{
-+    return DH_security_bits(pkey->pkey.dh);
-+}
-+
-+static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) ||
-+        BN_cmp(a->pkey.dh->g, b->pkey.dh->g))
-+        return 0;
-+    else if (a->ameth == &dhx_asn1_meth) {
-+        if (BN_cmp(a->pkey.dh->q, b->pkey.dh->q))
-+            return 0;
-+    }
-+    return 1;
-+}
-+
-+static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src)
-+{
-+    BIGNUM *a;
-+    if (src) {
-+        a = BN_dup(src);
-+        if (!a)
-+            return 0;
-+    } else
-+        a = NULL;
-+    BN_free(*dst);
-+    *dst = a;
-+    return 1;
-+}
-+
-+static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
-+{
-+    if (is_x942 == -1)
-+        is_x942 = ! !from->q;
-+    if (!int_dh_bn_cpy(&to->p, from->p))
-+        return 0;
-+    if (!int_dh_bn_cpy(&to->g, from->g))
-+        return 0;
-+    if (is_x942) {
-+        if (!int_dh_bn_cpy(&to->q, from->q))
-+            return 0;
-+        if (!int_dh_bn_cpy(&to->j, from->j))
-+            return 0;
-+        OPENSSL_free(to->seed);
-+        to->seed = NULL;
-+        to->seedlen = 0;
-+        if (from->seed) {
-+            to->seed = OPENSSL_memdup(from->seed, from->seedlen);
-+            if (!to->seed)
-+                return 0;
-+            to->seedlen = from->seedlen;
-+        }
-+    } else
-+        to->length = from->length;
-+    return 1;
-+}
-+
-+DH *DHparams_dup(DH *dh)
-+{
-+    DH *ret;
-+    ret = DH_new();
-+    if (ret == NULL)
-+        return NULL;
-+    if (!int_dh_param_copy(ret, dh, -1)) {
-+        DH_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
-+{
-+    if (to->pkey.dh == NULL) {
-+        to->pkey.dh = DH_new();
-+        if (to->pkey.dh == NULL)
-+            return 0;
-+    }
-+    return int_dh_param_copy(to->pkey.dh, from->pkey.dh,
-+                             from->ameth == &dhx_asn1_meth);
-+}
-+
-+static int dh_missing_parameters(const EVP_PKEY *a)
-+{
-+    if (a->pkey.dh == NULL || a->pkey.dh->p == NULL || a->pkey.dh->g == NULL)
-+        return 1;
-+    return 0;
-+}
-+
-+static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    if (dh_cmp_parameters(a, b) == 0)
-+        return 0;
-+    if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0)
-+        return 0;
-+    else
-+        return 1;
-+}
-+
-+static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                          ASN1_PCTX *ctx)
-+{
-+    return do_dh_print(bp, pkey->pkey.dh, indent, 0);
-+}
-+
-+static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                           ASN1_PCTX *ctx)
-+{
-+    return do_dh_print(bp, pkey->pkey.dh, indent, 1);
-+}
-+
-+static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                            ASN1_PCTX *ctx)
-+{
-+    return do_dh_print(bp, pkey->pkey.dh, indent, 2);
-+}
-+
-+int DHparams_print(BIO *bp, const DH *x)
-+{
-+    return do_dh_print(bp, x, 4, 0);
-+}
-+
-+#ifndef OPENSSL_NO_CMS
-+static int dh_cms_decrypt(CMS_RecipientInfo *ri);
-+static int dh_cms_encrypt(CMS_RecipientInfo *ri);
-+#endif
-+
-+static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
-+{
-+    switch (op) {
-+#ifndef OPENSSL_NO_CMS
-+
-+    case ASN1_PKEY_CTRL_CMS_ENVELOPE:
-+        if (arg1 == 1)
-+            return dh_cms_decrypt(arg2);
-+        else if (arg1 == 0)
-+            return dh_cms_encrypt(arg2);
-+        return -2;
-+
-+    case ASN1_PKEY_CTRL_CMS_RI_TYPE:
-+        *(int *)arg2 = CMS_RECIPINFO_AGREE;
-+        return 1;
-+#endif
-+    default:
-+        return -2;
-+    }
-+
-+}
-+
-+const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
-+    EVP_PKEY_DH,
-+    EVP_PKEY_DH,
-+    0,
-+
-+    "DH",
-+    "OpenSSL PKCS#3 DH method",
-+
-+    dh_pub_decode,
-+    dh_pub_encode,
-+    dh_pub_cmp,
-+    dh_public_print,
-+
-+    dh_priv_decode,
-+    dh_priv_encode,
-+    dh_private_print,
-+
-+    int_dh_size,
-+    dh_bits,
-+    dh_security_bits,
-+
-+    dh_param_decode,
-+    dh_param_encode,
-+    dh_missing_parameters,
-+    dh_copy_parameters,
-+    dh_cmp_parameters,
-+    dh_param_print,
-+    0,
-+
-+    int_dh_free,
-+    0
-+};
-+
-+const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
-+    EVP_PKEY_DHX,
-+    EVP_PKEY_DHX,
-+    0,
-+
-+    "X9.42 DH",
-+    "OpenSSL X9.42 DH method",
-+
-+    dh_pub_decode,
-+    dh_pub_encode,
-+    dh_pub_cmp,
-+    dh_public_print,
-+
-+    dh_priv_decode,
-+    dh_priv_encode,
-+    dh_private_print,
-+
-+    int_dh_size,
-+    dh_bits,
-+    dh_security_bits,
-+
-+    dh_param_decode,
-+    dh_param_encode,
-+    dh_missing_parameters,
-+    dh_copy_parameters,
-+    dh_cmp_parameters,
-+    dh_param_print,
-+    0,
-+
-+    int_dh_free,
-+    dh_pkey_ctrl
-+};
-+
-+#ifndef OPENSSL_NO_CMS
-+
-+static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
-+                              X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
-+{
-+    const ASN1_OBJECT *aoid;
-+    int atype;
-+    const void *aval;
-+    ASN1_INTEGER *public_key = NULL;
-+    int rv = 0;
-+    EVP_PKEY *pkpeer = NULL, *pk = NULL;
-+    DH *dhpeer = NULL;
-+    const unsigned char *p;
-+    int plen;
-+
-+    X509_ALGOR_get0(&aoid, &atype, &aval, alg);
-+    if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
-+        goto err;
-+    /* Only absent parameters allowed in RFC XXXX */
-+    if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
-+        goto err;
-+
-+    pk = EVP_PKEY_CTX_get0_pkey(pctx);
-+    if (!pk)
-+        goto err;
-+    if (pk->type != EVP_PKEY_DHX)
-+        goto err;
-+    /* Get parameters from parent key */
-+    dhpeer = DHparams_dup(pk->pkey.dh);
-+    /* We have parameters now set public key */
-+    plen = ASN1_STRING_length(pubkey);
-+    p = ASN1_STRING_get0_data(pubkey);
-+    if (!p || !plen)
-+        goto err;
-+
-+    if ((public_key = d2i_ASN1_INTEGER(NULL, &p, plen)) == NULL) {
-+        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    /* We have parameters now set public key */
-+    if ((dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
-+        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    pkpeer = EVP_PKEY_new();
-+    if (pkpeer == NULL)
-+        goto err;
-+    EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
-+    dhpeer = NULL;
-+    if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
-+        rv = 1;
-+ err:
-+    ASN1_INTEGER_free(public_key);
-+    EVP_PKEY_free(pkpeer);
-+    DH_free(dhpeer);
-+    return rv;
-+}
-+
-+static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
-+{
-+    int rv = 0;
-+
-+    X509_ALGOR *alg, *kekalg = NULL;
-+    ASN1_OCTET_STRING *ukm;
-+    const unsigned char *p;
-+    unsigned char *dukm = NULL;
-+    size_t dukmlen = 0;
-+    int keylen, plen;
-+    const EVP_CIPHER *kekcipher;
-+    EVP_CIPHER_CTX *kekctx;
-+
-+    if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
-+        goto err;
-+
-+    /*
-+     * For DH we only have one OID permissible. If ever any more get defined
-+     * we will need something cleverer.
-+     */
-+    if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) {
-+        DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR);
-+        goto err;
-+    }
-+
-+    if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0)
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
-+        goto err;
-+
-+    if (alg->parameter->type != V_ASN1_SEQUENCE)
-+        goto err;
-+
-+    p = alg->parameter->value.sequence->data;
-+    plen = alg->parameter->value.sequence->length;
-+    kekalg = d2i_X509_ALGOR(NULL, &p, plen);
-+    if (!kekalg)
-+        goto err;
-+    kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
-+    if (!kekctx)
-+        goto err;
-+    kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
-+    if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
-+        goto err;
-+    if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
-+        goto err;
-+    if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
-+        goto err;
-+
-+    keylen = EVP_CIPHER_CTX_key_length(kekctx);
-+    if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
-+        goto err;
-+    /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
-+    if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx,
-+                                     OBJ_nid2obj(EVP_CIPHER_type(kekcipher)))
-+        <= 0)
-+        goto err;
-+
-+    if (ukm) {
-+        dukmlen = ASN1_STRING_length(ukm);
-+        dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
-+        if (!dukm)
-+            goto err;
-+    }
-+
-+    if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
-+        goto err;
-+    dukm = NULL;
-+
-+    rv = 1;
-+ err:
-+    X509_ALGOR_free(kekalg);
-+    OPENSSL_free(dukm);
-+    return rv;
-+}
-+
-+static int dh_cms_decrypt(CMS_RecipientInfo *ri)
-+{
-+    EVP_PKEY_CTX *pctx;
-+    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
-+    if (!pctx)
-+        return 0;
-+    /* See if we need to set peer key */
-+    if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
-+        X509_ALGOR *alg;
-+        ASN1_BIT_STRING *pubkey;
-+        if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
-+                                                 NULL, NULL, NULL))
-+            return 0;
-+        if (!alg || !pubkey)
-+            return 0;
-+        if (!dh_cms_set_peerkey(pctx, alg, pubkey)) {
-+            DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR);
-+            return 0;
-+        }
-+    }
-+    /* Set DH derivation parameters and initialise unwrap context */
-+    if (!dh_cms_set_shared_info(pctx, ri)) {
-+        DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+static int dh_cms_encrypt(CMS_RecipientInfo *ri)
-+{
-+    EVP_PKEY_CTX *pctx;
-+    EVP_PKEY *pkey;
-+    EVP_CIPHER_CTX *ctx;
-+    int keylen;
-+    X509_ALGOR *talg, *wrap_alg = NULL;
-+    const ASN1_OBJECT *aoid;
-+    ASN1_BIT_STRING *pubkey;
-+    ASN1_STRING *wrap_str;
-+    ASN1_OCTET_STRING *ukm;
-+    unsigned char *penc = NULL, *dukm = NULL;
-+    int penclen;
-+    size_t dukmlen = 0;
-+    int rv = 0;
-+    int kdf_type, wrap_nid;
-+    const EVP_MD *kdf_md;
-+    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
-+    if (!pctx)
-+        return 0;
-+    /* Get ephemeral key */
-+    pkey = EVP_PKEY_CTX_get0_pkey(pctx);
-+    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
-+                                             NULL, NULL, NULL))
-+        goto err;
-+    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
-+    /* Is everything uninitialised? */
-+    if (aoid == OBJ_nid2obj(NID_undef)) {
-+        ASN1_INTEGER *pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
-+        if (!pubk)
-+            goto err;
-+        /* Set the key */
-+
-+        penclen = i2d_ASN1_INTEGER(pubk, &penc);
-+        ASN1_INTEGER_free(pubk);
-+        if (penclen <= 0)
-+            goto err;
-+        ASN1_STRING_set0(pubkey, penc, penclen);
-+        pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-+        pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-+
-+        penc = NULL;
-+        X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
-+                        V_ASN1_UNDEF, NULL);
-+    }
-+
-+    /* See if custom parameters set */
-+    kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
-+    if (kdf_type <= 0)
-+        goto err;
-+    if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
-+        goto err;
-+
-+    if (kdf_type == EVP_PKEY_DH_KDF_NONE) {
-+        kdf_type = EVP_PKEY_DH_KDF_X9_42;
-+        if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
-+            goto err;
-+    } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
-+        /* Unknown KDF */
-+        goto err;
-+    if (kdf_md == NULL) {
-+        /* Only SHA1 supported */
-+        kdf_md = EVP_sha1();
-+        if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
-+            goto err;
-+    } else if (EVP_MD_type(kdf_md) != NID_sha1)
-+        /* Unsupported digest */
-+        goto err;
-+
-+    if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
-+        goto err;
-+
-+    /* Get wrap NID */
-+    ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
-+    wrap_nid = EVP_CIPHER_CTX_type(ctx);
-+    if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
-+        goto err;
-+    keylen = EVP_CIPHER_CTX_key_length(ctx);
-+
-+    /* Package wrap algorithm in an AlgorithmIdentifier */
-+
-+    wrap_alg = X509_ALGOR_new();
-+    if (wrap_alg == NULL)
-+        goto err;
-+    wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
-+    wrap_alg->parameter = ASN1_TYPE_new();
-+    if (wrap_alg->parameter == NULL)
-+        goto err;
-+    if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
-+        goto err;
-+    if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
-+        ASN1_TYPE_free(wrap_alg->parameter);
-+        wrap_alg->parameter = NULL;
-+    }
-+
-+    if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
-+        goto err;
-+
-+    if (ukm) {
-+        dukmlen = ASN1_STRING_length(ukm);
-+        dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
-+        if (!dukm)
-+            goto err;
-+    }
-+
-+    if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
-+        goto err;
-+    dukm = NULL;
-+
-+    /*
-+     * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
-+     * of another AlgorithmIdentifier.
-+     */
-+    penc = NULL;
-+    penclen = i2d_X509_ALGOR(wrap_alg, &penc);
-+    if (!penc || !penclen)
-+        goto err;
-+    wrap_str = ASN1_STRING_new();
-+    if (wrap_str == NULL)
-+        goto err;
-+    ASN1_STRING_set0(wrap_str, penc, penclen);
-+    penc = NULL;
-+    X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
-+                    V_ASN1_SEQUENCE, wrap_str);
-+
-+    rv = 1;
-+
-+ err:
-+    OPENSSL_free(penc);
-+    X509_ALGOR_free(wrap_alg);
-+    return rv;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_asn1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_asn1.c
-new file mode 100644
-index 0000000..7c72fd6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_asn1.c
-@@ -0,0 +1,138 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "dh_locl.h"
-+#include 
-+#include 
-+
-+/* Override the default free and new methods */
-+static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                 void *exarg)
-+{
-+    if (operation == ASN1_OP_NEW_PRE) {
-+        *pval = (ASN1_VALUE *)DH_new();
-+        if (*pval != NULL)
-+            return 2;
-+        return 0;
-+    } else if (operation == ASN1_OP_FREE_PRE) {
-+        DH_free((DH *)*pval);
-+        *pval = NULL;
-+        return 2;
-+    }
-+    return 1;
-+}
-+
-+ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
-+        ASN1_SIMPLE(DH, p, BIGNUM),
-+        ASN1_SIMPLE(DH, g, BIGNUM),
-+        ASN1_OPT(DH, length, ZLONG),
-+} ASN1_SEQUENCE_END_cb(DH, DHparams)
-+
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
-+
-+/*
-+ * Internal only structures for handling X9.42 DH: this gets translated to or
-+ * from a DH structure straight away.
-+ */
-+
-+typedef struct {
-+    ASN1_BIT_STRING *seed;
-+    BIGNUM *counter;
-+} int_dhvparams;
-+
-+typedef struct {
-+    BIGNUM *p;
-+    BIGNUM *q;
-+    BIGNUM *g;
-+    BIGNUM *j;
-+    int_dhvparams *vparams;
-+} int_dhx942_dh;
-+
-+ASN1_SEQUENCE(DHvparams) = {
-+        ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING),
-+        ASN1_SIMPLE(int_dhvparams, counter, BIGNUM)
-+} static_ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams)
-+
-+ASN1_SEQUENCE(DHxparams) = {
-+        ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM),
-+        ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM),
-+        ASN1_SIMPLE(int_dhx942_dh, q, BIGNUM),
-+        ASN1_OPT(int_dhx942_dh, j, BIGNUM),
-+        ASN1_OPT(int_dhx942_dh, vparams, DHvparams),
-+} static_ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams)
-+
-+int_dhx942_dh *d2i_int_dhx(int_dhx942_dh **a,
-+                           const unsigned char **pp, long length);
-+int i2d_int_dhx(const int_dhx942_dh *a, unsigned char **pp);
-+
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(int_dhx942_dh, DHxparams, int_dhx)
-+
-+/* Application public function: read in X9.42 DH parameters into DH structure */
-+
-+DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length)
-+{
-+    int_dhx942_dh *dhx = NULL;
-+    DH *dh = NULL;
-+    dh = DH_new();
-+    if (dh == NULL)
-+        return NULL;
-+    dhx = d2i_int_dhx(NULL, pp, length);
-+    if (dhx == NULL) {
-+        DH_free(dh);
-+        return NULL;
-+    }
-+
-+    if (a) {
-+        DH_free(*a);
-+        *a = dh;
-+    }
-+
-+    dh->p = dhx->p;
-+    dh->q = dhx->q;
-+    dh->g = dhx->g;
-+    dh->j = dhx->j;
-+
-+    if (dhx->vparams) {
-+        dh->seed = dhx->vparams->seed->data;
-+        dh->seedlen = dhx->vparams->seed->length;
-+        dh->counter = dhx->vparams->counter;
-+        dhx->vparams->seed->data = NULL;
-+        ASN1_BIT_STRING_free(dhx->vparams->seed);
-+        OPENSSL_free(dhx->vparams);
-+        dhx->vparams = NULL;
-+    }
-+
-+    OPENSSL_free(dhx);
-+    return dh;
-+}
-+
-+int i2d_DHxparams(const DH *dh, unsigned char **pp)
-+{
-+    int_dhx942_dh dhx;
-+    int_dhvparams dhv;
-+    ASN1_BIT_STRING bs;
-+    dhx.p = dh->p;
-+    dhx.g = dh->g;
-+    dhx.q = dh->q;
-+    dhx.j = dh->j;
-+    if (dh->counter && dh->seed && dh->seedlen > 0) {
-+        bs.flags = ASN1_STRING_FLAG_BITS_LEFT;
-+        bs.data = dh->seed;
-+        bs.length = dh->seedlen;
-+        dhv.seed = &bs;
-+        dhv.counter = dh->counter;
-+        dhx.vparams = &dhv;
-+    } else
-+        dhx.vparams = NULL;
-+
-+    return i2d_int_dhx(&dhx, pp);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c
-new file mode 100644
-index 0000000..3b0fa59
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_check.c
-@@ -0,0 +1,183 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "dh_locl.h"
-+
-+/*-
-+ * Check that p and g are suitable enough
-+ *
-+ * p is odd
-+ * 1 < g < p - 1
-+ */
-+
-+int DH_check_params(const DH *dh, int *ret)
-+{
-+    int ok = 0;
-+    BIGNUM *tmp = NULL;
-+    BN_CTX *ctx = NULL;
-+
-+    *ret = 0;
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    tmp = BN_CTX_get(ctx);
-+    if (tmp == NULL)
-+        goto err;
-+
-+    if (!BN_is_odd(dh->p))
-+        *ret |= DH_CHECK_P_NOT_PRIME;
-+    if (BN_is_negative(dh->g) || BN_is_zero(dh->g) || BN_is_one(dh->g))
-+        *ret |= DH_NOT_SUITABLE_GENERATOR;
-+    if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
-+        goto err;
-+    if (BN_cmp(dh->g, tmp) >= 0)
-+        *ret |= DH_NOT_SUITABLE_GENERATOR;
-+
-+    ok = 1;
-+ err:
-+    if (ctx != NULL) {
-+        BN_CTX_end(ctx);
-+        BN_CTX_free(ctx);
-+    }
-+    return (ok);
-+}
-+
-+/*-
-+ * Check that p is a safe prime and
-+ * if g is 2, 3 or 5, check that it is a suitable generator
-+ * where
-+ * for 2, p mod 24 == 11
-+ * for 3, p mod 12 == 5
-+ * for 5, p mod 10 == 3 or 7
-+ * should hold.
-+ */
-+
-+int DH_check(const DH *dh, int *ret)
-+{
-+    int ok = 0, r;
-+    BN_CTX *ctx = NULL;
-+    BN_ULONG l;
-+    BIGNUM *t1 = NULL, *t2 = NULL;
-+
-+    *ret = 0;
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    t1 = BN_CTX_get(ctx);
-+    if (t1 == NULL)
-+        goto err;
-+    t2 = BN_CTX_get(ctx);
-+    if (t2 == NULL)
-+        goto err;
-+
-+    if (dh->q) {
-+        if (BN_cmp(dh->g, BN_value_one()) <= 0)
-+            *ret |= DH_NOT_SUITABLE_GENERATOR;
-+        else if (BN_cmp(dh->g, dh->p) >= 0)
-+            *ret |= DH_NOT_SUITABLE_GENERATOR;
-+        else {
-+            /* Check g^q == 1 mod p */
-+            if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
-+                goto err;
-+            if (!BN_is_one(t1))
-+                *ret |= DH_NOT_SUITABLE_GENERATOR;
-+        }
-+        r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL);
-+        if (r < 0)
-+            goto err;
-+        if (!r)
-+            *ret |= DH_CHECK_Q_NOT_PRIME;
-+        /* Check p == 1 mod q  i.e. q divides p - 1 */
-+        if (!BN_div(t1, t2, dh->p, dh->q, ctx))
-+            goto err;
-+        if (!BN_is_one(t2))
-+            *ret |= DH_CHECK_INVALID_Q_VALUE;
-+        if (dh->j && BN_cmp(dh->j, t1))
-+            *ret |= DH_CHECK_INVALID_J_VALUE;
-+
-+    } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
-+        l = BN_mod_word(dh->p, 24);
-+        if (l == (BN_ULONG)-1)
-+            goto err;
-+        if (l != 11)
-+            *ret |= DH_NOT_SUITABLE_GENERATOR;
-+    } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
-+        l = BN_mod_word(dh->p, 10);
-+        if (l == (BN_ULONG)-1)
-+            goto err;
-+        if ((l != 3) && (l != 7))
-+            *ret |= DH_NOT_SUITABLE_GENERATOR;
-+    } else
-+        *ret |= DH_UNABLE_TO_CHECK_GENERATOR;
-+
-+    r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL);
-+    if (r < 0)
-+        goto err;
-+    if (!r)
-+        *ret |= DH_CHECK_P_NOT_PRIME;
-+    else if (!dh->q) {
-+        if (!BN_rshift1(t1, dh->p))
-+            goto err;
-+        r = BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL);
-+        if (r < 0)
-+            goto err;
-+	if (!r)
-+            *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
-+    }
-+    ok = 1;
-+ err:
-+    if (ctx != NULL) {
-+        BN_CTX_end(ctx);
-+        BN_CTX_free(ctx);
-+    }
-+    return (ok);
-+}
-+
-+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
-+{
-+    int ok = 0;
-+    BIGNUM *tmp = NULL;
-+    BN_CTX *ctx = NULL;
-+
-+    *ret = 0;
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    tmp = BN_CTX_get(ctx);
-+    if (tmp == NULL || !BN_set_word(tmp, 1))
-+        goto err;
-+    if (BN_cmp(pub_key, tmp) <= 0)
-+        *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
-+    if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
-+        goto err;
-+    if (BN_cmp(pub_key, tmp) >= 0)
-+        *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
-+
-+    if (dh->q != NULL) {
-+        /* Check pub_key^q == 1 mod p */
-+        if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx))
-+            goto err;
-+        if (!BN_is_one(tmp))
-+            *ret |= DH_CHECK_PUBKEY_INVALID;
-+    }
-+
-+    ok = 1;
-+ err:
-+    if (ctx != NULL) {
-+        BN_CTX_end(ctx);
-+        BN_CTX_free(ctx);
-+    }
-+    return (ok);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_depr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_depr.c
-new file mode 100644
-index 0000000..f8ed1b7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_depr.c
-@@ -0,0 +1,46 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* This file contains deprecated functions as wrappers to the new ones */
-+
-+#include 
-+#if OPENSSL_API_COMPAT >= 0x00908000L
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+# include "internal/cryptlib.h"
-+# include 
-+# include 
-+
-+DH *DH_generate_parameters(int prime_len, int generator,
-+                           void (*callback) (int, int, void *), void *cb_arg)
-+{
-+    BN_GENCB *cb;
-+    DH *ret = NULL;
-+
-+    if ((ret = DH_new()) == NULL)
-+        return NULL;
-+    cb = BN_GENCB_new();
-+    if (cb == NULL) {
-+        DH_free(ret);
-+        return NULL;
-+    }
-+
-+    BN_GENCB_set_old(cb, callback, cb_arg);
-+
-+    if (DH_generate_parameters_ex(ret, prime_len, generator, cb)) {
-+        BN_GENCB_free(cb);
-+        return ret;
-+    }
-+    BN_GENCB_free(cb);
-+    DH_free(ret);
-+    return NULL;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c
-new file mode 100644
-index 0000000..4e21f28
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_err.c
-@@ -0,0 +1,73 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason)
-+
-+static ERR_STRING_DATA DH_str_functs[] = {
-+    {ERR_FUNC(DH_F_COMPUTE_KEY), "compute_key"},
-+    {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"},
-+    {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "dh_builtin_genparams"},
-+    {ERR_FUNC(DH_F_DH_CMS_DECRYPT), "dh_cms_decrypt"},
-+    {ERR_FUNC(DH_F_DH_CMS_SET_PEERKEY), "dh_cms_set_peerkey"},
-+    {ERR_FUNC(DH_F_DH_CMS_SET_SHARED_INFO), "dh_cms_set_shared_info"},
-+    {ERR_FUNC(DH_F_DH_METH_DUP), "DH_meth_dup"},
-+    {ERR_FUNC(DH_F_DH_METH_NEW), "DH_meth_new"},
-+    {ERR_FUNC(DH_F_DH_METH_SET1_NAME), "DH_meth_set1_name"},
-+    {ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"},
-+    {ERR_FUNC(DH_F_DH_PARAM_DECODE), "dh_param_decode"},
-+    {ERR_FUNC(DH_F_DH_PRIV_DECODE), "dh_priv_decode"},
-+    {ERR_FUNC(DH_F_DH_PRIV_ENCODE), "dh_priv_encode"},
-+    {ERR_FUNC(DH_F_DH_PUB_DECODE), "dh_pub_decode"},
-+    {ERR_FUNC(DH_F_DH_PUB_ENCODE), "dh_pub_encode"},
-+    {ERR_FUNC(DH_F_DO_DH_PRINT), "do_dh_print"},
-+    {ERR_FUNC(DH_F_GENERATE_KEY), "generate_key"},
-+    {ERR_FUNC(DH_F_PKEY_DH_DERIVE), "pkey_dh_derive"},
-+    {ERR_FUNC(DH_F_PKEY_DH_KEYGEN), "pkey_dh_keygen"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA DH_str_reasons[] = {
-+    {ERR_REASON(DH_R_BAD_GENERATOR), "bad generator"},
-+    {ERR_REASON(DH_R_BN_DECODE_ERROR), "bn decode error"},
-+    {ERR_REASON(DH_R_BN_ERROR), "bn error"},
-+    {ERR_REASON(DH_R_DECODE_ERROR), "decode error"},
-+    {ERR_REASON(DH_R_INVALID_PUBKEY), "invalid public key"},
-+    {ERR_REASON(DH_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
-+    {ERR_REASON(DH_R_KEYS_NOT_SET), "keys not set"},
-+    {ERR_REASON(DH_R_MODULUS_TOO_LARGE), "modulus too large"},
-+    {ERR_REASON(DH_R_NO_PARAMETERS_SET), "no parameters set"},
-+    {ERR_REASON(DH_R_NO_PRIVATE_VALUE), "no private value"},
-+    {ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"},
-+    {ERR_REASON(DH_R_PEER_KEY_ERROR), "peer key error"},
-+    {ERR_REASON(DH_R_SHARED_INFO_ERROR), "shared info error"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_DH_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(DH_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, DH_str_functs);
-+        ERR_load_strings(0, DH_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_gen.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_gen.c
-new file mode 100644
-index 0000000..27ecb98
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_gen.c
-@@ -0,0 +1,130 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * NB: These functions have been upgraded - the previous prototypes are in
-+ * dh_depr.c as wrappers to these ones.  - Geoff
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "dh_locl.h"
-+
-+static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
-+                                BN_GENCB *cb);
-+
-+int DH_generate_parameters_ex(DH *ret, int prime_len, int generator,
-+                              BN_GENCB *cb)
-+{
-+    if (ret->meth->generate_params)
-+        return ret->meth->generate_params(ret, prime_len, generator, cb);
-+    return dh_builtin_genparams(ret, prime_len, generator, cb);
-+}
-+
-+/*-
-+ * We generate DH parameters as follows
-+ * find a prime q which is prime_len/2 bits long.
-+ * p=(2*q)+1 or (p-1)/2 = q
-+ * For this case, g is a generator if
-+ * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
-+ * Since the factors of p-1 are q and 2, we just need to check
-+ * g^2 mod p != 1 and g^q mod p != 1.
-+ *
-+ * Having said all that,
-+ * there is another special case method for the generators 2, 3 and 5.
-+ * for 2, p mod 24 == 11
-+ * for 3, p mod 12 == 5  <<<<< does not work for safe primes.
-+ * for 5, p mod 10 == 3 or 7
-+ *
-+ * Thanks to Phil Karn  for the pointers about the
-+ * special generators and for answering some of my questions.
-+ *
-+ * I've implemented the second simple method :-).
-+ * Since DH should be using a safe prime (both p and q are prime),
-+ * this generator function can take a very very long time to run.
-+ */
-+/*
-+ * Actually there is no reason to insist that 'generator' be a generator.
-+ * It's just as OK (and in some sense better) to use a generator of the
-+ * order-q subgroup.
-+ */
-+static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
-+                                BN_GENCB *cb)
-+{
-+    BIGNUM *t1, *t2;
-+    int g, ok = -1;
-+    BN_CTX *ctx = NULL;
-+
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    t1 = BN_CTX_get(ctx);
-+    t2 = BN_CTX_get(ctx);
-+    if (t1 == NULL || t2 == NULL)
-+        goto err;
-+
-+    /* Make sure 'ret' has the necessary elements */
-+    if (!ret->p && ((ret->p = BN_new()) == NULL))
-+        goto err;
-+    if (!ret->g && ((ret->g = BN_new()) == NULL))
-+        goto err;
-+
-+    if (generator <= 1) {
-+        DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
-+        goto err;
-+    }
-+    if (generator == DH_GENERATOR_2) {
-+        if (!BN_set_word(t1, 24))
-+            goto err;
-+        if (!BN_set_word(t2, 11))
-+            goto err;
-+        g = 2;
-+    } else if (generator == DH_GENERATOR_5) {
-+        if (!BN_set_word(t1, 10))
-+            goto err;
-+        if (!BN_set_word(t2, 3))
-+            goto err;
-+        /*
-+         * BN_set_word(t3,7); just have to miss out on these ones :-(
-+         */
-+        g = 5;
-+    } else {
-+        /*
-+         * in the general case, don't worry if 'generator' is a generator or
-+         * not: since we are using safe primes, it will generate either an
-+         * order-q or an order-2q group, which both is OK
-+         */
-+        if (!BN_set_word(t1, 2))
-+            goto err;
-+        if (!BN_set_word(t2, 1))
-+            goto err;
-+        g = generator;
-+    }
-+
-+    if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb))
-+        goto err;
-+    if (!BN_GENCB_call(cb, 3, 0))
-+        goto err;
-+    if (!BN_set_word(ret->g, g))
-+        goto err;
-+    ok = 1;
-+ err:
-+    if (ok == -1) {
-+        DHerr(DH_F_DH_BUILTIN_GENPARAMS, ERR_R_BN_LIB);
-+        ok = 0;
-+    }
-+
-+    if (ctx != NULL) {
-+        BN_CTX_end(ctx);
-+        BN_CTX_free(ctx);
-+    }
-+    return ok;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_kdf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_kdf.c
-new file mode 100644
-index 0000000..2782eee
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_kdf.c
-@@ -0,0 +1,150 @@
-+/*
-+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#ifndef OPENSSL_NO_CMS
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+
-+/* Key derivation from X9.42/RFC2631 */
-+/* Uses CMS functions, hence the #ifdef wrapper. */
-+
-+#define DH_KDF_MAX      (1L << 30)
-+
-+/* Skip past an ASN1 structure: for OBJECT skip content octets too */
-+
-+static int skip_asn1(unsigned char **pp, long *plen, int exptag)
-+{
-+    const unsigned char *q = *pp;
-+    int i, tag, xclass;
-+    long tmplen;
-+    i = ASN1_get_object(&q, &tmplen, &tag, &xclass, *plen);
-+    if (i & 0x80)
-+        return 0;
-+    if (tag != exptag || xclass != V_ASN1_UNIVERSAL)
-+        return 0;
-+    if (tag == V_ASN1_OBJECT)
-+        q += tmplen;
-+    *plen -= q - *pp;
-+    *pp = (unsigned char *)q;
-+    return 1;
-+}
-+
-+/*
-+ * Encode the DH shared info structure, return an offset to the counter value
-+ * so we can update the structure without reencoding it.
-+ */
-+
-+static int dh_sharedinfo_encode(unsigned char **pder, unsigned char **pctr,
-+                                ASN1_OBJECT *key_oid, size_t outlen,
-+                                const unsigned char *ukm, size_t ukmlen)
-+{
-+    unsigned char *p;
-+    int derlen;
-+    long tlen;
-+    /* "magic" value to check offset is sane */
-+    static unsigned char ctr[4] = { 0xF3, 0x17, 0x22, 0x53 };
-+    X509_ALGOR atmp;
-+    ASN1_OCTET_STRING ctr_oct, ukm_oct, *pukm_oct;
-+    ASN1_TYPE ctr_atype;
-+    if (ukmlen > DH_KDF_MAX || outlen > DH_KDF_MAX)
-+        return 0;
-+    ctr_oct.data = ctr;
-+    ctr_oct.length = 4;
-+    ctr_oct.flags = 0;
-+    ctr_oct.type = V_ASN1_OCTET_STRING;
-+    ctr_atype.type = V_ASN1_OCTET_STRING;
-+    ctr_atype.value.octet_string = &ctr_oct;
-+    atmp.algorithm = key_oid;
-+    atmp.parameter = &ctr_atype;
-+    if (ukm) {
-+        ukm_oct.type = V_ASN1_OCTET_STRING;
-+        ukm_oct.flags = 0;
-+        ukm_oct.data = (unsigned char *)ukm;
-+        ukm_oct.length = ukmlen;
-+        pukm_oct = &ukm_oct;
-+    } else
-+        pukm_oct = NULL;
-+    derlen = CMS_SharedInfo_encode(pder, &atmp, pukm_oct, outlen);
-+    if (derlen <= 0)
-+        return 0;
-+    p = *pder;
-+    tlen = derlen;
-+    if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE))
-+        return 0;
-+    if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE))
-+        return 0;
-+    if (!skip_asn1(&p, &tlen, V_ASN1_OBJECT))
-+        return 0;
-+    if (!skip_asn1(&p, &tlen, V_ASN1_OCTET_STRING))
-+        return 0;
-+    if (CRYPTO_memcmp(p, ctr, 4))
-+        return 0;
-+    *pctr = p;
-+    return derlen;
-+}
-+
-+int DH_KDF_X9_42(unsigned char *out, size_t outlen,
-+                 const unsigned char *Z, size_t Zlen,
-+                 ASN1_OBJECT *key_oid,
-+                 const unsigned char *ukm, size_t ukmlen, const EVP_MD *md)
-+{
-+    EVP_MD_CTX *mctx = NULL;
-+    int rv = 0;
-+    unsigned int i;
-+    size_t mdlen;
-+    unsigned char *der = NULL, *ctr;
-+    int derlen;
-+    if (Zlen > DH_KDF_MAX)
-+        return 0;
-+    mctx = EVP_MD_CTX_new();
-+    if (mctx == NULL)
-+        return 0;
-+    mdlen = EVP_MD_size(md);
-+    derlen = dh_sharedinfo_encode(&der, &ctr, key_oid, outlen, ukm, ukmlen);
-+    if (derlen == 0)
-+        goto err;
-+    for (i = 1;; i++) {
-+        unsigned char mtmp[EVP_MAX_MD_SIZE];
-+        if (!EVP_DigestInit_ex(mctx, md, NULL)
-+            || !EVP_DigestUpdate(mctx, Z, Zlen))
-+            goto err;
-+        ctr[3] = i & 0xFF;
-+        ctr[2] = (i >> 8) & 0xFF;
-+        ctr[1] = (i >> 16) & 0xFF;
-+        ctr[0] = (i >> 24) & 0xFF;
-+        if (!EVP_DigestUpdate(mctx, der, derlen))
-+            goto err;
-+        if (outlen >= mdlen) {
-+            if (!EVP_DigestFinal(mctx, out, NULL))
-+                goto err;
-+            outlen -= mdlen;
-+            if (outlen == 0)
-+                break;
-+            out += mdlen;
-+        } else {
-+            if (!EVP_DigestFinal(mctx, mtmp, NULL))
-+                goto err;
-+            memcpy(out, mtmp, outlen);
-+            OPENSSL_cleanse(mtmp, mdlen);
-+            break;
-+        }
-+    }
-+    rv = 1;
-+ err:
-+    OPENSSL_free(der);
-+    EVP_MD_CTX_free(mctx);
-+    return rv;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_key.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_key.c
-new file mode 100644
-index 0000000..204e5a7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_key.c
-@@ -0,0 +1,215 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "dh_locl.h"
-+#include "internal/bn_int.h"
-+
-+static int generate_key(DH *dh);
-+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
-+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
-+                         const BIGNUM *a, const BIGNUM *p,
-+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
-+static int dh_init(DH *dh);
-+static int dh_finish(DH *dh);
-+
-+int DH_generate_key(DH *dh)
-+{
-+    return dh->meth->generate_key(dh);
-+}
-+
-+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
-+{
-+    return dh->meth->compute_key(key, pub_key, dh);
-+}
-+
-+int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh)
-+{
-+    int rv, pad;
-+    rv = dh->meth->compute_key(key, pub_key, dh);
-+    if (rv <= 0)
-+        return rv;
-+    pad = BN_num_bytes(dh->p) - rv;
-+    if (pad > 0) {
-+        memmove(key + pad, key, rv);
-+        memset(key, 0, pad);
-+    }
-+    return rv + pad;
-+}
-+
-+static DH_METHOD dh_ossl = {
-+    "OpenSSL DH Method",
-+    generate_key,
-+    compute_key,
-+    dh_bn_mod_exp,
-+    dh_init,
-+    dh_finish,
-+    DH_FLAG_FIPS_METHOD,
-+    NULL,
-+    NULL
-+};
-+
-+const DH_METHOD *DH_OpenSSL(void)
-+{
-+    return &dh_ossl;
-+}
-+
-+static int generate_key(DH *dh)
-+{
-+    int ok = 0;
-+    int generate_new_key = 0;
-+    unsigned l;
-+    BN_CTX *ctx;
-+    BN_MONT_CTX *mont = NULL;
-+    BIGNUM *pub_key = NULL, *priv_key = NULL;
-+
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+
-+    if (dh->priv_key == NULL) {
-+        priv_key = BN_secure_new();
-+        if (priv_key == NULL)
-+            goto err;
-+        generate_new_key = 1;
-+    } else
-+        priv_key = dh->priv_key;
-+
-+    if (dh->pub_key == NULL) {
-+        pub_key = BN_new();
-+        if (pub_key == NULL)
-+            goto err;
-+    } else
-+        pub_key = dh->pub_key;
-+
-+    if (dh->flags & DH_FLAG_CACHE_MONT_P) {
-+        mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
-+                                      dh->lock, dh->p, ctx);
-+        if (!mont)
-+            goto err;
-+    }
-+
-+    if (generate_new_key) {
-+        if (dh->q) {
-+            do {
-+                if (!BN_rand_range(priv_key, dh->q))
-+                    goto err;
-+            }
-+            while (BN_is_zero(priv_key) || BN_is_one(priv_key));
-+        } else {
-+            /* secret exponent length */
-+            l = dh->length ? dh->length : BN_num_bits(dh->p) - 1;
-+            if (!BN_rand(priv_key, l, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
-+                goto err;
-+        }
-+    }
-+
-+    {
-+        BIGNUM *prk = BN_new();
-+
-+        if (prk == NULL)
-+            goto err;
-+        BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
-+
-+        if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) {
-+            BN_free(prk);
-+            goto err;
-+        }
-+        /* We MUST free prk before any further use of priv_key */
-+        BN_free(prk);
-+    }
-+
-+    dh->pub_key = pub_key;
-+    dh->priv_key = priv_key;
-+    ok = 1;
-+ err:
-+    if (ok != 1)
-+        DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB);
-+
-+    if (pub_key != dh->pub_key)
-+        BN_free(pub_key);
-+    if (priv_key != dh->priv_key)
-+        BN_free(priv_key);
-+    BN_CTX_free(ctx);
-+    return (ok);
-+}
-+
-+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
-+{
-+    BN_CTX *ctx = NULL;
-+    BN_MONT_CTX *mont = NULL;
-+    BIGNUM *tmp;
-+    int ret = -1;
-+    int check_result;
-+
-+    if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
-+        DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE);
-+        goto err;
-+    }
-+
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    tmp = BN_CTX_get(ctx);
-+    if (tmp == NULL)
-+        goto err;
-+
-+    if (dh->priv_key == NULL) {
-+        DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE);
-+        goto err;
-+    }
-+
-+    if (dh->flags & DH_FLAG_CACHE_MONT_P) {
-+        mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
-+                                      dh->lock, dh->p, ctx);
-+        BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
-+        if (!mont)
-+            goto err;
-+    }
-+
-+    if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
-+        DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY);
-+        goto err;
-+    }
-+
-+    if (!dh->
-+        meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) {
-+        DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+
-+    ret = BN_bn2bin(tmp, key);
-+ err:
-+    if (ctx != NULL) {
-+        BN_CTX_end(ctx);
-+        BN_CTX_free(ctx);
-+    }
-+    return (ret);
-+}
-+
-+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
-+                         const BIGNUM *a, const BIGNUM *p,
-+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
-+{
-+    return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
-+}
-+
-+static int dh_init(DH *dh)
-+{
-+    dh->flags |= DH_FLAG_CACHE_MONT_P;
-+    return (1);
-+}
-+
-+static int dh_finish(DH *dh)
-+{
-+    BN_MONT_CTX_free(dh->method_mont_p);
-+    return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_lib.c
-new file mode 100644
-index 0000000..adf1771
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_lib.c
-@@ -0,0 +1,284 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "dh_locl.h"
-+#include 
-+
-+static const DH_METHOD *default_DH_method = NULL;
-+
-+void DH_set_default_method(const DH_METHOD *meth)
-+{
-+    default_DH_method = meth;
-+}
-+
-+const DH_METHOD *DH_get_default_method(void)
-+{
-+    if (!default_DH_method)
-+        default_DH_method = DH_OpenSSL();
-+    return default_DH_method;
-+}
-+
-+int DH_set_method(DH *dh, const DH_METHOD *meth)
-+{
-+    /*
-+     * NB: The caller is specifically setting a method, so it's not up to us
-+     * to deal with which ENGINE it comes from.
-+     */
-+    const DH_METHOD *mtmp;
-+    mtmp = dh->meth;
-+    if (mtmp->finish)
-+        mtmp->finish(dh);
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(dh->engine);
-+    dh->engine = NULL;
-+#endif
-+    dh->meth = meth;
-+    if (meth->init)
-+        meth->init(dh);
-+    return 1;
-+}
-+
-+DH *DH_new(void)
-+{
-+    return DH_new_method(NULL);
-+}
-+
-+DH *DH_new_method(ENGINE *engine)
-+{
-+    DH *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->references = 1;
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+
-+    ret->meth = DH_get_default_method();
-+#ifndef OPENSSL_NO_ENGINE
-+    ret->flags = ret->meth->flags;  /* early default init */
-+    if (engine) {
-+        if (!ENGINE_init(engine)) {
-+            DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
-+            goto err;
-+        }
-+        ret->engine = engine;
-+    } else
-+        ret->engine = ENGINE_get_default_DH();
-+    if (ret->engine) {
-+        ret->meth = ENGINE_get_DH(ret->engine);
-+        if (ret->meth == NULL) {
-+            DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
-+            goto err;
-+        }
-+    }
-+#endif
-+
-+    ret->flags = ret->meth->flags;
-+
-+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data))
-+        goto err;
-+
-+    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
-+        DHerr(DH_F_DH_NEW_METHOD, ERR_R_INIT_FAIL);
-+err:
-+        DH_free(ret);
-+        ret = NULL;
-+    }
-+
-+    return ret;
-+}
-+
-+void DH_free(DH *r)
-+{
-+    int i;
-+
-+    if (r == NULL)
-+        return;
-+
-+    CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
-+    REF_PRINT_COUNT("DH", r);
-+    if (i > 0)
-+        return;
-+    REF_ASSERT_ISNT(i < 0);
-+
-+    if (r->meth->finish)
-+        r->meth->finish(r);
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(r->engine);
-+#endif
-+
-+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data);
-+
-+    CRYPTO_THREAD_lock_free(r->lock);
-+
-+    BN_clear_free(r->p);
-+    BN_clear_free(r->g);
-+    BN_clear_free(r->q);
-+    BN_clear_free(r->j);
-+    OPENSSL_free(r->seed);
-+    BN_clear_free(r->counter);
-+    BN_clear_free(r->pub_key);
-+    BN_clear_free(r->priv_key);
-+    OPENSSL_free(r);
-+}
-+
-+int DH_up_ref(DH *r)
-+{
-+    int i;
-+
-+    if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
-+        return 0;
-+
-+    REF_PRINT_COUNT("DH", r);
-+    REF_ASSERT_ISNT(i < 2);
-+    return ((i > 1) ? 1 : 0);
-+}
-+
-+int DH_set_ex_data(DH *d, int idx, void *arg)
-+{
-+    return (CRYPTO_set_ex_data(&d->ex_data, idx, arg));
-+}
-+
-+void *DH_get_ex_data(DH *d, int idx)
-+{
-+    return (CRYPTO_get_ex_data(&d->ex_data, idx));
-+}
-+
-+int DH_bits(const DH *dh)
-+{
-+    return BN_num_bits(dh->p);
-+}
-+
-+int DH_size(const DH *dh)
-+{
-+    return (BN_num_bytes(dh->p));
-+}
-+
-+int DH_security_bits(const DH *dh)
-+{
-+    int N;
-+    if (dh->q)
-+        N = BN_num_bits(dh->q);
-+    else if (dh->length)
-+        N = dh->length;
-+    else
-+        N = -1;
-+    return BN_security_bits(BN_num_bits(dh->p), N);
-+}
-+
-+
-+void DH_get0_pqg(const DH *dh,
-+                 const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
-+{
-+    if (p != NULL)
-+        *p = dh->p;
-+    if (q != NULL)
-+        *q = dh->q;
-+    if (g != NULL)
-+        *g = dh->g;
-+}
-+
-+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
-+{
-+    /* If the fields p and g in d are NULL, the corresponding input
-+     * parameters MUST be non-NULL.  q may remain NULL.
-+     */
-+    if ((dh->p == NULL && p == NULL)
-+        || (dh->g == NULL && g == NULL))
-+        return 0;
-+
-+    if (p != NULL) {
-+        BN_free(dh->p);
-+        dh->p = p;
-+    }
-+    if (q != NULL) {
-+        BN_free(dh->q);
-+        dh->q = q;
-+    }
-+    if (g != NULL) {
-+        BN_free(dh->g);
-+        dh->g = g;
-+    }
-+
-+    if (q != NULL) {
-+        dh->length = BN_num_bits(q);
-+    }
-+
-+    return 1;
-+}
-+
-+long DH_get_length(const DH *dh)
-+{
-+    return dh->length;
-+}
-+
-+int DH_set_length(DH *dh, long length)
-+{
-+    dh->length = length;
-+    return 1;
-+}
-+
-+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
-+{
-+    if (pub_key != NULL)
-+        *pub_key = dh->pub_key;
-+    if (priv_key != NULL)
-+        *priv_key = dh->priv_key;
-+}
-+
-+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
-+{
-+    /* If the field pub_key in dh is NULL, the corresponding input
-+     * parameters MUST be non-NULL.  The priv_key field may
-+     * be left NULL.
-+     */
-+    if (dh->pub_key == NULL && pub_key == NULL)
-+        return 0;
-+
-+    if (pub_key != NULL) {
-+        BN_free(dh->pub_key);
-+        dh->pub_key = pub_key;
-+    }
-+    if (priv_key != NULL) {
-+        BN_free(dh->priv_key);
-+        dh->priv_key = priv_key;
-+    }
-+
-+    return 1;
-+}
-+
-+void DH_clear_flags(DH *dh, int flags)
-+{
-+    dh->flags &= ~flags;
-+}
-+
-+int DH_test_flags(const DH *dh, int flags)
-+{
-+    return dh->flags & flags;
-+}
-+
-+void DH_set_flags(DH *dh, int flags)
-+{
-+    dh->flags |= flags;
-+}
-+
-+ENGINE *DH_get0_engine(DH *dh)
-+{
-+    return dh->engine;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_locl.h
-new file mode 100644
-index 0000000..19301c3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_locl.h
-@@ -0,0 +1,56 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+struct dh_st {
-+    /*
-+     * This first argument is used to pick up errors when a DH is passed
-+     * instead of a EVP_PKEY
-+     */
-+    int pad;
-+    int version;
-+    BIGNUM *p;
-+    BIGNUM *g;
-+    long length;                /* optional */
-+    BIGNUM *pub_key;            /* g^x % p */
-+    BIGNUM *priv_key;           /* x */
-+    int flags;
-+    BN_MONT_CTX *method_mont_p;
-+    /* Place holders if we want to do X9.42 DH */
-+    BIGNUM *q;
-+    BIGNUM *j;
-+    unsigned char *seed;
-+    int seedlen;
-+    BIGNUM *counter;
-+    int references;
-+    CRYPTO_EX_DATA ex_data;
-+    const DH_METHOD *meth;
-+    ENGINE *engine;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+struct dh_method {
-+    char *name;
-+    /* Methods here */
-+    int (*generate_key) (DH *dh);
-+    int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh);
-+
-+    /* Can be null */
-+    int (*bn_mod_exp) (const DH *dh, BIGNUM *r, const BIGNUM *a,
-+                       const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
-+                       BN_MONT_CTX *m_ctx);
-+    int (*init) (DH *dh);
-+    int (*finish) (DH *dh);
-+    int flags;
-+    char *app_data;
-+    /* If this is non-NULL, it will be used to generate parameters */
-+    int (*generate_params) (DH *dh, int prime_len, int generator,
-+                            BN_GENCB *cb);
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_meth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_meth.c
-new file mode 100644
-index 0000000..ce6114c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_meth.c
-@@ -0,0 +1,173 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "dh_locl.h"
-+#include 
-+#include 
-+
-+DH_METHOD *DH_meth_new(const char *name, int flags)
-+{
-+    DH_METHOD *dhm = OPENSSL_zalloc(sizeof(*dhm));
-+
-+    if (dhm != NULL) {
-+        dhm->flags = flags;
-+
-+        dhm->name = OPENSSL_strdup(name);
-+        if (dhm->name != NULL)
-+            return dhm;
-+
-+        OPENSSL_free(dhm);
-+    }
-+
-+    DHerr(DH_F_DH_METH_NEW, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+void DH_meth_free(DH_METHOD *dhm)
-+{
-+    if (dhm != NULL) {
-+        OPENSSL_free(dhm->name);
-+        OPENSSL_free(dhm);
-+    }
-+}
-+
-+DH_METHOD *DH_meth_dup(const DH_METHOD *dhm)
-+{
-+    DH_METHOD *ret = OPENSSL_malloc(sizeof(*ret));
-+
-+    if (ret != NULL) {
-+        memcpy(ret, dhm, sizeof(*dhm));
-+
-+        ret->name = OPENSSL_strdup(dhm->name);
-+        if (ret->name != NULL)
-+            return ret;
-+
-+        OPENSSL_free(ret);
-+    }
-+
-+    DHerr(DH_F_DH_METH_DUP, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+const char *DH_meth_get0_name(const DH_METHOD *dhm)
-+{
-+    return dhm->name;
-+}
-+
-+int DH_meth_set1_name(DH_METHOD *dhm, const char *name)
-+{
-+    char *tmpname = OPENSSL_strdup(name);
-+
-+    if (tmpname == NULL) {
-+        DHerr(DH_F_DH_METH_SET1_NAME, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    OPENSSL_free(dhm->name);
-+    dhm->name = tmpname;
-+
-+    return 1;
-+}
-+
-+int DH_meth_get_flags(DH_METHOD *dhm)
-+{
-+    return dhm->flags;
-+}
-+
-+int DH_meth_set_flags(DH_METHOD *dhm, int flags)
-+{
-+    dhm->flags = flags;
-+    return 1;
-+}
-+
-+void *DH_meth_get0_app_data(const DH_METHOD *dhm)
-+{
-+    return dhm->app_data;
-+}
-+
-+int DH_meth_set0_app_data(DH_METHOD *dhm, void *app_data)
-+{
-+    dhm->app_data = app_data;
-+    return 1;
-+}
-+
-+int (*DH_meth_get_generate_key(const DH_METHOD *dhm)) (DH *)
-+{
-+    return dhm->generate_key;
-+}
-+
-+int DH_meth_set_generate_key(DH_METHOD *dhm, int (*generate_key) (DH *))
-+{
-+    dhm->generate_key = generate_key;
-+    return 1;
-+}
-+
-+int (*DH_meth_get_compute_key(const DH_METHOD *dhm))
-+        (unsigned char *key, const BIGNUM *pub_key, DH *dh)
-+{
-+    return dhm->compute_key;
-+}
-+
-+int DH_meth_set_compute_key(DH_METHOD *dhm,
-+        int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh))
-+{
-+    dhm->compute_key = compute_key;
-+    return 1;
-+}
-+
-+
-+int (*DH_meth_get_bn_mod_exp(const DH_METHOD *dhm))
-+    (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
-+     BN_CTX *, BN_MONT_CTX *)
-+{
-+    return dhm->bn_mod_exp;
-+}
-+
-+int DH_meth_set_bn_mod_exp(DH_METHOD *dhm,
-+    int (*bn_mod_exp) (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *,
-+                       const BIGNUM *, BN_CTX *, BN_MONT_CTX *))
-+{
-+    dhm->bn_mod_exp = bn_mod_exp;
-+    return 1;
-+}
-+
-+int (*DH_meth_get_init(const DH_METHOD *dhm))(DH *)
-+{
-+    return dhm->init;
-+}
-+
-+int DH_meth_set_init(DH_METHOD *dhm, int (*init)(DH *))
-+{
-+    dhm->init = init;
-+    return 1;
-+}
-+
-+int (*DH_meth_get_finish(const DH_METHOD *dhm)) (DH *)
-+{
-+    return dhm->finish;
-+}
-+
-+int DH_meth_set_finish(DH_METHOD *dhm, int (*finish) (DH *))
-+{
-+    dhm->finish = finish;
-+    return 1;
-+}
-+
-+int (*DH_meth_get_generate_params(const DH_METHOD *dhm))
-+        (DH *, int, int, BN_GENCB *)
-+{
-+    return dhm->generate_params;
-+}
-+
-+int DH_meth_set_generate_params(DH_METHOD *dhm,
-+        int (*generate_params) (DH *, int, int, BN_GENCB *))
-+{
-+    dhm->generate_params = generate_params;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_pmeth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_pmeth.c
-new file mode 100644
-index 0000000..c3e03c7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_pmeth.c
-@@ -0,0 +1,501 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "dh_locl.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+/* DH pkey context structure */
-+
-+typedef struct {
-+    /* Parameter gen parameters */
-+    int prime_len;
-+    int generator;
-+    int use_dsa;
-+    int subprime_len;
-+    /* message digest used for parameter generation */
-+    const EVP_MD *md;
-+    int rfc5114_param;
-+    /* Keygen callback info */
-+    int gentmp[2];
-+    /* KDF (if any) to use for DH */
-+    char kdf_type;
-+    /* OID to use for KDF */
-+    ASN1_OBJECT *kdf_oid;
-+    /* Message digest to use for key derivation */
-+    const EVP_MD *kdf_md;
-+    /* User key material */
-+    unsigned char *kdf_ukm;
-+    size_t kdf_ukmlen;
-+    /* KDF output length */
-+    size_t kdf_outlen;
-+} DH_PKEY_CTX;
-+
-+static int pkey_dh_init(EVP_PKEY_CTX *ctx)
-+{
-+    DH_PKEY_CTX *dctx;
-+
-+    dctx = OPENSSL_zalloc(sizeof(*dctx));
-+    if (dctx == NULL)
-+        return 0;
-+    dctx->prime_len = 1024;
-+    dctx->subprime_len = -1;
-+    dctx->generator = 2;
-+    dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
-+
-+    ctx->data = dctx;
-+    ctx->keygen_info = dctx->gentmp;
-+    ctx->keygen_info_count = 2;
-+
-+    return 1;
-+}
-+
-+static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
-+{
-+    DH_PKEY_CTX *dctx = ctx->data;
-+    if (dctx != NULL) {
-+        OPENSSL_free(dctx->kdf_ukm);
-+        ASN1_OBJECT_free(dctx->kdf_oid);
-+        OPENSSL_free(dctx);
-+    }
-+}
-+
-+
-+static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
-+{
-+    DH_PKEY_CTX *dctx, *sctx;
-+    if (!pkey_dh_init(dst))
-+        return 0;
-+    sctx = src->data;
-+    dctx = dst->data;
-+    dctx->prime_len = sctx->prime_len;
-+    dctx->subprime_len = sctx->subprime_len;
-+    dctx->generator = sctx->generator;
-+    dctx->use_dsa = sctx->use_dsa;
-+    dctx->md = sctx->md;
-+    dctx->rfc5114_param = sctx->rfc5114_param;
-+
-+    dctx->kdf_type = sctx->kdf_type;
-+    dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
-+    if (dctx->kdf_oid == NULL)
-+        return 0;
-+    dctx->kdf_md = sctx->kdf_md;
-+    if (sctx->kdf_ukm != NULL) {
-+        dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
-+        if (dctx->kdf_ukm == NULL)
-+          return 0;
-+        dctx->kdf_ukmlen = sctx->kdf_ukmlen;
-+    }
-+    dctx->kdf_outlen = sctx->kdf_outlen;
-+    return 1;
-+}
-+
-+static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-+{
-+    DH_PKEY_CTX *dctx = ctx->data;
-+    switch (type) {
-+    case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
-+        if (p1 < 256)
-+            return -2;
-+        dctx->prime_len = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
-+        if (dctx->use_dsa == 0)
-+            return -2;
-+        dctx->subprime_len = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
-+        if (dctx->use_dsa)
-+            return -2;
-+        dctx->generator = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
-+#ifdef OPENSSL_NO_DSA
-+        if (p1 != 0)
-+            return -2;
-+#else
-+        if (p1 < 0 || p1 > 2)
-+            return -2;
-+#endif
-+        dctx->use_dsa = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DH_RFC5114:
-+        if (p1 < 1 || p1 > 3)
-+            return -2;
-+        dctx->rfc5114_param = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_PEER_KEY:
-+        /* Default behaviour is OK */
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DH_KDF_TYPE:
-+        if (p1 == -2)
-+            return dctx->kdf_type;
-+#ifdef OPENSSL_NO_CMS
-+        if (p1 != EVP_PKEY_DH_KDF_NONE)
-+#else
-+        if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
-+#endif
-+            return -2;
-+        dctx->kdf_type = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DH_KDF_MD:
-+        dctx->kdf_md = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_DH_KDF_MD:
-+        *(const EVP_MD **)p2 = dctx->kdf_md;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
-+        if (p1 <= 0)
-+            return -2;
-+        dctx->kdf_outlen = (size_t)p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
-+        *(int *)p2 = dctx->kdf_outlen;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DH_KDF_UKM:
-+        OPENSSL_free(dctx->kdf_ukm);
-+        dctx->kdf_ukm = p2;
-+        if (p2)
-+            dctx->kdf_ukmlen = p1;
-+        else
-+            dctx->kdf_ukmlen = 0;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
-+        *(unsigned char **)p2 = dctx->kdf_ukm;
-+        return dctx->kdf_ukmlen;
-+
-+    case EVP_PKEY_CTRL_DH_KDF_OID:
-+        ASN1_OBJECT_free(dctx->kdf_oid);
-+        dctx->kdf_oid = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_DH_KDF_OID:
-+        *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
-+        return 1;
-+
-+    default:
-+        return -2;
-+
-+    }
-+}
-+
-+static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
-+                            const char *type, const char *value)
-+{
-+    if (strcmp(type, "dh_paramgen_prime_len") == 0) {
-+        int len;
-+        len = atoi(value);
-+        return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
-+    }
-+    if (strcmp(type, "dh_rfc5114") == 0) {
-+        DH_PKEY_CTX *dctx = ctx->data;
-+        int len;
-+        len = atoi(value);
-+        if (len < 0 || len > 3)
-+            return -2;
-+        dctx->rfc5114_param = len;
-+        return 1;
-+    }
-+    if (strcmp(type, "dh_paramgen_generator") == 0) {
-+        int len;
-+        len = atoi(value);
-+        return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
-+    }
-+    if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
-+        int len;
-+        len = atoi(value);
-+        return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
-+    }
-+    if (strcmp(type, "dh_paramgen_type") == 0) {
-+        int typ;
-+        typ = atoi(value);
-+        return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
-+    }
-+    return -2;
-+}
-+
-+#ifndef OPENSSL_NO_DSA
-+
-+extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
-+                                const EVP_MD *evpmd,
-+                                const unsigned char *seed_in, size_t seed_len,
-+                                unsigned char *seed_out, int *counter_ret,
-+                                unsigned long *h_ret, BN_GENCB *cb);
-+
-+extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
-+                                 const EVP_MD *evpmd,
-+                                 const unsigned char *seed_in,
-+                                 size_t seed_len, int idx,
-+                                 unsigned char *seed_out, int *counter_ret,
-+                                 unsigned long *h_ret, BN_GENCB *cb);
-+
-+static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
-+{
-+    DSA *ret;
-+    int rv = 0;
-+    int prime_len = dctx->prime_len;
-+    int subprime_len = dctx->subprime_len;
-+    const EVP_MD *md = dctx->md;
-+    if (dctx->use_dsa > 2)
-+        return NULL;
-+    ret = DSA_new();
-+    if (ret == NULL)
-+        return NULL;
-+    if (subprime_len == -1) {
-+        if (prime_len >= 2048)
-+            subprime_len = 256;
-+        else
-+            subprime_len = 160;
-+    }
-+    if (md == NULL) {
-+        if (prime_len >= 2048)
-+            md = EVP_sha256();
-+        else
-+            md = EVP_sha1();
-+    }
-+    if (dctx->use_dsa == 1)
-+        rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
-+                                  NULL, 0, NULL, NULL, NULL, pcb);
-+    else if (dctx->use_dsa == 2)
-+        rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
-+                                   NULL, 0, -1, NULL, NULL, NULL, pcb);
-+    if (rv <= 0) {
-+        DSA_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+#endif
-+
-+static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    DH *dh = NULL;
-+    DH_PKEY_CTX *dctx = ctx->data;
-+    BN_GENCB *pcb;
-+    int ret;
-+    if (dctx->rfc5114_param) {
-+        switch (dctx->rfc5114_param) {
-+        case 1:
-+            dh = DH_get_1024_160();
-+            break;
-+
-+        case 2:
-+            dh = DH_get_2048_224();
-+            break;
-+
-+        case 3:
-+            dh = DH_get_2048_256();
-+            break;
-+
-+        default:
-+            return -2;
-+        }
-+        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
-+        return 1;
-+    }
-+
-+    if (ctx->pkey_gencb) {
-+        pcb = BN_GENCB_new();
-+        if (pcb == NULL)
-+            return 0;
-+        evp_pkey_set_cb_translate(pcb, ctx);
-+    } else
-+        pcb = NULL;
-+#ifndef OPENSSL_NO_DSA
-+    if (dctx->use_dsa) {
-+        DSA *dsa_dh;
-+        dsa_dh = dsa_dh_generate(dctx, pcb);
-+        BN_GENCB_free(pcb);
-+        if (dsa_dh == NULL)
-+            return 0;
-+        dh = DSA_dup_DH(dsa_dh);
-+        DSA_free(dsa_dh);
-+        if (!dh)
-+            return 0;
-+        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
-+        return 1;
-+    }
-+#endif
-+    dh = DH_new();
-+    if (dh == NULL) {
-+        BN_GENCB_free(pcb);
-+        return 0;
-+    }
-+    ret = DH_generate_parameters_ex(dh,
-+                                    dctx->prime_len, dctx->generator, pcb);
-+    BN_GENCB_free(pcb);
-+    if (ret)
-+        EVP_PKEY_assign_DH(pkey, dh);
-+    else
-+        DH_free(dh);
-+    return ret;
-+}
-+
-+static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    DH *dh = NULL;
-+    if (ctx->pkey == NULL) {
-+        DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
-+        return 0;
-+    }
-+    dh = DH_new();
-+    if (dh == NULL)
-+        return 0;
-+    EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
-+    /* Note: if error return, pkey is freed by parent routine */
-+    if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
-+        return 0;
-+    return DH_generate_key(pkey->pkey.dh);
-+}
-+
-+static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
-+                          size_t *keylen)
-+{
-+    int ret;
-+    DH *dh;
-+    DH_PKEY_CTX *dctx = ctx->data;
-+    BIGNUM *dhpub;
-+    if (!ctx->pkey || !ctx->peerkey) {
-+        DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
-+        return 0;
-+    }
-+    dh = ctx->pkey->pkey.dh;
-+    dhpub = ctx->peerkey->pkey.dh->pub_key;
-+    if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
-+        if (key == NULL) {
-+            *keylen = DH_size(dh);
-+            return 1;
-+        }
-+        ret = DH_compute_key(key, dhpub, dh);
-+        if (ret < 0)
-+            return ret;
-+        *keylen = ret;
-+        return 1;
-+    }
-+#ifndef OPENSSL_NO_CMS
-+    else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
-+
-+        unsigned char *Z = NULL;
-+        size_t Zlen = 0;
-+        if (!dctx->kdf_outlen || !dctx->kdf_oid)
-+            return 0;
-+        if (key == NULL) {
-+            *keylen = dctx->kdf_outlen;
-+            return 1;
-+        }
-+        if (*keylen != dctx->kdf_outlen)
-+            return 0;
-+        ret = 0;
-+        Zlen = DH_size(dh);
-+        Z = OPENSSL_malloc(Zlen);
-+        if (Z == NULL) {
-+            goto err;
-+        }
-+        if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
-+            goto err;
-+        if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
-+                          dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
-+            goto err;
-+        *keylen = dctx->kdf_outlen;
-+        ret = 1;
-+ err:
-+        OPENSSL_clear_free(Z, Zlen);
-+        return ret;
-+    }
-+#endif
-+    return 0;
-+}
-+
-+const EVP_PKEY_METHOD dh_pkey_meth = {
-+    EVP_PKEY_DH,
-+    0,
-+    pkey_dh_init,
-+    pkey_dh_copy,
-+    pkey_dh_cleanup,
-+
-+    0,
-+    pkey_dh_paramgen,
-+
-+    0,
-+    pkey_dh_keygen,
-+
-+    0,
-+    0,
-+
-+    0,
-+    0,
-+
-+    0, 0,
-+
-+    0, 0, 0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0,
-+    pkey_dh_derive,
-+
-+    pkey_dh_ctrl,
-+    pkey_dh_ctrl_str
-+};
-+
-+const EVP_PKEY_METHOD dhx_pkey_meth = {
-+    EVP_PKEY_DHX,
-+    0,
-+    pkey_dh_init,
-+    pkey_dh_copy,
-+    pkey_dh_cleanup,
-+
-+    0,
-+    pkey_dh_paramgen,
-+
-+    0,
-+    pkey_dh_keygen,
-+
-+    0,
-+    0,
-+
-+    0,
-+    0,
-+
-+    0, 0,
-+
-+    0, 0, 0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0,
-+    pkey_dh_derive,
-+
-+    pkey_dh_ctrl,
-+    pkey_dh_ctrl_str
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_prn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_prn.c
-new file mode 100644
-index 0000000..283fb0f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_prn.c
-@@ -0,0 +1,30 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+#ifndef OPENSSL_NO_STDIO
-+int DHparams_print_fp(FILE *fp, const DH *x)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = DHparams_print(b, x);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_rfc5114.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_rfc5114.c
-new file mode 100644
-index 0000000..c4a2195
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dh/dh_rfc5114.c
-@@ -0,0 +1,41 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "dh_locl.h"
-+#include 
-+#include "internal/bn_dh.h"
-+
-+/*
-+ * Macro to make a DH structure from BIGNUM data. NB: although just copying
-+ * the BIGNUM static pointers would be more efficient, we can't do that
-+ * because they get wiped using BN_clear_free() when DH_free() is called.
-+ */
-+
-+#define make_dh(x) \
-+DH *DH_get_##x(void) \
-+{ \
-+    DH *dh = DH_new(); \
-+\
-+    if (dh == NULL) \
-+        return NULL; \
-+    dh->p = BN_dup(&_bignum_dh##x##_p); \
-+    dh->g = BN_dup(&_bignum_dh##x##_g); \
-+    dh->q = BN_dup(&_bignum_dh##x##_q); \
-+    if (dh->p == NULL || dh->q == NULL || dh->g == NULL) {\
-+        DH_free(dh); \
-+        return NULL; \
-+    } \
-+    return dh; \
-+}
-+
-+make_dh(1024_160)
-+make_dh(2048_224)
-+make_dh(2048_256)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dllmain.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dllmain.c
-new file mode 100644
-index 0000000..91904aa
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dllmain.c
-@@ -0,0 +1,60 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib_int.h"
-+
-+#if defined(_WIN32) || defined(__CYGWIN__)
-+# ifdef __CYGWIN__
-+/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
-+#  include 
-+/*
-+ * this has side-effect of _WIN32 getting defined, which otherwise is
-+ * mutually exclusive with __CYGWIN__...
-+ */
-+# endif
-+
-+/*
-+ * All we really need to do is remove the 'error' state when a thread
-+ * detaches
-+ */
-+
-+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
-+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-+{
-+    switch (fdwReason) {
-+    case DLL_PROCESS_ATTACH:
-+        OPENSSL_cpuid_setup();
-+# if defined(_WIN32_WINNT)
-+        {
-+            IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *) hinstDLL;
-+            IMAGE_NT_HEADERS *nt_headers;
-+
-+            if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) {
-+                nt_headers = (IMAGE_NT_HEADERS *) ((char *)dos_header
-+                                                   + dos_header->e_lfanew);
-+                if (nt_headers->Signature == IMAGE_NT_SIGNATURE &&
-+                    hinstDLL !=
-+                    (HINSTANCE) (nt_headers->OptionalHeader.ImageBase))
-+                    OPENSSL_NONPIC_relocated = 1;
-+            }
-+        }
-+# endif
-+        break;
-+    case DLL_THREAD_ATTACH:
-+        break;
-+    case DLL_THREAD_DETACH:
-+        OPENSSL_thread_stop();
-+        break;
-+    case DLL_PROCESS_DETACH:
-+        break;
-+    }
-+    return (TRUE);
-+}
-+#endif
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/build.info
-new file mode 100644
-index 0000000..2e75985
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/build.info
-@@ -0,0 +1,5 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        dsa_gen.c dsa_key.c dsa_lib.c dsa_asn1.c dsa_vrf.c dsa_sign.c \
-+        dsa_err.c dsa_ossl.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \
-+        dsa_meth.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_ameth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_ameth.c
-new file mode 100644
-index 0000000..7c0428d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_ameth.c
-@@ -0,0 +1,567 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "dsa_locl.h"
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
-+{
-+    const unsigned char *p, *pm;
-+    int pklen, pmlen;
-+    int ptype;
-+    const void *pval;
-+    const ASN1_STRING *pstr;
-+    X509_ALGOR *palg;
-+    ASN1_INTEGER *public_key = NULL;
-+
-+    DSA *dsa = NULL;
-+
-+    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
-+        return 0;
-+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-+
-+    if (ptype == V_ASN1_SEQUENCE) {
-+        pstr = pval;
-+        pm = pstr->data;
-+        pmlen = pstr->length;
-+
-+        if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) {
-+            DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
-+            goto err;
-+        }
-+
-+    } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) {
-+        if ((dsa = DSA_new()) == NULL) {
-+            DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    } else {
-+        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
-+        goto err;
-+    }
-+
-+    if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) {
-+        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    if ((dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
-+        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    ASN1_INTEGER_free(public_key);
-+    EVP_PKEY_assign_DSA(pkey, dsa);
-+    return 1;
-+
-+ err:
-+    ASN1_INTEGER_free(public_key);
-+    DSA_free(dsa);
-+    return 0;
-+
-+}
-+
-+static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
-+{
-+    DSA *dsa;
-+    int ptype;
-+    unsigned char *penc = NULL;
-+    int penclen;
-+    ASN1_STRING *str = NULL;
-+    ASN1_INTEGER *pubint = NULL;
-+
-+    dsa = pkey->pkey.dsa;
-+    if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
-+        str = ASN1_STRING_new();
-+        if (str == NULL) {
-+            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        str->length = i2d_DSAparams(dsa, &str->data);
-+        if (str->length <= 0) {
-+            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        ptype = V_ASN1_SEQUENCE;
-+    } else
-+        ptype = V_ASN1_UNDEF;
-+
-+    pubint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL);
-+
-+    if (pubint == NULL) {
-+        DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    penclen = i2d_ASN1_INTEGER(pubint, &penc);
-+    ASN1_INTEGER_free(pubint);
-+
-+    if (penclen <= 0) {
-+        DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
-+                               ptype, str, penc, penclen))
-+        return 1;
-+
-+ err:
-+    OPENSSL_free(penc);
-+    ASN1_STRING_free(str);
-+
-+    return 0;
-+}
-+
-+/*
-+ * In PKCS#8 DSA: you just get a private key integer and parameters in the
-+ * AlgorithmIdentifier the pubkey must be recalculated.
-+ */
-+
-+static int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
-+{
-+    const unsigned char *p, *pm;
-+    int pklen, pmlen;
-+    int ptype;
-+    const void *pval;
-+    const ASN1_STRING *pstr;
-+    const X509_ALGOR *palg;
-+    ASN1_INTEGER *privkey = NULL;
-+    BN_CTX *ctx = NULL;
-+
-+    DSA *dsa = NULL;
-+
-+    int ret = 0;
-+
-+    if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
-+        return 0;
-+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-+
-+    if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL)
-+        goto decerr;
-+    if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE)
-+        goto decerr;
-+
-+    pstr = pval;
-+    pm = pstr->data;
-+    pmlen = pstr->length;
-+    if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL)
-+        goto decerr;
-+    /* We have parameters now set private key */
-+    if ((dsa->priv_key = BN_secure_new()) == NULL
-+        || !ASN1_INTEGER_to_BN(privkey, dsa->priv_key)) {
-+        DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
-+        goto dsaerr;
-+    }
-+    /* Calculate public key */
-+    if ((dsa->pub_key = BN_new()) == NULL) {
-+        DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
-+        goto dsaerr;
-+    }
-+    if ((ctx = BN_CTX_new()) == NULL) {
-+        DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
-+        goto dsaerr;
-+    }
-+
-+    if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
-+        DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
-+        goto dsaerr;
-+    }
-+
-+    EVP_PKEY_assign_DSA(pkey, dsa);
-+
-+    ret = 1;
-+    goto done;
-+
-+ decerr:
-+    DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_DECODE_ERROR);
-+ dsaerr:
-+    DSA_free(dsa);
-+ done:
-+    BN_CTX_free(ctx);
-+    ASN1_STRING_clear_free(privkey);
-+    return ret;
-+}
-+
-+static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
-+{
-+    ASN1_STRING *params = NULL;
-+    ASN1_INTEGER *prkey = NULL;
-+    unsigned char *dp = NULL;
-+    int dplen;
-+
-+    if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
-+        DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_MISSING_PARAMETERS);
-+        goto err;
-+    }
-+
-+    params = ASN1_STRING_new();
-+
-+    if (params == NULL) {
-+        DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data);
-+    if (params->length <= 0) {
-+        DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    params->type = V_ASN1_SEQUENCE;
-+
-+    /* Get private key into integer */
-+    prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
-+
-+    if (!prkey) {
-+        DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR);
-+        goto err;
-+    }
-+
-+    dplen = i2d_ASN1_INTEGER(prkey, &dp);
-+
-+    ASN1_STRING_clear_free(prkey);
-+    prkey = NULL;
-+
-+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
-+                         V_ASN1_SEQUENCE, params, dp, dplen))
-+        goto err;
-+
-+    return 1;
-+
-+ err:
-+    OPENSSL_free(dp);
-+    ASN1_STRING_free(params);
-+    ASN1_STRING_clear_free(prkey);
-+    return 0;
-+}
-+
-+static int int_dsa_size(const EVP_PKEY *pkey)
-+{
-+    return (DSA_size(pkey->pkey.dsa));
-+}
-+
-+static int dsa_bits(const EVP_PKEY *pkey)
-+{
-+    return DSA_bits(pkey->pkey.dsa);
-+}
-+
-+static int dsa_security_bits(const EVP_PKEY *pkey)
-+{
-+    return DSA_security_bits(pkey->pkey.dsa);
-+}
-+
-+static int dsa_missing_parameters(const EVP_PKEY *pkey)
-+{
-+    DSA *dsa;
-+    dsa = pkey->pkey.dsa;
-+    if (dsa == NULL || dsa->p == NULL || dsa->q == NULL || dsa->g == NULL)
-+        return 1;
-+    return 0;
-+}
-+
-+static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
-+{
-+    BIGNUM *a;
-+
-+    if (to->pkey.dsa == NULL) {
-+        to->pkey.dsa = DSA_new();
-+        if (to->pkey.dsa == NULL)
-+            return 0;
-+    }
-+
-+    if ((a = BN_dup(from->pkey.dsa->p)) == NULL)
-+        return 0;
-+    BN_free(to->pkey.dsa->p);
-+    to->pkey.dsa->p = a;
-+
-+    if ((a = BN_dup(from->pkey.dsa->q)) == NULL)
-+        return 0;
-+    BN_free(to->pkey.dsa->q);
-+    to->pkey.dsa->q = a;
-+
-+    if ((a = BN_dup(from->pkey.dsa->g)) == NULL)
-+        return 0;
-+    BN_free(to->pkey.dsa->g);
-+    to->pkey.dsa->g = a;
-+    return 1;
-+}
-+
-+static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) ||
-+        BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) ||
-+        BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g))
-+        return 0;
-+    else
-+        return 1;
-+}
-+
-+static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0)
-+        return 0;
-+    else
-+        return 1;
-+}
-+
-+static void int_dsa_free(EVP_PKEY *pkey)
-+{
-+    DSA_free(pkey->pkey.dsa);
-+}
-+
-+static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
-+{
-+    int ret = 0;
-+    const char *ktype = NULL;
-+    const BIGNUM *priv_key, *pub_key;
-+
-+    if (ptype == 2)
-+        priv_key = x->priv_key;
-+    else
-+        priv_key = NULL;
-+
-+    if (ptype > 0)
-+        pub_key = x->pub_key;
-+    else
-+        pub_key = NULL;
-+
-+    if (ptype == 2)
-+        ktype = "Private-Key";
-+    else if (ptype == 1)
-+        ktype = "Public-Key";
-+    else
-+        ktype = "DSA-Parameters";
-+
-+    if (priv_key) {
-+        if (!BIO_indent(bp, off, 128))
-+            goto err;
-+        if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p))
-+            <= 0)
-+            goto err;
-+    }
-+
-+    if (!ASN1_bn_print(bp, "priv:", priv_key, NULL, off))
-+        goto err;
-+    if (!ASN1_bn_print(bp, "pub: ", pub_key, NULL, off))
-+        goto err;
-+    if (!ASN1_bn_print(bp, "P:   ", x->p, NULL, off))
-+        goto err;
-+    if (!ASN1_bn_print(bp, "Q:   ", x->q, NULL, off))
-+        goto err;
-+    if (!ASN1_bn_print(bp, "G:   ", x->g, NULL, off))
-+        goto err;
-+    ret = 1;
-+ err:
-+    return (ret);
-+}
-+
-+static int dsa_param_decode(EVP_PKEY *pkey,
-+                            const unsigned char **pder, int derlen)
-+{
-+    DSA *dsa;
-+
-+    if ((dsa = d2i_DSAparams(NULL, pder, derlen)) == NULL) {
-+        DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
-+        return 0;
-+    }
-+    EVP_PKEY_assign_DSA(pkey, dsa);
-+    return 1;
-+}
-+
-+static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
-+{
-+    return i2d_DSAparams(pkey->pkey.dsa, pder);
-+}
-+
-+static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                           ASN1_PCTX *ctx)
-+{
-+    return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
-+}
-+
-+static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                         ASN1_PCTX *ctx)
-+{
-+    return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
-+}
-+
-+static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                          ASN1_PCTX *ctx)
-+{
-+    return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
-+}
-+
-+static int old_dsa_priv_decode(EVP_PKEY *pkey,
-+                               const unsigned char **pder, int derlen)
-+{
-+    DSA *dsa;
-+
-+    if ((dsa = d2i_DSAPrivateKey(NULL, pder, derlen)) == NULL) {
-+        DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
-+        return 0;
-+    }
-+    EVP_PKEY_assign_DSA(pkey, dsa);
-+    return 1;
-+}
-+
-+static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
-+{
-+    return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
-+}
-+
-+static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
-+                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
-+{
-+    DSA_SIG *dsa_sig;
-+    const unsigned char *p;
-+
-+    if (!sig) {
-+        if (BIO_puts(bp, "\n") <= 0)
-+            return 0;
-+        else
-+            return 1;
-+    }
-+    p = sig->data;
-+    dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
-+    if (dsa_sig) {
-+        int rv = 0;
-+        const BIGNUM *r, *s;
-+
-+        DSA_SIG_get0(dsa_sig, &r, &s);
-+
-+        if (BIO_write(bp, "\n", 1) != 1)
-+            goto err;
-+
-+        if (!ASN1_bn_print(bp, "r:   ", r, NULL, indent))
-+            goto err;
-+        if (!ASN1_bn_print(bp, "s:   ", s, NULL, indent))
-+            goto err;
-+        rv = 1;
-+ err:
-+        DSA_SIG_free(dsa_sig);
-+        return rv;
-+    }
-+    return X509_signature_dump(bp, sig, indent);
-+}
-+
-+static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
-+{
-+    switch (op) {
-+    case ASN1_PKEY_CTRL_PKCS7_SIGN:
-+        if (arg1 == 0) {
-+            int snid, hnid;
-+            X509_ALGOR *alg1, *alg2;
-+            PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
-+            if (alg1 == NULL || alg1->algorithm == NULL)
-+                return -1;
-+            hnid = OBJ_obj2nid(alg1->algorithm);
-+            if (hnid == NID_undef)
-+                return -1;
-+            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
-+                return -1;
-+            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
-+        }
-+        return 1;
-+#ifndef OPENSSL_NO_CMS
-+    case ASN1_PKEY_CTRL_CMS_SIGN:
-+        if (arg1 == 0) {
-+            int snid, hnid;
-+            X509_ALGOR *alg1, *alg2;
-+            CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
-+            if (alg1 == NULL || alg1->algorithm == NULL)
-+                return -1;
-+            hnid = OBJ_obj2nid(alg1->algorithm);
-+            if (hnid == NID_undef)
-+                return -1;
-+            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
-+                return -1;
-+            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
-+        }
-+        return 1;
-+
-+    case ASN1_PKEY_CTRL_CMS_RI_TYPE:
-+        *(int *)arg2 = CMS_RECIPINFO_NONE;
-+        return 1;
-+#endif
-+
-+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
-+        *(int *)arg2 = NID_sha256;
-+        return 2;
-+
-+    default:
-+        return -2;
-+
-+    }
-+
-+}
-+
-+/* NB these are sorted in pkey_id order, lowest first */
-+
-+const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = {
-+
-+    {
-+     EVP_PKEY_DSA2,
-+     EVP_PKEY_DSA,
-+     ASN1_PKEY_ALIAS},
-+
-+    {
-+     EVP_PKEY_DSA1,
-+     EVP_PKEY_DSA,
-+     ASN1_PKEY_ALIAS},
-+
-+    {
-+     EVP_PKEY_DSA4,
-+     EVP_PKEY_DSA,
-+     ASN1_PKEY_ALIAS},
-+
-+    {
-+     EVP_PKEY_DSA3,
-+     EVP_PKEY_DSA,
-+     ASN1_PKEY_ALIAS},
-+
-+    {
-+     EVP_PKEY_DSA,
-+     EVP_PKEY_DSA,
-+     0,
-+
-+     "DSA",
-+     "OpenSSL DSA method",
-+
-+     dsa_pub_decode,
-+     dsa_pub_encode,
-+     dsa_pub_cmp,
-+     dsa_pub_print,
-+
-+     dsa_priv_decode,
-+     dsa_priv_encode,
-+     dsa_priv_print,
-+
-+     int_dsa_size,
-+     dsa_bits,
-+     dsa_security_bits,
-+
-+     dsa_param_decode,
-+     dsa_param_encode,
-+     dsa_missing_parameters,
-+     dsa_copy_parameters,
-+     dsa_cmp_parameters,
-+     dsa_param_print,
-+     dsa_sig_print,
-+
-+     int_dsa_free,
-+     dsa_pkey_ctrl,
-+     old_dsa_priv_decode,
-+     old_dsa_priv_encode}
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_asn1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_asn1.c
-new file mode 100644
-index 0000000..551c107
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_asn1.c
-@@ -0,0 +1,155 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "dsa_locl.h"
-+#include 
-+#include 
-+#include 
-+
-+ASN1_SEQUENCE(DSA_SIG) = {
-+        ASN1_SIMPLE(DSA_SIG, r, CBIGNUM),
-+        ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
-+} static_ASN1_SEQUENCE_END(DSA_SIG)
-+
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG)
-+
-+DSA_SIG *DSA_SIG_new(void)
-+{
-+    DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig));
-+    if (sig == NULL)
-+        DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE);
-+    return sig;
-+}
-+
-+void DSA_SIG_free(DSA_SIG *sig)
-+{
-+    if (sig == NULL)
-+        return;
-+    BN_clear_free(sig->r);
-+    BN_clear_free(sig->s);
-+    OPENSSL_free(sig);
-+}
-+
-+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
-+{
-+    if (pr != NULL)
-+        *pr = sig->r;
-+    if (ps != NULL)
-+        *ps = sig->s;
-+}
-+
-+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
-+{
-+    if (r == NULL || s == NULL)
-+        return 0;
-+    BN_clear_free(sig->r);
-+    BN_clear_free(sig->s);
-+    sig->r = r;
-+    sig->s = s;
-+    return 1;
-+}
-+
-+/* Override the default free and new methods */
-+static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                  void *exarg)
-+{
-+    if (operation == ASN1_OP_NEW_PRE) {
-+        *pval = (ASN1_VALUE *)DSA_new();
-+        if (*pval != NULL)
-+            return 2;
-+        return 0;
-+    } else if (operation == ASN1_OP_FREE_PRE) {
-+        DSA_free((DSA *)*pval);
-+        *pval = NULL;
-+        return 2;
-+    }
-+    return 1;
-+}
-+
-+ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
-+        ASN1_SIMPLE(DSA, version, LONG),
-+        ASN1_SIMPLE(DSA, p, BIGNUM),
-+        ASN1_SIMPLE(DSA, q, BIGNUM),
-+        ASN1_SIMPLE(DSA, g, BIGNUM),
-+        ASN1_SIMPLE(DSA, pub_key, BIGNUM),
-+        ASN1_SIMPLE(DSA, priv_key, CBIGNUM)
-+} static_ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey)
-+
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey)
-+
-+ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = {
-+        ASN1_SIMPLE(DSA, p, BIGNUM),
-+        ASN1_SIMPLE(DSA, q, BIGNUM),
-+        ASN1_SIMPLE(DSA, g, BIGNUM),
-+} static_ASN1_SEQUENCE_END_cb(DSA, DSAparams)
-+
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams)
-+
-+ASN1_SEQUENCE_cb(DSAPublicKey, dsa_cb) = {
-+        ASN1_SIMPLE(DSA, pub_key, BIGNUM),
-+        ASN1_SIMPLE(DSA, p, BIGNUM),
-+        ASN1_SIMPLE(DSA, q, BIGNUM),
-+        ASN1_SIMPLE(DSA, g, BIGNUM)
-+} static_ASN1_SEQUENCE_END_cb(DSA, DSAPublicKey)
-+
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey)
-+
-+DSA *DSAparams_dup(DSA *dsa)
-+{
-+    return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
-+}
-+
-+int DSA_sign(int type, const unsigned char *dgst, int dlen,
-+             unsigned char *sig, unsigned int *siglen, DSA *dsa)
-+{
-+    DSA_SIG *s;
-+    RAND_seed(dgst, dlen);
-+    s = DSA_do_sign(dgst, dlen, dsa);
-+    if (s == NULL) {
-+        *siglen = 0;
-+        return (0);
-+    }
-+    *siglen = i2d_DSA_SIG(s, &sig);
-+    DSA_SIG_free(s);
-+    return (1);
-+}
-+
-+/* data has already been hashed (probably with SHA or SHA-1). */
-+/*-
-+ * returns
-+ *      1: correct signature
-+ *      0: incorrect signature
-+ *     -1: error
-+ */
-+int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
-+               const unsigned char *sigbuf, int siglen, DSA *dsa)
-+{
-+    DSA_SIG *s;
-+    const unsigned char *p = sigbuf;
-+    unsigned char *der = NULL;
-+    int derlen = -1;
-+    int ret = -1;
-+
-+    s = DSA_SIG_new();
-+    if (s == NULL)
-+        return (ret);
-+    if (d2i_DSA_SIG(&s, &p, siglen) == NULL)
-+        goto err;
-+    /* Ensure signature uses DER and doesn't have trailing garbage */
-+    derlen = i2d_DSA_SIG(s, &der);
-+    if (derlen != siglen || memcmp(sigbuf, der, derlen))
-+        goto err;
-+    ret = DSA_do_verify(dgst, dgst_len, s, dsa);
-+ err:
-+    OPENSSL_clear_free(der, derlen);
-+    DSA_SIG_free(s);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_depr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_depr.c
-new file mode 100644
-index 0000000..f51aea7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_depr.c
-@@ -0,0 +1,62 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * This file contains deprecated function(s) that are now wrappers to the new
-+ * version(s).
-+ */
-+
-+/*
-+ * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
-+ * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB
-+ * 180-1)
-+ */
-+#define xxxHASH    EVP_sha1()
-+
-+#include 
-+#if OPENSSL_API_COMPAT >= 0x00908000L
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+# include 
-+# include "internal/cryptlib.h"
-+# include 
-+# include 
-+# include 
-+# include 
-+
-+DSA *DSA_generate_parameters(int bits,
-+                             unsigned char *seed_in, int seed_len,
-+                             int *counter_ret, unsigned long *h_ret,
-+                             void (*callback) (int, int, void *),
-+                             void *cb_arg)
-+{
-+    BN_GENCB *cb;
-+    DSA *ret;
-+
-+    if ((ret = DSA_new()) == NULL)
-+        return NULL;
-+    cb = BN_GENCB_new();
-+    if (cb == NULL)
-+        goto err;
-+
-+    BN_GENCB_set_old(cb, callback, cb_arg);
-+
-+    if (DSA_generate_parameters_ex(ret, bits, seed_in, seed_len,
-+                                   counter_ret, h_ret, cb)) {
-+        BN_GENCB_free(cb);
-+        return ret;
-+    }
-+    BN_GENCB_free(cb);
-+err:
-+    DSA_free(ret);
-+    return NULL;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_err.c
-new file mode 100644
-index 0000000..b8f0af4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_err.c
-@@ -0,0 +1,76 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSA,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSA,0,reason)
-+
-+static ERR_STRING_DATA DSA_str_functs[] = {
-+    {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"},
-+    {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"},
-+    {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN), "dsa_builtin_paramgen"},
-+    {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN2), "dsa_builtin_paramgen2"},
-+    {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"},
-+    {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"},
-+    {ERR_FUNC(DSA_F_DSA_METH_DUP), "DSA_meth_dup"},
-+    {ERR_FUNC(DSA_F_DSA_METH_NEW), "DSA_meth_new"},
-+    {ERR_FUNC(DSA_F_DSA_METH_SET1_NAME), "DSA_meth_set1_name"},
-+    {ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"},
-+    {ERR_FUNC(DSA_F_DSA_PARAM_DECODE), "dsa_param_decode"},
-+    {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
-+    {ERR_FUNC(DSA_F_DSA_PRIV_DECODE), "dsa_priv_decode"},
-+    {ERR_FUNC(DSA_F_DSA_PRIV_ENCODE), "dsa_priv_encode"},
-+    {ERR_FUNC(DSA_F_DSA_PUB_DECODE), "dsa_pub_decode"},
-+    {ERR_FUNC(DSA_F_DSA_PUB_ENCODE), "dsa_pub_encode"},
-+    {ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"},
-+    {ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"},
-+    {ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"},
-+    {ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE), "old_dsa_priv_decode"},
-+    {ERR_FUNC(DSA_F_PKEY_DSA_CTRL), "pkey_dsa_ctrl"},
-+    {ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN), "pkey_dsa_keygen"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA DSA_str_reasons[] = {
-+    {ERR_REASON(DSA_R_BAD_Q_VALUE), "bad q value"},
-+    {ERR_REASON(DSA_R_BN_DECODE_ERROR), "bn decode error"},
-+    {ERR_REASON(DSA_R_BN_ERROR), "bn error"},
-+    {ERR_REASON(DSA_R_DECODE_ERROR), "decode error"},
-+    {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE), "invalid digest type"},
-+    {ERR_REASON(DSA_R_INVALID_PARAMETERS), "invalid parameters"},
-+    {ERR_REASON(DSA_R_MISSING_PARAMETERS), "missing parameters"},
-+    {ERR_REASON(DSA_R_MODULUS_TOO_LARGE), "modulus too large"},
-+    {ERR_REASON(DSA_R_NO_PARAMETERS_SET), "no parameters set"},
-+    {ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"},
-+    {ERR_REASON(DSA_R_Q_NOT_PRIME), "q not prime"},
-+    {ERR_REASON(DSA_R_SEED_LEN_SMALL),
-+     "seed_len is less than the length of q"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_DSA_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(DSA_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, DSA_str_functs);
-+        ERR_load_strings(0, DSA_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_gen.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_gen.c
-new file mode 100644
-index 0000000..3efeab8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_gen.c
-@@ -0,0 +1,601 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
-+ * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB
-+ * 180-1)
-+ */
-+#define xxxHASH    EVP_sha1()
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "dsa_locl.h"
-+
-+int DSA_generate_parameters_ex(DSA *ret, int bits,
-+                               const unsigned char *seed_in, int seed_len,
-+                               int *counter_ret, unsigned long *h_ret,
-+                               BN_GENCB *cb)
-+{
-+    if (ret->meth->dsa_paramgen)
-+        return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
-+                                       counter_ret, h_ret, cb);
-+    else {
-+        const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1();
-+        size_t qbits = EVP_MD_size(evpmd) * 8;
-+
-+        return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
-+                                    seed_in, seed_len, NULL, counter_ret,
-+                                    h_ret, cb);
-+    }
-+}
-+
-+int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
-+                         const EVP_MD *evpmd, const unsigned char *seed_in,
-+                         size_t seed_len, unsigned char *seed_out,
-+                         int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
-+{
-+    int ok = 0;
-+    unsigned char seed[SHA256_DIGEST_LENGTH];
-+    unsigned char md[SHA256_DIGEST_LENGTH];
-+    unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
-+    BIGNUM *r0, *W, *X, *c, *test;
-+    BIGNUM *g = NULL, *q = NULL, *p = NULL;
-+    BN_MONT_CTX *mont = NULL;
-+    int i, k, n = 0, m = 0, qsize = qbits >> 3;
-+    int counter = 0;
-+    int r = 0;
-+    BN_CTX *ctx = NULL;
-+    unsigned int h = 2;
-+
-+    if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
-+        qsize != SHA256_DIGEST_LENGTH)
-+        /* invalid q size */
-+        return 0;
-+
-+    if (evpmd == NULL)
-+        /* use SHA1 as default */
-+        evpmd = EVP_sha1();
-+
-+    if (bits < 512)
-+        bits = 512;
-+
-+    bits = (bits + 63) / 64 * 64;
-+
-+    if (seed_in != NULL) {
-+        if (seed_len < (size_t)qsize) {
-+            DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_SEED_LEN_SMALL);
-+            return 0;
-+        }
-+        if (seed_len > (size_t)qsize) {
-+            /* Only consume as much seed as is expected. */
-+            seed_len = qsize;
-+        }
-+        memcpy(seed, seed_in, seed_len);
-+    }
-+
-+    if ((mont = BN_MONT_CTX_new()) == NULL)
-+        goto err;
-+
-+    if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+
-+    BN_CTX_start(ctx);
-+
-+    r0 = BN_CTX_get(ctx);
-+    g = BN_CTX_get(ctx);
-+    W = BN_CTX_get(ctx);
-+    q = BN_CTX_get(ctx);
-+    X = BN_CTX_get(ctx);
-+    c = BN_CTX_get(ctx);
-+    p = BN_CTX_get(ctx);
-+    test = BN_CTX_get(ctx);
-+
-+    if (test == NULL)
-+        goto err;
-+
-+    if (!BN_lshift(test, BN_value_one(), bits - 1))
-+        goto err;
-+
-+    for (;;) {
-+        for (;;) {              /* find q */
-+            int use_random_seed = (seed_in == NULL);
-+
-+            /* step 1 */
-+            if (!BN_GENCB_call(cb, 0, m++))
-+                goto err;
-+
-+            if (use_random_seed) {
-+                if (RAND_bytes(seed, qsize) <= 0)
-+                    goto err;
-+            } else {
-+                /* If we come back through, use random seed next time. */
-+                seed_in = NULL;
-+            }
-+            memcpy(buf, seed, qsize);
-+            memcpy(buf2, seed, qsize);
-+            /* precompute "SEED + 1" for step 7: */
-+            for (i = qsize - 1; i >= 0; i--) {
-+                buf[i]++;
-+                if (buf[i] != 0)
-+                    break;
-+            }
-+
-+            /* step 2 */
-+            if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
-+                goto err;
-+            if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
-+                goto err;
-+            for (i = 0; i < qsize; i++)
-+                md[i] ^= buf2[i];
-+
-+            /* step 3 */
-+            md[0] |= 0x80;
-+            md[qsize - 1] |= 0x01;
-+            if (!BN_bin2bn(md, qsize, q))
-+                goto err;
-+
-+            /* step 4 */
-+            r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
-+                                        use_random_seed, cb);
-+            if (r > 0)
-+                break;
-+            if (r != 0)
-+                goto err;
-+
-+            /* do a callback call */
-+            /* step 5 */
-+        }
-+
-+        if (!BN_GENCB_call(cb, 2, 0))
-+            goto err;
-+        if (!BN_GENCB_call(cb, 3, 0))
-+            goto err;
-+
-+        /* step 6 */
-+        counter = 0;
-+        /* "offset = 2" */
-+
-+        n = (bits - 1) / 160;
-+
-+        for (;;) {
-+            if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
-+                goto err;
-+
-+            /* step 7 */
-+            BN_zero(W);
-+            /* now 'buf' contains "SEED + offset - 1" */
-+            for (k = 0; k <= n; k++) {
-+                /*
-+                 * obtain "SEED + offset + k" by incrementing:
-+                 */
-+                for (i = qsize - 1; i >= 0; i--) {
-+                    buf[i]++;
-+                    if (buf[i] != 0)
-+                        break;
-+                }
-+
-+                if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
-+                    goto err;
-+
-+                /* step 8 */
-+                if (!BN_bin2bn(md, qsize, r0))
-+                    goto err;
-+                if (!BN_lshift(r0, r0, (qsize << 3) * k))
-+                    goto err;
-+                if (!BN_add(W, W, r0))
-+                    goto err;
-+            }
-+
-+            /* more of step 8 */
-+            if (!BN_mask_bits(W, bits - 1))
-+                goto err;
-+            if (!BN_copy(X, W))
-+                goto err;
-+            if (!BN_add(X, X, test))
-+                goto err;
-+
-+            /* step 9 */
-+            if (!BN_lshift1(r0, q))
-+                goto err;
-+            if (!BN_mod(c, X, r0, ctx))
-+                goto err;
-+            if (!BN_sub(r0, c, BN_value_one()))
-+                goto err;
-+            if (!BN_sub(p, X, r0))
-+                goto err;
-+
-+            /* step 10 */
-+            if (BN_cmp(p, test) >= 0) {
-+                /* step 11 */
-+                r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
-+                if (r > 0)
-+                    goto end;   /* found it */
-+                if (r != 0)
-+                    goto err;
-+            }
-+
-+            /* step 13 */
-+            counter++;
-+            /* "offset = offset + n + 1" */
-+
-+            /* step 14 */
-+            if (counter >= 4096)
-+                break;
-+        }
-+    }
-+ end:
-+    if (!BN_GENCB_call(cb, 2, 1))
-+        goto err;
-+
-+    /* We now need to generate g */
-+    /* Set r0=(p-1)/q */
-+    if (!BN_sub(test, p, BN_value_one()))
-+        goto err;
-+    if (!BN_div(r0, NULL, test, q, ctx))
-+        goto err;
-+
-+    if (!BN_set_word(test, h))
-+        goto err;
-+    if (!BN_MONT_CTX_set(mont, p, ctx))
-+        goto err;
-+
-+    for (;;) {
-+        /* g=test^r0%p */
-+        if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
-+            goto err;
-+        if (!BN_is_one(g))
-+            break;
-+        if (!BN_add(test, test, BN_value_one()))
-+            goto err;
-+        h++;
-+    }
-+
-+    if (!BN_GENCB_call(cb, 3, 1))
-+        goto err;
-+
-+    ok = 1;
-+ err:
-+    if (ok) {
-+        BN_free(ret->p);
-+        BN_free(ret->q);
-+        BN_free(ret->g);
-+        ret->p = BN_dup(p);
-+        ret->q = BN_dup(q);
-+        ret->g = BN_dup(g);
-+        if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
-+            ok = 0;
-+            goto err;
-+        }
-+        if (counter_ret != NULL)
-+            *counter_ret = counter;
-+        if (h_ret != NULL)
-+            *h_ret = h;
-+        if (seed_out)
-+            memcpy(seed_out, seed, qsize);
-+    }
-+    if (ctx)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    BN_MONT_CTX_free(mont);
-+    return ok;
-+}
-+
-+/*
-+ * This is a parameter generation algorithm for the DSA2 algorithm as
-+ * described in FIPS 186-3.
-+ */
-+
-+int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
-+                          const EVP_MD *evpmd, const unsigned char *seed_in,
-+                          size_t seed_len, int idx, unsigned char *seed_out,
-+                          int *counter_ret, unsigned long *h_ret,
-+                          BN_GENCB *cb)
-+{
-+    int ok = -1;
-+    unsigned char *seed = NULL, *seed_tmp = NULL;
-+    unsigned char md[EVP_MAX_MD_SIZE];
-+    int mdsize;
-+    BIGNUM *r0, *W, *X, *c, *test;
-+    BIGNUM *g = NULL, *q = NULL, *p = NULL;
-+    BN_MONT_CTX *mont = NULL;
-+    int i, k, n = 0, m = 0, qsize = N >> 3;
-+    int counter = 0;
-+    int r = 0;
-+    BN_CTX *ctx = NULL;
-+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-+    unsigned int h = 2;
-+
-+    if (mctx == NULL)
-+        goto err;
-+
-+    if (evpmd == NULL) {
-+        if (N == 160)
-+            evpmd = EVP_sha1();
-+        else if (N == 224)
-+            evpmd = EVP_sha224();
-+        else
-+            evpmd = EVP_sha256();
-+    }
-+
-+    mdsize = EVP_MD_size(evpmd);
-+    /* If unverifiable g generation only don't need seed */
-+    if (!ret->p || !ret->q || idx >= 0) {
-+        if (seed_len == 0)
-+            seed_len = mdsize;
-+
-+        seed = OPENSSL_malloc(seed_len);
-+
-+        if (seed_out)
-+            seed_tmp = seed_out;
-+        else
-+            seed_tmp = OPENSSL_malloc(seed_len);
-+
-+        if (seed == NULL || seed_tmp == NULL)
-+            goto err;
-+
-+        if (seed_in)
-+            memcpy(seed, seed_in, seed_len);
-+
-+    }
-+
-+    if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+
-+    if ((mont = BN_MONT_CTX_new()) == NULL)
-+        goto err;
-+
-+    BN_CTX_start(ctx);
-+    r0 = BN_CTX_get(ctx);
-+    g = BN_CTX_get(ctx);
-+    W = BN_CTX_get(ctx);
-+    X = BN_CTX_get(ctx);
-+    c = BN_CTX_get(ctx);
-+    test = BN_CTX_get(ctx);
-+    if (test == NULL)
-+        goto err;
-+
-+    /* if p, q already supplied generate g only */
-+    if (ret->p && ret->q) {
-+        p = ret->p;
-+        q = ret->q;
-+        if (idx >= 0)
-+            memcpy(seed_tmp, seed, seed_len);
-+        goto g_only;
-+    } else {
-+        p = BN_CTX_get(ctx);
-+        q = BN_CTX_get(ctx);
-+    }
-+
-+    if (!BN_lshift(test, BN_value_one(), L - 1))
-+        goto err;
-+    for (;;) {
-+        for (;;) {              /* find q */
-+            unsigned char *pmd;
-+            /* step 1 */
-+            if (!BN_GENCB_call(cb, 0, m++))
-+                goto err;
-+
-+            if (!seed_in) {
-+                if (RAND_bytes(seed, seed_len) <= 0)
-+                    goto err;
-+            }
-+            /* step 2 */
-+            if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
-+                goto err;
-+            /* Take least significant bits of md */
-+            if (mdsize > qsize)
-+                pmd = md + mdsize - qsize;
-+            else
-+                pmd = md;
-+
-+            if (mdsize < qsize)
-+                memset(md + mdsize, 0, qsize - mdsize);
-+
-+            /* step 3 */
-+            pmd[0] |= 0x80;
-+            pmd[qsize - 1] |= 0x01;
-+            if (!BN_bin2bn(pmd, qsize, q))
-+                goto err;
-+
-+            /* step 4 */
-+            r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
-+                                        seed_in ? 1 : 0, cb);
-+            if (r > 0)
-+                break;
-+            if (r != 0)
-+                goto err;
-+            /* Provided seed didn't produce a prime: error */
-+            if (seed_in) {
-+                ok = 0;
-+                DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME);
-+                goto err;
-+            }
-+
-+            /* do a callback call */
-+            /* step 5 */
-+        }
-+        /* Copy seed to seed_out before we mess with it */
-+        if (seed_out)
-+            memcpy(seed_out, seed, seed_len);
-+
-+        if (!BN_GENCB_call(cb, 2, 0))
-+            goto err;
-+        if (!BN_GENCB_call(cb, 3, 0))
-+            goto err;
-+
-+        /* step 6 */
-+        counter = 0;
-+        /* "offset = 1" */
-+
-+        n = (L - 1) / (mdsize << 3);
-+
-+        for (;;) {
-+            if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
-+                goto err;
-+
-+            /* step 7 */
-+            BN_zero(W);
-+            /* now 'buf' contains "SEED + offset - 1" */
-+            for (k = 0; k <= n; k++) {
-+                /*
-+                 * obtain "SEED + offset + k" by incrementing:
-+                 */
-+                for (i = seed_len - 1; i >= 0; i--) {
-+                    seed[i]++;
-+                    if (seed[i] != 0)
-+                        break;
-+                }
-+
-+                if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
-+                    goto err;
-+
-+                /* step 8 */
-+                if (!BN_bin2bn(md, mdsize, r0))
-+                    goto err;
-+                if (!BN_lshift(r0, r0, (mdsize << 3) * k))
-+                    goto err;
-+                if (!BN_add(W, W, r0))
-+                    goto err;
-+            }
-+
-+            /* more of step 8 */
-+            if (!BN_mask_bits(W, L - 1))
-+                goto err;
-+            if (!BN_copy(X, W))
-+                goto err;
-+            if (!BN_add(X, X, test))
-+                goto err;
-+
-+            /* step 9 */
-+            if (!BN_lshift1(r0, q))
-+                goto err;
-+            if (!BN_mod(c, X, r0, ctx))
-+                goto err;
-+            if (!BN_sub(r0, c, BN_value_one()))
-+                goto err;
-+            if (!BN_sub(p, X, r0))
-+                goto err;
-+
-+            /* step 10 */
-+            if (BN_cmp(p, test) >= 0) {
-+                /* step 11 */
-+                r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
-+                if (r > 0)
-+                    goto end;   /* found it */
-+                if (r != 0)
-+                    goto err;
-+            }
-+
-+            /* step 13 */
-+            counter++;
-+            /* "offset = offset + n + 1" */
-+
-+            /* step 14 */
-+            if (counter >= (int)(4 * L))
-+                break;
-+        }
-+        if (seed_in) {
-+            ok = 0;
-+            DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
-+            goto err;
-+        }
-+    }
-+ end:
-+    if (!BN_GENCB_call(cb, 2, 1))
-+        goto err;
-+
-+ g_only:
-+
-+    /* We now need to generate g */
-+    /* Set r0=(p-1)/q */
-+    if (!BN_sub(test, p, BN_value_one()))
-+        goto err;
-+    if (!BN_div(r0, NULL, test, q, ctx))
-+        goto err;
-+
-+    if (idx < 0) {
-+        if (!BN_set_word(test, h))
-+            goto err;
-+    } else
-+        h = 1;
-+    if (!BN_MONT_CTX_set(mont, p, ctx))
-+        goto err;
-+
-+    for (;;) {
-+        static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e };
-+        if (idx >= 0) {
-+            md[0] = idx & 0xff;
-+            md[1] = (h >> 8) & 0xff;
-+            md[2] = h & 0xff;
-+            if (!EVP_DigestInit_ex(mctx, evpmd, NULL))
-+                goto err;
-+            if (!EVP_DigestUpdate(mctx, seed_tmp, seed_len))
-+                goto err;
-+            if (!EVP_DigestUpdate(mctx, ggen, sizeof(ggen)))
-+                goto err;
-+            if (!EVP_DigestUpdate(mctx, md, 3))
-+                goto err;
-+            if (!EVP_DigestFinal_ex(mctx, md, NULL))
-+                goto err;
-+            if (!BN_bin2bn(md, mdsize, test))
-+                goto err;
-+        }
-+        /* g=test^r0%p */
-+        if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
-+            goto err;
-+        if (!BN_is_one(g))
-+            break;
-+        if (idx < 0 && !BN_add(test, test, BN_value_one()))
-+            goto err;
-+        h++;
-+        if (idx >= 0 && h > 0xffff)
-+            goto err;
-+    }
-+
-+    if (!BN_GENCB_call(cb, 3, 1))
-+        goto err;
-+
-+    ok = 1;
-+ err:
-+    if (ok == 1) {
-+        if (p != ret->p) {
-+            BN_free(ret->p);
-+            ret->p = BN_dup(p);
-+        }
-+        if (q != ret->q) {
-+            BN_free(ret->q);
-+            ret->q = BN_dup(q);
-+        }
-+        BN_free(ret->g);
-+        ret->g = BN_dup(g);
-+        if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
-+            ok = -1;
-+            goto err;
-+        }
-+        if (counter_ret != NULL)
-+            *counter_ret = counter;
-+        if (h_ret != NULL)
-+            *h_ret = h;
-+    }
-+    OPENSSL_free(seed);
-+    if (seed_out != seed_tmp)
-+        OPENSSL_free(seed_tmp);
-+    if (ctx)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    BN_MONT_CTX_free(mont);
-+    EVP_MD_CTX_free(mctx);
-+    return ok;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_key.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_key.c
-new file mode 100644
-index 0000000..31442b1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_key.c
-@@ -0,0 +1,77 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "dsa_locl.h"
-+
-+static int dsa_builtin_keygen(DSA *dsa);
-+
-+int DSA_generate_key(DSA *dsa)
-+{
-+    if (dsa->meth->dsa_keygen)
-+        return dsa->meth->dsa_keygen(dsa);
-+    return dsa_builtin_keygen(dsa);
-+}
-+
-+static int dsa_builtin_keygen(DSA *dsa)
-+{
-+    int ok = 0;
-+    BN_CTX *ctx = NULL;
-+    BIGNUM *pub_key = NULL, *priv_key = NULL;
-+
-+    if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+
-+    if (dsa->priv_key == NULL) {
-+        if ((priv_key = BN_secure_new()) == NULL)
-+            goto err;
-+    } else
-+        priv_key = dsa->priv_key;
-+
-+    do
-+        if (!BN_rand_range(priv_key, dsa->q))
-+            goto err;
-+    while (BN_is_zero(priv_key)) ;
-+
-+    if (dsa->pub_key == NULL) {
-+        if ((pub_key = BN_new()) == NULL)
-+            goto err;
-+    } else
-+        pub_key = dsa->pub_key;
-+
-+    {
-+        BIGNUM *prk = BN_new();
-+
-+        if (prk == NULL)
-+            goto err;
-+        BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
-+
-+        if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) {
-+            BN_free(prk);
-+            goto err;
-+        }
-+        /* We MUST free prk before any further use of priv_key */
-+        BN_free(prk);
-+    }
-+
-+    dsa->priv_key = priv_key;
-+    dsa->pub_key = pub_key;
-+    ok = 1;
-+
-+ err:
-+    if (pub_key != dsa->pub_key)
-+        BN_free(pub_key);
-+    if (priv_key != dsa->priv_key)
-+        BN_free(priv_key);
-+    BN_CTX_free(ctx);
-+    return (ok);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_lib.c
-new file mode 100644
-index 0000000..42324c7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_lib.c
-@@ -0,0 +1,346 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Original version from Steven Schoch  */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "dsa_locl.h"
-+#include 
-+#include 
-+#include 
-+
-+static const DSA_METHOD *default_DSA_method = NULL;
-+
-+void DSA_set_default_method(const DSA_METHOD *meth)
-+{
-+    default_DSA_method = meth;
-+}
-+
-+const DSA_METHOD *DSA_get_default_method(void)
-+{
-+    if (!default_DSA_method)
-+        default_DSA_method = DSA_OpenSSL();
-+    return default_DSA_method;
-+}
-+
-+DSA *DSA_new(void)
-+{
-+    return DSA_new_method(NULL);
-+}
-+
-+int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
-+{
-+    /*
-+     * NB: The caller is specifically setting a method, so it's not up to us
-+     * to deal with which ENGINE it comes from.
-+     */
-+    const DSA_METHOD *mtmp;
-+    mtmp = dsa->meth;
-+    if (mtmp->finish)
-+        mtmp->finish(dsa);
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(dsa->engine);
-+    dsa->engine = NULL;
-+#endif
-+    dsa->meth = meth;
-+    if (meth->init)
-+        meth->init(dsa);
-+    return 1;
-+}
-+
-+const DSA_METHOD *DSA_get_method(DSA *d)
-+{
-+    return d->meth;
-+}
-+
-+DSA *DSA_new_method(ENGINE *engine)
-+{
-+    DSA *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->references = 1;
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+
-+    ret->meth = DSA_get_default_method();
-+#ifndef OPENSSL_NO_ENGINE
-+    ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */
-+    if (engine) {
-+        if (!ENGINE_init(engine)) {
-+            DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
-+            goto err;
-+        }
-+        ret->engine = engine;
-+    } else
-+        ret->engine = ENGINE_get_default_DSA();
-+    if (ret->engine) {
-+        ret->meth = ENGINE_get_DSA(ret->engine);
-+        if (ret->meth == NULL) {
-+            DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
-+            goto err;
-+        }
-+    }
-+#endif
-+
-+    ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
-+
-+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data))
-+        goto err;
-+
-+    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
-+        DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL);
-+err:
-+        DSA_free(ret);
-+        ret = NULL;
-+    }
-+
-+    return ret;
-+}
-+
-+void DSA_free(DSA *r)
-+{
-+    int i;
-+
-+    if (r == NULL)
-+        return;
-+
-+    CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
-+    REF_PRINT_COUNT("DSA", r);
-+    if (i > 0)
-+        return;
-+    REF_ASSERT_ISNT(i < 0);
-+
-+    if (r->meth->finish)
-+        r->meth->finish(r);
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(r->engine);
-+#endif
-+
-+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
-+
-+    CRYPTO_THREAD_lock_free(r->lock);
-+
-+    BN_clear_free(r->p);
-+    BN_clear_free(r->q);
-+    BN_clear_free(r->g);
-+    BN_clear_free(r->pub_key);
-+    BN_clear_free(r->priv_key);
-+    OPENSSL_free(r);
-+}
-+
-+int DSA_up_ref(DSA *r)
-+{
-+    int i;
-+
-+    if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
-+        return 0;
-+
-+    REF_PRINT_COUNT("DSA", r);
-+    REF_ASSERT_ISNT(i < 2);
-+    return ((i > 1) ? 1 : 0);
-+}
-+
-+int DSA_size(const DSA *r)
-+{
-+    int ret, i;
-+    ASN1_INTEGER bs;
-+    unsigned char buf[4];       /* 4 bytes looks really small. However,
-+                                 * i2d_ASN1_INTEGER() will not look beyond
-+                                 * the first byte, as long as the second
-+                                 * parameter is NULL. */
-+
-+    i = BN_num_bits(r->q);
-+    bs.length = (i + 7) / 8;
-+    bs.data = buf;
-+    bs.type = V_ASN1_INTEGER;
-+    /* If the top bit is set the asn1 encoding is 1 larger. */
-+    buf[0] = 0xff;
-+
-+    i = i2d_ASN1_INTEGER(&bs, NULL);
-+    i += i;                     /* r and s */
-+    ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
-+    return (ret);
-+}
-+
-+int DSA_set_ex_data(DSA *d, int idx, void *arg)
-+{
-+    return (CRYPTO_set_ex_data(&d->ex_data, idx, arg));
-+}
-+
-+void *DSA_get_ex_data(DSA *d, int idx)
-+{
-+    return (CRYPTO_get_ex_data(&d->ex_data, idx));
-+}
-+
-+int DSA_security_bits(const DSA *d)
-+{
-+    if (d->p && d->q)
-+        return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
-+    return -1;
-+}
-+
-+#ifndef OPENSSL_NO_DH
-+DH *DSA_dup_DH(const DSA *r)
-+{
-+    /*
-+     * DSA has p, q, g, optional pub_key, optional priv_key. DH has p,
-+     * optional length, g, optional pub_key, optional priv_key, optional q.
-+     */
-+
-+    DH *ret = NULL;
-+    BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL;
-+
-+    if (r == NULL)
-+        goto err;
-+    ret = DH_new();
-+    if (ret == NULL)
-+        goto err;
-+    if (r->p != NULL || r->g != NULL || r->q != NULL) {
-+        if (r->p == NULL || r->g == NULL || r->q == NULL) {
-+            /* Shouldn't happen */
-+            goto err;
-+        }
-+        p = BN_dup(r->p);
-+        g = BN_dup(r->g);
-+        q = BN_dup(r->q);
-+        if (p == NULL || g == NULL || q == NULL || !DH_set0_pqg(ret, p, q, g))
-+            goto err;
-+        p = g = q = NULL;
-+    }
-+
-+    if (r->pub_key != NULL) {
-+        pub_key = BN_dup(r->pub_key);
-+        if (pub_key == NULL)
-+            goto err;
-+        if (r->priv_key != NULL) {
-+            priv_key = BN_dup(r->priv_key);
-+            if (priv_key == NULL)
-+                goto err;
-+        }
-+        if (!DH_set0_key(ret, pub_key, priv_key))
-+            goto err;
-+    } else if (r->priv_key != NULL) {
-+        /* Shouldn't happen */
-+        goto err;
-+    }
-+
-+    return ret;
-+
-+ err:
-+    BN_free(p);
-+    BN_free(g);
-+    BN_free(q);
-+    BN_free(pub_key);
-+    BN_free(priv_key);
-+    DH_free(ret);
-+    return NULL;
-+}
-+#endif
-+
-+void DSA_get0_pqg(const DSA *d,
-+                  const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
-+{
-+    if (p != NULL)
-+        *p = d->p;
-+    if (q != NULL)
-+        *q = d->q;
-+    if (g != NULL)
-+        *g = d->g;
-+}
-+
-+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
-+{
-+    /* If the fields p, q and g in d are NULL, the corresponding input
-+     * parameters MUST be non-NULL.
-+     */
-+    if ((d->p == NULL && p == NULL)
-+        || (d->q == NULL && q == NULL)
-+        || (d->g == NULL && g == NULL))
-+        return 0;
-+
-+    if (p != NULL) {
-+        BN_free(d->p);
-+        d->p = p;
-+    }
-+    if (q != NULL) {
-+        BN_free(d->q);
-+        d->q = q;
-+    }
-+    if (g != NULL) {
-+        BN_free(d->g);
-+        d->g = g;
-+    }
-+
-+    return 1;
-+}
-+
-+void DSA_get0_key(const DSA *d,
-+                  const BIGNUM **pub_key, const BIGNUM **priv_key)
-+{
-+    if (pub_key != NULL)
-+        *pub_key = d->pub_key;
-+    if (priv_key != NULL)
-+        *priv_key = d->priv_key;
-+}
-+
-+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
-+{
-+    /* If the field pub_key in d is NULL, the corresponding input
-+     * parameters MUST be non-NULL.  The priv_key field may
-+     * be left NULL.
-+     */
-+    if (d->pub_key == NULL && pub_key == NULL)
-+        return 0;
-+
-+    if (pub_key != NULL) {
-+        BN_free(d->pub_key);
-+        d->pub_key = pub_key;
-+    }
-+    if (priv_key != NULL) {
-+        BN_free(d->priv_key);
-+        d->priv_key = priv_key;
-+    }
-+
-+    return 1;
-+}
-+
-+void DSA_clear_flags(DSA *d, int flags)
-+{
-+    d->flags &= ~flags;
-+}
-+
-+int DSA_test_flags(const DSA *d, int flags)
-+{
-+    return d->flags & flags;
-+}
-+
-+void DSA_set_flags(DSA *d, int flags)
-+{
-+    d->flags |= flags;
-+}
-+
-+ENGINE *DSA_get0_engine(DSA *d)
-+{
-+    return d->engine;
-+}
-+
-+int DSA_bits(const DSA *dsa)
-+{
-+    return BN_num_bits(dsa->p);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_locl.h
-new file mode 100644
-index 0000000..9021fce
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_locl.h
-@@ -0,0 +1,76 @@
-+/*
-+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+struct dsa_st {
-+    /*
-+     * This first variable is used to pick up errors where a DSA is passed
-+     * instead of of a EVP_PKEY
-+     */
-+    int pad;
-+    long version;
-+    BIGNUM *p;
-+    BIGNUM *q;                  /* == 20 */
-+    BIGNUM *g;
-+    BIGNUM *pub_key;            /* y public key */
-+    BIGNUM *priv_key;           /* x private key */
-+    int flags;
-+    /* Normally used to cache montgomery values */
-+    BN_MONT_CTX *method_mont_p;
-+    int references;
-+    CRYPTO_EX_DATA ex_data;
-+    const DSA_METHOD *meth;
-+    /* functional reference if 'meth' is ENGINE-provided */
-+    ENGINE *engine;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+struct DSA_SIG_st {
-+    BIGNUM *r;
-+    BIGNUM *s;
-+};
-+
-+struct dsa_method {
-+    char *name;
-+    DSA_SIG *(*dsa_do_sign) (const unsigned char *dgst, int dlen, DSA *dsa);
-+    int (*dsa_sign_setup) (DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
-+                           BIGNUM **rp);
-+    int (*dsa_do_verify) (const unsigned char *dgst, int dgst_len,
-+                          DSA_SIG *sig, DSA *dsa);
-+    int (*dsa_mod_exp) (DSA *dsa, BIGNUM *rr, const BIGNUM *a1,
-+                        const BIGNUM *p1, const BIGNUM *a2, const BIGNUM *p2,
-+                        const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont);
-+    /* Can be null */
-+    int (*bn_mod_exp) (DSA *dsa, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-+                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
-+    int (*init) (DSA *dsa);
-+    int (*finish) (DSA *dsa);
-+    int flags;
-+    void *app_data;
-+    /* If this is non-NULL, it is used to generate DSA parameters */
-+    int (*dsa_paramgen) (DSA *dsa, int bits,
-+                         const unsigned char *seed, int seed_len,
-+                         int *counter_ret, unsigned long *h_ret,
-+                         BN_GENCB *cb);
-+    /* If this is non-NULL, it is used to generate DSA keys */
-+    int (*dsa_keygen) (DSA *dsa);
-+};
-+
-+int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
-+                         const EVP_MD *evpmd, const unsigned char *seed_in,
-+                         size_t seed_len, unsigned char *seed_out,
-+                         int *counter_ret, unsigned long *h_ret,
-+                         BN_GENCB *cb);
-+
-+int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
-+                          const EVP_MD *evpmd, const unsigned char *seed_in,
-+                          size_t seed_len, int idx, unsigned char *seed_out,
-+                          int *counter_ret, unsigned long *h_ret,
-+                          BN_GENCB *cb);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_meth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_meth.c
-new file mode 100644
-index 0000000..f0188f2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_meth.c
-@@ -0,0 +1,224 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Licensed under the OpenSSL licenses, (the "License");
-+ * you may not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ * https://www.openssl.org/source/license.html
-+ * or in the file LICENSE in the source distribution.
-+ */
-+
-+#include "dsa_locl.h"
-+#include 
-+#include 
-+
-+DSA_METHOD *DSA_meth_new(const char *name, int flags)
-+{
-+    DSA_METHOD *dsam = OPENSSL_zalloc(sizeof(*dsam));
-+
-+    if (dsam != NULL) {
-+        dsam->flags = flags;
-+
-+        dsam->name = OPENSSL_strdup(name);
-+        if (dsam->name != NULL)
-+            return dsam;
-+
-+        OPENSSL_free(dsam);
-+    }
-+
-+    DSAerr(DSA_F_DSA_METH_NEW, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+void DSA_meth_free(DSA_METHOD *dsam)
-+{
-+    if (dsam != NULL) {
-+        OPENSSL_free(dsam->name);
-+        OPENSSL_free(dsam);
-+    }
-+}
-+
-+DSA_METHOD *DSA_meth_dup(const DSA_METHOD *dsam)
-+{
-+    DSA_METHOD *ret = OPENSSL_malloc(sizeof(*ret));
-+
-+    if (ret != NULL) {
-+        memcpy(ret, dsam, sizeof(*dsam));
-+
-+        ret->name = OPENSSL_strdup(dsam->name);
-+        if (ret->name != NULL)
-+            return ret;
-+
-+        OPENSSL_free(ret);
-+    }
-+
-+    DSAerr(DSA_F_DSA_METH_DUP, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+const char *DSA_meth_get0_name(const DSA_METHOD *dsam)
-+{
-+    return dsam->name;
-+}
-+
-+int DSA_meth_set1_name(DSA_METHOD *dsam, const char *name)
-+{
-+    char *tmpname = OPENSSL_strdup(name);
-+
-+    if (tmpname == NULL) {
-+        DSAerr(DSA_F_DSA_METH_SET1_NAME, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    OPENSSL_free(dsam->name);
-+    dsam->name = tmpname;
-+
-+    return 1;
-+}
-+
-+int DSA_meth_get_flags(DSA_METHOD *dsam)
-+{
-+    return dsam->flags;
-+}
-+
-+int DSA_meth_set_flags(DSA_METHOD *dsam, int flags)
-+{
-+    dsam->flags = flags;
-+    return 1;
-+}
-+
-+void *DSA_meth_get0_app_data(const DSA_METHOD *dsam)
-+{
-+    return dsam->app_data;
-+}
-+
-+int DSA_meth_set0_app_data(DSA_METHOD *dsam, void *app_data)
-+{
-+    dsam->app_data = app_data;
-+    return 1;
-+}
-+
-+DSA_SIG *(*DSA_meth_get_sign(const DSA_METHOD *dsam))
-+        (const unsigned char *, int, DSA *)
-+{
-+    return dsam->dsa_do_sign;
-+}
-+
-+int DSA_meth_set_sign(DSA_METHOD *dsam,
-+                       DSA_SIG *(*sign) (const unsigned char *, int, DSA *))
-+{
-+    dsam->dsa_do_sign = sign;
-+    return 1;
-+}
-+
-+int (*DSA_meth_get_sign_setup(const DSA_METHOD *dsam))
-+        (DSA *, BN_CTX *, BIGNUM **, BIGNUM **)
-+{
-+    return dsam->dsa_sign_setup;
-+}
-+
-+int DSA_meth_set_sign_setup(DSA_METHOD *dsam,
-+        int (*sign_setup) (DSA *, BN_CTX *, BIGNUM **, BIGNUM **))
-+{
-+    dsam->dsa_sign_setup = sign_setup;
-+    return 1;
-+}
-+
-+int (*DSA_meth_get_verify(const DSA_METHOD *dsam))
-+        (const unsigned char *, int , DSA_SIG *, DSA *)
-+{
-+    return dsam->dsa_do_verify;
-+}
-+
-+int DSA_meth_set_verify(DSA_METHOD *dsam,
-+    int (*verify) (const unsigned char *, int, DSA_SIG *, DSA *))
-+{
-+    dsam->dsa_do_verify = verify;
-+    return 1;
-+}
-+
-+int (*DSA_meth_get_mod_exp(const DSA_METHOD *dsam))
-+        (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
-+         const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *)
-+{
-+    return dsam->dsa_mod_exp;
-+}
-+
-+int DSA_meth_set_mod_exp(DSA_METHOD *dsam,
-+    int (*mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *,
-+                    const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *,
-+                    BN_MONT_CTX *))
-+{
-+    dsam->dsa_mod_exp = mod_exp;
-+    return 1;
-+}
-+
-+int (*DSA_meth_get_bn_mod_exp(const DSA_METHOD *dsam))
-+    (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *,
-+     BN_MONT_CTX *)
-+{
-+    return dsam->bn_mod_exp;
-+}
-+
-+int DSA_meth_set_bn_mod_exp(DSA_METHOD *dsam,
-+    int (*bn_mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *,
-+                       const BIGNUM *, BN_CTX *, BN_MONT_CTX *))
-+{
-+    dsam->bn_mod_exp = bn_mod_exp;
-+    return 1;
-+}
-+
-+int (*DSA_meth_get_init(const DSA_METHOD *dsam))(DSA *)
-+{
-+    return dsam->init;
-+}
-+
-+int DSA_meth_set_init(DSA_METHOD *dsam, int (*init)(DSA *))
-+{
-+    dsam->init = init;
-+    return 1;
-+}
-+
-+int (*DSA_meth_get_finish(const DSA_METHOD *dsam)) (DSA *)
-+{
-+    return dsam->finish;
-+}
-+
-+int DSA_meth_set_finish(DSA_METHOD *dsam, int (*finish) (DSA *))
-+{
-+    dsam->finish = finish;
-+    return 1;
-+}
-+
-+int (*DSA_meth_get_paramgen(const DSA_METHOD *dsam))
-+        (DSA *, int, const unsigned char *, int, int *, unsigned long *,
-+         BN_GENCB *)
-+{
-+    return dsam->dsa_paramgen;
-+}
-+
-+int DSA_meth_set_paramgen(DSA_METHOD *dsam,
-+        int (*paramgen) (DSA *, int, const unsigned char *, int, int *,
-+                         unsigned long *, BN_GENCB *))
-+{
-+    dsam->dsa_paramgen = paramgen;
-+    return 1;
-+}
-+
-+int (*DSA_meth_get_keygen(const DSA_METHOD *dsam)) (DSA *)
-+{
-+    return dsam->dsa_keygen;
-+}
-+
-+int DSA_meth_set_keygen(DSA_METHOD *dsam, int (*keygen) (DSA *))
-+{
-+    dsam->dsa_keygen = keygen;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_ossl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_ossl.c
-new file mode 100644
-index 0000000..f9f6a13
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_ossl.c
-@@ -0,0 +1,338 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Original version from Steven Schoch  */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "dsa_locl.h"
-+#include 
-+
-+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
-+static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
-+                                    BIGNUM **rp);
-+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
-+                          BIGNUM **rp, const unsigned char *dgst, int dlen);
-+static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
-+                         DSA_SIG *sig, DSA *dsa);
-+static int dsa_init(DSA *dsa);
-+static int dsa_finish(DSA *dsa);
-+
-+static DSA_METHOD openssl_dsa_meth = {
-+    "OpenSSL DSA method",
-+    dsa_do_sign,
-+    dsa_sign_setup_no_digest,
-+    dsa_do_verify,
-+    NULL,                       /* dsa_mod_exp, */
-+    NULL,                       /* dsa_bn_mod_exp, */
-+    dsa_init,
-+    dsa_finish,
-+    DSA_FLAG_FIPS_METHOD,
-+    NULL,
-+    NULL,
-+    NULL
-+};
-+
-+const DSA_METHOD *DSA_OpenSSL(void)
-+{
-+    return &openssl_dsa_meth;
-+}
-+
-+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
-+{
-+    BIGNUM *kinv = NULL;
-+    BIGNUM *m;
-+    BIGNUM *xr;
-+    BN_CTX *ctx = NULL;
-+    int reason = ERR_R_BN_LIB;
-+    DSA_SIG *ret = NULL;
-+    int rv = 0;
-+
-+    m = BN_new();
-+    xr = BN_new();
-+    if (m == NULL || xr == NULL)
-+        goto err;
-+
-+    if (!dsa->p || !dsa->q || !dsa->g) {
-+        reason = DSA_R_MISSING_PARAMETERS;
-+        goto err;
-+    }
-+
-+    ret = DSA_SIG_new();
-+    if (ret == NULL)
-+        goto err;
-+    ret->r = BN_new();
-+    ret->s = BN_new();
-+    if (ret->r == NULL || ret->s == NULL)
-+        goto err;
-+
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+ redo:
-+    if (!dsa_sign_setup(dsa, ctx, &kinv, &ret->r, dgst, dlen))
-+        goto err;
-+
-+    if (dlen > BN_num_bytes(dsa->q))
-+        /*
-+         * if the digest length is greater than the size of q use the
-+         * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3,
-+         * 4.2
-+         */
-+        dlen = BN_num_bytes(dsa->q);
-+    if (BN_bin2bn(dgst, dlen, m) == NULL)
-+        goto err;
-+
-+    /* Compute  s = inv(k) (m + xr) mod q */
-+    if (!BN_mod_mul(xr, dsa->priv_key, ret->r, dsa->q, ctx))
-+        goto err;               /* s = xr */
-+    if (!BN_add(ret->s, xr, m))
-+        goto err;               /* s = m + xr */
-+    if (BN_cmp(ret->s, dsa->q) > 0)
-+        if (!BN_sub(ret->s, ret->s, dsa->q))
-+            goto err;
-+    if (!BN_mod_mul(ret->s, ret->s, kinv, dsa->q, ctx))
-+        goto err;
-+
-+    /*
-+     * Redo if r or s is zero as required by FIPS 186-3: this is very
-+     * unlikely.
-+     */
-+    if (BN_is_zero(ret->r) || BN_is_zero(ret->s))
-+        goto redo;
-+
-+    rv = 1;
-+
-+ err:
-+    if (rv == 0) {
-+        DSAerr(DSA_F_DSA_DO_SIGN, reason);
-+        DSA_SIG_free(ret);
-+        ret = NULL;
-+    }
-+    BN_CTX_free(ctx);
-+    BN_clear_free(m);
-+    BN_clear_free(xr);
-+    BN_clear_free(kinv);
-+    return ret;
-+}
-+
-+static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in,
-+                                    BIGNUM **kinvp, BIGNUM **rp)
-+{
-+    return dsa_sign_setup(dsa, ctx_in, kinvp, rp, NULL, 0);
-+}
-+
-+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
-+                          BIGNUM **kinvp, BIGNUM **rp,
-+                          const unsigned char *dgst, int dlen)
-+{
-+    BN_CTX *ctx = NULL;
-+    BIGNUM *k, *kinv = NULL, *r = *rp;
-+    int ret = 0;
-+
-+    if (!dsa->p || !dsa->q || !dsa->g) {
-+        DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);
-+        return 0;
-+    }
-+
-+    k = BN_new();
-+    if (k == NULL)
-+        goto err;
-+
-+    if (ctx_in == NULL) {
-+        if ((ctx = BN_CTX_new()) == NULL)
-+            goto err;
-+    } else
-+        ctx = ctx_in;
-+
-+    /* Get random k */
-+    do {
-+        if (dgst != NULL) {
-+            /*
-+             * We calculate k from SHA512(private_key + H(message) + random).
-+             * This protects the private key from a weak PRNG.
-+             */
-+            if (!BN_generate_dsa_nonce(k, dsa->q, dsa->priv_key, dgst,
-+                                       dlen, ctx))
-+                goto err;
-+        } else if (!BN_rand_range(k, dsa->q))
-+            goto err;
-+    } while (BN_is_zero(k));
-+
-+    BN_set_flags(k, BN_FLG_CONSTTIME);
-+
-+    if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
-+        if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
-+                                    dsa->lock, dsa->p, ctx))
-+            goto err;
-+    }
-+
-+    /* Compute r = (g^k mod p) mod q */
-+
-+    /*
-+     * We do not want timing information to leak the length of k, so we
-+     * compute g^k using an equivalent exponent of fixed length. (This
-+     * is a kludge that we need because the BN_mod_exp_mont() does not
-+     * let us specify the desired timing behaviour.)
-+     */
-+
-+    if (!BN_add(k, k, dsa->q))
-+        goto err;
-+    if (BN_num_bits(k) <= BN_num_bits(dsa->q)) {
-+        if (!BN_add(k, k, dsa->q))
-+            goto err;
-+    }
-+
-+    if ((dsa)->meth->bn_mod_exp != NULL) {
-+            if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx,
-+                                       dsa->method_mont_p))
-+                goto err;
-+    } else {
-+            if (!BN_mod_exp_mont(r, dsa->g, k, dsa->p, ctx, dsa->method_mont_p))
-+                goto err;
-+    }
-+
-+    if (!BN_mod(r, r, dsa->q, ctx))
-+        goto err;
-+
-+    /* Compute  part of 's = inv(k) (m + xr) mod q' */
-+    if ((kinv = BN_mod_inverse(NULL, k, dsa->q, ctx)) == NULL)
-+        goto err;
-+
-+    BN_clear_free(*kinvp);
-+    *kinvp = kinv;
-+    kinv = NULL;
-+    ret = 1;
-+ err:
-+    if (!ret)
-+        DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB);
-+    if (ctx != ctx_in)
-+        BN_CTX_free(ctx);
-+    BN_clear_free(k);
-+    return ret;
-+}
-+
-+static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
-+                         DSA_SIG *sig, DSA *dsa)
-+{
-+    BN_CTX *ctx;
-+    BIGNUM *u1, *u2, *t1;
-+    BN_MONT_CTX *mont = NULL;
-+    const BIGNUM *r, *s;
-+    int ret = -1, i;
-+    if (!dsa->p || !dsa->q || !dsa->g) {
-+        DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS);
-+        return -1;
-+    }
-+
-+    i = BN_num_bits(dsa->q);
-+    /* fips 186-3 allows only different sizes for q */
-+    if (i != 160 && i != 224 && i != 256) {
-+        DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE);
-+        return -1;
-+    }
-+
-+    if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
-+        DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE);
-+        return -1;
-+    }
-+    u1 = BN_new();
-+    u2 = BN_new();
-+    t1 = BN_new();
-+    ctx = BN_CTX_new();
-+    if (u1 == NULL || u2 == NULL || t1 == NULL || ctx == NULL)
-+        goto err;
-+
-+    DSA_SIG_get0(sig, &r, &s);
-+
-+    if (BN_is_zero(r) || BN_is_negative(r) ||
-+        BN_ucmp(r, dsa->q) >= 0) {
-+        ret = 0;
-+        goto err;
-+    }
-+    if (BN_is_zero(s) || BN_is_negative(s) ||
-+        BN_ucmp(s, dsa->q) >= 0) {
-+        ret = 0;
-+        goto err;
-+    }
-+
-+    /*
-+     * Calculate W = inv(S) mod Q save W in u2
-+     */
-+    if ((BN_mod_inverse(u2, s, dsa->q, ctx)) == NULL)
-+        goto err;
-+
-+    /* save M in u1 */
-+    if (dgst_len > (i >> 3))
-+        /*
-+         * if the digest length is greater than the size of q use the
-+         * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3,
-+         * 4.2
-+         */
-+        dgst_len = (i >> 3);
-+    if (BN_bin2bn(dgst, dgst_len, u1) == NULL)
-+        goto err;
-+
-+    /* u1 = M * w mod q */
-+    if (!BN_mod_mul(u1, u1, u2, dsa->q, ctx))
-+        goto err;
-+
-+    /* u2 = r * w mod q */
-+    if (!BN_mod_mul(u2, r, u2, dsa->q, ctx))
-+        goto err;
-+
-+    if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
-+        mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
-+                                      dsa->lock, dsa->p, ctx);
-+        if (!mont)
-+            goto err;
-+    }
-+
-+    if (dsa->meth->dsa_mod_exp != NULL) {
-+        if (!dsa->meth->dsa_mod_exp(dsa, t1, dsa->g, u1, dsa->pub_key, u2,
-+                                    dsa->p, ctx, mont))
-+            goto err;
-+    } else {
-+        if (!BN_mod_exp2_mont(t1, dsa->g, u1, dsa->pub_key, u2, dsa->p, ctx,
-+                              mont))
-+            goto err;
-+    }
-+
-+    /* let u1 = u1 mod q */
-+    if (!BN_mod(u1, t1, dsa->q, ctx))
-+        goto err;
-+
-+    /*
-+     * V is now in u1.  If the signature is correct, it will be equal to R.
-+     */
-+    ret = (BN_ucmp(u1, r) == 0);
-+
-+ err:
-+    if (ret < 0)
-+        DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_BN_LIB);
-+    BN_CTX_free(ctx);
-+    BN_free(u1);
-+    BN_free(u2);
-+    BN_free(t1);
-+    return (ret);
-+}
-+
-+static int dsa_init(DSA *dsa)
-+{
-+    dsa->flags |= DSA_FLAG_CACHE_MONT_P;
-+    return (1);
-+}
-+
-+static int dsa_finish(DSA *dsa)
-+{
-+    BN_MONT_CTX_free(dsa->method_mont_p);
-+    return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_pmeth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_pmeth.c
-new file mode 100644
-index 0000000..95f088a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_pmeth.c
-@@ -0,0 +1,273 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+#include "dsa_locl.h"
-+
-+/* DSA pkey context structure */
-+
-+typedef struct {
-+    /* Parameter gen parameters */
-+    int nbits;                  /* size of p in bits (default: 1024) */
-+    int qbits;                  /* size of q in bits (default: 160) */
-+    const EVP_MD *pmd;          /* MD for parameter generation */
-+    /* Keygen callback info */
-+    int gentmp[2];
-+    /* message digest */
-+    const EVP_MD *md;           /* MD for the signature */
-+} DSA_PKEY_CTX;
-+
-+static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
-+{
-+    DSA_PKEY_CTX *dctx;
-+    dctx = OPENSSL_malloc(sizeof(*dctx));
-+    if (dctx == NULL)
-+        return 0;
-+    dctx->nbits = 1024;
-+    dctx->qbits = 160;
-+    dctx->pmd = NULL;
-+    dctx->md = NULL;
-+
-+    ctx->data = dctx;
-+    ctx->keygen_info = dctx->gentmp;
-+    ctx->keygen_info_count = 2;
-+
-+    return 1;
-+}
-+
-+static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
-+{
-+    DSA_PKEY_CTX *dctx, *sctx;
-+    if (!pkey_dsa_init(dst))
-+        return 0;
-+    sctx = src->data;
-+    dctx = dst->data;
-+    dctx->nbits = sctx->nbits;
-+    dctx->qbits = sctx->qbits;
-+    dctx->pmd = sctx->pmd;
-+    dctx->md = sctx->md;
-+    return 1;
-+}
-+
-+static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx)
-+{
-+    DSA_PKEY_CTX *dctx = ctx->data;
-+    OPENSSL_free(dctx);
-+}
-+
-+static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
-+                         size_t *siglen, const unsigned char *tbs,
-+                         size_t tbslen)
-+{
-+    int ret;
-+    unsigned int sltmp;
-+    DSA_PKEY_CTX *dctx = ctx->data;
-+    DSA *dsa = ctx->pkey->pkey.dsa;
-+
-+    if (dctx->md) {
-+        if (tbslen != (size_t)EVP_MD_size(dctx->md))
-+            return 0;
-+    } else {
-+        if (tbslen != SHA_DIGEST_LENGTH)
-+            return 0;
-+    }
-+
-+    ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, dsa);
-+
-+    if (ret <= 0)
-+        return ret;
-+    *siglen = sltmp;
-+    return 1;
-+}
-+
-+static int pkey_dsa_verify(EVP_PKEY_CTX *ctx,
-+                           const unsigned char *sig, size_t siglen,
-+                           const unsigned char *tbs, size_t tbslen)
-+{
-+    int ret;
-+    DSA_PKEY_CTX *dctx = ctx->data;
-+    DSA *dsa = ctx->pkey->pkey.dsa;
-+
-+    if (dctx->md) {
-+        if (tbslen != (size_t)EVP_MD_size(dctx->md))
-+            return 0;
-+    } else {
-+        if (tbslen != SHA_DIGEST_LENGTH)
-+            return 0;
-+    }
-+
-+    ret = DSA_verify(0, tbs, tbslen, sig, siglen, dsa);
-+
-+    return ret;
-+}
-+
-+static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-+{
-+    DSA_PKEY_CTX *dctx = ctx->data;
-+    switch (type) {
-+    case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS:
-+        if (p1 < 256)
-+            return -2;
-+        dctx->nbits = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS:
-+        if (p1 != 160 && p1 != 224 && p1 && p1 != 256)
-+            return -2;
-+        dctx->qbits = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
-+        if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_sha256) {
-+            DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
-+            return 0;
-+        }
-+        dctx->pmd = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_MD:
-+        if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_dsa &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
-+            DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
-+            return 0;
-+        }
-+        dctx->md = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_MD:
-+        *(const EVP_MD **)p2 = dctx->md;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_DIGESTINIT:
-+    case EVP_PKEY_CTRL_PKCS7_SIGN:
-+    case EVP_PKEY_CTRL_CMS_SIGN:
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_PEER_KEY:
-+        DSAerr(DSA_F_PKEY_DSA_CTRL,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    default:
-+        return -2;
-+
-+    }
-+}
-+
-+static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx,
-+                             const char *type, const char *value)
-+{
-+    if (strcmp(type, "dsa_paramgen_bits") == 0) {
-+        int nbits;
-+        nbits = atoi(value);
-+        return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits);
-+    }
-+    if (strcmp(type, "dsa_paramgen_q_bits") == 0) {
-+        int qbits = atoi(value);
-+        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
-+                                 EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits,
-+                                 NULL);
-+    }
-+    if (strcmp(type, "dsa_paramgen_md") == 0) {
-+        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
-+                                 EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0,
-+                                 (void *)EVP_get_digestbyname(value));
-+    }
-+    return -2;
-+}
-+
-+static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    DSA *dsa = NULL;
-+    DSA_PKEY_CTX *dctx = ctx->data;
-+    BN_GENCB *pcb;
-+    int ret;
-+    if (ctx->pkey_gencb) {
-+        pcb = BN_GENCB_new();
-+        if (pcb == NULL)
-+            return 0;
-+        evp_pkey_set_cb_translate(pcb, ctx);
-+    } else
-+        pcb = NULL;
-+    dsa = DSA_new();
-+    if (dsa == NULL) {
-+        BN_GENCB_free(pcb);
-+        return 0;
-+    }
-+    ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
-+                               NULL, 0, NULL, NULL, NULL, pcb);
-+    BN_GENCB_free(pcb);
-+    if (ret)
-+        EVP_PKEY_assign_DSA(pkey, dsa);
-+    else
-+        DSA_free(dsa);
-+    return ret;
-+}
-+
-+static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    DSA *dsa = NULL;
-+    if (ctx->pkey == NULL) {
-+        DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET);
-+        return 0;
-+    }
-+    dsa = DSA_new();
-+    if (dsa == NULL)
-+        return 0;
-+    EVP_PKEY_assign_DSA(pkey, dsa);
-+    /* Note: if error return, pkey is freed by parent routine */
-+    if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
-+        return 0;
-+    return DSA_generate_key(pkey->pkey.dsa);
-+}
-+
-+const EVP_PKEY_METHOD dsa_pkey_meth = {
-+    EVP_PKEY_DSA,
-+    EVP_PKEY_FLAG_AUTOARGLEN,
-+    pkey_dsa_init,
-+    pkey_dsa_copy,
-+    pkey_dsa_cleanup,
-+
-+    0,
-+    pkey_dsa_paramgen,
-+
-+    0,
-+    pkey_dsa_keygen,
-+
-+    0,
-+    pkey_dsa_sign,
-+
-+    0,
-+    pkey_dsa_verify,
-+
-+    0, 0,
-+
-+    0, 0, 0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    pkey_dsa_ctrl,
-+    pkey_dsa_ctrl_str
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_prn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_prn.c
-new file mode 100644
-index 0000000..f3c20ea
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_prn.c
-@@ -0,0 +1,69 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+#ifndef OPENSSL_NO_STDIO
-+int DSA_print_fp(FILE *fp, const DSA *x, int off)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        DSAerr(DSA_F_DSA_PRINT_FP, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = DSA_print(b, x, off);
-+    BIO_free(b);
-+    return (ret);
-+}
-+
-+int DSAparams_print_fp(FILE *fp, const DSA *x)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        DSAerr(DSA_F_DSAPARAMS_PRINT_FP, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = DSAparams_print(b, x);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-+
-+int DSA_print(BIO *bp, const DSA *x, int off)
-+{
-+    EVP_PKEY *pk;
-+    int ret;
-+    pk = EVP_PKEY_new();
-+    if (pk == NULL || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
-+        return 0;
-+    ret = EVP_PKEY_print_private(bp, pk, off, NULL);
-+    EVP_PKEY_free(pk);
-+    return ret;
-+}
-+
-+int DSAparams_print(BIO *bp, const DSA *x)
-+{
-+    EVP_PKEY *pk;
-+    int ret;
-+    pk = EVP_PKEY_new();
-+    if (pk == NULL || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
-+        return 0;
-+    ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
-+    EVP_PKEY_free(pk);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_sign.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_sign.c
-new file mode 100644
-index 0000000..2e29d40
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_sign.c
-@@ -0,0 +1,24 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Original version from Steven Schoch  */
-+
-+#include "internal/cryptlib.h"
-+#include "dsa_locl.h"
-+#include 
-+
-+DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
-+{
-+    return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
-+}
-+
-+int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
-+{
-+    return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_vrf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_vrf.c
-new file mode 100644
-index 0000000..a84d521
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dsa/dsa_vrf.c
-@@ -0,0 +1,19 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Original version from Steven Schoch  */
-+
-+#include "internal/cryptlib.h"
-+#include "dsa_locl.h"
-+
-+int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
-+                  DSA *dsa)
-+{
-+    return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/build.info
-new file mode 100644
-index 0000000..82b592d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/build.info
-@@ -0,0 +1,4 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        dso_dl.c dso_dlfcn.c dso_err.c dso_lib.c \
-+        dso_openssl.c dso_win32.c dso_vms.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_dl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_dl.c
-new file mode 100644
-index 0000000..d80bf56
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_dl.c
-@@ -0,0 +1,279 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "dso_locl.h"
-+
-+#ifdef DSO_DL
-+
-+# include 
-+
-+/* Part of the hack in "dl_load" ... */
-+# define DSO_MAX_TRANSLATED_SIZE 256
-+
-+static int dl_load(DSO *dso);
-+static int dl_unload(DSO *dso);
-+static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname);
-+static char *dl_name_converter(DSO *dso, const char *filename);
-+static char *dl_merger(DSO *dso, const char *filespec1,
-+                       const char *filespec2);
-+static int dl_pathbyaddr(void *addr, char *path, int sz);
-+static void *dl_globallookup(const char *name);
-+
-+static DSO_METHOD dso_meth_dl = {
-+    "OpenSSL 'dl' shared library method",
-+    dl_load,
-+    dl_unload,
-+    dl_bind_func,
-+    NULL,                       /* ctrl */
-+    dl_name_converter,
-+    dl_merger,
-+    NULL,                       /* init */
-+    NULL,                       /* finish */
-+    dl_pathbyaddr,
-+    dl_globallookup
-+};
-+
-+DSO_METHOD *DSO_METHOD_openssl(void)
-+{
-+    return &dso_meth_dl;
-+}
-+
-+/*
-+ * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle
-+ * (shl_t) returned from shl_load(). NB: I checked on HPUX11 and shl_t is
-+ * itself a pointer type so the cast is safe.
-+ */
-+
-+static int dl_load(DSO *dso)
-+{
-+    shl_t ptr = NULL;
-+    /*
-+     * We don't do any fancy retries or anything, just take the method's (or
-+     * DSO's if it has the callback set) best translation of the
-+     * platform-independent filename and try once with that.
-+     */
-+    char *filename = DSO_convert_filename(dso, NULL);
-+
-+    if (filename == NULL) {
-+        DSOerr(DSO_F_DL_LOAD, DSO_R_NO_FILENAME);
-+        goto err;
-+    }
-+    ptr = shl_load(filename, BIND_IMMEDIATE |
-+                   (dso->flags & DSO_FLAG_NO_NAME_TRANSLATION ? 0 :
-+                    DYNAMIC_PATH), 0L);
-+    if (ptr == NULL) {
-+        char errbuf[160];
-+        DSOerr(DSO_F_DL_LOAD, DSO_R_LOAD_FAILED);
-+        if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
-+            ERR_add_error_data(4, "filename(", filename, "): ", errbuf);
-+        goto err;
-+    }
-+    if (!sk_push(dso->meth_data, (char *)ptr)) {
-+        DSOerr(DSO_F_DL_LOAD, DSO_R_STACK_ERROR);
-+        goto err;
-+    }
-+    /*
-+     * Success, stick the converted filename we've loaded under into the DSO
-+     * (it also serves as the indicator that we are currently loaded).
-+     */
-+    dso->loaded_filename = filename;
-+    return (1);
-+ err:
-+    /* Cleanup! */
-+    OPENSSL_free(filename);
-+    if (ptr != NULL)
-+        shl_unload(ptr);
-+    return (0);
-+}
-+
-+static int dl_unload(DSO *dso)
-+{
-+    shl_t ptr;
-+    if (dso == NULL) {
-+        DSOerr(DSO_F_DL_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
-+        return (0);
-+    }
-+    if (sk_num(dso->meth_data) < 1)
-+        return (1);
-+    /* Is this statement legal? */
-+    ptr = (shl_t) sk_pop(dso->meth_data);
-+    if (ptr == NULL) {
-+        DSOerr(DSO_F_DL_UNLOAD, DSO_R_NULL_HANDLE);
-+        /*
-+         * Should push the value back onto the stack in case of a retry.
-+         */
-+        sk_push(dso->meth_data, (char *)ptr);
-+        return (0);
-+    }
-+    shl_unload(ptr);
-+    return (1);
-+}
-+
-+static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
-+{
-+    shl_t ptr;
-+    void *sym;
-+
-+    if ((dso == NULL) || (symname == NULL)) {
-+        DSOerr(DSO_F_DL_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    if (sk_num(dso->meth_data) < 1) {
-+        DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_STACK_ERROR);
-+        return (NULL);
-+    }
-+    ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
-+    if (ptr == NULL) {
-+        DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_NULL_HANDLE);
-+        return (NULL);
-+    }
-+    if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) {
-+        char errbuf[160];
-+        DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_SYM_FAILURE);
-+        if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
-+            ERR_add_error_data(4, "symname(", symname, "): ", errbuf);
-+        return (NULL);
-+    }
-+    return ((DSO_FUNC_TYPE)sym);
-+}
-+
-+static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
-+{
-+    char *merged;
-+
-+    if (!filespec1 && !filespec2) {
-+        DSOerr(DSO_F_DL_MERGER, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    /*
-+     * If the first file specification is a rooted path, it rules. same goes
-+     * if the second file specification is missing.
-+     */
-+    if (!filespec2 || filespec1[0] == '/') {
-+        merged = OPENSSL_strdup(filespec1);
-+        if (merged == NULL) {
-+            DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
-+            return (NULL);
-+        }
-+    }
-+    /*
-+     * If the first file specification is missing, the second one rules.
-+     */
-+    else if (!filespec1) {
-+        merged = OPENSSL_strdup(filespec2);
-+        if (merged == NULL) {
-+            DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
-+            return (NULL);
-+        }
-+    } else
-+        /*
-+         * This part isn't as trivial as it looks.  It assumes that the
-+         * second file specification really is a directory, and makes no
-+         * checks whatsoever.  Therefore, the result becomes the
-+         * concatenation of filespec2 followed by a slash followed by
-+         * filespec1.
-+         */
-+    {
-+        int spec2len, len;
-+
-+        spec2len = (filespec2 ? strlen(filespec2) : 0);
-+        len = spec2len + (filespec1 ? strlen(filespec1) : 0);
-+
-+        if (spec2len && filespec2[spec2len - 1] == '/') {
-+            spec2len--;
-+            len--;
-+        }
-+        merged = OPENSSL_malloc(len + 2);
-+        if (merged == NULL) {
-+            DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
-+            return (NULL);
-+        }
-+        strcpy(merged, filespec2);
-+        merged[spec2len] = '/';
-+        strcpy(&merged[spec2len + 1], filespec1);
-+    }
-+    return (merged);
-+}
-+
-+/*
-+ * This function is identical to the one in dso_dlfcn.c, but as it is highly
-+ * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at
-+ * the same time, there's no great duplicating the code. Figuring out an
-+ * elegant way to share one copy of the code would be more difficult and
-+ * would not leave the implementations independent.
-+ */
-+static char *dl_name_converter(DSO *dso, const char *filename)
-+{
-+    char *translated;
-+    int len, rsize, transform;
-+
-+    len = strlen(filename);
-+    rsize = len + 1;
-+    transform = (strstr(filename, "/") == NULL);
-+    {
-+        /* We will convert this to "%s.s?" or "lib%s.s?" */
-+        rsize += strlen(DSO_EXTENSION); /* The length of ".s?" */
-+        if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
-+            rsize += 3;         /* The length of "lib" */
-+    }
-+    translated = OPENSSL_malloc(rsize);
-+    if (translated == NULL) {
-+        DSOerr(DSO_F_DL_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
-+        return (NULL);
-+    }
-+    if (transform) {
-+        if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
-+            sprintf(translated, "lib%s%s", filename, DSO_EXTENSION);
-+        else
-+            sprintf(translated, "%s%s", filename, DSO_EXTENSION);
-+    } else
-+        sprintf(translated, "%s", filename);
-+    return (translated);
-+}
-+
-+static int dl_pathbyaddr(void *addr, char *path, int sz)
-+{
-+    struct shl_descriptor inf;
-+    int i, len;
-+
-+    if (addr == NULL) {
-+        union {
-+            int (*f) (void *, char *, int);
-+            void *p;
-+        } t = {
-+            dl_pathbyaddr
-+        };
-+        addr = t.p;
-+    }
-+
-+    for (i = -1; shl_get_r(i, &inf) == 0; i++) {
-+        if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
-+            ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) {
-+            len = (int)strlen(inf.filename);
-+            if (sz <= 0)
-+                return len + 1;
-+            if (len >= sz)
-+                len = sz - 1;
-+            memcpy(path, inf.filename, len);
-+            path[len++] = 0;
-+            return len;
-+        }
-+    }
-+
-+    return -1;
-+}
-+
-+static void *dl_globallookup(const char *name)
-+{
-+    void *ret;
-+    shl_t h = NULL;
-+
-+    return shl_findsym(&h, name, TYPE_UNDEFINED, &ret) ? NULL : ret;
-+}
-+#endif                          /* DSO_DL */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_dlfcn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_dlfcn.c
-new file mode 100644
-index 0000000..a4b0cdd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_dlfcn.c
-@@ -0,0 +1,354 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * We need to do this early, because stdio.h includes the header files that
-+ * handle _GNU_SOURCE and other similar macros.  Defining it later is simply
-+ * too late, because those headers are protected from re- inclusion.
-+ */
-+#ifndef _GNU_SOURCE
-+# define _GNU_SOURCE            /* make sure dladdr is declared */
-+#endif
-+
-+#include "dso_locl.h"
-+
-+#ifdef DSO_DLFCN
-+
-+# ifdef HAVE_DLFCN_H
-+#  ifdef __osf__
-+#   define __EXTENSIONS__
-+#  endif
-+#  include 
-+#  define HAVE_DLINFO 1
-+#  if defined(_AIX) || defined(__CYGWIN__) || \
-+     defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
-+     (defined(__osf__) && !defined(RTLD_NEXT))     || \
-+     (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \
-+        defined(__ANDROID__)
-+#   undef HAVE_DLINFO
-+#  endif
-+# endif
-+
-+/* Part of the hack in "dlfcn_load" ... */
-+# define DSO_MAX_TRANSLATED_SIZE 256
-+
-+static int dlfcn_load(DSO *dso);
-+static int dlfcn_unload(DSO *dso);
-+static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
-+static char *dlfcn_name_converter(DSO *dso, const char *filename);
-+static char *dlfcn_merger(DSO *dso, const char *filespec1,
-+                          const char *filespec2);
-+static int dlfcn_pathbyaddr(void *addr, char *path, int sz);
-+static void *dlfcn_globallookup(const char *name);
-+
-+static DSO_METHOD dso_meth_dlfcn = {
-+    "OpenSSL 'dlfcn' shared library method",
-+    dlfcn_load,
-+    dlfcn_unload,
-+    dlfcn_bind_func,
-+    NULL,                       /* ctrl */
-+    dlfcn_name_converter,
-+    dlfcn_merger,
-+    NULL,                       /* init */
-+    NULL,                       /* finish */
-+    dlfcn_pathbyaddr,
-+    dlfcn_globallookup
-+};
-+
-+DSO_METHOD *DSO_METHOD_openssl(void)
-+{
-+    return &dso_meth_dlfcn;
-+}
-+
-+/*
-+ * Prior to using the dlopen() function, we should decide on the flag we
-+ * send. There's a few different ways of doing this and it's a messy
-+ * venn-diagram to match up which platforms support what. So as we don't have
-+ * autoconf yet, I'm implementing a hack that could be hacked further
-+ * relatively easily to deal with cases as we find them. Initially this is to
-+ * cope with OpenBSD.
-+ */
-+# if defined(__OpenBSD__) || defined(__NetBSD__)
-+#  ifdef DL_LAZY
-+#   define DLOPEN_FLAG DL_LAZY
-+#  else
-+#   ifdef RTLD_NOW
-+#    define DLOPEN_FLAG RTLD_NOW
-+#   else
-+#    define DLOPEN_FLAG 0
-+#   endif
-+#  endif
-+# else
-+#  define DLOPEN_FLAG RTLD_NOW  /* Hope this works everywhere else */
-+# endif
-+
-+/*
-+ * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle
-+ * (void*) returned from dlopen().
-+ */
-+
-+static int dlfcn_load(DSO *dso)
-+{
-+    void *ptr = NULL;
-+    /* See applicable comments in dso_dl.c */
-+    char *filename = DSO_convert_filename(dso, NULL);
-+    int flags = DLOPEN_FLAG;
-+
-+    if (filename == NULL) {
-+        DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME);
-+        goto err;
-+    }
-+# ifdef RTLD_GLOBAL
-+    if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
-+        flags |= RTLD_GLOBAL;
-+# endif
-+    ptr = dlopen(filename, flags);
-+    if (ptr == NULL) {
-+        DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED);
-+        ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
-+        goto err;
-+    }
-+    if (!sk_void_push(dso->meth_data, (char *)ptr)) {
-+        DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR);
-+        goto err;
-+    }
-+    /* Success */
-+    dso->loaded_filename = filename;
-+    return (1);
-+ err:
-+    /* Cleanup! */
-+    OPENSSL_free(filename);
-+    if (ptr != NULL)
-+        dlclose(ptr);
-+    return (0);
-+}
-+
-+static int dlfcn_unload(DSO *dso)
-+{
-+    void *ptr;
-+    if (dso == NULL) {
-+        DSOerr(DSO_F_DLFCN_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
-+        return (0);
-+    }
-+    if (sk_void_num(dso->meth_data) < 1)
-+        return (1);
-+    ptr = sk_void_pop(dso->meth_data);
-+    if (ptr == NULL) {
-+        DSOerr(DSO_F_DLFCN_UNLOAD, DSO_R_NULL_HANDLE);
-+        /*
-+         * Should push the value back onto the stack in case of a retry.
-+         */
-+        sk_void_push(dso->meth_data, ptr);
-+        return (0);
-+    }
-+    /* For now I'm not aware of any errors associated with dlclose() */
-+    dlclose(ptr);
-+    return (1);
-+}
-+
-+static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
-+{
-+    void *ptr;
-+    union {
-+        DSO_FUNC_TYPE sym;
-+        void *dlret;
-+    } u;
-+
-+    if ((dso == NULL) || (symname == NULL)) {
-+        DSOerr(DSO_F_DLFCN_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    if (sk_void_num(dso->meth_data) < 1) {
-+        DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_STACK_ERROR);
-+        return (NULL);
-+    }
-+    ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
-+    if (ptr == NULL) {
-+        DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_NULL_HANDLE);
-+        return (NULL);
-+    }
-+    u.dlret = dlsym(ptr, symname);
-+    if (u.dlret == NULL) {
-+        DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_SYM_FAILURE);
-+        ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
-+        return (NULL);
-+    }
-+    return u.sym;
-+}
-+
-+static char *dlfcn_merger(DSO *dso, const char *filespec1,
-+                          const char *filespec2)
-+{
-+    char *merged;
-+
-+    if (!filespec1 && !filespec2) {
-+        DSOerr(DSO_F_DLFCN_MERGER, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    /*
-+     * If the first file specification is a rooted path, it rules. same goes
-+     * if the second file specification is missing.
-+     */
-+    if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) {
-+        merged = OPENSSL_strdup(filespec1);
-+        if (merged == NULL) {
-+            DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
-+            return (NULL);
-+        }
-+    }
-+    /*
-+     * If the first file specification is missing, the second one rules.
-+     */
-+    else if (!filespec1) {
-+        merged = OPENSSL_strdup(filespec2);
-+        if (merged == NULL) {
-+            DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
-+            return (NULL);
-+        }
-+    } else {
-+        /*
-+         * This part isn't as trivial as it looks.  It assumes that the
-+         * second file specification really is a directory, and makes no
-+         * checks whatsoever.  Therefore, the result becomes the
-+         * concatenation of filespec2 followed by a slash followed by
-+         * filespec1.
-+         */
-+        int spec2len, len;
-+
-+        spec2len = strlen(filespec2);
-+        len = spec2len + strlen(filespec1);
-+
-+        if (spec2len && filespec2[spec2len - 1] == '/') {
-+            spec2len--;
-+            len--;
-+        }
-+        merged = OPENSSL_malloc(len + 2);
-+        if (merged == NULL) {
-+            DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
-+            return (NULL);
-+        }
-+        strcpy(merged, filespec2);
-+        merged[spec2len] = '/';
-+        strcpy(&merged[spec2len + 1], filespec1);
-+    }
-+    return (merged);
-+}
-+
-+static char *dlfcn_name_converter(DSO *dso, const char *filename)
-+{
-+    char *translated;
-+    int len, rsize, transform;
-+
-+    len = strlen(filename);
-+    rsize = len + 1;
-+    transform = (strstr(filename, "/") == NULL);
-+    if (transform) {
-+        /* We will convert this to "%s.so" or "lib%s.so" etc */
-+        rsize += strlen(DSO_EXTENSION);    /* The length of ".so" */
-+        if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
-+            rsize += 3;         /* The length of "lib" */
-+    }
-+    translated = OPENSSL_malloc(rsize);
-+    if (translated == NULL) {
-+        DSOerr(DSO_F_DLFCN_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
-+        return (NULL);
-+    }
-+    if (transform) {
-+        if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
-+            sprintf(translated, "lib%s" DSO_EXTENSION, filename);
-+        else
-+            sprintf(translated, "%s" DSO_EXTENSION, filename);
-+    } else
-+        sprintf(translated, "%s", filename);
-+    return (translated);
-+}
-+
-+# ifdef __sgi
-+/*-
-+This is a quote from IRIX manual for dladdr(3c):
-+
-+      does not contain a prototype for dladdr or definition of
-+     Dl_info.  The #include   in the SYNOPSIS line is traditional,
-+     but contains no dladdr prototype and no IRIX library contains an
-+     implementation.  Write your own declaration based on the code below.
-+
-+     The following code is dependent on internal interfaces that are not
-+     part of the IRIX compatibility guarantee; however, there is no future
-+     intention to change this interface, so on a practical level, the code
-+     below is safe to use on IRIX.
-+*/
-+#  include 
-+#  ifndef _RLD_INTERFACE_DLFCN_H_DLADDR
-+#   define _RLD_INTERFACE_DLFCN_H_DLADDR
-+typedef struct Dl_info {
-+    const char *dli_fname;
-+    void *dli_fbase;
-+    const char *dli_sname;
-+    void *dli_saddr;
-+    int dli_version;
-+    int dli_reserved1;
-+    long dli_reserved[4];
-+} Dl_info;
-+#  else
-+typedef struct Dl_info Dl_info;
-+#  endif
-+#  define _RLD_DLADDR             14
-+
-+static int dladdr(void *address, Dl_info *dl)
-+{
-+    void *v;
-+    v = _rld_new_interface(_RLD_DLADDR, address, dl);
-+    return (int)v;
-+}
-+# endif                         /* __sgi */
-+
-+static int dlfcn_pathbyaddr(void *addr, char *path, int sz)
-+{
-+# ifdef HAVE_DLINFO
-+    Dl_info dli;
-+    int len;
-+
-+    if (addr == NULL) {
-+        union {
-+            int (*f) (void *, char *, int);
-+            void *p;
-+        } t = {
-+            dlfcn_pathbyaddr
-+        };
-+        addr = t.p;
-+    }
-+
-+    if (dladdr(addr, &dli)) {
-+        len = (int)strlen(dli.dli_fname);
-+        if (sz <= 0)
-+            return len + 1;
-+        if (len >= sz)
-+            len = sz - 1;
-+        memcpy(path, dli.dli_fname, len);
-+        path[len++] = 0;
-+        return len;
-+    }
-+
-+    ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror());
-+# endif
-+    return -1;
-+}
-+
-+static void *dlfcn_globallookup(const char *name)
-+{
-+    void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY);
-+
-+    if (handle) {
-+        ret = dlsym(handle, name);
-+        dlclose(handle);
-+    }
-+
-+    return ret;
-+}
-+#endif                          /* DSO_DLFCN */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_err.c
-new file mode 100644
-index 0000000..07588d5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_err.c
-@@ -0,0 +1,93 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/dso.h"
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSO,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSO,0,reason)
-+
-+static ERR_STRING_DATA DSO_str_functs[] = {
-+    {ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "dlfcn_bind_func"},
-+    {ERR_FUNC(DSO_F_DLFCN_LOAD), "dlfcn_load"},
-+    {ERR_FUNC(DSO_F_DLFCN_MERGER), "dlfcn_merger"},
-+    {ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER), "dlfcn_name_converter"},
-+    {ERR_FUNC(DSO_F_DLFCN_UNLOAD), "dlfcn_unload"},
-+    {ERR_FUNC(DSO_F_DL_BIND_FUNC), "dl_bind_func"},
-+    {ERR_FUNC(DSO_F_DL_LOAD), "dl_load"},
-+    {ERR_FUNC(DSO_F_DL_MERGER), "dl_merger"},
-+    {ERR_FUNC(DSO_F_DL_NAME_CONVERTER), "dl_name_converter"},
-+    {ERR_FUNC(DSO_F_DL_UNLOAD), "dl_unload"},
-+    {ERR_FUNC(DSO_F_DSO_BIND_FUNC), "DSO_bind_func"},
-+    {ERR_FUNC(DSO_F_DSO_CONVERT_FILENAME), "DSO_convert_filename"},
-+    {ERR_FUNC(DSO_F_DSO_CTRL), "DSO_ctrl"},
-+    {ERR_FUNC(DSO_F_DSO_FREE), "DSO_free"},
-+    {ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"},
-+    {ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP), "DSO_global_lookup"},
-+    {ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"},
-+    {ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"},
-+    {ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"},
-+    {ERR_FUNC(DSO_F_DSO_PATHBYADDR), "DSO_pathbyaddr"},
-+    {ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"},
-+    {ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"},
-+    {ERR_FUNC(DSO_F_VMS_BIND_SYM), "vms_bind_sym"},
-+    {ERR_FUNC(DSO_F_VMS_LOAD), "vms_load"},
-+    {ERR_FUNC(DSO_F_VMS_MERGER), "vms_merger"},
-+    {ERR_FUNC(DSO_F_VMS_UNLOAD), "vms_unload"},
-+    {ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "win32_bind_func"},
-+    {ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP), "win32_globallookup"},
-+    {ERR_FUNC(DSO_F_WIN32_JOINER), "win32_joiner"},
-+    {ERR_FUNC(DSO_F_WIN32_LOAD), "win32_load"},
-+    {ERR_FUNC(DSO_F_WIN32_MERGER), "win32_merger"},
-+    {ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "win32_name_converter"},
-+    {ERR_FUNC(DSO_F_WIN32_PATHBYADDR), "win32_pathbyaddr"},
-+    {ERR_FUNC(DSO_F_WIN32_SPLITTER), "win32_splitter"},
-+    {ERR_FUNC(DSO_F_WIN32_UNLOAD), "win32_unload"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA DSO_str_reasons[] = {
-+    {ERR_REASON(DSO_R_CTRL_FAILED), "control command failed"},
-+    {ERR_REASON(DSO_R_DSO_ALREADY_LOADED), "dso already loaded"},
-+    {ERR_REASON(DSO_R_EMPTY_FILE_STRUCTURE), "empty file structure"},
-+    {ERR_REASON(DSO_R_FAILURE), "failure"},
-+    {ERR_REASON(DSO_R_FILENAME_TOO_BIG), "filename too big"},
-+    {ERR_REASON(DSO_R_FINISH_FAILED), "cleanup method function failed"},
-+    {ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX), "incorrect file syntax"},
-+    {ERR_REASON(DSO_R_LOAD_FAILED), "could not load the shared library"},
-+    {ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED), "name translation failed"},
-+    {ERR_REASON(DSO_R_NO_FILENAME), "no filename"},
-+    {ERR_REASON(DSO_R_NULL_HANDLE), "a null shared library handle was used"},
-+    {ERR_REASON(DSO_R_SET_FILENAME_FAILED), "set filename failed"},
-+    {ERR_REASON(DSO_R_STACK_ERROR), "the meth_data stack is corrupt"},
-+    {ERR_REASON(DSO_R_SYM_FAILURE),
-+     "could not bind to the requested symbol name"},
-+    {ERR_REASON(DSO_R_UNLOAD_FAILED), "could not unload the shared library"},
-+    {ERR_REASON(DSO_R_UNSUPPORTED), "functionality not supported"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_DSO_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(DSO_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, DSO_str_functs);
-+        ERR_load_strings(0, DSO_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_lib.c
-new file mode 100644
-index 0000000..f58237d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_lib.c
-@@ -0,0 +1,349 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "dso_locl.h"
-+
-+static DSO_METHOD *default_DSO_meth = NULL;
-+
-+static DSO *DSO_new_method(DSO_METHOD *meth)
-+{
-+    DSO *ret;
-+
-+    if (default_DSO_meth == NULL) {
-+        /*
-+         * We default to DSO_METH_openssl() which in turn defaults to
-+         * stealing the "best available" method. Will fallback to
-+         * DSO_METH_null() in the worst case.
-+         */
-+        default_DSO_meth = DSO_METHOD_openssl();
-+    }
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL) {
-+        DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+    ret->meth_data = sk_void_new_null();
-+    if (ret->meth_data == NULL) {
-+        /* sk_new doesn't generate any errors so we do */
-+        DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return (NULL);
-+    }
-+    ret->meth = default_DSO_meth;
-+    ret->references = 1;
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        sk_void_free(ret->meth_data);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+
-+    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
-+        DSO_free(ret);
-+        ret = NULL;
-+    }
-+
-+    return ret;
-+}
-+
-+DSO *DSO_new(void)
-+{
-+    return DSO_new_method(NULL);
-+}
-+
-+int DSO_free(DSO *dso)
-+{
-+    int i;
-+
-+    if (dso == NULL)
-+        return (1);
-+
-+    if (CRYPTO_atomic_add(&dso->references, -1, &i, dso->lock) <= 0)
-+        return 0;
-+
-+    REF_PRINT_COUNT("DSO", dso);
-+    if (i > 0)
-+        return 1;
-+    REF_ASSERT_ISNT(i < 0);
-+
-+    if ((dso->flags & DSO_FLAG_NO_UNLOAD_ON_FREE) == 0) {
-+        if ((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) {
-+            DSOerr(DSO_F_DSO_FREE, DSO_R_UNLOAD_FAILED);
-+            return 0;
-+        }
-+    }
-+
-+    if ((dso->meth->finish != NULL) && !dso->meth->finish(dso)) {
-+        DSOerr(DSO_F_DSO_FREE, DSO_R_FINISH_FAILED);
-+        return 0;
-+    }
-+
-+    sk_void_free(dso->meth_data);
-+    OPENSSL_free(dso->filename);
-+    OPENSSL_free(dso->loaded_filename);
-+    CRYPTO_THREAD_lock_free(dso->lock);
-+    OPENSSL_free(dso);
-+    return 1;
-+}
-+
-+int DSO_flags(DSO *dso)
-+{
-+    return ((dso == NULL) ? 0 : dso->flags);
-+}
-+
-+int DSO_up_ref(DSO *dso)
-+{
-+    int i;
-+
-+    if (dso == NULL) {
-+        DSOerr(DSO_F_DSO_UP_REF, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+
-+    if (CRYPTO_atomic_add(&dso->references, 1, &i, dso->lock) <= 0)
-+        return 0;
-+
-+    REF_PRINT_COUNT("DSO", r);
-+    REF_ASSERT_ISNT(i < 2);
-+    return ((i > 1) ? 1 : 0);
-+}
-+
-+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
-+{
-+    DSO *ret;
-+    int allocated = 0;
-+
-+    if (dso == NULL) {
-+        ret = DSO_new_method(meth);
-+        if (ret == NULL) {
-+            DSOerr(DSO_F_DSO_LOAD, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        allocated = 1;
-+        /* Pass the provided flags to the new DSO object */
-+        if (DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) {
-+            DSOerr(DSO_F_DSO_LOAD, DSO_R_CTRL_FAILED);
-+            goto err;
-+        }
-+    } else
-+        ret = dso;
-+    /* Don't load if we're currently already loaded */
-+    if (ret->filename != NULL) {
-+        DSOerr(DSO_F_DSO_LOAD, DSO_R_DSO_ALREADY_LOADED);
-+        goto err;
-+    }
-+    /*
-+     * filename can only be NULL if we were passed a dso that already has one
-+     * set.
-+     */
-+    if (filename != NULL)
-+        if (!DSO_set_filename(ret, filename)) {
-+            DSOerr(DSO_F_DSO_LOAD, DSO_R_SET_FILENAME_FAILED);
-+            goto err;
-+        }
-+    filename = ret->filename;
-+    if (filename == NULL) {
-+        DSOerr(DSO_F_DSO_LOAD, DSO_R_NO_FILENAME);
-+        goto err;
-+    }
-+    if (ret->meth->dso_load == NULL) {
-+        DSOerr(DSO_F_DSO_LOAD, DSO_R_UNSUPPORTED);
-+        goto err;
-+    }
-+    if (!ret->meth->dso_load(ret)) {
-+        DSOerr(DSO_F_DSO_LOAD, DSO_R_LOAD_FAILED);
-+        goto err;
-+    }
-+    /* Load succeeded */
-+    return (ret);
-+ err:
-+    if (allocated)
-+        DSO_free(ret);
-+    return (NULL);
-+}
-+
-+DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
-+{
-+    DSO_FUNC_TYPE ret = NULL;
-+
-+    if ((dso == NULL) || (symname == NULL)) {
-+        DSOerr(DSO_F_DSO_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    if (dso->meth->dso_bind_func == NULL) {
-+        DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_UNSUPPORTED);
-+        return (NULL);
-+    }
-+    if ((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) {
-+        DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_SYM_FAILURE);
-+        return (NULL);
-+    }
-+    /* Success */
-+    return (ret);
-+}
-+
-+/*
-+ * I don't really like these *_ctrl functions very much to be perfectly
-+ * honest. For one thing, I think I have to return a negative value for any
-+ * error because possible DSO_ctrl() commands may return values such as
-+ * "size"s that can legitimately be zero (making the standard
-+ * "if (DSO_cmd(...))" form that works almost everywhere else fail at odd
-+ * times. I'd prefer "output" values to be passed by reference and the return
-+ * value as success/failure like usual ... but we conform when we must... :-)
-+ */
-+long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
-+{
-+    if (dso == NULL) {
-+        DSOerr(DSO_F_DSO_CTRL, ERR_R_PASSED_NULL_PARAMETER);
-+        return (-1);
-+    }
-+    /*
-+     * We should intercept certain generic commands and only pass control to
-+     * the method-specific ctrl() function if it's something we don't handle.
-+     */
-+    switch (cmd) {
-+    case DSO_CTRL_GET_FLAGS:
-+        return dso->flags;
-+    case DSO_CTRL_SET_FLAGS:
-+        dso->flags = (int)larg;
-+        return (0);
-+    case DSO_CTRL_OR_FLAGS:
-+        dso->flags |= (int)larg;
-+        return (0);
-+    default:
-+        break;
-+    }
-+    if ((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) {
-+        DSOerr(DSO_F_DSO_CTRL, DSO_R_UNSUPPORTED);
-+        return (-1);
-+    }
-+    return (dso->meth->dso_ctrl(dso, cmd, larg, parg));
-+}
-+
-+const char *DSO_get_filename(DSO *dso)
-+{
-+    if (dso == NULL) {
-+        DSOerr(DSO_F_DSO_GET_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    return (dso->filename);
-+}
-+
-+int DSO_set_filename(DSO *dso, const char *filename)
-+{
-+    char *copied;
-+
-+    if ((dso == NULL) || (filename == NULL)) {
-+        DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
-+        return (0);
-+    }
-+    if (dso->loaded_filename) {
-+        DSOerr(DSO_F_DSO_SET_FILENAME, DSO_R_DSO_ALREADY_LOADED);
-+        return (0);
-+    }
-+    /* We'll duplicate filename */
-+    copied = OPENSSL_strdup(filename);
-+    if (copied == NULL) {
-+        DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_MALLOC_FAILURE);
-+        return (0);
-+    }
-+    OPENSSL_free(dso->filename);
-+    dso->filename = copied;
-+    return (1);
-+}
-+
-+char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
-+{
-+    char *result = NULL;
-+
-+    if (dso == NULL || filespec1 == NULL) {
-+        DSOerr(DSO_F_DSO_MERGE, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
-+        if (dso->merger != NULL)
-+            result = dso->merger(dso, filespec1, filespec2);
-+        else if (dso->meth->dso_merger != NULL)
-+            result = dso->meth->dso_merger(dso, filespec1, filespec2);
-+    }
-+    return (result);
-+}
-+
-+char *DSO_convert_filename(DSO *dso, const char *filename)
-+{
-+    char *result = NULL;
-+
-+    if (dso == NULL) {
-+        DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    if (filename == NULL)
-+        filename = dso->filename;
-+    if (filename == NULL) {
-+        DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME);
-+        return (NULL);
-+    }
-+    if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
-+        if (dso->name_converter != NULL)
-+            result = dso->name_converter(dso, filename);
-+        else if (dso->meth->dso_name_converter != NULL)
-+            result = dso->meth->dso_name_converter(dso, filename);
-+    }
-+    if (result == NULL) {
-+        result = OPENSSL_strdup(filename);
-+        if (result == NULL) {
-+            DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE);
-+            return (NULL);
-+        }
-+    }
-+    return (result);
-+}
-+
-+int DSO_pathbyaddr(void *addr, char *path, int sz)
-+{
-+    DSO_METHOD *meth = default_DSO_meth;
-+    if (meth == NULL)
-+        meth = DSO_METHOD_openssl();
-+    if (meth->pathbyaddr == NULL) {
-+        DSOerr(DSO_F_DSO_PATHBYADDR, DSO_R_UNSUPPORTED);
-+        return -1;
-+    }
-+    return (*meth->pathbyaddr) (addr, path, sz);
-+}
-+
-+DSO *DSO_dsobyaddr(void *addr, int flags)
-+{
-+    DSO *ret = NULL;
-+    char *filename = NULL;
-+    int len = DSO_pathbyaddr(addr, NULL, 0);
-+
-+    if (len < 0)
-+        return NULL;
-+
-+    filename = OPENSSL_malloc(len);
-+    if (filename != NULL
-+            && DSO_pathbyaddr(addr, filename, len) == len)
-+        ret = DSO_load(NULL, filename, NULL, flags);
-+
-+    OPENSSL_free(filename);
-+    return ret;
-+}
-+
-+void *DSO_global_lookup(const char *name)
-+{
-+    DSO_METHOD *meth = default_DSO_meth;
-+    if (meth == NULL)
-+        meth = DSO_METHOD_openssl();
-+    if (meth->globallookup == NULL) {
-+        DSOerr(DSO_F_DSO_GLOBAL_LOOKUP, DSO_R_UNSUPPORTED);
-+        return NULL;
-+    }
-+    return (*meth->globallookup) (name);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_locl.h
-new file mode 100644
-index 0000000..fbfad05
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_locl.h
-@@ -0,0 +1,106 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "internal/dso.h"
-+#include "internal/dso_conf.h"
-+
-+/**********************************************************************/
-+/* The low-level handle type used to refer to a loaded shared library */
-+
-+struct dso_st {
-+    DSO_METHOD *meth;
-+    /*
-+     * Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS doesn't use
-+     * anything but will need to cache the filename for use in the dso_bind
-+     * handler. All in all, let each method control its own destiny.
-+     * "Handles" and such go in a STACK.
-+     */
-+    STACK_OF(void) *meth_data;
-+    int references;
-+    int flags;
-+    /*
-+     * For use by applications etc ... use this for your bits'n'pieces, don't
-+     * touch meth_data!
-+     */
-+    CRYPTO_EX_DATA ex_data;
-+    /*
-+     * If this callback function pointer is set to non-NULL, then it will be
-+     * used in DSO_load() in place of meth->dso_name_converter. NB: This
-+     * should normally set using DSO_set_name_converter().
-+     */
-+    DSO_NAME_CONVERTER_FUNC name_converter;
-+    /*
-+     * If this callback function pointer is set to non-NULL, then it will be
-+     * used in DSO_load() in place of meth->dso_merger. NB: This should
-+     * normally set using DSO_set_merger().
-+     */
-+    DSO_MERGER_FUNC merger;
-+    /*
-+     * This is populated with (a copy of) the platform-independent filename
-+     * used for this DSO.
-+     */
-+    char *filename;
-+    /*
-+     * This is populated with (a copy of) the translated filename by which
-+     * the DSO was actually loaded. It is NULL iff the DSO is not currently
-+     * loaded. NB: This is here because the filename translation process may
-+     * involve a callback being invoked more than once not only to convert to
-+     * a platform-specific form, but also to try different filenames in the
-+     * process of trying to perform a load. As such, this variable can be
-+     * used to indicate (a) whether this DSO structure corresponds to a
-+     * loaded library or not, and (b) the filename with which it was actually
-+     * loaded.
-+     */
-+    char *loaded_filename;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+struct dso_meth_st {
-+    const char *name;
-+    /*
-+     * Loads a shared library, NB: new DSO_METHODs must ensure that a
-+     * successful load populates the loaded_filename field, and likewise a
-+     * successful unload OPENSSL_frees and NULLs it out.
-+     */
-+    int (*dso_load) (DSO *dso);
-+    /* Unloads a shared library */
-+    int (*dso_unload) (DSO *dso);
-+    /*
-+     * Binds a function - assumes a return type of DSO_FUNC_TYPE. This should
-+     * be cast to the real function prototype by the caller. Platforms that
-+     * don't have compatible representations for different prototypes (this
-+     * is possible within ANSI C) are highly unlikely to have shared
-+     * libraries at all, let alone a DSO_METHOD implemented for them.
-+     */
-+    DSO_FUNC_TYPE (*dso_bind_func) (DSO *dso, const char *symname);
-+    /*
-+     * The generic (yuck) "ctrl()" function. NB: Negative return values
-+     * (rather than zero) indicate errors.
-+     */
-+    long (*dso_ctrl) (DSO *dso, int cmd, long larg, void *parg);
-+    /*
-+     * The default DSO_METHOD-specific function for converting filenames to a
-+     * canonical native form.
-+     */
-+    DSO_NAME_CONVERTER_FUNC dso_name_converter;
-+    /*
-+     * The default DSO_METHOD-specific function for converting filenames to a
-+     * canonical native form.
-+     */
-+    DSO_MERGER_FUNC dso_merger;
-+    /* [De]Initialisation handlers. */
-+    int (*init) (DSO *dso);
-+    int (*finish) (DSO *dso);
-+    /* Return pathname of the module containing location */
-+    int (*pathbyaddr) (void *addr, char *path, int sz);
-+    /* Perform global symbol lookup, i.e. among *all* modules */
-+    void *(*globallookup) (const char *symname);
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_openssl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_openssl.c
-new file mode 100644
-index 0000000..6626331
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_openssl.c
-@@ -0,0 +1,22 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "dso_locl.h"
-+
-+#if !defined(DSO_VMS) && !defined(DSO_DLCFN) && !defined(DSO_DL) && !defined(DSO_WIN32) && !defined(DSO_DLFCN)
-+
-+static DSO_METHOD dso_meth_null = {
-+    "NULL shared library method"
-+};
-+
-+DSO_METHOD *DSO_METHOD_openssl(void)
-+{
-+    return &dso_meth_null;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_vms.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_vms.c
-new file mode 100644
-index 0000000..b9a98dd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_vms.c
-@@ -0,0 +1,468 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "dso_locl.h"
-+
-+#ifdef OPENSSL_SYS_VMS
-+
-+# pragma message disable DOLLARID
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "../vms_rms.h"
-+
-+/* Some compiler options may mask the declaration of "_malloc32". */
-+# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
-+#  if __INITIAL_POINTER_SIZE == 64
-+#   pragma pointer_size save
-+#   pragma pointer_size 32
-+void *_malloc32(__size_t);
-+#   pragma pointer_size restore
-+#  endif                        /* __INITIAL_POINTER_SIZE == 64 */
-+# endif                         /* __INITIAL_POINTER_SIZE && defined
-+                                 * _ANSI_C_SOURCE */
-+
-+# pragma message disable DOLLARID
-+
-+static int vms_load(DSO *dso);
-+static int vms_unload(DSO *dso);
-+static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname);
-+static char *vms_name_converter(DSO *dso, const char *filename);
-+static char *vms_merger(DSO *dso, const char *filespec1,
-+                        const char *filespec2);
-+
-+static DSO_METHOD dso_meth_vms = {
-+    "OpenSSL 'VMS' shared library method",
-+    vms_load,
-+    NULL,                       /* unload */
-+    vms_bind_func,
-+    NULL,                       /* ctrl */
-+    vms_name_converter,
-+    vms_merger,
-+    NULL,                       /* init */
-+    NULL,                       /* finish */
-+    NULL,                       /* pathbyaddr */
-+    NULL                        /* globallookup */
-+};
-+
-+/*
-+ * On VMS, the only "handle" is the file name.  LIB$FIND_IMAGE_SYMBOL depends
-+ * on the reference to the file name being the same for all calls regarding
-+ * one shared image, so we'll just store it in an instance of the following
-+ * structure and put a pointer to that instance in the meth_data stack.
-+ */
-+typedef struct dso_internal_st {
-+    /*
-+     * This should contain the name only, no directory, no extension, nothing
-+     * but a name.
-+     */
-+    struct dsc$descriptor_s filename_dsc;
-+    char filename[NAMX_MAXRSS + 1];
-+    /*
-+     * This contains whatever is not in filename, if needed. Normally not
-+     * defined.
-+     */
-+    struct dsc$descriptor_s imagename_dsc;
-+    char imagename[NAMX_MAXRSS + 1];
-+} DSO_VMS_INTERNAL;
-+
-+DSO_METHOD *DSO_METHOD_openssl(void)
-+{
-+    return &dso_meth_vms;
-+}
-+
-+static int vms_load(DSO *dso)
-+{
-+    void *ptr = NULL;
-+    /* See applicable comments in dso_dl.c */
-+    char *filename = DSO_convert_filename(dso, NULL);
-+
-+/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */
-+# if __INITIAL_POINTER_SIZE == 64
-+#  define DSO_MALLOC _malloc32
-+#  pragma pointer_size save
-+#  pragma pointer_size 32
-+# else                          /* __INITIAL_POINTER_SIZE == 64 */
-+#  define DSO_MALLOC OPENSSL_malloc
-+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
-+
-+    DSO_VMS_INTERNAL *p = NULL;
-+
-+# if __INITIAL_POINTER_SIZE == 64
-+#  pragma pointer_size restore
-+# endif                         /* __INITIAL_POINTER_SIZE == 64 */
-+
-+    const char *sp1, *sp2;      /* Search result */
-+    const char *ext = NULL;     /* possible extension to add */
-+
-+    if (filename == NULL) {
-+        DSOerr(DSO_F_VMS_LOAD, DSO_R_NO_FILENAME);
-+        goto err;
-+    }
-+
-+    /*-
-+     * A file specification may look like this:
-+     *
-+     *      node::dev:[dir-spec]name.type;ver
-+     *
-+     * or (for compatibility with TOPS-20):
-+     *
-+     *      node::dev:name.type;ver
-+     *
-+     * and the dir-spec uses '.' as separator.  Also, a dir-spec
-+     * may consist of several parts, with mixed use of [] and <>:
-+     *
-+     *      [dir1.]
-+     *
-+     * We need to split the file specification into the name and
-+     * the rest (both before and after the name itself).
-+     */
-+    /*
-+     * Start with trying to find the end of a dir-spec, and save the position
-+     * of the byte after in sp1
-+     */
-+    sp1 = strrchr(filename, ']');
-+    sp2 = strrchr(filename, '>');
-+    if (sp1 == NULL)
-+        sp1 = sp2;
-+    if (sp2 != NULL && sp2 > sp1)
-+        sp1 = sp2;
-+    if (sp1 == NULL)
-+        sp1 = strrchr(filename, ':');
-+    if (sp1 == NULL)
-+        sp1 = filename;
-+    else
-+        sp1++;                  /* The byte after the found character */
-+    /* Now, let's see if there's a type, and save the position in sp2 */
-+    sp2 = strchr(sp1, '.');
-+    /*
-+     * If there is a period and the next character is a semi-colon,
-+     * we need to add an extension
-+     */
-+    if (sp2 != NULL && sp2[1] == ';')
-+        ext = ".EXE";
-+    /*
-+     * If we found it, that's where we'll cut.  Otherwise, look for a version
-+     * number and save the position in sp2
-+     */
-+    if (sp2 == NULL) {
-+        sp2 = strchr(sp1, ';');
-+        ext = ".EXE";
-+    }
-+    /*
-+     * If there was still nothing to find, set sp2 to point at the end of the
-+     * string
-+     */
-+    if (sp2 == NULL)
-+        sp2 = sp1 + strlen(sp1);
-+
-+    /* Check that we won't get buffer overflows */
-+    if (sp2 - sp1 > FILENAME_MAX
-+        || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) {
-+        DSOerr(DSO_F_VMS_LOAD, DSO_R_FILENAME_TOO_BIG);
-+        goto err;
-+    }
-+
-+    p = DSO_MALLOC(sizeof(*p));
-+    if (p == NULL) {
-+        DSOerr(DSO_F_VMS_LOAD, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    strncpy(p->filename, sp1, sp2 - sp1);
-+    p->filename[sp2 - sp1] = '\0';
-+
-+    strncpy(p->imagename, filename, sp1 - filename);
-+    p->imagename[sp1 - filename] = '\0';
-+    if (ext) {
-+        strcat(p->imagename, ext);
-+        if (*sp2 == '.')
-+            sp2++;
-+    }
-+    strcat(p->imagename, sp2);
-+
-+    p->filename_dsc.dsc$w_length = strlen(p->filename);
-+    p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
-+    p->filename_dsc.dsc$b_class = DSC$K_CLASS_S;
-+    p->filename_dsc.dsc$a_pointer = p->filename;
-+    p->imagename_dsc.dsc$w_length = strlen(p->imagename);
-+    p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
-+    p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S;
-+    p->imagename_dsc.dsc$a_pointer = p->imagename;
-+
-+    if (!sk_void_push(dso->meth_data, (char *)p)) {
-+        DSOerr(DSO_F_VMS_LOAD, DSO_R_STACK_ERROR);
-+        goto err;
-+    }
-+
-+    /* Success (for now, we lie.  We actually do not know...) */
-+    dso->loaded_filename = filename;
-+    return (1);
-+ err:
-+    /* Cleanup! */
-+    OPENSSL_free(p);
-+    OPENSSL_free(filename);
-+    return (0);
-+}
-+
-+/*
-+ * Note that this doesn't actually unload the shared image, as there is no
-+ * such thing in VMS.  Next time it get loaded again, a new copy will
-+ * actually be loaded.
-+ */
-+static int vms_unload(DSO *dso)
-+{
-+    DSO_VMS_INTERNAL *p;
-+    if (dso == NULL) {
-+        DSOerr(DSO_F_VMS_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
-+        return (0);
-+    }
-+    if (sk_void_num(dso->meth_data) < 1)
-+        return (1);
-+    p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data);
-+    if (p == NULL) {
-+        DSOerr(DSO_F_VMS_UNLOAD, DSO_R_NULL_HANDLE);
-+        return (0);
-+    }
-+    /* Cleanup */
-+    OPENSSL_free(p);
-+    return (1);
-+}
-+
-+/*
-+ * We must do this in a separate function because of the way the exception
-+ * handler works (it makes this function return
-+ */
-+static int do_find_symbol(DSO_VMS_INTERNAL *ptr,
-+                          struct dsc$descriptor_s *symname_dsc, void **sym,
-+                          unsigned long flags)
-+{
-+    /*
-+     * Make sure that signals are caught and returned instead of aborting the
-+     * program.  The exception handler gets unestablished automatically on
-+     * return from this function.
-+     */
-+    lib$establish(lib$sig_to_ret);
-+
-+    if (ptr->imagename_dsc.dsc$w_length)
-+        return lib$find_image_symbol(&ptr->filename_dsc,
-+                                     symname_dsc, sym,
-+                                     &ptr->imagename_dsc, flags);
-+    else
-+        return lib$find_image_symbol(&ptr->filename_dsc,
-+                                     symname_dsc, sym, 0, flags);
-+}
-+
-+void vms_bind_sym(DSO *dso, const char *symname, void **sym)
-+{
-+    DSO_VMS_INTERNAL *ptr;
-+    int status;
-+# ifdef LIB$M_FIS_MIXEDCASE
-+    int flags = LIB$M_FIS_MIXEDCASE;
-+# else
-+    int flags = (1 << 4);
-+# endif
-+    struct dsc$descriptor_s symname_dsc;
-+
-+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
-+# if __INITIAL_POINTER_SIZE == 64
-+#  define SYMNAME symname_32p
-+#  pragma pointer_size save
-+#  pragma pointer_size 32
-+    char *symname_32p;
-+#  pragma pointer_size restore
-+    char symname_32[NAMX_MAXRSS + 1];
-+# else                          /* __INITIAL_POINTER_SIZE == 64 */
-+#  define SYMNAME ((char *) symname)
-+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
-+
-+    *sym = NULL;
-+
-+    if ((dso == NULL) || (symname == NULL)) {
-+        DSOerr(DSO_F_VMS_BIND_SYM, ERR_R_PASSED_NULL_PARAMETER);
-+        return;
-+    }
-+# if __INITIAL_POINTER_SIZE == 64
-+    /* Copy the symbol name to storage with a 32-bit pointer. */
-+    symname_32p = symname_32;
-+    strcpy(symname_32p, symname);
-+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
-+
-+    symname_dsc.dsc$w_length = strlen(SYMNAME);
-+    symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
-+    symname_dsc.dsc$b_class = DSC$K_CLASS_S;
-+    symname_dsc.dsc$a_pointer = SYMNAME;
-+
-+    if (sk_void_num(dso->meth_data) < 1) {
-+        DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_STACK_ERROR);
-+        return;
-+    }
-+    ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data,
-+                                            sk_void_num(dso->meth_data) - 1);
-+    if (ptr == NULL) {
-+        DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_NULL_HANDLE);
-+        return;
-+    }
-+
-+    if (dso->flags & DSO_FLAG_UPCASE_SYMBOL)
-+        flags = 0;
-+
-+    status = do_find_symbol(ptr, &symname_dsc, sym, flags);
-+
-+    if (!$VMS_STATUS_SUCCESS(status)) {
-+        unsigned short length;
-+        char errstring[257];
-+        struct dsc$descriptor_s errstring_dsc;
-+
-+        errstring_dsc.dsc$w_length = sizeof(errstring);
-+        errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
-+        errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
-+        errstring_dsc.dsc$a_pointer = errstring;
-+
-+        *sym = NULL;
-+
-+        status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
-+
-+        if (!$VMS_STATUS_SUCCESS(status))
-+            lib$signal(status); /* This is really bad.  Abort! */
-+        else {
-+            errstring[length] = '\0';
-+
-+            DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_SYM_FAILURE);
-+            if (ptr->imagename_dsc.dsc$w_length)
-+                ERR_add_error_data(9,
-+                                   "Symbol ", symname,
-+                                   " in ", ptr->filename,
-+                                   " (", ptr->imagename, ")",
-+                                   ": ", errstring);
-+            else
-+                ERR_add_error_data(6,
-+                                   "Symbol ", symname,
-+                                   " in ", ptr->filename, ": ", errstring);
-+        }
-+        return;
-+    }
-+    return;
-+}
-+
-+static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname)
-+{
-+    DSO_FUNC_TYPE sym = 0;
-+    vms_bind_sym(dso, symname, (void **)&sym);
-+    return sym;
-+}
-+
-+static char *vms_merger(DSO *dso, const char *filespec1,
-+                        const char *filespec2)
-+{
-+    int status;
-+    int filespec1len, filespec2len;
-+    struct FAB fab;
-+    struct NAMX_STRUCT nam;
-+    char esa[NAMX_MAXRSS + 1];
-+    char *merged;
-+
-+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
-+# if __INITIAL_POINTER_SIZE == 64
-+#  define FILESPEC1 filespec1_32p;
-+#  define FILESPEC2 filespec2_32p;
-+#  pragma pointer_size save
-+#  pragma pointer_size 32
-+    char *filespec1_32p;
-+    char *filespec2_32p;
-+#  pragma pointer_size restore
-+    char filespec1_32[NAMX_MAXRSS + 1];
-+    char filespec2_32[NAMX_MAXRSS + 1];
-+# else                          /* __INITIAL_POINTER_SIZE == 64 */
-+#  define FILESPEC1 ((char *) filespec1)
-+#  define FILESPEC2 ((char *) filespec2)
-+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
-+
-+    if (!filespec1)
-+        filespec1 = "";
-+    if (!filespec2)
-+        filespec2 = "";
-+    filespec1len = strlen(filespec1);
-+    filespec2len = strlen(filespec2);
-+
-+# if __INITIAL_POINTER_SIZE == 64
-+    /* Copy the file names to storage with a 32-bit pointer. */
-+    filespec1_32p = filespec1_32;
-+    filespec2_32p = filespec2_32;
-+    strcpy(filespec1_32p, filespec1);
-+    strcpy(filespec2_32p, filespec2);
-+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
-+
-+    fab = cc$rms_fab;
-+    nam = CC_RMS_NAMX;
-+
-+    FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNA = FILESPEC1;
-+    FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNS = filespec1len;
-+    FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNA = FILESPEC2;
-+    FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNS = filespec2len;
-+    NAMX_DNA_FNA_SET(fab)
-+
-+        nam.NAMX_ESA = esa;
-+    nam.NAMX_ESS = NAMX_MAXRSS;
-+    nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD;
-+    SET_NAMX_NO_SHORT_UPCASE(nam);
-+
-+    fab.FAB_NAMX = &nam;
-+
-+    status = sys$parse(&fab, 0, 0);
-+
-+    if (!$VMS_STATUS_SUCCESS(status)) {
-+        unsigned short length;
-+        char errstring[257];
-+        struct dsc$descriptor_s errstring_dsc;
-+
-+        errstring_dsc.dsc$w_length = sizeof(errstring);
-+        errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
-+        errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
-+        errstring_dsc.dsc$a_pointer = errstring;
-+
-+        status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
-+
-+        if (!$VMS_STATUS_SUCCESS(status))
-+            lib$signal(status); /* This is really bad.  Abort! */
-+        else {
-+            errstring[length] = '\0';
-+
-+            DSOerr(DSO_F_VMS_MERGER, DSO_R_FAILURE);
-+            ERR_add_error_data(7,
-+                               "filespec \"", filespec1, "\", ",
-+                               "defaults \"", filespec2, "\": ", errstring);
-+        }
-+        return (NULL);
-+    }
-+
-+    merged = OPENSSL_malloc(nam.NAMX_ESL + 1);
-+    if (merged == NULL)
-+        goto malloc_err;
-+    strncpy(merged, nam.NAMX_ESA, nam.NAMX_ESL);
-+    merged[nam.NAMX_ESL] = '\0';
-+    return (merged);
-+ malloc_err:
-+    DSOerr(DSO_F_VMS_MERGER, ERR_R_MALLOC_FAILURE);
-+}
-+
-+static char *vms_name_converter(DSO *dso, const char *filename)
-+{
-+    int len = strlen(filename);
-+    char *not_translated = OPENSSL_malloc(len + 1);
-+    if (not_translated != NULL)
-+        strcpy(not_translated, filename);
-+    return (not_translated);
-+}
-+
-+#endif                          /* OPENSSL_SYS_VMS */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_win32.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_win32.c
-new file mode 100644
-index 0000000..4a4c34a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/dso/dso_win32.c
-@@ -0,0 +1,573 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "dso_locl.h"
-+
-+#if defined(DSO_WIN32)
-+
-+# ifdef _WIN32_WCE
-+#  if _WIN32_WCE < 300
-+static FARPROC GetProcAddressA(HMODULE hModule, LPCSTR lpProcName)
-+{
-+    WCHAR lpProcNameW[64];
-+    int i;
-+
-+    for (i = 0; lpProcName[i] && i < 64; i++)
-+        lpProcNameW[i] = (WCHAR)lpProcName[i];
-+    if (i == 64)
-+        return NULL;
-+    lpProcNameW[i] = 0;
-+
-+    return GetProcAddressW(hModule, lpProcNameW);
-+}
-+#  endif
-+#  undef GetProcAddress
-+#  define GetProcAddress GetProcAddressA
-+
-+static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
-+{
-+    WCHAR *fnamw;
-+    size_t len_0 = strlen(lpLibFileName) + 1, i;
-+
-+#  ifdef _MSC_VER
-+    fnamw = (WCHAR *)_alloca(len_0 * sizeof(WCHAR));
-+#  else
-+    fnamw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
-+#  endif
-+    if (fnamw == NULL) {
-+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-+        return NULL;
-+    }
-+#  if defined(_WIN32_WCE) && _WIN32_WCE>=101
-+    if (!MultiByteToWideChar(CP_ACP, 0, lpLibFileName, len_0, fnamw, len_0))
-+#  endif
-+        for (i = 0; i < len_0; i++)
-+            fnamw[i] = (WCHAR)lpLibFileName[i];
-+
-+    return LoadLibraryW(fnamw);
-+}
-+# endif
-+
-+/* Part of the hack in "win32_load" ... */
-+# define DSO_MAX_TRANSLATED_SIZE 256
-+
-+static int win32_load(DSO *dso);
-+static int win32_unload(DSO *dso);
-+static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
-+static char *win32_name_converter(DSO *dso, const char *filename);
-+static char *win32_merger(DSO *dso, const char *filespec1,
-+                          const char *filespec2);
-+static void *win32_globallookup(const char *name);
-+
-+static const char *openssl_strnchr(const char *string, int c, size_t len);
-+
-+static DSO_METHOD dso_meth_win32 = {
-+    "OpenSSL 'win32' shared library method",
-+    win32_load,
-+    win32_unload,
-+    win32_bind_func,
-+    NULL,                       /* ctrl */
-+    win32_name_converter,
-+    win32_merger,
-+    NULL,                       /* init */
-+    NULL,                       /* finish */
-+    NULL,                       /* pathbyaddr */
-+    win32_globallookup
-+};
-+
-+DSO_METHOD *DSO_METHOD_openssl(void)
-+{
-+    return &dso_meth_win32;
-+}
-+
-+/*
-+ * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to
-+ * the handle (HINSTANCE) returned from LoadLibrary(), and copied.
-+ */
-+
-+static int win32_load(DSO *dso)
-+{
-+    HINSTANCE h = NULL, *p = NULL;
-+    /* See applicable comments from dso_dl.c */
-+    char *filename = DSO_convert_filename(dso, NULL);
-+
-+    if (filename == NULL) {
-+        DSOerr(DSO_F_WIN32_LOAD, DSO_R_NO_FILENAME);
-+        goto err;
-+    }
-+    h = LoadLibraryA(filename);
-+    if (h == NULL) {
-+        DSOerr(DSO_F_WIN32_LOAD, DSO_R_LOAD_FAILED);
-+        ERR_add_error_data(3, "filename(", filename, ")");
-+        goto err;
-+    }
-+    p = OPENSSL_malloc(sizeof(*p));
-+    if (p == NULL) {
-+        DSOerr(DSO_F_WIN32_LOAD, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    *p = h;
-+    if (!sk_void_push(dso->meth_data, p)) {
-+        DSOerr(DSO_F_WIN32_LOAD, DSO_R_STACK_ERROR);
-+        goto err;
-+    }
-+    /* Success */
-+    dso->loaded_filename = filename;
-+    return (1);
-+ err:
-+    /* Cleanup ! */
-+    OPENSSL_free(filename);
-+    OPENSSL_free(p);
-+    if (h != NULL)
-+        FreeLibrary(h);
-+    return (0);
-+}
-+
-+static int win32_unload(DSO *dso)
-+{
-+    HINSTANCE *p;
-+    if (dso == NULL) {
-+        DSOerr(DSO_F_WIN32_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
-+        return (0);
-+    }
-+    if (sk_void_num(dso->meth_data) < 1)
-+        return (1);
-+    p = sk_void_pop(dso->meth_data);
-+    if (p == NULL) {
-+        DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_NULL_HANDLE);
-+        return (0);
-+    }
-+    if (!FreeLibrary(*p)) {
-+        DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_UNLOAD_FAILED);
-+        /*
-+         * We should push the value back onto the stack in case of a retry.
-+         */
-+        sk_void_push(dso->meth_data, p);
-+        return (0);
-+    }
-+    /* Cleanup */
-+    OPENSSL_free(p);
-+    return (1);
-+}
-+
-+static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
-+{
-+    HINSTANCE *ptr;
-+    union {
-+        void *p;
-+        FARPROC f;
-+    } sym;
-+
-+    if ((dso == NULL) || (symname == NULL)) {
-+        DSOerr(DSO_F_WIN32_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    if (sk_void_num(dso->meth_data) < 1) {
-+        DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_STACK_ERROR);
-+        return (NULL);
-+    }
-+    ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
-+    if (ptr == NULL) {
-+        DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_NULL_HANDLE);
-+        return (NULL);
-+    }
-+    sym.f = GetProcAddress(*ptr, symname);
-+    if (sym.p == NULL) {
-+        DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_SYM_FAILURE);
-+        ERR_add_error_data(3, "symname(", symname, ")");
-+        return (NULL);
-+    }
-+    return ((DSO_FUNC_TYPE)sym.f);
-+}
-+
-+struct file_st {
-+    const char *node;
-+    int nodelen;
-+    const char *device;
-+    int devicelen;
-+    const char *predir;
-+    int predirlen;
-+    const char *dir;
-+    int dirlen;
-+    const char *file;
-+    int filelen;
-+};
-+
-+static struct file_st *win32_splitter(DSO *dso, const char *filename,
-+                                      int assume_last_is_dir)
-+{
-+    struct file_st *result = NULL;
-+    enum { IN_NODE, IN_DEVICE, IN_FILE } position;
-+    const char *start = filename;
-+    char last;
-+
-+    if (!filename) {
-+        DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_NO_FILENAME);
-+        /*
-+         * goto err;
-+         */
-+        return (NULL);
-+    }
-+
-+    result = OPENSSL_zalloc(sizeof(*result));
-+    if (result == NULL) {
-+        DSOerr(DSO_F_WIN32_SPLITTER, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+
-+    position = IN_DEVICE;
-+
-+    if ((filename[0] == '\\' && filename[1] == '\\')
-+        || (filename[0] == '/' && filename[1] == '/')) {
-+        position = IN_NODE;
-+        filename += 2;
-+        start = filename;
-+        result->node = start;
-+    }
-+
-+    do {
-+        last = filename[0];
-+        switch (last) {
-+        case ':':
-+            if (position != IN_DEVICE) {
-+                DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_INCORRECT_FILE_SYNTAX);
-+                /*
-+                 * goto err;
-+                 */
-+                OPENSSL_free(result);
-+                return (NULL);
-+            }
-+            result->device = start;
-+            result->devicelen = (int)(filename - start);
-+            position = IN_FILE;
-+            start = ++filename;
-+            result->dir = start;
-+            break;
-+        case '\\':
-+        case '/':
-+            if (position == IN_NODE) {
-+                result->nodelen = (int)(filename - start);
-+                position = IN_FILE;
-+                start = ++filename;
-+                result->dir = start;
-+            } else if (position == IN_DEVICE) {
-+                position = IN_FILE;
-+                filename++;
-+                result->dir = start;
-+                result->dirlen = (int)(filename - start);
-+                start = filename;
-+            } else {
-+                filename++;
-+                result->dirlen += (int)(filename - start);
-+                start = filename;
-+            }
-+            break;
-+        case '\0':
-+            if (position == IN_NODE) {
-+                result->nodelen = (int)(filename - start);
-+            } else {
-+                if (filename - start > 0) {
-+                    if (assume_last_is_dir) {
-+                        if (position == IN_DEVICE) {
-+                            result->dir = start;
-+                            result->dirlen = 0;
-+                        }
-+                        result->dirlen += (int)(filename - start);
-+                    } else {
-+                        result->file = start;
-+                        result->filelen = (int)(filename - start);
-+                    }
-+                }
-+            }
-+            break;
-+        default:
-+            filename++;
-+            break;
-+        }
-+    }
-+    while (last);
-+
-+    if (!result->nodelen)
-+        result->node = NULL;
-+    if (!result->devicelen)
-+        result->device = NULL;
-+    if (!result->dirlen)
-+        result->dir = NULL;
-+    if (!result->filelen)
-+        result->file = NULL;
-+
-+    return (result);
-+}
-+
-+static char *win32_joiner(DSO *dso, const struct file_st *file_split)
-+{
-+    int len = 0, offset = 0;
-+    char *result = NULL;
-+    const char *start;
-+
-+    if (!file_split) {
-+        DSOerr(DSO_F_WIN32_JOINER, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    if (file_split->node) {
-+        len += 2 + file_split->nodelen; /* 2 for starting \\ */
-+        if (file_split->predir || file_split->dir || file_split->file)
-+            len++;              /* 1 for ending \ */
-+    } else if (file_split->device) {
-+        len += file_split->devicelen + 1; /* 1 for ending : */
-+    }
-+    len += file_split->predirlen;
-+    if (file_split->predir && (file_split->dir || file_split->file)) {
-+        len++;                  /* 1 for ending \ */
-+    }
-+    len += file_split->dirlen;
-+    if (file_split->dir && file_split->file) {
-+        len++;                  /* 1 for ending \ */
-+    }
-+    len += file_split->filelen;
-+
-+    if (!len) {
-+        DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE);
-+        return (NULL);
-+    }
-+
-+    result = OPENSSL_malloc(len + 1);
-+    if (result == NULL) {
-+        DSOerr(DSO_F_WIN32_JOINER, ERR_R_MALLOC_FAILURE);
-+        return (NULL);
-+    }
-+
-+    if (file_split->node) {
-+        strcpy(&result[offset], "\\\\");
-+        offset += 2;
-+        strncpy(&result[offset], file_split->node, file_split->nodelen);
-+        offset += file_split->nodelen;
-+        if (file_split->predir || file_split->dir || file_split->file) {
-+            result[offset] = '\\';
-+            offset++;
-+        }
-+    } else if (file_split->device) {
-+        strncpy(&result[offset], file_split->device, file_split->devicelen);
-+        offset += file_split->devicelen;
-+        result[offset] = ':';
-+        offset++;
-+    }
-+    start = file_split->predir;
-+    while (file_split->predirlen > (start - file_split->predir)) {
-+        const char *end = openssl_strnchr(start, '/',
-+                                          file_split->predirlen - (start -
-+                                                                   file_split->predir));
-+        if (!end)
-+            end = start
-+                + file_split->predirlen - (start - file_split->predir);
-+        strncpy(&result[offset], start, end - start);
-+        offset += (int)(end - start);
-+        result[offset] = '\\';
-+        offset++;
-+        start = end + 1;
-+    }
-+    start = file_split->dir;
-+    while (file_split->dirlen > (start - file_split->dir)) {
-+        const char *end = openssl_strnchr(start, '/',
-+                                          file_split->dirlen - (start -
-+                                                                file_split->dir));
-+        if (!end)
-+            end = start + file_split->dirlen - (start - file_split->dir);
-+        strncpy(&result[offset], start, end - start);
-+        offset += (int)(end - start);
-+        result[offset] = '\\';
-+        offset++;
-+        start = end + 1;
-+    }
-+    strncpy(&result[offset], file_split->file, file_split->filelen);
-+    offset += file_split->filelen;
-+    result[offset] = '\0';
-+    return (result);
-+}
-+
-+static char *win32_merger(DSO *dso, const char *filespec1,
-+                          const char *filespec2)
-+{
-+    char *merged = NULL;
-+    struct file_st *filespec1_split = NULL;
-+    struct file_st *filespec2_split = NULL;
-+
-+    if (!filespec1 && !filespec2) {
-+        DSOerr(DSO_F_WIN32_MERGER, ERR_R_PASSED_NULL_PARAMETER);
-+        return (NULL);
-+    }
-+    if (!filespec2) {
-+        merged = OPENSSL_malloc(strlen(filespec1) + 1);
-+        if (merged == NULL) {
-+            DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
-+            return (NULL);
-+        }
-+        strcpy(merged, filespec1);
-+    } else if (!filespec1) {
-+        merged = OPENSSL_malloc(strlen(filespec2) + 1);
-+        if (merged == NULL) {
-+            DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
-+            return (NULL);
-+        }
-+        strcpy(merged, filespec2);
-+    } else {
-+        filespec1_split = win32_splitter(dso, filespec1, 0);
-+        if (!filespec1_split) {
-+            DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
-+            return (NULL);
-+        }
-+        filespec2_split = win32_splitter(dso, filespec2, 1);
-+        if (!filespec2_split) {
-+            DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
-+            OPENSSL_free(filespec1_split);
-+            return (NULL);
-+        }
-+
-+        /* Fill in into filespec1_split */
-+        if (!filespec1_split->node && !filespec1_split->device) {
-+            filespec1_split->node = filespec2_split->node;
-+            filespec1_split->nodelen = filespec2_split->nodelen;
-+            filespec1_split->device = filespec2_split->device;
-+            filespec1_split->devicelen = filespec2_split->devicelen;
-+        }
-+        if (!filespec1_split->dir) {
-+            filespec1_split->dir = filespec2_split->dir;
-+            filespec1_split->dirlen = filespec2_split->dirlen;
-+        } else if (filespec1_split->dir[0] != '\\'
-+                   && filespec1_split->dir[0] != '/') {
-+            filespec1_split->predir = filespec2_split->dir;
-+            filespec1_split->predirlen = filespec2_split->dirlen;
-+        }
-+        if (!filespec1_split->file) {
-+            filespec1_split->file = filespec2_split->file;
-+            filespec1_split->filelen = filespec2_split->filelen;
-+        }
-+
-+        merged = win32_joiner(dso, filespec1_split);
-+    }
-+    OPENSSL_free(filespec1_split);
-+    OPENSSL_free(filespec2_split);
-+    return (merged);
-+}
-+
-+static char *win32_name_converter(DSO *dso, const char *filename)
-+{
-+    char *translated;
-+    int len, transform;
-+
-+    len = strlen(filename);
-+    transform = ((strstr(filename, "/") == NULL) &&
-+                 (strstr(filename, "\\") == NULL) &&
-+                 (strstr(filename, ":") == NULL));
-+    if (transform)
-+        /* We will convert this to "%s.dll" */
-+        translated = OPENSSL_malloc(len + 5);
-+    else
-+        /* We will simply duplicate filename */
-+        translated = OPENSSL_malloc(len + 1);
-+    if (translated == NULL) {
-+        DSOerr(DSO_F_WIN32_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
-+        return (NULL);
-+    }
-+    if (transform)
-+        sprintf(translated, "%s.dll", filename);
-+    else
-+        sprintf(translated, "%s", filename);
-+    return (translated);
-+}
-+
-+static const char *openssl_strnchr(const char *string, int c, size_t len)
-+{
-+    size_t i;
-+    const char *p;
-+    for (i = 0, p = string; i < len && *p; i++, p++) {
-+        if (*p == c)
-+            return p;
-+    }
-+    return NULL;
-+}
-+
-+# include 
-+# ifdef _WIN32_WCE
-+#  define DLLNAME "TOOLHELP.DLL"
-+# else
-+#  ifdef MODULEENTRY32
-+#   undef MODULEENTRY32         /* unmask the ASCII version! */
-+#  endif
-+#  define DLLNAME "KERNEL32.DLL"
-+# endif
-+
-+typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD);
-+typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE);
-+typedef BOOL(WINAPI *MODULE32) (HANDLE, MODULEENTRY32 *);
-+
-+static void *win32_globallookup(const char *name)
-+{
-+    HMODULE dll;
-+    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
-+    MODULEENTRY32 me32;
-+    CREATETOOLHELP32SNAPSHOT create_snap;
-+    CLOSETOOLHELP32SNAPSHOT close_snap;
-+    MODULE32 module_first, module_next;
-+    union {
-+        void *p;
-+        FARPROC f;
-+    } ret = { NULL };
-+
-+    dll = LoadLibrary(TEXT(DLLNAME));
-+    if (dll == NULL) {
-+        DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED);
-+        return NULL;
-+    }
-+
-+    create_snap = (CREATETOOLHELP32SNAPSHOT)
-+        GetProcAddress(dll, "CreateToolhelp32Snapshot");
-+    if (create_snap == NULL) {
-+        FreeLibrary(dll);
-+        DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED);
-+        return NULL;
-+    }
-+    /* We take the rest for granted... */
-+# ifdef _WIN32_WCE
-+    close_snap = (CLOSETOOLHELP32SNAPSHOT)
-+        GetProcAddress(dll, "CloseToolhelp32Snapshot");
-+# else
-+    close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle;
-+# endif
-+    module_first = (MODULE32) GetProcAddress(dll, "Module32First");
-+    module_next = (MODULE32) GetProcAddress(dll, "Module32Next");
-+
-+    hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0);
-+    if (hModuleSnap == INVALID_HANDLE_VALUE) {
-+        FreeLibrary(dll);
-+        DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED);
-+        return NULL;
-+    }
-+
-+    me32.dwSize = sizeof(me32);
-+
-+    if (!(*module_first) (hModuleSnap, &me32)) {
-+        (*close_snap) (hModuleSnap);
-+        FreeLibrary(dll);
-+        return NULL;
-+    }
-+
-+    do {
-+        if ((ret.f = GetProcAddress(me32.hModule, name))) {
-+            (*close_snap) (hModuleSnap);
-+            FreeLibrary(dll);
-+            return ret.p;
-+        }
-+    } while ((*module_next) (hModuleSnap, &me32));
-+
-+    (*close_snap) (hModuleSnap);
-+    FreeLibrary(dll);
-+    return NULL;
-+}
-+#endif                          /* DSO_WIN32 */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ebcdic.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ebcdic.c
-new file mode 100644
-index 0000000..6871953
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ebcdic.c
-@@ -0,0 +1,366 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+# include 
-+#ifndef CHARSET_EBCDIC
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+
-+/*-
-+ *      Initial Port for  Apache-1.3     by 
-+ *      Adapted for       OpenSSL-0.9.4  by 
-+ */
-+
-+# ifdef CHARSET_EBCDIC_TEST
-+/*
-+ * Here we're looking to test the EBCDIC code on an ASCII system so we don't do
-+ * any translation in these tables at all.
-+ */
-+
-+/* The ebcdic-to-ascii table: */
-+const unsigned char os_toascii[256] = {
-+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
-+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
-+    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
-+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
-+    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-+    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
-+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
-+    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
-+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
-+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
-+    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
-+    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
-+    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
-+    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
-+    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
-+    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
-+    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
-+    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
-+    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
-+    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
-+    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
-+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
-+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
-+};
-+
-+/* The ascii-to-ebcdic table: */
-+const unsigned char os_toebcdic[256] = {
-+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
-+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
-+    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
-+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
-+    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-+    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
-+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
-+    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
-+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
-+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
-+    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
-+    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
-+    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
-+    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
-+    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
-+    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
-+    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
-+    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
-+    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
-+    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
-+    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
-+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
-+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
-+};
-+
-+# elif defined(_OSD_POSIX)
-+/*
-+ * "BS2000 OSD" is a POSIX subsystem on a main frame. It is made by Siemens
-+ * AG, Germany, for their BS2000 mainframe machines. Within the POSIX
-+ * subsystem, the same character set was chosen as in "native BS2000", namely
-+ * EBCDIC. (EDF04)
-+ *
-+ * The name "ASCII" in these routines is misleading: actually, conversion is
-+ * not between EBCDIC and ASCII, but EBCDIC(EDF04) and ISO-8859.1; that means
-+ * that (western european) national characters are preserved.
-+ *
-+ * This table is identical to the one used by rsh/rcp/ftp and other POSIX
-+ * tools.
-+ */
-+
-+/* Here's the bijective ebcdic-to-ascii table: */
-+const unsigned char os_toascii[256] = {
-+    /*
-+     * 00
-+     */ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,
-+    0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
-+    /*
-+     * 10
-+     */ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97,
-+    0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
-+    /*
-+     * 20
-+     */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b,
-+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */
-+    /*
-+     * 30
-+     */ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
-+    0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */
-+    /*
-+     * 40
-+     */ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
-+    0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+| */
-+    /*
-+     * 50
-+     */ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
-+    0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /* &.........!$*);. */
-+    /*
-+     * 60
-+     */ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
-+    0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,    /*-/........^,%_>?*/
-+    /*
-+     * 70
-+     */ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
-+    0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* ..........:#@'=" */
-+    /*
-+     * 80
-+     */ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-+    0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */
-+    /*
-+     * 90
-+     */ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
-+    0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */
-+    /*
-+     * a0
-+     */ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-+    0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /* ..stuvwxyz...... */
-+    /*
-+     * b0
-+     */ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
-+    0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /* ...........[\].. */
-+    /*
-+     * c0
-+     */ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
-+    0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* .ABCDEFGHI...... */
-+    /*
-+     * d0
-+     */ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
-+    0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /* .JKLMNOPQR...... */
-+    /*
-+     * e0
-+     */ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
-+    0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* ..STUVWXYZ...... */
-+    /*
-+     * f0
-+     */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-+    0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /* 0123456789.{.}.~ */
-+};
-+
-+/* The ascii-to-ebcdic table: */
-+const unsigned char os_toebcdic[256] = {
-+    /*
-+     * 00
-+     */ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
-+    0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
-+    /*
-+     * 10
-+     */ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
-+    0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
-+    /*
-+     * 20
-+     */ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
-+    0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */
-+    /*
-+     * 30
-+     */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
-+    0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */
-+    /*
-+     * 40
-+     */ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
-+    0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */
-+    /*
-+     * 50
-+     */ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
-+    0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d, /* PQRSTUVWXYZ[\]^_ */
-+    /*
-+     * 60
-+     */ 0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-+    0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */
-+    /*
-+     * 70
-+     */ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
-+    0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07, /* pqrstuvwxyz{|}~. */
-+    /*
-+     * 80
-+     */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08,
-+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */
-+    /*
-+     * 90
-+     */ 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17,
-+    0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f, /* ................ */
-+    /*
-+     * a0
-+     */ 0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5,
-+    0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1, /* ................ */
-+    /*
-+     * b0
-+     */ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
-+    0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */
-+    /*
-+     * c0
-+     */ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
-+    0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */
-+    /*
-+     * d0
-+     */ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
-+    0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59, /* ................ */
-+    /*
-+     * e0
-+     */ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
-+    0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */
-+    /*
-+     * f0
-+     */ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
-+    0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */
-+};
-+
-+# else /*_OSD_POSIX*/
-+
-+/*
-+ * This code does basic character mapping for IBM's TPF and OS/390 operating
-+ * systems. It is a modified version of the BS2000 table.
-+ *
-+ * Bijective EBCDIC (character set IBM-1047) to US-ASCII table: This table is
-+ * bijective - there are no ambiguous or duplicate characters.
-+ */
-+const unsigned char os_toascii[256] = {
-+    0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f: */
-+    0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
-+    0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f: */
-+    0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
-+    0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f: */
-+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */
-+    0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f: */
-+    0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */
-+    0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f: */
-+    0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* ...........<(+| */
-+    0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f: */
-+    0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */
-+    0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f: */
-+    0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */
-+    0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f: */
-+    0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */
-+    0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f: */
-+    0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */
-+    0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f: */
-+    0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */
-+    0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af: */
-+    0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */
-+    0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf: */
-+    0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */
-+    0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf: */
-+    0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */
-+    0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df: */
-+    0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */
-+    0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef: */
-+    0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */
-+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff: */
-+    0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f /* 0123456789...... */
-+};
-+
-+/*
-+ * The US-ASCII to EBCDIC (character set IBM-1047) table: This table is
-+ * bijective (no ambiguous or duplicate characters)
-+ */
-+const unsigned char os_toebcdic[256] = {
-+    0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, /* 00-0f: */
-+    0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
-+    0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, /* 10-1f: */
-+    0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
-+    0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, /* 20-2f: */
-+    0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */
-+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 30-3f: */
-+    0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */
-+    0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 40-4f: */
-+    0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */
-+    0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, /* 50-5f: */
-+    0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d, /* PQRSTUVWXYZ[\]^_ */
-+    0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60-6f: */
-+    0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */
-+    0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 70-7f: */
-+    0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, /* pqrstuvwxyz{|}~. */
-+    0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, /* 80-8f: */
-+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */
-+    0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, /* 90-9f: */
-+    0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0xff, /* ................ */
-+    0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, /* a0-af: */
-+    0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc, /* ................ */
-+    0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, /* b0-bf: */
-+    0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */
-+    0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, /* c0-cf: */
-+    0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */
-+    0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, /* d0-df: */
-+    0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59, /* ................ */
-+    0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, /* e0-ef: */
-+    0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */
-+    0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, /* f0-ff: */
-+    0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */
-+};
-+# endif/*_OSD_POSIX*/
-+
-+/*
-+ * Translate a memory block from EBCDIC (host charset) to ASCII (net charset)
-+ * dest and srce may be identical, or separate memory blocks, but should not
-+ * overlap. These functions intentionally have an interface compatible to
-+ * memcpy(3).
-+ */
-+
-+void *ebcdic2ascii(void *dest, const void *srce, size_t count)
-+{
-+    unsigned char *udest = dest;
-+    const unsigned char *usrce = srce;
-+
-+    while (count-- != 0) {
-+        *udest++ = os_toascii[*usrce++];
-+    }
-+
-+    return dest;
-+}
-+
-+void *ascii2ebcdic(void *dest, const void *srce, size_t count)
-+{
-+    unsigned char *udest = dest;
-+    const unsigned char *usrce = srce;
-+
-+    while (count-- != 0) {
-+        *udest++ = os_toebcdic[*usrce++];
-+    }
-+
-+    return dest;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-armv4.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-armv4.pl
-new file mode 100755
-index 0000000..2314b75
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-armv4.pl
-@@ -0,0 +1,1865 @@
-+#! /usr/bin/env perl
-+# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# ECP_NISTZ256 module for ARMv4.
-+#
-+# October 2014.
-+#
-+# Original ECP_NISTZ256 submission targeting x86_64 is detailed in
-+# http://eprint.iacr.org/2013/816. In the process of adaptation
-+# original .c module was made 32-bit savvy in order to make this
-+# implementation possible.
-+#
-+#			with/without -DECP_NISTZ256_ASM
-+# Cortex-A8		+53-170%
-+# Cortex-A9		+76-205%
-+# Cortex-A15		+100-316%
-+# Snapdragon S4		+66-187%
-+#
-+# Ranges denote minimum and maximum improvement coefficients depending
-+# on benchmark. Lower coefficients are for ECDSA sign, server-side
-+# operation. Keep in mind that +200% means 3x improvement.
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+$code.=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+#if defined(__thumb2__)
-+.syntax	unified
-+.thumb
-+#else
-+.code	32
-+#endif
-+___
-+########################################################################
-+# Convert ecp_nistz256_table.c to layout expected by ecp_nistz_gather_w7
-+#
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+open TABLE,") {
-+	s/TOBN\(\s*(0x[0-9a-f]+),\s*(0x[0-9a-f]+)\s*\)/push @arr,hex($2),hex($1)/geo;
-+}
-+close TABLE;
-+
-+# See ecp_nistz256_table.c for explanation for why it's 64*16*37.
-+# 64*16*37-1 is because $#arr returns last valid index or @arr, not
-+# amount of elements.
-+die "insane number of elements" if ($#arr != 64*16*37-1);
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_precomputed
-+.type	ecp_nistz256_precomputed,%object
-+.align	12
-+ecp_nistz256_precomputed:
-+___
-+########################################################################
-+# this conversion smashes P256_POINT_AFFINE by individual bytes with
-+# 64 byte interval, similar to
-+#	1111222233334444
-+#	1234123412341234
-+for(1..37) {
-+	@tbl = splice(@arr,0,64*16);
-+	for($i=0;$i<64;$i++) {
-+		undef @line;
-+		for($j=0;$j<64;$j++) {
-+			push @line,(@tbl[$j*16+$i/4]>>(($i%4)*8))&0xff;
-+		}
-+		$code.=".byte\t";
-+		$code.=join(',',map { sprintf "0x%02x",$_} @line);
-+		$code.="\n";
-+	}
-+}
-+$code.=<<___;
-+.size	ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
-+.align	5
-+.LRR:	@ 2^512 mod P precomputed for NIST P256 polynomial
-+.long	0x00000003, 0x00000000, 0xffffffff, 0xfffffffb
-+.long	0xfffffffe, 0xffffffff, 0xfffffffd, 0x00000004
-+.Lone:
-+.long	1,0,0,0,0,0,0,0
-+.asciz	"ECP_NISTZ256 for ARMv4, CRYPTOGAMS by "
-+.align	6
-+___
-+
-+########################################################################
-+# common register layout, note that $t2 is link register, so that if
-+# internal subroutine uses $t2, then it has to offload lr...
-+
-+($r_ptr,$a_ptr,$b_ptr,$ff,$a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$t1,$t2)=
-+		map("r$_",(0..12,14));
-+($t0,$t3)=($ff,$a_ptr);
-+
-+$code.=<<___;
-+@ void	ecp_nistz256_to_mont(BN_ULONG r0[8],const BN_ULONG r1[8]);
-+.globl	ecp_nistz256_to_mont
-+.type	ecp_nistz256_to_mont,%function
-+ecp_nistz256_to_mont:
-+	adr	$b_ptr,.LRR
-+	b	.Lecp_nistz256_mul_mont
-+.size	ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
-+
-+@ void	ecp_nistz256_from_mont(BN_ULONG r0[8],const BN_ULONG r1[8]);
-+.globl	ecp_nistz256_from_mont
-+.type	ecp_nistz256_from_mont,%function
-+ecp_nistz256_from_mont:
-+	adr	$b_ptr,.Lone
-+	b	.Lecp_nistz256_mul_mont
-+.size	ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
-+
-+@ void	ecp_nistz256_mul_by_2(BN_ULONG r0[8],const BN_ULONG r1[8]);
-+.globl	ecp_nistz256_mul_by_2
-+.type	ecp_nistz256_mul_by_2,%function
-+.align	4
-+ecp_nistz256_mul_by_2:
-+	stmdb	sp!,{r4-r12,lr}
-+	bl	__ecp_nistz256_mul_by_2
-+#if __ARM_ARCH__>=5 || !defined(__thumb__)
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
-+
-+.type	__ecp_nistz256_mul_by_2,%function
-+.align	4
-+__ecp_nistz256_mul_by_2:
-+	ldr	$a0,[$a_ptr,#0]
-+	ldr	$a1,[$a_ptr,#4]
-+	ldr	$a2,[$a_ptr,#8]
-+	adds	$a0,$a0,$a0		@ a[0:7]+=a[0:7], i.e. add with itself
-+	ldr	$a3,[$a_ptr,#12]
-+	adcs	$a1,$a1,$a1
-+	ldr	$a4,[$a_ptr,#16]
-+	adcs	$a2,$a2,$a2
-+	ldr	$a5,[$a_ptr,#20]
-+	adcs	$a3,$a3,$a3
-+	ldr	$a6,[$a_ptr,#24]
-+	adcs	$a4,$a4,$a4
-+	ldr	$a7,[$a_ptr,#28]
-+	adcs	$a5,$a5,$a5
-+	adcs	$a6,$a6,$a6
-+	mov	$ff,#0
-+	adcs	$a7,$a7,$a7
-+	adc	$ff,$ff,#0
-+
-+	b	.Lreduce_by_sub
-+.size	__ecp_nistz256_mul_by_2,.-__ecp_nistz256_mul_by_2
-+
-+@ void	ecp_nistz256_add(BN_ULONG r0[8],const BN_ULONG r1[8],
-+@					const BN_ULONG r2[8]);
-+.globl	ecp_nistz256_add
-+.type	ecp_nistz256_add,%function
-+.align	4
-+ecp_nistz256_add:
-+	stmdb	sp!,{r4-r12,lr}
-+	bl	__ecp_nistz256_add
-+#if __ARM_ARCH__>=5 || !defined(__thumb__)
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	ecp_nistz256_add,.-ecp_nistz256_add
-+
-+.type	__ecp_nistz256_add,%function
-+.align	4
-+__ecp_nistz256_add:
-+	str	lr,[sp,#-4]!		@ push lr
-+
-+	ldr	$a0,[$a_ptr,#0]
-+	ldr	$a1,[$a_ptr,#4]
-+	ldr	$a2,[$a_ptr,#8]
-+	ldr	$a3,[$a_ptr,#12]
-+	ldr	$a4,[$a_ptr,#16]
-+	 ldr	$t0,[$b_ptr,#0]
-+	ldr	$a5,[$a_ptr,#20]
-+	 ldr	$t1,[$b_ptr,#4]
-+	ldr	$a6,[$a_ptr,#24]
-+	 ldr	$t2,[$b_ptr,#8]
-+	ldr	$a7,[$a_ptr,#28]
-+	 ldr	$t3,[$b_ptr,#12]
-+	adds	$a0,$a0,$t0
-+	 ldr	$t0,[$b_ptr,#16]
-+	adcs	$a1,$a1,$t1
-+	 ldr	$t1,[$b_ptr,#20]
-+	adcs	$a2,$a2,$t2
-+	 ldr	$t2,[$b_ptr,#24]
-+	adcs	$a3,$a3,$t3
-+	 ldr	$t3,[$b_ptr,#28]
-+	adcs	$a4,$a4,$t0
-+	adcs	$a5,$a5,$t1
-+	adcs	$a6,$a6,$t2
-+	mov	$ff,#0
-+	adcs	$a7,$a7,$t3
-+	adc	$ff,$ff,#0
-+	ldr	lr,[sp],#4		@ pop lr
-+
-+.Lreduce_by_sub:
-+
-+	@ if a+b >= modulus, subtract modulus.
-+	@
-+	@ But since comparison implies subtraction, we subtract
-+	@ modulus and then add it back if subraction borrowed.
-+
-+	subs	$a0,$a0,#-1
-+	sbcs	$a1,$a1,#-1
-+	sbcs	$a2,$a2,#-1
-+	sbcs	$a3,$a3,#0
-+	sbcs	$a4,$a4,#0
-+	sbcs	$a5,$a5,#0
-+	sbcs	$a6,$a6,#1
-+	sbcs	$a7,$a7,#-1
-+	sbc	$ff,$ff,#0
-+
-+	@ Note that because mod has special form, i.e. consists of
-+	@ 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	@ using value of borrow as a whole or extracting single bit.
-+	@ Follow $ff register...
-+
-+	adds	$a0,$a0,$ff		@ add synthesized modulus
-+	adcs	$a1,$a1,$ff
-+	str	$a0,[$r_ptr,#0]
-+	adcs	$a2,$a2,$ff
-+	str	$a1,[$r_ptr,#4]
-+	adcs	$a3,$a3,#0
-+	str	$a2,[$r_ptr,#8]
-+	adcs	$a4,$a4,#0
-+	str	$a3,[$r_ptr,#12]
-+	adcs	$a5,$a5,#0
-+	str	$a4,[$r_ptr,#16]
-+	adcs	$a6,$a6,$ff,lsr#31
-+	str	$a5,[$r_ptr,#20]
-+	adcs	$a7,$a7,$ff
-+	str	$a6,[$r_ptr,#24]
-+	str	$a7,[$r_ptr,#28]
-+
-+	mov	pc,lr
-+.size	__ecp_nistz256_add,.-__ecp_nistz256_add
-+
-+@ void	ecp_nistz256_mul_by_3(BN_ULONG r0[8],const BN_ULONG r1[8]);
-+.globl	ecp_nistz256_mul_by_3
-+.type	ecp_nistz256_mul_by_3,%function
-+.align	4
-+ecp_nistz256_mul_by_3:
-+	stmdb	sp!,{r4-r12,lr}
-+	bl	__ecp_nistz256_mul_by_3
-+#if __ARM_ARCH__>=5 || !defined(__thumb__)
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
-+
-+.type	__ecp_nistz256_mul_by_3,%function
-+.align	4
-+__ecp_nistz256_mul_by_3:
-+	str	lr,[sp,#-4]!		@ push lr
-+
-+	@ As multiplication by 3 is performed as 2*n+n, below are inline
-+	@ copies of __ecp_nistz256_mul_by_2 and __ecp_nistz256_add, see
-+	@ corresponding subroutines for details.
-+
-+	ldr	$a0,[$a_ptr,#0]
-+	ldr	$a1,[$a_ptr,#4]
-+	ldr	$a2,[$a_ptr,#8]
-+	adds	$a0,$a0,$a0		@ a[0:7]+=a[0:7]
-+	ldr	$a3,[$a_ptr,#12]
-+	adcs	$a1,$a1,$a1
-+	ldr	$a4,[$a_ptr,#16]
-+	adcs	$a2,$a2,$a2
-+	ldr	$a5,[$a_ptr,#20]
-+	adcs	$a3,$a3,$a3
-+	ldr	$a6,[$a_ptr,#24]
-+	adcs	$a4,$a4,$a4
-+	ldr	$a7,[$a_ptr,#28]
-+	adcs	$a5,$a5,$a5
-+	adcs	$a6,$a6,$a6
-+	mov	$ff,#0
-+	adcs	$a7,$a7,$a7
-+	adc	$ff,$ff,#0
-+
-+	subs	$a0,$a0,#-1		@ .Lreduce_by_sub but without stores
-+	sbcs	$a1,$a1,#-1
-+	sbcs	$a2,$a2,#-1
-+	sbcs	$a3,$a3,#0
-+	sbcs	$a4,$a4,#0
-+	sbcs	$a5,$a5,#0
-+	sbcs	$a6,$a6,#1
-+	sbcs	$a7,$a7,#-1
-+	sbc	$ff,$ff,#0
-+
-+	adds	$a0,$a0,$ff		@ add synthesized modulus
-+	adcs	$a1,$a1,$ff
-+	adcs	$a2,$a2,$ff
-+	adcs	$a3,$a3,#0
-+	adcs	$a4,$a4,#0
-+	 ldr	$b_ptr,[$a_ptr,#0]
-+	adcs	$a5,$a5,#0
-+	 ldr	$t1,[$a_ptr,#4]
-+	adcs	$a6,$a6,$ff,lsr#31
-+	 ldr	$t2,[$a_ptr,#8]
-+	adc	$a7,$a7,$ff
-+
-+	ldr	$t0,[$a_ptr,#12]
-+	adds	$a0,$a0,$b_ptr		@ 2*a[0:7]+=a[0:7]
-+	ldr	$b_ptr,[$a_ptr,#16]
-+	adcs	$a1,$a1,$t1
-+	ldr	$t1,[$a_ptr,#20]
-+	adcs	$a2,$a2,$t2
-+	ldr	$t2,[$a_ptr,#24]
-+	adcs	$a3,$a3,$t0
-+	ldr	$t3,[$a_ptr,#28]
-+	adcs	$a4,$a4,$b_ptr
-+	adcs	$a5,$a5,$t1
-+	adcs	$a6,$a6,$t2
-+	mov	$ff,#0
-+	adcs	$a7,$a7,$t3
-+	adc	$ff,$ff,#0
-+	ldr	lr,[sp],#4		@ pop lr
-+
-+	b	.Lreduce_by_sub
-+.size	ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
-+
-+@ void	ecp_nistz256_div_by_2(BN_ULONG r0[8],const BN_ULONG r1[8]);
-+.globl	ecp_nistz256_div_by_2
-+.type	ecp_nistz256_div_by_2,%function
-+.align	4
-+ecp_nistz256_div_by_2:
-+	stmdb	sp!,{r4-r12,lr}
-+	bl	__ecp_nistz256_div_by_2
-+#if __ARM_ARCH__>=5 || !defined(__thumb__)
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
-+
-+.type	__ecp_nistz256_div_by_2,%function
-+.align	4
-+__ecp_nistz256_div_by_2:
-+	@ ret = (a is odd ? a+mod : a) >> 1
-+
-+	ldr	$a0,[$a_ptr,#0]
-+	ldr	$a1,[$a_ptr,#4]
-+	ldr	$a2,[$a_ptr,#8]
-+	mov	$ff,$a0,lsl#31		@ place least significant bit to most
-+					@ significant position, now arithmetic
-+					@ right shift by 31 will produce -1 or
-+					@ 0, while logical right shift 1 or 0,
-+					@ this is how modulus is conditionally
-+					@ synthesized in this case...
-+	ldr	$a3,[$a_ptr,#12]
-+	adds	$a0,$a0,$ff,asr#31
-+	ldr	$a4,[$a_ptr,#16]
-+	adcs	$a1,$a1,$ff,asr#31
-+	ldr	$a5,[$a_ptr,#20]
-+	adcs	$a2,$a2,$ff,asr#31
-+	ldr	$a6,[$a_ptr,#24]
-+	adcs	$a3,$a3,#0
-+	ldr	$a7,[$a_ptr,#28]
-+	adcs	$a4,$a4,#0
-+	 mov	$a0,$a0,lsr#1		@ a[0:7]>>=1, we can start early
-+					@ because it doesn't affect flags
-+	adcs	$a5,$a5,#0
-+	 orr	$a0,$a0,$a1,lsl#31
-+	adcs	$a6,$a6,$ff,lsr#31
-+	mov	$b_ptr,#0
-+	adcs	$a7,$a7,$ff,asr#31
-+	 mov	$a1,$a1,lsr#1
-+	adc	$b_ptr,$b_ptr,#0	@ top-most carry bit from addition
-+
-+	orr	$a1,$a1,$a2,lsl#31
-+	mov	$a2,$a2,lsr#1
-+	str	$a0,[$r_ptr,#0]
-+	orr	$a2,$a2,$a3,lsl#31
-+	mov	$a3,$a3,lsr#1
-+	str	$a1,[$r_ptr,#4]
-+	orr	$a3,$a3,$a4,lsl#31
-+	mov	$a4,$a4,lsr#1
-+	str	$a2,[$r_ptr,#8]
-+	orr	$a4,$a4,$a5,lsl#31
-+	mov	$a5,$a5,lsr#1
-+	str	$a3,[$r_ptr,#12]
-+	orr	$a5,$a5,$a6,lsl#31
-+	mov	$a6,$a6,lsr#1
-+	str	$a4,[$r_ptr,#16]
-+	orr	$a6,$a6,$a7,lsl#31
-+	mov	$a7,$a7,lsr#1
-+	str	$a5,[$r_ptr,#20]
-+	orr	$a7,$a7,$b_ptr,lsl#31	@ don't forget the top-most carry bit
-+	str	$a6,[$r_ptr,#24]
-+	str	$a7,[$r_ptr,#28]
-+
-+	mov	pc,lr
-+.size	__ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2
-+
-+@ void	ecp_nistz256_sub(BN_ULONG r0[8],const BN_ULONG r1[8],
-+@				        const BN_ULONG r2[8]);
-+.globl	ecp_nistz256_sub
-+.type	ecp_nistz256_sub,%function
-+.align	4
-+ecp_nistz256_sub:
-+	stmdb	sp!,{r4-r12,lr}
-+	bl	__ecp_nistz256_sub
-+#if __ARM_ARCH__>=5 || !defined(__thumb__)
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	ecp_nistz256_sub,.-ecp_nistz256_sub
-+
-+.type	__ecp_nistz256_sub,%function
-+.align	4
-+__ecp_nistz256_sub:
-+	str	lr,[sp,#-4]!		@ push lr
-+
-+	ldr	$a0,[$a_ptr,#0]
-+	ldr	$a1,[$a_ptr,#4]
-+	ldr	$a2,[$a_ptr,#8]
-+	ldr	$a3,[$a_ptr,#12]
-+	ldr	$a4,[$a_ptr,#16]
-+	 ldr	$t0,[$b_ptr,#0]
-+	ldr	$a5,[$a_ptr,#20]
-+	 ldr	$t1,[$b_ptr,#4]
-+	ldr	$a6,[$a_ptr,#24]
-+	 ldr	$t2,[$b_ptr,#8]
-+	ldr	$a7,[$a_ptr,#28]
-+	 ldr	$t3,[$b_ptr,#12]
-+	subs	$a0,$a0,$t0
-+	 ldr	$t0,[$b_ptr,#16]
-+	sbcs	$a1,$a1,$t1
-+	 ldr	$t1,[$b_ptr,#20]
-+	sbcs	$a2,$a2,$t2
-+	 ldr	$t2,[$b_ptr,#24]
-+	sbcs	$a3,$a3,$t3
-+	 ldr	$t3,[$b_ptr,#28]
-+	sbcs	$a4,$a4,$t0
-+	sbcs	$a5,$a5,$t1
-+	sbcs	$a6,$a6,$t2
-+	sbcs	$a7,$a7,$t3
-+	sbc	$ff,$ff,$ff		@ broadcast borrow bit
-+	ldr	lr,[sp],#4		@ pop lr
-+
-+.Lreduce_by_add:
-+
-+	@ if a-b borrows, add modulus.
-+	@
-+	@ Note that because mod has special form, i.e. consists of
-+	@ 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	@ broadcasting borrow bit to a register, $ff, and using it as
-+	@ a whole or extracting single bit.
-+
-+	adds	$a0,$a0,$ff		@ add synthesized modulus
-+	adcs	$a1,$a1,$ff
-+	str	$a0,[$r_ptr,#0]
-+	adcs	$a2,$a2,$ff
-+	str	$a1,[$r_ptr,#4]
-+	adcs	$a3,$a3,#0
-+	str	$a2,[$r_ptr,#8]
-+	adcs	$a4,$a4,#0
-+	str	$a3,[$r_ptr,#12]
-+	adcs	$a5,$a5,#0
-+	str	$a4,[$r_ptr,#16]
-+	adcs	$a6,$a6,$ff,lsr#31
-+	str	$a5,[$r_ptr,#20]
-+	adcs	$a7,$a7,$ff
-+	str	$a6,[$r_ptr,#24]
-+	str	$a7,[$r_ptr,#28]
-+
-+	mov	pc,lr
-+.size	__ecp_nistz256_sub,.-__ecp_nistz256_sub
-+
-+@ void	ecp_nistz256_neg(BN_ULONG r0[8],const BN_ULONG r1[8]);
-+.globl	ecp_nistz256_neg
-+.type	ecp_nistz256_neg,%function
-+.align	4
-+ecp_nistz256_neg:
-+	stmdb	sp!,{r4-r12,lr}
-+	bl	__ecp_nistz256_neg
-+#if __ARM_ARCH__>=5 || !defined(__thumb__)
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	ecp_nistz256_neg,.-ecp_nistz256_neg
-+
-+.type	__ecp_nistz256_neg,%function
-+.align	4
-+__ecp_nistz256_neg:
-+	ldr	$a0,[$a_ptr,#0]
-+	eor	$ff,$ff,$ff
-+	ldr	$a1,[$a_ptr,#4]
-+	ldr	$a2,[$a_ptr,#8]
-+	subs	$a0,$ff,$a0
-+	ldr	$a3,[$a_ptr,#12]
-+	sbcs	$a1,$ff,$a1
-+	ldr	$a4,[$a_ptr,#16]
-+	sbcs	$a2,$ff,$a2
-+	ldr	$a5,[$a_ptr,#20]
-+	sbcs	$a3,$ff,$a3
-+	ldr	$a6,[$a_ptr,#24]
-+	sbcs	$a4,$ff,$a4
-+	ldr	$a7,[$a_ptr,#28]
-+	sbcs	$a5,$ff,$a5
-+	sbcs	$a6,$ff,$a6
-+	sbcs	$a7,$ff,$a7
-+	sbc	$ff,$ff,$ff
-+
-+	b	.Lreduce_by_add
-+.size	__ecp_nistz256_neg,.-__ecp_nistz256_neg
-+___
-+{
-+my @acc=map("r$_",(3..11));
-+my ($t0,$t1,$bj,$t2,$t3)=map("r$_",(0,1,2,12,14));
-+
-+$code.=<<___;
-+@ void	ecp_nistz256_sqr_mont(BN_ULONG r0[8],const BN_ULONG r1[8]);
-+.globl	ecp_nistz256_sqr_mont
-+.type	ecp_nistz256_sqr_mont,%function
-+.align	4
-+ecp_nistz256_sqr_mont:
-+	mov	$b_ptr,$a_ptr
-+	b	.Lecp_nistz256_mul_mont
-+.size	ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
-+
-+@ void	ecp_nistz256_mul_mont(BN_ULONG r0[8],const BN_ULONG r1[8],
-+@					     const BN_ULONG r2[8]);
-+.globl	ecp_nistz256_mul_mont
-+.type	ecp_nistz256_mul_mont,%function
-+.align	4
-+ecp_nistz256_mul_mont:
-+.Lecp_nistz256_mul_mont:
-+	stmdb	sp!,{r4-r12,lr}
-+	bl	__ecp_nistz256_mul_mont
-+#if __ARM_ARCH__>=5 || !defined(__thumb__)
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
-+
-+.type	__ecp_nistz256_mul_mont,%function
-+.align	4
-+__ecp_nistz256_mul_mont:
-+	stmdb	sp!,{r0-r2,lr}			@ make a copy of arguments too
-+
-+	ldr	$bj,[$b_ptr,#0]			@ b[0]
-+	ldmia	$a_ptr,{@acc[1]-@acc[8]}
-+
-+	umull	@acc[0],$t3,@acc[1],$bj		@ r[0]=a[0]*b[0]
-+	stmdb	sp!,{$acc[1]-@acc[8]}		@ copy a[0-7] to stack, so
-+						@ that it can be addressed
-+						@ without spending register
-+						@ on address
-+	umull	@acc[1],$t0,@acc[2],$bj		@ r[1]=a[1]*b[0]
-+	umull	@acc[2],$t1,@acc[3],$bj
-+	adds	@acc[1],@acc[1],$t3		@ accumulate high part of mult
-+	umull	@acc[3],$t2,@acc[4],$bj
-+	adcs	@acc[2],@acc[2],$t0
-+	umull	@acc[4],$t3,@acc[5],$bj
-+	adcs	@acc[3],@acc[3],$t1
-+	umull	@acc[5],$t0,@acc[6],$bj
-+	adcs	@acc[4],@acc[4],$t2
-+	umull	@acc[6],$t1,@acc[7],$bj
-+	adcs	@acc[5],@acc[5],$t3
-+	umull	@acc[7],$t2,@acc[8],$bj
-+	adcs	@acc[6],@acc[6],$t0
-+	adcs	@acc[7],@acc[7],$t1
-+	eor	$t3,$t3,$t3			@ first overflow bit is zero
-+	adc	@acc[8],$t2,#0
-+___
-+for(my $i=1;$i<8;$i++) {
-+my $t4=@acc[0];
-+
-+	# Reduction iteration is normally performed by accumulating
-+	# result of multiplication of modulus by "magic" digit [and
-+	# omitting least significant word, which is guaranteed to
-+	# be 0], but thanks to special form of modulus and "magic"
-+	# digit being equal to least significant word, it can be
-+	# performed with additions and subtractions alone. Indeed:
-+	#
-+	#        ffff.0001.0000.0000.0000.ffff.ffff.ffff
-+	# *                                         abcd
-+	# + xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.abcd
-+	#
-+	# Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we
-+	# rewrite above as:
-+	#
-+	#   xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.abcd
-+	# + abcd.0000.abcd.0000.0000.abcd.0000.0000.0000
-+	# -      abcd.0000.0000.0000.0000.0000.0000.abcd
-+	#
-+	# or marking redundant operations:
-+	#
-+	#   xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.----
-+	# + abcd.0000.abcd.0000.0000.abcd.----.----.----
-+	# -      abcd.----.----.----.----.----.----.----
-+
-+$code.=<<___;
-+	@ multiplication-less reduction $i
-+	adds	@acc[3],@acc[3],@acc[0]		@ r[3]+=r[0]
-+	 ldr	$bj,[sp,#40]			@ restore b_ptr
-+	adcs	@acc[4],@acc[4],#0		@ r[4]+=0
-+	adcs	@acc[5],@acc[5],#0		@ r[5]+=0
-+	adcs	@acc[6],@acc[6],@acc[0]		@ r[6]+=r[0]
-+	 ldr	$t1,[sp,#0]			@ load a[0]
-+	adcs	@acc[7],@acc[7],#0		@ r[7]+=0
-+	 ldr	$bj,[$bj,#4*$i]			@ load b[i]
-+	adcs	@acc[8],@acc[8],@acc[0]		@ r[8]+=r[0]
-+	 eor	$t0,$t0,$t0
-+	adc	$t3,$t3,#0			@ overflow bit
-+	subs	@acc[7],@acc[7],@acc[0]		@ r[7]-=r[0]
-+	 ldr	$t2,[sp,#4]			@ a[1]
-+	sbcs	@acc[8],@acc[8],#0		@ r[8]-=0
-+	 umlal	@acc[1],$t0,$t1,$bj		@ "r[0]"+=a[0]*b[i]
-+	 eor	$t1,$t1,$t1
-+	sbc	@acc[0],$t3,#0			@ overflow bit, keep in mind
-+						@ that netto result is
-+						@ addition of a value which
-+						@ makes underflow impossible
-+
-+	ldr	$t3,[sp,#8]			@ a[2]
-+	umlal	@acc[2],$t1,$t2,$bj		@ "r[1]"+=a[1]*b[i]
-+	 str	@acc[0],[sp,#36]		@ temporarily offload overflow
-+	eor	$t2,$t2,$t2
-+	ldr	$t4,[sp,#12]			@ a[3], $t4 is alias @acc[0]
-+	umlal	@acc[3],$t2,$t3,$bj		@ "r[2]"+=a[2]*b[i]
-+	eor	$t3,$t3,$t3
-+	adds	@acc[2],@acc[2],$t0		@ accumulate high part of mult
-+	ldr	$t0,[sp,#16]			@ a[4]
-+	umlal	@acc[4],$t3,$t4,$bj		@ "r[3]"+=a[3]*b[i]
-+	eor	$t4,$t4,$t4
-+	adcs	@acc[3],@acc[3],$t1
-+	ldr	$t1,[sp,#20]			@ a[5]
-+	umlal	@acc[5],$t4,$t0,$bj		@ "r[4]"+=a[4]*b[i]
-+	eor	$t0,$t0,$t0
-+	adcs	@acc[4],@acc[4],$t2
-+	ldr	$t2,[sp,#24]			@ a[6]
-+	umlal	@acc[6],$t0,$t1,$bj		@ "r[5]"+=a[5]*b[i]
-+	eor	$t1,$t1,$t1
-+	adcs	@acc[5],@acc[5],$t3
-+	ldr	$t3,[sp,#28]			@ a[7]
-+	umlal	@acc[7],$t1,$t2,$bj		@ "r[6]"+=a[6]*b[i]
-+	eor	$t2,$t2,$t2
-+	adcs	@acc[6],@acc[6],$t4
-+	 ldr	@acc[0],[sp,#36]		@ restore overflow bit
-+	umlal	@acc[8],$t2,$t3,$bj		@ "r[7]"+=a[7]*b[i]
-+	eor	$t3,$t3,$t3
-+	adcs	@acc[7],@acc[7],$t0
-+	adcs	@acc[8],@acc[8],$t1
-+	adcs	@acc[0],$acc[0],$t2
-+	adc	$t3,$t3,#0			@ new overflow bit
-+___
-+	push(@acc,shift(@acc));			# rotate registers, so that
-+						# "r[i]" becomes r[i]
-+}
-+$code.=<<___;
-+	@ last multiplication-less reduction
-+	adds	@acc[3],@acc[3],@acc[0]
-+	ldr	$r_ptr,[sp,#32]			@ restore r_ptr
-+	adcs	@acc[4],@acc[4],#0
-+	adcs	@acc[5],@acc[5],#0
-+	adcs	@acc[6],@acc[6],@acc[0]
-+	adcs	@acc[7],@acc[7],#0
-+	adcs	@acc[8],@acc[8],@acc[0]
-+	adc	$t3,$t3,#0
-+	subs	@acc[7],@acc[7],@acc[0]
-+	sbcs	@acc[8],@acc[8],#0
-+	sbc	@acc[0],$t3,#0			@ overflow bit
-+
-+	@ Final step is "if result > mod, subtract mod", but we do it
-+	@ "other way around", namely subtract modulus from result
-+	@ and if it borrowed, add modulus back.
-+
-+	adds	@acc[1],@acc[1],#1		@ subs	@acc[1],@acc[1],#-1
-+	adcs	@acc[2],@acc[2],#0		@ sbcs	@acc[2],@acc[2],#-1
-+	adcs	@acc[3],@acc[3],#0		@ sbcs	@acc[3],@acc[3],#-1
-+	sbcs	@acc[4],@acc[4],#0
-+	sbcs	@acc[5],@acc[5],#0
-+	sbcs	@acc[6],@acc[6],#0
-+	sbcs	@acc[7],@acc[7],#1
-+	adcs	@acc[8],@acc[8],#0		@ sbcs	@acc[8],@acc[8],#-1
-+	ldr	lr,[sp,#44]			@ restore lr
-+	sbc	@acc[0],@acc[0],#0		@ broadcast borrow bit
-+	add	sp,sp,#48
-+
-+	@ Note that because mod has special form, i.e. consists of
-+	@ 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	@ broadcasting borrow bit to a register, @acc[0], and using it as
-+	@ a whole or extracting single bit.
-+
-+	adds	@acc[1],@acc[1],@acc[0]		@ add modulus or zero
-+	adcs	@acc[2],@acc[2],@acc[0]
-+	str	@acc[1],[$r_ptr,#0]
-+	adcs	@acc[3],@acc[3],@acc[0]
-+	str	@acc[2],[$r_ptr,#4]
-+	adcs	@acc[4],@acc[4],#0
-+	str	@acc[3],[$r_ptr,#8]
-+	adcs	@acc[5],@acc[5],#0
-+	str	@acc[4],[$r_ptr,#12]
-+	adcs	@acc[6],@acc[6],#0
-+	str	@acc[5],[$r_ptr,#16]
-+	adcs	@acc[7],@acc[7],@acc[0],lsr#31
-+	str	@acc[6],[$r_ptr,#20]
-+	adc	@acc[8],@acc[8],@acc[0]
-+	str	@acc[7],[$r_ptr,#24]
-+	str	@acc[8],[$r_ptr,#28]
-+
-+	mov	pc,lr
-+.size	__ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont
-+___
-+}
-+
-+{
-+my ($out,$inp,$index,$mask)=map("r$_",(0..3));
-+$code.=<<___;
-+@ void	ecp_nistz256_scatter_w5(void *r0,const P256_POINT *r1,
-+@					 int r2);
-+.globl	ecp_nistz256_scatter_w5
-+.type	ecp_nistz256_scatter_w5,%function
-+.align	5
-+ecp_nistz256_scatter_w5:
-+	stmdb	sp!,{r4-r11}
-+
-+	add	$out,$out,$index,lsl#2
-+
-+	ldmia	$inp!,{r4-r11}		@ X
-+	str	r4,[$out,#64*0-4]
-+	str	r5,[$out,#64*1-4]
-+	str	r6,[$out,#64*2-4]
-+	str	r7,[$out,#64*3-4]
-+	str	r8,[$out,#64*4-4]
-+	str	r9,[$out,#64*5-4]
-+	str	r10,[$out,#64*6-4]
-+	str	r11,[$out,#64*7-4]
-+	add	$out,$out,#64*8
-+
-+	ldmia	$inp!,{r4-r11}		@ Y
-+	str	r4,[$out,#64*0-4]
-+	str	r5,[$out,#64*1-4]
-+	str	r6,[$out,#64*2-4]
-+	str	r7,[$out,#64*3-4]
-+	str	r8,[$out,#64*4-4]
-+	str	r9,[$out,#64*5-4]
-+	str	r10,[$out,#64*6-4]
-+	str	r11,[$out,#64*7-4]
-+	add	$out,$out,#64*8
-+
-+	ldmia	$inp,{r4-r11}		@ Z
-+	str	r4,[$out,#64*0-4]
-+	str	r5,[$out,#64*1-4]
-+	str	r6,[$out,#64*2-4]
-+	str	r7,[$out,#64*3-4]
-+	str	r8,[$out,#64*4-4]
-+	str	r9,[$out,#64*5-4]
-+	str	r10,[$out,#64*6-4]
-+	str	r11,[$out,#64*7-4]
-+
-+	ldmia	sp!,{r4-r11}
-+#if __ARM_ARCH__>=5 || defined(__thumb__)
-+	bx	lr
-+#else
-+	mov	pc,lr
-+#endif
-+.size	ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5
-+
-+@ void	ecp_nistz256_gather_w5(P256_POINT *r0,const void *r1,
-+@					      int r2);
-+.globl	ecp_nistz256_gather_w5
-+.type	ecp_nistz256_gather_w5,%function
-+.align	5
-+ecp_nistz256_gather_w5:
-+	stmdb	sp!,{r4-r11}
-+
-+	cmp	$index,#0
-+	mov	$mask,#0
-+#ifdef	__thumb2__
-+	itt	ne
-+#endif
-+	subne	$index,$index,#1
-+	movne	$mask,#-1
-+	add	$inp,$inp,$index,lsl#2
-+
-+	ldr	r4,[$inp,#64*0]
-+	ldr	r5,[$inp,#64*1]
-+	ldr	r6,[$inp,#64*2]
-+	and	r4,r4,$mask
-+	ldr	r7,[$inp,#64*3]
-+	and	r5,r5,$mask
-+	ldr	r8,[$inp,#64*4]
-+	and	r6,r6,$mask
-+	ldr	r9,[$inp,#64*5]
-+	and	r7,r7,$mask
-+	ldr	r10,[$inp,#64*6]
-+	and	r8,r8,$mask
-+	ldr	r11,[$inp,#64*7]
-+	add	$inp,$inp,#64*8
-+	and	r9,r9,$mask
-+	and	r10,r10,$mask
-+	and	r11,r11,$mask
-+	stmia	$out!,{r4-r11}	@ X
-+
-+	ldr	r4,[$inp,#64*0]
-+	ldr	r5,[$inp,#64*1]
-+	ldr	r6,[$inp,#64*2]
-+	and	r4,r4,$mask
-+	ldr	r7,[$inp,#64*3]
-+	and	r5,r5,$mask
-+	ldr	r8,[$inp,#64*4]
-+	and	r6,r6,$mask
-+	ldr	r9,[$inp,#64*5]
-+	and	r7,r7,$mask
-+	ldr	r10,[$inp,#64*6]
-+	and	r8,r8,$mask
-+	ldr	r11,[$inp,#64*7]
-+	add	$inp,$inp,#64*8
-+	and	r9,r9,$mask
-+	and	r10,r10,$mask
-+	and	r11,r11,$mask
-+	stmia	$out!,{r4-r11}	@ Y
-+
-+	ldr	r4,[$inp,#64*0]
-+	ldr	r5,[$inp,#64*1]
-+	ldr	r6,[$inp,#64*2]
-+	and	r4,r4,$mask
-+	ldr	r7,[$inp,#64*3]
-+	and	r5,r5,$mask
-+	ldr	r8,[$inp,#64*4]
-+	and	r6,r6,$mask
-+	ldr	r9,[$inp,#64*5]
-+	and	r7,r7,$mask
-+	ldr	r10,[$inp,#64*6]
-+	and	r8,r8,$mask
-+	ldr	r11,[$inp,#64*7]
-+	and	r9,r9,$mask
-+	and	r10,r10,$mask
-+	and	r11,r11,$mask
-+	stmia	$out,{r4-r11}		@ Z
-+
-+	ldmia	sp!,{r4-r11}
-+#if __ARM_ARCH__>=5 || defined(__thumb__)
-+	bx	lr
-+#else
-+	mov	pc,lr
-+#endif
-+.size	ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5
-+
-+@ void	ecp_nistz256_scatter_w7(void *r0,const P256_POINT_AFFINE *r1,
-+@					 int r2);
-+.globl	ecp_nistz256_scatter_w7
-+.type	ecp_nistz256_scatter_w7,%function
-+.align	5
-+ecp_nistz256_scatter_w7:
-+	add	$out,$out,$index
-+	mov	$index,#64/4
-+.Loop_scatter_w7:
-+	ldr	$mask,[$inp],#4
-+	subs	$index,$index,#1
-+	strb	$mask,[$out,#64*0-1]
-+	mov	$mask,$mask,lsr#8
-+	strb	$mask,[$out,#64*1-1]
-+	mov	$mask,$mask,lsr#8
-+	strb	$mask,[$out,#64*2-1]
-+	mov	$mask,$mask,lsr#8
-+	strb	$mask,[$out,#64*3-1]
-+	add	$out,$out,#64*4
-+	bne	.Loop_scatter_w7
-+
-+#if __ARM_ARCH__>=5 || defined(__thumb__)
-+	bx	lr
-+#else
-+	mov	pc,lr
-+#endif
-+.size	ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7
-+
-+@ void	ecp_nistz256_gather_w7(P256_POINT_AFFINE *r0,const void *r1,
-+@						     int r2);
-+.globl	ecp_nistz256_gather_w7
-+.type	ecp_nistz256_gather_w7,%function
-+.align	5
-+ecp_nistz256_gather_w7:
-+	stmdb	sp!,{r4-r7}
-+
-+	cmp	$index,#0
-+	mov	$mask,#0
-+#ifdef	__thumb2__
-+	itt	ne
-+#endif
-+	subne	$index,$index,#1
-+	movne	$mask,#-1
-+	add	$inp,$inp,$index
-+	mov	$index,#64/4
-+	nop
-+.Loop_gather_w7:
-+	ldrb	r4,[$inp,#64*0]
-+	subs	$index,$index,#1
-+	ldrb	r5,[$inp,#64*1]
-+	ldrb	r6,[$inp,#64*2]
-+	ldrb	r7,[$inp,#64*3]
-+	add	$inp,$inp,#64*4
-+	orr	r4,r4,r5,lsl#8
-+	orr	r4,r4,r6,lsl#16
-+	orr	r4,r4,r7,lsl#24
-+	and	r4,r4,$mask
-+	str	r4,[$out],#4
-+	bne	.Loop_gather_w7
-+
-+	ldmia	sp!,{r4-r7}
-+#if __ARM_ARCH__>=5 || defined(__thumb__)
-+	bx	lr
-+#else
-+	mov	pc,lr
-+#endif
-+.size	ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7
-+___
-+}
-+if (0) {
-+# In comparison to integer-only equivalent of below subroutine:
-+#
-+# Cortex-A8	+10%
-+# Cortex-A9	-10%
-+# Snapdragon S4	+5%
-+#
-+# As not all time is spent in multiplication, overall impact is deemed
-+# too low to care about.
-+
-+my ($A0,$A1,$A2,$A3,$Bi,$zero,$temp)=map("d$_",(0..7));
-+my $mask="q4";
-+my $mult="q5";
-+my @AxB=map("q$_",(8..15));
-+
-+my ($rptr,$aptr,$bptr,$toutptr)=map("r$_",(0..3));
-+
-+$code.=<<___;
-+#if __ARM_ARCH__>=7
-+.fpu	neon
-+
-+.globl	ecp_nistz256_mul_mont_neon
-+.type	ecp_nistz256_mul_mont_neon,%function
-+.align	5
-+ecp_nistz256_mul_mont_neon:
-+	mov	ip,sp
-+	stmdb	sp!,{r4-r9}
-+	vstmdb	sp!,{q4-q5}		@ ABI specification says so
-+
-+	sub		$toutptr,sp,#40
-+	vld1.32		{${Bi}[0]},[$bptr,:32]!
-+	veor		$zero,$zero,$zero
-+	vld1.32		{$A0-$A3}, [$aptr]		@ can't specify :32 :-(
-+	vzip.16		$Bi,$zero
-+	mov		sp,$toutptr			@ alloca
-+	vmov.i64	$mask,#0xffff
-+
-+	vmull.u32	@AxB[0],$Bi,${A0}[0]
-+	vmull.u32	@AxB[1],$Bi,${A0}[1]
-+	vmull.u32	@AxB[2],$Bi,${A1}[0]
-+	vmull.u32	@AxB[3],$Bi,${A1}[1]
-+	 vshr.u64	$temp,@AxB[0]#lo,#16
-+	vmull.u32	@AxB[4],$Bi,${A2}[0]
-+	 vadd.u64	@AxB[0]#hi,@AxB[0]#hi,$temp
-+	vmull.u32	@AxB[5],$Bi,${A2}[1]
-+	 vshr.u64	$temp,@AxB[0]#hi,#16		@ upper 32 bits of a[0]*b[0]
-+	vmull.u32	@AxB[6],$Bi,${A3}[0]
-+	 vand.u64	@AxB[0],@AxB[0],$mask		@ lower 32 bits of a[0]*b[0]
-+	vmull.u32	@AxB[7],$Bi,${A3}[1]
-+___
-+for($i=1;$i<8;$i++) {
-+$code.=<<___;
-+	 vld1.32	{${Bi}[0]},[$bptr,:32]!
-+	 veor		$zero,$zero,$zero
-+	vadd.u64	@AxB[1]#lo,@AxB[1]#lo,$temp	@ reduction
-+	vshl.u64	$mult,@AxB[0],#32
-+	vadd.u64	@AxB[3],@AxB[3],@AxB[0]
-+	vsub.u64	$mult,$mult,@AxB[0]
-+	 vzip.16	$Bi,$zero
-+	vadd.u64	@AxB[6],@AxB[6],@AxB[0]
-+	vadd.u64	@AxB[7],@AxB[7],$mult
-+___
-+	push(@AxB,shift(@AxB));
-+$code.=<<___;
-+	vmlal.u32	@AxB[0],$Bi,${A0}[0]
-+	vmlal.u32	@AxB[1],$Bi,${A0}[1]
-+	vmlal.u32	@AxB[2],$Bi,${A1}[0]
-+	vmlal.u32	@AxB[3],$Bi,${A1}[1]
-+	 vshr.u64	$temp,@AxB[0]#lo,#16
-+	vmlal.u32	@AxB[4],$Bi,${A2}[0]
-+	 vadd.u64	@AxB[0]#hi,@AxB[0]#hi,$temp
-+	vmlal.u32	@AxB[5],$Bi,${A2}[1]
-+	 vshr.u64	$temp,@AxB[0]#hi,#16		@ upper 33 bits of a[0]*b[i]+t[0]
-+	vmlal.u32	@AxB[6],$Bi,${A3}[0]
-+	 vand.u64	@AxB[0],@AxB[0],$mask		@ lower 32 bits of a[0]*b[0]
-+	vmull.u32	@AxB[7],$Bi,${A3}[1]
-+___
-+}
-+$code.=<<___;
-+	vadd.u64	@AxB[1]#lo,@AxB[1]#lo,$temp	@ last reduction
-+	vshl.u64	$mult,@AxB[0],#32
-+	vadd.u64	@AxB[3],@AxB[3],@AxB[0]
-+	vsub.u64	$mult,$mult,@AxB[0]
-+	vadd.u64	@AxB[6],@AxB[6],@AxB[0]
-+	vadd.u64	@AxB[7],@AxB[7],$mult
-+
-+	vshr.u64	$temp,@AxB[1]#lo,#16		@ convert
-+	vadd.u64	@AxB[1]#hi,@AxB[1]#hi,$temp
-+	vshr.u64	$temp,@AxB[1]#hi,#16
-+	vzip.16		@AxB[1]#lo,@AxB[1]#hi
-+___
-+foreach (2..7) {
-+$code.=<<___;
-+	vadd.u64	@AxB[$_]#lo,@AxB[$_]#lo,$temp
-+	vst1.32		{@AxB[$_-1]#lo[0]},[$toutptr,:32]!
-+	vshr.u64	$temp,@AxB[$_]#lo,#16
-+	vadd.u64	@AxB[$_]#hi,@AxB[$_]#hi,$temp
-+	vshr.u64	$temp,@AxB[$_]#hi,#16
-+	vzip.16		@AxB[$_]#lo,@AxB[$_]#hi
-+___
-+}
-+$code.=<<___;
-+	vst1.32		{@AxB[7]#lo[0]},[$toutptr,:32]!
-+	vst1.32		{$temp},[$toutptr]		@ upper 33 bits
-+
-+	ldr	r1,[sp,#0]
-+	ldr	r2,[sp,#4]
-+	ldr	r3,[sp,#8]
-+	subs	r1,r1,#-1
-+	ldr	r4,[sp,#12]
-+	sbcs	r2,r2,#-1
-+	ldr	r5,[sp,#16]
-+	sbcs	r3,r3,#-1
-+	ldr	r6,[sp,#20]
-+	sbcs	r4,r4,#0
-+	ldr	r7,[sp,#24]
-+	sbcs	r5,r5,#0
-+	ldr	r8,[sp,#28]
-+	sbcs	r6,r6,#0
-+	ldr	r9,[sp,#32]				@ top-most bit
-+	sbcs	r7,r7,#1
-+	sub	sp,ip,#40+16
-+	sbcs	r8,r8,#-1
-+	sbc	r9,r9,#0
-+        vldmia  sp!,{q4-q5}
-+
-+	adds	r1,r1,r9
-+	adcs	r2,r2,r9
-+	str	r1,[$rptr,#0]
-+	adcs	r3,r3,r9
-+	str	r2,[$rptr,#4]
-+	adcs	r4,r4,#0
-+	str	r3,[$rptr,#8]
-+	adcs	r5,r5,#0
-+	str	r4,[$rptr,#12]
-+	adcs	r6,r6,#0
-+	str	r5,[$rptr,#16]
-+	adcs	r7,r7,r9,lsr#31
-+	str	r6,[$rptr,#20]
-+	adcs	r8,r8,r9
-+	str	r7,[$rptr,#24]
-+	str	r8,[$rptr,#28]
-+
-+        ldmia   sp!,{r4-r9}
-+	bx	lr
-+.size	ecp_nistz256_mul_mont_neon,.-ecp_nistz256_mul_mont_neon
-+#endif
-+___
-+}
-+
-+{{{
-+########################################################################
-+# Below $aN assignment matches order in which 256-bit result appears in
-+# register bank at return from __ecp_nistz256_mul_mont, so that we can
-+# skip over reloading it from memory. This means that below functions
-+# use custom calling sequence accepting 256-bit input in registers,
-+# output pointer in r0, $r_ptr, and optional pointer in r2, $b_ptr.
-+#
-+# See their "normal" counterparts for insights on calculations.
-+
-+my ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,
-+    $t0,$t1,$t2,$t3)=map("r$_",(11,3..10,12,14,1));
-+my $ff=$b_ptr;
-+
-+$code.=<<___;
-+.type	__ecp_nistz256_sub_from,%function
-+.align	5
-+__ecp_nistz256_sub_from:
-+	str	lr,[sp,#-4]!		@ push lr
-+
-+	 ldr	$t0,[$b_ptr,#0]
-+	 ldr	$t1,[$b_ptr,#4]
-+	 ldr	$t2,[$b_ptr,#8]
-+	 ldr	$t3,[$b_ptr,#12]
-+	subs	$a0,$a0,$t0
-+	 ldr	$t0,[$b_ptr,#16]
-+	sbcs	$a1,$a1,$t1
-+	 ldr	$t1,[$b_ptr,#20]
-+	sbcs	$a2,$a2,$t2
-+	 ldr	$t2,[$b_ptr,#24]
-+	sbcs	$a3,$a3,$t3
-+	 ldr	$t3,[$b_ptr,#28]
-+	sbcs	$a4,$a4,$t0
-+	sbcs	$a5,$a5,$t1
-+	sbcs	$a6,$a6,$t2
-+	sbcs	$a7,$a7,$t3
-+	sbc	$ff,$ff,$ff		@ broadcast borrow bit
-+	ldr	lr,[sp],#4		@ pop lr
-+
-+	adds	$a0,$a0,$ff		@ add synthesized modulus
-+	adcs	$a1,$a1,$ff
-+	str	$a0,[$r_ptr,#0]
-+	adcs	$a2,$a2,$ff
-+	str	$a1,[$r_ptr,#4]
-+	adcs	$a3,$a3,#0
-+	str	$a2,[$r_ptr,#8]
-+	adcs	$a4,$a4,#0
-+	str	$a3,[$r_ptr,#12]
-+	adcs	$a5,$a5,#0
-+	str	$a4,[$r_ptr,#16]
-+	adcs	$a6,$a6,$ff,lsr#31
-+	str	$a5,[$r_ptr,#20]
-+	adcs	$a7,$a7,$ff
-+	str	$a6,[$r_ptr,#24]
-+	str	$a7,[$r_ptr,#28]
-+
-+	mov	pc,lr
-+.size	__ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from
-+
-+.type	__ecp_nistz256_sub_morf,%function
-+.align	5
-+__ecp_nistz256_sub_morf:
-+	str	lr,[sp,#-4]!		@ push lr
-+
-+	 ldr	$t0,[$b_ptr,#0]
-+	 ldr	$t1,[$b_ptr,#4]
-+	 ldr	$t2,[$b_ptr,#8]
-+	 ldr	$t3,[$b_ptr,#12]
-+	subs	$a0,$t0,$a0
-+	 ldr	$t0,[$b_ptr,#16]
-+	sbcs	$a1,$t1,$a1
-+	 ldr	$t1,[$b_ptr,#20]
-+	sbcs	$a2,$t2,$a2
-+	 ldr	$t2,[$b_ptr,#24]
-+	sbcs	$a3,$t3,$a3
-+	 ldr	$t3,[$b_ptr,#28]
-+	sbcs	$a4,$t0,$a4
-+	sbcs	$a5,$t1,$a5
-+	sbcs	$a6,$t2,$a6
-+	sbcs	$a7,$t3,$a7
-+	sbc	$ff,$ff,$ff		@ broadcast borrow bit
-+	ldr	lr,[sp],#4		@ pop lr
-+
-+	adds	$a0,$a0,$ff		@ add synthesized modulus
-+	adcs	$a1,$a1,$ff
-+	str	$a0,[$r_ptr,#0]
-+	adcs	$a2,$a2,$ff
-+	str	$a1,[$r_ptr,#4]
-+	adcs	$a3,$a3,#0
-+	str	$a2,[$r_ptr,#8]
-+	adcs	$a4,$a4,#0
-+	str	$a3,[$r_ptr,#12]
-+	adcs	$a5,$a5,#0
-+	str	$a4,[$r_ptr,#16]
-+	adcs	$a6,$a6,$ff,lsr#31
-+	str	$a5,[$r_ptr,#20]
-+	adcs	$a7,$a7,$ff
-+	str	$a6,[$r_ptr,#24]
-+	str	$a7,[$r_ptr,#28]
-+
-+	mov	pc,lr
-+.size	__ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf
-+
-+.type	__ecp_nistz256_add_self,%function
-+.align	4
-+__ecp_nistz256_add_self:
-+	adds	$a0,$a0,$a0		@ a[0:7]+=a[0:7]
-+	adcs	$a1,$a1,$a1
-+	adcs	$a2,$a2,$a2
-+	adcs	$a3,$a3,$a3
-+	adcs	$a4,$a4,$a4
-+	adcs	$a5,$a5,$a5
-+	adcs	$a6,$a6,$a6
-+	mov	$ff,#0
-+	adcs	$a7,$a7,$a7
-+	adc	$ff,$ff,#0
-+
-+	@ if a+b >= modulus, subtract modulus.
-+	@
-+	@ But since comparison implies subtraction, we subtract
-+	@ modulus and then add it back if subraction borrowed.
-+
-+	subs	$a0,$a0,#-1
-+	sbcs	$a1,$a1,#-1
-+	sbcs	$a2,$a2,#-1
-+	sbcs	$a3,$a3,#0
-+	sbcs	$a4,$a4,#0
-+	sbcs	$a5,$a5,#0
-+	sbcs	$a6,$a6,#1
-+	sbcs	$a7,$a7,#-1
-+	sbc	$ff,$ff,#0
-+
-+	@ Note that because mod has special form, i.e. consists of
-+	@ 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	@ using value of borrow as a whole or extracting single bit.
-+	@ Follow $ff register...
-+
-+	adds	$a0,$a0,$ff		@ add synthesized modulus
-+	adcs	$a1,$a1,$ff
-+	str	$a0,[$r_ptr,#0]
-+	adcs	$a2,$a2,$ff
-+	str	$a1,[$r_ptr,#4]
-+	adcs	$a3,$a3,#0
-+	str	$a2,[$r_ptr,#8]
-+	adcs	$a4,$a4,#0
-+	str	$a3,[$r_ptr,#12]
-+	adcs	$a5,$a5,#0
-+	str	$a4,[$r_ptr,#16]
-+	adcs	$a6,$a6,$ff,lsr#31
-+	str	$a5,[$r_ptr,#20]
-+	adcs	$a7,$a7,$ff
-+	str	$a6,[$r_ptr,#24]
-+	str	$a7,[$r_ptr,#28]
-+
-+	mov	pc,lr
-+.size	__ecp_nistz256_add_self,.-__ecp_nistz256_add_self
-+
-+___
-+
-+########################################################################
-+# following subroutines are "literal" implementation of those found in
-+# ecp_nistz256.c
-+#
-+########################################################################
-+# void ecp_nistz256_point_double(P256_POINT *out,const P256_POINT *inp);
-+#
-+{
-+my ($S,$M,$Zsqr,$in_x,$tmp0)=map(32*$_,(0..4));
-+# above map() describes stack layout with 5 temporary
-+# 256-bit vectors on top. Then note that we push
-+# starting from r0, which means that we have copy of
-+# input arguments just below these temporary vectors.
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_double
-+.type	ecp_nistz256_point_double,%function
-+.align	5
-+ecp_nistz256_point_double:
-+	stmdb	sp!,{r0-r12,lr}		@ push from r0, unusual, but intentional
-+	sub	sp,sp,#32*5
-+
-+.Lpoint_double_shortcut:
-+	add	r3,sp,#$in_x
-+	ldmia	$a_ptr!,{r4-r11}	@ copy in_x
-+	stmia	r3,{r4-r11}
-+
-+	add	$r_ptr,sp,#$S
-+	bl	__ecp_nistz256_mul_by_2	@ p256_mul_by_2(S, in_y);
-+
-+	add	$b_ptr,$a_ptr,#32
-+	add	$a_ptr,$a_ptr,#32
-+	add	$r_ptr,sp,#$Zsqr
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(Zsqr, in_z);
-+
-+	add	$a_ptr,sp,#$S
-+	add	$b_ptr,sp,#$S
-+	add	$r_ptr,sp,#$S
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(S, S);
-+
-+	ldr	$b_ptr,[sp,#32*5+4]
-+	add	$a_ptr,$b_ptr,#32
-+	add	$b_ptr,$b_ptr,#64
-+	add	$r_ptr,sp,#$tmp0
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(tmp0, in_z, in_y);
-+
-+	ldr	$r_ptr,[sp,#32*5]
-+	add	$r_ptr,$r_ptr,#64
-+	bl	__ecp_nistz256_add_self	@ p256_mul_by_2(res_z, tmp0);
-+
-+	add	$a_ptr,sp,#$in_x
-+	add	$b_ptr,sp,#$Zsqr
-+	add	$r_ptr,sp,#$M
-+	bl	__ecp_nistz256_add	@ p256_add(M, in_x, Zsqr);
-+
-+	add	$a_ptr,sp,#$in_x
-+	add	$b_ptr,sp,#$Zsqr
-+	add	$r_ptr,sp,#$Zsqr
-+	bl	__ecp_nistz256_sub	@ p256_sub(Zsqr, in_x, Zsqr);
-+
-+	add	$a_ptr,sp,#$S
-+	add	$b_ptr,sp,#$S
-+	add	$r_ptr,sp,#$tmp0
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(tmp0, S);
-+
-+	add	$a_ptr,sp,#$Zsqr
-+	add	$b_ptr,sp,#$M
-+	add	$r_ptr,sp,#$M
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(M, M, Zsqr);
-+
-+	ldr	$r_ptr,[sp,#32*5]
-+	add	$a_ptr,sp,#$tmp0
-+	add	$r_ptr,$r_ptr,#32
-+	bl	__ecp_nistz256_div_by_2	@ p256_div_by_2(res_y, tmp0);
-+
-+	add	$a_ptr,sp,#$M
-+	add	$r_ptr,sp,#$M
-+	bl	__ecp_nistz256_mul_by_3	@ p256_mul_by_3(M, M);
-+
-+	add	$a_ptr,sp,#$in_x
-+	add	$b_ptr,sp,#$S
-+	add	$r_ptr,sp,#$S
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(S, S, in_x);
-+
-+	add	$r_ptr,sp,#$tmp0
-+	bl	__ecp_nistz256_add_self	@ p256_mul_by_2(tmp0, S);
-+
-+	ldr	$r_ptr,[sp,#32*5]
-+	add	$a_ptr,sp,#$M
-+	add	$b_ptr,sp,#$M
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(res_x, M);
-+
-+	add	$b_ptr,sp,#$tmp0
-+	bl	__ecp_nistz256_sub_from	@ p256_sub(res_x, res_x, tmp0);
-+
-+	add	$b_ptr,sp,#$S
-+	add	$r_ptr,sp,#$S
-+	bl	__ecp_nistz256_sub_morf	@ p256_sub(S, S, res_x);
-+
-+	add	$a_ptr,sp,#$M
-+	add	$b_ptr,sp,#$S
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(S, S, M);
-+
-+	ldr	$r_ptr,[sp,#32*5]
-+	add	$b_ptr,$r_ptr,#32
-+	add	$r_ptr,$r_ptr,#32
-+	bl	__ecp_nistz256_sub_from	@ p256_sub(res_y, S, res_y);
-+
-+	add	sp,sp,#32*5+16		@ +16 means "skip even over saved r0-r3"
-+#if __ARM_ARCH__>=5 || !defined(__thumb__)
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	ecp_nistz256_point_double,.-ecp_nistz256_point_double
-+___
-+}
-+
-+########################################################################
-+# void ecp_nistz256_point_add(P256_POINT *out,const P256_POINT *in1,
-+#			      const P256_POINT *in2);
-+{
-+my ($res_x,$res_y,$res_z,
-+    $in1_x,$in1_y,$in1_z,
-+    $in2_x,$in2_y,$in2_z,
-+    $H,$Hsqr,$R,$Rsqr,$Hcub,
-+    $U1,$U2,$S1,$S2)=map(32*$_,(0..17));
-+my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
-+# above map() describes stack layout with 18 temporary
-+# 256-bit vectors on top. Then note that we push
-+# starting from r0, which means that we have copy of
-+# input arguments just below these temporary vectors.
-+# We use three of them for !in1infty, !in2intfy and
-+# result of check for zero.
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_add
-+.type	ecp_nistz256_point_add,%function
-+.align	5
-+ecp_nistz256_point_add:
-+	stmdb	sp!,{r0-r12,lr}		@ push from r0, unusual, but intentional
-+	sub	sp,sp,#32*18+16
-+
-+	ldmia	$b_ptr!,{r4-r11}	@ copy in2_x
-+	add	r3,sp,#$in2_x
-+	stmia	r3!,{r4-r11}
-+	ldmia	$b_ptr!,{r4-r11}	@ copy in2_y
-+	stmia	r3!,{r4-r11}
-+	ldmia	$b_ptr,{r4-r11}		@ copy in2_z
-+	orr	r12,r4,r5
-+	orr	r12,r12,r6
-+	orr	r12,r12,r7
-+	orr	r12,r12,r8
-+	orr	r12,r12,r9
-+	orr	r12,r12,r10
-+	orr	r12,r12,r11
-+	cmp	r12,#0
-+#ifdef	__thumb2__
-+	it	ne
-+#endif
-+	movne	r12,#-1
-+	stmia	r3,{r4-r11}
-+	str	r12,[sp,#32*18+8]	@ !in2infty
-+
-+	ldmia	$a_ptr!,{r4-r11}	@ copy in1_x
-+	add	r3,sp,#$in1_x
-+	stmia	r3!,{r4-r11}
-+	ldmia	$a_ptr!,{r4-r11}	@ copy in1_y
-+	stmia	r3!,{r4-r11}
-+	ldmia	$a_ptr,{r4-r11}		@ copy in1_z
-+	orr	r12,r4,r5
-+	orr	r12,r12,r6
-+	orr	r12,r12,r7
-+	orr	r12,r12,r8
-+	orr	r12,r12,r9
-+	orr	r12,r12,r10
-+	orr	r12,r12,r11
-+	cmp	r12,#0
-+#ifdef	__thumb2__
-+	it	ne
-+#endif
-+	movne	r12,#-1
-+	stmia	r3,{r4-r11}
-+	str	r12,[sp,#32*18+4]	@ !in1infty
-+
-+	add	$a_ptr,sp,#$in2_z
-+	add	$b_ptr,sp,#$in2_z
-+	add	$r_ptr,sp,#$Z2sqr
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(Z2sqr, in2_z);
-+
-+	add	$a_ptr,sp,#$in1_z
-+	add	$b_ptr,sp,#$in1_z
-+	add	$r_ptr,sp,#$Z1sqr
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(Z1sqr, in1_z);
-+
-+	add	$a_ptr,sp,#$in2_z
-+	add	$b_ptr,sp,#$Z2sqr
-+	add	$r_ptr,sp,#$S1
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(S1, Z2sqr, in2_z);
-+
-+	add	$a_ptr,sp,#$in1_z
-+	add	$b_ptr,sp,#$Z1sqr
-+	add	$r_ptr,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(S2, Z1sqr, in1_z);
-+
-+	add	$a_ptr,sp,#$in1_y
-+	add	$b_ptr,sp,#$S1
-+	add	$r_ptr,sp,#$S1
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(S1, S1, in1_y);
-+
-+	add	$a_ptr,sp,#$in2_y
-+	add	$b_ptr,sp,#$S2
-+	add	$r_ptr,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(S2, S2, in2_y);
-+
-+	add	$b_ptr,sp,#$S1
-+	add	$r_ptr,sp,#$R
-+	bl	__ecp_nistz256_sub_from	@ p256_sub(R, S2, S1);
-+
-+	orr	$a0,$a0,$a1		@ see if result is zero
-+	orr	$a2,$a2,$a3
-+	orr	$a4,$a4,$a5
-+	orr	$a0,$a0,$a2
-+	orr	$a4,$a4,$a6
-+	orr	$a0,$a0,$a7
-+	 add	$a_ptr,sp,#$in1_x
-+	orr	$a0,$a0,$a4
-+	 add	$b_ptr,sp,#$Z2sqr
-+	str	$a0,[sp,#32*18+12]
-+
-+	add	$r_ptr,sp,#$U1
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(U1, in1_x, Z2sqr);
-+
-+	add	$a_ptr,sp,#$in2_x
-+	add	$b_ptr,sp,#$Z1sqr
-+	add	$r_ptr,sp,#$U2
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(U2, in2_x, Z1sqr);
-+
-+	add	$b_ptr,sp,#$U1
-+	add	$r_ptr,sp,#$H
-+	bl	__ecp_nistz256_sub_from	@ p256_sub(H, U2, U1);
-+
-+	orr	$a0,$a0,$a1		@ see if result is zero
-+	orr	$a2,$a2,$a3
-+	orr	$a4,$a4,$a5
-+	orr	$a0,$a0,$a2
-+	orr	$a4,$a4,$a6
-+	orr	$a0,$a0,$a7
-+	orrs	$a0,$a0,$a4
-+
-+	bne	.Ladd_proceed		@ is_equal(U1,U2)?
-+
-+	ldr	$t0,[sp,#32*18+4]
-+	ldr	$t1,[sp,#32*18+8]
-+	ldr	$t2,[sp,#32*18+12]
-+	tst	$t0,$t1
-+	beq	.Ladd_proceed		@ (in1infty || in2infty)?
-+	tst	$t2,$t2
-+	beq	.Ladd_double		@ is_equal(S1,S2)?
-+
-+	ldr	$r_ptr,[sp,#32*18+16]
-+	eor	r4,r4,r4
-+	eor	r5,r5,r5
-+	eor	r6,r6,r6
-+	eor	r7,r7,r7
-+	eor	r8,r8,r8
-+	eor	r9,r9,r9
-+	eor	r10,r10,r10
-+	eor	r11,r11,r11
-+	stmia	$r_ptr!,{r4-r11}
-+	stmia	$r_ptr!,{r4-r11}
-+	stmia	$r_ptr!,{r4-r11}
-+	b	.Ladd_done
-+
-+.align	4
-+.Ladd_double:
-+	ldr	$a_ptr,[sp,#32*18+20]
-+	add	sp,sp,#32*(18-5)+16	@ difference in frame sizes
-+	b	.Lpoint_double_shortcut
-+
-+.align	4
-+.Ladd_proceed:
-+	add	$a_ptr,sp,#$R
-+	add	$b_ptr,sp,#$R
-+	add	$r_ptr,sp,#$Rsqr
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(Rsqr, R);
-+
-+	add	$a_ptr,sp,#$H
-+	add	$b_ptr,sp,#$in1_z
-+	add	$r_ptr,sp,#$res_z
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(res_z, H, in1_z);
-+
-+	add	$a_ptr,sp,#$H
-+	add	$b_ptr,sp,#$H
-+	add	$r_ptr,sp,#$Hsqr
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(Hsqr, H);
-+
-+	add	$a_ptr,sp,#$in2_z
-+	add	$b_ptr,sp,#$res_z
-+	add	$r_ptr,sp,#$res_z
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(res_z, res_z, in2_z);
-+
-+	add	$a_ptr,sp,#$H
-+	add	$b_ptr,sp,#$Hsqr
-+	add	$r_ptr,sp,#$Hcub
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(Hcub, Hsqr, H);
-+
-+	add	$a_ptr,sp,#$Hsqr
-+	add	$b_ptr,sp,#$U1
-+	add	$r_ptr,sp,#$U2
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(U2, U1, Hsqr);
-+
-+	add	$r_ptr,sp,#$Hsqr
-+	bl	__ecp_nistz256_add_self	@ p256_mul_by_2(Hsqr, U2);
-+
-+	add	$b_ptr,sp,#$Rsqr
-+	add	$r_ptr,sp,#$res_x
-+	bl	__ecp_nistz256_sub_morf	@ p256_sub(res_x, Rsqr, Hsqr);
-+
-+	add	$b_ptr,sp,#$Hcub
-+	bl	__ecp_nistz256_sub_from	@  p256_sub(res_x, res_x, Hcub);
-+
-+	add	$b_ptr,sp,#$U2
-+	add	$r_ptr,sp,#$res_y
-+	bl	__ecp_nistz256_sub_morf	@ p256_sub(res_y, U2, res_x);
-+
-+	add	$a_ptr,sp,#$Hcub
-+	add	$b_ptr,sp,#$S1
-+	add	$r_ptr,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(S2, S1, Hcub);
-+
-+	add	$a_ptr,sp,#$R
-+	add	$b_ptr,sp,#$res_y
-+	add	$r_ptr,sp,#$res_y
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(res_y, res_y, R);
-+
-+	add	$b_ptr,sp,#$S2
-+	bl	__ecp_nistz256_sub_from	@ p256_sub(res_y, res_y, S2);
-+
-+	ldr	r11,[sp,#32*18+4]	@ !in1intfy
-+	ldr	r12,[sp,#32*18+8]	@ !in2intfy
-+	add	r1,sp,#$res_x
-+	add	r2,sp,#$in2_x
-+	and	r10,r11,r12
-+	mvn	r11,r11
-+	add	r3,sp,#$in1_x
-+	and	r11,r11,r12
-+	mvn	r12,r12
-+	ldr	$r_ptr,[sp,#32*18+16]
-+___
-+for($i=0;$i<96;$i+=8) {			# conditional moves
-+$code.=<<___;
-+	ldmia	r1!,{r4-r5}		@ res_x
-+	ldmia	r2!,{r6-r7}		@ in2_x
-+	ldmia	r3!,{r8-r9}		@ in1_x
-+	and	r4,r4,r10
-+	and	r5,r5,r10
-+	and	r6,r6,r11
-+	and	r7,r7,r11
-+	and	r8,r8,r12
-+	and	r9,r9,r12
-+	orr	r4,r4,r6
-+	orr	r5,r5,r7
-+	orr	r4,r4,r8
-+	orr	r5,r5,r9
-+	stmia	$r_ptr!,{r4-r5}
-+___
-+}
-+$code.=<<___;
-+.Ladd_done:
-+	add	sp,sp,#32*18+16+16	@ +16 means "skip even over saved r0-r3"
-+#if __ARM_ARCH__>=5 || defined(__thumb__)
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	ecp_nistz256_point_add,.-ecp_nistz256_point_add
-+___
-+}
-+
-+########################################################################
-+# void ecp_nistz256_point_add_affine(P256_POINT *out,const P256_POINT *in1,
-+#				     const P256_POINT_AFFINE *in2);
-+{
-+my ($res_x,$res_y,$res_z,
-+    $in1_x,$in1_y,$in1_z,
-+    $in2_x,$in2_y,
-+    $U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr)=map(32*$_,(0..14));
-+my $Z1sqr = $S2;
-+# above map() describes stack layout with 18 temporary
-+# 256-bit vectors on top. Then note that we push
-+# starting from r0, which means that we have copy of
-+# input arguments just below these temporary vectors.
-+# We use two of them for !in1infty, !in2intfy.
-+
-+my @ONE_mont=(1,0,0,-1,-1,-1,-2,0);
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_add_affine
-+.type	ecp_nistz256_point_add_affine,%function
-+.align	5
-+ecp_nistz256_point_add_affine:
-+	stmdb	sp!,{r0-r12,lr}		@ push from r0, unusual, but intentional
-+	sub	sp,sp,#32*15
-+
-+	ldmia	$a_ptr!,{r4-r11}	@ copy in1_x
-+	add	r3,sp,#$in1_x
-+	stmia	r3!,{r4-r11}
-+	ldmia	$a_ptr!,{r4-r11}	@ copy in1_y
-+	stmia	r3!,{r4-r11}
-+	ldmia	$a_ptr,{r4-r11}		@ copy in1_z
-+	orr	r12,r4,r5
-+	orr	r12,r12,r6
-+	orr	r12,r12,r7
-+	orr	r12,r12,r8
-+	orr	r12,r12,r9
-+	orr	r12,r12,r10
-+	orr	r12,r12,r11
-+	cmp	r12,#0
-+#ifdef	__thumb2__
-+	it	ne
-+#endif
-+	movne	r12,#-1
-+	stmia	r3,{r4-r11}
-+	str	r12,[sp,#32*15+4]	@ !in1infty
-+
-+	ldmia	$b_ptr!,{r4-r11}	@ copy in2_x
-+	add	r3,sp,#$in2_x
-+	orr	r12,r4,r5
-+	orr	r12,r12,r6
-+	orr	r12,r12,r7
-+	orr	r12,r12,r8
-+	orr	r12,r12,r9
-+	orr	r12,r12,r10
-+	orr	r12,r12,r11
-+	stmia	r3!,{r4-r11}
-+	ldmia	$b_ptr!,{r4-r11}	@ copy in2_y
-+	orr	r12,r12,r4
-+	orr	r12,r12,r5
-+	orr	r12,r12,r6
-+	orr	r12,r12,r7
-+	orr	r12,r12,r8
-+	orr	r12,r12,r9
-+	orr	r12,r12,r10
-+	orr	r12,r12,r11
-+	stmia	r3!,{r4-r11}
-+	cmp	r12,#0
-+#ifdef	__thumb2__
-+	it	ne
-+#endif
-+	movne	r12,#-1
-+	str	r12,[sp,#32*15+8]	@ !in2infty
-+
-+	add	$a_ptr,sp,#$in1_z
-+	add	$b_ptr,sp,#$in1_z
-+	add	$r_ptr,sp,#$Z1sqr
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(Z1sqr, in1_z);
-+
-+	add	$a_ptr,sp,#$Z1sqr
-+	add	$b_ptr,sp,#$in2_x
-+	add	$r_ptr,sp,#$U2
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(U2, Z1sqr, in2_x);
-+
-+	add	$b_ptr,sp,#$in1_x
-+	add	$r_ptr,sp,#$H
-+	bl	__ecp_nistz256_sub_from	@ p256_sub(H, U2, in1_x);
-+
-+	add	$a_ptr,sp,#$Z1sqr
-+	add	$b_ptr,sp,#$in1_z
-+	add	$r_ptr,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(S2, Z1sqr, in1_z);
-+
-+	add	$a_ptr,sp,#$H
-+	add	$b_ptr,sp,#$in1_z
-+	add	$r_ptr,sp,#$res_z
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(res_z, H, in1_z);
-+
-+	add	$a_ptr,sp,#$in2_y
-+	add	$b_ptr,sp,#$S2
-+	add	$r_ptr,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(S2, S2, in2_y);
-+
-+	add	$b_ptr,sp,#$in1_y
-+	add	$r_ptr,sp,#$R
-+	bl	__ecp_nistz256_sub_from	@ p256_sub(R, S2, in1_y);
-+
-+	add	$a_ptr,sp,#$H
-+	add	$b_ptr,sp,#$H
-+	add	$r_ptr,sp,#$Hsqr
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(Hsqr, H);
-+
-+	add	$a_ptr,sp,#$R
-+	add	$b_ptr,sp,#$R
-+	add	$r_ptr,sp,#$Rsqr
-+	bl	__ecp_nistz256_mul_mont	@ p256_sqr_mont(Rsqr, R);
-+
-+	add	$a_ptr,sp,#$H
-+	add	$b_ptr,sp,#$Hsqr
-+	add	$r_ptr,sp,#$Hcub
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(Hcub, Hsqr, H);
-+
-+	add	$a_ptr,sp,#$Hsqr
-+	add	$b_ptr,sp,#$in1_x
-+	add	$r_ptr,sp,#$U2
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(U2, in1_x, Hsqr);
-+
-+	add	$r_ptr,sp,#$Hsqr
-+	bl	__ecp_nistz256_add_self	@ p256_mul_by_2(Hsqr, U2);
-+
-+	add	$b_ptr,sp,#$Rsqr
-+	add	$r_ptr,sp,#$res_x
-+	bl	__ecp_nistz256_sub_morf	@ p256_sub(res_x, Rsqr, Hsqr);
-+
-+	add	$b_ptr,sp,#$Hcub
-+	bl	__ecp_nistz256_sub_from	@  p256_sub(res_x, res_x, Hcub);
-+
-+	add	$b_ptr,sp,#$U2
-+	add	$r_ptr,sp,#$res_y
-+	bl	__ecp_nistz256_sub_morf	@ p256_sub(res_y, U2, res_x);
-+
-+	add	$a_ptr,sp,#$Hcub
-+	add	$b_ptr,sp,#$in1_y
-+	add	$r_ptr,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(S2, in1_y, Hcub);
-+
-+	add	$a_ptr,sp,#$R
-+	add	$b_ptr,sp,#$res_y
-+	add	$r_ptr,sp,#$res_y
-+	bl	__ecp_nistz256_mul_mont	@ p256_mul_mont(res_y, res_y, R);
-+
-+	add	$b_ptr,sp,#$S2
-+	bl	__ecp_nistz256_sub_from	@ p256_sub(res_y, res_y, S2);
-+
-+	ldr	r11,[sp,#32*15+4]	@ !in1intfy
-+	ldr	r12,[sp,#32*15+8]	@ !in2intfy
-+	add	r1,sp,#$res_x
-+	add	r2,sp,#$in2_x
-+	and	r10,r11,r12
-+	mvn	r11,r11
-+	add	r3,sp,#$in1_x
-+	and	r11,r11,r12
-+	mvn	r12,r12
-+	ldr	$r_ptr,[sp,#32*15]
-+___
-+for($i=0;$i<64;$i+=8) {			# conditional moves
-+$code.=<<___;
-+	ldmia	r1!,{r4-r5}		@ res_x
-+	ldmia	r2!,{r6-r7}		@ in2_x
-+	ldmia	r3!,{r8-r9}		@ in1_x
-+	and	r4,r4,r10
-+	and	r5,r5,r10
-+	and	r6,r6,r11
-+	and	r7,r7,r11
-+	and	r8,r8,r12
-+	and	r9,r9,r12
-+	orr	r4,r4,r6
-+	orr	r5,r5,r7
-+	orr	r4,r4,r8
-+	orr	r5,r5,r9
-+	stmia	$r_ptr!,{r4-r5}
-+___
-+}
-+for(;$i<96;$i+=8) {
-+my $j=($i-64)/4;
-+$code.=<<___;
-+	ldmia	r1!,{r4-r5}		@ res_z
-+	ldmia	r3!,{r8-r9}		@ in1_z
-+	and	r4,r4,r10
-+	and	r5,r5,r10
-+	and	r6,r11,#@ONE_mont[$j]
-+	and	r7,r11,#@ONE_mont[$j+1]
-+	and	r8,r8,r12
-+	and	r9,r9,r12
-+	orr	r4,r4,r6
-+	orr	r5,r5,r7
-+	orr	r4,r4,r8
-+	orr	r5,r5,r9
-+	stmia	$r_ptr!,{r4-r5}
-+___
-+}
-+$code.=<<___;
-+	add	sp,sp,#32*15+16		@ +16 means "skip even over saved r0-r3"
-+#if __ARM_ARCH__>=5 || !defined(__thumb__)
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
-+___
-+}					}}}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo;
-+
-+	print $_,"\n";
-+}
-+close STDOUT;	# enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-armv8.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-armv8.pl
-new file mode 100644
-index 0000000..cdc9161
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-armv8.pl
-@@ -0,0 +1,1558 @@
-+#! /usr/bin/env perl
-+# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# ECP_NISTZ256 module for ARMv8.
-+#
-+# February 2015.
-+#
-+# Original ECP_NISTZ256 submission targeting x86_64 is detailed in
-+# http://eprint.iacr.org/2013/816.
-+#
-+#			with/without -DECP_NISTZ256_ASM
-+# Apple A7		+120-360%
-+# Cortex-A53		+120-400%
-+# Cortex-A57		+120-350%
-+# X-Gene		+200-330%
-+# Denver		+140-400%
-+#
-+# Ranges denote minimum and maximum improvement coefficients depending
-+# on benchmark. Lower coefficients are for ECDSA sign, server-side
-+# operation. Keep in mind that +400% means 5x improvement.
-+
-+$flavour = shift;
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+{
-+my ($rp,$ap,$bp,$bi,$a0,$a1,$a2,$a3,$t0,$t1,$t2,$t3,$poly1,$poly3,
-+    $acc0,$acc1,$acc2,$acc3,$acc4,$acc5) =
-+    map("x$_",(0..17,19,20));
-+
-+my ($acc6,$acc7)=($ap,$bp);	# used in __ecp_nistz256_sqr_mont
-+
-+$code.=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+___
-+########################################################################
-+# Convert ecp_nistz256_table.c to layout expected by ecp_nistz_gather_w7
-+#
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+open TABLE,") {
-+	s/TOBN\(\s*(0x[0-9a-f]+),\s*(0x[0-9a-f]+)\s*\)/push @arr,hex($2),hex($1)/geo;
-+}
-+close TABLE;
-+
-+# See ecp_nistz256_table.c for explanation for why it's 64*16*37.
-+# 64*16*37-1 is because $#arr returns last valid index or @arr, not
-+# amount of elements.
-+die "insane number of elements" if ($#arr != 64*16*37-1);
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_precomputed
-+.type	ecp_nistz256_precomputed,%object
-+.align	12
-+ecp_nistz256_precomputed:
-+___
-+########################################################################
-+# this conversion smashes P256_POINT_AFFINE by individual bytes with
-+# 64 byte interval, similar to
-+#	1111222233334444
-+#	1234123412341234
-+for(1..37) {
-+	@tbl = splice(@arr,0,64*16);
-+	for($i=0;$i<64;$i++) {
-+		undef @line;
-+		for($j=0;$j<64;$j++) {
-+			push @line,(@tbl[$j*16+$i/4]>>(($i%4)*8))&0xff;
-+		}
-+		$code.=".byte\t";
-+		$code.=join(',',map { sprintf "0x%02x",$_} @line);
-+		$code.="\n";
-+	}
-+}
-+$code.=<<___;
-+.size	ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
-+.align	5
-+.Lpoly:
-+.quad	0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001
-+.LRR:	// 2^512 mod P precomputed for NIST P256 polynomial
-+.quad	0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd
-+.Lone_mont:
-+.quad	0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe
-+.Lone:
-+.quad	1,0,0,0
-+.asciz	"ECP_NISTZ256 for ARMv8, CRYPTOGAMS by "
-+
-+// void	ecp_nistz256_to_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
-+.globl	ecp_nistz256_to_mont
-+.type	ecp_nistz256_to_mont,%function
-+.align	6
-+ecp_nistz256_to_mont:
-+	stp	x29,x30,[sp,#-32]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+
-+	ldr	$bi,.LRR		// bp[0]
-+	ldp	$a0,$a1,[$ap]
-+	ldp	$a2,$a3,[$ap,#16]
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+	adr	$bp,.LRR		// &bp[0]
-+
-+	bl	__ecp_nistz256_mul_mont
-+
-+	ldp	x19,x20,[sp,#16]
-+	ldp	x29,x30,[sp],#32
-+	ret
-+.size	ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
-+
-+// void	ecp_nistz256_from_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
-+.globl	ecp_nistz256_from_mont
-+.type	ecp_nistz256_from_mont,%function
-+.align	4
-+ecp_nistz256_from_mont:
-+	stp	x29,x30,[sp,#-32]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+
-+	mov	$bi,#1			// bp[0]
-+	ldp	$a0,$a1,[$ap]
-+	ldp	$a2,$a3,[$ap,#16]
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+	adr	$bp,.Lone		// &bp[0]
-+
-+	bl	__ecp_nistz256_mul_mont
-+
-+	ldp	x19,x20,[sp,#16]
-+	ldp	x29,x30,[sp],#32
-+	ret
-+.size	ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
-+
-+// void	ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4],
-+//					     const BN_ULONG x2[4]);
-+.globl	ecp_nistz256_mul_mont
-+.type	ecp_nistz256_mul_mont,%function
-+.align	4
-+ecp_nistz256_mul_mont:
-+	stp	x29,x30,[sp,#-32]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+
-+	ldr	$bi,[$bp]		// bp[0]
-+	ldp	$a0,$a1,[$ap]
-+	ldp	$a2,$a3,[$ap,#16]
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+
-+	bl	__ecp_nistz256_mul_mont
-+
-+	ldp	x19,x20,[sp,#16]
-+	ldp	x29,x30,[sp],#32
-+	ret
-+.size	ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
-+
-+// void	ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
-+.globl	ecp_nistz256_sqr_mont
-+.type	ecp_nistz256_sqr_mont,%function
-+.align	4
-+ecp_nistz256_sqr_mont:
-+	stp	x29,x30,[sp,#-32]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+
-+	ldp	$a0,$a1,[$ap]
-+	ldp	$a2,$a3,[$ap,#16]
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+
-+	bl	__ecp_nistz256_sqr_mont
-+
-+	ldp	x19,x20,[sp,#16]
-+	ldp	x29,x30,[sp],#32
-+	ret
-+.size	ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
-+
-+// void	ecp_nistz256_add(BN_ULONG x0[4],const BN_ULONG x1[4],
-+//					const BN_ULONG x2[4]);
-+.globl	ecp_nistz256_add
-+.type	ecp_nistz256_add,%function
-+.align	4
-+ecp_nistz256_add:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	ldp	$acc0,$acc1,[$ap]
-+	ldp	$t0,$t1,[$bp]
-+	ldp	$acc2,$acc3,[$ap,#16]
-+	ldp	$t2,$t3,[$bp,#16]
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+
-+	bl	__ecp_nistz256_add
-+
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	ecp_nistz256_add,.-ecp_nistz256_add
-+
-+// void	ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]);
-+.globl	ecp_nistz256_div_by_2
-+.type	ecp_nistz256_div_by_2,%function
-+.align	4
-+ecp_nistz256_div_by_2:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	ldp	$acc0,$acc1,[$ap]
-+	ldp	$acc2,$acc3,[$ap,#16]
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+
-+	bl	__ecp_nistz256_div_by_2
-+
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
-+
-+// void	ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]);
-+.globl	ecp_nistz256_mul_by_2
-+.type	ecp_nistz256_mul_by_2,%function
-+.align	4
-+ecp_nistz256_mul_by_2:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	ldp	$acc0,$acc1,[$ap]
-+	ldp	$acc2,$acc3,[$ap,#16]
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+	mov	$t0,$acc0
-+	mov	$t1,$acc1
-+	mov	$t2,$acc2
-+	mov	$t3,$acc3
-+
-+	bl	__ecp_nistz256_add	// ret = a+a	// 2*a
-+
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
-+
-+// void	ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]);
-+.globl	ecp_nistz256_mul_by_3
-+.type	ecp_nistz256_mul_by_3,%function
-+.align	4
-+ecp_nistz256_mul_by_3:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	ldp	$acc0,$acc1,[$ap]
-+	ldp	$acc2,$acc3,[$ap,#16]
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+	mov	$t0,$acc0
-+	mov	$t1,$acc1
-+	mov	$t2,$acc2
-+	mov	$t3,$acc3
-+	mov	$a0,$acc0
-+	mov	$a1,$acc1
-+	mov	$a2,$acc2
-+	mov	$a3,$acc3
-+
-+	bl	__ecp_nistz256_add	// ret = a+a	// 2*a
-+
-+	mov	$t0,$a0
-+	mov	$t1,$a1
-+	mov	$t2,$a2
-+	mov	$t3,$a3
-+
-+	bl	__ecp_nistz256_add	// ret += a	// 2*a+a=3*a
-+
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
-+
-+// void	ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4],
-+//				        const BN_ULONG x2[4]);
-+.globl	ecp_nistz256_sub
-+.type	ecp_nistz256_sub,%function
-+.align	4
-+ecp_nistz256_sub:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	ldp	$acc0,$acc1,[$ap]
-+	ldp	$acc2,$acc3,[$ap,#16]
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+
-+	bl	__ecp_nistz256_sub_from
-+
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	ecp_nistz256_sub,.-ecp_nistz256_sub
-+
-+// void	ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]);
-+.globl	ecp_nistz256_neg
-+.type	ecp_nistz256_neg,%function
-+.align	4
-+ecp_nistz256_neg:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	mov	$bp,$ap
-+	mov	$acc0,xzr		// a = 0
-+	mov	$acc1,xzr
-+	mov	$acc2,xzr
-+	mov	$acc3,xzr
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+
-+	bl	__ecp_nistz256_sub_from
-+
-+	ldp	x29,x30,[sp],#16
-+	ret
-+.size	ecp_nistz256_neg,.-ecp_nistz256_neg
-+
-+// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded
-+// to $a0-$a3 and b[0] - to $bi
-+.type	__ecp_nistz256_mul_mont,%function
-+.align	4
-+__ecp_nistz256_mul_mont:
-+	mul	$acc0,$a0,$bi		// a[0]*b[0]
-+	umulh	$t0,$a0,$bi
-+
-+	mul	$acc1,$a1,$bi		// a[1]*b[0]
-+	umulh	$t1,$a1,$bi
-+
-+	mul	$acc2,$a2,$bi		// a[2]*b[0]
-+	umulh	$t2,$a2,$bi
-+
-+	mul	$acc3,$a3,$bi		// a[3]*b[0]
-+	umulh	$t3,$a3,$bi
-+	ldr	$bi,[$bp,#8]		// b[1]
-+
-+	adds	$acc1,$acc1,$t0		// accumulate high parts of multiplication
-+	 lsl	$t0,$acc0,#32
-+	adcs	$acc2,$acc2,$t1
-+	 lsr	$t1,$acc0,#32
-+	adcs	$acc3,$acc3,$t2
-+	adc	$acc4,xzr,$t3
-+	mov	$acc5,xzr
-+___
-+for($i=1;$i<4;$i++) {
-+        # Reduction iteration is normally performed by accumulating
-+        # result of multiplication of modulus by "magic" digit [and
-+        # omitting least significant word, which is guaranteed to
-+        # be 0], but thanks to special form of modulus and "magic"
-+        # digit being equal to least significant word, it can be
-+        # performed with additions and subtractions alone. Indeed:
-+        #
-+        #            ffff0001.00000000.0000ffff.ffffffff
-+        # *                                     abcdefgh
-+        # + xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh
-+        #
-+        # Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we
-+        # rewrite above as:
-+        #
-+        #   xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh
-+        # + abcdefgh.abcdefgh.0000abcd.efgh0000.00000000
-+        # - 0000abcd.efgh0000.00000000.00000000.abcdefgh
-+        #
-+        # or marking redundant operations:
-+        #
-+        #   xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.--------
-+        # + abcdefgh.abcdefgh.0000abcd.efgh0000.--------
-+        # - 0000abcd.efgh0000.--------.--------.--------
-+
-+$code.=<<___;
-+	subs	$t2,$acc0,$t0		// "*0xffff0001"
-+	sbc	$t3,$acc0,$t1
-+	adds	$acc0,$acc1,$t0		// +=acc[0]<<96 and omit acc[0]
-+	 mul	$t0,$a0,$bi		// lo(a[0]*b[i])
-+	adcs	$acc1,$acc2,$t1
-+	 mul	$t1,$a1,$bi		// lo(a[1]*b[i])
-+	adcs	$acc2,$acc3,$t2		// +=acc[0]*0xffff0001
-+	 mul	$t2,$a2,$bi		// lo(a[2]*b[i])
-+	adcs	$acc3,$acc4,$t3
-+	 mul	$t3,$a3,$bi		// lo(a[3]*b[i])
-+	adc	$acc4,$acc5,xzr
-+
-+	adds	$acc0,$acc0,$t0		// accumulate low parts of multiplication
-+	 umulh	$t0,$a0,$bi		// hi(a[0]*b[i])
-+	adcs	$acc1,$acc1,$t1
-+	 umulh	$t1,$a1,$bi		// hi(a[1]*b[i])
-+	adcs	$acc2,$acc2,$t2
-+	 umulh	$t2,$a2,$bi		// hi(a[2]*b[i])
-+	adcs	$acc3,$acc3,$t3
-+	 umulh	$t3,$a3,$bi		// hi(a[3]*b[i])
-+	adc	$acc4,$acc4,xzr
-+___
-+$code.=<<___	if ($i<3);
-+	ldr	$bi,[$bp,#8*($i+1)]	// b[$i+1]
-+___
-+$code.=<<___;
-+	adds	$acc1,$acc1,$t0		// accumulate high parts of multiplication
-+	 lsl	$t0,$acc0,#32
-+	adcs	$acc2,$acc2,$t1
-+	 lsr	$t1,$acc0,#32
-+	adcs	$acc3,$acc3,$t2
-+	adcs	$acc4,$acc4,$t3
-+	adc	$acc5,xzr,xzr
-+___
-+}
-+$code.=<<___;
-+	// last reduction
-+	subs	$t2,$acc0,$t0		// "*0xffff0001"
-+	sbc	$t3,$acc0,$t1
-+	adds	$acc0,$acc1,$t0		// +=acc[0]<<96 and omit acc[0]
-+	adcs	$acc1,$acc2,$t1
-+	adcs	$acc2,$acc3,$t2		// +=acc[0]*0xffff0001
-+	adcs	$acc3,$acc4,$t3
-+	adc	$acc4,$acc5,xzr
-+
-+	adds	$t0,$acc0,#1		// subs	$t0,$acc0,#-1 // tmp = ret-modulus
-+	sbcs	$t1,$acc1,$poly1
-+	sbcs	$t2,$acc2,xzr
-+	sbcs	$t3,$acc3,$poly3
-+	sbcs	xzr,$acc4,xzr		// did it borrow?
-+
-+	csel	$acc0,$acc0,$t0,lo	// ret = borrow ? ret : ret-modulus
-+	csel	$acc1,$acc1,$t1,lo
-+	csel	$acc2,$acc2,$t2,lo
-+	stp	$acc0,$acc1,[$rp]
-+	csel	$acc3,$acc3,$t3,lo
-+	stp	$acc2,$acc3,[$rp,#16]
-+
-+	ret
-+.size	__ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont
-+
-+// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded
-+// to $a0-$a3
-+.type	__ecp_nistz256_sqr_mont,%function
-+.align	4
-+__ecp_nistz256_sqr_mont:
-+	//  |  |  |  |  |  |a1*a0|  |
-+	//  |  |  |  |  |a2*a0|  |  |
-+	//  |  |a3*a2|a3*a0|  |  |  |
-+	//  |  |  |  |a2*a1|  |  |  |
-+	//  |  |  |a3*a1|  |  |  |  |
-+	// *|  |  |  |  |  |  |  | 2|
-+	// +|a3*a3|a2*a2|a1*a1|a0*a0|
-+	//  |--+--+--+--+--+--+--+--|
-+	//  |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx
-+	//
-+	//  "can't overflow" below mark carrying into high part of
-+	//  multiplication result, which can't overflow, because it
-+	//  can never be all ones.
-+
-+	mul	$acc1,$a1,$a0		// a[1]*a[0]
-+	umulh	$t1,$a1,$a0
-+	mul	$acc2,$a2,$a0		// a[2]*a[0]
-+	umulh	$t2,$a2,$a0
-+	mul	$acc3,$a3,$a0		// a[3]*a[0]
-+	umulh	$acc4,$a3,$a0
-+
-+	adds	$acc2,$acc2,$t1		// accumulate high parts of multiplication
-+	 mul	$t0,$a2,$a1		// a[2]*a[1]
-+	 umulh	$t1,$a2,$a1
-+	adcs	$acc3,$acc3,$t2
-+	 mul	$t2,$a3,$a1		// a[3]*a[1]
-+	 umulh	$t3,$a3,$a1
-+	adc	$acc4,$acc4,xzr		// can't overflow
-+
-+	mul	$acc5,$a3,$a2		// a[3]*a[2]
-+	umulh	$acc6,$a3,$a2
-+
-+	adds	$t1,$t1,$t2		// accumulate high parts of multiplication
-+	 mul	$acc0,$a0,$a0		// a[0]*a[0]
-+	adc	$t2,$t3,xzr		// can't overflow
-+
-+	adds	$acc3,$acc3,$t0		// accumulate low parts of multiplication
-+	 umulh	$a0,$a0,$a0
-+	adcs	$acc4,$acc4,$t1
-+	 mul	$t1,$a1,$a1		// a[1]*a[1]
-+	adcs	$acc5,$acc5,$t2
-+	 umulh	$a1,$a1,$a1
-+	adc	$acc6,$acc6,xzr		// can't overflow
-+
-+	adds	$acc1,$acc1,$acc1	// acc[1-6]*=2
-+	 mul	$t2,$a2,$a2		// a[2]*a[2]
-+	adcs	$acc2,$acc2,$acc2
-+	 umulh	$a2,$a2,$a2
-+	adcs	$acc3,$acc3,$acc3
-+	 mul	$t3,$a3,$a3		// a[3]*a[3]
-+	adcs	$acc4,$acc4,$acc4
-+	 umulh	$a3,$a3,$a3
-+	adcs	$acc5,$acc5,$acc5
-+	adcs	$acc6,$acc6,$acc6
-+	adc	$acc7,xzr,xzr
-+
-+	adds	$acc1,$acc1,$a0		// +a[i]*a[i]
-+	adcs	$acc2,$acc2,$t1
-+	adcs	$acc3,$acc3,$a1
-+	adcs	$acc4,$acc4,$t2
-+	adcs	$acc5,$acc5,$a2
-+	 lsl	$t0,$acc0,#32
-+	adcs	$acc6,$acc6,$t3
-+	 lsr	$t1,$acc0,#32
-+	adc	$acc7,$acc7,$a3
-+___
-+for($i=0;$i<3;$i++) {			# reductions, see commentary in
-+					# multiplication for details
-+$code.=<<___;
-+	subs	$t2,$acc0,$t0		// "*0xffff0001"
-+	sbc	$t3,$acc0,$t1
-+	adds	$acc0,$acc1,$t0		// +=acc[0]<<96 and omit acc[0]
-+	adcs	$acc1,$acc2,$t1
-+	 lsl	$t0,$acc0,#32
-+	adcs	$acc2,$acc3,$t2		// +=acc[0]*0xffff0001
-+	 lsr	$t1,$acc0,#32
-+	adc	$acc3,$t3,xzr		// can't overflow
-+___
-+}
-+$code.=<<___;
-+	subs	$t2,$acc0,$t0		// "*0xffff0001"
-+	sbc	$t3,$acc0,$t1
-+	adds	$acc0,$acc1,$t0		// +=acc[0]<<96 and omit acc[0]
-+	adcs	$acc1,$acc2,$t1
-+	adcs	$acc2,$acc3,$t2		// +=acc[0]*0xffff0001
-+	adc	$acc3,$t3,xzr		// can't overflow
-+
-+	adds	$acc0,$acc0,$acc4	// accumulate upper half
-+	adcs	$acc1,$acc1,$acc5
-+	adcs	$acc2,$acc2,$acc6
-+	adcs	$acc3,$acc3,$acc7
-+	adc	$acc4,xzr,xzr
-+
-+	adds	$t0,$acc0,#1		// subs	$t0,$acc0,#-1 // tmp = ret-modulus
-+	sbcs	$t1,$acc1,$poly1
-+	sbcs	$t2,$acc2,xzr
-+	sbcs	$t3,$acc3,$poly3
-+	sbcs	xzr,$acc4,xzr		// did it borrow?
-+
-+	csel	$acc0,$acc0,$t0,lo	// ret = borrow ? ret : ret-modulus
-+	csel	$acc1,$acc1,$t1,lo
-+	csel	$acc2,$acc2,$t2,lo
-+	stp	$acc0,$acc1,[$rp]
-+	csel	$acc3,$acc3,$t3,lo
-+	stp	$acc2,$acc3,[$rp,#16]
-+
-+	ret
-+.size	__ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont
-+
-+// Note that __ecp_nistz256_add expects both input vectors pre-loaded to
-+// $a0-$a3 and $t0-$t3. This is done because it's used in multiple
-+// contexts, e.g. in multiplication by 2 and 3...
-+.type	__ecp_nistz256_add,%function
-+.align	4
-+__ecp_nistz256_add:
-+	adds	$acc0,$acc0,$t0		// ret = a+b
-+	adcs	$acc1,$acc1,$t1
-+	adcs	$acc2,$acc2,$t2
-+	adcs	$acc3,$acc3,$t3
-+	adc	$ap,xzr,xzr		// zap $ap
-+
-+	adds	$t0,$acc0,#1		// subs	$t0,$a0,#-1 // tmp = ret-modulus
-+	sbcs	$t1,$acc1,$poly1
-+	sbcs	$t2,$acc2,xzr
-+	sbcs	$t3,$acc3,$poly3
-+	sbcs	xzr,$ap,xzr		// did subtraction borrow?
-+
-+	csel	$acc0,$acc0,$t0,lo	// ret = borrow ? ret : ret-modulus
-+	csel	$acc1,$acc1,$t1,lo
-+	csel	$acc2,$acc2,$t2,lo
-+	stp	$acc0,$acc1,[$rp]
-+	csel	$acc3,$acc3,$t3,lo
-+	stp	$acc2,$acc3,[$rp,#16]
-+
-+	ret
-+.size	__ecp_nistz256_add,.-__ecp_nistz256_add
-+
-+.type	__ecp_nistz256_sub_from,%function
-+.align	4
-+__ecp_nistz256_sub_from:
-+	ldp	$t0,$t1,[$bp]
-+	ldp	$t2,$t3,[$bp,#16]
-+	subs	$acc0,$acc0,$t0		// ret = a-b
-+	sbcs	$acc1,$acc1,$t1
-+	sbcs	$acc2,$acc2,$t2
-+	sbcs	$acc3,$acc3,$t3
-+	sbc	$ap,xzr,xzr		// zap $ap
-+
-+	subs	$t0,$acc0,#1		// adds	$t0,$a0,#-1 // tmp = ret+modulus
-+	adcs	$t1,$acc1,$poly1
-+	adcs	$t2,$acc2,xzr
-+	adc	$t3,$acc3,$poly3
-+	cmp	$ap,xzr			// did subtraction borrow?
-+
-+	csel	$acc0,$acc0,$t0,eq	// ret = borrow ? ret+modulus : ret
-+	csel	$acc1,$acc1,$t1,eq
-+	csel	$acc2,$acc2,$t2,eq
-+	stp	$acc0,$acc1,[$rp]
-+	csel	$acc3,$acc3,$t3,eq
-+	stp	$acc2,$acc3,[$rp,#16]
-+
-+	ret
-+.size	__ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from
-+
-+.type	__ecp_nistz256_sub_morf,%function
-+.align	4
-+__ecp_nistz256_sub_morf:
-+	ldp	$t0,$t1,[$bp]
-+	ldp	$t2,$t3,[$bp,#16]
-+	subs	$acc0,$t0,$acc0		// ret = b-a
-+	sbcs	$acc1,$t1,$acc1
-+	sbcs	$acc2,$t2,$acc2
-+	sbcs	$acc3,$t3,$acc3
-+	sbc	$ap,xzr,xzr		// zap $ap
-+
-+	subs	$t0,$acc0,#1		// adds	$t0,$a0,#-1 // tmp = ret+modulus
-+	adcs	$t1,$acc1,$poly1
-+	adcs	$t2,$acc2,xzr
-+	adc	$t3,$acc3,$poly3
-+	cmp	$ap,xzr			// did subtraction borrow?
-+
-+	csel	$acc0,$acc0,$t0,eq	// ret = borrow ? ret+modulus : ret
-+	csel	$acc1,$acc1,$t1,eq
-+	csel	$acc2,$acc2,$t2,eq
-+	stp	$acc0,$acc1,[$rp]
-+	csel	$acc3,$acc3,$t3,eq
-+	stp	$acc2,$acc3,[$rp,#16]
-+
-+	ret
-+.size	__ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf
-+
-+.type	__ecp_nistz256_div_by_2,%function
-+.align	4
-+__ecp_nistz256_div_by_2:
-+	subs	$t0,$acc0,#1		// adds	$t0,$a0,#-1 // tmp = a+modulus
-+	adcs	$t1,$acc1,$poly1
-+	adcs	$t2,$acc2,xzr
-+	adcs	$t3,$acc3,$poly3
-+	adc	$ap,xzr,xzr		// zap $ap
-+	tst	$acc0,#1		// is a even?
-+
-+	csel	$acc0,$acc0,$t0,eq	// ret = even ? a : a+modulus 
-+	csel	$acc1,$acc1,$t1,eq
-+	csel	$acc2,$acc2,$t2,eq
-+	csel	$acc3,$acc3,$t3,eq
-+	csel	$ap,xzr,$ap,eq
-+
-+	lsr	$acc0,$acc0,#1		// ret >>= 1
-+	orr	$acc0,$acc0,$acc1,lsl#63
-+	lsr	$acc1,$acc1,#1
-+	orr	$acc1,$acc1,$acc2,lsl#63
-+	lsr	$acc2,$acc2,#1
-+	orr	$acc2,$acc2,$acc3,lsl#63
-+	lsr	$acc3,$acc3,#1
-+	stp	$acc0,$acc1,[$rp]
-+	orr	$acc3,$acc3,$ap,lsl#63
-+	stp	$acc2,$acc3,[$rp,#16]
-+
-+	ret
-+.size	__ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2
-+___
-+########################################################################
-+# following subroutines are "literal" implementation of those found in
-+# ecp_nistz256.c
-+#
-+########################################################################
-+# void ecp_nistz256_point_double(P256_POINT *out,const P256_POINT *inp);
-+#
-+{
-+my ($S,$M,$Zsqr,$tmp0)=map(32*$_,(0..3));
-+# above map() describes stack layout with 4 temporary
-+# 256-bit vectors on top.
-+my ($rp_real,$ap_real) = map("x$_",(21,22));
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_double
-+.type	ecp_nistz256_point_double,%function
-+.align	5
-+ecp_nistz256_point_double:
-+	stp	x29,x30,[sp,#-80]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	sub	sp,sp,#32*4
-+
-+.Ldouble_shortcut:
-+	ldp	$acc0,$acc1,[$ap,#32]
-+	 mov	$rp_real,$rp
-+	ldp	$acc2,$acc3,[$ap,#48]
-+	 mov	$ap_real,$ap
-+	 ldr	$poly1,.Lpoly+8
-+	mov	$t0,$acc0
-+	 ldr	$poly3,.Lpoly+24
-+	mov	$t1,$acc1
-+	 ldp	$a0,$a1,[$ap_real,#64]	// forward load for p256_sqr_mont
-+	mov	$t2,$acc2
-+	mov	$t3,$acc3
-+	 ldp	$a2,$a3,[$ap_real,#64+16]
-+	add	$rp,sp,#$S
-+	bl	__ecp_nistz256_add	// p256_mul_by_2(S, in_y);
-+
-+	add	$rp,sp,#$Zsqr
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(Zsqr, in_z);
-+
-+	ldp	$t0,$t1,[$ap_real]
-+	ldp	$t2,$t3,[$ap_real,#16]
-+	mov	$a0,$acc0		// put Zsqr aside for p256_sub
-+	mov	$a1,$acc1
-+	mov	$a2,$acc2
-+	mov	$a3,$acc3
-+	add	$rp,sp,#$M
-+	bl	__ecp_nistz256_add	// p256_add(M, Zsqr, in_x);
-+
-+	add	$bp,$ap_real,#0
-+	mov	$acc0,$a0		// restore Zsqr
-+	mov	$acc1,$a1
-+	 ldp	$a0,$a1,[sp,#$S]	// forward load for p256_sqr_mont
-+	mov	$acc2,$a2
-+	mov	$acc3,$a3
-+	 ldp	$a2,$a3,[sp,#$S+16]
-+	add	$rp,sp,#$Zsqr
-+	bl	__ecp_nistz256_sub_morf	// p256_sub(Zsqr, in_x, Zsqr);
-+
-+	add	$rp,sp,#$S
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(S, S);
-+
-+	ldr	$bi,[$ap_real,#32]
-+	ldp	$a0,$a1,[$ap_real,#64]
-+	ldp	$a2,$a3,[$ap_real,#64+16]
-+	add	$bp,$ap_real,#32
-+	add	$rp,sp,#$tmp0
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(tmp0, in_z, in_y);
-+
-+	mov	$t0,$acc0
-+	mov	$t1,$acc1
-+	 ldp	$a0,$a1,[sp,#$S]	// forward load for p256_sqr_mont
-+	mov	$t2,$acc2
-+	mov	$t3,$acc3
-+	 ldp	$a2,$a3,[sp,#$S+16]
-+	add	$rp,$rp_real,#64
-+	bl	__ecp_nistz256_add	// p256_mul_by_2(res_z, tmp0);
-+
-+	add	$rp,sp,#$tmp0
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(tmp0, S);
-+
-+	 ldr	$bi,[sp,#$Zsqr]		// forward load for p256_mul_mont
-+	 ldp	$a0,$a1,[sp,#$M]
-+	 ldp	$a2,$a3,[sp,#$M+16]
-+	add	$rp,$rp_real,#32
-+	bl	__ecp_nistz256_div_by_2	// p256_div_by_2(res_y, tmp0);
-+
-+	add	$bp,sp,#$Zsqr
-+	add	$rp,sp,#$M
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(M, M, Zsqr);
-+
-+	mov	$t0,$acc0		// duplicate M
-+	mov	$t1,$acc1
-+	mov	$t2,$acc2
-+	mov	$t3,$acc3
-+	mov	$a0,$acc0		// put M aside
-+	mov	$a1,$acc1
-+	mov	$a2,$acc2
-+	mov	$a3,$acc3
-+	add	$rp,sp,#$M
-+	bl	__ecp_nistz256_add
-+	mov	$t0,$a0			// restore M
-+	mov	$t1,$a1
-+	 ldr	$bi,[$ap_real]		// forward load for p256_mul_mont
-+	mov	$t2,$a2
-+	 ldp	$a0,$a1,[sp,#$S]
-+	mov	$t3,$a3
-+	 ldp	$a2,$a3,[sp,#$S+16]
-+	bl	__ecp_nistz256_add	// p256_mul_by_3(M, M);
-+
-+	add	$bp,$ap_real,#0
-+	add	$rp,sp,#$S
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(S, S, in_x);
-+
-+	mov	$t0,$acc0
-+	mov	$t1,$acc1
-+	 ldp	$a0,$a1,[sp,#$M]	// forward load for p256_sqr_mont
-+	mov	$t2,$acc2
-+	mov	$t3,$acc3
-+	 ldp	$a2,$a3,[sp,#$M+16]
-+	add	$rp,sp,#$tmp0
-+	bl	__ecp_nistz256_add	// p256_mul_by_2(tmp0, S);
-+
-+	add	$rp,$rp_real,#0
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(res_x, M);
-+
-+	add	$bp,sp,#$tmp0
-+	bl	__ecp_nistz256_sub_from	// p256_sub(res_x, res_x, tmp0);
-+
-+	add	$bp,sp,#$S
-+	add	$rp,sp,#$S
-+	bl	__ecp_nistz256_sub_morf	// p256_sub(S, S, res_x);
-+
-+	ldr	$bi,[sp,#$M]
-+	mov	$a0,$acc0		// copy S
-+	mov	$a1,$acc1
-+	mov	$a2,$acc2
-+	mov	$a3,$acc3
-+	add	$bp,sp,#$M
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(S, S, M);
-+
-+	add	$bp,$rp_real,#32
-+	add	$rp,$rp_real,#32
-+	bl	__ecp_nistz256_sub_from	// p256_sub(res_y, S, res_y);
-+
-+	add	sp,x29,#0		// destroy frame
-+	ldp	x19,x20,[x29,#16]
-+	ldp	x21,x22,[x29,#32]
-+	ldp	x29,x30,[sp],#80
-+	ret
-+.size	ecp_nistz256_point_double,.-ecp_nistz256_point_double
-+___
-+}
-+
-+########################################################################
-+# void ecp_nistz256_point_add(P256_POINT *out,const P256_POINT *in1,
-+#			      const P256_POINT *in2);
-+{
-+my ($res_x,$res_y,$res_z,
-+    $H,$Hsqr,$R,$Rsqr,$Hcub,
-+    $U1,$U2,$S1,$S2)=map(32*$_,(0..11));
-+my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
-+# above map() describes stack layout with 12 temporary
-+# 256-bit vectors on top.
-+my ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp)=map("x$_",(21..26));
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_add
-+.type	ecp_nistz256_point_add,%function
-+.align	5
-+ecp_nistz256_point_add:
-+	stp	x29,x30,[sp,#-80]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	stp	x23,x24,[sp,#48]
-+	stp	x25,x26,[sp,#64]
-+	sub	sp,sp,#32*12
-+
-+	ldp	$a0,$a1,[$bp,#64]	// in2_z
-+	ldp	$a2,$a3,[$bp,#64+16]
-+	 mov	$rp_real,$rp
-+	 mov	$ap_real,$ap
-+	 mov	$bp_real,$bp
-+	 ldr	$poly1,.Lpoly+8
-+	 ldr	$poly3,.Lpoly+24
-+	orr	$t0,$a0,$a1
-+	orr	$t2,$a2,$a3
-+	orr	$in2infty,$t0,$t2
-+	cmp	$in2infty,#0
-+	csetm	$in2infty,ne		// !in2infty
-+	add	$rp,sp,#$Z2sqr
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(Z2sqr, in2_z);
-+
-+	ldp	$a0,$a1,[$ap_real,#64]	// in1_z
-+	ldp	$a2,$a3,[$ap_real,#64+16]
-+	orr	$t0,$a0,$a1
-+	orr	$t2,$a2,$a3
-+	orr	$in1infty,$t0,$t2
-+	cmp	$in1infty,#0
-+	csetm	$in1infty,ne		// !in1infty
-+	add	$rp,sp,#$Z1sqr
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(Z1sqr, in1_z);
-+
-+	ldr	$bi,[$bp_real,#64]
-+	ldp	$a0,$a1,[sp,#$Z2sqr]
-+	ldp	$a2,$a3,[sp,#$Z2sqr+16]
-+	add	$bp,$bp_real,#64
-+	add	$rp,sp,#$S1
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(S1, Z2sqr, in2_z);
-+
-+	ldr	$bi,[$ap_real,#64]
-+	ldp	$a0,$a1,[sp,#$Z1sqr]
-+	ldp	$a2,$a3,[sp,#$Z1sqr+16]
-+	add	$bp,$ap_real,#64
-+	add	$rp,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(S2, Z1sqr, in1_z);
-+
-+	ldr	$bi,[$ap_real,#32]
-+	ldp	$a0,$a1,[sp,#$S1]
-+	ldp	$a2,$a3,[sp,#$S1+16]
-+	add	$bp,$ap_real,#32
-+	add	$rp,sp,#$S1
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(S1, S1, in1_y);
-+
-+	ldr	$bi,[$bp_real,#32]
-+	ldp	$a0,$a1,[sp,#$S2]
-+	ldp	$a2,$a3,[sp,#$S2+16]
-+	add	$bp,$bp_real,#32
-+	add	$rp,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(S2, S2, in2_y);
-+
-+	add	$bp,sp,#$S1
-+	 ldr	$bi,[sp,#$Z2sqr]	// forward load for p256_mul_mont
-+	 ldp	$a0,$a1,[$ap_real]
-+	 ldp	$a2,$a3,[$ap_real,#16]
-+	add	$rp,sp,#$R
-+	bl	__ecp_nistz256_sub_from	// p256_sub(R, S2, S1);
-+
-+	orr	$acc0,$acc0,$acc1	// see if result is zero
-+	orr	$acc2,$acc2,$acc3
-+	orr	$temp,$acc0,$acc2
-+
-+	add	$bp,sp,#$Z2sqr
-+	add	$rp,sp,#$U1
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(U1, in1_x, Z2sqr);
-+
-+	ldr	$bi,[sp,#$Z1sqr]
-+	ldp	$a0,$a1,[$bp_real]
-+	ldp	$a2,$a3,[$bp_real,#16]
-+	add	$bp,sp,#$Z1sqr
-+	add	$rp,sp,#$U2
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(U2, in2_x, Z1sqr);
-+
-+	add	$bp,sp,#$U1
-+	 ldp	$a0,$a1,[sp,#$R]	// forward load for p256_sqr_mont
-+	 ldp	$a2,$a3,[sp,#$R+16]
-+	add	$rp,sp,#$H
-+	bl	__ecp_nistz256_sub_from	// p256_sub(H, U2, U1);
-+
-+	orr	$acc0,$acc0,$acc1	// see if result is zero
-+	orr	$acc2,$acc2,$acc3
-+	orr	$acc0,$acc0,$acc2
-+	tst	$acc0,$acc0
-+	b.ne	.Ladd_proceed		// is_equal(U1,U2)?
-+
-+	tst	$in1infty,$in2infty
-+	b.eq	.Ladd_proceed		// (in1infty || in2infty)?
-+
-+	tst	$temp,$temp
-+	b.eq	.Ladd_double		// is_equal(S1,S2)?
-+
-+	eor	$a0,$a0,$a0
-+	eor	$a1,$a1,$a1
-+	stp	$a0,$a1,[$rp_real]
-+	stp	$a0,$a1,[$rp_real,#16]
-+	stp	$a0,$a1,[$rp_real,#32]
-+	stp	$a0,$a1,[$rp_real,#48]
-+	stp	$a0,$a1,[$rp_real,#64]
-+	stp	$a0,$a1,[$rp_real,#80]
-+	b	.Ladd_done
-+
-+.align	4
-+.Ladd_double:
-+	mov	$ap,$ap_real
-+	mov	$rp,$rp_real
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	add	sp,sp,#32*(12-4)	// difference in stack frames
-+	b	.Ldouble_shortcut
-+
-+.align	4
-+.Ladd_proceed:
-+	add	$rp,sp,#$Rsqr
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(Rsqr, R);
-+
-+	ldr	$bi,[$ap_real,#64]
-+	ldp	$a0,$a1,[sp,#$H]
-+	ldp	$a2,$a3,[sp,#$H+16]
-+	add	$bp,$ap_real,#64
-+	add	$rp,sp,#$res_z
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(res_z, H, in1_z);
-+
-+	ldp	$a0,$a1,[sp,#$H]
-+	ldp	$a2,$a3,[sp,#$H+16]
-+	add	$rp,sp,#$Hsqr
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(Hsqr, H);
-+
-+	ldr	$bi,[$bp_real,#64]
-+	ldp	$a0,$a1,[sp,#$res_z]
-+	ldp	$a2,$a3,[sp,#$res_z+16]
-+	add	$bp,$bp_real,#64
-+	add	$rp,sp,#$res_z
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(res_z, res_z, in2_z);
-+
-+	ldr	$bi,[sp,#$H]
-+	ldp	$a0,$a1,[sp,#$Hsqr]
-+	ldp	$a2,$a3,[sp,#$Hsqr+16]
-+	add	$bp,sp,#$H
-+	add	$rp,sp,#$Hcub
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(Hcub, Hsqr, H);
-+
-+	ldr	$bi,[sp,#$Hsqr]
-+	ldp	$a0,$a1,[sp,#$U1]
-+	ldp	$a2,$a3,[sp,#$U1+16]
-+	add	$bp,sp,#$Hsqr
-+	add	$rp,sp,#$U2
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(U2, U1, Hsqr);
-+
-+	mov	$t0,$acc0
-+	mov	$t1,$acc1
-+	mov	$t2,$acc2
-+	mov	$t3,$acc3
-+	add	$rp,sp,#$Hsqr
-+	bl	__ecp_nistz256_add	// p256_mul_by_2(Hsqr, U2);
-+
-+	add	$bp,sp,#$Rsqr
-+	add	$rp,sp,#$res_x
-+	bl	__ecp_nistz256_sub_morf	// p256_sub(res_x, Rsqr, Hsqr);
-+
-+	add	$bp,sp,#$Hcub
-+	bl	__ecp_nistz256_sub_from	//  p256_sub(res_x, res_x, Hcub);
-+
-+	add	$bp,sp,#$U2
-+	 ldr	$bi,[sp,#$Hcub]		// forward load for p256_mul_mont
-+	 ldp	$a0,$a1,[sp,#$S1]
-+	 ldp	$a2,$a3,[sp,#$S1+16]
-+	add	$rp,sp,#$res_y
-+	bl	__ecp_nistz256_sub_morf	// p256_sub(res_y, U2, res_x);
-+
-+	add	$bp,sp,#$Hcub
-+	add	$rp,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(S2, S1, Hcub);
-+
-+	ldr	$bi,[sp,#$R]
-+	ldp	$a0,$a1,[sp,#$res_y]
-+	ldp	$a2,$a3,[sp,#$res_y+16]
-+	add	$bp,sp,#$R
-+	add	$rp,sp,#$res_y
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(res_y, res_y, R);
-+
-+	add	$bp,sp,#$S2
-+	bl	__ecp_nistz256_sub_from	// p256_sub(res_y, res_y, S2);
-+
-+	ldp	$a0,$a1,[sp,#$res_x]		// res
-+	ldp	$a2,$a3,[sp,#$res_x+16]
-+	ldp	$t0,$t1,[$bp_real]		// in2
-+	ldp	$t2,$t3,[$bp_real,#16]
-+___
-+for($i=0;$i<64;$i+=32) {		# conditional moves
-+$code.=<<___;
-+	ldp	$acc0,$acc1,[$ap_real,#$i]	// in1
-+	cmp	$in1infty,#0			// !$in1intfy, remember?
-+	ldp	$acc2,$acc3,[$ap_real,#$i+16]
-+	csel	$t0,$a0,$t0,ne
-+	csel	$t1,$a1,$t1,ne
-+	ldp	$a0,$a1,[sp,#$res_x+$i+32]	// res
-+	csel	$t2,$a2,$t2,ne
-+	csel	$t3,$a3,$t3,ne
-+	cmp	$in2infty,#0			// !$in2intfy, remember?
-+	ldp	$a2,$a3,[sp,#$res_x+$i+48]
-+	csel	$acc0,$t0,$acc0,ne
-+	csel	$acc1,$t1,$acc1,ne
-+	ldp	$t0,$t1,[$bp_real,#$i+32]	// in2
-+	csel	$acc2,$t2,$acc2,ne
-+	csel	$acc3,$t3,$acc3,ne
-+	ldp	$t2,$t3,[$bp_real,#$i+48]
-+	stp	$acc0,$acc1,[$rp_real,#$i]
-+	stp	$acc2,$acc3,[$rp_real,#$i+16]
-+___
-+}
-+$code.=<<___;
-+	ldp	$acc0,$acc1,[$ap_real,#$i]	// in1
-+	cmp	$in1infty,#0			// !$in1intfy, remember?
-+	ldp	$acc2,$acc3,[$ap_real,#$i+16]
-+	csel	$t0,$a0,$t0,ne
-+	csel	$t1,$a1,$t1,ne
-+	csel	$t2,$a2,$t2,ne
-+	csel	$t3,$a3,$t3,ne
-+	cmp	$in2infty,#0			// !$in2intfy, remember?
-+	csel	$acc0,$t0,$acc0,ne
-+	csel	$acc1,$t1,$acc1,ne
-+	csel	$acc2,$t2,$acc2,ne
-+	csel	$acc3,$t3,$acc3,ne
-+	stp	$acc0,$acc1,[$rp_real,#$i]
-+	stp	$acc2,$acc3,[$rp_real,#$i+16]
-+
-+.Ladd_done:
-+	add	sp,x29,#0	// destroy frame
-+	ldp	x19,x20,[x29,#16]
-+	ldp	x21,x22,[x29,#32]
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	ldp	x29,x30,[sp],#80
-+	ret
-+.size	ecp_nistz256_point_add,.-ecp_nistz256_point_add
-+___
-+}
-+
-+########################################################################
-+# void ecp_nistz256_point_add_affine(P256_POINT *out,const P256_POINT *in1,
-+#				     const P256_POINT_AFFINE *in2);
-+{
-+my ($res_x,$res_y,$res_z,
-+    $U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr)=map(32*$_,(0..9));
-+my $Z1sqr = $S2;
-+# above map() describes stack layout with 10 temporary
-+# 256-bit vectors on top.
-+my ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp)=map("x$_",(21..26));
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_add_affine
-+.type	ecp_nistz256_point_add_affine,%function
-+.align	5
-+ecp_nistz256_point_add_affine:
-+	stp	x29,x30,[sp,#-80]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	stp	x23,x24,[sp,#48]
-+	stp	x25,x26,[sp,#64]
-+	sub	sp,sp,#32*10
-+
-+	mov	$rp_real,$rp
-+	mov	$ap_real,$ap
-+	mov	$bp_real,$bp
-+	ldr	$poly1,.Lpoly+8
-+	ldr	$poly3,.Lpoly+24
-+
-+	ldp	$a0,$a1,[$ap,#64]	// in1_z
-+	ldp	$a2,$a3,[$ap,#64+16]
-+	orr	$t0,$a0,$a1
-+	orr	$t2,$a2,$a3
-+	orr	$in1infty,$t0,$t2
-+	cmp	$in1infty,#0
-+	csetm	$in1infty,ne		// !in1infty
-+
-+	ldp	$acc0,$acc1,[$bp]	// in2_x
-+	ldp	$acc2,$acc3,[$bp,#16]
-+	ldp	$t0,$t1,[$bp,#32]	// in2_y
-+	ldp	$t2,$t3,[$bp,#48]
-+	orr	$acc0,$acc0,$acc1
-+	orr	$acc2,$acc2,$acc3
-+	orr	$t0,$t0,$t1
-+	orr	$t2,$t2,$t3
-+	orr	$acc0,$acc0,$acc2
-+	orr	$t0,$t0,$t2
-+	orr	$in2infty,$acc0,$t0
-+	cmp	$in2infty,#0
-+	csetm	$in2infty,ne		// !in2infty
-+
-+	add	$rp,sp,#$Z1sqr
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(Z1sqr, in1_z);
-+
-+	mov	$a0,$acc0
-+	mov	$a1,$acc1
-+	mov	$a2,$acc2
-+	mov	$a3,$acc3
-+	ldr	$bi,[$bp_real]
-+	add	$bp,$bp_real,#0
-+	add	$rp,sp,#$U2
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(U2, Z1sqr, in2_x);
-+
-+	add	$bp,$ap_real,#0
-+	 ldr	$bi,[$ap_real,#64]	// forward load for p256_mul_mont
-+	 ldp	$a0,$a1,[sp,#$Z1sqr]
-+	 ldp	$a2,$a3,[sp,#$Z1sqr+16]
-+	add	$rp,sp,#$H
-+	bl	__ecp_nistz256_sub_from	// p256_sub(H, U2, in1_x);
-+
-+	add	$bp,$ap_real,#64
-+	add	$rp,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(S2, Z1sqr, in1_z);
-+
-+	ldr	$bi,[$ap_real,#64]
-+	ldp	$a0,$a1,[sp,#$H]
-+	ldp	$a2,$a3,[sp,#$H+16]
-+	add	$bp,$ap_real,#64
-+	add	$rp,sp,#$res_z
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(res_z, H, in1_z);
-+
-+	ldr	$bi,[$bp_real,#32]
-+	ldp	$a0,$a1,[sp,#$S2]
-+	ldp	$a2,$a3,[sp,#$S2+16]
-+	add	$bp,$bp_real,#32
-+	add	$rp,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(S2, S2, in2_y);
-+
-+	add	$bp,$ap_real,#32
-+	 ldp	$a0,$a1,[sp,#$H]	// forward load for p256_sqr_mont
-+	 ldp	$a2,$a3,[sp,#$H+16]
-+	add	$rp,sp,#$R
-+	bl	__ecp_nistz256_sub_from	// p256_sub(R, S2, in1_y);
-+
-+	add	$rp,sp,#$Hsqr
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(Hsqr, H);
-+
-+	ldp	$a0,$a1,[sp,#$R]
-+	ldp	$a2,$a3,[sp,#$R+16]
-+	add	$rp,sp,#$Rsqr
-+	bl	__ecp_nistz256_sqr_mont	// p256_sqr_mont(Rsqr, R);
-+
-+	ldr	$bi,[sp,#$H]
-+	ldp	$a0,$a1,[sp,#$Hsqr]
-+	ldp	$a2,$a3,[sp,#$Hsqr+16]
-+	add	$bp,sp,#$H
-+	add	$rp,sp,#$Hcub
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(Hcub, Hsqr, H);
-+
-+	ldr	$bi,[$ap_real]
-+	ldp	$a0,$a1,[sp,#$Hsqr]
-+	ldp	$a2,$a3,[sp,#$Hsqr+16]
-+	add	$bp,$ap_real,#0
-+	add	$rp,sp,#$U2
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(U2, in1_x, Hsqr);
-+
-+	mov	$t0,$acc0
-+	mov	$t1,$acc1
-+	mov	$t2,$acc2
-+	mov	$t3,$acc3
-+	add	$rp,sp,#$Hsqr
-+	bl	__ecp_nistz256_add	// p256_mul_by_2(Hsqr, U2);
-+
-+	add	$bp,sp,#$Rsqr
-+	add	$rp,sp,#$res_x
-+	bl	__ecp_nistz256_sub_morf	// p256_sub(res_x, Rsqr, Hsqr);
-+
-+	add	$bp,sp,#$Hcub
-+	bl	__ecp_nistz256_sub_from	//  p256_sub(res_x, res_x, Hcub);
-+
-+	add	$bp,sp,#$U2
-+	 ldr	$bi,[$ap_real,#32]	// forward load for p256_mul_mont
-+	 ldp	$a0,$a1,[sp,#$Hcub]
-+	 ldp	$a2,$a3,[sp,#$Hcub+16]
-+	add	$rp,sp,#$res_y
-+	bl	__ecp_nistz256_sub_morf	// p256_sub(res_y, U2, res_x);
-+
-+	add	$bp,$ap_real,#32
-+	add	$rp,sp,#$S2
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(S2, in1_y, Hcub);
-+
-+	ldr	$bi,[sp,#$R]
-+	ldp	$a0,$a1,[sp,#$res_y]
-+	ldp	$a2,$a3,[sp,#$res_y+16]
-+	add	$bp,sp,#$R
-+	add	$rp,sp,#$res_y
-+	bl	__ecp_nistz256_mul_mont	// p256_mul_mont(res_y, res_y, R);
-+
-+	add	$bp,sp,#$S2
-+	bl	__ecp_nistz256_sub_from	// p256_sub(res_y, res_y, S2);
-+
-+	ldp	$a0,$a1,[sp,#$res_x]		// res
-+	ldp	$a2,$a3,[sp,#$res_x+16]
-+	ldp	$t0,$t1,[$bp_real]		// in2
-+	ldp	$t2,$t3,[$bp_real,#16]
-+___
-+for($i=0;$i<64;$i+=32) {		# conditional moves
-+$code.=<<___;
-+	ldp	$acc0,$acc1,[$ap_real,#$i]	// in1
-+	cmp	$in1infty,#0			// !$in1intfy, remember?
-+	ldp	$acc2,$acc3,[$ap_real,#$i+16]
-+	csel	$t0,$a0,$t0,ne
-+	csel	$t1,$a1,$t1,ne
-+	ldp	$a0,$a1,[sp,#$res_x+$i+32]	// res
-+	csel	$t2,$a2,$t2,ne
-+	csel	$t3,$a3,$t3,ne
-+	cmp	$in2infty,#0			// !$in2intfy, remember?
-+	ldp	$a2,$a3,[sp,#$res_x+$i+48]
-+	csel	$acc0,$t0,$acc0,ne
-+	csel	$acc1,$t1,$acc1,ne
-+	ldp	$t0,$t1,[$bp_real,#$i+32]	// in2
-+	csel	$acc2,$t2,$acc2,ne
-+	csel	$acc3,$t3,$acc3,ne
-+	ldp	$t2,$t3,[$bp_real,#$i+48]
-+	stp	$acc0,$acc1,[$rp_real,#$i]
-+	stp	$acc2,$acc3,[$rp_real,#$i+16]
-+___
-+$code.=<<___	if ($i == 0);
-+	adr	$bp_real,.Lone_mont-64
-+___
-+}
-+$code.=<<___;
-+	ldp	$acc0,$acc1,[$ap_real,#$i]	// in1
-+	cmp	$in1infty,#0			// !$in1intfy, remember?
-+	ldp	$acc2,$acc3,[$ap_real,#$i+16]
-+	csel	$t0,$a0,$t0,ne
-+	csel	$t1,$a1,$t1,ne
-+	csel	$t2,$a2,$t2,ne
-+	csel	$t3,$a3,$t3,ne
-+	cmp	$in2infty,#0			// !$in2intfy, remember?
-+	csel	$acc0,$t0,$acc0,ne
-+	csel	$acc1,$t1,$acc1,ne
-+	csel	$acc2,$t2,$acc2,ne
-+	csel	$acc3,$t3,$acc3,ne
-+	stp	$acc0,$acc1,[$rp_real,#$i]
-+	stp	$acc2,$acc3,[$rp_real,#$i+16]
-+
-+	add	sp,x29,#0		// destroy frame
-+	ldp	x19,x20,[x29,#16]
-+	ldp	x21,x22,[x29,#32]
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	ldp	x29,x30,[sp],#80
-+	ret
-+.size	ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
-+___
-+}	}
-+
-+########################################################################
-+# scatter-gather subroutines
-+{
-+my ($out,$inp,$index,$mask)=map("x$_",(0..3));
-+$code.=<<___;
-+// void	ecp_nistz256_scatter_w5(void *x0,const P256_POINT *x1,
-+//					 int x2);
-+.globl	ecp_nistz256_scatter_w5
-+.type	ecp_nistz256_scatter_w5,%function
-+.align	4
-+ecp_nistz256_scatter_w5:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	add	$out,$out,$index,lsl#2
-+
-+	ldp	x4,x5,[$inp]		// X
-+	ldp	x6,x7,[$inp,#16]
-+	str	w4,[$out,#64*0-4]
-+	lsr	x4,x4,#32
-+	str	w5,[$out,#64*1-4]
-+	lsr	x5,x5,#32
-+	str	w6,[$out,#64*2-4]
-+	lsr	x6,x6,#32
-+	str	w7,[$out,#64*3-4]
-+	lsr	x7,x7,#32
-+	str	w4,[$out,#64*4-4]
-+	str	w5,[$out,#64*5-4]
-+	str	w6,[$out,#64*6-4]
-+	str	w7,[$out,#64*7-4]
-+	add	$out,$out,#64*8
-+
-+	ldp	x4,x5,[$inp,#32]	// Y
-+	ldp	x6,x7,[$inp,#48]
-+	str	w4,[$out,#64*0-4]
-+	lsr	x4,x4,#32
-+	str	w5,[$out,#64*1-4]
-+	lsr	x5,x5,#32
-+	str	w6,[$out,#64*2-4]
-+	lsr	x6,x6,#32
-+	str	w7,[$out,#64*3-4]
-+	lsr	x7,x7,#32
-+	str	w4,[$out,#64*4-4]
-+	str	w5,[$out,#64*5-4]
-+	str	w6,[$out,#64*6-4]
-+	str	w7,[$out,#64*7-4]
-+	add	$out,$out,#64*8
-+
-+	ldp	x4,x5,[$inp,#64]	// Z
-+	ldp	x6,x7,[$inp,#80]
-+	str	w4,[$out,#64*0-4]
-+	lsr	x4,x4,#32
-+	str	w5,[$out,#64*1-4]
-+	lsr	x5,x5,#32
-+	str	w6,[$out,#64*2-4]
-+	lsr	x6,x6,#32
-+	str	w7,[$out,#64*3-4]
-+	lsr	x7,x7,#32
-+	str	w4,[$out,#64*4-4]
-+	str	w5,[$out,#64*5-4]
-+	str	w6,[$out,#64*6-4]
-+	str	w7,[$out,#64*7-4]
-+
-+	ldr	x29,[sp],#16
-+	ret
-+.size	ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5
-+
-+// void	ecp_nistz256_gather_w5(P256_POINT *x0,const void *x1,
-+//					      int x2);
-+.globl	ecp_nistz256_gather_w5
-+.type	ecp_nistz256_gather_w5,%function
-+.align	4
-+ecp_nistz256_gather_w5:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	cmp	$index,xzr
-+	csetm	x3,ne
-+	add	$index,$index,x3
-+	add	$inp,$inp,$index,lsl#2
-+
-+	ldr	w4,[$inp,#64*0]
-+	ldr	w5,[$inp,#64*1]
-+	ldr	w6,[$inp,#64*2]
-+	ldr	w7,[$inp,#64*3]
-+	ldr	w8,[$inp,#64*4]
-+	ldr	w9,[$inp,#64*5]
-+	ldr	w10,[$inp,#64*6]
-+	ldr	w11,[$inp,#64*7]
-+	add	$inp,$inp,#64*8
-+	orr	x4,x4,x8,lsl#32
-+	orr	x5,x5,x9,lsl#32
-+	orr	x6,x6,x10,lsl#32
-+	orr	x7,x7,x11,lsl#32
-+	csel	x4,x4,xzr,ne
-+	csel	x5,x5,xzr,ne
-+	csel	x6,x6,xzr,ne
-+	csel	x7,x7,xzr,ne
-+	stp	x4,x5,[$out]		// X
-+	stp	x6,x7,[$out,#16]
-+
-+	ldr	w4,[$inp,#64*0]
-+	ldr	w5,[$inp,#64*1]
-+	ldr	w6,[$inp,#64*2]
-+	ldr	w7,[$inp,#64*3]
-+	ldr	w8,[$inp,#64*4]
-+	ldr	w9,[$inp,#64*5]
-+	ldr	w10,[$inp,#64*6]
-+	ldr	w11,[$inp,#64*7]
-+	add	$inp,$inp,#64*8
-+	orr	x4,x4,x8,lsl#32
-+	orr	x5,x5,x9,lsl#32
-+	orr	x6,x6,x10,lsl#32
-+	orr	x7,x7,x11,lsl#32
-+	csel	x4,x4,xzr,ne
-+	csel	x5,x5,xzr,ne
-+	csel	x6,x6,xzr,ne
-+	csel	x7,x7,xzr,ne
-+	stp	x4,x5,[$out,#32]	// Y
-+	stp	x6,x7,[$out,#48]
-+
-+	ldr	w4,[$inp,#64*0]
-+	ldr	w5,[$inp,#64*1]
-+	ldr	w6,[$inp,#64*2]
-+	ldr	w7,[$inp,#64*3]
-+	ldr	w8,[$inp,#64*4]
-+	ldr	w9,[$inp,#64*5]
-+	ldr	w10,[$inp,#64*6]
-+	ldr	w11,[$inp,#64*7]
-+	orr	x4,x4,x8,lsl#32
-+	orr	x5,x5,x9,lsl#32
-+	orr	x6,x6,x10,lsl#32
-+	orr	x7,x7,x11,lsl#32
-+	csel	x4,x4,xzr,ne
-+	csel	x5,x5,xzr,ne
-+	csel	x6,x6,xzr,ne
-+	csel	x7,x7,xzr,ne
-+	stp	x4,x5,[$out,#64]	// Z
-+	stp	x6,x7,[$out,#80]
-+
-+	ldr	x29,[sp],#16
-+	ret
-+.size	ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5
-+
-+// void	ecp_nistz256_scatter_w7(void *x0,const P256_POINT_AFFINE *x1,
-+//					 int x2);
-+.globl	ecp_nistz256_scatter_w7
-+.type	ecp_nistz256_scatter_w7,%function
-+.align	4
-+ecp_nistz256_scatter_w7:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	add	$out,$out,$index
-+	mov	$index,#64/8
-+.Loop_scatter_w7:
-+	ldr	x3,[$inp],#8
-+	subs	$index,$index,#1
-+	prfm	pstl1strm,[$out,#4096+64*0]
-+	prfm	pstl1strm,[$out,#4096+64*1]
-+	prfm	pstl1strm,[$out,#4096+64*2]
-+	prfm	pstl1strm,[$out,#4096+64*3]
-+	prfm	pstl1strm,[$out,#4096+64*4]
-+	prfm	pstl1strm,[$out,#4096+64*5]
-+	prfm	pstl1strm,[$out,#4096+64*6]
-+	prfm	pstl1strm,[$out,#4096+64*7]
-+	strb	w3,[$out,#64*0-1]
-+	lsr	x3,x3,#8
-+	strb	w3,[$out,#64*1-1]
-+	lsr	x3,x3,#8
-+	strb	w3,[$out,#64*2-1]
-+	lsr	x3,x3,#8
-+	strb	w3,[$out,#64*3-1]
-+	lsr	x3,x3,#8
-+	strb	w3,[$out,#64*4-1]
-+	lsr	x3,x3,#8
-+	strb	w3,[$out,#64*5-1]
-+	lsr	x3,x3,#8
-+	strb	w3,[$out,#64*6-1]
-+	lsr	x3,x3,#8
-+	strb	w3,[$out,#64*7-1]
-+	add	$out,$out,#64*8
-+	b.ne	.Loop_scatter_w7
-+
-+	ldr	x29,[sp],#16
-+	ret
-+.size	ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7
-+
-+// void	ecp_nistz256_gather_w7(P256_POINT_AFFINE *x0,const void *x1,
-+//						     int x2);
-+.globl	ecp_nistz256_gather_w7
-+.type	ecp_nistz256_gather_w7,%function
-+.align	4
-+ecp_nistz256_gather_w7:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	cmp	$index,xzr
-+	csetm	x3,ne
-+	add	$index,$index,x3
-+	add	$inp,$inp,$index
-+	mov	$index,#64/8
-+	nop
-+.Loop_gather_w7:
-+	ldrb	w4,[$inp,#64*0]
-+	prfm	pldl1strm,[$inp,#4096+64*0]
-+	subs	$index,$index,#1
-+	ldrb	w5,[$inp,#64*1]
-+	prfm	pldl1strm,[$inp,#4096+64*1]
-+	ldrb	w6,[$inp,#64*2]
-+	prfm	pldl1strm,[$inp,#4096+64*2]
-+	ldrb	w7,[$inp,#64*3]
-+	prfm	pldl1strm,[$inp,#4096+64*3]
-+	ldrb	w8,[$inp,#64*4]
-+	prfm	pldl1strm,[$inp,#4096+64*4]
-+	ldrb	w9,[$inp,#64*5]
-+	prfm	pldl1strm,[$inp,#4096+64*5]
-+	ldrb	w10,[$inp,#64*6]
-+	prfm	pldl1strm,[$inp,#4096+64*6]
-+	ldrb	w11,[$inp,#64*7]
-+	prfm	pldl1strm,[$inp,#4096+64*7]
-+	add	$inp,$inp,#64*8
-+	orr	x4,x4,x5,lsl#8
-+	orr	x6,x6,x7,lsl#8
-+	orr	x8,x8,x9,lsl#8
-+	orr	x4,x4,x6,lsl#16
-+	orr	x10,x10,x11,lsl#8
-+	orr	x4,x4,x8,lsl#32
-+	orr	x4,x4,x10,lsl#48
-+	and	x4,x4,x3
-+	str	x4,[$out],#8
-+	b.ne	.Loop_gather_w7
-+
-+	ldr	x29,[sp],#16
-+	ret
-+.size	ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7
-+___
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	print $_,"\n";
-+}
-+close STDOUT;	# enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-avx2.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-avx2.pl
-new file mode 100755
-index 0000000..3bdd2cf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-avx2.pl
-@@ -0,0 +1,2100 @@
-+#! /usr/bin/env perl
-+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+##############################################################################
-+#                                                                            #
-+# Copyright 2014 Intel Corporation                                           #
-+#                                                                            #
-+# Licensed under the Apache License, Version 2.0 (the "License");            #
-+# you may not use this file except in compliance with the License.           #
-+# You may obtain a copy of the License at                                    #
-+#                                                                            #
-+#    http://www.apache.org/licenses/LICENSE-2.0                              #
-+#                                                                            #
-+# Unless required by applicable law or agreed to in writing, software        #
-+# distributed under the License is distributed on an "AS IS" BASIS,          #
-+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
-+# See the License for the specific language governing permissions and        #
-+# limitations under the License.                                             #
-+#                                                                            #
-+##############################################################################
-+#                                                                            #
-+#  Developers and authors:                                                   #
-+#  Shay Gueron (1, 2), and Vlad Krasnov (1)                                  #
-+#  (1) Intel Corporation, Israel Development Center                          #
-+#  (2) University of Haifa                                                   #
-+#  Reference:                                                                #
-+#  S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with#
-+#                           256 Bit Primes"                                  #
-+#                                                                            #
-+##############################################################################
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+	$addx = ($1>=2.23);
-+}
-+
-+if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	    `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+	$addx = ($1>=2.10);
-+}
-+
-+if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	    `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+	$addx = ($1>=12);
-+}
-+
-+if (!$addx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
-+	my $ver = $2 + $3/100.0;	# 3.1->3.01, 3.10->3.10
-+	$avx = ($ver>=3.0) + ($ver>=3.01);
-+	$addx = ($ver>=3.03);
-+}
-+
-+if ($avx>=2) {{
-+$digit_size = "\$29";
-+$n_digits = "\$9";
-+
-+$code.=<<___;
-+.text
-+
-+.align 64
-+.LAVX2_AND_MASK:
-+.LAVX2_POLY:
-+.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
-+.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
-+.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
-+.quad 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff
-+.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
-+.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
-+.quad 0x00040000, 0x00040000, 0x00040000, 0x00040000
-+.quad 0x1fe00000, 0x1fe00000, 0x1fe00000, 0x1fe00000
-+.quad 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff
-+
-+.LAVX2_POLY_x2:
-+.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
-+.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
-+.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
-+.quad 0x400007FC, 0x400007FC, 0x400007FC, 0x400007FC
-+.quad 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE
-+.quad 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE
-+.quad 0x400FFFFE, 0x400FFFFE, 0x400FFFFE, 0x400FFFFE
-+.quad 0x7F7FFFFE, 0x7F7FFFFE, 0x7F7FFFFE, 0x7F7FFFFE
-+.quad 0x03FFFFFC, 0x03FFFFFC, 0x03FFFFFC, 0x03FFFFFC
-+
-+.LAVX2_POLY_x8:
-+.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8
-+.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8
-+.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8
-+.quad 0x80000FF8, 0x80000FF8, 0x80000FF8, 0x80000FF8
-+.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
-+.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC
-+.quad 0x801FFFFC, 0x801FFFFC, 0x801FFFFC, 0x801FFFFC
-+.quad 0xFEFFFFFC, 0xFEFFFFFC, 0xFEFFFFFC, 0xFEFFFFFC
-+.quad 0x07FFFFF8, 0x07FFFFF8, 0x07FFFFF8, 0x07FFFFF8
-+
-+.LONE:
-+.quad 0x00000020, 0x00000020, 0x00000020, 0x00000020
-+.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
-+.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
-+.quad 0x1fffc000, 0x1fffc000, 0x1fffc000, 0x1fffc000
-+.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
-+.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
-+.quad 0x1f7fffff, 0x1f7fffff, 0x1f7fffff, 0x1f7fffff
-+.quad 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff
-+.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
-+
-+# RR = 2^266 mod p in AVX2 format, to transform from the native OpenSSL
-+# Montgomery form (*2^256) to our format (*2^261)
-+
-+.LTO_MONT_AVX2:
-+.quad 0x00000400, 0x00000400, 0x00000400, 0x00000400
-+.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
-+.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
-+.quad 0x1ff80000, 0x1ff80000, 0x1ff80000, 0x1ff80000
-+.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
-+.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
-+.quad 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff
-+.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
-+.quad 0x00000003, 0x00000003, 0x00000003, 0x00000003
-+
-+.LFROM_MONT_AVX2:
-+.quad 0x00000001, 0x00000001, 0x00000001, 0x00000001
-+.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
-+.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
-+.quad 0x1ffffe00, 0x1ffffe00, 0x1ffffe00, 0x1ffffe00
-+.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
-+.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff
-+.quad 0x1ffbffff, 0x1ffbffff, 0x1ffbffff, 0x1ffbffff
-+.quad 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff
-+.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000
-+
-+.LIntOne:
-+.long 1,1,1,1,1,1,1,1
-+___
-+
-+{
-+# This function receives a pointer to an array of four affine points
-+# (X, Y, <1>) and rearanges the data for AVX2 execution, while
-+# converting it to 2^29 radix redundant form
-+
-+my ($X0,$X1,$X2,$X3, $Y0,$Y1,$Y2,$Y3,
-+    $T0,$T1,$T2,$T3, $T4,$T5,$T6,$T7)=map("%ymm$_",(0..15));
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_avx2_transpose_convert
-+.type	ecp_nistz256_avx2_transpose_convert,\@function,2
-+.align 64
-+ecp_nistz256_avx2_transpose_convert:
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	lea	-8-16*10(%rsp), %rsp
-+	vmovaps	%xmm6, -8-16*10(%rax)
-+	vmovaps	%xmm7, -8-16*9(%rax)
-+	vmovaps	%xmm8, -8-16*8(%rax)
-+	vmovaps	%xmm9, -8-16*7(%rax)
-+	vmovaps	%xmm10, -8-16*6(%rax)
-+	vmovaps	%xmm11, -8-16*5(%rax)
-+	vmovaps	%xmm12, -8-16*4(%rax)
-+	vmovaps	%xmm13, -8-16*3(%rax)
-+	vmovaps	%xmm14, -8-16*2(%rax)
-+	vmovaps	%xmm15, -8-16*1(%rax)
-+___
-+$code.=<<___;
-+	# Load the data
-+	vmovdqa		32*0(%rsi), $X0
-+	lea		112(%rsi), %rax		# size optimization
-+	vmovdqa		32*1(%rsi), $Y0
-+	lea		.LAVX2_AND_MASK(%rip), %rdx
-+	vmovdqa		32*2(%rsi), $X1
-+	vmovdqa		32*3(%rsi), $Y1
-+	vmovdqa		32*4-112(%rax), $X2
-+	vmovdqa		32*5-112(%rax), $Y2
-+	vmovdqa		32*6-112(%rax), $X3
-+	vmovdqa		32*7-112(%rax), $Y3
-+
-+	# Transpose X and Y independently
-+	vpunpcklqdq	$X1, $X0, $T0		# T0 = [B2 A2 B0 A0]
-+	vpunpcklqdq	$X3, $X2, $T1		# T1 = [D2 C2 D0 C0]
-+	vpunpckhqdq	$X1, $X0, $T2		# T2 = [B3 A3 B1 A1]
-+	vpunpckhqdq	$X3, $X2, $T3		# T3 = [D3 C3 D1 C1]
-+
-+	vpunpcklqdq	$Y1, $Y0, $T4
-+	vpunpcklqdq	$Y3, $Y2, $T5
-+	vpunpckhqdq	$Y1, $Y0, $T6
-+	vpunpckhqdq	$Y3, $Y2, $T7
-+
-+	vperm2i128	\$0x20, $T1, $T0, $X0	# X0 = [D0 C0 B0 A0]
-+	vperm2i128	\$0x20, $T3, $T2, $X1	# X1 = [D1 C1 B1 A1]
-+	vperm2i128	\$0x31, $T1, $T0, $X2	# X2 = [D2 C2 B2 A2]
-+	vperm2i128	\$0x31, $T3, $T2, $X3	# X3 = [D3 C3 B3 A3]
-+
-+	vperm2i128	\$0x20, $T5, $T4, $Y0
-+	vperm2i128	\$0x20, $T7, $T6, $Y1
-+	vperm2i128	\$0x31, $T5, $T4, $Y2
-+	vperm2i128	\$0x31, $T7, $T6, $Y3
-+	vmovdqa		(%rdx), $T7
-+
-+	vpand		(%rdx), $X0, $T0	# out[0] = in[0] & mask;
-+	vpsrlq		\$29, $X0, $X0
-+	vpand		$T7, $X0, $T1		# out[1] = (in[0] >> shift) & mask;
-+	vpsrlq		\$29, $X0, $X0
-+	vpsllq		\$6, $X1, $T2
-+	vpxor		$X0, $T2, $T2
-+	vpand		$T7, $T2, $T2		# out[2] = ((in[0] >> (shift*2)) ^ (in[1] << (64-shift*2))) & mask;
-+	vpsrlq		\$23, $X1, $X1
-+	vpand		$T7, $X1, $T3		# out[3] = (in[1] >> ((shift*3)%64)) & mask;
-+	vpsrlq		\$29, $X1, $X1
-+	vpsllq		\$12, $X2, $T4
-+	vpxor		$X1, $T4, $T4
-+	vpand		$T7, $T4, $T4		# out[4] = ((in[1] >> ((shift*4)%64)) ^ (in[2] << (64*2-shift*4))) & mask;
-+	vpsrlq		\$17, $X2, $X2
-+	vpand		$T7, $X2, $T5		# out[5] = (in[2] >> ((shift*5)%64)) & mask;
-+	vpsrlq		\$29, $X2, $X2
-+	vpsllq		\$18, $X3, $T6
-+	vpxor		$X2, $T6, $T6
-+	vpand		$T7, $T6, $T6		# out[6] = ((in[2] >> ((shift*6)%64)) ^ (in[3] << (64*3-shift*6))) & mask;
-+	vpsrlq		\$11, $X3, $X3
-+	 vmovdqa	$T0, 32*0(%rdi)
-+	 lea		112(%rdi), %rax		# size optimization
-+	vpand		$T7, $X3, $T0		# out[7] = (in[3] >> ((shift*7)%64)) & mask;
-+	vpsrlq		\$29, $X3, $X3		# out[8] = (in[3] >> ((shift*8)%64)) & mask;
-+
-+	vmovdqa		$T1, 32*1(%rdi)
-+	vmovdqa		$T2, 32*2(%rdi)
-+	vmovdqa		$T3, 32*3(%rdi)
-+	vmovdqa		$T4, 32*4-112(%rax)
-+	vmovdqa		$T5, 32*5-112(%rax)
-+	vmovdqa		$T6, 32*6-112(%rax)
-+	vmovdqa		$T0, 32*7-112(%rax)
-+	vmovdqa		$X3, 32*8-112(%rax)
-+	lea		448(%rdi), %rax		# size optimization
-+
-+	vpand		$T7, $Y0, $T0		# out[0] = in[0] & mask;
-+	vpsrlq		\$29, $Y0, $Y0
-+	vpand		$T7, $Y0, $T1		# out[1] = (in[0] >> shift) & mask;
-+	vpsrlq		\$29, $Y0, $Y0
-+	vpsllq		\$6, $Y1, $T2
-+	vpxor		$Y0, $T2, $T2
-+	vpand		$T7, $T2, $T2		# out[2] = ((in[0] >> (shift*2)) ^ (in[1] << (64-shift*2))) & mask;
-+	vpsrlq		\$23, $Y1, $Y1
-+	vpand		$T7, $Y1, $T3		# out[3] = (in[1] >> ((shift*3)%64)) & mask;
-+	vpsrlq		\$29, $Y1, $Y1
-+	vpsllq		\$12, $Y2, $T4
-+	vpxor		$Y1, $T4, $T4
-+	vpand		$T7, $T4, $T4		# out[4] = ((in[1] >> ((shift*4)%64)) ^ (in[2] << (64*2-shift*4))) & mask;
-+	vpsrlq		\$17, $Y2, $Y2
-+	vpand		$T7, $Y2, $T5		# out[5] = (in[2] >> ((shift*5)%64)) & mask;
-+	vpsrlq		\$29, $Y2, $Y2
-+	vpsllq		\$18, $Y3, $T6
-+	vpxor		$Y2, $T6, $T6
-+	vpand		$T7, $T6, $T6		# out[6] = ((in[2] >> ((shift*6)%64)) ^ (in[3] << (64*3-shift*6))) & mask;
-+	vpsrlq		\$11, $Y3, $Y3
-+	 vmovdqa	$T0, 32*9-448(%rax)
-+	vpand		$T7, $Y3, $T0		# out[7] = (in[3] >> ((shift*7)%64)) & mask;
-+	vpsrlq		\$29, $Y3, $Y3		# out[8] = (in[3] >> ((shift*8)%64)) & mask;
-+
-+	vmovdqa		$T1, 32*10-448(%rax)
-+	vmovdqa		$T2, 32*11-448(%rax)
-+	vmovdqa		$T3, 32*12-448(%rax)
-+	vmovdqa		$T4, 32*13-448(%rax)
-+	vmovdqa		$T5, 32*14-448(%rax)
-+	vmovdqa		$T6, 32*15-448(%rax)
-+	vmovdqa		$T0, 32*16-448(%rax)
-+	vmovdqa		$Y3, 32*17-448(%rax)
-+
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	movaps	16*0(%rsp), %xmm6
-+	movaps	16*1(%rsp), %xmm7
-+	movaps	16*2(%rsp), %xmm8
-+	movaps	16*3(%rsp), %xmm9
-+	movaps	16*4(%rsp), %xmm10
-+	movaps	16*5(%rsp), %xmm11
-+	movaps	16*6(%rsp), %xmm12
-+	movaps	16*7(%rsp), %xmm13
-+	movaps	16*8(%rsp), %xmm14
-+	movaps	16*9(%rsp), %xmm15
-+	lea	8+16*10(%rsp), %rsp
-+___
-+$code.=<<___;
-+	ret
-+.size	ecp_nistz256_avx2_transpose_convert,.-ecp_nistz256_avx2_transpose_convert
-+___
-+}
-+{
-+################################################################################
-+# This function receives a pointer to an array of four AVX2 formatted points
-+# (X, Y, Z) convert the data to normal representation, and rearanges the data
-+
-+my ($D0,$D1,$D2,$D3, $D4,$D5,$D6,$D7, $D8)=map("%ymm$_",(0..8));
-+my ($T0,$T1,$T2,$T3, $T4,$T5,$T6)=map("%ymm$_",(9..15));
-+
-+$code.=<<___;
-+
-+.globl	ecp_nistz256_avx2_convert_transpose_back
-+.type	ecp_nistz256_avx2_convert_transpose_back,\@function,2
-+.align	32
-+ecp_nistz256_avx2_convert_transpose_back:
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	lea	-8-16*10(%rsp), %rsp
-+	vmovaps	%xmm6, -8-16*10(%rax)
-+	vmovaps	%xmm7, -8-16*9(%rax)
-+	vmovaps	%xmm8, -8-16*8(%rax)
-+	vmovaps	%xmm9, -8-16*7(%rax)
-+	vmovaps	%xmm10, -8-16*6(%rax)
-+	vmovaps	%xmm11, -8-16*5(%rax)
-+	vmovaps	%xmm12, -8-16*4(%rax)
-+	vmovaps	%xmm13, -8-16*3(%rax)
-+	vmovaps	%xmm14, -8-16*2(%rax)
-+	vmovaps	%xmm15, -8-16*1(%rax)
-+___
-+$code.=<<___;
-+	mov	\$3, %ecx
-+
-+.Lconv_loop:
-+	vmovdqa		32*0(%rsi), $D0
-+	lea		160(%rsi), %rax		# size optimization
-+	vmovdqa		32*1(%rsi), $D1
-+	vmovdqa		32*2(%rsi), $D2
-+	vmovdqa		32*3(%rsi), $D3
-+	vmovdqa		32*4-160(%rax), $D4
-+	vmovdqa		32*5-160(%rax), $D5
-+	vmovdqa		32*6-160(%rax), $D6
-+	vmovdqa		32*7-160(%rax), $D7
-+	vmovdqa		32*8-160(%rax), $D8
-+
-+	vpsllq		\$29, $D1, $D1
-+	vpsllq		\$58, $D2, $T0
-+	vpaddq		$D1, $D0, $D0
-+	vpaddq		$T0, $D0, $D0		# out[0] = (in[0]) ^ (in[1] << shift*1) ^ (in[2] << shift*2);
-+
-+	vpsrlq		\$6, $D2, $D2
-+	vpsllq		\$23, $D3, $D3
-+	vpsllq		\$52, $D4, $T1
-+	vpaddq		$D2, $D3, $D3
-+	vpaddq		$D3, $T1, $D1		# out[1] = (in[2] >> (64*1-shift*2)) ^ (in[3] << shift*3%64) ^ (in[4] << shift*4%64);
-+
-+	vpsrlq		\$12, $D4, $D4
-+	vpsllq		\$17, $D5, $D5
-+	vpsllq		\$46, $D6, $T2
-+	vpaddq		$D4, $D5, $D5
-+	vpaddq		$D5, $T2, $D2		# out[2] = (in[4] >> (64*2-shift*4)) ^ (in[5] << shift*5%64) ^ (in[6] << shift*6%64);
-+
-+	vpsrlq		\$18, $D6, $D6
-+	vpsllq		\$11, $D7, $D7
-+	vpsllq		\$40, $D8, $T3
-+	vpaddq		$D6, $D7, $D7
-+	vpaddq		$D7, $T3, $D3		# out[3] = (in[6] >> (64*3-shift*6)) ^ (in[7] << shift*7%64) ^ (in[8] << shift*8%64);
-+
-+	vpunpcklqdq	$D1, $D0, $T0		# T0 = [B2 A2 B0 A0]
-+	vpunpcklqdq	$D3, $D2, $T1		# T1 = [D2 C2 D0 C0]
-+	vpunpckhqdq	$D1, $D0, $T2		# T2 = [B3 A3 B1 A1]
-+	vpunpckhqdq	$D3, $D2, $T3		# T3 = [D3 C3 D1 C1]
-+
-+	vperm2i128	\$0x20, $T1, $T0, $D0	# X0 = [D0 C0 B0 A0]
-+	vperm2i128	\$0x20, $T3, $T2, $D1	# X1 = [D1 C1 B1 A1]
-+	vperm2i128	\$0x31, $T1, $T0, $D2	# X2 = [D2 C2 B2 A2]
-+	vperm2i128	\$0x31, $T3, $T2, $D3	# X3 = [D3 C3 B3 A3]
-+
-+	vmovdqa		$D0, 32*0(%rdi)
-+	vmovdqa		$D1, 32*3(%rdi)
-+	vmovdqa		$D2, 32*6(%rdi)
-+	vmovdqa		$D3, 32*9(%rdi)
-+
-+	lea		32*9(%rsi), %rsi
-+	lea		32*1(%rdi), %rdi
-+
-+	dec	%ecx
-+	jnz	.Lconv_loop
-+
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	movaps	16*0(%rsp), %xmm6
-+	movaps	16*1(%rsp), %xmm7
-+	movaps	16*2(%rsp), %xmm8
-+	movaps	16*3(%rsp), %xmm9
-+	movaps	16*4(%rsp), %xmm10
-+	movaps	16*5(%rsp), %xmm11
-+	movaps	16*6(%rsp), %xmm12
-+	movaps	16*7(%rsp), %xmm13
-+	movaps	16*8(%rsp), %xmm14
-+	movaps	16*9(%rsp), %xmm15
-+	lea	8+16*10(%rsp), %rsp
-+___
-+$code.=<<___;
-+	ret
-+.size	ecp_nistz256_avx2_convert_transpose_back,.-ecp_nistz256_avx2_convert_transpose_back
-+___
-+}
-+{
-+my ($r_ptr,$a_ptr,$b_ptr,$itr)=("%rdi","%rsi","%rdx","%ecx");
-+my ($ACC0,$ACC1,$ACC2,$ACC3,$ACC4,$ACC5,$ACC6,$ACC7,$ACC8)=map("%ymm$_",(0..8));
-+my ($B,$Y,$T0,$AND_MASK,$OVERFLOW)=map("%ymm$_",(9..13));
-+
-+sub NORMALIZE {
-+my $ret=<<___;
-+	vpsrlq		$digit_size, $ACC0, $T0
-+	vpand		$AND_MASK, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC1, $ACC1
-+
-+	vpsrlq		$digit_size, $ACC1, $T0
-+	vpand		$AND_MASK, $ACC1, $ACC1
-+	vpaddq		$T0, $ACC2, $ACC2
-+
-+	vpsrlq		$digit_size, $ACC2, $T0
-+	vpand		$AND_MASK, $ACC2, $ACC2
-+	vpaddq		$T0, $ACC3, $ACC3
-+
-+	vpsrlq		$digit_size, $ACC3, $T0
-+	vpand		$AND_MASK, $ACC3, $ACC3
-+	vpaddq		$T0, $ACC4, $ACC4
-+
-+	vpsrlq		$digit_size, $ACC4, $T0
-+	vpand		$AND_MASK, $ACC4, $ACC4
-+	vpaddq		$T0, $ACC5, $ACC5
-+
-+	vpsrlq		$digit_size, $ACC5, $T0
-+	vpand		$AND_MASK, $ACC5, $ACC5
-+	vpaddq		$T0, $ACC6, $ACC6
-+
-+	vpsrlq		$digit_size, $ACC6, $T0
-+	vpand		$AND_MASK, $ACC6, $ACC6
-+	vpaddq		$T0, $ACC7, $ACC7
-+
-+	vpsrlq		$digit_size, $ACC7, $T0
-+	vpand		$AND_MASK, $ACC7, $ACC7
-+	vpaddq		$T0, $ACC8, $ACC8
-+	#vpand		$AND_MASK, $ACC8, $ACC8
-+___
-+    $ret;
-+}
-+
-+sub STORE {
-+my $ret=<<___;
-+	vmovdqa		$ACC0, 32*0(%rdi)
-+	lea		160(%rdi), %rax		# size optimization
-+	vmovdqa		$ACC1, 32*1(%rdi)
-+	vmovdqa		$ACC2, 32*2(%rdi)
-+	vmovdqa		$ACC3, 32*3(%rdi)
-+	vmovdqa		$ACC4, 32*4-160(%rax)
-+	vmovdqa		$ACC5, 32*5-160(%rax)
-+	vmovdqa		$ACC6, 32*6-160(%rax)
-+	vmovdqa		$ACC7, 32*7-160(%rax)
-+	vmovdqa		$ACC8, 32*8-160(%rax)
-+___
-+    $ret;
-+}
-+
-+$code.=<<___;
-+.type	avx2_normalize,\@abi-omnipotent
-+.align	32
-+avx2_normalize:
-+	vpsrlq		$digit_size, $ACC0, $T0
-+	vpand		$AND_MASK, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC1, $ACC1
-+
-+	vpsrlq		$digit_size, $ACC1, $T0
-+	vpand		$AND_MASK, $ACC1, $ACC1
-+	vpaddq		$T0, $ACC2, $ACC2
-+
-+	vpsrlq		$digit_size, $ACC2, $T0
-+	vpand		$AND_MASK, $ACC2, $ACC2
-+	vpaddq		$T0, $ACC3, $ACC3
-+
-+	vpsrlq		$digit_size, $ACC3, $T0
-+	vpand		$AND_MASK, $ACC3, $ACC3
-+	vpaddq		$T0, $ACC4, $ACC4
-+
-+	vpsrlq		$digit_size, $ACC4, $T0
-+	vpand		$AND_MASK, $ACC4, $ACC4
-+	vpaddq		$T0, $ACC5, $ACC5
-+
-+	vpsrlq		$digit_size, $ACC5, $T0
-+	vpand		$AND_MASK, $ACC5, $ACC5
-+	vpaddq		$T0, $ACC6, $ACC6
-+
-+	vpsrlq		$digit_size, $ACC6, $T0
-+	vpand		$AND_MASK, $ACC6, $ACC6
-+	vpaddq		$T0, $ACC7, $ACC7
-+
-+	vpsrlq		$digit_size, $ACC7, $T0
-+	vpand		$AND_MASK, $ACC7, $ACC7
-+	vpaddq		$T0, $ACC8, $ACC8
-+	#vpand		$AND_MASK, $ACC8, $ACC8
-+
-+	ret
-+.size	avx2_normalize,.-avx2_normalize
-+
-+.type	avx2_normalize_n_store,\@abi-omnipotent
-+.align	32
-+avx2_normalize_n_store:
-+	vpsrlq		$digit_size, $ACC0, $T0
-+	vpand		$AND_MASK, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC1, $ACC1
-+
-+	vpsrlq		$digit_size, $ACC1, $T0
-+	vpand		$AND_MASK, $ACC1, $ACC1
-+	 vmovdqa	$ACC0, 32*0(%rdi)
-+	 lea		160(%rdi), %rax		# size optimization
-+	vpaddq		$T0, $ACC2, $ACC2
-+
-+	vpsrlq		$digit_size, $ACC2, $T0
-+	vpand		$AND_MASK, $ACC2, $ACC2
-+	 vmovdqa	$ACC1, 32*1(%rdi)
-+	vpaddq		$T0, $ACC3, $ACC3
-+
-+	vpsrlq		$digit_size, $ACC3, $T0
-+	vpand		$AND_MASK, $ACC3, $ACC3
-+	 vmovdqa	$ACC2, 32*2(%rdi)
-+	vpaddq		$T0, $ACC4, $ACC4
-+
-+	vpsrlq		$digit_size, $ACC4, $T0
-+	vpand		$AND_MASK, $ACC4, $ACC4
-+	 vmovdqa	$ACC3, 32*3(%rdi)
-+	vpaddq		$T0, $ACC5, $ACC5
-+
-+	vpsrlq		$digit_size, $ACC5, $T0
-+	vpand		$AND_MASK, $ACC5, $ACC5
-+	 vmovdqa	$ACC4, 32*4-160(%rax)
-+	vpaddq		$T0, $ACC6, $ACC6
-+
-+	vpsrlq		$digit_size, $ACC6, $T0
-+	vpand		$AND_MASK, $ACC6, $ACC6
-+	 vmovdqa	$ACC5, 32*5-160(%rax)
-+	vpaddq		$T0, $ACC7, $ACC7
-+
-+	vpsrlq		$digit_size, $ACC7, $T0
-+	vpand		$AND_MASK, $ACC7, $ACC7
-+	 vmovdqa	$ACC6, 32*6-160(%rax)
-+	vpaddq		$T0, $ACC8, $ACC8
-+	#vpand		$AND_MASK, $ACC8, $ACC8
-+	 vmovdqa	$ACC7, 32*7-160(%rax)
-+	 vmovdqa	$ACC8, 32*8-160(%rax)
-+
-+	ret
-+.size	avx2_normalize_n_store,.-avx2_normalize_n_store
-+
-+################################################################################
-+# void avx2_mul_x4(void* RESULTx4, void *Ax4, void *Bx4);
-+.type	avx2_mul_x4,\@abi-omnipotent
-+.align	32
-+avx2_mul_x4:
-+	lea	.LAVX2_POLY(%rip), %rax
-+
-+	vpxor	$ACC0, $ACC0, $ACC0
-+	vpxor	$ACC1, $ACC1, $ACC1
-+	vpxor	$ACC2, $ACC2, $ACC2
-+	vpxor	$ACC3, $ACC3, $ACC3
-+	vpxor	$ACC4, $ACC4, $ACC4
-+	vpxor	$ACC5, $ACC5, $ACC5
-+	vpxor	$ACC6, $ACC6, $ACC6
-+	vpxor	$ACC7, $ACC7, $ACC7
-+
-+	vmovdqa	32*7(%rax), %ymm14
-+	vmovdqa	32*8(%rax), %ymm15
-+
-+	mov	$n_digits, $itr
-+	lea	-512($a_ptr), $a_ptr	# strategic bias to control u-op density
-+	jmp	.Lavx2_mul_x4_loop
-+
-+.align	32
-+.Lavx2_mul_x4_loop:
-+	vmovdqa		32*0($b_ptr), $B
-+	lea		32*1($b_ptr), $b_ptr
-+
-+	vpmuludq	32*0+512($a_ptr), $B, $T0
-+	vpmuludq	32*1+512($a_ptr), $B, $OVERFLOW	# borrow $OVERFLOW
-+	vpaddq		$T0, $ACC0, $ACC0
-+	vpmuludq	32*2+512($a_ptr), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC1, $ACC1
-+	 vpand		$AND_MASK, $ACC0, $Y
-+	vpmuludq	32*3+512($a_ptr), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC2, $ACC2
-+	vpmuludq	32*4+512($a_ptr), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC3, $ACC3
-+	vpmuludq	32*5+512($a_ptr), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC4, $ACC4
-+	vpmuludq	32*6+512($a_ptr), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC5, $ACC5
-+	vpmuludq	32*7+512($a_ptr), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC6
-+
-+	# Skip some multiplications, optimizing for the constant poly
-+	vpmuludq	$AND_MASK, $Y, $T0
-+	 vpaddq		$OVERFLOW, $ACC7, $ACC7
-+	 vpmuludq	32*8+512($a_ptr), $B, $ACC8
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	.byte		0x67
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $OVERFLOW
-+	.byte		0x67
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	%ymm14, $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC6, $ACC5
-+	vpmuludq	%ymm15, $Y, $OVERFLOW
-+	vpaddq		$T0, $ACC7, $ACC6
-+	vpaddq		$OVERFLOW, $ACC8, $ACC7
-+
-+	dec	$itr
-+	jnz	.Lavx2_mul_x4_loop
-+
-+	vpxor	$ACC8, $ACC8, $ACC8
-+
-+	ret
-+.size	avx2_mul_x4,.-avx2_mul_x4
-+
-+# Function optimized for the constant 1
-+################################################################################
-+# void avx2_mul_by1_x4(void* RESULTx4, void *Ax4);
-+.type	avx2_mul_by1_x4,\@abi-omnipotent
-+.align	32
-+avx2_mul_by1_x4:
-+	lea	.LAVX2_POLY(%rip), %rax
-+
-+	vpxor	$ACC0, $ACC0, $ACC0
-+	vpxor	$ACC1, $ACC1, $ACC1
-+	vpxor	$ACC2, $ACC2, $ACC2
-+	vpxor	$ACC3, $ACC3, $ACC3
-+	vpxor	$ACC4, $ACC4, $ACC4
-+	vpxor	$ACC5, $ACC5, $ACC5
-+	vpxor	$ACC6, $ACC6, $ACC6
-+	vpxor	$ACC7, $ACC7, $ACC7
-+	vpxor	$ACC8, $ACC8, $ACC8
-+
-+	vmovdqa	32*3+.LONE(%rip), %ymm14
-+	vmovdqa	32*7+.LONE(%rip), %ymm15
-+
-+	mov	$n_digits, $itr
-+	jmp	.Lavx2_mul_by1_x4_loop
-+
-+.align	32
-+.Lavx2_mul_by1_x4_loop:
-+	vmovdqa		32*0($a_ptr), $B
-+	.byte		0x48,0x8d,0xb6,0x20,0,0,0	# lea	32*1($a_ptr), $a_ptr
-+
-+	vpsllq		\$5, $B, $OVERFLOW
-+	vpmuludq	%ymm14, $B, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC3
-+	.byte		0x67
-+	vpmuludq	$AND_MASK, $B, $T0
-+	vpand		$AND_MASK, $ACC0, $Y
-+	vpaddq		$T0, $ACC4, $ACC4
-+	vpaddq		$T0, $ACC5, $ACC5
-+	vpaddq		$T0, $ACC6, $ACC6
-+	vpsllq		\$23, $B, $T0
-+
-+	.byte		0x67,0x67
-+	vpmuludq	%ymm15, $B, $OVERFLOW
-+	vpsubq		$T0, $ACC6, $ACC6
-+
-+	vpmuludq	$AND_MASK, $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC7, $ACC7
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	.byte		0x67,0x67
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $OVERFLOW
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	32*7(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC6, $ACC5
-+	vpaddq		$T0, $ACC7, $ACC6
-+	vpmuludq	32*8(%rax), $Y, $ACC7
-+
-+	dec	$itr
-+	jnz	.Lavx2_mul_by1_x4_loop
-+
-+	ret
-+.size	avx2_mul_by1_x4,.-avx2_mul_by1_x4
-+
-+################################################################################
-+# void avx2_sqr_x4(void* RESULTx4, void *Ax4, void *Bx4);
-+.type	avx2_sqr_x4,\@abi-omnipotent
-+.align	32
-+avx2_sqr_x4:
-+	lea		.LAVX2_POLY(%rip), %rax
-+
-+	vmovdqa		32*7(%rax), %ymm14
-+	vmovdqa		32*8(%rax), %ymm15
-+
-+	vmovdqa		32*0($a_ptr), $B
-+	vmovdqa		32*1($a_ptr), $ACC1
-+	vmovdqa		32*2($a_ptr), $ACC2
-+	vmovdqa		32*3($a_ptr), $ACC3
-+	vmovdqa		32*4($a_ptr), $ACC4
-+	vmovdqa		32*5($a_ptr), $ACC5
-+	vmovdqa		32*6($a_ptr), $ACC6
-+	vmovdqa		32*7($a_ptr), $ACC7
-+	vpaddq		$ACC1, $ACC1, $ACC1	# 2*$ACC0..7
-+	vmovdqa		32*8($a_ptr), $ACC8
-+	vpaddq		$ACC2, $ACC2, $ACC2
-+	vmovdqa		$ACC1, 32*0(%rcx)
-+	vpaddq		$ACC3, $ACC3, $ACC3
-+	vmovdqa		$ACC2, 32*1(%rcx)
-+	vpaddq		$ACC4, $ACC4, $ACC4
-+	vmovdqa		$ACC3, 32*2(%rcx)
-+	vpaddq		$ACC5, $ACC5, $ACC5
-+	vmovdqa		$ACC4, 32*3(%rcx)
-+	vpaddq		$ACC6, $ACC6, $ACC6
-+	vmovdqa		$ACC5, 32*4(%rcx)
-+	vpaddq		$ACC7, $ACC7, $ACC7
-+	vmovdqa		$ACC6, 32*5(%rcx)
-+	vpaddq		$ACC8, $ACC8, $ACC8
-+	vmovdqa		$ACC7, 32*6(%rcx)
-+	vmovdqa		$ACC8, 32*7(%rcx)
-+
-+	#itr		1
-+	vpmuludq	$B, $B, $ACC0
-+	vpmuludq	$B, $ACC1, $ACC1
-+	 vpand		$AND_MASK, $ACC0, $Y
-+	vpmuludq	$B, $ACC2, $ACC2
-+	vpmuludq	$B, $ACC3, $ACC3
-+	vpmuludq	$B, $ACC4, $ACC4
-+	vpmuludq	$B, $ACC5, $ACC5
-+	vpmuludq	$B, $ACC6, $ACC6
-+	 vpmuludq	$AND_MASK, $Y, $T0
-+	vpmuludq	$B, $ACC7, $ACC7
-+	vpmuludq	$B, $ACC8, $ACC8
-+	 vmovdqa	32*1($a_ptr), $B
-+
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $T0
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	%ymm14, $Y, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC5
-+	vpmuludq	%ymm15, $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC7, $ACC6
-+	vpaddq		$T0, $ACC8, $ACC7
-+
-+	#itr		2
-+	vpmuludq	$B, $B, $OVERFLOW
-+	 vpand		$AND_MASK, $ACC0, $Y
-+	vpmuludq	32*1(%rcx), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC1, $ACC1
-+	vpmuludq	32*2(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC2, $ACC2
-+	vpmuludq	32*3(%rcx), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC3, $ACC3
-+	vpmuludq	32*4(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC4, $ACC4
-+	vpmuludq	32*5(%rcx), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC5, $ACC5
-+	vpmuludq	32*6(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC6
-+
-+	vpmuludq	$AND_MASK, $Y, $T0
-+	 vpaddq		$OVERFLOW, $ACC7, $ACC7
-+	 vpmuludq	32*7(%rcx), $B, $ACC8
-+	 vmovdqa	32*2($a_ptr), $B
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $T0
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	%ymm14, $Y, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC5
-+	vpmuludq	%ymm15, $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC7, $ACC6
-+	vpaddq		$T0, $ACC8, $ACC7
-+
-+	#itr		3
-+	vpmuludq	$B, $B, $T0
-+	 vpand		$AND_MASK, $ACC0, $Y
-+	vpmuludq	32*2(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC2, $ACC2
-+	vpmuludq	32*3(%rcx), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC3, $ACC3
-+	vpmuludq	32*4(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC4, $ACC4
-+	vpmuludq	32*5(%rcx), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC5, $ACC5
-+	vpmuludq	32*6(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC6
-+
-+	vpmuludq	$AND_MASK, $Y, $T0
-+	 vpaddq		$OVERFLOW, $ACC7, $ACC7
-+	 vpmuludq	32*7(%rcx), $B, $ACC8
-+	 vmovdqa	32*3($a_ptr), $B
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $T0
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	%ymm14, $Y, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC5
-+	vpmuludq	%ymm15, $Y, $T0
-+	 vpand		$AND_MASK, $ACC0, $Y
-+	vpaddq		$OVERFLOW, $ACC7, $ACC6
-+	vpaddq		$T0, $ACC8, $ACC7
-+
-+	#itr		4
-+	vpmuludq	$B, $B, $OVERFLOW
-+	vpmuludq	32*3(%rcx), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC3, $ACC3
-+	vpmuludq	32*4(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC4, $ACC4
-+	vpmuludq	32*5(%rcx), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC5, $ACC5
-+	vpmuludq	32*6(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC6
-+
-+	vpmuludq	$AND_MASK, $Y, $T0
-+	 vpaddq		$OVERFLOW, $ACC7, $ACC7
-+	 vpmuludq	32*7(%rcx), $B, $ACC8
-+	 vmovdqa	32*4($a_ptr), $B
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $T0
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	%ymm14, $Y, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC5
-+	vpmuludq	%ymm15, $Y, $T0
-+	 vpand		$AND_MASK, $ACC0, $Y
-+	vpaddq		$OVERFLOW, $ACC7, $ACC6
-+	vpaddq		$T0, $ACC8, $ACC7
-+
-+	#itr		5
-+	vpmuludq	$B, $B, $T0
-+	vpmuludq	32*4(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC4, $ACC4
-+	vpmuludq	32*5(%rcx), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC5, $ACC5
-+	vpmuludq	32*6(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC6
-+
-+	vpmuludq	$AND_MASK, $Y, $T0
-+	 vpaddq		$OVERFLOW, $ACC7, $ACC7
-+	 vpmuludq	32*7(%rcx), $B, $ACC8
-+	 vmovdqa	32*5($a_ptr), $B
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3+.LAVX2_POLY(%rip), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $T0
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	%ymm14, $Y, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC5
-+	vpmuludq	%ymm15, $Y, $T0
-+	 vpand		$AND_MASK, $ACC0, $Y
-+	vpaddq		$OVERFLOW, $ACC7, $ACC6
-+	vpaddq		$T0, $ACC8, $ACC7
-+
-+	#itr		6
-+	vpmuludq	$B, $B, $OVERFLOW
-+	vpmuludq	32*5(%rcx), $B, $T0
-+	vpaddq		$OVERFLOW, $ACC5, $ACC5
-+	vpmuludq	32*6(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC6
-+
-+	vpmuludq	$AND_MASK, $Y, $T0
-+	 vpaddq		$OVERFLOW, $ACC7, $ACC7
-+	 vpmuludq	32*7(%rcx), $B, $ACC8
-+	 vmovdqa	32*6($a_ptr), $B
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $T0
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	%ymm14, $Y, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC5
-+	vpmuludq	%ymm15, $Y, $T0
-+	 vpand		$AND_MASK, $ACC0, $Y
-+	vpaddq		$OVERFLOW, $ACC7, $ACC6
-+	vpaddq		$T0, $ACC8, $ACC7
-+
-+	#itr		7
-+	vpmuludq	$B, $B, $T0
-+	vpmuludq	32*6(%rcx), $B, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC6
-+
-+	vpmuludq	$AND_MASK, $Y, $T0
-+	 vpaddq		$OVERFLOW, $ACC7, $ACC7
-+	 vpmuludq	32*7(%rcx), $B, $ACC8
-+	 vmovdqa	32*7($a_ptr), $B
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $T0
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	%ymm14, $Y, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC5
-+	vpmuludq	%ymm15, $Y, $T0
-+	 vpand		$AND_MASK, $ACC0, $Y
-+	vpaddq		$OVERFLOW, $ACC7, $ACC6
-+	vpaddq		$T0, $ACC8, $ACC7
-+
-+	#itr		8
-+	vpmuludq	$B, $B, $OVERFLOW
-+
-+	vpmuludq	$AND_MASK, $Y, $T0
-+	 vpaddq		$OVERFLOW, $ACC7, $ACC7
-+	 vpmuludq	32*7(%rcx), $B, $ACC8
-+	 vmovdqa	32*8($a_ptr), $B
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $T0
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	%ymm14, $Y, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC5
-+	vpmuludq	%ymm15, $Y, $T0
-+	 vpand		$AND_MASK, $ACC0, $Y
-+	vpaddq		$OVERFLOW, $ACC7, $ACC6
-+	vpaddq		$T0, $ACC8, $ACC7
-+
-+	#itr		9
-+	vpmuludq	$B, $B, $ACC8
-+
-+	vpmuludq	$AND_MASK, $Y, $T0
-+	vpaddq		$T0, $ACC0, $OVERFLOW
-+	vpsrlq		$digit_size, $OVERFLOW, $OVERFLOW
-+	vpaddq		$T0, $ACC1, $ACC0
-+	vpaddq		$T0, $ACC2, $ACC1
-+	vpmuludq	32*3(%rax), $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC0, $ACC0
-+	vpaddq		$T0, $ACC3, $ACC2
-+	vmovdqa		$ACC4, $ACC3
-+	vpsllq		\$18, $Y, $T0
-+	vmovdqa		$ACC5, $ACC4
-+	vpmuludq	%ymm14, $Y, $OVERFLOW
-+	vpaddq		$T0, $ACC6, $ACC5
-+	vpmuludq	%ymm15, $Y, $T0
-+	vpaddq		$OVERFLOW, $ACC7, $ACC6
-+	vpaddq		$T0, $ACC8, $ACC7
-+
-+	vpxor		$ACC8, $ACC8, $ACC8
-+
-+	ret
-+.size	avx2_sqr_x4,.-avx2_sqr_x4
-+
-+################################################################################
-+# void avx2_sub_x4(void* RESULTx4, void *Ax4, void *Bx4);
-+.type	avx2_sub_x4,\@abi-omnipotent
-+.align	32
-+avx2_sub_x4:
-+	vmovdqa	32*0($a_ptr), $ACC0
-+	lea	160($a_ptr), $a_ptr
-+	lea	.LAVX2_POLY_x8+128(%rip), %rax
-+	lea	128($b_ptr), $b_ptr
-+	vmovdqa	32*1-160($a_ptr), $ACC1
-+	vmovdqa	32*2-160($a_ptr), $ACC2
-+	vmovdqa	32*3-160($a_ptr), $ACC3
-+	vmovdqa	32*4-160($a_ptr), $ACC4
-+	vmovdqa	32*5-160($a_ptr), $ACC5
-+	vmovdqa	32*6-160($a_ptr), $ACC6
-+	vmovdqa	32*7-160($a_ptr), $ACC7
-+	vmovdqa	32*8-160($a_ptr), $ACC8
-+
-+	vpaddq	32*0-128(%rax), $ACC0, $ACC0
-+	vpaddq	32*1-128(%rax), $ACC1, $ACC1
-+	vpaddq	32*2-128(%rax), $ACC2, $ACC2
-+	vpaddq	32*3-128(%rax), $ACC3, $ACC3
-+	vpaddq	32*4-128(%rax), $ACC4, $ACC4
-+	vpaddq	32*5-128(%rax), $ACC5, $ACC5
-+	vpaddq	32*6-128(%rax), $ACC6, $ACC6
-+	vpaddq	32*7-128(%rax), $ACC7, $ACC7
-+	vpaddq	32*8-128(%rax), $ACC8, $ACC8
-+
-+	vpsubq	32*0-128($b_ptr), $ACC0, $ACC0
-+	vpsubq	32*1-128($b_ptr), $ACC1, $ACC1
-+	vpsubq	32*2-128($b_ptr), $ACC2, $ACC2
-+	vpsubq	32*3-128($b_ptr), $ACC3, $ACC3
-+	vpsubq	32*4-128($b_ptr), $ACC4, $ACC4
-+	vpsubq	32*5-128($b_ptr), $ACC5, $ACC5
-+	vpsubq	32*6-128($b_ptr), $ACC6, $ACC6
-+	vpsubq	32*7-128($b_ptr), $ACC7, $ACC7
-+	vpsubq	32*8-128($b_ptr), $ACC8, $ACC8
-+
-+	ret
-+.size	avx2_sub_x4,.-avx2_sub_x4
-+
-+.type	avx2_select_n_store,\@abi-omnipotent
-+.align	32
-+avx2_select_n_store:
-+	vmovdqa	`8+32*9*8`(%rsp), $Y
-+	vpor	`8+32*9*8+32`(%rsp), $Y, $Y
-+
-+	vpandn	$ACC0, $Y, $ACC0
-+	vpandn	$ACC1, $Y, $ACC1
-+	vpandn	$ACC2, $Y, $ACC2
-+	vpandn	$ACC3, $Y, $ACC3
-+	vpandn	$ACC4, $Y, $ACC4
-+	vpandn	$ACC5, $Y, $ACC5
-+	vpandn	$ACC6, $Y, $ACC6
-+	vmovdqa	`8+32*9*8+32`(%rsp), $B
-+	vpandn	$ACC7, $Y, $ACC7
-+	vpandn	`8+32*9*8`(%rsp), $B, $B
-+	vpandn	$ACC8, $Y, $ACC8
-+
-+	vpand	32*0(%rsi), $B, $T0
-+	lea	160(%rsi), %rax
-+	vpand	32*1(%rsi), $B, $Y
-+	vpxor	$T0, $ACC0, $ACC0
-+	vpand	32*2(%rsi), $B, $T0
-+	vpxor	$Y, $ACC1, $ACC1
-+	vpand	32*3(%rsi), $B, $Y
-+	vpxor	$T0, $ACC2, $ACC2
-+	vpand	32*4-160(%rax), $B, $T0
-+	vpxor	$Y, $ACC3, $ACC3
-+	vpand	32*5-160(%rax), $B, $Y
-+	vpxor	$T0, $ACC4, $ACC4
-+	vpand	32*6-160(%rax), $B, $T0
-+	vpxor	$Y, $ACC5, $ACC5
-+	vpand	32*7-160(%rax), $B, $Y
-+	vpxor	$T0, $ACC6, $ACC6
-+	vpand	32*8-160(%rax), $B, $T0
-+	vmovdqa	`8+32*9*8+32`(%rsp), $B
-+	vpxor	$Y, $ACC7, $ACC7
-+
-+	vpand	32*0(%rdx), $B, $Y
-+	lea	160(%rdx), %rax
-+	vpxor	$T0, $ACC8, $ACC8
-+	vpand	32*1(%rdx), $B, $T0
-+	vpxor	$Y, $ACC0, $ACC0
-+	vpand	32*2(%rdx), $B, $Y
-+	vpxor	$T0, $ACC1, $ACC1
-+	vpand	32*3(%rdx), $B, $T0
-+	vpxor	$Y, $ACC2, $ACC2
-+	vpand	32*4-160(%rax), $B, $Y
-+	vpxor	$T0, $ACC3, $ACC3
-+	vpand	32*5-160(%rax), $B, $T0
-+	vpxor	$Y, $ACC4, $ACC4
-+	vpand	32*6-160(%rax), $B, $Y
-+	vpxor	$T0, $ACC5, $ACC5
-+	vpand	32*7-160(%rax), $B, $T0
-+	vpxor	$Y, $ACC6, $ACC6
-+	vpand	32*8-160(%rax), $B, $Y
-+	vpxor	$T0, $ACC7, $ACC7
-+	vpxor	$Y, $ACC8, $ACC8
-+	`&STORE`
-+
-+	ret
-+.size	avx2_select_n_store,.-avx2_select_n_store
-+___
-+$code.=<<___	if (0);				# inlined
-+################################################################################
-+# void avx2_mul_by2_x4(void* RESULTx4, void *Ax4);
-+.type	avx2_mul_by2_x4,\@abi-omnipotent
-+.align	32
-+avx2_mul_by2_x4:
-+	vmovdqa	32*0($a_ptr), $ACC0
-+	lea	160($a_ptr), %rax
-+	vmovdqa	32*1($a_ptr), $ACC1
-+	vmovdqa	32*2($a_ptr), $ACC2
-+	vmovdqa	32*3($a_ptr), $ACC3
-+	vmovdqa	32*4-160(%rax), $ACC4
-+	vmovdqa	32*5-160(%rax), $ACC5
-+	vmovdqa	32*6-160(%rax), $ACC6
-+	vmovdqa	32*7-160(%rax), $ACC7
-+	vmovdqa	32*8-160(%rax), $ACC8
-+
-+	vpaddq	$ACC0, $ACC0, $ACC0
-+	vpaddq	$ACC1, $ACC1, $ACC1
-+	vpaddq	$ACC2, $ACC2, $ACC2
-+	vpaddq	$ACC3, $ACC3, $ACC3
-+	vpaddq	$ACC4, $ACC4, $ACC4
-+	vpaddq	$ACC5, $ACC5, $ACC5
-+	vpaddq	$ACC6, $ACC6, $ACC6
-+	vpaddq	$ACC7, $ACC7, $ACC7
-+	vpaddq	$ACC8, $ACC8, $ACC8
-+
-+	ret
-+.size	avx2_mul_by2_x4,.-avx2_mul_by2_x4
-+___
-+my ($r_ptr_in,$a_ptr_in,$b_ptr_in)=("%rdi","%rsi","%rdx");
-+my ($r_ptr,$a_ptr,$b_ptr)=("%r8","%r9","%r10");
-+
-+$code.=<<___;
-+################################################################################
-+# void ecp_nistz256_avx2_point_add_affine_x4(void* RESULTx4, void *Ax4, void *Bx4);
-+.globl	ecp_nistz256_avx2_point_add_affine_x4
-+.type	ecp_nistz256_avx2_point_add_affine_x4,\@function,3
-+.align	32
-+ecp_nistz256_avx2_point_add_affine_x4:
-+	mov	%rsp, %rax
-+	push    %rbp
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	lea	-16*10(%rsp), %rsp
-+	vmovaps	%xmm6, -8-16*10(%rax)
-+	vmovaps	%xmm7, -8-16*9(%rax)
-+	vmovaps	%xmm8, -8-16*8(%rax)
-+	vmovaps	%xmm9, -8-16*7(%rax)
-+	vmovaps	%xmm10, -8-16*6(%rax)
-+	vmovaps	%xmm11, -8-16*5(%rax)
-+	vmovaps	%xmm12, -8-16*4(%rax)
-+	vmovaps	%xmm13, -8-16*3(%rax)
-+	vmovaps	%xmm14, -8-16*2(%rax)
-+	vmovaps	%xmm15, -8-16*1(%rax)
-+___
-+$code.=<<___;
-+	lea	-8(%rax), %rbp
-+
-+# Result + 32*0 = Result.X
-+# Result + 32*9 = Result.Y
-+# Result + 32*18 = Result.Z
-+
-+# A + 32*0 = A.X
-+# A + 32*9 = A.Y
-+# A + 32*18 = A.Z
-+
-+# B + 32*0 = B.X
-+# B + 32*9 = B.Y
-+
-+	sub	\$`32*9*8+32*2+32*8`, %rsp
-+	and	\$-64, %rsp
-+
-+	mov	$r_ptr_in, $r_ptr
-+	mov	$a_ptr_in, $a_ptr
-+	mov	$b_ptr_in, $b_ptr
-+
-+	vmovdqa	32*0($a_ptr_in), %ymm0
-+	vmovdqa	.LAVX2_AND_MASK(%rip), $AND_MASK
-+	vpxor	%ymm1, %ymm1, %ymm1
-+	lea	256($a_ptr_in), %rax		# size optimization
-+	vpor	32*1($a_ptr_in), %ymm0, %ymm0
-+	vpor	32*2($a_ptr_in), %ymm0, %ymm0
-+	vpor	32*3($a_ptr_in), %ymm0, %ymm0
-+	vpor	32*4-256(%rax), %ymm0, %ymm0
-+	lea	256(%rax), %rcx			# size optimization
-+	vpor	32*5-256(%rax), %ymm0, %ymm0
-+	vpor	32*6-256(%rax), %ymm0, %ymm0
-+	vpor	32*7-256(%rax), %ymm0, %ymm0
-+	vpor	32*8-256(%rax), %ymm0, %ymm0
-+	vpor	32*9-256(%rax), %ymm0, %ymm0
-+	vpor	32*10-256(%rax), %ymm0, %ymm0
-+	vpor	32*11-256(%rax), %ymm0, %ymm0
-+	vpor	32*12-512(%rcx), %ymm0, %ymm0
-+	vpor	32*13-512(%rcx), %ymm0, %ymm0
-+	vpor	32*14-512(%rcx), %ymm0, %ymm0
-+	vpor	32*15-512(%rcx), %ymm0, %ymm0
-+	vpor	32*16-512(%rcx), %ymm0, %ymm0
-+	vpor	32*17-512(%rcx), %ymm0, %ymm0
-+	vpcmpeqq %ymm1, %ymm0, %ymm0
-+	vmovdqa	%ymm0, `32*9*8`(%rsp)
-+
-+	vpxor	%ymm1, %ymm1, %ymm1
-+	vmovdqa	32*0($b_ptr), %ymm0
-+	lea	256($b_ptr), %rax		# size optimization
-+	vpor	32*1($b_ptr), %ymm0, %ymm0
-+	vpor	32*2($b_ptr), %ymm0, %ymm0
-+	vpor	32*3($b_ptr), %ymm0, %ymm0
-+	vpor	32*4-256(%rax), %ymm0, %ymm0
-+	lea	256(%rax), %rcx			# size optimization
-+	vpor	32*5-256(%rax), %ymm0, %ymm0
-+	vpor	32*6-256(%rax), %ymm0, %ymm0
-+	vpor	32*7-256(%rax), %ymm0, %ymm0
-+	vpor	32*8-256(%rax), %ymm0, %ymm0
-+	vpor	32*9-256(%rax), %ymm0, %ymm0
-+	vpor	32*10-256(%rax), %ymm0, %ymm0
-+	vpor	32*11-256(%rax), %ymm0, %ymm0
-+	vpor	32*12-512(%rcx), %ymm0, %ymm0
-+	vpor	32*13-512(%rcx), %ymm0, %ymm0
-+	vpor	32*14-512(%rcx), %ymm0, %ymm0
-+	vpor	32*15-512(%rcx), %ymm0, %ymm0
-+	vpor	32*16-512(%rcx), %ymm0, %ymm0
-+	vpor	32*17-512(%rcx), %ymm0, %ymm0
-+	vpcmpeqq %ymm1, %ymm0, %ymm0
-+	vmovdqa	%ymm0, `32*9*8+32`(%rsp)
-+
-+	#	Z1^2 = Z1*Z1
-+	lea	`32*9*2`($a_ptr), %rsi
-+	lea	`32*9*2`(%rsp), %rdi
-+	lea	`32*9*8+32*2`(%rsp), %rcx	# temporary vector
-+	call	avx2_sqr_x4
-+	call	avx2_normalize_n_store
-+
-+	#	U2 = X2*Z1^2
-+	lea	`32*9*0`($b_ptr), %rsi
-+	lea	`32*9*2`(%rsp), %rdx
-+	lea	`32*9*0`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	#call	avx2_normalize
-+	`&STORE`
-+
-+	#	S2 = Z1*Z1^2 = Z1^3
-+	lea	`32*9*2`($a_ptr), %rsi
-+	lea	`32*9*2`(%rsp), %rdx
-+	lea	`32*9*1`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	call	avx2_normalize_n_store
-+
-+	#	S2 = S2*Y2 = Y2*Z1^3
-+	lea	`32*9*1`($b_ptr), %rsi
-+	lea	`32*9*1`(%rsp), %rdx
-+	lea	`32*9*1`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	call	avx2_normalize_n_store
-+
-+	#	H = U2 - U1 = U2 - X1
-+	lea	`32*9*0`(%rsp), %rsi
-+	lea	`32*9*0`($a_ptr), %rdx
-+	lea	`32*9*3`(%rsp), %rdi
-+	call	avx2_sub_x4
-+	call	avx2_normalize_n_store
-+
-+	#	R = S2 - S1 = S2 - Y1
-+	lea	`32*9*1`(%rsp), %rsi
-+	lea	`32*9*1`($a_ptr), %rdx
-+	lea	`32*9*4`(%rsp), %rdi
-+	call	avx2_sub_x4
-+	call	avx2_normalize_n_store
-+
-+	#	Z3 = H*Z1*Z2
-+	lea	`32*9*3`(%rsp), %rsi
-+	lea	`32*9*2`($a_ptr), %rdx
-+	lea	`32*9*2`($r_ptr), %rdi
-+	call	avx2_mul_x4
-+	call	avx2_normalize
-+
-+	lea	.LONE(%rip), %rsi
-+	lea	`32*9*2`($a_ptr), %rdx
-+	call	avx2_select_n_store
-+
-+	#	R^2 = R^2
-+	lea	`32*9*4`(%rsp), %rsi
-+	lea	`32*9*6`(%rsp), %rdi
-+	lea	`32*9*8+32*2`(%rsp), %rcx	# temporary vector
-+	call	avx2_sqr_x4
-+	call	avx2_normalize_n_store
-+
-+	#	H^2 = H^2
-+	lea	`32*9*3`(%rsp), %rsi
-+	lea	`32*9*5`(%rsp), %rdi
-+	call	avx2_sqr_x4
-+	call	avx2_normalize_n_store
-+
-+	#	H^3 = H^2*H
-+	lea	`32*9*3`(%rsp), %rsi
-+	lea	`32*9*5`(%rsp), %rdx
-+	lea	`32*9*7`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	call	avx2_normalize_n_store
-+
-+	#	U2 = U1*H^2
-+	lea	`32*9*0`($a_ptr), %rsi
-+	lea	`32*9*5`(%rsp), %rdx
-+	lea	`32*9*0`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	#call	avx2_normalize
-+	`&STORE`
-+
-+	#	Hsqr = U2*2
-+	#lea	32*9*0(%rsp), %rsi
-+	#lea	32*9*5(%rsp), %rdi
-+	#call	avx2_mul_by2_x4
-+
-+	vpaddq	$ACC0, $ACC0, $ACC0	# inlined avx2_mul_by2_x4
-+	lea	`32*9*5`(%rsp), %rdi
-+	vpaddq	$ACC1, $ACC1, $ACC1
-+	vpaddq	$ACC2, $ACC2, $ACC2
-+	vpaddq	$ACC3, $ACC3, $ACC3
-+	vpaddq	$ACC4, $ACC4, $ACC4
-+	vpaddq	$ACC5, $ACC5, $ACC5
-+	vpaddq	$ACC6, $ACC6, $ACC6
-+	vpaddq	$ACC7, $ACC7, $ACC7
-+	vpaddq	$ACC8, $ACC8, $ACC8
-+	call	avx2_normalize_n_store
-+
-+	#	X3 = R^2 - H^3
-+	#lea	32*9*6(%rsp), %rsi
-+	#lea	32*9*7(%rsp), %rdx
-+	#lea	32*9*5(%rsp), %rcx
-+	#lea	32*9*0($r_ptr), %rdi
-+	#call	avx2_sub_x4
-+	#NORMALIZE
-+	#STORE
-+
-+	#	X3 = X3 - U2*2
-+	#lea	32*9*0($r_ptr), %rsi
-+	#lea	32*9*0($r_ptr), %rdi
-+	#call	avx2_sub_x4
-+	#NORMALIZE
-+	#STORE
-+
-+	lea	`32*9*6+128`(%rsp), %rsi
-+	lea	.LAVX2_POLY_x2+128(%rip), %rax
-+	lea	`32*9*7+128`(%rsp), %rdx
-+	lea	`32*9*5+128`(%rsp), %rcx
-+	lea	`32*9*0`($r_ptr), %rdi
-+
-+	vmovdqa	32*0-128(%rsi), $ACC0
-+	vmovdqa	32*1-128(%rsi), $ACC1
-+	vmovdqa	32*2-128(%rsi), $ACC2
-+	vmovdqa	32*3-128(%rsi), $ACC3
-+	vmovdqa	32*4-128(%rsi), $ACC4
-+	vmovdqa	32*5-128(%rsi), $ACC5
-+	vmovdqa	32*6-128(%rsi), $ACC6
-+	vmovdqa	32*7-128(%rsi), $ACC7
-+	vmovdqa	32*8-128(%rsi), $ACC8
-+
-+	vpaddq	32*0-128(%rax), $ACC0, $ACC0
-+	vpaddq	32*1-128(%rax), $ACC1, $ACC1
-+	vpaddq	32*2-128(%rax), $ACC2, $ACC2
-+	vpaddq	32*3-128(%rax), $ACC3, $ACC3
-+	vpaddq	32*4-128(%rax), $ACC4, $ACC4
-+	vpaddq	32*5-128(%rax), $ACC5, $ACC5
-+	vpaddq	32*6-128(%rax), $ACC6, $ACC6
-+	vpaddq	32*7-128(%rax), $ACC7, $ACC7
-+	vpaddq	32*8-128(%rax), $ACC8, $ACC8
-+
-+	vpsubq	32*0-128(%rdx), $ACC0, $ACC0
-+	vpsubq	32*1-128(%rdx), $ACC1, $ACC1
-+	vpsubq	32*2-128(%rdx), $ACC2, $ACC2
-+	vpsubq	32*3-128(%rdx), $ACC3, $ACC3
-+	vpsubq	32*4-128(%rdx), $ACC4, $ACC4
-+	vpsubq	32*5-128(%rdx), $ACC5, $ACC5
-+	vpsubq	32*6-128(%rdx), $ACC6, $ACC6
-+	vpsubq	32*7-128(%rdx), $ACC7, $ACC7
-+	vpsubq	32*8-128(%rdx), $ACC8, $ACC8
-+
-+	vpsubq	32*0-128(%rcx), $ACC0, $ACC0
-+	vpsubq	32*1-128(%rcx), $ACC1, $ACC1
-+	vpsubq	32*2-128(%rcx), $ACC2, $ACC2
-+	vpsubq	32*3-128(%rcx), $ACC3, $ACC3
-+	vpsubq	32*4-128(%rcx), $ACC4, $ACC4
-+	vpsubq	32*5-128(%rcx), $ACC5, $ACC5
-+	vpsubq	32*6-128(%rcx), $ACC6, $ACC6
-+	vpsubq	32*7-128(%rcx), $ACC7, $ACC7
-+	vpsubq	32*8-128(%rcx), $ACC8, $ACC8
-+	call	avx2_normalize
-+
-+	lea	32*0($b_ptr), %rsi
-+	lea	32*0($a_ptr), %rdx
-+	call	avx2_select_n_store
-+
-+	#	H = U2 - X3
-+	lea	`32*9*0`(%rsp), %rsi
-+	lea	`32*9*0`($r_ptr), %rdx
-+	lea	`32*9*3`(%rsp), %rdi
-+	call	avx2_sub_x4
-+	call	avx2_normalize_n_store
-+
-+	#
-+	lea	`32*9*3`(%rsp), %rsi
-+	lea	`32*9*4`(%rsp), %rdx
-+	lea	`32*9*3`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	call	avx2_normalize_n_store
-+
-+	#
-+	lea	`32*9*7`(%rsp), %rsi
-+	lea	`32*9*1`($a_ptr), %rdx
-+	lea	`32*9*1`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	call	avx2_normalize_n_store
-+
-+	#
-+	lea	`32*9*3`(%rsp), %rsi
-+	lea	`32*9*1`(%rsp), %rdx
-+	lea	`32*9*1`($r_ptr), %rdi
-+	call	avx2_sub_x4
-+	call	avx2_normalize
-+
-+	lea	32*9($b_ptr), %rsi
-+	lea	32*9($a_ptr), %rdx
-+	call	avx2_select_n_store
-+
-+	#lea	32*9*0($r_ptr), %rsi
-+	#lea	32*9*0($r_ptr), %rdi
-+	#call	avx2_mul_by1_x4
-+	#NORMALIZE
-+	#STORE
-+
-+	lea	`32*9*1`($r_ptr), %rsi
-+	lea	`32*9*1`($r_ptr), %rdi
-+	call	avx2_mul_by1_x4
-+	call	avx2_normalize_n_store
-+
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	movaps	%xmm6, -16*10(%rbp)
-+	movaps	%xmm7, -16*9(%rbp)
-+	movaps	%xmm8, -16*8(%rbp)
-+	movaps	%xmm9, -16*7(%rbp)
-+	movaps	%xmm10, -16*6(%rbp)
-+	movaps	%xmm11, -16*5(%rbp)
-+	movaps	%xmm12, -16*4(%rbp)
-+	movaps	%xmm13, -16*3(%rbp)
-+	movaps	%xmm14, -16*2(%rbp)
-+	movaps	%xmm15, -16*1(%rbp)
-+___
-+$code.=<<___;
-+	mov	%rbp, %rsp
-+	pop	%rbp
-+	ret
-+.size	ecp_nistz256_avx2_point_add_affine_x4,.-ecp_nistz256_avx2_point_add_affine_x4
-+
-+################################################################################
-+# void ecp_nistz256_avx2_point_add_affines_x4(void* RESULTx4, void *Ax4, void *Bx4);
-+.globl	ecp_nistz256_avx2_point_add_affines_x4
-+.type	ecp_nistz256_avx2_point_add_affines_x4,\@function,3
-+.align	32
-+ecp_nistz256_avx2_point_add_affines_x4:
-+	mov	%rsp, %rax
-+	push    %rbp
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	lea	-16*10(%rsp), %rsp
-+	vmovaps	%xmm6, -8-16*10(%rax)
-+	vmovaps	%xmm7, -8-16*9(%rax)
-+	vmovaps	%xmm8, -8-16*8(%rax)
-+	vmovaps	%xmm9, -8-16*7(%rax)
-+	vmovaps	%xmm10, -8-16*6(%rax)
-+	vmovaps	%xmm11, -8-16*5(%rax)
-+	vmovaps	%xmm12, -8-16*4(%rax)
-+	vmovaps	%xmm13, -8-16*3(%rax)
-+	vmovaps	%xmm14, -8-16*2(%rax)
-+	vmovaps	%xmm15, -8-16*1(%rax)
-+___
-+$code.=<<___;
-+	lea	-8(%rax), %rbp
-+
-+# Result + 32*0 = Result.X
-+# Result + 32*9 = Result.Y
-+# Result + 32*18 = Result.Z
-+
-+# A + 32*0 = A.X
-+# A + 32*9 = A.Y
-+
-+# B + 32*0 = B.X
-+# B + 32*9 = B.Y
-+
-+	sub	\$`32*9*8+32*2+32*8`, %rsp
-+	and	\$-64, %rsp
-+
-+	mov	$r_ptr_in, $r_ptr
-+	mov	$a_ptr_in, $a_ptr
-+	mov	$b_ptr_in, $b_ptr
-+
-+	vmovdqa	32*0($a_ptr_in), %ymm0
-+	vmovdqa	.LAVX2_AND_MASK(%rip), $AND_MASK
-+	vpxor	%ymm1, %ymm1, %ymm1
-+	lea	256($a_ptr_in), %rax		# size optimization
-+	vpor	32*1($a_ptr_in), %ymm0, %ymm0
-+	vpor	32*2($a_ptr_in), %ymm0, %ymm0
-+	vpor	32*3($a_ptr_in), %ymm0, %ymm0
-+	vpor	32*4-256(%rax), %ymm0, %ymm0
-+	lea	256(%rax), %rcx			# size optimization
-+	vpor	32*5-256(%rax), %ymm0, %ymm0
-+	vpor	32*6-256(%rax), %ymm0, %ymm0
-+	vpor	32*7-256(%rax), %ymm0, %ymm0
-+	vpor	32*8-256(%rax), %ymm0, %ymm0
-+	vpor	32*9-256(%rax), %ymm0, %ymm0
-+	vpor	32*10-256(%rax), %ymm0, %ymm0
-+	vpor	32*11-256(%rax), %ymm0, %ymm0
-+	vpor	32*12-512(%rcx), %ymm0, %ymm0
-+	vpor	32*13-512(%rcx), %ymm0, %ymm0
-+	vpor	32*14-512(%rcx), %ymm0, %ymm0
-+	vpor	32*15-512(%rcx), %ymm0, %ymm0
-+	vpor	32*16-512(%rcx), %ymm0, %ymm0
-+	vpor	32*17-512(%rcx), %ymm0, %ymm0
-+	vpcmpeqq %ymm1, %ymm0, %ymm0
-+	vmovdqa	%ymm0, `32*9*8`(%rsp)
-+
-+	vpxor	%ymm1, %ymm1, %ymm1
-+	vmovdqa	32*0($b_ptr), %ymm0
-+	lea	256($b_ptr), %rax		# size optimization
-+	vpor	32*1($b_ptr), %ymm0, %ymm0
-+	vpor	32*2($b_ptr), %ymm0, %ymm0
-+	vpor	32*3($b_ptr), %ymm0, %ymm0
-+	vpor	32*4-256(%rax), %ymm0, %ymm0
-+	lea	256(%rax), %rcx			# size optimization
-+	vpor	32*5-256(%rax), %ymm0, %ymm0
-+	vpor	32*6-256(%rax), %ymm0, %ymm0
-+	vpor	32*7-256(%rax), %ymm0, %ymm0
-+	vpor	32*8-256(%rax), %ymm0, %ymm0
-+	vpor	32*9-256(%rax), %ymm0, %ymm0
-+	vpor	32*10-256(%rax), %ymm0, %ymm0
-+	vpor	32*11-256(%rax), %ymm0, %ymm0
-+	vpor	32*12-512(%rcx), %ymm0, %ymm0
-+	vpor	32*13-512(%rcx), %ymm0, %ymm0
-+	vpor	32*14-512(%rcx), %ymm0, %ymm0
-+	vpor	32*15-512(%rcx), %ymm0, %ymm0
-+	vpor	32*16-512(%rcx), %ymm0, %ymm0
-+	vpor	32*17-512(%rcx), %ymm0, %ymm0
-+	vpcmpeqq %ymm1, %ymm0, %ymm0
-+	vmovdqa	%ymm0, `32*9*8+32`(%rsp)
-+
-+	#	H = U2 - U1 = X2 - X1
-+	lea	`32*9*0`($b_ptr), %rsi
-+	lea	`32*9*0`($a_ptr), %rdx
-+	lea	`32*9*3`(%rsp), %rdi
-+	call	avx2_sub_x4
-+	call	avx2_normalize_n_store
-+
-+	#	R = S2 - S1 = Y2 - Y1
-+	lea	`32*9*1`($b_ptr), %rsi
-+	lea	`32*9*1`($a_ptr), %rdx
-+	lea	`32*9*4`(%rsp), %rdi
-+	call	avx2_sub_x4
-+	call	avx2_normalize_n_store
-+
-+	#	Z3 = H*Z1*Z2 = H
-+	lea	`32*9*3`(%rsp), %rsi
-+	lea	`32*9*2`($r_ptr), %rdi
-+	call	avx2_mul_by1_x4
-+	call	avx2_normalize
-+
-+	vmovdqa	`32*9*8`(%rsp), $B
-+	vpor	`32*9*8+32`(%rsp), $B, $B
-+
-+	vpandn	$ACC0, $B, $ACC0
-+	lea	.LONE+128(%rip), %rax
-+	vpandn	$ACC1, $B, $ACC1
-+	vpandn	$ACC2, $B, $ACC2
-+	vpandn	$ACC3, $B, $ACC3
-+	vpandn	$ACC4, $B, $ACC4
-+	vpandn	$ACC5, $B, $ACC5
-+	vpandn	$ACC6, $B, $ACC6
-+	vpandn	$ACC7, $B, $ACC7
-+
-+	vpand	32*0-128(%rax), $B, $T0
-+	 vpandn	$ACC8, $B, $ACC8
-+	vpand	32*1-128(%rax), $B, $Y
-+	vpxor	$T0, $ACC0, $ACC0
-+	vpand	32*2-128(%rax), $B, $T0
-+	vpxor	$Y, $ACC1, $ACC1
-+	vpand	32*3-128(%rax), $B, $Y
-+	vpxor	$T0, $ACC2, $ACC2
-+	vpand	32*4-128(%rax), $B, $T0
-+	vpxor	$Y, $ACC3, $ACC3
-+	vpand	32*5-128(%rax), $B, $Y
-+	vpxor	$T0, $ACC4, $ACC4
-+	vpand	32*6-128(%rax), $B, $T0
-+	vpxor	$Y, $ACC5, $ACC5
-+	vpand	32*7-128(%rax), $B, $Y
-+	vpxor	$T0, $ACC6, $ACC6
-+	vpand	32*8-128(%rax), $B, $T0
-+	vpxor	$Y, $ACC7, $ACC7
-+	vpxor	$T0, $ACC8, $ACC8
-+	`&STORE`
-+
-+	#	R^2 = R^2
-+	lea	`32*9*4`(%rsp), %rsi
-+	lea	`32*9*6`(%rsp), %rdi
-+	lea	`32*9*8+32*2`(%rsp), %rcx	# temporary vector
-+	call	avx2_sqr_x4
-+	call	avx2_normalize_n_store
-+
-+	#	H^2 = H^2
-+	lea	`32*9*3`(%rsp), %rsi
-+	lea	`32*9*5`(%rsp), %rdi
-+	call	avx2_sqr_x4
-+	call	avx2_normalize_n_store
-+
-+	#	H^3 = H^2*H
-+	lea	`32*9*3`(%rsp), %rsi
-+	lea	`32*9*5`(%rsp), %rdx
-+	lea	`32*9*7`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	call	avx2_normalize_n_store
-+
-+	#	U2 = U1*H^2
-+	lea	`32*9*0`($a_ptr), %rsi
-+	lea	`32*9*5`(%rsp), %rdx
-+	lea	`32*9*0`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	#call	avx2_normalize
-+	`&STORE`
-+
-+	#	Hsqr = U2*2
-+	#lea	32*9*0(%rsp), %rsi
-+	#lea	32*9*5(%rsp), %rdi
-+	#call	avx2_mul_by2_x4
-+
-+	vpaddq	$ACC0, $ACC0, $ACC0	# inlined avx2_mul_by2_x4
-+	lea	`32*9*5`(%rsp), %rdi
-+	vpaddq	$ACC1, $ACC1, $ACC1
-+	vpaddq	$ACC2, $ACC2, $ACC2
-+	vpaddq	$ACC3, $ACC3, $ACC3
-+	vpaddq	$ACC4, $ACC4, $ACC4
-+	vpaddq	$ACC5, $ACC5, $ACC5
-+	vpaddq	$ACC6, $ACC6, $ACC6
-+	vpaddq	$ACC7, $ACC7, $ACC7
-+	vpaddq	$ACC8, $ACC8, $ACC8
-+	call	avx2_normalize_n_store
-+
-+	#	X3 = R^2 - H^3
-+	#lea	32*9*6(%rsp), %rsi
-+	#lea	32*9*7(%rsp), %rdx
-+	#lea	32*9*5(%rsp), %rcx
-+	#lea	32*9*0($r_ptr), %rdi
-+	#call	avx2_sub_x4
-+	#NORMALIZE
-+	#STORE
-+
-+	#	X3 = X3 - U2*2
-+	#lea	32*9*0($r_ptr), %rsi
-+	#lea	32*9*0($r_ptr), %rdi
-+	#call	avx2_sub_x4
-+	#NORMALIZE
-+	#STORE
-+
-+	lea	`32*9*6+128`(%rsp), %rsi
-+	lea	.LAVX2_POLY_x2+128(%rip), %rax
-+	lea	`32*9*7+128`(%rsp), %rdx
-+	lea	`32*9*5+128`(%rsp), %rcx
-+	lea	`32*9*0`($r_ptr), %rdi
-+
-+	vmovdqa	32*0-128(%rsi), $ACC0
-+	vmovdqa	32*1-128(%rsi), $ACC1
-+	vmovdqa	32*2-128(%rsi), $ACC2
-+	vmovdqa	32*3-128(%rsi), $ACC3
-+	vmovdqa	32*4-128(%rsi), $ACC4
-+	vmovdqa	32*5-128(%rsi), $ACC5
-+	vmovdqa	32*6-128(%rsi), $ACC6
-+	vmovdqa	32*7-128(%rsi), $ACC7
-+	vmovdqa	32*8-128(%rsi), $ACC8
-+
-+	vpaddq	32*0-128(%rax), $ACC0, $ACC0
-+	vpaddq	32*1-128(%rax), $ACC1, $ACC1
-+	vpaddq	32*2-128(%rax), $ACC2, $ACC2
-+	vpaddq	32*3-128(%rax), $ACC3, $ACC3
-+	vpaddq	32*4-128(%rax), $ACC4, $ACC4
-+	vpaddq	32*5-128(%rax), $ACC5, $ACC5
-+	vpaddq	32*6-128(%rax), $ACC6, $ACC6
-+	vpaddq	32*7-128(%rax), $ACC7, $ACC7
-+	vpaddq	32*8-128(%rax), $ACC8, $ACC8
-+
-+	vpsubq	32*0-128(%rdx), $ACC0, $ACC0
-+	vpsubq	32*1-128(%rdx), $ACC1, $ACC1
-+	vpsubq	32*2-128(%rdx), $ACC2, $ACC2
-+	vpsubq	32*3-128(%rdx), $ACC3, $ACC3
-+	vpsubq	32*4-128(%rdx), $ACC4, $ACC4
-+	vpsubq	32*5-128(%rdx), $ACC5, $ACC5
-+	vpsubq	32*6-128(%rdx), $ACC6, $ACC6
-+	vpsubq	32*7-128(%rdx), $ACC7, $ACC7
-+	vpsubq	32*8-128(%rdx), $ACC8, $ACC8
-+
-+	vpsubq	32*0-128(%rcx), $ACC0, $ACC0
-+	vpsubq	32*1-128(%rcx), $ACC1, $ACC1
-+	vpsubq	32*2-128(%rcx), $ACC2, $ACC2
-+	vpsubq	32*3-128(%rcx), $ACC3, $ACC3
-+	vpsubq	32*4-128(%rcx), $ACC4, $ACC4
-+	vpsubq	32*5-128(%rcx), $ACC5, $ACC5
-+	vpsubq	32*6-128(%rcx), $ACC6, $ACC6
-+	vpsubq	32*7-128(%rcx), $ACC7, $ACC7
-+	vpsubq	32*8-128(%rcx), $ACC8, $ACC8
-+	call	avx2_normalize
-+
-+	lea	32*0($b_ptr), %rsi
-+	lea	32*0($a_ptr), %rdx
-+	call	avx2_select_n_store
-+
-+	#	H = U2 - X3
-+	lea	`32*9*0`(%rsp), %rsi
-+	lea	`32*9*0`($r_ptr), %rdx
-+	lea	`32*9*3`(%rsp), %rdi
-+	call	avx2_sub_x4
-+	call	avx2_normalize_n_store
-+
-+	#	H = H*R
-+	lea	`32*9*3`(%rsp), %rsi
-+	lea	`32*9*4`(%rsp), %rdx
-+	lea	`32*9*3`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	call	avx2_normalize_n_store
-+
-+	#	S2 = S1 * H^3
-+	lea	`32*9*7`(%rsp), %rsi
-+	lea	`32*9*1`($a_ptr), %rdx
-+	lea	`32*9*1`(%rsp), %rdi
-+	call	avx2_mul_x4
-+	call	avx2_normalize_n_store
-+
-+	#
-+	lea	`32*9*3`(%rsp), %rsi
-+	lea	`32*9*1`(%rsp), %rdx
-+	lea	`32*9*1`($r_ptr), %rdi
-+	call	avx2_sub_x4
-+	call	avx2_normalize
-+
-+	lea	32*9($b_ptr), %rsi
-+	lea	32*9($a_ptr), %rdx
-+	call	avx2_select_n_store
-+
-+	#lea	32*9*0($r_ptr), %rsi
-+	#lea	32*9*0($r_ptr), %rdi
-+	#call	avx2_mul_by1_x4
-+	#NORMALIZE
-+	#STORE
-+
-+	lea	`32*9*1`($r_ptr), %rsi
-+	lea	`32*9*1`($r_ptr), %rdi
-+	call	avx2_mul_by1_x4
-+	call	avx2_normalize_n_store
-+
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	movaps	%xmm6, -16*10(%rbp)
-+	movaps	%xmm7, -16*9(%rbp)
-+	movaps	%xmm8, -16*8(%rbp)
-+	movaps	%xmm9, -16*7(%rbp)
-+	movaps	%xmm10, -16*6(%rbp)
-+	movaps	%xmm11, -16*5(%rbp)
-+	movaps	%xmm12, -16*4(%rbp)
-+	movaps	%xmm13, -16*3(%rbp)
-+	movaps	%xmm14, -16*2(%rbp)
-+	movaps	%xmm15, -16*1(%rbp)
-+___
-+$code.=<<___;
-+	mov	%rbp, %rsp
-+	pop	%rbp
-+	ret
-+.size	ecp_nistz256_avx2_point_add_affines_x4,.-ecp_nistz256_avx2_point_add_affines_x4
-+
-+################################################################################
-+# void ecp_nistz256_avx2_to_mont(void* RESULTx4, void *Ax4);
-+.globl	ecp_nistz256_avx2_to_mont
-+.type	ecp_nistz256_avx2_to_mont,\@function,2
-+.align	32
-+ecp_nistz256_avx2_to_mont:
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	lea	-8-16*10(%rsp), %rsp
-+	vmovaps	%xmm6, -8-16*10(%rax)
-+	vmovaps	%xmm7, -8-16*9(%rax)
-+	vmovaps	%xmm8, -8-16*8(%rax)
-+	vmovaps	%xmm9, -8-16*7(%rax)
-+	vmovaps	%xmm10, -8-16*6(%rax)
-+	vmovaps	%xmm11, -8-16*5(%rax)
-+	vmovaps	%xmm12, -8-16*4(%rax)
-+	vmovaps	%xmm13, -8-16*3(%rax)
-+	vmovaps	%xmm14, -8-16*2(%rax)
-+	vmovaps	%xmm15, -8-16*1(%rax)
-+___
-+$code.=<<___;
-+	vmovdqa	.LAVX2_AND_MASK(%rip), $AND_MASK
-+	lea	.LTO_MONT_AVX2(%rip), %rdx
-+	call	avx2_mul_x4
-+	call	avx2_normalize_n_store
-+
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	movaps	16*0(%rsp), %xmm6
-+	movaps	16*1(%rsp), %xmm7
-+	movaps	16*2(%rsp), %xmm8
-+	movaps	16*3(%rsp), %xmm9
-+	movaps	16*4(%rsp), %xmm10
-+	movaps	16*5(%rsp), %xmm11
-+	movaps	16*6(%rsp), %xmm12
-+	movaps	16*7(%rsp), %xmm13
-+	movaps	16*8(%rsp), %xmm14
-+	movaps	16*9(%rsp), %xmm15
-+	lea	8+16*10(%rsp), %rsp
-+___
-+$code.=<<___;
-+	ret
-+.size	ecp_nistz256_avx2_to_mont,.-ecp_nistz256_avx2_to_mont
-+
-+################################################################################
-+# void ecp_nistz256_avx2_from_mont(void* RESULTx4, void *Ax4);
-+.globl	ecp_nistz256_avx2_from_mont
-+.type	ecp_nistz256_avx2_from_mont,\@function,2
-+.align	32
-+ecp_nistz256_avx2_from_mont:
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	lea	-8-16*10(%rsp), %rsp
-+	vmovaps	%xmm6, -8-16*10(%rax)
-+	vmovaps	%xmm7, -8-16*9(%rax)
-+	vmovaps	%xmm8, -8-16*8(%rax)
-+	vmovaps	%xmm9, -8-16*7(%rax)
-+	vmovaps	%xmm10, -8-16*6(%rax)
-+	vmovaps	%xmm11, -8-16*5(%rax)
-+	vmovaps	%xmm12, -8-16*4(%rax)
-+	vmovaps	%xmm13, -8-16*3(%rax)
-+	vmovaps	%xmm14, -8-16*2(%rax)
-+	vmovaps	%xmm15, -8-16*1(%rax)
-+___
-+$code.=<<___;
-+	vmovdqa	.LAVX2_AND_MASK(%rip), $AND_MASK
-+	lea	.LFROM_MONT_AVX2(%rip), %rdx
-+	call	avx2_mul_x4
-+	call	avx2_normalize_n_store
-+
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	movaps	16*0(%rsp), %xmm6
-+	movaps	16*1(%rsp), %xmm7
-+	movaps	16*2(%rsp), %xmm8
-+	movaps	16*3(%rsp), %xmm9
-+	movaps	16*4(%rsp), %xmm10
-+	movaps	16*5(%rsp), %xmm11
-+	movaps	16*6(%rsp), %xmm12
-+	movaps	16*7(%rsp), %xmm13
-+	movaps	16*8(%rsp), %xmm14
-+	movaps	16*9(%rsp), %xmm15
-+	lea	8+16*10(%rsp), %rsp
-+___
-+$code.=<<___;
-+	ret
-+.size	ecp_nistz256_avx2_from_mont,.-ecp_nistz256_avx2_from_mont
-+
-+################################################################################
-+# void ecp_nistz256_avx2_set1(void* RESULTx4);
-+.globl	ecp_nistz256_avx2_set1
-+.type	ecp_nistz256_avx2_set1,\@function,1
-+.align	32
-+ecp_nistz256_avx2_set1:
-+	lea	.LONE+128(%rip), %rax
-+	lea	128(%rdi), %rdi
-+	vzeroupper
-+	vmovdqa	32*0-128(%rax), %ymm0
-+	vmovdqa	32*1-128(%rax), %ymm1
-+	vmovdqa	32*2-128(%rax), %ymm2
-+	vmovdqa	32*3-128(%rax), %ymm3
-+	vmovdqa	32*4-128(%rax), %ymm4
-+	vmovdqa	32*5-128(%rax), %ymm5
-+	vmovdqa	%ymm0, 32*0-128(%rdi)
-+	vmovdqa	32*6-128(%rax), %ymm0
-+	vmovdqa	%ymm1, 32*1-128(%rdi)
-+	vmovdqa	32*7-128(%rax), %ymm1
-+	vmovdqa	%ymm2, 32*2-128(%rdi)
-+	vmovdqa	32*8-128(%rax), %ymm2
-+	vmovdqa	%ymm3, 32*3-128(%rdi)
-+	vmovdqa	%ymm4, 32*4-128(%rdi)
-+	vmovdqa	%ymm5, 32*5-128(%rdi)
-+	vmovdqa	%ymm0, 32*6-128(%rdi)
-+	vmovdqa	%ymm1, 32*7-128(%rdi)
-+	vmovdqa	%ymm2, 32*8-128(%rdi)
-+
-+	vzeroupper
-+	ret
-+.size	ecp_nistz256_avx2_set1,.-ecp_nistz256_avx2_set1
-+___
-+}
-+{
-+################################################################################
-+# void ecp_nistz256_avx2_multi_gather_w7(void* RESULT, void *in,
-+#			    int index0, int index1, int index2, int index3);
-+################################################################################
-+
-+my ($val,$in_t,$index0,$index1,$index2,$index3)=("%rdi","%rsi","%edx","%ecx","%r8d","%r9d");
-+my ($INDEX0,$INDEX1,$INDEX2,$INDEX3)=map("%ymm$_",(0..3));
-+my ($R0a,$R0b,$R1a,$R1b,$R2a,$R2b,$R3a,$R3b)=map("%ymm$_",(4..11));
-+my ($M0,$T0,$T1,$TMP0)=map("%ymm$_",(12..15));
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_avx2_multi_gather_w7
-+.type	ecp_nistz256_avx2_multi_gather_w7,\@function,6
-+.align	32
-+ecp_nistz256_avx2_multi_gather_w7:
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	lea	-8-16*10(%rsp), %rsp
-+	vmovaps	%xmm6, -8-16*10(%rax)
-+	vmovaps	%xmm7, -8-16*9(%rax)
-+	vmovaps	%xmm8, -8-16*8(%rax)
-+	vmovaps	%xmm9, -8-16*7(%rax)
-+	vmovaps	%xmm10, -8-16*6(%rax)
-+	vmovaps	%xmm11, -8-16*5(%rax)
-+	vmovaps	%xmm12, -8-16*4(%rax)
-+	vmovaps	%xmm13, -8-16*3(%rax)
-+	vmovaps	%xmm14, -8-16*2(%rax)
-+	vmovaps	%xmm15, -8-16*1(%rax)
-+___
-+$code.=<<___;
-+	lea	.LIntOne(%rip), %rax
-+
-+	vmovd	$index0, %xmm0
-+	vmovd	$index1, %xmm1
-+	vmovd	$index2, %xmm2
-+	vmovd	$index3, %xmm3
-+
-+	vpxor	$R0a, $R0a, $R0a
-+	vpxor	$R0b, $R0b, $R0b
-+	vpxor	$R1a, $R1a, $R1a
-+	vpxor	$R1b, $R1b, $R1b
-+	vpxor	$R2a, $R2a, $R2a
-+	vpxor	$R2b, $R2b, $R2b
-+	vpxor	$R3a, $R3a, $R3a
-+	vpxor	$R3b, $R3b, $R3b
-+	vmovdqa	(%rax), $M0
-+
-+	vpermd	$INDEX0, $R0a, $INDEX0
-+	vpermd	$INDEX1, $R0a, $INDEX1
-+	vpermd	$INDEX2, $R0a, $INDEX2
-+	vpermd	$INDEX3, $R0a, $INDEX3
-+
-+	mov	\$64, %ecx
-+	lea	112($val), $val		# size optimization
-+	jmp	.Lmulti_select_loop_avx2
-+
-+# INDEX=0, corresponds to the point at infty (0,0)
-+.align	32
-+.Lmulti_select_loop_avx2:
-+	vpcmpeqd	$INDEX0, $M0, $TMP0
-+
-+	vmovdqa		`32*0+32*64*2*0`($in_t), $T0
-+	vmovdqa		`32*1+32*64*2*0`($in_t), $T1
-+	vpand		$TMP0, $T0, $T0
-+	vpand		$TMP0, $T1, $T1
-+	vpxor		$T0, $R0a, $R0a
-+	vpxor		$T1, $R0b, $R0b
-+
-+	vpcmpeqd	$INDEX1, $M0, $TMP0
-+
-+	vmovdqa		`32*0+32*64*2*1`($in_t), $T0
-+	vmovdqa		`32*1+32*64*2*1`($in_t), $T1
-+	vpand		$TMP0, $T0, $T0
-+	vpand		$TMP0, $T1, $T1
-+	vpxor		$T0, $R1a, $R1a
-+	vpxor		$T1, $R1b, $R1b
-+
-+	vpcmpeqd	$INDEX2, $M0, $TMP0
-+
-+	vmovdqa		`32*0+32*64*2*2`($in_t), $T0
-+	vmovdqa		`32*1+32*64*2*2`($in_t), $T1
-+	vpand		$TMP0, $T0, $T0
-+	vpand		$TMP0, $T1, $T1
-+	vpxor		$T0, $R2a, $R2a
-+	vpxor		$T1, $R2b, $R2b
-+
-+	vpcmpeqd	$INDEX3, $M0, $TMP0
-+
-+	vmovdqa		`32*0+32*64*2*3`($in_t), $T0
-+	vmovdqa		`32*1+32*64*2*3`($in_t), $T1
-+	vpand		$TMP0, $T0, $T0
-+	vpand		$TMP0, $T1, $T1
-+	vpxor		$T0, $R3a, $R3a
-+	vpxor		$T1, $R3b, $R3b
-+
-+	vpaddd		(%rax), $M0, $M0	# increment
-+	lea		32*2($in_t), $in_t
-+
-+        dec	%ecx
-+	jnz	.Lmulti_select_loop_avx2
-+
-+	vmovdqu	$R0a, 32*0-112($val)
-+	vmovdqu	$R0b, 32*1-112($val)
-+	vmovdqu	$R1a, 32*2-112($val)
-+	vmovdqu	$R1b, 32*3-112($val)
-+	vmovdqu	$R2a, 32*4-112($val)
-+	vmovdqu	$R2b, 32*5-112($val)
-+	vmovdqu	$R3a, 32*6-112($val)
-+	vmovdqu	$R3b, 32*7-112($val)
-+
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	movaps	16*0(%rsp), %xmm6
-+	movaps	16*1(%rsp), %xmm7
-+	movaps	16*2(%rsp), %xmm8
-+	movaps	16*3(%rsp), %xmm9
-+	movaps	16*4(%rsp), %xmm10
-+	movaps	16*5(%rsp), %xmm11
-+	movaps	16*6(%rsp), %xmm12
-+	movaps	16*7(%rsp), %xmm13
-+	movaps	16*8(%rsp), %xmm14
-+	movaps	16*9(%rsp), %xmm15
-+	lea	8+16*10(%rsp), %rsp
-+___
-+$code.=<<___;
-+	ret
-+.size	ecp_nistz256_avx2_multi_gather_w7,.-ecp_nistz256_avx2_multi_gather_w7
-+
-+.extern	OPENSSL_ia32cap_P
-+.globl	ecp_nistz_avx2_eligible
-+.type	ecp_nistz_avx2_eligible,\@abi-omnipotent
-+.align	32
-+ecp_nistz_avx2_eligible:
-+	mov	OPENSSL_ia32cap_P+8(%rip),%eax
-+	shr	\$5,%eax
-+	and	\$1,%eax
-+	ret
-+.size	ecp_nistz_avx2_eligible,.-ecp_nistz_avx2_eligible
-+___
-+}
-+}} else {{	# assembler is too old
-+$code.=<<___;
-+.text
-+
-+.globl	ecp_nistz256_avx2_transpose_convert
-+.globl	ecp_nistz256_avx2_convert_transpose_back
-+.globl	ecp_nistz256_avx2_point_add_affine_x4
-+.globl	ecp_nistz256_avx2_point_add_affines_x4
-+.globl	ecp_nistz256_avx2_to_mont
-+.globl	ecp_nistz256_avx2_from_mont
-+.globl	ecp_nistz256_avx2_set1
-+.globl	ecp_nistz256_avx2_multi_gather_w7
-+.type	ecp_nistz256_avx2_multi_gather_w7,\@abi-omnipotent
-+ecp_nistz256_avx2_transpose_convert:
-+ecp_nistz256_avx2_convert_transpose_back:
-+ecp_nistz256_avx2_point_add_affine_x4:
-+ecp_nistz256_avx2_point_add_affines_x4:
-+ecp_nistz256_avx2_to_mont:
-+ecp_nistz256_avx2_from_mont:
-+ecp_nistz256_avx2_set1:
-+ecp_nistz256_avx2_multi_gather_w7:
-+	.byte	0x0f,0x0b	# ud2
-+	ret
-+.size	ecp_nistz256_avx2_multi_gather_w7,.-ecp_nistz256_avx2_multi_gather_w7
-+
-+.globl	ecp_nistz_avx2_eligible
-+.type	ecp_nistz_avx2_eligible,\@abi-omnipotent
-+ecp_nistz_avx2_eligible:
-+	xor	%eax,%eax
-+	ret
-+.size	ecp_nistz_avx2_eligible,.-ecp_nistz_avx2_eligible
-+___
-+}}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval($1)/geo;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-sparcv9.pl
-new file mode 100755
-index 0000000..97201cb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-sparcv9.pl
-@@ -0,0 +1,3061 @@
-+#! /usr/bin/env perl
-+# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# ECP_NISTZ256 module for SPARCv9.
-+#
-+# February 2015.
-+#
-+# Original ECP_NISTZ256 submission targeting x86_64 is detailed in
-+# http://eprint.iacr.org/2013/816. In the process of adaptation
-+# original .c module was made 32-bit savvy in order to make this
-+# implementation possible.
-+#
-+#			with/without -DECP_NISTZ256_ASM
-+# UltraSPARC III	+12-18%
-+# SPARC T4		+99-550% (+66-150% on 32-bit Solaris)
-+#
-+# Ranges denote minimum and maximum improvement coefficients depending
-+# on benchmark. Lower coefficients are for ECDSA sign, server-side
-+# operation. Keep in mind that +200% means 3x improvement.
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#define LOCALS	(STACK_BIAS+STACK_FRAME)
-+#ifdef	__arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+# define STACK64_FRAME	STACK_FRAME
-+# define LOCALS64	LOCALS
-+#else
-+# define STACK64_FRAME	(2047+192)
-+# define LOCALS64	STACK64_FRAME
-+#endif
-+
-+.section	".text",#alloc,#execinstr
-+___
-+########################################################################
-+# Convert ecp_nistz256_table.c to layout expected by ecp_nistz_gather_w7
-+#
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+open TABLE,") {
-+	s/TOBN\(\s*(0x[0-9a-f]+),\s*(0x[0-9a-f]+)\s*\)/push @arr,hex($2),hex($1)/geo;
-+}
-+close TABLE;
-+
-+# See ecp_nistz256_table.c for explanation for why it's 64*16*37.
-+# 64*16*37-1 is because $#arr returns last valid index or @arr, not
-+# amount of elements.
-+die "insane number of elements" if ($#arr != 64*16*37-1);
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_precomputed
-+.align	4096
-+ecp_nistz256_precomputed:
-+___
-+########################################################################
-+# this conversion smashes P256_POINT_AFFINE by individual bytes with
-+# 64 byte interval, similar to
-+#	1111222233334444
-+#	1234123412341234
-+for(1..37) {
-+	@tbl = splice(@arr,0,64*16);
-+	for($i=0;$i<64;$i++) {
-+		undef @line;
-+		for($j=0;$j<64;$j++) {
-+			push @line,(@tbl[$j*16+$i/4]>>(($i%4)*8))&0xff;
-+		}
-+		$code.=".byte\t";
-+		$code.=join(',',map { sprintf "0x%02x",$_} @line);
-+		$code.="\n";
-+	}
-+}
-+
-+{{{
-+my ($rp,$ap,$bp)=map("%i$_",(0..2));
-+my @acc=map("%l$_",(0..7));
-+my ($t0,$t1,$t2,$t3,$t4,$t5,$t6,$t7)=(map("%o$_",(0..5)),"%g4","%g5");
-+my ($bi,$a0,$mask,$carry)=(map("%i$_",(3..5)),"%g1");
-+my ($rp_real,$ap_real)=("%g2","%g3");
-+
-+$code.=<<___;
-+.type	ecp_nistz256_precomputed,#object
-+.size	ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
-+.align	64
-+.LRR:	! 2^512 mod P precomputed for NIST P256 polynomial
-+.long	0x00000003, 0x00000000, 0xffffffff, 0xfffffffb
-+.long	0xfffffffe, 0xffffffff, 0xfffffffd, 0x00000004
-+.Lone:
-+.long	1,0,0,0,0,0,0,0
-+.asciz	"ECP_NISTZ256 for SPARCv9, CRYPTOGAMS by "
-+
-+! void	ecp_nistz256_to_mont(BN_ULONG %i0[8],const BN_ULONG %i1[8]);
-+.globl	ecp_nistz256_to_mont
-+.align	64
-+ecp_nistz256_to_mont:
-+	save	%sp,-STACK_FRAME,%sp
-+	nop
-+1:	call	.+8
-+	add	%o7,.LRR-1b,$bp
-+	call	__ecp_nistz256_mul_mont
-+	nop
-+	ret
-+	restore
-+.type	ecp_nistz256_to_mont,#function
-+.size	ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
-+
-+! void	ecp_nistz256_from_mont(BN_ULONG %i0[8],const BN_ULONG %i1[8]);
-+.globl	ecp_nistz256_from_mont
-+.align	32
-+ecp_nistz256_from_mont:
-+	save	%sp,-STACK_FRAME,%sp
-+	nop
-+1:	call	.+8
-+	add	%o7,.Lone-1b,$bp
-+	call	__ecp_nistz256_mul_mont
-+	nop
-+	ret
-+	restore
-+.type	ecp_nistz256_from_mont,#function
-+.size	ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
-+
-+! void	ecp_nistz256_mul_mont(BN_ULONG %i0[8],const BN_ULONG %i1[8],
-+!					      const BN_ULONG %i2[8]);
-+.globl	ecp_nistz256_mul_mont
-+.align	32
-+ecp_nistz256_mul_mont:
-+	save	%sp,-STACK_FRAME,%sp
-+	nop
-+	call	__ecp_nistz256_mul_mont
-+	nop
-+	ret
-+	restore
-+.type	ecp_nistz256_mul_mont,#function
-+.size	ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
-+
-+! void	ecp_nistz256_sqr_mont(BN_ULONG %i0[8],const BN_ULONG %i2[8]);
-+.globl	ecp_nistz256_sqr_mont
-+.align	32
-+ecp_nistz256_sqr_mont:
-+	save	%sp,-STACK_FRAME,%sp
-+	mov	$ap,$bp
-+	call	__ecp_nistz256_mul_mont
-+	nop
-+	ret
-+	restore
-+.type	ecp_nistz256_sqr_mont,#function
-+.size	ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
-+___
-+
-+########################################################################
-+# Special thing to keep in mind is that $t0-$t7 hold 64-bit values,
-+# while all others are meant to keep 32. "Meant to" means that additions
-+# to @acc[0-7] do "contaminate" upper bits, but they are cleared before
-+# they can affect outcome (follow 'and' with $mask). Also keep in mind
-+# that addition with carry is addition with 32-bit carry, even though
-+# CPU is 64-bit. [Addition with 64-bit carry was introduced in T3, see
-+# below for VIS3 code paths.]
-+
-+$code.=<<___;
-+.align	32
-+__ecp_nistz256_mul_mont:
-+	ld	[$bp+0],$bi		! b[0]
-+	mov	-1,$mask
-+	ld	[$ap+0],$a0
-+	srl	$mask,0,$mask		! 0xffffffff
-+	ld	[$ap+4],$t1
-+	ld	[$ap+8],$t2
-+	ld	[$ap+12],$t3
-+	ld	[$ap+16],$t4
-+	ld	[$ap+20],$t5
-+	ld	[$ap+24],$t6
-+	ld	[$ap+28],$t7
-+	mulx	$a0,$bi,$t0		! a[0-7]*b[0], 64-bit results
-+	mulx	$t1,$bi,$t1
-+	mulx	$t2,$bi,$t2
-+	mulx	$t3,$bi,$t3
-+	mulx	$t4,$bi,$t4
-+	mulx	$t5,$bi,$t5
-+	mulx	$t6,$bi,$t6
-+	mulx	$t7,$bi,$t7
-+	srlx	$t0,32,@acc[1]		! extract high parts
-+	srlx	$t1,32,@acc[2]
-+	srlx	$t2,32,@acc[3]
-+	srlx	$t3,32,@acc[4]
-+	srlx	$t4,32,@acc[5]
-+	srlx	$t5,32,@acc[6]
-+	srlx	$t6,32,@acc[7]
-+	srlx	$t7,32,@acc[0]		! "@acc[8]"
-+	mov	0,$carry
-+___
-+for($i=1;$i<8;$i++) {
-+$code.=<<___;
-+	addcc	@acc[1],$t1,@acc[1]	! accumulate high parts
-+	ld	[$bp+4*$i],$bi		! b[$i]
-+	ld	[$ap+4],$t1		! re-load a[1-7]
-+	addccc	@acc[2],$t2,@acc[2]
-+	addccc	@acc[3],$t3,@acc[3]
-+	ld	[$ap+8],$t2
-+	ld	[$ap+12],$t3
-+	addccc	@acc[4],$t4,@acc[4]
-+	addccc	@acc[5],$t5,@acc[5]
-+	ld	[$ap+16],$t4
-+	ld	[$ap+20],$t5
-+	addccc	@acc[6],$t6,@acc[6]
-+	addccc	@acc[7],$t7,@acc[7]
-+	ld	[$ap+24],$t6
-+	ld	[$ap+28],$t7
-+	addccc	@acc[0],$carry,@acc[0]	! "@acc[8]"
-+	addc	%g0,%g0,$carry
-+___
-+	# Reduction iteration is normally performed by accumulating
-+	# result of multiplication of modulus by "magic" digit [and
-+	# omitting least significant word, which is guaranteed to
-+	# be 0], but thanks to special form of modulus and "magic"
-+	# digit being equal to least significant word, it can be
-+	# performed with additions and subtractions alone. Indeed:
-+	#
-+	#        ffff.0001.0000.0000.0000.ffff.ffff.ffff
-+	# *                                         abcd
-+	# + xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.abcd
-+	#
-+	# Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we
-+	# rewrite above as:
-+	#
-+	#   xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.abcd
-+	# + abcd.0000.abcd.0000.0000.abcd.0000.0000.0000
-+	# -      abcd.0000.0000.0000.0000.0000.0000.abcd
-+	#
-+	# or marking redundant operations:
-+	#
-+	#   xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.----
-+	# + abcd.0000.abcd.0000.0000.abcd.----.----.----
-+	# -      abcd.----.----.----.----.----.----.----
-+
-+$code.=<<___;
-+	! multiplication-less reduction
-+	addcc	@acc[3],$t0,@acc[3]	! r[3]+=r[0]
-+	addccc	@acc[4],%g0,@acc[4]	! r[4]+=0
-+	 and	@acc[1],$mask,@acc[1]
-+	 and	@acc[2],$mask,@acc[2]
-+	addccc	@acc[5],%g0,@acc[5]	! r[5]+=0
-+	addccc	@acc[6],$t0,@acc[6]	! r[6]+=r[0]
-+	 and	@acc[3],$mask,@acc[3]
-+	 and	@acc[4],$mask,@acc[4]
-+	addccc	@acc[7],%g0,@acc[7]	! r[7]+=0
-+	addccc	@acc[0],$t0,@acc[0]	! r[8]+=r[0]	"@acc[8]"
-+	 and	@acc[5],$mask,@acc[5]
-+	 and	@acc[6],$mask,@acc[6]
-+	addc	$carry,%g0,$carry	! top-most carry
-+	subcc	@acc[7],$t0,@acc[7]	! r[7]-=r[0]
-+	subccc	@acc[0],%g0,@acc[0]	! r[8]-=0	"@acc[8]"
-+	subc	$carry,%g0,$carry	! top-most carry
-+	 and	@acc[7],$mask,@acc[7]
-+	 and	@acc[0],$mask,@acc[0]	! "@acc[8]"
-+___
-+	push(@acc,shift(@acc));		# rotate registers to "omit" acc[0]
-+$code.=<<___;
-+	mulx	$a0,$bi,$t0		! a[0-7]*b[$i], 64-bit results
-+	mulx	$t1,$bi,$t1
-+	mulx	$t2,$bi,$t2
-+	mulx	$t3,$bi,$t3
-+	mulx	$t4,$bi,$t4
-+	mulx	$t5,$bi,$t5
-+	mulx	$t6,$bi,$t6
-+	mulx	$t7,$bi,$t7
-+	add	@acc[0],$t0,$t0		! accumulate low parts, can't overflow
-+	add	@acc[1],$t1,$t1
-+	srlx	$t0,32,@acc[1]		! extract high parts
-+	add	@acc[2],$t2,$t2
-+	srlx	$t1,32,@acc[2]
-+	add	@acc[3],$t3,$t3
-+	srlx	$t2,32,@acc[3]
-+	add	@acc[4],$t4,$t4
-+	srlx	$t3,32,@acc[4]
-+	add	@acc[5],$t5,$t5
-+	srlx	$t4,32,@acc[5]
-+	add	@acc[6],$t6,$t6
-+	srlx	$t5,32,@acc[6]
-+	add	@acc[7],$t7,$t7
-+	srlx	$t6,32,@acc[7]
-+	srlx	$t7,32,@acc[0]		! "@acc[8]"
-+___
-+}
-+$code.=<<___;
-+	addcc	@acc[1],$t1,@acc[1]	! accumulate high parts
-+	addccc	@acc[2],$t2,@acc[2]
-+	addccc	@acc[3],$t3,@acc[3]
-+	addccc	@acc[4],$t4,@acc[4]
-+	addccc	@acc[5],$t5,@acc[5]
-+	addccc	@acc[6],$t6,@acc[6]
-+	addccc	@acc[7],$t7,@acc[7]
-+	addccc	@acc[0],$carry,@acc[0]	! "@acc[8]"
-+	addc	%g0,%g0,$carry
-+
-+	addcc	@acc[3],$t0,@acc[3]	! multiplication-less reduction
-+	addccc	@acc[4],%g0,@acc[4]
-+	addccc	@acc[5],%g0,@acc[5]
-+	addccc	@acc[6],$t0,@acc[6]
-+	addccc	@acc[7],%g0,@acc[7]
-+	addccc	@acc[0],$t0,@acc[0]	! "@acc[8]"
-+	addc	$carry,%g0,$carry
-+	subcc	@acc[7],$t0,@acc[7]
-+	subccc	@acc[0],%g0,@acc[0]	! "@acc[8]"
-+	subc	$carry,%g0,$carry	! top-most carry
-+___
-+	push(@acc,shift(@acc));		# rotate registers to omit acc[0]
-+$code.=<<___;
-+	! Final step is "if result > mod, subtract mod", but we do it
-+	! "other way around", namely subtract modulus from result
-+	! and if it borrowed, add modulus back.
-+
-+	subcc	@acc[0],-1,@acc[0]	! subtract modulus
-+	subccc	@acc[1],-1,@acc[1]
-+	subccc	@acc[2],-1,@acc[2]
-+	subccc	@acc[3],0,@acc[3]
-+	subccc	@acc[4],0,@acc[4]
-+	subccc	@acc[5],0,@acc[5]
-+	subccc	@acc[6],1,@acc[6]
-+	subccc	@acc[7],-1,@acc[7]
-+	subc	$carry,0,$carry		! broadcast borrow bit
-+
-+	! Note that because mod has special form, i.e. consists of
-+	! 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	! using value of broadcasted borrow and the borrow bit itself.
-+	! To minimize dependency chain we first broadcast and then
-+	! extract the bit by negating (follow $bi).
-+
-+	addcc	@acc[0],$carry,@acc[0]	! add modulus or zero
-+	addccc	@acc[1],$carry,@acc[1]
-+	neg	$carry,$bi
-+	st	@acc[0],[$rp]
-+	addccc	@acc[2],$carry,@acc[2]
-+	st	@acc[1],[$rp+4]
-+	addccc	@acc[3],0,@acc[3]
-+	st	@acc[2],[$rp+8]
-+	addccc	@acc[4],0,@acc[4]
-+	st	@acc[3],[$rp+12]
-+	addccc	@acc[5],0,@acc[5]
-+	st	@acc[4],[$rp+16]
-+	addccc	@acc[6],$bi,@acc[6]
-+	st	@acc[5],[$rp+20]
-+	addc	@acc[7],$carry,@acc[7]
-+	st	@acc[6],[$rp+24]
-+	retl
-+	st	@acc[7],[$rp+28]
-+.type	__ecp_nistz256_mul_mont,#function
-+.size	__ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont
-+
-+! void	ecp_nistz256_add(BN_ULONG %i0[8],const BN_ULONG %i1[8],
-+!					 const BN_ULONG %i2[8]);
-+.globl	ecp_nistz256_add
-+.align	32
-+ecp_nistz256_add:
-+	save	%sp,-STACK_FRAME,%sp
-+	ld	[$ap],@acc[0]
-+	ld	[$ap+4],@acc[1]
-+	ld	[$ap+8],@acc[2]
-+	ld	[$ap+12],@acc[3]
-+	ld	[$ap+16],@acc[4]
-+	ld	[$ap+20],@acc[5]
-+	ld	[$ap+24],@acc[6]
-+	call	__ecp_nistz256_add
-+	ld	[$ap+28],@acc[7]
-+	ret
-+	restore
-+.type	ecp_nistz256_add,#function
-+.size	ecp_nistz256_add,.-ecp_nistz256_add
-+
-+.align	32
-+__ecp_nistz256_add:
-+	ld	[$bp+0],$t0		! b[0]
-+	ld	[$bp+4],$t1
-+	ld	[$bp+8],$t2
-+	ld	[$bp+12],$t3
-+	addcc	@acc[0],$t0,@acc[0]
-+	ld	[$bp+16],$t4
-+	ld	[$bp+20],$t5
-+	addccc	@acc[1],$t1,@acc[1]
-+	ld	[$bp+24],$t6
-+	ld	[$bp+28],$t7
-+	addccc	@acc[2],$t2,@acc[2]
-+	addccc	@acc[3],$t3,@acc[3]
-+	addccc	@acc[4],$t4,@acc[4]
-+	addccc	@acc[5],$t5,@acc[5]
-+	addccc	@acc[6],$t6,@acc[6]
-+	addccc	@acc[7],$t7,@acc[7]
-+	addc	%g0,%g0,$carry
-+
-+.Lreduce_by_sub:
-+
-+	! if a+b >= modulus, subtract modulus.
-+	!
-+	! But since comparison implies subtraction, we subtract
-+	! modulus and then add it back if subraction borrowed.
-+
-+	subcc	@acc[0],-1,@acc[0]
-+	subccc	@acc[1],-1,@acc[1]
-+	subccc	@acc[2],-1,@acc[2]
-+	subccc	@acc[3], 0,@acc[3]
-+	subccc	@acc[4], 0,@acc[4]
-+	subccc	@acc[5], 0,@acc[5]
-+	subccc	@acc[6], 1,@acc[6]
-+	subccc	@acc[7],-1,@acc[7]
-+	subc	$carry,0,$carry
-+
-+	! Note that because mod has special form, i.e. consists of
-+	! 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	! using value of borrow and its negative.
-+
-+	addcc	@acc[0],$carry,@acc[0]	! add synthesized modulus
-+	addccc	@acc[1],$carry,@acc[1]
-+	neg	$carry,$bi
-+	st	@acc[0],[$rp]
-+	addccc	@acc[2],$carry,@acc[2]
-+	st	@acc[1],[$rp+4]
-+	addccc	@acc[3],0,@acc[3]
-+	st	@acc[2],[$rp+8]
-+	addccc	@acc[4],0,@acc[4]
-+	st	@acc[3],[$rp+12]
-+	addccc	@acc[5],0,@acc[5]
-+	st	@acc[4],[$rp+16]
-+	addccc	@acc[6],$bi,@acc[6]
-+	st	@acc[5],[$rp+20]
-+	addc	@acc[7],$carry,@acc[7]
-+	st	@acc[6],[$rp+24]
-+	retl
-+	st	@acc[7],[$rp+28]
-+.type	__ecp_nistz256_add,#function
-+.size	__ecp_nistz256_add,.-__ecp_nistz256_add
-+
-+! void	ecp_nistz256_mul_by_2(BN_ULONG %i0[8],const BN_ULONG %i1[8]);
-+.globl	ecp_nistz256_mul_by_2
-+.align	32
-+ecp_nistz256_mul_by_2:
-+	save	%sp,-STACK_FRAME,%sp
-+	ld	[$ap],@acc[0]
-+	ld	[$ap+4],@acc[1]
-+	ld	[$ap+8],@acc[2]
-+	ld	[$ap+12],@acc[3]
-+	ld	[$ap+16],@acc[4]
-+	ld	[$ap+20],@acc[5]
-+	ld	[$ap+24],@acc[6]
-+	call	__ecp_nistz256_mul_by_2
-+	ld	[$ap+28],@acc[7]
-+	ret
-+	restore
-+.type	ecp_nistz256_mul_by_2,#function
-+.size	ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
-+
-+.align	32
-+__ecp_nistz256_mul_by_2:
-+	addcc	@acc[0],@acc[0],@acc[0]	! a+a=2*a
-+	addccc	@acc[1],@acc[1],@acc[1]
-+	addccc	@acc[2],@acc[2],@acc[2]
-+	addccc	@acc[3],@acc[3],@acc[3]
-+	addccc	@acc[4],@acc[4],@acc[4]
-+	addccc	@acc[5],@acc[5],@acc[5]
-+	addccc	@acc[6],@acc[6],@acc[6]
-+	addccc	@acc[7],@acc[7],@acc[7]
-+	b	.Lreduce_by_sub
-+	addc	%g0,%g0,$carry
-+.type	__ecp_nistz256_mul_by_2,#function
-+.size	__ecp_nistz256_mul_by_2,.-__ecp_nistz256_mul_by_2
-+
-+! void	ecp_nistz256_mul_by_3(BN_ULONG %i0[8],const BN_ULONG %i1[8]);
-+.globl	ecp_nistz256_mul_by_3
-+.align	32
-+ecp_nistz256_mul_by_3:
-+	save	%sp,-STACK_FRAME,%sp
-+	ld	[$ap],@acc[0]
-+	ld	[$ap+4],@acc[1]
-+	ld	[$ap+8],@acc[2]
-+	ld	[$ap+12],@acc[3]
-+	ld	[$ap+16],@acc[4]
-+	ld	[$ap+20],@acc[5]
-+	ld	[$ap+24],@acc[6]
-+	call	__ecp_nistz256_mul_by_3
-+	ld	[$ap+28],@acc[7]
-+	ret
-+	restore
-+.type	ecp_nistz256_mul_by_3,#function
-+.size	ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
-+
-+.align	32
-+__ecp_nistz256_mul_by_3:
-+	addcc	@acc[0],@acc[0],$t0	! a+a=2*a
-+	addccc	@acc[1],@acc[1],$t1
-+	addccc	@acc[2],@acc[2],$t2
-+	addccc	@acc[3],@acc[3],$t3
-+	addccc	@acc[4],@acc[4],$t4
-+	addccc	@acc[5],@acc[5],$t5
-+	addccc	@acc[6],@acc[6],$t6
-+	addccc	@acc[7],@acc[7],$t7
-+	addc	%g0,%g0,$carry
-+
-+	subcc	$t0,-1,$t0		! .Lreduce_by_sub but without stores
-+	subccc	$t1,-1,$t1
-+	subccc	$t2,-1,$t2
-+	subccc	$t3, 0,$t3
-+	subccc	$t4, 0,$t4
-+	subccc	$t5, 0,$t5
-+	subccc	$t6, 1,$t6
-+	subccc	$t7,-1,$t7
-+	subc	$carry,0,$carry
-+
-+	addcc	$t0,$carry,$t0		! add synthesized modulus
-+	addccc	$t1,$carry,$t1
-+	neg	$carry,$bi
-+	addccc	$t2,$carry,$t2
-+	addccc	$t3,0,$t3
-+	addccc	$t4,0,$t4
-+	addccc	$t5,0,$t5
-+	addccc	$t6,$bi,$t6
-+	addc	$t7,$carry,$t7
-+
-+	addcc	$t0,@acc[0],@acc[0]	! 2*a+a=3*a
-+	addccc	$t1,@acc[1],@acc[1]
-+	addccc	$t2,@acc[2],@acc[2]
-+	addccc	$t3,@acc[3],@acc[3]
-+	addccc	$t4,@acc[4],@acc[4]
-+	addccc	$t5,@acc[5],@acc[5]
-+	addccc	$t6,@acc[6],@acc[6]
-+	addccc	$t7,@acc[7],@acc[7]
-+	b	.Lreduce_by_sub
-+	addc	%g0,%g0,$carry
-+.type	__ecp_nistz256_mul_by_3,#function
-+.size	__ecp_nistz256_mul_by_3,.-__ecp_nistz256_mul_by_3
-+
-+! void	ecp_nistz256_sub(BN_ULONG %i0[8],const BN_ULONG %i1[8],
-+!				         const BN_ULONG %i2[8]);
-+.globl	ecp_nistz256_sub
-+.align	32
-+ecp_nistz256_sub:
-+	save	%sp,-STACK_FRAME,%sp
-+	ld	[$ap],@acc[0]
-+	ld	[$ap+4],@acc[1]
-+	ld	[$ap+8],@acc[2]
-+	ld	[$ap+12],@acc[3]
-+	ld	[$ap+16],@acc[4]
-+	ld	[$ap+20],@acc[5]
-+	ld	[$ap+24],@acc[6]
-+	call	__ecp_nistz256_sub_from
-+	ld	[$ap+28],@acc[7]
-+	ret
-+	restore
-+.type	ecp_nistz256_sub,#function
-+.size	ecp_nistz256_sub,.-ecp_nistz256_sub
-+
-+! void	ecp_nistz256_neg(BN_ULONG %i0[8],const BN_ULONG %i1[8]);
-+.globl	ecp_nistz256_neg
-+.align	32
-+ecp_nistz256_neg:
-+	save	%sp,-STACK_FRAME,%sp
-+	mov	$ap,$bp
-+	mov	0,@acc[0]
-+	mov	0,@acc[1]
-+	mov	0,@acc[2]
-+	mov	0,@acc[3]
-+	mov	0,@acc[4]
-+	mov	0,@acc[5]
-+	mov	0,@acc[6]
-+	call	__ecp_nistz256_sub_from
-+	mov	0,@acc[7]
-+	ret
-+	restore
-+.type	ecp_nistz256_neg,#function
-+.size	ecp_nistz256_neg,.-ecp_nistz256_neg
-+
-+.align	32
-+__ecp_nistz256_sub_from:
-+	ld	[$bp+0],$t0		! b[0]
-+	ld	[$bp+4],$t1
-+	ld	[$bp+8],$t2
-+	ld	[$bp+12],$t3
-+	subcc	@acc[0],$t0,@acc[0]
-+	ld	[$bp+16],$t4
-+	ld	[$bp+20],$t5
-+	subccc	@acc[1],$t1,@acc[1]
-+	subccc	@acc[2],$t2,@acc[2]
-+	ld	[$bp+24],$t6
-+	ld	[$bp+28],$t7
-+	subccc	@acc[3],$t3,@acc[3]
-+	subccc	@acc[4],$t4,@acc[4]
-+	subccc	@acc[5],$t5,@acc[5]
-+	subccc	@acc[6],$t6,@acc[6]
-+	subccc	@acc[7],$t7,@acc[7]
-+	subc	%g0,%g0,$carry		! broadcast borrow bit
-+
-+.Lreduce_by_add:
-+
-+	! if a-b borrows, add modulus.
-+	!
-+	! Note that because mod has special form, i.e. consists of
-+	! 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	! using value of broadcasted borrow and the borrow bit itself.
-+	! To minimize dependency chain we first broadcast and then
-+	! extract the bit by negating (follow $bi).
-+
-+	addcc	@acc[0],$carry,@acc[0]	! add synthesized modulus
-+	addccc	@acc[1],$carry,@acc[1]
-+	neg	$carry,$bi
-+	st	@acc[0],[$rp]
-+	addccc	@acc[2],$carry,@acc[2]
-+	st	@acc[1],[$rp+4]
-+	addccc	@acc[3],0,@acc[3]
-+	st	@acc[2],[$rp+8]
-+	addccc	@acc[4],0,@acc[4]
-+	st	@acc[3],[$rp+12]
-+	addccc	@acc[5],0,@acc[5]
-+	st	@acc[4],[$rp+16]
-+	addccc	@acc[6],$bi,@acc[6]
-+	st	@acc[5],[$rp+20]
-+	addc	@acc[7],$carry,@acc[7]
-+	st	@acc[6],[$rp+24]
-+	retl
-+	st	@acc[7],[$rp+28]
-+.type	__ecp_nistz256_sub_from,#function
-+.size	__ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from
-+
-+.align	32
-+__ecp_nistz256_sub_morf:
-+	ld	[$bp+0],$t0		! b[0]
-+	ld	[$bp+4],$t1
-+	ld	[$bp+8],$t2
-+	ld	[$bp+12],$t3
-+	subcc	$t0,@acc[0],@acc[0]
-+	ld	[$bp+16],$t4
-+	ld	[$bp+20],$t5
-+	subccc	$t1,@acc[1],@acc[1]
-+	subccc	$t2,@acc[2],@acc[2]
-+	ld	[$bp+24],$t6
-+	ld	[$bp+28],$t7
-+	subccc	$t3,@acc[3],@acc[3]
-+	subccc	$t4,@acc[4],@acc[4]
-+	subccc	$t5,@acc[5],@acc[5]
-+	subccc	$t6,@acc[6],@acc[6]
-+	subccc	$t7,@acc[7],@acc[7]
-+	b	.Lreduce_by_add
-+	subc	%g0,%g0,$carry		! broadcast borrow bit
-+.type	__ecp_nistz256_sub_morf,#function
-+.size	__ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf
-+
-+! void	ecp_nistz256_div_by_2(BN_ULONG %i0[8],const BN_ULONG %i1[8]);
-+.globl	ecp_nistz256_div_by_2
-+.align	32
-+ecp_nistz256_div_by_2:
-+	save	%sp,-STACK_FRAME,%sp
-+	ld	[$ap],@acc[0]
-+	ld	[$ap+4],@acc[1]
-+	ld	[$ap+8],@acc[2]
-+	ld	[$ap+12],@acc[3]
-+	ld	[$ap+16],@acc[4]
-+	ld	[$ap+20],@acc[5]
-+	ld	[$ap+24],@acc[6]
-+	call	__ecp_nistz256_div_by_2
-+	ld	[$ap+28],@acc[7]
-+	ret
-+	restore
-+.type	ecp_nistz256_div_by_2,#function
-+.size	ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
-+
-+.align	32
-+__ecp_nistz256_div_by_2:
-+	! ret = (a is odd ? a+mod : a) >> 1
-+
-+	and	@acc[0],1,$bi
-+	neg	$bi,$carry
-+	addcc	@acc[0],$carry,@acc[0]
-+	addccc	@acc[1],$carry,@acc[1]
-+	addccc	@acc[2],$carry,@acc[2]
-+	addccc	@acc[3],0,@acc[3]
-+	addccc	@acc[4],0,@acc[4]
-+	addccc	@acc[5],0,@acc[5]
-+	addccc	@acc[6],$bi,@acc[6]
-+	addccc	@acc[7],$carry,@acc[7]
-+	addc	%g0,%g0,$carry
-+
-+	! ret >>= 1
-+
-+	srl	@acc[0],1,@acc[0]
-+	sll	@acc[1],31,$t0
-+	srl	@acc[1],1,@acc[1]
-+	or	@acc[0],$t0,@acc[0]
-+	sll	@acc[2],31,$t1
-+	srl	@acc[2],1,@acc[2]
-+	or	@acc[1],$t1,@acc[1]
-+	sll	@acc[3],31,$t2
-+	st	@acc[0],[$rp]
-+	srl	@acc[3],1,@acc[3]
-+	or	@acc[2],$t2,@acc[2]
-+	sll	@acc[4],31,$t3
-+	st	@acc[1],[$rp+4]
-+	srl	@acc[4],1,@acc[4]
-+	or	@acc[3],$t3,@acc[3]
-+	sll	@acc[5],31,$t4
-+	st	@acc[2],[$rp+8]
-+	srl	@acc[5],1,@acc[5]
-+	or	@acc[4],$t4,@acc[4]
-+	sll	@acc[6],31,$t5
-+	st	@acc[3],[$rp+12]
-+	srl	@acc[6],1,@acc[6]
-+	or	@acc[5],$t5,@acc[5]
-+	sll	@acc[7],31,$t6
-+	st	@acc[4],[$rp+16]
-+	srl	@acc[7],1,@acc[7]
-+	or	@acc[6],$t6,@acc[6]
-+	sll	$carry,31,$t7
-+	st	@acc[5],[$rp+20]
-+	or	@acc[7],$t7,@acc[7]
-+	st	@acc[6],[$rp+24]
-+	retl
-+	st	@acc[7],[$rp+28]
-+.type	__ecp_nistz256_div_by_2,#function
-+.size	__ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2
-+___
-+
-+########################################################################
-+# following subroutines are "literal" implementation of those found in
-+# ecp_nistz256.c
-+#
-+########################################################################
-+# void ecp_nistz256_point_double(P256_POINT *out,const P256_POINT *inp);
-+#
-+{
-+my ($S,$M,$Zsqr,$tmp0)=map(32*$_,(0..3));
-+# above map() describes stack layout with 4 temporary
-+# 256-bit vectors on top.
-+
-+$code.=<<___;
-+#ifdef __PIC__
-+SPARC_PIC_THUNK(%g1)
-+#endif
-+
-+.globl	ecp_nistz256_point_double
-+.align	32
-+ecp_nistz256_point_double:
-+	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+	ld	[%g1],%g1		! OPENSSL_sparcv9cap_P[0]
-+	and	%g1,(SPARCV9_VIS3|SPARCV9_64BIT_STACK),%g1
-+	cmp	%g1,(SPARCV9_VIS3|SPARCV9_64BIT_STACK)
-+	be	ecp_nistz256_point_double_vis3
-+	nop
-+
-+	save	%sp,-STACK_FRAME-32*4,%sp
-+
-+	mov	$rp,$rp_real
-+	mov	$ap,$ap_real
-+
-+.Lpoint_double_shortcut:
-+	ld	[$ap+32],@acc[0]
-+	ld	[$ap+32+4],@acc[1]
-+	ld	[$ap+32+8],@acc[2]
-+	ld	[$ap+32+12],@acc[3]
-+	ld	[$ap+32+16],@acc[4]
-+	ld	[$ap+32+20],@acc[5]
-+	ld	[$ap+32+24],@acc[6]
-+	ld	[$ap+32+28],@acc[7]
-+	call	__ecp_nistz256_mul_by_2	! p256_mul_by_2(S, in_y);
-+	add	%sp,LOCALS+$S,$rp
-+
-+	add	$ap_real,64,$bp
-+	add	$ap_real,64,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(Zsqr, in_z);
-+	add	%sp,LOCALS+$Zsqr,$rp
-+
-+	add	$ap_real,0,$bp
-+	call	__ecp_nistz256_add	! p256_add(M, Zsqr, in_x);
-+	add	%sp,LOCALS+$M,$rp
-+
-+	add	%sp,LOCALS+$S,$bp
-+	add	%sp,LOCALS+$S,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(S, S);
-+	add	%sp,LOCALS+$S,$rp
-+
-+	ld	[$ap_real],@acc[0]
-+	add	%sp,LOCALS+$Zsqr,$bp
-+	ld	[$ap_real+4],@acc[1]
-+	ld	[$ap_real+8],@acc[2]
-+	ld	[$ap_real+12],@acc[3]
-+	ld	[$ap_real+16],@acc[4]
-+	ld	[$ap_real+20],@acc[5]
-+	ld	[$ap_real+24],@acc[6]
-+	ld	[$ap_real+28],@acc[7]
-+	call	__ecp_nistz256_sub_from	! p256_sub(Zsqr, in_x, Zsqr);
-+	add	%sp,LOCALS+$Zsqr,$rp
-+
-+	add	$ap_real,32,$bp
-+	add	$ap_real,64,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(tmp0, in_z, in_y);
-+	add	%sp,LOCALS+$tmp0,$rp
-+
-+	call	__ecp_nistz256_mul_by_2	! p256_mul_by_2(res_z, tmp0);
-+	add	$rp_real,64,$rp
-+
-+	add	%sp,LOCALS+$Zsqr,$bp
-+	add	%sp,LOCALS+$M,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(M, M, Zsqr);
-+	add	%sp,LOCALS+$M,$rp
-+
-+	call	__ecp_nistz256_mul_by_3	! p256_mul_by_3(M, M);
-+	add	%sp,LOCALS+$M,$rp
-+
-+	add	%sp,LOCALS+$S,$bp
-+	add	%sp,LOCALS+$S,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(tmp0, S);
-+	add	%sp,LOCALS+$tmp0,$rp
-+
-+	call	__ecp_nistz256_div_by_2	! p256_div_by_2(res_y, tmp0);
-+	add	$rp_real,32,$rp
-+
-+	add	$ap_real,0,$bp
-+	add	%sp,LOCALS+$S,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(S, S, in_x);
-+	add	%sp,LOCALS+$S,$rp
-+
-+	call	__ecp_nistz256_mul_by_2	! p256_mul_by_2(tmp0, S);
-+	add	%sp,LOCALS+$tmp0,$rp
-+
-+	add	%sp,LOCALS+$M,$bp
-+	add	%sp,LOCALS+$M,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(res_x, M);
-+	add	$rp_real,0,$rp
-+
-+	add	%sp,LOCALS+$tmp0,$bp
-+	call	__ecp_nistz256_sub_from	! p256_sub(res_x, res_x, tmp0);
-+	add	$rp_real,0,$rp
-+
-+	add	%sp,LOCALS+$S,$bp
-+	call	__ecp_nistz256_sub_morf	! p256_sub(S, S, res_x);
-+	add	%sp,LOCALS+$S,$rp
-+
-+	add	%sp,LOCALS+$M,$bp
-+	add	%sp,LOCALS+$S,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(S, S, M);
-+	add	%sp,LOCALS+$S,$rp
-+
-+	add	$rp_real,32,$bp
-+	call	__ecp_nistz256_sub_from	! p256_sub(res_y, S, res_y);
-+	add	$rp_real,32,$rp
-+
-+	ret
-+	restore
-+.type	ecp_nistz256_point_double,#function
-+.size	ecp_nistz256_point_double,.-ecp_nistz256_point_double
-+___
-+}
-+
-+########################################################################
-+# void ecp_nistz256_point_add(P256_POINT *out,const P256_POINT *in1,
-+#			      const P256_POINT *in2);
-+{
-+my ($res_x,$res_y,$res_z,
-+    $H,$Hsqr,$R,$Rsqr,$Hcub,
-+    $U1,$U2,$S1,$S2)=map(32*$_,(0..11));
-+my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
-+
-+# above map() describes stack layout with 12 temporary
-+# 256-bit vectors on top. Then we reserve some space for
-+# !in1infty, !in2infty, result of check for zero and return pointer.
-+
-+my $bp_real=$rp_real;
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_add
-+.align	32
-+ecp_nistz256_point_add:
-+	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+	ld	[%g1],%g1		! OPENSSL_sparcv9cap_P[0]
-+	and	%g1,(SPARCV9_VIS3|SPARCV9_64BIT_STACK),%g1
-+	cmp	%g1,(SPARCV9_VIS3|SPARCV9_64BIT_STACK)
-+	be	ecp_nistz256_point_add_vis3
-+	nop
-+
-+	save	%sp,-STACK_FRAME-32*12-32,%sp
-+
-+	stx	$rp,[%fp+STACK_BIAS-8]	! off-load $rp
-+	mov	$ap,$ap_real
-+	mov	$bp,$bp_real
-+
-+	ld	[$bp+64],$t0		! in2_z
-+	ld	[$bp+64+4],$t1
-+	ld	[$bp+64+8],$t2
-+	ld	[$bp+64+12],$t3
-+	ld	[$bp+64+16],$t4
-+	ld	[$bp+64+20],$t5
-+	ld	[$bp+64+24],$t6
-+	ld	[$bp+64+28],$t7
-+	or	$t1,$t0,$t0
-+	or	$t3,$t2,$t2
-+	or	$t5,$t4,$t4
-+	or	$t7,$t6,$t6
-+	or	$t2,$t0,$t0
-+	or	$t6,$t4,$t4
-+	or	$t4,$t0,$t0		! !in2infty
-+	movrnz	$t0,-1,$t0
-+	st	$t0,[%fp+STACK_BIAS-12]
-+
-+	ld	[$ap+64],$t0		! in1_z
-+	ld	[$ap+64+4],$t1
-+	ld	[$ap+64+8],$t2
-+	ld	[$ap+64+12],$t3
-+	ld	[$ap+64+16],$t4
-+	ld	[$ap+64+20],$t5
-+	ld	[$ap+64+24],$t6
-+	ld	[$ap+64+28],$t7
-+	or	$t1,$t0,$t0
-+	or	$t3,$t2,$t2
-+	or	$t5,$t4,$t4
-+	or	$t7,$t6,$t6
-+	or	$t2,$t0,$t0
-+	or	$t6,$t4,$t4
-+	or	$t4,$t0,$t0		! !in1infty
-+	movrnz	$t0,-1,$t0
-+	st	$t0,[%fp+STACK_BIAS-16]
-+
-+	add	$bp_real,64,$bp
-+	add	$bp_real,64,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(Z2sqr, in2_z);
-+	add	%sp,LOCALS+$Z2sqr,$rp
-+
-+	add	$ap_real,64,$bp
-+	add	$ap_real,64,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(Z1sqr, in1_z);
-+	add	%sp,LOCALS+$Z1sqr,$rp
-+
-+	add	$bp_real,64,$bp
-+	add	%sp,LOCALS+$Z2sqr,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(S1, Z2sqr, in2_z);
-+	add	%sp,LOCALS+$S1,$rp
-+
-+	add	$ap_real,64,$bp
-+	add	%sp,LOCALS+$Z1sqr,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(S2, Z1sqr, in1_z);
-+	add	%sp,LOCALS+$S2,$rp
-+
-+	add	$ap_real,32,$bp
-+	add	%sp,LOCALS+$S1,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(S1, S1, in1_y);
-+	add	%sp,LOCALS+$S1,$rp
-+
-+	add	$bp_real,32,$bp
-+	add	%sp,LOCALS+$S2,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(S2, S2, in2_y);
-+	add	%sp,LOCALS+$S2,$rp
-+
-+	add	%sp,LOCALS+$S1,$bp
-+	call	__ecp_nistz256_sub_from	! p256_sub(R, S2, S1);
-+	add	%sp,LOCALS+$R,$rp
-+
-+	or	@acc[1],@acc[0],@acc[0]	! see if result is zero
-+	or	@acc[3],@acc[2],@acc[2]
-+	or	@acc[5],@acc[4],@acc[4]
-+	or	@acc[7],@acc[6],@acc[6]
-+	or	@acc[2],@acc[0],@acc[0]
-+	or	@acc[6],@acc[4],@acc[4]
-+	or	@acc[4],@acc[0],@acc[0]
-+	st	@acc[0],[%fp+STACK_BIAS-20]
-+
-+	add	$ap_real,0,$bp
-+	add	%sp,LOCALS+$Z2sqr,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(U1, in1_x, Z2sqr);
-+	add	%sp,LOCALS+$U1,$rp
-+
-+	add	$bp_real,0,$bp
-+	add	%sp,LOCALS+$Z1sqr,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(U2, in2_x, Z1sqr);
-+	add	%sp,LOCALS+$U2,$rp
-+
-+	add	%sp,LOCALS+$U1,$bp
-+	call	__ecp_nistz256_sub_from	! p256_sub(H, U2, U1);
-+	add	%sp,LOCALS+$H,$rp
-+
-+	or	@acc[1],@acc[0],@acc[0]	! see if result is zero
-+	or	@acc[3],@acc[2],@acc[2]
-+	or	@acc[5],@acc[4],@acc[4]
-+	or	@acc[7],@acc[6],@acc[6]
-+	or	@acc[2],@acc[0],@acc[0]
-+	or	@acc[6],@acc[4],@acc[4]
-+	orcc	@acc[4],@acc[0],@acc[0]
-+
-+	bne,pt	%icc,.Ladd_proceed	! is_equal(U1,U2)?
-+	nop
-+
-+	ld	[%fp+STACK_BIAS-12],$t0
-+	ld	[%fp+STACK_BIAS-16],$t1
-+	ld	[%fp+STACK_BIAS-20],$t2
-+	andcc	$t0,$t1,%g0
-+	be,pt	%icc,.Ladd_proceed	! (in1infty || in2infty)?
-+	nop
-+	andcc	$t2,$t2,%g0
-+	be,pt	%icc,.Ladd_double	! is_equal(S1,S2)?
-+	nop
-+
-+	ldx	[%fp+STACK_BIAS-8],$rp
-+	st	%g0,[$rp]
-+	st	%g0,[$rp+4]
-+	st	%g0,[$rp+8]
-+	st	%g0,[$rp+12]
-+	st	%g0,[$rp+16]
-+	st	%g0,[$rp+20]
-+	st	%g0,[$rp+24]
-+	st	%g0,[$rp+28]
-+	st	%g0,[$rp+32]
-+	st	%g0,[$rp+32+4]
-+	st	%g0,[$rp+32+8]
-+	st	%g0,[$rp+32+12]
-+	st	%g0,[$rp+32+16]
-+	st	%g0,[$rp+32+20]
-+	st	%g0,[$rp+32+24]
-+	st	%g0,[$rp+32+28]
-+	st	%g0,[$rp+64]
-+	st	%g0,[$rp+64+4]
-+	st	%g0,[$rp+64+8]
-+	st	%g0,[$rp+64+12]
-+	st	%g0,[$rp+64+16]
-+	st	%g0,[$rp+64+20]
-+	st	%g0,[$rp+64+24]
-+	st	%g0,[$rp+64+28]
-+	b	.Ladd_done
-+	nop
-+
-+.align	16
-+.Ladd_double:
-+	ldx	[%fp+STACK_BIAS-8],$rp_real
-+	mov	$ap_real,$ap
-+	b	.Lpoint_double_shortcut
-+	add	%sp,32*(12-4)+32,%sp	! difference in frame sizes
-+
-+.align	16
-+.Ladd_proceed:
-+	add	%sp,LOCALS+$R,$bp
-+	add	%sp,LOCALS+$R,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(Rsqr, R);
-+	add	%sp,LOCALS+$Rsqr,$rp
-+
-+	add	$ap_real,64,$bp
-+	add	%sp,LOCALS+$H,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(res_z, H, in1_z);
-+	add	%sp,LOCALS+$res_z,$rp
-+
-+	add	%sp,LOCALS+$H,$bp
-+	add	%sp,LOCALS+$H,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(Hsqr, H);
-+	add	%sp,LOCALS+$Hsqr,$rp
-+
-+	add	$bp_real,64,$bp
-+	add	%sp,LOCALS+$res_z,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(res_z, res_z, in2_z);
-+	add	%sp,LOCALS+$res_z,$rp
-+
-+	add	%sp,LOCALS+$H,$bp
-+	add	%sp,LOCALS+$Hsqr,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(Hcub, Hsqr, H);
-+	add	%sp,LOCALS+$Hcub,$rp
-+
-+	add	%sp,LOCALS+$U1,$bp
-+	add	%sp,LOCALS+$Hsqr,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(U2, U1, Hsqr);
-+	add	%sp,LOCALS+$U2,$rp
-+
-+	call	__ecp_nistz256_mul_by_2	! p256_mul_by_2(Hsqr, U2);
-+	add	%sp,LOCALS+$Hsqr,$rp
-+
-+	add	%sp,LOCALS+$Rsqr,$bp
-+	call	__ecp_nistz256_sub_morf	! p256_sub(res_x, Rsqr, Hsqr);
-+	add	%sp,LOCALS+$res_x,$rp
-+
-+	add	%sp,LOCALS+$Hcub,$bp
-+	call	__ecp_nistz256_sub_from	!  p256_sub(res_x, res_x, Hcub);
-+	add	%sp,LOCALS+$res_x,$rp
-+
-+	add	%sp,LOCALS+$U2,$bp
-+	call	__ecp_nistz256_sub_morf	! p256_sub(res_y, U2, res_x);
-+	add	%sp,LOCALS+$res_y,$rp
-+
-+	add	%sp,LOCALS+$Hcub,$bp
-+	add	%sp,LOCALS+$S1,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(S2, S1, Hcub);
-+	add	%sp,LOCALS+$S2,$rp
-+
-+	add	%sp,LOCALS+$R,$bp
-+	add	%sp,LOCALS+$res_y,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(res_y, res_y, R);
-+	add	%sp,LOCALS+$res_y,$rp
-+
-+	add	%sp,LOCALS+$S2,$bp
-+	call	__ecp_nistz256_sub_from	! p256_sub(res_y, res_y, S2);
-+	add	%sp,LOCALS+$res_y,$rp
-+
-+	ld	[%fp+STACK_BIAS-16],$t1	! !in1infty
-+	ld	[%fp+STACK_BIAS-12],$t2	! !in2infty
-+	ldx	[%fp+STACK_BIAS-8],$rp
-+___
-+for($i=0;$i<96;$i+=8) {			# conditional moves
-+$code.=<<___;
-+	ld	[%sp+LOCALS+$i],@acc[0]		! res
-+	ld	[%sp+LOCALS+$i+4],@acc[1]
-+	ld	[$bp_real+$i],@acc[2]		! in2
-+	ld	[$bp_real+$i+4],@acc[3]
-+	ld	[$ap_real+$i],@acc[4]		! in1
-+	ld	[$ap_real+$i+4],@acc[5]
-+	movrz	$t1,@acc[2],@acc[0]
-+	movrz	$t1,@acc[3],@acc[1]
-+	movrz	$t2,@acc[4],@acc[0]
-+	movrz	$t2,@acc[5],@acc[1]
-+	st	@acc[0],[$rp+$i]
-+	st	@acc[1],[$rp+$i+4]
-+___
-+}
-+$code.=<<___;
-+.Ladd_done:
-+	ret
-+	restore
-+.type	ecp_nistz256_point_add,#function
-+.size	ecp_nistz256_point_add,.-ecp_nistz256_point_add
-+___
-+}
-+
-+########################################################################
-+# void ecp_nistz256_point_add_affine(P256_POINT *out,const P256_POINT *in1,
-+#				     const P256_POINT_AFFINE *in2);
-+{
-+my ($res_x,$res_y,$res_z,
-+    $U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr)=map(32*$_,(0..9));
-+my $Z1sqr = $S2;
-+# above map() describes stack layout with 10 temporary
-+# 256-bit vectors on top. Then we reserve some space for
-+# !in1infty, !in2infty, result of check for zero and return pointer.
-+
-+my @ONE_mont=(1,0,0,-1,-1,-1,-2,0);
-+my $bp_real=$rp_real;
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_add_affine
-+.align	32
-+ecp_nistz256_point_add_affine:
-+	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+	ld	[%g1],%g1		! OPENSSL_sparcv9cap_P[0]
-+	and	%g1,(SPARCV9_VIS3|SPARCV9_64BIT_STACK),%g1
-+	cmp	%g1,(SPARCV9_VIS3|SPARCV9_64BIT_STACK)
-+	be	ecp_nistz256_point_add_affine_vis3
-+	nop
-+
-+	save	%sp,-STACK_FRAME-32*10-32,%sp
-+
-+	stx	$rp,[%fp+STACK_BIAS-8]	! off-load $rp
-+	mov	$ap,$ap_real
-+	mov	$bp,$bp_real
-+
-+	ld	[$ap+64],$t0		! in1_z
-+	ld	[$ap+64+4],$t1
-+	ld	[$ap+64+8],$t2
-+	ld	[$ap+64+12],$t3
-+	ld	[$ap+64+16],$t4
-+	ld	[$ap+64+20],$t5
-+	ld	[$ap+64+24],$t6
-+	ld	[$ap+64+28],$t7
-+	or	$t1,$t0,$t0
-+	or	$t3,$t2,$t2
-+	or	$t5,$t4,$t4
-+	or	$t7,$t6,$t6
-+	or	$t2,$t0,$t0
-+	or	$t6,$t4,$t4
-+	or	$t4,$t0,$t0		! !in1infty
-+	movrnz	$t0,-1,$t0
-+	st	$t0,[%fp+STACK_BIAS-16]
-+
-+	ld	[$bp],@acc[0]		! in2_x
-+	ld	[$bp+4],@acc[1]
-+	ld	[$bp+8],@acc[2]
-+	ld	[$bp+12],@acc[3]
-+	ld	[$bp+16],@acc[4]
-+	ld	[$bp+20],@acc[5]
-+	ld	[$bp+24],@acc[6]
-+	ld	[$bp+28],@acc[7]
-+	ld	[$bp+32],$t0		! in2_y
-+	ld	[$bp+32+4],$t1
-+	ld	[$bp+32+8],$t2
-+	ld	[$bp+32+12],$t3
-+	ld	[$bp+32+16],$t4
-+	ld	[$bp+32+20],$t5
-+	ld	[$bp+32+24],$t6
-+	ld	[$bp+32+28],$t7
-+	or	@acc[1],@acc[0],@acc[0]
-+	or	@acc[3],@acc[2],@acc[2]
-+	or	@acc[5],@acc[4],@acc[4]
-+	or	@acc[7],@acc[6],@acc[6]
-+	or	@acc[2],@acc[0],@acc[0]
-+	or	@acc[6],@acc[4],@acc[4]
-+	or	@acc[4],@acc[0],@acc[0]
-+	or	$t1,$t0,$t0
-+	or	$t3,$t2,$t2
-+	or	$t5,$t4,$t4
-+	or	$t7,$t6,$t6
-+	or	$t2,$t0,$t0
-+	or	$t6,$t4,$t4
-+	or	$t4,$t0,$t0
-+	or	@acc[0],$t0,$t0		! !in2infty
-+	movrnz	$t0,-1,$t0
-+	st	$t0,[%fp+STACK_BIAS-12]
-+
-+	add	$ap_real,64,$bp
-+	add	$ap_real,64,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(Z1sqr, in1_z);
-+	add	%sp,LOCALS+$Z1sqr,$rp
-+
-+	add	$bp_real,0,$bp
-+	add	%sp,LOCALS+$Z1sqr,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(U2, Z1sqr, in2_x);
-+	add	%sp,LOCALS+$U2,$rp
-+
-+	add	$ap_real,0,$bp
-+	call	__ecp_nistz256_sub_from	! p256_sub(H, U2, in1_x);
-+	add	%sp,LOCALS+$H,$rp
-+
-+	add	$ap_real,64,$bp
-+	add	%sp,LOCALS+$Z1sqr,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(S2, Z1sqr, in1_z);
-+	add	%sp,LOCALS+$S2,$rp
-+
-+	add	$ap_real,64,$bp
-+	add	%sp,LOCALS+$H,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(res_z, H, in1_z);
-+	add	%sp,LOCALS+$res_z,$rp
-+
-+	add	$bp_real,32,$bp
-+	add	%sp,LOCALS+$S2,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(S2, S2, in2_y);
-+	add	%sp,LOCALS+$S2,$rp
-+
-+	add	$ap_real,32,$bp
-+	call	__ecp_nistz256_sub_from	! p256_sub(R, S2, in1_y);
-+	add	%sp,LOCALS+$R,$rp
-+
-+	add	%sp,LOCALS+$H,$bp
-+	add	%sp,LOCALS+$H,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(Hsqr, H);
-+	add	%sp,LOCALS+$Hsqr,$rp
-+
-+	add	%sp,LOCALS+$R,$bp
-+	add	%sp,LOCALS+$R,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_sqr_mont(Rsqr, R);
-+	add	%sp,LOCALS+$Rsqr,$rp
-+
-+	add	%sp,LOCALS+$H,$bp
-+	add	%sp,LOCALS+$Hsqr,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(Hcub, Hsqr, H);
-+	add	%sp,LOCALS+$Hcub,$rp
-+
-+	add	$ap_real,0,$bp
-+	add	%sp,LOCALS+$Hsqr,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(U2, in1_x, Hsqr);
-+	add	%sp,LOCALS+$U2,$rp
-+
-+	call	__ecp_nistz256_mul_by_2	! p256_mul_by_2(Hsqr, U2);
-+	add	%sp,LOCALS+$Hsqr,$rp
-+
-+	add	%sp,LOCALS+$Rsqr,$bp
-+	call	__ecp_nistz256_sub_morf	! p256_sub(res_x, Rsqr, Hsqr);
-+	add	%sp,LOCALS+$res_x,$rp
-+
-+	add	%sp,LOCALS+$Hcub,$bp
-+	call	__ecp_nistz256_sub_from	!  p256_sub(res_x, res_x, Hcub);
-+	add	%sp,LOCALS+$res_x,$rp
-+
-+	add	%sp,LOCALS+$U2,$bp
-+	call	__ecp_nistz256_sub_morf	! p256_sub(res_y, U2, res_x);
-+	add	%sp,LOCALS+$res_y,$rp
-+
-+	add	$ap_real,32,$bp
-+	add	%sp,LOCALS+$Hcub,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(S2, in1_y, Hcub);
-+	add	%sp,LOCALS+$S2,$rp
-+
-+	add	%sp,LOCALS+$R,$bp
-+	add	%sp,LOCALS+$res_y,$ap
-+	call	__ecp_nistz256_mul_mont	! p256_mul_mont(res_y, res_y, R);
-+	add	%sp,LOCALS+$res_y,$rp
-+
-+	add	%sp,LOCALS+$S2,$bp
-+	call	__ecp_nistz256_sub_from	! p256_sub(res_y, res_y, S2);
-+	add	%sp,LOCALS+$res_y,$rp
-+
-+	ld	[%fp+STACK_BIAS-16],$t1	! !in1infty
-+	ld	[%fp+STACK_BIAS-12],$t2	! !in2infty
-+	ldx	[%fp+STACK_BIAS-8],$rp
-+___
-+for($i=0;$i<64;$i+=8) {			# conditional moves
-+$code.=<<___;
-+	ld	[%sp+LOCALS+$i],@acc[0]		! res
-+	ld	[%sp+LOCALS+$i+4],@acc[1]
-+	ld	[$bp_real+$i],@acc[2]		! in2
-+	ld	[$bp_real+$i+4],@acc[3]
-+	ld	[$ap_real+$i],@acc[4]		! in1
-+	ld	[$ap_real+$i+4],@acc[5]
-+	movrz	$t1,@acc[2],@acc[0]
-+	movrz	$t1,@acc[3],@acc[1]
-+	movrz	$t2,@acc[4],@acc[0]
-+	movrz	$t2,@acc[5],@acc[1]
-+	st	@acc[0],[$rp+$i]
-+	st	@acc[1],[$rp+$i+4]
-+___
-+}
-+for(;$i<96;$i+=8) {
-+my $j=($i-64)/4;
-+$code.=<<___;
-+	ld	[%sp+LOCALS+$i],@acc[0]		! res
-+	ld	[%sp+LOCALS+$i+4],@acc[1]
-+	ld	[$ap_real+$i],@acc[4]		! in1
-+	ld	[$ap_real+$i+4],@acc[5]
-+	movrz	$t1,@ONE_mont[$j],@acc[0]
-+	movrz	$t1,@ONE_mont[$j+1],@acc[1]
-+	movrz	$t2,@acc[4],@acc[0]
-+	movrz	$t2,@acc[5],@acc[1]
-+	st	@acc[0],[$rp+$i]
-+	st	@acc[1],[$rp+$i+4]
-+___
-+}
-+$code.=<<___;
-+	ret
-+	restore
-+.type	ecp_nistz256_point_add_affine,#function
-+.size	ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
-+___
-+}								}}}
-+{{{
-+my ($out,$inp,$index)=map("%i$_",(0..2));
-+my $mask="%o0";
-+
-+$code.=<<___;
-+! void	ecp_nistz256_scatter_w5(void *%i0,const P256_POINT *%i1,
-+!					  int %i2);
-+.globl	ecp_nistz256_scatter_w5
-+.align	32
-+ecp_nistz256_scatter_w5:
-+	save	%sp,-STACK_FRAME,%sp
-+
-+	sll	$index,2,$index
-+	add	$out,$index,$out
-+
-+	ld	[$inp],%l0		! X
-+	ld	[$inp+4],%l1
-+	ld	[$inp+8],%l2
-+	ld	[$inp+12],%l3
-+	ld	[$inp+16],%l4
-+	ld	[$inp+20],%l5
-+	ld	[$inp+24],%l6
-+	ld	[$inp+28],%l7
-+	add	$inp,32,$inp
-+	st	%l0,[$out+64*0-4]
-+	st	%l1,[$out+64*1-4]
-+	st	%l2,[$out+64*2-4]
-+	st	%l3,[$out+64*3-4]
-+	st	%l4,[$out+64*4-4]
-+	st	%l5,[$out+64*5-4]
-+	st	%l6,[$out+64*6-4]
-+	st	%l7,[$out+64*7-4]
-+	add	$out,64*8,$out
-+
-+	ld	[$inp],%l0		! Y
-+	ld	[$inp+4],%l1
-+	ld	[$inp+8],%l2
-+	ld	[$inp+12],%l3
-+	ld	[$inp+16],%l4
-+	ld	[$inp+20],%l5
-+	ld	[$inp+24],%l6
-+	ld	[$inp+28],%l7
-+	add	$inp,32,$inp
-+	st	%l0,[$out+64*0-4]
-+	st	%l1,[$out+64*1-4]
-+	st	%l2,[$out+64*2-4]
-+	st	%l3,[$out+64*3-4]
-+	st	%l4,[$out+64*4-4]
-+	st	%l5,[$out+64*5-4]
-+	st	%l6,[$out+64*6-4]
-+	st	%l7,[$out+64*7-4]
-+	add	$out,64*8,$out
-+
-+	ld	[$inp],%l0		! Z
-+	ld	[$inp+4],%l1
-+	ld	[$inp+8],%l2
-+	ld	[$inp+12],%l3
-+	ld	[$inp+16],%l4
-+	ld	[$inp+20],%l5
-+	ld	[$inp+24],%l6
-+	ld	[$inp+28],%l7
-+	st	%l0,[$out+64*0-4]
-+	st	%l1,[$out+64*1-4]
-+	st	%l2,[$out+64*2-4]
-+	st	%l3,[$out+64*3-4]
-+	st	%l4,[$out+64*4-4]
-+	st	%l5,[$out+64*5-4]
-+	st	%l6,[$out+64*6-4]
-+	st	%l7,[$out+64*7-4]
-+
-+	ret
-+	restore
-+.type	ecp_nistz256_scatter_w5,#function
-+.size	ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5
-+
-+! void	ecp_nistz256_gather_w5(P256_POINT *%i0,const void *%i1,
-+!					       int %i2);
-+.globl	ecp_nistz256_gather_w5
-+.align	32
-+ecp_nistz256_gather_w5:
-+	save	%sp,-STACK_FRAME,%sp
-+
-+	neg	$index,$mask
-+	srax	$mask,63,$mask
-+
-+	add	$index,$mask,$index
-+	sll	$index,2,$index
-+	add	$inp,$index,$inp
-+
-+	ld	[$inp+64*0],%l0
-+	ld	[$inp+64*1],%l1
-+	ld	[$inp+64*2],%l2
-+	ld	[$inp+64*3],%l3
-+	ld	[$inp+64*4],%l4
-+	ld	[$inp+64*5],%l5
-+	ld	[$inp+64*6],%l6
-+	ld	[$inp+64*7],%l7
-+	add	$inp,64*8,$inp
-+	and	%l0,$mask,%l0
-+	and	%l1,$mask,%l1
-+	st	%l0,[$out]		! X
-+	and	%l2,$mask,%l2
-+	st	%l1,[$out+4]
-+	and	%l3,$mask,%l3
-+	st	%l2,[$out+8]
-+	and	%l4,$mask,%l4
-+	st	%l3,[$out+12]
-+	and	%l5,$mask,%l5
-+	st	%l4,[$out+16]
-+	and	%l6,$mask,%l6
-+	st	%l5,[$out+20]
-+	and	%l7,$mask,%l7
-+	st	%l6,[$out+24]
-+	st	%l7,[$out+28]
-+	add	$out,32,$out
-+
-+	ld	[$inp+64*0],%l0
-+	ld	[$inp+64*1],%l1
-+	ld	[$inp+64*2],%l2
-+	ld	[$inp+64*3],%l3
-+	ld	[$inp+64*4],%l4
-+	ld	[$inp+64*5],%l5
-+	ld	[$inp+64*6],%l6
-+	ld	[$inp+64*7],%l7
-+	add	$inp,64*8,$inp
-+	and	%l0,$mask,%l0
-+	and	%l1,$mask,%l1
-+	st	%l0,[$out]		! Y
-+	and	%l2,$mask,%l2
-+	st	%l1,[$out+4]
-+	and	%l3,$mask,%l3
-+	st	%l2,[$out+8]
-+	and	%l4,$mask,%l4
-+	st	%l3,[$out+12]
-+	and	%l5,$mask,%l5
-+	st	%l4,[$out+16]
-+	and	%l6,$mask,%l6
-+	st	%l5,[$out+20]
-+	and	%l7,$mask,%l7
-+	st	%l6,[$out+24]
-+	st	%l7,[$out+28]
-+	add	$out,32,$out
-+
-+	ld	[$inp+64*0],%l0
-+	ld	[$inp+64*1],%l1
-+	ld	[$inp+64*2],%l2
-+	ld	[$inp+64*3],%l3
-+	ld	[$inp+64*4],%l4
-+	ld	[$inp+64*5],%l5
-+	ld	[$inp+64*6],%l6
-+	ld	[$inp+64*7],%l7
-+	and	%l0,$mask,%l0
-+	and	%l1,$mask,%l1
-+	st	%l0,[$out]		! Z
-+	and	%l2,$mask,%l2
-+	st	%l1,[$out+4]
-+	and	%l3,$mask,%l3
-+	st	%l2,[$out+8]
-+	and	%l4,$mask,%l4
-+	st	%l3,[$out+12]
-+	and	%l5,$mask,%l5
-+	st	%l4,[$out+16]
-+	and	%l6,$mask,%l6
-+	st	%l5,[$out+20]
-+	and	%l7,$mask,%l7
-+	st	%l6,[$out+24]
-+	st	%l7,[$out+28]
-+
-+	ret
-+	restore
-+.type	ecp_nistz256_gather_w5,#function
-+.size	ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5
-+
-+! void	ecp_nistz256_scatter_w7(void *%i0,const P256_POINT_AFFINE *%i1,
-+!					  int %i2);
-+.globl	ecp_nistz256_scatter_w7
-+.align	32
-+ecp_nistz256_scatter_w7:
-+	save	%sp,-STACK_FRAME,%sp
-+	nop
-+	add	$out,$index,$out
-+	mov	64/4,$index
-+.Loop_scatter_w7:
-+	ld	[$inp],%l0
-+	add	$inp,4,$inp
-+	subcc	$index,1,$index
-+	stb	%l0,[$out+64*0-1]
-+	srl	%l0,8,%l1
-+	stb	%l1,[$out+64*1-1]
-+	srl	%l0,16,%l2
-+	stb	%l2,[$out+64*2-1]
-+	srl	%l0,24,%l3
-+	stb	%l3,[$out+64*3-1]
-+	bne	.Loop_scatter_w7
-+	add	$out,64*4,$out
-+
-+	ret
-+	restore
-+.type	ecp_nistz256_scatter_w7,#function
-+.size	ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7
-+
-+! void	ecp_nistz256_gather_w7(P256_POINT_AFFINE *%i0,const void *%i1,
-+!						      int %i2);
-+.globl	ecp_nistz256_gather_w7
-+.align	32
-+ecp_nistz256_gather_w7:
-+	save	%sp,-STACK_FRAME,%sp
-+
-+	neg	$index,$mask
-+	srax	$mask,63,$mask
-+
-+	add	$index,$mask,$index
-+	add	$inp,$index,$inp
-+	mov	64/4,$index
-+
-+.Loop_gather_w7:
-+	ldub	[$inp+64*0],%l0
-+	prefetch [$inp+3840+64*0],1
-+	subcc	$index,1,$index
-+	ldub	[$inp+64*1],%l1
-+	prefetch [$inp+3840+64*1],1
-+	ldub	[$inp+64*2],%l2
-+	prefetch [$inp+3840+64*2],1
-+	ldub	[$inp+64*3],%l3
-+	prefetch [$inp+3840+64*3],1
-+	add	$inp,64*4,$inp
-+	sll	%l1,8,%l1
-+	sll	%l2,16,%l2
-+	or	%l0,%l1,%l0
-+	sll	%l3,24,%l3
-+	or	%l0,%l2,%l0
-+	or	%l0,%l3,%l0
-+	and	%l0,$mask,%l0
-+	st	%l0,[$out]
-+	bne	.Loop_gather_w7
-+	add	$out,4,$out
-+
-+	ret
-+	restore
-+.type	ecp_nistz256_gather_w7,#function
-+.size	ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7
-+___
-+}}}
-+{{{
-+########################################################################
-+# Following subroutines are VIS3 counterparts of those above that
-+# implement ones found in ecp_nistz256.c. Key difference is that they
-+# use 128-bit muliplication and addition with 64-bit carry, and in order
-+# to do that they perform conversion from uin32_t[8] to uint64_t[4] upon
-+# entry and vice versa on return.
-+#
-+my ($rp,$ap,$bp)=map("%i$_",(0..2));
-+my ($t0,$t1,$t2,$t3,$a0,$a1,$a2,$a3)=map("%l$_",(0..7));
-+my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5)=map("%o$_",(0..5));
-+my ($bi,$poly1,$poly3,$minus1)=(map("%i$_",(3..5)),"%g1");
-+my ($rp_real,$ap_real)=("%g2","%g3");
-+my ($acc6,$acc7)=($bp,$bi);	# used in squaring
-+
-+$code.=<<___;
-+.align	32
-+__ecp_nistz256_mul_by_2_vis3:
-+	addcc	$acc0,$acc0,$acc0
-+	addxccc	$acc1,$acc1,$acc1
-+	addxccc	$acc2,$acc2,$acc2
-+	addxccc	$acc3,$acc3,$acc3
-+	b	.Lreduce_by_sub_vis3
-+	addxc	%g0,%g0,$acc4		! did it carry?
-+.type	__ecp_nistz256_mul_by_2_vis3,#function
-+.size	__ecp_nistz256_mul_by_2_vis3,.-__ecp_nistz256_mul_by_2_vis3
-+
-+.align	32
-+__ecp_nistz256_add_vis3:
-+	ldx	[$bp+0],$t0
-+	ldx	[$bp+8],$t1
-+	ldx	[$bp+16],$t2
-+	ldx	[$bp+24],$t3
-+
-+__ecp_nistz256_add_noload_vis3:
-+
-+	addcc	$t0,$acc0,$acc0
-+	addxccc	$t1,$acc1,$acc1
-+	addxccc	$t2,$acc2,$acc2
-+	addxccc	$t3,$acc3,$acc3
-+	addxc	%g0,%g0,$acc4		! did it carry?
-+
-+.Lreduce_by_sub_vis3:
-+
-+	addcc	$acc0,1,$t0		! add -modulus, i.e. subtract
-+	addxccc	$acc1,$poly1,$t1
-+	addxccc	$acc2,$minus1,$t2
-+	addxccc	$acc3,$poly3,$t3
-+	addxc	$acc4,$minus1,$acc4
-+
-+	movrz	$acc4,$t0,$acc0		! ret = borrow ? ret : ret-modulus
-+	movrz	$acc4,$t1,$acc1
-+	stx	$acc0,[$rp]
-+	movrz	$acc4,$t2,$acc2
-+	stx	$acc1,[$rp+8]
-+	movrz	$acc4,$t3,$acc3
-+	stx	$acc2,[$rp+16]
-+	retl
-+	stx	$acc3,[$rp+24]
-+.type	__ecp_nistz256_add_vis3,#function
-+.size	__ecp_nistz256_add_vis3,.-__ecp_nistz256_add_vis3
-+
-+! Trouble with subtraction is that there is no subtraction with 64-bit
-+! borrow, only with 32-bit one. For this reason we "decompose" 64-bit
-+! $acc0-$acc3 to 32-bit values and pick b[4] in 32-bit pieces. But
-+! recall that SPARC is big-endian, which is why you'll observe that
-+! b[4] is accessed as 4-0-12-8-20-16-28-24. And prior reduction we
-+! "collect" result back to 64-bit $acc0-$acc3.
-+.align	32
-+__ecp_nistz256_sub_from_vis3:
-+	ld	[$bp+4],$t0
-+	ld	[$bp+0],$t1
-+	ld	[$bp+12],$t2
-+	ld	[$bp+8],$t3
-+
-+	srlx	$acc0,32,$acc4
-+	not	$poly1,$poly1
-+	srlx	$acc1,32,$acc5
-+	subcc	$acc0,$t0,$acc0
-+	ld	[$bp+20],$t0
-+	subccc	$acc4,$t1,$acc4
-+	ld	[$bp+16],$t1
-+	subccc	$acc1,$t2,$acc1
-+	ld	[$bp+28],$t2
-+	and	$acc0,$poly1,$acc0
-+	subccc	$acc5,$t3,$acc5
-+	ld	[$bp+24],$t3
-+	sllx	$acc4,32,$acc4
-+	and	$acc1,$poly1,$acc1
-+	sllx	$acc5,32,$acc5
-+	or	$acc0,$acc4,$acc0
-+	srlx	$acc2,32,$acc4
-+	or	$acc1,$acc5,$acc1
-+	srlx	$acc3,32,$acc5
-+	subccc	$acc2,$t0,$acc2
-+	subccc	$acc4,$t1,$acc4
-+	subccc	$acc3,$t2,$acc3
-+	and	$acc2,$poly1,$acc2
-+	subccc	$acc5,$t3,$acc5
-+	sllx	$acc4,32,$acc4
-+	and	$acc3,$poly1,$acc3
-+	sllx	$acc5,32,$acc5
-+	or	$acc2,$acc4,$acc2
-+	subc	%g0,%g0,$acc4		! did it borrow?
-+	b	.Lreduce_by_add_vis3
-+	or	$acc3,$acc5,$acc3
-+.type	__ecp_nistz256_sub_from_vis3,#function
-+.size	__ecp_nistz256_sub_from_vis3,.-__ecp_nistz256_sub_from_vis3
-+
-+.align	32
-+__ecp_nistz256_sub_morf_vis3:
-+	ld	[$bp+4],$t0
-+	ld	[$bp+0],$t1
-+	ld	[$bp+12],$t2
-+	ld	[$bp+8],$t3
-+
-+	srlx	$acc0,32,$acc4
-+	not	$poly1,$poly1
-+	srlx	$acc1,32,$acc5
-+	subcc	$t0,$acc0,$acc0
-+	ld	[$bp+20],$t0
-+	subccc	$t1,$acc4,$acc4
-+	ld	[$bp+16],$t1
-+	subccc	$t2,$acc1,$acc1
-+	ld	[$bp+28],$t2
-+	and	$acc0,$poly1,$acc0
-+	subccc	$t3,$acc5,$acc5
-+	ld	[$bp+24],$t3
-+	sllx	$acc4,32,$acc4
-+	and	$acc1,$poly1,$acc1
-+	sllx	$acc5,32,$acc5
-+	or	$acc0,$acc4,$acc0
-+	srlx	$acc2,32,$acc4
-+	or	$acc1,$acc5,$acc1
-+	srlx	$acc3,32,$acc5
-+	subccc	$t0,$acc2,$acc2
-+	subccc	$t1,$acc4,$acc4
-+	subccc	$t2,$acc3,$acc3
-+	and	$acc2,$poly1,$acc2
-+	subccc	$t3,$acc5,$acc5
-+	sllx	$acc4,32,$acc4
-+	and	$acc3,$poly1,$acc3
-+	sllx	$acc5,32,$acc5
-+	or	$acc2,$acc4,$acc2
-+	subc	%g0,%g0,$acc4		! did it borrow?
-+	or	$acc3,$acc5,$acc3
-+
-+.Lreduce_by_add_vis3:
-+
-+	addcc	$acc0,-1,$t0		! add modulus
-+	not	$poly3,$t3
-+	addxccc	$acc1,$poly1,$t1
-+	not	$poly1,$poly1		! restore $poly1
-+	addxccc	$acc2,%g0,$t2
-+	addxc	$acc3,$t3,$t3
-+
-+	movrnz	$acc4,$t0,$acc0		! if a-b borrowed, ret = ret+mod
-+	movrnz	$acc4,$t1,$acc1
-+	stx	$acc0,[$rp]
-+	movrnz	$acc4,$t2,$acc2
-+	stx	$acc1,[$rp+8]
-+	movrnz	$acc4,$t3,$acc3
-+	stx	$acc2,[$rp+16]
-+	retl
-+	stx	$acc3,[$rp+24]
-+.type	__ecp_nistz256_sub_morf_vis3,#function
-+.size	__ecp_nistz256_sub_morf_vis3,.-__ecp_nistz256_sub_morf_vis3
-+
-+.align	32
-+__ecp_nistz256_div_by_2_vis3:
-+	! ret = (a is odd ? a+mod : a) >> 1
-+
-+	not	$poly1,$t1
-+	not	$poly3,$t3
-+	and	$acc0,1,$acc5
-+	addcc	$acc0,-1,$t0		! add modulus
-+	addxccc	$acc1,$t1,$t1
-+	addxccc	$acc2,%g0,$t2
-+	addxccc	$acc3,$t3,$t3
-+	addxc	%g0,%g0,$acc4		! carry bit
-+
-+	movrnz	$acc5,$t0,$acc0
-+	movrnz	$acc5,$t1,$acc1
-+	movrnz	$acc5,$t2,$acc2
-+	movrnz	$acc5,$t3,$acc3
-+	movrz	$acc5,%g0,$acc4
-+
-+	! ret >>= 1
-+
-+	srlx	$acc0,1,$acc0
-+	sllx	$acc1,63,$t0
-+	srlx	$acc1,1,$acc1
-+	or	$acc0,$t0,$acc0
-+	sllx	$acc2,63,$t1
-+	srlx	$acc2,1,$acc2
-+	or	$acc1,$t1,$acc1
-+	sllx	$acc3,63,$t2
-+	stx	$acc0,[$rp]
-+	srlx	$acc3,1,$acc3
-+	or	$acc2,$t2,$acc2
-+	sllx	$acc4,63,$t3		! don't forget carry bit
-+	stx	$acc1,[$rp+8]
-+	or	$acc3,$t3,$acc3
-+	stx	$acc2,[$rp+16]
-+	retl
-+	stx	$acc3,[$rp+24]
-+.type	__ecp_nistz256_div_by_2_vis3,#function
-+.size	__ecp_nistz256_div_by_2_vis3,.-__ecp_nistz256_div_by_2_vis3
-+
-+! compared to __ecp_nistz256_mul_mont it's almost 4x smaller and
-+! 4x faster [on T4]...
-+.align	32
-+__ecp_nistz256_mul_mont_vis3:
-+	mulx	$a0,$bi,$acc0
-+	not	$poly3,$poly3		! 0xFFFFFFFF00000001
-+	umulxhi	$a0,$bi,$t0
-+	mulx	$a1,$bi,$acc1
-+	umulxhi	$a1,$bi,$t1
-+	mulx	$a2,$bi,$acc2
-+	umulxhi	$a2,$bi,$t2
-+	mulx	$a3,$bi,$acc3
-+	umulxhi	$a3,$bi,$t3
-+	ldx	[$bp+8],$bi		! b[1]
-+
-+	addcc	$acc1,$t0,$acc1		! accumulate high parts of multiplication
-+	 sllx	$acc0,32,$t0
-+	addxccc	$acc2,$t1,$acc2
-+	 srlx	$acc0,32,$t1
-+	addxccc	$acc3,$t2,$acc3
-+	addxc	%g0,$t3,$acc4
-+	mov	0,$acc5
-+___
-+for($i=1;$i<4;$i++) {
-+	# Reduction iteration is normally performed by accumulating
-+	# result of multiplication of modulus by "magic" digit [and
-+	# omitting least significant word, which is guaranteed to
-+	# be 0], but thanks to special form of modulus and "magic"
-+	# digit being equal to least significant word, it can be
-+	# performed with additions and subtractions alone. Indeed:
-+	#
-+	#            ffff0001.00000000.0000ffff.ffffffff
-+	# *                                     abcdefgh
-+	# + xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh
-+	#
-+	# Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we
-+	# rewrite above as:
-+	#
-+	#   xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh
-+	# + abcdefgh.abcdefgh.0000abcd.efgh0000.00000000
-+	# - 0000abcd.efgh0000.00000000.00000000.abcdefgh
-+	#
-+	# or marking redundant operations:
-+	#
-+	#   xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.--------
-+	# + abcdefgh.abcdefgh.0000abcd.efgh0000.--------
-+	# - 0000abcd.efgh0000.--------.--------.--------
-+	#   ^^^^^^^^ but this word is calculated with umulxhi, because
-+	#            there is no subtract with 64-bit borrow:-(
-+
-+$code.=<<___;
-+	sub	$acc0,$t0,$t2		! acc0*0xFFFFFFFF00000001, low part
-+	umulxhi	$acc0,$poly3,$t3	! acc0*0xFFFFFFFF00000001, high part
-+	addcc	$acc1,$t0,$acc0		! +=acc[0]<<96 and omit acc[0]
-+	mulx	$a0,$bi,$t0
-+	addxccc	$acc2,$t1,$acc1
-+	mulx	$a1,$bi,$t1
-+	addxccc	$acc3,$t2,$acc2		! +=acc[0]*0xFFFFFFFF00000001
-+	mulx	$a2,$bi,$t2
-+	addxccc	$acc4,$t3,$acc3
-+	mulx	$a3,$bi,$t3
-+	addxc	$acc5,%g0,$acc4
-+
-+	addcc	$acc0,$t0,$acc0		! accumulate low parts of multiplication
-+	umulxhi	$a0,$bi,$t0
-+	addxccc	$acc1,$t1,$acc1
-+	umulxhi	$a1,$bi,$t1
-+	addxccc	$acc2,$t2,$acc2
-+	umulxhi	$a2,$bi,$t2
-+	addxccc	$acc3,$t3,$acc3
-+	umulxhi	$a3,$bi,$t3
-+	addxc	$acc4,%g0,$acc4
-+___
-+$code.=<<___	if ($i<3);
-+	ldx	[$bp+8*($i+1)],$bi	! bp[$i+1]
-+___
-+$code.=<<___;
-+	addcc	$acc1,$t0,$acc1		! accumulate high parts of multiplication 
-+	 sllx	$acc0,32,$t0
-+	addxccc	$acc2,$t1,$acc2
-+	 srlx	$acc0,32,$t1
-+	addxccc	$acc3,$t2,$acc3
-+	addxccc	$acc4,$t3,$acc4
-+	addxc	%g0,%g0,$acc5
-+___
-+}
-+$code.=<<___;
-+	sub	$acc0,$t0,$t2		! acc0*0xFFFFFFFF00000001, low part
-+	umulxhi	$acc0,$poly3,$t3	! acc0*0xFFFFFFFF00000001, high part
-+	addcc	$acc1,$t0,$acc0		! +=acc[0]<<96 and omit acc[0]
-+	addxccc	$acc2,$t1,$acc1
-+	addxccc	$acc3,$t2,$acc2		! +=acc[0]*0xFFFFFFFF00000001
-+	addxccc	$acc4,$t3,$acc3
-+	b	.Lmul_final_vis3	! see below
-+	addxc	$acc5,%g0,$acc4
-+.type	__ecp_nistz256_mul_mont_vis3,#function
-+.size	__ecp_nistz256_mul_mont_vis3,.-__ecp_nistz256_mul_mont_vis3
-+
-+! compared to above __ecp_nistz256_mul_mont_vis3 it's 21% less
-+! instructions, but only 14% faster [on T4]...
-+.align	32
-+__ecp_nistz256_sqr_mont_vis3:
-+	!  |  |  |  |  |  |a1*a0|  |
-+	!  |  |  |  |  |a2*a0|  |  |
-+	!  |  |a3*a2|a3*a0|  |  |  |
-+	!  |  |  |  |a2*a1|  |  |  |
-+	!  |  |  |a3*a1|  |  |  |  |
-+	! *|  |  |  |  |  |  |  | 2|
-+	! +|a3*a3|a2*a2|a1*a1|a0*a0|
-+	!  |--+--+--+--+--+--+--+--|
-+	!  |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx
-+	!
-+	!  "can't overflow" below mark carrying into high part of
-+	!  multiplication result, which can't overflow, because it
-+	!  can never be all ones.
-+
-+	mulx	$a1,$a0,$acc1		! a[1]*a[0]
-+	umulxhi	$a1,$a0,$t1
-+	mulx	$a2,$a0,$acc2		! a[2]*a[0]
-+	umulxhi	$a2,$a0,$t2
-+	mulx	$a3,$a0,$acc3		! a[3]*a[0]
-+	umulxhi	$a3,$a0,$acc4
-+
-+	addcc	$acc2,$t1,$acc2		! accumulate high parts of multiplication
-+	mulx	$a2,$a1,$t0		! a[2]*a[1]
-+	umulxhi	$a2,$a1,$t1
-+	addxccc	$acc3,$t2,$acc3
-+	mulx	$a3,$a1,$t2		! a[3]*a[1]
-+	umulxhi	$a3,$a1,$t3
-+	addxc	$acc4,%g0,$acc4		! can't overflow
-+
-+	mulx	$a3,$a2,$acc5		! a[3]*a[2]
-+	not	$poly3,$poly3		! 0xFFFFFFFF00000001
-+	umulxhi	$a3,$a2,$acc6
-+
-+	addcc	$t2,$t1,$t1		! accumulate high parts of multiplication
-+	mulx	$a0,$a0,$acc0		! a[0]*a[0]
-+	addxc	$t3,%g0,$t2		! can't overflow
-+
-+	addcc	$acc3,$t0,$acc3		! accumulate low parts of multiplication
-+	umulxhi	$a0,$a0,$a0
-+	addxccc	$acc4,$t1,$acc4
-+	mulx	$a1,$a1,$t1		! a[1]*a[1]
-+	addxccc	$acc5,$t2,$acc5
-+	umulxhi	$a1,$a1,$a1
-+	addxc	$acc6,%g0,$acc6		! can't overflow
-+
-+	addcc	$acc1,$acc1,$acc1	! acc[1-6]*=2
-+	mulx	$a2,$a2,$t2		! a[2]*a[2]
-+	addxccc	$acc2,$acc2,$acc2
-+	umulxhi	$a2,$a2,$a2
-+	addxccc	$acc3,$acc3,$acc3
-+	mulx	$a3,$a3,$t3		! a[3]*a[3]
-+	addxccc	$acc4,$acc4,$acc4
-+	umulxhi	$a3,$a3,$a3
-+	addxccc	$acc5,$acc5,$acc5
-+	addxccc	$acc6,$acc6,$acc6
-+	addxc	%g0,%g0,$acc7
-+
-+	addcc	$acc1,$a0,$acc1		! +a[i]*a[i]
-+	addxccc	$acc2,$t1,$acc2
-+	addxccc	$acc3,$a1,$acc3
-+	addxccc	$acc4,$t2,$acc4
-+	 sllx	$acc0,32,$t0
-+	addxccc	$acc5,$a2,$acc5
-+	 srlx	$acc0,32,$t1
-+	addxccc	$acc6,$t3,$acc6
-+	 sub	$acc0,$t0,$t2		! acc0*0xFFFFFFFF00000001, low part
-+	addxc	$acc7,$a3,$acc7
-+___
-+for($i=0;$i<3;$i++) {			# reductions, see commentary
-+					# in multiplication for details
-+$code.=<<___;
-+	umulxhi	$acc0,$poly3,$t3	! acc0*0xFFFFFFFF00000001, high part
-+	addcc	$acc1,$t0,$acc0		! +=acc[0]<<96 and omit acc[0]
-+	 sllx	$acc0,32,$t0
-+	addxccc	$acc2,$t1,$acc1
-+	 srlx	$acc0,32,$t1
-+	addxccc	$acc3,$t2,$acc2		! +=acc[0]*0xFFFFFFFF00000001
-+	 sub	$acc0,$t0,$t2		! acc0*0xFFFFFFFF00000001, low part
-+	addxc	%g0,$t3,$acc3		! cant't overflow
-+___
-+}
-+$code.=<<___;
-+	umulxhi	$acc0,$poly3,$t3	! acc0*0xFFFFFFFF00000001, high part
-+	addcc	$acc1,$t0,$acc0		! +=acc[0]<<96 and omit acc[0]
-+	addxccc	$acc2,$t1,$acc1
-+	addxccc	$acc3,$t2,$acc2		! +=acc[0]*0xFFFFFFFF00000001
-+	addxc	%g0,$t3,$acc3		! can't overflow
-+
-+	addcc	$acc0,$acc4,$acc0	! accumulate upper half
-+	addxccc	$acc1,$acc5,$acc1
-+	addxccc	$acc2,$acc6,$acc2
-+	addxccc	$acc3,$acc7,$acc3
-+	addxc	%g0,%g0,$acc4
-+
-+.Lmul_final_vis3:
-+
-+	! Final step is "if result > mod, subtract mod", but as comparison
-+	! means subtraction, we do the subtraction and then copy outcome
-+	! if it didn't borrow. But note that as we [have to] replace
-+	! subtraction with addition with negative, carry/borrow logic is
-+	! inverse.
-+
-+	addcc	$acc0,1,$t0		! add -modulus, i.e. subtract
-+	not	$poly3,$poly3		! restore 0x00000000FFFFFFFE
-+	addxccc	$acc1,$poly1,$t1
-+	addxccc	$acc2,$minus1,$t2
-+	addxccc	$acc3,$poly3,$t3
-+	addxccc	$acc4,$minus1,%g0	! did it carry?
-+
-+	movcs	%xcc,$t0,$acc0
-+	movcs	%xcc,$t1,$acc1
-+	stx	$acc0,[$rp]
-+	movcs	%xcc,$t2,$acc2
-+	stx	$acc1,[$rp+8]
-+	movcs	%xcc,$t3,$acc3
-+	stx	$acc2,[$rp+16]
-+	retl
-+	stx	$acc3,[$rp+24]
-+.type	__ecp_nistz256_sqr_mont_vis3,#function
-+.size	__ecp_nistz256_sqr_mont_vis3,.-__ecp_nistz256_sqr_mont_vis3
-+___
-+
-+########################################################################
-+# void ecp_nistz256_point_double(P256_POINT *out,const P256_POINT *inp);
-+#
-+{
-+my ($res_x,$res_y,$res_z,
-+    $in_x,$in_y,$in_z,
-+    $S,$M,$Zsqr,$tmp0)=map(32*$_,(0..9));
-+# above map() describes stack layout with 10 temporary
-+# 256-bit vectors on top.
-+
-+$code.=<<___;
-+.align	32
-+ecp_nistz256_point_double_vis3:
-+	save	%sp,-STACK64_FRAME-32*10,%sp
-+
-+	mov	$rp,$rp_real
-+.Ldouble_shortcut_vis3:
-+	mov	-1,$minus1
-+	mov	-2,$poly3
-+	sllx	$minus1,32,$poly1		! 0xFFFFFFFF00000000
-+	srl	$poly3,0,$poly3			! 0x00000000FFFFFFFE
-+
-+	! convert input to uint64_t[4]
-+	ld	[$ap],$a0			! in_x
-+	ld	[$ap+4],$t0
-+	ld	[$ap+8],$a1
-+	ld	[$ap+12],$t1
-+	ld	[$ap+16],$a2
-+	ld	[$ap+20],$t2
-+	ld	[$ap+24],$a3
-+	ld	[$ap+28],$t3
-+	sllx	$t0,32,$t0
-+	sllx	$t1,32,$t1
-+	ld	[$ap+32],$acc0			! in_y
-+	or	$a0,$t0,$a0
-+	ld	[$ap+32+4],$t0
-+	sllx	$t2,32,$t2
-+	ld	[$ap+32+8],$acc1
-+	or	$a1,$t1,$a1
-+	ld	[$ap+32+12],$t1
-+	sllx	$t3,32,$t3
-+	ld	[$ap+32+16],$acc2
-+	or	$a2,$t2,$a2
-+	ld	[$ap+32+20],$t2
-+	or	$a3,$t3,$a3
-+	ld	[$ap+32+24],$acc3
-+	sllx	$t0,32,$t0
-+	ld	[$ap+32+28],$t3
-+	sllx	$t1,32,$t1
-+	stx	$a0,[%sp+LOCALS64+$in_x]
-+	sllx	$t2,32,$t2
-+	stx	$a1,[%sp+LOCALS64+$in_x+8]
-+	sllx	$t3,32,$t3
-+	stx	$a2,[%sp+LOCALS64+$in_x+16]
-+	or	$acc0,$t0,$acc0
-+	stx	$a3,[%sp+LOCALS64+$in_x+24]
-+	or	$acc1,$t1,$acc1
-+	stx	$acc0,[%sp+LOCALS64+$in_y]
-+	or	$acc2,$t2,$acc2
-+	stx	$acc1,[%sp+LOCALS64+$in_y+8]
-+	or	$acc3,$t3,$acc3
-+	stx	$acc2,[%sp+LOCALS64+$in_y+16]
-+	stx	$acc3,[%sp+LOCALS64+$in_y+24]
-+
-+	ld	[$ap+64],$a0			! in_z
-+	ld	[$ap+64+4],$t0
-+	ld	[$ap+64+8],$a1
-+	ld	[$ap+64+12],$t1
-+	ld	[$ap+64+16],$a2
-+	ld	[$ap+64+20],$t2
-+	ld	[$ap+64+24],$a3
-+	ld	[$ap+64+28],$t3
-+	sllx	$t0,32,$t0
-+	sllx	$t1,32,$t1
-+	or	$a0,$t0,$a0
-+	sllx	$t2,32,$t2
-+	or	$a1,$t1,$a1
-+	sllx	$t3,32,$t3
-+	or	$a2,$t2,$a2
-+	or	$a3,$t3,$a3
-+	sllx	$t0,32,$t0
-+	sllx	$t1,32,$t1
-+	stx	$a0,[%sp+LOCALS64+$in_z]
-+	sllx	$t2,32,$t2
-+	stx	$a1,[%sp+LOCALS64+$in_z+8]
-+	sllx	$t3,32,$t3
-+	stx	$a2,[%sp+LOCALS64+$in_z+16]
-+	stx	$a3,[%sp+LOCALS64+$in_z+24]
-+
-+	! in_y is still in $acc0-$acc3
-+	call	__ecp_nistz256_mul_by_2_vis3	! p256_mul_by_2(S, in_y);
-+	add	%sp,LOCALS64+$S,$rp
-+
-+	! in_z is still in $a0-$a3
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(Zsqr, in_z);
-+	add	%sp,LOCALS64+$Zsqr,$rp
-+
-+	mov	$acc0,$a0			! put Zsqr aside
-+	mov	$acc1,$a1
-+	mov	$acc2,$a2
-+	mov	$acc3,$a3
-+
-+	add	%sp,LOCALS64+$in_x,$bp
-+	call	__ecp_nistz256_add_vis3		! p256_add(M, Zsqr, in_x);
-+	add	%sp,LOCALS64+$M,$rp
-+
-+	mov	$a0,$acc0			! restore Zsqr
-+	ldx	[%sp+LOCALS64+$S],$a0		! forward load
-+	mov	$a1,$acc1
-+	ldx	[%sp+LOCALS64+$S+8],$a1
-+	mov	$a2,$acc2
-+	ldx	[%sp+LOCALS64+$S+16],$a2
-+	mov	$a3,$acc3
-+	ldx	[%sp+LOCALS64+$S+24],$a3
-+
-+	add	%sp,LOCALS64+$in_x,$bp
-+	call	__ecp_nistz256_sub_morf_vis3	! p256_sub(Zsqr, in_x, Zsqr);
-+	add	%sp,LOCALS64+$Zsqr,$rp
-+
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(S, S);
-+	add	%sp,LOCALS64+$S,$rp
-+
-+	ldx	[%sp+LOCALS64+$in_z],$bi
-+	ldx	[%sp+LOCALS64+$in_y],$a0
-+	ldx	[%sp+LOCALS64+$in_y+8],$a1
-+	ldx	[%sp+LOCALS64+$in_y+16],$a2
-+	ldx	[%sp+LOCALS64+$in_y+24],$a3
-+	add	%sp,LOCALS64+$in_z,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(tmp0, in_z, in_y);
-+	add	%sp,LOCALS64+$tmp0,$rp
-+
-+	ldx	[%sp+LOCALS64+$M],$bi		! forward load
-+	ldx	[%sp+LOCALS64+$Zsqr],$a0
-+	ldx	[%sp+LOCALS64+$Zsqr+8],$a1
-+	ldx	[%sp+LOCALS64+$Zsqr+16],$a2
-+	ldx	[%sp+LOCALS64+$Zsqr+24],$a3
-+
-+	call	__ecp_nistz256_mul_by_2_vis3	! p256_mul_by_2(res_z, tmp0);
-+	add	%sp,LOCALS64+$res_z,$rp
-+
-+	add	%sp,LOCALS64+$M,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(M, M, Zsqr);
-+	add	%sp,LOCALS64+$M,$rp
-+
-+	mov	$acc0,$a0			! put aside M
-+	mov	$acc1,$a1
-+	mov	$acc2,$a2
-+	mov	$acc3,$a3
-+	call	__ecp_nistz256_mul_by_2_vis3
-+	add	%sp,LOCALS64+$M,$rp
-+	mov	$a0,$t0				! copy M
-+	ldx	[%sp+LOCALS64+$S],$a0		! forward load
-+	mov	$a1,$t1
-+	ldx	[%sp+LOCALS64+$S+8],$a1
-+	mov	$a2,$t2
-+	ldx	[%sp+LOCALS64+$S+16],$a2
-+	mov	$a3,$t3
-+	ldx	[%sp+LOCALS64+$S+24],$a3
-+	call	__ecp_nistz256_add_noload_vis3	! p256_mul_by_3(M, M);
-+	add	%sp,LOCALS64+$M,$rp
-+
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(tmp0, S);
-+	add	%sp,LOCALS64+$tmp0,$rp
-+
-+	ldx	[%sp+LOCALS64+$S],$bi		! forward load
-+	ldx	[%sp+LOCALS64+$in_x],$a0
-+	ldx	[%sp+LOCALS64+$in_x+8],$a1
-+	ldx	[%sp+LOCALS64+$in_x+16],$a2
-+	ldx	[%sp+LOCALS64+$in_x+24],$a3
-+
-+	call	__ecp_nistz256_div_by_2_vis3	! p256_div_by_2(res_y, tmp0);
-+	add	%sp,LOCALS64+$res_y,$rp
-+
-+	add	%sp,LOCALS64+$S,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(S, S, in_x);
-+	add	%sp,LOCALS64+$S,$rp
-+
-+	ldx	[%sp+LOCALS64+$M],$a0		! forward load
-+	ldx	[%sp+LOCALS64+$M+8],$a1
-+	ldx	[%sp+LOCALS64+$M+16],$a2
-+	ldx	[%sp+LOCALS64+$M+24],$a3
-+
-+	call	__ecp_nistz256_mul_by_2_vis3	! p256_mul_by_2(tmp0, S);
-+	add	%sp,LOCALS64+$tmp0,$rp
-+
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(res_x, M);
-+	add	%sp,LOCALS64+$res_x,$rp
-+
-+	add	%sp,LOCALS64+$tmp0,$bp
-+	call	__ecp_nistz256_sub_from_vis3	! p256_sub(res_x, res_x, tmp0);
-+	add	%sp,LOCALS64+$res_x,$rp
-+
-+	ldx	[%sp+LOCALS64+$M],$a0		! forward load
-+	ldx	[%sp+LOCALS64+$M+8],$a1
-+	ldx	[%sp+LOCALS64+$M+16],$a2
-+	ldx	[%sp+LOCALS64+$M+24],$a3
-+
-+	add	%sp,LOCALS64+$S,$bp
-+	call	__ecp_nistz256_sub_morf_vis3	! p256_sub(S, S, res_x);
-+	add	%sp,LOCALS64+$S,$rp
-+
-+	mov	$acc0,$bi
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(S, S, M);
-+	add	%sp,LOCALS64+$S,$rp
-+
-+	ldx	[%sp+LOCALS64+$res_x],$a0	! forward load
-+	ldx	[%sp+LOCALS64+$res_x+8],$a1
-+	ldx	[%sp+LOCALS64+$res_x+16],$a2
-+	ldx	[%sp+LOCALS64+$res_x+24],$a3
-+
-+	add	%sp,LOCALS64+$res_y,$bp
-+	call	__ecp_nistz256_sub_from_vis3	! p256_sub(res_y, S, res_y);
-+	add	%sp,LOCALS64+$res_y,$bp
-+
-+	! convert output to uint_32[8]
-+	srlx	$a0,32,$t0
-+	srlx	$a1,32,$t1
-+	st	$a0,[$rp_real]			! res_x
-+	srlx	$a2,32,$t2
-+	st	$t0,[$rp_real+4]
-+	srlx	$a3,32,$t3
-+	st	$a1,[$rp_real+8]
-+	st	$t1,[$rp_real+12]
-+	st	$a2,[$rp_real+16]
-+	st	$t2,[$rp_real+20]
-+	st	$a3,[$rp_real+24]
-+	st	$t3,[$rp_real+28]
-+
-+	ldx	[%sp+LOCALS64+$res_z],$a0	! forward load
-+	srlx	$acc0,32,$t0
-+	ldx	[%sp+LOCALS64+$res_z+8],$a1
-+	srlx	$acc1,32,$t1
-+	ldx	[%sp+LOCALS64+$res_z+16],$a2
-+	srlx	$acc2,32,$t2
-+	ldx	[%sp+LOCALS64+$res_z+24],$a3
-+	srlx	$acc3,32,$t3
-+	st	$acc0,[$rp_real+32]		! res_y
-+	st	$t0,  [$rp_real+32+4]
-+	st	$acc1,[$rp_real+32+8]
-+	st	$t1,  [$rp_real+32+12]
-+	st	$acc2,[$rp_real+32+16]
-+	st	$t2,  [$rp_real+32+20]
-+	st	$acc3,[$rp_real+32+24]
-+	st	$t3,  [$rp_real+32+28]
-+
-+	srlx	$a0,32,$t0
-+	srlx	$a1,32,$t1
-+	st	$a0,[$rp_real+64]		! res_z
-+	srlx	$a2,32,$t2
-+	st	$t0,[$rp_real+64+4]
-+	srlx	$a3,32,$t3
-+	st	$a1,[$rp_real+64+8]
-+	st	$t1,[$rp_real+64+12]
-+	st	$a2,[$rp_real+64+16]
-+	st	$t2,[$rp_real+64+20]
-+	st	$a3,[$rp_real+64+24]
-+	st	$t3,[$rp_real+64+28]
-+
-+	ret
-+	restore
-+.type	ecp_nistz256_point_double_vis3,#function
-+.size	ecp_nistz256_point_double_vis3,.-ecp_nistz256_point_double_vis3
-+___
-+}
-+########################################################################
-+# void ecp_nistz256_point_add(P256_POINT *out,const P256_POINT *in1,
-+#			      const P256_POINT *in2);
-+{
-+my ($res_x,$res_y,$res_z,
-+    $in1_x,$in1_y,$in1_z,
-+    $in2_x,$in2_y,$in2_z,
-+    $H,$Hsqr,$R,$Rsqr,$Hcub,
-+    $U1,$U2,$S1,$S2)=map(32*$_,(0..17));
-+my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
-+
-+# above map() describes stack layout with 18 temporary
-+# 256-bit vectors on top. Then we reserve some space for
-+# !in1infty, !in2infty and result of check for zero.
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_add_vis3
-+.align	32
-+ecp_nistz256_point_add_vis3:
-+	save	%sp,-STACK64_FRAME-32*18-32,%sp
-+
-+	mov	$rp,$rp_real
-+	mov	-1,$minus1
-+	mov	-2,$poly3
-+	sllx	$minus1,32,$poly1		! 0xFFFFFFFF00000000
-+	srl	$poly3,0,$poly3			! 0x00000000FFFFFFFE
-+
-+	! convert input to uint64_t[4]
-+	ld	[$bp],$a0			! in2_x
-+	ld	[$bp+4],$t0
-+	ld	[$bp+8],$a1
-+	ld	[$bp+12],$t1
-+	ld	[$bp+16],$a2
-+	ld	[$bp+20],$t2
-+	ld	[$bp+24],$a3
-+	ld	[$bp+28],$t3
-+	sllx	$t0,32,$t0
-+	sllx	$t1,32,$t1
-+	ld	[$bp+32],$acc0			! in2_y
-+	or	$a0,$t0,$a0
-+	ld	[$bp+32+4],$t0
-+	sllx	$t2,32,$t2
-+	ld	[$bp+32+8],$acc1
-+	or	$a1,$t1,$a1
-+	ld	[$bp+32+12],$t1
-+	sllx	$t3,32,$t3
-+	ld	[$bp+32+16],$acc2
-+	or	$a2,$t2,$a2
-+	ld	[$bp+32+20],$t2
-+	or	$a3,$t3,$a3
-+	ld	[$bp+32+24],$acc3
-+	sllx	$t0,32,$t0
-+	ld	[$bp+32+28],$t3
-+	sllx	$t1,32,$t1
-+	stx	$a0,[%sp+LOCALS64+$in2_x]
-+	sllx	$t2,32,$t2
-+	stx	$a1,[%sp+LOCALS64+$in2_x+8]
-+	sllx	$t3,32,$t3
-+	stx	$a2,[%sp+LOCALS64+$in2_x+16]
-+	or	$acc0,$t0,$acc0
-+	stx	$a3,[%sp+LOCALS64+$in2_x+24]
-+	or	$acc1,$t1,$acc1
-+	stx	$acc0,[%sp+LOCALS64+$in2_y]
-+	or	$acc2,$t2,$acc2
-+	stx	$acc1,[%sp+LOCALS64+$in2_y+8]
-+	or	$acc3,$t3,$acc3
-+	stx	$acc2,[%sp+LOCALS64+$in2_y+16]
-+	stx	$acc3,[%sp+LOCALS64+$in2_y+24]
-+
-+	ld	[$bp+64],$acc0			! in2_z
-+	ld	[$bp+64+4],$t0
-+	ld	[$bp+64+8],$acc1
-+	ld	[$bp+64+12],$t1
-+	ld	[$bp+64+16],$acc2
-+	ld	[$bp+64+20],$t2
-+	ld	[$bp+64+24],$acc3
-+	ld	[$bp+64+28],$t3
-+	sllx	$t0,32,$t0
-+	sllx	$t1,32,$t1
-+	ld	[$ap],$a0			! in1_x
-+	or	$acc0,$t0,$acc0
-+	ld	[$ap+4],$t0
-+	sllx	$t2,32,$t2
-+	ld	[$ap+8],$a1
-+	or	$acc1,$t1,$acc1
-+	ld	[$ap+12],$t1
-+	sllx	$t3,32,$t3
-+	ld	[$ap+16],$a2
-+	or	$acc2,$t2,$acc2
-+	ld	[$ap+20],$t2
-+	or	$acc3,$t3,$acc3
-+	ld	[$ap+24],$a3
-+	sllx	$t0,32,$t0
-+	ld	[$ap+28],$t3
-+	sllx	$t1,32,$t1
-+	stx	$acc0,[%sp+LOCALS64+$in2_z]
-+	sllx	$t2,32,$t2
-+	stx	$acc1,[%sp+LOCALS64+$in2_z+8]
-+	sllx	$t3,32,$t3
-+	stx	$acc2,[%sp+LOCALS64+$in2_z+16]
-+	stx	$acc3,[%sp+LOCALS64+$in2_z+24]
-+
-+	or	$acc1,$acc0,$acc0
-+	or	$acc3,$acc2,$acc2
-+	or	$acc2,$acc0,$acc0
-+	movrnz	$acc0,-1,$acc0			! !in2infty
-+	stx	$acc0,[%fp+STACK_BIAS-8]
-+
-+	or	$a0,$t0,$a0
-+	ld	[$ap+32],$acc0			! in1_y
-+	or	$a1,$t1,$a1
-+	ld	[$ap+32+4],$t0
-+	or	$a2,$t2,$a2
-+	ld	[$ap+32+8],$acc1
-+	or	$a3,$t3,$a3
-+	ld	[$ap+32+12],$t1
-+	ld	[$ap+32+16],$acc2
-+	ld	[$ap+32+20],$t2
-+	ld	[$ap+32+24],$acc3
-+	sllx	$t0,32,$t0
-+	ld	[$ap+32+28],$t3
-+	sllx	$t1,32,$t1
-+	stx	$a0,[%sp+LOCALS64+$in1_x]
-+	sllx	$t2,32,$t2
-+	stx	$a1,[%sp+LOCALS64+$in1_x+8]
-+	sllx	$t3,32,$t3
-+	stx	$a2,[%sp+LOCALS64+$in1_x+16]
-+	or	$acc0,$t0,$acc0
-+	stx	$a3,[%sp+LOCALS64+$in1_x+24]
-+	or	$acc1,$t1,$acc1
-+	stx	$acc0,[%sp+LOCALS64+$in1_y]
-+	or	$acc2,$t2,$acc2
-+	stx	$acc1,[%sp+LOCALS64+$in1_y+8]
-+	or	$acc3,$t3,$acc3
-+	stx	$acc2,[%sp+LOCALS64+$in1_y+16]
-+	stx	$acc3,[%sp+LOCALS64+$in1_y+24]
-+
-+	ldx	[%sp+LOCALS64+$in2_z],$a0	! forward load
-+	ldx	[%sp+LOCALS64+$in2_z+8],$a1
-+	ldx	[%sp+LOCALS64+$in2_z+16],$a2
-+	ldx	[%sp+LOCALS64+$in2_z+24],$a3
-+
-+	ld	[$ap+64],$acc0			! in1_z
-+	ld	[$ap+64+4],$t0
-+	ld	[$ap+64+8],$acc1
-+	ld	[$ap+64+12],$t1
-+	ld	[$ap+64+16],$acc2
-+	ld	[$ap+64+20],$t2
-+	ld	[$ap+64+24],$acc3
-+	ld	[$ap+64+28],$t3
-+	sllx	$t0,32,$t0
-+	sllx	$t1,32,$t1
-+	or	$acc0,$t0,$acc0
-+	sllx	$t2,32,$t2
-+	or	$acc1,$t1,$acc1
-+	sllx	$t3,32,$t3
-+	stx	$acc0,[%sp+LOCALS64+$in1_z]
-+	or	$acc2,$t2,$acc2
-+	stx	$acc1,[%sp+LOCALS64+$in1_z+8]
-+	or	$acc3,$t3,$acc3
-+	stx	$acc2,[%sp+LOCALS64+$in1_z+16]
-+	stx	$acc3,[%sp+LOCALS64+$in1_z+24]
-+
-+	or	$acc1,$acc0,$acc0
-+	or	$acc3,$acc2,$acc2
-+	or	$acc2,$acc0,$acc0
-+	movrnz	$acc0,-1,$acc0			! !in1infty
-+	stx	$acc0,[%fp+STACK_BIAS-16]
-+
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(Z2sqr, in2_z);
-+	add	%sp,LOCALS64+$Z2sqr,$rp
-+
-+	ldx	[%sp+LOCALS64+$in1_z],$a0
-+	ldx	[%sp+LOCALS64+$in1_z+8],$a1
-+	ldx	[%sp+LOCALS64+$in1_z+16],$a2
-+	ldx	[%sp+LOCALS64+$in1_z+24],$a3
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(Z1sqr, in1_z);
-+	add	%sp,LOCALS64+$Z1sqr,$rp
-+
-+	ldx	[%sp+LOCALS64+$Z2sqr],$bi
-+	ldx	[%sp+LOCALS64+$in2_z],$a0
-+	ldx	[%sp+LOCALS64+$in2_z+8],$a1
-+	ldx	[%sp+LOCALS64+$in2_z+16],$a2
-+	ldx	[%sp+LOCALS64+$in2_z+24],$a3
-+	add	%sp,LOCALS64+$Z2sqr,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(S1, Z2sqr, in2_z);
-+	add	%sp,LOCALS64+$S1,$rp
-+
-+	ldx	[%sp+LOCALS64+$Z1sqr],$bi
-+	ldx	[%sp+LOCALS64+$in1_z],$a0
-+	ldx	[%sp+LOCALS64+$in1_z+8],$a1
-+	ldx	[%sp+LOCALS64+$in1_z+16],$a2
-+	ldx	[%sp+LOCALS64+$in1_z+24],$a3
-+	add	%sp,LOCALS64+$Z1sqr,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(S2, Z1sqr, in1_z);
-+	add	%sp,LOCALS64+$S2,$rp
-+
-+	ldx	[%sp+LOCALS64+$S1],$bi
-+	ldx	[%sp+LOCALS64+$in1_y],$a0
-+	ldx	[%sp+LOCALS64+$in1_y+8],$a1
-+	ldx	[%sp+LOCALS64+$in1_y+16],$a2
-+	ldx	[%sp+LOCALS64+$in1_y+24],$a3
-+	add	%sp,LOCALS64+$S1,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(S1, S1, in1_y);
-+	add	%sp,LOCALS64+$S1,$rp
-+
-+	ldx	[%sp+LOCALS64+$S2],$bi
-+	ldx	[%sp+LOCALS64+$in2_y],$a0
-+	ldx	[%sp+LOCALS64+$in2_y+8],$a1
-+	ldx	[%sp+LOCALS64+$in2_y+16],$a2
-+	ldx	[%sp+LOCALS64+$in2_y+24],$a3
-+	add	%sp,LOCALS64+$S2,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(S2, S2, in2_y);
-+	add	%sp,LOCALS64+$S2,$rp
-+
-+	ldx	[%sp+LOCALS64+$Z2sqr],$bi	! forward load
-+	ldx	[%sp+LOCALS64+$in1_x],$a0
-+	ldx	[%sp+LOCALS64+$in1_x+8],$a1
-+	ldx	[%sp+LOCALS64+$in1_x+16],$a2
-+	ldx	[%sp+LOCALS64+$in1_x+24],$a3
-+
-+	add	%sp,LOCALS64+$S1,$bp
-+	call	__ecp_nistz256_sub_from_vis3	! p256_sub(R, S2, S1);
-+	add	%sp,LOCALS64+$R,$rp
-+
-+	or	$acc1,$acc0,$acc0		! see if result is zero
-+	or	$acc3,$acc2,$acc2
-+	or	$acc2,$acc0,$acc0
-+	stx	$acc0,[%fp+STACK_BIAS-24]
-+
-+	add	%sp,LOCALS64+$Z2sqr,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(U1, in1_x, Z2sqr);
-+	add	%sp,LOCALS64+$U1,$rp
-+
-+	ldx	[%sp+LOCALS64+$Z1sqr],$bi
-+	ldx	[%sp+LOCALS64+$in2_x],$a0
-+	ldx	[%sp+LOCALS64+$in2_x+8],$a1
-+	ldx	[%sp+LOCALS64+$in2_x+16],$a2
-+	ldx	[%sp+LOCALS64+$in2_x+24],$a3
-+	add	%sp,LOCALS64+$Z1sqr,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(U2, in2_x, Z1sqr);
-+	add	%sp,LOCALS64+$U2,$rp
-+
-+	ldx	[%sp+LOCALS64+$R],$a0		! forward load
-+	ldx	[%sp+LOCALS64+$R+8],$a1
-+	ldx	[%sp+LOCALS64+$R+16],$a2
-+	ldx	[%sp+LOCALS64+$R+24],$a3
-+
-+	add	%sp,LOCALS64+$U1,$bp
-+	call	__ecp_nistz256_sub_from_vis3	! p256_sub(H, U2, U1);
-+	add	%sp,LOCALS64+$H,$rp
-+
-+	or	$acc1,$acc0,$acc0		! see if result is zero
-+	or	$acc3,$acc2,$acc2
-+	orcc	$acc2,$acc0,$acc0
-+
-+	bne,pt	%xcc,.Ladd_proceed_vis3		! is_equal(U1,U2)?
-+	nop
-+
-+	ldx	[%fp+STACK_BIAS-8],$t0
-+	ldx	[%fp+STACK_BIAS-16],$t1
-+	ldx	[%fp+STACK_BIAS-24],$t2
-+	andcc	$t0,$t1,%g0
-+	be,pt	%xcc,.Ladd_proceed_vis3		! (in1infty || in2infty)?
-+	nop
-+	andcc	$t2,$t2,%g0
-+	be,a,pt	%xcc,.Ldouble_shortcut_vis3	! is_equal(S1,S2)?
-+	add	%sp,32*(12-10)+32,%sp		! difference in frame sizes
-+
-+	st	%g0,[$rp_real]
-+	st	%g0,[$rp_real+4]
-+	st	%g0,[$rp_real+8]
-+	st	%g0,[$rp_real+12]
-+	st	%g0,[$rp_real+16]
-+	st	%g0,[$rp_real+20]
-+	st	%g0,[$rp_real+24]
-+	st	%g0,[$rp_real+28]
-+	st	%g0,[$rp_real+32]
-+	st	%g0,[$rp_real+32+4]
-+	st	%g0,[$rp_real+32+8]
-+	st	%g0,[$rp_real+32+12]
-+	st	%g0,[$rp_real+32+16]
-+	st	%g0,[$rp_real+32+20]
-+	st	%g0,[$rp_real+32+24]
-+	st	%g0,[$rp_real+32+28]
-+	st	%g0,[$rp_real+64]
-+	st	%g0,[$rp_real+64+4]
-+	st	%g0,[$rp_real+64+8]
-+	st	%g0,[$rp_real+64+12]
-+	st	%g0,[$rp_real+64+16]
-+	st	%g0,[$rp_real+64+20]
-+	st	%g0,[$rp_real+64+24]
-+	st	%g0,[$rp_real+64+28]
-+	b	.Ladd_done_vis3
-+	nop
-+
-+.align	16
-+.Ladd_proceed_vis3:
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(Rsqr, R);
-+	add	%sp,LOCALS64+$Rsqr,$rp
-+
-+	ldx	[%sp+LOCALS64+$H],$bi
-+	ldx	[%sp+LOCALS64+$in1_z],$a0
-+	ldx	[%sp+LOCALS64+$in1_z+8],$a1
-+	ldx	[%sp+LOCALS64+$in1_z+16],$a2
-+	ldx	[%sp+LOCALS64+$in1_z+24],$a3
-+	add	%sp,LOCALS64+$H,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(res_z, H, in1_z);
-+	add	%sp,LOCALS64+$res_z,$rp
-+
-+	ldx	[%sp+LOCALS64+$H],$a0
-+	ldx	[%sp+LOCALS64+$H+8],$a1
-+	ldx	[%sp+LOCALS64+$H+16],$a2
-+	ldx	[%sp+LOCALS64+$H+24],$a3
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(Hsqr, H);
-+	add	%sp,LOCALS64+$Hsqr,$rp
-+
-+	ldx	[%sp+LOCALS64+$res_z],$bi
-+	ldx	[%sp+LOCALS64+$in2_z],$a0
-+	ldx	[%sp+LOCALS64+$in2_z+8],$a1
-+	ldx	[%sp+LOCALS64+$in2_z+16],$a2
-+	ldx	[%sp+LOCALS64+$in2_z+24],$a3
-+	add	%sp,LOCALS64+$res_z,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(res_z, res_z, in2_z);
-+	add	%sp,LOCALS64+$res_z,$rp
-+
-+	ldx	[%sp+LOCALS64+$H],$bi
-+	ldx	[%sp+LOCALS64+$Hsqr],$a0
-+	ldx	[%sp+LOCALS64+$Hsqr+8],$a1
-+	ldx	[%sp+LOCALS64+$Hsqr+16],$a2
-+	ldx	[%sp+LOCALS64+$Hsqr+24],$a3
-+	add	%sp,LOCALS64+$H,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(Hcub, Hsqr, H);
-+	add	%sp,LOCALS64+$Hcub,$rp
-+
-+	ldx	[%sp+LOCALS64+$U1],$bi
-+	ldx	[%sp+LOCALS64+$Hsqr],$a0
-+	ldx	[%sp+LOCALS64+$Hsqr+8],$a1
-+	ldx	[%sp+LOCALS64+$Hsqr+16],$a2
-+	ldx	[%sp+LOCALS64+$Hsqr+24],$a3
-+	add	%sp,LOCALS64+$U1,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(U2, U1, Hsqr);
-+	add	%sp,LOCALS64+$U2,$rp
-+
-+	call	__ecp_nistz256_mul_by_2_vis3	! p256_mul_by_2(Hsqr, U2);
-+	add	%sp,LOCALS64+$Hsqr,$rp
-+
-+	add	%sp,LOCALS64+$Rsqr,$bp
-+	call	__ecp_nistz256_sub_morf_vis3	! p256_sub(res_x, Rsqr, Hsqr);
-+	add	%sp,LOCALS64+$res_x,$rp
-+
-+	add	%sp,LOCALS64+$Hcub,$bp
-+	call	__ecp_nistz256_sub_from_vis3	!  p256_sub(res_x, res_x, Hcub);
-+	add	%sp,LOCALS64+$res_x,$rp
-+
-+	ldx	[%sp+LOCALS64+$S1],$bi		! forward load
-+	ldx	[%sp+LOCALS64+$Hcub],$a0
-+	ldx	[%sp+LOCALS64+$Hcub+8],$a1
-+	ldx	[%sp+LOCALS64+$Hcub+16],$a2
-+	ldx	[%sp+LOCALS64+$Hcub+24],$a3
-+
-+	add	%sp,LOCALS64+$U2,$bp
-+	call	__ecp_nistz256_sub_morf_vis3	! p256_sub(res_y, U2, res_x);
-+	add	%sp,LOCALS64+$res_y,$rp
-+
-+	add	%sp,LOCALS64+$S1,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(S2, S1, Hcub);
-+	add	%sp,LOCALS64+$S2,$rp
-+
-+	ldx	[%sp+LOCALS64+$R],$bi
-+	ldx	[%sp+LOCALS64+$res_y],$a0
-+	ldx	[%sp+LOCALS64+$res_y+8],$a1
-+	ldx	[%sp+LOCALS64+$res_y+16],$a2
-+	ldx	[%sp+LOCALS64+$res_y+24],$a3
-+	add	%sp,LOCALS64+$R,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(res_y, res_y, R);
-+	add	%sp,LOCALS64+$res_y,$rp
-+
-+	add	%sp,LOCALS64+$S2,$bp
-+	call	__ecp_nistz256_sub_from_vis3	! p256_sub(res_y, res_y, S2);
-+	add	%sp,LOCALS64+$res_y,$rp
-+
-+	ldx	[%fp+STACK_BIAS-16],$t1		! !in1infty
-+	ldx	[%fp+STACK_BIAS-8],$t2		! !in2infty
-+___
-+for($i=0;$i<96;$i+=16) {			# conditional moves
-+$code.=<<___;
-+	ldx	[%sp+LOCALS64+$res_x+$i],$acc0	! res
-+	ldx	[%sp+LOCALS64+$res_x+$i+8],$acc1
-+	ldx	[%sp+LOCALS64+$in2_x+$i],$acc2	! in2
-+	ldx	[%sp+LOCALS64+$in2_x+$i+8],$acc3
-+	ldx	[%sp+LOCALS64+$in1_x+$i],$acc4	! in1
-+	ldx	[%sp+LOCALS64+$in1_x+$i+8],$acc5
-+	movrz	$t1,$acc2,$acc0
-+	movrz	$t1,$acc3,$acc1
-+	movrz	$t2,$acc4,$acc0
-+	movrz	$t2,$acc5,$acc1
-+	srlx	$acc0,32,$acc2
-+	srlx	$acc1,32,$acc3
-+	st	$acc0,[$rp_real+$i]
-+	st	$acc2,[$rp_real+$i+4]
-+	st	$acc1,[$rp_real+$i+8]
-+	st	$acc3,[$rp_real+$i+12]
-+___
-+}
-+$code.=<<___;
-+.Ladd_done_vis3:
-+	ret
-+	restore
-+.type	ecp_nistz256_point_add_vis3,#function
-+.size	ecp_nistz256_point_add_vis3,.-ecp_nistz256_point_add_vis3
-+___
-+}
-+########################################################################
-+# void ecp_nistz256_point_add_affine(P256_POINT *out,const P256_POINT *in1,
-+#				     const P256_POINT_AFFINE *in2);
-+{
-+my ($res_x,$res_y,$res_z,
-+    $in1_x,$in1_y,$in1_z,
-+    $in2_x,$in2_y,
-+    $U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr)=map(32*$_,(0..14));
-+my $Z1sqr = $S2;
-+# above map() describes stack layout with 15 temporary
-+# 256-bit vectors on top. Then we reserve some space for
-+# !in1infty and !in2infty.
-+
-+$code.=<<___;
-+.align	32
-+ecp_nistz256_point_add_affine_vis3:
-+	save	%sp,-STACK64_FRAME-32*15-32,%sp
-+
-+	mov	$rp,$rp_real
-+	mov	-1,$minus1
-+	mov	-2,$poly3
-+	sllx	$minus1,32,$poly1		! 0xFFFFFFFF00000000
-+	srl	$poly3,0,$poly3			! 0x00000000FFFFFFFE
-+
-+	! convert input to uint64_t[4]
-+	ld	[$bp],$a0			! in2_x
-+	ld	[$bp+4],$t0
-+	ld	[$bp+8],$a1
-+	ld	[$bp+12],$t1
-+	ld	[$bp+16],$a2
-+	ld	[$bp+20],$t2
-+	ld	[$bp+24],$a3
-+	ld	[$bp+28],$t3
-+	sllx	$t0,32,$t0
-+	sllx	$t1,32,$t1
-+	ld	[$bp+32],$acc0			! in2_y
-+	or	$a0,$t0,$a0
-+	ld	[$bp+32+4],$t0
-+	sllx	$t2,32,$t2
-+	ld	[$bp+32+8],$acc1
-+	or	$a1,$t1,$a1
-+	ld	[$bp+32+12],$t1
-+	sllx	$t3,32,$t3
-+	ld	[$bp+32+16],$acc2
-+	or	$a2,$t2,$a2
-+	ld	[$bp+32+20],$t2
-+	or	$a3,$t3,$a3
-+	ld	[$bp+32+24],$acc3
-+	sllx	$t0,32,$t0
-+	ld	[$bp+32+28],$t3
-+	sllx	$t1,32,$t1
-+	stx	$a0,[%sp+LOCALS64+$in2_x]
-+	sllx	$t2,32,$t2
-+	stx	$a1,[%sp+LOCALS64+$in2_x+8]
-+	sllx	$t3,32,$t3
-+	stx	$a2,[%sp+LOCALS64+$in2_x+16]
-+	or	$acc0,$t0,$acc0
-+	stx	$a3,[%sp+LOCALS64+$in2_x+24]
-+	or	$acc1,$t1,$acc1
-+	stx	$acc0,[%sp+LOCALS64+$in2_y]
-+	or	$acc2,$t2,$acc2
-+	stx	$acc1,[%sp+LOCALS64+$in2_y+8]
-+	or	$acc3,$t3,$acc3
-+	stx	$acc2,[%sp+LOCALS64+$in2_y+16]
-+	stx	$acc3,[%sp+LOCALS64+$in2_y+24]
-+
-+	or	$a1,$a0,$a0
-+	or	$a3,$a2,$a2
-+	or	$acc1,$acc0,$acc0
-+	or	$acc3,$acc2,$acc2
-+	or	$a2,$a0,$a0
-+	or	$acc2,$acc0,$acc0
-+	or	$acc0,$a0,$a0
-+	movrnz	$a0,-1,$a0			! !in2infty
-+	stx	$a0,[%fp+STACK_BIAS-8]
-+
-+	ld	[$ap],$a0			! in1_x
-+	ld	[$ap+4],$t0
-+	ld	[$ap+8],$a1
-+	ld	[$ap+12],$t1
-+	ld	[$ap+16],$a2
-+	ld	[$ap+20],$t2
-+	ld	[$ap+24],$a3
-+	ld	[$ap+28],$t3
-+	sllx	$t0,32,$t0
-+	sllx	$t1,32,$t1
-+	ld	[$ap+32],$acc0			! in1_y
-+	or	$a0,$t0,$a0
-+	ld	[$ap+32+4],$t0
-+	sllx	$t2,32,$t2
-+	ld	[$ap+32+8],$acc1
-+	or	$a1,$t1,$a1
-+	ld	[$ap+32+12],$t1
-+	sllx	$t3,32,$t3
-+	ld	[$ap+32+16],$acc2
-+	or	$a2,$t2,$a2
-+	ld	[$ap+32+20],$t2
-+	or	$a3,$t3,$a3
-+	ld	[$ap+32+24],$acc3
-+	sllx	$t0,32,$t0
-+	ld	[$ap+32+28],$t3
-+	sllx	$t1,32,$t1
-+	stx	$a0,[%sp+LOCALS64+$in1_x]
-+	sllx	$t2,32,$t2
-+	stx	$a1,[%sp+LOCALS64+$in1_x+8]
-+	sllx	$t3,32,$t3
-+	stx	$a2,[%sp+LOCALS64+$in1_x+16]
-+	or	$acc0,$t0,$acc0
-+	stx	$a3,[%sp+LOCALS64+$in1_x+24]
-+	or	$acc1,$t1,$acc1
-+	stx	$acc0,[%sp+LOCALS64+$in1_y]
-+	or	$acc2,$t2,$acc2
-+	stx	$acc1,[%sp+LOCALS64+$in1_y+8]
-+	or	$acc3,$t3,$acc3
-+	stx	$acc2,[%sp+LOCALS64+$in1_y+16]
-+	stx	$acc3,[%sp+LOCALS64+$in1_y+24]
-+
-+	ld	[$ap+64],$a0			! in1_z
-+	ld	[$ap+64+4],$t0
-+	ld	[$ap+64+8],$a1
-+	ld	[$ap+64+12],$t1
-+	ld	[$ap+64+16],$a2
-+	ld	[$ap+64+20],$t2
-+	ld	[$ap+64+24],$a3
-+	ld	[$ap+64+28],$t3
-+	sllx	$t0,32,$t0
-+	sllx	$t1,32,$t1
-+	or	$a0,$t0,$a0
-+	sllx	$t2,32,$t2
-+	or	$a1,$t1,$a1
-+	sllx	$t3,32,$t3
-+	stx	$a0,[%sp+LOCALS64+$in1_z]
-+	or	$a2,$t2,$a2
-+	stx	$a1,[%sp+LOCALS64+$in1_z+8]
-+	or	$a3,$t3,$a3
-+	stx	$a2,[%sp+LOCALS64+$in1_z+16]
-+	stx	$a3,[%sp+LOCALS64+$in1_z+24]
-+
-+	or	$a1,$a0,$t0
-+	or	$a3,$a2,$t2
-+	or	$t2,$t0,$t0
-+	movrnz	$t0,-1,$t0			! !in1infty
-+	stx	$t0,[%fp+STACK_BIAS-16]
-+
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(Z1sqr, in1_z);
-+	add	%sp,LOCALS64+$Z1sqr,$rp
-+
-+	ldx	[%sp+LOCALS64+$in2_x],$bi
-+	mov	$acc0,$a0
-+	mov	$acc1,$a1
-+	mov	$acc2,$a2
-+	mov	$acc3,$a3
-+	add	%sp,LOCALS64+$in2_x,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(U2, Z1sqr, in2_x);
-+	add	%sp,LOCALS64+$U2,$rp
-+
-+	ldx	[%sp+LOCALS64+$Z1sqr],$bi	! forward load
-+	ldx	[%sp+LOCALS64+$in1_z],$a0
-+	ldx	[%sp+LOCALS64+$in1_z+8],$a1
-+	ldx	[%sp+LOCALS64+$in1_z+16],$a2
-+	ldx	[%sp+LOCALS64+$in1_z+24],$a3
-+
-+	add	%sp,LOCALS64+$in1_x,$bp
-+	call	__ecp_nistz256_sub_from_vis3	! p256_sub(H, U2, in1_x);
-+	add	%sp,LOCALS64+$H,$rp
-+
-+	add	%sp,LOCALS64+$Z1sqr,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(S2, Z1sqr, in1_z);
-+	add	%sp,LOCALS64+$S2,$rp
-+
-+	ldx	[%sp+LOCALS64+$H],$bi
-+	ldx	[%sp+LOCALS64+$in1_z],$a0
-+	ldx	[%sp+LOCALS64+$in1_z+8],$a1
-+	ldx	[%sp+LOCALS64+$in1_z+16],$a2
-+	ldx	[%sp+LOCALS64+$in1_z+24],$a3
-+	add	%sp,LOCALS64+$H,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(res_z, H, in1_z);
-+	add	%sp,LOCALS64+$res_z,$rp
-+
-+	ldx	[%sp+LOCALS64+$S2],$bi
-+	ldx	[%sp+LOCALS64+$in2_y],$a0
-+	ldx	[%sp+LOCALS64+$in2_y+8],$a1
-+	ldx	[%sp+LOCALS64+$in2_y+16],$a2
-+	ldx	[%sp+LOCALS64+$in2_y+24],$a3
-+	add	%sp,LOCALS64+$S2,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(S2, S2, in2_y);
-+	add	%sp,LOCALS64+$S2,$rp
-+
-+	ldx	[%sp+LOCALS64+$H],$a0		! forward load
-+	ldx	[%sp+LOCALS64+$H+8],$a1
-+	ldx	[%sp+LOCALS64+$H+16],$a2
-+	ldx	[%sp+LOCALS64+$H+24],$a3
-+
-+	add	%sp,LOCALS64+$in1_y,$bp
-+	call	__ecp_nistz256_sub_from_vis3	! p256_sub(R, S2, in1_y);
-+	add	%sp,LOCALS64+$R,$rp
-+
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(Hsqr, H);
-+	add	%sp,LOCALS64+$Hsqr,$rp
-+
-+	ldx	[%sp+LOCALS64+$R],$a0
-+	ldx	[%sp+LOCALS64+$R+8],$a1
-+	ldx	[%sp+LOCALS64+$R+16],$a2
-+	ldx	[%sp+LOCALS64+$R+24],$a3
-+	call	__ecp_nistz256_sqr_mont_vis3	! p256_sqr_mont(Rsqr, R);
-+	add	%sp,LOCALS64+$Rsqr,$rp
-+
-+	ldx	[%sp+LOCALS64+$H],$bi
-+	ldx	[%sp+LOCALS64+$Hsqr],$a0
-+	ldx	[%sp+LOCALS64+$Hsqr+8],$a1
-+	ldx	[%sp+LOCALS64+$Hsqr+16],$a2
-+	ldx	[%sp+LOCALS64+$Hsqr+24],$a3
-+	add	%sp,LOCALS64+$H,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(Hcub, Hsqr, H);
-+	add	%sp,LOCALS64+$Hcub,$rp
-+
-+	ldx	[%sp+LOCALS64+$Hsqr],$bi
-+	ldx	[%sp+LOCALS64+$in1_x],$a0
-+	ldx	[%sp+LOCALS64+$in1_x+8],$a1
-+	ldx	[%sp+LOCALS64+$in1_x+16],$a2
-+	ldx	[%sp+LOCALS64+$in1_x+24],$a3
-+	add	%sp,LOCALS64+$Hsqr,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(U2, in1_x, Hsqr);
-+	add	%sp,LOCALS64+$U2,$rp
-+
-+	call	__ecp_nistz256_mul_by_2_vis3	! p256_mul_by_2(Hsqr, U2);
-+	add	%sp,LOCALS64+$Hsqr,$rp
-+
-+	add	%sp,LOCALS64+$Rsqr,$bp
-+	call	__ecp_nistz256_sub_morf_vis3	! p256_sub(res_x, Rsqr, Hsqr);
-+	add	%sp,LOCALS64+$res_x,$rp
-+
-+	add	%sp,LOCALS64+$Hcub,$bp
-+	call	__ecp_nistz256_sub_from_vis3	!  p256_sub(res_x, res_x, Hcub);
-+	add	%sp,LOCALS64+$res_x,$rp
-+
-+	ldx	[%sp+LOCALS64+$Hcub],$bi	! forward load
-+	ldx	[%sp+LOCALS64+$in1_y],$a0
-+	ldx	[%sp+LOCALS64+$in1_y+8],$a1
-+	ldx	[%sp+LOCALS64+$in1_y+16],$a2
-+	ldx	[%sp+LOCALS64+$in1_y+24],$a3
-+
-+	add	%sp,LOCALS64+$U2,$bp
-+	call	__ecp_nistz256_sub_morf_vis3	! p256_sub(res_y, U2, res_x);
-+	add	%sp,LOCALS64+$res_y,$rp
-+
-+	add	%sp,LOCALS64+$Hcub,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(S2, in1_y, Hcub);
-+	add	%sp,LOCALS64+$S2,$rp
-+
-+	ldx	[%sp+LOCALS64+$R],$bi
-+	ldx	[%sp+LOCALS64+$res_y],$a0
-+	ldx	[%sp+LOCALS64+$res_y+8],$a1
-+	ldx	[%sp+LOCALS64+$res_y+16],$a2
-+	ldx	[%sp+LOCALS64+$res_y+24],$a3
-+	add	%sp,LOCALS64+$R,$bp
-+	call	__ecp_nistz256_mul_mont_vis3	! p256_mul_mont(res_y, res_y, R);
-+	add	%sp,LOCALS64+$res_y,$rp
-+
-+	add	%sp,LOCALS64+$S2,$bp
-+	call	__ecp_nistz256_sub_from_vis3	! p256_sub(res_y, res_y, S2);
-+	add	%sp,LOCALS64+$res_y,$rp
-+
-+	ldx	[%fp+STACK_BIAS-16],$t1		! !in1infty
-+	ldx	[%fp+STACK_BIAS-8],$t2		! !in2infty
-+1:	call	.+8
-+	add	%o7,.Lone_mont_vis3-1b,$bp
-+___
-+for($i=0;$i<64;$i+=16) {			# conditional moves
-+$code.=<<___;
-+	ldx	[%sp+LOCALS64+$res_x+$i],$acc0	! res
-+	ldx	[%sp+LOCALS64+$res_x+$i+8],$acc1
-+	ldx	[%sp+LOCALS64+$in2_x+$i],$acc2	! in2
-+	ldx	[%sp+LOCALS64+$in2_x+$i+8],$acc3
-+	ldx	[%sp+LOCALS64+$in1_x+$i],$acc4	! in1
-+	ldx	[%sp+LOCALS64+$in1_x+$i+8],$acc5
-+	movrz	$t1,$acc2,$acc0
-+	movrz	$t1,$acc3,$acc1
-+	movrz	$t2,$acc4,$acc0
-+	movrz	$t2,$acc5,$acc1
-+	srlx	$acc0,32,$acc2
-+	srlx	$acc1,32,$acc3
-+	st	$acc0,[$rp_real+$i]
-+	st	$acc2,[$rp_real+$i+4]
-+	st	$acc1,[$rp_real+$i+8]
-+	st	$acc3,[$rp_real+$i+12]
-+___
-+}
-+for(;$i<96;$i+=16) {
-+$code.=<<___;
-+	ldx	[%sp+LOCALS64+$res_x+$i],$acc0	! res
-+	ldx	[%sp+LOCALS64+$res_x+$i+8],$acc1
-+	ldx	[$bp+$i-64],$acc2		! "in2"
-+	ldx	[$bp+$i-64+8],$acc3
-+	ldx	[%sp+LOCALS64+$in1_x+$i],$acc4	! in1
-+	ldx	[%sp+LOCALS64+$in1_x+$i+8],$acc5
-+	movrz	$t1,$acc2,$acc0
-+	movrz	$t1,$acc3,$acc1
-+	movrz	$t2,$acc4,$acc0
-+	movrz	$t2,$acc5,$acc1
-+	srlx	$acc0,32,$acc2
-+	srlx	$acc1,32,$acc3
-+	st	$acc0,[$rp_real+$i]
-+	st	$acc2,[$rp_real+$i+4]
-+	st	$acc1,[$rp_real+$i+8]
-+	st	$acc3,[$rp_real+$i+12]
-+___
-+}
-+$code.=<<___;
-+	ret
-+	restore
-+.type	ecp_nistz256_point_add_affine_vis3,#function
-+.size	ecp_nistz256_point_add_affine_vis3,.-ecp_nistz256_point_add_affine_vis3
-+.align	64
-+.Lone_mont_vis3:
-+.long	0x00000000,0x00000001, 0xffffffff,0x00000000
-+.long	0xffffffff,0xffffffff, 0x00000000,0xfffffffe
-+.align	64
-+___
-+}								}}}
-+
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis3 {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my ($ref,$opf);
-+my %visopf = (	"addxc"		=> 0x011,
-+		"addxccc"	=> 0x013,
-+		"umulxhi"	=> 0x016	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%([goli])([0-9])/);
-+	    $_=$bias{$1}+$2;
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	s/\b(umulxhi|addxc[c]{0,2})\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+		&unvis3($1,$2,$3,$4)
-+	 /ge;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-x86.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-x86.pl
-new file mode 100755
-index 0000000..1d9e006
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-x86.pl
-@@ -0,0 +1,1866 @@
-+#! /usr/bin/env perl
-+# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# ECP_NISTZ256 module for x86/SSE2.
-+#
-+# October 2014.
-+#
-+# Original ECP_NISTZ256 submission targeting x86_64 is detailed in
-+# http://eprint.iacr.org/2013/816. In the process of adaptation
-+# original .c module was made 32-bit savvy in order to make this
-+# implementation possible.
-+#
-+#		with/without -DECP_NISTZ256_ASM
-+# Pentium	+66-163%
-+# PIII		+72-172%
-+# P4		+65-132%
-+# Core2		+90-215%
-+# Sandy Bridge	+105-265% (contemporary i[57]-* are all close to this)
-+# Atom		+65-155%
-+# Opteron	+54-110%
-+# Bulldozer	+99-240%
-+# VIA Nano	+93-290%
-+#
-+# Ranges denote minimum and maximum improvement coefficients depending
-+# on benchmark. Lower coefficients are for ECDSA sign, server-side
-+# operation. Keep in mind that +200% means 3x improvement.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"ecp_nistz256-x86.pl",$ARGV[$#ARGV] eq "386");
-+
-+$sse2=0;
-+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-+
-+&external_label("OPENSSL_ia32cap_P") if ($sse2);
-+
-+
-+########################################################################
-+# Convert ecp_nistz256_table.c to layout expected by ecp_nistz_gather_w7
-+#
-+open TABLE,") {
-+	s/TOBN\(\s*(0x[0-9a-f]+),\s*(0x[0-9a-f]+)\s*\)/push @arr,hex($2),hex($1)/geo;
-+}
-+close TABLE;
-+
-+# See ecp_nistz256_table.c for explanation for why it's 64*16*37.
-+# 64*16*37-1 is because $#arr returns last valid index or @arr, not
-+# amount of elements.
-+die "insane number of elements" if ($#arr != 64*16*37-1);
-+
-+&public_label("ecp_nistz256_precomputed");
-+&align(4096);
-+&set_label("ecp_nistz256_precomputed");
-+
-+########################################################################
-+# this conversion smashes P256_POINT_AFFINE by individual bytes with
-+# 64 byte interval, similar to
-+#	1111222233334444
-+#	1234123412341234
-+for(1..37) {
-+	@tbl = splice(@arr,0,64*16);
-+	for($i=0;$i<64;$i++) {
-+		undef @line;
-+		for($j=0;$j<64;$j++) {
-+			push @line,(@tbl[$j*16+$i/4]>>(($i%4)*8))&0xff;
-+		}
-+		&data_byte(join(',',map { sprintf "0x%02x",$_} @line));
-+	}
-+}
-+
-+########################################################################
-+# Keep in mind that constants are stored least to most significant word
-+&static_label("RR");
-+&set_label("RR",64);
-+&data_word(3,0,-1,-5,-2,-1,-3,4);	# 2^512 mod P-256
-+
-+&static_label("ONE_mont");
-+&set_label("ONE_mont");
-+&data_word(1,0,0,-1,-1,-1,-2,0);
-+
-+&static_label("ONE");
-+&set_label("ONE");
-+&data_word(1,0,0,0,0,0,0,0);
-+&asciz("ECP_NISZ256 for x86/SSE2, CRYPTOGAMS by ");
-+&align(64);
-+
-+########################################################################
-+# void ecp_nistz256_mul_by_2(BN_ULONG edi[8],const BN_ULONG esi[8]);
-+&function_begin("ecp_nistz256_mul_by_2");
-+	&mov	("esi",&wparam(1));
-+	&mov	("edi",&wparam(0));
-+	&mov	("ebp","esi");
-+########################################################################
-+# common pattern for internal functions is that %edi is result pointer,
-+# %esi and %ebp are input ones, %ebp being optional. %edi is preserved.
-+	&call	("_ecp_nistz256_add");
-+&function_end("ecp_nistz256_mul_by_2");
-+
-+########################################################################
-+# void ecp_nistz256_mul_by_3(BN_ULONG edi[8],const BN_ULONG esi[8]);
-+&function_begin("ecp_nistz256_mul_by_3");
-+	&mov	("esi",&wparam(1));
-+					# multiplication by 3 is performed
-+					# as 2*n+n, but we can't use output
-+					# to store 2*n, because if output
-+					# pointer equals to input, then
-+					# we'll get 2*n+2*n.
-+	&stack_push(8);			# therefore we need to allocate
-+					# 256-bit intermediate buffer.
-+	&mov	("edi","esp");
-+	&mov	("ebp","esi");
-+	&call	("_ecp_nistz256_add");
-+	&lea	("esi",&DWP(0,"edi"));
-+	&mov	("ebp",&wparam(1));
-+	&mov	("edi",&wparam(0));
-+	&call	("_ecp_nistz256_add");
-+	&stack_pop(8);
-+&function_end("ecp_nistz256_mul_by_3");
-+
-+########################################################################
-+# void ecp_nistz256_div_by_2(BN_ULONG edi[8],const BN_ULONG esi[8]);
-+&function_begin("ecp_nistz256_div_by_2");
-+	&mov	("esi",&wparam(1));
-+	&mov	("edi",&wparam(0));
-+	&call	("_ecp_nistz256_div_by_2");
-+&function_end("ecp_nistz256_div_by_2");
-+
-+&function_begin_B("_ecp_nistz256_div_by_2");
-+	# tmp = a is odd ? a+mod : a
-+	#
-+	# note that because mod has special form, i.e. consists of
-+	# 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	# assigning least significant bit of input to one register,
-+	# %ebp, and its negative to another, %edx.
-+
-+	&mov	("ebp",&DWP(0,"esi"));
-+	&xor	("edx","edx");
-+	&mov	("ebx",&DWP(4,"esi"));
-+	&mov	("eax","ebp");
-+	&and	("ebp",1);
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&sub	("edx","ebp");
-+
-+	&add	("eax","edx");
-+	&adc	("ebx","edx");
-+	&mov	(&DWP(0,"edi"),"eax");
-+	&adc	("ecx","edx");
-+	&mov	(&DWP(4,"edi"),"ebx");
-+	&mov	(&DWP(8,"edi"),"ecx");
-+
-+	&mov	("eax",&DWP(12,"esi"));
-+	&mov	("ebx",&DWP(16,"esi"));
-+	&adc	("eax",0);
-+	&mov	("ecx",&DWP(20,"esi"));
-+	&adc	("ebx",0);
-+	&mov	(&DWP(12,"edi"),"eax");
-+	&adc	("ecx",0);
-+	&mov	(&DWP(16,"edi"),"ebx");
-+	&mov	(&DWP(20,"edi"),"ecx");
-+
-+	&mov	("eax",&DWP(24,"esi"));
-+	&mov	("ebx",&DWP(28,"esi"));
-+	&adc	("eax","ebp");
-+	&adc	("ebx","edx");
-+	&mov	(&DWP(24,"edi"),"eax");
-+	&sbb	("esi","esi");			# broadcast carry bit
-+	&mov	(&DWP(28,"edi"),"ebx");
-+
-+	# ret = tmp >> 1
-+
-+	&mov	("eax",&DWP(0,"edi"));
-+	&mov	("ebx",&DWP(4,"edi"));
-+	&mov	("ecx",&DWP(8,"edi"));
-+	&mov	("edx",&DWP(12,"edi"));
-+
-+	&shr	("eax",1);
-+	&mov	("ebp","ebx");
-+	&shl	("ebx",31);
-+	&or	("eax","ebx");
-+
-+	&shr	("ebp",1);
-+	&mov	("ebx","ecx");
-+	&shl	("ecx",31);
-+	&mov	(&DWP(0,"edi"),"eax");
-+	&or	("ebp","ecx");
-+	&mov	("eax",&DWP(16,"edi"));
-+
-+	&shr	("ebx",1);
-+	&mov	("ecx","edx");
-+	&shl	("edx",31);
-+	&mov	(&DWP(4,"edi"),"ebp");
-+	&or	("ebx","edx");
-+	&mov	("ebp",&DWP(20,"edi"));
-+
-+	&shr	("ecx",1);
-+	&mov	("edx","eax");
-+	&shl	("eax",31);
-+	&mov	(&DWP(8,"edi"),"ebx");
-+	&or	("ecx","eax");
-+	&mov	("ebx",&DWP(24,"edi"));
-+
-+	&shr	("edx",1);
-+	&mov	("eax","ebp");
-+	&shl	("ebp",31);
-+	&mov	(&DWP(12,"edi"),"ecx");
-+	&or	("edx","ebp");
-+	&mov	("ecx",&DWP(28,"edi"));
-+
-+	&shr	("eax",1);
-+	&mov	("ebp","ebx");
-+	&shl	("ebx",31);
-+	&mov	(&DWP(16,"edi"),"edx");
-+	&or	("eax","ebx");
-+
-+	&shr	("ebp",1);
-+	&mov	("ebx","ecx");
-+	&shl	("ecx",31);
-+	&mov	(&DWP(20,"edi"),"eax");
-+	&or	("ebp","ecx");
-+
-+	&shr	("ebx",1);
-+	&shl	("esi",31);
-+	&mov	(&DWP(24,"edi"),"ebp");
-+	&or	("ebx","esi");			# handle top-most carry bit
-+	&mov	(&DWP(28,"edi"),"ebx");
-+
-+	&ret	();
-+&function_end_B("_ecp_nistz256_div_by_2");
-+
-+########################################################################
-+# void ecp_nistz256_add(BN_ULONG edi[8],const BN_ULONG esi[8],
-+#					const BN_ULONG ebp[8]);
-+&function_begin("ecp_nistz256_add");
-+	&mov	("esi",&wparam(1));
-+	&mov	("ebp",&wparam(2));
-+	&mov	("edi",&wparam(0));
-+	&call	("_ecp_nistz256_add");
-+&function_end("ecp_nistz256_add");
-+
-+&function_begin_B("_ecp_nistz256_add");
-+	&mov	("eax",&DWP(0,"esi"));
-+	&mov	("ebx",&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&add	("eax",&DWP(0,"ebp"));
-+	&mov	("edx",&DWP(12,"esi"));
-+	&adc	("ebx",&DWP(4,"ebp"));
-+	&mov	(&DWP(0,"edi"),"eax");
-+	&adc	("ecx",&DWP(8,"ebp"));
-+	&mov	(&DWP(4,"edi"),"ebx");
-+	&adc	("edx",&DWP(12,"ebp"));
-+	&mov	(&DWP(8,"edi"),"ecx");
-+	&mov	(&DWP(12,"edi"),"edx");
-+
-+	&mov	("eax",&DWP(16,"esi"));
-+	&mov	("ebx",&DWP(20,"esi"));
-+	&mov	("ecx",&DWP(24,"esi"));
-+	&adc	("eax",&DWP(16,"ebp"));
-+	&mov	("edx",&DWP(28,"esi"));
-+	&adc	("ebx",&DWP(20,"ebp"));
-+	&mov	(&DWP(16,"edi"),"eax");
-+	&adc	("ecx",&DWP(24,"ebp"));
-+	&mov	(&DWP(20,"edi"),"ebx");
-+	&mov	("esi",0);
-+	&adc	("edx",&DWP(28,"ebp"));
-+	&mov	(&DWP(24,"edi"),"ecx");
-+	&adc	("esi",0);
-+	&mov	(&DWP(28,"edi"),"edx");
-+
-+	# if a+b >= modulus, subtract modulus.
-+	#
-+	# But since comparison implies subtraction, we subtract modulus
-+	# to see if it borrows, and then subtract it for real if
-+	# subtraction didn't borrow.
-+
-+	&mov	("eax",&DWP(0,"edi"));
-+	&mov	("ebx",&DWP(4,"edi"));
-+	&mov	("ecx",&DWP(8,"edi"));
-+	&sub	("eax",-1);
-+	&mov	("edx",&DWP(12,"edi"));
-+	&sbb	("ebx",-1);
-+	&mov	("eax",&DWP(16,"edi"));
-+	&sbb	("ecx",-1);
-+	&mov	("ebx",&DWP(20,"edi"));
-+	&sbb	("edx",0);
-+	&mov	("ecx",&DWP(24,"edi"));
-+	&sbb	("eax",0);
-+	&mov	("edx",&DWP(28,"edi"));
-+	&sbb	("ebx",0);
-+	&sbb	("ecx",1);
-+	&sbb	("edx",-1);
-+	&sbb	("esi",0);
-+
-+	# Note that because mod has special form, i.e. consists of
-+	# 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	# by using borrow.
-+
-+	¬	("esi");
-+	&mov	("eax",&DWP(0,"edi"));
-+	&mov	("ebp","esi");
-+	&mov	("ebx",&DWP(4,"edi"));
-+	&shr	("ebp",31);
-+	&mov	("ecx",&DWP(8,"edi"));
-+	&sub	("eax","esi");
-+	&mov	("edx",&DWP(12,"edi"));
-+	&sbb	("ebx","esi");
-+	&mov	(&DWP(0,"edi"),"eax");
-+	&sbb	("ecx","esi");
-+	&mov	(&DWP(4,"edi"),"ebx");
-+	&sbb	("edx",0);
-+	&mov	(&DWP(8,"edi"),"ecx");
-+	&mov	(&DWP(12,"edi"),"edx");
-+
-+	&mov	("eax",&DWP(16,"edi"));
-+	&mov	("ebx",&DWP(20,"edi"));
-+	&mov	("ecx",&DWP(24,"edi"));
-+	&sbb	("eax",0);
-+	&mov	("edx",&DWP(28,"edi"));
-+	&sbb	("ebx",0);
-+	&mov	(&DWP(16,"edi"),"eax");
-+	&sbb	("ecx","ebp");
-+	&mov	(&DWP(20,"edi"),"ebx");
-+	&sbb	("edx","esi");
-+	&mov	(&DWP(24,"edi"),"ecx");
-+	&mov	(&DWP(28,"edi"),"edx");
-+
-+	&ret	();
-+&function_end_B("_ecp_nistz256_add");
-+
-+########################################################################
-+# void ecp_nistz256_sub(BN_ULONG edi[8],const BN_ULONG esi[8],
-+#					const BN_ULONG ebp[8]);
-+&function_begin("ecp_nistz256_sub");
-+	&mov	("esi",&wparam(1));
-+	&mov	("ebp",&wparam(2));
-+	&mov	("edi",&wparam(0));
-+	&call	("_ecp_nistz256_sub");
-+&function_end("ecp_nistz256_sub");
-+
-+&function_begin_B("_ecp_nistz256_sub");
-+	&mov	("eax",&DWP(0,"esi"));
-+	&mov	("ebx",&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&sub	("eax",&DWP(0,"ebp"));
-+	&mov	("edx",&DWP(12,"esi"));
-+	&sbb	("ebx",&DWP(4,"ebp"));
-+	&mov	(&DWP(0,"edi"),"eax");
-+	&sbb	("ecx",&DWP(8,"ebp"));
-+	&mov	(&DWP(4,"edi"),"ebx");
-+	&sbb	("edx",&DWP(12,"ebp"));
-+	&mov	(&DWP(8,"edi"),"ecx");
-+	&mov	(&DWP(12,"edi"),"edx");
-+
-+	&mov	("eax",&DWP(16,"esi"));
-+	&mov	("ebx",&DWP(20,"esi"));
-+	&mov	("ecx",&DWP(24,"esi"));
-+	&sbb	("eax",&DWP(16,"ebp"));
-+	&mov	("edx",&DWP(28,"esi"));
-+	&sbb	("ebx",&DWP(20,"ebp"));
-+	&sbb	("ecx",&DWP(24,"ebp"));
-+	&mov	(&DWP(16,"edi"),"eax");
-+	&sbb	("edx",&DWP(28,"ebp"));
-+	&mov	(&DWP(20,"edi"),"ebx");
-+	&sbb	("esi","esi");			# broadcast borrow bit
-+	&mov	(&DWP(24,"edi"),"ecx");
-+	&mov	(&DWP(28,"edi"),"edx");
-+
-+	# if a-b borrows, add modulus.
-+	#
-+	# Note that because mod has special form, i.e. consists of
-+	# 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	# assigning borrow bit to one register, %ebp, and its negative
-+	# to another, %esi. But we started by calculating %esi...
-+
-+	&mov	("eax",&DWP(0,"edi"));
-+	&mov	("ebp","esi");
-+	&mov	("ebx",&DWP(4,"edi"));
-+	&shr	("ebp",31);
-+	&mov	("ecx",&DWP(8,"edi"));
-+	&add	("eax","esi");
-+	&mov	("edx",&DWP(12,"edi"));
-+	&adc	("ebx","esi");
-+	&mov	(&DWP(0,"edi"),"eax");
-+	&adc	("ecx","esi");
-+	&mov	(&DWP(4,"edi"),"ebx");
-+	&adc	("edx",0);
-+	&mov	(&DWP(8,"edi"),"ecx");
-+	&mov	(&DWP(12,"edi"),"edx");
-+
-+	&mov	("eax",&DWP(16,"edi"));
-+	&mov	("ebx",&DWP(20,"edi"));
-+	&mov	("ecx",&DWP(24,"edi"));
-+	&adc	("eax",0);
-+	&mov	("edx",&DWP(28,"edi"));
-+	&adc	("ebx",0);
-+	&mov	(&DWP(16,"edi"),"eax");
-+	&adc	("ecx","ebp");
-+	&mov	(&DWP(20,"edi"),"ebx");
-+	&adc	("edx","esi");
-+	&mov	(&DWP(24,"edi"),"ecx");
-+	&mov	(&DWP(28,"edi"),"edx");
-+
-+	&ret	();
-+&function_end_B("_ecp_nistz256_sub");
-+
-+########################################################################
-+# void ecp_nistz256_neg(BN_ULONG edi[8],const BN_ULONG esi[8]);
-+&function_begin("ecp_nistz256_neg");
-+	&mov	("ebp",&wparam(1));
-+	&mov	("edi",&wparam(0));
-+
-+	&xor	("eax","eax");
-+	&stack_push(8);
-+	&mov	(&DWP(0,"esp"),"eax");
-+	&mov	("esi","esp");
-+	&mov	(&DWP(4,"esp"),"eax");
-+	&mov	(&DWP(8,"esp"),"eax");
-+	&mov	(&DWP(12,"esp"),"eax");
-+	&mov	(&DWP(16,"esp"),"eax");
-+	&mov	(&DWP(20,"esp"),"eax");
-+	&mov	(&DWP(24,"esp"),"eax");
-+	&mov	(&DWP(28,"esp"),"eax");
-+	
-+	&call	("_ecp_nistz256_sub");
-+
-+	&stack_pop(8);
-+&function_end("ecp_nistz256_neg");
-+
-+&function_begin_B("_picup_eax");
-+	&mov	("eax",&DWP(0,"esp"));
-+	&ret	();
-+&function_end_B("_picup_eax");
-+
-+########################################################################
-+# void ecp_nistz256_to_mont(BN_ULONG edi[8],const BN_ULONG esi[8]);
-+&function_begin("ecp_nistz256_to_mont");
-+	&mov	("esi",&wparam(1));
-+	&call	("_picup_eax");
-+    &set_label("pic");
-+	&lea	("ebp",&DWP(&label("RR")."-".&label("pic"),"eax"));
-+						if ($sse2) {
-+	&picmeup("eax","OPENSSL_ia32cap_P","eax",&label("pic"));
-+	&mov	("eax",&DWP(0,"eax"));		}
-+	&mov	("edi",&wparam(0));
-+	&call	("_ecp_nistz256_mul_mont");
-+&function_end("ecp_nistz256_to_mont");
-+
-+########################################################################
-+# void ecp_nistz256_from_mont(BN_ULONG edi[8],const BN_ULONG esi[8]);
-+&function_begin("ecp_nistz256_from_mont");
-+	&mov	("esi",&wparam(1));
-+	&call	("_picup_eax");
-+    &set_label("pic");
-+	&lea	("ebp",&DWP(&label("ONE")."-".&label("pic"),"eax"));
-+						if ($sse2) {
-+	&picmeup("eax","OPENSSL_ia32cap_P","eax",&label("pic"));
-+	&mov	("eax",&DWP(0,"eax"));		}
-+	&mov	("edi",&wparam(0));
-+	&call	("_ecp_nistz256_mul_mont");
-+&function_end("ecp_nistz256_from_mont");
-+
-+########################################################################
-+# void ecp_nistz256_mul_mont(BN_ULONG edi[8],const BN_ULONG esi[8],
-+#					     const BN_ULONG ebp[8]);
-+&function_begin("ecp_nistz256_mul_mont");
-+	&mov	("esi",&wparam(1));
-+	&mov	("ebp",&wparam(2));
-+						if ($sse2) {
-+	&call	("_picup_eax");
-+    &set_label("pic");
-+	&picmeup("eax","OPENSSL_ia32cap_P","eax",&label("pic"));
-+	&mov	("eax",&DWP(0,"eax"));		}
-+	&mov	("edi",&wparam(0));
-+	&call	("_ecp_nistz256_mul_mont");
-+&function_end("ecp_nistz256_mul_mont");
-+
-+########################################################################
-+# void ecp_nistz256_sqr_mont(BN_ULONG edi[8],const BN_ULONG esi[8]);
-+&function_begin("ecp_nistz256_sqr_mont");
-+	&mov	("esi",&wparam(1));
-+						if ($sse2) {
-+	&call	("_picup_eax");
-+    &set_label("pic");
-+	&picmeup("eax","OPENSSL_ia32cap_P","eax",&label("pic"));
-+	&mov	("eax",&DWP(0,"eax"));		}
-+	&mov	("edi",&wparam(0));
-+	&mov	("ebp","esi");
-+	&call	("_ecp_nistz256_mul_mont");
-+&function_end("ecp_nistz256_sqr_mont");
-+
-+&function_begin_B("_ecp_nistz256_mul_mont");
-+						if ($sse2) {
-+	&and	("eax",1<<24|1<<26);
-+	&cmp	("eax",1<<24|1<<26);		# see if XMM+SSE2 is on
-+	&jne	(&label("mul_mont_ialu"));
-+
-+	########################################
-+	# SSE2 code path featuring 32x16-bit
-+	# multiplications is ~2x faster than
-+	# IALU counterpart (except on Atom)...
-+	########################################
-+	# stack layout:
-+	# +------------------------------------+< %esp
-+	# | 7 16-byte temporary XMM words,     |
-+	# | "sliding" toward lower address     |
-+	# .                                    .
-+	# +------------------------------------+
-+	# | unused XMM word                    |
-+	# +------------------------------------+< +128,%ebx
-+	# | 8 16-byte XMM words holding copies |
-+	# | of a[i]<<64|a[i]                   |
-+	# .                                    .
-+	# .                                    .
-+	# +------------------------------------+< +256
-+	&mov	("edx","esp");
-+	&sub	("esp",0x100);
-+
-+	&movd	("xmm7",&DWP(0,"ebp"));		# b[0] -> 0000.00xy
-+	&lea	("ebp",&DWP(4,"ebp"));
-+	&pcmpeqd("xmm6","xmm6");
-+	&psrlq	("xmm6",48);			# compose 0xffff<<64|0xffff
-+
-+	&pshuflw("xmm7","xmm7",0b11011100);	# 0000.00xy -> 0000.0x0y
-+	&and	("esp",-64);
-+	&pshufd	("xmm7","xmm7",0b11011100);	# 0000.0x0y -> 000x.000y
-+	&lea	("ebx",&DWP(0x80,"esp"));
-+
-+	&movd	("xmm0",&DWP(4*0,"esi"));	# a[0] -> 0000.00xy
-+	&pshufd	("xmm0","xmm0",0b11001100);	# 0000.00xy -> 00xy.00xy
-+	&movd	("xmm1",&DWP(4*1,"esi"));	# a[1] -> ...
-+	&movdqa	(&QWP(0x00,"ebx"),"xmm0");	# offload converted a[0]
-+	&pmuludq("xmm0","xmm7");		# a[0]*b[0]
-+
-+	&movd	("xmm2",&DWP(4*2,"esi"));
-+	&pshufd	("xmm1","xmm1",0b11001100);
-+	&movdqa	(&QWP(0x10,"ebx"),"xmm1");
-+	&pmuludq("xmm1","xmm7");		# a[1]*b[0]
-+
-+	 &movq	("xmm4","xmm0");		# clear upper 64 bits
-+	 &pslldq("xmm4",6);
-+	 &paddq	("xmm4","xmm0");
-+	 &movdqa("xmm5","xmm4");
-+	 &psrldq("xmm4",10);			# upper 32 bits of a[0]*b[0]
-+	 &pand	("xmm5","xmm6");		# lower 32 bits of a[0]*b[0]
-+
-+	# Upper half of a[0]*b[i] is carried into next multiplication
-+	# iteration, while lower one "participates" in actual reduction.
-+	# Normally latter is done by accumulating result of multiplication
-+	# of modulus by "magic" digit, but thanks to special form of modulus
-+	# and "magic" digit it can be performed only with additions and
-+	# subtractions (see note in IALU section below). Note that we are
-+	# not bothered with carry bits, they are accumulated in "flatten"
-+	# phase after all multiplications and reductions.
-+
-+	&movd	("xmm3",&DWP(4*3,"esi"));
-+	&pshufd	("xmm2","xmm2",0b11001100);
-+	&movdqa	(&QWP(0x20,"ebx"),"xmm2");
-+	&pmuludq("xmm2","xmm7");		# a[2]*b[0]
-+	 &paddq	("xmm1","xmm4");		# a[1]*b[0]+hw(a[0]*b[0]), carry
-+	&movdqa	(&QWP(0x00,"esp"),"xmm1");	# t[0]
-+
-+	&movd	("xmm0",&DWP(4*4,"esi"));
-+	&pshufd	("xmm3","xmm3",0b11001100);
-+	&movdqa	(&QWP(0x30,"ebx"),"xmm3");
-+	&pmuludq("xmm3","xmm7");		# a[3]*b[0]
-+	&movdqa	(&QWP(0x10,"esp"),"xmm2");
-+
-+	&movd	("xmm1",&DWP(4*5,"esi"));
-+	&pshufd	("xmm0","xmm0",0b11001100);
-+	&movdqa	(&QWP(0x40,"ebx"),"xmm0");
-+	&pmuludq("xmm0","xmm7");		# a[4]*b[0]
-+	 &paddq	("xmm3","xmm5");		# a[3]*b[0]+lw(a[0]*b[0]), reduction step
-+	&movdqa	(&QWP(0x20,"esp"),"xmm3");
-+
-+	&movd	("xmm2",&DWP(4*6,"esi"));
-+	&pshufd	("xmm1","xmm1",0b11001100);
-+	&movdqa	(&QWP(0x50,"ebx"),"xmm1");
-+	&pmuludq("xmm1","xmm7");		# a[5]*b[0]
-+	&movdqa	(&QWP(0x30,"esp"),"xmm0");
-+	 &pshufd("xmm4","xmm5",0b10110001);	# xmm4 = xmm5<<32, reduction step
-+
-+	&movd	("xmm3",&DWP(4*7,"esi"));
-+	&pshufd	("xmm2","xmm2",0b11001100);
-+	&movdqa	(&QWP(0x60,"ebx"),"xmm2");
-+	&pmuludq("xmm2","xmm7");		# a[6]*b[0]
-+	&movdqa	(&QWP(0x40,"esp"),"xmm1");
-+	 &psubq	("xmm4","xmm5");		# xmm4 = xmm5*0xffffffff, reduction step
-+
-+	&movd	("xmm0",&DWP(0,"ebp"));		# b[1] -> 0000.00xy
-+	&pshufd	("xmm3","xmm3",0b11001100);
-+	&movdqa	(&QWP(0x70,"ebx"),"xmm3");
-+	&pmuludq("xmm3","xmm7");		# a[7]*b[0]
-+
-+	&pshuflw("xmm7","xmm0",0b11011100);	# 0000.00xy -> 0000.0x0y
-+	&movdqa	("xmm0",&QWP(0x00,"ebx"));	# pre-load converted a[0]
-+	&pshufd	("xmm7","xmm7",0b11011100);	# 0000.0x0y -> 000x.000y
-+
-+	&mov	("ecx",6);
-+	&lea	("ebp",&DWP(4,"ebp"));
-+	&jmp	(&label("madd_sse2"));
-+
-+&set_label("madd_sse2",16);
-+	 &paddq	("xmm2","xmm5");		# a[6]*b[i-1]+lw(a[0]*b[i-1]), reduction step [modulo-scheduled]
-+	 &paddq	("xmm3","xmm4");		# a[7]*b[i-1]+lw(a[0]*b[i-1])*0xffffffff, reduction step [modulo-scheduled]
-+	&movdqa	("xmm1",&QWP(0x10,"ebx"));
-+	&pmuludq("xmm0","xmm7");		# a[0]*b[i]
-+	 &movdqa(&QWP(0x50,"esp"),"xmm2");
-+
-+	&movdqa	("xmm2",&QWP(0x20,"ebx"));
-+	&pmuludq("xmm1","xmm7");		# a[1]*b[i]
-+	 &movdqa(&QWP(0x60,"esp"),"xmm3");
-+	&paddq	("xmm0",&QWP(0x00,"esp"));
-+
-+	&movdqa	("xmm3",&QWP(0x30,"ebx"));
-+	&pmuludq("xmm2","xmm7");		# a[2]*b[i]
-+	 &movq	("xmm4","xmm0");		# clear upper 64 bits
-+	 &pslldq("xmm4",6);
-+	&paddq	("xmm1",&QWP(0x10,"esp"));
-+	 &paddq	("xmm4","xmm0");
-+	 &movdqa("xmm5","xmm4");
-+	 &psrldq("xmm4",10);			# upper 33 bits of a[0]*b[i]+t[0]
-+
-+	&movdqa	("xmm0",&QWP(0x40,"ebx"));
-+	&pmuludq("xmm3","xmm7");		# a[3]*b[i]
-+	 &paddq	("xmm1","xmm4");		# a[1]*b[i]+hw(a[0]*b[i]), carry
-+	&paddq	("xmm2",&QWP(0x20,"esp"));
-+	&movdqa	(&QWP(0x00,"esp"),"xmm1");
-+
-+	&movdqa	("xmm1",&QWP(0x50,"ebx"));
-+	&pmuludq("xmm0","xmm7");		# a[4]*b[i]
-+	&paddq	("xmm3",&QWP(0x30,"esp"));
-+	&movdqa	(&QWP(0x10,"esp"),"xmm2");
-+	 &pand	("xmm5","xmm6");		# lower 32 bits of a[0]*b[i]
-+
-+	&movdqa	("xmm2",&QWP(0x60,"ebx"));
-+	&pmuludq("xmm1","xmm7");		# a[5]*b[i]
-+	 &paddq	("xmm3","xmm5");		# a[3]*b[i]+lw(a[0]*b[i]), reduction step
-+	&paddq	("xmm0",&QWP(0x40,"esp"));
-+	&movdqa	(&QWP(0x20,"esp"),"xmm3");
-+	 &pshufd("xmm4","xmm5",0b10110001);	# xmm4 = xmm5<<32, reduction step
-+
-+	&movdqa	("xmm3","xmm7");
-+	&pmuludq("xmm2","xmm7");		# a[6]*b[i]
-+	 &movd	("xmm7",&DWP(0,"ebp"));		# b[i++] -> 0000.00xy
-+	 &lea	("ebp",&DWP(4,"ebp"));
-+	&paddq	("xmm1",&QWP(0x50,"esp"));
-+	 &psubq	("xmm4","xmm5");		# xmm4 = xmm5*0xffffffff, reduction step
-+	&movdqa	(&QWP(0x30,"esp"),"xmm0");
-+	 &pshuflw("xmm7","xmm7",0b11011100);	# 0000.00xy -> 0000.0x0y
-+
-+	&pmuludq("xmm3",&QWP(0x70,"ebx"));	# a[7]*b[i]
-+	 &pshufd("xmm7","xmm7",0b11011100);	# 0000.0x0y -> 000x.000y
-+	 &movdqa("xmm0",&QWP(0x00,"ebx"));	# pre-load converted a[0]
-+	&movdqa	(&QWP(0x40,"esp"),"xmm1");
-+	&paddq	("xmm2",&QWP(0x60,"esp"));
-+
-+	&dec	("ecx");
-+	&jnz	(&label("madd_sse2"));
-+
-+	 &paddq	("xmm2","xmm5");		# a[6]*b[6]+lw(a[0]*b[6]), reduction step [modulo-scheduled]
-+	 &paddq	("xmm3","xmm4");		# a[7]*b[6]+lw(a[0]*b[6])*0xffffffff, reduction step [modulo-scheduled]
-+	&movdqa	("xmm1",&QWP(0x10,"ebx"));
-+	&pmuludq("xmm0","xmm7");		# a[0]*b[7]
-+	 &movdqa(&QWP(0x50,"esp"),"xmm2");
-+
-+	&movdqa	("xmm2",&QWP(0x20,"ebx"));
-+	&pmuludq("xmm1","xmm7");		# a[1]*b[7]
-+	 &movdqa(&QWP(0x60,"esp"),"xmm3");
-+	&paddq	("xmm0",&QWP(0x00,"esp"));
-+
-+	&movdqa	("xmm3",&QWP(0x30,"ebx"));
-+	&pmuludq("xmm2","xmm7");		# a[2]*b[7]
-+	 &movq	("xmm4","xmm0");		# clear upper 64 bits
-+	 &pslldq("xmm4",6);
-+	&paddq	("xmm1",&QWP(0x10,"esp"));
-+	 &paddq	("xmm4","xmm0");
-+	 &movdqa("xmm5","xmm4");
-+	 &psrldq("xmm4",10);			# upper 33 bits of a[0]*b[i]+t[0]
-+
-+	&movdqa	("xmm0",&QWP(0x40,"ebx"));
-+	&pmuludq("xmm3","xmm7");		# a[3]*b[7]
-+	 &paddq	("xmm1","xmm4");		# a[1]*b[7]+hw(a[0]*b[7]), carry
-+	&paddq	("xmm2",&QWP(0x20,"esp"));
-+	&movdqa	(&QWP(0x00,"esp"),"xmm1");
-+
-+	&movdqa	("xmm1",&QWP(0x50,"ebx"));
-+	&pmuludq("xmm0","xmm7");		# a[4]*b[7]
-+	&paddq	("xmm3",&QWP(0x30,"esp"));
-+	&movdqa	(&QWP(0x10,"esp"),"xmm2");
-+	 &pand	("xmm5","xmm6");		# lower 32 bits of a[0]*b[i]
-+
-+	&movdqa	("xmm2",&QWP(0x60,"ebx"));
-+	&pmuludq("xmm1","xmm7");		# a[5]*b[7]
-+	 &paddq	("xmm3","xmm5");		# reduction step
-+	&paddq	("xmm0",&QWP(0x40,"esp"));
-+	&movdqa	(&QWP(0x20,"esp"),"xmm3");
-+	 &pshufd("xmm4","xmm5",0b10110001);	# xmm4 = xmm5<<32, reduction step
-+
-+	&movdqa	("xmm3",&QWP(0x70,"ebx"));
-+	&pmuludq("xmm2","xmm7");		# a[6]*b[7]
-+	&paddq	("xmm1",&QWP(0x50,"esp"));
-+	 &psubq	("xmm4","xmm5");		# xmm4 = xmm5*0xffffffff, reduction step
-+	&movdqa	(&QWP(0x30,"esp"),"xmm0");
-+
-+	&pmuludq("xmm3","xmm7");		# a[7]*b[7]
-+	&pcmpeqd("xmm7","xmm7");
-+	&movdqa	("xmm0",&QWP(0x00,"esp"));
-+	&pslldq	("xmm7",8);
-+	&movdqa	(&QWP(0x40,"esp"),"xmm1");
-+	&paddq	("xmm2",&QWP(0x60,"esp"));
-+
-+	 &paddq	("xmm2","xmm5");		# a[6]*b[7]+lw(a[0]*b[7]), reduction step
-+	 &paddq	("xmm3","xmm4");		# a[6]*b[7]+lw(a[0]*b[7])*0xffffffff, reduction step
-+	 &movdqa(&QWP(0x50,"esp"),"xmm2");
-+	 &movdqa(&QWP(0x60,"esp"),"xmm3");
-+
-+	&movdqa	("xmm1",&QWP(0x10,"esp"));
-+	&movdqa	("xmm2",&QWP(0x20,"esp"));
-+	&movdqa	("xmm3",&QWP(0x30,"esp"));
-+
-+	&movq	("xmm4","xmm0");		# "flatten"
-+	&pand	("xmm0","xmm7");
-+	&xor	("ebp","ebp");
-+	&pslldq	("xmm4",6);
-+	 &movq	("xmm5","xmm1");
-+	&paddq	("xmm0","xmm4");
-+	 &pand	("xmm1","xmm7");
-+	&psrldq	("xmm0",6);
-+	&movd	("eax","xmm0");
-+	&psrldq	("xmm0",4);
-+
-+	&paddq	("xmm5","xmm0");
-+	&movdqa	("xmm0",&QWP(0x40,"esp"));
-+	&sub	("eax",-1);			# start subtracting modulus,
-+						# this is used to determine
-+						# if result is larger/smaller
-+						# than modulus (see below)
-+	&pslldq	("xmm5",6);
-+	 &movq	("xmm4","xmm2");
-+	&paddq	("xmm1","xmm5");
-+	 &pand	("xmm2","xmm7");
-+	&psrldq	("xmm1",6);
-+	&mov	(&DWP(4*0,"edi"),"eax");
-+	&movd	("eax","xmm1");
-+	&psrldq	("xmm1",4);
-+
-+	&paddq	("xmm4","xmm1");
-+	&movdqa	("xmm1",&QWP(0x50,"esp"));
-+	&sbb	("eax",-1);
-+	&pslldq	("xmm4",6);
-+	 &movq	("xmm5","xmm3");
-+	&paddq	("xmm2","xmm4");
-+	 &pand	("xmm3","xmm7");
-+	&psrldq	("xmm2",6);
-+	&mov	(&DWP(4*1,"edi"),"eax");
-+	&movd	("eax","xmm2");
-+	&psrldq	("xmm2",4);
-+
-+	&paddq	("xmm5","xmm2");
-+	&movdqa	("xmm2",&QWP(0x60,"esp"));
-+	&sbb	("eax",-1);
-+	&pslldq	("xmm5",6);
-+	 &movq	("xmm4","xmm0");
-+	&paddq	("xmm3","xmm5");
-+	 &pand	("xmm0","xmm7");
-+	&psrldq	("xmm3",6);
-+	&mov	(&DWP(4*2,"edi"),"eax");
-+	&movd	("eax","xmm3");
-+	&psrldq	("xmm3",4);
-+
-+	&paddq	("xmm4","xmm3");
-+	&sbb	("eax",0);
-+	&pslldq	("xmm4",6);
-+	 &movq	("xmm5","xmm1");
-+	&paddq	("xmm0","xmm4");
-+	 &pand	("xmm1","xmm7");
-+	&psrldq	("xmm0",6);
-+	&mov	(&DWP(4*3,"edi"),"eax");
-+	&movd	("eax","xmm0");
-+	&psrldq	("xmm0",4);
-+
-+	&paddq	("xmm5","xmm0");
-+	&sbb	("eax",0);
-+	&pslldq	("xmm5",6);
-+	 &movq	("xmm4","xmm2");
-+	&paddq	("xmm1","xmm5");
-+	 &pand	("xmm2","xmm7");
-+	&psrldq	("xmm1",6);
-+	&movd	("ebx","xmm1");
-+	&psrldq	("xmm1",4);
-+	&mov	("esp","edx");
-+
-+	&paddq	("xmm4","xmm1");
-+	&pslldq	("xmm4",6);
-+	&paddq	("xmm2","xmm4");
-+	&psrldq	("xmm2",6);
-+	&movd	("ecx","xmm2");
-+	&psrldq	("xmm2",4);
-+	&sbb	("ebx",0);
-+	&movd	("edx","xmm2");
-+	&pextrw	("esi","xmm2",2);		# top-most overflow bit
-+	&sbb	("ecx",1);
-+	&sbb	("edx",-1);
-+	&sbb	("esi",0);			# borrow from subtraction
-+
-+	# Final step is "if result > mod, subtract mod", and at this point
-+	# we have result - mod written to output buffer, as well as borrow
-+	# bit from this subtraction, and if borrow bit is set, we add
-+	# modulus back.
-+	#
-+	# Note that because mod has special form, i.e. consists of
-+	# 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	# assigning borrow bit to one register, %ebp, and its negative
-+	# to another, %esi. But we started by calculating %esi...
-+
-+	&sub	("ebp","esi");
-+	&add	(&DWP(4*0,"edi"),"esi");	# add modulus or zero
-+	&adc	(&DWP(4*1,"edi"),"esi");
-+	&adc	(&DWP(4*2,"edi"),"esi");
-+	&adc	(&DWP(4*3,"edi"),0);
-+	&adc	("eax",0);
-+	&adc	("ebx",0);
-+	&mov	(&DWP(4*4,"edi"),"eax");
-+	&adc	("ecx","ebp");
-+	&mov	(&DWP(4*5,"edi"),"ebx");
-+	&adc	("edx","esi");
-+	&mov	(&DWP(4*6,"edi"),"ecx");
-+	&mov	(&DWP(4*7,"edi"),"edx");
-+
-+	&ret	();
-+
-+&set_label("mul_mont_ialu",16);			}
-+
-+	########################################
-+	# IALU code path suitable for all CPUs.
-+	########################################
-+	# stack layout:
-+	# +------------------------------------+< %esp
-+	# | 8 32-bit temporary words, accessed |
-+	# | as circular buffer                 |
-+	# .                                    .
-+	# .                                    .
-+	# +------------------------------------+< +32
-+	# | offloaded destination pointer      |
-+	# +------------------------------------+
-+	# | unused                             |
-+	# +------------------------------------+< +40
-+	&sub	("esp",10*4);
-+
-+	&mov	("eax",&DWP(0*4,"esi"));		# a[0]
-+	&mov	("ebx",&DWP(0*4,"ebp"));		# b[0]
-+	&mov	(&DWP(8*4,"esp"),"edi");		# off-load dst ptr
-+
-+	&mul	("ebx");				# a[0]*b[0]
-+	&mov	(&DWP(0*4,"esp"),"eax");		# t[0]
-+	&mov	("eax",&DWP(1*4,"esi"));
-+	&mov	("ecx","edx")
-+
-+	&mul	("ebx");				# a[1]*b[0]
-+	&add	("ecx","eax");
-+	&mov	("eax",&DWP(2*4,"esi"));
-+	&adc	("edx",0);
-+	&mov	(&DWP(1*4,"esp"),"ecx");		# t[1]
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[2]*b[0]
-+	&add	("ecx","eax");
-+	&mov	("eax",&DWP(3*4,"esi"));
-+	&adc	("edx",0);
-+	&mov	(&DWP(2*4,"esp"),"ecx");		# t[2]
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[3]*b[0]
-+	&add	("ecx","eax");
-+	&mov	("eax",&DWP(4*4,"esi"));
-+	&adc	("edx",0);
-+	&mov	(&DWP(3*4,"esp"),"ecx");		# t[3]
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[4]*b[0]
-+	&add	("ecx","eax");
-+	&mov	("eax",&DWP(5*4,"esi"));
-+	&adc	("edx",0);
-+	&mov	(&DWP(4*4,"esp"),"ecx");		# t[4]
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[5]*b[0]
-+	&add	("ecx","eax");
-+	&mov	("eax",&DWP(6*4,"esi"));
-+	&adc	("edx",0);
-+	&mov	(&DWP(5*4,"esp"),"ecx");		# t[5]
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[6]*b[0]
-+	&add	("ecx","eax");
-+	&mov	("eax",&DWP(7*4,"esi"));
-+	&adc	("edx",0);
-+	&mov	(&DWP(6*4,"esp"),"ecx");		# t[6]
-+	&mov	("ecx","edx");
-+
-+	&xor	("edi","edi");				# initial top-most carry
-+	&mul	("ebx");				# a[7]*b[0]
-+	&add	("ecx","eax");				# t[7]
-+	&mov	("eax",&DWP(0*4,"esp"));		# t[0]
-+	&adc	("edx",0);				# t[8]
-+
-+for ($i=0;$i<7;$i++) {
-+	my $j=$i+1;
-+
-+	# Reduction iteration is normally performed by accumulating
-+	# result of multiplication of modulus by "magic" digit [and
-+	# omitting least significant word, which is guaranteed to
-+	# be 0], but thanks to special form of modulus and "magic"
-+	# digit being equal to least significant word, it can be
-+	# performed with additions and subtractions alone. Indeed:
-+	#
-+	#        ffff.0001.0000.0000.0000.ffff.ffff.ffff
-+	# *                                         abcd
-+	# + xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.abcd
-+	#
-+	# Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we
-+	# rewrite above as:
-+	#
-+	#   xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.abcd
-+	# + abcd.0000.abcd.0000.0000.abcd.0000.0000.0000
-+	# -      abcd.0000.0000.0000.0000.0000.0000.abcd
-+	#
-+	# or marking redundant operations:
-+	#
-+	#   xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.----
-+	# + abcd.0000.abcd.0000.0000.abcd.----.----.----
-+	# -      abcd.----.----.----.----.----.----.----
-+
-+	&add	(&DWP((($i+3)%8)*4,"esp"),"eax");	# t[3]+=t[0]
-+	&adc	(&DWP((($i+4)%8)*4,"esp"),0);		# t[4]+=0
-+	&adc	(&DWP((($i+5)%8)*4,"esp"),0);		# t[5]+=0
-+	&adc	(&DWP((($i+6)%8)*4,"esp"),"eax");	# t[6]+=t[0]
-+	&adc	("ecx",0);				# t[7]+=0
-+	&adc	("edx","eax");				# t[8]+=t[0]
-+	&adc	("edi",0);				# top-most carry
-+	 &mov	("ebx",&DWP($j*4,"ebp"));		# b[i]
-+	&sub	("ecx","eax");				# t[7]-=t[0]
-+	 &mov	("eax",&DWP(0*4,"esi"));		# a[0]
-+	&sbb	("edx",0);				# t[8]-=0
-+	&mov	(&DWP((($i+7)%8)*4,"esp"),"ecx");
-+	&sbb	("edi",0);				# top-most carry,
-+							# keep in mind that
-+							# netto result is
-+							# *addition* of value
-+							# with (abcd<<32)-abcd
-+							# on top, so that
-+							# underflow is
-+							# impossible, because
-+							# (abcd<<32)-abcd
-+							# doesn't underflow
-+	&mov	(&DWP((($i+8)%8)*4,"esp"),"edx");
-+
-+	&mul	("ebx");				# a[0]*b[i]
-+	&add	("eax",&DWP((($j+0)%8)*4,"esp"));
-+	&adc	("edx",0);
-+	&mov	(&DWP((($j+0)%8)*4,"esp"),"eax");
-+	&mov	("eax",&DWP(1*4,"esi"));
-+	&mov	("ecx","edx")
-+
-+	&mul	("ebx");				# a[1]*b[i]
-+	&add	("ecx",&DWP((($j+1)%8)*4,"esp"));
-+	&adc	("edx",0);
-+	&add	("ecx","eax");
-+	&adc	("edx",0);
-+	&mov	("eax",&DWP(2*4,"esi"));
-+	&mov	(&DWP((($j+1)%8)*4,"esp"),"ecx");
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[2]*b[i]
-+	&add	("ecx",&DWP((($j+2)%8)*4,"esp"));
-+	&adc	("edx",0);
-+	&add	("ecx","eax");
-+	&adc	("edx",0);
-+	&mov	("eax",&DWP(3*4,"esi"));
-+	&mov	(&DWP((($j+2)%8)*4,"esp"),"ecx");
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[3]*b[i]
-+	&add	("ecx",&DWP((($j+3)%8)*4,"esp"));
-+	&adc	("edx",0);
-+	&add	("ecx","eax");
-+	&adc	("edx",0);
-+	&mov	("eax",&DWP(4*4,"esi"));
-+	&mov	(&DWP((($j+3)%8)*4,"esp"),"ecx");
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[4]*b[i]
-+	&add	("ecx",&DWP((($j+4)%8)*4,"esp"));
-+	&adc	("edx",0);
-+	&add	("ecx","eax");
-+	&adc	("edx",0);
-+	&mov	("eax",&DWP(5*4,"esi"));
-+	&mov	(&DWP((($j+4)%8)*4,"esp"),"ecx");
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[5]*b[i]
-+	&add	("ecx",&DWP((($j+5)%8)*4,"esp"));
-+	&adc	("edx",0);
-+	&add	("ecx","eax");
-+	&adc	("edx",0);
-+	&mov	("eax",&DWP(6*4,"esi"));
-+	&mov	(&DWP((($j+5)%8)*4,"esp"),"ecx");
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[6]*b[i]
-+	&add	("ecx",&DWP((($j+6)%8)*4,"esp"));
-+	&adc	("edx",0);
-+	&add	("ecx","eax");
-+	&adc	("edx",0);
-+	&mov	("eax",&DWP(7*4,"esi"));
-+	&mov	(&DWP((($j+6)%8)*4,"esp"),"ecx");
-+	&mov	("ecx","edx");
-+
-+	&mul	("ebx");				# a[7]*b[i]
-+	&add	("ecx",&DWP((($j+7)%8)*4,"esp"));
-+	&adc	("edx",0);
-+	&add	("ecx","eax");				# t[7]
-+	&mov	("eax",&DWP((($j+0)%8)*4,"esp"));	# t[0]
-+	&adc	("edx","edi");				# t[8]
-+	&mov	("edi",0);
-+	&adc	("edi",0);				# top-most carry
-+}
-+	&mov	("ebp",&DWP(8*4,"esp"));		# restore dst ptr
-+	&xor	("esi","esi");
-+	my $j=$i+1;
-+
-+	# last multiplication-less reduction
-+	&add	(&DWP((($i+3)%8)*4,"esp"),"eax");	# t[3]+=t[0]
-+	&adc	(&DWP((($i+4)%8)*4,"esp"),0);		# t[4]+=0
-+	&adc	(&DWP((($i+5)%8)*4,"esp"),0);		# t[5]+=0
-+	&adc	(&DWP((($i+6)%8)*4,"esp"),"eax");	# t[6]+=t[0]
-+	&adc	("ecx",0);				# t[7]+=0
-+	&adc	("edx","eax");				# t[8]+=t[0]
-+	&adc	("edi",0);				# top-most carry
-+	 &mov	("ebx",&DWP((($j+1)%8)*4,"esp"));
-+	&sub	("ecx","eax");				# t[7]-=t[0]
-+	 &mov	("eax",&DWP((($j+0)%8)*4,"esp"));
-+	&sbb	("edx",0);				# t[8]-=0
-+	&mov	(&DWP((($i+7)%8)*4,"esp"),"ecx");
-+	&sbb	("edi",0);				# top-most carry
-+	&mov	(&DWP((($i+8)%8)*4,"esp"),"edx");
-+
-+	# Final step is "if result > mod, subtract mod", but we do it
-+	# "other way around", namely write result - mod to output buffer
-+	# and if subtraction borrowed, add modulus back.
-+
-+	&mov	("ecx",&DWP((($j+2)%8)*4,"esp"));
-+	&sub	("eax",-1);
-+	&mov	("edx",&DWP((($j+3)%8)*4,"esp"));
-+	&sbb	("ebx",-1);
-+	&mov	(&DWP(0*4,"ebp"),"eax");
-+	&sbb	("ecx",-1);
-+	&mov	(&DWP(1*4,"ebp"),"ebx");
-+	&sbb	("edx",0);
-+	&mov	(&DWP(2*4,"ebp"),"ecx");
-+	&mov	(&DWP(3*4,"ebp"),"edx");
-+
-+	&mov	("eax",&DWP((($j+4)%8)*4,"esp"));
-+	&mov	("ebx",&DWP((($j+5)%8)*4,"esp"));
-+	&mov	("ecx",&DWP((($j+6)%8)*4,"esp"));
-+	&sbb	("eax",0);
-+	&mov	("edx",&DWP((($j+7)%8)*4,"esp"));
-+	&sbb	("ebx",0);
-+	&sbb	("ecx",1);
-+	&sbb	("edx",-1);
-+	&sbb	("edi",0);
-+
-+	# Note that because mod has special form, i.e. consists of
-+	# 0xffffffff, 1 and 0s, we can conditionally synthesize it by
-+	# assigning borrow bit to one register, %ebp, and its negative
-+	# to another, %esi. But we started by calculating %esi...
-+
-+	&sub	("esi","edi");
-+	&add	(&DWP(0*4,"ebp"),"edi");		# add modulus or zero
-+	&adc	(&DWP(1*4,"ebp"),"edi");
-+	&adc	(&DWP(2*4,"ebp"),"edi");
-+	&adc	(&DWP(3*4,"ebp"),0);
-+	&adc	("eax",0);
-+	&adc	("ebx",0);
-+	&mov	(&DWP(4*4,"ebp"),"eax");
-+	&adc	("ecx","esi");
-+	&mov	(&DWP(5*4,"ebp"),"ebx");
-+	&adc	("edx","edi");
-+	&mov	(&DWP(6*4,"ebp"),"ecx");
-+	&mov	("edi","ebp");				# fulfill contract
-+	&mov	(&DWP(7*4,"ebp"),"edx");
-+
-+	&add	("esp",10*4);
-+	&ret	();
-+&function_end_B("_ecp_nistz256_mul_mont");
-+
-+########################################################################
-+# void ecp_nistz256_scatter_w5(void *edi,const P256_POINT *esi,
-+#					 int ebp);
-+&function_begin("ecp_nistz256_scatter_w5");
-+	&mov	("edi",&wparam(0));
-+	&mov	("esi",&wparam(1));
-+	&mov	("ebp",&wparam(2));
-+
-+	&lea	("edi",&DWP(128-4,"edi","ebp",4));
-+	&mov	("ebp",96/16);
-+&set_label("scatter_w5_loop");
-+	&mov	("eax",&DWP(0,"esi"));
-+	&mov	("ebx",&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&mov	("edx",&DWP(12,"esi"));
-+	&lea	("esi",&DWP(16,"esi"));
-+	&mov	(&DWP(64*0-128,"edi"),"eax");
-+	&mov	(&DWP(64*1-128,"edi"),"ebx");
-+	&mov	(&DWP(64*2-128,"edi"),"ecx");
-+	&mov	(&DWP(64*3-128,"edi"),"edx");
-+	&lea	("edi",&DWP(64*4,"edi"));
-+	&dec	("ebp");
-+	&jnz	(&label("scatter_w5_loop"));
-+&function_end("ecp_nistz256_scatter_w5");
-+
-+########################################################################
-+# void ecp_nistz256_gather_w5(P256_POINT *edi,const void *esi,
-+#					      int ebp);
-+&function_begin("ecp_nistz256_gather_w5");
-+	&mov	("esi",&wparam(1));
-+	&mov	("ebp",&wparam(2));
-+
-+	&lea	("esi",&DWP(0,"esi","ebp",4));
-+	&neg	("ebp");
-+	&sar	("ebp",31);
-+	&mov	("edi",&wparam(0));
-+	&lea	("esi",&DWP(0,"esi","ebp",4));
-+
-+    for($i=0;$i<24;$i+=4) {
-+	&mov	("eax",&DWP(64*($i+0),"esi"));
-+	&mov	("ebx",&DWP(64*($i+1),"esi"));
-+	&mov	("ecx",&DWP(64*($i+2),"esi"));
-+	&mov	("edx",&DWP(64*($i+3),"esi"));
-+	&and	("eax","ebp");
-+	&and	("ebx","ebp");
-+	&and	("ecx","ebp");
-+	&and	("edx","ebp");
-+	&mov	(&DWP(4*($i+0),"edi"),"eax");
-+	&mov	(&DWP(4*($i+1),"edi"),"ebx");
-+	&mov	(&DWP(4*($i+2),"edi"),"ecx");
-+	&mov	(&DWP(4*($i+3),"edi"),"edx");
-+    }
-+&function_end("ecp_nistz256_gather_w5");
-+
-+########################################################################
-+# void ecp_nistz256_scatter_w7(void *edi,const P256_POINT_AFFINE *esi,
-+#					 int ebp);
-+&function_begin("ecp_nistz256_scatter_w7");
-+	&mov	("edi",&wparam(0));
-+	&mov	("esi",&wparam(1));
-+	&mov	("ebp",&wparam(2));
-+
-+	&lea	("edi",&DWP(-1,"edi","ebp"));
-+	&mov	("ebp",64/4);
-+&set_label("scatter_w7_loop");
-+	&mov	("eax",&DWP(0,"esi"));
-+	&lea	("esi",&DWP(4,"esi"));
-+	&mov	(&BP(64*0,"edi"),"al");
-+	&mov	(&BP(64*1,"edi"),"ah");
-+	&shr	("eax",16);
-+	&mov	(&BP(64*2,"edi"),"al");
-+	&mov	(&BP(64*3,"edi"),"ah");
-+	&lea	("edi",&DWP(64*4,"edi"));
-+	&dec	("ebp");
-+	&jnz	(&label("scatter_w7_loop"));
-+&function_end("ecp_nistz256_scatter_w7");
-+
-+########################################################################
-+# void ecp_nistz256_gather_w7(P256_POINT_AFFINE *edi,const void *esi,
-+#						     int ebp);
-+&function_begin("ecp_nistz256_gather_w7");
-+	&mov	("esi",&wparam(1));
-+	&mov	("ebp",&wparam(2));
-+
-+	&add	("esi","ebp");
-+	&neg	("ebp"),
-+	&sar	("ebp",31);
-+	&mov	("edi",&wparam(0));
-+	&lea	("esi",&DWP(0,"esi","ebp"));
-+
-+    for($i=0;$i<64;$i+=4) {
-+	&movz	("eax",&BP(64*($i+0),"esi"));
-+	&movz	("ebx",&BP(64*($i+1),"esi"));
-+	&movz	("ecx",&BP(64*($i+2),"esi"));
-+	&and	("eax","ebp");
-+	&movz	("edx",&BP(64*($i+3),"esi"));
-+	&and	("ebx","ebp");
-+	&mov	(&BP($i+0,"edi"),"al");
-+	&and	("ecx","ebp");
-+	&mov	(&BP($i+1,"edi"),"bl");
-+	&and	("edx","ebp");
-+	&mov	(&BP($i+2,"edi"),"cl");
-+	&mov	(&BP($i+3,"edi"),"dl");
-+    }
-+&function_end("ecp_nistz256_gather_w7");
-+
-+########################################################################
-+# following subroutines are "literal" implementation of those found in
-+# ecp_nistz256.c
-+#
-+########################################################################
-+# void ecp_nistz256_point_double(P256_POINT *out,const P256_POINT *inp);
-+#
-+&static_label("point_double_shortcut");
-+&function_begin("ecp_nistz256_point_double");
-+{   my ($S,$M,$Zsqr,$in_x,$tmp0)=map(32*$_,(0..4));
-+
-+	&mov	("esi",&wparam(1));
-+
-+	# above map() describes stack layout with 5 temporary
-+	# 256-bit vectors on top, then we take extra word for
-+	# OPENSSL_ia32cap_P copy.
-+	&stack_push(8*5+1);
-+						if ($sse2) {
-+	&call	("_picup_eax");
-+    &set_label("pic");
-+	&picmeup("edx","OPENSSL_ia32cap_P","eax",&label("pic"));
-+	&mov	("ebp",&DWP(0,"edx"));		}
-+
-+&set_label("point_double_shortcut");
-+	&mov	("eax",&DWP(0,"esi"));		# copy in_x
-+	&mov	("ebx",&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&mov	("edx",&DWP(12,"esi"));
-+	&mov	(&DWP($in_x+0,"esp"),"eax");
-+	&mov	(&DWP($in_x+4,"esp"),"ebx");
-+	&mov	(&DWP($in_x+8,"esp"),"ecx");
-+	&mov	(&DWP($in_x+12,"esp"),"edx");
-+	&mov	("eax",&DWP(16,"esi"));
-+	&mov	("ebx",&DWP(20,"esi"));
-+	&mov	("ecx",&DWP(24,"esi"));
-+	&mov	("edx",&DWP(28,"esi"));
-+	&mov	(&DWP($in_x+16,"esp"),"eax");
-+	&mov	(&DWP($in_x+20,"esp"),"ebx");
-+	&mov	(&DWP($in_x+24,"esp"),"ecx");
-+	&mov	(&DWP($in_x+28,"esp"),"edx");
-+	&mov	(&DWP(32*5,"esp"),"ebp");	# OPENSSL_ia32cap_P copy
-+
-+	&lea	("ebp",&DWP(32,"esi"));
-+	&lea	("esi",&DWP(32,"esi"));
-+	&lea	("edi",&DWP($S,"esp"));
-+	&call	("_ecp_nistz256_add");		# p256_mul_by_2(S, in_y);
-+
-+	&mov	("eax",&DWP(32*5,"esp"));	# OPENSSL_ia32cap_P copy
-+	&mov	("esi",64);
-+	&add	("esi",&wparam(1));
-+	&lea	("edi",&DWP($Zsqr,"esp"));
-+	&mov	("ebp","esi");
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(Zsqr, in_z);
-+
-+	&mov	("eax",&DWP(32*5,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($S,"esp"));
-+	&lea	("ebp",&DWP($S,"esp"));
-+	&lea	("edi",&DWP($S,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(S, S);
-+
-+	&mov	("eax",&DWP(32*5,"esp"));	# OPENSSL_ia32cap_P copy
-+	&mov	("ebp",&wparam(1));
-+	&lea	("esi",&DWP(32,"ebp"));
-+	&lea	("ebp",&DWP(64,"ebp"));
-+	&lea	("edi",&DWP($tmp0,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(tmp0, in_z, in_y);
-+
-+	&lea	("esi",&DWP($in_x,"esp"));
-+	&lea	("ebp",&DWP($Zsqr,"esp"));
-+	&lea	("edi",&DWP($M,"esp"));
-+	&call	("_ecp_nistz256_add");		# p256_add(M, in_x, Zsqr);
-+
-+	&mov	("edi",64);
-+	&lea	("esi",&DWP($tmp0,"esp"));
-+	&lea	("ebp",&DWP($tmp0,"esp"));
-+	&add	("edi",&wparam(0));
-+	&call	("_ecp_nistz256_add");		# p256_mul_by_2(res_z, tmp0);
-+
-+	&lea	("esi",&DWP($in_x,"esp"));
-+	&lea	("ebp",&DWP($Zsqr,"esp"));
-+	&lea	("edi",&DWP($Zsqr,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(Zsqr, in_x, Zsqr);
-+
-+	&mov	("eax",&DWP(32*5,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($S,"esp"));
-+	&lea	("ebp",&DWP($S,"esp"));
-+	&lea	("edi",&DWP($tmp0,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(tmp0, S);
-+
-+	&mov	("eax",&DWP(32*5,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($M,"esp"));
-+	&lea	("ebp",&DWP($Zsqr,"esp"));
-+	&lea	("edi",&DWP($M,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(M, M, Zsqr);
-+
-+	&mov	("edi",32);
-+	&lea	("esi",&DWP($tmp0,"esp"));
-+	&add	("edi",&wparam(0));
-+	&call	("_ecp_nistz256_div_by_2");	# p256_div_by_2(res_y, tmp0);
-+
-+	&lea	("esi",&DWP($M,"esp"));
-+	&lea	("ebp",&DWP($M,"esp"));
-+	&lea	("edi",&DWP($tmp0,"esp"));
-+	&call	("_ecp_nistz256_add");		# 1/2 p256_mul_by_3(M, M);
-+
-+	&mov	("eax",&DWP(32*5,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in_x,"esp"));
-+	&lea	("ebp",&DWP($S,"esp"));
-+	&lea	("edi",&DWP($S,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(S, S, in_x);
-+
-+	&lea	("esi",&DWP($tmp0,"esp"));
-+	&lea	("ebp",&DWP($M,"esp"));
-+	&lea	("edi",&DWP($M,"esp"));
-+	&call	("_ecp_nistz256_add");		# 2/2 p256_mul_by_3(M, M);
-+
-+	&lea	("esi",&DWP($S,"esp"));
-+	&lea	("ebp",&DWP($S,"esp"));
-+	&lea	("edi",&DWP($tmp0,"esp"));
-+	&call	("_ecp_nistz256_add");		# p256_mul_by_2(tmp0, S);
-+
-+	&mov	("eax",&DWP(32*5,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($M,"esp"));
-+	&lea	("ebp",&DWP($M,"esp"));
-+	&mov	("edi",&wparam(0));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(res_x, M);
-+
-+	&mov	("esi","edi");			# %edi is still res_x here
-+	&lea	("ebp",&DWP($tmp0,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(res_x, res_x, tmp0);
-+
-+	&lea	("esi",&DWP($S,"esp"));
-+	&mov	("ebp","edi");			# %edi is still res_x
-+	&lea	("edi",&DWP($S,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(S, S, res_x);
-+
-+	&mov	("eax",&DWP(32*5,"esp"));	# OPENSSL_ia32cap_P copy
-+	&mov	("esi","edi");			# %edi is still &S
-+	&lea	("ebp",&DWP($M,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(S, S, M);
-+
-+	&mov	("ebp",32);
-+	&lea	("esi",&DWP($S,"esp"));
-+	&add	("ebp",&wparam(0));
-+	&mov	("edi","ebp");
-+	&call	("_ecp_nistz256_sub");		# p256_sub(res_y, S, res_y);
-+
-+	&stack_pop(8*5+1);
-+} &function_end("ecp_nistz256_point_double");
-+
-+########################################################################
-+# void ecp_nistz256_point_add(P256_POINT *out,const P256_POINT *in1,
-+#					      const P256_POINT *in2);
-+&function_begin("ecp_nistz256_point_add");
-+{   my ($res_x,$res_y,$res_z,
-+	$in1_x,$in1_y,$in1_z,
-+	$in2_x,$in2_y,$in2_z,
-+	$H,$Hsqr,$R,$Rsqr,$Hcub,
-+	$U1,$U2,$S1,$S2)=map(32*$_,(0..17));
-+    my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
-+
-+	&mov	("esi",&wparam(2));
-+
-+	# above map() describes stack layout with 18 temporary
-+	# 256-bit vectors on top, then we take extra words for
-+	# !in1infty, !in2infty, result of check for zero and
-+	# OPENSSL_ia32cap_P copy. [one unused word for padding]
-+	&stack_push(8*18+5);
-+						if ($sse2) {
-+	&call	("_picup_eax");
-+    &set_label("pic");
-+	&picmeup("edx","OPENSSL_ia32cap_P","eax",&label("pic"));
-+	&mov	("ebp",&DWP(0,"edx"));		}
-+
-+	&lea	("edi",&DWP($in2_x,"esp"));
-+    for($i=0;$i<96;$i+=16) {
-+	&mov	("eax",&DWP($i+0,"esi"));	# copy in2
-+	&mov	("ebx",&DWP($i+4,"esi"));
-+	&mov	("ecx",&DWP($i+8,"esi"));
-+	&mov	("edx",&DWP($i+12,"esi"));
-+	&mov	(&DWP($i+0,"edi"),"eax");
-+	&mov	(&DWP(32*18+12,"esp"),"ebp")	if ($i==0);
-+	&mov	("ebp","eax")			if ($i==64);
-+	&or	("ebp","eax")			if ($i>64);
-+	&mov	(&DWP($i+4,"edi"),"ebx");
-+	&or	("ebp","ebx")			if ($i>=64);
-+	&mov	(&DWP($i+8,"edi"),"ecx");
-+	&or	("ebp","ecx")			if ($i>=64);
-+	&mov	(&DWP($i+12,"edi"),"edx");
-+	&or	("ebp","edx")			if ($i>=64);
-+    }
-+	&xor	("eax","eax");
-+	&mov	("esi",&wparam(1));
-+	&sub	("eax","ebp");
-+	&or	("ebp","eax");
-+	&sar	("ebp",31);
-+	&mov	(&DWP(32*18+4,"esp"),"ebp");	# !in2infty
-+
-+	&lea	("edi",&DWP($in1_x,"esp"));
-+    for($i=0;$i<96;$i+=16) {
-+	&mov	("eax",&DWP($i+0,"esi"));	# copy in1
-+	&mov	("ebx",&DWP($i+4,"esi"));
-+	&mov	("ecx",&DWP($i+8,"esi"));
-+	&mov	("edx",&DWP($i+12,"esi"));
-+	&mov	(&DWP($i+0,"edi"),"eax");
-+	&mov	("ebp","eax")			if ($i==64);
-+	&or	("ebp","eax")			if ($i>64);
-+	&mov	(&DWP($i+4,"edi"),"ebx");
-+	&or	("ebp","ebx")			if ($i>=64);
-+	&mov	(&DWP($i+8,"edi"),"ecx");
-+	&or	("ebp","ecx")			if ($i>=64);
-+	&mov	(&DWP($i+12,"edi"),"edx");
-+	&or	("ebp","edx")			if ($i>=64);
-+    }
-+	&xor	("eax","eax");
-+	&sub	("eax","ebp");
-+	&or	("ebp","eax");
-+	&sar	("ebp",31);
-+	&mov	(&DWP(32*18+0,"esp"),"ebp");	# !in1infty
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in2_z,"esp"));
-+	&lea	("ebp",&DWP($in2_z,"esp"));
-+	&lea	("edi",&DWP($Z2sqr,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(Z2sqr, in2_z);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in1_z,"esp"));
-+	&lea	("ebp",&DWP($in1_z,"esp"));
-+	&lea	("edi",&DWP($Z1sqr,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(Z1sqr, in1_z);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($Z2sqr,"esp"));
-+	&lea	("ebp",&DWP($in2_z,"esp"));
-+	&lea	("edi",&DWP($S1,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(S1, Z2sqr, in2_z);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($Z1sqr,"esp"));
-+	&lea	("ebp",&DWP($in1_z,"esp"));
-+	&lea	("edi",&DWP($S2,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(S2, Z1sqr, in1_z);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in1_y,"esp"));
-+	&lea	("ebp",&DWP($S1,"esp"));
-+	&lea	("edi",&DWP($S1,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(S1, S1, in1_y);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in2_y,"esp"));
-+	&lea	("ebp",&DWP($S2,"esp"));
-+	&lea	("edi",&DWP($S2,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(S2, S2, in2_y);
-+
-+	&lea	("esi",&DWP($S2,"esp"));
-+	&lea	("ebp",&DWP($S1,"esp"));
-+	&lea	("edi",&DWP($R,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(R, S2, S1);
-+
-+	&or	("ebx","eax");			# see if result is zero
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&or	("ebx","ecx");
-+	&or	("ebx","edx");
-+	&or	("ebx",&DWP(0,"edi"));
-+	&or	("ebx",&DWP(4,"edi"));
-+	 &lea	("esi",&DWP($in1_x,"esp"));
-+	&or	("ebx",&DWP(8,"edi"));
-+	 &lea	("ebp",&DWP($Z2sqr,"esp"));
-+	&or	("ebx",&DWP(12,"edi"));
-+	 &lea	("edi",&DWP($U1,"esp"));
-+	&mov	(&DWP(32*18+8,"esp"),"ebx");
-+
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(U1, in1_x, Z2sqr);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in2_x,"esp"));
-+	&lea	("ebp",&DWP($Z1sqr,"esp"));
-+	&lea	("edi",&DWP($U2,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(U2, in2_x, Z1sqr);
-+
-+	&lea	("esi",&DWP($U2,"esp"));
-+	&lea	("ebp",&DWP($U1,"esp"));
-+	&lea	("edi",&DWP($H,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(H, U2, U1);
-+
-+	&or	("eax","ebx");			# see if result is zero
-+	&or	("eax","ecx");
-+	&or	("eax","edx");
-+	&or	("eax",&DWP(0,"edi"));
-+	&or	("eax",&DWP(4,"edi"));
-+	&or	("eax",&DWP(8,"edi"));
-+	&or	("eax",&DWP(12,"edi"));
-+
-+	&data_byte(0x3e);			# predict taken
-+	&jnz	(&label("add_proceed"));	# is_equal(U1,U2)?
-+
-+	&mov	("eax",&DWP(32*18+0,"esp"));
-+	&and	("eax",&DWP(32*18+4,"esp"));
-+	&mov	("ebx",&DWP(32*18+8,"esp"));
-+	&jz	(&label("add_proceed"));	# (in1infty || in2infty)?
-+	&test	("ebx","ebx");
-+	&jz	(&label("add_double"));		# is_equal(S1,S2)?
-+
-+	&mov	("edi",&wparam(0));
-+	&xor	("eax","eax");
-+	&mov	("ecx",96/4);
-+	&data_byte(0xfc,0xf3,0xab);		# cld; stosd
-+	&jmp	(&label("add_done"));
-+
-+&set_label("add_double",16);
-+	&mov	("esi",&wparam(1));
-+	&mov	("ebp",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&add	("esp",4*((8*18+5)-(8*5+1)));	# difference in frame sizes
-+	&jmp	(&label("point_double_shortcut"));
-+
-+&set_label("add_proceed",16);
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($R,"esp"));
-+	&lea	("ebp",&DWP($R,"esp"));
-+	&lea	("edi",&DWP($Rsqr,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(Rsqr, R);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($H,"esp"));
-+	&lea	("ebp",&DWP($in1_z,"esp"));
-+	&lea	("edi",&DWP($res_z,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(res_z, H, in1_z);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($H,"esp"));
-+	&lea	("ebp",&DWP($H,"esp"));
-+	&lea	("edi",&DWP($Hsqr,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(Hsqr, H);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in2_z,"esp"));
-+	&lea	("ebp",&DWP($res_z,"esp"));
-+	&lea	("edi",&DWP($res_z,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(res_z, res_z, in2_z);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($Hsqr,"esp"));
-+	&lea	("ebp",&DWP($U1,"esp"));
-+	&lea	("edi",&DWP($U2,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(U2, U1, Hsqr);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($H,"esp"));
-+	&lea	("ebp",&DWP($Hsqr,"esp"));
-+	&lea	("edi",&DWP($Hcub,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(Hcub, Hsqr, H);
-+
-+	&lea	("esi",&DWP($U2,"esp"));
-+	&lea	("ebp",&DWP($U2,"esp"));
-+	&lea	("edi",&DWP($Hsqr,"esp"));
-+	&call	("_ecp_nistz256_add");		# p256_mul_by_2(Hsqr, U2);
-+
-+	&lea	("esi",&DWP($Rsqr,"esp"));
-+	&lea	("ebp",&DWP($Hsqr,"esp"));
-+	&lea	("edi",&DWP($res_x,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(res_x, Rsqr, Hsqr);
-+
-+	&lea	("esi",&DWP($res_x,"esp"));
-+	&lea	("ebp",&DWP($Hcub,"esp"));
-+	&lea	("edi",&DWP($res_x,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(res_x, res_x, Hcub);
-+
-+	&lea	("esi",&DWP($U2,"esp"));
-+	&lea	("ebp",&DWP($res_x,"esp"));
-+	&lea	("edi",&DWP($res_y,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(res_y, U2, res_x);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($Hcub,"esp"));
-+	&lea	("ebp",&DWP($S1,"esp"));
-+	&lea	("edi",&DWP($S2,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(S2, S1, Hcub);
-+
-+	&mov	("eax",&DWP(32*18+12,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($R,"esp"));
-+	&lea	("ebp",&DWP($res_y,"esp"));
-+	&lea	("edi",&DWP($res_y,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(res_y, R, res_y);
-+
-+	&lea	("esi",&DWP($res_y,"esp"));
-+	&lea	("ebp",&DWP($S2,"esp"));
-+	&lea	("edi",&DWP($res_y,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(res_y, res_y, S2);
-+
-+	&mov	("ebp",&DWP(32*18+0,"esp"));	# !in1infty
-+	&mov	("esi",&DWP(32*18+4,"esp"));	# !in2infty
-+	&mov	("edi",&wparam(0));
-+	&mov	("edx","ebp");
-+	¬	("ebp");
-+	&and	("edx","esi");
-+	&and	("ebp","esi");
-+	¬	("esi");
-+
-+	########################################
-+	# conditional moves
-+    for($i=64;$i<96;$i+=4) {
-+	&mov	("eax","edx");
-+	&and	("eax",&DWP($res_x+$i,"esp"));
-+	&mov	("ebx","ebp");
-+	&and	("ebx",&DWP($in2_x+$i,"esp"));
-+	&mov	("ecx","esi");
-+	&and	("ecx",&DWP($in1_x+$i,"esp"));
-+	&or	("eax","ebx");
-+	&or	("eax","ecx");
-+	&mov	(&DWP($i,"edi"),"eax");
-+    }
-+    for($i=0;$i<64;$i+=4) {
-+	&mov	("eax","edx");
-+	&and	("eax",&DWP($res_x+$i,"esp"));
-+	&mov	("ebx","ebp");
-+	&and	("ebx",&DWP($in2_x+$i,"esp"));
-+	&mov	("ecx","esi");
-+	&and	("ecx",&DWP($in1_x+$i,"esp"));
-+	&or	("eax","ebx");
-+	&or	("eax","ecx");
-+	&mov	(&DWP($i,"edi"),"eax");
-+    }
-+    &set_label("add_done");
-+	&stack_pop(8*18+5);
-+} &function_end("ecp_nistz256_point_add");
-+
-+########################################################################
-+# void ecp_nistz256_point_add_affine(P256_POINT *out,
-+#				     const P256_POINT *in1,
-+#				     const P256_POINT_AFFINE *in2);
-+&function_begin("ecp_nistz256_point_add_affine");
-+{
-+    my ($res_x,$res_y,$res_z,
-+	$in1_x,$in1_y,$in1_z,
-+	$in2_x,$in2_y,
-+	$U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr)=map(32*$_,(0..14));
-+    my $Z1sqr = $S2;
-+    my @ONE_mont=(1,0,0,-1,-1,-1,-2,0);
-+
-+	&mov	("esi",&wparam(1));
-+
-+	# above map() describes stack layout with 15 temporary
-+	# 256-bit vectors on top, then we take extra words for
-+	# !in1infty, !in2infty, and OPENSSL_ia32cap_P copy.
-+	&stack_push(8*15+3);
-+						if ($sse2) {
-+	&call	("_picup_eax");
-+    &set_label("pic");
-+	&picmeup("edx","OPENSSL_ia32cap_P","eax",&label("pic"));
-+	&mov	("ebp",&DWP(0,"edx"));		}
-+
-+	&lea	("edi",&DWP($in1_x,"esp"));
-+    for($i=0;$i<96;$i+=16) {
-+	&mov	("eax",&DWP($i+0,"esi"));	# copy in1
-+	&mov	("ebx",&DWP($i+4,"esi"));
-+	&mov	("ecx",&DWP($i+8,"esi"));
-+	&mov	("edx",&DWP($i+12,"esi"));
-+	&mov	(&DWP($i+0,"edi"),"eax");
-+	&mov	(&DWP(32*15+8,"esp"),"ebp")	if ($i==0);
-+	&mov	("ebp","eax")			if ($i==64);
-+	&or	("ebp","eax")			if ($i>64);
-+	&mov	(&DWP($i+4,"edi"),"ebx");
-+	&or	("ebp","ebx")			if ($i>=64);
-+	&mov	(&DWP($i+8,"edi"),"ecx");
-+	&or	("ebp","ecx")			if ($i>=64);
-+	&mov	(&DWP($i+12,"edi"),"edx");
-+	&or	("ebp","edx")			if ($i>=64);
-+    }
-+	&xor	("eax","eax");
-+	&mov	("esi",&wparam(2));
-+	&sub	("eax","ebp");
-+	&or	("ebp","eax");
-+	&sar	("ebp",31);
-+	&mov	(&DWP(32*15+0,"esp"),"ebp");	# !in1infty
-+
-+	&lea	("edi",&DWP($in2_x,"esp"));
-+    for($i=0;$i<64;$i+=16) {
-+	&mov	("eax",&DWP($i+0,"esi"));	# copy in2
-+	&mov	("ebx",&DWP($i+4,"esi"));
-+	&mov	("ecx",&DWP($i+8,"esi"));
-+	&mov	("edx",&DWP($i+12,"esi"));
-+	&mov	(&DWP($i+0,"edi"),"eax");
-+	&mov	("ebp","eax")			if ($i==0);
-+	&or	("ebp","eax")			if ($i!=0);
-+	&mov	(&DWP($i+4,"edi"),"ebx");
-+	&or	("ebp","ebx");
-+	&mov	(&DWP($i+8,"edi"),"ecx");
-+	&or	("ebp","ecx");
-+	&mov	(&DWP($i+12,"edi"),"edx");
-+	&or	("ebp","edx");
-+    }
-+	&xor	("ebx","ebx");
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&sub	("ebx","ebp");
-+	 &lea	("esi",&DWP($in1_z,"esp"));
-+	&or	("ebx","ebp");
-+	 &lea	("ebp",&DWP($in1_z,"esp"));
-+	&sar	("ebx",31);
-+	 &lea	("edi",&DWP($Z1sqr,"esp"));
-+	&mov	(&DWP(32*15+4,"esp"),"ebx");	# !in2infty
-+
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(Z1sqr, in1_z);
-+
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in2_x,"esp"));
-+	&mov	("ebp","edi");			# %esi is stull &Z1sqr
-+	&lea	("edi",&DWP($U2,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(U2, Z1sqr, in2_x);
-+
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in1_z,"esp"));
-+	&lea	("ebp",&DWP($Z1sqr,"esp"));
-+	&lea	("edi",&DWP($S2,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(S2, Z1sqr, in1_z);
-+
-+	&lea	("esi",&DWP($U2,"esp"));
-+	&lea	("ebp",&DWP($in1_x,"esp"));
-+	&lea	("edi",&DWP($H,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(H, U2, in1_x);
-+
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in2_y,"esp"));
-+	&lea	("ebp",&DWP($S2,"esp"));
-+	&lea	("edi",&DWP($S2,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(S2, S2, in2_y);
-+
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in1_z,"esp"));
-+	&lea	("ebp",&DWP($H,"esp"));
-+	&lea	("edi",&DWP($res_z,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(res_z, H, in1_z);
-+
-+	&lea	("esi",&DWP($S2,"esp"));
-+	&lea	("ebp",&DWP($in1_y,"esp"));
-+	&lea	("edi",&DWP($R,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(R, S2, in1_y);
-+
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($H,"esp"));
-+	&lea	("ebp",&DWP($H,"esp"));
-+	&lea	("edi",&DWP($Hsqr,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(Hsqr, H);
-+
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($R,"esp"));
-+	&lea	("ebp",&DWP($R,"esp"));
-+	&lea	("edi",&DWP($Rsqr,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_sqr_mont(Rsqr, R);
-+
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($in1_x,"esp"));
-+	&lea	("ebp",&DWP($Hsqr,"esp"));
-+	&lea	("edi",&DWP($U2,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(U2, in1_x, Hsqr);
-+
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($H,"esp"));
-+	&lea	("ebp",&DWP($Hsqr,"esp"));
-+	&lea	("edi",&DWP($Hcub,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(Hcub, Hsqr, H);
-+
-+	&lea	("esi",&DWP($U2,"esp"));
-+	&lea	("ebp",&DWP($U2,"esp"));
-+	&lea	("edi",&DWP($Hsqr,"esp"));
-+	&call	("_ecp_nistz256_add");		# p256_mul_by_2(Hsqr, U2);
-+
-+	&lea	("esi",&DWP($Rsqr,"esp"));
-+	&lea	("ebp",&DWP($Hsqr,"esp"));
-+	&lea	("edi",&DWP($res_x,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(res_x, Rsqr, Hsqr);
-+
-+	&lea	("esi",&DWP($res_x,"esp"));
-+	&lea	("ebp",&DWP($Hcub,"esp"));
-+	&lea	("edi",&DWP($res_x,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(res_x, res_x, Hcub);
-+
-+	&lea	("esi",&DWP($U2,"esp"));
-+	&lea	("ebp",&DWP($res_x,"esp"));
-+	&lea	("edi",&DWP($res_y,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(res_y, U2, res_x);
-+
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($Hcub,"esp"));
-+	&lea	("ebp",&DWP($in1_y,"esp"));
-+	&lea	("edi",&DWP($S2,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(S2, Hcub, in1_y);
-+
-+	&mov	("eax",&DWP(32*15+8,"esp"));	# OPENSSL_ia32cap_P copy
-+	&lea	("esi",&DWP($R,"esp"));
-+	&lea	("ebp",&DWP($res_y,"esp"));
-+	&lea	("edi",&DWP($res_y,"esp"));
-+	&call	("_ecp_nistz256_mul_mont");	# p256_mul_mont(res_y, res_y, R);
-+
-+	&lea	("esi",&DWP($res_y,"esp"));
-+	&lea	("ebp",&DWP($S2,"esp"));
-+	&lea	("edi",&DWP($res_y,"esp"));
-+	&call	("_ecp_nistz256_sub");		# p256_sub(res_y, res_y, S2);
-+
-+	&mov	("ebp",&DWP(32*15+0,"esp"));	# !in1infty
-+	&mov	("esi",&DWP(32*15+4,"esp"));	# !in2infty
-+	&mov	("edi",&wparam(0));
-+	&mov	("edx","ebp");
-+	¬	("ebp");
-+	&and	("edx","esi");
-+	&and	("ebp","esi");
-+	¬	("esi");
-+
-+	########################################
-+	# conditional moves
-+    for($i=64;$i<96;$i+=4) {
-+	my $one=@ONE_mont[($i-64)/4];
-+
-+	&mov	("eax","edx");
-+	&and	("eax",&DWP($res_x+$i,"esp"));
-+	&mov	("ebx","ebp")			if ($one && $one!=-1);
-+	&and	("ebx",$one)			if ($one && $one!=-1);
-+	&mov	("ecx","esi");
-+	&and	("ecx",&DWP($in1_x+$i,"esp"));
-+	&or	("eax",$one==-1?"ebp":"ebx")	if ($one);
-+	&or	("eax","ecx");
-+	&mov	(&DWP($i,"edi"),"eax");
-+    }
-+    for($i=0;$i<64;$i+=4) {
-+	&mov	("eax","edx");
-+	&and	("eax",&DWP($res_x+$i,"esp"));
-+	&mov	("ebx","ebp");
-+	&and	("ebx",&DWP($in2_x+$i,"esp"));
-+	&mov	("ecx","esi");
-+	&and	("ecx",&DWP($in1_x+$i,"esp"));
-+	&or	("eax","ebx");
-+	&or	("eax","ecx");
-+	&mov	(&DWP($i,"edi"),"eax");
-+    }
-+	&stack_pop(8*15+3);
-+} &function_end("ecp_nistz256_point_add_affine");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl
-new file mode 100755
-index 0000000..16b6639
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl
-@@ -0,0 +1,3087 @@
-+#! /usr/bin/env perl
-+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+##############################################################################
-+#                                                                            #
-+# Copyright 2014 Intel Corporation                                           #
-+#                                                                            #
-+# Licensed under the Apache License, Version 2.0 (the "License");            #
-+# you may not use this file except in compliance with the License.           #
-+# You may obtain a copy of the License at                                    #
-+#                                                                            #
-+#    http://www.apache.org/licenses/LICENSE-2.0                              #
-+#                                                                            #
-+# Unless required by applicable law or agreed to in writing, software        #
-+# distributed under the License is distributed on an "AS IS" BASIS,          #
-+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
-+# See the License for the specific language governing permissions and        #
-+# limitations under the License.                                             #
-+#                                                                            #
-+##############################################################################
-+#                                                                            #
-+#  Developers and authors:                                                   #
-+#  Shay Gueron (1, 2), and Vlad Krasnov (1)                                  #
-+#  (1) Intel Corporation, Israel Development Center                          #
-+#  (2) University of Haifa                                                   #
-+#  Reference:                                                                #
-+#  S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with#
-+#                           256 Bit Primes"                                  #
-+#                                                                            #
-+##############################################################################
-+
-+# Further optimization by :
-+#
-+#		this/original	with/without -DECP_NISTZ256_ASM(*)
-+# Opteron	+12-49%		+110-150%
-+# Bulldozer	+14-45%		+175-210%
-+# P4		+18-46%		n/a :-(
-+# Westmere	+12-34%		+80-87%
-+# Sandy Bridge	+9-35%		+110-120%
-+# Ivy Bridge	+9-35%		+110-125%
-+# Haswell	+8-37%		+140-160%
-+# Broadwell	+18-58%		+145-210%
-+# Atom		+15-50%		+130-180%
-+# VIA Nano	+43-160%	+300-480%
-+#
-+# (*)	"without -DECP_NISTZ256_ASM" refers to build with
-+#	"enable-ec_nistp_64_gcc_128";
-+#
-+# Ranges denote minimum and maximum improvement coefficients depending
-+# on benchmark. Lower coefficients are for ECDSA sign, relatively fastest
-+# server-side operation. Keep in mind that +100% means 2x improvement.
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+	$addx = ($1>=2.23);
-+}
-+
-+if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	    `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+	$addx = ($1>=2.10);
-+}
-+
-+if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	    `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+	$addx = ($1>=12);
-+}
-+
-+if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) {
-+	my $ver = $2 + $3/100.0;	# 3.1->3.01, 3.10->3.10
-+	$avx = ($ver>=3.0) + ($ver>=3.01);
-+	$addx = ($ver>=3.03);
-+}
-+
-+$code.=<<___;
-+.text
-+.extern	OPENSSL_ia32cap_P
-+
-+# The polynomial
-+.align 64
-+.Lpoly:
-+.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
-+
-+# 2^512 mod P precomputed for NIST P256 polynomial
-+.LRR:
-+.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd
-+
-+.LOne:
-+.long 1,1,1,1,1,1,1,1
-+.LTwo:
-+.long 2,2,2,2,2,2,2,2
-+.LThree:
-+.long 3,3,3,3,3,3,3,3
-+.LONE_mont:
-+.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
-+___
-+
-+{
-+################################################################################
-+# void ecp_nistz256_mul_by_2(uint64_t res[4], uint64_t a[4]);
-+
-+my ($a0,$a1,$a2,$a3)=map("%r$_",(8..11));
-+my ($t0,$t1,$t2,$t3,$t4)=("%rax","%rdx","%rcx","%r12","%r13");
-+my ($r_ptr,$a_ptr,$b_ptr)=("%rdi","%rsi","%rdx");
-+
-+$code.=<<___;
-+
-+.globl	ecp_nistz256_mul_by_2
-+.type	ecp_nistz256_mul_by_2,\@function,2
-+.align	64
-+ecp_nistz256_mul_by_2:
-+	push	%r12
-+	push	%r13
-+
-+	mov	8*0($a_ptr), $a0
-+	xor	$t4,$t4
-+	mov	8*1($a_ptr), $a1
-+	add	$a0, $a0		# a0:a3+a0:a3
-+	mov	8*2($a_ptr), $a2
-+	adc	$a1, $a1
-+	mov	8*3($a_ptr), $a3
-+	lea	.Lpoly(%rip), $a_ptr
-+	 mov	$a0, $t0
-+	adc	$a2, $a2
-+	adc	$a3, $a3
-+	 mov	$a1, $t1
-+	adc	\$0, $t4
-+
-+	sub	8*0($a_ptr), $a0
-+	 mov	$a2, $t2
-+	sbb	8*1($a_ptr), $a1
-+	sbb	8*2($a_ptr), $a2
-+	 mov	$a3, $t3
-+	sbb	8*3($a_ptr), $a3
-+	sbb	\$0, $t4
-+
-+	cmovc	$t0, $a0
-+	cmovc	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovc	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovc	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	pop	%r13
-+	pop	%r12
-+	ret
-+.size	ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
-+
-+################################################################################
-+# void ecp_nistz256_div_by_2(uint64_t res[4], uint64_t a[4]);
-+.globl	ecp_nistz256_div_by_2
-+.type	ecp_nistz256_div_by_2,\@function,2
-+.align	32
-+ecp_nistz256_div_by_2:
-+	push	%r12
-+	push	%r13
-+
-+	mov	8*0($a_ptr), $a0
-+	mov	8*1($a_ptr), $a1
-+	mov	8*2($a_ptr), $a2
-+	 mov	$a0, $t0
-+	mov	8*3($a_ptr), $a3
-+	lea	.Lpoly(%rip), $a_ptr
-+
-+	 mov	$a1, $t1
-+	xor	$t4, $t4
-+	add	8*0($a_ptr), $a0
-+	 mov	$a2, $t2
-+	adc	8*1($a_ptr), $a1
-+	adc	8*2($a_ptr), $a2
-+	 mov	$a3, $t3
-+	adc	8*3($a_ptr), $a3
-+	adc	\$0, $t4
-+	xor	$a_ptr, $a_ptr		# borrow $a_ptr
-+	test	\$1, $t0
-+
-+	cmovz	$t0, $a0
-+	cmovz	$t1, $a1
-+	cmovz	$t2, $a2
-+	cmovz	$t3, $a3
-+	cmovz	$a_ptr, $t4
-+
-+	mov	$a1, $t0		# a0:a3>>1
-+	shr	\$1, $a0
-+	shl	\$63, $t0
-+	mov	$a2, $t1
-+	shr	\$1, $a1
-+	or	$t0, $a0
-+	shl	\$63, $t1
-+	mov	$a3, $t2
-+	shr	\$1, $a2
-+	or	$t1, $a1
-+	shl	\$63, $t2
-+	shr	\$1, $a3
-+	shl	\$63, $t4
-+	or	$t2, $a2
-+	or	$t4, $a3
-+
-+	mov	$a0, 8*0($r_ptr)
-+	mov	$a1, 8*1($r_ptr)
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	pop	%r13
-+	pop	%r12
-+	ret
-+.size	ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
-+
-+################################################################################
-+# void ecp_nistz256_mul_by_3(uint64_t res[4], uint64_t a[4]);
-+.globl	ecp_nistz256_mul_by_3
-+.type	ecp_nistz256_mul_by_3,\@function,2
-+.align	32
-+ecp_nistz256_mul_by_3:
-+	push	%r12
-+	push	%r13
-+
-+	mov	8*0($a_ptr), $a0
-+	xor	$t4, $t4
-+	mov	8*1($a_ptr), $a1
-+	add	$a0, $a0		# a0:a3+a0:a3
-+	mov	8*2($a_ptr), $a2
-+	adc	$a1, $a1
-+	mov	8*3($a_ptr), $a3
-+	 mov	$a0, $t0
-+	adc	$a2, $a2
-+	adc	$a3, $a3
-+	 mov	$a1, $t1
-+	adc	\$0, $t4
-+
-+	sub	\$-1, $a0
-+	 mov	$a2, $t2
-+	sbb	.Lpoly+8*1(%rip), $a1
-+	sbb	\$0, $a2
-+	 mov	$a3, $t3
-+	sbb	.Lpoly+8*3(%rip), $a3
-+	sbb	\$0, $t4
-+
-+	cmovc	$t0, $a0
-+	cmovc	$t1, $a1
-+	cmovc	$t2, $a2
-+	cmovc	$t3, $a3
-+
-+	xor	$t4, $t4
-+	add	8*0($a_ptr), $a0	# a0:a3+=a_ptr[0:3]
-+	adc	8*1($a_ptr), $a1
-+	 mov	$a0, $t0
-+	adc	8*2($a_ptr), $a2
-+	adc	8*3($a_ptr), $a3
-+	 mov	$a1, $t1
-+	adc	\$0, $t4
-+
-+	sub	\$-1, $a0
-+	 mov	$a2, $t2
-+	sbb	.Lpoly+8*1(%rip), $a1
-+	sbb	\$0, $a2
-+	 mov	$a3, $t3
-+	sbb	.Lpoly+8*3(%rip), $a3
-+	sbb	\$0, $t4
-+
-+	cmovc	$t0, $a0
-+	cmovc	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovc	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovc	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	pop %r13
-+	pop %r12
-+	ret
-+.size	ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
-+
-+################################################################################
-+# void ecp_nistz256_add(uint64_t res[4], uint64_t a[4], uint64_t b[4]);
-+.globl	ecp_nistz256_add
-+.type	ecp_nistz256_add,\@function,3
-+.align	32
-+ecp_nistz256_add:
-+	push	%r12
-+	push	%r13
-+
-+	mov	8*0($a_ptr), $a0
-+	xor	$t4, $t4
-+	mov	8*1($a_ptr), $a1
-+	mov	8*2($a_ptr), $a2
-+	mov	8*3($a_ptr), $a3
-+	lea	.Lpoly(%rip), $a_ptr
-+
-+	add	8*0($b_ptr), $a0
-+	adc	8*1($b_ptr), $a1
-+	 mov	$a0, $t0
-+	adc	8*2($b_ptr), $a2
-+	adc	8*3($b_ptr), $a3
-+	 mov	$a1, $t1
-+	adc	\$0, $t4
-+
-+	sub	8*0($a_ptr), $a0
-+	 mov	$a2, $t2
-+	sbb	8*1($a_ptr), $a1
-+	sbb	8*2($a_ptr), $a2
-+	 mov	$a3, $t3
-+	sbb	8*3($a_ptr), $a3
-+	sbb	\$0, $t4
-+
-+	cmovc	$t0, $a0
-+	cmovc	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovc	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovc	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	pop %r13
-+	pop %r12
-+	ret
-+.size	ecp_nistz256_add,.-ecp_nistz256_add
-+
-+################################################################################
-+# void ecp_nistz256_sub(uint64_t res[4], uint64_t a[4], uint64_t b[4]);
-+.globl	ecp_nistz256_sub
-+.type	ecp_nistz256_sub,\@function,3
-+.align	32
-+ecp_nistz256_sub:
-+	push	%r12
-+	push	%r13
-+
-+	mov	8*0($a_ptr), $a0
-+	xor	$t4, $t4
-+	mov	8*1($a_ptr), $a1
-+	mov	8*2($a_ptr), $a2
-+	mov	8*3($a_ptr), $a3
-+	lea	.Lpoly(%rip), $a_ptr
-+
-+	sub	8*0($b_ptr), $a0
-+	sbb	8*1($b_ptr), $a1
-+	 mov	$a0, $t0
-+	sbb	8*2($b_ptr), $a2
-+	sbb	8*3($b_ptr), $a3
-+	 mov	$a1, $t1
-+	sbb	\$0, $t4
-+
-+	add	8*0($a_ptr), $a0
-+	 mov	$a2, $t2
-+	adc	8*1($a_ptr), $a1
-+	adc	8*2($a_ptr), $a2
-+	 mov	$a3, $t3
-+	adc	8*3($a_ptr), $a3
-+	test	$t4, $t4
-+
-+	cmovz	$t0, $a0
-+	cmovz	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovz	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovz	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	pop %r13
-+	pop %r12
-+	ret
-+.size	ecp_nistz256_sub,.-ecp_nistz256_sub
-+
-+################################################################################
-+# void ecp_nistz256_neg(uint64_t res[4], uint64_t a[4]);
-+.globl	ecp_nistz256_neg
-+.type	ecp_nistz256_neg,\@function,2
-+.align	32
-+ecp_nistz256_neg:
-+	push	%r12
-+	push	%r13
-+
-+	xor	$a0, $a0
-+	xor	$a1, $a1
-+	xor	$a2, $a2
-+	xor	$a3, $a3
-+	xor	$t4, $t4
-+
-+	sub	8*0($a_ptr), $a0
-+	sbb	8*1($a_ptr), $a1
-+	sbb	8*2($a_ptr), $a2
-+	 mov	$a0, $t0
-+	sbb	8*3($a_ptr), $a3
-+	lea	.Lpoly(%rip), $a_ptr
-+	 mov	$a1, $t1
-+	sbb	\$0, $t4
-+
-+	add	8*0($a_ptr), $a0
-+	 mov	$a2, $t2
-+	adc	8*1($a_ptr), $a1
-+	adc	8*2($a_ptr), $a2
-+	 mov	$a3, $t3
-+	adc	8*3($a_ptr), $a3
-+	test	$t4, $t4
-+
-+	cmovz	$t0, $a0
-+	cmovz	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovz	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovz	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	pop %r13
-+	pop %r12
-+	ret
-+.size	ecp_nistz256_neg,.-ecp_nistz256_neg
-+___
-+}
-+{
-+my ($r_ptr,$a_ptr,$b_org,$b_ptr)=("%rdi","%rsi","%rdx","%rbx");
-+my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7)=map("%r$_",(8..15));
-+my ($t0,$t1,$t2,$t3,$t4)=("%rcx","%rbp","%rbx","%rdx","%rax");
-+my ($poly1,$poly3)=($acc6,$acc7);
-+
-+$code.=<<___;
-+################################################################################
-+# void ecp_nistz256_to_mont(
-+#   uint64_t res[4],
-+#   uint64_t in[4]);
-+.globl	ecp_nistz256_to_mont
-+.type	ecp_nistz256_to_mont,\@function,2
-+.align	32
-+ecp_nistz256_to_mont:
-+___
-+$code.=<<___	if ($addx);
-+	mov	\$0x80100, %ecx
-+	and	OPENSSL_ia32cap_P+8(%rip), %ecx
-+___
-+$code.=<<___;
-+	lea	.LRR(%rip), $b_org
-+	jmp	.Lmul_mont
-+.size	ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
-+
-+################################################################################
-+# void ecp_nistz256_mul_mont(
-+#   uint64_t res[4],
-+#   uint64_t a[4],
-+#   uint64_t b[4]);
-+
-+.globl	ecp_nistz256_mul_mont
-+.type	ecp_nistz256_mul_mont,\@function,3
-+.align	32
-+ecp_nistz256_mul_mont:
-+___
-+$code.=<<___	if ($addx);
-+	mov	\$0x80100, %ecx
-+	and	OPENSSL_ia32cap_P+8(%rip), %ecx
-+___
-+$code.=<<___;
-+.Lmul_mont:
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___	if ($addx);
-+	cmp	\$0x80100, %ecx
-+	je	.Lmul_montx
-+___
-+$code.=<<___;
-+	mov	$b_org, $b_ptr
-+	mov	8*0($b_org), %rax
-+	mov	8*0($a_ptr), $acc1
-+	mov	8*1($a_ptr), $acc2
-+	mov	8*2($a_ptr), $acc3
-+	mov	8*3($a_ptr), $acc4
-+
-+	call	__ecp_nistz256_mul_montq
-+___
-+$code.=<<___	if ($addx);
-+	jmp	.Lmul_mont_done
-+
-+.align	32
-+.Lmul_montx:
-+	mov	$b_org, $b_ptr
-+	mov	8*0($b_org), %rdx
-+	mov	8*0($a_ptr), $acc1
-+	mov	8*1($a_ptr), $acc2
-+	mov	8*2($a_ptr), $acc3
-+	mov	8*3($a_ptr), $acc4
-+	lea	-128($a_ptr), $a_ptr	# control u-op density
-+
-+	call	__ecp_nistz256_mul_montx
-+___
-+$code.=<<___;
-+.Lmul_mont_done:
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbx
-+	pop	%rbp
-+	ret
-+.size	ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
-+
-+.type	__ecp_nistz256_mul_montq,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_mul_montq:
-+	########################################################################
-+	# Multiply a by b[0]
-+	mov	%rax, $t1
-+	mulq	$acc1
-+	mov	.Lpoly+8*1(%rip),$poly1
-+	mov	%rax, $acc0
-+	mov	$t1, %rax
-+	mov	%rdx, $acc1
-+
-+	mulq	$acc2
-+	mov	.Lpoly+8*3(%rip),$poly3
-+	add	%rax, $acc1
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $acc2
-+
-+	mulq	$acc3
-+	add	%rax, $acc2
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $acc3
-+
-+	mulq	$acc4
-+	add	%rax, $acc3
-+	 mov	$acc0, %rax
-+	adc	\$0, %rdx
-+	xor	$acc5, $acc5
-+	mov	%rdx, $acc4
-+
-+	########################################################################
-+	# First reduction step
-+	# Basically now we want to multiply acc[0] by p256,
-+	# and add the result to the acc.
-+	# Due to the special form of p256 we do some optimizations
-+	#
-+	# acc[0] x p256[0..1] = acc[0] x 2^96 - acc[0]
-+	# then we add acc[0] and get acc[0] x 2^96
-+
-+	mov	$acc0, $t1
-+	shl	\$32, $acc0
-+	mulq	$poly3
-+	shr	\$32, $t1
-+	add	$acc0, $acc1		# +=acc[0]<<96
-+	adc	$t1, $acc2
-+	adc	%rax, $acc3
-+	 mov	8*1($b_ptr), %rax
-+	adc	%rdx, $acc4
-+	adc	\$0, $acc5
-+	xor	$acc0, $acc0
-+
-+	########################################################################
-+	# Multiply by b[1]
-+	mov	%rax, $t1
-+	mulq	8*0($a_ptr)
-+	add	%rax, $acc1
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	8*1($a_ptr)
-+	add	$t0, $acc2
-+	adc	\$0, %rdx
-+	add	%rax, $acc2
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	8*2($a_ptr)
-+	add	$t0, $acc3
-+	adc	\$0, %rdx
-+	add	%rax, $acc3
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	8*3($a_ptr)
-+	add	$t0, $acc4
-+	adc	\$0, %rdx
-+	add	%rax, $acc4
-+	 mov	$acc1, %rax
-+	adc	%rdx, $acc5
-+	adc	\$0, $acc0
-+
-+	########################################################################
-+	# Second reduction step	
-+	mov	$acc1, $t1
-+	shl	\$32, $acc1
-+	mulq	$poly3
-+	shr	\$32, $t1
-+	add	$acc1, $acc2
-+	adc	$t1, $acc3
-+	adc	%rax, $acc4
-+	 mov	8*2($b_ptr), %rax
-+	adc	%rdx, $acc5
-+	adc	\$0, $acc0
-+	xor	$acc1, $acc1
-+
-+	########################################################################
-+	# Multiply by b[2]
-+	mov	%rax, $t1
-+	mulq	8*0($a_ptr)
-+	add	%rax, $acc2
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	8*1($a_ptr)
-+	add	$t0, $acc3
-+	adc	\$0, %rdx
-+	add	%rax, $acc3
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	8*2($a_ptr)
-+	add	$t0, $acc4
-+	adc	\$0, %rdx
-+	add	%rax, $acc4
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	8*3($a_ptr)
-+	add	$t0, $acc5
-+	adc	\$0, %rdx
-+	add	%rax, $acc5
-+	 mov	$acc2, %rax
-+	adc	%rdx, $acc0
-+	adc	\$0, $acc1
-+
-+	########################################################################
-+	# Third reduction step	
-+	mov	$acc2, $t1
-+	shl	\$32, $acc2
-+	mulq	$poly3
-+	shr	\$32, $t1
-+	add	$acc2, $acc3
-+	adc	$t1, $acc4
-+	adc	%rax, $acc5
-+	 mov	8*3($b_ptr), %rax
-+	adc	%rdx, $acc0
-+	adc	\$0, $acc1
-+	xor	$acc2, $acc2
-+
-+	########################################################################
-+	# Multiply by b[3]
-+	mov	%rax, $t1
-+	mulq	8*0($a_ptr)
-+	add	%rax, $acc3
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	8*1($a_ptr)
-+	add	$t0, $acc4
-+	adc	\$0, %rdx
-+	add	%rax, $acc4
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	8*2($a_ptr)
-+	add	$t0, $acc5
-+	adc	\$0, %rdx
-+	add	%rax, $acc5
-+	mov	$t1, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	8*3($a_ptr)
-+	add	$t0, $acc0
-+	adc	\$0, %rdx
-+	add	%rax, $acc0
-+	 mov	$acc3, %rax
-+	adc	%rdx, $acc1
-+	adc	\$0, $acc2
-+
-+	########################################################################
-+	# Final reduction step	
-+	mov	$acc3, $t1
-+	shl	\$32, $acc3
-+	mulq	$poly3
-+	shr	\$32, $t1
-+	add	$acc3, $acc4
-+	adc	$t1, $acc5
-+	 mov	$acc4, $t0
-+	adc	%rax, $acc0
-+	adc	%rdx, $acc1
-+	 mov	$acc5, $t1
-+	adc	\$0, $acc2
-+
-+	########################################################################	
-+	# Branch-less conditional subtraction of P
-+	sub	\$-1, $acc4		# .Lpoly[0]
-+	 mov	$acc0, $t2
-+	sbb	$poly1, $acc5		# .Lpoly[1]
-+	sbb	\$0, $acc0		# .Lpoly[2]
-+	 mov	$acc1, $t3
-+	sbb	$poly3, $acc1		# .Lpoly[3]
-+	sbb	\$0, $acc2
-+
-+	cmovc	$t0, $acc4
-+	cmovc	$t1, $acc5
-+	mov	$acc4, 8*0($r_ptr)
-+	cmovc	$t2, $acc0
-+	mov	$acc5, 8*1($r_ptr)
-+	cmovc	$t3, $acc1
-+	mov	$acc0, 8*2($r_ptr)
-+	mov	$acc1, 8*3($r_ptr)
-+
-+	ret
-+.size	__ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq
-+
-+################################################################################
-+# void ecp_nistz256_sqr_mont(
-+#   uint64_t res[4],
-+#   uint64_t a[4]);
-+
-+# we optimize the square according to S.Gueron and V.Krasnov,
-+# "Speeding up Big-Number Squaring"
-+.globl	ecp_nistz256_sqr_mont
-+.type	ecp_nistz256_sqr_mont,\@function,2
-+.align	32
-+ecp_nistz256_sqr_mont:
-+___
-+$code.=<<___	if ($addx);
-+	mov	\$0x80100, %ecx
-+	and	OPENSSL_ia32cap_P+8(%rip), %ecx
-+___
-+$code.=<<___;
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___	if ($addx);
-+	cmp	\$0x80100, %ecx
-+	je	.Lsqr_montx
-+___
-+$code.=<<___;
-+	mov	8*0($a_ptr), %rax
-+	mov	8*1($a_ptr), $acc6
-+	mov	8*2($a_ptr), $acc7
-+	mov	8*3($a_ptr), $acc0
-+
-+	call	__ecp_nistz256_sqr_montq
-+___
-+$code.=<<___	if ($addx);
-+	jmp	.Lsqr_mont_done
-+
-+.align	32
-+.Lsqr_montx:
-+	mov	8*0($a_ptr), %rdx
-+	mov	8*1($a_ptr), $acc6
-+	mov	8*2($a_ptr), $acc7
-+	mov	8*3($a_ptr), $acc0
-+	lea	-128($a_ptr), $a_ptr	# control u-op density
-+
-+	call	__ecp_nistz256_sqr_montx
-+___
-+$code.=<<___;
-+.Lsqr_mont_done:
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbx
-+	pop	%rbp
-+	ret
-+.size	ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
-+
-+.type	__ecp_nistz256_sqr_montq,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_sqr_montq:
-+	mov	%rax, $acc5
-+	mulq	$acc6			# a[1]*a[0]
-+	mov	%rax, $acc1
-+	mov	$acc7, %rax
-+	mov	%rdx, $acc2
-+
-+	mulq	$acc5			# a[0]*a[2]
-+	add	%rax, $acc2
-+	mov	$acc0, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $acc3
-+
-+	mulq	$acc5			# a[0]*a[3]
-+	add	%rax, $acc3
-+	 mov	$acc7, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $acc4
-+
-+	#################################
-+	mulq	$acc6			# a[1]*a[2]
-+	add	%rax, $acc3
-+	mov	$acc0, %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t1
-+
-+	mulq	$acc6			# a[1]*a[3]
-+	add	%rax, $acc4
-+	 mov	$acc0, %rax
-+	adc	\$0, %rdx
-+	add	$t1, $acc4
-+	mov	%rdx, $acc5
-+	adc	\$0, $acc5
-+
-+	#################################
-+	mulq	$acc7			# a[2]*a[3]
-+	xor	$acc7, $acc7
-+	add	%rax, $acc5
-+	 mov	8*0($a_ptr), %rax
-+	mov	%rdx, $acc6
-+	adc	\$0, $acc6
-+
-+	add	$acc1, $acc1		# acc1:6<<1
-+	adc	$acc2, $acc2
-+	adc	$acc3, $acc3
-+	adc	$acc4, $acc4
-+	adc	$acc5, $acc5
-+	adc	$acc6, $acc6
-+	adc	\$0, $acc7
-+
-+	mulq	%rax
-+	mov	%rax, $acc0
-+	mov	8*1($a_ptr), %rax
-+	mov	%rdx, $t0
-+
-+	mulq	%rax
-+	add	$t0, $acc1
-+	adc	%rax, $acc2
-+	mov	8*2($a_ptr), %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	%rax
-+	add	$t0, $acc3
-+	adc	%rax, $acc4
-+	mov	8*3($a_ptr), %rax
-+	adc	\$0, %rdx
-+	mov	%rdx, $t0
-+
-+	mulq	%rax
-+	add	$t0, $acc5
-+	adc	%rax, $acc6
-+	 mov	$acc0, %rax
-+	adc	%rdx, $acc7
-+
-+	mov	.Lpoly+8*1(%rip), $a_ptr
-+	mov	.Lpoly+8*3(%rip), $t1
-+
-+	##########################################
-+	# Now the reduction
-+	# First iteration
-+	mov	$acc0, $t0
-+	shl	\$32, $acc0
-+	mulq	$t1
-+	shr	\$32, $t0
-+	add	$acc0, $acc1		# +=acc[0]<<96
-+	adc	$t0, $acc2
-+	adc	%rax, $acc3
-+	 mov	$acc1, %rax
-+	adc	\$0, %rdx
-+
-+	##########################################
-+	# Second iteration
-+	mov	$acc1, $t0
-+	shl	\$32, $acc1
-+	mov	%rdx, $acc0
-+	mulq	$t1
-+	shr	\$32, $t0
-+	add	$acc1, $acc2
-+	adc	$t0, $acc3
-+	adc	%rax, $acc0
-+	 mov	$acc2, %rax
-+	adc	\$0, %rdx
-+
-+	##########################################
-+	# Third iteration
-+	mov	$acc2, $t0
-+	shl	\$32, $acc2
-+	mov	%rdx, $acc1
-+	mulq	$t1
-+	shr	\$32, $t0
-+	add	$acc2, $acc3
-+	adc	$t0, $acc0
-+	adc	%rax, $acc1
-+	 mov	$acc3, %rax
-+	adc	\$0, %rdx
-+
-+	###########################################
-+	# Last iteration
-+	mov	$acc3, $t0
-+	shl	\$32, $acc3
-+	mov	%rdx, $acc2
-+	mulq	$t1
-+	shr	\$32, $t0
-+	add	$acc3, $acc0
-+	adc	$t0, $acc1
-+	adc	%rax, $acc2
-+	adc	\$0, %rdx
-+	xor	$acc3, $acc3
-+
-+	############################################
-+	# Add the rest of the acc
-+	add	$acc0, $acc4
-+	adc	$acc1, $acc5
-+	 mov	$acc4, $acc0
-+	adc	$acc2, $acc6
-+	adc	%rdx, $acc7
-+	 mov	$acc5, $acc1
-+	adc	\$0, $acc3
-+
-+	sub	\$-1, $acc4		# .Lpoly[0]
-+	 mov	$acc6, $acc2
-+	sbb	$a_ptr, $acc5		# .Lpoly[1]
-+	sbb	\$0, $acc6		# .Lpoly[2]
-+	 mov	$acc7, $t0
-+	sbb	$t1, $acc7		# .Lpoly[3]
-+	sbb	\$0, $acc3
-+
-+	cmovc	$acc0, $acc4
-+	cmovc	$acc1, $acc5
-+	mov	$acc4, 8*0($r_ptr)
-+	cmovc	$acc2, $acc6
-+	mov	$acc5, 8*1($r_ptr)
-+	cmovc	$t0, $acc7
-+	mov	$acc6, 8*2($r_ptr)
-+	mov	$acc7, 8*3($r_ptr)
-+
-+	ret
-+.size	__ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq
-+___
-+
-+if ($addx) {
-+$code.=<<___;
-+.type	__ecp_nistz256_mul_montx,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_mul_montx:
-+	########################################################################
-+	# Multiply by b[0]
-+	mulx	$acc1, $acc0, $acc1
-+	mulx	$acc2, $t0, $acc2
-+	mov	\$32, $poly1
-+	xor	$acc5, $acc5		# cf=0
-+	mulx	$acc3, $t1, $acc3
-+	mov	.Lpoly+8*3(%rip), $poly3
-+	adc	$t0, $acc1
-+	mulx	$acc4, $t0, $acc4
-+	 mov	$acc0, %rdx
-+	adc	$t1, $acc2
-+	 shlx	$poly1,$acc0,$t1
-+	adc	$t0, $acc3
-+	 shrx	$poly1,$acc0,$t0
-+	adc	\$0, $acc4
-+
-+	########################################################################
-+	# First reduction step
-+	add	$t1, $acc1
-+	adc	$t0, $acc2
-+
-+	mulx	$poly3, $t0, $t1
-+	 mov	8*1($b_ptr), %rdx
-+	adc	$t0, $acc3
-+	adc	$t1, $acc4
-+	adc	\$0, $acc5
-+	xor	$acc0, $acc0		# $acc0=0,cf=0,of=0
-+
-+	########################################################################
-+	# Multiply by b[1]
-+	mulx	8*0+128($a_ptr), $t0, $t1
-+	adcx	$t0, $acc1
-+	adox	$t1, $acc2
-+
-+	mulx	8*1+128($a_ptr), $t0, $t1
-+	adcx	$t0, $acc2
-+	adox	$t1, $acc3
-+
-+	mulx	8*2+128($a_ptr), $t0, $t1
-+	adcx	$t0, $acc3
-+	adox	$t1, $acc4
-+
-+	mulx	8*3+128($a_ptr), $t0, $t1
-+	 mov	$acc1, %rdx
-+	adcx	$t0, $acc4
-+	 shlx	$poly1, $acc1, $t0
-+	adox	$t1, $acc5
-+	 shrx	$poly1, $acc1, $t1
-+
-+	adcx	$acc0, $acc5
-+	adox	$acc0, $acc0
-+	adc	\$0, $acc0
-+
-+	########################################################################
-+	# Second reduction step
-+	add	$t0, $acc2
-+	adc	$t1, $acc3
-+
-+	mulx	$poly3, $t0, $t1
-+	 mov	8*2($b_ptr), %rdx
-+	adc	$t0, $acc4
-+	adc	$t1, $acc5
-+	adc	\$0, $acc0
-+	xor	$acc1 ,$acc1		# $acc1=0,cf=0,of=0
-+
-+	########################################################################
-+	# Multiply by b[2]
-+	mulx	8*0+128($a_ptr), $t0, $t1
-+	adcx	$t0, $acc2
-+	adox	$t1, $acc3
-+
-+	mulx	8*1+128($a_ptr), $t0, $t1
-+	adcx	$t0, $acc3
-+	adox	$t1, $acc4
-+
-+	mulx	8*2+128($a_ptr), $t0, $t1
-+	adcx	$t0, $acc4
-+	adox	$t1, $acc5
-+
-+	mulx	8*3+128($a_ptr), $t0, $t1
-+	 mov	$acc2, %rdx
-+	adcx	$t0, $acc5
-+	 shlx	$poly1, $acc2, $t0
-+	adox	$t1, $acc0
-+	 shrx	$poly1, $acc2, $t1
-+
-+	adcx	$acc1, $acc0
-+	adox	$acc1, $acc1
-+	adc	\$0, $acc1
-+
-+	########################################################################
-+	# Third reduction step
-+	add	$t0, $acc3
-+	adc	$t1, $acc4
-+
-+	mulx	$poly3, $t0, $t1
-+	 mov	8*3($b_ptr), %rdx
-+	adc	$t0, $acc5
-+	adc	$t1, $acc0
-+	adc	\$0, $acc1
-+	xor	$acc2, $acc2		# $acc2=0,cf=0,of=0
-+
-+	########################################################################
-+	# Multiply by b[3]
-+	mulx	8*0+128($a_ptr), $t0, $t1
-+	adcx	$t0, $acc3
-+	adox	$t1, $acc4
-+
-+	mulx	8*1+128($a_ptr), $t0, $t1
-+	adcx	$t0, $acc4
-+	adox	$t1, $acc5
-+
-+	mulx	8*2+128($a_ptr), $t0, $t1
-+	adcx	$t0, $acc5
-+	adox	$t1, $acc0
-+
-+	mulx	8*3+128($a_ptr), $t0, $t1
-+	 mov	$acc3, %rdx
-+	adcx	$t0, $acc0
-+	 shlx	$poly1, $acc3, $t0
-+	adox	$t1, $acc1
-+	 shrx	$poly1, $acc3, $t1
-+
-+	adcx	$acc2, $acc1
-+	adox	$acc2, $acc2
-+	adc	\$0, $acc2
-+
-+	########################################################################
-+	# Fourth reduction step
-+	add	$t0, $acc4
-+	adc	$t1, $acc5
-+
-+	mulx	$poly3, $t0, $t1
-+	 mov	$acc4, $t2
-+	mov	.Lpoly+8*1(%rip), $poly1
-+	adc	$t0, $acc0
-+	 mov	$acc5, $t3
-+	adc	$t1, $acc1
-+	adc	\$0, $acc2
-+
-+	########################################################################
-+	# Branch-less conditional subtraction of P
-+	xor	%eax, %eax
-+	 mov	$acc0, $t0
-+	sbb	\$-1, $acc4		# .Lpoly[0]
-+	sbb	$poly1, $acc5		# .Lpoly[1]
-+	sbb	\$0, $acc0		# .Lpoly[2]
-+	 mov	$acc1, $t1
-+	sbb	$poly3, $acc1		# .Lpoly[3]
-+	sbb	\$0, $acc2
-+
-+	cmovc	$t2, $acc4
-+	cmovc	$t3, $acc5
-+	mov	$acc4, 8*0($r_ptr)
-+	cmovc	$t0, $acc0
-+	mov	$acc5, 8*1($r_ptr)
-+	cmovc	$t1, $acc1
-+	mov	$acc0, 8*2($r_ptr)
-+	mov	$acc1, 8*3($r_ptr)
-+
-+	ret
-+.size	__ecp_nistz256_mul_montx,.-__ecp_nistz256_mul_montx
-+
-+.type	__ecp_nistz256_sqr_montx,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_sqr_montx:
-+	mulx	$acc6, $acc1, $acc2	# a[0]*a[1]
-+	mulx	$acc7, $t0, $acc3	# a[0]*a[2]
-+	xor	%eax, %eax
-+	adc	$t0, $acc2
-+	mulx	$acc0, $t1, $acc4	# a[0]*a[3]
-+	 mov	$acc6, %rdx
-+	adc	$t1, $acc3
-+	adc	\$0, $acc4
-+	xor	$acc5, $acc5		# $acc5=0,cf=0,of=0
-+
-+	#################################
-+	mulx	$acc7, $t0, $t1		# a[1]*a[2]
-+	adcx	$t0, $acc3
-+	adox	$t1, $acc4
-+
-+	mulx	$acc0, $t0, $t1		# a[1]*a[3]
-+	 mov	$acc7, %rdx
-+	adcx	$t0, $acc4
-+	adox	$t1, $acc5
-+	adc	\$0, $acc5
-+
-+	#################################
-+	mulx	$acc0, $t0, $acc6	# a[2]*a[3]
-+	 mov	8*0+128($a_ptr), %rdx
-+	xor	$acc7, $acc7		# $acc7=0,cf=0,of=0
-+	 adcx	$acc1, $acc1		# acc1:6<<1
-+	adox	$t0, $acc5
-+	 adcx	$acc2, $acc2
-+	adox	$acc7, $acc6		# of=0
-+
-+	mulx	%rdx, $acc0, $t1
-+	mov	8*1+128($a_ptr), %rdx
-+	 adcx	$acc3, $acc3
-+	adox	$t1, $acc1
-+	 adcx	$acc4, $acc4
-+	mulx	%rdx, $t0, $t4
-+	mov	8*2+128($a_ptr), %rdx
-+	 adcx	$acc5, $acc5
-+	adox	$t0, $acc2
-+	 adcx	$acc6, $acc6
-+	.byte	0x67
-+	mulx	%rdx, $t0, $t1
-+	mov	8*3+128($a_ptr), %rdx
-+	adox	$t4, $acc3
-+	 adcx	$acc7, $acc7
-+	adox	$t0, $acc4
-+	 mov	\$32, $a_ptr
-+	adox	$t1, $acc5
-+	.byte	0x67,0x67
-+	mulx	%rdx, $t0, $t4
-+	 mov	$acc0, %rdx
-+	adox	$t0, $acc6
-+	 shlx	$a_ptr, $acc0, $t0
-+	adox	$t4, $acc7
-+	 shrx	$a_ptr, $acc0, $t4
-+	 mov	.Lpoly+8*3(%rip), $t1
-+
-+	# reduction step 1
-+	add	$t0, $acc1
-+	adc	$t4, $acc2
-+
-+	mulx	$t1, $t0, $acc0
-+	 mov	$acc1, %rdx
-+	adc	$t0, $acc3
-+	 shlx	$a_ptr, $acc1, $t0
-+	adc	\$0, $acc0
-+	 shrx	$a_ptr, $acc1, $t4
-+
-+	# reduction step 2
-+	add	$t0, $acc2
-+	adc	$t4, $acc3
-+
-+	mulx	$t1, $t0, $acc1
-+	 mov	$acc2, %rdx
-+	adc	$t0, $acc0
-+	 shlx	$a_ptr, $acc2, $t0
-+	adc	\$0, $acc1
-+	 shrx	$a_ptr, $acc2, $t4
-+
-+	# reduction step 3
-+	add	$t0, $acc3
-+	adc	$t4, $acc0
-+
-+	mulx	$t1, $t0, $acc2
-+	 mov	$acc3, %rdx
-+	adc	$t0, $acc1
-+	 shlx	$a_ptr, $acc3, $t0
-+	adc	\$0, $acc2
-+	 shrx	$a_ptr, $acc3, $t4
-+
-+	# reduction step 4
-+	add	$t0, $acc0
-+	adc	$t4, $acc1
-+
-+	mulx	$t1, $t0, $acc3
-+	adc	$t0, $acc2
-+	adc	\$0, $acc3
-+
-+	xor	$t3, $t3		# cf=0
-+	adc	$acc0, $acc4		# accumulate upper half
-+	 mov	.Lpoly+8*1(%rip), $a_ptr
-+	adc	$acc1, $acc5
-+	 mov	$acc4, $acc0
-+	adc	$acc2, $acc6
-+	adc	$acc3, $acc7
-+	 mov	$acc5, $acc1
-+	adc	\$0, $t3
-+
-+	xor	%eax, %eax		# cf=0
-+	sbb	\$-1, $acc4		# .Lpoly[0]
-+	 mov	$acc6, $acc2
-+	sbb	$a_ptr, $acc5		# .Lpoly[1]
-+	sbb	\$0, $acc6		# .Lpoly[2]
-+	 mov	$acc7, $acc3
-+	sbb	$t1, $acc7		# .Lpoly[3]
-+	sbb	\$0, $t3
-+
-+	cmovc	$acc0, $acc4
-+	cmovc	$acc1, $acc5
-+	mov	$acc4, 8*0($r_ptr)
-+	cmovc	$acc2, $acc6
-+	mov	$acc5, 8*1($r_ptr)
-+	cmovc	$acc3, $acc7
-+	mov	$acc6, 8*2($r_ptr)
-+	mov	$acc7, 8*3($r_ptr)
-+
-+	ret
-+.size	__ecp_nistz256_sqr_montx,.-__ecp_nistz256_sqr_montx
-+___
-+}
-+}
-+{
-+my ($r_ptr,$in_ptr)=("%rdi","%rsi");
-+my ($acc0,$acc1,$acc2,$acc3)=map("%r$_",(8..11));
-+my ($t0,$t1,$t2)=("%rcx","%r12","%r13");
-+
-+$code.=<<___;
-+################################################################################
-+# void ecp_nistz256_from_mont(
-+#   uint64_t res[4],
-+#   uint64_t in[4]);
-+# This one performs Montgomery multiplication by 1, so we only need the reduction
-+
-+.globl	ecp_nistz256_from_mont
-+.type	ecp_nistz256_from_mont,\@function,2
-+.align	32
-+ecp_nistz256_from_mont:
-+	push	%r12
-+	push	%r13
-+
-+	mov	8*0($in_ptr), %rax
-+	mov	.Lpoly+8*3(%rip), $t2
-+	mov	8*1($in_ptr), $acc1
-+	mov	8*2($in_ptr), $acc2
-+	mov	8*3($in_ptr), $acc3
-+	mov	%rax, $acc0
-+	mov	.Lpoly+8*1(%rip), $t1
-+
-+	#########################################
-+	# First iteration
-+	mov	%rax, $t0
-+	shl	\$32, $acc0
-+	mulq	$t2
-+	shr	\$32, $t0
-+	add	$acc0, $acc1
-+	adc	$t0, $acc2
-+	adc	%rax, $acc3
-+	 mov	$acc1, %rax
-+	adc	\$0, %rdx
-+
-+	#########################################
-+	# Second iteration
-+	mov	$acc1, $t0
-+	shl	\$32, $acc1
-+	mov	%rdx, $acc0
-+	mulq	$t2
-+	shr	\$32, $t0
-+	add	$acc1, $acc2
-+	adc	$t0, $acc3
-+	adc	%rax, $acc0
-+	 mov	$acc2, %rax
-+	adc	\$0, %rdx
-+
-+	##########################################
-+	# Third iteration
-+	mov	$acc2, $t0
-+	shl	\$32, $acc2
-+	mov	%rdx, $acc1
-+	mulq	$t2
-+	shr	\$32, $t0
-+	add	$acc2, $acc3
-+	adc	$t0, $acc0
-+	adc	%rax, $acc1
-+	 mov	$acc3, %rax
-+	adc	\$0, %rdx
-+
-+	###########################################
-+	# Last iteration
-+	mov	$acc3, $t0
-+	shl	\$32, $acc3
-+	mov	%rdx, $acc2
-+	mulq	$t2
-+	shr	\$32, $t0
-+	add	$acc3, $acc0
-+	adc	$t0, $acc1
-+	 mov	$acc0, $t0
-+	adc	%rax, $acc2
-+	 mov	$acc1, $in_ptr
-+	adc	\$0, %rdx
-+
-+	###########################################
-+	# Branch-less conditional subtraction
-+	sub	\$-1, $acc0
-+	 mov	$acc2, %rax
-+	sbb	$t1, $acc1
-+	sbb	\$0, $acc2
-+	 mov	%rdx, $acc3
-+	sbb	$t2, %rdx
-+	sbb	$t2, $t2
-+
-+	cmovnz	$t0, $acc0
-+	cmovnz	$in_ptr, $acc1
-+	mov	$acc0, 8*0($r_ptr)
-+	cmovnz	%rax, $acc2
-+	mov	$acc1, 8*1($r_ptr)
-+	cmovz	%rdx, $acc3
-+	mov	$acc2, 8*2($r_ptr)
-+	mov	$acc3, 8*3($r_ptr)
-+
-+	pop	%r13
-+	pop	%r12
-+	ret
-+.size	ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
-+___
-+}
-+{
-+my ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx");
-+my ($ONE,$INDEX,$Ra,$Rb,$Rc,$Rd,$Re,$Rf)=map("%xmm$_",(0..7));
-+my ($M0,$T0a,$T0b,$T0c,$T0d,$T0e,$T0f,$TMP0)=map("%xmm$_",(8..15));
-+my ($M1,$T2a,$T2b,$TMP2,$M2,$T2a,$T2b,$TMP2)=map("%xmm$_",(8..15));
-+
-+$code.=<<___;
-+################################################################################
-+# void ecp_nistz256_scatter_w5(uint64_t *val, uint64_t *in_t, int index);
-+.globl	ecp_nistz256_scatter_w5
-+.type	ecp_nistz256_scatter_w5,\@abi-omnipotent
-+.align	32
-+ecp_nistz256_scatter_w5:
-+	lea	-3($index,$index,2), $index
-+	movdqa	0x00($in_t), %xmm0
-+	shl	\$5, $index
-+	movdqa	0x10($in_t), %xmm1
-+	movdqa	0x20($in_t), %xmm2
-+	movdqa	0x30($in_t), %xmm3
-+	movdqa	0x40($in_t), %xmm4
-+	movdqa	0x50($in_t), %xmm5
-+	movdqa	%xmm0, 0x00($val,$index)
-+	movdqa	%xmm1, 0x10($val,$index)
-+	movdqa	%xmm2, 0x20($val,$index)
-+	movdqa	%xmm3, 0x30($val,$index)
-+	movdqa	%xmm4, 0x40($val,$index)
-+	movdqa	%xmm5, 0x50($val,$index)
-+
-+	ret
-+.size	ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5
-+
-+################################################################################
-+# void ecp_nistz256_gather_w5(uint64_t *val, uint64_t *in_t, int index);
-+.globl	ecp_nistz256_gather_w5
-+.type	ecp_nistz256_gather_w5,\@abi-omnipotent
-+.align	32
-+ecp_nistz256_gather_w5:
-+___
-+$code.=<<___	if ($avx>1);
-+	mov	OPENSSL_ia32cap_P+8(%rip), %eax
-+	test	\$`1<<5`, %eax
-+	jnz	.Lavx2_gather_w5
-+___
-+$code.=<<___	if ($win64);
-+	lea	-0x88(%rsp), %rax
-+.LSEH_begin_ecp_nistz256_gather_w5:
-+	.byte	0x48,0x8d,0x60,0xe0		#lea	-0x20(%rax), %rsp
-+	.byte	0x0f,0x29,0x70,0xe0		#movaps	%xmm6, -0x20(%rax)
-+	.byte	0x0f,0x29,0x78,0xf0		#movaps	%xmm7, -0x10(%rax)
-+	.byte	0x44,0x0f,0x29,0x00		#movaps	%xmm8, 0(%rax)
-+	.byte	0x44,0x0f,0x29,0x48,0x10	#movaps	%xmm9, 0x10(%rax)
-+	.byte	0x44,0x0f,0x29,0x50,0x20	#movaps	%xmm10, 0x20(%rax)
-+	.byte	0x44,0x0f,0x29,0x58,0x30	#movaps	%xmm11, 0x30(%rax)
-+	.byte	0x44,0x0f,0x29,0x60,0x40	#movaps	%xmm12, 0x40(%rax)
-+	.byte	0x44,0x0f,0x29,0x68,0x50	#movaps	%xmm13, 0x50(%rax)
-+	.byte	0x44,0x0f,0x29,0x70,0x60	#movaps	%xmm14, 0x60(%rax)
-+	.byte	0x44,0x0f,0x29,0x78,0x70	#movaps	%xmm15, 0x70(%rax)
-+___
-+$code.=<<___;
-+	movdqa	.LOne(%rip), $ONE
-+	movd	$index, $INDEX
-+
-+	pxor	$Ra, $Ra
-+	pxor	$Rb, $Rb
-+	pxor	$Rc, $Rc
-+	pxor	$Rd, $Rd
-+	pxor	$Re, $Re
-+	pxor	$Rf, $Rf
-+
-+	movdqa	$ONE, $M0
-+	pshufd	\$0, $INDEX, $INDEX
-+
-+	mov	\$16, %rax
-+.Lselect_loop_sse_w5:
-+
-+	movdqa	$M0, $TMP0
-+	paddd	$ONE, $M0
-+	pcmpeqd $INDEX, $TMP0
-+
-+	movdqa	16*0($in_t), $T0a
-+	movdqa	16*1($in_t), $T0b
-+	movdqa	16*2($in_t), $T0c
-+	movdqa	16*3($in_t), $T0d
-+	movdqa	16*4($in_t), $T0e
-+	movdqa	16*5($in_t), $T0f
-+	lea 16*6($in_t), $in_t
-+
-+	pand	$TMP0, $T0a
-+	pand	$TMP0, $T0b
-+	por	$T0a, $Ra
-+	pand	$TMP0, $T0c
-+	por	$T0b, $Rb
-+	pand	$TMP0, $T0d
-+	por	$T0c, $Rc
-+	pand	$TMP0, $T0e
-+	por	$T0d, $Rd
-+	pand	$TMP0, $T0f
-+	por	$T0e, $Re
-+	por	$T0f, $Rf
-+
-+	dec	%rax
-+	jnz	.Lselect_loop_sse_w5
-+
-+	movdqu	$Ra, 16*0($val)
-+	movdqu	$Rb, 16*1($val)
-+	movdqu	$Rc, 16*2($val)
-+	movdqu	$Rd, 16*3($val)
-+	movdqu	$Re, 16*4($val)
-+	movdqu	$Rf, 16*5($val)
-+___
-+$code.=<<___	if ($win64);
-+	movaps	(%rsp), %xmm6
-+	movaps	0x10(%rsp), %xmm7
-+	movaps	0x20(%rsp), %xmm8
-+	movaps	0x30(%rsp), %xmm9
-+	movaps	0x40(%rsp), %xmm10
-+	movaps	0x50(%rsp), %xmm11
-+	movaps	0x60(%rsp), %xmm12
-+	movaps	0x70(%rsp), %xmm13
-+	movaps	0x80(%rsp), %xmm14
-+	movaps	0x90(%rsp), %xmm15
-+	lea	0xa8(%rsp), %rsp
-+.LSEH_end_ecp_nistz256_gather_w5:
-+___
-+$code.=<<___;
-+	ret
-+.size	ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5
-+
-+################################################################################
-+# void ecp_nistz256_scatter_w7(uint64_t *val, uint64_t *in_t, int index);
-+.globl	ecp_nistz256_scatter_w7
-+.type	ecp_nistz256_scatter_w7,\@abi-omnipotent
-+.align	32
-+ecp_nistz256_scatter_w7:
-+	movdqu	0x00($in_t), %xmm0
-+	shl	\$6, $index
-+	movdqu	0x10($in_t), %xmm1
-+	movdqu	0x20($in_t), %xmm2
-+	movdqu	0x30($in_t), %xmm3
-+	movdqa	%xmm0, 0x00($val,$index)
-+	movdqa	%xmm1, 0x10($val,$index)
-+	movdqa	%xmm2, 0x20($val,$index)
-+	movdqa	%xmm3, 0x30($val,$index)
-+
-+	ret
-+.size	ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7
-+
-+################################################################################
-+# void ecp_nistz256_gather_w7(uint64_t *val, uint64_t *in_t, int index);
-+.globl	ecp_nistz256_gather_w7
-+.type	ecp_nistz256_gather_w7,\@abi-omnipotent
-+.align	32
-+ecp_nistz256_gather_w7:
-+___
-+$code.=<<___	if ($avx>1);
-+	mov	OPENSSL_ia32cap_P+8(%rip), %eax
-+	test	\$`1<<5`, %eax
-+	jnz	.Lavx2_gather_w7
-+___
-+$code.=<<___	if ($win64);
-+	lea	-0x88(%rsp), %rax
-+.LSEH_begin_ecp_nistz256_gather_w7:
-+	.byte	0x48,0x8d,0x60,0xe0		#lea	-0x20(%rax), %rsp
-+	.byte	0x0f,0x29,0x70,0xe0		#movaps	%xmm6, -0x20(%rax)
-+	.byte	0x0f,0x29,0x78,0xf0		#movaps	%xmm7, -0x10(%rax)
-+	.byte	0x44,0x0f,0x29,0x00		#movaps	%xmm8, 0(%rax)
-+	.byte	0x44,0x0f,0x29,0x48,0x10	#movaps	%xmm9, 0x10(%rax)
-+	.byte	0x44,0x0f,0x29,0x50,0x20	#movaps	%xmm10, 0x20(%rax)
-+	.byte	0x44,0x0f,0x29,0x58,0x30	#movaps	%xmm11, 0x30(%rax)
-+	.byte	0x44,0x0f,0x29,0x60,0x40	#movaps	%xmm12, 0x40(%rax)
-+	.byte	0x44,0x0f,0x29,0x68,0x50	#movaps	%xmm13, 0x50(%rax)
-+	.byte	0x44,0x0f,0x29,0x70,0x60	#movaps	%xmm14, 0x60(%rax)
-+	.byte	0x44,0x0f,0x29,0x78,0x70	#movaps	%xmm15, 0x70(%rax)
-+___
-+$code.=<<___;
-+	movdqa	.LOne(%rip), $M0
-+	movd	$index, $INDEX
-+
-+	pxor	$Ra, $Ra
-+	pxor	$Rb, $Rb
-+	pxor	$Rc, $Rc
-+	pxor	$Rd, $Rd
-+
-+	movdqa	$M0, $ONE
-+	pshufd	\$0, $INDEX, $INDEX
-+	mov	\$64, %rax
-+
-+.Lselect_loop_sse_w7:
-+	movdqa	$M0, $TMP0
-+	paddd	$ONE, $M0
-+	movdqa	16*0($in_t), $T0a
-+	movdqa	16*1($in_t), $T0b
-+	pcmpeqd	$INDEX, $TMP0
-+	movdqa	16*2($in_t), $T0c
-+	movdqa	16*3($in_t), $T0d
-+	lea	16*4($in_t), $in_t
-+
-+	pand	$TMP0, $T0a
-+	pand	$TMP0, $T0b
-+	por	$T0a, $Ra
-+	pand	$TMP0, $T0c
-+	por	$T0b, $Rb
-+	pand	$TMP0, $T0d
-+	por	$T0c, $Rc
-+	prefetcht0	255($in_t)
-+	por	$T0d, $Rd
-+
-+	dec	%rax
-+	jnz	.Lselect_loop_sse_w7
-+
-+	movdqu	$Ra, 16*0($val)
-+	movdqu	$Rb, 16*1($val)
-+	movdqu	$Rc, 16*2($val)
-+	movdqu	$Rd, 16*3($val)
-+___
-+$code.=<<___	if ($win64);
-+	movaps	(%rsp), %xmm6
-+	movaps	0x10(%rsp), %xmm7
-+	movaps	0x20(%rsp), %xmm8
-+	movaps	0x30(%rsp), %xmm9
-+	movaps	0x40(%rsp), %xmm10
-+	movaps	0x50(%rsp), %xmm11
-+	movaps	0x60(%rsp), %xmm12
-+	movaps	0x70(%rsp), %xmm13
-+	movaps	0x80(%rsp), %xmm14
-+	movaps	0x90(%rsp), %xmm15
-+	lea	0xa8(%rsp), %rsp
-+.LSEH_end_ecp_nistz256_gather_w7:
-+___
-+$code.=<<___;
-+	ret
-+.size	ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7
-+___
-+}
-+if ($avx>1) {
-+my ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx");
-+my ($TWO,$INDEX,$Ra,$Rb,$Rc)=map("%ymm$_",(0..4));
-+my ($M0,$T0a,$T0b,$T0c,$TMP0)=map("%ymm$_",(5..9));
-+my ($M1,$T1a,$T1b,$T1c,$TMP1)=map("%ymm$_",(10..14));
-+
-+$code.=<<___;
-+################################################################################
-+# void ecp_nistz256_avx2_gather_w5(uint64_t *val, uint64_t *in_t, int index);
-+.type	ecp_nistz256_avx2_gather_w5,\@abi-omnipotent
-+.align	32
-+ecp_nistz256_avx2_gather_w5:
-+.Lavx2_gather_w5:
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	lea	-0x88(%rsp), %rax
-+.LSEH_begin_ecp_nistz256_avx2_gather_w5:
-+	.byte	0x48,0x8d,0x60,0xe0		#lea	-0x20(%rax), %rsp
-+	.byte	0xc5,0xf8,0x29,0x70,0xe0	#vmovaps %xmm6, -0x20(%rax)
-+	.byte	0xc5,0xf8,0x29,0x78,0xf0	#vmovaps %xmm7, -0x10(%rax)
-+	.byte	0xc5,0x78,0x29,0x40,0x00	#vmovaps %xmm8, 8(%rax)
-+	.byte	0xc5,0x78,0x29,0x48,0x10	#vmovaps %xmm9, 0x10(%rax)
-+	.byte	0xc5,0x78,0x29,0x50,0x20	#vmovaps %xmm10, 0x20(%rax)
-+	.byte	0xc5,0x78,0x29,0x58,0x30	#vmovaps %xmm11, 0x30(%rax)
-+	.byte	0xc5,0x78,0x29,0x60,0x40	#vmovaps %xmm12, 0x40(%rax)
-+	.byte	0xc5,0x78,0x29,0x68,0x50	#vmovaps %xmm13, 0x50(%rax)
-+	.byte	0xc5,0x78,0x29,0x70,0x60	#vmovaps %xmm14, 0x60(%rax)
-+	.byte	0xc5,0x78,0x29,0x78,0x70	#vmovaps %xmm15, 0x70(%rax)
-+___
-+$code.=<<___;
-+	vmovdqa	.LTwo(%rip), $TWO
-+
-+	vpxor	$Ra, $Ra, $Ra
-+	vpxor	$Rb, $Rb, $Rb
-+	vpxor	$Rc, $Rc, $Rc
-+
-+	vmovdqa .LOne(%rip), $M0
-+	vmovdqa .LTwo(%rip), $M1
-+
-+	vmovd	$index, %xmm1
-+	vpermd	$INDEX, $Ra, $INDEX
-+
-+	mov	\$8, %rax
-+.Lselect_loop_avx2_w5:
-+
-+	vmovdqa	32*0($in_t), $T0a
-+	vmovdqa	32*1($in_t), $T0b
-+	vmovdqa	32*2($in_t), $T0c
-+
-+	vmovdqa	32*3($in_t), $T1a
-+	vmovdqa	32*4($in_t), $T1b
-+	vmovdqa	32*5($in_t), $T1c
-+
-+	vpcmpeqd	$INDEX, $M0, $TMP0
-+	vpcmpeqd	$INDEX, $M1, $TMP1
-+
-+	vpaddd	$TWO, $M0, $M0
-+	vpaddd	$TWO, $M1, $M1
-+	lea	32*6($in_t), $in_t
-+
-+	vpand	$TMP0, $T0a, $T0a
-+	vpand	$TMP0, $T0b, $T0b
-+	vpand	$TMP0, $T0c, $T0c
-+	vpand	$TMP1, $T1a, $T1a
-+	vpand	$TMP1, $T1b, $T1b
-+	vpand	$TMP1, $T1c, $T1c
-+
-+	vpxor	$T0a, $Ra, $Ra
-+	vpxor	$T0b, $Rb, $Rb
-+	vpxor	$T0c, $Rc, $Rc
-+	vpxor	$T1a, $Ra, $Ra
-+	vpxor	$T1b, $Rb, $Rb
-+	vpxor	$T1c, $Rc, $Rc
-+
-+	dec %rax
-+	jnz .Lselect_loop_avx2_w5
-+
-+	vmovdqu $Ra, 32*0($val)
-+	vmovdqu $Rb, 32*1($val)
-+	vmovdqu $Rc, 32*2($val)
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	movaps	(%rsp), %xmm6
-+	movaps	0x10(%rsp), %xmm7
-+	movaps	0x20(%rsp), %xmm8
-+	movaps	0x30(%rsp), %xmm9
-+	movaps	0x40(%rsp), %xmm10
-+	movaps	0x50(%rsp), %xmm11
-+	movaps	0x60(%rsp), %xmm12
-+	movaps	0x70(%rsp), %xmm13
-+	movaps	0x80(%rsp), %xmm14
-+	movaps	0x90(%rsp), %xmm15
-+	lea	0xa8(%rsp), %rsp
-+.LSEH_end_ecp_nistz256_avx2_gather_w5:
-+___
-+$code.=<<___;
-+	ret
-+.size	ecp_nistz256_avx2_gather_w5,.-ecp_nistz256_avx2_gather_w5
-+___
-+}
-+if ($avx>1) {
-+my ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx");
-+my ($THREE,$INDEX,$Ra,$Rb)=map("%ymm$_",(0..3));
-+my ($M0,$T0a,$T0b,$TMP0)=map("%ymm$_",(4..7));
-+my ($M1,$T1a,$T1b,$TMP1)=map("%ymm$_",(8..11));
-+my ($M2,$T2a,$T2b,$TMP2)=map("%ymm$_",(12..15));
-+
-+$code.=<<___;
-+
-+################################################################################
-+# void ecp_nistz256_avx2_gather_w7(uint64_t *val, uint64_t *in_t, int index);
-+.globl	ecp_nistz256_avx2_gather_w7
-+.type	ecp_nistz256_avx2_gather_w7,\@abi-omnipotent
-+.align	32
-+ecp_nistz256_avx2_gather_w7:
-+.Lavx2_gather_w7:
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	lea	-0x88(%rsp), %rax
-+.LSEH_begin_ecp_nistz256_avx2_gather_w7:
-+	.byte	0x48,0x8d,0x60,0xe0		#lea	-0x20(%rax), %rsp
-+	.byte	0xc5,0xf8,0x29,0x70,0xe0	#vmovaps %xmm6, -0x20(%rax)
-+	.byte	0xc5,0xf8,0x29,0x78,0xf0	#vmovaps %xmm7, -0x10(%rax)
-+	.byte	0xc5,0x78,0x29,0x40,0x00	#vmovaps %xmm8, 8(%rax)
-+	.byte	0xc5,0x78,0x29,0x48,0x10	#vmovaps %xmm9, 0x10(%rax)
-+	.byte	0xc5,0x78,0x29,0x50,0x20	#vmovaps %xmm10, 0x20(%rax)
-+	.byte	0xc5,0x78,0x29,0x58,0x30	#vmovaps %xmm11, 0x30(%rax)
-+	.byte	0xc5,0x78,0x29,0x60,0x40	#vmovaps %xmm12, 0x40(%rax)
-+	.byte	0xc5,0x78,0x29,0x68,0x50	#vmovaps %xmm13, 0x50(%rax)
-+	.byte	0xc5,0x78,0x29,0x70,0x60	#vmovaps %xmm14, 0x60(%rax)
-+	.byte	0xc5,0x78,0x29,0x78,0x70	#vmovaps %xmm15, 0x70(%rax)
-+___
-+$code.=<<___;
-+	vmovdqa	.LThree(%rip), $THREE
-+
-+	vpxor	$Ra, $Ra, $Ra
-+	vpxor	$Rb, $Rb, $Rb
-+
-+	vmovdqa .LOne(%rip), $M0
-+	vmovdqa .LTwo(%rip), $M1
-+	vmovdqa .LThree(%rip), $M2
-+
-+	vmovd	$index, %xmm1
-+	vpermd	$INDEX, $Ra, $INDEX
-+	# Skip index = 0, because it is implicitly the point at infinity
-+
-+	mov	\$21, %rax
-+.Lselect_loop_avx2_w7:
-+
-+	vmovdqa	32*0($in_t), $T0a
-+	vmovdqa	32*1($in_t), $T0b
-+
-+	vmovdqa	32*2($in_t), $T1a
-+	vmovdqa	32*3($in_t), $T1b
-+
-+	vmovdqa	32*4($in_t), $T2a
-+	vmovdqa	32*5($in_t), $T2b
-+
-+	vpcmpeqd	$INDEX, $M0, $TMP0
-+	vpcmpeqd	$INDEX, $M1, $TMP1
-+	vpcmpeqd	$INDEX, $M2, $TMP2
-+
-+	vpaddd	$THREE, $M0, $M0
-+	vpaddd	$THREE, $M1, $M1
-+	vpaddd	$THREE, $M2, $M2
-+	lea	32*6($in_t), $in_t
-+
-+	vpand	$TMP0, $T0a, $T0a
-+	vpand	$TMP0, $T0b, $T0b
-+	vpand	$TMP1, $T1a, $T1a
-+	vpand	$TMP1, $T1b, $T1b
-+	vpand	$TMP2, $T2a, $T2a
-+	vpand	$TMP2, $T2b, $T2b
-+
-+	vpxor	$T0a, $Ra, $Ra
-+	vpxor	$T0b, $Rb, $Rb
-+	vpxor	$T1a, $Ra, $Ra
-+	vpxor	$T1b, $Rb, $Rb
-+	vpxor	$T2a, $Ra, $Ra
-+	vpxor	$T2b, $Rb, $Rb
-+
-+	dec %rax
-+	jnz .Lselect_loop_avx2_w7
-+
-+
-+	vmovdqa	32*0($in_t), $T0a
-+	vmovdqa	32*1($in_t), $T0b
-+
-+	vpcmpeqd	$INDEX, $M0, $TMP0
-+
-+	vpand	$TMP0, $T0a, $T0a
-+	vpand	$TMP0, $T0b, $T0b
-+
-+	vpxor	$T0a, $Ra, $Ra
-+	vpxor	$T0b, $Rb, $Rb
-+
-+	vmovdqu $Ra, 32*0($val)
-+	vmovdqu $Rb, 32*1($val)
-+	vzeroupper
-+___
-+$code.=<<___	if ($win64);
-+	movaps	(%rsp), %xmm6
-+	movaps	0x10(%rsp), %xmm7
-+	movaps	0x20(%rsp), %xmm8
-+	movaps	0x30(%rsp), %xmm9
-+	movaps	0x40(%rsp), %xmm10
-+	movaps	0x50(%rsp), %xmm11
-+	movaps	0x60(%rsp), %xmm12
-+	movaps	0x70(%rsp), %xmm13
-+	movaps	0x80(%rsp), %xmm14
-+	movaps	0x90(%rsp), %xmm15
-+	lea	0xa8(%rsp), %rsp
-+.LSEH_end_ecp_nistz256_avx2_gather_w7:
-+___
-+$code.=<<___;
-+	ret
-+.size	ecp_nistz256_avx2_gather_w7,.-ecp_nistz256_avx2_gather_w7
-+___
-+} else {
-+$code.=<<___;
-+.globl	ecp_nistz256_avx2_gather_w7
-+.type	ecp_nistz256_avx2_gather_w7,\@function,3
-+.align	32
-+ecp_nistz256_avx2_gather_w7:
-+	.byte	0x0f,0x0b	# ud2
-+	ret
-+.size	ecp_nistz256_avx2_gather_w7,.-ecp_nistz256_avx2_gather_w7
-+___
-+}
-+{{{
-+########################################################################
-+# This block implements higher level point_double, point_add and
-+# point_add_affine. The key to performance in this case is to allow
-+# out-of-order execution logic to overlap computations from next step
-+# with tail processing from current step. By using tailored calling
-+# sequence we minimize inter-step overhead to give processor better
-+# shot at overlapping operations...
-+#
-+# You will notice that input data is copied to stack. Trouble is that
-+# there are no registers to spare for holding original pointers and
-+# reloading them, pointers, would create undesired dependencies on
-+# effective addresses calculation paths. In other words it's too done
-+# to favour out-of-order execution logic.
-+#						
-+
-+my ($r_ptr,$a_ptr,$b_org,$b_ptr)=("%rdi","%rsi","%rdx","%rbx");
-+my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7)=map("%r$_",(8..15));
-+my ($t0,$t1,$t2,$t3,$t4)=("%rax","%rbp","%rcx",$acc4,$acc4);
-+my ($poly1,$poly3)=($acc6,$acc7);
-+
-+sub load_for_mul () {
-+my ($a,$b,$src0) = @_;
-+my $bias = $src0 eq "%rax" ? 0 : -128;
-+
-+"	mov	$b, $src0
-+	lea	$b, $b_ptr
-+	mov	8*0+$a, $acc1
-+	mov	8*1+$a, $acc2
-+	lea	$bias+$a, $a_ptr
-+	mov	8*2+$a, $acc3
-+	mov	8*3+$a, $acc4"
-+}
-+
-+sub load_for_sqr () {
-+my ($a,$src0) = @_;
-+my $bias = $src0 eq "%rax" ? 0 : -128;
-+
-+"	mov	8*0+$a, $src0
-+	mov	8*1+$a, $acc6
-+	lea	$bias+$a, $a_ptr
-+	mov	8*2+$a, $acc7
-+	mov	8*3+$a, $acc0"
-+}
-+
-+									{
-+########################################################################
-+# operate in 4-5-0-1 "name space" that matches multiplication output
-+#
-+my ($a0,$a1,$a2,$a3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
-+
-+$code.=<<___;
-+.type	__ecp_nistz256_add_toq,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_add_toq:
-+	xor	$t4,$t4
-+	add	8*0($b_ptr), $a0
-+	adc	8*1($b_ptr), $a1
-+	 mov	$a0, $t0
-+	adc	8*2($b_ptr), $a2
-+	adc	8*3($b_ptr), $a3
-+	 mov	$a1, $t1
-+	adc	\$0, $t4
-+
-+	sub	\$-1, $a0
-+	 mov	$a2, $t2
-+	sbb	$poly1, $a1
-+	sbb	\$0, $a2
-+	 mov	$a3, $t3
-+	sbb	$poly3, $a3
-+	sbb	\$0, $t4
-+
-+	cmovc	$t0, $a0
-+	cmovc	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovc	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovc	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	ret
-+.size	__ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq
-+
-+.type	__ecp_nistz256_sub_fromq,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_sub_fromq:
-+	sub	8*0($b_ptr), $a0
-+	sbb	8*1($b_ptr), $a1
-+	 mov	$a0, $t0
-+	sbb	8*2($b_ptr), $a2
-+	sbb	8*3($b_ptr), $a3
-+	 mov	$a1, $t1
-+	sbb	$t4, $t4
-+
-+	add	\$-1, $a0
-+	 mov	$a2, $t2
-+	adc	$poly1, $a1
-+	adc	\$0, $a2
-+	 mov	$a3, $t3
-+	adc	$poly3, $a3
-+	test	$t4, $t4
-+
-+	cmovz	$t0, $a0
-+	cmovz	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovz	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovz	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	ret
-+.size	__ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq
-+
-+.type	__ecp_nistz256_subq,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_subq:
-+	sub	$a0, $t0
-+	sbb	$a1, $t1
-+	 mov	$t0, $a0
-+	sbb	$a2, $t2
-+	sbb	$a3, $t3
-+	 mov	$t1, $a1
-+	sbb	$t4, $t4
-+
-+	add	\$-1, $t0
-+	 mov	$t2, $a2
-+	adc	$poly1, $t1
-+	adc	\$0, $t2
-+	 mov	$t3, $a3
-+	adc	$poly3, $t3
-+	test	$t4, $t4
-+
-+	cmovnz	$t0, $a0
-+	cmovnz	$t1, $a1
-+	cmovnz	$t2, $a2
-+	cmovnz	$t3, $a3
-+
-+	ret
-+.size	__ecp_nistz256_subq,.-__ecp_nistz256_subq
-+
-+.type	__ecp_nistz256_mul_by_2q,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_mul_by_2q:
-+	xor	$t4, $t4
-+	add	$a0, $a0		# a0:a3+a0:a3
-+	adc	$a1, $a1
-+	 mov	$a0, $t0
-+	adc	$a2, $a2
-+	adc	$a3, $a3
-+	 mov	$a1, $t1
-+	adc	\$0, $t4
-+
-+	sub	\$-1, $a0
-+	 mov	$a2, $t2
-+	sbb	$poly1, $a1
-+	sbb	\$0, $a2
-+	 mov	$a3, $t3
-+	sbb	$poly3, $a3
-+	sbb	\$0, $t4
-+
-+	cmovc	$t0, $a0
-+	cmovc	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovc	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovc	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	ret
-+.size	__ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q
-+___
-+									}
-+sub gen_double () {
-+    my $x = shift;
-+    my ($src0,$sfx,$bias);
-+    my ($S,$M,$Zsqr,$in_x,$tmp0)=map(32*$_,(0..4));
-+
-+    if ($x ne "x") {
-+	$src0 = "%rax";
-+	$sfx  = "";
-+	$bias = 0;
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_double
-+.type	ecp_nistz256_point_double,\@function,2
-+.align	32
-+ecp_nistz256_point_double:
-+___
-+$code.=<<___	if ($addx);
-+	mov	\$0x80100, %ecx
-+	and	OPENSSL_ia32cap_P+8(%rip), %ecx
-+	cmp	\$0x80100, %ecx
-+	je	.Lpoint_doublex
-+___
-+    } else {
-+	$src0 = "%rdx";
-+	$sfx  = "x";
-+	$bias = 128;
-+
-+$code.=<<___;
-+.type	ecp_nistz256_point_doublex,\@function,2
-+.align	32
-+ecp_nistz256_point_doublex:
-+.Lpoint_doublex:
-+___
-+    }
-+$code.=<<___;
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	sub	\$32*5+8, %rsp
-+
-+.Lpoint_double_shortcut$x:
-+	movdqu	0x00($a_ptr), %xmm0		# copy	*(P256_POINT *)$a_ptr.x
-+	mov	$a_ptr, $b_ptr			# backup copy
-+	movdqu	0x10($a_ptr), %xmm1
-+	 mov	0x20+8*0($a_ptr), $acc4		# load in_y in "5-4-0-1" order
-+	 mov	0x20+8*1($a_ptr), $acc5
-+	 mov	0x20+8*2($a_ptr), $acc0
-+	 mov	0x20+8*3($a_ptr), $acc1
-+	 mov	.Lpoly+8*1(%rip), $poly1
-+	 mov	.Lpoly+8*3(%rip), $poly3
-+	movdqa	%xmm0, $in_x(%rsp)
-+	movdqa	%xmm1, $in_x+0x10(%rsp)
-+	lea	0x20($r_ptr), $acc2
-+	lea	0x40($r_ptr), $acc3
-+	movq	$r_ptr, %xmm0
-+	movq	$acc2, %xmm1
-+	movq	$acc3, %xmm2
-+
-+	lea	$S(%rsp), $r_ptr
-+	call	__ecp_nistz256_mul_by_2$x	# p256_mul_by_2(S, in_y);
-+
-+	mov	0x40+8*0($a_ptr), $src0
-+	mov	0x40+8*1($a_ptr), $acc6
-+	mov	0x40+8*2($a_ptr), $acc7
-+	mov	0x40+8*3($a_ptr), $acc0
-+	lea	0x40-$bias($a_ptr), $a_ptr
-+	lea	$Zsqr(%rsp), $r_ptr
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(Zsqr, in_z);
-+
-+	`&load_for_sqr("$S(%rsp)", "$src0")`
-+	lea	$S(%rsp), $r_ptr
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(S, S);
-+
-+	mov	0x20($b_ptr), $src0		# $b_ptr is still valid
-+	mov	0x40+8*0($b_ptr), $acc1
-+	mov	0x40+8*1($b_ptr), $acc2
-+	mov	0x40+8*2($b_ptr), $acc3
-+	mov	0x40+8*3($b_ptr), $acc4
-+	lea	0x40-$bias($b_ptr), $a_ptr
-+	lea	0x20($b_ptr), $b_ptr
-+	movq	%xmm2, $r_ptr
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(res_z, in_z, in_y);
-+	call	__ecp_nistz256_mul_by_2$x	# p256_mul_by_2(res_z, res_z);
-+
-+	mov	$in_x+8*0(%rsp), $acc4		# "5-4-0-1" order
-+	mov	$in_x+8*1(%rsp), $acc5
-+	lea	$Zsqr(%rsp), $b_ptr
-+	mov	$in_x+8*2(%rsp), $acc0
-+	mov	$in_x+8*3(%rsp), $acc1
-+	lea	$M(%rsp), $r_ptr
-+	call	__ecp_nistz256_add_to$x		# p256_add(M, in_x, Zsqr);
-+
-+	mov	$in_x+8*0(%rsp), $acc4		# "5-4-0-1" order
-+	mov	$in_x+8*1(%rsp), $acc5
-+	lea	$Zsqr(%rsp), $b_ptr
-+	mov	$in_x+8*2(%rsp), $acc0
-+	mov	$in_x+8*3(%rsp), $acc1
-+	lea	$Zsqr(%rsp), $r_ptr
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(Zsqr, in_x, Zsqr);
-+
-+	`&load_for_sqr("$S(%rsp)", "$src0")`
-+	movq	%xmm1, $r_ptr
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(res_y, S);
-+___
-+{	
-+######## ecp_nistz256_div_by_2(res_y, res_y); ##########################
-+# operate in 4-5-6-7 "name space" that matches squaring output
-+#
-+my ($poly1,$poly3)=($a_ptr,$t1);
-+my ($a0,$a1,$a2,$a3,$t3,$t4,$t1)=($acc4,$acc5,$acc6,$acc7,$acc0,$acc1,$acc2);
-+
-+$code.=<<___;
-+	xor	$t4, $t4
-+	mov	$a0, $t0
-+	add	\$-1, $a0
-+	mov	$a1, $t1
-+	adc	$poly1, $a1
-+	mov	$a2, $t2
-+	adc	\$0, $a2
-+	mov	$a3, $t3
-+	adc	$poly3, $a3
-+	adc	\$0, $t4
-+	xor	$a_ptr, $a_ptr		# borrow $a_ptr
-+	test	\$1, $t0
-+
-+	cmovz	$t0, $a0
-+	cmovz	$t1, $a1
-+	cmovz	$t2, $a2
-+	cmovz	$t3, $a3
-+	cmovz	$a_ptr, $t4
-+
-+	mov	$a1, $t0		# a0:a3>>1
-+	shr	\$1, $a0
-+	shl	\$63, $t0
-+	mov	$a2, $t1
-+	shr	\$1, $a1
-+	or	$t0, $a0
-+	shl	\$63, $t1
-+	mov	$a3, $t2
-+	shr	\$1, $a2
-+	or	$t1, $a1
-+	shl	\$63, $t2
-+	mov	$a0, 8*0($r_ptr)
-+	shr	\$1, $a3
-+	mov	$a1, 8*1($r_ptr)
-+	shl	\$63, $t4
-+	or	$t2, $a2
-+	or	$t4, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+___
-+}
-+$code.=<<___;
-+	`&load_for_mul("$M(%rsp)", "$Zsqr(%rsp)", "$src0")`
-+	lea	$M(%rsp), $r_ptr
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(M, M, Zsqr);
-+
-+	lea	$tmp0(%rsp), $r_ptr
-+	call	__ecp_nistz256_mul_by_2$x
-+
-+	lea	$M(%rsp), $b_ptr
-+	lea	$M(%rsp), $r_ptr
-+	call	__ecp_nistz256_add_to$x		# p256_mul_by_3(M, M);
-+
-+	`&load_for_mul("$S(%rsp)", "$in_x(%rsp)", "$src0")`
-+	lea	$S(%rsp), $r_ptr
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(S, S, in_x);
-+
-+	lea	$tmp0(%rsp), $r_ptr
-+	call	__ecp_nistz256_mul_by_2$x	# p256_mul_by_2(tmp0, S);
-+
-+	`&load_for_sqr("$M(%rsp)", "$src0")`
-+	movq	%xmm0, $r_ptr
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(res_x, M);
-+
-+	lea	$tmp0(%rsp), $b_ptr
-+	mov	$acc6, $acc0			# harmonize sqr output and sub input
-+	mov	$acc7, $acc1
-+	mov	$a_ptr, $poly1
-+	mov	$t1, $poly3
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(res_x, res_x, tmp0);
-+
-+	mov	$S+8*0(%rsp), $t0
-+	mov	$S+8*1(%rsp), $t1
-+	mov	$S+8*2(%rsp), $t2
-+	mov	$S+8*3(%rsp), $acc2		# "4-5-0-1" order
-+	lea	$S(%rsp), $r_ptr
-+	call	__ecp_nistz256_sub$x		# p256_sub(S, S, res_x);
-+
-+	mov	$M(%rsp), $src0
-+	lea	$M(%rsp), $b_ptr
-+	mov	$acc4, $acc6			# harmonize sub output and mul input
-+	xor	%ecx, %ecx
-+	mov	$acc4, $S+8*0(%rsp)		# have to save:-(	
-+	mov	$acc5, $acc2
-+	mov	$acc5, $S+8*1(%rsp)
-+	cmovz	$acc0, $acc3
-+	mov	$acc0, $S+8*2(%rsp)
-+	lea	$S-$bias(%rsp), $a_ptr
-+	cmovz	$acc1, $acc4
-+	mov	$acc1, $S+8*3(%rsp)
-+	mov	$acc6, $acc1
-+	lea	$S(%rsp), $r_ptr
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(S, S, M);
-+
-+	movq	%xmm1, $b_ptr
-+	movq	%xmm1, $r_ptr
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(res_y, S, res_y);
-+
-+	add	\$32*5+8, %rsp
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbx
-+	pop	%rbp
-+	ret
-+.size	ecp_nistz256_point_double$sfx,.-ecp_nistz256_point_double$sfx
-+___
-+}
-+&gen_double("q");
-+
-+sub gen_add () {
-+    my $x = shift;
-+    my ($src0,$sfx,$bias);
-+    my ($H,$Hsqr,$R,$Rsqr,$Hcub,
-+	$U1,$U2,$S1,$S2,
-+	$res_x,$res_y,$res_z,
-+	$in1_x,$in1_y,$in1_z,
-+	$in2_x,$in2_y,$in2_z)=map(32*$_,(0..17));
-+    my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
-+
-+    if ($x ne "x") {
-+	$src0 = "%rax";
-+	$sfx  = "";
-+	$bias = 0;
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_add
-+.type	ecp_nistz256_point_add,\@function,3
-+.align	32
-+ecp_nistz256_point_add:
-+___
-+$code.=<<___	if ($addx);
-+	mov	\$0x80100, %ecx
-+	and	OPENSSL_ia32cap_P+8(%rip), %ecx
-+	cmp	\$0x80100, %ecx
-+	je	.Lpoint_addx
-+___
-+    } else {
-+	$src0 = "%rdx";
-+	$sfx  = "x";
-+	$bias = 128;
-+
-+$code.=<<___;
-+.type	ecp_nistz256_point_addx,\@function,3
-+.align	32
-+ecp_nistz256_point_addx:
-+.Lpoint_addx:
-+___
-+    }
-+$code.=<<___;
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	sub	\$32*18+8, %rsp
-+
-+	movdqu	0x00($a_ptr), %xmm0		# copy	*(P256_POINT *)$a_ptr
-+	movdqu	0x10($a_ptr), %xmm1
-+	movdqu	0x20($a_ptr), %xmm2
-+	movdqu	0x30($a_ptr), %xmm3
-+	movdqu	0x40($a_ptr), %xmm4
-+	movdqu	0x50($a_ptr), %xmm5
-+	mov	$a_ptr, $b_ptr			# reassign
-+	mov	$b_org, $a_ptr			# reassign
-+	movdqa	%xmm0, $in1_x(%rsp)
-+	movdqa	%xmm1, $in1_x+0x10(%rsp)
-+	movdqa	%xmm2, $in1_y(%rsp)
-+	movdqa	%xmm3, $in1_y+0x10(%rsp)
-+	movdqa	%xmm4, $in1_z(%rsp)
-+	movdqa	%xmm5, $in1_z+0x10(%rsp)
-+	por	%xmm4, %xmm5
-+
-+	movdqu	0x00($a_ptr), %xmm0		# copy	*(P256_POINT *)$b_ptr
-+	 pshufd	\$0xb1, %xmm5, %xmm3
-+	movdqu	0x10($a_ptr), %xmm1
-+	movdqu	0x20($a_ptr), %xmm2
-+	 por	%xmm3, %xmm5
-+	movdqu	0x30($a_ptr), %xmm3
-+	 mov	0x40+8*0($a_ptr), $src0		# load original in2_z
-+	 mov	0x40+8*1($a_ptr), $acc6
-+	 mov	0x40+8*2($a_ptr), $acc7
-+	 mov	0x40+8*3($a_ptr), $acc0
-+	movdqa	%xmm0, $in2_x(%rsp)
-+	 pshufd	\$0x1e, %xmm5, %xmm4
-+	movdqa	%xmm1, $in2_x+0x10(%rsp)
-+	movdqu	0x40($a_ptr),%xmm0		# in2_z again
-+	movdqu	0x50($a_ptr),%xmm1
-+	movdqa	%xmm2, $in2_y(%rsp)
-+	movdqa	%xmm3, $in2_y+0x10(%rsp)
-+	 por	%xmm4, %xmm5
-+	 pxor	%xmm4, %xmm4
-+	por	%xmm0, %xmm1
-+	 movq	$r_ptr, %xmm0			# save $r_ptr
-+
-+	lea	0x40-$bias($a_ptr), $a_ptr	# $a_ptr is still valid
-+	 mov	$src0, $in2_z+8*0(%rsp)		# make in2_z copy
-+	 mov	$acc6, $in2_z+8*1(%rsp)
-+	 mov	$acc7, $in2_z+8*2(%rsp)
-+	 mov	$acc0, $in2_z+8*3(%rsp)
-+	lea	$Z2sqr(%rsp), $r_ptr		# Z2^2
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(Z2sqr, in2_z);
-+
-+	pcmpeqd	%xmm4, %xmm5
-+	pshufd	\$0xb1, %xmm1, %xmm4
-+	por	%xmm1, %xmm4
-+	pshufd	\$0, %xmm5, %xmm5		# in1infty
-+	pshufd	\$0x1e, %xmm4, %xmm3
-+	por	%xmm3, %xmm4
-+	pxor	%xmm3, %xmm3
-+	pcmpeqd	%xmm3, %xmm4
-+	pshufd	\$0, %xmm4, %xmm4		# in2infty
-+	 mov	0x40+8*0($b_ptr), $src0		# load original in1_z
-+	 mov	0x40+8*1($b_ptr), $acc6
-+	 mov	0x40+8*2($b_ptr), $acc7
-+	 mov	0x40+8*3($b_ptr), $acc0
-+	movq	$b_ptr, %xmm1
-+
-+	lea	0x40-$bias($b_ptr), $a_ptr
-+	lea	$Z1sqr(%rsp), $r_ptr		# Z1^2
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(Z1sqr, in1_z);
-+
-+	`&load_for_mul("$Z2sqr(%rsp)", "$in2_z(%rsp)", "$src0")`
-+	lea	$S1(%rsp), $r_ptr		# S1 = Z2^3
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(S1, Z2sqr, in2_z);
-+
-+	`&load_for_mul("$Z1sqr(%rsp)", "$in1_z(%rsp)", "$src0")`
-+	lea	$S2(%rsp), $r_ptr		# S2 = Z1^3
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(S2, Z1sqr, in1_z);
-+
-+	`&load_for_mul("$S1(%rsp)", "$in1_y(%rsp)", "$src0")`
-+	lea	$S1(%rsp), $r_ptr		# S1 = Y1*Z2^3
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(S1, S1, in1_y);
-+
-+	`&load_for_mul("$S2(%rsp)", "$in2_y(%rsp)", "$src0")`
-+	lea	$S2(%rsp), $r_ptr		# S2 = Y2*Z1^3
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(S2, S2, in2_y);
-+
-+	lea	$S1(%rsp), $b_ptr
-+	lea	$R(%rsp), $r_ptr		# R = S2 - S1
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(R, S2, S1);
-+
-+	or	$acc5, $acc4			# see if result is zero
-+	movdqa	%xmm4, %xmm2
-+	or	$acc0, $acc4
-+	or	$acc1, $acc4
-+	por	%xmm5, %xmm2			# in1infty || in2infty
-+	movq	$acc4, %xmm3
-+
-+	`&load_for_mul("$Z2sqr(%rsp)", "$in1_x(%rsp)", "$src0")`
-+	lea	$U1(%rsp), $r_ptr		# U1 = X1*Z2^2
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(U1, in1_x, Z2sqr);
-+
-+	`&load_for_mul("$Z1sqr(%rsp)", "$in2_x(%rsp)", "$src0")`
-+	lea	$U2(%rsp), $r_ptr		# U2 = X2*Z1^2
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(U2, in2_x, Z1sqr);
-+
-+	lea	$U1(%rsp), $b_ptr
-+	lea	$H(%rsp), $r_ptr		# H = U2 - U1
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(H, U2, U1);
-+
-+	or	$acc5, $acc4			# see if result is zero
-+	or	$acc0, $acc4
-+	or	$acc1, $acc4
-+
-+	.byte	0x3e				# predict taken
-+	jnz	.Ladd_proceed$x			# is_equal(U1,U2)?
-+	movq	%xmm2, $acc0
-+	movq	%xmm3, $acc1
-+	test	$acc0, $acc0
-+	jnz	.Ladd_proceed$x			# (in1infty || in2infty)?
-+	test	$acc1, $acc1
-+	jz	.Ladd_double$x			# is_equal(S1,S2)?
-+
-+	movq	%xmm0, $r_ptr			# restore $r_ptr
-+	pxor	%xmm0, %xmm0
-+	movdqu	%xmm0, 0x00($r_ptr)
-+	movdqu	%xmm0, 0x10($r_ptr)
-+	movdqu	%xmm0, 0x20($r_ptr)
-+	movdqu	%xmm0, 0x30($r_ptr)
-+	movdqu	%xmm0, 0x40($r_ptr)
-+	movdqu	%xmm0, 0x50($r_ptr)
-+	jmp	.Ladd_done$x
-+
-+.align	32
-+.Ladd_double$x:
-+	movq	%xmm1, $a_ptr			# restore $a_ptr
-+	movq	%xmm0, $r_ptr			# restore $r_ptr
-+	add	\$`32*(18-5)`, %rsp		# difference in frame sizes
-+	jmp	.Lpoint_double_shortcut$x
-+
-+.align	32
-+.Ladd_proceed$x:
-+	`&load_for_sqr("$R(%rsp)", "$src0")`
-+	lea	$Rsqr(%rsp), $r_ptr		# R^2
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(Rsqr, R);
-+
-+	`&load_for_mul("$H(%rsp)", "$in1_z(%rsp)", "$src0")`
-+	lea	$res_z(%rsp), $r_ptr		# Z3 = H*Z1*Z2
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(res_z, H, in1_z);
-+
-+	`&load_for_sqr("$H(%rsp)", "$src0")`
-+	lea	$Hsqr(%rsp), $r_ptr		# H^2
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(Hsqr, H);
-+
-+	`&load_for_mul("$res_z(%rsp)", "$in2_z(%rsp)", "$src0")`
-+	lea	$res_z(%rsp), $r_ptr		# Z3 = H*Z1*Z2
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(res_z, res_z, in2_z);
-+
-+	`&load_for_mul("$Hsqr(%rsp)", "$H(%rsp)", "$src0")`
-+	lea	$Hcub(%rsp), $r_ptr		# H^3
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(Hcub, Hsqr, H);
-+
-+	`&load_for_mul("$Hsqr(%rsp)", "$U1(%rsp)", "$src0")`
-+	lea	$U2(%rsp), $r_ptr		# U1*H^2
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(U2, U1, Hsqr);
-+___
-+{
-+#######################################################################
-+# operate in 4-5-0-1 "name space" that matches multiplication output
-+#
-+my ($acc0,$acc1,$acc2,$acc3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
-+my ($poly1, $poly3)=($acc6,$acc7);
-+
-+$code.=<<___;
-+	#lea	$U2(%rsp), $a_ptr
-+	#lea	$Hsqr(%rsp), $r_ptr	# 2*U1*H^2
-+	#call	__ecp_nistz256_mul_by_2	# ecp_nistz256_mul_by_2(Hsqr, U2);
-+
-+	xor	$t4, $t4
-+	add	$acc0, $acc0		# a0:a3+a0:a3
-+	lea	$Rsqr(%rsp), $a_ptr
-+	adc	$acc1, $acc1
-+	 mov	$acc0, $t0
-+	adc	$acc2, $acc2
-+	adc	$acc3, $acc3
-+	 mov	$acc1, $t1
-+	adc	\$0, $t4
-+
-+	sub	\$-1, $acc0
-+	 mov	$acc2, $t2
-+	sbb	$poly1, $acc1
-+	sbb	\$0, $acc2
-+	 mov	$acc3, $t3
-+	sbb	$poly3, $acc3
-+	sbb	\$0, $t4
-+
-+	cmovc	$t0, $acc0
-+	mov	8*0($a_ptr), $t0
-+	cmovc	$t1, $acc1
-+	mov	8*1($a_ptr), $t1
-+	cmovc	$t2, $acc2
-+	mov	8*2($a_ptr), $t2
-+	cmovc	$t3, $acc3
-+	mov	8*3($a_ptr), $t3
-+
-+	call	__ecp_nistz256_sub$x		# p256_sub(res_x, Rsqr, Hsqr);
-+
-+	lea	$Hcub(%rsp), $b_ptr
-+	lea	$res_x(%rsp), $r_ptr
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(res_x, res_x, Hcub);
-+
-+	mov	$U2+8*0(%rsp), $t0
-+	mov	$U2+8*1(%rsp), $t1
-+	mov	$U2+8*2(%rsp), $t2
-+	mov	$U2+8*3(%rsp), $t3
-+	lea	$res_y(%rsp), $r_ptr
-+
-+	call	__ecp_nistz256_sub$x		# p256_sub(res_y, U2, res_x);
-+
-+	mov	$acc0, 8*0($r_ptr)		# save the result, as
-+	mov	$acc1, 8*1($r_ptr)		# __ecp_nistz256_sub doesn't
-+	mov	$acc2, 8*2($r_ptr)
-+	mov	$acc3, 8*3($r_ptr)
-+___
-+}
-+$code.=<<___;
-+	`&load_for_mul("$S1(%rsp)", "$Hcub(%rsp)", "$src0")`
-+	lea	$S2(%rsp), $r_ptr
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(S2, S1, Hcub);
-+
-+	`&load_for_mul("$R(%rsp)", "$res_y(%rsp)", "$src0")`
-+	lea	$res_y(%rsp), $r_ptr
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(res_y, R, res_y);
-+
-+	lea	$S2(%rsp), $b_ptr
-+	lea	$res_y(%rsp), $r_ptr
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(res_y, res_y, S2);
-+
-+	movq	%xmm0, $r_ptr		# restore $r_ptr
-+
-+	movdqa	%xmm5, %xmm0		# copy_conditional(res_z, in2_z, in1infty);
-+	movdqa	%xmm5, %xmm1
-+	pandn	$res_z(%rsp), %xmm0
-+	movdqa	%xmm5, %xmm2
-+	pandn	$res_z+0x10(%rsp), %xmm1
-+	movdqa	%xmm5, %xmm3
-+	pand	$in2_z(%rsp), %xmm2
-+	pand	$in2_z+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+
-+	movdqa	%xmm4, %xmm0		# copy_conditional(res_z, in1_z, in2infty);
-+	movdqa	%xmm4, %xmm1
-+	pandn	%xmm2, %xmm0
-+	movdqa	%xmm4, %xmm2
-+	pandn	%xmm3, %xmm1
-+	movdqa	%xmm4, %xmm3
-+	pand	$in1_z(%rsp), %xmm2
-+	pand	$in1_z+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+	movdqu	%xmm2, 0x40($r_ptr)
-+	movdqu	%xmm3, 0x50($r_ptr)
-+
-+	movdqa	%xmm5, %xmm0		# copy_conditional(res_x, in2_x, in1infty);
-+	movdqa	%xmm5, %xmm1
-+	pandn	$res_x(%rsp), %xmm0
-+	movdqa	%xmm5, %xmm2
-+	pandn	$res_x+0x10(%rsp), %xmm1
-+	movdqa	%xmm5, %xmm3
-+	pand	$in2_x(%rsp), %xmm2
-+	pand	$in2_x+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+
-+	movdqa	%xmm4, %xmm0		# copy_conditional(res_x, in1_x, in2infty);
-+	movdqa	%xmm4, %xmm1
-+	pandn	%xmm2, %xmm0
-+	movdqa	%xmm4, %xmm2
-+	pandn	%xmm3, %xmm1
-+	movdqa	%xmm4, %xmm3
-+	pand	$in1_x(%rsp), %xmm2
-+	pand	$in1_x+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+	movdqu	%xmm2, 0x00($r_ptr)
-+	movdqu	%xmm3, 0x10($r_ptr)
-+
-+	movdqa	%xmm5, %xmm0		# copy_conditional(res_y, in2_y, in1infty);
-+	movdqa	%xmm5, %xmm1
-+	pandn	$res_y(%rsp), %xmm0
-+	movdqa	%xmm5, %xmm2
-+	pandn	$res_y+0x10(%rsp), %xmm1
-+	movdqa	%xmm5, %xmm3
-+	pand	$in2_y(%rsp), %xmm2
-+	pand	$in2_y+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+
-+	movdqa	%xmm4, %xmm0		# copy_conditional(res_y, in1_y, in2infty);
-+	movdqa	%xmm4, %xmm1
-+	pandn	%xmm2, %xmm0
-+	movdqa	%xmm4, %xmm2
-+	pandn	%xmm3, %xmm1
-+	movdqa	%xmm4, %xmm3
-+	pand	$in1_y(%rsp), %xmm2
-+	pand	$in1_y+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+	movdqu	%xmm2, 0x20($r_ptr)
-+	movdqu	%xmm3, 0x30($r_ptr)
-+
-+.Ladd_done$x:
-+	add	\$32*18+8, %rsp
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbx
-+	pop	%rbp
-+	ret
-+.size	ecp_nistz256_point_add$sfx,.-ecp_nistz256_point_add$sfx
-+___
-+}
-+&gen_add("q");
-+
-+sub gen_add_affine () {
-+    my $x = shift;
-+    my ($src0,$sfx,$bias);
-+    my ($U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr,
-+	$res_x,$res_y,$res_z,
-+	$in1_x,$in1_y,$in1_z,
-+	$in2_x,$in2_y)=map(32*$_,(0..14));
-+    my $Z1sqr = $S2;
-+
-+    if ($x ne "x") {
-+	$src0 = "%rax";
-+	$sfx  = "";
-+	$bias = 0;
-+
-+$code.=<<___;
-+.globl	ecp_nistz256_point_add_affine
-+.type	ecp_nistz256_point_add_affine,\@function,3
-+.align	32
-+ecp_nistz256_point_add_affine:
-+___
-+$code.=<<___	if ($addx);
-+	mov	\$0x80100, %ecx
-+	and	OPENSSL_ia32cap_P+8(%rip), %ecx
-+	cmp	\$0x80100, %ecx
-+	je	.Lpoint_add_affinex
-+___
-+    } else {
-+	$src0 = "%rdx";
-+	$sfx  = "x";
-+	$bias = 128;
-+
-+$code.=<<___;
-+.type	ecp_nistz256_point_add_affinex,\@function,3
-+.align	32
-+ecp_nistz256_point_add_affinex:
-+.Lpoint_add_affinex:
-+___
-+    }
-+$code.=<<___;
-+	push	%rbp
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	sub	\$32*15+8, %rsp
-+
-+	movdqu	0x00($a_ptr), %xmm0	# copy	*(P256_POINT *)$a_ptr
-+	mov	$b_org, $b_ptr		# reassign
-+	movdqu	0x10($a_ptr), %xmm1
-+	movdqu	0x20($a_ptr), %xmm2
-+	movdqu	0x30($a_ptr), %xmm3
-+	movdqu	0x40($a_ptr), %xmm4
-+	movdqu	0x50($a_ptr), %xmm5
-+	 mov	0x40+8*0($a_ptr), $src0	# load original in1_z
-+	 mov	0x40+8*1($a_ptr), $acc6
-+	 mov	0x40+8*2($a_ptr), $acc7
-+	 mov	0x40+8*3($a_ptr), $acc0
-+	movdqa	%xmm0, $in1_x(%rsp)
-+	movdqa	%xmm1, $in1_x+0x10(%rsp)
-+	movdqa	%xmm2, $in1_y(%rsp)
-+	movdqa	%xmm3, $in1_y+0x10(%rsp)
-+	movdqa	%xmm4, $in1_z(%rsp)
-+	movdqa	%xmm5, $in1_z+0x10(%rsp)
-+	por	%xmm4, %xmm5
-+
-+	movdqu	0x00($b_ptr), %xmm0	# copy	*(P256_POINT_AFFINE *)$b_ptr
-+	 pshufd	\$0xb1, %xmm5, %xmm3
-+	movdqu	0x10($b_ptr), %xmm1
-+	movdqu	0x20($b_ptr), %xmm2
-+	 por	%xmm3, %xmm5
-+	movdqu	0x30($b_ptr), %xmm3
-+	movdqa	%xmm0, $in2_x(%rsp)
-+	 pshufd	\$0x1e, %xmm5, %xmm4
-+	movdqa	%xmm1, $in2_x+0x10(%rsp)
-+	por	%xmm0, %xmm1
-+	 movq	$r_ptr, %xmm0		# save $r_ptr
-+	movdqa	%xmm2, $in2_y(%rsp)
-+	movdqa	%xmm3, $in2_y+0x10(%rsp)
-+	por	%xmm2, %xmm3
-+	 por	%xmm4, %xmm5
-+	 pxor	%xmm4, %xmm4
-+	por	%xmm1, %xmm3
-+
-+	lea	0x40-$bias($a_ptr), $a_ptr	# $a_ptr is still valid
-+	lea	$Z1sqr(%rsp), $r_ptr		# Z1^2
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(Z1sqr, in1_z);
-+
-+	pcmpeqd	%xmm4, %xmm5
-+	pshufd	\$0xb1, %xmm3, %xmm4
-+	 mov	0x00($b_ptr), $src0		# $b_ptr is still valid
-+	 #lea	0x00($b_ptr), $b_ptr
-+	 mov	$acc4, $acc1			# harmonize sqr output and mul input
-+	por	%xmm3, %xmm4
-+	pshufd	\$0, %xmm5, %xmm5		# in1infty
-+	pshufd	\$0x1e, %xmm4, %xmm3
-+	 mov	$acc5, $acc2
-+	por	%xmm3, %xmm4
-+	pxor	%xmm3, %xmm3
-+	 mov	$acc6, $acc3
-+	pcmpeqd	%xmm3, %xmm4
-+	pshufd	\$0, %xmm4, %xmm4		# in2infty
-+
-+	lea	$Z1sqr-$bias(%rsp), $a_ptr
-+	mov	$acc7, $acc4
-+	lea	$U2(%rsp), $r_ptr		# U2 = X2*Z1^2
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(U2, Z1sqr, in2_x);
-+
-+	lea	$in1_x(%rsp), $b_ptr
-+	lea	$H(%rsp), $r_ptr		# H = U2 - U1
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(H, U2, in1_x);
-+
-+	`&load_for_mul("$Z1sqr(%rsp)", "$in1_z(%rsp)", "$src0")`
-+	lea	$S2(%rsp), $r_ptr		# S2 = Z1^3
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(S2, Z1sqr, in1_z);
-+
-+	`&load_for_mul("$H(%rsp)", "$in1_z(%rsp)", "$src0")`
-+	lea	$res_z(%rsp), $r_ptr		# Z3 = H*Z1*Z2
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(res_z, H, in1_z);
-+
-+	`&load_for_mul("$S2(%rsp)", "$in2_y(%rsp)", "$src0")`
-+	lea	$S2(%rsp), $r_ptr		# S2 = Y2*Z1^3
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(S2, S2, in2_y);
-+
-+	lea	$in1_y(%rsp), $b_ptr
-+	lea	$R(%rsp), $r_ptr		# R = S2 - S1
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(R, S2, in1_y);
-+
-+	`&load_for_sqr("$H(%rsp)", "$src0")`
-+	lea	$Hsqr(%rsp), $r_ptr		# H^2
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(Hsqr, H);
-+
-+	`&load_for_sqr("$R(%rsp)", "$src0")`
-+	lea	$Rsqr(%rsp), $r_ptr		# R^2
-+	call	__ecp_nistz256_sqr_mont$x	# p256_sqr_mont(Rsqr, R);
-+
-+	`&load_for_mul("$H(%rsp)", "$Hsqr(%rsp)", "$src0")`
-+	lea	$Hcub(%rsp), $r_ptr		# H^3
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(Hcub, Hsqr, H);
-+
-+	`&load_for_mul("$Hsqr(%rsp)", "$in1_x(%rsp)", "$src0")`
-+	lea	$U2(%rsp), $r_ptr		# U1*H^2
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(U2, in1_x, Hsqr);
-+___
-+{
-+#######################################################################
-+# operate in 4-5-0-1 "name space" that matches multiplication output
-+#
-+my ($acc0,$acc1,$acc2,$acc3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
-+my ($poly1, $poly3)=($acc6,$acc7);
-+
-+$code.=<<___;
-+	#lea	$U2(%rsp), $a_ptr
-+	#lea	$Hsqr(%rsp), $r_ptr	# 2*U1*H^2
-+	#call	__ecp_nistz256_mul_by_2	# ecp_nistz256_mul_by_2(Hsqr, U2);
-+
-+	xor	$t4, $t4
-+	add	$acc0, $acc0		# a0:a3+a0:a3
-+	lea	$Rsqr(%rsp), $a_ptr
-+	adc	$acc1, $acc1
-+	 mov	$acc0, $t0
-+	adc	$acc2, $acc2
-+	adc	$acc3, $acc3
-+	 mov	$acc1, $t1
-+	adc	\$0, $t4
-+
-+	sub	\$-1, $acc0
-+	 mov	$acc2, $t2
-+	sbb	$poly1, $acc1
-+	sbb	\$0, $acc2
-+	 mov	$acc3, $t3
-+	sbb	$poly3, $acc3
-+	sbb	\$0, $t4
-+
-+	cmovc	$t0, $acc0
-+	mov	8*0($a_ptr), $t0
-+	cmovc	$t1, $acc1
-+	mov	8*1($a_ptr), $t1
-+	cmovc	$t2, $acc2
-+	mov	8*2($a_ptr), $t2
-+	cmovc	$t3, $acc3
-+	mov	8*3($a_ptr), $t3
-+
-+	call	__ecp_nistz256_sub$x		# p256_sub(res_x, Rsqr, Hsqr);
-+
-+	lea	$Hcub(%rsp), $b_ptr
-+	lea	$res_x(%rsp), $r_ptr
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(res_x, res_x, Hcub);
-+
-+	mov	$U2+8*0(%rsp), $t0
-+	mov	$U2+8*1(%rsp), $t1
-+	mov	$U2+8*2(%rsp), $t2
-+	mov	$U2+8*3(%rsp), $t3
-+	lea	$H(%rsp), $r_ptr
-+
-+	call	__ecp_nistz256_sub$x		# p256_sub(H, U2, res_x);
-+
-+	mov	$acc0, 8*0($r_ptr)		# save the result, as
-+	mov	$acc1, 8*1($r_ptr)		# __ecp_nistz256_sub doesn't
-+	mov	$acc2, 8*2($r_ptr)
-+	mov	$acc3, 8*3($r_ptr)
-+___
-+}
-+$code.=<<___;
-+	`&load_for_mul("$Hcub(%rsp)", "$in1_y(%rsp)", "$src0")`
-+	lea	$S2(%rsp), $r_ptr
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(S2, Hcub, in1_y);
-+
-+	`&load_for_mul("$H(%rsp)", "$R(%rsp)", "$src0")`
-+	lea	$H(%rsp), $r_ptr
-+	call	__ecp_nistz256_mul_mont$x	# p256_mul_mont(H, H, R);
-+
-+	lea	$S2(%rsp), $b_ptr
-+	lea	$res_y(%rsp), $r_ptr
-+	call	__ecp_nistz256_sub_from$x	# p256_sub(res_y, H, S2);
-+
-+	movq	%xmm0, $r_ptr		# restore $r_ptr
-+
-+	movdqa	%xmm5, %xmm0		# copy_conditional(res_z, ONE, in1infty);
-+	movdqa	%xmm5, %xmm1
-+	pandn	$res_z(%rsp), %xmm0
-+	movdqa	%xmm5, %xmm2
-+	pandn	$res_z+0x10(%rsp), %xmm1
-+	movdqa	%xmm5, %xmm3
-+	pand	.LONE_mont(%rip), %xmm2
-+	pand	.LONE_mont+0x10(%rip), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+
-+	movdqa	%xmm4, %xmm0		# copy_conditional(res_z, in1_z, in2infty);
-+	movdqa	%xmm4, %xmm1
-+	pandn	%xmm2, %xmm0
-+	movdqa	%xmm4, %xmm2
-+	pandn	%xmm3, %xmm1
-+	movdqa	%xmm4, %xmm3
-+	pand	$in1_z(%rsp), %xmm2
-+	pand	$in1_z+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+	movdqu	%xmm2, 0x40($r_ptr)
-+	movdqu	%xmm3, 0x50($r_ptr)
-+
-+	movdqa	%xmm5, %xmm0		# copy_conditional(res_x, in2_x, in1infty);
-+	movdqa	%xmm5, %xmm1
-+	pandn	$res_x(%rsp), %xmm0
-+	movdqa	%xmm5, %xmm2
-+	pandn	$res_x+0x10(%rsp), %xmm1
-+	movdqa	%xmm5, %xmm3
-+	pand	$in2_x(%rsp), %xmm2
-+	pand	$in2_x+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+
-+	movdqa	%xmm4, %xmm0		# copy_conditional(res_x, in1_x, in2infty);
-+	movdqa	%xmm4, %xmm1
-+	pandn	%xmm2, %xmm0
-+	movdqa	%xmm4, %xmm2
-+	pandn	%xmm3, %xmm1
-+	movdqa	%xmm4, %xmm3
-+	pand	$in1_x(%rsp), %xmm2
-+	pand	$in1_x+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+	movdqu	%xmm2, 0x00($r_ptr)
-+	movdqu	%xmm3, 0x10($r_ptr)
-+
-+	movdqa	%xmm5, %xmm0		# copy_conditional(res_y, in2_y, in1infty);
-+	movdqa	%xmm5, %xmm1
-+	pandn	$res_y(%rsp), %xmm0
-+	movdqa	%xmm5, %xmm2
-+	pandn	$res_y+0x10(%rsp), %xmm1
-+	movdqa	%xmm5, %xmm3
-+	pand	$in2_y(%rsp), %xmm2
-+	pand	$in2_y+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+
-+	movdqa	%xmm4, %xmm0		# copy_conditional(res_y, in1_y, in2infty);
-+	movdqa	%xmm4, %xmm1
-+	pandn	%xmm2, %xmm0
-+	movdqa	%xmm4, %xmm2
-+	pandn	%xmm3, %xmm1
-+	movdqa	%xmm4, %xmm3
-+	pand	$in1_y(%rsp), %xmm2
-+	pand	$in1_y+0x10(%rsp), %xmm3
-+	por	%xmm0, %xmm2
-+	por	%xmm1, %xmm3
-+	movdqu	%xmm2, 0x20($r_ptr)
-+	movdqu	%xmm3, 0x30($r_ptr)
-+
-+	add	\$32*15+8, %rsp
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbx
-+	pop	%rbp
-+	ret
-+.size	ecp_nistz256_point_add_affine$sfx,.-ecp_nistz256_point_add_affine$sfx
-+___
-+}
-+&gen_add_affine("q");
-+
-+########################################################################
-+# AD*X magic
-+#
-+if ($addx) {								{
-+########################################################################
-+# operate in 4-5-0-1 "name space" that matches multiplication output
-+#
-+my ($a0,$a1,$a2,$a3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
-+
-+$code.=<<___;
-+.type	__ecp_nistz256_add_tox,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_add_tox:
-+	xor	$t4, $t4
-+	adc	8*0($b_ptr), $a0
-+	adc	8*1($b_ptr), $a1
-+	 mov	$a0, $t0
-+	adc	8*2($b_ptr), $a2
-+	adc	8*3($b_ptr), $a3
-+	 mov	$a1, $t1
-+	adc	\$0, $t4
-+
-+	xor	$t3, $t3
-+	sbb	\$-1, $a0
-+	 mov	$a2, $t2
-+	sbb	$poly1, $a1
-+	sbb	\$0, $a2
-+	 mov	$a3, $t3
-+	sbb	$poly3, $a3
-+	sbb	\$0, $t4
-+
-+	cmovc	$t0, $a0
-+	cmovc	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovc	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovc	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	ret
-+.size	__ecp_nistz256_add_tox,.-__ecp_nistz256_add_tox
-+
-+.type	__ecp_nistz256_sub_fromx,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_sub_fromx:
-+	xor	$t4, $t4
-+	sbb	8*0($b_ptr), $a0
-+	sbb	8*1($b_ptr), $a1
-+	 mov	$a0, $t0
-+	sbb	8*2($b_ptr), $a2
-+	sbb	8*3($b_ptr), $a3
-+	 mov	$a1, $t1
-+	sbb	\$0, $t4
-+
-+	xor	$t3, $t3
-+	adc	\$-1, $a0
-+	 mov	$a2, $t2
-+	adc	$poly1, $a1
-+	adc	\$0, $a2
-+	 mov	$a3, $t3
-+	adc	$poly3, $a3
-+
-+	bt	\$0, $t4
-+	cmovnc	$t0, $a0
-+	cmovnc	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovnc	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovnc	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	ret
-+.size	__ecp_nistz256_sub_fromx,.-__ecp_nistz256_sub_fromx
-+
-+.type	__ecp_nistz256_subx,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_subx:
-+	xor	$t4, $t4
-+	sbb	$a0, $t0
-+	sbb	$a1, $t1
-+	 mov	$t0, $a0
-+	sbb	$a2, $t2
-+	sbb	$a3, $t3
-+	 mov	$t1, $a1
-+	sbb	\$0, $t4
-+
-+	xor	$a3 ,$a3
-+	adc	\$-1, $t0
-+	 mov	$t2, $a2
-+	adc	$poly1, $t1
-+	adc	\$0, $t2
-+	 mov	$t3, $a3
-+	adc	$poly3, $t3
-+
-+	bt	\$0, $t4
-+	cmovc	$t0, $a0
-+	cmovc	$t1, $a1
-+	cmovc	$t2, $a2
-+	cmovc	$t3, $a3
-+
-+	ret
-+.size	__ecp_nistz256_subx,.-__ecp_nistz256_subx
-+
-+.type	__ecp_nistz256_mul_by_2x,\@abi-omnipotent
-+.align	32
-+__ecp_nistz256_mul_by_2x:
-+	xor	$t4, $t4
-+	adc	$a0, $a0		# a0:a3+a0:a3
-+	adc	$a1, $a1
-+	 mov	$a0, $t0
-+	adc	$a2, $a2
-+	adc	$a3, $a3
-+	 mov	$a1, $t1
-+	adc	\$0, $t4
-+
-+	xor	$t3, $t3
-+	sbb	\$-1, $a0
-+	 mov	$a2, $t2
-+	sbb	$poly1, $a1
-+	sbb	\$0, $a2
-+	 mov	$a3, $t3
-+	sbb	$poly3, $a3
-+	sbb	\$0, $t4
-+
-+	cmovc	$t0, $a0
-+	cmovc	$t1, $a1
-+	mov	$a0, 8*0($r_ptr)
-+	cmovc	$t2, $a2
-+	mov	$a1, 8*1($r_ptr)
-+	cmovc	$t3, $a3
-+	mov	$a2, 8*2($r_ptr)
-+	mov	$a3, 8*3($r_ptr)
-+
-+	ret
-+.size	__ecp_nistz256_mul_by_2x,.-__ecp_nistz256_mul_by_2x
-+___
-+									}
-+&gen_double("x");
-+&gen_add("x");
-+&gen_add_affine("x");
-+}
-+}}}
-+
-+########################################################################
-+# Convert ecp_nistz256_table.c to layout expected by ecp_nistz_gather_w7
-+#
-+open TABLE,") {
-+	s/TOBN\(\s*(0x[0-9a-f]+),\s*(0x[0-9a-f]+)\s*\)/push @arr,hex($2),hex($1)/geo;
-+}
-+close TABLE;
-+
-+die "insane number of elements" if ($#arr != 64*16*37-1);
-+
-+print <<___;
-+.text
-+.globl	ecp_nistz256_precomputed
-+.type	ecp_nistz256_precomputed,\@object
-+.align	4096
-+ecp_nistz256_precomputed:
-+___
-+while (@line=splice(@arr,0,16)) {
-+	print ".long\t",join(',',map { sprintf "0x%08x",$_} @line),"\n";
-+}
-+print <<___;
-+.size	ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/build.info
-new file mode 100644
-index 0000000..970c292
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/build.info
-@@ -0,0 +1,28 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
-+        ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c \
-+        ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c \
-+        ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \
-+        ecp_oct.c ec2_oct.c ec_oct.c ec_kmeth.c ecdh_ossl.c ecdh_kdf.c \
-+        ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c ecx_meth.c \
-+        {- $target{ec_asm_src} -}
-+
-+GENERATE[ecp_nistz256-x86.s]=asm/ecp_nistz256-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+
-+GENERATE[ecp_nistz256-x86_64.s]=asm/ecp_nistz256-x86_64.pl $(PERLASM_SCHEME)
-+
-+GENERATE[ecp_nistz256-avx2.s]=asm/ecp_nistz256-avx2.pl $(PERLASM_SCHEME)
-+
-+GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[ecp_nistz256-sparcv9.o]=..
-+
-+GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl $(PERLASM_SCHEME)
-+INCLUDE[ecp_nistz256-armv4.o]=..
-+GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl $(PERLASM_SCHEME)
-+INCLUDE[ecp_nistz256-armv8.o]=..
-+
-+BEGINRAW[Makefile]
-+{- $builddir -}/ecp_nistz256-%.S:	{- $sourcedir -}/asm/ecp_nistz256-%.pl
-+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-+ENDRAW[Makefile]
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/curve25519.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/curve25519.c
-new file mode 100644
-index 0000000..e535823
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/curve25519.c
-@@ -0,0 +1,3394 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP
-+ * 20141124 (http://bench.cr.yp.to/supercop.html).
-+ *
-+ * The field functions are shared by Ed25519 and X25519 where possible. */
-+
-+#include 
-+#include "ec_lcl.h"
-+
-+
-+/* fe means field element. Here the field is \Z/(2^255-19). An element t,
-+ * entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
-+ * t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
-+ * context.  */
-+typedef int32_t fe[10];
-+
-+static const int64_t kBottom25Bits = 0x1ffffffLL;
-+static const int64_t kBottom26Bits = 0x3ffffffLL;
-+static const int64_t kTop39Bits = 0xfffffffffe000000LL;
-+static const int64_t kTop38Bits = 0xfffffffffc000000LL;
-+
-+static uint64_t load_3(const uint8_t *in) {
-+  uint64_t result;
-+  result = (uint64_t)in[0];
-+  result |= ((uint64_t)in[1]) << 8;
-+  result |= ((uint64_t)in[2]) << 16;
-+  return result;
-+}
-+
-+static uint64_t load_4(const uint8_t *in) {
-+  uint64_t result;
-+  result = (uint64_t)in[0];
-+  result |= ((uint64_t)in[1]) << 8;
-+  result |= ((uint64_t)in[2]) << 16;
-+  result |= ((uint64_t)in[3]) << 24;
-+  return result;
-+}
-+
-+static void fe_frombytes(fe h, const uint8_t *s) {
-+  /* Ignores top bit of h. */
-+  int64_t h0 = load_4(s);
-+  int64_t h1 = load_3(s + 4) << 6;
-+  int64_t h2 = load_3(s + 7) << 5;
-+  int64_t h3 = load_3(s + 10) << 3;
-+  int64_t h4 = load_3(s + 13) << 2;
-+  int64_t h5 = load_4(s + 16);
-+  int64_t h6 = load_3(s + 20) << 7;
-+  int64_t h7 = load_3(s + 23) << 5;
-+  int64_t h8 = load_3(s + 26) << 4;
-+  int64_t h9 = (load_3(s + 29) & 8388607) << 2;
-+  int64_t carry0;
-+  int64_t carry1;
-+  int64_t carry2;
-+  int64_t carry3;
-+  int64_t carry4;
-+  int64_t carry5;
-+  int64_t carry6;
-+  int64_t carry7;
-+  int64_t carry8;
-+  int64_t carry9;
-+
-+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
-+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
-+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
-+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
-+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
-+
-+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
-+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
-+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
-+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
-+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
-+
-+  h[0] = h0;
-+  h[1] = h1;
-+  h[2] = h2;
-+  h[3] = h3;
-+  h[4] = h4;
-+  h[5] = h5;
-+  h[6] = h6;
-+  h[7] = h7;
-+  h[8] = h8;
-+  h[9] = h9;
-+}
-+
-+/* Preconditions:
-+ *  |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
-+ *
-+ * Write p=2^255-19; q=floor(h/p).
-+ * Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
-+ *
-+ * Proof:
-+ *   Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
-+ *   Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
-+ *
-+ *   Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
-+ *   Then 0> 25;
-+  q = (h0 + q) >> 26;
-+  q = (h1 + q) >> 25;
-+  q = (h2 + q) >> 26;
-+  q = (h3 + q) >> 25;
-+  q = (h4 + q) >> 26;
-+  q = (h5 + q) >> 25;
-+  q = (h6 + q) >> 26;
-+  q = (h7 + q) >> 25;
-+  q = (h8 + q) >> 26;
-+  q = (h9 + q) >> 25;
-+
-+  /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
-+  h0 += 19 * q;
-+  /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
-+
-+  h1 += h0 >> 26; h0 &= kBottom26Bits;
-+  h2 += h1 >> 25; h1 &= kBottom25Bits;
-+  h3 += h2 >> 26; h2 &= kBottom26Bits;
-+  h4 += h3 >> 25; h3 &= kBottom25Bits;
-+  h5 += h4 >> 26; h4 &= kBottom26Bits;
-+  h6 += h5 >> 25; h5 &= kBottom25Bits;
-+  h7 += h6 >> 26; h6 &= kBottom26Bits;
-+  h8 += h7 >> 25; h7 &= kBottom25Bits;
-+  h9 += h8 >> 26; h8 &= kBottom26Bits;
-+                  h9 &= kBottom25Bits;
-+                  /* h10 = carry9 */
-+
-+  /* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
-+   * Have h0+...+2^230 h9 between 0 and 2^255-1;
-+   * evidently 2^255 h10-2^255 q = 0.
-+   * Goal: Output h0+...+2^230 h9.  */
-+
-+  s[0] = h0 >> 0;
-+  s[1] = h0 >> 8;
-+  s[2] = h0 >> 16;
-+  s[3] = (h0 >> 24) | ((uint32_t)(h1) << 2);
-+  s[4] = h1 >> 6;
-+  s[5] = h1 >> 14;
-+  s[6] = (h1 >> 22) | ((uint32_t)(h2) << 3);
-+  s[7] = h2 >> 5;
-+  s[8] = h2 >> 13;
-+  s[9] = (h2 >> 21) | ((uint32_t)(h3) << 5);
-+  s[10] = h3 >> 3;
-+  s[11] = h3 >> 11;
-+  s[12] = (h3 >> 19) | ((uint32_t)(h4) << 6);
-+  s[13] = h4 >> 2;
-+  s[14] = h4 >> 10;
-+  s[15] = h4 >> 18;
-+  s[16] = h5 >> 0;
-+  s[17] = h5 >> 8;
-+  s[18] = h5 >> 16;
-+  s[19] = (h5 >> 24) | ((uint32_t)(h6) << 1);
-+  s[20] = h6 >> 7;
-+  s[21] = h6 >> 15;
-+  s[22] = (h6 >> 23) | ((uint32_t)(h7) << 3);
-+  s[23] = h7 >> 5;
-+  s[24] = h7 >> 13;
-+  s[25] = (h7 >> 21) | ((uint32_t)(h8) << 4);
-+  s[26] = h8 >> 4;
-+  s[27] = h8 >> 12;
-+  s[28] = (h8 >> 20) | ((uint32_t)(h9) << 6);
-+  s[29] = h9 >> 2;
-+  s[30] = h9 >> 10;
-+  s[31] = h9 >> 18;
-+}
-+
-+/* h = f */
-+static void fe_copy(fe h, const fe f) {
-+  memmove(h, f, sizeof(int32_t) * 10);
-+}
-+
-+/* h = 0 */
-+static void fe_0(fe h) { memset(h, 0, sizeof(int32_t) * 10); }
-+
-+/* h = 1 */
-+static void fe_1(fe h) {
-+  memset(h, 0, sizeof(int32_t) * 10);
-+  h[0] = 1;
-+}
-+
-+/* h = f + g
-+ * Can overlap h with f or g.
-+ *
-+ * Preconditions:
-+ *    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-+ *    |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-+ *
-+ * Postconditions:
-+ *    |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
-+static void fe_add(fe h, const fe f, const fe g) {
-+  unsigned i;
-+  for (i = 0; i < 10; i++) {
-+    h[i] = f[i] + g[i];
-+  }
-+}
-+
-+/* h = f - g
-+ * Can overlap h with f or g.
-+ *
-+ * Preconditions:
-+ *    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-+ *    |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-+ *
-+ * Postconditions:
-+ *    |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
-+static void fe_sub(fe h, const fe f, const fe g) {
-+  unsigned i;
-+  for (i = 0; i < 10; i++) {
-+    h[i] = f[i] - g[i];
-+  }
-+}
-+
-+/* h = f * g
-+ * Can overlap h with f or g.
-+ *
-+ * Preconditions:
-+ *    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
-+ *    |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
-+ *
-+ * Postconditions:
-+ *    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
-+ *
-+ * Notes on implementation strategy:
-+ *
-+ * Using schoolbook multiplication.
-+ * Karatsuba would save a little in some cost models.
-+ *
-+ * Most multiplications by 2 and 19 are 32-bit precomputations;
-+ * cheaper than 64-bit postcomputations.
-+ *
-+ * There is one remaining multiplication by 19 in the carry chain;
-+ * one *19 precomputation can be merged into this,
-+ * but the resulting data flow is considerably less clean.
-+ *
-+ * There are 12 carries below.
-+ * 10 of them are 2-way parallelizable and vectorizable.
-+ * Can get away with 11 carries, but then data flow is much deeper.
-+ *
-+ * With tighter constraints on inputs can squeeze carries into int32. */
-+static void fe_mul(fe h, const fe f, const fe g) {
-+  int32_t f0 = f[0];
-+  int32_t f1 = f[1];
-+  int32_t f2 = f[2];
-+  int32_t f3 = f[3];
-+  int32_t f4 = f[4];
-+  int32_t f5 = f[5];
-+  int32_t f6 = f[6];
-+  int32_t f7 = f[7];
-+  int32_t f8 = f[8];
-+  int32_t f9 = f[9];
-+  int32_t g0 = g[0];
-+  int32_t g1 = g[1];
-+  int32_t g2 = g[2];
-+  int32_t g3 = g[3];
-+  int32_t g4 = g[4];
-+  int32_t g5 = g[5];
-+  int32_t g6 = g[6];
-+  int32_t g7 = g[7];
-+  int32_t g8 = g[8];
-+  int32_t g9 = g[9];
-+  int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
-+  int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
-+  int32_t g3_19 = 19 * g3;
-+  int32_t g4_19 = 19 * g4;
-+  int32_t g5_19 = 19 * g5;
-+  int32_t g6_19 = 19 * g6;
-+  int32_t g7_19 = 19 * g7;
-+  int32_t g8_19 = 19 * g8;
-+  int32_t g9_19 = 19 * g9;
-+  int32_t f1_2 = 2 * f1;
-+  int32_t f3_2 = 2 * f3;
-+  int32_t f5_2 = 2 * f5;
-+  int32_t f7_2 = 2 * f7;
-+  int32_t f9_2 = 2 * f9;
-+  int64_t f0g0    = f0   * (int64_t) g0;
-+  int64_t f0g1    = f0   * (int64_t) g1;
-+  int64_t f0g2    = f0   * (int64_t) g2;
-+  int64_t f0g3    = f0   * (int64_t) g3;
-+  int64_t f0g4    = f0   * (int64_t) g4;
-+  int64_t f0g5    = f0   * (int64_t) g5;
-+  int64_t f0g6    = f0   * (int64_t) g6;
-+  int64_t f0g7    = f0   * (int64_t) g7;
-+  int64_t f0g8    = f0   * (int64_t) g8;
-+  int64_t f0g9    = f0   * (int64_t) g9;
-+  int64_t f1g0    = f1   * (int64_t) g0;
-+  int64_t f1g1_2  = f1_2 * (int64_t) g1;
-+  int64_t f1g2    = f1   * (int64_t) g2;
-+  int64_t f1g3_2  = f1_2 * (int64_t) g3;
-+  int64_t f1g4    = f1   * (int64_t) g4;
-+  int64_t f1g5_2  = f1_2 * (int64_t) g5;
-+  int64_t f1g6    = f1   * (int64_t) g6;
-+  int64_t f1g7_2  = f1_2 * (int64_t) g7;
-+  int64_t f1g8    = f1   * (int64_t) g8;
-+  int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
-+  int64_t f2g0    = f2   * (int64_t) g0;
-+  int64_t f2g1    = f2   * (int64_t) g1;
-+  int64_t f2g2    = f2   * (int64_t) g2;
-+  int64_t f2g3    = f2   * (int64_t) g3;
-+  int64_t f2g4    = f2   * (int64_t) g4;
-+  int64_t f2g5    = f2   * (int64_t) g5;
-+  int64_t f2g6    = f2   * (int64_t) g6;
-+  int64_t f2g7    = f2   * (int64_t) g7;
-+  int64_t f2g8_19 = f2   * (int64_t) g8_19;
-+  int64_t f2g9_19 = f2   * (int64_t) g9_19;
-+  int64_t f3g0    = f3   * (int64_t) g0;
-+  int64_t f3g1_2  = f3_2 * (int64_t) g1;
-+  int64_t f3g2    = f3   * (int64_t) g2;
-+  int64_t f3g3_2  = f3_2 * (int64_t) g3;
-+  int64_t f3g4    = f3   * (int64_t) g4;
-+  int64_t f3g5_2  = f3_2 * (int64_t) g5;
-+  int64_t f3g6    = f3   * (int64_t) g6;
-+  int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
-+  int64_t f3g8_19 = f3   * (int64_t) g8_19;
-+  int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
-+  int64_t f4g0    = f4   * (int64_t) g0;
-+  int64_t f4g1    = f4   * (int64_t) g1;
-+  int64_t f4g2    = f4   * (int64_t) g2;
-+  int64_t f4g3    = f4   * (int64_t) g3;
-+  int64_t f4g4    = f4   * (int64_t) g4;
-+  int64_t f4g5    = f4   * (int64_t) g5;
-+  int64_t f4g6_19 = f4   * (int64_t) g6_19;
-+  int64_t f4g7_19 = f4   * (int64_t) g7_19;
-+  int64_t f4g8_19 = f4   * (int64_t) g8_19;
-+  int64_t f4g9_19 = f4   * (int64_t) g9_19;
-+  int64_t f5g0    = f5   * (int64_t) g0;
-+  int64_t f5g1_2  = f5_2 * (int64_t) g1;
-+  int64_t f5g2    = f5   * (int64_t) g2;
-+  int64_t f5g3_2  = f5_2 * (int64_t) g3;
-+  int64_t f5g4    = f5   * (int64_t) g4;
-+  int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
-+  int64_t f5g6_19 = f5   * (int64_t) g6_19;
-+  int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
-+  int64_t f5g8_19 = f5   * (int64_t) g8_19;
-+  int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
-+  int64_t f6g0    = f6   * (int64_t) g0;
-+  int64_t f6g1    = f6   * (int64_t) g1;
-+  int64_t f6g2    = f6   * (int64_t) g2;
-+  int64_t f6g3    = f6   * (int64_t) g3;
-+  int64_t f6g4_19 = f6   * (int64_t) g4_19;
-+  int64_t f6g5_19 = f6   * (int64_t) g5_19;
-+  int64_t f6g6_19 = f6   * (int64_t) g6_19;
-+  int64_t f6g7_19 = f6   * (int64_t) g7_19;
-+  int64_t f6g8_19 = f6   * (int64_t) g8_19;
-+  int64_t f6g9_19 = f6   * (int64_t) g9_19;
-+  int64_t f7g0    = f7   * (int64_t) g0;
-+  int64_t f7g1_2  = f7_2 * (int64_t) g1;
-+  int64_t f7g2    = f7   * (int64_t) g2;
-+  int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
-+  int64_t f7g4_19 = f7   * (int64_t) g4_19;
-+  int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
-+  int64_t f7g6_19 = f7   * (int64_t) g6_19;
-+  int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
-+  int64_t f7g8_19 = f7   * (int64_t) g8_19;
-+  int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
-+  int64_t f8g0    = f8   * (int64_t) g0;
-+  int64_t f8g1    = f8   * (int64_t) g1;
-+  int64_t f8g2_19 = f8   * (int64_t) g2_19;
-+  int64_t f8g3_19 = f8   * (int64_t) g3_19;
-+  int64_t f8g4_19 = f8   * (int64_t) g4_19;
-+  int64_t f8g5_19 = f8   * (int64_t) g5_19;
-+  int64_t f8g6_19 = f8   * (int64_t) g6_19;
-+  int64_t f8g7_19 = f8   * (int64_t) g7_19;
-+  int64_t f8g8_19 = f8   * (int64_t) g8_19;
-+  int64_t f8g9_19 = f8   * (int64_t) g9_19;
-+  int64_t f9g0    = f9   * (int64_t) g0;
-+  int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
-+  int64_t f9g2_19 = f9   * (int64_t) g2_19;
-+  int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
-+  int64_t f9g4_19 = f9   * (int64_t) g4_19;
-+  int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
-+  int64_t f9g6_19 = f9   * (int64_t) g6_19;
-+  int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
-+  int64_t f9g8_19 = f9   * (int64_t) g8_19;
-+  int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
-+  int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
-+  int64_t h1 = f0g1+f1g0   +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
-+  int64_t h2 = f0g2+f1g1_2 +f2g0   +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
-+  int64_t h3 = f0g3+f1g2   +f2g1   +f3g0   +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
-+  int64_t h4 = f0g4+f1g3_2 +f2g2   +f3g1_2 +f4g0   +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
-+  int64_t h5 = f0g5+f1g4   +f2g3   +f3g2   +f4g1   +f5g0   +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
-+  int64_t h6 = f0g6+f1g5_2 +f2g4   +f3g3_2 +f4g2   +f5g1_2 +f6g0   +f7g9_38+f8g8_19+f9g7_38;
-+  int64_t h7 = f0g7+f1g6   +f2g5   +f3g4   +f4g3   +f5g2   +f6g1   +f7g0   +f8g9_19+f9g8_19;
-+  int64_t h8 = f0g8+f1g7_2 +f2g6   +f3g5_2 +f4g4   +f5g3_2 +f6g2   +f7g1_2 +f8g0   +f9g9_38;
-+  int64_t h9 = f0g9+f1g8   +f2g7   +f3g6   +f4g5   +f5g4   +f6g3   +f7g2   +f8g1   +f9g0   ;
-+  int64_t carry0;
-+  int64_t carry1;
-+  int64_t carry2;
-+  int64_t carry3;
-+  int64_t carry4;
-+  int64_t carry5;
-+  int64_t carry6;
-+  int64_t carry7;
-+  int64_t carry8;
-+  int64_t carry9;
-+
-+  /* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
-+   *   i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
-+   * |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
-+   *   i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */
-+
-+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
-+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
-+  /* |h0| <= 2^25 */
-+  /* |h4| <= 2^25 */
-+  /* |h1| <= 1.71*2^59 */
-+  /* |h5| <= 1.71*2^59 */
-+
-+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
-+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
-+  /* |h1| <= 2^24; from now on fits into int32 */
-+  /* |h5| <= 2^24; from now on fits into int32 */
-+  /* |h2| <= 1.41*2^60 */
-+  /* |h6| <= 1.41*2^60 */
-+
-+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
-+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
-+  /* |h2| <= 2^25; from now on fits into int32 unchanged */
-+  /* |h6| <= 2^25; from now on fits into int32 unchanged */
-+  /* |h3| <= 1.71*2^59 */
-+  /* |h7| <= 1.71*2^59 */
-+
-+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
-+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
-+  /* |h3| <= 2^24; from now on fits into int32 unchanged */
-+  /* |h7| <= 2^24; from now on fits into int32 unchanged */
-+  /* |h4| <= 1.72*2^34 */
-+  /* |h8| <= 1.41*2^60 */
-+
-+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
-+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
-+  /* |h4| <= 2^25; from now on fits into int32 unchanged */
-+  /* |h8| <= 2^25; from now on fits into int32 unchanged */
-+  /* |h5| <= 1.01*2^24 */
-+  /* |h9| <= 1.71*2^59 */
-+
-+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
-+  /* |h9| <= 2^24; from now on fits into int32 unchanged */
-+  /* |h0| <= 1.1*2^39 */
-+
-+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
-+  /* |h0| <= 2^25; from now on fits into int32 unchanged */
-+  /* |h1| <= 1.01*2^24 */
-+
-+  h[0] = h0;
-+  h[1] = h1;
-+  h[2] = h2;
-+  h[3] = h3;
-+  h[4] = h4;
-+  h[5] = h5;
-+  h[6] = h6;
-+  h[7] = h7;
-+  h[8] = h8;
-+  h[9] = h9;
-+}
-+
-+/* h = f * f
-+ * Can overlap h with f.
-+ *
-+ * Preconditions:
-+ *    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
-+ *
-+ * Postconditions:
-+ *    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
-+ *
-+ * See fe_mul.c for discussion of implementation strategy. */
-+static void fe_sq(fe h, const fe f) {
-+  int32_t f0 = f[0];
-+  int32_t f1 = f[1];
-+  int32_t f2 = f[2];
-+  int32_t f3 = f[3];
-+  int32_t f4 = f[4];
-+  int32_t f5 = f[5];
-+  int32_t f6 = f[6];
-+  int32_t f7 = f[7];
-+  int32_t f8 = f[8];
-+  int32_t f9 = f[9];
-+  int32_t f0_2 = 2 * f0;
-+  int32_t f1_2 = 2 * f1;
-+  int32_t f2_2 = 2 * f2;
-+  int32_t f3_2 = 2 * f3;
-+  int32_t f4_2 = 2 * f4;
-+  int32_t f5_2 = 2 * f5;
-+  int32_t f6_2 = 2 * f6;
-+  int32_t f7_2 = 2 * f7;
-+  int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
-+  int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
-+  int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
-+  int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
-+  int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
-+  int64_t f0f0    = f0   * (int64_t) f0;
-+  int64_t f0f1_2  = f0_2 * (int64_t) f1;
-+  int64_t f0f2_2  = f0_2 * (int64_t) f2;
-+  int64_t f0f3_2  = f0_2 * (int64_t) f3;
-+  int64_t f0f4_2  = f0_2 * (int64_t) f4;
-+  int64_t f0f5_2  = f0_2 * (int64_t) f5;
-+  int64_t f0f6_2  = f0_2 * (int64_t) f6;
-+  int64_t f0f7_2  = f0_2 * (int64_t) f7;
-+  int64_t f0f8_2  = f0_2 * (int64_t) f8;
-+  int64_t f0f9_2  = f0_2 * (int64_t) f9;
-+  int64_t f1f1_2  = f1_2 * (int64_t) f1;
-+  int64_t f1f2_2  = f1_2 * (int64_t) f2;
-+  int64_t f1f3_4  = f1_2 * (int64_t) f3_2;
-+  int64_t f1f4_2  = f1_2 * (int64_t) f4;
-+  int64_t f1f5_4  = f1_2 * (int64_t) f5_2;
-+  int64_t f1f6_2  = f1_2 * (int64_t) f6;
-+  int64_t f1f7_4  = f1_2 * (int64_t) f7_2;
-+  int64_t f1f8_2  = f1_2 * (int64_t) f8;
-+  int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
-+  int64_t f2f2    = f2   * (int64_t) f2;
-+  int64_t f2f3_2  = f2_2 * (int64_t) f3;
-+  int64_t f2f4_2  = f2_2 * (int64_t) f4;
-+  int64_t f2f5_2  = f2_2 * (int64_t) f5;
-+  int64_t f2f6_2  = f2_2 * (int64_t) f6;
-+  int64_t f2f7_2  = f2_2 * (int64_t) f7;
-+  int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
-+  int64_t f2f9_38 = f2   * (int64_t) f9_38;
-+  int64_t f3f3_2  = f3_2 * (int64_t) f3;
-+  int64_t f3f4_2  = f3_2 * (int64_t) f4;
-+  int64_t f3f5_4  = f3_2 * (int64_t) f5_2;
-+  int64_t f3f6_2  = f3_2 * (int64_t) f6;
-+  int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
-+  int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
-+  int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
-+  int64_t f4f4    = f4   * (int64_t) f4;
-+  int64_t f4f5_2  = f4_2 * (int64_t) f5;
-+  int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
-+  int64_t f4f7_38 = f4   * (int64_t) f7_38;
-+  int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
-+  int64_t f4f9_38 = f4   * (int64_t) f9_38;
-+  int64_t f5f5_38 = f5   * (int64_t) f5_38;
-+  int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
-+  int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
-+  int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
-+  int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
-+  int64_t f6f6_19 = f6   * (int64_t) f6_19;
-+  int64_t f6f7_38 = f6   * (int64_t) f7_38;
-+  int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
-+  int64_t f6f9_38 = f6   * (int64_t) f9_38;
-+  int64_t f7f7_38 = f7   * (int64_t) f7_38;
-+  int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
-+  int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
-+  int64_t f8f8_19 = f8   * (int64_t) f8_19;
-+  int64_t f8f9_38 = f8   * (int64_t) f9_38;
-+  int64_t f9f9_38 = f9   * (int64_t) f9_38;
-+  int64_t h0 = f0f0  +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
-+  int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
-+  int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
-+  int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
-+  int64_t h4 = f0f4_2+f1f3_4 +f2f2   +f5f9_76+f6f8_38+f7f7_38;
-+  int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
-+  int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
-+  int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
-+  int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4   +f9f9_38;
-+  int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
-+  int64_t carry0;
-+  int64_t carry1;
-+  int64_t carry2;
-+  int64_t carry3;
-+  int64_t carry4;
-+  int64_t carry5;
-+  int64_t carry6;
-+  int64_t carry7;
-+  int64_t carry8;
-+  int64_t carry9;
-+
-+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
-+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
-+
-+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
-+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
-+
-+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
-+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
-+
-+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
-+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
-+
-+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
-+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
-+
-+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
-+
-+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
-+
-+  h[0] = h0;
-+  h[1] = h1;
-+  h[2] = h2;
-+  h[3] = h3;
-+  h[4] = h4;
-+  h[5] = h5;
-+  h[6] = h6;
-+  h[7] = h7;
-+  h[8] = h8;
-+  h[9] = h9;
-+}
-+
-+static void fe_invert(fe out, const fe z) {
-+  fe t0;
-+  fe t1;
-+  fe t2;
-+  fe t3;
-+  int i;
-+
-+  /*
-+   * Compute z ** -1 = z ** (2 ** 255 - 19 - 2) with the exponent as
-+   * 2 ** 255 - 21 = (2 ** 5) * (2 ** 250 - 1) + 11.
-+   */
-+
-+  /* t0 = z ** 2 */
-+  fe_sq(t0, z);
-+
-+  /* t1 = t0 ** (2 ** 2) = z ** 8 */
-+  fe_sq(t1, t0);
-+  fe_sq(t1, t1);
-+
-+  /* t1 = z * t1 = z ** 9 */
-+  fe_mul(t1, z, t1);
-+  /* t0 = t0 * t1 = z ** 11 -- stash t0 away for the end. */
-+  fe_mul(t0, t0, t1);
-+
-+  /* t2 = t0 ** 2 = z ** 22 */
-+  fe_sq(t2, t0);
-+
-+  /* t1 = t1 * t2 = z ** (2 ** 5 - 1) */
-+  fe_mul(t1, t1, t2);
-+
-+  /* t2 = t1 ** (2 ** 5) = z ** ((2 ** 5) * (2 ** 5 - 1)) */
-+  fe_sq(t2, t1);
-+  for (i = 1; i < 5; ++i) {
-+    fe_sq(t2, t2);
-+  }
-+
-+  /* t1 = t1 * t2 = z ** ((2 ** 5 + 1) * (2 ** 5 - 1)) = z ** (2 ** 10 - 1) */
-+  fe_mul(t1, t2, t1);
-+
-+  /* Continuing similarly... */
-+
-+  /* t2 = z ** (2 ** 20 - 1) */
-+  fe_sq(t2, t1);
-+  for (i = 1; i < 10; ++i) {
-+    fe_sq(t2, t2);
-+  }
-+  fe_mul(t2, t2, t1);
-+
-+  /* t2 = z ** (2 ** 40 - 1) */
-+  fe_sq(t3, t2);
-+  for (i = 1; i < 20; ++i) {
-+    fe_sq(t3, t3);
-+  }
-+  fe_mul(t2, t3, t2);
-+
-+  /* t2 = z ** (2 ** 10) * (2 ** 40 - 1) */
-+  for (i = 0; i < 10; ++i) {
-+    fe_sq(t2, t2);
-+  }
-+  /* t1 = z ** (2 ** 50 - 1) */
-+  fe_mul(t1, t2, t1);
-+
-+  /* t2 = z ** (2 ** 100 - 1) */
-+  fe_sq(t2, t1);
-+  for (i = 1; i < 50; ++i) {
-+    fe_sq(t2, t2);
-+  }
-+  fe_mul(t2, t2, t1);
-+
-+  /* t2 = z ** (2 ** 200 - 1) */
-+  fe_sq(t3, t2);
-+  for (i = 1; i < 100; ++i) {
-+    fe_sq(t3, t3);
-+  }
-+  fe_mul(t2, t3, t2);
-+
-+  /* t2 = z ** ((2 ** 50) * (2 ** 200 - 1) */
-+  fe_sq(t2, t2);
-+  for (i = 1; i < 50; ++i) {
-+    fe_sq(t2, t2);
-+  }
-+
-+  /* t1 = z ** (2 ** 250 - 1) */
-+  fe_mul(t1, t2, t1);
-+
-+  /* t1 = z ** ((2 ** 5) * (2 ** 250 - 1)) */
-+  fe_sq(t1, t1);
-+  for (i = 1; i < 5; ++i) {
-+    fe_sq(t1, t1);
-+  }
-+
-+  /* Recall t0 = z ** 11; out = z ** (2 ** 255 - 21) */
-+  fe_mul(out, t1, t0);
-+}
-+
-+/* h = -f
-+ *
-+ * Preconditions:
-+ *    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
-+ *
-+ * Postconditions:
-+ *    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
-+static void fe_neg(fe h, const fe f) {
-+  unsigned i;
-+  for (i = 0; i < 10; i++) {
-+    h[i] = -f[i];
-+  }
-+}
-+
-+/* Replace (f,g) with (g,g) if b == 1;
-+ * replace (f,g) with (f,g) if b == 0.
-+ *
-+ * Preconditions: b in {0,1}. */
-+static void fe_cmov(fe f, const fe g, unsigned b) {
-+  size_t i;
-+  b = 0-b;
-+  for (i = 0; i < 10; i++) {
-+    int32_t x = f[i] ^ g[i];
-+    x &= b;
-+    f[i] ^= x;
-+  }
-+}
-+
-+/* h = 2 * f * f
-+ * Can overlap h with f.
-+ *
-+ * Preconditions:
-+ *    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
-+ *
-+ * Postconditions:
-+ *    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
-+ *
-+ * See fe_mul.c for discussion of implementation strategy. */
-+static void fe_sq2(fe h, const fe f) {
-+  int32_t f0 = f[0];
-+  int32_t f1 = f[1];
-+  int32_t f2 = f[2];
-+  int32_t f3 = f[3];
-+  int32_t f4 = f[4];
-+  int32_t f5 = f[5];
-+  int32_t f6 = f[6];
-+  int32_t f7 = f[7];
-+  int32_t f8 = f[8];
-+  int32_t f9 = f[9];
-+  int32_t f0_2 = 2 * f0;
-+  int32_t f1_2 = 2 * f1;
-+  int32_t f2_2 = 2 * f2;
-+  int32_t f3_2 = 2 * f3;
-+  int32_t f4_2 = 2 * f4;
-+  int32_t f5_2 = 2 * f5;
-+  int32_t f6_2 = 2 * f6;
-+  int32_t f7_2 = 2 * f7;
-+  int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
-+  int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
-+  int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
-+  int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
-+  int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
-+  int64_t f0f0    = f0   * (int64_t) f0;
-+  int64_t f0f1_2  = f0_2 * (int64_t) f1;
-+  int64_t f0f2_2  = f0_2 * (int64_t) f2;
-+  int64_t f0f3_2  = f0_2 * (int64_t) f3;
-+  int64_t f0f4_2  = f0_2 * (int64_t) f4;
-+  int64_t f0f5_2  = f0_2 * (int64_t) f5;
-+  int64_t f0f6_2  = f0_2 * (int64_t) f6;
-+  int64_t f0f7_2  = f0_2 * (int64_t) f7;
-+  int64_t f0f8_2  = f0_2 * (int64_t) f8;
-+  int64_t f0f9_2  = f0_2 * (int64_t) f9;
-+  int64_t f1f1_2  = f1_2 * (int64_t) f1;
-+  int64_t f1f2_2  = f1_2 * (int64_t) f2;
-+  int64_t f1f3_4  = f1_2 * (int64_t) f3_2;
-+  int64_t f1f4_2  = f1_2 * (int64_t) f4;
-+  int64_t f1f5_4  = f1_2 * (int64_t) f5_2;
-+  int64_t f1f6_2  = f1_2 * (int64_t) f6;
-+  int64_t f1f7_4  = f1_2 * (int64_t) f7_2;
-+  int64_t f1f8_2  = f1_2 * (int64_t) f8;
-+  int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
-+  int64_t f2f2    = f2   * (int64_t) f2;
-+  int64_t f2f3_2  = f2_2 * (int64_t) f3;
-+  int64_t f2f4_2  = f2_2 * (int64_t) f4;
-+  int64_t f2f5_2  = f2_2 * (int64_t) f5;
-+  int64_t f2f6_2  = f2_2 * (int64_t) f6;
-+  int64_t f2f7_2  = f2_2 * (int64_t) f7;
-+  int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
-+  int64_t f2f9_38 = f2   * (int64_t) f9_38;
-+  int64_t f3f3_2  = f3_2 * (int64_t) f3;
-+  int64_t f3f4_2  = f3_2 * (int64_t) f4;
-+  int64_t f3f5_4  = f3_2 * (int64_t) f5_2;
-+  int64_t f3f6_2  = f3_2 * (int64_t) f6;
-+  int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
-+  int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
-+  int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
-+  int64_t f4f4    = f4   * (int64_t) f4;
-+  int64_t f4f5_2  = f4_2 * (int64_t) f5;
-+  int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
-+  int64_t f4f7_38 = f4   * (int64_t) f7_38;
-+  int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
-+  int64_t f4f9_38 = f4   * (int64_t) f9_38;
-+  int64_t f5f5_38 = f5   * (int64_t) f5_38;
-+  int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
-+  int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
-+  int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
-+  int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
-+  int64_t f6f6_19 = f6   * (int64_t) f6_19;
-+  int64_t f6f7_38 = f6   * (int64_t) f7_38;
-+  int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
-+  int64_t f6f9_38 = f6   * (int64_t) f9_38;
-+  int64_t f7f7_38 = f7   * (int64_t) f7_38;
-+  int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
-+  int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
-+  int64_t f8f8_19 = f8   * (int64_t) f8_19;
-+  int64_t f8f9_38 = f8   * (int64_t) f9_38;
-+  int64_t f9f9_38 = f9   * (int64_t) f9_38;
-+  int64_t h0 = f0f0  +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
-+  int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
-+  int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
-+  int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
-+  int64_t h4 = f0f4_2+f1f3_4 +f2f2   +f5f9_76+f6f8_38+f7f7_38;
-+  int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
-+  int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
-+  int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
-+  int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4   +f9f9_38;
-+  int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
-+  int64_t carry0;
-+  int64_t carry1;
-+  int64_t carry2;
-+  int64_t carry3;
-+  int64_t carry4;
-+  int64_t carry5;
-+  int64_t carry6;
-+  int64_t carry7;
-+  int64_t carry8;
-+  int64_t carry9;
-+
-+  h0 += h0;
-+  h1 += h1;
-+  h2 += h2;
-+  h3 += h3;
-+  h4 += h4;
-+  h5 += h5;
-+  h6 += h6;
-+  h7 += h7;
-+  h8 += h8;
-+  h9 += h9;
-+
-+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
-+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
-+
-+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
-+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
-+
-+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
-+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
-+
-+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
-+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
-+
-+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
-+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
-+
-+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
-+
-+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
-+
-+  h[0] = h0;
-+  h[1] = h1;
-+  h[2] = h2;
-+  h[3] = h3;
-+  h[4] = h4;
-+  h[5] = h5;
-+  h[6] = h6;
-+  h[7] = h7;
-+  h[8] = h8;
-+  h[9] = h9;
-+}
-+
-+/* ge means group element.
-+
-+ * Here the group is the set of pairs (x,y) of field elements (see fe.h)
-+ * satisfying -x^2 + y^2 = 1 + d x^2y^2
-+ * where d = -121665/121666.
-+ *
-+ * Representations:
-+ *   ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
-+ *   ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
-+ *   ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
-+ *   ge_precomp (Duif): (y+x,y-x,2dxy) */
-+
-+typedef struct {
-+  fe X;
-+  fe Y;
-+  fe Z;
-+} ge_p2;
-+
-+typedef struct {
-+  fe X;
-+  fe Y;
-+  fe Z;
-+  fe T;
-+} ge_p3;
-+
-+typedef struct {
-+  fe X;
-+  fe Y;
-+  fe Z;
-+  fe T;
-+} ge_p1p1;
-+
-+typedef struct {
-+  fe yplusx;
-+  fe yminusx;
-+  fe xy2d;
-+} ge_precomp;
-+
-+typedef struct {
-+  fe YplusX;
-+  fe YminusX;
-+  fe Z;
-+  fe T2d;
-+} ge_cached;
-+
-+static void ge_p3_0(ge_p3 *h) {
-+  fe_0(h->X);
-+  fe_1(h->Y);
-+  fe_1(h->Z);
-+  fe_0(h->T);
-+}
-+
-+static void ge_precomp_0(ge_precomp *h) {
-+  fe_1(h->yplusx);
-+  fe_1(h->yminusx);
-+  fe_0(h->xy2d);
-+}
-+
-+/* r = p */
-+static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
-+  fe_copy(r->X, p->X);
-+  fe_copy(r->Y, p->Y);
-+  fe_copy(r->Z, p->Z);
-+}
-+
-+/* r = p */
-+static void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
-+  fe_mul(r->X, p->X, p->T);
-+  fe_mul(r->Y, p->Y, p->Z);
-+  fe_mul(r->Z, p->Z, p->T);
-+}
-+
-+/* r = p */
-+static void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
-+  fe_mul(r->X, p->X, p->T);
-+  fe_mul(r->Y, p->Y, p->Z);
-+  fe_mul(r->Z, p->Z, p->T);
-+  fe_mul(r->T, p->X, p->Y);
-+}
-+
-+/* r = 2 * p */
-+static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
-+  fe t0;
-+
-+  fe_sq(r->X, p->X);
-+  fe_sq(r->Z, p->Y);
-+  fe_sq2(r->T, p->Z);
-+  fe_add(r->Y, p->X, p->Y);
-+  fe_sq(t0, r->Y);
-+  fe_add(r->Y, r->Z, r->X);
-+  fe_sub(r->Z, r->Z, r->X);
-+  fe_sub(r->X, t0, r->Y);
-+  fe_sub(r->T, r->T, r->Z);
-+}
-+
-+/* r = 2 * p */
-+static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
-+  ge_p2 q;
-+  ge_p3_to_p2(&q, p);
-+  ge_p2_dbl(r, &q);
-+}
-+
-+/* r = p + q */
-+static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
-+  fe t0;
-+
-+  fe_add(r->X, p->Y, p->X);
-+  fe_sub(r->Y, p->Y, p->X);
-+  fe_mul(r->Z, r->X, q->yplusx);
-+  fe_mul(r->Y, r->Y, q->yminusx);
-+  fe_mul(r->T, q->xy2d, p->T);
-+  fe_add(t0, p->Z, p->Z);
-+  fe_sub(r->X, r->Z, r->Y);
-+  fe_add(r->Y, r->Z, r->Y);
-+  fe_add(r->Z, t0, r->T);
-+  fe_sub(r->T, t0, r->T);
-+}
-+
-+static uint8_t equal(signed char b, signed char c) {
-+  uint8_t ub = b;
-+  uint8_t uc = c;
-+  uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */
-+  uint32_t y = x;      /* 0: yes; 1..255: no */
-+  y -= 1;              /* 4294967295: yes; 0..254: no */
-+  y >>= 31;            /* 1: yes; 0: no */
-+  return y;
-+}
-+
-+static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) {
-+  fe_cmov(t->yplusx, u->yplusx, b);
-+  fe_cmov(t->yminusx, u->yminusx, b);
-+  fe_cmov(t->xy2d, u->xy2d, b);
-+}
-+
-+/* k25519Precomp[i][j] = (j+1)*256^i*B */
-+static const ge_precomp k25519Precomp[32][8] = {
-+    {
-+        {
-+            {25967493, -14356035, 29566456, 3660896, -12694345, 4014787,
-+             27544626, -11754271, -6079156, 2047605},
-+            {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692,
-+             5043384, 19500929, -15469378},
-+            {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380,
-+             29287919, 11864899, -24514362, -4438546},
-+        },
-+        {
-+            {-12815894, -12976347, -21581243, 11784320, -25355658, -2750717,
-+             -11717903, -3814571, -358445, -10211303},
-+            {-21703237, 6903825, 27185491, 6451973, -29577724, -9554005,
-+             -15616551, 11189268, -26829678, -5319081},
-+            {26966642, 11152617, 32442495, 15396054, 14353839, -12752335,
-+             -3128826, -9541118, -15472047, -4166697},
-+        },
-+        {
-+            {15636291, -9688557, 24204773, -7912398, 616977, -16685262,
-+             27787600, -14772189, 28944400, -1550024},
-+            {16568933, 4717097, -11556148, -1102322, 15682896, -11807043,
-+             16354577, -11775962, 7689662, 11199574},
-+            {30464156, -5976125, -11779434, -15670865, 23220365, 15915852,
-+             7512774, 10017326, -17749093, -9920357},
-+        },
-+        {
-+            {-17036878, 13921892, 10945806, -6033431, 27105052, -16084379,
-+             -28926210, 15006023, 3284568, -6276540},
-+            {23599295, -8306047, -11193664, -7687416, 13236774, 10506355,
-+             7464579, 9656445, 13059162, 10374397},
-+            {7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664,
-+             -3839045, -641708, -101325},
-+        },
-+        {
-+            {10861363, 11473154, 27284546, 1981175, -30064349, 12577861,
-+             32867885, 14515107, -15438304, 10819380},
-+            {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668,
-+             12483688, -12668491, 5581306},
-+            {19563160, 16186464, -29386857, 4097519, 10237984, -4348115,
-+             28542350, 13850243, -23678021, -15815942},
-+        },
-+        {
-+            {-15371964, -12862754, 32573250, 4720197, -26436522, 5875511,
-+             -19188627, -15224819, -9818940, -12085777},
-+            {-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240,
-+             -15689887, 1762328, 14866737},
-+            {-18199695, -15951423, -10473290, 1707278, -17185920, 3916101,
-+             -28236412, 3959421, 27914454, 4383652},
-+        },
-+        {
-+            {5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852,
-+             5230134, -23952439, -15175766},
-+            {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722,
-+             20654025, 16520125, 30598449, 7715701},
-+            {28881845, 14381568, 9657904, 3680757, -20181635, 7843316,
-+             -31400660, 1370708, 29794553, -1409300},
-+        },
-+        {
-+            {14499471, -2729599, -33191113, -4254652, 28494862, 14271267,
-+             30290735, 10876454, -33154098, 2381726},
-+            {-7195431, -2655363, -14730155, 462251, -27724326, 3941372,
-+             -6236617, 3696005, -32300832, 15351955},
-+            {27431194, 8222322, 16448760, -3907995, -18707002, 11938355,
-+             -32961401, -2970515, 29551813, 10109425},
-+        },
-+    },
-+    {
-+        {
-+            {-13657040, -13155431, -31283750, 11777098, 21447386, 6519384,
-+             -2378284, -1627556, 10092783, -4764171},
-+            {27939166, 14210322, 4677035, 16277044, -22964462, -12398139,
-+             -32508754, 12005538, -17810127, 12803510},
-+            {17228999, -15661624, -1233527, 300140, -1224870, -11714777,
-+             30364213, -9038194, 18016357, 4397660},
-+        },
-+        {
-+            {-10958843, -7690207, 4776341, -14954238, 27850028, -15602212,
-+             -26619106, 14544525, -17477504, 982639},
-+            {29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899,
-+             -4120128, -21047696, 9934963},
-+            {5793303, 16271923, -24131614, -10116404, 29188560, 1206517,
-+             -14747930, 4559895, -30123922, -10897950},
-+        },
-+        {
-+            {-27643952, -11493006, 16282657, -11036493, 28414021, -15012264,
-+             24191034, 4541697, -13338309, 5500568},
-+            {12650548, -1497113, 9052871, 11355358, -17680037, -8400164,
-+             -17430592, 12264343, 10874051, 13524335},
-+            {25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038,
-+             5080568, -22528059, 5376628},
-+        },
-+        {
-+            {-26088264, -4011052, -17013699, -3537628, -6726793, 1920897,
-+             -22321305, -9447443, 4535768, 1569007},
-+            {-2255422, 14606630, -21692440, -8039818, 28430649, 8775819,
-+             -30494562, 3044290, 31848280, 12543772},
-+            {-22028579, 2943893, -31857513, 6777306, 13784462, -4292203,
-+             -27377195, -2062731, 7718482, 14474653},
-+        },
-+        {
-+            {2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965,
-+             -7236665, 24316168, -5253567},
-+            {13741529, 10911568, -33233417, -8603737, -20177830, -1033297,
-+             33040651, -13424532, -20729456, 8321686},
-+            {21060490, -2212744, 15712757, -4336099, 1639040, 10656336,
-+             23845965, -11874838, -9984458, 608372},
-+        },
-+        {
-+            {-13672732, -15087586, -10889693, -7557059, -6036909, 11305547,
-+             1123968, -6780577, 27229399, 23887},
-+            {-23244140, -294205, -11744728, 14712571, -29465699, -2029617,
-+             12797024, -6440308, -1633405, 16678954},
-+            {-29500620, 4770662, -16054387, 14001338, 7830047, 9564805,
-+             -1508144, -4795045, -17169265, 4904953},
-+        },
-+        {
-+            {24059557, 14617003, 19037157, -15039908, 19766093, -14906429,
-+             5169211, 16191880, 2128236, -4326833},
-+            {-16981152, 4124966, -8540610, -10653797, 30336522, -14105247,
-+             -29806336, 916033, -6882542, -2986532},
-+            {-22630907, 12419372, -7134229, -7473371, -16478904, 16739175,
-+             285431, 2763829, 15736322, 4143876},
-+        },
-+        {
-+            {2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801,
-+             -14594663, 23527084, -16458268},
-+            {33431127, -11130478, -17838966, -15626900, 8909499, 8376530,
-+             -32625340, 4087881, -15188911, -14416214},
-+            {1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055,
-+             4357868, -4774191, -16323038},
-+        },
-+    },
-+    {
-+        {
-+            {6721966, 13833823, -23523388, -1551314, 26354293, -11863321,
-+             23365147, -3949732, 7390890, 2759800},
-+            {4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353,
-+             -4264057, 1244380, -12919645},
-+            {-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413,
-+             9208236, 15886429, 16489664},
-+        },
-+        {
-+            {1996075, 10375649, 14346367, 13311202, -6874135, -16438411,
-+             -13693198, 398369, -30606455, -712933},
-+            {-25307465, 9795880, -2777414, 14878809, -33531835, 14780363,
-+             13348553, 12076947, -30836462, 5113182},
-+            {-17770784, 11797796, 31950843, 13929123, -25888302, 12288344,
-+             -30341101, -7336386, 13847711, 5387222},
-+        },
-+        {
-+            {-18582163, -3416217, 17824843, -2340966, 22744343, -10442611,
-+             8763061, 3617786, -19600662, 10370991},
-+            {20246567, -14369378, 22358229, -543712, 18507283, -10413996,
-+             14554437, -8746092, 32232924, 16763880},
-+            {9648505, 10094563, 26416693, 14745928, -30374318, -6472621,
-+             11094161, 15689506, 3140038, -16510092},
-+        },
-+        {
-+            {-16160072, 5472695, 31895588, 4744994, 8823515, 10365685,
-+             -27224800, 9448613, -28774454, 366295},
-+            {19153450, 11523972, -11096490, -6503142, -24647631, 5420647,
-+             28344573, 8041113, 719605, 11671788},
-+            {8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916,
-+             -15266516, 27000813, -10195553},
-+        },
-+        {
-+            {-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065,
-+             5336097, 6750977, -14521026},
-+            {11836410, -3979488, 26297894, 16080799, 23455045, 15735944,
-+             1695823, -8819122, 8169720, 16220347},
-+            {-18115838, 8653647, 17578566, -6092619, -8025777, -16012763,
-+             -11144307, -2627664, -5990708, -14166033},
-+        },
-+        {
-+            {-23308498, -10968312, 15213228, -10081214, -30853605, -11050004,
-+             27884329, 2847284, 2655861, 1738395},
-+            {-27537433, -14253021, -25336301, -8002780, -9370762, 8129821,
-+             21651608, -3239336, -19087449, -11005278},
-+            {1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092,
-+             5821408, 10478196, 8544890},
-+        },
-+        {
-+            {32173121, -16129311, 24896207, 3921497, 22579056, -3410854,
-+             19270449, 12217473, 17789017, -3395995},
-+            {-30552961, -2228401, -15578829, -10147201, 13243889, 517024,
-+             15479401, -3853233, 30460520, 1052596},
-+            {-11614875, 13323618, 32618793, 8175907, -15230173, 12596687,
-+             27491595, -4612359, 3179268, -9478891},
-+        },
-+        {
-+            {31947069, -14366651, -4640583, -15339921, -15125977, -6039709,
-+             -14756777, -16411740, 19072640, -9511060},
-+            {11685058, 11822410, 3158003, -13952594, 33402194, -4165066,
-+             5977896, -5215017, 473099, 5040608},
-+            {-20290863, 8198642, -27410132, 11602123, 1290375, -2799760,
-+             28326862, 1721092, -19558642, -3131606},
-+        },
-+    },
-+    {
-+        {
-+            {7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786,
-+             8076149, -27868496, 11538389},
-+            {-19935666, 3899861, 18283497, -6801568, -15728660, -11249211,
-+             8754525, 7446702, -5676054, 5797016},
-+            {-11295600, -3793569, -15782110, -7964573, 12708869, -8456199,
-+             2014099, -9050574, -2369172, -5877341},
-+        },
-+        {
-+            {-22472376, -11568741, -27682020, 1146375, 18956691, 16640559,
-+             1192730, -3714199, 15123619, 10811505},
-+            {14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363,
-+             15776356, -28886779, -11974553},
-+            {-28241164, -8072475, -4978962, -5315317, 29416931, 1847569,
-+             -20654173, -16484855, 4714547, -9600655},
-+        },
-+        {
-+            {15200332, 8368572, 19679101, 15970074, -31872674, 1959451,
-+             24611599, -4543832, -11745876, 12340220},
-+            {12876937, -10480056, 33134381, 6590940, -6307776, 14872440,
-+             9613953, 8241152, 15370987, 9608631},
-+            {-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868,
-+             15866074, -28210621, -8814099},
-+        },
-+        {
-+            {26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233,
-+             858697, 20571223, 8420556},
-+            {14620715, 13067227, -15447274, 8264467, 14106269, 15080814,
-+             33531827, 12516406, -21574435, -12476749},
-+            {236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519,
-+             7256740, 8791136, 15069930},
-+        },
-+        {
-+            {1276410, -9371918, 22949635, -16322807, -23493039, -5702186,
-+             14711875, 4874229, -30663140, -2331391},
-+            {5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175,
-+             -7912378, -33069337, 9234253},
-+            {20590503, -9018988, 31529744, -7352666, -2706834, 10650548,
-+             31559055, -11609587, 18979186, 13396066},
-+        },
-+        {
-+            {24474287, 4968103, 22267082, 4407354, 24063882, -8325180,
-+             -18816887, 13594782, 33514650, 7021958},
-+            {-11566906, -6565505, -21365085, 15928892, -26158305, 4315421,
-+             -25948728, -3916677, -21480480, 12868082},
-+            {-28635013, 13504661, 19988037, -2132761, 21078225, 6443208,
-+             -21446107, 2244500, -12455797, -8089383},
-+        },
-+        {
-+            {-30595528, 13793479, -5852820, 319136, -25723172, -6263899,
-+             33086546, 8957937, -15233648, 5540521},
-+            {-11630176, -11503902, -8119500, -7643073, 2620056, 1022908,
-+             -23710744, -1568984, -16128528, -14962807},
-+            {23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819,
-+             892185, -11513277, -15205948},
-+        },
-+        {
-+            {9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819,
-+             4763127, -19179614, 5867134},
-+            {-32765025, 1927590, 31726409, -4753295, 23962434, -16019500,
-+             27846559, 5931263, -29749703, -16108455},
-+            {27461885, -2977536, 22380810, 1815854, -23033753, -3031938,
-+             7283490, -15148073, -19526700, 7734629},
-+        },
-+    },
-+    {
-+        {
-+            {-8010264, -9590817, -11120403, 6196038, 29344158, -13430885,
-+             7585295, -3176626, 18549497, 15302069},
-+            {-32658337, -6171222, -7672793, -11051681, 6258878, 13504381,
-+             10458790, -6418461, -8872242, 8424746},
-+            {24687205, 8613276, -30667046, -3233545, 1863892, -1830544,
-+             19206234, 7134917, -11284482, -828919},
-+        },
-+        {
-+            {11334899, -9218022, 8025293, 12707519, 17523892, -10476071,
-+             10243738, -14685461, -5066034, 16498837},
-+            {8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925,
-+             -14124238, 6536641, 10543906},
-+            {-28946384, 15479763, -17466835, 568876, -1497683, 11223454,
-+             -2669190, -16625574, -27235709, 8876771},
-+        },
-+        {
-+            {-25742899, -12566864, -15649966, -846607, -33026686, -796288,
-+             -33481822, 15824474, -604426, -9039817},
-+            {10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697,
-+             -4890037, 1657394, 3084098},
-+            {10477963, -7470260, 12119566, -13250805, 29016247, -5365589,
-+             31280319, 14396151, -30233575, 15272409},
-+        },
-+        {
-+            {-12288309, 3169463, 28813183, 16658753, 25116432, -5630466,
-+             -25173957, -12636138, -25014757, 1950504},
-+            {-26180358, 9489187, 11053416, -14746161, -31053720, 5825630,
-+             -8384306, -8767532, 15341279, 8373727},
-+            {28685821, 7759505, -14378516, -12002860, -31971820, 4079242,
-+             298136, -10232602, -2878207, 15190420},
-+        },
-+        {
-+            {-32932876, 13806336, -14337485, -15794431, -24004620, 10940928,
-+             8669718, 2742393, -26033313, -6875003},
-+            {-1580388, -11729417, -25979658, -11445023, -17411874, -10912854,
-+             9291594, -16247779, -12154742, 6048605},
-+            {-30305315, 14843444, 1539301, 11864366, 20201677, 1900163,
-+             13934231, 5128323, 11213262, 9168384},
-+        },
-+        {
-+            {-26280513, 11007847, 19408960, -940758, -18592965, -4328580,
-+             -5088060, -11105150, 20470157, -16398701},
-+            {-23136053, 9282192, 14855179, -15390078, -7362815, -14408560,
-+             -22783952, 14461608, 14042978, 5230683},
-+            {29969567, -2741594, -16711867, -8552442, 9175486, -2468974,
-+             21556951, 3506042, -5933891, -12449708},
-+        },
-+        {
-+            {-3144746, 8744661, 19704003, 4581278, -20430686, 6830683,
-+             -21284170, 8971513, -28539189, 15326563},
-+            {-19464629, 10110288, -17262528, -3503892, -23500387, 1355669,
-+             -15523050, 15300988, -20514118, 9168260},
-+            {-5353335, 4488613, -23803248, 16314347, 7780487, -15638939,
-+             -28948358, 9601605, 33087103, -9011387},
-+        },
-+        {
-+            {-19443170, -15512900, -20797467, -12445323, -29824447, 10229461,
-+             -27444329, -15000531, -5996870, 15664672},
-+            {23294591, -16632613, -22650781, -8470978, 27844204, 11461195,
-+             13099750, -2460356, 18151676, 13417686},
-+            {-24722913, -4176517, -31150679, 5988919, -26858785, 6685065,
-+             1661597, -12551441, 15271676, -15452665},
-+        },
-+    },
-+    {
-+        {
-+            {11433042, -13228665, 8239631, -5279517, -1985436, -725718,
-+             -18698764, 2167544, -6921301, -13440182},
-+            {-31436171, 15575146, 30436815, 12192228, -22463353, 9395379,
-+             -9917708, -8638997, 12215110, 12028277},
-+            {14098400, 6555944, 23007258, 5757252, -15427832, -12950502,
-+             30123440, 4617780, -16900089, -655628},
-+        },
-+        {
-+            {-4026201, -15240835, 11893168, 13718664, -14809462, 1847385,
-+             -15819999, 10154009, 23973261, -12684474},
-+            {-26531820, -3695990, -1908898, 2534301, -31870557, -16550355,
-+             18341390, -11419951, 32013174, -10103539},
-+            {-25479301, 10876443, -11771086, -14625140, -12369567, 1838104,
-+             21911214, 6354752, 4425632, -837822},
-+        },
-+        {
-+            {-10433389, -14612966, 22229858, -3091047, -13191166, 776729,
-+             -17415375, -12020462, 4725005, 14044970},
-+            {19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390,
-+             -1411784, -19522291, -16109756},
-+            {-24864089, 12986008, -10898878, -5558584, -11312371, -148526,
-+             19541418, 8180106, 9282262, 10282508},
-+        },
-+        {
-+            {-26205082, 4428547, -8661196, -13194263, 4098402, -14165257,
-+             15522535, 8372215, 5542595, -10702683},
-+            {-10562541, 14895633, 26814552, -16673850, -17480754, -2489360,
-+             -2781891, 6993761, -18093885, 10114655},
-+            {-20107055, -929418, 31422704, 10427861, -7110749, 6150669,
-+             -29091755, -11529146, 25953725, -106158},
-+        },
-+        {
-+            {-4234397, -8039292, -9119125, 3046000, 2101609, -12607294,
-+             19390020, 6094296, -3315279, 12831125},
-+            {-15998678, 7578152, 5310217, 14408357, -33548620, -224739,
-+             31575954, 6326196, 7381791, -2421839},
-+            {-20902779, 3296811, 24736065, -16328389, 18374254, 7318640,
-+             6295303, 8082724, -15362489, 12339664},
-+        },
-+        {
-+            {27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414,
-+             15768922, 25091167, 14856294},
-+            {-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300,
-+             -12695493, -22182473, -9012899},
-+            {-11423429, -5421590, 11632845, 3405020, 30536730, -11674039,
-+             -27260765, 13866390, 30146206, 9142070},
-+        },
-+        {
-+            {3924129, -15307516, -13817122, -10054960, 12291820, -668366,
-+             -27702774, 9326384, -8237858, 4171294},
-+            {-15921940, 16037937, 6713787, 16606682, -21612135, 2790944,
-+             26396185, 3731949, 345228, -5462949},
-+            {-21327538, 13448259, 25284571, 1143661, 20614966, -8849387,
-+             2031539, -12391231, -16253183, -13582083},
-+        },
-+        {
-+            {31016211, -16722429, 26371392, -14451233, -5027349, 14854137,
-+             17477601, 3842657, 28012650, -16405420},
-+            {-5075835, 9368966, -8562079, -4600902, -15249953, 6970560,
-+             -9189873, 16292057, -8867157, 3507940},
-+            {29439664, 3537914, 23333589, 6997794, -17555561, -11018068,
-+             -15209202, -15051267, -9164929, 6580396},
-+        },
-+    },
-+    {
-+        {
-+            {-12185861, -7679788, 16438269, 10826160, -8696817, -6235611,
-+             17860444, -9273846, -2095802, 9304567},
-+            {20714564, -4336911, 29088195, 7406487, 11426967, -5095705,
-+             14792667, -14608617, 5289421, -477127},
-+            {-16665533, -10650790, -6160345, -13305760, 9192020, -1802462,
-+             17271490, 12349094, 26939669, -3752294},
-+        },
-+        {
-+            {-12889898, 9373458, 31595848, 16374215, 21471720, 13221525,
-+             -27283495, -12348559, -3698806, 117887},
-+            {22263325, -6560050, 3984570, -11174646, -15114008, -566785,
-+             28311253, 5358056, -23319780, 541964},
-+            {16259219, 3261970, 2309254, -15534474, -16885711, -4581916,
-+             24134070, -16705829, -13337066, -13552195},
-+        },
-+        {
-+            {9378160, -13140186, -22845982, -12745264, 28198281, -7244098,
-+             -2399684, -717351, 690426, 14876244},
-+            {24977353, -314384, -8223969, -13465086, 28432343, -1176353,
-+             -13068804, -12297348, -22380984, 6618999},
-+            {-1538174, 11685646, 12944378, 13682314, -24389511, -14413193,
-+             8044829, -13817328, 32239829, -5652762},
-+        },
-+        {
-+            {-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647,
-+             -10350059, 32779359, 5095274},
-+            {-33008130, -5214506, -32264887, -3685216, 9460461, -9327423,
-+             -24601656, 14506724, 21639561, -2630236},
-+            {-16400943, -13112215, 25239338, 15531969, 3987758, -4499318,
-+             -1289502, -6863535, 17874574, 558605},
-+        },
-+        {
-+            {-13600129, 10240081, 9171883, 16131053, -20869254, 9599700,
-+             33499487, 5080151, 2085892, 5119761},
-+            {-22205145, -2519528, -16381601, 414691, -25019550, 2170430,
-+             30634760, -8363614, -31999993, -5759884},
-+            {-6845704, 15791202, 8550074, -1312654, 29928809, -12092256,
-+             27534430, -7192145, -22351378, 12961482},
-+        },
-+        {
-+            {-24492060, -9570771, 10368194, 11582341, -23397293, -2245287,
-+             16533930, 8206996, -30194652, -5159638},
-+            {-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630,
-+             7031275, 7589640, 8945490},
-+            {-32152748, 8917967, 6661220, -11677616, -1192060, -15793393,
-+             7251489, -11182180, 24099109, -14456170},
-+        },
-+        {
-+            {5019558, -7907470, 4244127, -14714356, -26933272, 6453165,
-+             -19118182, -13289025, -6231896, -10280736},
-+            {10853594, 10721687, 26480089, 5861829, -22995819, 1972175,
-+             -1866647, -10557898, -3363451, -6441124},
-+            {-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661,
-+             -2008168, -13866408, 7421392},
-+        },
-+        {
-+            {8139927, -6546497, 32257646, -5890546, 30375719, 1886181,
-+             -21175108, 15441252, 28826358, -4123029},
-+            {6267086, 9695052, 7709135, -16603597, -32869068, -1886135,
-+             14795160, -7840124, 13746021, -1742048},
-+            {28584902, 7787108, -6732942, -15050729, 22846041, -7571236,
-+             -3181936, -363524, 4771362, -8419958},
-+        },
-+    },
-+    {
-+        {
-+            {24949256, 6376279, -27466481, -8174608, -18646154, -9930606,
-+             33543569, -12141695, 3569627, 11342593},
-+            {26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886,
-+             4608608, 7325975, -14801071},
-+            {-11618399, -14554430, -24321212, 7655128, -1369274, 5214312,
-+             -27400540, 10258390, -17646694, -8186692},
-+        },
-+        {
-+            {11431204, 15823007, 26570245, 14329124, 18029990, 4796082,
-+             -31446179, 15580664, 9280358, -3973687},
-+            {-160783, -10326257, -22855316, -4304997, -20861367, -13621002,
-+             -32810901, -11181622, -15545091, 4387441},
-+            {-20799378, 12194512, 3937617, -5805892, -27154820, 9340370,
-+             -24513992, 8548137, 20617071, -7482001},
-+        },
-+        {
-+            {-938825, -3930586, -8714311, 16124718, 24603125, -6225393,
-+             -13775352, -11875822, 24345683, 10325460},
-+            {-19855277, -1568885, -22202708, 8714034, 14007766, 6928528,
-+             16318175, -1010689, 4766743, 3552007},
-+            {-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514,
-+             14481909, 10988822, -3994762},
-+        },
-+        {
-+            {15564307, -14311570, 3101243, 5684148, 30446780, -8051356,
-+             12677127, -6505343, -8295852, 13296005},
-+            {-9442290, 6624296, -30298964, -11913677, -4670981, -2057379,
-+             31521204, 9614054, -30000824, 12074674},
-+            {4771191, -135239, 14290749, -13089852, 27992298, 14998318,
-+             -1413936, -1556716, 29832613, -16391035},
-+        },
-+        {
-+            {7064884, -7541174, -19161962, -5067537, -18891269, -2912736,
-+             25825242, 5293297, -27122660, 13101590},
-+            {-2298563, 2439670, -7466610, 1719965, -27267541, -16328445,
-+             32512469, -5317593, -30356070, -4190957},
-+            {-30006540, 10162316, -33180176, 3981723, -16482138, -13070044,
-+             14413974, 9515896, 19568978, 9628812},
-+        },
-+        {
-+            {33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894,
-+             -6106839, -6291786, 3437740},
-+            {-18978877, 3884493, 19469877, 12726490, 15913552, 13614290,
-+             -22961733, 70104, 7463304, 4176122},
-+            {-27124001, 10659917, 11482427, -16070381, 12771467, -6635117,
-+             -32719404, -5322751, 24216882, 5944158},
-+        },
-+        {
-+            {8894125, 7450974, -2664149, -9765752, -28080517, -12389115,
-+             19345746, 14680796, 11632993, 5847885},
-+            {26942781, -2315317, 9129564, -4906607, 26024105, 11769399,
-+             -11518837, 6367194, -9727230, 4782140},
-+            {19916461, -4828410, -22910704, -11414391, 25606324, -5972441,
-+             33253853, 8220911, 6358847, -1873857},
-+        },
-+        {
-+            {801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388,
-+             -4480480, -13538503, 1387155},
-+            {19646058, 5720633, -11416706, 12814209, 11607948, 12749789,
-+             14147075, 15156355, -21866831, 11835260},
-+            {19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523,
-+             15467869, -26560550, 5052483},
-+        },
-+    },
-+    {
-+        {
-+            {-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123,
-+             -12618185, 12228557, -7003677},
-+            {32944382, 14922211, -22844894, 5188528, 21913450, -8719943,
-+             4001465, 13238564, -6114803, 8653815},
-+            {22865569, -4652735, 27603668, -12545395, 14348958, 8234005,
-+             24808405, 5719875, 28483275, 2841751},
-+        },
-+        {
-+            {-16420968, -1113305, -327719, -12107856, 21886282, -15552774,
-+             -1887966, -315658, 19932058, -12739203},
-+            {-11656086, 10087521, -8864888, -5536143, -19278573, -3055912,
-+             3999228, 13239134, -4777469, -13910208},
-+            {1382174, -11694719, 17266790, 9194690, -13324356, 9720081,
-+             20403944, 11284705, -14013818, 3093230},
-+        },
-+        {
-+            {16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424,
-+             16271225, -24049421, -6691850},
-+            {-21911077, -5927941, -4611316, -5560156, -31744103, -10785293,
-+             24123614, 15193618, -21652117, -16739389},
-+            {-9935934, -4289447, -25279823, 4372842, 2087473, 10399484,
-+             31870908, 14690798, 17361620, 11864968},
-+        },
-+        {
-+            {-11307610, 6210372, 13206574, 5806320, -29017692, -13967200,
-+             -12331205, -7486601, -25578460, -16240689},
-+            {14668462, -12270235, 26039039, 15305210, 25515617, 4542480,
-+             10453892, 6577524, 9145645, -6443880},
-+            {5974874, 3053895, -9433049, -10385191, -31865124, 3225009,
-+             -7972642, 3936128, -5652273, -3050304},
-+        },
-+        {
-+            {30625386, -4729400, -25555961, -12792866, -20484575, 7695099,
-+             17097188, -16303496, -27999779, 1803632},
-+            {-3553091, 9865099, -5228566, 4272701, -5673832, -16689700,
-+             14911344, 12196514, -21405489, 7047412},
-+            {20093277, 9920966, -11138194, -5343857, 13161587, 12044805,
-+             -32856851, 4124601, -32343828, -10257566},
-+        },
-+        {
-+            {-20788824, 14084654, -13531713, 7842147, 19119038, -13822605,
-+             4752377, -8714640, -21679658, 2288038},
-+            {-26819236, -3283715, 29965059, 3039786, -14473765, 2540457,
-+             29457502, 14625692, -24819617, 12570232},
-+            {-1063558, -11551823, 16920318, 12494842, 1278292, -5869109,
-+             -21159943, -3498680, -11974704, 4724943},
-+        },
-+        {
-+            {17960970, -11775534, -4140968, -9702530, -8876562, -1410617,
-+             -12907383, -8659932, -29576300, 1903856},
-+            {23134274, -14279132, -10681997, -1611936, 20684485, 15770816,
-+             -12989750, 3190296, 26955097, 14109738},
-+            {15308788, 5320727, -30113809, -14318877, 22902008, 7767164,
-+             29425325, -11277562, 31960942, 11934971},
-+        },
-+        {
-+            {-27395711, 8435796, 4109644, 12222639, -24627868, 14818669,
-+             20638173, 4875028, 10491392, 1379718},
-+            {-13159415, 9197841, 3875503, -8936108, -1383712, -5879801,
-+             33518459, 16176658, 21432314, 12180697},
-+            {-11787308, 11500838, 13787581, -13832590, -22430679, 10140205,
-+             1465425, 12689540, -10301319, -13872883},
-+        },
-+    },
-+    {
-+        {
-+            {5414091, -15386041, -21007664, 9643570, 12834970, 1186149,
-+             -2622916, -1342231, 26128231, 6032912},
-+            {-26337395, -13766162, 32496025, -13653919, 17847801, -12669156,
-+             3604025, 8316894, -25875034, -10437358},
-+            {3296484, 6223048, 24680646, -12246460, -23052020, 5903205,
-+             -8862297, -4639164, 12376617, 3188849},
-+        },
-+        {
-+            {29190488, -14659046, 27549113, -1183516, 3520066, -10697301,
-+             32049515, -7309113, -16109234, -9852307},
-+            {-14744486, -9309156, 735818, -598978, -20407687, -5057904,
-+             25246078, -15795669, 18640741, -960977},
-+            {-6928835, -16430795, 10361374, 5642961, 4910474, 12345252,
-+             -31638386, -494430, 10530747, 1053335},
-+        },
-+        {
-+            {-29265967, -14186805, -13538216, -12117373, -19457059, -10655384,
-+             -31462369, -2948985, 24018831, 15026644},
-+            {-22592535, -3145277, -2289276, 5953843, -13440189, 9425631,
-+             25310643, 13003497, -2314791, -15145616},
-+            {-27419985, -603321, -8043984, -1669117, -26092265, 13987819,
-+             -27297622, 187899, -23166419, -2531735},
-+        },
-+        {
-+            {-21744398, -13810475, 1844840, 5021428, -10434399, -15911473,
-+             9716667, 16266922, -5070217, 726099},
-+            {29370922, -6053998, 7334071, -15342259, 9385287, 2247707,
-+             -13661962, -4839461, 30007388, -15823341},
-+            {-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109,
-+             730663, 9835848, 4555336},
-+        },
-+        {
-+            {-23376435, 1410446, -22253753, -12899614, 30867635, 15826977,
-+             17693930, 544696, -11985298, 12422646},
-+            {31117226, -12215734, -13502838, 6561947, -9876867, -12757670,
-+             -5118685, -4096706, 29120153, 13924425},
-+            {-17400879, -14233209, 19675799, -2734756, -11006962, -5858820,
-+             -9383939, -11317700, 7240931, -237388},
-+        },
-+        {
-+            {-31361739, -11346780, -15007447, -5856218, -22453340, -12152771,
-+             1222336, 4389483, 3293637, -15551743},
-+            {-16684801, -14444245, 11038544, 11054958, -13801175, -3338533,
-+             -24319580, 7733547, 12796905, -6335822},
-+            {-8759414, -10817836, -25418864, 10783769, -30615557, -9746811,
-+             -28253339, 3647836, 3222231, -11160462},
-+        },
-+        {
-+            {18606113, 1693100, -25448386, -15170272, 4112353, 10045021,
-+             23603893, -2048234, -7550776, 2484985},
-+            {9255317, -3131197, -12156162, -1004256, 13098013, -9214866,
-+             16377220, -2102812, -19802075, -3034702},
-+            {-22729289, 7496160, -5742199, 11329249, 19991973, -3347502,
-+             -31718148, 9936966, -30097688, -10618797},
-+        },
-+        {
-+            {21878590, -5001297, 4338336, 13643897, -3036865, 13160960,
-+             19708896, 5415497, -7360503, -4109293},
-+            {27736861, 10103576, 12500508, 8502413, -3413016, -9633558,
-+             10436918, -1550276, -23659143, -8132100},
-+            {19492550, -12104365, -29681976, -852630, -3208171, 12403437,
-+             30066266, 8367329, 13243957, 8709688},
-+        },
-+    },
-+    {
-+        {
-+            {12015105, 2801261, 28198131, 10151021, 24818120, -4743133,
-+             -11194191, -5645734, 5150968, 7274186},
-+            {2831366, -12492146, 1478975, 6122054, 23825128, -12733586,
-+             31097299, 6083058, 31021603, -9793610},
-+            {-2529932, -2229646, 445613, 10720828, -13849527, -11505937,
-+             -23507731, 16354465, 15067285, -14147707},
-+        },
-+        {
-+            {7840942, 14037873, -33364863, 15934016, -728213, -3642706,
-+             21403988, 1057586, -19379462, -12403220},
-+            {915865, -16469274, 15608285, -8789130, -24357026, 6060030,
-+             -17371319, 8410997, -7220461, 16527025},
-+            {32922597, -556987, 20336074, -16184568, 10903705, -5384487,
-+             16957574, 52992, 23834301, 6588044},
-+        },
-+        {
-+            {32752030, 11232950, 3381995, -8714866, 22652988, -10744103,
-+             17159699, 16689107, -20314580, -1305992},
-+            {-4689649, 9166776, -25710296, -10847306, 11576752, 12733943,
-+             7924251, -2752281, 1976123, -7249027},
-+            {21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041,
-+             -3371252, 12331345, -8237197},
-+        },
-+        {
-+            {8651614, -4477032, -16085636, -4996994, 13002507, 2950805,
-+             29054427, -5106970, 10008136, -4667901},
-+            {31486080, 15114593, -14261250, 12951354, 14369431, -7387845,
-+             16347321, -13662089, 8684155, -10532952},
-+            {19443825, 11385320, 24468943, -9659068, -23919258, 2187569,
-+             -26263207, -6086921, 31316348, 14219878},
-+        },
-+        {
-+            {-28594490, 1193785, 32245219, 11392485, 31092169, 15722801,
-+             27146014, 6992409, 29126555, 9207390},
-+            {32382935, 1110093, 18477781, 11028262, -27411763, -7548111,
-+             -4980517, 10843782, -7957600, -14435730},
-+            {2814918, 7836403, 27519878, -7868156, -20894015, -11553689,
-+             -21494559, 8550130, 28346258, 1994730},
-+        },
-+        {
-+            {-19578299, 8085545, -14000519, -3948622, 2785838, -16231307,
-+             -19516951, 7174894, 22628102, 8115180},
-+            {-30405132, 955511, -11133838, -15078069, -32447087, -13278079,
-+             -25651578, 3317160, -9943017, 930272},
-+            {-15303681, -6833769, 28856490, 1357446, 23421993, 1057177,
-+             24091212, -1388970, -22765376, -10650715},
-+        },
-+        {
-+            {-22751231, -5303997, -12907607, -12768866, -15811511, -7797053,
-+             -14839018, -16554220, -1867018, 8398970},
-+            {-31969310, 2106403, -4736360, 1362501, 12813763, 16200670,
-+             22981545, -6291273, 18009408, -15772772},
-+            {-17220923, -9545221, -27784654, 14166835, 29815394, 7444469,
-+             29551787, -3727419, 19288549, 1325865},
-+        },
-+        {
-+            {15100157, -15835752, -23923978, -1005098, -26450192, 15509408,
-+             12376730, -3479146, 33166107, -8042750},
-+            {20909231, 13023121, -9209752, 16251778, -5778415, -8094914,
-+             12412151, 10018715, 2213263, -13878373},
-+            {32529814, -11074689, 30361439, -16689753, -9135940, 1513226,
-+             22922121, 6382134, -5766928, 8371348},
-+        },
-+    },
-+    {
-+        {
-+            {9923462, 11271500, 12616794, 3544722, -29998368, -1721626,
-+             12891687, -8193132, -26442943, 10486144},
-+            {-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726,
-+             2610596, -23921530, -11455195},
-+            {5408411, -1136691, -4969122, 10561668, 24145918, 14240566,
-+             31319731, -4235541, 19985175, -3436086},
-+        },
-+        {
-+            {-13994457, 16616821, 14549246, 3341099, 32155958, 13648976,
-+             -17577068, 8849297, 65030, 8370684},
-+            {-8320926, -12049626, 31204563, 5839400, -20627288, -1057277,
-+             -19442942, 6922164, 12743482, -9800518},
-+            {-2361371, 12678785, 28815050, 4759974, -23893047, 4884717,
-+             23783145, 11038569, 18800704, 255233},
-+        },
-+        {
-+            {-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847,
-+             9066957, 19258688, -14753793},
-+            {-2936654, -10827535, -10432089, 14516793, -3640786, 4372541,
-+             -31934921, 2209390, -1524053, 2055794},
-+            {580882, 16705327, 5468415, -2683018, -30926419, -14696000,
-+             -7203346, -8994389, -30021019, 7394435},
-+        },
-+        {
-+            {23838809, 1822728, -15738443, 15242727, 8318092, -3733104,
-+             -21672180, -3492205, -4821741, 14799921},
-+            {13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804,
-+             13496856, -9056018, 7402518},
-+            {2286874, -4435931, -20042458, -2008336, -13696227, 5038122,
-+             11006906, -15760352, 8205061, 1607563},
-+        },
-+        {
-+            {14414086, -8002132, 3331830, -3208217, 22249151, -5594188,
-+             18364661, -2906958, 30019587, -9029278},
-+            {-27688051, 1585953, -10775053, 931069, -29120221, -11002319,
-+             -14410829, 12029093, 9944378, 8024},
-+            {4368715, -3709630, 29874200, -15022983, -20230386, -11410704,
-+             -16114594, -999085, -8142388, 5640030},
-+        },
-+        {
-+            {10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887,
-+             -16694564, 15219798, -14327783},
-+            {27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605,
-+             -1173195, -18342183, 9742717},
-+            {6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614,
-+             7406442, 12420155, 1994844},
-+        },
-+        {
-+            {14012521, -5024720, -18384453, -9578469, -26485342, -3936439,
-+             -13033478, -10909803, 24319929, -6446333},
-+            {16412690, -4507367, 10772641, 15929391, -17068788, -4658621,
-+             10555945, -10484049, -30102368, -4739048},
-+            {22397382, -7767684, -9293161, -12792868, 17166287, -9755136,
-+             -27333065, 6199366, 21880021, -12250760},
-+        },
-+        {
-+            {-4283307, 5368523, -31117018, 8163389, -30323063, 3209128,
-+             16557151, 8890729, 8840445, 4957760},
-+            {-15447727, 709327, -6919446, -10870178, -29777922, 6522332,
-+             -21720181, 12130072, -14796503, 5005757},
-+            {-2114751, -14308128, 23019042, 15765735, -25269683, 6002752,
-+             10183197, -13239326, -16395286, -2176112},
-+        },
-+    },
-+    {
-+        {
-+            {-19025756, 1632005, 13466291, -7995100, -23640451, 16573537,
-+             -32013908, -3057104, 22208662, 2000468},
-+            {3065073, -1412761, -25598674, -361432, -17683065, -5703415,
-+             -8164212, 11248527, -3691214, -7414184},
-+            {10379208, -6045554, 8877319, 1473647, -29291284, -12507580,
-+             16690915, 2553332, -3132688, 16400289},
-+        },
-+        {
-+            {15716668, 1254266, -18472690, 7446274, -8448918, 6344164,
-+             -22097271, -7285580, 26894937, 9132066},
-+            {24158887, 12938817, 11085297, -8177598, -28063478, -4457083,
-+             -30576463, 64452, -6817084, -2692882},
-+            {13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710,
-+             -3418511, -4688006, 2364226},
-+        },
-+        {
-+            {16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024,
-+             -11697457, 15445875, -7798101},
-+            {29004207, -7867081, 28661402, -640412, -12794003, -7943086,
-+             31863255, -4135540, -278050, -15759279},
-+            {-6122061, -14866665, -28614905, 14569919, -10857999, -3591829,
-+             10343412, -6976290, -29828287, -10815811},
-+        },
-+        {
-+            {27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636,
-+             15372179, 17293797, 960709},
-+            {20263915, 11434237, -5765435, 11236810, 13505955, -10857102,
-+             -16111345, 6493122, -19384511, 7639714},
-+            {-2830798, -14839232, 25403038, -8215196, -8317012, -16173699,
-+             18006287, -16043750, 29994677, -15808121},
-+        },
-+        {
-+            {9769828, 5202651, -24157398, -13631392, -28051003, -11561624,
-+             -24613141, -13860782, -31184575, 709464},
-+            {12286395, 13076066, -21775189, -1176622, -25003198, 4057652,
-+             -32018128, -8890874, 16102007, 13205847},
-+            {13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170,
-+             8525972, 10151379, 10394400},
-+        },
-+        {
-+            {4024660, -16137551, 22436262, 12276534, -9099015, -2686099,
-+             19698229, 11743039, -33302334, 8934414},
-+            {-15879800, -4525240, -8580747, -2934061, 14634845, -698278,
-+             -9449077, 3137094, -11536886, 11721158},
-+            {17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229,
-+             8835153, -9205489, -1280045},
-+        },
-+        {
-+            {-461409, -7830014, 20614118, 16688288, -7514766, -4807119,
-+             22300304, 505429, 6108462, -6183415},
-+            {-5070281, 12367917, -30663534, 3234473, 32617080, -8422642,
-+             29880583, -13483331, -26898490, -7867459},
-+            {-31975283, 5726539, 26934134, 10237677, -3173717, -605053,
-+             24199304, 3795095, 7592688, -14992079},
-+        },
-+        {
-+            {21594432, -14964228, 17466408, -4077222, 32537084, 2739898,
-+             6407723, 12018833, -28256052, 4298412},
-+            {-20650503, -11961496, -27236275, 570498, 3767144, -1717540,
-+             13891942, -1569194, 13717174, 10805743},
-+            {-14676630, -15644296, 15287174, 11927123, 24177847, -8175568,
-+             -796431, 14860609, -26938930, -5863836},
-+        },
-+    },
-+    {
-+        {
-+            {12962541, 5311799, -10060768, 11658280, 18855286, -7954201,
-+             13286263, -12808704, -4381056, 9882022},
-+            {18512079, 11319350, -20123124, 15090309, 18818594, 5271736,
-+             -22727904, 3666879, -23967430, -3299429},
-+            {-6789020, -3146043, 16192429, 13241070, 15898607, -14206114,
-+             -10084880, -6661110, -2403099, 5276065},
-+        },
-+        {
-+            {30169808, -5317648, 26306206, -11750859, 27814964, 7069267,
-+             7152851, 3684982, 1449224, 13082861},
-+            {10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382,
-+             15056736, -21016438, -8202000},
-+            {-33150110, 3261608, 22745853, 7948688, 19370557, -15177665,
-+             -26171976, 6482814, -10300080, -11060101},
-+        },
-+        {
-+            {32869458, -5408545, 25609743, 15678670, -10687769, -15471071,
-+             26112421, 2521008, -22664288, 6904815},
-+            {29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737,
-+             3841096, -29003639, -6657642},
-+            {10340844, -6630377, -18656632, -2278430, 12621151, -13339055,
-+             30878497, -11824370, -25584551, 5181966},
-+        },
-+        {
-+            {25940115, -12658025, 17324188, -10307374, -8671468, 15029094,
-+             24396252, -16450922, -2322852, -12388574},
-+            {-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390,
-+             12641087, 20603771, -6561742},
-+            {-18882287, -11673380, 24849422, 11501709, 13161720, -4768874,
-+             1925523, 11914390, 4662781, 7820689},
-+        },
-+        {
-+            {12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456,
-+             12172924, 16136752, 15264020},
-+            {-10349955, -14680563, -8211979, 2330220, -17662549, -14545780,
-+             10658213, 6671822, 19012087, 3772772},
-+            {3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732,
-+             -15762884, 20527771, 12988982},
-+        },
-+        {
-+            {-14822485, -5797269, -3707987, 12689773, -898983, -10914866,
-+             -24183046, -10564943, 3299665, -12424953},
-+            {-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197,
-+             6461331, -25583147, 8991218},
-+            {-17226263, 1816362, -1673288, -6086439, 31783888, -8175991,
-+             -32948145, 7417950, -30242287, 1507265},
-+        },
-+        {
-+            {29692663, 6829891, -10498800, 4334896, 20945975, -11906496,
-+             -28887608, 8209391, 14606362, -10647073},
-+            {-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695,
-+             9761487, 4170404, -2085325},
-+            {-11587470, 14855945, -4127778, -1531857, -26649089, 15084046,
-+             22186522, 16002000, -14276837, -8400798},
-+        },
-+        {
-+            {-4811456, 13761029, -31703877, -2483919, -3312471, 7869047,
-+             -7113572, -9620092, 13240845, 10965870},
-+            {-7742563, -8256762, -14768334, -13656260, -23232383, 12387166,
-+             4498947, 14147411, 29514390, 4302863},
-+            {-13413405, -12407859, 20757302, -13801832, 14785143, 8976368,
-+             -5061276, -2144373, 17846988, -13971927},
-+        },
-+    },
-+    {
-+        {
-+            {-2244452, -754728, -4597030, -1066309, -6247172, 1455299,
-+             -21647728, -9214789, -5222701, 12650267},
-+            {-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813,
-+             13770293, -19134326, 10958663},
-+            {22470984, 12369526, 23446014, -5441109, -21520802, -9698723,
-+             -11772496, -11574455, -25083830, 4271862},
-+        },
-+        {
-+            {-25169565, -10053642, -19909332, 15361595, -5984358, 2159192,
-+             75375, -4278529, -32526221, 8469673},
-+            {15854970, 4148314, -8893890, 7259002, 11666551, 13824734,
-+             -30531198, 2697372, 24154791, -9460943},
-+            {15446137, -15806644, 29759747, 14019369, 30811221, -9610191,
-+             -31582008, 12840104, 24913809, 9815020},
-+        },
-+        {
-+            {-4709286, -5614269, -31841498, -12288893, -14443537, 10799414,
-+             -9103676, 13438769, 18735128, 9466238},
-+            {11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821,
-+             -10896103, -22728655, 16199064},
-+            {14576810, 379472, -26786533, -8317236, -29426508, -10812974,
-+             -102766, 1876699, 30801119, 2164795},
-+        },
-+        {
-+            {15995086, 3199873, 13672555, 13712240, -19378835, -4647646,
-+             -13081610, -15496269, -13492807, 1268052},
-+            {-10290614, -3659039, -3286592, 10948818, 23037027, 3794475,
-+             -3470338, -12600221, -17055369, 3565904},
-+            {29210088, -9419337, -5919792, -4952785, 10834811, -13327726,
-+             -16512102, -10820713, -27162222, -14030531},
-+        },
-+        {
-+            {-13161890, 15508588, 16663704, -8156150, -28349942, 9019123,
-+             -29183421, -3769423, 2244111, -14001979},
-+            {-5152875, -3800936, -9306475, -6071583, 16243069, 14684434,
-+             -25673088, -16180800, 13491506, 4641841},
-+            {10813417, 643330, -19188515, -728916, 30292062, -16600078,
-+             27548447, -7721242, 14476989, -12767431},
-+        },
-+        {
-+            {10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937,
-+             -1644259, -27912810, 12651324},
-+            {-31185513, -813383, 22271204, 11835308, 10201545, 15351028,
-+             17099662, 3988035, 21721536, -3148940},
-+            {10202177, -6545839, -31373232, -9574638, -32150642, -8119683,
-+             -12906320, 3852694, 13216206, 14842320},
-+        },
-+        {
-+            {-15815640, -10601066, -6538952, -7258995, -6984659, -6581778,
-+             -31500847, 13765824, -27434397, 9900184},
-+            {14465505, -13833331, -32133984, -14738873, -27443187, 12990492,
-+             33046193, 15796406, -7051866, -8040114},
-+            {30924417, -8279620, 6359016, -12816335, 16508377, 9071735,
-+             -25488601, 15413635, 9524356, -7018878},
-+        },
-+        {
-+            {12274201, -13175547, 32627641, -1785326, 6736625, 13267305,
-+             5237659, -5109483, 15663516, 4035784},
-+            {-2951309, 8903985, 17349946, 601635, -16432815, -4612556,
-+             -13732739, -15889334, -22258478, 4659091},
-+            {-16916263, -4952973, -30393711, -15158821, 20774812, 15897498,
-+             5736189, 15026997, -2178256, -13455585},
-+        },
-+    },
-+    {
-+        {
-+            {-8858980, -2219056, 28571666, -10155518, -474467, -10105698,
-+             -3801496, 278095, 23440562, -290208},
-+            {10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275,
-+             11551483, -16571960, -7442864},
-+            {17932739, -12437276, -24039557, 10749060, 11316803, 7535897,
-+             22503767, 5561594, -3646624, 3898661},
-+        },
-+        {
-+            {7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531,
-+             7152530, 21831162, 1245233},
-+            {26958459, -14658026, 4314586, 8346991, -5677764, 11960072,
-+             -32589295, -620035, -30402091, -16716212},
-+            {-12165896, 9166947, 33491384, 13673479, 29787085, 13096535,
-+             6280834, 14587357, -22338025, 13987525},
-+        },
-+        {
-+            {-24349909, 7778775, 21116000, 15572597, -4833266, -5357778,
-+             -4300898, -5124639, -7469781, -2858068},
-+            {9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781,
-+             6439245, -14581012, 4091397},
-+            {-8426427, 1470727, -28109679, -1596990, 3978627, -5123623,
-+             -19622683, 12092163, 29077877, -14741988},
-+        },
-+        {
-+            {5269168, -6859726, -13230211, -8020715, 25932563, 1763552,
-+             -5606110, -5505881, -20017847, 2357889},
-+            {32264008, -15407652, -5387735, -1160093, -2091322, -3946900,
-+             23104804, -12869908, 5727338, 189038},
-+            {14609123, -8954470, -6000566, -16622781, -14577387, -7743898,
-+             -26745169, 10942115, -25888931, -14884697},
-+        },
-+        {
-+            {20513500, 5557931, -15604613, 7829531, 26413943, -2019404,
-+             -21378968, 7471781, 13913677, -5137875},
-+            {-25574376, 11967826, 29233242, 12948236, -6754465, 4713227,
-+             -8940970, 14059180, 12878652, 8511905},
-+            {-25656801, 3393631, -2955415, -7075526, -2250709, 9366908,
-+             -30223418, 6812974, 5568676, -3127656},
-+        },
-+        {
-+            {11630004, 12144454, 2116339, 13606037, 27378885, 15676917,
-+             -17408753, -13504373, -14395196, 8070818},
-+            {27117696, -10007378, -31282771, -5570088, 1127282, 12772488,
-+             -29845906, 10483306, -11552749, -1028714},
-+            {10637467, -5688064, 5674781, 1072708, -26343588, -6982302,
-+             -1683975, 9177853, -27493162, 15431203},
-+        },
-+        {
-+            {20525145, 10892566, -12742472, 12779443, -29493034, 16150075,
-+             -28240519, 14943142, -15056790, -7935931},
-+            {-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767,
-+             -3239766, -3356550, 9594024},
-+            {-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683,
-+             -6492290, 13352335, -10977084},
-+        },
-+        {
-+            {-1931799, -5407458, 3304649, -12884869, 17015806, -4877091,
-+             -29783850, -7752482, -13215537, -319204},
-+            {20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742,
-+             15077870, -22750759, 14523817},
-+            {27406042, -6041657, 27423596, -4497394, 4996214, 10002360,
-+             -28842031, -4545494, -30172742, -4805667},
-+        },
-+    },
-+    {
-+        {
-+            {11374242, 12660715, 17861383, -12540833, 10935568, 1099227,
-+             -13886076, -9091740, -27727044, 11358504},
-+            {-12730809, 10311867, 1510375, 10778093, -2119455, -9145702,
-+             32676003, 11149336, -26123651, 4985768},
-+            {-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043,
-+             13794114, -19414307, -15621255},
-+        },
-+        {
-+            {6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603,
-+             6970005, -1691065, -9004790},
-+            {1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622,
-+             -5475723, -16796596, -5031438},
-+            {-22273315, -13524424, -64685, -4334223, -18605636, -10921968,
-+             -20571065, -7007978, -99853, -10237333},
-+        },
-+        {
-+            {17747465, 10039260, 19368299, -4050591, -20630635, -16041286,
-+             31992683, -15857976, -29260363, -5511971},
-+            {31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999,
-+             -3744247, 4882242, -10626905},
-+            {29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198,
-+             3272828, -5190932, -4162409},
-+        },
-+        {
-+            {12501286, 4044383, -8612957, -13392385, -32430052, 5136599,
-+             -19230378, -3529697, 330070, -3659409},
-+            {6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522,
-+             -8573892, -271295, 12071499},
-+            {-8365515, -4042521, 25133448, -4517355, -6211027, 2265927,
-+             -32769618, 1936675, -5159697, 3829363},
-+        },
-+        {
-+            {28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550,
-+             -6567787, 26333140, 14267664},
-+            {-11067219, 11871231, 27385719, -10559544, -4585914, -11189312,
-+             10004786, -8709488, -21761224, 8930324},
-+            {-21197785, -16396035, 25654216, -1725397, 12282012, 11008919,
-+             1541940, 4757911, -26491501, -16408940},
-+        },
-+        {
-+            {13537262, -7759490, -20604840, 10961927, -5922820, -13218065,
-+             -13156584, 6217254, -15943699, 13814990},
-+            {-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681,
-+             9257833, -1956526, -1776914},
-+            {-25045300, -10191966, 15366585, 15166509, -13105086, 8423556,
-+             -29171540, 12361135, -18685978, 4578290},
-+        },
-+        {
-+            {24579768, 3711570, 1342322, -11180126, -27005135, 14124956,
-+             -22544529, 14074919, 21964432, 8235257},
-+            {-6528613, -2411497, 9442966, -5925588, 12025640, -1487420,
-+             -2981514, -1669206, 13006806, 2355433},
-+            {-16304899, -13605259, -6632427, -5142349, 16974359, -10911083,
-+             27202044, 1719366, 1141648, -12796236},
-+        },
-+        {
-+            {-12863944, -13219986, -8318266, -11018091, -6810145, -4843894,
-+             13475066, -3133972, 32674895, 13715045},
-+            {11423335, -5468059, 32344216, 8962751, 24989809, 9241752,
-+             -13265253, 16086212, -28740881, -15642093},
-+            {-1409668, 12530728, -6368726, 10847387, 19531186, -14132160,
-+             -11709148, 7791794, -27245943, 4383347},
-+        },
-+    },
-+    {
-+        {
-+            {-28970898, 5271447, -1266009, -9736989, -12455236, 16732599,
-+             -4862407, -4906449, 27193557, 6245191},
-+            {-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898,
-+             3260492, 22510453, 8577507},
-+            {-12632451, 11257346, -32692994, 13548177, -721004, 10879011,
-+             31168030, 13952092, -29571492, -3635906},
-+        },
-+        {
-+            {3877321, -9572739, 32416692, 5405324, -11004407, -13656635,
-+             3759769, 11935320, 5611860, 8164018},
-+            {-16275802, 14667797, 15906460, 12155291, -22111149, -9039718,
-+             32003002, -8832289, 5773085, -8422109},
-+            {-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725,
-+             12376320, 31632953, 190926},
-+        },
-+        {
-+            {-24593607, -16138885, -8423991, 13378746, 14162407, 6901328,
-+             -8288749, 4508564, -25341555, -3627528},
-+            {8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941,
-+             -14786005, -1672488, 827625},
-+            {-32720583, -16289296, -32503547, 7101210, 13354605, 2659080,
-+             -1800575, -14108036, -24878478, 1541286},
-+        },
-+        {
-+            {2901347, -1117687, 3880376, -10059388, -17620940, -3612781,
-+             -21802117, -3567481, 20456845, -1885033},
-+            {27019610, 12299467, -13658288, -1603234, -12861660, -4861471,
-+             -19540150, -5016058, 29439641, 15138866},
-+            {21536104, -6626420, -32447818, -10690208, -22408077, 5175814,
-+             -5420040, -16361163, 7779328, 109896},
-+        },
-+        {
-+            {30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390,
-+             12180118, 23177719, -554075},
-+            {26572847, 3405927, -31701700, 12890905, -19265668, 5335866,
-+             -6493768, 2378492, 4439158, -13279347},
-+            {-22716706, 3489070, -9225266, -332753, 18875722, -1140095,
-+             14819434, -12731527, -17717757, -5461437},
-+        },
-+        {
-+            {-5056483, 16566551, 15953661, 3767752, -10436499, 15627060,
-+             -820954, 2177225, 8550082, -15114165},
-+            {-18473302, 16596775, -381660, 15663611, 22860960, 15585581,
-+             -27844109, -3582739, -23260460, -8428588},
-+            {-32480551, 15707275, -8205912, -5652081, 29464558, 2713815,
-+             -22725137, 15860482, -21902570, 1494193},
-+        },
-+        {
-+            {-19562091, -14087393, -25583872, -9299552, 13127842, 759709,
-+             21923482, 16529112, 8742704, 12967017},
-+            {-28464899, 1553205, 32536856, -10473729, -24691605, -406174,
-+             -8914625, -2933896, -29903758, 15553883},
-+            {21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572,
-+             14513274, 19375923, -12647961},
-+        },
-+        {
-+            {8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818,
-+             -6222716, 2862653, 9455043},
-+            {29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124,
-+             -2990080, 15511449, 4789663},
-+            {-20679756, 7004547, 8824831, -9434977, -4045704, -3750736,
-+             -5754762, 108893, 23513200, 16652362},
-+        },
-+    },
-+    {
-+        {
-+            {-33256173, 4144782, -4476029, -6579123, 10770039, -7155542,
-+             -6650416, -12936300, -18319198, 10212860},
-+            {2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801,
-+             2600940, -9988298, -12506466},
-+            {-24645692, 13317462, -30449259, -15653928, 21365574, -10869657,
-+             11344424, 864440, -2499677, -16710063},
-+        },
-+        {
-+            {-26432803, 6148329, -17184412, -14474154, 18782929, -275997,
-+             -22561534, 211300, 2719757, 4940997},
-+            {-1323882, 3911313, -6948744, 14759765, -30027150, 7851207,
-+             21690126, 8518463, 26699843, 5276295},
-+            {-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586,
-+             149635, -15452774, 7159369},
-+        },
-+        {
-+            {9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009,
-+             8312176, 22477218, -8403385},
-+            {18155857, -16504990, 19744716, 9006923, 15154154, -10538976,
-+             24256460, -4864995, -22548173, 9334109},
-+            {2986088, -4911893, 10776628, -3473844, 10620590, -7083203,
-+             -21413845, 14253545, -22587149, 536906},
-+        },
-+        {
-+            {4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551,
-+             10589625, 10838060, -15420424},
-+            {-19342404, 867880, 9277171, -3218459, -14431572, -1986443,
-+             19295826, -15796950, 6378260, 699185},
-+            {7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039,
-+             15693155, -5045064, -13373962},
-+        },
-+        {
-+            {-7737563, -5869402, -14566319, -7406919, 11385654, 13201616,
-+             31730678, -10962840, -3918636, -9669325},
-+            {10188286, -15770834, -7336361, 13427543, 22223443, 14896287,
-+             30743455, 7116568, -21786507, 5427593},
-+            {696102, 13206899, 27047647, -10632082, 15285305, -9853179,
-+             10798490, -4578720, 19236243, 12477404},
-+        },
-+        {
-+            {-11229439, 11243796, -17054270, -8040865, -788228, -8167967,
-+             -3897669, 11180504, -23169516, 7733644},
-+            {17800790, -14036179, -27000429, -11766671, 23887827, 3149671,
-+             23466177, -10538171, 10322027, 15313801},
-+            {26246234, 11968874, 32263343, -5468728, 6830755, -13323031,
-+             -15794704, -101982, -24449242, 10890804},
-+        },
-+        {
-+            {-31365647, 10271363, -12660625, -6267268, 16690207, -13062544,
-+             -14982212, 16484931, 25180797, -5334884},
-+            {-586574, 10376444, -32586414, -11286356, 19801893, 10997610,
-+             2276632, 9482883, 316878, 13820577},
-+            {-9882808, -4510367, -2115506, 16457136, -11100081, 11674996,
-+             30756178, -7515054, 30696930, -3712849},
-+        },
-+        {
-+            {32988917, -9603412, 12499366, 7910787, -10617257, -11931514,
-+             -7342816, -9985397, -32349517, 7392473},
-+            {-8855661, 15927861, 9866406, -3649411, -2396914, -16655781,
-+             -30409476, -9134995, 25112947, -2926644},
-+            {-2504044, -436966, 25621774, -5678772, 15085042, -5479877,
-+             -24884878, -13526194, 5537438, -13914319},
-+        },
-+    },
-+    {
-+        {
-+            {-11225584, 2320285, -9584280, 10149187, -33444663, 5808648,
-+             -14876251, -1729667, 31234590, 6090599},
-+            {-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721,
-+             15878753, -6970405, -9034768},
-+            {-27757857, 247744, -15194774, -9002551, 23288161, -10011936,
-+             -23869595, 6503646, 20650474, 1804084},
-+        },
-+        {
-+            {-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995,
-+             -10329713, 27842616, -202328},
-+            {-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656,
-+             5031932, -11375082, 12714369},
-+            {20807691, -7270825, 29286141, 11421711, -27876523, -13868230,
-+             -21227475, 1035546, -19733229, 12796920},
-+        },
-+        {
-+            {12076899, -14301286, -8785001, -11848922, -25012791, 16400684,
-+             -17591495, -12899438, 3480665, -15182815},
-+            {-32361549, 5457597, 28548107, 7833186, 7303070, -11953545,
-+             -24363064, -15921875, -33374054, 2771025},
-+            {-21389266, 421932, 26597266, 6860826, 22486084, -6737172,
-+             -17137485, -4210226, -24552282, 15673397},
-+        },
-+        {
-+            {-20184622, 2338216, 19788685, -9620956, -4001265, -8740893,
-+             -20271184, 4733254, 3727144, -12934448},
-+            {6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594,
-+             7975683, 31123697, -10958981},
-+            {30069250, -11435332, 30434654, 2958439, 18399564, -976289,
-+             12296869, 9204260, -16432438, 9648165},
-+        },
-+        {
-+            {32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266,
-+             5248604, -26008332, -11377501},
-+            {17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711,
-+             15298639, 2662509, -16297073},
-+            {-1172927, -7558695, -4366770, -4287744, -21346413, -8434326,
-+             32087529, -1222777, 32247248, -14389861},
-+        },
-+        {
-+            {14312628, 1221556, 17395390, -8700143, -4945741, -8684635,
-+             -28197744, -9637817, -16027623, -13378845},
-+            {-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502,
-+             9803137, 17597934, 2346211},
-+            {18510800, 15337574, 26171504, 981392, -22241552, 7827556,
-+             -23491134, -11323352, 3059833, -11782870},
-+        },
-+        {
-+            {10141598, 6082907, 17829293, -1947643, 9830092, 13613136,
-+             -25556636, -5544586, -33502212, 3592096},
-+            {33114168, -15889352, -26525686, -13343397, 33076705, 8716171,
-+             1151462, 1521897, -982665, -6837803},
-+            {-32939165, -4255815, 23947181, -324178, -33072974, -12305637,
-+             -16637686, 3891704, 26353178, 693168},
-+        },
-+        {
-+            {30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294,
-+             -400668, 31375464, 14369965},
-+            {-14370654, -7772529, 1510301, 6434173, -18784789, -6262728,
-+             32732230, -13108839, 17901441, 16011505},
-+            {18171223, -11934626, -12500402, 15197122, -11038147, -15230035,
-+             -19172240, -16046376, 8764035, 12309598},
-+        },
-+    },
-+    {
-+        {
-+            {5975908, -5243188, -19459362, -9681747, -11541277, 14015782,
-+             -23665757, 1228319, 17544096, -10593782},
-+            {5811932, -1715293, 3442887, -2269310, -18367348, -8359541,
-+             -18044043, -15410127, -5565381, 12348900},
-+            {-31399660, 11407555, 25755363, 6891399, -3256938, 14872274,
-+             -24849353, 8141295, -10632534, -585479},
-+        },
-+        {
-+            {-12675304, 694026, -5076145, 13300344, 14015258, -14451394,
-+             -9698672, -11329050, 30944593, 1130208},
-+            {8247766, -6710942, -26562381, -7709309, -14401939, -14648910,
-+             4652152, 2488540, 23550156, -271232},
-+            {17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737,
-+             -5908146, -408818, -137719},
-+        },
-+        {
-+            {16091085, -16253926, 18599252, 7340678, 2137637, -1221657,
-+             -3364161, 14550936, 3260525, -7166271},
-+            {-4910104, -13332887, 18550887, 10864893, -16459325, -7291596,
-+             -23028869, -13204905, -12748722, 2701326},
-+            {-8574695, 16099415, 4629974, -16340524, -20786213, -6005432,
-+             -10018363, 9276971, 11329923, 1862132},
-+        },
-+        {
-+            {14763076, -15903608, -30918270, 3689867, 3511892, 10313526,
-+             -21951088, 12219231, -9037963, -940300},
-+            {8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216,
-+             -2909717, -15438168, 11595570},
-+            {15214962, 3537601, -26238722, -14058872, 4418657, -15230761,
-+             13947276, 10730794, -13489462, -4363670},
-+        },
-+        {
-+            {-2538306, 7682793, 32759013, 263109, -29984731, -7955452,
-+             -22332124, -10188635, 977108, 699994},
-+            {-12466472, 4195084, -9211532, 550904, -15565337, 12917920,
-+             19118110, -439841, -30534533, -14337913},
-+            {31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237,
-+             -10051775, 12493932, -5409317},
-+        },
-+        {
-+            {-25680606, 5260744, -19235809, -6284470, -3695942, 16566087,
-+             27218280, 2607121, 29375955, 6024730},
-+            {842132, -2794693, -4763381, -8722815, 26332018, -12405641,
-+             11831880, 6985184, -9940361, 2854096},
-+            {-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645,
-+             960770, 12121869, 16648078},
-+        },
-+        {
-+            {-15218652, 14667096, -13336229, 2013717, 30598287, -464137,
-+             -31504922, -7882064, 20237806, 2838411},
-+            {-19288047, 4453152, 15298546, -16178388, 22115043, -15972604,
-+             12544294, -13470457, 1068881, -12499905},
-+            {-9558883, -16518835, 33238498, 13506958, 30505848, -1114596,
-+             -8486907, -2630053, 12521378, 4845654},
-+        },
-+        {
-+            {-28198521, 10744108, -2958380, 10199664, 7759311, -13088600,
-+             3409348, -873400, -6482306, -12885870},
-+            {-23561822, 6230156, -20382013, 10655314, -24040585, -11621172,
-+             10477734, -1240216, -3113227, 13974498},
-+            {12966261, 15550616, -32038948, -1615346, 21025980, -629444,
-+             5642325, 7188737, 18895762, 12629579},
-+        },
-+    },
-+    {
-+        {
-+            {14741879, -14946887, 22177208, -11721237, 1279741, 8058600,
-+             11758140, 789443, 32195181, 3895677},
-+            {10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575,
-+             -3566119, -8982069, 4429647},
-+            {-2453894, 15725973, -20436342, -10410672, -5803908, -11040220,
-+             -7135870, -11642895, 18047436, -15281743},
-+        },
-+        {
-+            {-25173001, -11307165, 29759956, 11776784, -22262383, -15820455,
-+             10993114, -12850837, -17620701, -9408468},
-+            {21987233, 700364, -24505048, 14972008, -7774265, -5718395,
-+             32155026, 2581431, -29958985, 8773375},
-+            {-25568350, 454463, -13211935, 16126715, 25240068, 8594567,
-+             20656846, 12017935, -7874389, -13920155},
-+        },
-+        {
-+            {6028182, 6263078, -31011806, -11301710, -818919, 2461772,
-+             -31841174, -5468042, -1721788, -2776725},
-+            {-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845,
-+             -4166698, 28408820, 6816612},
-+            {-10358094, -8237829, 19549651, -12169222, 22082623, 16147817,
-+             20613181, 13982702, -10339570, 5067943},
-+        },
-+        {
-+            {-30505967, -3821767, 12074681, 13582412, -19877972, 2443951,
-+             -19719286, 12746132, 5331210, -10105944},
-+            {30528811, 3601899, -1957090, 4619785, -27361822, -15436388,
-+             24180793, -12570394, 27679908, -1648928},
-+            {9402404, -13957065, 32834043, 10838634, -26580150, -13237195,
-+             26653274, -8685565, 22611444, -12715406},
-+        },
-+        {
-+            {22190590, 1118029, 22736441, 15130463, -30460692, -5991321,
-+             19189625, -4648942, 4854859, 6622139},
-+            {-8310738, -2953450, -8262579, -3388049, -10401731, -271929,
-+             13424426, -3567227, 26404409, 13001963},
-+            {-31241838, -15415700, -2994250, 8939346, 11562230, -12840670,
-+             -26064365, -11621720, -15405155, 11020693},
-+        },
-+        {
-+            {1866042, -7949489, -7898649, -10301010, 12483315, 13477547,
-+             3175636, -12424163, 28761762, 1406734},
-+            {-448555, -1777666, 13018551, 3194501, -9580420, -11161737,
-+             24760585, -4347088, 25577411, -13378680},
-+            {-24290378, 4759345, -690653, -1852816, 2066747, 10693769,
-+             -29595790, 9884936, -9368926, 4745410},
-+        },
-+        {
-+            {-9141284, 6049714, -19531061, -4341411, -31260798, 9944276,
-+             -15462008, -11311852, 10931924, -11931931},
-+            {-16561513, 14112680, -8012645, 4817318, -8040464, -11414606,
-+             -22853429, 10856641, -20470770, 13434654},
-+            {22759489, -10073434, -16766264, -1871422, 13637442, -10168091,
-+             1765144, -12654326, 28445307, -5364710},
-+        },
-+        {
-+            {29875063, 12493613, 2795536, -3786330, 1710620, 15181182,
-+             -10195717, -8788675, 9074234, 1167180},
-+            {-26205683, 11014233, -9842651, -2635485, -26908120, 7532294,
-+             -18716888, -9535498, 3843903, 9367684},
-+            {-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123,
-+             8601684, -139197, 4242895},
-+        },
-+    },
-+    {
-+        {
-+            {22092954, -13191123, -2042793, -11968512, 32186753, -11517388,
-+             -6574341, 2470660, -27417366, 16625501},
-+            {-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857,
-+             2602725, -27351616, 14247413},
-+            {6314175, -10264892, -32772502, 15957557, -10157730, 168750,
-+             -8618807, 14290061, 27108877, -1180880},
-+        },
-+        {
-+            {-8586597, -7170966, 13241782, 10960156, -32991015, -13794596,
-+             33547976, -11058889, -27148451, 981874},
-+            {22833440, 9293594, -32649448, -13618667, -9136966, 14756819,
-+             -22928859, -13970780, -10479804, -16197962},
-+            {-7768587, 3326786, -28111797, 10783824, 19178761, 14905060,
-+             22680049, 13906969, -15933690, 3797899},
-+        },
-+        {
-+            {21721356, -4212746, -12206123, 9310182, -3882239, -13653110,
-+             23740224, -2709232, 20491983, -8042152},
-+            {9209270, -15135055, -13256557, -6167798, -731016, 15289673,
-+             25947805, 15286587, 30997318, -6703063},
-+            {7392032, 16618386, 23946583, -8039892, -13265164, -1533858,
-+             -14197445, -2321576, 17649998, -250080},
-+        },
-+        {
-+            {-9301088, -14193827, 30609526, -3049543, -25175069, -1283752,
-+             -15241566, -9525724, -2233253, 7662146},
-+            {-17558673, 1763594, -33114336, 15908610, -30040870, -12174295,
-+             7335080, -8472199, -3174674, 3440183},
-+            {-19889700, -5977008, -24111293, -9688870, 10799743, -16571957,
-+             40450, -4431835, 4862400, 1133},
-+        },
-+        {
-+            {-32856209, -7873957, -5422389, 14860950, -16319031, 7956142,
-+             7258061, 311861, -30594991, -7379421},
-+            {-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763,
-+             16527196, 18278453, 15405622},
-+            {-4381906, 8508652, -19898366, -3674424, -5984453, 15149970,
-+             -13313598, 843523, -21875062, 13626197},
-+        },
-+        {
-+            {2281448, -13487055, -10915418, -2609910, 1879358, 16164207,
-+             -10783882, 3953792, 13340839, 15928663},
-+            {31727126, -7179855, -18437503, -8283652, 2875793, -16390330,
-+             -25269894, -7014826, -23452306, 5964753},
-+            {4100420, -5959452, -17179337, 6017714, -18705837, 12227141,
-+             -26684835, 11344144, 2538215, -7570755},
-+        },
-+        {
-+            {-9433605, 6123113, 11159803, -2156608, 30016280, 14966241,
-+             -20474983, 1485421, -629256, -15958862},
-+            {-26804558, 4260919, 11851389, 9658551, -32017107, 16367492,
-+             -20205425, -13191288, 11659922, -11115118},
-+            {26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568,
-+             -10170080, 33100372, -1306171},
-+        },
-+        {
-+            {15121113, -5201871, -10389905, 15427821, -27509937, -15992507,
-+             21670947, 4486675, -5931810, -14466380},
-+            {16166486, -9483733, -11104130, 6023908, -31926798, -1364923,
-+             2340060, -16254968, -10735770, -10039824},
-+            {28042865, -3557089, -12126526, 12259706, -3717498, -6945899,
-+             6766453, -8689599, 18036436, 5803270},
-+        },
-+    },
-+    {
-+        {
-+            {-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391,
-+             4598332, -6159431, -14117438},
-+            {-31031306, -14256194, 17332029, -2383520, 31312682, -5967183,
-+             696309, 50292, -20095739, 11763584},
-+            {-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117,
-+             -12613632, -19773211, -10713562},
-+        },
-+        {
-+            {30464590, -11262872, -4127476, -12734478, 19835327, -7105613,
-+             -24396175, 2075773, -17020157, 992471},
-+            {18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841,
-+             8080033, -11574335, -10601610},
-+            {19598397, 10334610, 12555054, 2555664, 18821899, -10339780,
-+             21873263, 16014234, 26224780, 16452269},
-+        },
-+        {
-+            {-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804,
-+             -7618186, -20533829, 3698650},
-+            {14187449, 3448569, -10636236, -10810935, -22663880, -3433596,
-+             7268410, -10890444, 27394301, 12015369},
-+            {19695761, 16087646, 28032085, 12999827, 6817792, 11427614,
-+             20244189, -1312777, -13259127, -3402461},
-+        },
-+        {
-+            {30860103, 12735208, -1888245, -4699734, -16974906, 2256940,
-+             -8166013, 12298312, -8550524, -10393462},
-+            {-5719826, -11245325, -1910649, 15569035, 26642876, -7587760,
-+             -5789354, -15118654, -4976164, 12651793},
-+            {-2848395, 9953421, 11531313, -5282879, 26895123, -12697089,
-+             -13118820, -16517902, 9768698, -2533218},
-+        },
-+        {
-+            {-24719459, 1894651, -287698, -4704085, 15348719, -8156530,
-+             32767513, 12765450, 4940095, 10678226},
-+            {18860224, 15980149, -18987240, -1562570, -26233012, -11071856,
-+             -7843882, 13944024, -24372348, 16582019},
-+            {-15504260, 4970268, -29893044, 4175593, -20993212, -2199756,
-+             -11704054, 15444560, -11003761, 7989037},
-+        },
-+        {
-+            {31490452, 5568061, -2412803, 2182383, -32336847, 4531686,
-+             -32078269, 6200206, -19686113, -14800171},
-+            {-17308668, -15879940, -31522777, -2831, -32887382, 16375549,
-+             8680158, -16371713, 28550068, -6857132},
-+            {-28126887, -5688091, 16837845, -1820458, -6850681, 12700016,
-+             -30039981, 4364038, 1155602, 5988841},
-+        },
-+        {
-+            {21890435, -13272907, -12624011, 12154349, -7831873, 15300496,
-+             23148983, -4470481, 24618407, 8283181},
-+            {-33136107, -10512751, 9975416, 6841041, -31559793, 16356536,
-+             3070187, -7025928, 1466169, 10740210},
-+            {-1509399, -15488185, -13503385, -10655916, 32799044, 909394,
-+             -13938903, -5779719, -32164649, -15327040},
-+        },
-+        {
-+            {3960823, -14267803, -28026090, -15918051, -19404858, 13146868,
-+             15567327, 951507, -3260321, -573935},
-+            {24740841, 5052253, -30094131, 8961361, 25877428, 6165135,
-+             -24368180, 14397372, -7380369, -6144105},
-+            {-28888365, 3510803, -28103278, -1158478, -11238128, -10631454,
-+             -15441463, -14453128, -1625486, -6494814},
-+        },
-+    },
-+    {
-+        {
-+            {793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843,
-+             -4885251, -9906200, -621852},
-+            {5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374,
-+             1468826, -6171428, -15186581},
-+            {-4859255, -3779343, -2917758, -6748019, 7778750, 11688288,
-+             -30404353, -9871238, -1558923, -9863646},
-+        },
-+        {
-+            {10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958,
-+             14783338, -30581476, -15757844},
-+            {10566929, 12612572, -31944212, 11118703, -12633376, 12362879,
-+             21752402, 8822496, 24003793, 14264025},
-+            {27713862, -7355973, -11008240, 9227530, 27050101, 2504721,
-+             23886875, -13117525, 13958495, -5732453},
-+        },
-+        {
-+            {-23481610, 4867226, -27247128, 3900521, 29838369, -8212291,
-+             -31889399, -10041781, 7340521, -15410068},
-+            {4646514, -8011124, -22766023, -11532654, 23184553, 8566613,
-+             31366726, -1381061, -15066784, -10375192},
-+            {-17270517, 12723032, -16993061, 14878794, 21619651, -6197576,
-+             27584817, 3093888, -8843694, 3849921},
-+        },
-+        {
-+            {-9064912, 2103172, 25561640, -15125738, -5239824, 9582958,
-+             32477045, -9017955, 5002294, -15550259},
-+            {-12057553, -11177906, 21115585, -13365155, 8808712, -12030708,
-+             16489530, 13378448, -25845716, 12741426},
-+            {-5946367, 10645103, -30911586, 15390284, -3286982, -7118677,
-+             24306472, 15852464, 28834118, -7646072},
-+        },
-+        {
-+            {-17335748, -9107057, -24531279, 9434953, -8472084, -583362,
-+             -13090771, 455841, 20461858, 5491305},
-+            {13669248, -16095482, -12481974, -10203039, -14569770, -11893198,
-+             -24995986, 11293807, -28588204, -9421832},
-+            {28497928, 6272777, -33022994, 14470570, 8906179, -1225630,
-+             18504674, -14165166, 29867745, -8795943},
-+        },
-+        {
-+            {-16207023, 13517196, -27799630, -13697798, 24009064, -6373891,
-+             -6367600, -13175392, 22853429, -4012011},
-+            {24191378, 16712145, -13931797, 15217831, 14542237, 1646131,
-+             18603514, -11037887, 12876623, -2112447},
-+            {17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753,
-+             608397, 16031844, 3723494},
-+        },
-+        {
-+            {-28632773, 12763728, -20446446, 7577504, 33001348, -13017745,
-+             17558842, -7872890, 23896954, -4314245},
-+            {-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064,
-+             7229064, -9919646, -8826859},
-+            {28816045, 298879, -28165016, -15920938, 19000928, -1665890,
-+             -12680833, -2949325, -18051778, -2082915},
-+        },
-+        {
-+            {16000882, -344896, 3493092, -11447198, -29504595, -13159789,
-+             12577740, 16041268, -19715240, 7847707},
-+            {10151868, 10572098, 27312476, 7922682, 14825339, 4723128,
-+             -32855931, -6519018, -10020567, 3852848},
-+            {-11430470, 15697596, -21121557, -4420647, 5386314, 15063598,
-+             16514493, -15932110, 29330899, -15076224},
-+        },
-+    },
-+    {
-+        {
-+            {-25499735, -4378794, -15222908, -6901211, 16615731, 2051784,
-+             3303702, 15490, -27548796, 12314391},
-+            {15683520, -6003043, 18109120, -9980648, 15337968, -5997823,
-+             -16717435, 15921866, 16103996, -3731215},
-+            {-23169824, -10781249, 13588192, -1628807, -3798557, -1074929,
-+             -19273607, 5402699, -29815713, -9841101},
-+        },
-+        {
-+            {23190676, 2384583, -32714340, 3462154, -29903655, -1529132,
-+             -11266856, 8911517, -25205859, 2739713},
-+            {21374101, -3554250, -33524649, 9874411, 15377179, 11831242,
-+             -33529904, 6134907, 4931255, 11987849},
-+            {-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539,
-+             13861388, -30076310, 10117930},
-+        },
-+        {
-+            {-29501170, -10744872, -26163768, 13051539, -25625564, 5089643,
-+             -6325503, 6704079, 12890019, 15728940},
-+            {-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376,
-+             -10428139, 12885167, 8311031},
-+            {-17516482, 5352194, 10384213, -13811658, 7506451, 13453191,
-+             26423267, 4384730, 1888765, -5435404},
-+        },
-+        {
-+            {-25817338, -3107312, -13494599, -3182506, 30896459, -13921729,
-+             -32251644, -12707869, -19464434, -3340243},
-+            {-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245,
-+             14845197, 17151279, -9854116},
-+            {-24830458, -12733720, -15165978, 10367250, -29530908, -265356,
-+             22825805, -7087279, -16866484, 16176525},
-+        },
-+        {
-+            {-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182,
-+             -10363426, -28746253, -10197509},
-+            {-10626600, -4486402, -13320562, -5125317, 3432136, -6393229,
-+             23632037, -1940610, 32808310, 1099883},
-+            {15030977, 5768825, -27451236, -2887299, -6427378, -15361371,
-+             -15277896, -6809350, 2051441, -15225865},
-+        },
-+        {
-+            {-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398,
-+             -14154188, -22686354, 16633660},
-+            {4577086, -16752288, 13249841, -15304328, 19958763, -14537274,
-+             18559670, -10759549, 8402478, -9864273},
-+            {-28406330, -1051581, -26790155, -907698, -17212414, -11030789,
-+             9453451, -14980072, 17983010, 9967138},
-+        },
-+        {
-+            {-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990,
-+             7806337, 17507396, 3651560},
-+            {-10420457, -4118111, 14584639, 15971087, -15768321, 8861010,
-+             26556809, -5574557, -18553322, -11357135},
-+            {2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121,
-+             8459447, -5605463, -7621941},
-+        },
-+        {
-+            {-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813,
-+             -849066, 17258084, -7977739},
-+            {18164541, -10595176, -17154882, -1542417, 19237078, -9745295,
-+             23357533, -15217008, 26908270, 12150756},
-+            {-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168,
-+             -5537701, -32302074, 16215819},
-+        },
-+    },
-+    {
-+        {
-+            {-6898905, 9824394, -12304779, -4401089, -31397141, -6276835,
-+             32574489, 12532905, -7503072, -8675347},
-+            {-27343522, -16515468, -27151524, -10722951, 946346, 16291093,
-+             254968, 7168080, 21676107, -1943028},
-+            {21260961, -8424752, -16831886, -11920822, -23677961, 3968121,
-+             -3651949, -6215466, -3556191, -7913075},
-+        },
-+        {
-+            {16544754, 13250366, -16804428, 15546242, -4583003, 12757258,
-+             -2462308, -8680336, -18907032, -9662799},
-+            {-2415239, -15577728, 18312303, 4964443, -15272530, -12653564,
-+             26820651, 16690659, 25459437, -4564609},
-+            {-25144690, 11425020, 28423002, -11020557, -6144921, -15826224,
-+             9142795, -2391602, -6432418, -1644817},
-+        },
-+        {
-+            {-23104652, 6253476, 16964147, -3768872, -25113972, -12296437,
-+             -27457225, -16344658, 6335692, 7249989},
-+            {-30333227, 13979675, 7503222, -12368314, -11956721, -4621693,
-+             -30272269, 2682242, 25993170, -12478523},
-+            {4364628, 5930691, 32304656, -10044554, -8054781, 15091131,
-+             22857016, -10598955, 31820368, 15075278},
-+        },
-+        {
-+            {31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788,
-+             -9650886, -17970238, 12833045},
-+            {19073683, 14851414, -24403169, -11860168, 7625278, 11091125,
-+             -19619190, 2074449, -9413939, 14905377},
-+            {24483667, -11935567, -2518866, -11547418, -1553130, 15355506,
-+             -25282080, 9253129, 27628530, -7555480},
-+        },
-+        {
-+            {17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324,
-+             -9157582, -14110875, 15297016},
-+            {510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417,
-+             -11864220, 8683221, 2921426},
-+            {18606791, 11874196, 27155355, -5281482, -24031742, 6265446,
-+             -25178240, -1278924, 4674690, 13890525},
-+        },
-+        {
-+            {13609624, 13069022, -27372361, -13055908, 24360586, 9592974,
-+             14977157, 9835105, 4389687, 288396},
-+            {9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062,
-+             8317628, 23388070, 16052080},
-+            {12720016, 11937594, -31970060, -5028689, 26900120, 8561328,
-+             -20155687, -11632979, -14754271, -10812892},
-+        },
-+        {
-+            {15961858, 14150409, 26716931, -665832, -22794328, 13603569,
-+             11829573, 7467844, -28822128, 929275},
-+            {11038231, -11582396, -27310482, -7316562, -10498527, -16307831,
-+             -23479533, -9371869, -21393143, 2465074},
-+            {20017163, -4323226, 27915242, 1529148, 12396362, 15675764,
-+             13817261, -9658066, 2463391, -4622140},
-+        },
-+        {
-+            {-16358878, -12663911, -12065183, 4996454, -1256422, 1073572,
-+             9583558, 12851107, 4003896, 12673717},
-+            {-1731589, -15155870, -3262930, 16143082, 19294135, 13385325,
-+             14741514, -9103726, 7903886, 2348101},
-+            {24536016, -16515207, 12715592, -3862155, 1511293, 10047386,
-+             -3842346, -7129159, -28377538, 10048127},
-+        },
-+    },
-+    {
-+        {
-+            {-12622226, -6204820, 30718825, 2591312, -10617028, 12192840,
-+             18873298, -7297090, -32297756, 15221632},
-+            {-26478122, -11103864, 11546244, -1852483, 9180880, 7656409,
-+             -21343950, 2095755, 29769758, 6593415},
-+            {-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345,
-+             -6118678, 30958054, 8292160},
-+        },
-+        {
-+            {31429822, -13959116, 29173532, 15632448, 12174511, -2760094,
-+             32808831, 3977186, 26143136, -3148876},
-+            {22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633,
-+             -1674433, -3758243, -2304625},
-+            {-15491917, 8012313, -2514730, -12702462, -23965846, -10254029,
-+             -1612713, -1535569, -16664475, 8194478},
-+        },
-+        {
-+            {27338066, -7507420, -7414224, 10140405, -19026427, -6589889,
-+             27277191, 8855376, 28572286, 3005164},
-+            {26287124, 4821776, 25476601, -4145903, -3764513, -15788984,
-+             -18008582, 1182479, -26094821, -13079595},
-+            {-7171154, 3178080, 23970071, 6201893, -17195577, -4489192,
-+             -21876275, -13982627, 32208683, -1198248},
-+        },
-+        {
-+            {-16657702, 2817643, -10286362, 14811298, 6024667, 13349505,
-+             -27315504, -10497842, -27672585, -11539858},
-+            {15941029, -9405932, -21367050, 8062055, 31876073, -238629,
-+             -15278393, -1444429, 15397331, -4130193},
-+            {8934485, -13485467, -23286397, -13423241, -32446090, 14047986,
-+             31170398, -1441021, -27505566, 15087184},
-+        },
-+        {
-+            {-18357243, -2156491, 24524913, -16677868, 15520427, -6360776,
-+             -15502406, 11461896, 16788528, -5868942},
-+            {-1947386, 16013773, 21750665, 3714552, -17401782, -16055433,
-+             -3770287, -10323320, 31322514, -11615635},
-+            {21426655, -5650218, -13648287, -5347537, -28812189, -4920970,
-+             -18275391, -14621414, 13040862, -12112948},
-+        },
-+        {
-+            {11293895, 12478086, -27136401, 15083750, -29307421, 14748872,
-+             14555558, -13417103, 1613711, 4896935},
-+            {-25894883, 15323294, -8489791, -8057900, 25967126, -13425460,
-+             2825960, -4897045, -23971776, -11267415},
-+            {-15924766, -5229880, -17443532, 6410664, 3622847, 10243618,
-+             20615400, 12405433, -23753030, -8436416},
-+        },
-+        {
-+            {-7091295, 12556208, -20191352, 9025187, -17072479, 4333801,
-+             4378436, 2432030, 23097949, -566018},
-+            {4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264,
-+             10103221, -18512313, 2424778},
-+            {366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678,
-+             1344109, -3642553, 12412659},
-+        },
-+        {
-+            {-24001791, 7690286, 14929416, -168257, -32210835, -13412986,
-+             24162697, -15326504, -3141501, 11179385},
-+            {18289522, -14724954, 8056945, 16430056, -21729724, 7842514,
-+             -6001441, -1486897, -18684645, -11443503},
-+            {476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959,
-+             13403813, 11052904, 5219329},
-+        },
-+    },
-+    {
-+        {
-+            {20678546, -8375738, -32671898, 8849123, -5009758, 14574752,
-+             31186971, -3973730, 9014762, -8579056},
-+            {-13644050, -10350239, -15962508, 5075808, -1514661, -11534600,
-+             -33102500, 9160280, 8473550, -3256838},
-+            {24900749, 14435722, 17209120, -15292541, -22592275, 9878983,
-+             -7689309, -16335821, -24568481, 11788948},
-+        },
-+        {
-+            {-3118155, -11395194, -13802089, 14797441, 9652448, -6845904,
-+             -20037437, 10410733, -24568470, -1458691},
-+            {-15659161, 16736706, -22467150, 10215878, -9097177, 7563911,
-+             11871841, -12505194, -18513325, 8464118},
-+            {-23400612, 8348507, -14585951, -861714, -3950205, -6373419,
-+             14325289, 8628612, 33313881, -8370517},
-+        },
-+        {
-+            {-20186973, -4967935, 22367356, 5271547, -1097117, -4788838,
-+             -24805667, -10236854, -8940735, -5818269},
-+            {-6948785, -1795212, -32625683, -16021179, 32635414, -7374245,
-+             15989197, -12838188, 28358192, -4253904},
-+            {-23561781, -2799059, -32351682, -1661963, -9147719, 10429267,
-+             -16637684, 4072016, -5351664, 5596589},
-+        },
-+        {
-+            {-28236598, -3390048, 12312896, 6213178, 3117142, 16078565,
-+             29266239, 2557221, 1768301, 15373193},
-+            {-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902,
-+             -4504991, -24660491, 3442910},
-+            {-30210571, 5124043, 14181784, 8197961, 18964734, -11939093,
-+             22597931, 7176455, -18585478, 13365930},
-+        },
-+        {
-+            {-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107,
-+             -8570186, -9689599, -3031667},
-+            {25008904, -10771599, -4305031, -9638010, 16265036, 15721635,
-+             683793, -11823784, 15723479, -15163481},
-+            {-9660625, 12374379, -27006999, -7026148, -7724114, -12314514,
-+             11879682, 5400171, 519526, -1235876},
-+        },
-+        {
-+            {22258397, -16332233, -7869817, 14613016, -22520255, -2950923,
-+             -20353881, 7315967, 16648397, 7605640},
-+            {-8081308, -8464597, -8223311, 9719710, 19259459, -15348212,
-+             23994942, -5281555, -9468848, 4763278},
-+            {-21699244, 9220969, -15730624, 1084137, -25476107, -2852390,
-+             31088447, -7764523, -11356529, 728112},
-+        },
-+        {
-+            {26047220, -11751471, -6900323, -16521798, 24092068, 9158119,
-+             -4273545, -12555558, -29365436, -5498272},
-+            {17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007,
-+             12327945, 10750447, 10014012},
-+            {-10312768, 3936952, 9156313, -8897683, 16498692, -994647,
-+             -27481051, -666732, 3424691, 7540221},
-+        },
-+        {
-+            {30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422,
-+             -16317219, -9244265, 15258046},
-+            {13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406,
-+             2711395, 1062915, -5136345},
-+            {-19240248, -11254599, -29509029, -7499965, -5835763, 13005411,
-+             -6066489, 12194497, 32960380, 1459310},
-+        },
-+    },
-+    {
-+        {
-+            {19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197,
-+             -6101885, 18638003, -11174937},
-+            {31395534, 15098109, 26581030, 8030562, -16527914, -5007134,
-+             9012486, -7584354, -6643087, -5442636},
-+            {-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222,
-+             9677543, -32294889, -6456008},
-+        },
-+        {
-+            {-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579,
-+             -7839692, -7852844, -8138429},
-+            {-15236356, -15433509, 7766470, 746860, 26346930, -10221762,
-+             -27333451, 10754588, -9431476, 5203576},
-+            {31834314, 14135496, -770007, 5159118, 20917671, -16768096,
-+             -7467973, -7337524, 31809243, 7347066},
-+        },
-+        {
-+            {-9606723, -11874240, 20414459, 13033986, 13716524, -11691881,
-+             19797970, -12211255, 15192876, -2087490},
-+            {-12663563, -2181719, 1168162, -3804809, 26747877, -14138091,
-+             10609330, 12694420, 33473243, -13382104},
-+            {33184999, 11180355, 15832085, -11385430, -1633671, 225884,
-+             15089336, -11023903, -6135662, 14480053},
-+        },
-+        {
-+            {31308717, -5619998, 31030840, -1897099, 15674547, -6582883,
-+             5496208, 13685227, 27595050, 8737275},
-+            {-20318852, -15150239, 10933843, -16178022, 8335352, -7546022,
-+             -31008351, -12610604, 26498114, 66511},
-+            {22644454, -8761729, -16671776, 4884562, -3105614, -13559366,
-+             30540766, -4286747, -13327787, -7515095},
-+        },
-+        {
-+            {-28017847, 9834845, 18617207, -2681312, -3401956, -13307506,
-+             8205540, 13585437, -17127465, 15115439},
-+            {23711543, -672915, 31206561, -8362711, 6164647, -9709987,
-+             -33535882, -1426096, 8236921, 16492939},
-+            {-23910559, -13515526, -26299483, -4503841, 25005590, -7687270,
-+             19574902, 10071562, 6708380, -6222424},
-+        },
-+        {
-+            {2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017,
-+             9328700, 29955601, -11678310},
-+            {3096359, 9271816, -21620864, -15521844, -14847996, -7592937,
-+             -25892142, -12635595, -9917575, 6216608},
-+            {-32615849, 338663, -25195611, 2510422, -29213566, -13820213,
-+             24822830, -6146567, -26767480, 7525079},
-+        },
-+        {
-+            {-23066649, -13985623, 16133487, -7896178, -3389565, 778788,
-+             -910336, -2782495, -19386633, 11994101},
-+            {21691500, -13624626, -641331, -14367021, 3285881, -3483596,
-+             -25064666, 9718258, -7477437, 13381418},
-+            {18445390, -4202236, 14979846, 11622458, -1727110, -3582980,
-+             23111648, -6375247, 28535282, 15779576},
-+        },
-+        {
-+            {30098053, 3089662, -9234387, 16662135, -21306940, 11308411,
-+             -14068454, 12021730, 9955285, -16303356},
-+            {9734894, -14576830, -7473633, -9138735, 2060392, 11313496,
-+             -18426029, 9924399, 20194861, 13380996},
-+            {-26378102, -7965207, -22167821, 15789297, -18055342, -6168792,
-+             -1984914, 15707771, 26342023, 10146099},
-+        },
-+    },
-+    {
-+        {
-+            {-26016874, -219943, 21339191, -41388, 19745256, -2878700,
-+             -29637280, 2227040, 21612326, -545728},
-+            {-13077387, 1184228, 23562814, -5970442, -20351244, -6348714,
-+             25764461, 12243797, -20856566, 11649658},
-+            {-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944,
-+             6114064, 33514190, 2333242},
-+        },
-+        {
-+            {-21433588, -12421821, 8119782, 7219913, -21830522, -9016134,
-+             -6679750, -12670638, 24350578, -13450001},
-+            {-4116307, -11271533, -23886186, 4843615, -30088339, 690623,
-+             -31536088, -10406836, 8317860, 12352766},
-+            {18200138, -14475911, -33087759, -2696619, -23702521, -9102511,
-+             -23552096, -2287550, 20712163, 6719373},
-+        },
-+        {
-+            {26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530,
-+             -3763210, 26224235, -3297458},
-+            {-17168938, -14854097, -3395676, -16369877, -19954045, 14050420,
-+             21728352, 9493610, 18620611, -16428628},
-+            {-13323321, 13325349, 11432106, 5964811, 18609221, 6062965,
-+             -5269471, -9725556, -30701573, -16479657},
-+        },
-+        {
-+            {-23860538, -11233159, 26961357, 1640861, -32413112, -16737940,
-+             12248509, -5240639, 13735342, 1934062},
-+            {25089769, 6742589, 17081145, -13406266, 21909293, -16067981,
-+             -15136294, -3765346, -21277997, 5473616},
-+            {31883677, -7961101, 1083432, -11572403, 22828471, 13290673,
-+             -7125085, 12469656, 29111212, -5451014},
-+        },
-+        {
-+            {24244947, -15050407, -26262976, 2791540, -14997599, 16666678,
-+             24367466, 6388839, -10295587, 452383},
-+            {-25640782, -3417841, 5217916, 16224624, 19987036, -4082269,
-+             -24236251, -5915248, 15766062, 8407814},
-+            {-20406999, 13990231, 15495425, 16395525, 5377168, 15166495,
-+             -8917023, -4388953, -8067909, 2276718},
-+        },
-+        {
-+            {30157918, 12924066, -17712050, 9245753, 19895028, 3368142,
-+             -23827587, 5096219, 22740376, -7303417},
-+            {2041139, -14256350, 7783687, 13876377, -25946985, -13352459,
-+             24051124, 13742383, -15637599, 13295222},
-+            {33338237, -8505733, 12532113, 7977527, 9106186, -1715251,
-+             -17720195, -4612972, -4451357, -14669444},
-+        },
-+        {
-+            {-20045281, 5454097, -14346548, 6447146, 28862071, 1883651,
-+             -2469266, -4141880, 7770569, 9620597},
-+            {23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528,
-+             -1694323, -33502340, -14767970},
-+            {1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801,
-+             1220118, 30494170, -11440799},
-+        },
-+        {
-+            {-5037580, -13028295, -2970559, -3061767, 15640974, -6701666,
-+             -26739026, 926050, -1684339, -13333647},
-+            {13908495, -3549272, 30919928, -6273825, -21521863, 7989039,
-+             9021034, 9078865, 3353509, 4033511},
-+            {-29663431, -15113610, 32259991, -344482, 24295849, -12912123,
-+             23161163, 8839127, 27485041, 7356032},
-+        },
-+    },
-+    {
-+        {
-+            {9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142,
-+             2625015, 28431036, -16771834},
-+            {-23839233, -8311415, -25945511, 7480958, -17681669, -8354183,
-+             -22545972, 14150565, 15970762, 4099461},
-+            {29262576, 16756590, 26350592, -8793563, 8529671, -11208050,
-+             13617293, -9937143, 11465739, 8317062},
-+        },
-+        {
-+            {-25493081, -6962928, 32500200, -9419051, -23038724, -2302222,
-+             14898637, 3848455, 20969334, -5157516},
-+            {-20384450, -14347713, -18336405, 13884722, -33039454, 2842114,
-+             -21610826, -3649888, 11177095, 14989547},
-+            {-24496721, -11716016, 16959896, 2278463, 12066309, 10137771,
-+             13515641, 2581286, -28487508, 9930240},
-+        },
-+        {
-+            {-17751622, -2097826, 16544300, -13009300, -15914807, -14949081,
-+             18345767, -13403753, 16291481, -5314038},
-+            {-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774,
-+             6957617, 4368891, 9788741},
-+            {16660756, 7281060, -10830758, 12911820, 20108584, -8101676,
-+             -21722536, -8613148, 16250552, -11111103},
-+        },
-+        {
-+            {-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584,
-+             10604807, -30190403, 4782747},
-+            {-1354539, 14736941, -7367442, -13292886, 7710542, -14155590,
-+             -9981571, 4383045, 22546403, 437323},
-+            {31665577, -12180464, -16186830, 1491339, -18368625, 3294682,
-+             27343084, 2786261, -30633590, -14097016},
-+        },
-+        {
-+            {-14467279, -683715, -33374107, 7448552, 19294360, 14334329,
-+             -19690631, 2355319, -19284671, -6114373},
-+            {15121312, -15796162, 6377020, -6031361, -10798111, -12957845,
-+             18952177, 15496498, -29380133, 11754228},
-+            {-2637277, -13483075, 8488727, -14303896, 12728761, -1622493,
-+             7141596, 11724556, 22761615, -10134141},
-+        },
-+        {
-+            {16918416, 11729663, -18083579, 3022987, -31015732, -13339659,
-+             -28741185, -12227393, 32851222, 11717399},
-+            {11166634, 7338049, -6722523, 4531520, -29468672, -7302055,
-+             31474879, 3483633, -1193175, -4030831},
-+            {-185635, 9921305, 31456609, -13536438, -12013818, 13348923,
-+             33142652, 6546660, -19985279, -3948376},
-+        },
-+        {
-+            {-32460596, 11266712, -11197107, -7899103, 31703694, 3855903,
-+             -8537131, -12833048, -30772034, -15486313},
-+            {-18006477, 12709068, 3991746, -6479188, -21491523, -10550425,
-+             -31135347, -16049879, 10928917, 3011958},
-+            {-6957757, -15594337, 31696059, 334240, 29576716, 14796075,
-+             -30831056, -12805180, 18008031, 10258577},
-+        },
-+        {
-+            {-22448644, 15655569, 7018479, -4410003, -30314266, -1201591,
-+             -1853465, 1367120, 25127874, 6671743},
-+            {29701166, -14373934, -10878120, 9279288, -17568, 13127210,
-+             21382910, 11042292, 25838796, 4642684},
-+            {-20430234, 14955537, -24126347, 8124619, -5369288, -5990470,
-+             30468147, -13900640, 18423289, 4177476},
-+        },
-+    },
-+};
-+
-+static uint8_t negative(signed char b) {
-+  uint32_t x = b;
-+  x >>= 31; /* 1: yes; 0: no */
-+  return x;
-+}
-+
-+static void table_select(ge_precomp *t, int pos, signed char b) {
-+  ge_precomp minust;
-+  uint8_t bnegative = negative(b);
-+  uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1);
-+
-+  ge_precomp_0(t);
-+  cmov(t, &k25519Precomp[pos][0], equal(babs, 1));
-+  cmov(t, &k25519Precomp[pos][1], equal(babs, 2));
-+  cmov(t, &k25519Precomp[pos][2], equal(babs, 3));
-+  cmov(t, &k25519Precomp[pos][3], equal(babs, 4));
-+  cmov(t, &k25519Precomp[pos][4], equal(babs, 5));
-+  cmov(t, &k25519Precomp[pos][5], equal(babs, 6));
-+  cmov(t, &k25519Precomp[pos][6], equal(babs, 7));
-+  cmov(t, &k25519Precomp[pos][7], equal(babs, 8));
-+  fe_copy(minust.yplusx, t->yminusx);
-+  fe_copy(minust.yminusx, t->yplusx);
-+  fe_neg(minust.xy2d, t->xy2d);
-+  cmov(t, &minust, bnegative);
-+}
-+
-+/* h = a * B
-+ * where a = a[0]+256*a[1]+...+256^31 a[31]
-+ * B is the Ed25519 base point (x,4/5) with x positive.
-+ *
-+ * Preconditions:
-+ *   a[31] <= 127 */
-+static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
-+  signed char e[64];
-+  signed char carry;
-+  ge_p1p1 r;
-+  ge_p2 s;
-+  ge_precomp t;
-+  int i;
-+
-+  for (i = 0; i < 32; ++i) {
-+    e[2 * i + 0] = (a[i] >> 0) & 15;
-+    e[2 * i + 1] = (a[i] >> 4) & 15;
-+  }
-+  /* each e[i] is between 0 and 15 */
-+  /* e[63] is between 0 and 7 */
-+
-+  carry = 0;
-+  for (i = 0; i < 63; ++i) {
-+    e[i] += carry;
-+    carry = e[i] + 8;
-+    carry >>= 4;
-+    e[i] -= carry << 4;
-+  }
-+  e[63] += carry;
-+  /* each e[i] is between -8 and 8 */
-+
-+  ge_p3_0(h);
-+  for (i = 1; i < 64; i += 2) {
-+    table_select(&t, i / 2, e[i]);
-+    ge_madd(&r, h, &t);
-+    ge_p1p1_to_p3(h, &r);
-+  }
-+
-+  ge_p3_dbl(&r, h);
-+  ge_p1p1_to_p2(&s, &r);
-+  ge_p2_dbl(&r, &s);
-+  ge_p1p1_to_p2(&s, &r);
-+  ge_p2_dbl(&r, &s);
-+  ge_p1p1_to_p2(&s, &r);
-+  ge_p2_dbl(&r, &s);
-+  ge_p1p1_to_p3(h, &r);
-+
-+  for (i = 0; i < 64; i += 2) {
-+    table_select(&t, i / 2, e[i]);
-+    ge_madd(&r, h, &t);
-+    ge_p1p1_to_p3(h, &r);
-+  }
-+}
-+
-+/* Replace (f,g) with (g,f) if b == 1;
-+ * replace (f,g) with (f,g) if b == 0.
-+ *
-+ * Preconditions: b in {0,1}. */
-+static void fe_cswap(fe f, fe g, unsigned int b) {
-+  size_t i;
-+  b = 0-b;
-+  for (i = 0; i < 10; i++) {
-+    int32_t x = f[i] ^ g[i];
-+    x &= b;
-+    f[i] ^= x;
-+    g[i] ^= x;
-+  }
-+}
-+
-+/* h = f * 121666
-+ * Can overlap h with f.
-+ *
-+ * Preconditions:
-+ *    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
-+ *
-+ * Postconditions:
-+ *    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
-+static void fe_mul121666(fe h, fe f) {
-+  int32_t f0 = f[0];
-+  int32_t f1 = f[1];
-+  int32_t f2 = f[2];
-+  int32_t f3 = f[3];
-+  int32_t f4 = f[4];
-+  int32_t f5 = f[5];
-+  int32_t f6 = f[6];
-+  int32_t f7 = f[7];
-+  int32_t f8 = f[8];
-+  int32_t f9 = f[9];
-+  int64_t h0 = f0 * (int64_t) 121666;
-+  int64_t h1 = f1 * (int64_t) 121666;
-+  int64_t h2 = f2 * (int64_t) 121666;
-+  int64_t h3 = f3 * (int64_t) 121666;
-+  int64_t h4 = f4 * (int64_t) 121666;
-+  int64_t h5 = f5 * (int64_t) 121666;
-+  int64_t h6 = f6 * (int64_t) 121666;
-+  int64_t h7 = f7 * (int64_t) 121666;
-+  int64_t h8 = f8 * (int64_t) 121666;
-+  int64_t h9 = f9 * (int64_t) 121666;
-+  int64_t carry0;
-+  int64_t carry1;
-+  int64_t carry2;
-+  int64_t carry3;
-+  int64_t carry4;
-+  int64_t carry5;
-+  int64_t carry6;
-+  int64_t carry7;
-+  int64_t carry8;
-+  int64_t carry9;
-+
-+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
-+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
-+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
-+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
-+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
-+
-+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
-+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
-+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
-+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
-+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
-+
-+  h[0] = h0;
-+  h[1] = h1;
-+  h[2] = h2;
-+  h[3] = h3;
-+  h[4] = h4;
-+  h[5] = h5;
-+  h[6] = h6;
-+  h[7] = h7;
-+  h[8] = h8;
-+  h[9] = h9;
-+}
-+
-+static void x25519_scalar_mult_generic(uint8_t out[32],
-+                                       const uint8_t scalar[32],
-+                                       const uint8_t point[32]) {
-+  fe x1, x2, z2, x3, z3, tmp0, tmp1;
-+  uint8_t e[32];
-+  unsigned swap = 0;
-+  int pos;
-+
-+  memcpy(e, scalar, 32);
-+  e[0] &= 248;
-+  e[31] &= 127;
-+  e[31] |= 64;
-+  fe_frombytes(x1, point);
-+  fe_1(x2);
-+  fe_0(z2);
-+  fe_copy(x3, x1);
-+  fe_1(z3);
-+
-+  for (pos = 254; pos >= 0; --pos) {
-+    unsigned b = 1 & (e[pos / 8] >> (pos & 7));
-+    swap ^= b;
-+    fe_cswap(x2, x3, swap);
-+    fe_cswap(z2, z3, swap);
-+    swap = b;
-+    fe_sub(tmp0, x3, z3);
-+    fe_sub(tmp1, x2, z2);
-+    fe_add(x2, x2, z2);
-+    fe_add(z2, x3, z3);
-+    fe_mul(z3, tmp0, x2);
-+    fe_mul(z2, z2, tmp1);
-+    fe_sq(tmp0, tmp1);
-+    fe_sq(tmp1, x2);
-+    fe_add(x3, z3, z2);
-+    fe_sub(z2, z3, z2);
-+    fe_mul(x2, tmp1, tmp0);
-+    fe_sub(tmp1, tmp1, tmp0);
-+    fe_sq(z2, z2);
-+    fe_mul121666(z3, tmp1);
-+    fe_sq(x3, x3);
-+    fe_add(tmp0, tmp0, z3);
-+    fe_mul(z3, x1, z2);
-+    fe_mul(z2, tmp1, tmp0);
-+  }
-+  fe_cswap(x2, x3, swap);
-+  fe_cswap(z2, z3, swap);
-+
-+  fe_invert(z2, z2);
-+  fe_mul(x2, x2, z2);
-+  fe_tobytes(out, x2);
-+}
-+
-+static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
-+                               const uint8_t point[32]) {
-+  x25519_scalar_mult_generic(out, scalar, point);
-+}
-+
-+int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
-+           const uint8_t peer_public_value[32]) {
-+  static const uint8_t kZeros[32] = {0};
-+  x25519_scalar_mult(out_shared_key, private_key, peer_public_value);
-+  /* The all-zero output results when the input is a point of small order. */
-+  return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0;
-+}
-+
-+void X25519_public_from_private(uint8_t out_public_value[32],
-+                                const uint8_t private_key[32]) {
-+  uint8_t e[32];
-+  ge_p3 A;
-+  fe zplusy, zminusy, zminusy_inv;
-+
-+  memcpy(e, private_key, 32);
-+  e[0] &= 248;
-+  e[31] &= 127;
-+  e[31] |= 64;
-+
-+  ge_scalarmult_base(&A, e);
-+
-+  /* We only need the u-coordinate of the curve25519 point. The map is
-+   * u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */
-+  fe_add(zplusy, A.Z, A.Y);
-+  fe_sub(zminusy, A.Z, A.Y);
-+  fe_invert(zminusy_inv, zminusy);
-+  fe_mul(zplusy, zplusy, zminusy_inv);
-+  fe_tobytes(out_public_value, zplusy);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec2_mult.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec2_mult.c
-new file mode 100644
-index 0000000..e69de29
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec2_oct.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec2_oct.c
-new file mode 100644
-index 0000000..e69de29
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec2_smpl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec2_smpl.c
-new file mode 100644
-index 0000000..e69de29
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_ameth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_ameth.c
-new file mode 100644
-index 0000000..fa5bd03
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_ameth.c
-@@ -0,0 +1,881 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+#include "ec_lcl.h"
-+
-+#ifndef OPENSSL_NO_CMS
-+static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
-+static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
-+#endif
-+
-+static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
-+{
-+    const EC_GROUP *group;
-+    int nid;
-+    if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
-+        ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
-+        return 0;
-+    }
-+    if (EC_GROUP_get_asn1_flag(group)
-+        && (nid = EC_GROUP_get_curve_name(group)))
-+        /* we have a 'named curve' => just set the OID */
-+    {
-+        *ppval = OBJ_nid2obj(nid);
-+        *pptype = V_ASN1_OBJECT;
-+    } else {                    /* explicit parameters */
-+
-+        ASN1_STRING *pstr = NULL;
-+        pstr = ASN1_STRING_new();
-+        if (pstr == NULL)
-+            return 0;
-+        pstr->length = i2d_ECParameters(ec_key, &pstr->data);
-+        if (pstr->length <= 0) {
-+            ASN1_STRING_free(pstr);
-+            ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
-+            return 0;
-+        }
-+        *ppval = pstr;
-+        *pptype = V_ASN1_SEQUENCE;
-+    }
-+    return 1;
-+}
-+
-+static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
-+{
-+    EC_KEY *ec_key = pkey->pkey.ec;
-+    void *pval = NULL;
-+    int ptype;
-+    unsigned char *penc = NULL, *p;
-+    int penclen;
-+
-+    if (!eckey_param2type(&ptype, &pval, ec_key)) {
-+        ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
-+        return 0;
-+    }
-+    penclen = i2o_ECPublicKey(ec_key, NULL);
-+    if (penclen <= 0)
-+        goto err;
-+    penc = OPENSSL_malloc(penclen);
-+    if (penc == NULL)
-+        goto err;
-+    p = penc;
-+    penclen = i2o_ECPublicKey(ec_key, &p);
-+    if (penclen <= 0)
-+        goto err;
-+    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
-+                               ptype, pval, penc, penclen))
-+        return 1;
-+ err:
-+    if (ptype == V_ASN1_OBJECT)
-+        ASN1_OBJECT_free(pval);
-+    else
-+        ASN1_STRING_free(pval);
-+    OPENSSL_free(penc);
-+    return 0;
-+}
-+
-+static EC_KEY *eckey_type2param(int ptype, const void *pval)
-+{
-+    EC_KEY *eckey = NULL;
-+    if (ptype == V_ASN1_SEQUENCE) {
-+        const ASN1_STRING *pstr = pval;
-+        const unsigned char *pm = NULL;
-+        int pmlen;
-+        pm = pstr->data;
-+        pmlen = pstr->length;
-+        if ((eckey = d2i_ECParameters(NULL, &pm, pmlen)) == NULL) {
-+            ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
-+            goto ecerr;
-+        }
-+    } else if (ptype == V_ASN1_OBJECT) {
-+        const ASN1_OBJECT *poid = pval;
-+        EC_GROUP *group;
-+
-+        /*
-+         * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID
-+         */
-+        if ((eckey = EC_KEY_new()) == NULL) {
-+            ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
-+            goto ecerr;
-+        }
-+        group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
-+        if (group == NULL)
-+            goto ecerr;
-+        EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
-+        if (EC_KEY_set_group(eckey, group) == 0)
-+            goto ecerr;
-+        EC_GROUP_free(group);
-+    } else {
-+        ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
-+        goto ecerr;
-+    }
-+
-+    return eckey;
-+
-+ ecerr:
-+    EC_KEY_free(eckey);
-+    return NULL;
-+}
-+
-+static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
-+{
-+    const unsigned char *p = NULL;
-+    const void *pval;
-+    int ptype, pklen;
-+    EC_KEY *eckey = NULL;
-+    X509_ALGOR *palg;
-+
-+    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
-+        return 0;
-+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-+
-+    eckey = eckey_type2param(ptype, pval);
-+
-+    if (!eckey) {
-+        ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
-+        return 0;
-+    }
-+
-+    /* We have parameters now set public key */
-+    if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
-+        ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
-+        goto ecerr;
-+    }
-+
-+    EVP_PKEY_assign_EC_KEY(pkey, eckey);
-+    return 1;
-+
-+ ecerr:
-+    EC_KEY_free(eckey);
-+    return 0;
-+}
-+
-+static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    int r;
-+    const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
-+    const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
-+        *pb = EC_KEY_get0_public_key(b->pkey.ec);
-+    if (group == NULL || pa == NULL || pb == NULL)
-+        return -2;
-+    r = EC_POINT_cmp(group, pa, pb, NULL);
-+    if (r == 0)
-+        return 1;
-+    if (r == 1)
-+        return 0;
-+    return -2;
-+}
-+
-+static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
-+{
-+    const unsigned char *p = NULL;
-+    const void *pval;
-+    int ptype, pklen;
-+    EC_KEY *eckey = NULL;
-+    const X509_ALGOR *palg;
-+
-+    if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
-+        return 0;
-+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-+
-+    eckey = eckey_type2param(ptype, pval);
-+
-+    if (!eckey)
-+        goto ecliberr;
-+
-+    /* We have parameters now set private key */
-+    if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
-+        ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
-+        goto ecerr;
-+    }
-+
-+    EVP_PKEY_assign_EC_KEY(pkey, eckey);
-+    return 1;
-+
-+ ecliberr:
-+    ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
-+ ecerr:
-+    EC_KEY_free(eckey);
-+    return 0;
-+}
-+
-+static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
-+{
-+    EC_KEY ec_key = *(pkey->pkey.ec);
-+    unsigned char *ep, *p;
-+    int eplen, ptype;
-+    void *pval;
-+    unsigned int old_flags;
-+
-+    if (!eckey_param2type(&ptype, &pval, &ec_key)) {
-+        ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
-+        return 0;
-+    }
-+
-+    /* set the private key */
-+
-+    /*
-+     * do not include the parameters in the SEC1 private key see PKCS#11
-+     * 12.11
-+     */
-+    old_flags = EC_KEY_get_enc_flags(&ec_key);
-+    EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS);
-+
-+    eplen = i2d_ECPrivateKey(&ec_key, NULL);
-+    if (!eplen) {
-+        ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
-+        return 0;
-+    }
-+    ep = OPENSSL_malloc(eplen);
-+    if (ep == NULL) {
-+        ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    p = ep;
-+    if (!i2d_ECPrivateKey(&ec_key, &p)) {
-+        OPENSSL_free(ep);
-+        ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
-+        return 0;
-+    }
-+
-+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
-+                         ptype, pval, ep, eplen)) {
-+        OPENSSL_free(ep);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+static int int_ec_size(const EVP_PKEY *pkey)
-+{
-+    return ECDSA_size(pkey->pkey.ec);
-+}
-+
-+static int ec_bits(const EVP_PKEY *pkey)
-+{
-+    return EC_GROUP_order_bits(EC_KEY_get0_group(pkey->pkey.ec));
-+}
-+
-+static int ec_security_bits(const EVP_PKEY *pkey)
-+{
-+    int ecbits = ec_bits(pkey);
-+    if (ecbits >= 512)
-+        return 256;
-+    if (ecbits >= 384)
-+        return 192;
-+    if (ecbits >= 256)
-+        return 128;
-+    if (ecbits >= 224)
-+        return 112;
-+    if (ecbits >= 160)
-+        return 80;
-+    return ecbits / 2;
-+}
-+
-+static int ec_missing_parameters(const EVP_PKEY *pkey)
-+{
-+    if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL)
-+        return 1;
-+    return 0;
-+}
-+
-+static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
-+{
-+    EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
-+    if (group == NULL)
-+        return 0;
-+    if (to->pkey.ec == NULL) {
-+        to->pkey.ec = EC_KEY_new();
-+        if (to->pkey.ec == NULL)
-+            return 0;
-+    }
-+    if (EC_KEY_set_group(to->pkey.ec, group) == 0)
-+        return 0;
-+    EC_GROUP_free(group);
-+    return 1;
-+}
-+
-+static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
-+        *group_b = EC_KEY_get0_group(b->pkey.ec);
-+    if (group_a == NULL || group_b == NULL)
-+        return -2;
-+    if (EC_GROUP_cmp(group_a, group_b, NULL))
-+        return 0;
-+    else
-+        return 1;
-+}
-+
-+static void int_ec_free(EVP_PKEY *pkey)
-+{
-+    EC_KEY_free(pkey->pkey.ec);
-+}
-+
-+typedef enum {
-+    EC_KEY_PRINT_PRIVATE,
-+    EC_KEY_PRINT_PUBLIC,
-+    EC_KEY_PRINT_PARAM
-+} ec_print_t;
-+
-+static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
-+{
-+    const char *ecstr;
-+    unsigned char *priv = NULL, *pub = NULL;
-+    size_t privlen = 0, publen = 0;
-+    int ret = 0;
-+    const EC_GROUP *group;
-+
-+    if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
-+        ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+
-+    if (ktype != EC_KEY_PRINT_PARAM && EC_KEY_get0_public_key(x) != NULL) {
-+        publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL);
-+        if (publen == 0)
-+            goto err;
-+    }
-+
-+    if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) {
-+        privlen = EC_KEY_priv2buf(x, &priv);
-+        if (privlen == 0)
-+            goto err;
-+    }
-+
-+    if (ktype == EC_KEY_PRINT_PRIVATE)
-+        ecstr = "Private-Key";
-+    else if (ktype == EC_KEY_PRINT_PUBLIC)
-+        ecstr = "Public-Key";
-+    else
-+        ecstr = "ECDSA-Parameters";
-+
-+    if (!BIO_indent(bp, off, 128))
-+        goto err;
-+    if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
-+                   EC_GROUP_order_bits(group)) <= 0)
-+        goto err;
-+
-+    if (privlen != 0) {
-+        if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0)
-+            goto err;
-+        if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0)
-+            goto err;
-+    }
-+
-+    if (publen != 0) {
-+        if (BIO_printf(bp, "%*spub:\n", off, "") <= 0)
-+            goto err;
-+        if (ASN1_buf_print(bp, pub, publen, off + 4) == 0)
-+            goto err;
-+    }
-+
-+    if (!ECPKParameters_print(bp, group, off))
-+        goto err;
-+    ret = 1;
-+ err:
-+    if (!ret)
-+        ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB);
-+    OPENSSL_clear_free(priv, privlen);
-+    OPENSSL_free(pub);
-+    return ret;
-+}
-+
-+static int eckey_param_decode(EVP_PKEY *pkey,
-+                              const unsigned char **pder, int derlen)
-+{
-+    EC_KEY *eckey;
-+
-+    if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL) {
-+        ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
-+        return 0;
-+    }
-+    EVP_PKEY_assign_EC_KEY(pkey, eckey);
-+    return 1;
-+}
-+
-+static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
-+{
-+    return i2d_ECParameters(pkey->pkey.ec, pder);
-+}
-+
-+static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                             ASN1_PCTX *ctx)
-+{
-+    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PARAM);
-+}
-+
-+static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                           ASN1_PCTX *ctx)
-+{
-+    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PUBLIC);
-+}
-+
-+static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                            ASN1_PCTX *ctx)
-+{
-+    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PRIVATE);
-+}
-+
-+static int old_ec_priv_decode(EVP_PKEY *pkey,
-+                              const unsigned char **pder, int derlen)
-+{
-+    EC_KEY *ec;
-+
-+    if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) {
-+        ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
-+        return 0;
-+    }
-+    EVP_PKEY_assign_EC_KEY(pkey, ec);
-+    return 1;
-+}
-+
-+static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
-+{
-+    return i2d_ECPrivateKey(pkey->pkey.ec, pder);
-+}
-+
-+static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
-+{
-+    switch (op) {
-+    case ASN1_PKEY_CTRL_PKCS7_SIGN:
-+        if (arg1 == 0) {
-+            int snid, hnid;
-+            X509_ALGOR *alg1, *alg2;
-+            PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
-+            if (alg1 == NULL || alg1->algorithm == NULL)
-+                return -1;
-+            hnid = OBJ_obj2nid(alg1->algorithm);
-+            if (hnid == NID_undef)
-+                return -1;
-+            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
-+                return -1;
-+            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
-+        }
-+        return 1;
-+#ifndef OPENSSL_NO_CMS
-+    case ASN1_PKEY_CTRL_CMS_SIGN:
-+        if (arg1 == 0) {
-+            int snid, hnid;
-+            X509_ALGOR *alg1, *alg2;
-+            CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
-+            if (alg1 == NULL || alg1->algorithm == NULL)
-+                return -1;
-+            hnid = OBJ_obj2nid(alg1->algorithm);
-+            if (hnid == NID_undef)
-+                return -1;
-+            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
-+                return -1;
-+            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
-+        }
-+        return 1;
-+
-+    case ASN1_PKEY_CTRL_CMS_ENVELOPE:
-+        if (arg1 == 1)
-+            return ecdh_cms_decrypt(arg2);
-+        else if (arg1 == 0)
-+            return ecdh_cms_encrypt(arg2);
-+        return -2;
-+
-+    case ASN1_PKEY_CTRL_CMS_RI_TYPE:
-+        *(int *)arg2 = CMS_RECIPINFO_AGREE;
-+        return 1;
-+#endif
-+
-+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
-+        *(int *)arg2 = NID_sha256;
-+        return 2;
-+
-+    case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
-+        return EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(pkey), arg2, arg1, NULL);
-+
-+    case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
-+        return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey),
-+                              POINT_CONVERSION_UNCOMPRESSED, arg2, NULL);
-+
-+    default:
-+        return -2;
-+
-+    }
-+
-+}
-+
-+const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
-+    EVP_PKEY_EC,
-+    EVP_PKEY_EC,
-+    0,
-+    "EC",
-+    "OpenSSL EC algorithm",
-+
-+    eckey_pub_decode,
-+    eckey_pub_encode,
-+    eckey_pub_cmp,
-+    eckey_pub_print,
-+
-+    eckey_priv_decode,
-+    eckey_priv_encode,
-+    eckey_priv_print,
-+
-+    int_ec_size,
-+    ec_bits,
-+    ec_security_bits,
-+
-+    eckey_param_decode,
-+    eckey_param_encode,
-+    ec_missing_parameters,
-+    ec_copy_parameters,
-+    ec_cmp_parameters,
-+    eckey_param_print,
-+    0,
-+
-+    int_ec_free,
-+    ec_pkey_ctrl,
-+    old_ec_priv_decode,
-+    old_ec_priv_encode
-+};
-+
-+int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
-+{
-+    int private = EC_KEY_get0_private_key(x) != NULL;
-+
-+    return do_EC_KEY_print(bp, x, off,
-+                private ? EC_KEY_PRINT_PRIVATE : EC_KEY_PRINT_PUBLIC);
-+}
-+
-+int ECParameters_print(BIO *bp, const EC_KEY *x)
-+{
-+    return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM);
-+}
-+
-+#ifndef OPENSSL_NO_CMS
-+
-+static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
-+                                X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
-+{
-+    const ASN1_OBJECT *aoid;
-+    int atype;
-+    const void *aval;
-+    int rv = 0;
-+    EVP_PKEY *pkpeer = NULL;
-+    EC_KEY *ecpeer = NULL;
-+    const unsigned char *p;
-+    int plen;
-+    X509_ALGOR_get0(&aoid, &atype, &aval, alg);
-+    if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
-+        goto err;
-+    /* If absent parameters get group from main key */
-+    if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
-+        const EC_GROUP *grp;
-+        EVP_PKEY *pk;
-+        pk = EVP_PKEY_CTX_get0_pkey(pctx);
-+        if (!pk)
-+            goto err;
-+        grp = EC_KEY_get0_group(pk->pkey.ec);
-+        ecpeer = EC_KEY_new();
-+        if (ecpeer == NULL)
-+            goto err;
-+        if (!EC_KEY_set_group(ecpeer, grp))
-+            goto err;
-+    } else {
-+        ecpeer = eckey_type2param(atype, aval);
-+        if (!ecpeer)
-+            goto err;
-+    }
-+    /* We have parameters now set public key */
-+    plen = ASN1_STRING_length(pubkey);
-+    p = ASN1_STRING_get0_data(pubkey);
-+    if (!p || !plen)
-+        goto err;
-+    if (!o2i_ECPublicKey(&ecpeer, &p, plen))
-+        goto err;
-+    pkpeer = EVP_PKEY_new();
-+    if (pkpeer == NULL)
-+        goto err;
-+    EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
-+    if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
-+        rv = 1;
-+ err:
-+    EC_KEY_free(ecpeer);
-+    EVP_PKEY_free(pkpeer);
-+    return rv;
-+}
-+
-+/* Set KDF parameters based on KDF NID */
-+static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
-+{
-+    int kdf_nid, kdfmd_nid, cofactor;
-+    const EVP_MD *kdf_md;
-+    if (eckdf_nid == NID_undef)
-+        return 0;
-+
-+    /* Lookup KDF type, cofactor mode and digest */
-+    if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
-+        return 0;
-+
-+    if (kdf_nid == NID_dh_std_kdf)
-+        cofactor = 0;
-+    else if (kdf_nid == NID_dh_cofactor_kdf)
-+        cofactor = 1;
-+    else
-+        return 0;
-+
-+    if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
-+        return 0;
-+
-+    if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0)
-+        return 0;
-+
-+    kdf_md = EVP_get_digestbynid(kdfmd_nid);
-+    if (!kdf_md)
-+        return 0;
-+
-+    if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
-+        return 0;
-+    return 1;
-+}
-+
-+static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
-+{
-+    int rv = 0;
-+
-+    X509_ALGOR *alg, *kekalg = NULL;
-+    ASN1_OCTET_STRING *ukm;
-+    const unsigned char *p;
-+    unsigned char *der = NULL;
-+    int plen, keylen;
-+    const EVP_CIPHER *kekcipher;
-+    EVP_CIPHER_CTX *kekctx;
-+
-+    if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
-+        return 0;
-+
-+    if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
-+        ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR);
-+        return 0;
-+    }
-+
-+    if (alg->parameter->type != V_ASN1_SEQUENCE)
-+        return 0;
-+
-+    p = alg->parameter->value.sequence->data;
-+    plen = alg->parameter->value.sequence->length;
-+    kekalg = d2i_X509_ALGOR(NULL, &p, plen);
-+    if (!kekalg)
-+        goto err;
-+    kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
-+    if (!kekctx)
-+        goto err;
-+    kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
-+    if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
-+        goto err;
-+    if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
-+        goto err;
-+    if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
-+        goto err;
-+
-+    keylen = EVP_CIPHER_CTX_key_length(kekctx);
-+    if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
-+        goto err;
-+
-+    plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
-+
-+    if (!plen)
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
-+        goto err;
-+    der = NULL;
-+
-+    rv = 1;
-+ err:
-+    X509_ALGOR_free(kekalg);
-+    OPENSSL_free(der);
-+    return rv;
-+}
-+
-+static int ecdh_cms_decrypt(CMS_RecipientInfo *ri)
-+{
-+    EVP_PKEY_CTX *pctx;
-+    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
-+    if (!pctx)
-+        return 0;
-+    /* See if we need to set peer key */
-+    if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
-+        X509_ALGOR *alg;
-+        ASN1_BIT_STRING *pubkey;
-+        if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
-+                                                 NULL, NULL, NULL))
-+            return 0;
-+        if (!alg || !pubkey)
-+            return 0;
-+        if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
-+            ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR);
-+            return 0;
-+        }
-+    }
-+    /* Set ECDH derivation parameters and initialise unwrap context */
-+    if (!ecdh_cms_set_shared_info(pctx, ri)) {
-+        ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
-+{
-+    EVP_PKEY_CTX *pctx;
-+    EVP_PKEY *pkey;
-+    EVP_CIPHER_CTX *ctx;
-+    int keylen;
-+    X509_ALGOR *talg, *wrap_alg = NULL;
-+    const ASN1_OBJECT *aoid;
-+    ASN1_BIT_STRING *pubkey;
-+    ASN1_STRING *wrap_str;
-+    ASN1_OCTET_STRING *ukm;
-+    unsigned char *penc = NULL;
-+    int penclen;
-+    int rv = 0;
-+    int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
-+    const EVP_MD *kdf_md;
-+    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
-+    if (!pctx)
-+        return 0;
-+    /* Get ephemeral key */
-+    pkey = EVP_PKEY_CTX_get0_pkey(pctx);
-+    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
-+                                             NULL, NULL, NULL))
-+        goto err;
-+    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
-+    /* Is everything uninitialised? */
-+    if (aoid == OBJ_nid2obj(NID_undef)) {
-+
-+        EC_KEY *eckey = pkey->pkey.ec;
-+        /* Set the key */
-+        unsigned char *p;
-+
-+        penclen = i2o_ECPublicKey(eckey, NULL);
-+        if (penclen <= 0)
-+            goto err;
-+        penc = OPENSSL_malloc(penclen);
-+        if (penc == NULL)
-+            goto err;
-+        p = penc;
-+        penclen = i2o_ECPublicKey(eckey, &p);
-+        if (penclen <= 0)
-+            goto err;
-+        ASN1_STRING_set0(pubkey, penc, penclen);
-+        pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-+        pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-+
-+        penc = NULL;
-+        X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
-+                        V_ASN1_UNDEF, NULL);
-+    }
-+
-+    /* See if custom parameters set */
-+    kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
-+    if (kdf_type <= 0)
-+        goto err;
-+    if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
-+        goto err;
-+    ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
-+    if (ecdh_nid < 0)
-+        goto err;
-+    else if (ecdh_nid == 0)
-+        ecdh_nid = NID_dh_std_kdf;
-+    else if (ecdh_nid == 1)
-+        ecdh_nid = NID_dh_cofactor_kdf;
-+
-+    if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
-+        kdf_type = EVP_PKEY_ECDH_KDF_X9_62;
-+        if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
-+            goto err;
-+    } else
-+        /* Unknown KDF */
-+        goto err;
-+    if (kdf_md == NULL) {
-+        /* Fixme later for better MD */
-+        kdf_md = EVP_sha1();
-+        if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
-+            goto err;
-+    }
-+
-+    if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
-+        goto err;
-+
-+    /* Lookup NID for KDF+cofactor+digest */
-+
-+    if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
-+        goto err;
-+    /* Get wrap NID */
-+    ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
-+    wrap_nid = EVP_CIPHER_CTX_type(ctx);
-+    keylen = EVP_CIPHER_CTX_key_length(ctx);
-+
-+    /* Package wrap algorithm in an AlgorithmIdentifier */
-+
-+    wrap_alg = X509_ALGOR_new();
-+    if (wrap_alg == NULL)
-+        goto err;
-+    wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
-+    wrap_alg->parameter = ASN1_TYPE_new();
-+    if (wrap_alg->parameter == NULL)
-+        goto err;
-+    if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
-+        goto err;
-+    if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
-+        ASN1_TYPE_free(wrap_alg->parameter);
-+        wrap_alg->parameter = NULL;
-+    }
-+
-+    if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
-+        goto err;
-+
-+    penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
-+
-+    if (!penclen)
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
-+        goto err;
-+    penc = NULL;
-+
-+    /*
-+     * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
-+     * of another AlgorithmIdentifier.
-+     */
-+    penclen = i2d_X509_ALGOR(wrap_alg, &penc);
-+    if (!penc || !penclen)
-+        goto err;
-+    wrap_str = ASN1_STRING_new();
-+    if (wrap_str == NULL)
-+        goto err;
-+    ASN1_STRING_set0(wrap_str, penc, penclen);
-+    penc = NULL;
-+    X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
-+
-+    rv = 1;
-+
-+ err:
-+    OPENSSL_free(penc);
-+    X509_ALGOR_free(wrap_alg);
-+    return rv;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_asn1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_asn1.c
-new file mode 100644
-index 0000000..4f4d1ed
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_asn1.c
-@@ -0,0 +1,1234 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "ec_lcl.h"
-+#include 
-+#include 
-+#include 
-+
-+int EC_GROUP_get_basis_type(const EC_GROUP *group)
-+{
-+    int i = 0;
-+
-+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
-+        NID_X9_62_characteristic_two_field)
-+        /* everything else is currently not supported */
-+        return 0;
-+
-+    while (group->poly[i] != 0)
-+        i++;
-+
-+    if (i == 4)
-+        return NID_X9_62_ppBasis;
-+    else if (i == 2)
-+        return NID_X9_62_tpBasis;
-+    else
-+        /* everything else is currently not supported */
-+        return 0;
-+}
-+
-+#ifndef OPENSSL_NO_EC2M
-+int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
-+{
-+    if (group == NULL)
-+        return 0;
-+
-+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
-+        NID_X9_62_characteristic_two_field
-+        || !((group->poly[0] != 0) && (group->poly[1] != 0)
-+             && (group->poly[2] == 0))) {
-+        ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+
-+    if (k)
-+        *k = group->poly[1];
-+
-+    return 1;
-+}
-+
-+int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
-+                                   unsigned int *k2, unsigned int *k3)
-+{
-+    if (group == NULL)
-+        return 0;
-+
-+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
-+        NID_X9_62_characteristic_two_field
-+        || !((group->poly[0] != 0) && (group->poly[1] != 0)
-+             && (group->poly[2] != 0) && (group->poly[3] != 0)
-+             && (group->poly[4] == 0))) {
-+        ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+
-+    if (k1)
-+        *k1 = group->poly[3];
-+    if (k2)
-+        *k2 = group->poly[2];
-+    if (k3)
-+        *k3 = group->poly[1];
-+
-+    return 1;
-+}
-+#endif
-+
-+/* some structures needed for the asn1 encoding */
-+typedef struct x9_62_pentanomial_st {
-+    long k1;
-+    long k2;
-+    long k3;
-+} X9_62_PENTANOMIAL;
-+
-+typedef struct x9_62_characteristic_two_st {
-+    long m;
-+    ASN1_OBJECT *type;
-+    union {
-+        char *ptr;
-+        /* NID_X9_62_onBasis */
-+        ASN1_NULL *onBasis;
-+        /* NID_X9_62_tpBasis */
-+        ASN1_INTEGER *tpBasis;
-+        /* NID_X9_62_ppBasis */
-+        X9_62_PENTANOMIAL *ppBasis;
-+        /* anything else */
-+        ASN1_TYPE *other;
-+    } p;
-+} X9_62_CHARACTERISTIC_TWO;
-+
-+typedef struct x9_62_fieldid_st {
-+    ASN1_OBJECT *fieldType;
-+    union {
-+        char *ptr;
-+        /* NID_X9_62_prime_field */
-+        ASN1_INTEGER *prime;
-+        /* NID_X9_62_characteristic_two_field */
-+        X9_62_CHARACTERISTIC_TWO *char_two;
-+        /* anything else */
-+        ASN1_TYPE *other;
-+    } p;
-+} X9_62_FIELDID;
-+
-+typedef struct x9_62_curve_st {
-+    ASN1_OCTET_STRING *a;
-+    ASN1_OCTET_STRING *b;
-+    ASN1_BIT_STRING *seed;
-+} X9_62_CURVE;
-+
-+struct ec_parameters_st {
-+    long version;
-+    X9_62_FIELDID *fieldID;
-+    X9_62_CURVE *curve;
-+    ASN1_OCTET_STRING *base;
-+    ASN1_INTEGER *order;
-+    ASN1_INTEGER *cofactor;
-+} /* ECPARAMETERS */ ;
-+
-+struct ecpk_parameters_st {
-+    int type;
-+    union {
-+        ASN1_OBJECT *named_curve;
-+        ECPARAMETERS *parameters;
-+        ASN1_NULL *implicitlyCA;
-+    } value;
-+} /* ECPKPARAMETERS */ ;
-+
-+/* SEC1 ECPrivateKey */
-+typedef struct ec_privatekey_st {
-+    long version;
-+    ASN1_OCTET_STRING *privateKey;
-+    ECPKPARAMETERS *parameters;
-+    ASN1_BIT_STRING *publicKey;
-+} EC_PRIVATEKEY;
-+
-+/* the OpenSSL ASN.1 definitions */
-+ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
-+        ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
-+        ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
-+        ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
-+} static_ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
-+
-+DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
-+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
-+
-+ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
-+
-+ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
-+        ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
-+        ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
-+        ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
-+} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
-+
-+ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
-+        ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
-+        ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
-+        ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
-+} static_ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
-+
-+DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
-+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
-+
-+ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
-+
-+ASN1_ADB(X9_62_FIELDID) = {
-+        ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
-+        ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
-+} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
-+
-+ASN1_SEQUENCE(X9_62_FIELDID) = {
-+        ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
-+        ASN1_ADB_OBJECT(X9_62_FIELDID)
-+} static_ASN1_SEQUENCE_END(X9_62_FIELDID)
-+
-+ASN1_SEQUENCE(X9_62_CURVE) = {
-+        ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
-+        ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
-+        ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
-+} static_ASN1_SEQUENCE_END(X9_62_CURVE)
-+
-+ASN1_SEQUENCE(ECPARAMETERS) = {
-+        ASN1_SIMPLE(ECPARAMETERS, version, LONG),
-+        ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
-+        ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
-+        ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
-+        ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
-+        ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
-+} ASN1_SEQUENCE_END(ECPARAMETERS)
-+
-+DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
-+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
-+
-+ASN1_CHOICE(ECPKPARAMETERS) = {
-+        ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
-+        ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
-+        ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
-+} ASN1_CHOICE_END(ECPKPARAMETERS)
-+
-+DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
-+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
-+IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
-+
-+ASN1_SEQUENCE(EC_PRIVATEKEY) = {
-+        ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
-+        ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
-+        ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
-+        ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
-+} static_ASN1_SEQUENCE_END(EC_PRIVATEKEY)
-+
-+DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
-+DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
-+IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
-+
-+/* some declarations of internal function */
-+
-+/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
-+static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
-+/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
-+static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
-+
-+/* the function definitions */
-+
-+static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
-+{
-+    int ok = 0, nid;
-+    BIGNUM *tmp = NULL;
-+
-+    if (group == NULL || field == NULL)
-+        return 0;
-+
-+    /* clear the old values (if necessary) */
-+    ASN1_OBJECT_free(field->fieldType);
-+    ASN1_TYPE_free(field->p.other);
-+
-+    nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
-+    /* set OID for the field */
-+    if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
-+        ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
-+        goto err;
-+    }
-+
-+    if (nid == NID_X9_62_prime_field) {
-+        if ((tmp = BN_new()) == NULL) {
-+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        /* the parameters are specified by the prime number p */
-+        if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) {
-+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+        /* set the prime number */
-+        field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL);
-+        if (field->p.prime == NULL) {
-+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
-+            goto err;
-+        }
-+    } else if (nid == NID_X9_62_characteristic_two_field)
-+#ifdef OPENSSL_NO_EC2M
-+    {
-+        ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
-+        goto err;
-+    }
-+#else
-+    {
-+        int field_type;
-+        X9_62_CHARACTERISTIC_TWO *char_two;
-+
-+        field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
-+        char_two = field->p.char_two;
-+
-+        if (char_two == NULL) {
-+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+
-+        char_two->m = (long)EC_GROUP_get_degree(group);
-+
-+        field_type = EC_GROUP_get_basis_type(group);
-+
-+        if (field_type == 0) {
-+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+        /* set base type OID */
-+        if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) {
-+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
-+            goto err;
-+        }
-+
-+        if (field_type == NID_X9_62_tpBasis) {
-+            unsigned int k;
-+
-+            if (!EC_GROUP_get_trinomial_basis(group, &k))
-+                goto err;
-+
-+            char_two->p.tpBasis = ASN1_INTEGER_new();
-+            if (char_two->p.tpBasis == NULL) {
-+                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) {
-+                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
-+                goto err;
-+            }
-+        } else if (field_type == NID_X9_62_ppBasis) {
-+            unsigned int k1, k2, k3;
-+
-+            if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
-+                goto err;
-+
-+            char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
-+            if (char_two->p.ppBasis == NULL) {
-+                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+
-+            /* set k? values */
-+            char_two->p.ppBasis->k1 = (long)k1;
-+            char_two->p.ppBasis->k2 = (long)k2;
-+            char_two->p.ppBasis->k3 = (long)k3;
-+        } else {                /* field_type == NID_X9_62_onBasis */
-+
-+            /* for ONB the parameters are (asn1) NULL */
-+            char_two->p.onBasis = ASN1_NULL_new();
-+            if (char_two->p.onBasis == NULL) {
-+                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+        }
-+    }
-+#endif
-+    else {
-+        ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_UNSUPPORTED_FIELD);
-+        goto err;
-+    }
-+
-+    ok = 1;
-+
-+ err:
-+    BN_free(tmp);
-+    return (ok);
-+}
-+
-+static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
-+{
-+    int ok = 0, nid;
-+    BIGNUM *tmp_1 = NULL, *tmp_2 = NULL;
-+    unsigned char *buffer_1 = NULL, *buffer_2 = NULL,
-+        *a_buf = NULL, *b_buf = NULL;
-+    size_t len_1, len_2;
-+    unsigned char char_zero = 0;
-+
-+    if (!group || !curve || !curve->a || !curve->b)
-+        return 0;
-+
-+    if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) {
-+        ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
-+
-+    /* get a and b */
-+    if (nid == NID_X9_62_prime_field) {
-+        if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) {
-+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+    }
-+#ifndef OPENSSL_NO_EC2M
-+    else {                      /* nid == NID_X9_62_characteristic_two_field */
-+
-+        if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) {
-+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+    }
-+#endif
-+    len_1 = (size_t)BN_num_bytes(tmp_1);
-+    len_2 = (size_t)BN_num_bytes(tmp_2);
-+
-+    if (len_1 == 0) {
-+        /* len_1 == 0 => a == 0 */
-+        a_buf = &char_zero;
-+        len_1 = 1;
-+    } else {
-+        if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) {
-+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) {
-+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+        a_buf = buffer_1;
-+    }
-+
-+    if (len_2 == 0) {
-+        /* len_2 == 0 => b == 0 */
-+        b_buf = &char_zero;
-+        len_2 = 1;
-+    } else {
-+        if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) {
-+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) {
-+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+        b_buf = buffer_2;
-+    }
-+
-+    /* set a and b */
-+    if (!ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
-+        !ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) {
-+        ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
-+        goto err;
-+    }
-+
-+    /* set the seed (optional) */
-+    if (group->seed) {
-+        if (!curve->seed)
-+            if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
-+                ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+        curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-+        curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-+        if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
-+                                 (int)group->seed_len)) {
-+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
-+            goto err;
-+        }
-+    } else {
-+        ASN1_BIT_STRING_free(curve->seed);
-+        curve->seed = NULL;
-+    }
-+
-+    ok = 1;
-+
-+ err:
-+    OPENSSL_free(buffer_1);
-+    OPENSSL_free(buffer_2);
-+    BN_free(tmp_1);
-+    BN_free(tmp_2);
-+    return (ok);
-+}
-+
-+ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
-+                                               ECPARAMETERS *params)
-+{
-+    size_t len = 0;
-+    ECPARAMETERS *ret = NULL;
-+    const BIGNUM *tmp;
-+    unsigned char *buffer = NULL;
-+    const EC_POINT *point = NULL;
-+    point_conversion_form_t form;
-+
-+    if (params == NULL) {
-+        if ((ret = ECPARAMETERS_new()) == NULL) {
-+            ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    } else
-+        ret = params;
-+
-+    /* set the version (always one) */
-+    ret->version = (long)0x1;
-+
-+    /* set the fieldID */
-+    if (!ec_asn1_group2fieldid(group, ret->fieldID)) {
-+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+
-+    /* set the curve */
-+    if (!ec_asn1_group2curve(group, ret->curve)) {
-+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+
-+    /* set the base point */
-+    if ((point = EC_GROUP_get0_generator(group)) == NULL) {
-+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, EC_R_UNDEFINED_GENERATOR);
-+        goto err;
-+    }
-+
-+    form = EC_GROUP_get_point_conversion_form(group);
-+
-+    len = EC_POINT_point2buf(group, point, form, &buffer, NULL);
-+    if (len == 0) {
-+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+    if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) {
-+        OPENSSL_free(buffer);
-+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    ASN1_STRING_set0(ret->base, buffer, len);
-+
-+    /* set the order */
-+    tmp = EC_GROUP_get0_order(group);
-+    if (tmp == NULL) {
-+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+    ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
-+    if (ret->order == NULL) {
-+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB);
-+        goto err;
-+    }
-+
-+    /* set the cofactor (optional) */
-+    tmp = EC_GROUP_get0_cofactor(group);
-+    if (tmp != NULL) {
-+        ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
-+        if (ret->cofactor == NULL) {
-+            ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB);
-+            goto err;
-+        }
-+    }
-+
-+    return ret;
-+
-+ err:
-+    if (params == NULL)
-+        ECPARAMETERS_free(ret);
-+    return NULL;
-+}
-+
-+ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
-+                                            ECPKPARAMETERS *params)
-+{
-+    int ok = 1, tmp;
-+    ECPKPARAMETERS *ret = params;
-+
-+    if (ret == NULL) {
-+        if ((ret = ECPKPARAMETERS_new()) == NULL) {
-+            ECerr(EC_F_EC_GROUP_GET_ECPKPARAMETERS, ERR_R_MALLOC_FAILURE);
-+            return NULL;
-+        }
-+    } else {
-+        if (ret->type == 0)
-+            ASN1_OBJECT_free(ret->value.named_curve);
-+        else if (ret->type == 1 && ret->value.parameters)
-+            ECPARAMETERS_free(ret->value.parameters);
-+    }
-+
-+    if (EC_GROUP_get_asn1_flag(group)) {
-+        /*
-+         * use the asn1 OID to describe the the elliptic curve parameters
-+         */
-+        tmp = EC_GROUP_get_curve_name(group);
-+        if (tmp) {
-+            ret->type = 0;
-+            if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
-+                ok = 0;
-+        } else
-+            /* we don't know the nid => ERROR */
-+            ok = 0;
-+    } else {
-+        /* use the ECPARAMETERS structure */
-+        ret->type = 1;
-+        if ((ret->value.parameters =
-+             EC_GROUP_get_ecparameters(group, NULL)) == NULL)
-+            ok = 0;
-+    }
-+
-+    if (!ok) {
-+        ECPKPARAMETERS_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
-+{
-+    int ok = 0, tmp;
-+    EC_GROUP *ret = NULL;
-+    BIGNUM *p = NULL, *a = NULL, *b = NULL;
-+    EC_POINT *point = NULL;
-+    long field_bits;
-+
-+    if (!params->fieldID || !params->fieldID->fieldType ||
-+        !params->fieldID->p.ptr) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
-+        goto err;
-+    }
-+
-+    /* now extract the curve parameters a and b */
-+    if (!params->curve || !params->curve->a ||
-+        !params->curve->a->data || !params->curve->b ||
-+        !params->curve->b->data) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
-+        goto err;
-+    }
-+    a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
-+    if (a == NULL) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
-+    if (b == NULL) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+
-+    /* get the field parameters */
-+    tmp = OBJ_obj2nid(params->fieldID->fieldType);
-+    if (tmp == NID_X9_62_characteristic_two_field)
-+#ifdef OPENSSL_NO_EC2M
-+    {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_GF2M_NOT_SUPPORTED);
-+        goto err;
-+    }
-+#else
-+    {
-+        X9_62_CHARACTERISTIC_TWO *char_two;
-+
-+        char_two = params->fieldID->p.char_two;
-+
-+        field_bits = char_two->m;
-+        if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_FIELD_TOO_LARGE);
-+            goto err;
-+        }
-+
-+        if ((p = BN_new()) == NULL) {
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+
-+        /* get the base type */
-+        tmp = OBJ_obj2nid(char_two->type);
-+
-+        if (tmp == NID_X9_62_tpBasis) {
-+            long tmp_long;
-+
-+            if (!char_two->p.tpBasis) {
-+                ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
-+                goto err;
-+            }
-+
-+            tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
-+
-+            if (!(char_two->m > tmp_long && tmp_long > 0)) {
-+                ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS,
-+                      EC_R_INVALID_TRINOMIAL_BASIS);
-+                goto err;
-+            }
-+
-+            /* create the polynomial */
-+            if (!BN_set_bit(p, (int)char_two->m))
-+                goto err;
-+            if (!BN_set_bit(p, (int)tmp_long))
-+                goto err;
-+            if (!BN_set_bit(p, 0))
-+                goto err;
-+        } else if (tmp == NID_X9_62_ppBasis) {
-+            X9_62_PENTANOMIAL *penta;
-+
-+            penta = char_two->p.ppBasis;
-+            if (!penta) {
-+                ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
-+                goto err;
-+            }
-+
-+            if (!
-+                (char_two->m > penta->k3 && penta->k3 > penta->k2
-+                 && penta->k2 > penta->k1 && penta->k1 > 0)) {
-+                ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS,
-+                      EC_R_INVALID_PENTANOMIAL_BASIS);
-+                goto err;
-+            }
-+
-+            /* create the polynomial */
-+            if (!BN_set_bit(p, (int)char_two->m))
-+                goto err;
-+            if (!BN_set_bit(p, (int)penta->k1))
-+                goto err;
-+            if (!BN_set_bit(p, (int)penta->k2))
-+                goto err;
-+            if (!BN_set_bit(p, (int)penta->k3))
-+                goto err;
-+            if (!BN_set_bit(p, 0))
-+                goto err;
-+        } else if (tmp == NID_X9_62_onBasis) {
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_NOT_IMPLEMENTED);
-+            goto err;
-+        } else {                /* error */
-+
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
-+            goto err;
-+        }
-+
-+        /* create the EC_GROUP structure */
-+        ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
-+    }
-+#endif
-+    else if (tmp == NID_X9_62_prime_field) {
-+        /* we have a curve over a prime field */
-+        /* extract the prime number */
-+        if (!params->fieldID->p.prime) {
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
-+            goto err;
-+        }
-+        p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
-+        if (p == NULL) {
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
-+            goto err;
-+        }
-+
-+        if (BN_is_negative(p) || BN_is_zero(p)) {
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_FIELD);
-+            goto err;
-+        }
-+
-+        field_bits = BN_num_bits(p);
-+        if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_FIELD_TOO_LARGE);
-+            goto err;
-+        }
-+
-+        /* create the EC_GROUP structure */
-+        ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
-+    } else {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_FIELD);
-+        goto err;
-+    }
-+
-+    if (ret == NULL) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+
-+    /* extract seed (optional) */
-+    if (params->curve->seed != NULL) {
-+        OPENSSL_free(ret->seed);
-+        if ((ret->seed = OPENSSL_malloc(params->curve->seed->length)) == NULL) {
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        memcpy(ret->seed, params->curve->seed->data,
-+               params->curve->seed->length);
-+        ret->seed_len = params->curve->seed->length;
-+    }
-+
-+    if (!params->order || !params->base || !params->base->data) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
-+        goto err;
-+    }
-+
-+    if ((point = EC_POINT_new(ret)) == NULL)
-+        goto err;
-+
-+    /* set the point conversion form */
-+    EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
-+                                       (params->base->data[0] & ~0x01));
-+
-+    /* extract the ec point */
-+    if (!EC_POINT_oct2point(ret, point, params->base->data,
-+                            params->base->length, NULL)) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+
-+    /* extract the order */
-+    if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
-+        goto err;
-+    }
-+    if (BN_is_negative(a) || BN_is_zero(a)) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_GROUP_ORDER);
-+        goto err;
-+    }
-+    if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_GROUP_ORDER);
-+        goto err;
-+    }
-+
-+    /* extract the cofactor (optional) */
-+    if (params->cofactor == NULL) {
-+        BN_free(b);
-+        b = NULL;
-+    } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
-+        goto err;
-+    }
-+    /* set the generator, order and cofactor (if present) */
-+    if (!EC_GROUP_set_generator(ret, point, a, b)) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+
-+    ok = 1;
-+
-+ err:
-+    if (!ok) {
-+        EC_GROUP_clear_free(ret);
-+        ret = NULL;
-+    }
-+
-+    BN_free(p);
-+    BN_free(a);
-+    BN_free(b);
-+    EC_POINT_free(point);
-+    return (ret);
-+}
-+
-+EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
-+{
-+    EC_GROUP *ret = NULL;
-+    int tmp = 0;
-+
-+    if (params == NULL) {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_MISSING_PARAMETERS);
-+        return NULL;
-+    }
-+
-+    if (params->type == 0) {    /* the curve is given by an OID */
-+        tmp = OBJ_obj2nid(params->value.named_curve);
-+        if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS,
-+                  EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
-+            return NULL;
-+        }
-+        EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
-+    } else if (params->type == 1) { /* the parameters are given by a
-+                                     * ECPARAMETERS structure */
-+        ret = EC_GROUP_new_from_ecparameters(params->value.parameters);
-+        if (!ret) {
-+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, ERR_R_EC_LIB);
-+            return NULL;
-+        }
-+        EC_GROUP_set_asn1_flag(ret, 0x0);
-+    } else if (params->type == 2) { /* implicitlyCA */
-+        return NULL;
-+    } else {
-+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_ASN1_ERROR);
-+        return NULL;
-+    }
-+
-+    return ret;
-+}
-+
-+/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
-+
-+EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
-+{
-+    EC_GROUP *group = NULL;
-+    ECPKPARAMETERS *params = NULL;
-+    const unsigned char *p = *in;
-+
-+    if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) {
-+        ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
-+        ECPKPARAMETERS_free(params);
-+        return NULL;
-+    }
-+
-+    if ((group = EC_GROUP_new_from_ecpkparameters(params)) == NULL) {
-+        ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
-+        ECPKPARAMETERS_free(params);
-+        return NULL;
-+    }
-+
-+    if (a) {
-+        EC_GROUP_clear_free(*a);
-+        *a = group;
-+    }
-+
-+    ECPKPARAMETERS_free(params);
-+    *in = p;
-+    return (group);
-+}
-+
-+int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
-+{
-+    int ret = 0;
-+    ECPKPARAMETERS *tmp = EC_GROUP_get_ecpkparameters(a, NULL);
-+    if (tmp == NULL) {
-+        ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
-+        return 0;
-+    }
-+    if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
-+        ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
-+        ECPKPARAMETERS_free(tmp);
-+        return 0;
-+    }
-+    ECPKPARAMETERS_free(tmp);
-+    return (ret);
-+}
-+
-+/* some EC_KEY functions */
-+
-+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
-+{
-+    EC_KEY *ret = NULL;
-+    EC_PRIVATEKEY *priv_key = NULL;
-+    const unsigned char *p = *in;
-+
-+    if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) {
-+        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
-+        return NULL;
-+    }
-+
-+    if (a == NULL || *a == NULL) {
-+        if ((ret = EC_KEY_new()) == NULL) {
-+            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    } else
-+        ret = *a;
-+
-+    if (priv_key->parameters) {
-+        EC_GROUP_clear_free(ret->group);
-+        ret->group = EC_GROUP_new_from_ecpkparameters(priv_key->parameters);
-+    }
-+
-+    if (ret->group == NULL) {
-+        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+
-+    ret->version = priv_key->version;
-+
-+    if (priv_key->privateKey) {
-+        ASN1_OCTET_STRING *pkey = priv_key->privateKey;
-+        if (EC_KEY_oct2priv(ret, ASN1_STRING_get0_data(pkey),
-+                            ASN1_STRING_length(pkey)) == 0)
-+            goto err;
-+    } else {
-+        ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY);
-+        goto err;
-+    }
-+
-+    EC_POINT_clear_free(ret->pub_key);
-+    ret->pub_key = EC_POINT_new(ret->group);
-+    if (ret->pub_key == NULL) {
-+        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+
-+    if (priv_key->publicKey) {
-+        const unsigned char *pub_oct;
-+        int pub_oct_len;
-+
-+        pub_oct = ASN1_STRING_get0_data(priv_key->publicKey);
-+        pub_oct_len = ASN1_STRING_length(priv_key->publicKey);
-+        if (!EC_KEY_oct2key(ret, pub_oct, pub_oct_len, NULL)) {
-+            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+    } else {
-+        if (ret->group->meth->keygenpub == NULL
-+            || ret->group->meth->keygenpub(ret) == 0)
-+                goto err;
-+        /* Remember the original private-key-only encoding. */
-+        ret->enc_flag |= EC_PKEY_NO_PUBKEY;
-+    }
-+
-+    if (a)
-+        *a = ret;
-+    EC_PRIVATEKEY_free(priv_key);
-+    *in = p;
-+    return (ret);
-+
-+ err:
-+    if (a == NULL || *a != ret)
-+        EC_KEY_free(ret);
-+    EC_PRIVATEKEY_free(priv_key);
-+    return NULL;
-+}
-+
-+int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
-+{
-+    int ret = 0, ok = 0;
-+    unsigned char *priv= NULL, *pub= NULL;
-+    size_t privlen = 0, publen = 0;
-+
-+    EC_PRIVATEKEY *priv_key = NULL;
-+
-+    if (a == NULL || a->group == NULL ||
-+        (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) {
-+        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
-+        goto err;
-+    }
-+
-+    if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
-+        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    priv_key->version = a->version;
-+
-+    privlen = EC_KEY_priv2buf(a, &priv);
-+
-+    if (privlen == 0) {
-+        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+
-+    ASN1_STRING_set0(priv_key->privateKey, priv, privlen);
-+    priv = NULL;
-+
-+    if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
-+        if ((priv_key->parameters =
-+             EC_GROUP_get_ecpkparameters(a->group,
-+                                        priv_key->parameters)) == NULL) {
-+            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+    }
-+
-+    if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) {
-+        priv_key->publicKey = ASN1_BIT_STRING_new();
-+        if (priv_key->publicKey == NULL) {
-+            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+
-+        publen = EC_KEY_key2buf(a, a->conv_form, &pub, NULL);
-+
-+        if (publen == 0) {
-+            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+
-+        priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-+        priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-+        ASN1_STRING_set0(priv_key->publicKey, pub, publen);
-+        pub = NULL;
-+    }
-+
-+    if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
-+        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+    ok = 1;
-+ err:
-+    OPENSSL_clear_free(priv, privlen);
-+    OPENSSL_free(pub);
-+    EC_PRIVATEKEY_free(priv_key);
-+    return (ok ? ret : 0);
-+}
-+
-+int i2d_ECParameters(EC_KEY *a, unsigned char **out)
-+{
-+    if (a == NULL) {
-+        ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    return i2d_ECPKParameters(a->group, out);
-+}
-+
-+EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
-+{
-+    EC_KEY *ret;
-+
-+    if (in == NULL || *in == NULL) {
-+        ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
-+        return NULL;
-+    }
-+
-+    if (a == NULL || *a == NULL) {
-+        if ((ret = EC_KEY_new()) == NULL) {
-+            ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
-+            return NULL;
-+        }
-+    } else
-+        ret = *a;
-+
-+    if (!d2i_ECPKParameters(&ret->group, in, len)) {
-+        ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
-+        if (a == NULL || *a != ret)
-+             EC_KEY_free(ret);
-+        return NULL;
-+    }
-+
-+    if (a)
-+        *a = ret;
-+
-+    return ret;
-+}
-+
-+EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
-+{
-+    EC_KEY *ret = NULL;
-+
-+    if (a == NULL || (*a) == NULL || (*a)->group == NULL) {
-+        /*
-+         * sorry, but a EC_GROUP-structure is necessary to set the public key
-+         */
-+        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    ret = *a;
-+    if (!EC_KEY_oct2key(ret, *in, len, NULL)) {
-+        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
-+        return 0;
-+    }
-+    *in += len;
-+    return ret;
-+}
-+
-+int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out)
-+{
-+    size_t buf_len = 0;
-+    int new_buffer = 0;
-+
-+    if (a == NULL) {
-+        ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+
-+    buf_len = EC_POINT_point2oct(a->group, a->pub_key,
-+                                 a->conv_form, NULL, 0, NULL);
-+
-+    if (out == NULL || buf_len == 0)
-+        /* out == NULL => just return the length of the octet string */
-+        return buf_len;
-+
-+    if (*out == NULL) {
-+        if ((*out = OPENSSL_malloc(buf_len)) == NULL) {
-+            ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        new_buffer = 1;
-+    }
-+    if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
-+                            *out, buf_len, NULL)) {
-+        ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
-+        if (new_buffer) {
-+            OPENSSL_free(*out);
-+            *out = NULL;
-+        }
-+        return 0;
-+    }
-+    if (!new_buffer)
-+        *out += buf_len;
-+    return buf_len;
-+}
-+
-+ASN1_SEQUENCE(ECDSA_SIG) = {
-+        ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
-+        ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
-+} static_ASN1_SEQUENCE_END(ECDSA_SIG)
-+
-+DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG)
-+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG)
-+
-+ECDSA_SIG *ECDSA_SIG_new(void)
-+{
-+    ECDSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig));
-+    if (sig == NULL)
-+        ECerr(EC_F_ECDSA_SIG_NEW, ERR_R_MALLOC_FAILURE);
-+    return sig;
-+}
-+
-+void ECDSA_SIG_free(ECDSA_SIG *sig)
-+{
-+    if (sig == NULL)
-+        return;
-+    BN_clear_free(sig->r);
-+    BN_clear_free(sig->s);
-+    OPENSSL_free(sig);
-+}
-+
-+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
-+{
-+    if (pr != NULL)
-+        *pr = sig->r;
-+    if (ps != NULL)
-+        *ps = sig->s;
-+}
-+
-+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
-+{
-+    if (r == NULL || s == NULL)
-+        return 0;
-+    BN_clear_free(sig->r);
-+    BN_clear_free(sig->s);
-+    sig->r = r;
-+    sig->s = s;
-+    return 1;
-+}
-+
-+int ECDSA_size(const EC_KEY *r)
-+{
-+    int ret, i;
-+    ASN1_INTEGER bs;
-+    unsigned char buf[4];
-+    const EC_GROUP *group;
-+
-+    if (r == NULL)
-+        return 0;
-+    group = EC_KEY_get0_group(r);
-+    if (group == NULL)
-+        return 0;
-+
-+    i = EC_GROUP_order_bits(group);
-+    if (i == 0)
-+        return 0;
-+    bs.length = (i + 7) / 8;
-+    bs.data = buf;
-+    bs.type = V_ASN1_INTEGER;
-+    /* If the top bit is set the asn1 encoding is 1 larger. */
-+    buf[0] = 0xff;
-+
-+    i = i2d_ASN1_INTEGER(&bs, NULL);
-+    i += i;                     /* r and s */
-+    ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_check.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_check.c
-new file mode 100644
-index 0000000..eeb06ec
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_check.c
-@@ -0,0 +1,72 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "ec_lcl.h"
-+#include 
-+
-+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    const BIGNUM *order;
-+    BN_CTX *new_ctx = NULL;
-+    EC_POINT *point = NULL;
-+
-+    /* Custom curves assumed to be correct */
-+    if ((group->meth->flags & EC_FLAGS_CUSTOM_CURVE) != 0)
-+        return 1;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL) {
-+            ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    }
-+
-+    /* check the discriminant */
-+    if (!EC_GROUP_check_discriminant(group, ctx)) {
-+        ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
-+        goto err;
-+    }
-+
-+    /* check the generator */
-+    if (group->generator == NULL) {
-+        ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
-+        goto err;
-+    }
-+    if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {
-+        ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
-+        goto err;
-+    }
-+
-+    /* check the order of the generator */
-+    if ((point = EC_POINT_new(group)) == NULL)
-+        goto err;
-+    order = EC_GROUP_get0_order(group);
-+    if (order == NULL)
-+        goto err;
-+    if (BN_is_zero(order)) {
-+        ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
-+        goto err;
-+    }
-+
-+    if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
-+        goto err;
-+    if (!EC_POINT_is_at_infinity(group, point)) {
-+        ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
-+        goto err;
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_free(new_ctx);
-+    EC_POINT_free(point);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_curve.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_curve.c
-new file mode 100644
-index 0000000..e69de29
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_cvt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_cvt.c
-new file mode 100644
-index 0000000..bfff6d6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_cvt.c
-@@ -0,0 +1,95 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ *
-+ * Portions of the attached software ("Contribution") are developed by
-+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
-+ *
-+ * The Contribution is licensed pursuant to the OpenSSL open source
-+ * license provided above.
-+ *
-+ * The elliptic curve binary polynomial software is originally written by
-+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
-+ *
-+ */
-+
-+#include 
-+#include "ec_lcl.h"
-+
-+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
-+                                 const BIGNUM *b, BN_CTX *ctx)
-+{
-+    const EC_METHOD *meth;
-+    EC_GROUP *ret;
-+
-+#if defined(OPENSSL_BN_ASM_MONT)
-+    /*
-+     * This might appear controversial, but the fact is that generic
-+     * prime method was observed to deliver better performance even
-+     * for NIST primes on a range of platforms, e.g.: 60%-15%
-+     * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25%
-+     * in 32-bit build and 35%--12% in 64-bit build on Core2...
-+     * Coefficients are relative to optimized bn_nist.c for most
-+     * intensive ECDSA verify and ECDH operations for 192- and 521-
-+     * bit keys respectively. Choice of these boundary values is
-+     * arguable, because the dependency of improvement coefficient
-+     * from key length is not a "monotone" curve. For example while
-+     * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's
-+     * generally faster, sometimes "respectfully" faster, sometimes
-+     * "tolerably" slower... What effectively happens is that loop
-+     * with bn_mul_add_words is put against bn_mul_mont, and the
-+     * latter "wins" on short vectors. Correct solution should be
-+     * implementing dedicated NxN multiplication subroutines for
-+     * small N. But till it materializes, let's stick to generic
-+     * prime method...
-+     *                                              
-+     */
-+    meth = EC_GFp_mont_method();
-+#else
-+    if (BN_nist_mod_func(p))
-+        meth = EC_GFp_nist_method();
-+    else
-+        meth = EC_GFp_mont_method();
-+#endif
-+
-+    ret = EC_GROUP_new(meth);
-+    if (ret == NULL)
-+        return NULL;
-+
-+    if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
-+        EC_GROUP_clear_free(ret);
-+        return NULL;
-+    }
-+
-+    return ret;
-+}
-+
-+#ifndef OPENSSL_NO_EC2M
-+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
-+                                  const BIGNUM *b, BN_CTX *ctx)
-+{
-+    const EC_METHOD *meth;
-+    EC_GROUP *ret;
-+
-+    meth = EC_GF2m_simple_method();
-+
-+    ret = EC_GROUP_new(meth);
-+    if (ret == NULL)
-+        return NULL;
-+
-+    if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) {
-+        EC_GROUP_clear_free(ret);
-+        return NULL;
-+    }
-+
-+    return ret;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_err.c
-new file mode 100644
-index 0000000..e4c2c1c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_err.c
-@@ -0,0 +1,290 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
-+
-+static ERR_STRING_DATA EC_str_functs[] = {
-+    {ERR_FUNC(EC_F_BN_TO_FELEM), "BN_to_felem"},
-+    {ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
-+    {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
-+    {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
-+    {ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "do_EC_KEY_print"},
-+    {ERR_FUNC(EC_F_ECDH_CMS_DECRYPT), "ecdh_cms_decrypt"},
-+    {ERR_FUNC(EC_F_ECDH_CMS_SET_SHARED_INFO), "ecdh_cms_set_shared_info"},
-+    {ERR_FUNC(EC_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"},
-+    {ERR_FUNC(EC_F_ECDH_SIMPLE_COMPUTE_KEY), "ecdh_simple_compute_key"},
-+    {ERR_FUNC(EC_F_ECDSA_DO_SIGN_EX), "ECDSA_do_sign_ex"},
-+    {ERR_FUNC(EC_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"},
-+    {ERR_FUNC(EC_F_ECDSA_SIGN_EX), "ECDSA_sign_ex"},
-+    {ERR_FUNC(EC_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"},
-+    {ERR_FUNC(EC_F_ECDSA_SIG_NEW), "ECDSA_SIG_new"},
-+    {ERR_FUNC(EC_F_ECDSA_VERIFY), "ECDSA_verify"},
-+    {ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "eckey_param2type"},
-+    {ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "eckey_param_decode"},
-+    {ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "eckey_priv_decode"},
-+    {ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "eckey_priv_encode"},
-+    {ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "eckey_pub_decode"},
-+    {ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "eckey_pub_encode"},
-+    {ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "eckey_type2param"},
-+    {ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
-+    {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
-+    {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
-+    {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
-+    {ERR_FUNC(EC_F_ECP_NISTZ256_GET_AFFINE), "ecp_nistz256_get_affine"},
-+    {ERR_FUNC(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE),
-+     "ecp_nistz256_mult_precompute"},
-+    {ERR_FUNC(EC_F_ECP_NISTZ256_POINTS_MUL), "ecp_nistz256_points_mul"},
-+    {ERR_FUNC(EC_F_ECP_NISTZ256_PRE_COMP_NEW), "ecp_nistz256_pre_comp_new"},
-+    {ERR_FUNC(EC_F_ECP_NISTZ256_WINDOWED_MUL), "ecp_nistz256_windowed_mul"},
-+    {ERR_FUNC(EC_F_ECX_KEY_OP), "ecx_key_op"},
-+    {ERR_FUNC(EC_F_ECX_PRIV_ENCODE), "ecx_priv_encode"},
-+    {ERR_FUNC(EC_F_ECX_PUB_ENCODE), "ecx_pub_encode"},
-+    {ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "ec_asn1_group2curve"},
-+    {ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "ec_asn1_group2fieldid"},
-+    {ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY),
-+     "ec_GF2m_montgomery_point_multiply"},
-+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT),
-+     "ec_GF2m_simple_group_check_discriminant"},
-+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE),
-+     "ec_GF2m_simple_group_set_curve"},
-+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
-+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
-+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES),
-+     "ec_GF2m_simple_point_get_affine_coordinates"},
-+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES),
-+     "ec_GF2m_simple_point_set_affine_coordinates"},
-+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES),
-+     "ec_GF2m_simple_set_compressed_coordinates"},
-+    {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
-+    {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
-+    {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
-+    {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE),
-+     "ec_GFp_mont_field_set_to_one"},
-+    {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
-+    {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE),
-+     "ec_GFp_mont_group_set_curve"},
-+    {ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE),
-+     "ec_GFp_nistp224_group_set_curve"},
-+    {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"},
-+    {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES),
-+     "ec_GFp_nistp224_point_get_affine_coordinates"},
-+    {ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE),
-+     "ec_GFp_nistp256_group_set_curve"},
-+    {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"},
-+    {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES),
-+     "ec_GFp_nistp256_point_get_affine_coordinates"},
-+    {ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE),
-+     "ec_GFp_nistp521_group_set_curve"},
-+    {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"},
-+    {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES),
-+     "ec_GFp_nistp521_point_get_affine_coordinates"},
-+    {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
-+    {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
-+    {ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE),
-+     "ec_GFp_nist_group_set_curve"},
-+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT),
-+     "ec_GFp_simple_group_check_discriminant"},
-+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE),
-+     "ec_GFp_simple_group_set_curve"},
-+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"},
-+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"},
-+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"},
-+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE),
-+     "ec_GFp_simple_points_make_affine"},
-+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES),
-+     "ec_GFp_simple_point_get_affine_coordinates"},
-+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES),
-+     "ec_GFp_simple_point_set_affine_coordinates"},
-+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES),
-+     "ec_GFp_simple_set_compressed_coordinates"},
-+    {ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
-+    {ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT),
-+     "EC_GROUP_check_discriminant"},
-+    {ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"},
-+    {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"},
-+    {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"},
-+    {ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"},
-+    {ERR_FUNC(EC_F_EC_GROUP_GET_ECPARAMETERS), "EC_GROUP_get_ecparameters"},
-+    {ERR_FUNC(EC_F_EC_GROUP_GET_ECPKPARAMETERS),
-+     "EC_GROUP_get_ecpkparameters"},
-+    {ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS),
-+     "EC_GROUP_get_pentanomial_basis"},
-+    {ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS),
-+     "EC_GROUP_get_trinomial_basis"},
-+    {ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
-+    {ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
-+    {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "ec_group_new_from_data"},
-+    {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS),
-+     "EC_GROUP_new_from_ecparameters"},
-+    {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS),
-+     "EC_GROUP_new_from_ecpkparameters"},
-+    {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"},
-+    {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"},
-+    {ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"},
-+    {ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
-+    {ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
-+    {ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
-+    {ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
-+    {ERR_FUNC(EC_F_EC_KEY_NEW_METHOD), "EC_KEY_new_method"},
-+    {ERR_FUNC(EC_F_EC_KEY_OCT2PRIV), "EC_KEY_oct2priv"},
-+    {ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
-+    {ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
-+    {ERR_FUNC(EC_F_EC_KEY_PRIV2OCT), "EC_KEY_priv2oct"},
-+    {ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),
-+     "EC_KEY_set_public_key_affine_coordinates"},
-+    {ERR_FUNC(EC_F_EC_KEY_SIMPLE_CHECK_KEY), "ec_key_simple_check_key"},
-+    {ERR_FUNC(EC_F_EC_KEY_SIMPLE_OCT2PRIV), "ec_key_simple_oct2priv"},
-+    {ERR_FUNC(EC_F_EC_KEY_SIMPLE_PRIV2OCT), "ec_key_simple_priv2oct"},
-+    {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
-+    {ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
-+    {ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
-+    {ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
-+    {ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
-+    {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M),
-+     "EC_POINT_get_affine_coordinates_GF2m"},
-+    {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP),
-+     "EC_POINT_get_affine_coordinates_GFp"},
-+    {ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP),
-+     "EC_POINT_get_Jprojective_coordinates_GFp"},
-+    {ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
-+    {ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"},
-+    {ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"},
-+    {ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"},
-+    {ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"},
-+    {ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"},
-+    {ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"},
-+    {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M),
-+     "EC_POINT_set_affine_coordinates_GF2m"},
-+    {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP),
-+     "EC_POINT_set_affine_coordinates_GFp"},
-+    {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M),
-+     "EC_POINT_set_compressed_coordinates_GF2m"},
-+    {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP),
-+     "EC_POINT_set_compressed_coordinates_GFp"},
-+    {ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP),
-+     "EC_POINT_set_Jprojective_coordinates_GFp"},
-+    {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"},
-+    {ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "ec_pre_comp_new"},
-+    {ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"},
-+    {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"},
-+    {ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
-+    {ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
-+    {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
-+    {ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
-+    {ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "nistp224_pre_comp_new"},
-+    {ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "nistp256_pre_comp_new"},
-+    {ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "nistp521_pre_comp_new"},
-+    {ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
-+    {ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "old_ec_priv_decode"},
-+    {ERR_FUNC(EC_F_OSSL_ECDH_COMPUTE_KEY), "ossl_ecdh_compute_key"},
-+    {ERR_FUNC(EC_F_OSSL_ECDSA_SIGN_SIG), "ossl_ecdsa_sign_sig"},
-+    {ERR_FUNC(EC_F_OSSL_ECDSA_VERIFY_SIG), "ossl_ecdsa_verify_sig"},
-+    {ERR_FUNC(EC_F_PKEY_ECX_DERIVE), "pkey_ecx_derive"},
-+    {ERR_FUNC(EC_F_PKEY_EC_CTRL), "pkey_ec_ctrl"},
-+    {ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "pkey_ec_ctrl_str"},
-+    {ERR_FUNC(EC_F_PKEY_EC_DERIVE), "pkey_ec_derive"},
-+    {ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "pkey_ec_keygen"},
-+    {ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "pkey_ec_paramgen"},
-+    {ERR_FUNC(EC_F_PKEY_EC_SIGN), "pkey_ec_sign"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA EC_str_reasons[] = {
-+    {ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"},
-+    {ERR_REASON(EC_R_BAD_SIGNATURE), "bad signature"},
-+    {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
-+    {ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"},
-+    {ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"},
-+    {ERR_REASON(EC_R_CURVE_DOES_NOT_SUPPORT_ECDH),
-+     "curve does not support ecdh"},
-+    {ERR_REASON(EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING),
-+     "curve does not support signing"},
-+    {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),
-+     "d2i ecpkparameters failure"},
-+    {ERR_REASON(EC_R_DECODE_ERROR), "decode error"},
-+    {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"},
-+    {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),
-+     "ec group new by name failure"},
-+    {ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"},
-+    {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
-+    {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),
-+     "group2pkparameters failure"},
-+    {ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),
-+     "i2d ecpkparameters failure"},
-+    {ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"},
-+    {ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"},
-+    {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
-+    {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
-+    {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"},
-+    {ERR_REASON(EC_R_INVALID_DIGEST), "invalid digest"},
-+    {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
-+    {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
-+    {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"},
-+    {ERR_REASON(EC_R_INVALID_FORM), "invalid form"},
-+    {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"},
-+    {ERR_REASON(EC_R_INVALID_KEY), "invalid key"},
-+    {ERR_REASON(EC_R_INVALID_OUTPUT_LENGTH), "invalid output length"},
-+    {ERR_REASON(EC_R_INVALID_PEER_KEY), "invalid peer key"},
-+    {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
-+    {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
-+    {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"},
-+    {ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
-+    {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"},
-+    {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"},
-+    {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"},
-+    {ERR_REASON(EC_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
-+    {ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"},
-+    {ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"},
-+    {ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"},
-+    {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"},
-+    {ERR_REASON(EC_R_NO_PRIVATE_VALUE), "no private value"},
-+    {ERR_REASON(EC_R_OPERATION_NOT_SUPPORTED), "operation not supported"},
-+    {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"},
-+    {ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"},
-+    {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),
-+     "pkparameters2group failure"},
-+    {ERR_REASON(EC_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"},
-+    {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"},
-+    {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
-+    {ERR_REASON(EC_R_RANDOM_NUMBER_GENERATION_FAILED),
-+     "random number generation failed"},
-+    {ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"},
-+    {ERR_REASON(EC_R_SLOT_FULL), "slot full"},
-+    {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
-+    {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
-+    {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
-+    {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
-+    {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},
-+    {ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"},
-+    {ERR_REASON(EC_R_WRONG_ORDER), "wrong order"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_EC_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(EC_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, EC_str_functs);
-+        ERR_load_strings(0, EC_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_key.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_key.c
-new file mode 100644
-index 0000000..f1f0afb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_key.c
-@@ -0,0 +1,637 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * Portions originally developed by SUN MICROSYSTEMS, INC., and
-+ * contributed to the OpenSSL project.
-+ */
-+
-+#include 
-+#include 
-+#include "ec_lcl.h"
-+#include 
-+#include 
-+
-+EC_KEY *EC_KEY_new(void)
-+{
-+    return EC_KEY_new_method(NULL);
-+}
-+
-+EC_KEY *EC_KEY_new_by_curve_name(int nid)
-+{
-+    EC_KEY *ret = EC_KEY_new();
-+    if (ret == NULL)
-+        return NULL;
-+    ret->group = EC_GROUP_new_by_curve_name(nid);
-+    if (ret->group == NULL) {
-+        EC_KEY_free(ret);
-+        return NULL;
-+    }
-+    if (ret->meth->set_group != NULL
-+        && ret->meth->set_group(ret, ret->group) == 0) {
-+        EC_KEY_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+void EC_KEY_free(EC_KEY *r)
-+{
-+    int i;
-+
-+    if (r == NULL)
-+        return;
-+
-+    CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
-+    REF_PRINT_COUNT("EC_KEY", r);
-+    if (i > 0)
-+        return;
-+    REF_ASSERT_ISNT(i < 0);
-+
-+    if (r->meth->finish != NULL)
-+        r->meth->finish(r);
-+
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(r->engine);
-+#endif
-+
-+    if (r->group && r->group->meth->keyfinish)
-+        r->group->meth->keyfinish(r);
-+
-+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
-+    CRYPTO_THREAD_lock_free(r->lock);
-+    EC_GROUP_free(r->group);
-+    EC_POINT_free(r->pub_key);
-+    BN_clear_free(r->priv_key);
-+
-+    OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
-+}
-+
-+EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
-+{
-+    if (dest == NULL || src == NULL) {
-+        ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
-+        return NULL;
-+    }
-+    if (src->meth != dest->meth) {
-+        if (dest->meth->finish != NULL)
-+            dest->meth->finish(dest);
-+        if (dest->group && dest->group->meth->keyfinish)
-+            dest->group->meth->keyfinish(dest);
-+#ifndef OPENSSL_NO_ENGINE
-+        if (ENGINE_finish(dest->engine) == 0)
-+            return 0;
-+        dest->engine = NULL;
-+#endif
-+    }
-+    /* copy the parameters */
-+    if (src->group != NULL) {
-+        const EC_METHOD *meth = EC_GROUP_method_of(src->group);
-+        /* clear the old group */
-+        EC_GROUP_free(dest->group);
-+        dest->group = EC_GROUP_new(meth);
-+        if (dest->group == NULL)
-+            return NULL;
-+        if (!EC_GROUP_copy(dest->group, src->group))
-+            return NULL;
-+
-+        /*  copy the public key */
-+        if (src->pub_key != NULL) {
-+            EC_POINT_free(dest->pub_key);
-+            dest->pub_key = EC_POINT_new(src->group);
-+            if (dest->pub_key == NULL)
-+                return NULL;
-+            if (!EC_POINT_copy(dest->pub_key, src->pub_key))
-+                return NULL;
-+        }
-+        /* copy the private key */
-+        if (src->priv_key != NULL) {
-+            if (dest->priv_key == NULL) {
-+                dest->priv_key = BN_new();
-+                if (dest->priv_key == NULL)
-+                    return NULL;
-+            }
-+            if (!BN_copy(dest->priv_key, src->priv_key))
-+                return NULL;
-+            if (src->group->meth->keycopy
-+                && src->group->meth->keycopy(dest, src) == 0)
-+                return NULL;
-+        }
-+    }
-+
-+
-+    /* copy the rest */
-+    dest->enc_flag = src->enc_flag;
-+    dest->conv_form = src->conv_form;
-+    dest->version = src->version;
-+    dest->flags = src->flags;
-+    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
-+                            &dest->ex_data, &src->ex_data))
-+        return NULL;
-+
-+    if (src->meth != dest->meth) {
-+#ifndef OPENSSL_NO_ENGINE
-+        if (src->engine != NULL && ENGINE_init(src->engine) == 0)
-+            return NULL;
-+        dest->engine = src->engine;
-+#endif
-+        dest->meth = src->meth;
-+    }
-+
-+    if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0)
-+        return NULL;
-+
-+    return dest;
-+}
-+
-+EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
-+{
-+    EC_KEY *ret = EC_KEY_new_method(ec_key->engine);
-+
-+    if (ret == NULL)
-+        return NULL;
-+
-+    if (EC_KEY_copy(ret, ec_key) == NULL) {
-+        EC_KEY_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+int EC_KEY_up_ref(EC_KEY *r)
-+{
-+    int i;
-+
-+    if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
-+        return 0;
-+
-+    REF_PRINT_COUNT("EC_KEY", r);
-+    REF_ASSERT_ISNT(i < 2);
-+    return ((i > 1) ? 1 : 0);
-+}
-+
-+int EC_KEY_generate_key(EC_KEY *eckey)
-+{
-+    if (eckey == NULL || eckey->group == NULL) {
-+        ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    if (eckey->meth->keygen != NULL)
-+        return eckey->meth->keygen(eckey);
-+    ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
-+    return 0;
-+}
-+
-+int ossl_ec_key_gen(EC_KEY *eckey)
-+{
-+    OPENSSL_assert(eckey->group->meth->keygen != NULL);
-+    return eckey->group->meth->keygen(eckey);
-+}
-+
-+int ec_key_simple_generate_key(EC_KEY *eckey)
-+{
-+    int ok = 0;
-+    BN_CTX *ctx = NULL;
-+    BIGNUM *priv_key = NULL;
-+    const BIGNUM *order = NULL;
-+    EC_POINT *pub_key = NULL;
-+
-+    if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+
-+    if (eckey->priv_key == NULL) {
-+        priv_key = BN_new();
-+        if (priv_key == NULL)
-+            goto err;
-+    } else
-+        priv_key = eckey->priv_key;
-+
-+    order = EC_GROUP_get0_order(eckey->group);
-+    if (order == NULL)
-+        goto err;
-+
-+    do
-+        if (!BN_rand_range(priv_key, order))
-+            goto err;
-+    while (BN_is_zero(priv_key)) ;
-+
-+    if (eckey->pub_key == NULL) {
-+        pub_key = EC_POINT_new(eckey->group);
-+        if (pub_key == NULL)
-+            goto err;
-+    } else
-+        pub_key = eckey->pub_key;
-+
-+    if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
-+        goto err;
-+
-+    eckey->priv_key = priv_key;
-+    eckey->pub_key = pub_key;
-+
-+    ok = 1;
-+
-+ err:
-+    if (eckey->pub_key == NULL)
-+        EC_POINT_free(pub_key);
-+    if (eckey->priv_key != priv_key)
-+        BN_free(priv_key);
-+    BN_CTX_free(ctx);
-+    return ok;
-+}
-+
-+int ec_key_simple_generate_public_key(EC_KEY *eckey)
-+{
-+    return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
-+                        NULL, NULL);
-+}
-+
-+int EC_KEY_check_key(const EC_KEY *eckey)
-+{
-+    if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
-+        ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+
-+    if (eckey->group->meth->keycheck == NULL) {
-+        ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+
-+    return eckey->group->meth->keycheck(eckey);
-+}
-+
-+int ec_key_simple_check_key(const EC_KEY *eckey)
-+{
-+    int ok = 0;
-+    BN_CTX *ctx = NULL;
-+    const BIGNUM *order = NULL;
-+    EC_POINT *point = NULL;
-+
-+    if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
-+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+
-+    if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
-+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY);
-+        goto err;
-+    }
-+
-+    if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+    if ((point = EC_POINT_new(eckey->group)) == NULL)
-+        goto err;
-+
-+    /* testing whether the pub_key is on the elliptic curve */
-+    if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
-+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
-+        goto err;
-+    }
-+    /* testing whether pub_key * order is the point at infinity */
-+    order = eckey->group->order;
-+    if (BN_is_zero(order)) {
-+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
-+        goto err;
-+    }
-+    if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
-+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+    if (!EC_POINT_is_at_infinity(eckey->group, point)) {
-+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
-+        goto err;
-+    }
-+    /*
-+     * in case the priv_key is present : check if generator * priv_key ==
-+     * pub_key
-+     */
-+    if (eckey->priv_key != NULL) {
-+        if (BN_cmp(eckey->priv_key, order) >= 0) {
-+            ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
-+            goto err;
-+        }
-+        if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
-+                          NULL, NULL, ctx)) {
-+            ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+        if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
-+            ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
-+            goto err;
-+        }
-+    }
-+    ok = 1;
-+ err:
-+    BN_CTX_free(ctx);
-+    EC_POINT_free(point);
-+    return ok;
-+}
-+
-+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
-+                                             BIGNUM *y)
-+{
-+    BN_CTX *ctx = NULL;
-+    BIGNUM *tx, *ty;
-+    EC_POINT *point = NULL;
-+    int ok = 0;
-+#ifndef OPENSSL_NO_EC2M
-+    int tmp_nid, is_char_two = 0;
-+#endif
-+
-+    if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
-+        ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
-+              ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        return 0;
-+
-+    BN_CTX_start(ctx);
-+    point = EC_POINT_new(key->group);
-+
-+    if (point == NULL)
-+        goto err;
-+
-+    tx = BN_CTX_get(ctx);
-+    ty = BN_CTX_get(ctx);
-+    if (ty == NULL)
-+        goto err;
-+
-+#ifndef OPENSSL_NO_EC2M
-+    tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
-+
-+    if (tmp_nid == NID_X9_62_characteristic_two_field)
-+        is_char_two = 1;
-+
-+    if (is_char_two) {
-+        if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
-+                                                  x, y, ctx))
-+            goto err;
-+        if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
-+                                                  tx, ty, ctx))
-+            goto err;
-+    } else
-+#endif
-+    {
-+        if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
-+                                                 x, y, ctx))
-+            goto err;
-+        if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
-+                                                 tx, ty, ctx))
-+            goto err;
-+    }
-+    /*
-+     * Check if retrieved coordinates match originals and are less than field
-+     * order: if not values are out of range.
-+     */
-+    if (BN_cmp(x, tx) || BN_cmp(y, ty)
-+        || (BN_cmp(x, key->group->field) >= 0)
-+        || (BN_cmp(y, key->group->field) >= 0)) {
-+        ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
-+              EC_R_COORDINATES_OUT_OF_RANGE);
-+        goto err;
-+    }
-+
-+    if (!EC_KEY_set_public_key(key, point))
-+        goto err;
-+
-+    if (EC_KEY_check_key(key) == 0)
-+        goto err;
-+
-+    ok = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    EC_POINT_free(point);
-+    return ok;
-+
-+}
-+
-+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
-+{
-+    return key->group;
-+}
-+
-+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
-+{
-+    if (key->meth->set_group != NULL && key->meth->set_group(key, group) == 0)
-+        return 0;
-+    EC_GROUP_free(key->group);
-+    key->group = EC_GROUP_dup(group);
-+    return (key->group == NULL) ? 0 : 1;
-+}
-+
-+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
-+{
-+    return key->priv_key;
-+}
-+
-+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
-+{
-+    if (key->group == NULL || key->group->meth == NULL)
-+        return 0;
-+    if (key->group->meth->set_private != NULL
-+        && key->group->meth->set_private(key, priv_key) == 0)
-+        return 0;
-+    if (key->meth->set_private != NULL
-+        && key->meth->set_private(key, priv_key) == 0)
-+        return 0;
-+    BN_clear_free(key->priv_key);
-+    key->priv_key = BN_dup(priv_key);
-+    return (key->priv_key == NULL) ? 0 : 1;
-+}
-+
-+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
-+{
-+    return key->pub_key;
-+}
-+
-+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
-+{
-+    if (key->meth->set_public != NULL
-+        && key->meth->set_public(key, pub_key) == 0)
-+        return 0;
-+    EC_POINT_free(key->pub_key);
-+    key->pub_key = EC_POINT_dup(pub_key, key->group);
-+    return (key->pub_key == NULL) ? 0 : 1;
-+}
-+
-+unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
-+{
-+    return key->enc_flag;
-+}
-+
-+void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
-+{
-+    key->enc_flag = flags;
-+}
-+
-+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
-+{
-+    return key->conv_form;
-+}
-+
-+void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
-+{
-+    key->conv_form = cform;
-+    if (key->group != NULL)
-+        EC_GROUP_set_point_conversion_form(key->group, cform);
-+}
-+
-+void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
-+{
-+    if (key->group != NULL)
-+        EC_GROUP_set_asn1_flag(key->group, flag);
-+}
-+
-+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
-+{
-+    if (key->group == NULL)
-+        return 0;
-+    return EC_GROUP_precompute_mult(key->group, ctx);
-+}
-+
-+int EC_KEY_get_flags(const EC_KEY *key)
-+{
-+    return key->flags;
-+}
-+
-+void EC_KEY_set_flags(EC_KEY *key, int flags)
-+{
-+    key->flags |= flags;
-+}
-+
-+void EC_KEY_clear_flags(EC_KEY *key, int flags)
-+{
-+    key->flags &= ~flags;
-+}
-+
-+size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
-+                        unsigned char **pbuf, BN_CTX *ctx)
-+{
-+    if (key == NULL || key->pub_key == NULL || key->group == NULL)
-+        return 0;
-+    return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx);
-+}
-+
-+int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
-+                   BN_CTX *ctx)
-+{
-+    if (key == NULL || key->group == NULL)
-+        return 0;
-+    if (key->pub_key == NULL)
-+        key->pub_key = EC_POINT_new(key->group);
-+    if (key->pub_key == NULL)
-+        return 0;
-+    if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0)
-+        return 0;
-+    /*
-+     * Save the point conversion form.
-+     * For non-custom curves the first octet of the buffer (excluding
-+     * the last significant bit) contains the point conversion form.
-+     * EC_POINT_oct2point() has already performed sanity checking of
-+     * the buffer so we know it is valid.
-+     */
-+    if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0)
-+        key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01);
-+    return 1;
-+}
-+
-+size_t EC_KEY_priv2oct(const EC_KEY *eckey,
-+                       unsigned char *buf, size_t len)
-+{
-+    if (eckey->group == NULL || eckey->group->meth == NULL)
-+        return 0;
-+    if (eckey->group->meth->priv2oct == NULL) {
-+        ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+
-+    return eckey->group->meth->priv2oct(eckey, buf, len);
-+}
-+
-+size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
-+                              unsigned char *buf, size_t len)
-+{
-+    size_t buf_len;
-+
-+    buf_len = (EC_GROUP_order_bits(eckey->group) + 7) / 8;
-+    if (eckey->priv_key == NULL)
-+        return 0;
-+    if (buf == NULL)
-+        return buf_len;
-+    else if (len < buf_len)
-+        return 0;
-+
-+    /* Octetstring may need leading zeros if BN is to short */
-+
-+    if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) {
-+        ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL);
-+        return 0;
-+    }
-+
-+    return buf_len;
-+}
-+
-+int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
-+{
-+    if (eckey->group == NULL || eckey->group->meth == NULL)
-+        return 0;
-+    if (eckey->group->meth->oct2priv == NULL) {
-+        ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    return eckey->group->meth->oct2priv(eckey, buf, len);
-+}
-+
-+int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
-+{
-+    if (eckey->priv_key == NULL)
-+        eckey->priv_key = BN_secure_new();
-+    if (eckey->priv_key == NULL) {
-+        ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    eckey->priv_key = BN_bin2bn(buf, len, eckey->priv_key);
-+    if (eckey->priv_key == NULL) {
-+        ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
-+{
-+    size_t len;
-+    unsigned char *buf;
-+    len = EC_KEY_priv2oct(eckey, NULL, 0);
-+    if (len == 0)
-+        return 0;
-+    buf = OPENSSL_malloc(len);
-+    if (buf == NULL)
-+        return 0;
-+    len = EC_KEY_priv2oct(eckey, buf, len);
-+    if (len == 0) {
-+        OPENSSL_free(buf);
-+        return 0;
-+    }
-+    *pbuf = buf;
-+    return len;
-+}
-+
-+int EC_KEY_can_sign(const EC_KEY *eckey)
-+{
-+    if (eckey->group == NULL || eckey->group->meth == NULL
-+        || (eckey->group->meth->flags & EC_FLAGS_NO_SIGN))
-+        return 0;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_kmeth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_kmeth.c
-new file mode 100644
-index 0000000..eb469ba
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_kmeth.c
-@@ -0,0 +1,317 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "ec_lcl.h"
-+
-+
-+static const EC_KEY_METHOD openssl_ec_key_method = {
-+    "OpenSSL EC_KEY method",
-+    0,
-+    0,0,0,0,0,0,
-+    ossl_ec_key_gen,
-+    ossl_ecdh_compute_key,
-+    ossl_ecdsa_sign,
-+    ossl_ecdsa_sign_setup,
-+    ossl_ecdsa_sign_sig,
-+    ossl_ecdsa_verify,
-+    ossl_ecdsa_verify_sig
-+};
-+
-+static const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method;
-+
-+const EC_KEY_METHOD *EC_KEY_OpenSSL(void)
-+{
-+    return &openssl_ec_key_method;
-+}
-+
-+const EC_KEY_METHOD *EC_KEY_get_default_method(void)
-+{
-+    return default_ec_key_meth;
-+}
-+
-+void EC_KEY_set_default_method(const EC_KEY_METHOD *meth)
-+{
-+    if (meth == NULL)
-+        default_ec_key_meth = &openssl_ec_key_method;
-+    else
-+        default_ec_key_meth = meth;
-+}
-+
-+const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key)
-+{
-+    return key->meth;
-+}
-+
-+int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
-+{
-+    void (*finish)(EC_KEY *key) = key->meth->finish;
-+
-+    if (finish != NULL)
-+        finish(key);
-+
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(key->engine);
-+    key->engine = NULL;
-+#endif
-+
-+    key->meth = meth;
-+    if (meth->init != NULL)
-+        return meth->init(key);
-+    return 1;
-+}
-+
-+EC_KEY *EC_KEY_new_method(ENGINE *engine)
-+{
-+    EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->references = 1;
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+
-+    ret->meth = EC_KEY_get_default_method();
-+#ifndef OPENSSL_NO_ENGINE
-+    if (engine != NULL) {
-+        if (!ENGINE_init(engine)) {
-+            ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
-+            goto err;
-+        }
-+        ret->engine = engine;
-+    } else
-+        ret->engine = ENGINE_get_default_EC();
-+    if (ret->engine != NULL) {
-+        ret->meth = ENGINE_get_EC(ret->engine);
-+        if (ret->meth == NULL) {
-+            ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
-+            goto err;
-+        }
-+    }
-+#endif
-+
-+    ret->version = 1;
-+    ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
-+
-+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) {
-+        goto err;
-+    }
-+
-+    if (ret->meth->init != NULL && ret->meth->init(ret) == 0) {
-+        ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_INIT_FAIL);
-+        goto err;
-+    }
-+    return ret;
-+
-+err:
-+    EC_KEY_free(ret);
-+    return NULL;
-+}
-+
-+int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
-+                     const EC_KEY *eckey,
-+                     void *(*KDF) (const void *in, size_t inlen, void *out,
-+                                   size_t *outlen))
-+{
-+    unsigned char *sec = NULL;
-+    size_t seclen;
-+    if (eckey->meth->compute_key == NULL) {
-+        ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
-+        return 0;
-+    }
-+    if (outlen > INT_MAX) {
-+        ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_INVALID_OUTPUT_LENGTH);
-+        return 0;
-+    }
-+    if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey))
-+        return 0;
-+    if (KDF != NULL) {
-+        KDF(sec, seclen, out, &outlen);
-+    } else {
-+        if (outlen > seclen)
-+            outlen = seclen;
-+        memcpy(out, sec, outlen);
-+    }
-+    OPENSSL_clear_free(sec, seclen);
-+    return outlen;
-+}
-+
-+EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth)
-+{
-+    EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth));
-+
-+    if (ret == NULL)
-+        return NULL;
-+    if (meth != NULL)
-+        *ret = *meth;
-+    ret->flags |= EC_KEY_METHOD_DYNAMIC;
-+    return ret;
-+}
-+
-+void EC_KEY_METHOD_free(EC_KEY_METHOD *meth)
-+{
-+    if (meth->flags & EC_KEY_METHOD_DYNAMIC)
-+        OPENSSL_free(meth);
-+}
-+
-+void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
-+                            int (*init)(EC_KEY *key),
-+                            void (*finish)(EC_KEY *key),
-+                            int (*copy)(EC_KEY *dest, const EC_KEY *src),
-+                            int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
-+                            int (*set_private)(EC_KEY *key,
-+                                               const BIGNUM *priv_key),
-+                            int (*set_public)(EC_KEY *key,
-+                                              const EC_POINT *pub_key))
-+{
-+    meth->init = init;
-+    meth->finish = finish;
-+    meth->copy = copy;
-+    meth->set_group = set_group;
-+    meth->set_private = set_private;
-+    meth->set_public = set_public;
-+}
-+
-+void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth,
-+                              int (*keygen)(EC_KEY *key))
-+{
-+    meth->keygen = keygen;
-+}
-+
-+void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth,
-+                                   int (*ckey)(unsigned char **psec,
-+                                               size_t *pseclen,
-+                                               const EC_POINT *pub_key,
-+                                               const EC_KEY *ecdh))
-+{
-+    meth->compute_key = ckey;
-+}
-+
-+void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
-+                            int (*sign)(int type, const unsigned char *dgst,
-+                                        int dlen, unsigned char *sig,
-+                                        unsigned int *siglen,
-+                                        const BIGNUM *kinv, const BIGNUM *r,
-+                                        EC_KEY *eckey),
-+                            int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
-+                                              BIGNUM **kinvp, BIGNUM **rp),
-+                            ECDSA_SIG *(*sign_sig)(const unsigned char *dgst,
-+                                                   int dgst_len,
-+                                                   const BIGNUM *in_kinv,
-+                                                   const BIGNUM *in_r,
-+                                                   EC_KEY *eckey))
-+{
-+    meth->sign = sign;
-+    meth->sign_setup = sign_setup;
-+    meth->sign_sig = sign_sig;
-+}
-+
-+void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth,
-+                              int (*verify)(int type, const unsigned
-+                                            char *dgst, int dgst_len,
-+                                            const unsigned char *sigbuf,
-+                                            int sig_len, EC_KEY *eckey),
-+                              int (*verify_sig)(const unsigned char *dgst,
-+                                                int dgst_len,
-+                                                const ECDSA_SIG *sig,
-+                                                EC_KEY *eckey))
-+{
-+    meth->verify = verify;
-+    meth->verify_sig = verify_sig;
-+}
-+
-+void EC_KEY_METHOD_get_init(EC_KEY_METHOD *meth,
-+                            int (**pinit)(EC_KEY *key),
-+                            void (**pfinish)(EC_KEY *key),
-+                            int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
-+                            int (**pset_group)(EC_KEY *key,
-+                                               const EC_GROUP *grp),
-+                            int (**pset_private)(EC_KEY *key,
-+                                                 const BIGNUM *priv_key),
-+                            int (**pset_public)(EC_KEY *key,
-+                                                const EC_POINT *pub_key))
-+{
-+    if (pinit != NULL)
-+        *pinit = meth->init;
-+    if (pfinish != NULL)
-+        *pfinish = meth->finish;
-+    if (pcopy != NULL)
-+        *pcopy = meth->copy;
-+    if (pset_group != NULL)
-+        *pset_group = meth->set_group;
-+    if (pset_private != NULL)
-+        *pset_private = meth->set_private;
-+    if (pset_public != NULL)
-+        *pset_public = meth->set_public;
-+}
-+
-+void EC_KEY_METHOD_get_keygen(EC_KEY_METHOD *meth,
-+                              int (**pkeygen)(EC_KEY *key))
-+{
-+    if (pkeygen != NULL)
-+        *pkeygen = meth->keygen;
-+}
-+
-+void EC_KEY_METHOD_get_compute_key(EC_KEY_METHOD *meth,
-+                                   int (**pck)(unsigned char **pout,
-+                                               size_t *poutlen,
-+                                               const EC_POINT *pub_key,
-+                                               const EC_KEY *ecdh))
-+{
-+    if (pck != NULL)
-+        *pck = meth->compute_key;
-+}
-+
-+void EC_KEY_METHOD_get_sign(EC_KEY_METHOD *meth,
-+                            int (**psign)(int type, const unsigned char *dgst,
-+                                          int dlen, unsigned char *sig,
-+                                          unsigned int *siglen,
-+                                          const BIGNUM *kinv, const BIGNUM *r,
-+                                          EC_KEY *eckey),
-+                            int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
-+                                                BIGNUM **kinvp, BIGNUM **rp),
-+                            ECDSA_SIG *(**psign_sig)(const unsigned char *dgst,
-+                                                     int dgst_len,
-+                                                     const BIGNUM *in_kinv,
-+                                                     const BIGNUM *in_r,
-+                                                     EC_KEY *eckey))
-+{
-+    if (psign != NULL)
-+        *psign = meth->sign;
-+    if (psign_setup != NULL)
-+        *psign_setup = meth->sign_setup;
-+    if (psign_sig != NULL)
-+        *psign_sig = meth->sign_sig;
-+}
-+
-+void EC_KEY_METHOD_get_verify(EC_KEY_METHOD *meth,
-+                              int (**pverify)(int type, const unsigned
-+                                              char *dgst, int dgst_len,
-+                                              const unsigned char *sigbuf,
-+                                              int sig_len, EC_KEY *eckey),
-+                              int (**pverify_sig)(const unsigned char *dgst,
-+                                                  int dgst_len,
-+                                                  const ECDSA_SIG *sig,
-+                                                  EC_KEY *eckey))
-+{
-+    if (pverify != NULL)
-+        *pverify = meth->verify;
-+    if (pverify_sig != NULL)
-+        *pverify_sig = meth->verify_sig;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lcl.h
-new file mode 100644
-index 0000000..ded35a7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lcl.h
-@@ -0,0 +1,613 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ *
-+ * Portions of the attached software ("Contribution") are developed by
-+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
-+ *
-+ * The Contribution is licensed pursuant to the OpenSSL open source
-+ * license provided above.
-+ *
-+ * The elliptic curve binary polynomial software is originally written by
-+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
-+ *
-+ */
-+
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+
-+#include "e_os.h"
-+
-+#if defined(__SUNPRO_C)
-+# if __SUNPRO_C >= 0x520
-+#  pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
-+# endif
-+#endif
-+
-+/* Use default functions for poin2oct, oct2point and compressed coordinates */
-+#define EC_FLAGS_DEFAULT_OCT    0x1
-+
-+/* Use custom formats for EC_GROUP, EC_POINT and EC_KEY */
-+#define EC_FLAGS_CUSTOM_CURVE   0x2
-+
-+/* Curve does not support signing operations */
-+#define EC_FLAGS_NO_SIGN        0x4
-+
-+/*
-+ * Structure details are not part of the exported interface, so all this may
-+ * change in future versions.
-+ */
-+
-+struct ec_method_st {
-+    /* Various method flags */
-+    int flags;
-+    /* used by EC_METHOD_get_field_type: */
-+    int field_type;             /* a NID */
-+    /*
-+     * used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free,
-+     * EC_GROUP_copy:
-+     */
-+    int (*group_init) (EC_GROUP *);
-+    void (*group_finish) (EC_GROUP *);
-+    void (*group_clear_finish) (EC_GROUP *);
-+    int (*group_copy) (EC_GROUP *, const EC_GROUP *);
-+    /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
-+    /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
-+    int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
-+                            const BIGNUM *b, BN_CTX *);
-+    int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b,
-+                            BN_CTX *);
-+    /* used by EC_GROUP_get_degree: */
-+    int (*group_get_degree) (const EC_GROUP *);
-+    int (*group_order_bits) (const EC_GROUP *);
-+    /* used by EC_GROUP_check: */
-+    int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *);
-+    /*
-+     * used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free,
-+     * EC_POINT_copy:
-+     */
-+    int (*point_init) (EC_POINT *);
-+    void (*point_finish) (EC_POINT *);
-+    void (*point_clear_finish) (EC_POINT *);
-+    int (*point_copy) (EC_POINT *, const EC_POINT *);
-+    /*-
-+     * used by EC_POINT_set_to_infinity,
-+     * EC_POINT_set_Jprojective_coordinates_GFp,
-+     * EC_POINT_get_Jprojective_coordinates_GFp,
-+     * EC_POINT_set_affine_coordinates_GFp,     ..._GF2m,
-+     * EC_POINT_get_affine_coordinates_GFp,     ..._GF2m,
-+     * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
-+     */
-+    int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *);
-+    int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *,
-+                                                  EC_POINT *, const BIGNUM *x,
-+                                                  const BIGNUM *y,
-+                                                  const BIGNUM *z, BN_CTX *);
-+    int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *,
-+                                                  const EC_POINT *, BIGNUM *x,
-+                                                  BIGNUM *y, BIGNUM *z,
-+                                                  BN_CTX *);
-+    int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *,
-+                                         const BIGNUM *x, const BIGNUM *y,
-+                                         BN_CTX *);
-+    int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *,
-+                                         BIGNUM *x, BIGNUM *y, BN_CTX *);
-+    int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *,
-+                                             const BIGNUM *x, int y_bit,
-+                                             BN_CTX *);
-+    /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
-+    size_t (*point2oct) (const EC_GROUP *, const EC_POINT *,
-+                         point_conversion_form_t form, unsigned char *buf,
-+                         size_t len, BN_CTX *);
-+    int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf,
-+                      size_t len, BN_CTX *);
-+    /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
-+    int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
-+                const EC_POINT *b, BN_CTX *);
-+    int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
-+    int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *);
-+    /*
-+     * used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp:
-+     */
-+    int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *);
-+    int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *);
-+    int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
-+                      BN_CTX *);
-+    /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
-+    int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *);
-+    int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[],
-+                               BN_CTX *);
-+    /*
-+     * used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
-+     * EC_POINT_have_precompute_mult (default implementations are used if the
-+     * 'mul' pointer is 0):
-+     */
-+    int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
-+                size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
-+                BN_CTX *);
-+    int (*precompute_mult) (EC_GROUP *group, BN_CTX *);
-+    int (*have_precompute_mult) (const EC_GROUP *group);
-+    /* internal functions */
-+    /*
-+     * 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and
-+     * 'dbl' so that the same implementations of point operations can be used
-+     * with different optimized implementations of expensive field
-+     * operations:
-+     */
-+    int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                      const BIGNUM *b, BN_CTX *);
-+    int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
-+    int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                      const BIGNUM *b, BN_CTX *);
-+    /* e.g. to Montgomery */
-+    int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                         BN_CTX *);
-+    /* e.g. from Montgomery */
-+    int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                         BN_CTX *);
-+    int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *);
-+    /* private key operations */
-+    size_t (*priv2oct)(const EC_KEY *eckey, unsigned char *buf, size_t len);
-+    int (*oct2priv)(EC_KEY *eckey, const unsigned char *buf, size_t len);
-+    int (*set_private)(EC_KEY *eckey, const BIGNUM *priv_key);
-+    int (*keygen)(EC_KEY *eckey);
-+    int (*keycheck)(const EC_KEY *eckey);
-+    int (*keygenpub)(EC_KEY *eckey);
-+    int (*keycopy)(EC_KEY *dst, const EC_KEY *src);
-+    void (*keyfinish)(EC_KEY *eckey);
-+    /* custom ECDH operation */
-+    int (*ecdh_compute_key)(unsigned char **pout, size_t *poutlen,
-+                            const EC_POINT *pub_key, const EC_KEY *ecdh);
-+};
-+
-+/*
-+ * Types and functions to manipulate pre-computed values.
-+ */
-+typedef struct nistp224_pre_comp_st NISTP224_PRE_COMP;
-+typedef struct nistp256_pre_comp_st NISTP256_PRE_COMP;
-+typedef struct nistp521_pre_comp_st NISTP521_PRE_COMP;
-+typedef struct nistz256_pre_comp_st NISTZ256_PRE_COMP;
-+typedef struct ec_pre_comp_st EC_PRE_COMP;
-+
-+struct ec_group_st {
-+    const EC_METHOD *meth;
-+    EC_POINT *generator;        /* optional */
-+    BIGNUM *order, *cofactor;
-+    int curve_name;             /* optional NID for named curve */
-+    int asn1_flag;              /* flag to control the asn1 encoding */
-+    point_conversion_form_t asn1_form;
-+    unsigned char *seed;        /* optional seed for parameters (appears in
-+                                 * ASN1) */
-+    size_t seed_len;
-+    /*
-+     * The following members are handled by the method functions, even if
-+     * they appear generic
-+     */
-+    /*
-+     * Field specification. For curves over GF(p), this is the modulus; for
-+     * curves over GF(2^m), this is the irreducible polynomial defining the
-+     * field.
-+     */
-+    BIGNUM *field;
-+    /*
-+     * Field specification for curves over GF(2^m). The irreducible f(t) is
-+     * then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m =
-+     * poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with
-+     * poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero
-+     * terms.
-+     */
-+    int poly[6];
-+    /*
-+     * Curve coefficients. (Here the assumption is that BIGNUMs can be used
-+     * or abused for all kinds of fields, not just GF(p).) For characteristic
-+     * > 3, the curve is defined by a Weierstrass equation of the form y^2 =
-+     * x^3 + a*x + b. For characteristic 2, the curve is defined by an
-+     * equation of the form y^2 + x*y = x^3 + a*x^2 + b.
-+     */
-+    BIGNUM *a, *b;
-+    /* enable optimized point arithmetics for special case */
-+    int a_is_minus3;
-+    /* method-specific (e.g., Montgomery structure) */
-+    void *field_data1;
-+    /* method-specific */
-+    void *field_data2;
-+    /* method-specific */
-+    int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *,
-+                           BN_CTX *);
-+    /* data for ECDSA inverse */
-+    BN_MONT_CTX *mont_data;
-+
-+    /*
-+     * Precomputed values for speed. The PCT_xxx names match the
-+     * pre_comp.xxx union names; see the SETPRECOMP and HAVEPRECOMP
-+     * macros, below.
-+     */
-+    enum {
-+        PCT_none,
-+        PCT_nistp224, PCT_nistp256, PCT_nistp521, PCT_nistz256,
-+        PCT_ec
-+    } pre_comp_type;
-+    union {
-+        NISTP224_PRE_COMP *nistp224;
-+        NISTP256_PRE_COMP *nistp256;
-+        NISTP521_PRE_COMP *nistp521;
-+        NISTZ256_PRE_COMP *nistz256;
-+        EC_PRE_COMP *ec;
-+    } pre_comp;
-+};
-+
-+#define SETPRECOMP(g, type, pre) \
-+    g->pre_comp_type = PCT_##type, g->pre_comp.type = pre
-+#define HAVEPRECOMP(g, type) \
-+    g->pre_comp_type == PCT_##type && g->pre_comp.type != NULL
-+
-+struct ec_key_st {
-+    const EC_KEY_METHOD *meth;
-+    ENGINE *engine;
-+    int version;
-+    EC_GROUP *group;
-+    EC_POINT *pub_key;
-+    BIGNUM *priv_key;
-+    unsigned int enc_flag;
-+    point_conversion_form_t conv_form;
-+    int references;
-+    int flags;
-+    CRYPTO_EX_DATA ex_data;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+struct ec_point_st {
-+    const EC_METHOD *meth;
-+    /*
-+     * All members except 'meth' are handled by the method functions, even if
-+     * they appear generic
-+     */
-+    BIGNUM *X;
-+    BIGNUM *Y;
-+    BIGNUM *Z;                  /* Jacobian projective coordinates: * (X, Y,
-+                                 * Z) represents (X/Z^2, Y/Z^3) if Z != 0 */
-+    int Z_is_one;               /* enable optimized point arithmetics for
-+                                 * special case */
-+};
-+
-+NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *);
-+NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
-+NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *);
-+NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *);
-+NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
-+EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *);
-+
-+void EC_pre_comp_free(EC_GROUP *group);
-+void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *);
-+void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *);
-+void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *);
-+void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *);
-+void EC_ec_pre_comp_free(EC_PRE_COMP *);
-+
-+/*
-+ * method functions in ec_mult.c (ec_lib.c uses these as defaults if
-+ * group->method->mul is 0)
-+ */
-+int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
-+                size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
-+                BN_CTX *);
-+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
-+int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
-+
-+/* method functions in ecp_smpl.c */
-+int ec_GFp_simple_group_init(EC_GROUP *);
-+void ec_GFp_simple_group_finish(EC_GROUP *);
-+void ec_GFp_simple_group_clear_finish(EC_GROUP *);
-+int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
-+int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
-+                                  const BIGNUM *a, const BIGNUM *b, BN_CTX *);
-+int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
-+                                  BIGNUM *b, BN_CTX *);
-+int ec_GFp_simple_group_get_degree(const EC_GROUP *);
-+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
-+int ec_GFp_simple_point_init(EC_POINT *);
-+void ec_GFp_simple_point_finish(EC_POINT *);
-+void ec_GFp_simple_point_clear_finish(EC_POINT *);
-+int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
-+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
-+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *,
-+                                                  EC_POINT *, const BIGNUM *x,
-+                                                  const BIGNUM *y,
-+                                                  const BIGNUM *z, BN_CTX *);
-+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *,
-+                                                  const EC_POINT *, BIGNUM *x,
-+                                                  BIGNUM *y, BIGNUM *z,
-+                                                  BN_CTX *);
-+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
-+                                               const BIGNUM *x,
-+                                               const BIGNUM *y, BN_CTX *);
-+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *,
-+                                               const EC_POINT *, BIGNUM *x,
-+                                               BIGNUM *y, BN_CTX *);
-+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
-+                                             const BIGNUM *x, int y_bit,
-+                                             BN_CTX *);
-+size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *,
-+                               point_conversion_form_t form,
-+                               unsigned char *buf, size_t len, BN_CTX *);
-+int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
-+                            const unsigned char *buf, size_t len, BN_CTX *);
-+int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
-+                      const EC_POINT *b, BN_CTX *);
-+int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
-+                      BN_CTX *);
-+int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
-+int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
-+int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
-+int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
-+                      BN_CTX *);
-+int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
-+int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num,
-+                                     EC_POINT *[], BN_CTX *);
-+int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                            const BIGNUM *b, BN_CTX *);
-+int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                            BN_CTX *);
-+
-+/* method functions in ecp_mont.c */
-+int ec_GFp_mont_group_init(EC_GROUP *);
-+int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
-+                                const BIGNUM *b, BN_CTX *);
-+void ec_GFp_mont_group_finish(EC_GROUP *);
-+void ec_GFp_mont_group_clear_finish(EC_GROUP *);
-+int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
-+int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                          const BIGNUM *b, BN_CTX *);
-+int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                          BN_CTX *);
-+int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                             BN_CTX *);
-+int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                             BN_CTX *);
-+int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
-+
-+/* method functions in ecp_nist.c */
-+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
-+int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
-+                                const BIGNUM *b, BN_CTX *);
-+int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                          const BIGNUM *b, BN_CTX *);
-+int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                          BN_CTX *);
-+
-+/* method functions in ec2_smpl.c */
-+int ec_GF2m_simple_group_init(EC_GROUP *);
-+void ec_GF2m_simple_group_finish(EC_GROUP *);
-+void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
-+int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
-+int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
-+                                   const BIGNUM *a, const BIGNUM *b,
-+                                   BN_CTX *);
-+int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
-+                                   BIGNUM *b, BN_CTX *);
-+int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
-+int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
-+int ec_GF2m_simple_point_init(EC_POINT *);
-+void ec_GF2m_simple_point_finish(EC_POINT *);
-+void ec_GF2m_simple_point_clear_finish(EC_POINT *);
-+int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
-+int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
-+int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
-+                                                const BIGNUM *x,
-+                                                const BIGNUM *y, BN_CTX *);
-+int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *,
-+                                                const EC_POINT *, BIGNUM *x,
-+                                                BIGNUM *y, BN_CTX *);
-+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
-+                                              const BIGNUM *x, int y_bit,
-+                                              BN_CTX *);
-+size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *,
-+                                point_conversion_form_t form,
-+                                unsigned char *buf, size_t len, BN_CTX *);
-+int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
-+                             const unsigned char *buf, size_t len, BN_CTX *);
-+int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
-+                       const EC_POINT *b, BN_CTX *);
-+int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
-+                       BN_CTX *);
-+int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
-+int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
-+int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
-+int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
-+                       BN_CTX *);
-+int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
-+int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num,
-+                                      EC_POINT *[], BN_CTX *);
-+int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                             const BIGNUM *b, BN_CTX *);
-+int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                             BN_CTX *);
-+int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
-+                             const BIGNUM *b, BN_CTX *);
-+
-+/* method functions in ec2_mult.c */
-+int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
-+                       const BIGNUM *scalar, size_t num,
-+                       const EC_POINT *points[], const BIGNUM *scalars[],
-+                       BN_CTX *);
-+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
-+int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
-+
-+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
-+/* method functions in ecp_nistp224.c */
-+int ec_GFp_nistp224_group_init(EC_GROUP *group);
-+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
-+                                    const BIGNUM *a, const BIGNUM *n,
-+                                    BN_CTX *);
-+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
-+                                                 const EC_POINT *point,
-+                                                 BIGNUM *x, BIGNUM *y,
-+                                                 BN_CTX *ctx);
-+int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r,
-+                        const BIGNUM *scalar, size_t num,
-+                        const EC_POINT *points[], const BIGNUM *scalars[],
-+                        BN_CTX *);
-+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
-+                               const BIGNUM *scalar, size_t num,
-+                               const EC_POINT *points[],
-+                               const BIGNUM *scalars[], BN_CTX *ctx);
-+int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
-+int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
-+
-+/* method functions in ecp_nistp256.c */
-+int ec_GFp_nistp256_group_init(EC_GROUP *group);
-+int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
-+                                    const BIGNUM *a, const BIGNUM *n,
-+                                    BN_CTX *);
-+int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
-+                                                 const EC_POINT *point,
-+                                                 BIGNUM *x, BIGNUM *y,
-+                                                 BN_CTX *ctx);
-+int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r,
-+                        const BIGNUM *scalar, size_t num,
-+                        const EC_POINT *points[], const BIGNUM *scalars[],
-+                        BN_CTX *);
-+int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
-+                               const BIGNUM *scalar, size_t num,
-+                               const EC_POINT *points[],
-+                               const BIGNUM *scalars[], BN_CTX *ctx);
-+int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
-+int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
-+
-+/* method functions in ecp_nistp521.c */
-+int ec_GFp_nistp521_group_init(EC_GROUP *group);
-+int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
-+                                    const BIGNUM *a, const BIGNUM *n,
-+                                    BN_CTX *);
-+int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
-+                                                 const EC_POINT *point,
-+                                                 BIGNUM *x, BIGNUM *y,
-+                                                 BN_CTX *ctx);
-+int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r,
-+                        const BIGNUM *scalar, size_t num,
-+                        const EC_POINT *points[], const BIGNUM *scalars[],
-+                        BN_CTX *);
-+int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
-+                               const BIGNUM *scalar, size_t num,
-+                               const EC_POINT *points[],
-+                               const BIGNUM *scalars[], BN_CTX *ctx);
-+int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
-+int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
-+
-+/* utility functions in ecp_nistputil.c */
-+void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
-+                                              size_t felem_size,
-+                                              void *tmp_felems,
-+                                              void (*felem_one) (void *out),
-+                                              int (*felem_is_zero) (const void
-+                                                                    *in),
-+                                              void (*felem_assign) (void *out,
-+                                                                    const void
-+                                                                    *in),
-+                                              void (*felem_square) (void *out,
-+                                                                    const void
-+                                                                    *in),
-+                                              void (*felem_mul) (void *out,
-+                                                                 const void
-+                                                                 *in1,
-+                                                                 const void
-+                                                                 *in2),
-+                                              void (*felem_inv) (void *out,
-+                                                                 const void
-+                                                                 *in),
-+                                              void (*felem_contract) (void
-+                                                                      *out,
-+                                                                      const
-+                                                                      void
-+                                                                      *in));
-+void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
-+                                     unsigned char *digit, unsigned char in);
-+#endif
-+int ec_precompute_mont_data(EC_GROUP *);
-+int ec_group_simple_order_bits(const EC_GROUP *group);
-+
-+#ifdef ECP_NISTZ256_ASM
-+/** Returns GFp methods using montgomery multiplication, with x86-64 optimized
-+ * P256. See http://eprint.iacr.org/2013/816.
-+ *  \return  EC_METHOD object
-+ */
-+const EC_METHOD *EC_GFp_nistz256_method(void);
-+#endif
-+
-+size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
-+                              unsigned char *buf, size_t len);
-+int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len);
-+int ec_key_simple_generate_key(EC_KEY *eckey);
-+int ec_key_simple_generate_public_key(EC_KEY *eckey);
-+int ec_key_simple_check_key(const EC_KEY *eckey);
-+
-+/* EC_METHOD definitions */
-+
-+struct ec_key_method_st {
-+    const char *name;
-+    int32_t flags;
-+    int (*init)(EC_KEY *key);
-+    void (*finish)(EC_KEY *key);
-+    int (*copy)(EC_KEY *dest, const EC_KEY *src);
-+    int (*set_group)(EC_KEY *key, const EC_GROUP *grp);
-+    int (*set_private)(EC_KEY *key, const BIGNUM *priv_key);
-+    int (*set_public)(EC_KEY *key, const EC_POINT *pub_key);
-+    int (*keygen)(EC_KEY *key);
-+    int (*compute_key)(unsigned char **pout, size_t *poutlen,
-+                       const EC_POINT *pub_key, const EC_KEY *ecdh);
-+    int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char
-+                *sig, unsigned int *siglen, const BIGNUM *kinv,
-+                const BIGNUM *r, EC_KEY *eckey);
-+    int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
-+                      BIGNUM **rp);
-+    ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len,
-+                           const BIGNUM *in_kinv, const BIGNUM *in_r,
-+                           EC_KEY *eckey);
-+
-+    int (*verify)(int type, const unsigned char *dgst, int dgst_len,
-+                  const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
-+    int (*verify_sig)(const unsigned char *dgst, int dgst_len,
-+                      const ECDSA_SIG *sig, EC_KEY *eckey);
-+};
-+
-+#define EC_KEY_METHOD_DYNAMIC   1
-+
-+int ossl_ec_key_gen(EC_KEY *eckey);
-+int ossl_ecdh_compute_key(unsigned char **pout, size_t *poutlen,
-+                          const EC_POINT *pub_key, const EC_KEY *ecdh);
-+int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
-+                            const EC_POINT *pub_key, const EC_KEY *ecdh);
-+
-+struct ECDSA_SIG_st {
-+    BIGNUM *r;
-+    BIGNUM *s;
-+};
-+
-+int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
-+                          BIGNUM **rp);
-+int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
-+                    unsigned char *sig, unsigned int *siglen,
-+                    const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey);
-+ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
-+                               const BIGNUM *in_kinv, const BIGNUM *in_r,
-+                               EC_KEY *eckey);
-+int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
-+                      const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
-+int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
-+                          const ECDSA_SIG *sig, EC_KEY *eckey);
-+
-+int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
-+           const uint8_t peer_public_value[32]);
-+void X25519_public_from_private(uint8_t out_public_value[32],
-+                                const uint8_t private_key[32]);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lib.c
-new file mode 100644
-index 0000000..7cb4bfe
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_lib.c
-@@ -0,0 +1,1004 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * Binary polynomial ECC support in OpenSSL originally developed by
-+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
-+ */
-+
-+#include 
-+
-+#include 
-+#include 
-+
-+#include "ec_lcl.h"
-+
-+/* functions for EC_GROUP objects */
-+
-+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
-+{
-+    EC_GROUP *ret;
-+
-+    if (meth == NULL) {
-+        ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
-+        return NULL;
-+    }
-+    if (meth->group_init == 0) {
-+        ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return NULL;
-+    }
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL) {
-+        ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->meth = meth;
-+    if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
-+        ret->order = BN_new();
-+        if (ret->order == NULL)
-+            goto err;
-+        ret->cofactor = BN_new();
-+        if (ret->cofactor == NULL)
-+            goto err;
-+    }
-+    ret->asn1_flag = OPENSSL_EC_NAMED_CURVE;
-+    ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
-+    if (!meth->group_init(ret))
-+        goto err;
-+    return ret;
-+
-+ err:
-+    BN_free(ret->order);
-+    BN_free(ret->cofactor);
-+    OPENSSL_free(ret);
-+    return NULL;
-+}
-+
-+void EC_pre_comp_free(EC_GROUP *group)
-+{
-+    switch (group->pre_comp_type) {
-+    default:
-+        break;
-+#ifdef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
-+    case PCT_nistz256:
-+        EC_nistz256_pre_comp_free(group->pre_comp.nistz256);
-+        break;
-+#endif
-+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
-+    case PCT_nistp224:
-+        EC_nistp224_pre_comp_free(group->pre_comp.nistp224);
-+        break;
-+    case PCT_nistp256:
-+        EC_nistp256_pre_comp_free(group->pre_comp.nistp256);
-+        break;
-+    case PCT_nistp521:
-+        EC_nistp521_pre_comp_free(group->pre_comp.nistp521);
-+        break;
-+#endif
-+    case PCT_ec:
-+        EC_ec_pre_comp_free(group->pre_comp.ec);
-+        break;
-+    }
-+    group->pre_comp.ec = NULL;
-+}
-+
-+void EC_GROUP_free(EC_GROUP *group)
-+{
-+    if (!group)
-+        return;
-+
-+    if (group->meth->group_finish != 0)
-+        group->meth->group_finish(group);
-+
-+    EC_pre_comp_free(group);
-+    BN_MONT_CTX_free(group->mont_data);
-+    EC_POINT_free(group->generator);
-+    BN_free(group->order);
-+    BN_free(group->cofactor);
-+    OPENSSL_free(group->seed);
-+    OPENSSL_free(group);
-+}
-+
-+void EC_GROUP_clear_free(EC_GROUP *group)
-+{
-+    if (!group)
-+        return;
-+
-+    if (group->meth->group_clear_finish != 0)
-+        group->meth->group_clear_finish(group);
-+    else if (group->meth->group_finish != 0)
-+        group->meth->group_finish(group);
-+
-+    EC_pre_comp_free(group);
-+    BN_MONT_CTX_free(group->mont_data);
-+    EC_POINT_clear_free(group->generator);
-+    BN_clear_free(group->order);
-+    BN_clear_free(group->cofactor);
-+    OPENSSL_clear_free(group->seed, group->seed_len);
-+    OPENSSL_clear_free(group, sizeof(*group));
-+}
-+
-+int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
-+{
-+    if (dest->meth->group_copy == 0) {
-+        ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (dest->meth != src->meth) {
-+        ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    if (dest == src)
-+        return 1;
-+
-+    /* Copy precomputed */
-+    dest->pre_comp_type = src->pre_comp_type;
-+    switch (src->pre_comp_type) {
-+    default:
-+        dest->pre_comp.ec = NULL;
-+        break;
-+#ifdef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
-+    case PCT_nistz256:
-+        dest->pre_comp.nistz256 = EC_nistz256_pre_comp_dup(src->pre_comp.nistz256);
-+        break;
-+#endif
-+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
-+    case PCT_nistp224:
-+        dest->pre_comp.nistp224 = EC_nistp224_pre_comp_dup(src->pre_comp.nistp224);
-+        break;
-+    case PCT_nistp256:
-+        dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256);
-+        break;
-+    case PCT_nistp521:
-+        dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521);
-+        break;
-+#endif
-+    case PCT_ec:
-+        dest->pre_comp.ec = EC_ec_pre_comp_dup(src->pre_comp.ec);
-+        break;
-+    }
-+
-+    if (src->mont_data != NULL) {
-+        if (dest->mont_data == NULL) {
-+            dest->mont_data = BN_MONT_CTX_new();
-+            if (dest->mont_data == NULL)
-+                return 0;
-+        }
-+        if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data))
-+            return 0;
-+    } else {
-+        /* src->generator == NULL */
-+        BN_MONT_CTX_free(dest->mont_data);
-+        dest->mont_data = NULL;
-+    }
-+
-+    if (src->generator != NULL) {
-+        if (dest->generator == NULL) {
-+            dest->generator = EC_POINT_new(dest);
-+            if (dest->generator == NULL)
-+                return 0;
-+        }
-+        if (!EC_POINT_copy(dest->generator, src->generator))
-+            return 0;
-+    } else {
-+        /* src->generator == NULL */
-+        EC_POINT_clear_free(dest->generator);
-+        dest->generator = NULL;
-+    }
-+
-+    if ((src->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
-+        if (!BN_copy(dest->order, src->order))
-+            return 0;
-+        if (!BN_copy(dest->cofactor, src->cofactor))
-+            return 0;
-+    }
-+
-+    dest->curve_name = src->curve_name;
-+    dest->asn1_flag = src->asn1_flag;
-+    dest->asn1_form = src->asn1_form;
-+
-+    if (src->seed) {
-+        OPENSSL_free(dest->seed);
-+        dest->seed = OPENSSL_malloc(src->seed_len);
-+        if (dest->seed == NULL)
-+            return 0;
-+        if (!memcpy(dest->seed, src->seed, src->seed_len))
-+            return 0;
-+        dest->seed_len = src->seed_len;
-+    } else {
-+        OPENSSL_free(dest->seed);
-+        dest->seed = NULL;
-+        dest->seed_len = 0;
-+    }
-+
-+    return dest->meth->group_copy(dest, src);
-+}
-+
-+EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
-+{
-+    EC_GROUP *t = NULL;
-+    int ok = 0;
-+
-+    if (a == NULL)
-+        return NULL;
-+
-+    if ((t = EC_GROUP_new(a->meth)) == NULL)
-+        return (NULL);
-+    if (!EC_GROUP_copy(t, a))
-+        goto err;
-+
-+    ok = 1;
-+
-+ err:
-+    if (!ok) {
-+        EC_GROUP_free(t);
-+        return NULL;
-+    }
-+        return t;
-+}
-+
-+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
-+{
-+    return group->meth;
-+}
-+
-+int EC_METHOD_get_field_type(const EC_METHOD *meth)
-+{
-+    return meth->field_type;
-+}
-+
-+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
-+                           const BIGNUM *order, const BIGNUM *cofactor)
-+{
-+    if (generator == NULL) {
-+        ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+
-+    if (group->generator == NULL) {
-+        group->generator = EC_POINT_new(group);
-+        if (group->generator == NULL)
-+            return 0;
-+    }
-+    if (!EC_POINT_copy(group->generator, generator))
-+        return 0;
-+
-+    if (order != NULL) {
-+        if (!BN_copy(group->order, order))
-+            return 0;
-+    } else
-+        BN_zero(group->order);
-+
-+    if (cofactor != NULL) {
-+        if (!BN_copy(group->cofactor, cofactor))
-+            return 0;
-+    } else
-+        BN_zero(group->cofactor);
-+
-+    /*
-+     * Some groups have an order with
-+     * factors of two, which makes the Montgomery setup fail.
-+     * |group->mont_data| will be NULL in this case.
-+     */
-+    if (BN_is_odd(group->order)) {
-+        return ec_precompute_mont_data(group);
-+    }
-+
-+    BN_MONT_CTX_free(group->mont_data);
-+    group->mont_data = NULL;
-+    return 1;
-+}
-+
-+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
-+{
-+    return group->generator;
-+}
-+
-+BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
-+{
-+    return group->mont_data;
-+}
-+
-+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
-+{
-+    if (group->order == NULL)
-+        return 0;
-+    if (!BN_copy(order, group->order))
-+        return 0;
-+
-+    return !BN_is_zero(order);
-+}
-+
-+const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group)
-+{
-+    return group->order;
-+}
-+
-+int EC_GROUP_order_bits(const EC_GROUP *group)
-+{
-+    OPENSSL_assert(group->meth->group_order_bits != NULL);
-+    return group->meth->group_order_bits(group);
-+}
-+
-+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
-+                          BN_CTX *ctx)
-+{
-+
-+    if (group->cofactor == NULL)
-+        return 0;
-+    if (!BN_copy(cofactor, group->cofactor))
-+        return 0;
-+
-+    return !BN_is_zero(group->cofactor);
-+}
-+
-+const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group)
-+{
-+    return group->cofactor;
-+}
-+
-+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
-+{
-+    group->curve_name = nid;
-+}
-+
-+int EC_GROUP_get_curve_name(const EC_GROUP *group)
-+{
-+    return group->curve_name;
-+}
-+
-+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
-+{
-+    group->asn1_flag = flag;
-+}
-+
-+int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
-+{
-+    return group->asn1_flag;
-+}
-+
-+void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
-+                                        point_conversion_form_t form)
-+{
-+    group->asn1_form = form;
-+}
-+
-+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP
-+                                                           *group)
-+{
-+    return group->asn1_form;
-+}
-+
-+size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
-+{
-+    OPENSSL_free(group->seed);
-+    group->seed = NULL;
-+    group->seed_len = 0;
-+
-+    if (!len || !p)
-+        return 1;
-+
-+    if ((group->seed = OPENSSL_malloc(len)) == NULL)
-+        return 0;
-+    memcpy(group->seed, p, len);
-+    group->seed_len = len;
-+
-+    return len;
-+}
-+
-+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
-+{
-+    return group->seed;
-+}
-+
-+size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
-+{
-+    return group->seed_len;
-+}
-+
-+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
-+                           const BIGNUM *b, BN_CTX *ctx)
-+{
-+    if (group->meth->group_set_curve == 0) {
-+        ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    return group->meth->group_set_curve(group, p, a, b, ctx);
-+}
-+
-+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
-+                           BIGNUM *b, BN_CTX *ctx)
-+{
-+    if (group->meth->group_get_curve == 0) {
-+        ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    return group->meth->group_get_curve(group, p, a, b, ctx);
-+}
-+
-+#ifndef OPENSSL_NO_EC2M
-+int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
-+                            const BIGNUM *b, BN_CTX *ctx)
-+{
-+    if (group->meth->group_set_curve == 0) {
-+        ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    return group->meth->group_set_curve(group, p, a, b, ctx);
-+}
-+
-+int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
-+                            BIGNUM *b, BN_CTX *ctx)
-+{
-+    if (group->meth->group_get_curve == 0) {
-+        ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    return group->meth->group_get_curve(group, p, a, b, ctx);
-+}
-+#endif
-+
-+int EC_GROUP_get_degree(const EC_GROUP *group)
-+{
-+    if (group->meth->group_get_degree == 0) {
-+        ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    return group->meth->group_get_degree(group);
-+}
-+
-+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
-+{
-+    if (group->meth->group_check_discriminant == 0) {
-+        ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    return group->meth->group_check_discriminant(group, ctx);
-+}
-+
-+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
-+{
-+    int r = 0;
-+    BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
-+    BN_CTX *ctx_new = NULL;
-+
-+    /* compare the field types */
-+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
-+        EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
-+        return 1;
-+    /* compare the curve name (if present in both) */
-+    if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
-+        EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
-+        return 1;
-+    if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE)
-+        return 0;
-+
-+    if (ctx == NULL)
-+        ctx_new = ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        return -1;
-+
-+    BN_CTX_start(ctx);
-+    a1 = BN_CTX_get(ctx);
-+    a2 = BN_CTX_get(ctx);
-+    a3 = BN_CTX_get(ctx);
-+    b1 = BN_CTX_get(ctx);
-+    b2 = BN_CTX_get(ctx);
-+    b3 = BN_CTX_get(ctx);
-+    if (b3 == NULL) {
-+        BN_CTX_end(ctx);
-+        BN_CTX_free(ctx_new);
-+        return -1;
-+    }
-+
-+    /*
-+     * XXX This approach assumes that the external representation of curves
-+     * over the same field type is the same.
-+     */
-+    if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
-+        !b->meth->group_get_curve(b, b1, b2, b3, ctx))
-+        r = 1;
-+
-+    if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
-+        r = 1;
-+
-+    /* XXX EC_POINT_cmp() assumes that the methods are equal */
-+    if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
-+                          EC_GROUP_get0_generator(b), ctx))
-+        r = 1;
-+
-+    if (!r) {
-+        const BIGNUM *ao, *bo, *ac, *bc;
-+        /* compare the order and cofactor */
-+        ao = EC_GROUP_get0_order(a);
-+        bo = EC_GROUP_get0_order(b);
-+        ac = EC_GROUP_get0_cofactor(a);
-+        bc = EC_GROUP_get0_cofactor(b);
-+        if (ao == NULL || bo == NULL) {
-+            BN_CTX_end(ctx);
-+            BN_CTX_free(ctx_new);
-+            return -1;
-+        }
-+        if (BN_cmp(ao, bo) || BN_cmp(ac, bc))
-+            r = 1;
-+    }
-+
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(ctx_new);
-+
-+    return r;
-+}
-+
-+/* functions for EC_POINT objects */
-+
-+EC_POINT *EC_POINT_new(const EC_GROUP *group)
-+{
-+    EC_POINT *ret;
-+
-+    if (group == NULL) {
-+        ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
-+        return NULL;
-+    }
-+    if (group->meth->point_init == 0) {
-+        ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return NULL;
-+    }
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL) {
-+        ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->meth = group->meth;
-+
-+    if (!ret->meth->point_init(ret)) {
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+
-+    return ret;
-+}
-+
-+void EC_POINT_free(EC_POINT *point)
-+{
-+    if (!point)
-+        return;
-+
-+    if (point->meth->point_finish != 0)
-+        point->meth->point_finish(point);
-+    OPENSSL_free(point);
-+}
-+
-+void EC_POINT_clear_free(EC_POINT *point)
-+{
-+    if (!point)
-+        return;
-+
-+    if (point->meth->point_clear_finish != 0)
-+        point->meth->point_clear_finish(point);
-+    else if (point->meth->point_finish != 0)
-+        point->meth->point_finish(point);
-+    OPENSSL_clear_free(point, sizeof(*point));
-+}
-+
-+int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
-+{
-+    if (dest->meth->point_copy == 0) {
-+        ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (dest->meth != src->meth) {
-+        ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    if (dest == src)
-+        return 1;
-+    return dest->meth->point_copy(dest, src);
-+}
-+
-+EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
-+{
-+    EC_POINT *t;
-+    int r;
-+
-+    if (a == NULL)
-+        return NULL;
-+
-+    t = EC_POINT_new(group);
-+    if (t == NULL)
-+        return (NULL);
-+    r = EC_POINT_copy(t, a);
-+    if (!r) {
-+        EC_POINT_free(t);
-+        return NULL;
-+    }
-+    return t;
-+}
-+
-+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
-+{
-+    return point->meth;
-+}
-+
-+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
-+{
-+    if (group->meth->point_set_to_infinity == 0) {
-+        ECerr(EC_F_EC_POINT_SET_TO_INFINITY,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->point_set_to_infinity(group, point);
-+}
-+
-+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
-+                                             EC_POINT *point, const BIGNUM *x,
-+                                             const BIGNUM *y, const BIGNUM *z,
-+                                             BN_CTX *ctx)
-+{
-+    if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
-+        ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
-+              EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x,
-+                                                              y, z, ctx);
-+}
-+
-+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
-+                                             const EC_POINT *point, BIGNUM *x,
-+                                             BIGNUM *y, BIGNUM *z,
-+                                             BN_CTX *ctx)
-+{
-+    if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
-+        ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
-+              EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x,
-+                                                              y, z, ctx);
-+}
-+
-+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
-+                                        EC_POINT *point, const BIGNUM *x,
-+                                        const BIGNUM *y, BN_CTX *ctx)
-+{
-+    if (group->meth->point_set_affine_coordinates == 0) {
-+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
-+              EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
-+        return 0;
-+
-+    if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
-+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
-+              EC_R_POINT_IS_NOT_ON_CURVE);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+#ifndef OPENSSL_NO_EC2M
-+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
-+                                         EC_POINT *point, const BIGNUM *x,
-+                                         const BIGNUM *y, BN_CTX *ctx)
-+{
-+    if (group->meth->point_set_affine_coordinates == 0) {
-+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
-+              EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
-+        return 0;
-+
-+    if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
-+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
-+              EC_R_POINT_IS_NOT_ON_CURVE);
-+        return 0;
-+    }
-+    return 1;
-+}
-+#endif
-+
-+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
-+                                        const EC_POINT *point, BIGNUM *x,
-+                                        BIGNUM *y, BN_CTX *ctx)
-+{
-+    if (group->meth->point_get_affine_coordinates == 0) {
-+        ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
-+              EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
-+}
-+
-+#ifndef OPENSSL_NO_EC2M
-+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
-+                                         const EC_POINT *point, BIGNUM *x,
-+                                         BIGNUM *y, BN_CTX *ctx)
-+{
-+    if (group->meth->point_get_affine_coordinates == 0) {
-+        ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
-+              EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
-+}
-+#endif
-+
-+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
-+                 const EC_POINT *b, BN_CTX *ctx)
-+{
-+    if (group->meth->add == 0) {
-+        ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if ((group->meth != r->meth) || (r->meth != a->meth)
-+        || (a->meth != b->meth)) {
-+        ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->add(group, r, a, b, ctx);
-+}
-+
-+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
-+                 BN_CTX *ctx)
-+{
-+    if (group->meth->dbl == 0) {
-+        ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if ((group->meth != r->meth) || (r->meth != a->meth)) {
-+        ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->dbl(group, r, a, ctx);
-+}
-+
-+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
-+{
-+    if (group->meth->invert == 0) {
-+        ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != a->meth) {
-+        ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->invert(group, a, ctx);
-+}
-+
-+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
-+{
-+    if (group->meth->is_at_infinity == 0) {
-+        ECerr(EC_F_EC_POINT_IS_AT_INFINITY,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->is_at_infinity(group, point);
-+}
-+
-+/*
-+ * Check whether an EC_POINT is on the curve or not. Note that the return
-+ * value for this function should NOT be treated as a boolean. Return values:
-+ *  1: The point is on the curve
-+ *  0: The point is not on the curve
-+ * -1: An error occurred
-+ */
-+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
-+                         BN_CTX *ctx)
-+{
-+    if (group->meth->is_on_curve == 0) {
-+        ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->is_on_curve(group, point, ctx);
-+}
-+
-+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
-+                 BN_CTX *ctx)
-+{
-+    if (group->meth->point_cmp == 0) {
-+        ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return -1;
-+    }
-+    if ((group->meth != a->meth) || (a->meth != b->meth)) {
-+        ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
-+        return -1;
-+    }
-+    return group->meth->point_cmp(group, a, b, ctx);
-+}
-+
-+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
-+{
-+    if (group->meth->make_affine == 0) {
-+        ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    return group->meth->make_affine(group, point, ctx);
-+}
-+
-+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
-+                          EC_POINT *points[], BN_CTX *ctx)
-+{
-+    size_t i;
-+
-+    if (group->meth->points_make_affine == 0) {
-+        ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    for (i = 0; i < num; i++) {
-+        if (group->meth != points[i]->meth) {
-+            ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
-+            return 0;
-+        }
-+    }
-+    return group->meth->points_make_affine(group, num, points, ctx);
-+}
-+
-+/*
-+ * Functions for point multiplication. If group->meth->mul is 0, we use the
-+ * wNAF-based implementations in ec_mult.c; otherwise we dispatch through
-+ * methods.
-+ */
-+
-+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
-+                  size_t num, const EC_POINT *points[],
-+                  const BIGNUM *scalars[], BN_CTX *ctx)
-+{
-+    if (group->meth->mul == 0)
-+        /* use default */
-+        return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
-+
-+    return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
-+}
-+
-+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
-+                 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
-+{
-+    /* just a convenient interface to EC_POINTs_mul() */
-+
-+    const EC_POINT *points[1];
-+    const BIGNUM *scalars[1];
-+
-+    points[0] = point;
-+    scalars[0] = p_scalar;
-+
-+    return EC_POINTs_mul(group, r, g_scalar,
-+                         (point != NULL
-+                          && p_scalar != NULL), points, scalars, ctx);
-+}
-+
-+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
-+{
-+    if (group->meth->mul == 0)
-+        /* use default */
-+        return ec_wNAF_precompute_mult(group, ctx);
-+
-+    if (group->meth->precompute_mult != 0)
-+        return group->meth->precompute_mult(group, ctx);
-+    else
-+        return 1;               /* nothing to do, so report success */
-+}
-+
-+int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
-+{
-+    if (group->meth->mul == 0)
-+        /* use default */
-+        return ec_wNAF_have_precompute_mult(group);
-+
-+    if (group->meth->have_precompute_mult != 0)
-+        return group->meth->have_precompute_mult(group);
-+    else
-+        return 0;               /* cannot tell whether precomputation has
-+                                 * been performed */
-+}
-+
-+/*
-+ * ec_precompute_mont_data sets |group->mont_data| from |group->order| and
-+ * returns one on success. On error it returns zero.
-+ */
-+int ec_precompute_mont_data(EC_GROUP *group)
-+{
-+    BN_CTX *ctx = BN_CTX_new();
-+    int ret = 0;
-+
-+    BN_MONT_CTX_free(group->mont_data);
-+    group->mont_data = NULL;
-+
-+    if (ctx == NULL)
-+        goto err;
-+
-+    group->mont_data = BN_MONT_CTX_new();
-+    if (group->mont_data == NULL)
-+        goto err;
-+
-+    if (!BN_MONT_CTX_set(group->mont_data, group->order, ctx)) {
-+        BN_MONT_CTX_free(group->mont_data);
-+        group->mont_data = NULL;
-+        goto err;
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+
-+    BN_CTX_free(ctx);
-+    return ret;
-+}
-+
-+int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg)
-+{
-+    return CRYPTO_set_ex_data(&key->ex_data, idx, arg);
-+}
-+
-+void *EC_KEY_get_ex_data(const EC_KEY *key, int idx)
-+{
-+    return CRYPTO_get_ex_data(&key->ex_data, idx);
-+}
-+
-+int ec_group_simple_order_bits(const EC_GROUP *group)
-+{
-+    if (group->order == NULL)
-+        return 0;
-+    return BN_num_bits(group->order);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_mult.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_mult.c
-new file mode 100644
-index 0000000..036cdde
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_mult.c
-@@ -0,0 +1,680 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
-+ * and contributed to the OpenSSL project.
-+ */
-+
-+#include 
-+#include 
-+
-+#include "internal/cryptlib.h"
-+#include "internal/bn_int.h"
-+#include "ec_lcl.h"
-+
-+/*
-+ * This file implements the wNAF-based interleaving multi-exponentiation method
-+ * ();
-+ * for multiplication with precomputation, we use wNAF splitting
-+ * ().
-+ */
-+
-+/* structure for precomputed multiples of the generator */
-+struct ec_pre_comp_st {
-+    const EC_GROUP *group;      /* parent EC_GROUP object */
-+    size_t blocksize;           /* block size for wNAF splitting */
-+    size_t numblocks;           /* max. number of blocks for which we have
-+                                 * precomputation */
-+    size_t w;                   /* window size */
-+    EC_POINT **points;          /* array with pre-calculated multiples of
-+                                 * generator: 'num' pointers to EC_POINT
-+                                 * objects followed by a NULL */
-+    size_t num;                 /* numblocks * 2^(w-1) */
-+    int references;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
-+{
-+    EC_PRE_COMP *ret = NULL;
-+
-+    if (!group)
-+        return NULL;
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL) {
-+        ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
-+        return ret;
-+    }
-+
-+    ret->group = group;
-+    ret->blocksize = 8;         /* default */
-+    ret->w = 4;                 /* default */
-+    ret->references = 1;
-+
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre)
-+{
-+    int i;
-+    if (pre != NULL)
-+        CRYPTO_atomic_add(&pre->references, 1, &i, pre->lock);
-+    return pre;
-+}
-+
-+void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
-+{
-+    int i;
-+
-+    if (pre == NULL)
-+        return;
-+
-+    CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
-+    REF_PRINT_COUNT("EC_ec", pre);
-+    if (i > 0)
-+        return;
-+    REF_ASSERT_ISNT(i < 0);
-+
-+    if (pre->points != NULL) {
-+        EC_POINT **pts;
-+
-+        for (pts = pre->points; *pts != NULL; pts++)
-+            EC_POINT_free(*pts);
-+        OPENSSL_free(pre->points);
-+    }
-+    CRYPTO_THREAD_lock_free(pre->lock);
-+    OPENSSL_free(pre);
-+}
-+
-+/*
-+ * TODO: table should be optimised for the wNAF-based implementation,
-+ * sometimes smaller windows will give better performance (thus the
-+ * boundaries should be increased)
-+ */
-+#define EC_window_bits_for_scalar_size(b) \
-+                ((size_t) \
-+                 ((b) >= 2000 ? 6 : \
-+                  (b) >=  800 ? 5 : \
-+                  (b) >=  300 ? 4 : \
-+                  (b) >=   70 ? 3 : \
-+                  (b) >=   20 ? 2 : \
-+                  1))
-+
-+/*-
-+ * Compute
-+ *      \sum scalars[i]*points[i],
-+ * also including
-+ *      scalar*generator
-+ * in the addition if scalar != NULL
-+ */
-+int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
-+                size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
-+                BN_CTX *ctx)
-+{
-+    BN_CTX *new_ctx = NULL;
-+    const EC_POINT *generator = NULL;
-+    EC_POINT *tmp = NULL;
-+    size_t totalnum;
-+    size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
-+    size_t pre_points_per_block = 0;
-+    size_t i, j;
-+    int k;
-+    int r_is_inverted = 0;
-+    int r_is_at_infinity = 1;
-+    size_t *wsize = NULL;       /* individual window sizes */
-+    signed char **wNAF = NULL;  /* individual wNAFs */
-+    size_t *wNAF_len = NULL;
-+    size_t max_len = 0;
-+    size_t num_val;
-+    EC_POINT **val = NULL;      /* precomputation */
-+    EC_POINT **v;
-+    EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or
-+                                 * 'pre_comp->points' */
-+    const EC_PRE_COMP *pre_comp = NULL;
-+    int num_scalar = 0;         /* flag: will be set to 1 if 'scalar' must be
-+                                 * treated like other scalars, i.e.
-+                                 * precomputation is not available */
-+    int ret = 0;
-+
-+    if (group->meth != r->meth) {
-+        ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+
-+    if ((scalar == NULL) && (num == 0)) {
-+        return EC_POINT_set_to_infinity(group, r);
-+    }
-+
-+    for (i = 0; i < num; i++) {
-+        if (group->meth != points[i]->meth) {
-+            ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
-+            return 0;
-+        }
-+    }
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            goto err;
-+    }
-+
-+    if (scalar != NULL) {
-+        generator = EC_GROUP_get0_generator(group);
-+        if (generator == NULL) {
-+            ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
-+            goto err;
-+        }
-+
-+        /* look if we can use precomputed multiples of generator */
-+
-+        pre_comp = group->pre_comp.ec;
-+        if (pre_comp && pre_comp->numblocks
-+            && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) ==
-+                0)) {
-+            blocksize = pre_comp->blocksize;
-+
-+            /*
-+             * determine maximum number of blocks that wNAF splitting may
-+             * yield (NB: maximum wNAF length is bit length plus one)
-+             */
-+            numblocks = (BN_num_bits(scalar) / blocksize) + 1;
-+
-+            /*
-+             * we cannot use more blocks than we have precomputation for
-+             */
-+            if (numblocks > pre_comp->numblocks)
-+                numblocks = pre_comp->numblocks;
-+
-+            pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
-+
-+            /* check that pre_comp looks sane */
-+            if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
-+                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
-+                goto err;
-+            }
-+        } else {
-+            /* can't use precomputation */
-+            pre_comp = NULL;
-+            numblocks = 1;
-+            num_scalar = 1;     /* treat 'scalar' like 'num'-th element of
-+                                 * 'scalars' */
-+        }
-+    }
-+
-+    totalnum = num + numblocks;
-+
-+    wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]);
-+    wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
-+    wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space
-+                                                             * for pivot */
-+    val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
-+
-+    /* Ensure wNAF is initialised in case we end up going to err */
-+    if (wNAF != NULL)
-+        wNAF[0] = NULL;         /* preliminary pivot */
-+
-+    if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) {
-+        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    /*
-+     * num_val will be the total number of temporarily precomputed points
-+     */
-+    num_val = 0;
-+
-+    for (i = 0; i < num + num_scalar; i++) {
-+        size_t bits;
-+
-+        bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
-+        wsize[i] = EC_window_bits_for_scalar_size(bits);
-+        num_val += (size_t)1 << (wsize[i] - 1);
-+        wNAF[i + 1] = NULL;     /* make sure we always have a pivot */
-+        wNAF[i] =
-+            bn_compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],
-+                            &wNAF_len[i]);
-+        if (wNAF[i] == NULL)
-+            goto err;
-+        if (wNAF_len[i] > max_len)
-+            max_len = wNAF_len[i];
-+    }
-+
-+    if (numblocks) {
-+        /* we go here iff scalar != NULL */
-+
-+        if (pre_comp == NULL) {
-+            if (num_scalar != 1) {
-+                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
-+                goto err;
-+            }
-+            /* we have already generated a wNAF for 'scalar' */
-+        } else {
-+            signed char *tmp_wNAF = NULL;
-+            size_t tmp_len = 0;
-+
-+            if (num_scalar != 0) {
-+                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
-+                goto err;
-+            }
-+
-+            /*
-+             * use the window size for which we have precomputation
-+             */
-+            wsize[num] = pre_comp->w;
-+            tmp_wNAF = bn_compute_wNAF(scalar, wsize[num], &tmp_len);
-+            if (!tmp_wNAF)
-+                goto err;
-+
-+            if (tmp_len <= max_len) {
-+                /*
-+                 * One of the other wNAFs is at least as long as the wNAF
-+                 * belonging to the generator, so wNAF splitting will not buy
-+                 * us anything.
-+                 */
-+
-+                numblocks = 1;
-+                totalnum = num + 1; /* don't use wNAF splitting */
-+                wNAF[num] = tmp_wNAF;
-+                wNAF[num + 1] = NULL;
-+                wNAF_len[num] = tmp_len;
-+                /*
-+                 * pre_comp->points starts with the points that we need here:
-+                 */
-+                val_sub[num] = pre_comp->points;
-+            } else {
-+                /*
-+                 * don't include tmp_wNAF directly into wNAF array - use wNAF
-+                 * splitting and include the blocks
-+                 */
-+
-+                signed char *pp;
-+                EC_POINT **tmp_points;
-+
-+                if (tmp_len < numblocks * blocksize) {
-+                    /*
-+                     * possibly we can do with fewer blocks than estimated
-+                     */
-+                    numblocks = (tmp_len + blocksize - 1) / blocksize;
-+                    if (numblocks > pre_comp->numblocks) {
-+                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
-+                        OPENSSL_free(tmp_wNAF);
-+                        goto err;
-+                    }
-+                    totalnum = num + numblocks;
-+                }
-+
-+                /* split wNAF in 'numblocks' parts */
-+                pp = tmp_wNAF;
-+                tmp_points = pre_comp->points;
-+
-+                for (i = num; i < totalnum; i++) {
-+                    if (i < totalnum - 1) {
-+                        wNAF_len[i] = blocksize;
-+                        if (tmp_len < blocksize) {
-+                            ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
-+                            OPENSSL_free(tmp_wNAF);
-+                            goto err;
-+                        }
-+                        tmp_len -= blocksize;
-+                    } else
-+                        /*
-+                         * last block gets whatever is left (this could be
-+                         * more or less than 'blocksize'!)
-+                         */
-+                        wNAF_len[i] = tmp_len;
-+
-+                    wNAF[i + 1] = NULL;
-+                    wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
-+                    if (wNAF[i] == NULL) {
-+                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
-+                        OPENSSL_free(tmp_wNAF);
-+                        goto err;
-+                    }
-+                    memcpy(wNAF[i], pp, wNAF_len[i]);
-+                    if (wNAF_len[i] > max_len)
-+                        max_len = wNAF_len[i];
-+
-+                    if (*tmp_points == NULL) {
-+                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
-+                        OPENSSL_free(tmp_wNAF);
-+                        goto err;
-+                    }
-+                    val_sub[i] = tmp_points;
-+                    tmp_points += pre_points_per_block;
-+                    pp += blocksize;
-+                }
-+                OPENSSL_free(tmp_wNAF);
-+            }
-+        }
-+    }
-+
-+    /*
-+     * All points we precompute now go into a single array 'val'.
-+     * 'val_sub[i]' is a pointer to the subarray for the i-th point, or to a
-+     * subarray of 'pre_comp->points' if we already have precomputation.
-+     */
-+    val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
-+    if (val == NULL) {
-+        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    val[num_val] = NULL;        /* pivot element */
-+
-+    /* allocate points for precomputation */
-+    v = val;
-+    for (i = 0; i < num + num_scalar; i++) {
-+        val_sub[i] = v;
-+        for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {
-+            *v = EC_POINT_new(group);
-+            if (*v == NULL)
-+                goto err;
-+            v++;
-+        }
-+    }
-+    if (!(v == val + num_val)) {
-+        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
-+        goto err;
-+    }
-+
-+    if ((tmp = EC_POINT_new(group)) == NULL)
-+        goto err;
-+
-+    /*-
-+     * prepare precomputed values:
-+     *    val_sub[i][0] :=     points[i]
-+     *    val_sub[i][1] := 3 * points[i]
-+     *    val_sub[i][2] := 5 * points[i]
-+     *    ...
-+     */
-+    for (i = 0; i < num + num_scalar; i++) {
-+        if (i < num) {
-+            if (!EC_POINT_copy(val_sub[i][0], points[i]))
-+                goto err;
-+        } else {
-+            if (!EC_POINT_copy(val_sub[i][0], generator))
-+                goto err;
-+        }
-+
-+        if (wsize[i] > 1) {
-+            if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx))
-+                goto err;
-+            for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) {
-+                if (!EC_POINT_add
-+                    (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx))
-+                    goto err;
-+            }
-+        }
-+    }
-+
-+    if (!EC_POINTs_make_affine(group, num_val, val, ctx))
-+        goto err;
-+
-+    r_is_at_infinity = 1;
-+
-+    for (k = max_len - 1; k >= 0; k--) {
-+        if (!r_is_at_infinity) {
-+            if (!EC_POINT_dbl(group, r, r, ctx))
-+                goto err;
-+        }
-+
-+        for (i = 0; i < totalnum; i++) {
-+            if (wNAF_len[i] > (size_t)k) {
-+                int digit = wNAF[i][k];
-+                int is_neg;
-+
-+                if (digit) {
-+                    is_neg = digit < 0;
-+
-+                    if (is_neg)
-+                        digit = -digit;
-+
-+                    if (is_neg != r_is_inverted) {
-+                        if (!r_is_at_infinity) {
-+                            if (!EC_POINT_invert(group, r, ctx))
-+                                goto err;
-+                        }
-+                        r_is_inverted = !r_is_inverted;
-+                    }
-+
-+                    /* digit > 0 */
-+
-+                    if (r_is_at_infinity) {
-+                        if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))
-+                            goto err;
-+                        r_is_at_infinity = 0;
-+                    } else {
-+                        if (!EC_POINT_add
-+                            (group, r, r, val_sub[i][digit >> 1], ctx))
-+                            goto err;
-+                    }
-+                }
-+            }
-+        }
-+    }
-+
-+    if (r_is_at_infinity) {
-+        if (!EC_POINT_set_to_infinity(group, r))
-+            goto err;
-+    } else {
-+        if (r_is_inverted)
-+            if (!EC_POINT_invert(group, r, ctx))
-+                goto err;
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_free(new_ctx);
-+    EC_POINT_free(tmp);
-+    OPENSSL_free(wsize);
-+    OPENSSL_free(wNAF_len);
-+    if (wNAF != NULL) {
-+        signed char **w;
-+
-+        for (w = wNAF; *w != NULL; w++)
-+            OPENSSL_free(*w);
-+
-+        OPENSSL_free(wNAF);
-+    }
-+    if (val != NULL) {
-+        for (v = val; *v != NULL; v++)
-+            EC_POINT_clear_free(*v);
-+
-+        OPENSSL_free(val);
-+    }
-+    OPENSSL_free(val_sub);
-+    return ret;
-+}
-+
-+/*-
-+ * ec_wNAF_precompute_mult()
-+ * creates an EC_PRE_COMP object with preprecomputed multiples of the generator
-+ * for use with wNAF splitting as implemented in ec_wNAF_mul().
-+ *
-+ * 'pre_comp->points' is an array of multiples of the generator
-+ * of the following form:
-+ * points[0] =     generator;
-+ * points[1] = 3 * generator;
-+ * ...
-+ * points[2^(w-1)-1] =     (2^(w-1)-1) * generator;
-+ * points[2^(w-1)]   =     2^blocksize * generator;
-+ * points[2^(w-1)+1] = 3 * 2^blocksize * generator;
-+ * ...
-+ * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) *  2^(blocksize*(numblocks-2)) * generator
-+ * points[2^(w-1)*(numblocks-1)]   =              2^(blocksize*(numblocks-1)) * generator
-+ * ...
-+ * points[2^(w-1)*numblocks-1]     = (2^(w-1)) *  2^(blocksize*(numblocks-1)) * generator
-+ * points[2^(w-1)*numblocks]       = NULL
-+ */
-+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
-+{
-+    const EC_POINT *generator;
-+    EC_POINT *tmp_point = NULL, *base = NULL, **var;
-+    BN_CTX *new_ctx = NULL;
-+    const BIGNUM *order;
-+    size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
-+    EC_POINT **points = NULL;
-+    EC_PRE_COMP *pre_comp;
-+    int ret = 0;
-+
-+    /* if there is an old EC_PRE_COMP object, throw it away */
-+    EC_pre_comp_free(group);
-+    if ((pre_comp = ec_pre_comp_new(group)) == NULL)
-+        return 0;
-+
-+    generator = EC_GROUP_get0_generator(group);
-+    if (generator == NULL) {
-+        ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
-+        goto err;
-+    }
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            goto err;
-+    }
-+
-+    BN_CTX_start(ctx);
-+
-+    order = EC_GROUP_get0_order(group);
-+    if (order == NULL)
-+        goto err;
-+    if (BN_is_zero(order)) {
-+        ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
-+        goto err;
-+    }
-+
-+    bits = BN_num_bits(order);
-+    /*
-+     * The following parameters mean we precompute (approximately) one point
-+     * per bit. TBD: The combination 8, 4 is perfect for 160 bits; for other
-+     * bit lengths, other parameter combinations might provide better
-+     * efficiency.
-+     */
-+    blocksize = 8;
-+    w = 4;
-+    if (EC_window_bits_for_scalar_size(bits) > w) {
-+        /* let's not make the window too small ... */
-+        w = EC_window_bits_for_scalar_size(bits);
-+    }
-+
-+    numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks
-+                                                     * to use for wNAF
-+                                                     * splitting */
-+
-+    pre_points_per_block = (size_t)1 << (w - 1);
-+    num = pre_points_per_block * numblocks; /* number of points to compute
-+                                             * and store */
-+
-+    points = OPENSSL_malloc(sizeof(*points) * (num + 1));
-+    if (points == NULL) {
-+        ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    var = points;
-+    var[num] = NULL;            /* pivot */
-+    for (i = 0; i < num; i++) {
-+        if ((var[i] = EC_POINT_new(group)) == NULL) {
-+            ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    }
-+
-+    if ((tmp_point = EC_POINT_new(group)) == NULL
-+        || (base = EC_POINT_new(group)) == NULL) {
-+        ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (!EC_POINT_copy(base, generator))
-+        goto err;
-+
-+    /* do the precomputation */
-+    for (i = 0; i < numblocks; i++) {
-+        size_t j;
-+
-+        if (!EC_POINT_dbl(group, tmp_point, base, ctx))
-+            goto err;
-+
-+        if (!EC_POINT_copy(*var++, base))
-+            goto err;
-+
-+        for (j = 1; j < pre_points_per_block; j++, var++) {
-+            /*
-+             * calculate odd multiples of the current base point
-+             */
-+            if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
-+                goto err;
-+        }
-+
-+        if (i < numblocks - 1) {
-+            /*
-+             * get the next base (multiply current one by 2^blocksize)
-+             */
-+            size_t k;
-+
-+            if (blocksize <= 2) {
-+                ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
-+                goto err;
-+            }
-+
-+            if (!EC_POINT_dbl(group, base, tmp_point, ctx))
-+                goto err;
-+            for (k = 2; k < blocksize; k++) {
-+                if (!EC_POINT_dbl(group, base, base, ctx))
-+                    goto err;
-+            }
-+        }
-+    }
-+
-+    if (!EC_POINTs_make_affine(group, num, points, ctx))
-+        goto err;
-+
-+    pre_comp->group = group;
-+    pre_comp->blocksize = blocksize;
-+    pre_comp->numblocks = numblocks;
-+    pre_comp->w = w;
-+    pre_comp->points = points;
-+    points = NULL;
-+    pre_comp->num = num;
-+    SETPRECOMP(group, ec, pre_comp);
-+    pre_comp = NULL;
-+    ret = 1;
-+
-+ err:
-+    if (ctx != NULL)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    EC_ec_pre_comp_free(pre_comp);
-+    if (points) {
-+        EC_POINT **p;
-+
-+        for (p = points; *p != NULL; p++)
-+            EC_POINT_free(*p);
-+        OPENSSL_free(points);
-+    }
-+    EC_POINT_free(tmp_point);
-+    EC_POINT_free(base);
-+    return ret;
-+}
-+
-+int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
-+{
-+    return HAVEPRECOMP(group, ec);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_oct.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_oct.c
-new file mode 100644
-index 0000000..effc42a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_oct.c
-@@ -0,0 +1,165 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * Binary polynomial ECC support in OpenSSL originally developed by
-+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
-+ */
-+
-+#include 
-+
-+#include 
-+#include 
-+
-+#include "ec_lcl.h"
-+
-+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
-+                                            EC_POINT *point, const BIGNUM *x,
-+                                            int y_bit, BN_CTX *ctx)
-+{
-+    if (group->meth->point_set_compressed_coordinates == 0
-+        && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
-+        ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
-+              EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
-+        if (group->meth->field_type == NID_X9_62_prime_field)
-+            return ec_GFp_simple_set_compressed_coordinates(group, point, x,
-+                                                            y_bit, ctx);
-+        else
-+#ifdef OPENSSL_NO_EC2M
-+        {
-+            ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
-+                  EC_R_GF2M_NOT_SUPPORTED);
-+            return 0;
-+        }
-+#else
-+            return ec_GF2m_simple_set_compressed_coordinates(group, point, x,
-+                                                             y_bit, ctx);
-+#endif
-+    }
-+    return group->meth->point_set_compressed_coordinates(group, point, x,
-+                                                         y_bit, ctx);
-+}
-+
-+#ifndef OPENSSL_NO_EC2M
-+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group,
-+                                             EC_POINT *point, const BIGNUM *x,
-+                                             int y_bit, BN_CTX *ctx)
-+{
-+    if (group->meth->point_set_compressed_coordinates == 0
-+        && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
-+        ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M,
-+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M,
-+              EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
-+        if (group->meth->field_type == NID_X9_62_prime_field)
-+            return ec_GFp_simple_set_compressed_coordinates(group, point, x,
-+                                                            y_bit, ctx);
-+        else
-+            return ec_GF2m_simple_set_compressed_coordinates(group, point, x,
-+                                                             y_bit, ctx);
-+    }
-+    return group->meth->point_set_compressed_coordinates(group, point, x,
-+                                                         y_bit, ctx);
-+}
-+#endif
-+
-+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
-+                          point_conversion_form_t form, unsigned char *buf,
-+                          size_t len, BN_CTX *ctx)
-+{
-+    if (group->meth->point2oct == 0
-+        && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
-+        ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
-+        if (group->meth->field_type == NID_X9_62_prime_field)
-+            return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
-+        else
-+#ifdef OPENSSL_NO_EC2M
-+        {
-+            ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
-+            return 0;
-+        }
-+#else
-+            return ec_GF2m_simple_point2oct(group, point,
-+                                            form, buf, len, ctx);
-+#endif
-+    }
-+
-+    return group->meth->point2oct(group, point, form, buf, len, ctx);
-+}
-+
-+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
-+                       const unsigned char *buf, size_t len, BN_CTX *ctx)
-+{
-+    if (group->meth->oct2point == 0
-+        && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
-+        ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+        return 0;
-+    }
-+    if (group->meth != point->meth) {
-+        ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+    if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
-+        if (group->meth->field_type == NID_X9_62_prime_field)
-+            return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
-+        else
-+#ifdef OPENSSL_NO_EC2M
-+        {
-+            ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
-+            return 0;
-+        }
-+#else
-+            return ec_GF2m_simple_oct2point(group, point, buf, len, ctx);
-+#endif
-+    }
-+    return group->meth->oct2point(group, point, buf, len, ctx);
-+}
-+
-+size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
-+                          point_conversion_form_t form,
-+                          unsigned char **pbuf, BN_CTX *ctx)
-+{
-+    size_t len;
-+    unsigned char *buf;
-+    len = EC_POINT_point2oct(group, point, form, NULL, 0, NULL);
-+    if (len == 0)
-+        return 0;
-+    buf = OPENSSL_malloc(len);
-+    if (buf == NULL)
-+        return 0;
-+    len = EC_POINT_point2oct(group, point, form, buf, len, ctx);
-+    if (len == 0) {
-+        OPENSSL_free(buf);
-+        return 0;
-+    }
-+    *pbuf = buf;
-+    return len;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_pmeth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_pmeth.c
-new file mode 100644
-index 0000000..68ff2bb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_pmeth.c
-@@ -0,0 +1,463 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "ec_lcl.h"
-+#include 
-+#include "internal/evp_int.h"
-+
-+/* EC pkey context structure */
-+
-+typedef struct {
-+    /* Key and paramgen group */
-+    EC_GROUP *gen_group;
-+    /* message digest */
-+    const EVP_MD *md;
-+    /* Duplicate key if custom cofactor needed */
-+    EC_KEY *co_key;
-+    /* Cofactor mode */
-+    signed char cofactor_mode;
-+    /* KDF (if any) to use for ECDH */
-+    char kdf_type;
-+    /* Message digest to use for key derivation */
-+    const EVP_MD *kdf_md;
-+    /* User key material */
-+    unsigned char *kdf_ukm;
-+    size_t kdf_ukmlen;
-+    /* KDF output length */
-+    size_t kdf_outlen;
-+} EC_PKEY_CTX;
-+
-+static int pkey_ec_init(EVP_PKEY_CTX *ctx)
-+{
-+    EC_PKEY_CTX *dctx;
-+
-+    dctx = OPENSSL_zalloc(sizeof(*dctx));
-+    if (dctx == NULL)
-+        return 0;
-+
-+    dctx->cofactor_mode = -1;
-+    dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
-+    ctx->data = dctx;
-+    return 1;
-+}
-+
-+static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
-+{
-+    EC_PKEY_CTX *dctx, *sctx;
-+    if (!pkey_ec_init(dst))
-+        return 0;
-+    sctx = src->data;
-+    dctx = dst->data;
-+    if (sctx->gen_group) {
-+        dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
-+        if (!dctx->gen_group)
-+            return 0;
-+    }
-+    dctx->md = sctx->md;
-+
-+    if (sctx->co_key) {
-+        dctx->co_key = EC_KEY_dup(sctx->co_key);
-+        if (!dctx->co_key)
-+            return 0;
-+    }
-+    dctx->kdf_type = sctx->kdf_type;
-+    dctx->kdf_md = sctx->kdf_md;
-+    dctx->kdf_outlen = sctx->kdf_outlen;
-+    if (sctx->kdf_ukm) {
-+        dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
-+        if (!dctx->kdf_ukm)
-+            return 0;
-+    } else
-+        dctx->kdf_ukm = NULL;
-+    dctx->kdf_ukmlen = sctx->kdf_ukmlen;
-+    return 1;
-+}
-+
-+static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
-+{
-+    EC_PKEY_CTX *dctx = ctx->data;
-+    if (dctx) {
-+        EC_GROUP_free(dctx->gen_group);
-+        EC_KEY_free(dctx->co_key);
-+        OPENSSL_free(dctx->kdf_ukm);
-+        OPENSSL_free(dctx);
-+    }
-+}
-+
-+static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
-+                        const unsigned char *tbs, size_t tbslen)
-+{
-+    int ret, type;
-+    unsigned int sltmp;
-+    EC_PKEY_CTX *dctx = ctx->data;
-+    EC_KEY *ec = ctx->pkey->pkey.ec;
-+
-+    if (!sig) {
-+        *siglen = ECDSA_size(ec);
-+        return 1;
-+    } else if (*siglen < (size_t)ECDSA_size(ec)) {
-+        ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
-+        return 0;
-+    }
-+
-+    if (dctx->md)
-+        type = EVP_MD_type(dctx->md);
-+    else
-+        type = NID_sha1;
-+
-+    ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
-+
-+    if (ret <= 0)
-+        return ret;
-+    *siglen = (size_t)sltmp;
-+    return 1;
-+}
-+
-+static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
-+                          const unsigned char *sig, size_t siglen,
-+                          const unsigned char *tbs, size_t tbslen)
-+{
-+    int ret, type;
-+    EC_PKEY_CTX *dctx = ctx->data;
-+    EC_KEY *ec = ctx->pkey->pkey.ec;
-+
-+    if (dctx->md)
-+        type = EVP_MD_type(dctx->md);
-+    else
-+        type = NID_sha1;
-+
-+    ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
-+
-+    return ret;
-+}
-+
-+#ifndef OPENSSL_NO_EC
-+static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
-+                          size_t *keylen)
-+{
-+    int ret;
-+    size_t outlen;
-+    const EC_POINT *pubkey = NULL;
-+    EC_KEY *eckey;
-+    EC_PKEY_CTX *dctx = ctx->data;
-+    if (!ctx->pkey || !ctx->peerkey) {
-+        ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
-+        return 0;
-+    }
-+
-+    eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
-+
-+    if (!key) {
-+        const EC_GROUP *group;
-+        group = EC_KEY_get0_group(eckey);
-+        *keylen = (EC_GROUP_get_degree(group) + 7) / 8;
-+        return 1;
-+    }
-+    pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
-+
-+    /*
-+     * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not
-+     * an error, the result is truncated.
-+     */
-+
-+    outlen = *keylen;
-+
-+    ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0);
-+    if (ret <= 0)
-+        return 0;
-+    *keylen = ret;
-+    return 1;
-+}
-+
-+static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
-+                              unsigned char *key, size_t *keylen)
-+{
-+    EC_PKEY_CTX *dctx = ctx->data;
-+    unsigned char *ktmp = NULL;
-+    size_t ktmplen;
-+    int rv = 0;
-+    if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE)
-+        return pkey_ec_derive(ctx, key, keylen);
-+    if (!key) {
-+        *keylen = dctx->kdf_outlen;
-+        return 1;
-+    }
-+    if (*keylen != dctx->kdf_outlen)
-+        return 0;
-+    if (!pkey_ec_derive(ctx, NULL, &ktmplen))
-+        return 0;
-+    ktmp = OPENSSL_malloc(ktmplen);
-+    if (ktmp == NULL)
-+        return 0;
-+    if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
-+        goto err;
-+    /* Do KDF stuff */
-+    if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen,
-+                        dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
-+        goto err;
-+    rv = 1;
-+
-+ err:
-+    OPENSSL_clear_free(ktmp, ktmplen);
-+    return rv;
-+}
-+#endif
-+
-+static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-+{
-+    EC_PKEY_CTX *dctx = ctx->data;
-+    EC_GROUP *group;
-+    switch (type) {
-+    case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
-+        group = EC_GROUP_new_by_curve_name(p1);
-+        if (group == NULL) {
-+            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
-+            return 0;
-+        }
-+        EC_GROUP_free(dctx->gen_group);
-+        dctx->gen_group = group;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_EC_PARAM_ENC:
-+        if (!dctx->gen_group) {
-+            ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
-+            return 0;
-+        }
-+        EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
-+        return 1;
-+
-+#ifndef OPENSSL_NO_EC
-+    case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
-+        if (p1 == -2) {
-+            if (dctx->cofactor_mode != -1)
-+                return dctx->cofactor_mode;
-+            else {
-+                EC_KEY *ec_key = ctx->pkey->pkey.ec;
-+                return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 :
-+                    0;
-+            }
-+        } else if (p1 < -1 || p1 > 1)
-+            return -2;
-+        dctx->cofactor_mode = p1;
-+        if (p1 != -1) {
-+            EC_KEY *ec_key = ctx->pkey->pkey.ec;
-+            if (!ec_key->group)
-+                return -2;
-+            /* If cofactor is 1 cofactor mode does nothing */
-+            if (BN_is_one(ec_key->group->cofactor))
-+                return 1;
-+            if (!dctx->co_key) {
-+                dctx->co_key = EC_KEY_dup(ec_key);
-+                if (!dctx->co_key)
-+                    return 0;
-+            }
-+            if (p1)
-+                EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
-+            else
-+                EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
-+        } else {
-+            EC_KEY_free(dctx->co_key);
-+            dctx->co_key = NULL;
-+        }
-+        return 1;
-+#endif
-+
-+    case EVP_PKEY_CTRL_EC_KDF_TYPE:
-+        if (p1 == -2)
-+            return dctx->kdf_type;
-+        if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62)
-+            return -2;
-+        dctx->kdf_type = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_EC_KDF_MD:
-+        dctx->kdf_md = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_EC_KDF_MD:
-+        *(const EVP_MD **)p2 = dctx->kdf_md;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
-+        if (p1 <= 0)
-+            return -2;
-+        dctx->kdf_outlen = (size_t)p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
-+        *(int *)p2 = dctx->kdf_outlen;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_EC_KDF_UKM:
-+        OPENSSL_free(dctx->kdf_ukm);
-+        dctx->kdf_ukm = p2;
-+        if (p2)
-+            dctx->kdf_ukmlen = p1;
-+        else
-+            dctx->kdf_ukmlen = 0;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
-+        *(unsigned char **)p2 = dctx->kdf_ukm;
-+        return dctx->kdf_ukmlen;
-+
-+    case EVP_PKEY_CTRL_MD:
-+        if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
-+            EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
-+            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
-+            return 0;
-+        }
-+        dctx->md = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_MD:
-+        *(const EVP_MD **)p2 = dctx->md;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_PEER_KEY:
-+        /* Default behaviour is OK */
-+    case EVP_PKEY_CTRL_DIGESTINIT:
-+    case EVP_PKEY_CTRL_PKCS7_SIGN:
-+    case EVP_PKEY_CTRL_CMS_SIGN:
-+        return 1;
-+
-+    default:
-+        return -2;
-+
-+    }
-+}
-+
-+static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
-+                            const char *type, const char *value)
-+{
-+    if (strcmp(type, "ec_paramgen_curve") == 0) {
-+        int nid;
-+        nid = EC_curve_nist2nid(value);
-+        if (nid == NID_undef)
-+            nid = OBJ_sn2nid(value);
-+        if (nid == NID_undef)
-+            nid = OBJ_ln2nid(value);
-+        if (nid == NID_undef) {
-+            ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
-+            return 0;
-+        }
-+        return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
-+    } else if (strcmp(type, "ec_param_enc") == 0) {
-+        int param_enc;
-+        if (strcmp(value, "explicit") == 0)
-+            param_enc = 0;
-+        else if (strcmp(value, "named_curve") == 0)
-+            param_enc = OPENSSL_EC_NAMED_CURVE;
-+        else
-+            return -2;
-+        return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
-+    } else if (strcmp(type, "ecdh_kdf_md") == 0) {
-+        const EVP_MD *md;
-+        if ((md = EVP_get_digestbyname(value)) == NULL) {
-+            ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST);
-+            return 0;
-+        }
-+        return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md);
-+    } else if (strcmp(type, "ecdh_cofactor_mode") == 0) {
-+        int co_mode;
-+        co_mode = atoi(value);
-+        return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode);
-+    }
-+
-+    return -2;
-+}
-+
-+static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    EC_KEY *ec = NULL;
-+    EC_PKEY_CTX *dctx = ctx->data;
-+    int ret = 0;
-+    if (dctx->gen_group == NULL) {
-+        ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
-+        return 0;
-+    }
-+    ec = EC_KEY_new();
-+    if (ec == NULL)
-+        return 0;
-+    ret = EC_KEY_set_group(ec, dctx->gen_group);
-+    if (ret)
-+        EVP_PKEY_assign_EC_KEY(pkey, ec);
-+    else
-+        EC_KEY_free(ec);
-+    return ret;
-+}
-+
-+static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    EC_KEY *ec = NULL;
-+    EC_PKEY_CTX *dctx = ctx->data;
-+    if (ctx->pkey == NULL && dctx->gen_group == NULL) {
-+        ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
-+        return 0;
-+    }
-+    ec = EC_KEY_new();
-+    if (!ec)
-+        return 0;
-+    EVP_PKEY_assign_EC_KEY(pkey, ec);
-+    if (ctx->pkey) {
-+        /* Note: if error return, pkey is freed by parent routine */
-+        if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
-+            return 0;
-+    } else {
-+        if (!EC_KEY_set_group(ec, dctx->gen_group))
-+            return 0;
-+    }
-+    return EC_KEY_generate_key(pkey->pkey.ec);
-+}
-+
-+const EVP_PKEY_METHOD ec_pkey_meth = {
-+    EVP_PKEY_EC,
-+    0,
-+    pkey_ec_init,
-+    pkey_ec_copy,
-+    pkey_ec_cleanup,
-+
-+    0,
-+    pkey_ec_paramgen,
-+
-+    0,
-+    pkey_ec_keygen,
-+
-+    0,
-+    pkey_ec_sign,
-+
-+    0,
-+    pkey_ec_verify,
-+
-+    0, 0,
-+
-+    0, 0, 0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0,
-+#ifndef OPENSSL_NO_EC
-+    pkey_ec_kdf_derive,
-+#else
-+    0,
-+#endif
-+    pkey_ec_ctrl,
-+    pkey_ec_ctrl_str
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_print.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_print.c
-new file mode 100644
-index 0000000..1afa2ce
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ec_print.c
-@@ -0,0 +1,119 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "ec_lcl.h"
-+
-+BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
-+                          const EC_POINT *point,
-+                          point_conversion_form_t form,
-+                          BIGNUM *ret, BN_CTX *ctx)
-+{
-+    size_t buf_len = 0;
-+    unsigned char *buf;
-+
-+    buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
-+
-+    if (buf_len == 0)
-+        return NULL;
-+
-+    ret = BN_bin2bn(buf, buf_len, ret);
-+
-+    OPENSSL_free(buf);
-+
-+    return ret;
-+}
-+
-+EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
-+                            const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx)
-+{
-+    size_t buf_len = 0;
-+    unsigned char *buf;
-+    EC_POINT *ret;
-+
-+    if ((buf_len = BN_num_bytes(bn)) == 0)
-+        return NULL;
-+    buf = OPENSSL_malloc(buf_len);
-+    if (buf == NULL)
-+        return NULL;
-+
-+    if (!BN_bn2bin(bn, buf)) {
-+        OPENSSL_free(buf);
-+        return NULL;
-+    }
-+
-+    if (point == NULL) {
-+        if ((ret = EC_POINT_new(group)) == NULL) {
-+            OPENSSL_free(buf);
-+            return NULL;
-+        }
-+    } else
-+        ret = point;
-+
-+    if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
-+        if (ret != point)
-+            EC_POINT_clear_free(ret);
-+        OPENSSL_free(buf);
-+        return NULL;
-+    }
-+
-+    OPENSSL_free(buf);
-+    return ret;
-+}
-+
-+static const char *HEX_DIGITS = "0123456789ABCDEF";
-+
-+/* the return value must be freed (using OPENSSL_free()) */
-+char *EC_POINT_point2hex(const EC_GROUP *group,
-+                         const EC_POINT *point,
-+                         point_conversion_form_t form, BN_CTX *ctx)
-+{
-+    char *ret, *p;
-+    size_t buf_len = 0, i;
-+    unsigned char *buf = NULL, *pbuf;
-+
-+    buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
-+
-+    if (buf_len == 0)
-+        return NULL;
-+
-+    ret = OPENSSL_malloc(buf_len * 2 + 2);
-+    if (ret == NULL) {
-+        OPENSSL_free(buf);
-+        return NULL;
-+    }
-+    p = ret;
-+    pbuf = buf;
-+    for (i = buf_len; i > 0; i--) {
-+        int v = (int)*(pbuf++);
-+        *(p++) = HEX_DIGITS[v >> 4];
-+        *(p++) = HEX_DIGITS[v & 0x0F];
-+    }
-+    *p = '\0';
-+
-+    OPENSSL_free(buf);
-+
-+    return ret;
-+}
-+
-+EC_POINT *EC_POINT_hex2point(const EC_GROUP *group,
-+                             const char *buf, EC_POINT *point, BN_CTX *ctx)
-+{
-+    EC_POINT *ret = NULL;
-+    BIGNUM *tmp_bn = NULL;
-+
-+    if (!BN_hex2bn(&tmp_bn, buf))
-+        return NULL;
-+
-+    ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
-+
-+    BN_clear_free(tmp_bn);
-+
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdh_kdf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdh_kdf.c
-new file mode 100644
-index 0000000..d47486e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdh_kdf.c
-@@ -0,0 +1,68 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* Key derivation function from X9.62/SECG */
-+/* Way more than we will ever need */
-+#define ECDH_KDF_MAX    (1 << 30)
-+
-+int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
-+                   const unsigned char *Z, size_t Zlen,
-+                   const unsigned char *sinfo, size_t sinfolen,
-+                   const EVP_MD *md)
-+{
-+    EVP_MD_CTX *mctx = NULL;
-+    int rv = 0;
-+    unsigned int i;
-+    size_t mdlen;
-+    unsigned char ctr[4];
-+    if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX
-+        || Zlen > ECDH_KDF_MAX)
-+        return 0;
-+    mctx = EVP_MD_CTX_new();
-+    if (mctx == NULL)
-+        return 0;
-+    mdlen = EVP_MD_size(md);
-+    for (i = 1;; i++) {
-+        unsigned char mtmp[EVP_MAX_MD_SIZE];
-+        if (!EVP_DigestInit_ex(mctx, md, NULL))
-+            goto err;
-+        ctr[3] = i & 0xFF;
-+        ctr[2] = (i >> 8) & 0xFF;
-+        ctr[1] = (i >> 16) & 0xFF;
-+        ctr[0] = (i >> 24) & 0xFF;
-+        if (!EVP_DigestUpdate(mctx, Z, Zlen))
-+            goto err;
-+        if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr)))
-+            goto err;
-+        if (!EVP_DigestUpdate(mctx, sinfo, sinfolen))
-+            goto err;
-+        if (outlen >= mdlen) {
-+            if (!EVP_DigestFinal(mctx, out, NULL))
-+                goto err;
-+            outlen -= mdlen;
-+            if (outlen == 0)
-+                break;
-+            out += mdlen;
-+        } else {
-+            if (!EVP_DigestFinal(mctx, mtmp, NULL))
-+                goto err;
-+            memcpy(out, mtmp, outlen);
-+            OPENSSL_cleanse(mtmp, mdlen);
-+            break;
-+        }
-+    }
-+    rv = 1;
-+ err:
-+    EVP_MD_CTX_free(mctx);
-+    return rv;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdh_ossl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdh_ossl.c
-new file mode 100644
-index 0000000..caf65de
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdh_ossl.c
-@@ -0,0 +1,143 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ *
-+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
-+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
-+ * to the OpenSSL project.
-+ *
-+ * The ECC Code is licensed pursuant to the OpenSSL open source
-+ * license provided below.
-+ *
-+ * The ECDH software is originally written by Douglas Stebila of
-+ * Sun Microsystems Laboratories.
-+ *
-+ */
-+
-+#include 
-+#include 
-+
-+#include "internal/cryptlib.h"
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "ec_lcl.h"
-+
-+int ossl_ecdh_compute_key(unsigned char **psec, size_t *pseclen,
-+                          const EC_POINT *pub_key, const EC_KEY *ecdh)
-+{
-+    if (ecdh->group->meth->ecdh_compute_key == NULL) {
-+        ECerr(EC_F_OSSL_ECDH_COMPUTE_KEY, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH);
-+        return 0;
-+    }
-+
-+    return ecdh->group->meth->ecdh_compute_key(psec, pseclen, pub_key, ecdh);
-+}
-+
-+/*-
-+ * This implementation is based on the following primitives in the IEEE 1363 standard:
-+ *  - ECKAS-DH1
-+ *  - ECSVDP-DH
-+ */
-+int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
-+                            const EC_POINT *pub_key, const EC_KEY *ecdh)
-+{
-+    BN_CTX *ctx;
-+    EC_POINT *tmp = NULL;
-+    BIGNUM *x = NULL, *y = NULL;
-+    const BIGNUM *priv_key;
-+    const EC_GROUP *group;
-+    int ret = 0;
-+    size_t buflen, len;
-+    unsigned char *buf = NULL;
-+
-+    if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    x = BN_CTX_get(ctx);
-+    y = BN_CTX_get(ctx);
-+
-+    priv_key = EC_KEY_get0_private_key(ecdh);
-+    if (priv_key == NULL) {
-+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_NO_PRIVATE_VALUE);
-+        goto err;
-+    }
-+
-+    group = EC_KEY_get0_group(ecdh);
-+
-+    if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) {
-+        if (!EC_GROUP_get_cofactor(group, x, NULL) ||
-+            !BN_mul(x, x, priv_key, ctx)) {
-+            ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        priv_key = x;
-+    }
-+
-+    if ((tmp = EC_POINT_new(group)) == NULL) {
-+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) {
-+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
-+        NID_X9_62_prime_field) {
-+        if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) {
-+            ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
-+            goto err;
-+        }
-+    }
-+#ifndef OPENSSL_NO_EC2M
-+    else {
-+        if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) {
-+            ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
-+            goto err;
-+        }
-+    }
-+#endif
-+
-+    buflen = (EC_GROUP_get_degree(group) + 7) / 8;
-+    len = BN_num_bytes(x);
-+    if (len > buflen) {
-+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
-+        goto err;
-+    }
-+    if ((buf = OPENSSL_malloc(buflen)) == NULL) {
-+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    memset(buf, 0, buflen - len);
-+    if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) {
-+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+
-+    *pout = buf;
-+    *poutlen = buflen;
-+    buf = NULL;
-+
-+    ret = 1;
-+
-+ err:
-+    EC_POINT_free(tmp);
-+    if (ctx)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    OPENSSL_free(buf);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_ossl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_ossl.c
-new file mode 100644
-index 0000000..d67c485
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_ossl.c
-@@ -0,0 +1,462 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "ec_lcl.h"
-+
-+int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
-+                    unsigned char *sig, unsigned int *siglen,
-+                    const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
-+{
-+    ECDSA_SIG *s;
-+    RAND_seed(dgst, dlen);
-+    s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
-+    if (s == NULL) {
-+        *siglen = 0;
-+        return 0;
-+    }
-+    *siglen = i2d_ECDSA_SIG(s, &sig);
-+    ECDSA_SIG_free(s);
-+    return 1;
-+}
-+
-+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
-+                            BIGNUM **kinvp, BIGNUM **rp,
-+                            const unsigned char *dgst, int dlen)
-+{
-+    BN_CTX *ctx = NULL;
-+    BIGNUM *k = NULL, *r = NULL, *X = NULL;
-+    const BIGNUM *order;
-+    EC_POINT *tmp_point = NULL;
-+    const EC_GROUP *group;
-+    int ret = 0;
-+
-+    if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
-+        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+
-+    if (!EC_KEY_can_sign(eckey)) {
-+        ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
-+        return 0;
-+    }
-+
-+    if (ctx_in == NULL) {
-+        if ((ctx = BN_CTX_new()) == NULL) {
-+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+    } else
-+        ctx = ctx_in;
-+
-+    k = BN_new();               /* this value is later returned in *kinvp */
-+    r = BN_new();               /* this value is later returned in *rp */
-+    X = BN_new();
-+    if (k == NULL || r == NULL || X == NULL) {
-+        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if ((tmp_point = EC_POINT_new(group)) == NULL) {
-+        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+    order = EC_GROUP_get0_order(group);
-+    if (order == NULL) {
-+        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+
-+    do {
-+        /* get random k */
-+        do
-+            if (dgst != NULL) {
-+                if (!BN_generate_dsa_nonce
-+                    (k, order, EC_KEY_get0_private_key(eckey), dgst, dlen,
-+                     ctx)) {
-+                    ECerr(EC_F_ECDSA_SIGN_SETUP,
-+                             EC_R_RANDOM_NUMBER_GENERATION_FAILED);
-+                    goto err;
-+                }
-+            } else {
-+                if (!BN_rand_range(k, order)) {
-+                    ECerr(EC_F_ECDSA_SIGN_SETUP,
-+                             EC_R_RANDOM_NUMBER_GENERATION_FAILED);
-+                    goto err;
-+                }
-+            }
-+        while (BN_is_zero(k));
-+
-+        /*
-+         * We do not want timing information to leak the length of k, so we
-+         * compute G*k using an equivalent scalar of fixed bit-length.
-+         */
-+
-+        if (!BN_add(k, k, order))
-+            goto err;
-+        if (BN_num_bits(k) <= BN_num_bits(order))
-+            if (!BN_add(k, k, order))
-+                goto err;
-+
-+        /* compute r the x-coordinate of generator * k */
-+        if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
-+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+        if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
-+            NID_X9_62_prime_field) {
-+            if (!EC_POINT_get_affine_coordinates_GFp
-+                (group, tmp_point, X, NULL, ctx)) {
-+                ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
-+                goto err;
-+            }
-+        }
-+#ifndef OPENSSL_NO_EC2M
-+        else {                  /* NID_X9_62_characteristic_two_field */
-+
-+            if (!EC_POINT_get_affine_coordinates_GF2m(group,
-+                                                      tmp_point, X, NULL,
-+                                                      ctx)) {
-+                ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
-+                goto err;
-+            }
-+        }
-+#endif
-+        if (!BN_nnmod(r, X, order, ctx)) {
-+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+    }
-+    while (BN_is_zero(r));
-+
-+    /* compute the inverse of k */
-+    if (EC_GROUP_get_mont_data(group) != NULL) {
-+        /*
-+         * We want inverse in constant time, therefore we utilize the fact
-+         * order must be prime and use Fermats Little Theorem instead.
-+         */
-+        if (!BN_set_word(X, 2)) {
-+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+        if (!BN_mod_sub(X, order, X, order, ctx)) {
-+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+        BN_set_flags(X, BN_FLG_CONSTTIME);
-+        if (!BN_mod_exp_mont_consttime
-+            (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) {
-+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+    } else {
-+        if (!BN_mod_inverse(k, k, order, ctx)) {
-+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+    }
-+
-+    /* clear old values if necessary */
-+    BN_clear_free(*rp);
-+    BN_clear_free(*kinvp);
-+    /* save the pre-computed values  */
-+    *rp = r;
-+    *kinvp = k;
-+    ret = 1;
-+ err:
-+    if (!ret) {
-+        BN_clear_free(k);
-+        BN_clear_free(r);
-+    }
-+    if (ctx != ctx_in)
-+        BN_CTX_free(ctx);
-+    EC_POINT_free(tmp_point);
-+    BN_clear_free(X);
-+    return (ret);
-+}
-+
-+int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
-+                          BIGNUM **rp)
-+{
-+    return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0);
-+}
-+
-+ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
-+                               const BIGNUM *in_kinv, const BIGNUM *in_r,
-+                               EC_KEY *eckey)
-+{
-+    int ok = 0, i;
-+    BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL;
-+    const BIGNUM *order, *ckinv;
-+    BN_CTX *ctx = NULL;
-+    const EC_GROUP *group;
-+    ECDSA_SIG *ret;
-+    const BIGNUM *priv_key;
-+
-+    group = EC_KEY_get0_group(eckey);
-+    priv_key = EC_KEY_get0_private_key(eckey);
-+
-+    if (group == NULL || priv_key == NULL) {
-+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER);
-+        return NULL;
-+    }
-+
-+    if (!EC_KEY_can_sign(eckey)) {
-+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
-+        return NULL;
-+    }
-+
-+    ret = ECDSA_SIG_new();
-+    if (ret == NULL) {
-+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    ret->r = BN_new();
-+    ret->s = BN_new();
-+    if (ret->r == NULL || ret->s == NULL) {
-+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    s = ret->s;
-+
-+    if ((ctx = BN_CTX_new()) == NULL ||
-+        (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
-+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    order = EC_GROUP_get0_order(group);
-+    if (order == NULL) {
-+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+    i = BN_num_bits(order);
-+    /*
-+     * Need to truncate digest if it is too long: first truncate whole bytes.
-+     */
-+    if (8 * dgst_len > i)
-+        dgst_len = (i + 7) / 8;
-+    if (!BN_bin2bn(dgst, dgst_len, m)) {
-+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    /* If still too long truncate remaining bits with a shift */
-+    if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
-+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    do {
-+        if (in_kinv == NULL || in_r == NULL) {
-+            if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) {
-+                ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_ECDSA_LIB);
-+                goto err;
-+            }
-+            ckinv = kinv;
-+        } else {
-+            ckinv = in_kinv;
-+            if (BN_copy(ret->r, in_r) == NULL) {
-+                ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+        }
-+
-+        if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
-+            ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+        if (!BN_mod_add_quick(s, tmp, m, order)) {
-+            ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+        if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
-+            ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+        if (BN_is_zero(s)) {
-+            /*
-+             * if kinv and r have been supplied by the caller don't to
-+             * generate new kinv and r values
-+             */
-+            if (in_kinv != NULL && in_r != NULL) {
-+                ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_NEED_NEW_SETUP_VALUES);
-+                goto err;
-+            }
-+        } else
-+            /* s != 0 => we have a valid signature */
-+            break;
-+    }
-+    while (1);
-+
-+    ok = 1;
-+ err:
-+    if (!ok) {
-+        ECDSA_SIG_free(ret);
-+        ret = NULL;
-+    }
-+    BN_CTX_free(ctx);
-+    BN_clear_free(m);
-+    BN_clear_free(tmp);
-+    BN_clear_free(kinv);
-+    return ret;
-+}
-+
-+/*-
-+ * returns
-+ *      1: correct signature
-+ *      0: incorrect signature
-+ *     -1: error
-+ */
-+int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
-+                      const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
-+{
-+    ECDSA_SIG *s;
-+    const unsigned char *p = sigbuf;
-+    unsigned char *der = NULL;
-+    int derlen = -1;
-+    int ret = -1;
-+
-+    s = ECDSA_SIG_new();
-+    if (s == NULL)
-+        return (ret);
-+    if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
-+        goto err;
-+    /* Ensure signature uses DER and doesn't have trailing garbage */
-+    derlen = i2d_ECDSA_SIG(s, &der);
-+    if (derlen != sig_len || memcmp(sigbuf, der, derlen) != 0)
-+        goto err;
-+    ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);
-+ err:
-+    OPENSSL_clear_free(der, derlen);
-+    ECDSA_SIG_free(s);
-+    return (ret);
-+}
-+
-+int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
-+                          const ECDSA_SIG *sig, EC_KEY *eckey)
-+{
-+    int ret = -1, i;
-+    BN_CTX *ctx;
-+    const BIGNUM *order;
-+    BIGNUM *u1, *u2, *m, *X;
-+    EC_POINT *point = NULL;
-+    const EC_GROUP *group;
-+    const EC_POINT *pub_key;
-+
-+    /* check input values */
-+    if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
-+        (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_MISSING_PARAMETERS);
-+        return -1;
-+    }
-+
-+    if (!EC_KEY_can_sign(eckey)) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
-+        return -1;
-+    }
-+
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
-+        return -1;
-+    }
-+    BN_CTX_start(ctx);
-+    u1 = BN_CTX_get(ctx);
-+    u2 = BN_CTX_get(ctx);
-+    m = BN_CTX_get(ctx);
-+    X = BN_CTX_get(ctx);
-+    if (X == NULL) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+
-+    order = EC_GROUP_get0_order(group);
-+    if (order == NULL) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+
-+    if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
-+        BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
-+        BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_BAD_SIGNATURE);
-+        ret = 0;                /* signature is invalid */
-+        goto err;
-+    }
-+    /* calculate tmp1 = inv(S) mod order */
-+    if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    /* digest -> m */
-+    i = BN_num_bits(order);
-+    /*
-+     * Need to truncate digest if it is too long: first truncate whole bytes.
-+     */
-+    if (8 * dgst_len > i)
-+        dgst_len = (i + 7) / 8;
-+    if (!BN_bin2bn(dgst, dgst_len, m)) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    /* If still too long truncate remaining bits with a shift */
-+    if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    /* u1 = m * tmp mod order */
-+    if (!BN_mod_mul(u1, m, u2, order, ctx)) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    /* u2 = r * w mod q */
-+    if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+
-+    if ((point = EC_POINT_new(group)) == NULL) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
-+        goto err;
-+    }
-+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
-+        NID_X9_62_prime_field) {
-+        if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) {
-+            ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+    }
-+#ifndef OPENSSL_NO_EC2M
-+    else {                      /* NID_X9_62_characteristic_two_field */
-+
-+        if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) {
-+            ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
-+            goto err;
-+        }
-+    }
-+#endif
-+    if (!BN_nnmod(u1, X, order, ctx)) {
-+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    /*  if the signature is correct u1 is equal to sig->r */
-+    ret = (BN_ucmp(u1, sig->r) == 0);
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    EC_POINT_free(point);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_sign.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_sign.c
-new file mode 100644
-index 0000000..aee06e9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_sign.c
-@@ -0,0 +1,52 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "ec_lcl.h"
-+#include 
-+
-+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
-+{
-+    return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey);
-+}
-+
-+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen,
-+                            const BIGNUM *kinv, const BIGNUM *rp,
-+                            EC_KEY *eckey)
-+{
-+    if (eckey->meth->sign_sig != NULL)
-+        return eckey->meth->sign_sig(dgst, dlen, kinv, rp, eckey);
-+    ECerr(EC_F_ECDSA_DO_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
-+    return NULL;
-+}
-+
-+int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char
-+               *sig, unsigned int *siglen, EC_KEY *eckey)
-+{
-+    return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
-+}
-+
-+int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen,
-+                  unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
-+                  const BIGNUM *r, EC_KEY *eckey)
-+{
-+    if (eckey->meth->sign != NULL)
-+        return eckey->meth->sign(type, dgst, dlen, sig, siglen, kinv, r, eckey);
-+    ECerr(EC_F_ECDSA_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
-+    return 0;
-+}
-+
-+int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
-+                     BIGNUM **rp)
-+{
-+    if (eckey->meth->sign_setup != NULL)
-+        return eckey->meth->sign_setup(eckey, ctx_in, kinvp, rp);
-+    ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_OPERATION_NOT_SUPPORTED);
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_vrf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_vrf.c
-new file mode 100644
-index 0000000..f61a200
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecdsa_vrf.c
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "ec_lcl.h"
-+#include 
-+
-+/*-
-+ * returns
-+ *      1: correct signature
-+ *      0: incorrect signature
-+ *     -1: error
-+ */
-+int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
-+                    const ECDSA_SIG *sig, EC_KEY *eckey)
-+{
-+    if (eckey->meth->verify_sig != NULL)
-+        return eckey->meth->verify_sig(dgst, dgst_len, sig, eckey);
-+    ECerr(EC_F_ECDSA_DO_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
-+    return 0;
-+}
-+
-+/*-
-+ * returns
-+ *      1: correct signature
-+ *      0: incorrect signature
-+ *     -1: error
-+ */
-+int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
-+                 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
-+{
-+    if (eckey->meth->verify != NULL)
-+        return eckey->meth->verify(type, dgst, dgst_len, sigbuf, sig_len,
-+                                   eckey);
-+    ECerr(EC_F_ECDSA_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/eck_prn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/eck_prn.c
-new file mode 100644
-index 0000000..dd3f857
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/eck_prn.c
-@@ -0,0 +1,273 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * Portions originally developed by SUN MICROSYSTEMS, INC., and
-+ * contributed to the OpenSSL project.
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+#ifndef OPENSSL_NO_STDIO
-+int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = ECPKParameters_print(b, x, off);
-+    BIO_free(b);
-+    return (ret);
-+}
-+
-+int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = EC_KEY_print(b, x, off);
-+    BIO_free(b);
-+    return (ret);
-+}
-+
-+int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = ECParameters_print(b, x);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-+
-+static int print_bin(BIO *fp, const char *str, const unsigned char *num,
-+                     size_t len, int off);
-+
-+int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
-+{
-+    int ret = 0, reason = ERR_R_BIO_LIB;
-+    BN_CTX *ctx = NULL;
-+    const EC_POINT *point = NULL;
-+    BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL;
-+    const BIGNUM *order = NULL, *cofactor = NULL;
-+    const unsigned char *seed;
-+    size_t seed_len = 0;
-+
-+    static const char *gen_compressed = "Generator (compressed):";
-+    static const char *gen_uncompressed = "Generator (uncompressed):";
-+    static const char *gen_hybrid = "Generator (hybrid):";
-+
-+    if (!x) {
-+        reason = ERR_R_PASSED_NULL_PARAMETER;
-+        goto err;
-+    }
-+
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL) {
-+        reason = ERR_R_MALLOC_FAILURE;
-+        goto err;
-+    }
-+
-+    if (EC_GROUP_get_asn1_flag(x)) {
-+        /* the curve parameter are given by an asn1 OID */
-+        int nid;
-+        const char *nname;
-+
-+        if (!BIO_indent(bp, off, 128))
-+            goto err;
-+
-+        nid = EC_GROUP_get_curve_name(x);
-+        if (nid == 0)
-+            goto err;
-+        if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
-+            goto err;
-+        if (BIO_printf(bp, "\n") <= 0)
-+            goto err;
-+        nname = EC_curve_nid2nist(nid);
-+        if (nname) {
-+            if (!BIO_indent(bp, off, 128))
-+                goto err;
-+            if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0)
-+                goto err;
-+        }
-+    } else {
-+        /* explicit parameters */
-+        int is_char_two = 0;
-+        point_conversion_form_t form;
-+        int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
-+
-+        if (tmp_nid == NID_X9_62_characteristic_two_field)
-+            is_char_two = 1;
-+
-+        if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
-+            (b = BN_new()) == NULL) {
-+            reason = ERR_R_MALLOC_FAILURE;
-+            goto err;
-+        }
-+#ifndef OPENSSL_NO_EC2M
-+        if (is_char_two) {
-+            if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
-+                reason = ERR_R_EC_LIB;
-+                goto err;
-+            }
-+        } else                  /* prime field */
-+#endif
-+        {
-+            if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
-+                reason = ERR_R_EC_LIB;
-+                goto err;
-+            }
-+        }
-+
-+        if ((point = EC_GROUP_get0_generator(x)) == NULL) {
-+            reason = ERR_R_EC_LIB;
-+            goto err;
-+        }
-+        order = EC_GROUP_get0_order(x);
-+        cofactor = EC_GROUP_get0_cofactor(x);
-+        if (order == NULL) {
-+            reason = ERR_R_EC_LIB;
-+            goto err;
-+        }
-+
-+        form = EC_GROUP_get_point_conversion_form(x);
-+
-+        if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) {
-+            reason = ERR_R_EC_LIB;
-+            goto err;
-+        }
-+
-+        if ((seed = EC_GROUP_get0_seed(x)) != NULL)
-+            seed_len = EC_GROUP_get_seed_len(x);
-+
-+        if (!BIO_indent(bp, off, 128))
-+            goto err;
-+
-+        /* print the 'short name' of the field type */
-+        if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
-+            <= 0)
-+            goto err;
-+
-+        if (is_char_two) {
-+            /* print the 'short name' of the base type OID */
-+            int basis_type = EC_GROUP_get_basis_type(x);
-+            if (basis_type == 0)
-+                goto err;
-+
-+            if (!BIO_indent(bp, off, 128))
-+                goto err;
-+
-+            if (BIO_printf(bp, "Basis Type: %s\n",
-+                           OBJ_nid2sn(basis_type)) <= 0)
-+                goto err;
-+
-+            /* print the polynomial */
-+            if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, NULL,
-+                                              off))
-+                goto err;
-+        } else {
-+            if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, NULL, off))
-+                goto err;
-+        }
-+        if ((a != NULL) && !ASN1_bn_print(bp, "A:   ", a, NULL, off))
-+            goto err;
-+        if ((b != NULL) && !ASN1_bn_print(bp, "B:   ", b, NULL, off))
-+            goto err;
-+        if (form == POINT_CONVERSION_COMPRESSED) {
-+            if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
-+                                                NULL, off))
-+                goto err;
-+        } else if (form == POINT_CONVERSION_UNCOMPRESSED) {
-+            if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
-+                                                NULL, off))
-+                goto err;
-+        } else {                /* form == POINT_CONVERSION_HYBRID */
-+
-+            if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
-+                                                NULL, off))
-+                goto err;
-+        }
-+        if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
-+                                              NULL, off))
-+            goto err;
-+        if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
-+                                                 NULL, off))
-+            goto err;
-+        if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
-+            goto err;
-+    }
-+    ret = 1;
-+ err:
-+    if (!ret)
-+        ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
-+    BN_free(p);
-+    BN_free(a);
-+    BN_free(b);
-+    BN_free(gen);
-+    BN_CTX_free(ctx);
-+    return (ret);
-+}
-+
-+static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
-+                     size_t len, int off)
-+{
-+    size_t i;
-+    char str[128];
-+
-+    if (buf == NULL)
-+        return 1;
-+    if (off > 0) {
-+        if (off > 128)
-+            off = 128;
-+        memset(str, ' ', off);
-+        if (BIO_write(fp, str, off) <= 0)
-+            return 0;
-+    } else {
-+        off = 0;
-+    }
-+
-+    if (BIO_printf(fp, "%s", name) <= 0)
-+        return 0;
-+
-+    for (i = 0; i < len; i++) {
-+        if ((i % 15) == 0) {
-+            str[0] = '\n';
-+            memset(&(str[1]), ' ', off + 4);
-+            if (BIO_write(fp, str, off + 1 + 4) <= 0)
-+                return 0;
-+        }
-+        if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <=
-+            0)
-+            return 0;
-+    }
-+    if (BIO_write(fp, "\n", 1) <= 0)
-+        return 0;
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_mont.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_mont.c
-new file mode 100644
-index 0000000..994cc1d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_mont.c
-@@ -0,0 +1,242 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
-+ * and contributed to the OpenSSL project.
-+ */
-+
-+#include 
-+
-+#include "ec_lcl.h"
-+
-+const EC_METHOD *EC_GFp_mont_method(void)
-+{
-+    static const EC_METHOD ret = {
-+        EC_FLAGS_DEFAULT_OCT,
-+        NID_X9_62_prime_field,
-+        ec_GFp_mont_group_init,
-+        ec_GFp_mont_group_finish,
-+        ec_GFp_mont_group_clear_finish,
-+        ec_GFp_mont_group_copy,
-+        ec_GFp_mont_group_set_curve,
-+        ec_GFp_simple_group_get_curve,
-+        ec_GFp_simple_group_get_degree,
-+        ec_group_simple_order_bits,
-+        ec_GFp_simple_group_check_discriminant,
-+        ec_GFp_simple_point_init,
-+        ec_GFp_simple_point_finish,
-+        ec_GFp_simple_point_clear_finish,
-+        ec_GFp_simple_point_copy,
-+        ec_GFp_simple_point_set_to_infinity,
-+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_point_set_affine_coordinates,
-+        ec_GFp_simple_point_get_affine_coordinates,
-+        0, 0, 0,
-+        ec_GFp_simple_add,
-+        ec_GFp_simple_dbl,
-+        ec_GFp_simple_invert,
-+        ec_GFp_simple_is_at_infinity,
-+        ec_GFp_simple_is_on_curve,
-+        ec_GFp_simple_cmp,
-+        ec_GFp_simple_make_affine,
-+        ec_GFp_simple_points_make_affine,
-+        0 /* mul */ ,
-+        0 /* precompute_mult */ ,
-+        0 /* have_precompute_mult */ ,
-+        ec_GFp_mont_field_mul,
-+        ec_GFp_mont_field_sqr,
-+        0 /* field_div */ ,
-+        ec_GFp_mont_field_encode,
-+        ec_GFp_mont_field_decode,
-+        ec_GFp_mont_field_set_to_one,
-+        ec_key_simple_priv2oct,
-+        ec_key_simple_oct2priv,
-+        0, /* set private */
-+        ec_key_simple_generate_key,
-+        ec_key_simple_check_key,
-+        ec_key_simple_generate_public_key,
-+        0, /* keycopy */
-+        0, /* keyfinish */
-+        ecdh_simple_compute_key
-+    };
-+
-+    return &ret;
-+}
-+
-+int ec_GFp_mont_group_init(EC_GROUP *group)
-+{
-+    int ok;
-+
-+    ok = ec_GFp_simple_group_init(group);
-+    group->field_data1 = NULL;
-+    group->field_data2 = NULL;
-+    return ok;
-+}
-+
-+void ec_GFp_mont_group_finish(EC_GROUP *group)
-+{
-+    BN_MONT_CTX_free(group->field_data1);
-+    group->field_data1 = NULL;
-+    BN_free(group->field_data2);
-+    group->field_data2 = NULL;
-+    ec_GFp_simple_group_finish(group);
-+}
-+
-+void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
-+{
-+    BN_MONT_CTX_free(group->field_data1);
-+    group->field_data1 = NULL;
-+    BN_clear_free(group->field_data2);
-+    group->field_data2 = NULL;
-+    ec_GFp_simple_group_clear_finish(group);
-+}
-+
-+int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
-+{
-+    BN_MONT_CTX_free(dest->field_data1);
-+    dest->field_data1 = NULL;
-+    BN_clear_free(dest->field_data2);
-+    dest->field_data2 = NULL;
-+
-+    if (!ec_GFp_simple_group_copy(dest, src))
-+        return 0;
-+
-+    if (src->field_data1 != NULL) {
-+        dest->field_data1 = BN_MONT_CTX_new();
-+        if (dest->field_data1 == NULL)
-+            return 0;
-+        if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1))
-+            goto err;
-+    }
-+    if (src->field_data2 != NULL) {
-+        dest->field_data2 = BN_dup(src->field_data2);
-+        if (dest->field_data2 == NULL)
-+            goto err;
-+    }
-+
-+    return 1;
-+
-+ err:
-+    BN_MONT_CTX_free(dest->field_data1);
-+    dest->field_data1 = NULL;
-+    return 0;
-+}
-+
-+int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
-+                                const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
-+{
-+    BN_CTX *new_ctx = NULL;
-+    BN_MONT_CTX *mont = NULL;
-+    BIGNUM *one = NULL;
-+    int ret = 0;
-+
-+    BN_MONT_CTX_free(group->field_data1);
-+    group->field_data1 = NULL;
-+    BN_free(group->field_data2);
-+    group->field_data2 = NULL;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return 0;
-+    }
-+
-+    mont = BN_MONT_CTX_new();
-+    if (mont == NULL)
-+        goto err;
-+    if (!BN_MONT_CTX_set(mont, p, ctx)) {
-+        ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    one = BN_new();
-+    if (one == NULL)
-+        goto err;
-+    if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
-+        goto err;
-+
-+    group->field_data1 = mont;
-+    mont = NULL;
-+    group->field_data2 = one;
-+    one = NULL;
-+
-+    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
-+
-+    if (!ret) {
-+        BN_MONT_CTX_free(group->field_data1);
-+        group->field_data1 = NULL;
-+        BN_free(group->field_data2);
-+        group->field_data2 = NULL;
-+    }
-+
-+ err:
-+    BN_free(one);
-+    BN_CTX_free(new_ctx);
-+    BN_MONT_CTX_free(mont);
-+    return ret;
-+}
-+
-+int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
-+                          const BIGNUM *b, BN_CTX *ctx)
-+{
-+    if (group->field_data1 == NULL) {
-+        ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
-+        return 0;
-+    }
-+
-+    return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
-+}
-+
-+int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
-+                          BN_CTX *ctx)
-+{
-+    if (group->field_data1 == NULL) {
-+        ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
-+        return 0;
-+    }
-+
-+    return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
-+}
-+
-+int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r,
-+                             const BIGNUM *a, BN_CTX *ctx)
-+{
-+    if (group->field_data1 == NULL) {
-+        ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
-+        return 0;
-+    }
-+
-+    return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
-+}
-+
-+int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r,
-+                             const BIGNUM *a, BN_CTX *ctx)
-+{
-+    if (group->field_data1 == NULL) {
-+        ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
-+        return 0;
-+    }
-+
-+    return BN_from_montgomery(r, a, group->field_data1, ctx);
-+}
-+
-+int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
-+                                 BN_CTX *ctx)
-+{
-+    if (group->field_data2 == NULL) {
-+        ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
-+        return 0;
-+    }
-+
-+    if (!BN_copy(r, group->field_data2))
-+        return 0;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nist.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nist.c
-new file mode 100644
-index 0000000..615563b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nist.c
-@@ -0,0 +1,167 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
-+ * and contributed to the OpenSSL project.
-+ */
-+
-+#include 
-+
-+#include 
-+#include 
-+#include "ec_lcl.h"
-+
-+const EC_METHOD *EC_GFp_nist_method(void)
-+{
-+    static const EC_METHOD ret = {
-+        EC_FLAGS_DEFAULT_OCT,
-+        NID_X9_62_prime_field,
-+        ec_GFp_simple_group_init,
-+        ec_GFp_simple_group_finish,
-+        ec_GFp_simple_group_clear_finish,
-+        ec_GFp_nist_group_copy,
-+        ec_GFp_nist_group_set_curve,
-+        ec_GFp_simple_group_get_curve,
-+        ec_GFp_simple_group_get_degree,
-+        ec_group_simple_order_bits,
-+        ec_GFp_simple_group_check_discriminant,
-+        ec_GFp_simple_point_init,
-+        ec_GFp_simple_point_finish,
-+        ec_GFp_simple_point_clear_finish,
-+        ec_GFp_simple_point_copy,
-+        ec_GFp_simple_point_set_to_infinity,
-+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_point_set_affine_coordinates,
-+        ec_GFp_simple_point_get_affine_coordinates,
-+        0, 0, 0,
-+        ec_GFp_simple_add,
-+        ec_GFp_simple_dbl,
-+        ec_GFp_simple_invert,
-+        ec_GFp_simple_is_at_infinity,
-+        ec_GFp_simple_is_on_curve,
-+        ec_GFp_simple_cmp,
-+        ec_GFp_simple_make_affine,
-+        ec_GFp_simple_points_make_affine,
-+        0 /* mul */ ,
-+        0 /* precompute_mult */ ,
-+        0 /* have_precompute_mult */ ,
-+        ec_GFp_nist_field_mul,
-+        ec_GFp_nist_field_sqr,
-+        0 /* field_div */ ,
-+        0 /* field_encode */ ,
-+        0 /* field_decode */ ,
-+        0,                      /* field_set_to_one */
-+        ec_key_simple_priv2oct,
-+        ec_key_simple_oct2priv,
-+        0, /* set private */
-+        ec_key_simple_generate_key,
-+        ec_key_simple_check_key,
-+        ec_key_simple_generate_public_key,
-+        0, /* keycopy */
-+        0, /* keyfinish */
-+        ecdh_simple_compute_key
-+    };
-+
-+    return &ret;
-+}
-+
-+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
-+{
-+    dest->field_mod_func = src->field_mod_func;
-+
-+    return ec_GFp_simple_group_copy(dest, src);
-+}
-+
-+int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
-+                                const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BN_CTX *new_ctx = NULL;
-+
-+    if (ctx == NULL)
-+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+
-+    BN_CTX_start(ctx);
-+
-+    if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
-+        group->field_mod_func = BN_nist_mod_192;
-+    else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
-+        group->field_mod_func = BN_nist_mod_224;
-+    else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
-+        group->field_mod_func = BN_nist_mod_256;
-+    else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
-+        group->field_mod_func = BN_nist_mod_384;
-+    else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
-+        group->field_mod_func = BN_nist_mod_521;
-+    else {
-+        ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
-+        goto err;
-+    }
-+
-+    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
-+                          const BIGNUM *b, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BN_CTX *ctx_new = NULL;
-+
-+    if (!group || !r || !a || !b) {
-+        ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
-+        goto err;
-+    }
-+    if (!ctx)
-+        if ((ctx_new = ctx = BN_CTX_new()) == NULL)
-+            goto err;
-+
-+    if (!BN_mul(r, a, b, ctx))
-+        goto err;
-+    if (!group->field_mod_func(r, r, group->field, ctx))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    BN_CTX_free(ctx_new);
-+    return ret;
-+}
-+
-+int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
-+                          BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BN_CTX *ctx_new = NULL;
-+
-+    if (!group || !r || !a) {
-+        ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
-+        goto err;
-+    }
-+    if (!ctx)
-+        if ((ctx_new = ctx = BN_CTX_new()) == NULL)
-+            goto err;
-+
-+    if (!BN_sqr(r, a, ctx))
-+        goto err;
-+    if (!group->field_mod_func(r, r, group->field, ctx))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    BN_CTX_free(ctx_new);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp224.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp224.c
-new file mode 100644
-index 0000000..0c11abc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp224.c
-@@ -0,0 +1,1717 @@
-+/*
-+ * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Copyright 2011 Google Inc.
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the "License");
-+ *
-+ * you may not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ *     http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+
-+/*
-+ * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
-+ *
-+ * Inspired by Daniel J. Bernstein's public domain nistp224 implementation
-+ * and Adam Langley's public domain 64-bit C implementation of curve25519
-+ */
-+
-+#include 
-+#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+# include 
-+# include 
-+# include "ec_lcl.h"
-+
-+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-+  /* even with gcc, the typedef won't work for 32-bit platforms */
-+typedef __uint128_t uint128_t;  /* nonstandard; implemented by gcc on 64-bit
-+                                 * platforms */
-+# else
-+#  error "Need GCC 3.1 or later to define type uint128_t"
-+# endif
-+
-+typedef uint8_t u8;
-+typedef uint64_t u64;
-+typedef int64_t s64;
-+
-+/******************************************************************************/
-+/*-
-+ * INTERNAL REPRESENTATION OF FIELD ELEMENTS
-+ *
-+ * Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
-+ * using 64-bit coefficients called 'limbs',
-+ * and sometimes (for multiplication results) as
-+ * b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + 2^336*b_6
-+ * using 128-bit coefficients called 'widelimbs'.
-+ * A 4-limb representation is an 'felem';
-+ * a 7-widelimb representation is a 'widefelem'.
-+ * Even within felems, bits of adjacent limbs overlap, and we don't always
-+ * reduce the representations: we ensure that inputs to each felem
-+ * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60,
-+ * and fit into a 128-bit word without overflow. The coefficients are then
-+ * again partially reduced to obtain an felem satisfying a_i < 2^57.
-+ * We only reduce to the unique minimal representation at the end of the
-+ * computation.
-+ */
-+
-+typedef uint64_t limb;
-+typedef uint128_t widelimb;
-+
-+typedef limb felem[4];
-+typedef widelimb widefelem[7];
-+
-+/*
-+ * Field element represented as a byte arrary. 28*8 = 224 bits is also the
-+ * group order size for the elliptic curve, and we also use this type for
-+ * scalars for point multiplication.
-+ */
-+typedef u8 felem_bytearray[28];
-+
-+static const felem_bytearray nistp224_curve_params[5] = {
-+    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
-+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
-+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
-+    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
-+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
-+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE},
-+    {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */
-+     0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA,
-+     0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4},
-+    {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */
-+     0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22,
-+     0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21},
-+    {0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */
-+     0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
-+     0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34}
-+};
-+
-+/*-
-+ * Precomputed multiples of the standard generator
-+ * Points are given in coordinates (X, Y, Z) where Z normally is 1
-+ * (0 for the point at infinity).
-+ * For each field element, slice a_0 is word 0, etc.
-+ *
-+ * The table has 2 * 16 elements, starting with the following:
-+ * index | bits    | point
-+ * ------+---------+------------------------------
-+ *     0 | 0 0 0 0 | 0G
-+ *     1 | 0 0 0 1 | 1G
-+ *     2 | 0 0 1 0 | 2^56G
-+ *     3 | 0 0 1 1 | (2^56 + 1)G
-+ *     4 | 0 1 0 0 | 2^112G
-+ *     5 | 0 1 0 1 | (2^112 + 1)G
-+ *     6 | 0 1 1 0 | (2^112 + 2^56)G
-+ *     7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
-+ *     8 | 1 0 0 0 | 2^168G
-+ *     9 | 1 0 0 1 | (2^168 + 1)G
-+ *    10 | 1 0 1 0 | (2^168 + 2^56)G
-+ *    11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
-+ *    12 | 1 1 0 0 | (2^168 + 2^112)G
-+ *    13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
-+ *    14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
-+ *    15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
-+ * followed by a copy of this with each element multiplied by 2^28.
-+ *
-+ * The reason for this is so that we can clock bits into four different
-+ * locations when doing simple scalar multiplies against the base point,
-+ * and then another four locations using the second 16 elements.
-+ */
-+static const felem gmul[2][16][3] = {
-+{{{0, 0, 0, 0},
-+  {0, 0, 0, 0},
-+  {0, 0, 0, 0}},
-+ {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
-+  {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
-+  {1, 0, 0, 0}},
-+ {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
-+  {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
-+  {1, 0, 0, 0}},
-+ {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
-+  {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
-+  {1, 0, 0, 0}},
-+ {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
-+  {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
-+  {1, 0, 0, 0}},
-+ {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
-+  {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
-+  {1, 0, 0, 0}},
-+ {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
-+  {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
-+  {1, 0, 0, 0}},
-+ {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
-+  {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
-+  {1, 0, 0, 0}},
-+ {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
-+  {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
-+  {1, 0, 0, 0}},
-+ {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
-+  {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
-+  {1, 0, 0, 0}},
-+ {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
-+  {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
-+  {1, 0, 0, 0}},
-+ {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
-+  {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
-+  {1, 0, 0, 0}},
-+ {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
-+  {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
-+  {1, 0, 0, 0}},
-+ {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
-+  {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
-+  {1, 0, 0, 0}},
-+ {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
-+  {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
-+  {1, 0, 0, 0}},
-+ {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
-+  {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
-+  {1, 0, 0, 0}}},
-+{{{0, 0, 0, 0},
-+  {0, 0, 0, 0},
-+  {0, 0, 0, 0}},
-+ {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
-+  {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
-+  {1, 0, 0, 0}},
-+ {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
-+  {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
-+  {1, 0, 0, 0}},
-+ {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
-+  {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
-+  {1, 0, 0, 0}},
-+ {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
-+  {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
-+  {1, 0, 0, 0}},
-+ {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
-+  {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
-+  {1, 0, 0, 0}},
-+ {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
-+  {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
-+  {1, 0, 0, 0}},
-+ {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
-+  {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
-+  {1, 0, 0, 0}},
-+ {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
-+  {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
-+  {1, 0, 0, 0}},
-+ {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
-+  {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
-+  {1, 0, 0, 0}},
-+ {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
-+  {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
-+  {1, 0, 0, 0}},
-+ {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
-+  {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
-+  {1, 0, 0, 0}},
-+ {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
-+  {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
-+  {1, 0, 0, 0}},
-+ {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
-+  {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
-+  {1, 0, 0, 0}},
-+ {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
-+  {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
-+  {1, 0, 0, 0}},
-+ {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
-+  {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
-+  {1, 0, 0, 0}}}
-+};
-+
-+/* Precomputation for the group generator. */
-+struct nistp224_pre_comp_st {
-+    felem g_pre_comp[2][16][3];
-+    int references;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+const EC_METHOD *EC_GFp_nistp224_method(void)
-+{
-+    static const EC_METHOD ret = {
-+        EC_FLAGS_DEFAULT_OCT,
-+        NID_X9_62_prime_field,
-+        ec_GFp_nistp224_group_init,
-+        ec_GFp_simple_group_finish,
-+        ec_GFp_simple_group_clear_finish,
-+        ec_GFp_nist_group_copy,
-+        ec_GFp_nistp224_group_set_curve,
-+        ec_GFp_simple_group_get_curve,
-+        ec_GFp_simple_group_get_degree,
-+        ec_group_simple_order_bits,
-+        ec_GFp_simple_group_check_discriminant,
-+        ec_GFp_simple_point_init,
-+        ec_GFp_simple_point_finish,
-+        ec_GFp_simple_point_clear_finish,
-+        ec_GFp_simple_point_copy,
-+        ec_GFp_simple_point_set_to_infinity,
-+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_point_set_affine_coordinates,
-+        ec_GFp_nistp224_point_get_affine_coordinates,
-+        0 /* point_set_compressed_coordinates */ ,
-+        0 /* point2oct */ ,
-+        0 /* oct2point */ ,
-+        ec_GFp_simple_add,
-+        ec_GFp_simple_dbl,
-+        ec_GFp_simple_invert,
-+        ec_GFp_simple_is_at_infinity,
-+        ec_GFp_simple_is_on_curve,
-+        ec_GFp_simple_cmp,
-+        ec_GFp_simple_make_affine,
-+        ec_GFp_simple_points_make_affine,
-+        ec_GFp_nistp224_points_mul,
-+        ec_GFp_nistp224_precompute_mult,
-+        ec_GFp_nistp224_have_precompute_mult,
-+        ec_GFp_nist_field_mul,
-+        ec_GFp_nist_field_sqr,
-+        0 /* field_div */ ,
-+        0 /* field_encode */ ,
-+        0 /* field_decode */ ,
-+        0,                      /* field_set_to_one */
-+        ec_key_simple_priv2oct,
-+        ec_key_simple_oct2priv,
-+        0, /* set private */
-+        ec_key_simple_generate_key,
-+        ec_key_simple_check_key,
-+        ec_key_simple_generate_public_key,
-+        0, /* keycopy */
-+        0, /* keyfinish */
-+        ecdh_simple_compute_key
-+    };
-+
-+    return &ret;
-+}
-+
-+/*
-+ * Helper functions to convert field elements to/from internal representation
-+ */
-+static void bin28_to_felem(felem out, const u8 in[28])
-+{
-+    out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
-+    out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
-+    out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
-+    out[3] = (*((const uint64_t *)(in+20))) >> 8;
-+}
-+
-+static void felem_to_bin28(u8 out[28], const felem in)
-+{
-+    unsigned i;
-+    for (i = 0; i < 7; ++i) {
-+        out[i] = in[0] >> (8 * i);
-+        out[i + 7] = in[1] >> (8 * i);
-+        out[i + 14] = in[2] >> (8 * i);
-+        out[i + 21] = in[3] >> (8 * i);
-+    }
-+}
-+
-+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-+static void flip_endian(u8 *out, const u8 *in, unsigned len)
-+{
-+    unsigned i;
-+    for (i = 0; i < len; ++i)
-+        out[i] = in[len - 1 - i];
-+}
-+
-+/* From OpenSSL BIGNUM to internal representation */
-+static int BN_to_felem(felem out, const BIGNUM *bn)
-+{
-+    felem_bytearray b_in;
-+    felem_bytearray b_out;
-+    unsigned num_bytes;
-+
-+    /* BN_bn2bin eats leading zeroes */
-+    memset(b_out, 0, sizeof(b_out));
-+    num_bytes = BN_num_bytes(bn);
-+    if (num_bytes > sizeof b_out) {
-+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
-+        return 0;
-+    }
-+    if (BN_is_negative(bn)) {
-+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
-+        return 0;
-+    }
-+    num_bytes = BN_bn2bin(bn, b_in);
-+    flip_endian(b_out, b_in, num_bytes);
-+    bin28_to_felem(out, b_out);
-+    return 1;
-+}
-+
-+/* From internal representation to OpenSSL BIGNUM */
-+static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
-+{
-+    felem_bytearray b_in, b_out;
-+    felem_to_bin28(b_in, in);
-+    flip_endian(b_out, b_in, sizeof b_out);
-+    return BN_bin2bn(b_out, sizeof b_out, out);
-+}
-+
-+/******************************************************************************/
-+/*-
-+ *                              FIELD OPERATIONS
-+ *
-+ * Field operations, using the internal representation of field elements.
-+ * NB! These operations are specific to our point multiplication and cannot be
-+ * expected to be correct in general - e.g., multiplication with a large scalar
-+ * will cause an overflow.
-+ *
-+ */
-+
-+static void felem_one(felem out)
-+{
-+    out[0] = 1;
-+    out[1] = 0;
-+    out[2] = 0;
-+    out[3] = 0;
-+}
-+
-+static void felem_assign(felem out, const felem in)
-+{
-+    out[0] = in[0];
-+    out[1] = in[1];
-+    out[2] = in[2];
-+    out[3] = in[3];
-+}
-+
-+/* Sum two field elements: out += in */
-+static void felem_sum(felem out, const felem in)
-+{
-+    out[0] += in[0];
-+    out[1] += in[1];
-+    out[2] += in[2];
-+    out[3] += in[3];
-+}
-+
-+/* Get negative value: out = -in */
-+/* Assumes in[i] < 2^57 */
-+static void felem_neg(felem out, const felem in)
-+{
-+    static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
-+    static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
-+    static const limb two58m42m2 = (((limb) 1) << 58) -
-+        (((limb) 1) << 42) - (((limb) 1) << 2);
-+
-+    /* Set to 0 mod 2^224-2^96+1 to ensure out > in */
-+    out[0] = two58p2 - in[0];
-+    out[1] = two58m42m2 - in[1];
-+    out[2] = two58m2 - in[2];
-+    out[3] = two58m2 - in[3];
-+}
-+
-+/* Subtract field elements: out -= in */
-+/* Assumes in[i] < 2^57 */
-+static void felem_diff(felem out, const felem in)
-+{
-+    static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
-+    static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
-+    static const limb two58m42m2 = (((limb) 1) << 58) -
-+        (((limb) 1) << 42) - (((limb) 1) << 2);
-+
-+    /* Add 0 mod 2^224-2^96+1 to ensure out > in */
-+    out[0] += two58p2;
-+    out[1] += two58m42m2;
-+    out[2] += two58m2;
-+    out[3] += two58m2;
-+
-+    out[0] -= in[0];
-+    out[1] -= in[1];
-+    out[2] -= in[2];
-+    out[3] -= in[3];
-+}
-+
-+/* Subtract in unreduced 128-bit mode: out -= in */
-+/* Assumes in[i] < 2^119 */
-+static void widefelem_diff(widefelem out, const widefelem in)
-+{
-+    static const widelimb two120 = ((widelimb) 1) << 120;
-+    static const widelimb two120m64 = (((widelimb) 1) << 120) -
-+        (((widelimb) 1) << 64);
-+    static const widelimb two120m104m64 = (((widelimb) 1) << 120) -
-+        (((widelimb) 1) << 104) - (((widelimb) 1) << 64);
-+
-+    /* Add 0 mod 2^224-2^96+1 to ensure out > in */
-+    out[0] += two120;
-+    out[1] += two120m64;
-+    out[2] += two120m64;
-+    out[3] += two120;
-+    out[4] += two120m104m64;
-+    out[5] += two120m64;
-+    out[6] += two120m64;
-+
-+    out[0] -= in[0];
-+    out[1] -= in[1];
-+    out[2] -= in[2];
-+    out[3] -= in[3];
-+    out[4] -= in[4];
-+    out[5] -= in[5];
-+    out[6] -= in[6];
-+}
-+
-+/* Subtract in mixed mode: out128 -= in64 */
-+/* in[i] < 2^63 */
-+static void felem_diff_128_64(widefelem out, const felem in)
-+{
-+    static const widelimb two64p8 = (((widelimb) 1) << 64) +
-+        (((widelimb) 1) << 8);
-+    static const widelimb two64m8 = (((widelimb) 1) << 64) -
-+        (((widelimb) 1) << 8);
-+    static const widelimb two64m48m8 = (((widelimb) 1) << 64) -
-+        (((widelimb) 1) << 48) - (((widelimb) 1) << 8);
-+
-+    /* Add 0 mod 2^224-2^96+1 to ensure out > in */
-+    out[0] += two64p8;
-+    out[1] += two64m48m8;
-+    out[2] += two64m8;
-+    out[3] += two64m8;
-+
-+    out[0] -= in[0];
-+    out[1] -= in[1];
-+    out[2] -= in[2];
-+    out[3] -= in[3];
-+}
-+
-+/*
-+ * Multiply a field element by a scalar: out = out * scalar The scalars we
-+ * actually use are small, so results fit without overflow
-+ */
-+static void felem_scalar(felem out, const limb scalar)
-+{
-+    out[0] *= scalar;
-+    out[1] *= scalar;
-+    out[2] *= scalar;
-+    out[3] *= scalar;
-+}
-+
-+/*
-+ * Multiply an unreduced field element by a scalar: out = out * scalar The
-+ * scalars we actually use are small, so results fit without overflow
-+ */
-+static void widefelem_scalar(widefelem out, const widelimb scalar)
-+{
-+    out[0] *= scalar;
-+    out[1] *= scalar;
-+    out[2] *= scalar;
-+    out[3] *= scalar;
-+    out[4] *= scalar;
-+    out[5] *= scalar;
-+    out[6] *= scalar;
-+}
-+
-+/* Square a field element: out = in^2 */
-+static void felem_square(widefelem out, const felem in)
-+{
-+    limb tmp0, tmp1, tmp2;
-+    tmp0 = 2 * in[0];
-+    tmp1 = 2 * in[1];
-+    tmp2 = 2 * in[2];
-+    out[0] = ((widelimb) in[0]) * in[0];
-+    out[1] = ((widelimb) in[0]) * tmp1;
-+    out[2] = ((widelimb) in[0]) * tmp2 + ((widelimb) in[1]) * in[1];
-+    out[3] = ((widelimb) in[3]) * tmp0 + ((widelimb) in[1]) * tmp2;
-+    out[4] = ((widelimb) in[3]) * tmp1 + ((widelimb) in[2]) * in[2];
-+    out[5] = ((widelimb) in[3]) * tmp2;
-+    out[6] = ((widelimb) in[3]) * in[3];
-+}
-+
-+/* Multiply two field elements: out = in1 * in2 */
-+static void felem_mul(widefelem out, const felem in1, const felem in2)
-+{
-+    out[0] = ((widelimb) in1[0]) * in2[0];
-+    out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0];
-+    out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] +
-+             ((widelimb) in1[2]) * in2[0];
-+    out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] +
-+             ((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0];
-+    out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] +
-+             ((widelimb) in1[3]) * in2[1];
-+    out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2];
-+    out[6] = ((widelimb) in1[3]) * in2[3];
-+}
-+
-+/*-
-+ * Reduce seven 128-bit coefficients to four 64-bit coefficients.
-+ * Requires in[i] < 2^126,
-+ * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */
-+static void felem_reduce(felem out, const widefelem in)
-+{
-+    static const widelimb two127p15 = (((widelimb) 1) << 127) +
-+        (((widelimb) 1) << 15);
-+    static const widelimb two127m71 = (((widelimb) 1) << 127) -
-+        (((widelimb) 1) << 71);
-+    static const widelimb two127m71m55 = (((widelimb) 1) << 127) -
-+        (((widelimb) 1) << 71) - (((widelimb) 1) << 55);
-+    widelimb output[5];
-+
-+    /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */
-+    output[0] = in[0] + two127p15;
-+    output[1] = in[1] + two127m71m55;
-+    output[2] = in[2] + two127m71;
-+    output[3] = in[3];
-+    output[4] = in[4];
-+
-+    /* Eliminate in[4], in[5], in[6] */
-+    output[4] += in[6] >> 16;
-+    output[3] += (in[6] & 0xffff) << 40;
-+    output[2] -= in[6];
-+
-+    output[3] += in[5] >> 16;
-+    output[2] += (in[5] & 0xffff) << 40;
-+    output[1] -= in[5];
-+
-+    output[2] += output[4] >> 16;
-+    output[1] += (output[4] & 0xffff) << 40;
-+    output[0] -= output[4];
-+
-+    /* Carry 2 -> 3 -> 4 */
-+    output[3] += output[2] >> 56;
-+    output[2] &= 0x00ffffffffffffff;
-+
-+    output[4] = output[3] >> 56;
-+    output[3] &= 0x00ffffffffffffff;
-+
-+    /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */
-+
-+    /* Eliminate output[4] */
-+    output[2] += output[4] >> 16;
-+    /* output[2] < 2^56 + 2^56 = 2^57 */
-+    output[1] += (output[4] & 0xffff) << 40;
-+    output[0] -= output[4];
-+
-+    /* Carry 0 -> 1 -> 2 -> 3 */
-+    output[1] += output[0] >> 56;
-+    out[0] = output[0] & 0x00ffffffffffffff;
-+
-+    output[2] += output[1] >> 56;
-+    /* output[2] < 2^57 + 2^72 */
-+    out[1] = output[1] & 0x00ffffffffffffff;
-+    output[3] += output[2] >> 56;
-+    /* output[3] <= 2^56 + 2^16 */
-+    out[2] = output[2] & 0x00ffffffffffffff;
-+
-+    /*-
-+     * out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
-+     * out[3] <= 2^56 + 2^16 (due to final carry),
-+     * so out < 2*p
-+     */
-+    out[3] = output[3];
-+}
-+
-+static void felem_square_reduce(felem out, const felem in)
-+{
-+    widefelem tmp;
-+    felem_square(tmp, in);
-+    felem_reduce(out, tmp);
-+}
-+
-+static void felem_mul_reduce(felem out, const felem in1, const felem in2)
-+{
-+    widefelem tmp;
-+    felem_mul(tmp, in1, in2);
-+    felem_reduce(out, tmp);
-+}
-+
-+/*
-+ * Reduce to unique minimal representation. Requires 0 <= in < 2*p (always
-+ * call felem_reduce first)
-+ */
-+static void felem_contract(felem out, const felem in)
-+{
-+    static const int64_t two56 = ((limb) 1) << 56;
-+    /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */
-+    /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */
-+    int64_t tmp[4], a;
-+    tmp[0] = in[0];
-+    tmp[1] = in[1];
-+    tmp[2] = in[2];
-+    tmp[3] = in[3];
-+    /* Case 1: a = 1 iff in >= 2^224 */
-+    a = (in[3] >> 56);
-+    tmp[0] -= a;
-+    tmp[1] += a << 40;
-+    tmp[3] &= 0x00ffffffffffffff;
-+    /*
-+     * Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1
-+     * and the lower part is non-zero
-+     */
-+    a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
-+        (((int64_t) (in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
-+    a &= 0x00ffffffffffffff;
-+    /* turn a into an all-one mask (if a = 0) or an all-zero mask */
-+    a = (a - 1) >> 63;
-+    /* subtract 2^224 - 2^96 + 1 if a is all-one */
-+    tmp[3] &= a ^ 0xffffffffffffffff;
-+    tmp[2] &= a ^ 0xffffffffffffffff;
-+    tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
-+    tmp[0] -= 1 & a;
-+
-+    /*
-+     * eliminate negative coefficients: if tmp[0] is negative, tmp[1] must be
-+     * non-zero, so we only need one step
-+     */
-+    a = tmp[0] >> 63;
-+    tmp[0] += two56 & a;
-+    tmp[1] -= 1 & a;
-+
-+    /* carry 1 -> 2 -> 3 */
-+    tmp[2] += tmp[1] >> 56;
-+    tmp[1] &= 0x00ffffffffffffff;
-+
-+    tmp[3] += tmp[2] >> 56;
-+    tmp[2] &= 0x00ffffffffffffff;
-+
-+    /* Now 0 <= out < p */
-+    out[0] = tmp[0];
-+    out[1] = tmp[1];
-+    out[2] = tmp[2];
-+    out[3] = tmp[3];
-+}
-+
-+/*
-+ * Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field
-+ * elements are reduced to in < 2^225, so we only need to check three cases:
-+ * 0, 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2
-+ */
-+static limb felem_is_zero(const felem in)
-+{
-+    limb zero, two224m96p1, two225m97p2;
-+
-+    zero = in[0] | in[1] | in[2] | in[3];
-+    zero = (((int64_t) (zero) - 1) >> 63) & 1;
-+    two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000)
-+        | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x00ffffffffffffff);
-+    two224m96p1 = (((int64_t) (two224m96p1) - 1) >> 63) & 1;
-+    two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000)
-+        | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x01ffffffffffffff);
-+    two225m97p2 = (((int64_t) (two225m97p2) - 1) >> 63) & 1;
-+    return (zero | two224m96p1 | two225m97p2);
-+}
-+
-+static limb felem_is_zero_int(const felem in)
-+{
-+    return (int)(felem_is_zero(in) & ((limb) 1));
-+}
-+
-+/* Invert a field element */
-+/* Computation chain copied from djb's code */
-+static void felem_inv(felem out, const felem in)
-+{
-+    felem ftmp, ftmp2, ftmp3, ftmp4;
-+    widefelem tmp;
-+    unsigned i;
-+
-+    felem_square(tmp, in);
-+    felem_reduce(ftmp, tmp);    /* 2 */
-+    felem_mul(tmp, in, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^2 - 1 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^3 - 2 */
-+    felem_mul(tmp, in, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^3 - 1 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp2, tmp);   /* 2^4 - 2 */
-+    felem_square(tmp, ftmp2);
-+    felem_reduce(ftmp2, tmp);   /* 2^5 - 4 */
-+    felem_square(tmp, ftmp2);
-+    felem_reduce(ftmp2, tmp);   /* 2^6 - 8 */
-+    felem_mul(tmp, ftmp2, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^6 - 1 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp2, tmp);   /* 2^7 - 2 */
-+    for (i = 0; i < 5; ++i) {   /* 2^12 - 2^6 */
-+        felem_square(tmp, ftmp2);
-+        felem_reduce(ftmp2, tmp);
-+    }
-+    felem_mul(tmp, ftmp2, ftmp);
-+    felem_reduce(ftmp2, tmp);   /* 2^12 - 1 */
-+    felem_square(tmp, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^13 - 2 */
-+    for (i = 0; i < 11; ++i) {  /* 2^24 - 2^12 */
-+        felem_square(tmp, ftmp3);
-+        felem_reduce(ftmp3, tmp);
-+    }
-+    felem_mul(tmp, ftmp3, ftmp2);
-+    felem_reduce(ftmp2, tmp);   /* 2^24 - 1 */
-+    felem_square(tmp, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^25 - 2 */
-+    for (i = 0; i < 23; ++i) {  /* 2^48 - 2^24 */
-+        felem_square(tmp, ftmp3);
-+        felem_reduce(ftmp3, tmp);
-+    }
-+    felem_mul(tmp, ftmp3, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^48 - 1 */
-+    felem_square(tmp, ftmp3);
-+    felem_reduce(ftmp4, tmp);   /* 2^49 - 2 */
-+    for (i = 0; i < 47; ++i) {  /* 2^96 - 2^48 */
-+        felem_square(tmp, ftmp4);
-+        felem_reduce(ftmp4, tmp);
-+    }
-+    felem_mul(tmp, ftmp3, ftmp4);
-+    felem_reduce(ftmp3, tmp);   /* 2^96 - 1 */
-+    felem_square(tmp, ftmp3);
-+    felem_reduce(ftmp4, tmp);   /* 2^97 - 2 */
-+    for (i = 0; i < 23; ++i) {  /* 2^120 - 2^24 */
-+        felem_square(tmp, ftmp4);
-+        felem_reduce(ftmp4, tmp);
-+    }
-+    felem_mul(tmp, ftmp2, ftmp4);
-+    felem_reduce(ftmp2, tmp);   /* 2^120 - 1 */
-+    for (i = 0; i < 6; ++i) {   /* 2^126 - 2^6 */
-+        felem_square(tmp, ftmp2);
-+        felem_reduce(ftmp2, tmp);
-+    }
-+    felem_mul(tmp, ftmp2, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^126 - 1 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^127 - 2 */
-+    felem_mul(tmp, ftmp, in);
-+    felem_reduce(ftmp, tmp);    /* 2^127 - 1 */
-+    for (i = 0; i < 97; ++i) {  /* 2^224 - 2^97 */
-+        felem_square(tmp, ftmp);
-+        felem_reduce(ftmp, tmp);
-+    }
-+    felem_mul(tmp, ftmp, ftmp3);
-+    felem_reduce(out, tmp);     /* 2^224 - 2^96 - 1 */
-+}
-+
-+/*
-+ * Copy in constant time: if icopy == 1, copy in to out, if icopy == 0, copy
-+ * out to itself.
-+ */
-+static void copy_conditional(felem out, const felem in, limb icopy)
-+{
-+    unsigned i;
-+    /*
-+     * icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one
-+     */
-+    const limb copy = -icopy;
-+    for (i = 0; i < 4; ++i) {
-+        const limb tmp = copy & (in[i] ^ out[i]);
-+        out[i] ^= tmp;
-+    }
-+}
-+
-+/******************************************************************************/
-+/*-
-+ *                       ELLIPTIC CURVE POINT OPERATIONS
-+ *
-+ * Points are represented in Jacobian projective coordinates:
-+ * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
-+ * or to the point at infinity if Z == 0.
-+ *
-+ */
-+
-+/*-
-+ * Double an elliptic curve point:
-+ * (X', Y', Z') = 2 * (X, Y, Z), where
-+ * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
-+ * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
-+ * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
-+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
-+ * while x_out == y_in is not (maybe this works, but it's not tested).
-+ */
-+static void
-+point_double(felem x_out, felem y_out, felem z_out,
-+             const felem x_in, const felem y_in, const felem z_in)
-+{
-+    widefelem tmp, tmp2;
-+    felem delta, gamma, beta, alpha, ftmp, ftmp2;
-+
-+    felem_assign(ftmp, x_in);
-+    felem_assign(ftmp2, x_in);
-+
-+    /* delta = z^2 */
-+    felem_square(tmp, z_in);
-+    felem_reduce(delta, tmp);
-+
-+    /* gamma = y^2 */
-+    felem_square(tmp, y_in);
-+    felem_reduce(gamma, tmp);
-+
-+    /* beta = x*gamma */
-+    felem_mul(tmp, x_in, gamma);
-+    felem_reduce(beta, tmp);
-+
-+    /* alpha = 3*(x-delta)*(x+delta) */
-+    felem_diff(ftmp, delta);
-+    /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */
-+    felem_sum(ftmp2, delta);
-+    /* ftmp2[i] < 2^57 + 2^57 = 2^58 */
-+    felem_scalar(ftmp2, 3);
-+    /* ftmp2[i] < 3 * 2^58 < 2^60 */
-+    felem_mul(tmp, ftmp, ftmp2);
-+    /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */
-+    felem_reduce(alpha, tmp);
-+
-+    /* x' = alpha^2 - 8*beta */
-+    felem_square(tmp, alpha);
-+    /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
-+    felem_assign(ftmp, beta);
-+    felem_scalar(ftmp, 8);
-+    /* ftmp[i] < 8 * 2^57 = 2^60 */
-+    felem_diff_128_64(tmp, ftmp);
-+    /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
-+    felem_reduce(x_out, tmp);
-+
-+    /* z' = (y + z)^2 - gamma - delta */
-+    felem_sum(delta, gamma);
-+    /* delta[i] < 2^57 + 2^57 = 2^58 */
-+    felem_assign(ftmp, y_in);
-+    felem_sum(ftmp, z_in);
-+    /* ftmp[i] < 2^57 + 2^57 = 2^58 */
-+    felem_square(tmp, ftmp);
-+    /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */
-+    felem_diff_128_64(tmp, delta);
-+    /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */
-+    felem_reduce(z_out, tmp);
-+
-+    /* y' = alpha*(4*beta - x') - 8*gamma^2 */
-+    felem_scalar(beta, 4);
-+    /* beta[i] < 4 * 2^57 = 2^59 */
-+    felem_diff(beta, x_out);
-+    /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */
-+    felem_mul(tmp, alpha, beta);
-+    /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */
-+    felem_square(tmp2, gamma);
-+    /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */
-+    widefelem_scalar(tmp2, 8);
-+    /* tmp2[i] < 8 * 2^116 = 2^119 */
-+    widefelem_diff(tmp, tmp2);
-+    /* tmp[i] < 2^119 + 2^120 < 2^121 */
-+    felem_reduce(y_out, tmp);
-+}
-+
-+/*-
-+ * Add two elliptic curve points:
-+ * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
-+ * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
-+ * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
-+ * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - X_3) -
-+ *        Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
-+ * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
-+ *
-+ * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0.
-+ */
-+
-+/*
-+ * This function is not entirely constant-time: it includes a branch for
-+ * checking whether the two input points are equal, (while not equal to the
-+ * point at infinity). This case never happens during single point
-+ * multiplication, so there is no timing leak for ECDH or ECDSA signing.
-+ */
-+static void point_add(felem x3, felem y3, felem z3,
-+                      const felem x1, const felem y1, const felem z1,
-+                      const int mixed, const felem x2, const felem y2,
-+                      const felem z2)
-+{
-+    felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
-+    widefelem tmp, tmp2;
-+    limb z1_is_zero, z2_is_zero, x_equal, y_equal;
-+
-+    if (!mixed) {
-+        /* ftmp2 = z2^2 */
-+        felem_square(tmp, z2);
-+        felem_reduce(ftmp2, tmp);
-+
-+        /* ftmp4 = z2^3 */
-+        felem_mul(tmp, ftmp2, z2);
-+        felem_reduce(ftmp4, tmp);
-+
-+        /* ftmp4 = z2^3*y1 */
-+        felem_mul(tmp2, ftmp4, y1);
-+        felem_reduce(ftmp4, tmp2);
-+
-+        /* ftmp2 = z2^2*x1 */
-+        felem_mul(tmp2, ftmp2, x1);
-+        felem_reduce(ftmp2, tmp2);
-+    } else {
-+        /*
-+         * We'll assume z2 = 1 (special case z2 = 0 is handled later)
-+         */
-+
-+        /* ftmp4 = z2^3*y1 */
-+        felem_assign(ftmp4, y1);
-+
-+        /* ftmp2 = z2^2*x1 */
-+        felem_assign(ftmp2, x1);
-+    }
-+
-+    /* ftmp = z1^2 */
-+    felem_square(tmp, z1);
-+    felem_reduce(ftmp, tmp);
-+
-+    /* ftmp3 = z1^3 */
-+    felem_mul(tmp, ftmp, z1);
-+    felem_reduce(ftmp3, tmp);
-+
-+    /* tmp = z1^3*y2 */
-+    felem_mul(tmp, ftmp3, y2);
-+    /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
-+
-+    /* ftmp3 = z1^3*y2 - z2^3*y1 */
-+    felem_diff_128_64(tmp, ftmp4);
-+    /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
-+    felem_reduce(ftmp3, tmp);
-+
-+    /* tmp = z1^2*x2 */
-+    felem_mul(tmp, ftmp, x2);
-+    /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
-+
-+    /* ftmp = z1^2*x2 - z2^2*x1 */
-+    felem_diff_128_64(tmp, ftmp2);
-+    /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
-+    felem_reduce(ftmp, tmp);
-+
-+    /*
-+     * the formulae are incorrect if the points are equal so we check for
-+     * this and do doubling if this happens
-+     */
-+    x_equal = felem_is_zero(ftmp);
-+    y_equal = felem_is_zero(ftmp3);
-+    z1_is_zero = felem_is_zero(z1);
-+    z2_is_zero = felem_is_zero(z2);
-+    /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
-+    if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
-+        point_double(x3, y3, z3, x1, y1, z1);
-+        return;
-+    }
-+
-+    /* ftmp5 = z1*z2 */
-+    if (!mixed) {
-+        felem_mul(tmp, z1, z2);
-+        felem_reduce(ftmp5, tmp);
-+    } else {
-+        /* special case z2 = 0 is handled later */
-+        felem_assign(ftmp5, z1);
-+    }
-+
-+    /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */
-+    felem_mul(tmp, ftmp, ftmp5);
-+    felem_reduce(z_out, tmp);
-+
-+    /* ftmp = (z1^2*x2 - z2^2*x1)^2 */
-+    felem_assign(ftmp5, ftmp);
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);
-+
-+    /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */
-+    felem_mul(tmp, ftmp, ftmp5);
-+    felem_reduce(ftmp5, tmp);
-+
-+    /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
-+    felem_mul(tmp, ftmp2, ftmp);
-+    felem_reduce(ftmp2, tmp);
-+
-+    /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
-+    felem_mul(tmp, ftmp4, ftmp5);
-+    /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
-+
-+    /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */
-+    felem_square(tmp2, ftmp3);
-+    /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */
-+
-+    /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */
-+    felem_diff_128_64(tmp2, ftmp5);
-+    /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */
-+
-+    /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
-+    felem_assign(ftmp5, ftmp2);
-+    felem_scalar(ftmp5, 2);
-+    /* ftmp5[i] < 2 * 2^57 = 2^58 */
-+
-+    /*-
-+     * x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
-+     *  2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2
-+     */
-+    felem_diff_128_64(tmp2, ftmp5);
-+    /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */
-+    felem_reduce(x_out, tmp2);
-+
-+    /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */
-+    felem_diff(ftmp2, x_out);
-+    /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */
-+
-+    /*
-+     * tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out)
-+     */
-+    felem_mul(tmp2, ftmp3, ftmp2);
-+    /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */
-+
-+    /*-
-+     * y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
-+     *  z2^3*y1*(z1^2*x2 - z2^2*x1)^3
-+     */
-+    widefelem_diff(tmp2, tmp);
-+    /* tmp2[i] < 2^118 + 2^120 < 2^121 */
-+    felem_reduce(y_out, tmp2);
-+
-+    /*
-+     * the result (x_out, y_out, z_out) is incorrect if one of the inputs is
-+     * the point at infinity, so we need to check for this separately
-+     */
-+
-+    /*
-+     * if point 1 is at infinity, copy point 2 to output, and vice versa
-+     */
-+    copy_conditional(x_out, x2, z1_is_zero);
-+    copy_conditional(x_out, x1, z2_is_zero);
-+    copy_conditional(y_out, y2, z1_is_zero);
-+    copy_conditional(y_out, y1, z2_is_zero);
-+    copy_conditional(z_out, z2, z1_is_zero);
-+    copy_conditional(z_out, z1, z2_is_zero);
-+    felem_assign(x3, x_out);
-+    felem_assign(y3, y_out);
-+    felem_assign(z3, z_out);
-+}
-+
-+/*
-+ * select_point selects the |idx|th point from a precomputation table and
-+ * copies it to out.
-+ * The pre_comp array argument should be size of |size| argument
-+ */
-+static void select_point(const u64 idx, unsigned int size,
-+                         const felem pre_comp[][3], felem out[3])
-+{
-+    unsigned i, j;
-+    limb *outlimbs = &out[0][0];
-+
-+    memset(out, 0, sizeof(*out) * 3);
-+    for (i = 0; i < size; i++) {
-+        const limb *inlimbs = &pre_comp[i][0][0];
-+        u64 mask = i ^ idx;
-+        mask |= mask >> 4;
-+        mask |= mask >> 2;
-+        mask |= mask >> 1;
-+        mask &= 1;
-+        mask--;
-+        for (j = 0; j < 4 * 3; j++)
-+            outlimbs[j] |= inlimbs[j] & mask;
-+    }
-+}
-+
-+/* get_bit returns the |i|th bit in |in| */
-+static char get_bit(const felem_bytearray in, unsigned i)
-+{
-+    if (i >= 224)
-+        return 0;
-+    return (in[i >> 3] >> (i & 7)) & 1;
-+}
-+
-+/*
-+ * Interleaved point multiplication using precomputed point multiples: The
-+ * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars
-+ * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the
-+ * generator, using certain (large) precomputed multiples in g_pre_comp.
-+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out
-+ */
-+static void batch_mul(felem x_out, felem y_out, felem z_out,
-+                      const felem_bytearray scalars[],
-+                      const unsigned num_points, const u8 *g_scalar,
-+                      const int mixed, const felem pre_comp[][17][3],
-+                      const felem g_pre_comp[2][16][3])
-+{
-+    int i, skip;
-+    unsigned num;
-+    unsigned gen_mul = (g_scalar != NULL);
-+    felem nq[3], tmp[4];
-+    u64 bits;
-+    u8 sign, digit;
-+
-+    /* set nq to the point at infinity */
-+    memset(nq, 0, sizeof(nq));
-+
-+    /*
-+     * Loop over all scalars msb-to-lsb, interleaving additions of multiples
-+     * of the generator (two in each of the last 28 rounds) and additions of
-+     * other points multiples (every 5th round).
-+     */
-+    skip = 1;                   /* save two point operations in the first
-+                                 * round */
-+    for (i = (num_points ? 220 : 27); i >= 0; --i) {
-+        /* double */
-+        if (!skip)
-+            point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
-+
-+        /* add multiples of the generator */
-+        if (gen_mul && (i <= 27)) {
-+            /* first, look 28 bits upwards */
-+            bits = get_bit(g_scalar, i + 196) << 3;
-+            bits |= get_bit(g_scalar, i + 140) << 2;
-+            bits |= get_bit(g_scalar, i + 84) << 1;
-+            bits |= get_bit(g_scalar, i + 28);
-+            /* select the point to add, in constant time */
-+            select_point(bits, 16, g_pre_comp[1], tmp);
-+
-+            if (!skip) {
-+                /* value 1 below is argument for "mixed" */
-+                point_add(nq[0], nq[1], nq[2],
-+                          nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
-+            } else {
-+                memcpy(nq, tmp, 3 * sizeof(felem));
-+                skip = 0;
-+            }
-+
-+            /* second, look at the current position */
-+            bits = get_bit(g_scalar, i + 168) << 3;
-+            bits |= get_bit(g_scalar, i + 112) << 2;
-+            bits |= get_bit(g_scalar, i + 56) << 1;
-+            bits |= get_bit(g_scalar, i);
-+            /* select the point to add, in constant time */
-+            select_point(bits, 16, g_pre_comp[0], tmp);
-+            point_add(nq[0], nq[1], nq[2],
-+                      nq[0], nq[1], nq[2],
-+                      1 /* mixed */ , tmp[0], tmp[1], tmp[2]);
-+        }
-+
-+        /* do other additions every 5 doublings */
-+        if (num_points && (i % 5 == 0)) {
-+            /* loop over all scalars */
-+            for (num = 0; num < num_points; ++num) {
-+                bits = get_bit(scalars[num], i + 4) << 5;
-+                bits |= get_bit(scalars[num], i + 3) << 4;
-+                bits |= get_bit(scalars[num], i + 2) << 3;
-+                bits |= get_bit(scalars[num], i + 1) << 2;
-+                bits |= get_bit(scalars[num], i) << 1;
-+                bits |= get_bit(scalars[num], i - 1);
-+                ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
-+
-+                /* select the point to add or subtract */
-+                select_point(digit, 17, pre_comp[num], tmp);
-+                felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative
-+                                            * point */
-+                copy_conditional(tmp[1], tmp[3], sign);
-+
-+                if (!skip) {
-+                    point_add(nq[0], nq[1], nq[2],
-+                              nq[0], nq[1], nq[2],
-+                              mixed, tmp[0], tmp[1], tmp[2]);
-+                } else {
-+                    memcpy(nq, tmp, 3 * sizeof(felem));
-+                    skip = 0;
-+                }
-+            }
-+        }
-+    }
-+    felem_assign(x_out, nq[0]);
-+    felem_assign(y_out, nq[1]);
-+    felem_assign(z_out, nq[2]);
-+}
-+
-+/******************************************************************************/
-+/*
-+ * FUNCTIONS TO MANAGE PRECOMPUTATION
-+ */
-+
-+static NISTP224_PRE_COMP *nistp224_pre_comp_new()
-+{
-+    NISTP224_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (!ret) {
-+        ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
-+        return ret;
-+    }
-+
-+    ret->references = 1;
-+
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *p)
-+{
-+    int i;
-+    if (p != NULL)
-+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
-+    return p;
-+}
-+
-+void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p)
-+{
-+    int i;
-+
-+    if (p == NULL)
-+        return;
-+
-+    CRYPTO_atomic_add(&p->references, -1, &i, p->lock);
-+    REF_PRINT_COUNT("EC_nistp224", x);
-+    if (i > 0)
-+        return;
-+    REF_ASSERT_ISNT(i < 0);
-+
-+    CRYPTO_THREAD_lock_free(p->lock);
-+    OPENSSL_free(p);
-+}
-+
-+/******************************************************************************/
-+/*
-+ * OPENSSL EC_METHOD FUNCTIONS
-+ */
-+
-+int ec_GFp_nistp224_group_init(EC_GROUP *group)
-+{
-+    int ret;
-+    ret = ec_GFp_simple_group_init(group);
-+    group->a_is_minus3 = 1;
-+    return ret;
-+}
-+
-+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
-+                                    const BIGNUM *a, const BIGNUM *b,
-+                                    BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *curve_p, *curve_a, *curve_b;
-+
-+    if (ctx == NULL)
-+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+    BN_CTX_start(ctx);
-+    if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
-+        ((curve_a = BN_CTX_get(ctx)) == NULL) ||
-+        ((curve_b = BN_CTX_get(ctx)) == NULL))
-+        goto err;
-+    BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
-+    BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
-+    BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
-+    if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
-+        ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE,
-+              EC_R_WRONG_CURVE_PARAMETERS);
-+        goto err;
-+    }
-+    group->field_mod_func = BN_nist_mod_224;
-+    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+/*
-+ * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
-+ * (X/Z^2, Y/Z^3)
-+ */
-+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
-+                                                 const EC_POINT *point,
-+                                                 BIGNUM *x, BIGNUM *y,
-+                                                 BN_CTX *ctx)
-+{
-+    felem z1, z2, x_in, y_in, x_out, y_out;
-+    widefelem tmp;
-+
-+    if (EC_POINT_is_at_infinity(group, point)) {
-+        ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
-+              EC_R_POINT_AT_INFINITY);
-+        return 0;
-+    }
-+    if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
-+        (!BN_to_felem(z1, point->Z)))
-+        return 0;
-+    felem_inv(z2, z1);
-+    felem_square(tmp, z2);
-+    felem_reduce(z1, tmp);
-+    felem_mul(tmp, x_in, z1);
-+    felem_reduce(x_in, tmp);
-+    felem_contract(x_out, x_in);
-+    if (x != NULL) {
-+        if (!felem_to_BN(x, x_out)) {
-+            ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
-+                  ERR_R_BN_LIB);
-+            return 0;
-+        }
-+    }
-+    felem_mul(tmp, z1, z2);
-+    felem_reduce(z1, tmp);
-+    felem_mul(tmp, y_in, z1);
-+    felem_reduce(y_in, tmp);
-+    felem_contract(y_out, y_in);
-+    if (y != NULL) {
-+        if (!felem_to_BN(y, y_out)) {
-+            ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
-+                  ERR_R_BN_LIB);
-+            return 0;
-+        }
-+    }
-+    return 1;
-+}
-+
-+static void make_points_affine(size_t num, felem points[ /* num */ ][3],
-+                               felem tmp_felems[ /* num+1 */ ])
-+{
-+    /*
-+     * Runs in constant time, unless an input is the point at infinity (which
-+     * normally shouldn't happen).
-+     */
-+    ec_GFp_nistp_points_make_affine_internal(num,
-+                                             points,
-+                                             sizeof(felem),
-+                                             tmp_felems,
-+                                             (void (*)(void *))felem_one,
-+                                             (int (*)(const void *))
-+                                             felem_is_zero_int,
-+                                             (void (*)(void *, const void *))
-+                                             felem_assign,
-+                                             (void (*)(void *, const void *))
-+                                             felem_square_reduce, (void (*)
-+                                                                   (void *,
-+                                                                    const void
-+                                                                    *,
-+                                                                    const void
-+                                                                    *))
-+                                             felem_mul_reduce,
-+                                             (void (*)(void *, const void *))
-+                                             felem_inv,
-+                                             (void (*)(void *, const void *))
-+                                             felem_contract);
-+}
-+
-+/*
-+ * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
-+ * values Result is stored in r (r can equal one of the inputs).
-+ */
-+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
-+                               const BIGNUM *scalar, size_t num,
-+                               const EC_POINT *points[],
-+                               const BIGNUM *scalars[], BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    int j;
-+    unsigned i;
-+    int mixed = 0;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *x, *y, *z, *tmp_scalar;
-+    felem_bytearray g_secret;
-+    felem_bytearray *secrets = NULL;
-+    felem (*pre_comp)[17][3] = NULL;
-+    felem *tmp_felems = NULL;
-+    felem_bytearray tmp;
-+    unsigned num_bytes;
-+    int have_pre_comp = 0;
-+    size_t num_points = num;
-+    felem x_in, y_in, z_in, x_out, y_out, z_out;
-+    NISTP224_PRE_COMP *pre = NULL;
-+    const felem(*g_pre_comp)[16][3] = NULL;
-+    EC_POINT *generator = NULL;
-+    const EC_POINT *p = NULL;
-+    const BIGNUM *p_scalar = NULL;
-+
-+    if (ctx == NULL)
-+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+    BN_CTX_start(ctx);
-+    if (((x = BN_CTX_get(ctx)) == NULL) ||
-+        ((y = BN_CTX_get(ctx)) == NULL) ||
-+        ((z = BN_CTX_get(ctx)) == NULL) ||
-+        ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
-+        goto err;
-+
-+    if (scalar != NULL) {
-+        pre = group->pre_comp.nistp224;
-+        if (pre)
-+            /* we have precomputation, try to use it */
-+            g_pre_comp = (const felem(*)[16][3])pre->g_pre_comp;
-+        else
-+            /* try to use the standard precomputation */
-+            g_pre_comp = &gmul[0];
-+        generator = EC_POINT_new(group);
-+        if (generator == NULL)
-+            goto err;
-+        /* get the generator from precomputation */
-+        if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
-+            !felem_to_BN(y, g_pre_comp[0][1][1]) ||
-+            !felem_to_BN(z, g_pre_comp[0][1][2])) {
-+            ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+        if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
-+                                                      generator, x, y, z,
-+                                                      ctx))
-+            goto err;
-+        if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
-+            /* precomputation matches generator */
-+            have_pre_comp = 1;
-+        else
-+            /*
-+             * we don't have valid precomputation: treat the generator as a
-+             * random point
-+             */
-+            num_points = num_points + 1;
-+    }
-+
-+    if (num_points > 0) {
-+        if (num_points >= 3) {
-+            /*
-+             * unless we precompute multiples for just one or two points,
-+             * converting those into affine form is time well spent
-+             */
-+            mixed = 1;
-+        }
-+        secrets = OPENSSL_zalloc(sizeof(*secrets) * num_points);
-+        pre_comp = OPENSSL_zalloc(sizeof(*pre_comp) * num_points);
-+        if (mixed)
-+            tmp_felems =
-+                OPENSSL_malloc(sizeof(felem) * (num_points * 17 + 1));
-+        if ((secrets == NULL) || (pre_comp == NULL)
-+            || (mixed && (tmp_felems == NULL))) {
-+            ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+
-+        /*
-+         * we treat NULL scalars as 0, and NULL points as points at infinity,
-+         * i.e., they contribute nothing to the linear combination
-+         */
-+        for (i = 0; i < num_points; ++i) {
-+            if (i == num)
-+                /* the generator */
-+            {
-+                p = EC_GROUP_get0_generator(group);
-+                p_scalar = scalar;
-+            } else
-+                /* the i^th point */
-+            {
-+                p = points[i];
-+                p_scalar = scalars[i];
-+            }
-+            if ((p_scalar != NULL) && (p != NULL)) {
-+                /* reduce scalar to 0 <= scalar < 2^224 */
-+                if ((BN_num_bits(p_scalar) > 224)
-+                    || (BN_is_negative(p_scalar))) {
-+                    /*
-+                     * this is an unusual input, and we don't guarantee
-+                     * constant-timeness
-+                     */
-+                    if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
-+                        ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
-+                        goto err;
-+                    }
-+                    num_bytes = BN_bn2bin(tmp_scalar, tmp);
-+                } else
-+                    num_bytes = BN_bn2bin(p_scalar, tmp);
-+                flip_endian(secrets[i], tmp, num_bytes);
-+                /* precompute multiples */
-+                if ((!BN_to_felem(x_out, p->X)) ||
-+                    (!BN_to_felem(y_out, p->Y)) ||
-+                    (!BN_to_felem(z_out, p->Z)))
-+                    goto err;
-+                felem_assign(pre_comp[i][1][0], x_out);
-+                felem_assign(pre_comp[i][1][1], y_out);
-+                felem_assign(pre_comp[i][1][2], z_out);
-+                for (j = 2; j <= 16; ++j) {
-+                    if (j & 1) {
-+                        point_add(pre_comp[i][j][0], pre_comp[i][j][1],
-+                                  pre_comp[i][j][2], pre_comp[i][1][0],
-+                                  pre_comp[i][1][1], pre_comp[i][1][2], 0,
-+                                  pre_comp[i][j - 1][0],
-+                                  pre_comp[i][j - 1][1],
-+                                  pre_comp[i][j - 1][2]);
-+                    } else {
-+                        point_double(pre_comp[i][j][0], pre_comp[i][j][1],
-+                                     pre_comp[i][j][2], pre_comp[i][j / 2][0],
-+                                     pre_comp[i][j / 2][1],
-+                                     pre_comp[i][j / 2][2]);
-+                    }
-+                }
-+            }
-+        }
-+        if (mixed)
-+            make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
-+    }
-+
-+    /* the scalar for the generator */
-+    if ((scalar != NULL) && (have_pre_comp)) {
-+        memset(g_secret, 0, sizeof(g_secret));
-+        /* reduce scalar to 0 <= scalar < 2^224 */
-+        if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar))) {
-+            /*
-+             * this is an unusual input, and we don't guarantee
-+             * constant-timeness
-+             */
-+            if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
-+                ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
-+                goto err;
-+            }
-+            num_bytes = BN_bn2bin(tmp_scalar, tmp);
-+        } else
-+            num_bytes = BN_bn2bin(scalar, tmp);
-+        flip_endian(g_secret, tmp, num_bytes);
-+        /* do the multiplication with generator precomputation */
-+        batch_mul(x_out, y_out, z_out,
-+                  (const felem_bytearray(*))secrets, num_points,
-+                  g_secret,
-+                  mixed, (const felem(*)[17][3])pre_comp, g_pre_comp);
-+    } else
-+        /* do the multiplication without generator precomputation */
-+        batch_mul(x_out, y_out, z_out,
-+                  (const felem_bytearray(*))secrets, num_points,
-+                  NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
-+    /* reduce the output to its unique minimal representation */
-+    felem_contract(x_in, x_out);
-+    felem_contract(y_in, y_out);
-+    felem_contract(z_in, z_out);
-+    if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
-+        (!felem_to_BN(z, z_in))) {
-+        ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    EC_POINT_free(generator);
-+    BN_CTX_free(new_ctx);
-+    OPENSSL_free(secrets);
-+    OPENSSL_free(pre_comp);
-+    OPENSSL_free(tmp_felems);
-+    return ret;
-+}
-+
-+int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    NISTP224_PRE_COMP *pre = NULL;
-+    int i, j;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *x, *y;
-+    EC_POINT *generator = NULL;
-+    felem tmp_felems[32];
-+
-+    /* throw away old precomputation */
-+    EC_pre_comp_free(group);
-+    if (ctx == NULL)
-+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+    BN_CTX_start(ctx);
-+    if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
-+        goto err;
-+    /* get the generator */
-+    if (group->generator == NULL)
-+        goto err;
-+    generator = EC_POINT_new(group);
-+    if (generator == NULL)
-+        goto err;
-+    BN_bin2bn(nistp224_curve_params[3], sizeof(felem_bytearray), x);
-+    BN_bin2bn(nistp224_curve_params[4], sizeof(felem_bytearray), y);
-+    if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
-+        goto err;
-+    if ((pre = nistp224_pre_comp_new()) == NULL)
-+        goto err;
-+    /*
-+     * if the generator is the standard one, use built-in precomputation
-+     */
-+    if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
-+        memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
-+        goto done;
-+    }
-+    if ((!BN_to_felem(pre->g_pre_comp[0][1][0], group->generator->X)) ||
-+        (!BN_to_felem(pre->g_pre_comp[0][1][1], group->generator->Y)) ||
-+        (!BN_to_felem(pre->g_pre_comp[0][1][2], group->generator->Z)))
-+        goto err;
-+    /*
-+     * compute 2^56*G, 2^112*G, 2^168*G for the first table, 2^28*G, 2^84*G,
-+     * 2^140*G, 2^196*G for the second one
-+     */
-+    for (i = 1; i <= 8; i <<= 1) {
-+        point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
-+                     pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0],
-+                     pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
-+        for (j = 0; j < 27; ++j) {
-+            point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
-+                         pre->g_pre_comp[1][i][2], pre->g_pre_comp[1][i][0],
-+                         pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
-+        }
-+        if (i == 8)
-+            break;
-+        point_double(pre->g_pre_comp[0][2 * i][0],
-+                     pre->g_pre_comp[0][2 * i][1],
-+                     pre->g_pre_comp[0][2 * i][2], pre->g_pre_comp[1][i][0],
-+                     pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
-+        for (j = 0; j < 27; ++j) {
-+            point_double(pre->g_pre_comp[0][2 * i][0],
-+                         pre->g_pre_comp[0][2 * i][1],
-+                         pre->g_pre_comp[0][2 * i][2],
-+                         pre->g_pre_comp[0][2 * i][0],
-+                         pre->g_pre_comp[0][2 * i][1],
-+                         pre->g_pre_comp[0][2 * i][2]);
-+        }
-+    }
-+    for (i = 0; i < 2; i++) {
-+        /* g_pre_comp[i][0] is the point at infinity */
-+        memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
-+        /* the remaining multiples */
-+        /* 2^56*G + 2^112*G resp. 2^84*G + 2^140*G */
-+        point_add(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1],
-+                  pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0],
-+                  pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
-+                  0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
-+                  pre->g_pre_comp[i][2][2]);
-+        /* 2^56*G + 2^168*G resp. 2^84*G + 2^196*G */
-+        point_add(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1],
-+                  pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0],
-+                  pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
-+                  0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
-+                  pre->g_pre_comp[i][2][2]);
-+        /* 2^112*G + 2^168*G resp. 2^140*G + 2^196*G */
-+        point_add(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1],
-+                  pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0],
-+                  pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
-+                  0, pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1],
-+                  pre->g_pre_comp[i][4][2]);
-+        /*
-+         * 2^56*G + 2^112*G + 2^168*G resp. 2^84*G + 2^140*G + 2^196*G
-+         */
-+        point_add(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1],
-+                  pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0],
-+                  pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
-+                  0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
-+                  pre->g_pre_comp[i][2][2]);
-+        for (j = 1; j < 8; ++j) {
-+            /* odd multiples: add G resp. 2^28*G */
-+            point_add(pre->g_pre_comp[i][2 * j + 1][0],
-+                      pre->g_pre_comp[i][2 * j + 1][1],
-+                      pre->g_pre_comp[i][2 * j + 1][2],
-+                      pre->g_pre_comp[i][2 * j][0],
-+                      pre->g_pre_comp[i][2 * j][1],
-+                      pre->g_pre_comp[i][2 * j][2], 0,
-+                      pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1],
-+                      pre->g_pre_comp[i][1][2]);
-+        }
-+    }
-+    make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems);
-+
-+ done:
-+    SETPRECOMP(group, nistp224, pre);
-+    pre = NULL;
-+    ret = 1;
-+ err:
-+    BN_CTX_end(ctx);
-+    EC_POINT_free(generator);
-+    BN_CTX_free(new_ctx);
-+    EC_nistp224_pre_comp_free(pre);
-+    return ret;
-+}
-+
-+int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
-+{
-+    return HAVEPRECOMP(group, nistp224);
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp256.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp256.c
-new file mode 100644
-index 0000000..8cd7222
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp256.c
-@@ -0,0 +1,2350 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Copyright 2011 Google Inc.
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the "License");
-+ *
-+ * you may not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ *     http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+
-+/*
-+ * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication
-+ *
-+ * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
-+ * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
-+ * work which got its smarts from Daniel J. Bernstein's work on the same.
-+ */
-+
-+#include 
-+#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+# include 
-+# include 
-+# include "ec_lcl.h"
-+
-+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-+  /* even with gcc, the typedef won't work for 32-bit platforms */
-+typedef __uint128_t uint128_t;  /* nonstandard; implemented by gcc on 64-bit
-+                                 * platforms */
-+typedef __int128_t int128_t;
-+# else
-+#  error "Need GCC 3.1 or later to define type uint128_t"
-+# endif
-+
-+typedef uint8_t u8;
-+typedef uint32_t u32;
-+typedef uint64_t u64;
-+typedef int64_t s64;
-+
-+/*
-+ * The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We
-+ * can serialise an element of this field into 32 bytes. We call this an
-+ * felem_bytearray.
-+ */
-+
-+typedef u8 felem_bytearray[32];
-+
-+/*
-+ * These are the parameters of P256, taken from FIPS 186-3, page 86. These
-+ * values are big-endian.
-+ */
-+static const felem_bytearray nistp256_curve_params[5] = {
-+    {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */
-+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
-+    {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */
-+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */
-+    {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
-+     0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
-+     0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
-+     0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
-+    {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */
-+     0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
-+     0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
-+     0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96},
-+    {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */
-+     0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
-+     0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
-+     0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5}
-+};
-+
-+/*-
-+ * The representation of field elements.
-+ * ------------------------------------
-+ *
-+ * We represent field elements with either four 128-bit values, eight 128-bit
-+ * values, or four 64-bit values. The field element represented is:
-+ *   v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192  (mod p)
-+ * or:
-+ *   v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512  (mod p)
-+ *
-+ * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits
-+ * apart, but are 128-bits wide, the most significant bits of each limb overlap
-+ * with the least significant bits of the next.
-+ *
-+ * A field element with four limbs is an 'felem'. One with eight limbs is a
-+ * 'longfelem'
-+ *
-+ * A field element with four, 64-bit values is called a 'smallfelem'. Small
-+ * values are used as intermediate values before multiplication.
-+ */
-+
-+# define NLIMBS 4
-+
-+typedef uint128_t limb;
-+typedef limb felem[NLIMBS];
-+typedef limb longfelem[NLIMBS * 2];
-+typedef u64 smallfelem[NLIMBS];
-+
-+/* This is the value of the prime as four 64-bit words, little-endian. */
-+static const u64 kPrime[4] =
-+    { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul };
-+static const u64 bottom63bits = 0x7ffffffffffffffful;
-+
-+/*
-+ * bin32_to_felem takes a little-endian byte array and converts it into felem
-+ * form. This assumes that the CPU is little-endian.
-+ */
-+static void bin32_to_felem(felem out, const u8 in[32])
-+{
-+    out[0] = *((u64 *)&in[0]);
-+    out[1] = *((u64 *)&in[8]);
-+    out[2] = *((u64 *)&in[16]);
-+    out[3] = *((u64 *)&in[24]);
-+}
-+
-+/*
-+ * smallfelem_to_bin32 takes a smallfelem and serialises into a little
-+ * endian, 32 byte array. This assumes that the CPU is little-endian.
-+ */
-+static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
-+{
-+    *((u64 *)&out[0]) = in[0];
-+    *((u64 *)&out[8]) = in[1];
-+    *((u64 *)&out[16]) = in[2];
-+    *((u64 *)&out[24]) = in[3];
-+}
-+
-+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-+static void flip_endian(u8 *out, const u8 *in, unsigned len)
-+{
-+    unsigned i;
-+    for (i = 0; i < len; ++i)
-+        out[i] = in[len - 1 - i];
-+}
-+
-+/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
-+static int BN_to_felem(felem out, const BIGNUM *bn)
-+{
-+    felem_bytearray b_in;
-+    felem_bytearray b_out;
-+    unsigned num_bytes;
-+
-+    /* BN_bn2bin eats leading zeroes */
-+    memset(b_out, 0, sizeof(b_out));
-+    num_bytes = BN_num_bytes(bn);
-+    if (num_bytes > sizeof b_out) {
-+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
-+        return 0;
-+    }
-+    if (BN_is_negative(bn)) {
-+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
-+        return 0;
-+    }
-+    num_bytes = BN_bn2bin(bn, b_in);
-+    flip_endian(b_out, b_in, num_bytes);
-+    bin32_to_felem(out, b_out);
-+    return 1;
-+}
-+
-+/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
-+static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in)
-+{
-+    felem_bytearray b_in, b_out;
-+    smallfelem_to_bin32(b_in, in);
-+    flip_endian(b_out, b_in, sizeof b_out);
-+    return BN_bin2bn(b_out, sizeof b_out, out);
-+}
-+
-+/*-
-+ * Field operations
-+ * ----------------
-+ */
-+
-+static void smallfelem_one(smallfelem out)
-+{
-+    out[0] = 1;
-+    out[1] = 0;
-+    out[2] = 0;
-+    out[3] = 0;
-+}
-+
-+static void smallfelem_assign(smallfelem out, const smallfelem in)
-+{
-+    out[0] = in[0];
-+    out[1] = in[1];
-+    out[2] = in[2];
-+    out[3] = in[3];
-+}
-+
-+static void felem_assign(felem out, const felem in)
-+{
-+    out[0] = in[0];
-+    out[1] = in[1];
-+    out[2] = in[2];
-+    out[3] = in[3];
-+}
-+
-+/* felem_sum sets out = out + in. */
-+static void felem_sum(felem out, const felem in)
-+{
-+    out[0] += in[0];
-+    out[1] += in[1];
-+    out[2] += in[2];
-+    out[3] += in[3];
-+}
-+
-+/* felem_small_sum sets out = out + in. */
-+static void felem_small_sum(felem out, const smallfelem in)
-+{
-+    out[0] += in[0];
-+    out[1] += in[1];
-+    out[2] += in[2];
-+    out[3] += in[3];
-+}
-+
-+/* felem_scalar sets out = out * scalar */
-+static void felem_scalar(felem out, const u64 scalar)
-+{
-+    out[0] *= scalar;
-+    out[1] *= scalar;
-+    out[2] *= scalar;
-+    out[3] *= scalar;
-+}
-+
-+/* longfelem_scalar sets out = out * scalar */
-+static void longfelem_scalar(longfelem out, const u64 scalar)
-+{
-+    out[0] *= scalar;
-+    out[1] *= scalar;
-+    out[2] *= scalar;
-+    out[3] *= scalar;
-+    out[4] *= scalar;
-+    out[5] *= scalar;
-+    out[6] *= scalar;
-+    out[7] *= scalar;
-+}
-+
-+# define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
-+# define two105 (((limb)1) << 105)
-+# define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
-+
-+/* zero105 is 0 mod p */
-+static const felem zero105 =
-+    { two105m41m9, two105, two105m41p9, two105m41p9 };
-+
-+/*-
-+ * smallfelem_neg sets |out| to |-small|
-+ * On exit:
-+ *   out[i] < out[i] + 2^105
-+ */
-+static void smallfelem_neg(felem out, const smallfelem small)
-+{
-+    /* In order to prevent underflow, we subtract from 0 mod p. */
-+    out[0] = zero105[0] - small[0];
-+    out[1] = zero105[1] - small[1];
-+    out[2] = zero105[2] - small[2];
-+    out[3] = zero105[3] - small[3];
-+}
-+
-+/*-
-+ * felem_diff subtracts |in| from |out|
-+ * On entry:
-+ *   in[i] < 2^104
-+ * On exit:
-+ *   out[i] < out[i] + 2^105
-+ */
-+static void felem_diff(felem out, const felem in)
-+{
-+    /*
-+     * In order to prevent underflow, we add 0 mod p before subtracting.
-+     */
-+    out[0] += zero105[0];
-+    out[1] += zero105[1];
-+    out[2] += zero105[2];
-+    out[3] += zero105[3];
-+
-+    out[0] -= in[0];
-+    out[1] -= in[1];
-+    out[2] -= in[2];
-+    out[3] -= in[3];
-+}
-+
-+# define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
-+# define two107 (((limb)1) << 107)
-+# define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
-+
-+/* zero107 is 0 mod p */
-+static const felem zero107 =
-+    { two107m43m11, two107, two107m43p11, two107m43p11 };
-+
-+/*-
-+ * An alternative felem_diff for larger inputs |in|
-+ * felem_diff_zero107 subtracts |in| from |out|
-+ * On entry:
-+ *   in[i] < 2^106
-+ * On exit:
-+ *   out[i] < out[i] + 2^107
-+ */
-+static void felem_diff_zero107(felem out, const felem in)
-+{
-+    /*
-+     * In order to prevent underflow, we add 0 mod p before subtracting.
-+     */
-+    out[0] += zero107[0];
-+    out[1] += zero107[1];
-+    out[2] += zero107[2];
-+    out[3] += zero107[3];
-+
-+    out[0] -= in[0];
-+    out[1] -= in[1];
-+    out[2] -= in[2];
-+    out[3] -= in[3];
-+}
-+
-+/*-
-+ * longfelem_diff subtracts |in| from |out|
-+ * On entry:
-+ *   in[i] < 7*2^67
-+ * On exit:
-+ *   out[i] < out[i] + 2^70 + 2^40
-+ */
-+static void longfelem_diff(longfelem out, const longfelem in)
-+{
-+    static const limb two70m8p6 =
-+        (((limb) 1) << 70) - (((limb) 1) << 8) + (((limb) 1) << 6);
-+    static const limb two70p40 = (((limb) 1) << 70) + (((limb) 1) << 40);
-+    static const limb two70 = (((limb) 1) << 70);
-+    static const limb two70m40m38p6 =
-+        (((limb) 1) << 70) - (((limb) 1) << 40) - (((limb) 1) << 38) +
-+        (((limb) 1) << 6);
-+    static const limb two70m6 = (((limb) 1) << 70) - (((limb) 1) << 6);
-+
-+    /* add 0 mod p to avoid underflow */
-+    out[0] += two70m8p6;
-+    out[1] += two70p40;
-+    out[2] += two70;
-+    out[3] += two70m40m38p6;
-+    out[4] += two70m6;
-+    out[5] += two70m6;
-+    out[6] += two70m6;
-+    out[7] += two70m6;
-+
-+    /* in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6 */
-+    out[0] -= in[0];
-+    out[1] -= in[1];
-+    out[2] -= in[2];
-+    out[3] -= in[3];
-+    out[4] -= in[4];
-+    out[5] -= in[5];
-+    out[6] -= in[6];
-+    out[7] -= in[7];
-+}
-+
-+# define two64m0 (((limb)1) << 64) - 1
-+# define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
-+# define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
-+# define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
-+
-+/* zero110 is 0 mod p */
-+static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 };
-+
-+/*-
-+ * felem_shrink converts an felem into a smallfelem. The result isn't quite
-+ * minimal as the value may be greater than p.
-+ *
-+ * On entry:
-+ *   in[i] < 2^109
-+ * On exit:
-+ *   out[i] < 2^64
-+ */
-+static void felem_shrink(smallfelem out, const felem in)
-+{
-+    felem tmp;
-+    u64 a, b, mask;
-+    s64 high, low;
-+    static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */
-+
-+    /* Carry 2->3 */
-+    tmp[3] = zero110[3] + in[3] + ((u64)(in[2] >> 64));
-+    /* tmp[3] < 2^110 */
-+
-+    tmp[2] = zero110[2] + (u64)in[2];
-+    tmp[0] = zero110[0] + in[0];
-+    tmp[1] = zero110[1] + in[1];
-+    /* tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65 */
-+
-+    /*
-+     * We perform two partial reductions where we eliminate the high-word of
-+     * tmp[3]. We don't update the other words till the end.
-+     */
-+    a = tmp[3] >> 64;           /* a < 2^46 */
-+    tmp[3] = (u64)tmp[3];
-+    tmp[3] -= a;
-+    tmp[3] += ((limb) a) << 32;
-+    /* tmp[3] < 2^79 */
-+
-+    b = a;
-+    a = tmp[3] >> 64;           /* a < 2^15 */
-+    b += a;                     /* b < 2^46 + 2^15 < 2^47 */
-+    tmp[3] = (u64)tmp[3];
-+    tmp[3] -= a;
-+    tmp[3] += ((limb) a) << 32;
-+    /* tmp[3] < 2^64 + 2^47 */
-+
-+    /*
-+     * This adjusts the other two words to complete the two partial
-+     * reductions.
-+     */
-+    tmp[0] += b;
-+    tmp[1] -= (((limb) b) << 32);
-+
-+    /*
-+     * In order to make space in tmp[3] for the carry from 2 -> 3, we
-+     * conditionally subtract kPrime if tmp[3] is large enough.
-+     */
-+    high = tmp[3] >> 64;
-+    /* As tmp[3] < 2^65, high is either 1 or 0 */
-+    high <<= 63;
-+    high >>= 63;
-+    /*-
-+     * high is:
-+     *   all ones   if the high word of tmp[3] is 1
-+     *   all zeros  if the high word of tmp[3] if 0 */
-+    low = tmp[3];
-+    mask = low >> 63;
-+    /*-
-+     * mask is:
-+     *   all ones   if the MSB of low is 1
-+     *   all zeros  if the MSB of low if 0 */
-+    low &= bottom63bits;
-+    low -= kPrime3Test;
-+    /* if low was greater than kPrime3Test then the MSB is zero */
-+    low = ~low;
-+    low >>= 63;
-+    /*-
-+     * low is:
-+     *   all ones   if low was > kPrime3Test
-+     *   all zeros  if low was <= kPrime3Test */
-+    mask = (mask & low) | high;
-+    tmp[0] -= mask & kPrime[0];
-+    tmp[1] -= mask & kPrime[1];
-+    /* kPrime[2] is zero, so omitted */
-+    tmp[3] -= mask & kPrime[3];
-+    /* tmp[3] < 2**64 - 2**32 + 1 */
-+
-+    tmp[1] += ((u64)(tmp[0] >> 64));
-+    tmp[0] = (u64)tmp[0];
-+    tmp[2] += ((u64)(tmp[1] >> 64));
-+    tmp[1] = (u64)tmp[1];
-+    tmp[3] += ((u64)(tmp[2] >> 64));
-+    tmp[2] = (u64)tmp[2];
-+    /* tmp[i] < 2^64 */
-+
-+    out[0] = tmp[0];
-+    out[1] = tmp[1];
-+    out[2] = tmp[2];
-+    out[3] = tmp[3];
-+}
-+
-+/* smallfelem_expand converts a smallfelem to an felem */
-+static void smallfelem_expand(felem out, const smallfelem in)
-+{
-+    out[0] = in[0];
-+    out[1] = in[1];
-+    out[2] = in[2];
-+    out[3] = in[3];
-+}
-+
-+/*-
-+ * smallfelem_square sets |out| = |small|^2
-+ * On entry:
-+ *   small[i] < 2^64
-+ * On exit:
-+ *   out[i] < 7 * 2^64 < 2^67
-+ */
-+static void smallfelem_square(longfelem out, const smallfelem small)
-+{
-+    limb a;
-+    u64 high, low;
-+
-+    a = ((uint128_t) small[0]) * small[0];
-+    low = a;
-+    high = a >> 64;
-+    out[0] = low;
-+    out[1] = high;
-+
-+    a = ((uint128_t) small[0]) * small[1];
-+    low = a;
-+    high = a >> 64;
-+    out[1] += low;
-+    out[1] += low;
-+    out[2] = high;
-+
-+    a = ((uint128_t) small[0]) * small[2];
-+    low = a;
-+    high = a >> 64;
-+    out[2] += low;
-+    out[2] *= 2;
-+    out[3] = high;
-+
-+    a = ((uint128_t) small[0]) * small[3];
-+    low = a;
-+    high = a >> 64;
-+    out[3] += low;
-+    out[4] = high;
-+
-+    a = ((uint128_t) small[1]) * small[2];
-+    low = a;
-+    high = a >> 64;
-+    out[3] += low;
-+    out[3] *= 2;
-+    out[4] += high;
-+
-+    a = ((uint128_t) small[1]) * small[1];
-+    low = a;
-+    high = a >> 64;
-+    out[2] += low;
-+    out[3] += high;
-+
-+    a = ((uint128_t) small[1]) * small[3];
-+    low = a;
-+    high = a >> 64;
-+    out[4] += low;
-+    out[4] *= 2;
-+    out[5] = high;
-+
-+    a = ((uint128_t) small[2]) * small[3];
-+    low = a;
-+    high = a >> 64;
-+    out[5] += low;
-+    out[5] *= 2;
-+    out[6] = high;
-+    out[6] += high;
-+
-+    a = ((uint128_t) small[2]) * small[2];
-+    low = a;
-+    high = a >> 64;
-+    out[4] += low;
-+    out[5] += high;
-+
-+    a = ((uint128_t) small[3]) * small[3];
-+    low = a;
-+    high = a >> 64;
-+    out[6] += low;
-+    out[7] = high;
-+}
-+
-+/*-
-+ * felem_square sets |out| = |in|^2
-+ * On entry:
-+ *   in[i] < 2^109
-+ * On exit:
-+ *   out[i] < 7 * 2^64 < 2^67
-+ */
-+static void felem_square(longfelem out, const felem in)
-+{
-+    u64 small[4];
-+    felem_shrink(small, in);
-+    smallfelem_square(out, small);
-+}
-+
-+/*-
-+ * smallfelem_mul sets |out| = |small1| * |small2|
-+ * On entry:
-+ *   small1[i] < 2^64
-+ *   small2[i] < 2^64
-+ * On exit:
-+ *   out[i] < 7 * 2^64 < 2^67
-+ */
-+static void smallfelem_mul(longfelem out, const smallfelem small1,
-+                           const smallfelem small2)
-+{
-+    limb a;
-+    u64 high, low;
-+
-+    a = ((uint128_t) small1[0]) * small2[0];
-+    low = a;
-+    high = a >> 64;
-+    out[0] = low;
-+    out[1] = high;
-+
-+    a = ((uint128_t) small1[0]) * small2[1];
-+    low = a;
-+    high = a >> 64;
-+    out[1] += low;
-+    out[2] = high;
-+
-+    a = ((uint128_t) small1[1]) * small2[0];
-+    low = a;
-+    high = a >> 64;
-+    out[1] += low;
-+    out[2] += high;
-+
-+    a = ((uint128_t) small1[0]) * small2[2];
-+    low = a;
-+    high = a >> 64;
-+    out[2] += low;
-+    out[3] = high;
-+
-+    a = ((uint128_t) small1[1]) * small2[1];
-+    low = a;
-+    high = a >> 64;
-+    out[2] += low;
-+    out[3] += high;
-+
-+    a = ((uint128_t) small1[2]) * small2[0];
-+    low = a;
-+    high = a >> 64;
-+    out[2] += low;
-+    out[3] += high;
-+
-+    a = ((uint128_t) small1[0]) * small2[3];
-+    low = a;
-+    high = a >> 64;
-+    out[3] += low;
-+    out[4] = high;
-+
-+    a = ((uint128_t) small1[1]) * small2[2];
-+    low = a;
-+    high = a >> 64;
-+    out[3] += low;
-+    out[4] += high;
-+
-+    a = ((uint128_t) small1[2]) * small2[1];
-+    low = a;
-+    high = a >> 64;
-+    out[3] += low;
-+    out[4] += high;
-+
-+    a = ((uint128_t) small1[3]) * small2[0];
-+    low = a;
-+    high = a >> 64;
-+    out[3] += low;
-+    out[4] += high;
-+
-+    a = ((uint128_t) small1[1]) * small2[3];
-+    low = a;
-+    high = a >> 64;
-+    out[4] += low;
-+    out[5] = high;
-+
-+    a = ((uint128_t) small1[2]) * small2[2];
-+    low = a;
-+    high = a >> 64;
-+    out[4] += low;
-+    out[5] += high;
-+
-+    a = ((uint128_t) small1[3]) * small2[1];
-+    low = a;
-+    high = a >> 64;
-+    out[4] += low;
-+    out[5] += high;
-+
-+    a = ((uint128_t) small1[2]) * small2[3];
-+    low = a;
-+    high = a >> 64;
-+    out[5] += low;
-+    out[6] = high;
-+
-+    a = ((uint128_t) small1[3]) * small2[2];
-+    low = a;
-+    high = a >> 64;
-+    out[5] += low;
-+    out[6] += high;
-+
-+    a = ((uint128_t) small1[3]) * small2[3];
-+    low = a;
-+    high = a >> 64;
-+    out[6] += low;
-+    out[7] = high;
-+}
-+
-+/*-
-+ * felem_mul sets |out| = |in1| * |in2|
-+ * On entry:
-+ *   in1[i] < 2^109
-+ *   in2[i] < 2^109
-+ * On exit:
-+ *   out[i] < 7 * 2^64 < 2^67
-+ */
-+static void felem_mul(longfelem out, const felem in1, const felem in2)
-+{
-+    smallfelem small1, small2;
-+    felem_shrink(small1, in1);
-+    felem_shrink(small2, in2);
-+    smallfelem_mul(out, small1, small2);
-+}
-+
-+/*-
-+ * felem_small_mul sets |out| = |small1| * |in2|
-+ * On entry:
-+ *   small1[i] < 2^64
-+ *   in2[i] < 2^109
-+ * On exit:
-+ *   out[i] < 7 * 2^64 < 2^67
-+ */
-+static void felem_small_mul(longfelem out, const smallfelem small1,
-+                            const felem in2)
-+{
-+    smallfelem small2;
-+    felem_shrink(small2, in2);
-+    smallfelem_mul(out, small1, small2);
-+}
-+
-+# define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
-+# define two100 (((limb)1) << 100)
-+# define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
-+/* zero100 is 0 mod p */
-+static const felem zero100 =
-+    { two100m36m4, two100, two100m36p4, two100m36p4 };
-+
-+/*-
-+ * Internal function for the different flavours of felem_reduce.
-+ * felem_reduce_ reduces the higher coefficients in[4]-in[7].
-+ * On entry:
-+ *   out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7]
-+ *   out[1] >= in[7] + 2^32*in[4]
-+ *   out[2] >= in[5] + 2^32*in[5]
-+ *   out[3] >= in[4] + 2^32*in[5] + 2^32*in[6]
-+ * On exit:
-+ *   out[0] <= out[0] + in[4] + 2^32*in[5]
-+ *   out[1] <= out[1] + in[5] + 2^33*in[6]
-+ *   out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7]
-+ *   out[3] <= out[3] + 2^32*in[4] + 3*in[7]
-+ */
-+static void felem_reduce_(felem out, const longfelem in)
-+{
-+    int128_t c;
-+    /* combine common terms from below */
-+    c = in[4] + (in[5] << 32);
-+    out[0] += c;
-+    out[3] -= c;
-+
-+    c = in[5] - in[7];
-+    out[1] += c;
-+    out[2] -= c;
-+
-+    /* the remaining terms */
-+    /* 256: [(0,1),(96,-1),(192,-1),(224,1)] */
-+    out[1] -= (in[4] << 32);
-+    out[3] += (in[4] << 32);
-+
-+    /* 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)] */
-+    out[2] -= (in[5] << 32);
-+
-+    /* 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)] */
-+    out[0] -= in[6];
-+    out[0] -= (in[6] << 32);
-+    out[1] += (in[6] << 33);
-+    out[2] += (in[6] * 2);
-+    out[3] -= (in[6] << 32);
-+
-+    /* 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)] */
-+    out[0] -= in[7];
-+    out[0] -= (in[7] << 32);
-+    out[2] += (in[7] << 33);
-+    out[3] += (in[7] * 3);
-+}
-+
-+/*-
-+ * felem_reduce converts a longfelem into an felem.
-+ * To be called directly after felem_square or felem_mul.
-+ * On entry:
-+ *   in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64
-+ *   in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64
-+ * On exit:
-+ *   out[i] < 2^101
-+ */
-+static void felem_reduce(felem out, const longfelem in)
-+{
-+    out[0] = zero100[0] + in[0];
-+    out[1] = zero100[1] + in[1];
-+    out[2] = zero100[2] + in[2];
-+    out[3] = zero100[3] + in[3];
-+
-+    felem_reduce_(out, in);
-+
-+    /*-
-+     * out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0
-+     * out[1] > 2^100 - 2^64 - 7*2^96 > 0
-+     * out[2] > 2^100 - 2^36 + 2^4 - 5*2^64 - 5*2^96 > 0
-+     * out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96 - 3*2^96 > 0
-+     *
-+     * out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101
-+     * out[1] < 2^100 + 3*2^64 + 5*2^64 + 3*2^97 < 2^101
-+     * out[2] < 2^100 + 5*2^64 + 2^64 + 3*2^65 + 2^97 < 2^101
-+     * out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 < 2^101
-+     */
-+}
-+
-+/*-
-+ * felem_reduce_zero105 converts a larger longfelem into an felem.
-+ * On entry:
-+ *   in[0] < 2^71
-+ * On exit:
-+ *   out[i] < 2^106
-+ */
-+static void felem_reduce_zero105(felem out, const longfelem in)
-+{
-+    out[0] = zero105[0] + in[0];
-+    out[1] = zero105[1] + in[1];
-+    out[2] = zero105[2] + in[2];
-+    out[3] = zero105[3] + in[3];
-+
-+    felem_reduce_(out, in);
-+
-+    /*-
-+     * out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0
-+     * out[1] > 2^105 - 2^71 - 2^103 > 0
-+     * out[2] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 > 0
-+     * out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 - 2^103 > 0
-+     *
-+     * out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
-+     * out[1] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
-+     * out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 < 2^106
-+     * out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106
-+     */
-+}
-+
-+/*
-+ * subtract_u64 sets *result = *result - v and *carry to one if the
-+ * subtraction underflowed.
-+ */
-+static void subtract_u64(u64 *result, u64 *carry, u64 v)
-+{
-+    uint128_t r = *result;
-+    r -= v;
-+    *carry = (r >> 64) & 1;
-+    *result = (u64)r;
-+}
-+
-+/*
-+ * felem_contract converts |in| to its unique, minimal representation. On
-+ * entry: in[i] < 2^109
-+ */
-+static void felem_contract(smallfelem out, const felem in)
-+{
-+    unsigned i;
-+    u64 all_equal_so_far = 0, result = 0, carry;
-+
-+    felem_shrink(out, in);
-+    /* small is minimal except that the value might be > p */
-+
-+    all_equal_so_far--;
-+    /*
-+     * We are doing a constant time test if out >= kPrime. We need to compare
-+     * each u64, from most-significant to least significant. For each one, if
-+     * all words so far have been equal (m is all ones) then a non-equal
-+     * result is the answer. Otherwise we continue.
-+     */
-+    for (i = 3; i < 4; i--) {
-+        u64 equal;
-+        uint128_t a = ((uint128_t) kPrime[i]) - out[i];
-+        /*
-+         * if out[i] > kPrime[i] then a will underflow and the high 64-bits
-+         * will all be set.
-+         */
-+        result |= all_equal_so_far & ((u64)(a >> 64));
-+
-+        /*
-+         * if kPrime[i] == out[i] then |equal| will be all zeros and the
-+         * decrement will make it all ones.
-+         */
-+        equal = kPrime[i] ^ out[i];
-+        equal--;
-+        equal &= equal << 32;
-+        equal &= equal << 16;
-+        equal &= equal << 8;
-+        equal &= equal << 4;
-+        equal &= equal << 2;
-+        equal &= equal << 1;
-+        equal = ((s64) equal) >> 63;
-+
-+        all_equal_so_far &= equal;
-+    }
-+
-+    /*
-+     * if all_equal_so_far is still all ones then the two values are equal
-+     * and so out >= kPrime is true.
-+     */
-+    result |= all_equal_so_far;
-+
-+    /* if out >= kPrime then we subtract kPrime. */
-+    subtract_u64(&out[0], &carry, result & kPrime[0]);
-+    subtract_u64(&out[1], &carry, carry);
-+    subtract_u64(&out[2], &carry, carry);
-+    subtract_u64(&out[3], &carry, carry);
-+
-+    subtract_u64(&out[1], &carry, result & kPrime[1]);
-+    subtract_u64(&out[2], &carry, carry);
-+    subtract_u64(&out[3], &carry, carry);
-+
-+    subtract_u64(&out[2], &carry, result & kPrime[2]);
-+    subtract_u64(&out[3], &carry, carry);
-+
-+    subtract_u64(&out[3], &carry, result & kPrime[3]);
-+}
-+
-+static void smallfelem_square_contract(smallfelem out, const smallfelem in)
-+{
-+    longfelem longtmp;
-+    felem tmp;
-+
-+    smallfelem_square(longtmp, in);
-+    felem_reduce(tmp, longtmp);
-+    felem_contract(out, tmp);
-+}
-+
-+static void smallfelem_mul_contract(smallfelem out, const smallfelem in1,
-+                                    const smallfelem in2)
-+{
-+    longfelem longtmp;
-+    felem tmp;
-+
-+    smallfelem_mul(longtmp, in1, in2);
-+    felem_reduce(tmp, longtmp);
-+    felem_contract(out, tmp);
-+}
-+
-+/*-
-+ * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
-+ * otherwise.
-+ * On entry:
-+ *   small[i] < 2^64
-+ */
-+static limb smallfelem_is_zero(const smallfelem small)
-+{
-+    limb result;
-+    u64 is_p;
-+
-+    u64 is_zero = small[0] | small[1] | small[2] | small[3];
-+    is_zero--;
-+    is_zero &= is_zero << 32;
-+    is_zero &= is_zero << 16;
-+    is_zero &= is_zero << 8;
-+    is_zero &= is_zero << 4;
-+    is_zero &= is_zero << 2;
-+    is_zero &= is_zero << 1;
-+    is_zero = ((s64) is_zero) >> 63;
-+
-+    is_p = (small[0] ^ kPrime[0]) |
-+        (small[1] ^ kPrime[1]) |
-+        (small[2] ^ kPrime[2]) | (small[3] ^ kPrime[3]);
-+    is_p--;
-+    is_p &= is_p << 32;
-+    is_p &= is_p << 16;
-+    is_p &= is_p << 8;
-+    is_p &= is_p << 4;
-+    is_p &= is_p << 2;
-+    is_p &= is_p << 1;
-+    is_p = ((s64) is_p) >> 63;
-+
-+    is_zero |= is_p;
-+
-+    result = is_zero;
-+    result |= ((limb) is_zero) << 64;
-+    return result;
-+}
-+
-+static int smallfelem_is_zero_int(const smallfelem small)
-+{
-+    return (int)(smallfelem_is_zero(small) & ((limb) 1));
-+}
-+
-+/*-
-+ * felem_inv calculates |out| = |in|^{-1}
-+ *
-+ * Based on Fermat's Little Theorem:
-+ *   a^p = a (mod p)
-+ *   a^{p-1} = 1 (mod p)
-+ *   a^{p-2} = a^{-1} (mod p)
-+ */
-+static void felem_inv(felem out, const felem in)
-+{
-+    felem ftmp, ftmp2;
-+    /* each e_I will hold |in|^{2^I - 1} */
-+    felem e2, e4, e8, e16, e32, e64;
-+    longfelem tmp;
-+    unsigned i;
-+
-+    felem_square(tmp, in);
-+    felem_reduce(ftmp, tmp);    /* 2^1 */
-+    felem_mul(tmp, in, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^2 - 2^0 */
-+    felem_assign(e2, ftmp);
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^3 - 2^1 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^4 - 2^2 */
-+    felem_mul(tmp, ftmp, e2);
-+    felem_reduce(ftmp, tmp);    /* 2^4 - 2^0 */
-+    felem_assign(e4, ftmp);
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^5 - 2^1 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^6 - 2^2 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^7 - 2^3 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^8 - 2^4 */
-+    felem_mul(tmp, ftmp, e4);
-+    felem_reduce(ftmp, tmp);    /* 2^8 - 2^0 */
-+    felem_assign(e8, ftmp);
-+    for (i = 0; i < 8; i++) {
-+        felem_square(tmp, ftmp);
-+        felem_reduce(ftmp, tmp);
-+    }                           /* 2^16 - 2^8 */
-+    felem_mul(tmp, ftmp, e8);
-+    felem_reduce(ftmp, tmp);    /* 2^16 - 2^0 */
-+    felem_assign(e16, ftmp);
-+    for (i = 0; i < 16; i++) {
-+        felem_square(tmp, ftmp);
-+        felem_reduce(ftmp, tmp);
-+    }                           /* 2^32 - 2^16 */
-+    felem_mul(tmp, ftmp, e16);
-+    felem_reduce(ftmp, tmp);    /* 2^32 - 2^0 */
-+    felem_assign(e32, ftmp);
-+    for (i = 0; i < 32; i++) {
-+        felem_square(tmp, ftmp);
-+        felem_reduce(ftmp, tmp);
-+    }                           /* 2^64 - 2^32 */
-+    felem_assign(e64, ftmp);
-+    felem_mul(tmp, ftmp, in);
-+    felem_reduce(ftmp, tmp);    /* 2^64 - 2^32 + 2^0 */
-+    for (i = 0; i < 192; i++) {
-+        felem_square(tmp, ftmp);
-+        felem_reduce(ftmp, tmp);
-+    }                           /* 2^256 - 2^224 + 2^192 */
-+
-+    felem_mul(tmp, e64, e32);
-+    felem_reduce(ftmp2, tmp);   /* 2^64 - 2^0 */
-+    for (i = 0; i < 16; i++) {
-+        felem_square(tmp, ftmp2);
-+        felem_reduce(ftmp2, tmp);
-+    }                           /* 2^80 - 2^16 */
-+    felem_mul(tmp, ftmp2, e16);
-+    felem_reduce(ftmp2, tmp);   /* 2^80 - 2^0 */
-+    for (i = 0; i < 8; i++) {
-+        felem_square(tmp, ftmp2);
-+        felem_reduce(ftmp2, tmp);
-+    }                           /* 2^88 - 2^8 */
-+    felem_mul(tmp, ftmp2, e8);
-+    felem_reduce(ftmp2, tmp);   /* 2^88 - 2^0 */
-+    for (i = 0; i < 4; i++) {
-+        felem_square(tmp, ftmp2);
-+        felem_reduce(ftmp2, tmp);
-+    }                           /* 2^92 - 2^4 */
-+    felem_mul(tmp, ftmp2, e4);
-+    felem_reduce(ftmp2, tmp);   /* 2^92 - 2^0 */
-+    felem_square(tmp, ftmp2);
-+    felem_reduce(ftmp2, tmp);   /* 2^93 - 2^1 */
-+    felem_square(tmp, ftmp2);
-+    felem_reduce(ftmp2, tmp);   /* 2^94 - 2^2 */
-+    felem_mul(tmp, ftmp2, e2);
-+    felem_reduce(ftmp2, tmp);   /* 2^94 - 2^0 */
-+    felem_square(tmp, ftmp2);
-+    felem_reduce(ftmp2, tmp);   /* 2^95 - 2^1 */
-+    felem_square(tmp, ftmp2);
-+    felem_reduce(ftmp2, tmp);   /* 2^96 - 2^2 */
-+    felem_mul(tmp, ftmp2, in);
-+    felem_reduce(ftmp2, tmp);   /* 2^96 - 3 */
-+
-+    felem_mul(tmp, ftmp2, ftmp);
-+    felem_reduce(out, tmp);     /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
-+}
-+
-+static void smallfelem_inv_contract(smallfelem out, const smallfelem in)
-+{
-+    felem tmp;
-+
-+    smallfelem_expand(tmp, in);
-+    felem_inv(tmp, tmp);
-+    felem_contract(out, tmp);
-+}
-+
-+/*-
-+ * Group operations
-+ * ----------------
-+ *
-+ * Building on top of the field operations we have the operations on the
-+ * elliptic curve group itself. Points on the curve are represented in Jacobian
-+ * coordinates
-+ */
-+
-+/*-
-+ * point_double calculates 2*(x_in, y_in, z_in)
-+ *
-+ * The method is taken from:
-+ *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
-+ *
-+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
-+ * while x_out == y_in is not (maybe this works, but it's not tested).
-+ */
-+static void
-+point_double(felem x_out, felem y_out, felem z_out,
-+             const felem x_in, const felem y_in, const felem z_in)
-+{
-+    longfelem tmp, tmp2;
-+    felem delta, gamma, beta, alpha, ftmp, ftmp2;
-+    smallfelem small1, small2;
-+
-+    felem_assign(ftmp, x_in);
-+    /* ftmp[i] < 2^106 */
-+    felem_assign(ftmp2, x_in);
-+    /* ftmp2[i] < 2^106 */
-+
-+    /* delta = z^2 */
-+    felem_square(tmp, z_in);
-+    felem_reduce(delta, tmp);
-+    /* delta[i] < 2^101 */
-+
-+    /* gamma = y^2 */
-+    felem_square(tmp, y_in);
-+    felem_reduce(gamma, tmp);
-+    /* gamma[i] < 2^101 */
-+    felem_shrink(small1, gamma);
-+
-+    /* beta = x*gamma */
-+    felem_small_mul(tmp, small1, x_in);
-+    felem_reduce(beta, tmp);
-+    /* beta[i] < 2^101 */
-+
-+    /* alpha = 3*(x-delta)*(x+delta) */
-+    felem_diff(ftmp, delta);
-+    /* ftmp[i] < 2^105 + 2^106 < 2^107 */
-+    felem_sum(ftmp2, delta);
-+    /* ftmp2[i] < 2^105 + 2^106 < 2^107 */
-+    felem_scalar(ftmp2, 3);
-+    /* ftmp2[i] < 3 * 2^107 < 2^109 */
-+    felem_mul(tmp, ftmp, ftmp2);
-+    felem_reduce(alpha, tmp);
-+    /* alpha[i] < 2^101 */
-+    felem_shrink(small2, alpha);
-+
-+    /* x' = alpha^2 - 8*beta */
-+    smallfelem_square(tmp, small2);
-+    felem_reduce(x_out, tmp);
-+    felem_assign(ftmp, beta);
-+    felem_scalar(ftmp, 8);
-+    /* ftmp[i] < 8 * 2^101 = 2^104 */
-+    felem_diff(x_out, ftmp);
-+    /* x_out[i] < 2^105 + 2^101 < 2^106 */
-+
-+    /* z' = (y + z)^2 - gamma - delta */
-+    felem_sum(delta, gamma);
-+    /* delta[i] < 2^101 + 2^101 = 2^102 */
-+    felem_assign(ftmp, y_in);
-+    felem_sum(ftmp, z_in);
-+    /* ftmp[i] < 2^106 + 2^106 = 2^107 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(z_out, tmp);
-+    felem_diff(z_out, delta);
-+    /* z_out[i] < 2^105 + 2^101 < 2^106 */
-+
-+    /* y' = alpha*(4*beta - x') - 8*gamma^2 */
-+    felem_scalar(beta, 4);
-+    /* beta[i] < 4 * 2^101 = 2^103 */
-+    felem_diff_zero107(beta, x_out);
-+    /* beta[i] < 2^107 + 2^103 < 2^108 */
-+    felem_small_mul(tmp, small2, beta);
-+    /* tmp[i] < 7 * 2^64 < 2^67 */
-+    smallfelem_square(tmp2, small1);
-+    /* tmp2[i] < 7 * 2^64 */
-+    longfelem_scalar(tmp2, 8);
-+    /* tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67 */
-+    longfelem_diff(tmp, tmp2);
-+    /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
-+    felem_reduce_zero105(y_out, tmp);
-+    /* y_out[i] < 2^106 */
-+}
-+
-+/*
-+ * point_double_small is the same as point_double, except that it operates on
-+ * smallfelems
-+ */
-+static void
-+point_double_small(smallfelem x_out, smallfelem y_out, smallfelem z_out,
-+                   const smallfelem x_in, const smallfelem y_in,
-+                   const smallfelem z_in)
-+{
-+    felem felem_x_out, felem_y_out, felem_z_out;
-+    felem felem_x_in, felem_y_in, felem_z_in;
-+
-+    smallfelem_expand(felem_x_in, x_in);
-+    smallfelem_expand(felem_y_in, y_in);
-+    smallfelem_expand(felem_z_in, z_in);
-+    point_double(felem_x_out, felem_y_out, felem_z_out,
-+                 felem_x_in, felem_y_in, felem_z_in);
-+    felem_shrink(x_out, felem_x_out);
-+    felem_shrink(y_out, felem_y_out);
-+    felem_shrink(z_out, felem_z_out);
-+}
-+
-+/* copy_conditional copies in to out iff mask is all ones. */
-+static void copy_conditional(felem out, const felem in, limb mask)
-+{
-+    unsigned i;
-+    for (i = 0; i < NLIMBS; ++i) {
-+        const limb tmp = mask & (in[i] ^ out[i]);
-+        out[i] ^= tmp;
-+    }
-+}
-+
-+/* copy_small_conditional copies in to out iff mask is all ones. */
-+static void copy_small_conditional(felem out, const smallfelem in, limb mask)
-+{
-+    unsigned i;
-+    const u64 mask64 = mask;
-+    for (i = 0; i < NLIMBS; ++i) {
-+        out[i] = ((limb) (in[i] & mask64)) | (out[i] & ~mask);
-+    }
-+}
-+
-+/*-
-+ * point_add calculates (x1, y1, z1) + (x2, y2, z2)
-+ *
-+ * The method is taken from:
-+ *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
-+ * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
-+ *
-+ * This function includes a branch for checking whether the two input points
-+ * are equal, (while not equal to the point at infinity). This case never
-+ * happens during single point multiplication, so there is no timing leak for
-+ * ECDH or ECDSA signing.
-+ */
-+static void point_add(felem x3, felem y3, felem z3,
-+                      const felem x1, const felem y1, const felem z1,
-+                      const int mixed, const smallfelem x2,
-+                      const smallfelem y2, const smallfelem z2)
-+{
-+    felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
-+    longfelem tmp, tmp2;
-+    smallfelem small1, small2, small3, small4, small5;
-+    limb x_equal, y_equal, z1_is_zero, z2_is_zero;
-+
-+    felem_shrink(small3, z1);
-+
-+    z1_is_zero = smallfelem_is_zero(small3);
-+    z2_is_zero = smallfelem_is_zero(z2);
-+
-+    /* ftmp = z1z1 = z1**2 */
-+    smallfelem_square(tmp, small3);
-+    felem_reduce(ftmp, tmp);
-+    /* ftmp[i] < 2^101 */
-+    felem_shrink(small1, ftmp);
-+
-+    if (!mixed) {
-+        /* ftmp2 = z2z2 = z2**2 */
-+        smallfelem_square(tmp, z2);
-+        felem_reduce(ftmp2, tmp);
-+        /* ftmp2[i] < 2^101 */
-+        felem_shrink(small2, ftmp2);
-+
-+        felem_shrink(small5, x1);
-+
-+        /* u1 = ftmp3 = x1*z2z2 */
-+        smallfelem_mul(tmp, small5, small2);
-+        felem_reduce(ftmp3, tmp);
-+        /* ftmp3[i] < 2^101 */
-+
-+        /* ftmp5 = z1 + z2 */
-+        felem_assign(ftmp5, z1);
-+        felem_small_sum(ftmp5, z2);
-+        /* ftmp5[i] < 2^107 */
-+
-+        /* ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 */
-+        felem_square(tmp, ftmp5);
-+        felem_reduce(ftmp5, tmp);
-+        /* ftmp2 = z2z2 + z1z1 */
-+        felem_sum(ftmp2, ftmp);
-+        /* ftmp2[i] < 2^101 + 2^101 = 2^102 */
-+        felem_diff(ftmp5, ftmp2);
-+        /* ftmp5[i] < 2^105 + 2^101 < 2^106 */
-+
-+        /* ftmp2 = z2 * z2z2 */
-+        smallfelem_mul(tmp, small2, z2);
-+        felem_reduce(ftmp2, tmp);
-+
-+        /* s1 = ftmp2 = y1 * z2**3 */
-+        felem_mul(tmp, y1, ftmp2);
-+        felem_reduce(ftmp6, tmp);
-+        /* ftmp6[i] < 2^101 */
-+    } else {
-+        /*
-+         * We'll assume z2 = 1 (special case z2 = 0 is handled later)
-+         */
-+
-+        /* u1 = ftmp3 = x1*z2z2 */
-+        felem_assign(ftmp3, x1);
-+        /* ftmp3[i] < 2^106 */
-+
-+        /* ftmp5 = 2z1z2 */
-+        felem_assign(ftmp5, z1);
-+        felem_scalar(ftmp5, 2);
-+        /* ftmp5[i] < 2*2^106 = 2^107 */
-+
-+        /* s1 = ftmp2 = y1 * z2**3 */
-+        felem_assign(ftmp6, y1);
-+        /* ftmp6[i] < 2^106 */
-+    }
-+
-+    /* u2 = x2*z1z1 */
-+    smallfelem_mul(tmp, x2, small1);
-+    felem_reduce(ftmp4, tmp);
-+
-+    /* h = ftmp4 = u2 - u1 */
-+    felem_diff_zero107(ftmp4, ftmp3);
-+    /* ftmp4[i] < 2^107 + 2^101 < 2^108 */
-+    felem_shrink(small4, ftmp4);
-+
-+    x_equal = smallfelem_is_zero(small4);
-+
-+    /* z_out = ftmp5 * h */
-+    felem_small_mul(tmp, small4, ftmp5);
-+    felem_reduce(z_out, tmp);
-+    /* z_out[i] < 2^101 */
-+
-+    /* ftmp = z1 * z1z1 */
-+    smallfelem_mul(tmp, small1, small3);
-+    felem_reduce(ftmp, tmp);
-+
-+    /* s2 = tmp = y2 * z1**3 */
-+    felem_small_mul(tmp, y2, ftmp);
-+    felem_reduce(ftmp5, tmp);
-+
-+    /* r = ftmp5 = (s2 - s1)*2 */
-+    felem_diff_zero107(ftmp5, ftmp6);
-+    /* ftmp5[i] < 2^107 + 2^107 = 2^108 */
-+    felem_scalar(ftmp5, 2);
-+    /* ftmp5[i] < 2^109 */
-+    felem_shrink(small1, ftmp5);
-+    y_equal = smallfelem_is_zero(small1);
-+
-+    if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
-+        point_double(x3, y3, z3, x1, y1, z1);
-+        return;
-+    }
-+
-+    /* I = ftmp = (2h)**2 */
-+    felem_assign(ftmp, ftmp4);
-+    felem_scalar(ftmp, 2);
-+    /* ftmp[i] < 2*2^108 = 2^109 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);
-+
-+    /* J = ftmp2 = h * I */
-+    felem_mul(tmp, ftmp4, ftmp);
-+    felem_reduce(ftmp2, tmp);
-+
-+    /* V = ftmp4 = U1 * I */
-+    felem_mul(tmp, ftmp3, ftmp);
-+    felem_reduce(ftmp4, tmp);
-+
-+    /* x_out = r**2 - J - 2V */
-+    smallfelem_square(tmp, small1);
-+    felem_reduce(x_out, tmp);
-+    felem_assign(ftmp3, ftmp4);
-+    felem_scalar(ftmp4, 2);
-+    felem_sum(ftmp4, ftmp2);
-+    /* ftmp4[i] < 2*2^101 + 2^101 < 2^103 */
-+    felem_diff(x_out, ftmp4);
-+    /* x_out[i] < 2^105 + 2^101 */
-+
-+    /* y_out = r(V-x_out) - 2 * s1 * J */
-+    felem_diff_zero107(ftmp3, x_out);
-+    /* ftmp3[i] < 2^107 + 2^101 < 2^108 */
-+    felem_small_mul(tmp, small1, ftmp3);
-+    felem_mul(tmp2, ftmp6, ftmp2);
-+    longfelem_scalar(tmp2, 2);
-+    /* tmp2[i] < 2*2^67 = 2^68 */
-+    longfelem_diff(tmp, tmp2);
-+    /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
-+    felem_reduce_zero105(y_out, tmp);
-+    /* y_out[i] < 2^106 */
-+
-+    copy_small_conditional(x_out, x2, z1_is_zero);
-+    copy_conditional(x_out, x1, z2_is_zero);
-+    copy_small_conditional(y_out, y2, z1_is_zero);
-+    copy_conditional(y_out, y1, z2_is_zero);
-+    copy_small_conditional(z_out, z2, z1_is_zero);
-+    copy_conditional(z_out, z1, z2_is_zero);
-+    felem_assign(x3, x_out);
-+    felem_assign(y3, y_out);
-+    felem_assign(z3, z_out);
-+}
-+
-+/*
-+ * point_add_small is the same as point_add, except that it operates on
-+ * smallfelems
-+ */
-+static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
-+                            smallfelem x1, smallfelem y1, smallfelem z1,
-+                            smallfelem x2, smallfelem y2, smallfelem z2)
-+{
-+    felem felem_x3, felem_y3, felem_z3;
-+    felem felem_x1, felem_y1, felem_z1;
-+    smallfelem_expand(felem_x1, x1);
-+    smallfelem_expand(felem_y1, y1);
-+    smallfelem_expand(felem_z1, z1);
-+    point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0,
-+              x2, y2, z2);
-+    felem_shrink(x3, felem_x3);
-+    felem_shrink(y3, felem_y3);
-+    felem_shrink(z3, felem_z3);
-+}
-+
-+/*-
-+ * Base point pre computation
-+ * --------------------------
-+ *
-+ * Two different sorts of precomputed tables are used in the following code.
-+ * Each contain various points on the curve, where each point is three field
-+ * elements (x, y, z).
-+ *
-+ * For the base point table, z is usually 1 (0 for the point at infinity).
-+ * This table has 2 * 16 elements, starting with the following:
-+ * index | bits    | point
-+ * ------+---------+------------------------------
-+ *     0 | 0 0 0 0 | 0G
-+ *     1 | 0 0 0 1 | 1G
-+ *     2 | 0 0 1 0 | 2^64G
-+ *     3 | 0 0 1 1 | (2^64 + 1)G
-+ *     4 | 0 1 0 0 | 2^128G
-+ *     5 | 0 1 0 1 | (2^128 + 1)G
-+ *     6 | 0 1 1 0 | (2^128 + 2^64)G
-+ *     7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
-+ *     8 | 1 0 0 0 | 2^192G
-+ *     9 | 1 0 0 1 | (2^192 + 1)G
-+ *    10 | 1 0 1 0 | (2^192 + 2^64)G
-+ *    11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
-+ *    12 | 1 1 0 0 | (2^192 + 2^128)G
-+ *    13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
-+ *    14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
-+ *    15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
-+ * followed by a copy of this with each element multiplied by 2^32.
-+ *
-+ * The reason for this is so that we can clock bits into four different
-+ * locations when doing simple scalar multiplies against the base point,
-+ * and then another four locations using the second 16 elements.
-+ *
-+ * Tables for other points have table[i] = iG for i in 0 .. 16. */
-+
-+/* gmul is the table of precomputed base points */
-+static const smallfelem gmul[2][16][3] = {
-+    {{{0, 0, 0, 0},
-+      {0, 0, 0, 0},
-+      {0, 0, 0, 0}},
-+     {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2,
-+       0x6b17d1f2e12c4247},
-+      {0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16,
-+       0x4fe342e2fe1a7f9b},
-+      {1, 0, 0, 0}},
-+     {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de,
-+       0x0fa822bc2811aaa5},
-+      {0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b,
-+       0xbff44ae8f5dba80d},
-+      {1, 0, 0, 0}},
-+     {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789,
-+       0x300a4bbc89d6726f},
-+      {0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f,
-+       0x72aac7e0d09b4644},
-+      {1, 0, 0, 0}},
-+     {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e,
-+       0x447d739beedb5e67},
-+      {0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7,
-+       0x2d4825ab834131ee},
-+      {1, 0, 0, 0}},
-+     {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60,
-+       0xef9519328a9c72ff},
-+      {0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c,
-+       0x611e9fc37dbb2c9b},
-+      {1, 0, 0, 0}},
-+     {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf,
-+       0x550663797b51f5d8},
-+      {0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5,
-+       0x157164848aecb851},
-+      {1, 0, 0, 0}},
-+     {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391,
-+       0xeb5d7745b21141ea},
-+      {0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee,
-+       0xeafd72ebdbecc17b},
-+      {1, 0, 0, 0}},
-+     {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5,
-+       0xa6d39677a7849276},
-+      {0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf,
-+       0x674f84749b0b8816},
-+      {1, 0, 0, 0}},
-+     {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb,
-+       0x4e769e7672c9ddad},
-+      {0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281,
-+       0x42b99082de830663},
-+      {1, 0, 0, 0}},
-+     {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478,
-+       0x78878ef61c6ce04d},
-+      {0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def,
-+       0xb6cb3f5d7b72c321},
-+      {1, 0, 0, 0}},
-+     {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae,
-+       0x0c88bc4d716b1287},
-+      {0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa,
-+       0xdd5ddea3f3901dc6},
-+      {1, 0, 0, 0}},
-+     {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3,
-+       0x68f344af6b317466},
-+      {0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3,
-+       0x31b9c405f8540a20},
-+      {1, 0, 0, 0}},
-+     {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0,
-+       0x4052bf4b6f461db9},
-+      {0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8,
-+       0xfecf4d5190b0fc61},
-+      {1, 0, 0, 0}},
-+     {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a,
-+       0x1eddbae2c802e41a},
-+      {0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0,
-+       0x43104d86560ebcfc},
-+      {1, 0, 0, 0}},
-+     {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a,
-+       0xb48e26b484f7a21c},
-+      {0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668,
-+       0xfac015404d4d3dab},
-+      {1, 0, 0, 0}}},
-+    {{{0, 0, 0, 0},
-+      {0, 0, 0, 0},
-+      {0, 0, 0, 0}},
-+     {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da,
-+       0x7fe36b40af22af89},
-+      {0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1,
-+       0xe697d45825b63624},
-+      {1, 0, 0, 0}},
-+     {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902,
-+       0x4a5b506612a677a6},
-+      {0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40,
-+       0xeb13461ceac089f1},
-+      {1, 0, 0, 0}},
-+     {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857,
-+       0x0781b8291c6a220a},
-+      {0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434,
-+       0x690cde8df0151593},
-+      {1, 0, 0, 0}},
-+     {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326,
-+       0x8a535f566ec73617},
-+      {0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf,
-+       0x0455c08468b08bd7},
-+      {1, 0, 0, 0}},
-+     {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279,
-+       0x06bada7ab77f8276},
-+      {0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70,
-+       0x5b476dfd0e6cb18a},
-+      {1, 0, 0, 0}},
-+     {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8,
-+       0x3e29864e8a2ec908},
-+      {0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed,
-+       0x239b90ea3dc31e7e},
-+      {1, 0, 0, 0}},
-+     {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4,
-+       0x820f4dd949f72ff7},
-+      {0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3,
-+       0x140406ec783a05ec},
-+      {1, 0, 0, 0}},
-+     {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe,
-+       0x68f6b8542783dfee},
-+      {0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028,
-+       0xcbe1feba92e40ce6},
-+      {1, 0, 0, 0}},
-+     {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927,
-+       0xd0b2f94d2f420109},
-+      {0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a,
-+       0x971459828b0719e5},
-+      {1, 0, 0, 0}},
-+     {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687,
-+       0x961610004a866aba},
-+      {0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c,
-+       0x7acb9fadcee75e44},
-+      {1, 0, 0, 0}},
-+     {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea,
-+       0x24eb9acca333bf5b},
-+      {0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d,
-+       0x69f891c5acd079cc},
-+      {1, 0, 0, 0}},
-+     {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514,
-+       0xe51f547c5972a107},
-+      {0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06,
-+       0x1c309a2b25bb1387},
-+      {1, 0, 0, 0}},
-+     {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828,
-+       0x20b87b8aa2c4e503},
-+      {0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044,
-+       0xf5c6fa49919776be},
-+      {1, 0, 0, 0}},
-+     {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56,
-+       0x1ed7d1b9332010b9},
-+      {0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24,
-+       0x3a2b03f03217257a},
-+      {1, 0, 0, 0}},
-+     {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b,
-+       0x15fee545c78dd9f6},
-+      {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb,
-+       0x4ab5b6b2b8753f81},
-+      {1, 0, 0, 0}}}
-+};
-+
-+/*
-+ * select_point selects the |idx|th point from a precomputation table and
-+ * copies it to out.
-+ */
-+static void select_point(const u64 idx, unsigned int size,
-+                         const smallfelem pre_comp[16][3], smallfelem out[3])
-+{
-+    unsigned i, j;
-+    u64 *outlimbs = &out[0][0];
-+
-+    memset(out, 0, sizeof(*out) * 3);
-+
-+    for (i = 0; i < size; i++) {
-+        const u64 *inlimbs = (u64 *)&pre_comp[i][0][0];
-+        u64 mask = i ^ idx;
-+        mask |= mask >> 4;
-+        mask |= mask >> 2;
-+        mask |= mask >> 1;
-+        mask &= 1;
-+        mask--;
-+        for (j = 0; j < NLIMBS * 3; j++)
-+            outlimbs[j] |= inlimbs[j] & mask;
-+    }
-+}
-+
-+/* get_bit returns the |i|th bit in |in| */
-+static char get_bit(const felem_bytearray in, int i)
-+{
-+    if ((i < 0) || (i >= 256))
-+        return 0;
-+    return (in[i >> 3] >> (i & 7)) & 1;
-+}
-+
-+/*
-+ * Interleaved point multiplication using precomputed point multiples: The
-+ * small point multiples 0*P, 1*P, ..., 17*P are in pre_comp[], the scalars
-+ * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the
-+ * generator, using certain (large) precomputed multiples in g_pre_comp.
-+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out
-+ */
-+static void batch_mul(felem x_out, felem y_out, felem z_out,
-+                      const felem_bytearray scalars[],
-+                      const unsigned num_points, const u8 *g_scalar,
-+                      const int mixed, const smallfelem pre_comp[][17][3],
-+                      const smallfelem g_pre_comp[2][16][3])
-+{
-+    int i, skip;
-+    unsigned num, gen_mul = (g_scalar != NULL);
-+    felem nq[3], ftmp;
-+    smallfelem tmp[3];
-+    u64 bits;
-+    u8 sign, digit;
-+
-+    /* set nq to the point at infinity */
-+    memset(nq, 0, sizeof(nq));
-+
-+    /*
-+     * Loop over all scalars msb-to-lsb, interleaving additions of multiples
-+     * of the generator (two in each of the last 32 rounds) and additions of
-+     * other points multiples (every 5th round).
-+     */
-+    skip = 1;                   /* save two point operations in the first
-+                                 * round */
-+    for (i = (num_points ? 255 : 31); i >= 0; --i) {
-+        /* double */
-+        if (!skip)
-+            point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
-+
-+        /* add multiples of the generator */
-+        if (gen_mul && (i <= 31)) {
-+            /* first, look 32 bits upwards */
-+            bits = get_bit(g_scalar, i + 224) << 3;
-+            bits |= get_bit(g_scalar, i + 160) << 2;
-+            bits |= get_bit(g_scalar, i + 96) << 1;
-+            bits |= get_bit(g_scalar, i + 32);
-+            /* select the point to add, in constant time */
-+            select_point(bits, 16, g_pre_comp[1], tmp);
-+
-+            if (!skip) {
-+                /* Arg 1 below is for "mixed" */
-+                point_add(nq[0], nq[1], nq[2],
-+                          nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
-+            } else {
-+                smallfelem_expand(nq[0], tmp[0]);
-+                smallfelem_expand(nq[1], tmp[1]);
-+                smallfelem_expand(nq[2], tmp[2]);
-+                skip = 0;
-+            }
-+
-+            /* second, look at the current position */
-+            bits = get_bit(g_scalar, i + 192) << 3;
-+            bits |= get_bit(g_scalar, i + 128) << 2;
-+            bits |= get_bit(g_scalar, i + 64) << 1;
-+            bits |= get_bit(g_scalar, i);
-+            /* select the point to add, in constant time */
-+            select_point(bits, 16, g_pre_comp[0], tmp);
-+            /* Arg 1 below is for "mixed" */
-+            point_add(nq[0], nq[1], nq[2],
-+                      nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
-+        }
-+
-+        /* do other additions every 5 doublings */
-+        if (num_points && (i % 5 == 0)) {
-+            /* loop over all scalars */
-+            for (num = 0; num < num_points; ++num) {
-+                bits = get_bit(scalars[num], i + 4) << 5;
-+                bits |= get_bit(scalars[num], i + 3) << 4;
-+                bits |= get_bit(scalars[num], i + 2) << 3;
-+                bits |= get_bit(scalars[num], i + 1) << 2;
-+                bits |= get_bit(scalars[num], i) << 1;
-+                bits |= get_bit(scalars[num], i - 1);
-+                ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
-+
-+                /*
-+                 * select the point to add or subtract, in constant time
-+                 */
-+                select_point(digit, 17, pre_comp[num], tmp);
-+                smallfelem_neg(ftmp, tmp[1]); /* (X, -Y, Z) is the negative
-+                                               * point */
-+                copy_small_conditional(ftmp, tmp[1], (((limb) sign) - 1));
-+                felem_contract(tmp[1], ftmp);
-+
-+                if (!skip) {
-+                    point_add(nq[0], nq[1], nq[2],
-+                              nq[0], nq[1], nq[2],
-+                              mixed, tmp[0], tmp[1], tmp[2]);
-+                } else {
-+                    smallfelem_expand(nq[0], tmp[0]);
-+                    smallfelem_expand(nq[1], tmp[1]);
-+                    smallfelem_expand(nq[2], tmp[2]);
-+                    skip = 0;
-+                }
-+            }
-+        }
-+    }
-+    felem_assign(x_out, nq[0]);
-+    felem_assign(y_out, nq[1]);
-+    felem_assign(z_out, nq[2]);
-+}
-+
-+/* Precomputation for the group generator. */
-+struct nistp256_pre_comp_st {
-+    smallfelem g_pre_comp[2][16][3];
-+    int references;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+const EC_METHOD *EC_GFp_nistp256_method(void)
-+{
-+    static const EC_METHOD ret = {
-+        EC_FLAGS_DEFAULT_OCT,
-+        NID_X9_62_prime_field,
-+        ec_GFp_nistp256_group_init,
-+        ec_GFp_simple_group_finish,
-+        ec_GFp_simple_group_clear_finish,
-+        ec_GFp_nist_group_copy,
-+        ec_GFp_nistp256_group_set_curve,
-+        ec_GFp_simple_group_get_curve,
-+        ec_GFp_simple_group_get_degree,
-+        ec_group_simple_order_bits,
-+        ec_GFp_simple_group_check_discriminant,
-+        ec_GFp_simple_point_init,
-+        ec_GFp_simple_point_finish,
-+        ec_GFp_simple_point_clear_finish,
-+        ec_GFp_simple_point_copy,
-+        ec_GFp_simple_point_set_to_infinity,
-+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_point_set_affine_coordinates,
-+        ec_GFp_nistp256_point_get_affine_coordinates,
-+        0 /* point_set_compressed_coordinates */ ,
-+        0 /* point2oct */ ,
-+        0 /* oct2point */ ,
-+        ec_GFp_simple_add,
-+        ec_GFp_simple_dbl,
-+        ec_GFp_simple_invert,
-+        ec_GFp_simple_is_at_infinity,
-+        ec_GFp_simple_is_on_curve,
-+        ec_GFp_simple_cmp,
-+        ec_GFp_simple_make_affine,
-+        ec_GFp_simple_points_make_affine,
-+        ec_GFp_nistp256_points_mul,
-+        ec_GFp_nistp256_precompute_mult,
-+        ec_GFp_nistp256_have_precompute_mult,
-+        ec_GFp_nist_field_mul,
-+        ec_GFp_nist_field_sqr,
-+        0 /* field_div */ ,
-+        0 /* field_encode */ ,
-+        0 /* field_decode */ ,
-+        0,                      /* field_set_to_one */
-+        ec_key_simple_priv2oct,
-+        ec_key_simple_oct2priv,
-+        0, /* set private */
-+        ec_key_simple_generate_key,
-+        ec_key_simple_check_key,
-+        ec_key_simple_generate_public_key,
-+        0, /* keycopy */
-+        0, /* keyfinish */
-+        ecdh_simple_compute_key
-+    };
-+
-+    return &ret;
-+}
-+
-+/******************************************************************************/
-+/*
-+ * FUNCTIONS TO MANAGE PRECOMPUTATION
-+ */
-+
-+static NISTP256_PRE_COMP *nistp256_pre_comp_new()
-+{
-+    NISTP256_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
-+        return ret;
-+    }
-+
-+    ret->references = 1;
-+
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *p)
-+{
-+    int i;
-+    if (p != NULL)
-+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
-+    return p;
-+}
-+
-+void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre)
-+{
-+    int i;
-+
-+    if (pre == NULL)
-+        return;
-+
-+    CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
-+    REF_PRINT_COUNT("EC_nistp256", x);
-+    if (i > 0)
-+        return;
-+    REF_ASSERT_ISNT(i < 0);
-+
-+    CRYPTO_THREAD_lock_free(pre->lock);
-+    OPENSSL_free(pre);
-+}
-+
-+/******************************************************************************/
-+/*
-+ * OPENSSL EC_METHOD FUNCTIONS
-+ */
-+
-+int ec_GFp_nistp256_group_init(EC_GROUP *group)
-+{
-+    int ret;
-+    ret = ec_GFp_simple_group_init(group);
-+    group->a_is_minus3 = 1;
-+    return ret;
-+}
-+
-+int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
-+                                    const BIGNUM *a, const BIGNUM *b,
-+                                    BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *curve_p, *curve_a, *curve_b;
-+
-+    if (ctx == NULL)
-+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+    BN_CTX_start(ctx);
-+    if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
-+        ((curve_a = BN_CTX_get(ctx)) == NULL) ||
-+        ((curve_b = BN_CTX_get(ctx)) == NULL))
-+        goto err;
-+    BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p);
-+    BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
-+    BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b);
-+    if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
-+        ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE,
-+              EC_R_WRONG_CURVE_PARAMETERS);
-+        goto err;
-+    }
-+    group->field_mod_func = BN_nist_mod_256;
-+    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+/*
-+ * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
-+ * (X/Z^2, Y/Z^3)
-+ */
-+int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
-+                                                 const EC_POINT *point,
-+                                                 BIGNUM *x, BIGNUM *y,
-+                                                 BN_CTX *ctx)
-+{
-+    felem z1, z2, x_in, y_in;
-+    smallfelem x_out, y_out;
-+    longfelem tmp;
-+
-+    if (EC_POINT_is_at_infinity(group, point)) {
-+        ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
-+              EC_R_POINT_AT_INFINITY);
-+        return 0;
-+    }
-+    if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
-+        (!BN_to_felem(z1, point->Z)))
-+        return 0;
-+    felem_inv(z2, z1);
-+    felem_square(tmp, z2);
-+    felem_reduce(z1, tmp);
-+    felem_mul(tmp, x_in, z1);
-+    felem_reduce(x_in, tmp);
-+    felem_contract(x_out, x_in);
-+    if (x != NULL) {
-+        if (!smallfelem_to_BN(x, x_out)) {
-+            ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
-+                  ERR_R_BN_LIB);
-+            return 0;
-+        }
-+    }
-+    felem_mul(tmp, z1, z2);
-+    felem_reduce(z1, tmp);
-+    felem_mul(tmp, y_in, z1);
-+    felem_reduce(y_in, tmp);
-+    felem_contract(y_out, y_in);
-+    if (y != NULL) {
-+        if (!smallfelem_to_BN(y, y_out)) {
-+            ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
-+                  ERR_R_BN_LIB);
-+            return 0;
-+        }
-+    }
-+    return 1;
-+}
-+
-+/* points below is of size |num|, and tmp_smallfelems is of size |num+1| */
-+static void make_points_affine(size_t num, smallfelem points[][3],
-+                               smallfelem tmp_smallfelems[])
-+{
-+    /*
-+     * Runs in constant time, unless an input is the point at infinity (which
-+     * normally shouldn't happen).
-+     */
-+    ec_GFp_nistp_points_make_affine_internal(num,
-+                                             points,
-+                                             sizeof(smallfelem),
-+                                             tmp_smallfelems,
-+                                             (void (*)(void *))smallfelem_one,
-+                                             (int (*)(const void *))
-+                                             smallfelem_is_zero_int,
-+                                             (void (*)(void *, const void *))
-+                                             smallfelem_assign,
-+                                             (void (*)(void *, const void *))
-+                                             smallfelem_square_contract,
-+                                             (void (*)
-+                                              (void *, const void *,
-+                                               const void *))
-+                                             smallfelem_mul_contract,
-+                                             (void (*)(void *, const void *))
-+                                             smallfelem_inv_contract,
-+                                             /* nothing to contract */
-+                                             (void (*)(void *, const void *))
-+                                             smallfelem_assign);
-+}
-+
-+/*
-+ * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
-+ * values Result is stored in r (r can equal one of the inputs).
-+ */
-+int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
-+                               const BIGNUM *scalar, size_t num,
-+                               const EC_POINT *points[],
-+                               const BIGNUM *scalars[], BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    int j;
-+    int mixed = 0;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *x, *y, *z, *tmp_scalar;
-+    felem_bytearray g_secret;
-+    felem_bytearray *secrets = NULL;
-+    smallfelem (*pre_comp)[17][3] = NULL;
-+    smallfelem *tmp_smallfelems = NULL;
-+    felem_bytearray tmp;
-+    unsigned i, num_bytes;
-+    int have_pre_comp = 0;
-+    size_t num_points = num;
-+    smallfelem x_in, y_in, z_in;
-+    felem x_out, y_out, z_out;
-+    NISTP256_PRE_COMP *pre = NULL;
-+    const smallfelem(*g_pre_comp)[16][3] = NULL;
-+    EC_POINT *generator = NULL;
-+    const EC_POINT *p = NULL;
-+    const BIGNUM *p_scalar = NULL;
-+
-+    if (ctx == NULL)
-+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+    BN_CTX_start(ctx);
-+    if (((x = BN_CTX_get(ctx)) == NULL) ||
-+        ((y = BN_CTX_get(ctx)) == NULL) ||
-+        ((z = BN_CTX_get(ctx)) == NULL) ||
-+        ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
-+        goto err;
-+
-+    if (scalar != NULL) {
-+        pre = group->pre_comp.nistp256;
-+        if (pre)
-+            /* we have precomputation, try to use it */
-+            g_pre_comp = (const smallfelem(*)[16][3])pre->g_pre_comp;
-+        else
-+            /* try to use the standard precomputation */
-+            g_pre_comp = &gmul[0];
-+        generator = EC_POINT_new(group);
-+        if (generator == NULL)
-+            goto err;
-+        /* get the generator from precomputation */
-+        if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
-+            !smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
-+            !smallfelem_to_BN(z, g_pre_comp[0][1][2])) {
-+            ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+        if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
-+                                                      generator, x, y, z,
-+                                                      ctx))
-+            goto err;
-+        if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
-+            /* precomputation matches generator */
-+            have_pre_comp = 1;
-+        else
-+            /*
-+             * we don't have valid precomputation: treat the generator as a
-+             * random point
-+             */
-+            num_points++;
-+    }
-+    if (num_points > 0) {
-+        if (num_points >= 3) {
-+            /*
-+             * unless we precompute multiples for just one or two points,
-+             * converting those into affine form is time well spent
-+             */
-+            mixed = 1;
-+        }
-+        secrets = OPENSSL_malloc(sizeof(*secrets) * num_points);
-+        pre_comp = OPENSSL_malloc(sizeof(*pre_comp) * num_points);
-+        if (mixed)
-+            tmp_smallfelems =
-+              OPENSSL_malloc(sizeof(*tmp_smallfelems) * (num_points * 17 + 1));
-+        if ((secrets == NULL) || (pre_comp == NULL)
-+            || (mixed && (tmp_smallfelems == NULL))) {
-+            ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+
-+        /*
-+         * we treat NULL scalars as 0, and NULL points as points at infinity,
-+         * i.e., they contribute nothing to the linear combination
-+         */
-+        memset(secrets, 0, sizeof(*secrets) * num_points);
-+        memset(pre_comp, 0, sizeof(*pre_comp) * num_points);
-+        for (i = 0; i < num_points; ++i) {
-+            if (i == num)
-+                /*
-+                 * we didn't have a valid precomputation, so we pick the
-+                 * generator
-+                 */
-+            {
-+                p = EC_GROUP_get0_generator(group);
-+                p_scalar = scalar;
-+            } else
-+                /* the i^th point */
-+            {
-+                p = points[i];
-+                p_scalar = scalars[i];
-+            }
-+            if ((p_scalar != NULL) && (p != NULL)) {
-+                /* reduce scalar to 0 <= scalar < 2^256 */
-+                if ((BN_num_bits(p_scalar) > 256)
-+                    || (BN_is_negative(p_scalar))) {
-+                    /*
-+                     * this is an unusual input, and we don't guarantee
-+                     * constant-timeness
-+                     */
-+                    if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
-+                        ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
-+                        goto err;
-+                    }
-+                    num_bytes = BN_bn2bin(tmp_scalar, tmp);
-+                } else
-+                    num_bytes = BN_bn2bin(p_scalar, tmp);
-+                flip_endian(secrets[i], tmp, num_bytes);
-+                /* precompute multiples */
-+                if ((!BN_to_felem(x_out, p->X)) ||
-+                    (!BN_to_felem(y_out, p->Y)) ||
-+                    (!BN_to_felem(z_out, p->Z)))
-+                    goto err;
-+                felem_shrink(pre_comp[i][1][0], x_out);
-+                felem_shrink(pre_comp[i][1][1], y_out);
-+                felem_shrink(pre_comp[i][1][2], z_out);
-+                for (j = 2; j <= 16; ++j) {
-+                    if (j & 1) {
-+                        point_add_small(pre_comp[i][j][0], pre_comp[i][j][1],
-+                                        pre_comp[i][j][2], pre_comp[i][1][0],
-+                                        pre_comp[i][1][1], pre_comp[i][1][2],
-+                                        pre_comp[i][j - 1][0],
-+                                        pre_comp[i][j - 1][1],
-+                                        pre_comp[i][j - 1][2]);
-+                    } else {
-+                        point_double_small(pre_comp[i][j][0],
-+                                           pre_comp[i][j][1],
-+                                           pre_comp[i][j][2],
-+                                           pre_comp[i][j / 2][0],
-+                                           pre_comp[i][j / 2][1],
-+                                           pre_comp[i][j / 2][2]);
-+                    }
-+                }
-+            }
-+        }
-+        if (mixed)
-+            make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems);
-+    }
-+
-+    /* the scalar for the generator */
-+    if ((scalar != NULL) && (have_pre_comp)) {
-+        memset(g_secret, 0, sizeof(g_secret));
-+        /* reduce scalar to 0 <= scalar < 2^256 */
-+        if ((BN_num_bits(scalar) > 256) || (BN_is_negative(scalar))) {
-+            /*
-+             * this is an unusual input, and we don't guarantee
-+             * constant-timeness
-+             */
-+            if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
-+                ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
-+                goto err;
-+            }
-+            num_bytes = BN_bn2bin(tmp_scalar, tmp);
-+        } else
-+            num_bytes = BN_bn2bin(scalar, tmp);
-+        flip_endian(g_secret, tmp, num_bytes);
-+        /* do the multiplication with generator precomputation */
-+        batch_mul(x_out, y_out, z_out,
-+                  (const felem_bytearray(*))secrets, num_points,
-+                  g_secret,
-+                  mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp);
-+    } else
-+        /* do the multiplication without generator precomputation */
-+        batch_mul(x_out, y_out, z_out,
-+                  (const felem_bytearray(*))secrets, num_points,
-+                  NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL);
-+    /* reduce the output to its unique minimal representation */
-+    felem_contract(x_in, x_out);
-+    felem_contract(y_in, y_out);
-+    felem_contract(z_in, z_out);
-+    if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) ||
-+        (!smallfelem_to_BN(z, z_in))) {
-+        ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    EC_POINT_free(generator);
-+    BN_CTX_free(new_ctx);
-+    OPENSSL_free(secrets);
-+    OPENSSL_free(pre_comp);
-+    OPENSSL_free(tmp_smallfelems);
-+    return ret;
-+}
-+
-+int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    NISTP256_PRE_COMP *pre = NULL;
-+    int i, j;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *x, *y;
-+    EC_POINT *generator = NULL;
-+    smallfelem tmp_smallfelems[32];
-+    felem x_tmp, y_tmp, z_tmp;
-+
-+    /* throw away old precomputation */
-+    EC_pre_comp_free(group);
-+    if (ctx == NULL)
-+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+    BN_CTX_start(ctx);
-+    if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
-+        goto err;
-+    /* get the generator */
-+    if (group->generator == NULL)
-+        goto err;
-+    generator = EC_POINT_new(group);
-+    if (generator == NULL)
-+        goto err;
-+    BN_bin2bn(nistp256_curve_params[3], sizeof(felem_bytearray), x);
-+    BN_bin2bn(nistp256_curve_params[4], sizeof(felem_bytearray), y);
-+    if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
-+        goto err;
-+    if ((pre = nistp256_pre_comp_new()) == NULL)
-+        goto err;
-+    /*
-+     * if the generator is the standard one, use built-in precomputation
-+     */
-+    if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
-+        memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
-+        goto done;
-+    }
-+    if ((!BN_to_felem(x_tmp, group->generator->X)) ||
-+        (!BN_to_felem(y_tmp, group->generator->Y)) ||
-+        (!BN_to_felem(z_tmp, group->generator->Z)))
-+        goto err;
-+    felem_shrink(pre->g_pre_comp[0][1][0], x_tmp);
-+    felem_shrink(pre->g_pre_comp[0][1][1], y_tmp);
-+    felem_shrink(pre->g_pre_comp[0][1][2], z_tmp);
-+    /*
-+     * compute 2^64*G, 2^128*G, 2^192*G for the first table, 2^32*G, 2^96*G,
-+     * 2^160*G, 2^224*G for the second one
-+     */
-+    for (i = 1; i <= 8; i <<= 1) {
-+        point_double_small(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
-+                           pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0],
-+                           pre->g_pre_comp[0][i][1],
-+                           pre->g_pre_comp[0][i][2]);
-+        for (j = 0; j < 31; ++j) {
-+            point_double_small(pre->g_pre_comp[1][i][0],
-+                               pre->g_pre_comp[1][i][1],
-+                               pre->g_pre_comp[1][i][2],
-+                               pre->g_pre_comp[1][i][0],
-+                               pre->g_pre_comp[1][i][1],
-+                               pre->g_pre_comp[1][i][2]);
-+        }
-+        if (i == 8)
-+            break;
-+        point_double_small(pre->g_pre_comp[0][2 * i][0],
-+                           pre->g_pre_comp[0][2 * i][1],
-+                           pre->g_pre_comp[0][2 * i][2],
-+                           pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
-+                           pre->g_pre_comp[1][i][2]);
-+        for (j = 0; j < 31; ++j) {
-+            point_double_small(pre->g_pre_comp[0][2 * i][0],
-+                               pre->g_pre_comp[0][2 * i][1],
-+                               pre->g_pre_comp[0][2 * i][2],
-+                               pre->g_pre_comp[0][2 * i][0],
-+                               pre->g_pre_comp[0][2 * i][1],
-+                               pre->g_pre_comp[0][2 * i][2]);
-+        }
-+    }
-+    for (i = 0; i < 2; i++) {
-+        /* g_pre_comp[i][0] is the point at infinity */
-+        memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
-+        /* the remaining multiples */
-+        /* 2^64*G + 2^128*G resp. 2^96*G + 2^160*G */
-+        point_add_small(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1],
-+                        pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0],
-+                        pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
-+                        pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
-+                        pre->g_pre_comp[i][2][2]);
-+        /* 2^64*G + 2^192*G resp. 2^96*G + 2^224*G */
-+        point_add_small(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1],
-+                        pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0],
-+                        pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
-+                        pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
-+                        pre->g_pre_comp[i][2][2]);
-+        /* 2^128*G + 2^192*G resp. 2^160*G + 2^224*G */
-+        point_add_small(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1],
-+                        pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0],
-+                        pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
-+                        pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1],
-+                        pre->g_pre_comp[i][4][2]);
-+        /*
-+         * 2^64*G + 2^128*G + 2^192*G resp. 2^96*G + 2^160*G + 2^224*G
-+         */
-+        point_add_small(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1],
-+                        pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0],
-+                        pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
-+                        pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
-+                        pre->g_pre_comp[i][2][2]);
-+        for (j = 1; j < 8; ++j) {
-+            /* odd multiples: add G resp. 2^32*G */
-+            point_add_small(pre->g_pre_comp[i][2 * j + 1][0],
-+                            pre->g_pre_comp[i][2 * j + 1][1],
-+                            pre->g_pre_comp[i][2 * j + 1][2],
-+                            pre->g_pre_comp[i][2 * j][0],
-+                            pre->g_pre_comp[i][2 * j][1],
-+                            pre->g_pre_comp[i][2 * j][2],
-+                            pre->g_pre_comp[i][1][0],
-+                            pre->g_pre_comp[i][1][1],
-+                            pre->g_pre_comp[i][1][2]);
-+        }
-+    }
-+    make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems);
-+
-+ done:
-+    SETPRECOMP(group, nistp256, pre);
-+    pre = NULL;
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    EC_POINT_free(generator);
-+    BN_CTX_free(new_ctx);
-+    EC_nistp256_pre_comp_free(pre);
-+    return ret;
-+}
-+
-+int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group)
-+{
-+    return HAVEPRECOMP(group, nistp256);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp521.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp521.c
-new file mode 100644
-index 0000000..7207494
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistp521.c
-@@ -0,0 +1,2146 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Copyright 2011 Google Inc.
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the "License");
-+ *
-+ * you may not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ *     http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+
-+/*
-+ * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication
-+ *
-+ * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
-+ * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
-+ * work which got its smarts from Daniel J. Bernstein's work on the same.
-+ */
-+
-+#include 
-+#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# ifndef OPENSSL_SYS_VMS
-+#  include 
-+# else
-+#  include 
-+# endif
-+
-+# include 
-+# include 
-+# include "ec_lcl.h"
-+
-+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-+  /* even with gcc, the typedef won't work for 32-bit platforms */
-+typedef __uint128_t uint128_t;  /* nonstandard; implemented by gcc on 64-bit
-+                                 * platforms */
-+# else
-+#  error "Need GCC 3.1 or later to define type uint128_t"
-+# endif
-+
-+typedef uint8_t u8;
-+typedef uint64_t u64;
-+typedef int64_t s64;
-+
-+/*
-+ * The underlying field. P521 operates over GF(2^521-1). We can serialise an
-+ * element of this field into 66 bytes where the most significant byte
-+ * contains only a single bit. We call this an felem_bytearray.
-+ */
-+
-+typedef u8 felem_bytearray[66];
-+
-+/*
-+ * These are the parameters of P521, taken from FIPS 186-3, section D.1.2.5.
-+ * These values are big-endian.
-+ */
-+static const felem_bytearray nistp521_curve_params[5] = {
-+    {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff},
-+    {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a = -3 */
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+     0xff, 0xfc},
-+    {0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, /* b */
-+     0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
-+     0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
-+     0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
-+     0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
-+     0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
-+     0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
-+     0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
-+     0x3f, 0x00},
-+    {0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, /* x */
-+     0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
-+     0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
-+     0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
-+     0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
-+     0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
-+     0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
-+     0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
-+     0xbd, 0x66},
-+    {0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, /* y */
-+     0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
-+     0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
-+     0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
-+     0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
-+     0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
-+     0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
-+     0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
-+     0x66, 0x50}
-+};
-+
-+/*-
-+ * The representation of field elements.
-+ * ------------------------------------
-+ *
-+ * We represent field elements with nine values. These values are either 64 or
-+ * 128 bits and the field element represented is:
-+ *   v[0]*2^0 + v[1]*2^58 + v[2]*2^116 + ... + v[8]*2^464  (mod p)
-+ * Each of the nine values is called a 'limb'. Since the limbs are spaced only
-+ * 58 bits apart, but are greater than 58 bits in length, the most significant
-+ * bits of each limb overlap with the least significant bits of the next.
-+ *
-+ * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a
-+ * 'largefelem' */
-+
-+# define NLIMBS 9
-+
-+typedef uint64_t limb;
-+typedef limb felem[NLIMBS];
-+typedef uint128_t largefelem[NLIMBS];
-+
-+static const limb bottom57bits = 0x1ffffffffffffff;
-+static const limb bottom58bits = 0x3ffffffffffffff;
-+
-+/*
-+ * bin66_to_felem takes a little-endian byte array and converts it into felem
-+ * form. This assumes that the CPU is little-endian.
-+ */
-+static void bin66_to_felem(felem out, const u8 in[66])
-+{
-+    out[0] = (*((limb *) & in[0])) & bottom58bits;
-+    out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits;
-+    out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits;
-+    out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits;
-+    out[4] = (*((limb *) & in[29])) & bottom58bits;
-+    out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits;
-+    out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits;
-+    out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits;
-+    out[8] = (*((limb *) & in[58])) & bottom57bits;
-+}
-+
-+/*
-+ * felem_to_bin66 takes an felem and serialises into a little endian, 66 byte
-+ * array. This assumes that the CPU is little-endian.
-+ */
-+static void felem_to_bin66(u8 out[66], const felem in)
-+{
-+    memset(out, 0, 66);
-+    (*((limb *) & out[0])) = in[0];
-+    (*((limb *) & out[7])) |= in[1] << 2;
-+    (*((limb *) & out[14])) |= in[2] << 4;
-+    (*((limb *) & out[21])) |= in[3] << 6;
-+    (*((limb *) & out[29])) = in[4];
-+    (*((limb *) & out[36])) |= in[5] << 2;
-+    (*((limb *) & out[43])) |= in[6] << 4;
-+    (*((limb *) & out[50])) |= in[7] << 6;
-+    (*((limb *) & out[58])) = in[8];
-+}
-+
-+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
-+static void flip_endian(u8 *out, const u8 *in, unsigned len)
-+{
-+    unsigned i;
-+    for (i = 0; i < len; ++i)
-+        out[i] = in[len - 1 - i];
-+}
-+
-+/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
-+static int BN_to_felem(felem out, const BIGNUM *bn)
-+{
-+    felem_bytearray b_in;
-+    felem_bytearray b_out;
-+    unsigned num_bytes;
-+
-+    /* BN_bn2bin eats leading zeroes */
-+    memset(b_out, 0, sizeof(b_out));
-+    num_bytes = BN_num_bytes(bn);
-+    if (num_bytes > sizeof b_out) {
-+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
-+        return 0;
-+    }
-+    if (BN_is_negative(bn)) {
-+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
-+        return 0;
-+    }
-+    num_bytes = BN_bn2bin(bn, b_in);
-+    flip_endian(b_out, b_in, num_bytes);
-+    bin66_to_felem(out, b_out);
-+    return 1;
-+}
-+
-+/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
-+static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
-+{
-+    felem_bytearray b_in, b_out;
-+    felem_to_bin66(b_in, in);
-+    flip_endian(b_out, b_in, sizeof b_out);
-+    return BN_bin2bn(b_out, sizeof b_out, out);
-+}
-+
-+/*-
-+ * Field operations
-+ * ----------------
-+ */
-+
-+static void felem_one(felem out)
-+{
-+    out[0] = 1;
-+    out[1] = 0;
-+    out[2] = 0;
-+    out[3] = 0;
-+    out[4] = 0;
-+    out[5] = 0;
-+    out[6] = 0;
-+    out[7] = 0;
-+    out[8] = 0;
-+}
-+
-+static void felem_assign(felem out, const felem in)
-+{
-+    out[0] = in[0];
-+    out[1] = in[1];
-+    out[2] = in[2];
-+    out[3] = in[3];
-+    out[4] = in[4];
-+    out[5] = in[5];
-+    out[6] = in[6];
-+    out[7] = in[7];
-+    out[8] = in[8];
-+}
-+
-+/* felem_sum64 sets out = out + in. */
-+static void felem_sum64(felem out, const felem in)
-+{
-+    out[0] += in[0];
-+    out[1] += in[1];
-+    out[2] += in[2];
-+    out[3] += in[3];
-+    out[4] += in[4];
-+    out[5] += in[5];
-+    out[6] += in[6];
-+    out[7] += in[7];
-+    out[8] += in[8];
-+}
-+
-+/* felem_scalar sets out = in * scalar */
-+static void felem_scalar(felem out, const felem in, limb scalar)
-+{
-+    out[0] = in[0] * scalar;
-+    out[1] = in[1] * scalar;
-+    out[2] = in[2] * scalar;
-+    out[3] = in[3] * scalar;
-+    out[4] = in[4] * scalar;
-+    out[5] = in[5] * scalar;
-+    out[6] = in[6] * scalar;
-+    out[7] = in[7] * scalar;
-+    out[8] = in[8] * scalar;
-+}
-+
-+/* felem_scalar64 sets out = out * scalar */
-+static void felem_scalar64(felem out, limb scalar)
-+{
-+    out[0] *= scalar;
-+    out[1] *= scalar;
-+    out[2] *= scalar;
-+    out[3] *= scalar;
-+    out[4] *= scalar;
-+    out[5] *= scalar;
-+    out[6] *= scalar;
-+    out[7] *= scalar;
-+    out[8] *= scalar;
-+}
-+
-+/* felem_scalar128 sets out = out * scalar */
-+static void felem_scalar128(largefelem out, limb scalar)
-+{
-+    out[0] *= scalar;
-+    out[1] *= scalar;
-+    out[2] *= scalar;
-+    out[3] *= scalar;
-+    out[4] *= scalar;
-+    out[5] *= scalar;
-+    out[6] *= scalar;
-+    out[7] *= scalar;
-+    out[8] *= scalar;
-+}
-+
-+/*-
-+ * felem_neg sets |out| to |-in|
-+ * On entry:
-+ *   in[i] < 2^59 + 2^14
-+ * On exit:
-+ *   out[i] < 2^62
-+ */
-+static void felem_neg(felem out, const felem in)
-+{
-+    /* In order to prevent underflow, we subtract from 0 mod p. */
-+    static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5);
-+    static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4);
-+
-+    out[0] = two62m3 - in[0];
-+    out[1] = two62m2 - in[1];
-+    out[2] = two62m2 - in[2];
-+    out[3] = two62m2 - in[3];
-+    out[4] = two62m2 - in[4];
-+    out[5] = two62m2 - in[5];
-+    out[6] = two62m2 - in[6];
-+    out[7] = two62m2 - in[7];
-+    out[8] = two62m2 - in[8];
-+}
-+
-+/*-
-+ * felem_diff64 subtracts |in| from |out|
-+ * On entry:
-+ *   in[i] < 2^59 + 2^14
-+ * On exit:
-+ *   out[i] < out[i] + 2^62
-+ */
-+static void felem_diff64(felem out, const felem in)
-+{
-+    /*
-+     * In order to prevent underflow, we add 0 mod p before subtracting.
-+     */
-+    static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5);
-+    static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4);
-+
-+    out[0] += two62m3 - in[0];
-+    out[1] += two62m2 - in[1];
-+    out[2] += two62m2 - in[2];
-+    out[3] += two62m2 - in[3];
-+    out[4] += two62m2 - in[4];
-+    out[5] += two62m2 - in[5];
-+    out[6] += two62m2 - in[6];
-+    out[7] += two62m2 - in[7];
-+    out[8] += two62m2 - in[8];
-+}
-+
-+/*-
-+ * felem_diff_128_64 subtracts |in| from |out|
-+ * On entry:
-+ *   in[i] < 2^62 + 2^17
-+ * On exit:
-+ *   out[i] < out[i] + 2^63
-+ */
-+static void felem_diff_128_64(largefelem out, const felem in)
-+{
-+    /*
-+     * In order to prevent underflow, we add 0 mod p before subtracting.
-+     */
-+    static const limb two63m6 = (((limb) 1) << 62) - (((limb) 1) << 5);
-+    static const limb two63m5 = (((limb) 1) << 62) - (((limb) 1) << 4);
-+
-+    out[0] += two63m6 - in[0];
-+    out[1] += two63m5 - in[1];
-+    out[2] += two63m5 - in[2];
-+    out[3] += two63m5 - in[3];
-+    out[4] += two63m5 - in[4];
-+    out[5] += two63m5 - in[5];
-+    out[6] += two63m5 - in[6];
-+    out[7] += two63m5 - in[7];
-+    out[8] += two63m5 - in[8];
-+}
-+
-+/*-
-+ * felem_diff_128_64 subtracts |in| from |out|
-+ * On entry:
-+ *   in[i] < 2^126
-+ * On exit:
-+ *   out[i] < out[i] + 2^127 - 2^69
-+ */
-+static void felem_diff128(largefelem out, const largefelem in)
-+{
-+    /*
-+     * In order to prevent underflow, we add 0 mod p before subtracting.
-+     */
-+    static const uint128_t two127m70 =
-+        (((uint128_t) 1) << 127) - (((uint128_t) 1) << 70);
-+    static const uint128_t two127m69 =
-+        (((uint128_t) 1) << 127) - (((uint128_t) 1) << 69);
-+
-+    out[0] += (two127m70 - in[0]);
-+    out[1] += (two127m69 - in[1]);
-+    out[2] += (two127m69 - in[2]);
-+    out[3] += (two127m69 - in[3]);
-+    out[4] += (two127m69 - in[4]);
-+    out[5] += (two127m69 - in[5]);
-+    out[6] += (two127m69 - in[6]);
-+    out[7] += (two127m69 - in[7]);
-+    out[8] += (two127m69 - in[8]);
-+}
-+
-+/*-
-+ * felem_square sets |out| = |in|^2
-+ * On entry:
-+ *   in[i] < 2^62
-+ * On exit:
-+ *   out[i] < 17 * max(in[i]) * max(in[i])
-+ */
-+static void felem_square(largefelem out, const felem in)
-+{
-+    felem inx2, inx4;
-+    felem_scalar(inx2, in, 2);
-+    felem_scalar(inx4, in, 4);
-+
-+    /*-
-+     * We have many cases were we want to do
-+     *   in[x] * in[y] +
-+     *   in[y] * in[x]
-+     * This is obviously just
-+     *   2 * in[x] * in[y]
-+     * However, rather than do the doubling on the 128 bit result, we
-+     * double one of the inputs to the multiplication by reading from
-+     * |inx2|
-+     */
-+
-+    out[0] = ((uint128_t) in[0]) * in[0];
-+    out[1] = ((uint128_t) in[0]) * inx2[1];
-+    out[2] = ((uint128_t) in[0]) * inx2[2] + ((uint128_t) in[1]) * in[1];
-+    out[3] = ((uint128_t) in[0]) * inx2[3] + ((uint128_t) in[1]) * inx2[2];
-+    out[4] = ((uint128_t) in[0]) * inx2[4] +
-+             ((uint128_t) in[1]) * inx2[3] + ((uint128_t) in[2]) * in[2];
-+    out[5] = ((uint128_t) in[0]) * inx2[5] +
-+             ((uint128_t) in[1]) * inx2[4] + ((uint128_t) in[2]) * inx2[3];
-+    out[6] = ((uint128_t) in[0]) * inx2[6] +
-+             ((uint128_t) in[1]) * inx2[5] +
-+             ((uint128_t) in[2]) * inx2[4] + ((uint128_t) in[3]) * in[3];
-+    out[7] = ((uint128_t) in[0]) * inx2[7] +
-+             ((uint128_t) in[1]) * inx2[6] +
-+             ((uint128_t) in[2]) * inx2[5] + ((uint128_t) in[3]) * inx2[4];
-+    out[8] = ((uint128_t) in[0]) * inx2[8] +
-+             ((uint128_t) in[1]) * inx2[7] +
-+             ((uint128_t) in[2]) * inx2[6] +
-+             ((uint128_t) in[3]) * inx2[5] + ((uint128_t) in[4]) * in[4];
-+
-+    /*
-+     * The remaining limbs fall above 2^521, with the first falling at 2^522.
-+     * They correspond to locations one bit up from the limbs produced above
-+     * so we would have to multiply by two to align them. Again, rather than
-+     * operate on the 128-bit result, we double one of the inputs to the
-+     * multiplication. If we want to double for both this reason, and the
-+     * reason above, then we end up multiplying by four.
-+     */
-+
-+    /* 9 */
-+    out[0] += ((uint128_t) in[1]) * inx4[8] +
-+              ((uint128_t) in[2]) * inx4[7] +
-+              ((uint128_t) in[3]) * inx4[6] + ((uint128_t) in[4]) * inx4[5];
-+
-+    /* 10 */
-+    out[1] += ((uint128_t) in[2]) * inx4[8] +
-+              ((uint128_t) in[3]) * inx4[7] +
-+              ((uint128_t) in[4]) * inx4[6] + ((uint128_t) in[5]) * inx2[5];
-+
-+    /* 11 */
-+    out[2] += ((uint128_t) in[3]) * inx4[8] +
-+              ((uint128_t) in[4]) * inx4[7] + ((uint128_t) in[5]) * inx4[6];
-+
-+    /* 12 */
-+    out[3] += ((uint128_t) in[4]) * inx4[8] +
-+              ((uint128_t) in[5]) * inx4[7] + ((uint128_t) in[6]) * inx2[6];
-+
-+    /* 13 */
-+    out[4] += ((uint128_t) in[5]) * inx4[8] + ((uint128_t) in[6]) * inx4[7];
-+
-+    /* 14 */
-+    out[5] += ((uint128_t) in[6]) * inx4[8] + ((uint128_t) in[7]) * inx2[7];
-+
-+    /* 15 */
-+    out[6] += ((uint128_t) in[7]) * inx4[8];
-+
-+    /* 16 */
-+    out[7] += ((uint128_t) in[8]) * inx2[8];
-+}
-+
-+/*-
-+ * felem_mul sets |out| = |in1| * |in2|
-+ * On entry:
-+ *   in1[i] < 2^64
-+ *   in2[i] < 2^63
-+ * On exit:
-+ *   out[i] < 17 * max(in1[i]) * max(in2[i])
-+ */
-+static void felem_mul(largefelem out, const felem in1, const felem in2)
-+{
-+    felem in2x2;
-+    felem_scalar(in2x2, in2, 2);
-+
-+    out[0] = ((uint128_t) in1[0]) * in2[0];
-+
-+    out[1] = ((uint128_t) in1[0]) * in2[1] +
-+             ((uint128_t) in1[1]) * in2[0];
-+
-+    out[2] = ((uint128_t) in1[0]) * in2[2] +
-+             ((uint128_t) in1[1]) * in2[1] +
-+             ((uint128_t) in1[2]) * in2[0];
-+
-+    out[3] = ((uint128_t) in1[0]) * in2[3] +
-+             ((uint128_t) in1[1]) * in2[2] +
-+             ((uint128_t) in1[2]) * in2[1] +
-+             ((uint128_t) in1[3]) * in2[0];
-+
-+    out[4] = ((uint128_t) in1[0]) * in2[4] +
-+             ((uint128_t) in1[1]) * in2[3] +
-+             ((uint128_t) in1[2]) * in2[2] +
-+             ((uint128_t) in1[3]) * in2[1] +
-+             ((uint128_t) in1[4]) * in2[0];
-+
-+    out[5] = ((uint128_t) in1[0]) * in2[5] +
-+             ((uint128_t) in1[1]) * in2[4] +
-+             ((uint128_t) in1[2]) * in2[3] +
-+             ((uint128_t) in1[3]) * in2[2] +
-+             ((uint128_t) in1[4]) * in2[1] +
-+             ((uint128_t) in1[5]) * in2[0];
-+
-+    out[6] = ((uint128_t) in1[0]) * in2[6] +
-+             ((uint128_t) in1[1]) * in2[5] +
-+             ((uint128_t) in1[2]) * in2[4] +
-+             ((uint128_t) in1[3]) * in2[3] +
-+             ((uint128_t) in1[4]) * in2[2] +
-+             ((uint128_t) in1[5]) * in2[1] +
-+             ((uint128_t) in1[6]) * in2[0];
-+
-+    out[7] = ((uint128_t) in1[0]) * in2[7] +
-+             ((uint128_t) in1[1]) * in2[6] +
-+             ((uint128_t) in1[2]) * in2[5] +
-+             ((uint128_t) in1[3]) * in2[4] +
-+             ((uint128_t) in1[4]) * in2[3] +
-+             ((uint128_t) in1[5]) * in2[2] +
-+             ((uint128_t) in1[6]) * in2[1] +
-+             ((uint128_t) in1[7]) * in2[0];
-+
-+    out[8] = ((uint128_t) in1[0]) * in2[8] +
-+             ((uint128_t) in1[1]) * in2[7] +
-+             ((uint128_t) in1[2]) * in2[6] +
-+             ((uint128_t) in1[3]) * in2[5] +
-+             ((uint128_t) in1[4]) * in2[4] +
-+             ((uint128_t) in1[5]) * in2[3] +
-+             ((uint128_t) in1[6]) * in2[2] +
-+             ((uint128_t) in1[7]) * in2[1] +
-+             ((uint128_t) in1[8]) * in2[0];
-+
-+    /* See comment in felem_square about the use of in2x2 here */
-+
-+    out[0] += ((uint128_t) in1[1]) * in2x2[8] +
-+              ((uint128_t) in1[2]) * in2x2[7] +
-+              ((uint128_t) in1[3]) * in2x2[6] +
-+              ((uint128_t) in1[4]) * in2x2[5] +
-+              ((uint128_t) in1[5]) * in2x2[4] +
-+              ((uint128_t) in1[6]) * in2x2[3] +
-+              ((uint128_t) in1[7]) * in2x2[2] +
-+              ((uint128_t) in1[8]) * in2x2[1];
-+
-+    out[1] += ((uint128_t) in1[2]) * in2x2[8] +
-+              ((uint128_t) in1[3]) * in2x2[7] +
-+              ((uint128_t) in1[4]) * in2x2[6] +
-+              ((uint128_t) in1[5]) * in2x2[5] +
-+              ((uint128_t) in1[6]) * in2x2[4] +
-+              ((uint128_t) in1[7]) * in2x2[3] +
-+              ((uint128_t) in1[8]) * in2x2[2];
-+
-+    out[2] += ((uint128_t) in1[3]) * in2x2[8] +
-+              ((uint128_t) in1[4]) * in2x2[7] +
-+              ((uint128_t) in1[5]) * in2x2[6] +
-+              ((uint128_t) in1[6]) * in2x2[5] +
-+              ((uint128_t) in1[7]) * in2x2[4] +
-+              ((uint128_t) in1[8]) * in2x2[3];
-+
-+    out[3] += ((uint128_t) in1[4]) * in2x2[8] +
-+              ((uint128_t) in1[5]) * in2x2[7] +
-+              ((uint128_t) in1[6]) * in2x2[6] +
-+              ((uint128_t) in1[7]) * in2x2[5] +
-+              ((uint128_t) in1[8]) * in2x2[4];
-+
-+    out[4] += ((uint128_t) in1[5]) * in2x2[8] +
-+              ((uint128_t) in1[6]) * in2x2[7] +
-+              ((uint128_t) in1[7]) * in2x2[6] +
-+              ((uint128_t) in1[8]) * in2x2[5];
-+
-+    out[5] += ((uint128_t) in1[6]) * in2x2[8] +
-+              ((uint128_t) in1[7]) * in2x2[7] +
-+              ((uint128_t) in1[8]) * in2x2[6];
-+
-+    out[6] += ((uint128_t) in1[7]) * in2x2[8] +
-+              ((uint128_t) in1[8]) * in2x2[7];
-+
-+    out[7] += ((uint128_t) in1[8]) * in2x2[8];
-+}
-+
-+static const limb bottom52bits = 0xfffffffffffff;
-+
-+/*-
-+ * felem_reduce converts a largefelem to an felem.
-+ * On entry:
-+ *   in[i] < 2^128
-+ * On exit:
-+ *   out[i] < 2^59 + 2^14
-+ */
-+static void felem_reduce(felem out, const largefelem in)
-+{
-+    u64 overflow1, overflow2;
-+
-+    out[0] = ((limb) in[0]) & bottom58bits;
-+    out[1] = ((limb) in[1]) & bottom58bits;
-+    out[2] = ((limb) in[2]) & bottom58bits;
-+    out[3] = ((limb) in[3]) & bottom58bits;
-+    out[4] = ((limb) in[4]) & bottom58bits;
-+    out[5] = ((limb) in[5]) & bottom58bits;
-+    out[6] = ((limb) in[6]) & bottom58bits;
-+    out[7] = ((limb) in[7]) & bottom58bits;
-+    out[8] = ((limb) in[8]) & bottom58bits;
-+
-+    /* out[i] < 2^58 */
-+
-+    out[1] += ((limb) in[0]) >> 58;
-+    out[1] += (((limb) (in[0] >> 64)) & bottom52bits) << 6;
-+    /*-
-+     * out[1] < 2^58 + 2^6 + 2^58
-+     *        = 2^59 + 2^6
-+     */
-+    out[2] += ((limb) (in[0] >> 64)) >> 52;
-+
-+    out[2] += ((limb) in[1]) >> 58;
-+    out[2] += (((limb) (in[1] >> 64)) & bottom52bits) << 6;
-+    out[3] += ((limb) (in[1] >> 64)) >> 52;
-+
-+    out[3] += ((limb) in[2]) >> 58;
-+    out[3] += (((limb) (in[2] >> 64)) & bottom52bits) << 6;
-+    out[4] += ((limb) (in[2] >> 64)) >> 52;
-+
-+    out[4] += ((limb) in[3]) >> 58;
-+    out[4] += (((limb) (in[3] >> 64)) & bottom52bits) << 6;
-+    out[5] += ((limb) (in[3] >> 64)) >> 52;
-+
-+    out[5] += ((limb) in[4]) >> 58;
-+    out[5] += (((limb) (in[4] >> 64)) & bottom52bits) << 6;
-+    out[6] += ((limb) (in[4] >> 64)) >> 52;
-+
-+    out[6] += ((limb) in[5]) >> 58;
-+    out[6] += (((limb) (in[5] >> 64)) & bottom52bits) << 6;
-+    out[7] += ((limb) (in[5] >> 64)) >> 52;
-+
-+    out[7] += ((limb) in[6]) >> 58;
-+    out[7] += (((limb) (in[6] >> 64)) & bottom52bits) << 6;
-+    out[8] += ((limb) (in[6] >> 64)) >> 52;
-+
-+    out[8] += ((limb) in[7]) >> 58;
-+    out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6;
-+    /*-
-+     * out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12
-+     *            < 2^59 + 2^13
-+     */
-+    overflow1 = ((limb) (in[7] >> 64)) >> 52;
-+
-+    overflow1 += ((limb) in[8]) >> 58;
-+    overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6;
-+    overflow2 = ((limb) (in[8] >> 64)) >> 52;
-+
-+    overflow1 <<= 1;            /* overflow1 < 2^13 + 2^7 + 2^59 */
-+    overflow2 <<= 1;            /* overflow2 < 2^13 */
-+
-+    out[0] += overflow1;        /* out[0] < 2^60 */
-+    out[1] += overflow2;        /* out[1] < 2^59 + 2^6 + 2^13 */
-+
-+    out[1] += out[0] >> 58;
-+    out[0] &= bottom58bits;
-+    /*-
-+     * out[0] < 2^58
-+     * out[1] < 2^59 + 2^6 + 2^13 + 2^2
-+     *        < 2^59 + 2^14
-+     */
-+}
-+
-+static void felem_square_reduce(felem out, const felem in)
-+{
-+    largefelem tmp;
-+    felem_square(tmp, in);
-+    felem_reduce(out, tmp);
-+}
-+
-+static void felem_mul_reduce(felem out, const felem in1, const felem in2)
-+{
-+    largefelem tmp;
-+    felem_mul(tmp, in1, in2);
-+    felem_reduce(out, tmp);
-+}
-+
-+/*-
-+ * felem_inv calculates |out| = |in|^{-1}
-+ *
-+ * Based on Fermat's Little Theorem:
-+ *   a^p = a (mod p)
-+ *   a^{p-1} = 1 (mod p)
-+ *   a^{p-2} = a^{-1} (mod p)
-+ */
-+static void felem_inv(felem out, const felem in)
-+{
-+    felem ftmp, ftmp2, ftmp3, ftmp4;
-+    largefelem tmp;
-+    unsigned i;
-+
-+    felem_square(tmp, in);
-+    felem_reduce(ftmp, tmp);    /* 2^1 */
-+    felem_mul(tmp, in, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^2 - 2^0 */
-+    felem_assign(ftmp2, ftmp);
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^3 - 2^1 */
-+    felem_mul(tmp, in, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^3 - 2^0 */
-+    felem_square(tmp, ftmp);
-+    felem_reduce(ftmp, tmp);    /* 2^4 - 2^1 */
-+
-+    felem_square(tmp, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^3 - 2^1 */
-+    felem_square(tmp, ftmp3);
-+    felem_reduce(ftmp3, tmp);   /* 2^4 - 2^2 */
-+    felem_mul(tmp, ftmp3, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^4 - 2^0 */
-+
-+    felem_assign(ftmp2, ftmp3);
-+    felem_square(tmp, ftmp3);
-+    felem_reduce(ftmp3, tmp);   /* 2^5 - 2^1 */
-+    felem_square(tmp, ftmp3);
-+    felem_reduce(ftmp3, tmp);   /* 2^6 - 2^2 */
-+    felem_square(tmp, ftmp3);
-+    felem_reduce(ftmp3, tmp);   /* 2^7 - 2^3 */
-+    felem_square(tmp, ftmp3);
-+    felem_reduce(ftmp3, tmp);   /* 2^8 - 2^4 */
-+    felem_assign(ftmp4, ftmp3);
-+    felem_mul(tmp, ftmp3, ftmp);
-+    felem_reduce(ftmp4, tmp);   /* 2^8 - 2^1 */
-+    felem_square(tmp, ftmp4);
-+    felem_reduce(ftmp4, tmp);   /* 2^9 - 2^2 */
-+    felem_mul(tmp, ftmp3, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^8 - 2^0 */
-+    felem_assign(ftmp2, ftmp3);
-+
-+    for (i = 0; i < 8; i++) {
-+        felem_square(tmp, ftmp3);
-+        felem_reduce(ftmp3, tmp); /* 2^16 - 2^8 */
-+    }
-+    felem_mul(tmp, ftmp3, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^16 - 2^0 */
-+    felem_assign(ftmp2, ftmp3);
-+
-+    for (i = 0; i < 16; i++) {
-+        felem_square(tmp, ftmp3);
-+        felem_reduce(ftmp3, tmp); /* 2^32 - 2^16 */
-+    }
-+    felem_mul(tmp, ftmp3, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^32 - 2^0 */
-+    felem_assign(ftmp2, ftmp3);
-+
-+    for (i = 0; i < 32; i++) {
-+        felem_square(tmp, ftmp3);
-+        felem_reduce(ftmp3, tmp); /* 2^64 - 2^32 */
-+    }
-+    felem_mul(tmp, ftmp3, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^64 - 2^0 */
-+    felem_assign(ftmp2, ftmp3);
-+
-+    for (i = 0; i < 64; i++) {
-+        felem_square(tmp, ftmp3);
-+        felem_reduce(ftmp3, tmp); /* 2^128 - 2^64 */
-+    }
-+    felem_mul(tmp, ftmp3, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^128 - 2^0 */
-+    felem_assign(ftmp2, ftmp3);
-+
-+    for (i = 0; i < 128; i++) {
-+        felem_square(tmp, ftmp3);
-+        felem_reduce(ftmp3, tmp); /* 2^256 - 2^128 */
-+    }
-+    felem_mul(tmp, ftmp3, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^256 - 2^0 */
-+    felem_assign(ftmp2, ftmp3);
-+
-+    for (i = 0; i < 256; i++) {
-+        felem_square(tmp, ftmp3);
-+        felem_reduce(ftmp3, tmp); /* 2^512 - 2^256 */
-+    }
-+    felem_mul(tmp, ftmp3, ftmp2);
-+    felem_reduce(ftmp3, tmp);   /* 2^512 - 2^0 */
-+
-+    for (i = 0; i < 9; i++) {
-+        felem_square(tmp, ftmp3);
-+        felem_reduce(ftmp3, tmp); /* 2^521 - 2^9 */
-+    }
-+    felem_mul(tmp, ftmp3, ftmp4);
-+    felem_reduce(ftmp3, tmp);   /* 2^512 - 2^2 */
-+    felem_mul(tmp, ftmp3, in);
-+    felem_reduce(out, tmp);     /* 2^512 - 3 */
-+}
-+
-+/* This is 2^521-1, expressed as an felem */
-+static const felem kPrime = {
-+    0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
-+    0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
-+    0x03ffffffffffffff, 0x03ffffffffffffff, 0x01ffffffffffffff
-+};
-+
-+/*-
-+ * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
-+ * otherwise.
-+ * On entry:
-+ *   in[i] < 2^59 + 2^14
-+ */
-+static limb felem_is_zero(const felem in)
-+{
-+    felem ftmp;
-+    limb is_zero, is_p;
-+    felem_assign(ftmp, in);
-+
-+    ftmp[0] += ftmp[8] >> 57;
-+    ftmp[8] &= bottom57bits;
-+    /* ftmp[8] < 2^57 */
-+    ftmp[1] += ftmp[0] >> 58;
-+    ftmp[0] &= bottom58bits;
-+    ftmp[2] += ftmp[1] >> 58;
-+    ftmp[1] &= bottom58bits;
-+    ftmp[3] += ftmp[2] >> 58;
-+    ftmp[2] &= bottom58bits;
-+    ftmp[4] += ftmp[3] >> 58;
-+    ftmp[3] &= bottom58bits;
-+    ftmp[5] += ftmp[4] >> 58;
-+    ftmp[4] &= bottom58bits;
-+    ftmp[6] += ftmp[5] >> 58;
-+    ftmp[5] &= bottom58bits;
-+    ftmp[7] += ftmp[6] >> 58;
-+    ftmp[6] &= bottom58bits;
-+    ftmp[8] += ftmp[7] >> 58;
-+    ftmp[7] &= bottom58bits;
-+    /* ftmp[8] < 2^57 + 4 */
-+
-+    /*
-+     * The ninth limb of 2*(2^521-1) is 0x03ffffffffffffff, which is greater
-+     * than our bound for ftmp[8]. Therefore we only have to check if the
-+     * zero is zero or 2^521-1.
-+     */
-+
-+    is_zero = 0;
-+    is_zero |= ftmp[0];
-+    is_zero |= ftmp[1];
-+    is_zero |= ftmp[2];
-+    is_zero |= ftmp[3];
-+    is_zero |= ftmp[4];
-+    is_zero |= ftmp[5];
-+    is_zero |= ftmp[6];
-+    is_zero |= ftmp[7];
-+    is_zero |= ftmp[8];
-+
-+    is_zero--;
-+    /*
-+     * We know that ftmp[i] < 2^63, therefore the only way that the top bit
-+     * can be set is if is_zero was 0 before the decrement.
-+     */
-+    is_zero = ((s64) is_zero) >> 63;
-+
-+    is_p = ftmp[0] ^ kPrime[0];
-+    is_p |= ftmp[1] ^ kPrime[1];
-+    is_p |= ftmp[2] ^ kPrime[2];
-+    is_p |= ftmp[3] ^ kPrime[3];
-+    is_p |= ftmp[4] ^ kPrime[4];
-+    is_p |= ftmp[5] ^ kPrime[5];
-+    is_p |= ftmp[6] ^ kPrime[6];
-+    is_p |= ftmp[7] ^ kPrime[7];
-+    is_p |= ftmp[8] ^ kPrime[8];
-+
-+    is_p--;
-+    is_p = ((s64) is_p) >> 63;
-+
-+    is_zero |= is_p;
-+    return is_zero;
-+}
-+
-+static int felem_is_zero_int(const felem in)
-+{
-+    return (int)(felem_is_zero(in) & ((limb) 1));
-+}
-+
-+/*-
-+ * felem_contract converts |in| to its unique, minimal representation.
-+ * On entry:
-+ *   in[i] < 2^59 + 2^14
-+ */
-+static void felem_contract(felem out, const felem in)
-+{
-+    limb is_p, is_greater, sign;
-+    static const limb two58 = ((limb) 1) << 58;
-+
-+    felem_assign(out, in);
-+
-+    out[0] += out[8] >> 57;
-+    out[8] &= bottom57bits;
-+    /* out[8] < 2^57 */
-+    out[1] += out[0] >> 58;
-+    out[0] &= bottom58bits;
-+    out[2] += out[1] >> 58;
-+    out[1] &= bottom58bits;
-+    out[3] += out[2] >> 58;
-+    out[2] &= bottom58bits;
-+    out[4] += out[3] >> 58;
-+    out[3] &= bottom58bits;
-+    out[5] += out[4] >> 58;
-+    out[4] &= bottom58bits;
-+    out[6] += out[5] >> 58;
-+    out[5] &= bottom58bits;
-+    out[7] += out[6] >> 58;
-+    out[6] &= bottom58bits;
-+    out[8] += out[7] >> 58;
-+    out[7] &= bottom58bits;
-+    /* out[8] < 2^57 + 4 */
-+
-+    /*
-+     * If the value is greater than 2^521-1 then we have to subtract 2^521-1
-+     * out. See the comments in felem_is_zero regarding why we don't test for
-+     * other multiples of the prime.
-+     */
-+
-+    /*
-+     * First, if |out| is equal to 2^521-1, we subtract it out to get zero.
-+     */
-+
-+    is_p = out[0] ^ kPrime[0];
-+    is_p |= out[1] ^ kPrime[1];
-+    is_p |= out[2] ^ kPrime[2];
-+    is_p |= out[3] ^ kPrime[3];
-+    is_p |= out[4] ^ kPrime[4];
-+    is_p |= out[5] ^ kPrime[5];
-+    is_p |= out[6] ^ kPrime[6];
-+    is_p |= out[7] ^ kPrime[7];
-+    is_p |= out[8] ^ kPrime[8];
-+
-+    is_p--;
-+    is_p &= is_p << 32;
-+    is_p &= is_p << 16;
-+    is_p &= is_p << 8;
-+    is_p &= is_p << 4;
-+    is_p &= is_p << 2;
-+    is_p &= is_p << 1;
-+    is_p = ((s64) is_p) >> 63;
-+    is_p = ~is_p;
-+
-+    /* is_p is 0 iff |out| == 2^521-1 and all ones otherwise */
-+
-+    out[0] &= is_p;
-+    out[1] &= is_p;
-+    out[2] &= is_p;
-+    out[3] &= is_p;
-+    out[4] &= is_p;
-+    out[5] &= is_p;
-+    out[6] &= is_p;
-+    out[7] &= is_p;
-+    out[8] &= is_p;
-+
-+    /*
-+     * In order to test that |out| >= 2^521-1 we need only test if out[8] >>
-+     * 57 is greater than zero as (2^521-1) + x >= 2^522
-+     */
-+    is_greater = out[8] >> 57;
-+    is_greater |= is_greater << 32;
-+    is_greater |= is_greater << 16;
-+    is_greater |= is_greater << 8;
-+    is_greater |= is_greater << 4;
-+    is_greater |= is_greater << 2;
-+    is_greater |= is_greater << 1;
-+    is_greater = ((s64) is_greater) >> 63;
-+
-+    out[0] -= kPrime[0] & is_greater;
-+    out[1] -= kPrime[1] & is_greater;
-+    out[2] -= kPrime[2] & is_greater;
-+    out[3] -= kPrime[3] & is_greater;
-+    out[4] -= kPrime[4] & is_greater;
-+    out[5] -= kPrime[5] & is_greater;
-+    out[6] -= kPrime[6] & is_greater;
-+    out[7] -= kPrime[7] & is_greater;
-+    out[8] -= kPrime[8] & is_greater;
-+
-+    /* Eliminate negative coefficients */
-+    sign = -(out[0] >> 63);
-+    out[0] += (two58 & sign);
-+    out[1] -= (1 & sign);
-+    sign = -(out[1] >> 63);
-+    out[1] += (two58 & sign);
-+    out[2] -= (1 & sign);
-+    sign = -(out[2] >> 63);
-+    out[2] += (two58 & sign);
-+    out[3] -= (1 & sign);
-+    sign = -(out[3] >> 63);
-+    out[3] += (two58 & sign);
-+    out[4] -= (1 & sign);
-+    sign = -(out[4] >> 63);
-+    out[4] += (two58 & sign);
-+    out[5] -= (1 & sign);
-+    sign = -(out[0] >> 63);
-+    out[5] += (two58 & sign);
-+    out[6] -= (1 & sign);
-+    sign = -(out[6] >> 63);
-+    out[6] += (two58 & sign);
-+    out[7] -= (1 & sign);
-+    sign = -(out[7] >> 63);
-+    out[7] += (two58 & sign);
-+    out[8] -= (1 & sign);
-+    sign = -(out[5] >> 63);
-+    out[5] += (two58 & sign);
-+    out[6] -= (1 & sign);
-+    sign = -(out[6] >> 63);
-+    out[6] += (two58 & sign);
-+    out[7] -= (1 & sign);
-+    sign = -(out[7] >> 63);
-+    out[7] += (two58 & sign);
-+    out[8] -= (1 & sign);
-+}
-+
-+/*-
-+ * Group operations
-+ * ----------------
-+ *
-+ * Building on top of the field operations we have the operations on the
-+ * elliptic curve group itself. Points on the curve are represented in Jacobian
-+ * coordinates */
-+
-+/*-
-+ * point_double calculates 2*(x_in, y_in, z_in)
-+ *
-+ * The method is taken from:
-+ *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
-+ *
-+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
-+ * while x_out == y_in is not (maybe this works, but it's not tested). */
-+static void
-+point_double(felem x_out, felem y_out, felem z_out,
-+             const felem x_in, const felem y_in, const felem z_in)
-+{
-+    largefelem tmp, tmp2;
-+    felem delta, gamma, beta, alpha, ftmp, ftmp2;
-+
-+    felem_assign(ftmp, x_in);
-+    felem_assign(ftmp2, x_in);
-+
-+    /* delta = z^2 */
-+    felem_square(tmp, z_in);
-+    felem_reduce(delta, tmp);   /* delta[i] < 2^59 + 2^14 */
-+
-+    /* gamma = y^2 */
-+    felem_square(tmp, y_in);
-+    felem_reduce(gamma, tmp);   /* gamma[i] < 2^59 + 2^14 */
-+
-+    /* beta = x*gamma */
-+    felem_mul(tmp, x_in, gamma);
-+    felem_reduce(beta, tmp);    /* beta[i] < 2^59 + 2^14 */
-+
-+    /* alpha = 3*(x-delta)*(x+delta) */
-+    felem_diff64(ftmp, delta);
-+    /* ftmp[i] < 2^61 */
-+    felem_sum64(ftmp2, delta);
-+    /* ftmp2[i] < 2^60 + 2^15 */
-+    felem_scalar64(ftmp2, 3);
-+    /* ftmp2[i] < 3*2^60 + 3*2^15 */
-+    felem_mul(tmp, ftmp, ftmp2);
-+    /*-
-+     * tmp[i] < 17(3*2^121 + 3*2^76)
-+     *        = 61*2^121 + 61*2^76
-+     *        < 64*2^121 + 64*2^76
-+     *        = 2^127 + 2^82
-+     *        < 2^128
-+     */
-+    felem_reduce(alpha, tmp);
-+
-+    /* x' = alpha^2 - 8*beta */
-+    felem_square(tmp, alpha);
-+    /*
-+     * tmp[i] < 17*2^120 < 2^125
-+     */
-+    felem_assign(ftmp, beta);
-+    felem_scalar64(ftmp, 8);
-+    /* ftmp[i] < 2^62 + 2^17 */
-+    felem_diff_128_64(tmp, ftmp);
-+    /* tmp[i] < 2^125 + 2^63 + 2^62 + 2^17 */
-+    felem_reduce(x_out, tmp);
-+
-+    /* z' = (y + z)^2 - gamma - delta */
-+    felem_sum64(delta, gamma);
-+    /* delta[i] < 2^60 + 2^15 */
-+    felem_assign(ftmp, y_in);
-+    felem_sum64(ftmp, z_in);
-+    /* ftmp[i] < 2^60 + 2^15 */
-+    felem_square(tmp, ftmp);
-+    /*
-+     * tmp[i] < 17(2^122) < 2^127
-+     */
-+    felem_diff_128_64(tmp, delta);
-+    /* tmp[i] < 2^127 + 2^63 */
-+    felem_reduce(z_out, tmp);
-+
-+    /* y' = alpha*(4*beta - x') - 8*gamma^2 */
-+    felem_scalar64(beta, 4);
-+    /* beta[i] < 2^61 + 2^16 */
-+    felem_diff64(beta, x_out);
-+    /* beta[i] < 2^61 + 2^60 + 2^16 */
-+    felem_mul(tmp, alpha, beta);
-+    /*-
-+     * tmp[i] < 17*((2^59 + 2^14)(2^61 + 2^60 + 2^16))
-+     *        = 17*(2^120 + 2^75 + 2^119 + 2^74 + 2^75 + 2^30)
-+     *        = 17*(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
-+     *        < 2^128
-+     */
-+    felem_square(tmp2, gamma);
-+    /*-
-+     * tmp2[i] < 17*(2^59 + 2^14)^2
-+     *         = 17*(2^118 + 2^74 + 2^28)
-+     */
-+    felem_scalar128(tmp2, 8);
-+    /*-
-+     * tmp2[i] < 8*17*(2^118 + 2^74 + 2^28)
-+     *         = 2^125 + 2^121 + 2^81 + 2^77 + 2^35 + 2^31
-+     *         < 2^126
-+     */
-+    felem_diff128(tmp, tmp2);
-+    /*-
-+     * tmp[i] < 2^127 - 2^69 + 17(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
-+     *        = 2^127 + 2^124 + 2^122 + 2^120 + 2^118 + 2^80 + 2^78 + 2^76 +
-+     *          2^74 + 2^69 + 2^34 + 2^30
-+     *        < 2^128
-+     */
-+    felem_reduce(y_out, tmp);
-+}
-+
-+/* copy_conditional copies in to out iff mask is all ones. */
-+static void copy_conditional(felem out, const felem in, limb mask)
-+{
-+    unsigned i;
-+    for (i = 0; i < NLIMBS; ++i) {
-+        const limb tmp = mask & (in[i] ^ out[i]);
-+        out[i] ^= tmp;
-+    }
-+}
-+
-+/*-
-+ * point_add calculates (x1, y1, z1) + (x2, y2, z2)
-+ *
-+ * The method is taken from
-+ *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
-+ * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
-+ *
-+ * This function includes a branch for checking whether the two input points
-+ * are equal (while not equal to the point at infinity). This case never
-+ * happens during single point multiplication, so there is no timing leak for
-+ * ECDH or ECDSA signing. */
-+static void point_add(felem x3, felem y3, felem z3,
-+                      const felem x1, const felem y1, const felem z1,
-+                      const int mixed, const felem x2, const felem y2,
-+                      const felem z2)
-+{
-+    felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
-+    largefelem tmp, tmp2;
-+    limb x_equal, y_equal, z1_is_zero, z2_is_zero;
-+
-+    z1_is_zero = felem_is_zero(z1);
-+    z2_is_zero = felem_is_zero(z2);
-+
-+    /* ftmp = z1z1 = z1**2 */
-+    felem_square(tmp, z1);
-+    felem_reduce(ftmp, tmp);
-+
-+    if (!mixed) {
-+        /* ftmp2 = z2z2 = z2**2 */
-+        felem_square(tmp, z2);
-+        felem_reduce(ftmp2, tmp);
-+
-+        /* u1 = ftmp3 = x1*z2z2 */
-+        felem_mul(tmp, x1, ftmp2);
-+        felem_reduce(ftmp3, tmp);
-+
-+        /* ftmp5 = z1 + z2 */
-+        felem_assign(ftmp5, z1);
-+        felem_sum64(ftmp5, z2);
-+        /* ftmp5[i] < 2^61 */
-+
-+        /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */
-+        felem_square(tmp, ftmp5);
-+        /* tmp[i] < 17*2^122 */
-+        felem_diff_128_64(tmp, ftmp);
-+        /* tmp[i] < 17*2^122 + 2^63 */
-+        felem_diff_128_64(tmp, ftmp2);
-+        /* tmp[i] < 17*2^122 + 2^64 */
-+        felem_reduce(ftmp5, tmp);
-+
-+        /* ftmp2 = z2 * z2z2 */
-+        felem_mul(tmp, ftmp2, z2);
-+        felem_reduce(ftmp2, tmp);
-+
-+        /* s1 = ftmp6 = y1 * z2**3 */
-+        felem_mul(tmp, y1, ftmp2);
-+        felem_reduce(ftmp6, tmp);
-+    } else {
-+        /*
-+         * We'll assume z2 = 1 (special case z2 = 0 is handled later)
-+         */
-+
-+        /* u1 = ftmp3 = x1*z2z2 */
-+        felem_assign(ftmp3, x1);
-+
-+        /* ftmp5 = 2*z1z2 */
-+        felem_scalar(ftmp5, z1, 2);
-+
-+        /* s1 = ftmp6 = y1 * z2**3 */
-+        felem_assign(ftmp6, y1);
-+    }
-+
-+    /* u2 = x2*z1z1 */
-+    felem_mul(tmp, x2, ftmp);
-+    /* tmp[i] < 17*2^120 */
-+
-+    /* h = ftmp4 = u2 - u1 */
-+    felem_diff_128_64(tmp, ftmp3);
-+    /* tmp[i] < 17*2^120 + 2^63 */
-+    felem_reduce(ftmp4, tmp);
-+
-+    x_equal = felem_is_zero(ftmp4);
-+
-+    /* z_out = ftmp5 * h */
-+    felem_mul(tmp, ftmp5, ftmp4);
-+    felem_reduce(z_out, tmp);
-+
-+    /* ftmp = z1 * z1z1 */
-+    felem_mul(tmp, ftmp, z1);
-+    felem_reduce(ftmp, tmp);
-+
-+    /* s2 = tmp = y2 * z1**3 */
-+    felem_mul(tmp, y2, ftmp);
-+    /* tmp[i] < 17*2^120 */
-+
-+    /* r = ftmp5 = (s2 - s1)*2 */
-+    felem_diff_128_64(tmp, ftmp6);
-+    /* tmp[i] < 17*2^120 + 2^63 */
-+    felem_reduce(ftmp5, tmp);
-+    y_equal = felem_is_zero(ftmp5);
-+    felem_scalar64(ftmp5, 2);
-+    /* ftmp5[i] < 2^61 */
-+
-+    if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
-+        point_double(x3, y3, z3, x1, y1, z1);
-+        return;
-+    }
-+
-+    /* I = ftmp = (2h)**2 */
-+    felem_assign(ftmp, ftmp4);
-+    felem_scalar64(ftmp, 2);
-+    /* ftmp[i] < 2^61 */
-+    felem_square(tmp, ftmp);
-+    /* tmp[i] < 17*2^122 */
-+    felem_reduce(ftmp, tmp);
-+
-+    /* J = ftmp2 = h * I */
-+    felem_mul(tmp, ftmp4, ftmp);
-+    felem_reduce(ftmp2, tmp);
-+
-+    /* V = ftmp4 = U1 * I */
-+    felem_mul(tmp, ftmp3, ftmp);
-+    felem_reduce(ftmp4, tmp);
-+
-+    /* x_out = r**2 - J - 2V */
-+    felem_square(tmp, ftmp5);
-+    /* tmp[i] < 17*2^122 */
-+    felem_diff_128_64(tmp, ftmp2);
-+    /* tmp[i] < 17*2^122 + 2^63 */
-+    felem_assign(ftmp3, ftmp4);
-+    felem_scalar64(ftmp4, 2);
-+    /* ftmp4[i] < 2^61 */
-+    felem_diff_128_64(tmp, ftmp4);
-+    /* tmp[i] < 17*2^122 + 2^64 */
-+    felem_reduce(x_out, tmp);
-+
-+    /* y_out = r(V-x_out) - 2 * s1 * J */
-+    felem_diff64(ftmp3, x_out);
-+    /*
-+     * ftmp3[i] < 2^60 + 2^60 = 2^61
-+     */
-+    felem_mul(tmp, ftmp5, ftmp3);
-+    /* tmp[i] < 17*2^122 */
-+    felem_mul(tmp2, ftmp6, ftmp2);
-+    /* tmp2[i] < 17*2^120 */
-+    felem_scalar128(tmp2, 2);
-+    /* tmp2[i] < 17*2^121 */
-+    felem_diff128(tmp, tmp2);
-+        /*-
-+         * tmp[i] < 2^127 - 2^69 + 17*2^122
-+         *        = 2^126 - 2^122 - 2^6 - 2^2 - 1
-+         *        < 2^127
-+         */
-+    felem_reduce(y_out, tmp);
-+
-+    copy_conditional(x_out, x2, z1_is_zero);
-+    copy_conditional(x_out, x1, z2_is_zero);
-+    copy_conditional(y_out, y2, z1_is_zero);
-+    copy_conditional(y_out, y1, z2_is_zero);
-+    copy_conditional(z_out, z2, z1_is_zero);
-+    copy_conditional(z_out, z1, z2_is_zero);
-+    felem_assign(x3, x_out);
-+    felem_assign(y3, y_out);
-+    felem_assign(z3, z_out);
-+}
-+
-+/*-
-+ * Base point pre computation
-+ * --------------------------
-+ *
-+ * Two different sorts of precomputed tables are used in the following code.
-+ * Each contain various points on the curve, where each point is three field
-+ * elements (x, y, z).
-+ *
-+ * For the base point table, z is usually 1 (0 for the point at infinity).
-+ * This table has 16 elements:
-+ * index | bits    | point
-+ * ------+---------+------------------------------
-+ *     0 | 0 0 0 0 | 0G
-+ *     1 | 0 0 0 1 | 1G
-+ *     2 | 0 0 1 0 | 2^130G
-+ *     3 | 0 0 1 1 | (2^130 + 1)G
-+ *     4 | 0 1 0 0 | 2^260G
-+ *     5 | 0 1 0 1 | (2^260 + 1)G
-+ *     6 | 0 1 1 0 | (2^260 + 2^130)G
-+ *     7 | 0 1 1 1 | (2^260 + 2^130 + 1)G
-+ *     8 | 1 0 0 0 | 2^390G
-+ *     9 | 1 0 0 1 | (2^390 + 1)G
-+ *    10 | 1 0 1 0 | (2^390 + 2^130)G
-+ *    11 | 1 0 1 1 | (2^390 + 2^130 + 1)G
-+ *    12 | 1 1 0 0 | (2^390 + 2^260)G
-+ *    13 | 1 1 0 1 | (2^390 + 2^260 + 1)G
-+ *    14 | 1 1 1 0 | (2^390 + 2^260 + 2^130)G
-+ *    15 | 1 1 1 1 | (2^390 + 2^260 + 2^130 + 1)G
-+ *
-+ * The reason for this is so that we can clock bits into four different
-+ * locations when doing simple scalar multiplies against the base point.
-+ *
-+ * Tables for other points have table[i] = iG for i in 0 .. 16. */
-+
-+/* gmul is the table of precomputed base points */
-+static const felem gmul[16][3] = {
-+{{0, 0, 0, 0, 0, 0, 0, 0, 0},
-+ {0, 0, 0, 0, 0, 0, 0, 0, 0},
-+ {0, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334,
-+  0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8,
-+  0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404},
-+ {0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353,
-+  0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45,
-+  0x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad,
-+  0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e,
-+  0x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5},
-+ {0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58,
-+  0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c,
-+  0x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873,
-+  0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c,
-+  0x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9},
-+ {0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52,
-+  0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e,
-+  0x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2,
-+  0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561,
-+  0x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065},
-+ {0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a,
-+  0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e,
-+  0x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6,
-+  0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51,
-+  0x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe},
-+ {0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d,
-+  0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c,
-+  0x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27,
-+  0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f,
-+  0x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256},
-+ {0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa,
-+  0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2,
-+  0x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890,
-+  0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74,
-+  0x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23},
-+ {0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516,
-+  0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1,
-+  0x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce,
-+  0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7,
-+  0x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5},
-+ {0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318,
-+  0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83,
-+  0x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae,
-+  0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef,
-+  0x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203},
-+ {0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447,
-+  0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283,
-+  0x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5,
-+  0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c,
-+  0x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a},
-+ {0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df,
-+  0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645,
-+  0x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292,
-+  0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422,
-+  0x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b},
-+ {0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30,
-+  0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb,
-+  0x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767,
-+  0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3,
-+  0x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf},
-+ {0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2,
-+  0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692,
-+  0x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3,
-+  0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade,
-+  0x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684},
-+ {0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8,
-+  0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a,
-+  0x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608,
-+  0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610,
-+  0x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d},
-+ {0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006,
-+  0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86,
-+  0x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
-+{{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c,
-+  0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9,
-+  0x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f},
-+ {0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7,
-+  0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c,
-+  0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055},
-+ {1, 0, 0, 0, 0, 0, 0, 0, 0}}
-+};
-+
-+/*
-+ * select_point selects the |idx|th point from a precomputation table and
-+ * copies it to out.
-+ */
-+ /* pre_comp below is of the size provided in |size| */
-+static void select_point(const limb idx, unsigned int size,
-+                         const felem pre_comp[][3], felem out[3])
-+{
-+    unsigned i, j;
-+    limb *outlimbs = &out[0][0];
-+
-+    memset(out, 0, sizeof(*out) * 3);
-+
-+    for (i = 0; i < size; i++) {
-+        const limb *inlimbs = &pre_comp[i][0][0];
-+        limb mask = i ^ idx;
-+        mask |= mask >> 4;
-+        mask |= mask >> 2;
-+        mask |= mask >> 1;
-+        mask &= 1;
-+        mask--;
-+        for (j = 0; j < NLIMBS * 3; j++)
-+            outlimbs[j] |= inlimbs[j] & mask;
-+    }
-+}
-+
-+/* get_bit returns the |i|th bit in |in| */
-+static char get_bit(const felem_bytearray in, int i)
-+{
-+    if (i < 0)
-+        return 0;
-+    return (in[i >> 3] >> (i & 7)) & 1;
-+}
-+
-+/*
-+ * Interleaved point multiplication using precomputed point multiples: The
-+ * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars
-+ * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the
-+ * generator, using certain (large) precomputed multiples in g_pre_comp.
-+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out
-+ */
-+static void batch_mul(felem x_out, felem y_out, felem z_out,
-+                      const felem_bytearray scalars[],
-+                      const unsigned num_points, const u8 *g_scalar,
-+                      const int mixed, const felem pre_comp[][17][3],
-+                      const felem g_pre_comp[16][3])
-+{
-+    int i, skip;
-+    unsigned num, gen_mul = (g_scalar != NULL);
-+    felem nq[3], tmp[4];
-+    limb bits;
-+    u8 sign, digit;
-+
-+    /* set nq to the point at infinity */
-+    memset(nq, 0, sizeof(nq));
-+
-+    /*
-+     * Loop over all scalars msb-to-lsb, interleaving additions of multiples
-+     * of the generator (last quarter of rounds) and additions of other
-+     * points multiples (every 5th round).
-+     */
-+    skip = 1;                   /* save two point operations in the first
-+                                 * round */
-+    for (i = (num_points ? 520 : 130); i >= 0; --i) {
-+        /* double */
-+        if (!skip)
-+            point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
-+
-+        /* add multiples of the generator */
-+        if (gen_mul && (i <= 130)) {
-+            bits = get_bit(g_scalar, i + 390) << 3;
-+            if (i < 130) {
-+                bits |= get_bit(g_scalar, i + 260) << 2;
-+                bits |= get_bit(g_scalar, i + 130) << 1;
-+                bits |= get_bit(g_scalar, i);
-+            }
-+            /* select the point to add, in constant time */
-+            select_point(bits, 16, g_pre_comp, tmp);
-+            if (!skip) {
-+                /* The 1 argument below is for "mixed" */
-+                point_add(nq[0], nq[1], nq[2],
-+                          nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
-+            } else {
-+                memcpy(nq, tmp, 3 * sizeof(felem));
-+                skip = 0;
-+            }
-+        }
-+
-+        /* do other additions every 5 doublings */
-+        if (num_points && (i % 5 == 0)) {
-+            /* loop over all scalars */
-+            for (num = 0; num < num_points; ++num) {
-+                bits = get_bit(scalars[num], i + 4) << 5;
-+                bits |= get_bit(scalars[num], i + 3) << 4;
-+                bits |= get_bit(scalars[num], i + 2) << 3;
-+                bits |= get_bit(scalars[num], i + 1) << 2;
-+                bits |= get_bit(scalars[num], i) << 1;
-+                bits |= get_bit(scalars[num], i - 1);
-+                ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
-+
-+                /*
-+                 * select the point to add or subtract, in constant time
-+                 */
-+                select_point(digit, 17, pre_comp[num], tmp);
-+                felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative
-+                                            * point */
-+                copy_conditional(tmp[1], tmp[3], (-(limb) sign));
-+
-+                if (!skip) {
-+                    point_add(nq[0], nq[1], nq[2],
-+                              nq[0], nq[1], nq[2],
-+                              mixed, tmp[0], tmp[1], tmp[2]);
-+                } else {
-+                    memcpy(nq, tmp, 3 * sizeof(felem));
-+                    skip = 0;
-+                }
-+            }
-+        }
-+    }
-+    felem_assign(x_out, nq[0]);
-+    felem_assign(y_out, nq[1]);
-+    felem_assign(z_out, nq[2]);
-+}
-+
-+/* Precomputation for the group generator. */
-+struct nistp521_pre_comp_st {
-+    felem g_pre_comp[16][3];
-+    int references;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+const EC_METHOD *EC_GFp_nistp521_method(void)
-+{
-+    static const EC_METHOD ret = {
-+        EC_FLAGS_DEFAULT_OCT,
-+        NID_X9_62_prime_field,
-+        ec_GFp_nistp521_group_init,
-+        ec_GFp_simple_group_finish,
-+        ec_GFp_simple_group_clear_finish,
-+        ec_GFp_nist_group_copy,
-+        ec_GFp_nistp521_group_set_curve,
-+        ec_GFp_simple_group_get_curve,
-+        ec_GFp_simple_group_get_degree,
-+        ec_group_simple_order_bits,
-+        ec_GFp_simple_group_check_discriminant,
-+        ec_GFp_simple_point_init,
-+        ec_GFp_simple_point_finish,
-+        ec_GFp_simple_point_clear_finish,
-+        ec_GFp_simple_point_copy,
-+        ec_GFp_simple_point_set_to_infinity,
-+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_point_set_affine_coordinates,
-+        ec_GFp_nistp521_point_get_affine_coordinates,
-+        0 /* point_set_compressed_coordinates */ ,
-+        0 /* point2oct */ ,
-+        0 /* oct2point */ ,
-+        ec_GFp_simple_add,
-+        ec_GFp_simple_dbl,
-+        ec_GFp_simple_invert,
-+        ec_GFp_simple_is_at_infinity,
-+        ec_GFp_simple_is_on_curve,
-+        ec_GFp_simple_cmp,
-+        ec_GFp_simple_make_affine,
-+        ec_GFp_simple_points_make_affine,
-+        ec_GFp_nistp521_points_mul,
-+        ec_GFp_nistp521_precompute_mult,
-+        ec_GFp_nistp521_have_precompute_mult,
-+        ec_GFp_nist_field_mul,
-+        ec_GFp_nist_field_sqr,
-+        0 /* field_div */ ,
-+        0 /* field_encode */ ,
-+        0 /* field_decode */ ,
-+        0,                      /* field_set_to_one */
-+        ec_key_simple_priv2oct,
-+        ec_key_simple_oct2priv,
-+        0, /* set private */
-+        ec_key_simple_generate_key,
-+        ec_key_simple_check_key,
-+        ec_key_simple_generate_public_key,
-+        0, /* keycopy */
-+        0, /* keyfinish */
-+        ecdh_simple_compute_key
-+    };
-+
-+    return &ret;
-+}
-+
-+/******************************************************************************/
-+/*
-+ * FUNCTIONS TO MANAGE PRECOMPUTATION
-+ */
-+
-+static NISTP521_PRE_COMP *nistp521_pre_comp_new()
-+{
-+    NISTP521_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
-+        return ret;
-+    }
-+
-+    ret->references = 1;
-+
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *p)
-+{
-+    int i;
-+    if (p != NULL)
-+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
-+    return p;
-+}
-+
-+void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *p)
-+{
-+    int i;
-+
-+    if (p == NULL)
-+        return;
-+
-+    CRYPTO_atomic_add(&p->references, -1, &i, p->lock);
-+    REF_PRINT_COUNT("EC_nistp521", x);
-+    if (i > 0)
-+        return;
-+    REF_ASSERT_ISNT(i < 0);
-+
-+    CRYPTO_THREAD_lock_free(p->lock);
-+    OPENSSL_free(p);
-+}
-+
-+/******************************************************************************/
-+/*
-+ * OPENSSL EC_METHOD FUNCTIONS
-+ */
-+
-+int ec_GFp_nistp521_group_init(EC_GROUP *group)
-+{
-+    int ret;
-+    ret = ec_GFp_simple_group_init(group);
-+    group->a_is_minus3 = 1;
-+    return ret;
-+}
-+
-+int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
-+                                    const BIGNUM *a, const BIGNUM *b,
-+                                    BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *curve_p, *curve_a, *curve_b;
-+
-+    if (ctx == NULL)
-+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+    BN_CTX_start(ctx);
-+    if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
-+        ((curve_a = BN_CTX_get(ctx)) == NULL) ||
-+        ((curve_b = BN_CTX_get(ctx)) == NULL))
-+        goto err;
-+    BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p);
-+    BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a);
-+    BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b);
-+    if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
-+        ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE,
-+              EC_R_WRONG_CURVE_PARAMETERS);
-+        goto err;
-+    }
-+    group->field_mod_func = BN_nist_mod_521;
-+    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+/*
-+ * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
-+ * (X/Z^2, Y/Z^3)
-+ */
-+int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
-+                                                 const EC_POINT *point,
-+                                                 BIGNUM *x, BIGNUM *y,
-+                                                 BN_CTX *ctx)
-+{
-+    felem z1, z2, x_in, y_in, x_out, y_out;
-+    largefelem tmp;
-+
-+    if (EC_POINT_is_at_infinity(group, point)) {
-+        ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
-+              EC_R_POINT_AT_INFINITY);
-+        return 0;
-+    }
-+    if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
-+        (!BN_to_felem(z1, point->Z)))
-+        return 0;
-+    felem_inv(z2, z1);
-+    felem_square(tmp, z2);
-+    felem_reduce(z1, tmp);
-+    felem_mul(tmp, x_in, z1);
-+    felem_reduce(x_in, tmp);
-+    felem_contract(x_out, x_in);
-+    if (x != NULL) {
-+        if (!felem_to_BN(x, x_out)) {
-+            ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
-+                  ERR_R_BN_LIB);
-+            return 0;
-+        }
-+    }
-+    felem_mul(tmp, z1, z2);
-+    felem_reduce(z1, tmp);
-+    felem_mul(tmp, y_in, z1);
-+    felem_reduce(y_in, tmp);
-+    felem_contract(y_out, y_in);
-+    if (y != NULL) {
-+        if (!felem_to_BN(y, y_out)) {
-+            ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
-+                  ERR_R_BN_LIB);
-+            return 0;
-+        }
-+    }
-+    return 1;
-+}
-+
-+/* points below is of size |num|, and tmp_felems is of size |num+1/ */
-+static void make_points_affine(size_t num, felem points[][3],
-+                               felem tmp_felems[])
-+{
-+    /*
-+     * Runs in constant time, unless an input is the point at infinity (which
-+     * normally shouldn't happen).
-+     */
-+    ec_GFp_nistp_points_make_affine_internal(num,
-+                                             points,
-+                                             sizeof(felem),
-+                                             tmp_felems,
-+                                             (void (*)(void *))felem_one,
-+                                             (int (*)(const void *))
-+                                             felem_is_zero_int,
-+                                             (void (*)(void *, const void *))
-+                                             felem_assign,
-+                                             (void (*)(void *, const void *))
-+                                             felem_square_reduce, (void (*)
-+                                                                   (void *,
-+                                                                    const void
-+                                                                    *,
-+                                                                    const void
-+                                                                    *))
-+                                             felem_mul_reduce,
-+                                             (void (*)(void *, const void *))
-+                                             felem_inv,
-+                                             (void (*)(void *, const void *))
-+                                             felem_contract);
-+}
-+
-+/*
-+ * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
-+ * values Result is stored in r (r can equal one of the inputs).
-+ */
-+int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
-+                               const BIGNUM *scalar, size_t num,
-+                               const EC_POINT *points[],
-+                               const BIGNUM *scalars[], BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    int j;
-+    int mixed = 0;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *x, *y, *z, *tmp_scalar;
-+    felem_bytearray g_secret;
-+    felem_bytearray *secrets = NULL;
-+    felem (*pre_comp)[17][3] = NULL;
-+    felem *tmp_felems = NULL;
-+    felem_bytearray tmp;
-+    unsigned i, num_bytes;
-+    int have_pre_comp = 0;
-+    size_t num_points = num;
-+    felem x_in, y_in, z_in, x_out, y_out, z_out;
-+    NISTP521_PRE_COMP *pre = NULL;
-+    felem(*g_pre_comp)[3] = NULL;
-+    EC_POINT *generator = NULL;
-+    const EC_POINT *p = NULL;
-+    const BIGNUM *p_scalar = NULL;
-+
-+    if (ctx == NULL)
-+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+    BN_CTX_start(ctx);
-+    if (((x = BN_CTX_get(ctx)) == NULL) ||
-+        ((y = BN_CTX_get(ctx)) == NULL) ||
-+        ((z = BN_CTX_get(ctx)) == NULL) ||
-+        ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
-+        goto err;
-+
-+    if (scalar != NULL) {
-+        pre = group->pre_comp.nistp521;
-+        if (pre)
-+            /* we have precomputation, try to use it */
-+            g_pre_comp = &pre->g_pre_comp[0];
-+        else
-+            /* try to use the standard precomputation */
-+            g_pre_comp = (felem(*)[3]) gmul;
-+        generator = EC_POINT_new(group);
-+        if (generator == NULL)
-+            goto err;
-+        /* get the generator from precomputation */
-+        if (!felem_to_BN(x, g_pre_comp[1][0]) ||
-+            !felem_to_BN(y, g_pre_comp[1][1]) ||
-+            !felem_to_BN(z, g_pre_comp[1][2])) {
-+            ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
-+            goto err;
-+        }
-+        if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
-+                                                      generator, x, y, z,
-+                                                      ctx))
-+            goto err;
-+        if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
-+            /* precomputation matches generator */
-+            have_pre_comp = 1;
-+        else
-+            /*
-+             * we don't have valid precomputation: treat the generator as a
-+             * random point
-+             */
-+            num_points++;
-+    }
-+
-+    if (num_points > 0) {
-+        if (num_points >= 2) {
-+            /*
-+             * unless we precompute multiples for just one point, converting
-+             * those into affine form is time well spent
-+             */
-+            mixed = 1;
-+        }
-+        secrets = OPENSSL_zalloc(sizeof(*secrets) * num_points);
-+        pre_comp = OPENSSL_zalloc(sizeof(*pre_comp) * num_points);
-+        if (mixed)
-+            tmp_felems =
-+                OPENSSL_malloc(sizeof(*tmp_felems) * (num_points * 17 + 1));
-+        if ((secrets == NULL) || (pre_comp == NULL)
-+            || (mixed && (tmp_felems == NULL))) {
-+            ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+
-+        /*
-+         * we treat NULL scalars as 0, and NULL points as points at infinity,
-+         * i.e., they contribute nothing to the linear combination
-+         */
-+        for (i = 0; i < num_points; ++i) {
-+            if (i == num)
-+                /*
-+                 * we didn't have a valid precomputation, so we pick the
-+                 * generator
-+                 */
-+            {
-+                p = EC_GROUP_get0_generator(group);
-+                p_scalar = scalar;
-+            } else
-+                /* the i^th point */
-+            {
-+                p = points[i];
-+                p_scalar = scalars[i];
-+            }
-+            if ((p_scalar != NULL) && (p != NULL)) {
-+                /* reduce scalar to 0 <= scalar < 2^521 */
-+                if ((BN_num_bits(p_scalar) > 521)
-+                    || (BN_is_negative(p_scalar))) {
-+                    /*
-+                     * this is an unusual input, and we don't guarantee
-+                     * constant-timeness
-+                     */
-+                    if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
-+                        ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
-+                        goto err;
-+                    }
-+                    num_bytes = BN_bn2bin(tmp_scalar, tmp);
-+                } else
-+                    num_bytes = BN_bn2bin(p_scalar, tmp);
-+                flip_endian(secrets[i], tmp, num_bytes);
-+                /* precompute multiples */
-+                if ((!BN_to_felem(x_out, p->X)) ||
-+                    (!BN_to_felem(y_out, p->Y)) ||
-+                    (!BN_to_felem(z_out, p->Z)))
-+                    goto err;
-+                memcpy(pre_comp[i][1][0], x_out, sizeof(felem));
-+                memcpy(pre_comp[i][1][1], y_out, sizeof(felem));
-+                memcpy(pre_comp[i][1][2], z_out, sizeof(felem));
-+                for (j = 2; j <= 16; ++j) {
-+                    if (j & 1) {
-+                        point_add(pre_comp[i][j][0], pre_comp[i][j][1],
-+                                  pre_comp[i][j][2], pre_comp[i][1][0],
-+                                  pre_comp[i][1][1], pre_comp[i][1][2], 0,
-+                                  pre_comp[i][j - 1][0],
-+                                  pre_comp[i][j - 1][1],
-+                                  pre_comp[i][j - 1][2]);
-+                    } else {
-+                        point_double(pre_comp[i][j][0], pre_comp[i][j][1],
-+                                     pre_comp[i][j][2], pre_comp[i][j / 2][0],
-+                                     pre_comp[i][j / 2][1],
-+                                     pre_comp[i][j / 2][2]);
-+                    }
-+                }
-+            }
-+        }
-+        if (mixed)
-+            make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
-+    }
-+
-+    /* the scalar for the generator */
-+    if ((scalar != NULL) && (have_pre_comp)) {
-+        memset(g_secret, 0, sizeof(g_secret));
-+        /* reduce scalar to 0 <= scalar < 2^521 */
-+        if ((BN_num_bits(scalar) > 521) || (BN_is_negative(scalar))) {
-+            /*
-+             * this is an unusual input, and we don't guarantee
-+             * constant-timeness
-+             */
-+            if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
-+                ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
-+                goto err;
-+            }
-+            num_bytes = BN_bn2bin(tmp_scalar, tmp);
-+        } else
-+            num_bytes = BN_bn2bin(scalar, tmp);
-+        flip_endian(g_secret, tmp, num_bytes);
-+        /* do the multiplication with generator precomputation */
-+        batch_mul(x_out, y_out, z_out,
-+                  (const felem_bytearray(*))secrets, num_points,
-+                  g_secret,
-+                  mixed, (const felem(*)[17][3])pre_comp,
-+                  (const felem(*)[3])g_pre_comp);
-+    } else
-+        /* do the multiplication without generator precomputation */
-+        batch_mul(x_out, y_out, z_out,
-+                  (const felem_bytearray(*))secrets, num_points,
-+                  NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
-+    /* reduce the output to its unique minimal representation */
-+    felem_contract(x_in, x_out);
-+    felem_contract(y_in, y_out);
-+    felem_contract(z_in, z_out);
-+    if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
-+        (!felem_to_BN(z, z_in))) {
-+        ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    EC_POINT_free(generator);
-+    BN_CTX_free(new_ctx);
-+    OPENSSL_free(secrets);
-+    OPENSSL_free(pre_comp);
-+    OPENSSL_free(tmp_felems);
-+    return ret;
-+}
-+
-+int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    NISTP521_PRE_COMP *pre = NULL;
-+    int i, j;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *x, *y;
-+    EC_POINT *generator = NULL;
-+    felem tmp_felems[16];
-+
-+    /* throw away old precomputation */
-+    EC_pre_comp_free(group);
-+    if (ctx == NULL)
-+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+    BN_CTX_start(ctx);
-+    if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
-+        goto err;
-+    /* get the generator */
-+    if (group->generator == NULL)
-+        goto err;
-+    generator = EC_POINT_new(group);
-+    if (generator == NULL)
-+        goto err;
-+    BN_bin2bn(nistp521_curve_params[3], sizeof(felem_bytearray), x);
-+    BN_bin2bn(nistp521_curve_params[4], sizeof(felem_bytearray), y);
-+    if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
-+        goto err;
-+    if ((pre = nistp521_pre_comp_new()) == NULL)
-+        goto err;
-+    /*
-+     * if the generator is the standard one, use built-in precomputation
-+     */
-+    if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
-+        memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
-+        goto done;
-+    }
-+    if ((!BN_to_felem(pre->g_pre_comp[1][0], group->generator->X)) ||
-+        (!BN_to_felem(pre->g_pre_comp[1][1], group->generator->Y)) ||
-+        (!BN_to_felem(pre->g_pre_comp[1][2], group->generator->Z)))
-+        goto err;
-+    /* compute 2^130*G, 2^260*G, 2^390*G */
-+    for (i = 1; i <= 4; i <<= 1) {
-+        point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1],
-+                     pre->g_pre_comp[2 * i][2], pre->g_pre_comp[i][0],
-+                     pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]);
-+        for (j = 0; j < 129; ++j) {
-+            point_double(pre->g_pre_comp[2 * i][0],
-+                         pre->g_pre_comp[2 * i][1],
-+                         pre->g_pre_comp[2 * i][2],
-+                         pre->g_pre_comp[2 * i][0],
-+                         pre->g_pre_comp[2 * i][1],
-+                         pre->g_pre_comp[2 * i][2]);
-+        }
-+    }
-+    /* g_pre_comp[0] is the point at infinity */
-+    memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0]));
-+    /* the remaining multiples */
-+    /* 2^130*G + 2^260*G */
-+    point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1],
-+              pre->g_pre_comp[6][2], pre->g_pre_comp[4][0],
-+              pre->g_pre_comp[4][1], pre->g_pre_comp[4][2],
-+              0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
-+              pre->g_pre_comp[2][2]);
-+    /* 2^130*G + 2^390*G */
-+    point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1],
-+              pre->g_pre_comp[10][2], pre->g_pre_comp[8][0],
-+              pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
-+              0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
-+              pre->g_pre_comp[2][2]);
-+    /* 2^260*G + 2^390*G */
-+    point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1],
-+              pre->g_pre_comp[12][2], pre->g_pre_comp[8][0],
-+              pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
-+              0, pre->g_pre_comp[4][0], pre->g_pre_comp[4][1],
-+              pre->g_pre_comp[4][2]);
-+    /* 2^130*G + 2^260*G + 2^390*G */
-+    point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1],
-+              pre->g_pre_comp[14][2], pre->g_pre_comp[12][0],
-+              pre->g_pre_comp[12][1], pre->g_pre_comp[12][2],
-+              0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
-+              pre->g_pre_comp[2][2]);
-+    for (i = 1; i < 8; ++i) {
-+        /* odd multiples: add G */
-+        point_add(pre->g_pre_comp[2 * i + 1][0],
-+                  pre->g_pre_comp[2 * i + 1][1],
-+                  pre->g_pre_comp[2 * i + 1][2], pre->g_pre_comp[2 * i][0],
-+                  pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2], 0,
-+                  pre->g_pre_comp[1][0], pre->g_pre_comp[1][1],
-+                  pre->g_pre_comp[1][2]);
-+    }
-+    make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems);
-+
-+ done:
-+    SETPRECOMP(group, nistp521, pre);
-+    ret = 1;
-+    pre = NULL;
-+ err:
-+    BN_CTX_end(ctx);
-+    EC_POINT_free(generator);
-+    BN_CTX_free(new_ctx);
-+    EC_nistp521_pre_comp_free(pre);
-+    return ret;
-+}
-+
-+int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group)
-+{
-+    return HAVEPRECOMP(group, nistp521);
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistputil.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistputil.c
-new file mode 100644
-index 0000000..97fb631
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistputil.c
-@@ -0,0 +1,223 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Copyright 2011 Google Inc.
-+ *
-+ * Licensed under the Apache License, Version 2.0 (the "License");
-+ *
-+ * you may not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ *
-+ *     http://www.apache.org/licenses/LICENSE-2.0
-+ *
-+ *  Unless required by applicable law or agreed to in writing, software
-+ *  distributed under the License is distributed on an "AS IS" BASIS,
-+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+ *  See the License for the specific language governing permissions and
-+ *  limitations under the License.
-+ */
-+
-+#include 
-+#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+/*
-+ * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
-+ */
-+
-+# include 
-+# include "ec_lcl.h"
-+
-+/*
-+ * Convert an array of points into affine coordinates. (If the point at
-+ * infinity is found (Z = 0), it remains unchanged.) This function is
-+ * essentially an equivalent to EC_POINTs_make_affine(), but works with the
-+ * internal representation of points as used by ecp_nistp###.c rather than
-+ * with (BIGNUM-based) EC_POINT data structures. point_array is the
-+ * input/output buffer ('num' points in projective form, i.e. three
-+ * coordinates each), based on an internal representation of field elements
-+ * of size 'felem_size'. tmp_felems needs to point to a temporary array of
-+ * 'num'+1 field elements for storage of intermediate values.
-+ */
-+void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
-+                                              size_t felem_size,
-+                                              void *tmp_felems,
-+                                              void (*felem_one) (void *out),
-+                                              int (*felem_is_zero) (const void
-+                                                                    *in),
-+                                              void (*felem_assign) (void *out,
-+                                                                    const void
-+                                                                    *in),
-+                                              void (*felem_square) (void *out,
-+                                                                    const void
-+                                                                    *in),
-+                                              void (*felem_mul) (void *out,
-+                                                                 const void
-+                                                                 *in1,
-+                                                                 const void
-+                                                                 *in2),
-+                                              void (*felem_inv) (void *out,
-+                                                                 const void
-+                                                                 *in),
-+                                              void (*felem_contract) (void
-+                                                                      *out,
-+                                                                      const
-+                                                                      void
-+                                                                      *in))
-+{
-+    int i = 0;
-+
-+# define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
-+# define X(I) (&((char *)point_array)[3*(I) * felem_size])
-+# define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
-+# define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
-+
-+    if (!felem_is_zero(Z(0)))
-+        felem_assign(tmp_felem(0), Z(0));
-+    else
-+        felem_one(tmp_felem(0));
-+    for (i = 1; i < (int)num; i++) {
-+        if (!felem_is_zero(Z(i)))
-+            felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i));
-+        else
-+            felem_assign(tmp_felem(i), tmp_felem(i - 1));
-+    }
-+    /*
-+     * Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any
-+     * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1
-+     */
-+
-+    felem_inv(tmp_felem(num - 1), tmp_felem(num - 1));
-+    for (i = num - 1; i >= 0; i--) {
-+        if (i > 0)
-+            /*
-+             * tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i)
-+             * is the inverse of the product of Z(0) .. Z(i)
-+             */
-+            /* 1/Z(i) */
-+            felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i));
-+        else
-+            felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
-+
-+        if (!felem_is_zero(Z(i))) {
-+            if (i > 0)
-+                /*
-+                 * For next iteration, replace tmp_felem(i-1) by its inverse
-+                 */
-+                felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i));
-+
-+            /*
-+             * Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1)
-+             */
-+            felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */
-+            felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */
-+            felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
-+            felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */
-+            felem_contract(X(i), X(i));
-+            felem_contract(Y(i), Y(i));
-+            felem_one(Z(i));
-+        } else {
-+            if (i > 0)
-+                /*
-+                 * For next iteration, replace tmp_felem(i-1) by its inverse
-+                 */
-+                felem_assign(tmp_felem(i - 1), tmp_felem(i));
-+        }
-+    }
-+}
-+
-+/*-
-+ * This function looks at 5+1 scalar bits (5 current, 1 adjacent less
-+ * significant bit), and recodes them into a signed digit for use in fast point
-+ * multiplication: the use of signed rather than unsigned digits means that
-+ * fewer points need to be precomputed, given that point inversion is easy
-+ * (a precomputed point dP makes -dP available as well).
-+ *
-+ * BACKGROUND:
-+ *
-+ * Signed digits for multiplication were introduced by Booth ("A signed binary
-+ * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
-+ * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
-+ * Booth's original encoding did not generally improve the density of nonzero
-+ * digits over the binary representation, and was merely meant to simplify the
-+ * handling of signed factors given in two's complement; but it has since been
-+ * shown to be the basis of various signed-digit representations that do have
-+ * further advantages, including the wNAF, using the following general approach:
-+ *
-+ * (1) Given a binary representation
-+ *
-+ *       b_k  ...  b_2  b_1  b_0,
-+ *
-+ *     of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
-+ *     by using bit-wise subtraction as follows:
-+ *
-+ *        b_k b_(k-1)  ...  b_2  b_1  b_0
-+ *      -     b_k      ...  b_3  b_2  b_1  b_0
-+ *       -------------------------------------
-+ *        s_k b_(k-1)  ...  s_3  s_2  s_1  s_0
-+ *
-+ *     A left-shift followed by subtraction of the original value yields a new
-+ *     representation of the same value, using signed bits s_i = b_(i+1) - b_i.
-+ *     This representation from Booth's paper has since appeared in the
-+ *     literature under a variety of different names including "reversed binary
-+ *     form", "alternating greedy expansion", "mutual opposite form", and
-+ *     "sign-alternating {+-1}-representation".
-+ *
-+ *     An interesting property is that among the nonzero bits, values 1 and -1
-+ *     strictly alternate.
-+ *
-+ * (2) Various window schemes can be applied to the Booth representation of
-+ *     integers: for example, right-to-left sliding windows yield the wNAF
-+ *     (a signed-digit encoding independently discovered by various researchers
-+ *     in the 1990s), and left-to-right sliding windows yield a left-to-right
-+ *     equivalent of the wNAF (independently discovered by various researchers
-+ *     around 2004).
-+ *
-+ * To prevent leaking information through side channels in point multiplication,
-+ * we need to recode the given integer into a regular pattern: sliding windows
-+ * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
-+ * decades older: we'll be using the so-called "modified Booth encoding" due to
-+ * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
-+ * (1961), pp. 67-91), in a radix-2^5 setting.  That is, we always combine five
-+ * signed bits into a signed digit:
-+ *
-+ *       s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
-+ *
-+ * The sign-alternating property implies that the resulting digit values are
-+ * integers from -16 to 16.
-+ *
-+ * Of course, we don't actually need to compute the signed digits s_i as an
-+ * intermediate step (that's just a nice way to see how this scheme relates
-+ * to the wNAF): a direct computation obtains the recoded digit from the
-+ * six bits b_(4j + 4) ... b_(4j - 1).
-+ *
-+ * This function takes those five bits as an integer (0 .. 63), writing the
-+ * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
-+ * value, in the range 0 .. 8).  Note that this integer essentially provides the
-+ * input bits "shifted to the left" by one position: for example, the input to
-+ * compute the least significant recoded digit, given that there's no bit b_-1,
-+ * has to be b_4 b_3 b_2 b_1 b_0 0.
-+ *
-+ */
-+void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
-+                                     unsigned char *digit, unsigned char in)
-+{
-+    unsigned char s, d;
-+
-+    s = ~((in >> 5) - 1);       /* sets all bits to MSB(in), 'in' seen as
-+                                 * 6-bit value */
-+    d = (1 << 6) - in - 1;
-+    d = (d & s) | (in & ~s);
-+    d = (d >> 1) + (d & 1);
-+
-+    *sign = s & 1;
-+    *digit = d;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistz256.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistz256.c
-new file mode 100644
-index 0000000..dca3a2d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistz256.c
-@@ -0,0 +1,1559 @@
-+/*
-+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/******************************************************************************
-+ *                                                                            *
-+ * Copyright 2014 Intel Corporation                                           *
-+ *                                                                            *
-+ * Licensed under the Apache License, Version 2.0 (the "License");            *
-+ * you may not use this file except in compliance with the License.           *
-+ * You may obtain a copy of the License at                                    *
-+ *                                                                            *
-+ *    http://www.apache.org/licenses/LICENSE-2.0                              *
-+ *                                                                            *
-+ * Unless required by applicable law or agreed to in writing, software        *
-+ * distributed under the License is distributed on an "AS IS" BASIS,          *
-+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
-+ * See the License for the specific language governing permissions and        *
-+ * limitations under the License.                                             *
-+ *                                                                            *
-+ ******************************************************************************
-+ *                                                                            *
-+ * Developers and authors:                                                    *
-+ * Shay Gueron (1, 2), and Vlad Krasnov (1)                                   *
-+ * (1) Intel Corporation, Israel Development Center                           *
-+ * (2) University of Haifa                                                    *
-+ * Reference:                                                                 *
-+ * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with *
-+ *                          256 Bit Primes"                                   *
-+ *                                                                            *
-+ ******************************************************************************/
-+
-+#include 
-+
-+#include "internal/cryptlib.h"
-+#include "internal/bn_int.h"
-+#include "ec_lcl.h"
-+
-+#if BN_BITS2 != 64
-+# define TOBN(hi,lo)    lo,hi
-+#else
-+# define TOBN(hi,lo)    ((BN_ULONG)hi<<32|lo)
-+#endif
-+
-+#if defined(__GNUC__)
-+# define ALIGN32        __attribute((aligned(32)))
-+#elif defined(_MSC_VER)
-+# define ALIGN32        __declspec(align(32))
-+#else
-+# define ALIGN32
-+#endif
-+
-+#define ALIGNPTR(p,N)   ((unsigned char *)p+N-(size_t)p%N)
-+#define P256_LIMBS      (256/BN_BITS2)
-+
-+typedef unsigned short u16;
-+
-+typedef struct {
-+    BN_ULONG X[P256_LIMBS];
-+    BN_ULONG Y[P256_LIMBS];
-+    BN_ULONG Z[P256_LIMBS];
-+} P256_POINT;
-+
-+typedef struct {
-+    BN_ULONG X[P256_LIMBS];
-+    BN_ULONG Y[P256_LIMBS];
-+} P256_POINT_AFFINE;
-+
-+typedef P256_POINT_AFFINE PRECOMP256_ROW[64];
-+
-+/* structure for precomputed multiples of the generator */
-+struct nistz256_pre_comp_st {
-+    const EC_GROUP *group;      /* Parent EC_GROUP object */
-+    size_t w;                   /* Window size */
-+    /*
-+     * Constant time access to the X and Y coordinates of the pre-computed,
-+     * generator multiplies, in the Montgomery domain. Pre-calculated
-+     * multiplies are stored in affine form.
-+     */
-+    PRECOMP256_ROW *precomp;
-+    void *precomp_storage;
-+    int references;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+/* Functions implemented in assembly */
-+/*
-+ * Most of below mentioned functions *preserve* the property of inputs
-+ * being fully reduced, i.e. being in [0, modulus) range. Simply put if
-+ * inputs are fully reduced, then output is too. Note that reverse is
-+ * not true, in sense that given partially reduced inputs output can be
-+ * either, not unlikely reduced. And "most" in first sentence refers to
-+ * the fact that given the calculations flow one can tolerate that
-+ * addition, 1st function below, produces partially reduced result *if*
-+ * multiplications by 2 and 3, which customarily use addition, fully
-+ * reduce it. This effectively gives two options: a) addition produces
-+ * fully reduced result [as long as inputs are, just like remaining
-+ * functions]; b) addition is allowed to produce partially reduced
-+ * result, but multiplications by 2 and 3 perform additional reduction
-+ * step. Choice between the two can be platform-specific, but it was a)
-+ * in all cases so far...
-+ */
-+/* Modular add: res = a+b mod P   */
-+void ecp_nistz256_add(BN_ULONG res[P256_LIMBS],
-+                      const BN_ULONG a[P256_LIMBS],
-+                      const BN_ULONG b[P256_LIMBS]);
-+/* Modular mul by 2: res = 2*a mod P */
-+void ecp_nistz256_mul_by_2(BN_ULONG res[P256_LIMBS],
-+                           const BN_ULONG a[P256_LIMBS]);
-+/* Modular mul by 3: res = 3*a mod P */
-+void ecp_nistz256_mul_by_3(BN_ULONG res[P256_LIMBS],
-+                           const BN_ULONG a[P256_LIMBS]);
-+
-+/* Modular div by 2: res = a/2 mod P */
-+void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS],
-+                           const BN_ULONG a[P256_LIMBS]);
-+/* Modular sub: res = a-b mod P   */
-+void ecp_nistz256_sub(BN_ULONG res[P256_LIMBS],
-+                      const BN_ULONG a[P256_LIMBS],
-+                      const BN_ULONG b[P256_LIMBS]);
-+/* Modular neg: res = -a mod P    */
-+void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]);
-+/* Montgomery mul: res = a*b*2^-256 mod P */
-+void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS],
-+                           const BN_ULONG a[P256_LIMBS],
-+                           const BN_ULONG b[P256_LIMBS]);
-+/* Montgomery sqr: res = a*a*2^-256 mod P */
-+void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
-+                           const BN_ULONG a[P256_LIMBS]);
-+/* Convert a number from Montgomery domain, by multiplying with 1 */
-+void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS],
-+                            const BN_ULONG in[P256_LIMBS]);
-+/* Convert a number to Montgomery domain, by multiplying with 2^512 mod P*/
-+void ecp_nistz256_to_mont(BN_ULONG res[P256_LIMBS],
-+                          const BN_ULONG in[P256_LIMBS]);
-+/* Functions that perform constant time access to the precomputed tables */
-+void ecp_nistz256_scatter_w5(P256_POINT *val,
-+                             const P256_POINT *in_t, int idx);
-+void ecp_nistz256_gather_w5(P256_POINT *val,
-+                            const P256_POINT *in_t, int idx);
-+void ecp_nistz256_scatter_w7(P256_POINT_AFFINE *val,
-+                             const P256_POINT_AFFINE *in_t, int idx);
-+void ecp_nistz256_gather_w7(P256_POINT_AFFINE *val,
-+                            const P256_POINT_AFFINE *in_t, int idx);
-+
-+/* One converted into the Montgomery domain */
-+static const BN_ULONG ONE[P256_LIMBS] = {
-+    TOBN(0x00000000, 0x00000001), TOBN(0xffffffff, 0x00000000),
-+    TOBN(0xffffffff, 0xffffffff), TOBN(0x00000000, 0xfffffffe)
-+};
-+
-+static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group);
-+
-+/* Precomputed tables for the default generator */
-+extern const PRECOMP256_ROW ecp_nistz256_precomputed[37];
-+
-+/* Recode window to a signed digit, see ecp_nistputil.c for details */
-+static unsigned int _booth_recode_w5(unsigned int in)
-+{
-+    unsigned int s, d;
-+
-+    s = ~((in >> 5) - 1);
-+    d = (1 << 6) - in - 1;
-+    d = (d & s) | (in & ~s);
-+    d = (d >> 1) + (d & 1);
-+
-+    return (d << 1) + (s & 1);
-+}
-+
-+static unsigned int _booth_recode_w7(unsigned int in)
-+{
-+    unsigned int s, d;
-+
-+    s = ~((in >> 7) - 1);
-+    d = (1 << 8) - in - 1;
-+    d = (d & s) | (in & ~s);
-+    d = (d >> 1) + (d & 1);
-+
-+    return (d << 1) + (s & 1);
-+}
-+
-+static void copy_conditional(BN_ULONG dst[P256_LIMBS],
-+                             const BN_ULONG src[P256_LIMBS], BN_ULONG move)
-+{
-+    BN_ULONG mask1 = 0-move;
-+    BN_ULONG mask2 = ~mask1;
-+
-+    dst[0] = (src[0] & mask1) ^ (dst[0] & mask2);
-+    dst[1] = (src[1] & mask1) ^ (dst[1] & mask2);
-+    dst[2] = (src[2] & mask1) ^ (dst[2] & mask2);
-+    dst[3] = (src[3] & mask1) ^ (dst[3] & mask2);
-+    if (P256_LIMBS == 8) {
-+        dst[4] = (src[4] & mask1) ^ (dst[4] & mask2);
-+        dst[5] = (src[5] & mask1) ^ (dst[5] & mask2);
-+        dst[6] = (src[6] & mask1) ^ (dst[6] & mask2);
-+        dst[7] = (src[7] & mask1) ^ (dst[7] & mask2);
-+    }
-+}
-+
-+static BN_ULONG is_zero(BN_ULONG in)
-+{
-+    in |= (0 - in);
-+    in = ~in;
-+    in >>= BN_BITS2 - 1;
-+    return in;
-+}
-+
-+static BN_ULONG is_equal(const BN_ULONG a[P256_LIMBS],
-+                         const BN_ULONG b[P256_LIMBS])
-+{
-+    BN_ULONG res;
-+
-+    res = a[0] ^ b[0];
-+    res |= a[1] ^ b[1];
-+    res |= a[2] ^ b[2];
-+    res |= a[3] ^ b[3];
-+    if (P256_LIMBS == 8) {
-+        res |= a[4] ^ b[4];
-+        res |= a[5] ^ b[5];
-+        res |= a[6] ^ b[6];
-+        res |= a[7] ^ b[7];
-+    }
-+
-+    return is_zero(res);
-+}
-+
-+static BN_ULONG is_one(const BIGNUM *z)
-+{
-+    BN_ULONG res = 0;
-+    BN_ULONG *a = bn_get_words(z);
-+
-+    if (bn_get_top(z) == (P256_LIMBS - P256_LIMBS / 8)) {
-+        res = a[0] ^ ONE[0];
-+        res |= a[1] ^ ONE[1];
-+        res |= a[2] ^ ONE[2];
-+        res |= a[3] ^ ONE[3];
-+        if (P256_LIMBS == 8) {
-+            res |= a[4] ^ ONE[4];
-+            res |= a[5] ^ ONE[5];
-+            res |= a[6] ^ ONE[6];
-+            /*
-+             * no check for a[7] (being zero) on 32-bit platforms,
-+             * because value of "one" takes only 7 limbs.
-+             */
-+        }
-+        res = is_zero(res);
-+    }
-+
-+    return res;
-+}
-+
-+#ifndef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
-+void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
-+void ecp_nistz256_point_add(P256_POINT *r,
-+                            const P256_POINT *a, const P256_POINT *b);
-+void ecp_nistz256_point_add_affine(P256_POINT *r,
-+                                   const P256_POINT *a,
-+                                   const P256_POINT_AFFINE *b);
-+#else
-+/* Point double: r = 2*a */
-+static void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a)
-+{
-+    BN_ULONG S[P256_LIMBS];
-+    BN_ULONG M[P256_LIMBS];
-+    BN_ULONG Zsqr[P256_LIMBS];
-+    BN_ULONG tmp0[P256_LIMBS];
-+
-+    const BN_ULONG *in_x = a->X;
-+    const BN_ULONG *in_y = a->Y;
-+    const BN_ULONG *in_z = a->Z;
-+
-+    BN_ULONG *res_x = r->X;
-+    BN_ULONG *res_y = r->Y;
-+    BN_ULONG *res_z = r->Z;
-+
-+    ecp_nistz256_mul_by_2(S, in_y);
-+
-+    ecp_nistz256_sqr_mont(Zsqr, in_z);
-+
-+    ecp_nistz256_sqr_mont(S, S);
-+
-+    ecp_nistz256_mul_mont(res_z, in_z, in_y);
-+    ecp_nistz256_mul_by_2(res_z, res_z);
-+
-+    ecp_nistz256_add(M, in_x, Zsqr);
-+    ecp_nistz256_sub(Zsqr, in_x, Zsqr);
-+
-+    ecp_nistz256_sqr_mont(res_y, S);
-+    ecp_nistz256_div_by_2(res_y, res_y);
-+
-+    ecp_nistz256_mul_mont(M, M, Zsqr);
-+    ecp_nistz256_mul_by_3(M, M);
-+
-+    ecp_nistz256_mul_mont(S, S, in_x);
-+    ecp_nistz256_mul_by_2(tmp0, S);
-+
-+    ecp_nistz256_sqr_mont(res_x, M);
-+
-+    ecp_nistz256_sub(res_x, res_x, tmp0);
-+    ecp_nistz256_sub(S, S, res_x);
-+
-+    ecp_nistz256_mul_mont(S, S, M);
-+    ecp_nistz256_sub(res_y, S, res_y);
-+}
-+
-+/* Point addition: r = a+b */
-+static void ecp_nistz256_point_add(P256_POINT *r,
-+                                   const P256_POINT *a, const P256_POINT *b)
-+{
-+    BN_ULONG U2[P256_LIMBS], S2[P256_LIMBS];
-+    BN_ULONG U1[P256_LIMBS], S1[P256_LIMBS];
-+    BN_ULONG Z1sqr[P256_LIMBS];
-+    BN_ULONG Z2sqr[P256_LIMBS];
-+    BN_ULONG H[P256_LIMBS], R[P256_LIMBS];
-+    BN_ULONG Hsqr[P256_LIMBS];
-+    BN_ULONG Rsqr[P256_LIMBS];
-+    BN_ULONG Hcub[P256_LIMBS];
-+
-+    BN_ULONG res_x[P256_LIMBS];
-+    BN_ULONG res_y[P256_LIMBS];
-+    BN_ULONG res_z[P256_LIMBS];
-+
-+    BN_ULONG in1infty, in2infty;
-+
-+    const BN_ULONG *in1_x = a->X;
-+    const BN_ULONG *in1_y = a->Y;
-+    const BN_ULONG *in1_z = a->Z;
-+
-+    const BN_ULONG *in2_x = b->X;
-+    const BN_ULONG *in2_y = b->Y;
-+    const BN_ULONG *in2_z = b->Z;
-+
-+    /*
-+     * Infinity in encoded as (,,0)
-+     */
-+    in1infty = (in1_z[0] | in1_z[1] | in1_z[2] | in1_z[3]);
-+    if (P256_LIMBS == 8)
-+        in1infty |= (in1_z[4] | in1_z[5] | in1_z[6] | in1_z[7]);
-+
-+    in2infty = (in2_z[0] | in2_z[1] | in2_z[2] | in2_z[3]);
-+    if (P256_LIMBS == 8)
-+        in2infty |= (in2_z[4] | in2_z[5] | in2_z[6] | in2_z[7]);
-+
-+    in1infty = is_zero(in1infty);
-+    in2infty = is_zero(in2infty);
-+
-+    ecp_nistz256_sqr_mont(Z2sqr, in2_z);        /* Z2^2 */
-+    ecp_nistz256_sqr_mont(Z1sqr, in1_z);        /* Z1^2 */
-+
-+    ecp_nistz256_mul_mont(S1, Z2sqr, in2_z);    /* S1 = Z2^3 */
-+    ecp_nistz256_mul_mont(S2, Z1sqr, in1_z);    /* S2 = Z1^3 */
-+
-+    ecp_nistz256_mul_mont(S1, S1, in1_y);       /* S1 = Y1*Z2^3 */
-+    ecp_nistz256_mul_mont(S2, S2, in2_y);       /* S2 = Y2*Z1^3 */
-+    ecp_nistz256_sub(R, S2, S1);                /* R = S2 - S1 */
-+
-+    ecp_nistz256_mul_mont(U1, in1_x, Z2sqr);    /* U1 = X1*Z2^2 */
-+    ecp_nistz256_mul_mont(U2, in2_x, Z1sqr);    /* U2 = X2*Z1^2 */
-+    ecp_nistz256_sub(H, U2, U1);                /* H = U2 - U1 */
-+
-+    /*
-+     * This should not happen during sign/ecdh, so no constant time violation
-+     */
-+    if (is_equal(U1, U2) && !in1infty && !in2infty) {
-+        if (is_equal(S1, S2)) {
-+            ecp_nistz256_point_double(r, a);
-+            return;
-+        } else {
-+            memset(r, 0, sizeof(*r));
-+            return;
-+        }
-+    }
-+
-+    ecp_nistz256_sqr_mont(Rsqr, R);             /* R^2 */
-+    ecp_nistz256_mul_mont(res_z, H, in1_z);     /* Z3 = H*Z1*Z2 */
-+    ecp_nistz256_sqr_mont(Hsqr, H);             /* H^2 */
-+    ecp_nistz256_mul_mont(res_z, res_z, in2_z); /* Z3 = H*Z1*Z2 */
-+    ecp_nistz256_mul_mont(Hcub, Hsqr, H);       /* H^3 */
-+
-+    ecp_nistz256_mul_mont(U2, U1, Hsqr);        /* U1*H^2 */
-+    ecp_nistz256_mul_by_2(Hsqr, U2);            /* 2*U1*H^2 */
-+
-+    ecp_nistz256_sub(res_x, Rsqr, Hsqr);
-+    ecp_nistz256_sub(res_x, res_x, Hcub);
-+
-+    ecp_nistz256_sub(res_y, U2, res_x);
-+
-+    ecp_nistz256_mul_mont(S2, S1, Hcub);
-+    ecp_nistz256_mul_mont(res_y, R, res_y);
-+    ecp_nistz256_sub(res_y, res_y, S2);
-+
-+    copy_conditional(res_x, in2_x, in1infty);
-+    copy_conditional(res_y, in2_y, in1infty);
-+    copy_conditional(res_z, in2_z, in1infty);
-+
-+    copy_conditional(res_x, in1_x, in2infty);
-+    copy_conditional(res_y, in1_y, in2infty);
-+    copy_conditional(res_z, in1_z, in2infty);
-+
-+    memcpy(r->X, res_x, sizeof(res_x));
-+    memcpy(r->Y, res_y, sizeof(res_y));
-+    memcpy(r->Z, res_z, sizeof(res_z));
-+}
-+
-+/* Point addition when b is known to be affine: r = a+b */
-+static void ecp_nistz256_point_add_affine(P256_POINT *r,
-+                                          const P256_POINT *a,
-+                                          const P256_POINT_AFFINE *b)
-+{
-+    BN_ULONG U2[P256_LIMBS], S2[P256_LIMBS];
-+    BN_ULONG Z1sqr[P256_LIMBS];
-+    BN_ULONG H[P256_LIMBS], R[P256_LIMBS];
-+    BN_ULONG Hsqr[P256_LIMBS];
-+    BN_ULONG Rsqr[P256_LIMBS];
-+    BN_ULONG Hcub[P256_LIMBS];
-+
-+    BN_ULONG res_x[P256_LIMBS];
-+    BN_ULONG res_y[P256_LIMBS];
-+    BN_ULONG res_z[P256_LIMBS];
-+
-+    BN_ULONG in1infty, in2infty;
-+
-+    const BN_ULONG *in1_x = a->X;
-+    const BN_ULONG *in1_y = a->Y;
-+    const BN_ULONG *in1_z = a->Z;
-+
-+    const BN_ULONG *in2_x = b->X;
-+    const BN_ULONG *in2_y = b->Y;
-+
-+    /*
-+     * Infinity in encoded as (,,0)
-+     */
-+    in1infty = (in1_z[0] | in1_z[1] | in1_z[2] | in1_z[3]);
-+    if (P256_LIMBS == 8)
-+        in1infty |= (in1_z[4] | in1_z[5] | in1_z[6] | in1_z[7]);
-+
-+    /*
-+     * In affine representation we encode infinity as (0,0), which is
-+     * not on the curve, so it is OK
-+     */
-+    in2infty = (in2_x[0] | in2_x[1] | in2_x[2] | in2_x[3] |
-+                in2_y[0] | in2_y[1] | in2_y[2] | in2_y[3]);
-+    if (P256_LIMBS == 8)
-+        in2infty |= (in2_x[4] | in2_x[5] | in2_x[6] | in2_x[7] |
-+                     in2_y[4] | in2_y[5] | in2_y[6] | in2_y[7]);
-+
-+    in1infty = is_zero(in1infty);
-+    in2infty = is_zero(in2infty);
-+
-+    ecp_nistz256_sqr_mont(Z1sqr, in1_z);        /* Z1^2 */
-+
-+    ecp_nistz256_mul_mont(U2, in2_x, Z1sqr);    /* U2 = X2*Z1^2 */
-+    ecp_nistz256_sub(H, U2, in1_x);             /* H = U2 - U1 */
-+
-+    ecp_nistz256_mul_mont(S2, Z1sqr, in1_z);    /* S2 = Z1^3 */
-+
-+    ecp_nistz256_mul_mont(res_z, H, in1_z);     /* Z3 = H*Z1*Z2 */
-+
-+    ecp_nistz256_mul_mont(S2, S2, in2_y);       /* S2 = Y2*Z1^3 */
-+    ecp_nistz256_sub(R, S2, in1_y);             /* R = S2 - S1 */
-+
-+    ecp_nistz256_sqr_mont(Hsqr, H);             /* H^2 */
-+    ecp_nistz256_sqr_mont(Rsqr, R);             /* R^2 */
-+    ecp_nistz256_mul_mont(Hcub, Hsqr, H);       /* H^3 */
-+
-+    ecp_nistz256_mul_mont(U2, in1_x, Hsqr);     /* U1*H^2 */
-+    ecp_nistz256_mul_by_2(Hsqr, U2);            /* 2*U1*H^2 */
-+
-+    ecp_nistz256_sub(res_x, Rsqr, Hsqr);
-+    ecp_nistz256_sub(res_x, res_x, Hcub);
-+    ecp_nistz256_sub(H, U2, res_x);
-+
-+    ecp_nistz256_mul_mont(S2, in1_y, Hcub);
-+    ecp_nistz256_mul_mont(H, H, R);
-+    ecp_nistz256_sub(res_y, H, S2);
-+
-+    copy_conditional(res_x, in2_x, in1infty);
-+    copy_conditional(res_x, in1_x, in2infty);
-+
-+    copy_conditional(res_y, in2_y, in1infty);
-+    copy_conditional(res_y, in1_y, in2infty);
-+
-+    copy_conditional(res_z, ONE, in1infty);
-+    copy_conditional(res_z, in1_z, in2infty);
-+
-+    memcpy(r->X, res_x, sizeof(res_x));
-+    memcpy(r->Y, res_y, sizeof(res_y));
-+    memcpy(r->Z, res_z, sizeof(res_z));
-+}
-+#endif
-+
-+/* r = in^-1 mod p */
-+static void ecp_nistz256_mod_inverse(BN_ULONG r[P256_LIMBS],
-+                                     const BN_ULONG in[P256_LIMBS])
-+{
-+    /*
-+     * The poly is ffffffff 00000001 00000000 00000000 00000000 ffffffff
-+     * ffffffff ffffffff We use FLT and used poly-2 as exponent
-+     */
-+    BN_ULONG p2[P256_LIMBS];
-+    BN_ULONG p4[P256_LIMBS];
-+    BN_ULONG p8[P256_LIMBS];
-+    BN_ULONG p16[P256_LIMBS];
-+    BN_ULONG p32[P256_LIMBS];
-+    BN_ULONG res[P256_LIMBS];
-+    int i;
-+
-+    ecp_nistz256_sqr_mont(res, in);
-+    ecp_nistz256_mul_mont(p2, res, in);         /* 3*p */
-+
-+    ecp_nistz256_sqr_mont(res, p2);
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(p4, res, p2);         /* f*p */
-+
-+    ecp_nistz256_sqr_mont(res, p4);
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(p8, res, p4);         /* ff*p */
-+
-+    ecp_nistz256_sqr_mont(res, p8);
-+    for (i = 0; i < 7; i++)
-+        ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(p16, res, p8);        /* ffff*p */
-+
-+    ecp_nistz256_sqr_mont(res, p16);
-+    for (i = 0; i < 15; i++)
-+        ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(p32, res, p16);       /* ffffffff*p */
-+
-+    ecp_nistz256_sqr_mont(res, p32);
-+    for (i = 0; i < 31; i++)
-+        ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(res, res, in);
-+
-+    for (i = 0; i < 32 * 4; i++)
-+        ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(res, res, p32);
-+
-+    for (i = 0; i < 32; i++)
-+        ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(res, res, p32);
-+
-+    for (i = 0; i < 16; i++)
-+        ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(res, res, p16);
-+
-+    for (i = 0; i < 8; i++)
-+        ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(res, res, p8);
-+
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(res, res, p4);
-+
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(res, res, p2);
-+
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_sqr_mont(res, res);
-+    ecp_nistz256_mul_mont(res, res, in);
-+
-+    memcpy(r, res, sizeof(res));
-+}
-+
-+/*
-+ * ecp_nistz256_bignum_to_field_elem copies the contents of |in| to |out| and
-+ * returns one if it fits. Otherwise it returns zero.
-+ */
-+__owur static int ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS],
-+                                                    const BIGNUM *in)
-+{
-+    return bn_copy_words(out, in, P256_LIMBS);
-+}
-+
-+/* r = sum(scalar[i]*point[i]) */
-+__owur static int ecp_nistz256_windowed_mul(const EC_GROUP *group,
-+                                            P256_POINT *r,
-+                                            const BIGNUM **scalar,
-+                                            const EC_POINT **point,
-+                                            size_t num, BN_CTX *ctx)
-+{
-+    size_t i;
-+    int j, ret = 0;
-+    unsigned int idx;
-+    unsigned char (*p_str)[33] = NULL;
-+    const unsigned int window_size = 5;
-+    const unsigned int mask = (1 << (window_size + 1)) - 1;
-+    unsigned int wvalue;
-+    P256_POINT *temp;           /* place for 5 temporary points */
-+    const BIGNUM **scalars = NULL;
-+    P256_POINT (*table)[16] = NULL;
-+    void *table_storage = NULL;
-+
-+    if ((num * 16 + 6) > OPENSSL_MALLOC_MAX_NELEMS(P256_POINT)
-+        || (table_storage =
-+            OPENSSL_malloc((num * 16 + 5) * sizeof(P256_POINT) + 64)) == NULL
-+        || (p_str =
-+            OPENSSL_malloc(num * 33 * sizeof(unsigned char))) == NULL
-+        || (scalars = OPENSSL_malloc(num * sizeof(BIGNUM *))) == NULL) {
-+        ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    table = (void *)ALIGNPTR(table_storage, 64);
-+    temp = (P256_POINT *)(table + num);
-+
-+    for (i = 0; i < num; i++) {
-+        P256_POINT *row = table[i];
-+
-+        /* This is an unusual input, we don't guarantee constant-timeness. */
-+        if ((BN_num_bits(scalar[i]) > 256) || BN_is_negative(scalar[i])) {
-+            BIGNUM *mod;
-+
-+            if ((mod = BN_CTX_get(ctx)) == NULL)
-+                goto err;
-+            if (!BN_nnmod(mod, scalar[i], group->order, ctx)) {
-+                ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL, ERR_R_BN_LIB);
-+                goto err;
-+            }
-+            scalars[i] = mod;
-+        } else
-+            scalars[i] = scalar[i];
-+
-+        for (j = 0; j < bn_get_top(scalars[i]) * BN_BYTES; j += BN_BYTES) {
-+            BN_ULONG d = bn_get_words(scalars[i])[j / BN_BYTES];
-+
-+            p_str[i][j + 0] = (unsigned char)d;
-+            p_str[i][j + 1] = (unsigned char)(d >> 8);
-+            p_str[i][j + 2] = (unsigned char)(d >> 16);
-+            p_str[i][j + 3] = (unsigned char)(d >>= 24);
-+            if (BN_BYTES == 8) {
-+                d >>= 8;
-+                p_str[i][j + 4] = (unsigned char)d;
-+                p_str[i][j + 5] = (unsigned char)(d >> 8);
-+                p_str[i][j + 6] = (unsigned char)(d >> 16);
-+                p_str[i][j + 7] = (unsigned char)(d >> 24);
-+            }
-+        }
-+        for (; j < 33; j++)
-+            p_str[i][j] = 0;
-+
-+        if (!ecp_nistz256_bignum_to_field_elem(temp[0].X, point[i]->X)
-+            || !ecp_nistz256_bignum_to_field_elem(temp[0].Y, point[i]->Y)
-+            || !ecp_nistz256_bignum_to_field_elem(temp[0].Z, point[i]->Z)) {
-+            ECerr(EC_F_ECP_NISTZ256_WINDOWED_MUL,
-+                  EC_R_COORDINATES_OUT_OF_RANGE);
-+            goto err;
-+        }
-+
-+        /*
-+         * row[0] is implicitly (0,0,0) (the point at infinity), therefore it
-+         * is not stored. All other values are actually stored with an offset
-+         * of -1 in table.
-+         */
-+
-+        ecp_nistz256_scatter_w5  (row, &temp[0], 1);
-+        ecp_nistz256_point_double(&temp[1], &temp[0]);              /*1+1=2  */
-+        ecp_nistz256_scatter_w5  (row, &temp[1], 2);
-+        ecp_nistz256_point_add   (&temp[2], &temp[1], &temp[0]);    /*2+1=3  */
-+        ecp_nistz256_scatter_w5  (row, &temp[2], 3);
-+        ecp_nistz256_point_double(&temp[1], &temp[1]);              /*2*2=4  */
-+        ecp_nistz256_scatter_w5  (row, &temp[1], 4);
-+        ecp_nistz256_point_double(&temp[2], &temp[2]);              /*2*3=6  */
-+        ecp_nistz256_scatter_w5  (row, &temp[2], 6);
-+        ecp_nistz256_point_add   (&temp[3], &temp[1], &temp[0]);    /*4+1=5  */
-+        ecp_nistz256_scatter_w5  (row, &temp[3], 5);
-+        ecp_nistz256_point_add   (&temp[4], &temp[2], &temp[0]);    /*6+1=7  */
-+        ecp_nistz256_scatter_w5  (row, &temp[4], 7);
-+        ecp_nistz256_point_double(&temp[1], &temp[1]);              /*2*4=8  */
-+        ecp_nistz256_scatter_w5  (row, &temp[1], 8);
-+        ecp_nistz256_point_double(&temp[2], &temp[2]);              /*2*6=12 */
-+        ecp_nistz256_scatter_w5  (row, &temp[2], 12);
-+        ecp_nistz256_point_double(&temp[3], &temp[3]);              /*2*5=10 */
-+        ecp_nistz256_scatter_w5  (row, &temp[3], 10);
-+        ecp_nistz256_point_double(&temp[4], &temp[4]);              /*2*7=14 */
-+        ecp_nistz256_scatter_w5  (row, &temp[4], 14);
-+        ecp_nistz256_point_add   (&temp[2], &temp[2], &temp[0]);    /*12+1=13*/
-+        ecp_nistz256_scatter_w5  (row, &temp[2], 13);
-+        ecp_nistz256_point_add   (&temp[3], &temp[3], &temp[0]);    /*10+1=11*/
-+        ecp_nistz256_scatter_w5  (row, &temp[3], 11);
-+        ecp_nistz256_point_add   (&temp[4], &temp[4], &temp[0]);    /*14+1=15*/
-+        ecp_nistz256_scatter_w5  (row, &temp[4], 15);
-+        ecp_nistz256_point_add   (&temp[2], &temp[1], &temp[0]);    /*8+1=9  */
-+        ecp_nistz256_scatter_w5  (row, &temp[2], 9);
-+        ecp_nistz256_point_double(&temp[1], &temp[1]);              /*2*8=16 */
-+        ecp_nistz256_scatter_w5  (row, &temp[1], 16);
-+    }
-+
-+    idx = 255;
-+
-+    wvalue = p_str[0][(idx - 1) / 8];
-+    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+
-+    /*
-+     * We gather to temp[0], because we know it's position relative
-+     * to table
-+     */
-+    ecp_nistz256_gather_w5(&temp[0], table[0], _booth_recode_w5(wvalue) >> 1);
-+    memcpy(r, &temp[0], sizeof(temp[0]));
-+
-+    while (idx >= 5) {
-+        for (i = (idx == 255 ? 1 : 0); i < num; i++) {
-+            unsigned int off = (idx - 1) / 8;
-+
-+            wvalue = p_str[i][off] | p_str[i][off + 1] << 8;
-+            wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+
-+            wvalue = _booth_recode_w5(wvalue);
-+
-+            ecp_nistz256_gather_w5(&temp[0], table[i], wvalue >> 1);
-+
-+            ecp_nistz256_neg(temp[1].Y, temp[0].Y);
-+            copy_conditional(temp[0].Y, temp[1].Y, (wvalue & 1));
-+
-+            ecp_nistz256_point_add(r, r, &temp[0]);
-+        }
-+
-+        idx -= window_size;
-+
-+        ecp_nistz256_point_double(r, r);
-+        ecp_nistz256_point_double(r, r);
-+        ecp_nistz256_point_double(r, r);
-+        ecp_nistz256_point_double(r, r);
-+        ecp_nistz256_point_double(r, r);
-+    }
-+
-+    /* Final window */
-+    for (i = 0; i < num; i++) {
-+        wvalue = p_str[i][0];
-+        wvalue = (wvalue << 1) & mask;
-+
-+        wvalue = _booth_recode_w5(wvalue);
-+
-+        ecp_nistz256_gather_w5(&temp[0], table[i], wvalue >> 1);
-+
-+        ecp_nistz256_neg(temp[1].Y, temp[0].Y);
-+        copy_conditional(temp[0].Y, temp[1].Y, wvalue & 1);
-+
-+        ecp_nistz256_point_add(r, r, &temp[0]);
-+    }
-+
-+    ret = 1;
-+ err:
-+    OPENSSL_free(table_storage);
-+    OPENSSL_free(p_str);
-+    OPENSSL_free(scalars);
-+    return ret;
-+}
-+
-+/* Coordinates of G, for which we have precomputed tables */
-+const static BN_ULONG def_xG[P256_LIMBS] = {
-+    TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601),
-+    TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6)
-+};
-+
-+const static BN_ULONG def_yG[P256_LIMBS] = {
-+    TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c),
-+    TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85)
-+};
-+
-+/*
-+ * ecp_nistz256_is_affine_G returns one if |generator| is the standard, P-256
-+ * generator.
-+ */
-+static int ecp_nistz256_is_affine_G(const EC_POINT *generator)
-+{
-+    return (bn_get_top(generator->X) == P256_LIMBS) &&
-+        (bn_get_top(generator->Y) == P256_LIMBS) &&
-+        is_equal(bn_get_words(generator->X), def_xG) &&
-+        is_equal(bn_get_words(generator->Y), def_yG) &&
-+        is_one(generator->Z);
-+}
-+
-+__owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
-+{
-+    /*
-+     * We precompute a table for a Booth encoded exponent (wNAF) based
-+     * computation. Each table holds 64 values for safe access, with an
-+     * implicit value of infinity at index zero. We use window of size 7, and
-+     * therefore require ceil(256/7) = 37 tables.
-+     */
-+    const BIGNUM *order;
-+    EC_POINT *P = NULL, *T = NULL;
-+    const EC_POINT *generator;
-+    NISTZ256_PRE_COMP *pre_comp;
-+    BN_CTX *new_ctx = NULL;
-+    int i, j, k, ret = 0;
-+    size_t w;
-+
-+    PRECOMP256_ROW *preComputedTable = NULL;
-+    unsigned char *precomp_storage = NULL;
-+
-+    /* if there is an old NISTZ256_PRE_COMP object, throw it away */
-+    EC_pre_comp_free(group);
-+    generator = EC_GROUP_get0_generator(group);
-+    if (generator == NULL) {
-+        ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, EC_R_UNDEFINED_GENERATOR);
-+        return 0;
-+    }
-+
-+    if (ecp_nistz256_is_affine_G(generator)) {
-+        /*
-+         * No need to calculate tables for the standard generator because we
-+         * have them statically.
-+         */
-+        return 1;
-+    }
-+
-+    if ((pre_comp = ecp_nistz256_pre_comp_new(group)) == NULL)
-+        return 0;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            goto err;
-+    }
-+
-+    BN_CTX_start(ctx);
-+
-+    order = EC_GROUP_get0_order(group);
-+    if (order == NULL)
-+        goto err;
-+
-+    if (BN_is_zero(order)) {
-+        ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, EC_R_UNKNOWN_ORDER);
-+        goto err;
-+    }
-+
-+    w = 7;
-+
-+    if ((precomp_storage =
-+         OPENSSL_malloc(37 * 64 * sizeof(P256_POINT_AFFINE) + 64)) == NULL) {
-+        ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    preComputedTable = (void *)ALIGNPTR(precomp_storage, 64);
-+
-+    P = EC_POINT_new(group);
-+    T = EC_POINT_new(group);
-+    if (P == NULL || T == NULL)
-+        goto err;
-+
-+    /*
-+     * The zero entry is implicitly infinity, and we skip it, storing other
-+     * values with -1 offset.
-+     */
-+    if (!EC_POINT_copy(T, generator))
-+        goto err;
-+
-+    for (k = 0; k < 64; k++) {
-+        if (!EC_POINT_copy(P, T))
-+            goto err;
-+        for (j = 0; j < 37; j++) {
-+            P256_POINT_AFFINE temp;
-+            /*
-+             * It would be faster to use EC_POINTs_make_affine and
-+             * make multiple points affine at the same time.
-+             */
-+            if (!EC_POINT_make_affine(group, P, ctx))
-+                goto err;
-+            if (!ecp_nistz256_bignum_to_field_elem(temp.X, P->X) ||
-+                !ecp_nistz256_bignum_to_field_elem(temp.Y, P->Y)) {
-+                ECerr(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE,
-+                      EC_R_COORDINATES_OUT_OF_RANGE);
-+                goto err;
-+            }
-+            ecp_nistz256_scatter_w7(preComputedTable[j], &temp, k);
-+            for (i = 0; i < 7; i++) {
-+                if (!EC_POINT_dbl(group, P, P, ctx))
-+                    goto err;
-+            }
-+        }
-+        if (!EC_POINT_add(group, T, T, generator, ctx))
-+            goto err;
-+    }
-+
-+    pre_comp->group = group;
-+    pre_comp->w = w;
-+    pre_comp->precomp = preComputedTable;
-+    pre_comp->precomp_storage = precomp_storage;
-+    precomp_storage = NULL;
-+    SETPRECOMP(group, nistz256, pre_comp);
-+    pre_comp = NULL;
-+    ret = 1;
-+
-+ err:
-+    if (ctx != NULL)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+
-+    EC_nistz256_pre_comp_free(pre_comp);
-+    OPENSSL_free(precomp_storage);
-+    EC_POINT_free(P);
-+    EC_POINT_free(T);
-+    return ret;
-+}
-+
-+/*
-+ * Note that by default ECP_NISTZ256_AVX2 is undefined. While it's great
-+ * code processing 4 points in parallel, corresponding serial operation
-+ * is several times slower, because it uses 29x29=58-bit multiplication
-+ * as opposite to 64x64=128-bit in integer-only scalar case. As result
-+ * it doesn't provide *significant* performance improvement. Note that
-+ * just defining ECP_NISTZ256_AVX2 is not sufficient to make it work,
-+ * you'd need to compile even asm/ecp_nistz256-avx.pl module.
-+ */
-+#if defined(ECP_NISTZ256_AVX2)
-+# if !(defined(__x86_64) || defined(__x86_64__) || \
-+       defined(_M_AMD64) || defined(_MX64)) || \
-+     !(defined(__GNUC__) || defined(_MSC_VER)) /* this is for ALIGN32 */
-+#  undef ECP_NISTZ256_AVX2
-+# else
-+/* Constant time access, loading four values, from four consecutive tables */
-+void ecp_nistz256_avx2_multi_gather_w7(void *result, const void *in,
-+                                       int index0, int index1, int index2,
-+                                       int index3);
-+void ecp_nistz256_avx2_transpose_convert(void *RESULTx4, const void *in);
-+void ecp_nistz256_avx2_convert_transpose_back(void *result, const void *Ax4);
-+void ecp_nistz256_avx2_point_add_affine_x4(void *RESULTx4, const void *Ax4,
-+                                           const void *Bx4);
-+void ecp_nistz256_avx2_point_add_affines_x4(void *RESULTx4, const void *Ax4,
-+                                            const void *Bx4);
-+void ecp_nistz256_avx2_to_mont(void *RESULTx4, const void *Ax4);
-+void ecp_nistz256_avx2_from_mont(void *RESULTx4, const void *Ax4);
-+void ecp_nistz256_avx2_set1(void *RESULTx4);
-+int ecp_nistz_avx2_eligible(void);
-+
-+static void booth_recode_w7(unsigned char *sign,
-+                            unsigned char *digit, unsigned char in)
-+{
-+    unsigned char s, d;
-+
-+    s = ~((in >> 7) - 1);
-+    d = (1 << 8) - in - 1;
-+    d = (d & s) | (in & ~s);
-+    d = (d >> 1) + (d & 1);
-+
-+    *sign = s & 1;
-+    *digit = d;
-+}
-+
-+/*
-+ * ecp_nistz256_avx2_mul_g performs multiplication by G, using only the
-+ * precomputed table. It does 4 affine point additions in parallel,
-+ * significantly speeding up point multiplication for a fixed value.
-+ */
-+static void ecp_nistz256_avx2_mul_g(P256_POINT *r,
-+                                    unsigned char p_str[33],
-+                                    const P256_POINT_AFFINE(*preComputedTable)[64])
-+{
-+    const unsigned int window_size = 7;
-+    const unsigned int mask = (1 << (window_size + 1)) - 1;
-+    unsigned int wvalue;
-+    /* Using 4 windows at a time */
-+    unsigned char sign0, digit0;
-+    unsigned char sign1, digit1;
-+    unsigned char sign2, digit2;
-+    unsigned char sign3, digit3;
-+    unsigned int idx = 0;
-+    BN_ULONG tmp[P256_LIMBS];
-+    int i;
-+
-+    ALIGN32 BN_ULONG aX4[4 * 9 * 3] = { 0 };
-+    ALIGN32 BN_ULONG bX4[4 * 9 * 2] = { 0 };
-+    ALIGN32 P256_POINT_AFFINE point_arr[4];
-+    ALIGN32 P256_POINT res_point_arr[4];
-+
-+    /* Initial four windows */
-+    wvalue = *((u16 *) & p_str[0]);
-+    wvalue = (wvalue << 1) & mask;
-+    idx += window_size;
-+    booth_recode_w7(&sign0, &digit0, wvalue);
-+    wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+    idx += window_size;
-+    booth_recode_w7(&sign1, &digit1, wvalue);
-+    wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+    idx += window_size;
-+    booth_recode_w7(&sign2, &digit2, wvalue);
-+    wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+    idx += window_size;
-+    booth_recode_w7(&sign3, &digit3, wvalue);
-+
-+    ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[0],
-+                                      digit0, digit1, digit2, digit3);
-+
-+    ecp_nistz256_neg(tmp, point_arr[0].Y);
-+    copy_conditional(point_arr[0].Y, tmp, sign0);
-+    ecp_nistz256_neg(tmp, point_arr[1].Y);
-+    copy_conditional(point_arr[1].Y, tmp, sign1);
-+    ecp_nistz256_neg(tmp, point_arr[2].Y);
-+    copy_conditional(point_arr[2].Y, tmp, sign2);
-+    ecp_nistz256_neg(tmp, point_arr[3].Y);
-+    copy_conditional(point_arr[3].Y, tmp, sign3);
-+
-+    ecp_nistz256_avx2_transpose_convert(aX4, point_arr);
-+    ecp_nistz256_avx2_to_mont(aX4, aX4);
-+    ecp_nistz256_avx2_to_mont(&aX4[4 * 9], &aX4[4 * 9]);
-+    ecp_nistz256_avx2_set1(&aX4[4 * 9 * 2]);
-+
-+    wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+    idx += window_size;
-+    booth_recode_w7(&sign0, &digit0, wvalue);
-+    wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+    idx += window_size;
-+    booth_recode_w7(&sign1, &digit1, wvalue);
-+    wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+    idx += window_size;
-+    booth_recode_w7(&sign2, &digit2, wvalue);
-+    wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+    idx += window_size;
-+    booth_recode_w7(&sign3, &digit3, wvalue);
-+
-+    ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[4 * 1],
-+                                      digit0, digit1, digit2, digit3);
-+
-+    ecp_nistz256_neg(tmp, point_arr[0].Y);
-+    copy_conditional(point_arr[0].Y, tmp, sign0);
-+    ecp_nistz256_neg(tmp, point_arr[1].Y);
-+    copy_conditional(point_arr[1].Y, tmp, sign1);
-+    ecp_nistz256_neg(tmp, point_arr[2].Y);
-+    copy_conditional(point_arr[2].Y, tmp, sign2);
-+    ecp_nistz256_neg(tmp, point_arr[3].Y);
-+    copy_conditional(point_arr[3].Y, tmp, sign3);
-+
-+    ecp_nistz256_avx2_transpose_convert(bX4, point_arr);
-+    ecp_nistz256_avx2_to_mont(bX4, bX4);
-+    ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]);
-+    /* Optimized when both inputs are affine */
-+    ecp_nistz256_avx2_point_add_affines_x4(aX4, aX4, bX4);
-+
-+    for (i = 2; i < 9; i++) {
-+        wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+        wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+        idx += window_size;
-+        booth_recode_w7(&sign0, &digit0, wvalue);
-+        wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+        wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+        idx += window_size;
-+        booth_recode_w7(&sign1, &digit1, wvalue);
-+        wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+        wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+        idx += window_size;
-+        booth_recode_w7(&sign2, &digit2, wvalue);
-+        wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+        wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+        idx += window_size;
-+        booth_recode_w7(&sign3, &digit3, wvalue);
-+
-+        ecp_nistz256_avx2_multi_gather_w7(point_arr,
-+                                          preComputedTable[4 * i],
-+                                          digit0, digit1, digit2, digit3);
-+
-+        ecp_nistz256_neg(tmp, point_arr[0].Y);
-+        copy_conditional(point_arr[0].Y, tmp, sign0);
-+        ecp_nistz256_neg(tmp, point_arr[1].Y);
-+        copy_conditional(point_arr[1].Y, tmp, sign1);
-+        ecp_nistz256_neg(tmp, point_arr[2].Y);
-+        copy_conditional(point_arr[2].Y, tmp, sign2);
-+        ecp_nistz256_neg(tmp, point_arr[3].Y);
-+        copy_conditional(point_arr[3].Y, tmp, sign3);
-+
-+        ecp_nistz256_avx2_transpose_convert(bX4, point_arr);
-+        ecp_nistz256_avx2_to_mont(bX4, bX4);
-+        ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]);
-+
-+        ecp_nistz256_avx2_point_add_affine_x4(aX4, aX4, bX4);
-+    }
-+
-+    ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 0], &aX4[4 * 9 * 0]);
-+    ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 1], &aX4[4 * 9 * 1]);
-+    ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 2], &aX4[4 * 9 * 2]);
-+
-+    ecp_nistz256_avx2_convert_transpose_back(res_point_arr, aX4);
-+    /* Last window is performed serially */
-+    wvalue = *((u16 *) & p_str[(idx - 1) / 8]);
-+    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+    booth_recode_w7(&sign0, &digit0, wvalue);
-+    ecp_nistz256_gather_w7((P256_POINT_AFFINE *)r,
-+                           preComputedTable[36], digit0);
-+    ecp_nistz256_neg(tmp, r->Y);
-+    copy_conditional(r->Y, tmp, sign0);
-+    memcpy(r->Z, ONE, sizeof(ONE));
-+    /* Sum the four windows */
-+    ecp_nistz256_point_add(r, r, &res_point_arr[0]);
-+    ecp_nistz256_point_add(r, r, &res_point_arr[1]);
-+    ecp_nistz256_point_add(r, r, &res_point_arr[2]);
-+    ecp_nistz256_point_add(r, r, &res_point_arr[3]);
-+}
-+# endif
-+#endif
-+
-+__owur static int ecp_nistz256_set_from_affine(EC_POINT *out, const EC_GROUP *group,
-+                                               const P256_POINT_AFFINE *in,
-+                                               BN_CTX *ctx)
-+{
-+    BIGNUM *x, *y;
-+    BN_ULONG d_x[P256_LIMBS], d_y[P256_LIMBS];
-+    int ret = 0;
-+
-+    x = BN_new();
-+    if (x == NULL)
-+        return 0;
-+    y = BN_new();
-+    if (y == NULL) {
-+        BN_free(x);
-+        return 0;
-+    }
-+    memcpy(d_x, in->X, sizeof(d_x));
-+    bn_set_static_words(x, d_x, P256_LIMBS);
-+
-+    memcpy(d_y, in->Y, sizeof(d_y));
-+    bn_set_static_words(y, d_y, P256_LIMBS);
-+
-+    ret = EC_POINT_set_affine_coordinates_GFp(group, out, x, y, ctx);
-+
-+    BN_free(x);
-+    BN_free(y);
-+
-+    return ret;
-+}
-+
-+/* r = scalar*G + sum(scalars[i]*points[i]) */
-+__owur static int ecp_nistz256_points_mul(const EC_GROUP *group,
-+                                          EC_POINT *r,
-+                                          const BIGNUM *scalar,
-+                                          size_t num,
-+                                          const EC_POINT *points[],
-+                                          const BIGNUM *scalars[], BN_CTX *ctx)
-+{
-+    int i = 0, ret = 0, no_precomp_for_generator = 0, p_is_infinity = 0;
-+    size_t j;
-+    unsigned char p_str[33] = { 0 };
-+    const PRECOMP256_ROW *preComputedTable = NULL;
-+    const NISTZ256_PRE_COMP *pre_comp = NULL;
-+    const EC_POINT *generator = NULL;
-+    BN_CTX *new_ctx = NULL;
-+    const BIGNUM **new_scalars = NULL;
-+    const EC_POINT **new_points = NULL;
-+    unsigned int idx = 0;
-+    const unsigned int window_size = 7;
-+    const unsigned int mask = (1 << (window_size + 1)) - 1;
-+    unsigned int wvalue;
-+    ALIGN32 union {
-+        P256_POINT p;
-+        P256_POINT_AFFINE a;
-+    } t, p;
-+    BIGNUM *tmp_scalar;
-+
-+    if ((num + 1) == 0 || (num + 1) > OPENSSL_MALLOC_MAX_NELEMS(void *)) {
-+        ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    if (group->meth != r->meth) {
-+        ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
-+        return 0;
-+    }
-+
-+    if ((scalar == NULL) && (num == 0))
-+        return EC_POINT_set_to_infinity(group, r);
-+
-+    for (j = 0; j < num; j++) {
-+        if (group->meth != points[j]->meth) {
-+            ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
-+            return 0;
-+        }
-+    }
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            goto err;
-+    }
-+
-+    BN_CTX_start(ctx);
-+
-+    if (scalar) {
-+        generator = EC_GROUP_get0_generator(group);
-+        if (generator == NULL) {
-+            ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_UNDEFINED_GENERATOR);
-+            goto err;
-+        }
-+
-+        /* look if we can use precomputed multiples of generator */
-+        pre_comp = group->pre_comp.nistz256;
-+
-+        if (pre_comp) {
-+            /*
-+             * If there is a precomputed table for the generator, check that
-+             * it was generated with the same generator.
-+             */
-+            EC_POINT *pre_comp_generator = EC_POINT_new(group);
-+            if (pre_comp_generator == NULL)
-+                goto err;
-+
-+            if (!ecp_nistz256_set_from_affine(pre_comp_generator,
-+                                              group, pre_comp->precomp[0],
-+                                              ctx)) {
-+                EC_POINT_free(pre_comp_generator);
-+                goto err;
-+            }
-+
-+            if (0 == EC_POINT_cmp(group, generator, pre_comp_generator, ctx))
-+                preComputedTable = (const PRECOMP256_ROW *)pre_comp->precomp;
-+
-+            EC_POINT_free(pre_comp_generator);
-+        }
-+
-+        if (preComputedTable == NULL && ecp_nistz256_is_affine_G(generator)) {
-+            /*
-+             * If there is no precomputed data, but the generator is the
-+             * default, a hardcoded table of precomputed data is used. This
-+             * is because applications, such as Apache, do not use
-+             * EC_KEY_precompute_mult.
-+             */
-+            preComputedTable = ecp_nistz256_precomputed;
-+        }
-+
-+        if (preComputedTable) {
-+            if ((BN_num_bits(scalar) > 256)
-+                || BN_is_negative(scalar)) {
-+                if ((tmp_scalar = BN_CTX_get(ctx)) == NULL)
-+                    goto err;
-+
-+                if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
-+                    ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_BN_LIB);
-+                    goto err;
-+                }
-+                scalar = tmp_scalar;
-+            }
-+
-+            for (i = 0; i < bn_get_top(scalar) * BN_BYTES; i += BN_BYTES) {
-+                BN_ULONG d = bn_get_words(scalar)[i / BN_BYTES];
-+
-+                p_str[i + 0] = (unsigned char)d;
-+                p_str[i + 1] = (unsigned char)(d >> 8);
-+                p_str[i + 2] = (unsigned char)(d >> 16);
-+                p_str[i + 3] = (unsigned char)(d >>= 24);
-+                if (BN_BYTES == 8) {
-+                    d >>= 8;
-+                    p_str[i + 4] = (unsigned char)d;
-+                    p_str[i + 5] = (unsigned char)(d >> 8);
-+                    p_str[i + 6] = (unsigned char)(d >> 16);
-+                    p_str[i + 7] = (unsigned char)(d >> 24);
-+                }
-+            }
-+
-+            for (; i < 33; i++)
-+                p_str[i] = 0;
-+
-+#if defined(ECP_NISTZ256_AVX2)
-+            if (ecp_nistz_avx2_eligible()) {
-+                ecp_nistz256_avx2_mul_g(&p.p, p_str, preComputedTable);
-+            } else
-+#endif
-+            {
-+                BN_ULONG infty;
-+
-+                /* First window */
-+                wvalue = (p_str[0] << 1) & mask;
-+                idx += window_size;
-+
-+                wvalue = _booth_recode_w7(wvalue);
-+
-+                ecp_nistz256_gather_w7(&p.a, preComputedTable[0],
-+                                       wvalue >> 1);
-+
-+                ecp_nistz256_neg(p.p.Z, p.p.Y);
-+                copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
-+
-+                /*
-+                 * Since affine infinity is encoded as (0,0) and
-+                 * Jacobian ias (,,0), we need to harmonize them
-+                 * by assigning "one" or zero to Z.
-+                 */
-+                infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] |
-+                         p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]);
-+                if (P256_LIMBS == 8)
-+                    infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] |
-+                              p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]);
-+
-+                infty = 0 - is_zero(infty);
-+                infty = ~infty;
-+
-+                p.p.Z[0] = ONE[0] & infty;
-+                p.p.Z[1] = ONE[1] & infty;
-+                p.p.Z[2] = ONE[2] & infty;
-+                p.p.Z[3] = ONE[3] & infty;
-+                if (P256_LIMBS == 8) {
-+                    p.p.Z[4] = ONE[4] & infty;
-+                    p.p.Z[5] = ONE[5] & infty;
-+                    p.p.Z[6] = ONE[6] & infty;
-+                    p.p.Z[7] = ONE[7] & infty;
-+                }
-+
-+                for (i = 1; i < 37; i++) {
-+                    unsigned int off = (idx - 1) / 8;
-+                    wvalue = p_str[off] | p_str[off + 1] << 8;
-+                    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;
-+                    idx += window_size;
-+
-+                    wvalue = _booth_recode_w7(wvalue);
-+
-+                    ecp_nistz256_gather_w7(&t.a,
-+                                           preComputedTable[i], wvalue >> 1);
-+
-+                    ecp_nistz256_neg(t.p.Z, t.a.Y);
-+                    copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
-+
-+                    ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
-+                }
-+            }
-+        } else {
-+            p_is_infinity = 1;
-+            no_precomp_for_generator = 1;
-+        }
-+    } else
-+        p_is_infinity = 1;
-+
-+    if (no_precomp_for_generator) {
-+        /*
-+         * Without a precomputed table for the generator, it has to be
-+         * handled like a normal point.
-+         */
-+        new_scalars = OPENSSL_malloc((num + 1) * sizeof(BIGNUM *));
-+        if (new_scalars == NULL) {
-+            ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+
-+        new_points = OPENSSL_malloc((num + 1) * sizeof(EC_POINT *));
-+        if (new_points == NULL) {
-+            ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+
-+        memcpy(new_scalars, scalars, num * sizeof(BIGNUM *));
-+        new_scalars[num] = scalar;
-+        memcpy(new_points, points, num * sizeof(EC_POINT *));
-+        new_points[num] = generator;
-+
-+        scalars = new_scalars;
-+        points = new_points;
-+        num++;
-+    }
-+
-+    if (num) {
-+        P256_POINT *out = &t.p;
-+        if (p_is_infinity)
-+            out = &p.p;
-+
-+        if (!ecp_nistz256_windowed_mul(group, out, scalars, points, num, ctx))
-+            goto err;
-+
-+        if (!p_is_infinity)
-+            ecp_nistz256_point_add(&p.p, &p.p, out);
-+    }
-+
-+    /* Not constant-time, but we're only operating on the public output. */
-+    if (!bn_set_words(r->X, p.p.X, P256_LIMBS) ||
-+        !bn_set_words(r->Y, p.p.Y, P256_LIMBS) ||
-+        !bn_set_words(r->Z, p.p.Z, P256_LIMBS)) {
-+        goto err;
-+    }
-+    r->Z_is_one = is_one(r->Z) & 1;
-+
-+    ret = 1;
-+
-+err:
-+    if (ctx)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    OPENSSL_free(new_points);
-+    OPENSSL_free(new_scalars);
-+    return ret;
-+}
-+
-+__owur static int ecp_nistz256_get_affine(const EC_GROUP *group,
-+                                          const EC_POINT *point,
-+                                          BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
-+{
-+    BN_ULONG z_inv2[P256_LIMBS];
-+    BN_ULONG z_inv3[P256_LIMBS];
-+    BN_ULONG x_aff[P256_LIMBS];
-+    BN_ULONG y_aff[P256_LIMBS];
-+    BN_ULONG point_x[P256_LIMBS], point_y[P256_LIMBS], point_z[P256_LIMBS];
-+    BN_ULONG x_ret[P256_LIMBS], y_ret[P256_LIMBS];
-+
-+    if (EC_POINT_is_at_infinity(group, point)) {
-+        ECerr(EC_F_ECP_NISTZ256_GET_AFFINE, EC_R_POINT_AT_INFINITY);
-+        return 0;
-+    }
-+
-+    if (!ecp_nistz256_bignum_to_field_elem(point_x, point->X) ||
-+        !ecp_nistz256_bignum_to_field_elem(point_y, point->Y) ||
-+        !ecp_nistz256_bignum_to_field_elem(point_z, point->Z)) {
-+        ECerr(EC_F_ECP_NISTZ256_GET_AFFINE, EC_R_COORDINATES_OUT_OF_RANGE);
-+        return 0;
-+    }
-+
-+    ecp_nistz256_mod_inverse(z_inv3, point_z);
-+    ecp_nistz256_sqr_mont(z_inv2, z_inv3);
-+    ecp_nistz256_mul_mont(x_aff, z_inv2, point_x);
-+
-+    if (x != NULL) {
-+        ecp_nistz256_from_mont(x_ret, x_aff);
-+        if (!bn_set_words(x, x_ret, P256_LIMBS))
-+            return 0;
-+    }
-+
-+    if (y != NULL) {
-+        ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2);
-+        ecp_nistz256_mul_mont(y_aff, z_inv3, point_y);
-+        ecp_nistz256_from_mont(y_ret, y_aff);
-+        if (!bn_set_words(y, y_ret, P256_LIMBS))
-+            return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group)
-+{
-+    NISTZ256_PRE_COMP *ret = NULL;
-+
-+    if (!group)
-+        return NULL;
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        ECerr(EC_F_ECP_NISTZ256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
-+        return ret;
-+    }
-+
-+    ret->group = group;
-+    ret->w = 6;                 /* default */
-+    ret->references = 1;
-+
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        ECerr(EC_F_ECP_NISTZ256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *p)
-+{
-+    int i;
-+    if (p != NULL)
-+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
-+    return p;
-+}
-+
-+void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *pre)
-+{
-+    int i;
-+
-+    if (pre == NULL)
-+        return;
-+
-+    CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
-+    REF_PRINT_COUNT("EC_nistz256", x);
-+    if (i > 0)
-+        return;
-+    REF_ASSERT_ISNT(i < 0);
-+
-+    OPENSSL_free(pre->precomp_storage);
-+    CRYPTO_THREAD_lock_free(pre->lock);
-+    OPENSSL_free(pre);
-+}
-+
-+
-+static int ecp_nistz256_window_have_precompute_mult(const EC_GROUP *group)
-+{
-+    /* There is a hard-coded table for the default generator. */
-+    const EC_POINT *generator = EC_GROUP_get0_generator(group);
-+
-+    if (generator != NULL && ecp_nistz256_is_affine_G(generator)) {
-+        /* There is a hard-coded table for the default generator. */
-+        return 1;
-+    }
-+
-+    return HAVEPRECOMP(group, nistz256);
-+}
-+
-+const EC_METHOD *EC_GFp_nistz256_method(void)
-+{
-+    static const EC_METHOD ret = {
-+        EC_FLAGS_DEFAULT_OCT,
-+        NID_X9_62_prime_field,
-+        ec_GFp_mont_group_init,
-+        ec_GFp_mont_group_finish,
-+        ec_GFp_mont_group_clear_finish,
-+        ec_GFp_mont_group_copy,
-+        ec_GFp_mont_group_set_curve,
-+        ec_GFp_simple_group_get_curve,
-+        ec_GFp_simple_group_get_degree,
-+        ec_group_simple_order_bits,
-+        ec_GFp_simple_group_check_discriminant,
-+        ec_GFp_simple_point_init,
-+        ec_GFp_simple_point_finish,
-+        ec_GFp_simple_point_clear_finish,
-+        ec_GFp_simple_point_copy,
-+        ec_GFp_simple_point_set_to_infinity,
-+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_point_set_affine_coordinates,
-+        ecp_nistz256_get_affine,
-+        0, 0, 0,
-+        ec_GFp_simple_add,
-+        ec_GFp_simple_dbl,
-+        ec_GFp_simple_invert,
-+        ec_GFp_simple_is_at_infinity,
-+        ec_GFp_simple_is_on_curve,
-+        ec_GFp_simple_cmp,
-+        ec_GFp_simple_make_affine,
-+        ec_GFp_simple_points_make_affine,
-+        ecp_nistz256_points_mul,                    /* mul */
-+        ecp_nistz256_mult_precompute,               /* precompute_mult */
-+        ecp_nistz256_window_have_precompute_mult,   /* have_precompute_mult */
-+        ec_GFp_mont_field_mul,
-+        ec_GFp_mont_field_sqr,
-+        0,                                          /* field_div */
-+        ec_GFp_mont_field_encode,
-+        ec_GFp_mont_field_decode,
-+        ec_GFp_mont_field_set_to_one,
-+        ec_key_simple_priv2oct,
-+        ec_key_simple_oct2priv,
-+        0, /* set private */
-+        ec_key_simple_generate_key,
-+        ec_key_simple_check_key,
-+        ec_key_simple_generate_public_key,
-+        0, /* keycopy */
-+        0, /* keyfinish */
-+        ecdh_simple_compute_key
-+    };
-+
-+    return &ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistz256_table.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistz256_table.c
-new file mode 100644
-index 0000000..3f5625c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_nistz256_table.c
-@@ -0,0 +1,9542 @@
-+/*
-+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * This is the precomputed constant time access table for the code in
-+ * ecp_montp256.c, for the default generator. The table consists of 37
-+ * subtables, each subtable contains 64 affine points. The affine points are
-+ * encoded as eight uint64's, four for the x coordinate and four for the y.
-+ * Both values are in little-endian order. There are 37 tables because a
-+ * signed, 6-bit wNAF form of the scalar is used and ceil(256/(6 + 1)) = 37.
-+ * Within each table there are 64 values because the 6-bit wNAF value can
-+ * take 64 values, ignoring the sign bit, which is implemented by performing
-+ * a negation of the affine point when required. We would like to align it
-+ * to 2MB in order to increase the chances of using a large page but that
-+ * appears to lead to invalid ELF files being produced.
-+ */
-+
-+#if defined(__GNUC__)
-+__attribute((aligned(4096)))
-+#elif defined(_MSC_VER)
-+__declspec(align(4096))
-+#elif defined(__SUNPRO_C)
-+# pragma align 4096(ecp_nistz256_precomputed)
-+#endif
-+static const BN_ULONG ecp_nistz256_precomputed[37][64 *
-+                                                   sizeof(P256_POINT_AFFINE) /
-+                                                   sizeof(BN_ULONG)] = {
-+    {TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601),
-+     TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6),
-+     TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c),
-+     TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85),
-+     TOBN(0x850046d4, 0x10ddd64d), TOBN(0xaa6ae3c1, 0xa433827d),
-+     TOBN(0x73220503, 0x8d1490d9), TOBN(0xf6bb32e4, 0x3dcf3a3b),
-+     TOBN(0x2f3648d3, 0x61bee1a5), TOBN(0x152cd7cb, 0xeb236ff8),
-+     TOBN(0x19a8fb0e, 0x92042dbe), TOBN(0x78c57751, 0x0a5b8a3b),
-+     TOBN(0xffac3f90, 0x4eebc127), TOBN(0xb027f84a, 0x087d81fb),
-+     TOBN(0x66ad77dd, 0x87cbbc98), TOBN(0x26936a3f, 0xb6ff747e),
-+     TOBN(0xb04c5c1f, 0xc983a7eb), TOBN(0x583e47ad, 0x0861fe1a),
-+     TOBN(0x78820831, 0x1a2ee98e), TOBN(0xd5f06a29, 0xe587cc07),
-+     TOBN(0x74b0b50d, 0x46918dcc), TOBN(0x4650a6ed, 0xc623c173),
-+     TOBN(0x0cdaacac, 0xe8100af2), TOBN(0x577362f5, 0x41b0176b),
-+     TOBN(0x2d96f24c, 0xe4cbaba6), TOBN(0x17628471, 0xfad6f447),
-+     TOBN(0x6b6c36de, 0xe5ddd22e), TOBN(0x84b14c39, 0x4c5ab863),
-+     TOBN(0xbe1b8aae, 0xc45c61f5), TOBN(0x90ec649a, 0x94b9537d),
-+     TOBN(0x941cb5aa, 0xd076c20c), TOBN(0xc9079605, 0x890523c8),
-+     TOBN(0xeb309b4a, 0xe7ba4f10), TOBN(0x73c568ef, 0xe5eb882b),
-+     TOBN(0x3540a987, 0x7e7a1f68), TOBN(0x73a076bb, 0x2dd1e916),
-+     TOBN(0x40394737, 0x3e77664a), TOBN(0x55ae744f, 0x346cee3e),
-+     TOBN(0xd50a961a, 0x5b17a3ad), TOBN(0x13074b59, 0x54213673),
-+     TOBN(0x93d36220, 0xd377e44b), TOBN(0x299c2b53, 0xadff14b5),
-+     TOBN(0xf424d44c, 0xef639f11), TOBN(0xa4c9916d, 0x4a07f75f),
-+     TOBN(0x0746354e, 0xa0173b4f), TOBN(0x2bd20213, 0xd23c00f7),
-+     TOBN(0xf43eaab5, 0x0c23bb08), TOBN(0x13ba5119, 0xc3123e03),
-+     TOBN(0x2847d030, 0x3f5b9d4d), TOBN(0x6742f2f2, 0x5da67bdd),
-+     TOBN(0xef933bdc, 0x77c94195), TOBN(0xeaedd915, 0x6e240867),
-+     TOBN(0x27f14cd1, 0x9499a78f), TOBN(0x462ab5c5, 0x6f9b3455),
-+     TOBN(0x8f90f02a, 0xf02cfc6b), TOBN(0xb763891e, 0xb265230d),
-+     TOBN(0xf59da3a9, 0x532d4977), TOBN(0x21e3327d, 0xcf9eba15),
-+     TOBN(0x123c7b84, 0xbe60bbf0), TOBN(0x56ec12f2, 0x7706df76),
-+     TOBN(0x75c96e8f, 0x264e20e8), TOBN(0xabe6bfed, 0x59a7a841),
-+     TOBN(0x2cc09c04, 0x44c8eb00), TOBN(0xe05b3080, 0xf0c4e16b),
-+     TOBN(0x1eb7777a, 0xa45f3314), TOBN(0x56af7bed, 0xce5d45e3),
-+     TOBN(0x2b6e019a, 0x88b12f1a), TOBN(0x086659cd, 0xfd835f9b),
-+     TOBN(0x2c18dbd1, 0x9dc21ec8), TOBN(0x98f9868a, 0x0fcf8139),
-+     TOBN(0x737d2cd6, 0x48250b49), TOBN(0xcc61c947, 0x24b3428f),
-+     TOBN(0x0c2b4078, 0x80dd9e76), TOBN(0xc43a8991, 0x383fbe08),
-+     TOBN(0x5f7d2d65, 0x779be5d2), TOBN(0x78719a54, 0xeb3b4ab5),
-+     TOBN(0xea7d260a, 0x6245e404), TOBN(0x9de40795, 0x6e7fdfe0),
-+     TOBN(0x1ff3a415, 0x8dac1ab5), TOBN(0x3e7090f1, 0x649c9073),
-+     TOBN(0x1a768561, 0x2b944e88), TOBN(0x250f939e, 0xe57f61c8),
-+     TOBN(0x0c0daa89, 0x1ead643d), TOBN(0x68930023, 0xe125b88e),
-+     TOBN(0x04b71aa7, 0xd2697768), TOBN(0xabdedef5, 0xca345a33),
-+     TOBN(0x2409d29d, 0xee37385e), TOBN(0x4ee1df77, 0xcb83e156),
-+     TOBN(0x0cac12d9, 0x1cbb5b43), TOBN(0x170ed2f6, 0xca895637),
-+     TOBN(0x28228cfa, 0x8ade6d66), TOBN(0x7ff57c95, 0x53238aca),
-+     TOBN(0xccc42563, 0x4b2ed709), TOBN(0x0e356769, 0x856fd30d),
-+     TOBN(0xbcbcd43f, 0x559e9811), TOBN(0x738477ac, 0x5395b759),
-+     TOBN(0x35752b90, 0xc00ee17f), TOBN(0x68748390, 0x742ed2e3),
-+     TOBN(0x7cd06422, 0xbd1f5bc1), TOBN(0xfbc08769, 0xc9e7b797),
-+     TOBN(0xa242a35b, 0xb0cf664a), TOBN(0x126e48f7, 0x7f9707e3),
-+     TOBN(0x1717bf54, 0xc6832660), TOBN(0xfaae7332, 0xfd12c72e),
-+     TOBN(0x27b52db7, 0x995d586b), TOBN(0xbe29569e, 0x832237c2),
-+     TOBN(0xe8e4193e, 0x2a65e7db), TOBN(0x152706dc, 0x2eaa1bbb),
-+     TOBN(0x72bcd8b7, 0xbc60055b), TOBN(0x03cc23ee, 0x56e27e4b),
-+     TOBN(0xee337424, 0xe4819370), TOBN(0xe2aa0e43, 0x0ad3da09),
-+     TOBN(0x40b8524f, 0x6383c45d), TOBN(0xd7663554, 0x42a41b25),
-+     TOBN(0x64efa6de, 0x778a4797), TOBN(0x2042170a, 0x7079adf4),
-+     TOBN(0x808b0b65, 0x0bc6fb80), TOBN(0x5882e075, 0x3ffe2e6b),
-+     TOBN(0xd5ef2f7c, 0x2c83f549), TOBN(0x54d63c80, 0x9103b723),
-+     TOBN(0xf2f11bd6, 0x52a23f9b), TOBN(0x3670c319, 0x4b0b6587),
-+     TOBN(0x55c4623b, 0xb1580e9e), TOBN(0x64edf7b2, 0x01efe220),
-+     TOBN(0x97091dcb, 0xd53c5c9d), TOBN(0xf17624b6, 0xac0a177b),
-+     TOBN(0xb0f13975, 0x2cfe2dff), TOBN(0xc1a35c0a, 0x6c7a574e),
-+     TOBN(0x227d3146, 0x93e79987), TOBN(0x0575bf30, 0xe89cb80e),
-+     TOBN(0x2f4e247f, 0x0d1883bb), TOBN(0xebd51226, 0x3274c3d0),
-+     TOBN(0x5f3e51c8, 0x56ada97a), TOBN(0x4afc964d, 0x8f8b403e),
-+     TOBN(0xa6f247ab, 0x412e2979), TOBN(0x675abd1b, 0x6f80ebda),
-+     TOBN(0x66a2bd72, 0x5e485a1d), TOBN(0x4b2a5caf, 0x8f4f0b3c),
-+     TOBN(0x2626927f, 0x1b847bba), TOBN(0x6c6fc7d9, 0x0502394d),
-+     TOBN(0xfea912ba, 0xa5659ae8), TOBN(0x68363aba, 0x25e1a16e),
-+     TOBN(0xb8842277, 0x752c41ac), TOBN(0xfe545c28, 0x2897c3fc),
-+     TOBN(0x2d36e9e7, 0xdc4c696b), TOBN(0x5806244a, 0xfba977c5),
-+     TOBN(0x85665e9b, 0xe39508c1), TOBN(0xf720ee25, 0x6d12597b),
-+     TOBN(0x8a979129, 0xd2337a31), TOBN(0x5916868f, 0x0f862bdc),
-+     TOBN(0x048099d9, 0x5dd283ba), TOBN(0xe2d1eeb6, 0xfe5bfb4e),
-+     TOBN(0x82ef1c41, 0x7884005d), TOBN(0xa2d4ec17, 0xffffcbae),
-+     TOBN(0x9161c53f, 0x8aa95e66), TOBN(0x5ee104e1, 0xc5fee0d0),
-+     TOBN(0x562e4cec, 0xc135b208), TOBN(0x74e1b265, 0x4783f47d),
-+     TOBN(0x6d2a506c, 0x5a3f3b30), TOBN(0xecead9f4, 0xc16762fc),
-+     TOBN(0xf29dd4b2, 0xe286e5b9), TOBN(0x1b0fadc0, 0x83bb3c61),
-+     TOBN(0x7a75023e, 0x7fac29a4), TOBN(0xc086d5f1, 0xc9477fa3),
-+     TOBN(0x0fc61135, 0x2f6f3076), TOBN(0xc99ffa23, 0xe3912a9a),
-+     TOBN(0x6a0b0685, 0xd2f8ba3d), TOBN(0xfdc777e8, 0xe93358a4),
-+     TOBN(0x94a787bb, 0x35415f04), TOBN(0x640c2d6a, 0x4d23fea4),
-+     TOBN(0x9de917da, 0x153a35b5), TOBN(0x793e8d07, 0x5d5cd074),
-+     TOBN(0xf4f87653, 0x2de45068), TOBN(0x37c7a7e8, 0x9e2e1f6e),
-+     TOBN(0xd0825fa2, 0xa3584069), TOBN(0xaf2cea7c, 0x1727bf42),
-+     TOBN(0x0360a4fb, 0x9e4785a9), TOBN(0xe5fda49c, 0x27299f4a),
-+     TOBN(0x48068e13, 0x71ac2f71), TOBN(0x83d0687b, 0x9077666f),
-+     TOBN(0x6d3883b2, 0x15d02819), TOBN(0x6d0d7550, 0x40dd9a35),
-+     TOBN(0x61d7cbf9, 0x1d2b469f), TOBN(0xf97b232f, 0x2efc3115),
-+     TOBN(0xa551d750, 0xb24bcbc7), TOBN(0x11ea4949, 0x88a1e356),
-+     TOBN(0x7669f031, 0x93cb7501), TOBN(0x595dc55e, 0xca737b8a),
-+     TOBN(0xa4a319ac, 0xd837879f), TOBN(0x6fc1b49e, 0xed6b67b0),
-+     TOBN(0xe3959933, 0x32f1f3af), TOBN(0x966742eb, 0x65432a2e),
-+     TOBN(0x4b8dc9fe, 0xb4966228), TOBN(0x96cc6312, 0x43f43950),
-+     TOBN(0x12068859, 0xc9b731ee), TOBN(0x7b948dc3, 0x56f79968),
-+     TOBN(0x61e4ad32, 0xed1f8008), TOBN(0xe6c9267a, 0xd8b17538),
-+     TOBN(0x1ac7c5eb, 0x857ff6fb), TOBN(0x994baaa8, 0x55f2fb10),
-+     TOBN(0x84cf14e1, 0x1d248018), TOBN(0x5a39898b, 0x628ac508),
-+     TOBN(0x14fde97b, 0x5fa944f5), TOBN(0xed178030, 0xd12e5ac7),
-+     TOBN(0x042c2af4, 0x97e2feb4), TOBN(0xd36a42d7, 0xaebf7313),
-+     TOBN(0x49d2c9eb, 0x084ffdd7), TOBN(0x9f8aa54b, 0x2ef7c76a),
-+     TOBN(0x9200b7ba, 0x09895e70), TOBN(0x3bd0c66f, 0xddb7fb58),
-+     TOBN(0x2d97d108, 0x78eb4cbb), TOBN(0x2d431068, 0xd84bde31),
-+     TOBN(0x4b523eb7, 0x172ccd1f), TOBN(0x7323cb28, 0x30a6a892),
-+     TOBN(0x97082ec0, 0xcfe153eb), TOBN(0xe97f6b6a, 0xf2aadb97),
-+     TOBN(0x1d3d393e, 0xd1a83da1), TOBN(0xa6a7f9c7, 0x804b2a68),
-+     TOBN(0x4a688b48, 0x2d0cb71e), TOBN(0xa9b4cc5f, 0x40585278),
-+     TOBN(0x5e5db46a, 0xcb66e132), TOBN(0xf1be963a, 0x0d925880),
-+     TOBN(0x944a7027, 0x0317b9e2), TOBN(0xe266f959, 0x48603d48),
-+     TOBN(0x98db6673, 0x5c208899), TOBN(0x90472447, 0xa2fb18a3),
-+     TOBN(0x8a966939, 0x777c619f), TOBN(0x3798142a, 0x2a3be21b),
-+     TOBN(0xb4241cb1, 0x3298b343), TOBN(0xa3a14e49, 0xb44f65a1),
-+     TOBN(0xc5f4d6cd, 0x3ac77acd), TOBN(0xd0288cb5, 0x52b6fc3c),
-+     TOBN(0xd5cc8c2f, 0x1c040abc), TOBN(0xb675511e, 0x06bf9b4a),
-+     TOBN(0xd667da37, 0x9b3aa441), TOBN(0x460d45ce, 0x51601f72),
-+     TOBN(0xe2f73c69, 0x6755ff89), TOBN(0xdd3cf7e7, 0x473017e6),
-+     TOBN(0x8ef5689d, 0x3cf7600d), TOBN(0x948dc4f8, 0xb1fc87b4),
-+     TOBN(0xd9e9fe81, 0x4ea53299), TOBN(0x2d921ca2, 0x98eb6028),
-+     TOBN(0xfaecedfd, 0x0c9803fc), TOBN(0xf38ae891, 0x4d7b4745),
-+     TOBN(0xd8c5fccf, 0xc5e3a3d8), TOBN(0xbefd904c, 0x4079dfbf),
-+     TOBN(0xbc6d6a58, 0xfead0197), TOBN(0x39227077, 0x695532a4),
-+     TOBN(0x09e23e6d, 0xdbef42f5), TOBN(0x7e449b64, 0x480a9908),
-+     TOBN(0x7b969c1a, 0xad9a2e40), TOBN(0x6231d792, 0x9591c2a4),
-+     TOBN(0x87151456, 0x0f664534), TOBN(0x85ceae7c, 0x4b68f103),
-+     TOBN(0xac09c4ae, 0x65578ab9), TOBN(0x33ec6868, 0xf044b10c),
-+     TOBN(0x6ac4832b, 0x3a8ec1f1), TOBN(0x5509d128, 0x5847d5ef),
-+     TOBN(0xf909604f, 0x763f1574), TOBN(0xb16c4303, 0xc32f63c4),
-+     TOBN(0xb6ab2014, 0x7ca23cd3), TOBN(0xcaa7a5c6, 0xa391849d),
-+     TOBN(0x5b0673a3, 0x75678d94), TOBN(0xc982ddd4, 0xdd303e64),
-+     TOBN(0xfd7b000b, 0x5db6f971), TOBN(0xbba2cb1f, 0x6f876f92),
-+     TOBN(0xc77332a3, 0x3c569426), TOBN(0xa159100c, 0x570d74f8),
-+     TOBN(0xfd16847f, 0xdec67ef5), TOBN(0x742ee464, 0x233e76b7),
-+     TOBN(0x0b8e4134, 0xefc2b4c8), TOBN(0xca640b86, 0x42a3e521),
-+     TOBN(0x653a0190, 0x8ceb6aa9), TOBN(0x313c300c, 0x547852d5),
-+     TOBN(0x24e4ab12, 0x6b237af7), TOBN(0x2ba90162, 0x8bb47af8),
-+     TOBN(0x3d5e58d6, 0xa8219bb7), TOBN(0xc691d0bd, 0x1b06c57f),
-+     TOBN(0x0ae4cb10, 0xd257576e), TOBN(0x3569656c, 0xd54a3dc3),
-+     TOBN(0xe5ebaebd, 0x94cda03a), TOBN(0x934e82d3, 0x162bfe13),
-+     TOBN(0x450ac0ba, 0xe251a0c6), TOBN(0x480b9e11, 0xdd6da526),
-+     TOBN(0x00467bc5, 0x8cce08b5), TOBN(0xb636458c, 0x7f178d55),
-+     TOBN(0xc5748bae, 0xa677d806), TOBN(0x2763a387, 0xdfa394eb),
-+     TOBN(0xa12b448a, 0x7d3cebb6), TOBN(0xe7adda3e, 0x6f20d850),
-+     TOBN(0xf63ebce5, 0x1558462c), TOBN(0x58b36143, 0x620088a8),
-+     TOBN(0x8a2cc3ca, 0x4d63c0ee), TOBN(0x51233117, 0x0fe948ce),
-+     TOBN(0x7463fd85, 0x222ef33b), TOBN(0xadf0c7dc, 0x7c603d6c),
-+     TOBN(0x0ec32d3b, 0xfe7765e5), TOBN(0xccaab359, 0xbf380409),
-+     TOBN(0xbdaa84d6, 0x8e59319c), TOBN(0xd9a4c280, 0x9c80c34d),
-+     TOBN(0xa9d89488, 0xa059c142), TOBN(0x6f5ae714, 0xff0b9346),
-+     TOBN(0x068f237d, 0x16fb3664), TOBN(0x5853e4c4, 0x363186ac),
-+     TOBN(0xe2d87d23, 0x63c52f98), TOBN(0x2ec4a766, 0x81828876),
-+     TOBN(0x47b864fa, 0xe14e7b1c), TOBN(0x0c0bc0e5, 0x69192408),
-+     TOBN(0xe4d7681d, 0xb82e9f3e), TOBN(0x83200f0b, 0xdf25e13c),
-+     TOBN(0x8909984c, 0x66f27280), TOBN(0x462d7b00, 0x75f73227),
-+     TOBN(0xd90ba188, 0xf2651798), TOBN(0x74c6e18c, 0x36ab1c34),
-+     TOBN(0xab256ea3, 0x5ef54359), TOBN(0x03466612, 0xd1aa702f),
-+     TOBN(0x624d6049, 0x2ed22e91), TOBN(0x6fdfe0b5, 0x6f072822),
-+     TOBN(0xeeca1115, 0x39ce2271), TOBN(0x98100a4f, 0xdb01614f),
-+     TOBN(0xb6b0daa2, 0xa35c628f), TOBN(0xb6f94d2e, 0xc87e9a47),
-+     TOBN(0xc6773259, 0x1d57d9ce), TOBN(0xf70bfeec, 0x03884a7b),
-+     TOBN(0x5fb35ccf, 0xed2bad01), TOBN(0xa155cbe3, 0x1da6a5c7),
-+     TOBN(0xc2e2594c, 0x30a92f8f), TOBN(0x649c89ce, 0x5bfafe43),
-+     TOBN(0xd158667d, 0xe9ff257a), TOBN(0x9b359611, 0xf32c50ae),
-+     TOBN(0x4b00b20b, 0x906014cf), TOBN(0xf3a8cfe3, 0x89bc7d3d),
-+     TOBN(0x4ff23ffd, 0x248a7d06), TOBN(0x80c5bfb4, 0x878873fa),
-+     TOBN(0xb7d9ad90, 0x05745981), TOBN(0x179c85db, 0x3db01994),
-+     TOBN(0xba41b062, 0x61a6966c), TOBN(0x4d82d052, 0xeadce5a8),
-+     TOBN(0x9e91cd3b, 0xa5e6a318), TOBN(0x47795f4f, 0x95b2dda0),
-+     TOBN(0xecfd7c1f, 0xd55a897c), TOBN(0x009194ab, 0xb29110fb),
-+     TOBN(0x5f0e2046, 0xe381d3b0), TOBN(0x5f3425f6, 0xa98dd291),
-+     TOBN(0xbfa06687, 0x730d50da), TOBN(0x0423446c, 0x4b083b7f),
-+     TOBN(0x397a247d, 0xd69d3417), TOBN(0xeb629f90, 0x387ba42a),
-+     TOBN(0x1ee426cc, 0xd5cd79bf), TOBN(0x0032940b, 0x946c6e18),
-+     TOBN(0x1b1e8ae0, 0x57477f58), TOBN(0xe94f7d34, 0x6d823278),
-+     TOBN(0xc747cb96, 0x782ba21a), TOBN(0xc5254469, 0xf72b33a5),
-+     TOBN(0x772ef6de, 0xc7f80c81), TOBN(0xd73acbfe, 0x2cd9e6b5),
-+     TOBN(0x4075b5b1, 0x49ee90d9), TOBN(0x785c339a, 0xa06e9eba),
-+     TOBN(0xa1030d5b, 0xabf825e0), TOBN(0xcec684c3, 0xa42931dc),
-+     TOBN(0x42ab62c9, 0xc1586e63), TOBN(0x45431d66, 0x5ab43f2b),
-+     TOBN(0x57c8b2c0, 0x55f7835d), TOBN(0x033da338, 0xc1b7f865),
-+     TOBN(0x283c7513, 0xcaa76097), TOBN(0x0a624fa9, 0x36c83906),
-+     TOBN(0x6b20afec, 0x715af2c7), TOBN(0x4b969974, 0xeba78bfd),
-+     TOBN(0x220755cc, 0xd921d60e), TOBN(0x9b944e10, 0x7baeca13),
-+     TOBN(0x04819d51, 0x5ded93d4), TOBN(0x9bbff86e, 0x6dddfd27),
-+     TOBN(0x6b344130, 0x77adc612), TOBN(0xa7496529, 0xbbd803a0),
-+     TOBN(0x1a1baaa7, 0x6d8805bd), TOBN(0xc8403902, 0x470343ad),
-+     TOBN(0x39f59f66, 0x175adff1), TOBN(0x0b26d7fb, 0xb7d8c5b7),
-+     TOBN(0xa875f5ce, 0x529d75e3), TOBN(0x85efc7e9, 0x41325cc2),
-+     TOBN(0x21950b42, 0x1ff6acd3), TOBN(0xffe70484, 0x53dc6909),
-+     TOBN(0xff4cd0b2, 0x28766127), TOBN(0xabdbe608, 0x4fb7db2b),
-+     TOBN(0x837c9228, 0x5e1109e8), TOBN(0x26147d27, 0xf4645b5a),
-+     TOBN(0x4d78f592, 0xf7818ed8), TOBN(0xd394077e, 0xf247fa36),
-+     TOBN(0x0fb9c2d0, 0x488c171a), TOBN(0xa78bfbaa, 0x13685278),
-+     TOBN(0xedfbe268, 0xd5b1fa6a), TOBN(0x0dceb8db, 0x2b7eaba7),
-+     TOBN(0xbf9e8089, 0x9ae2b710), TOBN(0xefde7ae6, 0xa4449c96),
-+     TOBN(0x43b7716b, 0xcc143a46), TOBN(0xd7d34194, 0xc3628c13),
-+     TOBN(0x508cec1c, 0x3b3f64c9), TOBN(0xe20bc0ba, 0x1e5edf3f),
-+     TOBN(0xda1deb85, 0x2f4318d4), TOBN(0xd20ebe0d, 0x5c3fa443),
-+     TOBN(0x370b4ea7, 0x73241ea3), TOBN(0x61f1511c, 0x5e1a5f65),
-+     TOBN(0x99a5e23d, 0x82681c62), TOBN(0xd731e383, 0xa2f54c2d),
-+     TOBN(0x2692f36e, 0x83445904), TOBN(0x2e0ec469, 0xaf45f9c0),
-+     TOBN(0x905a3201, 0xc67528b7), TOBN(0x88f77f34, 0xd0e5e542),
-+     TOBN(0xf67a8d29, 0x5864687c), TOBN(0x23b92eae, 0x22df3562),
-+     TOBN(0x5c27014b, 0x9bbec39e), TOBN(0x7ef2f226, 0x9c0f0f8d),
-+     TOBN(0x97359638, 0x546c4d8d), TOBN(0x5f9c3fc4, 0x92f24679),
-+     TOBN(0x912e8bed, 0xa8c8acd9), TOBN(0xec3a318d, 0x306634b0),
-+     TOBN(0x80167f41, 0xc31cb264), TOBN(0x3db82f6f, 0x522113f2),
-+     TOBN(0xb155bcd2, 0xdcafe197), TOBN(0xfba1da59, 0x43465283),
-+     TOBN(0xa0425b8e, 0xb212cf53), TOBN(0x4f2e512e, 0xf8557c5f),
-+     TOBN(0xc1286ff9, 0x25c4d56c), TOBN(0xbb8a0fea, 0xee26c851),
-+     TOBN(0xc28f70d2, 0xe7d6107e), TOBN(0x7ee0c444, 0xe76265aa),
-+     TOBN(0x3df277a4, 0x1d1936b1), TOBN(0x1a556e3f, 0xea9595eb),
-+     TOBN(0x258bbbf9, 0xe7305683), TOBN(0x31eea5bf, 0x07ef5be6),
-+     TOBN(0x0deb0e4a, 0x46c814c1), TOBN(0x5cee8449, 0xa7b730dd),
-+     TOBN(0xeab495c5, 0xa0182bde), TOBN(0xee759f87, 0x9e27a6b4),
-+     TOBN(0xc2cf6a68, 0x80e518ca), TOBN(0x25e8013f, 0xf14cf3f4),
-+     TOBN(0x8fc44140, 0x7e8d7a14), TOBN(0xbb1ff3ca, 0x9556f36a),
-+     TOBN(0x6a844385, 0x14600044), TOBN(0xba3f0c4a, 0x7451ae63),
-+     TOBN(0xdfcac25b, 0x1f9af32a), TOBN(0x01e0db86, 0xb1f2214b),
-+     TOBN(0x4e9a5bc2, 0xa4b596ac), TOBN(0x83927681, 0x026c2c08),
-+     TOBN(0x3ec832e7, 0x7acaca28), TOBN(0x1bfeea57, 0xc7385b29),
-+     TOBN(0x068212e3, 0xfd1eaf38), TOBN(0xc1329830, 0x6acf8ccc),
-+     TOBN(0xb909f2db, 0x2aac9e59), TOBN(0x5748060d, 0xb661782a),
-+     TOBN(0xc5ab2632, 0xc79b7a01), TOBN(0xda44c6c6, 0x00017626),
-+     TOBN(0xf26c00e8, 0xa7ea82f0), TOBN(0x99cac80d, 0xe4299aaf),
-+     TOBN(0xd66fe3b6, 0x7ed78be1), TOBN(0x305f725f, 0x648d02cd),
-+     TOBN(0x33ed1bc4, 0x623fb21b), TOBN(0xfa70533e, 0x7a6319ad),
-+     TOBN(0x17ab562d, 0xbe5ffb3e), TOBN(0x06374994, 0x56674741),
-+     TOBN(0x69d44ed6, 0x5c46aa8e), TOBN(0x2100d5d3, 0xa8d063d1),
-+     TOBN(0xcb9727ea, 0xa2d17c36), TOBN(0x4c2bab1b, 0x8add53b7),
-+     TOBN(0xa084e90c, 0x15426704), TOBN(0x778afcd3, 0xa837ebea),
-+     TOBN(0x6651f701, 0x7ce477f8), TOBN(0xa0624998, 0x46fb7a8b),
-+     TOBN(0xdc1e6828, 0xed8a6e19), TOBN(0x33fc2336, 0x4189d9c7),
-+     TOBN(0x026f8fe2, 0x671c39bc), TOBN(0xd40c4ccd, 0xbc6f9915),
-+     TOBN(0xafa135bb, 0xf80e75ca), TOBN(0x12c651a0, 0x22adff2c),
-+     TOBN(0xc40a04bd, 0x4f51ad96), TOBN(0x04820109, 0xbbe4e832),
-+     TOBN(0x3667eb1a, 0x7f4c04cc), TOBN(0x59556621, 0xa9404f84),
-+     TOBN(0x71cdf653, 0x7eceb50a), TOBN(0x994a44a6, 0x9b8335fa),
-+     TOBN(0xd7faf819, 0xdbeb9b69), TOBN(0x473c5680, 0xeed4350d),
-+     TOBN(0xb6658466, 0xda44bba2), TOBN(0x0d1bc780, 0x872bdbf3),
-+     TOBN(0xe535f175, 0xa1962f91), TOBN(0x6ed7e061, 0xed58f5a7),
-+     TOBN(0x177aa4c0, 0x2089a233), TOBN(0x0dbcb03a, 0xe539b413),
-+     TOBN(0xe3dc424e, 0xbb32e38e), TOBN(0x6472e5ef, 0x6806701e),
-+     TOBN(0xdd47ff98, 0x814be9ee), TOBN(0x6b60cfff, 0x35ace009),
-+     TOBN(0xb8d3d931, 0x9ff91fe5), TOBN(0x039c4800, 0xf0518eed),
-+     TOBN(0x95c37632, 0x9182cb26), TOBN(0x0763a434, 0x82fc568d),
-+     TOBN(0x707c04d5, 0x383e76ba), TOBN(0xac98b930, 0x824e8197),
-+     TOBN(0x92bf7c8f, 0x91230de0), TOBN(0x90876a01, 0x40959b70),
-+     TOBN(0xdb6d96f3, 0x05968b80), TOBN(0x380a0913, 0x089f73b9),
-+     TOBN(0x7da70b83, 0xc2c61e01), TOBN(0x95fb8394, 0x569b38c7),
-+     TOBN(0x9a3c6512, 0x80edfe2f), TOBN(0x8f726bb9, 0x8faeaf82),
-+     TOBN(0x8010a4a0, 0x78424bf8), TOBN(0x29672044, 0x0e844970)}
-+    ,
-+    {TOBN(0x63c5cb81, 0x7a2ad62a), TOBN(0x7ef2b6b9, 0xac62ff54),
-+     TOBN(0x3749bba4, 0xb3ad9db5), TOBN(0xad311f2c, 0x46d5a617),
-+     TOBN(0xb77a8087, 0xc2ff3b6d), TOBN(0xb46feaf3, 0x367834ff),
-+     TOBN(0xf8aa266d, 0x75d6b138), TOBN(0xfa38d320, 0xec008188),
-+     TOBN(0x486d8ffa, 0x696946fc), TOBN(0x50fbc6d8, 0xb9cba56d),
-+     TOBN(0x7e3d423e, 0x90f35a15), TOBN(0x7c3da195, 0xc0dd962c),
-+     TOBN(0xe673fdb0, 0x3cfd5d8b), TOBN(0x0704b7c2, 0x889dfca5),
-+     TOBN(0xf6ce581f, 0xf52305aa), TOBN(0x399d49eb, 0x914d5e53),
-+     TOBN(0x380a496d, 0x6ec293cd), TOBN(0x733dbda7, 0x8e7051f5),
-+     TOBN(0x037e388d, 0xb849140a), TOBN(0xee4b32b0, 0x5946dbf6),
-+     TOBN(0xb1c4fda9, 0xcae368d1), TOBN(0x5001a7b0, 0xfdb0b2f3),
-+     TOBN(0x6df59374, 0x2e3ac46e), TOBN(0x4af675f2, 0x39b3e656),
-+     TOBN(0x44e38110, 0x39949296), TOBN(0x5b63827b, 0x361db1b5),
-+     TOBN(0x3e5323ed, 0x206eaff5), TOBN(0x942370d2, 0xc21f4290),
-+     TOBN(0xf2caaf2e, 0xe0d985a1), TOBN(0x192cc64b, 0x7239846d),
-+     TOBN(0x7c0b8f47, 0xae6312f8), TOBN(0x7dc61f91, 0x96620108),
-+     TOBN(0xb830fb5b, 0xc2da7de9), TOBN(0xd0e643df, 0x0ff8d3be),
-+     TOBN(0x31ee77ba, 0x188a9641), TOBN(0x4e8aa3aa, 0xbcf6d502),
-+     TOBN(0xf9fb6532, 0x9a49110f), TOBN(0xd18317f6, 0x2dd6b220),
-+     TOBN(0x7e3ced41, 0x52c3ea5a), TOBN(0x0d296a14, 0x7d579c4a),
-+     TOBN(0x35d6a53e, 0xed4c3717), TOBN(0x9f8240cf, 0x3d0ed2a3),
-+     TOBN(0x8c0d4d05, 0xe5543aa5), TOBN(0x45d5bbfb, 0xdd33b4b4),
-+     TOBN(0xfa04cc73, 0x137fd28e), TOBN(0x862ac6ef, 0xc73b3ffd),
-+     TOBN(0x403ff9f5, 0x31f51ef2), TOBN(0x34d5e0fc, 0xbc73f5a2),
-+     TOBN(0xf2526820, 0x08913f4f), TOBN(0xea20ed61, 0xeac93d95),
-+     TOBN(0x51ed38b4, 0x6ca6b26c), TOBN(0x8662dcbc, 0xea4327b0),
-+     TOBN(0x6daf295c, 0x725d2aaa), TOBN(0xbad2752f, 0x8e52dcda),
-+     TOBN(0x2210e721, 0x0b17dacc), TOBN(0xa37f7912, 0xd51e8232),
-+     TOBN(0x4f7081e1, 0x44cc3add), TOBN(0xd5ffa1d6, 0x87be82cf),
-+     TOBN(0x89890b6c, 0x0edd6472), TOBN(0xada26e1a, 0x3ed17863),
-+     TOBN(0x276f2715, 0x63483caa), TOBN(0xe6924cd9, 0x2f6077fd),
-+     TOBN(0x05a7fe98, 0x0a466e3c), TOBN(0xf1c794b0, 0xb1902d1f),
-+     TOBN(0xe5213688, 0x82a8042c), TOBN(0xd931cfaf, 0xcd278298),
-+     TOBN(0x069a0ae0, 0xf597a740), TOBN(0x0adbb3f3, 0xeb59107c),
-+     TOBN(0x983e951e, 0x5eaa8eb8), TOBN(0xe663a8b5, 0x11b48e78),
-+     TOBN(0x1631cc0d, 0x8a03f2c5), TOBN(0x7577c11e, 0x11e271e2),
-+     TOBN(0x33b2385c, 0x08369a90), TOBN(0x2990c59b, 0x190eb4f8),
-+     TOBN(0x819a6145, 0xc68eac80), TOBN(0x7a786d62, 0x2ec4a014),
-+     TOBN(0x33faadbe, 0x20ac3a8d), TOBN(0x31a21781, 0x5aba2d30),
-+     TOBN(0x209d2742, 0xdba4f565), TOBN(0xdb2ce9e3, 0x55aa0fbb),
-+     TOBN(0x8cef334b, 0x168984df), TOBN(0xe81dce17, 0x33879638),
-+     TOBN(0xf6e6949c, 0x263720f0), TOBN(0x5c56feaf, 0xf593cbec),
-+     TOBN(0x8bff5601, 0xfde58c84), TOBN(0x74e24117, 0x2eccb314),
-+     TOBN(0xbcf01b61, 0x4c9a8a78), TOBN(0xa233e35e, 0x544c9868),
-+     TOBN(0xb3156bf3, 0x8bd7aff1), TOBN(0x1b5ee4cb, 0x1d81b146),
-+     TOBN(0x7ba1ac41, 0xd628a915), TOBN(0x8f3a8f9c, 0xfd89699e),
-+     TOBN(0x7329b9c9, 0xa0748be7), TOBN(0x1d391c95, 0xa92e621f),
-+     TOBN(0xe51e6b21, 0x4d10a837), TOBN(0xd255f53a, 0x4947b435),
-+     TOBN(0x07669e04, 0xf1788ee3), TOBN(0xc14f27af, 0xa86938a2),
-+     TOBN(0x8b47a334, 0xe93a01c0), TOBN(0xff627438, 0xd9366808),
-+     TOBN(0x7a0985d8, 0xca2a5965), TOBN(0x3d9a5542, 0xd6e9b9b3),
-+     TOBN(0xc23eb80b, 0x4cf972e8), TOBN(0x5c1c33bb, 0x4fdf72fd),
-+     TOBN(0x0c4a58d4, 0x74a86108), TOBN(0xf8048a8f, 0xee4c5d90),
-+     TOBN(0xe3c7c924, 0xe86d4c80), TOBN(0x28c889de, 0x056a1e60),
-+     TOBN(0x57e2662e, 0xb214a040), TOBN(0xe8c48e98, 0x37e10347),
-+     TOBN(0x87742862, 0x80ac748a), TOBN(0xf1c24022, 0x186b06f2),
-+     TOBN(0xac2dd4c3, 0x5f74040a), TOBN(0x409aeb71, 0xfceac957),
-+     TOBN(0x4fbad782, 0x55c4ec23), TOBN(0xb359ed61, 0x8a7b76ec),
-+     TOBN(0x12744926, 0xed6f4a60), TOBN(0xe21e8d7f, 0x4b912de3),
-+     TOBN(0xe2575a59, 0xfc705a59), TOBN(0x72f1d4de, 0xed2dbc0e),
-+     TOBN(0x3d2b24b9, 0xeb7926b8), TOBN(0xbff88cb3, 0xcdbe5509),
-+     TOBN(0xd0f399af, 0xe4dd640b), TOBN(0x3c5fe130, 0x2f76ed45),
-+     TOBN(0x6f3562f4, 0x3764fb3d), TOBN(0x7b5af318, 0x3151b62d),
-+     TOBN(0xd5bd0bc7, 0xd79ce5f3), TOBN(0xfdaf6b20, 0xec66890f),
-+     TOBN(0x735c67ec, 0x6063540c), TOBN(0x50b259c2, 0xe5f9cb8f),
-+     TOBN(0xb8734f9a, 0x3f99c6ab), TOBN(0xf8cc13d5, 0xa3a7bc85),
-+     TOBN(0x80c1b305, 0xc5217659), TOBN(0xfe5364d4, 0x4ec12a54),
-+     TOBN(0xbd87045e, 0x681345fe), TOBN(0x7f8efeb1, 0x582f897f),
-+     TOBN(0xe8cbf1e5, 0xd5923359), TOBN(0xdb0cea9d, 0x539b9fb0),
-+     TOBN(0x0c5b34cf, 0x49859b98), TOBN(0x5e583c56, 0xa4403cc6),
-+     TOBN(0x11fc1a2d, 0xd48185b7), TOBN(0xc93fbc7e, 0x6e521787),
-+     TOBN(0x47e7a058, 0x05105b8b), TOBN(0x7b4d4d58, 0xdb8260c8),
-+     TOBN(0xe33930b0, 0x46eb842a), TOBN(0x8e844a9a, 0x7bdae56d),
-+     TOBN(0x34ef3a9e, 0x13f7fdfc), TOBN(0xb3768f82, 0x636ca176),
-+     TOBN(0x2821f4e0, 0x4e09e61c), TOBN(0x414dc3a1, 0xa0c7cddc),
-+     TOBN(0xd5379437, 0x54945fcd), TOBN(0x151b6eef, 0xb3555ff1),
-+     TOBN(0xb31bd613, 0x6339c083), TOBN(0x39ff8155, 0xdfb64701),
-+     TOBN(0x7c3388d2, 0xe29604ab), TOBN(0x1e19084b, 0xa6b10442),
-+     TOBN(0x17cf54c0, 0xeccd47ef), TOBN(0x89693385, 0x4a5dfb30),
-+     TOBN(0x69d023fb, 0x47daf9f6), TOBN(0x9222840b, 0x7d91d959),
-+     TOBN(0x439108f5, 0x803bac62), TOBN(0x0b7dd91d, 0x379bd45f),
-+     TOBN(0xd651e827, 0xca63c581), TOBN(0x5c5d75f6, 0x509c104f),
-+     TOBN(0x7d5fc738, 0x1f2dc308), TOBN(0x20faa7bf, 0xd98454be),
-+     TOBN(0x95374bee, 0xa517b031), TOBN(0xf036b9b1, 0x642692ac),
-+     TOBN(0xc5106109, 0x39842194), TOBN(0xb7e2353e, 0x49d05295),
-+     TOBN(0xfc8c1d5c, 0xefb42ee0), TOBN(0xe04884eb, 0x08ce811c),
-+     TOBN(0xf1f75d81, 0x7419f40e), TOBN(0x5b0ac162, 0xa995c241),
-+     TOBN(0x120921bb, 0xc4c55646), TOBN(0x713520c2, 0x8d33cf97),
-+     TOBN(0xb4a65a5c, 0xe98c5100), TOBN(0x6cec871d, 0x2ddd0f5a),
-+     TOBN(0x251f0b7f, 0x9ba2e78b), TOBN(0x224a8434, 0xce3a2a5f),
-+     TOBN(0x26827f61, 0x25f5c46f), TOBN(0x6a22bedc, 0x48545ec0),
-+     TOBN(0x25ae5fa0, 0xb1bb5cdc), TOBN(0xd693682f, 0xfcb9b98f),
-+     TOBN(0x32027fe8, 0x91e5d7d3), TOBN(0xf14b7d17, 0x73a07678),
-+     TOBN(0xf88497b3, 0xc0dfdd61), TOBN(0xf7c2eec0, 0x2a8c4f48),
-+     TOBN(0xaa5573f4, 0x3756e621), TOBN(0xc013a240, 0x1825b948),
-+     TOBN(0x1c03b345, 0x63878572), TOBN(0xa0472bea, 0x653a4184),
-+     TOBN(0xf4222e27, 0x0ac69a80), TOBN(0x34096d25, 0xf51e54f6),
-+     TOBN(0x00a648cb, 0x8fffa591), TOBN(0x4e87acdc, 0x69b6527f),
-+     TOBN(0x0575e037, 0xe285ccb4), TOBN(0x188089e4, 0x50ddcf52),
-+     TOBN(0xaa96c9a8, 0x870ff719), TOBN(0x74a56cd8, 0x1fc7e369),
-+     TOBN(0x41d04ee2, 0x1726931a), TOBN(0x0bbbb2c8, 0x3660ecfd),
-+     TOBN(0xa6ef6de5, 0x24818e18), TOBN(0xe421cc51, 0xe7d57887),
-+     TOBN(0xf127d208, 0xbea87be6), TOBN(0x16a475d3, 0xb1cdd682),
-+     TOBN(0x9db1b684, 0x439b63f7), TOBN(0x5359b3db, 0xf0f113b6),
-+     TOBN(0xdfccf1de, 0x8bf06e31), TOBN(0x1fdf8f44, 0xdd383901),
-+     TOBN(0x10775cad, 0x5017e7d2), TOBN(0xdfc3a597, 0x58d11eef),
-+     TOBN(0x6ec9c8a0, 0xb1ecff10), TOBN(0xee6ed6cc, 0x28400549),
-+     TOBN(0xb5ad7bae, 0x1b4f8d73), TOBN(0x61b4f11d, 0xe00aaab9),
-+     TOBN(0x7b32d69b, 0xd4eff2d7), TOBN(0x88ae6771, 0x4288b60f),
-+     TOBN(0x159461b4, 0x37a1e723), TOBN(0x1f3d4789, 0x570aae8c),
-+     TOBN(0x869118c0, 0x7f9871da), TOBN(0x35fbda78, 0xf635e278),
-+     TOBN(0x738f3641, 0xe1541dac), TOBN(0x6794b13a, 0xc0dae45f),
-+     TOBN(0x065064ac, 0x09cc0917), TOBN(0x27c53729, 0xc68540fd),
-+     TOBN(0x0d2d4c8e, 0xef227671), TOBN(0xd23a9f80, 0xa1785a04),
-+     TOBN(0x98c59528, 0x52650359), TOBN(0xfa09ad01, 0x74a1acad),
-+     TOBN(0x082d5a29, 0x0b55bf5c), TOBN(0xa40f1c67, 0x419b8084),
-+     TOBN(0x3a5c752e, 0xdcc18770), TOBN(0x4baf1f2f, 0x8825c3a5),
-+     TOBN(0xebd63f74, 0x21b153ed), TOBN(0xa2383e47, 0xb2f64723),
-+     TOBN(0xe7bf620a, 0x2646d19a), TOBN(0x56cb44ec, 0x03c83ffd),
-+     TOBN(0xaf7267c9, 0x4f6be9f1), TOBN(0x8b2dfd7b, 0xc06bb5e9),
-+     TOBN(0xb87072f2, 0xa672c5c7), TOBN(0xeacb11c8, 0x0d53c5e2),
-+     TOBN(0x22dac29d, 0xff435932), TOBN(0x37bdb99d, 0x4408693c),
-+     TOBN(0xf6e62fb6, 0x2899c20f), TOBN(0x3535d512, 0x447ece24),
-+     TOBN(0xfbdc6b88, 0xff577ce3), TOBN(0x726693bd, 0x190575f2),
-+     TOBN(0x6772b0e5, 0xab4b35a2), TOBN(0x1d8b6001, 0xf5eeaacf),
-+     TOBN(0x728f7ce4, 0x795b9580), TOBN(0x4a20ed2a, 0x41fb81da),
-+     TOBN(0x9f685cd4, 0x4fec01e6), TOBN(0x3ed7ddcc, 0xa7ff50ad),
-+     TOBN(0x460fd264, 0x0c2d97fd), TOBN(0x3a241426, 0xeb82f4f9),
-+     TOBN(0x17d1df2c, 0x6a8ea820), TOBN(0xb2b50d3b, 0xf22cc254),
-+     TOBN(0x03856cba, 0xb7291426), TOBN(0x87fd26ae, 0x04f5ee39),
-+     TOBN(0x9cb696cc, 0x02bee4ba), TOBN(0x53121804, 0x06820fd6),
-+     TOBN(0xa5dfc269, 0x0212e985), TOBN(0x666f7ffa, 0x160f9a09),
-+     TOBN(0xc503cd33, 0xbccd9617), TOBN(0x365dede4, 0xba7730a3),
-+     TOBN(0x798c6355, 0x5ddb0786), TOBN(0xa6c3200e, 0xfc9cd3bc),
-+     TOBN(0x060ffb2c, 0xe5e35efd), TOBN(0x99a4e25b, 0x5555a1c1),
-+     TOBN(0x11d95375, 0xf70b3751), TOBN(0x0a57354a, 0x160e1bf6),
-+     TOBN(0xecb3ae4b, 0xf8e4b065), TOBN(0x07a834c4, 0x2e53022b),
-+     TOBN(0x1cd300b3, 0x8692ed96), TOBN(0x16a6f792, 0x61ee14ec),
-+     TOBN(0x8f1063c6, 0x6a8649ed), TOBN(0xfbcdfcfe, 0x869f3e14),
-+     TOBN(0x2cfb97c1, 0x00a7b3ec), TOBN(0xcea49b3c, 0x7130c2f1),
-+     TOBN(0x462d044f, 0xe9d96488), TOBN(0x4b53d52e, 0x8182a0c1),
-+     TOBN(0x84b6ddd3, 0x0391e9e9), TOBN(0x80ab7b48, 0xb1741a09),
-+     TOBN(0xec0e15d4, 0x27d3317f), TOBN(0x8dfc1ddb, 0x1a64671e),
-+     TOBN(0x93cc5d5f, 0xd49c5b92), TOBN(0xc995d53d, 0x3674a331),
-+     TOBN(0x302e41ec, 0x090090ae), TOBN(0x2278a0cc, 0xedb06830),
-+     TOBN(0x1d025932, 0xfbc99690), TOBN(0x0c32fbd2, 0xb80d68da),
-+     TOBN(0xd79146da, 0xf341a6c1), TOBN(0xae0ba139, 0x1bef68a0),
-+     TOBN(0xc6b8a563, 0x8d774b3a), TOBN(0x1cf307bd, 0x880ba4d7),
-+     TOBN(0xc033bdc7, 0x19803511), TOBN(0xa9f97b3b, 0x8888c3be),
-+     TOBN(0x3d68aebc, 0x85c6d05e), TOBN(0xc3b88a9d, 0x193919eb),
-+     TOBN(0x2d300748, 0xc48b0ee3), TOBN(0x7506bc7c, 0x07a746c1),
-+     TOBN(0xfc48437c, 0x6e6d57f3), TOBN(0x5bd71587, 0xcfeaa91a),
-+     TOBN(0xa4ed0408, 0xc1bc5225), TOBN(0xd0b946db, 0x2719226d),
-+     TOBN(0x109ecd62, 0x758d2d43), TOBN(0x75c8485a, 0x2751759b),
-+     TOBN(0xb0b75f49, 0x9ce4177a), TOBN(0x4fa61a1e, 0x79c10c3d),
-+     TOBN(0xc062d300, 0xa167fcd7), TOBN(0x4df3874c, 0x750f0fa8),
-+     TOBN(0x29ae2cf9, 0x83dfedc9), TOBN(0xf8437134, 0x8d87631a),
-+     TOBN(0xaf571711, 0x7429c8d2), TOBN(0x18d15867, 0x146d9272),
-+     TOBN(0x83053ecf, 0x69769bb7), TOBN(0xc55eb856, 0xc479ab82),
-+     TOBN(0x5ef7791c, 0x21b0f4b2), TOBN(0xaa5956ba, 0x3d491525),
-+     TOBN(0x407a96c2, 0x9fe20eba), TOBN(0xf27168bb, 0xe52a5ad3),
-+     TOBN(0x43b60ab3, 0xbf1d9d89), TOBN(0xe45c51ef, 0x710e727a),
-+     TOBN(0xdfca5276, 0x099b4221), TOBN(0x8dc6407c, 0x2557a159),
-+     TOBN(0x0ead8335, 0x91035895), TOBN(0x0a9db957, 0x9c55dc32),
-+     TOBN(0xe40736d3, 0xdf61bc76), TOBN(0x13a619c0, 0x3f778cdb),
-+     TOBN(0x6dd921a4, 0xc56ea28f), TOBN(0x76a52433, 0x2fa647b4),
-+     TOBN(0x23591891, 0xac5bdc5d), TOBN(0xff4a1a72, 0xbac7dc01),
-+     TOBN(0x9905e261, 0x62df8453), TOBN(0x3ac045df, 0xe63b265f),
-+     TOBN(0x8a3f341b, 0xad53dba7), TOBN(0x8ec269cc, 0x837b625a),
-+     TOBN(0xd71a2782, 0x3ae31189), TOBN(0x8fb4f9a3, 0x55e96120),
-+     TOBN(0x804af823, 0xff9875cf), TOBN(0x23224f57, 0x5d442a9b),
-+     TOBN(0x1c4d3b9e, 0xecc62679), TOBN(0x91da22fb, 0xa0e7ddb1),
-+     TOBN(0xa370324d, 0x6c04a661), TOBN(0x9710d3b6, 0x5e376d17),
-+     TOBN(0xed8c98f0, 0x3044e357), TOBN(0xc364ebbe, 0x6422701c),
-+     TOBN(0x347f5d51, 0x7733d61c), TOBN(0xd55644b9, 0xcea826c3),
-+     TOBN(0x80c6e0ad, 0x55a25548), TOBN(0x0aa7641d, 0x844220a7),
-+     TOBN(0x1438ec81, 0x31810660), TOBN(0x9dfa6507, 0xde4b4043),
-+     TOBN(0x10b515d8, 0xcc3e0273), TOBN(0x1b6066dd, 0x28d8cfb2),
-+     TOBN(0xd3b04591, 0x9c9efebd), TOBN(0x425d4bdf, 0xa21c1ff4),
-+     TOBN(0x5fe5af19, 0xd57607d3), TOBN(0xbbf773f7, 0x54481084),
-+     TOBN(0x8435bd69, 0x94b03ed1), TOBN(0xd9ad1de3, 0x634cc546),
-+     TOBN(0x2cf423fc, 0x00e420ca), TOBN(0xeed26d80, 0xa03096dd),
-+     TOBN(0xd7f60be7, 0xa4db09d2), TOBN(0xf47f569d, 0x960622f7),
-+     TOBN(0xe5925fd7, 0x7296c729), TOBN(0xeff2db26, 0x26ca2715),
-+     TOBN(0xa6fcd014, 0xb913e759), TOBN(0x53da4786, 0x8ff4de93),
-+     TOBN(0x14616d79, 0xc32068e1), TOBN(0xb187d664, 0xccdf352e),
-+     TOBN(0xf7afb650, 0x1dc90b59), TOBN(0x8170e943, 0x7daa1b26),
-+     TOBN(0xc8e3bdd8, 0x700c0a84), TOBN(0x6e8d345f, 0x6482bdfa),
-+     TOBN(0x84cfbfa1, 0xc5c5ea50), TOBN(0xd3baf14c, 0x67960681),
-+     TOBN(0x26398403, 0x0dd50942), TOBN(0xe4b7839c, 0x4716a663),
-+     TOBN(0xd5f1f794, 0xe7de6dc0), TOBN(0x5cd0f4d4, 0x622aa7ce),
-+     TOBN(0x5295f3f1, 0x59acfeec), TOBN(0x8d933552, 0x953e0607),
-+     TOBN(0xc7db8ec5, 0x776c5722), TOBN(0xdc467e62, 0x2b5f290c),
-+     TOBN(0xd4297e70, 0x4ff425a9), TOBN(0x4be924c1, 0x0cf7bb72),
-+     TOBN(0x0d5dc5ae, 0xa1892131), TOBN(0x8bf8a8e3, 0xa705c992),
-+     TOBN(0x73a0b064, 0x7a305ac5), TOBN(0x00c9ca4e, 0x9a8c77a8),
-+     TOBN(0x5dfee80f, 0x83774bdd), TOBN(0x63131602, 0x85734485),
-+     TOBN(0xa1b524ae, 0x914a69a9), TOBN(0xebc2ffaf, 0xd4e300d7),
-+     TOBN(0x52c93db7, 0x7cfa46a5), TOBN(0x71e6161f, 0x21653b50),
-+     TOBN(0x3574fc57, 0xa4bc580a), TOBN(0xc09015dd, 0xe1bc1253),
-+     TOBN(0x4b7b47b2, 0xd174d7aa), TOBN(0x4072d8e8, 0xf3a15d04),
-+     TOBN(0xeeb7d47f, 0xd6fa07ed), TOBN(0x6f2b9ff9, 0xedbdafb1),
-+     TOBN(0x18c51615, 0x3760fe8a), TOBN(0x7a96e6bf, 0xf06c6c13),
-+     TOBN(0x4d7a0410, 0x0ea2d071), TOBN(0xa1914e9b, 0x0be2a5ce),
-+     TOBN(0x5726e357, 0xd8a3c5cf), TOBN(0x1197ecc3, 0x2abb2b13),
-+     TOBN(0x6c0d7f7f, 0x31ae88dd), TOBN(0x15b20d1a, 0xfdbb3efe),
-+     TOBN(0xcd06aa26, 0x70584039), TOBN(0x2277c969, 0xa7dc9747),
-+     TOBN(0xbca69587, 0x7855d815), TOBN(0x899ea238, 0x5188b32a),
-+     TOBN(0x37d9228b, 0x760c1c9d), TOBN(0xc7efbb11, 0x9b5c18da),
-+     TOBN(0x7f0d1bc8, 0x19f6dbc5), TOBN(0x4875384b, 0x07e6905b),
-+     TOBN(0xc7c50baa, 0x3ba8cd86), TOBN(0xb0ce40fb, 0xc2905de0),
-+     TOBN(0x70840673, 0x7a231952), TOBN(0xa912a262, 0xcf43de26),
-+     TOBN(0x9c38ddcc, 0xeb5b76c1), TOBN(0x746f5285, 0x26fc0ab4),
-+     TOBN(0x52a63a50, 0xd62c269f), TOBN(0x60049c55, 0x99458621),
-+     TOBN(0xe7f48f82, 0x3c2f7c9e), TOBN(0x6bd99043, 0x917d5cf3),
-+     TOBN(0xeb1317a8, 0x8701f469), TOBN(0xbd3fe2ed, 0x9a449fe0),
-+     TOBN(0x421e79ca, 0x12ef3d36), TOBN(0x9ee3c36c, 0x3e7ea5de),
-+     TOBN(0xe48198b5, 0xcdff36f7), TOBN(0xaff4f967, 0xc6b82228),
-+     TOBN(0x15e19dd0, 0xc47adb7e), TOBN(0x45699b23, 0x032e7dfa),
-+     TOBN(0x40680c8b, 0x1fae026a), TOBN(0x5a347a48, 0x550dbf4d),
-+     TOBN(0xe652533b, 0x3cef0d7d), TOBN(0xd94f7b18, 0x2bbb4381),
-+     TOBN(0x838752be, 0x0e80f500), TOBN(0x8e6e2488, 0x9e9c9bfb),
-+     TOBN(0xc9751697, 0x16caca6a), TOBN(0x866c49d8, 0x38531ad9),
-+     TOBN(0xc917e239, 0x7151ade1), TOBN(0x2d016ec1, 0x6037c407),
-+     TOBN(0xa407ccc9, 0x00eac3f9), TOBN(0x835f6280, 0xe2ed4748),
-+     TOBN(0xcc54c347, 0x1cc98e0d), TOBN(0x0e969937, 0xdcb572eb),
-+     TOBN(0x1b16c8e8, 0x8f30c9cb), TOBN(0xa606ae75, 0x373c4661),
-+     TOBN(0x47aa689b, 0x35502cab), TOBN(0xf89014ae, 0x4d9bb64f),
-+     TOBN(0x202f6a9c, 0x31c71f7b), TOBN(0x01f95aa3, 0x296ffe5c),
-+     TOBN(0x5fc06014, 0x53cec3a3), TOBN(0xeb991237, 0x5f498a45),
-+     TOBN(0xae9a935e, 0x5d91ba87), TOBN(0xc6ac6281, 0x0b564a19),
-+     TOBN(0x8a8fe81c, 0x3bd44e69), TOBN(0x7c8b467f, 0x9dd11d45),
-+     TOBN(0xf772251f, 0xea5b8e69), TOBN(0xaeecb3bd, 0xc5b75fbc),
-+     TOBN(0x1aca3331, 0x887ff0e5), TOBN(0xbe5d49ff, 0x19f0a131),
-+     TOBN(0x582c13aa, 0xe5c8646f), TOBN(0xdbaa12e8, 0x20e19980),
-+     TOBN(0x8f40f31a, 0xf7abbd94), TOBN(0x1f13f5a8, 0x1dfc7663),
-+     TOBN(0x5d81f1ee, 0xaceb4fc0), TOBN(0x36256002, 0x5e6f0f42),
-+     TOBN(0x4b67d6d7, 0x751370c8), TOBN(0x2608b698, 0x03e80589),
-+     TOBN(0xcfc0d2fc, 0x05268301), TOBN(0xa6943d39, 0x40309212),
-+     TOBN(0x192a90c2, 0x1fd0e1c2), TOBN(0xb209f113, 0x37f1dc76),
-+     TOBN(0xefcc5e06, 0x97bf1298), TOBN(0xcbdb6730, 0x219d639e),
-+     TOBN(0xd009c116, 0xb81e8c6f), TOBN(0xa3ffdde3, 0x1a7ce2e5),
-+     TOBN(0xc53fbaaa, 0xa914d3ba), TOBN(0x836d500f, 0x88df85ee),
-+     TOBN(0xd98dc71b, 0x66ee0751), TOBN(0x5a3d7005, 0x714516fd),
-+     TOBN(0x21d3634d, 0x39eedbba), TOBN(0x35cd2e68, 0x0455a46d),
-+     TOBN(0xc8cafe65, 0xf9d7eb0c), TOBN(0xbda3ce9e, 0x00cefb3e),
-+     TOBN(0xddc17a60, 0x2c9cf7a4), TOBN(0x01572ee4, 0x7bcb8773),
-+     TOBN(0xa92b2b01, 0x8c7548df), TOBN(0x732fd309, 0xa84600e3),
-+     TOBN(0xe22109c7, 0x16543a40), TOBN(0x9acafd36, 0xfede3c6c),
-+     TOBN(0xfb206852, 0x6824e614), TOBN(0x2a4544a9, 0xda25dca0),
-+     TOBN(0x25985262, 0x91d60b06), TOBN(0x281b7be9, 0x28753545),
-+     TOBN(0xec667b1a, 0x90f13b27), TOBN(0x33a83aff, 0x940e2eb4),
-+     TOBN(0x80009862, 0xd5d721d5), TOBN(0x0c3357a3, 0x5bd3a182),
-+     TOBN(0x27f3a83b, 0x7aa2cda4), TOBN(0xb58ae74e, 0xf6f83085),
-+     TOBN(0x2a911a81, 0x2e6dad6b), TOBN(0xde286051, 0xf43d6c5b),
-+     TOBN(0x4bdccc41, 0xf996c4d8), TOBN(0xe7312ec0, 0x0ae1e24e)}
-+    ,
-+    {TOBN(0xf8d112e7, 0x6e6485b3), TOBN(0x4d3e24db, 0x771c52f8),
-+     TOBN(0x48e3ee41, 0x684a2f6d), TOBN(0x7161957d, 0x21d95551),
-+     TOBN(0x19631283, 0xcdb12a6c), TOBN(0xbf3fa882, 0x2e50e164),
-+     TOBN(0xf6254b63, 0x3166cc73), TOBN(0x3aefa7ae, 0xaee8cc38),
-+     TOBN(0x79b0fe62, 0x3b36f9fd), TOBN(0x26543b23, 0xfde19fc0),
-+     TOBN(0x136e64a0, 0x958482ef), TOBN(0x23f63771, 0x9b095825),
-+     TOBN(0x14cfd596, 0xb6a1142e), TOBN(0x5ea6aac6, 0x335aac0b),
-+     TOBN(0x86a0e8bd, 0xf3081dd5), TOBN(0x5fb89d79, 0x003dc12a),
-+     TOBN(0xf615c33a, 0xf72e34d4), TOBN(0x0bd9ea40, 0x110eec35),
-+     TOBN(0x1c12bc5b, 0xc1dea34e), TOBN(0x686584c9, 0x49ae4699),
-+     TOBN(0x13ad95d3, 0x8c97b942), TOBN(0x4609561a, 0x4e5c7562),
-+     TOBN(0x9e94a4ae, 0xf2737f89), TOBN(0xf57594c6, 0x371c78b6),
-+     TOBN(0x0f0165fc, 0xe3779ee3), TOBN(0xe00e7f9d, 0xbd495d9e),
-+     TOBN(0x1fa4efa2, 0x20284e7a), TOBN(0x4564bade, 0x47ac6219),
-+     TOBN(0x90e6312a, 0xc4708e8e), TOBN(0x4f5725fb, 0xa71e9adf),
-+     TOBN(0xe95f55ae, 0x3d684b9f), TOBN(0x47f7ccb1, 0x1e94b415),
-+     TOBN(0x7322851b, 0x8d946581), TOBN(0xf0d13133, 0xbdf4a012),
-+     TOBN(0xa3510f69, 0x6584dae0), TOBN(0x03a7c171, 0x3c9f6c6d),
-+     TOBN(0x5be97f38, 0xe475381a), TOBN(0xca1ba422, 0x85823334),
-+     TOBN(0xf83cc5c7, 0x0be17dda), TOBN(0x158b1494, 0x0b918c0f),
-+     TOBN(0xda3a77e5, 0x522e6b69), TOBN(0x69c908c3, 0xbbcd6c18),
-+     TOBN(0x1f1b9e48, 0xd924fd56), TOBN(0x37c64e36, 0xaa4bb3f7),
-+     TOBN(0x5a4fdbdf, 0xee478d7d), TOBN(0xba75c8bc, 0x0193f7a0),
-+     TOBN(0x84bc1e84, 0x56cd16df), TOBN(0x1fb08f08, 0x46fad151),
-+     TOBN(0x8a7cabf9, 0x842e9f30), TOBN(0xa331d4bf, 0x5eab83af),
-+     TOBN(0xd272cfba, 0x017f2a6a), TOBN(0x27560abc, 0x83aba0e3),
-+     TOBN(0x94b83387, 0x0e3a6b75), TOBN(0x25c6aea2, 0x6b9f50f5),
-+     TOBN(0x803d691d, 0xb5fdf6d0), TOBN(0x03b77509, 0xe6333514),
-+     TOBN(0x36178903, 0x61a341c1), TOBN(0x3604dc60, 0x0cfd6142),
-+     TOBN(0x022295eb, 0x8533316c), TOBN(0x3dbde4ac, 0x44af2922),
-+     TOBN(0x898afc5d, 0x1c7eef69), TOBN(0x58896805, 0xd14f4fa1),
-+     TOBN(0x05002160, 0x203c21ca), TOBN(0x6f0d1f30, 0x40ef730b),
-+     TOBN(0x8e8c44d4, 0x196224f8), TOBN(0x75a4ab95, 0x374d079d),
-+     TOBN(0x79085ecc, 0x7d48f123), TOBN(0x56f04d31, 0x1bf65ad8),
-+     TOBN(0xe220bf1c, 0xbda602b2), TOBN(0x73ee1742, 0xf9612c69),
-+     TOBN(0x76008fc8, 0x084fd06b), TOBN(0x4000ef9f, 0xf11380d1),
-+     TOBN(0x48201b4b, 0x12cfe297), TOBN(0x3eee129c, 0x292f74e5),
-+     TOBN(0xe1fe114e, 0xc9e874e8), TOBN(0x899b055c, 0x92c5fc41),
-+     TOBN(0x4e477a64, 0x3a39c8cf), TOBN(0x82f09efe, 0x78963cc9),
-+     TOBN(0x6fd3fd8f, 0xd333f863), TOBN(0x85132b2a, 0xdc949c63),
-+     TOBN(0x7e06a3ab, 0x516eb17b), TOBN(0x73bec06f, 0xd2c7372b),
-+     TOBN(0xe4f74f55, 0xba896da6), TOBN(0xbb4afef8, 0x8e9eb40f),
-+     TOBN(0x2d75bec8, 0xe61d66b0), TOBN(0x02bda4b4, 0xef29300b),
-+     TOBN(0x8bbaa8de, 0x026baa5a), TOBN(0xff54befd, 0xa07f4440),
-+     TOBN(0xbd9b8b1d, 0xbe7a2af3), TOBN(0xec51caa9, 0x4fb74a72),
-+     TOBN(0xb9937a4b, 0x63879697), TOBN(0x7c9a9d20, 0xec2687d5),
-+     TOBN(0x1773e44f, 0x6ef5f014), TOBN(0x8abcf412, 0xe90c6900),
-+     TOBN(0x387bd022, 0x8142161e), TOBN(0x50393755, 0xfcb6ff2a),
-+     TOBN(0x9813fd56, 0xed6def63), TOBN(0x53cf6482, 0x7d53106c),
-+     TOBN(0x991a35bd, 0x431f7ac1), TOBN(0xf1e274dd, 0x63e65faf),
-+     TOBN(0xf63ffa3c, 0x44cc7880), TOBN(0x411a426b, 0x7c256981),
-+     TOBN(0xb698b9fd, 0x93a420e0), TOBN(0x89fdddc0, 0xae53f8fe),
-+     TOBN(0x766e0722, 0x32398baa), TOBN(0x205fee42, 0x5cfca031),
-+     TOBN(0xa49f5341, 0x7a029cf2), TOBN(0xa88c68b8, 0x4023890d),
-+     TOBN(0xbc275041, 0x7337aaa8), TOBN(0x9ed364ad, 0x0eb384f4),
-+     TOBN(0xe0816f85, 0x29aba92f), TOBN(0x2e9e1941, 0x04e38a88),
-+     TOBN(0x57eef44a, 0x3dafd2d5), TOBN(0x35d1fae5, 0x97ed98d8),
-+     TOBN(0x50628c09, 0x2307f9b1), TOBN(0x09d84aae, 0xd6cba5c6),
-+     TOBN(0x67071bc7, 0x88aaa691), TOBN(0x2dea57a9, 0xafe6cb03),
-+     TOBN(0xdfe11bb4, 0x3d78ac01), TOBN(0x7286418c, 0x7fd7aa51),
-+     TOBN(0xfabf7709, 0x77f7195a), TOBN(0x8ec86167, 0xadeb838f),
-+     TOBN(0xea1285a8, 0xbb4f012d), TOBN(0xd6883503, 0x9a3eab3f),
-+     TOBN(0xee5d24f8, 0x309004c2), TOBN(0xa96e4b76, 0x13ffe95e),
-+     TOBN(0x0cdffe12, 0xbd223ea4), TOBN(0x8f5c2ee5, 0xb6739a53),
-+     TOBN(0x5cb4aaa5, 0xdd968198), TOBN(0xfa131c52, 0x72413a6c),
-+     TOBN(0x53d46a90, 0x9536d903), TOBN(0xb270f0d3, 0x48606d8e),
-+     TOBN(0x518c7564, 0xa053a3bc), TOBN(0x088254b7, 0x1a86caef),
-+     TOBN(0xb3ba8cb4, 0x0ab5efd0), TOBN(0x5c59900e, 0x4605945d),
-+     TOBN(0xecace1dd, 0xa1887395), TOBN(0x40960f36, 0x932a65de),
-+     TOBN(0x9611ff5c, 0x3aa95529), TOBN(0xc58215b0, 0x7c1e5a36),
-+     TOBN(0xd48c9b58, 0xf0e1a524), TOBN(0xb406856b, 0xf590dfb8),
-+     TOBN(0xc7605e04, 0x9cd95662), TOBN(0x0dd036ee, 0xa33ecf82),
-+     TOBN(0xa50171ac, 0xc33156b3), TOBN(0xf09d24ea, 0x4a80172e),
-+     TOBN(0x4e1f72c6, 0x76dc8eef), TOBN(0xe60caadc, 0x5e3d44ee),
-+     TOBN(0x006ef8a6, 0x979b1d8f), TOBN(0x60908a1c, 0x97788d26),
-+     TOBN(0x6e08f95b, 0x266feec0), TOBN(0x618427c2, 0x22e8c94e),
-+     TOBN(0x3d613339, 0x59145a65), TOBN(0xcd9bc368, 0xfa406337),
-+     TOBN(0x82d11be3, 0x2d8a52a0), TOBN(0xf6877b27, 0x97a1c590),
-+     TOBN(0x837a819b, 0xf5cbdb25), TOBN(0x2a4fd1d8, 0xde090249),
-+     TOBN(0x622a7de7, 0x74990e5f), TOBN(0x840fa5a0, 0x7945511b),
-+     TOBN(0x30b974be, 0x6558842d), TOBN(0x70df8c64, 0x17f3d0a6),
-+     TOBN(0x7c803520, 0x7542e46d), TOBN(0x7251fe7f, 0xe4ecc823),
-+     TOBN(0xe59134cb, 0x5e9aac9a), TOBN(0x11bb0934, 0xf0045d71),
-+     TOBN(0x53e5d9b5, 0xdbcb1d4e), TOBN(0x8d97a905, 0x92defc91),
-+     TOBN(0xfe289327, 0x7946d3f9), TOBN(0xe132bd24, 0x07472273),
-+     TOBN(0xeeeb510c, 0x1eb6ae86), TOBN(0x777708c5, 0xf0595067),
-+     TOBN(0x18e2c8cd, 0x1297029e), TOBN(0x2c61095c, 0xbbf9305e),
-+     TOBN(0xe466c258, 0x6b85d6d9), TOBN(0x8ac06c36, 0xda1ea530),
-+     TOBN(0xa365dc39, 0xa1304668), TOBN(0xe4a9c885, 0x07f89606),
-+     TOBN(0x65a4898f, 0xacc7228d), TOBN(0x3e2347ff, 0x84ca8303),
-+     TOBN(0xa5f6fb77, 0xea7d23a3), TOBN(0x2fac257d, 0x672a71cd),
-+     TOBN(0x6908bef8, 0x7e6a44d3), TOBN(0x8ff87566, 0x891d3d7a),
-+     TOBN(0xe58e90b3, 0x6b0cf82e), TOBN(0x6438d246, 0x2615b5e7),
-+     TOBN(0x07b1f8fc, 0x669c145a), TOBN(0xb0d8b2da, 0x36f1e1cb),
-+     TOBN(0x54d5dadb, 0xd9184c4d), TOBN(0x3dbb18d5, 0xf93d9976),
-+     TOBN(0x0a3e0f56, 0xd1147d47), TOBN(0x2afa8c8d, 0xa0a48609),
-+     TOBN(0x275353e8, 0xbc36742c), TOBN(0x898f427e, 0xeea0ed90),
-+     TOBN(0x26f4947e, 0x3e477b00), TOBN(0x8ad8848a, 0x308741e3),
-+     TOBN(0x6c703c38, 0xd74a2a46), TOBN(0x5e3e05a9, 0x9ba17ba2),
-+     TOBN(0xc1fa6f66, 0x4ab9a9e4), TOBN(0x474a2d9a, 0x3841d6ec),
-+     TOBN(0x871239ad, 0x653ae326), TOBN(0x14bcf72a, 0xa74cbb43),
-+     TOBN(0x8737650e, 0x20d4c083), TOBN(0x3df86536, 0x110ed4af),
-+     TOBN(0xd2d86fe7, 0xb53ca555), TOBN(0x688cb00d, 0xabd5d538),
-+     TOBN(0xcf81bda3, 0x1ad38468), TOBN(0x7ccfe3cc, 0xf01167b6),
-+     TOBN(0xcf4f47e0, 0x6c4c1fe6), TOBN(0x557e1f1a, 0x298bbb79),
-+     TOBN(0xf93b974f, 0x30d45a14), TOBN(0x174a1d2d, 0x0baf97c4),
-+     TOBN(0x7a003b30, 0xc51fbf53), TOBN(0xd8940991, 0xee68b225),
-+     TOBN(0x5b0aa7b7, 0x1c0f4173), TOBN(0x975797c9, 0xa20a7153),
-+     TOBN(0x26e08c07, 0xe3533d77), TOBN(0xd7222e6a, 0x2e341c99),
-+     TOBN(0x9d60ec3d, 0x8d2dc4ed), TOBN(0xbdfe0d8f, 0x7c476cf8),
-+     TOBN(0x1fe59ab6, 0x1d056605), TOBN(0xa9ea9df6, 0x86a8551f),
-+     TOBN(0x8489941e, 0x47fb8d8c), TOBN(0xfeb874eb, 0x4a7f1b10),
-+     TOBN(0xfe5fea86, 0x7ee0d98f), TOBN(0x201ad34b, 0xdbf61864),
-+     TOBN(0x45d8fe47, 0x37c031d4), TOBN(0xd5f49fae, 0x795f0822),
-+     TOBN(0xdb0fb291, 0xc7f4a40c), TOBN(0x2e69d9c1, 0x730ddd92),
-+     TOBN(0x754e1054, 0x49d76987), TOBN(0x8a24911d, 0x7662db87),
-+     TOBN(0x61fc1810, 0x60a71676), TOBN(0xe852d1a8, 0xf66a8ad1),
-+     TOBN(0x172bbd65, 0x6417231e), TOBN(0x0d6de7bd, 0x3babb11f),
-+     TOBN(0x6fde6f88, 0xc8e347f8), TOBN(0x1c587547, 0x9bd99cc3),
-+     TOBN(0x78e54ed0, 0x34076950), TOBN(0x97f0f334, 0x796e83ba),
-+     TOBN(0xe4dbe1ce, 0x4924867a), TOBN(0xbd5f51b0, 0x60b84917),
-+     TOBN(0x37530040, 0x3cb09a79), TOBN(0xdb3fe0f8, 0xff1743d8),
-+     TOBN(0xed7894d8, 0x556fa9db), TOBN(0xfa262169, 0x23412fbf),
-+     TOBN(0x563be0db, 0xba7b9291), TOBN(0x6ca8b8c0, 0x0c9fb234),
-+     TOBN(0xed406aa9, 0xbd763802), TOBN(0xc21486a0, 0x65303da1),
-+     TOBN(0x61ae291e, 0xc7e62ec4), TOBN(0x622a0492, 0xdf99333e),
-+     TOBN(0x7fd80c9d, 0xbb7a8ee0), TOBN(0xdc2ed3bc, 0x6c01aedb),
-+     TOBN(0x35c35a12, 0x08be74ec), TOBN(0xd540cb1a, 0x469f671f),
-+     TOBN(0xd16ced4e, 0xcf84f6c7), TOBN(0x8561fb9c, 0x2d090f43),
-+     TOBN(0x7e693d79, 0x6f239db4), TOBN(0xa736f928, 0x77bd0d94),
-+     TOBN(0x07b4d929, 0x2c1950ee), TOBN(0xda177543, 0x56dc11b3),
-+     TOBN(0xa5dfbbaa, 0x7a6a878e), TOBN(0x1c70cb29, 0x4decb08a),
-+     TOBN(0xfba28c8b, 0x6f0f7c50), TOBN(0xa8eba2b8, 0x854dcc6d),
-+     TOBN(0x5ff8e89a, 0x36b78642), TOBN(0x070c1c8e, 0xf6873adf),
-+     TOBN(0xbbd3c371, 0x6484d2e4), TOBN(0xfb78318f, 0x0d414129),
-+     TOBN(0x2621a39c, 0x6ad93b0b), TOBN(0x979d74c2, 0xa9e917f7),
-+     TOBN(0xfc195647, 0x61fb0428), TOBN(0x4d78954a, 0xbee624d4),
-+     TOBN(0xb94896e0, 0xb8ae86fd), TOBN(0x6667ac0c, 0xc91c8b13),
-+     TOBN(0x9f180512, 0x43bcf832), TOBN(0xfbadf8b7, 0xa0010137),
-+     TOBN(0xc69b4089, 0xb3ba8aa7), TOBN(0xfac4bacd, 0xe687ce85),
-+     TOBN(0x9164088d, 0x977eab40), TOBN(0x51f4c5b6, 0x2760b390),
-+     TOBN(0xd238238f, 0x340dd553), TOBN(0x358566c3, 0xdb1d31c9),
-+     TOBN(0x3a5ad69e, 0x5068f5ff), TOBN(0xf31435fc, 0xdaff6b06),
-+     TOBN(0xae549a5b, 0xd6debff0), TOBN(0x59e5f0b7, 0x75e01331),
-+     TOBN(0x5d492fb8, 0x98559acf), TOBN(0x96018c2e, 0x4db79b50),
-+     TOBN(0x55f4a48f, 0x609f66aa), TOBN(0x1943b3af, 0x4900a14f),
-+     TOBN(0xc22496df, 0x15a40d39), TOBN(0xb2a44684, 0x4c20f7c5),
-+     TOBN(0x76a35afa, 0x3b98404c), TOBN(0xbec75725, 0xff5d1b77),
-+     TOBN(0xb67aa163, 0xbea06444), TOBN(0x27e95bb2, 0xf724b6f2),
-+     TOBN(0x3c20e3e9, 0xd238c8ab), TOBN(0x1213754e, 0xddd6ae17),
-+     TOBN(0x8c431020, 0x716e0f74), TOBN(0x6679c82e, 0xffc095c2),
-+     TOBN(0x2eb3adf4, 0xd0ac2932), TOBN(0x2cc970d3, 0x01bb7a76),
-+     TOBN(0x70c71f2f, 0x740f0e66), TOBN(0x545c616b, 0x2b6b23cc),
-+     TOBN(0x4528cfcb, 0xb40a8bd7), TOBN(0xff839633, 0x2ab27722),
-+     TOBN(0x049127d9, 0x025ac99a), TOBN(0xd314d4a0, 0x2b63e33b),
-+     TOBN(0xc8c310e7, 0x28d84519), TOBN(0x0fcb8983, 0xb3bc84ba),
-+     TOBN(0x2cc52261, 0x38634818), TOBN(0x501814f4, 0xb44c2e0b),
-+     TOBN(0xf7e181aa, 0x54dfdba3), TOBN(0xcfd58ff0, 0xe759718c),
-+     TOBN(0xf90cdb14, 0xd3b507a8), TOBN(0x57bd478e, 0xc50bdad8),
-+     TOBN(0x29c197e2, 0x50e5f9aa), TOBN(0x4db6eef8, 0xe40bc855),
-+     TOBN(0x2cc8f21a, 0xd1fc0654), TOBN(0xc71cc963, 0x81269d73),
-+     TOBN(0xecfbb204, 0x077f49f9), TOBN(0xdde92571, 0xca56b793),
-+     TOBN(0x9abed6a3, 0xf97ad8f7), TOBN(0xe6c19d3f, 0x924de3bd),
-+     TOBN(0x8dce92f4, 0xa140a800), TOBN(0x85f44d1e, 0x1337af07),
-+     TOBN(0x5953c08b, 0x09d64c52), TOBN(0xa1b5e49f, 0xf5df9749),
-+     TOBN(0x336a8fb8, 0x52735f7d), TOBN(0xb332b6db, 0x9add676b),
-+     TOBN(0x558b88a0, 0xb4511aa4), TOBN(0x09788752, 0xdbd5cc55),
-+     TOBN(0x16b43b9c, 0xd8cd52bd), TOBN(0x7f0bc5a0, 0xc2a2696b),
-+     TOBN(0x146e12d4, 0xc11f61ef), TOBN(0x9ce10754, 0x3a83e79e),
-+     TOBN(0x08ec73d9, 0x6cbfca15), TOBN(0x09ff29ad, 0x5b49653f),
-+     TOBN(0xe31b72bd, 0xe7da946e), TOBN(0xebf9eb3b, 0xee80a4f2),
-+     TOBN(0xd1aabd08, 0x17598ce4), TOBN(0x18b5fef4, 0x53f37e80),
-+     TOBN(0xd5d5cdd3, 0x5958cd79), TOBN(0x3580a1b5, 0x1d373114),
-+     TOBN(0xa36e4c91, 0xfa935726), TOBN(0xa38c534d, 0xef20d760),
-+     TOBN(0x7088e40a, 0x2ff5845b), TOBN(0xe5bb40bd, 0xbd78177f),
-+     TOBN(0x4f06a7a8, 0x857f9920), TOBN(0xe3cc3e50, 0xe968f05d),
-+     TOBN(0x1d68b7fe, 0xe5682d26), TOBN(0x5206f76f, 0xaec7f87c),
-+     TOBN(0x41110530, 0x041951ab), TOBN(0x58ec52c1, 0xd4b5a71a),
-+     TOBN(0xf3488f99, 0x0f75cf9a), TOBN(0xf411951f, 0xba82d0d5),
-+     TOBN(0x27ee75be, 0x618895ab), TOBN(0xeae060d4, 0x6d8aab14),
-+     TOBN(0x9ae1df73, 0x7fb54dc2), TOBN(0x1f3e391b, 0x25963649),
-+     TOBN(0x242ec32a, 0xfe055081), TOBN(0x5bd450ef, 0x8491c9bd),
-+     TOBN(0x367efc67, 0x981eb389), TOBN(0xed7e1928, 0x3a0550d5),
-+     TOBN(0x362e776b, 0xab3ce75c), TOBN(0xe890e308, 0x1f24c523),
-+     TOBN(0xb961b682, 0xfeccef76), TOBN(0x8b8e11f5, 0x8bba6d92),
-+     TOBN(0x8f2ccc4c, 0x2b2375c4), TOBN(0x0d7f7a52, 0xe2f86cfa),
-+     TOBN(0xfd94d30a, 0x9efe5633), TOBN(0x2d8d246b, 0x5451f934),
-+     TOBN(0x2234c6e3, 0x244e6a00), TOBN(0xde2b5b0d, 0xddec8c50),
-+     TOBN(0x2ce53c5a, 0xbf776f5b), TOBN(0x6f724071, 0x60357b05),
-+     TOBN(0xb2593717, 0x71bf3f7a), TOBN(0x87d2501c, 0x440c4a9f),
-+     TOBN(0x440552e1, 0x87b05340), TOBN(0xb7bf7cc8, 0x21624c32),
-+     TOBN(0x4155a6ce, 0x22facddb), TOBN(0x5a4228cb, 0x889837ef),
-+     TOBN(0xef87d6d6, 0xfd4fd671), TOBN(0xa233687e, 0xc2daa10e),
-+     TOBN(0x75622244, 0x03c0eb96), TOBN(0x7632d184, 0x8bf19be6),
-+     TOBN(0x05d0f8e9, 0x40735ff4), TOBN(0x3a3e6e13, 0xc00931f1),
-+     TOBN(0x31ccde6a, 0xdafe3f18), TOBN(0xf381366a, 0xcfe51207),
-+     TOBN(0x24c222a9, 0x60167d92), TOBN(0x62f9d6f8, 0x7529f18c),
-+     TOBN(0x412397c0, 0x0353b114), TOBN(0x334d89dc, 0xef808043),
-+     TOBN(0xd9ec63ba, 0x2a4383ce), TOBN(0xcec8e937, 0x5cf92ba0),
-+     TOBN(0xfb8b4288, 0xc8be74c0), TOBN(0x67d6912f, 0x105d4391),
-+     TOBN(0x7b996c46, 0x1b913149), TOBN(0x36aae2ef, 0x3a4e02da),
-+     TOBN(0xb68aa003, 0x972de594), TOBN(0x284ec70d, 0x4ec6d545),
-+     TOBN(0xf3d2b2d0, 0x61391d54), TOBN(0x69c5d5d6, 0xfe114e92),
-+     TOBN(0xbe0f00b5, 0xb4482dff), TOBN(0xe1596fa5, 0xf5bf33c5),
-+     TOBN(0x10595b56, 0x96a71cba), TOBN(0x944938b2, 0xfdcadeb7),
-+     TOBN(0xa282da4c, 0xfccd8471), TOBN(0x98ec05f3, 0x0d37bfe1),
-+     TOBN(0xe171ce1b, 0x0698304a), TOBN(0x2d691444, 0x21bdf79b),
-+     TOBN(0xd0cd3b74, 0x1b21dec1), TOBN(0x712ecd8b, 0x16a15f71),
-+     TOBN(0x8d4c00a7, 0x00fd56e1), TOBN(0x02ec9692, 0xf9527c18),
-+     TOBN(0x21c44937, 0x4a3e42e1), TOBN(0x9176fbab, 0x1392ae0a),
-+     TOBN(0x8726f1ba, 0x44b7b618), TOBN(0xb4d7aae9, 0xf1de491c),
-+     TOBN(0xf91df7b9, 0x07b582c0), TOBN(0x7e116c30, 0xef60aa3a),
-+     TOBN(0x99270f81, 0x466265d7), TOBN(0xb15b6fe2, 0x4df7adf0),
-+     TOBN(0xfe33b2d3, 0xf9738f7f), TOBN(0x48553ab9, 0xd6d70f95),
-+     TOBN(0x2cc72ac8, 0xc21e94db), TOBN(0x795ac38d, 0xbdc0bbee),
-+     TOBN(0x0a1be449, 0x2e40478f), TOBN(0x81bd3394, 0x052bde55),
-+     TOBN(0x63c8dbe9, 0x56b3c4f2), TOBN(0x017a99cf, 0x904177cc),
-+     TOBN(0x947bbddb, 0x4d010fc1), TOBN(0xacf9b00b, 0xbb2c9b21),
-+     TOBN(0x2970bc8d, 0x47173611), TOBN(0x1a4cbe08, 0xac7d756f),
-+     TOBN(0x06d9f4aa, 0x67d541a2), TOBN(0xa3e8b689, 0x59c2cf44),
-+     TOBN(0xaad066da, 0x4d88f1dd), TOBN(0xc604f165, 0x7ad35dea),
-+     TOBN(0x7edc0720, 0x4478ca67), TOBN(0xa10dfae0, 0xba02ce06),
-+     TOBN(0xeceb1c76, 0xaf36f4e4), TOBN(0x994b2292, 0xaf3f8f48),
-+     TOBN(0xbf9ed77b, 0x77c8a68c), TOBN(0x74f544ea, 0x51744c9d),
-+     TOBN(0x82d05bb9, 0x8113a757), TOBN(0x4ef2d2b4, 0x8a9885e4),
-+     TOBN(0x1e332be5, 0x1aa7865f), TOBN(0x22b76b18, 0x290d1a52),
-+     TOBN(0x308a2310, 0x44351683), TOBN(0x9d861896, 0xa3f22840),
-+     TOBN(0x5959ddcd, 0x841ed947), TOBN(0x0def0c94, 0x154b73bf),
-+     TOBN(0xf0105417, 0x4c7c15e0), TOBN(0x539bfb02, 0x3a277c32),
-+     TOBN(0xe699268e, 0xf9dccf5f), TOBN(0x9f5796a5, 0x0247a3bd),
-+     TOBN(0x8b839de8, 0x4f157269), TOBN(0xc825c1e5, 0x7a30196b),
-+     TOBN(0x6ef0aabc, 0xdc8a5a91), TOBN(0xf4a8ce6c, 0x498b7fe6),
-+     TOBN(0x1cce35a7, 0x70cbac78), TOBN(0x83488e9b, 0xf6b23958),
-+     TOBN(0x0341a070, 0xd76cb011), TOBN(0xda6c9d06, 0xae1b2658),
-+     TOBN(0xb701fb30, 0xdd648c52), TOBN(0x994ca02c, 0x52fb9fd1),
-+     TOBN(0x06933117, 0x6f563086), TOBN(0x3d2b8100, 0x17856bab),
-+     TOBN(0xe89f48c8, 0x5963a46e), TOBN(0x658ab875, 0xa99e61c7),
-+     TOBN(0x6e296f87, 0x4b8517b4), TOBN(0x36c4fcdc, 0xfc1bc656),
-+     TOBN(0xde5227a1, 0xa3906def), TOBN(0x9fe95f57, 0x62418945),
-+     TOBN(0x20c91e81, 0xfdd96cde), TOBN(0x5adbe47e, 0xda4480de),
-+     TOBN(0xa009370f, 0x396de2b6), TOBN(0x98583d4b, 0xf0ecc7bd),
-+     TOBN(0xf44f6b57, 0xe51d0672), TOBN(0x03d6b078, 0x556b1984),
-+     TOBN(0x27dbdd93, 0xb0b64912), TOBN(0x9b3a3434, 0x15687b09),
-+     TOBN(0x0dba6461, 0x51ec20a9), TOBN(0xec93db7f, 0xff28187c),
-+     TOBN(0x00ff8c24, 0x66e48bdd), TOBN(0x2514f2f9, 0x11ccd78e),
-+     TOBN(0xeba11f4f, 0xe1250603), TOBN(0x8a22cd41, 0x243fa156),
-+     TOBN(0xa4e58df4, 0xb283e4c6), TOBN(0x78c29859, 0x8b39783f),
-+     TOBN(0x5235aee2, 0xa5259809), TOBN(0xc16284b5, 0x0e0227dd),
-+     TOBN(0xa5f57916, 0x1338830d), TOBN(0x6d4b8a6b, 0xd2123fca),
-+     TOBN(0x236ea68a, 0xf9c546f8), TOBN(0xc1d36873, 0xfa608d36),
-+     TOBN(0xcd76e495, 0x8d436d13), TOBN(0xd4d9c221, 0x8fb080af),
-+     TOBN(0x665c1728, 0xe8ad3fb5), TOBN(0xcf1ebe4d, 0xb3d572e0),
-+     TOBN(0xa7a8746a, 0x584c5e20), TOBN(0x267e4ea1, 0xb9dc7035),
-+     TOBN(0x593a15cf, 0xb9548c9b), TOBN(0x5e6e2135, 0x4bd012f3),
-+     TOBN(0xdf31cc6a, 0x8c8f936e), TOBN(0x8af84d04, 0xb5c241dc),
-+     TOBN(0x63990a6f, 0x345efb86), TOBN(0x6fef4e61, 0xb9b962cb)}
-+    ,
-+    {TOBN(0xf6368f09, 0x25722608), TOBN(0x131260db, 0x131cf5c6),
-+     TOBN(0x40eb353b, 0xfab4f7ac), TOBN(0x85c78880, 0x37eee829),
-+     TOBN(0x4c1581ff, 0xc3bdf24e), TOBN(0x5bff75cb, 0xf5c3c5a8),
-+     TOBN(0x35e8c83f, 0xa14e6f40), TOBN(0xb81d1c0f, 0x0295e0ca),
-+     TOBN(0xfcde7cc8, 0xf43a730f), TOBN(0xe89b6f3c, 0x33ab590e),
-+     TOBN(0xc823f529, 0xad03240b), TOBN(0x82b79afe, 0x98bea5db),
-+     TOBN(0x568f2856, 0x962fe5de), TOBN(0x0c590adb, 0x60c591f3),
-+     TOBN(0x1fc74a14, 0x4a28a858), TOBN(0x3b662498, 0xb3203f4c),
-+     TOBN(0x91e3cf0d, 0x6c39765a), TOBN(0xa2db3acd, 0xac3cca0b),
-+     TOBN(0x288f2f08, 0xcb953b50), TOBN(0x2414582c, 0xcf43cf1a),
-+     TOBN(0x8dec8bbc, 0x60eee9a8), TOBN(0x54c79f02, 0x729aa042),
-+     TOBN(0xd81cd5ec, 0x6532f5d5), TOBN(0xa672303a, 0xcf82e15f),
-+     TOBN(0x376aafa8, 0x719c0563), TOBN(0xcd8ad2dc, 0xbc5fc79f),
-+     TOBN(0x303fdb9f, 0xcb750cd3), TOBN(0x14ff052f, 0x4418b08e),
-+     TOBN(0xf75084cf, 0x3e2d6520), TOBN(0x7ebdf0f8, 0x144ed509),
-+     TOBN(0xf43bf0f2, 0xd3f25b98), TOBN(0x86ad71cf, 0xa354d837),
-+     TOBN(0xb827fe92, 0x26f43572), TOBN(0xdfd3ab5b, 0x5d824758),
-+     TOBN(0x315dd23a, 0x539094c1), TOBN(0x85c0e37a, 0x66623d68),
-+     TOBN(0x575c7972, 0x7be19ae0), TOBN(0x616a3396, 0xdf0d36b5),
-+     TOBN(0xa1ebb3c8, 0x26b1ff7e), TOBN(0x635b9485, 0x140ad453),
-+     TOBN(0x92bf3cda, 0xda430c0b), TOBN(0x4702850e, 0x3a96dac6),
-+     TOBN(0xc91cf0a5, 0x15ac326a), TOBN(0x95de4f49, 0xab8c25e4),
-+     TOBN(0xb01bad09, 0xe265c17c), TOBN(0x24e45464, 0x087b3881),
-+     TOBN(0xd43e583c, 0xe1fac5ca), TOBN(0xe17cb318, 0x6ead97a6),
-+     TOBN(0x6cc39243, 0x74dcec46), TOBN(0x33cfc02d, 0x54c2b73f),
-+     TOBN(0x82917844, 0xf26cd99c), TOBN(0x8819dd95, 0xd1773f89),
-+     TOBN(0x09572aa6, 0x0871f427), TOBN(0x8e0cf365, 0xf6f01c34),
-+     TOBN(0x7fa52988, 0xbff1f5af), TOBN(0x4eb357ea, 0xe75e8e50),
-+     TOBN(0xd9d0c8c4, 0x868af75d), TOBN(0xd7325cff, 0x45c8c7ea),
-+     TOBN(0xab471996, 0xcc81ecb0), TOBN(0xff5d55f3, 0x611824ed),
-+     TOBN(0xbe314541, 0x1977a0ee), TOBN(0x5085c4c5, 0x722038c6),
-+     TOBN(0x2d5335bf, 0xf94bb495), TOBN(0x894ad8a6, 0xc8e2a082),
-+     TOBN(0x5c3e2341, 0xada35438), TOBN(0xf4a9fc89, 0x049b8c4e),
-+     TOBN(0xbeeb355a, 0x9f17cf34), TOBN(0x3f311e0e, 0x6c91fe10),
-+     TOBN(0xc2d20038, 0x92ab9891), TOBN(0x257bdcc1, 0x3e8ce9a9),
-+     TOBN(0x1b2d9789, 0x88c53bee), TOBN(0x927ce89a, 0xcdba143a),
-+     TOBN(0xb0a32cca, 0x523db280), TOBN(0x5c889f8a, 0x50d43783),
-+     TOBN(0x503e04b3, 0x4897d16f), TOBN(0x8cdb6e78, 0x08f5f2e8),
-+     TOBN(0x6ab91cf0, 0x179c8e74), TOBN(0xd8874e52, 0x48211d60),
-+     TOBN(0xf948d4d5, 0xea851200), TOBN(0x4076d41e, 0xe6f9840a),
-+     TOBN(0xc20e263c, 0x47b517ea), TOBN(0x79a448fd, 0x30685e5e),
-+     TOBN(0xe55f6f78, 0xf90631a0), TOBN(0x88a790b1, 0xa79e6346),
-+     TOBN(0x62160c7d, 0x80969fe8), TOBN(0x54f92fd4, 0x41491bb9),
-+     TOBN(0xa6645c23, 0x5c957526), TOBN(0xf44cc5ae, 0xbea3ce7b),
-+     TOBN(0xf7628327, 0x8b1e68b7), TOBN(0xc731ad7a, 0x303f29d3),
-+     TOBN(0xfe5a9ca9, 0x57d03ecb), TOBN(0x96c0d50c, 0x41bc97a7),
-+     TOBN(0xc4669fe7, 0x9b4f7f24), TOBN(0xfdd781d8, 0x3d9967ef),
-+     TOBN(0x7892c7c3, 0x5d2c208d), TOBN(0x8bf64f7c, 0xae545cb3),
-+     TOBN(0xc01f862c, 0x467be912), TOBN(0xf4c85ee9, 0xc73d30cc),
-+     TOBN(0x1fa6f4be, 0x6ab83ec7), TOBN(0xa07a3c1c, 0x4e3e3cf9),
-+     TOBN(0x87f8ef45, 0x0c00beb3), TOBN(0x30e2c2b3, 0x000d4c3e),
-+     TOBN(0x1aa00b94, 0xfe08bf5b), TOBN(0x32c133aa, 0x9224ef52),
-+     TOBN(0x38df16bb, 0x32e5685d), TOBN(0x68a9e069, 0x58e6f544),
-+     TOBN(0x495aaff7, 0xcdc5ebc6), TOBN(0xf894a645, 0x378b135f),
-+     TOBN(0xf316350a, 0x09e27ecf), TOBN(0xeced201e, 0x58f7179d),
-+     TOBN(0x2eec273c, 0xe97861ba), TOBN(0x47ec2cae, 0xd693be2e),
-+     TOBN(0xfa4c97c4, 0xf68367ce), TOBN(0xe4f47d0b, 0xbe5a5755),
-+     TOBN(0x17de815d, 0xb298a979), TOBN(0xd7eca659, 0xc177dc7d),
-+     TOBN(0x20fdbb71, 0x49ded0a3), TOBN(0x4cb2aad4, 0xfb34d3c5),
-+     TOBN(0x2cf31d28, 0x60858a33), TOBN(0x3b6873ef, 0xa24aa40f),
-+     TOBN(0x540234b2, 0x2c11bb37), TOBN(0x2d0366dd, 0xed4c74a3),
-+     TOBN(0xf9a968da, 0xeec5f25d), TOBN(0x36601068, 0x67b63142),
-+     TOBN(0x07cd6d2c, 0x68d7b6d4), TOBN(0xa8f74f09, 0x0c842942),
-+     TOBN(0xe2751404, 0x7768b1ee), TOBN(0x4b5f7e89, 0xfe62aee4),
-+     TOBN(0xc6a77177, 0x89070d26), TOBN(0xa1f28e4e, 0xdd1c8bc7),
-+     TOBN(0xea5f4f06, 0x469e1f17), TOBN(0x78fc242a, 0xfbdb78e0),
-+     TOBN(0xc9c7c592, 0x8b0588f1), TOBN(0xb6b7a0fd, 0x1535921e),
-+     TOBN(0xcc5bdb91, 0xbde5ae35), TOBN(0xb42c485e, 0x12ff1864),
-+     TOBN(0xa1113e13, 0xdbab98aa), TOBN(0xde9d469b, 0xa17b1024),
-+     TOBN(0x23f48b37, 0xc0462d3a), TOBN(0x3752e537, 0x7c5c078d),
-+     TOBN(0xe3a86add, 0x15544eb9), TOBN(0xf013aea7, 0x80fba279),
-+     TOBN(0x8b5bb76c, 0xf22001b5), TOBN(0xe617ba14, 0xf02891ab),
-+     TOBN(0xd39182a6, 0x936219d3), TOBN(0x5ce1f194, 0xae51cb19),
-+     TOBN(0xc78f8598, 0xbf07a74c), TOBN(0x6d7158f2, 0x22cbf1bc),
-+     TOBN(0x3b846b21, 0xe300ce18), TOBN(0x35fba630, 0x2d11275d),
-+     TOBN(0x5fe25c36, 0xa0239b9b), TOBN(0xd8beb35d, 0xdf05d940),
-+     TOBN(0x4db02bb0, 0x1f7e320d), TOBN(0x0641c364, 0x6da320ea),
-+     TOBN(0x6d95fa5d, 0x821389a3), TOBN(0x92699748, 0x8fcd8e3d),
-+     TOBN(0x316fef17, 0xceb6c143), TOBN(0x67fcb841, 0xd933762b),
-+     TOBN(0xbb837e35, 0x118b17f8), TOBN(0x4b92552f, 0x9fd24821),
-+     TOBN(0xae6bc70e, 0x46aca793), TOBN(0x1cf0b0e4, 0xe579311b),
-+     TOBN(0x8dc631be, 0x5802f716), TOBN(0x099bdc6f, 0xbddbee4d),
-+     TOBN(0xcc352bb2, 0x0caf8b05), TOBN(0xf74d505a, 0x72d63df2),
-+     TOBN(0xb9876d4b, 0x91c4f408), TOBN(0x1ce18473, 0x9e229b2d),
-+     TOBN(0x49507597, 0x83abdb4a), TOBN(0x850fbcb6, 0xdee84b18),
-+     TOBN(0x6325236e, 0x609e67dc), TOBN(0x04d831d9, 0x9336c6d8),
-+     TOBN(0x8deaae3b, 0xfa12d45d), TOBN(0xe425f8ce, 0x4746e246),
-+     TOBN(0x8004c175, 0x24f5f31e), TOBN(0xaca16d8f, 0xad62c3b7),
-+     TOBN(0x0dc15a6a, 0x9152f934), TOBN(0xf1235e5d, 0xed0e12c1),
-+     TOBN(0xc33c06ec, 0xda477dac), TOBN(0x76be8732, 0xb2ea0006),
-+     TOBN(0xcf3f7831, 0x0c0cd313), TOBN(0x3c524553, 0xa614260d),
-+     TOBN(0x31a756f8, 0xcab22d15), TOBN(0x03ee10d1, 0x77827a20),
-+     TOBN(0xd1e059b2, 0x1994ef20), TOBN(0x2a653b69, 0x638ae318),
-+     TOBN(0x70d5eb58, 0x2f699010), TOBN(0x279739f7, 0x09f5f84a),
-+     TOBN(0x5da4663c, 0x8b799336), TOBN(0xfdfdf14d, 0x203c37eb),
-+     TOBN(0x32d8a9dc, 0xa1dbfb2d), TOBN(0xab40cff0, 0x77d48f9b),
-+     TOBN(0xc018b383, 0xd20b42d5), TOBN(0xf9a810ef, 0x9f78845f),
-+     TOBN(0x40af3753, 0xbdba9df0), TOBN(0xb90bdcfc, 0x131dfdf9),
-+     TOBN(0x18720591, 0xf01ab782), TOBN(0xc823f211, 0x6af12a88),
-+     TOBN(0xa51b80f3, 0x0dc14401), TOBN(0xde248f77, 0xfb2dfbe3),
-+     TOBN(0xef5a44e5, 0x0cafe751), TOBN(0x73997c9c, 0xd4dcd221),
-+     TOBN(0x32fd86d1, 0xde854024), TOBN(0xd5b53adc, 0xa09b84bb),
-+     TOBN(0x008d7a11, 0xdcedd8d1), TOBN(0x406bd1c8, 0x74b32c84),
-+     TOBN(0x5d4472ff, 0x05dde8b1), TOBN(0x2e25f2cd, 0xfce2b32f),
-+     TOBN(0xbec0dd5e, 0x29dfc254), TOBN(0x4455fcf6, 0x2b98b267),
-+     TOBN(0x0b4d43a5, 0xc72df2ad), TOBN(0xea70e6be, 0x48a75397),
-+     TOBN(0x2aad6169, 0x5820f3bf), TOBN(0xf410d2dd, 0x9e37f68f),
-+     TOBN(0x70fb7dba, 0x7be5ac83), TOBN(0x636bb645, 0x36ec3eec),
-+     TOBN(0x27104ea3, 0x9754e21c), TOBN(0xbc87a3e6, 0x8d63c373),
-+     TOBN(0x483351d7, 0x4109db9a), TOBN(0x0fa724e3, 0x60134da7),
-+     TOBN(0x9ff44c29, 0xb0720b16), TOBN(0x2dd0cf13, 0x06aceead),
-+     TOBN(0x5942758c, 0xe26929a6), TOBN(0x96c5db92, 0xb766a92b),
-+     TOBN(0xcec7d4c0, 0x5f18395e), TOBN(0xd3f22744, 0x1f80d032),
-+     TOBN(0x7a68b37a, 0xcb86075b), TOBN(0x074764dd, 0xafef92db),
-+     TOBN(0xded1e950, 0x7bc7f389), TOBN(0xc580c850, 0xb9756460),
-+     TOBN(0xaeeec2a4, 0x7da48157), TOBN(0x3f0b4e7f, 0x82c587b3),
-+     TOBN(0x231c6de8, 0xa9f19c53), TOBN(0x5717bd73, 0x6974e34e),
-+     TOBN(0xd9e1d216, 0xf1508fa9), TOBN(0x9f112361, 0xdadaa124),
-+     TOBN(0x80145e31, 0x823b7348), TOBN(0x4dd8f0d5, 0xac634069),
-+     TOBN(0xe3d82fc7, 0x2297c258), TOBN(0x276fcfee, 0x9cee7431),
-+     TOBN(0x8eb61b5e, 0x2bc0aea9), TOBN(0x4f668fd5, 0xde329431),
-+     TOBN(0x03a32ab1, 0x38e4b87e), TOBN(0xe1374517, 0x73d0ef0b),
-+     TOBN(0x1a46f7e6, 0x853ac983), TOBN(0xc3bdf42e, 0x68e78a57),
-+     TOBN(0xacf20785, 0x2ea96dd1), TOBN(0xa10649b9, 0xf1638460),
-+     TOBN(0xf2369f0b, 0x879fbbed), TOBN(0x0ff0ae86, 0xda9d1869),
-+     TOBN(0x5251d759, 0x56766f45), TOBN(0x4984d8c0, 0x2be8d0fc),
-+     TOBN(0x7ecc95a6, 0xd21008f0), TOBN(0x29bd54a0, 0x3a1a1c49),
-+     TOBN(0xab9828c5, 0xd26c50f3), TOBN(0x32c0087c, 0x51d0d251),
-+     TOBN(0x9bac3ce6, 0x0c1cdb26), TOBN(0xcd94d947, 0x557ca205),
-+     TOBN(0x1b1bd598, 0x9db1fdcd), TOBN(0x0eda0108, 0xa3d8b149),
-+     TOBN(0x95066610, 0x56152fcc), TOBN(0xc2f037e6, 0xe7192b33),
-+     TOBN(0xdeffb41a, 0xc92e05a4), TOBN(0x1105f6c2, 0xc2f6c62e),
-+     TOBN(0x68e73500, 0x8733913c), TOBN(0xcce86163, 0x3f3adc40),
-+     TOBN(0xf407a942, 0x38a278e9), TOBN(0xd13c1b9d, 0x2ab21292),
-+     TOBN(0x93ed7ec7, 0x1c74cf5c), TOBN(0x8887dc48, 0xf1a4c1b4),
-+     TOBN(0x3830ff30, 0x4b3a11f1), TOBN(0x358c5a3c, 0x58937cb6),
-+     TOBN(0x027dc404, 0x89022829), TOBN(0x40e93977, 0x3b798f79),
-+     TOBN(0x90ad3337, 0x38be6ead), TOBN(0x9c23f6bc, 0xf34c0a5d),
-+     TOBN(0xd1711a35, 0xfbffd8bb), TOBN(0x60fcfb49, 0x1949d3dd),
-+     TOBN(0x09c8ef4b, 0x7825d93a), TOBN(0x24233cff, 0xa0a8c968),
-+     TOBN(0x67ade46c, 0xe6d982af), TOBN(0xebb6bf3e, 0xe7544d7c),
-+     TOBN(0xd6b9ba76, 0x3d8bd087), TOBN(0x46fe382d, 0x4dc61280),
-+     TOBN(0xbd39a7e8, 0xb5bdbd75), TOBN(0xab381331, 0xb8f228fe),
-+     TOBN(0x0709a77c, 0xce1c4300), TOBN(0x6a247e56, 0xf337ceac),
-+     TOBN(0x8f34f21b, 0x636288be), TOBN(0x9dfdca74, 0xc8a7c305),
-+     TOBN(0x6decfd1b, 0xea919e04), TOBN(0xcdf2688d, 0x8e1991f8),
-+     TOBN(0xe607df44, 0xd0f8a67e), TOBN(0xd985df4b, 0x0b58d010),
-+     TOBN(0x57f834c5, 0x0c24f8f4), TOBN(0xe976ef56, 0xa0bf01ae),
-+     TOBN(0x536395ac, 0xa1c32373), TOBN(0x351027aa, 0x734c0a13),
-+     TOBN(0xd2f1b5d6, 0x5e6bd5bc), TOBN(0x2b539e24, 0x223debed),
-+     TOBN(0xd4994cec, 0x0eaa1d71), TOBN(0x2a83381d, 0x661dcf65),
-+     TOBN(0x5f1aed2f, 0x7b54c740), TOBN(0x0bea3fa5, 0xd6dda5ee),
-+     TOBN(0x9d4fb684, 0x36cc6134), TOBN(0x8eb9bbf3, 0xc0a443dd),
-+     TOBN(0xfc500e2e, 0x383b7d2a), TOBN(0x7aad621c, 0x5b775257),
-+     TOBN(0x69284d74, 0x0a8f7cc0), TOBN(0xe820c2ce, 0x07562d65),
-+     TOBN(0xbf9531b9, 0x499758ee), TOBN(0x73e95ca5, 0x6ee0cc2d),
-+     TOBN(0xf61790ab, 0xfbaf50a5), TOBN(0xdf55e76b, 0x684e0750),
-+     TOBN(0xec516da7, 0xf176b005), TOBN(0x575553bb, 0x7a2dddc7),
-+     TOBN(0x37c87ca3, 0x553afa73), TOBN(0x315f3ffc, 0x4d55c251),
-+     TOBN(0xe846442a, 0xaf3e5d35), TOBN(0x61b91149, 0x6495ff28),
-+     TOBN(0x23cc95d3, 0xfa326dc3), TOBN(0x1df4da1f, 0x18fc2cea),
-+     TOBN(0x24bf9adc, 0xd0a37d59), TOBN(0xb6710053, 0x320d6e1e),
-+     TOBN(0x96f9667e, 0x618344d1), TOBN(0xcc7ce042, 0xa06445af),
-+     TOBN(0xa02d8514, 0xd68dbc3a), TOBN(0x4ea109e4, 0x280b5a5b),
-+     TOBN(0x5741a7ac, 0xb40961bf), TOBN(0x4ada5937, 0x6aa56bfa),
-+     TOBN(0x7feb9145, 0x02b765d1), TOBN(0x561e97be, 0xe6ad1582),
-+     TOBN(0xbbc4a5b6, 0xda3982f5), TOBN(0x0c2659ed, 0xb546f468),
-+     TOBN(0xb8e7e6aa, 0x59612d20), TOBN(0xd83dfe20, 0xac19e8e0),
-+     TOBN(0x8530c45f, 0xb835398c), TOBN(0x6106a8bf, 0xb38a41c2),
-+     TOBN(0x21e8f9a6, 0x35f5dcdb), TOBN(0x39707137, 0xcae498ed),
-+     TOBN(0x70c23834, 0xd8249f00), TOBN(0x9f14b58f, 0xab2537a0),
-+     TOBN(0xd043c365, 0x5f61c0c2), TOBN(0xdc5926d6, 0x09a194a7),
-+     TOBN(0xddec0339, 0x8e77738a), TOBN(0xd07a63ef, 0xfba46426),
-+     TOBN(0x2e58e79c, 0xee7f6e86), TOBN(0xe59b0459, 0xff32d241),
-+     TOBN(0xc5ec84e5, 0x20fa0338), TOBN(0x97939ac8, 0xeaff5ace),
-+     TOBN(0x0310a4e3, 0xb4a38313), TOBN(0x9115fba2, 0x8f9d9885),
-+     TOBN(0x8dd710c2, 0x5fadf8c3), TOBN(0x66be38a2, 0xce19c0e2),
-+     TOBN(0xd42a279c, 0x4cfe5022), TOBN(0x597bb530, 0x0e24e1b8),
-+     TOBN(0x3cde86b7, 0xc153ca7f), TOBN(0xa8d30fb3, 0x707d63bd),
-+     TOBN(0xac905f92, 0xbd60d21e), TOBN(0x98e7ffb6, 0x7b9a54ab),
-+     TOBN(0xd7147df8, 0xe9726a30), TOBN(0xb5e216ff, 0xafce3533),
-+     TOBN(0xb550b799, 0x2ff1ec40), TOBN(0x6b613b87, 0xa1e953fd),
-+     TOBN(0x87b88dba, 0x792d5610), TOBN(0x2ee1270a, 0xa190fbe1),
-+     TOBN(0x02f4e2dc, 0x2ef581da), TOBN(0x016530e4, 0xeff82a95),
-+     TOBN(0xcbb93dfd, 0x8fd6ee89), TOBN(0x16d3d986, 0x46848fff),
-+     TOBN(0x600eff24, 0x1da47adf), TOBN(0x1b9754a0, 0x0ad47a71),
-+     TOBN(0x8f9266df, 0x70c33b98), TOBN(0xaadc87ae, 0xdf34186e),
-+     TOBN(0x0d2ce8e1, 0x4ad24132), TOBN(0x8a47cbfc, 0x19946eba),
-+     TOBN(0x47feeb66, 0x62b5f3af), TOBN(0xcefab561, 0x0abb3734),
-+     TOBN(0x449de60e, 0x19f35cb1), TOBN(0x39f8db14, 0x157f0eb9),
-+     TOBN(0xffaecc5b, 0x3c61bfd6), TOBN(0xa5a4d41d, 0x41216703),
-+     TOBN(0x7f8fabed, 0x224e1cc2), TOBN(0x0d5a8186, 0x871ad953),
-+     TOBN(0xf10774f7, 0xd22da9a9), TOBN(0x45b8a678, 0xcc8a9b0d),
-+     TOBN(0xd9c2e722, 0xbdc32cff), TOBN(0xbf71b5f5, 0x337202a5),
-+     TOBN(0x95c57f2f, 0x69fc4db9), TOBN(0xb6dad34c, 0x765d01e1),
-+     TOBN(0x7e0bd13f, 0xcb904635), TOBN(0x61751253, 0x763a588c),
-+     TOBN(0xd85c2997, 0x81af2c2d), TOBN(0xc0f7d9c4, 0x81b9d7da),
-+     TOBN(0x838a34ae, 0x08533e8d), TOBN(0x15c4cb08, 0x311d8311),
-+     TOBN(0x97f83285, 0x8e121e14), TOBN(0xeea7dc1e, 0x85000a5f),
-+     TOBN(0x0c6059b6, 0x5d256274), TOBN(0xec9beace, 0xb95075c0),
-+     TOBN(0x173daad7, 0x1df97828), TOBN(0xbf851cb5, 0xa8937877),
-+     TOBN(0xb083c594, 0x01646f3c), TOBN(0x3bad30cf, 0x50c6d352),
-+     TOBN(0xfeb2b202, 0x496bbcea), TOBN(0x3cf9fd4f, 0x18a1e8ba),
-+     TOBN(0xd26de7ff, 0x1c066029), TOBN(0x39c81e9e, 0x4e9ed4f8),
-+     TOBN(0xd8be0cb9, 0x7b390d35), TOBN(0x01df2bbd, 0x964aab27),
-+     TOBN(0x3e8c1a65, 0xc3ef64f8), TOBN(0x567291d1, 0x716ed1dd),
-+     TOBN(0x95499c6c, 0x5f5406d3), TOBN(0x71fdda39, 0x5ba8e23f),
-+     TOBN(0xcfeb320e, 0xd5096ece), TOBN(0xbe7ba92b, 0xca66dd16),
-+     TOBN(0x4608d36b, 0xc6fb5a7d), TOBN(0xe3eea15a, 0x6d2dd0e0),
-+     TOBN(0x75b0a3eb, 0x8f97a36a), TOBN(0xf59814cc, 0x1c83de1e),
-+     TOBN(0x56c9c5b0, 0x1c33c23f), TOBN(0xa96c1da4, 0x6faa4136),
-+     TOBN(0x46bf2074, 0xde316551), TOBN(0x3b866e7b, 0x1f756c8f),
-+     TOBN(0x727727d8, 0x1495ed6b), TOBN(0xb2394243, 0xb682dce7),
-+     TOBN(0x8ab8454e, 0x758610f3), TOBN(0xc243ce84, 0x857d72a4),
-+     TOBN(0x7b320d71, 0xdbbf370f), TOBN(0xff9afa37, 0x78e0f7ca),
-+     TOBN(0x0119d1e0, 0xea7b523f), TOBN(0xb997f8cb, 0x058c7d42),
-+     TOBN(0x285bcd2a, 0x37bbb184), TOBN(0x51dcec49, 0xa45d1fa6),
-+     TOBN(0x6ade3b64, 0xe29634cb), TOBN(0x080c94a7, 0x26b86ef1),
-+     TOBN(0xba583db1, 0x2283fbe3), TOBN(0x902bddc8, 0x5a9315ed),
-+     TOBN(0x07c1ccb3, 0x86964bec), TOBN(0x78f4eacf, 0xb6258301),
-+     TOBN(0x4bdf3a49, 0x56f90823), TOBN(0xba0f5080, 0x741d777b),
-+     TOBN(0x091d71c3, 0xf38bf760), TOBN(0x9633d50f, 0x9b625b02),
-+     TOBN(0x03ecb743, 0xb8c9de61), TOBN(0xb4751254, 0x5de74720),
-+     TOBN(0x9f9defc9, 0x74ce1cb2), TOBN(0x774a4f6a, 0x00bd32ef),
-+     TOBN(0xaca385f7, 0x73848f22), TOBN(0x53dad716, 0xf3f8558e),
-+     TOBN(0xab7b34b0, 0x93c471f9), TOBN(0xf530e069, 0x19644bc7),
-+     TOBN(0x3d9fb1ff, 0xdd59d31a), TOBN(0x4382e0df, 0x08daa795),
-+     TOBN(0x165c6f4b, 0xd5cc88d7), TOBN(0xeaa392d5, 0x4a18c900),
-+     TOBN(0x94203c67, 0x648024ee), TOBN(0x188763f2, 0x8c2fabcd),
-+     TOBN(0xa80f87ac, 0xbbaec835), TOBN(0x632c96e0, 0xf29d8d54),
-+     TOBN(0x29b0a60e, 0x4c00a95e), TOBN(0x2ef17f40, 0xe011e9fa),
-+     TOBN(0xf6c0e1d1, 0x15b77223), TOBN(0xaaec2c62, 0x14b04e32),
-+     TOBN(0xd35688d8, 0x3d84e58c), TOBN(0x2af5094c, 0x958571db),
-+     TOBN(0x4fff7e19, 0x760682a6), TOBN(0x4cb27077, 0xe39a407c),
-+     TOBN(0x0f59c547, 0x4ff0e321), TOBN(0x169f34a6, 0x1b34c8ff),
-+     TOBN(0x2bff1096, 0x52bc1ba7), TOBN(0xa25423b7, 0x83583544),
-+     TOBN(0x5d55d5d5, 0x0ac8b782), TOBN(0xff6622ec, 0x2db3c892),
-+     TOBN(0x48fce741, 0x6b8bb642), TOBN(0x31d6998c, 0x69d7e3dc),
-+     TOBN(0xdbaf8004, 0xcadcaed0), TOBN(0x801b0142, 0xd81d053c),
-+     TOBN(0x94b189fc, 0x59630ec6), TOBN(0x120e9934, 0xaf762c8e),
-+     TOBN(0x53a29aa4, 0xfdc6a404), TOBN(0x19d8e01e, 0xa1909948),
-+     TOBN(0x3cfcabf1, 0xd7e89681), TOBN(0x3321a50d, 0x4e132d37),
-+     TOBN(0xd0496863, 0xe9a86111), TOBN(0x8c0cde61, 0x06a3bc65),
-+     TOBN(0xaf866c49, 0xfc9f8eef), TOBN(0x2066350e, 0xff7f5141),
-+     TOBN(0x4f8a4689, 0xe56ddfbd), TOBN(0xea1b0c07, 0xfe32983a),
-+     TOBN(0x2b317462, 0x873cb8cb), TOBN(0x658deddc, 0x2d93229f),
-+     TOBN(0x65efaf4d, 0x0f64ef58), TOBN(0xfe43287d, 0x730cc7a8),
-+     TOBN(0xaebc0c72, 0x3d047d70), TOBN(0x92efa539, 0xd92d26c9),
-+     TOBN(0x06e78457, 0x94b56526), TOBN(0x415cb80f, 0x0961002d),
-+     TOBN(0x89e5c565, 0x76dcb10f), TOBN(0x8bbb6982, 0xff9259fe),
-+     TOBN(0x4fe8795b, 0x9abc2668), TOBN(0xb5d4f534, 0x1e678fb1),
-+     TOBN(0x6601f3be, 0x7b7da2b9), TOBN(0x98da59e2, 0xa13d6805),
-+     TOBN(0x190d8ea6, 0x01799a52), TOBN(0xa20cec41, 0xb86d2952),
-+     TOBN(0x3062ffb2, 0x7fff2a7c), TOBN(0x741b32e5, 0x79f19d37),
-+     TOBN(0xf80d8181, 0x4eb57d47), TOBN(0x7a2d0ed4, 0x16aef06b),
-+     TOBN(0x09735fb0, 0x1cecb588), TOBN(0x1641caaa, 0xc6061f5b)}
-+    ,
-+    {TOBN(0x7f99824f, 0x20151427), TOBN(0x206828b6, 0x92430206),
-+     TOBN(0xaa9097d7, 0xe1112357), TOBN(0xacf9a2f2, 0x09e414ec),
-+     TOBN(0xdbdac9da, 0x27915356), TOBN(0x7e0734b7, 0x001efee3),
-+     TOBN(0x54fab5bb, 0xd2b288e2), TOBN(0x4c630fc4, 0xf62dd09c),
-+     TOBN(0x8537107a, 0x1ac2703b), TOBN(0xb49258d8, 0x6bc857b5),
-+     TOBN(0x57df14de, 0xbcdaccd1), TOBN(0x24ab68d7, 0xc4ae8529),
-+     TOBN(0x7ed8b5d4, 0x734e59d0), TOBN(0x5f8740c8, 0xc495cc80),
-+     TOBN(0x84aedd5a, 0x291db9b3), TOBN(0x80b360f8, 0x4fb995be),
-+     TOBN(0xae915f5d, 0x5fa067d1), TOBN(0x4134b57f, 0x9668960c),
-+     TOBN(0xbd3656d6, 0xa48edaac), TOBN(0xdac1e3e4, 0xfc1d7436),
-+     TOBN(0x674ff869, 0xd81fbb26), TOBN(0x449ed3ec, 0xb26c33d4),
-+     TOBN(0x85138705, 0xd94203e8), TOBN(0xccde538b, 0xbeeb6f4a),
-+     TOBN(0x55d5c68d, 0xa61a76fa), TOBN(0x598b441d, 0xca1554dc),
-+     TOBN(0xd39923b9, 0x773b279c), TOBN(0x33331d3c, 0x36bf9efc),
-+     TOBN(0x2d4c848e, 0x298de399), TOBN(0xcfdb8e77, 0xa1a27f56),
-+     TOBN(0x94c855ea, 0x57b8ab70), TOBN(0xdcdb9dae, 0x6f7879ba),
-+     TOBN(0x7bdff8c2, 0x019f2a59), TOBN(0xb3ce5bb3, 0xcb4fbc74),
-+     TOBN(0xea907f68, 0x8a9173dd), TOBN(0x6cd3d0d3, 0x95a75439),
-+     TOBN(0x92ecc4d6, 0xefed021c), TOBN(0x09a9f9b0, 0x6a77339a),
-+     TOBN(0x87ca6b15, 0x7188c64a), TOBN(0x10c29968, 0x44899158),
-+     TOBN(0x5859a229, 0xed6e82ef), TOBN(0x16f338e3, 0x65ebaf4e),
-+     TOBN(0x0cd31387, 0x5ead67ae), TOBN(0x1c73d228, 0x54ef0bb4),
-+     TOBN(0x4cb55131, 0x74a5c8c7), TOBN(0x01cd2970, 0x7f69ad6a),
-+     TOBN(0xa04d00dd, 0xe966f87e), TOBN(0xd96fe447, 0x0b7b0321),
-+     TOBN(0x342ac06e, 0x88fbd381), TOBN(0x02cd4a84, 0x5c35a493),
-+     TOBN(0xe8fa89de, 0x54f1bbcd), TOBN(0x341d6367, 0x2575ed4c),
-+     TOBN(0xebe357fb, 0xd238202b), TOBN(0x600b4d1a, 0xa984ead9),
-+     TOBN(0xc35c9f44, 0x52436ea0), TOBN(0x96fe0a39, 0xa370751b),
-+     TOBN(0x4c4f0736, 0x7f636a38), TOBN(0x9f943fb7, 0x0e76d5cb),
-+     TOBN(0xb03510ba, 0xa8b68b8b), TOBN(0xc246780a, 0x9ed07a1f),
-+     TOBN(0x3c051415, 0x6d549fc2), TOBN(0xc2953f31, 0x607781ca),
-+     TOBN(0x955e2c69, 0xd8d95413), TOBN(0xb300fadc, 0x7bd282e3),
-+     TOBN(0x81fe7b50, 0x87e9189f), TOBN(0xdb17375c, 0xf42dda27),
-+     TOBN(0x22f7d896, 0xcf0a5904), TOBN(0xa0e57c5a, 0xebe348e6),
-+     TOBN(0xa61011d3, 0xf40e3c80), TOBN(0xb1189321, 0x8db705c5),
-+     TOBN(0x4ed9309e, 0x50fedec3), TOBN(0xdcf14a10, 0x4d6d5c1d),
-+     TOBN(0x056c265b, 0x55691342), TOBN(0xe8e08504, 0x91049dc7),
-+     TOBN(0x131329f5, 0xc9bae20a), TOBN(0x96c8b3e8, 0xd9dccdb4),
-+     TOBN(0x8c5ff838, 0xfb4ee6b4), TOBN(0xfc5a9aeb, 0x41e8ccf0),
-+     TOBN(0x7417b764, 0xfae050c6), TOBN(0x0953c3d7, 0x00452080),
-+     TOBN(0x21372682, 0x38dfe7e8), TOBN(0xea417e15, 0x2bb79d4b),
-+     TOBN(0x59641f1c, 0x76e7cf2d), TOBN(0x271e3059, 0xea0bcfcc),
-+     TOBN(0x624c7dfd, 0x7253ecbd), TOBN(0x2f552e25, 0x4fca6186),
-+     TOBN(0xcbf84ecd, 0x4d866e9c), TOBN(0x73967709, 0xf68d4610),
-+     TOBN(0xa14b1163, 0xc27901b4), TOBN(0xfd9236e0, 0x899b8bf3),
-+     TOBN(0x42b091ec, 0xcbc6da0a), TOBN(0xbb1dac6f, 0x5ad1d297),
-+     TOBN(0x80e61d53, 0xa91cf76e), TOBN(0x4110a412, 0xd31f1ee7),
-+     TOBN(0x2d87c3ba, 0x13efcf77), TOBN(0x1f374bb4, 0xdf450d76),
-+     TOBN(0x5e78e2f2, 0x0d188dab), TOBN(0xe3968ed0, 0xf4b885ef),
-+     TOBN(0x46c0568e, 0x7314570f), TOBN(0x31616338, 0x01170521),
-+     TOBN(0x18e1e7e2, 0x4f0c8afe), TOBN(0x4caa75ff, 0xdeea78da),
-+     TOBN(0x82db67f2, 0x7c5d8a51), TOBN(0x36a44d86, 0x6f505370),
-+     TOBN(0xd72c5bda, 0x0333974f), TOBN(0x5db516ae, 0x27a70146),
-+     TOBN(0x34705281, 0x210ef921), TOBN(0xbff17a8f, 0x0c9c38e5),
-+     TOBN(0x78f4814e, 0x12476da1), TOBN(0xc1e16613, 0x33c16980),
-+     TOBN(0x9e5b386f, 0x424d4bca), TOBN(0x4c274e87, 0xc85740de),
-+     TOBN(0xb6a9b88d, 0x6c2f5226), TOBN(0x14d1b944, 0x550d7ca8),
-+     TOBN(0x580c85fc, 0x1fc41709), TOBN(0xc1da368b, 0x54c6d519),
-+     TOBN(0x2b0785ce, 0xd5113cf7), TOBN(0x0670f633, 0x5a34708f),
-+     TOBN(0x46e23767, 0x15cc3f88), TOBN(0x1b480cfa, 0x50c72c8f),
-+     TOBN(0x20288602, 0x4147519a), TOBN(0xd0981eac, 0x26b372f0),
-+     TOBN(0xa9d4a7ca, 0xa785ebc8), TOBN(0xd953c50d, 0xdbdf58e9),
-+     TOBN(0x9d6361cc, 0xfd590f8f), TOBN(0x72e9626b, 0x44e6c917),
-+     TOBN(0x7fd96110, 0x22eb64cf), TOBN(0x863ebb7e, 0x9eb288f3),
-+     TOBN(0x6e6ab761, 0x6aca8ee7), TOBN(0x97d10b39, 0xd7b40358),
-+     TOBN(0x1687d377, 0x1e5feb0d), TOBN(0xc83e50e4, 0x8265a27a),
-+     TOBN(0x8f75a9fe, 0xc954b313), TOBN(0xcc2e8f47, 0x310d1f61),
-+     TOBN(0xf5ba81c5, 0x6557d0e0), TOBN(0x25f9680c, 0x3eaf6207),
-+     TOBN(0xf95c6609, 0x4354080b), TOBN(0x5225bfa5, 0x7bf2fe1c),
-+     TOBN(0xc5c004e2, 0x5c7d98fa), TOBN(0x3561bf1c, 0x019aaf60),
-+     TOBN(0x5e6f9f17, 0xba151474), TOBN(0xdec2f934, 0xb04f6eca),
-+     TOBN(0x64e368a1, 0x269acb1e), TOBN(0x1332d9e4, 0x0cdda493),
-+     TOBN(0x60d6cf69, 0xdf23de05), TOBN(0x66d17da2, 0x009339a0),
-+     TOBN(0x9fcac985, 0x0a693923), TOBN(0xbcf057fc, 0xed7c6a6d),
-+     TOBN(0xc3c5c8c5, 0xf0b5662c), TOBN(0x25318dd8, 0xdcba4f24),
-+     TOBN(0x60e8cb75, 0x082b69ff), TOBN(0x7c23b3ee, 0x1e728c01),
-+     TOBN(0x15e10a0a, 0x097e4403), TOBN(0xcb3d0a86, 0x19854665),
-+     TOBN(0x88d8e211, 0xd67d4826), TOBN(0xb39af66e, 0x0b9d2839),
-+     TOBN(0xa5f94588, 0xbd475ca8), TOBN(0xe06b7966, 0xc077b80b),
-+     TOBN(0xfedb1485, 0xda27c26c), TOBN(0xd290d33a, 0xfe0fd5e0),
-+     TOBN(0xa40bcc47, 0xf34fb0fa), TOBN(0xb4760cc8, 0x1fb1ab09),
-+     TOBN(0x8fca0993, 0xa273bfe3), TOBN(0x13e4fe07, 0xf70b213c),
-+     TOBN(0x3bcdb992, 0xfdb05163), TOBN(0x8c484b11, 0x0c2b19b6),
-+     TOBN(0x1acb815f, 0xaaf2e3e2), TOBN(0xc6905935, 0xb89ff1b4),
-+     TOBN(0xb2ad6f9d, 0x586e74e1), TOBN(0x488883ad, 0x67b80484),
-+     TOBN(0x758aa2c7, 0x369c3ddb), TOBN(0x8ab74e69, 0x9f9afd31),
-+     TOBN(0x10fc2d28, 0x5e21beb1), TOBN(0x3484518a, 0x318c42f9),
-+     TOBN(0x377427dc, 0x53cf40c3), TOBN(0x9de0781a, 0x391bc1d9),
-+     TOBN(0x8faee858, 0x693807e1), TOBN(0xa3865327, 0x4e81ccc7),
-+     TOBN(0x02c30ff2, 0x6f835b84), TOBN(0xb604437b, 0x0d3d38d4),
-+     TOBN(0xb3fc8a98, 0x5ca1823d), TOBN(0xb82f7ec9, 0x03be0324),
-+     TOBN(0xee36d761, 0xcf684a33), TOBN(0x5a01df0e, 0x9f29bf7d),
-+     TOBN(0x686202f3, 0x1306583d), TOBN(0x05b10da0, 0x437c622e),
-+     TOBN(0xbf9aaa0f, 0x076a7bc8), TOBN(0x25e94efb, 0x8f8f4e43),
-+     TOBN(0x8a35c9b7, 0xfa3dc26d), TOBN(0xe0e5fb93, 0x96ff03c5),
-+     TOBN(0xa77e3843, 0xebc394ce), TOBN(0xcede6595, 0x8361de60),
-+     TOBN(0xd27c22f6, 0xa1993545), TOBN(0xab01cc36, 0x24d671ba),
-+     TOBN(0x63fa2877, 0xa169c28e), TOBN(0x925ef904, 0x2eb08376),
-+     TOBN(0x3b2fa3cf, 0x53aa0b32), TOBN(0xb27beb5b, 0x71c49d7a),
-+     TOBN(0xb60e1834, 0xd105e27f), TOBN(0xd6089788, 0x4f68570d),
-+     TOBN(0x23094ce0, 0xd6fbc2ac), TOBN(0x738037a1, 0x815ff551),
-+     TOBN(0xda73b1bb, 0x6bef119c), TOBN(0xdcf6c430, 0xeef506ba),
-+     TOBN(0x00e4fe7b, 0xe3ef104a), TOBN(0xebdd9a2c, 0x0a065628),
-+     TOBN(0x853a81c3, 0x8792043e), TOBN(0x22ad6ece, 0xb3b59108),
-+     TOBN(0x9fb813c0, 0x39cd297d), TOBN(0x8ec7e16e, 0x05bda5d9),
-+     TOBN(0x2834797c, 0x0d104b96), TOBN(0xcc11a2e7, 0x7c511510),
-+     TOBN(0x96ca5a53, 0x96ee6380), TOBN(0x054c8655, 0xcea38742),
-+     TOBN(0xb5946852, 0xd54dfa7d), TOBN(0x97c422e7, 0x1f4ab207),
-+     TOBN(0xbf907509, 0x0c22b540), TOBN(0x2cde42aa, 0xb7c267d4),
-+     TOBN(0xba18f9ed, 0x5ab0d693), TOBN(0x3ba62aa6, 0x6e4660d9),
-+     TOBN(0xb24bf97b, 0xab9ea96a), TOBN(0x5d039642, 0xe3b60e32),
-+     TOBN(0x4e6a4506, 0x7c4d9bd5), TOBN(0x666c5b9e, 0x7ed4a6a4),
-+     TOBN(0xfa3fdcd9, 0x8edbd7cc), TOBN(0x4660bb87, 0xc6ccd753),
-+     TOBN(0x9ae90820, 0x21e6b64f), TOBN(0x8a56a713, 0xb36bfb3f),
-+     TOBN(0xabfce096, 0x5726d47f), TOBN(0x9eed01b2, 0x0b1a9a7f),
-+     TOBN(0x30e9cad4, 0x4eb74a37), TOBN(0x7b2524cc, 0x53e9666d),
-+     TOBN(0x6a29683b, 0x8f4b002f), TOBN(0xc2200d7a, 0x41f4fc20),
-+     TOBN(0xcf3af47a, 0x3a338acc), TOBN(0x6539a4fb, 0xe7128975),
-+     TOBN(0xcec31c14, 0xc33c7fcf), TOBN(0x7eb6799b, 0xc7be322b),
-+     TOBN(0x119ef4e9, 0x6646f623), TOBN(0x7b7a26a5, 0x54d7299b),
-+     TOBN(0xcb37f08d, 0x403f46f2), TOBN(0x94b8fc43, 0x1a0ec0c7),
-+     TOBN(0xbb8514e3, 0xc332142f), TOBN(0xf3ed2c33, 0xe80d2a7a),
-+     TOBN(0x8d2080af, 0xb639126c), TOBN(0xf7b6be60, 0xe3553ade),
-+     TOBN(0x3950aa9f, 0x1c7e2b09), TOBN(0x847ff958, 0x6410f02b),
-+     TOBN(0x877b7cf5, 0x678a31b0), TOBN(0xd50301ae, 0x3998b620),
-+     TOBN(0x734257c5, 0xc00fb396), TOBN(0xf9fb18a0, 0x04e672a6),
-+     TOBN(0xff8bd8eb, 0xe8758851), TOBN(0x1e64e4c6, 0x5d99ba44),
-+     TOBN(0x4b8eaedf, 0x7dfd93b7), TOBN(0xba2f2a98, 0x04e76b8c),
-+     TOBN(0x7d790cba, 0xe8053433), TOBN(0xc8e725a0, 0x3d2c9585),
-+     TOBN(0x58c5c476, 0xcdd8f5ed), TOBN(0xd106b952, 0xefa9fe1d),
-+     TOBN(0x3c5c775b, 0x0eff13a9), TOBN(0x242442ba, 0xe057b930),
-+     TOBN(0xe9f458d4, 0xc9b70cbd), TOBN(0x69b71448, 0xa3cdb89a),
-+     TOBN(0x41ee46f6, 0x0e2ed742), TOBN(0x573f1045, 0x40067493),
-+     TOBN(0xb1e154ff, 0x9d54c304), TOBN(0x2ad0436a, 0x8d3a7502),
-+     TOBN(0xee4aaa2d, 0x431a8121), TOBN(0xcd38b3ab, 0x886f11ed),
-+     TOBN(0x57d49ea6, 0x034a0eb7), TOBN(0xd2b773bd, 0xf7e85e58),
-+     TOBN(0x4a559ac4, 0x9b5c1f14), TOBN(0xc444be1a, 0x3e54df2b),
-+     TOBN(0x13aad704, 0xeda41891), TOBN(0xcd927bec, 0x5eb5c788),
-+     TOBN(0xeb3c8516, 0xe48c8a34), TOBN(0x1b7ac812, 0x4b546669),
-+     TOBN(0x1815f896, 0x594df8ec), TOBN(0x87c6a79c, 0x79227865),
-+     TOBN(0xae02a2f0, 0x9b56ddbd), TOBN(0x1339b5ac, 0x8a2f1cf3),
-+     TOBN(0xf2b569c7, 0x839dff0d), TOBN(0xb0b9e864, 0xfee9a43d),
-+     TOBN(0x4ff8ca41, 0x77bb064e), TOBN(0x145a2812, 0xfd249f63),
-+     TOBN(0x3ab7beac, 0xf86f689a), TOBN(0x9bafec27, 0x01d35f5e),
-+     TOBN(0x28054c65, 0x4265aa91), TOBN(0xa4b18304, 0x035efe42),
-+     TOBN(0x6887b0e6, 0x9639dec7), TOBN(0xf4b8f6ad, 0x3d52aea5),
-+     TOBN(0xfb9293cc, 0x971a8a13), TOBN(0x3f159e5d, 0x4c934d07),
-+     TOBN(0x2c50e9b1, 0x09acbc29), TOBN(0x08eb65e6, 0x7154d129),
-+     TOBN(0x4feff589, 0x30b75c3e), TOBN(0x0bb82fe2, 0x94491c93),
-+     TOBN(0xd8ac377a, 0x89af62bb), TOBN(0xd7b51490, 0x9685e49f),
-+     TOBN(0xabca9a7b, 0x04497f19), TOBN(0x1b35ed0a, 0x1a7ad13f),
-+     TOBN(0x6b601e21, 0x3ec86ed6), TOBN(0xda91fcb9, 0xce0c76f1),
-+     TOBN(0x9e28507b, 0xd7ab27e1), TOBN(0x7c19a555, 0x63945b7b),
-+     TOBN(0x6b43f0a1, 0xaafc9827), TOBN(0x443b4fbd, 0x3aa55b91),
-+     TOBN(0x962b2e65, 0x6962c88f), TOBN(0x139da8d4, 0xce0db0ca),
-+     TOBN(0xb93f05dd, 0x1b8d6c4f), TOBN(0x779cdff7, 0x180b9824),
-+     TOBN(0xbba23fdd, 0xae57c7b7), TOBN(0x345342f2, 0x1b932522),
-+     TOBN(0xfd9c80fe, 0x556d4aa3), TOBN(0xa03907ba, 0x6525bb61),
-+     TOBN(0x38b010e1, 0xff218933), TOBN(0xc066b654, 0xaa52117b),
-+     TOBN(0x8e141920, 0x94f2e6ea), TOBN(0x66a27dca, 0x0d32f2b2),
-+     TOBN(0x69c7f993, 0x048b3717), TOBN(0xbf5a989a, 0xb178ae1c),
-+     TOBN(0x49fa9058, 0x564f1d6b), TOBN(0x27ec6e15, 0xd31fde4e),
-+     TOBN(0x4cce0373, 0x7276e7fc), TOBN(0x64086d79, 0x89d6bf02),
-+     TOBN(0x5a72f046, 0x4ccdd979), TOBN(0x909c3566, 0x47775631),
-+     TOBN(0x1c07bc6b, 0x75dd7125), TOBN(0xb4c6bc97, 0x87a0428d),
-+     TOBN(0x507ece52, 0xfdeb6b9d), TOBN(0xfca56512, 0xb2c95432),
-+     TOBN(0x15d97181, 0xd0e8bd06), TOBN(0x384dd317, 0xc6bb46ea),
-+     TOBN(0x5441ea20, 0x3952b624), TOBN(0xbcf70dee, 0x4e7dc2fb),
-+     TOBN(0x372b016e, 0x6628e8c3), TOBN(0x07a0d667, 0xb60a7522),
-+     TOBN(0xcf05751b, 0x0a344ee2), TOBN(0x0ec09a48, 0x118bdeec),
-+     TOBN(0x6e4b3d4e, 0xd83dce46), TOBN(0x43a6316d, 0x99d2fc6e),
-+     TOBN(0xa99d8989, 0x56cf044c), TOBN(0x7c7f4454, 0xae3e5fb7),
-+     TOBN(0xb2e6b121, 0xfbabbe92), TOBN(0x281850fb, 0xe1330076),
-+     TOBN(0x093581ec, 0x97890015), TOBN(0x69b1dded, 0x75ff77f5),
-+     TOBN(0x7cf0b18f, 0xab105105), TOBN(0x953ced31, 0xa89ccfef),
-+     TOBN(0x3151f85f, 0xeb914009), TOBN(0x3c9f1b87, 0x88ed48ad),
-+     TOBN(0xc9aba1a1, 0x4a7eadcb), TOBN(0x928e7501, 0x522e71cf),
-+     TOBN(0xeaede727, 0x3a2e4f83), TOBN(0x467e10d1, 0x1ce3bbd3),
-+     TOBN(0xf3442ac3, 0xb955dcf0), TOBN(0xba96307d, 0xd3d5e527),
-+     TOBN(0xf763a10e, 0xfd77f474), TOBN(0x5d744bd0, 0x6a6e1ff0),
-+     TOBN(0xd287282a, 0xa777899e), TOBN(0xe20eda8f, 0xd03f3cde),
-+     TOBN(0x6a7e75bb, 0x50b07d31), TOBN(0x0b7e2a94, 0x6f379de4),
-+     TOBN(0x31cb64ad, 0x19f593cf), TOBN(0x7b1a9e4f, 0x1e76ef1d),
-+     TOBN(0xe18c9c9d, 0xb62d609c), TOBN(0x439bad6d, 0xe779a650),
-+     TOBN(0x219d9066, 0xe032f144), TOBN(0x1db632b8, 0xe8b2ec6a),
-+     TOBN(0xff0d0fd4, 0xfda12f78), TOBN(0x56fb4c2d, 0x2a25d265),
-+     TOBN(0x5f4e2ee1, 0x255a03f1), TOBN(0x61cd6af2, 0xe96af176),
-+     TOBN(0xe0317ba8, 0xd068bc97), TOBN(0x927d6bab, 0x264b988e),
-+     TOBN(0xa18f07e0, 0xe90fb21e), TOBN(0x00fd2b80, 0xbba7fca1),
-+     TOBN(0x20387f27, 0x95cd67b5), TOBN(0x5b89a4e7, 0xd39707f7),
-+     TOBN(0x8f83ad3f, 0x894407ce), TOBN(0xa0025b94, 0x6c226132),
-+     TOBN(0xc79563c7, 0xf906c13b), TOBN(0x5f548f31, 0x4e7bb025),
-+     TOBN(0x2b4c6b8f, 0xeac6d113), TOBN(0xa67e3f9c, 0x0e813c76),
-+     TOBN(0x3982717c, 0x3fe1f4b9), TOBN(0x58865819, 0x26d8050e),
-+     TOBN(0x99f3640c, 0xf7f06f20), TOBN(0xdc610216, 0x2a66ebc2),
-+     TOBN(0x52f2c175, 0x767a1e08), TOBN(0x05660e1a, 0x5999871b),
-+     TOBN(0x6b0f1762, 0x6d3c4693), TOBN(0xf0e7d627, 0x37ed7bea),
-+     TOBN(0xc51758c7, 0xb75b226d), TOBN(0x40a88628, 0x1f91613b),
-+     TOBN(0x889dbaa7, 0xbbb38ce0), TOBN(0xe0404b65, 0xbddcad81),
-+     TOBN(0xfebccd3a, 0x8bc9671f), TOBN(0xfbf9a357, 0xee1f5375),
-+     TOBN(0x5dc169b0, 0x28f33398), TOBN(0xb07ec11d, 0x72e90f65),
-+     TOBN(0xae7f3b4a, 0xfaab1eb1), TOBN(0xd970195e, 0x5f17538a),
-+     TOBN(0x52b05cbe, 0x0181e640), TOBN(0xf5debd62, 0x2643313d),
-+     TOBN(0x76148154, 0x5df31f82), TOBN(0x23e03b33, 0x3a9e13c5),
-+     TOBN(0xff758949, 0x4fde0c1f), TOBN(0xbf8a1abe, 0xe5b6ec20),
-+     TOBN(0x702278fb, 0x87e1db6c), TOBN(0xc447ad7a, 0x35ed658f),
-+     TOBN(0x48d4aa38, 0x03d0ccf2), TOBN(0x80acb338, 0x819a7c03),
-+     TOBN(0x9bc7c89e, 0x6e17cecc), TOBN(0x46736b8b, 0x03be1d82),
-+     TOBN(0xd65d7b60, 0xc0432f96), TOBN(0xddebe7a3, 0xdeb5442f),
-+     TOBN(0x79a25307, 0x7dff69a2), TOBN(0x37a56d94, 0x02cf3122),
-+     TOBN(0x8bab8aed, 0xf2350d0a), TOBN(0x13c3f276, 0x037b0d9a),
-+     TOBN(0xc664957c, 0x44c65cae), TOBN(0x88b44089, 0xc2e71a88),
-+     TOBN(0xdb88e5a3, 0x5cb02664), TOBN(0x5d4c0bf1, 0x8686c72e),
-+     TOBN(0xea3d9b62, 0xa682d53e), TOBN(0x9b605ef4, 0x0b2ad431),
-+     TOBN(0x71bac202, 0xc69645d0), TOBN(0xa115f03a, 0x6a1b66e7),
-+     TOBN(0xfe2c563a, 0x158f4dc4), TOBN(0xf715b3a0, 0x4d12a78c),
-+     TOBN(0x8f7f0a48, 0xd413213a), TOBN(0x2035806d, 0xc04becdb),
-+     TOBN(0xecd34a99, 0x5d8587f5), TOBN(0x4d8c3079, 0x9f6d3a71),
-+     TOBN(0x1b2a2a67, 0x8d95a8f6), TOBN(0xc58c9d7d, 0xf2110d0d),
-+     TOBN(0xdeee81d5, 0xcf8fba3f), TOBN(0xa42be3c0, 0x0c7cdf68),
-+     TOBN(0x2126f742, 0xd43b5eaa), TOBN(0x054a0766, 0xdfa59b85),
-+     TOBN(0x9d0d5e36, 0x126bfd45), TOBN(0xa1f8fbd7, 0x384f8a8f),
-+     TOBN(0x317680f5, 0xd563fccc), TOBN(0x48ca5055, 0xf280a928),
-+     TOBN(0xe00b81b2, 0x27b578cf), TOBN(0x10aad918, 0x2994a514),
-+     TOBN(0xd9e07b62, 0xb7bdc953), TOBN(0x9f0f6ff2, 0x5bc086dd),
-+     TOBN(0x09d1ccff, 0x655eee77), TOBN(0x45475f79, 0x5bef7df1),
-+     TOBN(0x3faa28fa, 0x86f702cc), TOBN(0x92e60905, 0x0f021f07),
-+     TOBN(0xe9e62968, 0x7f8fa8c6), TOBN(0xbd71419a, 0xf036ea2c),
-+     TOBN(0x171ee1cc, 0x6028da9a), TOBN(0x5352fe1a, 0xc251f573),
-+     TOBN(0xf8ff236e, 0x3fa997f4), TOBN(0xd831b6c9, 0xa5749d5f),
-+     TOBN(0x7c872e1d, 0xe350e2c2), TOBN(0xc56240d9, 0x1e0ce403),
-+     TOBN(0xf9deb077, 0x6974f5cb), TOBN(0x7d50ba87, 0x961c3728),
-+     TOBN(0xd6f89426, 0x5a3a2518), TOBN(0xcf817799, 0xc6303d43),
-+     TOBN(0x510a0471, 0x619e5696), TOBN(0xab049ff6, 0x3a5e307b),
-+     TOBN(0xe4cdf9b0, 0xfeb13ec7), TOBN(0xd5e97117, 0x9d8ff90c),
-+     TOBN(0xf6f64d06, 0x9afa96af), TOBN(0x00d0bf5e, 0x9d2012a2),
-+     TOBN(0xe63f301f, 0x358bcdc0), TOBN(0x07689e99, 0x0a9d47f8),
-+     TOBN(0x1f689e2f, 0x4f43d43a), TOBN(0x4d542a16, 0x90920904),
-+     TOBN(0xaea293d5, 0x9ca0a707), TOBN(0xd061fe45, 0x8ac68065),
-+     TOBN(0x1033bf1b, 0x0090008c), TOBN(0x29749558, 0xc08a6db6),
-+     TOBN(0x74b5fc59, 0xc1d5d034), TOBN(0xf712e9f6, 0x67e215e0),
-+     TOBN(0xfd520cbd, 0x860200e6), TOBN(0x0229acb4, 0x3ea22588),
-+     TOBN(0x9cd1e14c, 0xfff0c82e), TOBN(0x87684b62, 0x59c69e73),
-+     TOBN(0xda85e61c, 0x96ccb989), TOBN(0x2d5dbb02, 0xa3d06493),
-+     TOBN(0xf22ad33a, 0xe86b173c), TOBN(0xe8e41ea5, 0xa79ff0e3),
-+     TOBN(0x01d2d725, 0xdd0d0c10), TOBN(0x31f39088, 0x032d28f9),
-+     TOBN(0x7b3f71e1, 0x7829839e), TOBN(0x0cf691b4, 0x4502ae58),
-+     TOBN(0xef658dbd, 0xbefc6115), TOBN(0xa5cd6ee5, 0xb3ab5314),
-+     TOBN(0x206c8d7b, 0x5f1d2347), TOBN(0x794645ba, 0x4cc2253a),
-+     TOBN(0xd517d8ff, 0x58389e08), TOBN(0x4fa20dee, 0x9f847288),
-+     TOBN(0xeba072d8, 0xd797770a), TOBN(0x7360c91d, 0xbf429e26),
-+     TOBN(0x7200a3b3, 0x80af8279), TOBN(0x6a1c9150, 0x82dadce3),
-+     TOBN(0x0ee6d3a7, 0xc35d8794), TOBN(0x042e6558, 0x0356bae5),
-+     TOBN(0x9f59698d, 0x643322fd), TOBN(0x9379ae15, 0x50a61967),
-+     TOBN(0x64b9ae62, 0xfcc9981e), TOBN(0xaed3d631, 0x6d2934c6),
-+     TOBN(0x2454b302, 0x5e4e65eb), TOBN(0xab09f647, 0xf9950428)}
-+    ,
-+    {TOBN(0xb2083a12, 0x22248acc), TOBN(0x1f6ec0ef, 0x3264e366),
-+     TOBN(0x5659b704, 0x5afdee28), TOBN(0x7a823a40, 0xe6430bb5),
-+     TOBN(0x24592a04, 0xe1900a79), TOBN(0xcde09d4a, 0xc9ee6576),
-+     TOBN(0x52b6463f, 0x4b5ea54a), TOBN(0x1efe9ed3, 0xd3ca65a7),
-+     TOBN(0xe27a6dbe, 0x305406dd), TOBN(0x8eb7dc7f, 0xdd5d1957),
-+     TOBN(0xf54a6876, 0x387d4d8f), TOBN(0x9c479409, 0xc7762de4),
-+     TOBN(0xbe4d5b5d, 0x99b30778), TOBN(0x25380c56, 0x6e793682),
-+     TOBN(0x602d37f3, 0xdac740e3), TOBN(0x140deabe, 0x1566e4ae),
-+     TOBN(0x4481d067, 0xafd32acf), TOBN(0xd8f0fcca, 0xe1f71ccf),
-+     TOBN(0xd208dd0c, 0xb596f2da), TOBN(0xd049d730, 0x9aad93f9),
-+     TOBN(0xc79f263d, 0x42ab580e), TOBN(0x09411bb1, 0x23f707b4),
-+     TOBN(0x8cfde1ff, 0x835e0eda), TOBN(0x72707490, 0x90f03402),
-+     TOBN(0xeaee6126, 0xc49a861e), TOBN(0x024f3b65, 0xe14f0d06),
-+     TOBN(0x51a3f1e8, 0xc69bfc17), TOBN(0xc3c3a8e9, 0xa7686381),
-+     TOBN(0x3400752c, 0xb103d4c8), TOBN(0x02bc4613, 0x9218b36b),
-+     TOBN(0xc67f75eb, 0x7651504a), TOBN(0xd6848b56, 0xd02aebfa),
-+     TOBN(0xbd9802e6, 0xc30fa92b), TOBN(0x5a70d96d, 0x9a552784),
-+     TOBN(0x9085c4ea, 0x3f83169b), TOBN(0xfa9423bb, 0x06908228),
-+     TOBN(0x2ffebe12, 0xfe97a5b9), TOBN(0x85da6049, 0x71b99118),
-+     TOBN(0x9cbc2f7f, 0x63178846), TOBN(0xfd96bc70, 0x9153218e),
-+     TOBN(0x958381db, 0x1782269b), TOBN(0xae34bf79, 0x2597e550),
-+     TOBN(0xbb5c6064, 0x5f385153), TOBN(0x6f0e96af, 0xe3088048),
-+     TOBN(0xbf6a0215, 0x77884456), TOBN(0xb3b5688c, 0x69310ea7),
-+     TOBN(0x17c94295, 0x04fad2de), TOBN(0xe020f0e5, 0x17896d4d),
-+     TOBN(0x730ba0ab, 0x0976505f), TOBN(0x567f6813, 0x095e2ec5),
-+     TOBN(0x47062010, 0x6331ab71), TOBN(0x72cfa977, 0x41d22b9f),
-+     TOBN(0x33e55ead, 0x8a2373da), TOBN(0xa8d0d5f4, 0x7ba45a68),
-+     TOBN(0xba1d8f9c, 0x03029d15), TOBN(0x8f34f1cc, 0xfc55b9f3),
-+     TOBN(0xcca4428d, 0xbbe5a1a9), TOBN(0x8187fd5f, 0x3126bd67),
-+     TOBN(0x0036973a, 0x48105826), TOBN(0xa39b6663, 0xb8bd61a0),
-+     TOBN(0x6d42deef, 0x2d65a808), TOBN(0x4969044f, 0x94636b19),
-+     TOBN(0xf611ee47, 0xdd5d564c), TOBN(0x7b2f3a49, 0xd2873077),
-+     TOBN(0x94157d45, 0x300eb294), TOBN(0x2b2a656e, 0x169c1494),
-+     TOBN(0xc000dd76, 0xd3a47aa9), TOBN(0xa2864e4f, 0xa6243ea4),
-+     TOBN(0x82716c47, 0xdb89842e), TOBN(0x12dfd7d7, 0x61479fb7),
-+     TOBN(0x3b9a2c56, 0xe0b2f6dc), TOBN(0x46be862a, 0xd7f85d67),
-+     TOBN(0x03b0d8dd, 0x0f82b214), TOBN(0x460c34f9, 0xf103cbc6),
-+     TOBN(0xf32e5c03, 0x18d79e19), TOBN(0x8b8888ba, 0xa84117f8),
-+     TOBN(0x8f3c37dc, 0xc0722677), TOBN(0x10d21be9, 0x1c1c0f27),
-+     TOBN(0xd47c8468, 0xe0f7a0c6), TOBN(0x9bf02213, 0xadecc0e0),
-+     TOBN(0x0baa7d12, 0x42b48b99), TOBN(0x1bcb665d, 0x48424096),
-+     TOBN(0x8b847cd6, 0xebfb5cfb), TOBN(0x87c2ae56, 0x9ad4d10d),
-+     TOBN(0xf1cbb122, 0x0de36726), TOBN(0xe7043c68, 0x3fdfbd21),
-+     TOBN(0x4bd0826a, 0x4e79d460), TOBN(0x11f5e598, 0x4bd1a2cb),
-+     TOBN(0x97554160, 0xb7fe7b6e), TOBN(0x7d16189a, 0x400a3fb2),
-+     TOBN(0xd73e9bea, 0xe328ca1e), TOBN(0x0dd04b97, 0xe793d8cc),
-+     TOBN(0xa9c83c9b, 0x506db8cc), TOBN(0x5cd47aae, 0xcf38814c),
-+     TOBN(0x26fc430d, 0xb64b45e6), TOBN(0x079b5499, 0xd818ea84),
-+     TOBN(0xebb01102, 0xc1c24a3b), TOBN(0xca24e568, 0x1c161c1a),
-+     TOBN(0x103eea69, 0x36f00a4a), TOBN(0x9ad76ee8, 0x76176c7b),
-+     TOBN(0x97451fc2, 0x538e0ff7), TOBN(0x94f89809, 0x6604b3b0),
-+     TOBN(0x6311436e, 0x3249cfd7), TOBN(0x27b4a7bd, 0x41224f69),
-+     TOBN(0x03b5d21a, 0xe0ac2941), TOBN(0x279b0254, 0xc2d31937),
-+     TOBN(0x3307c052, 0xcac992d0), TOBN(0x6aa7cb92, 0xefa8b1f3),
-+     TOBN(0x5a182580, 0x0d37c7a5), TOBN(0x13380c37, 0x342d5422),
-+     TOBN(0x92ac2d66, 0xd5d2ef92), TOBN(0x035a70c9, 0x030c63c6),
-+     TOBN(0xc16025dd, 0x4ce4f152), TOBN(0x1f419a71, 0xf9df7c06),
-+     TOBN(0x6d5b2214, 0x91e4bb14), TOBN(0xfc43c6cc, 0x839fb4ce),
-+     TOBN(0x49f06591, 0x925d6b2d), TOBN(0x4b37d9d3, 0x62186598),
-+     TOBN(0x8c54a971, 0xd01b1629), TOBN(0xe1a9c29f, 0x51d50e05),
-+     TOBN(0x5109b785, 0x71ba1861), TOBN(0x48b22d5c, 0xd0c8f93d),
-+     TOBN(0xe8fa84a7, 0x8633bb93), TOBN(0x53fba6ba, 0x5aebbd08),
-+     TOBN(0x7ff27df3, 0xe5eea7d8), TOBN(0x521c8796, 0x68ca7158),
-+     TOBN(0xb9d5133b, 0xce6f1a05), TOBN(0x2d50cd53, 0xfd0ebee4),
-+     TOBN(0xc82115d6, 0xc5a3ef16), TOBN(0x993eff9d, 0xba079221),
-+     TOBN(0xe4da2c5e, 0x4b5da81c), TOBN(0x9a89dbdb, 0x8033fd85),
-+     TOBN(0x60819ebf, 0x2b892891), TOBN(0x53902b21, 0x5d14a4d5),
-+     TOBN(0x6ac35051, 0xd7fda421), TOBN(0xcc6ab885, 0x61c83284),
-+     TOBN(0x14eba133, 0xf74cff17), TOBN(0x240aaa03, 0xecb813f2),
-+     TOBN(0xcfbb6540, 0x6f665bee), TOBN(0x084b1fe4, 0xa425ad73),
-+     TOBN(0x009d5d16, 0xd081f6a6), TOBN(0x35304fe8, 0xeef82c90),
-+     TOBN(0xf20346d5, 0xaa9eaa22), TOBN(0x0ada9f07, 0xac1c91e3),
-+     TOBN(0xa6e21678, 0x968a6144), TOBN(0x54c1f77c, 0x07b31a1e),
-+     TOBN(0xd6bb787e, 0x5781fbe1), TOBN(0x61bd2ee0, 0xe31f1c4a),
-+     TOBN(0xf25aa1e9, 0x781105fc), TOBN(0x9cf2971f, 0x7b2f8e80),
-+     TOBN(0x26d15412, 0xcdff919b), TOBN(0x01db4ebe, 0x34bc896e),
-+     TOBN(0x7d9b3e23, 0xb40df1cf), TOBN(0x59337373, 0x94e971b4),
-+     TOBN(0xbf57bd14, 0x669cf921), TOBN(0x865daedf, 0x0c1a1064),
-+     TOBN(0x3eb70bd3, 0x83279125), TOBN(0xbc3d5b9f, 0x34ecdaab),
-+     TOBN(0x91e3ed7e, 0x5f755caf), TOBN(0x49699f54, 0xd41e6f02),
-+     TOBN(0x185770e1, 0xd4a7a15b), TOBN(0x08f3587a, 0xeaac87e7),
-+     TOBN(0x352018db, 0x473133ea), TOBN(0x674ce719, 0x04fd30fc),
-+     TOBN(0x7b8d9835, 0x088b3e0e), TOBN(0x7a0356a9, 0x5d0d47a1),
-+     TOBN(0x9d9e7659, 0x6474a3c4), TOBN(0x61ea48a7, 0xff66966c),
-+     TOBN(0x30417758, 0x0f3e4834), TOBN(0xfdbb21c2, 0x17a9afcb),
-+     TOBN(0x756fa17f, 0x2f9a67b3), TOBN(0x2a6b2421, 0xa245c1a8),
-+     TOBN(0x64be2794, 0x4af02291), TOBN(0xade465c6, 0x2a5804fe),
-+     TOBN(0x8dffbd39, 0xa6f08fd7), TOBN(0xc4efa84c, 0xaa14403b),
-+     TOBN(0xa1b91b2a, 0x442b0f5c), TOBN(0xb748e317, 0xcf997736),
-+     TOBN(0x8d1b62bf, 0xcee90e16), TOBN(0x907ae271, 0x0b2078c0),
-+     TOBN(0xdf31534b, 0x0c9bcddd), TOBN(0x043fb054, 0x39adce83),
-+     TOBN(0x99031043, 0xd826846a), TOBN(0x61a9c0d6, 0xb144f393),
-+     TOBN(0xdab48046, 0x47718427), TOBN(0xdf17ff9b, 0x6e830f8b),
-+     TOBN(0x408d7ee8, 0xe49a1347), TOBN(0x6ac71e23, 0x91c1d4ae),
-+     TOBN(0xc8cbb9fd, 0x1defd73c), TOBN(0x19840657, 0xbbbbfec5),
-+     TOBN(0x39db1cb5, 0x9e7ef8ea), TOBN(0x78aa8296, 0x64105f30),
-+     TOBN(0xa3d9b7f0, 0xa3738c29), TOBN(0x0a2f235a, 0xbc3250a3),
-+     TOBN(0x55e506f6, 0x445e4caf), TOBN(0x0974f73d, 0x33475f7a),
-+     TOBN(0xd37dbba3, 0x5ba2f5a8), TOBN(0x542c6e63, 0x6af40066),
-+     TOBN(0x26d99b53, 0xc5d73e2c), TOBN(0x06060d7d, 0x6c3ca33e),
-+     TOBN(0xcdbef1c2, 0x065fef4a), TOBN(0x77e60f7d, 0xfd5b92e3),
-+     TOBN(0xd7c549f0, 0x26708350), TOBN(0x201b3ad0, 0x34f121bf),
-+     TOBN(0x5fcac2a1, 0x0334fc14), TOBN(0x8a9a9e09, 0x344552f6),
-+     TOBN(0x7dd8a1d3, 0x97653082), TOBN(0x5fc0738f, 0x79d4f289),
-+     TOBN(0x787d244d, 0x17d2d8c3), TOBN(0xeffc6345, 0x70830684),
-+     TOBN(0x5ddb96dd, 0xe4f73ae5), TOBN(0x8efb14b1, 0x172549a5),
-+     TOBN(0x6eb73eee, 0x2245ae7a), TOBN(0xbca4061e, 0xea11f13e),
-+     TOBN(0xb577421d, 0x30b01f5d), TOBN(0xaa688b24, 0x782e152c),
-+     TOBN(0x67608e71, 0xbd3502ba), TOBN(0x4ef41f24, 0xb4de75a0),
-+     TOBN(0xb08dde5e, 0xfd6125e5), TOBN(0xde484825, 0xa409543f),
-+     TOBN(0x1f198d98, 0x65cc2295), TOBN(0x428a3771, 0x6e0edfa2),
-+     TOBN(0x4f9697a2, 0xadf35fc7), TOBN(0x01a43c79, 0xf7cac3c7),
-+     TOBN(0xb05d7059, 0x0fd3659a), TOBN(0x8927f30c, 0xbb7f2d9a),
-+     TOBN(0x4023d1ac, 0x8cf984d3), TOBN(0x32125ed3, 0x02897a45),
-+     TOBN(0xfb572dad, 0x3d414205), TOBN(0x73000ef2, 0xe3fa82a9),
-+     TOBN(0x4c0868e9, 0xf10a5581), TOBN(0x5b61fc67, 0x6b0b3ca5),
-+     TOBN(0xc1258d5b, 0x7cae440c), TOBN(0x21c08b41, 0x402b7531),
-+     TOBN(0xf61a8955, 0xde932321), TOBN(0x3568faf8, 0x2d1408af),
-+     TOBN(0x71b15e99, 0x9ecf965b), TOBN(0xf14ed248, 0xe917276f),
-+     TOBN(0xc6f4caa1, 0x820cf9e2), TOBN(0x681b20b2, 0x18d83c7e),
-+     TOBN(0x6cde738d, 0xc6c01120), TOBN(0x71db0813, 0xae70e0db),
-+     TOBN(0x95fc0644, 0x74afe18c), TOBN(0x34619053, 0x129e2be7),
-+     TOBN(0x80615cea, 0xdb2a3b15), TOBN(0x0a49a19e, 0xdb4c7073),
-+     TOBN(0x0e1b84c8, 0x8fd2d367), TOBN(0xd74bf462, 0x033fb8aa),
-+     TOBN(0x889f6d65, 0x533ef217), TOBN(0x7158c7e4, 0xc3ca2e87),
-+     TOBN(0xfb670dfb, 0xdc2b4167), TOBN(0x75910a01, 0x844c257f),
-+     TOBN(0xf336bf07, 0xcf88577d), TOBN(0x22245250, 0xe45e2ace),
-+     TOBN(0x2ed92e8d, 0x7ca23d85), TOBN(0x29f8be4c, 0x2b812f58),
-+     TOBN(0xdd9ebaa7, 0x076fe12b), TOBN(0x3f2400cb, 0xae1537f9),
-+     TOBN(0x1aa93528, 0x17bdfb46), TOBN(0xc0f98430, 0x67883b41),
-+     TOBN(0x5590ede1, 0x0170911d), TOBN(0x7562f5bb, 0x34d4b17f),
-+     TOBN(0xe1fa1df2, 0x1826b8d2), TOBN(0xb40b796a, 0x6bd80d59),
-+     TOBN(0xd65bf197, 0x3467ba92), TOBN(0x8c9b46db, 0xf70954b0),
-+     TOBN(0x97c8a0f3, 0x0e78f15d), TOBN(0xa8f3a69a, 0x85a4c961),
-+     TOBN(0x4242660f, 0x61e4ce9b), TOBN(0xbf06aab3, 0x6ea6790c),
-+     TOBN(0xc6706f8e, 0xec986416), TOBN(0x9e56dec1, 0x9a9fc225),
-+     TOBN(0x527c46f4, 0x9a9898d9), TOBN(0xd799e77b, 0x5633cdef),
-+     TOBN(0x24eacc16, 0x7d9e4297), TOBN(0xabb61cea, 0x6b1cb734),
-+     TOBN(0xbee2e8a7, 0xf778443c), TOBN(0x3bb42bf1, 0x29de2fe6),
-+     TOBN(0xcbed86a1, 0x3003bb6f), TOBN(0xd3918e6c, 0xd781cdf6),
-+     TOBN(0x4bee3271, 0x9a5103f1), TOBN(0x5243efc6, 0xf50eac06),
-+     TOBN(0xb8e122cb, 0x6adcc119), TOBN(0x1b7faa84, 0xc0b80a08),
-+     TOBN(0x32c3d1bd, 0x6dfcd08c), TOBN(0x129dec4e, 0x0be427de),
-+     TOBN(0x98ab679c, 0x1d263c83), TOBN(0xafc83cb7, 0xcef64eff),
-+     TOBN(0x85eb6088, 0x2fa6be76), TOBN(0x892585fb, 0x1328cbfe),
-+     TOBN(0xc154d3ed, 0xcf618dda), TOBN(0xc44f601b, 0x3abaf26e),
-+     TOBN(0x7bf57d0b, 0x2be1fdfd), TOBN(0xa833bd2d, 0x21137fee),
-+     TOBN(0x9353af36, 0x2db591a8), TOBN(0xc76f26dc, 0x5562a056),
-+     TOBN(0x1d87e47d, 0x3fdf5a51), TOBN(0x7afb5f93, 0x55c9cab0),
-+     TOBN(0x91bbf58f, 0x89e0586e), TOBN(0x7c72c018, 0x0d843709),
-+     TOBN(0xa9a5aafb, 0x99b5c3dc), TOBN(0xa48a0f1d, 0x3844aeb0),
-+     TOBN(0x7178b7dd, 0xb667e482), TOBN(0x453985e9, 0x6e23a59a),
-+     TOBN(0x4a54c860, 0x01b25dd8), TOBN(0x0dd37f48, 0xfb897c8a),
-+     TOBN(0x5f8aa610, 0x0ea90cd9), TOBN(0xc8892c68, 0x16d5830d),
-+     TOBN(0xeb4befc0, 0xef514ca5), TOBN(0x478eb679, 0xe72c9ee6),
-+     TOBN(0x9bca20da, 0xdbc40d5f), TOBN(0xf015de21, 0xdde4f64a),
-+     TOBN(0xaa6a4de0, 0xeaf4b8a5), TOBN(0x68cfd9ca, 0x4bc60e32),
-+     TOBN(0x668a4b01, 0x7fd15e70), TOBN(0xd9f0694a, 0xf27dc09d),
-+     TOBN(0xf6c3cad5, 0xba708bcd), TOBN(0x5cd2ba69, 0x5bb95c2a),
-+     TOBN(0xaa28c1d3, 0x33c0a58f), TOBN(0x23e274e3, 0xabc77870),
-+     TOBN(0x44c3692d, 0xdfd20a4a), TOBN(0x091c5fd3, 0x81a66653),
-+     TOBN(0x6c0bb691, 0x09a0757d), TOBN(0x9072e8b9, 0x667343ea),
-+     TOBN(0x31d40eb0, 0x80848bec), TOBN(0x95bd480a, 0x79fd36cc),
-+     TOBN(0x01a77c61, 0x65ed43f5), TOBN(0xafccd127, 0x2e0d40bf),
-+     TOBN(0xeccfc82d, 0x1cc1884b), TOBN(0xc85ac201, 0x5d4753b4),
-+     TOBN(0xc7a6caac, 0x658e099f), TOBN(0xcf46369e, 0x04b27390),
-+     TOBN(0xe2e7d049, 0x506467ea), TOBN(0x481b63a2, 0x37cdeccc),
-+     TOBN(0x4029abd8, 0xed80143a), TOBN(0x28bfe3c7, 0xbcb00b88),
-+     TOBN(0x3bec1009, 0x0643d84a), TOBN(0x885f3668, 0xabd11041),
-+     TOBN(0xdb02432c, 0xf83a34d6), TOBN(0x32f7b360, 0x719ceebe),
-+     TOBN(0xf06c7837, 0xdad1fe7a), TOBN(0x60a157a9, 0x5441a0b0),
-+     TOBN(0x704970e9, 0xe2d47550), TOBN(0xcd2bd553, 0x271b9020),
-+     TOBN(0xff57f82f, 0x33e24a0b), TOBN(0x9cbee23f, 0xf2565079),
-+     TOBN(0x16353427, 0xeb5f5825), TOBN(0x276feec4, 0xe948d662),
-+     TOBN(0xd1b62bc6, 0xda10032b), TOBN(0x718351dd, 0xf0e72a53),
-+     TOBN(0x93452076, 0x2420e7ba), TOBN(0x96368fff, 0x3a00118d),
-+     TOBN(0x00ce2d26, 0x150a49e4), TOBN(0x0c28b636, 0x3f04706b),
-+     TOBN(0xbad65a46, 0x58b196d0), TOBN(0x6c8455fc, 0xec9f8b7c),
-+     TOBN(0xe90c895f, 0x2d71867e), TOBN(0x5c0be31b, 0xedf9f38c),
-+     TOBN(0x2a37a15e, 0xd8f6ec04), TOBN(0x239639e7, 0x8cd85251),
-+     TOBN(0xd8975315, 0x9c7c4c6b), TOBN(0x603aa3c0, 0xd7409af7),
-+     TOBN(0xb8d53d0c, 0x007132fb), TOBN(0x68d12af7, 0xa6849238),
-+     TOBN(0xbe0607e7, 0xbf5d9279), TOBN(0x9aa50055, 0xaada74ce),
-+     TOBN(0xe81079cb, 0xba7e8ccb), TOBN(0x610c71d1, 0xa5f4ff5e),
-+     TOBN(0x9e2ee1a7, 0x5aa07093), TOBN(0xca84004b, 0xa75da47c),
-+     TOBN(0x074d3951, 0x3de75401), TOBN(0xf938f756, 0xbb311592),
-+     TOBN(0x96197618, 0x00a43421), TOBN(0x39a25362, 0x07bc78c8),
-+     TOBN(0x278f710a, 0x0a171276), TOBN(0xb28446ea, 0x8d1a8f08),
-+     TOBN(0x184781bf, 0xe3b6a661), TOBN(0x7751cb1d, 0xe6d279f7),
-+     TOBN(0xf8ff95d6, 0xc59eb662), TOBN(0x186d90b7, 0x58d3dea7),
-+     TOBN(0x0e4bb6c1, 0xdfb4f754), TOBN(0x5c5cf56b, 0x2b2801dc),
-+     TOBN(0xc561e452, 0x1f54564d), TOBN(0xb4fb8c60, 0xf0dd7f13),
-+     TOBN(0xf8849630, 0x33ff98c7), TOBN(0x9619fffa, 0xcf17769c),
-+     TOBN(0xf8090bf6, 0x1bfdd80a), TOBN(0x14d9a149, 0x422cfe63),
-+     TOBN(0xb354c360, 0x6f6df9ea), TOBN(0xdbcf770d, 0x218f17ea),
-+     TOBN(0x207db7c8, 0x79eb3480), TOBN(0x213dbda8, 0x559b6a26),
-+     TOBN(0xac4c200b, 0x29fc81b3), TOBN(0xebc3e09f, 0x171d87c1),
-+     TOBN(0x91799530, 0x1481aa9e), TOBN(0x051b92e1, 0x92e114fa),
-+     TOBN(0xdf8f92e9, 0xecb5537f), TOBN(0x44b1b2cc, 0x290c7483),
-+     TOBN(0xa711455a, 0x2adeb016), TOBN(0x964b6856, 0x81a10c2c),
-+     TOBN(0x4f159d99, 0xcec03623), TOBN(0x05532225, 0xef3271ea),
-+     TOBN(0xb231bea3, 0xc5ee4849), TOBN(0x57a54f50, 0x7094f103),
-+     TOBN(0x3e2d421d, 0x9598b352), TOBN(0xe865a49c, 0x67412ab4),
-+     TOBN(0xd2998a25, 0x1cc3a912), TOBN(0x5d092808, 0x0c74d65d),
-+     TOBN(0x73f45908, 0x4088567a), TOBN(0xeb6b280e, 0x1f214a61),
-+     TOBN(0x8c9adc34, 0xcaf0c13d), TOBN(0x39d12938, 0xf561fb80),
-+     TOBN(0xb2dc3a5e, 0xbc6edfb4), TOBN(0x7485b1b1, 0xfe4d210e),
-+     TOBN(0x062e0400, 0xe186ae72), TOBN(0x91e32d5c, 0x6eeb3b88),
-+     TOBN(0x6df574d7, 0x4be59224), TOBN(0xebc88ccc, 0x716d55f3),
-+     TOBN(0x26c2e6d0, 0xcad6ed33), TOBN(0xc6e21e7d, 0x0d3e8b10),
-+     TOBN(0x2cc5840e, 0x5bcc36bb), TOBN(0x9292445e, 0x7da74f69),
-+     TOBN(0x8be8d321, 0x4e5193a8), TOBN(0x3ec23629, 0x8df06413),
-+     TOBN(0xc7e9ae85, 0xb134defa), TOBN(0x6073b1d0, 0x1bb2d475),
-+     TOBN(0xb9ad615e, 0x2863c00d), TOBN(0x9e29493d, 0x525f4ac4),
-+     TOBN(0xc32b1dea, 0x4e9acf4f), TOBN(0x3e1f01c8, 0xa50db88d),
-+     TOBN(0xb05d70ea, 0x04da916c), TOBN(0x714b0d0a, 0xd865803e),
-+     TOBN(0x4bd493fc, 0x9920cb5e), TOBN(0x5b44b1f7, 0x92c7a3ac),
-+     TOBN(0xa2a77293, 0xbcec9235), TOBN(0x5ee06e87, 0xcd378553),
-+     TOBN(0xceff8173, 0xda621607), TOBN(0x2bb03e4c, 0x99f5d290),
-+     TOBN(0x2945106a, 0xa6f734ac), TOBN(0xb5056604, 0xd25c4732),
-+     TOBN(0x5945920c, 0xe079afee), TOBN(0x686e17a0, 0x6789831f),
-+     TOBN(0x5966bee8, 0xb74a5ae5), TOBN(0x38a673a2, 0x1e258d46),
-+     TOBN(0xbd1cc1f2, 0x83141c95), TOBN(0x3b2ecf4f, 0x0e96e486),
-+     TOBN(0xcd3aa896, 0x74e5fc78), TOBN(0x415ec10c, 0x2482fa7a),
-+     TOBN(0x15234419, 0x80503380), TOBN(0x513d917a, 0xd314b392),
-+     TOBN(0xb0b52f4e, 0x63caecae), TOBN(0x07bf22ad, 0x2dc7780b),
-+     TOBN(0xe761e8a1, 0xe4306839), TOBN(0x1b3be962, 0x5dd7feaa),
-+     TOBN(0x4fe728de, 0x74c778f1), TOBN(0xf1fa0bda, 0x5e0070f6),
-+     TOBN(0x85205a31, 0x6ec3f510), TOBN(0x2c7e4a14, 0xd2980475),
-+     TOBN(0xde3c19c0, 0x6f30ebfd), TOBN(0xdb1c1f38, 0xd4b7e644),
-+     TOBN(0xfe291a75, 0x5dce364a), TOBN(0xb7b22a3c, 0x058f5be3),
-+     TOBN(0x2cd2c302, 0x37fea38c), TOBN(0x2930967a, 0x2e17be17),
-+     TOBN(0x87f009de, 0x0c061c65), TOBN(0xcb014aac, 0xedc6ed44),
-+     TOBN(0x49bd1cb4, 0x3bafb1eb), TOBN(0x81bd8b5c, 0x282d3688),
-+     TOBN(0x1cdab87e, 0xf01a17af), TOBN(0x21f37ac4, 0xe710063b),
-+     TOBN(0x5a6c5676, 0x42fc8193), TOBN(0xf4753e70, 0x56a6015c),
-+     TOBN(0x020f795e, 0xa15b0a44), TOBN(0x8f37c8d7, 0x8958a958),
-+     TOBN(0x63b7e89b, 0xa4b675b5), TOBN(0xb4fb0c0c, 0x0fc31aea),
-+     TOBN(0xed95e639, 0xa7ff1f2e), TOBN(0x9880f5a3, 0x619614fb),
-+     TOBN(0xdeb6ff02, 0x947151ab), TOBN(0x5bc5118c, 0xa868dcdb),
-+     TOBN(0xd8da2055, 0x4c20cea5), TOBN(0xcac2776e, 0x14c4d69a),
-+     TOBN(0xcccb22c1, 0x622d599b), TOBN(0xa4ddb653, 0x68a9bb50),
-+     TOBN(0x2c4ff151, 0x1b4941b4), TOBN(0xe1ff19b4, 0x6efba588),
-+     TOBN(0x35034363, 0xc48345e0), TOBN(0x45542e3d, 0x1e29dfc4),
-+     TOBN(0xf197cb91, 0x349f7aed), TOBN(0x3b2b5a00, 0x8fca8420),
-+     TOBN(0x7c175ee8, 0x23aaf6d8), TOBN(0x54dcf421, 0x35af32b6),
-+     TOBN(0x0ba14307, 0x27d6561e), TOBN(0x879d5ee4, 0xd175b1e2),
-+     TOBN(0xc7c43673, 0x99807db5), TOBN(0x77a54455, 0x9cd55bcd),
-+     TOBN(0xe6c2ff13, 0x0105c072), TOBN(0x18f7a99f, 0x8dda7da4),
-+     TOBN(0x4c301820, 0x0e2d35c1), TOBN(0x06a53ca0, 0xd9cc6c82),
-+     TOBN(0xaa21cc1e, 0xf1aa1d9e), TOBN(0x32414334, 0x4a75b1e8),
-+     TOBN(0x2a6d1328, 0x0ebe9fdc), TOBN(0x16bd173f, 0x98a4755a),
-+     TOBN(0xfbb9b245, 0x2133ffd9), TOBN(0x39a8b2f1, 0x830f1a20),
-+     TOBN(0x484bc97d, 0xd5a1f52a), TOBN(0xd6aebf56, 0xa40eddf8),
-+     TOBN(0x32257acb, 0x76ccdac6), TOBN(0xaf4d36ec, 0x1586ff27),
-+     TOBN(0x8eaa8863, 0xf8de7dd1), TOBN(0x0045d5cf, 0x88647c16)}
-+    ,
-+    {TOBN(0xa6f3d574, 0xc005979d), TOBN(0xc2072b42, 0x6a40e350),
-+     TOBN(0xfca5c156, 0x8de2ecf9), TOBN(0xa8c8bf5b, 0xa515344e),
-+     TOBN(0x97aee555, 0x114df14a), TOBN(0xd4374a4d, 0xfdc5ec6b),
-+     TOBN(0x754cc28f, 0x2ca85418), TOBN(0x71cb9e27, 0xd3c41f78),
-+     TOBN(0x89105079, 0x03605c39), TOBN(0xf0843d9e, 0xa142c96c),
-+     TOBN(0xf3744934, 0x16923684), TOBN(0x732caa2f, 0xfa0a2893),
-+     TOBN(0xb2e8c270, 0x61160170), TOBN(0xc32788cc, 0x437fbaa3),
-+     TOBN(0x39cd818e, 0xa6eda3ac), TOBN(0xe2e94239, 0x9e2b2e07),
-+     TOBN(0x6967d39b, 0x0260e52a), TOBN(0xd42585cc, 0x90653325),
-+     TOBN(0x0d9bd605, 0x21ca7954), TOBN(0x4fa20877, 0x81ed57b3),
-+     TOBN(0x60c1eff8, 0xe34a0bbe), TOBN(0x56b0040c, 0x84f6ef64),
-+     TOBN(0x28be2b24, 0xb1af8483), TOBN(0xb2278163, 0xf5531614),
-+     TOBN(0x8df27545, 0x5922ac1c), TOBN(0xa7b3ef5c, 0xa52b3f63),
-+     TOBN(0x8e77b214, 0x71de57c4), TOBN(0x31682c10, 0x834c008b),
-+     TOBN(0xc76824f0, 0x4bd55d31), TOBN(0xb6d1c086, 0x17b61c71),
-+     TOBN(0x31db0903, 0xc2a5089d), TOBN(0x9c092172, 0x184e5d3f),
-+     TOBN(0xdd7ced5b, 0xc00cc638), TOBN(0x1a2015eb, 0x61278fc2),
-+     TOBN(0x2e8e5288, 0x6a37f8d6), TOBN(0xc457786f, 0xe79933ad),
-+     TOBN(0xb3fe4cce, 0x2c51211a), TOBN(0xad9b10b2, 0x24c20498),
-+     TOBN(0x90d87a4f, 0xd28db5e5), TOBN(0x698cd105, 0x3aca2fc3),
-+     TOBN(0x4f112d07, 0xe91b536d), TOBN(0xceb982f2, 0x9eba09d6),
-+     TOBN(0x3c157b2c, 0x197c396f), TOBN(0xe23c2d41, 0x7b66eb24),
-+     TOBN(0x480c57d9, 0x3f330d37), TOBN(0xb3a4c8a1, 0x79108deb),
-+     TOBN(0x702388de, 0xcb199ce5), TOBN(0x0b019211, 0xb944a8d4),
-+     TOBN(0x24f2a692, 0x840bb336), TOBN(0x7c353bdc, 0xa669fa7b),
-+     TOBN(0xda20d6fc, 0xdec9c300), TOBN(0x625fbe2f, 0xa13a4f17),
-+     TOBN(0xa2b1b61a, 0xdbc17328), TOBN(0x008965bf, 0xa9515621),
-+     TOBN(0x49690939, 0xc620ff46), TOBN(0x182dd27d, 0x8717e91c),
-+     TOBN(0x5ace5035, 0xea6c3997), TOBN(0x54259aaa, 0xc2610bef),
-+     TOBN(0xef18bb3f, 0x3c80dd39), TOBN(0x6910b95b, 0x5fc3fa39),
-+     TOBN(0xfce2f510, 0x43e09aee), TOBN(0xced56c9f, 0xa7675665),
-+     TOBN(0x10e265ac, 0xd872db61), TOBN(0x6982812e, 0xae9fce69),
-+     TOBN(0x29be11c6, 0xce800998), TOBN(0x72bb1752, 0xb90360d9),
-+     TOBN(0x2c193197, 0x5a4ad590), TOBN(0x2ba2f548, 0x9fc1dbc0),
-+     TOBN(0x7fe4eebb, 0xe490ebe0), TOBN(0x12a0a4cd, 0x7fae11c0),
-+     TOBN(0x7197cf81, 0xe903ba37), TOBN(0xcf7d4aa8, 0xde1c6dd8),
-+     TOBN(0x92af6bf4, 0x3fd5684c), TOBN(0x2b26eecf, 0x80360aa1),
-+     TOBN(0xbd960f30, 0x00546a82), TOBN(0x407b3c43, 0xf59ad8fe),
-+     TOBN(0x86cae5fe, 0x249c82ba), TOBN(0x9e0faec7, 0x2463744c),
-+     TOBN(0x87f551e8, 0x94916272), TOBN(0x033f9344, 0x6ceb0615),
-+     TOBN(0x1e5eb0d1, 0x8be82e84), TOBN(0x89967f0e, 0x7a582fef),
-+     TOBN(0xbcf687d5, 0xa6e921fa), TOBN(0xdfee4cf3, 0xd37a09ba),
-+     TOBN(0x94f06965, 0xb493c465), TOBN(0x638b9a1c, 0x7635c030),
-+     TOBN(0x76667864, 0x66f05e9f), TOBN(0xccaf6808, 0xc04da725),
-+     TOBN(0xca2eb690, 0x768fccfc), TOBN(0xf402d37d, 0xb835b362),
-+     TOBN(0x0efac0d0, 0xe2fdfcce), TOBN(0xefc9cdef, 0xb638d990),
-+     TOBN(0x2af12b72, 0xd1669a8b), TOBN(0x33c536bc, 0x5774ccbd),
-+     TOBN(0x30b21909, 0xfb34870e), TOBN(0xc38fa2f7, 0x7df25aca),
-+     TOBN(0x74c5f02b, 0xbf81f3f5), TOBN(0x0525a5ae, 0xaf7e4581),
-+     TOBN(0x88d2aaba, 0x433c54ae), TOBN(0xed9775db, 0x806a56c5),
-+     TOBN(0xd320738a, 0xc0edb37d), TOBN(0x25fdb6ee, 0x66cc1f51),
-+     TOBN(0xac661d17, 0x10600d76), TOBN(0x931ec1f3, 0xbdd1ed76),
-+     TOBN(0x65c11d62, 0x19ee43f1), TOBN(0x5cd57c3e, 0x60829d97),
-+     TOBN(0xd26c91a3, 0x984be6e8), TOBN(0xf08d9309, 0x8b0c53bd),
-+     TOBN(0x94bc9e5b, 0xc016e4ea), TOBN(0xd3916839, 0x11d43d2b),
-+     TOBN(0x886c5ad7, 0x73701155), TOBN(0xe0377626, 0x20b00715),
-+     TOBN(0x7f01c9ec, 0xaa80ba59), TOBN(0x3083411a, 0x68538e51),
-+     TOBN(0x970370f1, 0xe88128af), TOBN(0x625cc3db, 0x91dec14b),
-+     TOBN(0xfef9666c, 0x01ac3107), TOBN(0xb2a8d577, 0xd5057ac3),
-+     TOBN(0xb0f26299, 0x92be5df7), TOBN(0xf579c8e5, 0x00353924),
-+     TOBN(0xb8fa3d93, 0x1341ed7a), TOBN(0x4223272c, 0xa7b59d49),
-+     TOBN(0x3dcb1947, 0x83b8c4a4), TOBN(0x4e413c01, 0xed1302e4),
-+     TOBN(0x6d999127, 0xe17e44ce), TOBN(0xee86bf75, 0x33b3adfb),
-+     TOBN(0xf6902fe6, 0x25aa96ca), TOBN(0xb73540e4, 0xe5aae47d),
-+     TOBN(0x32801d7b, 0x1b4a158c), TOBN(0xe571c99e, 0x27e2a369),
-+     TOBN(0x40cb76c0, 0x10d9f197), TOBN(0xc308c289, 0x3167c0ae),
-+     TOBN(0xa6ef9dd3, 0xeb7958f2), TOBN(0xa7226dfc, 0x300879b1),
-+     TOBN(0x6cd0b362, 0x7edf0636), TOBN(0x4efbce6c, 0x7bc37eed),
-+     TOBN(0x75f92a05, 0x8d699021), TOBN(0x586d4c79, 0x772566e3),
-+     TOBN(0x378ca5f1, 0x761ad23a), TOBN(0x650d86fc, 0x1465a8ac),
-+     TOBN(0x7a4ed457, 0x842ba251), TOBN(0x6b65e3e6, 0x42234933),
-+     TOBN(0xaf1543b7, 0x31aad657), TOBN(0xa4cefe98, 0xcbfec369),
-+     TOBN(0xb587da90, 0x9f47befb), TOBN(0x6562e9fb, 0x41312d13),
-+     TOBN(0xa691ea59, 0xeff1cefe), TOBN(0xcc30477a, 0x05fc4cf6),
-+     TOBN(0xa1632461, 0x0b0ffd3d), TOBN(0xa1f16f3b, 0x5b355956),
-+     TOBN(0x5b148d53, 0x4224ec24), TOBN(0xdc834e7b, 0xf977012a),
-+     TOBN(0x7bfc5e75, 0xb2c69dbc), TOBN(0x3aa77a29, 0x03c3da6c),
-+     TOBN(0xde0df03c, 0xca910271), TOBN(0xcbd5ca4a, 0x7806dc55),
-+     TOBN(0xe1ca5807, 0x6db476cb), TOBN(0xfde15d62, 0x5f37a31e),
-+     TOBN(0xf49af520, 0xf41af416), TOBN(0x96c5c5b1, 0x7d342db5),
-+     TOBN(0x155c43b7, 0xeb4ceb9b), TOBN(0x2e993010, 0x4e77371a),
-+     TOBN(0x1d2987da, 0x675d43af), TOBN(0xef2bc1c0, 0x8599fd72),
-+     TOBN(0x96894b7b, 0x9342f6b2), TOBN(0x201eadf2, 0x7c8e71f0),
-+     TOBN(0xf3479d9f, 0x4a1f3efc), TOBN(0xe0f8a742, 0x702a9704),
-+     TOBN(0xeafd44b6, 0xb3eba40c), TOBN(0xf9739f29, 0xc1c1e0d0),
-+     TOBN(0x0091471a, 0x619d505e), TOBN(0xc15f9c96, 0x9d7c263e),
-+     TOBN(0x5be47285, 0x83afbe33), TOBN(0xa3b6d6af, 0x04f1e092),
-+     TOBN(0xe76526b9, 0x751a9d11), TOBN(0x2ec5b26d, 0x9a4ae4d2),
-+     TOBN(0xeb66f4d9, 0x02f6fb8d), TOBN(0x4063c561, 0x96912164),
-+     TOBN(0xeb7050c1, 0x80ef3000), TOBN(0x288d1c33, 0xeaa5b3f0),
-+     TOBN(0xe87c68d6, 0x07806fd8), TOBN(0xb2f7f9d5, 0x4bbbf50f),
-+     TOBN(0x25972f3a, 0xac8d6627), TOBN(0xf8547774, 0x10e8c13b),
-+     TOBN(0xcc50ef6c, 0x872b4a60), TOBN(0xab2a34a4, 0x4613521b),
-+     TOBN(0x39c5c190, 0x983e15d1), TOBN(0x61dde5df, 0x59905512),
-+     TOBN(0xe417f621, 0x9f2275f3), TOBN(0x0750c8b6, 0x451d894b),
-+     TOBN(0x75b04ab9, 0x78b0bdaa), TOBN(0x3bfd9fd4, 0x458589bd),
-+     TOBN(0xf1013e30, 0xee9120b6), TOBN(0x2b51af93, 0x23a4743e),
-+     TOBN(0xea96ffae, 0x48d14d9e), TOBN(0x71dc0dbe, 0x698a1d32),
-+     TOBN(0x914962d2, 0x0180cca4), TOBN(0x1ae60677, 0xc3568963),
-+     TOBN(0x8cf227b1, 0x437bc444), TOBN(0xc650c83b, 0xc9962c7a),
-+     TOBN(0x23c2c7dd, 0xfe7ccfc4), TOBN(0xf925c89d, 0x1b929d48),
-+     TOBN(0x4460f74b, 0x06783c33), TOBN(0xac2c8d49, 0xa590475a),
-+     TOBN(0xfb40b407, 0xb807bba0), TOBN(0x9d1e362d, 0x69ff8f3a),
-+     TOBN(0xa33e9681, 0xcbef64a4), TOBN(0x67ece5fa, 0x332fb4b2),
-+     TOBN(0x6900a99b, 0x739f10e3), TOBN(0xc3341ca9, 0xff525925),
-+     TOBN(0xee18a626, 0xa9e2d041), TOBN(0xa5a83685, 0x29580ddd),
-+     TOBN(0xf3470c81, 0x9d7de3cd), TOBN(0xedf02586, 0x2062cf9c),
-+     TOBN(0xf43522fa, 0xc010edb0), TOBN(0x30314135, 0x13a4b1ae),
-+     TOBN(0xc792e02a, 0xdb22b94b), TOBN(0x993d8ae9, 0xa1eaa45b),
-+     TOBN(0x8aad6cd3, 0xcd1e1c63), TOBN(0x89529ca7, 0xc5ce688a),
-+     TOBN(0x2ccee3aa, 0xe572a253), TOBN(0xe02b6438, 0x02a21efb),
-+     TOBN(0xa7091b6e, 0xc9430358), TOBN(0x06d1b1fa, 0x9d7db504),
-+     TOBN(0x58846d32, 0xc4744733), TOBN(0x40517c71, 0x379f9e34),
-+     TOBN(0x2f65655f, 0x130ef6ca), TOBN(0x526e4488, 0xf1f3503f),
-+     TOBN(0x8467bd17, 0x7ee4a976), TOBN(0x1d9dc913, 0x921363d1),
-+     TOBN(0xd8d24c33, 0xb069e041), TOBN(0x5eb5da0a, 0x2cdf7f51),
-+     TOBN(0x1c0f3cb1, 0x197b994f), TOBN(0x3c95a6c5, 0x2843eae9),
-+     TOBN(0x7766ffc9, 0xa6097ea5), TOBN(0x7bea4093, 0xd723b867),
-+     TOBN(0xb48e1f73, 0x4db378f9), TOBN(0x70025b00, 0xe37b77ac),
-+     TOBN(0x943dc8e7, 0xaf24ad46), TOBN(0xb98a15ac, 0x16d00a85),
-+     TOBN(0x3adc38ba, 0x2743b004), TOBN(0xb1c7f4f7, 0x334415ee),
-+     TOBN(0xea43df8f, 0x1e62d05a), TOBN(0x32618905, 0x9d76a3b6),
-+     TOBN(0x2fbd0bb5, 0xa23a0f46), TOBN(0x5bc971db, 0x6a01918c),
-+     TOBN(0x7801d94a, 0xb4743f94), TOBN(0xb94df65e, 0x676ae22b),
-+     TOBN(0xaafcbfab, 0xaf95894c), TOBN(0x7b9bdc07, 0x276b2241),
-+     TOBN(0xeaf98362, 0x5bdda48b), TOBN(0x5977faf2, 0xa3fcb4df),
-+     TOBN(0xbed042ef, 0x052c4b5b), TOBN(0x9fe87f71, 0x067591f0),
-+     TOBN(0xc89c73ca, 0x22f24ec7), TOBN(0x7d37fa9e, 0xe64a9f1b),
-+     TOBN(0x2710841a, 0x15562627), TOBN(0x2c01a613, 0xc243b034),
-+     TOBN(0x1d135c56, 0x2bc68609), TOBN(0xc2ca1715, 0x8b03f1f6),
-+     TOBN(0xc9966c2d, 0x3eb81d82), TOBN(0xc02abf4a, 0x8f6df13e),
-+     TOBN(0x77b34bd7, 0x8f72b43b), TOBN(0xaff6218f, 0x360c82b0),
-+     TOBN(0x0aa5726c, 0x8d55b9d2), TOBN(0xdc0adbe9, 0x99e9bffb),
-+     TOBN(0x9097549c, 0xefb9e72a), TOBN(0x16755712, 0x9dfb3111),
-+     TOBN(0xdd8bf984, 0xf26847f9), TOBN(0xbcb8e387, 0xdfb30cb7),
-+     TOBN(0xc1fd32a7, 0x5171ef9c), TOBN(0x977f3fc7, 0x389b363f),
-+     TOBN(0x116eaf2b, 0xf4babda0), TOBN(0xfeab68bd, 0xf7113c8e),
-+     TOBN(0xd1e3f064, 0xb7def526), TOBN(0x1ac30885, 0xe0b3fa02),
-+     TOBN(0x1c5a6e7b, 0x40142d9d), TOBN(0x839b5603, 0x30921c0b),
-+     TOBN(0x48f301fa, 0x36a116a3), TOBN(0x380e1107, 0xcfd9ee6d),
-+     TOBN(0x7945ead8, 0x58854be1), TOBN(0x4111c12e, 0xcbd4d49d),
-+     TOBN(0xece3b1ec, 0x3a29c2ef), TOBN(0x6356d404, 0x8d3616f5),
-+     TOBN(0x9f0d6a8f, 0x594d320e), TOBN(0x0989316d, 0xf651ccd2),
-+     TOBN(0x6c32117a, 0x0f8fdde4), TOBN(0x9abe5cc5, 0xa26a9bbc),
-+     TOBN(0xcff560fb, 0x9723f671), TOBN(0x21b2a12d, 0x7f3d593c),
-+     TOBN(0xe4cb18da, 0x24ba0696), TOBN(0x186e2220, 0xc3543384),
-+     TOBN(0x722f64e0, 0x88312c29), TOBN(0x94282a99, 0x17dc7752),
-+     TOBN(0x62467bbf, 0x5a85ee89), TOBN(0xf435c650, 0xf10076a0),
-+     TOBN(0xc9ff1539, 0x43b3a50b), TOBN(0x7132130c, 0x1a53efbc),
-+     TOBN(0x31bfe063, 0xf7b0c5b7), TOBN(0xb0179a7d, 0x4ea994cc),
-+     TOBN(0x12d064b3, 0xc85f455b), TOBN(0x47259328, 0x8f6e0062),
-+     TOBN(0xf64e590b, 0xb875d6d9), TOBN(0x22dd6225, 0xad92bcc7),
-+     TOBN(0xb658038e, 0xb9c3bd6d), TOBN(0x00cdb0d6, 0xfbba27c8),
-+     TOBN(0x0c681337, 0x1062c45d), TOBN(0xd8515b8c, 0x2d33407d),
-+     TOBN(0xcb8f699e, 0x8cbb5ecf), TOBN(0x8c4347f8, 0xc608d7d8),
-+     TOBN(0x2c11850a, 0xbb3e00db), TOBN(0x20a8dafd, 0xecb49d19),
-+     TOBN(0xbd781480, 0x45ee2f40), TOBN(0x75e354af, 0x416b60cf),
-+     TOBN(0xde0b58a1, 0x8d49a8c4), TOBN(0xe40e94e2, 0xfa359536),
-+     TOBN(0xbd4fa59f, 0x62accd76), TOBN(0x05cf466a, 0x8c762837),
-+     TOBN(0xb5abda99, 0x448c277b), TOBN(0x5a9e01bf, 0x48b13740),
-+     TOBN(0x9d457798, 0x326aad8d), TOBN(0xbdef4954, 0xc396f7e7),
-+     TOBN(0x6fb274a2, 0xc253e292), TOBN(0x2800bf0a, 0x1cfe53e7),
-+     TOBN(0x22426d31, 0x44438fd4), TOBN(0xef233923, 0x5e259f9a),
-+     TOBN(0x4188503c, 0x03f66264), TOBN(0x9e5e7f13, 0x7f9fdfab),
-+     TOBN(0x565eb76c, 0x5fcc1aba), TOBN(0xea632548, 0x59b5bff8),
-+     TOBN(0x5587c087, 0xaab6d3fa), TOBN(0x92b639ea, 0x6ce39c1b),
-+     TOBN(0x0706e782, 0x953b135c), TOBN(0x7308912e, 0x425268ef),
-+     TOBN(0x599e92c7, 0x090e7469), TOBN(0x83b90f52, 0x9bc35e75),
-+     TOBN(0x4750b3d0, 0x244975b3), TOBN(0xf3a44358, 0x11965d72),
-+     TOBN(0x179c6774, 0x9c8dc751), TOBN(0xff18cdfe, 0xd23d9ff0),
-+     TOBN(0xc4013833, 0x2028e247), TOBN(0x96e280e2, 0xf3bfbc79),
-+     TOBN(0xf60417bd, 0xd0880a84), TOBN(0x263c9f3d, 0x2a568151),
-+     TOBN(0x36be15b3, 0x2d2ce811), TOBN(0x846dc0c2, 0xf8291d21),
-+     TOBN(0x5cfa0ecb, 0x789fcfdb), TOBN(0x45a0beed, 0xd7535b9a),
-+     TOBN(0xec8e9f07, 0x96d69af1), TOBN(0x31a7c5b8, 0x599ab6dc),
-+     TOBN(0xd36d45ef, 0xf9e2e09f), TOBN(0x3cf49ef1, 0xdcee954b),
-+     TOBN(0x6be34cf3, 0x086cff9b), TOBN(0x88dbd491, 0x39a3360f),
-+     TOBN(0x1e96b8cc, 0x0dbfbd1d), TOBN(0xc1e5f7bf, 0xcb7e2552),
-+     TOBN(0x0547b214, 0x28819d98), TOBN(0xc770dd9c, 0x7aea9dcb),
-+     TOBN(0xaef0d4c7, 0x041d68c8), TOBN(0xcc2b9818, 0x13cb9ba8),
-+     TOBN(0x7fc7bc76, 0xfe86c607), TOBN(0x6b7b9337, 0x502a9a95),
-+     TOBN(0x1948dc27, 0xd14dab63), TOBN(0x249dd198, 0xdae047be),
-+     TOBN(0xe8356584, 0xa981a202), TOBN(0x3531dd18, 0x3a893387),
-+     TOBN(0x1be11f90, 0xc85c7209), TOBN(0x93d2fe1e, 0xe2a52b5a),
-+     TOBN(0x8225bfe2, 0xec6d6b97), TOBN(0x9cf6d6f4, 0xbd0aa5de),
-+     TOBN(0x911459cb, 0x54779f5f), TOBN(0x5649cddb, 0x86aeb1f3),
-+     TOBN(0x32133579, 0x3f26ce5a), TOBN(0xc289a102, 0x550f431e),
-+     TOBN(0x559dcfda, 0x73b84c6f), TOBN(0x84973819, 0xee3ac4d7),
-+     TOBN(0xb51e55e6, 0xf2606a82), TOBN(0xe25f7061, 0x90f2fb57),
-+     TOBN(0xacef6c2a, 0xb1a4e37c), TOBN(0x864e359d, 0x5dcf2706),
-+     TOBN(0x479e6b18, 0x7ce57316), TOBN(0x2cab2500, 0x3a96b23d),
-+     TOBN(0xed489862, 0x8ef16df7), TOBN(0x2056538c, 0xef3758b5),
-+     TOBN(0xa7df865e, 0xf15d3101), TOBN(0x80c5533a, 0x61b553d7),
-+     TOBN(0x366e1997, 0x4ed14294), TOBN(0x6620741f, 0xb3c0bcd6),
-+     TOBN(0x21d1d9c4, 0xedc45418), TOBN(0x005b859e, 0xc1cc4a9d),
-+     TOBN(0xdf01f630, 0xa1c462f0), TOBN(0x15d06cf3, 0xf26820c7),
-+     TOBN(0x9f7f24ee, 0x3484be47), TOBN(0x2ff33e96, 0x4a0c902f),
-+     TOBN(0x00bdf457, 0x5a0bc453), TOBN(0x2378dfaf, 0x1aa238db),
-+     TOBN(0x272420ec, 0x856720f2), TOBN(0x2ad9d95b, 0x96797291),
-+     TOBN(0xd1242cc6, 0x768a1558), TOBN(0x2e287f8b, 0x5cc86aa8),
-+     TOBN(0x796873d0, 0x990cecaa), TOBN(0xade55f81, 0x675d4080),
-+     TOBN(0x2645eea3, 0x21f0cd84), TOBN(0x7a1efa0f, 0xb4e17d02),
-+     TOBN(0xf6858420, 0x037cc061), TOBN(0x682e05f0, 0xd5d43e12),
-+     TOBN(0x59c36994, 0x27218710), TOBN(0x85cbba4d, 0x3f7cd2fc),
-+     TOBN(0x726f9729, 0x7a3cd22a), TOBN(0x9f8cd5dc, 0x4a628397),
-+     TOBN(0x17b93ab9, 0xc23165ed), TOBN(0xff5f5dbf, 0x122823d4),
-+     TOBN(0xc1e4e4b5, 0x654a446d), TOBN(0xd1a9496f, 0x677257ba),
-+     TOBN(0x6387ba94, 0xde766a56), TOBN(0x23608bc8, 0x521ec74a),
-+     TOBN(0x16a522d7, 0x6688c4d4), TOBN(0x9d6b4282, 0x07373abd),
-+     TOBN(0xa62f07ac, 0xb42efaa3), TOBN(0xf73e00f7, 0xe3b90180),
-+     TOBN(0x36175fec, 0x49421c3e), TOBN(0xc4e44f9b, 0x3dcf2678),
-+     TOBN(0x76df436b, 0x7220f09f), TOBN(0x172755fb, 0x3aa8b6cf),
-+     TOBN(0xbab89d57, 0x446139cc), TOBN(0x0a0a6e02, 0x5fe0208f),
-+     TOBN(0xcdbb63e2, 0x11e5d399), TOBN(0x33ecaa12, 0xa8977f0b),
-+     TOBN(0x59598b21, 0xf7c42664), TOBN(0xb3e91b32, 0xab65d08a),
-+     TOBN(0x035822ee, 0xf4502526), TOBN(0x1dcf0176, 0x720a82a9),
-+     TOBN(0x50f8598f, 0x3d589e02), TOBN(0xdf0478ff, 0xb1d63d2c),
-+     TOBN(0x8b8068bd, 0x1571cd07), TOBN(0x30c3aa4f, 0xd79670cd),
-+     TOBN(0x25e8fd4b, 0x941ade7f), TOBN(0x3d1debdc, 0x32790011),
-+     TOBN(0x65b6dcbd, 0x3a3f9ff0), TOBN(0x282736a4, 0x793de69c),
-+     TOBN(0xef69a0c3, 0xd41d3bd3), TOBN(0xb533b8c9, 0x07a26bde),
-+     TOBN(0xe2801d97, 0xdb2edf9f), TOBN(0xdc4a8269, 0xe1877af0),
-+     TOBN(0x6c1c5851, 0x3d590dbe), TOBN(0x84632f6b, 0xee4e9357),
-+     TOBN(0xd36d36b7, 0x79b33374), TOBN(0xb46833e3, 0x9bbca2e6),
-+     TOBN(0x37893913, 0xf7fc0586), TOBN(0x385315f7, 0x66bf4719),
-+     TOBN(0x72c56293, 0xb31855dc), TOBN(0xd1416d4e, 0x849061fe),
-+     TOBN(0xbeb3ab78, 0x51047213), TOBN(0x447f6e61, 0xf040c996),
-+     TOBN(0xd06d310d, 0x638b1d0c), TOBN(0xe28a413f, 0xbad1522e),
-+     TOBN(0x685a76cb, 0x82003f86), TOBN(0x610d07f7, 0x0bcdbca3),
-+     TOBN(0x6ff66021, 0x9ca4c455), TOBN(0x7df39b87, 0xcea10eec),
-+     TOBN(0xb9255f96, 0xe22db218), TOBN(0x8cc6d9eb, 0x08a34c44),
-+     TOBN(0xcd4ffb86, 0x859f9276), TOBN(0x8fa15eb2, 0x50d07335),
-+     TOBN(0xdf553845, 0xcf2c24b5), TOBN(0x89f66a9f, 0x52f9c3ba),
-+     TOBN(0x8f22b5b9, 0xe4a7ceb3), TOBN(0xaffef809, 0x0e134686),
-+     TOBN(0x3e53e1c6, 0x8eb8fac2), TOBN(0x93c1e4eb, 0x28aec98e),
-+     TOBN(0xb6b91ec5, 0x32a43bcb), TOBN(0x2dbfa947, 0xb2d74a51),
-+     TOBN(0xe065d190, 0xca84bad7), TOBN(0xfb13919f, 0xad58e65c),
-+     TOBN(0x3c41718b, 0xf1cb6e31), TOBN(0x688969f0, 0x06d05c3f),
-+     TOBN(0xd4f94ce7, 0x21264d45), TOBN(0xfdfb65e9, 0x7367532b),
-+     TOBN(0x5b1be8b1, 0x0945a39d), TOBN(0x229f789c, 0x2b8baf3b),
-+     TOBN(0xd8f41f3e, 0x6f49f15d), TOBN(0x678ce828, 0x907f0792),
-+     TOBN(0xc69ace82, 0xfca6e867), TOBN(0x106451ae, 0xd01dcc89),
-+     TOBN(0x1bb4f7f0, 0x19fc32d2), TOBN(0x64633dfc, 0xb00c52d2),
-+     TOBN(0x8f13549a, 0xad9ea445), TOBN(0x99a3bf50, 0xfb323705),
-+     TOBN(0x0c9625a2, 0x534d4dbc), TOBN(0x45b8f1d1, 0xc2a2fea3),
-+     TOBN(0x76ec21a1, 0xa530fc1a), TOBN(0x4bac9c2a, 0x9e5bd734),
-+     TOBN(0x5996d76a, 0x7b4e3587), TOBN(0x0045cdee, 0x1182d9e3),
-+     TOBN(0x1aee24b9, 0x1207f13d), TOBN(0x66452e97, 0x97345a41),
-+     TOBN(0x16e5b054, 0x9f950cd0), TOBN(0x9cc72fb1, 0xd7fdd075),
-+     TOBN(0x6edd61e7, 0x66249663), TOBN(0xde4caa4d, 0xf043cccb),
-+     TOBN(0x11b1f57a, 0x55c7ac17), TOBN(0x779cbd44, 0x1a85e24d),
-+     TOBN(0x78030f86, 0xe46081e7), TOBN(0xfd4a6032, 0x8e20f643),
-+     TOBN(0xcc7a6488, 0x0a750c0f), TOBN(0x39bacfe3, 0x4e548e83),
-+     TOBN(0x3d418c76, 0x0c110f05), TOBN(0x3e4daa4c, 0xb1f11588),
-+     TOBN(0x2733e7b5, 0x5ffc69ff), TOBN(0x46f147bc, 0x92053127),
-+     TOBN(0x885b2434, 0xd722df94), TOBN(0x6a444f65, 0xe6fc6b7c)}
-+    ,
-+    {TOBN(0x7a1a465a, 0xc3f16ea8), TOBN(0x115a461d, 0xb2f1d11c),
-+     TOBN(0x4767dd95, 0x6c68a172), TOBN(0x3392f2eb, 0xd13a4698),
-+     TOBN(0xc7a99ccd, 0xe526cdc7), TOBN(0x8e537fdc, 0x22292b81),
-+     TOBN(0x76d8cf69, 0xa6d39198), TOBN(0xffc5ff43, 0x2446852d),
-+     TOBN(0x97b14f7e, 0xa90567e6), TOBN(0x513257b7, 0xb6ae5cb7),
-+     TOBN(0x85454a3c, 0x9f10903d), TOBN(0xd8d2c9ad, 0x69bc3724),
-+     TOBN(0x38da9324, 0x6b29cb44), TOBN(0xb540a21d, 0x77c8cbac),
-+     TOBN(0x9bbfe435, 0x01918e42), TOBN(0xfffa707a, 0x56c3614e),
-+     TOBN(0x0ce4e3f1, 0xd4e353b7), TOBN(0x062d8a14, 0xef46b0a0),
-+     TOBN(0x6408d5ab, 0x574b73fd), TOBN(0xbc41d1c9, 0xd3273ffd),
-+     TOBN(0x3538e1e7, 0x6be77800), TOBN(0x71fe8b37, 0xc5655031),
-+     TOBN(0x1cd91621, 0x6b9b331a), TOBN(0xad825d0b, 0xbb388f73),
-+     TOBN(0x56c2e05b, 0x1cb76219), TOBN(0x0ec0bf91, 0x71567e7e),
-+     TOBN(0xe7076f86, 0x61c4c910), TOBN(0xd67b085b, 0xbabc04d9),
-+     TOBN(0x9fb90459, 0x5e93a96a), TOBN(0x7526c1ea, 0xfbdc249a),
-+     TOBN(0x0d44d367, 0xecdd0bb7), TOBN(0x95399917, 0x9dc0d695),
-+     TOBN(0x61360ee9, 0x9e240d18), TOBN(0x057cdcac, 0xb4b94466),
-+     TOBN(0xe7667cd1, 0x2fe5325c), TOBN(0x1fa297b5, 0x21974e3b),
-+     TOBN(0xfa4081e7, 0xdb083d76), TOBN(0x31993be6, 0xf206bd15),
-+     TOBN(0x8949269b, 0x14c19f8c), TOBN(0x21468d72, 0xa9d92357),
-+     TOBN(0x2ccbc583, 0xa4c506ec), TOBN(0x957ed188, 0xd1acfe97),
-+     TOBN(0x8baed833, 0x12f1aea2), TOBN(0xef2a6cb4, 0x8325362d),
-+     TOBN(0x130dde42, 0x8e195c43), TOBN(0xc842025a, 0x0e6050c6),
-+     TOBN(0x2da972a7, 0x08686a5d), TOBN(0xb52999a1, 0xe508b4a8),
-+     TOBN(0xd9f090b9, 0x10a5a8bd), TOBN(0xca91d249, 0x096864da),
-+     TOBN(0x8e6a93be, 0x3f67dbc1), TOBN(0xacae6fba, 0xf5f4764c),
-+     TOBN(0x1563c6e0, 0xd21411a0), TOBN(0x28fa787f, 0xda0a4ad8),
-+     TOBN(0xd524491c, 0x908c8030), TOBN(0x1257ba0e, 0x4c795f07),
-+     TOBN(0x83f49167, 0xceca9754), TOBN(0x426d2cf6, 0x4b7939a0),
-+     TOBN(0x2555e355, 0x723fd0bf), TOBN(0xa96e6d06, 0xc4f144e2),
-+     TOBN(0x4768a8dd, 0x87880e61), TOBN(0x15543815, 0xe508e4d5),
-+     TOBN(0x09d7e772, 0xb1b65e15), TOBN(0x63439dd6, 0xac302fa0),
-+     TOBN(0xb93f802f, 0xc14e35c2), TOBN(0x71735b7c, 0x4341333c),
-+     TOBN(0x03a25104, 0x16d4f362), TOBN(0x3f4d069b, 0xbf433c8e),
-+     TOBN(0x0d83ae01, 0xf78f5a7c), TOBN(0x50a8ffbe, 0x7c4eed07),
-+     TOBN(0xc74f8906, 0x76e10f83), TOBN(0x7d080966, 0x9ddaf8e1),
-+     TOBN(0xb11df8e1, 0x698e04cc), TOBN(0x877be203, 0x169005c8),
-+     TOBN(0x32749e8c, 0x4f3c6179), TOBN(0x2dbc9d0a, 0x7853fc05),
-+     TOBN(0x187d4f93, 0x9454d937), TOBN(0xe682ce9d, 0xb4800e1b),
-+     TOBN(0xa9129ad8, 0x165e68e8), TOBN(0x0fe29735, 0xbe7f785b),
-+     TOBN(0x5303f40c, 0x5b9e02b7), TOBN(0xa37c9692, 0x35ee04e8),
-+     TOBN(0x5f46cc20, 0x34d6632b), TOBN(0x55ef72b2, 0x96ac545b),
-+     TOBN(0xabec5c1f, 0x7b91b062), TOBN(0x0a79e1c7, 0xbb33e821),
-+     TOBN(0xbb04b428, 0x3a9f4117), TOBN(0x0de1f28f, 0xfd2a475a),
-+     TOBN(0x31019ccf, 0x3a4434b4), TOBN(0xa3458111, 0x1a7954dc),
-+     TOBN(0xa9dac80d, 0xe34972a7), TOBN(0xb043d054, 0x74f6b8dd),
-+     TOBN(0x021c319e, 0x11137b1a), TOBN(0x00a754ce, 0xed5cc03f),
-+     TOBN(0x0aa2c794, 0xcbea5ad4), TOBN(0x093e67f4, 0x70c015b6),
-+     TOBN(0x72cdfee9, 0xc97e3f6b), TOBN(0xc10bcab4, 0xb6da7461),
-+     TOBN(0x3b02d2fc, 0xb59806b9), TOBN(0x85185e89, 0xa1de6f47),
-+     TOBN(0x39e6931f, 0x0eb6c4d4), TOBN(0x4d4440bd, 0xd4fa5b04),
-+     TOBN(0x5418786e, 0x34be7eb8), TOBN(0x6380e521, 0x9d7259bc),
-+     TOBN(0x20ac0351, 0xd598d710), TOBN(0x272c4166, 0xcb3a4da4),
-+     TOBN(0xdb82fe1a, 0xca71de1f), TOBN(0x746e79f2, 0xd8f54b0f),
-+     TOBN(0x6e7fc736, 0x4b573e9b), TOBN(0x75d03f46, 0xfd4b5040),
-+     TOBN(0x5c1cc36d, 0x0b98d87b), TOBN(0x513ba3f1, 0x1f472da1),
-+     TOBN(0x79d0af26, 0xabb177dd), TOBN(0xf82ab568, 0x7891d564),
-+     TOBN(0x2b6768a9, 0x72232173), TOBN(0xefbb3bb0, 0x8c1f6619),
-+     TOBN(0xb29c11db, 0xa6d18358), TOBN(0x519e2797, 0xb0916d3a),
-+     TOBN(0xd4dc18f0, 0x9188e290), TOBN(0x648e86e3, 0x98b0ca7f),
-+     TOBN(0x859d3145, 0x983c38b5), TOBN(0xb14f176c, 0x637abc8b),
-+     TOBN(0x2793fb9d, 0xcaff7be6), TOBN(0xebe5a55f, 0x35a66a5a),
-+     TOBN(0x7cec1dcd, 0x9f87dc59), TOBN(0x7c595cd3, 0xfbdbf560),
-+     TOBN(0x5b543b22, 0x26eb3257), TOBN(0x69080646, 0xc4c935fd),
-+     TOBN(0x7f2e4403, 0x81e9ede3), TOBN(0x243c3894, 0xcaf6df0a),
-+     TOBN(0x7c605bb1, 0x1c073b11), TOBN(0xcd06a541, 0xba6a4a62),
-+     TOBN(0x29168949, 0x49d4e2e5), TOBN(0x33649d07, 0x4af66880),
-+     TOBN(0xbfc0c885, 0xe9a85035), TOBN(0xb4e52113, 0xfc410f4b),
-+     TOBN(0xdca3b706, 0x78a6513b), TOBN(0x92ea4a2a, 0x9edb1943),
-+     TOBN(0x02642216, 0xdb6e2dd8), TOBN(0x9b45d0b4, 0x9fd57894),
-+     TOBN(0x114e70db, 0xc69d11ae), TOBN(0x1477dd19, 0x4c57595f),
-+     TOBN(0xbc2208b4, 0xec77c272), TOBN(0x95c5b4d7, 0xdb68f59c),
-+     TOBN(0xb8c4fc63, 0x42e532b7), TOBN(0x386ba422, 0x9ae35290),
-+     TOBN(0xfb5dda42, 0xd201ecbc), TOBN(0x2353dc8b, 0xa0e38fd6),
-+     TOBN(0x9a0b85ea, 0x68f7e978), TOBN(0x96ec5682, 0x2ad6d11f),
-+     TOBN(0x5e279d6c, 0xe5f6886d), TOBN(0xd3fe03cd, 0x3cb1914d),
-+     TOBN(0xfe541fa4, 0x7ea67c77), TOBN(0x952bd2af, 0xe3ea810c),
-+     TOBN(0x791fef56, 0x8d01d374), TOBN(0xa3a1c621, 0x0f11336e),
-+     TOBN(0x5ad0d5a9, 0xc7ec6d79), TOBN(0xff7038af, 0x3225c342),
-+     TOBN(0x003c6689, 0xbc69601b), TOBN(0x25059bc7, 0x45e8747d),
-+     TOBN(0xfa4965b2, 0xf2086fbf), TOBN(0xf6840ea6, 0x86916078),
-+     TOBN(0xd7ac7620, 0x70081d6c), TOBN(0xe600da31, 0xb5328645),
-+     TOBN(0x01916f63, 0x529b8a80), TOBN(0xe80e4858, 0x2d7d6f3e),
-+     TOBN(0x29eb0fe8, 0xd664ca7c), TOBN(0xf017637b, 0xe7b43b0c),
-+     TOBN(0x9a75c806, 0x76cb2566), TOBN(0x8f76acb1, 0xb24892d9),
-+     TOBN(0x7ae7b9cc, 0x1f08fe45), TOBN(0x19ef7329, 0x6a4907d8),
-+     TOBN(0x2db4ab71, 0x5f228bf0), TOBN(0xf3cdea39, 0x817032d7),
-+     TOBN(0x0b1f482e, 0xdcabe3c0), TOBN(0x3baf76b4, 0xbb86325c),
-+     TOBN(0xd49065e0, 0x10089465), TOBN(0x3bab5d29, 0x8e77c596),
-+     TOBN(0x7636c3a6, 0x193dbd95), TOBN(0xdef5d294, 0xb246e499),
-+     TOBN(0xb22c58b9, 0x286b2475), TOBN(0xa0b93939, 0xcd80862b),
-+     TOBN(0x3002c83a, 0xf0992388), TOBN(0x6de01f9b, 0xeacbe14c),
-+     TOBN(0x6aac688e, 0xadd70482), TOBN(0x708de92a, 0x7b4a4e8a),
-+     TOBN(0x75b6dd73, 0x758a6eef), TOBN(0xea4bf352, 0x725b3c43),
-+     TOBN(0x10041f2c, 0x87912868), TOBN(0xb1b1be95, 0xef09297a),
-+     TOBN(0x19ae23c5, 0xa9f3860a), TOBN(0xc4f0f839, 0x515dcf4b),
-+     TOBN(0x3c7ecca3, 0x97f6306a), TOBN(0x744c44ae, 0x68a3a4b0),
-+     TOBN(0x69cd13a0, 0xb3a1d8a2), TOBN(0x7cad0a1e, 0x5256b578),
-+     TOBN(0xea653fcd, 0x33791d9e), TOBN(0x9cc2a05d, 0x74b2e05f),
-+     TOBN(0x73b391dc, 0xfd7affa2), TOBN(0xddb7091e, 0xb6b05442),
-+     TOBN(0xc71e27bf, 0x8538a5c6), TOBN(0x195c63dd, 0x89abff17),
-+     TOBN(0xfd315285, 0x1b71e3da), TOBN(0x9cbdfda7, 0xfa680fa0),
-+     TOBN(0x9db876ca, 0x849d7eab), TOBN(0xebe2764b, 0x3c273271),
-+     TOBN(0x663357e3, 0xf208dcea), TOBN(0x8c5bd833, 0x565b1b70),
-+     TOBN(0xccc3b4f5, 0x9837fc0d), TOBN(0x9b641ba8, 0xa79cf00f),
-+     TOBN(0x7428243d, 0xdfdf3990), TOBN(0x83a594c4, 0x020786b1),
-+     TOBN(0xb712451a, 0x526c4502), TOBN(0x9d39438e, 0x6adb3f93),
-+     TOBN(0xfdb261e3, 0xe9ff0ccd), TOBN(0x80344e3c, 0xe07af4c3),
-+     TOBN(0x75900d7c, 0x2fa4f126), TOBN(0x08a3b865, 0x5c99a232),
-+     TOBN(0x2478b6bf, 0xdb25e0c3), TOBN(0x482cc2c2, 0x71db2edf),
-+     TOBN(0x37df7e64, 0x5f321bb8), TOBN(0x8a93821b, 0x9a8005b4),
-+     TOBN(0x3fa2f10c, 0xcc8c1958), TOBN(0x0d332218, 0x2c269d0a),
-+     TOBN(0x20ab8119, 0xe246b0e6), TOBN(0xb39781e4, 0xd349fd17),
-+     TOBN(0xd293231e, 0xb31aa100), TOBN(0x4b779c97, 0xbb032168),
-+     TOBN(0x4b3f19e1, 0xc8470500), TOBN(0x45b7efe9, 0x0c4c869d),
-+     TOBN(0xdb84f38a, 0xa1a6bbcc), TOBN(0x3b59cb15, 0xb2fddbc1),
-+     TOBN(0xba5514df, 0x3fd165e8), TOBN(0x499fd6a9, 0x061f8811),
-+     TOBN(0x72cd1fe0, 0xbfef9f00), TOBN(0x120a4bb9, 0x79ad7e8a),
-+     TOBN(0xf2ffd095, 0x5f4a5ac5), TOBN(0xcfd174f1, 0x95a7a2f0),
-+     TOBN(0xd42301ba, 0x9d17baf1), TOBN(0xd2fa487a, 0x77f22089),
-+     TOBN(0x9cb09efe, 0xb1dc77e1), TOBN(0xe9566939, 0x21c99682),
-+     TOBN(0x8c546901, 0x6c6067bb), TOBN(0xfd378574, 0x61c24456),
-+     TOBN(0x2b6a6cbe, 0x81796b33), TOBN(0x62d550f6, 0x58e87f8b),
-+     TOBN(0x1b763e1c, 0x7f1b01b4), TOBN(0x4b93cfea, 0x1b1b5e12),
-+     TOBN(0xb9345238, 0x1d531696), TOBN(0x57201c00, 0x88cdde69),
-+     TOBN(0xdde92251, 0x9a86afc7), TOBN(0xe3043895, 0xbd35cea8),
-+     TOBN(0x7608c1e1, 0x8555970d), TOBN(0x8267dfa9, 0x2535935e),
-+     TOBN(0xd4c60a57, 0x322ea38b), TOBN(0xe0bf7977, 0x804ef8b5),
-+     TOBN(0x1a0dab28, 0xc06fece4), TOBN(0xd405991e, 0x94e7b49d),
-+     TOBN(0xc542b6d2, 0x706dab28), TOBN(0xcb228da3, 0xa91618fb),
-+     TOBN(0x224e4164, 0x107d1cea), TOBN(0xeb9fdab3, 0xd0f5d8f1),
-+     TOBN(0xc02ba386, 0x0d6e41cd), TOBN(0x676a72c5, 0x9b1f7146),
-+     TOBN(0xffd6dd98, 0x4d6cb00b), TOBN(0xcef9c5ca, 0xde2e8d7c),
-+     TOBN(0xa1bbf5d7, 0x641c7936), TOBN(0x1b95b230, 0xee8f772e),
-+     TOBN(0xf765a92e, 0xe8ac25b1), TOBN(0xceb04cfc, 0x3a18b7c6),
-+     TOBN(0x27944cef, 0x0acc8966), TOBN(0xcbb3c957, 0x434c1004),
-+     TOBN(0x9c9971a1, 0xa43ff93c), TOBN(0x5bc2db17, 0xa1e358a9),
-+     TOBN(0x45b4862e, 0xa8d9bc82), TOBN(0x70ebfbfb, 0x2201e052),
-+     TOBN(0xafdf64c7, 0x92871591), TOBN(0xea5bcae6, 0xb42d0219),
-+     TOBN(0xde536c55, 0x2ad8f03c), TOBN(0xcd6c3f4d, 0xa76aa33c),
-+     TOBN(0xbeb5f623, 0x0bca6de3), TOBN(0xdd20dd99, 0xb1e706fd),
-+     TOBN(0x90b3ff9d, 0xac9059d4), TOBN(0x2d7b2902, 0x7ccccc4e),
-+     TOBN(0x8a090a59, 0xce98840f), TOBN(0xa5d947e0, 0x8410680a),
-+     TOBN(0x49ae346a, 0x923379a5), TOBN(0x7dbc84f9, 0xb28a3156),
-+     TOBN(0xfd40d916, 0x54a1aff2), TOBN(0xabf318ba, 0x3a78fb9b),
-+     TOBN(0x50152ed8, 0x3029f95e), TOBN(0x9fc1dd77, 0xc58ad7fa),
-+     TOBN(0x5fa57915, 0x13595c17), TOBN(0xb9504668, 0x8f62b3a9),
-+     TOBN(0x907b5b24, 0xff3055b0), TOBN(0x2e995e35, 0x9a84f125),
-+     TOBN(0x87dacf69, 0x7e9bbcfb), TOBN(0x95d0c1d6, 0xe86d96e3),
-+     TOBN(0x65726e3c, 0x2d95a75c), TOBN(0x2c3c9001, 0xacd27f21),
-+     TOBN(0x1deab561, 0x6c973f57), TOBN(0x108b7e2c, 0xa5221643),
-+     TOBN(0x5fee9859, 0xc4ef79d4), TOBN(0xbd62b88a, 0x40d4b8c6),
-+     TOBN(0xb4dd29c4, 0x197c75d6), TOBN(0x266a6df2, 0xb7076feb),
-+     TOBN(0x9512d0ea, 0x4bf2df11), TOBN(0x1320c24f, 0x6b0cc9ec),
-+     TOBN(0x6bb1e0e1, 0x01a59596), TOBN(0x8317c5bb, 0xeff9aaac),
-+     TOBN(0x65bb405e, 0x385aa6c9), TOBN(0x613439c1, 0x8f07988f),
-+     TOBN(0xd730049f, 0x16a66e91), TOBN(0xe97f2820, 0xfa1b0e0d),
-+     TOBN(0x4131e003, 0x304c28ea), TOBN(0x820ab732, 0x526bac62),
-+     TOBN(0xb2ac9ef9, 0x28714423), TOBN(0x54ecfffa, 0xadb10cb2),
-+     TOBN(0x8781476e, 0xf886a4cc), TOBN(0x4b2c87b5, 0xdb2f8d49),
-+     TOBN(0xe857cd20, 0x0a44295d), TOBN(0x707d7d21, 0x58c6b044),
-+     TOBN(0xae8521f9, 0xf596757c), TOBN(0x87448f03, 0x67b2b714),
-+     TOBN(0x13a9bc45, 0x5ebcd58d), TOBN(0x79bcced9, 0x9122d3c1),
-+     TOBN(0x3c644247, 0x9e076642), TOBN(0x0cf22778, 0x2df4767d),
-+     TOBN(0x5e61aee4, 0x71d444b6), TOBN(0x211236bf, 0xc5084a1d),
-+     TOBN(0x7e15bc9a, 0x4fd3eaf6), TOBN(0x68df2c34, 0xab622bf5),
-+     TOBN(0x9e674f0f, 0x59bf4f36), TOBN(0xf883669b, 0xd7f34d73),
-+     TOBN(0xc48ac1b8, 0x31497b1d), TOBN(0x323b925d, 0x5106703b),
-+     TOBN(0x22156f42, 0x74082008), TOBN(0xeffc521a, 0xc8482bcb),
-+     TOBN(0x5c6831bf, 0x12173479), TOBN(0xcaa2528f, 0xc4739490),
-+     TOBN(0x84d2102a, 0x8f1b3c4d), TOBN(0xcf64dfc1, 0x2d9bec0d),
-+     TOBN(0x433febad, 0x78a546ef), TOBN(0x1f621ec3, 0x7b73cef1),
-+     TOBN(0x6aecd627, 0x37338615), TOBN(0x162082ab, 0x01d8edf6),
-+     TOBN(0x833a8119, 0x19e86b66), TOBN(0x6023a251, 0xd299b5db),
-+     TOBN(0xf5bb0c3a, 0xbbf04b89), TOBN(0x6735eb69, 0xae749a44),
-+     TOBN(0xd0e058c5, 0x4713de3b), TOBN(0xfdf2593e, 0x2c3d4ccd),
-+     TOBN(0x1b8f414e, 0xfdd23667), TOBN(0xdd52aaca, 0xfa2015ee),
-+     TOBN(0x3e31b517, 0xbd9625ff), TOBN(0x5ec9322d, 0x8db5918c),
-+     TOBN(0xbc73ac85, 0xa96f5294), TOBN(0x82aa5bf3, 0x61a0666a),
-+     TOBN(0x49755810, 0xbf08ac42), TOBN(0xd21cdfd5, 0x891cedfc),
-+     TOBN(0x918cb57b, 0x67f8be10), TOBN(0x365d1a7c, 0x56ffa726),
-+     TOBN(0x2435c504, 0x6532de93), TOBN(0xc0fc5e10, 0x2674cd02),
-+     TOBN(0x6e51fcf8, 0x9cbbb142), TOBN(0x1d436e5a, 0xafc50692),
-+     TOBN(0x766bffff, 0x3fbcae22), TOBN(0x3148c2fd, 0xfd55d3b8),
-+     TOBN(0x52c7fdc9, 0x233222fa), TOBN(0x89ff1092, 0xe419fb6b),
-+     TOBN(0x3cd6db99, 0x25254977), TOBN(0x2e85a161, 0x1cf12ca7),
-+     TOBN(0xadd2547c, 0xdc810bc9), TOBN(0xea3f458f, 0x9d257c22),
-+     TOBN(0x642c1fbe, 0x27d6b19b), TOBN(0xed07e6b5, 0x140481a6),
-+     TOBN(0x6ada1d42, 0x86d2e0f8), TOBN(0xe5920122, 0x0e8a9fd5),
-+     TOBN(0x02c936af, 0x708c1b49), TOBN(0x60f30fee, 0x2b4bfaff),
-+     TOBN(0x6637ad06, 0x858e6a61), TOBN(0xce4c7767, 0x3fd374d0),
-+     TOBN(0x39d54b2d, 0x7188defb), TOBN(0xa8c9d250, 0xf56a6b66),
-+     TOBN(0x58fc0f5e, 0xb24fe1dc), TOBN(0x9eaf9dee, 0x6b73f24c),
-+     TOBN(0xa90d588b, 0x33650705), TOBN(0xde5b62c5, 0xaf2ec729),
-+     TOBN(0x5c72cfae, 0xd3c2b36e), TOBN(0x868c19d5, 0x034435da),
-+     TOBN(0x88605f93, 0xe17ee145), TOBN(0xaa60c4ee, 0x77a5d5b1),
-+     TOBN(0xbcf5bfd2, 0x3b60c472), TOBN(0xaf4ef13c, 0xeb1d3049),
-+     TOBN(0x373f44fc, 0xe13895c9), TOBN(0xf29b382f, 0x0cbc9822),
-+     TOBN(0x1bfcb853, 0x73efaef6), TOBN(0xcf56ac9c, 0xa8c96f40),
-+     TOBN(0xd7adf109, 0x7a191e24), TOBN(0x98035f44, 0xbf8a8dc2),
-+     TOBN(0xf40a71b9, 0x1e750c84), TOBN(0xc57f7b0c, 0x5dc6c469),
-+     TOBN(0x49a0e79c, 0x6fbc19c1), TOBN(0x6b0f5889, 0xa48ebdb8),
-+     TOBN(0x5d3fd084, 0xa07c4e9f), TOBN(0xc3830111, 0xab27de14),
-+     TOBN(0x0e4929fe, 0x33e08dcc), TOBN(0xf4a5ad24, 0x40bb73a3),
-+     TOBN(0xde86c2bf, 0x490f97ca), TOBN(0x288f09c6, 0x67a1ce18),
-+     TOBN(0x364bb886, 0x1844478d), TOBN(0x7840fa42, 0xceedb040),
-+     TOBN(0x1269fdd2, 0x5a631b37), TOBN(0x94761f1e, 0xa47c8b7d),
-+     TOBN(0xfc0c2e17, 0x481c6266), TOBN(0x85e16ea2, 0x3daa5fa7),
-+     TOBN(0xccd86033, 0x92491048), TOBN(0x0c2f6963, 0xf4d402d7),
-+     TOBN(0x6336f7df, 0xdf6a865c), TOBN(0x0a2a463c, 0xb5c02a87),
-+     TOBN(0xb0e29be7, 0xbf2f12ee), TOBN(0xf0a22002, 0x66bad988),
-+     TOBN(0x27f87e03, 0x9123c1d7), TOBN(0x21669c55, 0x328a8c98),
-+     TOBN(0x186b9803, 0x92f14529), TOBN(0xd3d056cc, 0x63954df3),
-+     TOBN(0x2f03fd58, 0x175a46f6), TOBN(0x63e34ebe, 0x11558558),
-+     TOBN(0xe13fedee, 0x5b80cfa5), TOBN(0xe872a120, 0xd401dbd1),
-+     TOBN(0x52657616, 0xe8a9d667), TOBN(0xbc8da4b6, 0xe08d6693),
-+     TOBN(0x370fb9bb, 0x1b703e75), TOBN(0x6773b186, 0xd4338363),
-+     TOBN(0x18dad378, 0xecef7bff), TOBN(0xaac787ed, 0x995677da),
-+     TOBN(0x4801ea8b, 0x0437164b), TOBN(0xf430ad20, 0x73fe795e),
-+     TOBN(0xb164154d, 0x8ee5eb73), TOBN(0x0884ecd8, 0x108f7c0e),
-+     TOBN(0x0e6ec096, 0x5f520698), TOBN(0x640631fe, 0x44f7b8d9),
-+     TOBN(0x92fd34fc, 0xa35a68b9), TOBN(0x9c5a4b66, 0x4d40cf4e),
-+     TOBN(0x949454bf, 0x80b6783d), TOBN(0x80e701fe, 0x3a320a10),
-+     TOBN(0x8d1a564a, 0x1a0a39b2), TOBN(0x1436d53d, 0x320587db),
-+     TOBN(0xf5096e6d, 0x6556c362), TOBN(0xbc23a3c0, 0xe2455d7e),
-+     TOBN(0x3a7aee54, 0x807230f9), TOBN(0x9ba1cfa6, 0x22ae82fd),
-+     TOBN(0x833a057a, 0x99c5d706), TOBN(0x8be85f4b, 0x842315c9),
-+     TOBN(0xd083179a, 0x66a72f12), TOBN(0x2fc77d5d, 0xcdcc73cd),
-+     TOBN(0x22b88a80, 0x5616ee30), TOBN(0xfb09548f, 0xe7ab1083),
-+     TOBN(0x8ad6ab0d, 0x511270cd), TOBN(0x61f6c57a, 0x6924d9ab),
-+     TOBN(0xa0f7bf72, 0x90aecb08), TOBN(0x849f87c9, 0x0df784a4),
-+     TOBN(0x27c79c15, 0xcfaf1d03), TOBN(0xbbf9f675, 0xc463face),
-+     TOBN(0x91502c65, 0x765ba543), TOBN(0x18ce3cac, 0x42ea60dd),
-+     TOBN(0xe5cee6ac, 0x6e43ecb3), TOBN(0x63e4e910, 0x68f2aeeb),
-+     TOBN(0x26234fa3, 0xc85932ee), TOBN(0x96883e8b, 0x4c90c44d),
-+     TOBN(0x29b9e738, 0xa18a50f6), TOBN(0xbfc62b2a, 0x3f0420df),
-+     TOBN(0xd22a7d90, 0x6d3e1fa9), TOBN(0x17115618, 0xfe05b8a3),
-+     TOBN(0x2a0c9926, 0xbb2b9c01), TOBN(0xc739fcc6, 0xe07e76a2),
-+     TOBN(0x540e9157, 0x165e439a), TOBN(0x06353a62, 0x6a9063d8),
-+     TOBN(0x84d95594, 0x61e927a3), TOBN(0x013b9b26, 0xe2e0be7f),
-+     TOBN(0x4feaec3b, 0x973497f1), TOBN(0x15c0f94e, 0x093ebc2d),
-+     TOBN(0x6af5f227, 0x33af0583), TOBN(0x0c2af206, 0xc61f3340),
-+     TOBN(0xd25dbdf1, 0x4457397c), TOBN(0x2e8ed017, 0xcabcbae0),
-+     TOBN(0xe3010938, 0xc2815306), TOBN(0xbaa99337, 0xe8c6cd68),
-+     TOBN(0x08513182, 0x3b0ec7de), TOBN(0x1e1b822b, 0x58df05df),
-+     TOBN(0x5c14842f, 0xa5c3b683), TOBN(0x98fe977e, 0x3eba34ce),
-+     TOBN(0xfd2316c2, 0x0d5e8873), TOBN(0xe48d839a, 0xbd0d427d),
-+     TOBN(0x495b2218, 0x623fc961), TOBN(0x24ee56e7, 0xb46fba5e),
-+     TOBN(0x9184a55b, 0x91e4de58), TOBN(0xa7488ca5, 0xdfdea288),
-+     TOBN(0xa723862e, 0xa8dcc943), TOBN(0x92d762b2, 0x849dc0fc),
-+     TOBN(0x3c444a12, 0x091ff4a9), TOBN(0x581113fa, 0x0cada274),
-+     TOBN(0xb9de0a45, 0x30d8eae2), TOBN(0x5e0fcd85, 0xdf6b41ea),
-+     TOBN(0x6233ea68, 0xc094dbb5), TOBN(0xb77d062e, 0xd968d410),
-+     TOBN(0x3e719bbc, 0x58b3002d), TOBN(0x68e7dd3d, 0x3dc49d58),
-+     TOBN(0x8d825740, 0x013a5e58), TOBN(0x21311747, 0x3c9e3c1b),
-+     TOBN(0x0cb0a2a7, 0x7c99b6ab), TOBN(0x5c48a3b3, 0xc2f888f2)}
-+    ,
-+    {TOBN(0xc7913e91, 0x991724f3), TOBN(0x5eda799c, 0x39cbd686),
-+     TOBN(0xddb595c7, 0x63d4fc1e), TOBN(0x6b63b80b, 0xac4fed54),
-+     TOBN(0x6ea0fc69, 0x7e5fb516), TOBN(0x737708ba, 0xd0f1c964),
-+     TOBN(0x9628745f, 0x11a92ca5), TOBN(0x61f37958, 0x9a86967a),
-+     TOBN(0x9af39b2c, 0xaa665072), TOBN(0x78322fa4, 0xefd324ef),
-+     TOBN(0x3d153394, 0xc327bd31), TOBN(0x81d5f271, 0x3129dab0),
-+     TOBN(0xc72e0c42, 0xf48027f5), TOBN(0xaa40cdbc, 0x8536e717),
-+     TOBN(0xf45a657a, 0x2d369d0f), TOBN(0xb03bbfc4, 0xea7f74e6),
-+     TOBN(0x46a8c418, 0x0d738ded), TOBN(0x6f1a5bb0, 0xe0de5729),
-+     TOBN(0xf10230b9, 0x8ba81675), TOBN(0x32c6f30c, 0x112b33d4),
-+     TOBN(0x7559129d, 0xd8fffb62), TOBN(0x6a281b47, 0xb459bf05),
-+     TOBN(0x77c1bd3a, 0xfa3b6776), TOBN(0x0709b380, 0x7829973a),
-+     TOBN(0x8c26b232, 0xa3326505), TOBN(0x38d69272, 0xee1d41bf),
-+     TOBN(0x0459453e, 0xffe32afa), TOBN(0xce8143ad, 0x7cb3ea87),
-+     TOBN(0x932ec1fa, 0x7e6ab666), TOBN(0x6cd2d230, 0x22286264),
-+     TOBN(0x459a46fe, 0x6736f8ed), TOBN(0x50bf0d00, 0x9eca85bb),
-+     TOBN(0x0b825852, 0x877a21ec), TOBN(0x300414a7, 0x0f537a94),
-+     TOBN(0x3f1cba40, 0x21a9a6a2), TOBN(0x50824eee, 0x76943c00),
-+     TOBN(0xa0dbfcec, 0xf83cba5d), TOBN(0xf9538148, 0x93b4f3c0),
-+     TOBN(0x61744162, 0x48f24dd7), TOBN(0x5322d64d, 0xe4fb09dd),
-+     TOBN(0x57447384, 0x3d9325f3), TOBN(0xa9bef2d0, 0xf371cb84),
-+     TOBN(0x77d2188b, 0xa61e36c5), TOBN(0xbbd6a7d7, 0xc602df72),
-+     TOBN(0xba3aa902, 0x8f61bc0b), TOBN(0xf49085ed, 0x6ed0b6a1),
-+     TOBN(0x8bc625d6, 0xae6e8298), TOBN(0x832b0b1d, 0xa2e9c01d),
-+     TOBN(0xa337c447, 0xf1f0ced1), TOBN(0x800cc793, 0x9492dd2b),
-+     TOBN(0x4b93151d, 0xbea08efa), TOBN(0x820cf3f8, 0xde0a741e),
-+     TOBN(0xff1982dc, 0x1c0f7d13), TOBN(0xef921960, 0x84dde6ca),
-+     TOBN(0x1ad7d972, 0x45f96ee3), TOBN(0x319c8dbe, 0x29dea0c7),
-+     TOBN(0xd3ea3871, 0x7b82b99b), TOBN(0x75922d4d, 0x470eb624),
-+     TOBN(0x8f66ec54, 0x3b95d466), TOBN(0x66e673cc, 0xbee1e346),
-+     TOBN(0x6afe67c4, 0xb5f2b89a), TOBN(0x3de9c1e6, 0x290e5cd3),
-+     TOBN(0x8c278bb6, 0x310a2ada), TOBN(0x420fa384, 0x0bdb323b),
-+     TOBN(0x0ae1d63b, 0x0eb919b0), TOBN(0xd74ee51d, 0xa74b9620),
-+     TOBN(0x395458d0, 0xa674290c), TOBN(0x324c930f, 0x4620a510),
-+     TOBN(0x2d1f4d19, 0xfbac27d4), TOBN(0x4086e8ca, 0x9bedeeac),
-+     TOBN(0x0cdd211b, 0x9b679ab8), TOBN(0x5970167d, 0x7090fec4),
-+     TOBN(0x3420f2c9, 0xfaf1fc63), TOBN(0x616d333a, 0x328c8bb4),
-+     TOBN(0x7d65364c, 0x57f1fe4a), TOBN(0x9343e877, 0x55e5c73a),
-+     TOBN(0x5795176b, 0xe970e78c), TOBN(0xa36ccebf, 0x60533627),
-+     TOBN(0xfc7c7380, 0x09cdfc1b), TOBN(0xb39a2afe, 0xb3fec326),
-+     TOBN(0xb7ff1ba1, 0x6224408a), TOBN(0xcc856e92, 0x247cfc5e),
-+     TOBN(0x01f102e7, 0xc18bc493), TOBN(0x4613ab74, 0x2091c727),
-+     TOBN(0xaa25e89c, 0xc420bf2b), TOBN(0x00a53176, 0x90337ec2),
-+     TOBN(0xd2be9f43, 0x7d025fc7), TOBN(0x3316fb85, 0x6e6fe3dc),
-+     TOBN(0x27520af5, 0x9ac50814), TOBN(0xfdf95e78, 0x9a8e4223),
-+     TOBN(0xb7e7df2a, 0x56bec5a0), TOBN(0xf7022f7d, 0xdf159e5d),
-+     TOBN(0x93eeeab1, 0xcac1fe8f), TOBN(0x8040188c, 0x37451168),
-+     TOBN(0x7ee8aa8a, 0xd967dce6), TOBN(0xfa0e79e7, 0x3abc9299),
-+     TOBN(0x67332cfc, 0x2064cfd1), TOBN(0x339c31de, 0xb0651934),
-+     TOBN(0x719b28d5, 0x2a3bcbea), TOBN(0xee74c82b, 0x9d6ae5c6),
-+     TOBN(0x0927d05e, 0xbaf28ee6), TOBN(0x82cecf2c, 0x9d719028),
-+     TOBN(0x0b0d353e, 0xddb30289), TOBN(0xfe4bb977, 0xfddb2e29),
-+     TOBN(0xbb5bb990, 0x640bfd9e), TOBN(0xd226e277, 0x82f62108),
-+     TOBN(0x4bf00985, 0x02ffdd56), TOBN(0x7756758a, 0x2ca1b1b5),
-+     TOBN(0xc32b62a3, 0x5285fe91), TOBN(0xedbc546a, 0x8c9cd140),
-+     TOBN(0x1e47a013, 0xaf5cb008), TOBN(0xbca7e720, 0x073ce8f2),
-+     TOBN(0xe10b2ab8, 0x17a91cae), TOBN(0xb89aab65, 0x08e27f63),
-+     TOBN(0x7b3074a7, 0xdba3ddf9), TOBN(0x1c20ce09, 0x330c2972),
-+     TOBN(0x6b9917b4, 0x5fcf7e33), TOBN(0xe6793743, 0x945ceb42),
-+     TOBN(0x18fc2215, 0x5c633d19), TOBN(0xad1adb3c, 0xc7485474),
-+     TOBN(0x646f9679, 0x6424c49b), TOBN(0xf888dfe8, 0x67c241c9),
-+     TOBN(0xe12d4b93, 0x24f68b49), TOBN(0x9a6b62d8, 0xa571df20),
-+     TOBN(0x81b4b26d, 0x179483cb), TOBN(0x666f9632, 0x9511fae2),
-+     TOBN(0xd281b3e4, 0xd53aa51f), TOBN(0x7f96a765, 0x7f3dbd16),
-+     TOBN(0xa7f8b5bf, 0x074a30ce), TOBN(0xd7f52107, 0x005a32e6),
-+     TOBN(0x6f9e0907, 0x50237ed4), TOBN(0x2f21da47, 0x8096fa2b),
-+     TOBN(0xf3e19cb4, 0xeec863a0), TOBN(0xd18f77fd, 0x9527620a),
-+     TOBN(0x9505c81c, 0x407c1cf8), TOBN(0x9998db4e, 0x1b6ec284),
-+     TOBN(0x7e3389e5, 0xc247d44d), TOBN(0x12507141, 0x3f4f3d80),
-+     TOBN(0xd4ba0110, 0x4a78a6c7), TOBN(0x312874a0, 0x767720be),
-+     TOBN(0xded059a6, 0x75944370), TOBN(0xd6123d90, 0x3b2c0bdd),
-+     TOBN(0xa56b717b, 0x51c108e3), TOBN(0x9bb7940e, 0x070623e9),
-+     TOBN(0x794e2d59, 0x84ac066c), TOBN(0xf5954a92, 0xe68c69a0),
-+     TOBN(0x28c52458, 0x4fd99dcc), TOBN(0x60e639fc, 0xb1012517),
-+     TOBN(0xc2e60125, 0x7de79248), TOBN(0xe9ef6404, 0xf12fc6d7),
-+     TOBN(0x4c4f2808, 0x2a3b5d32), TOBN(0x865ad32e, 0xc768eb8a),
-+     TOBN(0xac02331b, 0x13fb70b6), TOBN(0x037b44c1, 0x95599b27),
-+     TOBN(0x1a860fc4, 0x60bd082c), TOBN(0xa2e25745, 0xc980cd01),
-+     TOBN(0xee3387a8, 0x1da0263e), TOBN(0x931bfb95, 0x2d10f3d6),
-+     TOBN(0x5b687270, 0xa1f24a32), TOBN(0xf140e65d, 0xca494b86),
-+     TOBN(0x4f4ddf91, 0xb2f1ac7a), TOBN(0xf99eaabb, 0x760fee27),
-+     TOBN(0x57f4008a, 0x49c228e5), TOBN(0x090be440, 0x1cf713bb),
-+     TOBN(0xac91fbe4, 0x5004f022), TOBN(0xd838c2c2, 0x569e1af6),
-+     TOBN(0xd6c7d20b, 0x0f1daaa5), TOBN(0xaa063ac1, 0x1bbb02c0),
-+     TOBN(0x0938a422, 0x59558a78), TOBN(0x5343c669, 0x8435da2f),
-+     TOBN(0x96f67b18, 0x034410dc), TOBN(0x7cc1e424, 0x84510804),
-+     TOBN(0x86a1543f, 0x16dfbb7d), TOBN(0x921fa942, 0x5b5bd592),
-+     TOBN(0x9dcccb6e, 0xb33dd03c), TOBN(0x8581ddd9, 0xb843f51e),
-+     TOBN(0x54935fcb, 0x81d73c9e), TOBN(0x6d07e979, 0x0a5e97ab),
-+     TOBN(0x4dc7b30a, 0xcf3a6bab), TOBN(0x147ab1f3, 0x170bee11),
-+     TOBN(0x0aaf8e3d, 0x9fafdee4), TOBN(0xfab3dbcb, 0x538a8b95),
-+     TOBN(0x405df4b3, 0x6ef13871), TOBN(0xf1f4e9cb, 0x088d5a49),
-+     TOBN(0x9bcd24d3, 0x66b33f1d), TOBN(0x3b97b820, 0x5ce445c0),
-+     TOBN(0xe2926549, 0xba93ff61), TOBN(0xd9c341ce, 0x4dafe616),
-+     TOBN(0xfb30a76e, 0x16efb6f3), TOBN(0xdf24b8ca, 0x605b953c),
-+     TOBN(0x8bd52afe, 0xc2fffb9f), TOBN(0xbbac5ff7, 0xe19d0b96),
-+     TOBN(0x43c01b87, 0x459afccd), TOBN(0x6bd45143, 0xb7432652),
-+     TOBN(0x84734530, 0x55b5d78e), TOBN(0x81088fdb, 0x1554ba7d),
-+     TOBN(0xada0a52c, 0x1e269375), TOBN(0xf9f037c4, 0x2dc5ec10),
-+     TOBN(0xc0660607, 0x94bfbc11), TOBN(0xc0a630bb, 0xc9c40d2f),
-+     TOBN(0x5efc797e, 0xab64c31e), TOBN(0xffdb1dab, 0x74507144),
-+     TOBN(0xf6124287, 0x1ca6790c), TOBN(0xe9609d81, 0xe69bf1bf),
-+     TOBN(0xdb898595, 0x00d24fc9), TOBN(0x9c750333, 0xe51fb417),
-+     TOBN(0x51830a91, 0xfef7bbde), TOBN(0x0ce67dc8, 0x945f585c),
-+     TOBN(0x9a730ed4, 0x4763eb50), TOBN(0x24a0e221, 0xc1ab0d66),
-+     TOBN(0x643b6393, 0x648748f3), TOBN(0x1982daa1, 0x6d3c6291),
-+     TOBN(0x6f00a9f7, 0x8bbc5549), TOBN(0x7a1783e1, 0x7f36384e),
-+     TOBN(0xe8346323, 0xde977f50), TOBN(0x91ab688d, 0xb245502a),
-+     TOBN(0x331ab6b5, 0x6d0bdd66), TOBN(0x0a6ef32e, 0x64b71229),
-+     TOBN(0x1028150e, 0xfe7c352f), TOBN(0x27e04350, 0xce7b39d3),
-+     TOBN(0x2a3c8acd, 0xc1070c82), TOBN(0xfb2034d3, 0x80c9feef),
-+     TOBN(0x2d729621, 0x709f3729), TOBN(0x8df290bf, 0x62cb4549),
-+     TOBN(0x02f99f33, 0xfc2e4326), TOBN(0x3b30076d, 0x5eddf032),
-+     TOBN(0xbb21f8cf, 0x0c652fb5), TOBN(0x314fb49e, 0xed91cf7b),
-+     TOBN(0xa013eca5, 0x2f700750), TOBN(0x2b9e3c23, 0x712a4575),
-+     TOBN(0xe5355557, 0xaf30fbb0), TOBN(0x1ada3516, 0x7c77e771),
-+     TOBN(0x45f6ecb2, 0x7b135670), TOBN(0xe85d19df, 0x7cfc202e),
-+     TOBN(0x0f1b50c7, 0x58d1be9f), TOBN(0x5ebf2c0a, 0xead2e344),
-+     TOBN(0x1531fe4e, 0xabc199c9), TOBN(0xc7032592, 0x56bab0ae),
-+     TOBN(0x16ab2e48, 0x6c1fec54), TOBN(0x0f87fda8, 0x04280188),
-+     TOBN(0xdc9f46fc, 0x609e4a74), TOBN(0x2a44a143, 0xba667f91),
-+     TOBN(0xbc3d8b95, 0xb4d83436), TOBN(0xa01e4bd0, 0xc7bd2958),
-+     TOBN(0x7b182932, 0x73483c90), TOBN(0xa79c6aa1, 0xa7c7b598),
-+     TOBN(0xbf3983c6, 0xeaaac07e), TOBN(0x8f18181e, 0x96e0d4e6),
-+     TOBN(0x8553d37c, 0x051af62b), TOBN(0xe9a998eb, 0x0bf94496),
-+     TOBN(0xe0844f9f, 0xb0d59aa1), TOBN(0x983fd558, 0xe6afb813),
-+     TOBN(0x9670c0ca, 0x65d69804), TOBN(0x732b22de, 0x6ea5ff2d),
-+     TOBN(0xd7640ba9, 0x5fd8623b), TOBN(0x9f619163, 0xa6351782),
-+     TOBN(0x0bfc27ee, 0xacee5043), TOBN(0xae419e73, 0x2eb10f02),
-+     TOBN(0x19c028d1, 0x8943fb05), TOBN(0x71f01cf7, 0xff13aa2a),
-+     TOBN(0x7790737e, 0x8887a132), TOBN(0x67513309, 0x66318410),
-+     TOBN(0x9819e8a3, 0x7ddb795e), TOBN(0xfecb8ef5, 0xdad100b2),
-+     TOBN(0x59f74a22, 0x3021926a), TOBN(0xb7c28a49, 0x6f9b4c1c),
-+     TOBN(0xed1a733f, 0x912ad0ab), TOBN(0x42a910af, 0x01a5659c),
-+     TOBN(0x3842c6e0, 0x7bd68cab), TOBN(0x2b57fa38, 0x76d70ac8),
-+     TOBN(0x8a6707a8, 0x3c53aaeb), TOBN(0x62c1c510, 0x65b4db18),
-+     TOBN(0x8de2c1fb, 0xb2d09dc7), TOBN(0xc3dfed12, 0x266bd23b),
-+     TOBN(0x927d039b, 0xd5b27db6), TOBN(0x2fb2f0f1, 0x103243da),
-+     TOBN(0xf855a07b, 0x80be7399), TOBN(0xed9327ce, 0x1f9f27a8),
-+     TOBN(0xa0bd99c7, 0x729bdef7), TOBN(0x2b67125e, 0x28250d88),
-+     TOBN(0x784b26e8, 0x8670ced7), TOBN(0xe3dfe41f, 0xc31bd3b4),
-+     TOBN(0x9e353a06, 0xbcc85cbc), TOBN(0x302e2909, 0x60178a9d),
-+     TOBN(0x860abf11, 0xa6eac16e), TOBN(0x76447000, 0xaa2b3aac),
-+     TOBN(0x46ff9d19, 0x850afdab), TOBN(0x35bdd6a5, 0xfdb2d4c1),
-+     TOBN(0xe82594b0, 0x7e5c9ce9), TOBN(0x0f379e53, 0x20af346e),
-+     TOBN(0x608b31e3, 0xbc65ad4a), TOBN(0x710c6b12, 0x267c4826),
-+     TOBN(0x51c966f9, 0x71954cf1), TOBN(0xb1cec793, 0x0d0aa215),
-+     TOBN(0x1f155989, 0x86bd23a8), TOBN(0xae2ff99c, 0xf9452e86),
-+     TOBN(0xd8dd953c, 0x340ceaa2), TOBN(0x26355275, 0x2e2e9333),
-+     TOBN(0x15d4e5f9, 0x8586f06d), TOBN(0xd6bf94a8, 0xf7cab546),
-+     TOBN(0x33c59a0a, 0xb76a9af0), TOBN(0x52740ab3, 0xba095af7),
-+     TOBN(0xc444de8a, 0x24389ca0), TOBN(0xcc6f9863, 0x706da0cb),
-+     TOBN(0xb5a741a7, 0x6b2515cf), TOBN(0x71c41601, 0x9585c749),
-+     TOBN(0x78350d4f, 0xe683de97), TOBN(0x31d61524, 0x63d0b5f5),
-+     TOBN(0x7a0cc5e1, 0xfbce090b), TOBN(0xaac927ed, 0xfbcb2a5b),
-+     TOBN(0xe920de49, 0x20d84c35), TOBN(0x8c06a0b6, 0x22b4de26),
-+     TOBN(0xd34dd58b, 0xafe7ddf3), TOBN(0x55851fed, 0xc1e6e55b),
-+     TOBN(0xd1395616, 0x960696e7), TOBN(0x940304b2, 0x5f22705f),
-+     TOBN(0x6f43f861, 0xb0a2a860), TOBN(0xcf121282, 0x0e7cc981),
-+     TOBN(0x12186212, 0x0ab64a96), TOBN(0x09215b9a, 0xb789383c),
-+     TOBN(0x311eb305, 0x37387c09), TOBN(0xc5832fce, 0xf03ee760),
-+     TOBN(0x30358f58, 0x32f7ea19), TOBN(0xe01d3c34, 0x91d53551),
-+     TOBN(0x1ca5ee41, 0xda48ea80), TOBN(0x34e71e8e, 0xcf4fa4c1),
-+     TOBN(0x312abd25, 0x7af1e1c7), TOBN(0xe3afcdeb, 0x2153f4a5),
-+     TOBN(0x9d5c84d7, 0x00235e9a), TOBN(0x0308d3f4, 0x8c4c836f),
-+     TOBN(0xc0a66b04, 0x89332de5), TOBN(0x610dd399, 0x89e566ef),
-+     TOBN(0xf8eea460, 0xd1ac1635), TOBN(0x84cbb3fb, 0x20a2c0df),
-+     TOBN(0x40afb488, 0xe74a48c5), TOBN(0x29738198, 0xd326b150),
-+     TOBN(0x2a17747f, 0xa6d74081), TOBN(0x60ea4c05, 0x55a26214),
-+     TOBN(0x53514bb4, 0x1f88c5fe), TOBN(0xedd64567, 0x7e83426c),
-+     TOBN(0xd5d6cbec, 0x96460b25), TOBN(0xa12fd0ce, 0x68dc115e),
-+     TOBN(0xc5bc3ed2, 0x697840ea), TOBN(0x969876a8, 0xa6331e31),
-+     TOBN(0x60c36217, 0x472ff580), TOBN(0xf4229705, 0x4ad41393),
-+     TOBN(0x4bd99ef0, 0xa03b8b92), TOBN(0x501c7317, 0xc144f4f6),
-+     TOBN(0x159009b3, 0x18464945), TOBN(0x6d5e594c, 0x74c5c6be),
-+     TOBN(0x2d587011, 0x321a3660), TOBN(0xd1e184b1, 0x3898d022),
-+     TOBN(0x5ba04752, 0x4c6a7e04), TOBN(0x47fa1e2b, 0x45550b65),
-+     TOBN(0x9419daf0, 0x48c0a9a5), TOBN(0x66362953, 0x7c243236),
-+     TOBN(0xcd0744b1, 0x5cb12a88), TOBN(0x561b6f9a, 0x2b646188),
-+     TOBN(0x599415a5, 0x66c2c0c0), TOBN(0xbe3f0859, 0x0f83f09a),
-+     TOBN(0x9141c5be, 0xb92041b8), TOBN(0x01ae38c7, 0x26477d0d),
-+     TOBN(0xca8b71f3, 0xd12c7a94), TOBN(0xfab5b31f, 0x765c70db),
-+     TOBN(0x76ae7492, 0x487443e9), TOBN(0x8595a310, 0x990d1349),
-+     TOBN(0xf8dbeda8, 0x7d460a37), TOBN(0x7f7ad082, 0x1e45a38f),
-+     TOBN(0xed1d4db6, 0x1059705a), TOBN(0xa3dd492a, 0xe6b9c697),
-+     TOBN(0x4b92ee3a, 0x6eb38bd5), TOBN(0xbab2609d, 0x67cc0bb7),
-+     TOBN(0x7fc4fe89, 0x6e70ee82), TOBN(0xeff2c56e, 0x13e6b7e3),
-+     TOBN(0x9b18959e, 0x34d26fca), TOBN(0x2517ab66, 0x889d6b45),
-+     TOBN(0xf167b4e0, 0xbdefdd4f), TOBN(0x69958465, 0xf366e401),
-+     TOBN(0x5aa368ab, 0xa73bbec0), TOBN(0x12148709, 0x7b240c21),
-+     TOBN(0x378c3233, 0x18969006), TOBN(0xcb4d73ce, 0xe1fe53d1),
-+     TOBN(0x5f50a80e, 0x130c4361), TOBN(0xd67f5951, 0x7ef5212b),
-+     TOBN(0xf145e21e, 0x9e70c72e), TOBN(0xb2e52e29, 0x5566d2fb),
-+     TOBN(0x44eaba4a, 0x032397f5), TOBN(0x5e56937b, 0x7e31a7de),
-+     TOBN(0x68dcf517, 0x456c61e1), TOBN(0xbc2e954a, 0xa8b0a388),
-+     TOBN(0xe3552fa7, 0x60a8b755), TOBN(0x03442dae, 0x73ad0cde),
-+     TOBN(0x37ffe747, 0xceb26210), TOBN(0x983545e8, 0x787baef9),
-+     TOBN(0x8b8c8535, 0x86a3de31), TOBN(0xc621dbcb, 0xfacd46db),
-+     TOBN(0x82e442e9, 0x59266fbb), TOBN(0xa3514c37, 0x339d471c),
-+     TOBN(0x3a11b771, 0x62cdad96), TOBN(0xf0cb3b3c, 0xecf9bdf0),
-+     TOBN(0x3fcbdbce, 0x478e2135), TOBN(0x7547b5cf, 0xbda35342),
-+     TOBN(0xa97e81f1, 0x8a677af6), TOBN(0xc8c2bf83, 0x28817987),
-+     TOBN(0xdf07eaaf, 0x45580985), TOBN(0xc68d1f05, 0xc93b45cb),
-+     TOBN(0x106aa2fe, 0xc77b4cac), TOBN(0x4c1d8afc, 0x04a7ae86),
-+     TOBN(0xdb41c3fd, 0x9eb45ab2), TOBN(0x5b234b5b, 0xd4b22e74),
-+     TOBN(0xda253dec, 0xf215958a), TOBN(0x67e0606e, 0xa04edfa0),
-+     TOBN(0xabbbf070, 0xef751b11), TOBN(0xf352f175, 0xf6f06dce),
-+     TOBN(0xdfc4b6af, 0x6839f6b4), TOBN(0x53ddf9a8, 0x9959848e),
-+     TOBN(0xda49c379, 0xc21520b0), TOBN(0x90864ff0, 0xdbd5d1b6),
-+     TOBN(0x2f055d23, 0x5f49c7f7), TOBN(0xe51e4e6a, 0xa796b2d8),
-+     TOBN(0xc361a67f, 0x5c9dc340), TOBN(0x5ad53c37, 0xbca7c620),
-+     TOBN(0xda1d6588, 0x32c756d0), TOBN(0xad60d911, 0x8bb67e13),
-+     TOBN(0xd6c47bdf, 0x0eeec8c6), TOBN(0x4a27fec1, 0x078a1821),
-+     TOBN(0x081f7415, 0xc3099524), TOBN(0x8effdf0b, 0x82cd8060),
-+     TOBN(0xdb70ec1c, 0x65842df8), TOBN(0x8821b358, 0xd319a901),
-+     TOBN(0x72ee56ee, 0xde42b529), TOBN(0x5bb39592, 0x236e4286),
-+     TOBN(0xd1183316, 0xfd6f7140), TOBN(0xf9fadb5b, 0xbd8e81f7),
-+     TOBN(0x701d5e0c, 0x5a02d962), TOBN(0xfdee4dbf, 0x1b601324),
-+     TOBN(0xbed17407, 0x35d7620e), TOBN(0x04e3c2c3, 0xf48c0012),
-+     TOBN(0x9ee29da7, 0x3455449a), TOBN(0x562cdef4, 0x91a836c4),
-+     TOBN(0x8f682a5f, 0x47701097), TOBN(0x617125d8, 0xff88d0c2),
-+     TOBN(0x948fda24, 0x57bb86dd), TOBN(0x348abb8f, 0x289f7286),
-+     TOBN(0xeb10eab5, 0x99d94bbd), TOBN(0xd51ba28e, 0x4684d160),
-+     TOBN(0xabe0e51c, 0x30c8f41a), TOBN(0x66588b45, 0x13254f4a),
-+     TOBN(0x147ebf01, 0xfad097a5), TOBN(0x49883ea8, 0x610e815d),
-+     TOBN(0xe44d60ba, 0x8a11de56), TOBN(0xa970de6e, 0x827a7a6d),
-+     TOBN(0x2be41424, 0x5e17fc19), TOBN(0xd833c657, 0x01214057),
-+     TOBN(0x1375813b, 0x363e723f), TOBN(0x6820bb88, 0xe6a52e9b),
-+     TOBN(0x7e7f6970, 0xd875d56a), TOBN(0xd6a0a9ac, 0x51fbf6bf),
-+     TOBN(0x54ba8790, 0xa3083c12), TOBN(0xebaeb23d, 0x6ae7eb64),
-+     TOBN(0xa8685c3a, 0xb99a907a), TOBN(0xf1e74550, 0x026bf40b),
-+     TOBN(0x7b73a027, 0xc802cd9e), TOBN(0x9a8a927c, 0x4fef4635),
-+     TOBN(0xe1b6f60c, 0x08191224), TOBN(0xc4126ebb, 0xde4ec091),
-+     TOBN(0xe1dff4dc, 0x4ae38d84), TOBN(0xde3f57db, 0x4f2ef985),
-+     TOBN(0x34964337, 0xd446a1dd), TOBN(0x7bf217a0, 0x859e77f6),
-+     TOBN(0x8ff10527, 0x8e1d13f5), TOBN(0xa304ef03, 0x74eeae27),
-+     TOBN(0xfc6f5e47, 0xd19dfa5a), TOBN(0xdb007de3, 0x7fad982b),
-+     TOBN(0x28205ad1, 0x613715f5), TOBN(0x251e6729, 0x7889529e),
-+     TOBN(0x72705184, 0x1ae98e78), TOBN(0xf818537d, 0x271cac32),
-+     TOBN(0xc8a15b7e, 0xb7f410f5), TOBN(0xc474356f, 0x81f62393),
-+     TOBN(0x92dbdc5a, 0xc242316b), TOBN(0xabe060ac, 0xdbf4aff5),
-+     TOBN(0x6e8c38fe, 0x909a8ec6), TOBN(0x43e514e5, 0x6116cb94),
-+     TOBN(0x2078fa38, 0x07d784f9), TOBN(0x1161a880, 0xf4b5b357),
-+     TOBN(0x5283ce79, 0x13adea3d), TOBN(0x0756c3e6, 0xcc6a910b),
-+     TOBN(0x60bcfe01, 0xaaa79697), TOBN(0x04a73b29, 0x56391db1),
-+     TOBN(0xdd8dad47, 0x189b45a0), TOBN(0xbfac0dd0, 0x48d5b8d9),
-+     TOBN(0x34ab3af5, 0x7d3d2ec2), TOBN(0x6fa2fc2d, 0x207bd3af),
-+     TOBN(0x9ff40092, 0x66550ded), TOBN(0x719b3e87, 0x1fd5b913),
-+     TOBN(0xa573a496, 0x6d17fbc7), TOBN(0x0cd1a70a, 0x73d2b24e),
-+     TOBN(0x34e2c5ca, 0xb2676937), TOBN(0xe7050b06, 0xbf669f21),
-+     TOBN(0xfbe948b6, 0x1ede9046), TOBN(0xa0530051, 0x97662659),
-+     TOBN(0x58cbd4ed, 0xf10124c5), TOBN(0xde2646e4, 0xdd6c06c8),
-+     TOBN(0x332f8108, 0x8cad38c0), TOBN(0x471b7e90, 0x6bd68ae2),
-+     TOBN(0x56ac3fb2, 0x0d8e27a3), TOBN(0xb54660db, 0x136b4b0d),
-+     TOBN(0x123a1e11, 0xa6fd8de4), TOBN(0x44dbffea, 0xa37799ef),
-+     TOBN(0x4540b977, 0xce6ac17c), TOBN(0x495173a8, 0xaf60acef)}
-+    ,
-+    {TOBN(0x9ebb284d, 0x391c2a82), TOBN(0xbcdd4863, 0x158308e8),
-+     TOBN(0x006f16ec, 0x83f1edca), TOBN(0xa13e2c37, 0x695dc6c8),
-+     TOBN(0x2ab756f0, 0x4a057a87), TOBN(0xa8765500, 0xa6b48f98),
-+     TOBN(0x4252face, 0x68651c44), TOBN(0xa52b540b, 0xe1765e02),
-+     TOBN(0x4f922fc5, 0x16a0d2bb), TOBN(0x0d5cc16c, 0x1a623499),
-+     TOBN(0x9241cf3a, 0x57c62c8b), TOBN(0x2f5e6961, 0xfd1b667f),
-+     TOBN(0x5c15c70b, 0xf5a01797), TOBN(0x3d20b44d, 0x60956192),
-+     TOBN(0x04911b37, 0x071fdb52), TOBN(0xf648f916, 0x8d6f0f7b),
-+     TOBN(0x6dc1acaf, 0xe60b7cf7), TOBN(0x25860a50, 0x84a9d869),
-+     TOBN(0x56fc6f09, 0xe7ba8ac4), TOBN(0x828c5bd0, 0x6148d29e),
-+     TOBN(0xac6b435e, 0xdc55ae5f), TOBN(0xa527f56c, 0xc0117411),
-+     TOBN(0x94d5045e, 0xfd24342c), TOBN(0x2c4c0a35, 0x70b67c0d),
-+     TOBN(0x027cc8b8, 0xfac61d9a), TOBN(0x7d25e062, 0xe3c6fe8a),
-+     TOBN(0xe08805bf, 0xe5bff503), TOBN(0x13271e6c, 0x6ff632f7),
-+     TOBN(0x55dca6c0, 0x232f76a5), TOBN(0x8957c32d, 0x701ef426),
-+     TOBN(0xee728bcb, 0xa10a5178), TOBN(0x5ea60411, 0xb62c5173),
-+     TOBN(0xfc4e964e, 0xd0b8892b), TOBN(0x9ea17683, 0x9301bb74),
-+     TOBN(0x6265c5ae, 0xfcc48626), TOBN(0xe60cf82e, 0xbb3e9102),
-+     TOBN(0x57adf797, 0xd4df5531), TOBN(0x235b59a1, 0x8deeefe2),
-+     TOBN(0x60adcf58, 0x3f306eb1), TOBN(0x105c2753, 0x3d09492d),
-+     TOBN(0x4090914b, 0xb5def996), TOBN(0x1cb69c83, 0x233dd1e7),
-+     TOBN(0xc1e9c1d3, 0x9b3d5e76), TOBN(0x1f3338ed, 0xfccf6012),
-+     TOBN(0xb1e95d0d, 0x2f5378a8), TOBN(0xacf4c2c7, 0x2f00cd21),
-+     TOBN(0x6e984240, 0xeb5fe290), TOBN(0xd66c038d, 0x248088ae),
-+     TOBN(0x804d264a, 0xf94d70cf), TOBN(0xbdb802ef, 0x7314bf7e),
-+     TOBN(0x8fb54de2, 0x4333ed02), TOBN(0x740461e0, 0x285635d9),
-+     TOBN(0x4113b2c8, 0x365e9383), TOBN(0xea762c83, 0x3fdef652),
-+     TOBN(0x4eec6e2e, 0x47b956c1), TOBN(0xa3d814be, 0x65620fa4),
-+     TOBN(0x9ad5462b, 0xb4d8bc50), TOBN(0x181c0b16, 0xa9195770),
-+     TOBN(0xebd4fe1c, 0x78412a68), TOBN(0xae0341bc, 0xc0dff48c),
-+     TOBN(0xb6bc45cf, 0x7003e866), TOBN(0xf11a6dea, 0x8a24a41b),
-+     TOBN(0x5407151a, 0xd04c24c2), TOBN(0x62c9d27d, 0xda5b7b68),
-+     TOBN(0x2e964235, 0x88cceff6), TOBN(0x8594c54f, 0x8b07ed69),
-+     TOBN(0x1578e73c, 0xc84d0d0d), TOBN(0x7b4e1055, 0xff532868),
-+     TOBN(0xa348c0d5, 0xb5ec995a), TOBN(0xbf4b9d55, 0x14289a54),
-+     TOBN(0x9ba155a6, 0x58fbd777), TOBN(0x186ed7a8, 0x1a84491d),
-+     TOBN(0xd4992b30, 0x614c0900), TOBN(0xda98d121, 0xbd00c24b),
-+     TOBN(0x7f534dc8, 0x7ec4bfa1), TOBN(0x4a5ff674, 0x37dc34bc),
-+     TOBN(0x68c196b8, 0x1d7ea1d7), TOBN(0x38cf2893, 0x80a6d208),
-+     TOBN(0xfd56cd09, 0xe3cbbd6e), TOBN(0xec72e27e, 0x4205a5b6),
-+     TOBN(0x15ea68f5, 0xa44f77f7), TOBN(0x7aa5f9fd, 0xb43c52bc),
-+     TOBN(0x86ff676f, 0x94f0e609), TOBN(0xa4cde963, 0x2e2d432b),
-+     TOBN(0x8cafa0c0, 0xeee470af), TOBN(0x84137d0e, 0x8a3f5ec8),
-+     TOBN(0xebb40411, 0xfaa31231), TOBN(0xa239c13f, 0x6f7f7ccf),
-+     TOBN(0x32865719, 0xa8afd30b), TOBN(0x86798328, 0x8a826dce),
-+     TOBN(0xdf04e891, 0xc4a8fbe0), TOBN(0xbb6b6e1b, 0xebf56ad3),
-+     TOBN(0x0a695b11, 0x471f1ff0), TOBN(0xd76c3389, 0xbe15baf0),
-+     TOBN(0x018edb95, 0xbe96c43e), TOBN(0xf2beaaf4, 0x90794158),
-+     TOBN(0x152db09e, 0xc3076a27), TOBN(0x5e82908e, 0xe416545d),
-+     TOBN(0xa2c41272, 0x356d6f2e), TOBN(0xdc9c9642, 0x31fd74e1),
-+     TOBN(0x66ceb88d, 0x519bf615), TOBN(0xe29ecd76, 0x05a2274e),
-+     TOBN(0x3a0473c4, 0xbf5e2fa0), TOBN(0x6b6eb671, 0x64284e67),
-+     TOBN(0xe8b97932, 0xb88756dd), TOBN(0xed4e8652, 0xf17e3e61),
-+     TOBN(0xc2dd1499, 0x3ee1c4a4), TOBN(0xc0aaee17, 0x597f8c0e),
-+     TOBN(0x15c4edb9, 0x6c168af3), TOBN(0x6563c7bf, 0xb39ae875),
-+     TOBN(0xadfadb6f, 0x20adb436), TOBN(0xad55e8c9, 0x9a042ac0),
-+     TOBN(0x975a1ed8, 0xb76da1f5), TOBN(0x10dfa466, 0xa58acb94),
-+     TOBN(0x8dd7f7e3, 0xac060282), TOBN(0x6813e66a, 0x572a051e),
-+     TOBN(0xb4ccae1e, 0x350cb901), TOBN(0xb653d656, 0x50cb7822),
-+     TOBN(0x42484710, 0xdfab3b87), TOBN(0xcd7ee537, 0x9b670fd0),
-+     TOBN(0x0a50b12e, 0x523b8bf6), TOBN(0x8009eb5b, 0x8f910c1b),
-+     TOBN(0xf535af82, 0x4a167588), TOBN(0x0f835f9c, 0xfb2a2abd),
-+     TOBN(0xf59b2931, 0x2afceb62), TOBN(0xc797df2a, 0x169d383f),
-+     TOBN(0xeb3f5fb0, 0x66ac02b0), TOBN(0x029d4c6f, 0xdaa2d0ca),
-+     TOBN(0xd4059bc1, 0xafab4bc5), TOBN(0x833f5c6f, 0x56783247),
-+     TOBN(0xb5346630, 0x8d2d3605), TOBN(0x83387891, 0xd34d8433),
-+     TOBN(0xd973b30f, 0xadd9419a), TOBN(0xbcca1099, 0xafe3fce8),
-+     TOBN(0x08178315, 0x0809aac6), TOBN(0x01b7f21a, 0x540f0f11),
-+     TOBN(0x65c29219, 0x909523c8), TOBN(0xa62f648f, 0xa3a1c741),
-+     TOBN(0x88598d4f, 0x60c9e55a), TOBN(0xbce9141b, 0x0e4f347a),
-+     TOBN(0x9af97d84, 0x35f9b988), TOBN(0x0210da62, 0x320475b6),
-+     TOBN(0x3c076e22, 0x9191476c), TOBN(0x7520dbd9, 0x44fc7834),
-+     TOBN(0x6a6b2cfe, 0xc1ab1bbd), TOBN(0xef8a65be, 0xdc650938),
-+     TOBN(0x72855540, 0x805d7bc4), TOBN(0xda389396, 0xed11fdfd),
-+     TOBN(0xa9d5bd36, 0x74660876), TOBN(0x11d67c54, 0xb45dff35),
-+     TOBN(0x6af7d148, 0xa4f5da94), TOBN(0xbb8d4c3f, 0xc0bbeb31),
-+     TOBN(0x87a7ebd1, 0xe0a1b12a), TOBN(0x1e4ef88d, 0x770ba95f),
-+     TOBN(0x8c33345c, 0xdc2ae9cb), TOBN(0xcecf1276, 0x01cc8403),
-+     TOBN(0x687c012e, 0x1b39b80f), TOBN(0xfd90d0ad, 0x35c33ba4),
-+     TOBN(0xa3ef5a67, 0x5c9661c2), TOBN(0x368fc88e, 0xe017429e),
-+     TOBN(0xd30c6761, 0x196a2fa2), TOBN(0x931b9817, 0xbd5b312e),
-+     TOBN(0xba01000c, 0x72f54a31), TOBN(0xa203d2c8, 0x66eaa541),
-+     TOBN(0xf2abdee0, 0x98939db3), TOBN(0xe37d6c2c, 0x3e606c02),
-+     TOBN(0xf2921574, 0x521ff643), TOBN(0x2781b3c4, 0xd7e2fca3),
-+     TOBN(0x664300b0, 0x7850ec06), TOBN(0xac5a38b9, 0x7d3a10cf),
-+     TOBN(0x9233188d, 0xe34ab39d), TOBN(0xe77057e4, 0x5072cbb9),
-+     TOBN(0xbcf0c042, 0xb59e78df), TOBN(0x4cfc91e8, 0x1d97de52),
-+     TOBN(0x4661a26c, 0x3ee0ca4a), TOBN(0x5620a4c1, 0xfb8507bc),
-+     TOBN(0x4b44d4aa, 0x049f842c), TOBN(0xceabc5d5, 0x1540e82b),
-+     TOBN(0x306710fd, 0x15c6f156), TOBN(0xbe5ae52b, 0x63db1d72),
-+     TOBN(0x06f1e7e6, 0x334957f1), TOBN(0x57e388f0, 0x31144a70),
-+     TOBN(0xfb69bb2f, 0xdf96447b), TOBN(0x0f78ebd3, 0x73e38a12),
-+     TOBN(0xb8222605, 0x2b7ce542), TOBN(0xe6d4ce99, 0x7472bde1),
-+     TOBN(0x53e16ebe, 0x09d2f4da), TOBN(0x180ff42e, 0x53b92b2e),
-+     TOBN(0xc59bcc02, 0x2c34a1c6), TOBN(0x3803d6f9, 0x422c46c2),
-+     TOBN(0x18aff74f, 0x5c14a8a2), TOBN(0x55aebf80, 0x10a08b28),
-+     TOBN(0x66097d58, 0x7135593f), TOBN(0x32e6eff7, 0x2be570cd),
-+     TOBN(0x584e6a10, 0x2a8c860d), TOBN(0xcd185890, 0xa2eb4163),
-+     TOBN(0x7ceae99d, 0x6d97e134), TOBN(0xd42c6b70, 0xdd8447ce),
-+     TOBN(0x59ddbb4a, 0xb8c50273), TOBN(0x03c612df, 0x3cf34e1e),
-+     TOBN(0x84b9ca15, 0x04b6c5a0), TOBN(0x35216f39, 0x18f0e3a3),
-+     TOBN(0x3ec2d2bc, 0xbd986c00), TOBN(0x8bf546d9, 0xd19228fe),
-+     TOBN(0xd1c655a4, 0x4cd623c3), TOBN(0x366ce718, 0x502b8e5a),
-+     TOBN(0x2cfc84b4, 0xeea0bfe7), TOBN(0xe01d5cee, 0xcf443e8e),
-+     TOBN(0x8ec045d9, 0x036520f8), TOBN(0xdfb3c3d1, 0x92d40e98),
-+     TOBN(0x0bac4cce, 0xcc559a04), TOBN(0x35eccae5, 0x240ea6b1),
-+     TOBN(0x180b32db, 0xf8a5a0ac), TOBN(0x547972a5, 0xeb699700),
-+     TOBN(0xa3765801, 0xca26bca0), TOBN(0x57e09d0e, 0xa647f25a),
-+     TOBN(0xb956970e, 0x2fdd23cc), TOBN(0xb80288bc, 0x5682e971),
-+     TOBN(0xe6e6d91e, 0x9ae86ebc), TOBN(0x0564c83f, 0x8c9f1939),
-+     TOBN(0x551932a2, 0x39560368), TOBN(0xe893752b, 0x049c28e2),
-+     TOBN(0x0b03cee5, 0xa6a158c3), TOBN(0xe12d656b, 0x04964263),
-+     TOBN(0x4b47554e, 0x63e3bc1d), TOBN(0xc719b6a2, 0x45044ff7),
-+     TOBN(0x4f24d30a, 0xe48daa07), TOBN(0xa3f37556, 0xc8c1edc3),
-+     TOBN(0x9a47bf76, 0x0700d360), TOBN(0xbb1a1824, 0x822ae4e2),
-+     TOBN(0x22e275a3, 0x89f1fb4c), TOBN(0x72b1aa23, 0x9968c5f5),
-+     TOBN(0xa75feaca, 0xbe063f64), TOBN(0x9b392f43, 0xbce47a09),
-+     TOBN(0xd4241509, 0x1ad07aca), TOBN(0x4b0c591b, 0x8d26cd0f),
-+     TOBN(0x2d42ddfd, 0x92f1169a), TOBN(0x63aeb1ac, 0x4cbf2392),
-+     TOBN(0x1de9e877, 0x0691a2af), TOBN(0xebe79af7, 0xd98021da),
-+     TOBN(0xcfdf2a4e, 0x40e50acf), TOBN(0xf0a98ad7, 0xaf01d665),
-+     TOBN(0xefb640bf, 0x1831be1f), TOBN(0x6fe8bd2f, 0x80e9ada0),
-+     TOBN(0x94c103a1, 0x6cafbc91), TOBN(0x170f8759, 0x8308e08c),
-+     TOBN(0x5de2d2ab, 0x9780ff4f), TOBN(0x666466bc, 0x45b201f2),
-+     TOBN(0x58af2010, 0xf5b343bc), TOBN(0x0f2e400a, 0xf2f142fe),
-+     TOBN(0x3483bfde, 0xa85f4bdf), TOBN(0xf0b1d093, 0x03bfeaa9),
-+     TOBN(0x2ea01b95, 0xc7081603), TOBN(0xe943e4c9, 0x3dba1097),
-+     TOBN(0x47be92ad, 0xb438f3a6), TOBN(0x00bb7742, 0xe5bf6636),
-+     TOBN(0x136b7083, 0x824297b4), TOBN(0x9d0e5580, 0x5584455f),
-+     TOBN(0xab48cedc, 0xf1c7d69e), TOBN(0x53a9e481, 0x2a256e76),
-+     TOBN(0x0402b0e0, 0x65eb2413), TOBN(0xdadbbb84, 0x8fc407a7),
-+     TOBN(0xa65cd5a4, 0x8d7f5492), TOBN(0x21d44293, 0x74bae294),
-+     TOBN(0x66917ce6, 0x3b5f1cc4), TOBN(0x37ae52ea, 0xce872e62),
-+     TOBN(0xbb087b72, 0x2905f244), TOBN(0x12077086, 0x1e6af74f),
-+     TOBN(0x4b644e49, 0x1058edea), TOBN(0x827510e3, 0xb638ca1d),
-+     TOBN(0x8cf2b704, 0x6038591c), TOBN(0xffc8b47a, 0xfe635063),
-+     TOBN(0x3ae220e6, 0x1b4d5e63), TOBN(0xbd864742, 0x9d961b4b),
-+     TOBN(0x610c107e, 0x9bd16bed), TOBN(0x4270352a, 0x1127147b),
-+     TOBN(0x7d17ffe6, 0x64cfc50e), TOBN(0x50dee01a, 0x1e36cb42),
-+     TOBN(0x068a7622, 0x35dc5f9a), TOBN(0x9a08d536, 0xdf53f62c),
-+     TOBN(0x4ed71457, 0x6be5f7de), TOBN(0xd93006f8, 0xc2263c9e),
-+     TOBN(0xe073694c, 0xcacacb36), TOBN(0x2ff7a5b4, 0x3ae118ab),
-+     TOBN(0x3cce53f1, 0xcd871236), TOBN(0xf156a39d, 0xc2aa6d52),
-+     TOBN(0x9cc5f271, 0xb198d76d), TOBN(0xbc615b6f, 0x81383d39),
-+     TOBN(0xa54538e8, 0xde3eee6b), TOBN(0x58c77538, 0xab910d91),
-+     TOBN(0x31e5bdbc, 0x58d278bd), TOBN(0x3cde4adf, 0xb963acae),
-+     TOBN(0xb1881fd2, 0x5302169c), TOBN(0x8ca60fa0, 0xa989ed8b),
-+     TOBN(0xa1999458, 0xff96a0ee), TOBN(0xc1141f03, 0xac6c283d),
-+     TOBN(0x7677408d, 0x6dfafed3), TOBN(0x33a01653, 0x39661588),
-+     TOBN(0x3c9c15ec, 0x0b726fa0), TOBN(0x090cfd93, 0x6c9b56da),
-+     TOBN(0xe34f4bae, 0xa3c40af5), TOBN(0x3469eadb, 0xd21129f1),
-+     TOBN(0xcc51674a, 0x1e207ce8), TOBN(0x1e293b24, 0xc83b1ef9),
-+     TOBN(0x17173d13, 0x1e6c0bb4), TOBN(0x19004695, 0x90776d35),
-+     TOBN(0xe7980e34, 0x6de6f922), TOBN(0x873554cb, 0xf4dd9a22),
-+     TOBN(0x0316c627, 0xcbf18a51), TOBN(0x4d93651b, 0x3032c081),
-+     TOBN(0x207f2771, 0x3946834d), TOBN(0x2c08d7b4, 0x30cdbf80),
-+     TOBN(0x137a4fb4, 0x86df2a61), TOBN(0xa1ed9c07, 0xecf7b4a2),
-+     TOBN(0xb2e460e2, 0x7bd042ff), TOBN(0xb7f5e2fa, 0x5f62f5ec),
-+     TOBN(0x7aa6ec6b, 0xcc2423b7), TOBN(0x75ce0a7f, 0xba63eea7),
-+     TOBN(0x67a45fb1, 0xf250a6e1), TOBN(0x93bc919c, 0xe53cdc9f),
-+     TOBN(0x9271f56f, 0x871942df), TOBN(0x2372ff6f, 0x7859ad66),
-+     TOBN(0x5f4c2b96, 0x33cb1a78), TOBN(0xe3e29101, 0x5838aa83),
-+     TOBN(0xa7ed1611, 0xe4e8110c), TOBN(0x2a2d70d5, 0x330198ce),
-+     TOBN(0xbdf132e8, 0x6720efe0), TOBN(0xe61a8962, 0x66a471bf),
-+     TOBN(0x796d3a85, 0x825808bd), TOBN(0x51dc3cb7, 0x3fd6e902),
-+     TOBN(0x643c768a, 0x916219d1), TOBN(0x36cd7685, 0xa2ad7d32),
-+     TOBN(0xe3db9d05, 0xb22922a4), TOBN(0x6494c87e, 0xdba29660),
-+     TOBN(0xf0ac91df, 0xbcd2ebc7), TOBN(0x4deb57a0, 0x45107f8d),
-+     TOBN(0x42271f59, 0xc3d12a73), TOBN(0x5f71687c, 0xa5c2c51d),
-+     TOBN(0xcb1f50c6, 0x05797bcb), TOBN(0x29ed0ed9, 0xd6d34eb0),
-+     TOBN(0xe5fe5b47, 0x4683c2eb), TOBN(0x4956eeb5, 0x97447c46),
-+     TOBN(0x5b163a43, 0x71207167), TOBN(0x93fa2fed, 0x0248c5ef),
-+     TOBN(0x67930af2, 0x31f63950), TOBN(0xa77797c1, 0x14caa2c9),
-+     TOBN(0x526e80ee, 0x27ac7e62), TOBN(0xe1e6e626, 0x58b28aec),
-+     TOBN(0x636178b0, 0xb3c9fef0), TOBN(0xaf7752e0, 0x6d5f90be),
-+     TOBN(0x94ecaf18, 0xeece51cf), TOBN(0x2864d0ed, 0xca806e1f),
-+     TOBN(0x6de2e383, 0x97c69134), TOBN(0x5a42c316, 0xeb291293),
-+     TOBN(0xc7779219, 0x6a60bae0), TOBN(0xa24de346, 0x6b7599d1),
-+     TOBN(0x49d374aa, 0xb75d4941), TOBN(0x98900586, 0x2d501ff0),
-+     TOBN(0x9f16d40e, 0xeb7974cf), TOBN(0x1033860b, 0xcdd8c115),
-+     TOBN(0xb6c69ac8, 0x2094cec3), TOBN(0x9976fb88, 0x403b770c),
-+     TOBN(0x1dea026c, 0x4859590d), TOBN(0xb6acbb46, 0x8562d1fd),
-+     TOBN(0x7cd6c461, 0x44569d85), TOBN(0xc3190a36, 0x97f0891d),
-+     TOBN(0xc6f53195, 0x48d5a17d), TOBN(0x7d919966, 0xd749abc8),
-+     TOBN(0x65104837, 0xdd1c8a20), TOBN(0x7e5410c8, 0x2f683419),
-+     TOBN(0x958c3ca8, 0xbe94022e), TOBN(0x605c3197, 0x6145dac2),
-+     TOBN(0x3fc07501, 0x01683d54), TOBN(0x1d7127c5, 0x595b1234),
-+     TOBN(0x10b8f87c, 0x9481277f), TOBN(0x677db2a8, 0xe65a1adb),
-+     TOBN(0xec2fccaa, 0xddce3345), TOBN(0x2a6811b7, 0x012a4350),
-+     TOBN(0x96760ff1, 0xac598bdc), TOBN(0x054d652a, 0xd1bf4128),
-+     TOBN(0x0a1151d4, 0x92a21005), TOBN(0xad7f3971, 0x33110fdf),
-+     TOBN(0x8c95928c, 0x1960100f), TOBN(0x6c91c825, 0x7bf03362),
-+     TOBN(0xc8c8b2a2, 0xce309f06), TOBN(0xfdb27b59, 0xca27204b),
-+     TOBN(0xd223eaa5, 0x0848e32e), TOBN(0xb93e4b2e, 0xe7bfaf1e),
-+     TOBN(0xc5308ae6, 0x44aa3ded), TOBN(0x317a666a, 0xc015d573),
-+     TOBN(0xc888ce23, 0x1a979707), TOBN(0xf141c1e6, 0x0d5c4958),
-+     TOBN(0xb53b7de5, 0x61906373), TOBN(0x858dbade, 0xeb999595),
-+     TOBN(0x8cbb47b2, 0xa59e5c36), TOBN(0x660318b3, 0xdcf4e842),
-+     TOBN(0xbd161ccd, 0x12ba4b7a), TOBN(0xf399daab, 0xf8c8282a),
-+     TOBN(0x1587633a, 0xeeb2130d), TOBN(0xa465311a, 0xda38dd7d),
-+     TOBN(0x5f75eec8, 0x64d3779b), TOBN(0x3c5d0476, 0xad64c171),
-+     TOBN(0x87410371, 0x2a914428), TOBN(0x8096a891, 0x90e2fc29),
-+     TOBN(0xd3d2ae9d, 0x23b3ebc2), TOBN(0x90bdd6db, 0xa580cfd6),
-+     TOBN(0x52dbb7f3, 0xc5b01f6c), TOBN(0xe68eded4, 0xe102a2dc),
-+     TOBN(0x17785b77, 0x99eb6df0), TOBN(0x26c3cc51, 0x7386b779),
-+     TOBN(0x345ed988, 0x6417a48e), TOBN(0xe990b4e4, 0x07d6ef31),
-+     TOBN(0x0f456b7e, 0x2586abba), TOBN(0x239ca6a5, 0x59c96e9a),
-+     TOBN(0xe327459c, 0xe2eb4206), TOBN(0x3a4c3313, 0xa002b90a),
-+     TOBN(0x2a114806, 0xf6a3f6fb), TOBN(0xad5cad2f, 0x85c251dd),
-+     TOBN(0x92c1f613, 0xf5a784d3), TOBN(0xec7bfacf, 0x349766d5),
-+     TOBN(0x04b3cd33, 0x3e23cb3b), TOBN(0x3979fe84, 0xc5a64b2d),
-+     TOBN(0x192e2720, 0x7e589106), TOBN(0xa60c43d1, 0xa15b527f),
-+     TOBN(0x2dae9082, 0xbe7cf3a6), TOBN(0xcc86ba92, 0xbc967274),
-+     TOBN(0xf28a2ce8, 0xaea0a8a9), TOBN(0x404ca6d9, 0x6ee988b3),
-+     TOBN(0xfd7e9c5d, 0x005921b8), TOBN(0xf56297f1, 0x44e79bf9),
-+     TOBN(0xa163b460, 0x0d75ddc2), TOBN(0x30b23616, 0xa1f2be87),
-+     TOBN(0x4b070d21, 0xbfe50e2b), TOBN(0x7ef8cfd0, 0xe1bfede1),
-+     TOBN(0xadba0011, 0x2aac4ae0), TOBN(0x2a3e7d01, 0xb9ebd033),
-+     TOBN(0x995277ec, 0xe38d9d1c), TOBN(0xb500249e, 0x9c5d2de3),
-+     TOBN(0x8912b820, 0xf13ca8c9), TOBN(0xc8798114, 0x877793af),
-+     TOBN(0x19e6125d, 0xec3f1dec), TOBN(0x07b1f040, 0x911178da),
-+     TOBN(0xd93ededa, 0x904a6738), TOBN(0x55187a5a, 0x0bebedcd),
-+     TOBN(0xf7d04722, 0xeb329d41), TOBN(0xf449099e, 0xf170b391),
-+     TOBN(0xfd317a69, 0xca99f828), TOBN(0x50c3db2b, 0x34a4976d),
-+     TOBN(0xe9ba7784, 0x3757b392), TOBN(0x326caefd, 0xaa3ca05a),
-+     TOBN(0x78e5293b, 0xf1e593d4), TOBN(0x7842a937, 0x0d98fd13),
-+     TOBN(0xe694bf96, 0x5f96b10d), TOBN(0x373a9df6, 0x06a8cd05),
-+     TOBN(0x997d1e51, 0xe8f0c7fc), TOBN(0x1d019790, 0x63fd972e),
-+     TOBN(0x0064d858, 0x5499fb32), TOBN(0x7b67bad9, 0x77a8aeb7),
-+     TOBN(0x1d3eb977, 0x2d08eec5), TOBN(0x5fc047a6, 0xcbabae1d),
-+     TOBN(0x0577d159, 0xe54a64bb), TOBN(0x8862201b, 0xc43497e4),
-+     TOBN(0xad6b4e28, 0x2ce0608d), TOBN(0x8b687b7d, 0x0b167aac),
-+     TOBN(0x6ed4d367, 0x8b2ecfa9), TOBN(0x24dfe62d, 0xa90c3c38),
-+     TOBN(0xa1862e10, 0x3fe5c42b), TOBN(0x1ca73dca, 0xd5732a9f),
-+     TOBN(0x35f038b7, 0x76bb87ad), TOBN(0x674976ab, 0xf242b81f),
-+     TOBN(0x4f2bde7e, 0xb0fd90cd), TOBN(0x6efc172e, 0xa7fdf092),
-+     TOBN(0x3806b69b, 0x92222f1f), TOBN(0x5a2459ca, 0x6cf7ae70),
-+     TOBN(0x6789f69c, 0xa85217ee), TOBN(0x5f232b5e, 0xe3dc85ac),
-+     TOBN(0x660e3ec5, 0x48e9e516), TOBN(0x124b4e47, 0x3197eb31),
-+     TOBN(0x10a0cb13, 0xaafcca23), TOBN(0x7bd63ba4, 0x8213224f),
-+     TOBN(0xaffad7cc, 0x290a7f4f), TOBN(0x6b409c9e, 0x0286b461),
-+     TOBN(0x58ab809f, 0xffa407af), TOBN(0xc3122eed, 0xc68ac073),
-+     TOBN(0x17bf9e50, 0x4ef24d7e), TOBN(0x5d929794, 0x3e2a5811),
-+     TOBN(0x519bc867, 0x02902e01), TOBN(0x76bba5da, 0x39c8a851),
-+     TOBN(0xe9f9669c, 0xda94951e), TOBN(0x4b6af58d, 0x66b8d418),
-+     TOBN(0xfa321074, 0x17d426a4), TOBN(0xc78e66a9, 0x9dde6027),
-+     TOBN(0x0516c083, 0x4a53b964), TOBN(0xfc659d38, 0xff602330),
-+     TOBN(0x0ab55e5c, 0x58c5c897), TOBN(0x985099b2, 0x838bc5df),
-+     TOBN(0x061d9efc, 0xc52fc238), TOBN(0x712b2728, 0x6ac1da3f),
-+     TOBN(0xfb658149, 0x9283fe08), TOBN(0x4954ac94, 0xb8aaa2f7),
-+     TOBN(0x85c0ada4, 0x7fb2e74f), TOBN(0xee8ba98e, 0xb89926b0),
-+     TOBN(0xe4f9d37d, 0x23d1af5b), TOBN(0x14ccdbf9, 0xba9b015e),
-+     TOBN(0xb674481b, 0x7bfe7178), TOBN(0x4e1debae, 0x65405868),
-+     TOBN(0x061b2821, 0xc48c867d), TOBN(0x69c15b35, 0x513b30ea),
-+     TOBN(0x3b4a1666, 0x36871088), TOBN(0xe5e29f5d, 0x1220b1ff),
-+     TOBN(0x4b82bb35, 0x233d9f4d), TOBN(0x4e076333, 0x18cdc675)}
-+    ,
-+    {TOBN(0x0d53f5c7, 0xa3e6fced), TOBN(0xe8cbbdd5, 0xf45fbdeb),
-+     TOBN(0xf85c01df, 0x13339a70), TOBN(0x0ff71880, 0x142ceb81),
-+     TOBN(0x4c4e8774, 0xbd70437a), TOBN(0x5fb32891, 0xba0bda6a),
-+     TOBN(0x1cdbebd2, 0xf18bd26e), TOBN(0x2f9526f1, 0x03a9d522),
-+     TOBN(0x40ce3051, 0x92c4d684), TOBN(0x8b04d725, 0x7612efcd),
-+     TOBN(0xb9dcda36, 0x6f9cae20), TOBN(0x0edc4d24, 0xf058856c),
-+     TOBN(0x64f2e6bf, 0x85427900), TOBN(0x3de81295, 0xdc09dfea),
-+     TOBN(0xd41b4487, 0x379bf26c), TOBN(0x50b62c6d, 0x6df135a9),
-+     TOBN(0xd4f8e3b4, 0xc72dfe67), TOBN(0xc416b0f6, 0x90e19fdf),
-+     TOBN(0x18b9098d, 0x4c13bd35), TOBN(0xac11118a, 0x15b8cb9e),
-+     TOBN(0xf598a318, 0xf0062841), TOBN(0xbfe0602f, 0x89f356f4),
-+     TOBN(0x7ae3637e, 0x30177a0c), TOBN(0x34097747, 0x61136537),
-+     TOBN(0x0db2fb5e, 0xd005832a), TOBN(0x5f5efd3b, 0x91042e4f),
-+     TOBN(0x8c4ffdc6, 0xed70f8ca), TOBN(0xe4645d0b, 0xb52da9cc),
-+     TOBN(0x9596f58b, 0xc9001d1f), TOBN(0x52c8f0bc, 0x4e117205),
-+     TOBN(0xfd4aa0d2, 0xe398a084), TOBN(0x815bfe3a, 0x104f49de),
-+     TOBN(0x97e5443f, 0x23885e5f), TOBN(0xf72f8f99, 0xe8433aab),
-+     TOBN(0xbd00b154, 0xe4d4e604), TOBN(0xd0b35e6a, 0xe5e173ff),
-+     TOBN(0x57b2a048, 0x9164722d), TOBN(0x3e3c665b, 0x88761ec8),
-+     TOBN(0x6bdd1397, 0x3da83832), TOBN(0x3c8b1a1e, 0x73dafe3b),
-+     TOBN(0x4497ace6, 0x54317cac), TOBN(0xbe600ab9, 0x521771b3),
-+     TOBN(0xb42e409e, 0xb0dfe8b8), TOBN(0x386a67d7, 0x3942310f),
-+     TOBN(0x25548d8d, 0x4431cc28), TOBN(0xa7cff142, 0x985dc524),
-+     TOBN(0x4d60f5a1, 0x93c4be32), TOBN(0x83ebd5c8, 0xd071c6e1),
-+     TOBN(0xba3a80a7, 0xb1fd2b0b), TOBN(0x9b3ad396, 0x5bec33e8),
-+     TOBN(0xb3868d61, 0x79743fb3), TOBN(0xcfd169fc, 0xfdb462fa),
-+     TOBN(0xd3b499d7, 0x9ce0a6af), TOBN(0x55dc1cf1, 0xe42d3ff8),
-+     TOBN(0x04fb9e6c, 0xc6c3e1b2), TOBN(0x47e6961d, 0x6f69a474),
-+     TOBN(0x54eb3acc, 0xe548b37b), TOBN(0xb38e7542, 0x84d40549),
-+     TOBN(0x8c3daa51, 0x7b341b4f), TOBN(0x2f6928ec, 0x690bf7fa),
-+     TOBN(0x0496b323, 0x86ce6c41), TOBN(0x01be1c55, 0x10adadcd),
-+     TOBN(0xc04e67e7, 0x4bb5faf9), TOBN(0x3cbaf678, 0xe15c9985),
-+     TOBN(0x8cd12145, 0x50ca4247), TOBN(0xba1aa47a, 0xe7dd30aa),
-+     TOBN(0x2f81ddf1, 0xe58fee24), TOBN(0x03452936, 0xeec9b0e8),
-+     TOBN(0x8bdc3b81, 0x243aea96), TOBN(0x9a2919af, 0x15c3d0e5),
-+     TOBN(0x9ea640ec, 0x10948361), TOBN(0x5ac86d5b, 0x6e0bcccf),
-+     TOBN(0xf892d918, 0xc36cf440), TOBN(0xaed3e837, 0xc939719c),
-+     TOBN(0xb07b08d2, 0xc0218b64), TOBN(0x6f1bcbba, 0xce9790dd),
-+     TOBN(0x4a84d6ed, 0x60919b8e), TOBN(0xd8900791, 0x8ac1f9eb),
-+     TOBN(0xf84941aa, 0x0dd5daef), TOBN(0xb22fe40a, 0x67fd62c5),
-+     TOBN(0x97e15ba2, 0x157f2db3), TOBN(0xbda2fc8f, 0x8e28ca9c),
-+     TOBN(0x5d050da4, 0x37b9f454), TOBN(0x3d57eb57, 0x2379d72e),
-+     TOBN(0xe9b5eba2, 0xfb5ee997), TOBN(0x01648ca2, 0xe11538ca),
-+     TOBN(0x32bb76f6, 0xf6327974), TOBN(0x338f14b8, 0xff3f4bb7),
-+     TOBN(0x524d226a, 0xd7ab9a2d), TOBN(0x9c00090d, 0x7dfae958),
-+     TOBN(0x0ba5f539, 0x8751d8c2), TOBN(0x8afcbcdd, 0x3ab8262d),
-+     TOBN(0x57392729, 0xe99d043b), TOBN(0xef51263b, 0xaebc943a),
-+     TOBN(0x9feace93, 0x20862935), TOBN(0x639efc03, 0xb06c817b),
-+     TOBN(0x1fe054b3, 0x66b4be7a), TOBN(0x3f25a9de, 0x84a37a1e),
-+     TOBN(0xf39ef1ad, 0x78d75cd9), TOBN(0xd7b58f49, 0x5062c1b5),
-+     TOBN(0x6f74f9a9, 0xff563436), TOBN(0xf718ff29, 0xe8af51e7),
-+     TOBN(0x5234d313, 0x15e97fec), TOBN(0xb6a8e2b1, 0x292f1c0a),
-+     TOBN(0xa7f53aa8, 0x327720c1), TOBN(0x956ca322, 0xba092cc8),
-+     TOBN(0x8f03d64a, 0x28746c4d), TOBN(0x51fe1782, 0x66d0d392),
-+     TOBN(0xd19b34db, 0x3c832c80), TOBN(0x60dccc5c, 0x6da2e3b4),
-+     TOBN(0x245dd62e, 0x0a104ccc), TOBN(0xa7ab1de1, 0x620b21fd),
-+     TOBN(0xb293ae0b, 0x3893d123), TOBN(0xf7b75783, 0xb15ee71c),
-+     TOBN(0x5aa3c614, 0x42a9468b), TOBN(0xd686123c, 0xdb15d744),
-+     TOBN(0x8c616891, 0xa7ab4116), TOBN(0x6fcd72c8, 0xa4e6a459),
-+     TOBN(0xac219110, 0x77e5fad7), TOBN(0xfb6a20e7, 0x704fa46b),
-+     TOBN(0xe839be7d, 0x341d81dc), TOBN(0xcddb6889, 0x32148379),
-+     TOBN(0xda6211a1, 0xf7026ead), TOBN(0xf3b2575f, 0xf4d1cc5e),
-+     TOBN(0x40cfc8f6, 0xa7a73ae6), TOBN(0x83879a5e, 0x61d5b483),
-+     TOBN(0xc5acb1ed, 0x41a50ebc), TOBN(0x59a60cc8, 0x3c07d8fa),
-+     TOBN(0x1b73bdce, 0xb1876262), TOBN(0x2b0d79f0, 0x12af4ee9),
-+     TOBN(0x8bcf3b0b, 0xd46e1d07), TOBN(0x17d6af9d, 0xe45d152f),
-+     TOBN(0x73520461, 0x6d736451), TOBN(0x43cbbd97, 0x56b0bf5a),
-+     TOBN(0xb0833a5b, 0xd5999b9d), TOBN(0x702614f0, 0xeb72e398),
-+     TOBN(0x0aadf01a, 0x59c3e9f8), TOBN(0x40200e77, 0xce6b3d16),
-+     TOBN(0xda22bdd3, 0xdeddafad), TOBN(0x76dedaf4, 0x310d72e1),
-+     TOBN(0x49ef807c, 0x4bc2e88f), TOBN(0x6ba81291, 0x146dd5a5),
-+     TOBN(0xa1a4077a, 0x7d8d59e9), TOBN(0x87b6a2e7, 0x802db349),
-+     TOBN(0xd5679997, 0x1b4e598e), TOBN(0xf499ef1f, 0x06fe4b1d),
-+     TOBN(0x3978d3ae, 0xfcb267c5), TOBN(0xb582b557, 0x235786d0),
-+     TOBN(0x32b3b2ca, 0x1715cb07), TOBN(0x4c3de6a2, 0x8480241d),
-+     TOBN(0x63b5ffed, 0xcb571ecd), TOBN(0xeaf53900, 0xed2fe9a9),
-+     TOBN(0xdec98d4a, 0xc3b81990), TOBN(0x1cb83722, 0x9e0cc8fe),
-+     TOBN(0xfe0b0491, 0xd2b427b9), TOBN(0x0f2386ac, 0xe983a66c),
-+     TOBN(0x930c4d1e, 0xb3291213), TOBN(0xa2f82b2e, 0x59a62ae4),
-+     TOBN(0x77233853, 0xf93e89e3), TOBN(0x7f8063ac, 0x11777c7f),
-+     TOBN(0xff0eb567, 0x59ad2877), TOBN(0x6f454642, 0x9865c754),
-+     TOBN(0xe6fe701a, 0x236e9a84), TOBN(0xc586ef16, 0x06e40fc3),
-+     TOBN(0x3f62b6e0, 0x24bafad9), TOBN(0xc8b42bd2, 0x64da906a),
-+     TOBN(0xc98e1eb4, 0xda3276a0), TOBN(0x30d0e5fc, 0x06cbf852),
-+     TOBN(0x1b6b2ae1, 0xe8b4dfd4), TOBN(0xd754d5c7, 0x8301cbac),
-+     TOBN(0x66097629, 0x112a39ac), TOBN(0xf86b5999, 0x93ba4ab9),
-+     TOBN(0x26c9dea7, 0x99f9d581), TOBN(0x0473b1a8, 0xc2fafeaa),
-+     TOBN(0x1469af55, 0x3b2505a5), TOBN(0x227d16d7, 0xd6a43323),
-+     TOBN(0x3316f73c, 0xad3d97f9), TOBN(0x52bf3bb5, 0x1f137455),
-+     TOBN(0x953eafeb, 0x09954e7c), TOBN(0xa721dfed, 0xdd732411),
-+     TOBN(0xb4929821, 0x141d4579), TOBN(0x3411321c, 0xaa3bd435),
-+     TOBN(0xafb355aa, 0x17fa6015), TOBN(0xb4e7ef4a, 0x18e42f0e),
-+     TOBN(0x604ac97c, 0x59371000), TOBN(0xe1c48c70, 0x7f759c18),
-+     TOBN(0x3f62ecc5, 0xa5db6b65), TOBN(0x0a78b173, 0x38a21495),
-+     TOBN(0x6be1819d, 0xbcc8ad94), TOBN(0x70dc04f6, 0xd89c3400),
-+     TOBN(0x462557b4, 0xa6b4840a), TOBN(0x544c6ade, 0x60bd21c0),
-+     TOBN(0x6a00f24e, 0x907a544b), TOBN(0xa7520dcb, 0x313da210),
-+     TOBN(0xfe939b75, 0x11e4994b), TOBN(0x918b6ba6, 0xbc275d70),
-+     TOBN(0xd3e5e0fc, 0x644be892), TOBN(0x707a9816, 0xfdaf6c42),
-+     TOBN(0x60145567, 0xf15c13fe), TOBN(0x4818ebaa, 0xe130a54a),
-+     TOBN(0x28aad3ad, 0x58d2f767), TOBN(0xdc5267fd, 0xd7e7c773),
-+     TOBN(0x4919cc88, 0xc3afcc98), TOBN(0xaa2e6ab0, 0x2db8cd4b),
-+     TOBN(0xd46fec04, 0xd0c63eaa), TOBN(0xa1cb92c5, 0x19ffa832),
-+     TOBN(0x678dd178, 0xe43a631f), TOBN(0xfb5ae1cd, 0x3dc788b3),
-+     TOBN(0x68b4fb90, 0x6e77de04), TOBN(0x7992bcf0, 0xf06dbb97),
-+     TOBN(0x896e6a13, 0xc417c01d), TOBN(0x8d96332c, 0xb956be01),
-+     TOBN(0x902fc93a, 0x413aa2b9), TOBN(0x99a4d915, 0xfc98c8a5),
-+     TOBN(0x52c29407, 0x565f1137), TOBN(0x4072690f, 0x21e4f281),
-+     TOBN(0x36e607cf, 0x02ff6072), TOBN(0xa47d2ca9, 0x8ad98cdc),
-+     TOBN(0xbf471d1e, 0xf5f56609), TOBN(0xbcf86623, 0xf264ada0),
-+     TOBN(0xb70c0687, 0xaa9e5cb6), TOBN(0xc98124f2, 0x17401c6c),
-+     TOBN(0x8189635f, 0xd4a61435), TOBN(0xd28fb8af, 0xa9d98ea6),
-+     TOBN(0xb9a67c2a, 0x40c251f8), TOBN(0x88cd5d87, 0xa2da44be),
-+     TOBN(0x437deb96, 0xe09b5423), TOBN(0x150467db, 0x64287dc1),
-+     TOBN(0xe161debb, 0xcdabb839), TOBN(0xa79e9742, 0xf1839a3e),
-+     TOBN(0xbb8dd3c2, 0x652d202b), TOBN(0x7b3e67f7, 0xe9f97d96),
-+     TOBN(0x5aa5d78f, 0xb1cb6ac9), TOBN(0xffa13e8e, 0xca1d0d45),
-+     TOBN(0x369295dd, 0x2ba5bf95), TOBN(0xd68bd1f8, 0x39aff05e),
-+     TOBN(0xaf0d86f9, 0x26d783f2), TOBN(0x543a59b3, 0xfc3aafc1),
-+     TOBN(0x3fcf81d2, 0x7b7da97c), TOBN(0xc990a056, 0xd25dee46),
-+     TOBN(0x3e6775b8, 0x519cce2c), TOBN(0xfc9af71f, 0xae13d863),
-+     TOBN(0x774a4a6f, 0x47c1605c), TOBN(0x46ba4245, 0x2fd205e8),
-+     TOBN(0xa06feea4, 0xd3fd524d), TOBN(0x1e724641, 0x6de1acc2),
-+     TOBN(0xf53816f1, 0x334e2b42), TOBN(0x49e5918e, 0x922f0024),
-+     TOBN(0x439530b6, 0x65c7322d), TOBN(0xcf12cc01, 0xb3c1b3fb),
-+     TOBN(0xc70b0186, 0x0172f685), TOBN(0xb915ee22, 0x1b58391d),
-+     TOBN(0x9afdf03b, 0xa317db24), TOBN(0x87dec659, 0x17b8ffc4),
-+     TOBN(0x7f46597b, 0xe4d3d050), TOBN(0x80a1c1ed, 0x006500e7),
-+     TOBN(0x84902a96, 0x78bf030e), TOBN(0xfb5e9c9a, 0x50560148),
-+     TOBN(0x6dae0a92, 0x63362426), TOBN(0xdcaeecf4, 0xa9e30c40),
-+     TOBN(0xc0d887bb, 0x518d0c6b), TOBN(0x99181152, 0xcb985b9d),
-+     TOBN(0xad186898, 0xef7bc381), TOBN(0x18168ffb, 0x9ee46201),
-+     TOBN(0x9a04cdaa, 0x2502753c), TOBN(0xbb279e26, 0x51407c41),
-+     TOBN(0xeacb03aa, 0xf23564e5), TOBN(0x18336582, 0x71e61016),
-+     TOBN(0x8684b8c4, 0xeb809877), TOBN(0xb336e18d, 0xea0e672e),
-+     TOBN(0xefb601f0, 0x34ee5867), TOBN(0x2733edbe, 0x1341cfd1),
-+     TOBN(0xb15e809a, 0x26025c3c), TOBN(0xe6e981a6, 0x9350df88),
-+     TOBN(0x92376237, 0x8502fd8e), TOBN(0x4791f216, 0x0c12be9b),
-+     TOBN(0xb7256789, 0x25f02425), TOBN(0xec863194, 0x7a974443),
-+     TOBN(0x7c0ce882, 0xfb41cc52), TOBN(0xc266ff7e, 0xf25c07f2),
-+     TOBN(0x3d4da8c3, 0x017025f3), TOBN(0xefcf628c, 0xfb9579b4),
-+     TOBN(0x5c4d0016, 0x1f3716ec), TOBN(0x9c27ebc4, 0x6801116e),
-+     TOBN(0x5eba0ea1, 0x1da1767e), TOBN(0xfe151452, 0x47004c57),
-+     TOBN(0x3ace6df6, 0x8c2373b7), TOBN(0x75c3dffe, 0x5dbc37ac),
-+     TOBN(0x3dc32a73, 0xddc925fc), TOBN(0xb679c841, 0x2f65ee0b),
-+     TOBN(0x715a3295, 0x451cbfeb), TOBN(0xd9889768, 0xf76e9a29),
-+     TOBN(0xec20ce7f, 0xb28ad247), TOBN(0xe99146c4, 0x00894d79),
-+     TOBN(0x71457d7c, 0x9f5e3ea7), TOBN(0x097b2662, 0x38030031),
-+     TOBN(0xdb7f6ae6, 0xcf9f82a8), TOBN(0x319decb9, 0x438f473a),
-+     TOBN(0xa63ab386, 0x283856c3), TOBN(0x13e3172f, 0xb06a361b),
-+     TOBN(0x2959f8dc, 0x7d5a006c), TOBN(0x2dbc27c6, 0x75fba752),
-+     TOBN(0xc1227ab2, 0x87c22c9e), TOBN(0x06f61f75, 0x71a268b2),
-+     TOBN(0x1b6bb971, 0x04779ce2), TOBN(0xaca83812, 0x0aadcb1d),
-+     TOBN(0x297ae0bc, 0xaeaab2d5), TOBN(0xa5c14ee7, 0x5bfb9f13),
-+     TOBN(0xaa00c583, 0xf17a62c7), TOBN(0x39eb962c, 0x173759f6),
-+     TOBN(0x1eeba1d4, 0x86c9a88f), TOBN(0x0ab6c37a, 0xdf016c5e),
-+     TOBN(0xa2a147db, 0xa28a0749), TOBN(0x246c20d6, 0xee519165),
-+     TOBN(0x5068d1b1, 0xd3810715), TOBN(0xb1e7018c, 0x748160b9),
-+     TOBN(0x03f5b1fa, 0xf380ff62), TOBN(0xef7fb1dd, 0xf3cb2c1e),
-+     TOBN(0xeab539a8, 0xfc91a7da), TOBN(0x83ddb707, 0xf3f9b561),
-+     TOBN(0xc550e211, 0xfe7df7a4), TOBN(0xa7cd07f2, 0x063f6f40),
-+     TOBN(0xb0de3635, 0x2976879c), TOBN(0xb5f83f85, 0xe55741da),
-+     TOBN(0x4ea9d25e, 0xf3d8ac3d), TOBN(0x6fe2066f, 0x62819f02),
-+     TOBN(0x4ab2b9c2, 0xcef4a564), TOBN(0x1e155d96, 0x5ffa2de3),
-+     TOBN(0x0eb0a19b, 0xc3a72d00), TOBN(0x4037665b, 0x8513c31b),
-+     TOBN(0x2fb2b6bf, 0x04c64637), TOBN(0x45c34d6e, 0x08cdc639),
-+     TOBN(0x56f1e10f, 0xf01fd796), TOBN(0x4dfb8101, 0xfe3667b8),
-+     TOBN(0xe0eda253, 0x9021d0c0), TOBN(0x7a94e9ff, 0x8a06c6ab),
-+     TOBN(0x2d3bb0d9, 0xbb9aa882), TOBN(0xea20e4e5, 0xec05fd10),
-+     TOBN(0xed7eeb5f, 0x1a1ca64e), TOBN(0x2fa6b43c, 0xc6327cbd),
-+     TOBN(0xb577e3cf, 0x3aa91121), TOBN(0x8c6bd5ea, 0x3a34079b),
-+     TOBN(0xd7e5ba39, 0x60e02fc0), TOBN(0xf16dd2c3, 0x90141bf8),
-+     TOBN(0xb57276d9, 0x80101b98), TOBN(0x760883fd, 0xb82f0f66),
-+     TOBN(0x89d7de75, 0x4bc3eff3), TOBN(0x03b60643, 0x5dc2ab40),
-+     TOBN(0xcd6e53df, 0xe05beeac), TOBN(0xf2f1e862, 0xbc3325cd),
-+     TOBN(0xdd0f7921, 0x774f03c3), TOBN(0x97ca7221, 0x4552cc1b),
-+     TOBN(0x5a0d6afe, 0x1cd19f72), TOBN(0xa20915dc, 0xf183fbeb),
-+     TOBN(0x9fda4b40, 0x832c403c), TOBN(0x32738edd, 0xbe425442),
-+     TOBN(0x469a1df6, 0xb5eccf1a), TOBN(0x4b5aff42, 0x28bbe1f0),
-+     TOBN(0x31359d7f, 0x570dfc93), TOBN(0xa18be235, 0xf0088628),
-+     TOBN(0xa5b30fba, 0xb00ed3a9), TOBN(0x34c61374, 0x73cdf8be),
-+     TOBN(0x2c5c5f46, 0xabc56797), TOBN(0x5cecf93d, 0xb82a8ae2),
-+     TOBN(0x7d3dbe41, 0xa968fbf0), TOBN(0xd23d4583, 0x1a5c7f3d),
-+     TOBN(0xf28f69a0, 0xc087a9c7), TOBN(0xc2d75471, 0x474471ca),
-+     TOBN(0x36ec9f4a, 0x4eb732ec), TOBN(0x6c943bbd, 0xb1ca6bed),
-+     TOBN(0xd64535e1, 0xf2457892), TOBN(0x8b84a8ea, 0xf7e2ac06),
-+     TOBN(0xe0936cd3, 0x2499dd5f), TOBN(0x12053d7e, 0x0ed04e57),
-+     TOBN(0x4bdd0076, 0xe4305d9d), TOBN(0x34a527b9, 0x1f67f0a2),
-+     TOBN(0xe79a4af0, 0x9cec46ea), TOBN(0xb15347a1, 0x658b9bc7),
-+     TOBN(0x6bd2796f, 0x35af2f75), TOBN(0xac957990, 0x4051c435),
-+     TOBN(0x2669dda3, 0xc33a655d), TOBN(0x5d503c2e, 0x88514aa3),
-+     TOBN(0xdfa11337, 0x3753dd41), TOBN(0x3f054673, 0x0b754f78),
-+     TOBN(0xbf185677, 0x496125bd), TOBN(0xfb0023c8, 0x3775006c),
-+     TOBN(0xfa0f072f, 0x3a037899), TOBN(0x4222b6eb, 0x0e4aea57),
-+     TOBN(0x3dde5e76, 0x7866d25a), TOBN(0xb6eb04f8, 0x4837aa6f),
-+     TOBN(0x5315591a, 0x2cf1cdb8), TOBN(0x6dfb4f41, 0x2d4e683c),
-+     TOBN(0x7e923ea4, 0x48ee1f3a), TOBN(0x9604d9f7, 0x05a2afd5),
-+     TOBN(0xbe1d4a33, 0x40ea4948), TOBN(0x5b45f1f4, 0xb44cbd2f),
-+     TOBN(0x5faf8376, 0x4acc757e), TOBN(0xa7cf9ab8, 0x63d68ff7),
-+     TOBN(0x8ad62f69, 0xdf0e404b), TOBN(0xd65f33c2, 0x12bdafdf),
-+     TOBN(0xc365de15, 0xa377b14e), TOBN(0x6bf5463b, 0x8e39f60c),
-+     TOBN(0x62030d2d, 0x2ce68148), TOBN(0xd95867ef, 0xe6f843a8),
-+     TOBN(0xd39a0244, 0xef5ab017), TOBN(0x0bd2d8c1, 0x4ab55d12),
-+     TOBN(0xc9503db3, 0x41639169), TOBN(0x2d4e25b0, 0xf7660c8a),
-+     TOBN(0x760cb3b5, 0xe224c5d7), TOBN(0xfa3baf8c, 0x68616919),
-+     TOBN(0x9fbca113, 0x8d142552), TOBN(0x1ab18bf1, 0x7669ebf5),
-+     TOBN(0x55e6f53e, 0x9bdf25dd), TOBN(0x04cc0bf3, 0xcb6cd154),
-+     TOBN(0x595bef49, 0x95e89080), TOBN(0xfe9459a8, 0x104a9ac1),
-+     TOBN(0xad2d89ca, 0xcce9bb32), TOBN(0xddea65e1, 0xf7de8285),
-+     TOBN(0x62ed8c35, 0xb351bd4b), TOBN(0x4150ff36, 0x0c0e19a7),
-+     TOBN(0x86e3c801, 0x345f4e47), TOBN(0x3bf21f71, 0x203a266c),
-+     TOBN(0x7ae110d4, 0x855b1f13), TOBN(0x5d6aaf6a, 0x07262517),
-+     TOBN(0x1e0f12e1, 0x813d28f1), TOBN(0x6000e11d, 0x7ad7a523),
-+     TOBN(0xc7d8deef, 0xc744a17b), TOBN(0x1e990b48, 0x14c05a00),
-+     TOBN(0x68fddaee, 0x93e976d5), TOBN(0x696241d1, 0x46610d63),
-+     TOBN(0xb204e7c3, 0x893dda88), TOBN(0x8bccfa65, 0x6a3a6946),
-+     TOBN(0xb59425b4, 0xc5cd1411), TOBN(0x701b4042, 0xff3658b1),
-+     TOBN(0xe3e56bca, 0x4784cf93), TOBN(0x27de5f15, 0x8fe68d60),
-+     TOBN(0x4ab9cfce, 0xf8d53f19), TOBN(0xddb10311, 0xa40a730d),
-+     TOBN(0x6fa73cd1, 0x4eee0a8a), TOBN(0xfd548748, 0x5249719d),
-+     TOBN(0x49d66316, 0xa8123ef0), TOBN(0x73c32db4, 0xe7f95438),
-+     TOBN(0x2e2ed209, 0x0d9e7854), TOBN(0xf98a9329, 0x9d9f0507),
-+     TOBN(0xc5d33cf6, 0x0c6aa20a), TOBN(0x9a32ba14, 0x75279bb2),
-+     TOBN(0x7e3202cb, 0x774a7307), TOBN(0x64ed4bc4, 0xe8c42dbd),
-+     TOBN(0xc20f1a06, 0xd4caed0d), TOBN(0xb8021407, 0x171d22b3),
-+     TOBN(0xd426ca04, 0xd13268d7), TOBN(0x92377007, 0x25f4d126),
-+     TOBN(0x4204cbc3, 0x71f21a85), TOBN(0x18461b7a, 0xf82369ba),
-+     TOBN(0xc0c07d31, 0x3fc858f9), TOBN(0x5deb5a50, 0xe2bab569),
-+     TOBN(0xd5959d46, 0xd5eea89e), TOBN(0xfdff8424, 0x08437f4b),
-+     TOBN(0xf21071e4, 0x3cfe254f), TOBN(0x72417696, 0x95468321),
-+     TOBN(0x5d8288b9, 0x102cae3e), TOBN(0x2d143e3d, 0xf1965dff),
-+     TOBN(0x00c9a376, 0xa078d847), TOBN(0x6fc0da31, 0x26028731),
-+     TOBN(0xa2baeadf, 0xe45083a2), TOBN(0x66bc7218, 0x5e5b4bcd),
-+     TOBN(0x2c826442, 0xd04b8e7f), TOBN(0xc19f5451, 0x6c4b586b),
-+     TOBN(0x60182c49, 0x5b7eeed5), TOBN(0xd9954ecd, 0x7aa9dfa1),
-+     TOBN(0xa403a8ec, 0xc73884ad), TOBN(0x7fb17de2, 0x9bb39041),
-+     TOBN(0x694b64c5, 0xabb020e8), TOBN(0x3d18c184, 0x19c4eec7),
-+     TOBN(0x9c4673ef, 0x1c4793e5), TOBN(0xc7b8aeb5, 0x056092e6),
-+     TOBN(0x3aa1ca43, 0xf0f8c16b), TOBN(0x224ed5ec, 0xd679b2f6),
-+     TOBN(0x0d56eeaf, 0x55a205c9), TOBN(0xbfe115ba, 0x4b8e028b),
-+     TOBN(0x97e60849, 0x3927f4fe), TOBN(0xf91fbf94, 0x759aa7c5),
-+     TOBN(0x985af769, 0x6be90a51), TOBN(0xc1277b78, 0x78ccb823),
-+     TOBN(0x395b656e, 0xe7a75952), TOBN(0x00df7de0, 0x928da5f5),
-+     TOBN(0x09c23175, 0x4ca4454f), TOBN(0x4ec971f4, 0x7aa2d3c1),
-+     TOBN(0x45c3c507, 0xe75d9ccc), TOBN(0x63b7be8a, 0x3dc90306),
-+     TOBN(0x37e09c66, 0x5db44bdc), TOBN(0x50d60da1, 0x6841c6a2),
-+     TOBN(0x6f9b65ee, 0x08df1b12), TOBN(0x38734879, 0x7ff089df),
-+     TOBN(0x9c331a66, 0x3fe8013d), TOBN(0x017f5de9, 0x5f42fcc8),
-+     TOBN(0x43077866, 0xe8e57567), TOBN(0xc9f781ce, 0xf9fcdb18),
-+     TOBN(0x38131dda, 0x9b12e174), TOBN(0x25d84aa3, 0x8a03752a),
-+     TOBN(0x45e09e09, 0x4d0c0ce2), TOBN(0x1564008b, 0x92bebba5),
-+     TOBN(0xf7e8ad31, 0xa87284c7), TOBN(0xb7c4b46c, 0x97e7bbaa),
-+     TOBN(0x3e22a7b3, 0x97acf4ec), TOBN(0x0426c400, 0x5ea8b640),
-+     TOBN(0x5e3295a6, 0x4e969285), TOBN(0x22aabc59, 0xa6a45670),
-+     TOBN(0xb929714c, 0x5f5942bc), TOBN(0x9a6168bd, 0xfa3182ed),
-+     TOBN(0x2216a665, 0x104152ba), TOBN(0x46908d03, 0xb6926368)}
-+    ,
-+    {TOBN(0xa9f5d874, 0x5a1251fb), TOBN(0x967747a8, 0xc72725c7),
-+     TOBN(0x195c33e5, 0x31ffe89e), TOBN(0x609d210f, 0xe964935e),
-+     TOBN(0xcafd6ca8, 0x2fe12227), TOBN(0xaf9b5b96, 0x0426469d),
-+     TOBN(0x2e9ee04c, 0x5693183c), TOBN(0x1084a333, 0xc8146fef),
-+     TOBN(0x96649933, 0xaed1d1f7), TOBN(0x566eaff3, 0x50563090),
-+     TOBN(0x345057f0, 0xad2e39cf), TOBN(0x148ff65b, 0x1f832124),
-+     TOBN(0x042e89d4, 0xcf94cf0d), TOBN(0x319bec84, 0x520c58b3),
-+     TOBN(0x2a267626, 0x5361aa0d), TOBN(0xc86fa302, 0x8fbc87ad),
-+     TOBN(0xfc83d2ab, 0x5c8b06d5), TOBN(0xb1a785a2, 0xfe4eac46),
-+     TOBN(0xb99315bc, 0x846f7779), TOBN(0xcf31d816, 0xef9ea505),
-+     TOBN(0x2391fe6a, 0x15d7dc85), TOBN(0x2f132b04, 0xb4016b33),
-+     TOBN(0x29547fe3, 0x181cb4c7), TOBN(0xdb66d8a6, 0x650155a1),
-+     TOBN(0x6b66d7e1, 0xadc1696f), TOBN(0x98ebe593, 0x0acd72d0),
-+     TOBN(0x65f24550, 0xcc1b7435), TOBN(0xce231393, 0xb4b9a5ec),
-+     TOBN(0x234a22d4, 0xdb067df9), TOBN(0x98dda095, 0xcaff9b00),
-+     TOBN(0x1bbc75a0, 0x6100c9c1), TOBN(0x1560a9c8, 0x939cf695),
-+     TOBN(0xcf006d3e, 0x99e0925f), TOBN(0x2dd74a96, 0x6322375a),
-+     TOBN(0xc58b446a, 0xb56af5ba), TOBN(0x50292683, 0xe0b9b4f1),
-+     TOBN(0xe2c34cb4, 0x1aeaffa3), TOBN(0x8b17203f, 0x9b9587c1),
-+     TOBN(0x6d559207, 0xead1350c), TOBN(0x2b66a215, 0xfb7f9604),
-+     TOBN(0x0850325e, 0xfe51bf74), TOBN(0x9c4f579e, 0x5e460094),
-+     TOBN(0x5c87b92a, 0x76da2f25), TOBN(0x889de4e0, 0x6febef33),
-+     TOBN(0x6900ec06, 0x646083ce), TOBN(0xbe2a0335, 0xbfe12773),
-+     TOBN(0xadd1da35, 0xc5344110), TOBN(0x757568b7, 0xb802cd20),
-+     TOBN(0x75559779, 0x00f7e6c8), TOBN(0x38e8b94f, 0x0facd2f0),
-+     TOBN(0xfea1f3af, 0x03fde375), TOBN(0x5e11a1d8, 0x75881dfc),
-+     TOBN(0xb3a6b02e, 0xc1e2f2ef), TOBN(0x193d2bbb, 0xc605a6c5),
-+     TOBN(0x325ffeee, 0x339a0b2d), TOBN(0x27b6a724, 0x9e0c8846),
-+     TOBN(0xe4050f1c, 0xf1c367ca), TOBN(0x9bc85a9b, 0xc90fbc7d),
-+     TOBN(0xa373c4a2, 0xe1a11032), TOBN(0xb64232b7, 0xad0393a9),
-+     TOBN(0xf5577eb0, 0x167dad29), TOBN(0x1604f301, 0x94b78ab2),
-+     TOBN(0x0baa94af, 0xe829348b), TOBN(0x77fbd8dd, 0x41654342),
-+     TOBN(0xdab50ea5, 0xb964e39a), TOBN(0xd4c29e3c, 0xd0d3c76e),
-+     TOBN(0x80dae67c, 0x56d11964), TOBN(0x7307a8bf, 0xe5ffcc2f),
-+     TOBN(0x65bbc1aa, 0x91708c3b), TOBN(0xa151e62c, 0x28bf0eeb),
-+     TOBN(0x6cb53381, 0x6fa34db7), TOBN(0x5139e05c, 0xa29403a8),
-+     TOBN(0x6ff651b4, 0x94a7cd2e), TOBN(0x5671ffd1, 0x0699336c),
-+     TOBN(0x6f5fd2cc, 0x979a896a), TOBN(0x11e893a8, 0xd8148cef),
-+     TOBN(0x988906a1, 0x65cf7b10), TOBN(0x81b67178, 0xc50d8485),
-+     TOBN(0x7c0deb35, 0x8a35b3de), TOBN(0x423ac855, 0xc1d29799),
-+     TOBN(0xaf580d87, 0xdac50b74), TOBN(0x28b2b89f, 0x5869734c),
-+     TOBN(0x99a3b936, 0x874e28fb), TOBN(0xbb2c9190, 0x25f3f73a),
-+     TOBN(0x199f6918, 0x84a9d5b7), TOBN(0x7ebe2325, 0x7e770374),
-+     TOBN(0xf442e107, 0x0738efe2), TOBN(0xcf9f3f56, 0xcf9082d2),
-+     TOBN(0x719f69e1, 0x09618708), TOBN(0xcc9e8364, 0xc183f9b1),
-+     TOBN(0xec203a95, 0x366a21af), TOBN(0x6aec5d6d, 0x068b141f),
-+     TOBN(0xee2df78a, 0x994f04e9), TOBN(0xb39ccae8, 0x271245b0),
-+     TOBN(0xb875a4a9, 0x97e43f4f), TOBN(0x507dfe11, 0xdb2cea98),
-+     TOBN(0x4fbf81cb, 0x489b03e9), TOBN(0xdb86ec5b, 0x6ec414fa),
-+     TOBN(0xfad444f9, 0xf51b3ae5), TOBN(0xca7d33d6, 0x1914e3fe),
-+     TOBN(0xa9c32f5c, 0x0ae6c4d0), TOBN(0xa9ca1d1e, 0x73969568),
-+     TOBN(0x98043c31, 0x1aa7467e), TOBN(0xe832e75c, 0xe21b5ac6),
-+     TOBN(0x314b7aea, 0x5232123d), TOBN(0x08307c8c, 0x65ae86db),
-+     TOBN(0x06e7165c, 0xaa4668ed), TOBN(0xb170458b, 0xb4d3ec39),
-+     TOBN(0x4d2e3ec6, 0xc19bb986), TOBN(0xc5f34846, 0xae0304ed),
-+     TOBN(0x917695a0, 0x6c9f9722), TOBN(0x6c7f7317, 0x4cab1c0a),
-+     TOBN(0x6295940e, 0x9d6d2e8b), TOBN(0xd318b8c1, 0x549f7c97),
-+     TOBN(0x22453204, 0x97713885), TOBN(0x468d834b, 0xa8a440fe),
-+     TOBN(0xd81fe5b2, 0xbfba796e), TOBN(0x152364db, 0x6d71f116),
-+     TOBN(0xbb8c7c59, 0xb5b66e53), TOBN(0x0b12c61b, 0x2641a192),
-+     TOBN(0x31f14802, 0xfcf0a7fd), TOBN(0x42fd0789, 0x5488b01e),
-+     TOBN(0x71d78d6d, 0x9952b498), TOBN(0x8eb572d9, 0x07ac5201),
-+     TOBN(0xe0a2a44c, 0x4d194a88), TOBN(0xd2b63fd9, 0xba017e66),
-+     TOBN(0x78efc6c8, 0xf888aefc), TOBN(0xb76f6bda, 0x4a881a11),
-+     TOBN(0x187f314b, 0xb46c2397), TOBN(0x004cf566, 0x5ded2819),
-+     TOBN(0xa9ea5704, 0x38764d34), TOBN(0xbba45217, 0x78084709),
-+     TOBN(0x06474571, 0x1171121e), TOBN(0xad7b7eb1, 0xe7c9b671),
-+     TOBN(0xdacfbc40, 0x730f7507), TOBN(0x178cd8c6, 0xc7ad7bd1),
-+     TOBN(0xbf0be101, 0xb2a67238), TOBN(0x3556d367, 0xaf9c14f2),
-+     TOBN(0x104b7831, 0xa5662075), TOBN(0x58ca59bb, 0x79d9e60a),
-+     TOBN(0x4bc45392, 0xa569a73b), TOBN(0x517a52e8, 0x5698f6c9),
-+     TOBN(0x85643da5, 0xaeadd755), TOBN(0x1aed0cd5, 0x2a581b84),
-+     TOBN(0xb9b4ff84, 0x80af1372), TOBN(0x244c3113, 0xf1ba5d1f),
-+     TOBN(0x2a5dacbe, 0xf5f98d31), TOBN(0x2c3323e8, 0x4375bc2a),
-+     TOBN(0x17a3ab4a, 0x5594b1dd), TOBN(0xa1928bfb, 0xceb4797e),
-+     TOBN(0xe83af245, 0xe4886a19), TOBN(0x8979d546, 0x72b5a74a),
-+     TOBN(0xa0f726bc, 0x19f9e967), TOBN(0xd9d03152, 0xe8fbbf4e),
-+     TOBN(0xcfd6f51d, 0xb7707d40), TOBN(0x633084d9, 0x63f6e6e0),
-+     TOBN(0xedcd9cdc, 0x55667eaf), TOBN(0x73b7f92b, 0x2e44d56f),
-+     TOBN(0xfb2e39b6, 0x4e962b14), TOBN(0x7d408f6e, 0xf671fcbf),
-+     TOBN(0xcc634ddc, 0x164a89bb), TOBN(0x74a42bb2, 0x3ef3bd05),
-+     TOBN(0x1280dbb2, 0x428decbb), TOBN(0x6103f6bb, 0x402c8596),
-+     TOBN(0xfa2bf581, 0x355a5752), TOBN(0x562f96a8, 0x00946674),
-+     TOBN(0x4e4ca16d, 0x6da0223b), TOBN(0xfe47819f, 0x28d3aa25),
-+     TOBN(0x9eea3075, 0xf8dfcf8a), TOBN(0xa284f0aa, 0x95669825),
-+     TOBN(0xb3fca250, 0x867d3fd8), TOBN(0x20757b5f, 0x269d691e),
-+     TOBN(0xf2c24020, 0x93b8a5de), TOBN(0xd3f93359, 0xebc06da6),
-+     TOBN(0x1178293e, 0xb2739c33), TOBN(0xd2a3e770, 0xbcd686e5),
-+     TOBN(0xa76f49f4, 0xcd941534), TOBN(0x0d37406b, 0xe3c71c0e),
-+     TOBN(0x172d9397, 0x3b97f7e3), TOBN(0xec17e239, 0xbd7fd0de),
-+     TOBN(0xe3290551, 0x6f496ba2), TOBN(0x6a693172, 0x36ad50e7),
-+     TOBN(0xc4e539a2, 0x83e7eff5), TOBN(0x752737e7, 0x18e1b4cf),
-+     TOBN(0xa2f7932c, 0x68af43ee), TOBN(0x5502468e, 0x703d00bd),
-+     TOBN(0xe5dc978f, 0x2fb061f5), TOBN(0xc9a1904a, 0x28c815ad),
-+     TOBN(0xd3af538d, 0x470c56a4), TOBN(0x159abc5f, 0x193d8ced),
-+     TOBN(0x2a37245f, 0x20108ef3), TOBN(0xfa17081e, 0x223f7178),
-+     TOBN(0x27b0fb2b, 0x10c8c0f5), TOBN(0x2102c3ea, 0x40650547),
-+     TOBN(0x594564df, 0x8ac3bfa7), TOBN(0x98102033, 0x509dad96),
-+     TOBN(0x6989643f, 0xf1d18a13), TOBN(0x35eebd91, 0xd7fc5af0),
-+     TOBN(0x078d096a, 0xfaeaafd8), TOBN(0xb7a89341, 0xdef3de98),
-+     TOBN(0x2a206e8d, 0xecf2a73a), TOBN(0x066a6397, 0x8e551994),
-+     TOBN(0x3a6a088a, 0xb98d53a2), TOBN(0x0ce7c67c, 0x2d1124aa),
-+     TOBN(0x48cec671, 0x759a113c), TOBN(0xe3b373d3, 0x4f6f67fa),
-+     TOBN(0x5455d479, 0xfd36727b), TOBN(0xe5a428ee, 0xa13c0d81),
-+     TOBN(0xb853dbc8, 0x1c86682b), TOBN(0xb78d2727, 0xb8d02b2a),
-+     TOBN(0xaaf69bed, 0x8ebc329a), TOBN(0xdb6b40b3, 0x293b2148),
-+     TOBN(0xe42ea77d, 0xb8c4961f), TOBN(0xb1a12f7c, 0x20e5e0ab),
-+     TOBN(0xa0ec5274, 0x79e8b05e), TOBN(0x68027391, 0xfab60a80),
-+     TOBN(0x6bfeea5f, 0x16b1bd5e), TOBN(0xf957e420, 0x4de30ad3),
-+     TOBN(0xcbaf664e, 0x6a353b9e), TOBN(0x5c873312, 0x26d14feb),
-+     TOBN(0x4e87f98c, 0xb65f57cb), TOBN(0xdb60a621, 0x5e0cdd41),
-+     TOBN(0x67c16865, 0xa6881440), TOBN(0x1093ef1a, 0x46ab52aa),
-+     TOBN(0xc095afb5, 0x3f4ece64), TOBN(0x6a6bb02e, 0x7604551a),
-+     TOBN(0x55d44b4e, 0x0b26b8cd), TOBN(0xe5f9a999, 0xf971268a),
-+     TOBN(0xc08ec425, 0x11a7de84), TOBN(0x83568095, 0xfda469dd),
-+     TOBN(0x737bfba1, 0x6c6c90a2), TOBN(0x1cb9c4a0, 0xbe229831),
-+     TOBN(0x93bccbba, 0xbb2eec64), TOBN(0xa0c23b64, 0xda03adbe),
-+     TOBN(0x5f7aa00a, 0xe0e86ac4), TOBN(0x470b941e, 0xfc1401e6),
-+     TOBN(0x5ad8d679, 0x9df43574), TOBN(0x4ccfb8a9, 0x0f65d810),
-+     TOBN(0x1bce80e3, 0xaa7fbd81), TOBN(0x273291ad, 0x9508d20a),
-+     TOBN(0xf5c4b46b, 0x42a92806), TOBN(0x810684ec, 0xa86ab44a),
-+     TOBN(0x4591640b, 0xca0bc9f8), TOBN(0xb5efcdfc, 0x5c4b6054),
-+     TOBN(0x16fc8907, 0x6e9edd12), TOBN(0xe29d0b50, 0xd4d792f9),
-+     TOBN(0xa45fd01c, 0x9b03116d), TOBN(0x85035235, 0xc81765a4),
-+     TOBN(0x1fe2a9b2, 0xb4b4b67c), TOBN(0xc1d10df0, 0xe8020604),
-+     TOBN(0x9d64abfc, 0xbc8058d8), TOBN(0x8943b9b2, 0x712a0fbb),
-+     TOBN(0x90eed914, 0x3b3def04), TOBN(0x85ab3aa2, 0x4ce775ff),
-+     TOBN(0x605fd4ca, 0x7bbc9040), TOBN(0x8b34a564, 0xe2c75dfb),
-+     TOBN(0x41ffc94a, 0x10358560), TOBN(0x2d8a5072, 0x9e5c28aa),
-+     TOBN(0xe915a0fc, 0x4cc7eb15), TOBN(0xe9efab05, 0x8f6d0f5d),
-+     TOBN(0xdbab47a9, 0xd19e9b91), TOBN(0x8cfed745, 0x0276154c),
-+     TOBN(0x154357ae, 0x2cfede0d), TOBN(0x520630df, 0x19f5a4ef),
-+     TOBN(0x25759f7c, 0xe382360f), TOBN(0xb6db05c9, 0x88bf5857),
-+     TOBN(0x2917d61d, 0x6c58d46c), TOBN(0x14f8e491, 0xfd20cb7a),
-+     TOBN(0xb68a727a, 0x11c20340), TOBN(0x0386f86f, 0xaf7ccbb6),
-+     TOBN(0x5c8bc6cc, 0xfee09a20), TOBN(0x7d76ff4a, 0xbb7eea35),
-+     TOBN(0xa7bdebe7, 0xdb15be7a), TOBN(0x67a08054, 0xd89f0302),
-+     TOBN(0x56bf0ea9, 0xc1193364), TOBN(0xc8244467, 0x62837ebe),
-+     TOBN(0x32bd8e8b, 0x20d841b8), TOBN(0x127a0548, 0xdbb8a54f),
-+     TOBN(0x83dd4ca6, 0x63b20236), TOBN(0x87714718, 0x203491fa),
-+     TOBN(0x4dabcaaa, 0xaa8a5288), TOBN(0x91cc0c8a, 0xaf23a1c9),
-+     TOBN(0x34c72c6a, 0x3f220e0c), TOBN(0xbcc20bdf, 0x1232144a),
-+     TOBN(0x6e2f42da, 0xa20ede1b), TOBN(0xc441f00c, 0x74a00515),
-+     TOBN(0xbf46a5b6, 0x734b8c4b), TOBN(0x57409503, 0x7b56c9a4),
-+     TOBN(0x9f735261, 0xe4585d45), TOBN(0x9231faed, 0x6734e642),
-+     TOBN(0x1158a176, 0xbe70ee6c), TOBN(0x35f1068d, 0x7c3501bf),
-+     TOBN(0x6beef900, 0xa2d26115), TOBN(0x649406f2, 0xef0afee3),
-+     TOBN(0x3f43a60a, 0xbc2420a1), TOBN(0x509002a7, 0xd5aee4ac),
-+     TOBN(0xb46836a5, 0x3ff3571b), TOBN(0x24f98b78, 0x837927c1),
-+     TOBN(0x6254256a, 0x4533c716), TOBN(0xf27abb0b, 0xd07ee196),
-+     TOBN(0xd7cf64fc, 0x5c6d5bfd), TOBN(0x6915c751, 0xf0cd7a77),
-+     TOBN(0xd9f59012, 0x8798f534), TOBN(0x772b0da8, 0xf81d8b5f),
-+     TOBN(0x1244260c, 0x2e03fa69), TOBN(0x36cf0e3a, 0x3be1a374),
-+     TOBN(0x6e7c1633, 0xef06b960), TOBN(0xa71a4c55, 0x671f90f6),
-+     TOBN(0x7a941251, 0x33c673db), TOBN(0xc0bea510, 0x73e8c131),
-+     TOBN(0x61a8a699, 0xd4f6c734), TOBN(0x25e78c88, 0x341ed001),
-+     TOBN(0x5c18acf8, 0x8e2f7d90), TOBN(0xfdbf33d7, 0x77be32cd),
-+     TOBN(0x0a085cd7, 0xd2eb5ee9), TOBN(0x2d702cfb, 0xb3201115),
-+     TOBN(0xb6e0ebdb, 0x85c88ce8), TOBN(0x23a3ce3c, 0x1e01d617),
-+     TOBN(0x3041618e, 0x567333ac), TOBN(0x9dd0fd8f, 0x157edb6b),
-+     TOBN(0x27f74702, 0xb57872b8), TOBN(0x2ef26b4f, 0x657d5fe1),
-+     TOBN(0x95426f0a, 0x57cf3d40), TOBN(0x847e2ad1, 0x65a6067a),
-+     TOBN(0xd474d9a0, 0x09996a74), TOBN(0x16a56acd, 0x2a26115c),
-+     TOBN(0x02a615c3, 0xd16f4d43), TOBN(0xcc3fc965, 0xaadb85b7),
-+     TOBN(0x386bda73, 0xce07d1b0), TOBN(0xd82910c2, 0x58ad4178),
-+     TOBN(0x124f82cf, 0xcd2617f4), TOBN(0xcc2f5e8d, 0xef691770),
-+     TOBN(0x82702550, 0xb8c30ccc), TOBN(0x7b856aea, 0x1a8e575a),
-+     TOBN(0xbb822fef, 0xb1ab9459), TOBN(0x085928bc, 0xec24e38e),
-+     TOBN(0x5d0402ec, 0xba8f4b4d), TOBN(0xc07cd4ba, 0x00b4d58b),
-+     TOBN(0x5d8dffd5, 0x29227e7a), TOBN(0x61d44d0c, 0x31bf386f),
-+     TOBN(0xe486dc2b, 0x135e6f4d), TOBN(0x680962eb, 0xe79410ef),
-+     TOBN(0xa61bd343, 0xf10088b5), TOBN(0x6aa76076, 0xe2e28686),
-+     TOBN(0x80463d11, 0x8fb98871), TOBN(0xcb26f5c3, 0xbbc76aff),
-+     TOBN(0xd4ab8edd, 0xfbe03614), TOBN(0xc8eb579b, 0xc0cf2dee),
-+     TOBN(0xcc004c15, 0xc93bae41), TOBN(0x46fbae5d, 0x3aeca3b2),
-+     TOBN(0x671235cf, 0x0f1e9ab1), TOBN(0xadfba934, 0x9ec285c1),
-+     TOBN(0x88ded013, 0xf216c980), TOBN(0xc8ac4fb8, 0xf79e0bc1),
-+     TOBN(0xa29b89c6, 0xfb97a237), TOBN(0xb697b780, 0x9922d8e7),
-+     TOBN(0x3142c639, 0xddb945b5), TOBN(0x447b06c7, 0xe094c3a9),
-+     TOBN(0xcdcb3642, 0x72266c90), TOBN(0x633aad08, 0xa9385046),
-+     TOBN(0xa36c936b, 0xb57c6477), TOBN(0x871f8b64, 0xe94dbcc6),
-+     TOBN(0x28d0fb62, 0xa591a67b), TOBN(0x9d40e081, 0xc1d926f5),
-+     TOBN(0x3111eaf6, 0xf2d84b5a), TOBN(0x228993f9, 0xa565b644),
-+     TOBN(0x0ccbf592, 0x2c83188b), TOBN(0xf87b30ab, 0x3df3e197),
-+     TOBN(0xb8658b31, 0x7642bca8), TOBN(0x1a032d7f, 0x52800f17),
-+     TOBN(0x051dcae5, 0x79bf9445), TOBN(0xeba6b8ee, 0x54a2e253),
-+     TOBN(0x5c8b9cad, 0xd4485692), TOBN(0x84bda40e, 0x8986e9be),
-+     TOBN(0xd16d16a4, 0x2f0db448), TOBN(0x8ec80050, 0xa14d4188),
-+     TOBN(0xb2b26107, 0x98fa7aaa), TOBN(0x41209ee4, 0xf073aa4e),
-+     TOBN(0xf1570359, 0xf2d6b19b), TOBN(0xcbe6868c, 0xfc577caf),
-+     TOBN(0x186c4bdc, 0x32c04dd3), TOBN(0xa6c35fae, 0xcfeee397),
-+     TOBN(0xb4a1b312, 0xf086c0cf), TOBN(0xe0a5ccc6, 0xd9461fe2),
-+     TOBN(0xc32278aa, 0x1536189f), TOBN(0x1126c55f, 0xba6df571),
-+     TOBN(0x0f71a602, 0xb194560e), TOBN(0x8b2d7405, 0x324bd6e1),
-+     TOBN(0x8481939e, 0x3738be71), TOBN(0xb5090b1a, 0x1a4d97a9),
-+     TOBN(0x116c65a3, 0xf05ba915), TOBN(0x21863ad3, 0xaae448aa),
-+     TOBN(0xd24e2679, 0xa7aae5d3), TOBN(0x7076013d, 0x0de5c1c4),
-+     TOBN(0x2d50f8ba, 0xbb05b629), TOBN(0x73c1abe2, 0x6e66efbb),
-+     TOBN(0xefd4b422, 0xf2488af7), TOBN(0xe4105d02, 0x663ba575),
-+     TOBN(0x7eb60a8b, 0x53a69457), TOBN(0x62210008, 0xc945973b),
-+     TOBN(0xfb255478, 0x77a50ec6), TOBN(0xbf0392f7, 0x0a37a72c),
-+     TOBN(0xa0a7a19c, 0x4be18e7a), TOBN(0x90d8ea16, 0x25b1e0af),
-+     TOBN(0x7582a293, 0xef953f57), TOBN(0x90a64d05, 0xbdc5465a),
-+     TOBN(0xca79c497, 0xe2510717), TOBN(0x560dbb7c, 0x18cb641f),
-+     TOBN(0x1d8e3286, 0x4b66abfb), TOBN(0xd26f52e5, 0x59030900),
-+     TOBN(0x1ee3f643, 0x5584941a), TOBN(0x6d3b3730, 0x569f5958),
-+     TOBN(0x9ff2a62f, 0x4789dba5), TOBN(0x91fcb815, 0x72b5c9b7),
-+     TOBN(0xf446cb7d, 0x6c8f9a0e), TOBN(0x48f625c1, 0x39b7ecb5),
-+     TOBN(0xbabae801, 0x1c6219b8), TOBN(0xe7a562d9, 0x28ac2f23),
-+     TOBN(0xe1b48732, 0x26e20588), TOBN(0x06ee1cad, 0x775af051),
-+     TOBN(0xda29ae43, 0xfaff79f7), TOBN(0xc141a412, 0x652ee9e0),
-+     TOBN(0x1e127f6f, 0x195f4bd0), TOBN(0x29c6ab4f, 0x072f34f8),
-+     TOBN(0x7b7c1477, 0x30448112), TOBN(0x82b51af1, 0xe4a38656),
-+     TOBN(0x2bf2028a, 0x2f315010), TOBN(0xc9a4a01f, 0x6ea88cd4),
-+     TOBN(0xf63e95d8, 0x257e5818), TOBN(0xdd8efa10, 0xb4519b16),
-+     TOBN(0xed8973e0, 0x0da910bf), TOBN(0xed49d077, 0x5c0fe4a9),
-+     TOBN(0xac3aac5e, 0xb7caee1e), TOBN(0x1033898d, 0xa7f4da57),
-+     TOBN(0x42145c0e, 0x5c6669b9), TOBN(0x42daa688, 0xc1aa2aa0),
-+     TOBN(0x629cc15c, 0x1a1d885a), TOBN(0x25572ec0, 0xf4b76817),
-+     TOBN(0x8312e435, 0x9c8f8f28), TOBN(0x8107f8cd, 0x81965490),
-+     TOBN(0x516ff3a3, 0x6fa6110c), TOBN(0x74fb1eb1, 0xfb93561f),
-+     TOBN(0x6c0c9047, 0x8457522b), TOBN(0xcfd32104, 0x6bb8bdc6),
-+     TOBN(0x2d6884a2, 0xcc80ad57), TOBN(0x7c27fc35, 0x86a9b637),
-+     TOBN(0x3461baed, 0xadf4e8cd), TOBN(0x1d56251a, 0x617242f0),
-+     TOBN(0x0b80d209, 0xc955bef4), TOBN(0xdf02cad2, 0x06adb047),
-+     TOBN(0xf0d7cb91, 0x5ec74fee), TOBN(0xd2503375, 0x1111ba44),
-+     TOBN(0x9671755e, 0xdf53cb36), TOBN(0x54dcb612, 0x3368551b),
-+     TOBN(0x66d69aac, 0xc8a025a4), TOBN(0x6be946c6, 0xe77ef445),
-+     TOBN(0x719946d1, 0xa995e094), TOBN(0x65e848f6, 0xe51e04d8),
-+     TOBN(0xe62f3300, 0x6a1e3113), TOBN(0x1541c7c1, 0x501de503),
-+     TOBN(0x4daac9fa, 0xf4acfade), TOBN(0x0e585897, 0x44cd0b71),
-+     TOBN(0x544fd869, 0x0a51cd77), TOBN(0x60fc20ed, 0x0031016d),
-+     TOBN(0x58b404ec, 0xa4276867), TOBN(0x46f6c3cc, 0x34f34993),
-+     TOBN(0x477ca007, 0xc636e5bd), TOBN(0x8018f5e5, 0x7c458b47),
-+     TOBN(0xa1202270, 0xe47b668f), TOBN(0xcef48ccd, 0xee14f203),
-+     TOBN(0x23f98bae, 0x62ff9b4d), TOBN(0x55acc035, 0xc589eddd),
-+     TOBN(0x3fe712af, 0x64db4444), TOBN(0x19e9d634, 0xbecdd480),
-+     TOBN(0xe08bc047, 0xa930978a), TOBN(0x2dbf24ec, 0xa1280733),
-+     TOBN(0x3c0ae38c, 0x2cd706b2), TOBN(0x5b012a5b, 0x359017b9),
-+     TOBN(0x3943c38c, 0x72e0f5ae), TOBN(0x786167ea, 0x57176fa3),
-+     TOBN(0xe5f9897d, 0x594881dc), TOBN(0x6b5efad8, 0xcfb820c1),
-+     TOBN(0xb2179093, 0xd55018de), TOBN(0x39ad7d32, 0x0bac56ce),
-+     TOBN(0xb55122e0, 0x2cfc0e81), TOBN(0x117c4661, 0xf6d89daa),
-+     TOBN(0x362d01e1, 0xcb64fa09), TOBN(0x6a309b4e, 0x3e9c4ddd),
-+     TOBN(0xfa979fb7, 0xabea49b1), TOBN(0xb4b1d27d, 0x10e2c6c5),
-+     TOBN(0xbd61c2c4, 0x23afde7a), TOBN(0xeb6614f8, 0x9786d358),
-+     TOBN(0x4a5d816b, 0x7f6f7459), TOBN(0xe431a44f, 0x09360e7b),
-+     TOBN(0x8c27a032, 0xc309914c), TOBN(0xcea5d68a, 0xcaede3d8),
-+     TOBN(0x3668f665, 0x3a0a3f95), TOBN(0x89369416, 0x7ceba27b),
-+     TOBN(0x89981fad, 0xe4728fe9), TOBN(0x7102c8a0, 0x8a093562),
-+     TOBN(0xbb80310e, 0x235d21c8), TOBN(0x505e55d1, 0xbefb7f7b),
-+     TOBN(0xa0a90811, 0x12958a67), TOBN(0xd67e106a, 0x4d851fef),
-+     TOBN(0xb84011a9, 0x431dd80e), TOBN(0xeb7c7cca, 0x73306cd9),
-+     TOBN(0x20fadd29, 0xd1b3b730), TOBN(0x83858b5b, 0xfe37b3d3),
-+     TOBN(0xbf4cd193, 0xb6251d5c), TOBN(0x1cca1fd3, 0x1352d952),
-+     TOBN(0xc66157a4, 0x90fbc051), TOBN(0x7990a638, 0x89b98636),}
-+    ,
-+    {TOBN(0xe5aa692a, 0x87dec0e1), TOBN(0x010ded8d, 0xf7b39d00),
-+     TOBN(0x7b1b80c8, 0x54cfa0b5), TOBN(0x66beb876, 0xa0f8ea28),
-+     TOBN(0x50d7f531, 0x3476cd0e), TOBN(0xa63d0e65, 0xb08d3949),
-+     TOBN(0x1a09eea9, 0x53479fc6), TOBN(0x82ae9891, 0xf499e742),
-+     TOBN(0xab58b910, 0x5ca7d866), TOBN(0x582967e2, 0x3adb3b34),
-+     TOBN(0x89ae4447, 0xcceac0bc), TOBN(0x919c667c, 0x7bf56af5),
-+     TOBN(0x9aec17b1, 0x60f5dcd7), TOBN(0xec697b9f, 0xddcaadbc),
-+     TOBN(0x0b98f341, 0x463467f5), TOBN(0xb187f1f7, 0xa967132f),
-+     TOBN(0x90fe7a1d, 0x214aeb18), TOBN(0x1506af3c, 0x741432f7),
-+     TOBN(0xbb5565f9, 0xe591a0c4), TOBN(0x10d41a77, 0xb44f1bc3),
-+     TOBN(0xa09d65e4, 0xa84bde96), TOBN(0x42f060d8, 0xf20a6a1c),
-+     TOBN(0x652a3bfd, 0xf27f9ce7), TOBN(0xb6bdb65c, 0x3b3d739f),
-+     TOBN(0xeb5ddcb6, 0xec7fae9f), TOBN(0x995f2714, 0xefb66e5a),
-+     TOBN(0xdee95d8e, 0x69445d52), TOBN(0x1b6c2d46, 0x09e27620),
-+     TOBN(0x32621c31, 0x8129d716), TOBN(0xb03909f1, 0x0958c1aa),
-+     TOBN(0x8c468ef9, 0x1af4af63), TOBN(0x162c429f, 0xfba5cdf6),
-+     TOBN(0x2f682343, 0x753b9371), TOBN(0x29cab45a, 0x5f1f9cd7),
-+     TOBN(0x571623ab, 0xb245db96), TOBN(0xc507db09, 0x3fd79999),
-+     TOBN(0x4e2ef652, 0xaf036c32), TOBN(0x86f0cc78, 0x05018e5c),
-+     TOBN(0xc10a73d4, 0xab8be350), TOBN(0x6519b397, 0x7e826327),
-+     TOBN(0xe8cb5eef, 0x9c053df7), TOBN(0x8de25b37, 0xb300ea6f),
-+     TOBN(0xdb03fa92, 0xc849cffb), TOBN(0x242e43a7, 0xe84169bb),
-+     TOBN(0xe4fa51f4, 0xdd6f958e), TOBN(0x6925a77f, 0xf4445a8d),
-+     TOBN(0xe6e72a50, 0xe90d8949), TOBN(0xc66648e3, 0x2b1f6390),
-+     TOBN(0xb2ab1957, 0x173e460c), TOBN(0x1bbbce75, 0x30704590),
-+     TOBN(0xc0a90dbd, 0xdb1c7162), TOBN(0x505e399e, 0x15cdd65d),
-+     TOBN(0x68434dcb, 0x57797ab7), TOBN(0x60ad35ba, 0x6a2ca8e8),
-+     TOBN(0x4bfdb1e0, 0xde3336c1), TOBN(0xbbef99eb, 0xd8b39015),
-+     TOBN(0x6c3b96f3, 0x1711ebec), TOBN(0x2da40f1f, 0xce98fdc4),
-+     TOBN(0xb99774d3, 0x57b4411f), TOBN(0x87c8bdf4, 0x15b65bb6),
-+     TOBN(0xda3a89e3, 0xc2eef12d), TOBN(0xde95bb9b, 0x3c7471f3),
-+     TOBN(0x600f225b, 0xd812c594), TOBN(0x54907c5d, 0x2b75a56b),
-+     TOBN(0xa93cc5f0, 0x8db60e35), TOBN(0x743e3cd6, 0xfa833319),
-+     TOBN(0x7dad5c41, 0xf81683c9), TOBN(0x70c1e7d9, 0x9c34107e),
-+     TOBN(0x0edc4a39, 0xa6be0907), TOBN(0x36d47035, 0x86d0b7d3),
-+     TOBN(0x8c76da03, 0x272bfa60), TOBN(0x0b4a07ea, 0x0f08a414),
-+     TOBN(0x699e4d29, 0x45c1dd53), TOBN(0xcadc5898, 0x231debb5),
-+     TOBN(0xdf49fcc7, 0xa77f00e0), TOBN(0x93057bbf, 0xa73e5a0e),
-+     TOBN(0x2f8b7ecd, 0x027a4cd1), TOBN(0x114734b3, 0xc614011a),
-+     TOBN(0xe7a01db7, 0x67677c68), TOBN(0x89d9be5e, 0x7e273f4f),
-+     TOBN(0xd225cb2e, 0x089808ef), TOBN(0xf1f7a27d, 0xd59e4107),
-+     TOBN(0x53afc761, 0x8211b9c9), TOBN(0x0361bc67, 0xe6819159),
-+     TOBN(0x2a865d0b, 0x7f071426), TOBN(0x6a3c1810, 0xe7072567),
-+     TOBN(0x3e3bca1e, 0x0d6bcabd), TOBN(0xa1b02bc1, 0x408591bc),
-+     TOBN(0xe0deee59, 0x31fba239), TOBN(0xf47424d3, 0x98bd91d1),
-+     TOBN(0x0f8886f4, 0x071a3c1d), TOBN(0x3f7d41e8, 0xa819233b),
-+     TOBN(0x708623c2, 0xcf6eb998), TOBN(0x86bb49af, 0x609a287f),
-+     TOBN(0x942bb249, 0x63c90762), TOBN(0x0ef6eea5, 0x55a9654b),
-+     TOBN(0x5f6d2d72, 0x36f5defe), TOBN(0xfa9922dc, 0x56f99176),
-+     TOBN(0x6c8c5ece, 0xf78ce0c7), TOBN(0x7b44589d, 0xbe09b55e),
-+     TOBN(0xe11b3bca, 0x9ea83770), TOBN(0xd7fa2c7f, 0x2ab71547),
-+     TOBN(0x2a3dd6fa, 0x2a1ddcc0), TOBN(0x09acb430, 0x5a7b7707),
-+     TOBN(0x4add4a2e, 0x649d4e57), TOBN(0xcd53a2b0, 0x1917526e),
-+     TOBN(0xc5262330, 0x20b44ac4), TOBN(0x4028746a, 0xbaa2c31d),
-+     TOBN(0x51318390, 0x64291d4c), TOBN(0xbf48f151, 0xee5ad909),
-+     TOBN(0xcce57f59, 0x7b185681), TOBN(0x7c3ac1b0, 0x4854d442),
-+     TOBN(0x65587dc3, 0xc093c171), TOBN(0xae7acb24, 0x24f42b65),
-+     TOBN(0x5a338adb, 0x955996cb), TOBN(0xc8e65675, 0x6051f91b),
-+     TOBN(0x66711fba, 0x28b8d0b1), TOBN(0x15d74137, 0xb6c10a90),
-+     TOBN(0x70cdd7eb, 0x3a232a80), TOBN(0xc9e2f07f, 0x6191ed24),
-+     TOBN(0xa80d1db6, 0xf79588c0), TOBN(0xfa52fc69, 0xb55768cc),
-+     TOBN(0x0b4df1ae, 0x7f54438a), TOBN(0x0cadd1a7, 0xf9b46a4f),
-+     TOBN(0xb40ea6b3, 0x1803dd6f), TOBN(0x488e4fa5, 0x55eaae35),
-+     TOBN(0x9f047d55, 0x382e4e16), TOBN(0xc9b5b7e0, 0x2f6e0c98),
-+     TOBN(0x6b1bd2d3, 0x95762649), TOBN(0xa9604ee7, 0xc7aea3f6),
-+     TOBN(0x3646ff27, 0x6dc6f896), TOBN(0x9bf0e7f5, 0x2860bad1),
-+     TOBN(0x2d92c821, 0x7cb44b92), TOBN(0xa2f5ce63, 0xaea9c182),
-+     TOBN(0xd0a2afb1, 0x9154a5fd), TOBN(0x482e474c, 0x95801da6),
-+     TOBN(0xc19972d0, 0xb611c24b), TOBN(0x1d468e65, 0x60a8f351),
-+     TOBN(0xeb758069, 0x7bcf6421), TOBN(0xec9dd0ee, 0x88fbc491),
-+     TOBN(0x5b59d2bf, 0x956c2e32), TOBN(0x73dc6864, 0xdcddf94e),
-+     TOBN(0xfd5e2321, 0xbcee7665), TOBN(0xa7b4f8ef, 0x5e9a06c4),
-+     TOBN(0xfba918dd, 0x7280f855), TOBN(0xbbaac260, 0x8baec688),
-+     TOBN(0xa3b3f00f, 0x33400f42), TOBN(0x3d2dba29, 0x66f2e6e4),
-+     TOBN(0xb6f71a94, 0x98509375), TOBN(0x8f33031f, 0xcea423cc),
-+     TOBN(0x009b8dd0, 0x4807e6fb), TOBN(0x5163cfe5, 0x5cdb954c),
-+     TOBN(0x03cc8f17, 0xcf41c6e8), TOBN(0xf1f03c2a, 0x037b925c),
-+     TOBN(0xc39c19cc, 0x66d2427c), TOBN(0x823d24ba, 0x7b6c18e4),
-+     TOBN(0x32ef9013, 0x901f0b4f), TOBN(0x684360f1, 0xf8941c2e),
-+     TOBN(0x0ebaff52, 0x2c28092e), TOBN(0x7891e4e3, 0x256c932f),
-+     TOBN(0x51264319, 0xac445e3d), TOBN(0x553432e7, 0x8ea74381),
-+     TOBN(0xe6eeaa69, 0x67e9c50a), TOBN(0x27ced284, 0x62e628c7),
-+     TOBN(0x3f96d375, 0x7a4afa57), TOBN(0xde0a14c3, 0xe484c150),
-+     TOBN(0x364a24eb, 0x38bd9923), TOBN(0x1df18da0, 0xe5177422),
-+     TOBN(0x174e8f82, 0xd8d38a9b), TOBN(0x2e97c600, 0xe7de1391),
-+     TOBN(0xc5709850, 0xa1c175dd), TOBN(0x969041a0, 0x32ae5035),
-+     TOBN(0xcbfd533b, 0x76a2086b), TOBN(0xd6bba71b, 0xd7c2e8fe),
-+     TOBN(0xb2d58ee6, 0x099dfb67), TOBN(0x3a8b342d, 0x064a85d9),
-+     TOBN(0x3bc07649, 0x522f9be3), TOBN(0x690c075b, 0xdf1f49a8),
-+     TOBN(0x80e1aee8, 0x3854ec42), TOBN(0x2a7dbf44, 0x17689dc7),
-+     TOBN(0xc004fc0e, 0x3faf4078), TOBN(0xb2f02e9e, 0xdf11862c),
-+     TOBN(0xf10a5e0f, 0xa0a1b7b3), TOBN(0x30aca623, 0x8936ec80),
-+     TOBN(0xf83cbf05, 0x02f40d9a), TOBN(0x4681c468, 0x2c318a4d),
-+     TOBN(0x98575618, 0x0e9c2674), TOBN(0xbe79d046, 0x1847092e),
-+     TOBN(0xaf1e480a, 0x78bd01e0), TOBN(0x6dd359e4, 0x72a51db9),
-+     TOBN(0x62ce3821, 0xe3afbab6), TOBN(0xc5cee5b6, 0x17733199),
-+     TOBN(0xe08b30d4, 0x6ffd9fbb), TOBN(0x6e5bc699, 0x36c610b7),
-+     TOBN(0xf343cff2, 0x9ce262cf), TOBN(0xca2e4e35, 0x68b914c1),
-+     TOBN(0x011d64c0, 0x16de36c5), TOBN(0xe0b10fdd, 0x42e2b829),
-+     TOBN(0x78942981, 0x6685aaf8), TOBN(0xe7511708, 0x230ede97),
-+     TOBN(0x671ed8fc, 0x3b922bf8), TOBN(0xe4d8c0a0, 0x4c29b133),
-+     TOBN(0x87eb1239, 0x3b6e99c4), TOBN(0xaff3974c, 0x8793beba),
-+     TOBN(0x03749405, 0x2c18df9b), TOBN(0xc5c3a293, 0x91007139),
-+     TOBN(0x6a77234f, 0xe37a0b95), TOBN(0x02c29a21, 0xb661c96b),
-+     TOBN(0xc3aaf1d6, 0x141ecf61), TOBN(0x9195509e, 0x3bb22f53),
-+     TOBN(0x29597404, 0x22d51357), TOBN(0x1b083822, 0x537bed60),
-+     TOBN(0xcd7d6e35, 0xe07289f0), TOBN(0x1f94c48c, 0x6dd86eff),
-+     TOBN(0xc8bb1f82, 0xeb0f9cfa), TOBN(0x9ee0b7e6, 0x1b2eb97d),
-+     TOBN(0x5a52fe2e, 0x34d74e31), TOBN(0xa352c310, 0x3bf79ab6),
-+     TOBN(0x97ff6c5a, 0xabfeeb8f), TOBN(0xbfbe8fef, 0xf5c97305),
-+     TOBN(0xd6081ce6, 0xa7904608), TOBN(0x1f812f3a, 0xc4fca249),
-+     TOBN(0x9b24bc9a, 0xb9e5e200), TOBN(0x91022c67, 0x38012ee8),
-+     TOBN(0xe83d9c5d, 0x30a713a1), TOBN(0x4876e3f0, 0x84ef0f93),
-+     TOBN(0xc9777029, 0xc1fbf928), TOBN(0xef7a6bb3, 0xbce7d2a4),
-+     TOBN(0xb8067228, 0xdfa2a659), TOBN(0xd5cd3398, 0xd877a48f),
-+     TOBN(0xbea4fd8f, 0x025d0f3f), TOBN(0xd67d2e35, 0x2eae7c2b),
-+     TOBN(0x184de7d7, 0xcc5f4394), TOBN(0xb5551b5c, 0x4536e142),
-+     TOBN(0x2e89b212, 0xd34aa60a), TOBN(0x14a96fea, 0xf50051d5),
-+     TOBN(0x4e21ef74, 0x0d12bb0b), TOBN(0xc522f020, 0x60b9677e),
-+     TOBN(0x8b12e467, 0x2df7731d), TOBN(0x39f80382, 0x7b326d31),
-+     TOBN(0xdfb8630c, 0x39024a94), TOBN(0xaacb96a8, 0x97319452),
-+     TOBN(0xd68a3961, 0xeda3867c), TOBN(0x0c58e2b0, 0x77c4ffca),
-+     TOBN(0x3d545d63, 0x4da919fa), TOBN(0xef79b69a, 0xf15e2289),
-+     TOBN(0x54bc3d3d, 0x808bab10), TOBN(0xc8ab3007, 0x45f82c37),
-+     TOBN(0xc12738b6, 0x7c4a658a), TOBN(0xb3c47639, 0x40e72182),
-+     TOBN(0x3b77be46, 0x8798e44f), TOBN(0xdc047df2, 0x17a7f85f),
-+     TOBN(0x2439d4c5, 0x5e59d92d), TOBN(0xcedca475, 0xe8e64d8d),
-+     TOBN(0xa724cd0d, 0x87ca9b16), TOBN(0x35e4fd59, 0xa5540dfe),
-+     TOBN(0xf8c1ff18, 0xe4bcf6b1), TOBN(0x856d6285, 0x295018fa),
-+     TOBN(0x433f665c, 0x3263c949), TOBN(0xa6a76dd6, 0xa1f21409),
-+     TOBN(0x17d32334, 0xcc7b4f79), TOBN(0xa1d03122, 0x06720e4a),
-+     TOBN(0xadb6661d, 0x81d9bed5), TOBN(0xf0d6fb02, 0x11db15d1),
-+     TOBN(0x7fd11ad5, 0x1fb747d2), TOBN(0xab50f959, 0x3033762b),
-+     TOBN(0x2a7e711b, 0xfbefaf5a), TOBN(0xc7393278, 0x3fef2bbf),
-+     TOBN(0xe29fa244, 0x0df6f9be), TOBN(0x9092757b, 0x71efd215),
-+     TOBN(0xee60e311, 0x4f3d6fd9), TOBN(0x338542d4, 0x0acfb78b),
-+     TOBN(0x44a23f08, 0x38961a0f), TOBN(0x1426eade, 0x986987ca),
-+     TOBN(0x36e6ee2e, 0x4a863cc6), TOBN(0x48059420, 0x628b8b79),
-+     TOBN(0x30303ad8, 0x7396e1de), TOBN(0x5c8bdc48, 0x38c5aad1),
-+     TOBN(0x3e40e11f, 0x5c8f5066), TOBN(0xabd6e768, 0x8d246bbd),
-+     TOBN(0x68aa40bb, 0x23330a01), TOBN(0xd23f5ee4, 0xc34eafa0),
-+     TOBN(0x3bbee315, 0x5de02c21), TOBN(0x18dd4397, 0xd1d8dd06),
-+     TOBN(0x3ba1939a, 0x122d7b44), TOBN(0xe6d3b40a, 0xa33870d6),
-+     TOBN(0x8e620f70, 0x1c4fe3f8), TOBN(0xf6bba1a5, 0xd3a50cbf),
-+     TOBN(0x4a78bde5, 0xcfc0aee0), TOBN(0x847edc46, 0xc08c50bd),
-+     TOBN(0xbaa2439c, 0xad63c9b2), TOBN(0xceb4a728, 0x10fc2acb),
-+     TOBN(0xa419e40e, 0x26da033d), TOBN(0x6cc3889d, 0x03e02683),
-+     TOBN(0x1cd28559, 0xfdccf725), TOBN(0x0fd7e0f1, 0x8d13d208),
-+     TOBN(0x01b9733b, 0x1f0df9d4), TOBN(0x8cc2c5f3, 0xa2b5e4f3),
-+     TOBN(0x43053bfa, 0x3a304fd4), TOBN(0x8e87665c, 0x0a9f1aa7),
-+     TOBN(0x087f29ec, 0xd73dc965), TOBN(0x15ace455, 0x3e9023db),
-+     TOBN(0x2370e309, 0x2bce28b4), TOBN(0xf9723442, 0xb6b1e84a),
-+     TOBN(0xbeee662e, 0xb72d9f26), TOBN(0xb19396de, 0xf0e47109),
-+     TOBN(0x85b1fa73, 0xe13289d0), TOBN(0x436cf77e, 0x54e58e32),
-+     TOBN(0x0ec833b3, 0xe990ef77), TOBN(0x7373e3ed, 0x1b11fc25),
-+     TOBN(0xbe0eda87, 0x0fc332ce), TOBN(0xced04970, 0x8d7ea856),
-+     TOBN(0xf85ff785, 0x7e977ca0), TOBN(0xb66ee8da, 0xdfdd5d2b),
-+     TOBN(0xf5e37950, 0x905af461), TOBN(0x587b9090, 0x966d487c),
-+     TOBN(0x6a198a1b, 0x32ba0127), TOBN(0xa7720e07, 0x141615ac),
-+     TOBN(0xa23f3499, 0x996ef2f2), TOBN(0xef5f64b4, 0x470bcb3d),
-+     TOBN(0xa526a962, 0x92b8c559), TOBN(0x0c14aac0, 0x69740a0f),
-+     TOBN(0x0d41a9e3, 0xa6bdc0a5), TOBN(0x97d52106, 0x9c48aef4),
-+     TOBN(0xcf16bd30, 0x3e7c253b), TOBN(0xcc834b1a, 0x47fdedc1),
-+     TOBN(0x7362c6e5, 0x373aab2e), TOBN(0x264ed85e, 0xc5f590ff),
-+     TOBN(0x7a46d9c0, 0x66d41870), TOBN(0xa50c20b1, 0x4787ba09),
-+     TOBN(0x185e7e51, 0xe3d44635), TOBN(0xb3b3e080, 0x31e2d8dc),
-+     TOBN(0xbed1e558, 0xa179e9d9), TOBN(0x2daa3f79, 0x74a76781),
-+     TOBN(0x4372baf2, 0x3a40864f), TOBN(0x46900c54, 0x4fe75cb5),
-+     TOBN(0xb95f171e, 0xf76765d0), TOBN(0x4ad726d2, 0x95c87502),
-+     TOBN(0x2ec769da, 0x4d7c99bd), TOBN(0x5e2ddd19, 0xc36cdfa8),
-+     TOBN(0xc22117fc, 0xa93e6dea), TOBN(0xe8a2583b, 0x93771123),
-+     TOBN(0xbe2f6089, 0xfa08a3a2), TOBN(0x4809d5ed, 0x8f0e1112),
-+     TOBN(0x3b414aa3, 0xda7a095e), TOBN(0x9049acf1, 0x26f5aadd),
-+     TOBN(0x78d46a4d, 0x6be8b84a), TOBN(0xd66b1963, 0xb732b9b3),
-+     TOBN(0x5c2ac2a0, 0xde6e9555), TOBN(0xcf52d098, 0xb5bd8770),
-+     TOBN(0x15a15fa6, 0x0fd28921), TOBN(0x56ccb81e, 0x8b27536d),
-+     TOBN(0x0f0d8ab8, 0x9f4ccbb8), TOBN(0xed5f44d2, 0xdb221729),
-+     TOBN(0x43141988, 0x00bed10c), TOBN(0xc94348a4, 0x1d735b8b),
-+     TOBN(0x79f3e9c4, 0x29ef8479), TOBN(0x4c13a4e3, 0x614c693f),
-+     TOBN(0x32c9af56, 0x8e143a14), TOBN(0xbc517799, 0xe29ac5c4),
-+     TOBN(0x05e17992, 0x2774856f), TOBN(0x6e52fb05, 0x6c1bf55f),
-+     TOBN(0xaeda4225, 0xe4f19e16), TOBN(0x70f4728a, 0xaf5ccb26),
-+     TOBN(0x5d2118d1, 0xb2947f22), TOBN(0xc827ea16, 0x281d6fb9),
-+     TOBN(0x8412328d, 0x8cf0eabd), TOBN(0x45ee9fb2, 0x03ef9dcf),
-+     TOBN(0x8e700421, 0xbb937d63), TOBN(0xdf8ff2d5, 0xcc4b37a6),
-+     TOBN(0xa4c0d5b2, 0x5ced7b68), TOBN(0x6537c1ef, 0xc7308f59),
-+     TOBN(0x25ce6a26, 0x3b37f8e8), TOBN(0x170e9a9b, 0xdeebc6ce),
-+     TOBN(0xdd037952, 0x8728d72c), TOBN(0x445b0e55, 0x850154bc),
-+     TOBN(0x4b7d0e06, 0x83a7337b), TOBN(0x1e3416d4, 0xffecf249),
-+     TOBN(0x24840eff, 0x66a2b71f), TOBN(0xd0d9a50a, 0xb37cc26d),
-+     TOBN(0xe2198150, 0x6fe28ef7), TOBN(0x3cc5ef16, 0x23324c7f),
-+     TOBN(0x220f3455, 0x769b5263), TOBN(0xe2ade2f1, 0xa10bf475),
-+     TOBN(0x28cd20fa, 0x458d3671), TOBN(0x1549722c, 0x2dc4847b),
-+     TOBN(0x6dd01e55, 0x591941e3), TOBN(0x0e6fbcea, 0x27128ccb),
-+     TOBN(0xae1a1e6b, 0x3bef0262), TOBN(0xfa8c472c, 0x8f54e103),
-+     TOBN(0x7539c0a8, 0x72c052ec), TOBN(0xd7b27369, 0x5a3490e9),
-+     TOBN(0x143fe1f1, 0x71684349), TOBN(0x36b4722e, 0x32e19b97),
-+     TOBN(0xdc059227, 0x90980aff), TOBN(0x175c9c88, 0x9e13d674),
-+     TOBN(0xa7de5b22, 0x6e6bfdb1), TOBN(0x5ea5b7b2, 0xbedb4b46),
-+     TOBN(0xd5570191, 0xd34a6e44), TOBN(0xfcf60d2e, 0xa24ff7e6),
-+     TOBN(0x614a392d, 0x677819e1), TOBN(0x7be74c7e, 0xaa5a29e8),
-+     TOBN(0xab50fece, 0x63c85f3f), TOBN(0xaca2e2a9, 0x46cab337),
-+     TOBN(0x7f700388, 0x122a6fe3), TOBN(0xdb69f703, 0x882a04a8),
-+     TOBN(0x9a77935d, 0xcf7aed57), TOBN(0xdf16207c, 0x8d91c86f),
-+     TOBN(0x2fca49ab, 0x63ed9998), TOBN(0xa3125c44, 0xa77ddf96),
-+     TOBN(0x05dd8a86, 0x24344072), TOBN(0xa023dda2, 0xfec3fb56),
-+     TOBN(0x421b41fc, 0x0c743032), TOBN(0x4f2120c1, 0x5e438639),
-+     TOBN(0xfb7cae51, 0xc83c1b07), TOBN(0xb2370caa, 0xcac2171a),
-+     TOBN(0x2eb2d962, 0x6cc820fb), TOBN(0x59feee5c, 0xb85a44bf),
-+     TOBN(0x94620fca, 0x5b6598f0), TOBN(0x6b922cae, 0x7e314051),
-+     TOBN(0xff8745ad, 0x106bed4e), TOBN(0x546e71f5, 0xdfa1e9ab),
-+     TOBN(0x935c1e48, 0x1ec29487), TOBN(0x9509216c, 0x4d936530),
-+     TOBN(0xc7ca3067, 0x85c9a2db), TOBN(0xd6ae5152, 0x6be8606f),
-+     TOBN(0x09dbcae6, 0xe14c651d), TOBN(0xc9536e23, 0x9bc32f96),
-+     TOBN(0xa90535a9, 0x34521b03), TOBN(0xf39c526c, 0x878756ff),
-+     TOBN(0x383172ec, 0x8aedf03c), TOBN(0x20a8075e, 0xefe0c034),
-+     TOBN(0xf22f9c62, 0x64026422), TOBN(0x8dd10780, 0x24b9d076),
-+     TOBN(0x944c742a, 0x3bef2950), TOBN(0x55b9502e, 0x88a2b00b),
-+     TOBN(0xa59e14b4, 0x86a09817), TOBN(0xa39dd3ac, 0x47bb4071),
-+     TOBN(0x55137f66, 0x3be0592f), TOBN(0x07fcafd4, 0xc9e63f5b),
-+     TOBN(0x963652ee, 0x346eb226), TOBN(0x7dfab085, 0xec2facb7),
-+     TOBN(0x273bf2b8, 0x691add26), TOBN(0x30d74540, 0xf2b46c44),
-+     TOBN(0x05e8e73e, 0xf2c2d065), TOBN(0xff9b8a00, 0xd42eeac9),
-+     TOBN(0x2fcbd205, 0x97209d22), TOBN(0xeb740ffa, 0xde14ea2c),
-+     TOBN(0xc71ff913, 0xa8aef518), TOBN(0x7bfc74bb, 0xfff4cfa2),
-+     TOBN(0x1716680c, 0xb6b36048), TOBN(0x121b2cce, 0x9ef79af1),
-+     TOBN(0xbff3c836, 0xa01eb3d3), TOBN(0x50eb1c6a, 0x5f79077b),
-+     TOBN(0xa48c32d6, 0xa004bbcf), TOBN(0x47a59316, 0x7d64f61d),
-+     TOBN(0x6068147f, 0x93102016), TOBN(0x12c5f654, 0x94d12576),
-+     TOBN(0xefb071a7, 0xc9bc6b91), TOBN(0x7c2da0c5, 0x6e23ea95),
-+     TOBN(0xf4fd45b6, 0xd4a1dd5d), TOBN(0x3e7ad9b6, 0x9122b13c),
-+     TOBN(0x342ca118, 0xe6f57a48), TOBN(0x1c2e94a7, 0x06f8288f),
-+     TOBN(0x99e68f07, 0x5a97d231), TOBN(0x7c80de97, 0x4d838758),
-+     TOBN(0xbce0f5d0, 0x05872727), TOBN(0xbe5d95c2, 0x19c4d016),
-+     TOBN(0x921d5cb1, 0x9c2492ee), TOBN(0x42192dc1, 0x404d6fb3),
-+     TOBN(0x4c84dcd1, 0x32f988d3), TOBN(0xde26d61f, 0xa17b8e85),
-+     TOBN(0xc466dcb6, 0x137c7408), TOBN(0x9a38d7b6, 0x36a266da),
-+     TOBN(0x7ef5cb06, 0x83bebf1b), TOBN(0xe5cdcbbf, 0x0fd014e3),
-+     TOBN(0x30aa376d, 0xf65965a0), TOBN(0x60fe88c2, 0xebb3e95e),
-+     TOBN(0x33fd0b61, 0x66ee6f20), TOBN(0x8827dcdb, 0x3f41f0a0),
-+     TOBN(0xbf8a9d24, 0x0c56c690), TOBN(0x40265dad, 0xddb7641d),
-+     TOBN(0x522b05bf, 0x3a6b662b), TOBN(0x466d1dfe, 0xb1478c9b),
-+     TOBN(0xaa616962, 0x1484469b), TOBN(0x0db60549, 0x02df8f9f),
-+     TOBN(0xc37bca02, 0x3cb8bf51), TOBN(0x5effe346, 0x21371ce8),
-+     TOBN(0xe8f65264, 0xff112c32), TOBN(0x8a9c736d, 0x7b971fb2),
-+     TOBN(0xa4f19470, 0x7b75080d), TOBN(0xfc3f2c5a, 0x8839c59b),
-+     TOBN(0x1d6c777e, 0x5aeb49c2), TOBN(0xf3db034d, 0xda1addfe),
-+     TOBN(0xd76fee5a, 0x5535affc), TOBN(0x0853ac70, 0xb92251fd),
-+     TOBN(0x37e3d594, 0x8b2a29d5), TOBN(0x28f1f457, 0x4de00ddb),
-+     TOBN(0x8083c1b5, 0xf42c328b), TOBN(0xd8ef1d8f, 0xe493c73b),
-+     TOBN(0x96fb6260, 0x41dc61bd), TOBN(0xf74e8a9d, 0x27ee2f8a),
-+     TOBN(0x7c605a80, 0x2c946a5d), TOBN(0xeed48d65, 0x3839ccfd),
-+     TOBN(0x9894344f, 0x3a29467a), TOBN(0xde81e949, 0xc51eba6d),
-+     TOBN(0xdaea066b, 0xa5e5c2f2), TOBN(0x3fc8a614, 0x08c8c7b3),
-+     TOBN(0x7adff88f, 0x06d0de9f), TOBN(0xbbc11cf5, 0x3b75ce0a),
-+     TOBN(0x9fbb7acc, 0xfbbc87d5), TOBN(0xa1458e26, 0x7badfde2)}
-+    ,
-+    {TOBN(0x1cb43668, 0xe039c256), TOBN(0x5f26fb8b, 0x7c17fd5d),
-+     TOBN(0xeee426af, 0x79aa062b), TOBN(0x072002d0, 0xd78fbf04),
-+     TOBN(0x4c9ca237, 0xe84fb7e3), TOBN(0xb401d8a1, 0x0c82133d),
-+     TOBN(0xaaa52592, 0x6d7e4181), TOBN(0xe9430833, 0x73dbb152),
-+     TOBN(0xf92dda31, 0xbe24319a), TOBN(0x03f7d28b, 0xe095a8e7),
-+     TOBN(0xa52fe840, 0x98782185), TOBN(0x276ddafe, 0x29c24dbc),
-+     TOBN(0x80cd5496, 0x1d7a64eb), TOBN(0xe4360889, 0x7f1dbe42),
-+     TOBN(0x2f81a877, 0x8438d2d5), TOBN(0x7e4d52a8, 0x85169036),
-+     TOBN(0x19e3d5b1, 0x1d59715d), TOBN(0xc7eaa762, 0xd788983e),
-+     TOBN(0xe5a730b0, 0xabf1f248), TOBN(0xfbab8084, 0xfae3fd83),
-+     TOBN(0x65e50d21, 0x53765b2f), TOBN(0xbdd4e083, 0xfa127f3d),
-+     TOBN(0x9cf3c074, 0x397b1b10), TOBN(0x59f8090c, 0xb1b59fd3),
-+     TOBN(0x7b15fd9d, 0x615faa8f), TOBN(0x8fa1eb40, 0x968554ed),
-+     TOBN(0x7bb4447e, 0x7aa44882), TOBN(0x2bb2d0d1, 0x029fff32),
-+     TOBN(0x075e2a64, 0x6caa6d2f), TOBN(0x8eb879de, 0x22e7351b),
-+     TOBN(0xbcd5624e, 0x9a506c62), TOBN(0x218eaef0, 0xa87e24dc),
-+     TOBN(0x37e56847, 0x44ddfa35), TOBN(0x9ccfc5c5, 0xdab3f747),
-+     TOBN(0x9ac1df3f, 0x1ee96cf4), TOBN(0x0c0571a1, 0x3b480b8f),
-+     TOBN(0x2fbeb3d5, 0x4b3a7b3c), TOBN(0x35c03669, 0x5dcdbb99),
-+     TOBN(0x52a0f5dc, 0xb2415b3a), TOBN(0xd57759b4, 0x4413ed9a),
-+     TOBN(0x1fe647d8, 0x3d30a2c5), TOBN(0x0857f77e, 0xf78a81dc),
-+     TOBN(0x11d5a334, 0x131a4a9b), TOBN(0xc0a94af9, 0x29d393f5),
-+     TOBN(0xbc3a5c0b, 0xdaa6ec1a), TOBN(0xba9fe493, 0x88d2d7ed),
-+     TOBN(0xbb4335b4, 0xbb614797), TOBN(0x991c4d68, 0x72f83533),
-+     TOBN(0x53258c28, 0xd2f01cb3), TOBN(0x93d6eaa3, 0xd75db0b1),
-+     TOBN(0x419a2b0d, 0xe87d0db4), TOBN(0xa1e48f03, 0xd8fe8493),
-+     TOBN(0xf747faf6, 0xc508b23a), TOBN(0xf137571a, 0x35d53549),
-+     TOBN(0x9f5e58e2, 0xfcf9b838), TOBN(0xc7186cee, 0xa7fd3cf5),
-+     TOBN(0x77b868ce, 0xe978a1d3), TOBN(0xe3a68b33, 0x7ab92d04),
-+     TOBN(0x51029794, 0x87a5b862), TOBN(0x5f0606c3, 0x3a61d41d),
-+     TOBN(0x2814be27, 0x6f9326f1), TOBN(0x2f521c14, 0xc6fe3c2e),
-+     TOBN(0x17464d7d, 0xacdf7351), TOBN(0x10f5f9d3, 0x777f7e44),
-+     TOBN(0xce8e616b, 0x269fb37d), TOBN(0xaaf73804, 0x7de62de5),
-+     TOBN(0xaba11175, 0x4fdd4153), TOBN(0x515759ba, 0x3770b49b),
-+     TOBN(0x8b09ebf8, 0xaa423a61), TOBN(0x592245a1, 0xcd41fb92),
-+     TOBN(0x1cba8ec1, 0x9b4c8936), TOBN(0xa87e91e3, 0xaf36710e),
-+     TOBN(0x1fd84ce4, 0x3d34a2e3), TOBN(0xee3759ce, 0xb43b5d61),
-+     TOBN(0x895bc78c, 0x619186c7), TOBN(0xf19c3809, 0xcbb9725a),
-+     TOBN(0xc0be21aa, 0xde744b1f), TOBN(0xa7d222b0, 0x60f8056b),
-+     TOBN(0x74be6157, 0xb23efe11), TOBN(0x6fab2b4f, 0x0cd68253),
-+     TOBN(0xad33ea5f, 0x4bf1d725), TOBN(0x9c1d8ee2, 0x4f6c950f),
-+     TOBN(0x544ee78a, 0xa377af06), TOBN(0x54f489bb, 0x94a113e1),
-+     TOBN(0x8f11d634, 0x992fb7e8), TOBN(0x0169a7aa, 0xa2a44347),
-+     TOBN(0x1d49d4af, 0x95020e00), TOBN(0x95945722, 0xe08e120b),
-+     TOBN(0xb6e33878, 0xa4d32282), TOBN(0xe36e029d, 0x48020ae7),
-+     TOBN(0xe05847fb, 0x37a9b750), TOBN(0xf876812c, 0xb29e3819),
-+     TOBN(0x84ad138e, 0xd23a17f0), TOBN(0x6d7b4480, 0xf0b3950e),
-+     TOBN(0xdfa8aef4, 0x2fd67ae0), TOBN(0x8d3eea24, 0x52333af6),
-+     TOBN(0x0d052075, 0xb15d5acc), TOBN(0xc6d9c79f, 0xbd815bc4),
-+     TOBN(0x8dcafd88, 0xdfa36cf2), TOBN(0x908ccbe2, 0x38aa9070),
-+     TOBN(0x638722c4, 0xba35afce), TOBN(0x5a3da8b0, 0xfd6abf0b),
-+     TOBN(0x2dce252c, 0xc9c335c1), TOBN(0x84e7f0de, 0x65aa799b),
-+     TOBN(0x2101a522, 0xb99a72cb), TOBN(0x06de6e67, 0x87618016),
-+     TOBN(0x5ff8c7cd, 0xe6f3653e), TOBN(0x0a821ab5, 0xc7a6754a),
-+     TOBN(0x7e3fa52b, 0x7cb0b5a2), TOBN(0xa7fb121c, 0xc9048790),
-+     TOBN(0x1a725020, 0x06ce053a), TOBN(0xb490a31f, 0x04e929b0),
-+     TOBN(0xe17be47d, 0x62dd61ad), TOBN(0x781a961c, 0x6be01371),
-+     TOBN(0x1063bfd3, 0xdae3cbba), TOBN(0x35647406, 0x7f73c9ba),
-+     TOBN(0xf50e957b, 0x2736a129), TOBN(0xa6313702, 0xed13f256),
-+     TOBN(0x9436ee65, 0x3a19fcc5), TOBN(0xcf2bdb29, 0xe7a4c8b6),
-+     TOBN(0xb06b1244, 0xc5f95cd8), TOBN(0xda8c8af0, 0xf4ab95f4),
-+     TOBN(0x1bae59c2, 0xb9e5836d), TOBN(0x07d51e7e, 0x3acffffc),
-+     TOBN(0x01e15e6a, 0xc2ccbcda), TOBN(0x3bc1923f, 0x8528c3e0),
-+     TOBN(0x43324577, 0xa49fead4), TOBN(0x61a1b884, 0x2aa7a711),
-+     TOBN(0xf9a86e08, 0x700230ef), TOBN(0x0af585a1, 0xbd19adf8),
-+     TOBN(0x7645f361, 0xf55ad8f2), TOBN(0x6e676223, 0x46c3614c),
-+     TOBN(0x23cb257c, 0x4e774d3f), TOBN(0x82a38513, 0xac102d1b),
-+     TOBN(0x9bcddd88, 0x7b126aa5), TOBN(0xe716998b, 0xeefd3ee4),
-+     TOBN(0x4239d571, 0xfb167583), TOBN(0xdd011c78, 0xd16c8f8a),
-+     TOBN(0x271c2895, 0x69a27519), TOBN(0x9ce0a3b7, 0xd2d64b6a),
-+     TOBN(0x8c977289, 0xd5ec6738), TOBN(0xa3b49f9a, 0x8840ef6b),
-+     TOBN(0x808c14c9, 0x9a453419), TOBN(0x5c00295b, 0x0cf0a2d5),
-+     TOBN(0x524414fb, 0x1d4bcc76), TOBN(0xb07691d2, 0x459a88f1),
-+     TOBN(0x77f43263, 0xf70d110f), TOBN(0x64ada5e0, 0xb7abf9f3),
-+     TOBN(0xafd0f94e, 0x5b544cf5), TOBN(0xb4a13a15, 0xfd2713fe),
-+     TOBN(0xb99b7d6e, 0x250c74f4), TOBN(0x097f2f73, 0x20324e45),
-+     TOBN(0x994b37d8, 0xaffa8208), TOBN(0xc3c31b0b, 0xdc29aafc),
-+     TOBN(0x3da74651, 0x7a3a607f), TOBN(0xd8e1b8c1, 0xfe6955d6),
-+     TOBN(0x716e1815, 0xc8418682), TOBN(0x541d487f, 0x7dc91d97),
-+     TOBN(0x48a04669, 0xc6996982), TOBN(0xf39cab15, 0x83a6502e),
-+     TOBN(0x025801a0, 0xe68db055), TOBN(0xf3569758, 0xba3338d5),
-+     TOBN(0xb0c8c0aa, 0xee2afa84), TOBN(0x4f6985d3, 0xfb6562d1),
-+     TOBN(0x351f1f15, 0x132ed17a), TOBN(0x510ed0b4, 0xc04365fe),
-+     TOBN(0xa3f98138, 0xe5b1f066), TOBN(0xbc9d95d6, 0x32df03dc),
-+     TOBN(0xa83ccf6e, 0x19abd09e), TOBN(0x0b4097c1, 0x4ff17edb),
-+     TOBN(0x58a5c478, 0xd64a06ce), TOBN(0x2ddcc3fd, 0x544a58fd),
-+     TOBN(0xd449503d, 0x9e8153b8), TOBN(0x3324fd02, 0x7774179b),
-+     TOBN(0xaf5d47c8, 0xdbd9120c), TOBN(0xeb860162, 0x34fa94db),
-+     TOBN(0x5817bdd1, 0x972f07f4), TOBN(0xe5579e2e, 0xd27bbceb),
-+     TOBN(0x86847a1f, 0x5f11e5a6), TOBN(0xb39ed255, 0x7c3cf048),
-+     TOBN(0xe1076417, 0xa2f62e55), TOBN(0x6b9ab38f, 0x1bcf82a2),
-+     TOBN(0x4bb7c319, 0x7aeb29f9), TOBN(0xf6d17da3, 0x17227a46),
-+     TOBN(0xab53ddbd, 0x0f968c00), TOBN(0xa03da7ec, 0x000c880b),
-+     TOBN(0x7b239624, 0x6a9ad24d), TOBN(0x612c0401, 0x01ec60d0),
-+     TOBN(0x70d10493, 0x109f5df1), TOBN(0xfbda4030, 0x80af7550),
-+     TOBN(0x30b93f95, 0xc6b9a9b3), TOBN(0x0c74ec71, 0x007d9418),
-+     TOBN(0x94175564, 0x6edb951f), TOBN(0x5f4a9d78, 0x7f22c282),
-+     TOBN(0xb7870895, 0xb38d1196), TOBN(0xbc593df3, 0xa228ce7c),
-+     TOBN(0xc78c5bd4, 0x6af3641a), TOBN(0x7802200b, 0x3d9b3dcc),
-+     TOBN(0x0dc73f32, 0x8be33304), TOBN(0x847ed87d, 0x61ffb79a),
-+     TOBN(0xf85c974e, 0x6d671192), TOBN(0x1e14100a, 0xde16f60f),
-+     TOBN(0x45cb0d5a, 0x95c38797), TOBN(0x18923bba, 0x9b022da4),
-+     TOBN(0xef2be899, 0xbbe7e86e), TOBN(0x4a1510ee, 0x216067bf),
-+     TOBN(0xd98c8154, 0x84d5ce3e), TOBN(0x1af777f0, 0xf92a2b90),
-+     TOBN(0x9fbcb400, 0x4ef65724), TOBN(0x3e04a4c9, 0x3c0ca6fe),
-+     TOBN(0xfb3e2cb5, 0x55002994), TOBN(0x1f3a93c5, 0x5363ecab),
-+     TOBN(0x1fe00efe, 0x3923555b), TOBN(0x744bedd9, 0x1e1751ea),
-+     TOBN(0x3fb2db59, 0x6ab69357), TOBN(0x8dbd7365, 0xf5e6618b),
-+     TOBN(0x99d53099, 0xdf1ea40e), TOBN(0xb3f24a0b, 0x57d61e64),
-+     TOBN(0xd088a198, 0x596eb812), TOBN(0x22c8361b, 0x5762940b),
-+     TOBN(0x66f01f97, 0xf9c0d95c), TOBN(0x88461172, 0x8e43cdae),
-+     TOBN(0x11599a7f, 0xb72b15c3), TOBN(0x135a7536, 0x420d95cc),
-+     TOBN(0x2dcdf0f7, 0x5f7ae2f6), TOBN(0x15fc6e1d, 0xd7fa6da2),
-+     TOBN(0x81ca829a, 0xd1d441b6), TOBN(0x84c10cf8, 0x04a106b6),
-+     TOBN(0xa9b26c95, 0xa73fbbd0), TOBN(0x7f24e0cb, 0x4d8f6ee8),
-+     TOBN(0x48b45937, 0x1e25a043), TOBN(0xf8a74fca, 0x036f3dfe),
-+     TOBN(0x1ed46585, 0xc9f84296), TOBN(0x7fbaa8fb, 0x3bc278b0),
-+     TOBN(0xa8e96cd4, 0x6c4fcbd0), TOBN(0x940a1202, 0x73b60a5f),
-+     TOBN(0x34aae120, 0x55a4aec8), TOBN(0x550e9a74, 0xdbd742f0),
-+     TOBN(0x794456d7, 0x228c68ab), TOBN(0x492f8868, 0xa4e25ec6),
-+     TOBN(0x682915ad, 0xb2d8f398), TOBN(0xf13b51cc, 0x5b84c953),
-+     TOBN(0xcda90ab8, 0x5bb917d6), TOBN(0x4b615560, 0x4ea3dee1),
-+     TOBN(0x578b4e85, 0x0a52c1c8), TOBN(0xeab1a695, 0x20b75fc4),
-+     TOBN(0x60c14f3c, 0xaa0bb3c6), TOBN(0x220f448a, 0xb8216094),
-+     TOBN(0x4fe7ee31, 0xb0e63d34), TOBN(0xf4600572, 0xa9e54fab),
-+     TOBN(0xc0493334, 0xd5e7b5a4), TOBN(0x8589fb92, 0x06d54831),
-+     TOBN(0xaa70f5cc, 0x6583553a), TOBN(0x0879094a, 0xe25649e5),
-+     TOBN(0xcc904507, 0x10044652), TOBN(0xebb0696d, 0x02541c4f),
-+     TOBN(0x5a171fde, 0xb9718710), TOBN(0x38f1bed8, 0xf374a9f5),
-+     TOBN(0xc8c582e1, 0xba39bdc1), TOBN(0xfc457b0a, 0x908cc0ce),
-+     TOBN(0x9a187fd4, 0x883841e2), TOBN(0x8ec25b39, 0x38725381),
-+     TOBN(0x2553ed05, 0x96f84395), TOBN(0x095c7661, 0x6f6c6897),
-+     TOBN(0x917ac85c, 0x4bdc5610), TOBN(0xb2885fe4, 0x179eb301),
-+     TOBN(0x5fc65547, 0x8b78bdcc), TOBN(0x4a9fc893, 0xe59e4699),
-+     TOBN(0xbb7ff0cd, 0x3ce299af), TOBN(0x195be9b3, 0xadf38b20),
-+     TOBN(0x6a929c87, 0xd38ddb8f), TOBN(0x55fcc99c, 0xb21a51b9),
-+     TOBN(0x2b695b4c, 0x721a4593), TOBN(0xed1e9a15, 0x768eaac2),
-+     TOBN(0xfb63d71c, 0x7489f914), TOBN(0xf98ba31c, 0x78118910),
-+     TOBN(0x80291373, 0x9b128eb4), TOBN(0x7801214e, 0xd448af4a),
-+     TOBN(0xdbd2e22b, 0x55418dd3), TOBN(0xeffb3c0d, 0xd3998242),
-+     TOBN(0xdfa6077c, 0xc7bf3827), TOBN(0xf2165bcb, 0x47f8238f),
-+     TOBN(0xfe37cf68, 0x8564d554), TOBN(0xe5f825c4, 0x0a81fb98),
-+     TOBN(0x43cc4f67, 0xffed4d6f), TOBN(0xbc609578, 0xb50a34b0),
-+     TOBN(0x8aa8fcf9, 0x5041faf1), TOBN(0x5659f053, 0x651773b6),
-+     TOBN(0xe87582c3, 0x6044d63b), TOBN(0xa6089409, 0x0cdb0ca0),
-+     TOBN(0x8c993e0f, 0xbfb2bcf6), TOBN(0xfc64a719, 0x45985cfc),
-+     TOBN(0x15c4da80, 0x83dbedba), TOBN(0x804ae112, 0x2be67df7),
-+     TOBN(0xda4c9658, 0xa23defde), TOBN(0x12002ddd, 0x5156e0d3),
-+     TOBN(0xe68eae89, 0x5dd21b96), TOBN(0x8b99f28b, 0xcf44624d),
-+     TOBN(0x0ae00808, 0x1ec8897a), TOBN(0xdd0a9303, 0x6712f76e),
-+     TOBN(0x96237522, 0x4e233de4), TOBN(0x192445b1, 0x2b36a8a5),
-+     TOBN(0xabf9ff74, 0x023993d9), TOBN(0x21f37bf4, 0x2aad4a8f),
-+     TOBN(0x340a4349, 0xf8bd2bbd), TOBN(0x1d902cd9, 0x4868195d),
-+     TOBN(0x3d27bbf1, 0xe5fdb6f1), TOBN(0x7a5ab088, 0x124f9f1c),
-+     TOBN(0xc466ab06, 0xf7a09e03), TOBN(0x2f8a1977, 0x31f2c123),
-+     TOBN(0xda355dc7, 0x041b6657), TOBN(0xcb840d12, 0x8ece2a7c),
-+     TOBN(0xb600ad9f, 0x7db32675), TOBN(0x78fea133, 0x07a06f1b),
-+     TOBN(0x5d032269, 0xb31f6094), TOBN(0x07753ef5, 0x83ec37aa),
-+     TOBN(0x03485aed, 0x9c0bea78), TOBN(0x41bb3989, 0xbc3f4524),
-+     TOBN(0x09403761, 0x697f726d), TOBN(0x6109beb3, 0xdf394820),
-+     TOBN(0x804111ea, 0x3b6d1145), TOBN(0xb6271ea9, 0xa8582654),
-+     TOBN(0x619615e6, 0x24e66562), TOBN(0xa2554945, 0xd7b6ad9c),
-+     TOBN(0xd9c4985e, 0x99bfe35f), TOBN(0x9770ccc0, 0x7b51cdf6),
-+     TOBN(0x7c327013, 0x92881832), TOBN(0x8777d45f, 0x286b26d1),
-+     TOBN(0x9bbeda22, 0xd847999d), TOBN(0x03aa33b6, 0xc3525d32),
-+     TOBN(0x4b7b96d4, 0x28a959a1), TOBN(0xbb3786e5, 0x31e5d234),
-+     TOBN(0xaeb5d3ce, 0x6961f247), TOBN(0x20aa85af, 0x02f93d3f),
-+     TOBN(0x9cd1ad3d, 0xd7a7ae4f), TOBN(0xbf6688f0, 0x781adaa8),
-+     TOBN(0xb1b40e86, 0x7469cead), TOBN(0x1904c524, 0x309fca48),
-+     TOBN(0x9b7312af, 0x4b54bbc7), TOBN(0xbe24bf8f, 0x593affa2),
-+     TOBN(0xbe5e0790, 0xbd98764b), TOBN(0xa0f45f17, 0xa26e299e),
-+     TOBN(0x4af0d2c2, 0x6b8fe4c7), TOBN(0xef170db1, 0x8ae8a3e6),
-+     TOBN(0x0e8d61a0, 0x29e0ccc1), TOBN(0xcd53e87e, 0x60ad36ca),
-+     TOBN(0x328c6623, 0xc8173822), TOBN(0x7ee1767d, 0xa496be55),
-+     TOBN(0x89f13259, 0x648945af), TOBN(0x9e45a5fd, 0x25c8009c),
-+     TOBN(0xaf2febd9, 0x1f61ab8c), TOBN(0x43f6bc86, 0x8a275385),
-+     TOBN(0x87792348, 0xf2142e79), TOBN(0x17d89259, 0xc6e6238a),
-+     TOBN(0x7536d2f6, 0x4a839d9b), TOBN(0x1f428fce, 0x76a1fbdc),
-+     TOBN(0x1c109601, 0x0db06dfe), TOBN(0xbfc16bc1, 0x50a3a3cc),
-+     TOBN(0xf9cbd9ec, 0x9b30f41b), TOBN(0x5b5da0d6, 0x00138cce),
-+     TOBN(0xec1d0a48, 0x56ef96a7), TOBN(0xb47eb848, 0x982bf842),
-+     TOBN(0x66deae32, 0xec3f700d), TOBN(0x4e43c42c, 0xaa1181e0),
-+     TOBN(0xa1d72a31, 0xd1a4aa2a), TOBN(0x440d4668, 0xc004f3ce),
-+     TOBN(0x0d6a2d3b, 0x45fe8a7a), TOBN(0x820e52e2, 0xfb128365),
-+     TOBN(0x29ac5fcf, 0x25e51b09), TOBN(0x180cd2bf, 0x2023d159),
-+     TOBN(0xa9892171, 0xa1ebf90e), TOBN(0xf97c4c87, 0x7c132181),
-+     TOBN(0x9f1dc724, 0xc03dbb7e), TOBN(0xae043765, 0x018cbbe4),
-+     TOBN(0xfb0b2a36, 0x0767d153), TOBN(0xa8e2f4d6, 0x249cbaeb),
-+     TOBN(0x172a5247, 0xd95ea168), TOBN(0x1758fada, 0x2970764a),
-+     TOBN(0xac803a51, 0x1d978169), TOBN(0x299cfe2e, 0xde77e01b),
-+     TOBN(0x652a1e17, 0xb0a98927), TOBN(0x2e26e1d1, 0x20014495),
-+     TOBN(0x7ae0af9f, 0x7175b56a), TOBN(0xc2e22a80, 0xd64b9f95),
-+     TOBN(0x4d0ff9fb, 0xd90a060a), TOBN(0x496a27db, 0xbaf38085),
-+     TOBN(0x32305401, 0xda776bcf), TOBN(0xb8cdcef6, 0x725f209e),
-+     TOBN(0x61ba0f37, 0x436a0bba), TOBN(0x263fa108, 0x76860049),
-+     TOBN(0x92beb98e, 0xda3542cf), TOBN(0xa2d4d14a, 0xd5849538),
-+     TOBN(0x989b9d68, 0x12e9a1bc), TOBN(0x61d9075c, 0x5f6e3268),
-+     TOBN(0x352c6aa9, 0x99ace638), TOBN(0xde4e4a55, 0x920f43ff),
-+     TOBN(0xe5e4144a, 0xd673c017), TOBN(0x667417ae, 0x6f6e05ea),
-+     TOBN(0x613416ae, 0xdcd1bd56), TOBN(0x5eb36201, 0x86693711),
-+     TOBN(0x2d7bc504, 0x3a1aa914), TOBN(0x175a1299, 0x76dc5975),
-+     TOBN(0xe900e0f2, 0x3fc8125c), TOBN(0x569ef68c, 0x11198875),
-+     TOBN(0x9012db63, 0x63a113b4), TOBN(0xe3bd3f56, 0x98835766),
-+     TOBN(0xa5c94a52, 0x76412dea), TOBN(0xad9e2a09, 0xaa735e5c),
-+     TOBN(0x405a984c, 0x508b65e9), TOBN(0xbde4a1d1, 0x6df1a0d1),
-+     TOBN(0x1a9433a1, 0xdfba80da), TOBN(0xe9192ff9, 0x9440ad2e),
-+     TOBN(0x9f649696, 0x5099fe92), TOBN(0x25ddb65c, 0x0b27a54a),
-+     TOBN(0x178279dd, 0xc590da61), TOBN(0x5479a999, 0xfbde681a),
-+     TOBN(0xd0e84e05, 0x013fe162), TOBN(0xbe11dc92, 0x632d471b),
-+     TOBN(0xdf0b0c45, 0xfc0e089f), TOBN(0x04fb15b0, 0x4c144025),
-+     TOBN(0xa61d5fc2, 0x13c99927), TOBN(0xa033e9e0, 0x3de2eb35),
-+     TOBN(0xf8185d5c, 0xb8dacbb4), TOBN(0x9a88e265, 0x8644549d),
-+     TOBN(0xf717af62, 0x54671ff6), TOBN(0x4bd4241b, 0x5fa58603),
-+     TOBN(0x06fba40b, 0xe67773c0), TOBN(0xc1d933d2, 0x6a2847e9),
-+     TOBN(0xf4f5acf3, 0x689e2c70), TOBN(0x92aab0e7, 0x46bafd31),
-+     TOBN(0x798d76aa, 0x3473f6e5), TOBN(0xcc6641db, 0x93141934),
-+     TOBN(0xcae27757, 0xd31e535e), TOBN(0x04cc43b6, 0x87c2ee11),
-+     TOBN(0x8d1f9675, 0x2e029ffa), TOBN(0xc2150672, 0xe4cc7a2c),
-+     TOBN(0x3b03c1e0, 0x8d68b013), TOBN(0xa9d6816f, 0xedf298f3),
-+     TOBN(0x1bfbb529, 0xa2804464), TOBN(0x95a52fae, 0x5db22125),
-+     TOBN(0x55b32160, 0x0e1cb64e), TOBN(0x004828f6, 0x7e7fc9fe),
-+     TOBN(0x13394b82, 0x1bb0fb93), TOBN(0xb6293a2d, 0x35f1a920),
-+     TOBN(0xde35ef21, 0xd145d2d9), TOBN(0xbe6225b3, 0xbb8fa603),
-+     TOBN(0x00fc8f6b, 0x32cf252d), TOBN(0xa28e52e6, 0x117cf8c2),
-+     TOBN(0x9d1dc89b, 0x4c371e6d), TOBN(0xcebe0675, 0x36ef0f28),
-+     TOBN(0x5de05d09, 0xa4292f81), TOBN(0xa8303593, 0x353e3083),
-+     TOBN(0xa1715b0a, 0x7e37a9bb), TOBN(0x8c56f61e, 0x2b8faec3),
-+     TOBN(0x52507431, 0x33c9b102), TOBN(0x0130cefc, 0xa44431f0),
-+     TOBN(0x56039fa0, 0xbd865cfb), TOBN(0x4b03e578, 0xbc5f1dd7),
-+     TOBN(0x40edf2e4, 0xbabe7224), TOBN(0xc752496d, 0x3a1988f6),
-+     TOBN(0xd1572d3b, 0x564beb6b), TOBN(0x0db1d110, 0x39a1c608),
-+     TOBN(0x568d1934, 0x16f60126), TOBN(0x05ae9668, 0xf354af33),
-+     TOBN(0x19de6d37, 0xc92544f2), TOBN(0xcc084353, 0xa35837d5),
-+     TOBN(0xcbb6869c, 0x1a514ece), TOBN(0xb633e728, 0x2e1d1066),
-+     TOBN(0xf15dd69f, 0x936c581c), TOBN(0x96e7b8ce, 0x7439c4f9),
-+     TOBN(0x5e676f48, 0x2e448a5b), TOBN(0xb2ca7d5b, 0xfd916bbb),
-+     TOBN(0xd55a2541, 0xf5024025), TOBN(0x47bc5769, 0xe4c2d937),
-+     TOBN(0x7d31b92a, 0x0362189f), TOBN(0x83f3086e, 0xef7816f9),
-+     TOBN(0xf9f46d94, 0xb587579a), TOBN(0xec2d22d8, 0x30e76c5f),
-+     TOBN(0x27d57461, 0xb000ffcf), TOBN(0xbb7e65f9, 0x364ffc2c),
-+     TOBN(0x7c7c9477, 0x6652a220), TOBN(0x61618f89, 0xd696c981),
-+     TOBN(0x5021701d, 0x89effff3), TOBN(0xf2c8ff8e, 0x7c314163),
-+     TOBN(0x2da413ad, 0x8efb4d3e), TOBN(0x937b5adf, 0xce176d95),
-+     TOBN(0x22867d34, 0x2a67d51c), TOBN(0x262b9b10, 0x18eb3ac9),
-+     TOBN(0x4e314fe4, 0xc43ff28b), TOBN(0x76476627, 0x6a664e7a),
-+     TOBN(0x3e90e40b, 0xb7a565c2), TOBN(0x8588993a, 0xc1acf831),
-+     TOBN(0xd7b501d6, 0x8f938829), TOBN(0x996627ee, 0x3edd7d4c),
-+     TOBN(0x37d44a62, 0x90cd34c7), TOBN(0xa8327499, 0xf3833e8d),
-+     TOBN(0x2e18917d, 0x4bf50353), TOBN(0x85dd726b, 0x556765fb),
-+     TOBN(0x54fe65d6, 0x93d5ab66), TOBN(0x3ddbaced, 0x915c25fe),
-+     TOBN(0xa799d9a4, 0x12f22e85), TOBN(0xe2a24867, 0x6d06f6bc),
-+     TOBN(0xf4f1ee56, 0x43ca1637), TOBN(0xfda2828b, 0x61ece30a),
-+     TOBN(0x758c1a3e, 0xa2dee7a6), TOBN(0xdcde2f3c, 0x734b2284),
-+     TOBN(0xaba445d2, 0x4eaba6ad), TOBN(0x35aaf668, 0x76cee0a7),
-+     TOBN(0x7e0b04a9, 0xe5aa049a), TOBN(0xe74083ad, 0x91103e84),
-+     TOBN(0xbeb183ce, 0x40afecc3), TOBN(0x6b89de9f, 0xea043f7a),}
-+    ,
-+    {TOBN(0x0e299d23, 0xfe67ba66), TOBN(0x91450760, 0x93cf2f34),
-+     TOBN(0xf45b5ea9, 0x97fcf913), TOBN(0x5be00843, 0x8bd7ddda),
-+     TOBN(0x358c3e05, 0xd53ff04d), TOBN(0xbf7ccdc3, 0x5de91ef7),
-+     TOBN(0xad684dbf, 0xb69ec1a0), TOBN(0x367e7cf2, 0x801fd997),
-+     TOBN(0x0ca1f3b7, 0xb0dc8595), TOBN(0x27de4608, 0x9f1d9f2e),
-+     TOBN(0x1af3bf39, 0xbadd82a7), TOBN(0x79356a79, 0x65862448),
-+     TOBN(0xc0602345, 0xf5f9a052), TOBN(0x1a8b0f89, 0x139a42f9),
-+     TOBN(0xb53eee42, 0x844d40fc), TOBN(0x93b0bfe5, 0x4e5b6368),
-+     TOBN(0x5434dd02, 0xc024789c), TOBN(0x90dca9ea, 0x41b57bfc),
-+     TOBN(0x8aa898e2, 0x243398df), TOBN(0xf607c834, 0x894a94bb),
-+     TOBN(0xbb07be97, 0xc2c99b76), TOBN(0x6576ba67, 0x18c29302),
-+     TOBN(0x3d79efcc, 0xe703a88c), TOBN(0xf259ced7, 0xb6a0d106),
-+     TOBN(0x0f893a5d, 0xc8de610b), TOBN(0xe8c515fb, 0x67e223ce),
-+     TOBN(0x7774bfa6, 0x4ead6dc5), TOBN(0x89d20f95, 0x925c728f),
-+     TOBN(0x7a1e0966, 0x098583ce), TOBN(0xa2eedb94, 0x93f2a7d7),
-+     TOBN(0x1b282097, 0x4c304d4a), TOBN(0x0842e3da, 0xc077282d),
-+     TOBN(0xe4d972a3, 0x3b9e2d7b), TOBN(0x7cc60b27, 0xc48218ff),
-+     TOBN(0x8fc70838, 0x84149d91), TOBN(0x5c04346f, 0x2f461ecc),
-+     TOBN(0xebe9fdf2, 0x614650a9), TOBN(0x5e35b537, 0xc1f666ac),
-+     TOBN(0x645613d1, 0x88babc83), TOBN(0x88cace3a, 0xc5e1c93e),
-+     TOBN(0x209ca375, 0x3de92e23), TOBN(0xccb03cc8, 0x5fbbb6e3),
-+     TOBN(0xccb90f03, 0xd7b1487e), TOBN(0xfa9c2a38, 0xc710941f),
-+     TOBN(0x756c3823, 0x6724ceed), TOBN(0x3a902258, 0x192d0323),
-+     TOBN(0xb150e519, 0xea5e038e), TOBN(0xdcba2865, 0xc7427591),
-+     TOBN(0xe549237f, 0x78890732), TOBN(0xc443bef9, 0x53fcb4d9),
-+     TOBN(0x9884d8a6, 0xeb3480d6), TOBN(0x8a35b6a1, 0x3048b186),
-+     TOBN(0xb4e44716, 0x65e9a90a), TOBN(0x45bf380d, 0x653006c0),
-+     TOBN(0x8f3f820d, 0x4fe9ae3b), TOBN(0x244a35a0, 0x979a3b71),
-+     TOBN(0xa1010e9d, 0x74cd06ff), TOBN(0x9c17c7df, 0xaca3eeac),
-+     TOBN(0x74c86cd3, 0x8063aa2b), TOBN(0x8595c4b3, 0x734614ff),
-+     TOBN(0xa3de00ca, 0x990f62cc), TOBN(0xd9bed213, 0xca0c3be5),
-+     TOBN(0x7886078a, 0xdf8ce9f5), TOBN(0xddb27ce3, 0x5cd44444),
-+     TOBN(0xed374a66, 0x58926ddd), TOBN(0x138b2d49, 0x908015b8),
-+     TOBN(0x886c6579, 0xde1f7ab8), TOBN(0x888b9aa0, 0xc3020b7a),
-+     TOBN(0xd3ec034e, 0x3a96e355), TOBN(0xba65b0b8, 0xf30fbe9a),
-+     TOBN(0x064c8e50, 0xff21367a), TOBN(0x1f508ea4, 0x0b04b46e),
-+     TOBN(0x98561a49, 0x747c866c), TOBN(0xbbb1e5fe, 0x0518a062),
-+     TOBN(0x20ff4e8b, 0xecdc3608), TOBN(0x7f55cded, 0x20184027),
-+     TOBN(0x8d73ec95, 0xf38c85f0), TOBN(0x5b589fdf, 0x8bc3b8c3),
-+     TOBN(0xbe95dd98, 0x0f12b66f), TOBN(0xf5bd1a09, 0x0e338e01),
-+     TOBN(0x65163ae5, 0x5e915918), TOBN(0x6158d6d9, 0x86f8a46b),
-+     TOBN(0x8466b538, 0xeeebf99c), TOBN(0xca8761f6, 0xbca477ef),
-+     TOBN(0xaf3449c2, 0x9ebbc601), TOBN(0xef3b0f41, 0xe0c3ae2f),
-+     TOBN(0xaa6c577d, 0x5de63752), TOBN(0xe9166601, 0x64682a51),
-+     TOBN(0x5a3097be, 0xfc15aa1e), TOBN(0x40d12548, 0xb54b0745),
-+     TOBN(0x5bad4706, 0x519a5f12), TOBN(0xed03f717, 0xa439dee6),
-+     TOBN(0x0794bb6c, 0x4a02c499), TOBN(0xf725083d, 0xcffe71d2),
-+     TOBN(0x2cad7519, 0x0f3adcaf), TOBN(0x7f68ea1c, 0x43729310),
-+     TOBN(0xe747c8c7, 0xb7ffd977), TOBN(0xec104c35, 0x80761a22),
-+     TOBN(0x8395ebaf, 0x5a3ffb83), TOBN(0xfb3261f4, 0xe4b63db7),
-+     TOBN(0x53544960, 0xd883e544), TOBN(0x13520d70, 0x8cc2eeb8),
-+     TOBN(0x08f6337b, 0xd3d65f99), TOBN(0x83997db2, 0x781cf95b),
-+     TOBN(0xce6ff106, 0x0dbd2c01), TOBN(0x4f8eea6b, 0x1f9ce934),
-+     TOBN(0x546f7c4b, 0x0e993921), TOBN(0x6236a324, 0x5e753fc7),
-+     TOBN(0x65a41f84, 0xa16022e9), TOBN(0x0c18d878, 0x43d1dbb2),
-+     TOBN(0x73c55640, 0x2d4cef9c), TOBN(0xa0428108, 0x70444c74),
-+     TOBN(0x68e4f15e, 0x9afdfb3c), TOBN(0x49a56143, 0x5bdfb6df),
-+     TOBN(0xa9bc1bd4, 0x5f823d97), TOBN(0xbceb5970, 0xea111c2a),
-+     TOBN(0x366b455f, 0xb269bbc4), TOBN(0x7cd85e1e, 0xe9bc5d62),
-+     TOBN(0xc743c41c, 0x4f18b086), TOBN(0xa4b40990, 0x95294fb9),
-+     TOBN(0x9c7c581d, 0x26ee8382), TOBN(0xcf17dcc5, 0x359d638e),
-+     TOBN(0xee8273ab, 0xb728ae3d), TOBN(0x1d112926, 0xf821f047),
-+     TOBN(0x11498477, 0x50491a74), TOBN(0x687fa761, 0xfde0dfb9),
-+     TOBN(0x2c258022, 0x7ea435ab), TOBN(0x6b8bdb94, 0x91ce7e3f),
-+     TOBN(0x4c5b5dc9, 0x3bf834aa), TOBN(0x04371819, 0x4f6c7e4b),
-+     TOBN(0xc284e00a, 0x3736bcad), TOBN(0x0d881118, 0x21ae8f8d),
-+     TOBN(0xf9cf0f82, 0xf48c8e33), TOBN(0xa11fd075, 0xa1bf40db),
-+     TOBN(0xdceab0de, 0xdc2733e5), TOBN(0xc560a8b5, 0x8e986bd7),
-+     TOBN(0x48dd1fe2, 0x3929d097), TOBN(0x3885b290, 0x92f188f1),
-+     TOBN(0x0f2ae613, 0xda6fcdac), TOBN(0x9054303e, 0xb662a46c),
-+     TOBN(0xb6871e44, 0x0738042a), TOBN(0x98e6a977, 0xbdaf6449),
-+     TOBN(0xd8bc0650, 0xd1c9df1b), TOBN(0xef3d6451, 0x36e098f9),
-+     TOBN(0x03fbae82, 0xb6d72d28), TOBN(0x77ca9db1, 0xf5d84080),
-+     TOBN(0x8a112cff, 0xa58efc1c), TOBN(0x518d761c, 0xc564cb4a),
-+     TOBN(0x69b5740e, 0xf0d1b5ce), TOBN(0x717039cc, 0xe9eb1785),
-+     TOBN(0x3fe29f90, 0x22f53382), TOBN(0x8e54ba56, 0x6bc7c95c),
-+     TOBN(0x9c806d8a, 0xf7f91d0f), TOBN(0x3b61b0f1, 0xa82a5728),
-+     TOBN(0x4640032d, 0x94d76754), TOBN(0x273eb5de, 0x47d834c6),
-+     TOBN(0x2988abf7, 0x7b4e4d53), TOBN(0xb7ce66bf, 0xde401777),
-+     TOBN(0x9fba6b32, 0x715071b3), TOBN(0x82413c24, 0xad3a1a98),
-+     TOBN(0x5b7fc8c4, 0xe0e8ad93), TOBN(0xb5679aee, 0x5fab868d),
-+     TOBN(0xb1f9d2fa, 0x2b3946f3), TOBN(0x458897dc, 0x5685b50a),
-+     TOBN(0x1e98c930, 0x89d0caf3), TOBN(0x39564c5f, 0x78642e92),
-+     TOBN(0x1b77729a, 0x0dbdaf18), TOBN(0xf9170722, 0x579e82e6),
-+     TOBN(0x680c0317, 0xe4515fa5), TOBN(0xf85cff84, 0xfb0c790f),
-+     TOBN(0xc7a82aab, 0x6d2e0765), TOBN(0x7446bca9, 0x35c82b32),
-+     TOBN(0x5de607aa, 0x6d63184f), TOBN(0x7c1a46a8, 0x262803a6),
-+     TOBN(0xd218313d, 0xaebe8035), TOBN(0x92113ffd, 0xc73c51f8),
-+     TOBN(0x4b38e083, 0x12e7e46c), TOBN(0x69d0a37a, 0x56126bd5),
-+     TOBN(0xfb3f324b, 0x73c07e04), TOBN(0xa0c22f67, 0x8fda7267),
-+     TOBN(0x8f2c0051, 0x4d2c7d8f), TOBN(0xbc45ced3, 0xcbe2cae5),
-+     TOBN(0xe1c6cf07, 0xa8f0f277), TOBN(0xbc392312, 0x1eb99a98),
-+     TOBN(0x75537b7e, 0x3cc8ac85), TOBN(0x8d725f57, 0xdd02753b),
-+     TOBN(0xfd05ff64, 0xb737df2f), TOBN(0x55fe8712, 0xf6d2531d),
-+     TOBN(0x57ce04a9, 0x6ab6b01c), TOBN(0x69a02a89, 0x7cd93724),
-+     TOBN(0x4f82ac35, 0xcf86699b), TOBN(0x8242d3ad, 0x9cb4b232),
-+     TOBN(0x713d0f65, 0xd62105e5), TOBN(0xbb222bfa, 0x2d29be61),
-+     TOBN(0xf2f9a79e, 0x6cfbef09), TOBN(0xfc24d8d3, 0xd5d6782f),
-+     TOBN(0x5db77085, 0xd4129967), TOBN(0xdb81c3cc, 0xdc3c2a43),
-+     TOBN(0x9d655fc0, 0x05d8d9a3), TOBN(0x3f5d057a, 0x54298026),
-+     TOBN(0x1157f56d, 0x88c54694), TOBN(0xb26baba5, 0x9b09573e),
-+     TOBN(0x2cab03b0, 0x22adffd1), TOBN(0x60a412c8, 0xdd69f383),
-+     TOBN(0xed76e98b, 0x54b25039), TOBN(0xd4ee67d3, 0x687e714d),
-+     TOBN(0x87739648, 0x7b00b594), TOBN(0xce419775, 0xc9ef709b),
-+     TOBN(0x40f76f85, 0x1c203a40), TOBN(0x30d352d6, 0xeafd8f91),
-+     TOBN(0xaf196d3d, 0x95578dd2), TOBN(0xea4bb3d7, 0x77cc3f3d),
-+     TOBN(0x42a5bd03, 0xb98e782b), TOBN(0xac958c40, 0x0624920d),
-+     TOBN(0xb838134c, 0xfc56fcc8), TOBN(0x86ec4ccf, 0x89572e5e),
-+     TOBN(0x69c43526, 0x9be47be0), TOBN(0x323b7dd8, 0xcb28fea1),
-+     TOBN(0xfa5538ba, 0x3a6c67e5), TOBN(0xef921d70, 0x1d378e46),
-+     TOBN(0xf92961fc, 0x3c4b880e), TOBN(0x3f6f914e, 0x98940a67),
-+     TOBN(0xa990eb0a, 0xfef0ff39), TOBN(0xa6c2920f, 0xf0eeff9c),
-+     TOBN(0xca804166, 0x51b8d9a3), TOBN(0x42531bc9, 0x0ffb0db1),
-+     TOBN(0x72ce4718, 0xaa82e7ce), TOBN(0x6e199913, 0xdf574741),
-+     TOBN(0xd5f1b13d, 0xd5d36946), TOBN(0x8255dc65, 0xf68f0194),
-+     TOBN(0xdc9df4cd, 0x8710d230), TOBN(0x3453c20f, 0x138c1988),
-+     TOBN(0x9af98dc0, 0x89a6ef01), TOBN(0x4dbcc3f0, 0x9857df85),
-+     TOBN(0x34805601, 0x5c1ad924), TOBN(0x40448da5, 0xd0493046),
-+     TOBN(0xf629926d, 0x4ee343e2), TOBN(0x6343f1bd, 0x90e8a301),
-+     TOBN(0xefc93491, 0x40815b3f), TOBN(0xf882a423, 0xde8f66fb),
-+     TOBN(0x3a12d5f4, 0xe7db9f57), TOBN(0x7dfba38a, 0x3c384c27),
-+     TOBN(0x7a904bfd, 0x6fc660b1), TOBN(0xeb6c5db3, 0x2773b21c),
-+     TOBN(0xc350ee66, 0x1cdfe049), TOBN(0x9baac0ce, 0x44540f29),
-+     TOBN(0xbc57b6ab, 0xa5ec6aad), TOBN(0x167ce8c3, 0x0a7c1baa),
-+     TOBN(0xb23a03a5, 0x53fb2b56), TOBN(0x6ce141e7, 0x4e057f78),
-+     TOBN(0x796525c3, 0x89e490d9), TOBN(0x0bc95725, 0xa31a7e75),
-+     TOBN(0x1ec56791, 0x1220fd06), TOBN(0x716e3a3c, 0x408b0bd6),
-+     TOBN(0x31cd6bf7, 0xe8ebeba9), TOBN(0xa7326ca6, 0xbee6b670),
-+     TOBN(0x3d9f851c, 0xcd090c43), TOBN(0x561e8f13, 0xf12c3988),
-+     TOBN(0x50490b6a, 0x904b7be4), TOBN(0x61690ce1, 0x0410737b),
-+     TOBN(0x299e9a37, 0x0f009052), TOBN(0x258758f0, 0xf026092e),
-+     TOBN(0x9fa255f3, 0xfdfcdc0f), TOBN(0xdbc9fb1f, 0xc0e1bcd2),
-+     TOBN(0x35f9dd6e, 0x24651840), TOBN(0xdca45a84, 0xa5c59abc),
-+     TOBN(0x103d396f, 0xecca4938), TOBN(0x4532da0a, 0xb97b3f29),
-+     TOBN(0xc4135ea5, 0x1999a6bf), TOBN(0x3aa9505a, 0x5e6bf2ee),
-+     TOBN(0xf77cef06, 0x3f5be093), TOBN(0x97d1a0f8, 0xa943152e),
-+     TOBN(0x2cb0ebba, 0x2e1c21dd), TOBN(0xf41b29fc, 0x2c6797c4),
-+     TOBN(0xc6e17321, 0xb300101f), TOBN(0x4422b0e9, 0xd0d79a89),
-+     TOBN(0x49e4901c, 0x92f1bfc4), TOBN(0x06ab1f8f, 0xe1e10ed9),
-+     TOBN(0x84d35577, 0xdb2926b8), TOBN(0xca349d39, 0x356e8ec2),
-+     TOBN(0x70b63d32, 0x343bf1a9), TOBN(0x8fd3bd28, 0x37d1a6b1),
-+     TOBN(0x0454879c, 0x316865b4), TOBN(0xee959ff6, 0xc458efa2),
-+     TOBN(0x0461dcf8, 0x9706dc3f), TOBN(0x737db0e2, 0x164e4b2e),
-+     TOBN(0x09262680, 0x2f8843c8), TOBN(0x54498bbc, 0x7745e6f6),
-+     TOBN(0x359473fa, 0xa29e24af), TOBN(0xfcc3c454, 0x70aa87a1),
-+     TOBN(0xfd2c4bf5, 0x00573ace), TOBN(0xb65b514e, 0x28dd1965),
-+     TOBN(0xe46ae7cf, 0x2193e393), TOBN(0x60e9a4e1, 0xf5444d97),
-+     TOBN(0xe7594e96, 0x00ff38ed), TOBN(0x43d84d2f, 0x0a0e0f02),
-+     TOBN(0x8b6db141, 0xee398a21), TOBN(0xb88a56ae, 0xe3bcc5be),
-+     TOBN(0x0a1aa52f, 0x373460ea), TOBN(0x20da1a56, 0x160bb19b),
-+     TOBN(0xfb54999d, 0x65bf0384), TOBN(0x71a14d24, 0x5d5a180e),
-+     TOBN(0xbc44db7b, 0x21737b04), TOBN(0xd84fcb18, 0x01dd8e92),
-+     TOBN(0x80de937b, 0xfa44b479), TOBN(0x53505499, 0x5c98fd4f),
-+     TOBN(0x1edb12ab, 0x28f08727), TOBN(0x4c58b582, 0xa5f3ef53),
-+     TOBN(0xbfb236d8, 0x8327f246), TOBN(0xc3a3bfaa, 0x4d7df320),
-+     TOBN(0xecd96c59, 0xb96024f2), TOBN(0xfc293a53, 0x7f4e0433),
-+     TOBN(0x5341352b, 0x5acf6e10), TOBN(0xc50343fd, 0xafe652c3),
-+     TOBN(0x4af3792d, 0x18577a7f), TOBN(0xe1a4c617, 0xaf16823d),
-+     TOBN(0x9b26d0cd, 0x33425d0a), TOBN(0x306399ed, 0x9b7bc47f),
-+     TOBN(0x2a792f33, 0x706bb20b), TOBN(0x31219614, 0x98111055),
-+     TOBN(0x864ec064, 0x87f5d28b), TOBN(0x11392d91, 0x962277fd),
-+     TOBN(0xb5aa7942, 0xbb6aed5f), TOBN(0x080094dc, 0x47e799d9),
-+     TOBN(0x4afa588c, 0x208ba19b), TOBN(0xd3e7570f, 0x8512f284),
-+     TOBN(0xcbae64e6, 0x02f5799a), TOBN(0xdeebe7ef, 0x514b9492),
-+     TOBN(0x30300f98, 0xe5c298ff), TOBN(0x17f561be, 0x3678361f),
-+     TOBN(0xf52ff312, 0x98cb9a16), TOBN(0x6233c3bc, 0x5562d490),
-+     TOBN(0x7bfa15a1, 0x92e3a2cb), TOBN(0x961bcfd1, 0xe6365119),
-+     TOBN(0x3bdd29bf, 0x2c8c53b1), TOBN(0x739704df, 0x822844ba),
-+     TOBN(0x7dacfb58, 0x7e7b754b), TOBN(0x23360791, 0xa806c9b9),
-+     TOBN(0xe7eb88c9, 0x23504452), TOBN(0x2983e996, 0x852c1783),
-+     TOBN(0xdd4ae529, 0x958d881d), TOBN(0x026bae03, 0x262c7b3c),
-+     TOBN(0x3a6f9193, 0x960b52d1), TOBN(0xd0980f90, 0x92696cfb),
-+     TOBN(0x4c1f428c, 0xd5f30851), TOBN(0x94dfed27, 0x2a4f6630),
-+     TOBN(0x4df53772, 0xfc5d48a4), TOBN(0xdd2d5a2f, 0x933260ce),
-+     TOBN(0x574115bd, 0xd44cc7a5), TOBN(0x4ba6b20d, 0xbd12533a),
-+     TOBN(0x30e93cb8, 0x243057c9), TOBN(0x794c486a, 0x14de320e),
-+     TOBN(0xe925d4ce, 0xf21496e4), TOBN(0xf951d198, 0xec696331),
-+     TOBN(0x9810e2de, 0x3e8d812f), TOBN(0xd0a47259, 0x389294ab),
-+     TOBN(0x513ba2b5, 0x0e3bab66), TOBN(0x462caff5, 0xabad306f),
-+     TOBN(0xe2dc6d59, 0xaf04c49e), TOBN(0x1aeb8750, 0xe0b84b0b),
-+     TOBN(0xc034f12f, 0x2f7d0ca2), TOBN(0x6d2e8128, 0xe06acf2f),
-+     TOBN(0x801f4f83, 0x21facc2f), TOBN(0xa1170c03, 0xf40ef607),
-+     TOBN(0xfe0a1d4f, 0x7805a99c), TOBN(0xbde56a36, 0xcc26aba5),
-+     TOBN(0x5b1629d0, 0x35531f40), TOBN(0xac212c2b, 0x9afa6108),
-+     TOBN(0x30a06bf3, 0x15697be5), TOBN(0x6f0545dc, 0x2c63c7c1),
-+     TOBN(0x5d8cb842, 0x7ccdadaf), TOBN(0xd52e379b, 0xac7015bb),
-+     TOBN(0xc4f56147, 0xf462c23e), TOBN(0xd44a4298, 0x46bc24b0),
-+     TOBN(0xbc73d23a, 0xe2856d4f), TOBN(0x61cedd8c, 0x0832bcdf),
-+     TOBN(0x60953556, 0x99f241d7), TOBN(0xee4adbd7, 0x001a349d),
-+     TOBN(0x0b35bf6a, 0xaa89e491), TOBN(0x7f0076f4, 0x136f7546),
-+     TOBN(0xd19a18ba, 0x9264da3d), TOBN(0x6eb2d2cd, 0x62a7a28b),
-+     TOBN(0xcdba941f, 0x8761c971), TOBN(0x1550518b, 0xa3be4a5d),
-+     TOBN(0xd0e8e2f0, 0x57d0b70c), TOBN(0xeea8612e, 0xcd133ba3),
-+     TOBN(0x814670f0, 0x44416aec), TOBN(0x424db6c3, 0x30775061),
-+     TOBN(0xd96039d1, 0x16213fd1), TOBN(0xc61e7fa5, 0x18a3478f),
-+     TOBN(0xa805bdcc, 0xcb0c5021), TOBN(0xbdd6f3a8, 0x0cc616dd),
-+     TOBN(0x06009667, 0x5d97f7e2), TOBN(0x31db0fc1, 0xaf0bf4b6),
-+     TOBN(0x23680ed4, 0x5491627a), TOBN(0xb99a3c66, 0x7d741fb1),
-+     TOBN(0xe9bb5f55, 0x36b1ff92), TOBN(0x29738577, 0x512b388d),
-+     TOBN(0xdb8a2ce7, 0x50fcf263), TOBN(0x385346d4, 0x6c4f7b47),
-+     TOBN(0xbe86c5ef, 0x31631f9e), TOBN(0xbf91da21, 0x03a57a29),
-+     TOBN(0xc3b1f796, 0x7b23f821), TOBN(0x0f7d00d2, 0x770db354),
-+     TOBN(0x8ffc6c3b, 0xd8fe79da), TOBN(0xcc5e8c40, 0xd525c996),
-+     TOBN(0x4640991d, 0xcfff632a), TOBN(0x64d97e8c, 0x67112528),
-+     TOBN(0xc232d973, 0x02f1cd1e), TOBN(0xce87eacb, 0x1dd212a4),
-+     TOBN(0x6e4c8c73, 0xe69802f7), TOBN(0x12ef0290, 0x1fffddbd),
-+     TOBN(0x941ec74e, 0x1bcea6e2), TOBN(0xd0b54024, 0x3cb92cbb),
-+     TOBN(0x809fb9d4, 0x7e8f9d05), TOBN(0x3bf16159, 0xf2992aae),
-+     TOBN(0xad40f279, 0xf8a7a838), TOBN(0x11aea631, 0x05615660),
-+     TOBN(0xbf52e6f1, 0xa01f6fa1), TOBN(0xef046995, 0x3dc2aec9),
-+     TOBN(0x785dbec9, 0xd8080711), TOBN(0xe1aec60a, 0x9fdedf76),
-+     TOBN(0xece797b5, 0xfa21c126), TOBN(0xc66e898f, 0x05e52732),
-+     TOBN(0x39bb69c4, 0x08811fdb), TOBN(0x8bfe1ef8, 0x2fc7f082),
-+     TOBN(0xc8e7a393, 0x174f4138), TOBN(0xfba8ad1d, 0xd58d1f98),
-+     TOBN(0xbc21d0ce, 0xbfd2fd5b), TOBN(0x0b839a82, 0x6ee60d61),
-+     TOBN(0xaacf7658, 0xafd22253), TOBN(0xb526bed8, 0xaae396b3),
-+     TOBN(0xccc1bbc2, 0x38564464), TOBN(0x9e3ff947, 0x8c45bc73),
-+     TOBN(0xcde9bca3, 0x58188a78), TOBN(0x138b8ee0, 0xd73bf8f7),
-+     TOBN(0x5c7e234c, 0x4123c489), TOBN(0x66e69368, 0xfa643297),
-+     TOBN(0x0629eeee, 0x39a15fa3), TOBN(0x95fab881, 0xa9e2a927),
-+     TOBN(0xb2497007, 0xeafbb1e1), TOBN(0xd75c9ce6, 0xe75b7a93),
-+     TOBN(0x3558352d, 0xefb68d78), TOBN(0xa2f26699, 0x223f6396),
-+     TOBN(0xeb911ecf, 0xe469b17a), TOBN(0x62545779, 0xe72d3ec2),
-+     TOBN(0x8ea47de7, 0x82cb113f), TOBN(0xebe4b086, 0x4e1fa98d),
-+     TOBN(0xec2d5ed7, 0x8cdfedb1), TOBN(0xa535c077, 0xfe211a74),
-+     TOBN(0x9678109b, 0x11d244c5), TOBN(0xf17c8bfb, 0xbe299a76),
-+     TOBN(0xb651412e, 0xfb11fbc4), TOBN(0xea0b5482, 0x94ab3f65),
-+     TOBN(0xd8dffd95, 0x0cf78243), TOBN(0x2e719e57, 0xce0361d4),
-+     TOBN(0x9007f085, 0x304ddc5b), TOBN(0x095e8c6d, 0x4daba2ea),
-+     TOBN(0x5a33cdb4, 0x3f9d28a9), TOBN(0x85b95cd8, 0xe2283003),
-+     TOBN(0xbcd6c819, 0xb9744733), TOBN(0x29c5f538, 0xfc7f5783),
-+     TOBN(0x6c49b2fa, 0xd59038e4), TOBN(0x68349cc1, 0x3bbe1018),
-+     TOBN(0xcc490c1d, 0x21830ee5), TOBN(0x36f9c4ee, 0xe9bfa297),
-+     TOBN(0x58fd7294, 0x48de1a94), TOBN(0xaadb13a8, 0x4e8f2cdc),
-+     TOBN(0x515eaaa0, 0x81313dba), TOBN(0xc76bb468, 0xc2152dd8),
-+     TOBN(0x357f8d75, 0xa653dbf8), TOBN(0xe4d8c4d1, 0xb14ac143),
-+     TOBN(0xbdb8e675, 0xb055cb40), TOBN(0x898f8e7b, 0x977b5167),
-+     TOBN(0xecc65651, 0xb82fb863), TOBN(0x56544814, 0x6d88f01f),
-+     TOBN(0xb0928e95, 0x263a75a9), TOBN(0xcfb6836f, 0x1a22fcda),
-+     TOBN(0x651d14db, 0x3f3bd37c), TOBN(0x1d3837fb, 0xb6ad4664),
-+     TOBN(0x7c5fb538, 0xff4f94ab), TOBN(0x7243c712, 0x6d7fb8f2),
-+     TOBN(0xef13d60c, 0xa85c5287), TOBN(0x18cfb7c7, 0x4bb8dd1b),
-+     TOBN(0x82f9bfe6, 0x72908219), TOBN(0x35c4592b, 0x9d5144ab),
-+     TOBN(0x52734f37, 0x9cf4b42f), TOBN(0x6bac55e7, 0x8c60ddc4),
-+     TOBN(0xb5cd811e, 0x94dea0f6), TOBN(0x259ecae4, 0xe18cc1a3),
-+     TOBN(0x6a0e836e, 0x15e660f8), TOBN(0x6c639ea6, 0x0e02bff2),
-+     TOBN(0x8721b8cb, 0x7e1026fd), TOBN(0x9e73b50b, 0x63261942),
-+     TOBN(0xb8c70974, 0x77f01da3), TOBN(0x1839e6a6, 0x8268f57f),
-+     TOBN(0x571b9415, 0x5150b805), TOBN(0x1892389e, 0xf92c7097),
-+     TOBN(0x8d69c18e, 0x4a084b95), TOBN(0x7014c512, 0xbe5b495c),
-+     TOBN(0x4780db36, 0x1b07523c), TOBN(0x2f6219ce, 0x2c1c64fa),
-+     TOBN(0xc38b81b0, 0x602c105a), TOBN(0xab4f4f20, 0x5dc8e360),
-+     TOBN(0x20d3c982, 0xcf7d62d2), TOBN(0x1f36e29d, 0x23ba8150),
-+     TOBN(0x48ae0bf0, 0x92763f9e), TOBN(0x7a527e6b, 0x1d3a7007),
-+     TOBN(0xb4a89097, 0x581a85e3), TOBN(0x1f1a520f, 0xdc158be5),
-+     TOBN(0xf98db37d, 0x167d726e), TOBN(0x8802786e, 0x1113e862)}
-+    ,
-+    {TOBN(0xefb2149e, 0x36f09ab0), TOBN(0x03f163ca, 0x4a10bb5b),
-+     TOBN(0xd0297045, 0x06e20998), TOBN(0x56f0af00, 0x1b5a3bab),
-+     TOBN(0x7af4cfec, 0x70880e0d), TOBN(0x7332a66f, 0xbe3d913f),
-+     TOBN(0x32e6c84a, 0x7eceb4bd), TOBN(0xedc4a79a, 0x9c228f55),
-+     TOBN(0xc37c7dd0, 0xc55c4496), TOBN(0xa6a96357, 0x25bbabd2),
-+     TOBN(0x5b7e63f2, 0xadd7f363), TOBN(0x9dce3782, 0x2e73f1df),
-+     TOBN(0xe1e5a16a, 0xb2b91f71), TOBN(0xe4489823, 0x5ba0163c),
-+     TOBN(0xf2759c32, 0xf6e515ad), TOBN(0xa5e2f1f8, 0x8615eecf),
-+     TOBN(0x74519be7, 0xabded551), TOBN(0x03d358b8, 0xc8b74410),
-+     TOBN(0x4d00b10b, 0x0e10d9a9), TOBN(0x6392b0b1, 0x28da52b7),
-+     TOBN(0x6744a298, 0x0b75c904), TOBN(0xc305b0ae, 0xa8f7f96c),
-+     TOBN(0x042e421d, 0x182cf932), TOBN(0xf6fc5d50, 0x9e4636ca),
-+     TOBN(0x795847c9, 0xd64cc78c), TOBN(0x6c50621b, 0x9b6cb27b),
-+     TOBN(0x07099bf8, 0xdf8022ab), TOBN(0x48f862eb, 0xc04eda1d),
-+     TOBN(0xd12732ed, 0xe1603c16), TOBN(0x19a80e0f, 0x5c9a9450),
-+     TOBN(0xe2257f54, 0xb429b4fc), TOBN(0x66d3b2c6, 0x45460515),
-+     TOBN(0x6ca4f87e, 0x822e37be), TOBN(0x73f237b4, 0x253bda4e),
-+     TOBN(0xf747f3a2, 0x41190aeb), TOBN(0xf06fa36f, 0x804cf284),
-+     TOBN(0x0a6bbb6e, 0xfc621c12), TOBN(0x5d624b64, 0x40b80ec6),
-+     TOBN(0x4b072425, 0x7ba556f3), TOBN(0x7fa0c354, 0x3e2d20a8),
-+     TOBN(0xe921fa31, 0xe3229d41), TOBN(0xa929c652, 0x94531bd4),
-+     TOBN(0x84156027, 0xa6d38209), TOBN(0xf3d69f73, 0x6bdb97bd),
-+     TOBN(0x8906d19a, 0x16833631), TOBN(0x68a34c2e, 0x03d51be3),
-+     TOBN(0xcb59583b, 0x0e511cd8), TOBN(0x99ce6bfd, 0xfdc132a8),
-+     TOBN(0x3facdaaa, 0xffcdb463), TOBN(0x658bbc1a, 0x34a38b08),
-+     TOBN(0x12a801f8, 0xf1a9078d), TOBN(0x1567bcf9, 0x6ab855de),
-+     TOBN(0xe08498e0, 0x3572359b), TOBN(0xcf0353e5, 0x8659e68b),
-+     TOBN(0xbb86e9c8, 0x7d23807c), TOBN(0xbc08728d, 0x2198e8a2),
-+     TOBN(0x8de2b7bc, 0x453cadd6), TOBN(0x203900a7, 0xbc0bc1f8),
-+     TOBN(0xbcd86e47, 0xa6abd3af), TOBN(0x911cac12, 0x8502effb),
-+     TOBN(0x2d550242, 0xec965469), TOBN(0x0e9f7692, 0x29e0017e),
-+     TOBN(0x633f078f, 0x65979885), TOBN(0xfb87d449, 0x4cf751ef),
-+     TOBN(0xe1790e4b, 0xfc25419a), TOBN(0x36467203, 0x4bff3cfd),
-+     TOBN(0xc8db6386, 0x25b6e83f), TOBN(0x6cc69f23, 0x6cad6fd2),
-+     TOBN(0x0219e45a, 0x6bc68bb9), TOBN(0xe43d79b6, 0x297f7334),
-+     TOBN(0x7d445368, 0x465dc97c), TOBN(0x4b9eea32, 0x2a0b949a),
-+     TOBN(0x1b96c6ba, 0x6102d021), TOBN(0xeaafac78, 0x2f4461ea),
-+     TOBN(0xd4b85c41, 0xc49f19a8), TOBN(0x275c28e4, 0xcf538875),
-+     TOBN(0x35451a9d, 0xdd2e54e0), TOBN(0x6991adb5, 0x0605618b),
-+     TOBN(0x5b8b4bcd, 0x7b36cd24), TOBN(0x372a4f8c, 0x56f37216),
-+     TOBN(0xc890bd73, 0xa6a5da60), TOBN(0x6f083da0, 0xdc4c9ff0),
-+     TOBN(0xf4e14d94, 0xf0536e57), TOBN(0xf9ee1eda, 0xaaec8243),
-+     TOBN(0x571241ec, 0x8bdcf8e7), TOBN(0xa5db8271, 0x0b041e26),
-+     TOBN(0x9a0b9a99, 0xe3fff040), TOBN(0xcaaf21dd, 0x7c271202),
-+     TOBN(0xb4e2b2e1, 0x4f0dd2e8), TOBN(0xe77e7c4f, 0x0a377ac7),
-+     TOBN(0x69202c3f, 0x0d7a2198), TOBN(0xf759b7ff, 0x28200eb8),
-+     TOBN(0xc87526ed, 0xdcfe314e), TOBN(0xeb84c524, 0x53d5cf99),
-+     TOBN(0xb1b52ace, 0x515138b6), TOBN(0x5aa7ff8c, 0x23fca3f4),
-+     TOBN(0xff0b13c3, 0xb9791a26), TOBN(0x960022da, 0xcdd58b16),
-+     TOBN(0xdbd55c92, 0x57aad2de), TOBN(0x3baaaaa3, 0xf30fe619),
-+     TOBN(0x9a4b2346, 0x0d881efd), TOBN(0x506416c0, 0x46325e2a),
-+     TOBN(0x91381e76, 0x035c18d4), TOBN(0xb3bb68be, 0xf27817b0),
-+     TOBN(0x15bfb8bf, 0x5116f937), TOBN(0x7c64a586, 0xc1268943),
-+     TOBN(0x71e25cc3, 0x8419a2c8), TOBN(0x9fd6b0c4, 0x8335f463),
-+     TOBN(0x4bf0ba3c, 0xe8ee0e0e), TOBN(0x6f6fba60, 0x298c21fa),
-+     TOBN(0x57d57b39, 0xae66bee0), TOBN(0x292d5130, 0x22672544),
-+     TOBN(0xf451105d, 0xbab093b3), TOBN(0x012f59b9, 0x02839986),
-+     TOBN(0x8a915802, 0x3474a89c), TOBN(0x048c919c, 0x2de03e97),
-+     TOBN(0xc476a2b5, 0x91071cd5), TOBN(0x791ed89a, 0x034970a5),
-+     TOBN(0x89bd9042, 0xe1b7994b), TOBN(0x8eaf5179, 0xa1057ffd),
-+     TOBN(0x6066e2a2, 0xd551ee10), TOBN(0x87a8f1d8, 0x727e09a6),
-+     TOBN(0x00d08bab, 0x2c01148d), TOBN(0x6da8e4f1, 0x424f33fe),
-+     TOBN(0x466d17f0, 0xcf9a4e71), TOBN(0xff502010, 0x3bf5cb19),
-+     TOBN(0xdccf97d8, 0xd062ecc0), TOBN(0x80c0d9af, 0x81d80ac4),
-+     TOBN(0xe87771d8, 0x033f2876), TOBN(0xb0186ec6, 0x7d5cc3db),
-+     TOBN(0x58e8bb80, 0x3bc9bc1d), TOBN(0x4d1395cc, 0x6f6ef60e),
-+     TOBN(0xa73c62d6, 0x186244a0), TOBN(0x918e5f23, 0x110a5b53),
-+     TOBN(0xed4878ca, 0x741b7eab), TOBN(0x3038d71a, 0xdbe03e51),
-+     TOBN(0x840204b7, 0xa93c3246), TOBN(0x21ab6069, 0xa0b9b4cd),
-+     TOBN(0xf5fa6e2b, 0xb1d64218), TOBN(0x1de6ad0e, 0xf3d56191),
-+     TOBN(0x570aaa88, 0xff1929c7), TOBN(0xc6df4c6b, 0x640e87b5),
-+     TOBN(0xde8a74f2, 0xc65f0ccc), TOBN(0x8b972fd5, 0xe6f6cc01),
-+     TOBN(0x3fff36b6, 0x0b846531), TOBN(0xba7e45e6, 0x10a5e475),
-+     TOBN(0x84a1d10e, 0x4145b6c5), TOBN(0xf1f7f91a, 0x5e046d9d),
-+     TOBN(0x0317a692, 0x44de90d7), TOBN(0x951a1d4a, 0xf199c15e),
-+     TOBN(0x91f78046, 0xc9d73deb), TOBN(0x74c82828, 0xfab8224f),
-+     TOBN(0xaa6778fc, 0xe7560b90), TOBN(0xb4073e61, 0xa7e824ce),
-+     TOBN(0xff0d693c, 0xd642eba8), TOBN(0x7ce2e57a, 0x5dccef38),
-+     TOBN(0x89c2c789, 0x1df1ad46), TOBN(0x83a06922, 0x098346fd),
-+     TOBN(0x2d715d72, 0xda2fc177), TOBN(0x7b6dd71d, 0x85b6cf1d),
-+     TOBN(0xc60a6d0a, 0x73fa9cb0), TOBN(0xedd3992e, 0x328bf5a9),
-+     TOBN(0xc380ddd0, 0x832c8c82), TOBN(0xd182d410, 0xa2a0bf50),
-+     TOBN(0x7d9d7438, 0xd9a528db), TOBN(0xe8b1a0e9, 0xcaf53994),
-+     TOBN(0xddd6e5fe, 0x0e19987c), TOBN(0xacb8df03, 0x190b059d),
-+     TOBN(0x53703a32, 0x8300129f), TOBN(0x1f637662, 0x68c43bfd),
-+     TOBN(0xbcbd1913, 0x00e54051), TOBN(0x812fcc62, 0x7bf5a8c5),
-+     TOBN(0x3f969d5f, 0x29fb85da), TOBN(0x72f4e00a, 0x694759e8),
-+     TOBN(0x426b6e52, 0x790726b7), TOBN(0x617bbc87, 0x3bdbb209),
-+     TOBN(0x511f8bb9, 0x97aee317), TOBN(0x812a4096, 0xe81536a8),
-+     TOBN(0x137dfe59, 0x3ac09b9b), TOBN(0x0682238f, 0xba8c9a7a),
-+     TOBN(0x7072ead6, 0xaeccb4bd), TOBN(0x6a34e9aa, 0x692ba633),
-+     TOBN(0xc82eaec2, 0x6fff9d33), TOBN(0xfb753512, 0x1d4d2b62),
-+     TOBN(0x1a0445ff, 0x1d7aadab), TOBN(0x65d38260, 0xd5f6a67c),
-+     TOBN(0x6e62fb08, 0x91cfb26f), TOBN(0xef1e0fa5, 0x5c7d91d6),
-+     TOBN(0x47e7c7ba, 0x33db72cd), TOBN(0x017cbc09, 0xfa7c74b2),
-+     TOBN(0x3c931590, 0xf50a503c), TOBN(0xcac54f60, 0x616baa42),
-+     TOBN(0x9b6cd380, 0xb2369f0f), TOBN(0x97d3a70d, 0x23c76151),
-+     TOBN(0x5f9dd6fc, 0x9862a9c6), TOBN(0x044c4ab2, 0x12312f51),
-+     TOBN(0x035ea0fd, 0x834a2ddc), TOBN(0x49e6b862, 0xcc7b826d),
-+     TOBN(0xb03d6883, 0x62fce490), TOBN(0x62f2497a, 0xb37e36e9),
-+     TOBN(0x04b005b6, 0xc6458293), TOBN(0x36bb5276, 0xe8d10af7),
-+     TOBN(0xacf2dc13, 0x8ee617b8), TOBN(0x470d2d35, 0xb004b3d4),
-+     TOBN(0x06790832, 0xfeeb1b77), TOBN(0x2bb75c39, 0x85657f9c),
-+     TOBN(0xd70bd4ed, 0xc0f60004), TOBN(0xfe797ecc, 0x219b018b),
-+     TOBN(0x9b5bec2a, 0x753aebcc), TOBN(0xdaf9f3dc, 0xc939eca5),
-+     TOBN(0xd6bc6833, 0xd095ad09), TOBN(0x98abdd51, 0xdaa4d2fc),
-+     TOBN(0xd9840a31, 0x8d168be5), TOBN(0xcf7c10e0, 0x2325a23c),
-+     TOBN(0xa5c02aa0, 0x7e6ecfaf), TOBN(0x2462e7e6, 0xb5bfdf18),
-+     TOBN(0xab2d8a8b, 0xa0cc3f12), TOBN(0x68dd485d, 0xbc672a29),
-+     TOBN(0x72039752, 0x596f2cd3), TOBN(0x5d3eea67, 0xa0cf3d8d),
-+     TOBN(0x810a1a81, 0xe6602671), TOBN(0x8f144a40, 0x14026c0c),
-+     TOBN(0xbc753a6d, 0x76b50f85), TOBN(0xc4dc21e8, 0x645cd4a4),
-+     TOBN(0xc5262dea, 0x521d0378), TOBN(0x802b8e0e, 0x05011c6f),
-+     TOBN(0x1ba19cbb, 0x0b4c19ea), TOBN(0x21db64b5, 0xebf0aaec),
-+     TOBN(0x1f394ee9, 0x70342f9d), TOBN(0x93a10aee, 0x1bc44a14),
-+     TOBN(0xa7eed31b, 0x3efd0baa), TOBN(0x6e7c824e, 0x1d154e65),
-+     TOBN(0xee23fa81, 0x9966e7ee), TOBN(0x64ec4aa8, 0x05b7920d),
-+     TOBN(0x2d44462d, 0x2d90aad4), TOBN(0xf44dd195, 0xdf277ad5),
-+     TOBN(0x8d6471f1, 0xbb46b6a1), TOBN(0x1e65d313, 0xfd885090),
-+     TOBN(0x33a800f5, 0x13a977b4), TOBN(0xaca9d721, 0x0797e1ef),
-+     TOBN(0x9a5a85a0, 0xfcff6a17), TOBN(0x9970a3f3, 0x1eca7cee),
-+     TOBN(0xbb9f0d6b, 0xc9504be3), TOBN(0xe0c504be, 0xadd24ee2),
-+     TOBN(0x7e09d956, 0x77fcc2f4), TOBN(0xef1a5227, 0x65bb5fc4),
-+     TOBN(0x145d4fb1, 0x8b9286aa), TOBN(0x66fd0c5d, 0x6649028b),
-+     TOBN(0x98857ceb, 0x1bf4581c), TOBN(0xe635e186, 0xaca7b166),
-+     TOBN(0x278ddd22, 0x659722ac), TOBN(0xa0903c4c, 0x1db68007),
-+     TOBN(0x366e4589, 0x48f21402), TOBN(0x31b49c14, 0xb96abda2),
-+     TOBN(0x329c4b09, 0xe0403190), TOBN(0x97197ca3, 0xd29f43fe),
-+     TOBN(0x8073dd1e, 0x274983d8), TOBN(0xda1a3bde, 0x55717c8f),
-+     TOBN(0xfd3d4da2, 0x0361f9d1), TOBN(0x1332d081, 0x4c7de1ce),
-+     TOBN(0x9b7ef7a3, 0xaa6d0e10), TOBN(0x17db2e73, 0xf54f1c4a),
-+     TOBN(0xaf3dffae, 0x4cd35567), TOBN(0xaaa2f406, 0xe56f4e71),
-+     TOBN(0x8966759e, 0x7ace3fc7), TOBN(0x9594eacf, 0x45a8d8c6),
-+     TOBN(0x8de3bd8b, 0x91834e0e), TOBN(0xafe4ca53, 0x548c0421),
-+     TOBN(0xfdd7e856, 0xe6ee81c6), TOBN(0x8f671beb, 0x6b891a3a),
-+     TOBN(0xf7a58f2b, 0xfae63829), TOBN(0x9ab186fb, 0x9c11ac9f),
-+     TOBN(0x8d6eb369, 0x10b5be76), TOBN(0x046b7739, 0xfb040bcd),
-+     TOBN(0xccb4529f, 0xcb73de88), TOBN(0x1df0fefc, 0xcf26be03),
-+     TOBN(0xad7757a6, 0xbcfcd027), TOBN(0xa8786c75, 0xbb3165ca),
-+     TOBN(0xe9db1e34, 0x7e99a4d9), TOBN(0x99ee86df, 0xb06c504b),
-+     TOBN(0x5b7c2ddd, 0xc15c9f0a), TOBN(0xdf87a734, 0x4295989e),
-+     TOBN(0x59ece47c, 0x03d08fda), TOBN(0xb074d3dd, 0xad5fc702),
-+     TOBN(0x20407903, 0x51a03776), TOBN(0x2bb1f77b, 0x2a608007),
-+     TOBN(0x25c58f4f, 0xe1153185), TOBN(0xe6df62f6, 0x766e6447),
-+     TOBN(0xefb3d1be, 0xed51275a), TOBN(0x5de47dc7, 0x2f0f483f),
-+     TOBN(0x7932d98e, 0x97c2bedf), TOBN(0xd5c11927, 0x0219f8a1),
-+     TOBN(0x9d751200, 0xa73a294e), TOBN(0x5f88434a, 0x9dc20172),
-+     TOBN(0xd28d9fd3, 0xa26f506a), TOBN(0xa890cd31, 0x9d1dcd48),
-+     TOBN(0x0aebaec1, 0x70f4d3b4), TOBN(0xfd1a1369, 0x0ffc8d00),
-+     TOBN(0xb9d9c240, 0x57d57838), TOBN(0x45929d26, 0x68bac361),
-+     TOBN(0x5a2cd060, 0x25b15ca6), TOBN(0x4b3c83e1, 0x6e474446),
-+     TOBN(0x1aac7578, 0xee1e5134), TOBN(0xa418f5d6, 0xc91e2f41),
-+     TOBN(0x6936fc8a, 0x213ed68b), TOBN(0x860ae7ed, 0x510a5224),
-+     TOBN(0x63660335, 0xdef09b53), TOBN(0x641b2897, 0xcd79c98d),
-+     TOBN(0x29bd38e1, 0x01110f35), TOBN(0x79c26f42, 0x648b1937),
-+     TOBN(0x64dae519, 0x9d9164f4), TOBN(0xd85a2310, 0x0265c273),
-+     TOBN(0x7173dd5d, 0x4b07e2b1), TOBN(0xd144c4cb, 0x8d9ea221),
-+     TOBN(0xe8b04ea4, 0x1105ab14), TOBN(0x92dda542, 0xfe80d8f1),
-+     TOBN(0xe9982fa8, 0xcf03dce6), TOBN(0x8b5ea965, 0x1a22cffc),
-+     TOBN(0xf7f4ea7f, 0x3fad88c4), TOBN(0x62db773e, 0x6a5ba95c),
-+     TOBN(0xd20f02fb, 0x93f24567), TOBN(0xfd46c69a, 0x315257ca),
-+     TOBN(0x0ac74cc7, 0x8bcab987), TOBN(0x46f31c01, 0x5ceca2f5),
-+     TOBN(0x40aedb59, 0x888b219e), TOBN(0xe50ecc37, 0xe1fccd02),
-+     TOBN(0x1bcd9dad, 0x911f816c), TOBN(0x583cc1ec, 0x8db9b00c),
-+     TOBN(0xf3cd2e66, 0xa483bf11), TOBN(0xfa08a6f5, 0xb1b2c169),
-+     TOBN(0xf375e245, 0x4be9fa28), TOBN(0x99a7ffec, 0x5b6d011f),
-+     TOBN(0x6a3ebddb, 0xc4ae62da), TOBN(0x6cea00ae, 0x374aef5d),
-+     TOBN(0xab5fb98d, 0x9d4d05bc), TOBN(0x7cba1423, 0xd560f252),
-+     TOBN(0x49b2cc21, 0x208490de), TOBN(0x1ca66ec3, 0xbcfb2879),
-+     TOBN(0x7f1166b7, 0x1b6fb16f), TOBN(0xfff63e08, 0x65fe5db3),
-+     TOBN(0xb8345abe, 0x8b2610be), TOBN(0xb732ed80, 0x39de3df4),
-+     TOBN(0x0e24ed50, 0x211c32b4), TOBN(0xd10d8a69, 0x848ff27d),
-+     TOBN(0xc1074398, 0xed4de248), TOBN(0xd7cedace, 0x10488927),
-+     TOBN(0xa4aa6bf8, 0x85673e13), TOBN(0xb46bae91, 0x6daf30af),
-+     TOBN(0x07088472, 0xfcef7ad8), TOBN(0x61151608, 0xd4b35e97),
-+     TOBN(0xbcfe8f26, 0xdde29986), TOBN(0xeb84c4c7, 0xd5a34c79),
-+     TOBN(0xc1eec55c, 0x164e1214), TOBN(0x891be86d, 0xa147bb03),
-+     TOBN(0x9fab4d10, 0x0ba96835), TOBN(0xbf01e9b8, 0xa5c1ae9f),
-+     TOBN(0x6b4de139, 0xb186ebc0), TOBN(0xd5c74c26, 0x85b91bca),
-+     TOBN(0x5086a99c, 0xc2d93854), TOBN(0xeed62a7b, 0xa7a9dfbc),
-+     TOBN(0x8778ed6f, 0x76b7618a), TOBN(0xbff750a5, 0x03b66062),
-+     TOBN(0x4cb7be22, 0xb65186db), TOBN(0x369dfbf0, 0xcc3a6d13),
-+     TOBN(0xc7dab26c, 0x7191a321), TOBN(0x9edac3f9, 0x40ed718e),
-+     TOBN(0xbc142b36, 0xd0cfd183), TOBN(0xc8af82f6, 0x7c991693),
-+     TOBN(0xb3d1e4d8, 0x97ce0b2a), TOBN(0xe6d7c87f, 0xc3a55cdf),
-+     TOBN(0x35846b95, 0x68b81afe), TOBN(0x018d12af, 0xd3c239d8),
-+     TOBN(0x2b2c6208, 0x01206e15), TOBN(0xe0e42453, 0xa3b882c6),
-+     TOBN(0x854470a3, 0xa50162d5), TOBN(0x08157478, 0x7017a62a),
-+     TOBN(0x18bd3fb4, 0x820357c7), TOBN(0x992039ae, 0x6f1458ad),
-+     TOBN(0x9a1df3c5, 0x25b44aa1), TOBN(0x2d780357, 0xed3d5281),
-+     TOBN(0x58cf7e4d, 0xc77ad4d4), TOBN(0xd49a7998, 0xf9df4fc4),
-+     TOBN(0x4465a8b5, 0x1d71205e), TOBN(0xa0ee0ea6, 0x649254aa),
-+     TOBN(0x4b5eeecf, 0xab7bd771), TOBN(0x6c873073, 0x35c262b9),
-+     TOBN(0xdc5bd648, 0x3c9d61e7), TOBN(0x233d6d54, 0x321460d2),
-+     TOBN(0xd20c5626, 0xfc195bcc), TOBN(0x25445958, 0x04d78b63),
-+     TOBN(0xe03fcb3d, 0x17ec8ef3), TOBN(0x54b690d1, 0x46b8f781),
-+     TOBN(0x82fa2c8a, 0x21230646), TOBN(0xf51aabb9, 0x084f418c),
-+     TOBN(0xff4fbec1, 0x1a30ba43), TOBN(0x6a5acf73, 0x743c9df7),
-+     TOBN(0x1da2b357, 0xd635b4d5), TOBN(0xc3de68dd, 0xecd5c1da),
-+     TOBN(0xa689080b, 0xd61af0dd), TOBN(0xdea5938a, 0xd665bf99),
-+     TOBN(0x0231d71a, 0xfe637294), TOBN(0x01968aa6, 0xa5a81cd8),
-+     TOBN(0x11252d50, 0x048e63b5), TOBN(0xc446bc52, 0x6ca007e9),
-+     TOBN(0xef8c50a6, 0x96d6134b), TOBN(0x9361fbf5, 0x9e09a05c),
-+     TOBN(0xf17f85a6, 0xdca3291a), TOBN(0xb178d548, 0xff251a21),
-+     TOBN(0x87f6374b, 0xa4df3915), TOBN(0x566ce1bf, 0x2fd5d608),
-+     TOBN(0x425cba4d, 0x7de35102), TOBN(0x6b745f8f, 0x58c5d5e2),
-+     TOBN(0x88402af6, 0x63122edf), TOBN(0x3190f9ed, 0x3b989a89),
-+     TOBN(0x4ad3d387, 0xebba3156), TOBN(0xef385ad9, 0xc7c469a5),
-+     TOBN(0xb08281de, 0x3f642c29), TOBN(0x20be0888, 0x910ffb88),
-+     TOBN(0xf353dd4a, 0xd5292546), TOBN(0x3f1627de, 0x8377a262),
-+     TOBN(0xa5faa013, 0xeefcd638), TOBN(0x8f3bf626, 0x74cc77c3),
-+     TOBN(0x32618f65, 0xa348f55e), TOBN(0x5787c0dc, 0x9fefeb9e),
-+     TOBN(0xf1673aa2, 0xd9a23e44), TOBN(0x88dfa993, 0x4e10690d),
-+     TOBN(0x1ced1b36, 0x2bf91108), TOBN(0x9193ceca, 0x3af48649),
-+     TOBN(0xfb34327d, 0x2d738fc5), TOBN(0x6697b037, 0x975fee6c),
-+     TOBN(0x2f485da0, 0xc04079a5), TOBN(0x2cdf5735, 0x2feaa1ac),
-+     TOBN(0x76944420, 0xbd55659e), TOBN(0x7973e32b, 0x4376090c),
-+     TOBN(0x86bb4fe1, 0x163b591a), TOBN(0x10441aed, 0xc196f0ca),
-+     TOBN(0x3b431f4a, 0x045ad915), TOBN(0x6c11b437, 0xa4afacb1),
-+     TOBN(0x30b0c7db, 0x71fdbbd8), TOBN(0xb642931f, 0xeda65acd),
-+     TOBN(0x4baae6e8, 0x9c92b235), TOBN(0xa73bbd0e, 0x6b3993a1),
-+     TOBN(0xd06d60ec, 0x693dd031), TOBN(0x03cab91b, 0x7156881c),
-+     TOBN(0xd615862f, 0x1db3574b), TOBN(0x485b0185, 0x64bb061a),
-+     TOBN(0x27434988, 0xa0181e06), TOBN(0x2cd61ad4, 0xc1c0c757),
-+     TOBN(0x3effed5a, 0x2ff9f403), TOBN(0x8dc98d8b, 0x62239029),
-+     TOBN(0x2206021e, 0x1f17b70d), TOBN(0xafbec0ca, 0xbf510015),
-+     TOBN(0x9fed7164, 0x80130dfa), TOBN(0x306dc2b5, 0x8a02dcf5),
-+     TOBN(0x48f06620, 0xfeb10fc0), TOBN(0x78d1e1d5, 0x5a57cf51),
-+     TOBN(0xadef8c5a, 0x192ef710), TOBN(0x88afbd4b, 0x3b7431f9),
-+     TOBN(0x7e1f7407, 0x64250c9e), TOBN(0x6e31318d, 0xb58bec07),
-+     TOBN(0xfd4fc4b8, 0x24f89b4e), TOBN(0x65a5dd88, 0x48c36a2a),
-+     TOBN(0x4f1eccff, 0xf024baa7), TOBN(0x22a21cf2, 0xcba94650),
-+     TOBN(0x95d29dee, 0x42a554f7), TOBN(0x828983a5, 0x002ec4ba),
-+     TOBN(0x8112a1f7, 0x8badb73d), TOBN(0x79ea8897, 0xa27c1839),
-+     TOBN(0x8969a5a7, 0xd065fd83), TOBN(0xf49af791, 0xb262a0bc),
-+     TOBN(0xfcdea8b6, 0xaf2b5127), TOBN(0x10e913e1, 0x564c2dbc),
-+     TOBN(0x51239d14, 0xbc21ef51), TOBN(0xe51c3ceb, 0x4ce57292),
-+     TOBN(0x795ff068, 0x47bbcc3b), TOBN(0x86b46e1e, 0xbd7e11e6),
-+     TOBN(0x0ea6ba23, 0x80041ef4), TOBN(0xd72fe505, 0x6262342e),
-+     TOBN(0x8abc6dfd, 0x31d294d4), TOBN(0xbbe017a2, 0x1278c2c9),
-+     TOBN(0xb1fcfa09, 0xb389328a), TOBN(0x322fbc62, 0xd01771b5),
-+     TOBN(0x04c0d063, 0x60b045bf), TOBN(0xdb652edc, 0x10e52d01),
-+     TOBN(0x50ef932c, 0x03ec6627), TOBN(0xde1b3b2d, 0xc1ee50e3),
-+     TOBN(0x5ab7bdc5, 0xdc37a90d), TOBN(0xfea67213, 0x31e33a96),
-+     TOBN(0x6482b5cb, 0x4f2999aa), TOBN(0x38476cc6, 0xb8cbf0dd),
-+     TOBN(0x93ebfacb, 0x173405bb), TOBN(0x15cdafe7, 0xe52369ec),
-+     TOBN(0xd42d5ba4, 0xd935b7db), TOBN(0x648b6004, 0x1c99a4cd),
-+     TOBN(0x785101bd, 0xa3b5545b), TOBN(0x4bf2c38a, 0x9dd67faf),
-+     TOBN(0xb1aadc63, 0x4442449c), TOBN(0xe0e9921a, 0x33ad4fb8),
-+     TOBN(0x5c552313, 0xaa686d82), TOBN(0xdee635fa, 0x465d866c),
-+     TOBN(0xbc3c224a, 0x18ee6e8a), TOBN(0xeed748a6, 0xed42e02f),
-+     TOBN(0xe70f930a, 0xd474cd08), TOBN(0x774ea6ec, 0xfff24adf),
-+     TOBN(0x03e2de1c, 0xf3480d4a), TOBN(0xf0d8edc7, 0xbc8acf1a),
-+     TOBN(0xf23e3303, 0x68295a9c), TOBN(0xfadd5f68, 0xc546a97d),
-+     TOBN(0x895597ad, 0x96f8acb1), TOBN(0xbddd49d5, 0x671bdae2),
-+     TOBN(0x16fcd528, 0x21dd43f4), TOBN(0xa5a45412, 0x6619141a)}
-+    ,
-+    {TOBN(0x8ce9b6bf, 0xc360e25a), TOBN(0xe6425195, 0x075a1a78),
-+     TOBN(0x9dc756a8, 0x481732f4), TOBN(0x83c0440f, 0x5432b57a),
-+     TOBN(0xc670b3f1, 0xd720281f), TOBN(0x2205910e, 0xd135e051),
-+     TOBN(0xded14b0e, 0xdb052be7), TOBN(0x697b3d27, 0xc568ea39),
-+     TOBN(0x2e599b9a, 0xfb3ff9ed), TOBN(0x28c2e0ab, 0x17f6515c),
-+     TOBN(0x1cbee4fd, 0x474da449), TOBN(0x071279a4, 0x4f364452),
-+     TOBN(0x97abff66, 0x01fbe855), TOBN(0x3ee394e8, 0x5fda51c4),
-+     TOBN(0x190385f6, 0x67597c0b), TOBN(0x6e9fccc6, 0xa27ee34b),
-+     TOBN(0x0b89de93, 0x14092ebb), TOBN(0xf17256bd, 0x428e240c),
-+     TOBN(0xcf89a7f3, 0x93d2f064), TOBN(0x4f57841e, 0xe1ed3b14),
-+     TOBN(0x4ee14405, 0xe708d855), TOBN(0x856aae72, 0x03f1c3d0),
-+     TOBN(0xc8e5424f, 0xbdd7eed5), TOBN(0x3333e4ef, 0x73ab4270),
-+     TOBN(0x3bc77ade, 0xdda492f8), TOBN(0xc11a3aea, 0x78297205),
-+     TOBN(0x5e89a3e7, 0x34931b4c), TOBN(0x17512e2e, 0x9f5694bb),
-+     TOBN(0x5dc349f3, 0x177bf8b6), TOBN(0x232ea4ba, 0x08c7ff3e),
-+     TOBN(0x9c4f9d16, 0xf511145d), TOBN(0xccf109a3, 0x33b379c3),
-+     TOBN(0xe75e7a88, 0xa1f25897), TOBN(0x7ac6961f, 0xa1b5d4d8),
-+     TOBN(0xe3e10773, 0x08f3ed5c), TOBN(0x208a54ec, 0x0a892dfb),
-+     TOBN(0xbe826e19, 0x78660710), TOBN(0x0cf70a97, 0x237df2c8),
-+     TOBN(0x418a7340, 0xed704da5), TOBN(0xa3eeb9a9, 0x08ca33fd),
-+     TOBN(0x49d96233, 0x169bca96), TOBN(0x04d286d4, 0x2da6aafb),
-+     TOBN(0xc09606ec, 0xa0c2fa94), TOBN(0x8869d0d5, 0x23ff0fb3),
-+     TOBN(0xa99937e5, 0xd0150d65), TOBN(0xa92e2503, 0x240c14c9),
-+     TOBN(0x656bf945, 0x108e2d49), TOBN(0x152a733a, 0xa2f59e2b),
-+     TOBN(0xb4323d58, 0x8434a920), TOBN(0xc0af8e93, 0x622103c5),
-+     TOBN(0x667518ef, 0x938dbf9a), TOBN(0xa1843073, 0x83a9cdf2),
-+     TOBN(0x350a94aa, 0x5447ab80), TOBN(0xe5e5a325, 0xc75a3d61),
-+     TOBN(0x74ba507f, 0x68411a9e), TOBN(0x10581fc1, 0x594f70c5),
-+     TOBN(0x60e28570, 0x80eb24a9), TOBN(0x7bedfb4d, 0x488e0cfd),
-+     TOBN(0x721ebbd7, 0xc259cdb8), TOBN(0x0b0da855, 0xbc6390a9),
-+     TOBN(0x2b4d04db, 0xde314c70), TOBN(0xcdbf1fbc, 0x6c32e846),
-+     TOBN(0x33833eab, 0xb162fc9e), TOBN(0x9939b48b, 0xb0dd3ab7),
-+     TOBN(0x5aaa98a7, 0xcb0c9c8c), TOBN(0x75105f30, 0x81c4375c),
-+     TOBN(0xceee5057, 0x5ef1c90f), TOBN(0xb31e065f, 0xc23a17bf),
-+     TOBN(0x5364d275, 0xd4b6d45a), TOBN(0xd363f3ad, 0x62ec8996),
-+     TOBN(0xb5d21239, 0x4391c65b), TOBN(0x84564765, 0xebb41b47),
-+     TOBN(0x20d18ecc, 0x37107c78), TOBN(0xacff3b6b, 0x570c2a66),
-+     TOBN(0x22f975d9, 0x9bd0d845), TOBN(0xef0a0c46, 0xba178fa0),
-+     TOBN(0x1a419651, 0x76b6028e), TOBN(0xc49ec674, 0x248612d4),
-+     TOBN(0x5b6ac4f2, 0x7338af55), TOBN(0x06145e62, 0x7bee5a36),
-+     TOBN(0x33e95d07, 0xe75746b5), TOBN(0x1c1e1f6d, 0xc40c78be),
-+     TOBN(0x967833ef, 0x222ff8e2), TOBN(0x4bedcf6a, 0xb49180ad),
-+     TOBN(0x6b37e9c1, 0x3d7a4c8a), TOBN(0x2748887c, 0x6ddfe760),
-+     TOBN(0xf7055123, 0xaa3a5bbc), TOBN(0x954ff225, 0x7bbb8e74),
-+     TOBN(0xc42b8ab1, 0x97c3dfb9), TOBN(0x55a549b0, 0xcf168154),
-+     TOBN(0xad6748e7, 0xc1b50692), TOBN(0x2775780f, 0x6fc5cbcb),
-+     TOBN(0x4eab80b8, 0xe1c9d7c8), TOBN(0x8c69dae1, 0x3fdbcd56),
-+     TOBN(0x47e6b4fb, 0x9969eace), TOBN(0x002f1085, 0xa705cb5a),
-+     TOBN(0x4e23ca44, 0x6d3fea55), TOBN(0xb4ae9c86, 0xf4810568),
-+     TOBN(0x47bfb91b, 0x2a62f27d), TOBN(0x60deb4c9, 0xd9bac28c),
-+     TOBN(0xa892d894, 0x7de6c34c), TOBN(0x4ee68259, 0x4494587d),
-+     TOBN(0x914ee14e, 0x1a3f8a5b), TOBN(0xbb113eaa, 0x28700385),
-+     TOBN(0x81ca03b9, 0x2115b4c9), TOBN(0x7c163d38, 0x8908cad1),
-+     TOBN(0xc912a118, 0xaa18179a), TOBN(0xe09ed750, 0x886e3081),
-+     TOBN(0xa676e3fa, 0x26f516ca), TOBN(0x753cacf7, 0x8e732f91),
-+     TOBN(0x51592aea, 0x833da8b4), TOBN(0xc626f42f, 0x4cbea8aa),
-+     TOBN(0xef9dc899, 0xa7b56eaf), TOBN(0x00c0e52c, 0x34ef7316),
-+     TOBN(0x5b1e4e24, 0xfe818a86), TOBN(0x9d31e20d, 0xc538be47),
-+     TOBN(0x22eb932d, 0x3ed68974), TOBN(0xe44bbc08, 0x7c4e87c4),
-+     TOBN(0x4121086e, 0x0dde9aef), TOBN(0x8e6b9cff, 0x134f4345),
-+     TOBN(0x96892c1f, 0x711b0eb9), TOBN(0xb905f2c8, 0x780ab954),
-+     TOBN(0xace26309, 0xa20792db), TOBN(0xec8ac9b3, 0x0684e126),
-+     TOBN(0x486ad8b6, 0xb40a2447), TOBN(0x60121fc1, 0x9fe3fb24),
-+     TOBN(0x5626fccf, 0x1a8e3b3f), TOBN(0x4e568622, 0x6ad1f394),
-+     TOBN(0xda7aae0d, 0x196aa5a1), TOBN(0xe0df8c77, 0x1041b5fb),
-+     TOBN(0x451465d9, 0x26b318b7), TOBN(0xc29b6e55, 0x7ab136e9),
-+     TOBN(0x2c2ab48b, 0x71148463), TOBN(0xb5738de3, 0x64454a76),
-+     TOBN(0x54ccf9a0, 0x5a03abe4), TOBN(0x377c0296, 0x0427d58e),
-+     TOBN(0x73f5f0b9, 0x2bb39c1f), TOBN(0x14373f2c, 0xe608d8c5),
-+     TOBN(0xdcbfd314, 0x00fbb805), TOBN(0xdf18fb20, 0x83afdcfb),
-+     TOBN(0x81a57f42, 0x42b3523f), TOBN(0xe958532d, 0x87f650fb),
-+     TOBN(0xaa8dc8b6, 0x8b0a7d7c), TOBN(0x1b75dfb7, 0x150166be),
-+     TOBN(0x90e4f7c9, 0x2d7d1413), TOBN(0x67e2d6b5, 0x9834f597),
-+     TOBN(0x4fd4f4f9, 0xa808c3e8), TOBN(0xaf8237e0, 0xd5281ec1),
-+     TOBN(0x25ab5fdc, 0x84687cee), TOBN(0xc5ded6b1, 0xa5b26c09),
-+     TOBN(0x8e4a5aec, 0xc8ea7650), TOBN(0x23b73e5c, 0x14cc417f),
-+     TOBN(0x2bfb4318, 0x3037bf52), TOBN(0xb61e6db5, 0x78c725d7),
-+     TOBN(0x8efd4060, 0xbbb3e5d7), TOBN(0x2e014701, 0xdbac488e),
-+     TOBN(0xac75cf9a, 0x360aa449), TOBN(0xb70cfd05, 0x79634d08),
-+     TOBN(0xa591536d, 0xfffb15ef), TOBN(0xb2c37582, 0xd07c106c),
-+     TOBN(0xb4293fdc, 0xf50225f9), TOBN(0xc52e175c, 0xb0e12b03),
-+     TOBN(0xf649c3ba, 0xd0a8bf64), TOBN(0x745a8fef, 0xeb8ae3c6),
-+     TOBN(0x30d7e5a3, 0x58321bc3), TOBN(0xb1732be7, 0x0bc4df48),
-+     TOBN(0x1f217993, 0xe9ea5058), TOBN(0xf7a71cde, 0x3e4fd745),
-+     TOBN(0x86cc533e, 0x894c5bbb), TOBN(0x6915c7d9, 0x69d83082),
-+     TOBN(0xa6aa2d05, 0x5815c244), TOBN(0xaeeee592, 0x49b22ce5),
-+     TOBN(0x89e39d13, 0x78135486), TOBN(0x3a275c1f, 0x16b76f2f),
-+     TOBN(0xdb6bcc1b, 0xe036e8f5), TOBN(0x4df69b21, 0x5e4709f5),
-+     TOBN(0xa188b250, 0x2d0f39aa), TOBN(0x622118bb, 0x15a85947),
-+     TOBN(0x2ebf520f, 0xfde0f4fa), TOBN(0xa40e9f29, 0x4860e539),
-+     TOBN(0x7b6a51eb, 0x22b57f0f), TOBN(0x849a33b9, 0x7e80644a),
-+     TOBN(0x50e5d16f, 0x1cf095fe), TOBN(0xd754b54e, 0xec55f002),
-+     TOBN(0x5cfbbb22, 0x236f4a98), TOBN(0x0b0c59e9, 0x066800bb),
-+     TOBN(0x4ac69a8f, 0x5a9a7774), TOBN(0x2b33f804, 0xd6bec948),
-+     TOBN(0xb3729295, 0x32e6c466), TOBN(0x68956d0f, 0x4e599c73),
-+     TOBN(0xa47a249f, 0x155c31cc), TOBN(0x24d80f0d, 0xe1ce284e),
-+     TOBN(0xcd821dfb, 0x988baf01), TOBN(0xe6331a7d, 0xdbb16647),
-+     TOBN(0x1eb8ad33, 0x094cb960), TOBN(0x593cca38, 0xc91bbca5),
-+     TOBN(0x384aac8d, 0x26567456), TOBN(0x40fa0309, 0xc04b6490),
-+     TOBN(0x97834cd6, 0xdab6c8f6), TOBN(0x68a7318d, 0x3f91e55f),
-+     TOBN(0xa00fd04e, 0xfc4d3157), TOBN(0xb56f8ab2, 0x2bf3bdea),
-+     TOBN(0x014f5648, 0x4fa57172), TOBN(0x948c5860, 0x450abdb3),
-+     TOBN(0x342b5df0, 0x0ebd4f08), TOBN(0x3e5168cd, 0x0e82938e),
-+     TOBN(0x7aedc1ce, 0xb0df5dd0), TOBN(0x6bbbc6d9, 0xe5732516),
-+     TOBN(0xc7bfd486, 0x605daaa6), TOBN(0x46fd72b7, 0xbb9a6c9e),
-+     TOBN(0xe4847fb1, 0xa124fb89), TOBN(0x75959cbd, 0xa2d8ffbc),
-+     TOBN(0x42579f65, 0xc8a588ee), TOBN(0x368c92e6, 0xb80b499d),
-+     TOBN(0xea4ef6cd, 0x999a5df1), TOBN(0xaa73bb7f, 0x936fe604),
-+     TOBN(0xf347a70d, 0x6457d188), TOBN(0x86eda86b, 0x8b7a388b),
-+     TOBN(0xb7cdff06, 0x0ccd6013), TOBN(0xbeb1b6c7, 0xd0053fb2),
-+     TOBN(0x0b022387, 0x99240a9f), TOBN(0x1bbb384f, 0x776189b2),
-+     TOBN(0x8695e71e, 0x9066193a), TOBN(0x2eb50097, 0x06ffac7e),
-+     TOBN(0x0654a9c0, 0x4a7d2caa), TOBN(0x6f3fb3d1, 0xa5aaa290),
-+     TOBN(0x835db041, 0xff476e8f), TOBN(0x540b8b0b, 0xc42295e4),
-+     TOBN(0xa5c73ac9, 0x05e214f5), TOBN(0x9a74075a, 0x56a0b638),
-+     TOBN(0x2e4b1090, 0xce9e680b), TOBN(0x57a5b479, 0x6b8d9afa),
-+     TOBN(0x0dca48e7, 0x26bfe65c), TOBN(0x097e391c, 0x7290c307),
-+     TOBN(0x683c462e, 0x6669e72e), TOBN(0xf505be1e, 0x062559ac),
-+     TOBN(0x5fbe3ea1, 0xe3a3035a), TOBN(0x6431ebf6, 0x9cd50da8),
-+     TOBN(0xfd169d5c, 0x1f6407f2), TOBN(0x8d838a95, 0x60fce6b8),
-+     TOBN(0x2a2bfa7f, 0x650006f0), TOBN(0xdfd7dad3, 0x50c0fbb2),
-+     TOBN(0x92452495, 0xccf9ad96), TOBN(0x183bf494, 0xd95635f9),
-+     TOBN(0x02d5df43, 0x4a7bd989), TOBN(0x505385cc, 0xa5431095),
-+     TOBN(0xdd98e67d, 0xfd43f53e), TOBN(0xd61e1a6c, 0x500c34a9),
-+     TOBN(0x5a4b46c6, 0x4a8a3d62), TOBN(0x8469c4d0, 0x247743d2),
-+     TOBN(0x2bb3a13d, 0x88f7e433), TOBN(0x62b23a10, 0x01be5849),
-+     TOBN(0xe83596b4, 0xa63d1a4c), TOBN(0x454e7fea, 0x7d183f3e),
-+     TOBN(0x643fce61, 0x17afb01c), TOBN(0x4e65e5e6, 0x1c4c3638),
-+     TOBN(0x41d85ea1, 0xef74c45b), TOBN(0x2cfbfa66, 0xae328506),
-+     TOBN(0x98b078f5, 0x3ada7da9), TOBN(0xd985fe37, 0xec752fbb),
-+     TOBN(0xeece68fe, 0x5a0148b4), TOBN(0x6f9a55c7, 0x2d78136d),
-+     TOBN(0x232dccc4, 0xd2b729ce), TOBN(0xa27e0dfd, 0x90aafbc4),
-+     TOBN(0x96474452, 0x12b4603e), TOBN(0xa876c551, 0x6b706d14),
-+     TOBN(0xdf145fcf, 0x69a9d412), TOBN(0xe2ab75b7, 0x2d479c34),
-+     TOBN(0x12df9a76, 0x1a23ff97), TOBN(0xc6138992, 0x5d359d10),
-+     TOBN(0x6e51c7ae, 0xfa835f22), TOBN(0x69a79cb1, 0xc0fcc4d9),
-+     TOBN(0xf57f350d, 0x594cc7e1), TOBN(0x3079ca63, 0x3350ab79),
-+     TOBN(0x226fb614, 0x9aff594a), TOBN(0x35afec02, 0x6d59a62b),
-+     TOBN(0x9bee46f4, 0x06ed2c6e), TOBN(0x58da1735, 0x7d939a57),
-+     TOBN(0x44c50402, 0x8fd1797e), TOBN(0xd8853e7c, 0x5ccea6ca),
-+     TOBN(0x4065508d, 0xa35fcd5f), TOBN(0x8965df8c, 0x495ccaeb),
-+     TOBN(0x0f2da850, 0x12e1a962), TOBN(0xee471b94, 0xc1cf1cc4),
-+     TOBN(0xcef19bc8, 0x0a08fb75), TOBN(0x704958f5, 0x81de3591),
-+     TOBN(0x2867f8b2, 0x3aef4f88), TOBN(0x8d749384, 0xea9f9a5f),
-+     TOBN(0x1b385537, 0x8c9049f4), TOBN(0x5be948f3, 0x7b92d8b6),
-+     TOBN(0xd96f725d, 0xb6e2bd6b), TOBN(0x37a222bc, 0x958c454d),
-+     TOBN(0xe7c61abb, 0x8809bf61), TOBN(0x46f07fbc, 0x1346f18d),
-+     TOBN(0xfb567a7a, 0xe87c0d1c), TOBN(0x84a461c8, 0x7ef3d07a),
-+     TOBN(0x0a5adce6, 0xd9278d98), TOBN(0x24d94813, 0x9dfc73e1),
-+     TOBN(0x4f3528b6, 0x054321c3), TOBN(0x2e03fdde, 0x692ea706),
-+     TOBN(0x10e60619, 0x47b533c0), TOBN(0x1a8bc73f, 0x2ca3c055),
-+     TOBN(0xae58d4b2, 0x1bb62b8f), TOBN(0xb2045a73, 0x584a24e3),
-+     TOBN(0x3ab3d5af, 0xbd76e195), TOBN(0x478dd1ad, 0x6938a810),
-+     TOBN(0x6ffab393, 0x6ee3d5cb), TOBN(0xdfb693db, 0x22b361e4),
-+     TOBN(0xf9694496, 0x51dbf1a7), TOBN(0xcab4b4ef, 0x08a2e762),
-+     TOBN(0xe8c92f25, 0xd39bba9a), TOBN(0x850e61bc, 0xf1464d96),
-+     TOBN(0xb7e830e3, 0xdc09508b), TOBN(0xfaf6d2cf, 0x74317655),
-+     TOBN(0x72606ceb, 0xdf690355), TOBN(0x48bb92b3, 0xd0c3ded6),
-+     TOBN(0x65b75484, 0x5c7cf892), TOBN(0xf6cd7ac9, 0xd5d5f01f),
-+     TOBN(0xc2c30a59, 0x96401d69), TOBN(0x91268650, 0xed921878),
-+     TOBN(0x380bf913, 0xb78c558f), TOBN(0x43c0baeb, 0xc8afdaa9),
-+     TOBN(0x377f61d5, 0x54f169d3), TOBN(0xf8da07e3, 0xae5ff20b),
-+     TOBN(0xb676c49d, 0xa8a90ea8), TOBN(0x81c1ff2b, 0x83a29b21),
-+     TOBN(0x383297ac, 0x2ad8d276), TOBN(0x3001122f, 0xba89f982),
-+     TOBN(0xe1d794be, 0x6718e448), TOBN(0x246c1482, 0x7c3e6e13),
-+     TOBN(0x56646ef8, 0x5d26b5ef), TOBN(0x80f5091e, 0x88069cdd),
-+     TOBN(0xc5992e2f, 0x724bdd38), TOBN(0x02e915b4, 0x8471e8c7),
-+     TOBN(0x96ff320a, 0x0d0ff2a9), TOBN(0xbf886487, 0x4384d1a0),
-+     TOBN(0xbbe1e6a6, 0xc93f72d6), TOBN(0xd5f75d12, 0xcad800ea),
-+     TOBN(0xfa40a09f, 0xe7acf117), TOBN(0x32c8cdd5, 0x7581a355),
-+     TOBN(0x74221992, 0x7023c499), TOBN(0xa8afe5d7, 0x38ec3901),
-+     TOBN(0x5691afcb, 0xa90e83f0), TOBN(0x41bcaa03, 0x0b8f8eac),
-+     TOBN(0xe38b5ff9, 0x8d2668d5), TOBN(0x0715281a, 0x7ad81965),
-+     TOBN(0x1bc8fc7c, 0x03c6ce11), TOBN(0xcbbee6e2, 0x8b650436),
-+     TOBN(0x06b00fe8, 0x0cdb9808), TOBN(0x17d6e066, 0xfe3ed315),
-+     TOBN(0x2e9d38c6, 0x4d0b5018), TOBN(0xab8bfd56, 0x844dcaef),
-+     TOBN(0x42894a59, 0x513aed8b), TOBN(0xf77f3b6d, 0x314bd07a),
-+     TOBN(0xbbdecb8f, 0x8e42b582), TOBN(0xf10e2fa8, 0xd2390fe6),
-+     TOBN(0xefb95022, 0x62a2f201), TOBN(0x4d59ea50, 0x50ee32b0),
-+     TOBN(0xd87f7728, 0x6da789a8), TOBN(0xcf98a2cf, 0xf79492c4),
-+     TOBN(0xf9577239, 0x720943c2), TOBN(0xba044cf5, 0x3990b9d0),
-+     TOBN(0x5aa8e823, 0x95f2884a), TOBN(0x834de6ed, 0x0278a0af),
-+     TOBN(0xc8e1ee9a, 0x5f25bd12), TOBN(0x9259ceaa, 0x6f7ab271),
-+     TOBN(0x7e6d97a2, 0x77d00b76), TOBN(0x5c0c6eea, 0xa437832a),
-+     TOBN(0x5232c20f, 0x5606b81d), TOBN(0xabd7b375, 0x0d991ee5),
-+     TOBN(0x4d2bfe35, 0x8632d951), TOBN(0x78f85146, 0x98ed9364),
-+     TOBN(0x951873f0, 0xf30c3282), TOBN(0x0da8ac80, 0xa789230b),
-+     TOBN(0x3ac7789c, 0x5398967f), TOBN(0xa69b8f7f, 0xbdda0fb5),
-+     TOBN(0xe5db7717, 0x6add8545), TOBN(0x1b71cb66, 0x72c49b66),
-+     TOBN(0xd8560739, 0x68421d77), TOBN(0x03840fe8, 0x83e3afea),
-+     TOBN(0xb391dad5, 0x1ec69977), TOBN(0xae243fb9, 0x307f6726),
-+     TOBN(0xc88ac87b, 0xe8ca160c), TOBN(0x5174cced, 0x4ce355f4),
-+     TOBN(0x98a35966, 0xe58ba37d), TOBN(0xfdcc8da2, 0x7817335d),
-+     TOBN(0x5b752830, 0x83fbc7bf), TOBN(0x68e419d4, 0xd9c96984),
-+     TOBN(0x409a39f4, 0x02a40380), TOBN(0x88940faf, 0x1fe977bc),
-+     TOBN(0xc640a94b, 0x8f8edea6), TOBN(0x1e22cd17, 0xed11547d),
-+     TOBN(0xe28568ce, 0x59ffc3e2), TOBN(0x60aa1b55, 0xc1dee4e7),
-+     TOBN(0xc67497c8, 0x837cb363), TOBN(0x06fb438a, 0x105a2bf2),
-+     TOBN(0x30357ec4, 0x500d8e20), TOBN(0x1ad9095d, 0x0670db10),
-+     TOBN(0x7f589a05, 0xc73b7cfd), TOBN(0xf544607d, 0x880d6d28),
-+     TOBN(0x17ba93b1, 0xa20ef103), TOBN(0xad859130, 0x6ba6577b),
-+     TOBN(0x65c91cf6, 0x6fa214a0), TOBN(0xd7d49c6c, 0x27990da5),
-+     TOBN(0xecd9ec8d, 0x20bb569d), TOBN(0xbd4b2502, 0xeeffbc33),
-+     TOBN(0x2056ca5a, 0x6bed0467), TOBN(0x7916a1f7, 0x5b63728c),
-+     TOBN(0xd4f9497d, 0x53a4f566), TOBN(0x89734664, 0x97b56810),
-+     TOBN(0xf8e1da74, 0x0494a621), TOBN(0x82546a93, 0x8d011c68),
-+     TOBN(0x1f3acb19, 0xc61ac162), TOBN(0x52f8fa9c, 0xabad0d3e),
-+     TOBN(0x15356523, 0xb4b7ea43), TOBN(0x5a16ad61, 0xae608125),
-+     TOBN(0xb0bcb87f, 0x4faed184), TOBN(0x5f236b1d, 0x5029f45f),
-+     TOBN(0xd42c7607, 0x0bc6b1fc), TOBN(0xc644324e, 0x68aefce3),
-+     TOBN(0x8e191d59, 0x5c5d8446), TOBN(0xc0208077, 0x13ae1979),
-+     TOBN(0xadcaee55, 0x3ba59cc7), TOBN(0x20ed6d6b, 0xa2cb81ba),
-+     TOBN(0x0952ba19, 0xb6efcffc), TOBN(0x60f12d68, 0x97c0b87c),
-+     TOBN(0x4ee2c7c4, 0x9caa30bc), TOBN(0x767238b7, 0x97fbff4e),
-+     TOBN(0xebc73921, 0x501b5d92), TOBN(0x3279e3df, 0xc2a37737),
-+     TOBN(0x9fc12bc8, 0x6d197543), TOBN(0xfa94dc6f, 0x0a40db4e),
-+     TOBN(0x7392b41a, 0x530ccbbd), TOBN(0x87c82146, 0xea823525),
-+     TOBN(0xa52f984c, 0x05d98d0c), TOBN(0x2ae57d73, 0x5ef6974c),
-+     TOBN(0x9377f7bf, 0x3042a6dd), TOBN(0xb1a007c0, 0x19647a64),
-+     TOBN(0xfaa9079a, 0x0cca9767), TOBN(0x3d81a25b, 0xf68f72d5),
-+     TOBN(0x752067f8, 0xff81578e), TOBN(0x78622150, 0x9045447d),
-+     TOBN(0xc0c22fcf, 0x0505aa6f), TOBN(0x1030f0a6, 0x6bed1c77),
-+     TOBN(0x31f29f15, 0x1f0bd739), TOBN(0x2d7989c7, 0xe6debe85),
-+     TOBN(0x5c070e72, 0x8e677e98), TOBN(0x0a817bd3, 0x06e81fd5),
-+     TOBN(0xc110d830, 0xb0f2ac95), TOBN(0x48d0995a, 0xab20e64e),
-+     TOBN(0x0f3e00e1, 0x7729cd9a), TOBN(0x2a570c20, 0xdd556946),
-+     TOBN(0x912dbcfd, 0x4e86214d), TOBN(0x2d014ee2, 0xcf615498),
-+     TOBN(0x55e2b1e6, 0x3530d76e), TOBN(0xc5135ae4, 0xfd0fd6d1),
-+     TOBN(0x0066273a, 0xd4f3049f), TOBN(0xbb8e9893, 0xe7087477),
-+     TOBN(0x2dba1ddb, 0x14c6e5fd), TOBN(0xdba37886, 0x51f57e6c),
-+     TOBN(0x5aaee0a6, 0x5a72f2cf), TOBN(0x1208bfbf, 0x7bea5642),
-+     TOBN(0xf5c6aa3b, 0x67872c37), TOBN(0xd726e083, 0x43f93224),
-+     TOBN(0x1854daa5, 0x061f1658), TOBN(0xc0016df1, 0xdf0cd2b3),
-+     TOBN(0xc2a3f23e, 0x833d50de), TOBN(0x73b681d2, 0xbbbd3017),
-+     TOBN(0x2f046dc4, 0x3ac343c0), TOBN(0x9c847e7d, 0x85716421),
-+     TOBN(0xe1e13c91, 0x0917eed4), TOBN(0x3fc9eebd, 0x63a1b9c6),
-+     TOBN(0x0f816a72, 0x7fe02299), TOBN(0x6335ccc2, 0x294f3319),
-+     TOBN(0x3820179f, 0x4745c5be), TOBN(0xe647b782, 0x922f066e),
-+     TOBN(0xc22e49de, 0x02cafb8a), TOBN(0x299bc2ff, 0xfcc2eccc),
-+     TOBN(0x9a8feea2, 0x6e0e8282), TOBN(0xa627278b, 0xfe893205),
-+     TOBN(0xa7e19733, 0x7933e47b), TOBN(0xf4ff6b13, 0x2e766402),
-+     TOBN(0xa4d8be0a, 0x98440d9f), TOBN(0x658f5c2f, 0x38938808),
-+     TOBN(0x90b75677, 0xc95b3b3e), TOBN(0xfa044269, 0x3137b6ff),
-+     TOBN(0x077b039b, 0x43c47c29), TOBN(0xcca95dd3, 0x8a6445b2),
-+     TOBN(0x0b498ba4, 0x2333fc4c), TOBN(0x274f8e68, 0xf736a1b1),
-+     TOBN(0x6ca348fd, 0x5f1d4b2e), TOBN(0x24d3be78, 0xa8f10199),
-+     TOBN(0x8535f858, 0xca14f530), TOBN(0xa6e7f163, 0x5b982e51),
-+     TOBN(0x847c8512, 0x36e1bf62), TOBN(0xf6a7c58e, 0x03448418),
-+     TOBN(0x583f3703, 0xf9374ab6), TOBN(0x864f9195, 0x6e564145),
-+     TOBN(0x33bc3f48, 0x22526d50), TOBN(0x9f323c80, 0x1262a496),
-+     TOBN(0xaa97a7ae, 0x3f046a9a), TOBN(0x70da183e, 0xdf8a039a),
-+     TOBN(0x5b68f71c, 0x52aa0ba6), TOBN(0x9be0fe51, 0x21459c2d),
-+     TOBN(0xc1e17eb6, 0xcbc613e5), TOBN(0x33131d55, 0x497ea61c),
-+     TOBN(0x2f69d39e, 0xaf7eded5), TOBN(0x73c2f434, 0xde6af11b),
-+     TOBN(0x4ca52493, 0xa4a375fa), TOBN(0x5f06787c, 0xb833c5c2),
-+     TOBN(0x814e091f, 0x3e6e71cf), TOBN(0x76451f57, 0x8b746666)}
-+    ,
-+    {TOBN(0x80f9bdef, 0x694db7e0), TOBN(0xedca8787, 0xb9fcddc6),
-+     TOBN(0x51981c34, 0x03b8dce1), TOBN(0x4274dcf1, 0x70e10ba1),
-+     TOBN(0xf72743b8, 0x6def6d1a), TOBN(0xd25b1670, 0xebdb1866),
-+     TOBN(0xc4491e8c, 0x050c6f58), TOBN(0x2be2b2ab, 0x87fbd7f5),
-+     TOBN(0x3e0e5c9d, 0xd111f8ec), TOBN(0xbcc33f8d, 0xb7c4e760),
-+     TOBN(0x702f9a91, 0xbd392a51), TOBN(0x7da4a795, 0xc132e92d),
-+     TOBN(0x1a0b0ae3, 0x0bb1151b), TOBN(0x54febac8, 0x02e32251),
-+     TOBN(0xea3a5082, 0x694e9e78), TOBN(0xe58ffec1, 0xe4fe40b8),
-+     TOBN(0xf85592fc, 0xd1e0cf9e), TOBN(0xdea75f0d, 0xc0e7b2e8),
-+     TOBN(0xc04215cf, 0xc135584e), TOBN(0x174fc727, 0x2f57092a),
-+     TOBN(0xe7277877, 0xeb930bea), TOBN(0x504caccb, 0x5eb02a5a),
-+     TOBN(0xf9fe08f7, 0xf5241b9b), TOBN(0xe7fb62f4, 0x8d5ca954),
-+     TOBN(0xfbb8349d, 0x29c4120b), TOBN(0x9f94391f, 0xc0d0d915),
-+     TOBN(0xc4074fa7, 0x5410ba51), TOBN(0xa66adbf6, 0x150a5911),
-+     TOBN(0xc164543c, 0x34bfca38), TOBN(0xe0f27560, 0xb9e1ccfc),
-+     TOBN(0x99da0f53, 0xe820219c), TOBN(0xe8234498, 0xc6b4997a),
-+     TOBN(0xcfb88b76, 0x9d4c5423), TOBN(0x9e56eb10, 0xb0521c49),
-+     TOBN(0x418e0b5e, 0xbe8700a1), TOBN(0x00cbaad6, 0xf93cb58a),
-+     TOBN(0xe923fbde, 0xd92a5e67), TOBN(0xca4979ac, 0x1f347f11),
-+     TOBN(0x89162d85, 0x6bc0585b), TOBN(0xdd6254af, 0xac3c70e3),
-+     TOBN(0x7b23c513, 0x516e19e4), TOBN(0x56e2e847, 0xc5c4d593),
-+     TOBN(0x9f727d73, 0x5ce71ef6), TOBN(0x5b6304a6, 0xf79a44c5),
-+     TOBN(0x6638a736, 0x3ab7e433), TOBN(0x1adea470, 0xfe742f83),
-+     TOBN(0xe054b854, 0x5b7fc19f), TOBN(0xf935381a, 0xba1d0698),
-+     TOBN(0x546eab2d, 0x799e9a74), TOBN(0x96239e0e, 0xa949f729),
-+     TOBN(0xca274c6b, 0x7090055a), TOBN(0x835142c3, 0x9020c9b0),
-+     TOBN(0xa405667a, 0xa2e8807f), TOBN(0x29f2c085, 0x1aa3d39e),
-+     TOBN(0xcc555d64, 0x42fc72f5), TOBN(0xe856e0e7, 0xfbeacb3c),
-+     TOBN(0xb5504f9d, 0x918e4936), TOBN(0x65035ef6, 0xb2513982),
-+     TOBN(0x0553a0c2, 0x6f4d9cb9), TOBN(0x6cb10d56, 0xbea85509),
-+     TOBN(0x48d957b7, 0xa242da11), TOBN(0x16a4d3dd, 0x672b7268),
-+     TOBN(0x3d7e637c, 0x8502a96b), TOBN(0x27c7032b, 0x730d463b),
-+     TOBN(0xbdc02b18, 0xe4136a14), TOBN(0xbacf969d, 0x678e32bf),
-+     TOBN(0xc98d89a3, 0xdd9c3c03), TOBN(0x7b92420a, 0x23becc4f),
-+     TOBN(0xd4b41f78, 0xc64d565c), TOBN(0x9f969d00, 0x10f28295),
-+     TOBN(0xec7f7f76, 0xb13d051a), TOBN(0x08945e1e, 0xa92da585),
-+     TOBN(0x55366b7d, 0x5846426f), TOBN(0xe7d09e89, 0x247d441d),
-+     TOBN(0x510b404d, 0x736fbf48), TOBN(0x7fa003d0, 0xe784bd7d),
-+     TOBN(0x25f7614f, 0x17fd9596), TOBN(0x49e0e0a1, 0x35cb98db),
-+     TOBN(0x2c65957b, 0x2e83a76a), TOBN(0x5d40da8d, 0xcddbe0f8),
-+     TOBN(0xf2b8c405, 0x050bad24), TOBN(0x8918426d, 0xc2aa4823),
-+     TOBN(0x2aeab3dd, 0xa38365a7), TOBN(0x72031717, 0x7c91b690),
-+     TOBN(0x8b00d699, 0x60a94120), TOBN(0x478a255d, 0xe99eaeec),
-+     TOBN(0xbf656a5f, 0x6f60aafd), TOBN(0xdfd7cb75, 0x5dee77b3),
-+     TOBN(0x37f68bb4, 0xa595939d), TOBN(0x03556479, 0x28740217),
-+     TOBN(0x8e740e7c, 0x84ad7612), TOBN(0xd89bc843, 0x9044695f),
-+     TOBN(0xf7f3da5d, 0x85a9184d), TOBN(0x562563bb, 0x9fc0b074),
-+     TOBN(0x06d2e6aa, 0xf88a888e), TOBN(0x612d8643, 0x161fbe7c),
-+     TOBN(0x465edba7, 0xf64085e7), TOBN(0xb230f304, 0x29aa8511),
-+     TOBN(0x53388426, 0xcda2d188), TOBN(0x90885735, 0x4b666649),
-+     TOBN(0x6f02ff9a, 0x652f54f6), TOBN(0x65c82294, 0x5fae2bf0),
-+     TOBN(0x7816ade0, 0x62f5eee3), TOBN(0xdcdbdf43, 0xfcc56d70),
-+     TOBN(0x9fb3bba3, 0x54530bb2), TOBN(0xbde3ef77, 0xcb0869ea),
-+     TOBN(0x89bc9046, 0x0b431163), TOBN(0x4d03d7d2, 0xe4819a35),
-+     TOBN(0x33ae4f9e, 0x43b6a782), TOBN(0x216db307, 0x9c88a686),
-+     TOBN(0x91dd88e0, 0x00ffedd9), TOBN(0xb280da9f, 0x12bd4840),
-+     TOBN(0x32a7cb8a, 0x1635e741), TOBN(0xfe14008a, 0x78be02a7),
-+     TOBN(0x3fafb334, 0x1b7ae030), TOBN(0x7fd508e7, 0x5add0ce9),
-+     TOBN(0x72c83219, 0xd607ad51), TOBN(0x0f229c0a, 0x8d40964a),
-+     TOBN(0x1be2c336, 0x1c878da2), TOBN(0xe0c96742, 0xeab2ab86),
-+     TOBN(0x458f8691, 0x3e538cd7), TOBN(0xa7001f6c, 0x8e08ad53),
-+     TOBN(0x52b8c6e6, 0xbf5d15ff), TOBN(0x548234a4, 0x011215dd),
-+     TOBN(0xff5a9d2d, 0x3d5b4045), TOBN(0xb0ffeeb6, 0x4a904190),
-+     TOBN(0x55a3aca4, 0x48607f8b), TOBN(0x8cbd665c, 0x30a0672a),
-+     TOBN(0x87f834e0, 0x42583068), TOBN(0x02da2aeb, 0xf3f6e683),
-+     TOBN(0x6b763e5d, 0x05c12248), TOBN(0x7230378f, 0x65a8aefc),
-+     TOBN(0x93bd80b5, 0x71e8e5ca), TOBN(0x53ab041c, 0xb3b62524),
-+     TOBN(0x1b860513, 0x6c9c552e), TOBN(0xe84d402c, 0xd5524e66),
-+     TOBN(0xa37f3573, 0xf37f5937), TOBN(0xeb0f6c7d, 0xd1e4fca5),
-+     TOBN(0x2965a554, 0xac8ab0fc), TOBN(0x17fbf56c, 0x274676ac),
-+     TOBN(0x2e2f6bd9, 0xacf7d720), TOBN(0x41fc8f88, 0x10224766),
-+     TOBN(0x517a14b3, 0x85d53bef), TOBN(0xdae327a5, 0x7d76a7d1),
-+     TOBN(0x6ad0a065, 0xc4818267), TOBN(0x33aa189b, 0x37c1bbc1),
-+     TOBN(0x64970b52, 0x27392a92), TOBN(0x21699a1c, 0x2d1535ea),
-+     TOBN(0xcd20779c, 0xc2d7a7fd), TOBN(0xe3186059, 0x99c83cf2),
-+     TOBN(0x9b69440b, 0x72c0b8c7), TOBN(0xa81497d7, 0x7b9e0e4d),
-+     TOBN(0x515d5c89, 0x1f5f82dc), TOBN(0x9a7f67d7, 0x6361079e),
-+     TOBN(0xa8da81e3, 0x11a35330), TOBN(0xe44990c4, 0x4b18be1b),
-+     TOBN(0xc7d5ed95, 0xaf103e59), TOBN(0xece8aba7, 0x8dac9261),
-+     TOBN(0xbe82b099, 0x9394b8d3), TOBN(0x6830f09a, 0x16adfe83),
-+     TOBN(0x250a29b4, 0x88172d01), TOBN(0x8b20bd65, 0xcaff9e02),
-+     TOBN(0xb8a7661e, 0xe8a6329a), TOBN(0x4520304d, 0xd3fce920),
-+     TOBN(0xae45da1f, 0x2b47f7ef), TOBN(0xe07f5288, 0x5bffc540),
-+     TOBN(0xf7997009, 0x3464f874), TOBN(0x2244c2cd, 0xa6fa1f38),
-+     TOBN(0x43c41ac1, 0x94d7d9b1), TOBN(0x5bafdd82, 0xc82e7f17),
-+     TOBN(0xdf0614c1, 0x5fda0fca), TOBN(0x74b043a7, 0xa8ae37ad),
-+     TOBN(0x3ba6afa1, 0x9e71734c), TOBN(0x15d5437e, 0x9c450f2e),
-+     TOBN(0x4a5883fe, 0x67e242b1), TOBN(0x5143bdc2, 0x2c1953c2),
-+     TOBN(0x542b8b53, 0xfc5e8920), TOBN(0x363bf9a8, 0x9a9cee08),
-+     TOBN(0x02375f10, 0xc3486e08), TOBN(0x2037543b, 0x8c5e70d2),
-+     TOBN(0x7109bccc, 0x625640b4), TOBN(0xcbc1051e, 0x8bc62c3b),
-+     TOBN(0xf8455fed, 0x803f26ea), TOBN(0x6badceab, 0xeb372424),
-+     TOBN(0xa2a9ce7c, 0x6b53f5f9), TOBN(0x64246595, 0x1b176d99),
-+     TOBN(0xb1298d36, 0xb95c081b), TOBN(0x53505bb8, 0x1d9a9ee6),
-+     TOBN(0x3f6f9e61, 0xf2ba70b0), TOBN(0xd07e16c9, 0x8afad453),
-+     TOBN(0x9f1694bb, 0xe7eb4a6a), TOBN(0xdfebced9, 0x3cb0bc8e),
-+     TOBN(0x92d3dcdc, 0x53868c8b), TOBN(0x174311a2, 0x386107a6),
-+     TOBN(0x4109e07c, 0x689b4e64), TOBN(0x30e4587f, 0x2df3dcb6),
-+     TOBN(0x841aea31, 0x0811b3b2), TOBN(0x6144d41d, 0x0cce43ea),
-+     TOBN(0x464c4581, 0x2a9a7803), TOBN(0xd03d371f, 0x3e158930),
-+     TOBN(0xc676d7f2, 0xb1f3390b), TOBN(0x9f7a1b8c, 0xa5b61272),
-+     TOBN(0x4ebebfc9, 0xc2e127a9), TOBN(0x4602500c, 0x5dd997bf),
-+     TOBN(0x7f09771c, 0x4711230f), TOBN(0x058eb37c, 0x020f09c1),
-+     TOBN(0xab693d4b, 0xfee5e38b), TOBN(0x9289eb1f, 0x4653cbc0),
-+     TOBN(0xbecf46ab, 0xd51b9cf5), TOBN(0xd2aa9c02, 0x9f0121af),
-+     TOBN(0x36aaf7d2, 0xe90dc274), TOBN(0x909e4ea0, 0x48b95a3c),
-+     TOBN(0xe6b70496, 0x6f32dbdb), TOBN(0x672188a0, 0x8b030b3e),
-+     TOBN(0xeeffe5b3, 0xcfb617e2), TOBN(0x87e947de, 0x7c82709e),
-+     TOBN(0xa44d2b39, 0x1770f5a7), TOBN(0xe4d4d791, 0x0e44eb82),
-+     TOBN(0x42e69d1e, 0x3f69712a), TOBN(0xbf11c4d6, 0xac6a820e),
-+     TOBN(0xb5e7f3e5, 0x42c4224c), TOBN(0xd6b4e81c, 0x449d941c),
-+     TOBN(0x5d72bd16, 0x5450e878), TOBN(0x6a61e28a, 0xee25ac54),
-+     TOBN(0x33272094, 0xe6f1cd95), TOBN(0x7512f30d, 0x0d18673f),
-+     TOBN(0x32f7a4ca, 0x5afc1464), TOBN(0x2f095656, 0x6bbb977b),
-+     TOBN(0x586f47ca, 0xa8226200), TOBN(0x02c868ad, 0x1ac07369),
-+     TOBN(0x4ef2b845, 0xc613acbe), TOBN(0x43d7563e, 0x0386054c),
-+     TOBN(0x54da9dc7, 0xab952578), TOBN(0xb5423df2, 0x26e84d0b),
-+     TOBN(0xa8b64eeb, 0x9b872042), TOBN(0xac205782, 0x5990f6df),
-+     TOBN(0x4ff696eb, 0x21f4c77a), TOBN(0x1a79c3e4, 0xaab273af),
-+     TOBN(0x29bc922e, 0x9436b3f1), TOBN(0xff807ef8, 0xd6d9a27a),
-+     TOBN(0x82acea3d, 0x778f22a0), TOBN(0xfb10b2e8, 0x5b5e7469),
-+     TOBN(0xc0b16980, 0x2818ee7d), TOBN(0x011afff4, 0xc91c1a2f),
-+     TOBN(0x95a6d126, 0xad124418), TOBN(0x31c081a5, 0xe72e295f),
-+     TOBN(0x36bb283a, 0xf2f4db75), TOBN(0xd115540f, 0x7acef462),
-+     TOBN(0xc7f3a8f8, 0x33f6746c), TOBN(0x21e46f65, 0xfea990ca),
-+     TOBN(0x915fd5c5, 0xcaddb0a9), TOBN(0xbd41f016, 0x78614555),
-+     TOBN(0x346f4434, 0x426ffb58), TOBN(0x80559436, 0x14dbc204),
-+     TOBN(0xf3dd20fe, 0x5a969b7f), TOBN(0x9d59e956, 0xe899a39a),
-+     TOBN(0xf1b0971c, 0x8ad4cf4b), TOBN(0x03448860, 0x2ffb8fb8),
-+     TOBN(0xf071ac3c, 0x65340ba4), TOBN(0x408d0596, 0xb27fd758),
-+     TOBN(0xe7c78ea4, 0x98c364b0), TOBN(0xa4aac4a5, 0x051e8ab5),
-+     TOBN(0xb9e1d560, 0x485d9002), TOBN(0x9acd518a, 0x88844455),
-+     TOBN(0xe4ca688f, 0xd06f56c0), TOBN(0xa48af70d, 0xdf027972),
-+     TOBN(0x691f0f04, 0x5e9a609d), TOBN(0xa9dd82cd, 0xee61270e),
-+     TOBN(0x8903ca63, 0xa0ef18d3), TOBN(0x9fb7ee35, 0x3d6ca3bd),
-+     TOBN(0xa7b4a09c, 0xabf47d03), TOBN(0x4cdada01, 0x1c67de8e),
-+     TOBN(0x52003749, 0x9355a244), TOBN(0xe77fd2b6, 0x4f2151a9),
-+     TOBN(0x695d6cf6, 0x66b4efcb), TOBN(0xc5a0cacf, 0xda2cfe25),
-+     TOBN(0x104efe5c, 0xef811865), TOBN(0xf52813e8, 0x9ea5cc3d),
-+     TOBN(0x855683dc, 0x40b58dbc), TOBN(0x0338ecde, 0x175fcb11),
-+     TOBN(0xf9a05637, 0x74921592), TOBN(0xb4f1261d, 0xb9bb9d31),
-+     TOBN(0x551429b7, 0x4e9c5459), TOBN(0xbe182e6f, 0x6ea71f53),
-+     TOBN(0xd3a3b07c, 0xdfc50573), TOBN(0x9ba1afda, 0x62be8d44),
-+     TOBN(0x9bcfd2cb, 0x52ab65d3), TOBN(0xdf11d547, 0xa9571802),
-+     TOBN(0x099403ee, 0x02a2404a), TOBN(0x497406f4, 0x21088a71),
-+     TOBN(0x99479409, 0x5004ae71), TOBN(0xbdb42078, 0xa812c362),
-+     TOBN(0x2b72a30f, 0xd8828442), TOBN(0x283add27, 0xfcb5ed1c),
-+     TOBN(0xf7c0e200, 0x66a40015), TOBN(0x3e3be641, 0x08b295ef),
-+     TOBN(0xac127dc1, 0xe038a675), TOBN(0x729deff3, 0x8c5c6320),
-+     TOBN(0xb7df8fd4, 0xa90d2c53), TOBN(0x9b74b0ec, 0x681e7cd3),
-+     TOBN(0x5cb5a623, 0xdab407e5), TOBN(0xcdbd3615, 0x76b340c6),
-+     TOBN(0xa184415a, 0x7d28392c), TOBN(0xc184c1d8, 0xe96f7830),
-+     TOBN(0xc3204f19, 0x81d3a80f), TOBN(0xfde0c841, 0xc8e02432),
-+     TOBN(0x78203b3e, 0x8149e0c1), TOBN(0x5904bdbb, 0x08053a73),
-+     TOBN(0x30fc1dd1, 0x101b6805), TOBN(0x43c223bc, 0x49aa6d49),
-+     TOBN(0x9ed67141, 0x7a174087), TOBN(0x311469a0, 0xd5997008),
-+     TOBN(0xb189b684, 0x5e43fc61), TOBN(0xf3282375, 0xe0d3ab57),
-+     TOBN(0x4fa34b67, 0xb1181da8), TOBN(0x621ed0b2, 0x99ee52b8),
-+     TOBN(0x9b178de1, 0xad990676), TOBN(0xd51de67b, 0x56d54065),
-+     TOBN(0x2a2c27c4, 0x7538c201), TOBN(0x33856ec8, 0x38a40f5c),
-+     TOBN(0x2522fc15, 0xbe6cdcde), TOBN(0x1e603f33, 0x9f0c6f89),
-+     TOBN(0x7994edc3, 0x103e30a6), TOBN(0x033a00db, 0x220c853e),
-+     TOBN(0xd3cfa409, 0xf7bb7fd7), TOBN(0x70f8781e, 0x462d18f6),
-+     TOBN(0xbbd82980, 0x687fe295), TOBN(0x6eef4c32, 0x595669f3),
-+     TOBN(0x86a9303b, 0x2f7e85c3), TOBN(0x5fce4621, 0x71988f9b),
-+     TOBN(0x5b935bf6, 0xc138acb5), TOBN(0x30ea7d67, 0x25661212),
-+     TOBN(0xef1eb5f4, 0xe51ab9a2), TOBN(0x0587c98a, 0xae067c78),
-+     TOBN(0xb3ce1b3c, 0x77ca9ca6), TOBN(0x2a553d4d, 0x54b5f057),
-+     TOBN(0xc7898236, 0x4da29ec2), TOBN(0xdbdd5d13, 0xb9c57316),
-+     TOBN(0xc57d6e6b, 0x2cd80d47), TOBN(0x80b460cf, 0xfe9e7391),
-+     TOBN(0x98648cab, 0xf963c31e), TOBN(0x67f9f633, 0xcc4d32fd),
-+     TOBN(0x0af42a9d, 0xfdf7c687), TOBN(0x55f292a3, 0x0b015ea7),
-+     TOBN(0x89e468b2, 0xcd21ab3d), TOBN(0xe504f022, 0xc393d392),
-+     TOBN(0xab21e1d4, 0xa5013af9), TOBN(0xe3283f78, 0xc2c28acb),
-+     TOBN(0xf38b35f6, 0x226bf99f), TOBN(0xe8354274, 0x0e291e69),
-+     TOBN(0x61673a15, 0xb20c162d), TOBN(0xc101dc75, 0xb04fbdbe),
-+     TOBN(0x8323b4c2, 0x255bd617), TOBN(0x6c969693, 0x6c2a9154),
-+     TOBN(0xc6e65860, 0x62679387), TOBN(0x8e01db0c, 0xb8c88e23),
-+     TOBN(0x33c42873, 0x893a5559), TOBN(0x7630f04b, 0x47a3e149),
-+     TOBN(0xb5d80805, 0xddcf35f8), TOBN(0x582ca080, 0x77dfe732),
-+     TOBN(0x2c7156e1, 0x0b1894a0), TOBN(0x92034001, 0xd81c68c0),
-+     TOBN(0xed225d00, 0xc8b115b5), TOBN(0x237f9c22, 0x83b907f2),
-+     TOBN(0x0ea2f32f, 0x4470e2c0), TOBN(0xb725f7c1, 0x58be4e95),
-+     TOBN(0x0f1dcafa, 0xb1ae5463), TOBN(0x59ed5187, 0x1ba2fc04),
-+     TOBN(0xf6e0f316, 0xd0115d4d), TOBN(0x5180b12f, 0xd3691599),
-+     TOBN(0x157e32c9, 0x527f0a41), TOBN(0x7b0b081d, 0xa8e0ecc0),
-+     TOBN(0x6dbaaa8a, 0xbf4f0dd0), TOBN(0x99b289c7, 0x4d252696),
-+     TOBN(0x79b7755e, 0xdbf864fe), TOBN(0x6974e2b1, 0x76cad3ab),
-+     TOBN(0x35dbbee2, 0x06ddd657), TOBN(0xe7cbdd11, 0x2ff3a96d),
-+     TOBN(0x88381968, 0x076be758), TOBN(0x2d737e72, 0x08c91f5d),
-+     TOBN(0x5f83ab62, 0x86ec3776), TOBN(0x98aa649d, 0x945fa7a1),
-+     TOBN(0xf477ec37, 0x72ef0933), TOBN(0x66f52b1e, 0x098c17b1),
-+     TOBN(0x9eec58fb, 0xd803738b), TOBN(0x91aaade7, 0xe4e86aa4),
-+     TOBN(0x6b1ae617, 0xa5b51492), TOBN(0x63272121, 0xbbc45974),
-+     TOBN(0x7e0e28f0, 0x862c5129), TOBN(0x0a8f79a9, 0x3321a4a0),
-+     TOBN(0xe26d1664, 0x5041c88f), TOBN(0x0571b805, 0x53233e3a),
-+     TOBN(0xd1b0ccde, 0xc9520711), TOBN(0x55a9e4ed, 0x3c8b84bf),
-+     TOBN(0x9426bd39, 0xa1fef314), TOBN(0x4f5f638e, 0x6eb93f2b),
-+     TOBN(0xba2a1ed3, 0x2bf9341b), TOBN(0xd63c1321, 0x4d42d5a9),
-+     TOBN(0xd2964a89, 0x316dc7c5), TOBN(0xd1759606, 0xca511851),
-+     TOBN(0xd8a9201f, 0xf9e6ed35), TOBN(0xb7b5ee45, 0x6736925a),
-+     TOBN(0x0a83fbbc, 0x99581af7), TOBN(0x3076bc40, 0x64eeb051),
-+     TOBN(0x5511c98c, 0x02dec312), TOBN(0x270de898, 0x238dcb78),
-+     TOBN(0x2cf4cf9c, 0x539c08c9), TOBN(0xa70cb65e, 0x38d3b06e),
-+     TOBN(0xb12ec10e, 0xcfe57bbd), TOBN(0x82c7b656, 0x35a0c2b5),
-+     TOBN(0xddc7d5cd, 0x161c67bd), TOBN(0xe32e8985, 0xae3a32cc),
-+     TOBN(0x7aba9444, 0xd11a5529), TOBN(0xe964ed02, 0x2427fa1a),
-+     TOBN(0x1528392d, 0x24a1770a), TOBN(0xa152ce2c, 0x12c72fcd),
-+     TOBN(0x714553a4, 0x8ec07649), TOBN(0x18b4c290, 0x459dd453),
-+     TOBN(0xea32b714, 0x7b64b110), TOBN(0xb871bfa5, 0x2e6f07a2),
-+     TOBN(0xb67112e5, 0x9e2e3c9b), TOBN(0xfbf250e5, 0x44aa90f6),
-+     TOBN(0xf77aedb8, 0xbd539006), TOBN(0x3b0cdf9a, 0xd172a66f),
-+     TOBN(0xedf69fea, 0xf8c51187), TOBN(0x05bb67ec, 0x741e4da7),
-+     TOBN(0x47df0f32, 0x08114345), TOBN(0x56facb07, 0xbb9792b1),
-+     TOBN(0xf3e007e9, 0x8f6229e4), TOBN(0x62d103f4, 0x526fba0f),
-+     TOBN(0x4f33bef7, 0xb0339d79), TOBN(0x9841357b, 0xb59bfec1),
-+     TOBN(0xfa8dbb59, 0xc34e6705), TOBN(0xc3c7180b, 0x7fdaa84c),
-+     TOBN(0xf95872fc, 0xa4108537), TOBN(0x8750cc3b, 0x932a3e5a),
-+     TOBN(0xb61cc69d, 0xb7275d7d), TOBN(0xffa0168b, 0x2e59b2e9),
-+     TOBN(0xca032abc, 0x6ecbb493), TOBN(0x1d86dbd3, 0x2c9082d8),
-+     TOBN(0xae1e0b67, 0xe28ef5ba), TOBN(0x2c9a4699, 0xcb18e169),
-+     TOBN(0x0ecd0e33, 0x1e6bbd20), TOBN(0x571b360e, 0xaf5e81d2),
-+     TOBN(0xcd9fea58, 0x101c1d45), TOBN(0x6651788e, 0x18880452),
-+     TOBN(0xa9972635, 0x1f8dd446), TOBN(0x44bed022, 0xe37281d0),
-+     TOBN(0x094b2b2d, 0x33da525d), TOBN(0xf193678e, 0x13144fd8),
-+     TOBN(0xb8ab5ba4, 0xf4c1061d), TOBN(0x4343b5fa, 0xdccbe0f4),
-+     TOBN(0xa8702371, 0x63812713), TOBN(0x47bf6d2d, 0xf7611d93),
-+     TOBN(0x46729b8c, 0xbd21e1d7), TOBN(0x7484d4e0, 0xd629e77d),
-+     TOBN(0x830e6eea, 0x60dbac1f), TOBN(0x23d8c484, 0xda06a2f7),
-+     TOBN(0x896714b0, 0x50ca535b), TOBN(0xdc8d3644, 0xebd97a9b),
-+     TOBN(0x106ef9fa, 0xb12177b4), TOBN(0xf79bf464, 0x534d5d9c),
-+     TOBN(0x2537a349, 0xa6ab360b), TOBN(0xc7c54253, 0xa00c744f),
-+     TOBN(0xb3c7a047, 0xe5911a76), TOBN(0x61ffa5c8, 0x647f1ee7),
-+     TOBN(0x15aed36f, 0x8f56ab42), TOBN(0x6a0d41b0, 0xa3ff9ac9),
-+     TOBN(0x68f469f5, 0xcc30d357), TOBN(0xbe9adf81, 0x6b72be96),
-+     TOBN(0x1cd926fe, 0x903ad461), TOBN(0x7e89e38f, 0xcaca441b),
-+     TOBN(0xf0f82de5, 0xfacf69d4), TOBN(0x363b7e76, 0x4775344c),
-+     TOBN(0x6894f312, 0xb2e36d04), TOBN(0x3c6cb4fe, 0x11d1c9a5),
-+     TOBN(0x85d9c339, 0x4008e1f2), TOBN(0x5e9a85ea, 0x249f326c),
-+     TOBN(0xdc35c60a, 0x678c5e06), TOBN(0xc08b944f, 0x9f86fba9),
-+     TOBN(0xde40c02c, 0x89f71f0f), TOBN(0xad8f3e31, 0xff3da3c0),
-+     TOBN(0x3ea5096b, 0x42125ded), TOBN(0x13879cbf, 0xa7379183),
-+     TOBN(0x6f4714a5, 0x6b306a0b), TOBN(0x359c2ea6, 0x67646c5e),
-+     TOBN(0xfacf8943, 0x07726368), TOBN(0x07a58935, 0x65ff431e),
-+     TOBN(0x24d661d1, 0x68754ab0), TOBN(0x801fce1d, 0x6f429a76),
-+     TOBN(0xc068a85f, 0xa58ce769), TOBN(0xedc35c54, 0x5d5eca2b),
-+     TOBN(0xea31276f, 0xa3f660d1), TOBN(0xa0184ebe, 0xb8fc7167),
-+     TOBN(0x0f20f21a, 0x1d8db0ae), TOBN(0xd96d095f, 0x56c35e12),
-+     TOBN(0xedf402b5, 0xf8c2a25b), TOBN(0x1bb772b9, 0x059204b6),
-+     TOBN(0x50cbeae2, 0x19b4e34c), TOBN(0x93109d80, 0x3fa0845a),
-+     TOBN(0x54f7ccf7, 0x8ef59fb5), TOBN(0x3b438fe2, 0x88070963),
-+     TOBN(0x9e28c659, 0x31f3ba9b), TOBN(0x9cc31b46, 0xead9da92),
-+     TOBN(0x3c2f0ba9, 0xb733aa5f), TOBN(0xdece47cb, 0xf05af235),
-+     TOBN(0xf8e3f715, 0xa2ac82a5), TOBN(0xc97ba641, 0x2203f18a),
-+     TOBN(0xc3af5504, 0x09c11060), TOBN(0x56ea2c05, 0x46af512d),
-+     TOBN(0xfac28daf, 0xf3f28146), TOBN(0x87fab43a, 0x959ef494),}
-+    ,
-+    {TOBN(0x09891641, 0xd4c5105f), TOBN(0x1ae80f8e, 0x6d7fbd65),
-+     TOBN(0x9d67225f, 0xbee6bdb0), TOBN(0x3b433b59, 0x7fc4d860),
-+     TOBN(0x44e66db6, 0x93e85638), TOBN(0xf7b59252, 0xe3e9862f),
-+     TOBN(0xdb785157, 0x665c32ec), TOBN(0x702fefd7, 0xae362f50),
-+     TOBN(0x3754475d, 0x0fefb0c3), TOBN(0xd48fb56b, 0x46d7c35d),
-+     TOBN(0xa070b633, 0x363798a4), TOBN(0xae89f3d2, 0x8fdb98e6),
-+     TOBN(0x970b89c8, 0x6363d14c), TOBN(0x89817521, 0x67abd27d),
-+     TOBN(0x9bf7d474, 0x44d5a021), TOBN(0xb3083baf, 0xcac72aee),
-+     TOBN(0x389741de, 0xbe949a44), TOBN(0x638e9388, 0x546a4fa5),
-+     TOBN(0x3fe6419c, 0xa0047bdc), TOBN(0x7047f648, 0xaaea57ca),
-+     TOBN(0x54e48a90, 0x41fbab17), TOBN(0xda8e0b28, 0x576bdba2),
-+     TOBN(0xe807eebc, 0xc72afddc), TOBN(0x07d3336d, 0xf42577bf),
-+     TOBN(0x62a8c244, 0xbfe20925), TOBN(0x91c19ac3, 0x8fdce867),
-+     TOBN(0x5a96a5d5, 0xdd387063), TOBN(0x61d587d4, 0x21d324f6),
-+     TOBN(0xe87673a2, 0xa37173ea), TOBN(0x23848008, 0x53778b65),
-+     TOBN(0x10f8441e, 0x05bab43e), TOBN(0xfa11fe12, 0x4621efbe),
-+     TOBN(0x047b772e, 0x81685d7b), TOBN(0x23f27d81, 0xbf34a976),
-+     TOBN(0xc27608e2, 0x915f48ef), TOBN(0x3b0b43fa, 0xa521d5c3),
-+     TOBN(0x7613fb26, 0x63ca7284), TOBN(0x7f5729b4, 0x1d4db837),
-+     TOBN(0x87b14898, 0x583b526b), TOBN(0x00b732a6, 0xbbadd3d1),
-+     TOBN(0x8e02f426, 0x2048e396), TOBN(0x436b50b6, 0x383d9de4),
-+     TOBN(0xf78d3481, 0x471e85ad), TOBN(0x8b01ea6a, 0xd005c8d6),
-+     TOBN(0xd3c7afee, 0x97015c07), TOBN(0x46cdf1a9, 0x4e3ba2ae),
-+     TOBN(0x7a42e501, 0x83d3a1d2), TOBN(0xd54b5268, 0xb541dff4),
-+     TOBN(0x3f24cf30, 0x4e23e9bc), TOBN(0x4387f816, 0x126e3624),
-+     TOBN(0x26a46a03, 0x3b0b6d61), TOBN(0xaf1bc845, 0x8b2d777c),
-+     TOBN(0x25c401ba, 0x527de79c), TOBN(0x0e1346d4, 0x4261bbb6),
-+     TOBN(0x4b96c44b, 0x287b4bc7), TOBN(0x658493c7, 0x5254562f),
-+     TOBN(0x23f949fe, 0xb8a24a20), TOBN(0x17ebfed1, 0xf52ca53f),
-+     TOBN(0x9b691bbe, 0xbcfb4853), TOBN(0x5617ff6b, 0x6278a05d),
-+     TOBN(0x241b34c5, 0xe3c99ebd), TOBN(0xfc64242e, 0x1784156a),
-+     TOBN(0x4206482f, 0x695d67df), TOBN(0xb967ce0e, 0xee27c011),
-+     TOBN(0x65db3751, 0x21c80b5d), TOBN(0x2e7a563c, 0xa31ecca0),
-+     TOBN(0xe56ffc4e, 0x5238a07e), TOBN(0x3d6c2966, 0x32ced854),
-+     TOBN(0xe99d7d1a, 0xaf70b885), TOBN(0xafc3bad9, 0x2d686459),
-+     TOBN(0x9c78bf46, 0x0cc8ba5b), TOBN(0x5a439519, 0x18955aa3),
-+     TOBN(0xf8b517a8, 0x5fe4e314), TOBN(0xe60234d0, 0xfcb8906f),
-+     TOBN(0xffe542ac, 0xf2061b23), TOBN(0x287e191f, 0x6b4cb59c),
-+     TOBN(0x21857ddc, 0x09d877d8), TOBN(0x1c23478c, 0x14678941),
-+     TOBN(0xbbf0c056, 0xb6e05ea4), TOBN(0x82da4b53, 0xb01594fe),
-+     TOBN(0xf7526791, 0xfadb8608), TOBN(0x049e832d, 0x7b74cdf6),
-+     TOBN(0xa43581cc, 0xc2b90a34), TOBN(0x73639eb8, 0x9360b10c),
-+     TOBN(0x4fba331f, 0xe1e4a71b), TOBN(0x6ffd6b93, 0x8072f919),
-+     TOBN(0x6e53271c, 0x65679032), TOBN(0x67206444, 0xf14272ce),
-+     TOBN(0xc0f734a3, 0xb2335834), TOBN(0x9526205a, 0x90ef6860),
-+     TOBN(0xcb8be717, 0x04e2bb0d), TOBN(0x2418871e, 0x02f383fa),
-+     TOBN(0xd7177681, 0x4082c157), TOBN(0xcc914ad0, 0x29c20073),
-+     TOBN(0xf186c1eb, 0xe587e728), TOBN(0x6fdb3c22, 0x61bcd5fd),
-+     TOBN(0x30d014a6, 0xf2f9f8e9), TOBN(0x963ece23, 0x4fec49d2),
-+     TOBN(0x862025c5, 0x9605a8d9), TOBN(0x39874445, 0x19f8929a),
-+     TOBN(0x01b6ff65, 0x12bf476a), TOBN(0x598a64d8, 0x09cf7d91),
-+     TOBN(0xd7ec7749, 0x93be56ca), TOBN(0x10899785, 0xcbb33615),
-+     TOBN(0xb8a092fd, 0x02eee3ad), TOBN(0xa86b3d35, 0x30145270),
-+     TOBN(0x323d98c6, 0x8512b675), TOBN(0x4b8bc785, 0x62ebb40f),
-+     TOBN(0x7d301f54, 0x413f9cde), TOBN(0xa5e4fb4f, 0x2bab5664),
-+     TOBN(0x1d2b252d, 0x1cbfec23), TOBN(0xfcd576bb, 0xe177120d),
-+     TOBN(0x04427d3e, 0x83731a34), TOBN(0x2bb9028e, 0xed836e8e),
-+     TOBN(0xb36acff8, 0xb612ca7c), TOBN(0xb88fe5ef, 0xd3d9c73a),
-+     TOBN(0xbe2a6bc6, 0xedea4eb3), TOBN(0x43b93133, 0x488eec77),
-+     TOBN(0xf41ff566, 0xb17106e1), TOBN(0x469e9172, 0x654efa32),
-+     TOBN(0xb4480f04, 0x41c23fa3), TOBN(0xb4712eb0, 0xc1989a2e),
-+     TOBN(0x3ccbba0f, 0x93a29ca7), TOBN(0x6e205c14, 0xd619428c),
-+     TOBN(0x90db7957, 0xb3641686), TOBN(0x0432691d, 0x45ac8b4e),
-+     TOBN(0x07a759ac, 0xf64e0350), TOBN(0x0514d89c, 0x9c972517),
-+     TOBN(0x1701147f, 0xa8e67fc3), TOBN(0x9e2e0b8b, 0xab2085be),
-+     TOBN(0xd5651824, 0xac284e57), TOBN(0x890d4325, 0x74893664),
-+     TOBN(0x8a7c5e6e, 0xc55e68a3), TOBN(0xbf12e90b, 0x4339c85a),
-+     TOBN(0x31846b85, 0xf922b655), TOBN(0x9a54ce4d, 0x0bf4d700),
-+     TOBN(0xd7f4e83a, 0xf1a14295), TOBN(0x916f955c, 0xb285d4f9),
-+     TOBN(0xe57bb0e0, 0x99ffdaba), TOBN(0x28a43034, 0xeab0d152),
-+     TOBN(0x0a36ffa2, 0xb8a9cef8), TOBN(0x5517407e, 0xb9ec051a),
-+     TOBN(0x9c796096, 0xea68e672), TOBN(0x853db5fb, 0xfb3c77fb),
-+     TOBN(0x21474ba9, 0xe864a51a), TOBN(0x6c267699, 0x6e8a1b8b),
-+     TOBN(0x7c823626, 0x94120a28), TOBN(0xe61e9a48, 0x8383a5db),
-+     TOBN(0x7dd75003, 0x9f84216d), TOBN(0xab020d07, 0xad43cd85),
-+     TOBN(0x9437ae48, 0xda12c659), TOBN(0x6449c2eb, 0xe65452ad),
-+     TOBN(0xcc7c4c1c, 0x2cf9d7c1), TOBN(0x1320886a, 0xee95e5ab),
-+     TOBN(0xbb7b9056, 0xbeae170c), TOBN(0xc8a5b250, 0xdbc0d662),
-+     TOBN(0x4ed81432, 0xc11d2303), TOBN(0x7da66912, 0x1f03769f),
-+     TOBN(0x3ac7a5fd, 0x84539828), TOBN(0x14dada94, 0x3bccdd02),
-+     TOBN(0x8b84c321, 0x7ef6b0d1), TOBN(0x52a9477a, 0x7c933f22),
-+     TOBN(0x5ef6728a, 0xfd440b82), TOBN(0x5c3bd859, 0x6ce4bd5e),
-+     TOBN(0x918b80f5, 0xf22c2d3e), TOBN(0x368d5040, 0xb7bb6cc5),
-+     TOBN(0xb66142a1, 0x2695a11c), TOBN(0x60ac583a, 0xeb19ea70),
-+     TOBN(0x317cbb98, 0x0eab2437), TOBN(0x8cc08c55, 0x5e2654c8),
-+     TOBN(0xfe2d6520, 0xe6d8307f), TOBN(0xe9f147f3, 0x57428993),
-+     TOBN(0x5f9c7d14, 0xd2fd6cf1), TOBN(0xa3ecd064, 0x2d4fcbb0),
-+     TOBN(0xad83fef0, 0x8e7341f7), TOBN(0x643f23a0, 0x3a63115c),
-+     TOBN(0xd38a78ab, 0xe65ab743), TOBN(0xbf7c75b1, 0x35edc89c),
-+     TOBN(0x3dd8752e, 0x530df568), TOBN(0xf85c4a76, 0xe308c682),
-+     TOBN(0x4c9955b2, 0xe68acf37), TOBN(0xa544df3d, 0xab32af85),
-+     TOBN(0x4b8ec3f5, 0xa25cf493), TOBN(0x4d8f2764, 0x1a622feb),
-+     TOBN(0x7bb4f7aa, 0xf0dcbc49), TOBN(0x7de551f9, 0x70bbb45b),
-+     TOBN(0xcfd0f3e4, 0x9f2ca2e5), TOBN(0xece58709, 0x1f5c76ef),
-+     TOBN(0x32920edd, 0x167d79ae), TOBN(0x039df8a2, 0xfa7d7ec1),
-+     TOBN(0xf46206c0, 0xbb30af91), TOBN(0x1ff5e2f5, 0x22676b59),
-+     TOBN(0x11f4a039, 0x6ea51d66), TOBN(0x506c1445, 0x807d7a26),
-+     TOBN(0x60da5705, 0x755a9b24), TOBN(0x8fc8cc32, 0x1f1a319e),
-+     TOBN(0x83642d4d, 0x9433d67d), TOBN(0x7fa5cb8f, 0x6a7dd296),
-+     TOBN(0x576591db, 0x9b7bde07), TOBN(0x13173d25, 0x419716fb),
-+     TOBN(0xea30599d, 0xd5b340ff), TOBN(0xfc6b5297, 0xb0fe76c5),
-+     TOBN(0x1c6968c8, 0xab8f5adc), TOBN(0xf723c7f5, 0x901c928d),
-+     TOBN(0x4203c321, 0x9773d402), TOBN(0xdf7c6aa3, 0x1b51dd47),
-+     TOBN(0x3d49e37a, 0x552be23c), TOBN(0x57febee8, 0x0b5a6e87),
-+     TOBN(0xc5ecbee4, 0x7bd8e739), TOBN(0x79d44994, 0xae63bf75),
-+     TOBN(0x168bd00f, 0x38fb8923), TOBN(0x75d48ee4, 0xd0533130),
-+     TOBN(0x554f77aa, 0xdb5cdf33), TOBN(0x3396e896, 0x3c696769),
-+     TOBN(0x2fdddbf2, 0xd3fd674e), TOBN(0xbbb8f6ee, 0x99d0e3e5),
-+     TOBN(0x51b90651, 0xcbae2f70), TOBN(0xefc4bc05, 0x93aaa8eb),
-+     TOBN(0x8ecd8689, 0xdd1df499), TOBN(0x1aee99a8, 0x22f367a5),
-+     TOBN(0x95d485b9, 0xae8274c5), TOBN(0x6c14d445, 0x7d30b39c),
-+     TOBN(0xbafea90b, 0xbcc1ef81), TOBN(0x7c5f317a, 0xa459a2ed),
-+     TOBN(0x01211075, 0x4ef44227), TOBN(0xa17bed6e, 0xdc20f496),
-+     TOBN(0x0cdfe424, 0x819853cd), TOBN(0x13793298, 0xf71e2ce7),
-+     TOBN(0x3c1f3078, 0xdbbe307b), TOBN(0x6dd1c20e, 0x76ee9936),
-+     TOBN(0x23ee4b57, 0x423caa20), TOBN(0x4ac3793b, 0x8efb840e),
-+     TOBN(0x934438eb, 0xed1f8ca0), TOBN(0x3e546658, 0x4ebb25a2),
-+     TOBN(0xc415af0e, 0xc069896f), TOBN(0xc13eddb0, 0x9a5aa43d),
-+     TOBN(0x7a04204f, 0xd49eb8f6), TOBN(0xd0d5bdfc, 0xd74f1670),
-+     TOBN(0x3697e286, 0x56fc0558), TOBN(0x10207371, 0x01cebade),
-+     TOBN(0x5f87e690, 0x0647a82b), TOBN(0x908e0ed4, 0x8f40054f),
-+     TOBN(0xa9f633d4, 0x79853803), TOBN(0x8ed13c9a, 0x4a28b252),
-+     TOBN(0x3e2ef676, 0x1f460f64), TOBN(0x53930b9b, 0x36d06336),
-+     TOBN(0x347073ac, 0x8fc4979b), TOBN(0x84380e0e, 0x5ecd5597),
-+     TOBN(0xe3b22c6b, 0xc4fe3c39), TOBN(0xba4a8153, 0x6c7bebdf),
-+     TOBN(0xf23ab6b7, 0x25693459), TOBN(0x53bc3770, 0x14922b11),
-+     TOBN(0x4645c8ab, 0x5afc60db), TOBN(0xaa022355, 0x20b9f2a3),
-+     TOBN(0x52a2954c, 0xce0fc507), TOBN(0x8c2731bb, 0x7ce1c2e7),
-+     TOBN(0xf39608ab, 0x18a0339d), TOBN(0xac7a658d, 0x3735436c),
-+     TOBN(0xb22c2b07, 0xcd992b4f), TOBN(0x4e83daec, 0xf40dcfd4),
-+     TOBN(0x8a34c7be, 0x2f39ea3e), TOBN(0xef0c005f, 0xb0a56d2e),
-+     TOBN(0x62731f6a, 0x6edd8038), TOBN(0x5721d740, 0x4e3cb075),
-+     TOBN(0x1ea41511, 0xfbeeee1b), TOBN(0xd1ef5e73, 0xef1d0c05),
-+     TOBN(0x42feefd1, 0x73c07d35), TOBN(0xe530a00a, 0x8a329493),
-+     TOBN(0x5d55b7fe, 0xf15ebfb0), TOBN(0x549de03c, 0xd322491a),
-+     TOBN(0xf7b5f602, 0x745b3237), TOBN(0x3632a3a2, 0x1ab6e2b6),
-+     TOBN(0x0d3bba89, 0x0ef59f78), TOBN(0x0dfc6443, 0xc9e52b9a),
-+     TOBN(0x1dc79699, 0x72631447), TOBN(0xef033917, 0xb3be20b1),
-+     TOBN(0x0c92735d, 0xb1383948), TOBN(0xc1fc29a2, 0xc0dd7d7d),
-+     TOBN(0x6485b697, 0x403ed068), TOBN(0x13bfaab3, 0xaac93bdc),
-+     TOBN(0x410dc6a9, 0x0deeaf52), TOBN(0xb003fb02, 0x4c641c15),
-+     TOBN(0x1384978c, 0x5bc504c4), TOBN(0x37640487, 0x864a6a77),
-+     TOBN(0x05991bc6, 0x222a77da), TOBN(0x62260a57, 0x5e47eb11),
-+     TOBN(0xc7af6613, 0xf21b432c), TOBN(0x22f3acc9, 0xab4953e9),
-+     TOBN(0x52934922, 0x8e41d155), TOBN(0x4d024568, 0x3ac059ef),
-+     TOBN(0xb0201755, 0x4d884411), TOBN(0xce8055cf, 0xa59a178f),
-+     TOBN(0xcd77d1af, 0xf6204549), TOBN(0xa0a00a3e, 0xc7066759),
-+     TOBN(0x471071ef, 0x0272c229), TOBN(0x009bcf6b, 0xd3c4b6b0),
-+     TOBN(0x2a2638a8, 0x22305177), TOBN(0xd51d59df, 0x41645bbf),
-+     TOBN(0xa81142fd, 0xc0a7a3c0), TOBN(0xa17eca6d, 0x4c7063ee),
-+     TOBN(0x0bb887ed, 0x60d9dcec), TOBN(0xd6d28e51, 0x20ad2455),
-+     TOBN(0xebed6308, 0xa67102ba), TOBN(0x042c3114, 0x8bffa408),
-+     TOBN(0xfd099ac5, 0x8aa68e30), TOBN(0x7a6a3d7c, 0x1483513e),
-+     TOBN(0xffcc6b75, 0xba2d8f0c), TOBN(0x54dacf96, 0x1e78b954),
-+     TOBN(0xf645696f, 0xa4a9af89), TOBN(0x3a411940, 0x06ac98ec),
-+     TOBN(0x41b8b3f6, 0x22a67a20), TOBN(0x2d0b1e0f, 0x99dec626),
-+     TOBN(0x27c89192, 0x40be34e8), TOBN(0xc7162b37, 0x91907f35),
-+     TOBN(0x90188ec1, 0xa956702b), TOBN(0xca132f7d, 0xdf93769c),
-+     TOBN(0x3ece44f9, 0x0e2025b4), TOBN(0x67aaec69, 0x0c62f14c),
-+     TOBN(0xad741418, 0x22e3cc11), TOBN(0xcf9b75c3, 0x7ff9a50e),
-+     TOBN(0x02fa2b16, 0x4d348272), TOBN(0xbd99d61a, 0x9959d56d),
-+     TOBN(0xbc4f19db, 0x18762916), TOBN(0xcc7cce50, 0x49c1ac80),
-+     TOBN(0x4d59ebaa, 0xd846bd83), TOBN(0x8775a9dc, 0xa9202849),
-+     TOBN(0x07ec4ae1, 0x6e1f4ca9), TOBN(0x27eb5875, 0xba893f11),
-+     TOBN(0x00284d51, 0x662cc565), TOBN(0x82353a6b, 0x0db4138d),
-+     TOBN(0xd9c7aaaa, 0xaa32a594), TOBN(0xf5528b5e, 0xa5669c47),
-+     TOBN(0xf3220231, 0x2f23c5ff), TOBN(0xe3e8147a, 0x6affa3a1),
-+     TOBN(0xfb423d5c, 0x202ddda0), TOBN(0x3d6414ac, 0x6b871bd4),
-+     TOBN(0x586f82e1, 0xa51a168a), TOBN(0xb712c671, 0x48ae5448),
-+     TOBN(0x9a2e4bd1, 0x76233eb8), TOBN(0x0188223a, 0x78811ca9),
-+     TOBN(0x553c5e21, 0xf7c18de1), TOBN(0x7682e451, 0xb27bb286),
-+     TOBN(0x3ed036b3, 0x0e51e929), TOBN(0xf487211b, 0xec9cb34f),
-+     TOBN(0x0d094277, 0x0c24efc8), TOBN(0x0349fd04, 0xbef737a4),
-+     TOBN(0x6d1c9dd2, 0x514cdd28), TOBN(0x29c135ff, 0x30da9521),
-+     TOBN(0xea6e4508, 0xf78b0b6f), TOBN(0x176f5dd2, 0x678c143c),
-+     TOBN(0x08148418, 0x4be21e65), TOBN(0x27f7525c, 0xe7df38c4),
-+     TOBN(0x1fb70e09, 0x748ab1a4), TOBN(0x9cba50a0, 0x5efe4433),
-+     TOBN(0x7846c7a6, 0x15f75af2), TOBN(0x2a7c2c57, 0x5ee73ea8),
-+     TOBN(0x42e566a4, 0x3f0a449a), TOBN(0x45474c3b, 0xad90fc3d),
-+     TOBN(0x7447be3d, 0x8b61d057), TOBN(0x3e9d1cf1, 0x3a4ec092),
-+     TOBN(0x1603e453, 0xf380a6e6), TOBN(0x0b86e431, 0x9b1437c2),
-+     TOBN(0x7a4173f2, 0xef29610a), TOBN(0x8fa729a7, 0xf03d57f7),
-+     TOBN(0x3e186f6e, 0x6c9c217e), TOBN(0xbe1d3079, 0x91919524),
-+     TOBN(0x92a62a70, 0x153d4fb1), TOBN(0x32ed3e34, 0xd68c2f71),
-+     TOBN(0xd785027f, 0x9eb1a8b7), TOBN(0xbc37eb77, 0xc5b22fe8),
-+     TOBN(0x466b34f0, 0xb9d6a191), TOBN(0x008a89af, 0x9a05f816),
-+     TOBN(0x19b028fb, 0x7d42c10a), TOBN(0x7fe8c92f, 0x49b3f6b8),
-+     TOBN(0x58907cc0, 0xa5a0ade3), TOBN(0xb3154f51, 0x559d1a7c),
-+     TOBN(0x5066efb6, 0xd9790ed6), TOBN(0xa77a0cbc, 0xa6aa793b),
-+     TOBN(0x1a915f3c, 0x223e042e), TOBN(0x1c5def04, 0x69c5874b),
-+     TOBN(0x0e830078, 0x73b6c1da), TOBN(0x55cf85d2, 0xfcd8557a),
-+     TOBN(0x0f7c7c76, 0x0460f3b1), TOBN(0x87052acb, 0x46e58063),
-+     TOBN(0x09212b80, 0x907eae66), TOBN(0x3cb068e0, 0x4d721c89),
-+     TOBN(0xa87941ae, 0xdd45ac1c), TOBN(0xde8d5c0d, 0x0daa0dbb),
-+     TOBN(0xda421fdc, 0xe3502e6e), TOBN(0xc8944201, 0x4d89a084),
-+     TOBN(0x7307ba5e, 0xf0c24bfb), TOBN(0xda212beb, 0x20bde0ef),
-+     TOBN(0xea2da24b, 0xf82ce682), TOBN(0x058d3816, 0x07f71fe4),
-+     TOBN(0x35a02462, 0x5ffad8de), TOBN(0xcd7b05dc, 0xaadcefab),
-+     TOBN(0xd442f8ed, 0x1d9f54ec), TOBN(0x8be3d618, 0xb2d3b5ca),
-+     TOBN(0xe2220ed0, 0xe06b2ce2), TOBN(0x82699a5f, 0x1b0da4c0),
-+     TOBN(0x3ff106f5, 0x71c0c3a7), TOBN(0x8f580f5a, 0x0d34180c),
-+     TOBN(0x4ebb120e, 0x22d7d375), TOBN(0x5e5782cc, 0xe9513675),
-+     TOBN(0x2275580c, 0x99c82a70), TOBN(0xe8359fbf, 0x15ea8c4c),
-+     TOBN(0x53b48db8, 0x7b415e70), TOBN(0xaacf2240, 0x100c6014),
-+     TOBN(0x9faaccf5, 0xe4652f1d), TOBN(0xbd6fdd2a, 0xd56157b2),
-+     TOBN(0xa4f4fb1f, 0x6261ec50), TOBN(0x244e55ad, 0x476bcd52),
-+     TOBN(0x881c9305, 0x047d320b), TOBN(0x1ca983d5, 0x6181263f),
-+     TOBN(0x354e9a44, 0x278fb8ee), TOBN(0xad2dbc0f, 0x396e4964),
-+     TOBN(0x723f3aa2, 0x9268b3de), TOBN(0x0d1ca29a, 0xe6e0609a),
-+     TOBN(0x794866aa, 0x6cf44252), TOBN(0x0b59f3e3, 0x01af87ed),
-+     TOBN(0xe234e5ff, 0x7f4a6c51), TOBN(0xa8768fd2, 0x61dc2f7e),
-+     TOBN(0xdafc7332, 0x0a94d81f), TOBN(0xd7f84282, 0x06938ce1),
-+     TOBN(0xae0b3c0e, 0x0546063e), TOBN(0x7fbadcb2, 0x5d61abc6),
-+     TOBN(0xd5d7a2c9, 0x369ac400), TOBN(0xa5978d09, 0xae67d10c),
-+     TOBN(0x290f211e, 0x4f85eaac), TOBN(0xe61e2ad1, 0xfacac681),
-+     TOBN(0xae125225, 0x388384cd), TOBN(0xa7fb68e9, 0xccfde30f),
-+     TOBN(0x7a59b936, 0x3daed4c2), TOBN(0x80a9aa40, 0x2606f789),
-+     TOBN(0xb40c1ea5, 0xf6a6d90a), TOBN(0x948364d3, 0x514d5885),
-+     TOBN(0x062ebc60, 0x70985182), TOBN(0xa6db5b0e, 0x33310895),
-+     TOBN(0x64a12175, 0xe329c2f5), TOBN(0xc5f25bd2, 0x90ea237e),
-+     TOBN(0x7915c524, 0x2d0a4c23), TOBN(0xeb5d26e4, 0x6bb3cc52),
-+     TOBN(0x369a9116, 0xc09e2c92), TOBN(0x0c527f92, 0xcf182cf8),
-+     TOBN(0x9e591938, 0x2aede0ac), TOBN(0xb2922208, 0x6cc34939),
-+     TOBN(0x3c9d8962, 0x99a34361), TOBN(0x3c81836d, 0xc1905fe6),
-+     TOBN(0x4bfeb57f, 0xa001ec5a), TOBN(0xe993f5bb, 0xa0dc5dba),
-+     TOBN(0x47884109, 0x724a1380), TOBN(0x8a0369ab, 0x32fe9a04),
-+     TOBN(0xea068d60, 0x8c927db8), TOBN(0xbf5f37cf, 0x94655741),
-+     TOBN(0x47d402a2, 0x04b6c7ea), TOBN(0x4551c295, 0x6af259cb),
-+     TOBN(0x698b71e7, 0xed77ee8b), TOBN(0xbddf7bd0, 0xf309d5c7),
-+     TOBN(0x6201c22c, 0x34e780ca), TOBN(0xab04f7d8, 0x4c295ef4),
-+     TOBN(0x1c947294, 0x4313a8ce), TOBN(0xe532e4ac, 0x92ca4cfe),
-+     TOBN(0x89738f80, 0xd0a7a97a), TOBN(0xec088c88, 0xa580fd5b),
-+     TOBN(0x612b1ecc, 0x42ce9e51), TOBN(0x8f9840fd, 0xb25fdd2a),
-+     TOBN(0x3cda78c0, 0x01e7f839), TOBN(0x546b3d3a, 0xece05480),
-+     TOBN(0x271719a9, 0x80d30916), TOBN(0x45497107, 0x584c20c4),
-+     TOBN(0xaf8f9478, 0x5bc78608), TOBN(0x28c7d484, 0x277e2a4c),
-+     TOBN(0xfce01767, 0x88a2ffe4), TOBN(0xdc506a35, 0x28e169a5),
-+     TOBN(0x0ea10861, 0x7af9c93a), TOBN(0x1ed24361, 0x03fa0e08),
-+     TOBN(0x96eaaa92, 0xa3d694e7), TOBN(0xc0f43b4d, 0xef50bc74),
-+     TOBN(0xce6aa58c, 0x64114db4), TOBN(0x8218e8ea, 0x7c000fd4),
-+     TOBN(0xac815dfb, 0x185f8844), TOBN(0xcd7e90cb, 0x1557abfb),
-+     TOBN(0x23d16655, 0xafbfecdf), TOBN(0x80f3271f, 0x085cac4a),
-+     TOBN(0x7fc39aa7, 0xd0e62f47), TOBN(0x88d519d1, 0x460a48e5),
-+     TOBN(0x59559ac4, 0xd28f101e), TOBN(0x7981d9e9, 0xca9ae816),
-+     TOBN(0x5c38652c, 0x9ac38203), TOBN(0x86eaf87f, 0x57657fe5),
-+     TOBN(0x568fc472, 0xe21f5416), TOBN(0x2afff39c, 0xe7e597b5),
-+     TOBN(0x3adbbb07, 0x256d4eab), TOBN(0x22598692, 0x8285ab89),
-+     TOBN(0x35f8112a, 0x041caefe), TOBN(0x95df02e3, 0xa5064c8b),
-+     TOBN(0x4d63356e, 0xc7004bf3), TOBN(0x230a08f4, 0xdb83c7de),
-+     TOBN(0xca27b270, 0x8709a7b7), TOBN(0x0d1c4cc4, 0xcb9abd2d),
-+     TOBN(0x8a0bc66e, 0x7550fee8), TOBN(0x369cd4c7, 0x9cf7247e),
-+     TOBN(0x75562e84, 0x92b5b7e7), TOBN(0x8fed0da0, 0x5802af7b),
-+     TOBN(0x6a7091c2, 0xe48fb889), TOBN(0x26882c13, 0x7b8a9d06),
-+     TOBN(0xa2498663, 0x1b82a0e2), TOBN(0x844ed736, 0x3518152d),
-+     TOBN(0x282f476f, 0xd86e27c7), TOBN(0xa04edaca, 0x04afefdc),
-+     TOBN(0x8b256ebc, 0x6119e34d), TOBN(0x56a413e9, 0x0787d78b),}
-+    ,
-+    {TOBN(0x82ee061d, 0x5a74be50), TOBN(0xe41781c4, 0xdea16ff5),
-+     TOBN(0xe0b0c81e, 0x99bfc8a2), TOBN(0x624f4d69, 0x0b547e2d),
-+     TOBN(0x3a83545d, 0xbdcc9ae4), TOBN(0x2573dbb6, 0x409b1e8e),
-+     TOBN(0x482960c4, 0xa6c93539), TOBN(0xf01059ad, 0x5ae18798),
-+     TOBN(0x715c9f97, 0x3112795f), TOBN(0xe8244437, 0x984e6ee1),
-+     TOBN(0x55cb4858, 0xecb66bcd), TOBN(0x7c136735, 0xabaffbee),
-+     TOBN(0x54661595, 0x5dbec38e), TOBN(0x51c0782c, 0x388ad153),
-+     TOBN(0x9ba4c53a, 0xc6e0952f), TOBN(0x27e6782a, 0x1b21dfa8),
-+     TOBN(0x682f903d, 0x4ed2dbc2), TOBN(0x0eba59c8, 0x7c3b2d83),
-+     TOBN(0x8e9dc84d, 0x9c7e9335), TOBN(0x5f9b21b0, 0x0eb226d7),
-+     TOBN(0xe33bd394, 0xaf267bae), TOBN(0xaa86cc25, 0xbe2e15ae),
-+     TOBN(0x4f0bf67d, 0x6a8ec500), TOBN(0x5846aa44, 0xf9630658),
-+     TOBN(0xfeb09740, 0xe2c2bf15), TOBN(0x627a2205, 0xa9e99704),
-+     TOBN(0xec8d73d0, 0xc2fbc565), TOBN(0x223eed8f, 0xc20c8de8),
-+     TOBN(0x1ee32583, 0xa8363b49), TOBN(0x1a0b6cb9, 0xc9c2b0a6),
-+     TOBN(0x49f7c3d2, 0x90dbc85c), TOBN(0xa8dfbb97, 0x1ef4c1ac),
-+     TOBN(0xafb34d4c, 0x65c7c2ab), TOBN(0x1d4610e7, 0xe2c5ea84),
-+     TOBN(0x893f6d1b, 0x973c4ab5), TOBN(0xa3cdd7e9, 0x945ba5c4),
-+     TOBN(0x60514983, 0x064417ee), TOBN(0x1459b23c, 0xad6bdf2b),
-+     TOBN(0x23b2c341, 0x5cf726c3), TOBN(0x3a829635, 0x32d6354a),
-+     TOBN(0x294f901f, 0xab192c18), TOBN(0xec5fcbfe, 0x7030164f),
-+     TOBN(0xe2e2fcb7, 0xe2246ba6), TOBN(0x1e7c88b3, 0x221a1a0c),
-+     TOBN(0x72c7dd93, 0xc92d88c5), TOBN(0x41c2148e, 0x1106fb59),
-+     TOBN(0x547dd4f5, 0xa0f60f14), TOBN(0xed9b52b2, 0x63960f31),
-+     TOBN(0x6c8349eb, 0xb0a5b358), TOBN(0xb154c5c2, 0x9e7e2ed6),
-+     TOBN(0xcad5eccf, 0xeda462db), TOBN(0xf2d6dbe4, 0x2de66b69),
-+     TOBN(0x426aedf3, 0x8665e5b2), TOBN(0x488a8513, 0x7b7f5723),
-+     TOBN(0x15cc43b3, 0x8bcbb386), TOBN(0x27ad0af3, 0xd791d879),
-+     TOBN(0xc16c236e, 0x846e364f), TOBN(0x7f33527c, 0xdea50ca0),
-+     TOBN(0xc4810775, 0x0926b86d), TOBN(0x6c2a3609, 0x0598e70c),
-+     TOBN(0xa6755e52, 0xf024e924), TOBN(0xe0fa07a4, 0x9db4afca),
-+     TOBN(0x15c3ce7d, 0x66831790), TOBN(0x5b4ef350, 0xa6cbb0d6),
-+     TOBN(0x2c4aafc4, 0xb6205969), TOBN(0x42563f02, 0xf6c7854f),
-+     TOBN(0x016aced5, 0x1d983b48), TOBN(0xfeb356d8, 0x99949755),
-+     TOBN(0x8c2a2c81, 0xd1a39bd7), TOBN(0x8f44340f, 0xe6934ae9),
-+     TOBN(0x148cf91c, 0x447904da), TOBN(0x7340185f, 0x0f51a926),
-+     TOBN(0x2f8f00fb, 0x7409ab46), TOBN(0x057e78e6, 0x80e289b2),
-+     TOBN(0x03e5022c, 0xa888e5d1), TOBN(0x3c87111a, 0x9dede4e2),
-+     TOBN(0x5b9b0e1c, 0x7809460b), TOBN(0xe751c852, 0x71c9abc7),
-+     TOBN(0x8b944e28, 0xc7cc1dc9), TOBN(0x4f201ffa, 0x1d3cfa08),
-+     TOBN(0x02fc905c, 0x3e6721ce), TOBN(0xd52d70da, 0xd0b3674c),
-+     TOBN(0x5dc2e5ca, 0x18810da4), TOBN(0xa984b273, 0x5c69dd99),
-+     TOBN(0x63b92527, 0x84de5ca4), TOBN(0x2f1c9872, 0xc852dec4),
-+     TOBN(0x18b03593, 0xc2e3de09), TOBN(0x19d70b01, 0x9813dc2f),
-+     TOBN(0x42806b2d, 0xa6dc1d29), TOBN(0xd3030009, 0xf871e144),
-+     TOBN(0xa1feb333, 0xaaf49276), TOBN(0xb5583b9e, 0xc70bc04b),
-+     TOBN(0x1db0be78, 0x95695f20), TOBN(0xfc841811, 0x89d012b5),
-+     TOBN(0x6409f272, 0x05f61643), TOBN(0x40d34174, 0xd5883128),
-+     TOBN(0xd79196f5, 0x67419833), TOBN(0x6059e252, 0x863b7b08),
-+     TOBN(0x84da1817, 0x1c56700c), TOBN(0x5758ee56, 0xb28d3ec4),
-+     TOBN(0x7da2771d, 0x013b0ea6), TOBN(0xfddf524b, 0x54c5e9b9),
-+     TOBN(0x7df4faf8, 0x24305d80), TOBN(0x58f5c1bf, 0x3a97763f),
-+     TOBN(0xa5af37f1, 0x7c696042), TOBN(0xd4cba22c, 0x4a2538de),
-+     TOBN(0x211cb995, 0x9ea42600), TOBN(0xcd105f41, 0x7b069889),
-+     TOBN(0xb1e1cf19, 0xddb81e74), TOBN(0x472f2d89, 0x5157b8ca),
-+     TOBN(0x086fb008, 0xee9db885), TOBN(0x365cd570, 0x0f26d131),
-+     TOBN(0x284b02bb, 0xa2be7053), TOBN(0xdcbbf7c6, 0x7ab9a6d6),
-+     TOBN(0x4425559c, 0x20f7a530), TOBN(0x961f2dfa, 0x188767c8),
-+     TOBN(0xe2fd9435, 0x70dc80c4), TOBN(0x104d6b63, 0xf0784120),
-+     TOBN(0x7f592bc1, 0x53567122), TOBN(0xf6bc1246, 0xf688ad77),
-+     TOBN(0x05214c05, 0x0f15dde9), TOBN(0xa47a76a8, 0x0d5f2b82),
-+     TOBN(0xbb254d30, 0x62e82b62), TOBN(0x11a05fe0, 0x3ec955ee),
-+     TOBN(0x7eaff46e, 0x9d529b36), TOBN(0x55ab1301, 0x8f9e3df6),
-+     TOBN(0xc463e371, 0x99317698), TOBN(0xfd251438, 0xccda47ad),
-+     TOBN(0xca9c3547, 0x23d695ea), TOBN(0x48ce626e, 0x16e589b5),
-+     TOBN(0x6b5b64c7, 0xb187d086), TOBN(0xd02e1794, 0xb2207948),
-+     TOBN(0x8b58e98f, 0x7198111d), TOBN(0x90ca6305, 0xdcf9c3cc),
-+     TOBN(0x5691fe72, 0xf34089b0), TOBN(0x60941af1, 0xfc7c80ff),
-+     TOBN(0xa09bc0a2, 0x22eb51e5), TOBN(0xc0bb7244, 0xaa9cf09a),
-+     TOBN(0x36a8077f, 0x80159f06), TOBN(0x8b5c989e, 0xdddc560e),
-+     TOBN(0x19d2f316, 0x512e1f43), TOBN(0x02eac554, 0xad08ff62),
-+     TOBN(0x012ab84c, 0x07d20b4e), TOBN(0x37d1e115, 0xd6d4e4e1),
-+     TOBN(0xb6443e1a, 0xab7b19a8), TOBN(0xf08d067e, 0xdef8cd45),
-+     TOBN(0x63adf3e9, 0x685e03da), TOBN(0xcf15a10e, 0x4792b916),
-+     TOBN(0xf44bcce5, 0xb738a425), TOBN(0xebe131d5, 0x9636b2fd),
-+     TOBN(0x94068841, 0x7850d605), TOBN(0x09684eaa, 0xb40d749d),
-+     TOBN(0x8c3c669c, 0x72ba075b), TOBN(0x89f78b55, 0xba469015),
-+     TOBN(0x5706aade, 0x3e9f8ba8), TOBN(0x6d8bd565, 0xb32d7ed7),
-+     TOBN(0x25f4e63b, 0x805f08d6), TOBN(0x7f48200d, 0xc3bcc1b5),
-+     TOBN(0x4e801968, 0xb025d847), TOBN(0x74afac04, 0x87cbe0a8),
-+     TOBN(0x43ed2c2b, 0x7e63d690), TOBN(0xefb6bbf0, 0x0223cdb8),
-+     TOBN(0x4fec3cae, 0x2884d3fe), TOBN(0x065ecce6, 0xd75e25a4),
-+     TOBN(0x6c2294ce, 0x69f79071), TOBN(0x0d9a8e5f, 0x044b8666),
-+     TOBN(0x5009f238, 0x17b69d8f), TOBN(0x3c29f8fe, 0xc5dfdaf7),
-+     TOBN(0x9067528f, 0xebae68c4), TOBN(0x5b385632, 0x30c5ba21),
-+     TOBN(0x540df119, 0x1fdd1aec), TOBN(0xcf37825b, 0xcfba4c78),
-+     TOBN(0x77eff980, 0xbeb11454), TOBN(0x40a1a991, 0x60c1b066),
-+     TOBN(0xe8018980, 0xf889a1c7), TOBN(0xb9c52ae9, 0x76c24be0),
-+     TOBN(0x05fbbcce, 0x45650ef4), TOBN(0xae000f10, 0x8aa29ac7),
-+     TOBN(0x884b7172, 0x4f04c470), TOBN(0x7cd4fde2, 0x19bb5c25),
-+     TOBN(0x6477b22a, 0xe8840869), TOBN(0xa8868859, 0x5fbd0686),
-+     TOBN(0xf23cc02e, 0x1116dfba), TOBN(0x76cd563f, 0xd87d7776),
-+     TOBN(0xe2a37598, 0xa9d82abf), TOBN(0x5f188ccb, 0xe6c170f5),
-+     TOBN(0x81682200, 0x5066b087), TOBN(0xda22c212, 0xc7155ada),
-+     TOBN(0x151e5d3a, 0xfbddb479), TOBN(0x4b606b84, 0x6d715b99),
-+     TOBN(0x4a73b54b, 0xf997cb2e), TOBN(0x9a1bfe43, 0x3ecd8b66),
-+     TOBN(0x1c312809, 0x2a67d48a), TOBN(0xcd6a671e, 0x031fa9e2),
-+     TOBN(0xbec3312a, 0x0e43a34a), TOBN(0x1d935639, 0x55ef47d3),
-+     TOBN(0x5ea02489, 0x8fea73ea), TOBN(0x8247b364, 0xa035afb2),
-+     TOBN(0xb58300a6, 0x5265b54c), TOBN(0x3286662f, 0x722c7148),
-+     TOBN(0xb77fd76b, 0xb4ec4c20), TOBN(0xf0a12fa7, 0x0f3fe3fd),
-+     TOBN(0xf845bbf5, 0x41d8c7e8), TOBN(0xe4d969ca, 0x5ec10aa8),
-+     TOBN(0x4c0053b7, 0x43e232a3), TOBN(0xdc7a3fac, 0x37f8a45a),
-+     TOBN(0x3c4261c5, 0x20d81c8f), TOBN(0xfd4b3453, 0xb00eab00),
-+     TOBN(0x76d48f86, 0xd36e3062), TOBN(0x626c5277, 0xa143ff02),
-+     TOBN(0x538174de, 0xaf76f42e), TOBN(0x2267aa86, 0x6407ceac),
-+     TOBN(0xfad76351, 0x72e572d5), TOBN(0xab861af7, 0xba7330eb),
-+     TOBN(0xa0a1c8c7, 0x418d8657), TOBN(0x988821cb, 0x20289a52),
-+     TOBN(0x79732522, 0xcccc18ad), TOBN(0xaadf3f8d, 0xf1a6e027),
-+     TOBN(0xf7382c93, 0x17c2354d), TOBN(0x5ce1680c, 0xd818b689),
-+     TOBN(0x359ebbfc, 0xd9ecbee9), TOBN(0x4330689c, 0x1cae62ac),
-+     TOBN(0xb55ce5b4, 0xc51ac38a), TOBN(0x7921dfea, 0xfe238ee8),
-+     TOBN(0x3972bef8, 0x271d1ca5), TOBN(0x3e423bc7, 0xe8aabd18),
-+     TOBN(0x57b09f3f, 0x44a3e5e3), TOBN(0x5da886ae, 0x7b444d66),
-+     TOBN(0x68206634, 0xa9964375), TOBN(0x356a2fa3, 0x699cd0ff),
-+     TOBN(0xaf0faa24, 0xdba515e9), TOBN(0x536e1f5c, 0xb321d79a),
-+     TOBN(0xd3b9913a, 0x5c04e4ea), TOBN(0xd549dcfe, 0xd6f11513),
-+     TOBN(0xee227bf5, 0x79fd1d94), TOBN(0x9f35afee, 0xb43f2c67),
-+     TOBN(0xd2638d24, 0xf1314f53), TOBN(0x62baf948, 0xcabcd822),
-+     TOBN(0x5542de29, 0x4ef48db0), TOBN(0xb3eb6a04, 0xfc5f6bb2),
-+     TOBN(0x23c110ae, 0x1208e16a), TOBN(0x1a4d15b5, 0xf8363e24),
-+     TOBN(0x30716844, 0x164be00b), TOBN(0xa8e24824, 0xf6f4690d),
-+     TOBN(0x548773a2, 0x90b170cf), TOBN(0xa1bef331, 0x42f191f4),
-+     TOBN(0x70f418d0, 0x9247aa97), TOBN(0xea06028e, 0x48be9147),
-+     TOBN(0xe13122f3, 0xdbfb894e), TOBN(0xbe9b79f6, 0xce274b18),
-+     TOBN(0x85a49de5, 0xca58aadf), TOBN(0x24957758, 0x11487351),
-+     TOBN(0x111def61, 0xbb939099), TOBN(0x1d6a974a, 0x26d13694),
-+     TOBN(0x4474b4ce, 0xd3fc253b), TOBN(0x3a1485e6, 0x4c5db15e),
-+     TOBN(0xe79667b4, 0x147c15b4), TOBN(0xe34f553b, 0x7bc61301),
-+     TOBN(0x032b80f8, 0x17094381), TOBN(0x55d8bafd, 0x723eaa21),
-+     TOBN(0x5a987995, 0xf1c0e74e), TOBN(0x5a9b292e, 0xebba289c),
-+     TOBN(0x413cd4b2, 0xeb4c8251), TOBN(0x98b5d243, 0xd162db0a),
-+     TOBN(0xbb47bf66, 0x68342520), TOBN(0x08d68949, 0xbaa862d1),
-+     TOBN(0x11f349c7, 0xe906abcd), TOBN(0x454ce985, 0xed7bf00e),
-+     TOBN(0xacab5c9e, 0xb55b803b), TOBN(0xb03468ea, 0x31e3c16d),
-+     TOBN(0x5c24213d, 0xd273bf12), TOBN(0x211538eb, 0x71587887),
-+     TOBN(0x198e4a2f, 0x731dea2d), TOBN(0xd5856cf2, 0x74ed7b2a),
-+     TOBN(0x86a632eb, 0x13a664fe), TOBN(0x932cd909, 0xbda41291),
-+     TOBN(0x850e95d4, 0xc0c4ddc0), TOBN(0xc0f422f8, 0x347fc2c9),
-+     TOBN(0xe68cbec4, 0x86076bcb), TOBN(0xf9e7c0c0, 0xcd6cd286),
-+     TOBN(0x65994ddb, 0x0f5f27ca), TOBN(0xe85461fb, 0xa80d59ff),
-+     TOBN(0xff05481a, 0x66601023), TOBN(0xc665427a, 0xfc9ebbfb),
-+     TOBN(0xb0571a69, 0x7587fd52), TOBN(0x935289f8, 0x8d49efce),
-+     TOBN(0x61becc60, 0xea420688), TOBN(0xb22639d9, 0x13a786af),
-+     TOBN(0x1a8e6220, 0x361ecf90), TOBN(0x001f23e0, 0x25506463),
-+     TOBN(0xe4ae9b5d, 0x0a5c2b79), TOBN(0xebc9cdad, 0xd8149db5),
-+     TOBN(0xb33164a1, 0x934aa728), TOBN(0x750eb00e, 0xae9b60f3),
-+     TOBN(0x5a91615b, 0x9b9cfbfd), TOBN(0x97015cbf, 0xef45f7f6),
-+     TOBN(0xb462c4a5, 0xbf5151df), TOBN(0x21adcc41, 0xb07118f2),
-+     TOBN(0xd60c545b, 0x043fa42c), TOBN(0xfc21aa54, 0xe96be1ab),
-+     TOBN(0xe84bc32f, 0x4e51ea80), TOBN(0x3dae45f0, 0x259b5d8d),
-+     TOBN(0xbb73c7eb, 0xc38f1b5e), TOBN(0xe405a74a, 0xe8ae617d),
-+     TOBN(0xbb1ae9c6, 0x9f1c56bd), TOBN(0x8c176b98, 0x49f196a4),
-+     TOBN(0xc448f311, 0x6875092b), TOBN(0xb5afe3de, 0x9f976033),
-+     TOBN(0xa8dafd49, 0x145813e5), TOBN(0x687fc4d9, 0xe2b34226),
-+     TOBN(0xf2dfc92d, 0x4c7ff57f), TOBN(0x004e3fc1, 0x401f1b46),
-+     TOBN(0x5afddab6, 0x1430c9ab), TOBN(0x0bdd41d3, 0x2238e997),
-+     TOBN(0xf0947430, 0x418042ae), TOBN(0x71f9adda, 0xcdddc4cb),
-+     TOBN(0x7090c016, 0xc52dd907), TOBN(0xd9bdf44d, 0x29e2047f),
-+     TOBN(0xe6f1fe80, 0x1b1011a6), TOBN(0xb63accbc, 0xd9acdc78),
-+     TOBN(0xcfc7e235, 0x1272a95b), TOBN(0x0c667717, 0xa6276ac8),
-+     TOBN(0x3c0d3709, 0xe2d7eef7), TOBN(0x5add2b06, 0x9a685b3e),
-+     TOBN(0x363ad32d, 0x14ea5d65), TOBN(0xf8e01f06, 0x8d7dd506),
-+     TOBN(0xc9ea2213, 0x75b4aac6), TOBN(0xed2a2bf9, 0x0d353466),
-+     TOBN(0x439d79b5, 0xe9d3a7c3), TOBN(0x8e0ee5a6, 0x81b7f34b),
-+     TOBN(0xcf3dacf5, 0x1dc4ba75), TOBN(0x1d3d1773, 0xeb3310c7),
-+     TOBN(0xa8e67112, 0x7747ae83), TOBN(0x31f43160, 0x197d6b40),
-+     TOBN(0x0521ccee, 0xcd961400), TOBN(0x67246f11, 0xf6535768),
-+     TOBN(0x702fcc5a, 0xef0c3133), TOBN(0x247cc45d, 0x7e16693b),
-+     TOBN(0xfd484e49, 0xc729b749), TOBN(0x522cef7d, 0xb218320f),
-+     TOBN(0xe56ef405, 0x59ab93b3), TOBN(0x225fba11, 0x9f181071),
-+     TOBN(0x33bd6595, 0x15330ed0), TOBN(0xc4be69d5, 0x1ddb32f7),
-+     TOBN(0x264c7668, 0x0448087c), TOBN(0xac30903f, 0x71432dae),
-+     TOBN(0x3851b266, 0x00f9bf47), TOBN(0x400ed311, 0x6cdd6d03),
-+     TOBN(0x045e79fe, 0xf8fd2424), TOBN(0xfdfd974a, 0xfa6da98b),
-+     TOBN(0x45c9f641, 0x0c1e673a), TOBN(0x76f2e733, 0x5b2c5168),
-+     TOBN(0x1adaebb5, 0x2a601753), TOBN(0xb286514c, 0xc57c2d49),
-+     TOBN(0xd8769670, 0x1e0bfd24), TOBN(0x950c547e, 0x04478922),
-+     TOBN(0xd1d41969, 0xe5d32bfe), TOBN(0x30bc1472, 0x750d6c3e),
-+     TOBN(0x8f3679fe, 0xe0e27f3a), TOBN(0x8f64a7dc, 0xa4a6ee0c),
-+     TOBN(0x2fe59937, 0x633dfb1f), TOBN(0xea82c395, 0x977f2547),
-+     TOBN(0xcbdfdf1a, 0x661ea646), TOBN(0xc7ccc591, 0xb9085451),
-+     TOBN(0x82177962, 0x81761e13), TOBN(0xda57596f, 0x9196885c),
-+     TOBN(0xbc17e849, 0x28ffbd70), TOBN(0x1e6e0a41, 0x2671d36f),
-+     TOBN(0x61ae872c, 0x4152fcf5), TOBN(0x441c87b0, 0x9e77e754),
-+     TOBN(0xd0799dd5, 0xa34dff09), TOBN(0x766b4e44, 0x88a6b171),
-+     TOBN(0xdc06a512, 0x11f1c792), TOBN(0xea02ae93, 0x4be35c3e),
-+     TOBN(0xe5ca4d6d, 0xe90c469e), TOBN(0x4df4368e, 0x56e4ff5c),
-+     TOBN(0x7817acab, 0x4baef62e), TOBN(0x9f5a2202, 0xa85b91e8),
-+     TOBN(0x9666ebe6, 0x6ce57610), TOBN(0x32ad31f3, 0xf73bfe03),
-+     TOBN(0x628330a4, 0x25bcf4d6), TOBN(0xea950593, 0x515056e6),
-+     TOBN(0x59811c89, 0xe1332156), TOBN(0xc89cf1fe, 0x8c11b2d7),
-+     TOBN(0x75b63913, 0x04e60cc0), TOBN(0xce811e8d, 0x4625d375),
-+     TOBN(0x030e43fc, 0x2d26e562), TOBN(0xfbb30b4b, 0x608d36a0),
-+     TOBN(0x634ff82c, 0x48528118), TOBN(0x7c6fe085, 0xcd285911),
-+     TOBN(0x7f2830c0, 0x99358f28), TOBN(0x2e60a95e, 0x665e6c09),
-+     TOBN(0x08407d3d, 0x9b785dbf), TOBN(0x530889ab, 0xa759bce7),
-+     TOBN(0xf228e0e6, 0x52f61239), TOBN(0x2b6d1461, 0x6879be3c),
-+     TOBN(0xe6902c04, 0x51a7bbf7), TOBN(0x30ad99f0, 0x76f24a64),
-+     TOBN(0x66d9317a, 0x98bc6da0), TOBN(0xf4f877f3, 0xcb596ac0),
-+     TOBN(0xb05ff62d, 0x4c44f119), TOBN(0x4555f536, 0xe9b77416),
-+     TOBN(0xc7c0d059, 0x8caed63b), TOBN(0x0cd2b7ce, 0xc358b2a9),
-+     TOBN(0x3f33287b, 0x46945fa3), TOBN(0xf8785b20, 0xd67c8791),
-+     TOBN(0xc54a7a61, 0x9637bd08), TOBN(0x54d4598c, 0x18be79d7),
-+     TOBN(0x889e5acb, 0xc46d7ce1), TOBN(0x9a515bb7, 0x8b085877),
-+     TOBN(0xfac1a03d, 0x0b7a5050), TOBN(0x7d3e738a, 0xf2926035),
-+     TOBN(0x861cc2ce, 0x2a6cb0eb), TOBN(0x6f2e2955, 0x8f7adc79),
-+     TOBN(0x61c4d451, 0x33016376), TOBN(0xd9fd2c80, 0x5ad59090),
-+     TOBN(0xe5a83738, 0xb2b836a1), TOBN(0x855b41a0, 0x7c0d6622),
-+     TOBN(0x186fe317, 0x7cc19af1), TOBN(0x6465c1ff, 0xfdd99acb),
-+     TOBN(0x46e5c23f, 0x6974b99e), TOBN(0x75a7cf8b, 0xa2717cbe),
-+     TOBN(0x4d2ebc3f, 0x062be658), TOBN(0x094b4447, 0x5f209c98),
-+     TOBN(0x4af285ed, 0xb940cb5a), TOBN(0x6706d792, 0x7cc82f10),
-+     TOBN(0xc8c8776c, 0x030526fa), TOBN(0xfa8e6f76, 0xa0da9140),
-+     TOBN(0x77ea9d34, 0x591ee4f0), TOBN(0x5f46e337, 0x40274166),
-+     TOBN(0x1bdf98bb, 0xea671457), TOBN(0xd7c08b46, 0x862a1fe2),
-+     TOBN(0x46cc303c, 0x1c08ad63), TOBN(0x99543440, 0x4c845e7b),
-+     TOBN(0x1b8fbdb5, 0x48f36bf7), TOBN(0x5b82c392, 0x8c8273a7),
-+     TOBN(0x08f712c4, 0x928435d5), TOBN(0x071cf0f1, 0x79330380),
-+     TOBN(0xc74c2d24, 0xa8da054a), TOBN(0xcb0e7201, 0x43c46b5c),
-+     TOBN(0x0ad7337a, 0xc0b7eff3), TOBN(0x8552225e, 0xc5e48b3c),
-+     TOBN(0xe6f78b0c, 0x73f13a5f), TOBN(0x5e70062e, 0x82349cbe),
-+     TOBN(0x6b8d5048, 0xe7073969), TOBN(0x392d2a29, 0xc33cb3d2),
-+     TOBN(0xee4f727c, 0x4ecaa20f), TOBN(0xa068c99e, 0x2ccde707),
-+     TOBN(0xfcd5651f, 0xb87a2913), TOBN(0xea3e3c15, 0x3cc252f0),
-+     TOBN(0x777d92df, 0x3b6cd3e4), TOBN(0x7a414143, 0xc5a732e7),
-+     TOBN(0xa895951a, 0xa71ff493), TOBN(0xfe980c92, 0xbbd37cf6),
-+     TOBN(0x45bd5e64, 0xdecfeeff), TOBN(0x910dc2a9, 0xa44c43e9),
-+     TOBN(0xcb403f26, 0xcca9f54d), TOBN(0x928bbdfb, 0x9303f6db),
-+     TOBN(0x3c37951e, 0xa9eee67c), TOBN(0x3bd61a52, 0xf79961c3),
-+     TOBN(0x09a238e6, 0x395c9a79), TOBN(0x6940ca2d, 0x61eb352d),
-+     TOBN(0x7d1e5c5e, 0xc1875631), TOBN(0x1e19742c, 0x1e1b20d1),
-+     TOBN(0x4633d908, 0x23fc2e6e), TOBN(0xa76e29a9, 0x08959149),
-+     TOBN(0x61069d9c, 0x84ed7da5), TOBN(0x0baa11cf, 0x5dbcad51),
-+     TOBN(0xd01eec64, 0x961849da), TOBN(0x93b75f1f, 0xaf3d8c28),
-+     TOBN(0x57bc4f9f, 0x1ca2ee44), TOBN(0x5a26322d, 0x00e00558),
-+     TOBN(0x1888d658, 0x61a023ef), TOBN(0x1d72aab4, 0xb9e5246e),
-+     TOBN(0xa9a26348, 0xe5563ec0), TOBN(0xa0971963, 0xc3439a43),
-+     TOBN(0x567dd54b, 0xadb9b5b7), TOBN(0x73fac1a1, 0xc45a524b),
-+     TOBN(0x8fe97ef7, 0xfe38e608), TOBN(0x608748d2, 0x3f384f48),
-+     TOBN(0xb0571794, 0xc486094f), TOBN(0x869254a3, 0x8bf3a8d6),
-+     TOBN(0x148a8dd1, 0x310b0e25), TOBN(0x99ab9f3f, 0x9aa3f7d8),
-+     TOBN(0x0927c68a, 0x6706c02e), TOBN(0x22b5e76c, 0x69790e6c),
-+     TOBN(0x6c325260, 0x6c71376c), TOBN(0x53a57690, 0x09ef6657),
-+     TOBN(0x8d63f852, 0xedffcf3a), TOBN(0xb4d2ed04, 0x3c0a6f55),
-+     TOBN(0xdb3aa8de, 0x12519b9e), TOBN(0x5d38e9c4, 0x1e0a569a),
-+     TOBN(0x871528bf, 0x303747e2), TOBN(0xa208e77c, 0xf5b5c18d),
-+     TOBN(0x9d129c88, 0xca6bf923), TOBN(0xbcbf197f, 0xbf02839f),
-+     TOBN(0x9b9bf030, 0x27323194), TOBN(0x3b055a8b, 0x339ca59d),
-+     TOBN(0xb46b2312, 0x0f669520), TOBN(0x19789f1f, 0x497e5f24),
-+     TOBN(0x9c499468, 0xaaf01801), TOBN(0x72ee1190, 0x8b69d59c),
-+     TOBN(0x8bd39595, 0xacf4c079), TOBN(0x3ee11ece, 0x8e0cd048),
-+     TOBN(0xebde86ec, 0x1ed66f18), TOBN(0x225d906b, 0xd61fce43),
-+     TOBN(0x5cab07d6, 0xe8bed74d), TOBN(0x16e4617f, 0x27855ab7),
-+     TOBN(0x6568aadd, 0xb2fbc3dd), TOBN(0xedb5484f, 0x8aeddf5b),
-+     TOBN(0x878f20e8, 0x6dcf2fad), TOBN(0x3516497c, 0x615f5699),}
-+    ,
-+    {TOBN(0xef0a3fec, 0xfa181e69), TOBN(0x9ea02f81, 0x30d69a98),
-+     TOBN(0xb2e9cf8e, 0x66eab95d), TOBN(0x520f2beb, 0x24720021),
-+     TOBN(0x621c540a, 0x1df84361), TOBN(0x12037721, 0x71fa6d5d),
-+     TOBN(0x6e3c7b51, 0x0ff5f6ff), TOBN(0x817a069b, 0xabb2bef3),
-+     TOBN(0x83572fb6, 0xb294cda6), TOBN(0x6ce9bf75, 0xb9039f34),
-+     TOBN(0x20e012f0, 0x095cbb21), TOBN(0xa0aecc1b, 0xd063f0da),
-+     TOBN(0x57c21c3a, 0xf02909e5), TOBN(0xc7d59ecf, 0x48ce9cdc),
-+     TOBN(0x2732b844, 0x8ae336f8), TOBN(0x056e3723, 0x3f4f85f4),
-+     TOBN(0x8a10b531, 0x89e800ca), TOBN(0x50fe0c17, 0x145208fd),
-+     TOBN(0x9e43c0d3, 0xb714ba37), TOBN(0x427d200e, 0x34189acc),
-+     TOBN(0x05dee24f, 0xe616e2c0), TOBN(0x9c25f4c8, 0xee1854c1),
-+     TOBN(0x4d3222a5, 0x8f342a73), TOBN(0x0807804f, 0xa027c952),
-+     TOBN(0xc222653a, 0x4f0d56f3), TOBN(0x961e4047, 0xca28b805),
-+     TOBN(0x2c03f8b0, 0x4a73434b), TOBN(0x4c966787, 0xab712a19),
-+     TOBN(0xcc196c42, 0x864fee42), TOBN(0xc1be93da, 0x5b0ece5c),
-+     TOBN(0xa87d9f22, 0xc131c159), TOBN(0x2bb6d593, 0xdce45655),
-+     TOBN(0x22c49ec9, 0xb809b7ce), TOBN(0x8a41486b, 0xe2c72c2c),
-+     TOBN(0x813b9420, 0xfea0bf36), TOBN(0xb3d36ee9, 0xa66dac69),
-+     TOBN(0x6fddc08a, 0x328cc987), TOBN(0x0a3bcd2c, 0x3a326461),
-+     TOBN(0x7103c49d, 0xd810dbba), TOBN(0xf9d81a28, 0x4b78a4c4),
-+     TOBN(0x3de865ad, 0xe4d55941), TOBN(0xdedafa5e, 0x30384087),
-+     TOBN(0x6f414abb, 0x4ef18b9b), TOBN(0x9ee9ea42, 0xfaee5268),
-+     TOBN(0x260faa16, 0x37a55a4a), TOBN(0xeb19a514, 0x015f93b9),
-+     TOBN(0x51d7ebd2, 0x9e9c3598), TOBN(0x523fc56d, 0x1932178e),
-+     TOBN(0x501d070c, 0xb98fe684), TOBN(0xd60fbe9a, 0x124a1458),
-+     TOBN(0xa45761c8, 0x92bc6b3f), TOBN(0xf5384858, 0xfe6f27cb),
-+     TOBN(0x4b0271f7, 0xb59e763b), TOBN(0x3d4606a9, 0x5b5a8e5e),
-+     TOBN(0x1eda5d9b, 0x05a48292), TOBN(0xda7731d0, 0xe6fec446),
-+     TOBN(0xa3e33693, 0x90d45871), TOBN(0xe9764040, 0x06166d8d),
-+     TOBN(0xb5c33682, 0x89a90403), TOBN(0x4bd17983, 0x72f1d637),
-+     TOBN(0xa616679e, 0xd5d2c53a), TOBN(0x5ec4bcd8, 0xfdcf3b87),
-+     TOBN(0xae6d7613, 0xb66a694e), TOBN(0x7460fc76, 0xe3fc27e5),
-+     TOBN(0x70469b82, 0x95caabee), TOBN(0xde024ca5, 0x889501e3),
-+     TOBN(0x6bdadc06, 0x076ed265), TOBN(0x0cb1236b, 0x5a0ef8b2),
-+     TOBN(0x4065ddbf, 0x0972ebf9), TOBN(0xf1dd3875, 0x22aca432),
-+     TOBN(0xa88b97cf, 0x744aff76), TOBN(0xd1359afd, 0xfe8e3d24),
-+     TOBN(0x52a3ba2b, 0x91502cf3), TOBN(0x2c3832a8, 0x084db75d),
-+     TOBN(0x04a12ddd, 0xde30b1c9), TOBN(0x7802eabc, 0xe31fd60c),
-+     TOBN(0x33707327, 0xa37fddab), TOBN(0x65d6f2ab, 0xfaafa973),
-+     TOBN(0x3525c5b8, 0x11e6f91a), TOBN(0x76aeb0c9, 0x5f46530b),
-+     TOBN(0xe8815ff6, 0x2f93a675), TOBN(0xa6ec9684, 0x05f48679),
-+     TOBN(0x6dcbb556, 0x358ae884), TOBN(0x0af61472, 0xe19e3873),
-+     TOBN(0x72334372, 0xa5f696be), TOBN(0xc65e57ea, 0x6f22fb70),
-+     TOBN(0x268da30c, 0x946cea90), TOBN(0x136a8a87, 0x65681b2a),
-+     TOBN(0xad5e81dc, 0x0f9f44d4), TOBN(0xf09a6960, 0x2c46585a),
-+     TOBN(0xd1649164, 0xc447d1b1), TOBN(0x3b4b36c8, 0x879dc8b1),
-+     TOBN(0x20d4177b, 0x3b6b234c), TOBN(0x096a2505, 0x1730d9d0),
-+     TOBN(0x0611b9b8, 0xef80531d), TOBN(0xba904b3b, 0x64bb495d),
-+     TOBN(0x1192d9d4, 0x93a3147a), TOBN(0x9f30a5dc, 0x9a565545),
-+     TOBN(0x90b1f9cb, 0x6ef07212), TOBN(0x29958546, 0x0d87fc13),
-+     TOBN(0xd3323eff, 0xc17db9ba), TOBN(0xcb18548c, 0xcb1644a8),
-+     TOBN(0x18a306d4, 0x4f49ffbc), TOBN(0x28d658f1, 0x4c2e8684),
-+     TOBN(0x44ba60cd, 0xa99f8c71), TOBN(0x67b7abdb, 0x4bf742ff),
-+     TOBN(0x66310f9c, 0x914b3f99), TOBN(0xae430a32, 0xf412c161),
-+     TOBN(0x1e6776d3, 0x88ace52f), TOBN(0x4bc0fa24, 0x52d7067d),
-+     TOBN(0x03c286aa, 0x8f07cd1b), TOBN(0x4cb8f38c, 0xa985b2c1),
-+     TOBN(0x83ccbe80, 0x8c3bff36), TOBN(0x005a0bd2, 0x5263e575),
-+     TOBN(0x460d7dda, 0x259bdcd1), TOBN(0x4a1c5642, 0xfa5cab6b),
-+     TOBN(0x2b7bdbb9, 0x9fe4fc88), TOBN(0x09418e28, 0xcc97bbb5),
-+     TOBN(0xd8274fb4, 0xa12321ae), TOBN(0xb137007d, 0x5c87b64e),
-+     TOBN(0x80531fe1, 0xc63c4962), TOBN(0x50541e89, 0x981fdb25),
-+     TOBN(0xdc1291a1, 0xfd4c2b6b), TOBN(0xc0693a17, 0xa6df4fca),
-+     TOBN(0xb2c4604e, 0x0117f203), TOBN(0x245f1963, 0x0a99b8d0),
-+     TOBN(0xaedc20aa, 0xc6212c44), TOBN(0xb1ed4e56, 0x520f52a8),
-+     TOBN(0xfe48f575, 0xf8547be3), TOBN(0x0a7033cd, 0xa9e45f98),
-+     TOBN(0x4b45d3a9, 0x18c50100), TOBN(0xb2a6cd6a, 0xa61d41da),
-+     TOBN(0x60bbb4f5, 0x57933c6b), TOBN(0xa7538ebd, 0x2b0d7ffc),
-+     TOBN(0x9ea3ab8d, 0x8cd626b6), TOBN(0x8273a484, 0x3601625a),
-+     TOBN(0x88859845, 0x0168e508), TOBN(0x8cbc9bb2, 0x99a94abd),
-+     TOBN(0x713ac792, 0xfab0a671), TOBN(0xa3995b19, 0x6c9ebffc),
-+     TOBN(0xe711668e, 0x1239e152), TOBN(0x56892558, 0xbbb8dff4),
-+     TOBN(0x8bfc7dab, 0xdbf17963), TOBN(0x5b59fe5a, 0xb3de1253),
-+     TOBN(0x7e3320eb, 0x34a9f7ae), TOBN(0xe5e8cf72, 0xd751efe4),
-+     TOBN(0x7ea003bc, 0xd9be2f37), TOBN(0xc0f551a0, 0xb6c08ef7),
-+     TOBN(0x56606268, 0x038f6725), TOBN(0x1dd38e35, 0x6d92d3b6),
-+     TOBN(0x07dfce7c, 0xc3cbd686), TOBN(0x4e549e04, 0x651c5da8),
-+     TOBN(0x4058f93b, 0x08b19340), TOBN(0xc2fae6f4, 0xcac6d89d),
-+     TOBN(0x4bad8a8c, 0x8f159cc7), TOBN(0x0ddba4b3, 0xcb0b601c),
-+     TOBN(0xda4fc7b5, 0x1dd95f8c), TOBN(0x1d163cd7, 0xcea5c255),
-+     TOBN(0x30707d06, 0x274a8c4c), TOBN(0x79d9e008, 0x2802e9ce),
-+     TOBN(0x02a29ebf, 0xe6ddd505), TOBN(0x37064e74, 0xb50bed1a),
-+     TOBN(0x3f6bae65, 0xa7327d57), TOBN(0x3846f5f1, 0xf83920bc),
-+     TOBN(0x87c37491, 0x60df1b9b), TOBN(0x4cfb2895, 0x2d1da29f),
-+     TOBN(0x10a478ca, 0x4ed1743c), TOBN(0x390c6030, 0x3edd47c6),
-+     TOBN(0x8f3e5312, 0x8c0a78de), TOBN(0xccd02bda, 0x1e85df70),
-+     TOBN(0xd6c75c03, 0xa61b6582), TOBN(0x0762921c, 0xfc0eebd1),
-+     TOBN(0xd34d0823, 0xd85010c0), TOBN(0xd73aaacb, 0x0044cf1f),
-+     TOBN(0xfb4159bb, 0xa3b5e78a), TOBN(0x2287c7f7, 0xe5826f3f),
-+     TOBN(0x4aeaf742, 0x580b1a01), TOBN(0xf080415d, 0x60423b79),
-+     TOBN(0xe12622cd, 0xa7dea144), TOBN(0x49ea4996, 0x59d62472),
-+     TOBN(0xb42991ef, 0x571f3913), TOBN(0x0610f214, 0xf5b25a8a),
-+     TOBN(0x47adc585, 0x30b79e8f), TOBN(0xf90e3df6, 0x07a065a2),
-+     TOBN(0x5d0a5deb, 0x43e2e034), TOBN(0x53fb5a34, 0x444024aa),
-+     TOBN(0xa8628c68, 0x6b0c9f7f), TOBN(0x9c69c29c, 0xac563656),
-+     TOBN(0x5a231feb, 0xbace47b6), TOBN(0xbdce0289, 0x9ea5a2ec),
-+     TOBN(0x05da1fac, 0x9463853e), TOBN(0x96812c52, 0x509e78aa),
-+     TOBN(0xd3fb5771, 0x57151692), TOBN(0xeb2721f8, 0xd98e1c44),
-+     TOBN(0xc0506087, 0x32399be1), TOBN(0xda5a5511, 0xd979d8b8),
-+     TOBN(0x737ed55d, 0xc6f56780), TOBN(0xe20d3004, 0x0dc7a7f4),
-+     TOBN(0x02ce7301, 0xf5941a03), TOBN(0x91ef5215, 0xed30f83a),
-+     TOBN(0x28727fc1, 0x4092d85f), TOBN(0x72d223c6, 0x5c49e41a),
-+     TOBN(0xa7cf30a2, 0xba6a4d81), TOBN(0x7c086209, 0xb030d87d),
-+     TOBN(0x04844c7d, 0xfc588b09), TOBN(0x728cd499, 0x5874bbb0),
-+     TOBN(0xcc1281ee, 0xe84c0495), TOBN(0x0769b5ba, 0xec31958f),
-+     TOBN(0x665c228b, 0xf99c2471), TOBN(0xf2d8a11b, 0x191eb110),
-+     TOBN(0x4594f494, 0xd36d7024), TOBN(0x482ded8b, 0xcdcb25a1),
-+     TOBN(0xc958a9d8, 0xdadd4885), TOBN(0x7004477e, 0xf1d2b547),
-+     TOBN(0x0a45f6ef, 0x2a0af550), TOBN(0x4fc739d6, 0x2f8d6351),
-+     TOBN(0x75cdaf27, 0x786f08a9), TOBN(0x8700bb26, 0x42c2737f),
-+     TOBN(0x855a7141, 0x1c4e2670), TOBN(0x810188c1, 0x15076fef),
-+     TOBN(0xc251d0c9, 0xabcd3297), TOBN(0xae4c8967, 0xf48108eb),
-+     TOBN(0xbd146de7, 0x18ceed30), TOBN(0xf9d4f07a, 0xc986bced),
-+     TOBN(0x5ad98ed5, 0x83fa1e08), TOBN(0x7780d33e, 0xbeabd1fb),
-+     TOBN(0xe330513c, 0x903b1196), TOBN(0xba11de9e, 0xa47bc8c4),
-+     TOBN(0x684334da, 0x02c2d064), TOBN(0x7ecf360d, 0xa48de23b),
-+     TOBN(0x57a1b474, 0x0a9089d8), TOBN(0xf28fa439, 0xff36734c),
-+     TOBN(0xf2a482cb, 0xea4570b3), TOBN(0xee65d68b, 0xa5ebcee9),
-+     TOBN(0x988d0036, 0xb9694cd5), TOBN(0x53edd0e9, 0x37885d32),
-+     TOBN(0xe37e3307, 0xbeb9bc6d), TOBN(0xe9abb907, 0x9f5c6768),
-+     TOBN(0x4396ccd5, 0x51f2160f), TOBN(0x2500888c, 0x47336da6),
-+     TOBN(0x383f9ed9, 0x926fce43), TOBN(0x809dd1c7, 0x04da2930),
-+     TOBN(0x30f6f596, 0x8a4cb227), TOBN(0x0d700c7f, 0x73a56b38),
-+     TOBN(0x1825ea33, 0xab64a065), TOBN(0xaab9b735, 0x1338df80),
-+     TOBN(0x1516100d, 0x9b63f57f), TOBN(0x2574395a, 0x27a6a634),
-+     TOBN(0xb5560fb6, 0x700a1acd), TOBN(0xe823fd73, 0xfd999681),
-+     TOBN(0xda915d1f, 0x6cb4e1ba), TOBN(0x0d030118, 0x6ebe00a3),
-+     TOBN(0x744fb0c9, 0x89fca8cd), TOBN(0x970d01db, 0xf9da0e0b),
-+     TOBN(0x0ad8c564, 0x7931d76f), TOBN(0xb15737bf, 0xf659b96a),
-+     TOBN(0xdc9933e8, 0xa8b484e7), TOBN(0xb2fdbdf9, 0x7a26dec7),
-+     TOBN(0x2349e9a4, 0x9f1f0136), TOBN(0x7860368e, 0x70fddddb),
-+     TOBN(0xd93d2c1c, 0xf9ad3e18), TOBN(0x6d6c5f17, 0x689f4e79),
-+     TOBN(0x7a544d91, 0xb24ff1b6), TOBN(0x3e12a5eb, 0xfe16cd8c),
-+     TOBN(0x543574e9, 0xa56b872f), TOBN(0xa1ad550c, 0xfcf68ea2),
-+     TOBN(0x689e37d2, 0x3f560ef7), TOBN(0x8c54b9ca, 0xc9d47a8b),
-+     TOBN(0x46d40a4a, 0x088ac342), TOBN(0xec450c7c, 0x1576c6d0),
-+     TOBN(0xb589e31c, 0x1f9689e9), TOBN(0xdacf2602, 0xb8781718),
-+     TOBN(0xa89237c6, 0xc8cb6b42), TOBN(0x1326fc93, 0xb96ef381),
-+     TOBN(0x55d56c6d, 0xb5f07825), TOBN(0xacba2eea, 0x7449e22d),
-+     TOBN(0x74e0887a, 0x633c3000), TOBN(0xcb6cd172, 0xd7cbcf71),
-+     TOBN(0x309e81de, 0xc36cf1be), TOBN(0x07a18a6d, 0x60ae399b),
-+     TOBN(0xb36c2679, 0x9edce57e), TOBN(0x52b892f4, 0xdf001d41),
-+     TOBN(0xd884ae5d, 0x16a1f2c6), TOBN(0x9b329424, 0xefcc370a),
-+     TOBN(0x3120daf2, 0xbd2e21df), TOBN(0x55298d2d, 0x02470a99),
-+     TOBN(0x0b78af6c, 0xa05db32e), TOBN(0x5c76a331, 0x601f5636),
-+     TOBN(0xaae861ff, 0xf8a4f29c), TOBN(0x70dc9240, 0xd68f8d49),
-+     TOBN(0x960e649f, 0x81b1321c), TOBN(0x3d2c801b, 0x8792e4ce),
-+     TOBN(0xf479f772, 0x42521876), TOBN(0x0bed93bc, 0x416c79b1),
-+     TOBN(0xa67fbc05, 0x263e5bc9), TOBN(0x01e8e630, 0x521db049),
-+     TOBN(0x76f26738, 0xc6f3431e), TOBN(0xe609cb02, 0xe3267541),
-+     TOBN(0xb10cff2d, 0x818c877c), TOBN(0x1f0e75ce, 0x786a13cb),
-+     TOBN(0xf4fdca64, 0x1158544d), TOBN(0x5d777e89, 0x6cb71ed0),
-+     TOBN(0x3c233737, 0xa9aa4755), TOBN(0x7b453192, 0xe527ab40),
-+     TOBN(0xdb59f688, 0x39f05ffe), TOBN(0x8f4f4be0, 0x6d82574e),
-+     TOBN(0xcce3450c, 0xee292d1b), TOBN(0xaa448a12, 0x61ccd086),
-+     TOBN(0xabce91b3, 0xf7914967), TOBN(0x4537f09b, 0x1908a5ed),
-+     TOBN(0xa812421e, 0xf51042e7), TOBN(0xfaf5cebc, 0xec0b3a34),
-+     TOBN(0x730ffd87, 0x4ca6b39a), TOBN(0x70fb72ed, 0x02efd342),
-+     TOBN(0xeb4735f9, 0xd75c8edb), TOBN(0xc11f2157, 0xc278aa51),
-+     TOBN(0xc459f635, 0xbf3bfebf), TOBN(0x3a1ff0b4, 0x6bd9601f),
-+     TOBN(0xc9d12823, 0xc420cb73), TOBN(0x3e9af3e2, 0x3c2915a3),
-+     TOBN(0xe0c82c72, 0xb41c3440), TOBN(0x175239e5, 0xe3039a5f),
-+     TOBN(0xe1084b8a, 0x558795a3), TOBN(0x328d0a1d, 0xd01e5c60),
-+     TOBN(0x0a495f2e, 0xd3788a04), TOBN(0x25d8ff16, 0x66c11a9f),
-+     TOBN(0xf5155f05, 0x9ed692d6), TOBN(0x954fa107, 0x4f425fe4),
-+     TOBN(0xd16aabf2, 0xe98aaa99), TOBN(0x90cd8ba0, 0x96b0f88a),
-+     TOBN(0x957f4782, 0xc154026a), TOBN(0x54ee0734, 0x52af56d2),
-+     TOBN(0xbcf89e54, 0x45b4147a), TOBN(0x3d102f21, 0x9a52816c),
-+     TOBN(0x6808517e, 0x39b62e77), TOBN(0x92e25421, 0x69169ad8),
-+     TOBN(0xd721d871, 0xbb608558), TOBN(0x60e4ebae, 0xf6d4ff9b),
-+     TOBN(0x0ba10819, 0x41f2763e), TOBN(0xca2e45be, 0x51ee3247),
-+     TOBN(0x66d172ec, 0x2bfd7a5f), TOBN(0x528a8f2f, 0x74d0b12d),
-+     TOBN(0xe17f1e38, 0xdabe70dc), TOBN(0x1d5d7316, 0x9f93983c),
-+     TOBN(0x51b2184a, 0xdf423e31), TOBN(0xcb417291, 0xaedb1a10),
-+     TOBN(0x2054ca93, 0x625bcab9), TOBN(0x54396860, 0xa98998f0),
-+     TOBN(0x4e53f6c4, 0xa54ae57e), TOBN(0x0ffeb590, 0xee648e9d),
-+     TOBN(0xfbbdaadc, 0x6afaf6bc), TOBN(0xf88ae796, 0xaa3bfb8a),
-+     TOBN(0x209f1d44, 0xd2359ed9), TOBN(0xac68dd03, 0xf3544ce2),
-+     TOBN(0xf378da47, 0xfd51e569), TOBN(0xe1abd860, 0x2cc80097),
-+     TOBN(0x23ca18d9, 0x343b6e3a), TOBN(0x480797e8, 0xb40a1bae),
-+     TOBN(0xd1f0c717, 0x533f3e67), TOBN(0x44896970, 0x06e6cdfc),
-+     TOBN(0x8ca21055, 0x52a82e8d), TOBN(0xb2caf785, 0x78460cdc),
-+     TOBN(0x4c1b7b62, 0xe9037178), TOBN(0xefc09d2c, 0xdb514b58),
-+     TOBN(0x5f2df9ee, 0x9113be5c), TOBN(0x2fbda78f, 0xb3f9271c),
-+     TOBN(0xe09a81af, 0x8f83fc54), TOBN(0x06b13866, 0x8afb5141),
-+     TOBN(0x38f6480f, 0x43e3865d), TOBN(0x72dd77a8, 0x1ddf47d9),
-+     TOBN(0xf2a8e971, 0x4c205ff7), TOBN(0x46d449d8, 0x9d088ad8),
-+     TOBN(0x926619ea, 0x185d706f), TOBN(0xe47e02eb, 0xc7dd7f62),
-+     TOBN(0xe7f120a7, 0x8cbc2031), TOBN(0xc18bef00, 0x998d4ac9),
-+     TOBN(0x18f37a9c, 0x6bdf22da), TOBN(0xefbc432f, 0x90dc82df),
-+     TOBN(0xc52cef8e, 0x5d703651), TOBN(0x82887ba0, 0xd99881a5),
-+     TOBN(0x7cec9dda, 0xb920ec1d), TOBN(0xd0d7e8c3, 0xec3e8d3b),
-+     TOBN(0x445bc395, 0x4ca88747), TOBN(0xedeaa2e0, 0x9fd53535),
-+     TOBN(0x461b1d93, 0x6cc87475), TOBN(0xd92a52e2, 0x6d2383bd),
-+     TOBN(0xfabccb59, 0xd7903546), TOBN(0x6111a761, 0x3d14b112),
-+     TOBN(0x0ae584fe, 0xb3d5f612), TOBN(0x5ea69b8d, 0x60e828ec),
-+     TOBN(0x6c078985, 0x54087030), TOBN(0x649cab04, 0xac4821fe),
-+     TOBN(0x25ecedcf, 0x8bdce214), TOBN(0xb5622f72, 0x86af7361),
-+     TOBN(0x0e1227aa, 0x7038b9e2), TOBN(0xd0efb273, 0xac20fa77),
-+     TOBN(0x817ff88b, 0x79df975b), TOBN(0x856bf286, 0x1999503e),
-+     TOBN(0xb4d5351f, 0x5038ec46), TOBN(0x740a52c5, 0xfc42af6e),
-+     TOBN(0x2e38bb15, 0x2cbb1a3f), TOBN(0xc3eb99fe, 0x17a83429),
-+     TOBN(0xca4fcbf1, 0xdd66bb74), TOBN(0x880784d6, 0xcde5e8fc),
-+     TOBN(0xddc84c1c, 0xb4e7a0be), TOBN(0x8780510d, 0xbd15a72f),
-+     TOBN(0x44bcf1af, 0x81ec30e1), TOBN(0x141e50a8, 0x0a61073e),
-+     TOBN(0x0d955718, 0x47be87ae), TOBN(0x68a61417, 0xf76a4372),
-+     TOBN(0xf57e7e87, 0xc607c3d3), TOBN(0x043afaf8, 0x5252f332),
-+     TOBN(0xcc14e121, 0x1552a4d2), TOBN(0xb6dee692, 0xbb4d4ab4),
-+     TOBN(0xb6ab74c8, 0xa03816a4), TOBN(0x84001ae4, 0x6f394a29),
-+     TOBN(0x5bed8344, 0xd795fb45), TOBN(0x57326e7d, 0xb79f55a5),
-+     TOBN(0xc9533ce0, 0x4accdffc), TOBN(0x53473caf, 0x3993fa04),
-+     TOBN(0x7906eb93, 0xa13df4c8), TOBN(0xa73e51f6, 0x97cbe46f),
-+     TOBN(0xd1ab3ae1, 0x0ae4ccf8), TOBN(0x25614508, 0x8a5b3dbc),
-+     TOBN(0x61eff962, 0x11a71b27), TOBN(0xdf71412b, 0x6bb7fa39),
-+     TOBN(0xb31ba6b8, 0x2bd7f3ef), TOBN(0xb0b9c415, 0x69180d29),
-+     TOBN(0xeec14552, 0x014cdde5), TOBN(0x702c624b, 0x227b4bbb),
-+     TOBN(0x2b15e8c2, 0xd3e988f3), TOBN(0xee3bcc6d, 0xa4f7fd04),
-+     TOBN(0x9d00822a, 0x42ac6c85), TOBN(0x2db0cea6, 0x1df9f2b7),
-+     TOBN(0xd7cad2ab, 0x42de1e58), TOBN(0x346ed526, 0x2d6fbb61),
-+     TOBN(0xb3962995, 0x1a2faf09), TOBN(0x2fa8a580, 0x7c25612e),
-+     TOBN(0x30ae04da, 0x7cf56490), TOBN(0x75662908, 0x0eea3961),
-+     TOBN(0x3609f5c5, 0x3d080847), TOBN(0xcb081d39, 0x5241d4f6),
-+     TOBN(0xb4fb3810, 0x77961a63), TOBN(0xc20c5984, 0x2abb66fc),
-+     TOBN(0x3d40aa7c, 0xf902f245), TOBN(0x9cb12736, 0x4e536b1e),
-+     TOBN(0x5eda24da, 0x99b3134f), TOBN(0xafbd9c69, 0x5cd011af),
-+     TOBN(0x9a16e30a, 0xc7088c7d), TOBN(0x5ab65710, 0x3207389f),
-+     TOBN(0x1b09547f, 0xe7407a53), TOBN(0x2322f9d7, 0x4fdc6eab),
-+     TOBN(0xc0f2f22d, 0x7430de4d), TOBN(0x19382696, 0xe68ca9a9),
-+     TOBN(0x17f1eff1, 0x918e5868), TOBN(0xe3b5b635, 0x586f4204),
-+     TOBN(0x146ef980, 0x3fbc4341), TOBN(0x359f2c80, 0x5b5eed4e),
-+     TOBN(0x9f35744e, 0x7482e41d), TOBN(0x9a9ac3ec, 0xf3b224c2),
-+     TOBN(0x9161a6fe, 0x91fc50ae), TOBN(0x89ccc66b, 0xc613fa7c),
-+     TOBN(0x89268b14, 0xc732f15a), TOBN(0x7cd6f4e2, 0xb467ed03),
-+     TOBN(0xfbf79869, 0xce56b40e), TOBN(0xf93e094c, 0xc02dde98),
-+     TOBN(0xefe0c3a8, 0xedee2cd7), TOBN(0x90f3ffc0, 0xb268fd42),
-+     TOBN(0x81a7fd56, 0x08241aed), TOBN(0x95ab7ad8, 0x00b1afe8),
-+     TOBN(0x40127056, 0x3e310d52), TOBN(0xd3ffdeb1, 0x09d9fc43),
-+     TOBN(0xc8f85c91, 0xd11a8594), TOBN(0x2e74d258, 0x31cf6db8),
-+     TOBN(0x829c7ca3, 0x02b5dfd0), TOBN(0xe389cfbe, 0x69143c86),
-+     TOBN(0xd01b6405, 0x941768d8), TOBN(0x45103995, 0x03bf825d),
-+     TOBN(0xcc4ee166, 0x56cd17e2), TOBN(0xbea3c283, 0xba037e79),
-+     TOBN(0x4e1ac06e, 0xd9a47520), TOBN(0xfbfe18aa, 0xaf852404),
-+     TOBN(0x5615f8e2, 0x8087648a), TOBN(0x7301e47e, 0xb9d150d9),
-+     TOBN(0x79f9f9dd, 0xb299b977), TOBN(0x76697a7b, 0xa5b78314),
-+     TOBN(0x10d67468, 0x7d7c90e7), TOBN(0x7afffe03, 0x937210b5),
-+     TOBN(0x5aef3e4b, 0x28c22cee), TOBN(0xefb0ecd8, 0x09fd55ae),
-+     TOBN(0x4cea7132, 0x0d2a5d6a), TOBN(0x9cfb5fa1, 0x01db6357),
-+     TOBN(0x395e0b57, 0xf36e1ac5), TOBN(0x008fa9ad, 0x36cafb7d),
-+     TOBN(0x8f6cdf70, 0x5308c4db), TOBN(0x51527a37, 0x95ed2477),
-+     TOBN(0xba0dee30, 0x5bd21311), TOBN(0x6ed41b22, 0x909c90d7),
-+     TOBN(0xc5f6b758, 0x7c8696d3), TOBN(0x0db8eaa8, 0x3ce83a80),
-+     TOBN(0xd297fe37, 0xb24b4b6f), TOBN(0xfe58afe8, 0x522d1f0d),
-+     TOBN(0x97358736, 0x8c98dbd9), TOBN(0x6bc226ca, 0x9454a527),
-+     TOBN(0xa12b384e, 0xce53c2d0), TOBN(0x779d897d, 0x5e4606da),
-+     TOBN(0xa53e47b0, 0x73ec12b0), TOBN(0x462dbbba, 0x5756f1ad),
-+     TOBN(0x69fe09f2, 0xcafe37b6), TOBN(0x273d1ebf, 0xecce2e17),
-+     TOBN(0x8ac1d538, 0x3cf607fd), TOBN(0x8035f7ff, 0x12e10c25),}
-+    ,
-+    {TOBN(0x854d34c7, 0x7e6c5520), TOBN(0xc27df9ef, 0xdcb9ea58),
-+     TOBN(0x405f2369, 0xd686666d), TOBN(0x29d1febf, 0x0417aa85),
-+     TOBN(0x9846819e, 0x93470afe), TOBN(0x3e6a9669, 0xe2a27f9e),
-+     TOBN(0x24d008a2, 0xe31e6504), TOBN(0xdba7cecf, 0x9cb7680a),
-+     TOBN(0xecaff541, 0x338d6e43), TOBN(0x56f7dd73, 0x4541d5cc),
-+     TOBN(0xb5d426de, 0x96bc88ca), TOBN(0x48d94f6b, 0x9ed3a2c3),
-+     TOBN(0x6354a3bb, 0x2ef8279c), TOBN(0xd575465b, 0x0b1867f2),
-+     TOBN(0xef99b0ff, 0x95225151), TOBN(0xf3e19d88, 0xf94500d8),
-+     TOBN(0x92a83268, 0xe32dd620), TOBN(0x913ec99f, 0x627849a2),
-+     TOBN(0xedd8fdfa, 0x2c378882), TOBN(0xaf96f33e, 0xee6f8cfe),
-+     TOBN(0xc06737e5, 0xdc3fa8a5), TOBN(0x236bb531, 0xb0b03a1d),
-+     TOBN(0x33e59f29, 0x89f037b0), TOBN(0x13f9b5a7, 0xd9a12a53),
-+     TOBN(0x0d0df6ce, 0x51efb310), TOBN(0xcb5b2eb4, 0x958df5be),
-+     TOBN(0xd6459e29, 0x36158e59), TOBN(0x82aae2b9, 0x1466e336),
-+     TOBN(0xfb658a39, 0x411aa636), TOBN(0x7152ecc5, 0xd4c0a933),
-+     TOBN(0xf10c758a, 0x49f026b7), TOBN(0xf4837f97, 0xcb09311f),
-+     TOBN(0xddfb02c4, 0xc753c45f), TOBN(0x18ca81b6, 0xf9c840fe),
-+     TOBN(0x846fd09a, 0xb0f8a3e6), TOBN(0xb1162add, 0xe7733dbc),
-+     TOBN(0x7070ad20, 0x236e3ab6), TOBN(0xf88cdaf5, 0xb2a56326),
-+     TOBN(0x05fc8719, 0x997cbc7a), TOBN(0x442cd452, 0x4b665272),
-+     TOBN(0x7807f364, 0xb71698f5), TOBN(0x6ba418d2, 0x9f7b605e),
-+     TOBN(0xfd20b00f, 0xa03b2cbb), TOBN(0x883eca37, 0xda54386f),
-+     TOBN(0xff0be43f, 0xf3437f24), TOBN(0xe910b432, 0xa48bb33c),
-+     TOBN(0x4963a128, 0x329df765), TOBN(0xac1dd556, 0xbe2fe6f7),
-+     TOBN(0x557610f9, 0x24a0a3fc), TOBN(0x38e17bf4, 0xe881c3f9),
-+     TOBN(0x6ba84faf, 0xed0dac99), TOBN(0xd4a222c3, 0x59eeb918),
-+     TOBN(0xc79c1dbe, 0x13f542b6), TOBN(0x1fc65e0d, 0xe425d457),
-+     TOBN(0xeffb754f, 0x1debb779), TOBN(0x638d8fd0, 0x9e08af60),
-+     TOBN(0x994f523a, 0x626332d5), TOBN(0x7bc38833, 0x5561bb44),
-+     TOBN(0x005ed4b0, 0x3d845ea2), TOBN(0xd39d3ee1, 0xc2a1f08a),
-+     TOBN(0x6561fdd3, 0xe7676b0d), TOBN(0x620e35ff, 0xfb706017),
-+     TOBN(0x36ce424f, 0xf264f9a8), TOBN(0xc4c3419f, 0xda2681f7),
-+     TOBN(0xfb6afd2f, 0x69beb6e8), TOBN(0x3a50b993, 0x6d700d03),
-+     TOBN(0xc840b2ad, 0x0c83a14f), TOBN(0x573207be, 0x54085bef),
-+     TOBN(0x5af882e3, 0x09fe7e5b), TOBN(0x957678a4, 0x3b40a7e1),
-+     TOBN(0x172d4bdd, 0x543056e2), TOBN(0x9c1b26b4, 0x0df13c0a),
-+     TOBN(0x1c30861c, 0xf405ff06), TOBN(0xebac86bd, 0x486e828b),
-+     TOBN(0xe791a971, 0x636933fc), TOBN(0x50e7c2be, 0x7aeee947),
-+     TOBN(0xc3d4a095, 0xfa90d767), TOBN(0xae60eb7b, 0xe670ab7b),
-+     TOBN(0x17633a64, 0x397b056d), TOBN(0x93a21f33, 0x105012aa),
-+     TOBN(0x663c370b, 0xabb88643), TOBN(0x91df36d7, 0x22e21599),
-+     TOBN(0x183ba835, 0x8b761671), TOBN(0x381eea1d, 0x728f3bf1),
-+     TOBN(0xb9b2f1ba, 0x39966e6c), TOBN(0x7c464a28, 0xe7295492),
-+     TOBN(0x0fd5f70a, 0x09b26b7f), TOBN(0xa9aba1f9, 0xfbe009df),
-+     TOBN(0x857c1f22, 0x369b87ad), TOBN(0x3c00e5d9, 0x32fca556),
-+     TOBN(0x1ad74cab, 0x90b06466), TOBN(0xa7112386, 0x550faaf2),
-+     TOBN(0x7435e198, 0x6d9bd5f5), TOBN(0x2dcc7e38, 0x59c3463f),
-+     TOBN(0xdc7df748, 0xca7bd4b2), TOBN(0x13cd4c08, 0x9dec2f31),
-+     TOBN(0x0d3b5df8, 0xe3237710), TOBN(0x0dadb26e, 0xcbd2f7b0),
-+     TOBN(0x9f5966ab, 0xe4aa082b), TOBN(0x666ec8de, 0x350e966e),
-+     TOBN(0x1bfd1ed5, 0xee524216), TOBN(0xcd93c59b, 0x41dab0b6),
-+     TOBN(0x658a8435, 0xd186d6ba), TOBN(0x1b7d34d2, 0x159d1195),
-+     TOBN(0x5936e460, 0x22caf46b), TOBN(0x6a45dd8f, 0x9a96fe4f),
-+     TOBN(0xf7925434, 0xb98f474e), TOBN(0x41410412, 0x0053ef15),
-+     TOBN(0x71cf8d12, 0x41de97bf), TOBN(0xb8547b61, 0xbd80bef4),
-+     TOBN(0xb47d3970, 0xc4db0037), TOBN(0xf1bcd328, 0xfef20dff),
-+     TOBN(0x31a92e09, 0x10caad67), TOBN(0x1f591960, 0x5531a1e1),
-+     TOBN(0x3bb852e0, 0x5f4fc840), TOBN(0x63e297ca, 0x93a72c6c),
-+     TOBN(0x3c2b0b2e, 0x49abad67), TOBN(0x6ec405fc, 0xed3db0d9),
-+     TOBN(0xdc14a530, 0x7fef1d40), TOBN(0xccd19846, 0x280896fc),
-+     TOBN(0x00f83176, 0x9bb81648), TOBN(0xd69eb485, 0x653120d0),
-+     TOBN(0xd17d75f4, 0x4ccabc62), TOBN(0x34a07f82, 0xb749fcb1),
-+     TOBN(0x2c3af787, 0xbbfb5554), TOBN(0xb06ed4d0, 0x62e283f8),
-+     TOBN(0x5722889f, 0xa19213a0), TOBN(0x162b085e, 0xdcf3c7b4),
-+     TOBN(0xbcaecb31, 0xe0dd3eca), TOBN(0xc6237fbc, 0xe52f13a5),
-+     TOBN(0xcc2b6b03, 0x27bac297), TOBN(0x2ae1cac5, 0xb917f54a),
-+     TOBN(0x474807d4, 0x7845ae4f), TOBN(0xfec7dd92, 0xce5972e0),
-+     TOBN(0xc3bd2541, 0x1d7915bb), TOBN(0x66f85dc4, 0xd94907ca),
-+     TOBN(0xd981b888, 0xbdbcf0ca), TOBN(0xd75f5da6, 0xdf279e9f),
-+     TOBN(0x128bbf24, 0x7054e934), TOBN(0x3c6ff6e5, 0x81db134b),
-+     TOBN(0x795b7cf4, 0x047d26e4), TOBN(0xf370f7b8, 0x5049ec37),
-+     TOBN(0xc6712d4d, 0xced945af), TOBN(0xdf30b5ec, 0x095642bc),
-+     TOBN(0x9b034c62, 0x4896246e), TOBN(0x5652c016, 0xee90bbd1),
-+     TOBN(0xeb38636f, 0x87fedb73), TOBN(0x5e32f847, 0x0135a613),
-+     TOBN(0x0703b312, 0xcf933c83), TOBN(0xd05bb76e, 0x1a7f47e6),
-+     TOBN(0x825e4f0c, 0x949c2415), TOBN(0x569e5622, 0x7250d6f8),
-+     TOBN(0xbbe9eb3a, 0x6568013e), TOBN(0x8dbd203f, 0x22f243fc),
-+     TOBN(0x9dbd7694, 0xb342734a), TOBN(0x8f6d12f8, 0x46afa984),
-+     TOBN(0xb98610a2, 0xc9eade29), TOBN(0xbab4f323, 0x47dd0f18),
-+     TOBN(0x5779737b, 0x671c0d46), TOBN(0x10b6a7c6, 0xd3e0a42a),
-+     TOBN(0xfb19ddf3, 0x3035b41c), TOBN(0xd336343f, 0x99c45895),
-+     TOBN(0x61fe4938, 0x54c857e5), TOBN(0xc4d506be, 0xae4e57d5),
-+     TOBN(0x3cd8c8cb, 0xbbc33f75), TOBN(0x7281f08a, 0x9262c77d),
-+     TOBN(0x083f4ea6, 0xf11a2823), TOBN(0x8895041e, 0x9fba2e33),
-+     TOBN(0xfcdfea49, 0x9c438edf), TOBN(0x7678dcc3, 0x91edba44),
-+     TOBN(0xf07b3b87, 0xe2ba50f0), TOBN(0xc13888ef, 0x43948c1b),
-+     TOBN(0xc2135ad4, 0x1140af42), TOBN(0x8e5104f3, 0x926ed1a7),
-+     TOBN(0xf24430cb, 0x88f6695f), TOBN(0x0ce0637b, 0x6d73c120),
-+     TOBN(0xb2db01e6, 0xfe631e8f), TOBN(0x1c5563d7, 0xd7bdd24b),
-+     TOBN(0x8daea3ba, 0x369ad44f), TOBN(0x000c81b6, 0x8187a9f9),
-+     TOBN(0x5f48a951, 0xaae1fd9a), TOBN(0xe35626c7, 0x8d5aed8a),
-+     TOBN(0x20952763, 0x0498c622), TOBN(0x76d17634, 0x773aa504),
-+     TOBN(0x36d90dda, 0xeb300f7a), TOBN(0x9dcf7dfc, 0xedb5e801),
-+     TOBN(0x645cb268, 0x74d5244c), TOBN(0xa127ee79, 0x348e3aa2),
-+     TOBN(0x488acc53, 0x575f1dbb), TOBN(0x95037e85, 0x80e6161e),
-+     TOBN(0x57e59283, 0x292650d0), TOBN(0xabe67d99, 0x14938216),
-+     TOBN(0x3c7f944b, 0x3f8e1065), TOBN(0xed908cb6, 0x330e8924),
-+     TOBN(0x08ee8fd5, 0x6f530136), TOBN(0x2227b7d5, 0xd7ffc169),
-+     TOBN(0x4f55c893, 0xb5cd6dd5), TOBN(0x82225e11, 0xa62796e8),
-+     TOBN(0x5c6cead1, 0xcb18e12c), TOBN(0x4381ae0c, 0x84f5a51a),
-+     TOBN(0x345913d3, 0x7fafa4c8), TOBN(0x3d918082, 0x0491aac0),
-+     TOBN(0x9347871f, 0x3e69264c), TOBN(0xbea9dd3c, 0xb4f4f0cd),
-+     TOBN(0xbda5d067, 0x3eadd3e7), TOBN(0x0033c1b8, 0x0573bcd8),
-+     TOBN(0x25589379, 0x5da2486c), TOBN(0xcb89ee5b, 0x86abbee7),
-+     TOBN(0x8fe0a8f3, 0x22532e5d), TOBN(0xb6410ff0, 0x727dfc4c),
-+     TOBN(0x619b9d58, 0x226726db), TOBN(0x5ec25669, 0x7a2b2dc7),
-+     TOBN(0xaf4d2e06, 0x4c3beb01), TOBN(0x852123d0, 0x7acea556),
-+     TOBN(0x0e9470fa, 0xf783487a), TOBN(0x75a7ea04, 0x5664b3eb),
-+     TOBN(0x4ad78f35, 0x6798e4ba), TOBN(0x9214e6e5, 0xc7d0e091),
-+     TOBN(0xc420b488, 0xb1290403), TOBN(0x64049e0a, 0xfc295749),
-+     TOBN(0x03ef5af1, 0x3ae9841f), TOBN(0xdbe4ca19, 0xb0b662a6),
-+     TOBN(0x46845c5f, 0xfa453458), TOBN(0xf8dabf19, 0x10b66722),
-+     TOBN(0xb650f0aa, 0xcce2793b), TOBN(0x71db851e, 0xc5ec47c1),
-+     TOBN(0x3eb78f3e, 0x3b234fa9), TOBN(0xb0c60f35, 0xfc0106ce),
-+     TOBN(0x05427121, 0x774eadbd), TOBN(0x25367faf, 0xce323863),
-+     TOBN(0x7541b5c9, 0xcd086976), TOBN(0x4ff069e2, 0xdc507ad1),
-+     TOBN(0x74145256, 0x8776e667), TOBN(0x6e76142c, 0xb23c6bb5),
-+     TOBN(0xdbf30712, 0x1b3a8a87), TOBN(0x60e7363e, 0x98450836),
-+     TOBN(0x5741450e, 0xb7366d80), TOBN(0xe4ee14ca, 0x4837dbdf),
-+     TOBN(0xa765eb9b, 0x69d4316f), TOBN(0x04548dca, 0x8ef43825),
-+     TOBN(0x9c9f4e4c, 0x5ae888eb), TOBN(0x733abb51, 0x56e9ac99),
-+     TOBN(0xdaad3c20, 0xba6ac029), TOBN(0x9b8dd3d3, 0x2ba3e38e),
-+     TOBN(0xa9bb4c92, 0x0bc5d11a), TOBN(0xf20127a7, 0x9c5f88a3),
-+     TOBN(0x4f52b06e, 0x161d3cb8), TOBN(0x26c1ff09, 0x6afaf0a6),
-+     TOBN(0x32670d2f, 0x7189e71f), TOBN(0xc6438748, 0x5ecf91e7),
-+     TOBN(0x15758e57, 0xdb757a21), TOBN(0x427d09f8, 0x290a9ce5),
-+     TOBN(0x846a308f, 0x38384a7a), TOBN(0xaac3acb4, 0xb0732b99),
-+     TOBN(0x9e941009, 0x17845819), TOBN(0x95cba111, 0xa7ce5e03),
-+     TOBN(0x6f3d4f7f, 0xb00009c4), TOBN(0xb8396c27, 0x8ff28b5f),
-+     TOBN(0xb1a9ae43, 0x1c97975d), TOBN(0x9d7ba8af, 0xe5d9fed5),
-+     TOBN(0x338cf09f, 0x34f485b6), TOBN(0xbc0ddacc, 0x64122516),
-+     TOBN(0xa450da12, 0x05d471fe), TOBN(0x4c3a6250, 0x628dd8c9),
-+     TOBN(0x69c7d103, 0xd1295837), TOBN(0xa2893e50, 0x3807eb2f),
-+     TOBN(0xd6e1e1de, 0xbdb41491), TOBN(0xc630745b, 0x5e138235),
-+     TOBN(0xc892109e, 0x48661ae1), TOBN(0x8d17e7eb, 0xea2b2674),
-+     TOBN(0x00ec0f87, 0xc328d6b5), TOBN(0x6d858645, 0xf079ff9e),
-+     TOBN(0x6cdf243e, 0x19115ead), TOBN(0x1ce1393e, 0x4bac4fcf),
-+     TOBN(0x2c960ed0, 0x9c29f25b), TOBN(0x59be4d8e, 0x9d388a05),
-+     TOBN(0x0d46e06c, 0xd0def72b), TOBN(0xb923db5d, 0xe0342748),
-+     TOBN(0xf7d3aacd, 0x936d4a3d), TOBN(0x558519cc, 0x0b0b099e),
-+     TOBN(0x3ea8ebf8, 0x827097ef), TOBN(0x259353db, 0xd054f55d),
-+     TOBN(0x84c89abc, 0x6d2ed089), TOBN(0x5c548b69, 0x8e096a7c),
-+     TOBN(0xd587f616, 0x994b995d), TOBN(0x4d1531f6, 0xa5845601),
-+     TOBN(0x792ab31e, 0x451fd9f0), TOBN(0xc8b57bb2, 0x65adf6ca),
-+     TOBN(0x68440fcb, 0x1cd5ad73), TOBN(0xb9c860e6, 0x6144da4f),
-+     TOBN(0x2ab286aa, 0x8462beb8), TOBN(0xcc6b8fff, 0xef46797f),
-+     TOBN(0xac820da4, 0x20c8a471), TOBN(0x69ae05a1, 0x77ff7faf),
-+     TOBN(0xb9163f39, 0xbfb5da77), TOBN(0xbd03e590, 0x2c73ab7a),
-+     TOBN(0x7e862b5e, 0xb2940d9e), TOBN(0x3c663d86, 0x4b9af564),
-+     TOBN(0xd8309031, 0xbde3033d), TOBN(0x298231b2, 0xd42c5bc6),
-+     TOBN(0x42090d2c, 0x552ad093), TOBN(0xa4799d1c, 0xff854695),
-+     TOBN(0x0a88b5d6, 0xd31f0d00), TOBN(0xf8b40825, 0xa2f26b46),
-+     TOBN(0xec29b1ed, 0xf1bd7218), TOBN(0xd491c53b, 0x4b24c86e),
-+     TOBN(0xd2fe588f, 0x3395ea65), TOBN(0x6f3764f7, 0x4456ef15),
-+     TOBN(0xdb43116d, 0xcdc34800), TOBN(0xcdbcd456, 0xc1e33955),
-+     TOBN(0xefdb5540, 0x74ab286b), TOBN(0x948c7a51, 0xd18c5d7c),
-+     TOBN(0xeb81aa37, 0x7378058e), TOBN(0x41c746a1, 0x04411154),
-+     TOBN(0xa10c73bc, 0xfb828ac7), TOBN(0x6439be91, 0x9d972b29),
-+     TOBN(0x4bf3b4b0, 0x43a2fbad), TOBN(0x39e6dadf, 0x82b5e840),
-+     TOBN(0x4f716408, 0x6397bd4c), TOBN(0x0f7de568, 0x7f1eeccb),
-+     TOBN(0x5865c5a1, 0xd2ffbfc1), TOBN(0xf74211fa, 0x4ccb6451),
-+     TOBN(0x66368a88, 0xc0b32558), TOBN(0x5b539dc2, 0x9ad7812e),
-+     TOBN(0x579483d0, 0x2f3af6f6), TOBN(0x52132078, 0x99934ece),
-+     TOBN(0x50b9650f, 0xdcc9e983), TOBN(0xca989ec9, 0xaee42b8a),
-+     TOBN(0x6a44c829, 0xd6f62f99), TOBN(0x8f06a309, 0x4c2a7c0c),
-+     TOBN(0x4ea2b3a0, 0x98a0cb0a), TOBN(0x5c547b70, 0xbeee8364),
-+     TOBN(0x461d40e1, 0x682afe11), TOBN(0x9e0fc77a, 0x7b41c0a8),
-+     TOBN(0x79e4aefd, 0xe20d5d36), TOBN(0x2916e520, 0x32dd9f63),
-+     TOBN(0xf59e52e8, 0x3f883faf), TOBN(0x396f9639, 0x2b868d35),
-+     TOBN(0xc902a9df, 0x4ca19881), TOBN(0x0fc96822, 0xdb2401a6),
-+     TOBN(0x41237587, 0x66f1c68d), TOBN(0x10fc6de3, 0xfb476c0d),
-+     TOBN(0xf8b6b579, 0x841f5d90), TOBN(0x2ba8446c, 0xfa24f44a),
-+     TOBN(0xa237b920, 0xef4a9975), TOBN(0x60bb6004, 0x2330435f),
-+     TOBN(0xd6f4ab5a, 0xcfb7e7b5), TOBN(0xb2ac5097, 0x83435391),
-+     TOBN(0xf036ee2f, 0xb0d1ea67), TOBN(0xae779a6a, 0x74c56230),
-+     TOBN(0x59bff8c8, 0xab838ae6), TOBN(0xcd83ca99, 0x9b38e6f0),
-+     TOBN(0xbb27bef5, 0xe33deed3), TOBN(0xe6356f6f, 0x001892a8),
-+     TOBN(0xbf3be6cc, 0x7adfbd3e), TOBN(0xaecbc81c, 0x33d1ac9d),
-+     TOBN(0xe4feb909, 0xe6e861dc), TOBN(0x90a247a4, 0x53f5f801),
-+     TOBN(0x01c50acb, 0x27346e57), TOBN(0xce29242e, 0x461acc1b),
-+     TOBN(0x04dd214a, 0x2f998a91), TOBN(0x271ee9b1, 0xd4baf27b),
-+     TOBN(0x7e3027d1, 0xe8c26722), TOBN(0x21d1645c, 0x1820dce5),
-+     TOBN(0x086f242c, 0x7501779c), TOBN(0xf0061407, 0xfa0e8009),
-+     TOBN(0xf23ce477, 0x60187129), TOBN(0x05bbdedb, 0x0fde9bd0),
-+     TOBN(0x682f4832, 0x25d98473), TOBN(0xf207fe85, 0x5c658427),
-+     TOBN(0xb6fdd7ba, 0x4166ffa1), TOBN(0x0c314056, 0x9eed799d),
-+     TOBN(0x0db8048f, 0x4107e28f), TOBN(0x74ed3871, 0x41216840),
-+     TOBN(0x74489f8f, 0x56a3c06e), TOBN(0x1e1c005b, 0x12777134),
-+     TOBN(0xdb332a73, 0xf37ec3c3), TOBN(0xc65259bd, 0xdd59eba0),
-+     TOBN(0x2291709c, 0xdb4d3257), TOBN(0x9a793b25, 0xbd389390),
-+     TOBN(0xf39fe34b, 0xe43756f0), TOBN(0x2f76bdce, 0x9afb56c9),
-+     TOBN(0x9f37867a, 0x61208b27), TOBN(0xea1d4307, 0x089972c3),
-+     TOBN(0x8c595330, 0x8bdf623a), TOBN(0x5f5accda, 0x8441fb7d),
-+     TOBN(0xfafa9418, 0x32ddfd95), TOBN(0x6ad40c5a, 0x0fde9be7),
-+     TOBN(0x43faba89, 0xaeca8709), TOBN(0xc64a7cf1, 0x2c248a9d),
-+     TOBN(0x16620252, 0x72637a76), TOBN(0xaee1c791, 0x22b8d1bb),
-+     TOBN(0xf0f798fd, 0x21a843b2), TOBN(0x56e4ed4d, 0x8d005cb1),
-+     TOBN(0x355f7780, 0x1f0d8abe), TOBN(0x197b04cf, 0x34522326),
-+     TOBN(0x41f9b31f, 0xfd42c13f), TOBN(0x5ef7feb2, 0xb40f933d),
-+     TOBN(0x27326f42, 0x5d60bad4), TOBN(0x027ecdb2, 0x8c92cf89),
-+     TOBN(0x04aae4d1, 0x4e3352fe), TOBN(0x08414d2f, 0x73591b90),
-+     TOBN(0x5ed6124e, 0xb7da7d60), TOBN(0xb985b931, 0x4d13d4ec),
-+     TOBN(0xa592d3ab, 0x96bf36f9), TOBN(0x012dbed5, 0xbbdf51df),
-+     TOBN(0xa57963c0, 0xdf6c177d), TOBN(0x010ec869, 0x87ca29cf),
-+     TOBN(0xba1700f6, 0xbf926dff), TOBN(0x7c9fdbd1, 0xf4bf6bc2),
-+     TOBN(0xdc18dc8f, 0x64da11f5), TOBN(0xa6074b7a, 0xd938ae75),
-+     TOBN(0x14270066, 0xe84f44a4), TOBN(0x99998d38, 0xd27b954e),
-+     TOBN(0xc1be8ab2, 0xb4f38e9a), TOBN(0x8bb55bbf, 0x15c01016),
-+     TOBN(0xf73472b4, 0x0ea2ab30), TOBN(0xd365a340, 0xf73d68dd),
-+     TOBN(0xc01a7168, 0x19c2e1eb), TOBN(0x32f49e37, 0x34061719),
-+     TOBN(0xb73c57f1, 0x01d8b4d6), TOBN(0x03c8423c, 0x26b47700),
-+     TOBN(0x321d0bc8, 0xa4d8826a), TOBN(0x6004213c, 0x4bc0e638),
-+     TOBN(0xf78c64a1, 0xc1c06681), TOBN(0x16e0a16f, 0xef018e50),
-+     TOBN(0x31cbdf91, 0xdb42b2b3), TOBN(0xf8f4ffce, 0xe0d36f58),
-+     TOBN(0xcdcc71cd, 0x4cc5e3e0), TOBN(0xd55c7cfa, 0xa129e3e0),
-+     TOBN(0xccdb6ba0, 0x0fb2cbf1), TOBN(0x6aba0005, 0xc4bce3cb),
-+     TOBN(0x501cdb30, 0xd232cfc4), TOBN(0x9ddcf12e, 0xd58a3cef),
-+     TOBN(0x02d2cf9c, 0x87e09149), TOBN(0xdc5d7ec7, 0x2c976257),
-+     TOBN(0x6447986e, 0x0b50d7dd), TOBN(0x88fdbaf7, 0x807f112a),
-+     TOBN(0x58c9822a, 0xb00ae9f6), TOBN(0x6abfb950, 0x6d3d27e0),
-+     TOBN(0xd0a74487, 0x8a429f4f), TOBN(0x0649712b, 0xdb516609),
-+     TOBN(0xb826ba57, 0xe769b5df), TOBN(0x82335df2, 0x1fc7aaf2),
-+     TOBN(0x2389f067, 0x5c93d995), TOBN(0x59ac367a, 0x68677be6),
-+     TOBN(0xa77985ff, 0x21d9951b), TOBN(0x038956fb, 0x85011cce),
-+     TOBN(0x608e48cb, 0xbb734e37), TOBN(0xc08c0bf2, 0x2be5b26f),
-+     TOBN(0x17bbdd3b, 0xf9b1a0d9), TOBN(0xeac7d898, 0x10483319),
-+     TOBN(0xc95c4baf, 0xbc1a6dea), TOBN(0xfdd0e2bf, 0x172aafdb),
-+     TOBN(0x40373cbc, 0x8235c41a), TOBN(0x14303f21, 0xfb6f41d5),
-+     TOBN(0xba063621, 0x0408f237), TOBN(0xcad3b09a, 0xecd2d1ed),
-+     TOBN(0x4667855a, 0x52abb6a2), TOBN(0xba9157dc, 0xaa8b417b),
-+     TOBN(0xfe7f3507, 0x4f013efb), TOBN(0x1b112c4b, 0xaa38c4a2),
-+     TOBN(0xa1406a60, 0x9ba64345), TOBN(0xe53cba33, 0x6993c80b),
-+     TOBN(0x45466063, 0xded40d23), TOBN(0x3d5f1f4d, 0x54908e25),
-+     TOBN(0x9ebefe62, 0x403c3c31), TOBN(0x274ea0b5, 0x0672a624),
-+     TOBN(0xff818d99, 0x451d1b71), TOBN(0x80e82643, 0x8f79cf79),
-+     TOBN(0xa165df13, 0x73ce37f5), TOBN(0xa744ef4f, 0xfe3a21fd),
-+     TOBN(0x73f1e7f5, 0xcf551396), TOBN(0xc616898e, 0x868c676b),
-+     TOBN(0x671c28c7, 0x8c442c36), TOBN(0xcfe5e558, 0x5e0a317d),
-+     TOBN(0x1242d818, 0x7051f476), TOBN(0x56fad2a6, 0x14f03442),
-+     TOBN(0x262068bc, 0x0a44d0f6), TOBN(0xdfa2cd6e, 0xce6edf4e),
-+     TOBN(0x0f43813a, 0xd15d1517), TOBN(0x61214cb2, 0x377d44f5),
-+     TOBN(0xd399aa29, 0xc639b35f), TOBN(0x42136d71, 0x54c51c19),
-+     TOBN(0x9774711b, 0x08417221), TOBN(0x0a5546b3, 0x52545a57),
-+     TOBN(0x80624c41, 0x1150582d), TOBN(0x9ec5c418, 0xfbc555bc),
-+     TOBN(0x2c87dcad, 0x771849f1), TOBN(0xb0c932c5, 0x01d7bf6f),
-+     TOBN(0x6aa5cd3e, 0x89116eb2), TOBN(0xd378c25a, 0x51ca7bd3),
-+     TOBN(0xc612a0da, 0x9e6e3e31), TOBN(0x0417a54d, 0xb68ad5d0),
-+     TOBN(0x00451e4a, 0x22c6edb8), TOBN(0x9fbfe019, 0xb42827ce),
-+     TOBN(0x2fa92505, 0xba9384a2), TOBN(0x21b8596e, 0x64ad69c1),
-+     TOBN(0x8f4fcc49, 0x983b35a6), TOBN(0xde093760, 0x72754672),
-+     TOBN(0x2f14ccc8, 0xf7bffe6d), TOBN(0x27566bff, 0x5d94263d),
-+     TOBN(0xb5b4e9c6, 0x2df3ec30), TOBN(0x94f1d7d5, 0x3e6ea6ba),
-+     TOBN(0x97b7851a, 0xaaca5e9b), TOBN(0x518aa521, 0x56713b97),
-+     TOBN(0x3357e8c7, 0x150a61f6), TOBN(0x7842e7e2, 0xec2c2b69),
-+     TOBN(0x8dffaf65, 0x6868a548), TOBN(0xd963bd82, 0xe068fc81),
-+     TOBN(0x64da5c8b, 0x65917733), TOBN(0x927090ff, 0x7b247328),}
-+    ,
-+    {TOBN(0x214bc9a7, 0xd298c241), TOBN(0xe3b697ba, 0x56807cfd),
-+     TOBN(0xef1c7802, 0x4564eadb), TOBN(0xdde8cdcf, 0xb48149c5),
-+     TOBN(0x946bf0a7, 0x5a4d2604), TOBN(0x27154d7f, 0x6c1538af),
-+     TOBN(0x95cc9230, 0xde5b1fcc), TOBN(0xd88519e9, 0x66864f82),
-+     TOBN(0xb828dd1a, 0x7cb1282c), TOBN(0xa08d7626, 0xbe46973a),
-+     TOBN(0x6baf8d40, 0xe708d6b2), TOBN(0x72571fa1, 0x4daeb3f3),
-+     TOBN(0x85b1732f, 0xf22dfd98), TOBN(0x87ab01a7, 0x0087108d),
-+     TOBN(0xaaaafea8, 0x5988207a), TOBN(0xccc832f8, 0x69f00755),
-+     TOBN(0x964d950e, 0x36ff3bf0), TOBN(0x8ad20f6f, 0xf0b34638),
-+     TOBN(0x4d9177b3, 0xb5d7585f), TOBN(0xcf839760, 0xef3f019f),
-+     TOBN(0x582fc5b3, 0x8288c545), TOBN(0x2f8e4e9b, 0x13116bd1),
-+     TOBN(0xf91e1b2f, 0x332120ef), TOBN(0xcf568724, 0x2a17dd23),
-+     TOBN(0x488f1185, 0xca8d9d1a), TOBN(0xadf2c77d, 0xd987ded2),
-+     TOBN(0x5f3039f0, 0x60c46124), TOBN(0xe5d70b75, 0x71e095f4),
-+     TOBN(0x82d58650, 0x6260e70f), TOBN(0x39d75ea7, 0xf750d105),
-+     TOBN(0x8cf3d0b1, 0x75bac364), TOBN(0xf3a7564d, 0x21d01329),
-+     TOBN(0x182f04cd, 0x2f52d2a7), TOBN(0x4fde149a, 0xe2df565a),
-+     TOBN(0xb80c5eec, 0xa79fb2f7), TOBN(0xab491d7b, 0x22ddc897),
-+     TOBN(0x99d76c18, 0xc6312c7f), TOBN(0xca0d5f3d, 0x6aa41a57),
-+     TOBN(0x71207325, 0xd15363a0), TOBN(0xe82aa265, 0xbeb252c2),
-+     TOBN(0x94ab4700, 0xec3128c2), TOBN(0x6c76d862, 0x8e383f49),
-+     TOBN(0xdc36b150, 0xc03024eb), TOBN(0xfb439477, 0x53daac69),
-+     TOBN(0xfc68764a, 0x8dc79623), TOBN(0x5b86995d, 0xb440fbb2),
-+     TOBN(0xd66879bf, 0xccc5ee0d), TOBN(0x05228942, 0x95aa8bd3),
-+     TOBN(0xb51a40a5, 0x1e6a75c1), TOBN(0x24327c76, 0x0ea7d817),
-+     TOBN(0x06630182, 0x07774597), TOBN(0xd6fdbec3, 0x97fa7164),
-+     TOBN(0x20c99dfb, 0x13c90f48), TOBN(0xd6ac5273, 0x686ef263),
-+     TOBN(0xc6a50bdc, 0xfef64eeb), TOBN(0xcd87b281, 0x86fdfc32),
-+     TOBN(0xb24aa43e, 0x3fcd3efc), TOBN(0xdd26c034, 0xb8088e9a),
-+     TOBN(0xa5ef4dc9, 0xbd3d46ea), TOBN(0xa2f99d58, 0x8a4c6a6f),
-+     TOBN(0xddabd355, 0x2f1da46c), TOBN(0x72c3f8ce, 0x1afacdd1),
-+     TOBN(0xd90c4eee, 0x92d40578), TOBN(0xd28bb41f, 0xca623b94),
-+     TOBN(0x50fc0711, 0x745edc11), TOBN(0x9dd9ad7d, 0x3dc87558),
-+     TOBN(0xce6931fb, 0xb49d1e64), TOBN(0x6c77a0a2, 0xc98bd0f9),
-+     TOBN(0x62b9a629, 0x6baf7cb1), TOBN(0xcf065f91, 0xccf72d22),
-+     TOBN(0x7203cce9, 0x79639071), TOBN(0x09ae4885, 0xf9cb732f),
-+     TOBN(0x5e7c3bec, 0xee8314f3), TOBN(0x1c068aed, 0xdbea298f),
-+     TOBN(0x08d381f1, 0x7c80acec), TOBN(0x03b56be8, 0xe330495b),
-+     TOBN(0xaeffb8f2, 0x9222882d), TOBN(0x95ff38f6, 0xc4af8bf7),
-+     TOBN(0x50e32d35, 0x1fc57d8c), TOBN(0x6635be52, 0x17b444f0),
-+     TOBN(0x04d15276, 0xa5177900), TOBN(0x4e1dbb47, 0xf6858752),
-+     TOBN(0x5b475622, 0xc615796c), TOBN(0xa6fa0387, 0x691867bf),
-+     TOBN(0xed7f5d56, 0x2844c6d0), TOBN(0xc633cf9b, 0x03a2477d),
-+     TOBN(0xf6be5c40, 0x2d3721d6), TOBN(0xaf312eb7, 0xe9fd68e6),
-+     TOBN(0x242792d2, 0xe7417ce1), TOBN(0xff42bc71, 0x970ee7f5),
-+     TOBN(0x1ff4dc6d, 0x5c67a41e), TOBN(0x77709b7b, 0x20882a58),
-+     TOBN(0x3554731d, 0xbe217f2c), TOBN(0x2af2a8cd, 0x5bb72177),
-+     TOBN(0x58eee769, 0x591dd059), TOBN(0xbb2930c9, 0x4bba6477),
-+     TOBN(0x863ee047, 0x7d930cfc), TOBN(0x4c262ad1, 0x396fd1f4),
-+     TOBN(0xf4765bc8, 0x039af7e1), TOBN(0x2519834b, 0x5ba104f6),
-+     TOBN(0x7cd61b4c, 0xd105f961), TOBN(0xa5415da5, 0xd63bca54),
-+     TOBN(0x778280a0, 0x88a1f17c), TOBN(0xc4968949, 0x2329512c),
-+     TOBN(0x174a9126, 0xcecdaa7a), TOBN(0xfc8c7e0e, 0x0b13247b),
-+     TOBN(0x29c110d2, 0x3484c1c4), TOBN(0xf8eb8757, 0x831dfc3b),
-+     TOBN(0x022f0212, 0xc0067452), TOBN(0x3f6f69ee, 0x7b9b926c),
-+     TOBN(0x09032da0, 0xef42daf4), TOBN(0x79f00ade, 0x83f80de4),
-+     TOBN(0x6210db71, 0x81236c97), TOBN(0x74f7685b, 0x3ee0781f),
-+     TOBN(0x4df7da7b, 0xa3e41372), TOBN(0x2aae38b1, 0xb1a1553e),
-+     TOBN(0x1688e222, 0xf6dd9d1b), TOBN(0x57695448, 0x5b8b6487),
-+     TOBN(0x478d2127, 0x4b2edeaa), TOBN(0xb2818fa5, 0x1e85956a),
-+     TOBN(0x1e6addda, 0xf176f2c0), TOBN(0x01ca4604, 0xe2572658),
-+     TOBN(0x0a404ded, 0x85342ffb), TOBN(0x8cf60f96, 0x441838d6),
-+     TOBN(0x9bbc691c, 0xc9071c4a), TOBN(0xfd588744, 0x34442803),
-+     TOBN(0x97101c85, 0x809c0d81), TOBN(0xa7fb754c, 0x8c456f7f),
-+     TOBN(0xc95f3c5c, 0xd51805e1), TOBN(0xab4ccd39, 0xb299dca8),
-+     TOBN(0x3e03d20b, 0x47eaf500), TOBN(0xfa3165c1, 0xd7b80893),
-+     TOBN(0x005e8b54, 0xe160e552), TOBN(0xdc4972ba, 0x9019d11f),
-+     TOBN(0x21a6972e, 0x0c9a4a7a), TOBN(0xa52c258f, 0x37840fd7),
-+     TOBN(0xf8559ff4, 0xc1e99d81), TOBN(0x08e1a7d6, 0xa3c617c0),
-+     TOBN(0xb398fd43, 0x248c6ba7), TOBN(0x6ffedd91, 0xd1283794),
-+     TOBN(0x8a6a59d2, 0xd629d208), TOBN(0xa9d141d5, 0x3490530e),
-+     TOBN(0x42f6fc18, 0x38505989), TOBN(0x09bf250d, 0x479d94ee),
-+     TOBN(0x223ad3b1, 0xb3822790), TOBN(0x6c5926c0, 0x93b8971c),
-+     TOBN(0x609efc7e, 0x75f7fa62), TOBN(0x45d66a6d, 0x1ec2d989),
-+     TOBN(0x4422d663, 0x987d2792), TOBN(0x4a73caad, 0x3eb31d2b),
-+     TOBN(0xf06c2ac1, 0xa32cb9e6), TOBN(0xd9445c5f, 0x91aeba84),
-+     TOBN(0x6af7a1d5, 0xaf71013f), TOBN(0xe68216e5, 0x0bedc946),
-+     TOBN(0xf4cba30b, 0xd27370a0), TOBN(0x7981afbf, 0x870421cc),
-+     TOBN(0x02496a67, 0x9449f0e1), TOBN(0x86cfc4be, 0x0a47edae),
-+     TOBN(0x3073c936, 0xb1feca22), TOBN(0xf5694612, 0x03f8f8fb),
-+     TOBN(0xd063b723, 0x901515ea), TOBN(0x4c6c77a5, 0x749cf038),
-+     TOBN(0x6361e360, 0xab9e5059), TOBN(0x596cf171, 0xa76a37c0),
-+     TOBN(0x800f53fa, 0x6530ae7a), TOBN(0x0f5e631e, 0x0792a7a6),
-+     TOBN(0x5cc29c24, 0xefdb81c9), TOBN(0xa269e868, 0x3f9c40ba),
-+     TOBN(0xec14f9e1, 0x2cb7191e), TOBN(0x78ea1bd8, 0xe5b08ea6),
-+     TOBN(0x3c65aa9b, 0x46332bb9), TOBN(0x84cc22b3, 0xbf80ce25),
-+     TOBN(0x0098e9e9, 0xd49d5bf1), TOBN(0xcd4ec1c6, 0x19087da4),
-+     TOBN(0x3c9d07c5, 0xaef6e357), TOBN(0x839a0268, 0x9f8f64b8),
-+     TOBN(0xc5e9eb62, 0xc6d8607f), TOBN(0x759689f5, 0x6aa995e4),
-+     TOBN(0x70464669, 0xbbb48317), TOBN(0x921474bf, 0xe402417d),
-+     TOBN(0xcabe135b, 0x2a354c8c), TOBN(0xd51e52d2, 0x812fa4b5),
-+     TOBN(0xec741096, 0x53311fe8), TOBN(0x4f774535, 0xb864514b),
-+     TOBN(0xbcadd671, 0x5bde48f8), TOBN(0xc9703873, 0x2189bc7d),
-+     TOBN(0x5d45299e, 0xc709ee8a), TOBN(0xd1287ee2, 0x845aaff8),
-+     TOBN(0x7d1f8874, 0xdb1dbf1f), TOBN(0xea46588b, 0x990c88d6),
-+     TOBN(0x60ba649a, 0x84368313), TOBN(0xd5fdcbce, 0x60d543ae),
-+     TOBN(0x90b46d43, 0x810d5ab0), TOBN(0x6739d8f9, 0x04d7e5cc),
-+     TOBN(0x021c1a58, 0x0d337c33), TOBN(0x00a61162, 0x68e67c40),
-+     TOBN(0x95ef413b, 0x379f0a1f), TOBN(0xfe126605, 0xe9e2ab95),
-+     TOBN(0x67578b85, 0x2f5f199c), TOBN(0xf5c00329, 0x2cb84913),
-+     TOBN(0xf7956430, 0x37577dd8), TOBN(0x83b82af4, 0x29c5fe88),
-+     TOBN(0x9c1bea26, 0xcdbdc132), TOBN(0x589fa086, 0x9c04339e),
-+     TOBN(0x033e9538, 0xb13799df), TOBN(0x85fa8b21, 0xd295d034),
-+     TOBN(0xdf17f73f, 0xbd9ddcca), TOBN(0xf32bd122, 0xddb66334),
-+     TOBN(0x55ef88a7, 0x858b044c), TOBN(0x1f0d69c2, 0x5aa9e397),
-+     TOBN(0x55fd9cc3, 0x40d85559), TOBN(0xc774df72, 0x7785ddb2),
-+     TOBN(0x5dcce9f6, 0xd3bd2e1c), TOBN(0xeb30da20, 0xa85dfed0),
-+     TOBN(0x5ed7f5bb, 0xd3ed09c4), TOBN(0x7d42a35c, 0x82a9c1bd),
-+     TOBN(0xcf3de995, 0x9890272d), TOBN(0x75f3432a, 0x3e713a10),
-+     TOBN(0x5e13479f, 0xe28227b8), TOBN(0xb8561ea9, 0xfefacdc8),
-+     TOBN(0xa6a297a0, 0x8332aafd), TOBN(0x9b0d8bb5, 0x73809b62),
-+     TOBN(0xd2fa1cfd, 0x0c63036f), TOBN(0x7a16eb55, 0xbd64bda8),
-+     TOBN(0x3f5cf5f6, 0x78e62ddc), TOBN(0x2267c454, 0x07fd752b),
-+     TOBN(0x5e361b6b, 0x5e437bbe), TOBN(0x95c59501, 0x8354e075),
-+     TOBN(0xec725f85, 0xf2b254d9), TOBN(0x844b617d, 0x2cb52b4e),
-+     TOBN(0xed8554f5, 0xcf425fb5), TOBN(0xab67703e, 0x2af9f312),
-+     TOBN(0x4cc34ec1, 0x3cf48283), TOBN(0xb09daa25, 0x9c8a705e),
-+     TOBN(0xd1e9d0d0, 0x5b7d4f84), TOBN(0x4df6ef64, 0xdb38929d),
-+     TOBN(0xe16b0763, 0xaa21ba46), TOBN(0xc6b1d178, 0xa293f8fb),
-+     TOBN(0x0ff5b602, 0xd520aabf), TOBN(0x94d671bd, 0xc339397a),
-+     TOBN(0x7c7d98cf, 0x4f5792fa), TOBN(0x7c5e0d67, 0x11215261),
-+     TOBN(0x9b19a631, 0xa7c5a6d4), TOBN(0xc8511a62, 0x7a45274d),
-+     TOBN(0x0c16621c, 0xa5a60d99), TOBN(0xf7fbab88, 0xcf5e48cb),
-+     TOBN(0xab1e6ca2, 0xf7ddee08), TOBN(0x83bd08ce, 0xe7867f3c),
-+     TOBN(0xf7e48e8a, 0x2ac13e27), TOBN(0x4494f6df, 0x4eb1a9f5),
-+     TOBN(0xedbf84eb, 0x981f0a62), TOBN(0x49badc32, 0x536438f0),
-+     TOBN(0x50bea541, 0x004f7571), TOBN(0xbac67d10, 0xdf1c94ee),
-+     TOBN(0x253d73a1, 0xb727bc31), TOBN(0xb3d01cf2, 0x30686e28),
-+     TOBN(0x51b77b1b, 0x55fd0b8b), TOBN(0xa099d183, 0xfeec3173),
-+     TOBN(0x202b1fb7, 0x670e72b7), TOBN(0xadc88b33, 0xa8e1635f),
-+     TOBN(0x34e8216a, 0xf989d905), TOBN(0xc2e68d20, 0x29b58d01),
-+     TOBN(0x11f81c92, 0x6fe55a93), TOBN(0x15f1462a, 0x8f296f40),
-+     TOBN(0x1915d375, 0xea3d62f2), TOBN(0xa17765a3, 0x01c8977d),
-+     TOBN(0x7559710a, 0xe47b26f6), TOBN(0xe0bd29c8, 0x535077a5),
-+     TOBN(0x615f976d, 0x08d84858), TOBN(0x370dfe85, 0x69ced5c1),
-+     TOBN(0xbbc7503c, 0xa734fa56), TOBN(0xfbb9f1ec, 0x91ac4574),
-+     TOBN(0x95d7ec53, 0x060dd7ef), TOBN(0xeef2dacd, 0x6e657979),
-+     TOBN(0x54511af3, 0xe2a08235), TOBN(0x1e324aa4, 0x1f4aea3d),
-+     TOBN(0x550e7e71, 0xe6e67671), TOBN(0xbccd5190, 0xbf52faf7),
-+     TOBN(0xf880d316, 0x223cc62a), TOBN(0x0d402c7e, 0x2b32eb5d),
-+     TOBN(0xa40bc039, 0x306a5a3b), TOBN(0x4e0a41fd, 0x96783a1b),
-+     TOBN(0xa1e8d39a, 0x0253cdd4), TOBN(0x6480be26, 0xc7388638),
-+     TOBN(0xee365e1d, 0x2285f382), TOBN(0x188d8d8f, 0xec0b5c36),
-+     TOBN(0x34ef1a48, 0x1f0f4d82), TOBN(0x1a8f43e1, 0xa487d29a),
-+     TOBN(0x8168226d, 0x77aefb3a), TOBN(0xf69a751e, 0x1e72c253),
-+     TOBN(0x8e04359a, 0xe9594df1), TOBN(0x475ffd7d, 0xd14c0467),
-+     TOBN(0xb5a2c2b1, 0x3844e95c), TOBN(0x85caf647, 0xdd12ef94),
-+     TOBN(0x1ecd2a9f, 0xf1063d00), TOBN(0x1dd2e229, 0x23843311),
-+     TOBN(0x38f0e09d, 0x73d17244), TOBN(0x3ede7746, 0x8fc653f1),
-+     TOBN(0xae4459f5, 0xdc20e21c), TOBN(0x00db2ffa, 0x6a8599ea),
-+     TOBN(0x11682c39, 0x30cfd905), TOBN(0x4934d074, 0xa5c112a6),
-+     TOBN(0xbdf063c5, 0x568bfe95), TOBN(0x779a440a, 0x016c441a),
-+     TOBN(0x0c23f218, 0x97d6fbdc), TOBN(0xd3a5cd87, 0xe0776aac),
-+     TOBN(0xcee37f72, 0xd712e8db), TOBN(0xfb28c70d, 0x26f74e8d),
-+     TOBN(0xffe0c728, 0xb61301a0), TOBN(0xa6282168, 0xd3724354),
-+     TOBN(0x7ff4cb00, 0x768ffedc), TOBN(0xc51b3088, 0x03b02de9),
-+     TOBN(0xa5a8147c, 0x3902dda5), TOBN(0x35d2f706, 0xfe6973b4),
-+     TOBN(0x5ac2efcf, 0xc257457e), TOBN(0x933f48d4, 0x8700611b),
-+     TOBN(0xc365af88, 0x4912beb2), TOBN(0x7f5a4de6, 0x162edf94),
-+     TOBN(0xc646ba7c, 0x0c32f34b), TOBN(0x632c6af3, 0xb2091074),
-+     TOBN(0x58d4f2e3, 0x753e43a9), TOBN(0x70e1d217, 0x24d4e23f),
-+     TOBN(0xb24bf729, 0xafede6a6), TOBN(0x7f4a94d8, 0x710c8b60),
-+     TOBN(0xaad90a96, 0x8d4faa6a), TOBN(0xd9ed0b32, 0xb066b690),
-+     TOBN(0x52fcd37b, 0x78b6dbfd), TOBN(0x0b64615e, 0x8bd2b431),
-+     TOBN(0x228e2048, 0xcfb9fad5), TOBN(0xbeaa386d, 0x240b76bd),
-+     TOBN(0x2d6681c8, 0x90dad7bc), TOBN(0x3e553fc3, 0x06d38f5e),
-+     TOBN(0xf27cdb9b, 0x9d5f9750), TOBN(0x3e85c52a, 0xd28c5b0e),
-+     TOBN(0x190795af, 0x5247c39b), TOBN(0x547831eb, 0xbddd6828),
-+     TOBN(0xf327a227, 0x4a82f424), TOBN(0x36919c78, 0x7e47f89d),
-+     TOBN(0xe4783919, 0x43c7392c), TOBN(0xf101b9aa, 0x2316fefe),
-+     TOBN(0xbcdc9e9c, 0x1c5009d2), TOBN(0xfb55ea13, 0x9cd18345),
-+     TOBN(0xf5b5e231, 0xa3ce77c7), TOBN(0xde6b4527, 0xd2f2cb3d),
-+     TOBN(0x10f6a333, 0x9bb26f5f), TOBN(0x1e85db8e, 0x044d85b6),
-+     TOBN(0xc3697a08, 0x94197e54), TOBN(0x65e18cc0, 0xa7cb4ea8),
-+     TOBN(0xa38c4f50, 0xa471fe6e), TOBN(0xf031747a, 0x2f13439c),
-+     TOBN(0x53c4a6ba, 0xc007318b), TOBN(0xa8da3ee5, 0x1deccb3d),
-+     TOBN(0x0555b31c, 0x558216b1), TOBN(0x90c7810c, 0x2f79e6c2),
-+     TOBN(0x9b669f4d, 0xfe8eed3c), TOBN(0x70398ec8, 0xe0fac126),
-+     TOBN(0xa96a449e, 0xf701b235), TOBN(0x0ceecdb3, 0xeb94f395),
-+     TOBN(0x285fc368, 0xd0cb7431), TOBN(0x0d37bb52, 0x16a18c64),
-+     TOBN(0x05110d38, 0xb880d2dd), TOBN(0xa60f177b, 0x65930d57),
-+     TOBN(0x7da34a67, 0xf36235f5), TOBN(0x47f5e17c, 0x183816b9),
-+     TOBN(0xc7664b57, 0xdb394af4), TOBN(0x39ba215d, 0x7036f789),
-+     TOBN(0x46d2ca0e, 0x2f27b472), TOBN(0xc42647ee, 0xf73a84b7),
-+     TOBN(0x44bc7545, 0x64488f1d), TOBN(0xaa922708, 0xf4cf85d5),
-+     TOBN(0x721a01d5, 0x53e4df63), TOBN(0x649c0c51, 0x5db46ced),
-+     TOBN(0x6bf0d64e, 0x3cffcb6c), TOBN(0xe3bf93fe, 0x50f71d96),
-+     TOBN(0x75044558, 0xbcc194a0), TOBN(0x16ae3372, 0x6afdc554),
-+     TOBN(0xbfc01adf, 0x5ca48f3f), TOBN(0x64352f06, 0xe22a9b84),
-+     TOBN(0xcee54da1, 0xc1099e4a), TOBN(0xbbda54e8, 0xfa1b89c0),
-+     TOBN(0x166a3df5, 0x6f6e55fb), TOBN(0x1ca44a24, 0x20176f88),
-+     TOBN(0x936afd88, 0xdfb7b5ff), TOBN(0xe34c2437, 0x8611d4a0),
-+     TOBN(0x7effbb75, 0x86142103), TOBN(0x6704ba1b, 0x1f34fc4d),
-+     TOBN(0x7c2a468f, 0x10c1b122), TOBN(0x36b3a610, 0x8c6aace9),
-+     TOBN(0xabfcc0a7, 0x75a0d050), TOBN(0x066f9197, 0x3ce33e32),
-+     TOBN(0xce905ef4, 0x29fe09be), TOBN(0x89ee25ba, 0xa8376351),
-+     TOBN(0x2a3ede22, 0xfd29dc76), TOBN(0x7fd32ed9, 0x36f17260),
-+     TOBN(0x0cadcf68, 0x284b4126), TOBN(0x63422f08, 0xa7951fc8),
-+     TOBN(0x562b24f4, 0x0807e199), TOBN(0xfe9ce5d1, 0x22ad4490),
-+     TOBN(0xc2f51b10, 0x0db2b1b4), TOBN(0xeb3613ff, 0xe4541d0d),
-+     TOBN(0xbd2c4a05, 0x2680813b), TOBN(0x527aa55d, 0x561b08d6),
-+     TOBN(0xa9f8a40e, 0xa7205558), TOBN(0xe3eea56f, 0x243d0bec),
-+     TOBN(0x7b853817, 0xa0ff58b3), TOBN(0xb67d3f65, 0x1a69e627),
-+     TOBN(0x0b76bbb9, 0xa869b5d6), TOBN(0xa3afeb82, 0x546723ed),
-+     TOBN(0x5f24416d, 0x3e554892), TOBN(0x8413b53d, 0x430e2a45),
-+     TOBN(0x99c56aee, 0x9032a2a0), TOBN(0x09432bf6, 0xeec367b1),
-+     TOBN(0x552850c6, 0xdaf0ecc1), TOBN(0x49ebce55, 0x5bc92048),
-+     TOBN(0xdfb66ba6, 0x54811307), TOBN(0x1b84f797, 0x6f298597),
-+     TOBN(0x79590481, 0x8d1d7a0d), TOBN(0xd9fabe03, 0x3a6fa556),
-+     TOBN(0xa40f9c59, 0xba9e5d35), TOBN(0xcb1771c1, 0xf6247577),
-+     TOBN(0x542a47ca, 0xe9a6312b), TOBN(0xa34b3560, 0x552dd8c5),
-+     TOBN(0xfdf94de0, 0x0d794716), TOBN(0xd46124a9, 0x9c623094),
-+     TOBN(0x56b7435d, 0x68afe8b4), TOBN(0x27f20540, 0x6c0d8ea1),
-+     TOBN(0x12b77e14, 0x73186898), TOBN(0xdbc3dd46, 0x7479490f),
-+     TOBN(0x951a9842, 0xc03b0c05), TOBN(0x8b1b3bb3, 0x7921bc96),
-+     TOBN(0xa573b346, 0x2b202e0a), TOBN(0x77e4665d, 0x47254d56),
-+     TOBN(0x08b70dfc, 0xd23e3984), TOBN(0xab86e8bc, 0xebd14236),
-+     TOBN(0xaa3e07f8, 0x57114ba7), TOBN(0x5ac71689, 0xab0ef4f2),
-+     TOBN(0x88fca384, 0x0139d9af), TOBN(0x72733f88, 0x76644af0),
-+     TOBN(0xf122f72a, 0x65d74f4a), TOBN(0x13931577, 0xa5626c7a),
-+     TOBN(0xd5b5d9eb, 0x70f8d5a4), TOBN(0x375adde7, 0xd7bbb228),
-+     TOBN(0x31e88b86, 0x0c1c0b32), TOBN(0xd1f568c4, 0x173edbaa),
-+     TOBN(0x1592fc83, 0x5459df02), TOBN(0x2beac0fb, 0x0fcd9a7e),
-+     TOBN(0xb0a6fdb8, 0x1b473b0a), TOBN(0xe3224c6f, 0x0fe8fc48),
-+     TOBN(0x680bd00e, 0xe87edf5b), TOBN(0x30385f02, 0x20e77cf5),
-+     TOBN(0xe9ab98c0, 0x4d42d1b2), TOBN(0x72d191d2, 0xd3816d77),
-+     TOBN(0x1564daca, 0x0917d9e5), TOBN(0x394eab59, 0x1f8fed7f),
-+     TOBN(0xa209aa8d, 0x7fbb3896), TOBN(0x5564f3b9, 0xbe6ac98e),
-+     TOBN(0xead21d05, 0xd73654ef), TOBN(0x68d1a9c4, 0x13d78d74),
-+     TOBN(0x61e01708, 0x6d4973a0), TOBN(0x83da3500, 0x46e6d32a),
-+     TOBN(0x6a3dfca4, 0x68ae0118), TOBN(0xa1b9a4c9, 0xd02da069),
-+     TOBN(0x0b2ff9c7, 0xebab8302), TOBN(0x98af07c3, 0x944ba436),
-+     TOBN(0x85997326, 0x995f0f9f), TOBN(0x467fade0, 0x71b58bc6),
-+     TOBN(0x47e4495a, 0xbd625a2b), TOBN(0xfdd2d01d, 0x33c3b8cd),
-+     TOBN(0x2c38ae28, 0xc693f9fa), TOBN(0x48622329, 0x348f7999),
-+     TOBN(0x97bf738e, 0x2161f583), TOBN(0x15ee2fa7, 0x565e8cc9),
-+     TOBN(0xa1a5c845, 0x5777e189), TOBN(0xcc10bee0, 0x456f2829),
-+     TOBN(0x8ad95c56, 0xda762bd5), TOBN(0x152e2214, 0xe9d91da8),
-+     TOBN(0x975b0e72, 0x7cb23c74), TOBN(0xfd5d7670, 0xa90c66df),
-+     TOBN(0xb5b5b8ad, 0x225ffc53), TOBN(0xab6dff73, 0xfaded2ae),
-+     TOBN(0xebd56781, 0x6f4cbe9d), TOBN(0x0ed8b249, 0x6a574bd7),
-+     TOBN(0x41c246fe, 0x81a881fa), TOBN(0x91564805, 0xc3db9c70),
-+     TOBN(0xd7c12b08, 0x5b862809), TOBN(0x1facd1f1, 0x55858d7b),
-+     TOBN(0x7693747c, 0xaf09e92a), TOBN(0x3b69dcba, 0x189a425f),
-+     TOBN(0x0be28e9f, 0x967365ef), TOBN(0x57300eb2, 0xe801f5c9),
-+     TOBN(0x93b8ac6a, 0xd583352f), TOBN(0xa2cf1f89, 0xcd05b2b7),
-+     TOBN(0x7c0c9b74, 0x4dcc40cc), TOBN(0xfee38c45, 0xada523fb),
-+     TOBN(0xb49a4dec, 0x1099cc4d), TOBN(0x325c377f, 0x69f069c6),
-+     TOBN(0xe12458ce, 0x476cc9ff), TOBN(0x580e0b6c, 0xc6d4cb63),
-+     TOBN(0xd561c8b7, 0x9072289b), TOBN(0x0377f264, 0xa619e6da),
-+     TOBN(0x26685362, 0x88e591a5), TOBN(0xa453a7bd, 0x7523ca2b),
-+     TOBN(0x8a9536d2, 0xc1df4533), TOBN(0xc8e50f2f, 0xbe972f79),
-+     TOBN(0xd433e50f, 0x6d3549cf), TOBN(0x6f33696f, 0xfacd665e),
-+     TOBN(0x695bfdac, 0xce11fcb4), TOBN(0x810ee252, 0xaf7c9860),
-+     TOBN(0x65450fe1, 0x7159bb2c), TOBN(0xf7dfbebe, 0x758b357b),
-+     TOBN(0x2b057e74, 0xd69fea72), TOBN(0xd485717a, 0x92731745),}
-+    ,
-+    {TOBN(0x896c42e8, 0xee36860c), TOBN(0xdaf04dfd, 0x4113c22d),
-+     TOBN(0x1adbb7b7, 0x44104213), TOBN(0xe5fd5fa1, 0x1fd394ea),
-+     TOBN(0x68235d94, 0x1a4e0551), TOBN(0x6772cfbe, 0x18d10151),
-+     TOBN(0x276071e3, 0x09984523), TOBN(0xe4e879de, 0x5a56ba98),
-+     TOBN(0xaaafafb0, 0x285b9491), TOBN(0x01a0be88, 0x1e4c705e),
-+     TOBN(0xff1d4f5d, 0x2ad9caab), TOBN(0x6e349a4a, 0xc37a233f),
-+     TOBN(0xcf1c1246, 0x4a1c6a16), TOBN(0xd99e6b66, 0x29383260),
-+     TOBN(0xea3d4366, 0x5f6d5471), TOBN(0x36974d04, 0xff8cc89b),
-+     TOBN(0xc26c49a1, 0xcfe89d80), TOBN(0xb42c026d, 0xda9c8371),
-+     TOBN(0xca6c013a, 0xdad066d2), TOBN(0xfb8f7228, 0x56a4f3ee),
-+     TOBN(0x08b579ec, 0xd850935b), TOBN(0x34c1a74c, 0xd631e1b3),
-+     TOBN(0xcb5fe596, 0xac198534), TOBN(0x39ff21f6, 0xe1f24f25),
-+     TOBN(0x27f29e14, 0x8f929057), TOBN(0x7a64ae06, 0xc0c853df),
-+     TOBN(0x256cd183, 0x58e9c5ce), TOBN(0x9d9cce82, 0xded092a5),
-+     TOBN(0xcc6e5979, 0x6e93b7c7), TOBN(0xe1e47092, 0x31bb9e27),
-+     TOBN(0xb70b3083, 0xaa9e29a0), TOBN(0xbf181a75, 0x3785e644),
-+     TOBN(0xf53f2c65, 0x8ead09f7), TOBN(0x1335e1d5, 0x9780d14d),
-+     TOBN(0x69cc20e0, 0xcd1b66bc), TOBN(0x9b670a37, 0xbbe0bfc8),
-+     TOBN(0xce53dc81, 0x28efbeed), TOBN(0x0c74e77c, 0x8326a6e5),
-+     TOBN(0x3604e0d2, 0xb88e9a63), TOBN(0xbab38fca, 0x13dc2248),
-+     TOBN(0x8ed6e8c8, 0x5c0a3f1e), TOBN(0xbcad2492, 0x7c87c37f),
-+     TOBN(0xfdfb62bb, 0x9ee3b78d), TOBN(0xeba8e477, 0xcbceba46),
-+     TOBN(0x37d38cb0, 0xeeaede4b), TOBN(0x0bc498e8, 0x7976deb6),
-+     TOBN(0xb2944c04, 0x6b6147fb), TOBN(0x8b123f35, 0xf71f9609),
-+     TOBN(0xa155dcc7, 0xde79dc24), TOBN(0xf1168a32, 0x558f69cd),
-+     TOBN(0xbac21595, 0x0d1850df), TOBN(0x15c8295b, 0xb204c848),
-+     TOBN(0xf661aa36, 0x7d8184ff), TOBN(0xc396228e, 0x30447bdb),
-+     TOBN(0x11cd5143, 0xbde4a59e), TOBN(0xe3a26e3b, 0x6beab5e6),
-+     TOBN(0xd3b3a13f, 0x1402b9d0), TOBN(0x573441c3, 0x2c7bc863),
-+     TOBN(0x4b301ec4, 0x578c3e6e), TOBN(0xc26fc9c4, 0x0adaf57e),
-+     TOBN(0x96e71bfd, 0x7493cea3), TOBN(0xd05d4b3f, 0x1af81456),
-+     TOBN(0xdaca2a8a, 0x6a8c608f), TOBN(0x53ef07f6, 0x0725b276),
-+     TOBN(0x07a5fbd2, 0x7824fc56), TOBN(0x34675218, 0x13289077),
-+     TOBN(0x5bf69fd5, 0xe0c48349), TOBN(0xa613ddd3, 0xb6aa7875),
-+     TOBN(0x7f78c19c, 0x5450d866), TOBN(0x46f4409c, 0x8f84a481),
-+     TOBN(0x9f1d1928, 0x90fce239), TOBN(0x016c4168, 0xb2ce44b9),
-+     TOBN(0xbae023f0, 0xc7435978), TOBN(0xb152c888, 0x20e30e19),
-+     TOBN(0x9c241645, 0xe3fa6faf), TOBN(0x735d95c1, 0x84823e60),
-+     TOBN(0x03197573, 0x03955317), TOBN(0x0b4b02a9, 0xf03b4995),
-+     TOBN(0x076bf559, 0x70274600), TOBN(0x32c5cc53, 0xaaf57508),
-+     TOBN(0xe8af6d1f, 0x60624129), TOBN(0xb7bc5d64, 0x9a5e2b5e),
-+     TOBN(0x3814b048, 0x5f082d72), TOBN(0x76f267f2, 0xce19677a),
-+     TOBN(0x626c630f, 0xb36eed93), TOBN(0x55230cd7, 0x3bf56803),
-+     TOBN(0x78837949, 0xce2736a0), TOBN(0x0d792d60, 0xaa6c55f1),
-+     TOBN(0x0318dbfd, 0xd5c7c5d2), TOBN(0xb38f8da7, 0x072b342d),
-+     TOBN(0x3569bddc, 0x7b8de38a), TOBN(0xf25b5887, 0xa1c94842),
-+     TOBN(0xb2d5b284, 0x2946ad60), TOBN(0x854f29ad, 0xe9d1707e),
-+     TOBN(0xaa5159dc, 0x2c6a4509), TOBN(0x899f94c0, 0x57189837),
-+     TOBN(0xcf6adc51, 0xf4a55b03), TOBN(0x261762de, 0x35e3b2d5),
-+     TOBN(0x4cc43012, 0x04827b51), TOBN(0xcd22a113, 0xc6021442),
-+     TOBN(0xce2fd61a, 0x247c9569), TOBN(0x59a50973, 0xd152beca),
-+     TOBN(0x6c835a11, 0x63a716d4), TOBN(0xc26455ed, 0x187dedcf),
-+     TOBN(0x27f536e0, 0x49ce89e7), TOBN(0x18908539, 0xcc890cb5),
-+     TOBN(0x308909ab, 0xd83c2aa1), TOBN(0xecd3142b, 0x1ab73bd3),
-+     TOBN(0x6a85bf59, 0xb3f5ab84), TOBN(0x3c320a68, 0xf2bea4c6),
-+     TOBN(0xad8dc538, 0x6da4541f), TOBN(0xeaf34eb0, 0xb7c41186),
-+     TOBN(0x1c780129, 0x977c97c4), TOBN(0x5ff9beeb, 0xc57eb9fa),
-+     TOBN(0xa24d0524, 0xc822c478), TOBN(0xfd8eec2a, 0x461cd415),
-+     TOBN(0xfbde194e, 0xf027458c), TOBN(0xb4ff5319, 0x1d1be115),
-+     TOBN(0x63f874d9, 0x4866d6f4), TOBN(0x35c75015, 0xb21ad0c9),
-+     TOBN(0xa6b5c9d6, 0x46ac49d2), TOBN(0x42c77c0b, 0x83137aa9),
-+     TOBN(0x24d000fc, 0x68225a38), TOBN(0x0f63cfc8, 0x2fe1e907),
-+     TOBN(0x22d1b01b, 0xc6441f95), TOBN(0x7d38f719, 0xec8e448f),
-+     TOBN(0x9b33fa5f, 0x787fb1ba), TOBN(0x94dcfda1, 0x190158df),
-+     TOBN(0xc47cb339, 0x5f6d4a09), TOBN(0x6b4f355c, 0xee52b826),
-+     TOBN(0x3d100f5d, 0xf51b930a), TOBN(0xf4512fac, 0x9f668f69),
-+     TOBN(0x546781d5, 0x206c4c74), TOBN(0xd021d4d4, 0xcb4d2e48),
-+     TOBN(0x494a54c2, 0xca085c2d), TOBN(0xf1dbaca4, 0x520850a8),
-+     TOBN(0x63c79326, 0x490a1aca), TOBN(0xcb64dd9c, 0x41526b02),
-+     TOBN(0xbb772591, 0xa2979258), TOBN(0x3f582970, 0x48d97846),
-+     TOBN(0xd66b70d1, 0x7c213ba7), TOBN(0xc28febb5, 0xe8a0ced4),
-+     TOBN(0x6b911831, 0xc10338c1), TOBN(0x0d54e389, 0xbf0126f3),
-+     TOBN(0x7048d460, 0x4af206ee), TOBN(0x786c88f6, 0x77e97cb9),
-+     TOBN(0xd4375ae1, 0xac64802e), TOBN(0x469bcfe1, 0xd53ec11c),
-+     TOBN(0xfc9b340d, 0x47062230), TOBN(0xe743bb57, 0xc5b4a3ac),
-+     TOBN(0xfe00b4aa, 0x59ef45ac), TOBN(0x29a4ef23, 0x59edf188),
-+     TOBN(0x40242efe, 0xb483689b), TOBN(0x2575d3f6, 0x513ac262),
-+     TOBN(0xf30037c8, 0x0ca6db72), TOBN(0xc9fcce82, 0x98864be2),
-+     TOBN(0x84a112ff, 0x0149362d), TOBN(0x95e57582, 0x1c4ae971),
-+     TOBN(0x1fa4b1a8, 0x945cf86c), TOBN(0x4525a734, 0x0b024a2f),
-+     TOBN(0xe76c8b62, 0x8f338360), TOBN(0x483ff593, 0x28edf32b),
-+     TOBN(0x67e8e90a, 0x298b1aec), TOBN(0x9caab338, 0x736d9a21),
-+     TOBN(0x5c09d2fd, 0x66892709), TOBN(0x2496b4dc, 0xb55a1d41),
-+     TOBN(0x93f5fb1a, 0xe24a4394), TOBN(0x08c75049, 0x6fa8f6c1),
-+     TOBN(0xcaead1c2, 0xc905d85f), TOBN(0xe9d7f790, 0x0733ae57),
-+     TOBN(0x24c9a65c, 0xf07cdd94), TOBN(0x7389359c, 0xa4b55931),
-+     TOBN(0xf58709b7, 0x367e45f7), TOBN(0x1f203067, 0xcb7e7adc),
-+     TOBN(0x82444bff, 0xc7b72818), TOBN(0x07303b35, 0xbaac8033),
-+     TOBN(0x1e1ee4e4, 0xd13b7ea1), TOBN(0xe6489b24, 0xe0e74180),
-+     TOBN(0xa5f2c610, 0x7e70ef70), TOBN(0xa1655412, 0xbdd10894),
-+     TOBN(0x555ebefb, 0x7af4194e), TOBN(0x533c1c3c, 0x8e89bd9c),
-+     TOBN(0x735b9b57, 0x89895856), TOBN(0x15fb3cd2, 0x567f5c15),
-+     TOBN(0x057fed45, 0x526f09fd), TOBN(0xe8a4f10c, 0x8128240a),
-+     TOBN(0x9332efc4, 0xff2bfd8d), TOBN(0x214e77a0, 0xbd35aa31),
-+     TOBN(0x32896d73, 0x14faa40e), TOBN(0x767867ec, 0x01e5f186),
-+     TOBN(0xc9adf8f1, 0x17a1813e), TOBN(0xcb6cda78, 0x54741795),
-+     TOBN(0xb7521b6d, 0x349d51aa), TOBN(0xf56b5a9e, 0xe3c7b8e9),
-+     TOBN(0xc6f1e5c9, 0x32a096df), TOBN(0x083667c4, 0xa3635024),
-+     TOBN(0x365ea135, 0x18087f2f), TOBN(0xf1b8eaac, 0xd136e45d),
-+     TOBN(0xc8a0e484, 0x73aec989), TOBN(0xd75a324b, 0x142c9259),
-+     TOBN(0xb7b4d001, 0x01dae185), TOBN(0x45434e0b, 0x9b7a94bc),
-+     TOBN(0xf54339af, 0xfbd8cb0b), TOBN(0xdcc4569e, 0xe98ef49e),
-+     TOBN(0x7789318a, 0x09a51299), TOBN(0x81b4d206, 0xb2b025d8),
-+     TOBN(0xf64aa418, 0xfae85792), TOBN(0x3e50258f, 0xacd7baf7),
-+     TOBN(0xdce84cdb, 0x2996864b), TOBN(0xa2e67089, 0x1f485fa4),
-+     TOBN(0xb28b2bb6, 0x534c6a5a), TOBN(0x31a7ec6b, 0xc94b9d39),
-+     TOBN(0x1d217766, 0xd6bc20da), TOBN(0x4acdb5ec, 0x86761190),
-+     TOBN(0x68726328, 0x73701063), TOBN(0x4d24ee7c, 0x2128c29b),
-+     TOBN(0xc072ebd3, 0xa19fd868), TOBN(0x612e481c, 0xdb8ddd3b),
-+     TOBN(0xb4e1d754, 0x1a64d852), TOBN(0x00ef95ac, 0xc4c6c4ab),
-+     TOBN(0x1536d2ed, 0xaa0a6c46), TOBN(0x61294086, 0x43774790),
-+     TOBN(0x54af25e8, 0x343fda10), TOBN(0x9ff9d98d, 0xfd25d6f2),
-+     TOBN(0x0746af7c, 0x468b8835), TOBN(0x977a31cb, 0x730ecea7),
-+     TOBN(0xa5096b80, 0xc2cf4a81), TOBN(0xaa986833, 0x6458c37a),
-+     TOBN(0x6af29bf3, 0xa6bd9d34), TOBN(0x6a62fe9b, 0x33c5d854),
-+     TOBN(0x50e6c304, 0xb7133b5e), TOBN(0x04b60159, 0x7d6e6848),
-+     TOBN(0x4cd296df, 0x5579bea4), TOBN(0x10e35ac8, 0x5ceedaf1),
-+     TOBN(0x04c4c5fd, 0xe3bcc5b1), TOBN(0x95f9ee8a, 0x89412cf9),
-+     TOBN(0x2c9459ee, 0x82b6eb0f), TOBN(0x2e845765, 0x95c2aadd),
-+     TOBN(0x774a84ae, 0xd327fcfe), TOBN(0xd8c93722, 0x0368d476),
-+     TOBN(0x0dbd5748, 0xf83e8a3b), TOBN(0xa579aa96, 0x8d2495f3),
-+     TOBN(0x535996a0, 0xae496e9b), TOBN(0x07afbfe9, 0xb7f9bcc2),
-+     TOBN(0x3ac1dc6d, 0x5b7bd293), TOBN(0x3b592cff, 0x7022323d),
-+     TOBN(0xba0deb98, 0x9c0a3e76), TOBN(0x18e78e9f, 0x4b197acb),
-+     TOBN(0x211cde10, 0x296c36ef), TOBN(0x7ee89672, 0x82c4da77),
-+     TOBN(0xb617d270, 0xa57836da), TOBN(0xf0cd9c31, 0x9cb7560b),
-+     TOBN(0x01fdcbf7, 0xe455fe90), TOBN(0x3fb53cbb, 0x7e7334f3),
-+     TOBN(0x781e2ea4, 0x4e7de4ec), TOBN(0x8adab3ad, 0x0b384fd0),
-+     TOBN(0x129eee2f, 0x53d64829), TOBN(0x7a471e17, 0xa261492b),
-+     TOBN(0xe4f9adb9, 0xe4cb4a2c), TOBN(0x3d359f6f, 0x97ba2c2d),
-+     TOBN(0x346c6786, 0x0aacd697), TOBN(0x92b444c3, 0x75c2f8a8),
-+     TOBN(0xc79fa117, 0xd85df44e), TOBN(0x56782372, 0x398ddf31),
-+     TOBN(0x60e690f2, 0xbbbab3b8), TOBN(0x4851f8ae, 0x8b04816b),
-+     TOBN(0xc72046ab, 0x9c92e4d2), TOBN(0x518c74a1, 0x7cf3136b),
-+     TOBN(0xff4eb50a, 0xf9877d4c), TOBN(0x14578d90, 0xa919cabb),
-+     TOBN(0x8218f8c4, 0xac5eb2b6), TOBN(0xa3ccc547, 0x542016e4),
-+     TOBN(0x025bf48e, 0x327f8349), TOBN(0xf3e97346, 0xf43cb641),
-+     TOBN(0xdc2bafdf, 0x500f1085), TOBN(0x57167876, 0x2f063055),
-+     TOBN(0x5bd914b9, 0x411925a6), TOBN(0x7c078d48, 0xa1123de5),
-+     TOBN(0xee6bf835, 0x182b165d), TOBN(0xb11b5e5b, 0xba519727),
-+     TOBN(0xe33ea76c, 0x1eea7b85), TOBN(0x2352b461, 0x92d4f85e),
-+     TOBN(0xf101d334, 0xafe115bb), TOBN(0xfabc1294, 0x889175a3),
-+     TOBN(0x7f6bcdc0, 0x5233f925), TOBN(0xe0a802db, 0xe77fec55),
-+     TOBN(0xbdb47b75, 0x8069b659), TOBN(0x1c5e12de, 0xf98fbd74),
-+     TOBN(0x869c58c6, 0x4b8457ee), TOBN(0xa5360f69, 0x4f7ea9f7),
-+     TOBN(0xe576c09f, 0xf460b38f), TOBN(0x6b70d548, 0x22b7fb36),
-+     TOBN(0x3fd237f1, 0x3bfae315), TOBN(0x33797852, 0xcbdff369),
-+     TOBN(0x97df25f5, 0x25b516f9), TOBN(0x46f388f2, 0xba38ad2d),
-+     TOBN(0x656c4658, 0x89d8ddbb), TOBN(0x8830b26e, 0x70f38ee8),
-+     TOBN(0x4320fd5c, 0xde1212b0), TOBN(0xc34f30cf, 0xe4a2edb2),
-+     TOBN(0xabb131a3, 0x56ab64b8), TOBN(0x7f77f0cc, 0xd99c5d26),
-+     TOBN(0x66856a37, 0xbf981d94), TOBN(0x19e76d09, 0x738bd76e),
-+     TOBN(0xe76c8ac3, 0x96238f39), TOBN(0xc0a482be, 0xa830b366),
-+     TOBN(0xb7b8eaff, 0x0b4eb499), TOBN(0x8ecd83bc, 0x4bfb4865),
-+     TOBN(0x971b2cb7, 0xa2f3776f), TOBN(0xb42176a4, 0xf4b88adf),
-+     TOBN(0xb9617df5, 0xbe1fa446), TOBN(0x8b32d508, 0xcd031bd2),
-+     TOBN(0x1c6bd47d, 0x53b618c0), TOBN(0xc424f46c, 0x6a227923),
-+     TOBN(0x7303ffde, 0xdd92d964), TOBN(0xe9712878, 0x71b5abf2),
-+     TOBN(0x8f48a632, 0xf815561d), TOBN(0x85f48ff5, 0xd3c055d1),
-+     TOBN(0x222a1427, 0x7525684f), TOBN(0xd0d841a0, 0x67360cc3),
-+     TOBN(0x4245a926, 0x0b9267c6), TOBN(0xc78913f1, 0xcf07f863),
-+     TOBN(0xaa844c8e, 0x4d0d9e24), TOBN(0xa42ad522, 0x3d5f9017),
-+     TOBN(0xbd371749, 0xa2c989d5), TOBN(0x928292df, 0xe1f5e78e),
-+     TOBN(0x493b383e, 0x0a1ea6da), TOBN(0x5136fd8d, 0x13aee529),
-+     TOBN(0x860c44b1, 0xf2c34a99), TOBN(0x3b00aca4, 0xbf5855ac),
-+     TOBN(0xabf6aaa0, 0xfaaf37be), TOBN(0x65f43682, 0x2a53ec08),
-+     TOBN(0x1d9a5801, 0xa11b12e1), TOBN(0x78a7ab2c, 0xe20ed475),
-+     TOBN(0x0de1067e, 0x9a41e0d5), TOBN(0x30473f5f, 0x305023ea),
-+     TOBN(0xdd3ae09d, 0x169c7d97), TOBN(0x5cd5baa4, 0xcfaef9cd),
-+     TOBN(0x5cd7440b, 0x65a44803), TOBN(0xdc13966a, 0x47f364de),
-+     TOBN(0x077b2be8, 0x2b8357c1), TOBN(0x0cb1b4c5, 0xe9d57c2a),
-+     TOBN(0x7a4ceb32, 0x05ff363e), TOBN(0xf310fa4d, 0xca35a9ef),
-+     TOBN(0xdbb7b352, 0xf97f68c6), TOBN(0x0c773b50, 0x0b02cf58),
-+     TOBN(0xea2e4821, 0x3c1f96d9), TOBN(0xffb357b0, 0xeee01815),
-+     TOBN(0xb9c924cd, 0xe0f28039), TOBN(0x0b36c95a, 0x46a3fbe4),
-+     TOBN(0x1faaaea4, 0x5e46db6c), TOBN(0xcae575c3, 0x1928aaff),
-+     TOBN(0x7f671302, 0xa70dab86), TOBN(0xfcbd12a9, 0x71c58cfc),
-+     TOBN(0xcbef9acf, 0xbee0cb92), TOBN(0x573da0b9, 0xf8c1b583),
-+     TOBN(0x4752fcfe, 0x0d41d550), TOBN(0xe7eec0e3, 0x2155cffe),
-+     TOBN(0x0fc39fcb, 0x545ae248), TOBN(0x522cb8d1, 0x8065f44e),
-+     TOBN(0x263c962a, 0x70cbb96c), TOBN(0xe034362a, 0xbcd124a9),
-+     TOBN(0xf120db28, 0x3c2ae58d), TOBN(0xb9a38d49, 0xfef6d507),
-+     TOBN(0xb1fd2a82, 0x1ff140fd), TOBN(0xbd162f30, 0x20aee7e0),
-+     TOBN(0x4e17a5d4, 0xcb251949), TOBN(0x2aebcb83, 0x4f7e1c3d),
-+     TOBN(0x608eb25f, 0x937b0527), TOBN(0xf42e1e47, 0xeb7d9997),
-+     TOBN(0xeba699c4, 0xb8a53a29), TOBN(0x1f921c71, 0xe091b536),
-+     TOBN(0xcce29e7b, 0x5b26bbd5), TOBN(0x7a8ef5ed, 0x3b61a680),
-+     TOBN(0xe5ef8043, 0xba1f1c7e), TOBN(0x16ea8217, 0x18158dda),
-+     TOBN(0x01778a2b, 0x599ff0f9), TOBN(0x68a923d7, 0x8104fc6b),
-+     TOBN(0x5bfa44df, 0xda694ff3), TOBN(0x4f7199db, 0xf7667f12),
-+     TOBN(0xc06d8ff6, 0xe46f2a79), TOBN(0x08b5dead, 0xe9f8131d),
-+     TOBN(0x02519a59, 0xabb4ce7c), TOBN(0xc4f710bc, 0xb42aec3e),
-+     TOBN(0x3d77b057, 0x78bde41a), TOBN(0x6474bf80, 0xb4186b5a),
-+     TOBN(0x048b3f67, 0x88c65741), TOBN(0xc64519de, 0x03c7c154),
-+     TOBN(0xdf073846, 0x0edfcc4f), TOBN(0x319aa737, 0x48f1aa6b),
-+     TOBN(0x8b9f8a02, 0xca909f77), TOBN(0x90258139, 0x7580bfef),
-+     TOBN(0xd8bfd3ca, 0xc0c22719), TOBN(0xc60209e4, 0xc9ca151e),
-+     TOBN(0x7a744ab5, 0xd9a1a69c), TOBN(0x6de5048b, 0x14937f8f),
-+     TOBN(0x171938d8, 0xe115ac04), TOBN(0x7df70940, 0x1c6b16d2),
-+     TOBN(0xa6aeb663, 0x7f8e94e7), TOBN(0xc130388e, 0x2a2cf094),
-+     TOBN(0x1850be84, 0x77f54e6e), TOBN(0x9f258a72, 0x65d60fe5),
-+     TOBN(0xff7ff0c0, 0x6c9146d6), TOBN(0x039aaf90, 0xe63a830b),
-+     TOBN(0x38f27a73, 0x9460342f), TOBN(0x4703148c, 0x3f795f8a),
-+     TOBN(0x1bb5467b, 0x9681a97e), TOBN(0x00931ba5, 0xecaeb594),
-+     TOBN(0xcdb6719d, 0x786f337c), TOBN(0xd9c01cd2, 0xe704397d),
-+     TOBN(0x0f4a3f20, 0x555c2fef), TOBN(0x00452509, 0x7c0af223),
-+     TOBN(0x54a58047, 0x84db8e76), TOBN(0x3bacf1aa, 0x93c8aa06),
-+     TOBN(0x11ca957c, 0xf7919422), TOBN(0x50641053, 0x78cdaa40),
-+     TOBN(0x7a303874, 0x9f7144ae), TOBN(0x170c963f, 0x43d4acfd),
-+     TOBN(0x5e148149, 0x58ddd3ef), TOBN(0xa7bde582, 0x9e72dba8),
-+     TOBN(0x0769da8b, 0x6fa68750), TOBN(0xfa64e532, 0x572e0249),
-+     TOBN(0xfcaadf9d, 0x2619ad31), TOBN(0x87882daa, 0xa7b349cd),
-+     TOBN(0x9f6eb731, 0x6c67a775), TOBN(0xcb10471a, 0xefc5d0b1),
-+     TOBN(0xb433750c, 0xe1b806b2), TOBN(0x19c5714d, 0x57b1ae7e),
-+     TOBN(0xc0dc8b7b, 0xed03fd3f), TOBN(0xdd03344f, 0x31bc194e),
-+     TOBN(0xa66c52a7, 0x8c6320b5), TOBN(0x8bc82ce3, 0xd0b6fd93),
-+     TOBN(0xf8e13501, 0xb35f1341), TOBN(0xe53156dd, 0x25a43e42),
-+     TOBN(0xd3adf27e, 0x4daeb85c), TOBN(0xb81d8379, 0xbbeddeb5),
-+     TOBN(0x1b0b546e, 0x2e435867), TOBN(0x9020eb94, 0xeba5dd60),
-+     TOBN(0x37d91161, 0x8210cb9d), TOBN(0x4c596b31, 0x5c91f1cf),
-+     TOBN(0xb228a90f, 0x0e0b040d), TOBN(0xbaf02d82, 0x45ff897f),
-+     TOBN(0x2aac79e6, 0x00fa6122), TOBN(0x24828817, 0x8e36f557),
-+     TOBN(0xb9521d31, 0x113ec356), TOBN(0x9e48861e, 0x15eff1f8),
-+     TOBN(0x2aa1d412, 0xe0d41715), TOBN(0x71f86203, 0x53f131b8),
-+     TOBN(0xf60da8da, 0x3fd19408), TOBN(0x4aa716dc, 0x278d9d99),
-+     TOBN(0x394531f7, 0xa8c51c90), TOBN(0xb560b0e8, 0xf59db51c),
-+     TOBN(0xa28fc992, 0xfa34bdad), TOBN(0xf024fa14, 0x9cd4f8bd),
-+     TOBN(0x5cf530f7, 0x23a9d0d3), TOBN(0x615ca193, 0xe28c9b56),
-+     TOBN(0x6d2a483d, 0x6f73c51e), TOBN(0xa4cb2412, 0xea0dc2dd),
-+     TOBN(0x50663c41, 0x1eb917ff), TOBN(0x3d3a74cf, 0xeade299e),
-+     TOBN(0x29b3990f, 0x4a7a9202), TOBN(0xa9bccf59, 0xa7b15c3d),
-+     TOBN(0x66a3ccdc, 0xa5df9208), TOBN(0x48027c14, 0x43f2f929),
-+     TOBN(0xd385377c, 0x40b557f0), TOBN(0xe001c366, 0xcd684660),
-+     TOBN(0x1b18ed6b, 0xe2183a27), TOBN(0x879738d8, 0x63210329),
-+     TOBN(0xa687c74b, 0xbda94882), TOBN(0xd1bbcc48, 0xa684b299),
-+     TOBN(0xaf6f1112, 0x863b3724), TOBN(0x6943d1b4, 0x2c8ce9f8),
-+     TOBN(0xe044a3bb, 0x098cafb4), TOBN(0x27ed2310, 0x60d48caf),
-+     TOBN(0x542b5675, 0x3a31b84d), TOBN(0xcbf3dd50, 0xfcddbed7),
-+     TOBN(0x25031f16, 0x41b1d830), TOBN(0xa7ec851d, 0xcb0c1e27),
-+     TOBN(0xac1c8fe0, 0xb5ae75db), TOBN(0xb24c7557, 0x08c52120),
-+     TOBN(0x57f811dc, 0x1d4636c3), TOBN(0xf8436526, 0x681a9939),
-+     TOBN(0x1f6bc6d9, 0x9c81adb3), TOBN(0x840f8ac3, 0x5b7d80d4),
-+     TOBN(0x731a9811, 0xf4387f1a), TOBN(0x7c501cd3, 0xb5156880),
-+     TOBN(0xa5ca4a07, 0xdfe68867), TOBN(0xf123d8f0, 0x5fcea120),
-+     TOBN(0x1fbb0e71, 0xd607039e), TOBN(0x2b70e215, 0xcd3a4546),
-+     TOBN(0x32d2f01d, 0x53324091), TOBN(0xb796ff08, 0x180ab19b),
-+     TOBN(0x32d87a86, 0x3c57c4aa), TOBN(0x2aed9caf, 0xb7c49a27),
-+     TOBN(0x9fb35eac, 0x31630d98), TOBN(0x338e8cdf, 0x5c3e20a3),
-+     TOBN(0x80f16182, 0x66cde8db), TOBN(0x4e159980, 0x2d72fd36),
-+     TOBN(0xd7b8f13b, 0x9b6e5072), TOBN(0xf5213907, 0x3b7b5dc1),
-+     TOBN(0x4d431f1d, 0x8ce4396e), TOBN(0x37a1a680, 0xa7ed2142),
-+     TOBN(0xbf375696, 0xd01aaf6b), TOBN(0xaa1c0c54, 0xe63aab66),
-+     TOBN(0x3014368b, 0x4ed80940), TOBN(0x67e6d056, 0x7a6fcedd),
-+     TOBN(0x7c208c49, 0xca97579f), TOBN(0xfe3d7a81, 0xa23597f6),
-+     TOBN(0x5e203202, 0x7e096ae2), TOBN(0xb1f3e1e7, 0x24b39366),
-+     TOBN(0x26da26f3, 0x2fdcdffc), TOBN(0x79422f1d, 0x6097be83),}
-+    ,
-+    {TOBN(0x263a2cfb, 0x9db3b381), TOBN(0x9c3a2dee, 0xd4df0a4b),
-+     TOBN(0x728d06e9, 0x7d04e61f), TOBN(0x8b1adfbc, 0x42449325),
-+     TOBN(0x6ec1d939, 0x7e053a1b), TOBN(0xee2be5c7, 0x66daf707),
-+     TOBN(0x80ba1e14, 0x810ac7ab), TOBN(0xdd2ae778, 0xf530f174),
-+     TOBN(0x0435d97a, 0x205b9d8b), TOBN(0x6eb8f064, 0x056756d4),
-+     TOBN(0xd5e88a8b, 0xb6f8210e), TOBN(0x070ef12d, 0xec9fd9ea),
-+     TOBN(0x4d849505, 0x3bcc876a), TOBN(0x12a75338, 0xa7404ce3),
-+     TOBN(0xd22b49e1, 0xb8a1db5e), TOBN(0xec1f2051, 0x14bfa5ad),
-+     TOBN(0xadbaeb79, 0xb6828f36), TOBN(0x9d7a0258, 0x01bd5b9e),
-+     TOBN(0xeda01e0d, 0x1e844b0c), TOBN(0x4b625175, 0x887edfc9),
-+     TOBN(0x14109fdd, 0x9669b621), TOBN(0x88a2ca56, 0xf6f87b98),
-+     TOBN(0xfe2eb788, 0x170df6bc), TOBN(0x0cea06f4, 0xffa473f9),
-+     TOBN(0x43ed81b5, 0xc4e83d33), TOBN(0xd9f35879, 0x5efd488b),
-+     TOBN(0x164a620f, 0x9deb4d0f), TOBN(0xc6927bdb, 0xac6a7394),
-+     TOBN(0x45c28df7, 0x9f9e0f03), TOBN(0x2868661e, 0xfcd7e1a9),
-+     TOBN(0x7cf4e8d0, 0xffa348f1), TOBN(0x6bd4c284, 0x398538e0),
-+     TOBN(0x2618a091, 0x289a8619), TOBN(0xef796e60, 0x6671b173),
-+     TOBN(0x664e46e5, 0x9090c632), TOBN(0xa38062d4, 0x1e66f8fb),
-+     TOBN(0x6c744a20, 0x0573274e), TOBN(0xd07b67e4, 0xa9271394),
-+     TOBN(0x391223b2, 0x6bdc0e20), TOBN(0xbe2d93f1, 0xeb0a05a7),
-+     TOBN(0xf23e2e53, 0x3f36d141), TOBN(0xe84bb3d4, 0x4dfca442),
-+     TOBN(0xb804a48d, 0x6b7c023a), TOBN(0x1e16a8fa, 0x76431c3b),
-+     TOBN(0x1b5452ad, 0xddd472e0), TOBN(0x7d405ee7, 0x0d1ee127),
-+     TOBN(0x50fc6f1d, 0xffa27599), TOBN(0x351ac53c, 0xbf391b35),
-+     TOBN(0x7efa14b8, 0x4444896b), TOBN(0x64974d2f, 0xf94027fb),
-+     TOBN(0xefdcd0e8, 0xde84487d), TOBN(0x8c45b260, 0x2b48989b),
-+     TOBN(0xa8fcbbc2, 0xd8463487), TOBN(0xd1b2b3f7, 0x3fbc476c),
-+     TOBN(0x21d005b7, 0xc8f443c0), TOBN(0x518f2e67, 0x40c0139c),
-+     TOBN(0x56036e8c, 0x06d75fc1), TOBN(0x2dcf7bb7, 0x3249a89f),
-+     TOBN(0x81dd1d3d, 0xe245e7dd), TOBN(0xf578dc4b, 0xebd6e2a7),
-+     TOBN(0x4c028903, 0xdf2ce7a0), TOBN(0xaee36288, 0x9c39afac),
-+     TOBN(0xdc847c31, 0x146404ab), TOBN(0x6304c0d8, 0xa4e97818),
-+     TOBN(0xae51dca2, 0xa91f6791), TOBN(0x2abe4190, 0x9baa9efc),
-+     TOBN(0xd9d2e2f4, 0x559c7ac1), TOBN(0xe82f4b51, 0xfc9f773a),
-+     TOBN(0xa7713027, 0x4073e81c), TOBN(0xc0276fac, 0xfbb596fc),
-+     TOBN(0x1d819fc9, 0xa684f70c), TOBN(0x29b47fdd, 0xc9f7b1e0),
-+     TOBN(0x358de103, 0x459b1940), TOBN(0xec881c59, 0x5b013e93),
-+     TOBN(0x51574c93, 0x49532ad3), TOBN(0x2db1d445, 0xb37b46de),
-+     TOBN(0xc6445b87, 0xdf239fd8), TOBN(0xc718af75, 0x151d24ee),
-+     TOBN(0xaea1c4a4, 0xf43c6259), TOBN(0x40c0e5d7, 0x70be02f7),
-+     TOBN(0x6a4590f4, 0x721b33f2), TOBN(0x2124f1fb, 0xfedf04ea),
-+     TOBN(0xf8e53cde, 0x9745efe7), TOBN(0xe7e10432, 0x65f046d9),
-+     TOBN(0xc3fca28e, 0xe4d0c7e6), TOBN(0x847e339a, 0x87253b1b),
-+     TOBN(0x9b595348, 0x3743e643), TOBN(0xcb6a0a0b, 0x4fd12fc5),
-+     TOBN(0xfb6836c3, 0x27d02dcc), TOBN(0x5ad00982, 0x7a68bcc2),
-+     TOBN(0x1b24b44c, 0x005e912d), TOBN(0xcc83d20f, 0x811fdcfe),
-+     TOBN(0x36527ec1, 0x666fba0c), TOBN(0x69948197, 0x14754635),
-+     TOBN(0xfcdcb1a8, 0x556da9c2), TOBN(0xa5934267, 0x81a732b2),
-+     TOBN(0xec1214ed, 0xa714181d), TOBN(0x609ac13b, 0x6067b341),
-+     TOBN(0xff4b4c97, 0xa545df1f), TOBN(0xa1240501, 0x34d2076b),
-+     TOBN(0x6efa0c23, 0x1409ca97), TOBN(0x254cc1a8, 0x20638c43),
-+     TOBN(0xd4e363af, 0xdcfb46cd), TOBN(0x62c2adc3, 0x03942a27),
-+     TOBN(0xc67b9df0, 0x56e46483), TOBN(0xa55abb20, 0x63736356),
-+     TOBN(0xab93c098, 0xc551bc52), TOBN(0x382b49f9, 0xb15fe64b),
-+     TOBN(0x9ec221ad, 0x4dff8d47), TOBN(0x79caf615, 0x437df4d6),
-+     TOBN(0x5f13dc64, 0xbb456509), TOBN(0xe4c589d9, 0x191f0714),
-+     TOBN(0x27b6a8ab, 0x3fd40e09), TOBN(0xe455842e, 0x77313ea9),
-+     TOBN(0x8b51d1e2, 0x1f55988b), TOBN(0x5716dd73, 0x062bbbfc),
-+     TOBN(0x633c11e5, 0x4e8bf3de), TOBN(0x9a0e77b6, 0x1b85be3b),
-+     TOBN(0x56510729, 0x0911cca6), TOBN(0x27e76495, 0xefa6590f),
-+     TOBN(0xe4ac8b33, 0x070d3aab), TOBN(0x2643672b, 0x9a2cd5e5),
-+     TOBN(0x52eff79b, 0x1cfc9173), TOBN(0x665ca49b, 0x90a7c13f),
-+     TOBN(0x5a8dda59, 0xb3efb998), TOBN(0x8a5b922d, 0x052f1341),
-+     TOBN(0xae9ebbab, 0x3cf9a530), TOBN(0x35986e7b, 0xf56da4d7),
-+     TOBN(0x3a636b5c, 0xff3513cc), TOBN(0xbb0cf8ba, 0x3198f7dd),
-+     TOBN(0xb8d40522, 0x41f16f86), TOBN(0x760575d8, 0xde13a7bf),
-+     TOBN(0x36f74e16, 0x9f7aa181), TOBN(0x163a3ecf, 0xf509ed1c),
-+     TOBN(0x6aead61f, 0x3c40a491), TOBN(0x158c95fc, 0xdfe8fcaa),
-+     TOBN(0xa3991b6e, 0x13cda46f), TOBN(0x79482415, 0x342faed0),
-+     TOBN(0xf3ba5bde, 0x666b5970), TOBN(0x1d52e6bc, 0xb26ab6dd),
-+     TOBN(0x768ba1e7, 0x8608dd3d), TOBN(0x4930db2a, 0xea076586),
-+     TOBN(0xd9575714, 0xe7dc1afa), TOBN(0x1fc7bf7d, 0xf7c58817),
-+     TOBN(0x6b47accd, 0xd9eee96c), TOBN(0x0ca277fb, 0xe58cec37),
-+     TOBN(0x113fe413, 0xe702c42a), TOBN(0xdd1764ee, 0xc47cbe51),
-+     TOBN(0x041e7cde, 0x7b3ed739), TOBN(0x50cb7459, 0x5ce9e1c0),
-+     TOBN(0x35568513, 0x2925b212), TOBN(0x7cff95c4, 0x001b081c),
-+     TOBN(0x63ee4cbd, 0x8088b454), TOBN(0xdb7f32f7, 0x9a9e0c8a),
-+     TOBN(0xb377d418, 0x6b2447cb), TOBN(0xe3e982aa, 0xd370219b),
-+     TOBN(0x06ccc1e4, 0xc2a2a593), TOBN(0x72c36865, 0x0773f24f),
-+     TOBN(0xa13b4da7, 0x95859423), TOBN(0x8bbf1d33, 0x75040c8f),
-+     TOBN(0x726f0973, 0xda50c991), TOBN(0x48afcd5b, 0x822d6ee2),
-+     TOBN(0xe5fc718b, 0x20fd7771), TOBN(0xb9e8e77d, 0xfd0807a1),
-+     TOBN(0x7f5e0f44, 0x99a7703d), TOBN(0x6972930e, 0x618e36f3),
-+     TOBN(0x2b7c77b8, 0x23807bbe), TOBN(0xe5b82405, 0xcb27ff50),
-+     TOBN(0xba8b8be3, 0xbd379062), TOBN(0xd64b7a1d, 0x2dce4a92),
-+     TOBN(0x040a73c5, 0xb2952e37), TOBN(0x0a9e252e, 0xd438aeca),
-+     TOBN(0xdd43956b, 0xc39d3bcb), TOBN(0x1a31ca00, 0xb32b2d63),
-+     TOBN(0xd67133b8, 0x5c417a18), TOBN(0xd08e4790, 0x2ef442c8),
-+     TOBN(0x98cb1ae9, 0x255c0980), TOBN(0x4bd86381, 0x2b4a739f),
-+     TOBN(0x5a5c31e1, 0x1e4a45a1), TOBN(0x1e5d55fe, 0x9cb0db2f),
-+     TOBN(0x74661b06, 0x8ff5cc29), TOBN(0x026b389f, 0x0eb8a4f4),
-+     TOBN(0x536b21a4, 0x58848c24), TOBN(0x2e5bf8ec, 0x81dc72b0),
-+     TOBN(0x03c187d0, 0xad886aac), TOBN(0x5c16878a, 0xb771b645),
-+     TOBN(0xb07dfc6f, 0xc74045ab), TOBN(0x2c6360bf, 0x7800caed),
-+     TOBN(0x24295bb5, 0xb9c972a3), TOBN(0xc9e6f88e, 0x7c9a6dba),
-+     TOBN(0x90ffbf24, 0x92a79aa6), TOBN(0xde29d50a, 0x41c26ac2),
-+     TOBN(0x9f0af483, 0xd309cbe6), TOBN(0x5b020d8a, 0xe0bced4f),
-+     TOBN(0x606e986d, 0xb38023e3), TOBN(0xad8f2c9d, 0x1abc6933),
-+     TOBN(0x19292e1d, 0xe7400e93), TOBN(0xfe3e18a9, 0x52be5e4d),
-+     TOBN(0xe8e9771d, 0x2e0680bf), TOBN(0x8c5bec98, 0xc54db063),
-+     TOBN(0x2af9662a, 0x74a55d1f), TOBN(0xe3fbf28f, 0x046f66d8),
-+     TOBN(0xa3a72ab4, 0xd4dc4794), TOBN(0x09779f45, 0x5c7c2dd8),
-+     TOBN(0xd893bdaf, 0xc3d19d8d), TOBN(0xd5a75094, 0x57d6a6df),
-+     TOBN(0x8cf8fef9, 0x952e6255), TOBN(0x3da67cfb, 0xda9a8aff),
-+     TOBN(0x4c23f62a, 0x2c160dcd), TOBN(0x34e6c5e3, 0x8f90eaef),
-+     TOBN(0x35865519, 0xa9a65d5a), TOBN(0x07c48aae, 0x8fd38a3d),
-+     TOBN(0xb7e7aeda, 0x50068527), TOBN(0x2c09ef23, 0x1c90936a),
-+     TOBN(0x31ecfeb6, 0xe879324c), TOBN(0xa0871f6b, 0xfb0ec938),
-+     TOBN(0xb1f0fb68, 0xd84d835d), TOBN(0xc90caf39, 0x861dc1e6),
-+     TOBN(0x12e5b046, 0x7594f8d7), TOBN(0x26897ae2, 0x65012b92),
-+     TOBN(0xbcf68a08, 0xa4d6755d), TOBN(0x403ee41c, 0x0991fbda),
-+     TOBN(0x733e343e, 0x3bbf17e8), TOBN(0xd2c7980d, 0x679b3d65),
-+     TOBN(0x33056232, 0xd2e11305), TOBN(0x966be492, 0xf3c07a6f),
-+     TOBN(0x6a8878ff, 0xbb15509d), TOBN(0xff221101, 0x0a9b59a4),
-+     TOBN(0x6c9f564a, 0xabe30129), TOBN(0xc6f2c940, 0x336e64cf),
-+     TOBN(0x0fe75262, 0x8b0c8022), TOBN(0xbe0267e9, 0x6ae8db87),
-+     TOBN(0x22e192f1, 0x93bc042b), TOBN(0xf085b534, 0xb237c458),
-+     TOBN(0xa0d192bd, 0x832c4168), TOBN(0x7a76e9e3, 0xbdf6271d),
-+     TOBN(0x52a882fa, 0xb88911b5), TOBN(0xc85345e4, 0xb4db0eb5),
-+     TOBN(0xa3be02a6, 0x81a7c3ff), TOBN(0x51889c8c, 0xf0ec0469),
-+     TOBN(0x9d031369, 0xa5e829e5), TOBN(0xcbb4c6fc, 0x1607aa41),
-+     TOBN(0x75ac59a6, 0x241d84c1), TOBN(0xc043f2bf, 0x8829e0ee),
-+     TOBN(0x82a38f75, 0x8ea5e185), TOBN(0x8bda40b9, 0xd87cbd9f),
-+     TOBN(0x9e65e75e, 0x2d8fc601), TOBN(0x3d515f74, 0xa35690b3),
-+     TOBN(0x534acf4f, 0xda79e5ac), TOBN(0x68b83b3a, 0x8630215f),
-+     TOBN(0x5c748b2e, 0xd085756e), TOBN(0xb0317258, 0xe5d37cb2),
-+     TOBN(0x6735841a, 0xc5ccc2c4), TOBN(0x7d7dc96b, 0x3d9d5069),
-+     TOBN(0xa147e410, 0xfd1754bd), TOBN(0x65296e94, 0xd399ddd5),
-+     TOBN(0xf6b5b2d0, 0xbc8fa5bc), TOBN(0x8a5ead67, 0x500c277b),
-+     TOBN(0x214625e6, 0xdfa08a5d), TOBN(0x51fdfedc, 0x959cf047),
-+     TOBN(0x6bc9430b, 0x289fca32), TOBN(0xe36ff0cf, 0x9d9bdc3f),
-+     TOBN(0x2fe187cb, 0x58ea0ede), TOBN(0xed66af20, 0x5a900b3f),
-+     TOBN(0x00e0968b, 0x5fa9f4d6), TOBN(0x2d4066ce, 0x37a362e7),
-+     TOBN(0xa99a9748, 0xbd07e772), TOBN(0x710989c0, 0x06a4f1d0),
-+     TOBN(0xd5dedf35, 0xce40cbd8), TOBN(0xab55c5f0, 0x1743293d),
-+     TOBN(0x766f1144, 0x8aa24e2c), TOBN(0x94d874f8, 0x605fbcb4),
-+     TOBN(0xa365f0e8, 0xa518001b), TOBN(0xee605eb6, 0x9d04ef0f),
-+     TOBN(0x5a3915cd, 0xba8d4d25), TOBN(0x44c0e1b8, 0xb5113472),
-+     TOBN(0xcbb024e8, 0x8b6740dc), TOBN(0x89087a53, 0xee1d4f0c),
-+     TOBN(0xa88fa05c, 0x1fc4e372), TOBN(0x8bf395cb, 0xaf8b3af2),
-+     TOBN(0x1e71c9a1, 0xdeb8568b), TOBN(0xa35daea0, 0x80fb3d32),
-+     TOBN(0xe8b6f266, 0x2cf8fb81), TOBN(0x6d51afe8, 0x9490696a),
-+     TOBN(0x81beac6e, 0x51803a19), TOBN(0xe3d24b7f, 0x86219080),
-+     TOBN(0x727cfd9d, 0xdf6f463c), TOBN(0x8c6865ca, 0x72284ee8),
-+     TOBN(0x32c88b7d, 0xb743f4ef), TOBN(0x3793909b, 0xe7d11dce),
-+     TOBN(0xd398f922, 0x2ff2ebe8), TOBN(0x2c70ca44, 0xe5e49796),
-+     TOBN(0xdf4d9929, 0xcb1131b1), TOBN(0x7826f298, 0x25888e79),
-+     TOBN(0x4d3a112c, 0xf1d8740a), TOBN(0x00384cb6, 0x270afa8b),
-+     TOBN(0xcb64125b, 0x3ab48095), TOBN(0x3451c256, 0x62d05106),
-+     TOBN(0xd73d577d, 0xa4955845), TOBN(0x39570c16, 0xbf9f4433),
-+     TOBN(0xd7dfaad3, 0xadecf263), TOBN(0xf1c3d8d1, 0xdc76e102),
-+     TOBN(0x5e774a58, 0x54c6a836), TOBN(0xdad4b672, 0x3e92d47b),
-+     TOBN(0xbe7e990f, 0xf0d796a0), TOBN(0x5fc62478, 0xdf0e8b02),
-+     TOBN(0x8aae8bf4, 0x030c00ad), TOBN(0x3d2db93b, 0x9004ba0f),
-+     TOBN(0xe48c8a79, 0xd85d5ddc), TOBN(0xe907caa7, 0x6bb07f34),
-+     TOBN(0x58db343a, 0xa39eaed5), TOBN(0x0ea6e007, 0xadaf5724),
-+     TOBN(0xe00df169, 0xd23233f3), TOBN(0x3e322796, 0x77cb637f),
-+     TOBN(0x1f897c0e, 0x1da0cf6c), TOBN(0xa651f5d8, 0x31d6bbdd),
-+     TOBN(0xdd61af19, 0x1a230c76), TOBN(0xbd527272, 0xcdaa5e4a),
-+     TOBN(0xca753636, 0xd0abcd7e), TOBN(0x78bdd37c, 0x370bd8dc),
-+     TOBN(0xc23916c2, 0x17cd93fe), TOBN(0x65b97a4d, 0xdadce6e2),
-+     TOBN(0xe04ed4eb, 0x174e42f8), TOBN(0x1491ccaa, 0xbb21480a),
-+     TOBN(0x145a8280, 0x23196332), TOBN(0x3c3862d7, 0x587b479a),
-+     TOBN(0x9f4a88a3, 0x01dcd0ed), TOBN(0x4da2b7ef, 0x3ea12f1f),
-+     TOBN(0xf8e7ae33, 0xb126e48e), TOBN(0x404a0b32, 0xf494e237),
-+     TOBN(0x9beac474, 0xc55acadb), TOBN(0x4ee5cf3b, 0xcbec9fd9),
-+     TOBN(0x336b33b9, 0x7df3c8c3), TOBN(0xbd905fe3, 0xb76808fd),
-+     TOBN(0x8f436981, 0xaa45c16a), TOBN(0x255c5bfa, 0x3dd27b62),
-+     TOBN(0x71965cbf, 0xc3dd9b4d), TOBN(0xce23edbf, 0xfc068a87),
-+     TOBN(0xb78d4725, 0x745b029b), TOBN(0x74610713, 0xcefdd9bd),
-+     TOBN(0x7116f75f, 0x1266bf52), TOBN(0x02046722, 0x18e49bb6),
-+     TOBN(0xdf43df9f, 0x3d6f19e3), TOBN(0xef1bc7d0, 0xe685cb2f),
-+     TOBN(0xcddb27c1, 0x7078c432), TOBN(0xe1961b9c, 0xb77fedb7),
-+     TOBN(0x1edc2f5c, 0xc2290570), TOBN(0x2c3fefca, 0x19cbd886),
-+     TOBN(0xcf880a36, 0xc2af389a), TOBN(0x96c610fd, 0xbda71cea),
-+     TOBN(0xf03977a9, 0x32aa8463), TOBN(0x8eb7763f, 0x8586d90a),
-+     TOBN(0x3f342454, 0x2a296e77), TOBN(0xc8718683, 0x42837a35),
-+     TOBN(0x7dc71090, 0x6a09c731), TOBN(0x54778ffb, 0x51b816db),
-+     TOBN(0x6b33bfec, 0xaf06defd), TOBN(0xfe3c105f, 0x8592b70b),
-+     TOBN(0xf937fda4, 0x61da6114), TOBN(0x3c13e651, 0x4c266ad7),
-+     TOBN(0xe363a829, 0x855938e8), TOBN(0x2eeb5d9e, 0x9de54b72),
-+     TOBN(0xbeb93b0e, 0x20ccfab9), TOBN(0x3dffbb5f, 0x25e61a25),
-+     TOBN(0x7f655e43, 0x1acc093d), TOBN(0x0cb6cc3d, 0x3964ce61),
-+     TOBN(0x6ab283a1, 0xe5e9b460), TOBN(0x55d787c5, 0xa1c7e72d),
-+     TOBN(0x4d2efd47, 0xdeadbf02), TOBN(0x11e80219, 0xac459068),
-+     TOBN(0x810c7626, 0x71f311f0), TOBN(0xfa17ef8d, 0x4ab6ef53),
-+     TOBN(0xaf47fd25, 0x93e43bff), TOBN(0x5cb5ff3f, 0x0be40632),
-+     TOBN(0x54687106, 0x8ee61da3), TOBN(0x7764196e, 0xb08afd0f),
-+     TOBN(0x831ab3ed, 0xf0290a8f), TOBN(0xcae81966, 0xcb47c387),
-+     TOBN(0xaad7dece, 0x184efb4f), TOBN(0xdcfc53b3, 0x4749110e),
-+     TOBN(0x6698f23c, 0x4cb632f9), TOBN(0xc42a1ad6, 0xb91f8067),
-+     TOBN(0xb116a81d, 0x6284180a), TOBN(0xebedf5f8, 0xe901326f),
-+     TOBN(0xf2274c9f, 0x97e3e044), TOBN(0x42018520, 0x11d09fc9),
-+     TOBN(0x56a65f17, 0xd18e6e23), TOBN(0x2ea61e2a, 0x352b683c),
-+     TOBN(0x27d291bc, 0x575eaa94), TOBN(0x9e7bc721, 0xb8ff522d),
-+     TOBN(0x5f7268bf, 0xa7f04d6f), TOBN(0x5868c73f, 0xaba41748),
-+     TOBN(0x9f85c2db, 0x7be0eead), TOBN(0x511e7842, 0xff719135),
-+     TOBN(0x5a06b1e9, 0xc5ea90d7), TOBN(0x0c19e283, 0x26fab631),
-+     TOBN(0x8af8f0cf, 0xe9206c55), TOBN(0x89389cb4, 0x3553c06a),
-+     TOBN(0x39dbed97, 0xf65f8004), TOBN(0x0621b037, 0xc508991d),
-+     TOBN(0x1c52e635, 0x96e78cc4), TOBN(0x5385c8b2, 0x0c06b4a8),
-+     TOBN(0xd84ddfdb, 0xb0e87d03), TOBN(0xc49dfb66, 0x934bafad),
-+     TOBN(0x7071e170, 0x59f70772), TOBN(0x3a073a84, 0x3a1db56b),
-+     TOBN(0x03494903, 0x3b8af190), TOBN(0x7d882de3, 0xd32920f0),
-+     TOBN(0x91633f0a, 0xb2cf8940), TOBN(0x72b0b178, 0x6f948f51),
-+     TOBN(0x2d28dc30, 0x782653c8), TOBN(0x88829849, 0xdb903a05),
-+     TOBN(0xb8095d0c, 0x6a19d2bb), TOBN(0x4b9e7f0c, 0x86f782cb),
-+     TOBN(0x7af73988, 0x2d907064), TOBN(0xd12be0fe, 0x8b32643c),
-+     TOBN(0x358ed23d, 0x0e165dc3), TOBN(0x3d47ce62, 0x4e2378ce),
-+     TOBN(0x7e2bb0b9, 0xfeb8a087), TOBN(0x3246e8ae, 0xe29e10b9),
-+     TOBN(0x459f4ec7, 0x03ce2b4d), TOBN(0xe9b4ca1b, 0xbbc077cf),
-+     TOBN(0x2613b4f2, 0x0e9940c1), TOBN(0xfc598bb9, 0x047d1eb1),
-+     TOBN(0x9744c62b, 0x45036099), TOBN(0xa9dee742, 0x167c65d8),
-+     TOBN(0x0c511525, 0xdabe1943), TOBN(0xda110554, 0x93c6c624),
-+     TOBN(0xae00a52c, 0x651a3be2), TOBN(0xcda5111d, 0x884449a6),
-+     TOBN(0x063c06f4, 0xff33bed1), TOBN(0x73baaf9a, 0x0d3d76b4),
-+     TOBN(0x52fb0c9d, 0x7fc63668), TOBN(0x6886c9dd, 0x0c039cde),
-+     TOBN(0x602bd599, 0x55b22351), TOBN(0xb00cab02, 0x360c7c13),
-+     TOBN(0x8cb616bc, 0x81b69442), TOBN(0x41486700, 0xb55c3cee),
-+     TOBN(0x71093281, 0xf49ba278), TOBN(0xad956d9c, 0x64a50710),
-+     TOBN(0x9561f28b, 0x638a7e81), TOBN(0x54155cdf, 0x5980ddc3),
-+     TOBN(0xb2db4a96, 0xd26f247a), TOBN(0x9d774e4e, 0x4787d100),
-+     TOBN(0x1a9e6e2e, 0x078637d2), TOBN(0x1c363e2d, 0x5e0ae06a),
-+     TOBN(0x7493483e, 0xe9cfa354), TOBN(0x76843cb3, 0x7f74b98d),
-+     TOBN(0xbaca6591, 0xd4b66947), TOBN(0xb452ce98, 0x04460a8c),
-+     TOBN(0x6830d246, 0x43768f55), TOBN(0xf4197ed8, 0x7dff12df),
-+     TOBN(0x6521b472, 0x400dd0f7), TOBN(0x59f5ca8f, 0x4b1e7093),
-+     TOBN(0x6feff11b, 0x080338ae), TOBN(0x0ada31f6, 0xa29ca3c6),
-+     TOBN(0x24794eb6, 0x94a2c215), TOBN(0xd83a43ab, 0x05a57ab4),
-+     TOBN(0x264a543a, 0x2a6f89fe), TOBN(0x2c2a3868, 0xdd5ec7c2),
-+     TOBN(0xd3373940, 0x8439d9b2), TOBN(0x715ea672, 0x0acd1f11),
-+     TOBN(0x42c1d235, 0xe7e6cc19), TOBN(0x81ce6e96, 0xb990585c),
-+     TOBN(0x04e5dfe0, 0xd809c7bd), TOBN(0xd7b2580c, 0x8f1050ab),
-+     TOBN(0x6d91ad78, 0xd8a4176f), TOBN(0x0af556ee, 0x4e2e897c),
-+     TOBN(0x162a8b73, 0x921de0ac), TOBN(0x52ac9c22, 0x7ea78400),
-+     TOBN(0xee2a4eea, 0xefce2174), TOBN(0xbe61844e, 0x6d637f79),
-+     TOBN(0x0491f1bc, 0x789a283b), TOBN(0x72d3ac3d, 0x880836f4),
-+     TOBN(0xaa1c5ea3, 0x88e5402d), TOBN(0x1b192421, 0xd5cc473d),
-+     TOBN(0x5c0b9998, 0x9dc84cac), TOBN(0xb0a8482d, 0x9c6e75b8),
-+     TOBN(0x639961d0, 0x3a191ce2), TOBN(0xda3bc865, 0x6d837930),
-+     TOBN(0xca990653, 0x056e6f8f), TOBN(0x84861c41, 0x64d133a7),
-+     TOBN(0x8b403276, 0x746abe40), TOBN(0xb7b4d51a, 0xebf8e303),
-+     TOBN(0x05b43211, 0x220a255d), TOBN(0xc997152c, 0x02419e6e),
-+     TOBN(0x76ff47b6, 0x630c2fea), TOBN(0x50518677, 0x281fdade),
-+     TOBN(0x3283b8ba, 0xcf902b0b), TOBN(0x8d4b4eb5, 0x37db303b),
-+     TOBN(0xcc89f42d, 0x755011bc), TOBN(0xb43d74bb, 0xdd09d19b),
-+     TOBN(0x65746bc9, 0x8adba350), TOBN(0x364eaf8c, 0xb51c1927),
-+     TOBN(0x13c76596, 0x10ad72ec), TOBN(0x30045121, 0xf8d40c20),
-+     TOBN(0x6d2d99b7, 0xea7b979b), TOBN(0xcd78cd74, 0xe6fb3bcd),
-+     TOBN(0x11e45a9e, 0x86cffbfe), TOBN(0x78a61cf4, 0x637024f6),
-+     TOBN(0xd06bc872, 0x3d502295), TOBN(0xf1376854, 0x458cb288),
-+     TOBN(0xb9db26a1, 0x342f8586), TOBN(0xf33effcf, 0x4beee09e),
-+     TOBN(0xd7e0c4cd, 0xb30cfb3a), TOBN(0x6d09b8c1, 0x6c9db4c8),
-+     TOBN(0x40ba1a42, 0x07c8d9df), TOBN(0x6fd495f7, 0x1c52c66d),
-+     TOBN(0xfb0e169f, 0x275264da), TOBN(0x80c2b746, 0xe57d8362),
-+     TOBN(0xedd987f7, 0x49ad7222), TOBN(0xfdc229af, 0x4398ec7b),}
-+    ,
-+    {TOBN(0xb0d1ed84, 0x52666a58), TOBN(0x4bcb6e00, 0xe6a9c3c2),
-+     TOBN(0x3c57411c, 0x26906408), TOBN(0xcfc20755, 0x13556400),
-+     TOBN(0xa08b1c50, 0x5294dba3), TOBN(0xa30ba286, 0x8b7dd31e),
-+     TOBN(0xd70ba90e, 0x991eca74), TOBN(0x094e142c, 0xe762c2b9),
-+     TOBN(0xb81d783e, 0x979f3925), TOBN(0x1efd130a, 0xaf4c89a7),
-+     TOBN(0x525c2144, 0xfd1bf7fa), TOBN(0x4b296904, 0x1b265a9e),
-+     TOBN(0xed8e9634, 0xb9db65b6), TOBN(0x35c82e32, 0x03599d8a),
-+     TOBN(0xdaa7a54f, 0x403563f3), TOBN(0x9df088ad, 0x022c38ab),
-+     TOBN(0xe5cfb066, 0xbb3fd30a), TOBN(0x429169da, 0xeff0354e),
-+     TOBN(0x809cf852, 0x3524e36c), TOBN(0x136f4fb3, 0x0155be1d),
-+     TOBN(0x4826af01, 0x1fbba712), TOBN(0x6ef0f0b4, 0x506ba1a1),
-+     TOBN(0xd9928b31, 0x77aea73e), TOBN(0xe2bf6af2, 0x5eaa244e),
-+     TOBN(0x8d084f12, 0x4237b64b), TOBN(0x688ebe99, 0xe3ecfd07),
-+     TOBN(0x57b8a70c, 0xf6845dd8), TOBN(0x808fc59c, 0x5da4a325),
-+     TOBN(0xa9032b2b, 0xa3585862), TOBN(0xb66825d5, 0xedf29386),
-+     TOBN(0xb5a5a8db, 0x431ec29b), TOBN(0xbb143a98, 0x3a1e8dc8),
-+     TOBN(0x35ee94ce, 0x12ae381b), TOBN(0x3a7f176c, 0x86ccda90),
-+     TOBN(0xc63a657e, 0x4606eaca), TOBN(0x9ae5a380, 0x43cd04df),
-+     TOBN(0x9bec8d15, 0xed251b46), TOBN(0x1f5d6d30, 0xcaca5e64),
-+     TOBN(0x347b3b35, 0x9ff20f07), TOBN(0x4d65f034, 0xf7e4b286),
-+     TOBN(0x9e93ba24, 0xf111661e), TOBN(0xedced484, 0xb105eb04),
-+     TOBN(0x96dc9ba1, 0xf424b578), TOBN(0xbf8f66b7, 0xe83e9069),
-+     TOBN(0x872d4df4, 0xd7ed8216), TOBN(0xbf07f377, 0x8e2cbecf),
-+     TOBN(0x4281d899, 0x98e73754), TOBN(0xfec85fbb, 0x8aab8708),
-+     TOBN(0x9a3c0dee, 0xa5ba5b0b), TOBN(0xe6a116ce, 0x42d05299),
-+     TOBN(0xae9775fe, 0xe9b02d42), TOBN(0x72b05200, 0xa1545cb6),
-+     TOBN(0xbc506f7d, 0x31a3b4ea), TOBN(0xe5893078, 0x8bbd9b32),
-+     TOBN(0xc8bc5f37, 0xe4b12a97), TOBN(0x6b000c06, 0x4a73b671),
-+     TOBN(0x13b5bf22, 0x765fa7d0), TOBN(0x59805bf0, 0x1d6a5370),
-+     TOBN(0x67a5e29d, 0x4280db98), TOBN(0x4f53916f, 0x776b1ce3),
-+     TOBN(0x714ff61f, 0x33ddf626), TOBN(0x4206238e, 0xa085d103),
-+     TOBN(0x1c50d4b7, 0xe5809ee3), TOBN(0x999f450d, 0x85f8eb1d),
-+     TOBN(0x658a6051, 0xe4c79e9b), TOBN(0x1394cb73, 0xc66a9fea),
-+     TOBN(0x27f31ed5, 0xc6be7b23), TOBN(0xf4c88f36, 0x5aa6f8fe),
-+     TOBN(0x0fb0721f, 0x4aaa499e), TOBN(0x68b3a7d5, 0xe3fb2a6b),
-+     TOBN(0xa788097d, 0x3a92851d), TOBN(0x060e7f8a, 0xe96f4913),
-+     TOBN(0x82eebe73, 0x1a3a93bc), TOBN(0x42bbf465, 0xa21adc1a),
-+     TOBN(0xc10b6fa4, 0xef030efd), TOBN(0x247aa4c7, 0x87b097bb),
-+     TOBN(0x8b8dc632, 0xf60c77da), TOBN(0x6ffbc26a, 0xc223523e),
-+     TOBN(0xa4f6ff11, 0x344579cf), TOBN(0x5825653c, 0x980250f6),
-+     TOBN(0xb2dd097e, 0xbc1aa2b9), TOBN(0x07889393, 0x37a0333a),
-+     TOBN(0x1cf55e71, 0x37a0db38), TOBN(0x2648487f, 0x792c1613),
-+     TOBN(0xdad01336, 0x3fcef261), TOBN(0x6239c81d, 0x0eabf129),
-+     TOBN(0x8ee761de, 0x9d276be2), TOBN(0x406a7a34, 0x1eda6ad3),
-+     TOBN(0x4bf367ba, 0x4a493b31), TOBN(0x54f20a52, 0x9bf7f026),
-+     TOBN(0xb696e062, 0x9795914b), TOBN(0xcddab96d, 0x8bf236ac),
-+     TOBN(0x4ff2c70a, 0xed25ea13), TOBN(0xfa1d09eb, 0x81cbbbe7),
-+     TOBN(0x88fc8c87, 0x468544c5), TOBN(0x847a670d, 0x696b3317),
-+     TOBN(0xf133421e, 0x64bcb626), TOBN(0xaea638c8, 0x26dee0b5),
-+     TOBN(0xd6e7680b, 0xb310346c), TOBN(0xe06f4097, 0xd5d4ced3),
-+     TOBN(0x09961452, 0x7512a30b), TOBN(0xf3d867fd, 0xe589a59a),
-+     TOBN(0x2e73254f, 0x52d0c180), TOBN(0x9063d8a3, 0x333c74ac),
-+     TOBN(0xeda6c595, 0xd314e7bc), TOBN(0x2ee7464b, 0x467899ed),
-+     TOBN(0x1cef423c, 0x0a1ed5d3), TOBN(0x217e76ea, 0x69cc7613),
-+     TOBN(0x27ccce1f, 0xe7cda917), TOBN(0x12d8016b, 0x8a893f16),
-+     TOBN(0xbcd6de84, 0x9fc74f6b), TOBN(0xfa5817e2, 0xf3144e61),
-+     TOBN(0x1f354164, 0x0821ee4c), TOBN(0x1583eab4, 0x0bc61992),
-+     TOBN(0x7490caf6, 0x1d72879f), TOBN(0x998ad9f3, 0xf76ae7b2),
-+     TOBN(0x1e181950, 0xa41157f7), TOBN(0xa9d7e1e6, 0xe8da3a7e),
-+     TOBN(0x963784eb, 0x8426b95f), TOBN(0x0ee4ed6e, 0x542e2a10),
-+     TOBN(0xb79d4cc5, 0xac751e7b), TOBN(0x93f96472, 0xfd4211bd),
-+     TOBN(0x8c72d3d2, 0xc8de4fc6), TOBN(0x7b69cbf5, 0xdf44f064),
-+     TOBN(0x3da90ca2, 0xf4bf94e1), TOBN(0x1a5325f8, 0xf12894e2),
-+     TOBN(0x0a437f6c, 0x7917d60b), TOBN(0x9be70486, 0x96c9cb5d),
-+     TOBN(0xb4d880bf, 0xe1dc5c05), TOBN(0xd738adda, 0xeebeeb57),
-+     TOBN(0x6f0119d3, 0xdf0fe6a3), TOBN(0x5c686e55, 0x66eaaf5a),
-+     TOBN(0x9cb10b50, 0xdfd0b7ec), TOBN(0xbdd0264b, 0x6a497c21),
-+     TOBN(0xfc093514, 0x8c546c96), TOBN(0x58a947fa, 0x79dbf42a),
-+     TOBN(0xc0b48d4e, 0x49ccd6d7), TOBN(0xff8fb02c, 0x88bd5580),
-+     TOBN(0xc75235e9, 0x07d473b2), TOBN(0x4fab1ac5, 0xa2188af3),
-+     TOBN(0x030fa3bc, 0x97576ec0), TOBN(0xe8c946e8, 0x0b7e7d2f),
-+     TOBN(0x40a5c9cc, 0x70305600), TOBN(0x6d8260a9, 0xc8b013b4),
-+     TOBN(0x0368304f, 0x70bba85c), TOBN(0xad090da1, 0xa4a0d311),
-+     TOBN(0x7170e870, 0x2415eec1), TOBN(0xbfba35fe, 0x8461ea47),
-+     TOBN(0x6279019a, 0xc1e91938), TOBN(0xa47638f3, 0x1afc415f),
-+     TOBN(0x36c65cbb, 0xbcba0e0f), TOBN(0x02160efb, 0x034e2c48),
-+     TOBN(0xe6c51073, 0x615cd9e4), TOBN(0x498ec047, 0xf1243c06),
-+     TOBN(0x3e5a8809, 0xb17b3d8c), TOBN(0x5cd99e61, 0x0cc565f1),
-+     TOBN(0x81e312df, 0x7851dafe), TOBN(0xf156f5ba, 0xa79061e2),
-+     TOBN(0x80d62b71, 0x880c590e), TOBN(0xbec9746f, 0x0a39faa1),
-+     TOBN(0x1d98a9c1, 0xc8ed1f7a), TOBN(0x09e43bb5, 0xa81d5ff2),
-+     TOBN(0xd5f00f68, 0x0da0794a), TOBN(0x412050d9, 0x661aa836),
-+     TOBN(0xa89f7c4e, 0x90747e40), TOBN(0x6dc05ebb, 0xb62a3686),
-+     TOBN(0xdf4de847, 0x308e3353), TOBN(0x53868fbb, 0x9fb53bb9),
-+     TOBN(0x2b09d2c3, 0xcfdcf7dd), TOBN(0x41a9fce3, 0x723fcab4),
-+     TOBN(0x73d905f7, 0x07f57ca3), TOBN(0x080f9fb1, 0xac8e1555),
-+     TOBN(0x7c088e84, 0x9ba7a531), TOBN(0x07d35586, 0xed9a147f),
-+     TOBN(0x602846ab, 0xaf48c336), TOBN(0x7320fd32, 0x0ccf0e79),
-+     TOBN(0xaa780798, 0xb18bd1ff), TOBN(0x52c2e300, 0xafdd2905),
-+     TOBN(0xf27ea3d6, 0x434267cd), TOBN(0x8b96d16d, 0x15605b5f),
-+     TOBN(0x7bb31049, 0x4b45706b), TOBN(0xe7f58b8e, 0x743d25f8),
-+     TOBN(0xe9b5e45b, 0x87f30076), TOBN(0xd19448d6, 0x5d053d5a),
-+     TOBN(0x1ecc8cb9, 0xd3210a04), TOBN(0x6bc7d463, 0xdafb5269),
-+     TOBN(0x3e59b10a, 0x67c3489f), TOBN(0x1769788c, 0x65641e1b),
-+     TOBN(0x8a53b82d, 0xbd6cb838), TOBN(0x7066d6e6, 0x236d5f22),
-+     TOBN(0x03aa1c61, 0x6908536e), TOBN(0xc971da0d, 0x66ae9809),
-+     TOBN(0x01b3a86b, 0xc49a2fac), TOBN(0x3b8420c0, 0x3092e77a),
-+     TOBN(0x02057300, 0x7d6fb556), TOBN(0x6941b2a1, 0xbff40a87),
-+     TOBN(0x140b6308, 0x0658ff2a), TOBN(0x87804363, 0x3424ab36),
-+     TOBN(0x0253bd51, 0x5751e299), TOBN(0xc75bcd76, 0x449c3e3a),
-+     TOBN(0x92eb4090, 0x7f8f875d), TOBN(0x9c9d754e, 0x56c26bbf),
-+     TOBN(0x158cea61, 0x8110bbe7), TOBN(0x62a6b802, 0x745f91ea),
-+     TOBN(0xa79c41aa, 0xc6e7394b), TOBN(0x445b6a83, 0xad57ef10),
-+     TOBN(0x0c5277eb, 0x6ea6f40c), TOBN(0x319fe96b, 0x88633365),
-+     TOBN(0x0b0fc61f, 0x385f63cb), TOBN(0x41250c84, 0x22bdd127),
-+     TOBN(0x67d153f1, 0x09e942c2), TOBN(0x60920d08, 0xc021ad5d),
-+     TOBN(0x229f5746, 0x724d81a5), TOBN(0xb7ffb892, 0x5bba3299),
-+     TOBN(0x518c51a1, 0xde413032), TOBN(0x2a9bfe77, 0x3c2fd94c),
-+     TOBN(0xcbcde239, 0x3191f4fd), TOBN(0x43093e16, 0xd3d6ada1),
-+     TOBN(0x184579f3, 0x58769606), TOBN(0x2c94a8b3, 0xd236625c),
-+     TOBN(0x6922b9c0, 0x5c437d8e), TOBN(0x3d4ae423, 0xd8d9f3c8),
-+     TOBN(0xf72c31c1, 0x2e7090a2), TOBN(0x4ac3f5f3, 0xd76a55bd),
-+     TOBN(0x342508fc, 0x6b6af991), TOBN(0x0d527100, 0x1b5cebbd),
-+     TOBN(0xb84740d0, 0xdd440dd7), TOBN(0x748ef841, 0x780162fd),
-+     TOBN(0xa8dbfe0e, 0xdfc6fafb), TOBN(0xeadfdf05, 0xf7300f27),
-+     TOBN(0x7d06555f, 0xfeba4ec9), TOBN(0x12c56f83, 0x9e25fa97),
-+     TOBN(0x77f84203, 0xd39b8c34), TOBN(0xed8b1be6, 0x3125eddb),
-+     TOBN(0x5bbf2441, 0xf6e39dc5), TOBN(0xb00f6ee6, 0x6a5d678a),
-+     TOBN(0xba456ecf, 0x57d0ea99), TOBN(0xdcae0f58, 0x17e06c43),
-+     TOBN(0x01643de4, 0x0f5b4baa), TOBN(0x2c324341, 0xd161b9be),
-+     TOBN(0x80177f55, 0xe126d468), TOBN(0xed325f1f, 0x76748e09),
-+     TOBN(0x6116004a, 0xcfa9bdc2), TOBN(0x2d8607e6, 0x3a9fb468),
-+     TOBN(0x0e573e27, 0x6009d660), TOBN(0x3a525d2e, 0x8d10c5a1),
-+     TOBN(0xd26cb45c, 0x3b9009a0), TOBN(0xb6b0cdc0, 0xde9d7448),
-+     TOBN(0x949c9976, 0xe1337c26), TOBN(0x6faadebd, 0xd73d68e5),
-+     TOBN(0x9e158614, 0xf1b768d9), TOBN(0x22dfa557, 0x9cc4f069),
-+     TOBN(0xccd6da17, 0xbe93c6d6), TOBN(0x24866c61, 0xa504f5b9),
-+     TOBN(0x2121353c, 0x8d694da1), TOBN(0x1c6ca580, 0x0140b8c6),
-+     TOBN(0xc245ad8c, 0xe964021e), TOBN(0xb83bffba, 0x032b82b3),
-+     TOBN(0xfaa220c6, 0x47ef9898), TOBN(0x7e8d3ac6, 0x982c948a),
-+     TOBN(0x1faa2091, 0xbc2d124a), TOBN(0xbd54c3dd, 0x05b15ff4),
-+     TOBN(0x386bf3ab, 0xc87c6fb7), TOBN(0xfb2b0563, 0xfdeb6f66),
-+     TOBN(0x4e77c557, 0x5b45afb4), TOBN(0xe9ded649, 0xefb8912d),
-+     TOBN(0x7ec9bbf5, 0x42f6e557), TOBN(0x2570dfff, 0x62671f00),
-+     TOBN(0x2b3bfb78, 0x88e084bd), TOBN(0xa024b238, 0xf37fe5b4),
-+     TOBN(0x44e7dc04, 0x95649aee), TOBN(0x498ca255, 0x5e7ec1d8),
-+     TOBN(0x3bc766ea, 0xaaa07e86), TOBN(0x0db6facb, 0xf3608586),
-+     TOBN(0xbadd2549, 0xbdc259c8), TOBN(0x95af3c6e, 0x041c649f),
-+     TOBN(0xb36a928c, 0x02e30afb), TOBN(0x9b5356ad, 0x008a88b8),
-+     TOBN(0x4b67a5f1, 0xcf1d9e9d), TOBN(0xc6542e47, 0xa5d8d8ce),
-+     TOBN(0x73061fe8, 0x7adfb6cc), TOBN(0xcc826fd3, 0x98678141),
-+     TOBN(0x00e758b1, 0x3c80515a), TOBN(0x6afe3247, 0x41485083),
-+     TOBN(0x0fcb08b9, 0xb6ae8a75), TOBN(0xb8cf388d, 0x4acf51e1),
-+     TOBN(0x344a5560, 0x6961b9d6), TOBN(0x1a6778b8, 0x6a97fd0c),
-+     TOBN(0xd840fdc1, 0xecc4c7e3), TOBN(0xde9fe47d, 0x16db68cc),
-+     TOBN(0xe95f89de, 0xa3e216aa), TOBN(0x84f1a6a4, 0x9594a8be),
-+     TOBN(0x7ddc7d72, 0x5a7b162b), TOBN(0xc5cfda19, 0xadc817a3),
-+     TOBN(0x80a5d350, 0x78b58d46), TOBN(0x93365b13, 0x82978f19),
-+     TOBN(0x2e44d225, 0x26a1fc90), TOBN(0x0d6d10d2, 0x4d70705d),
-+     TOBN(0xd94b6b10, 0xd70c45f4), TOBN(0x0f201022, 0xb216c079),
-+     TOBN(0xcec966c5, 0x658fde41), TOBN(0xa8d2bc7d, 0x7e27601d),
-+     TOBN(0xbfcce3e1, 0xff230be7), TOBN(0x3394ff6b, 0x0033ffb5),
-+     TOBN(0xd890c509, 0x8132c9af), TOBN(0xaac4b0eb, 0x361e7868),
-+     TOBN(0x5194ded3, 0xe82d15aa), TOBN(0x4550bd2e, 0x23ae6b7d),
-+     TOBN(0x3fda318e, 0xea5399d4), TOBN(0xd989bffa, 0x91638b80),
-+     TOBN(0x5ea124d0, 0xa14aa12d), TOBN(0x1fb1b899, 0x3667b944),
-+     TOBN(0x95ec7969, 0x44c44d6a), TOBN(0x91df144a, 0x57e86137),
-+     TOBN(0x915fd620, 0x73adac44), TOBN(0x8f01732d, 0x59a83801),
-+     TOBN(0xec579d25, 0x3aa0a633), TOBN(0x06de5e7c, 0xc9d6d59c),
-+     TOBN(0xc132f958, 0xb1ef8010), TOBN(0x29476f96, 0xe65c1a02),
-+     TOBN(0x336a77c0, 0xd34c3565), TOBN(0xef1105b2, 0x1b9f1e9e),
-+     TOBN(0x63e6d08b, 0xf9e08002), TOBN(0x9aff2f21, 0xc613809e),
-+     TOBN(0xb5754f85, 0x3a80e75d), TOBN(0xde71853e, 0x6bbda681),
-+     TOBN(0x86f041df, 0x8197fd7a), TOBN(0x8b332e08, 0x127817fa),
-+     TOBN(0x05d99be8, 0xb9c20cda), TOBN(0x89f7aad5, 0xd5cd0c98),
-+     TOBN(0x7ef936fe, 0x5bb94183), TOBN(0x92ca0753, 0xb05cd7f2),
-+     TOBN(0x9d65db11, 0x74a1e035), TOBN(0x02628cc8, 0x13eaea92),
-+     TOBN(0xf2d9e242, 0x49e4fbf2), TOBN(0x94fdfd9b, 0xe384f8b7),
-+     TOBN(0x65f56054, 0x63428c6b), TOBN(0x2f7205b2, 0x90b409a5),
-+     TOBN(0xf778bb78, 0xff45ae11), TOBN(0xa13045be, 0xc5ee53b2),
-+     TOBN(0xe00a14ff, 0x03ef77fe), TOBN(0x689cd59f, 0xffef8bef),
-+     TOBN(0x3578f0ed, 0x1e9ade22), TOBN(0xe99f3ec0, 0x6268b6a8),
-+     TOBN(0xa2057d91, 0xea1b3c3e), TOBN(0x2d1a7053, 0xb8823a4a),
-+     TOBN(0xabbb336a, 0x2cca451e), TOBN(0xcd2466e3, 0x2218bb5d),
-+     TOBN(0x3ac1f42f, 0xc8cb762d), TOBN(0x7e312aae, 0x7690211f),
-+     TOBN(0xebb9bd73, 0x45d07450), TOBN(0x207c4b82, 0x46c2213f),
-+     TOBN(0x99d425c1, 0x375913ec), TOBN(0x94e45e96, 0x67908220),
-+     TOBN(0xc08f3087, 0xcd67dbf6), TOBN(0xa5670fbe, 0xc0887056),
-+     TOBN(0x6717b64a, 0x66f5b8fc), TOBN(0xd5a56aea, 0x786fec28),
-+     TOBN(0xa8c3f55f, 0xc0ff4952), TOBN(0xa77fefae, 0x457ac49b),
-+     TOBN(0x29882d7c, 0x98379d44), TOBN(0xd000bdfb, 0x509edc8a),
-+     TOBN(0xc6f95979, 0xe66fe464), TOBN(0x504a6115, 0xfa61bde0),
-+     TOBN(0x56b3b871, 0xeffea31a), TOBN(0x2d3de26d, 0xf0c21a54),
-+     TOBN(0x21dbff31, 0x834753bf), TOBN(0xe67ecf49, 0x69269d86),
-+     TOBN(0x7a176952, 0x151fe690), TOBN(0x03515804, 0x7f2adb5f),
-+     TOBN(0xee794b15, 0xd1b62a8d), TOBN(0xf004ceec, 0xaae454e6),
-+     TOBN(0x0897ea7c, 0xf0386fac), TOBN(0x3b62ff12, 0xd1fca751),
-+     TOBN(0x154181df, 0x1b7a04ec), TOBN(0x2008e04a, 0xfb5847ec),
-+     TOBN(0xd147148e, 0x41dbd772), TOBN(0x2b419f73, 0x22942654),
-+     TOBN(0x669f30d3, 0xe9c544f7), TOBN(0x52a2c223, 0xc8540149),
-+     TOBN(0x5da9ee14, 0x634dfb02), TOBN(0x5f074ff0, 0xf47869f3),
-+     TOBN(0x74ee878d, 0xa3933acc), TOBN(0xe6510651, 0x4fe35ed1),
-+     TOBN(0xb3eb9482, 0xf1012e7a), TOBN(0x51013cc0, 0xa8a566ae),
-+     TOBN(0xdd5e9243, 0x47c00d3b), TOBN(0x7fde089d, 0x946bb0e5),
-+     TOBN(0x030754fe, 0xc731b4b3), TOBN(0x12a136a4, 0x99fda062),
-+     TOBN(0x7c1064b8, 0x5a1a35bc), TOBN(0xbf1f5763, 0x446c84ef),
-+     TOBN(0xed29a56d, 0xa16d4b34), TOBN(0x7fba9d09, 0xdca21c4f),
-+     TOBN(0x66d7ac00, 0x6d8de486), TOBN(0x60061987, 0x73a2a5e1),
-+     TOBN(0x8b400f86, 0x9da28ff0), TOBN(0x3133f708, 0x43c4599c),
-+     TOBN(0x9911c9b8, 0xee28cb0d), TOBN(0xcd7e2874, 0x8e0af61d),
-+     TOBN(0x5a85f0f2, 0x72ed91fc), TOBN(0x85214f31, 0x9cd4a373),
-+     TOBN(0x881fe5be, 0x1925253c), TOBN(0xd8dc98e0, 0x91e8bc76),
-+     TOBN(0x7120affe, 0x585cc3a2), TOBN(0x724952ed, 0x735bf97a),
-+     TOBN(0x5581e7dc, 0x3eb34581), TOBN(0x5cbff4f2, 0xe52ee57d),
-+     TOBN(0x8d320a0e, 0x87d8cc7b), TOBN(0x9beaa7f3, 0xf1d280d0),
-+     TOBN(0x7a0b9571, 0x9beec704), TOBN(0x9126332e, 0x5b7f0057),
-+     TOBN(0x01fbc1b4, 0x8ed3bd6d), TOBN(0x35bb2c12, 0xd945eb24),
-+     TOBN(0x6404694e, 0x9a8ae255), TOBN(0xb6092eec, 0x8d6abfb3),
-+     TOBN(0x4d76143f, 0xcc058865), TOBN(0x7b0a5af2, 0x6e249922),
-+     TOBN(0x8aef9440, 0x6a50d353), TOBN(0xe11e4bcc, 0x64f0e07a),
-+     TOBN(0x4472993a, 0xa14a90fa), TOBN(0x7706e20c, 0xba0c51d4),
-+     TOBN(0xf403292f, 0x1532672d), TOBN(0x52573bfa, 0x21829382),
-+     TOBN(0x6a7bb6a9, 0x3b5bdb83), TOBN(0x08da65c0, 0xa4a72318),
-+     TOBN(0xc58d22aa, 0x63eb065f), TOBN(0x1717596c, 0x1b15d685),
-+     TOBN(0x112df0d0, 0xb266d88b), TOBN(0xf688ae97, 0x5941945a),
-+     TOBN(0x487386e3, 0x7c292cac), TOBN(0x42f3b50d, 0x57d6985c),
-+     TOBN(0x6da4f998, 0x6a90fc34), TOBN(0xc8f257d3, 0x65ca8a8d),
-+     TOBN(0xc2feabca, 0x6951f762), TOBN(0xe1bc81d0, 0x74c323ac),
-+     TOBN(0x1bc68f67, 0x251a2a12), TOBN(0x10d86587, 0xbe8a70dc),
-+     TOBN(0xd648af7f, 0xf0f84d2e), TOBN(0xf0aa9ebc, 0x6a43ac92),
-+     TOBN(0x69e3be04, 0x27596893), TOBN(0xb6bb02a6, 0x45bf452b),
-+     TOBN(0x0875c11a, 0xf4c698c8), TOBN(0x6652b5c7, 0xbece3794),
-+     TOBN(0x7b3755fd, 0x4f5c0499), TOBN(0x6ea16558, 0xb5532b38),
-+     TOBN(0xd1c69889, 0xa2e96ef7), TOBN(0x9c773c3a, 0x61ed8f48),
-+     TOBN(0x2b653a40, 0x9b323abc), TOBN(0xe26605e1, 0xf0e1d791),
-+     TOBN(0x45d41064, 0x4a87157a), TOBN(0x8f9a78b7, 0xcbbce616),
-+     TOBN(0xcf1e44aa, 0xc407eddd), TOBN(0x81ddd1d8, 0xa35b964f),
-+     TOBN(0x473e339e, 0xfd083999), TOBN(0x6c94bdde, 0x8e796802),
-+     TOBN(0x5a304ada, 0x8545d185), TOBN(0x82ae44ea, 0x738bb8cb),
-+     TOBN(0x628a35e3, 0xdf87e10e), TOBN(0xd3624f3d, 0xa15b9fe3),
-+     TOBN(0xcc44209b, 0x14be4254), TOBN(0x7d0efcbc, 0xbdbc2ea5),
-+     TOBN(0x1f603362, 0x04c37bbe), TOBN(0x21f363f5, 0x56a5852c),
-+     TOBN(0xa1503d1c, 0xa8501550), TOBN(0x2251e0e1, 0xd8ab10bb),
-+     TOBN(0xde129c96, 0x6961c51c), TOBN(0x1f7246a4, 0x81910f68),
-+     TOBN(0x2eb744ee, 0x5f2591f2), TOBN(0x3c47d33f, 0x5e627157),
-+     TOBN(0x4d6d62c9, 0x22f3bd68), TOBN(0x6120a64b, 0xcb8df856),
-+     TOBN(0x3a9ac6c0, 0x7b5d07df), TOBN(0xa92b9558, 0x7ef39783),
-+     TOBN(0xe128a134, 0xab3a9b4f), TOBN(0x41c18807, 0xb1252f05),
-+     TOBN(0xfc7ed089, 0x80ba9b1c), TOBN(0xac8dc6de, 0xc532a9dd),
-+     TOBN(0xbf829cef, 0x55246809), TOBN(0x101b784f, 0x5b4ee80f),
-+     TOBN(0xc09945bb, 0xb6f11603), TOBN(0x57b09dbe, 0x41d2801e),
-+     TOBN(0xfba5202f, 0xa97534a8), TOBN(0x7fd8ae5f, 0xc17b9614),
-+     TOBN(0xa50ba666, 0x78308435), TOBN(0x9572f77c, 0xd3868c4d),
-+     TOBN(0x0cef7bfd, 0x2dd7aab0), TOBN(0xe7958e08, 0x2c7c79ff),
-+     TOBN(0x81262e42, 0x25346689), TOBN(0x716da290, 0xb07c7004),
-+     TOBN(0x35f911ea, 0xb7950ee3), TOBN(0x6fd72969, 0x261d21b5),
-+     TOBN(0x52389803, 0x08b640d3), TOBN(0x5b0026ee, 0x887f12a1),
-+     TOBN(0x20e21660, 0x742e9311), TOBN(0x0ef6d541, 0x5ff77ff7),
-+     TOBN(0x969127f0, 0xf9c41135), TOBN(0xf21d60c9, 0x68a64993),
-+     TOBN(0x656e5d0c, 0xe541875c), TOBN(0xf1e0f84e, 0xa1d3c233),
-+     TOBN(0x9bcca359, 0x06002d60), TOBN(0xbe2da60c, 0x06191552),
-+     TOBN(0x5da8bbae, 0x61181ec3), TOBN(0x9f04b823, 0x65806f19),
-+     TOBN(0xf1604a7d, 0xd4b79bb8), TOBN(0xaee806fb, 0x52c878c8),
-+     TOBN(0x34144f11, 0x8d47b8e8), TOBN(0x72edf52b, 0x949f9054),
-+     TOBN(0xebfca84e, 0x2127015a), TOBN(0x9051d0c0, 0x9cb7cef3),
-+     TOBN(0x86e8fe58, 0x296deec8), TOBN(0x33b28188, 0x41010d74),}
-+    ,
-+    {TOBN(0x01079383, 0x171b445f), TOBN(0x9bcf21e3, 0x8131ad4c),
-+     TOBN(0x8cdfe205, 0xc93987e8), TOBN(0xe63f4152, 0xc92e8c8f),
-+     TOBN(0x729462a9, 0x30add43d), TOBN(0x62ebb143, 0xc980f05a),
-+     TOBN(0x4f3954e5, 0x3b06e968), TOBN(0xfe1d75ad, 0x242cf6b1),
-+     TOBN(0x5f95c6c7, 0xaf8685c8), TOBN(0xd4c1c8ce, 0x2f8f01aa),
-+     TOBN(0xc44bbe32, 0x2574692a), TOBN(0xb8003478, 0xd4a4a068),
-+     TOBN(0x7c8fc6e5, 0x2eca3cdb), TOBN(0xea1db16b, 0xec04d399),
-+     TOBN(0xb05bc82e, 0x8f2bc5cf), TOBN(0x763d517f, 0xf44793d2),
-+     TOBN(0x4451c1b8, 0x08bd98d0), TOBN(0x644b1cd4, 0x6575f240),
-+     TOBN(0x6907eb33, 0x7375d270), TOBN(0x56c8bebd, 0xfa2286bd),
-+     TOBN(0xc713d2ac, 0xc4632b46), TOBN(0x17da427a, 0xafd60242),
-+     TOBN(0x313065b7, 0xc95c7546), TOBN(0xf8239898, 0xbf17a3de),
-+     TOBN(0xf3b7963f, 0x4c830320), TOBN(0x842c7aa0, 0x903203e3),
-+     TOBN(0xaf22ca0a, 0xe7327afb), TOBN(0x38e13092, 0x967609b6),
-+     TOBN(0x73b8fb62, 0x757558f1), TOBN(0x3cc3e831, 0xf7eca8c1),
-+     TOBN(0xe4174474, 0xf6331627), TOBN(0xa77989ca, 0xc3c40234),
-+     TOBN(0xe5fd17a1, 0x44a081e0), TOBN(0xd797fb7d, 0xb70e296a),
-+     TOBN(0x2b472b30, 0x481f719c), TOBN(0x0e632a98, 0xfe6f8c52),
-+     TOBN(0x89ccd116, 0xc5f0c284), TOBN(0xf51088af, 0x2d987c62),
-+     TOBN(0x2a2bccda, 0x4c2de6cf), TOBN(0x810f9efe, 0xf679f0f9),
-+     TOBN(0xb0f394b9, 0x7ffe4b3e), TOBN(0x0b691d21, 0xe5fa5d21),
-+     TOBN(0xb0bd7747, 0x9dfbbc75), TOBN(0xd2830fda, 0xfaf78b00),
-+     TOBN(0xf78c249c, 0x52434f57), TOBN(0x4b1f7545, 0x98096dab),
-+     TOBN(0x73bf6f94, 0x8ff8c0b3), TOBN(0x34aef03d, 0x454e134c),
-+     TOBN(0xf8d151f4, 0xb7ac7ec5), TOBN(0xd6ceb95a, 0xe50da7d5),
-+     TOBN(0xa1b492b0, 0xdc3a0eb8), TOBN(0x75157b69, 0xb3dd2863),
-+     TOBN(0xe2c4c74e, 0xc5413d62), TOBN(0xbe329ff7, 0xbc5fc4c7),
-+     TOBN(0x835a2aea, 0x60fa9dda), TOBN(0xf117f5ad, 0x7445cb87),
-+     TOBN(0xae8317f4, 0xb0166f7a), TOBN(0xfbd3e3f7, 0xceec74e6),
-+     TOBN(0xfdb516ac, 0xe0874bfd), TOBN(0x3d846019, 0xc681f3a3),
-+     TOBN(0x0b12ee5c, 0x7c1620b0), TOBN(0xba68b4dd, 0x2b63c501),
-+     TOBN(0xac03cd32, 0x6668c51e), TOBN(0x2a6279f7, 0x4e0bcb5b),
-+     TOBN(0x17bd69b0, 0x6ae85c10), TOBN(0x72946979, 0x1dfdd3a6),
-+     TOBN(0xd9a03268, 0x2c078bec), TOBN(0x41c6a658, 0xbfd68a52),
-+     TOBN(0xcdea1024, 0x0e023900), TOBN(0xbaeec121, 0xb10d144d),
-+     TOBN(0x5a600e74, 0x058ab8dc), TOBN(0x1333af21, 0xbb89ccdd),
-+     TOBN(0xdf25eae0, 0x3aaba1f1), TOBN(0x2cada16e, 0x3b7144cf),
-+     TOBN(0x657ee27d, 0x71ab98bc), TOBN(0x99088b4c, 0x7a6fc96e),
-+     TOBN(0x05d5c0a0, 0x3549dbd4), TOBN(0x42cbdf8f, 0xf158c3ac),
-+     TOBN(0x3fb6b3b0, 0x87edd685), TOBN(0x22071cf6, 0x86f064d0),
-+     TOBN(0xd2d6721f, 0xff2811e5), TOBN(0xdb81b703, 0xfe7fae8c),
-+     TOBN(0x3cfb74ef, 0xd3f1f7bb), TOBN(0x0cdbcd76, 0x16cdeb5d),
-+     TOBN(0x4f39642a, 0x566a808c), TOBN(0x02b74454, 0x340064d6),
-+     TOBN(0xfabbadca, 0x0528fa6f), TOBN(0xe4c3074c, 0xd3fc0bb6),
-+     TOBN(0xb32cb8b0, 0xb796d219), TOBN(0xc3e95f4f, 0x34741dd9),
-+     TOBN(0x87212125, 0x68edf6f5), TOBN(0x7a03aee4, 0xa2b9cb8e),
-+     TOBN(0x0cd3c376, 0xf53a89aa), TOBN(0x0d8af9b1, 0x948a28dc),
-+     TOBN(0xcf86a3f4, 0x902ab04f), TOBN(0x8aacb62a, 0x7f42002d),
-+     TOBN(0x106985eb, 0xf62ffd52), TOBN(0xe670b54e, 0x5797bf10),
-+     TOBN(0x4b405209, 0xc5e30aef), TOBN(0x12c97a20, 0x4365b5e9),
-+     TOBN(0x104646ce, 0x1fe32093), TOBN(0x13cb4ff6, 0x3907a8c9),
-+     TOBN(0x8b9f30d1, 0xd46e726b), TOBN(0xe1985e21, 0xaba0f499),
-+     TOBN(0xc573dea9, 0x10a230cd), TOBN(0x24f46a93, 0xcd30f947),
-+     TOBN(0xf2623fcf, 0xabe2010a), TOBN(0x3f278cb2, 0x73f00e4f),
-+     TOBN(0xed55c67d, 0x50b920eb), TOBN(0xf1cb9a2d, 0x8e760571),
-+     TOBN(0x7c50d109, 0x0895b709), TOBN(0x4207cf07, 0x190d4369),
-+     TOBN(0x3b027e81, 0xc4127fe1), TOBN(0xa9f8b9ad, 0x3ae9c566),
-+     TOBN(0x5ab10851, 0xacbfbba5), TOBN(0xa747d648, 0x569556f5),
-+     TOBN(0xcc172b5c, 0x2ba97bf7), TOBN(0x15e0f77d, 0xbcfa3324),
-+     TOBN(0xa345b797, 0x7686279d), TOBN(0x5a723480, 0xe38003d3),
-+     TOBN(0xfd8e139f, 0x8f5fcda8), TOBN(0xf3e558c4, 0xbdee5bfd),
-+     TOBN(0xd76cbaf4, 0xe33f9f77), TOBN(0x3a4c97a4, 0x71771969),
-+     TOBN(0xda27e84b, 0xf6dce6a7), TOBN(0xff373d96, 0x13e6c2d1),
-+     TOBN(0xf115193c, 0xd759a6e9), TOBN(0x3f9b7025, 0x63d2262c),
-+     TOBN(0xd9764a31, 0x317cd062), TOBN(0x30779d8e, 0x199f8332),
-+     TOBN(0xd8074106, 0x16b11b0b), TOBN(0x7917ab9f, 0x78aeaed8),
-+     TOBN(0xb67a9cbe, 0x28fb1d8e), TOBN(0x2e313563, 0x136eda33),
-+     TOBN(0x010b7069, 0xa371a86c), TOBN(0x44d90fa2, 0x6744e6b7),
-+     TOBN(0x68190867, 0xd6b3e243), TOBN(0x9fe6cd9d, 0x59048c48),
-+     TOBN(0xb900b028, 0x95731538), TOBN(0xa012062f, 0x32cae04f),
-+     TOBN(0x8107c8bc, 0x9399d082), TOBN(0x47e8c54a, 0x41df12e2),
-+     TOBN(0x14ba5117, 0xb6ef3f73), TOBN(0x22260bea, 0x81362f0b),
-+     TOBN(0x90ea261e, 0x1a18cc20), TOBN(0x2192999f, 0x2321d636),
-+     TOBN(0xef64d314, 0xe311b6a0), TOBN(0xd7401e4c, 0x3b54a1f5),
-+     TOBN(0x19019983, 0x6fbca2ba), TOBN(0x46ad3293, 0x8fbffc4b),
-+     TOBN(0xa142d3f6, 0x3786bf40), TOBN(0xeb5cbc26, 0xb67039fc),
-+     TOBN(0x9cb0ae6c, 0x252bd479), TOBN(0x05e0f88a, 0x12b5848f),
-+     TOBN(0x78f6d2b2, 0xa5c97663), TOBN(0x6f6e149b, 0xc162225c),
-+     TOBN(0xe602235c, 0xde601a89), TOBN(0xd17bbe98, 0xf373be1f),
-+     TOBN(0xcaf49a5b, 0xa8471827), TOBN(0x7e1a0a85, 0x18aaa116),
-+     TOBN(0x6c833196, 0x270580c3), TOBN(0x1e233839, 0xf1c98a14),
-+     TOBN(0x67b2f7b4, 0xae34e0a5), TOBN(0x47ac8745, 0xd8ce7289),
-+     TOBN(0x2b74779a, 0x100dd467), TOBN(0x274a4337, 0x4ee50d09),
-+     TOBN(0x603dcf13, 0x83608bc9), TOBN(0xcd9da6c3, 0xc89e8388),
-+     TOBN(0x2660199f, 0x355116ac), TOBN(0xcc38bb59, 0xb6d18eed),
-+     TOBN(0x3075f31f, 0x2f4bc071), TOBN(0x9774457f, 0x265dc57e),
-+     TOBN(0x06a6a9c8, 0xc6db88bb), TOBN(0x6429d07f, 0x4ec98e04),
-+     TOBN(0x8d05e57b, 0x05ecaa8b), TOBN(0x20f140b1, 0x7872ea7b),
-+     TOBN(0xdf8c0f09, 0xca494693), TOBN(0x48d3a020, 0xf252e909),
-+     TOBN(0x4c5c29af, 0x57b14b12), TOBN(0x7e6fa37d, 0xbf47ad1c),
-+     TOBN(0x66e7b506, 0x49a0c938), TOBN(0xb72c0d48, 0x6be5f41f),
-+     TOBN(0x6a6242b8, 0xb2359412), TOBN(0xcd35c774, 0x8e859480),
-+     TOBN(0x12536fea, 0x87baa627), TOBN(0x58c1fec1, 0xf72aa680),
-+     TOBN(0x6c29b637, 0x601e5dc9), TOBN(0x9e3c3c1c, 0xde9e01b9),
-+     TOBN(0xefc8127b, 0x2bcfe0b0), TOBN(0x35107102, 0x2a12f50d),
-+     TOBN(0x6ccd6cb1, 0x4879b397), TOBN(0xf792f804, 0xf8a82f21),
-+     TOBN(0x509d4804, 0xa9b46402), TOBN(0xedddf85d, 0xc10f0850),
-+     TOBN(0x928410dc, 0x4b6208aa), TOBN(0xf6229c46, 0x391012dc),
-+     TOBN(0xc5a7c41e, 0x7727b9b6), TOBN(0x289e4e4b, 0xaa444842),
-+     TOBN(0x049ba1d9, 0xe9a947ea), TOBN(0x44f9e47f, 0x83c8debc),
-+     TOBN(0xfa77a1fe, 0x611f8b8e), TOBN(0xfd2e416a, 0xf518f427),
-+     TOBN(0xc5fffa70, 0x114ebac3), TOBN(0xfe57c4e9, 0x5d89697b),
-+     TOBN(0xfdd053ac, 0xb1aaf613), TOBN(0x31df210f, 0xea585a45),
-+     TOBN(0x318cc10e, 0x24985034), TOBN(0x1a38efd1, 0x5f1d6130),
-+     TOBN(0xbf86f237, 0x0b1e9e21), TOBN(0xb258514d, 0x1dbe88aa),
-+     TOBN(0x1e38a588, 0x90c1baf9), TOBN(0x2936a01e, 0xbdb9b692),
-+     TOBN(0xd576de98, 0x6dd5b20c), TOBN(0xb586bf71, 0x70f98ecf),
-+     TOBN(0xcccf0f12, 0xc42d2fd7), TOBN(0x8717e61c, 0xfb35bd7b),
-+     TOBN(0x8b1e5722, 0x35e6fc06), TOBN(0x3477728f, 0x0b3e13d5),
-+     TOBN(0x150c294d, 0xaa8a7372), TOBN(0xc0291d43, 0x3bfa528a),
-+     TOBN(0xc6c8bc67, 0xcec5a196), TOBN(0xdeeb31e4, 0x5c2e8a7c),
-+     TOBN(0xba93e244, 0xfb6e1c51), TOBN(0xb9f8b71b, 0x2e28e156),
-+     TOBN(0xce65a287, 0x968a2ab9), TOBN(0xe3c5ce69, 0x46bbcb1f),
-+     TOBN(0xf8c835b9, 0xe7ae3f30), TOBN(0x16bbee26, 0xff72b82b),
-+     TOBN(0x665e2017, 0xfd42cd22), TOBN(0x1e139970, 0xf8b1d2a0),
-+     TOBN(0x125cda29, 0x79204932), TOBN(0x7aee94a5, 0x49c3bee5),
-+     TOBN(0x68c70160, 0x89821a66), TOBN(0xf7c37678, 0x8f981669),
-+     TOBN(0xd90829fc, 0x48cc3645), TOBN(0x346af049, 0xd70addfc),
-+     TOBN(0x2057b232, 0x370bf29c), TOBN(0xf90c73ce, 0x42e650ee),
-+     TOBN(0xe03386ea, 0xa126ab90), TOBN(0x0e266e7e, 0x975a087b),
-+     TOBN(0x80578eb9, 0x0fca65d9), TOBN(0x7e2989ea, 0x16af45b8),
-+     TOBN(0x7438212d, 0xcac75a4e), TOBN(0x38c7ca39, 0x4fef36b8),
-+     TOBN(0x8650c494, 0xd402676a), TOBN(0x26ab5a66, 0xf72c7c48),
-+     TOBN(0x4e6cb426, 0xce3a464e), TOBN(0xf8f99896, 0x2b72f841),
-+     TOBN(0x8c318491, 0x1a335cc8), TOBN(0x563459ba, 0x6a5913e4),
-+     TOBN(0x1b920d61, 0xc7b32919), TOBN(0x805ab8b6, 0xa02425ad),
-+     TOBN(0x2ac512da, 0x8d006086), TOBN(0x6ca4846a, 0xbcf5c0fd),
-+     TOBN(0xafea51d8, 0xac2138d7), TOBN(0xcb647545, 0x344cd443),
-+     TOBN(0x0429ee8f, 0xbd7d9040), TOBN(0xee66a2de, 0x819b9c96),
-+     TOBN(0x54f9ec25, 0xdea7d744), TOBN(0x2ffea642, 0x671721bb),
-+     TOBN(0x4f19dbd1, 0x114344ea), TOBN(0x04304536, 0xfd0dbc8b),
-+     TOBN(0x014b50aa, 0x29ec7f91), TOBN(0xb5fc22fe, 0xbb06014d),
-+     TOBN(0x60d963a9, 0x1ee682e0), TOBN(0xdf48abc0, 0xfe85c727),
-+     TOBN(0x0cadba13, 0x2e707c2d), TOBN(0xde608d3a, 0xa645aeff),
-+     TOBN(0x05f1c28b, 0xedafd883), TOBN(0x3c362ede, 0xbd94de1f),
-+     TOBN(0x8dd0629d, 0x13593e41), TOBN(0x0a5e736f, 0x766d6eaf),
-+     TOBN(0xbfa92311, 0xf68cf9d1), TOBN(0xa4f9ef87, 0xc1797556),
-+     TOBN(0x10d75a1f, 0x5601c209), TOBN(0x651c374c, 0x09b07361),
-+     TOBN(0x49950b58, 0x88b5cead), TOBN(0x0ef00058, 0x6fa9dbaa),
-+     TOBN(0xf51ddc26, 0x4e15f33a), TOBN(0x1f8b5ca6, 0x2ef46140),
-+     TOBN(0x343ac0a3, 0xee9523f0), TOBN(0xbb75eab2, 0x975ea978),
-+     TOBN(0x1bccf332, 0x107387f4), TOBN(0x790f9259, 0x9ab0062e),
-+     TOBN(0xf1a363ad, 0x1e4f6a5f), TOBN(0x06e08b84, 0x62519a50),
-+     TOBN(0x60915187, 0x7265f1ee), TOBN(0x6a80ca34, 0x93ae985e),
-+     TOBN(0x81b29768, 0xaaba4864), TOBN(0xb13cabf2, 0x8d52a7d6),
-+     TOBN(0xb5c36348, 0x8ead03f1), TOBN(0xc932ad95, 0x81c7c1c0),
-+     TOBN(0x5452708e, 0xcae1e27b), TOBN(0x9dac4269, 0x1b0df648),
-+     TOBN(0x233e3f0c, 0xdfcdb8bc), TOBN(0xe6ceccdf, 0xec540174),
-+     TOBN(0xbd0d845e, 0x95081181), TOBN(0xcc8a7920, 0x699355d5),
-+     TOBN(0x111c0f6d, 0xc3b375a8), TOBN(0xfd95bc6b, 0xfd51e0dc),
-+     TOBN(0x4a106a26, 0x6888523a), TOBN(0x4d142bd6, 0xcb01a06d),
-+     TOBN(0x79bfd289, 0xadb9b397), TOBN(0x0bdbfb94, 0xe9863914),
-+     TOBN(0x29d8a229, 0x1660f6a6), TOBN(0x7f6abcd6, 0x551c042d),
-+     TOBN(0x13039deb, 0x0ac3ffe8), TOBN(0xa01be628, 0xec8523fb),
-+     TOBN(0x6ea34103, 0x0ca1c328), TOBN(0xc74114bd, 0xb903928e),
-+     TOBN(0x8aa4ff4e, 0x9e9144b0), TOBN(0x7064091f, 0x7f9a4b17),
-+     TOBN(0xa3f4f521, 0xe447f2c4), TOBN(0x81b8da7a, 0x604291f0),
-+     TOBN(0xd680bc46, 0x7d5926de), TOBN(0x84f21fd5, 0x34a1202f),
-+     TOBN(0x1d1e3181, 0x4e9df3d8), TOBN(0x1ca4861a, 0x39ab8d34),
-+     TOBN(0x809ddeec, 0x5b19aa4a), TOBN(0x59f72f7e, 0x4d329366),
-+     TOBN(0xa2f93f41, 0x386d5087), TOBN(0x40bf739c, 0xdd67d64f),
-+     TOBN(0xb4494205, 0x66702158), TOBN(0xc33c65be, 0x73b1e178),
-+     TOBN(0xcdcd657c, 0x38ca6153), TOBN(0x97f4519a, 0xdc791976),
-+     TOBN(0xcc7c7f29, 0xcd6e1f39), TOBN(0x38de9cfb, 0x7e3c3932),
-+     TOBN(0xe448eba3, 0x7b793f85), TOBN(0xe9f8dbf9, 0xf067e914),
-+     TOBN(0xc0390266, 0xf114ae87), TOBN(0x39ed75a7, 0xcd6a8e2a),
-+     TOBN(0xadb14848, 0x7ffba390), TOBN(0x67f8cb8b, 0x6af9bc09),
-+     TOBN(0x322c3848, 0x9c7476db), TOBN(0xa320fecf, 0x52a538d6),
-+     TOBN(0xe0493002, 0xb2aced2b), TOBN(0xdfba1809, 0x616bd430),
-+     TOBN(0x531c4644, 0xc331be70), TOBN(0xbc04d32e, 0x90d2e450),
-+     TOBN(0x1805a0d1, 0x0f9f142d), TOBN(0x2c44a0c5, 0x47ee5a23),
-+     TOBN(0x31875a43, 0x3989b4e3), TOBN(0x6b1949fd, 0x0c063481),
-+     TOBN(0x2dfb9e08, 0xbe0f4492), TOBN(0x3ff0da03, 0xe9d5e517),
-+     TOBN(0x03dbe9a1, 0xf79466a8), TOBN(0x0b87bcd0, 0x15ea9932),
-+     TOBN(0xeb64fc83, 0xab1f58ab), TOBN(0x6d9598da, 0x817edc8a),
-+     TOBN(0x699cff66, 0x1d3b67e5), TOBN(0x645c0f29, 0x92635853),
-+     TOBN(0x253cdd82, 0xeabaf21c), TOBN(0x82b9602a, 0x2241659e),
-+     TOBN(0x2cae07ec, 0x2d9f7091), TOBN(0xbe4c720c, 0x8b48cd9b),
-+     TOBN(0x6ce5bc03, 0x6f08d6c9), TOBN(0x36e8a997, 0xaf10bf40),
-+     TOBN(0x83422d21, 0x3e10ff12), TOBN(0x7b26d3eb, 0xbcc12494),
-+     TOBN(0xb240d2d0, 0xc9469ad6), TOBN(0xc4a11b4d, 0x30afa05b),
-+     TOBN(0x4b604ace, 0xdd6ba286), TOBN(0x18486600, 0x3ee2864c),
-+     TOBN(0x5869d6ba, 0x8d9ce5be), TOBN(0x0d8f68c5, 0xff4bfb0d),
-+     TOBN(0xb69f210b, 0x5700cf73), TOBN(0x61f6653a, 0x6d37c135),
-+     TOBN(0xff3d432b, 0x5aff5a48), TOBN(0x0d81c4b9, 0x72ba3a69),
-+     TOBN(0xee879ae9, 0xfa1899ef), TOBN(0xbac7e2a0, 0x2d6acafd),
-+     TOBN(0xd6d93f6c, 0x1c664399), TOBN(0x4c288de1, 0x5bcb135d),
-+     TOBN(0x83031dab, 0x9dab7cbf), TOBN(0xfe23feb0, 0x3abbf5f0),
-+     TOBN(0x9f1b2466, 0xcdedca85), TOBN(0x140bb710, 0x1a09538c),
-+     TOBN(0xac8ae851, 0x5e11115d), TOBN(0x0d63ff67, 0x6f03f59e),
-+     TOBN(0x755e5551, 0x7d234afb), TOBN(0x61c2db4e, 0x7e208fc1),
-+     TOBN(0xaa9859ce, 0xf28a4b5d), TOBN(0xbdd6d4fc, 0x34af030f),
-+     TOBN(0xd1c4a26d, 0x3be01cb1), TOBN(0x9ba14ffc, 0x243aa07c),
-+     TOBN(0xf95cd3a9, 0xb2503502), TOBN(0xe379bc06, 0x7d2a93ab),
-+     TOBN(0x3efc18e9, 0xd4ca8d68), TOBN(0x083558ec, 0x80bb412a),
-+     TOBN(0xd903b940, 0x9645a968), TOBN(0xa499f0b6, 0x9ba6054f),
-+     TOBN(0x208b573c, 0xb8349abe), TOBN(0x3baab3e5, 0x30b4fc1c),
-+     TOBN(0x87e978ba, 0xcb524990), TOBN(0x3524194e, 0xccdf0e80),
-+     TOBN(0x62711725, 0x7d4bcc42), TOBN(0xe90a3d9b, 0xb90109ba),
-+     TOBN(0x3b1bdd57, 0x1323e1e0), TOBN(0xb78e9bd5, 0x5eae1599),
-+     TOBN(0x0794b746, 0x9e03d278), TOBN(0x80178605, 0xd70e6297),
-+     TOBN(0x171792f8, 0x99c97855), TOBN(0x11b393ee, 0xf5a86b5c),
-+     TOBN(0x48ef6582, 0xd8884f27), TOBN(0xbd44737a, 0xbf19ba5f),
-+     TOBN(0x8698de4c, 0xa42062c6), TOBN(0x8975eb80, 0x61ce9c54),
-+     TOBN(0xd50e57c7, 0xd7fe71f3), TOBN(0x15342190, 0xbc97ce38),
-+     TOBN(0x51bda2de, 0x4df07b63), TOBN(0xba12aeae, 0x200eb87d),
-+     TOBN(0xabe135d2, 0xa9b4f8f6), TOBN(0x04619d65, 0xfad6d99c),
-+     TOBN(0x4a6683a7, 0x7994937c), TOBN(0x7a778c8b, 0x6f94f09a),
-+     TOBN(0x8c508623, 0x20a71b89), TOBN(0x241a2aed, 0x1c229165),
-+     TOBN(0x352be595, 0xaaf83a99), TOBN(0x9fbfee7f, 0x1562bac8),
-+     TOBN(0xeaf658b9, 0x5c4017e3), TOBN(0x1dc7f9e0, 0x15120b86),
-+     TOBN(0xd84f13dd, 0x4c034d6f), TOBN(0x283dd737, 0xeaea3038),
-+     TOBN(0x197f2609, 0xcd85d6a2), TOBN(0x6ebbc345, 0xfae60177),
-+     TOBN(0xb80f031b, 0x4e12fede), TOBN(0xde55d0c2, 0x07a2186b),
-+     TOBN(0x1fb3e37f, 0x24dcdd5a), TOBN(0x8d602da5, 0x7ed191fb),
-+     TOBN(0x108fb056, 0x76023e0d), TOBN(0x70178c71, 0x459c20c0),
-+     TOBN(0xfad5a386, 0x3fe54cf0), TOBN(0xa4a3ec4f, 0x02bbb475),
-+     TOBN(0x1aa5ec20, 0x919d94d7), TOBN(0x5d3b63b5, 0xa81e4ab3),
-+     TOBN(0x7fa733d8, 0x5ad3d2af), TOBN(0xfbc586dd, 0xd1ac7a37),
-+     TOBN(0x282925de, 0x40779614), TOBN(0xfe0ffffb, 0xe74a242a),
-+     TOBN(0x3f39e67f, 0x906151e5), TOBN(0xcea27f5f, 0x55e10649),
-+     TOBN(0xdca1d4e1, 0xc17cf7b7), TOBN(0x0c326d12, 0x2fe2362d),
-+     TOBN(0x05f7ac33, 0x7dd35df3), TOBN(0x0c3b7639, 0xc396dbdf),
-+     TOBN(0x0912f5ac, 0x03b7db1c), TOBN(0x9dea4b70, 0x5c9ed4a9),
-+     TOBN(0x475e6e53, 0xaae3f639), TOBN(0xfaba0e7c, 0xfc278bac),
-+     TOBN(0x16f9e221, 0x9490375f), TOBN(0xaebf9746, 0xa5a7ed0a),
-+     TOBN(0x45f9af3f, 0xf41ad5d6), TOBN(0x03c4623c, 0xb2e99224),
-+     TOBN(0x82c5bb5c, 0xb3cf56aa), TOBN(0x64311819, 0x34567ed3),
-+     TOBN(0xec57f211, 0x8be489ac), TOBN(0x2821895d, 0xb9a1104b),
-+     TOBN(0x610dc875, 0x6064e007), TOBN(0x8e526f3f, 0x5b20d0fe),
-+     TOBN(0x6e71ca77, 0x5b645aee), TOBN(0x3d1dcb9f, 0x800e10ff),
-+     TOBN(0x36b51162, 0x189cf6de), TOBN(0x2c5a3e30, 0x6bb17353),
-+     TOBN(0xc186cd3e, 0x2a6c6fbf), TOBN(0xa74516fa, 0x4bf97906),
-+     TOBN(0x5b4b8f4b, 0x279d6901), TOBN(0x0c4e57b4, 0x2b573743),
-+     TOBN(0x75fdb229, 0xb6e386b6), TOBN(0xb46793fd, 0x99deac27),
-+     TOBN(0xeeec47ea, 0xcf712629), TOBN(0xe965f3c4, 0xcbc3b2dd),
-+     TOBN(0x8dd1fb83, 0x425c6559), TOBN(0x7fc00ee6, 0x0af06fda),
-+     TOBN(0xe98c9225, 0x33d956df), TOBN(0x0f1ef335, 0x4fbdc8a2),
-+     TOBN(0x2abb5145, 0xb79b8ea2), TOBN(0x40fd2945, 0xbdbff288),
-+     TOBN(0x6a814ac4, 0xd7185db7), TOBN(0xc4329d6f, 0xc084609a),
-+     TOBN(0xc9ba7b52, 0xed1be45d), TOBN(0x891dd20d, 0xe4cd2c74),
-+     TOBN(0x5a4d4a7f, 0x824139b1), TOBN(0x66c17716, 0xb873c710),
-+     TOBN(0x5e5bc141, 0x2843c4e0), TOBN(0xd5ac4817, 0xb97eb5bf),
-+     TOBN(0xc0f8af54, 0x450c95c7), TOBN(0xc91b3fa0, 0x318406c5),
-+     TOBN(0x360c340a, 0xab9d97f8), TOBN(0xfb57bd07, 0x90a2d611),
-+     TOBN(0x4339ae3c, 0xa6a6f7e5), TOBN(0x9c1fcd2a, 0x2feb8a10),
-+     TOBN(0x972bcca9, 0xc7ea7432), TOBN(0x1b0b924c, 0x308076f6),
-+     TOBN(0x80b2814a, 0x2a5b4ca5), TOBN(0x2f78f55b, 0x61ef3b29),
-+     TOBN(0xf838744a, 0xc18a414f), TOBN(0xc611eaae, 0x903d0a86),
-+     TOBN(0x94dabc16, 0x2a453f55), TOBN(0xe6f2e3da, 0x14efb279),
-+     TOBN(0x5b7a6017, 0x9320dc3c), TOBN(0x692e382f, 0x8df6b5a4),
-+     TOBN(0x3f5e15e0, 0x2d40fa90), TOBN(0xc87883ae, 0x643dd318),
-+     TOBN(0x511053e4, 0x53544774), TOBN(0x834d0ecc, 0x3adba2bc),
-+     TOBN(0x4215d7f7, 0xbae371f5), TOBN(0xfcfd57bf, 0x6c8663bc),
-+     TOBN(0xded2383d, 0xd6901b1d), TOBN(0x3b49fbb4, 0xb5587dc3),
-+     TOBN(0xfd44a08d, 0x07625f62), TOBN(0x3ee4d65b, 0x9de9b762),}
-+    ,
-+    {TOBN(0x64e5137d, 0x0d63d1fa), TOBN(0x658fc052, 0x02a9d89f),
-+     TOBN(0x48894874, 0x50436309), TOBN(0xe9ae30f8, 0xd598da61),
-+     TOBN(0x2ed710d1, 0x818baf91), TOBN(0xe27e9e06, 0x8b6a0c20),
-+     TOBN(0x1e28dcfb, 0x1c1a6b44), TOBN(0x883acb64, 0xd6ac57dc),
-+     TOBN(0x8735728d, 0xc2c6ff70), TOBN(0x79d6122f, 0xc5dc2235),
-+     TOBN(0x23f5d003, 0x19e277f9), TOBN(0x7ee84e25, 0xdded8cc7),
-+     TOBN(0x91a8afb0, 0x63cd880a), TOBN(0x3f3ea7c6, 0x3574af60),
-+     TOBN(0x0cfcdc84, 0x02de7f42), TOBN(0x62d0792f, 0xb31aa152),
-+     TOBN(0x8e1b4e43, 0x8a5807ce), TOBN(0xad283893, 0xe4109a7e),
-+     TOBN(0xc30cc9cb, 0xafd59dda), TOBN(0xf65f36c6, 0x3d8d8093),
-+     TOBN(0xdf31469e, 0xa60d32b2), TOBN(0xee93df4b, 0x3e8191c8),
-+     TOBN(0x9c1017c5, 0x355bdeb5), TOBN(0xd2623185, 0x8616aa28),
-+     TOBN(0xb02c83f9, 0xdec31a21), TOBN(0x988c8b23, 0x6ad9d573),
-+     TOBN(0x53e983ae, 0xa57be365), TOBN(0xe968734d, 0x646f834e),
-+     TOBN(0x9137ea8f, 0x5da6309b), TOBN(0x10f3a624, 0xc1f1ce16),
-+     TOBN(0x782a9ea2, 0xca440921), TOBN(0xdf94739e, 0x5b46f1b5),
-+     TOBN(0x9f9be006, 0xcce85c9b), TOBN(0x360e70d6, 0xa4c7c2d3),
-+     TOBN(0x2cd5beea, 0xaefa1e60), TOBN(0x64cf63c0, 0x8c3d2b6d),
-+     TOBN(0xfb107fa3, 0xe1cf6f90), TOBN(0xb7e937c6, 0xd5e044e6),
-+     TOBN(0x74e8ca78, 0xce34db9f), TOBN(0x4f8b36c1, 0x3e210bd0),
-+     TOBN(0x1df165a4, 0x34a35ea8), TOBN(0x3418e0f7, 0x4d4412f6),
-+     TOBN(0x5af1f8af, 0x518836c3), TOBN(0x42ceef4d, 0x130e1965),
-+     TOBN(0x5560ca0b, 0x543a1957), TOBN(0xc33761e5, 0x886cb123),
-+     TOBN(0x66624b1f, 0xfe98ed30), TOBN(0xf772f4bf, 0x1090997d),
-+     TOBN(0xf4e540bb, 0x4885d410), TOBN(0x7287f810, 0x9ba5f8d7),
-+     TOBN(0x22d0d865, 0xde98dfb1), TOBN(0x49ff51a1, 0xbcfbb8a3),
-+     TOBN(0xb6b6fa53, 0x6bc3012e), TOBN(0x3d31fd72, 0x170d541d),
-+     TOBN(0x8018724f, 0x4b0f4966), TOBN(0x79e7399f, 0x87dbde07),
-+     TOBN(0x56f8410e, 0xf4f8b16a), TOBN(0x97241afe, 0xc47b266a),
-+     TOBN(0x0a406b8e, 0x6d9c87c1), TOBN(0x803f3e02, 0xcd42ab1b),
-+     TOBN(0x7f0309a8, 0x04dbec69), TOBN(0xa83b85f7, 0x3bbad05f),
-+     TOBN(0xc6097273, 0xad8e197f), TOBN(0xc097440e, 0x5067adc1),
-+     TOBN(0x730eafb6, 0x3524ff16), TOBN(0xd7f9b51e, 0x823fc6ce),
-+     TOBN(0x27bd0d32, 0x443e4ac0), TOBN(0x40c59ad9, 0x4d66f217),
-+     TOBN(0x6c33136f, 0x17c387a4), TOBN(0x5043b8d5, 0xeb86804d),
-+     TOBN(0x74970312, 0x675a73c9), TOBN(0x838fdb31, 0xf16669b6),
-+     TOBN(0xc507b6dd, 0x418e7ddd), TOBN(0x39888d93, 0x472f19d6),
-+     TOBN(0x7eae26be, 0x0c27eb4d), TOBN(0x17b53ed3, 0xfbabb884),
-+     TOBN(0xfc27021b, 0x2b01ae4f), TOBN(0x88462e87, 0xcf488682),
-+     TOBN(0xbee096ec, 0x215e2d87), TOBN(0xeb2fea9a, 0xd242e29b),
-+     TOBN(0x5d985b5f, 0xb821fc28), TOBN(0x89d2e197, 0xdc1e2ad2),
-+     TOBN(0x55b566b8, 0x9030ba62), TOBN(0xe3fd41b5, 0x4f41b1c6),
-+     TOBN(0xb738ac2e, 0xb9a96d61), TOBN(0x7f8567ca, 0x369443f4),
-+     TOBN(0x8698622d, 0xf803a440), TOBN(0x2b586236, 0x8fe2f4dc),
-+     TOBN(0xbbcc00c7, 0x56b95bce), TOBN(0x5ec03906, 0x616da680),
-+     TOBN(0x79162ee6, 0x72214252), TOBN(0x43132b63, 0x86a892d2),
-+     TOBN(0x4bdd3ff2, 0x2f3263bf), TOBN(0xd5b3733c, 0x9cd0a142),
-+     TOBN(0x592eaa82, 0x44415ccb), TOBN(0x663e8924, 0x8d5474ea),
-+     TOBN(0x8058a25e, 0x5236344e), TOBN(0x82e8df9d, 0xbda76ee6),
-+     TOBN(0xdcf6efd8, 0x11cc3d22), TOBN(0x00089cda, 0x3b4ab529),
-+     TOBN(0x91d3a071, 0xbd38a3db), TOBN(0x4ea97fc0, 0xef72b925),
-+     TOBN(0x0c9fc15b, 0xea3edf75), TOBN(0x5a6297cd, 0xa4348ed3),
-+     TOBN(0x0d38ab35, 0xce7c42d4), TOBN(0x9fd493ef, 0x82feab10),
-+     TOBN(0x46056b6d, 0x82111b45), TOBN(0xda11dae1, 0x73efc5c3),
-+     TOBN(0xdc740278, 0x5545a7fb), TOBN(0xbdb2601c, 0x40d507e6),
-+     TOBN(0x121dfeeb, 0x7066fa58), TOBN(0x214369a8, 0x39ae8c2a),
-+     TOBN(0x195709cb, 0x06e0956c), TOBN(0x4c9d254f, 0x010cd34b),
-+     TOBN(0xf51e13f7, 0x0471a532), TOBN(0xe19d6791, 0x1e73054d),
-+     TOBN(0xf702a628, 0xdb5c7be3), TOBN(0xc7141218, 0xb24dde05),
-+     TOBN(0xdc18233c, 0xf29b2e2e), TOBN(0x3a6bd1e8, 0x85342dba),
-+     TOBN(0x3f747fa0, 0xb311898c), TOBN(0xe2a272e4, 0xcd0eac65),
-+     TOBN(0x4bba5851, 0xf914d0bc), TOBN(0x7a1a9660, 0xc4a43ee3),
-+     TOBN(0xe5a367ce, 0xa1c8cde9), TOBN(0x9d958ba9, 0x7271abe3),
-+     TOBN(0xf3ff7eb6, 0x3d1615cd), TOBN(0xa2280dce, 0xf5ae20b0),
-+     TOBN(0x56dba5c1, 0xcf640147), TOBN(0xea5a2e3d, 0x5e83d118),
-+     TOBN(0x04cd6b6d, 0xda24c511), TOBN(0x1c0f4671, 0xe854d214),
-+     TOBN(0x91a6b7a9, 0x69565381), TOBN(0xdc966240, 0xdecf1f5b),
-+     TOBN(0x1b22d21c, 0xfcf5d009), TOBN(0x2a05f641, 0x9021dbd5),
-+     TOBN(0x8c0ed566, 0xd4312483), TOBN(0x5179a95d, 0x643e216f),
-+     TOBN(0xcc185fec, 0x17044493), TOBN(0xb3063339, 0x54991a21),
-+     TOBN(0xd801ecdb, 0x0081a726), TOBN(0x0149b0c6, 0x4fa89bbb),
-+     TOBN(0xafe9065a, 0x4391b6b9), TOBN(0xedc92786, 0xd633f3a3),
-+     TOBN(0xe408c24a, 0xae6a8e13), TOBN(0x85833fde, 0x9f3897ab),
-+     TOBN(0x43800e7e, 0xd81a0715), TOBN(0xde08e346, 0xb44ffc5f),
-+     TOBN(0x7094184c, 0xcdeff2e0), TOBN(0x49f9387b, 0x165eaed1),
-+     TOBN(0x635d6129, 0x777c468a), TOBN(0x8c0dcfd1, 0x538c2dd8),
-+     TOBN(0xd6d9d9e3, 0x7a6a308b), TOBN(0x62375830, 0x4c2767d3),
-+     TOBN(0x874a8bc6, 0xf38cbeb6), TOBN(0xd94d3f1a, 0xccb6fd9e),
-+     TOBN(0x92a9735b, 0xba21f248), TOBN(0x272ad0e5, 0x6cd1efb0),
-+     TOBN(0x7437b69c, 0x05b03284), TOBN(0xe7f04702, 0x6948c225),
-+     TOBN(0x8a56c04a, 0xcba2ecec), TOBN(0x0c181270, 0xe3a73e41),
-+     TOBN(0x6cb34e9d, 0x03e93725), TOBN(0xf77c8713, 0x496521a9),
-+     TOBN(0x94569183, 0xfa7f9f90), TOBN(0xf2e7aa4c, 0x8c9707ad),
-+     TOBN(0xced2c9ba, 0x26c1c9a3), TOBN(0x9109fe96, 0x40197507),
-+     TOBN(0x9ae868a9, 0xe9adfe1c), TOBN(0x3984403d, 0x314e39bb),
-+     TOBN(0xb5875720, 0xf2fe378f), TOBN(0x33f901e0, 0xba44a628),
-+     TOBN(0xea1125fe, 0x3652438c), TOBN(0xae9ec4e6, 0x9dd1f20b),
-+     TOBN(0x1e740d9e, 0xbebf7fbd), TOBN(0x6dbd3ddc, 0x42dbe79c),
-+     TOBN(0x62082aec, 0xedd36776), TOBN(0xf612c478, 0xe9859039),
-+     TOBN(0xa493b201, 0x032f7065), TOBN(0xebd4d8f2, 0x4ff9b211),
-+     TOBN(0x3f23a0aa, 0xaac4cb32), TOBN(0xea3aadb7, 0x15ed4005),
-+     TOBN(0xacf17ea4, 0xafa27e63), TOBN(0x56125c1a, 0xc11fd66c),
-+     TOBN(0x266344a4, 0x3794f8dc), TOBN(0xdcca923a, 0x483c5c36),
-+     TOBN(0x2d6b6bbf, 0x3f9d10a0), TOBN(0xb320c5ca, 0x81d9bdf3),
-+     TOBN(0x620e28ff, 0x47b50a95), TOBN(0x933e3b01, 0xcef03371),
-+     TOBN(0xf081bf85, 0x99100153), TOBN(0x183be9a0, 0xc3a8c8d6),
-+     TOBN(0x4e3ddc5a, 0xd6bbe24d), TOBN(0xc6c74630, 0x53843795),
-+     TOBN(0x78193dd7, 0x65ec2d4c), TOBN(0xb8df26cc, 0xcd3c89b2),
-+     TOBN(0x98dbe399, 0x5a483f8d), TOBN(0x72d8a957, 0x7dd3313a),
-+     TOBN(0x65087294, 0xab0bd375), TOBN(0xfcd89248, 0x7c259d16),
-+     TOBN(0x8a9443d7, 0x7613aa81), TOBN(0x80100800, 0x85fe6584),
-+     TOBN(0x70fc4dbc, 0x7fb10288), TOBN(0xf58280d3, 0xe86beee8),
-+     TOBN(0x14fdd82f, 0x7c978c38), TOBN(0xdf1204c1, 0x0de44d7b),
-+     TOBN(0xa08a1c84, 0x4160252f), TOBN(0x591554ca, 0xc17646a5),
-+     TOBN(0x214a37d6, 0xa05bd525), TOBN(0x48d5f09b, 0x07957b3c),
-+     TOBN(0x0247cdcb, 0xd7109bc9), TOBN(0x40f9e4bb, 0x30599ce7),
-+     TOBN(0xc325fa03, 0xf46ad2ec), TOBN(0x00f766cf, 0xc3e3f9ee),
-+     TOBN(0xab556668, 0xd43a4577), TOBN(0x68d30a61, 0x3ee03b93),
-+     TOBN(0x7ddc81ea, 0x77b46a08), TOBN(0xcf5a6477, 0xc7480699),
-+     TOBN(0x43a8cb34, 0x6633f683), TOBN(0x1b867e6b, 0x92363c60),
-+     TOBN(0x43921114, 0x1f60558e), TOBN(0xcdbcdd63, 0x2f41450e),
-+     TOBN(0x7fc04601, 0xcc630e8b), TOBN(0xea7c66d5, 0x97038b43),
-+     TOBN(0x7259b8a5, 0x04e99fd8), TOBN(0x98a8dd12, 0x4785549a),
-+     TOBN(0x0e459a7c, 0x840552e1), TOBN(0xcdfcf4d0, 0x4bb0909e),
-+     TOBN(0x34a86db2, 0x53758da7), TOBN(0xe643bb83, 0xeac997e1),
-+     TOBN(0x96400bd7, 0x530c5b7e), TOBN(0x9f97af87, 0xb41c8b52),
-+     TOBN(0x34fc8820, 0xfbeee3f9), TOBN(0x93e53490, 0x49091afd),
-+     TOBN(0x764b9be5, 0x9a31f35c), TOBN(0x71f37864, 0x57e3d924),
-+     TOBN(0x02fb34e0, 0x943aa75e), TOBN(0xa18c9c58, 0xab8ff6e4),
-+     TOBN(0x080f31b1, 0x33cf0d19), TOBN(0x5c9682db, 0x083518a7),
-+     TOBN(0x873d4ca6, 0xb709c3de), TOBN(0x64a84262, 0x3575b8f0),
-+     TOBN(0x6275da1f, 0x020154bb), TOBN(0x97678caa, 0xd17cf1ab),
-+     TOBN(0x8779795f, 0x951a95c3), TOBN(0xdd35b163, 0x50fccc08),
-+     TOBN(0x32709627, 0x33d8f031), TOBN(0x3c5ab10a, 0x498dd85c),
-+     TOBN(0xb6c185c3, 0x41dca566), TOBN(0x7de7feda, 0xd8622aa3),
-+     TOBN(0x99e84d92, 0x901b6dfb), TOBN(0x30a02b0e, 0x7c4ad288),
-+     TOBN(0xc7c81daa, 0x2fd3cf36), TOBN(0xd1319547, 0xdf89e59f),
-+     TOBN(0xb2be8184, 0xcd496733), TOBN(0xd5f449eb, 0x93d3412b),
-+     TOBN(0x7ea41b1b, 0x25fe531d), TOBN(0xf9797432, 0x6a1d5646),
-+     TOBN(0x86067f72, 0x2bde501a), TOBN(0xf91481c0, 0x0c85e89c),
-+     TOBN(0xca8ee465, 0xf8b05bc6), TOBN(0x1844e1cf, 0x02e83cda),
-+     TOBN(0xca82114a, 0xb4dbe33b), TOBN(0x0f9f8769, 0x4eabfde2),
-+     TOBN(0x4936b1c0, 0x38b27fe2), TOBN(0x63b6359b, 0xaba402df),
-+     TOBN(0x40c0ea2f, 0x656bdbab), TOBN(0x9c992a89, 0x6580c39c),
-+     TOBN(0x600e8f15, 0x2a60aed1), TOBN(0xeb089ca4, 0xe0bf49df),
-+     TOBN(0x9c233d7d, 0x2d42d99a), TOBN(0x648d3f95, 0x4c6bc2fa),
-+     TOBN(0xdcc383a8, 0xe1add3f3), TOBN(0xf42c0c6a, 0x4f64a348),
-+     TOBN(0x2abd176f, 0x0030dbdb), TOBN(0x4de501a3, 0x7d6c215e),
-+     TOBN(0x4a107c1f, 0x4b9a64bc), TOBN(0xa77f0ad3, 0x2496cd59),
-+     TOBN(0xfb78ac62, 0x7688dffb), TOBN(0x7025a2ca, 0x67937d8e),
-+     TOBN(0xfde8b2d1, 0xd1a8f4e7), TOBN(0xf5b3da47, 0x7354927c),
-+     TOBN(0xe48606a3, 0xd9205735), TOBN(0xac477cc6, 0xe177b917),
-+     TOBN(0xfb1f73d2, 0xa883239a), TOBN(0xe12572f6, 0xcc8b8357),
-+     TOBN(0x9d355e9c, 0xfb1f4f86), TOBN(0x89b795f8, 0xd9f3ec6e),
-+     TOBN(0x27be56f1, 0xb54398dc), TOBN(0x1890efd7, 0x3fedeed5),
-+     TOBN(0x62f77f1f, 0x9c6d0140), TOBN(0x7ef0e314, 0x596f0ee4),
-+     TOBN(0x50ca6631, 0xcc61dab3), TOBN(0x4a39801d, 0xf4866e4f),
-+     TOBN(0x66c8d032, 0xae363b39), TOBN(0x22c591e5, 0x2ead66aa),
-+     TOBN(0x954ba308, 0xde02a53e), TOBN(0x2a6c060f, 0xd389f357),
-+     TOBN(0xe6cfcde8, 0xfbf40b66), TOBN(0x8e02fc56, 0xc6340ce1),
-+     TOBN(0xe4957795, 0x73adb4ba), TOBN(0x7b86122c, 0xa7b03805),
-+     TOBN(0x63f83512, 0x0c8e6fa6), TOBN(0x83660ea0, 0x057d7804),
-+     TOBN(0xbad79105, 0x21ba473c), TOBN(0xb6c50bee, 0xded5389d),
-+     TOBN(0xee2caf4d, 0xaa7c9bc0), TOBN(0xd97b8de4, 0x8c4e98a7),
-+     TOBN(0xa9f63e70, 0xab3bbddb), TOBN(0x3898aabf, 0x2597815a),
-+     TOBN(0x7659af89, 0xac15b3d9), TOBN(0xedf7725b, 0x703ce784),
-+     TOBN(0x25470fab, 0xe085116b), TOBN(0x04a43375, 0x87285310),
-+     TOBN(0x4e39187e, 0xe2bfd52f), TOBN(0x36166b44, 0x7d9ebc74),
-+     TOBN(0x92ad433c, 0xfd4b322c), TOBN(0x726aa817, 0xba79ab51),
-+     TOBN(0xf96eacd8, 0xc1db15eb), TOBN(0xfaf71e91, 0x0476be63),
-+     TOBN(0xdd69a640, 0x641fad98), TOBN(0xb7995918, 0x29622559),
-+     TOBN(0x03c6daa5, 0xde4199dc), TOBN(0x92cadc97, 0xad545eb4),
-+     TOBN(0x1028238b, 0x256534e4), TOBN(0x73e80ce6, 0x8595409a),
-+     TOBN(0x690d4c66, 0xd05dc59b), TOBN(0xc95f7b8f, 0x981dee80),
-+     TOBN(0xf4337014, 0xd856ac25), TOBN(0x441bd9dd, 0xac524dca),
-+     TOBN(0x640b3d85, 0x5f0499f5), TOBN(0x39cf84a9, 0xd5fda182),
-+     TOBN(0x04e7b055, 0xb2aa95a0), TOBN(0x29e33f0a, 0x0ddf1860),
-+     TOBN(0x082e74b5, 0x423f6b43), TOBN(0x217edeb9, 0x0aaa2b0f),
-+     TOBN(0x58b83f35, 0x83cbea55), TOBN(0xc485ee4d, 0xbc185d70),
-+     TOBN(0x833ff03b, 0x1e5f6992), TOBN(0xb5b9b9cc, 0xcf0c0dd5),
-+     TOBN(0x7caaee8e, 0x4e9e8a50), TOBN(0x462e907b, 0x6269dafd),
-+     TOBN(0x6ed5cee9, 0xfbe791c6), TOBN(0x68ca3259, 0xed430790),
-+     TOBN(0x2b72bdf2, 0x13b5ba88), TOBN(0x60294c8a, 0x35ef0ac4),
-+     TOBN(0x9c3230ed, 0x19b99b08), TOBN(0x560fff17, 0x6c2589aa),
-+     TOBN(0x552b8487, 0xd6770374), TOBN(0xa373202d, 0x9a56f685),
-+     TOBN(0xd3e7f907, 0x45f175d9), TOBN(0x3c2f315f, 0xd080d810),
-+     TOBN(0x1130e9dd, 0x7b9520e8), TOBN(0xc078f9e2, 0x0af037b5),
-+     TOBN(0x38cd2ec7, 0x1e9c104c), TOBN(0x0f684368, 0xc472fe92),
-+     TOBN(0xd3f1b5ed, 0x6247e7ef), TOBN(0xb32d33a9, 0x396dfe21),
-+     TOBN(0x46f59cf4, 0x4a9aa2c2), TOBN(0x69cd5168, 0xff0f7e41),
-+     TOBN(0x3f59da0f, 0x4b3234da), TOBN(0xcf0b0235, 0xb4579ebe),
-+     TOBN(0x6d1cbb25, 0x6d2476c7), TOBN(0x4f0837e6, 0x9dc30f08),
-+     TOBN(0x9a4075bb, 0x906f6e98), TOBN(0x253bb434, 0xc761e7d1),
-+     TOBN(0xde2e645f, 0x6e73af10), TOBN(0xb89a4060, 0x0c5f131c),
-+     TOBN(0xd12840c5, 0xb8cc037f), TOBN(0x3d093a5b, 0x7405bb47),
-+     TOBN(0x6202c253, 0x206348b8), TOBN(0xbf5d57fc, 0xc55a3ca7),
-+     TOBN(0x89f6c90c, 0x8c3bef48), TOBN(0x23ac7623, 0x5a0a960a),
-+     TOBN(0xdfbd3d6b, 0x552b42ab), TOBN(0x3ef22458, 0x132061f6),
-+     TOBN(0xd74e9bda, 0xc97e6516), TOBN(0x88779360, 0xc230f49e),
-+     TOBN(0xa6ec1de3, 0x1e74ea49), TOBN(0x581dcee5, 0x3fb645a2),
-+     TOBN(0xbaef2391, 0x8f483f14), TOBN(0x6d2dddfc, 0xd137d13b),
-+     TOBN(0x54cde50e, 0xd2743a42), TOBN(0x89a34fc5, 0xe4d97e67),
-+     TOBN(0x13f1f5b3, 0x12e08ce5), TOBN(0xa80540b8, 0xa7f0b2ca),
-+     TOBN(0x854bcf77, 0x01982805), TOBN(0xb8653ffd, 0x233bea04),
-+     TOBN(0x8e7b8787, 0x02b0b4c9), TOBN(0x2675261f, 0x9acb170a),
-+     TOBN(0x061a9d90, 0x930c14e5), TOBN(0xb59b30e0, 0xdef0abea),
-+     TOBN(0x1dc19ea6, 0x0200ec7d), TOBN(0xb6f4a3f9, 0x0bce132b),
-+     TOBN(0xb8d5de90, 0xf13e27e0), TOBN(0xbaee5ef0, 0x1fade16f),
-+     TOBN(0x6f406aaa, 0xe4c6cf38), TOBN(0xab4cfe06, 0xd1369815),
-+     TOBN(0x0dcffe87, 0xefd550c6), TOBN(0x9d4f59c7, 0x75ff7d39),
-+     TOBN(0xb02553b1, 0x51deb6ad), TOBN(0x812399a4, 0xb1877749),
-+     TOBN(0xce90f71f, 0xca6006e1), TOBN(0xc32363a6, 0xb02b6e77),
-+     TOBN(0x02284fbe, 0xdc36c64d), TOBN(0x86c81e31, 0xa7e1ae61),
-+     TOBN(0x2576c7e5, 0xb909d94a), TOBN(0x8b6f7d02, 0x818b2bb0),
-+     TOBN(0xeca3ed07, 0x56faa38a), TOBN(0xa3790e6c, 0x9305bb54),
-+     TOBN(0xd784eeda, 0x7bc73061), TOBN(0xbd56d369, 0x6dd50614),
-+     TOBN(0xd6575949, 0x229a8aa9), TOBN(0xdcca8f47, 0x4595ec28),
-+     TOBN(0x814305c1, 0x06ab4fe6), TOBN(0xc8c39768, 0x24f43f16),
-+     TOBN(0xe2a45f36, 0x523f2b36), TOBN(0x995c6493, 0x920d93bb),
-+     TOBN(0xf8afdab7, 0x90f1632b), TOBN(0x79ebbecd, 0x1c295954),
-+     TOBN(0xc7bb3ddb, 0x79592f48), TOBN(0x67216a7b, 0x5f88e998),
-+     TOBN(0xd91f098b, 0xbc01193e), TOBN(0xf7d928a5, 0xb1db83fc),
-+     TOBN(0x55e38417, 0xe991f600), TOBN(0x2a91113e, 0x2981a934),
-+     TOBN(0xcbc9d648, 0x06b13bde), TOBN(0xb011b6ac, 0x0755ff44),
-+     TOBN(0x6f4cb518, 0x045ec613), TOBN(0x522d2d31, 0xc2f5930a),
-+     TOBN(0x5acae1af, 0x382e65de), TOBN(0x57643067, 0x27bc966f),
-+     TOBN(0x5e12705d, 0x1c7193f0), TOBN(0xf0f32f47, 0x3be8858e),
-+     TOBN(0x785c3d7d, 0x96c6dfc7), TOBN(0xd75b4a20, 0xbf31795d),
-+     TOBN(0x91acf17b, 0x342659d4), TOBN(0xe596ea34, 0x44f0378f),
-+     TOBN(0x4515708f, 0xce52129d), TOBN(0x17387e1e, 0x79f2f585),
-+     TOBN(0x72cfd2e9, 0x49dee168), TOBN(0x1ae05223, 0x3e2af239),
-+     TOBN(0x009e75be, 0x1d94066a), TOBN(0x6cca31c7, 0x38abf413),
-+     TOBN(0xb50bd61d, 0x9bc49908), TOBN(0x4a9b4a8c, 0xf5e2bc1e),
-+     TOBN(0xeb6cc5f7, 0x946f83ac), TOBN(0x27da93fc, 0xebffab28),
-+     TOBN(0xea314c96, 0x4821c8c5), TOBN(0x8de49ded, 0xa83c15f4),
-+     TOBN(0x7a64cf20, 0x7af33004), TOBN(0x45f1bfeb, 0xc9627e10),
-+     TOBN(0x878b0626, 0x54b9df60), TOBN(0x5e4fdc3c, 0xa95c0b33),
-+     TOBN(0xe54a37ca, 0xc2035d8e), TOBN(0x9087cda9, 0x80f20b8c),
-+     TOBN(0x36f61c23, 0x8319ade4), TOBN(0x766f287a, 0xde8cfdf8),
-+     TOBN(0x48821948, 0x346f3705), TOBN(0x49a7b853, 0x16e4f4a2),
-+     TOBN(0xb9b3f8a7, 0x5cedadfd), TOBN(0x8f562815, 0x8db2a815),
-+     TOBN(0xc0b7d554, 0x01f68f95), TOBN(0x12971e27, 0x688a208e),
-+     TOBN(0xc9f8b696, 0xd0ff34fc), TOBN(0x20824de2, 0x1222718c),
-+     TOBN(0x7213cf9f, 0x0c95284d), TOBN(0xe2ad741b, 0xdc158240),
-+     TOBN(0x0ee3a6df, 0x54043ccf), TOBN(0x16ff479b, 0xd84412b3),
-+     TOBN(0xf6c74ee0, 0xdfc98af0), TOBN(0xa78a169f, 0x52fcd2fb),
-+     TOBN(0xd8ae8746, 0x99c930e9), TOBN(0x1d33e858, 0x49e117a5),
-+     TOBN(0x7581fcb4, 0x6624759f), TOBN(0xde50644f, 0x5bedc01d),
-+     TOBN(0xbeec5d00, 0xcaf3155e), TOBN(0x672d66ac, 0xbc73e75f),
-+     TOBN(0x86b9d8c6, 0x270b01db), TOBN(0xd249ef83, 0x50f55b79),
-+     TOBN(0x6131d6d4, 0x73978fe3), TOBN(0xcc4e4542, 0x754b00a1),
-+     TOBN(0x4e05df05, 0x57dfcfe9), TOBN(0x94b29cdd, 0x51ef6bf0),
-+     TOBN(0xe4530cff, 0x9bc7edf2), TOBN(0x8ac236fd, 0xd3da65f3),
-+     TOBN(0x0faf7d5f, 0xc8eb0b48), TOBN(0x4d2de14c, 0x660eb039),
-+     TOBN(0xc006bba7, 0x60430e54), TOBN(0x10a2d0d6, 0xda3289ab),
-+     TOBN(0x9c037a5d, 0xd7979c59), TOBN(0x04d1f3d3, 0xa116d944),
-+     TOBN(0x9ff22473, 0x8a0983cd), TOBN(0x28e25b38, 0xc883cabb),
-+     TOBN(0xe968dba5, 0x47a58995), TOBN(0x2c80b505, 0x774eebdf),
-+     TOBN(0xee763b71, 0x4a953beb), TOBN(0x502e223f, 0x1642e7f6),
-+     TOBN(0x6fe4b641, 0x61d5e722), TOBN(0x9d37c5b0, 0xdbef5316),
-+     TOBN(0x0115ed70, 0xf8330bc7), TOBN(0x139850e6, 0x75a72789),
-+     TOBN(0x27d7faec, 0xffceccc2), TOBN(0x3016a860, 0x4fd9f7f6),
-+     TOBN(0xc492ec64, 0x4cd8f64c), TOBN(0x58a2d790, 0x279d7b51),
-+     TOBN(0x0ced1fc5, 0x1fc75256), TOBN(0x3e658aed, 0x8f433017),
-+     TOBN(0x0b61942e, 0x05da59eb), TOBN(0xba3d60a3, 0x0ddc3722),
-+     TOBN(0x7c311cd1, 0x742e7f87), TOBN(0x6473ffee, 0xf6b01b6e),}
-+    ,
-+    {TOBN(0x8303604f, 0x692ac542), TOBN(0xf079ffe1, 0x227b91d3),
-+     TOBN(0x19f63e63, 0x15aaf9bd), TOBN(0xf99ee565, 0xf1f344fb),
-+     TOBN(0x8a1d661f, 0xd6219199), TOBN(0x8c883bc6, 0xd48ce41c),
-+     TOBN(0x1065118f, 0x3c74d904), TOBN(0x713889ee, 0x0faf8b1b),
-+     TOBN(0x972b3f8f, 0x81a1b3be), TOBN(0x4f3ce145, 0xce2764a0),
-+     TOBN(0xe2d0f1cc, 0x28c4f5f7), TOBN(0xdeee0c0d, 0xc7f3985b),
-+     TOBN(0x7df4adc0, 0xd39e25c3), TOBN(0x40619820, 0xc467a080),
-+     TOBN(0x440ebc93, 0x61cf5a58), TOBN(0x527729a6, 0x422ad600),
-+     TOBN(0xca6c0937, 0xb1b76ba6), TOBN(0x1a2eab85, 0x4d2026dc),
-+     TOBN(0xb1715e15, 0x19d9ae0a), TOBN(0xf1ad9199, 0xbac4a026),
-+     TOBN(0x35b3dfb8, 0x07ea7b0e), TOBN(0xedf5496f, 0x3ed9eb89),
-+     TOBN(0x8932e5ff, 0x2d6d08ab), TOBN(0xf314874e, 0x25bd2731),
-+     TOBN(0xefb26a75, 0x3f73f449), TOBN(0x1d1c94f8, 0x8d44fc79),
-+     TOBN(0x49f0fbc5, 0x3bc0dc4d), TOBN(0xb747ea0b, 0x3698a0d0),
-+     TOBN(0x5218c3fe, 0x228d291e), TOBN(0x35b804b5, 0x43c129d6),
-+     TOBN(0xfac859b8, 0xd1acc516), TOBN(0x6c10697d, 0x95d6e668),
-+     TOBN(0xc38e438f, 0x0876fd4e), TOBN(0x45f0c307, 0x83d2f383),
-+     TOBN(0x203cc2ec, 0xb10934cb), TOBN(0x6a8f2439, 0x2c9d46ee),
-+     TOBN(0xf16b431b, 0x65ccde7b), TOBN(0x41e2cd18, 0x27e76a6f),
-+     TOBN(0xb9c8cf8f, 0x4e3484d7), TOBN(0x64426efd, 0x8315244a),
-+     TOBN(0x1c0a8e44, 0xfc94dea3), TOBN(0x34c8cdbf, 0xdad6a0b0),
-+     TOBN(0x919c3840, 0x04113cef), TOBN(0xfd32fba4, 0x15490ffa),
-+     TOBN(0x58d190f6, 0x795dcfb7), TOBN(0xfef01b03, 0x83588baf),
-+     TOBN(0x9e6d1d63, 0xca1fc1c0), TOBN(0x53173f96, 0xf0a41ac9),
-+     TOBN(0x2b1d402a, 0xba16f73b), TOBN(0x2fb31014, 0x8cf9b9fc),
-+     TOBN(0x2d51e60e, 0x446ef7bf), TOBN(0xc731021b, 0xb91e1745),
-+     TOBN(0x9d3b4724, 0x4fee99d4), TOBN(0x4bca48b6, 0xfac5c1ea),
-+     TOBN(0x70f5f514, 0xbbea9af7), TOBN(0x751f55a5, 0x974c283a),
-+     TOBN(0x6e30251a, 0xcb452fdb), TOBN(0x31ee6965, 0x50f30650),
-+     TOBN(0xb0b3e508, 0x933548d9), TOBN(0xb8949a4f, 0xf4b0ef5b),
-+     TOBN(0x208b8326, 0x3c88f3bd), TOBN(0xab147c30, 0xdb1d9989),
-+     TOBN(0xed6515fd, 0x44d4df03), TOBN(0x17a12f75, 0xe72eb0c5),
-+     TOBN(0x3b59796d, 0x36cf69db), TOBN(0x1219eee9, 0x56670c18),
-+     TOBN(0xfe3341f7, 0x7a070d8e), TOBN(0x9b70130b, 0xa327f90c),
-+     TOBN(0x36a32462, 0x0ae18e0e), TOBN(0x2021a623, 0x46c0a638),
-+     TOBN(0x251b5817, 0xc62eb0d4), TOBN(0x87bfbcdf, 0x4c762293),
-+     TOBN(0xf78ab505, 0xcdd61d64), TOBN(0x8c7a53fc, 0xc8c18857),
-+     TOBN(0xa653ce6f, 0x16147515), TOBN(0x9c923aa5, 0xea7d52d5),
-+     TOBN(0xc24709cb, 0x5c18871f), TOBN(0x7d53bec8, 0x73b3cc74),
-+     TOBN(0x59264aff, 0xfdd1d4c4), TOBN(0x5555917e, 0x240da582),
-+     TOBN(0xcae8bbda, 0x548f5a0e), TOBN(0x1910eaba, 0x3bbfbbe1),
-+     TOBN(0xae579685, 0x7677afc3), TOBN(0x49ea61f1, 0x73ff0b5c),
-+     TOBN(0x78655478, 0x4f7c3922), TOBN(0x95d337cd, 0x20c68eef),
-+     TOBN(0x68f1e1e5, 0xdf779ab9), TOBN(0x14b491b0, 0xb5cf69a8),
-+     TOBN(0x7a6cbbe0, 0x28e3fe89), TOBN(0xe7e1fee4, 0xc5aac0eb),
-+     TOBN(0x7f47eda5, 0x697e5140), TOBN(0x4f450137, 0xb454921f),
-+     TOBN(0xdb625f84, 0x95cd8185), TOBN(0x74be0ba1, 0xcdb2e583),
-+     TOBN(0xaee4fd7c, 0xdd5e6de4), TOBN(0x4251437d, 0xe8101739),
-+     TOBN(0x686d72a0, 0xac620366), TOBN(0x4be3fb9c, 0xb6d59344),
-+     TOBN(0x6e8b44e7, 0xa1eb75b9), TOBN(0x84e39da3, 0x91a5c10c),
-+     TOBN(0x37cc1490, 0xb38f0409), TOBN(0x02951943, 0x2c2ade82),
-+     TOBN(0x9b688783, 0x1190a2d8), TOBN(0x25627d14, 0x231182ba),
-+     TOBN(0x6eb550aa, 0x658a6d87), TOBN(0x1405aaa7, 0xcf9c7325),
-+     TOBN(0xd147142e, 0x5c8748c9), TOBN(0x7f637e4f, 0x53ede0e0),
-+     TOBN(0xf8ca2776, 0x14ffad2c), TOBN(0xe58fb1bd, 0xbafb6791),
-+     TOBN(0x17158c23, 0xbf8f93fc), TOBN(0x7f15b373, 0x0a4a4655),
-+     TOBN(0x39d4add2, 0xd842ca72), TOBN(0xa71e4391, 0x3ed96305),
-+     TOBN(0x5bb09cbe, 0x6700be14), TOBN(0x68d69d54, 0xd8befcf6),
-+     TOBN(0xa45f5367, 0x37183bcf), TOBN(0x7152b7bb, 0x3370dff7),
-+     TOBN(0xcf887baa, 0xbf12525b), TOBN(0xe7ac7bdd, 0xd6d1e3cd),
-+     TOBN(0x25914f78, 0x81fdad90), TOBN(0xcf638f56, 0x0d2cf6ab),
-+     TOBN(0xb90bc03f, 0xcc054de5), TOBN(0x932811a7, 0x18b06350),
-+     TOBN(0x2f00b330, 0x9bbd11ff), TOBN(0x76108a6f, 0xb4044974),
-+     TOBN(0x801bb9e0, 0xa851d266), TOBN(0x0dd099be, 0xbf8990c1),
-+     TOBN(0x58c5aaaa, 0xabe32986), TOBN(0x0fe9dd2a, 0x50d59c27),
-+     TOBN(0x84951ff4, 0x8d307305), TOBN(0x6c23f829, 0x86529b78),
-+     TOBN(0x50bb2218, 0x0b136a79), TOBN(0x7e2174de, 0x77a20996),
-+     TOBN(0x6f00a4b9, 0xc0bb4da6), TOBN(0x89a25a17, 0xefdde8da),
-+     TOBN(0xf728a27e, 0xc11ee01d), TOBN(0xf900553a, 0xe5f10dfb),
-+     TOBN(0x189a83c8, 0x02ec893c), TOBN(0x3ca5bdc1, 0x23f66d77),
-+     TOBN(0x98781537, 0x97eada9f), TOBN(0x59c50ab3, 0x10256230),
-+     TOBN(0x346042d9, 0x323c69b3), TOBN(0x1b715a6d, 0x2c460449),
-+     TOBN(0xa41dd476, 0x6ae06e0b), TOBN(0xcdd7888e, 0x9d42e25f),
-+     TOBN(0x0f395f74, 0x56b25a20), TOBN(0xeadfe0ae, 0x8700e27e),
-+     TOBN(0xb09d52a9, 0x69950093), TOBN(0x3525d9cb, 0x327f8d40),
-+     TOBN(0xb8235a94, 0x67df886a), TOBN(0x77e4b0dd, 0x035faec2),
-+     TOBN(0x115eb20a, 0x517d7061), TOBN(0x77fe3433, 0x6c2df683),
-+     TOBN(0x6870ddc7, 0xcdc6fc67), TOBN(0xb1610588, 0x0b87de83),
-+     TOBN(0x343584ca, 0xd9c4ddbe), TOBN(0xb3164f1c, 0x3d754be2),
-+     TOBN(0x0731ed3a, 0xc1e6c894), TOBN(0x26327dec, 0x4f6b904c),
-+     TOBN(0x9d49c6de, 0x97b5cd32), TOBN(0x40835dae, 0xb5eceecd),
-+     TOBN(0xc66350ed, 0xd9ded7fe), TOBN(0x8aeebb5c, 0x7a678804),
-+     TOBN(0x51d42fb7, 0x5b8ee9ec), TOBN(0xd7a17bdd, 0x8e3ca118),
-+     TOBN(0x40d7511a, 0x2ef4400e), TOBN(0xc48990ac, 0x875a66f4),
-+     TOBN(0x8de07d2a, 0x2199e347), TOBN(0xbee75556, 0x2a39e051),
-+     TOBN(0x56918786, 0x916e51dc), TOBN(0xeb191313, 0x4a2d89ec),
-+     TOBN(0x6679610d, 0x37d341ed), TOBN(0x434fbb41, 0x56d51c2b),
-+     TOBN(0xe54b7ee7, 0xd7492dba), TOBN(0xaa33a79a, 0x59021493),
-+     TOBN(0x49fc5054, 0xe4bd6d3d), TOBN(0x09540f04, 0x5ab551d0),
-+     TOBN(0x8acc9085, 0x4942d3a6), TOBN(0x231af02f, 0x2d28323b),
-+     TOBN(0x93458cac, 0x0992c163), TOBN(0x1fef8e71, 0x888e3bb4),
-+     TOBN(0x27578da5, 0xbe8c268c), TOBN(0xcc8be792, 0xe805ec00),
-+     TOBN(0x29267bae, 0xc61c3855), TOBN(0xebff429d, 0x58c1fd3b),
-+     TOBN(0x22d886c0, 0x8c0b93b8), TOBN(0xca5e00b2, 0x2ddb8953),
-+     TOBN(0xcf330117, 0xc3fed8b7), TOBN(0xd49ac6fa, 0x819c01f6),
-+     TOBN(0x6ddaa6bd, 0x3c0fbd54), TOBN(0x91743068, 0x8049a2cf),
-+     TOBN(0xd67f981e, 0xaff2ef81), TOBN(0xc3654d35, 0x2818ae80),
-+     TOBN(0x81d05044, 0x1b2aa892), TOBN(0x2db067bf, 0x3d099328),
-+     TOBN(0xe7c79e86, 0x703dcc97), TOBN(0xe66f9b37, 0xe133e215),
-+     TOBN(0xcdf119a6, 0xe39a7a5c), TOBN(0x47c60de3, 0x876f1b61),
-+     TOBN(0x6e405939, 0xd860f1b2), TOBN(0x3e9a1dbc, 0xf5ed4d4a),
-+     TOBN(0x3f23619e, 0xc9b6bcbd), TOBN(0x5ee790cf, 0x734e4497),
-+     TOBN(0xf0a834b1, 0x5bdaf9bb), TOBN(0x02cedda7, 0x4ca295f0),
-+     TOBN(0x4619aa2b, 0xcb8e378c), TOBN(0xe5613244, 0xcc987ea4),
-+     TOBN(0x0bc022cc, 0x76b23a50), TOBN(0x4a2793ad, 0x0a6c21ce),
-+     TOBN(0x38328780, 0x89cac3f5), TOBN(0x29176f1b, 0xcba26d56),
-+     TOBN(0x06296187, 0x4f6f59eb), TOBN(0x86e9bca9, 0x8bdc658e),
-+     TOBN(0x2ca9c4d3, 0x57e30402), TOBN(0x5438b216, 0x516a09bb),
-+     TOBN(0x0a6a063c, 0x7672765a), TOBN(0x37a3ce64, 0x0547b9bf),
-+     TOBN(0x42c099c8, 0x98b1a633), TOBN(0xb5ab800d, 0x05ee6961),
-+     TOBN(0xf1963f59, 0x11a5acd6), TOBN(0xbaee6157, 0x46201063),
-+     TOBN(0x36d9a649, 0xa596210a), TOBN(0xaed04363, 0x1ba7138c),
-+     TOBN(0xcf817d1c, 0xa4a82b76), TOBN(0x5586960e, 0xf3806be9),
-+     TOBN(0x7ab67c89, 0x09dc6bb5), TOBN(0x52ace7a0, 0x114fe7eb),
-+     TOBN(0xcd987618, 0xcbbc9b70), TOBN(0x4f06fd5a, 0x604ca5e1),
-+     TOBN(0x90af14ca, 0x6dbde133), TOBN(0x1afe4322, 0x948a3264),
-+     TOBN(0xa70d2ca6, 0xc44b2c6c), TOBN(0xab726799, 0x0ef87dfe),
-+     TOBN(0x310f64dc, 0x2e696377), TOBN(0x49b42e68, 0x4c8126a0),
-+     TOBN(0x0ea444c3, 0xcea0b176), TOBN(0x53a8ddf7, 0xcb269182),
-+     TOBN(0xf3e674eb, 0xbbba9dcb), TOBN(0x0d2878a8, 0xd8669d33),
-+     TOBN(0x04b935d5, 0xd019b6a3), TOBN(0xbb5cf88e, 0x406f1e46),
-+     TOBN(0xa1912d16, 0x5b57c111), TOBN(0x9803fc21, 0x19ebfd78),
-+     TOBN(0x4f231c9e, 0xc07764a9), TOBN(0xd93286ee, 0xb75bd055),
-+     TOBN(0x83a9457d, 0x8ee6c9de), TOBN(0x04695915, 0x6087ec90),
-+     TOBN(0x14c6dd8a, 0x58d6cd46), TOBN(0x9cb633b5, 0x8e6634d2),
-+     TOBN(0xc1305047, 0xf81bc328), TOBN(0x12ede0e2, 0x26a177e5),
-+     TOBN(0x332cca62, 0x065a6f4f), TOBN(0xc3a47ecd, 0x67be487b),
-+     TOBN(0x741eb187, 0x0f47ed1c), TOBN(0x99e66e58, 0xe7598b14),
-+     TOBN(0x6f0544ca, 0x63d0ff12), TOBN(0xe5efc784, 0xb610a05f),
-+     TOBN(0xf72917b1, 0x7cad7b47), TOBN(0x3ff6ea20, 0xf2cac0c0),
-+     TOBN(0xcc23791b, 0xf21db8b7), TOBN(0x7dac70b1, 0xd7d93565),
-+     TOBN(0x682cda1d, 0x694bdaad), TOBN(0xeb88bb8c, 0x1023516d),
-+     TOBN(0xc4c634b4, 0xdfdbeb1b), TOBN(0x22f5ca72, 0xb4ee4dea),
-+     TOBN(0x1045a368, 0xe6524821), TOBN(0xed9e8a3f, 0x052b18b2),
-+     TOBN(0x9b7f2cb1, 0xb961f49a), TOBN(0x7fee2ec1, 0x7b009670),
-+     TOBN(0x350d8754, 0x22507a6d), TOBN(0x561bd711, 0x4db55f1d),
-+     TOBN(0x4c189ccc, 0x320bbcaf), TOBN(0x568434cf, 0xdf1de48c),
-+     TOBN(0x6af1b00e, 0x0fa8f128), TOBN(0xf0ba9d02, 0x8907583c),
-+     TOBN(0x735a4004, 0x32ff9f60), TOBN(0x3dd8e4b6, 0xc25dcf33),
-+     TOBN(0xf2230f16, 0x42c74cef), TOBN(0xd8117623, 0x013fa8ad),
-+     TOBN(0x36822876, 0xf51fe76e), TOBN(0x8a6811cc, 0x11d62589),
-+     TOBN(0xc3fc7e65, 0x46225718), TOBN(0xb7df2c9f, 0xc82fdbcd),
-+     TOBN(0x3b1d4e52, 0xdd7b205b), TOBN(0xb6959478, 0x47a2e414),
-+     TOBN(0x05e4d793, 0xefa91148), TOBN(0xb47ed446, 0xfd2e9675),
-+     TOBN(0x1a7098b9, 0x04c9d9bf), TOBN(0x661e2881, 0x1b793048),
-+     TOBN(0xb1a16966, 0xb01ee461), TOBN(0xbc521308, 0x2954746f),
-+     TOBN(0xc909a0fc, 0x2477de50), TOBN(0xd80bb41c, 0x7dbd51ef),
-+     TOBN(0xa85be7ec, 0x53294905), TOBN(0x6d465b18, 0x83958f97),
-+     TOBN(0x16f6f330, 0xfb6840fd), TOBN(0xfaaeb214, 0x3401e6c8),
-+     TOBN(0xaf83d30f, 0xccb5b4f8), TOBN(0x22885739, 0x266dec4b),
-+     TOBN(0x51b4367c, 0x7bc467df), TOBN(0x926562e3, 0xd842d27a),
-+     TOBN(0xdfcb6614, 0x0fea14a6), TOBN(0xeb394dae, 0xf2734cd9),
-+     TOBN(0x3eeae5d2, 0x11c0be98), TOBN(0xb1e6ed11, 0x814e8165),
-+     TOBN(0x191086bc, 0xe52bce1c), TOBN(0x14b74cc6, 0xa75a04da),
-+     TOBN(0x63cf1186, 0x8c060985), TOBN(0x071047de, 0x2dbd7f7c),
-+     TOBN(0x4e433b8b, 0xce0942ca), TOBN(0xecbac447, 0xd8fec61d),
-+     TOBN(0x8f0ed0e2, 0xebf3232f), TOBN(0xfff80f9e, 0xc52a2edd),
-+     TOBN(0xad9ab433, 0x75b55fdb), TOBN(0x73ca7820, 0xe42e0c11),
-+     TOBN(0x6dace0a0, 0xe6251b46), TOBN(0x89bc6b5c, 0x4c0d932d),
-+     TOBN(0x3438cd77, 0x095da19a), TOBN(0x2f24a939, 0x8d48bdfb),
-+     TOBN(0x99b47e46, 0x766561b7), TOBN(0x736600e6, 0x0ed0322a),
-+     TOBN(0x06a47cb1, 0x638e1865), TOBN(0x927c1c2d, 0xcb136000),
-+     TOBN(0x29542337, 0x0cc5df69), TOBN(0x99b37c02, 0x09d649a9),
-+     TOBN(0xc5f0043c, 0x6aefdb27), TOBN(0x6cdd9987, 0x1be95c27),
-+     TOBN(0x69850931, 0x390420d2), TOBN(0x299c40ac, 0x0983efa4),
-+     TOBN(0x3a05e778, 0xaf39aead), TOBN(0x84274408, 0x43a45193),
-+     TOBN(0x6bcd0fb9, 0x91a711a0), TOBN(0x461592c8, 0x9f52ab17),
-+     TOBN(0xb49302b4, 0xda3c6ed6), TOBN(0xc51fddc7, 0x330d7067),
-+     TOBN(0x94babeb6, 0xda50d531), TOBN(0x521b840d, 0xa6a7b9da),
-+     TOBN(0x5305151e, 0x404bdc89), TOBN(0x1bcde201, 0xd0d07449),
-+     TOBN(0xf427a78b, 0x3b76a59a), TOBN(0xf84841ce, 0x07791a1b),
-+     TOBN(0xebd314be, 0xbf91ed1c), TOBN(0x8e61d34c, 0xbf172943),
-+     TOBN(0x1d5dc451, 0x5541b892), TOBN(0xb186ee41, 0xfc9d9e54),
-+     TOBN(0x9d9f345e, 0xd5bf610d), TOBN(0x3e7ba65d, 0xf6acca9f),
-+     TOBN(0x9dda787a, 0xa8369486), TOBN(0x09f9dab7, 0x8eb5ba53),
-+     TOBN(0x5afb2033, 0xd6481bc3), TOBN(0x76f4ce30, 0xafa62104),
-+     TOBN(0xa8fa00cf, 0xf4f066b5), TOBN(0x89ab5143, 0x461dafc2),
-+     TOBN(0x44339ed7, 0xa3389998), TOBN(0x2ff862f1, 0xbc214903),
-+     TOBN(0x2c88f985, 0xb05556e3), TOBN(0xcd96058e, 0x3467081e),
-+     TOBN(0x7d6a4176, 0xedc637ea), TOBN(0xe1743d09, 0x36a5acdc),
-+     TOBN(0x66fd72e2, 0x7eb37726), TOBN(0xf7fa264e, 0x1481a037),
-+     TOBN(0x9fbd3bde, 0x45f4aa79), TOBN(0xed1e0147, 0x767c3e22),
-+     TOBN(0x7621f979, 0x82e7abe2), TOBN(0x19eedc72, 0x45f633f8),
-+     TOBN(0xe69b155e, 0x6137bf3a), TOBN(0xa0ad13ce, 0x414ee94e),
-+     TOBN(0x93e3d524, 0x1c0e651a), TOBN(0xab1a6e2a, 0x02ce227e),
-+     TOBN(0xe7af1797, 0x4ab27eca), TOBN(0x245446de, 0xbd444f39),
-+     TOBN(0x59e22a21, 0x56c07613), TOBN(0x43deafce, 0xf4275498),
-+     TOBN(0x10834ccb, 0x67fd0946), TOBN(0xa75841e5, 0x47406edf),
-+     TOBN(0xebd6a677, 0x7b0ac93d), TOBN(0xa6e37b0d, 0x78f5e0d7),
-+     TOBN(0x2516c096, 0x76f5492b), TOBN(0x1e4bf888, 0x9ac05f3a),
-+     TOBN(0xcdb42ce0, 0x4df0ba2b), TOBN(0x935d5cfd, 0x5062341b),
-+     TOBN(0x8a303333, 0x82acac20), TOBN(0x429438c4, 0x5198b00e),
-+     TOBN(0x1d083bc9, 0x049d33fa), TOBN(0x58b82dda, 0x946f67ff),
-+     TOBN(0xac3e2db8, 0x67a1d6a3), TOBN(0x62e6bead, 0x1798aac8),
-+     TOBN(0xfc85980f, 0xde46c58c), TOBN(0xa7f69379, 0x69c8d7be),
-+     TOBN(0x23557927, 0x837b35ec), TOBN(0x06a933d8, 0xe0790c0c),
-+     TOBN(0x827c0e9b, 0x077ff55d), TOBN(0x53977798, 0xbb26e680),
-+     TOBN(0x59530874, 0x1d9cb54f), TOBN(0xcca3f449, 0x4aac53ef),
-+     TOBN(0x11dc5c87, 0xa07eda0f), TOBN(0xc138bccf, 0xfd6400c8),
-+     TOBN(0x549680d3, 0x13e5da72), TOBN(0xc93eed82, 0x4540617e),
-+     TOBN(0xfd3db157, 0x4d0b75c0), TOBN(0x9716eb42, 0x6386075b),
-+     TOBN(0x0639605c, 0x817b2c16), TOBN(0x09915109, 0xf1e4f201),
-+     TOBN(0x35c9a928, 0x5cca6c3b), TOBN(0xb25f7d1a, 0x3505c900),
-+     TOBN(0xeb9f7d20, 0x630480c4), TOBN(0xc3c7b8c6, 0x2a1a501c),
-+     TOBN(0x3f99183c, 0x5a1f8e24), TOBN(0xfdb118fa, 0x9dd255f0),
-+     TOBN(0xb9b18b90, 0xc27f62a6), TOBN(0xe8f732f7, 0x396ec191),
-+     TOBN(0x524a2d91, 0x0be786ab), TOBN(0x5d32adef, 0x0ac5a0f5),
-+     TOBN(0x9b53d4d6, 0x9725f694), TOBN(0x032a76c6, 0x0510ba89),
-+     TOBN(0x840391a3, 0xebeb1544), TOBN(0x44b7b88c, 0x3ed73ac3),
-+     TOBN(0xd24bae7a, 0x256cb8b3), TOBN(0x7ceb151a, 0xe394cb12),
-+     TOBN(0xbd6b66d0, 0x5bc1e6a8), TOBN(0xec70cecb, 0x090f07bf),
-+     TOBN(0x270644ed, 0x7d937589), TOBN(0xee9e1a3d, 0x5f1dccfe),
-+     TOBN(0xb0d40a84, 0x745b98d2), TOBN(0xda429a21, 0x2556ed40),
-+     TOBN(0xf676eced, 0x85148cb9), TOBN(0x5a22d40c, 0xded18936),
-+     TOBN(0x3bc4b9e5, 0x70e8a4ce), TOBN(0xbfd1445b, 0x9eae0379),
-+     TOBN(0xf23f2c0c, 0x1a0bd47e), TOBN(0xa9c0bb31, 0xe1845531),
-+     TOBN(0x9ddc4d60, 0x0a4c3f6b), TOBN(0xbdfaad79, 0x2c15ef44),
-+     TOBN(0xce55a236, 0x7f484acc), TOBN(0x08653ca7, 0x055b1f15),
-+     TOBN(0x2efa8724, 0x538873a3), TOBN(0x09299e5d, 0xace1c7e7),
-+     TOBN(0x07afab66, 0xade332ba), TOBN(0x9be1fdf6, 0x92dd71b7),
-+     TOBN(0xa49b5d59, 0x5758b11c), TOBN(0x0b852893, 0xc8654f40),
-+     TOBN(0xb63ef6f4, 0x52379447), TOBN(0xd4957d29, 0x105e690c),
-+     TOBN(0x7d484363, 0x646559b0), TOBN(0xf4a8273c, 0x49788a8e),
-+     TOBN(0xee406cb8, 0x34ce54a9), TOBN(0x1e1c260f, 0xf86fda9b),
-+     TOBN(0xe150e228, 0xcf6a4a81), TOBN(0x1fa3b6a3, 0x1b488772),
-+     TOBN(0x1e6ff110, 0xc5a9c15b), TOBN(0xc6133b91, 0x8ad6aa47),
-+     TOBN(0x8ac5d55c, 0x9dffa978), TOBN(0xba1d1c1d, 0x5f3965f2),
-+     TOBN(0xf969f4e0, 0x7732b52f), TOBN(0xfceecdb5, 0xa5172a07),
-+     TOBN(0xb0120a5f, 0x10f2b8f5), TOBN(0xc83a6cdf, 0x5c4c2f63),
-+     TOBN(0x4d47a491, 0xf8f9c213), TOBN(0xd9e1cce5, 0xd3f1bbd5),
-+     TOBN(0x0d91bc7c, 0xaba7e372), TOBN(0xfcdc74c8, 0xdfd1a2db),
-+     TOBN(0x05efa800, 0x374618e5), TOBN(0x11216969, 0x15a7925e),
-+     TOBN(0xd4c89823, 0xf6021c5d), TOBN(0x880d5e84, 0xeff14423),
-+     TOBN(0x6523bc5a, 0x6dcd1396), TOBN(0xd1acfdfc, 0x113c978b),
-+     TOBN(0xb0c164e8, 0xbbb66840), TOBN(0xf7f4301e, 0x72b58459),
-+     TOBN(0xc29ad4a6, 0xa638e8ec), TOBN(0xf5ab8961, 0x46b78699),
-+     TOBN(0x9dbd7974, 0x0e954750), TOBN(0x0121de88, 0x64f9d2c6),
-+     TOBN(0x2e597b42, 0xd985232e), TOBN(0x55b6c3c5, 0x53451777),
-+     TOBN(0xbb53e547, 0x519cb9fb), TOBN(0xf134019f, 0x8428600d),
-+     TOBN(0x5a473176, 0xe081791a), TOBN(0x2f3e2263, 0x35fb0c08),
-+     TOBN(0xb28c3017, 0x73d273b0), TOBN(0xccd21076, 0x7721ef9a),
-+     TOBN(0x054cc292, 0xb650dc39), TOBN(0x662246de, 0x6188045e),
-+     TOBN(0x904b52fa, 0x6b83c0d1), TOBN(0xa72df267, 0x97e9cd46),
-+     TOBN(0x886b43cd, 0x899725e4), TOBN(0x2b651688, 0xd849ff22),
-+     TOBN(0x60479b79, 0x02f34533), TOBN(0x5e354c14, 0x0c77c148),
-+     TOBN(0xb4bb7581, 0xa8537c78), TOBN(0x188043d7, 0xefe1495f),
-+     TOBN(0x9ba12f42, 0x8c1d5026), TOBN(0x2e0c8a26, 0x93d4aaab),
-+     TOBN(0xbdba7b8b, 0xaa57c450), TOBN(0x140c9ad6, 0x9bbdafef),
-+     TOBN(0x2067aa42, 0x25ac0f18), TOBN(0xf7b1295b, 0x04d1fbf3),
-+     TOBN(0x14829111, 0xa4b04824), TOBN(0x2ce3f192, 0x33bd5e91),
-+     TOBN(0x9c7a1d55, 0x8f2e1b72), TOBN(0xfe932286, 0x302aa243),
-+     TOBN(0x497ca7b4, 0xd4be9554), TOBN(0xb8e821b8, 0xe0547a6e),
-+     TOBN(0xfb2838be, 0x67e573e0), TOBN(0x05891db9, 0x4084c44b),
-+     TOBN(0x91311373, 0x96c1c2c5), TOBN(0x6aebfa3f, 0xd958444b),
-+     TOBN(0xac9cdce9, 0xe56e55c1), TOBN(0x7148ced3, 0x2caa46d0),
-+     TOBN(0x2e10c7ef, 0xb61fe8eb), TOBN(0x9fd835da, 0xff97cf4d),}
-+    ,
-+    {TOBN(0xa36da109, 0x081e9387), TOBN(0xfb9780d7, 0x8c935828),
-+     TOBN(0xd5940332, 0xe540b015), TOBN(0xc9d7b51b, 0xe0f466fa),
-+     TOBN(0xfaadcd41, 0xd6d9f671), TOBN(0xba6c1e28, 0xb1a2ac17),
-+     TOBN(0x066a7833, 0xed201e5f), TOBN(0x19d99719, 0xf90f462b),
-+     TOBN(0xf431f462, 0x060b5f61), TOBN(0xa56f46b4, 0x7bd057c2),
-+     TOBN(0x348dca6c, 0x47e1bf65), TOBN(0x9a38783e, 0x41bcf1ff),
-+     TOBN(0x7a5d33a9, 0xda710718), TOBN(0x5a779987, 0x2e0aeaf6),
-+     TOBN(0xca87314d, 0x2d29d187), TOBN(0xfa0edc3e, 0xc687d733),
-+     TOBN(0x9df33621, 0x6a31e09b), TOBN(0xde89e44d, 0xc1350e35),
-+     TOBN(0x29214871, 0x4ca0cf52), TOBN(0xdf379672, 0x0b88a538),
-+     TOBN(0xc92a510a, 0x2591d61b), TOBN(0x79aa87d7, 0x585b447b),
-+     TOBN(0xf67db604, 0xe5287f77), TOBN(0x1697c8bf, 0x5efe7a80),
-+     TOBN(0x1c894849, 0xcb198ac7), TOBN(0xa884a93d, 0x0f264665),
-+     TOBN(0x2da964ef, 0x9b200678), TOBN(0x3c351b87, 0x009834e6),
-+     TOBN(0xafb2ef9f, 0xe2c4b44b), TOBN(0x580f6c47, 0x3326790c),
-+     TOBN(0xb8480521, 0x0b02264a), TOBN(0x8ba6f9e2, 0x42a194e2),
-+     TOBN(0xfc87975f, 0x8fb54738), TOBN(0x35160788, 0x27c3ead3),
-+     TOBN(0x834116d2, 0xb74a085a), TOBN(0x53c99a73, 0xa62fe996),
-+     TOBN(0x87585be0, 0x5b81c51b), TOBN(0x925bafa8, 0xbe0852b7),
-+     TOBN(0x76a4fafd, 0xa84d19a7), TOBN(0x39a45982, 0x585206d4),
-+     TOBN(0x499b6ab6, 0x5eb03c0e), TOBN(0xf19b7954, 0x72bc3fde),
-+     TOBN(0xa86b5b9c, 0x6e3a80d2), TOBN(0xe4377508, 0x6d42819f),
-+     TOBN(0xc1663650, 0xbb3ee8a3), TOBN(0x75eb14fc, 0xb132075f),
-+     TOBN(0xa8ccc906, 0x7ad834f6), TOBN(0xea6a2474, 0xe6e92ffd),
-+     TOBN(0x9d72fd95, 0x0f8d6758), TOBN(0xcb84e101, 0x408c07dd),
-+     TOBN(0xb9114bfd, 0xa5e23221), TOBN(0x358b5fe2, 0xe94e742c),
-+     TOBN(0x1c0577ec, 0x95f40e75), TOBN(0xf0155451, 0x3d73f3d6),
-+     TOBN(0x9d55cd67, 0xbd1b9b66), TOBN(0x63e86e78, 0xaf8d63c7),
-+     TOBN(0x39d934ab, 0xd3c095f1), TOBN(0x04b261be, 0xe4b76d71),
-+     TOBN(0x1d2e6970, 0xe73e6984), TOBN(0x879fb23b, 0x5e5fcb11),
-+     TOBN(0x11506c72, 0xdfd75490), TOBN(0x3a97d085, 0x61bcf1c1),
-+     TOBN(0x43201d82, 0xbf5e7007), TOBN(0x7f0ac52f, 0x798232a7),
-+     TOBN(0x2715cbc4, 0x6eb564d4), TOBN(0x8d6c752c, 0x9e570e29),
-+     TOBN(0xf80247c8, 0x9ef5fd5d), TOBN(0xc3c66b46, 0xd53eb514),
-+     TOBN(0x9666b401, 0x0f87de56), TOBN(0xce62c06f, 0xc6c603b5),
-+     TOBN(0xae7b4c60, 0x7e4fc942), TOBN(0x38ac0b77, 0x663a9c19),
-+     TOBN(0xcb4d20ee, 0x4b049136), TOBN(0x8b63bf12, 0x356a4613),
-+     TOBN(0x1221aef6, 0x70e08128), TOBN(0xe62d8c51, 0x4acb6b16),
-+     TOBN(0x71f64a67, 0x379e7896), TOBN(0xb25237a2, 0xcafd7fa5),
-+     TOBN(0xf077bd98, 0x3841ba6a), TOBN(0xc4ac0244, 0x3cd16e7e),
-+     TOBN(0x548ba869, 0x21fea4ca), TOBN(0xd36d0817, 0xf3dfdac1),
-+     TOBN(0x09d8d71f, 0xf4685faf), TOBN(0x8eff66be, 0xc52c459a),
-+     TOBN(0x182faee7, 0x0b57235e), TOBN(0xee3c39b1, 0x0106712b),
-+     TOBN(0x5107331f, 0xc0fcdcb0), TOBN(0x669fb9dc, 0xa51054ba),
-+     TOBN(0xb25101fb, 0x319d7682), TOBN(0xb0293129, 0x0a982fee),
-+     TOBN(0x51c1c9b9, 0x0261b344), TOBN(0x0e008c5b, 0xbfd371fa),
-+     TOBN(0xd866dd1c, 0x0278ca33), TOBN(0x666f76a6, 0xe5aa53b1),
-+     TOBN(0xe5cfb779, 0x6013a2cf), TOBN(0x1d3a1aad, 0xa3521836),
-+     TOBN(0xcedd2531, 0x73faa485), TOBN(0xc8ee6c4f, 0xc0a76878),
-+     TOBN(0xddbccfc9, 0x2a11667d), TOBN(0x1a418ea9, 0x1c2f695a),
-+     TOBN(0xdb11bd92, 0x51f73971), TOBN(0x3e4b3c82, 0xda2ed89f),
-+     TOBN(0x9a44f3f4, 0xe73e0319), TOBN(0xd1e3de0f, 0x303431af),
-+     TOBN(0x3c5604ff, 0x50f75f9c), TOBN(0x1d8eddf3, 0x7e752b22),
-+     TOBN(0x0ef074dd, 0x3c9a1118), TOBN(0xd0ffc172, 0xccb86d7b),
-+     TOBN(0xabd1ece3, 0x037d90f2), TOBN(0xe3f307d6, 0x6055856c),
-+     TOBN(0x422f9328, 0x7e4c6daf), TOBN(0x902aac66, 0x334879a0),
-+     TOBN(0xb6a1e7bf, 0x94cdfade), TOBN(0x6c97e1ed, 0x7fc6d634),
-+     TOBN(0x662ad24d, 0xa2fb63f8), TOBN(0xf81be1b9, 0xa5928405),
-+     TOBN(0x86d765e4, 0xd14b4206), TOBN(0xbecc2e0e, 0x8fa0db65),
-+     TOBN(0xa28838e0, 0xb17fc76c), TOBN(0xe49a602a, 0xe37cf24e),
-+     TOBN(0x76b4131a, 0x567193ec), TOBN(0xaf3c305a, 0xe5f6e70b),
-+     TOBN(0x9587bd39, 0x031eebdd), TOBN(0x5709def8, 0x71bbe831),
-+     TOBN(0x57059983, 0x0eb2b669), TOBN(0x4d80ce1b, 0x875b7029),
-+     TOBN(0x838a7da8, 0x0364ac16), TOBN(0x2f431d23, 0xbe1c83ab),
-+     TOBN(0xe56812a6, 0xf9294dd3), TOBN(0xb448d01f, 0x9b4b0d77),
-+     TOBN(0xf3ae6061, 0x04e8305c), TOBN(0x2bead645, 0x94d8c63e),
-+     TOBN(0x0a85434d, 0x84fd8b07), TOBN(0x537b983f, 0xf7a9dee5),
-+     TOBN(0xedcc5f18, 0xef55bd85), TOBN(0x2041af62, 0x21c6cf8b),
-+     TOBN(0x8e52874c, 0xb940c71e), TOBN(0x211935a9, 0xdb5f4b3a),
-+     TOBN(0x94350492, 0x301b1dc3), TOBN(0x33d2646d, 0x29958620),
-+     TOBN(0x16b0d64b, 0xef911404), TOBN(0x9d1f25ea, 0x9a3c5ef4),
-+     TOBN(0x20f200eb, 0x4a352c78), TOBN(0x43929f2c, 0x4bd0b428),
-+     TOBN(0xa5656667, 0xc7196e29), TOBN(0x7992c2f0, 0x9391be48),
-+     TOBN(0xaaa97cbd, 0x9ee0cd6e), TOBN(0x51b0310c, 0x3dc8c9bf),
-+     TOBN(0x237f8acf, 0xdd9f22cb), TOBN(0xbb1d81a1, 0xb585d584),
-+     TOBN(0x8d5d85f5, 0x8c416388), TOBN(0x0d6e5a5a, 0x42fe474f),
-+     TOBN(0xe7812766, 0x38235d4e), TOBN(0x1c62bd67, 0x496e3298),
-+     TOBN(0x8378660c, 0x3f175bc8), TOBN(0x4d04e189, 0x17afdd4d),
-+     TOBN(0x32a81601, 0x85a8068c), TOBN(0xdb58e4e1, 0x92b29a85),
-+     TOBN(0xe8a65b86, 0xc70d8a3b), TOBN(0x5f0e6f4e, 0x98a0403b),
-+     TOBN(0x08129684, 0x69ed2370), TOBN(0x34dc30bd, 0x0871ee26),
-+     TOBN(0x3a5ce948, 0x7c9c5b05), TOBN(0x7d487b80, 0x43a90c87),
-+     TOBN(0x4089ba37, 0xdd0e7179), TOBN(0x45f80191, 0xb4041811),
-+     TOBN(0x1c3e1058, 0x98747ba5), TOBN(0x98c4e13a, 0x6e1ae592),
-+     TOBN(0xd44636e6, 0xe82c9f9e), TOBN(0x711db87c, 0xc33a1043),
-+     TOBN(0x6f431263, 0xaa8aec05), TOBN(0x43ff120d, 0x2744a4aa),
-+     TOBN(0xd3bd892f, 0xae77779b), TOBN(0xf0fe0cc9, 0x8cdc9f82),
-+     TOBN(0xca5f7fe6, 0xf1c5b1bc), TOBN(0xcc63a682, 0x44929a72),
-+     TOBN(0xc7eaba0c, 0x09dbe19a), TOBN(0x2f3585ad, 0x6b5c73c2),
-+     TOBN(0x8ab8924b, 0x0ae50c30), TOBN(0x17fcd27a, 0x638b30ba),
-+     TOBN(0xaf414d34, 0x10b3d5a5), TOBN(0x09c107d2, 0x2a9accf1),
-+     TOBN(0x15dac49f, 0x946a6242), TOBN(0xaec3df2a, 0xd707d642),
-+     TOBN(0x2c2492b7, 0x3f894ae0), TOBN(0xf59df3e5, 0xb75f18ce),
-+     TOBN(0x7cb740d2, 0x8f53cad0), TOBN(0x3eb585fb, 0xc4f01294),
-+     TOBN(0x17da0c86, 0x32c7f717), TOBN(0xeb8c795b, 0xaf943f4c),
-+     TOBN(0x4ee23fb5, 0xf67c51d2), TOBN(0xef187575, 0x68889949),
-+     TOBN(0xa6b4bdb2, 0x0389168b), TOBN(0xc4ecd258, 0xea577d03),
-+     TOBN(0x3a63782b, 0x55743082), TOBN(0x6f678f4c, 0xc72f08cd),
-+     TOBN(0x553511cf, 0x65e58dd8), TOBN(0xd53b4e3e, 0xd402c0cd),
-+     TOBN(0x37de3e29, 0xa037c14c), TOBN(0x86b6c516, 0xc05712aa),
-+     TOBN(0x2834da3e, 0xb38dff6f), TOBN(0xbe012c52, 0xea636be8),
-+     TOBN(0x292d238c, 0x61dd37f8), TOBN(0x0e54523f, 0x8f8142db),
-+     TOBN(0xe31eb436, 0x036a05d8), TOBN(0x83e3cdff, 0x1e93c0ff),
-+     TOBN(0x3fd2fe0f, 0x50821ddf), TOBN(0xc8e19b0d, 0xff9eb33b),
-+     TOBN(0xc8cc943f, 0xb569a5fe), TOBN(0xad0090d4, 0xd4342d75),
-+     TOBN(0x82090b4b, 0xcaeca000), TOBN(0xca39687f, 0x1bd410eb),
-+     TOBN(0xe7bb0df7, 0x65959d77), TOBN(0x39d78218, 0x9c964999),
-+     TOBN(0xd87f62e8, 0xb2415451), TOBN(0xe5efb774, 0xbed76108),
-+     TOBN(0x3ea011a4, 0xe822f0d0), TOBN(0xbc647ad1, 0x5a8704f8),
-+     TOBN(0xbb315b35, 0x50c6820f), TOBN(0x863dec3d, 0xb7e76bec),
-+     TOBN(0x01ff5d3a, 0xf017bfc7), TOBN(0x20054439, 0x976b8229),
-+     TOBN(0x067fca37, 0x0bbd0d3b), TOBN(0xf63dde64, 0x7f5e3d0f),
-+     TOBN(0x22dbefb3, 0x2a4c94e9), TOBN(0xafbff0fe, 0x96f8278a),
-+     TOBN(0x80aea0b1, 0x3503793d), TOBN(0xb2238029, 0x5f06cd29),
-+     TOBN(0x65703e57, 0x8ec3feca), TOBN(0x06c38314, 0x393e7053),
-+     TOBN(0xa0b751eb, 0x7c6734c4), TOBN(0xd2e8a435, 0xc59f0f1e),
-+     TOBN(0x147d9052, 0x5e9ca895), TOBN(0x2f4dd31e, 0x972072df),
-+     TOBN(0xa16fda8e, 0xe6c6755c), TOBN(0xc66826ff, 0xcf196558),
-+     TOBN(0x1f1a76a3, 0x0cf43895), TOBN(0xa9d604e0, 0x83c3097b),
-+     TOBN(0xe1908309, 0x66390e0e), TOBN(0xa50bf753, 0xb3c85eff),
-+     TOBN(0x0696bdde, 0xf6a70251), TOBN(0x548b801b, 0x3c6ab16a),
-+     TOBN(0x37fcf704, 0xa4d08762), TOBN(0x090b3def, 0xdff76c4e),
-+     TOBN(0x87e8cb89, 0x69cb9158), TOBN(0x44a90744, 0x995ece43),
-+     TOBN(0xf85395f4, 0x0ad9fbf5), TOBN(0x49b0f6c5, 0x4fb0c82d),
-+     TOBN(0x75d9bc15, 0xadf7cccf), TOBN(0x81a3e5d6, 0xdfa1e1b0),
-+     TOBN(0x8c39e444, 0x249bc17e), TOBN(0xf37dccb2, 0x8ea7fd43),
-+     TOBN(0xda654873, 0x907fba12), TOBN(0x35daa6da, 0x4a372904),
-+     TOBN(0x0564cfc6, 0x6283a6c5), TOBN(0xd09fa4f6, 0x4a9395bf),
-+     TOBN(0x688e9ec9, 0xaeb19a36), TOBN(0xd913f1ce, 0xc7bfbfb4),
-+     TOBN(0x797b9a3c, 0x61c2faa6), TOBN(0x2f979bec, 0x6a0a9c12),
-+     TOBN(0xb5969d0f, 0x359679ec), TOBN(0xebcf523d, 0x079b0460),
-+     TOBN(0xfd6b0008, 0x10fab870), TOBN(0x3f2edcda, 0x9373a39c),
-+     TOBN(0x0d64f9a7, 0x6f568431), TOBN(0xf848c27c, 0x02f8898c),
-+     TOBN(0xf418ade1, 0x260b5bd5), TOBN(0xc1f3e323, 0x6973dee8),
-+     TOBN(0x46e9319c, 0x26c185dd), TOBN(0x6d85b7d8, 0x546f0ac4),
-+     TOBN(0x427965f2, 0x247f9d57), TOBN(0xb519b636, 0xb0035f48),
-+     TOBN(0x6b6163a9, 0xab87d59c), TOBN(0xff9f58c3, 0x39caaa11),
-+     TOBN(0x4ac39cde, 0x3177387b), TOBN(0x5f6557c2, 0x873e77f9),
-+     TOBN(0x67504006, 0x36a83041), TOBN(0x9b1c96ca, 0x75ef196c),
-+     TOBN(0xf34283de, 0xb08c7940), TOBN(0x7ea09644, 0x1128c316),
-+     TOBN(0xb510b3b5, 0x6aa39dff), TOBN(0x59b43da2, 0x9f8e4d8c),
-+     TOBN(0xa8ce31fd, 0x9e4c4b9f), TOBN(0x0e20be26, 0xc1303c01),
-+     TOBN(0x18187182, 0xe8ee47c9), TOBN(0xd9687cdb, 0x7db98101),
-+     TOBN(0x7a520e4d, 0xa1e14ff6), TOBN(0x429808ba, 0x8836d572),
-+     TOBN(0xa37ca60d, 0x4944b663), TOBN(0xf901f7a9, 0xa3f91ae5),
-+     TOBN(0xe4e3e76e, 0x9e36e3b1), TOBN(0x9aa219cf, 0x29d93250),
-+     TOBN(0x347fe275, 0x056a2512), TOBN(0xa4d643d9, 0xde65d95c),
-+     TOBN(0x9669d396, 0x699fc3ed), TOBN(0xb598dee2, 0xcf8c6bbe),
-+     TOBN(0x682ac1e5, 0xdda9e5c6), TOBN(0x4e0d3c72, 0xcaa9fc95),
-+     TOBN(0x17faaade, 0x772bea44), TOBN(0x5ef8428c, 0xab0009c8),
-+     TOBN(0xcc4ce47a, 0x460ff016), TOBN(0xda6d12bf, 0x725281cb),
-+     TOBN(0x44c67848, 0x0223aad2), TOBN(0x6e342afa, 0x36256e28),
-+     TOBN(0x1400bb0b, 0x93a37c04), TOBN(0x62b1bc9b, 0xdd10bd96),
-+     TOBN(0x7251adeb, 0x0dac46b7), TOBN(0x7d33b92e, 0x7be4ef51),
-+     TOBN(0x28b2a94b, 0xe61fa29a), TOBN(0x4b2be13f, 0x06422233),
-+     TOBN(0x36d6d062, 0x330d8d37), TOBN(0x5ef80e1e, 0xb28ca005),
-+     TOBN(0x174d4699, 0x6d16768e), TOBN(0x9fc4ff6a, 0x628bf217),
-+     TOBN(0x77705a94, 0x154e490d), TOBN(0x9d96dd28, 0x8d2d997a),
-+     TOBN(0x77e2d9d8, 0xce5d72c4), TOBN(0x9d06c5a4, 0xc11c714f),
-+     TOBN(0x02aa5136, 0x79e4a03e), TOBN(0x1386b3c2, 0x030ff28b),
-+     TOBN(0xfe82e8a6, 0xfb283f61), TOBN(0x7df203e5, 0xf3abc3fb),
-+     TOBN(0xeec7c351, 0x3a4d3622), TOBN(0xf7d17dbf, 0xdf762761),
-+     TOBN(0xc3956e44, 0x522055f0), TOBN(0xde3012db, 0x8fa748db),
-+     TOBN(0xca9fcb63, 0xbf1dcc14), TOBN(0xa56d9dcf, 0xbe4e2f3a),
-+     TOBN(0xb86186b6, 0x8bcec9c2), TOBN(0x7cf24df9, 0x680b9f06),
-+     TOBN(0xc46b45ea, 0xc0d29281), TOBN(0xfff42bc5, 0x07b10e12),
-+     TOBN(0x12263c40, 0x4d289427), TOBN(0x3d5f1899, 0xb4848ec4),
-+     TOBN(0x11f97010, 0xd040800c), TOBN(0xb4c5f529, 0x300feb20),
-+     TOBN(0xcc543f8f, 0xde94fdcb), TOBN(0xe96af739, 0xc7c2f05e),
-+     TOBN(0xaa5e0036, 0x882692e1), TOBN(0x09c75b68, 0x950d4ae9),
-+     TOBN(0x62f63df2, 0xb5932a7a), TOBN(0x2658252e, 0xde0979ad),
-+     TOBN(0x2a19343f, 0xb5e69631), TOBN(0x718c7501, 0x525b666b),
-+     TOBN(0x26a42d69, 0xea40dc3a), TOBN(0xdc84ad22, 0xaecc018f),
-+     TOBN(0x25c36c7b, 0x3270f04a), TOBN(0x46ba6d47, 0x50fa72ed),
-+     TOBN(0x6c37d1c5, 0x93e58a8e), TOBN(0xa2394731, 0x120c088c),
-+     TOBN(0xc3be4263, 0xcb6e86da), TOBN(0x2c417d36, 0x7126d038),
-+     TOBN(0x5b70f9c5, 0x8b6f8efa), TOBN(0x671a2faa, 0x37718536),
-+     TOBN(0xd3ced3c6, 0xb539c92b), TOBN(0xe56f1bd9, 0xa31203c2),
-+     TOBN(0x8b096ec4, 0x9ff3c8eb), TOBN(0x2deae432, 0x43491cea),
-+     TOBN(0x2465c6eb, 0x17943794), TOBN(0x5d267e66, 0x20586843),
-+     TOBN(0x9d3d116d, 0xb07159d0), TOBN(0xae07a67f, 0xc1896210),
-+     TOBN(0x8fc84d87, 0xbb961579), TOBN(0x30009e49, 0x1c1f8dd6),
-+     TOBN(0x8a8caf22, 0xe3132819), TOBN(0xcffa197c, 0xf23ab4ff),
-+     TOBN(0x58103a44, 0x205dd687), TOBN(0x57b796c3, 0x0ded67a2),
-+     TOBN(0x0b9c3a6c, 0xa1779ad7), TOBN(0xa33cfe2e, 0x357c09c5),
-+     TOBN(0x2ea29315, 0x3db4a57e), TOBN(0x91959695, 0x8ebeb52e),
-+     TOBN(0x118db9a6, 0xe546c879), TOBN(0x8e996df4, 0x6295c8d6),
-+     TOBN(0xdd990484, 0x55ec806b), TOBN(0x24f291ca, 0x165c1035),
-+     TOBN(0xcca523bb, 0x440e2229), TOBN(0x324673a2, 0x73ef4d04),
-+     TOBN(0xaf3adf34, 0x3e11ec39), TOBN(0x6136d7f1, 0xdc5968d3),
-+     TOBN(0x7a7b2899, 0xb053a927), TOBN(0x3eaa2661, 0xae067ecd),
-+     TOBN(0x8549b9c8, 0x02779cd9), TOBN(0x061d7940, 0xc53385ea),
-+     TOBN(0x3e0ba883, 0xf06d18bd), TOBN(0x4ba6de53, 0xb2700843),
-+     TOBN(0xb966b668, 0x591a9e4d), TOBN(0x93f67567, 0x7f4fa0ed),
-+     TOBN(0x5a02711b, 0x4347237b), TOBN(0xbc041e2f, 0xe794608e),
-+     TOBN(0x55af10f5, 0x70f73d8c), TOBN(0xd2d4d4f7, 0xbb7564f7),
-+     TOBN(0xd7d27a89, 0xb3e93ce7), TOBN(0xf7b5a875, 0x5d3a2c1b),
-+     TOBN(0xb29e68a0, 0x255b218a), TOBN(0xb533837e, 0x8af76754),
-+     TOBN(0xd1b05a73, 0x579fab2e), TOBN(0xb41055a1, 0xecd74385),
-+     TOBN(0xb2369274, 0x445e9115), TOBN(0x2972a7c4, 0xf520274e),
-+     TOBN(0x6c08334e, 0xf678e68a), TOBN(0x4e4160f0, 0x99b057ed),
-+     TOBN(0x3cfe11b8, 0x52ccb69a), TOBN(0x2fd1823a, 0x21c8f772),
-+     TOBN(0xdf7f072f, 0x3298f055), TOBN(0x8c0566f9, 0xfec74a6e),
-+     TOBN(0xe549e019, 0x5bb4d041), TOBN(0x7c3930ba, 0x9208d850),
-+     TOBN(0xe07141fc, 0xaaa2902b), TOBN(0x539ad799, 0xe4f69ad3),
-+     TOBN(0xa6453f94, 0x813f9ffd), TOBN(0xc58d3c48, 0x375bc2f7),
-+     TOBN(0xb3326fad, 0x5dc64e96), TOBN(0x3aafcaa9, 0xb240e354),
-+     TOBN(0x1d1b0903, 0xaca1e7a9), TOBN(0x4ceb9767, 0x1211b8a0),
-+     TOBN(0xeca83e49, 0xe32a858e), TOBN(0x4c32892e, 0xae907bad),
-+     TOBN(0xd5b42ab6, 0x2eb9b494), TOBN(0x7fde3ee2, 0x1eabae1b),
-+     TOBN(0x13b5ab09, 0xcaf54957), TOBN(0xbfb028be, 0xe5f5d5d5),
-+     TOBN(0x928a0650, 0x2003e2c0), TOBN(0x90793aac, 0x67476843),
-+     TOBN(0x5e942e79, 0xc81710a0), TOBN(0x557e4a36, 0x27ccadd4),
-+     TOBN(0x72a2bc56, 0x4bcf6d0c), TOBN(0x09ee5f43, 0x26d7b80c),
-+     TOBN(0x6b70dbe9, 0xd4292f19), TOBN(0x56f74c26, 0x63f16b18),
-+     TOBN(0xc23db0f7, 0x35fbb42a), TOBN(0xb606bdf6, 0x6ae10040),
-+     TOBN(0x1eb15d4d, 0x044573ac), TOBN(0x7dc3cf86, 0x556b0ba4),
-+     TOBN(0x97af9a33, 0xc60df6f7), TOBN(0x0b1ef85c, 0xa716ce8c),
-+     TOBN(0x2922f884, 0xc96958be), TOBN(0x7c32fa94, 0x35690963),
-+     TOBN(0x2d7f667c, 0xeaa00061), TOBN(0xeaaf7c17, 0x3547365c),
-+     TOBN(0x1eb4de46, 0x87032d58), TOBN(0xc54f3d83, 0x5e2c79e0),
-+     TOBN(0x07818df4, 0x5d04ef23), TOBN(0x55faa9c8, 0x673d41b4),
-+     TOBN(0xced64f6f, 0x89b95355), TOBN(0x4860d2ea, 0xb7415c84),
-+     TOBN(0x5fdb9bd2, 0x050ebad3), TOBN(0xdb53e0cc, 0x6685a5bf),
-+     TOBN(0xb830c031, 0x9feb6593), TOBN(0xdd87f310, 0x6accff17),
-+     TOBN(0x2303ebab, 0x9f555c10), TOBN(0x94603695, 0x287e7065),
-+     TOBN(0xf88311c3, 0x2e83358c), TOBN(0x508dd9b4, 0xeefb0178),
-+     TOBN(0x7ca23706, 0x2dba8652), TOBN(0x62aac5a3, 0x0047abe5),
-+     TOBN(0x9a61d2a0, 0x8b1ea7b3), TOBN(0xd495ab63, 0xae8b1485),
-+     TOBN(0x38740f84, 0x87052f99), TOBN(0x178ebe5b, 0xb2974eea),
-+     TOBN(0x030bbcca, 0x5b36d17f), TOBN(0xb5e4cce3, 0xaaf86eea),
-+     TOBN(0xb51a0220, 0x68f8e9e0), TOBN(0xa4348796, 0x09eb3e75),
-+     TOBN(0xbe592309, 0xeef1a752), TOBN(0x5d7162d7, 0x6f2aa1ed),
-+     TOBN(0xaebfb5ed, 0x0f007dd2), TOBN(0x255e14b2, 0xc89edd22),
-+     TOBN(0xba85e072, 0x0303b697), TOBN(0xc5d17e25, 0xf05720ff),
-+     TOBN(0x02b58d6e, 0x5128ebb6), TOBN(0x2c80242d, 0xd754e113),
-+     TOBN(0x919fca5f, 0xabfae1ca), TOBN(0x937afaac, 0x1a21459b),
-+     TOBN(0x9e0ca91c, 0x1f66a4d2), TOBN(0x194cc7f3, 0x23ec1331),
-+     TOBN(0xad25143a, 0x8aa11690), TOBN(0xbe40ad8d, 0x09b59e08),
-+     TOBN(0x37d60d9b, 0xe750860a), TOBN(0x6c53b008, 0xc6bf434c),
-+     TOBN(0xb572415d, 0x1356eb80), TOBN(0xb8bf9da3, 0x9578ded8),
-+     TOBN(0x22658e36, 0x5e8fb38b), TOBN(0x9b70ce22, 0x5af8cb22),
-+     TOBN(0x7c00018a, 0x829a8180), TOBN(0x84329f93, 0xb81ed295),
-+     TOBN(0x7c343ea2, 0x5f3cea83), TOBN(0x38f8655f, 0x67586536),
-+     TOBN(0xa661a0d0, 0x1d3ec517), TOBN(0x98744652, 0x512321ae),
-+     TOBN(0x084ca591, 0xeca92598), TOBN(0xa9bb9dc9, 0x1dcb3feb),
-+     TOBN(0x14c54355, 0x78b4c240), TOBN(0x5ed62a3b, 0x610cafdc),
-+     TOBN(0x07512f37, 0x1b38846b), TOBN(0x571bb70a, 0xb0e38161),
-+     TOBN(0xb556b95b, 0x2da705d2), TOBN(0x3ef8ada6, 0xb1a08f98),
-+     TOBN(0x85302ca7, 0xddecfbe5), TOBN(0x0e530573, 0x943105cd),
-+     TOBN(0x60554d55, 0x21a9255d), TOBN(0x63a32fa1, 0xf2f3802a),
-+     TOBN(0x35c8c5b0, 0xcd477875), TOBN(0x97f458ea, 0x6ad42da1),
-+     TOBN(0x832d7080, 0xeb6b242d), TOBN(0xd30bd023, 0x3b71e246),
-+     TOBN(0x7027991b, 0xbe31139d), TOBN(0x68797e91, 0x462e4e53),
-+     TOBN(0x423fe20a, 0x6b4e185a), TOBN(0x82f2c67e, 0x42d9b707),
-+     TOBN(0x25c81768, 0x4cf7811b), TOBN(0xbd53005e, 0x045bb95d),}
-+    ,
-+    {TOBN(0xe5f649be, 0x9d8e68fd), TOBN(0xdb0f0533, 0x1b044320),
-+     TOBN(0xf6fde9b3, 0xe0c33398), TOBN(0x92f4209b, 0x66c8cfae),
-+     TOBN(0xe9d1afcc, 0x1a739d4b), TOBN(0x09aea75f, 0xa28ab8de),
-+     TOBN(0x14375fb5, 0xeac6f1d0), TOBN(0x6420b560, 0x708f7aa5),
-+     TOBN(0x9eae499c, 0x6254dc41), TOBN(0x7e293924, 0x7a837e7e),
-+     TOBN(0x74aec08c, 0x090524a7), TOBN(0xf82b9219, 0x8d6f55f2),
-+     TOBN(0x493c962e, 0x1402cec5), TOBN(0x9f17ca17, 0xfa2f30e7),
-+     TOBN(0xbcd783e8, 0xe9b879cb), TOBN(0xea3d8c14, 0x5a6f145f),
-+     TOBN(0xdede15e7, 0x5e0dee6e), TOBN(0x74f24872, 0xdc628aa2),
-+     TOBN(0xd3e9c4fe, 0x7861bb93), TOBN(0x56d4822a, 0x6187b2e0),
-+     TOBN(0xb66417cf, 0xc59826f9), TOBN(0xca260969, 0x2408169e),
-+     TOBN(0xedf69d06, 0xc79ef885), TOBN(0x00031f8a, 0xdc7d138f),
-+     TOBN(0x103c46e6, 0x0ebcf726), TOBN(0x4482b831, 0x6231470e),
-+     TOBN(0x6f6dfaca, 0x487c2109), TOBN(0x2e0ace97, 0x62e666ef),
-+     TOBN(0x3246a9d3, 0x1f8d1f42), TOBN(0x1b1e83f1, 0x574944d2),
-+     TOBN(0x13dfa63a, 0xa57f334b), TOBN(0x0cf8daed, 0x9f025d81),
-+     TOBN(0x30d78ea8, 0x00ee11c1), TOBN(0xeb053cd4, 0xb5e3dd75),
-+     TOBN(0x9b65b13e, 0xd58c43c5), TOBN(0xc3ad49bd, 0xbd151663),
-+     TOBN(0x99fd8e41, 0xb6427990), TOBN(0x12cf15bd, 0x707eae1e),
-+     TOBN(0x29ad4f1b, 0x1aabb71e), TOBN(0x5143e74d, 0x07545d0e),
-+     TOBN(0x30266336, 0xc88bdee1), TOBN(0x25f29306, 0x5876767c),
-+     TOBN(0x9c078571, 0xc6731996), TOBN(0xc88690b2, 0xed552951),
-+     TOBN(0x274f2c2d, 0x852705b4), TOBN(0xb0bf8d44, 0x4e09552d),
-+     TOBN(0x7628beeb, 0x986575d1), TOBN(0x407be238, 0x7f864651),
-+     TOBN(0x0e5e3049, 0xa639fc6b), TOBN(0xe75c35d9, 0x86003625),
-+     TOBN(0x0cf35bd8, 0x5dcc1646), TOBN(0x8bcaced2, 0x6c26273a),
-+     TOBN(0xe22ecf1d, 0xb5536742), TOBN(0x013dd897, 0x1a9e068b),
-+     TOBN(0x17f411cb, 0x8a7909c5), TOBN(0x5757ac98, 0x861dd506),
-+     TOBN(0x85de1f0d, 0x1e935abb), TOBN(0xdefd10b4, 0x154de37a),
-+     TOBN(0xb8d9e392, 0x369cebb5), TOBN(0x54d5ef9b, 0x761324be),
-+     TOBN(0x4d6341ba, 0x74f17e26), TOBN(0xc0a0e3c8, 0x78c1dde4),
-+     TOBN(0xa6d77581, 0x87d918fd), TOBN(0x66876015, 0x02ca3a13),
-+     TOBN(0xc7313e9c, 0xf36658f0), TOBN(0xc433ef1c, 0x71f8057e),
-+     TOBN(0x85326246, 0x1b6a835a), TOBN(0xc8f05398, 0x7c86394c),
-+     TOBN(0xff398cdf, 0xe983c4a1), TOBN(0xbf5e8162, 0x03b7b931),
-+     TOBN(0x93193c46, 0xb7b9045b), TOBN(0x1e4ebf5d, 0xa4a6e46b),
-+     TOBN(0xf9942a60, 0x43a24fe7), TOBN(0x29c1191e, 0xffb3492b),
-+     TOBN(0x9f662449, 0x902fde05), TOBN(0xc792a7ac, 0x6713c32d),
-+     TOBN(0x2fd88ad8, 0xb737982c), TOBN(0x7e3a0319, 0xa21e60e3),
-+     TOBN(0x09b0de44, 0x7383591a), TOBN(0x6df141ee, 0x8310a456),
-+     TOBN(0xaec1a039, 0xe6d6f471), TOBN(0x14b2ba0f, 0x1198d12e),
-+     TOBN(0xebc1a160, 0x3aeee5ac), TOBN(0x401f4836, 0xe0b964ce),
-+     TOBN(0x2ee43796, 0x4fd03f66), TOBN(0x3fdb4e49, 0xdd8f3f12),
-+     TOBN(0x6ef267f6, 0x29380f18), TOBN(0x3e8e9670, 0x8da64d16),
-+     TOBN(0xbc19180c, 0x207674f1), TOBN(0x112e09a7, 0x33ae8fdb),
-+     TOBN(0x99667554, 0x6aaeb71e), TOBN(0x79432af1, 0xe101b1c7),
-+     TOBN(0xd5eb558f, 0xde2ddec6), TOBN(0x81392d1f, 0x5357753f),
-+     TOBN(0xa7a76b97, 0x3ae1158a), TOBN(0x416fbbff, 0x4a899991),
-+     TOBN(0x9e65fdfd, 0x0d4a9dcf), TOBN(0x7bc29e48, 0x944ddf12),
-+     TOBN(0xbc1a92d9, 0x3c856866), TOBN(0x273c6905, 0x6e98dfe2),
-+     TOBN(0x69fce418, 0xcdfaa6b8), TOBN(0x606bd823, 0x5061c69f),
-+     TOBN(0x42d495a0, 0x6af75e27), TOBN(0x8ed3d505, 0x6d873a1f),
-+     TOBN(0xaf552841, 0x6ab25b6a), TOBN(0xc6c0ffc7, 0x2b1a4523),
-+     TOBN(0xab18827b, 0x21c99e03), TOBN(0x060e8648, 0x9034691b),
-+     TOBN(0x5207f90f, 0x93c7f398), TOBN(0x9f4a96cb, 0x82f8d10b),
-+     TOBN(0xdd71cd79, 0x3ad0f9e3), TOBN(0x84f435d2, 0xfc3a54f5),
-+     TOBN(0x4b03c55b, 0x8e33787f), TOBN(0xef42f975, 0xa6384673),
-+     TOBN(0xff7304f7, 0x5051b9f0), TOBN(0x18aca1dc, 0x741c87c2),
-+     TOBN(0x56f120a7, 0x2d4bfe80), TOBN(0xfd823b3d, 0x053e732c),
-+     TOBN(0x11bccfe4, 0x7537ca16), TOBN(0xdf6c9c74, 0x1b5a996b),
-+     TOBN(0xee7332c7, 0x904fc3fa), TOBN(0x14a23f45, 0xc7e3636a),
-+     TOBN(0xc38659c3, 0xf091d9aa), TOBN(0x4a995e5d, 0xb12d8540),
-+     TOBN(0x20a53bec, 0xf3a5598a), TOBN(0x56534b17, 0xb1eaa995),
-+     TOBN(0x9ed3dca4, 0xbf04e03c), TOBN(0x716c563a, 0xd8d56268),
-+     TOBN(0x27ba77a4, 0x1d6178e7), TOBN(0xe4c80c40, 0x68a1ff8e),
-+     TOBN(0x75011099, 0x0a13f63d), TOBN(0x7bf33521, 0xa61d46f3),
-+     TOBN(0x0aff218e, 0x10b365bb), TOBN(0x81021804, 0x0fd7ea75),
-+     TOBN(0x05a3fd8a, 0xa4b3a925), TOBN(0xb829e75f, 0x9b3db4e6),
-+     TOBN(0x6bdc75a5, 0x4d53e5fb), TOBN(0x04a5dc02, 0xd52717e3),
-+     TOBN(0x86af502f, 0xe9a42ec2), TOBN(0x8867e8fb, 0x2630e382),
-+     TOBN(0xbf845c6e, 0xbec9889b), TOBN(0x54f491f2, 0xcb47c98d),
-+     TOBN(0xa3091fba, 0x790c2a12), TOBN(0xd7f6fd78, 0xc20f708b),
-+     TOBN(0xa569ac30, 0xacde5e17), TOBN(0xd0f996d0, 0x6852b4d7),
-+     TOBN(0xe51d4bb5, 0x4609ae54), TOBN(0x3fa37d17, 0x0daed061),
-+     TOBN(0x62a88684, 0x34b8fb41), TOBN(0x99a2acbd, 0x9efb64f1),
-+     TOBN(0xb75c1a5e, 0x6448e1f2), TOBN(0xfa99951a, 0x42b5a069),
-+     TOBN(0x6d956e89, 0x2f3b26e7), TOBN(0xf4709860, 0xda875247),
-+     TOBN(0x3ad15179, 0x2482dda3), TOBN(0xd64110e3, 0x017d82f0),
-+     TOBN(0x14928d2c, 0xfad414e4), TOBN(0x2b155f58, 0x2ed02b24),
-+     TOBN(0x481a141b, 0xcb821bf1), TOBN(0x12e3c770, 0x4f81f5da),
-+     TOBN(0xe49c5de5, 0x9fff8381), TOBN(0x11053232, 0x5bbec894),
-+     TOBN(0xa0d051cc, 0x454d88c4), TOBN(0x4f6db89c, 0x1f8e531b),
-+     TOBN(0x34fe3fd6, 0xca563a44), TOBN(0x7f5c2215, 0x58da8ab9),
-+     TOBN(0x8445016d, 0x9474f0a1), TOBN(0x17d34d61, 0xcb7d8a0a),
-+     TOBN(0x8e9d3910, 0x1c474019), TOBN(0xcaff2629, 0xd52ceefb),
-+     TOBN(0xf9cf3e32, 0xc1622c2b), TOBN(0xd4b95e3c, 0xe9071a05),
-+     TOBN(0xfbbca61f, 0x1594438c), TOBN(0x1eb6e6a6, 0x04aadedf),
-+     TOBN(0x853027f4, 0x68e14940), TOBN(0x221d322a, 0xdfabda9c),
-+     TOBN(0xed8ea9f6, 0xb7cb179a), TOBN(0xdc7b764d, 0xb7934dcc),
-+     TOBN(0xfcb13940, 0x5e09180d), TOBN(0x6629a6bf, 0xb47dc2dd),
-+     TOBN(0xbfc55e4e, 0x9f5a915e), TOBN(0xb1db9d37, 0x6204441e),
-+     TOBN(0xf82d68cf, 0x930c5f53), TOBN(0x17d3a142, 0xcbb605b1),
-+     TOBN(0xdd5944ea, 0x308780f2), TOBN(0xdc8de761, 0x3845f5e4),
-+     TOBN(0x6beaba7d, 0x7624d7a3), TOBN(0x1e709afd, 0x304df11e),
-+     TOBN(0x95364376, 0x02170456), TOBN(0xbf204b3a, 0xc8f94b64),
-+     TOBN(0x4e53af7c, 0x5680ca68), TOBN(0x0526074a, 0xe0c67574),
-+     TOBN(0x95d8cef8, 0xecd92af6), TOBN(0xe6b9fa7a, 0x6cd1745a),
-+     TOBN(0x3d546d3d, 0xa325c3e4), TOBN(0x1f57691d, 0x9ae93aae),
-+     TOBN(0xe891f3fe, 0x9d2e1a33), TOBN(0xd430093f, 0xac063d35),
-+     TOBN(0xeda59b12, 0x5513a327), TOBN(0xdc2134f3, 0x5536f18f),
-+     TOBN(0xaa51fe2c, 0x5c210286), TOBN(0x3f68aaee, 0x1cab658c),
-+     TOBN(0x5a23a00b, 0xf9357292), TOBN(0x9a626f39, 0x7efdabed),
-+     TOBN(0xfe2b3bf3, 0x199d78e3), TOBN(0xb7a2af77, 0x71bbc345),
-+     TOBN(0x3d19827a, 0x1e59802c), TOBN(0x823bbc15, 0xb487a51c),
-+     TOBN(0x856139f2, 0x99d0a422), TOBN(0x9ac3df65, 0xf456c6fb),
-+     TOBN(0xaddf65c6, 0x701f8bd6), TOBN(0x149f321e, 0x3758df87),
-+     TOBN(0xb1ecf714, 0x721b7eba), TOBN(0xe17df098, 0x31a3312a),
-+     TOBN(0xdb2fd6ec, 0xd5c4d581), TOBN(0xfd02996f, 0x8fcea1b3),
-+     TOBN(0xe29fa63e, 0x7882f14f), TOBN(0xc9f6dc35, 0x07c6cadc),
-+     TOBN(0x46f22d6f, 0xb882bed0), TOBN(0x1a45755b, 0xd118e52c),
-+     TOBN(0x9f2c7c27, 0x7c4608cf), TOBN(0x7ccbdf32, 0x568012c2),
-+     TOBN(0xfcb0aedd, 0x61729b0e), TOBN(0x7ca2ca9e, 0xf7d75dbf),
-+     TOBN(0xf58fecb1, 0x6f640f62), TOBN(0xe274b92b, 0x39f51946),
-+     TOBN(0x7f4dfc04, 0x6288af44), TOBN(0x0a91f32a, 0xeac329e5),
-+     TOBN(0x43ad274b, 0xd6aaba31), TOBN(0x719a1640, 0x0f6884f9),
-+     TOBN(0x685d29f6, 0xdaf91e20), TOBN(0x5ec1cc33, 0x27e49d52),
-+     TOBN(0x38f4de96, 0x3b54a059), TOBN(0x0e0015e5, 0xefbcfdb3),
-+     TOBN(0x177d23d9, 0x4dbb8da6), TOBN(0x98724aa2, 0x97a617ad),
-+     TOBN(0x30f0885b, 0xfdb6558e), TOBN(0xf9f7a28a, 0xc7899a96),
-+     TOBN(0xd2ae8ac8, 0x872dc112), TOBN(0xfa0642ca, 0x73c3c459),
-+     TOBN(0x15296981, 0xe7dfc8d6), TOBN(0x67cd4450, 0x1fb5b94a),
-+     TOBN(0x0ec71cf1, 0x0eddfd37), TOBN(0xc7e5eeb3, 0x9a8eddc7),
-+     TOBN(0x02ac8e3d, 0x81d95028), TOBN(0x0088f172, 0x70b0e35d),
-+     TOBN(0xec041fab, 0xe1881fe3), TOBN(0x62cf71b8, 0xd99e7faa),
-+     TOBN(0x5043dea7, 0xe0f222c2), TOBN(0x309d42ac, 0x72e65142),
-+     TOBN(0x94fe9ddd, 0x9216cd30), TOBN(0xd6539c7d, 0x0f87feec),
-+     TOBN(0x03c5a57c, 0x432ac7d7), TOBN(0x72692cf0, 0x327fda10),
-+     TOBN(0xec28c85f, 0x280698de), TOBN(0x2331fb46, 0x7ec283b1),
-+     TOBN(0xd34bfa32, 0x2867e633), TOBN(0x78709a82, 0x0a9cc815),
-+     TOBN(0xb7fe6964, 0x875e2fa5), TOBN(0x25cc064f, 0x9e98bfb5),
-+     TOBN(0x9eb0151c, 0x493a65c5), TOBN(0x5fb5d941, 0x53182464),
-+     TOBN(0x69e6f130, 0xf04618e2), TOBN(0xa8ecec22, 0xf89c8ab6),
-+     TOBN(0xcd6ac88b, 0xb96209bd), TOBN(0x65fa8cdb, 0xb3e1c9e0),
-+     TOBN(0xa47d22f5, 0x4a8d8eac), TOBN(0x83895cdf, 0x8d33f963),
-+     TOBN(0xa8adca59, 0xb56cd3d1), TOBN(0x10c8350b, 0xdaf38232),
-+     TOBN(0x2b161fb3, 0xa5080a9f), TOBN(0xbe7f5c64, 0x3af65b3a),
-+     TOBN(0x2c754039, 0x97403a11), TOBN(0x94626cf7, 0x121b96af),
-+     TOBN(0x431de7c4, 0x6a983ec2), TOBN(0x3780dd3a, 0x52cc3df7),
-+     TOBN(0xe28a0e46, 0x2baf8e3b), TOBN(0xabe68aad, 0x51d299ae),
-+     TOBN(0x603eb8f9, 0x647a2408), TOBN(0x14c61ed6, 0x5c750981),
-+     TOBN(0x88b34414, 0xc53352e7), TOBN(0x5a34889c, 0x1337d46e),
-+     TOBN(0x612c1560, 0xf95f2bc8), TOBN(0x8a3f8441, 0xd4807a3a),
-+     TOBN(0x680d9e97, 0x5224da68), TOBN(0x60cd6e88, 0xc3eb00e9),
-+     TOBN(0x3875a98e, 0x9a6bc375), TOBN(0xdc80f924, 0x4fd554c2),
-+     TOBN(0x6c4b3415, 0x6ac77407), TOBN(0xa1e5ea8f, 0x25420681),
-+     TOBN(0x541bfa14, 0x4607a458), TOBN(0x5dbc7e7a, 0x96d7fbf9),
-+     TOBN(0x646a851b, 0x31590a47), TOBN(0x039e85ba, 0x15ee6df8),
-+     TOBN(0xd19fa231, 0xd7b43fc0), TOBN(0x84bc8be8, 0x299a0e04),
-+     TOBN(0x2b9d2936, 0xf20df03a), TOBN(0x24054382, 0x8608d472),
-+     TOBN(0x76b6ba04, 0x9149202a), TOBN(0xb21c3831, 0x3670e7b7),
-+     TOBN(0xddd93059, 0xd6fdee10), TOBN(0x9da47ad3, 0x78488e71),
-+     TOBN(0x99cc1dfd, 0xa0fcfb25), TOBN(0x42abde10, 0x64696954),
-+     TOBN(0x14cc15fc, 0x17eab9fe), TOBN(0xd6e863e4, 0xd3e70972),
-+     TOBN(0x29a7765c, 0x6432112c), TOBN(0x88660001, 0x5b0774d8),
-+     TOBN(0x3729175a, 0x2c088eae), TOBN(0x13afbcae, 0x8230b8d4),
-+     TOBN(0x44768151, 0x915f4379), TOBN(0xf086431a, 0xd8d22812),
-+     TOBN(0x37461955, 0xc298b974), TOBN(0x905fb5f0, 0xf8711e04),
-+     TOBN(0x787abf3a, 0xfe969d18), TOBN(0x392167c2, 0x6f6a494e),
-+     TOBN(0xfc7a0d2d, 0x28c511da), TOBN(0xf127c7dc, 0xb66a262d),
-+     TOBN(0xf9c4bb95, 0xfd63fdf0), TOBN(0x90016589, 0x3913ef46),
-+     TOBN(0x74d2a73c, 0x11aa600d), TOBN(0x2f5379bd, 0x9fb5ab52),
-+     TOBN(0xe49e53a4, 0x7fb70068), TOBN(0x68dd39e5, 0x404aa9a7),
-+     TOBN(0xb9b0cf57, 0x2ecaa9c3), TOBN(0xba0e103b, 0xe824826b),
-+     TOBN(0x60c2198b, 0x4631a3c4), TOBN(0xc5ff84ab, 0xfa8966a2),
-+     TOBN(0x2d6ebe22, 0xac95aff8), TOBN(0x1c9bb6db, 0xb5a46d09),
-+     TOBN(0x419062da, 0x53ee4f8d), TOBN(0x7b9042d0, 0xbb97efef),
-+     TOBN(0x0f87f080, 0x830cf6bd), TOBN(0x4861d19a, 0x6ec8a6c6),
-+     TOBN(0xd3a0daa1, 0x202f01aa), TOBN(0xb0111674, 0xf25afbd5),
-+     TOBN(0x6d00d6cf, 0x1afb20d9), TOBN(0x13695000, 0x40671bc5),
-+     TOBN(0x913ab0dc, 0x2485ea9b), TOBN(0x1f2bed06, 0x9eef61ac),
-+     TOBN(0x850c8217, 0x6d799e20), TOBN(0x93415f37, 0x3271c2de),
-+     TOBN(0x5afb06e9, 0x6c4f5910), TOBN(0x688a52df, 0xc4e9e421),
-+     TOBN(0x30495ba3, 0xe2a9a6db), TOBN(0x4601303d, 0x58f9268b),
-+     TOBN(0xbe3b0dad, 0x7eb0f04f), TOBN(0x4ea47250, 0x4456936d),
-+     TOBN(0x8caf8798, 0xd33fd3e7), TOBN(0x1ccd8a89, 0xeb433708),
-+     TOBN(0x9effe3e8, 0x87fd50ad), TOBN(0xbe240a56, 0x6b29c4df),
-+     TOBN(0xec4ffd98, 0xca0e7ebd), TOBN(0xf586783a, 0xe748616e),
-+     TOBN(0xa5b00d8f, 0xc77baa99), TOBN(0x0acada29, 0xb4f34c9c),
-+     TOBN(0x36dad67d, 0x0fe723ac), TOBN(0x1d8e53a5, 0x39c36c1e),
-+     TOBN(0xe4dd342d, 0x1f4bea41), TOBN(0x64fd5e35, 0xebc9e4e0),
-+     TOBN(0x96f01f90, 0x57908805), TOBN(0xb5b9ea3d, 0x5ed480dd),
-+     TOBN(0x366c5dc2, 0x3efd2dd0), TOBN(0xed2fe305, 0x6e9dfa27),
-+     TOBN(0x4575e892, 0x6e9197e2), TOBN(0x11719c09, 0xab502a5d),
-+     TOBN(0x264c7bec, 0xe81f213f), TOBN(0x741b9241, 0x55f5c457),
-+     TOBN(0x78ac7b68, 0x49a5f4f4), TOBN(0xf91d70a2, 0x9fc45b7d),
-+     TOBN(0x39b05544, 0xb0f5f355), TOBN(0x11f06bce, 0xeef930d9),
-+     TOBN(0xdb84d25d, 0x038d05e1), TOBN(0x04838ee5, 0xbacc1d51),
-+     TOBN(0x9da3ce86, 0x9e8ee00b), TOBN(0xc3412057, 0xc36eda1f),
-+     TOBN(0xae80b913, 0x64d9c2f4), TOBN(0x7468bac3, 0xa010a8ff),
-+     TOBN(0xdfd20037, 0x37359d41), TOBN(0x1a0f5ab8, 0x15efeacc),
-+     TOBN(0x7c25ad2f, 0x659d0ce0), TOBN(0x4011bcbb, 0x6785cff1),
-+     TOBN(0x128b9912, 0x7e2192c7), TOBN(0xa549d8e1, 0x13ccb0e8),
-+     TOBN(0x805588d8, 0xc85438b1), TOBN(0x5680332d, 0xbc25cb27),
-+     TOBN(0xdcd1bc96, 0x1a4bfdf4), TOBN(0x779ff428, 0x706f6566),
-+     TOBN(0x8bbee998, 0xf059987a), TOBN(0xf6ce8cf2, 0xcc686de7),
-+     TOBN(0xf8ad3c4a, 0x953cfdb2), TOBN(0xd1d426d9, 0x2205da36),
-+     TOBN(0xb3c0f13f, 0xc781a241), TOBN(0x3e89360e, 0xd75362a8),
-+     TOBN(0xccd05863, 0xc8a91184), TOBN(0x9bd0c9b7, 0xefa8a7f4),
-+     TOBN(0x97ee4d53, 0x8a912a4b), TOBN(0xde5e15f8, 0xbcf518fd),
-+     TOBN(0x6a055bf8, 0xc467e1e0), TOBN(0x10be4b4b, 0x1587e256),
-+     TOBN(0xd90c14f2, 0x668621c9), TOBN(0xd5518f51, 0xab9c92c1),
-+     TOBN(0x8e6a0100, 0xd6d47b3c), TOBN(0xcbe980dd, 0x66716175),
-+     TOBN(0x500d3f10, 0xddd83683), TOBN(0x3b6cb35d, 0x99cac73c),
-+     TOBN(0x53730c8b, 0x6083d550), TOBN(0xcf159767, 0xdf0a1987),
-+     TOBN(0x84bfcf53, 0x43ad73b3), TOBN(0x1b528c20, 0x4f035a94),
-+     TOBN(0x4294edf7, 0x33eeac69), TOBN(0xb6283e83, 0x817f3240),
-+     TOBN(0xc3fdc959, 0x0a5f25b1), TOBN(0xefaf8aa5, 0x5844ee22),
-+     TOBN(0xde269ba5, 0xdbdde4de), TOBN(0xe3347160, 0xc56133bf),
-+     TOBN(0xc1184219, 0x8d9ea9f8), TOBN(0x090de5db, 0xf3fc1ab5),
-+     TOBN(0x404c37b1, 0x0bf22cda), TOBN(0x7de20ec8, 0xf5618894),
-+     TOBN(0x754c588e, 0xecdaecab), TOBN(0x6ca4b0ed, 0x88342743),
-+     TOBN(0x76f08bdd, 0xf4a938ec), TOBN(0xd182de89, 0x91493ccb),
-+     TOBN(0xd652c53e, 0xc8a4186a), TOBN(0xb3e878db, 0x946d8e33),
-+     TOBN(0x088453c0, 0x5f37663c), TOBN(0x5cd9daaa, 0xb407748b),
-+     TOBN(0xa1f5197f, 0x586d5e72), TOBN(0x47500be8, 0xc443ca59),
-+     TOBN(0x78ef35b2, 0xe2652424), TOBN(0x09c5d26f, 0x6dd7767d),
-+     TOBN(0x7175a79a, 0xa74d3f7b), TOBN(0x0428fd8d, 0xcf5ea459),
-+     TOBN(0x511cb97c, 0xa5d1746d), TOBN(0x36363939, 0xe71d1278),
-+     TOBN(0xcf2df955, 0x10350bf4), TOBN(0xb3817439, 0x60aae782),
-+     TOBN(0xa748c0e4, 0x3e688809), TOBN(0x98021fbf, 0xd7a5a006),
-+     TOBN(0x9076a70c, 0x0e367a98), TOBN(0xbea1bc15, 0x0f62b7c2),
-+     TOBN(0x2645a68c, 0x30fe0343), TOBN(0xacaffa78, 0x699dc14f),
-+     TOBN(0xf4469964, 0x457bf9c4), TOBN(0x0db6407b, 0x0d2ead83),
-+     TOBN(0x68d56cad, 0xb2c6f3eb), TOBN(0x3b512e73, 0xf376356c),
-+     TOBN(0xe43b0e1f, 0xfce10408), TOBN(0x89ddc003, 0x5a5e257d),
-+     TOBN(0xb0ae0d12, 0x0362e5b3), TOBN(0x07f983c7, 0xb0519161),
-+     TOBN(0xc2e94d15, 0x5d5231e7), TOBN(0xcff22aed, 0x0b4f9513),
-+     TOBN(0xb02588dd, 0x6ad0b0b5), TOBN(0xb967d1ac, 0x11d0dcd5),
-+     TOBN(0x8dac6bc6, 0xcf777b6c), TOBN(0x0062bdbd, 0x4c6d1959),
-+     TOBN(0x53da71b5, 0x0ef5cc85), TOBN(0x07012c7d, 0x4006f14f),
-+     TOBN(0x4617f962, 0xac47800d), TOBN(0x53365f2b, 0xc102ed75),
-+     TOBN(0xb422efcb, 0x4ab8c9d3), TOBN(0x195cb26b, 0x34af31c9),
-+     TOBN(0x3a926e29, 0x05f2c4ce), TOBN(0xbd2bdecb, 0x9856966c),
-+     TOBN(0x5d16ab3a, 0x85527015), TOBN(0x9f81609e, 0x4486c231),
-+     TOBN(0xd8b96b2c, 0xda350002), TOBN(0xbd054690, 0xfa1b7d36),
-+     TOBN(0xdc90ebf5, 0xe71d79bc), TOBN(0xf241b6f9, 0x08964e4e),
-+     TOBN(0x7c838643, 0x2fe3cd4c), TOBN(0xe0f33acb, 0xb4bc633c),
-+     TOBN(0xb4a9ecec, 0x3d139f1f), TOBN(0x05ce69cd, 0xdc4a1f49),
-+     TOBN(0xa19d1b16, 0xf5f98aaf), TOBN(0x45bb71d6, 0x6f23e0ef),
-+     TOBN(0x33789fcd, 0x46cdfdd3), TOBN(0x9b8e2978, 0xcee040ca),
-+     TOBN(0x9c69b246, 0xae0a6828), TOBN(0xba533d24, 0x7078d5aa),
-+     TOBN(0x7a2e42c0, 0x7bb4fbdb), TOBN(0xcfb4879a, 0x7035385c),
-+     TOBN(0x8c3dd30b, 0x3281705b), TOBN(0x7e361c6c, 0x404fe081),
-+     TOBN(0x7b21649c, 0x3f604edf), TOBN(0x5dbf6a3f, 0xe52ffe47),
-+     TOBN(0xc41b7c23, 0x4b54d9bf), TOBN(0x1374e681, 0x3511c3d9),
-+     TOBN(0x1863bf16, 0xc1b2b758), TOBN(0x90e78507, 0x1e9e6a96),
-+     TOBN(0xab4bf98d, 0x5d86f174), TOBN(0xd74e0bd3, 0x85e96fe4),
-+     TOBN(0x8afde39f, 0xcac5d344), TOBN(0x90946dbc, 0xbd91b847),
-+     TOBN(0xf5b42358, 0xfe1a838c), TOBN(0x05aae6c5, 0x620ac9d8),
-+     TOBN(0x8e193bd8, 0xa1ce5a0b), TOBN(0x8f710571, 0x4dabfd72),
-+     TOBN(0x8d8fdd48, 0x182caaac), TOBN(0x8c4aeefa, 0x040745cf),
-+     TOBN(0x73c6c30a, 0xf3b93e6d), TOBN(0x991241f3, 0x16f42011),
-+     TOBN(0xa0158eea, 0xe457a477), TOBN(0xd19857db, 0xee6ddc05),
-+     TOBN(0xb3265224, 0x18c41671), TOBN(0x3ffdfc7e, 0x3c2c0d58),
-+     TOBN(0x3a3a5254, 0x26ee7cda), TOBN(0x341b0869, 0xdf02c3a8),
-+     TOBN(0xa023bf42, 0x723bbfc8), TOBN(0x3d15002a, 0x14452691),}
-+    ,
-+    {TOBN(0x5ef7324c, 0x85edfa30), TOBN(0x25976554, 0x87d4f3da),
-+     TOBN(0x352f5bc0, 0xdcb50c86), TOBN(0x8f6927b0, 0x4832a96c),
-+     TOBN(0xd08ee1ba, 0x55f2f94c), TOBN(0x6a996f99, 0x344b45fa),
-+     TOBN(0xe133cb8d, 0xa8aa455d), TOBN(0x5d0721ec, 0x758dc1f7),
-+     TOBN(0x6ba7a920, 0x79e5fb67), TOBN(0xe1331feb, 0x70aa725e),
-+     TOBN(0x5080ccf5, 0x7df5d837), TOBN(0xe4cae01d, 0x7ff72e21),
-+     TOBN(0xd9243ee6, 0x0412a77d), TOBN(0x06ff7cac, 0xdf449025),
-+     TOBN(0xbe75f7cd, 0x23ef5a31), TOBN(0xbc957822, 0x0ddef7a8),
-+     TOBN(0x8cf7230c, 0xb0ce1c55), TOBN(0x5b534d05, 0x0bbfb607),
-+     TOBN(0xee1ef113, 0x0e16363b), TOBN(0x27e0aa7a, 0xb4999e82),
-+     TOBN(0xce1dac2d, 0x79362c41), TOBN(0x67920c90, 0x91bb6cb0),
-+     TOBN(0x1e648d63, 0x2223df24), TOBN(0x0f7d9eef, 0xe32e8f28),
-+     TOBN(0x6943f39a, 0xfa833834), TOBN(0x22951722, 0xa6328562),
-+     TOBN(0x81d63dd5, 0x4170fc10), TOBN(0x9f5fa58f, 0xaecc2e6d),
-+     TOBN(0xb66c8725, 0xe77d9a3b), TOBN(0x11235cea, 0x6384ebe0),
-+     TOBN(0x06a8c118, 0x5845e24a), TOBN(0x0137b286, 0xebd093b1),
-+     TOBN(0xc589e1ce, 0x44ace150), TOBN(0xe0f8d3d9, 0x4381e97c),
-+     TOBN(0x59e99b11, 0x62c5a4b8), TOBN(0x90d262f7, 0xfd0ec9f9),
-+     TOBN(0xfbc854c9, 0x283e13c9), TOBN(0x2d04fde7, 0xaedc7085),
-+     TOBN(0x057d7765, 0x47dcbecb), TOBN(0x8dbdf591, 0x9a76fa5f),
-+     TOBN(0xd0150695, 0x0de1e578), TOBN(0x2e1463e7, 0xe9f72bc6),
-+     TOBN(0xffa68441, 0x1b39eca5), TOBN(0x673c8530, 0x7c037f2f),
-+     TOBN(0xd0d6a600, 0x747f91da), TOBN(0xb08d43e1, 0xc9cb78e9),
-+     TOBN(0x0fc0c644, 0x27b5cef5), TOBN(0x5c1d160a, 0xa60a2fd6),
-+     TOBN(0xf98cae53, 0x28c8e13b), TOBN(0x375f10c4, 0xb2eddcd1),
-+     TOBN(0xd4eb8b7f, 0x5cce06ad), TOBN(0xb4669f45, 0x80a2e1ef),
-+     TOBN(0xd593f9d0, 0x5bbd8699), TOBN(0x5528a4c9, 0xe7976d13),
-+     TOBN(0x3923e095, 0x1c7e28d3), TOBN(0xb9293790, 0x3f6bb577),
-+     TOBN(0xdb567d6a, 0xc42bd6d2), TOBN(0x6df86468, 0xbb1f96ae),
-+     TOBN(0x0efe5b1a, 0x4843b28e), TOBN(0x961bbb05, 0x6379b240),
-+     TOBN(0xb6caf5f0, 0x70a6a26b), TOBN(0x70686c0d, 0x328e6e39),
-+     TOBN(0x80da06cf, 0x895fc8d3), TOBN(0x804d8810, 0xb363fdc9),
-+     TOBN(0xbe22877b, 0x207f1670), TOBN(0x9b0dd188, 0x4e615291),
-+     TOBN(0x625ae8dc, 0x97a3c2bf), TOBN(0x08584ef7, 0x439b86e8),
-+     TOBN(0xde7190a5, 0xdcd898ff), TOBN(0x26286c40, 0x2058ee3d),
-+     TOBN(0x3db0b217, 0x5f87b1c1), TOBN(0xcc334771, 0x102a6db5),
-+     TOBN(0xd99de954, 0x2f770fb1), TOBN(0x97c1c620, 0x4cd7535e),
-+     TOBN(0xd3b6c448, 0x3f09cefc), TOBN(0xd725af15, 0x5a63b4f8),
-+     TOBN(0x0c95d24f, 0xc01e20ec), TOBN(0xdfd37494, 0x9ae7121f),
-+     TOBN(0x7d6ddb72, 0xec77b7ec), TOBN(0xfe079d3b, 0x0353a4ae),
-+     TOBN(0x3066e70a, 0x2e6ac8d2), TOBN(0x9c6b5a43, 0x106e5c05),
-+     TOBN(0x52d3c6f5, 0xede59b8c), TOBN(0x30d6a5c3, 0xfccec9ae),
-+     TOBN(0xedec7c22, 0x4fc0a9ef), TOBN(0x190ff083, 0x95c16ced),
-+     TOBN(0xbe12ec8f, 0x94de0fde), TOBN(0x0d131ab8, 0x852d3433),
-+     TOBN(0x42ace07e, 0x85701291), TOBN(0x94793ed9, 0x194061a8),
-+     TOBN(0x30e83ed6, 0xd7f4a485), TOBN(0x9eec7269, 0xf9eeff4d),
-+     TOBN(0x90acba59, 0x0c9d8005), TOBN(0x5feca458, 0x1e79b9d1),
-+     TOBN(0x8fbe5427, 0x1d506a1e), TOBN(0xa32b2c8e, 0x2439cfa7),
-+     TOBN(0x1671c173, 0x73dd0b4e), TOBN(0x37a28214, 0x44a054c6),
-+     TOBN(0x81760a1b, 0x4e8b53f1), TOBN(0xa6c04224, 0xf9f93b9e),
-+     TOBN(0x18784b34, 0xcf671e3c), TOBN(0x81bbecd2, 0xcda9b994),
-+     TOBN(0x38831979, 0xb2ab3848), TOBN(0xef54feb7, 0xf2e03c2d),
-+     TOBN(0xcf197ca7, 0xfb8088fa), TOBN(0x01427247, 0x4ddc96c5),
-+     TOBN(0xa2d2550a, 0x30777176), TOBN(0x53469898, 0x4d0cf71d),
-+     TOBN(0x6ce937b8, 0x3a2aaac6), TOBN(0xe9f91dc3, 0x5af38d9b),
-+     TOBN(0x2598ad83, 0xc8bf2899), TOBN(0x8e706ac9, 0xb5536c16),
-+     TOBN(0x40dc7495, 0xf688dc98), TOBN(0x26490cd7, 0x124c4afc),
-+     TOBN(0xe651ec84, 0x1f18775c), TOBN(0x393ea6c3, 0xb4fdaf4a),
-+     TOBN(0x1e1f3343, 0x7f338e0d), TOBN(0x39fb832b, 0x6053e7b5),
-+     TOBN(0x46e702da, 0x619e14d5), TOBN(0x859cacd1, 0xcdeef6e0),
-+     TOBN(0x63b99ce7, 0x4462007d), TOBN(0xb8ab48a5, 0x4cb5f5b7),
-+     TOBN(0x9ec673d2, 0xf55edde7), TOBN(0xd1567f74, 0x8cfaefda),
-+     TOBN(0x46381b6b, 0x0887bcec), TOBN(0x694497ce, 0xe178f3c2),
-+     TOBN(0x5e6525e3, 0x1e6266cb), TOBN(0x5931de26, 0x697d6413),
-+     TOBN(0x87f8df7c, 0x0e58d493), TOBN(0xb1ae5ed0, 0x58b73f12),
-+     TOBN(0xc368f784, 0xdea0c34d), TOBN(0x9bd0a120, 0x859a91a0),
-+     TOBN(0xb00d88b7, 0xcc863c68), TOBN(0x3a1cc11e, 0x3d1f4d65),
-+     TOBN(0xea38e0e7, 0x0aa85593), TOBN(0x37f13e98, 0x7dc4aee8),
-+     TOBN(0x10d38667, 0xbc947bad), TOBN(0x738e07ce, 0x2a36ee2e),
-+     TOBN(0xc93470cd, 0xc577fcac), TOBN(0xdee1b616, 0x2782470d),
-+     TOBN(0x36a25e67, 0x2e793d12), TOBN(0xd6aa6cae, 0xe0f186da),
-+     TOBN(0x474d0fd9, 0x80e07af7), TOBN(0xf7cdc47d, 0xba8a5cd4),
-+     TOBN(0x28af6d9d, 0xab15247f), TOBN(0x7c789c10, 0x493a537f),
-+     TOBN(0x7ac9b110, 0x23a334e7), TOBN(0x0236ac09, 0x12c9c277),
-+     TOBN(0xa7e5bd25, 0x1d7a5144), TOBN(0x098b9c2a, 0xf13ec4ec),
-+     TOBN(0x3639daca, 0xd3f0abca), TOBN(0x642da81a, 0xa23960f9),
-+     TOBN(0x7d2e5c05, 0x4f7269b1), TOBN(0xfcf30777, 0xe287c385),
-+     TOBN(0x10edc84f, 0xf2a46f21), TOBN(0x35441757, 0x4f43fa36),
-+     TOBN(0xf1327899, 0xfd703431), TOBN(0xa438d7a6, 0x16dd587a),
-+     TOBN(0x65c34c57, 0xe9c8352d), TOBN(0xa728edab, 0x5cc5a24e),
-+     TOBN(0xaed78abc, 0x42531689), TOBN(0x0a51a0e8, 0x010963ef),
-+     TOBN(0x5776fa0a, 0xd717d9b3), TOBN(0xf356c239, 0x7dd3428b),
-+     TOBN(0x29903fff, 0x8d3a3dac), TOBN(0x409597fa, 0x3d94491f),
-+     TOBN(0x4cd7a5ff, 0xbf4a56a4), TOBN(0xe5096474, 0x8adab462),
-+     TOBN(0xa97b5126, 0x5c3427b0), TOBN(0x6401405c, 0xd282c9bd),
-+     TOBN(0x3629f8d7, 0x222c5c45), TOBN(0xb1c02c16, 0xe8d50aed),
-+     TOBN(0xbea2ed75, 0xd9635bc9), TOBN(0x226790c7, 0x6e24552f),
-+     TOBN(0x3c33f2a3, 0x65f1d066), TOBN(0x2a43463e, 0x6dfccc2e),
-+     TOBN(0x8cc3453a, 0xdb483761), TOBN(0xe7cc6085, 0x65d5672b),
-+     TOBN(0x277ed6cb, 0xde3efc87), TOBN(0x19f2f368, 0x69234eaf),
-+     TOBN(0x9aaf4317, 0x5c0b800b), TOBN(0x1f1e7c89, 0x8b6da6e2),
-+     TOBN(0x6cfb4715, 0xb94ec75e), TOBN(0xd590dd5f, 0x453118c2),
-+     TOBN(0x14e49da1, 0x1f17a34c), TOBN(0x5420ab39, 0x235a1456),
-+     TOBN(0xb7637241, 0x2f50363b), TOBN(0x7b15d623, 0xc3fabb6e),
-+     TOBN(0xa0ef40b1, 0xe274e49c), TOBN(0x5cf50744, 0x96b1860a),
-+     TOBN(0xd6583fbf, 0x66afe5a4), TOBN(0x44240510, 0xf47e3e9a),
-+     TOBN(0x99254343, 0x11b2d595), TOBN(0xf1367499, 0xeec8df57),
-+     TOBN(0x3cb12c61, 0x3e73dd05), TOBN(0xd248c033, 0x7dac102a),
-+     TOBN(0xcf154f13, 0xa77739f5), TOBN(0xbf4288cb, 0x23d2af42),
-+     TOBN(0xaa64c9b6, 0x32e4a1cf), TOBN(0xee8c07a8, 0xc8a208f3),
-+     TOBN(0xe10d4999, 0x6fe8393f), TOBN(0x0f809a3f, 0xe91f3a32),
-+     TOBN(0x61096d1c, 0x802f63c8), TOBN(0x289e1462, 0x57750d3d),
-+     TOBN(0xed06167e, 0x9889feea), TOBN(0xd5c9c0e2, 0xe0993909),
-+     TOBN(0x46fca0d8, 0x56508ac6), TOBN(0x91826047, 0x4f1b8e83),
-+     TOBN(0x4f2c877a, 0x9a4a2751), TOBN(0x71bd0072, 0xcae6fead),
-+     TOBN(0x38df8dcc, 0x06aa1941), TOBN(0x5a074b4c, 0x63beeaa8),
-+     TOBN(0xd6d65934, 0xc1cec8ed), TOBN(0xa6ecb49e, 0xaabc03bd),
-+     TOBN(0xaade91c2, 0xde8a8415), TOBN(0xcfb0efdf, 0x691136e0),
-+     TOBN(0x11af45ee, 0x23ab3495), TOBN(0xa132df88, 0x0b77463d),
-+     TOBN(0x8923c15c, 0x815d06f4), TOBN(0xc3ceb3f5, 0x0d61a436),
-+     TOBN(0xaf52291d, 0xe88fb1da), TOBN(0xea057974, 0x1da12179),
-+     TOBN(0xb0d7218c, 0xd2fef720), TOBN(0x6c0899c9, 0x8e1d8845),
-+     TOBN(0x98157504, 0x752ddad7), TOBN(0xd60bd74f, 0xa1a68a97),
-+     TOBN(0x7047a3a9, 0xf658fb99), TOBN(0x1f5d86d6, 0x5f8511e4),
-+     TOBN(0xb8a4bc42, 0x4b5a6d88), TOBN(0x69eb2c33, 0x1abefa7d),
-+     TOBN(0x95bf39e8, 0x13c9c510), TOBN(0xf571960a, 0xd48aab43),
-+     TOBN(0x7e8cfbcf, 0x704e23c6), TOBN(0xc71b7d22, 0x28aaa65b),
-+     TOBN(0xa041b2bd, 0x245e3c83), TOBN(0x69b98834, 0xd21854ff),
-+     TOBN(0x89d227a3, 0x963bfeec), TOBN(0x99947aaa, 0xde7da7cb),
-+     TOBN(0x1d9ee9db, 0xee68a9b1), TOBN(0x0a08f003, 0x698ec368),
-+     TOBN(0xe9ea4094, 0x78ef2487), TOBN(0xc8d2d415, 0x02cfec26),
-+     TOBN(0xc52f9a6e, 0xb7dcf328), TOBN(0x0ed489e3, 0x85b6a937),
-+     TOBN(0x9b94986b, 0xbef3366e), TOBN(0x0de59c70, 0xedddddb8),
-+     TOBN(0xffdb748c, 0xeadddbe2), TOBN(0x9b9784bb, 0x8266ea40),
-+     TOBN(0x142b5502, 0x1a93507a), TOBN(0xb4cd1187, 0x8d3c06cf),
-+     TOBN(0xdf70e76a, 0x91ec3f40), TOBN(0x484e81ad, 0x4e7553c2),
-+     TOBN(0x830f87b5, 0x272e9d6e), TOBN(0xea1c93e5, 0xc6ff514a),
-+     TOBN(0x67cc2adc, 0xc4192a8e), TOBN(0xc77e27e2, 0x42f4535a),
-+     TOBN(0x9cdbab36, 0xd2b713c5), TOBN(0x86274ea0, 0xcf7b0cd3),
-+     TOBN(0x784680f3, 0x09af826b), TOBN(0xbfcc837a, 0x0c72dea3),
-+     TOBN(0xa8bdfe9d, 0xd6529b73), TOBN(0x708aa228, 0x63a88002),
-+     TOBN(0x6c7a9a54, 0xc91d45b9), TOBN(0xdf1a38bb, 0xfd004f56),
-+     TOBN(0x2e8c9a26, 0xb8bad853), TOBN(0x2d52cea3, 0x3723eae7),
-+     TOBN(0x054d6d81, 0x56ca2830), TOBN(0xa3317d14, 0x9a8dc411),
-+     TOBN(0xa08662fe, 0xfd4ddeda), TOBN(0xed2a153a, 0xb55d792b),
-+     TOBN(0x7035c16a, 0xbfc6e944), TOBN(0xb6bc5834, 0x00171cf3),
-+     TOBN(0xe27152b3, 0x83d102b6), TOBN(0xfe695a47, 0x0646b848),
-+     TOBN(0xa5bb09d8, 0x916e6d37), TOBN(0xb4269d64, 0x0d17015e),
-+     TOBN(0x8d8156a1, 0x0a1d2285), TOBN(0xfeef6c51, 0x46d26d72),
-+     TOBN(0x9dac57c8, 0x4c5434a7), TOBN(0x0282e5be, 0x59d39e31),
-+     TOBN(0xedfff181, 0x721c486d), TOBN(0x301baf10, 0xbc58824e),
-+     TOBN(0x8136a6aa, 0x00570031), TOBN(0x55aaf78c, 0x1cddde68),
-+     TOBN(0x26829371, 0x59c63952), TOBN(0x3a3bd274, 0x8bc25baf),
-+     TOBN(0xecdf8657, 0xb7e52dc3), TOBN(0x2dd8c087, 0xfd78e6c8),
-+     TOBN(0x20553274, 0xf5531461), TOBN(0x8b4a1281, 0x5d95499b),
-+     TOBN(0xe2c8763a, 0x1a80f9d2), TOBN(0xd1dbe32b, 0x4ddec758),
-+     TOBN(0xaf12210d, 0x30c34169), TOBN(0xba74a953, 0x78baa533),
-+     TOBN(0x3d133c6e, 0xa438f254), TOBN(0xa431531a, 0x201bef5b),
-+     TOBN(0x15295e22, 0xf669d7ec), TOBN(0xca374f64, 0x357fb515),
-+     TOBN(0x8a8406ff, 0xeaa3fdb3), TOBN(0x106ae448, 0xdf3f2da8),
-+     TOBN(0x8f9b0a90, 0x33c8e9a1), TOBN(0x234645e2, 0x71ad5885),
-+     TOBN(0x3d083224, 0x1c0aed14), TOBN(0xf10a7d3e, 0x7a942d46),
-+     TOBN(0x7c11deee, 0x40d5c9be), TOBN(0xb2bae7ff, 0xba84ed98),
-+     TOBN(0x93e97139, 0xaad58ddd), TOBN(0x3d872796, 0x3f6d1fa3),
-+     TOBN(0x483aca81, 0x8569ff13), TOBN(0x8b89a5fb, 0x9a600f72),
-+     TOBN(0x4cbc27c3, 0xc06f2b86), TOBN(0x22130713, 0x63ad9c0b),
-+     TOBN(0xb5358b1e, 0x48ac2840), TOBN(0x18311294, 0xecba9477),
-+     TOBN(0xda58f990, 0xa6946b43), TOBN(0x3098baf9, 0x9ab41819),
-+     TOBN(0x66c4c158, 0x4198da52), TOBN(0xab4fc17c, 0x146bfd1b),
-+     TOBN(0x2f0a4c3c, 0xbf36a908), TOBN(0x2ae9e34b, 0x58cf7838),
-+     TOBN(0xf411529e, 0x3fa11b1f), TOBN(0x21e43677, 0x974af2b4),
-+     TOBN(0x7c20958e, 0xc230793b), TOBN(0x710ea885, 0x16e840f3),
-+     TOBN(0xfc0b21fc, 0xc5dc67cf), TOBN(0x08d51647, 0x88405718),
-+     TOBN(0xd955c21f, 0xcfe49eb7), TOBN(0x9722a5d5, 0x56dd4a1f),
-+     TOBN(0xc9ef50e2, 0xc861baa5), TOBN(0xc0c21a5d, 0x9505ac3e),
-+     TOBN(0xaf6b9a33, 0x8b7c063f), TOBN(0xc6370339, 0x2f4779c1),
-+     TOBN(0x22df99c7, 0x638167c3), TOBN(0xfe6ffe76, 0x795db30c),
-+     TOBN(0x2b822d33, 0xa4854989), TOBN(0xfef031dd, 0x30563aa5),
-+     TOBN(0x16b09f82, 0xd57c667f), TOBN(0xc70312ce, 0xcc0b76f1),
-+     TOBN(0xbf04a9e6, 0xc9118aec), TOBN(0x82fcb419, 0x3409d133),
-+     TOBN(0x1a8ab385, 0xab45d44d), TOBN(0xfba07222, 0x617b83a3),
-+     TOBN(0xb05f50dd, 0x58e81b52), TOBN(0x1d8db553, 0x21ce5aff),
-+     TOBN(0x3097b8d4, 0xe344a873), TOBN(0x7d8d116d, 0xfe36d53e),
-+     TOBN(0x6db22f58, 0x7875e750), TOBN(0x2dc5e373, 0x43e144ea),
-+     TOBN(0xc05f32e6, 0xe799eb95), TOBN(0xe9e5f4df, 0x6899e6ec),
-+     TOBN(0xbdc3bd68, 0x1fab23d5), TOBN(0xb72b8ab7, 0x73af60e6),
-+     TOBN(0x8db27ae0, 0x2cecc84a), TOBN(0x600016d8, 0x7bdb871c),
-+     TOBN(0x42a44b13, 0xd7c46f58), TOBN(0xb8919727, 0xc3a77d39),
-+     TOBN(0xcfc6bbbd, 0xdafd6088), TOBN(0x1a740146, 0x6bd20d39),
-+     TOBN(0x8c747abd, 0x98c41072), TOBN(0x4c91e765, 0xbdf68ea1),
-+     TOBN(0x7c95e5ca, 0x08819a78), TOBN(0xcf48b729, 0xc9587921),
-+     TOBN(0x091c7c5f, 0xdebbcc7d), TOBN(0x6f287404, 0xf0e05149),
-+     TOBN(0xf83b5ac2, 0x26cd44ec), TOBN(0x88ae32a6, 0xcfea250e),
-+     TOBN(0x6ac5047a, 0x1d06ebc5), TOBN(0xc7e550b4, 0xd434f781),
-+     TOBN(0x61ab1cf2, 0x5c727bd2), TOBN(0x2e4badb1, 0x1cf915b0),
-+     TOBN(0x1b4dadec, 0xf69d3920), TOBN(0xe61b1ca6, 0xf14c1dfe),
-+     TOBN(0x90b479cc, 0xbd6bd51f), TOBN(0x8024e401, 0x8045ec30),
-+     TOBN(0xcab29ca3, 0x25ef0e62), TOBN(0x4f2e9416, 0x49e4ebc0),
-+     TOBN(0x45eb40ec, 0x0ccced58), TOBN(0x25cd4b9c, 0x0da44f98),
-+     TOBN(0x43e06458, 0x871812c6), TOBN(0x99f80d55, 0x16cef651),
-+     TOBN(0x571340c9, 0xce6dc153), TOBN(0x138d5117, 0xd8665521),
-+     TOBN(0xacdb45bc, 0x4e07014d), TOBN(0x2f34bb38, 0x84b60b91),
-+     TOBN(0xf44a4fd2, 0x2ae8921e), TOBN(0xb039288e, 0x892ba1e2),
-+     TOBN(0x9da50174, 0xb1c180b2), TOBN(0x6b70ab66, 0x1693dc87),
-+     TOBN(0x7e9babc9, 0xe7057481), TOBN(0x4581ddef, 0x9c80dc41),
-+     TOBN(0x0c890da9, 0x51294682), TOBN(0x0b5629d3, 0x3f4736e5),
-+     TOBN(0x2340c79e, 0xb06f5b41), TOBN(0xa42e84ce, 0x4e243469),
-+     TOBN(0xf9a20135, 0x045a71a9), TOBN(0xefbfb415, 0xd27b6fb6),
-+     TOBN(0x25ebea23, 0x9d33cd6f), TOBN(0x9caedb88, 0xaa6c0af8),
-+     TOBN(0x53dc7e9a, 0xd9ce6f96), TOBN(0x3897f9fd, 0x51e0b15a),
-+     TOBN(0xf51cb1f8, 0x8e5d788e), TOBN(0x1aec7ba8, 0xe1d490ee),
-+     TOBN(0x265991e0, 0xcc58cb3c), TOBN(0x9f306e8c, 0x9fc3ad31),
-+     TOBN(0x5fed006e, 0x5040a0ac), TOBN(0xca9d5043, 0xfb476f2e),
-+     TOBN(0xa19c06e8, 0xbeea7a23), TOBN(0xd2865801, 0x0edabb63),
-+     TOBN(0xdb92293f, 0x6967469a), TOBN(0x2894d839, 0x8d8a8ed8),
-+     TOBN(0x87c9e406, 0xbbc77122), TOBN(0x8671c6f1, 0x2ea3a26a),
-+     TOBN(0xe42df8d6, 0xd7de9853), TOBN(0x2e3ce346, 0xb1f2bcc7),
-+     TOBN(0xda601dfc, 0x899d50cf), TOBN(0xbfc913de, 0xfb1b598f),
-+     TOBN(0x81c4909f, 0xe61f7908), TOBN(0x192e304f, 0x9bbc7b29),
-+     TOBN(0xc3ed8738, 0xc104b338), TOBN(0xedbe9e47, 0x783f5d61),
-+     TOBN(0x0c06e9be, 0x2db30660), TOBN(0xda3e613f, 0xc0eb7d8e),
-+     TOBN(0xd8fa3e97, 0x322e096e), TOBN(0xfebd91e8, 0xd336e247),
-+     TOBN(0x8f13ccc4, 0xdf655a49), TOBN(0xa9e00dfc, 0x5eb20210),
-+     TOBN(0x84631d0f, 0xc656b6ea), TOBN(0x93a058cd, 0xd8c0d947),
-+     TOBN(0x6846904a, 0x67bd3448), TOBN(0x4a3d4e1a, 0xf394fd5c),
-+     TOBN(0xc102c1a5, 0xdb225f52), TOBN(0xe3455bba, 0xfc4f5e9a),
-+     TOBN(0x6b36985b, 0x4b9ad1ce), TOBN(0xa9818536, 0x5bb7f793),
-+     TOBN(0x6c25e1d0, 0x48b1a416), TOBN(0x1381dd53, 0x3c81bee7),
-+     TOBN(0xd2a30d61, 0x7a4a7620), TOBN(0xc8412926, 0x39b8944c),
-+     TOBN(0x3c1c6fbe, 0x7a97c33a), TOBN(0x941e541d, 0x938664e7),
-+     TOBN(0x417499e8, 0x4a34f239), TOBN(0x15fdb83c, 0xb90402d5),
-+     TOBN(0xb75f46bf, 0x433aa832), TOBN(0xb61e15af, 0x63215db1),
-+     TOBN(0xaabe59d4, 0xa127f89a), TOBN(0x5d541e0c, 0x07e816da),
-+     TOBN(0xaaba0659, 0xa618b692), TOBN(0x55327733, 0x17266026),
-+     TOBN(0xaf53a0fc, 0x95f57552), TOBN(0x32947650, 0x6cacb0c9),
-+     TOBN(0x253ff58d, 0xc821be01), TOBN(0xb0309531, 0xa06f1146),
-+     TOBN(0x59bbbdf5, 0x05c2e54d), TOBN(0x158f27ad, 0x26e8dd22),
-+     TOBN(0xcc5b7ffb, 0x397e1e53), TOBN(0xae03f65b, 0x7fc1e50d),
-+     TOBN(0xa9784ebd, 0x9c95f0f9), TOBN(0x5ed9deb2, 0x24640771),
-+     TOBN(0x31244af7, 0x035561c4), TOBN(0x87332f3a, 0x7ee857de),
-+     TOBN(0x09e16e9e, 0x2b9e0d88), TOBN(0x52d910f4, 0x56a06049),
-+     TOBN(0x507ed477, 0xa9592f48), TOBN(0x85cb917b, 0x2365d678),
-+     TOBN(0xf8511c93, 0x4c8998d1), TOBN(0x2186a3f1, 0x730ea58f),
-+     TOBN(0x50189626, 0xb2029db0), TOBN(0x9137a6d9, 0x02ceb75a),
-+     TOBN(0x2fe17f37, 0x748bc82c), TOBN(0x87c2e931, 0x80469f8c),
-+     TOBN(0x850f71cd, 0xbf891aa2), TOBN(0x0ca1b89b, 0x75ec3d8d),
-+     TOBN(0x516c43aa, 0x5e1cd3cd), TOBN(0x89397808, 0x9a887c28),
-+     TOBN(0x0059c699, 0xddea1f9f), TOBN(0x7737d6fa, 0x8e6868f7),
-+     TOBN(0x6d93746a, 0x60f1524b), TOBN(0x36985e55, 0xba052aa7),
-+     TOBN(0x41b1d322, 0xed923ea5), TOBN(0x3429759f, 0x25852a11),
-+     TOBN(0xbeca6ec3, 0x092e9f41), TOBN(0x3a238c66, 0x62256bbd),
-+     TOBN(0xd82958ea, 0x70ad487d), TOBN(0x4ac8aaf9, 0x65610d93),
-+     TOBN(0x3fa101b1, 0x5e4ccab0), TOBN(0x9bf430f2, 0x9de14bfb),
-+     TOBN(0xa10f5cc6, 0x6531899d), TOBN(0x590005fb, 0xea8ce17d),
-+     TOBN(0xc437912f, 0x24544cb6), TOBN(0x9987b71a, 0xd79ac2e3),
-+     TOBN(0x13e3d9dd, 0xc058a212), TOBN(0x00075aac, 0xd2de9606),
-+     TOBN(0x80ab508b, 0x6cac8369), TOBN(0x87842be7, 0xf54f6c89),
-+     TOBN(0xa7ad663d, 0x6bc532a4), TOBN(0x67813de7, 0x78a91bc8),
-+     TOBN(0x5dcb61ce, 0xc3427239), TOBN(0x5f3c7cf0, 0xc56934d9),
-+     TOBN(0xc079e0fb, 0xe3191591), TOBN(0xe40896bd, 0xb01aada7),
-+     TOBN(0x8d466791, 0x0492d25f), TOBN(0x8aeb30c9, 0xe7408276),
-+     TOBN(0xe9437495, 0x9287aacc), TOBN(0x23d4708d, 0x79fe03d4),
-+     TOBN(0x8cda9cf2, 0xd0c05199), TOBN(0x502fbc22, 0xfae78454),
-+     TOBN(0xc0bda9df, 0xf572a182), TOBN(0x5f9b71b8, 0x6158b372),
-+     TOBN(0xe0f33a59, 0x2b82dd07), TOBN(0x76302735, 0x9523032e),
-+     TOBN(0x7fe1a721, 0xc4505a32), TOBN(0x7b6e3e82, 0xf796409f),}
-+    ,
-+    {TOBN(0xe3417bc0, 0x35d0b34a), TOBN(0x440b386b, 0x8327c0a7),
-+     TOBN(0x8fb7262d, 0xac0362d1), TOBN(0x2c41114c, 0xe0cdf943),
-+     TOBN(0x2ba5cef1, 0xad95a0b1), TOBN(0xc09b37a8, 0x67d54362),
-+     TOBN(0x26d6cdd2, 0x01e486c9), TOBN(0x20477abf, 0x42ff9297),
-+     TOBN(0xa004dcb3, 0x292a9287), TOBN(0xddc15cf6, 0x77b092c7),
-+     TOBN(0x083a8464, 0x806c0605), TOBN(0x4a68df70, 0x3db997b0),
-+     TOBN(0x9c134e45, 0x05bf7dd0), TOBN(0xa4e63d39, 0x8ccf7f8c),
-+     TOBN(0xa6e6517f, 0x41b5f8af), TOBN(0xaa8b9342, 0xad7bc1cc),
-+     TOBN(0x126f35b5, 0x1e706ad9), TOBN(0xb99cebb4, 0xc3a9ebdf),
-+     TOBN(0xa75389af, 0xbf608d90), TOBN(0x76113c4f, 0xc6c89858),
-+     TOBN(0x80de8eb0, 0x97e2b5aa), TOBN(0x7e1022cc, 0x63b91304),
-+     TOBN(0x3bdab605, 0x6ccc066c), TOBN(0x33cbb144, 0xb2edf900),
-+     TOBN(0xc4176471, 0x7af715d2), TOBN(0xe2f7f594, 0xd0134a96),
-+     TOBN(0x2c1873ef, 0xa41ec956), TOBN(0xe4e7b4f6, 0x77821304),
-+     TOBN(0xe5c8ff97, 0x88d5374a), TOBN(0x2b915e63, 0x80823d5b),
-+     TOBN(0xea6bc755, 0xb2ee8fe2), TOBN(0x6657624c, 0xe7112651),
-+     TOBN(0x157af101, 0xdace5aca), TOBN(0xc4fdbcf2, 0x11a6a267),
-+     TOBN(0xdaddf340, 0xc49c8609), TOBN(0x97e49f52, 0xe9604a65),
-+     TOBN(0x9be8e790, 0x937e2ad5), TOBN(0x846e2508, 0x326e17f1),
-+     TOBN(0x3f38007a, 0x0bbbc0dc), TOBN(0xcf03603f, 0xb11e16d6),
-+     TOBN(0xd6f800e0, 0x7442f1d5), TOBN(0x475607d1, 0x66e0e3ab),
-+     TOBN(0x82807f16, 0xb7c64047), TOBN(0x8858e1e3, 0xa749883d),
-+     TOBN(0x5859120b, 0x8231ee10), TOBN(0x1b80e7eb, 0x638a1ece),
-+     TOBN(0xcb72525a, 0xc6aa73a4), TOBN(0xa7cdea3d, 0x844423ac),
-+     TOBN(0x5ed0c007, 0xf8ae7c38), TOBN(0x6db07a5c, 0x3d740192),
-+     TOBN(0xbe5e9c2a, 0x5fe36db3), TOBN(0xd5b9d57a, 0x76e95046),
-+     TOBN(0x54ac32e7, 0x8eba20f2), TOBN(0xef11ca8f, 0x71b9a352),
-+     TOBN(0x305e373e, 0xff98a658), TOBN(0xffe5a100, 0x823eb667),
-+     TOBN(0x57477b11, 0xe51732d2), TOBN(0xdfd6eb28, 0x2538fc0e),
-+     TOBN(0x5c43b0cc, 0x3b39eec5), TOBN(0x6af12778, 0xcb36cc57),
-+     TOBN(0x70b0852d, 0x06c425ae), TOBN(0x6df92f8c, 0x5c221b9b),
-+     TOBN(0x6c8d4f9e, 0xce826d9c), TOBN(0xf59aba7b, 0xb49359c3),
-+     TOBN(0x5c8ed8d5, 0xda64309d), TOBN(0x61a6de56, 0x91b30704),
-+     TOBN(0xd6b52f6a, 0x2f9b5808), TOBN(0x0eee4194, 0x98c958a7),
-+     TOBN(0xcddd9aab, 0x771e4caa), TOBN(0x83965dfd, 0x78bc21be),
-+     TOBN(0x02affce3, 0xb3b504f5), TOBN(0x30847a21, 0x561c8291),
-+     TOBN(0xd2eb2cf1, 0x52bfda05), TOBN(0xe0e4c4e9, 0x6197b98c),
-+     TOBN(0x1d35076c, 0xf8a1726f), TOBN(0x6c06085b, 0x2db11e3d),
-+     TOBN(0x15c0c4d7, 0x4463ba14), TOBN(0x9d292f83, 0x0030238c),
-+     TOBN(0x1311ee8b, 0x3727536d), TOBN(0xfeea86ef, 0xbeaedc1e),
-+     TOBN(0xb9d18cd3, 0x66131e2e), TOBN(0xf31d974f, 0x80fe2682),
-+     TOBN(0xb6e49e0f, 0xe4160289), TOBN(0x7c48ec0b, 0x08e92799),
-+     TOBN(0x818111d8, 0xd1989aa7), TOBN(0xb34fa0aa, 0xebf926f9),
-+     TOBN(0xdb5fe2f5, 0xa245474a), TOBN(0xf80a6ebb, 0x3c7ca756),
-+     TOBN(0xa7f96054, 0xafa05dd8), TOBN(0x26dfcf21, 0xfcaf119e),
-+     TOBN(0xe20ef2e3, 0x0564bb59), TOBN(0xef4dca50, 0x61cb02b8),
-+     TOBN(0xcda7838a, 0x65d30672), TOBN(0x8b08d534, 0xfd657e86),
-+     TOBN(0x4c5b4395, 0x46d595c8), TOBN(0x39b58725, 0x425cb836),
-+     TOBN(0x8ea61059, 0x3de9abe3), TOBN(0x40434881, 0x9cdc03be),
-+     TOBN(0x9b261245, 0xcfedce8c), TOBN(0x78c318b4, 0xcf5234a1),
-+     TOBN(0x510bcf16, 0xfde24c99), TOBN(0x2a77cb75, 0xa2c2ff5d),
-+     TOBN(0x9c895c2b, 0x27960fb4), TOBN(0xd30ce975, 0xb0eda42b),
-+     TOBN(0xfda85393, 0x1a62cc26), TOBN(0x23c69b96, 0x50c0e052),
-+     TOBN(0xa227df15, 0xbfc633f3), TOBN(0x2ac78848, 0x1bae7d48),
-+     TOBN(0x487878f9, 0x187d073d), TOBN(0x6c2be919, 0x967f807d),
-+     TOBN(0x765861d8, 0x336e6d8f), TOBN(0x88b8974c, 0xce528a43),
-+     TOBN(0x09521177, 0xff57d051), TOBN(0x2ff38037, 0xfb6a1961),
-+     TOBN(0xfc0aba74, 0xa3d76ad4), TOBN(0x7c764803, 0x25a7ec17),
-+     TOBN(0x7532d75f, 0x48879bc8), TOBN(0xea7eacc0, 0x58ce6bc1),
-+     TOBN(0xc82176b4, 0x8e896c16), TOBN(0x9a30e0b2, 0x2c750fed),
-+     TOBN(0xc37e2c2e, 0x421d3aa4), TOBN(0xf926407c, 0xe84fa840),
-+     TOBN(0x18abc03d, 0x1454e41c), TOBN(0x26605ecd, 0x3f7af644),
-+     TOBN(0x242341a6, 0xd6a5eabf), TOBN(0x1edb84f4, 0x216b668e),
-+     TOBN(0xd836edb8, 0x04010102), TOBN(0x5b337ce7, 0x945e1d8c),
-+     TOBN(0xd2075c77, 0xc055dc14), TOBN(0x2a0ffa25, 0x81d89cdf),
-+     TOBN(0x8ce815ea, 0x6ffdcbaf), TOBN(0xa3428878, 0xfb648867),
-+     TOBN(0x277699cf, 0x884655fb), TOBN(0xfa5b5bd6, 0x364d3e41),
-+     TOBN(0x01f680c6, 0x441e1cb7), TOBN(0x3fd61e66, 0xb70a7d67),
-+     TOBN(0x666ba2dc, 0xcc78cf66), TOBN(0xb3018174, 0x6fdbff77),
-+     TOBN(0x8d4dd0db, 0x168d4668), TOBN(0x259455d0, 0x1dab3a2a),
-+     TOBN(0xf58564c5, 0xcde3acec), TOBN(0x77141925, 0x13adb276),
-+     TOBN(0x527d725d, 0x8a303f65), TOBN(0x55deb6c9, 0xe6f38f7b),
-+     TOBN(0xfd5bb657, 0xb1fa70fb), TOBN(0xfa07f50f, 0xd8073a00),
-+     TOBN(0xf72e3aa7, 0xbca02500), TOBN(0xf68f895d, 0x9975740d),
-+     TOBN(0x30112060, 0x5cae2a6a), TOBN(0x01bd7218, 0x02874842),
-+     TOBN(0x3d423891, 0x7ce47bd3), TOBN(0xa66663c1, 0x789544f6),
-+     TOBN(0x864d05d7, 0x3272d838), TOBN(0xe22924f9, 0xfa6295c5),
-+     TOBN(0x8189593f, 0x6c2fda32), TOBN(0x330d7189, 0xb184b544),
-+     TOBN(0x79efa62c, 0xbde1f714), TOBN(0x35771c94, 0xe5cb1a63),
-+     TOBN(0x2f4826b8, 0x641c8332), TOBN(0x00a894fb, 0xc8cee854),
-+     TOBN(0xb4b9a39b, 0x36194d40), TOBN(0xe857a7c5, 0x77612601),
-+     TOBN(0xf4209dd2, 0x4ecf2f58), TOBN(0x82b9e66d, 0x5a033487),
-+     TOBN(0xc1e36934, 0xe4e8b9dd), TOBN(0xd2372c9d, 0xa42377d7),
-+     TOBN(0x51dc94c7, 0x0e3ae43b), TOBN(0x4c57761e, 0x04474f6f),
-+     TOBN(0xdcdacd0a, 0x1058a318), TOBN(0x369cf3f5, 0x78053a9a),
-+     TOBN(0xc6c3de50, 0x31c68de2), TOBN(0x4653a576, 0x3c4b6d9f),
-+     TOBN(0x1688dd5a, 0xaa4e5c97), TOBN(0x5be80aa1, 0xb7ab3c74),
-+     TOBN(0x70cefe7c, 0xbc65c283), TOBN(0x57f95f13, 0x06867091),
-+     TOBN(0xa39114e2, 0x4415503b), TOBN(0xc08ff7c6, 0x4cbb17e9),
-+     TOBN(0x1eff674d, 0xd7dec966), TOBN(0x6d4690af, 0x53376f63),
-+     TOBN(0xff6fe32e, 0xea74237b), TOBN(0xc436d17e, 0xcd57508e),
-+     TOBN(0x15aa28e1, 0xedcc40fe), TOBN(0x0d769c04, 0x581bbb44),
-+     TOBN(0xc240b6de, 0x34eaacda), TOBN(0xd9e116e8, 0x2ba0f1de),
-+     TOBN(0xcbe45ec7, 0x79438e55), TOBN(0x91787c9d, 0x96f752d7),
-+     TOBN(0x897f532b, 0xf129ac2f), TOBN(0xd307b7c8, 0x5a36e22c),
-+     TOBN(0x91940675, 0x749fb8f3), TOBN(0xd14f95d0, 0x157fdb28),
-+     TOBN(0xfe51d029, 0x6ae55043), TOBN(0x8931e98f, 0x44a87de1),
-+     TOBN(0xe57f1cc6, 0x09e4fee2), TOBN(0x0d063b67, 0x4e072d92),
-+     TOBN(0x70a998b9, 0xed0e4316), TOBN(0xe74a736b, 0x306aca46),
-+     TOBN(0xecf0fbf2, 0x4fda97c7), TOBN(0xa40f65cb, 0x3e178d93),
-+     TOBN(0x16253604, 0x16df4285), TOBN(0xb0c9babb, 0xd0c56ae2),
-+     TOBN(0x73032b19, 0xcfc5cfc3), TOBN(0xe497e5c3, 0x09752056),
-+     TOBN(0x12096bb4, 0x164bda96), TOBN(0x1ee42419, 0xa0b74da1),
-+     TOBN(0x8fc36243, 0x403826ba), TOBN(0x0c8f0069, 0xdc09e660),
-+     TOBN(0x8667e981, 0xc27253c9), TOBN(0x05a6aefb, 0x92b36a45),
-+     TOBN(0xa62c4b36, 0x9cb7bb46), TOBN(0x8394f375, 0x11f7027b),
-+     TOBN(0x747bc79c, 0x5f109d0f), TOBN(0xcad88a76, 0x5b8cc60a),
-+     TOBN(0x80c5a66b, 0x58f09e68), TOBN(0xe753d451, 0xf6127eac),
-+     TOBN(0xc44b74a1, 0x5b0ec6f5), TOBN(0x47989fe4, 0x5289b2b8),
-+     TOBN(0x745f8484, 0x58d6fc73), TOBN(0xec362a6f, 0xf61c70ab),
-+     TOBN(0x070c98a7, 0xb3a8ad41), TOBN(0x73a20fc0, 0x7b63db51),
-+     TOBN(0xed2c2173, 0xf44c35f4), TOBN(0x8a56149d, 0x9acc9dca),
-+     TOBN(0x98f17881, 0x9ac6e0f4), TOBN(0x360fdeaf, 0xa413b5ed),
-+     TOBN(0x0625b8f4, 0xa300b0fd), TOBN(0xf1f4d76a, 0x5b3222d3),
-+     TOBN(0x9d6f5109, 0x587f76b8), TOBN(0x8b4ee08d, 0x2317fdb5),
-+     TOBN(0x88089bb7, 0x8c68b095), TOBN(0x95570e9a, 0x5808d9b9),
-+     TOBN(0xa395c36f, 0x35d33ae7), TOBN(0x200ea123, 0x50bb5a94),
-+     TOBN(0x20c789bd, 0x0bafe84b), TOBN(0x243ef52d, 0x0919276a),
-+     TOBN(0x3934c577, 0xe23ae233), TOBN(0xb93807af, 0xa460d1ec),
-+     TOBN(0xb72a53b1, 0xf8fa76a4), TOBN(0xd8914cb0, 0xc3ca4491),
-+     TOBN(0x2e128494, 0x3fb42622), TOBN(0x3b2700ac, 0x500907d5),
-+     TOBN(0xf370fb09, 0x1a95ec63), TOBN(0xf8f30be2, 0x31b6dfbd),
-+     TOBN(0xf2b2f8d2, 0x69e55f15), TOBN(0x1fead851, 0xcc1323e9),
-+     TOBN(0xfa366010, 0xd9e5eef6), TOBN(0x64d487b0, 0xe316107e),
-+     TOBN(0x4c076b86, 0xd23ddc82), TOBN(0x03fd344c, 0x7e0143f0),
-+     TOBN(0xa95362ff, 0x317af2c5), TOBN(0x0add3db7, 0xe18b7a4f),
-+     TOBN(0x9c673e3f, 0x8260e01b), TOBN(0xfbeb49e5, 0x54a1cc91),
-+     TOBN(0x91351bf2, 0x92f2e433), TOBN(0xc755e7ec, 0x851141eb),
-+     TOBN(0xc9a95139, 0x29607745), TOBN(0x0ca07420, 0xa26f2b28),
-+     TOBN(0xcb2790e7, 0x4bc6f9dd), TOBN(0x345bbb58, 0xadcaffc0),
-+     TOBN(0xc65ea38c, 0xbe0f27a2), TOBN(0x67c24d7c, 0x641fcb56),
-+     TOBN(0x2c25f0a7, 0xa9e2c757), TOBN(0x93f5cdb0, 0x16f16c49),
-+     TOBN(0x2ca5a9d7, 0xc5ee30a1), TOBN(0xd1593635, 0xb909b729),
-+     TOBN(0x804ce9f3, 0xdadeff48), TOBN(0xec464751, 0xb07c30c3),
-+     TOBN(0x89d65ff3, 0x9e49af6a), TOBN(0xf2d6238a, 0x6f3d01bc),
-+     TOBN(0x1095561e, 0x0bced843), TOBN(0x51789e12, 0xc8a13fd8),
-+     TOBN(0xd633f929, 0x763231df), TOBN(0x46df9f7d, 0xe7cbddef),
-+     TOBN(0x01c889c0, 0xcb265da8), TOBN(0xfce1ad10, 0xaf4336d2),
-+     TOBN(0x8d110df6, 0xfc6a0a7e), TOBN(0xdd431b98, 0x6da425dc),
-+     TOBN(0xcdc4aeab, 0x1834aabe), TOBN(0x84deb124, 0x8439b7fc),
-+     TOBN(0x8796f169, 0x3c2a5998), TOBN(0x9b9247b4, 0x7947190d),
-+     TOBN(0x55b9d9a5, 0x11597014), TOBN(0x7e9dd70d, 0x7b1566ee),
-+     TOBN(0x94ad78f7, 0xcbcd5e64), TOBN(0x0359ac17, 0x9bd4c032),
-+     TOBN(0x3b11baaf, 0x7cc222ae), TOBN(0xa6a6e284, 0xba78e812),
-+     TOBN(0x8392053f, 0x24cea1a0), TOBN(0xc97bce4a, 0x33621491),
-+     TOBN(0x7eb1db34, 0x35399ee9), TOBN(0x473f78ef, 0xece81ad1),
-+     TOBN(0x41d72fe0, 0xf63d3d0d), TOBN(0xe620b880, 0xafab62fc),
-+     TOBN(0x92096bc9, 0x93158383), TOBN(0x41a21357, 0x8f896f6c),
-+     TOBN(0x1b5ee2fa, 0xc7dcfcab), TOBN(0x650acfde, 0x9546e007),
-+     TOBN(0xc081b749, 0xb1b02e07), TOBN(0xda9e41a0, 0xf9eca03d),
-+     TOBN(0x013ba727, 0x175a54ab), TOBN(0xca0cd190, 0xea5d8d10),
-+     TOBN(0x85ea52c0, 0x95fd96a9), TOBN(0x2c591b9f, 0xbc5c3940),
-+     TOBN(0x6fb4d4e4, 0x2bad4d5f), TOBN(0xfa4c3590, 0xfef0059b),
-+     TOBN(0x6a10218a, 0xf5122294), TOBN(0x9a78a81a, 0xa85751d1),
-+     TOBN(0x04f20579, 0xa98e84e7), TOBN(0xfe1242c0, 0x4997e5b5),
-+     TOBN(0xe77a273b, 0xca21e1e4), TOBN(0xfcc8b1ef, 0x9411939d),
-+     TOBN(0xe20ea302, 0x92d0487a), TOBN(0x1442dbec, 0x294b91fe),
-+     TOBN(0x1f7a4afe, 0xbb6b0e8f), TOBN(0x1700ef74, 0x6889c318),
-+     TOBN(0xf5bbffc3, 0x70f1fc62), TOBN(0x3b31d4b6, 0x69c79cca),
-+     TOBN(0xe8bc2aab, 0xa7f6340d), TOBN(0xb0b08ab4, 0xa725e10a),
-+     TOBN(0x44f05701, 0xae340050), TOBN(0xba4b3016, 0x1cf0c569),
-+     TOBN(0x5aa29f83, 0xfbe19a51), TOBN(0x1b9ed428, 0xb71d752e),
-+     TOBN(0x1666e54e, 0xeb4819f5), TOBN(0x616cdfed, 0x9e18b75b),
-+     TOBN(0x112ed5be, 0x3ee27b0b), TOBN(0xfbf28319, 0x44c7de4d),
-+     TOBN(0xd685ec85, 0xe0e60d84), TOBN(0x68037e30, 0x1db7ee78),
-+     TOBN(0x5b65bdcd, 0x003c4d6e), TOBN(0x33e7363a, 0x93e29a6a),
-+     TOBN(0x995b3a61, 0x08d0756c), TOBN(0xd727f85c, 0x2faf134b),
-+     TOBN(0xfac6edf7, 0x1d337823), TOBN(0x99b9aa50, 0x0439b8b4),
-+     TOBN(0x722eb104, 0xe2b4e075), TOBN(0x49987295, 0x437c4926),
-+     TOBN(0xb1e4c0e4, 0x46a9b82d), TOBN(0xd0cb3197, 0x57a006f5),
-+     TOBN(0xf3de0f7d, 0xd7808c56), TOBN(0xb5c54d8f, 0x51f89772),
-+     TOBN(0x500a114a, 0xadbd31aa), TOBN(0x9afaaaa6, 0x295f6cab),
-+     TOBN(0x94705e21, 0x04cf667a), TOBN(0xfc2a811b, 0x9d3935d7),
-+     TOBN(0x560b0280, 0x6d09267c), TOBN(0xf19ed119, 0xf780e53b),
-+     TOBN(0xf0227c09, 0x067b6269), TOBN(0x967b8533, 0x5caef599),
-+     TOBN(0x155b9243, 0x68efeebc), TOBN(0xcd6d34f5, 0xc497bae6),
-+     TOBN(0x1dd8d5d3, 0x6cceb370), TOBN(0x2aeac579, 0xa78d7bf9),
-+     TOBN(0x5d65017d, 0x70b67a62), TOBN(0x70c8e44f, 0x17c53f67),
-+     TOBN(0xd1fc0950, 0x86a34d09), TOBN(0xe0fca256, 0xe7134907),
-+     TOBN(0xe24fa29c, 0x80fdd315), TOBN(0x2c4acd03, 0xd87499ad),
-+     TOBN(0xbaaf7517, 0x3b5a9ba6), TOBN(0xb9cbe1f6, 0x12e51a51),
-+     TOBN(0xd88edae3, 0x5e154897), TOBN(0xe4309c3c, 0x77b66ca0),
-+     TOBN(0xf5555805, 0xf67f3746), TOBN(0x85fc37ba, 0xa36401ff),
-+     TOBN(0xdf86e2ca, 0xd9499a53), TOBN(0x6270b2a3, 0xecbc955b),
-+     TOBN(0xafae64f5, 0x974ad33b), TOBN(0x04d85977, 0xfe7b2df1),
-+     TOBN(0x2a3db3ff, 0x4ab03f73), TOBN(0x0b87878a, 0x8702740a),
-+     TOBN(0x6d263f01, 0x5a061732), TOBN(0xc25430ce, 0xa32a1901),
-+     TOBN(0xf7ebab3d, 0xdb155018), TOBN(0x3a86f693, 0x63a9b78e),
-+     TOBN(0x349ae368, 0xda9f3804), TOBN(0x470f07fe, 0xa164349c),
-+     TOBN(0xd52f4cc9, 0x8562baa5), TOBN(0xc74a9e86, 0x2b290df3),
-+     TOBN(0xd3a1aa35, 0x43471a24), TOBN(0x239446be, 0xb8194511),
-+     TOBN(0xbec2dd00, 0x81dcd44d), TOBN(0xca3d7f0f, 0xc42ac82d),
-+     TOBN(0x1f3db085, 0xfdaf4520), TOBN(0xbb6d3e80, 0x4549daf2),
-+     TOBN(0xf5969d8a, 0x19ad5c42), TOBN(0x7052b13d, 0xdbfd1511),
-+     TOBN(0x11890d1b, 0x682b9060), TOBN(0xa71d3883, 0xac34452c),
-+     TOBN(0xa438055b, 0x783805b4), TOBN(0x43241277, 0x4725b23e),
-+     TOBN(0xf20cf96e, 0x4901bbed), TOBN(0x6419c710, 0xf432a2bb),
-+     TOBN(0x57a0fbb9, 0xdfa9cd7d), TOBN(0x589111e4, 0x00daa249),
-+     TOBN(0x19809a33, 0x7b60554e), TOBN(0xea5f8887, 0xede283a4),
-+     TOBN(0x2d713802, 0x503bfd35), TOBN(0x151bb0af, 0x585d2a53),
-+     TOBN(0x40b08f74, 0x43b30ca8), TOBN(0xe10b5bba, 0xd9934583),
-+     TOBN(0xe8a546d6, 0xb51110ad), TOBN(0x1dd50e66, 0x28e0b6c5),
-+     TOBN(0x292e9d54, 0xcff2b821), TOBN(0x3882555d, 0x47281760),
-+     TOBN(0x134838f8, 0x3724d6e3), TOBN(0xf2c679e0, 0x22ddcda1),
-+     TOBN(0x40ee8815, 0x6d2a5768), TOBN(0x7f227bd2, 0x1c1e7e2d),
-+     TOBN(0x487ba134, 0xd04ff443), TOBN(0x76e2ff3d, 0xc614e54b),
-+     TOBN(0x36b88d6f, 0xa3177ec7), TOBN(0xbf731d51, 0x2328fff5),
-+     TOBN(0x758caea2, 0x49ba158e), TOBN(0x5ab8ff4c, 0x02938188),
-+     TOBN(0x33e16056, 0x35edc56d), TOBN(0x5a69d349, 0x7e940d79),
-+     TOBN(0x6c4fd001, 0x03866dcb), TOBN(0x20a38f57, 0x4893cdef),
-+     TOBN(0xfbf3e790, 0xfac3a15b), TOBN(0x6ed7ea2e, 0x7a4f8e6b),
-+     TOBN(0xa663eb4f, 0xbc3aca86), TOBN(0x22061ea5, 0x080d53f7),
-+     TOBN(0x2480dfe6, 0xf546783f), TOBN(0xd38bc6da, 0x5a0a641e),
-+     TOBN(0xfb093cd1, 0x2ede8965), TOBN(0x89654db4, 0xacb455cf),
-+     TOBN(0x413cbf9a, 0x26e1adee), TOBN(0x291f3764, 0x373294d4),
-+     TOBN(0x00797257, 0x648083fe), TOBN(0x25f504d3, 0x208cc341),
-+     TOBN(0x635a8e5e, 0xc3a0ee43), TOBN(0x70aaebca, 0x679898ff),
-+     TOBN(0x9ee9f547, 0x5dc63d56), TOBN(0xce987966, 0xffb34d00),
-+     TOBN(0xf9f86b19, 0x5e26310a), TOBN(0x9e435484, 0x382a8ca8),
-+     TOBN(0x253bcb81, 0xc2352fe4), TOBN(0xa4eac8b0, 0x4474b571),
-+     TOBN(0xc1b97512, 0xc1ad8cf8), TOBN(0x193b4e9e, 0x99e0b697),
-+     TOBN(0x939d2716, 0x01e85df0), TOBN(0x4fb265b3, 0xcd44eafd),
-+     TOBN(0x321e7dcd, 0xe51e1ae2), TOBN(0x8e3a8ca6, 0xe3d8b096),
-+     TOBN(0x8de46cb0, 0x52604998), TOBN(0x91099ad8, 0x39072aa7),
-+     TOBN(0x2617f91c, 0x93aa96b8), TOBN(0x0fc8716b, 0x7fca2e13),
-+     TOBN(0xa7106f5e, 0x95328723), TOBN(0xd1c9c40b, 0x262e6522),
-+     TOBN(0xb9bafe86, 0x42b7c094), TOBN(0x1873439d, 0x1543c021),
-+     TOBN(0xe1baa5de, 0x5cbefd5d), TOBN(0xa363fc5e, 0x521e8aff),
-+     TOBN(0xefe6320d, 0xf862eaac), TOBN(0x14419c63, 0x22c647dc),
-+     TOBN(0x0e06707c, 0x4e46d428), TOBN(0xcb6c834f, 0x4a178f8f),
-+     TOBN(0x0f993a45, 0xd30f917c), TOBN(0xd4c4b049, 0x9879afee),
-+     TOBN(0xb6142a1e, 0x70500063), TOBN(0x7c9b41c3, 0xa5d9d605),
-+     TOBN(0xbc00fc2f, 0x2f8ba2c7), TOBN(0x0966eb2f, 0x7c67aa28),
-+     TOBN(0x13f7b516, 0x5a786972), TOBN(0x3bfb7557, 0x8a2fbba0),
-+     TOBN(0x131c4f23, 0x5a2b9620), TOBN(0xbff3ed27, 0x6faf46be),
-+     TOBN(0x9b4473d1, 0x7e172323), TOBN(0x421e8878, 0x339f6246),
-+     TOBN(0x0fa8587a, 0x25a41632), TOBN(0xc0814124, 0xa35b6c93),
-+     TOBN(0x2b18a9f5, 0x59ebb8db), TOBN(0x264e3357, 0x76edb29c),
-+     TOBN(0xaf245ccd, 0xc87c51e2), TOBN(0x16b3015b, 0x501e6214),
-+     TOBN(0xbb31c560, 0x0a3882ce), TOBN(0x6961bb94, 0xfec11e04),
-+     TOBN(0x3b825b8d, 0xeff7a3a0), TOBN(0xbec33738, 0xb1df7326),
-+     TOBN(0x68ad747c, 0x99604a1f), TOBN(0xd154c934, 0x9a3bd499),
-+     TOBN(0xac33506f, 0x1cc7a906), TOBN(0x73bb5392, 0x6c560e8f),
-+     TOBN(0x6428fcbe, 0x263e3944), TOBN(0xc11828d5, 0x1c387434),
-+     TOBN(0x3cd04be1, 0x3e4b12ff), TOBN(0xc3aad9f9, 0x2d88667c),
-+     TOBN(0xc52ddcf8, 0x248120cf), TOBN(0x985a892e, 0x2a389532),
-+     TOBN(0xfbb4b21b, 0x3bb85fa0), TOBN(0xf95375e0, 0x8dfc6269),
-+     TOBN(0xfb4fb06c, 0x7ee2acea), TOBN(0x6785426e, 0x309c4d1f),
-+     TOBN(0x659b17c8, 0xd8ceb147), TOBN(0x9b649eee, 0xb70a5554),
-+     TOBN(0x6b7fa0b5, 0xac6bc634), TOBN(0xd99fe2c7, 0x1d6e732f),
-+     TOBN(0x30e6e762, 0x8d3abba2), TOBN(0x18fee6e7, 0xa797b799),
-+     TOBN(0x5c9d360d, 0xc696464d), TOBN(0xe3baeb48, 0x27bfde12),
-+     TOBN(0x2bf5db47, 0xf23206d5), TOBN(0x2f6d3420, 0x1d260152),
-+     TOBN(0x17b87653, 0x3f8ff89a), TOBN(0x5157c30c, 0x378fa458),
-+     TOBN(0x7517c5c5, 0x2d4fb936), TOBN(0xef22f7ac, 0xe6518cdc),
-+     TOBN(0xdeb483e6, 0xbf847a64), TOBN(0xf5084558, 0x92e0fa89),}
-+    ,
-+    {TOBN(0xab9659d8, 0xdf7304d4), TOBN(0xb71bcf1b, 0xff210e8e),
-+     TOBN(0xa9a2438b, 0xd73fbd60), TOBN(0x4595cd1f, 0x5d11b4de),
-+     TOBN(0x9c0d329a, 0x4835859d), TOBN(0x4a0f0d2d, 0x7dbb6e56),
-+     TOBN(0xc6038e5e, 0xdf928a4e), TOBN(0xc9429621, 0x8f5ad154),
-+     TOBN(0x91213462, 0xf23f2d92), TOBN(0x6cab71bd, 0x60b94078),
-+     TOBN(0x6bdd0a63, 0x176cde20), TOBN(0x54c9b20c, 0xee4d54bc),
-+     TOBN(0x3cd2d8aa, 0x9f2ac02f), TOBN(0x03f8e617, 0x206eedb0),
-+     TOBN(0xc7f68e16, 0x93086434), TOBN(0x831469c5, 0x92dd3db9),
-+     TOBN(0x8521df24, 0x8f981354), TOBN(0x587e23ec, 0x3588a259),
-+     TOBN(0xcbedf281, 0xd7a0992c), TOBN(0x06930a55, 0x38961407),
-+     TOBN(0x09320deb, 0xbe5bbe21), TOBN(0xa7ffa5b5, 0x2491817f),
-+     TOBN(0xe6c8b4d9, 0x09065160), TOBN(0xac4f3992, 0xfff6d2a9),
-+     TOBN(0x7aa7a158, 0x3ae9c1bd), TOBN(0xe0af6d98, 0xe37ce240),
-+     TOBN(0xe54342d9, 0x28ab38b4), TOBN(0xe8b75007, 0x0a1c98ca),
-+     TOBN(0xefce86af, 0xe02358f2), TOBN(0x31b8b856, 0xea921228),
-+     TOBN(0x052a1912, 0x0a1c67fc), TOBN(0xb4069ea4, 0xe3aead59),
-+     TOBN(0x3232d6e2, 0x7fa03cb3), TOBN(0xdb938e5b, 0x0fdd7d88),
-+     TOBN(0x04c1d2cd, 0x2ccbfc5d), TOBN(0xd2f45c12, 0xaf3a580f),
-+     TOBN(0x592620b5, 0x7883e614), TOBN(0x5fd27e68, 0xbe7c5f26),
-+     TOBN(0x139e45a9, 0x1567e1e3), TOBN(0x2cc71d2d, 0x44d8aaaf),
-+     TOBN(0x4a9090cd, 0xe36d0757), TOBN(0xf722d7b1, 0xd9a29382),
-+     TOBN(0xfb7fb04c, 0x04b48ddf), TOBN(0x628ad2a7, 0xebe16f43),
-+     TOBN(0xcd3fbfb5, 0x20226040), TOBN(0x6c34ecb1, 0x5104b6c4),
-+     TOBN(0x30c0754e, 0xc903c188), TOBN(0xec336b08, 0x2d23cab0),
-+     TOBN(0x473d62a2, 0x1e206ee5), TOBN(0xf1e27480, 0x8c49a633),
-+     TOBN(0x87ab956c, 0xe9f6b2c3), TOBN(0x61830b48, 0x62b606ea),
-+     TOBN(0x67cd6846, 0xe78e815f), TOBN(0xfe40139f, 0x4c02082a),
-+     TOBN(0x52bbbfcb, 0x952ec365), TOBN(0x74c11642, 0x6b9836ab),
-+     TOBN(0x9f51439e, 0x558df019), TOBN(0x230da4ba, 0xac712b27),
-+     TOBN(0x518919e3, 0x55185a24), TOBN(0x4dcefcdd, 0x84b78f50),
-+     TOBN(0xa7d90fb2, 0xa47d4c5a), TOBN(0x55ac9abf, 0xb30e009e),
-+     TOBN(0xfd2fc359, 0x74eed273), TOBN(0xb72d824c, 0xdbea8faf),
-+     TOBN(0xce721a74, 0x4513e2ca), TOBN(0x0b418612, 0x38240b2c),
-+     TOBN(0x05199968, 0xd5baa450), TOBN(0xeb1757ed, 0x2b0e8c25),
-+     TOBN(0x6ebc3e28, 0x3dfac6d5), TOBN(0xb2431e2e, 0x48a237f5),
-+     TOBN(0x2acb5e23, 0x52f61499), TOBN(0x5558a2a7, 0xe06c936b),
-+     TOBN(0xd213f923, 0xcbb13d1b), TOBN(0x98799f42, 0x5bfb9bfe),
-+     TOBN(0x1ae8ddc9, 0x701144a9), TOBN(0x0b8b3bb6, 0x4c5595ee),
-+     TOBN(0x0ea9ef2e, 0x3ecebb21), TOBN(0x17cb6c4b, 0x3671f9a7),
-+     TOBN(0x47ef464f, 0x726f1d1f), TOBN(0x171b9484, 0x6943a276),
-+     TOBN(0x51a4ae2d, 0x7ef0329c), TOBN(0x08509222, 0x91c4402a),
-+     TOBN(0x64a61d35, 0xafd45bbc), TOBN(0x38f096fe, 0x3035a851),
-+     TOBN(0xc7468b74, 0xa1dec027), TOBN(0xe8cf10e7, 0x4fc7dcba),
-+     TOBN(0xea35ff40, 0xf4a06353), TOBN(0x0b4c0dfa, 0x8b77dd66),
-+     TOBN(0x779b8552, 0xde7e5c19), TOBN(0xfab28609, 0xc1c0256c),
-+     TOBN(0x64f58eee, 0xabd4743d), TOBN(0x4e8ef838, 0x7b6cc93b),
-+     TOBN(0xee650d26, 0x4cb1bf3d), TOBN(0x4c1f9d09, 0x73dedf61),
-+     TOBN(0xaef7c9d7, 0xbfb70ced), TOBN(0x1ec0507e, 0x1641de1e),
-+     TOBN(0xcd7e5cc7, 0xcde45079), TOBN(0xde173c9a, 0x516ac9e4),
-+     TOBN(0x517a8494, 0xc170315c), TOBN(0x438fd905, 0x91d8e8fb),
-+     TOBN(0x5145c506, 0xc7d9630b), TOBN(0x6457a87b, 0xf47d4d75),
-+     TOBN(0xd31646bf, 0x0d9a80e8), TOBN(0x453add2b, 0xcef3aabe),
-+     TOBN(0xc9941109, 0xa607419d), TOBN(0xfaa71e62, 0xbb6bca80),
-+     TOBN(0x34158c13, 0x07c431f3), TOBN(0x594abebc, 0x992bc47a),
-+     TOBN(0x6dfea691, 0xeb78399f), TOBN(0x48aafb35, 0x3f42cba4),
-+     TOBN(0xedcd65af, 0x077c04f0), TOBN(0x1a29a366, 0xe884491a),
-+     TOBN(0x023a40e5, 0x1c21f2bf), TOBN(0xf99a513c, 0xa5057aee),
-+     TOBN(0xa3fe7e25, 0xbcab072e), TOBN(0x8568d2e1, 0x40e32bcf),
-+     TOBN(0x904594eb, 0xd3f69d9f), TOBN(0x181a9733, 0x07affab1),
-+     TOBN(0xe4d68d76, 0xb6e330f4), TOBN(0x87a6dafb, 0xc75a7fc1),
-+     TOBN(0x549db2b5, 0xef7d9289), TOBN(0x2480d4a8, 0x197f015a),
-+     TOBN(0x61d5590b, 0xc40493b6), TOBN(0x3a55b52e, 0x6f780331),
-+     TOBN(0x40eb8115, 0x309eadb0), TOBN(0xdea7de5a, 0x92e5c625),
-+     TOBN(0x64d631f0, 0xcc6a3d5a), TOBN(0x9d5e9d7c, 0x93e8dd61),
-+     TOBN(0xf297bef5, 0x206d3ffc), TOBN(0x23d5e033, 0x7d808bd4),
-+     TOBN(0x4a4f6912, 0xd24cf5ba), TOBN(0xe4d8163b, 0x09cdaa8a),
-+     TOBN(0x0e0de9ef, 0xd3082e8e), TOBN(0x4fe1246c, 0x0192f360),
-+     TOBN(0x1f900150, 0x4b8eee0a), TOBN(0x5219da81, 0xf1da391b),
-+     TOBN(0x7bf6a5c1, 0xf7ea25aa), TOBN(0xd165e6bf, 0xfbb07d5f),
-+     TOBN(0xe3539361, 0x89e78671), TOBN(0xa3fcac89, 0x2bac4219),
-+     TOBN(0xdfab6fd4, 0xf0baa8ab), TOBN(0x5a4adac1, 0xe2c1c2e5),
-+     TOBN(0x6cd75e31, 0x40d85849), TOBN(0xce263fea, 0x19b39181),
-+     TOBN(0xcb6803d3, 0x07032c72), TOBN(0x7f40d5ce, 0x790968c8),
-+     TOBN(0xa6de86bd, 0xdce978f0), TOBN(0x25547c4f, 0x368f751c),
-+     TOBN(0xb1e685fd, 0x65fb2a9e), TOBN(0xce69336f, 0x1eb9179c),
-+     TOBN(0xb15d1c27, 0x12504442), TOBN(0xb7df465c, 0xb911a06b),
-+     TOBN(0xb8d804a3, 0x315980cd), TOBN(0x693bc492, 0xfa3bebf7),
-+     TOBN(0x3578aeee, 0x2253c504), TOBN(0x158de498, 0xcd2474a2),
-+     TOBN(0x1331f5c7, 0xcfda8368), TOBN(0xd2d7bbb3, 0x78d7177e),
-+     TOBN(0xdf61133a, 0xf3c1e46e), TOBN(0x5836ce7d, 0xd30e7be8),
-+     TOBN(0x83084f19, 0x94f834cb), TOBN(0xd35653d4, 0x429ed782),
-+     TOBN(0xa542f16f, 0x59e58243), TOBN(0xc2b52f65, 0x0470a22d),
-+     TOBN(0xe3b6221b, 0x18f23d96), TOBN(0xcb05abac, 0x3f5252b4),
-+     TOBN(0xca00938b, 0x87d61402), TOBN(0x2f186cdd, 0x411933e4),
-+     TOBN(0xe042ece5, 0x9a29a5c5), TOBN(0xb19b3c07, 0x3b6c8402),
-+     TOBN(0xc97667c7, 0x19d92684), TOBN(0xb5624622, 0xebc66372),
-+     TOBN(0x0cb96e65, 0x3c04fa02), TOBN(0x83a7176c, 0x8eaa39aa),
-+     TOBN(0x2033561d, 0xeaa1633f), TOBN(0x45a9d086, 0x4533df73),
-+     TOBN(0xe0542c1d, 0x3dc090bc), TOBN(0x82c996ef, 0xaa59c167),
-+     TOBN(0xe3f735e8, 0x0ee7fc4d), TOBN(0x7b179393, 0x7c35db79),
-+     TOBN(0xb6419e25, 0xf8c5dbfd), TOBN(0x4d9d7a1e, 0x1f327b04),
-+     TOBN(0x979f6f9b, 0x298dfca8), TOBN(0xc7c5dff1, 0x8de9366a),
-+     TOBN(0x1b7a588d, 0x04c82bdd), TOBN(0x68005534, 0xf8319dfd),
-+     TOBN(0xde8a55b5, 0xd8eb9580), TOBN(0x5ea886da, 0x8d5bca81),
-+     TOBN(0xe8530a01, 0x252a0b4d), TOBN(0x1bffb4fe, 0x35eaa0a1),
-+     TOBN(0x2ad828b1, 0xd8e99563), TOBN(0x7de96ef5, 0x95f9cd87),
-+     TOBN(0x4abb2d0c, 0xd77d970c), TOBN(0x03cfb933, 0xd33ef9cb),
-+     TOBN(0xb0547c01, 0x8b211fe9), TOBN(0x2fe64809, 0xa56ed1c6),
-+     TOBN(0xcb7d5624, 0xc2ac98cc), TOBN(0x2a1372c0, 0x1a393e33),
-+     TOBN(0xc8d1ec1c, 0x29660521), TOBN(0xf3d31b04, 0xb37ac3e9),
-+     TOBN(0xa29ae9df, 0x5ece6e7c), TOBN(0x0603ac8f, 0x0facfb55),
-+     TOBN(0xcfe85b7a, 0xdda233a5), TOBN(0xe618919f, 0xbd75f0b8),
-+     TOBN(0xf555a3d2, 0x99bf1603), TOBN(0x1f43afc9, 0xf184255a),
-+     TOBN(0xdcdaf341, 0x319a3e02), TOBN(0xd3b117ef, 0x03903a39),
-+     TOBN(0xe095da13, 0x65d1d131), TOBN(0x86f16367, 0xc37ad03e),
-+     TOBN(0x5f37389e, 0x462cd8dd), TOBN(0xc103fa04, 0xd67a60e6),
-+     TOBN(0x57c34344, 0xf4b478f0), TOBN(0xce91edd8, 0xe117c98d),
-+     TOBN(0x001777b0, 0x231fc12e), TOBN(0x11ae47f2, 0xb207bccb),
-+     TOBN(0xd983cf8d, 0x20f8a242), TOBN(0x7aff5b1d, 0xf22e1ad8),
-+     TOBN(0x68fd11d0, 0x7fc4feb3), TOBN(0x5d53ae90, 0xb0f1c3e1),
-+     TOBN(0x50fb7905, 0xec041803), TOBN(0x85e3c977, 0x14404888),
-+     TOBN(0x0e67faed, 0xac628d8f), TOBN(0x2e865150, 0x6668532c),
-+     TOBN(0x15acaaa4, 0x6a67a6b0), TOBN(0xf4cdee25, 0xb25cec41),
-+     TOBN(0x49ee565a, 0xe4c6701e), TOBN(0x2a04ca66, 0xfc7d63d8),
-+     TOBN(0xeb105018, 0xef0543fb), TOBN(0xf709a4f5, 0xd1b0d81d),
-+     TOBN(0x5b906ee6, 0x2915d333), TOBN(0xf4a87412, 0x96f1f0ab),
-+     TOBN(0xb6b82fa7, 0x4d82f4c2), TOBN(0x90725a60, 0x6804efb3),
-+     TOBN(0xbc82ec46, 0xadc3425e), TOBN(0xb7b80581, 0x2787843e),
-+     TOBN(0xdf46d91c, 0xdd1fc74c), TOBN(0xdc1c62cb, 0xe783a6c4),
-+     TOBN(0x59d1b9f3, 0x1a04cbba), TOBN(0xd87f6f72, 0x95e40764),
-+     TOBN(0x02b4cfc1, 0x317f4a76), TOBN(0x8d2703eb, 0x91036bce),
-+     TOBN(0x98206cc6, 0xa5e72a56), TOBN(0x57be9ed1, 0xcf53fb0f),
-+     TOBN(0x09374571, 0xef0b17ac), TOBN(0x74b2655e, 0xd9181b38),
-+     TOBN(0xc8f80ea8, 0x89935d0e), TOBN(0xc0d9e942, 0x91529936),
-+     TOBN(0x19686041, 0x1e84e0e5), TOBN(0xa5db84d3, 0xaea34c93),
-+     TOBN(0xf9d5bb19, 0x7073a732), TOBN(0xb8d2fe56, 0x6bcfd7c0),
-+     TOBN(0x45775f36, 0xf3eb82fa), TOBN(0x8cb20ccc, 0xfdff8b58),
-+     TOBN(0x1659b65f, 0x8374c110), TOBN(0xb8b4a422, 0x330c789a),
-+     TOBN(0x75e3c3ea, 0x6fe8208b), TOBN(0xbd74b9e4, 0x286e78fe),
-+     TOBN(0x0be2e81b, 0xd7d93a1a), TOBN(0x7ed06e27, 0xdd0a5aae),
-+     TOBN(0x721f5a58, 0x6be8b800), TOBN(0x428299d1, 0xd846db28),
-+     TOBN(0x95cb8e6b, 0x5be88ed3), TOBN(0xc3186b23, 0x1c034e11),
-+     TOBN(0xa6312c9e, 0x8977d99b), TOBN(0xbe944331, 0x83f531e7),
-+     TOBN(0x8232c0c2, 0x18d3b1d4), TOBN(0x617aae8b, 0xe1247b73),
-+     TOBN(0x40153fc4, 0x282aec3b), TOBN(0xc6063d2f, 0xf7b8f823),
-+     TOBN(0x68f10e58, 0x3304f94c), TOBN(0x31efae74, 0xee676346),
-+     TOBN(0xbadb6c6d, 0x40a9b97c), TOBN(0x14702c63, 0x4f666256),
-+     TOBN(0xdeb954f1, 0x5184b2e3), TOBN(0x5184a526, 0x94b6ca40),
-+     TOBN(0xfff05337, 0x003c32ea), TOBN(0x5aa374dd, 0x205974c7),
-+     TOBN(0x9a763854, 0x4b0dd71a), TOBN(0x459cd27f, 0xdeb947ec),
-+     TOBN(0xa6e28161, 0x459c2b92), TOBN(0x2f020fa8, 0x75ee8ef5),
-+     TOBN(0xb132ec2d, 0x30b06310), TOBN(0xc3e15899, 0xbc6a4530),
-+     TOBN(0xdc5f53fe, 0xaa3f451a), TOBN(0x3a3c7f23, 0xc2d9acac),
-+     TOBN(0x2ec2f892, 0x6b27e58b), TOBN(0x68466ee7, 0xd742799f),
-+     TOBN(0x98324dd4, 0x1fa26613), TOBN(0xa2dc6dab, 0xbdc29d63),
-+     TOBN(0xf9675faa, 0xd712d657), TOBN(0x813994be, 0x21fd8d15),
-+     TOBN(0x5ccbb722, 0xfd4f7553), TOBN(0x5135ff8b, 0xf3a36b20),
-+     TOBN(0x44be28af, 0x69559df5), TOBN(0x40b65bed, 0x9d41bf30),
-+     TOBN(0xd98bf2a4, 0x3734e520), TOBN(0x5e3abbe3, 0x209bdcba),
-+     TOBN(0x77c76553, 0xbc945b35), TOBN(0x5331c093, 0xc6ef14aa),
-+     TOBN(0x518ffe29, 0x76b60c80), TOBN(0x2285593b, 0x7ace16f8),
-+     TOBN(0xab1f64cc, 0xbe2b9784), TOBN(0xe8f2c0d9, 0xab2421b6),
-+     TOBN(0x617d7174, 0xc1df065c), TOBN(0xafeeb5ab, 0x5f6578fa),
-+     TOBN(0x16ff1329, 0x263b54a8), TOBN(0x45c55808, 0xc990dce3),
-+     TOBN(0x42eab6c0, 0xecc8c177), TOBN(0x799ea9b5, 0x5982ecaa),
-+     TOBN(0xf65da244, 0xb607ef8e), TOBN(0x8ab226ce, 0x32a3fc2c),
-+     TOBN(0x745741e5, 0x7ea973dc), TOBN(0x5c00ca70, 0x20888f2e),
-+     TOBN(0x7cdce3cf, 0x45fd9cf1), TOBN(0x8a741ef1, 0x5507f872),
-+     TOBN(0x47c51c2f, 0x196b4cec), TOBN(0x70d08e43, 0xc97ea618),
-+     TOBN(0x930da15c, 0x15b18a2b), TOBN(0x33b6c678, 0x2f610514),
-+     TOBN(0xc662e4f8, 0x07ac9794), TOBN(0x1eccf050, 0xba06cb79),
-+     TOBN(0x1ff08623, 0xe7d954e5), TOBN(0x6ef2c5fb, 0x24cf71c3),
-+     TOBN(0xb2c063d2, 0x67978453), TOBN(0xa0cf3796, 0x1d654af8),
-+     TOBN(0x7cb242ea, 0x7ebdaa37), TOBN(0x206e0b10, 0xb86747e0),
-+     TOBN(0x481dae5f, 0xd5ecfefc), TOBN(0x07084fd8, 0xc2bff8fc),
-+     TOBN(0x8040a01a, 0xea324596), TOBN(0x4c646980, 0xd4de4036),
-+     TOBN(0x9eb8ab4e, 0xd65abfc3), TOBN(0xe01cb91f, 0x13541ec7),
-+     TOBN(0x8f029adb, 0xfd695012), TOBN(0x9ae28483, 0x3c7569ec),
-+     TOBN(0xa5614c9e, 0xa66d80a1), TOBN(0x680a3e44, 0x75f5f911),
-+     TOBN(0x0c07b14d, 0xceba4fc1), TOBN(0x891c285b, 0xa13071c1),
-+     TOBN(0xcac67ceb, 0x799ece3c), TOBN(0x29b910a9, 0x41e07e27),
-+     TOBN(0x66bdb409, 0xf2e43123), TOBN(0x06f8b137, 0x7ac9ecbe),
-+     TOBN(0x5981fafd, 0x38547090), TOBN(0x19ab8b9f, 0x85e3415d),
-+     TOBN(0xfc28c194, 0xc7e31b27), TOBN(0x843be0aa, 0x6fbcbb42),
-+     TOBN(0xf3b1ed43, 0xa6db836c), TOBN(0x2a1330e4, 0x01a45c05),
-+     TOBN(0x4f19f3c5, 0x95c1a377), TOBN(0xa85f39d0, 0x44b5ee33),
-+     TOBN(0x3da18e6d, 0x4ae52834), TOBN(0x5a403b39, 0x7423dcb0),
-+     TOBN(0xbb555e0a, 0xf2374aef), TOBN(0x2ad599c4, 0x1e8ca111),
-+     TOBN(0x1b3a2fb9, 0x014b3bf8), TOBN(0x73092684, 0xf66d5007),
-+     TOBN(0x079f1426, 0xc4340102), TOBN(0x1827cf81, 0x8fddf4de),
-+     TOBN(0xc83605f6, 0xf10ff927), TOBN(0xd3871451, 0x23739fc6),
-+     TOBN(0x6d163450, 0xcac1c2cc), TOBN(0x6b521296, 0xa2ec1ac5),
-+     TOBN(0x0606c4f9, 0x6e3cb4a5), TOBN(0xe47d3f41, 0x778abff7),
-+     TOBN(0x425a8d5e, 0xbe8e3a45), TOBN(0x53ea9e97, 0xa6102160),
-+     TOBN(0x477a106e, 0x39cbb688), TOBN(0x532401d2, 0xf3386d32),
-+     TOBN(0x8e564f64, 0xb1b9b421), TOBN(0xca9b8388, 0x81dad33f),
-+     TOBN(0xb1422b4e, 0x2093913e), TOBN(0x533d2f92, 0x69bc8112),
-+     TOBN(0x3fa017be, 0xebe7b2c7), TOBN(0xb2767c4a, 0xcaf197c6),
-+     TOBN(0xc925ff87, 0xaedbae9f), TOBN(0x7daf0eb9, 0x36880a54),
-+     TOBN(0x9284ddf5, 0x9c4d0e71), TOBN(0x1581cf93, 0x316f8cf5),
-+     TOBN(0x3eeca887, 0x3ac1f452), TOBN(0xb417fce9, 0xfb6aeffe),
-+     TOBN(0xa5918046, 0xeefb8dc3), TOBN(0x73d318ac, 0x02209400),
-+     TOBN(0xe800400f, 0x728693e5), TOBN(0xe87d814b, 0x339927ed),
-+     TOBN(0x93e94d3b, 0x57ea9910), TOBN(0xff8a35b6, 0x2245fb69),
-+     TOBN(0x043853d7, 0x7f200d34), TOBN(0x470f1e68, 0x0f653ce1),
-+     TOBN(0x81ac05bd, 0x59a06379), TOBN(0xa14052c2, 0x03930c29),
-+     TOBN(0x6b72fab5, 0x26bc2797), TOBN(0x13670d16, 0x99f16771),
-+     TOBN(0x00170052, 0x1e3e48d1), TOBN(0x978fe401, 0xb7adf678),
-+     TOBN(0x55ecfb92, 0xd41c5dd4), TOBN(0x5ff8e247, 0xc7b27da5),
-+     TOBN(0xe7518272, 0x013fb606), TOBN(0x5768d7e5, 0x2f547a3c),
-+     TOBN(0xbb24eaa3, 0x60017a5f), TOBN(0x6b18e6e4, 0x9c64ce9b),
-+     TOBN(0xc225c655, 0x103dde07), TOBN(0xfc3672ae, 0x7592f7ea),
-+     TOBN(0x9606ad77, 0xd06283a1), TOBN(0x542fc650, 0xe4d59d99),
-+     TOBN(0xabb57c49, 0x2a40e7c2), TOBN(0xac948f13, 0xa8db9f55),
-+     TOBN(0x6d4c9682, 0xb04465c3), TOBN(0xe3d062fa, 0x6468bd15),
-+     TOBN(0xa51729ac, 0x5f318d7e), TOBN(0x1fc87df6, 0x9eb6fc95),
-+     TOBN(0x63d146a8, 0x0591f652), TOBN(0xa861b8f7, 0x589621aa),
-+     TOBN(0x59f5f15a, 0xce31348c), TOBN(0x8f663391, 0x440da6da),
-+     TOBN(0xcfa778ac, 0xb591ffa3), TOBN(0x027ca9c5, 0x4cdfebce),
-+     TOBN(0xbe8e05a5, 0x444ea6b3), TOBN(0x8aab4e69, 0xa78d8254),
-+     TOBN(0x2437f04f, 0xb474d6b8), TOBN(0x6597ffd4, 0x045b3855),
-+     TOBN(0xbb0aea4e, 0xca47ecaa), TOBN(0x568aae83, 0x85c7ebfc),
-+     TOBN(0x0e966e64, 0xc73b2383), TOBN(0x49eb3447, 0xd17d8762),
-+     TOBN(0xde107821, 0x8da05dab), TOBN(0x443d8baa, 0x016b7236),
-+     TOBN(0x163b63a5, 0xea7610d6), TOBN(0xe47e4185, 0xce1ca979),
-+     TOBN(0xae648b65, 0x80baa132), TOBN(0xebf53de2, 0x0e0d5b64),
-+     TOBN(0x8d3bfcb4, 0xd3c8c1ca), TOBN(0x0d914ef3, 0x5d04b309),
-+     TOBN(0x55ef6415, 0x3de7d395), TOBN(0xbde1666f, 0x26b850e8),
-+     TOBN(0xdbe1ca6e, 0xd449ab19), TOBN(0x8902b322, 0xe89a2672),
-+     TOBN(0xb1674b7e, 0xdacb7a53), TOBN(0x8e9faf6e, 0xf52523ff),
-+     TOBN(0x6ba535da, 0x9a85788b), TOBN(0xd21f03ae, 0xbd0626d4),
-+     TOBN(0x099f8c47, 0xe873dc64), TOBN(0xcda8564d, 0x018ec97e),
-+     TOBN(0x3e8d7a5c, 0xde92c68c), TOBN(0x78e035a1, 0x73323cc4),
-+     TOBN(0x3ef26275, 0xf880ff7c), TOBN(0xa4ee3dff, 0x273eedaa),
-+     TOBN(0x58823507, 0xaf4e18f8), TOBN(0x967ec9b5, 0x0672f328),
-+     TOBN(0x9ded19d9, 0x559d3186), TOBN(0x5e2ab3de, 0x6cdce39c),
-+     TOBN(0xabad6e4d, 0x11c226df), TOBN(0xf9783f43, 0x87723014),
-+     TOBN(0x9a49a0cf, 0x1a885719), TOBN(0xfc0c1a5a, 0x90da9dbf),
-+     TOBN(0x8bbaec49, 0x571d92ac), TOBN(0x569e85fe, 0x4692517f),
-+     TOBN(0x8333b014, 0xa14ea4af), TOBN(0x32f2a62f, 0x12e5c5ad),
-+     TOBN(0x98c2ce3a, 0x06d89b85), TOBN(0xb90741aa, 0x2ff77a08),
-+     TOBN(0x2530defc, 0x01f795a2), TOBN(0xd6e5ba0b, 0x84b3c199),
-+     TOBN(0x7d8e8451, 0x12e4c936), TOBN(0xae419f7d, 0xbd0be17b),
-+     TOBN(0xa583fc8c, 0x22262bc9), TOBN(0x6b842ac7, 0x91bfe2bd),
-+     TOBN(0x33cef4e9, 0x440d6827), TOBN(0x5f69f4de, 0xef81fb14),
-+     TOBN(0xf16cf6f6, 0x234fbb92), TOBN(0x76ae3fc3, 0xd9e7e158),
-+     TOBN(0x4e89f6c2, 0xe9740b33), TOBN(0x677bc85d, 0x4962d6a1),
-+     TOBN(0x6c6d8a7f, 0x68d10d15), TOBN(0x5f9a7224, 0x0257b1cd),
-+     TOBN(0x7096b916, 0x4ad85961), TOBN(0x5f8c47f7, 0xe657ab4a),
-+     TOBN(0xde57d7d0, 0xf7461d7e), TOBN(0x7eb6094d, 0x80ce5ee2),
-+     TOBN(0x0b1e1dfd, 0x34190547), TOBN(0x8a394f43, 0xf05dd150),
-+     TOBN(0x0a9eb24d, 0x97df44e6), TOBN(0x78ca06bf, 0x87675719),
-+     TOBN(0x6f0b3462, 0x6ffeec22), TOBN(0x9d91bcea, 0x36cdd8fb),
-+     TOBN(0xac83363c, 0xa105be47), TOBN(0x81ba76c1, 0x069710e3),
-+     TOBN(0x3d1b24cb, 0x28c682c6), TOBN(0x27f25228, 0x8612575b),
-+     TOBN(0xb587c779, 0xe8e66e98), TOBN(0x7b0c03e9, 0x405eb1fe),
-+     TOBN(0xfdf0d030, 0x15b548e7), TOBN(0xa8be76e0, 0x38b36af7),
-+     TOBN(0x4cdab04a, 0x4f310c40), TOBN(0x6287223e, 0xf47ecaec),
-+     TOBN(0x678e6055, 0x8b399320), TOBN(0x61fe3fa6, 0xc01e4646),
-+     TOBN(0xc482866b, 0x03261a5e), TOBN(0xdfcf45b8, 0x5c2f244a),
-+     TOBN(0x8fab9a51, 0x2f684b43), TOBN(0xf796c654, 0xc7220a66),
-+     TOBN(0x1d90707e, 0xf5afa58f), TOBN(0x2c421d97, 0x4fdbe0de),
-+     TOBN(0xc4f4cda3, 0xaf2ebc2f), TOBN(0xa0af843d, 0xcb4efe24),
-+     TOBN(0x53b857c1, 0x9ccd10b1), TOBN(0xddc9d1eb, 0x914d3e04),
-+     TOBN(0x7bdec8bb, 0x62771deb), TOBN(0x829277aa, 0x91c5aa81),
-+     TOBN(0x7af18dd6, 0x832391ae), TOBN(0x1740f316, 0xc71a84ca),}
-+    ,
-+    {TOBN(0x8928e99a, 0xeeaf8c49), TOBN(0xee7aa73d, 0x6e24d728),
-+     TOBN(0x4c5007c2, 0xe72b156c), TOBN(0x5fcf57c5, 0xed408a1d),
-+     TOBN(0x9f719e39, 0xb6057604), TOBN(0x7d343c01, 0xc2868bbf),
-+     TOBN(0x2cca254b, 0x7e103e2d), TOBN(0xe6eb38a9, 0xf131bea2),
-+     TOBN(0xb33e624f, 0x8be762b4), TOBN(0x2a9ee4d1, 0x058e3413),
-+     TOBN(0x968e6369, 0x67d805fa), TOBN(0x9848949b, 0x7db8bfd7),
-+     TOBN(0x5308d7e5, 0xd23a8417), TOBN(0x892f3b1d, 0xf3e29da5),
-+     TOBN(0xc95c139e, 0x3dee471f), TOBN(0x8631594d, 0xd757e089),
-+     TOBN(0xe0c82a3c, 0xde918dcc), TOBN(0x2e7b5994, 0x26fdcf4b),
-+     TOBN(0x82c50249, 0x32cb1b2d), TOBN(0xea613a9d, 0x7657ae07),
-+     TOBN(0xc2eb5f6c, 0xf1fdc9f7), TOBN(0xb6eae8b8, 0x879fe682),
-+     TOBN(0x253dfee0, 0x591cbc7f), TOBN(0x000da713, 0x3e1290e6),
-+     TOBN(0x1083e2ea, 0x1f095615), TOBN(0x0a28ad77, 0x14e68c33),
-+     TOBN(0x6bfc0252, 0x3d8818be), TOBN(0xb585113a, 0xf35850cd),
-+     TOBN(0x7d935f0b, 0x30df8aa1), TOBN(0xaddda07c, 0x4ab7e3ac),
-+     TOBN(0x92c34299, 0x552f00cb), TOBN(0xc33ed1de, 0x2909df6c),
-+     TOBN(0x22c2195d, 0x80e87766), TOBN(0x9e99e6d8, 0x9ddf4ac0),
-+     TOBN(0x09642e4e, 0x65e74934), TOBN(0x2610ffa2, 0xff1ff241),
-+     TOBN(0x4d1d47d4, 0x751c8159), TOBN(0x697b4985, 0xaf3a9363),
-+     TOBN(0x0318ca46, 0x87477c33), TOBN(0xa90cb565, 0x9441eff3),
-+     TOBN(0x58bb3848, 0x36f024cb), TOBN(0x85be1f77, 0x36016168),
-+     TOBN(0x6c59587c, 0xdc7e07f1), TOBN(0x191be071, 0xaf1d8f02),
-+     TOBN(0xbf169fa5, 0xcca5e55c), TOBN(0x3864ba3c, 0xf7d04eac),
-+     TOBN(0x915e367f, 0x8d7d05db), TOBN(0xb48a876d, 0xa6549e5d),
-+     TOBN(0xef89c656, 0x580e40a2), TOBN(0xf194ed8c, 0x728068bc),
-+     TOBN(0x74528045, 0xa47990c9), TOBN(0xf53fc7d7, 0x5e1a4649),
-+     TOBN(0xbec5ae9b, 0x78593e7d), TOBN(0x2cac4ee3, 0x41db65d7),
-+     TOBN(0xa8c1eb24, 0x04a3d39b), TOBN(0x53b7d634, 0x03f8f3ef),
-+     TOBN(0x2dc40d48, 0x3e07113c), TOBN(0x6e4a5d39, 0x7d8b63ae),
-+     TOBN(0x5582a94b, 0x79684c2b), TOBN(0x932b33d4, 0x622da26c),
-+     TOBN(0xf534f651, 0x0dbbf08d), TOBN(0x211d07c9, 0x64c23a52),
-+     TOBN(0x0eeece0f, 0xee5bdc9b), TOBN(0xdf178168, 0xf7015558),
-+     TOBN(0xd4294635, 0x0a712229), TOBN(0x93cbe448, 0x09273f8c),
-+     TOBN(0x00b095ef, 0x8f13bc83), TOBN(0xbb741972, 0x8798978c),
-+     TOBN(0x9d7309a2, 0x56dbe6e7), TOBN(0xe578ec56, 0x5a5d39ec),
-+     TOBN(0x3961151b, 0x851f9a31), TOBN(0x2da7715d, 0xe5709eb4),
-+     TOBN(0x867f3017, 0x53dfabf0), TOBN(0x728d2078, 0xb8e39259),
-+     TOBN(0x5c75a0cd, 0x815d9958), TOBN(0xf84867a6, 0x16603be1),
-+     TOBN(0xc865b13d, 0x70e35b1c), TOBN(0x02414468, 0x19b03e2c),
-+     TOBN(0xe46041da, 0xac1f3121), TOBN(0x7c9017ad, 0x6f028a7c),
-+     TOBN(0xabc96de9, 0x0a482873), TOBN(0x4265d6b1, 0xb77e54d4),
-+     TOBN(0x68c38e79, 0xa57d88e7), TOBN(0xd461d766, 0x9ce82de3),
-+     TOBN(0x817a9ec5, 0x64a7e489), TOBN(0xcc5675cd, 0xa0def5f2),
-+     TOBN(0x9a00e785, 0x985d494e), TOBN(0xc626833f, 0x1b03514a),
-+     TOBN(0xabe7905a, 0x83cdd60e), TOBN(0x50602fb5, 0xa1170184),
-+     TOBN(0x689886cd, 0xb023642a), TOBN(0xd568d090, 0xa6e1fb00),
-+     TOBN(0x5b1922c7, 0x0259217f), TOBN(0x93831cd9, 0xc43141e4),
-+     TOBN(0xdfca3587, 0x0c95f86e), TOBN(0xdec2057a, 0x568ae828),
-+     TOBN(0xc44ea599, 0xf98a759a), TOBN(0x55a0a7a2, 0xf7c23c1d),
-+     TOBN(0xd5ffb6e6, 0x94c4f687), TOBN(0x3563cce2, 0x12848478),
-+     TOBN(0x812b3517, 0xe7b1fbe1), TOBN(0x8a7dc979, 0x4f7338e0),
-+     TOBN(0x211ecee9, 0x52d048db), TOBN(0x2eea4056, 0xc86ea3b8),
-+     TOBN(0xd8cb68a7, 0xba772b34), TOBN(0xe16ed341, 0x5f4e2541),
-+     TOBN(0x9b32f6a6, 0x0fec14db), TOBN(0xeee376f7, 0x391698be),
-+     TOBN(0xe9a7aa17, 0x83674c02), TOBN(0x65832f97, 0x5843022a),
-+     TOBN(0x29f3a8da, 0x5ba4990f), TOBN(0x79a59c3a, 0xfb8e3216),
-+     TOBN(0x9cdc4d2e, 0xbd19bb16), TOBN(0xc6c7cfd0, 0xb3262d86),
-+     TOBN(0xd4ce14d0, 0x969c0b47), TOBN(0x1fa352b7, 0x13e56128),
-+     TOBN(0x383d55b8, 0x973db6d3), TOBN(0x71836850, 0xe8e5b7bf),
-+     TOBN(0xc7714596, 0xe6bb571f), TOBN(0x259df31f, 0x2d5b2dd2),
-+     TOBN(0x568f8925, 0x913cc16d), TOBN(0x18bc5b6d, 0xe1a26f5a),
-+     TOBN(0xdfa413be, 0xf5f499ae), TOBN(0xf8835dec, 0xc3f0ae84),
-+     TOBN(0xb6e60bd8, 0x65a40ab0), TOBN(0x65596439, 0x194b377e),
-+     TOBN(0xbcd85625, 0x92084a69), TOBN(0x5ce433b9, 0x4f23ede0),
-+     TOBN(0xe8e8f04f, 0x6ad65143), TOBN(0x11511827, 0xd6e14af6),
-+     TOBN(0x3d390a10, 0x8295c0c7), TOBN(0x71e29ee4, 0x621eba16),
-+     TOBN(0xa588fc09, 0x63717b46), TOBN(0x02be02fe, 0xe06ad4a2),
-+     TOBN(0x931558c6, 0x04c22b22), TOBN(0xbb4d4bd6, 0x12f3c849),
-+     TOBN(0x54a4f496, 0x20efd662), TOBN(0x92ba6d20, 0xc5952d14),
-+     TOBN(0x2db8ea1e, 0xcc9784c2), TOBN(0x81cc10ca, 0x4b353644),
-+     TOBN(0x40b570ad, 0x4b4d7f6c), TOBN(0x5c9f1d96, 0x84a1dcd2),
-+     TOBN(0x01379f81, 0x3147e797), TOBN(0xe5c6097b, 0x2bd499f5),
-+     TOBN(0x40dcafa6, 0x328e5e20), TOBN(0xf7b5244a, 0x54815550),
-+     TOBN(0xb9a4f118, 0x47bfc978), TOBN(0x0ea0e79f, 0xd25825b1),
-+     TOBN(0xa50f96eb, 0x646c7ecf), TOBN(0xeb811493, 0x446dea9d),
-+     TOBN(0x2af04677, 0xdfabcf69), TOBN(0xbe3a068f, 0xc713f6e8),
-+     TOBN(0x860d523d, 0x42e06189), TOBN(0xbf077941, 0x4e3aff13),
-+     TOBN(0x0b616dca, 0xc1b20650), TOBN(0xe66dd6d1, 0x2131300d),
-+     TOBN(0xd4a0fd67, 0xff99abde), TOBN(0xc9903550, 0xc7aac50d),
-+     TOBN(0x022ecf8b, 0x7c46b2d7), TOBN(0x3333b1e8, 0x3abf92af),
-+     TOBN(0x11cc113c, 0x6c491c14), TOBN(0x05976688, 0x80dd3f88),
-+     TOBN(0xf5b4d9e7, 0x29d932ed), TOBN(0xe982aad8, 0xa2c38b6d),
-+     TOBN(0x6f925347, 0x8be0dcf0), TOBN(0x700080ae, 0x65ca53f2),
-+     TOBN(0xd8131156, 0x443ca77f), TOBN(0xe92d6942, 0xec51f984),
-+     TOBN(0xd2a08af8, 0x85dfe9ae), TOBN(0xd825d9a5, 0x4d2a86ca),
-+     TOBN(0x2c53988d, 0x39dff020), TOBN(0xf38b135a, 0x430cdc40),
-+     TOBN(0x0c918ae0, 0x62a7150b), TOBN(0xf31fd8de, 0x0c340e9b),
-+     TOBN(0xafa0e7ae, 0x4dbbf02e), TOBN(0x5847fb2a, 0x5eba6239),
-+     TOBN(0x6b1647dc, 0xdccbac8b), TOBN(0xb642aa78, 0x06f485c8),
-+     TOBN(0x873f3765, 0x7038ecdf), TOBN(0x2ce5e865, 0xfa49d3fe),
-+     TOBN(0xea223788, 0xc98c4400), TOBN(0x8104a8cd, 0xf1fa5279),
-+     TOBN(0xbcf7cc7a, 0x06becfd7), TOBN(0x49424316, 0xc8f974ae),
-+     TOBN(0xc0da65e7, 0x84d6365d), TOBN(0xbcb7443f, 0x8f759fb8),
-+     TOBN(0x35c712b1, 0x7ae81930), TOBN(0x80428dff, 0x4c6e08ab),
-+     TOBN(0xf19dafef, 0xa4faf843), TOBN(0xced8538d, 0xffa9855f),
-+     TOBN(0x20ac409c, 0xbe3ac7ce), TOBN(0x358c1fb6, 0x882da71e),
-+     TOBN(0xafa9c0e5, 0xfd349961), TOBN(0x2b2cfa51, 0x8421c2fc),
-+     TOBN(0x2a80db17, 0xf3a28d38), TOBN(0xa8aba539, 0x5d138e7e),
-+     TOBN(0x52012d1d, 0x6e96eb8d), TOBN(0x65d8dea0, 0xcbaf9622),
-+     TOBN(0x57735447, 0xb264f56c), TOBN(0xbeebef3f, 0x1b6c8da2),
-+     TOBN(0xfc346d98, 0xce785254), TOBN(0xd50e8d72, 0xbb64a161),
-+     TOBN(0xc03567c7, 0x49794add), TOBN(0x15a76065, 0x752c7ef6),
-+     TOBN(0x59f3a222, 0x961f23d6), TOBN(0x378e4438, 0x73ecc0b0),
-+     TOBN(0xc74be434, 0x5a82fde4), TOBN(0xae509af2, 0xd8b9cf34),
-+     TOBN(0x4a61ee46, 0x577f44a1), TOBN(0xe09b748c, 0xb611deeb),
-+     TOBN(0xc0481b2c, 0xf5f7b884), TOBN(0x35626678, 0x61acfa6b),
-+     TOBN(0x37f4c518, 0xbf8d21e6), TOBN(0x22d96531, 0xb205a76d),
-+     TOBN(0x37fb85e1, 0x954073c0), TOBN(0xbceafe4f, 0x65b3a567),
-+     TOBN(0xefecdef7, 0xbe42a582), TOBN(0xd3fc6080, 0x65046be6),
-+     TOBN(0xc9af13c8, 0x09e8dba9), TOBN(0x1e6c9847, 0x641491ff),
-+     TOBN(0x3b574925, 0xd30c31f7), TOBN(0xb7eb72ba, 0xac2a2122),
-+     TOBN(0x776a0dac, 0xef0859e7), TOBN(0x06fec314, 0x21900942),
-+     TOBN(0x2464bc10, 0xf8c22049), TOBN(0x9bfbcce7, 0x875ebf69),
-+     TOBN(0xd7a88e2a, 0x4336326b), TOBN(0xda05261c, 0x5bc2acfa),
-+     TOBN(0xc29f5bdc, 0xeba7efc8), TOBN(0x471237ca, 0x25dbbf2e),
-+     TOBN(0xa72773f2, 0x2975f127), TOBN(0xdc744e8e, 0x04d0b326),
-+     TOBN(0x38a7ed16, 0xa56edb73), TOBN(0x64357e37, 0x2c007e70),
-+     TOBN(0xa167d15b, 0x5080b400), TOBN(0x07b41164, 0x23de4be1),
-+     TOBN(0xb2d91e32, 0x74c89883), TOBN(0x3c162821, 0x2882e7ed),
-+     TOBN(0xad6b36ba, 0x7503e482), TOBN(0x48434e8e, 0x0ea34331),
-+     TOBN(0x79f4f24f, 0x2c7ae0b9), TOBN(0xc46fbf81, 0x1939b44a),
-+     TOBN(0x76fefae8, 0x56595eb1), TOBN(0x417b66ab, 0xcd5f29c7),
-+     TOBN(0x5f2332b2, 0xc5ceec20), TOBN(0xd69661ff, 0xe1a1cae2),
-+     TOBN(0x5ede7e52, 0x9b0286e6), TOBN(0x9d062529, 0xe276b993),
-+     TOBN(0x324794b0, 0x7e50122b), TOBN(0xdd744f8b, 0x4af07ca5),
-+     TOBN(0x30a12f08, 0xd63fc97b), TOBN(0x39650f1a, 0x76626d9d),
-+     TOBN(0x101b47f7, 0x1fa38477), TOBN(0x3d815f19, 0xd4dc124f),
-+     TOBN(0x1569ae95, 0xb26eb58a), TOBN(0xc3cde188, 0x95fb1887),
-+     TOBN(0x54e9f37b, 0xf9539a48), TOBN(0xb0100e06, 0x7408c1a5),
-+     TOBN(0x821d9811, 0xea580cbb), TOBN(0x8af52d35, 0x86e50c56),
-+     TOBN(0xdfbd9d47, 0xdbbf698b), TOBN(0x2961a1ea, 0x03dc1c73),
-+     TOBN(0x203d38f8, 0xe76a5df8), TOBN(0x08a53a68, 0x6def707a),
-+     TOBN(0x26eefb48, 0x1bee45d4), TOBN(0xb3cee346, 0x3c688036),
-+     TOBN(0x463c5315, 0xc42f2469), TOBN(0x19d84d2e, 0x81378162),
-+     TOBN(0x22d7c3c5, 0x1c4d349f), TOBN(0x65965844, 0x163d59c5),
-+     TOBN(0xcf198c56, 0xb8abceae), TOBN(0x6fb1fb1b, 0x628559d5),
-+     TOBN(0x8bbffd06, 0x07bf8fe3), TOBN(0x46259c58, 0x3467734b),
-+     TOBN(0xd8953cea, 0x35f7f0d3), TOBN(0x1f0bece2, 0xd65b0ff1),
-+     TOBN(0xf7d5b4b3, 0xf3c72914), TOBN(0x29e8ea95, 0x3cb53389),
-+     TOBN(0x4a365626, 0x836b6d46), TOBN(0xe849f910, 0xea174fde),
-+     TOBN(0x7ec62fbb, 0xf4737f21), TOBN(0xd8dba5ab, 0x6209f5ac),
-+     TOBN(0x24b5d7a9, 0xa5f9adbe), TOBN(0x707d28f7, 0xa61dc768),
-+     TOBN(0x7711460b, 0xcaa999ea), TOBN(0xba7b174d, 0x1c92e4cc),
-+     TOBN(0x3c4bab66, 0x18d4bf2d), TOBN(0xb8f0c980, 0xeb8bd279),
-+     TOBN(0x024bea9a, 0x324b4737), TOBN(0xfba9e423, 0x32a83bca),
-+     TOBN(0x6e635643, 0xa232dced), TOBN(0x99619367, 0x2571c8ba),
-+     TOBN(0xe8c9f357, 0x54b7032b), TOBN(0xf936b3ba, 0x2442d54a),
-+     TOBN(0x2263f0f0, 0x8290c65a), TOBN(0x48989780, 0xee2c7fdb),
-+     TOBN(0xadc5d55a, 0x13d4f95e), TOBN(0x737cff85, 0xad9b8500),
-+     TOBN(0x271c557b, 0x8a73f43d), TOBN(0xbed617a4, 0xe18bc476),
-+     TOBN(0x66245401, 0x7dfd8ab2), TOBN(0xae7b89ae, 0x3a2870aa),
-+     TOBN(0x1b555f53, 0x23a7e545), TOBN(0x6791e247, 0xbe057e4c),
-+     TOBN(0x860136ad, 0x324fa34d), TOBN(0xea111447, 0x4cbeae28),
-+     TOBN(0x023a4270, 0xbedd3299), TOBN(0x3d5c3a7f, 0xc1c35c34),
-+     TOBN(0xb0f6db67, 0x8d0412d2), TOBN(0xd92625e2, 0xfcdc6b9a),
-+     TOBN(0x92ae5ccc, 0x4e28a982), TOBN(0xea251c36, 0x47a3ce7e),
-+     TOBN(0x9d658932, 0x790691bf), TOBN(0xed610589, 0x06b736ae),
-+     TOBN(0x712c2f04, 0xc0d63b6e), TOBN(0x5cf06fd5, 0xc63d488f),
-+     TOBN(0x97363fac, 0xd9588e41), TOBN(0x1f9bf762, 0x2b93257e),
-+     TOBN(0xa9d1ffc4, 0x667acace), TOBN(0x1cf4a1aa, 0x0a061ecf),
-+     TOBN(0x40e48a49, 0xdc1818d0), TOBN(0x0643ff39, 0xa3621ab0),
-+     TOBN(0x5768640c, 0xe39ef639), TOBN(0x1fc099ea, 0x04d86854),
-+     TOBN(0x9130b9c3, 0xeccd28fd), TOBN(0xd743cbd2, 0x7eec54ab),
-+     TOBN(0x052b146f, 0xe5b475b6), TOBN(0x058d9a82, 0x900a7d1f),
-+     TOBN(0x65e02292, 0x91262b72), TOBN(0x96f924f9, 0xbb0edf03),
-+     TOBN(0x5cfa59c8, 0xfe206842), TOBN(0xf6037004, 0x5eafa720),
-+     TOBN(0x5f30699e, 0x18d7dd96), TOBN(0x381e8782, 0xcbab2495),
-+     TOBN(0x91669b46, 0xdd8be949), TOBN(0xb40606f5, 0x26aae8ef),
-+     TOBN(0x2812b839, 0xfc6751a4), TOBN(0x16196214, 0xfba800ef),
-+     TOBN(0x4398d5ca, 0x4c1a2875), TOBN(0x720c00ee, 0x653d8349),
-+     TOBN(0xc2699eb0, 0xd820007c), TOBN(0x880ee660, 0xa39b5825),
-+     TOBN(0x70694694, 0x471f6984), TOBN(0xf7d16ea8, 0xe3dda99a),
-+     TOBN(0x28d675b2, 0xc0519a23), TOBN(0x9ebf94fe, 0x4f6952e3),
-+     TOBN(0xf28bb767, 0xa2294a8a), TOBN(0x85512b4d, 0xfe0af3f5),
-+     TOBN(0x18958ba8, 0x99b16a0d), TOBN(0x95c2430c, 0xba7548a7),
-+     TOBN(0xb30d1b10, 0xa16be615), TOBN(0xe3ebbb97, 0x85bfb74c),
-+     TOBN(0xa3273cfe, 0x18549fdb), TOBN(0xf6e200bf, 0x4fcdb792),
-+     TOBN(0x54a76e18, 0x83aba56c), TOBN(0x73ec66f6, 0x89ef6aa2),
-+     TOBN(0x8d17add7, 0xd1b9a305), TOBN(0xa959c5b9, 0xb7ae1b9d),
-+     TOBN(0x88643522, 0x6bcc094a), TOBN(0xcc5616c4, 0xd7d429b9),
-+     TOBN(0xa6dada01, 0xe6a33f7c), TOBN(0xc6217a07, 0x9d4e70ad),
-+     TOBN(0xd619a818, 0x09c15b7c), TOBN(0xea06b329, 0x0e80c854),
-+     TOBN(0x174811ce, 0xa5f5e7b9), TOBN(0x66dfc310, 0x787c65f4),
-+     TOBN(0x4ea7bd69, 0x3316ab54), TOBN(0xc12c4acb, 0x1dcc0f70),
-+     TOBN(0xe4308d1a, 0x1e407dd9), TOBN(0xe8a3587c, 0x91afa997),
-+     TOBN(0xea296c12, 0xab77b7a5), TOBN(0xb5ad49e4, 0x673c0d52),
-+     TOBN(0x40f9b2b2, 0x7006085a), TOBN(0xa88ff340, 0x87bf6ec2),
-+     TOBN(0x978603b1, 0x4e3066a6), TOBN(0xb3f99fc2, 0xb5e486e2),
-+     TOBN(0x07b53f5e, 0xb2e63645), TOBN(0xbe57e547, 0x84c84232),
-+     TOBN(0xd779c216, 0x7214d5cf), TOBN(0x617969cd, 0x029a3aca),
-+     TOBN(0xd17668cd, 0x8a7017a0), TOBN(0x77b4d19a, 0xbe9b7ee8),
-+     TOBN(0x58fd0e93, 0x9c161776), TOBN(0xa8c4f4ef, 0xd5968a72),
-+     TOBN(0x296071cc, 0x67b3de77), TOBN(0xae3c0b8e, 0x634f7905),
-+     TOBN(0x67e440c2, 0x8a7100c9), TOBN(0xbb8c3c1b, 0xeb4b9b42),
-+     TOBN(0x6d71e8ea, 0xc51b3583), TOBN(0x7591f5af, 0x9525e642),
-+     TOBN(0xf73a2f7b, 0x13f509f3), TOBN(0x618487aa, 0x5619ac9b),
-+     TOBN(0x3a72e5f7, 0x9d61718a), TOBN(0x00413bcc, 0x7592d28c),
-+     TOBN(0x7d9b11d3, 0x963c35cf), TOBN(0x77623bcf, 0xb90a46ed),
-+     TOBN(0xdeef273b, 0xdcdd2a50), TOBN(0x4a741f9b, 0x0601846e),
-+     TOBN(0x33b89e51, 0x0ec6e929), TOBN(0xcb02319f, 0x8b7f22cd),
-+     TOBN(0xbbe1500d, 0x084bae24), TOBN(0x2f0ae8d7, 0x343d2693),
-+     TOBN(0xacffb5f2, 0x7cdef811), TOBN(0xaa0c030a, 0x263fb94f),
-+     TOBN(0x6eef0d61, 0xa0f442de), TOBN(0xf92e1817, 0x27b139d3),
-+     TOBN(0x1ae6deb7, 0x0ad8bc28), TOBN(0xa89e38dc, 0xc0514130),
-+     TOBN(0x81eeb865, 0xd2fdca23), TOBN(0x5a15ee08, 0xcc8ef895),
-+     TOBN(0x768fa10a, 0x01905614), TOBN(0xeff5b8ef, 0x880ee19b),
-+     TOBN(0xf0c0cabb, 0xcb1c8a0e), TOBN(0x2e1ee9cd, 0xb8c838f9),
-+     TOBN(0x0587d8b8, 0x8a4a14c0), TOBN(0xf6f27896, 0x2ff698e5),
-+     TOBN(0xed38ef1c, 0x89ee6256), TOBN(0xf44ee1fe, 0x6b353b45),
-+     TOBN(0x9115c0c7, 0x70e903b3), TOBN(0xc78ec0a1, 0x818f31df),
-+     TOBN(0x6c003324, 0xb7dccbc6), TOBN(0xd96dd1f3, 0x163bbc25),
-+     TOBN(0x33aa82dd, 0x5cedd805), TOBN(0x123aae4f, 0x7f7eb2f1),
-+     TOBN(0x1723fcf5, 0xa26262cd), TOBN(0x1f7f4d5d, 0x0060ebd5),
-+     TOBN(0xf19c5c01, 0xb2eaa3af), TOBN(0x2ccb9b14, 0x9790accf),
-+     TOBN(0x1f9c1cad, 0x52324aa6), TOBN(0x63200526, 0x7247df54),
-+     TOBN(0x5732fe42, 0xbac96f82), TOBN(0x52fe771f, 0x01a1c384),
-+     TOBN(0x546ca13d, 0xb1001684), TOBN(0xb56b4eee, 0xa1709f75),
-+     TOBN(0x266545a9, 0xd5db8672), TOBN(0xed971c90, 0x1e8f3cfb),
-+     TOBN(0x4e7d8691, 0xe3a07b29), TOBN(0x7570d9ec, 0xe4b696b9),
-+     TOBN(0xdc5fa067, 0x7bc7e9ae), TOBN(0x68b44caf, 0xc82c4844),
-+     TOBN(0x519d34b3, 0xbf44da80), TOBN(0x283834f9, 0x5ab32e66),
-+     TOBN(0x6e608797, 0x6278a000), TOBN(0x1e62960e, 0x627312f6),
-+     TOBN(0x9b87b27b, 0xe6901c55), TOBN(0x80e78538, 0x24fdbc1f),
-+     TOBN(0xbbbc0951, 0x2facc27d), TOBN(0x06394239, 0xac143b5a),
-+     TOBN(0x35bb4a40, 0x376c1944), TOBN(0x7cb62694, 0x63da1511),
-+     TOBN(0xafd29161, 0xb7148a3b), TOBN(0xa6f9d9ed, 0x4e2ea2ee),
-+     TOBN(0x15dc2ca2, 0x880dd212), TOBN(0x903c3813, 0xa61139a9),
-+     TOBN(0x2aa7b46d, 0x6c0f8785), TOBN(0x36ce2871, 0x901c60ff),
-+     TOBN(0xc683b028, 0xe10d9c12), TOBN(0x7573baa2, 0x032f33d3),
-+     TOBN(0x87a9b1f6, 0x67a31b58), TOBN(0xfd3ed11a, 0xf4ffae12),
-+     TOBN(0x83dcaa9a, 0x0cb2748e), TOBN(0x8239f018, 0x5d6fdf16),
-+     TOBN(0xba67b49c, 0x72753941), TOBN(0x2beec455, 0xc321cb36),
-+     TOBN(0x88015606, 0x3f8b84ce), TOBN(0x76417083, 0x8d38c86f),
-+     TOBN(0x054f1ca7, 0x598953dd), TOBN(0xc939e110, 0x4e8e7429),
-+     TOBN(0x9b1ac2b3, 0x5a914f2f), TOBN(0x39e35ed3, 0xe74b8f9c),
-+     TOBN(0xd0debdb2, 0x781b2fb0), TOBN(0x1585638f, 0x2d997ba2),
-+     TOBN(0x9c4b646e, 0x9e2fce99), TOBN(0x68a21081, 0x1e80857f),
-+     TOBN(0x06d54e44, 0x3643b52a), TOBN(0xde8d6d63, 0x0d8eb843),
-+     TOBN(0x70321563, 0x42146a0a), TOBN(0x8ba826f2, 0x5eaa3622),
-+     TOBN(0x227a58bd, 0x86138787), TOBN(0x43b6c03c, 0x10281d37),
-+     TOBN(0x6326afbb, 0xb54dde39), TOBN(0x744e5e8a, 0xdb6f2d5f),
-+     TOBN(0x48b2a99a, 0xcff158e1), TOBN(0xa93c8fa0, 0xef87918f),
-+     TOBN(0x2182f956, 0xde058c5c), TOBN(0x216235d2, 0x936f9e7a),
-+     TOBN(0xace0c0db, 0xd2e31e67), TOBN(0xc96449bf, 0xf23ac3e7),
-+     TOBN(0x7e9a2874, 0x170693bd), TOBN(0xa28e14fd, 0xa45e6335),
-+     TOBN(0x5757f6b3, 0x56427344), TOBN(0x822e4556, 0xacf8edf9),
-+     TOBN(0x2b7a6ee2, 0xe6a285cd), TOBN(0x5866f211, 0xa9df3af0),
-+     TOBN(0x40dde2dd, 0xf845b844), TOBN(0x986c3726, 0x110e5e49),
-+     TOBN(0x73680c2a, 0xf7172277), TOBN(0x57b94f0f, 0x0cccb244),
-+     TOBN(0xbdff7267, 0x2d438ca7), TOBN(0xbad1ce11, 0xcf4663fd),
-+     TOBN(0x9813ed9d, 0xd8f71cae), TOBN(0xf43272a6, 0x961fdaa6),
-+     TOBN(0xbeff0119, 0xbd6d1637), TOBN(0xfebc4f91, 0x30361978),
-+     TOBN(0x02b37a95, 0x2f41deff), TOBN(0x0e44a59a, 0xe63b89b7),
-+     TOBN(0x673257dc, 0x143ff951), TOBN(0x19c02205, 0xd752baf4),
-+     TOBN(0x46c23069, 0xc4b7d692), TOBN(0x2e6392c3, 0xfd1502ac),
-+     TOBN(0x6057b1a2, 0x1b220846), TOBN(0xe51ff946, 0x0c1b5b63),}
-+    ,
-+    {TOBN(0x6e85cb51, 0x566c5c43), TOBN(0xcff9c919, 0x3597f046),
-+     TOBN(0x9354e90c, 0x4994d94a), TOBN(0xe0a39332, 0x2147927d),
-+     TOBN(0x8427fac1, 0x0dc1eb2b), TOBN(0x88cfd8c2, 0x2ff319fa),
-+     TOBN(0xe2d4e684, 0x01965274), TOBN(0xfa2e067d, 0x67aaa746),
-+     TOBN(0xb6d92a7f, 0x3e5f9f11), TOBN(0x9afe153a, 0xd6cb3b8e),
-+     TOBN(0x4d1a6dd7, 0xddf800bd), TOBN(0xf6c13cc0, 0xcaf17e19),
-+     TOBN(0x15f6c58e, 0x325fc3ee), TOBN(0x71095400, 0xa31dc3b2),
-+     TOBN(0x168e7c07, 0xafa3d3e7), TOBN(0x3f8417a1, 0x94c7ae2d),
-+     TOBN(0xec234772, 0x813b230d), TOBN(0x634d0f5f, 0x17344427),
-+     TOBN(0x11548ab1, 0xd77fc56a), TOBN(0x7fab1750, 0xce06af77),
-+     TOBN(0xb62c10a7, 0x4f7c4f83), TOBN(0xa7d2edc4, 0x220a67d9),
-+     TOBN(0x1c404170, 0x921209a0), TOBN(0x0b9815a0, 0xface59f0),
-+     TOBN(0x2842589b, 0x319540c3), TOBN(0x18490f59, 0xa283d6f8),
-+     TOBN(0xa2731f84, 0xdaae9fcb), TOBN(0x3db6d960, 0xc3683ba0),
-+     TOBN(0xc85c63bb, 0x14611069), TOBN(0xb19436af, 0x0788bf05),
-+     TOBN(0x905459df, 0x347460d2), TOBN(0x73f6e094, 0xe11a7db1),
-+     TOBN(0xdc7f938e, 0xb6357f37), TOBN(0xc5d00f79, 0x2bd8aa62),
-+     TOBN(0xc878dcb9, 0x2ca979fc), TOBN(0x37e83ed9, 0xeb023a99),
-+     TOBN(0x6b23e273, 0x1560bf3d), TOBN(0x1086e459, 0x1d0fae61),
-+     TOBN(0x78248316, 0x9a9414bd), TOBN(0x1b956bc0, 0xf0ea9ea1),
-+     TOBN(0x7b85bb91, 0xc31b9c38), TOBN(0x0c5aa90b, 0x48ef57b5),
-+     TOBN(0xdedeb169, 0xaf3bab6f), TOBN(0xe610ad73, 0x2d373685),
-+     TOBN(0xf13870df, 0x02ba8e15), TOBN(0x0337edb6, 0x8ca7f771),
-+     TOBN(0xe4acf747, 0xb62c036c), TOBN(0xd921d576, 0xb6b94e81),
-+     TOBN(0xdbc86439, 0x2c422f7a), TOBN(0xfb635362, 0xed348898),
-+     TOBN(0x83084668, 0xc45bfcd1), TOBN(0xc357c9e3, 0x2b315e11),
-+     TOBN(0xb173b540, 0x5b2e5b8c), TOBN(0x7e946931, 0xe102b9a4),
-+     TOBN(0x17c890eb, 0x7b0fb199), TOBN(0xec225a83, 0xd61b662b),
-+     TOBN(0xf306a3c8, 0xee3c76cb), TOBN(0x3cf11623, 0xd32a1f6e),
-+     TOBN(0xe6d5ab64, 0x6863e956), TOBN(0x3b8a4cbe, 0x5c005c26),
-+     TOBN(0xdcd529a5, 0x9ce6bb27), TOBN(0xc4afaa52, 0x04d4b16f),
-+     TOBN(0xb0624a26, 0x7923798d), TOBN(0x85e56df6, 0x6b307fab),
-+     TOBN(0x0281893c, 0x2bf29698), TOBN(0x91fc19a4, 0xd7ce7603),
-+     TOBN(0x75a5dca3, 0xad9a558f), TOBN(0x40ceb3fa, 0x4d50bf77),
-+     TOBN(0x1baf6060, 0xbc9ba369), TOBN(0x927e1037, 0x597888c2),
-+     TOBN(0xd936bf19, 0x86a34c07), TOBN(0xd4cf10c1, 0xc34ae980),
-+     TOBN(0x3a3e5334, 0x859dd614), TOBN(0x9c475b5b, 0x18d0c8ee),
-+     TOBN(0x63080d1f, 0x07cd51d5), TOBN(0xc9c0d0a6, 0xb88b4326),
-+     TOBN(0x1ac98691, 0xc234296f), TOBN(0x2a0a83a4, 0x94887fb6),
-+     TOBN(0x56511427, 0x0cea9cf2), TOBN(0x5230a6e8, 0xa24802f5),
-+     TOBN(0xf7a2bf0f, 0x72e3d5c1), TOBN(0x37717446, 0x4f21439e),
-+     TOBN(0xfedcbf25, 0x9ce30334), TOBN(0xe0030a78, 0x7ce202f9),
-+     TOBN(0x6f2d9ebf, 0x1202e9ca), TOBN(0xe79dde6c, 0x75e6e591),
-+     TOBN(0xf52072af, 0xf1dac4f8), TOBN(0x6c8d087e, 0xbb9b404d),
-+     TOBN(0xad0fc73d, 0xbce913af), TOBN(0x909e587b, 0x458a07cb),
-+     TOBN(0x1300da84, 0xd4f00c8a), TOBN(0x425cd048, 0xb54466ac),
-+     TOBN(0xb59cb9be, 0x90e9d8bf), TOBN(0x991616db, 0x3e431b0e),
-+     TOBN(0xd3aa117a, 0x531aecff), TOBN(0x91af92d3, 0x59f4dc3b),
-+     TOBN(0x9b1ec292, 0xe93fda29), TOBN(0x76bb6c17, 0xe97d91bc),
-+     TOBN(0x7509d95f, 0xaface1e6), TOBN(0x3653fe47, 0xbe855ae3),
-+     TOBN(0x73180b28, 0x0f680e75), TOBN(0x75eefd1b, 0xeeb6c26c),
-+     TOBN(0xa4cdf29f, 0xb66d4236), TOBN(0x2d70a997, 0x6b5821d8),
-+     TOBN(0x7a3ee207, 0x20445c36), TOBN(0x71d1ac82, 0x59877174),
-+     TOBN(0x0fc539f7, 0x949f73e9), TOBN(0xd05cf3d7, 0x982e3081),
-+     TOBN(0x8758e20b, 0x7b1c7129), TOBN(0xffadcc20, 0x569e61f2),
-+     TOBN(0xb05d3a2f, 0x59544c2d), TOBN(0xbe16f5c1, 0x9fff5e53),
-+     TOBN(0x73cf65b8, 0xaad58135), TOBN(0x622c2119, 0x037aa5be),
-+     TOBN(0x79373b3f, 0x646fd6a0), TOBN(0x0e029db5, 0x0d3978cf),
-+     TOBN(0x8bdfc437, 0x94fba037), TOBN(0xaefbd687, 0x620797a6),
-+     TOBN(0x3fa5382b, 0xbd30d38e), TOBN(0x7627cfbf, 0x585d7464),
-+     TOBN(0xb2330fef, 0x4e4ca463), TOBN(0xbcef7287, 0x3566cc63),
-+     TOBN(0xd161d2ca, 0xcf780900), TOBN(0x135dc539, 0x5b54827d),
-+     TOBN(0x638f052e, 0x27bf1bc6), TOBN(0x10a224f0, 0x07dfa06c),
-+     TOBN(0xe973586d, 0x6d3321da), TOBN(0x8b0c5738, 0x26152c8f),
-+     TOBN(0x07ef4f2a, 0x34606074), TOBN(0x80fe7fe8, 0xa0f7047a),
-+     TOBN(0x3d1a8152, 0xe1a0e306), TOBN(0x32cf43d8, 0x88da5222),
-+     TOBN(0xbf89a95f, 0x5f02ffe6), TOBN(0x3d9eb9a4, 0x806ad3ea),
-+     TOBN(0x012c17bb, 0x79c8e55e), TOBN(0xfdcd1a74, 0x99c81dac),
-+     TOBN(0x7043178b, 0xb9556098), TOBN(0x4090a1df, 0x801c3886),
-+     TOBN(0x759800ff, 0x9b67b912), TOBN(0x3e5c0304, 0x232620c8),
-+     TOBN(0x4b9d3c4b, 0x70dceeca), TOBN(0xbb2d3c15, 0x181f648e),
-+     TOBN(0xf981d837, 0x6e33345c), TOBN(0xb626289b, 0x0cf2297a),
-+     TOBN(0x766ac659, 0x8baebdcf), TOBN(0x1a28ae09, 0x75df01e5),
-+     TOBN(0xb71283da, 0x375876d8), TOBN(0x4865a96d, 0x607b9800),
-+     TOBN(0x25dd1bcd, 0x237936b2), TOBN(0x332f4f4b, 0x60417494),
-+     TOBN(0xd0923d68, 0x370a2147), TOBN(0x497f5dfb, 0xdc842203),
-+     TOBN(0x9dc74cbd, 0x32be5e0f), TOBN(0x7475bcb7, 0x17a01375),
-+     TOBN(0x438477c9, 0x50d872b1), TOBN(0xcec67879, 0xffe1d63d),
-+     TOBN(0x9b006014, 0xd8578c70), TOBN(0xc9ad99a8, 0x78bb6b8b),
-+     TOBN(0x6799008e, 0x11fb3806), TOBN(0xcfe81435, 0xcd44cab3),
-+     TOBN(0xa2ee1582, 0x2f4fb344), TOBN(0xb8823450, 0x483fa6eb),
-+     TOBN(0x622d323d, 0x652c7749), TOBN(0xd8474a98, 0xbeb0a15b),
-+     TOBN(0xe43c154d, 0x5d1c00d0), TOBN(0x7fd581d9, 0x0e3e7aac),
-+     TOBN(0x2b44c619, 0x2525ddf8), TOBN(0x67a033eb, 0xb8ae9739),
-+     TOBN(0x113ffec1, 0x9ef2d2e4), TOBN(0x1bf6767e, 0xd5a0ea7f),
-+     TOBN(0x57fff75e, 0x03714c0a), TOBN(0xa23c422e, 0x0a23e9ee),
-+     TOBN(0xdd5f6b2d, 0x540f83af), TOBN(0xc2c2c27e, 0x55ea46a7),
-+     TOBN(0xeb6b4246, 0x672a1208), TOBN(0xd13599f7, 0xae634f7a),
-+     TOBN(0xcf914b5c, 0xd7b32c6e), TOBN(0x61a5a640, 0xeaf61814),
-+     TOBN(0x8dc3df8b, 0x208a1bbb), TOBN(0xef627fd6, 0xb6d79aa5),
-+     TOBN(0x44232ffc, 0xc4c86bc8), TOBN(0xe6f9231b, 0x061539fe),
-+     TOBN(0x1d04f25a, 0x958b9533), TOBN(0x180cf934, 0x49e8c885),
-+     TOBN(0x89689595, 0x9884aaf7), TOBN(0xb1959be3, 0x07b348a6),
-+     TOBN(0x96250e57, 0x3c147c87), TOBN(0xae0efb3a, 0xdd0c61f8),
-+     TOBN(0xed00745e, 0xca8c325e), TOBN(0x3c911696, 0xecff3f70),
-+     TOBN(0x73acbc65, 0x319ad41d), TOBN(0x7b01a020, 0xf0b1c7ef),
-+     TOBN(0xea32b293, 0x63a1483f), TOBN(0x89eabe71, 0x7a248f96),
-+     TOBN(0x9c6231d3, 0x343157e5), TOBN(0x93a375e5, 0xdf3c546d),
-+     TOBN(0xe76e9343, 0x6a2afe69), TOBN(0xc4f89100, 0xe166c88e),
-+     TOBN(0x248efd0d, 0x4f872093), TOBN(0xae0eb3ea, 0x8fe0ea61),
-+     TOBN(0xaf89790d, 0x9d79046e), TOBN(0x4d650f2d, 0x6cee0976),
-+     TOBN(0xa3935d9a, 0x43071eca), TOBN(0x66fcd2c9, 0x283b0bfe),
-+     TOBN(0x0e665eb5, 0x696605f1), TOBN(0xe77e5d07, 0xa54cd38d),
-+     TOBN(0x90ee050a, 0x43d950cf), TOBN(0x86ddebda, 0xd32e69b5),
-+     TOBN(0x6ad94a3d, 0xfddf7415), TOBN(0xf7fa1309, 0x3f6e8d5a),
-+     TOBN(0xc4831d1d, 0xe9957f75), TOBN(0x7de28501, 0xd5817447),
-+     TOBN(0x6f1d7078, 0x9e2aeb6b), TOBN(0xba2b9ff4, 0xf67a53c2),
-+     TOBN(0x36963767, 0xdf9defc3), TOBN(0x479deed3, 0x0d38022c),
-+     TOBN(0xd2edb89b, 0x3a8631e8), TOBN(0x8de855de, 0x7a213746),
-+     TOBN(0xb2056cb7, 0xb00c5f11), TOBN(0xdeaefbd0, 0x2c9b85e4),
-+     TOBN(0x03f39a8d, 0xd150892d), TOBN(0x37b84686, 0x218b7985),
-+     TOBN(0x36296dd8, 0xb7375f1a), TOBN(0x472cd4b1, 0xb78e898e),
-+     TOBN(0x15dff651, 0xe9f05de9), TOBN(0xd4045069, 0x2ce98ba9),
-+     TOBN(0x8466a7ae, 0x9b38024c), TOBN(0xb910e700, 0xe5a6b5ef),
-+     TOBN(0xae1c56ea, 0xb3aa8f0d), TOBN(0xbab2a507, 0x7eee74a6),
-+     TOBN(0x0dca11e2, 0x4b4c4620), TOBN(0xfd896e2e, 0x4c47d1f4),
-+     TOBN(0xeb45ae53, 0x308fbd93), TOBN(0x46cd5a2e, 0x02c36fda),
-+     TOBN(0x6a3d4e90, 0xbaa48385), TOBN(0xdd55e62e, 0x9dbe9960),
-+     TOBN(0xa1406aa0, 0x2a81ede7), TOBN(0x6860dd14, 0xf9274ea7),
-+     TOBN(0xcfdcb0c2, 0x80414f86), TOBN(0xff410b10, 0x22f94327),
-+     TOBN(0x5a33cc38, 0x49ad467b), TOBN(0xefb48b6c, 0x0a7335f1),
-+     TOBN(0x14fb54a4, 0xb153a360), TOBN(0x604aa9d2, 0xb52469cc),
-+     TOBN(0x5e9dc486, 0x754e48e9), TOBN(0x693cb455, 0x37471e8e),
-+     TOBN(0xfb2fd7cd, 0x8d3b37b6), TOBN(0x63345e16, 0xcf09ff07),
-+     TOBN(0x9910ba6b, 0x23a5d896), TOBN(0x1fe19e35, 0x7fe4364e),
-+     TOBN(0x6e1da8c3, 0x9a33c677), TOBN(0x15b4488b, 0x29fd9fd0),
-+     TOBN(0x1f439254, 0x1a1f22bf), TOBN(0x920a8a70, 0xab8163e8),
-+     TOBN(0x3fd1b249, 0x07e5658e), TOBN(0xf2c4f79c, 0xb6ec839b),
-+     TOBN(0x1abbc3d0, 0x4aa38d1b), TOBN(0x3b0db35c, 0xb5d9510e),
-+     TOBN(0x1754ac78, 0x3e60dec0), TOBN(0x53272fd7, 0xea099b33),
-+     TOBN(0x5fb0494f, 0x07a8e107), TOBN(0x4a89e137, 0x6a8191fa),
-+     TOBN(0xa113b7f6, 0x3c4ad544), TOBN(0x88a2e909, 0x6cb9897b),
-+     TOBN(0x17d55de3, 0xb44a3f84), TOBN(0xacb2f344, 0x17c6c690),
-+     TOBN(0x32088168, 0x10232390), TOBN(0xf2e8a61f, 0x6c733bf7),
-+     TOBN(0xa774aab6, 0x9c2d7652), TOBN(0xfb5307e3, 0xed95c5bc),
-+     TOBN(0xa05c73c2, 0x4981f110), TOBN(0x1baae31c, 0xa39458c9),
-+     TOBN(0x1def185b, 0xcbea62e7), TOBN(0xe8ac9eae, 0xeaf63059),
-+     TOBN(0x098a8cfd, 0x9921851c), TOBN(0xd959c3f1, 0x3abe2f5b),
-+     TOBN(0xa4f19525, 0x20e40ae5), TOBN(0x320789e3, 0x07a24aa1),
-+     TOBN(0x259e6927, 0x7392b2bc), TOBN(0x58f6c667, 0x1918668b),
-+     TOBN(0xce1db2bb, 0xc55d2d8b), TOBN(0x41d58bb7, 0xf4f6ca56),
-+     TOBN(0x7650b680, 0x8f877614), TOBN(0x905e16ba, 0xf4c349ed),
-+     TOBN(0xed415140, 0xf661acac), TOBN(0x3b8784f0, 0xcb2270af),
-+     TOBN(0x3bc280ac, 0x8a402cba), TOBN(0xd53f7146, 0x0937921a),
-+     TOBN(0xc03c8ee5, 0xe5681e83), TOBN(0x62126105, 0xf6ac9e4a),
-+     TOBN(0x9503a53f, 0x936b1a38), TOBN(0x3d45e2d4, 0x782fecbd),
-+     TOBN(0x69a5c439, 0x76e8ae98), TOBN(0xb53b2eeb, 0xbfb4b00e),
-+     TOBN(0xf1674712, 0x72386c89), TOBN(0x30ca34a2, 0x4268bce4),
-+     TOBN(0x7f1ed86c, 0x78341730), TOBN(0x8ef5beb8, 0xb525e248),
-+     TOBN(0xbbc489fd, 0xb74fbf38), TOBN(0x38a92a0e, 0x91a0b382),
-+     TOBN(0x7a77ba3f, 0x22433ccf), TOBN(0xde8362d6, 0xa29f05a9),
-+     TOBN(0x7f6a30ea, 0x61189afc), TOBN(0x693b5505, 0x59ef114f),
-+     TOBN(0x50266bc0, 0xcd1797a1), TOBN(0xea17b47e, 0xf4b7af2d),
-+     TOBN(0xd6c4025c, 0x3df9483e), TOBN(0x8cbb9d9f, 0xa37b18c9),
-+     TOBN(0x91cbfd9c, 0x4d8424cf), TOBN(0xdb7048f1, 0xab1c3506),
-+     TOBN(0x9eaf641f, 0x028206a3), TOBN(0xf986f3f9, 0x25bdf6ce),
-+     TOBN(0x262143b5, 0x224c08dc), TOBN(0x2bbb09b4, 0x81b50c91),
-+     TOBN(0xc16ed709, 0xaca8c84f), TOBN(0xa6210d9d, 0xb2850ca8),
-+     TOBN(0x6d8df67a, 0x09cb54d6), TOBN(0x91eef6e0, 0x500919a4),
-+     TOBN(0x90f61381, 0x0f132857), TOBN(0x9acede47, 0xf8d5028b),
-+     TOBN(0x844d1b71, 0x90b771c3), TOBN(0x563b71e4, 0xba6426be),
-+     TOBN(0x2efa2e83, 0xbdb802ff), TOBN(0x3410cbab, 0xab5b4a41),
-+     TOBN(0x555b2d26, 0x30da84dd), TOBN(0xd0711ae9, 0xee1cc29a),
-+     TOBN(0xcf3e8c60, 0x2f547792), TOBN(0x03d7d5de, 0xdc678b35),
-+     TOBN(0x071a2fa8, 0xced806b8), TOBN(0x222e6134, 0x697f1478),
-+     TOBN(0xdc16fd5d, 0xabfcdbbf), TOBN(0x44912ebf, 0x121b53b8),
-+     TOBN(0xac943674, 0x2496c27c), TOBN(0x8ea3176c, 0x1ffc26b0),
-+     TOBN(0xb6e224ac, 0x13debf2c), TOBN(0x524cc235, 0xf372a832),
-+     TOBN(0xd706e1d8, 0x9f6f1b18), TOBN(0x2552f005, 0x44cce35b),
-+     TOBN(0x8c8326c2, 0xa88e31fc), TOBN(0xb5468b2c, 0xf9552047),
-+     TOBN(0xce683e88, 0x3ff90f2b), TOBN(0x77947bdf, 0x2f0a5423),
-+     TOBN(0xd0a1b28b, 0xed56e328), TOBN(0xaee35253, 0xc20134ac),
-+     TOBN(0x7e98367d, 0x3567962f), TOBN(0x379ed61f, 0x8188bffb),
-+     TOBN(0x73bba348, 0xfaf130a1), TOBN(0x6c1f75e1, 0x904ed734),
-+     TOBN(0x18956642, 0x3b4a79fc), TOBN(0xf20bc83d, 0x54ef4493),
-+     TOBN(0x836d425d, 0x9111eca1), TOBN(0xe5b5c318, 0x009a8dcf),
-+     TOBN(0x3360b25d, 0x13221bc5), TOBN(0x707baad2, 0x6b3eeaf7),
-+     TOBN(0xd7279ed8, 0x743a95a1), TOBN(0x7450a875, 0x969e809f),
-+     TOBN(0x32b6bd53, 0xe5d0338f), TOBN(0x1e77f7af, 0x2b883bbc),
-+     TOBN(0x90da12cc, 0x1063ecd0), TOBN(0xe2697b58, 0xc315be47),
-+     TOBN(0x2771a5bd, 0xda85d534), TOBN(0x53e78c1f, 0xff980eea),
-+     TOBN(0xadf1cf84, 0x900385e7), TOBN(0x7d3b14f6, 0xc9387b62),
-+     TOBN(0x170e74b0, 0xcb8f2bd2), TOBN(0x2d50b486, 0x827fa993),
-+     TOBN(0xcdbe8c9a, 0xf6f32bab), TOBN(0x55e906b0, 0xc3b93ab8),
-+     TOBN(0x747f22fc, 0x8fe280d1), TOBN(0xcd8e0de5, 0xb2e114ab),
-+     TOBN(0x5ab7dbeb, 0xe10b68b0), TOBN(0x9dc63a9c, 0xa480d4b2),
-+     TOBN(0x78d4bc3b, 0x4be1495f), TOBN(0x25eb3db8, 0x9359122d),
-+     TOBN(0x3f8ac05b, 0x0809cbdc), TOBN(0xbf4187bb, 0xd37c702f),
-+     TOBN(0x84cea069, 0x1416a6a5), TOBN(0x8f860c79, 0x43ef881c),
-+     TOBN(0x41311f8a, 0x38038a5d), TOBN(0xe78c2ec0, 0xfc612067),
-+     TOBN(0x494d2e81, 0x5ad73581), TOBN(0xb4cc9e00, 0x59604097),
-+     TOBN(0xff558aec, 0xf3612cba), TOBN(0x35beef7a, 0x9e36c39e),
-+     TOBN(0x1845c7cf, 0xdbcf41b9), TOBN(0x5703662a, 0xaea997c0),
-+     TOBN(0x8b925afe, 0xe402f6d8), TOBN(0xd0a1b1ae, 0x4dd72162),
-+     TOBN(0x9f47b375, 0x03c41c4b), TOBN(0xa023829b, 0x0391d042),
-+     TOBN(0x5f5045c3, 0x503b8b0a), TOBN(0x123c2688, 0x98c010e5),
-+     TOBN(0x324ec0cc, 0x36ba06ee), TOBN(0xface3115, 0x3dd2cc0c),
-+     TOBN(0xb364f3be, 0xf333e91f), TOBN(0xef8aff73, 0x28e832b0),
-+     TOBN(0x1e9bad04, 0x2d05841b), TOBN(0x42f0e3df, 0x356a21e2),
-+     TOBN(0xa3270bcb, 0x4add627e), TOBN(0xb09a8158, 0xd322e711),
-+     TOBN(0x86e326a1, 0x0fee104a), TOBN(0xad7788f8, 0x3703f65d),
-+     TOBN(0x7e765430, 0x47bc4833), TOBN(0x6cee582b, 0x2b9b893a),
-+     TOBN(0x9cd2a167, 0xe8f55a7b), TOBN(0xefbee3c6, 0xd9e4190d),
-+     TOBN(0x33ee7185, 0xd40c2e9d), TOBN(0x844cc9c5, 0xa380b548),
-+     TOBN(0x323f8ecd, 0x66926e04), TOBN(0x0001e38f, 0x8110c1ba),
-+     TOBN(0x8dbcac12, 0xfc6a7f07), TOBN(0xd65e1d58, 0x0cec0827),
-+     TOBN(0xd2cd4141, 0xbe76ca2d), TOBN(0x7895cf5c, 0xe892f33a),
-+     TOBN(0x956d230d, 0x367139d2), TOBN(0xa91abd3e, 0xd012c4c1),
-+     TOBN(0x34fa4883, 0x87eb36bf), TOBN(0xc5f07102, 0x914b8fb4),
-+     TOBN(0x90f0e579, 0xadb9c95f), TOBN(0xfe6ea8cb, 0x28888195),
-+     TOBN(0x7b9b5065, 0xedfa9284), TOBN(0x6c510bd2, 0x2b8c8d65),
-+     TOBN(0xd7b8ebef, 0xcbe8aafd), TOBN(0xedb3af98, 0x96b1da07),
-+     TOBN(0x28ff779d, 0x6295d426), TOBN(0x0c4f6ac7, 0x3fa3ad7b),
-+     TOBN(0xec44d054, 0x8b8e2604), TOBN(0x9b32a66d, 0x8b0050e1),
-+     TOBN(0x1f943366, 0xf0476ce2), TOBN(0x7554d953, 0xa602c7b4),
-+     TOBN(0xbe35aca6, 0x524f2809), TOBN(0xb6881229, 0xfd4edbea),
-+     TOBN(0xe8cd0c8f, 0x508efb63), TOBN(0x9eb5b5c8, 0x6abcefc7),
-+     TOBN(0xf5621f5f, 0xb441ab4f), TOBN(0x79e6c046, 0xb76a2b22),
-+     TOBN(0x74a4792c, 0xe37a1f69), TOBN(0xcbd252cb, 0x03542b60),
-+     TOBN(0x785f65d5, 0xb3c20bd3), TOBN(0x8dea6143, 0x4fabc60c),
-+     TOBN(0x45e21446, 0xde673629), TOBN(0x57f7aa1e, 0x703c2d21),
-+     TOBN(0xa0e99b7f, 0x98c868c7), TOBN(0x4e42f66d, 0x8b641676),
-+     TOBN(0x602884dc, 0x91077896), TOBN(0xa0d690cf, 0xc2c9885b),
-+     TOBN(0xfeb4da33, 0x3b9a5187), TOBN(0x5f789598, 0x153c87ee),
-+     TOBN(0x2192dd47, 0x52b16dba), TOBN(0xdeefc0e6, 0x3524c1b1),
-+     TOBN(0x465ea76e, 0xe4383693), TOBN(0x79401711, 0x361b8d98),
-+     TOBN(0xa5f9ace9, 0xf21a15cb), TOBN(0x73d26163, 0xefee9aeb),
-+     TOBN(0xcca844b3, 0xe677016c), TOBN(0x6c122b07, 0x57eaee06),
-+     TOBN(0xb782dce7, 0x15f09690), TOBN(0x508b9b12, 0x2dfc0fc9),
-+     TOBN(0x9015ab4b, 0x65d89fc6), TOBN(0x5e79dab7, 0xd6d5bb0f),
-+     TOBN(0x64f021f0, 0x6c775aa2), TOBN(0xdf09d8cc, 0x37c7eca1),
-+     TOBN(0x9a761367, 0xef2fa506), TOBN(0xed4ca476, 0x5b81eec6),
-+     TOBN(0x262ede36, 0x10bbb8b5), TOBN(0x0737ce83, 0x0641ada3),
-+     TOBN(0x4c94288a, 0xe9831ccc), TOBN(0x487fc1ce, 0x8065e635),
-+     TOBN(0xb13d7ab3, 0xb8bb3659), TOBN(0xdea5df3e, 0x855e4120),
-+     TOBN(0xb9a18573, 0x85eb0244), TOBN(0x1a1b8ea3, 0xa7cfe0a3),
-+     TOBN(0x3b837119, 0x67b0867c), TOBN(0x8d5e0d08, 0x9d364520),
-+     TOBN(0x52dccc1e, 0xd930f0e3), TOBN(0xefbbcec7, 0xbf20bbaf),
-+     TOBN(0x99cffcab, 0x0263ad10), TOBN(0xd8199e6d, 0xfcd18f8a),
-+     TOBN(0x64e2773f, 0xe9f10617), TOBN(0x0079e8e1, 0x08704848),
-+     TOBN(0x1169989f, 0x8a342283), TOBN(0x8097799c, 0xa83012e6),
-+     TOBN(0xece966cb, 0x8a6a9001), TOBN(0x93b3afef, 0x072ac7fc),
-+     TOBN(0xe6893a2a, 0x2db3d5ba), TOBN(0x263dc462, 0x89bf4fdc),
-+     TOBN(0x8852dfc9, 0xe0396673), TOBN(0x7ac70895, 0x3af362b6),
-+     TOBN(0xbb9cce4d, 0x5c2f342b), TOBN(0xbf80907a, 0xb52d7aae),
-+     TOBN(0x97f3d3cd, 0x2161bcd0), TOBN(0xb25b0834, 0x0962744d),
-+     TOBN(0xc5b18ea5, 0x6c3a1dda), TOBN(0xfe4ec7eb, 0x06c92317),
-+     TOBN(0xb787b890, 0xad1c4afe), TOBN(0xdccd9a92, 0x0ede801a),
-+     TOBN(0x9ac6ddda, 0xdb58da1f), TOBN(0x22bbc12f, 0xb8cae6ee),
-+     TOBN(0xc6f8bced, 0x815c4a43), TOBN(0x8105a92c, 0xf96480c7),
-+     TOBN(0x0dc3dbf3, 0x7a859d51), TOBN(0xe3ec7ce6, 0x3041196b),
-+     TOBN(0xd9f64b25, 0x0d1067c9), TOBN(0xf2321321, 0x3d1f8dd8),
-+     TOBN(0x8b5c619c, 0x76497ee8), TOBN(0x5d2b0ac6, 0xc717370e),
-+     TOBN(0x98204cb6, 0x4fcf68e1), TOBN(0x0bdec211, 0x62bc6792),
-+     TOBN(0x6973ccef, 0xa63b1011), TOBN(0xf9e3fa97, 0xe0de1ac5),
-+     TOBN(0x5efb693e, 0x3d0e0c8b), TOBN(0x037248e9, 0xd2d4fcb4),}
-+    ,
-+    {TOBN(0x80802dc9, 0x1ec34f9e), TOBN(0xd8772d35, 0x33810603),
-+     TOBN(0x3f06d66c, 0x530cb4f3), TOBN(0x7be5ed0d, 0xc475c129),
-+     TOBN(0xcb9e3c19, 0x31e82b10), TOBN(0xc63d2857, 0xc9ff6b4c),
-+     TOBN(0xb92118c6, 0x92a1b45e), TOBN(0x0aec4414, 0x7285bbca),
-+     TOBN(0xfc189ae7, 0x1e29a3ef), TOBN(0xcbe906f0, 0x4c93302e),
-+     TOBN(0xd0107914, 0xceaae10e), TOBN(0xb7a23f34, 0xb68e19f8),
-+     TOBN(0xe9d875c2, 0xefd2119d), TOBN(0x03198c6e, 0xfcadc9c8),
-+     TOBN(0x65591bf6, 0x4da17113), TOBN(0x3cf0bbf8, 0x3d443038),
-+     TOBN(0xae485bb7, 0x2b724759), TOBN(0x945353e1, 0xb2d4c63a),
-+     TOBN(0x82159d07, 0xde7d6f2c), TOBN(0x389caef3, 0x4ec5b109),
-+     TOBN(0x4a8ebb53, 0xdb65ef14), TOBN(0x2dc2cb7e, 0xdd99de43),
-+     TOBN(0x816fa3ed, 0x83f2405f), TOBN(0x73429bb9, 0xc14208a3),
-+     TOBN(0xb618d590, 0xb01e6e27), TOBN(0x047e2ccd, 0xe180b2dc),
-+     TOBN(0xd1b299b5, 0x04aea4a9), TOBN(0x412c9e1e, 0x9fa403a4),
-+     TOBN(0x88d28a36, 0x79407552), TOBN(0x49c50136, 0xf332b8e3),
-+     TOBN(0x3a1b6fcc, 0xe668de19), TOBN(0x178851bc, 0x75122b97),
-+     TOBN(0xb1e13752, 0xfb85fa4c), TOBN(0xd61257ce, 0x383c8ce9),
-+     TOBN(0xd43da670, 0xd2f74dae), TOBN(0xa35aa23f, 0xbf846bbb),
-+     TOBN(0x5e74235d, 0x4421fc83), TOBN(0xf6df8ee0, 0xc363473b),
-+     TOBN(0x34d7f52a, 0x3c4aa158), TOBN(0x50d05aab, 0x9bc6d22e),
-+     TOBN(0x8c56e735, 0xa64785f4), TOBN(0xbc56637b, 0x5f29cd07),
-+     TOBN(0x53b2bb80, 0x3ee35067), TOBN(0x50235a0f, 0xdc919270),
-+     TOBN(0x191ab6d8, 0xf2c4aa65), TOBN(0xc3475831, 0x8396023b),
-+     TOBN(0x80400ba5, 0xf0f805ba), TOBN(0x8881065b, 0x5ec0f80f),
-+     TOBN(0xc370e522, 0xcc1b5e83), TOBN(0xde2d4ad1, 0x860b8bfb),
-+     TOBN(0xad364df0, 0x67b256df), TOBN(0x8f12502e, 0xe0138997),
-+     TOBN(0x503fa0dc, 0x7783920a), TOBN(0xe80014ad, 0xc0bc866a),
-+     TOBN(0x3f89b744, 0xd3064ba6), TOBN(0x03511dcd, 0xcba5dba5),
-+     TOBN(0x197dd46d, 0x95a7b1a2), TOBN(0x9c4e7ad6, 0x3c6341fb),
-+     TOBN(0x426eca29, 0x484c2ece), TOBN(0x9211e489, 0xde7f4f8a),
-+     TOBN(0x14997f6e, 0xc78ef1f4), TOBN(0x2b2c0910, 0x06574586),
-+     TOBN(0x17286a6e, 0x1c3eede8), TOBN(0x25f92e47, 0x0f60e018),
-+     TOBN(0x805c5646, 0x31890a36), TOBN(0x703ef600, 0x57feea5b),
-+     TOBN(0x389f747c, 0xaf3c3030), TOBN(0xe0e5daeb, 0x54dd3739),
-+     TOBN(0xfe24a4c3, 0xc9c9f155), TOBN(0x7e4bf176, 0xb5393962),
-+     TOBN(0x37183de2, 0xaf20bf29), TOBN(0x4a1bd7b5, 0xf95a8c3b),
-+     TOBN(0xa83b9699, 0x46191d3d), TOBN(0x281fc8dd, 0x7b87f257),
-+     TOBN(0xb18e2c13, 0x54107588), TOBN(0x6372def7, 0x9b2bafe8),
-+     TOBN(0xdaf4bb48, 0x0d8972ca), TOBN(0x3f2dd4b7, 0x56167a3f),
-+     TOBN(0x1eace32d, 0x84310cf4), TOBN(0xe3bcefaf, 0xe42700aa),
-+     TOBN(0x5fe5691e, 0xd785e73d), TOBN(0xa5db5ab6, 0x2ea60467),
-+     TOBN(0x02e23d41, 0xdfc6514a), TOBN(0x35e8048e, 0xe03c3665),
-+     TOBN(0x3f8b118f, 0x1adaa0f8), TOBN(0x28ec3b45, 0x84ce1a5a),
-+     TOBN(0xe8cacc6e, 0x2c6646b8), TOBN(0x1343d185, 0xdbd0e40f),
-+     TOBN(0xe5d7f844, 0xcaaa358c), TOBN(0x1a1db7e4, 0x9924182a),
-+     TOBN(0xd64cd42d, 0x9c875d9a), TOBN(0xb37b515f, 0x042eeec8),
-+     TOBN(0x4d4dd409, 0x7b165fbe), TOBN(0xfc322ed9, 0xe206eff3),
-+     TOBN(0x7dee4102, 0x59b7e17e), TOBN(0x55a481c0, 0x8236ca00),
-+     TOBN(0x8c885312, 0xc23fc975), TOBN(0x15715806, 0x05d6297b),
-+     TOBN(0xa078868e, 0xf78edd39), TOBN(0x956b31e0, 0x03c45e52),
-+     TOBN(0x470275d5, 0xff7b33a6), TOBN(0xc8d5dc3a, 0x0c7e673f),
-+     TOBN(0x419227b4, 0x7e2f2598), TOBN(0x8b37b634, 0x4c14a975),
-+     TOBN(0xd0667ed6, 0x8b11888c), TOBN(0x5e0e8c3e, 0x803e25dc),
-+     TOBN(0x34e5d0dc, 0xb987a24a), TOBN(0x9f40ac3b, 0xae920323),
-+     TOBN(0x5463de95, 0x34e0f63a), TOBN(0xa128bf92, 0x6b6328f9),
-+     TOBN(0x491ccd7c, 0xda64f1b7), TOBN(0x7ef1ec27, 0xc47bde35),
-+     TOBN(0xa857240f, 0xa36a2737), TOBN(0x35dc1366, 0x63621bc1),
-+     TOBN(0x7a3a6453, 0xd4fb6897), TOBN(0x80f1a439, 0xc929319d),
-+     TOBN(0xfc18274b, 0xf8cb0ba0), TOBN(0xb0b53766, 0x8078c5eb),
-+     TOBN(0xfb0d4924, 0x1e01d0ef), TOBN(0x50d7c67d, 0x372ab09c),
-+     TOBN(0xb4e370af, 0x3aeac968), TOBN(0xe4f7fee9, 0xc4b63266),
-+     TOBN(0xb4acd4c2, 0xe3ac5664), TOBN(0xf8910bd2, 0xceb38cbf),
-+     TOBN(0x1c3ae50c, 0xc9c0726e), TOBN(0x15309569, 0xd97b40bf),
-+     TOBN(0x70884b7f, 0xfd5a5a1b), TOBN(0x3890896a, 0xef8314cd),
-+     TOBN(0x58e1515c, 0xa5618c93), TOBN(0xe665432b, 0x77d942d1),
-+     TOBN(0xb32181bf, 0xb6f767a8), TOBN(0x753794e8, 0x3a604110),
-+     TOBN(0x09afeb7c, 0xe8c0dbcc), TOBN(0x31e02613, 0x598673a3),
-+     TOBN(0x5d98e557, 0x7d46db00), TOBN(0xfc21fb8c, 0x9d985b28),
-+     TOBN(0xc9040116, 0xb0843e0b), TOBN(0x53b1b3a8, 0x69b04531),
-+     TOBN(0xdd1649f0, 0x85d7d830), TOBN(0xbb3bcc87, 0xcb7427e8),
-+     TOBN(0x77261100, 0xc93dce83), TOBN(0x7e79da61, 0xa1922a2a),
-+     TOBN(0x587a2b02, 0xf3149ce8), TOBN(0x147e1384, 0xde92ec83),
-+     TOBN(0x484c83d3, 0xaf077f30), TOBN(0xea78f844, 0x0658b53a),
-+     TOBN(0x912076c2, 0x027aec53), TOBN(0xf34714e3, 0x93c8177d),
-+     TOBN(0x37ef5d15, 0xc2376c84), TOBN(0x8315b659, 0x3d1aa783),
-+     TOBN(0x3a75c484, 0xef852a90), TOBN(0x0ba0c58a, 0x16086bd4),
-+     TOBN(0x29688d7a, 0x529a6d48), TOBN(0x9c7f250d, 0xc2f19203),
-+     TOBN(0x123042fb, 0x682e2df9), TOBN(0x2b7587e7, 0xad8121bc),
-+     TOBN(0x30fc0233, 0xe0182a65), TOBN(0xb82ecf87, 0xe3e1128a),
-+     TOBN(0x71682861, 0x93fb098f), TOBN(0x043e21ae, 0x85e9e6a7),
-+     TOBN(0xab5b49d6, 0x66c834ea), TOBN(0x3be43e18, 0x47414287),
-+     TOBN(0xf40fb859, 0x219a2a47), TOBN(0x0e6559e9, 0xcc58df3c),
-+     TOBN(0xfe1dfe8e, 0x0c6615b4), TOBN(0x14abc8fd, 0x56459d70),
-+     TOBN(0x7be0fa8e, 0x05de0386), TOBN(0x8e63ef68, 0xe9035c7c),
-+     TOBN(0x116401b4, 0x53b31e91), TOBN(0x0cba7ad4, 0x4436b4d8),
-+     TOBN(0x9151f9a0, 0x107afd66), TOBN(0xafaca8d0, 0x1f0ee4c4),
-+     TOBN(0x75fe5c1d, 0x9ee9761c), TOBN(0x3497a16b, 0xf0c0588f),
-+     TOBN(0x3ee2bebd, 0x0304804c), TOBN(0xa8fb9a60, 0xc2c990b9),
-+     TOBN(0xd14d32fe, 0x39251114), TOBN(0x36bf25bc, 0xcac73366),
-+     TOBN(0xc9562c66, 0xdba7495c), TOBN(0x324d301b, 0x46ad348b),
-+     TOBN(0x9f46620c, 0xd670407e), TOBN(0x0ea8d4f1, 0xe3733a01),
-+     TOBN(0xd396d532, 0xb0c324e0), TOBN(0x5b211a0e, 0x03c317cd),
-+     TOBN(0x090d7d20, 0x5ffe7b37), TOBN(0x3b7f3efb, 0x1747d2da),
-+     TOBN(0xa2cb525f, 0xb54fc519), TOBN(0x6e220932, 0xf66a971e),
-+     TOBN(0xddc160df, 0xb486d440), TOBN(0x7fcfec46, 0x3fe13465),
-+     TOBN(0x83da7e4e, 0x76e4c151), TOBN(0xd6fa48a1, 0xd8d302b5),
-+     TOBN(0xc6304f26, 0x5872cd88), TOBN(0x806c1d3c, 0x278b90a1),
-+     TOBN(0x3553e725, 0xcaf0bc1c), TOBN(0xff59e603, 0xbb9d8d5c),
-+     TOBN(0xa4550f32, 0x7a0b85dd), TOBN(0xdec5720a, 0x93ecc217),
-+     TOBN(0x0b88b741, 0x69d62213), TOBN(0x7212f245, 0x5b365955),
-+     TOBN(0x20764111, 0xb5cae787), TOBN(0x13cb7f58, 0x1dfd3124),
-+     TOBN(0x2dca77da, 0x1175aefb), TOBN(0xeb75466b, 0xffaae775),
-+     TOBN(0x74d76f3b, 0xdb6cff32), TOBN(0x7440f37a, 0x61fcda9a),
-+     TOBN(0x1bb3ac92, 0xb525028b), TOBN(0x20fbf8f7, 0xa1975f29),
-+     TOBN(0x982692e1, 0xdf83097f), TOBN(0x28738f6c, 0x554b0800),
-+     TOBN(0xdc703717, 0xa2ce2f2f), TOBN(0x7913b93c, 0x40814194),
-+     TOBN(0x04924593, 0x1fe89636), TOBN(0x7b98443f, 0xf78834a6),
-+     TOBN(0x11c6ab01, 0x5114a5a1), TOBN(0x60deb383, 0xffba5f4c),
-+     TOBN(0x4caa54c6, 0x01a982e6), TOBN(0x1dd35e11, 0x3491cd26),
-+     TOBN(0x973c315f, 0x7cbd6b05), TOBN(0xcab00775, 0x52494724),
-+     TOBN(0x04659b1f, 0x6565e15a), TOBN(0xbf30f529, 0x8c8fb026),
-+     TOBN(0xfc21641b, 0xa8a0de37), TOBN(0xe9c7a366, 0xfa5e5114),
-+     TOBN(0xdb849ca5, 0x52f03ad8), TOBN(0xc7e8dbe9, 0x024e35c0),
-+     TOBN(0xa1a2bbac, 0xcfc3c789), TOBN(0xbf733e7d, 0x9c26f262),
-+     TOBN(0x882ffbf5, 0xb8444823), TOBN(0xb7224e88, 0x6bf8483b),
-+     TOBN(0x53023b8b, 0x65bef640), TOBN(0xaabfec91, 0xd4d5f8cd),
-+     TOBN(0xa40e1510, 0x079ea1bd), TOBN(0x1ad9addc, 0xd05d5d26),
-+     TOBN(0xdb3f2eab, 0x13e68d4f), TOBN(0x1cff1ae2, 0x640f803f),
-+     TOBN(0xe0e7b749, 0xd4cee117), TOBN(0x8e9f275b, 0x4036d909),
-+     TOBN(0xce34e31d, 0x8f4d4c38), TOBN(0x22b37f69, 0xd75130fc),
-+     TOBN(0x83e0f1fd, 0xb4014604), TOBN(0xa8ce9919, 0x89415078),
-+     TOBN(0x82375b75, 0x41792efe), TOBN(0x4f59bf5c, 0x97d4515b),
-+     TOBN(0xac4f324f, 0x923a277d), TOBN(0xd9bc9b7d, 0x650f3406),
-+     TOBN(0xc6fa87d1, 0x8a39bc51), TOBN(0x82588530, 0x5ccc108f),
-+     TOBN(0x5ced3c9f, 0x82e4c634), TOBN(0x8efb8314, 0x3a4464f8),
-+     TOBN(0xe706381b, 0x7a1dca25), TOBN(0x6cd15a3c, 0x5a2a412b),
-+     TOBN(0x9347a8fd, 0xbfcd8fb5), TOBN(0x31db2eef, 0x6e54cd22),
-+     TOBN(0xc4aeb11e, 0xf8d8932f), TOBN(0x11e7c1ed, 0x344411af),
-+     TOBN(0x2653050c, 0xdc9a151e), TOBN(0x9edbfc08, 0x3bb0a859),
-+     TOBN(0x926c81c7, 0xfd5691e7), TOBN(0x9c1b2342, 0x6f39019a),
-+     TOBN(0x64a81c8b, 0x7f8474b9), TOBN(0x90657c07, 0x01761819),
-+     TOBN(0x390b3331, 0x55e0375a), TOBN(0xc676c626, 0xb6ebc47d),
-+     TOBN(0x51623247, 0xb7d6dee8), TOBN(0x0948d927, 0x79659313),
-+     TOBN(0x99700161, 0xe9ab35ed), TOBN(0x06cc32b4, 0x8ddde408),
-+     TOBN(0x6f2fd664, 0x061ef338), TOBN(0x1606fa02, 0xc202e9ed),
-+     TOBN(0x55388bc1, 0x929ba99b), TOBN(0xc4428c5e, 0x1e81df69),
-+     TOBN(0xce2028ae, 0xf91b0b2a), TOBN(0xce870a23, 0xf03dfd3f),
-+     TOBN(0x66ec2c87, 0x0affe8ed), TOBN(0xb205fb46, 0x284d0c00),
-+     TOBN(0xbf5dffe7, 0x44cefa48), TOBN(0xb6fc37a8, 0xa19876d7),
-+     TOBN(0xbecfa84c, 0x08b72863), TOBN(0xd7205ff5, 0x2576374f),
-+     TOBN(0x80330d32, 0x8887de41), TOBN(0x5de0df0c, 0x869ea534),
-+     TOBN(0x13f42753, 0x3c56ea17), TOBN(0xeb1f6069, 0x452b1a78),
-+     TOBN(0x50474396, 0xe30ea15c), TOBN(0x575816a1, 0xc1494125),
-+     TOBN(0xbe1ce55b, 0xfe6bb38f), TOBN(0xb901a948, 0x96ae30f7),
-+     TOBN(0xe5af0f08, 0xd8fc3548), TOBN(0x5010b5d0, 0xd73bfd08),
-+     TOBN(0x993d2880, 0x53fe655a), TOBN(0x99f2630b, 0x1c1309fd),
-+     TOBN(0xd8677baf, 0xb4e3b76f), TOBN(0x14e51ddc, 0xb840784b),
-+     TOBN(0x326c750c, 0xbf0092ce), TOBN(0xc83d306b, 0xf528320f),
-+     TOBN(0xc4456715, 0x77d4715c), TOBN(0xd30019f9, 0x6b703235),
-+     TOBN(0x207ccb2e, 0xd669e986), TOBN(0x57c824af, 0xf6dbfc28),
-+     TOBN(0xf0eb532f, 0xd8f92a23), TOBN(0x4a557fd4, 0x9bb98fd2),
-+     TOBN(0xa57acea7, 0xc1e6199a), TOBN(0x0c663820, 0x8b94b1ed),
-+     TOBN(0x9b42be8f, 0xf83a9266), TOBN(0xc7741c97, 0x0101bd45),
-+     TOBN(0x95770c11, 0x07bd9ceb), TOBN(0x1f50250a, 0x8b2e0744),
-+     TOBN(0xf762eec8, 0x1477b654), TOBN(0xc65b900e, 0x15efe59a),
-+     TOBN(0x88c96148, 0x9546a897), TOBN(0x7e8025b3, 0xc30b4d7c),
-+     TOBN(0xae4065ef, 0x12045cf9), TOBN(0x6fcb2caf, 0x9ccce8bd),
-+     TOBN(0x1fa0ba4e, 0xf2cf6525), TOBN(0xf683125d, 0xcb72c312),
-+     TOBN(0xa01da4ea, 0xe312410e), TOBN(0x67e28677, 0x6cd8e830),
-+     TOBN(0xabd95752, 0x98fb3f07), TOBN(0x05f11e11, 0xeef649a5),
-+     TOBN(0xba47faef, 0x9d3472c2), TOBN(0x3adff697, 0xc77d1345),
-+     TOBN(0x4761fa04, 0xdd15afee), TOBN(0x64f1f61a, 0xb9e69462),
-+     TOBN(0xfa691fab, 0x9bfb9093), TOBN(0x3df8ae8f, 0xa1133dfe),
-+     TOBN(0xcd5f8967, 0x58cc710d), TOBN(0xfbb88d50, 0x16c7fe79),
-+     TOBN(0x8e011b4c, 0xe88c50d1), TOBN(0x7532e807, 0xa8771c4f),
-+     TOBN(0x64c78a48, 0xe2278ee4), TOBN(0x0b283e83, 0x3845072a),
-+     TOBN(0x98a6f291, 0x49e69274), TOBN(0xb96e9668, 0x1868b21c),
-+     TOBN(0x38f0adc2, 0xb1a8908e), TOBN(0x90afcff7, 0x1feb829d),
-+     TOBN(0x9915a383, 0x210b0856), TOBN(0xa5a80602, 0xdef04889),
-+     TOBN(0x800e9af9, 0x7c64d509), TOBN(0x81382d0b, 0xb8996f6f),
-+     TOBN(0x490eba53, 0x81927e27), TOBN(0x46c63b32, 0x4af50182),
-+     TOBN(0x784c5fd9, 0xd3ad62ce), TOBN(0xe4fa1870, 0xf8ae8736),
-+     TOBN(0x4ec9d0bc, 0xd7466b25), TOBN(0x84ddbe1a, 0xdb235c65),
-+     TOBN(0x5e2645ee, 0x163c1688), TOBN(0x570bd00e, 0x00eba747),
-+     TOBN(0xfa51b629, 0x128bfa0f), TOBN(0x92fce1bd, 0x6c1d3b68),
-+     TOBN(0x3e7361dc, 0xb66778b1), TOBN(0x9c7d249d, 0x5561d2bb),
-+     TOBN(0xa40b28bf, 0x0bbc6229), TOBN(0x1c83c05e, 0xdfd91497),
-+     TOBN(0x5f9f5154, 0xf083df05), TOBN(0xbac38b3c, 0xeee66c9d),
-+     TOBN(0xf71db7e3, 0xec0dfcfd), TOBN(0xf2ecda8e, 0x8b0a8416),
-+     TOBN(0x52fddd86, 0x7812aa66), TOBN(0x2896ef10, 0x4e6f4272),
-+     TOBN(0xff27186a, 0x0fe9a745), TOBN(0x08249fcd, 0x49ca70db),
-+     TOBN(0x7425a2e6, 0x441cac49), TOBN(0xf4a0885a, 0xece5ff57),
-+     TOBN(0x6e2cb731, 0x7d7ead58), TOBN(0xf96cf7d6, 0x1898d104),
-+     TOBN(0xafe67c9d, 0x4f2c9a89), TOBN(0x89895a50, 0x1c7bf5bc),
-+     TOBN(0xdc7cb8e5, 0x573cecfa), TOBN(0x66497eae, 0xd15f03e6),
-+     TOBN(0x6bc0de69, 0x3f084420), TOBN(0x323b9b36, 0xacd532b0),
-+     TOBN(0xcfed390a, 0x0115a3c1), TOBN(0x9414c40b, 0x2d65ca0e),
-+     TOBN(0x641406bd, 0x2f530c78), TOBN(0x29369a44, 0x833438f2),
-+     TOBN(0x996884f5, 0x903fa271), TOBN(0xe6da0fd2, 0xb9da921e),
-+     TOBN(0xa6f2f269, 0x5db01e54), TOBN(0x1ee3e9bd, 0x6876214e),
-+     TOBN(0xa26e181c, 0xe27a9497), TOBN(0x36d254e4, 0x8e215e04),
-+     TOBN(0x42f32a6c, 0x252cabca), TOBN(0x99481487, 0x80b57614),
-+     TOBN(0x4c4dfe69, 0x40d9cae1), TOBN(0x05869580, 0x11a10f09),
-+     TOBN(0xca287b57, 0x3491b64b), TOBN(0x77862d5d, 0x3fd4a53b),
-+     TOBN(0xbf94856e, 0x50349126), TOBN(0x2be30bd1, 0x71c5268f),
-+     TOBN(0x10393f19, 0xcbb650a6), TOBN(0x639531fe, 0x778cf9fd),
-+     TOBN(0x02556a11, 0xb2935359), TOBN(0xda38aa96, 0xaf8c126e),
-+     TOBN(0x47dbe6c2, 0x0960167f), TOBN(0x37bbabb6, 0x501901cd),
-+     TOBN(0xb6e979e0, 0x2c947778), TOBN(0xd69a5175, 0x7a1a1dc6),
-+     TOBN(0xc3ed5095, 0x9d9faf0c), TOBN(0x4dd9c096, 0x1d5fa5f0),
-+     TOBN(0xa0c4304d, 0x64f16ea8), TOBN(0x8b1cac16, 0x7e718623),
-+     TOBN(0x0b576546, 0x7c67f03e), TOBN(0x559cf5ad, 0xcbd88c01),
-+     TOBN(0x074877bb, 0x0e2af19a), TOBN(0x1f717ec1, 0xa1228c92),
-+     TOBN(0x70bcb800, 0x326e8920), TOBN(0xec6e2c5c, 0x4f312804),
-+     TOBN(0x426aea7d, 0x3fca4752), TOBN(0xf12c0949, 0x2211f62a),
-+     TOBN(0x24beecd8, 0x7be7b6b5), TOBN(0xb77eaf4c, 0x36d7a27d),
-+     TOBN(0x154c2781, 0xfda78fd3), TOBN(0x848a83b0, 0x264eeabe),
-+     TOBN(0x81287ef0, 0x4ffe2bc4), TOBN(0x7b6d88c6, 0xb6b6fc2a),
-+     TOBN(0x805fb947, 0xce417d99), TOBN(0x4b93dcc3, 0x8b916cc4),
-+     TOBN(0x72e65bb3, 0x21273323), TOBN(0xbcc1badd, 0x6ea9886e),
-+     TOBN(0x0e223011, 0x4bc5ee85), TOBN(0xa561be74, 0xc18ee1e4),
-+     TOBN(0x762fd2d4, 0xa6bcf1f1), TOBN(0x50e6a5a4, 0x95231489),
-+     TOBN(0xca96001f, 0xa00b500b), TOBN(0x5c098cfc, 0x5d7dcdf5),
-+     TOBN(0xa64e2d2e, 0x8c446a85), TOBN(0xbae9bcf1, 0x971f3c62),
-+     TOBN(0x4ec22683, 0x8435a2c5), TOBN(0x8ceaed6c, 0x4bad4643),
-+     TOBN(0xe9f8fb47, 0xccccf4e3), TOBN(0xbd4f3fa4, 0x1ce3b21e),
-+     TOBN(0xd79fb110, 0xa3db3292), TOBN(0xe28a37da, 0xb536c66a),
-+     TOBN(0x279ce87b, 0x8e49e6a9), TOBN(0x70ccfe8d, 0xfdcec8e3),
-+     TOBN(0x2193e4e0, 0x3ba464b2), TOBN(0x0f39d60e, 0xaca9a398),
-+     TOBN(0x7d7932af, 0xf82c12ab), TOBN(0xd8ff50ed, 0x91e7e0f7),
-+     TOBN(0xea961058, 0xfa28a7e0), TOBN(0xc726cf25, 0x0bf5ec74),
-+     TOBN(0xe74d55c8, 0xdb229666), TOBN(0x0bd9abbf, 0xa57f5799),
-+     TOBN(0x7479ef07, 0x4dfc47b3), TOBN(0xd9c65fc3, 0x0c52f91d),
-+     TOBN(0x8e0283fe, 0x36a8bde2), TOBN(0xa32a8b5e, 0x7d4b7280),
-+     TOBN(0x6a677c61, 0x12e83233), TOBN(0x0fbb3512, 0xdcc9bf28),
-+     TOBN(0x562e8ea5, 0x0d780f61), TOBN(0x0db8b22b, 0x1dc4e89c),
-+     TOBN(0x0a6fd1fb, 0x89be0144), TOBN(0x8c77d246, 0xca57113b),
-+     TOBN(0x4639075d, 0xff09c91c), TOBN(0x5b47b17f, 0x5060824c),
-+     TOBN(0x58aea2b0, 0x16287b52), TOBN(0xa1343520, 0xd0cd8eb0),
-+     TOBN(0x6148b4d0, 0xc5d58573), TOBN(0xdd2b6170, 0x291c68ae),
-+     TOBN(0xa61b3929, 0x1da3b3b7), TOBN(0x5f946d79, 0x08c4ac10),
-+     TOBN(0x4105d4a5, 0x7217d583), TOBN(0x5061da3d, 0x25e6de5e),
-+     TOBN(0x3113940d, 0xec1b4991), TOBN(0xf12195e1, 0x36f485ae),
-+     TOBN(0xa7507fb2, 0x731a2ee0), TOBN(0x95057a8e, 0x6e9e196e),
-+     TOBN(0xa3c2c911, 0x2e130136), TOBN(0x97dfbb36, 0x33c60d15),
-+     TOBN(0xcaf3c581, 0xb300ee2b), TOBN(0x77f25d90, 0xf4bac8b8),
-+     TOBN(0xdb1c4f98, 0x6d840cd6), TOBN(0x471d62c0, 0xe634288c),
-+     TOBN(0x8ec2f85e, 0xcec8a161), TOBN(0x41f37cbc, 0xfa6f4ae2),
-+     TOBN(0x6793a20f, 0x4b709985), TOBN(0x7a7bd33b, 0xefa8985b),
-+     TOBN(0x2c6a3fbd, 0x938e6446), TOBN(0x19042619, 0x2a8d47c1),
-+     TOBN(0x16848667, 0xcc36975f), TOBN(0x02acf168, 0x9d5f1dfb),
-+     TOBN(0x62d41ad4, 0x613baa94), TOBN(0xb56fbb92, 0x9f684670),
-+     TOBN(0xce610d0d, 0xe9e40569), TOBN(0x7b99c65f, 0x35489fef),
-+     TOBN(0x0c88ad1b, 0x3df18b97), TOBN(0x81b7d9be, 0x5d0e9edb),
-+     TOBN(0xd85218c0, 0xc716cc0a), TOBN(0xf4b5ff90, 0x85691c49),
-+     TOBN(0xa4fd666b, 0xce356ac6), TOBN(0x17c72895, 0x4b327a7a),
-+     TOBN(0xf93d5085, 0xda6be7de), TOBN(0xff71530e, 0x3301d34e),
-+     TOBN(0x4cd96442, 0xd8f448e8), TOBN(0x9283d331, 0x2ed18ffa),
-+     TOBN(0x4d33dd99, 0x2a849870), TOBN(0xa716964b, 0x41576335),
-+     TOBN(0xff5e3a9b, 0x179be0e5), TOBN(0x5b9d6b1b, 0x83b13632),
-+     TOBN(0x3b8bd7d4, 0xa52f313b), TOBN(0xc9dd95a0, 0x637a4660),
-+     TOBN(0x30035962, 0x0b3e218f), TOBN(0xce1481a3, 0xc7b28a3c),
-+     TOBN(0xab41b43a, 0x43228d83), TOBN(0x24ae1c30, 0x4ad63f99),
-+     TOBN(0x8e525f1a, 0x46a51229), TOBN(0x14af860f, 0xcd26d2b4),
-+     TOBN(0xd6baef61, 0x3f714aa1), TOBN(0xf51865ad, 0xeb78795e),
-+     TOBN(0xd3e21fce, 0xe6a9d694), TOBN(0x82ceb1dd, 0x8a37b527)}
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_oct.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_oct.c
-new file mode 100644
-index 0000000..4d142a4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_oct.c
-@@ -0,0 +1,372 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
-+ * and contributed to the OpenSSL project.
-+ */
-+
-+#include 
-+#include 
-+
-+#include "ec_lcl.h"
-+
-+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
-+                                             EC_POINT *point,
-+                                             const BIGNUM *x_, int y_bit,
-+                                             BN_CTX *ctx)
-+{
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *tmp1, *tmp2, *x, *y;
-+    int ret = 0;
-+
-+    /* clear error queue */
-+    ERR_clear_error();
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return 0;
-+    }
-+
-+    y_bit = (y_bit != 0);
-+
-+    BN_CTX_start(ctx);
-+    tmp1 = BN_CTX_get(ctx);
-+    tmp2 = BN_CTX_get(ctx);
-+    x = BN_CTX_get(ctx);
-+    y = BN_CTX_get(ctx);
-+    if (y == NULL)
-+        goto err;
-+
-+    /*-
-+     * Recover y.  We have a Weierstrass equation
-+     *     y^2 = x^3 + a*x + b,
-+     * so  y  is one of the square roots of  x^3 + a*x + b.
-+     */
-+
-+    /* tmp1 := x^3 */
-+    if (!BN_nnmod(x, x_, group->field, ctx))
-+        goto err;
-+    if (group->meth->field_decode == 0) {
-+        /* field_{sqr,mul} work on standard representation */
-+        if (!group->meth->field_sqr(group, tmp2, x_, ctx))
-+            goto err;
-+        if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
-+            goto err;
-+    } else {
-+        if (!BN_mod_sqr(tmp2, x_, group->field, ctx))
-+            goto err;
-+        if (!BN_mod_mul(tmp1, tmp2, x_, group->field, ctx))
-+            goto err;
-+    }
-+
-+    /* tmp1 := tmp1 + a*x */
-+    if (group->a_is_minus3) {
-+        if (!BN_mod_lshift1_quick(tmp2, x, group->field))
-+            goto err;
-+        if (!BN_mod_add_quick(tmp2, tmp2, x, group->field))
-+            goto err;
-+        if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, group->field))
-+            goto err;
-+    } else {
-+        if (group->meth->field_decode) {
-+            if (!group->meth->field_decode(group, tmp2, group->a, ctx))
-+                goto err;
-+            if (!BN_mod_mul(tmp2, tmp2, x, group->field, ctx))
-+                goto err;
-+        } else {
-+            /* field_mul works on standard representation */
-+            if (!group->meth->field_mul(group, tmp2, group->a, x, ctx))
-+                goto err;
-+        }
-+
-+        if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field))
-+            goto err;
-+    }
-+
-+    /* tmp1 := tmp1 + b */
-+    if (group->meth->field_decode) {
-+        if (!group->meth->field_decode(group, tmp2, group->b, ctx))
-+            goto err;
-+        if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field))
-+            goto err;
-+    } else {
-+        if (!BN_mod_add_quick(tmp1, tmp1, group->b, group->field))
-+            goto err;
-+    }
-+
-+    if (!BN_mod_sqrt(y, tmp1, group->field, ctx)) {
-+        unsigned long err = ERR_peek_last_error();
-+
-+        if (ERR_GET_LIB(err) == ERR_LIB_BN
-+            && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
-+            ERR_clear_error();
-+            ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
-+                  EC_R_INVALID_COMPRESSED_POINT);
-+        } else
-+            ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
-+                  ERR_R_BN_LIB);
-+        goto err;
-+    }
-+
-+    if (y_bit != BN_is_odd(y)) {
-+        if (BN_is_zero(y)) {
-+            int kron;
-+
-+            kron = BN_kronecker(x, group->field, ctx);
-+            if (kron == -2)
-+                goto err;
-+
-+            if (kron == 1)
-+                ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
-+                      EC_R_INVALID_COMPRESSION_BIT);
-+            else
-+                /*
-+                 * BN_mod_sqrt() should have cought this error (not a square)
-+                 */
-+                ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
-+                      EC_R_INVALID_COMPRESSED_POINT);
-+            goto err;
-+        }
-+        if (!BN_usub(y, group->field, y))
-+            goto err;
-+    }
-+    if (y_bit != BN_is_odd(y)) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
-+              ERR_R_INTERNAL_ERROR);
-+        goto err;
-+    }
-+
-+    if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
-+        goto err;
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
-+                               point_conversion_form_t form,
-+                               unsigned char *buf, size_t len, BN_CTX *ctx)
-+{
-+    size_t ret;
-+    BN_CTX *new_ctx = NULL;
-+    int used_ctx = 0;
-+    BIGNUM *x, *y;
-+    size_t field_len, i, skip;
-+
-+    if ((form != POINT_CONVERSION_COMPRESSED)
-+        && (form != POINT_CONVERSION_UNCOMPRESSED)
-+        && (form != POINT_CONVERSION_HYBRID)) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
-+        goto err;
-+    }
-+
-+    if (EC_POINT_is_at_infinity(group, point)) {
-+        /* encodes to a single 0 octet */
-+        if (buf != NULL) {
-+            if (len < 1) {
-+                ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
-+                return 0;
-+            }
-+            buf[0] = 0;
-+        }
-+        return 1;
-+    }
-+
-+    /* ret := required output buffer length */
-+    field_len = BN_num_bytes(group->field);
-+    ret =
-+        (form ==
-+         POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
-+
-+    /* if 'buf' is NULL, just return required length */
-+    if (buf != NULL) {
-+        if (len < ret) {
-+            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
-+            goto err;
-+        }
-+
-+        if (ctx == NULL) {
-+            ctx = new_ctx = BN_CTX_new();
-+            if (ctx == NULL)
-+                return 0;
-+        }
-+
-+        BN_CTX_start(ctx);
-+        used_ctx = 1;
-+        x = BN_CTX_get(ctx);
-+        y = BN_CTX_get(ctx);
-+        if (y == NULL)
-+            goto err;
-+
-+        if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
-+            goto err;
-+
-+        if ((form == POINT_CONVERSION_COMPRESSED
-+             || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
-+            buf[0] = form + 1;
-+        else
-+            buf[0] = form;
-+
-+        i = 1;
-+
-+        skip = field_len - BN_num_bytes(x);
-+        if (skip > field_len) {
-+            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
-+            goto err;
-+        }
-+        while (skip > 0) {
-+            buf[i++] = 0;
-+            skip--;
-+        }
-+        skip = BN_bn2bin(x, buf + i);
-+        i += skip;
-+        if (i != 1 + field_len) {
-+            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
-+            goto err;
-+        }
-+
-+        if (form == POINT_CONVERSION_UNCOMPRESSED
-+            || form == POINT_CONVERSION_HYBRID) {
-+            skip = field_len - BN_num_bytes(y);
-+            if (skip > field_len) {
-+                ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
-+                goto err;
-+            }
-+            while (skip > 0) {
-+                buf[i++] = 0;
-+                skip--;
-+            }
-+            skip = BN_bn2bin(y, buf + i);
-+            i += skip;
-+        }
-+
-+        if (i != ret) {
-+            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
-+            goto err;
-+        }
-+    }
-+
-+    if (used_ctx)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+
-+ err:
-+    if (used_ctx)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return 0;
-+}
-+
-+int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
-+                            const unsigned char *buf, size_t len, BN_CTX *ctx)
-+{
-+    point_conversion_form_t form;
-+    int y_bit;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *x, *y;
-+    size_t field_len, enc_len;
-+    int ret = 0;
-+
-+    if (len == 0) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
-+        return 0;
-+    }
-+    form = buf[0];
-+    y_bit = form & 1;
-+    form = form & ~1U;
-+    if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
-+        && (form != POINT_CONVERSION_UNCOMPRESSED)
-+        && (form != POINT_CONVERSION_HYBRID)) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
-+        return 0;
-+    }
-+    if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
-+        return 0;
-+    }
-+
-+    if (form == 0) {
-+        if (len != 1) {
-+            ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
-+            return 0;
-+        }
-+
-+        return EC_POINT_set_to_infinity(group, point);
-+    }
-+
-+    field_len = BN_num_bytes(group->field);
-+    enc_len =
-+        (form ==
-+         POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
-+
-+    if (len != enc_len) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
-+        return 0;
-+    }
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return 0;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    x = BN_CTX_get(ctx);
-+    y = BN_CTX_get(ctx);
-+    if (y == NULL)
-+        goto err;
-+
-+    if (!BN_bin2bn(buf + 1, field_len, x))
-+        goto err;
-+    if (BN_ucmp(x, group->field) >= 0) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
-+        goto err;
-+    }
-+
-+    if (form == POINT_CONVERSION_COMPRESSED) {
-+        if (!EC_POINT_set_compressed_coordinates_GFp
-+            (group, point, x, y_bit, ctx))
-+            goto err;
-+    } else {
-+        if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
-+            goto err;
-+        if (BN_ucmp(y, group->field) >= 0) {
-+            ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
-+            goto err;
-+        }
-+        if (form == POINT_CONVERSION_HYBRID) {
-+            if (y_bit != BN_is_odd(y)) {
-+                ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
-+                goto err;
-+            }
-+        }
-+
-+        /*
-+         * EC_POINT_set_affine_coordinates_GFp is responsible for checking that
-+         * the point is on the curve.
-+         */
-+        if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
-+            goto err;
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_smpl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_smpl.c
-new file mode 100644
-index 0000000..76e0caf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecp_smpl.c
-@@ -0,0 +1,1369 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
-+ * and contributed to the OpenSSL project.
-+ */
-+
-+#include 
-+#include 
-+
-+#include "ec_lcl.h"
-+
-+const EC_METHOD *EC_GFp_simple_method(void)
-+{
-+    static const EC_METHOD ret = {
-+        EC_FLAGS_DEFAULT_OCT,
-+        NID_X9_62_prime_field,
-+        ec_GFp_simple_group_init,
-+        ec_GFp_simple_group_finish,
-+        ec_GFp_simple_group_clear_finish,
-+        ec_GFp_simple_group_copy,
-+        ec_GFp_simple_group_set_curve,
-+        ec_GFp_simple_group_get_curve,
-+        ec_GFp_simple_group_get_degree,
-+        ec_group_simple_order_bits,
-+        ec_GFp_simple_group_check_discriminant,
-+        ec_GFp_simple_point_init,
-+        ec_GFp_simple_point_finish,
-+        ec_GFp_simple_point_clear_finish,
-+        ec_GFp_simple_point_copy,
-+        ec_GFp_simple_point_set_to_infinity,
-+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
-+        ec_GFp_simple_point_set_affine_coordinates,
-+        ec_GFp_simple_point_get_affine_coordinates,
-+        0, 0, 0,
-+        ec_GFp_simple_add,
-+        ec_GFp_simple_dbl,
-+        ec_GFp_simple_invert,
-+        ec_GFp_simple_is_at_infinity,
-+        ec_GFp_simple_is_on_curve,
-+        ec_GFp_simple_cmp,
-+        ec_GFp_simple_make_affine,
-+        ec_GFp_simple_points_make_affine,
-+        0 /* mul */ ,
-+        0 /* precompute_mult */ ,
-+        0 /* have_precompute_mult */ ,
-+        ec_GFp_simple_field_mul,
-+        ec_GFp_simple_field_sqr,
-+        0 /* field_div */ ,
-+        0 /* field_encode */ ,
-+        0 /* field_decode */ ,
-+        0,                      /* field_set_to_one */
-+        ec_key_simple_priv2oct,
-+        ec_key_simple_oct2priv,
-+        0, /* set private */
-+        ec_key_simple_generate_key,
-+        ec_key_simple_check_key,
-+        ec_key_simple_generate_public_key,
-+        0, /* keycopy */
-+        0, /* keyfinish */
-+        ecdh_simple_compute_key
-+    };
-+
-+    return &ret;
-+}
-+
-+/*
-+ * Most method functions in this file are designed to work with
-+ * non-trivial representations of field elements if necessary
-+ * (see ecp_mont.c): while standard modular addition and subtraction
-+ * are used, the field_mul and field_sqr methods will be used for
-+ * multiplication, and field_encode and field_decode (if defined)
-+ * will be used for converting between representations.
-+ *
-+ * Functions ec_GFp_simple_points_make_affine() and
-+ * ec_GFp_simple_point_get_affine_coordinates() specifically assume
-+ * that if a non-trivial representation is used, it is a Montgomery
-+ * representation (i.e. 'encoding' means multiplying by some factor R).
-+ */
-+
-+int ec_GFp_simple_group_init(EC_GROUP *group)
-+{
-+    group->field = BN_new();
-+    group->a = BN_new();
-+    group->b = BN_new();
-+    if (group->field == NULL || group->a == NULL || group->b == NULL) {
-+        BN_free(group->field);
-+        BN_free(group->a);
-+        BN_free(group->b);
-+        return 0;
-+    }
-+    group->a_is_minus3 = 0;
-+    return 1;
-+}
-+
-+void ec_GFp_simple_group_finish(EC_GROUP *group)
-+{
-+    BN_free(group->field);
-+    BN_free(group->a);
-+    BN_free(group->b);
-+}
-+
-+void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
-+{
-+    BN_clear_free(group->field);
-+    BN_clear_free(group->a);
-+    BN_clear_free(group->b);
-+}
-+
-+int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
-+{
-+    if (!BN_copy(dest->field, src->field))
-+        return 0;
-+    if (!BN_copy(dest->a, src->a))
-+        return 0;
-+    if (!BN_copy(dest->b, src->b))
-+        return 0;
-+
-+    dest->a_is_minus3 = src->a_is_minus3;
-+
-+    return 1;
-+}
-+
-+int ec_GFp_simple_group_set_curve(EC_GROUP *group,
-+                                  const BIGNUM *p, const BIGNUM *a,
-+                                  const BIGNUM *b, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *tmp_a;
-+
-+    /* p must be a prime > 3 */
-+    if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
-+        return 0;
-+    }
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return 0;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    tmp_a = BN_CTX_get(ctx);
-+    if (tmp_a == NULL)
-+        goto err;
-+
-+    /* group->field */
-+    if (!BN_copy(group->field, p))
-+        goto err;
-+    BN_set_negative(group->field, 0);
-+
-+    /* group->a */
-+    if (!BN_nnmod(tmp_a, a, p, ctx))
-+        goto err;
-+    if (group->meth->field_encode) {
-+        if (!group->meth->field_encode(group, group->a, tmp_a, ctx))
-+            goto err;
-+    } else if (!BN_copy(group->a, tmp_a))
-+        goto err;
-+
-+    /* group->b */
-+    if (!BN_nnmod(group->b, b, p, ctx))
-+        goto err;
-+    if (group->meth->field_encode)
-+        if (!group->meth->field_encode(group, group->b, group->b, ctx))
-+            goto err;
-+
-+    /* group->a_is_minus3 */
-+    if (!BN_add_word(tmp_a, 3))
-+        goto err;
-+    group->a_is_minus3 = (0 == BN_cmp(tmp_a, group->field));
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
-+                                  BIGNUM *b, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BN_CTX *new_ctx = NULL;
-+
-+    if (p != NULL) {
-+        if (!BN_copy(p, group->field))
-+            return 0;
-+    }
-+
-+    if (a != NULL || b != NULL) {
-+        if (group->meth->field_decode) {
-+            if (ctx == NULL) {
-+                ctx = new_ctx = BN_CTX_new();
-+                if (ctx == NULL)
-+                    return 0;
-+            }
-+            if (a != NULL) {
-+                if (!group->meth->field_decode(group, a, group->a, ctx))
-+                    goto err;
-+            }
-+            if (b != NULL) {
-+                if (!group->meth->field_decode(group, b, group->b, ctx))
-+                    goto err;
-+            }
-+        } else {
-+            if (a != NULL) {
-+                if (!BN_copy(a, group->a))
-+                    goto err;
-+            }
-+            if (b != NULL) {
-+                if (!BN_copy(b, group->b))
-+                    goto err;
-+            }
-+        }
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
-+{
-+    return BN_num_bits(group->field);
-+}
-+
-+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+    BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
-+    const BIGNUM *p = group->field;
-+    BN_CTX *new_ctx = NULL;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL) {
-+            ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT,
-+                  ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    }
-+    BN_CTX_start(ctx);
-+    a = BN_CTX_get(ctx);
-+    b = BN_CTX_get(ctx);
-+    tmp_1 = BN_CTX_get(ctx);
-+    tmp_2 = BN_CTX_get(ctx);
-+    order = BN_CTX_get(ctx);
-+    if (order == NULL)
-+        goto err;
-+
-+    if (group->meth->field_decode) {
-+        if (!group->meth->field_decode(group, a, group->a, ctx))
-+            goto err;
-+        if (!group->meth->field_decode(group, b, group->b, ctx))
-+            goto err;
-+    } else {
-+        if (!BN_copy(a, group->a))
-+            goto err;
-+        if (!BN_copy(b, group->b))
-+            goto err;
-+    }
-+
-+    /*-
-+     * check the discriminant:
-+     * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
-+     * 0 =< a, b < p
-+     */
-+    if (BN_is_zero(a)) {
-+        if (BN_is_zero(b))
-+            goto err;
-+    } else if (!BN_is_zero(b)) {
-+        if (!BN_mod_sqr(tmp_1, a, p, ctx))
-+            goto err;
-+        if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx))
-+            goto err;
-+        if (!BN_lshift(tmp_1, tmp_2, 2))
-+            goto err;
-+        /* tmp_1 = 4*a^3 */
-+
-+        if (!BN_mod_sqr(tmp_2, b, p, ctx))
-+            goto err;
-+        if (!BN_mul_word(tmp_2, 27))
-+            goto err;
-+        /* tmp_2 = 27*b^2 */
-+
-+        if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx))
-+            goto err;
-+        if (BN_is_zero(a))
-+            goto err;
-+    }
-+    ret = 1;
-+
-+ err:
-+    if (ctx != NULL)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_point_init(EC_POINT *point)
-+{
-+    point->X = BN_new();
-+    point->Y = BN_new();
-+    point->Z = BN_new();
-+    point->Z_is_one = 0;
-+
-+    if (point->X == NULL || point->Y == NULL || point->Z == NULL) {
-+        BN_free(point->X);
-+        BN_free(point->Y);
-+        BN_free(point->Z);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+void ec_GFp_simple_point_finish(EC_POINT *point)
-+{
-+    BN_free(point->X);
-+    BN_free(point->Y);
-+    BN_free(point->Z);
-+}
-+
-+void ec_GFp_simple_point_clear_finish(EC_POINT *point)
-+{
-+    BN_clear_free(point->X);
-+    BN_clear_free(point->Y);
-+    BN_clear_free(point->Z);
-+    point->Z_is_one = 0;
-+}
-+
-+int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
-+{
-+    if (!BN_copy(dest->X, src->X))
-+        return 0;
-+    if (!BN_copy(dest->Y, src->Y))
-+        return 0;
-+    if (!BN_copy(dest->Z, src->Z))
-+        return 0;
-+    dest->Z_is_one = src->Z_is_one;
-+
-+    return 1;
-+}
-+
-+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
-+                                        EC_POINT *point)
-+{
-+    point->Z_is_one = 0;
-+    BN_zero(point->Z);
-+    return 1;
-+}
-+
-+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
-+                                                  EC_POINT *point,
-+                                                  const BIGNUM *x,
-+                                                  const BIGNUM *y,
-+                                                  const BIGNUM *z,
-+                                                  BN_CTX *ctx)
-+{
-+    BN_CTX *new_ctx = NULL;
-+    int ret = 0;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return 0;
-+    }
-+
-+    if (x != NULL) {
-+        if (!BN_nnmod(point->X, x, group->field, ctx))
-+            goto err;
-+        if (group->meth->field_encode) {
-+            if (!group->meth->field_encode(group, point->X, point->X, ctx))
-+                goto err;
-+        }
-+    }
-+
-+    if (y != NULL) {
-+        if (!BN_nnmod(point->Y, y, group->field, ctx))
-+            goto err;
-+        if (group->meth->field_encode) {
-+            if (!group->meth->field_encode(group, point->Y, point->Y, ctx))
-+                goto err;
-+        }
-+    }
-+
-+    if (z != NULL) {
-+        int Z_is_one;
-+
-+        if (!BN_nnmod(point->Z, z, group->field, ctx))
-+            goto err;
-+        Z_is_one = BN_is_one(point->Z);
-+        if (group->meth->field_encode) {
-+            if (Z_is_one && (group->meth->field_set_to_one != 0)) {
-+                if (!group->meth->field_set_to_one(group, point->Z, ctx))
-+                    goto err;
-+            } else {
-+                if (!group->
-+                    meth->field_encode(group, point->Z, point->Z, ctx))
-+                    goto err;
-+            }
-+        }
-+        point->Z_is_one = Z_is_one;
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
-+                                                  const EC_POINT *point,
-+                                                  BIGNUM *x, BIGNUM *y,
-+                                                  BIGNUM *z, BN_CTX *ctx)
-+{
-+    BN_CTX *new_ctx = NULL;
-+    int ret = 0;
-+
-+    if (group->meth->field_decode != 0) {
-+        if (ctx == NULL) {
-+            ctx = new_ctx = BN_CTX_new();
-+            if (ctx == NULL)
-+                return 0;
-+        }
-+
-+        if (x != NULL) {
-+            if (!group->meth->field_decode(group, x, point->X, ctx))
-+                goto err;
-+        }
-+        if (y != NULL) {
-+            if (!group->meth->field_decode(group, y, point->Y, ctx))
-+                goto err;
-+        }
-+        if (z != NULL) {
-+            if (!group->meth->field_decode(group, z, point->Z, ctx))
-+                goto err;
-+        }
-+    } else {
-+        if (x != NULL) {
-+            if (!BN_copy(x, point->X))
-+                goto err;
-+        }
-+        if (y != NULL) {
-+            if (!BN_copy(y, point->Y))
-+                goto err;
-+        }
-+        if (z != NULL) {
-+            if (!BN_copy(z, point->Z))
-+                goto err;
-+        }
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
-+                                               EC_POINT *point,
-+                                               const BIGNUM *x,
-+                                               const BIGNUM *y, BN_CTX *ctx)
-+{
-+    if (x == NULL || y == NULL) {
-+        /*
-+         * unlike for projective coordinates, we do not tolerate this
-+         */
-+        ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES,
-+              ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+
-+    return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y,
-+                                                    BN_value_one(), ctx);
-+}
-+
-+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
-+                                               const EC_POINT *point,
-+                                               BIGNUM *x, BIGNUM *y,
-+                                               BN_CTX *ctx)
-+{
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *Z, *Z_1, *Z_2, *Z_3;
-+    const BIGNUM *Z_;
-+    int ret = 0;
-+
-+    if (EC_POINT_is_at_infinity(group, point)) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
-+              EC_R_POINT_AT_INFINITY);
-+        return 0;
-+    }
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return 0;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    Z = BN_CTX_get(ctx);
-+    Z_1 = BN_CTX_get(ctx);
-+    Z_2 = BN_CTX_get(ctx);
-+    Z_3 = BN_CTX_get(ctx);
-+    if (Z_3 == NULL)
-+        goto err;
-+
-+    /* transform  (X, Y, Z)  into  (x, y) := (X/Z^2, Y/Z^3) */
-+
-+    if (group->meth->field_decode) {
-+        if (!group->meth->field_decode(group, Z, point->Z, ctx))
-+            goto err;
-+        Z_ = Z;
-+    } else {
-+        Z_ = point->Z;
-+    }
-+
-+    if (BN_is_one(Z_)) {
-+        if (group->meth->field_decode) {
-+            if (x != NULL) {
-+                if (!group->meth->field_decode(group, x, point->X, ctx))
-+                    goto err;
-+            }
-+            if (y != NULL) {
-+                if (!group->meth->field_decode(group, y, point->Y, ctx))
-+                    goto err;
-+            }
-+        } else {
-+            if (x != NULL) {
-+                if (!BN_copy(x, point->X))
-+                    goto err;
-+            }
-+            if (y != NULL) {
-+                if (!BN_copy(y, point->Y))
-+                    goto err;
-+            }
-+        }
-+    } else {
-+        if (!BN_mod_inverse(Z_1, Z_, group->field, ctx)) {
-+            ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
-+                  ERR_R_BN_LIB);
-+            goto err;
-+        }
-+
-+        if (group->meth->field_encode == 0) {
-+            /* field_sqr works on standard representation */
-+            if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
-+                goto err;
-+        } else {
-+            if (!BN_mod_sqr(Z_2, Z_1, group->field, ctx))
-+                goto err;
-+        }
-+
-+        if (x != NULL) {
-+            /*
-+             * in the Montgomery case, field_mul will cancel out Montgomery
-+             * factor in X:
-+             */
-+            if (!group->meth->field_mul(group, x, point->X, Z_2, ctx))
-+                goto err;
-+        }
-+
-+        if (y != NULL) {
-+            if (group->meth->field_encode == 0) {
-+                /*
-+                 * field_mul works on standard representation
-+                 */
-+                if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
-+                    goto err;
-+            } else {
-+                if (!BN_mod_mul(Z_3, Z_2, Z_1, group->field, ctx))
-+                    goto err;
-+            }
-+
-+            /*
-+             * in the Montgomery case, field_mul will cancel out Montgomery
-+             * factor in Y:
-+             */
-+            if (!group->meth->field_mul(group, y, point->Y, Z_3, ctx))
-+                goto err;
-+        }
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
-+                      const EC_POINT *b, BN_CTX *ctx)
-+{
-+    int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
-+                      const BIGNUM *, BN_CTX *);
-+    int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
-+    const BIGNUM *p;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
-+    int ret = 0;
-+
-+    if (a == b)
-+        return EC_POINT_dbl(group, r, a, ctx);
-+    if (EC_POINT_is_at_infinity(group, a))
-+        return EC_POINT_copy(r, b);
-+    if (EC_POINT_is_at_infinity(group, b))
-+        return EC_POINT_copy(r, a);
-+
-+    field_mul = group->meth->field_mul;
-+    field_sqr = group->meth->field_sqr;
-+    p = group->field;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return 0;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    n0 = BN_CTX_get(ctx);
-+    n1 = BN_CTX_get(ctx);
-+    n2 = BN_CTX_get(ctx);
-+    n3 = BN_CTX_get(ctx);
-+    n4 = BN_CTX_get(ctx);
-+    n5 = BN_CTX_get(ctx);
-+    n6 = BN_CTX_get(ctx);
-+    if (n6 == NULL)
-+        goto end;
-+
-+    /*
-+     * Note that in this function we must not read components of 'a' or 'b'
-+     * once we have written the corresponding components of 'r'. ('r' might
-+     * be one of 'a' or 'b'.)
-+     */
-+
-+    /* n1, n2 */
-+    if (b->Z_is_one) {
-+        if (!BN_copy(n1, a->X))
-+            goto end;
-+        if (!BN_copy(n2, a->Y))
-+            goto end;
-+        /* n1 = X_a */
-+        /* n2 = Y_a */
-+    } else {
-+        if (!field_sqr(group, n0, b->Z, ctx))
-+            goto end;
-+        if (!field_mul(group, n1, a->X, n0, ctx))
-+            goto end;
-+        /* n1 = X_a * Z_b^2 */
-+
-+        if (!field_mul(group, n0, n0, b->Z, ctx))
-+            goto end;
-+        if (!field_mul(group, n2, a->Y, n0, ctx))
-+            goto end;
-+        /* n2 = Y_a * Z_b^3 */
-+    }
-+
-+    /* n3, n4 */
-+    if (a->Z_is_one) {
-+        if (!BN_copy(n3, b->X))
-+            goto end;
-+        if (!BN_copy(n4, b->Y))
-+            goto end;
-+        /* n3 = X_b */
-+        /* n4 = Y_b */
-+    } else {
-+        if (!field_sqr(group, n0, a->Z, ctx))
-+            goto end;
-+        if (!field_mul(group, n3, b->X, n0, ctx))
-+            goto end;
-+        /* n3 = X_b * Z_a^2 */
-+
-+        if (!field_mul(group, n0, n0, a->Z, ctx))
-+            goto end;
-+        if (!field_mul(group, n4, b->Y, n0, ctx))
-+            goto end;
-+        /* n4 = Y_b * Z_a^3 */
-+    }
-+
-+    /* n5, n6 */
-+    if (!BN_mod_sub_quick(n5, n1, n3, p))
-+        goto end;
-+    if (!BN_mod_sub_quick(n6, n2, n4, p))
-+        goto end;
-+    /* n5 = n1 - n3 */
-+    /* n6 = n2 - n4 */
-+
-+    if (BN_is_zero(n5)) {
-+        if (BN_is_zero(n6)) {
-+            /* a is the same point as b */
-+            BN_CTX_end(ctx);
-+            ret = EC_POINT_dbl(group, r, a, ctx);
-+            ctx = NULL;
-+            goto end;
-+        } else {
-+            /* a is the inverse of b */
-+            BN_zero(r->Z);
-+            r->Z_is_one = 0;
-+            ret = 1;
-+            goto end;
-+        }
-+    }
-+
-+    /* 'n7', 'n8' */
-+    if (!BN_mod_add_quick(n1, n1, n3, p))
-+        goto end;
-+    if (!BN_mod_add_quick(n2, n2, n4, p))
-+        goto end;
-+    /* 'n7' = n1 + n3 */
-+    /* 'n8' = n2 + n4 */
-+
-+    /* Z_r */
-+    if (a->Z_is_one && b->Z_is_one) {
-+        if (!BN_copy(r->Z, n5))
-+            goto end;
-+    } else {
-+        if (a->Z_is_one) {
-+            if (!BN_copy(n0, b->Z))
-+                goto end;
-+        } else if (b->Z_is_one) {
-+            if (!BN_copy(n0, a->Z))
-+                goto end;
-+        } else {
-+            if (!field_mul(group, n0, a->Z, b->Z, ctx))
-+                goto end;
-+        }
-+        if (!field_mul(group, r->Z, n0, n5, ctx))
-+            goto end;
-+    }
-+    r->Z_is_one = 0;
-+    /* Z_r = Z_a * Z_b * n5 */
-+
-+    /* X_r */
-+    if (!field_sqr(group, n0, n6, ctx))
-+        goto end;
-+    if (!field_sqr(group, n4, n5, ctx))
-+        goto end;
-+    if (!field_mul(group, n3, n1, n4, ctx))
-+        goto end;
-+    if (!BN_mod_sub_quick(r->X, n0, n3, p))
-+        goto end;
-+    /* X_r = n6^2 - n5^2 * 'n7' */
-+
-+    /* 'n9' */
-+    if (!BN_mod_lshift1_quick(n0, r->X, p))
-+        goto end;
-+    if (!BN_mod_sub_quick(n0, n3, n0, p))
-+        goto end;
-+    /* n9 = n5^2 * 'n7' - 2 * X_r */
-+
-+    /* Y_r */
-+    if (!field_mul(group, n0, n0, n6, ctx))
-+        goto end;
-+    if (!field_mul(group, n5, n4, n5, ctx))
-+        goto end;               /* now n5 is n5^3 */
-+    if (!field_mul(group, n1, n2, n5, ctx))
-+        goto end;
-+    if (!BN_mod_sub_quick(n0, n0, n1, p))
-+        goto end;
-+    if (BN_is_odd(n0))
-+        if (!BN_add(n0, n0, p))
-+            goto end;
-+    /* now  0 <= n0 < 2*p,  and n0 is even */
-+    if (!BN_rshift1(r->Y, n0))
-+        goto end;
-+    /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
-+
-+    ret = 1;
-+
-+ end:
-+    if (ctx)                    /* otherwise we already called BN_CTX_end */
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
-+                      BN_CTX *ctx)
-+{
-+    int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
-+                      const BIGNUM *, BN_CTX *);
-+    int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
-+    const BIGNUM *p;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *n0, *n1, *n2, *n3;
-+    int ret = 0;
-+
-+    if (EC_POINT_is_at_infinity(group, a)) {
-+        BN_zero(r->Z);
-+        r->Z_is_one = 0;
-+        return 1;
-+    }
-+
-+    field_mul = group->meth->field_mul;
-+    field_sqr = group->meth->field_sqr;
-+    p = group->field;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return 0;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    n0 = BN_CTX_get(ctx);
-+    n1 = BN_CTX_get(ctx);
-+    n2 = BN_CTX_get(ctx);
-+    n3 = BN_CTX_get(ctx);
-+    if (n3 == NULL)
-+        goto err;
-+
-+    /*
-+     * Note that in this function we must not read components of 'a' once we
-+     * have written the corresponding components of 'r'. ('r' might the same
-+     * as 'a'.)
-+     */
-+
-+    /* n1 */
-+    if (a->Z_is_one) {
-+        if (!field_sqr(group, n0, a->X, ctx))
-+            goto err;
-+        if (!BN_mod_lshift1_quick(n1, n0, p))
-+            goto err;
-+        if (!BN_mod_add_quick(n0, n0, n1, p))
-+            goto err;
-+        if (!BN_mod_add_quick(n1, n0, group->a, p))
-+            goto err;
-+        /* n1 = 3 * X_a^2 + a_curve */
-+    } else if (group->a_is_minus3) {
-+        if (!field_sqr(group, n1, a->Z, ctx))
-+            goto err;
-+        if (!BN_mod_add_quick(n0, a->X, n1, p))
-+            goto err;
-+        if (!BN_mod_sub_quick(n2, a->X, n1, p))
-+            goto err;
-+        if (!field_mul(group, n1, n0, n2, ctx))
-+            goto err;
-+        if (!BN_mod_lshift1_quick(n0, n1, p))
-+            goto err;
-+        if (!BN_mod_add_quick(n1, n0, n1, p))
-+            goto err;
-+        /*-
-+         * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
-+         *    = 3 * X_a^2 - 3 * Z_a^4
-+         */
-+    } else {
-+        if (!field_sqr(group, n0, a->X, ctx))
-+            goto err;
-+        if (!BN_mod_lshift1_quick(n1, n0, p))
-+            goto err;
-+        if (!BN_mod_add_quick(n0, n0, n1, p))
-+            goto err;
-+        if (!field_sqr(group, n1, a->Z, ctx))
-+            goto err;
-+        if (!field_sqr(group, n1, n1, ctx))
-+            goto err;
-+        if (!field_mul(group, n1, n1, group->a, ctx))
-+            goto err;
-+        if (!BN_mod_add_quick(n1, n1, n0, p))
-+            goto err;
-+        /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
-+    }
-+
-+    /* Z_r */
-+    if (a->Z_is_one) {
-+        if (!BN_copy(n0, a->Y))
-+            goto err;
-+    } else {
-+        if (!field_mul(group, n0, a->Y, a->Z, ctx))
-+            goto err;
-+    }
-+    if (!BN_mod_lshift1_quick(r->Z, n0, p))
-+        goto err;
-+    r->Z_is_one = 0;
-+    /* Z_r = 2 * Y_a * Z_a */
-+
-+    /* n2 */
-+    if (!field_sqr(group, n3, a->Y, ctx))
-+        goto err;
-+    if (!field_mul(group, n2, a->X, n3, ctx))
-+        goto err;
-+    if (!BN_mod_lshift_quick(n2, n2, 2, p))
-+        goto err;
-+    /* n2 = 4 * X_a * Y_a^2 */
-+
-+    /* X_r */
-+    if (!BN_mod_lshift1_quick(n0, n2, p))
-+        goto err;
-+    if (!field_sqr(group, r->X, n1, ctx))
-+        goto err;
-+    if (!BN_mod_sub_quick(r->X, r->X, n0, p))
-+        goto err;
-+    /* X_r = n1^2 - 2 * n2 */
-+
-+    /* n3 */
-+    if (!field_sqr(group, n0, n3, ctx))
-+        goto err;
-+    if (!BN_mod_lshift_quick(n3, n0, 3, p))
-+        goto err;
-+    /* n3 = 8 * Y_a^4 */
-+
-+    /* Y_r */
-+    if (!BN_mod_sub_quick(n0, n2, r->X, p))
-+        goto err;
-+    if (!field_mul(group, n0, n1, n0, ctx))
-+        goto err;
-+    if (!BN_mod_sub_quick(r->Y, n0, n3, p))
-+        goto err;
-+    /* Y_r = n1 * (n2 - X_r) - n3 */
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
-+{
-+    if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
-+        /* point is its own inverse */
-+        return 1;
-+
-+    return BN_usub(point->Y, group->field, point->Y);
-+}
-+
-+int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
-+{
-+    return BN_is_zero(point->Z);
-+}
-+
-+int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
-+                              BN_CTX *ctx)
-+{
-+    int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
-+                      const BIGNUM *, BN_CTX *);
-+    int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
-+    const BIGNUM *p;
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *rh, *tmp, *Z4, *Z6;
-+    int ret = -1;
-+
-+    if (EC_POINT_is_at_infinity(group, point))
-+        return 1;
-+
-+    field_mul = group->meth->field_mul;
-+    field_sqr = group->meth->field_sqr;
-+    p = group->field;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return -1;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    rh = BN_CTX_get(ctx);
-+    tmp = BN_CTX_get(ctx);
-+    Z4 = BN_CTX_get(ctx);
-+    Z6 = BN_CTX_get(ctx);
-+    if (Z6 == NULL)
-+        goto err;
-+
-+    /*-
-+     * We have a curve defined by a Weierstrass equation
-+     *      y^2 = x^3 + a*x + b.
-+     * The point to consider is given in Jacobian projective coordinates
-+     * where  (X, Y, Z)  represents  (x, y) = (X/Z^2, Y/Z^3).
-+     * Substituting this and multiplying by  Z^6  transforms the above equation into
-+     *      Y^2 = X^3 + a*X*Z^4 + b*Z^6.
-+     * To test this, we add up the right-hand side in 'rh'.
-+     */
-+
-+    /* rh := X^2 */
-+    if (!field_sqr(group, rh, point->X, ctx))
-+        goto err;
-+
-+    if (!point->Z_is_one) {
-+        if (!field_sqr(group, tmp, point->Z, ctx))
-+            goto err;
-+        if (!field_sqr(group, Z4, tmp, ctx))
-+            goto err;
-+        if (!field_mul(group, Z6, Z4, tmp, ctx))
-+            goto err;
-+
-+        /* rh := (rh + a*Z^4)*X */
-+        if (group->a_is_minus3) {
-+            if (!BN_mod_lshift1_quick(tmp, Z4, p))
-+                goto err;
-+            if (!BN_mod_add_quick(tmp, tmp, Z4, p))
-+                goto err;
-+            if (!BN_mod_sub_quick(rh, rh, tmp, p))
-+                goto err;
-+            if (!field_mul(group, rh, rh, point->X, ctx))
-+                goto err;
-+        } else {
-+            if (!field_mul(group, tmp, Z4, group->a, ctx))
-+                goto err;
-+            if (!BN_mod_add_quick(rh, rh, tmp, p))
-+                goto err;
-+            if (!field_mul(group, rh, rh, point->X, ctx))
-+                goto err;
-+        }
-+
-+        /* rh := rh + b*Z^6 */
-+        if (!field_mul(group, tmp, group->b, Z6, ctx))
-+            goto err;
-+        if (!BN_mod_add_quick(rh, rh, tmp, p))
-+            goto err;
-+    } else {
-+        /* point->Z_is_one */
-+
-+        /* rh := (rh + a)*X */
-+        if (!BN_mod_add_quick(rh, rh, group->a, p))
-+            goto err;
-+        if (!field_mul(group, rh, rh, point->X, ctx))
-+            goto err;
-+        /* rh := rh + b */
-+        if (!BN_mod_add_quick(rh, rh, group->b, p))
-+            goto err;
-+    }
-+
-+    /* 'lh' := Y^2 */
-+    if (!field_sqr(group, tmp, point->Y, ctx))
-+        goto err;
-+
-+    ret = (0 == BN_ucmp(tmp, rh));
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
-+                      const EC_POINT *b, BN_CTX *ctx)
-+{
-+    /*-
-+     * return values:
-+     *  -1   error
-+     *   0   equal (in affine coordinates)
-+     *   1   not equal
-+     */
-+
-+    int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
-+                      const BIGNUM *, BN_CTX *);
-+    int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
-+    const BIGNUM *tmp1_, *tmp2_;
-+    int ret = -1;
-+
-+    if (EC_POINT_is_at_infinity(group, a)) {
-+        return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
-+    }
-+
-+    if (EC_POINT_is_at_infinity(group, b))
-+        return 1;
-+
-+    if (a->Z_is_one && b->Z_is_one) {
-+        return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1;
-+    }
-+
-+    field_mul = group->meth->field_mul;
-+    field_sqr = group->meth->field_sqr;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return -1;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    tmp1 = BN_CTX_get(ctx);
-+    tmp2 = BN_CTX_get(ctx);
-+    Za23 = BN_CTX_get(ctx);
-+    Zb23 = BN_CTX_get(ctx);
-+    if (Zb23 == NULL)
-+        goto end;
-+
-+    /*-
-+     * We have to decide whether
-+     *     (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
-+     * or equivalently, whether
-+     *     (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
-+     */
-+
-+    if (!b->Z_is_one) {
-+        if (!field_sqr(group, Zb23, b->Z, ctx))
-+            goto end;
-+        if (!field_mul(group, tmp1, a->X, Zb23, ctx))
-+            goto end;
-+        tmp1_ = tmp1;
-+    } else
-+        tmp1_ = a->X;
-+    if (!a->Z_is_one) {
-+        if (!field_sqr(group, Za23, a->Z, ctx))
-+            goto end;
-+        if (!field_mul(group, tmp2, b->X, Za23, ctx))
-+            goto end;
-+        tmp2_ = tmp2;
-+    } else
-+        tmp2_ = b->X;
-+
-+    /* compare  X_a*Z_b^2  with  X_b*Z_a^2 */
-+    if (BN_cmp(tmp1_, tmp2_) != 0) {
-+        ret = 1;                /* points differ */
-+        goto end;
-+    }
-+
-+    if (!b->Z_is_one) {
-+        if (!field_mul(group, Zb23, Zb23, b->Z, ctx))
-+            goto end;
-+        if (!field_mul(group, tmp1, a->Y, Zb23, ctx))
-+            goto end;
-+        /* tmp1_ = tmp1 */
-+    } else
-+        tmp1_ = a->Y;
-+    if (!a->Z_is_one) {
-+        if (!field_mul(group, Za23, Za23, a->Z, ctx))
-+            goto end;
-+        if (!field_mul(group, tmp2, b->Y, Za23, ctx))
-+            goto end;
-+        /* tmp2_ = tmp2 */
-+    } else
-+        tmp2_ = b->Y;
-+
-+    /* compare  Y_a*Z_b^3  with  Y_b*Z_a^3 */
-+    if (BN_cmp(tmp1_, tmp2_) != 0) {
-+        ret = 1;                /* points differ */
-+        goto end;
-+    }
-+
-+    /* points are equal */
-+    ret = 0;
-+
-+ end:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
-+                              BN_CTX *ctx)
-+{
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *x, *y;
-+    int ret = 0;
-+
-+    if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
-+        return 1;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return 0;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    x = BN_CTX_get(ctx);
-+    y = BN_CTX_get(ctx);
-+    if (y == NULL)
-+        goto err;
-+
-+    if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
-+        goto err;
-+    if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
-+        goto err;
-+    if (!point->Z_is_one) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
-+        goto err;
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    return ret;
-+}
-+
-+int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
-+                                     EC_POINT *points[], BN_CTX *ctx)
-+{
-+    BN_CTX *new_ctx = NULL;
-+    BIGNUM *tmp, *tmp_Z;
-+    BIGNUM **prod_Z = NULL;
-+    size_t i;
-+    int ret = 0;
-+
-+    if (num == 0)
-+        return 1;
-+
-+    if (ctx == NULL) {
-+        ctx = new_ctx = BN_CTX_new();
-+        if (ctx == NULL)
-+            return 0;
-+    }
-+
-+    BN_CTX_start(ctx);
-+    tmp = BN_CTX_get(ctx);
-+    tmp_Z = BN_CTX_get(ctx);
-+    if (tmp == NULL || tmp_Z == NULL)
-+        goto err;
-+
-+    prod_Z = OPENSSL_malloc(num * sizeof prod_Z[0]);
-+    if (prod_Z == NULL)
-+        goto err;
-+    for (i = 0; i < num; i++) {
-+        prod_Z[i] = BN_new();
-+        if (prod_Z[i] == NULL)
-+            goto err;
-+    }
-+
-+    /*
-+     * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z,
-+     * skipping any zero-valued inputs (pretend that they're 1).
-+     */
-+
-+    if (!BN_is_zero(points[0]->Z)) {
-+        if (!BN_copy(prod_Z[0], points[0]->Z))
-+            goto err;
-+    } else {
-+        if (group->meth->field_set_to_one != 0) {
-+            if (!group->meth->field_set_to_one(group, prod_Z[0], ctx))
-+                goto err;
-+        } else {
-+            if (!BN_one(prod_Z[0]))
-+                goto err;
-+        }
-+    }
-+
-+    for (i = 1; i < num; i++) {
-+        if (!BN_is_zero(points[i]->Z)) {
-+            if (!group->
-+                meth->field_mul(group, prod_Z[i], prod_Z[i - 1], points[i]->Z,
-+                                ctx))
-+                goto err;
-+        } else {
-+            if (!BN_copy(prod_Z[i], prod_Z[i - 1]))
-+                goto err;
-+        }
-+    }
-+
-+    /*
-+     * Now use a single explicit inversion to replace every non-zero
-+     * points[i]->Z by its inverse.
-+     */
-+
-+    if (!BN_mod_inverse(tmp, prod_Z[num - 1], group->field, ctx)) {
-+        ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+    if (group->meth->field_encode != 0) {
-+        /*
-+         * In the Montgomery case, we just turned R*H (representing H) into
-+         * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to
-+         * multiply by the Montgomery factor twice.
-+         */
-+        if (!group->meth->field_encode(group, tmp, tmp, ctx))
-+            goto err;
-+        if (!group->meth->field_encode(group, tmp, tmp, ctx))
-+            goto err;
-+    }
-+
-+    for (i = num - 1; i > 0; --i) {
-+        /*
-+         * Loop invariant: tmp is the product of the inverses of points[0]->Z
-+         * .. points[i]->Z (zero-valued inputs skipped).
-+         */
-+        if (!BN_is_zero(points[i]->Z)) {
-+            /*
-+             * Set tmp_Z to the inverse of points[i]->Z (as product of Z
-+             * inverses 0 .. i, Z values 0 .. i - 1).
-+             */
-+            if (!group->
-+                meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
-+                goto err;
-+            /*
-+             * Update tmp to satisfy the loop invariant for i - 1.
-+             */
-+            if (!group->meth->field_mul(group, tmp, tmp, points[i]->Z, ctx))
-+                goto err;
-+            /* Replace points[i]->Z by its inverse. */
-+            if (!BN_copy(points[i]->Z, tmp_Z))
-+                goto err;
-+        }
-+    }
-+
-+    if (!BN_is_zero(points[0]->Z)) {
-+        /* Replace points[0]->Z by its inverse. */
-+        if (!BN_copy(points[0]->Z, tmp))
-+            goto err;
-+    }
-+
-+    /* Finally, fix up the X and Y coordinates for all points. */
-+
-+    for (i = 0; i < num; i++) {
-+        EC_POINT *p = points[i];
-+
-+        if (!BN_is_zero(p->Z)) {
-+            /* turn  (X, Y, 1/Z)  into  (X/Z^2, Y/Z^3, 1) */
-+
-+            if (!group->meth->field_sqr(group, tmp, p->Z, ctx))
-+                goto err;
-+            if (!group->meth->field_mul(group, p->X, p->X, tmp, ctx))
-+                goto err;
-+
-+            if (!group->meth->field_mul(group, tmp, tmp, p->Z, ctx))
-+                goto err;
-+            if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx))
-+                goto err;
-+
-+            if (group->meth->field_set_to_one != 0) {
-+                if (!group->meth->field_set_to_one(group, p->Z, ctx))
-+                    goto err;
-+            } else {
-+                if (!BN_one(p->Z))
-+                    goto err;
-+            }
-+            p->Z_is_one = 1;
-+        }
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    BN_CTX_free(new_ctx);
-+    if (prod_Z != NULL) {
-+        for (i = 0; i < num; i++) {
-+            if (prod_Z[i] == NULL)
-+                break;
-+            BN_clear_free(prod_Z[i]);
-+        }
-+        OPENSSL_free(prod_Z);
-+    }
-+    return ret;
-+}
-+
-+int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
-+                            const BIGNUM *b, BN_CTX *ctx)
-+{
-+    return BN_mod_mul(r, a, b, group->field, ctx);
-+}
-+
-+int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
-+                            BN_CTX *ctx)
-+{
-+    return BN_mod_sqr(r, a, group->field, ctx);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecx_meth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecx_meth.c
-new file mode 100644
-index 0000000..06e3911
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ec/ecx_meth.c
-@@ -0,0 +1,373 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+#include "ec_lcl.h"
-+
-+#define X25519_KEYLEN        32
-+#define X25519_BITS          253
-+#define X25519_SECURITY_BITS 128
-+
-+typedef struct {
-+    unsigned char pubkey[X25519_KEYLEN];
-+    unsigned char *privkey;
-+} X25519_KEY;
-+
-+typedef enum {
-+    X25519_PUBLIC,
-+    X25519_PRIVATE,
-+    X25519_KEYGEN
-+} ecx_key_op_t;
-+
-+/* Setup EVP_PKEY using public, private or generation */
-+static int ecx_key_op(EVP_PKEY *pkey, const X509_ALGOR *palg,
-+                      const unsigned char *p, int plen, ecx_key_op_t op)
-+{
-+    X25519_KEY *xkey;
-+
-+    if (op != X25519_KEYGEN) {
-+        if (palg != NULL) {
-+            int ptype;
-+
-+            /* Algorithm parameters must be absent */
-+            X509_ALGOR_get0(NULL, &ptype, NULL, palg);
-+            if (ptype != V_ASN1_UNDEF) {
-+                ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
-+                return 0;
-+            }
-+        }
-+
-+        if (p == NULL || plen != X25519_KEYLEN) {
-+            ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
-+            return 0;
-+        }
-+    }
-+
-+    xkey = OPENSSL_zalloc(sizeof(*xkey));
-+    if (xkey == NULL) {
-+        ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    if (op == X25519_PUBLIC) {
-+        memcpy(xkey->pubkey, p, plen);
-+    } else {
-+        xkey->privkey = OPENSSL_secure_malloc(X25519_KEYLEN);
-+        if (xkey->privkey == NULL) {
-+            ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
-+            OPENSSL_free(xkey);
-+            return 0;
-+        }
-+        if (op == X25519_KEYGEN) {
-+            if (RAND_bytes(xkey->privkey, X25519_KEYLEN) <= 0) {
-+                OPENSSL_secure_free(xkey->privkey);
-+                OPENSSL_free(xkey);
-+                return 0;
-+            }
-+            xkey->privkey[0] &= 248;
-+            xkey->privkey[31] &= 127;
-+            xkey->privkey[31] |= 64;
-+        } else {
-+            memcpy(xkey->privkey, p, X25519_KEYLEN);
-+        }
-+        X25519_public_from_private(xkey->pubkey, xkey->privkey);
-+    }
-+
-+    EVP_PKEY_assign(pkey, NID_X25519, xkey);
-+    return 1;
-+}
-+
-+static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
-+{
-+    const X25519_KEY *xkey = pkey->pkey.ptr;
-+    unsigned char *penc;
-+
-+    if (xkey == NULL) {
-+        ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
-+        return 0;
-+    }
-+
-+    penc = OPENSSL_memdup(xkey->pubkey, X25519_KEYLEN);
-+    if (penc == NULL) {
-+        ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(NID_X25519), V_ASN1_UNDEF,
-+                                NULL, penc, X25519_KEYLEN)) {
-+        OPENSSL_free(penc);
-+        ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
-+{
-+    const unsigned char *p;
-+    int pklen;
-+    X509_ALGOR *palg;
-+
-+    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
-+        return 0;
-+    return ecx_key_op(pkey, palg, p, pklen, X25519_PUBLIC);
-+}
-+
-+static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    const X25519_KEY *akey = a->pkey.ptr;
-+    const X25519_KEY *bkey = b->pkey.ptr;
-+
-+    if (akey == NULL || bkey == NULL)
-+        return -2;
-+    return !CRYPTO_memcmp(akey->pubkey, bkey->pubkey, X25519_KEYLEN);
-+}
-+
-+static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
-+{
-+    const unsigned char *p;
-+    int plen;
-+    ASN1_OCTET_STRING *oct = NULL;
-+    const X509_ALGOR *palg;
-+    int rv;
-+
-+    if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
-+        return 0;
-+
-+    oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
-+    if (oct == NULL) {
-+        p = NULL;
-+        plen = 0;
-+    } else {
-+        p = ASN1_STRING_get0_data(oct);
-+        plen = ASN1_STRING_length(oct);
-+    }
-+
-+    rv = ecx_key_op(pkey, palg, p, plen, X25519_PRIVATE);
-+    ASN1_OCTET_STRING_free(oct);
-+    return rv;
-+}
-+
-+static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
-+{
-+    const X25519_KEY *xkey = pkey->pkey.ptr;
-+    ASN1_OCTET_STRING oct;
-+    unsigned char *penc = NULL;
-+    int penclen;
-+
-+    if (xkey == NULL || xkey->privkey == NULL) {
-+        ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
-+        return 0;
-+    }
-+
-+    oct.data = xkey->privkey;
-+    oct.length = X25519_KEYLEN;
-+    oct.flags = 0;
-+
-+    penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
-+    if (penclen < 0) {
-+        ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X25519), 0,
-+                         V_ASN1_UNDEF, NULL, penc, penclen)) {
-+        OPENSSL_clear_free(penc, penclen);
-+        ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+static int ecx_size(const EVP_PKEY *pkey)
-+{
-+    return X25519_KEYLEN;
-+}
-+
-+static int ecx_bits(const EVP_PKEY *pkey)
-+{
-+    return X25519_BITS;
-+}
-+
-+static int ecx_security_bits(const EVP_PKEY *pkey)
-+{
-+    return X25519_SECURITY_BITS;
-+}
-+
-+static void ecx_free(EVP_PKEY *pkey)
-+{
-+    X25519_KEY *xkey = pkey->pkey.ptr;
-+
-+    if (xkey)
-+        OPENSSL_secure_free(xkey->privkey);
-+    OPENSSL_free(xkey);
-+}
-+
-+/* "parameters" are always equal */
-+static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    return 1;
-+}
-+
-+static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                         ASN1_PCTX *ctx, ecx_key_op_t op)
-+{
-+    const X25519_KEY *xkey = pkey->pkey.ptr;
-+
-+    if (op == X25519_PRIVATE) {
-+        if (xkey == NULL || xkey->privkey == NULL) {
-+            if (BIO_printf(bp, "%*s\n", indent, "") <= 0)
-+                return 0;
-+            return 1;
-+        }
-+        if (BIO_printf(bp, "%*sX25519 Private-Key:\n", indent, "") <= 0)
-+            return 0;
-+        if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
-+            return 0;
-+        if (ASN1_buf_print(bp, xkey->privkey, X25519_KEYLEN, indent + 4) == 0)
-+            return 0;
-+    } else {
-+        if (xkey == NULL) {
-+            if (BIO_printf(bp, "%*s\n", indent, "") <= 0)
-+                return 0;
-+            return 1;
-+        }
-+        if (BIO_printf(bp, "%*sX25519 Public-Key:\n", indent, "") <= 0)
-+            return 0;
-+    }
-+    if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
-+        return 0;
-+    if (ASN1_buf_print(bp, xkey->pubkey, X25519_KEYLEN, indent + 4) == 0)
-+        return 0;
-+    return 1;
-+}
-+
-+static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                          ASN1_PCTX *ctx)
-+{
-+    return ecx_key_print(bp, pkey, indent, ctx, X25519_PRIVATE);
-+}
-+
-+static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                         ASN1_PCTX *ctx)
-+{
-+    return ecx_key_print(bp, pkey, indent, ctx, X25519_PUBLIC);
-+}
-+
-+static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
-+{
-+    switch (op) {
-+
-+    case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
-+        return ecx_key_op(pkey, NULL, arg2, arg1, X25519_PUBLIC);
-+
-+    case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
-+        if (pkey->pkey.ptr != NULL) {
-+            const X25519_KEY *xkey = pkey->pkey.ptr;
-+            unsigned char **ppt = arg2;
-+            *ppt = OPENSSL_memdup(xkey->pubkey, X25519_KEYLEN);
-+            if (*ppt != NULL)
-+                return X25519_KEYLEN;
-+        }
-+        return 0;
-+
-+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
-+        *(int *)arg2 = NID_sha256;
-+        return 2;
-+
-+    default:
-+        return -2;
-+
-+    }
-+}
-+
-+const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
-+    NID_X25519,
-+    NID_X25519,
-+    0,
-+    "X25519",
-+    "OpenSSL X25519 algorithm",
-+
-+    ecx_pub_decode,
-+    ecx_pub_encode,
-+    ecx_pub_cmp,
-+    ecx_pub_print,
-+
-+    ecx_priv_decode,
-+    ecx_priv_encode,
-+    ecx_priv_print,
-+
-+    ecx_size,
-+    ecx_bits,
-+    ecx_security_bits,
-+
-+    0, 0, 0, 0,
-+    ecx_cmp_parameters,
-+    0, 0,
-+
-+    ecx_free,
-+    ecx_ctrl,
-+    NULL,
-+    NULL
-+};
-+
-+static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    return ecx_key_op(pkey, NULL, NULL, 0, X25519_KEYGEN);
-+}
-+
-+static int pkey_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
-+                           size_t *keylen)
-+{
-+    const X25519_KEY *pkey, *peerkey;
-+
-+    if (ctx->pkey == NULL || ctx->peerkey == NULL) {
-+        ECerr(EC_F_PKEY_ECX_DERIVE, EC_R_KEYS_NOT_SET);
-+        return 0;
-+    }
-+    pkey = ctx->pkey->pkey.ptr;
-+    peerkey = ctx->peerkey->pkey.ptr;
-+    if (pkey == NULL || pkey->privkey == NULL) {
-+        ECerr(EC_F_PKEY_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
-+        return 0;
-+    }
-+    if (peerkey == NULL) {
-+        ECerr(EC_F_PKEY_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
-+        return 0;
-+    }
-+    *keylen = X25519_KEYLEN;
-+    if (key != NULL && X25519(key, pkey->privkey, peerkey->pubkey) == 0)
-+        return 0;
-+    return 1;
-+}
-+
-+static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-+{
-+    /* Only need to handle peer key for derivation */
-+    if (type == EVP_PKEY_CTRL_PEER_KEY)
-+        return 1;
-+    return -2;
-+}
-+
-+const EVP_PKEY_METHOD ecx25519_pkey_meth = {
-+    NID_X25519,
-+    0, 0, 0, 0, 0, 0, 0,
-+    pkey_ecx_keygen,
-+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+    pkey_ecx_derive,
-+    pkey_ecx_ctrl,
-+    0
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/README b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/README
-new file mode 100644
-index 0000000..41baa18
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/README
-@@ -0,0 +1,211 @@
-+Notes: 2001-09-24
-+-----------------
-+
-+This "description" (if one chooses to call it that) needed some major updating
-+so here goes. This update addresses a change being made at the same time to
-+OpenSSL, and it pretty much completely restructures the underlying mechanics of
-+the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals
-+for masochists" document *and* a rather extensive commit log message. (I'd get
-+lynched for sticking all this in CHANGES or the commit mails :-).
-+
-+ENGINE_TABLE underlies this restructuring, as described in the internal header
-+"eng_int.h", implemented in eng_table.c, and used in each of the "class" files;
-+tb_rsa.c, tb_dsa.c, etc.
-+
-+However, "EVP_CIPHER" underlies the motivation and design of ENGINE_TABLE so
-+I'll mention a bit about that first. EVP_CIPHER (and most of this applies
-+equally to EVP_MD for digests) is both a "method" and a algorithm/mode
-+identifier that, in the current API, "lingers". These cipher description +
-+implementation structures can be defined or obtained directly by applications,
-+or can be loaded "en masse" into EVP storage so that they can be catalogued and
-+searched in various ways, ie. two ways of encrypting with the "des_cbc"
-+algorithm/mode pair are;
-+
-+(i) directly;
-+     const EVP_CIPHER *cipher = EVP_des_cbc();
-+     EVP_EncryptInit(&ctx, cipher, key, iv);
-+     [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...]
-+
-+(ii) indirectly; 
-+     OpenSSL_add_all_ciphers();
-+     cipher = EVP_get_cipherbyname("des_cbc");
-+     EVP_EncryptInit(&ctx, cipher, key, iv);
-+     [ ... etc ... ]
-+
-+The latter is more generally used because it also allows ciphers/digests to be
-+looked up based on other identifiers which can be useful for automatic cipher
-+selection, eg. in SSL/TLS, or by user-controllable configuration.
-+
-+The important point about this is that EVP_CIPHER definitions and structures are
-+passed around with impunity and there is no safe way, without requiring massive
-+rewrites of many applications, to assume that EVP_CIPHERs can be reference
-+counted. One an EVP_CIPHER is exposed to the caller, neither it nor anything it
-+comes from can "safely" be destroyed. Unless of course the way of getting to
-+such ciphers is via entirely distinct API calls that didn't exist before.
-+However existing API usage cannot be made to understand when an EVP_CIPHER
-+pointer, that has been passed to the caller, is no longer being used.
-+
-+The other problem with the existing API w.r.t. to hooking EVP_CIPHER support
-+into ENGINE is storage - the OBJ_NAME-based storage used by EVP to register
-+ciphers simultaneously registers cipher *types* and cipher *implementations* -
-+they are effectively the same thing, an "EVP_CIPHER" pointer. The problem with
-+hooking in ENGINEs is that multiple ENGINEs may implement the same ciphers. The
-+solution is necessarily that ENGINE-provided ciphers simply are not registered,
-+stored, or exposed to the caller in the same manner as existing ciphers. This is
-+especially necessary considering the fact ENGINE uses reference counts to allow
-+for cleanup, modularity, and DSO support - yet EVP_CIPHERs, as exposed to
-+callers in the current API, support no such controls.
-+
-+Another sticking point for integrating cipher support into ENGINE is linkage.
-+Already there is a problem with the way ENGINE supports RSA, DSA, etc whereby
-+they are available *because* they're part of a giant ENGINE called "openssl".
-+Ie. all implementations *have* to come from an ENGINE, but we get round that by
-+having a giant ENGINE with all the software support encapsulated. This creates
-+linker hassles if nothing else - linking a 1-line application that calls 2 basic
-+RSA functions (eg. "RSA_free(RSA_new());") will result in large quantities of
-+ENGINE code being linked in *and* because of that DSA, DH, and RAND also. If we
-+continue with this approach for EVP_CIPHER support (even if it *was* possible)
-+we would lose our ability to link selectively by selectively loading certain
-+implementations of certain functionality. Touching any part of any kind of
-+crypto would result in massive static linkage of everything else. So the
-+solution is to change the way ENGINE feeds existing "classes", ie. how the
-+hooking to ENGINE works from RSA, DSA, DH, RAND, as well as adding new hooking
-+for EVP_CIPHER, and EVP_MD.
-+
-+The way this is now being done is by mostly reverting back to how things used to
-+work prior to ENGINE :-). Ie. RSA now has a "RSA_METHOD" pointer again - this
-+was previously replaced by an "ENGINE" pointer and all RSA code that required
-+the RSA_METHOD would call ENGINE_get_RSA() each time on its ENGINE handle to
-+temporarily get and use the ENGINE's RSA implementation. Apart from being more
-+efficient, switching back to each RSA having an RSA_METHOD pointer also allows
-+us to conceivably operate with *no* ENGINE. As we'll see, this removes any need
-+for a fallback ENGINE that encapsulates default implementations - we can simply
-+have our RSA structure pointing its RSA_METHOD pointer to the software
-+implementation and have its ENGINE pointer set to NULL.
-+
-+A look at the EVP_CIPHER hooking is most explanatory, the RSA, DSA (etc) cases
-+turn out to be degenerate forms of the same thing. The EVP storage of ciphers,
-+and the existing EVP API functions that return "software" implementations and
-+descriptions remain untouched. However, the storage takes more meaning in terms
-+of "cipher description" and less meaning in terms of "implementation". When an
-+EVP_CIPHER_CTX is actually initialised with an EVP_CIPHER method and is about to
-+begin en/decryption, the hooking to ENGINE comes into play. What happens is that
-+cipher-specific ENGINE code is asked for an ENGINE pointer (a functional
-+reference) for any ENGINE that is registered to perform the algo/mode that the
-+provided EVP_CIPHER structure represents. Under normal circumstances, that
-+ENGINE code will return NULL because no ENGINEs will have had any cipher
-+implementations *registered*. As such, a NULL ENGINE pointer is stored in the
-+EVP_CIPHER_CTX context, and the EVP_CIPHER structure is left hooked into the
-+context and so is used as the implementation. Pretty much how things work now
-+except we'd have a redundant ENGINE pointer set to NULL and doing nothing.
-+
-+Conversely, if an ENGINE *has* been registered to perform the algorithm/mode
-+combination represented by the provided EVP_CIPHER, then a functional reference
-+to that ENGINE will be returned to the EVP_CIPHER_CTX during initialisation.
-+That functional reference will be stored in the context (and released on
-+cleanup) - and having that reference provides a *safe* way to use an EVP_CIPHER
-+definition that is private to the ENGINE. Ie. the EVP_CIPHER provided by the
-+application will actually be replaced by an EVP_CIPHER from the registered
-+ENGINE - it will support the same algorithm/mode as the original but will be a
-+completely different implementation. Because this EVP_CIPHER isn't stored in the
-+EVP storage, nor is it returned to applications from traditional API functions,
-+there is no associated problem with it not having reference counts. And of
-+course, when one of these "private" cipher implementations is hooked into
-+EVP_CIPHER_CTX, it is done whilst the EVP_CIPHER_CTX holds a functional
-+reference to the ENGINE that owns it, thus the use of the ENGINE's EVP_CIPHER is
-+safe.
-+
-+The "cipher-specific ENGINE code" I mentioned is implemented in tb_cipher.c but
-+in essence it is simply an instantiation of "ENGINE_TABLE" code for use by
-+EVP_CIPHER code. tb_digest.c is virtually identical but, of course, it is for
-+use by EVP_MD code. Ditto for tb_rsa.c, tb_dsa.c, etc. These instantiations of
-+ENGINE_TABLE essentially provide linker-separation of the classes so that even
-+if ENGINEs implement *all* possible algorithms, an application using only
-+EVP_CIPHER code will link at most code relating to EVP_CIPHER, tb_cipher.c, core
-+ENGINE code that is independent of class, and of course the ENGINE
-+implementation that the application loaded. It will *not* however link any
-+class-specific ENGINE code for digests, RSA, etc nor will it bleed over into
-+other APIs, such as the RSA/DSA/etc library code.
-+
-+ENGINE_TABLE is a little more complicated than may seem necessary but this is
-+mostly to avoid a lot of "init()"-thrashing on ENGINEs (that may have to load
-+DSOs, and other expensive setup that shouldn't be thrashed unnecessarily) *and*
-+to duplicate "default" behaviour. Basically an ENGINE_TABLE instantiation, for
-+example tb_cipher.c, implements a hash-table keyed by integer "nid" values.
-+These nids provide the uniquenness of an algorithm/mode - and each nid will hash
-+to a potentially NULL "ENGINE_PILE". An ENGINE_PILE is essentially a list of
-+pointers to ENGINEs that implement that particular 'nid'. Each "pile" uses some
-+caching tricks such that requests on that 'nid' will be cached and all future
-+requests will return immediately (well, at least with minimal operation) unless
-+a change is made to the pile, eg. perhaps an ENGINE was unloaded. The reason is
-+that an application could have support for 10 ENGINEs statically linked
-+in, and the machine in question may not have any of the hardware those 10
-+ENGINEs support. If each of those ENGINEs has a "des_cbc" implementation, we
-+want to avoid every EVP_CIPHER_CTX setup from trying (and failing) to initialise
-+each of those 10 ENGINEs. Instead, the first such request will try to do that
-+and will either return (and cache) a NULL ENGINE pointer or will return a
-+functional reference to the first that successfully initialised. In the latter
-+case it will also cache an extra functional reference to the ENGINE as a
-+"default" for that 'nid'. The caching is acknowledged by a 'uptodate' variable
-+that is unset only if un/registration takes place on that pile. Ie. if
-+implementations of "des_cbc" are added or removed. This behaviour can be
-+tweaked; the ENGINE_TABLE_FLAG_NOINIT value can be passed to
-+ENGINE_set_table_flags(), in which case the only ENGINEs that tb_cipher.c will
-+try to initialise from the "pile" will be those that are already initialised
-+(ie. it's simply an increment of the functional reference count, and no real
-+"initialisation" will take place).
-+
-+RSA, DSA, DH, and RAND all have their own ENGINE_TABLE code as well, and the
-+difference is that they all use an implicit 'nid' of 1. Whereas EVP_CIPHERs are
-+actually qualitatively different depending on 'nid' (the "des_cbc" EVP_CIPHER is
-+not an interoperable implementation of "aes_256_cbc"), RSA_METHODs are
-+necessarily interoperable and don't have different flavours, only different
-+implementations. In other words, the ENGINE_TABLE for RSA will either be empty,
-+or will have a single ENGING_PILE hashed to by the 'nid' 1 and that pile
-+represents ENGINEs that implement the single "type" of RSA there is.
-+
-+Cleanup - the registration and unregistration may pose questions about how
-+cleanup works with the ENGINE_PILE doing all this caching nonsense (ie. when the
-+application or EVP_CIPHER code releases its last reference to an ENGINE, the
-+ENGINE_PILE code may still have references and thus those ENGINEs will stay
-+hooked in forever). The way this is handled is via "unregistration". With these
-+new ENGINE changes, an abstract ENGINE can be loaded and initialised, but that
-+is an algorithm-agnostic process. Even if initialised, it will not have
-+registered any of its implementations (to do so would link all class "table"
-+code despite the fact the application may use only ciphers, for example). This
-+is deliberately a distinct step. Moreover, registration and unregistration has
-+nothing to do with whether an ENGINE is *functional* or not (ie. you can even
-+register an ENGINE and its implementations without it being operational, you may
-+not even have the drivers to make it operate). What actually happens with
-+respect to cleanup is managed inside eng_lib.c with the "engine_cleanup_***"
-+functions. These functions are internal-only and each part of ENGINE code that
-+could require cleanup will, upon performing its first allocation, register a
-+callback with the "engine_cleanup" code. The other part of this that makes it
-+tick is that the ENGINE_TABLE instantiations (tb_***.c) use NULL as their
-+initialised state. So if RSA code asks for an ENGINE and no ENGINE has
-+registered an implementation, the code will simply return NULL and the tb_rsa.c
-+state will be unchanged. Thus, no cleanup is required unless registration takes
-+place. ENGINE_cleanup() will simply iterate across a list of registered cleanup
-+callbacks calling each in turn, and will then internally delete its own storage
-+(a STACK). When a cleanup callback is next registered (eg. if the cleanup() is
-+part of a gracefull restart and the application wants to cleanup all state then
-+start again), the internal STACK storage will be freshly allocated. This is much
-+the same as the situation in the ENGINE_TABLE instantiations ... NULL is the
-+initialised state, so only modification operations (not queries) will cause that
-+code to have to register a cleanup.
-+
-+What else? The bignum callbacks and associated ENGINE functions have been
-+removed for two obvious reasons; (i) there was no way to generalise them to the
-+mechanism now used by RSA/DSA/..., because there's no such thing as a BIGNUM
-+method, and (ii) because of (i), there was no meaningful way for library or
-+application code to automatically hook and use ENGINE supplied bignum functions
-+anyway. Also, ENGINE_cpy() has been removed (although an internal-only version
-+exists) - the idea of providing an ENGINE_cpy() function probably wasn't a good
-+one and now certainly doesn't make sense in any generalised way. Some of the
-+RSA, DSA, DH, and RAND functions that were fiddled during the original ENGINE
-+changes have now, as a consequence, been reverted back. This is because the
-+hooking of ENGINE is now automatic (and passive, it can interally use a NULL
-+ENGINE pointer to simply ignore ENGINE from then on).
-+
-+Hell, that should be enough for now ... comments welcome: geoff@openssl.org
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/build.info
-new file mode 100644
-index 0000000..161dad4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/build.info
-@@ -0,0 +1,8 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
-+        eng_table.c eng_pkey.c eng_fat.c eng_all.c \
-+        tb_rsa.c tb_dsa.c tb_dh.c tb_rand.c \
-+        tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c \
-+        eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c \
-+        eng_rdrand.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_all.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_all.c
-new file mode 100644
-index 0000000..ebe0277
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_all.c
-@@ -0,0 +1,31 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "eng_int.h"
-+
-+void ENGINE_load_builtin_engines(void)
-+{
-+    /* Some ENGINEs need this */
-+    OPENSSL_cpuid_setup();
-+
-+    OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL);
-+}
-+
-+#if (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)) && !defined(OPENSSL_NO_DEPRECATED)
-+void ENGINE_setup_bsd_cryptodev(void)
-+{
-+    static int bsd_cryptodev_default_loaded = 0;
-+    if (!bsd_cryptodev_default_loaded) {
-+        OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CRYPTODEV, NULL);
-+        ENGINE_register_all_complete();
-+    }
-+    bsd_cryptodev_default_loaded = 1;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_cnf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_cnf.c
-new file mode 100644
-index 0000000..6f0a066
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_cnf.c
-@@ -0,0 +1,192 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+#include 
-+
-+/* #define ENGINE_CONF_DEBUG */
-+
-+/* ENGINE config module */
-+
-+static const char *skip_dot(const char *name)
-+{
-+    const char *p = strchr(name, '.');
-+
-+    if (p != NULL)
-+        return p + 1;
-+    return name;
-+}
-+
-+static STACK_OF(ENGINE) *initialized_engines = NULL;
-+
-+static int int_engine_init(ENGINE *e)
-+{
-+    if (!ENGINE_init(e))
-+        return 0;
-+    if (!initialized_engines)
-+        initialized_engines = sk_ENGINE_new_null();
-+    if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) {
-+        ENGINE_finish(e);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+static int int_engine_configure(const char *name, const char *value, const CONF *cnf)
-+{
-+    int i;
-+    int ret = 0;
-+    long do_init = -1;
-+    STACK_OF(CONF_VALUE) *ecmds;
-+    CONF_VALUE *ecmd = NULL;
-+    const char *ctrlname, *ctrlvalue;
-+    ENGINE *e = NULL;
-+    int soft = 0;
-+
-+    name = skip_dot(name);
-+#ifdef ENGINE_CONF_DEBUG
-+    fprintf(stderr, "Configuring engine %s\n", name);
-+#endif
-+    /* Value is a section containing ENGINE commands */
-+    ecmds = NCONF_get_section(cnf, value);
-+
-+    if (!ecmds) {
-+        ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
-+                  ENGINE_R_ENGINE_SECTION_ERROR);
-+        return 0;
-+    }
-+
-+    for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) {
-+        ecmd = sk_CONF_VALUE_value(ecmds, i);
-+        ctrlname = skip_dot(ecmd->name);
-+        ctrlvalue = ecmd->value;
-+#ifdef ENGINE_CONF_DEBUG
-+        fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname,
-+                ctrlvalue);
-+#endif
-+
-+        /* First handle some special pseudo ctrls */
-+
-+        /* Override engine name to use */
-+        if (strcmp(ctrlname, "engine_id") == 0)
-+            name = ctrlvalue;
-+        else if (strcmp(ctrlname, "soft_load") == 0)
-+            soft = 1;
-+        /* Load a dynamic ENGINE */
-+        else if (strcmp(ctrlname, "dynamic_path") == 0) {
-+            e = ENGINE_by_id("dynamic");
-+            if (!e)
-+                goto err;
-+            if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
-+                goto err;
-+            if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
-+                goto err;
-+            if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
-+                goto err;
-+        }
-+        /* ... add other pseudos here ... */
-+        else {
-+            /*
-+             * At this point we need an ENGINE structural reference if we
-+             * don't already have one.
-+             */
-+            if (!e) {
-+                e = ENGINE_by_id(name);
-+                if (!e && soft) {
-+                    ERR_clear_error();
-+                    return 1;
-+                }
-+                if (!e)
-+                    goto err;
-+            }
-+            /*
-+             * Allow "EMPTY" to mean no value: this allows a valid "value" to
-+             * be passed to ctrls of type NO_INPUT
-+             */
-+            if (strcmp(ctrlvalue, "EMPTY") == 0)
-+                ctrlvalue = NULL;
-+            if (strcmp(ctrlname, "init") == 0) {
-+                if (!NCONF_get_number_e(cnf, value, "init", &do_init))
-+                    goto err;
-+                if (do_init == 1) {
-+                    if (!int_engine_init(e))
-+                        goto err;
-+                } else if (do_init != 0) {
-+                    ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
-+                              ENGINE_R_INVALID_INIT_VALUE);
-+                    goto err;
-+                }
-+            } else if (strcmp(ctrlname, "default_algorithms") == 0) {
-+                if (!ENGINE_set_default_string(e, ctrlvalue))
-+                    goto err;
-+            } else if (!ENGINE_ctrl_cmd_string(e, ctrlname, ctrlvalue, 0))
-+                goto err;
-+        }
-+
-+    }
-+    if (e && (do_init == -1) && !int_engine_init(e)) {
-+        ecmd = NULL;
-+        goto err;
-+    }
-+    ret = 1;
-+ err:
-+    if (ret != 1) {
-+        ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
-+                  ENGINE_R_ENGINE_CONFIGURATION_ERROR);
-+        if (ecmd)
-+            ERR_add_error_data(6, "section=", ecmd->section,
-+                               ", name=", ecmd->name,
-+                               ", value=", ecmd->value);
-+    }
-+    ENGINE_free(e);
-+    return ret;
-+}
-+
-+static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
-+{
-+    STACK_OF(CONF_VALUE) *elist;
-+    CONF_VALUE *cval;
-+    int i;
-+#ifdef ENGINE_CONF_DEBUG
-+    fprintf(stderr, "Called engine module: name %s, value %s\n",
-+            CONF_imodule_get_name(md), CONF_imodule_get_value(md));
-+#endif
-+    /* Value is a section containing ENGINEs to configure */
-+    elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
-+
-+    if (!elist) {
-+        ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT,
-+                  ENGINE_R_ENGINES_SECTION_ERROR);
-+        return 0;
-+    }
-+
-+    for (i = 0; i < sk_CONF_VALUE_num(elist); i++) {
-+        cval = sk_CONF_VALUE_value(elist, i);
-+        if (!int_engine_configure(cval->name, cval->value, cnf))
-+            return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+static void int_engine_module_finish(CONF_IMODULE *md)
-+{
-+    ENGINE *e;
-+
-+    while ((e = sk_ENGINE_pop(initialized_engines)))
-+        ENGINE_finish(e);
-+    sk_ENGINE_free(initialized_engines);
-+    initialized_engines = NULL;
-+}
-+
-+void ENGINE_add_conf_module(void)
-+{
-+    CONF_module_add("engines",
-+                    int_engine_module_init, int_engine_module_finish);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_cryptodev.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_cryptodev.c
-new file mode 100644
-index 0000000..d63c918
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_cryptodev.c
-@@ -0,0 +1,1754 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Copyright (c) 2002 Bob Beck 
-+ * Copyright (c) 2002 Theo de Raadt
-+ * Copyright (c) 2002 Markus Friedl
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
-+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
-+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
-+        (defined(OpenBSD) || defined(__FreeBSD__))
-+# include 
-+# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
-+#  define HAVE_CRYPTODEV
-+# endif
-+# if (OpenBSD >= 200110)
-+#  define HAVE_SYSLOG_R
-+# endif
-+#endif
-+
-+#include 
-+#ifdef HAVE_CRYPTODEV
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+#endif
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifndef HAVE_CRYPTODEV
-+
-+void engine_load_cryptodev_int(void)
-+{
-+    /* This is a NOP on platforms without /dev/crypto */
-+    return;
-+}
-+
-+#else
-+
-+struct dev_crypto_state {
-+    struct session_op d_sess;
-+    int d_fd;
-+# ifdef USE_CRYPTODEV_DIGESTS
-+    char dummy_mac_key[HASH_MAX_LEN];
-+    unsigned char digest_res[HASH_MAX_LEN];
-+    char *mac_data;
-+    int mac_len;
-+# endif
-+};
-+
-+static u_int32_t cryptodev_asymfeat = 0;
-+
-+static RSA_METHOD *cryptodev_rsa;
-+#ifndef OPENSSL_NO_DSA
-+static DSA_METHOD *cryptodev_dsa = NULL;
-+#endif
-+#ifndef OPENSSL_NO_DH
-+static DH_METHOD *cryptodev_dh;
-+#endif
-+
-+static int get_asym_dev_crypto(void);
-+static int open_dev_crypto(void);
-+static int get_dev_crypto(void);
-+static int get_cryptodev_ciphers(const int **cnids);
-+# ifdef USE_CRYPTODEV_DIGESTS
-+static int get_cryptodev_digests(const int **cnids);
-+# endif
-+static int cryptodev_usable_ciphers(const int **nids);
-+static int cryptodev_usable_digests(const int **nids);
-+static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t inl);
-+static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                              const unsigned char *iv, int enc);
-+static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
-+static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-+                                    const int **nids, int nid);
-+static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
-+                                    const int **nids, int nid);
-+static int bn2crparam(const BIGNUM *a, struct crparam *crp);
-+static int crparam2bn(struct crparam *crp, BIGNUM *a);
-+static void zapparams(struct crypt_kop *kop);
-+static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
-+                          int slen, BIGNUM *s);
-+
-+static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
-+                                const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
-+                                BN_MONT_CTX *m_ctx);
-+static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
-+                                       BN_CTX *ctx);
-+static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
-+                                 BN_CTX *ctx);
-+#ifndef OPENSSL_NO_DSA
-+static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a,
-+                                    const BIGNUM *p, const BIGNUM *m,
-+                                    BN_CTX *ctx, BN_MONT_CTX *m_ctx);
-+static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, const BIGNUM *g,
-+                                     const BIGNUM *u1, const BIGNUM *pub_key,
-+                                     const BIGNUM *u2, const BIGNUM *p,
-+                                     BN_CTX *ctx, BN_MONT_CTX *mont);
-+static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
-+                                      DSA *dsa);
-+static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
-+                                DSA_SIG *sig, DSA *dsa);
-+#endif
-+#ifndef OPENSSL_NO_DH
-+static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
-+                                const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
-+                                BN_MONT_CTX *m_ctx);
-+static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key,
-+                                    DH *dh);
-+#endif
-+static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
-+                          void (*f) (void));
-+void engine_load_cryptodev_int(void);
-+
-+static const ENGINE_CMD_DEFN cryptodev_defns[] = {
-+    {0, NULL, NULL, 0}
-+};
-+
-+static struct {
-+    int id;
-+    int nid;
-+    int ivmax;
-+    int keylen;
-+} ciphers[] = {
-+    {
-+        CRYPTO_ARC4, NID_rc4, 0, 16,
-+    },
-+    {
-+        CRYPTO_DES_CBC, NID_des_cbc, 8, 8,
-+    },
-+    {
-+        CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24,
-+    },
-+    {
-+        CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16,
-+    },
-+    {
-+        CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24,
-+    },
-+    {
-+        CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32,
-+    },
-+# ifdef CRYPTO_AES_CTR
-+    {
-+        CRYPTO_AES_CTR, NID_aes_128_ctr, 14, 16,
-+    },
-+    {
-+        CRYPTO_AES_CTR, NID_aes_192_ctr, 14, 24,
-+    },
-+    {
-+        CRYPTO_AES_CTR, NID_aes_256_ctr, 14, 32,
-+    },
-+# endif
-+    {
-+        CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16,
-+    },
-+    {
-+        CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16,
-+    },
-+    {
-+        CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0,
-+    },
-+    {
-+        0, NID_undef, 0, 0,
-+    },
-+};
-+
-+# ifdef USE_CRYPTODEV_DIGESTS
-+static struct {
-+    int id;
-+    int nid;
-+    int keylen;
-+} digests[] = {
-+    {
-+        CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16
-+    },
-+    {
-+        CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20
-+    },
-+    {
-+        CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16
-+        /* ? */
-+    },
-+    {
-+        CRYPTO_MD5_KPDK, NID_undef, 0
-+    },
-+    {
-+        CRYPTO_SHA1_KPDK, NID_undef, 0
-+    },
-+    {
-+        CRYPTO_MD5, NID_md5, 16
-+    },
-+    {
-+        CRYPTO_SHA1, NID_sha1, 20
-+    },
-+    {
-+        0, NID_undef, 0
-+    },
-+};
-+# endif
-+
-+/*
-+ * Return a fd if /dev/crypto seems usable, 0 otherwise.
-+ */
-+static int open_dev_crypto(void)
-+{
-+    static int fd = -1;
-+
-+    if (fd == -1) {
-+        if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
-+            return (-1);
-+        /* close on exec */
-+        if (fcntl(fd, F_SETFD, 1) == -1) {
-+            close(fd);
-+            fd = -1;
-+            return (-1);
-+        }
-+    }
-+    return (fd);
-+}
-+
-+static int get_dev_crypto(void)
-+{
-+    int fd, retfd;
-+
-+    if ((fd = open_dev_crypto()) == -1)
-+        return (-1);
-+# ifndef CRIOGET_NOT_NEEDED
-+    if (ioctl(fd, CRIOGET, &retfd) == -1)
-+        return (-1);
-+
-+    /* close on exec */
-+    if (fcntl(retfd, F_SETFD, 1) == -1) {
-+        close(retfd);
-+        return (-1);
-+    }
-+# else
-+    retfd = fd;
-+# endif
-+    return (retfd);
-+}
-+
-+static void put_dev_crypto(int fd)
-+{
-+# ifndef CRIOGET_NOT_NEEDED
-+    close(fd);
-+# endif
-+}
-+
-+/* Caching version for asym operations */
-+static int get_asym_dev_crypto(void)
-+{
-+    static int fd = -1;
-+
-+    if (fd == -1)
-+        fd = get_dev_crypto();
-+    return fd;
-+}
-+
-+/*
-+ * Find out what ciphers /dev/crypto will let us have a session for.
-+ * XXX note, that some of these openssl doesn't deal with yet!
-+ * returning them here is harmless, as long as we return NULL
-+ * when asked for a handler in the cryptodev_engine_ciphers routine
-+ */
-+static int get_cryptodev_ciphers(const int **cnids)
-+{
-+    static int nids[CRYPTO_ALGORITHM_MAX];
-+    struct session_op sess;
-+    int fd, i, count = 0;
-+
-+    if ((fd = get_dev_crypto()) < 0) {
-+        *cnids = NULL;
-+        return (0);
-+    }
-+    memset(&sess, 0, sizeof(sess));
-+    sess.key = (caddr_t) "123456789abcdefghijklmno";
-+
-+    for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
-+        if (ciphers[i].nid == NID_undef)
-+            continue;
-+        sess.cipher = ciphers[i].id;
-+        sess.keylen = ciphers[i].keylen;
-+        sess.mac = 0;
-+        if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
-+            ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
-+            nids[count++] = ciphers[i].nid;
-+    }
-+    put_dev_crypto(fd);
-+
-+    if (count > 0)
-+        *cnids = nids;
-+    else
-+        *cnids = NULL;
-+    return (count);
-+}
-+
-+# ifdef USE_CRYPTODEV_DIGESTS
-+/*
-+ * Find out what digests /dev/crypto will let us have a session for.
-+ * XXX note, that some of these openssl doesn't deal with yet!
-+ * returning them here is harmless, as long as we return NULL
-+ * when asked for a handler in the cryptodev_engine_digests routine
-+ */
-+static int get_cryptodev_digests(const int **cnids)
-+{
-+    static int nids[CRYPTO_ALGORITHM_MAX];
-+    struct session_op sess;
-+    int fd, i, count = 0;
-+
-+    if ((fd = get_dev_crypto()) < 0) {
-+        *cnids = NULL;
-+        return (0);
-+    }
-+    memset(&sess, 0, sizeof(sess));
-+    sess.mackey = (caddr_t) "123456789abcdefghijklmno";
-+    for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
-+        if (digests[i].nid == NID_undef)
-+            continue;
-+        sess.mac = digests[i].id;
-+        sess.mackeylen = digests[i].keylen;
-+        sess.cipher = 0;
-+        if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
-+            ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
-+            nids[count++] = digests[i].nid;
-+    }
-+    put_dev_crypto(fd);
-+
-+    if (count > 0)
-+        *cnids = nids;
-+    else
-+        *cnids = NULL;
-+    return (count);
-+}
-+# endif                         /* 0 */
-+
-+/*
-+ * Find the useable ciphers|digests from dev/crypto - this is the first
-+ * thing called by the engine init crud which determines what it
-+ * can use for ciphers from this engine. We want to return
-+ * only what we can do, anything else is handled by software.
-+ *
-+ * If we can't initialize the device to do anything useful for
-+ * any reason, we want to return a NULL array, and 0 length,
-+ * which forces everything to be done is software. By putting
-+ * the initialization of the device in here, we ensure we can
-+ * use this engine as the default, and if for whatever reason
-+ * /dev/crypto won't do what we want it will just be done in
-+ * software
-+ *
-+ * This can (should) be greatly expanded to perhaps take into
-+ * account speed of the device, and what we want to do.
-+ * (although the disabling of particular alg's could be controlled
-+ * by the device driver with sysctl's.) - this is where we
-+ * want most of the decisions made about what we actually want
-+ * to use from /dev/crypto.
-+ */
-+static int cryptodev_usable_ciphers(const int **nids)
-+{
-+    return (get_cryptodev_ciphers(nids));
-+}
-+
-+static int cryptodev_usable_digests(const int **nids)
-+{
-+# ifdef USE_CRYPTODEV_DIGESTS
-+    return (get_cryptodev_digests(nids));
-+# else
-+    /*
-+     * XXXX just disable all digests for now, because it sucks.
-+     * we need a better way to decide this - i.e. I may not
-+     * want digests on slow cards like hifn on fast machines,
-+     * but might want them on slow or loaded machines, etc.
-+     * will also want them when using crypto cards that don't
-+     * suck moose gonads - would be nice to be able to decide something
-+     * as reasonable default without having hackery that's card dependent.
-+     * of course, the default should probably be just do everything,
-+     * with perhaps a sysctl to turn algorithms off (or have them off
-+     * by default) on cards that generally suck like the hifn.
-+     */
-+    *nids = NULL;
-+    return (0);
-+# endif
-+}
-+
-+static int
-+cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                 const unsigned char *in, size_t inl)
-+{
-+    struct crypt_op cryp;
-+    struct dev_crypto_state *state = EVP_CIPHER_CTX_get_cipher_data(ctx);
-+    struct session_op *sess = &state->d_sess;
-+    const void *iiv;
-+    unsigned char save_iv[EVP_MAX_IV_LENGTH];
-+
-+    if (state->d_fd < 0)
-+        return (0);
-+    if (!inl)
-+        return (1);
-+    if ((inl % EVP_CIPHER_CTX_block_size(ctx)) != 0)
-+        return (0);
-+
-+    memset(&cryp, 0, sizeof(cryp));
-+
-+    cryp.ses = sess->ses;
-+    cryp.flags = 0;
-+    cryp.len = inl;
-+    cryp.src = (caddr_t) in;
-+    cryp.dst = (caddr_t) out;
-+    cryp.mac = 0;
-+
-+    cryp.op = EVP_CIPHER_CTX_encrypting(ctx) ? COP_ENCRYPT : COP_DECRYPT;
-+
-+    if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
-+        cryp.iv = (caddr_t) EVP_CIPHER_CTX_iv(ctx);
-+        if (!EVP_CIPHER_CTX_encrypting(ctx)) {
-+            iiv = in + inl - EVP_CIPHER_CTX_iv_length(ctx);
-+            memcpy(save_iv, iiv, EVP_CIPHER_CTX_iv_length(ctx));
-+        }
-+    } else
-+        cryp.iv = NULL;
-+
-+    if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
-+        /*
-+         * XXX need better error handling this can fail for a number of
-+         * different reasons.
-+         */
-+        return (0);
-+    }
-+
-+    if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
-+        if (EVP_CIPHER_CTX_encrypting(ctx))
-+            iiv = out + inl - EVP_CIPHER_CTX_iv_length(ctx);
-+        else
-+            iiv = save_iv;
-+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iiv,
-+               EVP_CIPHER_CTX_iv_length(ctx));
-+    }
-+    return (1);
-+}
-+
-+static int
-+cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                   const unsigned char *iv, int enc)
-+{
-+    struct dev_crypto_state *state = EVP_CIPHER_CTX_get_cipher_data(ctx);
-+    struct session_op *sess = &state->d_sess;
-+    int cipher = -1, i;
-+
-+    for (i = 0; ciphers[i].id; i++)
-+        if (EVP_CIPHER_CTX_nid(ctx) == ciphers[i].nid &&
-+            EVP_CIPHER_CTX_iv_length(ctx) <= ciphers[i].ivmax &&
-+            EVP_CIPHER_CTX_key_length(ctx) == ciphers[i].keylen) {
-+            cipher = ciphers[i].id;
-+            break;
-+        }
-+
-+    if (!ciphers[i].id) {
-+        state->d_fd = -1;
-+        return (0);
-+    }
-+
-+    memset(sess, 0, sizeof(*sess));
-+
-+    if ((state->d_fd = get_dev_crypto()) < 0)
-+        return (0);
-+
-+    sess->key = (caddr_t) key;
-+    sess->keylen = EVP_CIPHER_CTX_key_length(ctx);
-+    sess->cipher = cipher;
-+
-+    if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
-+        put_dev_crypto(state->d_fd);
-+        state->d_fd = -1;
-+        return (0);
-+    }
-+    return (1);
-+}
-+
-+/*
-+ * free anything we allocated earlier when initing a
-+ * session, and close the session.
-+ */
-+static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
-+{
-+    int ret = 0;
-+    struct dev_crypto_state *state = EVP_CIPHER_CTX_get_cipher_data(ctx);
-+    struct session_op *sess = &state->d_sess;
-+
-+    if (state->d_fd < 0)
-+        return (0);
-+
-+    /*
-+     * XXX if this ioctl fails, something's wrong. the invoker may have called
-+     * us with a bogus ctx, or we could have a device that for whatever
-+     * reason just doesn't want to play ball - it's not clear what's right
-+     * here - should this be an error? should it just increase a counter,
-+     * hmm. For right now, we return 0 - I don't believe that to be "right".
-+     * we could call the gorpy openssl lib error handlers that print messages
-+     * to users of the library. hmm..
-+     */
-+
-+    if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
-+        ret = 0;
-+    } else {
-+        ret = 1;
-+    }
-+    put_dev_crypto(state->d_fd);
-+    state->d_fd = -1;
-+
-+    return (ret);
-+}
-+
-+/*
-+ * libcrypto EVP stuff - this is how we get wired to EVP so the engine
-+ * gets called when libcrypto requests a cipher NID.
-+ */
-+
-+/* RC4 */
-+static EVP_CIPHER *rc4_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_rc4(void)
-+{
-+    if (rc4_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_rc4, 1, 16)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 0)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_VARIABLE_LENGTH)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        rc4_cipher = cipher;
-+    }
-+    return rc4_cipher;
-+}
-+
-+/* DES CBC EVP */
-+static EVP_CIPHER *des_cbc_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_des_cbc(void)
-+{
-+    if (des_cbc_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_des_cbc, 8, 8)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 8)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
-+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
-+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        des_cbc_cipher = cipher;
-+    }
-+    return des_cbc_cipher;
-+}
-+
-+/* 3DES CBC EVP */
-+static EVP_CIPHER *des3_cbc_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_3des_cbc(void)
-+{
-+    if (des3_cbc_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_des_ede3_cbc, 8, 24)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 8)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
-+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
-+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        des3_cbc_cipher = cipher;
-+    }
-+    return des3_cbc_cipher;
-+}
-+
-+static EVP_CIPHER *bf_cbc_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_bf_cbc(void)
-+{
-+    if (bf_cbc_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_bf_cbc, 8, 16)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 8)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
-+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
-+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        bf_cbc_cipher = cipher;
-+    }
-+    return bf_cbc_cipher;
-+}
-+
-+static EVP_CIPHER *cast_cbc_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_cast_cbc(void)
-+{
-+    if (cast_cbc_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_cast5_cbc, 8, 16)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 8)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
-+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
-+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        cast_cbc_cipher = cipher;
-+    }
-+    return cast_cbc_cipher;
-+}
-+
-+static EVP_CIPHER *aes_cbc_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_aes_cbc(void)
-+{
-+    if (aes_cbc_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_128_cbc, 16, 16)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 16)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
-+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
-+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        aes_cbc_cipher = cipher;
-+    }
-+    return aes_cbc_cipher;
-+}
-+
-+static EVP_CIPHER *aes_192_cbc_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_aes_192_cbc(void)
-+{
-+    if (aes_192_cbc_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_192_cbc, 16, 24)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 16)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
-+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
-+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        aes_192_cbc_cipher = cipher;
-+    }
-+    return aes_192_cbc_cipher;
-+}
-+
-+static EVP_CIPHER *aes_256_cbc_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_aes_256_cbc(void)
-+{
-+    if (aes_256_cbc_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_256_cbc, 16, 32)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 16)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
-+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
-+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        aes_256_cbc_cipher = cipher;
-+    }
-+    return aes_256_cbc_cipher;
-+}
-+
-+# ifdef CRYPTO_AES_CTR
-+static EVP_CIPHER *aes_ctr_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_aes_ctr(void)
-+{
-+    if (aes_ctr_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_128_ctr, 16, 16)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 14)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CTR_MODE)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
-+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
-+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        aes_ctr_cipher = cipher;
-+    }
-+    return aes_ctr_cipher;
-+}
-+
-+static EVP_CIPHER *aes_192_ctr_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_aes_192_ctr(void)
-+{
-+    if (aes_192_ctr_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_192_ctr, 16, 24)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 14)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CTR_MODE)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
-+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
-+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        aes_192_ctr_cipher = cipher;
-+    }
-+    return aes_192_ctr_cipher;
-+}
-+
-+static EVP_CIPHER *aes_256_ctr_cipher = NULL;
-+static const EVP_CIPHER *cryptodev_aes_256_ctr(void)
-+{
-+    if (aes_256_ctr_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_256_ctr, 16, 32)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 14)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CTR_MODE)
-+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
-+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
-+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
-+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        aes_256_ctr_cipher = cipher;
-+    }
-+    return aes_256_ctr_cipher;
-+}
-+# endif
-+/*
-+ * Registered by the ENGINE when used to find out how to deal with
-+ * a particular NID in the ENGINE. this says what we'll do at the
-+ * top level - note, that list is restricted by what we answer with
-+ */
-+static int
-+cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-+                         const int **nids, int nid)
-+{
-+    if (!cipher)
-+        return (cryptodev_usable_ciphers(nids));
-+
-+    switch (nid) {
-+    case NID_rc4:
-+        *cipher = cryptodev_rc4();
-+        break;
-+    case NID_des_ede3_cbc:
-+        *cipher = cryptodev_3des_cbc();
-+        break;
-+    case NID_des_cbc:
-+        *cipher = cryptodev_des_cbc();
-+        break;
-+    case NID_bf_cbc:
-+        *cipher = cryptodev_bf_cbc();
-+        break;
-+    case NID_cast5_cbc:
-+        *cipher = cryptodev_cast_cbc();
-+        break;
-+    case NID_aes_128_cbc:
-+        *cipher = cryptodev_aes_cbc();
-+        break;
-+    case NID_aes_192_cbc:
-+        *cipher = cryptodev_aes_192_cbc();
-+        break;
-+    case NID_aes_256_cbc:
-+        *cipher = cryptodev_aes_256_cbc();
-+        break;
-+# ifdef CRYPTO_AES_CTR
-+    case NID_aes_128_ctr:
-+        *cipher = cryptodev_aes_ctr();
-+        break;
-+    case NID_aes_192_ctr:
-+        *cipher = cryptodev_aes_192_ctr();
-+        break;
-+    case NID_aes_256_ctr:
-+        *cipher = cryptodev_aes_256_ctr();
-+        break;
-+# endif
-+    default:
-+        *cipher = NULL;
-+        break;
-+    }
-+    return (*cipher != NULL);
-+}
-+
-+# ifdef USE_CRYPTODEV_DIGESTS
-+
-+/* convert digest type to cryptodev */
-+static int digest_nid_to_cryptodev(int nid)
-+{
-+    int i;
-+
-+    for (i = 0; digests[i].id; i++)
-+        if (digests[i].nid == nid)
-+            return (digests[i].id);
-+    return (0);
-+}
-+
-+static int digest_key_length(int nid)
-+{
-+    int i;
-+
-+    for (i = 0; digests[i].id; i++)
-+        if (digests[i].nid == nid)
-+            return digests[i].keylen;
-+    return (0);
-+}
-+
-+static int cryptodev_digest_init(EVP_MD_CTX *ctx)
-+{
-+    struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
-+    struct session_op *sess = &state->d_sess;
-+    int digest;
-+
-+    if ((digest = digest_nid_to_cryptodev(EVP_MD_CTX_type(ctx))) == NID_undef) {
-+        printf("cryptodev_digest_init: Can't get digest \n");
-+        return (0);
-+    }
-+
-+    memset(state, 0, sizeof(*state));
-+
-+    if ((state->d_fd = get_dev_crypto()) < 0) {
-+        printf("cryptodev_digest_init: Can't get Dev \n");
-+        return (0);
-+    }
-+
-+    sess->mackey = state->dummy_mac_key;
-+    sess->mackeylen = digest_key_length(EVP_MD_CTX_type(ctx));
-+    sess->mac = digest;
-+
-+    if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
-+        put_dev_crypto(state->d_fd);
-+        state->d_fd = -1;
-+        printf("cryptodev_digest_init: Open session failed\n");
-+        return (0);
-+    }
-+
-+    return (1);
-+}
-+
-+static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
-+                                   size_t count)
-+{
-+    struct crypt_op cryp;
-+    struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
-+    struct session_op *sess = &state->d_sess;
-+    char *new_mac_data;
-+
-+    if (!data || state->d_fd < 0) {
-+        printf("cryptodev_digest_update: illegal inputs \n");
-+        return (0);
-+    }
-+
-+    if (!count) {
-+        return (0);
-+    }
-+
-+    if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
-+        /* if application doesn't support one buffer */
-+        new_mac_data =
-+            OPENSSL_realloc(state->mac_data, state->mac_len + count);
-+
-+        if (!new_mac_data) {
-+            printf("cryptodev_digest_update: realloc failed\n");
-+            return (0);
-+        }
-+        state->mac_data = new_mac_data;
-+
-+        memcpy(state->mac_data + state->mac_len, data, count);
-+        state->mac_len += count;
-+
-+        return (1);
-+    }
-+
-+    memset(&cryp, 0, sizeof(cryp));
-+
-+    cryp.ses = sess->ses;
-+    cryp.flags = 0;
-+    cryp.len = count;
-+    cryp.src = (caddr_t) data;
-+    cryp.dst = NULL;
-+    cryp.mac = (caddr_t) state->digest_res;
-+    if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
-+        printf("cryptodev_digest_update: digest failed\n");
-+        return (0);
-+    }
-+    return (1);
-+}
-+
-+static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    struct crypt_op cryp;
-+    struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
-+    struct session_op *sess = &state->d_sess;
-+
-+    int ret = 1;
-+
-+    if (!md || state->d_fd < 0) {
-+        printf("cryptodev_digest_final: illegal input\n");
-+        return (0);
-+    }
-+
-+    if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
-+        /* if application doesn't support one buffer */
-+        memset(&cryp, 0, sizeof(cryp));
-+        cryp.ses = sess->ses;
-+        cryp.flags = 0;
-+        cryp.len = state->mac_len;
-+        cryp.src = state->mac_data;
-+        cryp.dst = NULL;
-+        cryp.mac = (caddr_t) md;
-+        if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
-+            printf("cryptodev_digest_final: digest failed\n");
-+            return (0);
-+        }
-+
-+        return 1;
-+    }
-+
-+    memcpy(md, state->digest_res, EVP_MD_CTX_size(ctx));
-+
-+    return (ret);
-+}
-+
-+static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
-+{
-+    int ret = 1;
-+    struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
-+    struct session_op *sess = &state->d_sess;
-+
-+    if (state == NULL)
-+        return 0;
-+
-+    if (state->d_fd < 0) {
-+        printf("cryptodev_digest_cleanup: illegal input\n");
-+        return (0);
-+    }
-+
-+    OPENSSL_free(state->mac_data);
-+    state->mac_data = NULL;
-+    state->mac_len = 0;
-+
-+    if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
-+        printf("cryptodev_digest_cleanup: failed to close session\n");
-+        ret = 0;
-+    } else {
-+        ret = 1;
-+    }
-+    put_dev_crypto(state->d_fd);
-+    state->d_fd = -1;
-+
-+    return (ret);
-+}
-+
-+static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
-+{
-+    struct dev_crypto_state *fstate = EVP_MD_CTX_md_data(from);
-+    struct dev_crypto_state *dstate = EVP_MD_CTX_md_data(to);
-+    struct session_op *sess;
-+    int digest;
-+
-+    if (dstate == NULL || fstate == NULL)
-+        return 1;
-+
-+    memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
-+
-+    sess = &dstate->d_sess;
-+
-+    digest = digest_nid_to_cryptodev(EVP_MD_CTX_type(to));
-+
-+    sess->mackey = dstate->dummy_mac_key;
-+    sess->mackeylen = digest_key_length(EVP_MD_CTX_type(to));
-+    sess->mac = digest;
-+
-+    dstate->d_fd = get_dev_crypto();
-+
-+    if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
-+        put_dev_crypto(dstate->d_fd);
-+        dstate->d_fd = -1;
-+        printf("cryptodev_digest_copy: Open session failed\n");
-+        return (0);
-+    }
-+
-+    if (fstate->mac_len != 0) {
-+        if (fstate->mac_data != NULL) {
-+            dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
-+            if (dstate->mac_data == NULL) {
-+                printf("cryptodev_digest_copy: mac_data allocation failed\n");
-+                return (0);
-+            }
-+            memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
-+            dstate->mac_len = fstate->mac_len;
-+        }
-+    }
-+
-+    return 1;
-+}
-+
-+static EVP_MD *sha1_md = NULL;
-+static const EVP_MD *cryptodev_sha1(void)
-+{
-+    if (sha1_md == NULL) {
-+        EVP_MD *md;
-+
-+        if ((md = EVP_MD_meth_new(NID_sha1, NID_undef)) == NULL
-+            || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)
-+            || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_ONESHOT)
-+            || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)
-+            || !EVP_MD_meth_set_app_datasize(md,
-+                                             sizeof(struct dev_crypto_state))
-+            || !EVP_MD_meth_set_init(md, cryptodev_digest_init)
-+            || !EVP_MD_meth_set_update(md, cryptodev_digest_update)
-+            || !EVP_MD_meth_set_final(md, cryptodev_digest_final)
-+            || !EVP_MD_meth_set_copy(md, cryptodev_digest_copy)
-+            || !EVP_MD_meth_set_cleanup(md, cryptodev_digest_cleanup)) {
-+            EVP_MD_meth_free(md);
-+            md = NULL;
-+        }
-+        sha1_md = md;
-+    }
-+    return sha1_md;
-+}
-+
-+static EVP_MD *md5_md = NULL;
-+static const EVP_MD *cryptodev_md5(void)
-+{
-+    if (md5_md == NULL) {
-+        EVP_MD *md;
-+
-+        if ((md = EVP_MD_meth_new(NID_md5, NID_undef)) == NULL
-+            || !EVP_MD_meth_set_result_size(md, 16 /* MD5_DIGEST_LENGTH */)
-+            || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_ONESHOT)
-+            || !EVP_MD_meth_set_input_blocksize(md, 64 /* MD5_CBLOCK */)
-+            || !EVP_MD_meth_set_app_datasize(md,
-+                                             sizeof(struct dev_crypto_state))
-+            || !EVP_MD_meth_set_init(md, cryptodev_digest_init)
-+            || !EVP_MD_meth_set_update(md, cryptodev_digest_update)
-+            || !EVP_MD_meth_set_final(md, cryptodev_digest_final)
-+            || !EVP_MD_meth_set_copy(md, cryptodev_digest_copy)
-+            || !EVP_MD_meth_set_cleanup(md, cryptodev_digest_cleanup)) {
-+            EVP_MD_meth_free(md);
-+            md = NULL;
-+        }
-+        md5_md = md;
-+    }
-+    return md5_md;
-+}
-+
-+# endif                         /* USE_CRYPTODEV_DIGESTS */
-+
-+static int
-+cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
-+                         const int **nids, int nid)
-+{
-+    if (!digest)
-+        return (cryptodev_usable_digests(nids));
-+
-+    switch (nid) {
-+# ifdef USE_CRYPTODEV_DIGESTS
-+    case NID_md5:
-+        *digest = cryptodev_md5();
-+        break;
-+    case NID_sha1:
-+        *digest = cryptodev_sha1();
-+        break;
-+    default:
-+# endif                         /* USE_CRYPTODEV_DIGESTS */
-+        *digest = NULL;
-+        break;
-+    }
-+    return (*digest != NULL);
-+}
-+
-+static int cryptodev_engine_destroy(ENGINE *e)
-+{
-+    EVP_CIPHER_meth_free(rc4_cipher);
-+    rc4_cipher = NULL;
-+    EVP_CIPHER_meth_free(des_cbc_cipher);
-+    des_cbc_cipher = NULL;
-+    EVP_CIPHER_meth_free(des3_cbc_cipher);
-+    des3_cbc_cipher = NULL;
-+    EVP_CIPHER_meth_free(bf_cbc_cipher);
-+    bf_cbc_cipher = NULL;
-+    EVP_CIPHER_meth_free(cast_cbc_cipher);
-+    cast_cbc_cipher = NULL;
-+    EVP_CIPHER_meth_free(aes_cbc_cipher);
-+    aes_cbc_cipher = NULL;
-+    EVP_CIPHER_meth_free(aes_192_cbc_cipher);
-+    aes_192_cbc_cipher = NULL;
-+    EVP_CIPHER_meth_free(aes_256_cbc_cipher);
-+    aes_256_cbc_cipher = NULL;
-+# ifdef CRYPTO_AES_CTR
-+    EVP_CIPHER_meth_free(aes_ctr_cipher);
-+    aes_ctr_cipher = NULL;
-+    EVP_CIPHER_meth_free(aes_192_ctr_cipher);
-+    aes_192_ctr_cipher = NULL;
-+    EVP_CIPHER_meth_free(aes_256_ctr_cipher);
-+    aes_256_ctr_cipher = NULL;
-+# endif
-+# ifdef USE_CRYPTODEV_DIGESTS
-+    EVP_MD_meth_free(sha1_md);
-+    sha1_md = NULL;
-+    EVP_MD_meth_free(md5_md);
-+    md5_md = NULL;
-+# endif
-+    RSA_meth_free(cryptodev_rsa);
-+    cryptodev_rsa = NULL;
-+#ifndef OPENSSL_NO_DSA
-+    DSA_meth_free(cryptodev_dsa);
-+    cryptodev_dsa = NULL;
-+#endif
-+#ifndef OPENSSL_NO_DH
-+    DH_meth_free(cryptodev_dh);
-+    cryptodev_dh = NULL;
-+#endif
-+    return 1;
-+}
-+
-+/*
-+ * Convert a BIGNUM to the representation that /dev/crypto needs.
-+ * Upon completion of use, the caller is responsible for freeing
-+ * crp->crp_p.
-+ */
-+static int bn2crparam(const BIGNUM *a, struct crparam *crp)
-+{
-+    ssize_t bytes, bits;
-+    u_char *b;
-+
-+    crp->crp_p = NULL;
-+    crp->crp_nbits = 0;
-+
-+    bits = BN_num_bits(a);
-+    bytes = BN_num_bytes(a);
-+
-+    b = OPENSSL_zalloc(bytes);
-+    if (b == NULL)
-+        return (1);
-+
-+    crp->crp_p = (caddr_t) b;
-+    crp->crp_nbits = bits;
-+
-+    BN_bn2bin(a, b);
-+    return (0);
-+}
-+
-+/* Convert a /dev/crypto parameter to a BIGNUM */
-+static int crparam2bn(struct crparam *crp, BIGNUM *a)
-+{
-+    u_int8_t *pd;
-+    int i, bytes;
-+
-+    bytes = (crp->crp_nbits + 7) / 8;
-+
-+    if (bytes == 0)
-+        return (-1);
-+
-+    if ((pd = OPENSSL_malloc(bytes)) == NULL)
-+        return (-1);
-+
-+    for (i = 0; i < bytes; i++)
-+        pd[i] = crp->crp_p[bytes - i - 1];
-+
-+    BN_bin2bn(pd, bytes, a);
-+    free(pd);
-+
-+    return (0);
-+}
-+
-+static void zapparams(struct crypt_kop *kop)
-+{
-+    int i;
-+
-+    for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
-+        OPENSSL_free(kop->crk_param[i].crp_p);
-+        kop->crk_param[i].crp_p = NULL;
-+        kop->crk_param[i].crp_nbits = 0;
-+    }
-+}
-+
-+static int
-+cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
-+               BIGNUM *s)
-+{
-+    int fd, ret = -1;
-+
-+    if ((fd = get_asym_dev_crypto()) < 0)
-+        return ret;
-+
-+    if (r) {
-+        kop->crk_param[kop->crk_iparams].crp_p = OPENSSL_zalloc(rlen);
-+        if (kop->crk_param[kop->crk_iparams].crp_p == NULL)
-+            return ret;
-+        kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
-+        kop->crk_oparams++;
-+    }
-+    if (s) {
-+        kop->crk_param[kop->crk_iparams + 1].crp_p =
-+            OPENSSL_zalloc(slen);
-+        /* No need to free the kop->crk_iparams parameter if it was allocated,
-+         * callers of this routine have to free allocated parameters through
-+         * zapparams both in case of success and failure
-+         */
-+        if (kop->crk_param[kop->crk_iparams+1].crp_p == NULL)
-+            return ret;
-+        kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8;
-+        kop->crk_oparams++;
-+    }
-+
-+    if (ioctl(fd, CIOCKEY, kop) == 0) {
-+        if (r)
-+            crparam2bn(&kop->crk_param[kop->crk_iparams], r);
-+        if (s)
-+            crparam2bn(&kop->crk_param[kop->crk_iparams + 1], s);
-+        ret = 0;
-+    }
-+
-+    return ret;
-+}
-+
-+static int
-+cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-+                     const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
-+{
-+    struct crypt_kop kop;
-+    int ret = 1;
-+
-+    /*
-+     * Currently, we know we can do mod exp iff we can do any asymmetric
-+     * operations at all.
-+     */
-+    if (cryptodev_asymfeat == 0) {
-+        ret = BN_mod_exp(r, a, p, m, ctx);
-+        return (ret);
-+    }
-+
-+    memset(&kop, 0, sizeof(kop));
-+    kop.crk_op = CRK_MOD_EXP;
-+
-+    /* inputs: a^p % m */
-+    if (bn2crparam(a, &kop.crk_param[0]))
-+        goto err;
-+    if (bn2crparam(p, &kop.crk_param[1]))
-+        goto err;
-+    if (bn2crparam(m, &kop.crk_param[2]))
-+        goto err;
-+    kop.crk_iparams = 3;
-+
-+    if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
-+        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
-+        printf("OCF asym process failed, Running in software\n");
-+        ret = RSA_meth_get_bn_mod_exp(meth)(r, a, p, m, ctx, in_mont);
-+
-+    } else if (ECANCELED == kop.crk_status) {
-+        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
-+        printf("OCF hardware operation cancelled. Running in Software\n");
-+        ret = RSA_meth_get_bn_mod_exp(meth)(r, a, p, m, ctx, in_mont);
-+    }
-+    /* else cryptodev operation worked ok ==> ret = 1 */
-+
-+ err:
-+    zapparams(&kop);
-+    return (ret);
-+}
-+
-+static int
-+cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
-+                            BN_CTX *ctx)
-+{
-+    int r;
-+    const BIGNUM *n = NULL;
-+    const BIGNUM *d = NULL;
-+
-+    ctx = BN_CTX_new();
-+    RSA_get0_key(rsa, &n, NULL, &d);
-+    r = cryptodev_bn_mod_exp(r0, I, d, n, ctx, NULL);
-+    BN_CTX_free(ctx);
-+    return (r);
-+}
-+
-+static int
-+cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
-+{
-+    struct crypt_kop kop;
-+    int ret = 1;
-+    const BIGNUM *p = NULL;
-+    const BIGNUM *q = NULL;
-+    const BIGNUM *dmp1 = NULL;
-+    const BIGNUM *dmq1 = NULL;
-+    const BIGNUM *iqmp = NULL;
-+    const BIGNUM *n = NULL;
-+
-+    RSA_get0_factors(rsa, &p, &q);
-+    RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
-+    RSA_get0_key(rsa, &n, NULL, NULL);
-+
-+    if (!p || !q || !dmp1 || !dmq1 || !iqmp) {
-+        /* XXX 0 means failure?? */
-+        return (0);
-+    }
-+
-+    memset(&kop, 0, sizeof(kop));
-+    kop.crk_op = CRK_MOD_EXP_CRT;
-+    /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
-+    if (bn2crparam(p, &kop.crk_param[0]))
-+        goto err;
-+    if (bn2crparam(q, &kop.crk_param[1]))
-+        goto err;
-+    if (bn2crparam(I, &kop.crk_param[2]))
-+        goto err;
-+    if (bn2crparam(dmp1, &kop.crk_param[3]))
-+        goto err;
-+    if (bn2crparam(dmq1, &kop.crk_param[4]))
-+        goto err;
-+    if (bn2crparam(iqmp, &kop.crk_param[5]))
-+        goto err;
-+    kop.crk_iparams = 6;
-+
-+    if (cryptodev_asym(&kop, BN_num_bytes(n), r0, 0, NULL)) {
-+        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
-+        printf("OCF asym process failed, running in Software\n");
-+        ret = RSA_meth_get_mod_exp(meth)(r0, I, rsa, ctx);
-+
-+    } else if (ECANCELED == kop.crk_status) {
-+        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
-+        printf("OCF hardware operation cancelled. Running in Software\n");
-+        ret = RSA_meth_get_mod_exp(meth)(r0, I, rsa, ctx);
-+    }
-+    /* else cryptodev operation worked ok ==> ret = 1 */
-+
-+ err:
-+    zapparams(&kop);
-+    return (ret);
-+}
-+
-+#ifndef OPENSSL_NO_DSA
-+static int
-+cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
-+{
-+    return cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx);
-+}
-+
-+static int
-+cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, const BIGNUM *g,
-+                          const BIGNUM *u1, const BIGNUM *pub_key,
-+                          const BIGNUM *u2, const BIGNUM *p, BN_CTX *ctx,
-+                          BN_MONT_CTX *mont)
-+{
-+    const BIGNUM *dsag, *dsap, *dsapub_key;
-+    BIGNUM *t2;
-+    int ret = 0;
-+    const DSA_METHOD *meth;
-+    int (*bn_mod_exp)(DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
-+                      BN_CTX *, BN_MONT_CTX *);
-+
-+    t2 = BN_new();
-+    if (t2 == NULL)
-+        goto err;
-+
-+    /* v = ( g^u1 * y^u2 mod p ) mod q */
-+    /* let t1 = g ^ u1 mod p */
-+    ret = 0;
-+
-+    DSA_get0_pqg(dsa, &dsap, NULL, &dsag);
-+    DSA_get0_key(dsa, &dsapub_key, NULL);
-+
-+    meth = DSA_get_method(dsa);
-+    if (meth == NULL)
-+        goto err;
-+    bn_mod_exp = DSA_meth_get_bn_mod_exp(meth);
-+    if (bn_mod_exp == NULL)
-+        goto err;
-+
-+    if (!bn_mod_exp(dsa, t1, dsag, u1, dsap, ctx, mont))
-+        goto err;
-+
-+    /* let t2 = y ^ u2 mod p */
-+    if (!bn_mod_exp(dsa, t2, dsapub_key, u2, dsap, ctx, mont))
-+        goto err;
-+    /* let t1 = t1 * t2 mod p */
-+    if (!BN_mod_mul(t1, t1, t2, dsap, ctx))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    BN_free(t2);
-+    return (ret);
-+}
-+
-+static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
-+                                      DSA *dsa)
-+{
-+    struct crypt_kop kop;
-+    BIGNUM *r, *s;
-+    const BIGNUM *dsap = NULL, *dsaq = NULL, *dsag = NULL;
-+    const BIGNUM *priv_key = NULL;
-+    DSA_SIG *dsasig, *dsaret = NULL;
-+
-+    dsasig = DSA_SIG_new();
-+    if (dsasig == NULL)
-+        goto err;
-+
-+    memset(&kop, 0, sizeof(kop));
-+    kop.crk_op = CRK_DSA_SIGN;
-+
-+    /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
-+    kop.crk_param[0].crp_p = (caddr_t) dgst;
-+    kop.crk_param[0].crp_nbits = dlen * 8;
-+    DSA_get0_pqg(dsa, &dsap, &dsaq, &dsag);
-+    DSA_get0_key(dsa, NULL, &priv_key);
-+    if (bn2crparam(dsap, &kop.crk_param[1]))
-+        goto err;
-+    if (bn2crparam(dsaq, &kop.crk_param[2]))
-+        goto err;
-+    if (bn2crparam(dsag, &kop.crk_param[3]))
-+        goto err;
-+    if (bn2crparam(priv_key, &kop.crk_param[4]))
-+        goto err;
-+    kop.crk_iparams = 5;
-+
-+    r = BN_new();
-+    if (r == NULL)
-+        goto err;
-+    s = BN_new();
-+    if (s == NULL)
-+        goto err;
-+    if (cryptodev_asym(&kop, BN_num_bytes(dsaq), r,
-+                       BN_num_bytes(dsaq), s) == 0) {
-+        DSA_SIG_set0(dsasig, r, s);
-+        dsaret = dsasig;
-+    } else {
-+        dsaret = DSA_meth_get_sign(DSA_OpenSSL())(dgst, dlen, dsa);
-+    }
-+ err:
-+    if (dsaret != dsasig)
-+        DSA_SIG_free(dsasig);
-+    kop.crk_param[0].crp_p = NULL;
-+    zapparams(&kop);
-+    return dsaret;
-+}
-+
-+static int
-+cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
-+                     DSA_SIG *sig, DSA *dsa)
-+{
-+    struct crypt_kop kop;
-+    int dsaret = 1;
-+    const BIGNUM *pr, *ps, *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL;
-+
-+    memset(&kop, 0, sizeof(kop));
-+    kop.crk_op = CRK_DSA_VERIFY;
-+
-+    /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
-+    kop.crk_param[0].crp_p = (caddr_t) dgst;
-+    kop.crk_param[0].crp_nbits = dlen * 8;
-+    DSA_get0_pqg(dsa, &p, &q, &g);
-+    if (bn2crparam(p, &kop.crk_param[1]))
-+        goto err;
-+    if (bn2crparam(q, &kop.crk_param[2]))
-+        goto err;
-+    if (bn2crparam(g, &kop.crk_param[3]))
-+        goto err;
-+    DSA_get0_key(dsa, &pub_key, NULL);
-+    if (bn2crparam(pub_key, &kop.crk_param[4]))
-+        goto err;
-+    DSA_SIG_get0(sig, &pr, &ps);
-+    if (bn2crparam(pr, &kop.crk_param[5]))
-+        goto err;
-+    if (bn2crparam(ps, &kop.crk_param[6]))
-+        goto err;
-+    kop.crk_iparams = 7;
-+
-+    if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
-+        /*
-+         * OCF success value is 0, if not zero, change dsaret to fail
-+         */
-+        if (0 != kop.crk_status)
-+            dsaret = 0;
-+    } else {
-+        dsaret = DSA_meth_get_verify(DSA_OpenSSL())(dgst, dlen, sig, dsa);
-+    }
-+ err:
-+    kop.crk_param[0].crp_p = NULL;
-+    zapparams(&kop);
-+    return (dsaret);
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_DH
-+static int
-+cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
-+                     const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
-+                     BN_MONT_CTX *m_ctx)
-+{
-+    return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
-+}
-+
-+static int
-+cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
-+{
-+    struct crypt_kop kop;
-+    int dhret = 1;
-+    int fd, keylen;
-+    const BIGNUM *p = NULL;
-+    const BIGNUM *priv_key = NULL;
-+
-+    if ((fd = get_asym_dev_crypto()) < 0) {
-+        const DH_METHOD *meth = DH_OpenSSL();
-+
-+        return DH_meth_get_compute_key(meth)(key, pub_key, dh);
-+    }
-+
-+    DH_get0_pqg(dh, &p, NULL, NULL);
-+    DH_get0_key(dh, NULL, &priv_key);
-+
-+    keylen = BN_num_bits(p);
-+
-+    memset(&kop, 0, sizeof(kop));
-+    kop.crk_op = CRK_DH_COMPUTE_KEY;
-+
-+    /* inputs: dh->priv_key pub_key dh->p key */
-+    if (bn2crparam(priv_key, &kop.crk_param[0]))
-+        goto err;
-+    if (bn2crparam(pub_key, &kop.crk_param[1]))
-+        goto err;
-+    if (bn2crparam(p, &kop.crk_param[2]))
-+        goto err;
-+    kop.crk_iparams = 3;
-+
-+    kop.crk_param[3].crp_p = (caddr_t) key;
-+    kop.crk_param[3].crp_nbits = keylen * 8;
-+    kop.crk_oparams = 1;
-+
-+    if (ioctl(fd, CIOCKEY, &kop) == -1) {
-+        const DH_METHOD *meth = DH_OpenSSL();
-+
-+        dhret = DH_meth_get_compute_key(meth)(key, pub_key, dh);
-+    }
-+ err:
-+    kop.crk_param[3].crp_p = NULL;
-+    zapparams(&kop);
-+    return (dhret);
-+}
-+
-+#endif /* ndef OPENSSL_NO_DH */
-+
-+/*
-+ * ctrl right now is just a wrapper that doesn't do much
-+ * but I expect we'll want some options soon.
-+ */
-+static int
-+cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
-+{
-+# ifdef HAVE_SYSLOG_R
-+    struct syslog_data sd = SYSLOG_DATA_INIT;
-+# endif
-+
-+    switch (cmd) {
-+    default:
-+# ifdef HAVE_SYSLOG_R
-+        syslog_r(LOG_ERR, &sd, "cryptodev_ctrl: unknown command %d", cmd);
-+# else
-+        syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
-+# endif
-+        break;
-+    }
-+    return (1);
-+}
-+
-+void engine_load_cryptodev_int(void)
-+{
-+    ENGINE *engine = ENGINE_new();
-+    int fd;
-+
-+    if (engine == NULL)
-+        return;
-+    if ((fd = get_dev_crypto()) < 0) {
-+        ENGINE_free(engine);
-+        return;
-+    }
-+
-+    /*
-+     * find out what asymmetric crypto algorithms we support
-+     */
-+    if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
-+        put_dev_crypto(fd);
-+        ENGINE_free(engine);
-+        return;
-+    }
-+    put_dev_crypto(fd);
-+
-+    if (!ENGINE_set_id(engine, "cryptodev") ||
-+        !ENGINE_set_name(engine, "BSD cryptodev engine") ||
-+        !ENGINE_set_destroy_function(engine, cryptodev_engine_destroy) ||
-+        !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
-+        !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
-+        !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
-+        !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
-+        ENGINE_free(engine);
-+        return;
-+    }
-+
-+    cryptodev_rsa = RSA_meth_dup(RSA_PKCS1_OpenSSL());
-+    if (cryptodev_rsa != NULL) {
-+        RSA_meth_set1_name(cryptodev_rsa, "cryptodev RSA method");
-+        RSA_meth_set_flags(cryptodev_rsa, 0);
-+        if (ENGINE_set_RSA(engine, cryptodev_rsa)) {
-+            if (cryptodev_asymfeat & CRF_MOD_EXP) {
-+                RSA_meth_set_bn_mod_exp(cryptodev_rsa, cryptodev_bn_mod_exp);
-+                if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
-+                    RSA_meth_set_mod_exp(cryptodev_rsa, cryptodev_rsa_mod_exp);
-+                else
-+                    RSA_meth_set_mod_exp(cryptodev_rsa,
-+                                         cryptodev_rsa_nocrt_mod_exp);
-+            }
-+        }
-+    } else {
-+        ENGINE_free(engine);
-+        return;
-+    }
-+
-+#ifndef OPENSSL_NO_DSA
-+    cryptodev_dsa = DSA_meth_dup(DSA_OpenSSL());
-+    if (cryptodev_dsa != NULL) {
-+        DSA_meth_set1_name(cryptodev_dsa, "cryptodev DSA method");
-+        DSA_meth_set_flags(cryptodev_dsa, 0);
-+        if (ENGINE_set_DSA(engine, cryptodev_dsa)) {
-+            if (cryptodev_asymfeat & CRF_DSA_SIGN)
-+                DSA_meth_set_sign(cryptodev_dsa, cryptodev_dsa_do_sign);
-+            if (cryptodev_asymfeat & CRF_MOD_EXP) {
-+                DSA_meth_set_bn_mod_exp(cryptodev_dsa,
-+                                        cryptodev_dsa_bn_mod_exp);
-+                DSA_meth_set_mod_exp(cryptodev_dsa, cryptodev_dsa_dsa_mod_exp);
-+            }
-+            if (cryptodev_asymfeat & CRF_DSA_VERIFY)
-+                DSA_meth_set_verify(cryptodev_dsa, cryptodev_dsa_verify);
-+        }
-+    } else {
-+        ENGINE_free(engine);
-+        return;
-+    }
-+#endif
-+
-+#ifndef OPENSSL_NO_DH
-+    cryptodev_dh = DH_meth_dup(DH_OpenSSL());
-+    if (cryptodev_dh != NULL) {
-+        DH_meth_set1_name(cryptodev_dh, "cryptodev DH method");
-+        DH_meth_set_flags(cryptodev_dh, 0);
-+        if (ENGINE_set_DH(engine, cryptodev_dh)) {
-+            if (cryptodev_asymfeat & CRF_MOD_EXP) {
-+                DH_meth_set_bn_mod_exp(cryptodev_dh, cryptodev_mod_exp_dh);
-+                if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
-+                    DH_meth_set_compute_key(cryptodev_dh,
-+                                            cryptodev_dh_compute_key);
-+            }
-+        }
-+    } else {
-+        ENGINE_free(engine);
-+        return;
-+    }
-+#endif
-+
-+    ENGINE_add(engine);
-+    ENGINE_free(engine);
-+    ERR_clear_error();
-+}
-+
-+#endif                          /* HAVE_CRYPTODEV */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_ctrl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_ctrl.c
-new file mode 100644
-index 0000000..7925f4f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_ctrl.c
-@@ -0,0 +1,338 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+
-+/*
-+ * When querying a ENGINE-specific control command's 'description', this
-+ * string is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL.
-+ */
-+static const char *int_no_description = "";
-+
-+/*
-+ * These internal functions handle 'CMD'-related control commands when the
-+ * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
-+ * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag.
-+ */
-+
-+static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
-+{
-+    if ((defn->cmd_num == 0) || (defn->cmd_name == NULL))
-+        return 1;
-+    return 0;
-+}
-+
-+static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
-+{
-+    int idx = 0;
-+    while (!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0)) {
-+        idx++;
-+        defn++;
-+    }
-+    if (int_ctrl_cmd_is_null(defn))
-+        /* The given name wasn't found */
-+        return -1;
-+    return idx;
-+}
-+
-+static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
-+{
-+    int idx = 0;
-+    /*
-+     * NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
-+     * our searches don't need to take any longer than necessary.
-+     */
-+    while (!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num)) {
-+        idx++;
-+        defn++;
-+    }
-+    if (defn->cmd_num == num)
-+        return idx;
-+    /* The given cmd_num wasn't found */
-+    return -1;
-+}
-+
-+static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
-+                           void (*f) (void))
-+{
-+    int idx;
-+    char *s = (char *)p;
-+    /* Take care of the easy one first (eg. it requires no searches) */
-+    if (cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) {
-+        if ((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
-+            return 0;
-+        return e->cmd_defns->cmd_num;
-+    }
-+    /* One or two commands require that "p" be a valid string buffer */
-+    if ((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
-+        (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
-+        (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) {
-+        if (s == NULL) {
-+            ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ERR_R_PASSED_NULL_PARAMETER);
-+            return -1;
-+        }
-+    }
-+    /* Now handle cmd_name -> cmd_num conversion */
-+    if (cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) {
-+        if ((e->cmd_defns == NULL)
-+            || ((idx = int_ctrl_cmd_by_name(e->cmd_defns, s)) < 0)) {
-+            ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NAME);
-+            return -1;
-+        }
-+        return e->cmd_defns[idx].cmd_num;
-+    }
-+    /*
-+     * For the rest of the commands, the 'long' argument must specify a valid
-+     * command number - so we need to conduct a search.
-+     */
-+    if ((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
-+                                                              (unsigned int)
-+                                                              i)) < 0)) {
-+        ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NUMBER);
-+        return -1;
-+    }
-+    /* Now the logic splits depending on command type */
-+    switch (cmd) {
-+    case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
-+        idx++;
-+        if (int_ctrl_cmd_is_null(e->cmd_defns + idx))
-+            /* end-of-list */
-+            return 0;
-+        else
-+            return e->cmd_defns[idx].cmd_num;
-+    case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
-+        return strlen(e->cmd_defns[idx].cmd_name);
-+    case ENGINE_CTRL_GET_NAME_FROM_CMD:
-+        return BIO_snprintf(s, strlen(e->cmd_defns[idx].cmd_name) + 1,
-+                            "%s", e->cmd_defns[idx].cmd_name);
-+    case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
-+        if (e->cmd_defns[idx].cmd_desc)
-+            return strlen(e->cmd_defns[idx].cmd_desc);
-+        return strlen(int_no_description);
-+    case ENGINE_CTRL_GET_DESC_FROM_CMD:
-+        if (e->cmd_defns[idx].cmd_desc)
-+            return BIO_snprintf(s,
-+                                strlen(e->cmd_defns[idx].cmd_desc) + 1,
-+                                "%s", e->cmd_defns[idx].cmd_desc);
-+        return BIO_snprintf(s, strlen(int_no_description) + 1, "%s",
-+                            int_no_description);
-+    case ENGINE_CTRL_GET_CMD_FLAGS:
-+        return e->cmd_defns[idx].cmd_flags;
-+    }
-+    /* Shouldn't really be here ... */
-+    ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INTERNAL_LIST_ERROR);
-+    return -1;
-+}
-+
-+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
-+{
-+    int ctrl_exists, ref_exists;
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    ref_exists = ((e->struct_ref > 0) ? 1 : 0);
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
-+    if (!ref_exists) {
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_REFERENCE);
-+        return 0;
-+    }
-+    /*
-+     * Intercept any "root-level" commands before trying to hand them on to
-+     * ctrl() handlers.
-+     */
-+    switch (cmd) {
-+    case ENGINE_CTRL_HAS_CTRL_FUNCTION:
-+        return ctrl_exists;
-+    case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
-+    case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
-+    case ENGINE_CTRL_GET_CMD_FROM_NAME:
-+    case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
-+    case ENGINE_CTRL_GET_NAME_FROM_CMD:
-+    case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
-+    case ENGINE_CTRL_GET_DESC_FROM_CMD:
-+    case ENGINE_CTRL_GET_CMD_FLAGS:
-+        if (ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
-+            return int_ctrl_helper(e, cmd, i, p, f);
-+        if (!ctrl_exists) {
-+            ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION);
-+            /*
-+             * For these cmd-related functions, failure is indicated by a -1
-+             * return value (because 0 is used as a valid return in some
-+             * places).
-+             */
-+            return -1;
-+        }
-+    default:
-+        break;
-+    }
-+    /* Anything else requires a ctrl() handler to exist. */
-+    if (!ctrl_exists) {
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION);
-+        return 0;
-+    }
-+    return e->ctrl(e, cmd, i, p, f);
-+}
-+
-+int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
-+{
-+    int flags;
-+    if ((flags =
-+         ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0) {
-+        ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
-+                  ENGINE_R_INVALID_CMD_NUMBER);
-+        return 0;
-+    }
-+    if (!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
-+        !(flags & ENGINE_CMD_FLAG_NUMERIC) &&
-+        !(flags & ENGINE_CMD_FLAG_STRING))
-+        return 0;
-+    return 1;
-+}
-+
-+int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
-+                    long i, void *p, void (*f) (void), int cmd_optional)
-+{
-+    int num;
-+
-+    if (e == NULL || cmd_name == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    if (e->ctrl == NULL
-+        || (num = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FROM_NAME,
-+                              0, (void *)cmd_name, NULL)) <= 0) {
-+        /*
-+         * If the command didn't *have* to be supported, we fake success.
-+         * This allows certain settings to be specified for multiple ENGINEs
-+         * and only require a change of ENGINE id (without having to
-+         * selectively apply settings). Eg. changing from a hardware device
-+         * back to the regular software ENGINE without editing the config
-+         * file, etc.
-+         */
-+        if (cmd_optional) {
-+            ERR_clear_error();
-+            return 1;
-+        }
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ENGINE_R_INVALID_CMD_NAME);
-+        return 0;
-+    }
-+    /*
-+     * Force the result of the control command to 0 or 1, for the reasons
-+     * mentioned before.
-+     */
-+    if (ENGINE_ctrl(e, num, i, p, f) > 0)
-+        return 1;
-+    return 0;
-+}
-+
-+int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
-+                           int cmd_optional)
-+{
-+    int num, flags;
-+    long l;
-+    char *ptr;
-+
-+    if (e == NULL || cmd_name == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    if (e->ctrl == NULL
-+        || (num = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FROM_NAME,
-+                              0, (void *)cmd_name, NULL)) <= 0) {
-+        /*
-+         * If the command didn't *have* to be supported, we fake success.
-+         * This allows certain settings to be specified for multiple ENGINEs
-+         * and only require a change of ENGINE id (without having to
-+         * selectively apply settings). Eg. changing from a hardware device
-+         * back to the regular software ENGINE without editing the config
-+         * file, etc.
-+         */
-+        if (cmd_optional) {
-+            ERR_clear_error();
-+            return 1;
-+        }
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, ENGINE_R_INVALID_CMD_NAME);
-+        return 0;
-+    }
-+    if (!ENGINE_cmd_is_executable(e, num)) {
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
-+                  ENGINE_R_CMD_NOT_EXECUTABLE);
-+        return 0;
-+    }
-+
-+    flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL);
-+    if (flags < 0) {
-+        /*
-+         * Shouldn't happen, given that ENGINE_cmd_is_executable() returned
-+         * success.
-+         */
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
-+                  ENGINE_R_INTERNAL_LIST_ERROR);
-+        return 0;
-+    }
-+    /*
-+     * If the command takes no input, there must be no input. And vice versa.
-+     */
-+    if (flags & ENGINE_CMD_FLAG_NO_INPUT) {
-+        if (arg != NULL) {
-+            ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
-+                      ENGINE_R_COMMAND_TAKES_NO_INPUT);
-+            return 0;
-+        }
-+        /*
-+         * We deliberately force the result of ENGINE_ctrl() to 0 or 1 rather
-+         * than returning it as "return data". This is to ensure usage of
-+         * these commands is consistent across applications and that certain
-+         * applications don't understand it one way, and others another.
-+         */
-+        if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
-+            return 1;
-+        return 0;
-+    }
-+    /* So, we require input */
-+    if (arg == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
-+                  ENGINE_R_COMMAND_TAKES_INPUT);
-+        return 0;
-+    }
-+    /* If it takes string input, that's easy */
-+    if (flags & ENGINE_CMD_FLAG_STRING) {
-+        /* Same explanation as above */
-+        if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
-+            return 1;
-+        return 0;
-+    }
-+    /*
-+     * If it doesn't take numeric either, then it is unsupported for use in a
-+     * config-setting situation, which is what this function is for. This
-+     * should never happen though, because ENGINE_cmd_is_executable() was
-+     * used.
-+     */
-+    if (!(flags & ENGINE_CMD_FLAG_NUMERIC)) {
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
-+                  ENGINE_R_INTERNAL_LIST_ERROR);
-+        return 0;
-+    }
-+    l = strtol(arg, &ptr, 10);
-+    if ((arg == ptr) || (*ptr != '\0')) {
-+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
-+                  ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
-+        return 0;
-+    }
-+    /*
-+     * Force the result of the control command to 0 or 1, for the reasons
-+     * mentioned before.
-+     */
-+    if (ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
-+        return 1;
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_dyn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_dyn.c
-new file mode 100644
-index 0000000..843226c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_dyn.c
-@@ -0,0 +1,510 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+#include "internal/dso.h"
-+#include 
-+
-+/*
-+ * Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE
-+ * loader should implement the hook-up functions with the following
-+ * prototypes.
-+ */
-+
-+/* Our ENGINE handlers */
-+static int dynamic_init(ENGINE *e);
-+static int dynamic_finish(ENGINE *e);
-+static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p,
-+                        void (*f) (void));
-+/* Predeclare our context type */
-+typedef struct st_dynamic_data_ctx dynamic_data_ctx;
-+/* The implementation for the important control command */
-+static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
-+
-+#define DYNAMIC_CMD_SO_PATH             ENGINE_CMD_BASE
-+#define DYNAMIC_CMD_NO_VCHECK           (ENGINE_CMD_BASE + 1)
-+#define DYNAMIC_CMD_ID                  (ENGINE_CMD_BASE + 2)
-+#define DYNAMIC_CMD_LIST_ADD            (ENGINE_CMD_BASE + 3)
-+#define DYNAMIC_CMD_DIR_LOAD            (ENGINE_CMD_BASE + 4)
-+#define DYNAMIC_CMD_DIR_ADD             (ENGINE_CMD_BASE + 5)
-+#define DYNAMIC_CMD_LOAD                (ENGINE_CMD_BASE + 6)
-+
-+/* The constants used when creating the ENGINE */
-+static const char *engine_dynamic_id = "dynamic";
-+static const char *engine_dynamic_name = "Dynamic engine loading support";
-+static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
-+    {DYNAMIC_CMD_SO_PATH,
-+     "SO_PATH",
-+     "Specifies the path to the new ENGINE shared library",
-+     ENGINE_CMD_FLAG_STRING},
-+    {DYNAMIC_CMD_NO_VCHECK,
-+     "NO_VCHECK",
-+     "Specifies to continue even if version checking fails (boolean)",
-+     ENGINE_CMD_FLAG_NUMERIC},
-+    {DYNAMIC_CMD_ID,
-+     "ID",
-+     "Specifies an ENGINE id name for loading",
-+     ENGINE_CMD_FLAG_STRING},
-+    {DYNAMIC_CMD_LIST_ADD,
-+     "LIST_ADD",
-+     "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
-+     ENGINE_CMD_FLAG_NUMERIC},
-+    {DYNAMIC_CMD_DIR_LOAD,
-+     "DIR_LOAD",
-+     "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
-+     ENGINE_CMD_FLAG_NUMERIC},
-+    {DYNAMIC_CMD_DIR_ADD,
-+     "DIR_ADD",
-+     "Adds a directory from which ENGINEs can be loaded",
-+     ENGINE_CMD_FLAG_STRING},
-+    {DYNAMIC_CMD_LOAD,
-+     "LOAD",
-+     "Load up the ENGINE specified by other settings",
-+     ENGINE_CMD_FLAG_NO_INPUT},
-+    {0, NULL, NULL, 0}
-+};
-+
-+/*
-+ * Loading code stores state inside the ENGINE structure via the "ex_data"
-+ * element. We load all our state into a single structure and use that as a
-+ * single context in the "ex_data" stack.
-+ */
-+struct st_dynamic_data_ctx {
-+    /* The DSO object we load that supplies the ENGINE code */
-+    DSO *dynamic_dso;
-+    /*
-+     * The function pointer to the version checking shared library function
-+     */
-+    dynamic_v_check_fn v_check;
-+    /*
-+     * The function pointer to the engine-binding shared library function
-+     */
-+    dynamic_bind_engine bind_engine;
-+    /* The default name/path for loading the shared library */
-+    char *DYNAMIC_LIBNAME;
-+    /* Whether to continue loading on a version check failure */
-+    int no_vcheck;
-+    /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */
-+    char *engine_id;
-+    /*
-+     * If non-zero, a successfully loaded ENGINE should be added to the
-+     * internal ENGINE list. If 2, the add must succeed or the entire load
-+     * should fail.
-+     */
-+    int list_add_value;
-+    /* The symbol name for the version checking function */
-+    const char *DYNAMIC_F1;
-+    /* The symbol name for the "initialise ENGINE structure" function */
-+    const char *DYNAMIC_F2;
-+    /*
-+     * Whether to never use 'dirs', use 'dirs' as a fallback, or only use
-+     * 'dirs' for loading. Default is to use 'dirs' as a fallback.
-+     */
-+    int dir_load;
-+    /* A stack of directories from which ENGINEs could be loaded */
-+    STACK_OF(OPENSSL_STRING) *dirs;
-+};
-+
-+/*
-+ * This is the "ex_data" index we obtain and reserve for use with our context
-+ * structure.
-+ */
-+static int dynamic_ex_data_idx = -1;
-+
-+static void int_free_str(char *s)
-+{
-+    OPENSSL_free(s);
-+}
-+
-+/*
-+ * Because our ex_data element may or may not get allocated depending on
-+ * whether a "first-use" occurs before the ENGINE is freed, we have a memory
-+ * leak problem to solve. We can't declare a "new" handler for the ex_data as
-+ * we don't want a dynamic_data_ctx in *all* ENGINE structures of all types
-+ * (this is a bug in the design of CRYPTO_EX_DATA). As such, we just declare
-+ * a "free" handler and that will get called if an ENGINE is being destroyed
-+ * and there was an ex_data element corresponding to our context type.
-+ */
-+static void dynamic_data_ctx_free_func(void *parent, void *ptr,
-+                                       CRYPTO_EX_DATA *ad, int idx, long argl,
-+                                       void *argp)
-+{
-+    if (ptr) {
-+        dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr;
-+        DSO_free(ctx->dynamic_dso);
-+        OPENSSL_free(ctx->DYNAMIC_LIBNAME);
-+        OPENSSL_free(ctx->engine_id);
-+        sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
-+        OPENSSL_free(ctx);
-+    }
-+}
-+
-+/*
-+ * Construct the per-ENGINE context. We create it blindly and then use a lock
-+ * to check for a race - if so, all but one of the threads "racing" will have
-+ * wasted their time. The alternative involves creating everything inside the
-+ * lock which is far worse.
-+ */
-+static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
-+{
-+    dynamic_data_ctx *c = OPENSSL_zalloc(sizeof(*c));
-+    int ret = 1;
-+
-+    if (c == NULL) {
-+        ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    c->dirs = sk_OPENSSL_STRING_new_null();
-+    if (c->dirs == NULL) {
-+        ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(c);
-+        return 0;
-+    }
-+    c->DYNAMIC_F1 = "v_check";
-+    c->DYNAMIC_F2 = "bind_engine";
-+    c->dir_load = 1;
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    if ((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
-+                                                       dynamic_ex_data_idx))
-+        == NULL) {
-+        /* Good, we're the first */
-+        ret = ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
-+        if (ret) {
-+            *ctx = c;
-+            c = NULL;
-+        }
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    /*
-+     * If we lost the race to set the context, c is non-NULL and *ctx is the
-+     * context of the thread that won.
-+     */
-+    if (c)
-+        sk_OPENSSL_STRING_free(c->dirs);
-+    OPENSSL_free(c);
-+    return ret;
-+}
-+
-+/*
-+ * This function retrieves the context structure from an ENGINE's "ex_data",
-+ * or if it doesn't exist yet, sets it up.
-+ */
-+static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e)
-+{
-+    dynamic_data_ctx *ctx;
-+    if (dynamic_ex_data_idx < 0) {
-+        /*
-+         * Create and register the ENGINE ex_data, and associate our "free"
-+         * function with it to ensure any allocated contexts get freed when
-+         * an ENGINE goes underground.
-+         */
-+        int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
-+                                              dynamic_data_ctx_free_func);
-+        if (new_idx == -1) {
-+            ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX, ENGINE_R_NO_INDEX);
-+            return NULL;
-+        }
-+        CRYPTO_THREAD_write_lock(global_engine_lock);
-+        /* Avoid a race by checking again inside this lock */
-+        if (dynamic_ex_data_idx < 0) {
-+            /* Good, someone didn't beat us to it */
-+            dynamic_ex_data_idx = new_idx;
-+            new_idx = -1;
-+        }
-+        CRYPTO_THREAD_unlock(global_engine_lock);
-+        /*
-+         * In theory we could "give back" the index here if (new_idx>-1), but
-+         * it's not possible and wouldn't gain us much if it were.
-+         */
-+    }
-+    ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
-+    /* Check if the context needs to be created */
-+    if ((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
-+        /* "set_data" will set errors if necessary */
-+        return NULL;
-+    return ctx;
-+}
-+
-+static ENGINE *engine_dynamic(void)
-+{
-+    ENGINE *ret = ENGINE_new();
-+    if (ret == NULL)
-+        return NULL;
-+    if (!ENGINE_set_id(ret, engine_dynamic_id) ||
-+        !ENGINE_set_name(ret, engine_dynamic_name) ||
-+        !ENGINE_set_init_function(ret, dynamic_init) ||
-+        !ENGINE_set_finish_function(ret, dynamic_finish) ||
-+        !ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
-+        !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
-+        !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns)) {
-+        ENGINE_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+void engine_load_dynamic_int(void)
-+{
-+    ENGINE *toadd = engine_dynamic();
-+    if (!toadd)
-+        return;
-+    ENGINE_add(toadd);
-+    /*
-+     * If the "add" worked, it gets a structural reference. So either way, we
-+     * release our just-created reference.
-+     */
-+    ENGINE_free(toadd);
-+    /*
-+     * If the "add" didn't work, it was probably a conflict because it was
-+     * already added (eg. someone calling ENGINE_load_blah then calling
-+     * ENGINE_load_builtin_engines() perhaps).
-+     */
-+    ERR_clear_error();
-+}
-+
-+static int dynamic_init(ENGINE *e)
-+{
-+    /*
-+     * We always return failure - the "dynamic" engine itself can't be used
-+     * for anything.
-+     */
-+    return 0;
-+}
-+
-+static int dynamic_finish(ENGINE *e)
-+{
-+    /*
-+     * This should never be called on account of "dynamic_init" always
-+     * failing.
-+     */
-+    return 0;
-+}
-+
-+static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
-+{
-+    dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
-+    int initialised;
-+
-+    if (!ctx) {
-+        ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_NOT_LOADED);
-+        return 0;
-+    }
-+    initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
-+    /* All our control commands require the ENGINE to be uninitialised */
-+    if (initialised) {
-+        ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_ALREADY_LOADED);
-+        return 0;
-+    }
-+    switch (cmd) {
-+    case DYNAMIC_CMD_SO_PATH:
-+        /* a NULL 'p' or a string of zero-length is the same thing */
-+        if (p && (strlen((const char *)p) < 1))
-+            p = NULL;
-+        OPENSSL_free(ctx->DYNAMIC_LIBNAME);
-+        if (p)
-+            ctx->DYNAMIC_LIBNAME = OPENSSL_strdup(p);
-+        else
-+            ctx->DYNAMIC_LIBNAME = NULL;
-+        return (ctx->DYNAMIC_LIBNAME ? 1 : 0);
-+    case DYNAMIC_CMD_NO_VCHECK:
-+        ctx->no_vcheck = ((i == 0) ? 0 : 1);
-+        return 1;
-+    case DYNAMIC_CMD_ID:
-+        /* a NULL 'p' or a string of zero-length is the same thing */
-+        if (p && (strlen((const char *)p) < 1))
-+            p = NULL;
-+        OPENSSL_free(ctx->engine_id);
-+        if (p)
-+            ctx->engine_id = OPENSSL_strdup(p);
-+        else
-+            ctx->engine_id = NULL;
-+        return (ctx->engine_id ? 1 : 0);
-+    case DYNAMIC_CMD_LIST_ADD:
-+        if ((i < 0) || (i > 2)) {
-+            ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT);
-+            return 0;
-+        }
-+        ctx->list_add_value = (int)i;
-+        return 1;
-+    case DYNAMIC_CMD_LOAD:
-+        return dynamic_load(e, ctx);
-+    case DYNAMIC_CMD_DIR_LOAD:
-+        if ((i < 0) || (i > 2)) {
-+            ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT);
-+            return 0;
-+        }
-+        ctx->dir_load = (int)i;
-+        return 1;
-+    case DYNAMIC_CMD_DIR_ADD:
-+        /* a NULL 'p' or a string of zero-length is the same thing */
-+        if (!p || (strlen((const char *)p) < 1)) {
-+            ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT);
-+            return 0;
-+        }
-+        {
-+            char *tmp_str = OPENSSL_strdup(p);
-+            if (tmp_str == NULL) {
-+                ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ERR_R_MALLOC_FAILURE);
-+                return 0;
-+            }
-+            if (!sk_OPENSSL_STRING_push(ctx->dirs, tmp_str)) {
-+                OPENSSL_free(tmp_str);
-+                ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ERR_R_MALLOC_FAILURE);
-+                return 0;
-+            }
-+        }
-+        return 1;
-+    default:
-+        break;
-+    }
-+    ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
-+    return 0;
-+}
-+
-+static int int_load(dynamic_data_ctx *ctx)
-+{
-+    int num, loop;
-+    /* Unless told not to, try a direct load */
-+    if ((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
-+                                          ctx->DYNAMIC_LIBNAME, NULL,
-+                                          0)) != NULL)
-+        return 1;
-+    /* If we're not allowed to use 'dirs' or we have none, fail */
-+    if (!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
-+        return 0;
-+    for (loop = 0; loop < num; loop++) {
-+        const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
-+        char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
-+        if (!merge)
-+            return 0;
-+        if (DSO_load(ctx->dynamic_dso, merge, NULL, 0)) {
-+            /* Found what we're looking for */
-+            OPENSSL_free(merge);
-+            return 1;
-+        }
-+        OPENSSL_free(merge);
-+    }
-+    return 0;
-+}
-+
-+static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
-+{
-+    ENGINE cpy;
-+    dynamic_fns fns;
-+
-+    if (ctx->dynamic_dso == NULL)
-+        ctx->dynamic_dso = DSO_new();
-+    if (ctx->dynamic_dso == NULL)
-+        return 0;
-+    if (!ctx->DYNAMIC_LIBNAME) {
-+        if (!ctx->engine_id)
-+            return 0;
-+        DSO_ctrl(ctx->dynamic_dso, DSO_CTRL_SET_FLAGS,
-+                 DSO_FLAG_NAME_TRANSLATION_EXT_ONLY, NULL);
-+        ctx->DYNAMIC_LIBNAME =
-+            DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id);
-+    }
-+    if (!int_load(ctx)) {
-+        ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_NOT_FOUND);
-+        DSO_free(ctx->dynamic_dso);
-+        ctx->dynamic_dso = NULL;
-+        return 0;
-+    }
-+    /* We have to find a bind function otherwise it'll always end badly */
-+    if (!
-+        (ctx->bind_engine =
-+         (dynamic_bind_engine) DSO_bind_func(ctx->dynamic_dso,
-+                                             ctx->DYNAMIC_F2))) {
-+        ctx->bind_engine = NULL;
-+        DSO_free(ctx->dynamic_dso);
-+        ctx->dynamic_dso = NULL;
-+        ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_FAILURE);
-+        return 0;
-+    }
-+    /* Do we perform version checking? */
-+    if (!ctx->no_vcheck) {
-+        unsigned long vcheck_res = 0;
-+        /*
-+         * Now we try to find a version checking function and decide how to
-+         * cope with failure if/when it fails.
-+         */
-+        ctx->v_check =
-+            (dynamic_v_check_fn) DSO_bind_func(ctx->dynamic_dso,
-+                                               ctx->DYNAMIC_F1);
-+        if (ctx->v_check)
-+            vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
-+        /*
-+         * We fail if the version checker veto'd the load *or* if it is
-+         * deferring to us (by returning its version) and we think it is too
-+         * old.
-+         */
-+        if (vcheck_res < OSSL_DYNAMIC_OLDEST) {
-+            /* Fail */
-+            ctx->bind_engine = NULL;
-+            ctx->v_check = NULL;
-+            DSO_free(ctx->dynamic_dso);
-+            ctx->dynamic_dso = NULL;
-+            ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
-+                      ENGINE_R_VERSION_INCOMPATIBILITY);
-+            return 0;
-+        }
-+    }
-+    /*
-+     * First binary copy the ENGINE structure so that we can roll back if the
-+     * hand-over fails
-+     */
-+    memcpy(&cpy, e, sizeof(ENGINE));
-+    /*
-+     * Provide the ERR, "ex_data", memory, and locking callbacks so the
-+     * loaded library uses our state rather than its own. FIXME: As noted in
-+     * engine.h, much of this would be simplified if each area of code
-+     * provided its own "summary" structure of all related callbacks. It
-+     * would also increase opaqueness.
-+     */
-+    fns.static_state = ENGINE_get_static_state();
-+    CRYPTO_get_mem_functions(&fns.mem_fns.malloc_fn, &fns.mem_fns.realloc_fn,
-+                             &fns.mem_fns.free_fn);
-+    /*
-+     * Now that we've loaded the dynamic engine, make sure no "dynamic"
-+     * ENGINE elements will show through.
-+     */
-+    engine_set_all_null(e);
-+
-+    /* Try to bind the ENGINE onto our own ENGINE structure */
-+    if (!ctx->bind_engine(e, ctx->engine_id, &fns)) {
-+        ctx->bind_engine = NULL;
-+        ctx->v_check = NULL;
-+        DSO_free(ctx->dynamic_dso);
-+        ctx->dynamic_dso = NULL;
-+        ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_INIT_FAILED);
-+        /* Copy the original ENGINE structure back */
-+        memcpy(e, &cpy, sizeof(ENGINE));
-+        return 0;
-+    }
-+    /* Do we try to add this ENGINE to the internal list too? */
-+    if (ctx->list_add_value > 0) {
-+        if (!ENGINE_add(e)) {
-+            /* Do we tolerate this or fail? */
-+            if (ctx->list_add_value > 1) {
-+                /*
-+                 * Fail - NB: By this time, it's too late to rollback, and
-+                 * trying to do so allows the bind_engine() code to have
-+                 * created leaks. We just have to fail where we are, after
-+                 * the ENGINE has changed.
-+                 */
-+                ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
-+                          ENGINE_R_CONFLICTING_ENGINE_ID);
-+                return 0;
-+            }
-+            /* Tolerate */
-+            ERR_clear_error();
-+        }
-+    }
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_err.c
-new file mode 100644
-index 0000000..5e9d16f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_err.c
-@@ -0,0 +1,123 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason)
-+
-+static ERR_STRING_DATA ENGINE_str_functs[] = {
-+    {ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "dynamic_ctrl"},
-+    {ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "dynamic_get_data_ctx"},
-+    {ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "dynamic_load"},
-+    {ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "dynamic_set_data_ctx"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_CTRL), "ENGINE_ctrl"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_GET_FIRST), "ENGINE_get_first"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_GET_LAST), "ENGINE_get_last"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH),
-+     "ENGINE_get_pkey_asn1_meth"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "engine_list_add"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "engine_list_remove"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT),
-+     "ENGINE_load_ssl_client_cert"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR),
-+     "ENGINE_pkey_asn1_find_str"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING),
-+     "ENGINE_set_default_string"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_SET_ID), "ENGINE_set_id"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "engine_table_register"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "engine_unlocked_finish"},
-+    {ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"},
-+    {ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "int_ctrl_helper"},
-+    {ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "int_engine_configure"},
-+    {ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "int_engine_module_init"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA ENGINE_str_reasons[] = {
-+    {ERR_REASON(ENGINE_R_ALREADY_LOADED), "already loaded"},
-+    {ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER),
-+     "argument is not a number"},
-+    {ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE), "cmd not executable"},
-+    {ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT), "command takes input"},
-+    {ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT), "command takes no input"},
-+    {ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID), "conflicting engine id"},
-+    {ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED),
-+     "ctrl command not implemented"},
-+    {ERR_REASON(ENGINE_R_DSO_FAILURE), "DSO failure"},
-+    {ERR_REASON(ENGINE_R_DSO_NOT_FOUND), "dso not found"},
-+    {ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR), "engines section error"},
-+    {ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),
-+     "engine configuration error"},
-+    {ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST), "engine is not in the list"},
-+    {ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR), "engine section error"},
-+    {ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),
-+     "failed loading private key"},
-+    {ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY),
-+     "failed loading public key"},
-+    {ERR_REASON(ENGINE_R_FINISH_FAILED), "finish failed"},
-+    {ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING), "'id' or 'name' missing"},
-+    {ERR_REASON(ENGINE_R_INIT_FAILED), "init failed"},
-+    {ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR), "internal list error"},
-+    {ERR_REASON(ENGINE_R_INVALID_ARGUMENT), "invalid argument"},
-+    {ERR_REASON(ENGINE_R_INVALID_CMD_NAME), "invalid cmd name"},
-+    {ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER), "invalid cmd number"},
-+    {ERR_REASON(ENGINE_R_INVALID_INIT_VALUE), "invalid init value"},
-+    {ERR_REASON(ENGINE_R_INVALID_STRING), "invalid string"},
-+    {ERR_REASON(ENGINE_R_NOT_INITIALISED), "not initialised"},
-+    {ERR_REASON(ENGINE_R_NOT_LOADED), "not loaded"},
-+    {ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION), "no control function"},
-+    {ERR_REASON(ENGINE_R_NO_INDEX), "no index"},
-+    {ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION), "no load function"},
-+    {ERR_REASON(ENGINE_R_NO_REFERENCE), "no reference"},
-+    {ERR_REASON(ENGINE_R_NO_SUCH_ENGINE), "no such engine"},
-+    {ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER), "unimplemented cipher"},
-+    {ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST), "unimplemented digest"},
-+    {ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),
-+     "unimplemented public key method"},
-+    {ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY), "version incompatibility"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_ENGINE_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, ENGINE_str_functs);
-+        ERR_load_strings(0, ENGINE_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_fat.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_fat.c
-new file mode 100644
-index 0000000..631aa39
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_fat.c
-@@ -0,0 +1,127 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * ECDH support in OpenSSL originally developed by
-+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
-+ */
-+
-+#include "eng_int.h"
-+#include 
-+
-+int ENGINE_set_default(ENGINE *e, unsigned int flags)
-+{
-+    if ((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
-+        return 0;
-+    if ((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
-+        return 0;
-+#ifndef OPENSSL_NO_RSA
-+    if ((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e))
-+        return 0;
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    if ((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e))
-+        return 0;
-+#endif
-+#ifndef OPENSSL_NO_DH
-+    if ((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e))
-+        return 0;
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    if ((flags & ENGINE_METHOD_EC) && !ENGINE_set_default_EC(e))
-+        return 0;
-+#endif
-+    if ((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
-+        return 0;
-+    if ((flags & ENGINE_METHOD_PKEY_METHS)
-+        && !ENGINE_set_default_pkey_meths(e))
-+        return 0;
-+    if ((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
-+        && !ENGINE_set_default_pkey_asn1_meths(e))
-+        return 0;
-+    return 1;
-+}
-+
-+/* Set default algorithms using a string */
-+
-+static int int_def_cb(const char *alg, int len, void *arg)
-+{
-+    unsigned int *pflags = arg;
-+    if (alg == NULL)
-+        return 0;
-+    if (strncmp(alg, "ALL", len) == 0)
-+        *pflags |= ENGINE_METHOD_ALL;
-+    else if (strncmp(alg, "RSA", len) == 0)
-+        *pflags |= ENGINE_METHOD_RSA;
-+    else if (strncmp(alg, "DSA", len) == 0)
-+        *pflags |= ENGINE_METHOD_DSA;
-+    else if (strncmp(alg, "DH", len) == 0)
-+        *pflags |= ENGINE_METHOD_DH;
-+    else if (strncmp(alg, "EC", len) == 0)
-+        *pflags |= ENGINE_METHOD_EC;
-+    else if (strncmp(alg, "RAND", len) == 0)
-+        *pflags |= ENGINE_METHOD_RAND;
-+    else if (strncmp(alg, "CIPHERS", len) == 0)
-+        *pflags |= ENGINE_METHOD_CIPHERS;
-+    else if (strncmp(alg, "DIGESTS", len) == 0)
-+        *pflags |= ENGINE_METHOD_DIGESTS;
-+    else if (strncmp(alg, "PKEY", len) == 0)
-+        *pflags |= ENGINE_METHOD_PKEY_METHS | ENGINE_METHOD_PKEY_ASN1_METHS;
-+    else if (strncmp(alg, "PKEY_CRYPTO", len) == 0)
-+        *pflags |= ENGINE_METHOD_PKEY_METHS;
-+    else if (strncmp(alg, "PKEY_ASN1", len) == 0)
-+        *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
-+    else
-+        return 0;
-+    return 1;
-+}
-+
-+int ENGINE_set_default_string(ENGINE *e, const char *def_list)
-+{
-+    unsigned int flags = 0;
-+    if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags)) {
-+        ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING,
-+                  ENGINE_R_INVALID_STRING);
-+        ERR_add_error_data(2, "str=", def_list);
-+        return 0;
-+    }
-+    return ENGINE_set_default(e, flags);
-+}
-+
-+int ENGINE_register_complete(ENGINE *e)
-+{
-+    ENGINE_register_ciphers(e);
-+    ENGINE_register_digests(e);
-+#ifndef OPENSSL_NO_RSA
-+    ENGINE_register_RSA(e);
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    ENGINE_register_DSA(e);
-+#endif
-+#ifndef OPENSSL_NO_DH
-+    ENGINE_register_DH(e);
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    ENGINE_register_EC(e);
-+#endif
-+    ENGINE_register_RAND(e);
-+    ENGINE_register_pkey_meths(e);
-+    return 1;
-+}
-+
-+int ENGINE_register_all_complete(void)
-+{
-+    ENGINE *e;
-+
-+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
-+        if (!(e->flags & ENGINE_FLAGS_NO_REGISTER_ALL))
-+            ENGINE_register_complete(e);
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_init.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_init.c
-new file mode 100644
-index 0000000..8be7c6f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_init.c
-@@ -0,0 +1,108 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+
-+/*
-+ * Initialise a engine type for use (or up its functional reference count if
-+ * it's already in use). This version is only used internally.
-+ */
-+int engine_unlocked_init(ENGINE *e)
-+{
-+    int to_return = 1;
-+
-+    if ((e->funct_ref == 0) && e->init)
-+        /*
-+         * This is the first functional reference and the engine requires
-+         * initialisation so we do it now.
-+         */
-+        to_return = e->init(e);
-+    if (to_return) {
-+        /*
-+         * OK, we return a functional reference which is also a structural
-+         * reference.
-+         */
-+        e->struct_ref++;
-+        e->funct_ref++;
-+        engine_ref_debug(e, 0, 1);
-+        engine_ref_debug(e, 1, 1);
-+    }
-+    return to_return;
-+}
-+
-+/*
-+ * Free a functional reference to a engine type. This version is only used
-+ * internally.
-+ */
-+int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
-+{
-+    int to_return = 1;
-+
-+    /*
-+     * Reduce the functional reference count here so if it's the terminating
-+     * case, we can release the lock safely and call the finish() handler
-+     * without risk of a race. We get a race if we leave the count until
-+     * after and something else is calling "finish" at the same time -
-+     * there's a chance that both threads will together take the count from 2
-+     * to 0 without either calling finish().
-+     */
-+    e->funct_ref--;
-+    engine_ref_debug(e, 1, -1);
-+    if ((e->funct_ref == 0) && e->finish) {
-+        if (unlock_for_handlers)
-+            CRYPTO_THREAD_unlock(global_engine_lock);
-+        to_return = e->finish(e);
-+        if (unlock_for_handlers)
-+            CRYPTO_THREAD_write_lock(global_engine_lock);
-+        if (!to_return)
-+            return 0;
-+    }
-+    REF_ASSERT_ISNT(e->funct_ref < 0);
-+    /* Release the structural reference too */
-+    if (!engine_free_util(e, 0)) {
-+        ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH, ENGINE_R_FINISH_FAILED);
-+        return 0;
-+    }
-+    return to_return;
-+}
-+
-+/* The API (locked) version of "init" */
-+int ENGINE_init(ENGINE *e)
-+{
-+    int ret;
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
-+        ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    ret = engine_unlocked_init(e);
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    return ret;
-+}
-+
-+/* The API (locked) version of "finish" */
-+int ENGINE_finish(ENGINE *e)
-+{
-+    int to_return = 1;
-+
-+    if (e == NULL)
-+        return 1;
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    to_return = engine_unlocked_finish(e, 1);
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    if (!to_return) {
-+        ENGINEerr(ENGINE_F_ENGINE_FINISH, ENGINE_R_FINISH_FAILED);
-+        return 0;
-+    }
-+    return to_return;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_int.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_int.h
-new file mode 100644
-index 0000000..c604fad
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_int.h
-@@ -0,0 +1,183 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * ECDH support in OpenSSL originally developed by
-+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
-+ */
-+
-+#ifndef HEADER_ENGINE_INT_H
-+# define HEADER_ENGINE_INT_H
-+
-+# include "internal/cryptlib.h"
-+# include 
-+# include 
-+
-+#ifdef  __cplusplus
-+extern "C" {
-+#endif
-+
-+extern CRYPTO_RWLOCK *global_engine_lock;
-+
-+/*
-+ * If we compile with this symbol defined, then both reference counts in the
-+ * ENGINE structure will be monitored with a line of output on stderr for
-+ * each change. This prints the engine's pointer address (truncated to
-+ * unsigned int), "struct" or "funct" to indicate the reference type, the
-+ * before and after reference count, and the file:line-number pair. The
-+ * "engine_ref_debug" statements must come *after* the change.
-+ */
-+# ifdef ENGINE_REF_COUNT_DEBUG
-+
-+#  define engine_ref_debug(e, isfunct, diff) \
-+        fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \
-+                (unsigned int)(e), (isfunct ? "funct" : "struct"), \
-+                ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \
-+                ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \
-+                (OPENSSL_FILE), (OPENSSL_LINE))
-+
-+# else
-+
-+#  define engine_ref_debug(e, isfunct, diff)
-+
-+# endif
-+
-+/*
-+ * Any code that will need cleanup operations should use these functions to
-+ * register callbacks. engine_cleanup_int() will call all registered
-+ * callbacks in order. NB: both the "add" functions assume the engine lock to
-+ * already be held (in "write" mode).
-+ */
-+typedef void (ENGINE_CLEANUP_CB) (void);
-+typedef struct st_engine_cleanup_item {
-+    ENGINE_CLEANUP_CB *cb;
-+} ENGINE_CLEANUP_ITEM;
-+DEFINE_STACK_OF(ENGINE_CLEANUP_ITEM)
-+void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb);
-+void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb);
-+
-+/* We need stacks of ENGINEs for use in eng_table.c */
-+DEFINE_STACK_OF(ENGINE)
-+
-+/*
-+ * If this symbol is defined then engine_table_select(), the function that is
-+ * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults
-+ * and functional references (etc), will display debugging summaries to
-+ * stderr.
-+ */
-+/* #define ENGINE_TABLE_DEBUG */
-+
-+/*
-+ * This represents an implementation table. Dependent code should instantiate
-+ * it as a (ENGINE_TABLE *) pointer value set initially to NULL.
-+ */
-+typedef struct st_engine_table ENGINE_TABLE;
-+int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
-+                          ENGINE *e, const int *nids, int num_nids,
-+                          int setdefault);
-+void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e);
-+void engine_table_cleanup(ENGINE_TABLE **table);
-+# ifndef ENGINE_TABLE_DEBUG
-+ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
-+# else
-+ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f,
-+                                int l);
-+#  define engine_table_select(t,n) engine_table_select_tmp(t,n,OPENSSL_FILE,OPENSSL_LINE)
-+# endif
-+typedef void (engine_table_doall_cb) (int nid, STACK_OF(ENGINE) *sk,
-+                                      ENGINE *def, void *arg);
-+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
-+                        void *arg);
-+
-+/*
-+ * Internal versions of API functions that have control over locking. These
-+ * are used between C files when functionality needs to be shared but the
-+ * caller may already be controlling of the engine lock.
-+ */
-+int engine_unlocked_init(ENGINE *e);
-+int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
-+int engine_free_util(ENGINE *e, int locked);
-+
-+/*
-+ * This function will reset all "set"able values in an ENGINE to NULL. This
-+ * won't touch reference counts or ex_data, but is equivalent to calling all
-+ * the ENGINE_set_***() functions with a NULL value.
-+ */
-+void engine_set_all_null(ENGINE *e);
-+
-+/*
-+ * NB: Bitwise OR-able values for the "flags" variable in ENGINE are now
-+ * exposed in engine.h.
-+ */
-+
-+/* Free up dynamically allocated public key methods associated with ENGINE */
-+
-+void engine_pkey_meths_free(ENGINE *e);
-+void engine_pkey_asn1_meths_free(ENGINE *e);
-+
-+/* Once initialisation function */
-+extern CRYPTO_ONCE engine_lock_init;
-+DECLARE_RUN_ONCE(do_engine_lock_init)
-+
-+/*
-+ * This is a structure for storing implementations of various crypto
-+ * algorithms and functions.
-+ */
-+struct engine_st {
-+    const char *id;
-+    const char *name;
-+    const RSA_METHOD *rsa_meth;
-+    const DSA_METHOD *dsa_meth;
-+    const DH_METHOD *dh_meth;
-+    const EC_KEY_METHOD *ec_meth;
-+    const RAND_METHOD *rand_meth;
-+    /* Cipher handling is via this callback */
-+    ENGINE_CIPHERS_PTR ciphers;
-+    /* Digest handling is via this callback */
-+    ENGINE_DIGESTS_PTR digests;
-+    /* Public key handling via this callback */
-+    ENGINE_PKEY_METHS_PTR pkey_meths;
-+    /* ASN1 public key handling via this callback */
-+    ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
-+    ENGINE_GEN_INT_FUNC_PTR destroy;
-+    ENGINE_GEN_INT_FUNC_PTR init;
-+    ENGINE_GEN_INT_FUNC_PTR finish;
-+    ENGINE_CTRL_FUNC_PTR ctrl;
-+    ENGINE_LOAD_KEY_PTR load_privkey;
-+    ENGINE_LOAD_KEY_PTR load_pubkey;
-+    ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
-+    const ENGINE_CMD_DEFN *cmd_defns;
-+    int flags;
-+    /* reference count on the structure itself */
-+    int struct_ref;
-+    /*
-+     * reference count on usability of the engine type. NB: This controls the
-+     * loading and initialisation of any functionality required by this
-+     * engine, whereas the previous count is simply to cope with
-+     * (de)allocation of this structure. Hence, running_ref <= struct_ref at
-+     * all times.
-+     */
-+    int funct_ref;
-+    /* A place to store per-ENGINE data */
-+    CRYPTO_EX_DATA ex_data;
-+    /* Used to maintain the linked-list of engines. */
-+    struct engine_st *prev;
-+    struct engine_st *next;
-+};
-+
-+typedef struct st_engine_pile ENGINE_PILE;
-+
-+DEFINE_LHASH_OF(ENGINE_PILE);
-+
-+#ifdef  __cplusplus
-+}
-+#endif
-+
-+#endif                          /* HEADER_ENGINE_INT_H */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_lib.c
-new file mode 100644
-index 0000000..28de21d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_lib.c
-@@ -0,0 +1,295 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+#include 
-+
-+CRYPTO_RWLOCK *global_engine_lock;
-+
-+CRYPTO_ONCE engine_lock_init = CRYPTO_ONCE_STATIC_INIT;
-+
-+/* The "new"/"free" stuff first */
-+
-+DEFINE_RUN_ONCE(do_engine_lock_init)
-+{
-+    OPENSSL_init_crypto(0, NULL);
-+    global_engine_lock = CRYPTO_THREAD_lock_new();
-+    return global_engine_lock != NULL;
-+}
-+
-+ENGINE *ENGINE_new(void)
-+{
-+    ENGINE *ret;
-+
-+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)
-+        || (ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    ret->struct_ref = 1;
-+    engine_ref_debug(ret, 0, 1);
-+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data)) {
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+/*
-+ * Placed here (close proximity to ENGINE_new) so that modifications to the
-+ * elements of the ENGINE structure are more likely to be caught and changed
-+ * here.
-+ */
-+void engine_set_all_null(ENGINE *e)
-+{
-+    e->id = NULL;
-+    e->name = NULL;
-+    e->rsa_meth = NULL;
-+    e->dsa_meth = NULL;
-+    e->dh_meth = NULL;
-+    e->rand_meth = NULL;
-+    e->ciphers = NULL;
-+    e->digests = NULL;
-+    e->destroy = NULL;
-+    e->init = NULL;
-+    e->finish = NULL;
-+    e->ctrl = NULL;
-+    e->load_privkey = NULL;
-+    e->load_pubkey = NULL;
-+    e->cmd_defns = NULL;
-+    e->flags = 0;
-+}
-+
-+int engine_free_util(ENGINE *e, int locked)
-+{
-+    int i;
-+
-+    if (e == NULL)
-+        return 1;
-+    if (locked)
-+        CRYPTO_atomic_add(&e->struct_ref, -1, &i, global_engine_lock);
-+    else
-+        i = --e->struct_ref;
-+    engine_ref_debug(e, 0, -1)
-+    if (i > 0)
-+        return 1;
-+    REF_ASSERT_ISNT(i < 0);
-+    /* Free up any dynamically allocated public key methods */
-+    engine_pkey_meths_free(e);
-+    engine_pkey_asn1_meths_free(e);
-+    /*
-+     * Give the ENGINE a chance to do any structural cleanup corresponding to
-+     * allocation it did in its constructor (eg. unload error strings)
-+     */
-+    if (e->destroy)
-+        e->destroy(e);
-+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data);
-+    OPENSSL_free(e);
-+    return 1;
-+}
-+
-+int ENGINE_free(ENGINE *e)
-+{
-+    return engine_free_util(e, 1);
-+}
-+
-+/* Cleanup stuff */
-+
-+/*
-+ * engine_cleanup_int() is coded such that anything that does work that will
-+ * need cleanup can register a "cleanup" callback here. That way we don't get
-+ * linker bloat by referring to all *possible* cleanups, but any linker bloat
-+ * into code "X" will cause X's cleanup function to end up here.
-+ */
-+static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL;
-+static int int_cleanup_check(int create)
-+{
-+    if (cleanup_stack)
-+        return 1;
-+    if (!create)
-+        return 0;
-+    cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null();
-+    return (cleanup_stack ? 1 : 0);
-+}
-+
-+static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb)
-+{
-+    ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(*item));
-+    if (item == NULL)
-+        return NULL;
-+    item->cb = cb;
-+    return item;
-+}
-+
-+void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb)
-+{
-+    ENGINE_CLEANUP_ITEM *item;
-+    if (!int_cleanup_check(1))
-+        return;
-+    item = int_cleanup_item(cb);
-+    if (item)
-+        sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0);
-+}
-+
-+void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb)
-+{
-+    ENGINE_CLEANUP_ITEM *item;
-+    if (!int_cleanup_check(1))
-+        return;
-+    item = int_cleanup_item(cb);
-+    if (item)
-+        sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item);
-+}
-+
-+/* The API function that performs all cleanup */
-+static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item)
-+{
-+    (*(item->cb)) ();
-+    OPENSSL_free(item);
-+}
-+
-+void engine_cleanup_int(void)
-+{
-+    if (int_cleanup_check(0)) {
-+        sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack,
-+                                        engine_cleanup_cb_free);
-+        cleanup_stack = NULL;
-+    }
-+    /*
-+     * FIXME: This should be handled (somehow) through RAND, eg. by it
-+     * registering a cleanup callback.
-+     */
-+    RAND_set_rand_method(NULL);
-+    CRYPTO_THREAD_lock_free(global_engine_lock);
-+}
-+
-+/* Now the "ex_data" support */
-+
-+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
-+{
-+    return (CRYPTO_set_ex_data(&e->ex_data, idx, arg));
-+}
-+
-+void *ENGINE_get_ex_data(const ENGINE *e, int idx)
-+{
-+    return (CRYPTO_get_ex_data(&e->ex_data, idx));
-+}
-+
-+/*
-+ * Functions to get/set an ENGINE's elements - mainly to avoid exposing the
-+ * ENGINE structure itself.
-+ */
-+
-+int ENGINE_set_id(ENGINE *e, const char *id)
-+{
-+    if (id == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_SET_ID, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    e->id = id;
-+    return 1;
-+}
-+
-+int ENGINE_set_name(ENGINE *e, const char *name)
-+{
-+    if (name == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_SET_NAME, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    e->name = name;
-+    return 1;
-+}
-+
-+int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f)
-+{
-+    e->destroy = destroy_f;
-+    return 1;
-+}
-+
-+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
-+{
-+    e->init = init_f;
-+    return 1;
-+}
-+
-+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
-+{
-+    e->finish = finish_f;
-+    return 1;
-+}
-+
-+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
-+{
-+    e->ctrl = ctrl_f;
-+    return 1;
-+}
-+
-+int ENGINE_set_flags(ENGINE *e, int flags)
-+{
-+    e->flags = flags;
-+    return 1;
-+}
-+
-+int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns)
-+{
-+    e->cmd_defns = defns;
-+    return 1;
-+}
-+
-+const char *ENGINE_get_id(const ENGINE *e)
-+{
-+    return e->id;
-+}
-+
-+const char *ENGINE_get_name(const ENGINE *e)
-+{
-+    return e->name;
-+}
-+
-+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e)
-+{
-+    return e->destroy;
-+}
-+
-+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e)
-+{
-+    return e->init;
-+}
-+
-+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e)
-+{
-+    return e->finish;
-+}
-+
-+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e)
-+{
-+    return e->ctrl;
-+}
-+
-+int ENGINE_get_flags(const ENGINE *e)
-+{
-+    return e->flags;
-+}
-+
-+const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e)
-+{
-+    return e->cmd_defns;
-+}
-+
-+/*
-+ * eng_lib.o is pretty much linked into anything that touches ENGINE already,
-+ * so put the "static_state" hack here.
-+ */
-+
-+static int internal_static_hack = 0;
-+
-+void *ENGINE_get_static_state(void)
-+{
-+    return &internal_static_hack;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_list.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_list.c
-new file mode 100644
-index 0000000..934389f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_list.c
-@@ -0,0 +1,354 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * ECDH support in OpenSSL originally developed by
-+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
-+ */
-+
-+#include "eng_int.h"
-+
-+/*
-+ * The linked-list of pointers to engine types. engine_list_head incorporates
-+ * an implicit structural reference but engine_list_tail does not - the
-+ * latter is a computational niceity and only points to something that is
-+ * already pointed to by its predecessor in the list (or engine_list_head
-+ * itself). In the same way, the use of the "prev" pointer in each ENGINE is
-+ * to save excessive list iteration, it doesn't correspond to an extra
-+ * structural reference. Hence, engine_list_head, and each non-null "next"
-+ * pointer account for the list itself assuming exactly 1 structural
-+ * reference on each list member.
-+ */
-+static ENGINE *engine_list_head = NULL;
-+static ENGINE *engine_list_tail = NULL;
-+
-+/*
-+ * This cleanup function is only needed internally. If it should be called,
-+ * we register it with the "engine_cleanup_int()" stack to be called during
-+ * cleanup.
-+ */
-+
-+static void engine_list_cleanup(void)
-+{
-+    ENGINE *iterator = engine_list_head;
-+
-+    while (iterator != NULL) {
-+        ENGINE_remove(iterator);
-+        iterator = engine_list_head;
-+    }
-+    return;
-+}
-+
-+/*
-+ * These static functions starting with a lower case "engine_" always take
-+ * place when global_engine_lock has been locked up.
-+ */
-+static int engine_list_add(ENGINE *e)
-+{
-+    int conflict = 0;
-+    ENGINE *iterator = NULL;
-+
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    iterator = engine_list_head;
-+    while (iterator && !conflict) {
-+        conflict = (strcmp(iterator->id, e->id) == 0);
-+        iterator = iterator->next;
-+    }
-+    if (conflict) {
-+        ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_CONFLICTING_ENGINE_ID);
-+        return 0;
-+    }
-+    if (engine_list_head == NULL) {
-+        /* We are adding to an empty list. */
-+        if (engine_list_tail) {
-+            ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR);
-+            return 0;
-+        }
-+        engine_list_head = e;
-+        e->prev = NULL;
-+        /*
-+         * The first time the list allocates, we should register the cleanup.
-+         */
-+        engine_cleanup_add_last(engine_list_cleanup);
-+    } else {
-+        /* We are adding to the tail of an existing list. */
-+        if ((engine_list_tail == NULL) || (engine_list_tail->next != NULL)) {
-+            ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR);
-+            return 0;
-+        }
-+        engine_list_tail->next = e;
-+        e->prev = engine_list_tail;
-+    }
-+    /*
-+     * Having the engine in the list assumes a structural reference.
-+     */
-+    e->struct_ref++;
-+    engine_ref_debug(e, 0, 1);
-+    /* However it came to be, e is the last item in the list. */
-+    engine_list_tail = e;
-+    e->next = NULL;
-+    return 1;
-+}
-+
-+static int engine_list_remove(ENGINE *e)
-+{
-+    ENGINE *iterator;
-+
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    /* We need to check that e is in our linked list! */
-+    iterator = engine_list_head;
-+    while (iterator && (iterator != e))
-+        iterator = iterator->next;
-+    if (iterator == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
-+                  ENGINE_R_ENGINE_IS_NOT_IN_LIST);
-+        return 0;
-+    }
-+    /* un-link e from the chain. */
-+    if (e->next)
-+        e->next->prev = e->prev;
-+    if (e->prev)
-+        e->prev->next = e->next;
-+    /* Correct our head/tail if necessary. */
-+    if (engine_list_head == e)
-+        engine_list_head = e->next;
-+    if (engine_list_tail == e)
-+        engine_list_tail = e->prev;
-+    engine_free_util(e, 0);
-+    return 1;
-+}
-+
-+/* Get the first/last "ENGINE" type available. */
-+ENGINE *ENGINE_get_first(void)
-+{
-+    ENGINE *ret;
-+
-+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
-+        ENGINEerr(ENGINE_F_ENGINE_GET_FIRST, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    ret = engine_list_head;
-+    if (ret) {
-+        ret->struct_ref++;
-+        engine_ref_debug(ret, 0, 1);
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    return ret;
-+}
-+
-+ENGINE *ENGINE_get_last(void)
-+{
-+    ENGINE *ret;
-+
-+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
-+        ENGINEerr(ENGINE_F_ENGINE_GET_LAST, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    ret = engine_list_tail;
-+    if (ret) {
-+        ret->struct_ref++;
-+        engine_ref_debug(ret, 0, 1);
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    return ret;
-+}
-+
-+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
-+ENGINE *ENGINE_get_next(ENGINE *e)
-+{
-+    ENGINE *ret = NULL;
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_GET_NEXT, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    ret = e->next;
-+    if (ret) {
-+        /* Return a valid structural reference to the next ENGINE */
-+        ret->struct_ref++;
-+        engine_ref_debug(ret, 0, 1);
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    /* Release the structural reference to the previous ENGINE */
-+    ENGINE_free(e);
-+    return ret;
-+}
-+
-+ENGINE *ENGINE_get_prev(ENGINE *e)
-+{
-+    ENGINE *ret = NULL;
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_GET_PREV, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    ret = e->prev;
-+    if (ret) {
-+        /* Return a valid structural reference to the next ENGINE */
-+        ret->struct_ref++;
-+        engine_ref_debug(ret, 0, 1);
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    /* Release the structural reference to the previous ENGINE */
-+    ENGINE_free(e);
-+    return ret;
-+}
-+
-+/* Add another "ENGINE" type into the list. */
-+int ENGINE_add(ENGINE *e)
-+{
-+    int to_return = 1;
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_ADD, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    if ((e->id == NULL) || (e->name == NULL)) {
-+        ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_ID_OR_NAME_MISSING);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    if (!engine_list_add(e)) {
-+        ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_INTERNAL_LIST_ERROR);
-+        to_return = 0;
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    return to_return;
-+}
-+
-+/* Remove an existing "ENGINE" type from the array. */
-+int ENGINE_remove(ENGINE *e)
-+{
-+    int to_return = 1;
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_REMOVE, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    if (!engine_list_remove(e)) {
-+        ENGINEerr(ENGINE_F_ENGINE_REMOVE, ENGINE_R_INTERNAL_LIST_ERROR);
-+        to_return = 0;
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    return to_return;
-+}
-+
-+static void engine_cpy(ENGINE *dest, const ENGINE *src)
-+{
-+    dest->id = src->id;
-+    dest->name = src->name;
-+#ifndef OPENSSL_NO_RSA
-+    dest->rsa_meth = src->rsa_meth;
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    dest->dsa_meth = src->dsa_meth;
-+#endif
-+#ifndef OPENSSL_NO_DH
-+    dest->dh_meth = src->dh_meth;
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    dest->ec_meth = src->ec_meth;
-+#endif
-+    dest->rand_meth = src->rand_meth;
-+    dest->ciphers = src->ciphers;
-+    dest->digests = src->digests;
-+    dest->pkey_meths = src->pkey_meths;
-+    dest->destroy = src->destroy;
-+    dest->init = src->init;
-+    dest->finish = src->finish;
-+    dest->ctrl = src->ctrl;
-+    dest->load_privkey = src->load_privkey;
-+    dest->load_pubkey = src->load_pubkey;
-+    dest->cmd_defns = src->cmd_defns;
-+    dest->flags = src->flags;
-+}
-+
-+ENGINE *ENGINE_by_id(const char *id)
-+{
-+    ENGINE *iterator;
-+    char *load_dir = NULL;
-+    if (id == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_PASSED_NULL_PARAMETER);
-+        return NULL;
-+    }
-+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
-+        ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    iterator = engine_list_head;
-+    while (iterator && (strcmp(id, iterator->id) != 0))
-+        iterator = iterator->next;
-+    if (iterator != NULL) {
-+        /*
-+         * We need to return a structural reference. If this is an ENGINE
-+         * type that returns copies, make a duplicate - otherwise increment
-+         * the existing ENGINE's reference count.
-+         */
-+        if (iterator->flags & ENGINE_FLAGS_BY_ID_COPY) {
-+            ENGINE *cp = ENGINE_new();
-+            if (cp == NULL)
-+                iterator = NULL;
-+            else {
-+                engine_cpy(cp, iterator);
-+                iterator = cp;
-+            }
-+        } else {
-+            iterator->struct_ref++;
-+            engine_ref_debug(iterator, 0, 1);
-+        }
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    if (iterator != NULL)
-+        return iterator;
-+    /*
-+     * Prevent infinite recursion if we're looking for the dynamic engine.
-+     */
-+    if (strcmp(id, "dynamic")) {
-+        if ((load_dir = getenv("OPENSSL_ENGINES")) == 0)
-+            load_dir = ENGINESDIR;
-+        iterator = ENGINE_by_id("dynamic");
-+        if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
-+            !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
-+            !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
-+                                    load_dir, 0) ||
-+            !ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) ||
-+            !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
-+            goto notfound;
-+        return iterator;
-+    }
-+ notfound:
-+    ENGINE_free(iterator);
-+    ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE);
-+    ERR_add_error_data(2, "id=", id);
-+    return NULL;
-+    /* EEK! Experimental code ends */
-+}
-+
-+int ENGINE_up_ref(ENGINE *e)
-+{
-+    int i;
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_UP_REF, ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    CRYPTO_atomic_add(&e->struct_ref, 1, &i, global_engine_lock);
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_openssl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_openssl.c
-new file mode 100644
-index 0000000..9208f7e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_openssl.c
-@@ -0,0 +1,652 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* ====================================================================
-+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
-+ * ECDH support in OpenSSL originally developed by
-+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+
-+/*
-+ * This testing gunk is implemented (and explained) lower down. It also
-+ * assumes the application explicitly calls "ENGINE_load_openssl()" because
-+ * this is no longer automatic in ENGINE_load_builtin_engines().
-+ */
-+#define TEST_ENG_OPENSSL_RC4
-+#ifndef OPENSSL_NO_STDIO
-+#define TEST_ENG_OPENSSL_PKEY
-+#endif
-+/* #define TEST_ENG_OPENSSL_HMAC */
-+/* #define TEST_ENG_OPENSSL_HMAC_INIT */
-+/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
-+#define TEST_ENG_OPENSSL_RC4_P_INIT
-+/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
-+#define TEST_ENG_OPENSSL_SHA
-+/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
-+/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
-+/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
-+/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
-+
-+/* Now check what of those algorithms are actually enabled */
-+#ifdef OPENSSL_NO_RC4
-+# undef TEST_ENG_OPENSSL_RC4
-+# undef TEST_ENG_OPENSSL_RC4_OTHERS
-+# undef TEST_ENG_OPENSSL_RC4_P_INIT
-+# undef TEST_ENG_OPENSSL_RC4_P_CIPHER
-+#endif
-+
-+static int openssl_destroy(ENGINE *e);
-+
-+#ifdef TEST_ENG_OPENSSL_RC4
-+static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-+                           const int **nids, int nid);
-+#endif
-+#ifdef TEST_ENG_OPENSSL_SHA
-+static int openssl_digests(ENGINE *e, const EVP_MD **digest,
-+                           const int **nids, int nid);
-+#endif
-+
-+#ifdef TEST_ENG_OPENSSL_PKEY
-+static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
-+                                      UI_METHOD *ui_method,
-+                                      void *callback_data);
-+#endif
-+
-+#ifdef TEST_ENG_OPENSSL_HMAC
-+static int ossl_register_hmac_meth(void);
-+static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
-+                           const int **nids, int nid);
-+#endif
-+
-+/* The constants used when creating the ENGINE */
-+static const char *engine_openssl_id = "openssl";
-+static const char *engine_openssl_name = "Software engine support";
-+
-+/*
-+ * This internal function is used by ENGINE_openssl() and possibly by the
-+ * "dynamic" ENGINE support too
-+ */
-+static int bind_helper(ENGINE *e)
-+{
-+    if (!ENGINE_set_id(e, engine_openssl_id)
-+        || !ENGINE_set_name(e, engine_openssl_name)
-+        || !ENGINE_set_destroy_function(e, openssl_destroy)
-+#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
-+# ifndef OPENSSL_NO_RSA
-+        || !ENGINE_set_RSA(e, RSA_get_default_method())
-+# endif
-+# ifndef OPENSSL_NO_DSA
-+        || !ENGINE_set_DSA(e, DSA_get_default_method())
-+# endif
-+# ifndef OPENSSL_NO_EC
-+        || !ENGINE_set_EC(e, EC_KEY_OpenSSL())
-+# endif
-+# ifndef OPENSSL_NO_DH
-+        || !ENGINE_set_DH(e, DH_get_default_method())
-+# endif
-+        || !ENGINE_set_RAND(e, RAND_OpenSSL())
-+# ifdef TEST_ENG_OPENSSL_RC4
-+        || !ENGINE_set_ciphers(e, openssl_ciphers)
-+# endif
-+# ifdef TEST_ENG_OPENSSL_SHA
-+        || !ENGINE_set_digests(e, openssl_digests)
-+# endif
-+#endif
-+#ifdef TEST_ENG_OPENSSL_PKEY
-+        || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
-+#endif
-+#ifdef TEST_ENG_OPENSSL_HMAC
-+        || !ossl_register_hmac_meth()
-+        || !ENGINE_set_pkey_meths(e, ossl_pkey_meths)
-+#endif
-+        )
-+        return 0;
-+    /*
-+     * If we add errors to this ENGINE, ensure the error handling is setup
-+     * here
-+     */
-+    /* openssl_load_error_strings(); */
-+    return 1;
-+}
-+
-+static ENGINE *engine_openssl(void)
-+{
-+    ENGINE *ret = ENGINE_new();
-+    if (ret == NULL)
-+        return NULL;
-+    if (!bind_helper(ret)) {
-+        ENGINE_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+void engine_load_openssl_int(void)
-+{
-+    ENGINE *toadd = engine_openssl();
-+    if (!toadd)
-+        return;
-+    ENGINE_add(toadd);
-+    /*
-+     * If the "add" worked, it gets a structural reference. So either way, we
-+     * release our just-created reference.
-+     */
-+    ENGINE_free(toadd);
-+    ERR_clear_error();
-+}
-+
-+/*
-+ * This stuff is needed if this ENGINE is being compiled into a
-+ * self-contained shared-library.
-+ */
-+#ifdef ENGINE_DYNAMIC_SUPPORT
-+static int bind_fn(ENGINE *e, const char *id)
-+{
-+    if (id && (strcmp(id, engine_openssl_id) != 0))
-+        return 0;
-+    if (!bind_helper(e))
-+        return 0;
-+    return 1;
-+}
-+
-+IMPLEMENT_DYNAMIC_CHECK_FN()
-+    IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
-+#endif                          /* ENGINE_DYNAMIC_SUPPORT */
-+#ifdef TEST_ENG_OPENSSL_RC4
-+/*-
-+ * This section of code compiles an "alternative implementation" of two modes of
-+ * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
-+ * should under normal circumstances go via this support rather than the default
-+ * EVP support. There are other symbols to tweak the testing;
-+ *    TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
-+ *        we're asked for a cipher we don't support (should not happen).
-+ *    TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
-+ *        the "init_key" handler is called.
-+ *    TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
-+ */
-+# include 
-+# define TEST_RC4_KEY_SIZE               16
-+typedef struct {
-+    unsigned char key[TEST_RC4_KEY_SIZE];
-+    RC4_KEY ks;
-+} TEST_RC4_KEY;
-+# define test(ctx) ((TEST_RC4_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx))
-+static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                             const unsigned char *iv, int enc)
-+{
-+# ifdef TEST_ENG_OPENSSL_RC4_P_INIT
-+    fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
-+# endif
-+    memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx));
-+    RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
-+                test(ctx)->key);
-+    return 1;
-+}
-+
-+static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                           const unsigned char *in, size_t inl)
-+{
-+# ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
-+    fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
-+# endif
-+    RC4(&test(ctx)->ks, inl, in, out);
-+    return 1;
-+}
-+
-+static EVP_CIPHER *r4_cipher = NULL;
-+static const EVP_CIPHER *test_r4_cipher(void)
-+{
-+    if (r4_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_rc4, 1, TEST_RC4_KEY_SIZE)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 0)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_VARIABLE_LENGTH)
-+            || !EVP_CIPHER_meth_set_init(cipher, test_rc4_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, test_rc4_cipher)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(TEST_RC4_KEY))) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        r4_cipher = cipher;
-+    }
-+    return r4_cipher;
-+}
-+static void test_r4_cipher_destroy(void)
-+{
-+    EVP_CIPHER_meth_free(r4_cipher);
-+    r4_cipher = NULL;
-+}
-+
-+static EVP_CIPHER *r4_40_cipher = NULL;
-+static const EVP_CIPHER *test_r4_40_cipher(void)
-+{
-+    if (r4_40_cipher == NULL) {
-+        EVP_CIPHER *cipher;
-+
-+        if ((cipher = EVP_CIPHER_meth_new(NID_rc4, 1, 5 /* 40 bits */)) == NULL
-+            || !EVP_CIPHER_meth_set_iv_length(cipher, 0)
-+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_VARIABLE_LENGTH)
-+            || !EVP_CIPHER_meth_set_init(cipher, test_rc4_init_key)
-+            || !EVP_CIPHER_meth_set_do_cipher(cipher, test_rc4_cipher)
-+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(TEST_RC4_KEY))) {
-+            EVP_CIPHER_meth_free(cipher);
-+            cipher = NULL;
-+        }
-+        r4_40_cipher = cipher;
-+    }
-+    return r4_40_cipher;
-+}
-+static void test_r4_40_cipher_destroy(void)
-+{
-+    EVP_CIPHER_meth_free(r4_40_cipher);
-+    r4_40_cipher = NULL;
-+}
-+static int test_cipher_nids(const int **nids)
-+{
-+    static int cipher_nids[4] = { 0, 0, 0, 0 };
-+    static int pos = 0;
-+    static int init = 0;
-+
-+    if (!init) {
-+        const EVP_CIPHER *cipher;
-+        if ((cipher = test_r4_cipher()) != NULL)
-+            cipher_nids[pos++] = EVP_CIPHER_nid(cipher);
-+        if ((cipher = test_r4_40_cipher()) != NULL)
-+            cipher_nids[pos++] = EVP_CIPHER_nid(cipher);
-+        cipher_nids[pos] = 0;
-+        init = 1;
-+    }
-+    *nids = cipher_nids;
-+    return pos;
-+}
-+
-+static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-+                           const int **nids, int nid)
-+{
-+    if (!cipher) {
-+        /* We are returning a list of supported nids */
-+        return test_cipher_nids(nids);
-+    }
-+    /* We are being asked for a specific cipher */
-+    if (nid == NID_rc4)
-+        *cipher = test_r4_cipher();
-+    else if (nid == NID_rc4_40)
-+        *cipher = test_r4_40_cipher();
-+    else {
-+# ifdef TEST_ENG_OPENSSL_RC4_OTHERS
-+        fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
-+                "nid %d\n", nid);
-+# endif
-+        *cipher = NULL;
-+        return 0;
-+    }
-+    return 1;
-+}
-+#endif
-+
-+#ifdef TEST_ENG_OPENSSL_SHA
-+/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
-+# include 
-+
-+static int test_sha1_init(EVP_MD_CTX *ctx)
-+{
-+# ifdef TEST_ENG_OPENSSL_SHA_P_INIT
-+    fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
-+# endif
-+    return SHA1_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+# ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
-+    fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
-+# endif
-+    return SHA1_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+# ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
-+    fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
-+# endif
-+    return SHA1_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static EVP_MD *sha1_md = NULL;
-+static const EVP_MD *test_sha_md(void)
-+{
-+    if (sha1_md == NULL) {
-+        EVP_MD *md;
-+
-+        if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL
-+            || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)
-+            || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)
-+            || !EVP_MD_meth_set_app_datasize(md,
-+                                             sizeof(EVP_MD *) + sizeof(SHA_CTX))
-+            || !EVP_MD_meth_set_flags(md, 0)
-+            || !EVP_MD_meth_set_init(md, test_sha1_init)
-+            || !EVP_MD_meth_set_update(md, test_sha1_update)
-+            || !EVP_MD_meth_set_final(md, test_sha1_final)) {
-+            EVP_MD_meth_free(md);
-+            md = NULL;
-+        }
-+        sha1_md = md;
-+    }
-+    return sha1_md;
-+}
-+static void test_sha_md_destroy(void)
-+{
-+    EVP_MD_meth_free(sha1_md);
-+    sha1_md = NULL;
-+}
-+static int test_digest_nids(const int **nids)
-+{
-+    static int digest_nids[2] = { 0, 0 };
-+    static int pos = 0;
-+    static int init = 0;
-+
-+    if (!init) {
-+        const EVP_MD *md;
-+        if ((md = test_sha_md()) != NULL)
-+            digest_nids[pos++] = EVP_MD_type(md);
-+        digest_nids[pos] = 0;
-+        init = 1;
-+    }
-+    *nids = digest_nids;
-+    return pos;
-+}
-+
-+static int openssl_digests(ENGINE *e, const EVP_MD **digest,
-+                           const int **nids, int nid)
-+{
-+    if (!digest) {
-+        /* We are returning a list of supported nids */
-+        return test_digest_nids(nids);
-+    }
-+    /* We are being asked for a specific digest */
-+    if (nid == NID_sha1)
-+        *digest = test_sha_md();
-+    else {
-+# ifdef TEST_ENG_OPENSSL_SHA_OTHERS
-+        fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
-+                "nid %d\n", nid);
-+# endif
-+        *digest = NULL;
-+        return 0;
-+    }
-+    return 1;
-+}
-+#endif
-+
-+#ifdef TEST_ENG_OPENSSL_PKEY
-+static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
-+                                      UI_METHOD *ui_method,
-+                                      void *callback_data)
-+{
-+    BIO *in;
-+    EVP_PKEY *key;
-+    fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n",
-+            key_id);
-+    in = BIO_new_file(key_id, "r");
-+    if (!in)
-+        return NULL;
-+    key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
-+    BIO_free(in);
-+    return key;
-+}
-+#endif
-+
-+#ifdef TEST_ENG_OPENSSL_HMAC
-+
-+/*
-+ * Experimental HMAC redirection implementation: mainly copied from
-+ * hm_pmeth.c
-+ */
-+
-+/* HMAC pkey context structure */
-+
-+typedef struct {
-+    const EVP_MD *md;           /* MD for HMAC use */
-+    ASN1_OCTET_STRING ktmp;     /* Temp storage for key */
-+    HMAC_CTX *ctx;
-+} OSSL_HMAC_PKEY_CTX;
-+
-+static int ossl_hmac_init(EVP_PKEY_CTX *ctx)
-+{
-+    OSSL_HMAC_PKEY_CTX *hctx;
-+
-+    hctx = OPENSSL_zalloc(sizeof(*hctx));
-+    if (hctx == NULL)
-+        return 0;
-+    hctx->ktmp.type = V_ASN1_OCTET_STRING;
-+    hctx->ctx = HMAC_CTX_new();
-+    if (hctx->ctx == NULL) {
-+        OPENSSL_free(hctx);
-+        return 0;
-+    }
-+    EVP_PKEY_CTX_set_data(ctx, hctx);
-+    EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0);
-+# ifdef TEST_ENG_OPENSSL_HMAC_INIT
-+    fprintf(stderr, "(TEST_ENG_OPENSSL_HMAC) ossl_hmac_init() called\n");
-+# endif
-+    return 1;
-+}
-+
-+static void ossl_hmac_cleanup(EVP_PKEY_CTX *ctx);
-+
-+static int ossl_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
-+{
-+    OSSL_HMAC_PKEY_CTX *sctx, *dctx;
-+
-+    /* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */
-+    if (!ossl_hmac_init(dst))
-+        return 0;
-+    sctx = EVP_PKEY_CTX_get_data(src);
-+    dctx = EVP_PKEY_CTX_get_data(dst);
-+    dctx->md = sctx->md;
-+    if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx))
-+        goto err;
-+    if (sctx->ktmp.data) {
-+        if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
-+                                   sctx->ktmp.data, sctx->ktmp.length))
-+            goto err;
-+    }
-+    return 1;
-+err:
-+    /* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */
-+    ossl_hmac_cleanup(dst);
-+    return 0;
-+}
-+
-+static void ossl_hmac_cleanup(EVP_PKEY_CTX *ctx)
-+{
-+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
-+
-+    if (hctx) {
-+        HMAC_CTX_free(hctx->ctx);
-+        OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
-+        OPENSSL_free(hctx);
-+        EVP_PKEY_CTX_set_data(ctx, NULL);
-+    }
-+}
-+
-+static int ossl_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    ASN1_OCTET_STRING *hkey = NULL;
-+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
-+    if (!hctx->ktmp.data)
-+        return 0;
-+    hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
-+    if (!hkey)
-+        return 0;
-+    EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
-+
-+    return 1;
-+}
-+
-+static int ossl_int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
-+    if (!HMAC_Update(hctx->ctx, data, count))
-+        return 0;
-+    return 1;
-+}
-+
-+static int ossl_hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
-+{
-+    EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
-+    EVP_MD_CTX_set_update_fn(mctx, ossl_int_update);
-+    return 1;
-+}
-+
-+static int ossl_hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
-+                             size_t *siglen, EVP_MD_CTX *mctx)
-+{
-+    unsigned int hlen;
-+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
-+    int l = EVP_MD_CTX_size(mctx);
-+
-+    if (l < 0)
-+        return 0;
-+    *siglen = l;
-+    if (!sig)
-+        return 1;
-+
-+    if (!HMAC_Final(hctx->ctx, sig, &hlen))
-+        return 0;
-+    *siglen = (size_t)hlen;
-+    return 1;
-+}
-+
-+static int ossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-+{
-+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
-+    EVP_PKEY *pk;
-+    ASN1_OCTET_STRING *key;
-+    switch (type) {
-+
-+    case EVP_PKEY_CTRL_SET_MAC_KEY:
-+        if ((!p2 && p1 > 0) || (p1 < -1))
-+            return 0;
-+        if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
-+            return 0;
-+        break;
-+
-+    case EVP_PKEY_CTRL_MD:
-+        hctx->md = p2;
-+        break;
-+
-+    case EVP_PKEY_CTRL_DIGESTINIT:
-+        pk = EVP_PKEY_CTX_get0_pkey(ctx);
-+        key = EVP_PKEY_get0(pk);
-+        if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md, NULL))
-+            return 0;
-+        break;
-+
-+    default:
-+        return -2;
-+
-+    }
-+    return 1;
-+}
-+
-+static int ossl_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
-+                              const char *type, const char *value)
-+{
-+    if (!value) {
-+        return 0;
-+    }
-+    if (strcmp(type, "key") == 0) {
-+        void *p = (void *)value;
-+        return ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, -1, p);
-+    }
-+    if (strcmp(type, "hexkey") == 0) {
-+        unsigned char *key;
-+        int r;
-+        long keylen;
-+        key = OPENSSL_hexstr2buf(value, &keylen);
-+        if (!key)
-+            return 0;
-+        r = ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
-+        OPENSSL_free(key);
-+        return r;
-+    }
-+    return -2;
-+}
-+
-+static EVP_PKEY_METHOD *ossl_hmac_meth;
-+
-+static int ossl_register_hmac_meth(void)
-+{
-+    EVP_PKEY_METHOD *meth;
-+    meth = EVP_PKEY_meth_new(EVP_PKEY_HMAC, 0);
-+    if (meth == NULL)
-+        return 0;
-+    EVP_PKEY_meth_set_init(meth, ossl_hmac_init);
-+    EVP_PKEY_meth_set_copy(meth, ossl_hmac_copy);
-+    EVP_PKEY_meth_set_cleanup(meth, ossl_hmac_cleanup);
-+
-+    EVP_PKEY_meth_set_keygen(meth, 0, ossl_hmac_keygen);
-+
-+    EVP_PKEY_meth_set_signctx(meth, ossl_hmac_signctx_init,
-+                              ossl_hmac_signctx);
-+
-+    EVP_PKEY_meth_set_ctrl(meth, ossl_hmac_ctrl, ossl_hmac_ctrl_str);
-+    ossl_hmac_meth = meth;
-+    return 1;
-+}
-+
-+static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
-+                           const int **nids, int nid)
-+{
-+    static int ossl_pkey_nids[] = {
-+        EVP_PKEY_HMAC,
-+        0
-+    };
-+    if (!pmeth) {
-+        *nids = ossl_pkey_nids;
-+        return 1;
-+    }
-+
-+    if (nid == EVP_PKEY_HMAC) {
-+        *pmeth = ossl_hmac_meth;
-+        return 1;
-+    }
-+
-+    *pmeth = NULL;
-+    return 0;
-+}
-+
-+#endif
-+
-+int openssl_destroy(ENGINE *e)
-+{
-+    test_sha_md_destroy();
-+#ifdef TEST_ENG_OPENSSL_RC4
-+    test_r4_cipher_destroy();
-+    test_r4_40_cipher_destroy();
-+#endif
-+    return 1;
-+}
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_pkey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_pkey.c
-new file mode 100644
-index 0000000..305a648
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_pkey.c
-@@ -0,0 +1,140 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+
-+/* Basic get/set stuff */
-+
-+int ENGINE_set_load_privkey_function(ENGINE *e,
-+                                     ENGINE_LOAD_KEY_PTR loadpriv_f)
-+{
-+    e->load_privkey = loadpriv_f;
-+    return 1;
-+}
-+
-+int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
-+{
-+    e->load_pubkey = loadpub_f;
-+    return 1;
-+}
-+
-+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
-+                                             ENGINE_SSL_CLIENT_CERT_PTR
-+                                             loadssl_f)
-+{
-+    e->load_ssl_client_cert = loadssl_f;
-+    return 1;
-+}
-+
-+ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
-+{
-+    return e->load_privkey;
-+}
-+
-+ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
-+{
-+    return e->load_pubkey;
-+}
-+
-+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE
-+                                                               *e)
-+{
-+    return e->load_ssl_client_cert;
-+}
-+
-+/* API functions to load public/private keys */
-+
-+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
-+                                  UI_METHOD *ui_method, void *callback_data)
-+{
-+    EVP_PKEY *pkey;
-+
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
-+                  ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    if (e->funct_ref == 0) {
-+        CRYPTO_THREAD_unlock(global_engine_lock);
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, ENGINE_R_NOT_INITIALISED);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    if (!e->load_privkey) {
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
-+                  ENGINE_R_NO_LOAD_FUNCTION);
-+        return 0;
-+    }
-+    pkey = e->load_privkey(e, key_id, ui_method, callback_data);
-+    if (!pkey) {
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
-+                  ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
-+        return 0;
-+    }
-+    return pkey;
-+}
-+
-+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
-+                                 UI_METHOD *ui_method, void *callback_data)
-+{
-+    EVP_PKEY *pkey;
-+
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
-+                  ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    if (e->funct_ref == 0) {
-+        CRYPTO_THREAD_unlock(global_engine_lock);
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NOT_INITIALISED);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    if (!e->load_pubkey) {
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NO_LOAD_FUNCTION);
-+        return 0;
-+    }
-+    pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
-+    if (!pkey) {
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
-+                  ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
-+        return 0;
-+    }
-+    return pkey;
-+}
-+
-+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
-+                                STACK_OF(X509_NAME) *ca_dn, X509 **pcert,
-+                                EVP_PKEY **ppkey, STACK_OF(X509) **pother,
-+                                UI_METHOD *ui_method, void *callback_data)
-+{
-+
-+    if (e == NULL) {
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
-+                  ERR_R_PASSED_NULL_PARAMETER);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    if (e->funct_ref == 0) {
-+        CRYPTO_THREAD_unlock(global_engine_lock);
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
-+                  ENGINE_R_NOT_INITIALISED);
-+        return 0;
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    if (!e->load_ssl_client_cert) {
-+        ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
-+                  ENGINE_R_NO_LOAD_FUNCTION);
-+        return 0;
-+    }
-+    return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
-+                                   ui_method, callback_data);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_rdrand.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_rdrand.c
-new file mode 100644
-index 0000000..b3defcb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_rdrand.c
-@@ -0,0 +1,110 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#if (defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
-+     defined(__x86_64) || defined(__x86_64__) || \
-+     defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ)
-+
-+size_t OPENSSL_ia32_rdrand(void);
-+
-+static int get_random_bytes(unsigned char *buf, int num)
-+{
-+    size_t rnd;
-+
-+    while (num >= (int)sizeof(size_t)) {
-+        if ((rnd = OPENSSL_ia32_rdrand()) == 0)
-+            return 0;
-+
-+        *((size_t *)buf) = rnd;
-+        buf += sizeof(size_t);
-+        num -= sizeof(size_t);
-+    }
-+    if (num) {
-+        if ((rnd = OPENSSL_ia32_rdrand()) == 0)
-+            return 0;
-+
-+        memcpy(buf, &rnd, num);
-+    }
-+
-+    return 1;
-+}
-+
-+static int random_status(void)
-+{
-+    return 1;
-+}
-+
-+static RAND_METHOD rdrand_meth = {
-+    NULL,                       /* seed */
-+    get_random_bytes,
-+    NULL,                       /* cleanup */
-+    NULL,                       /* add */
-+    get_random_bytes,
-+    random_status,
-+};
-+
-+static int rdrand_init(ENGINE *e)
-+{
-+    return 1;
-+}
-+
-+static const char *engine_e_rdrand_id = "rdrand";
-+static const char *engine_e_rdrand_name = "Intel RDRAND engine";
-+
-+static int bind_helper(ENGINE *e)
-+{
-+    if (!ENGINE_set_id(e, engine_e_rdrand_id) ||
-+        !ENGINE_set_name(e, engine_e_rdrand_name) ||
-+        !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) ||
-+        !ENGINE_set_init_function(e, rdrand_init) ||
-+        !ENGINE_set_RAND(e, &rdrand_meth))
-+        return 0;
-+
-+    return 1;
-+}
-+
-+static ENGINE *ENGINE_rdrand(void)
-+{
-+    ENGINE *ret = ENGINE_new();
-+    if (ret == NULL)
-+        return NULL;
-+    if (!bind_helper(ret)) {
-+        ENGINE_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+void engine_load_rdrand_int(void)
-+{
-+    extern unsigned int OPENSSL_ia32cap_P[];
-+
-+    if (OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) {
-+        ENGINE *toadd = ENGINE_rdrand();
-+        if (!toadd)
-+            return;
-+        ENGINE_add(toadd);
-+        ENGINE_free(toadd);
-+        ERR_clear_error();
-+    }
-+}
-+#else
-+void engine_load_rdrand_int(void)
-+{
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_table.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_table.c
-new file mode 100644
-index 0000000..219253a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/eng_table.c
-@@ -0,0 +1,303 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "eng_int.h"
-+
-+/* The type of the items in the table */
-+struct st_engine_pile {
-+    /* The 'nid' of this algorithm/mode */
-+    int nid;
-+    /* ENGINEs that implement this algorithm/mode. */
-+    STACK_OF(ENGINE) *sk;
-+    /* The default ENGINE to perform this algorithm/mode. */
-+    ENGINE *funct;
-+    /*
-+     * Zero if 'sk' is newer than the cached 'funct', non-zero otherwise
-+     */
-+    int uptodate;
-+};
-+
-+/* The type exposed in eng_int.h */
-+struct st_engine_table {
-+    LHASH_OF(ENGINE_PILE) piles;
-+};                              /* ENGINE_TABLE */
-+
-+typedef struct st_engine_pile_doall {
-+    engine_table_doall_cb *cb;
-+    void *arg;
-+} ENGINE_PILE_DOALL;
-+
-+/* Global flags (ENGINE_TABLE_FLAG_***). */
-+static unsigned int table_flags = 0;
-+
-+/* API function manipulating 'table_flags' */
-+unsigned int ENGINE_get_table_flags(void)
-+{
-+    return table_flags;
-+}
-+
-+void ENGINE_set_table_flags(unsigned int flags)
-+{
-+    table_flags = flags;
-+}
-+
-+/* Internal functions for the "piles" hash table */
-+static unsigned long engine_pile_hash(const ENGINE_PILE *c)
-+{
-+    return c->nid;
-+}
-+
-+static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
-+{
-+    return a->nid - b->nid;
-+}
-+
-+static int int_table_check(ENGINE_TABLE **t, int create)
-+{
-+    LHASH_OF(ENGINE_PILE) *lh;
-+
-+    if (*t)
-+        return 1;
-+    if (!create)
-+        return 0;
-+    if ((lh = lh_ENGINE_PILE_new(engine_pile_hash, engine_pile_cmp)) == NULL)
-+        return 0;
-+    *t = (ENGINE_TABLE *)lh;
-+    return 1;
-+}
-+
-+/*
-+ * Privately exposed (via eng_int.h) functions for adding and/or removing
-+ * ENGINEs from the implementation table
-+ */
-+int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
-+                          ENGINE *e, const int *nids, int num_nids,
-+                          int setdefault)
-+{
-+    int ret = 0, added = 0;
-+    ENGINE_PILE tmplate, *fnd;
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    if (!(*table))
-+        added = 1;
-+    if (!int_table_check(table, 1))
-+        goto end;
-+    if (added)
-+        /* The cleanup callback needs to be added */
-+        engine_cleanup_add_first(cleanup);
-+    while (num_nids--) {
-+        tmplate.nid = *nids;
-+        fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
-+        if (!fnd) {
-+            fnd = OPENSSL_malloc(sizeof(*fnd));
-+            if (fnd == NULL)
-+                goto end;
-+            fnd->uptodate = 1;
-+            fnd->nid = *nids;
-+            fnd->sk = sk_ENGINE_new_null();
-+            if (!fnd->sk) {
-+                OPENSSL_free(fnd);
-+                goto end;
-+            }
-+            fnd->funct = NULL;
-+            (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
-+        }
-+        /* A registration shouldn't add duplicate entries */
-+        (void)sk_ENGINE_delete_ptr(fnd->sk, e);
-+        /*
-+         * if 'setdefault', this ENGINE goes to the head of the list
-+         */
-+        if (!sk_ENGINE_push(fnd->sk, e))
-+            goto end;
-+        /* "touch" this ENGINE_PILE */
-+        fnd->uptodate = 0;
-+        if (setdefault) {
-+            if (!engine_unlocked_init(e)) {
-+                ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
-+                          ENGINE_R_INIT_FAILED);
-+                goto end;
-+            }
-+            if (fnd->funct)
-+                engine_unlocked_finish(fnd->funct, 0);
-+            fnd->funct = e;
-+            fnd->uptodate = 1;
-+        }
-+        nids++;
-+    }
-+    ret = 1;
-+ end:
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    return ret;
-+}
-+
-+static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
-+{
-+    int n;
-+    /* Iterate the 'c->sk' stack removing any occurrence of 'e' */
-+    while ((n = sk_ENGINE_find(pile->sk, e)) >= 0) {
-+        (void)sk_ENGINE_delete(pile->sk, n);
-+        pile->uptodate = 0;
-+    }
-+    if (pile->funct == e) {
-+        engine_unlocked_finish(e, 0);
-+        pile->funct = NULL;
-+    }
-+}
-+
-+IMPLEMENT_LHASH_DOALL_ARG(ENGINE_PILE, ENGINE);
-+
-+void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
-+{
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    if (int_table_check(table, 0))
-+        lh_ENGINE_PILE_doall_ENGINE(&(*table)->piles, int_unregister_cb, e);
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+}
-+
-+static void int_cleanup_cb_doall(ENGINE_PILE *p)
-+{
-+    if (!p)
-+        return;
-+    sk_ENGINE_free(p->sk);
-+    if (p->funct)
-+        engine_unlocked_finish(p->funct, 0);
-+    OPENSSL_free(p);
-+}
-+
-+void engine_table_cleanup(ENGINE_TABLE **table)
-+{
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    if (*table) {
-+        lh_ENGINE_PILE_doall(&(*table)->piles, int_cleanup_cb_doall);
-+        lh_ENGINE_PILE_free(&(*table)->piles);
-+        *table = NULL;
-+    }
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+}
-+
-+/* return a functional reference for a given 'nid' */
-+#ifndef ENGINE_TABLE_DEBUG
-+ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
-+#else
-+ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f,
-+                                int l)
-+#endif
-+{
-+    ENGINE *ret = NULL;
-+    ENGINE_PILE tmplate, *fnd = NULL;
-+    int initres, loop = 0;
-+
-+    if (!(*table)) {
-+#ifdef ENGINE_TABLE_DEBUG
-+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
-+                "registered!\n", f, l, nid);
-+#endif
-+        return NULL;
-+    }
-+    ERR_set_mark();
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    /*
-+     * Check again inside the lock otherwise we could race against cleanup
-+     * operations. But don't worry about a fprintf(stderr).
-+     */
-+    if (!int_table_check(table, 0))
-+        goto end;
-+    tmplate.nid = nid;
-+    fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
-+    if (!fnd)
-+        goto end;
-+    if (fnd->funct && engine_unlocked_init(fnd->funct)) {
-+#ifdef ENGINE_TABLE_DEBUG
-+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
-+                "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
-+#endif
-+        ret = fnd->funct;
-+        goto end;
-+    }
-+    if (fnd->uptodate) {
-+        ret = fnd->funct;
-+        goto end;
-+    }
-+ trynext:
-+    ret = sk_ENGINE_value(fnd->sk, loop++);
-+    if (!ret) {
-+#ifdef ENGINE_TABLE_DEBUG
-+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
-+                "registered implementations would initialise\n", f, l, nid);
-+#endif
-+        goto end;
-+    }
-+    /* Try to initialise the ENGINE? */
-+    if ((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
-+        initres = engine_unlocked_init(ret);
-+    else
-+        initres = 0;
-+    if (initres) {
-+        /* Update 'funct' */
-+        if ((fnd->funct != ret) && engine_unlocked_init(ret)) {
-+            /* If there was a previous default we release it. */
-+            if (fnd->funct)
-+                engine_unlocked_finish(fnd->funct, 0);
-+            fnd->funct = ret;
-+#ifdef ENGINE_TABLE_DEBUG
-+            fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
-+                    "setting default to '%s'\n", f, l, nid, ret->id);
-+#endif
-+        }
-+#ifdef ENGINE_TABLE_DEBUG
-+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
-+                "newly initialised '%s'\n", f, l, nid, ret->id);
-+#endif
-+        goto end;
-+    }
-+    goto trynext;
-+ end:
-+    /*
-+     * If it failed, it is unlikely to succeed again until some future
-+     * registrations have taken place. In all cases, we cache.
-+     */
-+    if (fnd)
-+        fnd->uptodate = 1;
-+#ifdef ENGINE_TABLE_DEBUG
-+    if (ret)
-+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
-+                "ENGINE '%s'\n", f, l, nid, ret->id);
-+    else
-+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
-+                "'no matching ENGINE'\n", f, l, nid);
-+#endif
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    /*
-+     * Whatever happened, any failed init()s are not failures in this
-+     * context, so clear our error state.
-+     */
-+    ERR_pop_to_mark();
-+    return ret;
-+}
-+
-+/* Table enumeration */
-+
-+static void int_dall(const ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
-+{
-+    dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
-+}
-+
-+IMPLEMENT_LHASH_DOALL_ARG_CONST(ENGINE_PILE, ENGINE_PILE_DOALL);
-+
-+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
-+                        void *arg)
-+{
-+    ENGINE_PILE_DOALL dall;
-+    dall.cb = cb;
-+    dall.arg = arg;
-+    if (table)
-+        lh_ENGINE_PILE_doall_ENGINE_PILE_DOALL(&table->piles, int_dall, &dall);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_asnmth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_asnmth.c
-new file mode 100644
-index 0000000..480267d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_asnmth.c
-@@ -0,0 +1,207 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+#include 
-+#include "internal/asn1_int.h"
-+
-+/*
-+ * If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
-+ * function that is used by EVP to hook in pkey_asn1_meth code and cache
-+ * defaults (etc), will display brief debugging summaries to stderr with the
-+ * 'nid'.
-+ */
-+/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
-+
-+static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
-+
-+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
-+{
-+    engine_table_unregister(&pkey_asn1_meth_table, e);
-+}
-+
-+static void engine_unregister_all_pkey_asn1_meths(void)
-+{
-+    engine_table_cleanup(&pkey_asn1_meth_table);
-+}
-+
-+int ENGINE_register_pkey_asn1_meths(ENGINE *e)
-+{
-+    if (e->pkey_asn1_meths) {
-+        const int *nids;
-+        int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
-+        if (num_nids > 0)
-+            return engine_table_register(&pkey_asn1_meth_table,
-+                                         engine_unregister_all_pkey_asn1_meths,
-+                                         e, nids, num_nids, 0);
-+    }
-+    return 1;
-+}
-+
-+void ENGINE_register_all_pkey_asn1_meths(void)
-+{
-+    ENGINE *e;
-+
-+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
-+        ENGINE_register_pkey_asn1_meths(e);
-+}
-+
-+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
-+{
-+    if (e->pkey_asn1_meths) {
-+        const int *nids;
-+        int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
-+        if (num_nids > 0)
-+            return engine_table_register(&pkey_asn1_meth_table,
-+                                         engine_unregister_all_pkey_asn1_meths,
-+                                         e, nids, num_nids, 1);
-+    }
-+    return 1;
-+}
-+
-+/*
-+ * Exposed API function to get a functional reference from the implementation
-+ * table (ie. try to get a functional reference from the tabled structural
-+ * references) for a given pkey_asn1_meth 'nid'
-+ */
-+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
-+{
-+    return engine_table_select(&pkey_asn1_meth_table, nid);
-+}
-+
-+/*
-+ * Obtains a pkey_asn1_meth implementation from an ENGINE functional
-+ * reference
-+ */
-+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
-+{
-+    EVP_PKEY_ASN1_METHOD *ret;
-+    ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
-+    if (!fn || !fn(e, &ret, NULL, nid)) {
-+        ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
-+                  ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+/* Gets the pkey_asn1_meth callback from an ENGINE structure */
-+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
-+{
-+    return e->pkey_asn1_meths;
-+}
-+
-+/* Sets the pkey_asn1_meth callback in an ENGINE structure */
-+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
-+{
-+    e->pkey_asn1_meths = f;
-+    return 1;
-+}
-+
-+/*
-+ * Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
-+ * ENGINE is destroyed
-+ */
-+
-+void engine_pkey_asn1_meths_free(ENGINE *e)
-+{
-+    int i;
-+    EVP_PKEY_ASN1_METHOD *pkm;
-+    if (e->pkey_asn1_meths) {
-+        const int *pknids;
-+        int npknids;
-+        npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
-+        for (i = 0; i < npknids; i++) {
-+            if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i])) {
-+                EVP_PKEY_asn1_free(pkm);
-+            }
-+        }
-+    }
-+}
-+
-+/*
-+ * Find a method based on a string. This does a linear search through all
-+ * implemented algorithms. This is OK in practice because only a small number
-+ * of algorithms are likely to be implemented in an engine and it is not used
-+ * for speed critical operations.
-+ */
-+
-+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
-+                                                          const char *str,
-+                                                          int len)
-+{
-+    int i, nidcount;
-+    const int *nids;
-+    EVP_PKEY_ASN1_METHOD *ameth;
-+    if (!e->pkey_asn1_meths)
-+        return NULL;
-+    if (len == -1)
-+        len = strlen(str);
-+    nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
-+    for (i = 0; i < nidcount; i++) {
-+        e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
-+        if (((int)strlen(ameth->pem_str) == len)
-+            && strncasecmp(ameth->pem_str, str, len) == 0)
-+            return ameth;
-+    }
-+    return NULL;
-+}
-+
-+typedef struct {
-+    ENGINE *e;
-+    const EVP_PKEY_ASN1_METHOD *ameth;
-+    const char *str;
-+    int len;
-+} ENGINE_FIND_STR;
-+
-+static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
-+{
-+    ENGINE_FIND_STR *lk = arg;
-+    int i;
-+    if (lk->ameth)
-+        return;
-+    for (i = 0; i < sk_ENGINE_num(sk); i++) {
-+        ENGINE *e = sk_ENGINE_value(sk, i);
-+        EVP_PKEY_ASN1_METHOD *ameth;
-+        e->pkey_asn1_meths(e, &ameth, NULL, nid);
-+        if (((int)strlen(ameth->pem_str) == lk->len)
-+                && strncasecmp(ameth->pem_str, lk->str, lk->len) == 0) {
-+            lk->e = e;
-+            lk->ameth = ameth;
-+            return;
-+        }
-+    }
-+}
-+
-+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
-+                                                      const char *str,
-+                                                      int len)
-+{
-+    ENGINE_FIND_STR fstr;
-+    fstr.e = NULL;
-+    fstr.ameth = NULL;
-+    fstr.str = str;
-+    fstr.len = len;
-+
-+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
-+        ENGINEerr(ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    CRYPTO_THREAD_write_lock(global_engine_lock);
-+    engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
-+    /* If found obtain a structural reference to engine */
-+    if (fstr.e) {
-+        fstr.e->struct_ref++;
-+        engine_ref_debug(fstr.e, 0, 1);
-+    }
-+    *pe = fstr.e;
-+    CRYPTO_THREAD_unlock(global_engine_lock);
-+    return fstr.ameth;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_cipher.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_cipher.c
-new file mode 100644
-index 0000000..ac49141
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_cipher.c
-@@ -0,0 +1,91 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+
-+static ENGINE_TABLE *cipher_table = NULL;
-+
-+void ENGINE_unregister_ciphers(ENGINE *e)
-+{
-+    engine_table_unregister(&cipher_table, e);
-+}
-+
-+static void engine_unregister_all_ciphers(void)
-+{
-+    engine_table_cleanup(&cipher_table);
-+}
-+
-+int ENGINE_register_ciphers(ENGINE *e)
-+{
-+    if (e->ciphers) {
-+        const int *nids;
-+        int num_nids = e->ciphers(e, NULL, &nids, 0);
-+        if (num_nids > 0)
-+            return engine_table_register(&cipher_table,
-+                                         engine_unregister_all_ciphers, e,
-+                                         nids, num_nids, 0);
-+    }
-+    return 1;
-+}
-+
-+void ENGINE_register_all_ciphers()
-+{
-+    ENGINE *e;
-+
-+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
-+        ENGINE_register_ciphers(e);
-+}
-+
-+int ENGINE_set_default_ciphers(ENGINE *e)
-+{
-+    if (e->ciphers) {
-+        const int *nids;
-+        int num_nids = e->ciphers(e, NULL, &nids, 0);
-+        if (num_nids > 0)
-+            return engine_table_register(&cipher_table,
-+                                         engine_unregister_all_ciphers, e,
-+                                         nids, num_nids, 1);
-+    }
-+    return 1;
-+}
-+
-+/*
-+ * Exposed API function to get a functional reference from the implementation
-+ * table (ie. try to get a functional reference from the tabled structural
-+ * references) for a given cipher 'nid'
-+ */
-+ENGINE *ENGINE_get_cipher_engine(int nid)
-+{
-+    return engine_table_select(&cipher_table, nid);
-+}
-+
-+/* Obtains a cipher implementation from an ENGINE functional reference */
-+const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid)
-+{
-+    const EVP_CIPHER *ret;
-+    ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
-+    if (!fn || !fn(e, &ret, NULL, nid)) {
-+        ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER, ENGINE_R_UNIMPLEMENTED_CIPHER);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+/* Gets the cipher callback from an ENGINE structure */
-+ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e)
-+{
-+    return e->ciphers;
-+}
-+
-+/* Sets the cipher callback in an ENGINE structure */
-+int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
-+{
-+    e->ciphers = f;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_dh.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_dh.c
-new file mode 100644
-index 0000000..c6440df
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_dh.c
-@@ -0,0 +1,72 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+
-+static ENGINE_TABLE *dh_table = NULL;
-+static const int dummy_nid = 1;
-+
-+void ENGINE_unregister_DH(ENGINE *e)
-+{
-+    engine_table_unregister(&dh_table, e);
-+}
-+
-+static void engine_unregister_all_DH(void)
-+{
-+    engine_table_cleanup(&dh_table);
-+}
-+
-+int ENGINE_register_DH(ENGINE *e)
-+{
-+    if (e->dh_meth)
-+        return engine_table_register(&dh_table,
-+                                     engine_unregister_all_DH, e, &dummy_nid,
-+                                     1, 0);
-+    return 1;
-+}
-+
-+void ENGINE_register_all_DH()
-+{
-+    ENGINE *e;
-+
-+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
-+        ENGINE_register_DH(e);
-+}
-+
-+int ENGINE_set_default_DH(ENGINE *e)
-+{
-+    if (e->dh_meth)
-+        return engine_table_register(&dh_table,
-+                                     engine_unregister_all_DH, e, &dummy_nid,
-+                                     1, 1);
-+    return 1;
-+}
-+
-+/*
-+ * Exposed API function to get a functional reference from the implementation
-+ * table (ie. try to get a functional reference from the tabled structural
-+ * references).
-+ */
-+ENGINE *ENGINE_get_default_DH(void)
-+{
-+    return engine_table_select(&dh_table, dummy_nid);
-+}
-+
-+/* Obtains an DH implementation from an ENGINE functional reference */
-+const DH_METHOD *ENGINE_get_DH(const ENGINE *e)
-+{
-+    return e->dh_meth;
-+}
-+
-+/* Sets an DH implementation in an ENGINE structure */
-+int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth)
-+{
-+    e->dh_meth = dh_meth;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_digest.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_digest.c
-new file mode 100644
-index 0000000..194b9c7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_digest.c
-@@ -0,0 +1,91 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+
-+static ENGINE_TABLE *digest_table = NULL;
-+
-+void ENGINE_unregister_digests(ENGINE *e)
-+{
-+    engine_table_unregister(&digest_table, e);
-+}
-+
-+static void engine_unregister_all_digests(void)
-+{
-+    engine_table_cleanup(&digest_table);
-+}
-+
-+int ENGINE_register_digests(ENGINE *e)
-+{
-+    if (e->digests) {
-+        const int *nids;
-+        int num_nids = e->digests(e, NULL, &nids, 0);
-+        if (num_nids > 0)
-+            return engine_table_register(&digest_table,
-+                                         engine_unregister_all_digests, e,
-+                                         nids, num_nids, 0);
-+    }
-+    return 1;
-+}
-+
-+void ENGINE_register_all_digests()
-+{
-+    ENGINE *e;
-+
-+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
-+        ENGINE_register_digests(e);
-+}
-+
-+int ENGINE_set_default_digests(ENGINE *e)
-+{
-+    if (e->digests) {
-+        const int *nids;
-+        int num_nids = e->digests(e, NULL, &nids, 0);
-+        if (num_nids > 0)
-+            return engine_table_register(&digest_table,
-+                                         engine_unregister_all_digests, e,
-+                                         nids, num_nids, 1);
-+    }
-+    return 1;
-+}
-+
-+/*
-+ * Exposed API function to get a functional reference from the implementation
-+ * table (ie. try to get a functional reference from the tabled structural
-+ * references) for a given digest 'nid'
-+ */
-+ENGINE *ENGINE_get_digest_engine(int nid)
-+{
-+    return engine_table_select(&digest_table, nid);
-+}
-+
-+/* Obtains a digest implementation from an ENGINE functional reference */
-+const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid)
-+{
-+    const EVP_MD *ret;
-+    ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e);
-+    if (!fn || !fn(e, &ret, NULL, nid)) {
-+        ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST, ENGINE_R_UNIMPLEMENTED_DIGEST);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+/* Gets the digest callback from an ENGINE structure */
-+ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e)
-+{
-+    return e->digests;
-+}
-+
-+/* Sets the digest callback in an ENGINE structure */
-+int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f)
-+{
-+    e->digests = f;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_dsa.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_dsa.c
-new file mode 100644
-index 0000000..fdb80cd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_dsa.c
-@@ -0,0 +1,72 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+
-+static ENGINE_TABLE *dsa_table = NULL;
-+static const int dummy_nid = 1;
-+
-+void ENGINE_unregister_DSA(ENGINE *e)
-+{
-+    engine_table_unregister(&dsa_table, e);
-+}
-+
-+static void engine_unregister_all_DSA(void)
-+{
-+    engine_table_cleanup(&dsa_table);
-+}
-+
-+int ENGINE_register_DSA(ENGINE *e)
-+{
-+    if (e->dsa_meth)
-+        return engine_table_register(&dsa_table,
-+                                     engine_unregister_all_DSA, e, &dummy_nid,
-+                                     1, 0);
-+    return 1;
-+}
-+
-+void ENGINE_register_all_DSA()
-+{
-+    ENGINE *e;
-+
-+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
-+        ENGINE_register_DSA(e);
-+}
-+
-+int ENGINE_set_default_DSA(ENGINE *e)
-+{
-+    if (e->dsa_meth)
-+        return engine_table_register(&dsa_table,
-+                                     engine_unregister_all_DSA, e, &dummy_nid,
-+                                     1, 1);
-+    return 1;
-+}
-+
-+/*
-+ * Exposed API function to get a functional reference from the implementation
-+ * table (ie. try to get a functional reference from the tabled structural
-+ * references).
-+ */
-+ENGINE *ENGINE_get_default_DSA(void)
-+{
-+    return engine_table_select(&dsa_table, dummy_nid);
-+}
-+
-+/* Obtains an DSA implementation from an ENGINE functional reference */
-+const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e)
-+{
-+    return e->dsa_meth;
-+}
-+
-+/* Sets an DSA implementation in an ENGINE structure */
-+int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth)
-+{
-+    e->dsa_meth = dsa_meth;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_eckey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_eckey.c
-new file mode 100644
-index 0000000..75750b2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_eckey.c
-@@ -0,0 +1,72 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+
-+static ENGINE_TABLE *dh_table = NULL;
-+static const int dummy_nid = 1;
-+
-+void ENGINE_unregister_EC(ENGINE *e)
-+{
-+    engine_table_unregister(&dh_table, e);
-+}
-+
-+static void engine_unregister_all_EC(void)
-+{
-+    engine_table_cleanup(&dh_table);
-+}
-+
-+int ENGINE_register_EC(ENGINE *e)
-+{
-+    if (e->ec_meth != NULL)
-+        return engine_table_register(&dh_table,
-+                                     engine_unregister_all_EC, e, &dummy_nid,
-+                                     1, 0);
-+    return 1;
-+}
-+
-+void ENGINE_register_all_EC()
-+{
-+    ENGINE *e;
-+
-+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
-+        ENGINE_register_EC(e);
-+}
-+
-+int ENGINE_set_default_EC(ENGINE *e)
-+{
-+    if (e->ec_meth != NULL)
-+        return engine_table_register(&dh_table,
-+                                     engine_unregister_all_EC, e, &dummy_nid,
-+                                     1, 1);
-+    return 1;
-+}
-+
-+/*
-+ * Exposed API function to get a functional reference from the implementation
-+ * table (ie. try to get a functional reference from the tabled structural
-+ * references).
-+ */
-+ENGINE *ENGINE_get_default_EC(void)
-+{
-+    return engine_table_select(&dh_table, dummy_nid);
-+}
-+
-+/* Obtains an EC_KEY implementation from an ENGINE functional reference */
-+const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *e)
-+{
-+    return e->ec_meth;
-+}
-+
-+/* Sets an EC_KEY implementation in an ENGINE structure */
-+int ENGINE_set_EC(ENGINE *e, const EC_KEY_METHOD *ec_meth)
-+{
-+    e->ec_meth = ec_meth;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_pkmeth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_pkmeth.c
-new file mode 100644
-index 0000000..2e82d85
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_pkmeth.c
-@@ -0,0 +1,114 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+#include 
-+
-+static ENGINE_TABLE *pkey_meth_table = NULL;
-+
-+void ENGINE_unregister_pkey_meths(ENGINE *e)
-+{
-+    engine_table_unregister(&pkey_meth_table, e);
-+}
-+
-+static void engine_unregister_all_pkey_meths(void)
-+{
-+    engine_table_cleanup(&pkey_meth_table);
-+}
-+
-+int ENGINE_register_pkey_meths(ENGINE *e)
-+{
-+    if (e->pkey_meths) {
-+        const int *nids;
-+        int num_nids = e->pkey_meths(e, NULL, &nids, 0);
-+        if (num_nids > 0)
-+            return engine_table_register(&pkey_meth_table,
-+                                         engine_unregister_all_pkey_meths, e,
-+                                         nids, num_nids, 0);
-+    }
-+    return 1;
-+}
-+
-+void ENGINE_register_all_pkey_meths()
-+{
-+    ENGINE *e;
-+
-+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
-+        ENGINE_register_pkey_meths(e);
-+}
-+
-+int ENGINE_set_default_pkey_meths(ENGINE *e)
-+{
-+    if (e->pkey_meths) {
-+        const int *nids;
-+        int num_nids = e->pkey_meths(e, NULL, &nids, 0);
-+        if (num_nids > 0)
-+            return engine_table_register(&pkey_meth_table,
-+                                         engine_unregister_all_pkey_meths, e,
-+                                         nids, num_nids, 1);
-+    }
-+    return 1;
-+}
-+
-+/*
-+ * Exposed API function to get a functional reference from the implementation
-+ * table (ie. try to get a functional reference from the tabled structural
-+ * references) for a given pkey_meth 'nid'
-+ */
-+ENGINE *ENGINE_get_pkey_meth_engine(int nid)
-+{
-+    return engine_table_select(&pkey_meth_table, nid);
-+}
-+
-+/* Obtains a pkey_meth implementation from an ENGINE functional reference */
-+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
-+{
-+    EVP_PKEY_METHOD *ret;
-+    ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
-+    if (!fn || !fn(e, &ret, NULL, nid)) {
-+        ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
-+                  ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+/* Gets the pkey_meth callback from an ENGINE structure */
-+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
-+{
-+    return e->pkey_meths;
-+}
-+
-+/* Sets the pkey_meth callback in an ENGINE structure */
-+int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
-+{
-+    e->pkey_meths = f;
-+    return 1;
-+}
-+
-+/*
-+ * Internal function to free up EVP_PKEY_METHOD structures before an ENGINE
-+ * is destroyed
-+ */
-+
-+void engine_pkey_meths_free(ENGINE *e)
-+{
-+    int i;
-+    EVP_PKEY_METHOD *pkm;
-+    if (e->pkey_meths) {
-+        const int *pknids;
-+        int npknids;
-+        npknids = e->pkey_meths(e, NULL, &pknids, 0);
-+        for (i = 0; i < npknids; i++) {
-+            if (e->pkey_meths(e, &pkm, NULL, pknids[i])) {
-+                EVP_PKEY_meth_free(pkm);
-+            }
-+        }
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_rand.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_rand.c
-new file mode 100644
-index 0000000..225e7c8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_rand.c
-@@ -0,0 +1,72 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+
-+static ENGINE_TABLE *rand_table = NULL;
-+static const int dummy_nid = 1;
-+
-+void ENGINE_unregister_RAND(ENGINE *e)
-+{
-+    engine_table_unregister(&rand_table, e);
-+}
-+
-+static void engine_unregister_all_RAND(void)
-+{
-+    engine_table_cleanup(&rand_table);
-+}
-+
-+int ENGINE_register_RAND(ENGINE *e)
-+{
-+    if (e->rand_meth)
-+        return engine_table_register(&rand_table,
-+                                     engine_unregister_all_RAND, e,
-+                                     &dummy_nid, 1, 0);
-+    return 1;
-+}
-+
-+void ENGINE_register_all_RAND()
-+{
-+    ENGINE *e;
-+
-+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
-+        ENGINE_register_RAND(e);
-+}
-+
-+int ENGINE_set_default_RAND(ENGINE *e)
-+{
-+    if (e->rand_meth)
-+        return engine_table_register(&rand_table,
-+                                     engine_unregister_all_RAND, e,
-+                                     &dummy_nid, 1, 1);
-+    return 1;
-+}
-+
-+/*
-+ * Exposed API function to get a functional reference from the implementation
-+ * table (ie. try to get a functional reference from the tabled structural
-+ * references).
-+ */
-+ENGINE *ENGINE_get_default_RAND(void)
-+{
-+    return engine_table_select(&rand_table, dummy_nid);
-+}
-+
-+/* Obtains an RAND implementation from an ENGINE functional reference */
-+const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e)
-+{
-+    return e->rand_meth;
-+}
-+
-+/* Sets an RAND implementation in an ENGINE structure */
-+int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth)
-+{
-+    e->rand_meth = rand_meth;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_rsa.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_rsa.c
-new file mode 100644
-index 0000000..e2cc680
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/engine/tb_rsa.c
-@@ -0,0 +1,72 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "eng_int.h"
-+
-+static ENGINE_TABLE *rsa_table = NULL;
-+static const int dummy_nid = 1;
-+
-+void ENGINE_unregister_RSA(ENGINE *e)
-+{
-+    engine_table_unregister(&rsa_table, e);
-+}
-+
-+static void engine_unregister_all_RSA(void)
-+{
-+    engine_table_cleanup(&rsa_table);
-+}
-+
-+int ENGINE_register_RSA(ENGINE *e)
-+{
-+    if (e->rsa_meth)
-+        return engine_table_register(&rsa_table,
-+                                     engine_unregister_all_RSA, e, &dummy_nid,
-+                                     1, 0);
-+    return 1;
-+}
-+
-+void ENGINE_register_all_RSA()
-+{
-+    ENGINE *e;
-+
-+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
-+        ENGINE_register_RSA(e);
-+}
-+
-+int ENGINE_set_default_RSA(ENGINE *e)
-+{
-+    if (e->rsa_meth)
-+        return engine_table_register(&rsa_table,
-+                                     engine_unregister_all_RSA, e, &dummy_nid,
-+                                     1, 1);
-+    return 1;
-+}
-+
-+/*
-+ * Exposed API function to get a functional reference from the implementation
-+ * table (ie. try to get a functional reference from the tabled structural
-+ * references).
-+ */
-+ENGINE *ENGINE_get_default_RSA(void)
-+{
-+    return engine_table_select(&rsa_table, dummy_nid);
-+}
-+
-+/* Obtains an RSA implementation from an ENGINE functional reference */
-+const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e)
-+{
-+    return e->rsa_meth;
-+}
-+
-+/* Sets an RSA implementation in an ENGINE structure */
-+int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth)
-+{
-+    e->rsa_meth = rsa_meth;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/README b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/README
-new file mode 100644
-index 0000000..6d2ce0c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/README
-@@ -0,0 +1,44 @@
-+Adding new libraries
-+--------------------
-+
-+When adding a new sub-library to OpenSSL, assign it a library number
-+ERR_LIB_XXX, define a macro XXXerr() (both in err.h), add its
-+name to ERR_str_libraries[] (in crypto/err/err.c), and add
-+ERR_load_XXX_strings() to the ERR_load_crypto_strings() function
-+(in crypto/err/err_all.c). Finally, add an entry:
-+
-+    L      XXX     xxx.h   xxx_err.c
-+
-+to crypto/err/openssl.ec, and add xxx_err.c to the Makefile.
-+Running make errors will then generate a file xxx_err.c, and
-+add all error codes used in the library to xxx.h.
-+
-+Additionally the library include file must have a certain form.
-+Typically it will initially look like this:
-+
-+    #ifndef HEADER_XXX_H
-+    #define HEADER_XXX_H
-+
-+    #ifdef __cplusplus
-+    extern "C" {
-+    #endif
-+
-+    /* Include files */
-+
-+    #include 
-+    #include 
-+
-+    /* Macros, structures and function prototypes */
-+
-+
-+    /* BEGIN ERROR CODES */
-+
-+The BEGIN ERROR CODES sequence is used by the error code
-+generation script as the point to place new error codes, any text
-+after this point will be overwritten when make errors is run.
-+The closing #endif etc will be automatically added by the script.
-+
-+The generated C error code file xxx_err.c will load the header
-+files stdio.h, openssl/err.h and openssl/xxx.h so the
-+header file must load any additional header files containing any
-+definitions it uses.
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/build.info
-new file mode 100644
-index 0000000..6163d95
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        err.c err_all.c err_prn.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/err.c
-new file mode 100644
-index 0000000..44a293a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/err.c
-@@ -0,0 +1,770 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+static void err_load_strings(int lib, ERR_STRING_DATA *str);
-+
-+static void ERR_STATE_free(ERR_STATE *s);
-+#ifndef OPENSSL_NO_ERR
-+static ERR_STRING_DATA ERR_str_libraries[] = {
-+    {ERR_PACK(ERR_LIB_NONE, 0, 0), "unknown library"},
-+    {ERR_PACK(ERR_LIB_SYS, 0, 0), "system library"},
-+    {ERR_PACK(ERR_LIB_BN, 0, 0), "bignum routines"},
-+    {ERR_PACK(ERR_LIB_RSA, 0, 0), "rsa routines"},
-+    {ERR_PACK(ERR_LIB_DH, 0, 0), "Diffie-Hellman routines"},
-+    {ERR_PACK(ERR_LIB_EVP, 0, 0), "digital envelope routines"},
-+    {ERR_PACK(ERR_LIB_BUF, 0, 0), "memory buffer routines"},
-+    {ERR_PACK(ERR_LIB_OBJ, 0, 0), "object identifier routines"},
-+    {ERR_PACK(ERR_LIB_PEM, 0, 0), "PEM routines"},
-+    {ERR_PACK(ERR_LIB_DSA, 0, 0), "dsa routines"},
-+    {ERR_PACK(ERR_LIB_X509, 0, 0), "x509 certificate routines"},
-+    {ERR_PACK(ERR_LIB_ASN1, 0, 0), "asn1 encoding routines"},
-+    {ERR_PACK(ERR_LIB_CONF, 0, 0), "configuration file routines"},
-+    {ERR_PACK(ERR_LIB_CRYPTO, 0, 0), "common libcrypto routines"},
-+    {ERR_PACK(ERR_LIB_EC, 0, 0), "elliptic curve routines"},
-+    {ERR_PACK(ERR_LIB_ECDSA, 0, 0), "ECDSA routines"},
-+    {ERR_PACK(ERR_LIB_ECDH, 0, 0), "ECDH routines"},
-+    {ERR_PACK(ERR_LIB_SSL, 0, 0), "SSL routines"},
-+    {ERR_PACK(ERR_LIB_BIO, 0, 0), "BIO routines"},
-+    {ERR_PACK(ERR_LIB_PKCS7, 0, 0), "PKCS7 routines"},
-+    {ERR_PACK(ERR_LIB_X509V3, 0, 0), "X509 V3 routines"},
-+    {ERR_PACK(ERR_LIB_PKCS12, 0, 0), "PKCS12 routines"},
-+    {ERR_PACK(ERR_LIB_RAND, 0, 0), "random number generator"},
-+    {ERR_PACK(ERR_LIB_DSO, 0, 0), "DSO support routines"},
-+    {ERR_PACK(ERR_LIB_TS, 0, 0), "time stamp routines"},
-+    {ERR_PACK(ERR_LIB_ENGINE, 0, 0), "engine routines"},
-+    {ERR_PACK(ERR_LIB_OCSP, 0, 0), "OCSP routines"},
-+    {ERR_PACK(ERR_LIB_UI, 0, 0), "UI routines"},
-+    {ERR_PACK(ERR_LIB_FIPS, 0, 0), "FIPS routines"},
-+    {ERR_PACK(ERR_LIB_CMS, 0, 0), "CMS routines"},
-+    {ERR_PACK(ERR_LIB_HMAC, 0, 0), "HMAC routines"},
-+    {ERR_PACK(ERR_LIB_CT, 0, 0), "CT routines"},
-+    {ERR_PACK(ERR_LIB_ASYNC, 0, 0), "ASYNC routines"},
-+    {ERR_PACK(ERR_LIB_KDF, 0, 0), "KDF routines"},
-+    {0, NULL},
-+};
-+
-+static ERR_STRING_DATA ERR_str_functs[] = {
-+    {ERR_PACK(0, SYS_F_FOPEN, 0), "fopen"},
-+    {ERR_PACK(0, SYS_F_CONNECT, 0), "connect"},
-+    {ERR_PACK(0, SYS_F_GETSERVBYNAME, 0), "getservbyname"},
-+    {ERR_PACK(0, SYS_F_SOCKET, 0), "socket"},
-+    {ERR_PACK(0, SYS_F_IOCTLSOCKET, 0), "ioctlsocket"},
-+    {ERR_PACK(0, SYS_F_BIND, 0), "bind"},
-+    {ERR_PACK(0, SYS_F_LISTEN, 0), "listen"},
-+    {ERR_PACK(0, SYS_F_ACCEPT, 0), "accept"},
-+# ifdef OPENSSL_SYS_WINDOWS
-+    {ERR_PACK(0, SYS_F_WSASTARTUP, 0), "WSAstartup"},
-+# endif
-+    {ERR_PACK(0, SYS_F_OPENDIR, 0), "opendir"},
-+    {ERR_PACK(0, SYS_F_FREAD, 0), "fread"},
-+    {ERR_PACK(0, SYS_F_GETADDRINFO, 0), "getaddrinfo"},
-+    {ERR_PACK(0, SYS_F_GETNAMEINFO, 0), "getnameinfo"},
-+    {ERR_PACK(0, SYS_F_SETSOCKOPT, 0), "setsockopt"},
-+    {ERR_PACK(0, SYS_F_GETSOCKOPT, 0), "getsockopt"},
-+    {ERR_PACK(0, SYS_F_GETSOCKNAME, 0), "getsockname"},
-+    {ERR_PACK(0, SYS_F_GETHOSTBYNAME, 0), "gethostbyname"},
-+    {0, NULL},
-+};
-+
-+static ERR_STRING_DATA ERR_str_reasons[] = {
-+    {ERR_R_SYS_LIB, "system lib"},
-+    {ERR_R_BN_LIB, "BN lib"},
-+    {ERR_R_RSA_LIB, "RSA lib"},
-+    {ERR_R_DH_LIB, "DH lib"},
-+    {ERR_R_EVP_LIB, "EVP lib"},
-+    {ERR_R_BUF_LIB, "BUF lib"},
-+    {ERR_R_OBJ_LIB, "OBJ lib"},
-+    {ERR_R_PEM_LIB, "PEM lib"},
-+    {ERR_R_DSA_LIB, "DSA lib"},
-+    {ERR_R_X509_LIB, "X509 lib"},
-+    {ERR_R_ASN1_LIB, "ASN1 lib"},
-+    {ERR_R_EC_LIB, "EC lib"},
-+    {ERR_R_BIO_LIB, "BIO lib"},
-+    {ERR_R_PKCS7_LIB, "PKCS7 lib"},
-+    {ERR_R_X509V3_LIB, "X509V3 lib"},
-+    {ERR_R_ENGINE_LIB, "ENGINE lib"},
-+    {ERR_R_ECDSA_LIB, "ECDSA lib"},
-+
-+    {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"},
-+    {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"},
-+
-+    {ERR_R_FATAL, "fatal"},
-+    {ERR_R_MALLOC_FAILURE, "malloc failure"},
-+    {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,
-+     "called a function you should not call"},
-+    {ERR_R_PASSED_NULL_PARAMETER, "passed a null parameter"},
-+    {ERR_R_INTERNAL_ERROR, "internal error"},
-+    {ERR_R_DISABLED, "called a function that was disabled at compile-time"},
-+    {ERR_R_INIT_FAIL, "init fail"},
-+
-+    {0, NULL},
-+};
-+#endif
-+
-+static CRYPTO_ONCE err_init = CRYPTO_ONCE_STATIC_INIT;
-+static CRYPTO_THREAD_LOCAL err_thread_local;
-+
-+static CRYPTO_ONCE err_string_init = CRYPTO_ONCE_STATIC_INIT;
-+static CRYPTO_RWLOCK *err_string_lock;
-+
-+static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
-+
-+/*
-+ * The internal state
-+ */
-+
-+static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
-+static int int_err_library_number = ERR_LIB_USER;
-+
-+static unsigned long get_error_values(int inc, int top, const char **file,
-+                                      int *line, const char **data,
-+                                      int *flags);
-+
-+static unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
-+{
-+    unsigned long ret, l;
-+
-+    l = a->error;
-+    ret = l ^ ERR_GET_LIB(l) ^ ERR_GET_FUNC(l);
-+    return (ret ^ ret % 19 * 13);
-+}
-+
-+static int err_string_data_cmp(const ERR_STRING_DATA *a,
-+                               const ERR_STRING_DATA *b)
-+{
-+    return (int)(a->error - b->error);
-+}
-+
-+static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
-+{
-+    ERR_STRING_DATA *p = NULL;
-+
-+    CRYPTO_THREAD_read_lock(err_string_lock);
-+    if (int_error_hash != NULL)
-+        p = lh_ERR_STRING_DATA_retrieve(int_error_hash, d);
-+    CRYPTO_THREAD_unlock(err_string_lock);
-+
-+    return p;
-+}
-+
-+#ifndef OPENSSL_NO_ERR
-+# define NUM_SYS_STR_REASONS 127
-+# define LEN_SYS_STR_REASON 32
-+
-+static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
-+/*
-+ * SYS_str_reasons is filled with copies of strerror() results at
-+ * initialization. 'errno' values up to 127 should cover all usual errors,
-+ * others will be displayed numerically by ERR_error_string. It is crucial
-+ * that we have something for each reason code that occurs in
-+ * ERR_str_reasons, or bogus reason strings will be returned for SYSerr(),
-+ * which always gets an errno value and never one of those 'standard' reason
-+ * codes.
-+ */
-+
-+static void build_SYS_str_reasons(void)
-+{
-+    /* OPENSSL_malloc cannot be used here, use static storage instead */
-+    static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
-+    static int init = 1;
-+    int i;
-+
-+    CRYPTO_THREAD_write_lock(err_string_lock);
-+    if (!init) {
-+        CRYPTO_THREAD_unlock(err_string_lock);
-+        return;
-+    }
-+
-+    for (i = 1; i <= NUM_SYS_STR_REASONS; i++) {
-+        ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
-+
-+        str->error = (unsigned long)i;
-+        if (str->string == NULL) {
-+            char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
-+            if (openssl_strerror_r(i, *dest, sizeof(*dest)))
-+                str->string = *dest;
-+        }
-+        if (str->string == NULL)
-+            str->string = "unknown";
-+    }
-+
-+    /*
-+     * Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, as
-+     * required by ERR_load_strings.
-+     */
-+
-+    init = 0;
-+
-+    CRYPTO_THREAD_unlock(err_string_lock);
-+}
-+#endif
-+
-+#define err_clear_data(p,i) \
-+        do { \
-+        if ((p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
-+                {  \
-+                OPENSSL_free((p)->err_data[i]); \
-+                (p)->err_data[i]=NULL; \
-+                } \
-+        (p)->err_data_flags[i]=0; \
-+        } while(0)
-+
-+#define err_clear(p,i) \
-+        do { \
-+        (p)->err_flags[i]=0; \
-+        (p)->err_buffer[i]=0; \
-+        err_clear_data(p,i); \
-+        (p)->err_file[i]=NULL; \
-+        (p)->err_line[i]= -1; \
-+        } while(0)
-+
-+static void ERR_STATE_free(ERR_STATE *s)
-+{
-+    int i;
-+
-+    if (s == NULL)
-+        return;
-+
-+    for (i = 0; i < ERR_NUM_ERRORS; i++) {
-+        err_clear_data(s, i);
-+    }
-+    OPENSSL_free(s);
-+}
-+
-+DEFINE_RUN_ONCE_STATIC(do_err_strings_init)
-+{
-+    OPENSSL_init_crypto(0, NULL);
-+    err_string_lock = CRYPTO_THREAD_lock_new();
-+    return err_string_lock != NULL;
-+}
-+
-+void err_cleanup(void)
-+{
-+    CRYPTO_THREAD_lock_free(err_string_lock);
-+    err_string_lock = NULL;
-+}
-+
-+int ERR_load_ERR_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+    if (!RUN_ONCE(&err_string_init, do_err_strings_init))
-+        return 0;
-+
-+    err_load_strings(0, ERR_str_libraries);
-+    err_load_strings(0, ERR_str_reasons);
-+    err_load_strings(ERR_LIB_SYS, ERR_str_functs);
-+    build_SYS_str_reasons();
-+    err_load_strings(ERR_LIB_SYS, SYS_str_reasons);
-+#endif
-+    return 1;
-+}
-+
-+static void err_load_strings(int lib, ERR_STRING_DATA *str)
-+{
-+    CRYPTO_THREAD_write_lock(err_string_lock);
-+    if (int_error_hash == NULL)
-+        int_error_hash = lh_ERR_STRING_DATA_new(err_string_data_hash,
-+                                                err_string_data_cmp);
-+    if (int_error_hash != NULL) {
-+        for (; str->error; str++) {
-+            if (lib)
-+                str->error |= ERR_PACK(lib, 0, 0);
-+            (void)lh_ERR_STRING_DATA_insert(int_error_hash, str);
-+        }
-+    }
-+    CRYPTO_THREAD_unlock(err_string_lock);
-+}
-+
-+int ERR_load_strings(int lib, ERR_STRING_DATA *str)
-+{
-+    if (ERR_load_ERR_strings() == 0)
-+        return 0;
-+    err_load_strings(lib, str);
-+    return 1;
-+}
-+
-+int ERR_unload_strings(int lib, ERR_STRING_DATA *str)
-+{
-+    if (!RUN_ONCE(&err_string_init, do_err_strings_init))
-+        return 0;
-+
-+    CRYPTO_THREAD_write_lock(err_string_lock);
-+    if (int_error_hash != NULL) {
-+        for (; str->error; str++) {
-+            if (lib)
-+                str->error |= ERR_PACK(lib, 0, 0);
-+            (void)lh_ERR_STRING_DATA_delete(int_error_hash, str);
-+        }
-+    }
-+    CRYPTO_THREAD_unlock(err_string_lock);
-+
-+    return 1;
-+}
-+
-+void err_free_strings_int(void)
-+{
-+    if (!RUN_ONCE(&err_string_init, do_err_strings_init))
-+        return;
-+
-+    CRYPTO_THREAD_write_lock(err_string_lock);
-+    lh_ERR_STRING_DATA_free(int_error_hash);
-+    int_error_hash = NULL;
-+    CRYPTO_THREAD_unlock(err_string_lock);
-+}
-+
-+/********************************************************/
-+
-+void ERR_put_error(int lib, int func, int reason, const char *file, int line)
-+{
-+    ERR_STATE *es;
-+
-+#ifdef _OSD_POSIX
-+    /*
-+     * In the BS2000-OSD POSIX subsystem, the compiler generates path names
-+     * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to
-+     * something sensible. @@@ We shouldn't modify a const string, though.
-+     */
-+    if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) {
-+        char *end;
-+
-+        /* Skip the "*POSIX(" prefix */
-+        file += sizeof("*POSIX(") - 1;
-+        end = &file[strlen(file) - 1];
-+        if (*end == ')')
-+            *end = '\0';
-+        /* Optional: use the basename of the path only. */
-+        if ((end = strrchr(file, '/')) != NULL)
-+            file = &end[1];
-+    }
-+#endif
-+    es = ERR_get_state();
-+
-+    es->top = (es->top + 1) % ERR_NUM_ERRORS;
-+    if (es->top == es->bottom)
-+        es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS;
-+    es->err_flags[es->top] = 0;
-+    es->err_buffer[es->top] = ERR_PACK(lib, func, reason);
-+    es->err_file[es->top] = file;
-+    es->err_line[es->top] = line;
-+    err_clear_data(es, es->top);
-+}
-+
-+void ERR_clear_error(void)
-+{
-+    int i;
-+    ERR_STATE *es;
-+
-+    es = ERR_get_state();
-+
-+    for (i = 0; i < ERR_NUM_ERRORS; i++) {
-+        err_clear(es, i);
-+    }
-+    es->top = es->bottom = 0;
-+}
-+
-+unsigned long ERR_get_error(void)
-+{
-+    return (get_error_values(1, 0, NULL, NULL, NULL, NULL));
-+}
-+
-+unsigned long ERR_get_error_line(const char **file, int *line)
-+{
-+    return (get_error_values(1, 0, file, line, NULL, NULL));
-+}
-+
-+unsigned long ERR_get_error_line_data(const char **file, int *line,
-+                                      const char **data, int *flags)
-+{
-+    return (get_error_values(1, 0, file, line, data, flags));
-+}
-+
-+unsigned long ERR_peek_error(void)
-+{
-+    return (get_error_values(0, 0, NULL, NULL, NULL, NULL));
-+}
-+
-+unsigned long ERR_peek_error_line(const char **file, int *line)
-+{
-+    return (get_error_values(0, 0, file, line, NULL, NULL));
-+}
-+
-+unsigned long ERR_peek_error_line_data(const char **file, int *line,
-+                                       const char **data, int *flags)
-+{
-+    return (get_error_values(0, 0, file, line, data, flags));
-+}
-+
-+unsigned long ERR_peek_last_error(void)
-+{
-+    return (get_error_values(0, 1, NULL, NULL, NULL, NULL));
-+}
-+
-+unsigned long ERR_peek_last_error_line(const char **file, int *line)
-+{
-+    return (get_error_values(0, 1, file, line, NULL, NULL));
-+}
-+
-+unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
-+                                            const char **data, int *flags)
-+{
-+    return (get_error_values(0, 1, file, line, data, flags));
-+}
-+
-+static unsigned long get_error_values(int inc, int top, const char **file,
-+                                      int *line, const char **data,
-+                                      int *flags)
-+{
-+    int i = 0;
-+    ERR_STATE *es;
-+    unsigned long ret;
-+
-+    es = ERR_get_state();
-+
-+    if (inc && top) {
-+        if (file)
-+            *file = "";
-+        if (line)
-+            *line = 0;
-+        if (data)
-+            *data = "";
-+        if (flags)
-+            *flags = 0;
-+
-+        return ERR_R_INTERNAL_ERROR;
-+    }
-+
-+    if (es->bottom == es->top)
-+        return 0;
-+    if (top)
-+        i = es->top;            /* last error */
-+    else
-+        i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */
-+
-+    ret = es->err_buffer[i];
-+    if (inc) {
-+        es->bottom = i;
-+        es->err_buffer[i] = 0;
-+    }
-+
-+    if ((file != NULL) && (line != NULL)) {
-+        if (es->err_file[i] == NULL) {
-+            *file = "NA";
-+            if (line != NULL)
-+                *line = 0;
-+        } else {
-+            *file = es->err_file[i];
-+            if (line != NULL)
-+                *line = es->err_line[i];
-+        }
-+    }
-+
-+    if (data == NULL) {
-+        if (inc) {
-+            err_clear_data(es, i);
-+        }
-+    } else {
-+        if (es->err_data[i] == NULL) {
-+            *data = "";
-+            if (flags != NULL)
-+                *flags = 0;
-+        } else {
-+            *data = es->err_data[i];
-+            if (flags != NULL)
-+                *flags = es->err_data_flags[i];
-+        }
-+    }
-+    return ret;
-+}
-+
-+void ERR_error_string_n(unsigned long e, char *buf, size_t len)
-+{
-+    char lsbuf[64], fsbuf[64], rsbuf[64];
-+    const char *ls, *fs, *rs;
-+    unsigned long l, f, r;
-+
-+    if (len == 0)
-+        return;
-+
-+    l = ERR_GET_LIB(e);
-+    f = ERR_GET_FUNC(e);
-+    r = ERR_GET_REASON(e);
-+
-+    ls = ERR_lib_error_string(e);
-+    fs = ERR_func_error_string(e);
-+    rs = ERR_reason_error_string(e);
-+
-+    if (ls == NULL)
-+        BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
-+    if (fs == NULL)
-+        BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
-+    if (rs == NULL)
-+        BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
-+
-+    BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls ? ls : lsbuf,
-+                 fs ? fs : fsbuf, rs ? rs : rsbuf);
-+    if (strlen(buf) == len - 1) {
-+        /*
-+         * output may be truncated; make sure we always have 5
-+         * colon-separated fields, i.e. 4 colons ...
-+         */
-+#define NUM_COLONS 4
-+        if (len > NUM_COLONS) { /* ... if possible */
-+            int i;
-+            char *s = buf;
-+
-+            for (i = 0; i < NUM_COLONS; i++) {
-+                char *colon = strchr(s, ':');
-+                if (colon == NULL || colon > &buf[len - 1] - NUM_COLONS + i) {
-+                    /*
-+                     * set colon no. i at last possible position (buf[len-1]
-+                     * is the terminating 0)
-+                     */
-+                    colon = &buf[len - 1] - NUM_COLONS + i;
-+                    *colon = ':';
-+                }
-+                s = colon + 1;
-+            }
-+        }
-+    }
-+}
-+
-+/*
-+ * ERR_error_string_n should be used instead for ret != NULL as
-+ * ERR_error_string cannot know how large the buffer is
-+ */
-+char *ERR_error_string(unsigned long e, char *ret)
-+{
-+    static char buf[256];
-+
-+    if (ret == NULL)
-+        ret = buf;
-+    ERR_error_string_n(e, ret, 256);
-+
-+    return ret;
-+}
-+
-+const char *ERR_lib_error_string(unsigned long e)
-+{
-+    ERR_STRING_DATA d, *p;
-+    unsigned long l;
-+
-+    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
-+        return NULL;
-+    }
-+
-+    l = ERR_GET_LIB(e);
-+    d.error = ERR_PACK(l, 0, 0);
-+    p = int_err_get_item(&d);
-+    return ((p == NULL) ? NULL : p->string);
-+}
-+
-+const char *ERR_func_error_string(unsigned long e)
-+{
-+    ERR_STRING_DATA d, *p;
-+    unsigned long l, f;
-+
-+    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
-+        return NULL;
-+    }
-+
-+    l = ERR_GET_LIB(e);
-+    f = ERR_GET_FUNC(e);
-+    d.error = ERR_PACK(l, f, 0);
-+    p = int_err_get_item(&d);
-+    return ((p == NULL) ? NULL : p->string);
-+}
-+
-+const char *ERR_reason_error_string(unsigned long e)
-+{
-+    ERR_STRING_DATA d, *p = NULL;
-+    unsigned long l, r;
-+
-+    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
-+        return NULL;
-+    }
-+
-+    l = ERR_GET_LIB(e);
-+    r = ERR_GET_REASON(e);
-+    d.error = ERR_PACK(l, 0, r);
-+    p = int_err_get_item(&d);
-+    if (!p) {
-+        d.error = ERR_PACK(0, 0, r);
-+        p = int_err_get_item(&d);
-+    }
-+    return ((p == NULL) ? NULL : p->string);
-+}
-+
-+void err_delete_thread_state(void)
-+{
-+    ERR_STATE *state = ERR_get_state();
-+    if (state == NULL)
-+        return;
-+
-+    CRYPTO_THREAD_set_local(&err_thread_local, NULL);
-+    ERR_STATE_free(state);
-+}
-+
-+#if OPENSSL_API_COMPAT < 0x10100000L
-+void ERR_remove_thread_state(void *dummy)
-+{
-+}
-+#endif
-+
-+#if OPENSSL_API_COMPAT < 0x10000000L
-+void ERR_remove_state(unsigned long pid)
-+{
-+}
-+#endif
-+
-+DEFINE_RUN_ONCE_STATIC(err_do_init)
-+{
-+    return CRYPTO_THREAD_init_local(&err_thread_local, NULL);
-+}
-+
-+ERR_STATE *ERR_get_state(void)
-+{
-+    ERR_STATE *state = NULL;
-+
-+    if (!RUN_ONCE(&err_init, err_do_init))
-+        return NULL;
-+
-+    state = CRYPTO_THREAD_get_local(&err_thread_local);
-+
-+    if (state == NULL) {
-+        state = OPENSSL_zalloc(sizeof(*state));
-+        if (state == NULL)
-+            return NULL;
-+
-+        if (!CRYPTO_THREAD_set_local(&err_thread_local, state)) {
-+            ERR_STATE_free(state);
-+            return NULL;
-+        }
-+
-+        /* Ignore failures from these */
-+        OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
-+        ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE);
-+    }
-+
-+    return state;
-+}
-+
-+int ERR_get_next_error_library(void)
-+{
-+    int ret;
-+
-+    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
-+        return 0;
-+    }
-+
-+    CRYPTO_THREAD_write_lock(err_string_lock);
-+    ret = int_err_library_number++;
-+    CRYPTO_THREAD_unlock(err_string_lock);
-+    return ret;
-+}
-+
-+void ERR_set_error_data(char *data, int flags)
-+{
-+    ERR_STATE *es;
-+    int i;
-+
-+    es = ERR_get_state();
-+
-+    i = es->top;
-+    if (i == 0)
-+        i = ERR_NUM_ERRORS - 1;
-+
-+    err_clear_data(es, i);
-+    es->err_data[i] = data;
-+    es->err_data_flags[i] = flags;
-+}
-+
-+void ERR_add_error_data(int num, ...)
-+{
-+    va_list args;
-+    va_start(args, num);
-+    ERR_add_error_vdata(num, args);
-+    va_end(args);
-+}
-+
-+void ERR_add_error_vdata(int num, va_list args)
-+{
-+    int i, n, s;
-+    char *str, *p, *a;
-+
-+    s = 80;
-+    str = OPENSSL_malloc(s + 1);
-+    if (str == NULL)
-+        return;
-+    str[0] = '\0';
-+
-+    n = 0;
-+    for (i = 0; i < num; i++) {
-+        a = va_arg(args, char *);
-+        /* ignore NULLs, thanks to Bob Beck  */
-+        if (a != NULL) {
-+            n += strlen(a);
-+            if (n > s) {
-+                s = n + 20;
-+                p = OPENSSL_realloc(str, s + 1);
-+                if (p == NULL) {
-+                    OPENSSL_free(str);
-+                    return;
-+                }
-+                str = p;
-+            }
-+            OPENSSL_strlcat(str, a, (size_t)s + 1);
-+        }
-+    }
-+    ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING);
-+}
-+
-+int ERR_set_mark(void)
-+{
-+    ERR_STATE *es;
-+
-+    es = ERR_get_state();
-+
-+    if (es->bottom == es->top)
-+        return 0;
-+    es->err_flags[es->top] |= ERR_FLAG_MARK;
-+    return 1;
-+}
-+
-+int ERR_pop_to_mark(void)
-+{
-+    ERR_STATE *es;
-+
-+    es = ERR_get_state();
-+
-+    while (es->bottom != es->top
-+           && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) {
-+        err_clear(es, es->top);
-+        es->top -= 1;
-+        if (es->top == -1)
-+            es->top = ERR_NUM_ERRORS - 1;
-+    }
-+
-+    if (es->bottom == es->top)
-+        return 0;
-+    es->err_flags[es->top] &= ~ERR_FLAG_MARK;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/err_all.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/err_all.c
-new file mode 100644
-index 0000000..3b1304f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/err_all.c
-@@ -0,0 +1,109 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/err_int.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/dso.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#ifdef OPENSSL_FIPS
-+# include 
-+#endif
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+int err_load_crypto_strings_int(void)
-+{
-+    if (
-+#ifdef OPENSSL_FIPS
-+        FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata) == 0 ||
-+#endif
-+#ifndef OPENSSL_NO_ERR
-+        ERR_load_ERR_strings() == 0 ||    /* include error strings for SYSerr */
-+        ERR_load_BN_strings() == 0 ||
-+# ifndef OPENSSL_NO_RSA
-+        ERR_load_RSA_strings() == 0 ||
-+# endif
-+# ifndef OPENSSL_NO_DH
-+        ERR_load_DH_strings() == 0 ||
-+# endif
-+        ERR_load_EVP_strings() == 0 ||
-+        ERR_load_BUF_strings() == 0 ||
-+        ERR_load_OBJ_strings() == 0 ||
-+        ERR_load_PEM_strings() == 0 ||
-+# ifndef OPENSSL_NO_DSA
-+        ERR_load_DSA_strings() == 0 ||
-+# endif
-+        ERR_load_X509_strings() == 0 ||
-+        ERR_load_ASN1_strings() == 0 ||
-+        ERR_load_CONF_strings() == 0 ||
-+        ERR_load_CRYPTO_strings() == 0 ||
-+# ifndef OPENSSL_NO_COMP
-+        ERR_load_COMP_strings() == 0 ||
-+# endif
-+# ifndef OPENSSL_NO_EC
-+        ERR_load_EC_strings() == 0 ||
-+# endif
-+        /* skip ERR_load_SSL_strings() because it is not in this library */
-+        ERR_load_BIO_strings() == 0 ||
-+        ERR_load_PKCS7_strings() == 0 ||
-+        ERR_load_X509V3_strings() == 0 ||
-+        ERR_load_PKCS12_strings() == 0 ||
-+        ERR_load_RAND_strings() == 0 ||
-+        ERR_load_DSO_strings() == 0 ||
-+# ifndef OPENSSL_NO_TS
-+        ERR_load_TS_strings() == 0 ||
-+# endif
-+# ifndef OPENSSL_NO_ENGINE
-+        ERR_load_ENGINE_strings() == 0 ||
-+# endif
-+# ifndef OPENSSL_NO_OCSP
-+        ERR_load_OCSP_strings() == 0 ||
-+# endif
-+#ifndef OPENSSL_NO_UI
-+        ERR_load_UI_strings() == 0 ||
-+#endif
-+# ifdef OPENSSL_FIPS
-+        ERR_load_FIPS_strings() == 0 ||
-+# endif
-+# ifndef OPENSSL_NO_CMS
-+        ERR_load_CMS_strings() == 0 ||
-+# endif
-+# ifndef OPENSSL_NO_CT
-+        ERR_load_CT_strings() == 0 ||
-+# endif
-+        ERR_load_ASYNC_strings() == 0 ||
-+#endif
-+        ERR_load_KDF_strings() == 0)
-+        return 0;
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/err_prn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/err_prn.c
-new file mode 100644
-index 0000000..c7dc1d1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/err_prn.c
-@@ -0,0 +1,66 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
-+                         void *u)
-+{
-+    unsigned long l;
-+    char buf[256];
-+    char buf2[4096];
-+    const char *file, *data;
-+    int line, flags;
-+    /*
-+     * We don't know what kind of thing CRYPTO_THREAD_ID is. Here is our best
-+     * attempt to convert it into something we can print.
-+     */
-+    union {
-+        CRYPTO_THREAD_ID tid;
-+        unsigned long ltid;
-+    } tid;
-+
-+    tid.ltid = 0;
-+    tid.tid = CRYPTO_THREAD_get_current_id();
-+
-+    while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
-+        ERR_error_string_n(l, buf, sizeof buf);
-+        BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", tid.ltid, buf,
-+                     file, line, (flags & ERR_TXT_STRING) ? data : "");
-+        if (cb(buf2, strlen(buf2), u) <= 0)
-+            break;              /* abort outputting the error report */
-+    }
-+}
-+
-+static int print_bio(const char *str, size_t len, void *bp)
-+{
-+    return BIO_write((BIO *)bp, str, len);
-+}
-+
-+void ERR_print_errors(BIO *bp)
-+{
-+    ERR_print_errors_cb(print_bio, bp);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+void ERR_print_errors_fp(FILE *fp)
-+{
-+    BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE);
-+    if (bio == NULL)
-+        return;
-+
-+    ERR_print_errors_cb(print_bio, bio);
-+    BIO_free(bio);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.ec b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.ec
-new file mode 100644
-index 0000000..f6f950e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/err/openssl.ec
-@@ -0,0 +1,100 @@
-+# crypto/err/openssl.ec
-+
-+# configuration file for util/mkerr.pl
-+
-+# files that may have to be rewritten by util/mkerr.pl
-+L ERR		NONE				NONE
-+L BN		include/openssl/bn.h		crypto/bn/bn_err.c
-+L RSA		include/openssl/rsa.h		crypto/rsa/rsa_err.c
-+L DH		include/openssl/dh.h		crypto/dh/dh_err.c
-+L EVP		include/openssl/evp.h		crypto/evp/evp_err.c
-+L BUF		include/openssl/buffer.h	crypto/buffer/buf_err.c
-+L OBJ		include/openssl/objects.h	crypto/objects/obj_err.c
-+L PEM		include/openssl/pem.h		crypto/pem/pem_err.c
-+L DSA		include/openssl/dsa.h		crypto/dsa/dsa_err.c
-+L X509		include/openssl/x509.h		crypto/x509/x509_err.c
-+L ASN1		include/openssl/asn1.h		crypto/asn1/asn1_err.c
-+L CONF		include/openssl/conf.h		crypto/conf/conf_err.c
-+L CRYPTO	include/openssl/crypto.h	crypto/cpt_err.c
-+L EC		include/openssl/ec.h		crypto/ec/ec_err.c
-+L SSL		include/openssl/ssl.h		ssl/ssl_err.c
-+L BIO		include/openssl/bio.h		crypto/bio/bio_err.c
-+L PKCS7		include/openssl/pkcs7.h		crypto/pkcs7/pkcs7err.c
-+L X509V3	include/openssl/x509v3.h	crypto/x509v3/v3err.c
-+L PKCS12	include/openssl/pkcs12.h	crypto/pkcs12/pk12err.c
-+L RAND		include/openssl/rand.h		crypto/rand/rand_err.c
-+L DSO		include/internal/dso.h		crypto/dso/dso_err.c
-+L ENGINE	include/openssl/engine.h	crypto/engine/eng_err.c
-+L OCSP		include/openssl/ocsp.h		crypto/ocsp/ocsp_err.c
-+L UI		include/openssl/ui.h		crypto/ui/ui_err.c
-+L COMP		include/openssl/comp.h		crypto/comp/comp_err.c
-+L TS		include/openssl/ts.h		crypto/ts/ts_err.c
-+#L HMAC		include/openssl/hmac.h		crypto/hmac/hmac_err.c
-+L CMS		include/openssl/cms.h		crypto/cms/cms_err.c
-+#L FIPS		include/openssl/fips.h		crypto/fips_err.h
-+L CT		include/openssl/ct.h		crypto/ct/ct_err.c
-+L ASYNC		include/openssl/async.h		crypto/async/async_err.c
-+L KDF		include/openssl/kdf.h		crypto/kdf/kdf_err.c
-+
-+# additional header files to be scanned for function names
-+L NONE		crypto/x509/x509_vfy.h		NONE
-+L NONE		crypto/ec/ec_lcl.h		NONE
-+L NONE		crypto/asn1/asn_lcl.h		NONE
-+L NONE		crypto/cms/cms_lcl.h		NONE
-+L NONE		crypto/ct/ct_locl.h		NONE
-+L NONE		fips/rand/fips_rand.h		NONE
-+L NONE		ssl/ssl_locl.h			NONE
-+
-+F RSAREF_F_RSA_BN2BIN
-+F RSAREF_F_RSA_PRIVATE_DECRYPT
-+F RSAREF_F_RSA_PRIVATE_ENCRYPT
-+F RSAREF_F_RSA_PUBLIC_DECRYPT
-+F RSAREF_F_RSA_PUBLIC_ENCRYPT
-+
-+R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE         1010
-+R SSL_R_SSLV3_ALERT_BAD_RECORD_MAC             1020
-+R SSL_R_TLSV1_ALERT_DECRYPTION_FAILED          1021
-+R SSL_R_TLSV1_ALERT_RECORD_OVERFLOW            1022
-+R SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE      1030
-+R SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE          1040
-+R SSL_R_SSLV3_ALERT_NO_CERTIFICATE             1041
-+R SSL_R_SSLV3_ALERT_BAD_CERTIFICATE            1042
-+R SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE    1043
-+R SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED        1044
-+R SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED        1045
-+R SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN        1046
-+R SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER          1047
-+R SSL_R_TLSV1_ALERT_UNKNOWN_CA                 1048
-+R SSL_R_TLSV1_ALERT_ACCESS_DENIED              1049
-+R SSL_R_TLSV1_ALERT_DECODE_ERROR               1050
-+R SSL_R_TLSV1_ALERT_DECRYPT_ERROR              1051
-+R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION         1060
-+R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION           1070
-+R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY      1071
-+R SSL_R_TLSV1_ALERT_INTERNAL_ERROR             1080
-+R SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK     1086
-+R SSL_R_TLSV1_ALERT_USER_CANCELLED             1090
-+R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION           1100
-+R SSL_R_TLSV1_UNSUPPORTED_EXTENSION            1110
-+R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE         1111
-+R SSL_R_TLSV1_UNRECOGNIZED_NAME                1112
-+R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE  1113
-+R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE       1114
-+R TLS1_AD_UNKNOWN_PSK_IDENTITY                 1115
-+R TLS1_AD_NO_APPLICATION_PROTOCOL              1120
-+
-+R RSAREF_R_CONTENT_ENCODING			0x0400
-+R RSAREF_R_DATA					0x0401
-+R RSAREF_R_DIGEST_ALGORITHM			0x0402
-+R RSAREF_R_ENCODING				0x0403
-+R RSAREF_R_KEY					0x0404
-+R RSAREF_R_KEY_ENCODING				0x0405
-+R RSAREF_R_LEN					0x0406
-+R RSAREF_R_MODULUS_LEN				0x0407
-+R RSAREF_R_NEED_RANDOM				0x0408
-+R RSAREF_R_PRIVATE_KEY				0x0409
-+R RSAREF_R_PUBLIC_KEY				0x040a
-+R RSAREF_R_SIGNATURE				0x040b
-+R RSAREF_R_SIGNATURE_ENCODING			0x040c
-+R RSAREF_R_ENCRYPTION_ALGORITHM			0x040d
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_b64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_b64.c
-new file mode 100644
-index 0000000..32a884a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_b64.c
-@@ -0,0 +1,542 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/bio.h"
-+
-+static int b64_write(BIO *h, const char *buf, int num);
-+static int b64_read(BIO *h, char *buf, int size);
-+static int b64_puts(BIO *h, const char *str);
-+/*
-+ * static int b64_gets(BIO *h, char *str, int size);
-+ */
-+static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int b64_new(BIO *h);
-+static int b64_free(BIO *data);
-+static long b64_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-+#define B64_BLOCK_SIZE  1024
-+#define B64_BLOCK_SIZE2 768
-+#define B64_NONE        0
-+#define B64_ENCODE      1
-+#define B64_DECODE      2
-+
-+typedef struct b64_struct {
-+    /*
-+     * BIO *bio; moved to the BIO structure
-+     */
-+    int buf_len;
-+    int buf_off;
-+    int tmp_len;                /* used to find the start when decoding */
-+    int tmp_nl;                 /* If true, scan until '\n' */
-+    int encode;
-+    int start;                  /* have we started decoding yet? */
-+    int cont;                   /* <= 0 when finished */
-+    EVP_ENCODE_CTX *base64;
-+    char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10];
-+    char tmp[B64_BLOCK_SIZE];
-+} BIO_B64_CTX;
-+
-+static const BIO_METHOD methods_b64 = {
-+    BIO_TYPE_BASE64, "base64 encoding",
-+    b64_write,
-+    b64_read,
-+    b64_puts,
-+    NULL,                       /* b64_gets, */
-+    b64_ctrl,
-+    b64_new,
-+    b64_free,
-+    b64_callback_ctrl,
-+};
-+
-+
-+const BIO_METHOD *BIO_f_base64(void)
-+{
-+    return &methods_b64;
-+}
-+
-+static int b64_new(BIO *bi)
-+{
-+    BIO_B64_CTX *ctx;
-+
-+    ctx = OPENSSL_zalloc(sizeof(*ctx));
-+    if (ctx == NULL)
-+        return 0;
-+
-+    ctx->cont = 1;
-+    ctx->start = 1;
-+    ctx->base64 = EVP_ENCODE_CTX_new();
-+    if (ctx->base64 == NULL) {
-+        OPENSSL_free(ctx);
-+        return 0;
-+    }
-+
-+    BIO_set_data(bi, ctx);
-+    BIO_set_init(bi, 1);
-+
-+    return 1;
-+}
-+
-+static int b64_free(BIO *a)
-+{
-+    BIO_B64_CTX *ctx;
-+    if (a == NULL)
-+        return 0;
-+
-+    ctx = BIO_get_data(a);
-+    if (ctx == NULL)
-+        return 0;
-+
-+    EVP_ENCODE_CTX_free(ctx->base64);
-+    OPENSSL_free(ctx);
-+    BIO_set_data(a, NULL);
-+    BIO_set_init(a, 0);
-+
-+    return 1;
-+}
-+
-+static int b64_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
-+    BIO_B64_CTX *ctx;
-+    unsigned char *p, *q;
-+    BIO *next;
-+
-+    if (out == NULL)
-+        return (0);
-+    ctx = (BIO_B64_CTX *)BIO_get_data(b);
-+
-+    next = BIO_next(b);
-+    if ((ctx == NULL) || (next == NULL))
-+        return 0;
-+
-+    BIO_clear_retry_flags(b);
-+
-+    if (ctx->encode != B64_DECODE) {
-+        ctx->encode = B64_DECODE;
-+        ctx->buf_len = 0;
-+        ctx->buf_off = 0;
-+        ctx->tmp_len = 0;
-+        EVP_DecodeInit(ctx->base64);
-+    }
-+
-+    /* First check if there are bytes decoded/encoded */
-+    if (ctx->buf_len > 0) {
-+        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
-+        i = ctx->buf_len - ctx->buf_off;
-+        if (i > outl)
-+            i = outl;
-+        OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
-+        memcpy(out, &(ctx->buf[ctx->buf_off]), i);
-+        ret = i;
-+        out += i;
-+        outl -= i;
-+        ctx->buf_off += i;
-+        if (ctx->buf_len == ctx->buf_off) {
-+            ctx->buf_len = 0;
-+            ctx->buf_off = 0;
-+        }
-+    }
-+
-+    /*
-+     * At this point, we have room of outl bytes and an empty buffer, so we
-+     * should read in some more.
-+     */
-+
-+    ret_code = 0;
-+    while (outl > 0) {
-+        if (ctx->cont <= 0)
-+            break;
-+
-+        i = BIO_read(next, &(ctx->tmp[ctx->tmp_len]),
-+                     B64_BLOCK_SIZE - ctx->tmp_len);
-+
-+        if (i <= 0) {
-+            ret_code = i;
-+
-+            /* Should we continue next time we are called? */
-+            if (!BIO_should_retry(next)) {
-+                ctx->cont = i;
-+                /* If buffer empty break */
-+                if (ctx->tmp_len == 0)
-+                    break;
-+                /* Fall through and process what we have */
-+                else
-+                    i = 0;
-+            }
-+            /* else we retry and add more data to buffer */
-+            else
-+                break;
-+        }
-+        i += ctx->tmp_len;
-+        ctx->tmp_len = i;
-+
-+        /*
-+         * We need to scan, a line at a time until we have a valid line if we
-+         * are starting.
-+         */
-+        if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) {
-+            /* ctx->start=1; */
-+            ctx->tmp_len = 0;
-+        } else if (ctx->start) {
-+            q = p = (unsigned char *)ctx->tmp;
-+            num = 0;
-+            for (j = 0; j < i; j++) {
-+                if (*(q++) != '\n')
-+                    continue;
-+
-+                /*
-+                 * due to a previous very long line, we need to keep on
-+                 * scanning for a '\n' before we even start looking for
-+                 * base64 encoded stuff.
-+                 */
-+                if (ctx->tmp_nl) {
-+                    p = q;
-+                    ctx->tmp_nl = 0;
-+                    continue;
-+                }
-+
-+                k = EVP_DecodeUpdate(ctx->base64,
-+                                     (unsigned char *)ctx->buf,
-+                                     &num, p, q - p);
-+                if ((k <= 0) && (num == 0) && (ctx->start))
-+                    EVP_DecodeInit(ctx->base64);
-+                else {
-+                    if (p != (unsigned char *)
-+                        &(ctx->tmp[0])) {
-+                        i -= (p - (unsigned char *)
-+                              &(ctx->tmp[0]));
-+                        for (x = 0; x < i; x++)
-+                            ctx->tmp[x] = p[x];
-+                    }
-+                    EVP_DecodeInit(ctx->base64);
-+                    ctx->start = 0;
-+                    break;
-+                }
-+                p = q;
-+            }
-+
-+            /* we fell off the end without starting */
-+            if ((j == i) && (num == 0)) {
-+                /*
-+                 * Is this is one long chunk?, if so, keep on reading until a
-+                 * new line.
-+                 */
-+                if (p == (unsigned char *)&(ctx->tmp[0])) {
-+                    /* Check buffer full */
-+                    if (i == B64_BLOCK_SIZE) {
-+                        ctx->tmp_nl = 1;
-+                        ctx->tmp_len = 0;
-+                    }
-+                } else if (p != q) { /* finished on a '\n' */
-+                    n = q - p;
-+                    for (ii = 0; ii < n; ii++)
-+                        ctx->tmp[ii] = p[ii];
-+                    ctx->tmp_len = n;
-+                }
-+                /* else finished on a '\n' */
-+                continue;
-+            } else {
-+                ctx->tmp_len = 0;
-+            }
-+        } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) {
-+            /*
-+             * If buffer isn't full and we can retry then restart to read in
-+             * more data.
-+             */
-+            continue;
-+        }
-+
-+        if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
-+            int z, jj;
-+
-+            jj = i & ~3;        /* process per 4 */
-+            z = EVP_DecodeBlock((unsigned char *)ctx->buf,
-+                                (unsigned char *)ctx->tmp, jj);
-+            if (jj > 2) {
-+                if (ctx->tmp[jj - 1] == '=') {
-+                    z--;
-+                    if (ctx->tmp[jj - 2] == '=')
-+                        z--;
-+                }
-+            }
-+            /*
-+             * z is now number of output bytes and jj is the number consumed
-+             */
-+            if (jj != i) {
-+                memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
-+                ctx->tmp_len = i - jj;
-+            }
-+            ctx->buf_len = 0;
-+            if (z > 0) {
-+                ctx->buf_len = z;
-+            }
-+            i = z;
-+        } else {
-+            i = EVP_DecodeUpdate(ctx->base64,
-+                                 (unsigned char *)ctx->buf, &ctx->buf_len,
-+                                 (unsigned char *)ctx->tmp, i);
-+            ctx->tmp_len = 0;
-+        }
-+        ctx->buf_off = 0;
-+        if (i < 0) {
-+            ret_code = 0;
-+            ctx->buf_len = 0;
-+            break;
-+        }
-+
-+        if (ctx->buf_len <= outl)
-+            i = ctx->buf_len;
-+        else
-+            i = outl;
-+
-+        memcpy(out, ctx->buf, i);
-+        ret += i;
-+        ctx->buf_off = i;
-+        if (ctx->buf_off == ctx->buf_len) {
-+            ctx->buf_len = 0;
-+            ctx->buf_off = 0;
-+        }
-+        outl -= i;
-+        out += i;
-+    }
-+    /* BIO_clear_retry_flags(b); */
-+    BIO_copy_next_retry(b);
-+    return ((ret == 0) ? ret_code : ret);
-+}
-+
-+static int b64_write(BIO *b, const char *in, int inl)
-+{
-+    int ret = 0;
-+    int n;
-+    int i;
-+    BIO_B64_CTX *ctx;
-+    BIO *next;
-+
-+    ctx = (BIO_B64_CTX *)BIO_get_data(b);
-+    next = BIO_next(b);
-+    if ((ctx == NULL) || (next == NULL))
-+        return 0;
-+
-+    BIO_clear_retry_flags(b);
-+
-+    if (ctx->encode != B64_ENCODE) {
-+        ctx->encode = B64_ENCODE;
-+        ctx->buf_len = 0;
-+        ctx->buf_off = 0;
-+        ctx->tmp_len = 0;
-+        EVP_EncodeInit(ctx->base64);
-+    }
-+
-+    OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
-+    OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
-+    OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
-+    n = ctx->buf_len - ctx->buf_off;
-+    while (n > 0) {
-+        i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
-+        if (i <= 0) {
-+            BIO_copy_next_retry(b);
-+            return (i);
-+        }
-+        OPENSSL_assert(i <= n);
-+        ctx->buf_off += i;
-+        OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
-+        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
-+        n -= i;
-+    }
-+    /* at this point all pending data has been written */
-+    ctx->buf_off = 0;
-+    ctx->buf_len = 0;
-+
-+    if ((in == NULL) || (inl <= 0))
-+        return (0);
-+
-+    while (inl > 0) {
-+        n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;
-+
-+        if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
-+            if (ctx->tmp_len > 0) {
-+                OPENSSL_assert(ctx->tmp_len <= 3);
-+                n = 3 - ctx->tmp_len;
-+                /*
-+                 * There's a theoretical possibility for this
-+                 */
-+                if (n > inl)
-+                    n = inl;
-+                memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
-+                ctx->tmp_len += n;
-+                ret += n;
-+                if (ctx->tmp_len < 3)
-+                    break;
-+                ctx->buf_len =
-+                    EVP_EncodeBlock((unsigned char *)ctx->buf,
-+                                    (unsigned char *)ctx->tmp, ctx->tmp_len);
-+                OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
-+                OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
-+                /*
-+                 * Since we're now done using the temporary buffer, the
-+                 * length should be 0'd
-+                 */
-+                ctx->tmp_len = 0;
-+            } else {
-+                if (n < 3) {
-+                    memcpy(ctx->tmp, in, n);
-+                    ctx->tmp_len = n;
-+                    ret += n;
-+                    break;
-+                }
-+                n -= n % 3;
-+                ctx->buf_len =
-+                    EVP_EncodeBlock((unsigned char *)ctx->buf,
-+                                    (const unsigned char *)in, n);
-+                OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
-+                OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
-+                ret += n;
-+            }
-+        } else {
-+            if (!EVP_EncodeUpdate(ctx->base64,
-+                                 (unsigned char *)ctx->buf, &ctx->buf_len,
-+                                 (unsigned char *)in, n))
-+                return ((ret == 0) ? -1 : ret);
-+            OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
-+            OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
-+            ret += n;
-+        }
-+        inl -= n;
-+        in += n;
-+
-+        ctx->buf_off = 0;
-+        n = ctx->buf_len;
-+        while (n > 0) {
-+            i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
-+            if (i <= 0) {
-+                BIO_copy_next_retry(b);
-+                return ((ret == 0) ? i : ret);
-+            }
-+            OPENSSL_assert(i <= n);
-+            n -= i;
-+            ctx->buf_off += i;
-+            OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
-+            OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
-+        }
-+        ctx->buf_len = 0;
-+        ctx->buf_off = 0;
-+    }
-+    return (ret);
-+}
-+
-+static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    BIO_B64_CTX *ctx;
-+    long ret = 1;
-+    int i;
-+    BIO *next;
-+
-+    ctx = (BIO_B64_CTX *)BIO_get_data(b);
-+    next = BIO_next(b);
-+    if ((ctx == NULL) || (next == NULL))
-+        return 0;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        ctx->cont = 1;
-+        ctx->start = 1;
-+        ctx->encode = B64_NONE;
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_EOF:         /* More to read */
-+        if (ctx->cont <= 0)
-+            ret = 1;
-+        else
-+            ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_WPENDING:    /* More to write in buffer */
-+        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
-+        ret = ctx->buf_len - ctx->buf_off;
-+        if ((ret == 0) && (ctx->encode != B64_NONE)
-+            && (EVP_ENCODE_CTX_num(ctx->base64) != 0))
-+            ret = 1;
-+        else if (ret <= 0)
-+            ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_PENDING:     /* More to read in buffer */
-+        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
-+        ret = ctx->buf_len - ctx->buf_off;
-+        if (ret <= 0)
-+            ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_FLUSH:
-+        /* do a final write */
-+ again:
-+        while (ctx->buf_len != ctx->buf_off) {
-+            i = b64_write(b, NULL, 0);
-+            if (i < 0)
-+                return i;
-+        }
-+        if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
-+            if (ctx->tmp_len != 0) {
-+                ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf,
-+                                               (unsigned char *)ctx->tmp,
-+                                               ctx->tmp_len);
-+                ctx->buf_off = 0;
-+                ctx->tmp_len = 0;
-+                goto again;
-+            }
-+        } else if (ctx->encode != B64_NONE
-+                   && EVP_ENCODE_CTX_num(ctx->base64) != 0) {
-+            ctx->buf_off = 0;
-+            EVP_EncodeFinal(ctx->base64,
-+                            (unsigned char *)ctx->buf, &(ctx->buf_len));
-+            /* push out the bytes */
-+            goto again;
-+        }
-+        /* Finally flush the underlying BIO */
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+
-+    case BIO_C_DO_STATE_MACHINE:
-+        BIO_clear_retry_flags(b);
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        BIO_copy_next_retry(b);
-+        break;
-+
-+    case BIO_CTRL_DUP:
-+        break;
-+    case BIO_CTRL_INFO:
-+    case BIO_CTRL_GET:
-+    case BIO_CTRL_SET:
-+    default:
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    }
-+    return ret;
-+}
-+
-+static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    long ret = 1;
-+    BIO *next = BIO_next(b);
-+
-+    if (next == NULL)
-+        return 0;
-+    switch (cmd) {
-+    default:
-+        ret = BIO_callback_ctrl(next, cmd, fp);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int b64_puts(BIO *b, const char *str)
-+{
-+    return b64_write(b, str, strlen(str));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_enc.c
-new file mode 100644
-index 0000000..5a3beef
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_enc.c
-@@ -0,0 +1,449 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/bio.h"
-+
-+static int enc_write(BIO *h, const char *buf, int num);
-+static int enc_read(BIO *h, char *buf, int size);
-+/*
-+ * static int enc_puts(BIO *h, const char *str);
-+ */
-+/*
-+ * static int enc_gets(BIO *h, char *str, int size);
-+ */
-+static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int enc_new(BIO *h);
-+static int enc_free(BIO *data);
-+static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
-+#define ENC_BLOCK_SIZE  (1024*4)
-+#define ENC_MIN_CHUNK   (256)
-+#define BUF_OFFSET      (ENC_MIN_CHUNK + EVP_MAX_BLOCK_LENGTH)
-+
-+typedef struct enc_struct {
-+    int buf_len;
-+    int buf_off;
-+    int cont;                   /* <= 0 when finished */
-+    int finished;
-+    int ok;                     /* bad decrypt */
-+    EVP_CIPHER_CTX *cipher;
-+    unsigned char *read_start, *read_end;
-+    /*
-+     * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return
-+     * up to a block more data than is presented to it
-+     */
-+    unsigned char buf[BUF_OFFSET + ENC_BLOCK_SIZE];
-+} BIO_ENC_CTX;
-+
-+static const BIO_METHOD methods_enc = {
-+    BIO_TYPE_CIPHER, "cipher",
-+    enc_write,
-+    enc_read,
-+    NULL,                       /* enc_puts, */
-+    NULL,                       /* enc_gets, */
-+    enc_ctrl,
-+    enc_new,
-+    enc_free,
-+    enc_callback_ctrl,
-+};
-+
-+const BIO_METHOD *BIO_f_cipher(void)
-+{
-+    return (&methods_enc);
-+}
-+
-+static int enc_new(BIO *bi)
-+{
-+    BIO_ENC_CTX *ctx;
-+
-+    ctx = OPENSSL_zalloc(sizeof(*ctx));
-+    if (ctx == NULL)
-+        return 0;
-+
-+    ctx->cipher = EVP_CIPHER_CTX_new();
-+    if (ctx->cipher == NULL) {
-+        OPENSSL_free(ctx);
-+        return 0;
-+    }
-+    ctx->cont = 1;
-+    ctx->ok = 1;
-+    ctx->read_end = ctx->read_start = &(ctx->buf[BUF_OFFSET]);
-+    BIO_set_data(bi, ctx);
-+    BIO_set_init(bi, 1);
-+
-+    return 1;
-+}
-+
-+static int enc_free(BIO *a)
-+{
-+    BIO_ENC_CTX *b;
-+
-+    if (a == NULL)
-+        return 0;
-+
-+    b = BIO_get_data(a);
-+    if (b == NULL)
-+        return 0;
-+
-+    EVP_CIPHER_CTX_free(b->cipher);
-+    OPENSSL_clear_free(b, sizeof(BIO_ENC_CTX));
-+    BIO_set_data(a, NULL);
-+    BIO_set_init(a, 0);
-+
-+    return 1;
-+}
-+
-+static int enc_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0, i, blocksize;
-+    BIO_ENC_CTX *ctx;
-+    BIO *next;
-+
-+    if (out == NULL)
-+        return (0);
-+    ctx = BIO_get_data(b);
-+
-+    next = BIO_next(b);
-+    if ((ctx == NULL) || (next == NULL))
-+        return 0;
-+
-+    /* First check if there are bytes decoded/encoded */
-+    if (ctx->buf_len > 0) {
-+        i = ctx->buf_len - ctx->buf_off;
-+        if (i > outl)
-+            i = outl;
-+        memcpy(out, &(ctx->buf[ctx->buf_off]), i);
-+        ret = i;
-+        out += i;
-+        outl -= i;
-+        ctx->buf_off += i;
-+        if (ctx->buf_len == ctx->buf_off) {
-+            ctx->buf_len = 0;
-+            ctx->buf_off = 0;
-+        }
-+    }
-+
-+    blocksize = EVP_CIPHER_CTX_block_size(ctx->cipher);
-+    if (blocksize == 1)
-+        blocksize = 0;
-+
-+    /*
-+     * At this point, we have room of outl bytes and an empty buffer, so we
-+     * should read in some more.
-+     */
-+
-+    while (outl > 0) {
-+        if (ctx->cont <= 0)
-+            break;
-+
-+        if (ctx->read_start == ctx->read_end) { /* time to read more data */
-+            ctx->read_end = ctx->read_start = &(ctx->buf[BUF_OFFSET]);
-+            i = BIO_read(next, ctx->read_start, ENC_BLOCK_SIZE);
-+            if (i > 0)
-+                ctx->read_end += i;
-+        } else {
-+            i = ctx->read_end - ctx->read_start;
-+        }
-+
-+        if (i <= 0) {
-+            /* Should be continue next time we are called? */
-+            if (!BIO_should_retry(next)) {
-+                ctx->cont = i;
-+                i = EVP_CipherFinal_ex(ctx->cipher,
-+                                       ctx->buf, &(ctx->buf_len));
-+                ctx->ok = i;
-+                ctx->buf_off = 0;
-+            } else {
-+                ret = (ret == 0) ? i : ret;
-+                break;
-+            }
-+        } else {
-+            if (outl > ENC_MIN_CHUNK) {
-+                /*
-+                 * Depending on flags block cipher decrypt can write
-+                 * one extra block and then back off, i.e. output buffer
-+                 * has to accommodate extra block...
-+                 */
-+                int j = outl - blocksize, buf_len;
-+
-+                if (!EVP_CipherUpdate(ctx->cipher,
-+                                      (unsigned char *)out, &buf_len,
-+                                      ctx->read_start, i > j ? j : i)) {
-+                    BIO_clear_retry_flags(b);
-+                    return 0;
-+                }
-+                ret += buf_len;
-+                out += buf_len;
-+                outl -= buf_len;
-+
-+                if ((i -= j) <= 0) {
-+                    ctx->read_start = ctx->read_end;
-+                    continue;
-+                }
-+                ctx->read_start += j;
-+            }
-+            if (i > ENC_MIN_CHUNK)
-+                i = ENC_MIN_CHUNK;
-+            if (!EVP_CipherUpdate(ctx->cipher,
-+                                  ctx->buf, &ctx->buf_len,
-+                                  ctx->read_start, i)) {
-+                BIO_clear_retry_flags(b);
-+                ctx->ok = 0;
-+                return 0;
-+            }
-+            ctx->read_start += i;
-+            ctx->cont = 1;
-+            /*
-+             * Note: it is possible for EVP_CipherUpdate to decrypt zero
-+             * bytes because this is or looks like the final block: if this
-+             * happens we should retry and either read more data or decrypt
-+             * the final block
-+             */
-+            if (ctx->buf_len == 0)
-+                continue;
-+        }
-+
-+        if (ctx->buf_len <= outl)
-+            i = ctx->buf_len;
-+        else
-+            i = outl;
-+        if (i <= 0)
-+            break;
-+        memcpy(out, ctx->buf, i);
-+        ret += i;
-+        ctx->buf_off = i;
-+        outl -= i;
-+        out += i;
-+    }
-+
-+    BIO_clear_retry_flags(b);
-+    BIO_copy_next_retry(b);
-+    return ((ret == 0) ? ctx->cont : ret);
-+}
-+
-+static int enc_write(BIO *b, const char *in, int inl)
-+{
-+    int ret = 0, n, i;
-+    BIO_ENC_CTX *ctx;
-+    BIO *next;
-+
-+    ctx = BIO_get_data(b);
-+    next = BIO_next(b);
-+    if ((ctx == NULL) || (next == NULL))
-+        return 0;
-+
-+    ret = inl;
-+
-+    BIO_clear_retry_flags(b);
-+    n = ctx->buf_len - ctx->buf_off;
-+    while (n > 0) {
-+        i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
-+        if (i <= 0) {
-+            BIO_copy_next_retry(b);
-+            return (i);
-+        }
-+        ctx->buf_off += i;
-+        n -= i;
-+    }
-+    /* at this point all pending data has been written */
-+
-+    if ((in == NULL) || (inl <= 0))
-+        return (0);
-+
-+    ctx->buf_off = 0;
-+    while (inl > 0) {
-+        n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
-+        if (!EVP_CipherUpdate(ctx->cipher,
-+                              ctx->buf, &ctx->buf_len,
-+                              (const unsigned char *)in, n)) {
-+            BIO_clear_retry_flags(b);
-+            ctx->ok = 0;
-+            return 0;
-+        }
-+        inl -= n;
-+        in += n;
-+
-+        ctx->buf_off = 0;
-+        n = ctx->buf_len;
-+        while (n > 0) {
-+            i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
-+            if (i <= 0) {
-+                BIO_copy_next_retry(b);
-+                return (ret == inl) ? i : ret - inl;
-+            }
-+            n -= i;
-+            ctx->buf_off += i;
-+        }
-+        ctx->buf_len = 0;
-+        ctx->buf_off = 0;
-+    }
-+    BIO_copy_next_retry(b);
-+    return (ret);
-+}
-+
-+static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    BIO *dbio;
-+    BIO_ENC_CTX *ctx, *dctx;
-+    long ret = 1;
-+    int i;
-+    EVP_CIPHER_CTX **c_ctx;
-+    BIO *next;
-+
-+    ctx = BIO_get_data(b);
-+    next = BIO_next(b);
-+    if (ctx == NULL)
-+        return 0;
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        ctx->ok = 1;
-+        ctx->finished = 0;
-+        if (!EVP_CipherInit_ex(ctx->cipher, NULL, NULL, NULL, NULL,
-+                               EVP_CIPHER_CTX_encrypting(ctx->cipher)))
-+            return 0;
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_EOF:         /* More to read */
-+        if (ctx->cont <= 0)
-+            ret = 1;
-+        else
-+            ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_WPENDING:
-+        ret = ctx->buf_len - ctx->buf_off;
-+        if (ret <= 0)
-+            ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_PENDING:     /* More to read in buffer */
-+        ret = ctx->buf_len - ctx->buf_off;
-+        if (ret <= 0)
-+            ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_FLUSH:
-+        /* do a final write */
-+ again:
-+        while (ctx->buf_len != ctx->buf_off) {
-+            i = enc_write(b, NULL, 0);
-+            if (i < 0)
-+                return i;
-+        }
-+
-+        if (!ctx->finished) {
-+            ctx->finished = 1;
-+            ctx->buf_off = 0;
-+            ret = EVP_CipherFinal_ex(ctx->cipher,
-+                                     (unsigned char *)ctx->buf,
-+                                     &(ctx->buf_len));
-+            ctx->ok = (int)ret;
-+            if (ret <= 0)
-+                break;
-+
-+            /* push out the bytes */
-+            goto again;
-+        }
-+
-+        /* Finally flush the underlying BIO */
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_C_GET_CIPHER_STATUS:
-+        ret = (long)ctx->ok;
-+        break;
-+    case BIO_C_DO_STATE_MACHINE:
-+        BIO_clear_retry_flags(b);
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        BIO_copy_next_retry(b);
-+        break;
-+    case BIO_C_GET_CIPHER_CTX:
-+        c_ctx = (EVP_CIPHER_CTX **)ptr;
-+        *c_ctx = ctx->cipher;
-+        BIO_set_init(b, 1);
-+        break;
-+    case BIO_CTRL_DUP:
-+        dbio = (BIO *)ptr;
-+        dctx = BIO_get_data(dbio);
-+        dctx->cipher = EVP_CIPHER_CTX_new();
-+        if (dctx->cipher == NULL)
-+            return 0;
-+        ret = EVP_CIPHER_CTX_copy(dctx->cipher, ctx->cipher);
-+        if (ret)
-+            BIO_set_init(dbio, 1);
-+        break;
-+    default:
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    long ret = 1;
-+    BIO *next = BIO_next(b);
-+
-+    if (next == NULL)
-+        return (0);
-+    switch (cmd) {
-+    default:
-+        ret = BIO_callback_ctrl(next, cmd, fp);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+/*-
-+void BIO_set_cipher_ctx(b,c)
-+BIO *b;
-+EVP_CIPHER_ctx *c;
-+        {
-+        if (b == NULL) return;
-+
-+        if ((b->callback != NULL) &&
-+                (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
-+                return;
-+
-+        b->init=1;
-+        ctx=(BIO_ENC_CTX *)b->ptr;
-+        memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
-+
-+        if (b->callback != NULL)
-+                b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
-+        }
-+*/
-+
-+int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
-+                   const unsigned char *i, int e)
-+{
-+    BIO_ENC_CTX *ctx;
-+    long (*callback) (struct bio_st *, int, const char *, int, long, long);
-+
-+    ctx = BIO_get_data(b);
-+    if (ctx == NULL)
-+        return 0;
-+
-+    callback = BIO_get_callback(b);
-+
-+    if ((callback != NULL) &&
-+            (callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e,
-+                      0L) <= 0))
-+        return 0;
-+
-+    BIO_set_init(b, 1);
-+
-+    if (!EVP_CipherInit_ex(ctx->cipher, c, NULL, k, i, e))
-+        return 0;
-+
-+    if (callback != NULL)
-+        return callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_md.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_md.c
-new file mode 100644
-index 0000000..cd968ec
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_md.c
-@@ -0,0 +1,231 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+#include "evp_locl.h"
-+#include "internal/bio.h"
-+
-+/*
-+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
-+ */
-+
-+static int md_write(BIO *h, char const *buf, int num);
-+static int md_read(BIO *h, char *buf, int size);
-+/*
-+ * static int md_puts(BIO *h, const char *str);
-+ */
-+static int md_gets(BIO *h, char *str, int size);
-+static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int md_new(BIO *h);
-+static int md_free(BIO *data);
-+static long md_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-+
-+static const BIO_METHOD methods_md = {
-+    BIO_TYPE_MD, "message digest",
-+    md_write,
-+    md_read,
-+    NULL,                       /* md_puts, */
-+    md_gets,
-+    md_ctrl,
-+    md_new,
-+    md_free,
-+    md_callback_ctrl,
-+};
-+
-+const BIO_METHOD *BIO_f_md(void)
-+{
-+    return (&methods_md);
-+}
-+
-+static int md_new(BIO *bi)
-+{
-+    EVP_MD_CTX *ctx;
-+
-+    ctx = EVP_MD_CTX_new();
-+    if (ctx == NULL)
-+        return (0);
-+
-+    BIO_set_init(bi, 1);
-+    BIO_set_data(bi, ctx);
-+
-+    return 1;
-+}
-+
-+static int md_free(BIO *a)
-+{
-+    if (a == NULL)
-+        return (0);
-+    EVP_MD_CTX_free(BIO_get_data(a));
-+    BIO_set_data(a, NULL);
-+    BIO_set_init(a, 0);
-+
-+    return 1;
-+}
-+
-+static int md_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0;
-+    EVP_MD_CTX *ctx;
-+    BIO *next;
-+
-+    if (out == NULL)
-+        return (0);
-+
-+    ctx = BIO_get_data(b);
-+    next = BIO_next(b);
-+
-+    if ((ctx == NULL) || (next == NULL))
-+        return (0);
-+
-+    ret = BIO_read(next, out, outl);
-+    if (BIO_get_init(b)) {
-+        if (ret > 0) {
-+            if (EVP_DigestUpdate(ctx, (unsigned char *)out,
-+                                 (unsigned int)ret) <= 0)
-+                return (-1);
-+        }
-+    }
-+    BIO_clear_retry_flags(b);
-+    BIO_copy_next_retry(b);
-+    return (ret);
-+}
-+
-+static int md_write(BIO *b, const char *in, int inl)
-+{
-+    int ret = 0;
-+    EVP_MD_CTX *ctx;
-+    BIO *next;
-+
-+    if ((in == NULL) || (inl <= 0))
-+        return 0;
-+
-+    ctx = BIO_get_data(b);
-+    next = BIO_next(b);
-+    if ((ctx != NULL) && (next != NULL))
-+        ret = BIO_write(next, in, inl);
-+
-+    if (BIO_get_init(b)) {
-+        if (ret > 0) {
-+            if (!EVP_DigestUpdate(ctx, (const unsigned char *)in,
-+                                  (unsigned int)ret)) {
-+                BIO_clear_retry_flags(b);
-+                return 0;
-+            }
-+        }
-+    }
-+    if (next != NULL) {
-+        BIO_clear_retry_flags(b);
-+        BIO_copy_next_retry(b);
-+    }
-+    return ret;
-+}
-+
-+static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    EVP_MD_CTX *ctx, *dctx, **pctx;
-+    const EVP_MD **ppmd;
-+    EVP_MD *md;
-+    long ret = 1;
-+    BIO *dbio, *next;
-+
-+
-+    ctx = BIO_get_data(b);
-+    next = BIO_next(b);
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        if (BIO_get_init(b))
-+            ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL);
-+        else
-+            ret = 0;
-+        if (ret > 0)
-+            ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_C_GET_MD:
-+        if (BIO_get_init(b)) {
-+            ppmd = ptr;
-+            *ppmd = ctx->digest;
-+        } else
-+            ret = 0;
-+        break;
-+    case BIO_C_GET_MD_CTX:
-+        pctx = ptr;
-+        *pctx = ctx;
-+        BIO_set_init(b, 1);
-+        break;
-+    case BIO_C_SET_MD_CTX:
-+        if (BIO_get_init(b))
-+            BIO_set_data(b, ptr);
-+        else
-+            ret = 0;
-+        break;
-+    case BIO_C_DO_STATE_MACHINE:
-+        BIO_clear_retry_flags(b);
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        BIO_copy_next_retry(b);
-+        break;
-+
-+    case BIO_C_SET_MD:
-+        md = ptr;
-+        ret = EVP_DigestInit_ex(ctx, md, NULL);
-+        if (ret > 0)
-+            BIO_set_init(b, 1);
-+        break;
-+    case BIO_CTRL_DUP:
-+        dbio = ptr;
-+        dctx = BIO_get_data(dbio);
-+        if (!EVP_MD_CTX_copy_ex(dctx, ctx))
-+            return 0;
-+        BIO_set_init(b, 1);
-+        break;
-+    default:
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static long md_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    long ret = 1;
-+    BIO *next;
-+
-+    next = BIO_next(b);
-+
-+    if (next == NULL)
-+        return 0;
-+
-+    switch (cmd) {
-+    default:
-+        ret = BIO_callback_ctrl(next, cmd, fp);
-+        break;
-+    }
-+    return (ret);
-+}
-+
-+static int md_gets(BIO *bp, char *buf, int size)
-+{
-+    EVP_MD_CTX *ctx;
-+    unsigned int ret;
-+
-+    ctx = BIO_get_data(bp);
-+
-+    if (size < ctx->digest->md_size)
-+        return 0;
-+
-+    if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0)
-+        return -1;
-+
-+    return ((int)ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_ok.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_ok.c
-new file mode 100644
-index 0000000..7974b96
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/bio_ok.c
-@@ -0,0 +1,604 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*-
-+        From: Arne Ansper 
-+
-+        Why BIO_f_reliable?
-+
-+        I wrote function which took BIO* as argument, read data from it
-+        and processed it. Then I wanted to store the input file in
-+        encrypted form. OK I pushed BIO_f_cipher to the BIO stack
-+        and everything was OK. BUT if user types wrong password
-+        BIO_f_cipher outputs only garbage and my function crashes. Yes
-+        I can and I should fix my function, but BIO_f_cipher is
-+        easy way to add encryption support to many existing applications
-+        and it's hard to debug and fix them all.
-+
-+        So I wanted another BIO which would catch the incorrect passwords and
-+        file damages which cause garbage on BIO_f_cipher's output.
-+
-+        The easy way is to push the BIO_f_md and save the checksum at
-+        the end of the file. However there are several problems with this
-+        approach:
-+
-+        1) you must somehow separate checksum from actual data.
-+        2) you need lot's of memory when reading the file, because you
-+        must read to the end of the file and verify the checksum before
-+        letting the application to read the data.
-+
-+        BIO_f_reliable tries to solve both problems, so that you can
-+        read and write arbitrary long streams using only fixed amount
-+        of memory.
-+
-+        BIO_f_reliable splits data stream into blocks. Each block is prefixed
-+        with it's length and suffixed with it's digest. So you need only
-+        several Kbytes of memory to buffer single block before verifying
-+        it's digest.
-+
-+        BIO_f_reliable goes further and adds several important capabilities:
-+
-+        1) the digest of the block is computed over the whole stream
-+        -- so nobody can rearrange the blocks or remove or replace them.
-+
-+        2) to detect invalid passwords right at the start BIO_f_reliable
-+        adds special prefix to the stream. In order to avoid known plain-text
-+        attacks this prefix is generated as follows:
-+
-+                *) digest is initialized with random seed instead of
-+                standardized one.
-+                *) same seed is written to output
-+                *) well-known text is then hashed and the output
-+                of the digest is also written to output.
-+
-+        reader can now read the seed from stream, hash the same string
-+        and then compare the digest output.
-+
-+        Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I
-+        initially wrote and tested this code on x86 machine and wrote the
-+        digests out in machine-dependent order :( There are people using
-+        this code and I cannot change this easily without making existing
-+        data files unreadable.
-+
-+*/
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "internal/bio.h"
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+static int ok_write(BIO *h, const char *buf, int num);
-+static int ok_read(BIO *h, char *buf, int size);
-+static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
-+static int ok_new(BIO *h);
-+static int ok_free(BIO *data);
-+static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
-+
-+static __owur int sig_out(BIO *b);
-+static __owur int sig_in(BIO *b);
-+static __owur int block_out(BIO *b);
-+static __owur int block_in(BIO *b);
-+#define OK_BLOCK_SIZE   (1024*4)
-+#define OK_BLOCK_BLOCK  4
-+#define IOBS            (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
-+#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."
-+
-+typedef struct ok_struct {
-+    size_t buf_len;
-+    size_t buf_off;
-+    size_t buf_len_save;
-+    size_t buf_off_save;
-+    int cont;                   /* <= 0 when finished */
-+    int finished;
-+    EVP_MD_CTX *md;
-+    int blockout;               /* output block is ready */
-+    int sigio;                  /* must process signature */
-+    unsigned char buf[IOBS];
-+} BIO_OK_CTX;
-+
-+static const BIO_METHOD methods_ok = {
-+    BIO_TYPE_CIPHER, "reliable",
-+    ok_write,
-+    ok_read,
-+    NULL,                       /* ok_puts, */
-+    NULL,                       /* ok_gets, */
-+    ok_ctrl,
-+    ok_new,
-+    ok_free,
-+    ok_callback_ctrl,
-+};
-+
-+const BIO_METHOD *BIO_f_reliable(void)
-+{
-+    return (&methods_ok);
-+}
-+
-+static int ok_new(BIO *bi)
-+{
-+    BIO_OK_CTX *ctx;
-+
-+    ctx = OPENSSL_zalloc(sizeof(*ctx));
-+    if (ctx == NULL)
-+        return 0;
-+
-+    ctx->cont = 1;
-+    ctx->sigio = 1;
-+    ctx->md = EVP_MD_CTX_new();
-+    if (ctx->md == NULL) {
-+        OPENSSL_free(ctx);
-+        return 0;
-+    }
-+    BIO_set_init(bi, 0);
-+    BIO_set_data(bi, ctx);
-+
-+    return 1;
-+}
-+
-+static int ok_free(BIO *a)
-+{
-+    BIO_OK_CTX *ctx;
-+
-+    if (a == NULL)
-+        return 0;
-+
-+    ctx = BIO_get_data(a);
-+
-+    EVP_MD_CTX_free(ctx->md);
-+    OPENSSL_clear_free(ctx, sizeof(BIO_OK_CTX));
-+    BIO_set_data(a, NULL);
-+    BIO_set_init(a, 0);
-+
-+    return 1;
-+}
-+
-+static int ok_read(BIO *b, char *out, int outl)
-+{
-+    int ret = 0, i, n;
-+    BIO_OK_CTX *ctx;
-+    BIO *next;
-+
-+    if (out == NULL)
-+        return 0;
-+
-+    ctx = BIO_get_data(b);
-+    next = BIO_next(b);
-+
-+    if ((ctx == NULL) || (next == NULL) || (BIO_get_init(b) == 0))
-+        return 0;
-+
-+    while (outl > 0) {
-+
-+        /* copy clean bytes to output buffer */
-+        if (ctx->blockout) {
-+            i = ctx->buf_len - ctx->buf_off;
-+            if (i > outl)
-+                i = outl;
-+            memcpy(out, &(ctx->buf[ctx->buf_off]), i);
-+            ret += i;
-+            out += i;
-+            outl -= i;
-+            ctx->buf_off += i;
-+
-+            /* all clean bytes are out */
-+            if (ctx->buf_len == ctx->buf_off) {
-+                ctx->buf_off = 0;
-+
-+                /*
-+                 * copy start of the next block into proper place
-+                 */
-+                if (ctx->buf_len_save - ctx->buf_off_save > 0) {
-+                    ctx->buf_len = ctx->buf_len_save - ctx->buf_off_save;
-+                    memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
-+                            ctx->buf_len);
-+                } else {
-+                    ctx->buf_len = 0;
-+                }
-+                ctx->blockout = 0;
-+            }
-+        }
-+
-+        /* output buffer full -- cancel */
-+        if (outl == 0)
-+            break;
-+
-+        /* no clean bytes in buffer -- fill it */
-+        n = IOBS - ctx->buf_len;
-+        i = BIO_read(next, &(ctx->buf[ctx->buf_len]), n);
-+
-+        if (i <= 0)
-+            break;              /* nothing new */
-+
-+        ctx->buf_len += i;
-+
-+        /* no signature yet -- check if we got one */
-+        if (ctx->sigio == 1) {
-+            if (!sig_in(b)) {
-+                BIO_clear_retry_flags(b);
-+                return 0;
-+            }
-+        }
-+
-+        /* signature ok -- check if we got block */
-+        if (ctx->sigio == 0) {
-+            if (!block_in(b)) {
-+                BIO_clear_retry_flags(b);
-+                return 0;
-+            }
-+        }
-+
-+        /* invalid block -- cancel */
-+        if (ctx->cont <= 0)
-+            break;
-+
-+    }
-+
-+    BIO_clear_retry_flags(b);
-+    BIO_copy_next_retry(b);
-+    return ret;
-+}
-+
-+static int ok_write(BIO *b, const char *in, int inl)
-+{
-+    int ret = 0, n, i;
-+    BIO_OK_CTX *ctx;
-+    BIO *next;
-+
-+    if (inl <= 0)
-+        return inl;
-+
-+    ctx = BIO_get_data(b);
-+    next = BIO_next(b);
-+    ret = inl;
-+
-+    if ((ctx == NULL) || (next == NULL) || (BIO_get_init(b) == 0))
-+        return (0);
-+
-+    if (ctx->sigio && !sig_out(b))
-+        return 0;
-+
-+    do {
-+        BIO_clear_retry_flags(b);
-+        n = ctx->buf_len - ctx->buf_off;
-+        while (ctx->blockout && n > 0) {
-+            i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
-+            if (i <= 0) {
-+                BIO_copy_next_retry(b);
-+                if (!BIO_should_retry(b))
-+                    ctx->cont = 0;
-+                return (i);
-+            }
-+            ctx->buf_off += i;
-+            n -= i;
-+        }
-+
-+        /* at this point all pending data has been written */
-+        ctx->blockout = 0;
-+        if (ctx->buf_len == ctx->buf_off) {
-+            ctx->buf_len = OK_BLOCK_BLOCK;
-+            ctx->buf_off = 0;
-+        }
-+
-+        if ((in == NULL) || (inl <= 0))
-+            return (0);
-+
-+        n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ?
-+            (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl;
-+
-+        memcpy(&ctx->buf[ctx->buf_len], in, n);
-+        ctx->buf_len += n;
-+        inl -= n;
-+        in += n;
-+
-+        if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) {
-+            if (!block_out(b)) {
-+                BIO_clear_retry_flags(b);
-+                return 0;
-+            }
-+        }
-+    } while (inl > 0);
-+
-+    BIO_clear_retry_flags(b);
-+    BIO_copy_next_retry(b);
-+    return (ret);
-+}
-+
-+static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
-+{
-+    BIO_OK_CTX *ctx;
-+    EVP_MD *md;
-+    const EVP_MD **ppmd;
-+    long ret = 1;
-+    int i;
-+    BIO *next;
-+
-+    ctx = BIO_get_data(b);
-+    next = BIO_next(b);
-+
-+    switch (cmd) {
-+    case BIO_CTRL_RESET:
-+        ctx->buf_len = 0;
-+        ctx->buf_off = 0;
-+        ctx->buf_len_save = 0;
-+        ctx->buf_off_save = 0;
-+        ctx->cont = 1;
-+        ctx->finished = 0;
-+        ctx->blockout = 0;
-+        ctx->sigio = 1;
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_EOF:         /* More to read */
-+        if (ctx->cont <= 0)
-+            ret = 1;
-+        else
-+            ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_PENDING:     /* More to read in buffer */
-+    case BIO_CTRL_WPENDING:    /* More to read in buffer */
-+        ret = ctx->blockout ? ctx->buf_len - ctx->buf_off : 0;
-+        if (ret <= 0)
-+            ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_CTRL_FLUSH:
-+        /* do a final write */
-+        if (ctx->blockout == 0)
-+            if (!block_out(b))
-+                return 0;
-+
-+        while (ctx->blockout) {
-+            i = ok_write(b, NULL, 0);
-+            if (i < 0) {
-+                ret = i;
-+                break;
-+            }
-+        }
-+
-+        ctx->finished = 1;
-+        ctx->buf_off = ctx->buf_len = 0;
-+        ctx->cont = (int)ret;
-+
-+        /* Finally flush the underlying BIO */
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    case BIO_C_DO_STATE_MACHINE:
-+        BIO_clear_retry_flags(b);
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        BIO_copy_next_retry(b);
-+        break;
-+    case BIO_CTRL_INFO:
-+        ret = (long)ctx->cont;
-+        break;
-+    case BIO_C_SET_MD:
-+        md = ptr;
-+        if (!EVP_DigestInit_ex(ctx->md, md, NULL))
-+            return 0;
-+        BIO_set_init(b, 1);
-+        break;
-+    case BIO_C_GET_MD:
-+        if (BIO_get_init(b)) {
-+            ppmd = ptr;
-+            *ppmd = EVP_MD_CTX_md(ctx->md);
-+        } else
-+            ret = 0;
-+        break;
-+    default:
-+        ret = BIO_ctrl(next, cmd, num, ptr);
-+        break;
-+    }
-+    return ret;
-+}
-+
-+static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
-+{
-+    long ret = 1;
-+    BIO *next;
-+
-+    next = BIO_next(b);
-+
-+    if (next == NULL)
-+        return 0;
-+
-+    switch (cmd) {
-+    default:
-+        ret = BIO_callback_ctrl(next, cmd, fp);
-+        break;
-+    }
-+
-+    return ret;
-+}
-+
-+static void longswap(void *_ptr, size_t len)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = {
-+        1
-+    };
-+
-+    if (is_endian.little) {
-+        size_t i;
-+        unsigned char *p = _ptr, c;
-+
-+        for (i = 0; i < len; i += 4) {
-+            c = p[0], p[0] = p[3], p[3] = c;
-+            c = p[1], p[1] = p[2], p[2] = c;
-+        }
-+    }
-+}
-+
-+static int sig_out(BIO *b)
-+{
-+    BIO_OK_CTX *ctx;
-+    EVP_MD_CTX *md;
-+    const EVP_MD *digest;
-+    int md_size;
-+    void *md_data;
-+
-+    ctx = BIO_get_data(b);
-+    md = ctx->md;
-+    digest = EVP_MD_CTX_md(md);
-+    md_size = EVP_MD_size(digest);
-+    md_data = EVP_MD_CTX_md_data(md);
-+
-+    if (ctx->buf_len + 2 * md_size > OK_BLOCK_SIZE)
-+        return 1;
-+
-+    if (!EVP_DigestInit_ex(md, digest, NULL))
-+        goto berr;
-+    /*
-+     * FIXME: there's absolutely no guarantee this makes any sense at all,
-+     * particularly now EVP_MD_CTX has been restructured.
-+     */
-+    if (RAND_bytes(md_data, md_size) <= 0)
-+        goto berr;
-+    memcpy(&(ctx->buf[ctx->buf_len]), md_data, md_size);
-+    longswap(&(ctx->buf[ctx->buf_len]), md_size);
-+    ctx->buf_len += md_size;
-+
-+    if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
-+        goto berr;
-+    if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
-+        goto berr;
-+    ctx->buf_len += md_size;
-+    ctx->blockout = 1;
-+    ctx->sigio = 0;
-+    return 1;
-+ berr:
-+    BIO_clear_retry_flags(b);
-+    return 0;
-+}
-+
-+static int sig_in(BIO *b)
-+{
-+    BIO_OK_CTX *ctx;
-+    EVP_MD_CTX *md;
-+    unsigned char tmp[EVP_MAX_MD_SIZE];
-+    int ret = 0;
-+    const EVP_MD *digest;
-+    int md_size;
-+    void *md_data;
-+
-+    ctx = BIO_get_data(b);
-+    md = ctx->md;
-+    digest = EVP_MD_CTX_md(md);
-+    md_size = EVP_MD_size(digest);
-+    md_data = EVP_MD_CTX_md_data(md);
-+
-+    if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md_size)
-+        return 1;
-+
-+    if (!EVP_DigestInit_ex(md, digest, NULL))
-+        goto berr;
-+    memcpy(md_data, &(ctx->buf[ctx->buf_off]), md_size);
-+    longswap(md_data, md_size);
-+    ctx->buf_off += md_size;
-+
-+    if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
-+        goto berr;
-+    if (!EVP_DigestFinal_ex(md, tmp, NULL))
-+        goto berr;
-+    ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md_size) == 0;
-+    ctx->buf_off += md_size;
-+    if (ret == 1) {
-+        ctx->sigio = 0;
-+        if (ctx->buf_len != ctx->buf_off) {
-+            memmove(ctx->buf, &(ctx->buf[ctx->buf_off]),
-+                    ctx->buf_len - ctx->buf_off);
-+        }
-+        ctx->buf_len -= ctx->buf_off;
-+        ctx->buf_off = 0;
-+    } else {
-+        ctx->cont = 0;
-+    }
-+    return 1;
-+ berr:
-+    BIO_clear_retry_flags(b);
-+    return 0;
-+}
-+
-+static int block_out(BIO *b)
-+{
-+    BIO_OK_CTX *ctx;
-+    EVP_MD_CTX *md;
-+    unsigned long tl;
-+    const EVP_MD *digest;
-+    int md_size;
-+
-+    ctx = BIO_get_data(b);
-+    md = ctx->md;
-+    digest = EVP_MD_CTX_md(md);
-+    md_size = EVP_MD_size(digest);
-+
-+    tl = ctx->buf_len - OK_BLOCK_BLOCK;
-+    ctx->buf[0] = (unsigned char)(tl >> 24);
-+    ctx->buf[1] = (unsigned char)(tl >> 16);
-+    ctx->buf[2] = (unsigned char)(tl >> 8);
-+    ctx->buf[3] = (unsigned char)(tl);
-+    if (!EVP_DigestUpdate(md,
-+                          (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
-+        goto berr;
-+    if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
-+        goto berr;
-+    ctx->buf_len += md_size;
-+    ctx->blockout = 1;
-+    return 1;
-+ berr:
-+    BIO_clear_retry_flags(b);
-+    return 0;
-+}
-+
-+static int block_in(BIO *b)
-+{
-+    BIO_OK_CTX *ctx;
-+    EVP_MD_CTX *md;
-+    unsigned long tl = 0;
-+    unsigned char tmp[EVP_MAX_MD_SIZE];
-+    int md_size;
-+
-+    ctx = BIO_get_data(b);
-+    md = ctx->md;
-+    md_size = EVP_MD_size(EVP_MD_CTX_md(md));
-+
-+    assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */
-+    tl = ctx->buf[0];
-+    tl <<= 8;
-+    tl |= ctx->buf[1];
-+    tl <<= 8;
-+    tl |= ctx->buf[2];
-+    tl <<= 8;
-+    tl |= ctx->buf[3];
-+
-+    if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md_size)
-+        return 1;
-+
-+    if (!EVP_DigestUpdate(md,
-+                          (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
-+        goto berr;
-+    if (!EVP_DigestFinal_ex(md, tmp, NULL))
-+        goto berr;
-+    if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md_size) == 0) {
-+        /* there might be parts from next block lurking around ! */
-+        ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md_size;
-+        ctx->buf_len_save = ctx->buf_len;
-+        ctx->buf_off = OK_BLOCK_BLOCK;
-+        ctx->buf_len = tl + OK_BLOCK_BLOCK;
-+        ctx->blockout = 1;
-+    } else {
-+        ctx->cont = 0;
-+    }
-+    return 1;
-+ berr:
-+    BIO_clear_retry_flags(b);
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/build.info
-new file mode 100644
-index 0000000..bf633dc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/build.info
-@@ -0,0 +1,22 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        encode.c digest.c evp_enc.c evp_key.c evp_cnf.c \
-+        e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
-+        e_rc4.c e_aes.c names.c e_seed.c \
-+        e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
-+        m_null.c m_md2.c m_md4.c m_md5.c m_sha1.c m_wp.c \
-+        m_md5_sha1.c m_mdc2.c m_ripemd.c \
-+        p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
-+        bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
-+        c_allc.c c_alld.c evp_lib.c bio_ok.c \
-+        evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c scrypt.c \
-+        e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
-+        e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
-+        e_chacha20_poly1305.c cmeth_lib.c
-+
-+INCLUDE[e_aes.o]=.. ../modes
-+INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes
-+INCLUDE[e_aes_cbc_hmac_sha256.o]=../modes
-+INCLUDE[e_camellia.o]=.. ../modes
-+INCLUDE[e_des.o]=..
-+INCLUDE[e_des3.o]=..
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/c_allc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/c_allc.c
-new file mode 100644
-index 0000000..6ed31ed
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/c_allc.c
-@@ -0,0 +1,220 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+void openssl_add_all_ciphers_int(void)
-+{
-+
-+#ifndef OPENSSL_NO_DES
-+    EVP_add_cipher(EVP_des_cfb());
-+    EVP_add_cipher(EVP_des_cfb1());
-+    EVP_add_cipher(EVP_des_cfb8());
-+    EVP_add_cipher(EVP_des_ede_cfb());
-+    EVP_add_cipher(EVP_des_ede3_cfb());
-+    EVP_add_cipher(EVP_des_ede3_cfb1());
-+    EVP_add_cipher(EVP_des_ede3_cfb8());
-+
-+    EVP_add_cipher(EVP_des_ofb());
-+    EVP_add_cipher(EVP_des_ede_ofb());
-+    EVP_add_cipher(EVP_des_ede3_ofb());
-+
-+    EVP_add_cipher(EVP_desx_cbc());
-+    EVP_add_cipher_alias(SN_desx_cbc, "DESX");
-+    EVP_add_cipher_alias(SN_desx_cbc, "desx");
-+
-+    EVP_add_cipher(EVP_des_cbc());
-+    EVP_add_cipher_alias(SN_des_cbc, "DES");
-+    EVP_add_cipher_alias(SN_des_cbc, "des");
-+    EVP_add_cipher(EVP_des_ede_cbc());
-+    EVP_add_cipher(EVP_des_ede3_cbc());
-+    EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3");
-+    EVP_add_cipher_alias(SN_des_ede3_cbc, "des3");
-+
-+    EVP_add_cipher(EVP_des_ecb());
-+    EVP_add_cipher(EVP_des_ede());
-+    EVP_add_cipher_alias(SN_des_ede_ecb, "DES-EDE-ECB");
-+    EVP_add_cipher_alias(SN_des_ede_ecb, "des-ede-ecb");
-+    EVP_add_cipher(EVP_des_ede3());
-+    EVP_add_cipher_alias(SN_des_ede3_ecb, "DES-EDE3-ECB");
-+    EVP_add_cipher_alias(SN_des_ede3_ecb, "des-ede3-ecb");
-+    EVP_add_cipher(EVP_des_ede3_wrap());
-+    EVP_add_cipher_alias(SN_id_smime_alg_CMS3DESwrap, "des3-wrap");
-+#endif
-+
-+#ifndef OPENSSL_NO_RC4
-+    EVP_add_cipher(EVP_rc4());
-+    EVP_add_cipher(EVP_rc4_40());
-+# ifndef OPENSSL_NO_MD5
-+    EVP_add_cipher(EVP_rc4_hmac_md5());
-+# endif
-+#endif
-+
-+#ifndef OPENSSL_NO_IDEA
-+    EVP_add_cipher(EVP_idea_ecb());
-+    EVP_add_cipher(EVP_idea_cfb());
-+    EVP_add_cipher(EVP_idea_ofb());
-+    EVP_add_cipher(EVP_idea_cbc());
-+    EVP_add_cipher_alias(SN_idea_cbc, "IDEA");
-+    EVP_add_cipher_alias(SN_idea_cbc, "idea");
-+#endif
-+
-+#ifndef OPENSSL_NO_SEED
-+    EVP_add_cipher(EVP_seed_ecb());
-+    EVP_add_cipher(EVP_seed_cfb());
-+    EVP_add_cipher(EVP_seed_ofb());
-+    EVP_add_cipher(EVP_seed_cbc());
-+    EVP_add_cipher_alias(SN_seed_cbc, "SEED");
-+    EVP_add_cipher_alias(SN_seed_cbc, "seed");
-+#endif
-+
-+#ifndef OPENSSL_NO_RC2
-+    EVP_add_cipher(EVP_rc2_ecb());
-+    EVP_add_cipher(EVP_rc2_cfb());
-+    EVP_add_cipher(EVP_rc2_ofb());
-+    EVP_add_cipher(EVP_rc2_cbc());
-+    EVP_add_cipher(EVP_rc2_40_cbc());
-+    EVP_add_cipher(EVP_rc2_64_cbc());
-+    EVP_add_cipher_alias(SN_rc2_cbc, "RC2");
-+    EVP_add_cipher_alias(SN_rc2_cbc, "rc2");
-+    EVP_add_cipher_alias(SN_rc2_cbc, "rc2-128");
-+    EVP_add_cipher_alias(SN_rc2_64_cbc, "rc2-64");
-+    EVP_add_cipher_alias(SN_rc2_40_cbc, "rc2-40");
-+#endif
-+
-+#ifndef OPENSSL_NO_BF
-+    EVP_add_cipher(EVP_bf_ecb());
-+    EVP_add_cipher(EVP_bf_cfb());
-+    EVP_add_cipher(EVP_bf_ofb());
-+    EVP_add_cipher(EVP_bf_cbc());
-+    EVP_add_cipher_alias(SN_bf_cbc, "BF");
-+    EVP_add_cipher_alias(SN_bf_cbc, "bf");
-+    EVP_add_cipher_alias(SN_bf_cbc, "blowfish");
-+#endif
-+
-+#ifndef OPENSSL_NO_CAST
-+    EVP_add_cipher(EVP_cast5_ecb());
-+    EVP_add_cipher(EVP_cast5_cfb());
-+    EVP_add_cipher(EVP_cast5_ofb());
-+    EVP_add_cipher(EVP_cast5_cbc());
-+    EVP_add_cipher_alias(SN_cast5_cbc, "CAST");
-+    EVP_add_cipher_alias(SN_cast5_cbc, "cast");
-+    EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc");
-+    EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc");
-+#endif
-+
-+#ifndef OPENSSL_NO_RC5
-+    EVP_add_cipher(EVP_rc5_32_12_16_ecb());
-+    EVP_add_cipher(EVP_rc5_32_12_16_cfb());
-+    EVP_add_cipher(EVP_rc5_32_12_16_ofb());
-+    EVP_add_cipher(EVP_rc5_32_12_16_cbc());
-+    EVP_add_cipher_alias(SN_rc5_cbc, "rc5");
-+    EVP_add_cipher_alias(SN_rc5_cbc, "RC5");
-+#endif
-+
-+    EVP_add_cipher(EVP_aes_128_ecb());
-+    EVP_add_cipher(EVP_aes_128_cbc());
-+    EVP_add_cipher(EVP_aes_128_cfb());
-+    EVP_add_cipher(EVP_aes_128_cfb1());
-+    EVP_add_cipher(EVP_aes_128_cfb8());
-+    EVP_add_cipher(EVP_aes_128_ofb());
-+    EVP_add_cipher(EVP_aes_128_ctr());
-+    EVP_add_cipher(EVP_aes_128_gcm());
-+#ifndef OPENSSL_NO_OCB
-+    EVP_add_cipher(EVP_aes_128_ocb());
-+#endif
-+    EVP_add_cipher(EVP_aes_128_xts());
-+    EVP_add_cipher(EVP_aes_128_ccm());
-+    EVP_add_cipher(EVP_aes_128_wrap());
-+    EVP_add_cipher_alias(SN_id_aes128_wrap, "aes128-wrap");
-+    EVP_add_cipher(EVP_aes_128_wrap_pad());
-+    EVP_add_cipher_alias(SN_aes_128_cbc, "AES128");
-+    EVP_add_cipher_alias(SN_aes_128_cbc, "aes128");
-+    EVP_add_cipher(EVP_aes_192_ecb());
-+    EVP_add_cipher(EVP_aes_192_cbc());
-+    EVP_add_cipher(EVP_aes_192_cfb());
-+    EVP_add_cipher(EVP_aes_192_cfb1());
-+    EVP_add_cipher(EVP_aes_192_cfb8());
-+    EVP_add_cipher(EVP_aes_192_ofb());
-+    EVP_add_cipher(EVP_aes_192_ctr());
-+    EVP_add_cipher(EVP_aes_192_gcm());
-+#ifndef OPENSSL_NO_OCB
-+    EVP_add_cipher(EVP_aes_192_ocb());
-+#endif
-+    EVP_add_cipher(EVP_aes_192_ccm());
-+    EVP_add_cipher(EVP_aes_192_wrap());
-+    EVP_add_cipher_alias(SN_id_aes192_wrap, "aes192-wrap");
-+    EVP_add_cipher(EVP_aes_192_wrap_pad());
-+    EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
-+    EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
-+    EVP_add_cipher(EVP_aes_256_ecb());
-+    EVP_add_cipher(EVP_aes_256_cbc());
-+    EVP_add_cipher(EVP_aes_256_cfb());
-+    EVP_add_cipher(EVP_aes_256_cfb1());
-+    EVP_add_cipher(EVP_aes_256_cfb8());
-+    EVP_add_cipher(EVP_aes_256_ofb());
-+    EVP_add_cipher(EVP_aes_256_ctr());
-+    EVP_add_cipher(EVP_aes_256_gcm());
-+#ifndef OPENSSL_NO_OCB
-+    EVP_add_cipher(EVP_aes_256_ocb());
-+#endif
-+    EVP_add_cipher(EVP_aes_256_xts());
-+    EVP_add_cipher(EVP_aes_256_ccm());
-+    EVP_add_cipher(EVP_aes_256_wrap());
-+    EVP_add_cipher_alias(SN_id_aes256_wrap, "aes256-wrap");
-+    EVP_add_cipher(EVP_aes_256_wrap_pad());
-+    EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
-+    EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
-+    EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
-+    EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
-+    EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
-+    EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
-+
-+#ifndef OPENSSL_NO_CAMELLIA
-+    EVP_add_cipher(EVP_camellia_128_ecb());
-+    EVP_add_cipher(EVP_camellia_128_cbc());
-+    EVP_add_cipher(EVP_camellia_128_cfb());
-+    EVP_add_cipher(EVP_camellia_128_cfb1());
-+    EVP_add_cipher(EVP_camellia_128_cfb8());
-+    EVP_add_cipher(EVP_camellia_128_ofb());
-+    EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128");
-+    EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128");
-+    EVP_add_cipher(EVP_camellia_192_ecb());
-+    EVP_add_cipher(EVP_camellia_192_cbc());
-+    EVP_add_cipher(EVP_camellia_192_cfb());
-+    EVP_add_cipher(EVP_camellia_192_cfb1());
-+    EVP_add_cipher(EVP_camellia_192_cfb8());
-+    EVP_add_cipher(EVP_camellia_192_ofb());
-+    EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192");
-+    EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192");
-+    EVP_add_cipher(EVP_camellia_256_ecb());
-+    EVP_add_cipher(EVP_camellia_256_cbc());
-+    EVP_add_cipher(EVP_camellia_256_cfb());
-+    EVP_add_cipher(EVP_camellia_256_cfb1());
-+    EVP_add_cipher(EVP_camellia_256_cfb8());
-+    EVP_add_cipher(EVP_camellia_256_ofb());
-+    EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256");
-+    EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256");
-+    EVP_add_cipher(EVP_camellia_128_ctr());
-+    EVP_add_cipher(EVP_camellia_192_ctr());
-+    EVP_add_cipher(EVP_camellia_256_ctr());
-+#endif
-+
-+#ifndef OPENSSL_NO_CHACHA
-+    EVP_add_cipher(EVP_chacha20());
-+# ifndef OPENSSL_NO_POLY1305
-+    EVP_add_cipher(EVP_chacha20_poly1305());
-+# endif
-+#endif
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/c_alld.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/c_alld.c
-new file mode 100644
-index 0000000..ec79734
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/c_alld.c
-@@ -0,0 +1,49 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+void openssl_add_all_digests_int(void)
-+{
-+#ifndef OPENSSL_NO_MD4
-+    EVP_add_digest(EVP_md4());
-+#endif
-+#ifndef OPENSSL_NO_MD5
-+    EVP_add_digest(EVP_md5());
-+    EVP_add_digest_alias(SN_md5, "ssl3-md5");
-+    EVP_add_digest(EVP_md5_sha1());
-+#endif
-+    EVP_add_digest(EVP_sha1());
-+    EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
-+    EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
-+#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
-+    EVP_add_digest(EVP_mdc2());
-+#endif
-+#ifndef OPENSSL_NO_RMD160
-+    EVP_add_digest(EVP_ripemd160());
-+    EVP_add_digest_alias(SN_ripemd160, "ripemd");
-+    EVP_add_digest_alias(SN_ripemd160, "rmd160");
-+#endif
-+    EVP_add_digest(EVP_sha224());
-+    EVP_add_digest(EVP_sha256());
-+    EVP_add_digest(EVP_sha384());
-+    EVP_add_digest(EVP_sha512());
-+#ifndef OPENSSL_NO_WHIRLPOOL
-+    EVP_add_digest(EVP_whirlpool());
-+#endif
-+#ifndef OPENSSL_NO_BLAKE2
-+    EVP_add_digest(EVP_blake2b512());
-+    EVP_add_digest(EVP_blake2s256());
-+#endif
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/cmeth_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/cmeth_lib.c
-new file mode 100644
-index 0000000..e2295c4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/cmeth_lib.c
-@@ -0,0 +1,151 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#include 
-+#include "internal/evp_int.h"
-+#include "evp_locl.h"
-+
-+EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
-+{
-+    EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER));
-+
-+    if (cipher != NULL) {
-+        cipher->nid = cipher_type;
-+        cipher->block_size = block_size;
-+        cipher->key_len = key_len;
-+    }
-+    return cipher;
-+}
-+
-+EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher)
-+{
-+    EVP_CIPHER *to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size,
-+                                         cipher->key_len);
-+
-+    if (to != NULL)
-+        memcpy(to, cipher, sizeof(*to));
-+    return to;
-+}
-+
-+void EVP_CIPHER_meth_free(EVP_CIPHER *cipher)
-+{
-+    OPENSSL_free(cipher);
-+}
-+
-+int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len)
-+{
-+    cipher->iv_len = iv_len;
-+    return 1;
-+}
-+
-+int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags)
-+{
-+    cipher->flags = flags;
-+    return 1;
-+}
-+
-+int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size)
-+{
-+    cipher->ctx_size = ctx_size;
-+    return 1;
-+}
-+
-+int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher,
-+                             int (*init) (EVP_CIPHER_CTX *ctx,
-+                                          const unsigned char *key,
-+                                          const unsigned char *iv,
-+                                          int enc))
-+{
-+    cipher->init = init;
-+    return 1;
-+}
-+
-+int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher,
-+                                  int (*do_cipher) (EVP_CIPHER_CTX *ctx,
-+                                                    unsigned char *out,
-+                                                    const unsigned char *in,
-+                                                    size_t inl))
-+{
-+    cipher->do_cipher = do_cipher;
-+    return 1;
-+}
-+
-+int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher,
-+                                int (*cleanup) (EVP_CIPHER_CTX *))
-+{
-+    cipher->cleanup = cleanup;
-+    return 1;
-+}
-+
-+int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher,
-+                                        int (*set_asn1_parameters) (EVP_CIPHER_CTX *,
-+                                                                    ASN1_TYPE *))
-+{
-+    cipher->set_asn1_parameters = set_asn1_parameters;
-+    return 1;
-+}
-+
-+int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher,
-+                                        int (*get_asn1_parameters) (EVP_CIPHER_CTX *,
-+                                                                    ASN1_TYPE *))
-+{
-+    cipher->get_asn1_parameters = get_asn1_parameters;
-+    return 1;
-+}
-+
-+int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher,
-+                             int (*ctrl) (EVP_CIPHER_CTX *, int type,
-+                                          int arg, void *ptr))
-+{
-+    cipher->ctrl = ctrl;
-+    return 1;
-+}
-+
-+
-+int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
-+                                                          const unsigned char *key,
-+                                                          const unsigned char *iv,
-+                                                          int enc)
-+{
-+    return cipher->init;
-+}
-+int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
-+                                                               unsigned char *out,
-+                                                               const unsigned char *in,
-+                                                               size_t inl)
-+{
-+    return cipher->do_cipher;
-+}
-+
-+int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *)
-+{
-+    return cipher->cleanup;
-+}
-+
-+int (*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
-+                                                                     ASN1_TYPE *)
-+{
-+    return cipher->set_asn1_parameters;
-+}
-+
-+int (*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
-+                                                               ASN1_TYPE *)
-+{
-+    return cipher->get_asn1_parameters;
-+}
-+
-+int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
-+                                                          int type, int arg,
-+                                                          void *ptr)
-+{
-+    return cipher->ctrl;
-+}
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/digest.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/digest.c
-new file mode 100644
-index 0000000..65eff7c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/digest.c
-@@ -0,0 +1,269 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+#include "evp_locl.h"
-+
-+/* This call frees resources associated with the context */
-+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
-+{
-+    if (ctx == NULL)
-+        return 1;
-+
-+    /*
-+     * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
-+     * sometimes only copies of the context are ever finalised.
-+     */
-+    if (ctx->digest && ctx->digest->cleanup
-+        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
-+        ctx->digest->cleanup(ctx);
-+    if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
-+        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
-+        OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
-+    }
-+    EVP_PKEY_CTX_free(ctx->pctx);
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(ctx->engine);
-+#endif
-+    OPENSSL_cleanse(ctx, sizeof(*ctx));
-+
-+    return 1;
-+}
-+
-+EVP_MD_CTX *EVP_MD_CTX_new(void)
-+{
-+    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
-+}
-+
-+void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
-+{
-+    EVP_MD_CTX_reset(ctx);
-+    OPENSSL_free(ctx);
-+}
-+
-+int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
-+{
-+    EVP_MD_CTX_reset(ctx);
-+    return EVP_DigestInit_ex(ctx, type, NULL);
-+}
-+
-+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
-+{
-+    EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
-+#ifndef OPENSSL_NO_ENGINE
-+    /*
-+     * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
-+     * this context may already have an ENGINE! Try to avoid releasing the
-+     * previous handle, re-querying for an ENGINE, and having a
-+     * reinitialisation, when it may all be unnecessary.
-+     */
-+    if (ctx->engine && ctx->digest &&
-+        (type == NULL || (type->type == ctx->digest->type)))
-+        goto skip_to_init;
-+    if (type) {
-+        /*
-+         * Ensure an ENGINE left lying around from last time is cleared (the
-+         * previous check attempted to avoid this if the same ENGINE and
-+         * EVP_MD could be used).
-+         */
-+        ENGINE_finish(ctx->engine);
-+        if (impl != NULL) {
-+            if (!ENGINE_init(impl)) {
-+                EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
-+                return 0;
-+            }
-+        } else {
-+            /* Ask if an ENGINE is reserved for this job */
-+            impl = ENGINE_get_digest_engine(type->type);
-+        }
-+        if (impl != NULL) {
-+            /* There's an ENGINE for this job ... (apparently) */
-+            const EVP_MD *d = ENGINE_get_digest(impl, type->type);
-+
-+            if (d == NULL) {
-+                EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
-+                ENGINE_finish(impl);
-+                return 0;
-+            }
-+            /* We'll use the ENGINE's private digest definition */
-+            type = d;
-+            /*
-+             * Store the ENGINE functional reference so we know 'type' came
-+             * from an ENGINE and we need to release it when done.
-+             */
-+            ctx->engine = impl;
-+        } else
-+            ctx->engine = NULL;
-+    } else {
-+        if (!ctx->digest) {
-+            EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET);
-+            return 0;
-+        }
-+        type = ctx->digest;
-+    }
-+#endif
-+    if (ctx->digest != type) {
-+        if (ctx->digest && ctx->digest->ctx_size) {
-+            OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
-+            ctx->md_data = NULL;
-+        }
-+        ctx->digest = type;
-+        if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
-+            ctx->update = type->update;
-+            ctx->md_data = OPENSSL_zalloc(type->ctx_size);
-+            if (ctx->md_data == NULL) {
-+                EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
-+                return 0;
-+            }
-+        }
-+    }
-+#ifndef OPENSSL_NO_ENGINE
-+ skip_to_init:
-+#endif
-+    if (ctx->pctx) {
-+        int r;
-+        r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
-+                              EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
-+        if (r <= 0 && (r != -2))
-+            return 0;
-+    }
-+    if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
-+        return 1;
-+    return ctx->digest->init(ctx);
-+}
-+
-+int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return ctx->update(ctx, data, count);
-+}
-+
-+/* The caller can assume that this removes any secret data from the context */
-+int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
-+{
-+    int ret;
-+    ret = EVP_DigestFinal_ex(ctx, md, size);
-+    EVP_MD_CTX_reset(ctx);
-+    return ret;
-+}
-+
-+/* The caller can assume that this removes any secret data from the context */
-+int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
-+{
-+    int ret;
-+
-+    OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
-+    ret = ctx->digest->final(ctx, md);
-+    if (size != NULL)
-+        *size = ctx->digest->md_size;
-+    if (ctx->digest->cleanup) {
-+        ctx->digest->cleanup(ctx);
-+        EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
-+    }
-+    OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
-+    return ret;
-+}
-+
-+int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
-+{
-+    EVP_MD_CTX_reset(out);
-+    return EVP_MD_CTX_copy_ex(out, in);
-+}
-+
-+int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
-+{
-+    unsigned char *tmp_buf;
-+    if ((in == NULL) || (in->digest == NULL)) {
-+        EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED);
-+        return 0;
-+    }
-+#ifndef OPENSSL_NO_ENGINE
-+    /* Make sure it's safe to copy a digest context using an ENGINE */
-+    if (in->engine && !ENGINE_init(in->engine)) {
-+        EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB);
-+        return 0;
-+    }
-+#endif
-+
-+    if (out->digest == in->digest) {
-+        tmp_buf = out->md_data;
-+        EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
-+    } else
-+        tmp_buf = NULL;
-+    EVP_MD_CTX_reset(out);
-+    memcpy(out, in, sizeof(*out));
-+
-+    /* Null these variables, since they are getting fixed up
-+     * properly below.  Anything else may cause a memleak and/or
-+     * double free if any of the memory allocations below fail
-+     */
-+    out->md_data = NULL;
-+    out->pctx = NULL;
-+
-+    if (in->md_data && out->digest->ctx_size) {
-+        if (tmp_buf)
-+            out->md_data = tmp_buf;
-+        else {
-+            out->md_data = OPENSSL_malloc(out->digest->ctx_size);
-+            if (out->md_data == NULL) {
-+                EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE);
-+                return 0;
-+            }
-+        }
-+        memcpy(out->md_data, in->md_data, out->digest->ctx_size);
-+    }
-+
-+    out->update = in->update;
-+
-+    if (in->pctx) {
-+        out->pctx = EVP_PKEY_CTX_dup(in->pctx);
-+        if (!out->pctx) {
-+            EVP_MD_CTX_reset(out);
-+            return 0;
-+        }
-+    }
-+
-+    if (out->digest->copy)
-+        return out->digest->copy(out, in);
-+
-+    return 1;
-+}
-+
-+int EVP_Digest(const void *data, size_t count,
-+               unsigned char *md, unsigned int *size, const EVP_MD *type,
-+               ENGINE *impl)
-+{
-+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
-+    int ret;
-+
-+    if (ctx == NULL)
-+        return 0;
-+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT);
-+    ret = EVP_DigestInit_ex(ctx, type, impl)
-+        && EVP_DigestUpdate(ctx, data, count)
-+        && EVP_DigestFinal_ex(ctx, md, size);
-+    EVP_MD_CTX_free(ctx);
-+
-+    return ret;
-+}
-+
-+int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
-+{
-+    if (ctx->digest && ctx->digest->md_ctrl) {
-+        int ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2);
-+        if (ret <= 0)
-+            return 0;
-+        return 1;
-+    }
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes.c
-new file mode 100644
-index 0000000..17822f2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes.c
-@@ -0,0 +1,2702 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+#include "modes_lcl.h"
-+#include 
-+#include "evp_locl.h"
-+
-+typedef struct {
-+    union {
-+        double align;
-+        AES_KEY ks;
-+    } ks;
-+    block128_f block;
-+    union {
-+        cbc128_f cbc;
-+        ctr128_f ctr;
-+    } stream;
-+} EVP_AES_KEY;
-+
-+typedef struct {
-+    union {
-+        double align;
-+        AES_KEY ks;
-+    } ks;                       /* AES key schedule to use */
-+    int key_set;                /* Set if key initialised */
-+    int iv_set;                 /* Set if an iv is set */
-+    GCM128_CONTEXT gcm;
-+    unsigned char *iv;          /* Temporary IV store */
-+    int ivlen;                  /* IV length */
-+    int taglen;
-+    int iv_gen;                 /* It is OK to generate IVs */
-+    int tls_aad_len;            /* TLS AAD length */
-+    ctr128_f ctr;
-+} EVP_AES_GCM_CTX;
-+
-+typedef struct {
-+    union {
-+        double align;
-+        AES_KEY ks;
-+    } ks1, ks2;                 /* AES key schedules to use */
-+    XTS128_CONTEXT xts;
-+    void (*stream) (const unsigned char *in,
-+                    unsigned char *out, size_t length,
-+                    const AES_KEY *key1, const AES_KEY *key2,
-+                    const unsigned char iv[16]);
-+} EVP_AES_XTS_CTX;
-+
-+typedef struct {
-+    union {
-+        double align;
-+        AES_KEY ks;
-+    } ks;                       /* AES key schedule to use */
-+    int key_set;                /* Set if key initialised */
-+    int iv_set;                 /* Set if an iv is set */
-+    int tag_set;                /* Set if tag is valid */
-+    int len_set;                /* Set if message length set */
-+    int L, M;                   /* L and M parameters from RFC3610 */
-+    int tls_aad_len;            /* TLS AAD length */
-+    CCM128_CONTEXT ccm;
-+    ccm128_f str;
-+} EVP_AES_CCM_CTX;
-+
-+#ifndef OPENSSL_NO_OCB
-+typedef struct {
-+    union {
-+        double align;
-+        AES_KEY ks;
-+    } ksenc;                    /* AES key schedule to use for encryption */
-+    union {
-+        double align;
-+        AES_KEY ks;
-+    } ksdec;                    /* AES key schedule to use for decryption */
-+    int key_set;                /* Set if key initialised */
-+    int iv_set;                 /* Set if an iv is set */
-+    OCB128_CONTEXT ocb;
-+    unsigned char *iv;          /* Temporary IV store */
-+    unsigned char tag[16];
-+    unsigned char data_buf[16]; /* Store partial data blocks */
-+    unsigned char aad_buf[16];  /* Store partial AAD blocks */
-+    int data_buf_len;
-+    int aad_buf_len;
-+    int ivlen;                  /* IV length */
-+    int taglen;
-+} EVP_AES_OCB_CTX;
-+#endif
-+
-+#define MAXBITCHUNK     ((size_t)1<<(sizeof(size_t)*8-4))
-+
-+#ifdef VPAES_ASM
-+int vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
-+                          AES_KEY *key);
-+int vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
-+                          AES_KEY *key);
-+
-+void vpaes_encrypt(const unsigned char *in, unsigned char *out,
-+                   const AES_KEY *key);
-+void vpaes_decrypt(const unsigned char *in, unsigned char *out,
-+                   const AES_KEY *key);
-+
-+void vpaes_cbc_encrypt(const unsigned char *in,
-+                       unsigned char *out,
-+                       size_t length,
-+                       const AES_KEY *key, unsigned char *ivec, int enc);
-+#endif
-+#ifdef BSAES_ASM
-+void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                       size_t length, const AES_KEY *key,
-+                       unsigned char ivec[16], int enc);
-+void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
-+                                size_t len, const AES_KEY *key,
-+                                const unsigned char ivec[16]);
-+void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
-+                       size_t len, const AES_KEY *key1,
-+                       const AES_KEY *key2, const unsigned char iv[16]);
-+void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
-+                       size_t len, const AES_KEY *key1,
-+                       const AES_KEY *key2, const unsigned char iv[16]);
-+#endif
-+#ifdef AES_CTR_ASM
-+void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
-+                       size_t blocks, const AES_KEY *key,
-+                       const unsigned char ivec[AES_BLOCK_SIZE]);
-+#endif
-+#ifdef AES_XTS_ASM
-+void AES_xts_encrypt(const char *inp, char *out, size_t len,
-+                     const AES_KEY *key1, const AES_KEY *key2,
-+                     const unsigned char iv[16]);
-+void AES_xts_decrypt(const char *inp, char *out, size_t len,
-+                     const AES_KEY *key1, const AES_KEY *key2,
-+                     const unsigned char iv[16]);
-+#endif
-+
-+#if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
-+# include "ppc_arch.h"
-+# ifdef VPAES_ASM
-+#  define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC)
-+# endif
-+# define HWAES_CAPABLE  (OPENSSL_ppccap_P & PPC_CRYPTO207)
-+# define HWAES_set_encrypt_key aes_p8_set_encrypt_key
-+# define HWAES_set_decrypt_key aes_p8_set_decrypt_key
-+# define HWAES_encrypt aes_p8_encrypt
-+# define HWAES_decrypt aes_p8_decrypt
-+# define HWAES_cbc_encrypt aes_p8_cbc_encrypt
-+# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
-+# define HWAES_xts_encrypt aes_p8_xts_encrypt
-+# define HWAES_xts_decrypt aes_p8_xts_decrypt
-+#endif
-+
-+#if     defined(AES_ASM) && !defined(I386_ONLY) &&      (  \
-+        ((defined(__i386)       || defined(__i386__)    || \
-+          defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
-+        defined(__x86_64)       || defined(__x86_64__)  || \
-+        defined(_M_AMD64)       || defined(_M_X64)      )
-+
-+extern unsigned int OPENSSL_ia32cap_P[];
-+
-+# ifdef VPAES_ASM
-+#  define VPAES_CAPABLE   (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
-+# endif
-+# ifdef BSAES_ASM
-+#  define BSAES_CAPABLE   (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
-+# endif
-+/*
-+ * AES-NI section
-+ */
-+# define AESNI_CAPABLE   (OPENSSL_ia32cap_P[1]&(1<<(57-32)))
-+
-+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
-+                          AES_KEY *key);
-+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
-+                          AES_KEY *key);
-+
-+void aesni_encrypt(const unsigned char *in, unsigned char *out,
-+                   const AES_KEY *key);
-+void aesni_decrypt(const unsigned char *in, unsigned char *out,
-+                   const AES_KEY *key);
-+
-+void aesni_ecb_encrypt(const unsigned char *in,
-+                       unsigned char *out,
-+                       size_t length, const AES_KEY *key, int enc);
-+void aesni_cbc_encrypt(const unsigned char *in,
-+                       unsigned char *out,
-+                       size_t length,
-+                       const AES_KEY *key, unsigned char *ivec, int enc);
-+
-+void aesni_ctr32_encrypt_blocks(const unsigned char *in,
-+                                unsigned char *out,
-+                                size_t blocks,
-+                                const void *key, const unsigned char *ivec);
-+
-+void aesni_xts_encrypt(const unsigned char *in,
-+                       unsigned char *out,
-+                       size_t length,
-+                       const AES_KEY *key1, const AES_KEY *key2,
-+                       const unsigned char iv[16]);
-+
-+void aesni_xts_decrypt(const unsigned char *in,
-+                       unsigned char *out,
-+                       size_t length,
-+                       const AES_KEY *key1, const AES_KEY *key2,
-+                       const unsigned char iv[16]);
-+
-+void aesni_ccm64_encrypt_blocks(const unsigned char *in,
-+                                unsigned char *out,
-+                                size_t blocks,
-+                                const void *key,
-+                                const unsigned char ivec[16],
-+                                unsigned char cmac[16]);
-+
-+void aesni_ccm64_decrypt_blocks(const unsigned char *in,
-+                                unsigned char *out,
-+                                size_t blocks,
-+                                const void *key,
-+                                const unsigned char ivec[16],
-+                                unsigned char cmac[16]);
-+
-+# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
-+size_t aesni_gcm_encrypt(const unsigned char *in,
-+                         unsigned char *out,
-+                         size_t len,
-+                         const void *key, unsigned char ivec[16], u64 *Xi);
-+#  define AES_gcm_encrypt aesni_gcm_encrypt
-+size_t aesni_gcm_decrypt(const unsigned char *in,
-+                         unsigned char *out,
-+                         size_t len,
-+                         const void *key, unsigned char ivec[16], u64 *Xi);
-+#  define AES_gcm_decrypt aesni_gcm_decrypt
-+void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in,
-+                   size_t len);
-+#  define AES_GCM_ASM(gctx)       (gctx->ctr==aesni_ctr32_encrypt_blocks && \
-+                                 gctx->gcm.ghash==gcm_ghash_avx)
-+#  define AES_GCM_ASM2(gctx)      (gctx->gcm.block==(block128_f)aesni_encrypt && \
-+                                 gctx->gcm.ghash==gcm_ghash_avx)
-+#  undef AES_GCM_ASM2          /* minor size optimization */
-+# endif
-+
-+static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                          const unsigned char *iv, int enc)
-+{
-+    int ret, mode;
-+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
-+
-+    mode = EVP_CIPHER_CTX_mode(ctx);
-+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
-+        && !enc) {
-+        ret = aesni_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                    &dat->ks.ks);
-+        dat->block = (block128_f) aesni_decrypt;
-+        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+            (cbc128_f) aesni_cbc_encrypt : NULL;
-+    } else {
-+        ret = aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                    &dat->ks.ks);
-+        dat->block = (block128_f) aesni_encrypt;
-+        if (mode == EVP_CIPH_CBC_MODE)
-+            dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt;
-+        else if (mode == EVP_CIPH_CTR_MODE)
-+            dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
-+        else
-+            dat->stream.cbc = NULL;
-+    }
-+
-+    if (ret < 0) {
-+        EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t len)
-+{
-+    aesni_cbc_encrypt(in, out, len, &EVP_C_DATA(EVP_AES_KEY,ctx)->ks.ks,
-+                      EVP_CIPHER_CTX_iv_noconst(ctx),
-+                      EVP_CIPHER_CTX_encrypting(ctx));
-+
-+    return 1;
-+}
-+
-+static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t len)
-+{
-+    size_t bl = EVP_CIPHER_CTX_block_size(ctx);
-+
-+    if (len < bl)
-+        return 1;
-+
-+    aesni_ecb_encrypt(in, out, len, &EVP_C_DATA(EVP_AES_KEY,ctx)->ks.ks,
-+                      EVP_CIPHER_CTX_encrypting(ctx));
-+
-+    return 1;
-+}
-+
-+# define aesni_ofb_cipher aes_ofb_cipher
-+static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t len);
-+
-+# define aesni_cfb_cipher aes_cfb_cipher
-+static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t len);
-+
-+# define aesni_cfb8_cipher aes_cfb8_cipher
-+static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+
-+# define aesni_cfb1_cipher aes_cfb1_cipher
-+static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+
-+# define aesni_ctr_cipher aes_ctr_cipher
-+static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t len);
-+
-+static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                              const unsigned char *iv, int enc)
-+{
-+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+    if (key) {
-+        aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                              &gctx->ks.ks);
-+        CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aesni_encrypt);
-+        gctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
-+        /*
-+         * If we have an iv can set it directly, otherwise use saved IV.
-+         */
-+        if (iv == NULL && gctx->iv_set)
-+            iv = gctx->iv;
-+        if (iv) {
-+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
-+            gctx->iv_set = 1;
-+        }
-+        gctx->key_set = 1;
-+    } else {
-+        /* If key set use IV, otherwise copy */
-+        if (gctx->key_set)
-+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
-+        else
-+            memcpy(gctx->iv, iv, gctx->ivlen);
-+        gctx->iv_set = 1;
-+        gctx->iv_gen = 0;
-+    }
-+    return 1;
-+}
-+
-+# define aesni_gcm_cipher aes_gcm_cipher
-+static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t len);
-+
-+static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                              const unsigned char *iv, int enc)
-+{
-+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+
-+    if (key) {
-+        /* key_len is two AES keys */
-+        if (enc) {
-+            aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                  &xctx->ks1.ks);
-+            xctx->xts.block1 = (block128_f) aesni_encrypt;
-+            xctx->stream = aesni_xts_encrypt;
-+        } else {
-+            aesni_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                  &xctx->ks1.ks);
-+            xctx->xts.block1 = (block128_f) aesni_decrypt;
-+            xctx->stream = aesni_xts_decrypt;
-+        }
-+
-+        aesni_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2,
-+                              EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                              &xctx->ks2.ks);
-+        xctx->xts.block2 = (block128_f) aesni_encrypt;
-+
-+        xctx->xts.key1 = &xctx->ks1;
-+    }
-+
-+    if (iv) {
-+        xctx->xts.key2 = &xctx->ks2;
-+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16);
-+    }
-+
-+    return 1;
-+}
-+
-+# define aesni_xts_cipher aes_xts_cipher
-+static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t len);
-+
-+static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                              const unsigned char *iv, int enc)
-+{
-+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+    if (key) {
-+        aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                              &cctx->ks.ks);
-+        CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
-+                           &cctx->ks, (block128_f) aesni_encrypt);
-+        cctx->str = enc ? (ccm128_f) aesni_ccm64_encrypt_blocks :
-+            (ccm128_f) aesni_ccm64_decrypt_blocks;
-+        cctx->key_set = 1;
-+    }
-+    if (iv) {
-+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L);
-+        cctx->iv_set = 1;
-+    }
-+    return 1;
-+}
-+
-+# define aesni_ccm_cipher aes_ccm_cipher
-+static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t len);
-+
-+# ifndef OPENSSL_NO_OCB
-+void aesni_ocb_encrypt(const unsigned char *in, unsigned char *out,
-+                       size_t blocks, const void *key,
-+                       size_t start_block_num,
-+                       unsigned char offset_i[16],
-+                       const unsigned char L_[][16],
-+                       unsigned char checksum[16]);
-+void aesni_ocb_decrypt(const unsigned char *in, unsigned char *out,
-+                       size_t blocks, const void *key,
-+                       size_t start_block_num,
-+                       unsigned char offset_i[16],
-+                       const unsigned char L_[][16],
-+                       unsigned char checksum[16]);
-+
-+static int aesni_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                              const unsigned char *iv, int enc)
-+{
-+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+    if (key) {
-+        do {
-+            /*
-+             * We set both the encrypt and decrypt key here because decrypt
-+             * needs both. We could possibly optimise to remove setting the
-+             * decrypt for an encryption operation.
-+             */
-+            aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                  &octx->ksenc.ks);
-+            aesni_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                  &octx->ksdec.ks);
-+            if (!CRYPTO_ocb128_init(&octx->ocb,
-+                                    &octx->ksenc.ks, &octx->ksdec.ks,
-+                                    (block128_f) aesni_encrypt,
-+                                    (block128_f) aesni_decrypt,
-+                                    enc ? aesni_ocb_encrypt
-+                                        : aesni_ocb_decrypt))
-+                return 0;
-+        }
-+        while (0);
-+
-+        /*
-+         * If we have an iv we can set it directly, otherwise use saved IV.
-+         */
-+        if (iv == NULL && octx->iv_set)
-+            iv = octx->iv;
-+        if (iv) {
-+            if (CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen)
-+                != 1)
-+                return 0;
-+            octx->iv_set = 1;
-+        }
-+        octx->key_set = 1;
-+    } else {
-+        /* If key set use IV, otherwise copy */
-+        if (octx->key_set)
-+            CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen);
-+        else
-+            memcpy(octx->iv, iv, octx->ivlen);
-+        octx->iv_set = 1;
-+    }
-+    return 1;
-+}
-+
-+#  define aesni_ocb_cipher aes_ocb_cipher
-+static int aesni_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t len);
-+# endif                        /* OPENSSL_NO_OCB */
-+
-+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
-+static const EVP_CIPHER aesni_##keylen##_##mode = { \
-+        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        aesni_init_key,                 \
-+        aesni_##mode##_cipher,          \
-+        NULL,                           \
-+        sizeof(EVP_AES_KEY),            \
-+        NULL,NULL,NULL,NULL }; \
-+static const EVP_CIPHER aes_##keylen##_##mode = { \
-+        nid##_##keylen##_##nmode,blocksize,     \
-+        keylen/8,ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        aes_init_key,                   \
-+        aes_##mode##_cipher,            \
-+        NULL,                           \
-+        sizeof(EVP_AES_KEY),            \
-+        NULL,NULL,NULL,NULL }; \
-+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
-+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
-+
-+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
-+static const EVP_CIPHER aesni_##keylen##_##mode = { \
-+        nid##_##keylen##_##mode,blocksize, \
-+        (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        aesni_##mode##_init_key,        \
-+        aesni_##mode##_cipher,          \
-+        aes_##mode##_cleanup,           \
-+        sizeof(EVP_AES_##MODE##_CTX),   \
-+        NULL,NULL,aes_##mode##_ctrl,NULL }; \
-+static const EVP_CIPHER aes_##keylen##_##mode = { \
-+        nid##_##keylen##_##mode,blocksize, \
-+        (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        aes_##mode##_init_key,          \
-+        aes_##mode##_cipher,            \
-+        aes_##mode##_cleanup,           \
-+        sizeof(EVP_AES_##MODE##_CTX),   \
-+        NULL,NULL,aes_##mode##_ctrl,NULL }; \
-+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
-+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
-+
-+#elif   defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
-+
-+# include "sparc_arch.h"
-+
-+extern unsigned int OPENSSL_sparcv9cap_P[];
-+
-+/*
-+ * Initial Fujitsu SPARC64 X support
-+ */
-+# define HWAES_CAPABLE           (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX)
-+# define HWAES_set_encrypt_key aes_fx_set_encrypt_key
-+# define HWAES_set_decrypt_key aes_fx_set_decrypt_key
-+# define HWAES_encrypt aes_fx_encrypt
-+# define HWAES_decrypt aes_fx_decrypt
-+# define HWAES_cbc_encrypt aes_fx_cbc_encrypt
-+# define HWAES_ctr32_encrypt_blocks aes_fx_ctr32_encrypt_blocks
-+
-+# define SPARC_AES_CAPABLE       (OPENSSL_sparcv9cap_P[1] & CFR_AES)
-+
-+void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
-+void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
-+void aes_t4_encrypt(const unsigned char *in, unsigned char *out,
-+                    const AES_KEY *key);
-+void aes_t4_decrypt(const unsigned char *in, unsigned char *out,
-+                    const AES_KEY *key);
-+/*
-+ * Key-length specific subroutines were chosen for following reason.
-+ * Each SPARC T4 core can execute up to 8 threads which share core's
-+ * resources. Loading as much key material to registers allows to
-+ * minimize references to shared memory interface, as well as amount
-+ * of instructions in inner loops [much needed on T4]. But then having
-+ * non-key-length specific routines would require conditional branches
-+ * either in inner loops or on subroutines' entries. Former is hardly
-+ * acceptable, while latter means code size increase to size occupied
-+ * by multiple key-length specific subroutines, so why fight?
-+ */
-+void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const AES_KEY *key,
-+                           unsigned char *ivec);
-+void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const AES_KEY *key,
-+                           unsigned char *ivec);
-+void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const AES_KEY *key,
-+                           unsigned char *ivec);
-+void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const AES_KEY *key,
-+                           unsigned char *ivec);
-+void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const AES_KEY *key,
-+                           unsigned char *ivec);
-+void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const AES_KEY *key,
-+                           unsigned char *ivec);
-+void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
-+                             size_t blocks, const AES_KEY *key,
-+                             unsigned char *ivec);
-+void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
-+                             size_t blocks, const AES_KEY *key,
-+                             unsigned char *ivec);
-+void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
-+                             size_t blocks, const AES_KEY *key,
-+                             unsigned char *ivec);
-+void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t blocks, const AES_KEY *key1,
-+                           const AES_KEY *key2, const unsigned char *ivec);
-+void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
-+                           size_t blocks, const AES_KEY *key1,
-+                           const AES_KEY *key2, const unsigned char *ivec);
-+void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t blocks, const AES_KEY *key1,
-+                           const AES_KEY *key2, const unsigned char *ivec);
-+void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
-+                           size_t blocks, const AES_KEY *key1,
-+                           const AES_KEY *key2, const unsigned char *ivec);
-+
-+static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                           const unsigned char *iv, int enc)
-+{
-+    int ret, mode, bits;
-+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
-+
-+    mode = EVP_CIPHER_CTX_mode(ctx);
-+    bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
-+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
-+        && !enc) {
-+        ret = 0;
-+        aes_t4_set_decrypt_key(key, bits, &dat->ks.ks);
-+        dat->block = (block128_f) aes_t4_decrypt;
-+        switch (bits) {
-+        case 128:
-+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+                (cbc128_f) aes128_t4_cbc_decrypt : NULL;
-+            break;
-+        case 192:
-+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+                (cbc128_f) aes192_t4_cbc_decrypt : NULL;
-+            break;
-+        case 256:
-+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+                (cbc128_f) aes256_t4_cbc_decrypt : NULL;
-+            break;
-+        default:
-+            ret = -1;
-+        }
-+    } else {
-+        ret = 0;
-+        aes_t4_set_encrypt_key(key, bits, &dat->ks.ks);
-+        dat->block = (block128_f) aes_t4_encrypt;
-+        switch (bits) {
-+        case 128:
-+            if (mode == EVP_CIPH_CBC_MODE)
-+                dat->stream.cbc = (cbc128_f) aes128_t4_cbc_encrypt;
-+            else if (mode == EVP_CIPH_CTR_MODE)
-+                dat->stream.ctr = (ctr128_f) aes128_t4_ctr32_encrypt;
-+            else
-+                dat->stream.cbc = NULL;
-+            break;
-+        case 192:
-+            if (mode == EVP_CIPH_CBC_MODE)
-+                dat->stream.cbc = (cbc128_f) aes192_t4_cbc_encrypt;
-+            else if (mode == EVP_CIPH_CTR_MODE)
-+                dat->stream.ctr = (ctr128_f) aes192_t4_ctr32_encrypt;
-+            else
-+                dat->stream.cbc = NULL;
-+            break;
-+        case 256:
-+            if (mode == EVP_CIPH_CBC_MODE)
-+                dat->stream.cbc = (cbc128_f) aes256_t4_cbc_encrypt;
-+            else if (mode == EVP_CIPH_CTR_MODE)
-+                dat->stream.ctr = (ctr128_f) aes256_t4_ctr32_encrypt;
-+            else
-+                dat->stream.cbc = NULL;
-+            break;
-+        default:
-+            ret = -1;
-+        }
-+    }
-+
-+    if (ret < 0) {
-+        EVPerr(EVP_F_AES_T4_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+# define aes_t4_cbc_cipher aes_cbc_cipher
-+static int aes_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+
-+# define aes_t4_ecb_cipher aes_ecb_cipher
-+static int aes_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+
-+# define aes_t4_ofb_cipher aes_ofb_cipher
-+static int aes_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+
-+# define aes_t4_cfb_cipher aes_cfb_cipher
-+static int aes_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+
-+# define aes_t4_cfb8_cipher aes_cfb8_cipher
-+static int aes_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t len);
-+
-+# define aes_t4_cfb1_cipher aes_cfb1_cipher
-+static int aes_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t len);
-+
-+# define aes_t4_ctr_cipher aes_ctr_cipher
-+static int aes_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+
-+static int aes_t4_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                               const unsigned char *iv, int enc)
-+{
-+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+    if (key) {
-+        int bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
-+        aes_t4_set_encrypt_key(key, bits, &gctx->ks.ks);
-+        CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
-+                           (block128_f) aes_t4_encrypt);
-+        switch (bits) {
-+        case 128:
-+            gctx->ctr = (ctr128_f) aes128_t4_ctr32_encrypt;
-+            break;
-+        case 192:
-+            gctx->ctr = (ctr128_f) aes192_t4_ctr32_encrypt;
-+            break;
-+        case 256:
-+            gctx->ctr = (ctr128_f) aes256_t4_ctr32_encrypt;
-+            break;
-+        default:
-+            return 0;
-+        }
-+        /*
-+         * If we have an iv can set it directly, otherwise use saved IV.
-+         */
-+        if (iv == NULL && gctx->iv_set)
-+            iv = gctx->iv;
-+        if (iv) {
-+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
-+            gctx->iv_set = 1;
-+        }
-+        gctx->key_set = 1;
-+    } else {
-+        /* If key set use IV, otherwise copy */
-+        if (gctx->key_set)
-+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
-+        else
-+            memcpy(gctx->iv, iv, gctx->ivlen);
-+        gctx->iv_set = 1;
-+        gctx->iv_gen = 0;
-+    }
-+    return 1;
-+}
-+
-+# define aes_t4_gcm_cipher aes_gcm_cipher
-+static int aes_t4_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+
-+static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                               const unsigned char *iv, int enc)
-+{
-+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+
-+    if (key) {
-+        int bits = EVP_CIPHER_CTX_key_length(ctx) * 4;
-+        xctx->stream = NULL;
-+        /* key_len is two AES keys */
-+        if (enc) {
-+            aes_t4_set_encrypt_key(key, bits, &xctx->ks1.ks);
-+            xctx->xts.block1 = (block128_f) aes_t4_encrypt;
-+            switch (bits) {
-+            case 128:
-+                xctx->stream = aes128_t4_xts_encrypt;
-+                break;
-+            case 256:
-+                xctx->stream = aes256_t4_xts_encrypt;
-+                break;
-+            default:
-+                return 0;
-+            }
-+        } else {
-+            aes_t4_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                   &xctx->ks1.ks);
-+            xctx->xts.block1 = (block128_f) aes_t4_decrypt;
-+            switch (bits) {
-+            case 128:
-+                xctx->stream = aes128_t4_xts_decrypt;
-+                break;
-+            case 256:
-+                xctx->stream = aes256_t4_xts_decrypt;
-+                break;
-+            default:
-+                return 0;
-+            }
-+        }
-+
-+        aes_t4_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2,
-+                               EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                               &xctx->ks2.ks);
-+        xctx->xts.block2 = (block128_f) aes_t4_encrypt;
-+
-+        xctx->xts.key1 = &xctx->ks1;
-+    }
-+
-+    if (iv) {
-+        xctx->xts.key2 = &xctx->ks2;
-+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16);
-+    }
-+
-+    return 1;
-+}
-+
-+# define aes_t4_xts_cipher aes_xts_cipher
-+static int aes_t4_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+
-+static int aes_t4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                               const unsigned char *iv, int enc)
-+{
-+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+    if (key) {
-+        int bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
-+        aes_t4_set_encrypt_key(key, bits, &cctx->ks.ks);
-+        CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
-+                           &cctx->ks, (block128_f) aes_t4_encrypt);
-+        cctx->str = NULL;
-+        cctx->key_set = 1;
-+    }
-+    if (iv) {
-+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L);
-+        cctx->iv_set = 1;
-+    }
-+    return 1;
-+}
-+
-+# define aes_t4_ccm_cipher aes_ccm_cipher
-+static int aes_t4_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+
-+# ifndef OPENSSL_NO_OCB
-+static int aes_t4_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                               const unsigned char *iv, int enc)
-+{
-+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+    if (key) {
-+        do {
-+            /*
-+             * We set both the encrypt and decrypt key here because decrypt
-+             * needs both. We could possibly optimise to remove setting the
-+             * decrypt for an encryption operation.
-+             */
-+            aes_t4_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                   &octx->ksenc.ks);
-+            aes_t4_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                   &octx->ksdec.ks);
-+            if (!CRYPTO_ocb128_init(&octx->ocb,
-+                                    &octx->ksenc.ks, &octx->ksdec.ks,
-+                                    (block128_f) aes_t4_encrypt,
-+                                    (block128_f) aes_t4_decrypt,
-+                                    NULL))
-+                return 0;
-+        }
-+        while (0);
-+
-+        /*
-+         * If we have an iv we can set it directly, otherwise use saved IV.
-+         */
-+        if (iv == NULL && octx->iv_set)
-+            iv = octx->iv;
-+        if (iv) {
-+            if (CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen)
-+                != 1)
-+                return 0;
-+            octx->iv_set = 1;
-+        }
-+        octx->key_set = 1;
-+    } else {
-+        /* If key set use IV, otherwise copy */
-+        if (octx->key_set)
-+            CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen);
-+        else
-+            memcpy(octx->iv, iv, octx->ivlen);
-+        octx->iv_set = 1;
-+    }
-+    return 1;
-+}
-+
-+#  define aes_t4_ocb_cipher aes_ocb_cipher
-+static int aes_t4_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                             const unsigned char *in, size_t len);
-+# endif                        /* OPENSSL_NO_OCB */
-+
-+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
-+static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
-+        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        aes_t4_init_key,                \
-+        aes_t4_##mode##_cipher,         \
-+        NULL,                           \
-+        sizeof(EVP_AES_KEY),            \
-+        NULL,NULL,NULL,NULL }; \
-+static const EVP_CIPHER aes_##keylen##_##mode = { \
-+        nid##_##keylen##_##nmode,blocksize,     \
-+        keylen/8,ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        aes_init_key,                   \
-+        aes_##mode##_cipher,            \
-+        NULL,                           \
-+        sizeof(EVP_AES_KEY),            \
-+        NULL,NULL,NULL,NULL }; \
-+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
-+{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
-+
-+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
-+static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
-+        nid##_##keylen##_##mode,blocksize, \
-+        (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        aes_t4_##mode##_init_key,       \
-+        aes_t4_##mode##_cipher,         \
-+        aes_##mode##_cleanup,           \
-+        sizeof(EVP_AES_##MODE##_CTX),   \
-+        NULL,NULL,aes_##mode##_ctrl,NULL }; \
-+static const EVP_CIPHER aes_##keylen##_##mode = { \
-+        nid##_##keylen##_##mode,blocksize, \
-+        (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        aes_##mode##_init_key,          \
-+        aes_##mode##_cipher,            \
-+        aes_##mode##_cleanup,           \
-+        sizeof(EVP_AES_##MODE##_CTX),   \
-+        NULL,NULL,aes_##mode##_ctrl,NULL }; \
-+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
-+{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
-+
-+#else
-+
-+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
-+static const EVP_CIPHER aes_##keylen##_##mode = { \
-+        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        aes_init_key,                   \
-+        aes_##mode##_cipher,            \
-+        NULL,                           \
-+        sizeof(EVP_AES_KEY),            \
-+        NULL,NULL,NULL,NULL }; \
-+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
-+{ return &aes_##keylen##_##mode; }
-+
-+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
-+static const EVP_CIPHER aes_##keylen##_##mode = { \
-+        nid##_##keylen##_##mode,blocksize, \
-+        (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        aes_##mode##_init_key,          \
-+        aes_##mode##_cipher,            \
-+        aes_##mode##_cleanup,           \
-+        sizeof(EVP_AES_##MODE##_CTX),   \
-+        NULL,NULL,aes_##mode##_ctrl,NULL }; \
-+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
-+{ return &aes_##keylen##_##mode; }
-+
-+#endif
-+
-+#if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__))
-+# include "arm_arch.h"
-+# if __ARM_MAX_ARCH__>=7
-+#  if defined(BSAES_ASM)
-+#   define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
-+#  endif
-+#  if defined(VPAES_ASM)
-+#   define VPAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
-+#  endif
-+#  define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
-+#  define HWAES_set_encrypt_key aes_v8_set_encrypt_key
-+#  define HWAES_set_decrypt_key aes_v8_set_decrypt_key
-+#  define HWAES_encrypt aes_v8_encrypt
-+#  define HWAES_decrypt aes_v8_decrypt
-+#  define HWAES_cbc_encrypt aes_v8_cbc_encrypt
-+#  define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
-+# endif
-+#endif
-+
-+#if defined(HWAES_CAPABLE)
-+int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
-+                          AES_KEY *key);
-+int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
-+                          AES_KEY *key);
-+void HWAES_encrypt(const unsigned char *in, unsigned char *out,
-+                   const AES_KEY *key);
-+void HWAES_decrypt(const unsigned char *in, unsigned char *out,
-+                   const AES_KEY *key);
-+void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                       size_t length, const AES_KEY *key,
-+                       unsigned char *ivec, const int enc);
-+void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
-+                                size_t len, const AES_KEY *key,
-+                                const unsigned char ivec[16]);
-+void HWAES_xts_encrypt(const unsigned char *inp, unsigned char *out,
-+                       size_t len, const AES_KEY *key1,
-+                       const AES_KEY *key2, const unsigned char iv[16]);
-+void HWAES_xts_decrypt(const unsigned char *inp, unsigned char *out,
-+                       size_t len, const AES_KEY *key1,
-+                       const AES_KEY *key2, const unsigned char iv[16]);
-+#endif
-+
-+#define BLOCK_CIPHER_generic_pack(nid,keylen,flags)             \
-+        BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)     \
-+        BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)      \
-+        BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
-+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
-+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags)       \
-+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)       \
-+        BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
-+
-+static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                        const unsigned char *iv, int enc)
-+{
-+    int ret, mode;
-+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
-+
-+    mode = EVP_CIPHER_CTX_mode(ctx);
-+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
-+        && !enc) {
-+#ifdef HWAES_CAPABLE
-+        if (HWAES_CAPABLE) {
-+            ret = HWAES_set_decrypt_key(key,
-+                                        EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                        &dat->ks.ks);
-+            dat->block = (block128_f) HWAES_decrypt;
-+            dat->stream.cbc = NULL;
-+# ifdef HWAES_cbc_encrypt
-+            if (mode == EVP_CIPH_CBC_MODE)
-+                dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt;
-+# endif
-+        } else
-+#endif
-+#ifdef BSAES_CAPABLE
-+        if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) {
-+            ret = AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                      &dat->ks.ks);
-+            dat->block = (block128_f) AES_decrypt;
-+            dat->stream.cbc = (cbc128_f) bsaes_cbc_encrypt;
-+        } else
-+#endif
-+#ifdef VPAES_CAPABLE
-+        if (VPAES_CAPABLE) {
-+            ret = vpaes_set_decrypt_key(key,
-+                                        EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                        &dat->ks.ks);
-+            dat->block = (block128_f) vpaes_decrypt;
-+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+                (cbc128_f) vpaes_cbc_encrypt : NULL;
-+        } else
-+#endif
-+        {
-+            ret = AES_set_decrypt_key(key,
-+                                      EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                      &dat->ks.ks);
-+            dat->block = (block128_f) AES_decrypt;
-+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+                (cbc128_f) AES_cbc_encrypt : NULL;
-+        }
-+    } else
-+#ifdef HWAES_CAPABLE
-+    if (HWAES_CAPABLE) {
-+        ret = HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                    &dat->ks.ks);
-+        dat->block = (block128_f) HWAES_encrypt;
-+        dat->stream.cbc = NULL;
-+# ifdef HWAES_cbc_encrypt
-+        if (mode == EVP_CIPH_CBC_MODE)
-+            dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt;
-+        else
-+# endif
-+# ifdef HWAES_ctr32_encrypt_blocks
-+        if (mode == EVP_CIPH_CTR_MODE)
-+            dat->stream.ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks;
-+        else
-+# endif
-+            (void)0;            /* terminate potentially open 'else' */
-+    } else
-+#endif
-+#ifdef BSAES_CAPABLE
-+    if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) {
-+        ret = AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                  &dat->ks.ks);
-+        dat->block = (block128_f) AES_encrypt;
-+        dat->stream.ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks;
-+    } else
-+#endif
-+#ifdef VPAES_CAPABLE
-+    if (VPAES_CAPABLE) {
-+        ret = vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                    &dat->ks.ks);
-+        dat->block = (block128_f) vpaes_encrypt;
-+        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+            (cbc128_f) vpaes_cbc_encrypt : NULL;
-+    } else
-+#endif
-+    {
-+        ret = AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                  &dat->ks.ks);
-+        dat->block = (block128_f) AES_encrypt;
-+        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+            (cbc128_f) AES_cbc_encrypt : NULL;
-+#ifdef AES_CTR_ASM
-+        if (mode == EVP_CIPH_CTR_MODE)
-+            dat->stream.ctr = (ctr128_f) AES_ctr32_encrypt;
-+#endif
-+    }
-+
-+    if (ret < 0) {
-+        EVPerr(EVP_F_AES_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t len)
-+{
-+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
-+
-+    if (dat->stream.cbc)
-+        (*dat->stream.cbc) (in, out, len, &dat->ks,
-+                            EVP_CIPHER_CTX_iv_noconst(ctx),
-+                            EVP_CIPHER_CTX_encrypting(ctx));
-+    else if (EVP_CIPHER_CTX_encrypting(ctx))
-+        CRYPTO_cbc128_encrypt(in, out, len, &dat->ks,
-+                              EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
-+    else
-+        CRYPTO_cbc128_decrypt(in, out, len, &dat->ks,
-+                              EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
-+
-+    return 1;
-+}
-+
-+static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t len)
-+{
-+    size_t bl = EVP_CIPHER_CTX_block_size(ctx);
-+    size_t i;
-+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
-+
-+    if (len < bl)
-+        return 1;
-+
-+    for (i = 0, len -= bl; i <= len; i += bl)
-+        (*dat->block) (in + i, out + i, &dat->ks);
-+
-+    return 1;
-+}
-+
-+static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t len)
-+{
-+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
-+
-+    int num = EVP_CIPHER_CTX_num(ctx);
-+    CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
-+                          EVP_CIPHER_CTX_iv_noconst(ctx), &num, dat->block);
-+    EVP_CIPHER_CTX_set_num(ctx, num);
-+    return 1;
-+}
-+
-+static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t len)
-+{
-+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
-+
-+    int num = EVP_CIPHER_CTX_num(ctx);
-+    CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
-+                          EVP_CIPHER_CTX_iv_noconst(ctx), &num,
-+                          EVP_CIPHER_CTX_encrypting(ctx), dat->block);
-+    EVP_CIPHER_CTX_set_num(ctx, num);
-+    return 1;
-+}
-+
-+static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                           const unsigned char *in, size_t len)
-+{
-+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
-+
-+    int num = EVP_CIPHER_CTX_num(ctx);
-+    CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
-+                            EVP_CIPHER_CTX_iv_noconst(ctx), &num,
-+                            EVP_CIPHER_CTX_encrypting(ctx), dat->block);
-+    EVP_CIPHER_CTX_set_num(ctx, num);
-+    return 1;
-+}
-+
-+static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                           const unsigned char *in, size_t len)
-+{
-+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
-+
-+    if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
-+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num,
-+                                EVP_CIPHER_CTX_encrypting(ctx), dat->block);
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+        return 1;
-+    }
-+
-+    while (len >= MAXBITCHUNK) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
-+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num,
-+                                EVP_CIPHER_CTX_encrypting(ctx), dat->block);
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+        len -= MAXBITCHUNK;
-+    }
-+    if (len) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
-+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num,
-+                                EVP_CIPHER_CTX_encrypting(ctx), dat->block);
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+    }
-+
-+    return 1;
-+}
-+
-+static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t len)
-+{
-+    unsigned int num = EVP_CIPHER_CTX_num(ctx);
-+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
-+
-+    if (dat->stream.ctr)
-+        CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
-+                                    EVP_CIPHER_CTX_iv_noconst(ctx),
-+                                    EVP_CIPHER_CTX_buf_noconst(ctx),
-+                                    &num, dat->stream.ctr);
-+    else
-+        CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
-+                              EVP_CIPHER_CTX_iv_noconst(ctx),
-+                              EVP_CIPHER_CTX_buf_noconst(ctx), &num,
-+                              dat->block);
-+    EVP_CIPHER_CTX_set_num(ctx, num);
-+    return 1;
-+}
-+
-+BLOCK_CIPHER_generic_pack(NID_aes, 128, 0)
-+    BLOCK_CIPHER_generic_pack(NID_aes, 192, 0)
-+    BLOCK_CIPHER_generic_pack(NID_aes, 256, 0)
-+
-+static int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
-+{
-+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,c);
-+    if (gctx == NULL)
-+        return 0;
-+    OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
-+    if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c))
-+        OPENSSL_free(gctx->iv);
-+    return 1;
-+}
-+
-+/* increment counter (64-bit int) by 1 */
-+static void ctr64_inc(unsigned char *counter)
-+{
-+    int n = 8;
-+    unsigned char c;
-+
-+    do {
-+        --n;
-+        c = counter[n];
-+        ++c;
-+        counter[n] = c;
-+        if (c)
-+            return;
-+    } while (n);
-+}
-+
-+static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
-+{
-+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,c);
-+    switch (type) {
-+    case EVP_CTRL_INIT:
-+        gctx->key_set = 0;
-+        gctx->iv_set = 0;
-+        gctx->ivlen = EVP_CIPHER_CTX_iv_length(c);
-+        gctx->iv = EVP_CIPHER_CTX_iv_noconst(c);
-+        gctx->taglen = -1;
-+        gctx->iv_gen = 0;
-+        gctx->tls_aad_len = -1;
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_SET_IVLEN:
-+        if (arg <= 0)
-+            return 0;
-+        /* Allocate memory for IV if needed */
-+        if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) {
-+            if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c))
-+                OPENSSL_free(gctx->iv);
-+            gctx->iv = OPENSSL_malloc(arg);
-+            if (gctx->iv == NULL)
-+                return 0;
-+        }
-+        gctx->ivlen = arg;
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_SET_TAG:
-+        if (arg <= 0 || arg > 16 || EVP_CIPHER_CTX_encrypting(c))
-+            return 0;
-+        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
-+        gctx->taglen = arg;
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_GET_TAG:
-+        if (arg <= 0 || arg > 16 || !EVP_CIPHER_CTX_encrypting(c)
-+            || gctx->taglen < 0)
-+            return 0;
-+        memcpy(ptr, EVP_CIPHER_CTX_buf_noconst(c), arg);
-+        return 1;
-+
-+    case EVP_CTRL_GCM_SET_IV_FIXED:
-+        /* Special case: -1 length restores whole IV */
-+        if (arg == -1) {
-+            memcpy(gctx->iv, ptr, gctx->ivlen);
-+            gctx->iv_gen = 1;
-+            return 1;
-+        }
-+        /*
-+         * Fixed field must be at least 4 bytes and invocation field at least
-+         * 8.
-+         */
-+        if ((arg < 4) || (gctx->ivlen - arg) < 8)
-+            return 0;
-+        if (arg)
-+            memcpy(gctx->iv, ptr, arg);
-+        if (EVP_CIPHER_CTX_encrypting(c)
-+            && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
-+            return 0;
-+        gctx->iv_gen = 1;
-+        return 1;
-+
-+    case EVP_CTRL_GCM_IV_GEN:
-+        if (gctx->iv_gen == 0 || gctx->key_set == 0)
-+            return 0;
-+        CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
-+        if (arg <= 0 || arg > gctx->ivlen)
-+            arg = gctx->ivlen;
-+        memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
-+        /*
-+         * Invocation field will be at least 8 bytes in size and so no need
-+         * to check wrap around or increment more than last 8 bytes.
-+         */
-+        ctr64_inc(gctx->iv + gctx->ivlen - 8);
-+        gctx->iv_set = 1;
-+        return 1;
-+
-+    case EVP_CTRL_GCM_SET_IV_INV:
-+        if (gctx->iv_gen == 0 || gctx->key_set == 0
-+            || EVP_CIPHER_CTX_encrypting(c))
-+            return 0;
-+        memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
-+        CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
-+        gctx->iv_set = 1;
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_TLS1_AAD:
-+        /* Save the AAD for later use */
-+        if (arg != EVP_AEAD_TLS1_AAD_LEN)
-+            return 0;
-+        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
-+        gctx->tls_aad_len = arg;
-+        {
-+            unsigned int len =
-+                EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
-+                | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
-+            /* Correct length for explicit IV */
-+            if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN)
-+                return 0;
-+            len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
-+            /* If decrypting correct for tag too */
-+            if (!EVP_CIPHER_CTX_encrypting(c)) {
-+                if (len < EVP_GCM_TLS_TAG_LEN)
-+                    return 0;
-+                len -= EVP_GCM_TLS_TAG_LEN;
-+            }
-+            EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
-+            EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
-+        }
-+        /* Extra padding: tag appended to record */
-+        return EVP_GCM_TLS_TAG_LEN;
-+
-+    case EVP_CTRL_COPY:
-+        {
-+            EVP_CIPHER_CTX *out = ptr;
-+            EVP_AES_GCM_CTX *gctx_out = EVP_C_DATA(EVP_AES_GCM_CTX,out);
-+            if (gctx->gcm.key) {
-+                if (gctx->gcm.key != &gctx->ks)
-+                    return 0;
-+                gctx_out->gcm.key = &gctx_out->ks;
-+            }
-+            if (gctx->iv == EVP_CIPHER_CTX_iv_noconst(c))
-+                gctx_out->iv = EVP_CIPHER_CTX_iv_noconst(out);
-+            else {
-+                gctx_out->iv = OPENSSL_malloc(gctx->ivlen);
-+                if (gctx_out->iv == NULL)
-+                    return 0;
-+                memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
-+            }
-+            return 1;
-+        }
-+
-+    default:
-+        return -1;
-+
-+    }
-+}
-+
-+static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                            const unsigned char *iv, int enc)
-+{
-+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+    if (key) {
-+        do {
-+#ifdef HWAES_CAPABLE
-+            if (HWAES_CAPABLE) {
-+                HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                      &gctx->ks.ks);
-+                CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
-+                                   (block128_f) HWAES_encrypt);
-+# ifdef HWAES_ctr32_encrypt_blocks
-+                gctx->ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks;
-+# else
-+                gctx->ctr = NULL;
-+# endif
-+                break;
-+            } else
-+#endif
-+#ifdef BSAES_CAPABLE
-+            if (BSAES_CAPABLE) {
-+                AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                    &gctx->ks.ks);
-+                CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
-+                                   (block128_f) AES_encrypt);
-+                gctx->ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks;
-+                break;
-+            } else
-+#endif
-+#ifdef VPAES_CAPABLE
-+            if (VPAES_CAPABLE) {
-+                vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                      &gctx->ks.ks);
-+                CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
-+                                   (block128_f) vpaes_encrypt);
-+                gctx->ctr = NULL;
-+                break;
-+            } else
-+#endif
-+                (void)0;        /* terminate potentially open 'else' */
-+
-+            AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                &gctx->ks.ks);
-+            CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
-+                               (block128_f) AES_encrypt);
-+#ifdef AES_CTR_ASM
-+            gctx->ctr = (ctr128_f) AES_ctr32_encrypt;
-+#else
-+            gctx->ctr = NULL;
-+#endif
-+        } while (0);
-+
-+        /*
-+         * If we have an iv can set it directly, otherwise use saved IV.
-+         */
-+        if (iv == NULL && gctx->iv_set)
-+            iv = gctx->iv;
-+        if (iv) {
-+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
-+            gctx->iv_set = 1;
-+        }
-+        gctx->key_set = 1;
-+    } else {
-+        /* If key set use IV, otherwise copy */
-+        if (gctx->key_set)
-+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
-+        else
-+            memcpy(gctx->iv, iv, gctx->ivlen);
-+        gctx->iv_set = 1;
-+        gctx->iv_gen = 0;
-+    }
-+    return 1;
-+}
-+
-+/*
-+ * Handle TLS GCM packet format. This consists of the last portion of the IV
-+ * followed by the payload and finally the tag. On encrypt generate IV,
-+ * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
-+ * and verify tag.
-+ */
-+
-+static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t len)
-+{
-+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx);
-+    int rv = -1;
-+    /* Encrypt/decrypt must be performed in place */
-+    if (out != in
-+        || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN))
-+        return -1;
-+    /*
-+     * Set IV from start of buffer or generate IV and write to start of
-+     * buffer.
-+     */
-+    if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CIPHER_CTX_encrypting(ctx) ?
-+                            EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
-+                            EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
-+        goto err;
-+    /* Use saved AAD */
-+    if (CRYPTO_gcm128_aad(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx),
-+                          gctx->tls_aad_len))
-+        goto err;
-+    /* Fix buffer and length to point to payload */
-+    in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
-+    out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
-+    len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
-+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+        /* Encrypt payload */
-+        if (gctx->ctr) {
-+            size_t bulk = 0;
-+#if defined(AES_GCM_ASM)
-+            if (len >= 32 && AES_GCM_ASM(gctx)) {
-+                if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0))
-+                    return -1;
-+
-+                bulk = AES_gcm_encrypt(in, out, len,
-+                                       gctx->gcm.key,
-+                                       gctx->gcm.Yi.c, gctx->gcm.Xi.u);
-+                gctx->gcm.len.u[1] += bulk;
-+            }
-+#endif
-+            if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
-+                                            in + bulk,
-+                                            out + bulk,
-+                                            len - bulk, gctx->ctr))
-+                goto err;
-+        } else {
-+            size_t bulk = 0;
-+#if defined(AES_GCM_ASM2)
-+            if (len >= 32 && AES_GCM_ASM2(gctx)) {
-+                if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0))
-+                    return -1;
-+
-+                bulk = AES_gcm_encrypt(in, out, len,
-+                                       gctx->gcm.key,
-+                                       gctx->gcm.Yi.c, gctx->gcm.Xi.u);
-+                gctx->gcm.len.u[1] += bulk;
-+            }
-+#endif
-+            if (CRYPTO_gcm128_encrypt(&gctx->gcm,
-+                                      in + bulk, out + bulk, len - bulk))
-+                goto err;
-+        }
-+        out += len;
-+        /* Finally write tag */
-+        CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
-+        rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
-+    } else {
-+        /* Decrypt */
-+        if (gctx->ctr) {
-+            size_t bulk = 0;
-+#if defined(AES_GCM_ASM)
-+            if (len >= 16 && AES_GCM_ASM(gctx)) {
-+                if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0))
-+                    return -1;
-+
-+                bulk = AES_gcm_decrypt(in, out, len,
-+                                       gctx->gcm.key,
-+                                       gctx->gcm.Yi.c, gctx->gcm.Xi.u);
-+                gctx->gcm.len.u[1] += bulk;
-+            }
-+#endif
-+            if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
-+                                            in + bulk,
-+                                            out + bulk,
-+                                            len - bulk, gctx->ctr))
-+                goto err;
-+        } else {
-+            size_t bulk = 0;
-+#if defined(AES_GCM_ASM2)
-+            if (len >= 16 && AES_GCM_ASM2(gctx)) {
-+                if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0))
-+                    return -1;
-+
-+                bulk = AES_gcm_decrypt(in, out, len,
-+                                       gctx->gcm.key,
-+                                       gctx->gcm.Yi.c, gctx->gcm.Xi.u);
-+                gctx->gcm.len.u[1] += bulk;
-+            }
-+#endif
-+            if (CRYPTO_gcm128_decrypt(&gctx->gcm,
-+                                      in + bulk, out + bulk, len - bulk))
-+                goto err;
-+        }
-+        /* Retrieve tag */
-+        CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx),
-+                          EVP_GCM_TLS_TAG_LEN);
-+        /* If tag mismatch wipe buffer */
-+        if (CRYPTO_memcmp(EVP_CIPHER_CTX_buf_noconst(ctx), in + len,
-+                          EVP_GCM_TLS_TAG_LEN)) {
-+            OPENSSL_cleanse(out, len);
-+            goto err;
-+        }
-+        rv = len;
-+    }
-+
-+ err:
-+    gctx->iv_set = 0;
-+    gctx->tls_aad_len = -1;
-+    return rv;
-+}
-+
-+static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t len)
-+{
-+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx);
-+    /* If not set up, return error */
-+    if (!gctx->key_set)
-+        return -1;
-+
-+    if (gctx->tls_aad_len >= 0)
-+        return aes_gcm_tls_cipher(ctx, out, in, len);
-+
-+    if (!gctx->iv_set)
-+        return -1;
-+    if (in) {
-+        if (out == NULL) {
-+            if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
-+                return -1;
-+        } else if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+            if (gctx->ctr) {
-+                size_t bulk = 0;
-+#if defined(AES_GCM_ASM)
-+                if (len >= 32 && AES_GCM_ASM(gctx)) {
-+                    size_t res = (16 - gctx->gcm.mres) % 16;
-+
-+                    if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res))
-+                        return -1;
-+
-+                    bulk = AES_gcm_encrypt(in + res,
-+                                           out + res, len - res,
-+                                           gctx->gcm.key, gctx->gcm.Yi.c,
-+                                           gctx->gcm.Xi.u);
-+                    gctx->gcm.len.u[1] += bulk;
-+                    bulk += res;
-+                }
-+#endif
-+                if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
-+                                                in + bulk,
-+                                                out + bulk,
-+                                                len - bulk, gctx->ctr))
-+                    return -1;
-+            } else {
-+                size_t bulk = 0;
-+#if defined(AES_GCM_ASM2)
-+                if (len >= 32 && AES_GCM_ASM2(gctx)) {
-+                    size_t res = (16 - gctx->gcm.mres) % 16;
-+
-+                    if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res))
-+                        return -1;
-+
-+                    bulk = AES_gcm_encrypt(in + res,
-+                                           out + res, len - res,
-+                                           gctx->gcm.key, gctx->gcm.Yi.c,
-+                                           gctx->gcm.Xi.u);
-+                    gctx->gcm.len.u[1] += bulk;
-+                    bulk += res;
-+                }
-+#endif
-+                if (CRYPTO_gcm128_encrypt(&gctx->gcm,
-+                                          in + bulk, out + bulk, len - bulk))
-+                    return -1;
-+            }
-+        } else {
-+            if (gctx->ctr) {
-+                size_t bulk = 0;
-+#if defined(AES_GCM_ASM)
-+                if (len >= 16 && AES_GCM_ASM(gctx)) {
-+                    size_t res = (16 - gctx->gcm.mres) % 16;
-+
-+                    if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res))
-+                        return -1;
-+
-+                    bulk = AES_gcm_decrypt(in + res,
-+                                           out + res, len - res,
-+                                           gctx->gcm.key,
-+                                           gctx->gcm.Yi.c, gctx->gcm.Xi.u);
-+                    gctx->gcm.len.u[1] += bulk;
-+                    bulk += res;
-+                }
-+#endif
-+                if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
-+                                                in + bulk,
-+                                                out + bulk,
-+                                                len - bulk, gctx->ctr))
-+                    return -1;
-+            } else {
-+                size_t bulk = 0;
-+#if defined(AES_GCM_ASM2)
-+                if (len >= 16 && AES_GCM_ASM2(gctx)) {
-+                    size_t res = (16 - gctx->gcm.mres) % 16;
-+
-+                    if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res))
-+                        return -1;
-+
-+                    bulk = AES_gcm_decrypt(in + res,
-+                                           out + res, len - res,
-+                                           gctx->gcm.key,
-+                                           gctx->gcm.Yi.c, gctx->gcm.Xi.u);
-+                    gctx->gcm.len.u[1] += bulk;
-+                    bulk += res;
-+                }
-+#endif
-+                if (CRYPTO_gcm128_decrypt(&gctx->gcm,
-+                                          in + bulk, out + bulk, len - bulk))
-+                    return -1;
-+            }
-+        }
-+        return len;
-+    } else {
-+        if (!EVP_CIPHER_CTX_encrypting(ctx)) {
-+            if (gctx->taglen < 0)
-+                return -1;
-+            if (CRYPTO_gcm128_finish(&gctx->gcm,
-+                                     EVP_CIPHER_CTX_buf_noconst(ctx),
-+                                     gctx->taglen) != 0)
-+                return -1;
-+            gctx->iv_set = 0;
-+            return 0;
-+        }
-+        CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 16);
-+        gctx->taglen = 16;
-+        /* Don't reuse the IV */
-+        gctx->iv_set = 0;
-+        return 0;
-+    }
-+
-+}
-+
-+#define CUSTOM_FLAGS    (EVP_CIPH_FLAG_DEFAULT_ASN1 \
-+                | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
-+                | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
-+                | EVP_CIPH_CUSTOM_COPY)
-+
-+BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM,
-+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
-+    BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, gcm, GCM,
-+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
-+    BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, gcm, GCM,
-+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
-+
-+static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
-+{
-+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,c);
-+    if (type == EVP_CTRL_COPY) {
-+        EVP_CIPHER_CTX *out = ptr;
-+        EVP_AES_XTS_CTX *xctx_out = EVP_C_DATA(EVP_AES_XTS_CTX,out);
-+        if (xctx->xts.key1) {
-+            if (xctx->xts.key1 != &xctx->ks1)
-+                return 0;
-+            xctx_out->xts.key1 = &xctx_out->ks1;
-+        }
-+        if (xctx->xts.key2) {
-+            if (xctx->xts.key2 != &xctx->ks2)
-+                return 0;
-+            xctx_out->xts.key2 = &xctx_out->ks2;
-+        }
-+        return 1;
-+    } else if (type != EVP_CTRL_INIT)
-+        return -1;
-+    /* key1 and key2 are used as an indicator both key and IV are set */
-+    xctx->xts.key1 = NULL;
-+    xctx->xts.key2 = NULL;
-+    return 1;
-+}
-+
-+static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                            const unsigned char *iv, int enc)
-+{
-+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+
-+    if (key)
-+        do {
-+#ifdef AES_XTS_ASM
-+            xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
-+#else
-+            xctx->stream = NULL;
-+#endif
-+            /* key_len is two AES keys */
-+#ifdef HWAES_CAPABLE
-+            if (HWAES_CAPABLE) {
-+                if (enc) {
-+                    HWAES_set_encrypt_key(key,
-+                                          EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                          &xctx->ks1.ks);
-+                    xctx->xts.block1 = (block128_f) HWAES_encrypt;
-+# ifdef HWAES_xts_encrypt
-+                    xctx->stream = HWAES_xts_encrypt;
-+# endif
-+                } else {
-+                    HWAES_set_decrypt_key(key,
-+                                          EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                          &xctx->ks1.ks);
-+                    xctx->xts.block1 = (block128_f) HWAES_decrypt;
-+# ifdef HWAES_xts_decrypt
-+                    xctx->stream = HWAES_xts_decrypt;
-+#endif
-+                }
-+
-+                HWAES_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2,
-+                                      EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                      &xctx->ks2.ks);
-+                xctx->xts.block2 = (block128_f) HWAES_encrypt;
-+
-+                xctx->xts.key1 = &xctx->ks1;
-+                break;
-+            } else
-+#endif
-+#ifdef BSAES_CAPABLE
-+            if (BSAES_CAPABLE)
-+                xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt;
-+            else
-+#endif
-+#ifdef VPAES_CAPABLE
-+            if (VPAES_CAPABLE) {
-+                if (enc) {
-+                    vpaes_set_encrypt_key(key,
-+                                          EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                          &xctx->ks1.ks);
-+                    xctx->xts.block1 = (block128_f) vpaes_encrypt;
-+                } else {
-+                    vpaes_set_decrypt_key(key,
-+                                          EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                          &xctx->ks1.ks);
-+                    xctx->xts.block1 = (block128_f) vpaes_decrypt;
-+                }
-+
-+                vpaes_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2,
-+                                      EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                      &xctx->ks2.ks);
-+                xctx->xts.block2 = (block128_f) vpaes_encrypt;
-+
-+                xctx->xts.key1 = &xctx->ks1;
-+                break;
-+            } else
-+#endif
-+                (void)0;        /* terminate potentially open 'else' */
-+
-+            if (enc) {
-+                AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                    &xctx->ks1.ks);
-+                xctx->xts.block1 = (block128_f) AES_encrypt;
-+            } else {
-+                AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                    &xctx->ks1.ks);
-+                xctx->xts.block1 = (block128_f) AES_decrypt;
-+            }
-+
-+            AES_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2,
-+                                EVP_CIPHER_CTX_key_length(ctx) * 4,
-+                                &xctx->ks2.ks);
-+            xctx->xts.block2 = (block128_f) AES_encrypt;
-+
-+            xctx->xts.key1 = &xctx->ks1;
-+        } while (0);
-+
-+    if (iv) {
-+        xctx->xts.key2 = &xctx->ks2;
-+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16);
-+    }
-+
-+    return 1;
-+}
-+
-+static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t len)
-+{
-+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
-+    if (!xctx->xts.key1 || !xctx->xts.key2)
-+        return 0;
-+    if (!out || !in || len < AES_BLOCK_SIZE)
-+        return 0;
-+    if (xctx->stream)
-+        (*xctx->stream) (in, out, len,
-+                         xctx->xts.key1, xctx->xts.key2,
-+                         EVP_CIPHER_CTX_iv_noconst(ctx));
-+    else if (CRYPTO_xts128_encrypt(&xctx->xts, EVP_CIPHER_CTX_iv_noconst(ctx),
-+                                   in, out, len,
-+                                   EVP_CIPHER_CTX_encrypting(ctx)))
-+        return 0;
-+    return 1;
-+}
-+
-+#define aes_xts_cleanup NULL
-+
-+#define XTS_FLAGS       (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
-+                         | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
-+                         | EVP_CIPH_CUSTOM_COPY)
-+
-+BLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS, XTS_FLAGS)
-+    BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS, XTS_FLAGS)
-+
-+static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
-+{
-+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,c);
-+    switch (type) {
-+    case EVP_CTRL_INIT:
-+        cctx->key_set = 0;
-+        cctx->iv_set = 0;
-+        cctx->L = 8;
-+        cctx->M = 12;
-+        cctx->tag_set = 0;
-+        cctx->len_set = 0;
-+        cctx->tls_aad_len = -1;
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_TLS1_AAD:
-+        /* Save the AAD for later use */
-+        if (arg != EVP_AEAD_TLS1_AAD_LEN)
-+            return 0;
-+        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
-+        cctx->tls_aad_len = arg;
-+        {
-+            uint16_t len =
-+                EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
-+                | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
-+            /* Correct length for explicit IV */
-+            if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN)
-+                return 0;
-+            len -= EVP_CCM_TLS_EXPLICIT_IV_LEN;
-+            /* If decrypting correct for tag too */
-+            if (!EVP_CIPHER_CTX_encrypting(c)) {
-+                if (len < cctx->M)
-+                    return 0;
-+                len -= cctx->M;
-+            }
-+            EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
-+            EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
-+        }
-+        /* Extra padding: tag appended to record */
-+        return cctx->M;
-+
-+    case EVP_CTRL_CCM_SET_IV_FIXED:
-+        /* Sanity check length */
-+        if (arg != EVP_CCM_TLS_FIXED_IV_LEN)
-+            return 0;
-+        /* Just copy to first part of IV */
-+        memcpy(EVP_CIPHER_CTX_iv_noconst(c), ptr, arg);
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_SET_IVLEN:
-+        arg = 15 - arg;
-+    case EVP_CTRL_CCM_SET_L:
-+        if (arg < 2 || arg > 8)
-+            return 0;
-+        cctx->L = arg;
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_SET_TAG:
-+        if ((arg & 1) || arg < 4 || arg > 16)
-+            return 0;
-+        if (EVP_CIPHER_CTX_encrypting(c) && ptr)
-+            return 0;
-+        if (ptr) {
-+            cctx->tag_set = 1;
-+            memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
-+        }
-+        cctx->M = arg;
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_GET_TAG:
-+        if (!EVP_CIPHER_CTX_encrypting(c) || !cctx->tag_set)
-+            return 0;
-+        if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
-+            return 0;
-+        cctx->tag_set = 0;
-+        cctx->iv_set = 0;
-+        cctx->len_set = 0;
-+        return 1;
-+
-+    case EVP_CTRL_COPY:
-+        {
-+            EVP_CIPHER_CTX *out = ptr;
-+            EVP_AES_CCM_CTX *cctx_out = EVP_C_DATA(EVP_AES_CCM_CTX,out);
-+            if (cctx->ccm.key) {
-+                if (cctx->ccm.key != &cctx->ks)
-+                    return 0;
-+                cctx_out->ccm.key = &cctx_out->ks;
-+            }
-+            return 1;
-+        }
-+
-+    default:
-+        return -1;
-+
-+    }
-+}
-+
-+static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                            const unsigned char *iv, int enc)
-+{
-+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+    if (key)
-+        do {
-+#ifdef HWAES_CAPABLE
-+            if (HWAES_CAPABLE) {
-+                HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                      &cctx->ks.ks);
-+
-+                CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
-+                                   &cctx->ks, (block128_f) HWAES_encrypt);
-+                cctx->str = NULL;
-+                cctx->key_set = 1;
-+                break;
-+            } else
-+#endif
-+#ifdef VPAES_CAPABLE
-+            if (VPAES_CAPABLE) {
-+                vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                      &cctx->ks.ks);
-+                CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
-+                                   &cctx->ks, (block128_f) vpaes_encrypt);
-+                cctx->str = NULL;
-+                cctx->key_set = 1;
-+                break;
-+            }
-+#endif
-+            AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                &cctx->ks.ks);
-+            CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
-+                               &cctx->ks, (block128_f) AES_encrypt);
-+            cctx->str = NULL;
-+            cctx->key_set = 1;
-+        } while (0);
-+    if (iv) {
-+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L);
-+        cctx->iv_set = 1;
-+    }
-+    return 1;
-+}
-+
-+static int aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t len)
-+{
-+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,ctx);
-+    CCM128_CONTEXT *ccm = &cctx->ccm;
-+    /* Encrypt/decrypt must be performed in place */
-+    if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M))
-+        return -1;
-+    /* If encrypting set explicit IV from sequence number (start of AAD) */
-+    if (EVP_CIPHER_CTX_encrypting(ctx))
-+        memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx),
-+               EVP_CCM_TLS_EXPLICIT_IV_LEN);
-+    /* Get rest of IV from explicit IV */
-+    memcpy(EVP_CIPHER_CTX_iv_noconst(ctx) + EVP_CCM_TLS_FIXED_IV_LEN, in,
-+           EVP_CCM_TLS_EXPLICIT_IV_LEN);
-+    /* Correct length value */
-+    len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M;
-+    if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), 15 - cctx->L,
-+                            len))
-+            return -1;
-+    /* Use saved AAD */
-+    CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), cctx->tls_aad_len);
-+    /* Fix buffer to point to payload */
-+    in += EVP_CCM_TLS_EXPLICIT_IV_LEN;
-+    out += EVP_CCM_TLS_EXPLICIT_IV_LEN;
-+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+        if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
-+                                                    cctx->str) :
-+            CRYPTO_ccm128_encrypt(ccm, in, out, len))
-+            return -1;
-+        if (!CRYPTO_ccm128_tag(ccm, out + len, cctx->M))
-+            return -1;
-+        return len + EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M;
-+    } else {
-+        if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
-+                                                     cctx->str) :
-+            !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
-+            unsigned char tag[16];
-+            if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
-+                if (!CRYPTO_memcmp(tag, in + len, cctx->M))
-+                    return len;
-+            }
-+        }
-+        OPENSSL_cleanse(out, len);
-+        return -1;
-+    }
-+}
-+
-+static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t len)
-+{
-+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,ctx);
-+    CCM128_CONTEXT *ccm = &cctx->ccm;
-+    /* If not set up, return error */
-+    if (!cctx->key_set)
-+        return -1;
-+
-+    if (cctx->tls_aad_len >= 0)
-+        return aes_ccm_tls_cipher(ctx, out, in, len);
-+
-+    if (!cctx->iv_set)
-+        return -1;
-+
-+    if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
-+        return -1;
-+    if (!out) {
-+        if (!in) {
-+            if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
-+                                    15 - cctx->L, len))
-+                return -1;
-+            cctx->len_set = 1;
-+            return len;
-+        }
-+        /* If have AAD need message length */
-+        if (!cctx->len_set && len)
-+            return -1;
-+        CRYPTO_ccm128_aad(ccm, in, len);
-+        return len;
-+    }
-+    /* EVP_*Final() doesn't return any data */
-+    if (!in)
-+        return 0;
-+    /* If not set length yet do it */
-+    if (!cctx->len_set) {
-+        if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
-+                                15 - cctx->L, len))
-+            return -1;
-+        cctx->len_set = 1;
-+    }
-+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+        if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
-+                                                    cctx->str) :
-+            CRYPTO_ccm128_encrypt(ccm, in, out, len))
-+            return -1;
-+        cctx->tag_set = 1;
-+        return len;
-+    } else {
-+        int rv = -1;
-+        if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
-+                                                     cctx->str) :
-+            !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
-+            unsigned char tag[16];
-+            if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
-+                if (!CRYPTO_memcmp(tag, EVP_CIPHER_CTX_buf_noconst(ctx),
-+                                   cctx->M))
-+                    rv = len;
-+            }
-+        }
-+        if (rv == -1)
-+            OPENSSL_cleanse(out, len);
-+        cctx->iv_set = 0;
-+        cctx->tag_set = 0;
-+        cctx->len_set = 0;
-+        return rv;
-+    }
-+}
-+
-+#define aes_ccm_cleanup NULL
-+
-+BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM,
-+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
-+    BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM,
-+                        EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
-+    BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM,
-+                        EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
-+
-+typedef struct {
-+    union {
-+        double align;
-+        AES_KEY ks;
-+    } ks;
-+    /* Indicates if IV has been set */
-+    unsigned char *iv;
-+} EVP_AES_WRAP_CTX;
-+
-+static int aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                             const unsigned char *iv, int enc)
-+{
-+    EVP_AES_WRAP_CTX *wctx = EVP_C_DATA(EVP_AES_WRAP_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+    if (key) {
-+        if (EVP_CIPHER_CTX_encrypting(ctx))
-+            AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                &wctx->ks.ks);
-+        else
-+            AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                &wctx->ks.ks);
-+        if (!iv)
-+            wctx->iv = NULL;
-+    }
-+    if (iv) {
-+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, EVP_CIPHER_CTX_iv_length(ctx));
-+        wctx->iv = EVP_CIPHER_CTX_iv_noconst(ctx);
-+    }
-+    return 1;
-+}
-+
-+static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                           const unsigned char *in, size_t inlen)
-+{
-+    EVP_AES_WRAP_CTX *wctx = EVP_C_DATA(EVP_AES_WRAP_CTX,ctx);
-+    size_t rv;
-+    /* AES wrap with padding has IV length of 4, without padding 8 */
-+    int pad = EVP_CIPHER_CTX_iv_length(ctx) == 4;
-+    /* No final operation so always return zero length */
-+    if (!in)
-+        return 0;
-+    /* Input length must always be non-zero */
-+    if (!inlen)
-+        return -1;
-+    /* If decrypting need at least 16 bytes and multiple of 8 */
-+    if (!EVP_CIPHER_CTX_encrypting(ctx) && (inlen < 16 || inlen & 0x7))
-+        return -1;
-+    /* If not padding input must be multiple of 8 */
-+    if (!pad && inlen & 0x7)
-+        return -1;
-+    if (is_partially_overlapping(out, in, inlen)) {
-+        EVPerr(EVP_F_AES_WRAP_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
-+        return 0;
-+    }
-+    if (!out) {
-+        if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+            /* If padding round up to multiple of 8 */
-+            if (pad)
-+                inlen = (inlen + 7) / 8 * 8;
-+            /* 8 byte prefix */
-+            return inlen + 8;
-+        } else {
-+            /*
-+             * If not padding output will be exactly 8 bytes smaller than
-+             * input. If padding it will be at least 8 bytes smaller but we
-+             * don't know how much.
-+             */
-+            return inlen - 8;
-+        }
-+    }
-+    if (pad) {
-+        if (EVP_CIPHER_CTX_encrypting(ctx))
-+            rv = CRYPTO_128_wrap_pad(&wctx->ks.ks, wctx->iv,
-+                                     out, in, inlen,
-+                                     (block128_f) AES_encrypt);
-+        else
-+            rv = CRYPTO_128_unwrap_pad(&wctx->ks.ks, wctx->iv,
-+                                       out, in, inlen,
-+                                       (block128_f) AES_decrypt);
-+    } else {
-+        if (EVP_CIPHER_CTX_encrypting(ctx))
-+            rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv,
-+                                 out, in, inlen, (block128_f) AES_encrypt);
-+        else
-+            rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv,
-+                                   out, in, inlen, (block128_f) AES_decrypt);
-+    }
-+    return rv ? (int)rv : -1;
-+}
-+
-+#define WRAP_FLAGS      (EVP_CIPH_WRAP_MODE \
-+                | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
-+                | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1)
-+
-+static const EVP_CIPHER aes_128_wrap = {
-+    NID_id_aes128_wrap,
-+    8, 16, 8, WRAP_FLAGS,
-+    aes_wrap_init_key, aes_wrap_cipher,
-+    NULL,
-+    sizeof(EVP_AES_WRAP_CTX),
-+    NULL, NULL, NULL, NULL
-+};
-+
-+const EVP_CIPHER *EVP_aes_128_wrap(void)
-+{
-+    return &aes_128_wrap;
-+}
-+
-+static const EVP_CIPHER aes_192_wrap = {
-+    NID_id_aes192_wrap,
-+    8, 24, 8, WRAP_FLAGS,
-+    aes_wrap_init_key, aes_wrap_cipher,
-+    NULL,
-+    sizeof(EVP_AES_WRAP_CTX),
-+    NULL, NULL, NULL, NULL
-+};
-+
-+const EVP_CIPHER *EVP_aes_192_wrap(void)
-+{
-+    return &aes_192_wrap;
-+}
-+
-+static const EVP_CIPHER aes_256_wrap = {
-+    NID_id_aes256_wrap,
-+    8, 32, 8, WRAP_FLAGS,
-+    aes_wrap_init_key, aes_wrap_cipher,
-+    NULL,
-+    sizeof(EVP_AES_WRAP_CTX),
-+    NULL, NULL, NULL, NULL
-+};
-+
-+const EVP_CIPHER *EVP_aes_256_wrap(void)
-+{
-+    return &aes_256_wrap;
-+}
-+
-+static const EVP_CIPHER aes_128_wrap_pad = {
-+    NID_id_aes128_wrap_pad,
-+    8, 16, 4, WRAP_FLAGS,
-+    aes_wrap_init_key, aes_wrap_cipher,
-+    NULL,
-+    sizeof(EVP_AES_WRAP_CTX),
-+    NULL, NULL, NULL, NULL
-+};
-+
-+const EVP_CIPHER *EVP_aes_128_wrap_pad(void)
-+{
-+    return &aes_128_wrap_pad;
-+}
-+
-+static const EVP_CIPHER aes_192_wrap_pad = {
-+    NID_id_aes192_wrap_pad,
-+    8, 24, 4, WRAP_FLAGS,
-+    aes_wrap_init_key, aes_wrap_cipher,
-+    NULL,
-+    sizeof(EVP_AES_WRAP_CTX),
-+    NULL, NULL, NULL, NULL
-+};
-+
-+const EVP_CIPHER *EVP_aes_192_wrap_pad(void)
-+{
-+    return &aes_192_wrap_pad;
-+}
-+
-+static const EVP_CIPHER aes_256_wrap_pad = {
-+    NID_id_aes256_wrap_pad,
-+    8, 32, 4, WRAP_FLAGS,
-+    aes_wrap_init_key, aes_wrap_cipher,
-+    NULL,
-+    sizeof(EVP_AES_WRAP_CTX),
-+    NULL, NULL, NULL, NULL
-+};
-+
-+const EVP_CIPHER *EVP_aes_256_wrap_pad(void)
-+{
-+    return &aes_256_wrap_pad;
-+}
-+
-+#ifndef OPENSSL_NO_OCB
-+static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
-+{
-+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,c);
-+    EVP_CIPHER_CTX *newc;
-+    EVP_AES_OCB_CTX *new_octx;
-+
-+    switch (type) {
-+    case EVP_CTRL_INIT:
-+        octx->key_set = 0;
-+        octx->iv_set = 0;
-+        octx->ivlen = EVP_CIPHER_CTX_iv_length(c);
-+        octx->iv = EVP_CIPHER_CTX_iv_noconst(c);
-+        octx->taglen = 16;
-+        octx->data_buf_len = 0;
-+        octx->aad_buf_len = 0;
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_SET_IVLEN:
-+        /* IV len must be 1 to 15 */
-+        if (arg <= 0 || arg > 15)
-+            return 0;
-+
-+        octx->ivlen = arg;
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_SET_TAG:
-+        if (!ptr) {
-+            /* Tag len must be 0 to 16 */
-+            if (arg < 0 || arg > 16)
-+                return 0;
-+
-+            octx->taglen = arg;
-+            return 1;
-+        }
-+        if (arg != octx->taglen || EVP_CIPHER_CTX_encrypting(c))
-+            return 0;
-+        memcpy(octx->tag, ptr, arg);
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_GET_TAG:
-+        if (arg != octx->taglen || !EVP_CIPHER_CTX_encrypting(c))
-+            return 0;
-+
-+        memcpy(ptr, octx->tag, arg);
-+        return 1;
-+
-+    case EVP_CTRL_COPY:
-+        newc = (EVP_CIPHER_CTX *)ptr;
-+        new_octx = EVP_C_DATA(EVP_AES_OCB_CTX,newc);
-+        return CRYPTO_ocb128_copy_ctx(&new_octx->ocb, &octx->ocb,
-+                                      &new_octx->ksenc.ks,
-+                                      &new_octx->ksdec.ks);
-+
-+    default:
-+        return -1;
-+
-+    }
-+}
-+
-+# ifdef HWAES_CAPABLE
-+#  ifdef HWAES_ocb_encrypt
-+void HWAES_ocb_encrypt(const unsigned char *in, unsigned char *out,
-+                       size_t blocks, const void *key,
-+                       size_t start_block_num,
-+                       unsigned char offset_i[16],
-+                       const unsigned char L_[][16],
-+                       unsigned char checksum[16]);
-+#  else
-+#    define HWAES_ocb_encrypt ((ocb128_f)NULL)
-+#  endif
-+#  ifdef HWAES_ocb_decrypt
-+void HWAES_ocb_decrypt(const unsigned char *in, unsigned char *out,
-+                       size_t blocks, const void *key,
-+                       size_t start_block_num,
-+                       unsigned char offset_i[16],
-+                       const unsigned char L_[][16],
-+                       unsigned char checksum[16]);
-+#  else
-+#    define HWAES_ocb_decrypt ((ocb128_f)NULL)
-+#  endif
-+# endif
-+
-+static int aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                            const unsigned char *iv, int enc)
-+{
-+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,ctx);
-+    if (!iv && !key)
-+        return 1;
-+    if (key) {
-+        do {
-+            /*
-+             * We set both the encrypt and decrypt key here because decrypt
-+             * needs both. We could possibly optimise to remove setting the
-+             * decrypt for an encryption operation.
-+             */
-+# ifdef HWAES_CAPABLE
-+            if (HWAES_CAPABLE) {
-+                HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                      &octx->ksenc.ks);
-+                HWAES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                      &octx->ksdec.ks);
-+                if (!CRYPTO_ocb128_init(&octx->ocb,
-+                                        &octx->ksenc.ks, &octx->ksdec.ks,
-+                                        (block128_f) HWAES_encrypt,
-+                                        (block128_f) HWAES_decrypt,
-+                                        enc ? HWAES_ocb_encrypt
-+                                            : HWAES_ocb_decrypt))
-+                    return 0;
-+                break;
-+            }
-+# endif
-+# ifdef VPAES_CAPABLE
-+            if (VPAES_CAPABLE) {
-+                vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                      &octx->ksenc.ks);
-+                vpaes_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                      &octx->ksdec.ks);
-+                if (!CRYPTO_ocb128_init(&octx->ocb,
-+                                        &octx->ksenc.ks, &octx->ksdec.ks,
-+                                        (block128_f) vpaes_encrypt,
-+                                        (block128_f) vpaes_decrypt,
-+                                        NULL))
-+                    return 0;
-+                break;
-+            }
-+# endif
-+            AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                &octx->ksenc.ks);
-+            AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                &octx->ksdec.ks);
-+            if (!CRYPTO_ocb128_init(&octx->ocb,
-+                                    &octx->ksenc.ks, &octx->ksdec.ks,
-+                                    (block128_f) AES_encrypt,
-+                                    (block128_f) AES_decrypt,
-+                                    NULL))
-+                return 0;
-+        }
-+        while (0);
-+
-+        /*
-+         * If we have an iv we can set it directly, otherwise use saved IV.
-+         */
-+        if (iv == NULL && octx->iv_set)
-+            iv = octx->iv;
-+        if (iv) {
-+            if (CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen)
-+                != 1)
-+                return 0;
-+            octx->iv_set = 1;
-+        }
-+        octx->key_set = 1;
-+    } else {
-+        /* If key set use IV, otherwise copy */
-+        if (octx->key_set)
-+            CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen);
-+        else
-+            memcpy(octx->iv, iv, octx->ivlen);
-+        octx->iv_set = 1;
-+    }
-+    return 1;
-+}
-+
-+static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t len)
-+{
-+    unsigned char *buf;
-+    int *buf_len;
-+    int written_len = 0;
-+    size_t trailing_len;
-+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,ctx);
-+
-+    /* If IV or Key not set then return error */
-+    if (!octx->iv_set)
-+        return -1;
-+
-+    if (!octx->key_set)
-+        return -1;
-+
-+    if (in != NULL) {
-+        /*
-+         * Need to ensure we are only passing full blocks to low level OCB
-+         * routines. We do it here rather than in EVP_EncryptUpdate/
-+         * EVP_DecryptUpdate because we need to pass full blocks of AAD too
-+         * and those routines don't support that
-+         */
-+
-+        /* Are we dealing with AAD or normal data here? */
-+        if (out == NULL) {
-+            buf = octx->aad_buf;
-+            buf_len = &(octx->aad_buf_len);
-+        } else {
-+            buf = octx->data_buf;
-+            buf_len = &(octx->data_buf_len);
-+
-+            if (is_partially_overlapping(out + *buf_len, in, len)) {
-+                EVPerr(EVP_F_AES_OCB_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
-+                return 0;
-+            }
-+        }
-+
-+        /*
-+         * If we've got a partially filled buffer from a previous call then
-+         * use that data first
-+         */
-+        if (*buf_len > 0) {
-+            unsigned int remaining;
-+
-+            remaining = AES_BLOCK_SIZE - (*buf_len);
-+            if (remaining > len) {
-+                memcpy(buf + (*buf_len), in, len);
-+                *(buf_len) += len;
-+                return 0;
-+            }
-+            memcpy(buf + (*buf_len), in, remaining);
-+
-+            /*
-+             * If we get here we've filled the buffer, so process it
-+             */
-+            len -= remaining;
-+            in += remaining;
-+            if (out == NULL) {
-+                if (!CRYPTO_ocb128_aad(&octx->ocb, buf, AES_BLOCK_SIZE))
-+                    return -1;
-+            } else if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+                if (!CRYPTO_ocb128_encrypt(&octx->ocb, buf, out,
-+                                           AES_BLOCK_SIZE))
-+                    return -1;
-+            } else {
-+                if (!CRYPTO_ocb128_decrypt(&octx->ocb, buf, out,
-+                                           AES_BLOCK_SIZE))
-+                    return -1;
-+            }
-+            written_len = AES_BLOCK_SIZE;
-+            *buf_len = 0;
-+            if (out != NULL)
-+                out += AES_BLOCK_SIZE;
-+        }
-+
-+        /* Do we have a partial block to handle at the end? */
-+        trailing_len = len % AES_BLOCK_SIZE;
-+
-+        /*
-+         * If we've got some full blocks to handle, then process these first
-+         */
-+        if (len != trailing_len) {
-+            if (out == NULL) {
-+                if (!CRYPTO_ocb128_aad(&octx->ocb, in, len - trailing_len))
-+                    return -1;
-+            } else if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+                if (!CRYPTO_ocb128_encrypt
-+                    (&octx->ocb, in, out, len - trailing_len))
-+                    return -1;
-+            } else {
-+                if (!CRYPTO_ocb128_decrypt
-+                    (&octx->ocb, in, out, len - trailing_len))
-+                    return -1;
-+            }
-+            written_len += len - trailing_len;
-+            in += len - trailing_len;
-+        }
-+
-+        /* Handle any trailing partial block */
-+        if (trailing_len > 0) {
-+            memcpy(buf, in, trailing_len);
-+            *buf_len = trailing_len;
-+        }
-+
-+        return written_len;
-+    } else {
-+        /*
-+         * First of all empty the buffer of any partial block that we might
-+         * have been provided - both for data and AAD
-+         */
-+        if (octx->data_buf_len > 0) {
-+            if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+                if (!CRYPTO_ocb128_encrypt(&octx->ocb, octx->data_buf, out,
-+                                           octx->data_buf_len))
-+                    return -1;
-+            } else {
-+                if (!CRYPTO_ocb128_decrypt(&octx->ocb, octx->data_buf, out,
-+                                           octx->data_buf_len))
-+                    return -1;
-+            }
-+            written_len = octx->data_buf_len;
-+            octx->data_buf_len = 0;
-+        }
-+        if (octx->aad_buf_len > 0) {
-+            if (!CRYPTO_ocb128_aad
-+                (&octx->ocb, octx->aad_buf, octx->aad_buf_len))
-+                return -1;
-+            octx->aad_buf_len = 0;
-+        }
-+        /* If decrypting then verify */
-+        if (!EVP_CIPHER_CTX_encrypting(ctx)) {
-+            if (octx->taglen < 0)
-+                return -1;
-+            if (CRYPTO_ocb128_finish(&octx->ocb,
-+                                     octx->tag, octx->taglen) != 0)
-+                return -1;
-+            octx->iv_set = 0;
-+            return written_len;
-+        }
-+        /* If encrypting then just get the tag */
-+        if (CRYPTO_ocb128_tag(&octx->ocb, octx->tag, 16) != 1)
-+            return -1;
-+        /* Don't reuse the IV */
-+        octx->iv_set = 0;
-+        return written_len;
-+    }
-+}
-+
-+static int aes_ocb_cleanup(EVP_CIPHER_CTX *c)
-+{
-+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,c);
-+    CRYPTO_ocb128_cleanup(&octx->ocb);
-+    return 1;
-+}
-+
-+BLOCK_CIPHER_custom(NID_aes, 128, 16, 12, ocb, OCB,
-+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
-+BLOCK_CIPHER_custom(NID_aes, 192, 16, 12, ocb, OCB,
-+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
-+BLOCK_CIPHER_custom(NID_aes, 256, 16, 12, ocb, OCB,
-+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
-+#endif                         /* OPENSSL_NO_OCB */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
-new file mode 100644
-index 0000000..52c7c74
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
-@@ -0,0 +1,957 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "modes_lcl.h"
-+#include "internal/evp_int.h"
-+#include "internal/constant_time_locl.h"
-+
-+typedef struct {
-+    AES_KEY ks;
-+    SHA_CTX head, tail, md;
-+    size_t payload_length;      /* AAD length in decrypt case */
-+    union {
-+        unsigned int tls_ver;
-+        unsigned char tls_aad[16]; /* 13 used */
-+    } aux;
-+} EVP_AES_HMAC_SHA1;
-+
-+#define NO_PAYLOAD_LENGTH       ((size_t)-1)
-+
-+#if     defined(AES_ASM) &&     ( \
-+        defined(__x86_64)       || defined(__x86_64__)  || \
-+        defined(_M_AMD64)       || defined(_M_X64)      )
-+
-+extern unsigned int OPENSSL_ia32cap_P[];
-+# define AESNI_CAPABLE   (1<<(57-32))
-+
-+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
-+                          AES_KEY *key);
-+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
-+                          AES_KEY *key);
-+
-+void aesni_cbc_encrypt(const unsigned char *in,
-+                       unsigned char *out,
-+                       size_t length,
-+                       const AES_KEY *key, unsigned char *ivec, int enc);
-+
-+void aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks,
-+                        const AES_KEY *key, unsigned char iv[16],
-+                        SHA_CTX *ctx, const void *in0);
-+
-+void aesni256_cbc_sha1_dec(const void *inp, void *out, size_t blocks,
-+                           const AES_KEY *key, unsigned char iv[16],
-+                           SHA_CTX *ctx, const void *in0);
-+
-+# define data(ctx) ((EVP_AES_HMAC_SHA1 *)EVP_CIPHER_CTX_get_cipher_data(ctx))
-+
-+static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
-+                                        const unsigned char *inkey,
-+                                        const unsigned char *iv, int enc)
-+{
-+    EVP_AES_HMAC_SHA1 *key = data(ctx);
-+    int ret;
-+
-+    if (enc)
-+        ret = aesni_set_encrypt_key(inkey,
-+                                    EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                    &key->ks);
-+    else
-+        ret = aesni_set_decrypt_key(inkey,
-+                                    EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                    &key->ks);
-+
-+    SHA1_Init(&key->head);      /* handy when benchmarking */
-+    key->tail = key->head;
-+    key->md = key->head;
-+
-+    key->payload_length = NO_PAYLOAD_LENGTH;
-+
-+    return ret < 0 ? 0 : 1;
-+}
-+
-+# define STITCHED_CALL
-+# undef  STITCHED_DECRYPT_CALL
-+
-+# if !defined(STITCHED_CALL)
-+#  define aes_off 0
-+# endif
-+
-+void sha1_block_data_order(void *c, const void *p, size_t len);
-+
-+static void sha1_update(SHA_CTX *c, const void *data, size_t len)
-+{
-+    const unsigned char *ptr = data;
-+    size_t res;
-+
-+    if ((res = c->num)) {
-+        res = SHA_CBLOCK - res;
-+        if (len < res)
-+            res = len;
-+        SHA1_Update(c, ptr, res);
-+        ptr += res;
-+        len -= res;
-+    }
-+
-+    res = len % SHA_CBLOCK;
-+    len -= res;
-+
-+    if (len) {
-+        sha1_block_data_order(c, ptr, len / SHA_CBLOCK);
-+
-+        ptr += len;
-+        c->Nh += len >> 29;
-+        c->Nl += len <<= 3;
-+        if (c->Nl < (unsigned int)len)
-+            c->Nh++;
-+    }
-+
-+    if (res)
-+        SHA1_Update(c, ptr, res);
-+}
-+
-+# ifdef SHA1_Update
-+#  undef SHA1_Update
-+# endif
-+# define SHA1_Update sha1_update
-+
-+# if !defined(OPENSSL_NO_MULTIBLOCK)
-+
-+typedef struct {
-+    unsigned int A[8], B[8], C[8], D[8], E[8];
-+} SHA1_MB_CTX;
-+typedef struct {
-+    const unsigned char *ptr;
-+    int blocks;
-+} HASH_DESC;
-+
-+void sha1_multi_block(SHA1_MB_CTX *, const HASH_DESC *, int);
-+
-+typedef struct {
-+    const unsigned char *inp;
-+    unsigned char *out;
-+    int blocks;
-+    u64 iv[2];
-+} CIPH_DESC;
-+
-+void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int);
-+
-+static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA1 *key,
-+                                         unsigned char *out,
-+                                         const unsigned char *inp,
-+                                         size_t inp_len, int n4x)
-+{                               /* n4x is 1 or 2 */
-+    HASH_DESC hash_d[8], edges[8];
-+    CIPH_DESC ciph_d[8];
-+    unsigned char storage[sizeof(SHA1_MB_CTX) + 32];
-+    union {
-+        u64 q[16];
-+        u32 d[32];
-+        u8 c[128];
-+    } blocks[8];
-+    SHA1_MB_CTX *ctx;
-+    unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed =
-+        0;
-+    size_t ret = 0;
-+    u8 *IVs;
-+#  if defined(BSWAP8)
-+    u64 seqnum;
-+#  endif
-+
-+    /* ask for IVs in bulk */
-+    if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0)
-+        return 0;
-+
-+    ctx = (SHA1_MB_CTX *) (storage + 32 - ((size_t)storage % 32)); /* align */
-+
-+    frag = (unsigned int)inp_len >> (1 + n4x);
-+    last = (unsigned int)inp_len + frag - (frag << (1 + n4x));
-+    if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) {
-+        frag++;
-+        last -= x4 - 1;
-+    }
-+
-+    packlen = 5 + 16 + ((frag + 20 + 16) & -16);
-+
-+    /* populate descriptors with pointers and IVs */
-+    hash_d[0].ptr = inp;
-+    ciph_d[0].inp = inp;
-+    /* 5+16 is place for header and explicit IV */
-+    ciph_d[0].out = out + 5 + 16;
-+    memcpy(ciph_d[0].out - 16, IVs, 16);
-+    memcpy(ciph_d[0].iv, IVs, 16);
-+    IVs += 16;
-+
-+    for (i = 1; i < x4; i++) {
-+        ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag;
-+        ciph_d[i].out = ciph_d[i - 1].out + packlen;
-+        memcpy(ciph_d[i].out - 16, IVs, 16);
-+        memcpy(ciph_d[i].iv, IVs, 16);
-+        IVs += 16;
-+    }
-+
-+#  if defined(BSWAP8)
-+    memcpy(blocks[0].c, key->md.data, 8);
-+    seqnum = BSWAP8(blocks[0].q[0]);
-+#  endif
-+    for (i = 0; i < x4; i++) {
-+        unsigned int len = (i == (x4 - 1) ? last : frag);
-+#  if !defined(BSWAP8)
-+        unsigned int carry, j;
-+#  endif
-+
-+        ctx->A[i] = key->md.h0;
-+        ctx->B[i] = key->md.h1;
-+        ctx->C[i] = key->md.h2;
-+        ctx->D[i] = key->md.h3;
-+        ctx->E[i] = key->md.h4;
-+
-+        /* fix seqnum */
-+#  if defined(BSWAP8)
-+        blocks[i].q[0] = BSWAP8(seqnum + i);
-+#  else
-+        for (carry = i, j = 8; j--;) {
-+            blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry;
-+            carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1);
-+        }
-+#  endif
-+        blocks[i].c[8] = ((u8 *)key->md.data)[8];
-+        blocks[i].c[9] = ((u8 *)key->md.data)[9];
-+        blocks[i].c[10] = ((u8 *)key->md.data)[10];
-+        /* fix length */
-+        blocks[i].c[11] = (u8)(len >> 8);
-+        blocks[i].c[12] = (u8)(len);
-+
-+        memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13);
-+        hash_d[i].ptr += 64 - 13;
-+        hash_d[i].blocks = (len - (64 - 13)) / 64;
-+
-+        edges[i].ptr = blocks[i].c;
-+        edges[i].blocks = 1;
-+    }
-+
-+    /* hash 13-byte headers and first 64-13 bytes of inputs */
-+    sha1_multi_block(ctx, edges, n4x);
-+    /* hash bulk inputs */
-+#  define MAXCHUNKSIZE    2048
-+#  if     MAXCHUNKSIZE%64
-+#   error  "MAXCHUNKSIZE is not divisible by 64"
-+#  elif   MAXCHUNKSIZE
-+    /*
-+     * goal is to minimize pressure on L1 cache by moving in shorter steps,
-+     * so that hashed data is still in the cache by the time we encrypt it
-+     */
-+    minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64;
-+    if (minblocks > MAXCHUNKSIZE / 64) {
-+        for (i = 0; i < x4; i++) {
-+            edges[i].ptr = hash_d[i].ptr;
-+            edges[i].blocks = MAXCHUNKSIZE / 64;
-+            ciph_d[i].blocks = MAXCHUNKSIZE / 16;
-+        }
-+        do {
-+            sha1_multi_block(ctx, edges, n4x);
-+            aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
-+
-+            for (i = 0; i < x4; i++) {
-+                edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE;
-+                hash_d[i].blocks -= MAXCHUNKSIZE / 64;
-+                edges[i].blocks = MAXCHUNKSIZE / 64;
-+                ciph_d[i].inp += MAXCHUNKSIZE;
-+                ciph_d[i].out += MAXCHUNKSIZE;
-+                ciph_d[i].blocks = MAXCHUNKSIZE / 16;
-+                memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16);
-+            }
-+            processed += MAXCHUNKSIZE;
-+            minblocks -= MAXCHUNKSIZE / 64;
-+        } while (minblocks > MAXCHUNKSIZE / 64);
-+    }
-+#  endif
-+#  undef  MAXCHUNKSIZE
-+    sha1_multi_block(ctx, hash_d, n4x);
-+
-+    memset(blocks, 0, sizeof(blocks));
-+    for (i = 0; i < x4; i++) {
-+        unsigned int len = (i == (x4 - 1) ? last : frag),
-+            off = hash_d[i].blocks * 64;
-+        const unsigned char *ptr = hash_d[i].ptr + off;
-+
-+        off = (len - processed) - (64 - 13) - off; /* remainder actually */
-+        memcpy(blocks[i].c, ptr, off);
-+        blocks[i].c[off] = 0x80;
-+        len += 64 + 13;         /* 64 is HMAC header */
-+        len *= 8;               /* convert to bits */
-+        if (off < (64 - 8)) {
-+#  ifdef BSWAP4
-+            blocks[i].d[15] = BSWAP4(len);
-+#  else
-+            PUTU32(blocks[i].c + 60, len);
-+#  endif
-+            edges[i].blocks = 1;
-+        } else {
-+#  ifdef BSWAP4
-+            blocks[i].d[31] = BSWAP4(len);
-+#  else
-+            PUTU32(blocks[i].c + 124, len);
-+#  endif
-+            edges[i].blocks = 2;
-+        }
-+        edges[i].ptr = blocks[i].c;
-+    }
-+
-+    /* hash input tails and finalize */
-+    sha1_multi_block(ctx, edges, n4x);
-+
-+    memset(blocks, 0, sizeof(blocks));
-+    for (i = 0; i < x4; i++) {
-+#  ifdef BSWAP4
-+        blocks[i].d[0] = BSWAP4(ctx->A[i]);
-+        ctx->A[i] = key->tail.h0;
-+        blocks[i].d[1] = BSWAP4(ctx->B[i]);
-+        ctx->B[i] = key->tail.h1;
-+        blocks[i].d[2] = BSWAP4(ctx->C[i]);
-+        ctx->C[i] = key->tail.h2;
-+        blocks[i].d[3] = BSWAP4(ctx->D[i]);
-+        ctx->D[i] = key->tail.h3;
-+        blocks[i].d[4] = BSWAP4(ctx->E[i]);
-+        ctx->E[i] = key->tail.h4;
-+        blocks[i].c[20] = 0x80;
-+        blocks[i].d[15] = BSWAP4((64 + 20) * 8);
-+#  else
-+        PUTU32(blocks[i].c + 0, ctx->A[i]);
-+        ctx->A[i] = key->tail.h0;
-+        PUTU32(blocks[i].c + 4, ctx->B[i]);
-+        ctx->B[i] = key->tail.h1;
-+        PUTU32(blocks[i].c + 8, ctx->C[i]);
-+        ctx->C[i] = key->tail.h2;
-+        PUTU32(blocks[i].c + 12, ctx->D[i]);
-+        ctx->D[i] = key->tail.h3;
-+        PUTU32(blocks[i].c + 16, ctx->E[i]);
-+        ctx->E[i] = key->tail.h4;
-+        blocks[i].c[20] = 0x80;
-+        PUTU32(blocks[i].c + 60, (64 + 20) * 8);
-+#  endif
-+        edges[i].ptr = blocks[i].c;
-+        edges[i].blocks = 1;
-+    }
-+
-+    /* finalize MACs */
-+    sha1_multi_block(ctx, edges, n4x);
-+
-+    for (i = 0; i < x4; i++) {
-+        unsigned int len = (i == (x4 - 1) ? last : frag), pad, j;
-+        unsigned char *out0 = out;
-+
-+        memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed);
-+        ciph_d[i].inp = ciph_d[i].out;
-+
-+        out += 5 + 16 + len;
-+
-+        /* write MAC */
-+        PUTU32(out + 0, ctx->A[i]);
-+        PUTU32(out + 4, ctx->B[i]);
-+        PUTU32(out + 8, ctx->C[i]);
-+        PUTU32(out + 12, ctx->D[i]);
-+        PUTU32(out + 16, ctx->E[i]);
-+        out += 20;
-+        len += 20;
-+
-+        /* pad */
-+        pad = 15 - len % 16;
-+        for (j = 0; j <= pad; j++)
-+            *(out++) = pad;
-+        len += pad + 1;
-+
-+        ciph_d[i].blocks = (len - processed) / 16;
-+        len += 16;              /* account for explicit iv */
-+
-+        /* arrange header */
-+        out0[0] = ((u8 *)key->md.data)[8];
-+        out0[1] = ((u8 *)key->md.data)[9];
-+        out0[2] = ((u8 *)key->md.data)[10];
-+        out0[3] = (u8)(len >> 8);
-+        out0[4] = (u8)(len);
-+
-+        ret += len + 5;
-+        inp += frag;
-+    }
-+
-+    aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
-+
-+    OPENSSL_cleanse(blocks, sizeof(blocks));
-+    OPENSSL_cleanse(ctx, sizeof(*ctx));
-+
-+    return ret;
-+}
-+# endif
-+
-+static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                                      const unsigned char *in, size_t len)
-+{
-+    EVP_AES_HMAC_SHA1 *key = data(ctx);
-+    unsigned int l;
-+    size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and
-+                                                * later */
-+        sha_off = 0;
-+# if defined(STITCHED_CALL)
-+    size_t aes_off = 0, blocks;
-+
-+    sha_off = SHA_CBLOCK - key->md.num;
-+# endif
-+
-+    key->payload_length = NO_PAYLOAD_LENGTH;
-+
-+    if (len % AES_BLOCK_SIZE)
-+        return 0;
-+
-+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+        if (plen == NO_PAYLOAD_LENGTH)
-+            plen = len;
-+        else if (len !=
-+                 ((plen + SHA_DIGEST_LENGTH +
-+                   AES_BLOCK_SIZE) & -AES_BLOCK_SIZE))
-+            return 0;
-+        else if (key->aux.tls_ver >= TLS1_1_VERSION)
-+            iv = AES_BLOCK_SIZE;
-+
-+# if defined(STITCHED_CALL)
-+        if (plen > (sha_off + iv)
-+            && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) {
-+            SHA1_Update(&key->md, in + iv, sha_off);
-+
-+            aesni_cbc_sha1_enc(in, out, blocks, &key->ks,
-+                               EVP_CIPHER_CTX_iv_noconst(ctx),
-+                               &key->md, in + iv + sha_off);
-+            blocks *= SHA_CBLOCK;
-+            aes_off += blocks;
-+            sha_off += blocks;
-+            key->md.Nh += blocks >> 29;
-+            key->md.Nl += blocks <<= 3;
-+            if (key->md.Nl < (unsigned int)blocks)
-+                key->md.Nh++;
-+        } else {
-+            sha_off = 0;
-+        }
-+# endif
-+        sha_off += iv;
-+        SHA1_Update(&key->md, in + sha_off, plen - sha_off);
-+
-+        if (plen != len) {      /* "TLS" mode of operation */
-+            if (in != out)
-+                memcpy(out + aes_off, in + aes_off, plen - aes_off);
-+
-+            /* calculate HMAC and append it to payload */
-+            SHA1_Final(out + plen, &key->md);
-+            key->md = key->tail;
-+            SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH);
-+            SHA1_Final(out + plen, &key->md);
-+
-+            /* pad the payload|hmac */
-+            plen += SHA_DIGEST_LENGTH;
-+            for (l = len - plen - 1; plen < len; plen++)
-+                out[plen] = l;
-+            /* encrypt HMAC|padding at once */
-+            aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off,
-+                              &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
-+        } else {
-+            aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
-+                              &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
-+        }
-+    } else {
-+        union {
-+            unsigned int u[SHA_DIGEST_LENGTH / sizeof(unsigned int)];
-+            unsigned char c[32 + SHA_DIGEST_LENGTH];
-+        } mac, *pmac;
-+
-+        /* arrange cache line alignment */
-+        pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32));
-+
-+        if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
-+            size_t inp_len, mask, j, i;
-+            unsigned int res, maxpad, pad, bitlen;
-+            int ret = 1;
-+            union {
-+                unsigned int u[SHA_LBLOCK];
-+                unsigned char c[SHA_CBLOCK];
-+            } *data = (void *)key->md.data;
-+# if defined(STITCHED_DECRYPT_CALL)
-+            unsigned char tail_iv[AES_BLOCK_SIZE];
-+            int stitch = 0;
-+# endif
-+
-+            if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3])
-+                >= TLS1_1_VERSION) {
-+                if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1))
-+                    return 0;
-+
-+                /* omit explicit iv */
-+                memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), in, AES_BLOCK_SIZE);
-+
-+                in += AES_BLOCK_SIZE;
-+                out += AES_BLOCK_SIZE;
-+                len -= AES_BLOCK_SIZE;
-+            } else if (len < (SHA_DIGEST_LENGTH + 1))
-+                return 0;
-+
-+# if defined(STITCHED_DECRYPT_CALL)
-+            if (len >= 1024 && ctx->key_len == 32) {
-+                /* decrypt last block */
-+                memcpy(tail_iv, in + len - 2 * AES_BLOCK_SIZE,
-+                       AES_BLOCK_SIZE);
-+                aesni_cbc_encrypt(in + len - AES_BLOCK_SIZE,
-+                                  out + len - AES_BLOCK_SIZE, AES_BLOCK_SIZE,
-+                                  &key->ks, tail_iv, 0);
-+                stitch = 1;
-+            } else
-+# endif
-+                /* decrypt HMAC|padding at once */
-+                aesni_cbc_encrypt(in, out, len, &key->ks,
-+                                  EVP_CIPHER_CTX_iv_noconst(ctx), 0);
-+
-+            /* figure out payload length */
-+            pad = out[len - 1];
-+            maxpad = len - (SHA_DIGEST_LENGTH + 1);
-+            maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
-+            maxpad &= 255;
-+
-+            ret &= constant_time_ge(maxpad, pad);
-+
-+            inp_len = len - (SHA_DIGEST_LENGTH + pad + 1);
-+            mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
-+            inp_len &= mask;
-+            ret &= (int)mask;
-+
-+            key->aux.tls_aad[plen - 2] = inp_len >> 8;
-+            key->aux.tls_aad[plen - 1] = inp_len;
-+
-+            /* calculate HMAC */
-+            key->md = key->head;
-+            SHA1_Update(&key->md, key->aux.tls_aad, plen);
-+
-+# if defined(STITCHED_DECRYPT_CALL)
-+            if (stitch) {
-+                blocks = (len - (256 + 32 + SHA_CBLOCK)) / SHA_CBLOCK;
-+                aes_off = len - AES_BLOCK_SIZE - blocks * SHA_CBLOCK;
-+                sha_off = SHA_CBLOCK - plen;
-+
-+                aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0);
-+
-+                SHA1_Update(&key->md, out, sha_off);
-+                aesni256_cbc_sha1_dec(in + aes_off,
-+                                      out + aes_off, blocks, &key->ks,
-+                                      ctx->iv, &key->md, out + sha_off);
-+
-+                sha_off += blocks *= SHA_CBLOCK;
-+                out += sha_off;
-+                len -= sha_off;
-+                inp_len -= sha_off;
-+
-+                key->md.Nl += (blocks << 3); /* at most 18 bits */
-+                memcpy(ctx->iv, tail_iv, AES_BLOCK_SIZE);
-+            }
-+# endif
-+
-+# if 1
-+            len -= SHA_DIGEST_LENGTH; /* amend mac */
-+            if (len >= (256 + SHA_CBLOCK)) {
-+                j = (len - (256 + SHA_CBLOCK)) & (0 - SHA_CBLOCK);
-+                j += SHA_CBLOCK - key->md.num;
-+                SHA1_Update(&key->md, out, j);
-+                out += j;
-+                len -= j;
-+                inp_len -= j;
-+            }
-+
-+            /* but pretend as if we hashed padded payload */
-+            bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */
-+#  ifdef BSWAP4
-+            bitlen = BSWAP4(bitlen);
-+#  else
-+            mac.c[0] = 0;
-+            mac.c[1] = (unsigned char)(bitlen >> 16);
-+            mac.c[2] = (unsigned char)(bitlen >> 8);
-+            mac.c[3] = (unsigned char)bitlen;
-+            bitlen = mac.u[0];
-+#  endif
-+
-+            pmac->u[0] = 0;
-+            pmac->u[1] = 0;
-+            pmac->u[2] = 0;
-+            pmac->u[3] = 0;
-+            pmac->u[4] = 0;
-+
-+            for (res = key->md.num, j = 0; j < len; j++) {
-+                size_t c = out[j];
-+                mask = (j - inp_len) >> (sizeof(j) * 8 - 8);
-+                c &= mask;
-+                c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8));
-+                data->c[res++] = (unsigned char)c;
-+
-+                if (res != SHA_CBLOCK)
-+                    continue;
-+
-+                /* j is not incremented yet */
-+                mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1));
-+                data->u[SHA_LBLOCK - 1] |= bitlen & mask;
-+                sha1_block_data_order(&key->md, data, 1);
-+                mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1));
-+                pmac->u[0] |= key->md.h0 & mask;
-+                pmac->u[1] |= key->md.h1 & mask;
-+                pmac->u[2] |= key->md.h2 & mask;
-+                pmac->u[3] |= key->md.h3 & mask;
-+                pmac->u[4] |= key->md.h4 & mask;
-+                res = 0;
-+            }
-+
-+            for (i = res; i < SHA_CBLOCK; i++, j++)
-+                data->c[i] = 0;
-+
-+            if (res > SHA_CBLOCK - 8) {
-+                mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1));
-+                data->u[SHA_LBLOCK - 1] |= bitlen & mask;
-+                sha1_block_data_order(&key->md, data, 1);
-+                mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
-+                pmac->u[0] |= key->md.h0 & mask;
-+                pmac->u[1] |= key->md.h1 & mask;
-+                pmac->u[2] |= key->md.h2 & mask;
-+                pmac->u[3] |= key->md.h3 & mask;
-+                pmac->u[4] |= key->md.h4 & mask;
-+
-+                memset(data, 0, SHA_CBLOCK);
-+                j += 64;
-+            }
-+            data->u[SHA_LBLOCK - 1] = bitlen;
-+            sha1_block_data_order(&key->md, data, 1);
-+            mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
-+            pmac->u[0] |= key->md.h0 & mask;
-+            pmac->u[1] |= key->md.h1 & mask;
-+            pmac->u[2] |= key->md.h2 & mask;
-+            pmac->u[3] |= key->md.h3 & mask;
-+            pmac->u[4] |= key->md.h4 & mask;
-+
-+#  ifdef BSWAP4
-+            pmac->u[0] = BSWAP4(pmac->u[0]);
-+            pmac->u[1] = BSWAP4(pmac->u[1]);
-+            pmac->u[2] = BSWAP4(pmac->u[2]);
-+            pmac->u[3] = BSWAP4(pmac->u[3]);
-+            pmac->u[4] = BSWAP4(pmac->u[4]);
-+#  else
-+            for (i = 0; i < 5; i++) {
-+                res = pmac->u[i];
-+                pmac->c[4 * i + 0] = (unsigned char)(res >> 24);
-+                pmac->c[4 * i + 1] = (unsigned char)(res >> 16);
-+                pmac->c[4 * i + 2] = (unsigned char)(res >> 8);
-+                pmac->c[4 * i + 3] = (unsigned char)res;
-+            }
-+#  endif
-+            len += SHA_DIGEST_LENGTH;
-+# else
-+            SHA1_Update(&key->md, out, inp_len);
-+            res = key->md.num;
-+            SHA1_Final(pmac->c, &key->md);
-+
-+            {
-+                unsigned int inp_blocks, pad_blocks;
-+
-+                /* but pretend as if we hashed padded payload */
-+                inp_blocks =
-+                    1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
-+                res += (unsigned int)(len - inp_len);
-+                pad_blocks = res / SHA_CBLOCK;
-+                res %= SHA_CBLOCK;
-+                pad_blocks +=
-+                    1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
-+                for (; inp_blocks < pad_blocks; inp_blocks++)
-+                    sha1_block_data_order(&key->md, data, 1);
-+            }
-+# endif
-+            key->md = key->tail;
-+            SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH);
-+            SHA1_Final(pmac->c, &key->md);
-+
-+            /* verify HMAC */
-+            out += inp_len;
-+            len -= inp_len;
-+# if 1
-+            {
-+                unsigned char *p = out + len - 1 - maxpad - SHA_DIGEST_LENGTH;
-+                size_t off = out - p;
-+                unsigned int c, cmask;
-+
-+                maxpad += SHA_DIGEST_LENGTH;
-+                for (res = 0, i = 0, j = 0; j < maxpad; j++) {
-+                    c = p[j];
-+                    cmask =
-+                        ((int)(j - off - SHA_DIGEST_LENGTH)) >> (sizeof(int) *
-+                                                                 8 - 1);
-+                    res |= (c ^ pad) & ~cmask; /* ... and padding */
-+                    cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1);
-+                    res |= (c ^ pmac->c[i]) & cmask;
-+                    i += 1 & cmask;
-+                }
-+                maxpad -= SHA_DIGEST_LENGTH;
-+
-+                res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
-+                ret &= (int)~res;
-+            }
-+# else
-+            for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++)
-+                res |= out[i] ^ pmac->c[i];
-+            res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
-+            ret &= (int)~res;
-+
-+            /* verify padding */
-+            pad = (pad & ~res) | (maxpad & res);
-+            out = out + len - 1 - pad;
-+            for (res = 0, i = 0; i < pad; i++)
-+                res |= out[i] ^ pad;
-+
-+            res = (0 - res) >> (sizeof(res) * 8 - 1);
-+            ret &= (int)~res;
-+# endif
-+            return ret;
-+        } else {
-+# if defined(STITCHED_DECRYPT_CALL)
-+            if (len >= 1024 && ctx->key_len == 32) {
-+                if (sha_off %= SHA_CBLOCK)
-+                    blocks = (len - 3 * SHA_CBLOCK) / SHA_CBLOCK;
-+                else
-+                    blocks = (len - 2 * SHA_CBLOCK) / SHA_CBLOCK;
-+                aes_off = len - blocks * SHA_CBLOCK;
-+
-+                aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0);
-+                SHA1_Update(&key->md, out, sha_off);
-+                aesni256_cbc_sha1_dec(in + aes_off,
-+                                      out + aes_off, blocks, &key->ks,
-+                                      ctx->iv, &key->md, out + sha_off);
-+
-+                sha_off += blocks *= SHA_CBLOCK;
-+                out += sha_off;
-+                len -= sha_off;
-+
-+                key->md.Nh += blocks >> 29;
-+                key->md.Nl += blocks <<= 3;
-+                if (key->md.Nl < (unsigned int)blocks)
-+                    key->md.Nh++;
-+            } else
-+# endif
-+                /* decrypt HMAC|padding at once */
-+                aesni_cbc_encrypt(in, out, len, &key->ks,
-+                                  EVP_CIPHER_CTX_iv_noconst(ctx), 0);
-+
-+            SHA1_Update(&key->md, out, len);
-+        }
-+    }
-+
-+    return 1;
-+}
-+
-+static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
-+                                    void *ptr)
-+{
-+    EVP_AES_HMAC_SHA1 *key = data(ctx);
-+
-+    switch (type) {
-+    case EVP_CTRL_AEAD_SET_MAC_KEY:
-+        {
-+            unsigned int i;
-+            unsigned char hmac_key[64];
-+
-+            memset(hmac_key, 0, sizeof(hmac_key));
-+
-+            if (arg > (int)sizeof(hmac_key)) {
-+                SHA1_Init(&key->head);
-+                SHA1_Update(&key->head, ptr, arg);
-+                SHA1_Final(hmac_key, &key->head);
-+            } else {
-+                memcpy(hmac_key, ptr, arg);
-+            }
-+
-+            for (i = 0; i < sizeof(hmac_key); i++)
-+                hmac_key[i] ^= 0x36; /* ipad */
-+            SHA1_Init(&key->head);
-+            SHA1_Update(&key->head, hmac_key, sizeof(hmac_key));
-+
-+            for (i = 0; i < sizeof(hmac_key); i++)
-+                hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
-+            SHA1_Init(&key->tail);
-+            SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key));
-+
-+            OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
-+
-+            return 1;
-+        }
-+    case EVP_CTRL_AEAD_TLS1_AAD:
-+        {
-+            unsigned char *p = ptr;
-+            unsigned int len;
-+
-+            if (arg != EVP_AEAD_TLS1_AAD_LEN)
-+                return -1;
-+
-+            len = p[arg - 2] << 8 | p[arg - 1];
-+
-+            if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+                key->payload_length = len;
-+                if ((key->aux.tls_ver =
-+                     p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
-+                    len -= AES_BLOCK_SIZE;
-+                    p[arg - 2] = len >> 8;
-+                    p[arg - 1] = len;
-+                }
-+                key->md = key->head;
-+                SHA1_Update(&key->md, p, arg);
-+
-+                return (int)(((len + SHA_DIGEST_LENGTH +
-+                               AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
-+                             - len);
-+            } else {
-+                memcpy(key->aux.tls_aad, ptr, arg);
-+                key->payload_length = arg;
-+
-+                return SHA_DIGEST_LENGTH;
-+            }
-+        }
-+# if !defined(OPENSSL_NO_MULTIBLOCK)
-+    case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE:
-+        return (int)(5 + 16 + ((arg + 20 + 16) & -16));
-+    case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD:
-+        {
-+            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
-+                (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
-+            unsigned int n4x = 1, x4;
-+            unsigned int frag, last, packlen, inp_len;
-+
-+            if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM))
-+                return -1;
-+
-+            inp_len = param->inp[11] << 8 | param->inp[12];
-+
-+            if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+                if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION)
-+                    return -1;
-+
-+                if (inp_len) {
-+                    if (inp_len < 4096)
-+                        return 0; /* too short */
-+
-+                    if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5))
-+                        n4x = 2; /* AVX2 */
-+                } else if ((n4x = param->interleave / 4) && n4x <= 2)
-+                    inp_len = param->len;
-+                else
-+                    return -1;
-+
-+                key->md = key->head;
-+                SHA1_Update(&key->md, param->inp, 13);
-+
-+                x4 = 4 * n4x;
-+                n4x += 1;
-+
-+                frag = inp_len >> n4x;
-+                last = inp_len + frag - (frag << n4x);
-+                if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) {
-+                    frag++;
-+                    last -= x4 - 1;
-+                }
-+
-+                packlen = 5 + 16 + ((frag + 20 + 16) & -16);
-+                packlen = (packlen << n4x) - packlen;
-+                packlen += 5 + 16 + ((last + 20 + 16) & -16);
-+
-+                param->interleave = x4;
-+
-+                return (int)packlen;
-+            } else
-+                return -1;      /* not yet */
-+        }
-+    case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT:
-+        {
-+            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
-+                (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
-+
-+            return (int)tls1_1_multi_block_encrypt(key, param->out,
-+                                                   param->inp, param->len,
-+                                                   param->interleave / 4);
-+        }
-+    case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT:
-+# endif
-+    default:
-+        return -1;
-+    }
-+}
-+
-+static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = {
-+# ifdef NID_aes_128_cbc_hmac_sha1
-+    NID_aes_128_cbc_hmac_sha1,
-+# else
-+    NID_undef,
-+# endif
-+    AES_BLOCK_SIZE, 16, AES_BLOCK_SIZE,
-+    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
-+        EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
-+    aesni_cbc_hmac_sha1_init_key,
-+    aesni_cbc_hmac_sha1_cipher,
-+    NULL,
-+    sizeof(EVP_AES_HMAC_SHA1),
-+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
-+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
-+    aesni_cbc_hmac_sha1_ctrl,
-+    NULL
-+};
-+
-+static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = {
-+# ifdef NID_aes_256_cbc_hmac_sha1
-+    NID_aes_256_cbc_hmac_sha1,
-+# else
-+    NID_undef,
-+# endif
-+    AES_BLOCK_SIZE, 32, AES_BLOCK_SIZE,
-+    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
-+        EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
-+    aesni_cbc_hmac_sha1_init_key,
-+    aesni_cbc_hmac_sha1_cipher,
-+    NULL,
-+    sizeof(EVP_AES_HMAC_SHA1),
-+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
-+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
-+    aesni_cbc_hmac_sha1_ctrl,
-+    NULL
-+};
-+
-+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
-+{
-+    return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ?
-+            &aesni_128_cbc_hmac_sha1_cipher : NULL);
-+}
-+
-+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
-+{
-+    return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ?
-+            &aesni_256_cbc_hmac_sha1_cipher : NULL);
-+}
-+#else
-+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
-+{
-+    return NULL;
-+}
-+
-+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
-+{
-+    return NULL;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c
-new file mode 100644
-index 0000000..5a92e0b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c
-@@ -0,0 +1,939 @@
-+/*
-+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#include 
-+#include 
-+
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "modes_lcl.h"
-+#include "internal/constant_time_locl.h"
-+#include "internal/evp_int.h"
-+
-+typedef struct {
-+    AES_KEY ks;
-+    SHA256_CTX head, tail, md;
-+    size_t payload_length;      /* AAD length in decrypt case */
-+    union {
-+        unsigned int tls_ver;
-+        unsigned char tls_aad[16]; /* 13 used */
-+    } aux;
-+} EVP_AES_HMAC_SHA256;
-+
-+# define NO_PAYLOAD_LENGTH       ((size_t)-1)
-+
-+#if     defined(AES_ASM) &&     ( \
-+        defined(__x86_64)       || defined(__x86_64__)  || \
-+        defined(_M_AMD64)       || defined(_M_X64)      )
-+
-+extern unsigned int OPENSSL_ia32cap_P[];
-+# define AESNI_CAPABLE   (1<<(57-32))
-+
-+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
-+                          AES_KEY *key);
-+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
-+                          AES_KEY *key);
-+
-+void aesni_cbc_encrypt(const unsigned char *in,
-+                       unsigned char *out,
-+                       size_t length,
-+                       const AES_KEY *key, unsigned char *ivec, int enc);
-+
-+int aesni_cbc_sha256_enc(const void *inp, void *out, size_t blocks,
-+                         const AES_KEY *key, unsigned char iv[16],
-+                         SHA256_CTX *ctx, const void *in0);
-+
-+# define data(ctx) ((EVP_AES_HMAC_SHA256 *)EVP_CIPHER_CTX_get_cipher_data(ctx))
-+
-+static int aesni_cbc_hmac_sha256_init_key(EVP_CIPHER_CTX *ctx,
-+                                          const unsigned char *inkey,
-+                                          const unsigned char *iv, int enc)
-+{
-+    EVP_AES_HMAC_SHA256 *key = data(ctx);
-+    int ret;
-+
-+    if (enc)
-+        ret = aesni_set_encrypt_key(inkey,
-+                                    EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                    &key->ks);
-+    else
-+        ret = aesni_set_decrypt_key(inkey,
-+                                    EVP_CIPHER_CTX_key_length(ctx) * 8,
-+                                    &key->ks);
-+
-+    SHA256_Init(&key->head);    /* handy when benchmarking */
-+    key->tail = key->head;
-+    key->md = key->head;
-+
-+    key->payload_length = NO_PAYLOAD_LENGTH;
-+
-+    return ret < 0 ? 0 : 1;
-+}
-+
-+# define STITCHED_CALL
-+
-+# if !defined(STITCHED_CALL)
-+#  define aes_off 0
-+# endif
-+
-+void sha256_block_data_order(void *c, const void *p, size_t len);
-+
-+static void sha256_update(SHA256_CTX *c, const void *data, size_t len)
-+{
-+    const unsigned char *ptr = data;
-+    size_t res;
-+
-+    if ((res = c->num)) {
-+        res = SHA256_CBLOCK - res;
-+        if (len < res)
-+            res = len;
-+        SHA256_Update(c, ptr, res);
-+        ptr += res;
-+        len -= res;
-+    }
-+
-+    res = len % SHA256_CBLOCK;
-+    len -= res;
-+
-+    if (len) {
-+        sha256_block_data_order(c, ptr, len / SHA256_CBLOCK);
-+
-+        ptr += len;
-+        c->Nh += len >> 29;
-+        c->Nl += len <<= 3;
-+        if (c->Nl < (unsigned int)len)
-+            c->Nh++;
-+    }
-+
-+    if (res)
-+        SHA256_Update(c, ptr, res);
-+}
-+
-+# ifdef SHA256_Update
-+#  undef SHA256_Update
-+# endif
-+# define SHA256_Update sha256_update
-+
-+# if !defined(OPENSSL_NO_MULTIBLOCK)
-+
-+typedef struct {
-+    unsigned int A[8], B[8], C[8], D[8], E[8], F[8], G[8], H[8];
-+} SHA256_MB_CTX;
-+typedef struct {
-+    const unsigned char *ptr;
-+    int blocks;
-+} HASH_DESC;
-+
-+void sha256_multi_block(SHA256_MB_CTX *, const HASH_DESC *, int);
-+
-+typedef struct {
-+    const unsigned char *inp;
-+    unsigned char *out;
-+    int blocks;
-+    u64 iv[2];
-+} CIPH_DESC;
-+
-+void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int);
-+
-+static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA256 *key,
-+                                         unsigned char *out,
-+                                         const unsigned char *inp,
-+                                         size_t inp_len, int n4x)
-+{                               /* n4x is 1 or 2 */
-+    HASH_DESC hash_d[8], edges[8];
-+    CIPH_DESC ciph_d[8];
-+    unsigned char storage[sizeof(SHA256_MB_CTX) + 32];
-+    union {
-+        u64 q[16];
-+        u32 d[32];
-+        u8 c[128];
-+    } blocks[8];
-+    SHA256_MB_CTX *ctx;
-+    unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed =
-+        0;
-+    size_t ret = 0;
-+    u8 *IVs;
-+#  if defined(BSWAP8)
-+    u64 seqnum;
-+#  endif
-+
-+    /* ask for IVs in bulk */
-+    if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0)
-+        return 0;
-+
-+    /* align */
-+    ctx = (SHA256_MB_CTX *) (storage + 32 - ((size_t)storage % 32));
-+
-+    frag = (unsigned int)inp_len >> (1 + n4x);
-+    last = (unsigned int)inp_len + frag - (frag << (1 + n4x));
-+    if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) {
-+        frag++;
-+        last -= x4 - 1;
-+    }
-+
-+    packlen = 5 + 16 + ((frag + 32 + 16) & -16);
-+
-+    /* populate descriptors with pointers and IVs */
-+    hash_d[0].ptr = inp;
-+    ciph_d[0].inp = inp;
-+    /* 5+16 is place for header and explicit IV */
-+    ciph_d[0].out = out + 5 + 16;
-+    memcpy(ciph_d[0].out - 16, IVs, 16);
-+    memcpy(ciph_d[0].iv, IVs, 16);
-+    IVs += 16;
-+
-+    for (i = 1; i < x4; i++) {
-+        ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag;
-+        ciph_d[i].out = ciph_d[i - 1].out + packlen;
-+        memcpy(ciph_d[i].out - 16, IVs, 16);
-+        memcpy(ciph_d[i].iv, IVs, 16);
-+        IVs += 16;
-+    }
-+
-+#  if defined(BSWAP8)
-+    memcpy(blocks[0].c, key->md.data, 8);
-+    seqnum = BSWAP8(blocks[0].q[0]);
-+#  endif
-+    for (i = 0; i < x4; i++) {
-+        unsigned int len = (i == (x4 - 1) ? last : frag);
-+#  if !defined(BSWAP8)
-+        unsigned int carry, j;
-+#  endif
-+
-+        ctx->A[i] = key->md.h[0];
-+        ctx->B[i] = key->md.h[1];
-+        ctx->C[i] = key->md.h[2];
-+        ctx->D[i] = key->md.h[3];
-+        ctx->E[i] = key->md.h[4];
-+        ctx->F[i] = key->md.h[5];
-+        ctx->G[i] = key->md.h[6];
-+        ctx->H[i] = key->md.h[7];
-+
-+        /* fix seqnum */
-+#  if defined(BSWAP8)
-+        blocks[i].q[0] = BSWAP8(seqnum + i);
-+#  else
-+        for (carry = i, j = 8; j--;) {
-+            blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry;
-+            carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1);
-+        }
-+#  endif
-+        blocks[i].c[8] = ((u8 *)key->md.data)[8];
-+        blocks[i].c[9] = ((u8 *)key->md.data)[9];
-+        blocks[i].c[10] = ((u8 *)key->md.data)[10];
-+        /* fix length */
-+        blocks[i].c[11] = (u8)(len >> 8);
-+        blocks[i].c[12] = (u8)(len);
-+
-+        memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13);
-+        hash_d[i].ptr += 64 - 13;
-+        hash_d[i].blocks = (len - (64 - 13)) / 64;
-+
-+        edges[i].ptr = blocks[i].c;
-+        edges[i].blocks = 1;
-+    }
-+
-+    /* hash 13-byte headers and first 64-13 bytes of inputs */
-+    sha256_multi_block(ctx, edges, n4x);
-+    /* hash bulk inputs */
-+#  define MAXCHUNKSIZE    2048
-+#  if     MAXCHUNKSIZE%64
-+#   error  "MAXCHUNKSIZE is not divisible by 64"
-+#  elif   MAXCHUNKSIZE
-+    /*
-+     * goal is to minimize pressure on L1 cache by moving in shorter steps,
-+     * so that hashed data is still in the cache by the time we encrypt it
-+     */
-+    minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64;
-+    if (minblocks > MAXCHUNKSIZE / 64) {
-+        for (i = 0; i < x4; i++) {
-+            edges[i].ptr = hash_d[i].ptr;
-+            edges[i].blocks = MAXCHUNKSIZE / 64;
-+            ciph_d[i].blocks = MAXCHUNKSIZE / 16;
-+        }
-+        do {
-+            sha256_multi_block(ctx, edges, n4x);
-+            aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
-+
-+            for (i = 0; i < x4; i++) {
-+                edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE;
-+                hash_d[i].blocks -= MAXCHUNKSIZE / 64;
-+                edges[i].blocks = MAXCHUNKSIZE / 64;
-+                ciph_d[i].inp += MAXCHUNKSIZE;
-+                ciph_d[i].out += MAXCHUNKSIZE;
-+                ciph_d[i].blocks = MAXCHUNKSIZE / 16;
-+                memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16);
-+            }
-+            processed += MAXCHUNKSIZE;
-+            minblocks -= MAXCHUNKSIZE / 64;
-+        } while (minblocks > MAXCHUNKSIZE / 64);
-+    }
-+#  endif
-+#  undef  MAXCHUNKSIZE
-+    sha256_multi_block(ctx, hash_d, n4x);
-+
-+    memset(blocks, 0, sizeof(blocks));
-+    for (i = 0; i < x4; i++) {
-+        unsigned int len = (i == (x4 - 1) ? last : frag),
-+            off = hash_d[i].blocks * 64;
-+        const unsigned char *ptr = hash_d[i].ptr + off;
-+
-+        off = (len - processed) - (64 - 13) - off; /* remainder actually */
-+        memcpy(blocks[i].c, ptr, off);
-+        blocks[i].c[off] = 0x80;
-+        len += 64 + 13;         /* 64 is HMAC header */
-+        len *= 8;               /* convert to bits */
-+        if (off < (64 - 8)) {
-+#  ifdef BSWAP4
-+            blocks[i].d[15] = BSWAP4(len);
-+#  else
-+            PUTU32(blocks[i].c + 60, len);
-+#  endif
-+            edges[i].blocks = 1;
-+        } else {
-+#  ifdef BSWAP4
-+            blocks[i].d[31] = BSWAP4(len);
-+#  else
-+            PUTU32(blocks[i].c + 124, len);
-+#  endif
-+            edges[i].blocks = 2;
-+        }
-+        edges[i].ptr = blocks[i].c;
-+    }
-+
-+    /* hash input tails and finalize */
-+    sha256_multi_block(ctx, edges, n4x);
-+
-+    memset(blocks, 0, sizeof(blocks));
-+    for (i = 0; i < x4; i++) {
-+#  ifdef BSWAP4
-+        blocks[i].d[0] = BSWAP4(ctx->A[i]);
-+        ctx->A[i] = key->tail.h[0];
-+        blocks[i].d[1] = BSWAP4(ctx->B[i]);
-+        ctx->B[i] = key->tail.h[1];
-+        blocks[i].d[2] = BSWAP4(ctx->C[i]);
-+        ctx->C[i] = key->tail.h[2];
-+        blocks[i].d[3] = BSWAP4(ctx->D[i]);
-+        ctx->D[i] = key->tail.h[3];
-+        blocks[i].d[4] = BSWAP4(ctx->E[i]);
-+        ctx->E[i] = key->tail.h[4];
-+        blocks[i].d[5] = BSWAP4(ctx->F[i]);
-+        ctx->F[i] = key->tail.h[5];
-+        blocks[i].d[6] = BSWAP4(ctx->G[i]);
-+        ctx->G[i] = key->tail.h[6];
-+        blocks[i].d[7] = BSWAP4(ctx->H[i]);
-+        ctx->H[i] = key->tail.h[7];
-+        blocks[i].c[32] = 0x80;
-+        blocks[i].d[15] = BSWAP4((64 + 32) * 8);
-+#  else
-+        PUTU32(blocks[i].c + 0, ctx->A[i]);
-+        ctx->A[i] = key->tail.h[0];
-+        PUTU32(blocks[i].c + 4, ctx->B[i]);
-+        ctx->B[i] = key->tail.h[1];
-+        PUTU32(blocks[i].c + 8, ctx->C[i]);
-+        ctx->C[i] = key->tail.h[2];
-+        PUTU32(blocks[i].c + 12, ctx->D[i]);
-+        ctx->D[i] = key->tail.h[3];
-+        PUTU32(blocks[i].c + 16, ctx->E[i]);
-+        ctx->E[i] = key->tail.h[4];
-+        PUTU32(blocks[i].c + 20, ctx->F[i]);
-+        ctx->F[i] = key->tail.h[5];
-+        PUTU32(blocks[i].c + 24, ctx->G[i]);
-+        ctx->G[i] = key->tail.h[6];
-+        PUTU32(blocks[i].c + 28, ctx->H[i]);
-+        ctx->H[i] = key->tail.h[7];
-+        blocks[i].c[32] = 0x80;
-+        PUTU32(blocks[i].c + 60, (64 + 32) * 8);
-+#  endif
-+        edges[i].ptr = blocks[i].c;
-+        edges[i].blocks = 1;
-+    }
-+
-+    /* finalize MACs */
-+    sha256_multi_block(ctx, edges, n4x);
-+
-+    for (i = 0; i < x4; i++) {
-+        unsigned int len = (i == (x4 - 1) ? last : frag), pad, j;
-+        unsigned char *out0 = out;
-+
-+        memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed);
-+        ciph_d[i].inp = ciph_d[i].out;
-+
-+        out += 5 + 16 + len;
-+
-+        /* write MAC */
-+        PUTU32(out + 0, ctx->A[i]);
-+        PUTU32(out + 4, ctx->B[i]);
-+        PUTU32(out + 8, ctx->C[i]);
-+        PUTU32(out + 12, ctx->D[i]);
-+        PUTU32(out + 16, ctx->E[i]);
-+        PUTU32(out + 20, ctx->F[i]);
-+        PUTU32(out + 24, ctx->G[i]);
-+        PUTU32(out + 28, ctx->H[i]);
-+        out += 32;
-+        len += 32;
-+
-+        /* pad */
-+        pad = 15 - len % 16;
-+        for (j = 0; j <= pad; j++)
-+            *(out++) = pad;
-+        len += pad + 1;
-+
-+        ciph_d[i].blocks = (len - processed) / 16;
-+        len += 16;              /* account for explicit iv */
-+
-+        /* arrange header */
-+        out0[0] = ((u8 *)key->md.data)[8];
-+        out0[1] = ((u8 *)key->md.data)[9];
-+        out0[2] = ((u8 *)key->md.data)[10];
-+        out0[3] = (u8)(len >> 8);
-+        out0[4] = (u8)(len);
-+
-+        ret += len + 5;
-+        inp += frag;
-+    }
-+
-+    aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
-+
-+    OPENSSL_cleanse(blocks, sizeof(blocks));
-+    OPENSSL_cleanse(ctx, sizeof(*ctx));
-+
-+    return ret;
-+}
-+# endif
-+
-+static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx,
-+                                        unsigned char *out,
-+                                        const unsigned char *in, size_t len)
-+{
-+    EVP_AES_HMAC_SHA256 *key = data(ctx);
-+    unsigned int l;
-+    size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and
-+                                                * later */
-+        sha_off = 0;
-+# if defined(STITCHED_CALL)
-+    size_t aes_off = 0, blocks;
-+
-+    sha_off = SHA256_CBLOCK - key->md.num;
-+# endif
-+
-+    key->payload_length = NO_PAYLOAD_LENGTH;
-+
-+    if (len % AES_BLOCK_SIZE)
-+        return 0;
-+
-+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+        if (plen == NO_PAYLOAD_LENGTH)
-+            plen = len;
-+        else if (len !=
-+                 ((plen + SHA256_DIGEST_LENGTH +
-+                   AES_BLOCK_SIZE) & -AES_BLOCK_SIZE))
-+            return 0;
-+        else if (key->aux.tls_ver >= TLS1_1_VERSION)
-+            iv = AES_BLOCK_SIZE;
-+
-+# if defined(STITCHED_CALL)
-+        /*
-+         * Assembly stitch handles AVX-capable processors, but its
-+         * performance is not optimal on AMD Jaguar, ~40% worse, for
-+         * unknown reasons. Incidentally processor in question supports
-+         * AVX, but not AMD-specific XOP extension, which can be used
-+         * to identify it and avoid stitch invocation. So that after we
-+         * establish that current CPU supports AVX, we even see if it's
-+         * either even XOP-capable Bulldozer-based or GenuineIntel one.
-+         */
-+        if (OPENSSL_ia32cap_P[1] & (1 << (60 - 32)) && /* AVX? */
-+            ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */
-+             | (OPENSSL_ia32cap_P[0] & (1<<30))) &&    /* "Intel CPU"? */
-+            plen > (sha_off + iv) &&
-+            (blocks = (plen - (sha_off + iv)) / SHA256_CBLOCK)) {
-+            SHA256_Update(&key->md, in + iv, sha_off);
-+
-+            (void)aesni_cbc_sha256_enc(in, out, blocks, &key->ks,
-+                                       EVP_CIPHER_CTX_iv_noconst(ctx),
-+                                       &key->md, in + iv + sha_off);
-+            blocks *= SHA256_CBLOCK;
-+            aes_off += blocks;
-+            sha_off += blocks;
-+            key->md.Nh += blocks >> 29;
-+            key->md.Nl += blocks <<= 3;
-+            if (key->md.Nl < (unsigned int)blocks)
-+                key->md.Nh++;
-+        } else {
-+            sha_off = 0;
-+        }
-+# endif
-+        sha_off += iv;
-+        SHA256_Update(&key->md, in + sha_off, plen - sha_off);
-+
-+        if (plen != len) {      /* "TLS" mode of operation */
-+            if (in != out)
-+                memcpy(out + aes_off, in + aes_off, plen - aes_off);
-+
-+            /* calculate HMAC and append it to payload */
-+            SHA256_Final(out + plen, &key->md);
-+            key->md = key->tail;
-+            SHA256_Update(&key->md, out + plen, SHA256_DIGEST_LENGTH);
-+            SHA256_Final(out + plen, &key->md);
-+
-+            /* pad the payload|hmac */
-+            plen += SHA256_DIGEST_LENGTH;
-+            for (l = len - plen - 1; plen < len; plen++)
-+                out[plen] = l;
-+            /* encrypt HMAC|padding at once */
-+            aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off,
-+                              &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
-+        } else {
-+            aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
-+                              &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
-+        }
-+    } else {
-+        union {
-+            unsigned int u[SHA256_DIGEST_LENGTH / sizeof(unsigned int)];
-+            unsigned char c[64 + SHA256_DIGEST_LENGTH];
-+        } mac, *pmac;
-+
-+        /* arrange cache line alignment */
-+        pmac = (void *)(((size_t)mac.c + 63) & ((size_t)0 - 64));
-+
-+        /* decrypt HMAC|padding at once */
-+        aesni_cbc_encrypt(in, out, len, &key->ks,
-+                          EVP_CIPHER_CTX_iv_noconst(ctx), 0);
-+
-+        if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
-+            size_t inp_len, mask, j, i;
-+            unsigned int res, maxpad, pad, bitlen;
-+            int ret = 1;
-+            union {
-+                unsigned int u[SHA_LBLOCK];
-+                unsigned char c[SHA256_CBLOCK];
-+            } *data = (void *)key->md.data;
-+
-+            if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3])
-+                >= TLS1_1_VERSION)
-+                iv = AES_BLOCK_SIZE;
-+
-+            if (len < (iv + SHA256_DIGEST_LENGTH + 1))
-+                return 0;
-+
-+            /* omit explicit iv */
-+            out += iv;
-+            len -= iv;
-+
-+            /* figure out payload length */
-+            pad = out[len - 1];
-+            maxpad = len - (SHA256_DIGEST_LENGTH + 1);
-+            maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
-+            maxpad &= 255;
-+
-+            ret &= constant_time_ge(maxpad, pad);
-+
-+            inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1);
-+            mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
-+            inp_len &= mask;
-+            ret &= (int)mask;
-+
-+            key->aux.tls_aad[plen - 2] = inp_len >> 8;
-+            key->aux.tls_aad[plen - 1] = inp_len;
-+
-+            /* calculate HMAC */
-+            key->md = key->head;
-+            SHA256_Update(&key->md, key->aux.tls_aad, plen);
-+
-+# if 1
-+            len -= SHA256_DIGEST_LENGTH; /* amend mac */
-+            if (len >= (256 + SHA256_CBLOCK)) {
-+                j = (len - (256 + SHA256_CBLOCK)) & (0 - SHA256_CBLOCK);
-+                j += SHA256_CBLOCK - key->md.num;
-+                SHA256_Update(&key->md, out, j);
-+                out += j;
-+                len -= j;
-+                inp_len -= j;
-+            }
-+
-+            /* but pretend as if we hashed padded payload */
-+            bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */
-+#  ifdef BSWAP4
-+            bitlen = BSWAP4(bitlen);
-+#  else
-+            mac.c[0] = 0;
-+            mac.c[1] = (unsigned char)(bitlen >> 16);
-+            mac.c[2] = (unsigned char)(bitlen >> 8);
-+            mac.c[3] = (unsigned char)bitlen;
-+            bitlen = mac.u[0];
-+#  endif
-+
-+            pmac->u[0] = 0;
-+            pmac->u[1] = 0;
-+            pmac->u[2] = 0;
-+            pmac->u[3] = 0;
-+            pmac->u[4] = 0;
-+            pmac->u[5] = 0;
-+            pmac->u[6] = 0;
-+            pmac->u[7] = 0;
-+
-+            for (res = key->md.num, j = 0; j < len; j++) {
-+                size_t c = out[j];
-+                mask = (j - inp_len) >> (sizeof(j) * 8 - 8);
-+                c &= mask;
-+                c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8));
-+                data->c[res++] = (unsigned char)c;
-+
-+                if (res != SHA256_CBLOCK)
-+                    continue;
-+
-+                /* j is not incremented yet */
-+                mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1));
-+                data->u[SHA_LBLOCK - 1] |= bitlen & mask;
-+                sha256_block_data_order(&key->md, data, 1);
-+                mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1));
-+                pmac->u[0] |= key->md.h[0] & mask;
-+                pmac->u[1] |= key->md.h[1] & mask;
-+                pmac->u[2] |= key->md.h[2] & mask;
-+                pmac->u[3] |= key->md.h[3] & mask;
-+                pmac->u[4] |= key->md.h[4] & mask;
-+                pmac->u[5] |= key->md.h[5] & mask;
-+                pmac->u[6] |= key->md.h[6] & mask;
-+                pmac->u[7] |= key->md.h[7] & mask;
-+                res = 0;
-+            }
-+
-+            for (i = res; i < SHA256_CBLOCK; i++, j++)
-+                data->c[i] = 0;
-+
-+            if (res > SHA256_CBLOCK - 8) {
-+                mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1));
-+                data->u[SHA_LBLOCK - 1] |= bitlen & mask;
-+                sha256_block_data_order(&key->md, data, 1);
-+                mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
-+                pmac->u[0] |= key->md.h[0] & mask;
-+                pmac->u[1] |= key->md.h[1] & mask;
-+                pmac->u[2] |= key->md.h[2] & mask;
-+                pmac->u[3] |= key->md.h[3] & mask;
-+                pmac->u[4] |= key->md.h[4] & mask;
-+                pmac->u[5] |= key->md.h[5] & mask;
-+                pmac->u[6] |= key->md.h[6] & mask;
-+                pmac->u[7] |= key->md.h[7] & mask;
-+
-+                memset(data, 0, SHA256_CBLOCK);
-+                j += 64;
-+            }
-+            data->u[SHA_LBLOCK - 1] = bitlen;
-+            sha256_block_data_order(&key->md, data, 1);
-+            mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
-+            pmac->u[0] |= key->md.h[0] & mask;
-+            pmac->u[1] |= key->md.h[1] & mask;
-+            pmac->u[2] |= key->md.h[2] & mask;
-+            pmac->u[3] |= key->md.h[3] & mask;
-+            pmac->u[4] |= key->md.h[4] & mask;
-+            pmac->u[5] |= key->md.h[5] & mask;
-+            pmac->u[6] |= key->md.h[6] & mask;
-+            pmac->u[7] |= key->md.h[7] & mask;
-+
-+#  ifdef BSWAP4
-+            pmac->u[0] = BSWAP4(pmac->u[0]);
-+            pmac->u[1] = BSWAP4(pmac->u[1]);
-+            pmac->u[2] = BSWAP4(pmac->u[2]);
-+            pmac->u[3] = BSWAP4(pmac->u[3]);
-+            pmac->u[4] = BSWAP4(pmac->u[4]);
-+            pmac->u[5] = BSWAP4(pmac->u[5]);
-+            pmac->u[6] = BSWAP4(pmac->u[6]);
-+            pmac->u[7] = BSWAP4(pmac->u[7]);
-+#  else
-+            for (i = 0; i < 8; i++) {
-+                res = pmac->u[i];
-+                pmac->c[4 * i + 0] = (unsigned char)(res >> 24);
-+                pmac->c[4 * i + 1] = (unsigned char)(res >> 16);
-+                pmac->c[4 * i + 2] = (unsigned char)(res >> 8);
-+                pmac->c[4 * i + 3] = (unsigned char)res;
-+            }
-+#  endif
-+            len += SHA256_DIGEST_LENGTH;
-+# else
-+            SHA256_Update(&key->md, out, inp_len);
-+            res = key->md.num;
-+            SHA256_Final(pmac->c, &key->md);
-+
-+            {
-+                unsigned int inp_blocks, pad_blocks;
-+
-+                /* but pretend as if we hashed padded payload */
-+                inp_blocks =
-+                    1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
-+                res += (unsigned int)(len - inp_len);
-+                pad_blocks = res / SHA256_CBLOCK;
-+                res %= SHA256_CBLOCK;
-+                pad_blocks +=
-+                    1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
-+                for (; inp_blocks < pad_blocks; inp_blocks++)
-+                    sha1_block_data_order(&key->md, data, 1);
-+            }
-+# endif
-+            key->md = key->tail;
-+            SHA256_Update(&key->md, pmac->c, SHA256_DIGEST_LENGTH);
-+            SHA256_Final(pmac->c, &key->md);
-+
-+            /* verify HMAC */
-+            out += inp_len;
-+            len -= inp_len;
-+# if 1
-+            {
-+                unsigned char *p =
-+                    out + len - 1 - maxpad - SHA256_DIGEST_LENGTH;
-+                size_t off = out - p;
-+                unsigned int c, cmask;
-+
-+                maxpad += SHA256_DIGEST_LENGTH;
-+                for (res = 0, i = 0, j = 0; j < maxpad; j++) {
-+                    c = p[j];
-+                    cmask =
-+                        ((int)(j - off - SHA256_DIGEST_LENGTH)) >>
-+                        (sizeof(int) * 8 - 1);
-+                    res |= (c ^ pad) & ~cmask; /* ... and padding */
-+                    cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1);
-+                    res |= (c ^ pmac->c[i]) & cmask;
-+                    i += 1 & cmask;
-+                }
-+                maxpad -= SHA256_DIGEST_LENGTH;
-+
-+                res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
-+                ret &= (int)~res;
-+            }
-+# else
-+            for (res = 0, i = 0; i < SHA256_DIGEST_LENGTH; i++)
-+                res |= out[i] ^ pmac->c[i];
-+            res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
-+            ret &= (int)~res;
-+
-+            /* verify padding */
-+            pad = (pad & ~res) | (maxpad & res);
-+            out = out + len - 1 - pad;
-+            for (res = 0, i = 0; i < pad; i++)
-+                res |= out[i] ^ pad;
-+
-+            res = (0 - res) >> (sizeof(res) * 8 - 1);
-+            ret &= (int)~res;
-+# endif
-+            return ret;
-+        } else {
-+            SHA256_Update(&key->md, out, len);
-+        }
-+    }
-+
-+    return 1;
-+}
-+
-+static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
-+                                      void *ptr)
-+{
-+    EVP_AES_HMAC_SHA256 *key = data(ctx);
-+    unsigned int u_arg = (unsigned int)arg;
-+
-+    switch (type) {
-+    case EVP_CTRL_AEAD_SET_MAC_KEY:
-+        {
-+            unsigned int i;
-+            unsigned char hmac_key[64];
-+
-+            memset(hmac_key, 0, sizeof(hmac_key));
-+
-+            if (arg < 0)
-+                return -1;
-+
-+            if (u_arg > sizeof(hmac_key)) {
-+                SHA256_Init(&key->head);
-+                SHA256_Update(&key->head, ptr, arg);
-+                SHA256_Final(hmac_key, &key->head);
-+            } else {
-+                memcpy(hmac_key, ptr, arg);
-+            }
-+
-+            for (i = 0; i < sizeof(hmac_key); i++)
-+                hmac_key[i] ^= 0x36; /* ipad */
-+            SHA256_Init(&key->head);
-+            SHA256_Update(&key->head, hmac_key, sizeof(hmac_key));
-+
-+            for (i = 0; i < sizeof(hmac_key); i++)
-+                hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
-+            SHA256_Init(&key->tail);
-+            SHA256_Update(&key->tail, hmac_key, sizeof(hmac_key));
-+
-+            OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
-+
-+            return 1;
-+        }
-+    case EVP_CTRL_AEAD_TLS1_AAD:
-+        {
-+            unsigned char *p = ptr;
-+            unsigned int len = p[arg - 2] << 8 | p[arg - 1];
-+
-+            if (arg != EVP_AEAD_TLS1_AAD_LEN)
-+                return -1;
-+
-+            if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+                key->payload_length = len;
-+                if ((key->aux.tls_ver =
-+                     p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
-+                    len -= AES_BLOCK_SIZE;
-+                    p[arg - 2] = len >> 8;
-+                    p[arg - 1] = len;
-+                }
-+                key->md = key->head;
-+                SHA256_Update(&key->md, p, arg);
-+
-+                return (int)(((len + SHA256_DIGEST_LENGTH +
-+                               AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
-+                             - len);
-+            } else {
-+                memcpy(key->aux.tls_aad, ptr, arg);
-+                key->payload_length = arg;
-+
-+                return SHA256_DIGEST_LENGTH;
-+            }
-+        }
-+# if !defined(OPENSSL_NO_MULTIBLOCK)
-+    case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE:
-+        return (int)(5 + 16 + ((arg + 32 + 16) & -16));
-+    case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD:
-+        {
-+            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
-+                (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
-+            unsigned int n4x = 1, x4;
-+            unsigned int frag, last, packlen, inp_len;
-+
-+            if (arg < 0)
-+                return -1;
-+
-+            if (u_arg < sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM))
-+                return -1;
-+
-+            inp_len = param->inp[11] << 8 | param->inp[12];
-+
-+            if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+                if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION)
-+                    return -1;
-+
-+                if (inp_len) {
-+                    if (inp_len < 4096)
-+                        return 0; /* too short */
-+
-+                    if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5))
-+                        n4x = 2; /* AVX2 */
-+                } else if ((n4x = param->interleave / 4) && n4x <= 2)
-+                    inp_len = param->len;
-+                else
-+                    return -1;
-+
-+                key->md = key->head;
-+                SHA256_Update(&key->md, param->inp, 13);
-+
-+                x4 = 4 * n4x;
-+                n4x += 1;
-+
-+                frag = inp_len >> n4x;
-+                last = inp_len + frag - (frag << n4x);
-+                if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) {
-+                    frag++;
-+                    last -= x4 - 1;
-+                }
-+
-+                packlen = 5 + 16 + ((frag + 32 + 16) & -16);
-+                packlen = (packlen << n4x) - packlen;
-+                packlen += 5 + 16 + ((last + 32 + 16) & -16);
-+
-+                param->interleave = x4;
-+
-+                return (int)packlen;
-+            } else
-+                return -1;      /* not yet */
-+        }
-+    case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT:
-+        {
-+            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
-+                (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
-+
-+            return (int)tls1_1_multi_block_encrypt(key, param->out,
-+                                                   param->inp, param->len,
-+                                                   param->interleave / 4);
-+        }
-+    case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT:
-+# endif
-+    default:
-+        return -1;
-+    }
-+}
-+
-+static EVP_CIPHER aesni_128_cbc_hmac_sha256_cipher = {
-+# ifdef NID_aes_128_cbc_hmac_sha256
-+    NID_aes_128_cbc_hmac_sha256,
-+# else
-+    NID_undef,
-+# endif
-+    AES_BLOCK_SIZE, 16, AES_BLOCK_SIZE,
-+    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
-+        EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
-+    aesni_cbc_hmac_sha256_init_key,
-+    aesni_cbc_hmac_sha256_cipher,
-+    NULL,
-+    sizeof(EVP_AES_HMAC_SHA256),
-+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
-+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
-+    aesni_cbc_hmac_sha256_ctrl,
-+    NULL
-+};
-+
-+static EVP_CIPHER aesni_256_cbc_hmac_sha256_cipher = {
-+# ifdef NID_aes_256_cbc_hmac_sha256
-+    NID_aes_256_cbc_hmac_sha256,
-+# else
-+    NID_undef,
-+# endif
-+    AES_BLOCK_SIZE, 32, AES_BLOCK_SIZE,
-+    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
-+        EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
-+    aesni_cbc_hmac_sha256_init_key,
-+    aesni_cbc_hmac_sha256_cipher,
-+    NULL,
-+    sizeof(EVP_AES_HMAC_SHA256),
-+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
-+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
-+    aesni_cbc_hmac_sha256_ctrl,
-+    NULL
-+};
-+
-+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void)
-+{
-+    return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) &&
-+            aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ?
-+            &aesni_128_cbc_hmac_sha256_cipher : NULL);
-+}
-+
-+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void)
-+{
-+    return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) &&
-+            aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ?
-+            &aesni_256_cbc_hmac_sha256_cipher : NULL);
-+}
-+#else
-+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void)
-+{
-+    return NULL;
-+}
-+
-+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void)
-+{
-+    return NULL;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_bf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_bf.c
-new file mode 100644
-index 0000000..dc38690
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_bf.c
-@@ -0,0 +1,38 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#ifndef OPENSSL_NO_BF
-+# include 
-+# include "internal/evp_int.h"
-+# include 
-+# include 
-+
-+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                       const unsigned char *iv, int enc);
-+
-+typedef struct {
-+    BF_KEY ks;
-+} EVP_BF_KEY;
-+
-+# define data(ctx)       EVP_C_DATA(EVP_BF_KEY,ctx)
-+
-+IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64,
-+                       EVP_CIPH_VARIABLE_LENGTH, bf_init_key, NULL,
-+                       EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
-+
-+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                       const unsigned char *iv, int enc)
-+{
-+    BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
-+    return 1;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_camellia.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_camellia.c
-new file mode 100644
-index 0000000..b50fa0b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_camellia.c
-@@ -0,0 +1,364 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#ifdef OPENSSL_NO_CAMELLIA
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+# include "modes_lcl.h"
-+
-+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                             const unsigned char *iv, int enc);
-+
-+/* Camellia subkey Structure */
-+typedef struct {
-+    CAMELLIA_KEY ks;
-+    block128_f block;
-+    union {
-+        cbc128_f cbc;
-+        ctr128_f ctr;
-+    } stream;
-+} EVP_CAMELLIA_KEY;
-+
-+# define MAXBITCHUNK     ((size_t)1<<(sizeof(size_t)*8-4))
-+
-+/* Attribute operation for Camellia */
-+# define data(ctx)       EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
-+
-+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
-+/* ---------^^^ this is not a typo, just a way to detect that
-+ * assembler support was in general requested... */
-+#  include "sparc_arch.h"
-+
-+extern unsigned int OPENSSL_sparcv9cap_P[];
-+
-+#  define SPARC_CMLL_CAPABLE      (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
-+
-+void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks);
-+void cmll_t4_encrypt(const unsigned char *in, unsigned char *out,
-+                     const CAMELLIA_KEY *key);
-+void cmll_t4_decrypt(const unsigned char *in, unsigned char *out,
-+                     const CAMELLIA_KEY *key);
-+
-+void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                            size_t len, const CAMELLIA_KEY *key,
-+                            unsigned char *ivec);
-+void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
-+                            size_t len, const CAMELLIA_KEY *key,
-+                            unsigned char *ivec);
-+void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                            size_t len, const CAMELLIA_KEY *key,
-+                            unsigned char *ivec);
-+void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
-+                            size_t len, const CAMELLIA_KEY *key,
-+                            unsigned char *ivec);
-+void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
-+                              size_t blocks, const CAMELLIA_KEY *key,
-+                              unsigned char *ivec);
-+void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
-+                              size_t blocks, const CAMELLIA_KEY *key,
-+                              unsigned char *ivec);
-+
-+static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                            const unsigned char *iv, int enc)
-+{
-+    int ret, mode, bits;
-+    EVP_CAMELLIA_KEY *dat =
-+        (EVP_CAMELLIA_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx);
-+
-+    mode = EVP_CIPHER_CTX_mode(ctx);
-+    bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
-+
-+    cmll_t4_set_key(key, bits, &dat->ks);
-+
-+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
-+        && !enc) {
-+        ret = 0;
-+        dat->block = (block128_f) cmll_t4_decrypt;
-+        switch (bits) {
-+        case 128:
-+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+                (cbc128_f) cmll128_t4_cbc_decrypt : NULL;
-+            break;
-+        case 192:
-+        case 256:
-+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+                (cbc128_f) cmll256_t4_cbc_decrypt : NULL;
-+            break;
-+        default:
-+            ret = -1;
-+        }
-+    } else {
-+        ret = 0;
-+        dat->block = (block128_f) cmll_t4_encrypt;
-+        switch (bits) {
-+        case 128:
-+            if (mode == EVP_CIPH_CBC_MODE)
-+                dat->stream.cbc = (cbc128_f) cmll128_t4_cbc_encrypt;
-+            else if (mode == EVP_CIPH_CTR_MODE)
-+                dat->stream.ctr = (ctr128_f) cmll128_t4_ctr32_encrypt;
-+            else
-+                dat->stream.cbc = NULL;
-+            break;
-+        case 192:
-+        case 256:
-+            if (mode == EVP_CIPH_CBC_MODE)
-+                dat->stream.cbc = (cbc128_f) cmll256_t4_cbc_encrypt;
-+            else if (mode == EVP_CIPH_CTR_MODE)
-+                dat->stream.ctr = (ctr128_f) cmll256_t4_ctr32_encrypt;
-+            else
-+                dat->stream.cbc = NULL;
-+            break;
-+        default:
-+            ret = -1;
-+        }
-+    }
-+
-+    if (ret < 0) {
-+        EVPerr(EVP_F_CMLL_T4_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+#  define cmll_t4_cbc_cipher camellia_cbc_cipher
-+static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t len);
-+
-+#  define cmll_t4_ecb_cipher camellia_ecb_cipher
-+static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t len);
-+
-+#  define cmll_t4_ofb_cipher camellia_ofb_cipher
-+static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t len);
-+
-+#  define cmll_t4_cfb_cipher camellia_cfb_cipher
-+static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t len);
-+
-+#  define cmll_t4_cfb8_cipher camellia_cfb8_cipher
-+static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                               const unsigned char *in, size_t len);
-+
-+#  define cmll_t4_cfb1_cipher camellia_cfb1_cipher
-+static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                               const unsigned char *in, size_t len);
-+
-+#  define cmll_t4_ctr_cipher camellia_ctr_cipher
-+static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t len);
-+
-+#  define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
-+static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \
-+        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        cmll_t4_init_key,               \
-+        cmll_t4_##mode##_cipher,        \
-+        NULL,                           \
-+        sizeof(EVP_CAMELLIA_KEY),       \
-+        NULL,NULL,NULL,NULL }; \
-+static const EVP_CIPHER camellia_##keylen##_##mode = { \
-+        nid##_##keylen##_##nmode,blocksize,     \
-+        keylen/8,ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        camellia_init_key,              \
-+        camellia_##mode##_cipher,       \
-+        NULL,                           \
-+        sizeof(EVP_CAMELLIA_KEY),       \
-+        NULL,NULL,NULL,NULL }; \
-+const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
-+{ return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; }
-+
-+# else
-+
-+#  define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
-+static const EVP_CIPHER camellia_##keylen##_##mode = { \
-+        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
-+        flags|EVP_CIPH_##MODE##_MODE,   \
-+        camellia_init_key,              \
-+        camellia_##mode##_cipher,       \
-+        NULL,                           \
-+        sizeof(EVP_CAMELLIA_KEY),       \
-+        NULL,NULL,NULL,NULL }; \
-+const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
-+{ return &camellia_##keylen##_##mode; }
-+
-+# endif
-+
-+# define BLOCK_CIPHER_generic_pack(nid,keylen,flags)             \
-+        BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)     \
-+        BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)      \
-+        BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
-+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
-+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags)       \
-+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)       \
-+        BLOCK_CIPHER_generic(nid, keylen, 1, 16, ctr, ctr, CTR, flags)
-+
-+/* The subkey for Camellia is generated. */
-+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                             const unsigned char *iv, int enc)
-+{
-+    int ret, mode;
-+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
-+
-+    ret = Camellia_set_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, &dat->ks);
-+    if (ret < 0) {
-+        EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
-+        return 0;
-+    }
-+
-+    mode = EVP_CIPHER_CTX_mode(ctx);
-+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
-+        && !enc) {
-+        dat->block = (block128_f) Camellia_decrypt;
-+        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+            (cbc128_f) Camellia_cbc_encrypt : NULL;
-+    } else {
-+        dat->block = (block128_f) Camellia_encrypt;
-+        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-+            (cbc128_f) Camellia_cbc_encrypt : NULL;
-+    }
-+
-+    return 1;
-+}
-+
-+static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                               const unsigned char *in, size_t len)
-+{
-+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
-+
-+    if (dat->stream.cbc)
-+        (*dat->stream.cbc) (in, out, len, &dat->ks,
-+                            EVP_CIPHER_CTX_iv_noconst(ctx),
-+                            EVP_CIPHER_CTX_encrypting(ctx));
-+    else if (EVP_CIPHER_CTX_encrypting(ctx))
-+        CRYPTO_cbc128_encrypt(in, out, len, &dat->ks,
-+                              EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
-+    else
-+        CRYPTO_cbc128_decrypt(in, out, len, &dat->ks,
-+                              EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
-+
-+    return 1;
-+}
-+
-+static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                               const unsigned char *in, size_t len)
-+{
-+    size_t bl = EVP_CIPHER_CTX_block_size(ctx);
-+    size_t i;
-+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
-+
-+    if (len < bl)
-+        return 1;
-+
-+    for (i = 0, len -= bl; i <= len; i += bl)
-+        (*dat->block) (in + i, out + i, &dat->ks);
-+
-+    return 1;
-+}
-+
-+static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                               const unsigned char *in, size_t len)
-+{
-+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
-+
-+    int num = EVP_CIPHER_CTX_num(ctx);
-+    CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
-+                          EVP_CIPHER_CTX_iv_noconst(ctx), &num, dat->block);
-+    EVP_CIPHER_CTX_set_num(ctx, num);
-+    return 1;
-+}
-+
-+static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                               const unsigned char *in, size_t len)
-+{
-+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
-+
-+    int num = EVP_CIPHER_CTX_num(ctx);
-+    CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
-+                          EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
-+    EVP_CIPHER_CTX_set_num(ctx, num);
-+    return 1;
-+}
-+
-+static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                                const unsigned char *in, size_t len)
-+{
-+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
-+
-+    int num = EVP_CIPHER_CTX_num(ctx);
-+    CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
-+                            EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
-+    EVP_CIPHER_CTX_set_num(ctx, num);
-+    return 1;
-+}
-+
-+static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                                const unsigned char *in, size_t len)
-+{
-+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
-+
-+    if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
-+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+        return 1;
-+    }
-+
-+    while (len >= MAXBITCHUNK) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
-+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
-+        len -= MAXBITCHUNK;
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+    }
-+    if (len) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
-+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+    }
-+
-+    return 1;
-+}
-+
-+static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                               const unsigned char *in, size_t len)
-+{
-+    unsigned int num = EVP_CIPHER_CTX_num(ctx);
-+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
-+
-+    if (dat->stream.ctr)
-+        CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
-+                                    EVP_CIPHER_CTX_iv_noconst(ctx),
-+                                    EVP_CIPHER_CTX_buf_noconst(ctx), &num,
-+                                    dat->stream.ctr);
-+    else
-+        CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
-+                              EVP_CIPHER_CTX_iv_noconst(ctx),
-+                              EVP_CIPHER_CTX_buf_noconst(ctx), &num,
-+                              dat->block);
-+    EVP_CIPHER_CTX_set_num(ctx, num);
-+    return 1;
-+}
-+
-+BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0)
-+    BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0)
-+    BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0)
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_cast.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_cast.c
-new file mode 100644
-index 0000000..259d440
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_cast.c
-@@ -0,0 +1,40 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_CAST
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+# include 
-+
-+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                         const unsigned char *iv, int enc);
-+
-+typedef struct {
-+    CAST_KEY ks;
-+} EVP_CAST_KEY;
-+
-+# define data(ctx)       EVP_C_DATA(EVP_CAST_KEY,ctx)
-+
-+IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY,
-+                       NID_cast5, 8, CAST_KEY_LENGTH, 8, 64,
-+                       EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL,
-+                       EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
-+
-+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                         const unsigned char *iv, int enc)
-+{
-+    CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
-+    return 1;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_chacha20_poly1305.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_chacha20_poly1305.c
-new file mode 100644
-index 0000000..7fd4f8d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_chacha20_poly1305.c
-@@ -0,0 +1,454 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_CHACHA
-+
-+# include 
-+# include 
-+# include "evp_locl.h"
-+# include "internal/evp_int.h"
-+# include "internal/chacha.h"
-+
-+typedef struct {
-+    union {
-+        double align;   /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */
-+        unsigned int d[CHACHA_KEY_SIZE / 4];
-+    } key;
-+    unsigned int  counter[CHACHA_CTR_SIZE / 4];
-+    unsigned char buf[CHACHA_BLK_SIZE];
-+    unsigned int  partial_len;
-+} EVP_CHACHA_KEY;
-+
-+#define data(ctx)   ((EVP_CHACHA_KEY *)(ctx)->cipher_data)
-+
-+static int chacha_init_key(EVP_CIPHER_CTX *ctx,
-+                           const unsigned char user_key[CHACHA_KEY_SIZE],
-+                           const unsigned char iv[CHACHA_CTR_SIZE], int enc)
-+{
-+    EVP_CHACHA_KEY *key = data(ctx);
-+    unsigned int i;
-+
-+    if (user_key)
-+        for (i = 0; i < CHACHA_KEY_SIZE; i+=4) {
-+            key->key.d[i/4] = CHACHA_U8TOU32(user_key+i);
-+        }
-+
-+    if (iv)
-+        for (i = 0; i < CHACHA_CTR_SIZE; i+=4) {
-+            key->counter[i/4] = CHACHA_U8TOU32(iv+i);
-+        }
-+
-+    key->partial_len = 0;
-+
-+    return 1;
-+}
-+
-+static int chacha_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out,
-+                         const unsigned char *inp, size_t len)
-+{
-+    EVP_CHACHA_KEY *key = data(ctx);
-+    unsigned int n, rem, ctr32;
-+
-+    if ((n = key->partial_len)) {
-+        while (len && n < CHACHA_BLK_SIZE) {
-+            *out++ = *inp++ ^ key->buf[n++];
-+            len--;
-+        }
-+        key->partial_len = n;
-+
-+        if (len == 0)
-+            return 1;
-+
-+        if (n == CHACHA_BLK_SIZE) {
-+            key->partial_len = 0;
-+            key->counter[0]++;
-+            if (key->counter[0] == 0)
-+                key->counter[1]++;
-+        }
-+    }
-+
-+    rem = (unsigned int)(len % CHACHA_BLK_SIZE);
-+    len -= rem;
-+    ctr32 = key->counter[0];
-+    while (len >= CHACHA_BLK_SIZE) {
-+        size_t blocks = len / CHACHA_BLK_SIZE;
-+        /*
-+         * 1<<28 is just a not-so-small yet not-so-large number...
-+         * Below condition is practically never met, but it has to
-+         * be checked for code correctness.
-+         */
-+        if (sizeof(size_t)>sizeof(unsigned int) && blocks>(1U<<28))
-+            blocks = (1U<<28);
-+
-+        /*
-+         * As ChaCha20_ctr32 operates on 32-bit counter, caller
-+         * has to handle overflow. 'if' below detects the
-+         * overflow, which is then handled by limiting the
-+         * amount of blocks to the exact overflow point...
-+         */
-+        ctr32 += (unsigned int)blocks;
-+        if (ctr32 < blocks) {
-+            blocks -= ctr32;
-+            ctr32 = 0;
-+        }
-+        blocks *= CHACHA_BLK_SIZE;
-+        ChaCha20_ctr32(out, inp, blocks, key->key.d, key->counter);
-+        len -= blocks;
-+        inp += blocks;
-+        out += blocks;
-+
-+        key->counter[0] = ctr32;
-+        if (ctr32 == 0) key->counter[1]++;
-+    }
-+
-+    if (rem) {
-+        memset(key->buf, 0, sizeof(key->buf));
-+        ChaCha20_ctr32(key->buf, key->buf, CHACHA_BLK_SIZE,
-+                       key->key.d, key->counter);
-+        for (n = 0; n < rem; n++)
-+            out[n] = inp[n] ^ key->buf[n];
-+        key->partial_len = rem;
-+    }
-+
-+    return 1;
-+}
-+
-+static const EVP_CIPHER chacha20 = {
-+    NID_chacha20,
-+    1,                      /* block_size */
-+    CHACHA_KEY_SIZE,        /* key_len */
-+    CHACHA_CTR_SIZE,        /* iv_len, 128-bit counter in the context */
-+    EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT,
-+    chacha_init_key,
-+    chacha_cipher,
-+    NULL,
-+    sizeof(EVP_CHACHA_KEY),
-+    NULL,
-+    NULL,
-+    NULL,
-+    NULL
-+};
-+
-+const EVP_CIPHER *EVP_chacha20(void)
-+{
-+    return (&chacha20);
-+}
-+
-+# ifndef OPENSSL_NO_POLY1305
-+#  include "internal/poly1305.h"
-+
-+typedef struct {
-+    EVP_CHACHA_KEY key;
-+    unsigned int nonce[12/4];
-+    unsigned char tag[POLY1305_BLOCK_SIZE];
-+    struct { uint64_t aad, text; } len;
-+    int aad, mac_inited, tag_len, nonce_len;
-+    size_t tls_payload_length;
-+} EVP_CHACHA_AEAD_CTX;
-+
-+#  define NO_TLS_PAYLOAD_LENGTH ((size_t)-1)
-+#  define aead_data(ctx)        ((EVP_CHACHA_AEAD_CTX *)(ctx)->cipher_data)
-+#  define POLY1305_ctx(actx)    ((POLY1305 *)(actx + 1))
-+
-+static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
-+                                      const unsigned char *inkey,
-+                                      const unsigned char *iv, int enc)
-+{
-+    EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
-+
-+    if (!inkey && !iv)
-+        return 1;
-+
-+    actx->len.aad = 0;
-+    actx->len.text = 0;
-+    actx->aad = 0;
-+    actx->mac_inited = 0;
-+    actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
-+
-+    if (iv != NULL) {
-+        unsigned char temp[CHACHA_CTR_SIZE] = { 0 };
-+
-+        /* pad on the left */
-+        if (actx->nonce_len <= CHACHA_CTR_SIZE)
-+            memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv, actx->nonce_len);
-+
-+        chacha_init_key(ctx, inkey, temp, enc);
-+
-+        actx->nonce[0] = actx->key.counter[1];
-+        actx->nonce[1] = actx->key.counter[2];
-+        actx->nonce[2] = actx->key.counter[3];
-+    } else {
-+        chacha_init_key(ctx, inkey, NULL, enc);
-+    }
-+
-+    return 1;
-+}
-+
-+static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                                    const unsigned char *in, size_t len)
-+{
-+    EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
-+    size_t rem, plen = actx->tls_payload_length;
-+    static const unsigned char zero[POLY1305_BLOCK_SIZE] = { 0 };
-+
-+    if (!actx->mac_inited) {
-+        actx->key.counter[0] = 0;
-+        memset(actx->key.buf, 0, sizeof(actx->key.buf));
-+        ChaCha20_ctr32(actx->key.buf, actx->key.buf, CHACHA_BLK_SIZE,
-+                       actx->key.key.d, actx->key.counter);
-+        Poly1305_Init(POLY1305_ctx(actx), actx->key.buf);
-+        actx->key.counter[0] = 1;
-+        actx->key.partial_len = 0;
-+        actx->len.aad = actx->len.text = 0;
-+        actx->mac_inited = 1;
-+    }
-+
-+    if (in) {                                   /* aad or text */
-+        if (out == NULL) {                      /* aad */
-+            Poly1305_Update(POLY1305_ctx(actx), in, len);
-+            actx->len.aad += len;
-+            actx->aad = 1;
-+            return len;
-+        } else {                                /* plain- or ciphertext */
-+            if (actx->aad) {                    /* wrap up aad */
-+                if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
-+                    Poly1305_Update(POLY1305_ctx(actx), zero,
-+                                    POLY1305_BLOCK_SIZE - rem);
-+                actx->aad = 0;
-+            }
-+
-+            actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
-+            if (plen == NO_TLS_PAYLOAD_LENGTH)
-+                plen = len;
-+            else if (len != plen + POLY1305_BLOCK_SIZE)
-+                return -1;
-+
-+            if (ctx->encrypt) {                 /* plaintext */
-+                chacha_cipher(ctx, out, in, plen);
-+                Poly1305_Update(POLY1305_ctx(actx), out, plen);
-+                in += plen;
-+                out += plen;
-+                actx->len.text += plen;
-+            } else {                            /* ciphertext */
-+                Poly1305_Update(POLY1305_ctx(actx), in, plen);
-+                chacha_cipher(ctx, out, in, plen);
-+                in += plen;
-+                out += plen;
-+                actx->len.text += plen;
-+            }
-+        }
-+    }
-+    if (in == NULL                              /* explicit final */
-+        || plen != len) {                       /* or tls mode */
-+        const union {
-+            long one;
-+            char little;
-+        } is_endian = { 1 };
-+        unsigned char temp[POLY1305_BLOCK_SIZE];
-+
-+        if (actx->aad) {                        /* wrap up aad */
-+            if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
-+                Poly1305_Update(POLY1305_ctx(actx), zero,
-+                                POLY1305_BLOCK_SIZE - rem);
-+            actx->aad = 0;
-+        }
-+
-+        if ((rem = (size_t)actx->len.text % POLY1305_BLOCK_SIZE))
-+            Poly1305_Update(POLY1305_ctx(actx), zero,
-+                            POLY1305_BLOCK_SIZE - rem);
-+
-+        if (is_endian.little) {
-+            Poly1305_Update(POLY1305_ctx(actx),
-+                            (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE);
-+        } else {
-+            temp[0]  = (unsigned char)(actx->len.aad);
-+            temp[1]  = (unsigned char)(actx->len.aad>>8);
-+            temp[2]  = (unsigned char)(actx->len.aad>>16);
-+            temp[3]  = (unsigned char)(actx->len.aad>>24);
-+            temp[4]  = (unsigned char)(actx->len.aad>>32);
-+            temp[5]  = (unsigned char)(actx->len.aad>>40);
-+            temp[6]  = (unsigned char)(actx->len.aad>>48);
-+            temp[7]  = (unsigned char)(actx->len.aad>>56);
-+
-+            temp[8]  = (unsigned char)(actx->len.text);
-+            temp[9]  = (unsigned char)(actx->len.text>>8);
-+            temp[10] = (unsigned char)(actx->len.text>>16);
-+            temp[11] = (unsigned char)(actx->len.text>>24);
-+            temp[12] = (unsigned char)(actx->len.text>>32);
-+            temp[13] = (unsigned char)(actx->len.text>>40);
-+            temp[14] = (unsigned char)(actx->len.text>>48);
-+            temp[15] = (unsigned char)(actx->len.text>>56);
-+
-+            Poly1305_Update(POLY1305_ctx(actx), temp, POLY1305_BLOCK_SIZE);
-+        }
-+        Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag
-+                                                        : temp);
-+        actx->mac_inited = 0;
-+
-+        if (in != NULL && len != plen) {        /* tls mode */
-+            if (ctx->encrypt) {
-+                memcpy(out, actx->tag, POLY1305_BLOCK_SIZE);
-+            } else {
-+                if (CRYPTO_memcmp(temp, in, POLY1305_BLOCK_SIZE)) {
-+                    memset(out - plen, 0, plen);
-+                    return -1;
-+                }
-+            }
-+        }
-+        else if (!ctx->encrypt) {
-+            if (CRYPTO_memcmp(temp, actx->tag, actx->tag_len))
-+                return -1;
-+        }
-+    }
-+    return len;
-+}
-+
-+static int chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx)
-+{
-+    EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
-+    if (actx)
-+        OPENSSL_cleanse(ctx->cipher_data, sizeof(*actx) + Poly1305_ctx_size());
-+    return 1;
-+}
-+
-+static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
-+                                  void *ptr)
-+{
-+    EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
-+
-+    switch(type) {
-+    case EVP_CTRL_INIT:
-+        if (actx == NULL)
-+            actx = ctx->cipher_data
-+                 = OPENSSL_zalloc(sizeof(*actx) + Poly1305_ctx_size());
-+        if (actx == NULL) {
-+            EVPerr(EVP_F_CHACHA20_POLY1305_CTRL, EVP_R_INITIALIZATION_ERROR);
-+            return 0;
-+        }
-+        actx->len.aad = 0;
-+        actx->len.text = 0;
-+        actx->aad = 0;
-+        actx->mac_inited = 0;
-+        actx->tag_len = 0;
-+        actx->nonce_len = 12;
-+        actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
-+        return 1;
-+
-+    case EVP_CTRL_COPY:
-+        if (actx) {
-+            EVP_CIPHER_CTX *dst = (EVP_CIPHER_CTX *)ptr;
-+
-+            dst->cipher_data =
-+                   OPENSSL_memdup(actx, sizeof(*actx) + Poly1305_ctx_size());
-+            if (dst->cipher_data == NULL) {
-+                EVPerr(EVP_F_CHACHA20_POLY1305_CTRL, EVP_R_COPY_ERROR);
-+                return 0;
-+            }
-+        }
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_SET_IVLEN:
-+        if (arg <= 0 || arg > CHACHA_CTR_SIZE)
-+            return 0;
-+        actx->nonce_len = arg;
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_SET_IV_FIXED:
-+        if (arg != 12)
-+            return 0;
-+        actx->nonce[0] = actx->key.counter[1]
-+                       = CHACHA_U8TOU32((unsigned char *)ptr);
-+        actx->nonce[1] = actx->key.counter[2]
-+                       = CHACHA_U8TOU32((unsigned char *)ptr+4);
-+        actx->nonce[2] = actx->key.counter[3]
-+                       = CHACHA_U8TOU32((unsigned char *)ptr+8);
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_SET_TAG:
-+        if (arg <= 0 || arg > POLY1305_BLOCK_SIZE)
-+            return 0;
-+        if (ptr != NULL) {
-+            memcpy(actx->tag, ptr, arg);
-+            actx->tag_len = arg;
-+        }
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_GET_TAG:
-+        if (arg <= 0 || arg > POLY1305_BLOCK_SIZE || !ctx->encrypt)
-+            return 0;
-+        memcpy(ptr, actx->tag, arg);
-+        return 1;
-+
-+    case EVP_CTRL_AEAD_TLS1_AAD:
-+        if (arg != EVP_AEAD_TLS1_AAD_LEN)
-+            return 0;
-+        {
-+            unsigned int len;
-+            unsigned char *aad = ptr, temp[POLY1305_BLOCK_SIZE];
-+
-+            len = aad[EVP_AEAD_TLS1_AAD_LEN - 2] << 8 |
-+                  aad[EVP_AEAD_TLS1_AAD_LEN - 1];
-+            if (!ctx->encrypt) {
-+                if (len < POLY1305_BLOCK_SIZE)
-+                    return 0;
-+                len -= POLY1305_BLOCK_SIZE;     /* discount attached tag */
-+                memcpy(temp, aad, EVP_AEAD_TLS1_AAD_LEN - 2);
-+                aad = temp;
-+                temp[EVP_AEAD_TLS1_AAD_LEN - 2] = (unsigned char)(len >> 8);
-+                temp[EVP_AEAD_TLS1_AAD_LEN - 1] = (unsigned char)len;
-+            }
-+            actx->tls_payload_length = len;
-+
-+            /*
-+             * merge record sequence number as per RFC7905
-+             */
-+            actx->key.counter[1] = actx->nonce[0];
-+            actx->key.counter[2] = actx->nonce[1] ^ CHACHA_U8TOU32(aad);
-+            actx->key.counter[3] = actx->nonce[2] ^ CHACHA_U8TOU32(aad+4);
-+            actx->mac_inited = 0;
-+            chacha20_poly1305_cipher(ctx, NULL, aad, EVP_AEAD_TLS1_AAD_LEN);
-+            return POLY1305_BLOCK_SIZE;         /* tag length */
-+        }
-+
-+    case EVP_CTRL_AEAD_SET_MAC_KEY:
-+        /* no-op */
-+        return 1;
-+
-+    default:
-+        return -1;
-+    }
-+}
-+
-+static EVP_CIPHER chacha20_poly1305 = {
-+    NID_chacha20_poly1305,
-+    1,                  /* block_size */
-+    CHACHA_KEY_SIZE,    /* key_len */
-+    12,                 /* iv_len, 96-bit nonce in the context */
-+    EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV |
-+    EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
-+    EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER,
-+    chacha20_poly1305_init_key,
-+    chacha20_poly1305_cipher,
-+    chacha20_poly1305_cleanup,
-+    0,          /* 0 moves context-specific structure allocation to ctrl */
-+    NULL,       /* set_asn1_parameters */
-+    NULL,       /* get_asn1_parameters */
-+    chacha20_poly1305_ctrl,
-+    NULL        /* app_data */
-+};
-+
-+const EVP_CIPHER *EVP_chacha20_poly1305(void)
-+{
-+    return(&chacha20_poly1305);
-+}
-+# endif
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_des.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_des.c
-new file mode 100644
-index 0000000..9b2facf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_des.c
-@@ -0,0 +1,242 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#ifndef OPENSSL_NO_DES
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+# include 
-+# include 
-+
-+typedef struct {
-+    union {
-+        double align;
-+        DES_key_schedule ks;
-+    } ks;
-+    union {
-+        void (*cbc) (const void *, void *, size_t,
-+                     const DES_key_schedule *, unsigned char *);
-+    } stream;
-+} EVP_DES_KEY;
-+
-+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
-+/* ----------^^^ this is not a typo, just a way to detect that
-+ * assembler support was in general requested... */
-+#  include "sparc_arch.h"
-+
-+extern unsigned int OPENSSL_sparcv9cap_P[];
-+
-+#  define SPARC_DES_CAPABLE       (OPENSSL_sparcv9cap_P[1] & CFR_DES)
-+
-+void des_t4_key_expand(const void *key, DES_key_schedule *ks);
-+void des_t4_cbc_encrypt(const void *inp, void *out, size_t len,
-+                        const DES_key_schedule *ks, unsigned char iv[8]);
-+void des_t4_cbc_decrypt(const void *inp, void *out, size_t len,
-+                        const DES_key_schedule *ks, unsigned char iv[8]);
-+# endif
-+
-+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                        const unsigned char *iv, int enc);
-+static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
-+
-+/*
-+ * Because of various casts and different names can't use
-+ * IMPLEMENT_BLOCK_CIPHER
-+ */
-+
-+static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t inl)
-+{
-+    BLOCK_CIPHER_ecb_loop()
-+        DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i),
-+                        EVP_CIPHER_CTX_get_cipher_data(ctx),
-+                        EVP_CIPHER_CTX_encrypting(ctx));
-+    return 1;
-+}
-+
-+static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t inl)
-+{
-+    while (inl >= EVP_MAXCHUNK) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
-+                          EVP_CIPHER_CTX_get_cipher_data(ctx),
-+                          (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num);
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+        inl -= EVP_MAXCHUNK;
-+        in += EVP_MAXCHUNK;
-+        out += EVP_MAXCHUNK;
-+    }
-+    if (inl) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        DES_ofb64_encrypt(in, out, (long)inl,
-+                          EVP_CIPHER_CTX_get_cipher_data(ctx),
-+                          (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num);
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+    }
-+    return 1;
-+}
-+
-+static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                          const unsigned char *in, size_t inl)
-+{
-+    EVP_DES_KEY *dat = (EVP_DES_KEY *) EVP_CIPHER_CTX_get_cipher_data(ctx);
-+
-+    if (dat->stream.cbc != NULL) {
-+        (*dat->stream.cbc) (in, out, inl, &dat->ks.ks,
-+                            EVP_CIPHER_CTX_iv_noconst(ctx));
-+        return 1;
-+    }
-+    while (inl >= EVP_MAXCHUNK) {
-+        DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK,
-+                         EVP_CIPHER_CTX_get_cipher_data(ctx),
-+                         (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                         EVP_CIPHER_CTX_encrypting(ctx));
-+        inl -= EVP_MAXCHUNK;
-+        in += EVP_MAXCHUNK;
-+        out += EVP_MAXCHUNK;
-+    }
-+    if (inl)
-+        DES_ncbc_encrypt(in, out, (long)inl,
-+                         EVP_CIPHER_CTX_get_cipher_data(ctx),
-+                         (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                         EVP_CIPHER_CTX_encrypting(ctx));
-+    return 1;
-+}
-+
-+static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                            const unsigned char *in, size_t inl)
-+{
-+    while (inl >= EVP_MAXCHUNK) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
-+                          EVP_CIPHER_CTX_get_cipher_data(ctx),
-+                          (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num,
-+                          EVP_CIPHER_CTX_encrypting(ctx));
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+        inl -= EVP_MAXCHUNK;
-+        in += EVP_MAXCHUNK;
-+        out += EVP_MAXCHUNK;
-+    }
-+    if (inl) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        DES_cfb64_encrypt(in, out, (long)inl,
-+                          EVP_CIPHER_CTX_get_cipher_data(ctx),
-+                          (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num,
-+                          EVP_CIPHER_CTX_encrypting(ctx));
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+    }
-+    return 1;
-+}
-+
-+/*
-+ * Although we have a CFB-r implementation for DES, it doesn't pack the right
-+ * way, so wrap it here
-+ */
-+static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                           const unsigned char *in, size_t inl)
-+{
-+    size_t n, chunk = EVP_MAXCHUNK / 8;
-+    unsigned char c[1], d[1];
-+
-+    if (inl < chunk)
-+        chunk = inl;
-+
-+    while (inl && inl >= chunk) {
-+        for (n = 0; n < chunk * 8; ++n) {
-+            c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
-+            DES_cfb_encrypt(c, d, 1, 1, EVP_CIPHER_CTX_get_cipher_data(ctx),
-+                            (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                            EVP_CIPHER_CTX_encrypting(ctx));
-+            out[n / 8] =
-+                (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
-+                ((d[0] & 0x80) >> (unsigned int)(n % 8));
-+        }
-+        inl -= chunk;
-+        in += chunk;
-+        out += chunk;
-+        if (inl < chunk)
-+            chunk = inl;
-+    }
-+
-+    return 1;
-+}
-+
-+static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                           const unsigned char *in, size_t inl)
-+{
-+    while (inl >= EVP_MAXCHUNK) {
-+        DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK,
-+                        EVP_CIPHER_CTX_get_cipher_data(ctx),
-+                        (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                        EVP_CIPHER_CTX_encrypting(ctx));
-+        inl -= EVP_MAXCHUNK;
-+        in += EVP_MAXCHUNK;
-+        out += EVP_MAXCHUNK;
-+    }
-+    if (inl)
-+        DES_cfb_encrypt(in, out, 8, (long)inl,
-+                        EVP_CIPHER_CTX_get_cipher_data(ctx),
-+                        (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                        EVP_CIPHER_CTX_encrypting(ctx));
-+    return 1;
-+}
-+
-+BLOCK_CIPHER_defs(des, EVP_DES_KEY, NID_des, 8, 8, 8, 64,
-+                  EVP_CIPH_RAND_KEY, des_init_key, NULL,
-+                  EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
-+
-+    BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 1,
-+                     EVP_CIPH_RAND_KEY, des_init_key, NULL,
-+                     EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
-+
-+    BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 8,
-+                     EVP_CIPH_RAND_KEY, des_init_key, NULL,
-+                     EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
-+
-+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                        const unsigned char *iv, int enc)
-+{
-+    DES_cblock *deskey = (DES_cblock *)key;
-+    EVP_DES_KEY *dat = (EVP_DES_KEY *) EVP_CIPHER_CTX_get_cipher_data(ctx);
-+
-+    dat->stream.cbc = NULL;
-+# if defined(SPARC_DES_CAPABLE)
-+    if (SPARC_DES_CAPABLE) {
-+        int mode = EVP_CIPHER_CTX_mode(ctx);
-+
-+        if (mode == EVP_CIPH_CBC_MODE) {
-+            des_t4_key_expand(key, &dat->ks.ks);
-+            dat->stream.cbc = enc ? des_t4_cbc_encrypt : des_t4_cbc_decrypt;
-+            return 1;
-+        }
-+    }
-+# endif
-+    DES_set_key_unchecked(deskey, EVP_CIPHER_CTX_get_cipher_data(ctx));
-+    return 1;
-+}
-+
-+static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
-+{
-+
-+    switch (type) {
-+    case EVP_CTRL_RAND_KEY:
-+        if (RAND_bytes(ptr, 8) <= 0)
-+            return 0;
-+        DES_set_odd_parity((DES_cblock *)ptr);
-+        return 1;
-+
-+    default:
-+        return -1;
-+    }
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_des3.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_des3.c
-new file mode 100644
-index 0000000..da77936
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_des3.c
-@@ -0,0 +1,424 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#ifndef OPENSSL_NO_DES
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+# include 
-+# include 
-+# include "evp_locl.h"
-+
-+typedef struct {
-+    union {
-+        double align;
-+        DES_key_schedule ks[3];
-+    } ks;
-+    union {
-+        void (*cbc) (const void *, void *, size_t,
-+                     const DES_key_schedule *, unsigned char *);
-+    } stream;
-+} DES_EDE_KEY;
-+# define ks1 ks.ks[0]
-+# define ks2 ks.ks[1]
-+# define ks3 ks.ks[2]
-+
-+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
-+/* ---------^^^ this is not a typo, just a way to detect that
-+ * assembler support was in general requested... */
-+#  include "sparc_arch.h"
-+
-+extern unsigned int OPENSSL_sparcv9cap_P[];
-+
-+#  define SPARC_DES_CAPABLE       (OPENSSL_sparcv9cap_P[1] & CFR_DES)
-+
-+void des_t4_key_expand(const void *key, DES_key_schedule *ks);
-+void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len,
-+                             const DES_key_schedule ks[3], unsigned char iv[8]);
-+void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len,
-+                             const DES_key_schedule ks[3], unsigned char iv[8]);
-+# endif
-+
-+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                            const unsigned char *iv, int enc);
-+
-+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                             const unsigned char *iv, int enc);
-+
-+static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
-+
-+# define data(ctx) EVP_C_DATA(DES_EDE_KEY,ctx)
-+
-+/*
-+ * Because of various casts and different args can't use
-+ * IMPLEMENT_BLOCK_CIPHER
-+ */
-+
-+static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t inl)
-+{
-+    BLOCK_CIPHER_ecb_loop()
-+        DES_ecb3_encrypt((const_DES_cblock *)(in + i),
-+                         (DES_cblock *)(out + i),
-+                         &data(ctx)->ks1, &data(ctx)->ks2,
-+                         &data(ctx)->ks3, EVP_CIPHER_CTX_encrypting(ctx));
-+    return 1;
-+}
-+
-+static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t inl)
-+{
-+    while (inl >= EVP_MAXCHUNK) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
-+                               &data(ctx)->ks1, &data(ctx)->ks2,
-+                               &data(ctx)->ks3,
-+                               (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                               &num);
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+        inl -= EVP_MAXCHUNK;
-+        in += EVP_MAXCHUNK;
-+        out += EVP_MAXCHUNK;
-+    }
-+    if (inl) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        DES_ede3_ofb64_encrypt(in, out, (long)inl,
-+                               &data(ctx)->ks1, &data(ctx)->ks2,
-+                               &data(ctx)->ks3,
-+                               (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                               &num);
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+    }
-+    return 1;
-+}
-+
-+static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                              const unsigned char *in, size_t inl)
-+{
-+    DES_EDE_KEY *dat = data(ctx);
-+
-+    if (dat->stream.cbc != NULL) {
-+        (*dat->stream.cbc) (in, out, inl, dat->ks.ks,
-+                            EVP_CIPHER_CTX_iv_noconst(ctx));
-+        return 1;
-+    }
-+
-+    while (inl >= EVP_MAXCHUNK) {
-+        DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
-+                             &dat->ks1, &dat->ks2, &dat->ks3,
-+                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                             EVP_CIPHER_CTX_encrypting(ctx));
-+        inl -= EVP_MAXCHUNK;
-+        in += EVP_MAXCHUNK;
-+        out += EVP_MAXCHUNK;
-+    }
-+    if (inl)
-+        DES_ede3_cbc_encrypt(in, out, (long)inl,
-+                             &dat->ks1, &dat->ks2, &dat->ks3,
-+                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                             EVP_CIPHER_CTX_encrypting(ctx));
-+    return 1;
-+}
-+
-+static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                                const unsigned char *in, size_t inl)
-+{
-+    while (inl >= EVP_MAXCHUNK) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
-+                               &data(ctx)->ks1, &data(ctx)->ks2,
-+                               &data(ctx)->ks3,
-+                               (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                               &num, EVP_CIPHER_CTX_encrypting(ctx));
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+        inl -= EVP_MAXCHUNK;
-+        in += EVP_MAXCHUNK;
-+        out += EVP_MAXCHUNK;
-+    }
-+    if (inl) {
-+        int num = EVP_CIPHER_CTX_num(ctx);
-+        DES_ede3_cfb64_encrypt(in, out, (long)inl,
-+                               &data(ctx)->ks1, &data(ctx)->ks2,
-+                               &data(ctx)->ks3,
-+                               (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                               &num, EVP_CIPHER_CTX_encrypting(ctx));
-+        EVP_CIPHER_CTX_set_num(ctx, num);
-+    }
-+    return 1;
-+}
-+
-+/*
-+ * Although we have a CFB-r implementation for 3-DES, it doesn't pack the
-+ * right way, so wrap it here
-+ */
-+static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                                const unsigned char *in, size_t inl)
-+{
-+    size_t n;
-+    unsigned char c[1], d[1];
-+
-+    if (!EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
-+            inl *= 8;
-+    for (n = 0; n < inl; ++n) {
-+        c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
-+        DES_ede3_cfb_encrypt(c, d, 1, 1,
-+                             &data(ctx)->ks1, &data(ctx)->ks2,
-+                             &data(ctx)->ks3,
-+                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                             EVP_CIPHER_CTX_encrypting(ctx));
-+        out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8)))
-+            | ((d[0] & 0x80) >> (unsigned int)(n % 8));
-+    }
-+
-+    return 1;
-+}
-+
-+static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                                const unsigned char *in, size_t inl)
-+{
-+    while (inl >= EVP_MAXCHUNK) {
-+        DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK,
-+                             &data(ctx)->ks1, &data(ctx)->ks2,
-+                             &data(ctx)->ks3,
-+                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                             EVP_CIPHER_CTX_encrypting(ctx));
-+        inl -= EVP_MAXCHUNK;
-+        in += EVP_MAXCHUNK;
-+        out += EVP_MAXCHUNK;
-+    }
-+    if (inl)
-+        DES_ede3_cfb_encrypt(in, out, 8, (long)inl,
-+                             &data(ctx)->ks1, &data(ctx)->ks2,
-+                             &data(ctx)->ks3,
-+                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                             EVP_CIPHER_CTX_encrypting(ctx));
-+    return 1;
-+}
-+
-+BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
-+                  EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1,
-+                  des_ede_init_key, NULL, NULL, NULL, des3_ctrl)
-+# define des_ede3_cfb64_cipher des_ede_cfb64_cipher
-+# define des_ede3_ofb_cipher des_ede_ofb_cipher
-+# define des_ede3_cbc_cipher des_ede_cbc_cipher
-+# define des_ede3_ecb_cipher des_ede_ecb_cipher
-+    BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
-+                  EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1,
-+                  des_ede3_init_key, NULL, NULL, NULL, des3_ctrl)
-+
-+    BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1,
-+                     EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1,
-+                     des_ede3_init_key, NULL, NULL, NULL, des3_ctrl)
-+
-+    BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8,
-+                     EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1,
-+                     des_ede3_init_key, NULL, NULL, NULL, des3_ctrl)
-+
-+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                            const unsigned char *iv, int enc)
-+{
-+    DES_cblock *deskey = (DES_cblock *)key;
-+    DES_EDE_KEY *dat = data(ctx);
-+
-+    dat->stream.cbc = NULL;
-+# if defined(SPARC_DES_CAPABLE)
-+    if (SPARC_DES_CAPABLE) {
-+        int mode = EVP_CIPHER_CTX_mode(ctx);
-+
-+        if (mode == EVP_CIPH_CBC_MODE) {
-+            des_t4_key_expand(&deskey[0], &dat->ks1);
-+            des_t4_key_expand(&deskey[1], &dat->ks2);
-+            memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1));
-+            dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
-+                des_t4_ede3_cbc_decrypt;
-+            return 1;
-+        }
-+    }
-+# endif
-+    DES_set_key_unchecked(&deskey[0], &dat->ks1);
-+    DES_set_key_unchecked(&deskey[1], &dat->ks2);
-+    memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1));
-+    return 1;
-+}
-+
-+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                             const unsigned char *iv, int enc)
-+{
-+    DES_cblock *deskey = (DES_cblock *)key;
-+    DES_EDE_KEY *dat = data(ctx);
-+
-+    dat->stream.cbc = NULL;
-+# if defined(SPARC_DES_CAPABLE)
-+    if (SPARC_DES_CAPABLE) {
-+        int mode = EVP_CIPHER_CTX_mode(ctx);
-+
-+        if (mode == EVP_CIPH_CBC_MODE) {
-+            des_t4_key_expand(&deskey[0], &dat->ks1);
-+            des_t4_key_expand(&deskey[1], &dat->ks2);
-+            des_t4_key_expand(&deskey[2], &dat->ks3);
-+            dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
-+                des_t4_ede3_cbc_decrypt;
-+            return 1;
-+        }
-+    }
-+# endif
-+    DES_set_key_unchecked(&deskey[0], &dat->ks1);
-+    DES_set_key_unchecked(&deskey[1], &dat->ks2);
-+    DES_set_key_unchecked(&deskey[2], &dat->ks3);
-+    return 1;
-+}
-+
-+static int des3_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
-+{
-+
-+    DES_cblock *deskey = ptr;
-+
-+    switch (type) {
-+    case EVP_CTRL_RAND_KEY:
-+        if (RAND_bytes(ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0)
-+            return 0;
-+        DES_set_odd_parity(deskey);
-+        if (EVP_CIPHER_CTX_key_length(ctx) >= 16)
-+            DES_set_odd_parity(deskey + 1);
-+        if (EVP_CIPHER_CTX_key_length(ctx) >= 24)
-+            DES_set_odd_parity(deskey + 2);
-+        return 1;
-+
-+    default:
-+        return -1;
-+    }
-+}
-+
-+const EVP_CIPHER *EVP_des_ede(void)
-+{
-+    return &des_ede_ecb;
-+}
-+
-+const EVP_CIPHER *EVP_des_ede3(void)
-+{
-+    return &des_ede3_ecb;
-+}
-+
-+
-+# include 
-+
-+static const unsigned char wrap_iv[8] =
-+    { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 };
-+
-+static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                           const unsigned char *in, size_t inl)
-+{
-+    unsigned char icv[8], iv[8], sha1tmp[SHA_DIGEST_LENGTH];
-+    int rv = -1;
-+    if (inl < 24)
-+        return -1;
-+    if (out == NULL)
-+        return inl - 16;
-+    memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), wrap_iv, 8);
-+    /* Decrypt first block which will end up as icv */
-+    des_ede_cbc_cipher(ctx, icv, in, 8);
-+    /* Decrypt central blocks */
-+    /*
-+     * If decrypting in place move whole output along a block so the next
-+     * des_ede_cbc_cipher is in place.
-+     */
-+    if (out == in) {
-+        memmove(out, out + 8, inl - 8);
-+        in -= 8;
-+    }
-+    des_ede_cbc_cipher(ctx, out, in + 8, inl - 16);
-+    /* Decrypt final block which will be IV */
-+    des_ede_cbc_cipher(ctx, iv, in + inl - 8, 8);
-+    /* Reverse order of everything */
-+    BUF_reverse(icv, NULL, 8);
-+    BUF_reverse(out, NULL, inl - 16);
-+    BUF_reverse(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 8);
-+    /* Decrypt again using new IV */
-+    des_ede_cbc_cipher(ctx, out, out, inl - 16);
-+    des_ede_cbc_cipher(ctx, icv, icv, 8);
-+    /* Work out SHA1 hash of first portion */
-+    SHA1(out, inl - 16, sha1tmp);
-+
-+    if (!CRYPTO_memcmp(sha1tmp, icv, 8))
-+        rv = inl - 16;
-+    OPENSSL_cleanse(icv, 8);
-+    OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
-+    OPENSSL_cleanse(iv, 8);
-+    OPENSSL_cleanse(EVP_CIPHER_CTX_iv_noconst(ctx), 8);
-+    if (rv == -1)
-+        OPENSSL_cleanse(out, inl - 16);
-+
-+    return rv;
-+}
-+
-+static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                         const unsigned char *in, size_t inl)
-+{
-+    unsigned char sha1tmp[SHA_DIGEST_LENGTH];
-+    if (out == NULL)
-+        return inl + 16;
-+    /* Copy input to output buffer + 8 so we have space for IV */
-+    memmove(out + 8, in, inl);
-+    /* Work out ICV */
-+    SHA1(in, inl, sha1tmp);
-+    memcpy(out + inl + 8, sha1tmp, 8);
-+    OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
-+    /* Generate random IV */
-+    if (RAND_bytes(EVP_CIPHER_CTX_iv_noconst(ctx), 8) <= 0)
-+        return -1;
-+    memcpy(out, EVP_CIPHER_CTX_iv_noconst(ctx), 8);
-+    /* Encrypt everything after IV in place */
-+    des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8);
-+    BUF_reverse(out, NULL, inl + 16);
-+    memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), wrap_iv, 8);
-+    des_ede_cbc_cipher(ctx, out, out, inl + 16);
-+    return inl + 16;
-+}
-+
-+static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                                const unsigned char *in, size_t inl)
-+{
-+    /*
-+     * Sanity check input length: we typically only wrap keys so EVP_MAXCHUNK
-+     * is more than will ever be needed. Also input length must be a multiple
-+     * of 8 bits.
-+     */
-+    if (inl >= EVP_MAXCHUNK || inl % 8)
-+        return -1;
-+
-+    if (is_partially_overlapping(out, in, inl)) {
-+        EVPerr(EVP_F_DES_EDE3_WRAP_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
-+        return 0;
-+    }
-+
-+    if (EVP_CIPHER_CTX_encrypting(ctx))
-+        return des_ede3_wrap(ctx, out, in, inl);
-+    else
-+        return des_ede3_unwrap(ctx, out, in, inl);
-+}
-+
-+static const EVP_CIPHER des3_wrap = {
-+    NID_id_smime_alg_CMS3DESwrap,
-+    8, 24, 0,
-+    EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER
-+        | EVP_CIPH_FLAG_DEFAULT_ASN1,
-+    des_ede3_init_key, des_ede3_wrap_cipher,
-+    NULL,
-+    sizeof(DES_EDE_KEY),
-+    NULL, NULL, NULL, NULL
-+};
-+
-+const EVP_CIPHER *EVP_des_ede3_wrap(void)
-+{
-+    return &des3_wrap;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_idea.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_idea.c
-new file mode 100644
-index 0000000..93f6a41
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_idea.c
-@@ -0,0 +1,70 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_IDEA
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+# include 
-+
-+/* Can't use IMPLEMENT_BLOCK_CIPHER because IDEA_ecb_encrypt is different */
-+
-+typedef struct {
-+    IDEA_KEY_SCHEDULE ks;
-+} EVP_IDEA_KEY;
-+
-+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                         const unsigned char *iv, int enc);
-+
-+/*
-+ * NB IDEA_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a
-+ * special case
-+ */
-+
-+static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                           const unsigned char *in, size_t inl)
-+{
-+    BLOCK_CIPHER_ecb_loop()
-+        IDEA_ecb_encrypt(in + i, out + i, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks);
-+    return 1;
-+}
-+
-+BLOCK_CIPHER_func_cbc(idea, IDEA, EVP_IDEA_KEY, ks)
-+BLOCK_CIPHER_func_ofb(idea, IDEA, 64, EVP_IDEA_KEY, ks)
-+BLOCK_CIPHER_func_cfb(idea, IDEA, 64, EVP_IDEA_KEY, ks)
-+
-+BLOCK_CIPHER_defs(idea, IDEA_KEY_SCHEDULE, NID_idea, 8, 16, 8, 64,
-+                  0, idea_init_key, NULL,
-+                  EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
-+
-+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                         const unsigned char *iv, int enc)
-+{
-+    if (!enc) {
-+        if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
-+            enc = 1;
-+        else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE)
-+            enc = 1;
-+    }
-+    if (enc)
-+        IDEA_set_encrypt_key(key, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks);
-+    else {
-+        IDEA_KEY_SCHEDULE tmp;
-+
-+        IDEA_set_encrypt_key(key, &tmp);
-+        IDEA_set_decrypt_key(&tmp, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks);
-+        OPENSSL_cleanse((unsigned char *)&tmp, sizeof(IDEA_KEY_SCHEDULE));
-+    }
-+    return 1;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_null.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_null.c
-new file mode 100644
-index 0000000..0dfc48a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_null.c
-@@ -0,0 +1,50 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                         const unsigned char *iv, int enc);
-+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                       const unsigned char *in, size_t inl);
-+static const EVP_CIPHER n_cipher = {
-+    NID_undef,
-+    1, 0, 0, 0,
-+    null_init_key,
-+    null_cipher,
-+    NULL,
-+    0,
-+    NULL,
-+    NULL,
-+    NULL,
-+    NULL
-+};
-+
-+const EVP_CIPHER *EVP_enc_null(void)
-+{
-+    return (&n_cipher);
-+}
-+
-+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                         const unsigned char *iv, int enc)
-+{
-+    return 1;
-+}
-+
-+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                       const unsigned char *in, size_t inl)
-+{
-+    if (in != out)
-+        memcpy(out, in, inl);
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_old.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_old.c
-new file mode 100644
-index 0000000..927908f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_old.c
-@@ -0,0 +1,113 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#if OPENSSL_API_COMPAT >= 0x00908000L
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+
-+/*
-+ * Define some deprecated functions, so older programs don't crash and burn
-+ * too quickly.  On Windows and VMS, these will never be used, since
-+ * functions and variables in shared libraries are selected by entry point
-+ * location, not by name.
-+ */
-+
-+# ifndef OPENSSL_NO_BF
-+#  undef EVP_bf_cfb
-+const EVP_CIPHER *EVP_bf_cfb(void);
-+const EVP_CIPHER *EVP_bf_cfb(void)
-+{
-+    return EVP_bf_cfb64();
-+}
-+# endif
-+
-+# ifndef OPENSSL_NO_DES
-+#  undef EVP_des_cfb
-+const EVP_CIPHER *EVP_des_cfb(void);
-+const EVP_CIPHER *EVP_des_cfb(void)
-+{
-+    return EVP_des_cfb64();
-+}
-+
-+#  undef EVP_des_ede3_cfb
-+const EVP_CIPHER *EVP_des_ede3_cfb(void);
-+const EVP_CIPHER *EVP_des_ede3_cfb(void)
-+{
-+    return EVP_des_ede3_cfb64();
-+}
-+
-+#  undef EVP_des_ede_cfb
-+const EVP_CIPHER *EVP_des_ede_cfb(void);
-+const EVP_CIPHER *EVP_des_ede_cfb(void)
-+{
-+    return EVP_des_ede_cfb64();
-+}
-+# endif
-+
-+# ifndef OPENSSL_NO_IDEA
-+#  undef EVP_idea_cfb
-+const EVP_CIPHER *EVP_idea_cfb(void);
-+const EVP_CIPHER *EVP_idea_cfb(void)
-+{
-+    return EVP_idea_cfb64();
-+}
-+# endif
-+
-+# ifndef OPENSSL_NO_RC2
-+#  undef EVP_rc2_cfb
-+const EVP_CIPHER *EVP_rc2_cfb(void);
-+const EVP_CIPHER *EVP_rc2_cfb(void)
-+{
-+    return EVP_rc2_cfb64();
-+}
-+# endif
-+
-+# ifndef OPENSSL_NO_CAST
-+#  undef EVP_cast5_cfb
-+const EVP_CIPHER *EVP_cast5_cfb(void);
-+const EVP_CIPHER *EVP_cast5_cfb(void)
-+{
-+    return EVP_cast5_cfb64();
-+}
-+# endif
-+
-+# ifndef OPENSSL_NO_RC5
-+#  undef EVP_rc5_32_12_16_cfb
-+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void);
-+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void)
-+{
-+    return EVP_rc5_32_12_16_cfb64();
-+}
-+# endif
-+
-+# undef EVP_aes_128_cfb
-+const EVP_CIPHER *EVP_aes_128_cfb(void);
-+const EVP_CIPHER *EVP_aes_128_cfb(void)
-+{
-+    return EVP_aes_128_cfb128();
-+}
-+
-+# undef EVP_aes_192_cfb
-+const EVP_CIPHER *EVP_aes_192_cfb(void);
-+const EVP_CIPHER *EVP_aes_192_cfb(void)
-+{
-+    return EVP_aes_192_cfb128();
-+}
-+
-+# undef EVP_aes_256_cfb
-+const EVP_CIPHER *EVP_aes_256_cfb(void);
-+const EVP_CIPHER *EVP_aes_256_cfb(void)
-+{
-+    return EVP_aes_256_cfb128();
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc2.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc2.c
-new file mode 100644
-index 0000000..ed10bb3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc2.c
-@@ -0,0 +1,189 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_RC2
-+
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+# include 
-+
-+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                        const unsigned char *iv, int enc);
-+static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
-+static int rc2_magic_to_meth(int i);
-+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
-+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
-+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
-+
-+typedef struct {
-+    int key_bits;               /* effective key bits */
-+    RC2_KEY ks;                 /* key schedule */
-+} EVP_RC2_KEY;
-+
-+# define data(ctx)       EVP_C_DATA(EVP_RC2_KEY,ctx)
-+
-+IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2,
-+                       8,
-+                       RC2_KEY_LENGTH, 8, 64,
-+                       EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
-+                       rc2_init_key, NULL,
-+                       rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv,
-+                       rc2_ctrl)
-+# define RC2_40_MAGIC    0xa0
-+# define RC2_64_MAGIC    0x78
-+# define RC2_128_MAGIC   0x3a
-+static const EVP_CIPHER r2_64_cbc_cipher = {
-+    NID_rc2_64_cbc,
-+    8, 8 /* 64 bit */ , 8,
-+    EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
-+    rc2_init_key,
-+    rc2_cbc_cipher,
-+    NULL,
-+    sizeof(EVP_RC2_KEY),
-+    rc2_set_asn1_type_and_iv,
-+    rc2_get_asn1_type_and_iv,
-+    rc2_ctrl,
-+    NULL
-+};
-+
-+static const EVP_CIPHER r2_40_cbc_cipher = {
-+    NID_rc2_40_cbc,
-+    8, 5 /* 40 bit */ , 8,
-+    EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
-+    rc2_init_key,
-+    rc2_cbc_cipher,
-+    NULL,
-+    sizeof(EVP_RC2_KEY),
-+    rc2_set_asn1_type_and_iv,
-+    rc2_get_asn1_type_and_iv,
-+    rc2_ctrl,
-+    NULL
-+};
-+
-+const EVP_CIPHER *EVP_rc2_64_cbc(void)
-+{
-+    return (&r2_64_cbc_cipher);
-+}
-+
-+const EVP_CIPHER *EVP_rc2_40_cbc(void)
-+{
-+    return (&r2_40_cbc_cipher);
-+}
-+
-+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                        const unsigned char *iv, int enc)
-+{
-+    RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
-+                key, data(ctx)->key_bits);
-+    return 1;
-+}
-+
-+static int rc2_meth_to_magic(EVP_CIPHER_CTX *e)
-+{
-+    int i;
-+
-+    EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i);
-+    if (i == 128)
-+        return (RC2_128_MAGIC);
-+    else if (i == 64)
-+        return (RC2_64_MAGIC);
-+    else if (i == 40)
-+        return (RC2_40_MAGIC);
-+    else
-+        return (0);
-+}
-+
-+static int rc2_magic_to_meth(int i)
-+{
-+    if (i == RC2_128_MAGIC)
-+        return 128;
-+    else if (i == RC2_64_MAGIC)
-+        return 64;
-+    else if (i == RC2_40_MAGIC)
-+        return 40;
-+    else {
-+        EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE);
-+        return (0);
-+    }
-+}
-+
-+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
-+{
-+    long num = 0;
-+    int i = 0;
-+    int key_bits;
-+    unsigned int l;
-+    unsigned char iv[EVP_MAX_IV_LENGTH];
-+
-+    if (type != NULL) {
-+        l = EVP_CIPHER_CTX_iv_length(c);
-+        OPENSSL_assert(l <= sizeof(iv));
-+        i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l);
-+        if (i != (int)l)
-+            return -1;
-+        key_bits = rc2_magic_to_meth((int)num);
-+        if (!key_bits)
-+            return -1;
-+        if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
-+            return -1;
-+        EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
-+        if (EVP_CIPHER_CTX_set_key_length(c, key_bits / 8) <= 0)
-+            return -1;
-+    }
-+    return i;
-+}
-+
-+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
-+{
-+    long num;
-+    int i = 0, j;
-+
-+    if (type != NULL) {
-+        num = rc2_meth_to_magic(c);
-+        j = EVP_CIPHER_CTX_iv_length(c);
-+        i = ASN1_TYPE_set_int_octetstring(type, num,
-+                                          (unsigned char *)EVP_CIPHER_CTX_original_iv(c),
-+                                          j);
-+    }
-+    return (i);
-+}
-+
-+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
-+{
-+    switch (type) {
-+    case EVP_CTRL_INIT:
-+        data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
-+        return 1;
-+
-+    case EVP_CTRL_GET_RC2_KEY_BITS:
-+        *(int *)ptr = data(c)->key_bits;
-+        return 1;
-+
-+    case EVP_CTRL_SET_RC2_KEY_BITS:
-+        if (arg > 0) {
-+            data(c)->key_bits = arg;
-+            return 1;
-+        }
-+        return 0;
-+# ifdef PBE_PRF_TEST
-+    case EVP_CTRL_PBE_PRF_NID:
-+        *(int *)ptr = NID_hmacWithMD5;
-+        return 1;
-+# endif
-+
-+    default:
-+        return -1;
-+    }
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc4.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc4.c
-new file mode 100644
-index 0000000..ea95dea
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc4.c
-@@ -0,0 +1,82 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_RC4
-+
-+# include 
-+# include 
-+# include 
-+
-+# include "internal/evp_int.h"
-+
-+typedef struct {
-+    RC4_KEY ks;                 /* working key */
-+} EVP_RC4_KEY;
-+
-+# define data(ctx) ((EVP_RC4_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx))
-+
-+static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                        const unsigned char *iv, int enc);
-+static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                      const unsigned char *in, size_t inl);
-+static const EVP_CIPHER r4_cipher = {
-+    NID_rc4,
-+    1, EVP_RC4_KEY_SIZE, 0,
-+    EVP_CIPH_VARIABLE_LENGTH,
-+    rc4_init_key,
-+    rc4_cipher,
-+    NULL,
-+    sizeof(EVP_RC4_KEY),
-+    NULL,
-+    NULL,
-+    NULL,
-+    NULL
-+};
-+
-+static const EVP_CIPHER r4_40_cipher = {
-+    NID_rc4_40,
-+    1, 5 /* 40 bit */ , 0,
-+    EVP_CIPH_VARIABLE_LENGTH,
-+    rc4_init_key,
-+    rc4_cipher,
-+    NULL,
-+    sizeof(EVP_RC4_KEY),
-+    NULL,
-+    NULL,
-+    NULL,
-+    NULL
-+};
-+
-+const EVP_CIPHER *EVP_rc4(void)
-+{
-+    return (&r4_cipher);
-+}
-+
-+const EVP_CIPHER *EVP_rc4_40(void)
-+{
-+    return (&r4_40_cipher);
-+}
-+
-+static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                        const unsigned char *iv, int enc)
-+{
-+    RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
-+    return 1;
-+}
-+
-+static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                      const unsigned char *in, size_t inl)
-+{
-+    RC4(&data(ctx)->ks, inl, in, out);
-+    return 1;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc4_hmac_md5.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc4_hmac_md5.c
-new file mode 100644
-index 0000000..8ab18c1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc4_hmac_md5.c
-@@ -0,0 +1,262 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#include 
-+#include 
-+
-+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+
-+typedef struct {
-+    RC4_KEY ks;
-+    MD5_CTX head, tail, md;
-+    size_t payload_length;
-+} EVP_RC4_HMAC_MD5;
-+
-+# define NO_PAYLOAD_LENGTH       ((size_t)-1)
-+
-+void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out,
-+                 MD5_CTX *ctx, const void *inp, size_t blocks);
-+
-+# define data(ctx) ((EVP_RC4_HMAC_MD5 *)EVP_CIPHER_CTX_get_cipher_data(ctx))
-+
-+static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx,
-+                                 const unsigned char *inkey,
-+                                 const unsigned char *iv, int enc)
-+{
-+    EVP_RC4_HMAC_MD5 *key = data(ctx);
-+
-+    RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey);
-+
-+    MD5_Init(&key->head);       /* handy when benchmarking */
-+    key->tail = key->head;
-+    key->md = key->head;
-+
-+    key->payload_length = NO_PAYLOAD_LENGTH;
-+
-+    return 1;
-+}
-+
-+# if     defined(RC4_ASM) && defined(MD5_ASM) &&     (	   \
-+        defined(__x86_64)       || defined(__x86_64__)  || \
-+        defined(_M_AMD64)       || defined(_M_X64)      )
-+#  define STITCHED_CALL
-+# endif
-+
-+# if !defined(STITCHED_CALL)
-+#  define rc4_off 0
-+#  define md5_off 0
-+# endif
-+
-+static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                               const unsigned char *in, size_t len)
-+{
-+    EVP_RC4_HMAC_MD5 *key = data(ctx);
-+# if defined(STITCHED_CALL)
-+    size_t rc4_off = 32 - 1 - (key->ks.x & (32 - 1)), /* 32 is $MOD from
-+                                                       * rc4_md5-x86_64.pl */
-+        md5_off = MD5_CBLOCK - key->md.num, blocks;
-+    unsigned int l;
-+    extern unsigned int OPENSSL_ia32cap_P[];
-+# endif
-+    size_t plen = key->payload_length;
-+
-+    if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH))
-+        return 0;
-+
-+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
-+        if (plen == NO_PAYLOAD_LENGTH)
-+            plen = len;
-+# if defined(STITCHED_CALL)
-+        /* cipher has to "fall behind" */
-+        if (rc4_off > md5_off)
-+            md5_off += MD5_CBLOCK;
-+
-+        if (plen > md5_off && (blocks = (plen - md5_off) / MD5_CBLOCK) &&
-+            (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
-+            MD5_Update(&key->md, in, md5_off);
-+            RC4(&key->ks, rc4_off, in, out);
-+
-+            rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off,
-+                        &key->md, in + md5_off, blocks);
-+            blocks *= MD5_CBLOCK;
-+            rc4_off += blocks;
-+            md5_off += blocks;
-+            key->md.Nh += blocks >> 29;
-+            key->md.Nl += blocks <<= 3;
-+            if (key->md.Nl < (unsigned int)blocks)
-+                key->md.Nh++;
-+        } else {
-+            rc4_off = 0;
-+            md5_off = 0;
-+        }
-+# endif
-+        MD5_Update(&key->md, in + md5_off, plen - md5_off);
-+
-+        if (plen != len) {      /* "TLS" mode of operation */
-+            if (in != out)
-+                memcpy(out + rc4_off, in + rc4_off, plen - rc4_off);
-+
-+            /* calculate HMAC and append it to payload */
-+            MD5_Final(out + plen, &key->md);
-+            key->md = key->tail;
-+            MD5_Update(&key->md, out + plen, MD5_DIGEST_LENGTH);
-+            MD5_Final(out + plen, &key->md);
-+            /* encrypt HMAC at once */
-+            RC4(&key->ks, len - rc4_off, out + rc4_off, out + rc4_off);
-+        } else {
-+            RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off);
-+        }
-+    } else {
-+        unsigned char mac[MD5_DIGEST_LENGTH];
-+# if defined(STITCHED_CALL)
-+        /* digest has to "fall behind" */
-+        if (md5_off > rc4_off)
-+            rc4_off += 2 * MD5_CBLOCK;
-+        else
-+            rc4_off += MD5_CBLOCK;
-+
-+        if (len > rc4_off && (blocks = (len - rc4_off) / MD5_CBLOCK) &&
-+            (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
-+            RC4(&key->ks, rc4_off, in, out);
-+            MD5_Update(&key->md, out, md5_off);
-+
-+            rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off,
-+                        &key->md, out + md5_off, blocks);
-+            blocks *= MD5_CBLOCK;
-+            rc4_off += blocks;
-+            md5_off += blocks;
-+            l = (key->md.Nl + (blocks << 3)) & 0xffffffffU;
-+            if (l < key->md.Nl)
-+                key->md.Nh++;
-+            key->md.Nl = l;
-+            key->md.Nh += blocks >> 29;
-+        } else {
-+            md5_off = 0;
-+            rc4_off = 0;
-+        }
-+# endif
-+        /* decrypt HMAC at once */
-+        RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off);
-+        if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
-+            MD5_Update(&key->md, out + md5_off, plen - md5_off);
-+
-+            /* calculate HMAC and verify it */
-+            MD5_Final(mac, &key->md);
-+            key->md = key->tail;
-+            MD5_Update(&key->md, mac, MD5_DIGEST_LENGTH);
-+            MD5_Final(mac, &key->md);
-+
-+            if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH))
-+                return 0;
-+        } else {
-+            MD5_Update(&key->md, out + md5_off, len - md5_off);
-+        }
-+    }
-+
-+    key->payload_length = NO_PAYLOAD_LENGTH;
-+
-+    return 1;
-+}
-+
-+static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
-+                             void *ptr)
-+{
-+    EVP_RC4_HMAC_MD5 *key = data(ctx);
-+
-+    switch (type) {
-+    case EVP_CTRL_AEAD_SET_MAC_KEY:
-+        {
-+            unsigned int i;
-+            unsigned char hmac_key[64];
-+
-+            memset(hmac_key, 0, sizeof(hmac_key));
-+
-+            if (arg > (int)sizeof(hmac_key)) {
-+                MD5_Init(&key->head);
-+                MD5_Update(&key->head, ptr, arg);
-+                MD5_Final(hmac_key, &key->head);
-+            } else {
-+                memcpy(hmac_key, ptr, arg);
-+            }
-+
-+            for (i = 0; i < sizeof(hmac_key); i++)
-+                hmac_key[i] ^= 0x36; /* ipad */
-+            MD5_Init(&key->head);
-+            MD5_Update(&key->head, hmac_key, sizeof(hmac_key));
-+
-+            for (i = 0; i < sizeof(hmac_key); i++)
-+                hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
-+            MD5_Init(&key->tail);
-+            MD5_Update(&key->tail, hmac_key, sizeof(hmac_key));
-+
-+            OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
-+
-+            return 1;
-+        }
-+    case EVP_CTRL_AEAD_TLS1_AAD:
-+        {
-+            unsigned char *p = ptr;
-+            unsigned int len;
-+
-+            if (arg != EVP_AEAD_TLS1_AAD_LEN)
-+                return -1;
-+
-+            len = p[arg - 2] << 8 | p[arg - 1];
-+
-+            if (!EVP_CIPHER_CTX_encrypting(ctx)) {
-+                if (len < MD5_DIGEST_LENGTH)
-+                    return -1;
-+                len -= MD5_DIGEST_LENGTH;
-+                p[arg - 2] = len >> 8;
-+                p[arg - 1] = len;
-+            }
-+            key->payload_length = len;
-+            key->md = key->head;
-+            MD5_Update(&key->md, p, arg);
-+
-+            return MD5_DIGEST_LENGTH;
-+        }
-+    default:
-+        return -1;
-+    }
-+}
-+
-+static EVP_CIPHER r4_hmac_md5_cipher = {
-+# ifdef NID_rc4_hmac_md5
-+    NID_rc4_hmac_md5,
-+# else
-+    NID_undef,
-+# endif
-+    1, EVP_RC4_KEY_SIZE, 0,
-+    EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH |
-+        EVP_CIPH_FLAG_AEAD_CIPHER,
-+    rc4_hmac_md5_init_key,
-+    rc4_hmac_md5_cipher,
-+    NULL,
-+    sizeof(EVP_RC4_HMAC_MD5),
-+    NULL,
-+    NULL,
-+    rc4_hmac_md5_ctrl,
-+    NULL
-+};
-+
-+const EVP_CIPHER *EVP_rc4_hmac_md5(void)
-+{
-+    return (&r4_hmac_md5_cipher);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc5.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc5.c
-new file mode 100644
-index 0000000..f69ba5b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_rc5.c
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_RC5
-+
-+# include 
-+# include 
-+# include 
-+# include "evp_locl.h"
-+# include 
-+
-+static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                               const unsigned char *iv, int enc);
-+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
-+
-+typedef struct {
-+    int rounds;                 /* number of rounds */
-+    RC5_32_KEY ks;              /* key schedule */
-+} EVP_RC5_KEY;
-+
-+# define data(ctx)       EVP_C_DATA(EVP_RC5_KEY,ctx)
-+
-+IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, ks, RC5_32, EVP_RC5_KEY, NID_rc5,
-+                       8, RC5_32_KEY_LENGTH, 8, 64,
-+                       EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
-+                       r_32_12_16_init_key, NULL, NULL, NULL, rc5_ctrl)
-+
-+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
-+{
-+    switch (type) {
-+    case EVP_CTRL_INIT:
-+        data(c)->rounds = RC5_12_ROUNDS;
-+        return 1;
-+
-+    case EVP_CTRL_GET_RC5_ROUNDS:
-+        *(int *)ptr = data(c)->rounds;
-+        return 1;
-+
-+    case EVP_CTRL_SET_RC5_ROUNDS:
-+        switch (arg) {
-+        case RC5_8_ROUNDS:
-+        case RC5_12_ROUNDS:
-+        case RC5_16_ROUNDS:
-+            data(c)->rounds = arg;
-+            return 1;
-+
-+        default:
-+            EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS);
-+            return 0;
-+        }
-+
-+    default:
-+        return -1;
-+    }
-+}
-+
-+static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                               const unsigned char *iv, int enc)
-+{
-+    RC5_32_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
-+                   key, data(ctx)->rounds);
-+    return 1;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_seed.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_seed.c
-new file mode 100644
-index 0000000..40aec5f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_seed.c
-@@ -0,0 +1,39 @@
-+/*
-+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#ifdef OPENSSL_NO_SEED
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+
-+static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                         const unsigned char *iv, int enc);
-+
-+typedef struct {
-+    SEED_KEY_SCHEDULE ks;
-+} EVP_SEED_KEY;
-+
-+IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed,
-+                       16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1,
-+                       seed_init_key, 0, 0, 0, 0)
-+
-+static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                         const unsigned char *iv, int enc)
-+{
-+    SEED_set_key(key, &EVP_C_DATA(EVP_SEED_KEY,ctx)->ks);
-+    return 1;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_xcbc_d.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_xcbc_d.c
-new file mode 100644
-index 0000000..effaf5c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/e_xcbc_d.c
-@@ -0,0 +1,83 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_DES
-+
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+# include 
-+
-+static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                             const unsigned char *iv, int enc);
-+static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                           const unsigned char *in, size_t inl);
-+
-+typedef struct {
-+    DES_key_schedule ks;        /* key schedule */
-+    DES_cblock inw;
-+    DES_cblock outw;
-+} DESX_CBC_KEY;
-+
-+# define data(ctx) EVP_C_DATA(DESX_CBC_KEY,ctx)
-+
-+static const EVP_CIPHER d_xcbc_cipher = {
-+    NID_desx_cbc,
-+    8, 24, 8,
-+    EVP_CIPH_CBC_MODE,
-+    desx_cbc_init_key,
-+    desx_cbc_cipher,
-+    NULL,
-+    sizeof(DESX_CBC_KEY),
-+    EVP_CIPHER_set_asn1_iv,
-+    EVP_CIPHER_get_asn1_iv,
-+    NULL,
-+    NULL
-+};
-+
-+const EVP_CIPHER *EVP_desx_cbc(void)
-+{
-+    return (&d_xcbc_cipher);
-+}
-+
-+static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                             const unsigned char *iv, int enc)
-+{
-+    DES_cblock *deskey = (DES_cblock *)key;
-+
-+    DES_set_key_unchecked(deskey, &data(ctx)->ks);
-+    memcpy(&data(ctx)->inw[0], &key[8], 8);
-+    memcpy(&data(ctx)->outw[0], &key[16], 8);
-+
-+    return 1;
-+}
-+
-+static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                           const unsigned char *in, size_t inl)
-+{
-+    while (inl >= EVP_MAXCHUNK) {
-+        DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks,
-+                         (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                         &data(ctx)->inw, &data(ctx)->outw,
-+                         EVP_CIPHER_CTX_encrypting(ctx));
-+        inl -= EVP_MAXCHUNK;
-+        in += EVP_MAXCHUNK;
-+        out += EVP_MAXCHUNK;
-+    }
-+    if (inl)
-+        DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks,
-+                         (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
-+                         &data(ctx)->inw, &data(ctx)->outw,
-+                         EVP_CIPHER_CTX_encrypting(ctx));
-+    return 1;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/encode.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/encode.c
-new file mode 100644
-index 0000000..abb1044
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/encode.c
-@@ -0,0 +1,404 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "evp_locl.h"
-+
-+static unsigned char conv_ascii2bin(unsigned char a);
-+#ifndef CHARSET_EBCDIC
-+# define conv_bin2ascii(a)       (data_bin2ascii[(a)&0x3f])
-+#else
-+/*
-+ * We assume that PEM encoded files are EBCDIC files (i.e., printable text
-+ * files). Convert them here while decoding. When encoding, output is EBCDIC
-+ * (text) format again. (No need for conversion in the conv_bin2ascii macro,
-+ * as the underlying textstring data_bin2ascii[] is already EBCDIC)
-+ */
-+# define conv_bin2ascii(a)       (data_bin2ascii[(a)&0x3f])
-+#endif
-+
-+/*-
-+ * 64 char lines
-+ * pad input with 0
-+ * left over chars are set to =
-+ * 1 byte  => xx==
-+ * 2 bytes => xxx=
-+ * 3 bytes => xxxx
-+ */
-+#define BIN_PER_LINE    (64/4*3)
-+#define CHUNKS_PER_LINE (64/4)
-+#define CHAR_PER_LINE   (64+1)
-+
-+static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
-+abcdefghijklmnopqrstuvwxyz0123456789+/";
-+
-+/*-
-+ * 0xF0 is a EOLN
-+ * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
-+ * 0xF2 is EOF
-+ * 0xE0 is ignore at start of line.
-+ * 0xFF is error
-+ */
-+
-+#define B64_EOLN                0xF0
-+#define B64_CR                  0xF1
-+#define B64_EOF                 0xF2
-+#define B64_WS                  0xE0
-+#define B64_ERROR               0xFF
-+#define B64_NOT_BASE64(a)       (((a)|0x13) == 0xF3)
-+#define B64_BASE64(a)           (!B64_NOT_BASE64(a))
-+
-+static const unsigned char data_ascii2bin[128] = {
-+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
-+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
-+    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
-+    0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
-+    0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
-+    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
-+    0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
-+    0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+    0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
-+    0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
-+    0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
-+    0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-+};
-+
-+#ifndef CHARSET_EBCDIC
-+static unsigned char conv_ascii2bin(unsigned char a)
-+{
-+    if (a & 0x80)
-+        return B64_ERROR;
-+    return data_ascii2bin[a];
-+}
-+#else
-+static unsigned char conv_ascii2bin(unsigned char a)
-+{
-+    a = os_toascii[a];
-+    if (a & 0x80)
-+        return B64_ERROR;
-+    return data_ascii2bin[a];
-+}
-+#endif
-+
-+EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void)
-+{
-+    return OPENSSL_zalloc(sizeof(EVP_ENCODE_CTX));
-+}
-+
-+void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx)
-+{
-+    OPENSSL_free(ctx);
-+}
-+
-+int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx)
-+{
-+    memcpy(dctx, sctx, sizeof(EVP_ENCODE_CTX));
-+
-+    return 1;
-+}
-+
-+int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx)
-+{
-+    return ctx->num;
-+}
-+
-+void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
-+{
-+    ctx->length = 48;
-+    ctx->num = 0;
-+    ctx->line_num = 0;
-+}
-+
-+int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
-+                      const unsigned char *in, int inl)
-+{
-+    int i, j;
-+    size_t total = 0;
-+
-+    *outl = 0;
-+    if (inl <= 0)
-+        return 0;
-+    OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
-+    if (ctx->length - ctx->num > inl) {
-+        memcpy(&(ctx->enc_data[ctx->num]), in, inl);
-+        ctx->num += inl;
-+        return 1;
-+    }
-+    if (ctx->num != 0) {
-+        i = ctx->length - ctx->num;
-+        memcpy(&(ctx->enc_data[ctx->num]), in, i);
-+        in += i;
-+        inl -= i;
-+        j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
-+        ctx->num = 0;
-+        out += j;
-+        *(out++) = '\n';
-+        *out = '\0';
-+        total = j + 1;
-+    }
-+    while (inl >= ctx->length && total <= INT_MAX) {
-+        j = EVP_EncodeBlock(out, in, ctx->length);
-+        in += ctx->length;
-+        inl -= ctx->length;
-+        out += j;
-+        *(out++) = '\n';
-+        *out = '\0';
-+        total += j + 1;
-+    }
-+    if (total > INT_MAX) {
-+        /* Too much output data! */
-+        *outl = 0;
-+        return 0;
-+    }
-+    if (inl != 0)
-+        memcpy(&(ctx->enc_data[0]), in, inl);
-+    ctx->num = inl;
-+    *outl = total;
-+
-+    return 1;
-+}
-+
-+void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
-+{
-+    unsigned int ret = 0;
-+
-+    if (ctx->num != 0) {
-+        ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
-+        out[ret++] = '\n';
-+        out[ret] = '\0';
-+        ctx->num = 0;
-+    }
-+    *outl = ret;
-+}
-+
-+int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
-+{
-+    int i, ret = 0;
-+    unsigned long l;
-+
-+    for (i = dlen; i > 0; i -= 3) {
-+        if (i >= 3) {
-+            l = (((unsigned long)f[0]) << 16L) |
-+                (((unsigned long)f[1]) << 8L) | f[2];
-+            *(t++) = conv_bin2ascii(l >> 18L);
-+            *(t++) = conv_bin2ascii(l >> 12L);
-+            *(t++) = conv_bin2ascii(l >> 6L);
-+            *(t++) = conv_bin2ascii(l);
-+        } else {
-+            l = ((unsigned long)f[0]) << 16L;
-+            if (i == 2)
-+                l |= ((unsigned long)f[1] << 8L);
-+
-+            *(t++) = conv_bin2ascii(l >> 18L);
-+            *(t++) = conv_bin2ascii(l >> 12L);
-+            *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L);
-+            *(t++) = '=';
-+        }
-+        ret += 4;
-+        f += 3;
-+    }
-+
-+    *t = '\0';
-+    return (ret);
-+}
-+
-+void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
-+{
-+    /* Only ctx->num is used during decoding. */
-+    ctx->num = 0;
-+    ctx->length = 0;
-+    ctx->line_num = 0;
-+    ctx->expect_nl = 0;
-+}
-+
-+/*-
-+ * -1 for error
-+ *  0 for last line
-+ *  1 for full line
-+ *
-+ * Note: even though EVP_DecodeUpdate attempts to detect and report end of
-+ * content, the context doesn't currently remember it and will accept more data
-+ * in the next call. Therefore, the caller is responsible for checking and
-+ * rejecting a 0 return value in the middle of content.
-+ *
-+ * Note: even though EVP_DecodeUpdate has historically tried to detect end of
-+ * content based on line length, this has never worked properly. Therefore,
-+ * we now return 0 when one of the following is true:
-+ *   - Padding or B64_EOF was detected and the last block is complete.
-+ *   - Input has zero-length.
-+ * -1 is returned if:
-+ *   - Invalid characters are detected.
-+ *   - There is extra trailing padding, or data after padding.
-+ *   - B64_EOF is detected after an incomplete base64 block.
-+ */
-+int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
-+                     const unsigned char *in, int inl)
-+{
-+    int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len;
-+    unsigned char *d;
-+
-+    n = ctx->num;
-+    d = ctx->enc_data;
-+
-+    if (n > 0 && d[n - 1] == '=') {
-+        eof++;
-+        if (n > 1 && d[n - 2] == '=')
-+            eof++;
-+    }
-+
-+     /* Legacy behaviour: an empty input chunk signals end of input. */
-+    if (inl == 0) {
-+        rv = 0;
-+        goto end;
-+    }
-+
-+    for (i = 0; i < inl; i++) {
-+        tmp = *(in++);
-+        v = conv_ascii2bin(tmp);
-+        if (v == B64_ERROR) {
-+            rv = -1;
-+            goto end;
-+        }
-+
-+        if (tmp == '=') {
-+            eof++;
-+        } else if (eof > 0 && B64_BASE64(v)) {
-+            /* More data after padding. */
-+            rv = -1;
-+            goto end;
-+        }
-+
-+        if (eof > 2) {
-+            rv = -1;
-+            goto end;
-+        }
-+
-+        if (v == B64_EOF) {
-+            seof = 1;
-+            goto tail;
-+        }
-+
-+        /* Only save valid base64 characters. */
-+        if (B64_BASE64(v)) {
-+            if (n >= 64) {
-+                /*
-+                 * We increment n once per loop, and empty the buffer as soon as
-+                 * we reach 64 characters, so this can only happen if someone's
-+                 * manually messed with the ctx. Refuse to write any more data.
-+                 */
-+                rv = -1;
-+                goto end;
-+            }
-+            OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
-+            d[n++] = tmp;
-+        }
-+
-+        if (n == 64) {
-+            decoded_len = EVP_DecodeBlock(out, d, n);
-+            n = 0;
-+            if (decoded_len < 0 || eof > decoded_len) {
-+                rv = -1;
-+                goto end;
-+            }
-+            ret += decoded_len - eof;
-+            out += decoded_len - eof;
-+        }
-+    }
-+
-+    /*
-+     * Legacy behaviour: if the current line is a full base64-block (i.e., has
-+     * 0 mod 4 base64 characters), it is processed immediately. We keep this
-+     * behaviour as applications may not be calling EVP_DecodeFinal properly.
-+     */
-+tail:
-+    if (n > 0) {
-+        if ((n & 3) == 0) {
-+            decoded_len = EVP_DecodeBlock(out, d, n);
-+            n = 0;
-+            if (decoded_len < 0 || eof > decoded_len) {
-+                rv = -1;
-+                goto end;
-+            }
-+            ret += (decoded_len - eof);
-+        } else if (seof) {
-+            /* EOF in the middle of a base64 block. */
-+            rv = -1;
-+            goto end;
-+        }
-+    }
-+
-+    rv = seof || (n == 0 && eof) ? 0 : 1;
-+end:
-+    /* Legacy behaviour. This should probably rather be zeroed on error. */
-+    *outl = ret;
-+    ctx->num = n;
-+    return (rv);
-+}
-+
-+int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
-+{
-+    int i, ret = 0, a, b, c, d;
-+    unsigned long l;
-+
-+    /* trim white space from the start of the line. */
-+    while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) {
-+        f++;
-+        n--;
-+    }
-+
-+    /*
-+     * strip off stuff at the end of the line ascii2bin values B64_WS,
-+     * B64_EOLN, B64_EOLN and B64_EOF
-+     */
-+    while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1]))))
-+        n--;
-+
-+    if (n % 4 != 0)
-+        return (-1);
-+
-+    for (i = 0; i < n; i += 4) {
-+        a = conv_ascii2bin(*(f++));
-+        b = conv_ascii2bin(*(f++));
-+        c = conv_ascii2bin(*(f++));
-+        d = conv_ascii2bin(*(f++));
-+        if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80))
-+            return (-1);
-+        l = ((((unsigned long)a) << 18L) |
-+             (((unsigned long)b) << 12L) |
-+             (((unsigned long)c) << 6L) | (((unsigned long)d)));
-+        *(t++) = (unsigned char)(l >> 16L) & 0xff;
-+        *(t++) = (unsigned char)(l >> 8L) & 0xff;
-+        *(t++) = (unsigned char)(l) & 0xff;
-+        ret += 3;
-+    }
-+    return (ret);
-+}
-+
-+int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
-+{
-+    int i;
-+
-+    *outl = 0;
-+    if (ctx->num != 0) {
-+        i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
-+        if (i < 0)
-+            return (-1);
-+        ctx->num = 0;
-+        *outl = i;
-+        return (1);
-+    } else
-+        return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_cnf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_cnf.c
-new file mode 100644
-index 0000000..71d13b8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_cnf.c
-@@ -0,0 +1,65 @@
-+/*
-+ * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+/* Algorithm configuration module. */
-+
-+static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
-+{
-+    int i;
-+    const char *oid_section;
-+    STACK_OF(CONF_VALUE) *sktmp;
-+    CONF_VALUE *oval;
-+
-+    oid_section = CONF_imodule_get_value(md);
-+    if ((sktmp = NCONF_get_section(cnf, oid_section)) == NULL) {
-+        EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
-+        return 0;
-+    }
-+    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
-+        oval = sk_CONF_VALUE_value(sktmp, i);
-+        if (strcmp(oval->name, "fips_mode") == 0) {
-+            int m;
-+            if (!X509V3_get_value_bool(oval, &m)) {
-+                EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
-+                return 0;
-+            }
-+            if (m > 0) {
-+#ifdef OPENSSL_FIPS
-+                if (!FIPS_mode() && !FIPS_mode_set(1)) {
-+                    EVPerr(EVP_F_ALG_MODULE_INIT,
-+                           EVP_R_ERROR_SETTING_FIPS_MODE);
-+                    return 0;
-+                }
-+#else
-+                EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
-+                return 0;
-+#endif
-+            }
-+        } else {
-+            EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
-+            ERR_add_error_data(4, "name=", oval->name,
-+                               ", value=", oval->value);
-+        }
-+
-+    }
-+    return 1;
-+}
-+
-+void EVP_add_alg_module(void)
-+{
-+    CONF_module_add("alg_section", alg_module_init, 0);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_enc.c
-new file mode 100644
-index 0000000..f829e8d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_enc.c
-@@ -0,0 +1,641 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+#include "evp_locl.h"
-+
-+int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c)
-+{
-+    if (c == NULL)
-+        return 1;
-+    if (c->cipher != NULL) {
-+        if (c->cipher->cleanup && !c->cipher->cleanup(c))
-+            return 0;
-+        /* Cleanse cipher context data */
-+        if (c->cipher_data && c->cipher->ctx_size)
-+            OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
-+    }
-+    OPENSSL_free(c->cipher_data);
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(c->engine);
-+#endif
-+    memset(c, 0, sizeof(*c));
-+    return 1;
-+}
-+
-+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
-+{
-+    return OPENSSL_zalloc(sizeof(EVP_CIPHER_CTX));
-+}
-+
-+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
-+{
-+    EVP_CIPHER_CTX_reset(ctx);
-+    OPENSSL_free(ctx);
-+}
-+
-+int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
-+                   const unsigned char *key, const unsigned char *iv, int enc)
-+{
-+    EVP_CIPHER_CTX_reset(ctx);
-+    return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc);
-+}
-+
-+int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
-+                      ENGINE *impl, const unsigned char *key,
-+                      const unsigned char *iv, int enc)
-+{
-+    if (enc == -1)
-+        enc = ctx->encrypt;
-+    else {
-+        if (enc)
-+            enc = 1;
-+        ctx->encrypt = enc;
-+    }
-+#ifndef OPENSSL_NO_ENGINE
-+    /*
-+     * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
-+     * this context may already have an ENGINE! Try to avoid releasing the
-+     * previous handle, re-querying for an ENGINE, and having a
-+     * reinitialisation, when it may all be unnecessary.
-+     */
-+    if (ctx->engine && ctx->cipher
-+        && (cipher == NULL || cipher->nid == ctx->cipher->nid))
-+        goto skip_to_init;
-+#endif
-+    if (cipher) {
-+        /*
-+         * Ensure a context left lying around from last time is cleared (the
-+         * previous check attempted to avoid this if the same ENGINE and
-+         * EVP_CIPHER could be used).
-+         */
-+        if (ctx->cipher) {
-+            unsigned long flags = ctx->flags;
-+            EVP_CIPHER_CTX_reset(ctx);
-+            /* Restore encrypt and flags */
-+            ctx->encrypt = enc;
-+            ctx->flags = flags;
-+        }
-+#ifndef OPENSSL_NO_ENGINE
-+        if (impl) {
-+            if (!ENGINE_init(impl)) {
-+                EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-+                return 0;
-+            }
-+        } else
-+            /* Ask if an ENGINE is reserved for this job */
-+            impl = ENGINE_get_cipher_engine(cipher->nid);
-+        if (impl) {
-+            /* There's an ENGINE for this job ... (apparently) */
-+            const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
-+            if (!c) {
-+                /*
-+                 * One positive side-effect of US's export control history,
-+                 * is that we should at least be able to avoid using US
-+                 * misspellings of "initialisation"?
-+                 */
-+                EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-+                return 0;
-+            }
-+            /* We'll use the ENGINE's private cipher definition */
-+            cipher = c;
-+            /*
-+             * Store the ENGINE functional reference so we know 'cipher' came
-+             * from an ENGINE and we need to release it when done.
-+             */
-+            ctx->engine = impl;
-+        } else
-+            ctx->engine = NULL;
-+#endif
-+
-+        ctx->cipher = cipher;
-+        if (ctx->cipher->ctx_size) {
-+            ctx->cipher_data = OPENSSL_zalloc(ctx->cipher->ctx_size);
-+            if (ctx->cipher_data == NULL) {
-+                ctx->cipher = NULL;
-+                EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
-+                return 0;
-+            }
-+        } else {
-+            ctx->cipher_data = NULL;
-+        }
-+        ctx->key_len = cipher->key_len;
-+        /* Preserve wrap enable flag, zero everything else */
-+        ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
-+        if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
-+            if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
-+                ctx->cipher = NULL;
-+                EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-+                return 0;
-+            }
-+        }
-+    } else if (!ctx->cipher) {
-+        EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
-+        return 0;
-+    }
-+#ifndef OPENSSL_NO_ENGINE
-+ skip_to_init:
-+#endif
-+    /* we assume block size is a power of 2 in *cryptUpdate */
-+    OPENSSL_assert(ctx->cipher->block_size == 1
-+                   || ctx->cipher->block_size == 8
-+                   || ctx->cipher->block_size == 16);
-+
-+    if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW)
-+        && EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) {
-+        EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_WRAP_MODE_NOT_ALLOWED);
-+        return 0;
-+    }
-+
-+    if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_CUSTOM_IV)) {
-+        switch (EVP_CIPHER_CTX_mode(ctx)) {
-+
-+        case EVP_CIPH_STREAM_CIPHER:
-+        case EVP_CIPH_ECB_MODE:
-+            break;
-+
-+        case EVP_CIPH_CFB_MODE:
-+        case EVP_CIPH_OFB_MODE:
-+
-+            ctx->num = 0;
-+            /* fall-through */
-+
-+        case EVP_CIPH_CBC_MODE:
-+
-+            OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
-+                           (int)sizeof(ctx->iv));
-+            if (iv)
-+                memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-+            memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
-+            break;
-+
-+        case EVP_CIPH_CTR_MODE:
-+            ctx->num = 0;
-+            /* Don't reuse IV for CTR mode */
-+            if (iv)
-+                memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-+            break;
-+
-+        default:
-+            return 0;
-+        }
-+    }
-+
-+    if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
-+        if (!ctx->cipher->init(ctx, key, iv, enc))
-+            return 0;
-+    }
-+    ctx->buf_len = 0;
-+    ctx->final_used = 0;
-+    ctx->block_mask = ctx->cipher->block_size - 1;
-+    return 1;
-+}
-+
-+int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
-+                     const unsigned char *in, int inl)
-+{
-+    if (ctx->encrypt)
-+        return EVP_EncryptUpdate(ctx, out, outl, in, inl);
-+    else
-+        return EVP_DecryptUpdate(ctx, out, outl, in, inl);
-+}
-+
-+int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
-+{
-+    if (ctx->encrypt)
-+        return EVP_EncryptFinal_ex(ctx, out, outl);
-+    else
-+        return EVP_DecryptFinal_ex(ctx, out, outl);
-+}
-+
-+int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
-+{
-+    if (ctx->encrypt)
-+        return EVP_EncryptFinal(ctx, out, outl);
-+    else
-+        return EVP_DecryptFinal(ctx, out, outl);
-+}
-+
-+int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
-+                    const unsigned char *key, const unsigned char *iv)
-+{
-+    return EVP_CipherInit(ctx, cipher, key, iv, 1);
-+}
-+
-+int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
-+                       ENGINE *impl, const unsigned char *key,
-+                       const unsigned char *iv)
-+{
-+    return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
-+}
-+
-+int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
-+                    const unsigned char *key, const unsigned char *iv)
-+{
-+    return EVP_CipherInit(ctx, cipher, key, iv, 0);
-+}
-+
-+int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
-+                       ENGINE *impl, const unsigned char *key,
-+                       const unsigned char *iv)
-+{
-+    return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
-+}
-+
-+/*
-+ * According to the letter of standard difference between pointers
-+ * is specified to be valid only within same object. This makes
-+ * it formally challenging to determine if input and output buffers
-+ * are not partially overlapping with standard pointer arithmetic.
-+ */
-+#ifdef PTRDIFF_T
-+# undef PTRDIFF_T
-+#endif
-+#if defined(OPENSSL_SYS_VMS) && __INITIAL_POINTER_SIZE==64
-+/*
-+ * Then we have VMS that distinguishes itself by adhering to
-+ * sizeof(size_t)==4 even in 64-bit builds, which means that
-+ * difference between two pointers might be truncated to 32 bits.
-+ * In the context one can even wonder how comparison for
-+ * equality is implemented. To be on the safe side we adhere to
-+ * PTRDIFF_T even for comparison for equality.
-+ */
-+# define PTRDIFF_T uint64_t
-+#else
-+# define PTRDIFF_T size_t
-+#endif
-+
-+int is_partially_overlapping(const void *ptr1, const void *ptr2, int len)
-+{
-+    PTRDIFF_T diff = (PTRDIFF_T)ptr1-(PTRDIFF_T)ptr2;
-+    /*
-+     * Check for partially overlapping buffers. [Binary logical
-+     * operations are used instead of boolean to minimize number
-+     * of conditional branches.]
-+     */
-+    int overlapped = (len > 0) & (diff != 0) & ((diff < (PTRDIFF_T)len) |
-+                                                (diff > (0 - (PTRDIFF_T)len)));
-+
-+    return overlapped;
-+}
-+
-+int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
-+                      const unsigned char *in, int inl)
-+{
-+    int i, j, bl, cmpl = inl;
-+
-+    if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
-+        cmpl = (cmpl + 7) / 8;
-+
-+    bl = ctx->cipher->block_size;
-+
-+    if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
-+        /* If block size > 1 then the cipher will have to do this check */
-+        if (bl == 1 && is_partially_overlapping(out, in, cmpl)) {
-+            EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
-+            return 0;
-+        }
-+
-+        i = ctx->cipher->do_cipher(ctx, out, in, inl);
-+        if (i < 0)
-+            return 0;
-+        else
-+            *outl = i;
-+        return 1;
-+    }
-+
-+    if (inl <= 0) {
-+        *outl = 0;
-+        return inl == 0;
-+    }
-+    if (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) {
-+        EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
-+        return 0;
-+    }
-+
-+    if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) {
-+        if (ctx->cipher->do_cipher(ctx, out, in, inl)) {
-+            *outl = inl;
-+            return 1;
-+        } else {
-+            *outl = 0;
-+            return 0;
-+        }
-+    }
-+    i = ctx->buf_len;
-+    OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
-+    if (i != 0) {
-+        if (bl - i > inl) {
-+            memcpy(&(ctx->buf[i]), in, inl);
-+            ctx->buf_len += inl;
-+            *outl = 0;
-+            return 1;
-+        } else {
-+            j = bl - i;
-+            memcpy(&(ctx->buf[i]), in, j);
-+            inl -= j;
-+            in += j;
-+            if (!ctx->cipher->do_cipher(ctx, out, ctx->buf, bl))
-+                return 0;
-+            out += bl;
-+            *outl = bl;
-+        }
-+    } else
-+        *outl = 0;
-+    i = inl & (bl - 1);
-+    inl -= i;
-+    if (inl > 0) {
-+        if (!ctx->cipher->do_cipher(ctx, out, in, inl))
-+            return 0;
-+        *outl += inl;
-+    }
-+
-+    if (i != 0)
-+        memcpy(ctx->buf, &(in[inl]), i);
-+    ctx->buf_len = i;
-+    return 1;
-+}
-+
-+int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
-+{
-+    int ret;
-+    ret = EVP_EncryptFinal_ex(ctx, out, outl);
-+    return ret;
-+}
-+
-+int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
-+{
-+    int n, ret;
-+    unsigned int i, b, bl;
-+
-+    if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
-+        ret = ctx->cipher->do_cipher(ctx, out, NULL, 0);
-+        if (ret < 0)
-+            return 0;
-+        else
-+            *outl = ret;
-+        return 1;
-+    }
-+
-+    b = ctx->cipher->block_size;
-+    OPENSSL_assert(b <= sizeof ctx->buf);
-+    if (b == 1) {
-+        *outl = 0;
-+        return 1;
-+    }
-+    bl = ctx->buf_len;
-+    if (ctx->flags & EVP_CIPH_NO_PADDING) {
-+        if (bl) {
-+            EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,
-+                   EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
-+            return 0;
-+        }
-+        *outl = 0;
-+        return 1;
-+    }
-+
-+    n = b - bl;
-+    for (i = bl; i < b; i++)
-+        ctx->buf[i] = n;
-+    ret = ctx->cipher->do_cipher(ctx, out, ctx->buf, b);
-+
-+    if (ret)
-+        *outl = b;
-+
-+    return ret;
-+}
-+
-+int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
-+                      const unsigned char *in, int inl)
-+{
-+    int fix_len, cmpl = inl;
-+    unsigned int b;
-+
-+    b = ctx->cipher->block_size;
-+
-+    if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
-+        cmpl = (cmpl + 7) / 8;
-+
-+    if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
-+        if (b == 1 && is_partially_overlapping(out, in, cmpl)) {
-+            EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
-+            return 0;
-+        }
-+
-+        fix_len = ctx->cipher->do_cipher(ctx, out, in, inl);
-+        if (fix_len < 0) {
-+            *outl = 0;
-+            return 0;
-+        } else
-+            *outl = fix_len;
-+        return 1;
-+    }
-+
-+    if (inl <= 0) {
-+        *outl = 0;
-+        return inl == 0;
-+    }
-+
-+    if (ctx->flags & EVP_CIPH_NO_PADDING)
-+        return EVP_EncryptUpdate(ctx, out, outl, in, inl);
-+
-+    OPENSSL_assert(b <= sizeof ctx->final);
-+
-+    if (ctx->final_used) {
-+        /* see comment about PTRDIFF_T comparison above */
-+        if (((PTRDIFF_T)out == (PTRDIFF_T)in)
-+            || is_partially_overlapping(out, in, b)) {
-+            EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
-+            return 0;
-+        }
-+        memcpy(out, ctx->final, b);
-+        out += b;
-+        fix_len = 1;
-+    } else
-+        fix_len = 0;
-+
-+    if (!EVP_EncryptUpdate(ctx, out, outl, in, inl))
-+        return 0;
-+
-+    /*
-+     * if we have 'decrypted' a multiple of block size, make sure we have a
-+     * copy of this last block
-+     */
-+    if (b > 1 && !ctx->buf_len) {
-+        *outl -= b;
-+        ctx->final_used = 1;
-+        memcpy(ctx->final, &out[*outl], b);
-+    } else
-+        ctx->final_used = 0;
-+
-+    if (fix_len)
-+        *outl += b;
-+
-+    return 1;
-+}
-+
-+int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
-+{
-+    int ret;
-+    ret = EVP_DecryptFinal_ex(ctx, out, outl);
-+    return ret;
-+}
-+
-+int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
-+{
-+    int i, n;
-+    unsigned int b;
-+    *outl = 0;
-+
-+    if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
-+        i = ctx->cipher->do_cipher(ctx, out, NULL, 0);
-+        if (i < 0)
-+            return 0;
-+        else
-+            *outl = i;
-+        return 1;
-+    }
-+
-+    b = ctx->cipher->block_size;
-+    if (ctx->flags & EVP_CIPH_NO_PADDING) {
-+        if (ctx->buf_len) {
-+            EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
-+                   EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
-+            return 0;
-+        }
-+        *outl = 0;
-+        return 1;
-+    }
-+    if (b > 1) {
-+        if (ctx->buf_len || !ctx->final_used) {
-+            EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH);
-+            return (0);
-+        }
-+        OPENSSL_assert(b <= sizeof ctx->final);
-+
-+        /*
-+         * The following assumes that the ciphertext has been authenticated.
-+         * Otherwise it provides a padding oracle.
-+         */
-+        n = ctx->final[b - 1];
-+        if (n == 0 || n > (int)b) {
-+            EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
-+            return (0);
-+        }
-+        for (i = 0; i < n; i++) {
-+            if (ctx->final[--b] != n) {
-+                EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
-+                return (0);
-+            }
-+        }
-+        n = ctx->cipher->block_size - n;
-+        for (i = 0; i < n; i++)
-+            out[i] = ctx->final[i];
-+        *outl = n;
-+    } else
-+        *outl = 0;
-+    return (1);
-+}
-+
-+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
-+{
-+    if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
-+        return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
-+    if (c->key_len == keylen)
-+        return 1;
-+    if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
-+        c->key_len = keylen;
-+        return 1;
-+    }
-+    EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH);
-+    return 0;
-+}
-+
-+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
-+{
-+    if (pad)
-+        ctx->flags &= ~EVP_CIPH_NO_PADDING;
-+    else
-+        ctx->flags |= EVP_CIPH_NO_PADDING;
-+    return 1;
-+}
-+
-+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
-+{
-+    int ret;
-+    if (!ctx->cipher) {
-+        EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
-+        return 0;
-+    }
-+
-+    if (!ctx->cipher->ctrl) {
-+        EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
-+        return 0;
-+    }
-+
-+    ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
-+    if (ret == -1) {
-+        EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL,
-+               EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
-+        return 0;
-+    }
-+    return ret;
-+}
-+
-+int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
-+{
-+    if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
-+        return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
-+    if (RAND_bytes(key, ctx->key_len) <= 0)
-+        return 0;
-+    return 1;
-+}
-+
-+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
-+{
-+    if ((in == NULL) || (in->cipher == NULL)) {
-+        EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INPUT_NOT_INITIALIZED);
-+        return 0;
-+    }
-+#ifndef OPENSSL_NO_ENGINE
-+    /* Make sure it's safe to copy a cipher context using an ENGINE */
-+    if (in->engine && !ENGINE_init(in->engine)) {
-+        EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_ENGINE_LIB);
-+        return 0;
-+    }
-+#endif
-+
-+    EVP_CIPHER_CTX_reset(out);
-+    memcpy(out, in, sizeof(*out));
-+
-+    if (in->cipher_data && in->cipher->ctx_size) {
-+        out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
-+        if (out->cipher_data == NULL) {
-+            out->cipher = NULL;
-+            EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
-+    }
-+
-+    if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
-+        if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) {
-+            out->cipher = NULL;
-+            EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INITIALIZATION_ERROR);
-+            return 0;
-+        }
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_err.c
-new file mode 100644
-index 0000000..e32a1c0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_err.c
-@@ -0,0 +1,180 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason)
-+
-+static ERR_STRING_DATA EVP_str_functs[] = {
-+    {ERR_FUNC(EVP_F_AESNI_INIT_KEY), "aesni_init_key"},
-+    {ERR_FUNC(EVP_F_AES_INIT_KEY), "aes_init_key"},
-+    {ERR_FUNC(EVP_F_AES_OCB_CIPHER), "aes_ocb_cipher"},
-+    {ERR_FUNC(EVP_F_AES_T4_INIT_KEY), "aes_t4_init_key"},
-+    {ERR_FUNC(EVP_F_AES_WRAP_CIPHER), "aes_wrap_cipher"},
-+    {ERR_FUNC(EVP_F_ALG_MODULE_INIT), "alg_module_init"},
-+    {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "camellia_init_key"},
-+    {ERR_FUNC(EVP_F_CHACHA20_POLY1305_CTRL), "chacha20_poly1305_ctrl"},
-+    {ERR_FUNC(EVP_F_CMLL_T4_INIT_KEY), "cmll_t4_init_key"},
-+    {ERR_FUNC(EVP_F_DES_EDE3_WRAP_CIPHER), "des_ede3_wrap_cipher"},
-+    {ERR_FUNC(EVP_F_DO_SIGVER_INIT), "do_sigver_init"},
-+    {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"},
-+    {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"},
-+    {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"},
-+    {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH),
-+     "EVP_CIPHER_CTX_set_key_length"},
-+    {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"},
-+    {ERR_FUNC(EVP_F_EVP_DECRYPTUPDATE), "EVP_DecryptUpdate"},
-+    {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
-+    {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
-+    {ERR_FUNC(EVP_F_EVP_ENCRYPTUPDATE), "EVP_EncryptUpdate"},
-+    {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"},
-+    {ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"},
-+    {ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"},
-+    {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"},
-+    {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"},
-+    {ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"},
-+    {ERR_FUNC(EVP_F_EVP_PBE_SCRYPT), "EVP_PBE_scrypt"},
-+    {ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8), "EVP_PKEY2PKCS8"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP), "EVP_PKEY_CTX_dup"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT), "EVP_PKEY_decrypt_init"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_derive"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_derive_init"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_derive_set_peer"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_GET0_DH), "EVP_PKEY_get0_DH"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_GET0_DSA), "EVP_PKEY_get0_DSA"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_GET0_EC_KEY), "EVP_PKEY_get0_EC_KEY"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_GET0_HMAC), "EVP_PKEY_get0_hmac"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_GET0_RSA), "EVP_PKEY_get0_RSA"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_keygen"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_keygen_init"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN), "EVP_PKEY_paramgen"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT), "EVP_PKEY_paramgen_init"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_SIGN), "EVP_PKEY_sign"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT), "EVP_PKEY_sign_init"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY), "EVP_PKEY_verify"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT), "EVP_PKEY_verify_init"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER), "EVP_PKEY_verify_recover"},
-+    {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT),
-+     "EVP_PKEY_verify_recover_init"},
-+    {ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"},
-+    {ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"},
-+    {ERR_FUNC(EVP_F_INT_CTX_NEW), "int_ctx_new"},
-+    {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"},
-+    {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"},
-+    {ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_v2_PBKDF2_keyivgen"},
-+    {ERR_FUNC(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN), "PKCS5_v2_scrypt_keyivgen"},
-+    {ERR_FUNC(EVP_F_PKEY_SET_TYPE), "pkey_set_type"},
-+    {ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "rc2_magic_to_meth"},
-+    {ERR_FUNC(EVP_F_RC5_CTRL), "rc5_ctrl"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA EVP_str_reasons[] = {
-+    {ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED), "aes key setup failed"},
-+    {ERR_REASON(EVP_R_BAD_DECRYPT), "bad decrypt"},
-+    {ERR_REASON(EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
-+    {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED),
-+     "camellia key setup failed"},
-+    {ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"},
-+    {ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED), "command not supported"},
-+    {ERR_REASON(EVP_R_COPY_ERROR), "copy error"},
-+    {ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED), "ctrl not implemented"},
-+    {ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),
-+     "ctrl operation not implemented"},
-+    {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),
-+     "data not multiple of block length"},
-+    {ERR_REASON(EVP_R_DECODE_ERROR), "decode error"},
-+    {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES), "different key types"},
-+    {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS), "different parameters"},
-+    {ERR_REASON(EVP_R_ERROR_LOADING_SECTION), "error loading section"},
-+    {ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE), "error setting fips mode"},
-+    {ERR_REASON(EVP_R_EXPECTING_AN_HMAC_KEY), "expecting an hmac key"},
-+    {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY), "expecting an rsa key"},
-+    {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"},
-+    {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY), "expecting a dsa key"},
-+    {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"},
-+    {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"},
-+    {ERR_REASON(EVP_R_ILLEGAL_SCRYPT_PARAMETERS),
-+     "illegal scrypt parameters"},
-+    {ERR_REASON(EVP_R_INITIALIZATION_ERROR), "initialization error"},
-+    {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"},
-+    {ERR_REASON(EVP_R_INVALID_DIGEST), "invalid digest"},
-+    {ERR_REASON(EVP_R_INVALID_FIPS_MODE), "invalid fips mode"},
-+    {ERR_REASON(EVP_R_INVALID_KEY), "invalid key"},
-+    {ERR_REASON(EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
-+    {ERR_REASON(EVP_R_INVALID_OPERATION), "invalid operation"},
-+    {ERR_REASON(EVP_R_KEYGEN_FAILURE), "keygen failure"},
-+    {ERR_REASON(EVP_R_MEMORY_LIMIT_EXCEEDED), "memory limit exceeded"},
-+    {ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"},
-+    {ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED), "method not supported"},
-+    {ERR_REASON(EVP_R_MISSING_PARAMETERS), "missing parameters"},
-+    {ERR_REASON(EVP_R_NO_CIPHER_SET), "no cipher set"},
-+    {ERR_REASON(EVP_R_NO_DEFAULT_DIGEST), "no default digest"},
-+    {ERR_REASON(EVP_R_NO_DIGEST_SET), "no digest set"},
-+    {ERR_REASON(EVP_R_NO_KEY_SET), "no key set"},
-+    {ERR_REASON(EVP_R_NO_OPERATION_SET), "no operation set"},
-+    {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
-+     "operation not supported for this keytype"},
-+    {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"},
-+    {ERR_REASON(EVP_R_PARTIALLY_OVERLAPPING),
-+     "partially overlapping buffers"},
-+    {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"},
-+    {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"},
-+    {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"},
-+    {ERR_REASON(EVP_R_UNKNOWN_CIPHER), "unknown cipher"},
-+    {ERR_REASON(EVP_R_UNKNOWN_DIGEST), "unknown digest"},
-+    {ERR_REASON(EVP_R_UNKNOWN_OPTION), "unknown option"},
-+    {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM), "unknown pbe algorithm"},
-+    {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
-+    {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
-+    {ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH), "unsupported keylength"},
-+    {ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),
-+     "unsupported key derivation function"},
-+    {ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE), "unsupported key size"},
-+    {ERR_REASON(EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS),
-+     "unsupported number of rounds"},
-+    {ERR_REASON(EVP_R_UNSUPPORTED_PRF), "unsupported prf"},
-+    {ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM),
-+     "unsupported private key algorithm"},
-+    {ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE), "unsupported salt type"},
-+    {ERR_REASON(EVP_R_WRAP_MODE_NOT_ALLOWED), "wrap mode not allowed"},
-+    {ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_EVP_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, EVP_str_functs);
-+        ERR_load_strings(0, EVP_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_key.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_key.c
-new file mode 100644
-index 0000000..8a4297c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_key.c
-@@ -0,0 +1,150 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifndef OPENSSL_NO_UI
-+/* should be init to zeros. */
-+static char prompt_string[80];
-+
-+void EVP_set_pw_prompt(const char *prompt)
-+{
-+    if (prompt == NULL)
-+        prompt_string[0] = '\0';
-+    else {
-+        strncpy(prompt_string, prompt, 79);
-+        prompt_string[79] = '\0';
-+    }
-+}
-+
-+char *EVP_get_pw_prompt(void)
-+{
-+    if (prompt_string[0] == '\0')
-+        return (NULL);
-+    else
-+        return (prompt_string);
-+}
-+
-+/*
-+ * For historical reasons, the standard function for reading passwords is in
-+ * the DES library -- if someone ever wants to disable DES, this function
-+ * will fail
-+ */
-+int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
-+{
-+    return EVP_read_pw_string_min(buf, 0, len, prompt, verify);
-+}
-+
-+int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt,
-+                           int verify)
-+{
-+    int ret;
-+    char buff[BUFSIZ];
-+    UI *ui;
-+
-+    if ((prompt == NULL) && (prompt_string[0] != '\0'))
-+        prompt = prompt_string;
-+    ui = UI_new();
-+    if (ui == NULL)
-+        return -1;
-+    UI_add_input_string(ui, prompt, 0, buf, min,
-+                        (len >= BUFSIZ) ? BUFSIZ - 1 : len);
-+    if (verify)
-+        UI_add_verify_string(ui, prompt, 0,
-+                             buff, min, (len >= BUFSIZ) ? BUFSIZ - 1 : len,
-+                             buf);
-+    ret = UI_process(ui);
-+    UI_free(ui);
-+    OPENSSL_cleanse(buff, BUFSIZ);
-+    return ret;
-+}
-+#endif /* OPENSSL_NO_UI */
-+
-+int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
-+                   const unsigned char *salt, const unsigned char *data,
-+                   int datal, int count, unsigned char *key,
-+                   unsigned char *iv)
-+{
-+    EVP_MD_CTX *c;
-+    unsigned char md_buf[EVP_MAX_MD_SIZE];
-+    int niv, nkey, addmd = 0;
-+    unsigned int mds = 0, i;
-+    int rv = 0;
-+    nkey = EVP_CIPHER_key_length(type);
-+    niv = EVP_CIPHER_iv_length(type);
-+    OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
-+    OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);
-+
-+    if (data == NULL)
-+        return (nkey);
-+
-+    c = EVP_MD_CTX_new();
-+    if (c == NULL)
-+        goto err;
-+    for (;;) {
-+        if (!EVP_DigestInit_ex(c, md, NULL))
-+            goto err;
-+        if (addmd++)
-+            if (!EVP_DigestUpdate(c, &(md_buf[0]), mds))
-+                goto err;
-+        if (!EVP_DigestUpdate(c, data, datal))
-+            goto err;
-+        if (salt != NULL)
-+            if (!EVP_DigestUpdate(c, salt, PKCS5_SALT_LEN))
-+                goto err;
-+        if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds))
-+            goto err;
-+
-+        for (i = 1; i < (unsigned int)count; i++) {
-+            if (!EVP_DigestInit_ex(c, md, NULL))
-+                goto err;
-+            if (!EVP_DigestUpdate(c, &(md_buf[0]), mds))
-+                goto err;
-+            if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds))
-+                goto err;
-+        }
-+        i = 0;
-+        if (nkey) {
-+            for (;;) {
-+                if (nkey == 0)
-+                    break;
-+                if (i == mds)
-+                    break;
-+                if (key != NULL)
-+                    *(key++) = md_buf[i];
-+                nkey--;
-+                i++;
-+            }
-+        }
-+        if (niv && (i != mds)) {
-+            for (;;) {
-+                if (niv == 0)
-+                    break;
-+                if (i == mds)
-+                    break;
-+                if (iv != NULL)
-+                    *(iv++) = md_buf[i];
-+                niv--;
-+                i++;
-+            }
-+        }
-+        if ((nkey == 0) && (niv == 0))
-+            break;
-+    }
-+    rv = EVP_CIPHER_key_length(type);
-+ err:
-+    EVP_MD_CTX_free(c);
-+    OPENSSL_cleanse(md_buf, sizeof(md_buf));
-+    return rv;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_lib.c
-new file mode 100644
-index 0000000..0c76db5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_lib.c
-@@ -0,0 +1,497 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+#include "evp_locl.h"
-+
-+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
-+{
-+    int ret;
-+
-+    if (c->cipher->set_asn1_parameters != NULL)
-+        ret = c->cipher->set_asn1_parameters(c, type);
-+    else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
-+        switch (EVP_CIPHER_CTX_mode(c)) {
-+        case EVP_CIPH_WRAP_MODE:
-+            if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap)
-+                ASN1_TYPE_set(type, V_ASN1_NULL, NULL);
-+            ret = 1;
-+            break;
-+
-+        case EVP_CIPH_GCM_MODE:
-+        case EVP_CIPH_CCM_MODE:
-+        case EVP_CIPH_XTS_MODE:
-+        case EVP_CIPH_OCB_MODE:
-+            ret = -1;
-+            break;
-+
-+        default:
-+            ret = EVP_CIPHER_set_asn1_iv(c, type);
-+        }
-+    } else
-+        ret = -1;
-+    return (ret);
-+}
-+
-+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
-+{
-+    int ret;
-+
-+    if (c->cipher->get_asn1_parameters != NULL)
-+        ret = c->cipher->get_asn1_parameters(c, type);
-+    else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
-+        switch (EVP_CIPHER_CTX_mode(c)) {
-+
-+        case EVP_CIPH_WRAP_MODE:
-+            ret = 1;
-+            break;
-+
-+        case EVP_CIPH_GCM_MODE:
-+        case EVP_CIPH_CCM_MODE:
-+        case EVP_CIPH_XTS_MODE:
-+        case EVP_CIPH_OCB_MODE:
-+            ret = -1;
-+            break;
-+
-+        default:
-+            ret = EVP_CIPHER_get_asn1_iv(c, type);
-+            break;
-+        }
-+    } else
-+        ret = -1;
-+    return (ret);
-+}
-+
-+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
-+{
-+    int i = 0;
-+    unsigned int l;
-+
-+    if (type != NULL) {
-+        l = EVP_CIPHER_CTX_iv_length(c);
-+        OPENSSL_assert(l <= sizeof(c->iv));
-+        i = ASN1_TYPE_get_octetstring(type, c->oiv, l);
-+        if (i != (int)l)
-+            return (-1);
-+        else if (i > 0)
-+            memcpy(c->iv, c->oiv, l);
-+    }
-+    return (i);
-+}
-+
-+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
-+{
-+    int i = 0;
-+    unsigned int j;
-+
-+    if (type != NULL) {
-+        j = EVP_CIPHER_CTX_iv_length(c);
-+        OPENSSL_assert(j <= sizeof(c->iv));
-+        i = ASN1_TYPE_set_octetstring(type, c->oiv, j);
-+    }
-+    return (i);
-+}
-+
-+/* Convert the various cipher NIDs and dummies to a proper OID NID */
-+int EVP_CIPHER_type(const EVP_CIPHER *ctx)
-+{
-+    int nid;
-+    ASN1_OBJECT *otmp;
-+    nid = EVP_CIPHER_nid(ctx);
-+
-+    switch (nid) {
-+
-+    case NID_rc2_cbc:
-+    case NID_rc2_64_cbc:
-+    case NID_rc2_40_cbc:
-+
-+        return NID_rc2_cbc;
-+
-+    case NID_rc4:
-+    case NID_rc4_40:
-+
-+        return NID_rc4;
-+
-+    case NID_aes_128_cfb128:
-+    case NID_aes_128_cfb8:
-+    case NID_aes_128_cfb1:
-+
-+        return NID_aes_128_cfb128;
-+
-+    case NID_aes_192_cfb128:
-+    case NID_aes_192_cfb8:
-+    case NID_aes_192_cfb1:
-+
-+        return NID_aes_192_cfb128;
-+
-+    case NID_aes_256_cfb128:
-+    case NID_aes_256_cfb8:
-+    case NID_aes_256_cfb1:
-+
-+        return NID_aes_256_cfb128;
-+
-+    case NID_des_cfb64:
-+    case NID_des_cfb8:
-+    case NID_des_cfb1:
-+
-+        return NID_des_cfb64;
-+
-+    case NID_des_ede3_cfb64:
-+    case NID_des_ede3_cfb8:
-+    case NID_des_ede3_cfb1:
-+
-+        return NID_des_cfb64;
-+
-+    default:
-+        /* Check it has an OID and it is valid */
-+        otmp = OBJ_nid2obj(nid);
-+        if (OBJ_get0_data(otmp) == NULL)
-+            nid = NID_undef;
-+        ASN1_OBJECT_free(otmp);
-+        return nid;
-+    }
-+}
-+
-+int EVP_CIPHER_block_size(const EVP_CIPHER *e)
-+{
-+    return e->block_size;
-+}
-+
-+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->cipher->block_size;
-+}
-+
-+int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
-+{
-+    return e->ctx_size;
-+}
-+
-+int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+               const unsigned char *in, unsigned int inl)
-+{
-+    return ctx->cipher->do_cipher(ctx, out, in, inl);
-+}
-+
-+const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->cipher;
-+}
-+
-+int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->encrypt;
-+}
-+
-+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
-+{
-+    return cipher->flags;
-+}
-+
-+void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->app_data;
-+}
-+
-+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
-+{
-+    ctx->app_data = data;
-+}
-+
-+void *EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->cipher_data;
-+}
-+
-+void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
-+{
-+    void *old_cipher_data;
-+
-+    old_cipher_data = ctx->cipher_data;
-+    ctx->cipher_data = cipher_data;
-+
-+    return old_cipher_data;
-+}
-+
-+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
-+{
-+    return cipher->iv_len;
-+}
-+
-+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->cipher->iv_len;
-+}
-+
-+const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->oiv;
-+}
-+
-+const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->iv;
-+}
-+
-+unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->iv;
-+}
-+
-+unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->buf;
-+}
-+
-+int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->num;
-+}
-+
-+void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num)
-+{
-+    ctx->num = num;
-+}
-+
-+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
-+{
-+    return cipher->key_len;
-+}
-+
-+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->key_len;
-+}
-+
-+int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
-+{
-+    return cipher->nid;
-+}
-+
-+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
-+{
-+    return ctx->cipher->nid;
-+}
-+
-+int EVP_MD_block_size(const EVP_MD *md)
-+{
-+    return md->block_size;
-+}
-+
-+int EVP_MD_type(const EVP_MD *md)
-+{
-+    return md->type;
-+}
-+
-+int EVP_MD_pkey_type(const EVP_MD *md)
-+{
-+    return md->pkey_type;
-+}
-+
-+int EVP_MD_size(const EVP_MD *md)
-+{
-+    if (!md) {
-+        EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
-+        return -1;
-+    }
-+    return md->md_size;
-+}
-+
-+unsigned long EVP_MD_flags(const EVP_MD *md)
-+{
-+    return md->flags;
-+}
-+
-+EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type)
-+{
-+    EVP_MD *md = OPENSSL_zalloc(sizeof(*md));
-+
-+    if (md != NULL) {
-+        md->type = md_type;
-+        md->pkey_type = pkey_type;
-+    }
-+    return md;
-+}
-+EVP_MD *EVP_MD_meth_dup(const EVP_MD *md)
-+{
-+    EVP_MD *to = EVP_MD_meth_new(md->type, md->pkey_type);
-+
-+    if (to != NULL)
-+        memcpy(to, md, sizeof(*to));
-+    return to;
-+}
-+void EVP_MD_meth_free(EVP_MD *md)
-+{
-+    OPENSSL_free(md);
-+}
-+int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize)
-+{
-+    md->block_size = blocksize;
-+    return 1;
-+}
-+int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize)
-+{
-+    md->md_size = resultsize;
-+    return 1;
-+}
-+int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize)
-+{
-+    md->ctx_size = datasize;
-+    return 1;
-+}
-+int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags)
-+{
-+    md->flags = flags;
-+    return 1;
-+}
-+int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx))
-+{
-+    md->init = init;
-+    return 1;
-+}
-+int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx,
-+                                                     const void *data,
-+                                                     size_t count))
-+{
-+    md->update = update;
-+    return 1;
-+}
-+int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx,
-+                                                   unsigned char *md))
-+{
-+    md->final = final;
-+    return 1;
-+}
-+int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to,
-+                                                 const EVP_MD_CTX *from))
-+{
-+    md->copy = copy;
-+    return 1;
-+}
-+int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx))
-+{
-+    md->cleanup = cleanup;
-+    return 1;
-+}
-+int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd,
-+                                                 int p1, void *p2))
-+{
-+    md->md_ctrl = ctrl;
-+    return 1;
-+}
-+
-+int EVP_MD_meth_get_input_blocksize(const EVP_MD *md)
-+{
-+    return md->block_size;
-+}
-+int EVP_MD_meth_get_result_size(const EVP_MD *md)
-+{
-+    return md->md_size;
-+}
-+int EVP_MD_meth_get_app_datasize(const EVP_MD *md)
-+{
-+    return md->ctx_size;
-+}
-+unsigned long EVP_MD_meth_get_flags(const EVP_MD *md)
-+{
-+    return md->flags;
-+}
-+int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx)
-+{
-+    return md->init;
-+}
-+int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx,
-+                                                const void *data,
-+                                                size_t count)
-+{
-+    return md->update;
-+}
-+int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx,
-+                                               unsigned char *md)
-+{
-+    return md->final;
-+}
-+int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to,
-+                                              const EVP_MD_CTX *from)
-+{
-+    return md->copy;
-+}
-+int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx)
-+{
-+    return md->cleanup;
-+}
-+int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
-+                                              int p1, void *p2)
-+{
-+    return md->md_ctrl;
-+}
-+
-+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
-+{
-+    if (!ctx)
-+        return NULL;
-+    return ctx->digest;
-+}
-+
-+EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx)
-+{
-+    return ctx->pctx;
-+}
-+
-+void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx)
-+{
-+    return ctx->md_data;
-+}
-+
-+int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx,
-+                                             const void *data, size_t count)
-+{
-+    return ctx->update;
-+}
-+
-+void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx,
-+                              int (*update) (EVP_MD_CTX *ctx,
-+                                             const void *data, size_t count))
-+{
-+    ctx->update = update;
-+}
-+
-+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
-+{
-+    ctx->flags |= flags;
-+}
-+
-+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags)
-+{
-+    ctx->flags &= ~flags;
-+}
-+
-+int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
-+{
-+    return (ctx->flags & flags);
-+}
-+
-+void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
-+{
-+    ctx->flags |= flags;
-+}
-+
-+void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
-+{
-+    ctx->flags &= ~flags;
-+}
-+
-+int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
-+{
-+    return (ctx->flags & flags);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_locl.h
-new file mode 100644
-index 0000000..209577b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_locl.h
-@@ -0,0 +1,68 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* EVP_MD_CTX related stuff */
-+
-+struct evp_md_ctx_st {
-+    const EVP_MD *digest;
-+    ENGINE *engine;             /* functional reference if 'digest' is
-+                                 * ENGINE-provided */
-+    unsigned long flags;
-+    void *md_data;
-+    /* Public key context for sign/verify */
-+    EVP_PKEY_CTX *pctx;
-+    /* Update function: usually copied from EVP_MD */
-+    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
-+} /* EVP_MD_CTX */ ;
-+
-+struct evp_cipher_ctx_st {
-+    const EVP_CIPHER *cipher;
-+    ENGINE *engine;             /* functional reference if 'cipher' is
-+                                 * ENGINE-provided */
-+    int encrypt;                /* encrypt or decrypt */
-+    int buf_len;                /* number we have left */
-+    unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
-+    unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
-+    unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */
-+    int num;                    /* used by cfb/ofb/ctr mode */
-+    /* FIXME: Should this even exist? It appears unused */
-+    void *app_data;             /* application stuff */
-+    int key_len;                /* May change for variable length cipher */
-+    unsigned long flags;        /* Various flags */
-+    void *cipher_data;          /* per EVP data */
-+    int final_used;
-+    int block_mask;
-+    unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
-+} /* EVP_CIPHER_CTX */ ;
-+
-+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
-+                             int passlen, ASN1_TYPE *param,
-+                             const EVP_CIPHER *c, const EVP_MD *md,
-+                             int en_de);
-+
-+struct evp_Encode_Ctx_st {
-+    /* number saved in a partial encode/decode */
-+    int num;
-+    /*
-+     * The length is either the output line length (in input bytes) or the
-+     * shortest input line length that is ok.  Once decoding begins, the
-+     * length is adjusted up each time a longer line is decoded
-+     */
-+    int length;
-+    /* data to encode */
-+    unsigned char enc_data[80];
-+    /* number read on current line */
-+    int line_num;
-+    int expect_nl;
-+};
-+
-+typedef struct evp_pbe_st EVP_PBE_CTL;
-+DEFINE_STACK_OF(EVP_PBE_CTL)
-+
-+int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_pbe.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_pbe.c
-new file mode 100644
-index 0000000..ce7aa2c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_pbe.c
-@@ -0,0 +1,259 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "evp_locl.h"
-+
-+/* Password based encryption (PBE) functions */
-+
-+/* Setup a cipher context from a PBE algorithm */
-+
-+struct evp_pbe_st {
-+    int pbe_type;
-+    int pbe_nid;
-+    int cipher_nid;
-+    int md_nid;
-+    EVP_PBE_KEYGEN *keygen;
-+};
-+
-+static STACK_OF(EVP_PBE_CTL) *pbe_algs;
-+
-+static const EVP_PBE_CTL builtin_pbe[] = {
-+    {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
-+     NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
-+    {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
-+     NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
-+    {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
-+     NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
-+
-+    {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
-+
-+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
-+     NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
-+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
-+     NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
-+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
-+     NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
-+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
-+     NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
-+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
-+     NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
-+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
-+     NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
-+
-+    {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
-+
-+    {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
-+     NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
-+    {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
-+     NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
-+    {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
-+     NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
-+
-+    {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
-+    {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
-+    {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
-+    {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
-+    {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
-+    {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
-+    {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
-+    {EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_2012_256, -1,
-+     NID_id_GostR3411_2012_256, 0},
-+    {EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_2012_512, -1,
-+     NID_id_GostR3411_2012_512, 0},
-+    {EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
-+#ifndef OPENSSL_NO_SCRYPT
-+    {EVP_PBE_TYPE_KDF, NID_id_scrypt, -1, -1, PKCS5_v2_scrypt_keyivgen}
-+#endif
-+};
-+
-+int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
-+                       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
-+{
-+    const EVP_CIPHER *cipher;
-+    const EVP_MD *md;
-+    int cipher_nid, md_nid;
-+    EVP_PBE_KEYGEN *keygen;
-+
-+    if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
-+                      &cipher_nid, &md_nid, &keygen)) {
-+        char obj_tmp[80];
-+        EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_PBE_ALGORITHM);
-+        if (!pbe_obj)
-+            OPENSSL_strlcpy(obj_tmp, "NULL", sizeof obj_tmp);
-+        else
-+            i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
-+        ERR_add_error_data(2, "TYPE=", obj_tmp);
-+        return 0;
-+    }
-+
-+    if (!pass)
-+        passlen = 0;
-+    else if (passlen == -1)
-+        passlen = strlen(pass);
-+
-+    if (cipher_nid == -1)
-+        cipher = NULL;
-+    else {
-+        cipher = EVP_get_cipherbynid(cipher_nid);
-+        if (!cipher) {
-+            EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_CIPHER);
-+            return 0;
-+        }
-+    }
-+
-+    if (md_nid == -1)
-+        md = NULL;
-+    else {
-+        md = EVP_get_digestbynid(md_nid);
-+        if (!md) {
-+            EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_DIGEST);
-+            return 0;
-+        }
-+    }
-+
-+    if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) {
-+        EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_KEYGEN_FAILURE);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
-+
-+static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
-+{
-+    int ret = pbe1->pbe_type - pbe2->pbe_type;
-+    if (ret)
-+        return ret;
-+    else
-+        return pbe1->pbe_nid - pbe2->pbe_nid;
-+}
-+
-+IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
-+
-+static int pbe_cmp(const EVP_PBE_CTL *const *a, const EVP_PBE_CTL *const *b)
-+{
-+    int ret = (*a)->pbe_type - (*b)->pbe_type;
-+    if (ret)
-+        return ret;
-+    else
-+        return (*a)->pbe_nid - (*b)->pbe_nid;
-+}
-+
-+/* Add a PBE algorithm */
-+
-+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid,
-+                         int md_nid, EVP_PBE_KEYGEN *keygen)
-+{
-+    EVP_PBE_CTL *pbe_tmp;
-+
-+    if (pbe_algs == NULL) {
-+        pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
-+        if (pbe_algs == NULL)
-+            goto err;
-+    }
-+
-+    if ((pbe_tmp = OPENSSL_malloc(sizeof(*pbe_tmp))) == NULL)
-+        goto err;
-+
-+    pbe_tmp->pbe_type = pbe_type;
-+    pbe_tmp->pbe_nid = pbe_nid;
-+    pbe_tmp->cipher_nid = cipher_nid;
-+    pbe_tmp->md_nid = md_nid;
-+    pbe_tmp->keygen = keygen;
-+
-+    if (!sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp)) {
-+        OPENSSL_free(pbe_tmp);
-+        goto err;
-+    }
-+    return 1;
-+
-+ err:
-+    EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE);
-+    return 0;
-+}
-+
-+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
-+                    EVP_PBE_KEYGEN *keygen)
-+{
-+    int cipher_nid, md_nid;
-+
-+    if (cipher)
-+        cipher_nid = EVP_CIPHER_nid(cipher);
-+    else
-+        cipher_nid = -1;
-+    if (md)
-+        md_nid = EVP_MD_type(md);
-+    else
-+        md_nid = -1;
-+
-+    return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
-+                                cipher_nid, md_nid, keygen);
-+}
-+
-+int EVP_PBE_find(int type, int pbe_nid,
-+                 int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
-+{
-+    EVP_PBE_CTL *pbetmp = NULL, pbelu;
-+    int i;
-+    if (pbe_nid == NID_undef)
-+        return 0;
-+
-+    pbelu.pbe_type = type;
-+    pbelu.pbe_nid = pbe_nid;
-+
-+    if (pbe_algs) {
-+        i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
-+        if (i != -1)
-+            pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i);
-+    }
-+    if (pbetmp == NULL) {
-+        pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, OSSL_NELEM(builtin_pbe));
-+    }
-+    if (pbetmp == NULL)
-+        return 0;
-+    if (pcnid)
-+        *pcnid = pbetmp->cipher_nid;
-+    if (pmnid)
-+        *pmnid = pbetmp->md_nid;
-+    if (pkeygen)
-+        *pkeygen = pbetmp->keygen;
-+    return 1;
-+}
-+
-+static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
-+{
-+    OPENSSL_free(pbe);
-+}
-+
-+void EVP_PBE_cleanup(void)
-+{
-+    sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
-+    pbe_algs = NULL;
-+}
-+
-+int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num)
-+{
-+    const EVP_PBE_CTL *tpbe;
-+
-+    if (num >= OSSL_NELEM(builtin_pbe))
-+        return 0;
-+
-+    tpbe = builtin_pbe + num;
-+    if (ptype)
-+        *ptype = tpbe->pbe_type;
-+    if (ppbe_nid)
-+        *ppbe_nid = tpbe->pbe_nid;
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_pkey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_pkey.c
-new file mode 100644
-index 0000000..81bffa6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/evp_pkey.c
-@@ -0,0 +1,150 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+#include "internal/x509_int.h"
-+
-+/* Extract a private key from a PKCS8 structure */
-+
-+EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
-+{
-+    EVP_PKEY *pkey = NULL;
-+    const ASN1_OBJECT *algoid;
-+    char obj_tmp[80];
-+
-+    if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
-+        return NULL;
-+
-+    if ((pkey = EVP_PKEY_new()) == NULL) {
-+        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
-+        EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
-+        i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
-+        ERR_add_error_data(2, "TYPE=", obj_tmp);
-+        goto error;
-+    }
-+
-+    if (pkey->ameth->priv_decode) {
-+        if (!pkey->ameth->priv_decode(pkey, p8)) {
-+            EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR);
-+            goto error;
-+        }
-+    } else {
-+        EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
-+        goto error;
-+    }
-+
-+    return pkey;
-+
-+ error:
-+    EVP_PKEY_free(pkey);
-+    return NULL;
-+}
-+
-+/* Turn a private key into a PKCS8 structure */
-+
-+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
-+{
-+    PKCS8_PRIV_KEY_INFO *p8 = PKCS8_PRIV_KEY_INFO_new();
-+    if (p8  == NULL) {
-+        EVPerr(EVP_F_EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    if (pkey->ameth) {
-+        if (pkey->ameth->priv_encode) {
-+            if (!pkey->ameth->priv_encode(p8, pkey)) {
-+                EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_PRIVATE_KEY_ENCODE_ERROR);
-+                goto error;
-+            }
-+        } else {
-+            EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_METHOD_NOT_SUPPORTED);
-+            goto error;
-+        }
-+    } else {
-+        EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
-+        goto error;
-+    }
-+    RAND_add(p8->pkey->data, p8->pkey->length, 0.0);
-+    return p8;
-+ error:
-+    PKCS8_PRIV_KEY_INFO_free(p8);
-+    return NULL;
-+}
-+
-+/* EVP_PKEY attribute functions */
-+
-+int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
-+{
-+    return X509at_get_attr_count(key->attributes);
-+}
-+
-+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos)
-+{
-+    return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
-+}
-+
-+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj,
-+                             int lastpos)
-+{
-+    return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
-+}
-+
-+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
-+{
-+    return X509at_get_attr(key->attributes, loc);
-+}
-+
-+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
-+{
-+    return X509at_delete_attr(key->attributes, loc);
-+}
-+
-+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
-+{
-+    if (X509at_add1_attr(&key->attributes, attr))
-+        return 1;
-+    return 0;
-+}
-+
-+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
-+                              const ASN1_OBJECT *obj, int type,
-+                              const unsigned char *bytes, int len)
-+{
-+    if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len))
-+        return 1;
-+    return 0;
-+}
-+
-+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
-+                              int nid, int type,
-+                              const unsigned char *bytes, int len)
-+{
-+    if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len))
-+        return 1;
-+    return 0;
-+}
-+
-+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
-+                              const char *attrname, int type,
-+                              const unsigned char *bytes, int len)
-+{
-+    if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, bytes, len))
-+        return 1;
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md2.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md2.c
-new file mode 100644
-index 0000000..c4e28ae
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md2.c
-@@ -0,0 +1,56 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_MD2
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+
-+#include "internal/evp_int.h"
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    return MD2_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return MD2_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return MD2_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static const EVP_MD md2_md = {
-+    NID_md2,
-+    NID_md2WithRSAEncryption,
-+    MD2_DIGEST_LENGTH,
-+    0,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    MD2_BLOCK,
-+    sizeof(EVP_MD *) + sizeof(MD2_CTX),
-+};
-+
-+const EVP_MD *EVP_md2(void)
-+{
-+    return &md2_md;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md4.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md4.c
-new file mode 100644
-index 0000000..f3decaa
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md4.c
-@@ -0,0 +1,55 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_MD4
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    return MD4_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return MD4_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return MD4_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static const EVP_MD md4_md = {
-+    NID_md4,
-+    NID_md4WithRSAEncryption,
-+    MD4_DIGEST_LENGTH,
-+    0,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    MD4_CBLOCK,
-+    sizeof(EVP_MD *) + sizeof(MD4_CTX),
-+};
-+
-+const EVP_MD *EVP_md4(void)
-+{
-+    return (&md4_md);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md5.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md5.c
-new file mode 100644
-index 0000000..f4dc0c4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md5.c
-@@ -0,0 +1,55 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_MD5
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    return MD5_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return MD5_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return MD5_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static const EVP_MD md5_md = {
-+    NID_md5,
-+    NID_md5WithRSAEncryption,
-+    MD5_DIGEST_LENGTH,
-+    0,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    MD5_CBLOCK,
-+    sizeof(EVP_MD *) + sizeof(MD5_CTX),
-+};
-+
-+const EVP_MD *EVP_md5(void)
-+{
-+    return (&md5_md);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md5_sha1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md5_sha1.c
-new file mode 100644
-index 0000000..2d98886
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_md5_sha1.c
-@@ -0,0 +1,142 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#if !defined(OPENSSL_NO_MD5)
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "internal/cryptlib.h"
-+# include "internal/evp_int.h"
-+# include 
-+
-+struct md5_sha1_ctx {
-+    MD5_CTX md5;
-+    SHA_CTX sha1;
-+};
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
-+    if (!MD5_Init(&mctx->md5))
-+        return 0;
-+    return SHA1_Init(&mctx->sha1);
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
-+    if (!MD5_Update(&mctx->md5, data, count))
-+        return 0;
-+    return SHA1_Update(&mctx->sha1, data, count);
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
-+    if (!MD5_Final(md, &mctx->md5))
-+        return 0;
-+    return SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1);
-+}
-+
-+static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
-+{
-+    unsigned char padtmp[48];
-+    unsigned char md5tmp[MD5_DIGEST_LENGTH];
-+    unsigned char sha1tmp[SHA_DIGEST_LENGTH];
-+    struct md5_sha1_ctx *mctx;
-+
-+    if (cmd != EVP_CTRL_SSL3_MASTER_SECRET)
-+        return -2;
-+
-+    if (ctx == NULL)
-+        return 0;
-+
-+    mctx = EVP_MD_CTX_md_data(ctx);
-+
-+    /* SSLv3 client auth handling: see RFC-6101 5.6.8 */
-+    if (mslen != 48)
-+        return 0;
-+
-+    /* At this point hash contains all handshake messages, update
-+     * with master secret and pad_1.
-+     */
-+
-+    if (update(ctx, ms, mslen) <= 0)
-+        return 0;
-+
-+    /* Set padtmp to pad_1 value */
-+    memset(padtmp, 0x36, sizeof(padtmp));
-+
-+    if (!MD5_Update(&mctx->md5, padtmp, sizeof(padtmp)))
-+        return 0;
-+
-+    if (!MD5_Final(md5tmp, &mctx->md5))
-+        return 0;
-+
-+    if (!SHA1_Update(&mctx->sha1, padtmp, 40))
-+        return 0;
-+
-+    if (!SHA1_Final(sha1tmp, &mctx->sha1))
-+        return 0;
-+
-+    /* Reinitialise context */
-+
-+    if (!init(ctx))
-+        return 0;
-+
-+    if (update(ctx, ms, mslen) <= 0)
-+        return 0;
-+
-+    /* Set padtmp to pad_2 value */
-+    memset(padtmp, 0x5c, sizeof(padtmp));
-+
-+    if (!MD5_Update(&mctx->md5, padtmp, sizeof(padtmp)))
-+        return 0;
-+
-+    if (!MD5_Update(&mctx->md5, md5tmp, sizeof(md5tmp)))
-+        return 0;
-+
-+    if (!SHA1_Update(&mctx->sha1, padtmp, 40))
-+        return 0;
-+
-+    if (!SHA1_Update(&mctx->sha1, sha1tmp, sizeof(sha1tmp)))
-+        return 0;
-+
-+    /* Now when ctx is finalised it will return the SSL v3 hash value */
-+
-+    OPENSSL_cleanse(md5tmp, sizeof(md5tmp));
-+    OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp));
-+
-+    return 1;
-+
-+}
-+
-+static const EVP_MD md5_sha1_md = {
-+    NID_md5_sha1,
-+    NID_md5_sha1,
-+    MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
-+    0,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    MD5_CBLOCK,
-+    sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx),
-+    ctrl
-+};
-+
-+const EVP_MD *EVP_md5_sha1(void)
-+{
-+    return &md5_sha1_md;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_mdc2.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_mdc2.c
-new file mode 100644
-index 0000000..b7f0fd8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_mdc2.c
-@@ -0,0 +1,55 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_MDC2
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    return MDC2_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return MDC2_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return MDC2_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static const EVP_MD mdc2_md = {
-+    NID_mdc2,
-+    NID_mdc2WithRSA,
-+    MDC2_DIGEST_LENGTH,
-+    0,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    MDC2_BLOCK,
-+    sizeof(EVP_MD *) + sizeof(MDC2_CTX),
-+};
-+
-+const EVP_MD *EVP_mdc2(void)
-+{
-+    return (&mdc2_md);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_null.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_null.c
-new file mode 100644
-index 0000000..6c4daf5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_null.c
-@@ -0,0 +1,49 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    return 1;
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return 1;
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return 1;
-+}
-+
-+static const EVP_MD null_md = {
-+    NID_undef,
-+    NID_undef,
-+    0,
-+    0,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    0,
-+    sizeof(EVP_MD *),
-+};
-+
-+const EVP_MD *EVP_md_null(void)
-+{
-+    return (&null_md);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_ripemd.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_ripemd.c
-new file mode 100644
-index 0000000..07b46bd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_ripemd.c
-@@ -0,0 +1,55 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_RMD160
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    return RIPEMD160_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return RIPEMD160_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return RIPEMD160_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static const EVP_MD ripemd160_md = {
-+    NID_ripemd160,
-+    NID_ripemd160WithRSA,
-+    RIPEMD160_DIGEST_LENGTH,
-+    0,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    RIPEMD160_CBLOCK,
-+    sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX),
-+};
-+
-+const EVP_MD *EVP_ripemd160(void)
-+{
-+    return (&ripemd160_md);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_sha1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_sha1.c
-new file mode 100644
-index 0000000..8f30077
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_sha1.c
-@@ -0,0 +1,233 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    return SHA1_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return SHA1_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return SHA1_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
-+{
-+    unsigned char padtmp[40];
-+    unsigned char sha1tmp[SHA_DIGEST_LENGTH];
-+
-+    SHA_CTX *sha1;
-+
-+    if (cmd != EVP_CTRL_SSL3_MASTER_SECRET)
-+        return -2;
-+
-+    if (ctx == NULL)
-+        return 0;
-+
-+    sha1 = EVP_MD_CTX_md_data(ctx);
-+
-+    /* SSLv3 client auth handling: see RFC-6101 5.6.8 */
-+    if (mslen != 48)
-+        return 0;
-+
-+    /* At this point hash contains all handshake messages, update
-+     * with master secret and pad_1.
-+     */
-+
-+    if (SHA1_Update(sha1, ms, mslen) <= 0)
-+        return 0;
-+
-+    /* Set padtmp to pad_1 value */
-+    memset(padtmp, 0x36, sizeof(padtmp));
-+
-+    if (!SHA1_Update(sha1, padtmp, sizeof(padtmp)))
-+        return 0;
-+
-+    if (!SHA1_Final(sha1tmp, sha1))
-+        return 0;
-+
-+    /* Reinitialise context */
-+
-+    if (!SHA1_Init(sha1))
-+        return 0;
-+
-+    if (SHA1_Update(sha1, ms, mslen) <= 0)
-+        return 0;
-+
-+    /* Set padtmp to pad_2 value */
-+    memset(padtmp, 0x5c, sizeof(padtmp));
-+
-+    if (!SHA1_Update(sha1, padtmp, sizeof(padtmp)))
-+        return 0;
-+
-+    if (!SHA1_Update(sha1, sha1tmp, sizeof(sha1tmp)))
-+        return 0;
-+
-+    /* Now when ctx is finalised it will return the SSL v3 hash value */
-+    OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp));
-+
-+    return 1;
-+
-+}
-+
-+static const EVP_MD sha1_md = {
-+    NID_sha1,
-+    NID_sha1WithRSAEncryption,
-+    SHA_DIGEST_LENGTH,
-+    EVP_MD_FLAG_DIGALGID_ABSENT,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    SHA_CBLOCK,
-+    sizeof(EVP_MD *) + sizeof(SHA_CTX),
-+    ctrl
-+};
-+
-+const EVP_MD *EVP_sha1(void)
-+{
-+    return (&sha1_md);
-+}
-+
-+static int init224(EVP_MD_CTX *ctx)
-+{
-+    return SHA224_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int init256(EVP_MD_CTX *ctx)
-+{
-+    return SHA256_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+/*
-+ * Even though there're separate SHA224_[Update|Final], we call
-+ * SHA256 functions even in SHA224 context. This is what happens
-+ * there anyway, so we can spare few CPU cycles:-)
-+ */
-+static int update256(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return SHA256_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final256(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return SHA256_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static const EVP_MD sha224_md = {
-+    NID_sha224,
-+    NID_sha224WithRSAEncryption,
-+    SHA224_DIGEST_LENGTH,
-+    EVP_MD_FLAG_DIGALGID_ABSENT,
-+    init224,
-+    update256,
-+    final256,
-+    NULL,
-+    NULL,
-+    SHA256_CBLOCK,
-+    sizeof(EVP_MD *) + sizeof(SHA256_CTX),
-+};
-+
-+const EVP_MD *EVP_sha224(void)
-+{
-+    return (&sha224_md);
-+}
-+
-+static const EVP_MD sha256_md = {
-+    NID_sha256,
-+    NID_sha256WithRSAEncryption,
-+    SHA256_DIGEST_LENGTH,
-+    EVP_MD_FLAG_DIGALGID_ABSENT,
-+    init256,
-+    update256,
-+    final256,
-+    NULL,
-+    NULL,
-+    SHA256_CBLOCK,
-+    sizeof(EVP_MD *) + sizeof(SHA256_CTX),
-+};
-+
-+const EVP_MD *EVP_sha256(void)
-+{
-+    return (&sha256_md);
-+}
-+
-+static int init384(EVP_MD_CTX *ctx)
-+{
-+    return SHA384_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int init512(EVP_MD_CTX *ctx)
-+{
-+    return SHA512_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+/* See comment in SHA224/256 section */
-+static int update512(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return SHA512_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final512(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return SHA512_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static const EVP_MD sha384_md = {
-+    NID_sha384,
-+    NID_sha384WithRSAEncryption,
-+    SHA384_DIGEST_LENGTH,
-+    EVP_MD_FLAG_DIGALGID_ABSENT,
-+    init384,
-+    update512,
-+    final512,
-+    NULL,
-+    NULL,
-+    SHA512_CBLOCK,
-+    sizeof(EVP_MD *) + sizeof(SHA512_CTX),
-+};
-+
-+const EVP_MD *EVP_sha384(void)
-+{
-+    return (&sha384_md);
-+}
-+
-+static const EVP_MD sha512_md = {
-+    NID_sha512,
-+    NID_sha512WithRSAEncryption,
-+    SHA512_DIGEST_LENGTH,
-+    EVP_MD_FLAG_DIGALGID_ABSENT,
-+    init512,
-+    update512,
-+    final512,
-+    NULL,
-+    NULL,
-+    SHA512_CBLOCK,
-+    sizeof(EVP_MD *) + sizeof(SHA512_CTX),
-+};
-+
-+const EVP_MD *EVP_sha512(void)
-+{
-+    return (&sha512_md);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_sigver.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_sigver.c
-new file mode 100644
-index 0000000..3b74f72
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_sigver.c
-@@ -0,0 +1,169 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+#include "evp_locl.h"
-+
-+static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
-+                          const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
-+                          int ver)
-+{
-+    if (ctx->pctx == NULL)
-+        ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
-+    if (ctx->pctx == NULL)
-+        return 0;
-+
-+    if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {
-+
-+        if (type == NULL) {
-+            int def_nid;
-+            if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
-+                type = EVP_get_digestbynid(def_nid);
-+        }
-+
-+        if (type == NULL) {
-+            EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
-+            return 0;
-+        }
-+    }
-+
-+    if (ver) {
-+        if (ctx->pctx->pmeth->verifyctx_init) {
-+            if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0)
-+                return 0;
-+            ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
-+        } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
-+            return 0;
-+    } else {
-+        if (ctx->pctx->pmeth->signctx_init) {
-+            if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
-+                return 0;
-+            ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
-+        } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
-+            return 0;
-+    }
-+    if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
-+        return 0;
-+    if (pctx)
-+        *pctx = ctx->pctx;
-+    if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
-+        return 1;
-+    if (!EVP_DigestInit_ex(ctx, type, e))
-+        return 0;
-+    return 1;
-+}
-+
-+int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
-+                       const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
-+{
-+    return do_sigver_init(ctx, pctx, type, e, pkey, 0);
-+}
-+
-+int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
-+                         const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
-+{
-+    return do_sigver_init(ctx, pctx, type, e, pkey, 1);
-+}
-+
-+int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
-+                        size_t *siglen)
-+{
-+    int sctx = 0, r = 0;
-+    EVP_PKEY_CTX *pctx = ctx->pctx;
-+    if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
-+        if (!sigret)
-+            return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
-+        if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
-+            r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
-+        else {
-+            EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(ctx->pctx);
-+            if (!dctx)
-+                return 0;
-+            r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
-+            EVP_PKEY_CTX_free(dctx);
-+        }
-+        return r;
-+    }
-+    if (pctx->pmeth->signctx)
-+        sctx = 1;
-+    else
-+        sctx = 0;
-+    if (sigret) {
-+        unsigned char md[EVP_MAX_MD_SIZE];
-+        unsigned int mdlen = 0;
-+        if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
-+            if (sctx)
-+                r = ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx);
-+            else
-+                r = EVP_DigestFinal_ex(ctx, md, &mdlen);
-+        } else {
-+            EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
-+            if (tmp_ctx == NULL || !EVP_MD_CTX_copy_ex(tmp_ctx, ctx))
-+                return 0;
-+            if (sctx)
-+                r = tmp_ctx->pctx->pmeth->signctx(tmp_ctx->pctx,
-+                                                  sigret, siglen, tmp_ctx);
-+            else
-+                r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
-+            EVP_MD_CTX_free(tmp_ctx);
-+        }
-+        if (sctx || !r)
-+            return r;
-+        if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
-+            return 0;
-+    } else {
-+        if (sctx) {
-+            if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0)
-+                return 0;
-+        } else {
-+            int s = EVP_MD_size(ctx->digest);
-+            if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0)
-+                return 0;
-+        }
-+    }
-+    return 1;
-+}
-+
-+int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
-+                          size_t siglen)
-+{
-+    unsigned char md[EVP_MAX_MD_SIZE];
-+    int r = 0;
-+    unsigned int mdlen = 0;
-+    int vctx = 0;
-+
-+    if (ctx->pctx->pmeth->verifyctx)
-+        vctx = 1;
-+    else
-+        vctx = 0;
-+    if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
-+        if (vctx) {
-+            r = ctx->pctx->pmeth->verifyctx(ctx->pctx, sig, siglen, ctx);
-+        } else
-+            r = EVP_DigestFinal_ex(ctx, md, &mdlen);
-+    } else {
-+        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
-+        if (tmp_ctx == NULL || !EVP_MD_CTX_copy_ex(tmp_ctx, ctx))
-+            return -1;
-+        if (vctx) {
-+            r = tmp_ctx->pctx->pmeth->verifyctx(tmp_ctx->pctx,
-+                                                sig, siglen, tmp_ctx);
-+        } else
-+            r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
-+        EVP_MD_CTX_free(tmp_ctx);
-+    }
-+    if (vctx || !r)
-+        return r;
-+    return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_wp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_wp.c
-new file mode 100644
-index 0000000..94fac22
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/m_wp.c
-@@ -0,0 +1,54 @@
-+/*
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+
-+#ifndef OPENSSL_NO_WHIRLPOOL
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "internal/evp_int.h"
-+
-+static int init(EVP_MD_CTX *ctx)
-+{
-+    return WHIRLPOOL_Init(EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    return WHIRLPOOL_Update(EVP_MD_CTX_md_data(ctx), data, count);
-+}
-+
-+static int final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+    return WHIRLPOOL_Final(md, EVP_MD_CTX_md_data(ctx));
-+}
-+
-+static const EVP_MD whirlpool_md = {
-+    NID_whirlpool,
-+    0,
-+    WHIRLPOOL_DIGEST_LENGTH,
-+    0,
-+    init,
-+    update,
-+    final,
-+    NULL,
-+    NULL,
-+    WHIRLPOOL_BBLOCK / 8,
-+    sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX),
-+};
-+
-+const EVP_MD *EVP_whirlpool(void)
-+{
-+    return (&whirlpool_md);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/names.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/names.c
-new file mode 100644
-index 0000000..a92be1f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/names.c
-@@ -0,0 +1,178 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+int EVP_add_cipher(const EVP_CIPHER *c)
-+{
-+    int r;
-+
-+    if (c == NULL)
-+        return 0;
-+
-+    r = OBJ_NAME_add(OBJ_nid2sn(c->nid), OBJ_NAME_TYPE_CIPHER_METH,
-+                     (const char *)c);
-+    if (r == 0)
-+        return (0);
-+    r = OBJ_NAME_add(OBJ_nid2ln(c->nid), OBJ_NAME_TYPE_CIPHER_METH,
-+                     (const char *)c);
-+    return (r);
-+}
-+
-+int EVP_add_digest(const EVP_MD *md)
-+{
-+    int r;
-+    const char *name;
-+
-+    name = OBJ_nid2sn(md->type);
-+    r = OBJ_NAME_add(name, OBJ_NAME_TYPE_MD_METH, (const char *)md);
-+    if (r == 0)
-+        return (0);
-+    r = OBJ_NAME_add(OBJ_nid2ln(md->type), OBJ_NAME_TYPE_MD_METH,
-+                     (const char *)md);
-+    if (r == 0)
-+        return (0);
-+
-+    if (md->pkey_type && md->type != md->pkey_type) {
-+        r = OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
-+                         OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name);
-+        if (r == 0)
-+            return (0);
-+        r = OBJ_NAME_add(OBJ_nid2ln(md->pkey_type),
-+                         OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name);
-+    }
-+    return (r);
-+}
-+
-+const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
-+{
-+    const EVP_CIPHER *cp;
-+
-+    if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL))
-+        return NULL;
-+
-+    cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH);
-+    return (cp);
-+}
-+
-+const EVP_MD *EVP_get_digestbyname(const char *name)
-+{
-+    const EVP_MD *cp;
-+
-+    if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL))
-+        return NULL;
-+
-+    cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
-+    return (cp);
-+}
-+
-+void evp_cleanup_int(void)
-+{
-+    OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
-+    OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
-+    /*
-+     * The above calls will only clean out the contents of the name hash
-+     * table, but not the hash table itself.  The following line does that
-+     * part.  -- Richard Levitte
-+     */
-+    OBJ_NAME_cleanup(-1);
-+
-+    EVP_PBE_cleanup();
-+    OBJ_sigid_free();
-+}
-+
-+struct doall_cipher {
-+    void *arg;
-+    void (*fn) (const EVP_CIPHER *ciph,
-+                const char *from, const char *to, void *arg);
-+};
-+
-+static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg)
-+{
-+    struct doall_cipher *dc = arg;
-+    if (nm->alias)
-+        dc->fn(NULL, nm->name, nm->data, dc->arg);
-+    else
-+        dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg);
-+}
-+
-+void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph,
-+                                   const char *from, const char *to, void *x),
-+                       void *arg)
-+{
-+    struct doall_cipher dc;
-+
-+    /* Ignore errors */
-+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL);
-+
-+    dc.fn = fn;
-+    dc.arg = arg;
-+    OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
-+}
-+
-+void EVP_CIPHER_do_all_sorted(void (*fn) (const EVP_CIPHER *ciph,
-+                                          const char *from, const char *to,
-+                                          void *x), void *arg)
-+{
-+    struct doall_cipher dc;
-+
-+    /* Ignore errors */
-+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL);
-+
-+    dc.fn = fn;
-+    dc.arg = arg;
-+    OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
-+}
-+
-+struct doall_md {
-+    void *arg;
-+    void (*fn) (const EVP_MD *ciph,
-+                const char *from, const char *to, void *arg);
-+};
-+
-+static void do_all_md_fn(const OBJ_NAME *nm, void *arg)
-+{
-+    struct doall_md *dc = arg;
-+    if (nm->alias)
-+        dc->fn(NULL, nm->name, nm->data, dc->arg);
-+    else
-+        dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg);
-+}
-+
-+void EVP_MD_do_all(void (*fn) (const EVP_MD *md,
-+                               const char *from, const char *to, void *x),
-+                   void *arg)
-+{
-+    struct doall_md dc;
-+
-+    /* Ignore errors */
-+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
-+
-+    dc.fn = fn;
-+    dc.arg = arg;
-+    OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
-+}
-+
-+void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md,
-+                                      const char *from, const char *to,
-+                                      void *x), void *arg)
-+{
-+    struct doall_md dc;
-+
-+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
-+
-+    dc.fn = fn;
-+    dc.arg = arg;
-+    OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p5_crpt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p5_crpt.c
-new file mode 100644
-index 0000000..7e55d0b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p5_crpt.c
-@@ -0,0 +1,103 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+/*
-+ * Doesn't do anything now: Builtin PBE algorithms in static table.
-+ */
-+
-+void PKCS5_PBE_add(void)
-+{
-+}
-+
-+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
-+                       ASN1_TYPE *param, const EVP_CIPHER *cipher,
-+                       const EVP_MD *md, int en_de)
-+{
-+    EVP_MD_CTX *ctx;
-+    unsigned char md_tmp[EVP_MAX_MD_SIZE];
-+    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
-+    int i;
-+    PBEPARAM *pbe;
-+    int saltlen, iter;
-+    unsigned char *salt;
-+    int mdsize;
-+    int rv = 0;
-+
-+    /* Extract useful info from parameter */
-+    if (param == NULL || param->type != V_ASN1_SEQUENCE ||
-+        param->value.sequence == NULL) {
-+        EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
-+        return 0;
-+    }
-+
-+    pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param);
-+    if (pbe == NULL) {
-+        EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
-+        return 0;
-+    }
-+
-+    if (!pbe->iter)
-+        iter = 1;
-+    else
-+        iter = ASN1_INTEGER_get(pbe->iter);
-+    salt = pbe->salt->data;
-+    saltlen = pbe->salt->length;
-+
-+    if (!pass)
-+        passlen = 0;
-+    else if (passlen == -1)
-+        passlen = strlen(pass);
-+
-+    ctx = EVP_MD_CTX_new();
-+    if (ctx == NULL) {
-+        EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (!EVP_DigestInit_ex(ctx, md, NULL))
-+        goto err;
-+    if (!EVP_DigestUpdate(ctx, pass, passlen))
-+        goto err;
-+    if (!EVP_DigestUpdate(ctx, salt, saltlen))
-+        goto err;
-+    PBEPARAM_free(pbe);
-+    if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
-+        goto err;
-+    mdsize = EVP_MD_size(md);
-+    if (mdsize < 0)
-+        return 0;
-+    for (i = 1; i < iter; i++) {
-+        if (!EVP_DigestInit_ex(ctx, md, NULL))
-+            goto err;
-+        if (!EVP_DigestUpdate(ctx, md_tmp, mdsize))
-+            goto err;
-+        if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
-+            goto err;
-+    }
-+    OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
-+    memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
-+    OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
-+    memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
-+           EVP_CIPHER_iv_length(cipher));
-+    if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
-+        goto err;
-+    OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
-+    OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
-+    OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
-+    rv = 1;
-+ err:
-+    EVP_MD_CTX_free(ctx);
-+    return rv;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p5_crpt2.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p5_crpt2.c
-new file mode 100644
-index 0000000..2e45aa3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p5_crpt2.c
-@@ -0,0 +1,277 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+# include 
-+# include 
-+# include 
-+# include "evp_locl.h"
-+
-+/* set this to print out info about the keygen algorithm */
-+/* #define OPENSSL_DEBUG_PKCS5V2 */
-+
-+# ifdef OPENSSL_DEBUG_PKCS5V2
-+static void h__dump(const unsigned char *p, int len);
-+# endif
-+
-+/*
-+ * This is an implementation of PKCS#5 v2.0 password based encryption key
-+ * derivation function PBKDF2. SHA1 version verified against test vectors
-+ * posted by Peter Gutmann  to the PKCS-TNG
-+ *  mailing list.
-+ */
-+
-+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
-+                      const unsigned char *salt, int saltlen, int iter,
-+                      const EVP_MD *digest, int keylen, unsigned char *out)
-+{
-+    unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
-+    int cplen, j, k, tkeylen, mdlen;
-+    unsigned long i = 1;
-+    HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;
-+
-+    mdlen = EVP_MD_size(digest);
-+    if (mdlen < 0)
-+        return 0;
-+
-+    hctx_tpl = HMAC_CTX_new();
-+    if (hctx_tpl == NULL)
-+        return 0;
-+    p = out;
-+    tkeylen = keylen;
-+    if (!pass)
-+        passlen = 0;
-+    else if (passlen == -1)
-+        passlen = strlen(pass);
-+    if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) {
-+        HMAC_CTX_free(hctx_tpl);
-+        return 0;
-+    }
-+    hctx = HMAC_CTX_new();
-+    if (hctx == NULL) {
-+        HMAC_CTX_free(hctx_tpl);
-+        return 0;
-+    }
-+    while (tkeylen) {
-+        if (tkeylen > mdlen)
-+            cplen = mdlen;
-+        else
-+            cplen = tkeylen;
-+        /*
-+         * We are unlikely to ever use more than 256 blocks (5120 bits!) but
-+         * just in case...
-+         */
-+        itmp[0] = (unsigned char)((i >> 24) & 0xff);
-+        itmp[1] = (unsigned char)((i >> 16) & 0xff);
-+        itmp[2] = (unsigned char)((i >> 8) & 0xff);
-+        itmp[3] = (unsigned char)(i & 0xff);
-+        if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
-+            HMAC_CTX_free(hctx);
-+            HMAC_CTX_free(hctx_tpl);
-+            return 0;
-+        }
-+        if (!HMAC_Update(hctx, salt, saltlen)
-+            || !HMAC_Update(hctx, itmp, 4)
-+            || !HMAC_Final(hctx, digtmp, NULL)) {
-+            HMAC_CTX_free(hctx);
-+            HMAC_CTX_free(hctx_tpl);
-+            return 0;
-+        }
-+        HMAC_CTX_reset(hctx);
-+        memcpy(p, digtmp, cplen);
-+        for (j = 1; j < iter; j++) {
-+            if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
-+                HMAC_CTX_free(hctx);
-+                HMAC_CTX_free(hctx_tpl);
-+                return 0;
-+            }
-+            if (!HMAC_Update(hctx, digtmp, mdlen)
-+                || !HMAC_Final(hctx, digtmp, NULL)) {
-+                HMAC_CTX_free(hctx);
-+                HMAC_CTX_free(hctx_tpl);
-+                return 0;
-+            }
-+            HMAC_CTX_reset(hctx);
-+            for (k = 0; k < cplen; k++)
-+                p[k] ^= digtmp[k];
-+        }
-+        tkeylen -= cplen;
-+        i++;
-+        p += cplen;
-+    }
-+    HMAC_CTX_free(hctx);
-+    HMAC_CTX_free(hctx_tpl);
-+# ifdef OPENSSL_DEBUG_PKCS5V2
-+    fprintf(stderr, "Password:\n");
-+    h__dump(pass, passlen);
-+    fprintf(stderr, "Salt:\n");
-+    h__dump(salt, saltlen);
-+    fprintf(stderr, "Iteration count %d\n", iter);
-+    fprintf(stderr, "Key:\n");
-+    h__dump(out, keylen);
-+# endif
-+    return 1;
-+}
-+
-+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
-+                           const unsigned char *salt, int saltlen, int iter,
-+                           int keylen, unsigned char *out)
-+{
-+    return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(),
-+                             keylen, out);
-+}
-+
-+# ifdef DO_TEST
-+main()
-+{
-+    unsigned char out[4];
-+    unsigned char salt[] = { 0x12, 0x34, 0x56, 0x78 };
-+    PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out);
-+    fprintf(stderr, "Out %02X %02X %02X %02X\n",
-+            out[0], out[1], out[2], out[3]);
-+}
-+
-+# endif
-+
-+/*
-+ * Now the key derivation function itself. This is a bit evil because it has
-+ * to check the ASN1 parameters are valid: and there are quite a few of
-+ * them...
-+ */
-+
-+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
-+                          ASN1_TYPE *param, const EVP_CIPHER *c,
-+                          const EVP_MD *md, int en_de)
-+{
-+    PBE2PARAM *pbe2 = NULL;
-+    const EVP_CIPHER *cipher;
-+    EVP_PBE_KEYGEN *kdf;
-+
-+    int rv = 0;
-+
-+    pbe2 = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBE2PARAM), param);
-+    if (pbe2 == NULL) {
-+        EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    /* See if we recognise the key derivation function */
-+    if (!EVP_PBE_find(EVP_PBE_TYPE_KDF, OBJ_obj2nid(pbe2->keyfunc->algorithm),
-+                        NULL, NULL, &kdf)) {
-+        EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
-+               EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
-+        goto err;
-+    }
-+
-+    /*
-+     * lets see if we recognise the encryption algorithm.
-+     */
-+
-+    cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
-+
-+    if (!cipher) {
-+        EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER);
-+        goto err;
-+    }
-+
-+    /* Fixup cipher based on AlgorithmIdentifier */
-+    if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
-+        goto err;
-+    if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
-+        EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR);
-+        goto err;
-+    }
-+    rv = kdf(ctx, pass, passlen, pbe2->keyfunc->parameter, NULL, NULL, en_de);
-+ err:
-+    PBE2PARAM_free(pbe2);
-+    return rv;
-+}
-+
-+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
-+                             int passlen, ASN1_TYPE *param,
-+                             const EVP_CIPHER *c, const EVP_MD *md, int en_de)
-+{
-+    unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
-+    int saltlen, iter;
-+    int rv = 0;
-+    unsigned int keylen = 0;
-+    int prf_nid, hmac_md_nid;
-+    PBKDF2PARAM *kdf = NULL;
-+    const EVP_MD *prfmd;
-+
-+    if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
-+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET);
-+        goto err;
-+    }
-+    keylen = EVP_CIPHER_CTX_key_length(ctx);
-+    OPENSSL_assert(keylen <= sizeof key);
-+
-+    /* Decode parameter */
-+
-+    kdf = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), param);
-+
-+    if (kdf == NULL) {
-+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
-+        goto err;
-+    }
-+
-+    keylen = EVP_CIPHER_CTX_key_length(ctx);
-+
-+    /* Now check the parameters of the kdf */
-+
-+    if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) {
-+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH);
-+        goto err;
-+    }
-+
-+    if (kdf->prf)
-+        prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
-+    else
-+        prf_nid = NID_hmacWithSHA1;
-+
-+    if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) {
-+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
-+        goto err;
-+    }
-+
-+    prfmd = EVP_get_digestbynid(hmac_md_nid);
-+    if (prfmd == NULL) {
-+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
-+        goto err;
-+    }
-+
-+    if (kdf->salt->type != V_ASN1_OCTET_STRING) {
-+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE);
-+        goto err;
-+    }
-+
-+    /* it seems that its all OK */
-+    salt = kdf->salt->value.octet_string->data;
-+    saltlen = kdf->salt->value.octet_string->length;
-+    iter = ASN1_INTEGER_get(kdf->iter);
-+    if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
-+                           keylen, key))
-+        goto err;
-+    rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
-+ err:
-+    OPENSSL_cleanse(key, keylen);
-+    PBKDF2PARAM_free(kdf);
-+    return rv;
-+}
-+
-+# ifdef OPENSSL_DEBUG_PKCS5V2
-+static void h__dump(const unsigned char *p, int len)
-+{
-+    for (; len--; p++)
-+        fprintf(stderr, "%02X ", *p);
-+    fprintf(stderr, "\n");
-+}
-+# endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_dec.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_dec.c
-new file mode 100644
-index 0000000..6bec406
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_dec.c
-@@ -0,0 +1,36 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
-+                         EVP_PKEY *priv)
-+{
-+    int ret = -1;
-+
-+#ifndef OPENSSL_NO_RSA
-+    if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) {
-+#endif
-+        EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
-+#ifndef OPENSSL_NO_RSA
-+        goto err;
-+    }
-+
-+    ret =
-+        RSA_private_decrypt(ekl, ek, key, EVP_PKEY_get0_RSA(priv),
-+                            RSA_PKCS1_PADDING);
-+ err:
-+#endif
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_enc.c
-new file mode 100644
-index 0000000..3277fbb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_enc.c
-@@ -0,0 +1,35 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key,
-+                         int key_len, EVP_PKEY *pubk)
-+{
-+    int ret = 0;
-+
-+#ifndef OPENSSL_NO_RSA
-+    if (EVP_PKEY_id(pubk) != EVP_PKEY_RSA) {
-+#endif
-+        EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
-+#ifndef OPENSSL_NO_RSA
-+        goto err;
-+    }
-+    ret =
-+        RSA_public_encrypt(key_len, key, ek, EVP_PKEY_get0_RSA(pubk),
-+                           RSA_PKCS1_PADDING);
-+ err:
-+#endif
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_lib.c
-new file mode 100644
-index 0000000..9828620
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_lib.c
-@@ -0,0 +1,484 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+static void EVP_PKEY_free_it(EVP_PKEY *x);
-+
-+int EVP_PKEY_bits(const EVP_PKEY *pkey)
-+{
-+    if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
-+        return pkey->ameth->pkey_bits(pkey);
-+    return 0;
-+}
-+
-+int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
-+{
-+    if (pkey == NULL)
-+        return 0;
-+    if (!pkey->ameth || !pkey->ameth->pkey_security_bits)
-+        return -2;
-+    return pkey->ameth->pkey_security_bits(pkey);
-+}
-+
-+int EVP_PKEY_size(EVP_PKEY *pkey)
-+{
-+    if (pkey && pkey->ameth && pkey->ameth->pkey_size)
-+        return pkey->ameth->pkey_size(pkey);
-+    return 0;
-+}
-+
-+int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
-+{
-+#ifndef OPENSSL_NO_DSA
-+    if (pkey->type == EVP_PKEY_DSA) {
-+        int ret = pkey->save_parameters;
-+
-+        if (mode >= 0)
-+            pkey->save_parameters = mode;
-+        return (ret);
-+    }
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    if (pkey->type == EVP_PKEY_EC) {
-+        int ret = pkey->save_parameters;
-+
-+        if (mode >= 0)
-+            pkey->save_parameters = mode;
-+        return (ret);
-+    }
-+#endif
-+    return (0);
-+}
-+
-+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
-+{
-+    if (to->type == EVP_PKEY_NONE) {
-+        if (EVP_PKEY_set_type(to, from->type) == 0)
-+            return 0;
-+    } else if (to->type != from->type) {
-+        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
-+        goto err;
-+    }
-+
-+    if (EVP_PKEY_missing_parameters(from)) {
-+        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS);
-+        goto err;
-+    }
-+
-+    if (!EVP_PKEY_missing_parameters(to)) {
-+        if (EVP_PKEY_cmp_parameters(to, from) == 1)
-+            return 1;
-+        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS);
-+        return 0;
-+    }
-+
-+    if (from->ameth && from->ameth->param_copy)
-+        return from->ameth->param_copy(to, from);
-+ err:
-+    return 0;
-+}
-+
-+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
-+{
-+    if (pkey->ameth && pkey->ameth->param_missing)
-+        return pkey->ameth->param_missing(pkey);
-+    return 0;
-+}
-+
-+int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    if (a->type != b->type)
-+        return -1;
-+    if (a->ameth && a->ameth->param_cmp)
-+        return a->ameth->param_cmp(a, b);
-+    return -2;
-+}
-+
-+int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    if (a->type != b->type)
-+        return -1;
-+
-+    if (a->ameth) {
-+        int ret;
-+        /* Compare parameters if the algorithm has them */
-+        if (a->ameth->param_cmp) {
-+            ret = a->ameth->param_cmp(a, b);
-+            if (ret <= 0)
-+                return ret;
-+        }
-+
-+        if (a->ameth->pub_cmp)
-+            return a->ameth->pub_cmp(a, b);
-+    }
-+
-+    return -2;
-+}
-+
-+EVP_PKEY *EVP_PKEY_new(void)
-+{
-+    EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    ret->type = EVP_PKEY_NONE;
-+    ret->save_type = EVP_PKEY_NONE;
-+    ret->references = 1;
-+    ret->save_parameters = 1;
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+int EVP_PKEY_up_ref(EVP_PKEY *pkey)
-+{
-+    int i;
-+
-+    if (CRYPTO_atomic_add(&pkey->references, 1, &i, pkey->lock) <= 0)
-+        return 0;
-+
-+    REF_PRINT_COUNT("EVP_PKEY", pkey);
-+    REF_ASSERT_ISNT(i < 2);
-+    return ((i > 1) ? 1 : 0);
-+}
-+
-+/*
-+ * Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey
-+ * is NULL just return 1 or 0 if the algorithm exists.
-+ */
-+
-+static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
-+{
-+    const EVP_PKEY_ASN1_METHOD *ameth;
-+    ENGINE *e = NULL;
-+    if (pkey) {
-+        if (pkey->pkey.ptr)
-+            EVP_PKEY_free_it(pkey);
-+        /*
-+         * If key type matches and a method exists then this lookup has
-+         * succeeded once so just indicate success.
-+         */
-+        if ((type == pkey->save_type) && pkey->ameth)
-+            return 1;
-+#ifndef OPENSSL_NO_ENGINE
-+        /* If we have an ENGINE release it */
-+        ENGINE_finish(pkey->engine);
-+        pkey->engine = NULL;
-+#endif
-+    }
-+    if (str)
-+        ameth = EVP_PKEY_asn1_find_str(&e, str, len);
-+    else
-+        ameth = EVP_PKEY_asn1_find(&e, type);
-+#ifndef OPENSSL_NO_ENGINE
-+    if (pkey == NULL)
-+        ENGINE_finish(e);
-+#endif
-+    if (ameth == NULL) {
-+        EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
-+        return 0;
-+    }
-+    if (pkey) {
-+        pkey->ameth = ameth;
-+        pkey->engine = e;
-+
-+        pkey->type = pkey->ameth->pkey_id;
-+        pkey->save_type = type;
-+    }
-+    return 1;
-+}
-+
-+int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
-+{
-+    return pkey_set_type(pkey, type, NULL, -1);
-+}
-+
-+int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
-+{
-+    return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
-+}
-+
-+int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
-+{
-+    if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
-+        return 0;
-+    pkey->pkey.ptr = key;
-+    return (key != NULL);
-+}
-+
-+void *EVP_PKEY_get0(const EVP_PKEY *pkey)
-+{
-+    return pkey->pkey.ptr;
-+}
-+
-+const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
-+{
-+    ASN1_OCTET_STRING *os = NULL;
-+    if (pkey->type != EVP_PKEY_HMAC) {
-+        EVPerr(EVP_F_EVP_PKEY_GET0_HMAC, EVP_R_EXPECTING_AN_HMAC_KEY);
-+        return NULL;
-+    }
-+    os = EVP_PKEY_get0(pkey);
-+    *len = os->length;
-+    return os->data;
-+}
-+
-+#ifndef OPENSSL_NO_RSA
-+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
-+{
-+    int ret = EVP_PKEY_assign_RSA(pkey, key);
-+    if (ret)
-+        RSA_up_ref(key);
-+    return ret;
-+}
-+
-+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
-+{
-+    if (pkey->type != EVP_PKEY_RSA) {
-+        EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
-+        return NULL;
-+    }
-+    return pkey->pkey.rsa;
-+}
-+
-+RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
-+{
-+    RSA *ret = EVP_PKEY_get0_RSA(pkey);
-+    if (ret != NULL)
-+        RSA_up_ref(ret);
-+    return ret;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_DSA
-+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
-+{
-+    int ret = EVP_PKEY_assign_DSA(pkey, key);
-+    if (ret)
-+        DSA_up_ref(key);
-+    return ret;
-+}
-+
-+DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
-+{
-+    if (pkey->type != EVP_PKEY_DSA) {
-+        EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY);
-+        return NULL;
-+    }
-+    return pkey->pkey.dsa;
-+}
-+
-+DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
-+{
-+    DSA *ret = EVP_PKEY_get0_DSA(pkey);
-+    if (ret != NULL)
-+        DSA_up_ref(ret);
-+    return ret;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_EC
-+
-+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
-+{
-+    int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
-+    if (ret)
-+        EC_KEY_up_ref(key);
-+    return ret;
-+}
-+
-+EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
-+{
-+    if (pkey->type != EVP_PKEY_EC) {
-+        EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
-+        return NULL;
-+    }
-+    return pkey->pkey.ec;
-+}
-+
-+EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
-+{
-+    EC_KEY *ret = EVP_PKEY_get0_EC_KEY(pkey);
-+    if (ret != NULL)
-+        EC_KEY_up_ref(ret);
-+    return ret;
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_DH
-+
-+int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
-+{
-+    int ret = EVP_PKEY_assign_DH(pkey, key);
-+    if (ret)
-+        DH_up_ref(key);
-+    return ret;
-+}
-+
-+DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey)
-+{
-+    if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
-+        EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY);
-+        return NULL;
-+    }
-+    return pkey->pkey.dh;
-+}
-+
-+DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
-+{
-+    DH *ret = EVP_PKEY_get0_DH(pkey);
-+    if (ret != NULL)
-+        DH_up_ref(ret);
-+    return ret;
-+}
-+#endif
-+
-+int EVP_PKEY_type(int type)
-+{
-+    int ret;
-+    const EVP_PKEY_ASN1_METHOD *ameth;
-+    ENGINE *e;
-+    ameth = EVP_PKEY_asn1_find(&e, type);
-+    if (ameth)
-+        ret = ameth->pkey_id;
-+    else
-+        ret = NID_undef;
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(e);
-+#endif
-+    return ret;
-+}
-+
-+int EVP_PKEY_id(const EVP_PKEY *pkey)
-+{
-+    return pkey->type;
-+}
-+
-+int EVP_PKEY_base_id(const EVP_PKEY *pkey)
-+{
-+    return EVP_PKEY_type(pkey->type);
-+}
-+
-+void EVP_PKEY_free(EVP_PKEY *x)
-+{
-+    int i;
-+
-+    if (x == NULL)
-+        return;
-+
-+    CRYPTO_atomic_add(&x->references, -1, &i, x->lock);
-+    REF_PRINT_COUNT("EVP_PKEY", x);
-+    if (i > 0)
-+        return;
-+    REF_ASSERT_ISNT(i < 0);
-+    EVP_PKEY_free_it(x);
-+    CRYPTO_THREAD_lock_free(x->lock);
-+    sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
-+    OPENSSL_free(x);
-+}
-+
-+static void EVP_PKEY_free_it(EVP_PKEY *x)
-+{
-+    /* internal function; x is never NULL */
-+    if (x->ameth && x->ameth->pkey_free) {
-+        x->ameth->pkey_free(x);
-+        x->pkey.ptr = NULL;
-+    }
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(x->engine);
-+    x->engine = NULL;
-+#endif
-+}
-+
-+static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
-+                     const char *kstr)
-+{
-+    BIO_indent(out, indent, 128);
-+    BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
-+               kstr, OBJ_nid2ln(pkey->type));
-+    return 1;
-+}
-+
-+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
-+                          int indent, ASN1_PCTX *pctx)
-+{
-+    if (pkey->ameth && pkey->ameth->pub_print)
-+        return pkey->ameth->pub_print(out, pkey, indent, pctx);
-+
-+    return unsup_alg(out, pkey, indent, "Public Key");
-+}
-+
-+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
-+                           int indent, ASN1_PCTX *pctx)
-+{
-+    if (pkey->ameth && pkey->ameth->priv_print)
-+        return pkey->ameth->priv_print(out, pkey, indent, pctx);
-+
-+    return unsup_alg(out, pkey, indent, "Private Key");
-+}
-+
-+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
-+                          int indent, ASN1_PCTX *pctx)
-+{
-+    if (pkey->ameth && pkey->ameth->param_print)
-+        return pkey->ameth->param_print(out, pkey, indent, pctx);
-+    return unsup_alg(out, pkey, indent, "Parameters");
-+}
-+
-+static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
-+{
-+    if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
-+        return -2;
-+    return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
-+}
-+
-+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
-+{
-+    return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
-+}
-+
-+int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
-+                               const unsigned char *pt, size_t ptlen)
-+{
-+    if (ptlen > INT_MAX)
-+        return 0;
-+    if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen,
-+                           (void *)pt) <= 0)
-+        return 0;
-+    return 1;
-+}
-+
-+size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
-+{
-+    int rv;
-+    rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt);
-+    if (rv <= 0)
-+        return 0;
-+    return rv;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_open.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_open.c
-new file mode 100644
-index 0000000..b65bc74
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_open.c
-@@ -0,0 +1,73 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#ifdef OPENSSL_NO_RSA
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+
-+int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
-+                 const unsigned char *ek, int ekl, const unsigned char *iv,
-+                 EVP_PKEY *priv)
-+{
-+    unsigned char *key = NULL;
-+    int i, size = 0, ret = 0;
-+
-+    if (type) {
-+        EVP_CIPHER_CTX_reset(ctx);
-+        if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL))
-+            return 0;
-+    }
-+
-+    if (!priv)
-+        return 1;
-+
-+    if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) {
-+        EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA);
-+        goto err;
-+    }
-+
-+    size = EVP_PKEY_size(priv);
-+    key = OPENSSL_malloc(size + 2);
-+    if (key == NULL) {
-+        /* ERROR */
-+        EVPerr(EVP_F_EVP_OPENINIT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    i = EVP_PKEY_decrypt_old(key, ek, ekl, priv);
-+    if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) {
-+        /* ERROR */
-+        goto err;
-+    }
-+    if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    OPENSSL_clear_free(key, size);
-+    return (ret);
-+}
-+
-+int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
-+{
-+    int i;
-+
-+    i = EVP_DecryptFinal_ex(ctx, out, outl);
-+    if (i)
-+        i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
-+    return (i);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_seal.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_seal.c
-new file mode 100644
-index 0000000..faa2464
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_seal.c
-@@ -0,0 +1,70 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
-+                 unsigned char **ek, int *ekl, unsigned char *iv,
-+                 EVP_PKEY **pubk, int npubk)
-+{
-+    unsigned char key[EVP_MAX_KEY_LENGTH];
-+    int i;
-+
-+    if (type) {
-+        EVP_CIPHER_CTX_reset(ctx);
-+        if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL))
-+            return 0;
-+    }
-+    if ((npubk <= 0) || !pubk)
-+        return 1;
-+    if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
-+        return 0;
-+    if (EVP_CIPHER_CTX_iv_length(ctx)
-+        && RAND_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx)) <= 0)
-+        return 0;
-+
-+    if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
-+        return 0;
-+
-+    for (i = 0; i < npubk; i++) {
-+        ekl[i] =
-+            EVP_PKEY_encrypt_old(ek[i], key, EVP_CIPHER_CTX_key_length(ctx),
-+                                 pubk[i]);
-+        if (ekl[i] <= 0)
-+            return (-1);
-+    }
-+    return (npubk);
-+}
-+
-+/*- MACRO
-+void EVP_SealUpdate(ctx,out,outl,in,inl)
-+EVP_CIPHER_CTX *ctx;
-+unsigned char *out;
-+int *outl;
-+unsigned char *in;
-+int inl;
-+        {
-+        EVP_EncryptUpdate(ctx,out,outl,in,inl);
-+        }
-+*/
-+
-+int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
-+{
-+    int i;
-+    i = EVP_EncryptFinal_ex(ctx, out, outl);
-+    if (i)
-+        i = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, NULL);
-+    return i;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_sign.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_sign.c
-new file mode 100644
-index 0000000..6cb442e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_sign.c
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
-+                  unsigned int *siglen, EVP_PKEY *pkey)
-+{
-+    unsigned char m[EVP_MAX_MD_SIZE];
-+    unsigned int m_len = 0;
-+    int i = 0;
-+    size_t sltmp;
-+    EVP_PKEY_CTX *pkctx = NULL;
-+
-+    *siglen = 0;
-+    if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_FINALISE)) {
-+        if (!EVP_DigestFinal_ex(ctx, m, &m_len))
-+            goto err;
-+    } else {
-+        int rv = 0;
-+        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
-+        if (tmp_ctx == NULL) {
-+            EVPerr(EVP_F_EVP_SIGNFINAL, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
-+        if (rv)
-+            rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
-+        EVP_MD_CTX_free(tmp_ctx);
-+        if (!rv)
-+            return 0;
-+    }
-+
-+    sltmp = (size_t)EVP_PKEY_size(pkey);
-+    i = 0;
-+    pkctx = EVP_PKEY_CTX_new(pkey, NULL);
-+    if (pkctx == NULL)
-+        goto err;
-+    if (EVP_PKEY_sign_init(pkctx) <= 0)
-+        goto err;
-+    if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0)
-+        goto err;
-+    if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
-+        goto err;
-+    *siglen = sltmp;
-+    i = 1;
-+ err:
-+    EVP_PKEY_CTX_free(pkctx);
-+    return i;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_verify.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_verify.c
-new file mode 100644
-index 0000000..6e8c565
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/p_verify.c
-@@ -0,0 +1,55 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
-+                    unsigned int siglen, EVP_PKEY *pkey)
-+{
-+    unsigned char m[EVP_MAX_MD_SIZE];
-+    unsigned int m_len = 0;
-+    int i = 0;
-+    EVP_PKEY_CTX *pkctx = NULL;
-+
-+    if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_FINALISE)) {
-+        if (!EVP_DigestFinal_ex(ctx, m, &m_len))
-+            goto err;
-+    } else {
-+        int rv = 0;
-+        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
-+        if (tmp_ctx == NULL) {
-+            EVPerr(EVP_F_EVP_VERIFYFINAL, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
-+        if (rv)
-+            rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
-+        EVP_MD_CTX_free(tmp_ctx);
-+        if (!rv)
-+            return 0;
-+    }
-+
-+    i = -1;
-+    pkctx = EVP_PKEY_CTX_new(pkey, NULL);
-+    if (pkctx == NULL)
-+        goto err;
-+    if (EVP_PKEY_verify_init(pkctx) <= 0)
-+        goto err;
-+    if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0)
-+        goto err;
-+    i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
-+ err:
-+    EVP_PKEY_CTX_free(pkctx);
-+    return i;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_fn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_fn.c
-new file mode 100644
-index 0000000..eb63801
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_fn.c
-@@ -0,0 +1,297 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+#define M_check_autoarg(ctx, arg, arglen, err) \
-+    if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) {           \
-+        size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey);         \
-+                                                                  \
-+        if (pksize == 0) {                                        \
-+            EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/      \
-+            return 0;                                             \
-+        }                                                         \
-+        if (!arg) {                                               \
-+            *arglen = pksize;                                     \
-+            return 1;                                             \
-+        }                                                         \
-+        if (*arglen < pksize) {                                   \
-+            EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \
-+            return 0;                                             \
-+        }                                                         \
-+    }
-+
-+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
-+        EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    ctx->operation = EVP_PKEY_OP_SIGN;
-+    if (!ctx->pmeth->sign_init)
-+        return 1;
-+    ret = ctx->pmeth->sign_init(ctx);
-+    if (ret <= 0)
-+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
-+    return ret;
-+}
-+
-+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
-+                  unsigned char *sig, size_t *siglen,
-+                  const unsigned char *tbs, size_t tbslen)
-+{
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
-+        EVPerr(EVP_F_EVP_PKEY_SIGN,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    if (ctx->operation != EVP_PKEY_OP_SIGN) {
-+        EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
-+        return -1;
-+    }
-+    M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
-+        return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
-+}
-+
-+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
-+        EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    ctx->operation = EVP_PKEY_OP_VERIFY;
-+    if (!ctx->pmeth->verify_init)
-+        return 1;
-+    ret = ctx->pmeth->verify_init(ctx);
-+    if (ret <= 0)
-+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
-+    return ret;
-+}
-+
-+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
-+                    const unsigned char *sig, size_t siglen,
-+                    const unsigned char *tbs, size_t tbslen)
-+{
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
-+        EVPerr(EVP_F_EVP_PKEY_VERIFY,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    if (ctx->operation != EVP_PKEY_OP_VERIFY) {
-+        EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
-+        return -1;
-+    }
-+    return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
-+}
-+
-+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
-+        EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
-+    if (!ctx->pmeth->verify_recover_init)
-+        return 1;
-+    ret = ctx->pmeth->verify_recover_init(ctx);
-+    if (ret <= 0)
-+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
-+    return ret;
-+}
-+
-+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
-+                            unsigned char *rout, size_t *routlen,
-+                            const unsigned char *sig, size_t siglen)
-+{
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
-+        EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
-+        EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
-+        return -1;
-+    }
-+    M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
-+        return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
-+}
-+
-+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
-+        EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    ctx->operation = EVP_PKEY_OP_ENCRYPT;
-+    if (!ctx->pmeth->encrypt_init)
-+        return 1;
-+    ret = ctx->pmeth->encrypt_init(ctx);
-+    if (ret <= 0)
-+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
-+    return ret;
-+}
-+
-+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
-+                     unsigned char *out, size_t *outlen,
-+                     const unsigned char *in, size_t inlen)
-+{
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
-+        EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
-+        EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
-+        return -1;
-+    }
-+    M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
-+        return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
-+}
-+
-+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
-+        EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    ctx->operation = EVP_PKEY_OP_DECRYPT;
-+    if (!ctx->pmeth->decrypt_init)
-+        return 1;
-+    ret = ctx->pmeth->decrypt_init(ctx);
-+    if (ret <= 0)
-+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
-+    return ret;
-+}
-+
-+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
-+                     unsigned char *out, size_t *outlen,
-+                     const unsigned char *in, size_t inlen)
-+{
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
-+        EVPerr(EVP_F_EVP_PKEY_DECRYPT,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
-+        EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
-+        return -1;
-+    }
-+    M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
-+        return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
-+}
-+
-+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
-+        EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    ctx->operation = EVP_PKEY_OP_DERIVE;
-+    if (!ctx->pmeth->derive_init)
-+        return 1;
-+    ret = ctx->pmeth->derive_init(ctx);
-+    if (ret <= 0)
-+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
-+    return ret;
-+}
-+
-+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth
-+        || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt)
-+        || !ctx->pmeth->ctrl) {
-+        EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    if (ctx->operation != EVP_PKEY_OP_DERIVE
-+        && ctx->operation != EVP_PKEY_OP_ENCRYPT
-+        && ctx->operation != EVP_PKEY_OP_DECRYPT) {
-+        EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
-+               EVP_R_OPERATON_NOT_INITIALIZED);
-+        return -1;
-+    }
-+
-+    ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
-+
-+    if (ret <= 0)
-+        return ret;
-+
-+    if (ret == 2)
-+        return 1;
-+
-+    if (!ctx->pkey) {
-+        EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
-+        return -1;
-+    }
-+
-+    if (ctx->pkey->type != peer->type) {
-+        EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES);
-+        return -1;
-+    }
-+
-+    /*
-+     * ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
-+     * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
-+     * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
-+     * (different key types) is impossible here because it is checked earlier.
-+     * -2 is OK for us here, as well as 1, so we can check for 0 only.
-+     */
-+    if (!EVP_PKEY_missing_parameters(peer) &&
-+        !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
-+        EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS);
-+        return -1;
-+    }
-+
-+    EVP_PKEY_free(ctx->peerkey);
-+    ctx->peerkey = peer;
-+
-+    ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
-+
-+    if (ret <= 0) {
-+        ctx->peerkey = NULL;
-+        return ret;
-+    }
-+
-+    EVP_PKEY_up_ref(peer);
-+    return 1;
-+}
-+
-+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
-+{
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
-+        EVPerr(EVP_F_EVP_PKEY_DERIVE,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    if (ctx->operation != EVP_PKEY_OP_DERIVE) {
-+        EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
-+        return -1;
-+    }
-+    M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
-+        return ctx->pmeth->derive(ctx, key, pkeylen);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_gn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_gn.c
-new file mode 100644
-index 0000000..6adc3a9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_gn.c
-@@ -0,0 +1,169 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/bn_int.h"
-+#include "internal/evp_int.h"
-+
-+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
-+        EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    ctx->operation = EVP_PKEY_OP_PARAMGEN;
-+    if (!ctx->pmeth->paramgen_init)
-+        return 1;
-+    ret = ctx->pmeth->paramgen_init(ctx);
-+    if (ret <= 0)
-+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
-+    return ret;
-+}
-+
-+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
-+        EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+
-+    if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
-+        EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
-+        return -1;
-+    }
-+
-+    if (ppkey == NULL)
-+        return -1;
-+
-+    if (*ppkey == NULL)
-+        *ppkey = EVP_PKEY_new();
-+
-+    if (*ppkey == NULL) {
-+        EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE);
-+        return -1;
-+    }
-+
-+    ret = ctx->pmeth->paramgen(ctx, *ppkey);
-+    if (ret <= 0) {
-+        EVP_PKEY_free(*ppkey);
-+        *ppkey = NULL;
-+    }
-+    return ret;
-+}
-+
-+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
-+        EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    ctx->operation = EVP_PKEY_OP_KEYGEN;
-+    if (!ctx->pmeth->keygen_init)
-+        return 1;
-+    ret = ctx->pmeth->keygen_init(ctx);
-+    if (ret <= 0)
-+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
-+    return ret;
-+}
-+
-+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
-+{
-+    int ret;
-+
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
-+        EVPerr(EVP_F_EVP_PKEY_KEYGEN,
-+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+    }
-+    if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
-+        EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
-+        return -1;
-+    }
-+
-+    if (ppkey == NULL)
-+        return -1;
-+
-+    if (*ppkey == NULL)
-+        *ppkey = EVP_PKEY_new();
-+    if (*ppkey == NULL)
-+        return -1;
-+
-+    ret = ctx->pmeth->keygen(ctx, *ppkey);
-+    if (ret <= 0) {
-+        EVP_PKEY_free(*ppkey);
-+        *ppkey = NULL;
-+    }
-+    return ret;
-+}
-+
-+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
-+{
-+    ctx->pkey_gencb = cb;
-+}
-+
-+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
-+{
-+    return ctx->pkey_gencb;
-+}
-+
-+/*
-+ * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style
-+ * callbacks.
-+ */
-+
-+static int trans_cb(int a, int b, BN_GENCB *gcb)
-+{
-+    EVP_PKEY_CTX *ctx = BN_GENCB_get_arg(gcb);
-+    ctx->keygen_info[0] = a;
-+    ctx->keygen_info[1] = b;
-+    return ctx->pkey_gencb(ctx);
-+}
-+
-+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
-+{
-+    BN_GENCB_set(cb, trans_cb, ctx);
-+}
-+
-+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
-+{
-+    if (idx == -1)
-+        return ctx->keygen_info_count;
-+    if (idx < 0 || idx > ctx->keygen_info_count)
-+        return 0;
-+    return ctx->keygen_info[idx];
-+}
-+
-+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
-+                               const unsigned char *key, int keylen)
-+{
-+    EVP_PKEY_CTX *mac_ctx = NULL;
-+    EVP_PKEY *mac_key = NULL;
-+    mac_ctx = EVP_PKEY_CTX_new_id(type, e);
-+    if (!mac_ctx)
-+        return NULL;
-+    if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
-+        goto merr;
-+    if (EVP_PKEY_CTX_set_mac_key(mac_ctx, key, keylen) <= 0)
-+        goto merr;
-+    if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
-+        goto merr;
-+ merr:
-+    EVP_PKEY_CTX_free(mac_ctx);
-+    return mac_key;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_lib.c
-new file mode 100644
-index 0000000..b7f06be
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/pmeth_lib.c
-@@ -0,0 +1,721 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+#include "internal/numbers.h"
-+
-+typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
-+
-+static STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
-+
-+static const EVP_PKEY_METHOD *standard_methods[] = {
-+#ifndef OPENSSL_NO_RSA
-+    &rsa_pkey_meth,
-+#endif
-+#ifndef OPENSSL_NO_DH
-+    &dh_pkey_meth,
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+    &dsa_pkey_meth,
-+#endif
-+#ifndef OPENSSL_NO_EC
-+    &ec_pkey_meth,
-+#endif
-+    &hmac_pkey_meth,
-+#ifndef OPENSSL_NO_CMAC
-+    &cmac_pkey_meth,
-+#endif
-+#ifndef OPENSSL_NO_DH
-+    &dhx_pkey_meth,
-+#endif
-+    &tls1_prf_pkey_meth,
-+#ifndef OPENSSL_NO_EC
-+    &ecx25519_pkey_meth,
-+#endif
-+    &hkdf_pkey_meth
-+};
-+
-+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
-+                           pmeth);
-+
-+static int pmeth_cmp(const EVP_PKEY_METHOD *const *a,
-+                     const EVP_PKEY_METHOD *const *b)
-+{
-+    return ((*a)->pkey_id - (*b)->pkey_id);
-+}
-+
-+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
-+                             pmeth);
-+
-+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
-+{
-+    EVP_PKEY_METHOD tmp;
-+    const EVP_PKEY_METHOD *t = &tmp, **ret;
-+    tmp.pkey_id = type;
-+    if (app_pkey_methods) {
-+        int idx;
-+        idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
-+        if (idx >= 0)
-+            return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
-+    }
-+    ret = OBJ_bsearch_pmeth(&t, standard_methods,
-+                            sizeof(standard_methods) /
-+                            sizeof(EVP_PKEY_METHOD *));
-+    if (!ret || !*ret)
-+        return NULL;
-+    return *ret;
-+}
-+
-+static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
-+{
-+    EVP_PKEY_CTX *ret;
-+    const EVP_PKEY_METHOD *pmeth;
-+    if (id == -1) {
-+        if (!pkey || !pkey->ameth)
-+            return NULL;
-+        id = pkey->ameth->pkey_id;
-+    }
-+#ifndef OPENSSL_NO_ENGINE
-+    if (pkey && pkey->engine)
-+        e = pkey->engine;
-+    /* Try to find an ENGINE which implements this method */
-+    if (e) {
-+        if (!ENGINE_init(e)) {
-+            EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB);
-+            return NULL;
-+        }
-+    } else
-+        e = ENGINE_get_pkey_meth_engine(id);
-+
-+    /*
-+     * If an ENGINE handled this method look it up. Otherwise use internal
-+     * tables.
-+     */
-+
-+    if (e)
-+        pmeth = ENGINE_get_pkey_meth(e, id);
-+    else
-+#endif
-+        pmeth = EVP_PKEY_meth_find(id);
-+
-+    if (pmeth == NULL) {
-+        EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
-+        return NULL;
-+    }
-+
-+    ret = OPENSSL_zalloc(sizeof(*ret));
-+    if (ret == NULL) {
-+#ifndef OPENSSL_NO_ENGINE
-+        ENGINE_finish(e);
-+#endif
-+        EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    ret->engine = e;
-+    ret->pmeth = pmeth;
-+    ret->operation = EVP_PKEY_OP_UNDEFINED;
-+    ret->pkey = pkey;
-+    if (pkey)
-+        EVP_PKEY_up_ref(pkey);
-+
-+    if (pmeth->init) {
-+        if (pmeth->init(ret) <= 0) {
-+            ret->pmeth = NULL;
-+            EVP_PKEY_CTX_free(ret);
-+            return NULL;
-+        }
-+    }
-+
-+    return ret;
-+}
-+
-+EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
-+{
-+    EVP_PKEY_METHOD *pmeth;
-+
-+    pmeth = OPENSSL_zalloc(sizeof(*pmeth));
-+    if (pmeth == NULL)
-+        return NULL;
-+
-+    pmeth->pkey_id = id;
-+    pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
-+    return pmeth;
-+}
-+
-+void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
-+                             const EVP_PKEY_METHOD *meth)
-+{
-+    if (ppkey_id)
-+        *ppkey_id = meth->pkey_id;
-+    if (pflags)
-+        *pflags = meth->flags;
-+}
-+
-+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
-+{
-+
-+    dst->init = src->init;
-+    dst->copy = src->copy;
-+    dst->cleanup = src->cleanup;
-+
-+    dst->paramgen_init = src->paramgen_init;
-+    dst->paramgen = src->paramgen;
-+
-+    dst->keygen_init = src->keygen_init;
-+    dst->keygen = src->keygen;
-+
-+    dst->sign_init = src->sign_init;
-+    dst->sign = src->sign;
-+
-+    dst->verify_init = src->verify_init;
-+    dst->verify = src->verify;
-+
-+    dst->verify_recover_init = src->verify_recover_init;
-+    dst->verify_recover = src->verify_recover;
-+
-+    dst->signctx_init = src->signctx_init;
-+    dst->signctx = src->signctx;
-+
-+    dst->verifyctx_init = src->verifyctx_init;
-+    dst->verifyctx = src->verifyctx;
-+
-+    dst->encrypt_init = src->encrypt_init;
-+    dst->encrypt = src->encrypt;
-+
-+    dst->decrypt_init = src->decrypt_init;
-+    dst->decrypt = src->decrypt;
-+
-+    dst->derive_init = src->derive_init;
-+    dst->derive = src->derive;
-+
-+    dst->ctrl = src->ctrl;
-+    dst->ctrl_str = src->ctrl_str;
-+}
-+
-+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
-+{
-+    if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
-+        OPENSSL_free(pmeth);
-+}
-+
-+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
-+{
-+    return int_ctx_new(pkey, e, -1);
-+}
-+
-+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
-+{
-+    return int_ctx_new(NULL, e, id);
-+}
-+
-+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
-+{
-+    EVP_PKEY_CTX *rctx;
-+    if (!pctx->pmeth || !pctx->pmeth->copy)
-+        return NULL;
-+#ifndef OPENSSL_NO_ENGINE
-+    /* Make sure it's safe to copy a pkey context using an ENGINE */
-+    if (pctx->engine && !ENGINE_init(pctx->engine)) {
-+        EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB);
-+        return 0;
-+    }
-+#endif
-+    rctx = OPENSSL_malloc(sizeof(*rctx));
-+    if (rctx == NULL)
-+        return NULL;
-+
-+    rctx->pmeth = pctx->pmeth;
-+#ifndef OPENSSL_NO_ENGINE
-+    rctx->engine = pctx->engine;
-+#endif
-+
-+    if (pctx->pkey)
-+        EVP_PKEY_up_ref(pctx->pkey);
-+
-+    rctx->pkey = pctx->pkey;
-+
-+    if (pctx->peerkey)
-+        EVP_PKEY_up_ref(pctx->peerkey);
-+
-+    rctx->peerkey = pctx->peerkey;
-+
-+    rctx->data = NULL;
-+    rctx->app_data = NULL;
-+    rctx->operation = pctx->operation;
-+
-+    if (pctx->pmeth->copy(rctx, pctx) > 0)
-+        return rctx;
-+
-+    rctx->pmeth = NULL;
-+    EVP_PKEY_CTX_free(rctx);
-+    return NULL;
-+
-+}
-+
-+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
-+{
-+    if (app_pkey_methods == NULL) {
-+        app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
-+        if (app_pkey_methods == NULL)
-+            return 0;
-+    }
-+    if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
-+        return 0;
-+    sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
-+    return 1;
-+}
-+
-+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
-+{
-+    if (ctx == NULL)
-+        return;
-+    if (ctx->pmeth && ctx->pmeth->cleanup)
-+        ctx->pmeth->cleanup(ctx);
-+    EVP_PKEY_free(ctx->pkey);
-+    EVP_PKEY_free(ctx->peerkey);
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(ctx->engine);
-+#endif
-+    OPENSSL_free(ctx);
-+}
-+
-+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
-+                      int cmd, int p1, void *p2)
-+{
-+    int ret;
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
-+        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
-+        return -2;
-+    }
-+    if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
-+        return -1;
-+
-+    if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
-+        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
-+        return -1;
-+    }
-+
-+    if ((optype != -1) && !(ctx->operation & optype)) {
-+        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
-+        return -1;
-+    }
-+
-+    ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
-+
-+    if (ret == -2)
-+        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
-+
-+    return ret;
-+
-+}
-+
-+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
-+                          const char *name, const char *value)
-+{
-+    if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
-+        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
-+        return -2;
-+    }
-+    if (strcmp(name, "digest") == 0) {
-+        const EVP_MD *md;
-+        if (value == NULL || (md = EVP_get_digestbyname(value)) == NULL) {
-+            EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_INVALID_DIGEST);
-+            return 0;
-+        }
-+        return EVP_PKEY_CTX_set_signature_md(ctx, md);
-+    }
-+    return ctx->pmeth->ctrl_str(ctx, name, value);
-+}
-+
-+/* Utility functions to send a string of hex string to a ctrl */
-+
-+int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str)
-+{
-+    size_t len;
-+
-+    len = strlen(str);
-+    if (len > INT_MAX)
-+        return -1;
-+    return ctx->pmeth->ctrl(ctx, cmd, len, (void *)str);
-+}
-+
-+int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex)
-+{
-+    unsigned char *bin;
-+    long binlen;
-+    int rv = -1;
-+
-+    bin = OPENSSL_hexstr2buf(hex, &binlen);
-+    if (bin == NULL)
-+        return 0;
-+    if (binlen <= INT_MAX)
-+        rv = ctx->pmeth->ctrl(ctx, cmd, binlen, bin);
-+    OPENSSL_free(bin);
-+    return rv;
-+}
-+
-+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
-+{
-+    return ctx->operation;
-+}
-+
-+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
-+{
-+    ctx->keygen_info = dat;
-+    ctx->keygen_info_count = datlen;
-+}
-+
-+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
-+{
-+    ctx->data = data;
-+}
-+
-+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
-+{
-+    return ctx->data;
-+}
-+
-+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
-+{
-+    return ctx->pkey;
-+}
-+
-+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
-+{
-+    return ctx->peerkey;
-+}
-+
-+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
-+{
-+    ctx->app_data = data;
-+}
-+
-+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
-+{
-+    return ctx->app_data;
-+}
-+
-+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
-+                            int (*init) (EVP_PKEY_CTX *ctx))
-+{
-+    pmeth->init = init;
-+}
-+
-+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
-+                            int (*copy) (EVP_PKEY_CTX *dst,
-+                                         EVP_PKEY_CTX *src))
-+{
-+    pmeth->copy = copy;
-+}
-+
-+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
-+                               void (*cleanup) (EVP_PKEY_CTX *ctx))
-+{
-+    pmeth->cleanup = cleanup;
-+}
-+
-+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
-+                                int (*paramgen_init) (EVP_PKEY_CTX *ctx),
-+                                int (*paramgen) (EVP_PKEY_CTX *ctx,
-+                                                 EVP_PKEY *pkey))
-+{
-+    pmeth->paramgen_init = paramgen_init;
-+    pmeth->paramgen = paramgen;
-+}
-+
-+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
-+                              int (*keygen_init) (EVP_PKEY_CTX *ctx),
-+                              int (*keygen) (EVP_PKEY_CTX *ctx,
-+                                             EVP_PKEY *pkey))
-+{
-+    pmeth->keygen_init = keygen_init;
-+    pmeth->keygen = keygen;
-+}
-+
-+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
-+                            int (*sign_init) (EVP_PKEY_CTX *ctx),
-+                            int (*sign) (EVP_PKEY_CTX *ctx,
-+                                         unsigned char *sig, size_t *siglen,
-+                                         const unsigned char *tbs,
-+                                         size_t tbslen))
-+{
-+    pmeth->sign_init = sign_init;
-+    pmeth->sign = sign;
-+}
-+
-+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
-+                              int (*verify_init) (EVP_PKEY_CTX *ctx),
-+                              int (*verify) (EVP_PKEY_CTX *ctx,
-+                                             const unsigned char *sig,
-+                                             size_t siglen,
-+                                             const unsigned char *tbs,
-+                                             size_t tbslen))
-+{
-+    pmeth->verify_init = verify_init;
-+    pmeth->verify = verify;
-+}
-+
-+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
-+                                      int (*verify_recover_init) (EVP_PKEY_CTX
-+                                                                  *ctx),
-+                                      int (*verify_recover) (EVP_PKEY_CTX
-+                                                             *ctx,
-+                                                             unsigned char
-+                                                             *sig,
-+                                                             size_t *siglen,
-+                                                             const unsigned
-+                                                             char *tbs,
-+                                                             size_t tbslen))
-+{
-+    pmeth->verify_recover_init = verify_recover_init;
-+    pmeth->verify_recover = verify_recover;
-+}
-+
-+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
-+                               int (*signctx_init) (EVP_PKEY_CTX *ctx,
-+                                                    EVP_MD_CTX *mctx),
-+                               int (*signctx) (EVP_PKEY_CTX *ctx,
-+                                               unsigned char *sig,
-+                                               size_t *siglen,
-+                                               EVP_MD_CTX *mctx))
-+{
-+    pmeth->signctx_init = signctx_init;
-+    pmeth->signctx = signctx;
-+}
-+
-+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
-+                                 int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
-+                                                        EVP_MD_CTX *mctx),
-+                                 int (*verifyctx) (EVP_PKEY_CTX *ctx,
-+                                                   const unsigned char *sig,
-+                                                   int siglen,
-+                                                   EVP_MD_CTX *mctx))
-+{
-+    pmeth->verifyctx_init = verifyctx_init;
-+    pmeth->verifyctx = verifyctx;
-+}
-+
-+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
-+                               int (*encrypt_init) (EVP_PKEY_CTX *ctx),
-+                               int (*encryptfn) (EVP_PKEY_CTX *ctx,
-+                                                 unsigned char *out,
-+                                                 size_t *outlen,
-+                                                 const unsigned char *in,
-+                                                 size_t inlen))
-+{
-+    pmeth->encrypt_init = encrypt_init;
-+    pmeth->encrypt = encryptfn;
-+}
-+
-+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
-+                               int (*decrypt_init) (EVP_PKEY_CTX *ctx),
-+                               int (*decrypt) (EVP_PKEY_CTX *ctx,
-+                                               unsigned char *out,
-+                                               size_t *outlen,
-+                                               const unsigned char *in,
-+                                               size_t inlen))
-+{
-+    pmeth->decrypt_init = decrypt_init;
-+    pmeth->decrypt = decrypt;
-+}
-+
-+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
-+                              int (*derive_init) (EVP_PKEY_CTX *ctx),
-+                              int (*derive) (EVP_PKEY_CTX *ctx,
-+                                             unsigned char *key,
-+                                             size_t *keylen))
-+{
-+    pmeth->derive_init = derive_init;
-+    pmeth->derive = derive;
-+}
-+
-+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
-+                            int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
-+                                         void *p2),
-+                            int (*ctrl_str) (EVP_PKEY_CTX *ctx,
-+                                             const char *type,
-+                                             const char *value))
-+{
-+    pmeth->ctrl = ctrl;
-+    pmeth->ctrl_str = ctrl_str;
-+}
-+
-+void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth,
-+                            int (**pinit) (EVP_PKEY_CTX *ctx))
-+{
-+    *pinit = pmeth->init;
-+}
-+
-+void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth,
-+                            int (**pcopy) (EVP_PKEY_CTX *dst,
-+                                           EVP_PKEY_CTX *src))
-+{
-+    *pcopy = pmeth->copy;
-+}
-+
-+void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth,
-+                               void (**pcleanup) (EVP_PKEY_CTX *ctx))
-+{
-+    *pcleanup = pmeth->cleanup;
-+}
-+
-+void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth,
-+                                int (**pparamgen_init) (EVP_PKEY_CTX *ctx),
-+                                int (**pparamgen) (EVP_PKEY_CTX *ctx,
-+                                                   EVP_PKEY *pkey))
-+{
-+    if (pparamgen_init)
-+        *pparamgen_init = pmeth->paramgen_init;
-+    if (pparamgen)
-+        *pparamgen = pmeth->paramgen;
-+}
-+
-+void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth,
-+                              int (**pkeygen_init) (EVP_PKEY_CTX *ctx),
-+                              int (**pkeygen) (EVP_PKEY_CTX *ctx,
-+                                               EVP_PKEY *pkey))
-+{
-+    if (pkeygen_init)
-+        *pkeygen_init = pmeth->keygen_init;
-+    if (pkeygen)
-+        *pkeygen = pmeth->keygen;
-+}
-+
-+void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth,
-+                            int (**psign_init) (EVP_PKEY_CTX *ctx),
-+                            int (**psign) (EVP_PKEY_CTX *ctx,
-+                                           unsigned char *sig, size_t *siglen,
-+                                           const unsigned char *tbs,
-+                                           size_t tbslen))
-+{
-+    if (psign_init)
-+        *psign_init = pmeth->sign_init;
-+    if (psign)
-+        *psign = pmeth->sign;
-+}
-+
-+void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth,
-+                              int (**pverify_init) (EVP_PKEY_CTX *ctx),
-+                              int (**pverify) (EVP_PKEY_CTX *ctx,
-+                                               const unsigned char *sig,
-+                                               size_t siglen,
-+                                               const unsigned char *tbs,
-+                                               size_t tbslen))
-+{
-+    if (pverify_init)
-+        *pverify_init = pmeth->verify_init;
-+    if (pverify)
-+        *pverify = pmeth->verify;
-+}
-+
-+void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth,
-+                                      int (**pverify_recover_init) (EVP_PKEY_CTX
-+                                                                    *ctx),
-+                                      int (**pverify_recover) (EVP_PKEY_CTX
-+                                                               *ctx,
-+                                                               unsigned char
-+                                                               *sig,
-+                                                               size_t *siglen,
-+                                                               const unsigned
-+                                                               char *tbs,
-+                                                               size_t tbslen))
-+{
-+    if (pverify_recover_init)
-+        *pverify_recover_init = pmeth->verify_recover_init;
-+    if (pverify_recover)
-+        *pverify_recover = pmeth->verify_recover;
-+}
-+
-+void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth,
-+                               int (**psignctx_init) (EVP_PKEY_CTX *ctx,
-+                                                      EVP_MD_CTX *mctx),
-+                               int (**psignctx) (EVP_PKEY_CTX *ctx,
-+                                                 unsigned char *sig,
-+                                                 size_t *siglen,
-+                                                 EVP_MD_CTX *mctx))
-+{
-+    if (psignctx_init)
-+        *psignctx_init = pmeth->signctx_init;
-+    if (psignctx)
-+        *psignctx = pmeth->signctx;
-+}
-+
-+void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth,
-+                                 int (**pverifyctx_init) (EVP_PKEY_CTX *ctx,
-+                                                          EVP_MD_CTX *mctx),
-+                                 int (**pverifyctx) (EVP_PKEY_CTX *ctx,
-+                                                     const unsigned char *sig,
-+                                                     int siglen,
-+                                                     EVP_MD_CTX *mctx))
-+{
-+    if (pverifyctx_init)
-+        *pverifyctx_init = pmeth->verifyctx_init;
-+    if (pverifyctx)
-+        *pverifyctx = pmeth->verifyctx;
-+}
-+
-+void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth,
-+                               int (**pencrypt_init) (EVP_PKEY_CTX *ctx),
-+                               int (**pencryptfn) (EVP_PKEY_CTX *ctx,
-+                                                   unsigned char *out,
-+                                                   size_t *outlen,
-+                                                   const unsigned char *in,
-+                                                   size_t inlen))
-+{
-+    if (pencrypt_init)
-+        *pencrypt_init = pmeth->encrypt_init;
-+    if (pencryptfn)
-+        *pencryptfn = pmeth->encrypt;
-+}
-+
-+void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth,
-+                               int (**pdecrypt_init) (EVP_PKEY_CTX *ctx),
-+                               int (**pdecrypt) (EVP_PKEY_CTX *ctx,
-+                                                 unsigned char *out,
-+                                                 size_t *outlen,
-+                                                 const unsigned char *in,
-+                                                 size_t inlen))
-+{
-+    if (pdecrypt_init)
-+        *pdecrypt_init = pmeth->decrypt_init;
-+    if (pdecrypt)
-+        *pdecrypt = pmeth->decrypt;
-+}
-+
-+void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth,
-+                              int (**pderive_init) (EVP_PKEY_CTX *ctx),
-+                              int (**pderive) (EVP_PKEY_CTX *ctx,
-+                                               unsigned char *key,
-+                                               size_t *keylen))
-+{
-+    if (pderive_init)
-+        *pderive_init = pmeth->derive_init;
-+    if (pderive)
-+        *pderive = pmeth->derive;
-+}
-+
-+void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth,
-+                            int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
-+                                           void *p2),
-+                            int (**pctrl_str) (EVP_PKEY_CTX *ctx,
-+                                               const char *type,
-+                                               const char *value))
-+{
-+    if (pctrl)
-+        *pctrl = pmeth->ctrl;
-+    if (pctrl_str)
-+        *pctrl_str = pmeth->ctrl_str;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/scrypt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/scrypt.c
-new file mode 100644
-index 0000000..101bb1e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/evp/scrypt.c
-@@ -0,0 +1,248 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifndef OPENSSL_NO_SCRYPT
-+
-+#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
-+static void salsa208_word_specification(uint32_t inout[16])
-+{
-+    int i;
-+    uint32_t x[16];
-+    memcpy(x, inout, sizeof(x));
-+    for (i = 8; i > 0; i -= 2) {
-+        x[4] ^= R(x[0] + x[12], 7);
-+        x[8] ^= R(x[4] + x[0], 9);
-+        x[12] ^= R(x[8] + x[4], 13);
-+        x[0] ^= R(x[12] + x[8], 18);
-+        x[9] ^= R(x[5] + x[1], 7);
-+        x[13] ^= R(x[9] + x[5], 9);
-+        x[1] ^= R(x[13] + x[9], 13);
-+        x[5] ^= R(x[1] + x[13], 18);
-+        x[14] ^= R(x[10] + x[6], 7);
-+        x[2] ^= R(x[14] + x[10], 9);
-+        x[6] ^= R(x[2] + x[14], 13);
-+        x[10] ^= R(x[6] + x[2], 18);
-+        x[3] ^= R(x[15] + x[11], 7);
-+        x[7] ^= R(x[3] + x[15], 9);
-+        x[11] ^= R(x[7] + x[3], 13);
-+        x[15] ^= R(x[11] + x[7], 18);
-+        x[1] ^= R(x[0] + x[3], 7);
-+        x[2] ^= R(x[1] + x[0], 9);
-+        x[3] ^= R(x[2] + x[1], 13);
-+        x[0] ^= R(x[3] + x[2], 18);
-+        x[6] ^= R(x[5] + x[4], 7);
-+        x[7] ^= R(x[6] + x[5], 9);
-+        x[4] ^= R(x[7] + x[6], 13);
-+        x[5] ^= R(x[4] + x[7], 18);
-+        x[11] ^= R(x[10] + x[9], 7);
-+        x[8] ^= R(x[11] + x[10], 9);
-+        x[9] ^= R(x[8] + x[11], 13);
-+        x[10] ^= R(x[9] + x[8], 18);
-+        x[12] ^= R(x[15] + x[14], 7);
-+        x[13] ^= R(x[12] + x[15], 9);
-+        x[14] ^= R(x[13] + x[12], 13);
-+        x[15] ^= R(x[14] + x[13], 18);
-+    }
-+    for (i = 0; i < 16; ++i)
-+        inout[i] += x[i];
-+    OPENSSL_cleanse(x, sizeof(x));
-+}
-+
-+static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r)
-+{
-+    uint64_t i, j;
-+    uint32_t X[16], *pB;
-+
-+    memcpy(X, B + (r * 2 - 1) * 16, sizeof(X));
-+    pB = B;
-+    for (i = 0; i < r * 2; i++) {
-+        for (j = 0; j < 16; j++)
-+            X[j] ^= *pB++;
-+        salsa208_word_specification(X);
-+        memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X));
-+    }
-+    OPENSSL_cleanse(X, sizeof(X));
-+}
-+
-+static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N,
-+                        uint32_t *X, uint32_t *T, uint32_t *V)
-+{
-+    unsigned char *pB;
-+    uint32_t *pV;
-+    uint64_t i, k;
-+
-+    /* Convert from little endian input */
-+    for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) {
-+        *pV = *pB++;
-+        *pV |= *pB++ << 8;
-+        *pV |= *pB++ << 16;
-+        *pV |= (uint32_t)*pB++ << 24;
-+    }
-+
-+    for (i = 1; i < N; i++, pV += 32 * r)
-+        scryptBlockMix(pV, pV - 32 * r, r);
-+
-+    scryptBlockMix(X, V + (N - 1) * 32 * r, r);
-+
-+    for (i = 0; i < N; i++) {
-+        uint32_t j;
-+        j = X[16 * (2 * r - 1)] % N;
-+        pV = V + 32 * r * j;
-+        for (k = 0; k < 32 * r; k++)
-+            T[k] = X[k] ^ *pV++;
-+        scryptBlockMix(X, T, r);
-+    }
-+    /* Convert output to little endian */
-+    for (i = 0, pB = B; i < 32 * r; i++) {
-+        uint32_t xtmp = X[i];
-+        *pB++ = xtmp & 0xff;
-+        *pB++ = (xtmp >> 8) & 0xff;
-+        *pB++ = (xtmp >> 16) & 0xff;
-+        *pB++ = (xtmp >> 24) & 0xff;
-+    }
-+}
-+
-+#ifndef SIZE_MAX
-+# define SIZE_MAX    ((size_t)-1)
-+#endif
-+
-+/*
-+ * Maximum power of two that will fit in uint64_t: this should work on
-+ * most (all?) platforms.
-+ */
-+
-+#define LOG2_UINT64_MAX         (sizeof(uint64_t) * 8 - 1)
-+
-+/*
-+ * Maximum value of p * r:
-+ * p <= ((2^32-1) * hLen) / MFLen =>
-+ * p <= ((2^32-1) * 32) / (128 * r) =>
-+ * p * r <= (2^30-1)
-+ *
-+ */
-+
-+#define SCRYPT_PR_MAX   ((1 << 30) - 1)
-+
-+/*
-+ * Maximum permitted memory allow this to be overridden with Configuration
-+ * option: e.g. -DSCRYPT_MAX_MEM=0 for maximum possible.
-+ */
-+
-+#ifdef SCRYPT_MAX_MEM
-+# if SCRYPT_MAX_MEM == 0
-+#  undef SCRYPT_MAX_MEM
-+/*
-+ * Although we could theoretically allocate SIZE_MAX memory that would leave
-+ * no memory available for anything else so set limit as half that.
-+ */
-+#  define SCRYPT_MAX_MEM (SIZE_MAX/2)
-+# endif
-+#else
-+/* Default memory limit: 32 MB */
-+# define SCRYPT_MAX_MEM  (1024 * 1024 * 32)
-+#endif
-+
-+int EVP_PBE_scrypt(const char *pass, size_t passlen,
-+                   const unsigned char *salt, size_t saltlen,
-+                   uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
-+                   unsigned char *key, size_t keylen)
-+{
-+    int rv = 0;
-+    unsigned char *B;
-+    uint32_t *X, *V, *T;
-+    uint64_t i, Blen, Vlen;
-+    size_t allocsize;
-+
-+    /* Sanity check parameters */
-+    /* initial check, r,p must be non zero, N >= 2 and a power of 2 */
-+    if (r == 0 || p == 0 || N < 2 || (N & (N - 1)))
-+        return 0;
-+    /* Check p * r < SCRYPT_PR_MAX avoiding overflow */
-+    if (p > SCRYPT_PR_MAX / r)
-+        return 0;
-+
-+    /*
-+     * Need to check N: if 2^(128 * r / 8) overflows limit this is
-+     * automatically satisfied since N <= UINT64_MAX.
-+     */
-+
-+    if (16 * r <= LOG2_UINT64_MAX) {
-+        if (N >= (((uint64_t)1) << (16 * r)))
-+            return 0;
-+    }
-+
-+    /* Memory checks: check total allocated buffer size fits in uint64_t */
-+
-+    /*
-+     * B size in section 5 step 1.S
-+     * Note: we know p * 128 * r < UINT64_MAX because we already checked
-+     * p * r < SCRYPT_PR_MAX
-+     */
-+    Blen = p * 128 * r;
-+
-+    /*
-+     * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in
-+     * uint64_t and also size_t (their sizes are unrelated).
-+     * This is combined size V, X and T (section 4)
-+     */
-+    i = UINT64_MAX / (32 * sizeof(uint32_t));
-+    if (N + 2 > i / r)
-+        return 0;
-+    Vlen = 32 * r * (N + 2) * sizeof(uint32_t);
-+
-+    /* check total allocated size fits in uint64_t */
-+    if (Blen > UINT64_MAX - Vlen)
-+        return 0;
-+    /* check total allocated size fits in size_t */
-+    if (Blen > SIZE_MAX - Vlen)
-+        return 0;
-+
-+    allocsize = (size_t)(Blen + Vlen);
-+
-+    if (maxmem == 0)
-+        maxmem = SCRYPT_MAX_MEM;
-+
-+    if (allocsize > maxmem) {
-+        EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
-+        return 0;
-+    }
-+
-+    /* If no key return to indicate parameters are OK */
-+    if (key == NULL)
-+        return 1;
-+
-+    B = OPENSSL_malloc(allocsize);
-+    if (B == NULL)
-+        return 0;
-+    X = (uint32_t *)(B + Blen);
-+    T = X + 32 * r;
-+    V = T + 32 * r;
-+    if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(),
-+                          Blen, B) == 0)
-+        goto err;
-+
-+    for (i = 0; i < p; i++)
-+        scryptROMix(B + 128 * r * i, r, N, X, T, V);
-+
-+    if (PKCS5_PBKDF2_HMAC(pass, passlen, B, Blen, 1, EVP_sha256(),
-+                          keylen, key) == 0)
-+        goto err;
-+    rv = 1;
-+ err:
-+    OPENSSL_clear_free(B, allocsize);
-+    return rv;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ex_data.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ex_data.c
-new file mode 100644
-index 0000000..84b6555
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ex_data.c
-@@ -0,0 +1,384 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib_int.h"
-+#include "internal/thread_once.h"
-+#include 
-+
-+/*
-+ * Each structure type (sometimes called a class), that supports
-+ * exdata has a stack of callbacks for each instance.
-+ */
-+struct ex_callback_st {
-+    long argl;                  /* Arbitrary long */
-+    void *argp;                 /* Arbitrary void * */
-+    CRYPTO_EX_new *new_func;
-+    CRYPTO_EX_free *free_func;
-+    CRYPTO_EX_dup *dup_func;
-+};
-+
-+/*
-+ * The state for each class.  This could just be a typedef, but
-+ * a structure allows future changes.
-+ */
-+typedef struct ex_callbacks_st {
-+    STACK_OF(EX_CALLBACK) *meth;
-+} EX_CALLBACKS;
-+
-+static EX_CALLBACKS ex_data[CRYPTO_EX_INDEX__COUNT];
-+
-+static CRYPTO_RWLOCK *ex_data_lock = NULL;
-+static CRYPTO_ONCE ex_data_init = CRYPTO_ONCE_STATIC_INIT;
-+
-+DEFINE_RUN_ONCE_STATIC(do_ex_data_init)
-+{
-+    OPENSSL_init_crypto(0, NULL);
-+    ex_data_lock = CRYPTO_THREAD_lock_new();
-+    return ex_data_lock != NULL;
-+}
-+
-+/*
-+ * Return the EX_CALLBACKS from the |ex_data| array that corresponds to
-+ * a given class.  On success, *holds the lock.*
-+ */
-+static EX_CALLBACKS *get_and_lock(int class_index)
-+{
-+    EX_CALLBACKS *ip;
-+
-+    if (class_index < 0 || class_index >= CRYPTO_EX_INDEX__COUNT) {
-+        CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_PASSED_INVALID_ARGUMENT);
-+        return NULL;
-+    }
-+
-+    if (!RUN_ONCE(&ex_data_init, do_ex_data_init)) {
-+        CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    if (ex_data_lock == NULL) {
-+        /*
-+         * This can happen in normal operation when using CRYPTO_mem_leaks().
-+         * The CRYPTO_mem_leaks() function calls OPENSSL_cleanup() which cleans
-+         * up the locks. Subsequently the BIO that CRYPTO_mem_leaks() uses gets
-+         * freed, which also attempts to free the ex_data. However
-+         * CRYPTO_mem_leaks() ensures that the ex_data is freed early (i.e.
-+         * before OPENSSL_cleanup() is called), so if we get here we can safely
-+         * ignore this operation. We just treat it as an error.
-+         */
-+         return NULL;
-+    }
-+
-+    ip = &ex_data[class_index];
-+    CRYPTO_THREAD_write_lock(ex_data_lock);
-+    return ip;
-+}
-+
-+static void cleanup_cb(EX_CALLBACK *funcs)
-+{
-+    OPENSSL_free(funcs);
-+}
-+
-+/*
-+ * Release all "ex_data" state to prevent memory leaks. This can't be made
-+ * thread-safe without overhauling a lot of stuff, and shouldn't really be
-+ * called under potential race-conditions anyway (it's for program shutdown
-+ * after all).
-+ */
-+void crypto_cleanup_all_ex_data_int(void)
-+{
-+    int i;
-+
-+    for (i = 0; i < CRYPTO_EX_INDEX__COUNT; ++i) {
-+        EX_CALLBACKS *ip = &ex_data[i];
-+
-+        sk_EX_CALLBACK_pop_free(ip->meth, cleanup_cb);
-+        ip->meth = NULL;
-+    }
-+
-+    CRYPTO_THREAD_lock_free(ex_data_lock);
-+    ex_data_lock = NULL;
-+}
-+
-+
-+/*
-+ * Unregister a new index by replacing the callbacks with no-ops.
-+ * Any in-use instances are leaked.
-+ */
-+static void dummy_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx,
-+                     long argl, void *argp)
-+{
-+}
-+
-+static void dummy_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx,
-+                       long argl, void *argp)
-+{
-+}
-+
-+static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
-+                     void *from_d, int idx,
-+                     long argl, void *argp)
-+{
-+    return 0;
-+}
-+
-+int CRYPTO_free_ex_index(int class_index, int idx)
-+{
-+    EX_CALLBACKS *ip = get_and_lock(class_index);
-+    EX_CALLBACK *a;
-+    int toret = 0;
-+
-+    if (ip == NULL)
-+        return 0;
-+    if (idx < 0 || idx >= sk_EX_CALLBACK_num(ip->meth))
-+        goto err;
-+    a = sk_EX_CALLBACK_value(ip->meth, idx);
-+    if (a == NULL)
-+        goto err;
-+    a->new_func = dummy_new;
-+    a->dup_func = dummy_dup;
-+    a->free_func = dummy_free;
-+    toret = 1;
-+err:
-+    CRYPTO_THREAD_unlock(ex_data_lock);
-+    return toret;
-+}
-+
-+/*
-+ * Register a new index.
-+ */
-+int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
-+                            CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
-+                            CRYPTO_EX_free *free_func)
-+{
-+    int toret = -1;
-+    EX_CALLBACK *a;
-+    EX_CALLBACKS *ip = get_and_lock(class_index);
-+
-+    if (ip == NULL)
-+        return -1;
-+
-+    if (ip->meth == NULL) {
-+        ip->meth = sk_EX_CALLBACK_new_null();
-+        /* We push an initial value on the stack because the SSL
-+         * "app_data" routines use ex_data index zero.  See RT 3710. */
-+        if (ip->meth == NULL
-+            || !sk_EX_CALLBACK_push(ip->meth, NULL)) {
-+            CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    }
-+
-+    a = (EX_CALLBACK *)OPENSSL_malloc(sizeof(*a));
-+    if (a == NULL) {
-+        CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    a->argl = argl;
-+    a->argp = argp;
-+    a->new_func = new_func;
-+    a->dup_func = dup_func;
-+    a->free_func = free_func;
-+
-+    if (!sk_EX_CALLBACK_push(ip->meth, NULL)) {
-+        CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(a);
-+        goto err;
-+    }
-+    toret = sk_EX_CALLBACK_num(ip->meth) - 1;
-+    (void)sk_EX_CALLBACK_set(ip->meth, toret, a);
-+
-+ err:
-+    CRYPTO_THREAD_unlock(ex_data_lock);
-+    return toret;
-+}
-+
-+/*
-+ * Initialise a new CRYPTO_EX_DATA for use in a particular class - including
-+ * calling new() callbacks for each index in the class used by this variable
-+ * Thread-safe by copying a class's array of "EX_CALLBACK" entries
-+ * in the lock, then using them outside the lock. Note this only applies
-+ * to the global "ex_data" state (ie. class definitions), not 'ad' itself.
-+ */
-+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
-+{
-+    int mx, i;
-+    void *ptr;
-+    EX_CALLBACK **storage = NULL;
-+    EX_CALLBACK *stack[10];
-+    EX_CALLBACKS *ip = get_and_lock(class_index);
-+
-+    if (ip == NULL)
-+        return 0;
-+
-+    ad->sk = NULL;
-+
-+    mx = sk_EX_CALLBACK_num(ip->meth);
-+    if (mx > 0) {
-+        if (mx < (int)OSSL_NELEM(stack))
-+            storage = stack;
-+        else
-+            storage = OPENSSL_malloc(sizeof(*storage) * mx);
-+        if (storage != NULL)
-+            for (i = 0; i < mx; i++)
-+                storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
-+    }
-+    CRYPTO_THREAD_unlock(ex_data_lock);
-+
-+    if (mx > 0 && storage == NULL) {
-+        CRYPTOerr(CRYPTO_F_CRYPTO_NEW_EX_DATA, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    for (i = 0; i < mx; i++) {
-+        if (storage[i] && storage[i]->new_func) {
-+            ptr = CRYPTO_get_ex_data(ad, i);
-+            storage[i]->new_func(obj, ptr, ad, i,
-+                                 storage[i]->argl, storage[i]->argp);
-+        }
-+    }
-+    if (storage != stack)
-+        OPENSSL_free(storage);
-+    return 1;
-+}
-+
-+/*
-+ * Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks
-+ * for each index in the class used by this variable
-+ */
-+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
-+                       const CRYPTO_EX_DATA *from)
-+{
-+    int mx, j, i;
-+    char *ptr;
-+    EX_CALLBACK *stack[10];
-+    EX_CALLBACK **storage = NULL;
-+    EX_CALLBACKS *ip;
-+
-+    if (from->sk == NULL)
-+        /* Nothing to copy over */
-+        return 1;
-+    if ((ip = get_and_lock(class_index)) == NULL)
-+        return 0;
-+
-+    mx = sk_EX_CALLBACK_num(ip->meth);
-+    j = sk_void_num(from->sk);
-+    if (j < mx)
-+        mx = j;
-+    if (mx > 0) {
-+        if (mx < (int)OSSL_NELEM(stack))
-+            storage = stack;
-+        else
-+            storage = OPENSSL_malloc(sizeof(*storage) * mx);
-+        if (storage != NULL)
-+            for (i = 0; i < mx; i++)
-+                storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
-+    }
-+    CRYPTO_THREAD_unlock(ex_data_lock);
-+
-+    if (mx > 0 && storage == NULL) {
-+        CRYPTOerr(CRYPTO_F_CRYPTO_DUP_EX_DATA, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    for (i = 0; i < mx; i++) {
-+        ptr = CRYPTO_get_ex_data(from, i);
-+        if (storage[i] && storage[i]->dup_func)
-+            storage[i]->dup_func(to, from, &ptr, i,
-+                                 storage[i]->argl, storage[i]->argp);
-+        CRYPTO_set_ex_data(to, i, ptr);
-+    }
-+    if (storage != stack)
-+        OPENSSL_free(storage);
-+    return 1;
-+}
-+
-+
-+/*
-+ * Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for
-+ * each index in the class used by this variable
-+ */
-+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
-+{
-+    int mx, i;
-+    EX_CALLBACKS *ip;
-+    void *ptr;
-+    EX_CALLBACK *f;
-+    EX_CALLBACK *stack[10];
-+    EX_CALLBACK **storage = NULL;
-+
-+    if ((ip = get_and_lock(class_index)) == NULL)
-+        goto err;
-+
-+    mx = sk_EX_CALLBACK_num(ip->meth);
-+    if (mx > 0) {
-+        if (mx < (int)OSSL_NELEM(stack))
-+            storage = stack;
-+        else
-+            storage = OPENSSL_malloc(sizeof(*storage) * mx);
-+        if (storage != NULL)
-+            for (i = 0; i < mx; i++)
-+                storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
-+    }
-+    CRYPTO_THREAD_unlock(ex_data_lock);
-+
-+    for (i = 0; i < mx; i++) {
-+        if (storage != NULL)
-+            f = storage[i];
-+        else {
-+            CRYPTO_THREAD_write_lock(ex_data_lock);
-+            f = sk_EX_CALLBACK_value(ip->meth, i);
-+            CRYPTO_THREAD_unlock(ex_data_lock);
-+        }
-+        if (f != NULL && f->free_func != NULL) {
-+            ptr = CRYPTO_get_ex_data(ad, i);
-+            f->free_func(obj, ptr, ad, i, f->argl, f->argp);
-+        }
-+    }
-+
-+    if (storage != stack)
-+        OPENSSL_free(storage);
-+ err:
-+    sk_void_free(ad->sk);
-+    ad->sk = NULL;
-+}
-+
-+/*
-+ * For a given CRYPTO_EX_DATA variable, set the value corresponding to a
-+ * particular index in the class used by this variable
-+ */
-+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
-+{
-+    int i;
-+
-+    if (ad->sk == NULL) {
-+        if ((ad->sk = sk_void_new_null()) == NULL) {
-+            CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+    }
-+
-+    for (i = sk_void_num(ad->sk); i <= idx; ++i) {
-+        if (!sk_void_push(ad->sk, NULL)) {
-+            CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+    }
-+    sk_void_set(ad->sk, idx, val);
-+    return 1;
-+}
-+
-+/*
-+ * For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a
-+ * particular index in the class used by this variable
-+ */
-+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
-+{
-+    if (ad->sk == NULL || idx >= sk_void_num(ad->sk))
-+        return NULL;
-+    return sk_void_value(ad->sk, idx);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/build.info
-new file mode 100644
-index 0000000..09f67c2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        hmac.c hm_ameth.c hm_pmeth.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hm_ameth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hm_ameth.c
-new file mode 100644
-index 0000000..78ae0ea
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hm_ameth.c
-@@ -0,0 +1,125 @@
-+/*
-+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "internal/asn1_int.h"
-+
-+#define HMAC_TEST_PRIVATE_KEY_FORMAT
-+
-+/*
-+ * HMAC "ASN1" method. This is just here to indicate the maximum HMAC output
-+ * length and to free up an HMAC key.
-+ */
-+
-+static int hmac_size(const EVP_PKEY *pkey)
-+{
-+    return EVP_MAX_MD_SIZE;
-+}
-+
-+static void hmac_key_free(EVP_PKEY *pkey)
-+{
-+    ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey);
-+    if (os) {
-+        if (os->data)
-+            OPENSSL_cleanse(os->data, os->length);
-+        ASN1_OCTET_STRING_free(os);
-+    }
-+}
-+
-+static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
-+{
-+    switch (op) {
-+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
-+        *(int *)arg2 = NID_sha256;
-+        return 1;
-+
-+    default:
-+        return -2;
-+    }
-+}
-+
-+static int hmac_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b));
-+}
-+
-+#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
-+/*
-+ * A bogus private key format for test purposes. This is simply the HMAC key
-+ * with "HMAC PRIVATE KEY" in the headers. When enabled the genpkey utility
-+ * can be used to "generate" HMAC keys.
-+ */
-+
-+static int old_hmac_decode(EVP_PKEY *pkey,
-+                           const unsigned char **pder, int derlen)
-+{
-+    ASN1_OCTET_STRING *os;
-+    os = ASN1_OCTET_STRING_new();
-+    if (os == NULL || !ASN1_OCTET_STRING_set(os, *pder, derlen))
-+        goto err;
-+    if (!EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os))
-+        goto err;
-+    return 1;
-+
-+ err:
-+    ASN1_OCTET_STRING_free(os);
-+    return 0;
-+}
-+
-+static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder)
-+{
-+    int inc;
-+    ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey);
-+    if (pder) {
-+        if (!*pder) {
-+            *pder = OPENSSL_malloc(os->length);
-+            if (*pder == NULL)
-+                return -1;
-+            inc = 0;
-+        } else
-+            inc = 1;
-+
-+        memcpy(*pder, os->data, os->length);
-+
-+        if (inc)
-+            *pder += os->length;
-+    }
-+
-+    return os->length;
-+}
-+
-+#endif
-+
-+const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
-+    EVP_PKEY_HMAC,
-+    EVP_PKEY_HMAC,
-+    0,
-+
-+    "HMAC",
-+    "OpenSSL HMAC method",
-+
-+    0, 0, hmac_pkey_public_cmp, 0,
-+
-+    0, 0, 0,
-+
-+    hmac_size,
-+    0, 0,
-+    0, 0, 0, 0, 0, 0, 0,
-+
-+    hmac_key_free,
-+    hmac_pkey_ctrl,
-+#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
-+    old_hmac_decode,
-+    old_hmac_encode
-+#else
-+    0, 0
-+#endif
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hm_pmeth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hm_pmeth.c
-new file mode 100644
-index 0000000..5b98477
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hm_pmeth.c
-@@ -0,0 +1,210 @@
-+/*
-+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+/* HMAC pkey context structure */
-+
-+typedef struct {
-+    const EVP_MD *md;           /* MD for HMAC use */
-+    ASN1_OCTET_STRING ktmp;     /* Temp storage for key */
-+    HMAC_CTX *ctx;
-+} HMAC_PKEY_CTX;
-+
-+static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
-+{
-+    HMAC_PKEY_CTX *hctx;
-+
-+    hctx = OPENSSL_zalloc(sizeof(*hctx));
-+    if (hctx == NULL)
-+        return 0;
-+    hctx->ktmp.type = V_ASN1_OCTET_STRING;
-+    hctx->ctx = HMAC_CTX_new();
-+    if (hctx->ctx == NULL) {
-+        OPENSSL_free(hctx);
-+        return 0;
-+    }
-+
-+    ctx->data = hctx;
-+    ctx->keygen_info_count = 0;
-+
-+    return 1;
-+}
-+
-+static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx);
-+
-+static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
-+{
-+    HMAC_PKEY_CTX *sctx, *dctx;
-+
-+    /* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */
-+    if (!pkey_hmac_init(dst))
-+        return 0;
-+    sctx = EVP_PKEY_CTX_get_data(src);
-+    dctx = EVP_PKEY_CTX_get_data(dst);
-+    dctx->md = sctx->md;
-+    if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx))
-+        goto err;
-+    if (sctx->ktmp.data) {
-+        if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
-+                                   sctx->ktmp.data, sctx->ktmp.length))
-+            goto err;
-+    }
-+    return 1;
-+err:
-+    /* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */
-+    pkey_hmac_cleanup (dst);
-+    return 0;
-+}
-+
-+static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
-+{
-+    HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
-+
-+    if (hctx != NULL) {
-+        HMAC_CTX_free(hctx->ctx);
-+        OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
-+        OPENSSL_free(hctx);
-+        EVP_PKEY_CTX_set_data(ctx, NULL);
-+    }
-+}
-+
-+static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    ASN1_OCTET_STRING *hkey = NULL;
-+    HMAC_PKEY_CTX *hctx = ctx->data;
-+    if (!hctx->ktmp.data)
-+        return 0;
-+    hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
-+    if (!hkey)
-+        return 0;
-+    EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
-+
-+    return 1;
-+}
-+
-+static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+    HMAC_PKEY_CTX *hctx = EVP_MD_CTX_pkey_ctx(ctx)->data;
-+    if (!HMAC_Update(hctx->ctx, data, count))
-+        return 0;
-+    return 1;
-+}
-+
-+static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
-+{
-+    HMAC_PKEY_CTX *hctx = ctx->data;
-+    HMAC_CTX_set_flags(hctx->ctx,
-+                       EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));
-+    EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
-+    EVP_MD_CTX_set_update_fn(mctx, int_update);
-+    return 1;
-+}
-+
-+static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
-+                        EVP_MD_CTX *mctx)
-+{
-+    unsigned int hlen;
-+    HMAC_PKEY_CTX *hctx = ctx->data;
-+    int l = EVP_MD_CTX_size(mctx);
-+
-+    if (l < 0)
-+        return 0;
-+    *siglen = l;
-+    if (!sig)
-+        return 1;
-+
-+    if (!HMAC_Final(hctx->ctx, sig, &hlen))
-+        return 0;
-+    *siglen = (size_t)hlen;
-+    return 1;
-+}
-+
-+static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-+{
-+    HMAC_PKEY_CTX *hctx = ctx->data;
-+    ASN1_OCTET_STRING *key;
-+    switch (type) {
-+
-+    case EVP_PKEY_CTRL_SET_MAC_KEY:
-+        if ((!p2 && p1 > 0) || (p1 < -1))
-+            return 0;
-+        if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
-+            return 0;
-+        break;
-+
-+    case EVP_PKEY_CTRL_MD:
-+        hctx->md = p2;
-+        break;
-+
-+    case EVP_PKEY_CTRL_DIGESTINIT:
-+        key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
-+        if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md,
-+                          ctx->engine))
-+            return 0;
-+        break;
-+
-+    default:
-+        return -2;
-+
-+    }
-+    return 1;
-+}
-+
-+static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
-+                              const char *type, const char *value)
-+{
-+    if (!value) {
-+        return 0;
-+    }
-+    if (strcmp(type, "key") == 0)
-+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
-+    if (strcmp(type, "hexkey") == 0)
-+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
-+    return -2;
-+}
-+
-+const EVP_PKEY_METHOD hmac_pkey_meth = {
-+    EVP_PKEY_HMAC,
-+    0,
-+    pkey_hmac_init,
-+    pkey_hmac_copy,
-+    pkey_hmac_cleanup,
-+
-+    0, 0,
-+
-+    0,
-+    pkey_hmac_keygen,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    hmac_signctx_init,
-+    hmac_signctx,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    pkey_hmac_ctrl,
-+    pkey_hmac_ctrl_str
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hmac.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hmac.c
-new file mode 100644
-index 0000000..3374105
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hmac.c
-@@ -0,0 +1,240 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "hmac_lcl.h"
-+
-+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
-+                 const EVP_MD *md, ENGINE *impl)
-+{
-+    int i, j, reset = 0;
-+    unsigned char pad[HMAC_MAX_MD_CBLOCK];
-+
-+    /* If we are changing MD then we must have a key */
-+    if (md != NULL && md != ctx->md && (key == NULL || len < 0))
-+        return 0;
-+
-+    if (md != NULL) {
-+        reset = 1;
-+        ctx->md = md;
-+    } else if (ctx->md) {
-+        md = ctx->md;
-+    } else {
-+        return 0;
-+    }
-+
-+    if (key != NULL) {
-+        reset = 1;
-+        j = EVP_MD_block_size(md);
-+        OPENSSL_assert(j <= (int)sizeof(ctx->key));
-+        if (j < len) {
-+            if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl))
-+                goto err;
-+            if (!EVP_DigestUpdate(ctx->md_ctx, key, len))
-+                goto err;
-+            if (!EVP_DigestFinal_ex(ctx->md_ctx, ctx->key,
-+                                    &ctx->key_length))
-+                goto err;
-+        } else {
-+            if (len < 0 || len > (int)sizeof(ctx->key))
-+                return 0;
-+            memcpy(ctx->key, key, len);
-+            ctx->key_length = len;
-+        }
-+        if (ctx->key_length != HMAC_MAX_MD_CBLOCK)
-+            memset(&ctx->key[ctx->key_length], 0,
-+                   HMAC_MAX_MD_CBLOCK - ctx->key_length);
-+    }
-+
-+    if (reset) {
-+        for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
-+            pad[i] = 0x36 ^ ctx->key[i];
-+        if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl))
-+            goto err;
-+        if (!EVP_DigestUpdate(ctx->i_ctx, pad, EVP_MD_block_size(md)))
-+            goto err;
-+
-+        for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
-+            pad[i] = 0x5c ^ ctx->key[i];
-+        if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl))
-+            goto err;
-+        if (!EVP_DigestUpdate(ctx->o_ctx, pad, EVP_MD_block_size(md)))
-+            goto err;
-+    }
-+    if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->i_ctx))
-+        goto err;
-+    return 1;
-+ err:
-+    return 0;
-+}
-+
-+#if OPENSSL_API_COMPAT < 0x10100000L
-+int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
-+{
-+    if (key && md)
-+        HMAC_CTX_reset(ctx);
-+    return HMAC_Init_ex(ctx, key, len, md, NULL);
-+}
-+#endif
-+
-+int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
-+{
-+    if (!ctx->md)
-+        return 0;
-+    return EVP_DigestUpdate(ctx->md_ctx, data, len);
-+}
-+
-+int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
-+{
-+    unsigned int i;
-+    unsigned char buf[EVP_MAX_MD_SIZE];
-+
-+    if (!ctx->md)
-+        goto err;
-+
-+    if (!EVP_DigestFinal_ex(ctx->md_ctx, buf, &i))
-+        goto err;
-+    if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->o_ctx))
-+        goto err;
-+    if (!EVP_DigestUpdate(ctx->md_ctx, buf, i))
-+        goto err;
-+    if (!EVP_DigestFinal_ex(ctx->md_ctx, md, len))
-+        goto err;
-+    return 1;
-+ err:
-+    return 0;
-+}
-+
-+size_t HMAC_size(const HMAC_CTX *ctx)
-+{
-+    return EVP_MD_size((ctx)->md);
-+}
-+
-+HMAC_CTX *HMAC_CTX_new(void)
-+{
-+    HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(HMAC_CTX));
-+
-+    if (ctx != NULL) {
-+        if (!HMAC_CTX_reset(ctx)) {
-+            HMAC_CTX_free(ctx);
-+            return NULL;
-+        }
-+    }
-+    return ctx;
-+}
-+
-+static void hmac_ctx_cleanup(HMAC_CTX *ctx)
-+{
-+    EVP_MD_CTX_reset(ctx->i_ctx);
-+    EVP_MD_CTX_reset(ctx->o_ctx);
-+    EVP_MD_CTX_reset(ctx->md_ctx);
-+    ctx->md = NULL;
-+    ctx->key_length = 0;
-+    OPENSSL_cleanse(ctx->key, sizeof(ctx->key));
-+}
-+
-+void HMAC_CTX_free(HMAC_CTX *ctx)
-+{
-+    if (ctx != NULL) {
-+        hmac_ctx_cleanup(ctx);
-+        EVP_MD_CTX_free(ctx->i_ctx);
-+        EVP_MD_CTX_free(ctx->o_ctx);
-+        EVP_MD_CTX_free(ctx->md_ctx);
-+        OPENSSL_free(ctx);
-+    }
-+}
-+
-+int HMAC_CTX_reset(HMAC_CTX *ctx)
-+{
-+    hmac_ctx_cleanup(ctx);
-+    if (ctx->i_ctx == NULL)
-+        ctx->i_ctx = EVP_MD_CTX_new();
-+    if (ctx->i_ctx == NULL)
-+        goto err;
-+    if (ctx->o_ctx == NULL)
-+        ctx->o_ctx = EVP_MD_CTX_new();
-+    if (ctx->o_ctx == NULL)
-+        goto err;
-+    if (ctx->md_ctx == NULL)
-+        ctx->md_ctx = EVP_MD_CTX_new();
-+    if (ctx->md_ctx == NULL)
-+        goto err;
-+    ctx->md = NULL;
-+    return 1;
-+ err:
-+    hmac_ctx_cleanup(ctx);
-+    return 0;
-+}
-+
-+int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
-+{
-+    if (!HMAC_CTX_reset(dctx))
-+        goto err;
-+    if (!EVP_MD_CTX_copy_ex(dctx->i_ctx, sctx->i_ctx))
-+        goto err;
-+    if (!EVP_MD_CTX_copy_ex(dctx->o_ctx, sctx->o_ctx))
-+        goto err;
-+    if (!EVP_MD_CTX_copy_ex(dctx->md_ctx, sctx->md_ctx))
-+        goto err;
-+    memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
-+    dctx->key_length = sctx->key_length;
-+    dctx->md = sctx->md;
-+    return 1;
-+ err:
-+    hmac_ctx_cleanup(dctx);
-+    return 0;
-+}
-+
-+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
-+                    const unsigned char *d, size_t n, unsigned char *md,
-+                    unsigned int *md_len)
-+{
-+    HMAC_CTX *c = NULL;
-+    static unsigned char m[EVP_MAX_MD_SIZE];
-+    static const unsigned char dummy_key[1] = {'\0'};
-+
-+    if (md == NULL)
-+        md = m;
-+    if ((c = HMAC_CTX_new()) == NULL)
-+        goto err;
-+
-+    /* For HMAC_Init_ex, NULL key signals reuse. */
-+    if (key == NULL && key_len == 0) {
-+        key = dummy_key;
-+    }
-+
-+    if (!HMAC_Init_ex(c, key, key_len, evp_md, NULL))
-+        goto err;
-+    if (!HMAC_Update(c, d, n))
-+        goto err;
-+    if (!HMAC_Final(c, md, md_len))
-+        goto err;
-+    HMAC_CTX_free(c);
-+    return md;
-+ err:
-+    HMAC_CTX_free(c);
-+    return NULL;
-+}
-+
-+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
-+{
-+    EVP_MD_CTX_set_flags(ctx->i_ctx, flags);
-+    EVP_MD_CTX_set_flags(ctx->o_ctx, flags);
-+    EVP_MD_CTX_set_flags(ctx->md_ctx, flags);
-+}
-+
-+const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx)
-+{
-+    return ctx->md;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hmac_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hmac_lcl.h
-new file mode 100644
-index 0000000..4c156dc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/hmac/hmac_lcl.h
-@@ -0,0 +1,33 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_HMAC_LCL_H
-+# define HEADER_HMAC_LCL_H
-+
-+#ifdef  __cplusplus
-+extern "C" {
-+#endif
-+#if 0                            /* emacs indentation fix */
-+}
-+#endif
-+
-+struct hmac_ctx_st {
-+    const EVP_MD *md;
-+    EVP_MD_CTX *md_ctx;
-+    EVP_MD_CTX *i_ctx;
-+    EVP_MD_CTX *o_ctx;
-+    unsigned int key_length;
-+    unsigned char key[HMAC_MAX_MD_CBLOCK];
-+};
-+
-+#ifdef __cplusplus
-+} /* extern "C" */
-+#endif
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ia64cpuid.S b/CryptoPkg/Library/OpensslLib/openssl/crypto/ia64cpuid.S
-new file mode 100644
-index 0000000..ffd6d6c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ia64cpuid.S
-@@ -0,0 +1,297 @@
-+// Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+//
-+// Licensed under the OpenSSL license (the "License").  You may not use
-+// this file except in compliance with the License.  You can obtain a copy
-+// in the file LICENSE in the source distribution or at
-+// https://www.openssl.org/source/license.html
-+// Works on all IA-64 platforms: Linux, HP-UX, Win64i...
-+// On Win64i compile with ias.exe.
-+.text
-+
-+#if defined(_HPUX_SOURCE) && !defined(_LP64)
-+#define	ADDP	addp4
-+#else
-+#define	ADDP	add
-+#endif
-+
-+.global	OPENSSL_cpuid_setup#
-+.proc	OPENSSL_cpuid_setup#
-+OPENSSL_cpuid_setup:
-+{ .mib;	br.ret.sptk.many	b0		};;
-+.endp	OPENSSL_cpuid_setup#
-+
-+.global	OPENSSL_rdtsc#
-+.proc	OPENSSL_rdtsc#
-+OPENSSL_rdtsc:
-+{ .mib;	mov			r8=ar.itc
-+	br.ret.sptk.many	b0		};;
-+.endp   OPENSSL_rdtsc#
-+
-+.global	OPENSSL_atomic_add#
-+.proc	OPENSSL_atomic_add#
-+.align	32
-+OPENSSL_atomic_add:
-+{ .mii;	ld4		r2=[r32]
-+	nop.i		0
-+	nop.i		0		};;
-+.Lspin:
-+{ .mii;	mov		ar.ccv=r2
-+	add		r8=r2,r33
-+	mov		r3=r2		};;
-+{ .mmi;	mf;;
-+	cmpxchg4.acq	r2=[r32],r8,ar.ccv
-+	nop.i		0		};;
-+{ .mib;	cmp.ne		p6,p0=r2,r3
-+	nop.i		0
-+(p6)	br.dpnt		.Lspin		};;
-+{ .mib;	nop.m		0
-+	sxt4		r8=r8
-+	br.ret.sptk.many	b0	};;
-+.endp	OPENSSL_atomic_add#
-+
-+// Returns a structure comprising pointer to the top of stack of
-+// the caller and pointer beyond backing storage for the current
-+// register frame. The latter is required, because it might be
-+// insufficient to wipe backing storage for the current frame
-+// (as this procedure does), one might have to go further, toward
-+// higher addresses to reach for whole "retroactively" saved
-+// context...
-+.global	OPENSSL_wipe_cpu#
-+.proc	OPENSSL_wipe_cpu#
-+.align	32
-+OPENSSL_wipe_cpu:
-+	.prologue
-+	.fframe	0
-+	.save	ar.pfs,r2
-+	.save	ar.lc,r3
-+{ .mib;	alloc		r2=ar.pfs,0,96,0,96
-+	mov		r3=ar.lc
-+	brp.loop.imp	.L_wipe_top,.L_wipe_end-16
-+					};;
-+{ .mii;	mov		r9=ar.bsp
-+	mov		r8=pr
-+	mov		ar.lc=96	};;
-+	.body
-+{ .mii;	add		r9=96*8-8,r9
-+	mov		ar.ec=1		};;
-+
-+// One can sweep double as fast, but then we can't quarantee
-+// that backing storage is wiped...
-+.L_wipe_top:
-+{ .mfi;	st8		[r9]=r0,-8
-+	mov		f127=f0
-+	mov		r127=r0		}
-+{ .mfb;	nop.m		0
-+	nop.f		0
-+	br.ctop.sptk	.L_wipe_top	};;
-+.L_wipe_end:
-+
-+{ .mfi;	mov		r11=r0
-+	mov		f6=f0
-+	mov		r14=r0		}
-+{ .mfi;	mov		r15=r0
-+	mov		f7=f0
-+	mov		r16=r0		}
-+{ .mfi;	mov		r17=r0
-+	mov		f8=f0
-+	mov		r18=r0		}
-+{ .mfi;	mov		r19=r0
-+	mov		f9=f0
-+	mov		r20=r0		}
-+{ .mfi;	mov		r21=r0
-+	mov		f10=f0
-+	mov		r22=r0		}
-+{ .mfi;	mov		r23=r0
-+	mov		f11=f0
-+	mov		r24=r0		}
-+{ .mfi;	mov		r25=r0
-+	mov		f12=f0
-+	mov		r26=r0		}
-+{ .mfi;	mov		r27=r0
-+	mov		f13=f0
-+	mov		r28=r0		}
-+{ .mfi;	mov		r29=r0
-+	mov		f14=f0
-+	mov		r30=r0		}
-+{ .mfi;	mov		r31=r0
-+	mov		f15=f0
-+	nop.i		0		}
-+{ .mfi;	mov		f16=f0		}
-+{ .mfi;	mov		f17=f0		}
-+{ .mfi;	mov		f18=f0		}
-+{ .mfi;	mov		f19=f0		}
-+{ .mfi;	mov		f20=f0		}
-+{ .mfi;	mov		f21=f0		}
-+{ .mfi;	mov		f22=f0		}
-+{ .mfi;	mov		f23=f0		}
-+{ .mfi;	mov		f24=f0		}
-+{ .mfi;	mov		f25=f0		}
-+{ .mfi;	mov		f26=f0		}
-+{ .mfi;	mov		f27=f0		}
-+{ .mfi;	mov		f28=f0		}
-+{ .mfi;	mov		f29=f0		}
-+{ .mfi;	mov		f30=f0		}
-+{ .mfi;	add		r9=96*8+8,r9
-+	mov		f31=f0
-+	mov		pr=r8,0x1ffff	}
-+{ .mib;	mov		r8=sp
-+	mov		ar.lc=r3
-+	br.ret.sptk	b0		};;
-+.endp	OPENSSL_wipe_cpu#
-+
-+.global	OPENSSL_cleanse#
-+.proc	OPENSSL_cleanse#
-+OPENSSL_cleanse:
-+{ .mib;	cmp.eq		p6,p0=0,r33	    // len==0
-+	ADDP		r32=0,r32
-+(p6)	br.ret.spnt	b0		};;
-+{ .mib;	and		r2=7,r32
-+	cmp.leu		p6,p0=15,r33	    // len>=15
-+(p6)	br.cond.dptk	.Lot		};;
-+
-+.Little:
-+{ .mib;	st1		[r32]=r0,1
-+	cmp.ltu		p6,p7=1,r33	}  // len>1
-+{ .mbb;	add		r33=-1,r33	   // len--
-+(p6)	br.cond.dptk	.Little
-+(p7)	br.ret.sptk.many	b0	};;
-+
-+.Lot:
-+{ .mib;	cmp.eq		p6,p0=0,r2
-+(p6)	br.cond.dptk	.Laligned	};;
-+{ .mmi;	st1		[r32]=r0,1;;
-+	and		r2=7,r32	}
-+{ .mib;	add		r33=-1,r33
-+	br		.Lot		};;
-+
-+.Laligned:
-+{ .mmi;	st8		[r32]=r0,8
-+	and		r2=-8,r33	    // len&~7
-+	add		r33=-8,r33	};; // len-=8
-+{ .mib;	cmp.ltu		p6,p0=8,r2	    // ((len+8)&~7)>8
-+(p6)	br.cond.dptk	.Laligned	};;
-+
-+{ .mbb;	cmp.eq		p6,p7=r0,r33
-+(p7)	br.cond.dpnt	.Little
-+(p6)	br.ret.sptk.many	b0	};;
-+.endp	OPENSSL_cleanse#
-+
-+.global	CRYPTO_memcmp#
-+.proc	CRYPTO_memcmp#
-+.align	32
-+.skip	16
-+CRYPTO_memcmp:
-+	.prologue
-+{ .mib;	mov		r8=0
-+	cmp.eq		p6,p0=0,r34	    // len==0?
-+(p6)	br.ret.spnt	b0		};;
-+	.save		ar.pfs,r2
-+{ .mib;	alloc		r2=ar.pfs,3,5,0,8
-+	.save		ar.lc,r3
-+	mov		r3=ar.lc
-+	brp.loop.imp	.Loop_cmp_ctop,.Loop_cmp_cend-16
-+					}
-+{ .mib;	sub		r10=r34,r0,1
-+	.save		pr,r9
-+	mov		r9=pr		};;
-+{ .mii;	ADDP		r16=0,r32
-+	mov		ar.lc=r10
-+	mov		ar.ec=4		}
-+{ .mib;	ADDP		r17=0,r33
-+	mov		pr.rot=1<<16	};;
-+
-+.Loop_cmp_ctop:
-+{ .mib;	(p16)	ld1	r32=[r16],1
-+	(p18)	xor	r34=r34,r38	}
-+{ .mib;	(p16)	ld1	r36=[r17],1
-+	(p19)	or	r8=r8,r35
-+	br.ctop.sptk	.Loop_cmp_ctop	};;
-+.Loop_cmp_cend:
-+
-+{ .mib;	cmp.ne		p6,p0=0,r8
-+	mov		ar.lc=r3	};;
-+{ .mib;
-+(p6)	mov		r8=1
-+	mov		pr=r9,0x1ffff
-+	br.ret.sptk.many	b0	};;
-+.endp	CRYPTO_memcmp#
-+
-+.global	OPENSSL_instrument_bus#
-+.proc	OPENSSL_instrument_bus#
-+OPENSSL_instrument_bus:
-+{ .mmi;	mov		r2=r33
-+	ADDP		r32=0,r32	}
-+{ .mmi;	mov		r8=ar.itc;;
-+	mov		r10=r0
-+	mov		r9=r8		};;
-+
-+{ .mmi;	fc		r32;;
-+	ld4		r8=[r32]	};;
-+{ .mmi;	mf
-+	mov		ar.ccv=r8
-+	add		r8=r8,r10	};;
-+{ .mmi;	cmpxchg4.acq	r3=[r32],r8,ar.ccv
-+					};;
-+.Loop:
-+{ .mmi;	mov		r8=ar.itc;;
-+	sub		r10=r8,r9		// diff=tick-lasttick
-+	mov		r9=r8		};;	// lasttick=tick
-+{ .mmi;	fc		r32;;
-+	ld4		r8=[r32]	};;
-+{ .mmi;	mf
-+	mov		ar.ccv=r8
-+	add		r8=r8,r10	};;
-+{ .mmi;	cmpxchg4.acq	r3=[r32],r8,ar.ccv
-+	add		r33=-1,r33
-+	add		r32=4,r32	};;
-+{ .mib;	cmp4.ne		p6,p0=0,r33
-+(p6)	br.cond.dptk	.Loop		};;
-+
-+{ .mib;	sub		r8=r2,r33
-+	br.ret.sptk.many	b0	};;
-+.endp	OPENSSL_instrument_bus#
-+
-+.global	OPENSSL_instrument_bus2#
-+.proc	OPENSSL_instrument_bus2#
-+OPENSSL_instrument_bus2:
-+{ .mmi;	mov		r2=r33			// put aside cnt
-+	ADDP		r32=0,r32	}
-+{ .mmi;	mov		r8=ar.itc;;
-+	mov		r10=r0
-+	mov		r9=r8		};;
-+
-+{ .mmi;	fc		r32;;
-+	ld4		r8=[r32]	};;
-+{ .mmi;	mf
-+	mov		ar.ccv=r8
-+	add		r8=r8,r10	};;
-+{ .mmi;	cmpxchg4.acq	r3=[r32],r8,ar.ccv
-+					};;
-+
-+{ .mmi;	mov		r8=ar.itc;;
-+	sub		r10=r8,r9
-+	mov		r9=r8		};;
-+.Loop2:
-+{ .mmi;	mov		r11=r10			// lastdiff=diff
-+	add		r34=-1,r34	};;	// --max
-+{ .mmi;	fc		r32;;
-+	ld4		r8=[r32]
-+	cmp4.eq		p6,p0=0,r34	};;
-+{ .mmi;	mf
-+	mov		ar.ccv=r8
-+	add		r8=r8,r10	};;
-+{ .mmb;	cmpxchg4.acq	r3=[r32],r8,ar.ccv
-+(p6)	br.cond.spnt	.Ldone2		};;
-+
-+{ .mmi;	mov		r8=ar.itc;;
-+	sub		r10=r8,r9		// diff=tick-lasttick
-+	mov		r9=r8		};;	// lasttick=tick
-+{ .mmi;	cmp.ne		p6,p0=r10,r11;;		// diff!=lastdiff
-+(p6)	add		r33=-1,r33	};;	// conditional --cnt
-+{ .mib;	cmp4.ne		p7,p0=0,r33
-+(p6)	add		r32=4,r32		// conditional ++out
-+(p7)	br.cond.dptk	.Loop2		};;
-+.Ldone2:
-+{ .mib;	sub		r8=r2,r33
-+	br.ret.sptk.many	b0	};;
-+.endp	OPENSSL_instrument_bus2#
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/build.info
-new file mode 100644
-index 0000000..2326123
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        i_cbc.c i_cfb64.c i_ofb64.c i_ecb.c i_skey.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_cbc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_cbc.c
-new file mode 100644
-index 0000000..a70a868
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_cbc.c
-@@ -0,0 +1,122 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "idea_lcl.h"
-+
-+void IDEA_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                      long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
-+                      int encrypt)
-+{
-+    register unsigned long tin0, tin1;
-+    register unsigned long tout0, tout1, xor0, xor1;
-+    register long l = length;
-+    unsigned long tin[2];
-+
-+    if (encrypt) {
-+        n2l(iv, tout0);
-+        n2l(iv, tout1);
-+        iv -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            n2l(in, tin0);
-+            n2l(in, tin1);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            IDEA_encrypt(tin, ks);
-+            tout0 = tin[0];
-+            l2n(tout0, out);
-+            tout1 = tin[1];
-+            l2n(tout1, out);
-+        }
-+        if (l != -8) {
-+            n2ln(in, tin0, tin1, l + 8);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            IDEA_encrypt(tin, ks);
-+            tout0 = tin[0];
-+            l2n(tout0, out);
-+            tout1 = tin[1];
-+            l2n(tout1, out);
-+        }
-+        l2n(tout0, iv);
-+        l2n(tout1, iv);
-+    } else {
-+        n2l(iv, xor0);
-+        n2l(iv, xor1);
-+        iv -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            n2l(in, tin0);
-+            tin[0] = tin0;
-+            n2l(in, tin1);
-+            tin[1] = tin1;
-+            IDEA_encrypt(tin, ks);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2n(tout0, out);
-+            l2n(tout1, out);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        if (l != -8) {
-+            n2l(in, tin0);
-+            tin[0] = tin0;
-+            n2l(in, tin1);
-+            tin[1] = tin1;
-+            IDEA_encrypt(tin, ks);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2nn(tout0, tout1, out, l + 8);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        l2n(xor0, iv);
-+        l2n(xor1, iv);
-+    }
-+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
-+    tin[0] = tin[1] = 0;
-+}
-+
-+void IDEA_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key)
-+{
-+    register IDEA_INT *p;
-+    register unsigned long x1, x2, x3, x4, t0, t1, ul;
-+
-+    x2 = d[0];
-+    x1 = (x2 >> 16);
-+    x4 = d[1];
-+    x3 = (x4 >> 16);
-+
-+    p = &(key->data[0][0]);
-+
-+    E_IDEA(0);
-+    E_IDEA(1);
-+    E_IDEA(2);
-+    E_IDEA(3);
-+    E_IDEA(4);
-+    E_IDEA(5);
-+    E_IDEA(6);
-+    E_IDEA(7);
-+
-+    x1 &= 0xffff;
-+    idea_mul(x1, x1, *p, ul);
-+    p++;
-+
-+    t0 = x3 + *(p++);
-+    t1 = x2 + *(p++);
-+
-+    x4 &= 0xffff;
-+    idea_mul(x4, x4, *p, ul);
-+
-+    d[0] = (t0 & 0xffff) | ((x1 & 0xffff) << 16);
-+    d[1] = (x4 & 0xffff) | ((t1 & 0xffff) << 16);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_cfb64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_cfb64.c
-new file mode 100644
-index 0000000..daf467e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_cfb64.c
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "idea_lcl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit cfb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+
-+void IDEA_cfb64_encrypt(const unsigned char *in, unsigned char *out,
-+                        long length, IDEA_KEY_SCHEDULE *schedule,
-+                        unsigned char *ivec, int *num, int encrypt)
-+{
-+    register unsigned long v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    unsigned long ti[2];
-+    unsigned char *iv, c, cc;
-+
-+    iv = (unsigned char *)ivec;
-+    if (encrypt) {
-+        while (l--) {
-+            if (n == 0) {
-+                n2l(iv, v0);
-+                ti[0] = v0;
-+                n2l(iv, v1);
-+                ti[1] = v1;
-+                IDEA_encrypt((unsigned long *)ti, schedule);
-+                iv = (unsigned char *)ivec;
-+                t = ti[0];
-+                l2n(t, iv);
-+                t = ti[1];
-+                l2n(t, iv);
-+                iv = (unsigned char *)ivec;
-+            }
-+            c = *(in++) ^ iv[n];
-+            *(out++) = c;
-+            iv[n] = c;
-+            n = (n + 1) & 0x07;
-+        }
-+    } else {
-+        while (l--) {
-+            if (n == 0) {
-+                n2l(iv, v0);
-+                ti[0] = v0;
-+                n2l(iv, v1);
-+                ti[1] = v1;
-+                IDEA_encrypt((unsigned long *)ti, schedule);
-+                iv = (unsigned char *)ivec;
-+                t = ti[0];
-+                l2n(t, iv);
-+                t = ti[1];
-+                l2n(t, iv);
-+                iv = (unsigned char *)ivec;
-+            }
-+            cc = *(in++);
-+            c = iv[n];
-+            iv[n] = cc;
-+            *(out++) = c ^ cc;
-+            n = (n + 1) & 0x07;
-+        }
-+    }
-+    v0 = v1 = ti[0] = ti[1] = t = c = cc = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_ecb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_ecb.c
-new file mode 100644
-index 0000000..2208287
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_ecb.c
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "idea_lcl.h"
-+#include 
-+
-+const char *IDEA_options(void)
-+{
-+    return ("idea(int)");
-+}
-+
-+void IDEA_ecb_encrypt(const unsigned char *in, unsigned char *out,
-+                      IDEA_KEY_SCHEDULE *ks)
-+{
-+    unsigned long l0, l1, d[2];
-+
-+    n2l(in, l0);
-+    d[0] = l0;
-+    n2l(in, l1);
-+    d[1] = l1;
-+    IDEA_encrypt(d, ks);
-+    l0 = d[0];
-+    l2n(l0, out);
-+    l1 = d[1];
-+    l2n(l1, out);
-+    l0 = l1 = d[0] = d[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_ofb64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_ofb64.c
-new file mode 100644
-index 0000000..997a7b8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_ofb64.c
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "idea_lcl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit ofb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+void IDEA_ofb64_encrypt(const unsigned char *in, unsigned char *out,
-+                        long length, IDEA_KEY_SCHEDULE *schedule,
-+                        unsigned char *ivec, int *num)
-+{
-+    register unsigned long v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    unsigned char d[8];
-+    register char *dp;
-+    unsigned long ti[2];
-+    unsigned char *iv;
-+    int save = 0;
-+
-+    iv = (unsigned char *)ivec;
-+    n2l(iv, v0);
-+    n2l(iv, v1);
-+    ti[0] = v0;
-+    ti[1] = v1;
-+    dp = (char *)d;
-+    l2n(v0, dp);
-+    l2n(v1, dp);
-+    while (l--) {
-+        if (n == 0) {
-+            IDEA_encrypt((unsigned long *)ti, schedule);
-+            dp = (char *)d;
-+            t = ti[0];
-+            l2n(t, dp);
-+            t = ti[1];
-+            l2n(t, dp);
-+            save++;
-+        }
-+        *(out++) = *(in++) ^ d[n];
-+        n = (n + 1) & 0x07;
-+    }
-+    if (save) {
-+        v0 = ti[0];
-+        v1 = ti[1];
-+        iv = (unsigned char *)ivec;
-+        l2n(v0, iv);
-+        l2n(v1, iv);
-+    }
-+    t = v0 = v1 = ti[0] = ti[1] = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_skey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_skey.c
-new file mode 100644
-index 0000000..0285324
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/i_skey.c
-@@ -0,0 +1,112 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "idea_lcl.h"
-+
-+static IDEA_INT inverse(unsigned int xin);
-+void IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks)
-+{
-+    int i;
-+    register IDEA_INT *kt, *kf, r0, r1, r2;
-+
-+    kt = &(ks->data[0][0]);
-+    n2s(key, kt[0]);
-+    n2s(key, kt[1]);
-+    n2s(key, kt[2]);
-+    n2s(key, kt[3]);
-+    n2s(key, kt[4]);
-+    n2s(key, kt[5]);
-+    n2s(key, kt[6]);
-+    n2s(key, kt[7]);
-+
-+    kf = kt;
-+    kt += 8;
-+    for (i = 0; i < 6; i++) {
-+        r2 = kf[1];
-+        r1 = kf[2];
-+        *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff;
-+        r0 = kf[3];
-+        *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
-+        r1 = kf[4];
-+        *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
-+        r0 = kf[5];
-+        *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
-+        r1 = kf[6];
-+        *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
-+        r0 = kf[7];
-+        *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
-+        r1 = kf[0];
-+        if (i >= 5)
-+            break;
-+        *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
-+        *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff;
-+        kf += 8;
-+    }
-+}
-+
-+void IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk)
-+{
-+    int r;
-+    register IDEA_INT *fp, *tp, t;
-+
-+    tp = &(dk->data[0][0]);
-+    fp = &(ek->data[8][0]);
-+    for (r = 0; r < 9; r++) {
-+        *(tp++) = inverse(fp[0]);
-+        *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff);
-+        *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff);
-+        *(tp++) = inverse(fp[3]);
-+        if (r == 8)
-+            break;
-+        fp -= 6;
-+        *(tp++) = fp[4];
-+        *(tp++) = fp[5];
-+    }
-+
-+    tp = &(dk->data[0][0]);
-+    t = tp[1];
-+    tp[1] = tp[2];
-+    tp[2] = t;
-+
-+    t = tp[49];
-+    tp[49] = tp[50];
-+    tp[50] = t;
-+}
-+
-+/* taken directly from the 'paper' I'll have a look at it later */
-+static IDEA_INT inverse(unsigned int xin)
-+{
-+    long n1, n2, q, r, b1, b2, t;
-+
-+    if (xin == 0)
-+        b2 = 0;
-+    else {
-+        n1 = 0x10001;
-+        n2 = xin;
-+        b2 = 1;
-+        b1 = 0;
-+
-+        do {
-+            r = (n1 % n2);
-+            q = (n1 - r) / n2;
-+            if (r == 0) {
-+                if (b2 < 0)
-+                    b2 = 0x10001 + b2;
-+            } else {
-+                n1 = n2;
-+                n2 = r;
-+                t = b2;
-+                b2 = b1 - q * b2;
-+                b1 = t;
-+            }
-+        } while (r != 0);
-+    }
-+    return ((IDEA_INT) b2);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/idea_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/idea_lcl.h
-new file mode 100644
-index 0000000..f227d0d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/idea/idea_lcl.h
-@@ -0,0 +1,103 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * The new form of this macro (check if the a*b == 0) was suggested by Colin
-+ * Plumb 
-+ */
-+/* Removal of the inner if from from Wei Dai 24/4/96 */
-+#define idea_mul(r,a,b,ul) \
-+ul=(unsigned long)a*b; \
-+if (ul != 0) \
-+        { \
-+        r=(ul&0xffff)-(ul>>16); \
-+        r-=((r)>>16); \
-+        } \
-+else \
-+        r=(-(int)a-b+1);        /* assuming a or b is 0 and in range */
-+
-+/*
-+ * 7/12/95 - Many thanks to Rhys Weatherley  for
-+ * pointing out that I was assuming little endian byte order for all
-+ * quantities what idea actually used bigendian.  No where in the spec does
-+ * it mention this, it is all in terms of 16 bit numbers and even the example
-+ * does not use byte streams for the input example :-(. If you byte swap each
-+ * pair of input, keys and iv, the functions would produce the output as the
-+ * old version :-(.
-+ */
-+
-+/* NOTE - c is not incremented as per n2l */
-+#define n2ln(c,l1,l2,n) { \
-+                        c+=n; \
-+                        l1=l2=0; \
-+                        switch (n) { \
-+                        case 8: l2 =((unsigned long)(*(--(c))))    ; \
-+                        case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
-+                        case 6: l2|=((unsigned long)(*(--(c))))<<16; \
-+                        case 5: l2|=((unsigned long)(*(--(c))))<<24; \
-+                        case 4: l1 =((unsigned long)(*(--(c))))    ; \
-+                        case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
-+                        case 2: l1|=((unsigned long)(*(--(c))))<<16; \
-+                        case 1: l1|=((unsigned long)(*(--(c))))<<24; \
-+                                } \
-+                        }
-+
-+/* NOTE - c is not incremented as per l2n */
-+#define l2nn(l1,l2,c,n) { \
-+                        c+=n; \
-+                        switch (n) { \
-+                        case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
-+                        case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
-+                        case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
-+                        case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
-+                        case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
-+                        case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
-+                        case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
-+                        case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
-+                                } \
-+                        }
-+
-+#undef n2l
-+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
-+                         l|=((unsigned long)(*((c)++)))<<16L, \
-+                         l|=((unsigned long)(*((c)++)))<< 8L, \
-+                         l|=((unsigned long)(*((c)++))))
-+
-+#undef l2n
-+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)     )&0xff))
-+
-+#undef s2n
-+#define s2n(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff))
-+
-+#undef n2s
-+#define n2s(c,l)        (l =((IDEA_INT)(*((c)++)))<< 8L, \
-+                         l|=((IDEA_INT)(*((c)++)))      )
-+
-+
-+#define E_IDEA(num) \
-+        x1&=0xffff; \
-+        idea_mul(x1,x1,*p,ul); p++; \
-+        x2+= *(p++); \
-+        x3+= *(p++); \
-+        x4&=0xffff; \
-+        idea_mul(x4,x4,*p,ul); p++; \
-+        t0=(x1^x3)&0xffff; \
-+        idea_mul(t0,t0,*p,ul); p++; \
-+        t1=(t0+(x2^x4))&0xffff; \
-+        idea_mul(t1,t1,*p,ul); p++; \
-+        t0+=t1; \
-+        x1^=t1; \
-+        x4^=t0; \
-+        ul=x2^t0; /* do the swap to x3 */ \
-+        x2=x3^t1; \
-+        x3=ul;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/asn1_int.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/asn1_int.h
-new file mode 100644
-index 0000000..f70e3b4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/asn1_int.h
-@@ -0,0 +1,94 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Internal ASN1 structures and functions: not for application use */
-+
-+/* ASN1 public key method structure */
-+
-+struct evp_pkey_asn1_method_st {
-+    int pkey_id;
-+    int pkey_base_id;
-+    unsigned long pkey_flags;
-+    char *pem_str;
-+    char *info;
-+    int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub);
-+    int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk);
-+    int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b);
-+    int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent,
-+                      ASN1_PCTX *pctx);
-+    int (*priv_decode) (EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf);
-+    int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
-+    int (*priv_print) (BIO *out, const EVP_PKEY *pkey, int indent,
-+                       ASN1_PCTX *pctx);
-+    int (*pkey_size) (const EVP_PKEY *pk);
-+    int (*pkey_bits) (const EVP_PKEY *pk);
-+    int (*pkey_security_bits) (const EVP_PKEY *pk);
-+    int (*param_decode) (EVP_PKEY *pkey,
-+                         const unsigned char **pder, int derlen);
-+    int (*param_encode) (const EVP_PKEY *pkey, unsigned char **pder);
-+    int (*param_missing) (const EVP_PKEY *pk);
-+    int (*param_copy) (EVP_PKEY *to, const EVP_PKEY *from);
-+    int (*param_cmp) (const EVP_PKEY *a, const EVP_PKEY *b);
-+    int (*param_print) (BIO *out, const EVP_PKEY *pkey, int indent,
-+                        ASN1_PCTX *pctx);
-+    int (*sig_print) (BIO *out,
-+                      const X509_ALGOR *sigalg, const ASN1_STRING *sig,
-+                      int indent, ASN1_PCTX *pctx);
-+    void (*pkey_free) (EVP_PKEY *pkey);
-+    int (*pkey_ctrl) (EVP_PKEY *pkey, int op, long arg1, void *arg2);
-+    /* Legacy functions for old PEM */
-+    int (*old_priv_decode) (EVP_PKEY *pkey,
-+                            const unsigned char **pder, int derlen);
-+    int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder);
-+    /* Custom ASN1 signature verification */
-+    int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
-+                        X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey);
-+    int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
-+                      X509_ALGOR *alg1, X509_ALGOR *alg2,
-+                      ASN1_BIT_STRING *sig);
-+} /* EVP_PKEY_ASN1_METHOD */ ;
-+
-+DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)
-+
-+extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
-+extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
-+extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth;
-+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5];
-+extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
-+extern const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth;
-+extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
-+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2];
-+
-+/*
-+ * These are used internally in the ASN1_OBJECT to keep track of whether the
-+ * names and data need to be free()ed
-+ */
-+# define ASN1_OBJECT_FLAG_DYNAMIC         0x01/* internal use */
-+# define ASN1_OBJECT_FLAG_CRITICAL        0x02/* critical x509v3 object id */
-+# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */
-+# define ASN1_OBJECT_FLAG_DYNAMIC_DATA    0x08/* internal use */
-+struct asn1_object_st {
-+    const char *sn, *ln;
-+    int nid;
-+    int length;
-+    const unsigned char *data;  /* data remains const after init */
-+    int flags;                  /* Should we free this one */
-+};
-+
-+/* ASN1 print context structure */
-+
-+struct asn1_pctx_st {
-+    unsigned long flags;
-+    unsigned long nm_flags;
-+    unsigned long cert_flags;
-+    unsigned long oid_flags;
-+    unsigned long str_flags;
-+} /* ASN1_PCTX */ ;
-+
-+int asn1_valid_host(const ASN1_STRING *host);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/async.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/async.h
-new file mode 100644
-index 0000000..db56258
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/async.h
-@@ -0,0 +1,14 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+int async_init(void);
-+void async_deinit(void);
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_conf.h.in b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_conf.h.in
-new file mode 100644
-index 0000000..ec6e4f6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_conf.h.in
-@@ -0,0 +1,27 @@
-+{- join("\n",map { "/* $_ */" } @autowarntext) -}
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_BN_CONF_H
-+# define HEADER_BN_CONF_H
-+
-+/*
-+ * The contents of this file are not used in the UEFI build, as
-+ * both 32-bit and 64-bit builds are supported from a single run
-+ * of the Configure script.
-+ */
-+
-+/* Should we define BN_DIV2W here? */
-+
-+/* Only one for the following should be defined */
-+{- $config{b64l} ? "#define" : "#undef" -} SIXTY_FOUR_BIT_LONG
-+{- $config{b64}  ? "#define" : "#undef" -} SIXTY_FOUR_BIT
-+{- $config{b32}  ? "#define" : "#undef" -} THIRTY_TWO_BIT
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_dh.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_dh.h
-new file mode 100644
-index 0000000..b4bca40
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_dh.h
-@@ -0,0 +1,17 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#define declare_dh_bn(x) \
-+    const extern BIGNUM _bignum_dh##x##_p;              \
-+    const extern BIGNUM _bignum_dh##x##_g;              \
-+    const extern BIGNUM _bignum_dh##x##_q;
-+
-+declare_dh_bn(1024_160)
-+declare_dh_bn(2048_224)
-+declare_dh_bn(2048_256)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_int.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_int.h
-new file mode 100644
-index 0000000..9c984ba
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_int.h
-@@ -0,0 +1,82 @@
-+/*
-+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_BN_INT_H
-+# define HEADER_BN_INT_H
-+
-+# include 
-+# include 
-+
-+#ifdef  __cplusplus
-+extern "C" {
-+#endif
-+
-+BIGNUM *bn_wexpand(BIGNUM *a, int words);
-+BIGNUM *bn_expand2(BIGNUM *a, int words);
-+
-+void bn_correct_top(BIGNUM *a);
-+
-+/*
-+ * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
-+ * This is an array r[] of values that are either zero or odd with an
-+ * absolute value less than 2^w satisfying scalar = \sum_j r[j]*2^j where at
-+ * most one of any w+1 consecutive digits is non-zero with the exception that
-+ * the most significant digit may be only w-1 zeros away from that next
-+ * non-zero digit.
-+ */
-+signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len);
-+
-+int bn_get_top(const BIGNUM *a);
-+
-+void bn_set_top(BIGNUM *a, int top);
-+
-+int bn_get_dmax(const BIGNUM *a);
-+
-+/* Set all words to zero */
-+void bn_set_all_zero(BIGNUM *a);
-+
-+/*
-+ * Copy the internal BIGNUM words into out which holds size elements (and size
-+ * must be bigger than top)
-+ */
-+int bn_copy_words(BN_ULONG *out, const BIGNUM *in, int size);
-+
-+BN_ULONG *bn_get_words(const BIGNUM *a);
-+
-+/*
-+ * Set the internal data words in a to point to words which contains size
-+ * elements. The BN_FLG_STATIC_DATA flag is set
-+ */
-+void bn_set_static_words(BIGNUM *a, BN_ULONG *words, int size);
-+
-+/*
-+ * Copy words into the BIGNUM |a|, reallocating space as necessary.
-+ * The negative flag of |a| is not modified.
-+ * Returns 1 on success and 0 on failure.
-+ */
-+/*
-+ * |num_words| is int because bn_expand2 takes an int. This is an internal
-+ * function so we simply trust callers not to pass negative values.
-+ */
-+int bn_set_words(BIGNUM *a, BN_ULONG *words, int num_words);
-+
-+size_t bn_sizeof_BIGNUM(void);
-+
-+/*
-+ * Return element el from an array of BIGNUMs starting at base (required
-+ * because callers do not know the size of BIGNUM at compilation time)
-+ */
-+BIGNUM *bn_array_el(BIGNUM *base, int el);
-+
-+
-+#ifdef  __cplusplus
-+}
-+#endif
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_srp.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_srp.h
-new file mode 100644
-index 0000000..844fd01
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/bn_srp.h
-@@ -0,0 +1,9 @@
-+/*
-+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/chacha.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/chacha.h
-new file mode 100644
-index 0000000..7d4366e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/chacha.h
-@@ -0,0 +1,49 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_CHACHA_H
-+#define HEADER_CHACHA_H
-+
-+#include 
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * ChaCha20_ctr32 encrypts |len| bytes from |inp| with the given key and
-+ * nonce and writes the result to |out|, which may be equal to |inp|.
-+ * The |key| is not 32 bytes of verbatim key material though, but the
-+ * said material collected into 8 32-bit elements array in host byte
-+ * order. Same approach applies to nonce: the |counter| argument is
-+ * pointer to concatenated nonce and counter values collected into 4
-+ * 32-bit elements. This, passing crypto material collected into 32-bit
-+ * elements as opposite to passing verbatim byte vectors, is chosen for
-+ * efficiency in multi-call scenarios.
-+ */
-+void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
-+                    size_t len, const unsigned int key[8],
-+                    const unsigned int counter[4]);
-+/*
-+ * You can notice that there is no key setup procedure. Because it's
-+ * as trivial as collecting bytes into 32-bit elements, it's reckoned
-+ * that below macro is sufficient.
-+ */
-+#define CHACHA_U8TOU32(p)  ( \
-+                ((unsigned int)(p)[0])     | ((unsigned int)(p)[1]<<8) | \
-+                ((unsigned int)(p)[2]<<16) | ((unsigned int)(p)[3]<<24)  )
-+
-+#define CHACHA_KEY_SIZE		32
-+#define CHACHA_CTR_SIZE		16
-+#define CHACHA_BLK_SIZE		64
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/cryptlib.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/cryptlib.h
-new file mode 100644
-index 0000000..f3ec9b6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/cryptlib.h
-@@ -0,0 +1,81 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_CRYPTLIB_H
-+# define HEADER_CRYPTLIB_H
-+
-+# include 
-+# include 
-+
-+# include "e_os.h"
-+
-+# ifdef OPENSSL_USE_APPLINK
-+#  undef BIO_FLAGS_UPLINK
-+#  define BIO_FLAGS_UPLINK 0x8000
-+#  include "ms/uplink.h"
-+# endif
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+
-+#ifdef  __cplusplus
-+extern "C" {
-+#endif
-+
-+typedef struct ex_callback_st EX_CALLBACK;
-+
-+DEFINE_STACK_OF(EX_CALLBACK)
-+
-+typedef struct app_mem_info_st APP_INFO;
-+
-+typedef struct mem_st MEM;
-+DEFINE_LHASH_OF(MEM);
-+
-+# ifndef OPENSSL_SYS_VMS
-+#  define X509_CERT_AREA          OPENSSLDIR
-+#  define X509_CERT_DIR           OPENSSLDIR "/certs"
-+#  define X509_CERT_FILE          OPENSSLDIR "/cert.pem"
-+#  define X509_PRIVATE_DIR        OPENSSLDIR "/private"
-+#  define CTLOG_FILE              OPENSSLDIR "/ct_log_list.cnf"
-+# else
-+#  define X509_CERT_AREA          "OSSL$DATAROOT:[000000]"
-+#  define X509_CERT_DIR           "OSSL$DATAROOT:[CERTS]"
-+#  define X509_CERT_FILE          "OSSL$DATAROOT:[000000]cert.pem"
-+#  define X509_PRIVATE_DIR        "OSSL$DATAROOT:[PRIVATE]"
-+#  define CTLOG_FILE              "OSSL$DATAROOT:[000000]ct_log_list.cnf"
-+# endif
-+
-+# define X509_CERT_DIR_EVP        "SSL_CERT_DIR"
-+# define X509_CERT_FILE_EVP       "SSL_CERT_FILE"
-+# define CTLOG_FILE_EVP           "CTLOG_FILE"
-+
-+/* size of string representations */
-+# define DECIMAL_SIZE(type)      ((sizeof(type)*8+2)/3+1)
-+# define HEX_SIZE(type)          (sizeof(type)*2)
-+
-+void OPENSSL_cpuid_setup(void);
-+extern unsigned int OPENSSL_ia32cap_P[];
-+void OPENSSL_showfatal(const char *fmta, ...);
-+extern int OPENSSL_NONPIC_relocated;
-+void crypto_cleanup_all_ex_data_int(void);
-+
-+int openssl_strerror_r(int errnum, char *buf, size_t buflen);
-+# if !defined(OPENSSL_NO_STDIO)
-+FILE *openssl_fopen(const char *filename, const char *mode);
-+# else
-+void *openssl_fopen(const char *filename, const char *mode);
-+# endif
-+
-+#ifdef  __cplusplus
-+}
-+#endif
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/cryptlib_int.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/cryptlib_int.h
-new file mode 100644
-index 0000000..8e2a719
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/cryptlib_int.h
-@@ -0,0 +1,31 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+/* This file is not scanned by mkdef.pl, whereas cryptlib.h is */
-+
-+struct thread_local_inits_st {
-+    int async;
-+    int err_state;
-+};
-+
-+int ossl_init_thread_start(uint64_t opts);
-+
-+/*
-+ * OPENSSL_INIT flags. The primary list of these is in crypto.h. Flags below
-+ * are those omitted from crypto.h because they are "reserved for internal
-+ * use".
-+ */
-+# define OPENSSL_INIT_ZLIB                   0x00010000L
-+
-+/* OPENSSL_INIT_THREAD flags */
-+# define OPENSSL_INIT_THREAD_ASYNC           0x01
-+# define OPENSSL_INIT_THREAD_ERR_STATE       0x02
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/dso_conf.h.in b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/dso_conf.h.in
-new file mode 100644
-index 0000000..daa5e24
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/dso_conf.h.in
-@@ -0,0 +1,15 @@
-+{- join("\n",map { "/* $_ */" } @autowarntext) -}
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_DSO_CONF_H
-+# define HEADER_DSO_CONF_H
-+
-+# define DSO_EXTENSION "{- $target{dso_extension} -}"
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/engine.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/engine.h
-new file mode 100644
-index 0000000..977cf06
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/engine.h
-@@ -0,0 +1,20 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+void engine_load_openssl_int(void);
-+void engine_load_cryptodev_int(void);
-+void engine_load_rdrand_int(void);
-+void engine_load_dynamic_int(void);
-+void engine_load_padlock_int(void);
-+void engine_load_capi_int(void);
-+void engine_load_dasync_int(void);
-+void engine_load_afalg_int(void);
-+void engine_cleanup_int(void);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/err_int.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/err_int.h
-new file mode 100644
-index 0000000..7fec3ed
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/err_int.h
-@@ -0,0 +1,17 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef INTERNAL_ERR_INT_H
-+# define INTERNAL_ERR_INT_H
-+
-+int err_load_crypto_strings_int(void);
-+void err_cleanup(void);
-+void err_delete_thread_state(void);
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/evp_int.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/evp_int.h
-new file mode 100644
-index 0000000..c9ef582
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/evp_int.h
-@@ -0,0 +1,389 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+struct evp_pkey_ctx_st {
-+    /* Method associated with this operation */
-+    const EVP_PKEY_METHOD *pmeth;
-+    /* Engine that implements this method or NULL if builtin */
-+    ENGINE *engine;
-+    /* Key: may be NULL */
-+    EVP_PKEY *pkey;
-+    /* Peer key for key agreement, may be NULL */
-+    EVP_PKEY *peerkey;
-+    /* Actual operation */
-+    int operation;
-+    /* Algorithm specific data */
-+    void *data;
-+    /* Application specific data */
-+    void *app_data;
-+    /* Keygen callback */
-+    EVP_PKEY_gen_cb *pkey_gencb;
-+    /* implementation specific keygen data */
-+    int *keygen_info;
-+    int keygen_info_count;
-+} /* EVP_PKEY_CTX */ ;
-+
-+#define EVP_PKEY_FLAG_DYNAMIC   1
-+
-+struct evp_pkey_method_st {
-+    int pkey_id;
-+    int flags;
-+    int (*init) (EVP_PKEY_CTX *ctx);
-+    int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
-+    void (*cleanup) (EVP_PKEY_CTX *ctx);
-+    int (*paramgen_init) (EVP_PKEY_CTX *ctx);
-+    int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
-+    int (*keygen_init) (EVP_PKEY_CTX *ctx);
-+    int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
-+    int (*sign_init) (EVP_PKEY_CTX *ctx);
-+    int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
-+                 const unsigned char *tbs, size_t tbslen);
-+    int (*verify_init) (EVP_PKEY_CTX *ctx);
-+    int (*verify) (EVP_PKEY_CTX *ctx,
-+                   const unsigned char *sig, size_t siglen,
-+                   const unsigned char *tbs, size_t tbslen);
-+    int (*verify_recover_init) (EVP_PKEY_CTX *ctx);
-+    int (*verify_recover) (EVP_PKEY_CTX *ctx,
-+                           unsigned char *rout, size_t *routlen,
-+                           const unsigned char *sig, size_t siglen);
-+    int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
-+    int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
-+                    EVP_MD_CTX *mctx);
-+    int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
-+    int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
-+                      EVP_MD_CTX *mctx);
-+    int (*encrypt_init) (EVP_PKEY_CTX *ctx);
-+    int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
-+                    const unsigned char *in, size_t inlen);
-+    int (*decrypt_init) (EVP_PKEY_CTX *ctx);
-+    int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
-+                    const unsigned char *in, size_t inlen);
-+    int (*derive_init) (EVP_PKEY_CTX *ctx);
-+    int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
-+    int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
-+    int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value);
-+} /* EVP_PKEY_METHOD */ ;
-+
-+DEFINE_STACK_OF_CONST(EVP_PKEY_METHOD)
-+
-+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
-+
-+extern const EVP_PKEY_METHOD cmac_pkey_meth;
-+extern const EVP_PKEY_METHOD dh_pkey_meth;
-+extern const EVP_PKEY_METHOD dhx_pkey_meth;
-+extern const EVP_PKEY_METHOD dsa_pkey_meth;
-+extern const EVP_PKEY_METHOD ec_pkey_meth;
-+extern const EVP_PKEY_METHOD ecx25519_pkey_meth;
-+extern const EVP_PKEY_METHOD hmac_pkey_meth;
-+extern const EVP_PKEY_METHOD rsa_pkey_meth;
-+extern const EVP_PKEY_METHOD tls1_prf_pkey_meth;
-+extern const EVP_PKEY_METHOD hkdf_pkey_meth;
-+
-+struct evp_md_st {
-+    int type;
-+    int pkey_type;
-+    int md_size;
-+    unsigned long flags;
-+    int (*init) (EVP_MD_CTX *ctx);
-+    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
-+    int (*final) (EVP_MD_CTX *ctx, unsigned char *md);
-+    int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from);
-+    int (*cleanup) (EVP_MD_CTX *ctx);
-+    int block_size;
-+    int ctx_size;               /* how big does the ctx->md_data need to be */
-+    /* control function */
-+    int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
-+} /* EVP_MD */ ;
-+
-+struct evp_cipher_st {
-+    int nid;
-+    int block_size;
-+    /* Default value for variable length ciphers */
-+    int key_len;
-+    int iv_len;
-+    /* Various flags */
-+    unsigned long flags;
-+    /* init key */
-+    int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+                 const unsigned char *iv, int enc);
-+    /* encrypt/decrypt data */
-+    int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out,
-+                      const unsigned char *in, size_t inl);
-+    /* cleanup ctx */
-+    int (*cleanup) (EVP_CIPHER_CTX *);
-+    /* how big ctx->cipher_data needs to be */
-+    int ctx_size;
-+    /* Populate a ASN1_TYPE with parameters */
-+    int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *);
-+    /* Get parameters from a ASN1_TYPE */
-+    int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *);
-+    /* Miscellaneous operations */
-+    int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr);
-+    /* Application data */
-+    void *app_data;
-+} /* EVP_CIPHER */ ;
-+
-+/* Macros to code block cipher wrappers */
-+
-+/* Wrapper functions for each cipher mode */
-+
-+#define EVP_C_DATA(kstruct, ctx) \
-+        ((kstruct *)EVP_CIPHER_CTX_get_cipher_data(ctx))
-+
-+#define BLOCK_CIPHER_ecb_loop() \
-+        size_t i, bl; \
-+        bl = EVP_CIPHER_CTX_cipher(ctx)->block_size;    \
-+        if (inl < bl) return 1;\
-+        inl -= bl; \
-+        for (i=0; i <= inl; i+=bl)
-+
-+#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
-+static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
-+{\
-+        BLOCK_CIPHER_ecb_loop() \
-+            cprefix##_ecb_encrypt(in + i, out + i, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_encrypting(ctx)); \
-+        return 1;\
-+}
-+
-+#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
-+
-+#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
-+    static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
-+{\
-+        while(inl>=EVP_MAXCHUNK) {\
-+            int num = EVP_CIPHER_CTX_num(ctx);\
-+            cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), &num); \
-+            EVP_CIPHER_CTX_set_num(ctx, num);\
-+            inl-=EVP_MAXCHUNK;\
-+            in +=EVP_MAXCHUNK;\
-+            out+=EVP_MAXCHUNK;\
-+        }\
-+        if (inl) {\
-+            int num = EVP_CIPHER_CTX_num(ctx);\
-+            cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), &num); \
-+            EVP_CIPHER_CTX_set_num(ctx, num);\
-+        }\
-+        return 1;\
-+}
-+
-+#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
-+static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
-+{\
-+        while(inl>=EVP_MAXCHUNK) \
-+            {\
-+            cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), EVP_CIPHER_CTX_encrypting(ctx));\
-+            inl-=EVP_MAXCHUNK;\
-+            in +=EVP_MAXCHUNK;\
-+            out+=EVP_MAXCHUNK;\
-+            }\
-+        if (inl)\
-+            cprefix##_cbc_encrypt(in, out, (long)inl, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), EVP_CIPHER_CTX_encrypting(ctx));\
-+        return 1;\
-+}
-+
-+#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched)  \
-+static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
-+{\
-+    size_t chunk = EVP_MAXCHUNK;\
-+    if (cbits == 1)  chunk >>= 3;\
-+    if (inl < chunk) chunk = inl;\
-+    while (inl && inl >= chunk)\
-+    {\
-+        int num = EVP_CIPHER_CTX_num(ctx);\
-+        cprefix##_cfb##cbits##_encrypt(in, out, (long) \
-+            ((cbits == 1) \
-+                && !EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS) \
-+                ? inl*8 : inl), \
-+            &EVP_C_DATA(kstruct, ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx),\
-+            &num, EVP_CIPHER_CTX_encrypting(ctx));\
-+        EVP_CIPHER_CTX_set_num(ctx, num);\
-+        inl -= chunk;\
-+        in += chunk;\
-+        out += chunk;\
-+        if (inl < chunk) chunk = inl;\
-+    }\
-+    return 1;\
-+}
-+
-+#define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
-+        BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
-+        BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
-+        BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
-+        BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched)
-+
-+#define BLOCK_CIPHER_def1(cname, nmode, mode, MODE, kstruct, nid, block_size, \
-+                          key_len, iv_len, flags, init_key, cleanup, \
-+                          set_asn1, get_asn1, ctrl) \
-+static const EVP_CIPHER cname##_##mode = { \
-+        nid##_##nmode, block_size, key_len, iv_len, \
-+        flags | EVP_CIPH_##MODE##_MODE, \
-+        init_key, \
-+        cname##_##mode##_cipher, \
-+        cleanup, \
-+        sizeof(kstruct), \
-+        set_asn1, get_asn1,\
-+        ctrl, \
-+        NULL \
-+}; \
-+const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }
-+
-+#define BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, \
-+                             iv_len, flags, init_key, cleanup, set_asn1, \
-+                             get_asn1, ctrl) \
-+BLOCK_CIPHER_def1(cname, cbc, cbc, CBC, kstruct, nid, block_size, key_len, \
-+                  iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
-+
-+#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \
-+                             iv_len, cbits, flags, init_key, cleanup, \
-+                             set_asn1, get_asn1, ctrl) \
-+BLOCK_CIPHER_def1(cname, cfb##cbits, cfb##cbits, CFB, kstruct, nid, 1, \
-+                  key_len, iv_len, flags, init_key, cleanup, set_asn1, \
-+                  get_asn1, ctrl)
-+
-+#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \
-+                             iv_len, cbits, flags, init_key, cleanup, \
-+                             set_asn1, get_asn1, ctrl) \
-+BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
-+                  key_len, iv_len, flags, init_key, cleanup, set_asn1, \
-+                  get_asn1, ctrl)
-+
-+#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
-+                             flags, init_key, cleanup, set_asn1, \
-+                             get_asn1, ctrl) \
-+BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
-+                  0, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
-+
-+#define BLOCK_CIPHER_defs(cname, kstruct, \
-+                          nid, block_size, key_len, iv_len, cbits, flags, \
-+                          init_key, cleanup, set_asn1, get_asn1, ctrl) \
-+BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
-+                     init_key, cleanup, set_asn1, get_asn1, ctrl) \
-+BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
-+                     flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
-+BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
-+                     flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
-+BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, flags, \
-+                     init_key, cleanup, set_asn1, get_asn1, ctrl)
-+
-+/*-
-+#define BLOCK_CIPHER_defs(cname, kstruct, \
-+                                nid, block_size, key_len, iv_len, flags,\
-+                                 init_key, cleanup, set_asn1, get_asn1, ctrl)\
-+static const EVP_CIPHER cname##_cbc = {\
-+        nid##_cbc, block_size, key_len, iv_len, \
-+        flags | EVP_CIPH_CBC_MODE,\
-+        init_key,\
-+        cname##_cbc_cipher,\
-+        cleanup,\
-+        sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
-+                sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
-+        set_asn1, get_asn1,\
-+        ctrl, \
-+        NULL \
-+};\
-+const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\
-+static const EVP_CIPHER cname##_cfb = {\
-+        nid##_cfb64, 1, key_len, iv_len, \
-+        flags | EVP_CIPH_CFB_MODE,\
-+        init_key,\
-+        cname##_cfb_cipher,\
-+        cleanup,\
-+        sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
-+                sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
-+        set_asn1, get_asn1,\
-+        ctrl,\
-+        NULL \
-+};\
-+const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\
-+static const EVP_CIPHER cname##_ofb = {\
-+        nid##_ofb64, 1, key_len, iv_len, \
-+        flags | EVP_CIPH_OFB_MODE,\
-+        init_key,\
-+        cname##_ofb_cipher,\
-+        cleanup,\
-+        sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
-+                sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
-+        set_asn1, get_asn1,\
-+        ctrl,\
-+        NULL \
-+};\
-+const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\
-+static const EVP_CIPHER cname##_ecb = {\
-+        nid##_ecb, block_size, key_len, iv_len, \
-+        flags | EVP_CIPH_ECB_MODE,\
-+        init_key,\
-+        cname##_ecb_cipher,\
-+        cleanup,\
-+        sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
-+                sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
-+        set_asn1, get_asn1,\
-+        ctrl,\
-+        NULL \
-+};\
-+const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
-+*/
-+
-+#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
-+                               block_size, key_len, iv_len, cbits, \
-+                               flags, init_key, \
-+                               cleanup, set_asn1, get_asn1, ctrl) \
-+        BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
-+        BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \
-+                          cbits, flags, init_key, cleanup, set_asn1, \
-+                          get_asn1, ctrl)
-+
-+#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len,fl) \
-+        BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
-+        BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
-+                             NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
-+                             (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \
-+                             cipher##_init_key, NULL, NULL, NULL, NULL)
-+
-+
-+/*
-+ * Type needs to be a bit field Sub-type needs to be for variations on the
-+ * method, as in, can it do arbitrary encryption....
-+ */
-+struct evp_pkey_st {
-+    int type;
-+    int save_type;
-+    int references;
-+    const EVP_PKEY_ASN1_METHOD *ameth;
-+    ENGINE *engine;
-+    union {
-+        void *ptr;
-+# ifndef OPENSSL_NO_RSA
-+        struct rsa_st *rsa;     /* RSA */
-+# endif
-+# ifndef OPENSSL_NO_DSA
-+        struct dsa_st *dsa;     /* DSA */
-+# endif
-+# ifndef OPENSSL_NO_DH
-+        struct dh_st *dh;       /* DH */
-+# endif
-+# ifndef OPENSSL_NO_EC
-+        struct ec_key_st *ec;   /* ECC */
-+# endif
-+    } pkey;
-+    int save_parameters;
-+    STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
-+    CRYPTO_RWLOCK *lock;
-+} /* EVP_PKEY */ ;
-+
-+
-+void openssl_add_all_ciphers_int(void);
-+void openssl_add_all_digests_int(void);
-+void evp_cleanup_int(void);
-+
-+/* Pulling defines out of C soure files */
-+
-+#define EVP_RC4_KEY_SIZE 16
-+#ifndef TLS1_1_VERSION
-+# define TLS1_1_VERSION   0x0302
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/md32_common.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/md32_common.h
-new file mode 100644
-index 0000000..6e4ce14
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/md32_common.h
-@@ -0,0 +1,383 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*-
-+ * This is a generic 32 bit "collector" for message digest algorithms.
-+ * Whenever needed it collects input character stream into chunks of
-+ * 32 bit values and invokes a block function that performs actual hash
-+ * calculations.
-+ *
-+ * Porting guide.
-+ *
-+ * Obligatory macros:
-+ *
-+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
-+ *      this macro defines byte order of input stream.
-+ * HASH_CBLOCK
-+ *      size of a unit chunk HASH_BLOCK operates on.
-+ * HASH_LONG
-+ *      has to be at lest 32 bit wide.
-+ * HASH_CTX
-+ *      context structure that at least contains following
-+ *      members:
-+ *              typedef struct {
-+ *                      ...
-+ *                      HASH_LONG       Nl,Nh;
-+ *                      either {
-+ *                      HASH_LONG       data[HASH_LBLOCK];
-+ *                      unsigned char   data[HASH_CBLOCK];
-+ *                      };
-+ *                      unsigned int    num;
-+ *                      ...
-+ *                      } HASH_CTX;
-+ *      data[] vector is expected to be zeroed upon first call to
-+ *      HASH_UPDATE.
-+ * HASH_UPDATE
-+ *      name of "Update" function, implemented here.
-+ * HASH_TRANSFORM
-+ *      name of "Transform" function, implemented here.
-+ * HASH_FINAL
-+ *      name of "Final" function, implemented here.
-+ * HASH_BLOCK_DATA_ORDER
-+ *      name of "block" function capable of treating *unaligned* input
-+ *      message in original (data) byte order, implemented externally.
-+ * HASH_MAKE_STRING
-+ *      macro convering context variables to an ASCII hash string.
-+ *
-+ * MD5 example:
-+ *
-+ *      #define DATA_ORDER_IS_LITTLE_ENDIAN
-+ *
-+ *      #define HASH_LONG               MD5_LONG
-+ *      #define HASH_CTX                MD5_CTX
-+ *      #define HASH_CBLOCK             MD5_CBLOCK
-+ *      #define HASH_UPDATE             MD5_Update
-+ *      #define HASH_TRANSFORM          MD5_Transform
-+ *      #define HASH_FINAL              MD5_Final
-+ *      #define HASH_BLOCK_DATA_ORDER   md5_block_data_order
-+ *
-+ *                                      
-+ */
-+
-+#include 
-+
-+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-+# error "DATA_ORDER must be defined!"
-+#endif
-+
-+#ifndef HASH_CBLOCK
-+# error "HASH_CBLOCK must be defined!"
-+#endif
-+#ifndef HASH_LONG
-+# error "HASH_LONG must be defined!"
-+#endif
-+#ifndef HASH_CTX
-+# error "HASH_CTX must be defined!"
-+#endif
-+
-+#ifndef HASH_UPDATE
-+# error "HASH_UPDATE must be defined!"
-+#endif
-+#ifndef HASH_TRANSFORM
-+# error "HASH_TRANSFORM must be defined!"
-+#endif
-+#ifndef HASH_FINAL
-+# error "HASH_FINAL must be defined!"
-+#endif
-+
-+#ifndef HASH_BLOCK_DATA_ORDER
-+# error "HASH_BLOCK_DATA_ORDER must be defined!"
-+#endif
-+
-+/*
-+ * Engage compiler specific rotate intrinsic function if available.
-+ */
-+#undef ROTATE
-+#ifndef PEDANTIC
-+# if defined(_MSC_VER)
-+#  define ROTATE(a,n)   _lrotl(a,n)
-+# elif defined(__ICC)
-+#  define ROTATE(a,n)   _rotl(a,n)
-+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
-+  /*
-+   * Some GNU C inline assembler templates. Note that these are
-+   * rotates by *constant* number of bits! But that's exactly
-+   * what we need here...
-+   *                                    
-+   */
-+#  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
-+#   define ROTATE(a,n)  ({ register unsigned int ret;   \
-+                                asm (                   \
-+                                "roll %1,%0"            \
-+                                : "=r"(ret)             \
-+                                : "I"(n), "0"((unsigned int)(a))        \
-+                                : "cc");                \
-+                           ret;                         \
-+                        })
-+#  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
-+        defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
-+#   define ROTATE(a,n)  ({ register unsigned int ret;   \
-+                                asm (                   \
-+                                "rlwinm %0,%1,%2,0,31"  \
-+                                : "=r"(ret)             \
-+                                : "r"(a), "I"(n));      \
-+                           ret;                         \
-+                        })
-+#  elif defined(__s390x__)
-+#   define ROTATE(a,n) ({ register unsigned int ret;    \
-+                                asm ("rll %0,%1,%2"     \
-+                                : "=r"(ret)             \
-+                                : "r"(a), "I"(n));      \
-+                          ret;                          \
-+                        })
-+#  endif
-+# endif
-+#endif                          /* PEDANTIC */
-+
-+#ifndef ROTATE
-+# define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
-+#endif
-+
-+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
-+
-+# ifndef PEDANTIC
-+#  if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
-+#   if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
-+      (defined(__x86_64) || defined(__x86_64__))
-+#    if !defined(B_ENDIAN)
-+    /*
-+     * This gives ~30-40% performance improvement in SHA-256 compiled
-+     * with gcc [on P4]. Well, first macro to be frank. We can pull
-+     * this trick on x86* platforms only, because these CPUs can fetch
-+     * unaligned data without raising an exception.
-+     */
-+#     define HOST_c2l(c,l)        ({ unsigned int r=*((const unsigned int *)(c)); \
-+                                   asm ("bswapl %0":"=r"(r):"0"(r));    \
-+                                   (c)+=4; (l)=r;                       })
-+#     define HOST_l2c(l,c)        ({ unsigned int r=(l);                  \
-+                                   asm ("bswapl %0":"=r"(r):"0"(r));    \
-+                                   *((unsigned int *)(c))=r; (c)+=4; r; })
-+#    endif
-+#   elif defined(__aarch64__)
-+#    if defined(__BYTE_ORDER__)
-+#     if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
-+#      define HOST_c2l(c,l)      ({ unsigned int r;              \
-+                                   asm ("rev    %w0,%w1"        \
-+                                        :"=r"(r)                \
-+                                        :"r"(*((const unsigned int *)(c))));\
-+                                   (c)+=4; (l)=r;               })
-+#      define HOST_l2c(l,c)      ({ unsigned int r;              \
-+                                   asm ("rev    %w0,%w1"        \
-+                                        :"=r"(r)                \
-+                                        :"r"((unsigned int)(l)));\
-+                                   *((unsigned int *)(c))=r; (c)+=4; r; })
-+#     elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
-+#      define HOST_c2l(c,l)      ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
-+#      define HOST_l2c(l,c)      (*((unsigned int *)(c))=(l), (c)+=4, (l))
-+#     endif
-+#    endif
-+#   endif
-+#  endif
-+#  if defined(__s390__) || defined(__s390x__)
-+#   define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
-+#   define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
-+#  endif
-+# endif
-+
-+# ifndef HOST_c2l
-+#  define HOST_c2l(c,l)   (l =(((unsigned long)(*((c)++)))<<24),          \
-+                         l|=(((unsigned long)(*((c)++)))<<16),          \
-+                         l|=(((unsigned long)(*((c)++)))<< 8),          \
-+                         l|=(((unsigned long)(*((c)++)))    )           )
-+# endif
-+# ifndef HOST_l2c
-+#  define HOST_l2c(l,c)   (*((c)++)=(unsigned char)(((l)>>24)&0xff),      \
-+                         *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
-+                         *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
-+                         *((c)++)=(unsigned char)(((l)    )&0xff),      \
-+                         l)
-+# endif
-+
-+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-+
-+# ifndef PEDANTIC
-+#  if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
-+#   if defined(__s390x__)
-+#    define HOST_c2l(c,l)        ({ asm ("lrv    %0,%1"                  \
-+                                   :"=d"(l) :"m"(*(const unsigned int *)(c)));\
-+                                   (c)+=4; (l);                         })
-+#    define HOST_l2c(l,c)        ({ asm ("strv   %1,%0"                  \
-+                                   :"=m"(*(unsigned int *)(c)) :"d"(l));\
-+                                   (c)+=4; (l);                         })
-+#   endif
-+#  endif
-+#  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
-+#   ifndef B_ENDIAN
-+    /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
-+#    define HOST_c2l(c,l)        ((l)=*((const unsigned int *)(c)), (c)+=4, l)
-+#    define HOST_l2c(l,c)        (*((unsigned int *)(c))=(l), (c)+=4, l)
-+#   endif
-+#  endif
-+# endif
-+
-+# ifndef HOST_c2l
-+#  define HOST_c2l(c,l)   (l =(((unsigned long)(*((c)++)))    ),          \
-+                         l|=(((unsigned long)(*((c)++)))<< 8),          \
-+                         l|=(((unsigned long)(*((c)++)))<<16),          \
-+                         l|=(((unsigned long)(*((c)++)))<<24)           )
-+# endif
-+# ifndef HOST_l2c
-+#  define HOST_l2c(l,c)   (*((c)++)=(unsigned char)(((l)    )&0xff),      \
-+                         *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
-+                         *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
-+                         *((c)++)=(unsigned char)(((l)>>24)&0xff),      \
-+                         l)
-+# endif
-+
-+#endif
-+
-+/*
-+ * Time for some action:-)
-+ */
-+
-+int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
-+{
-+    const unsigned char *data = data_;
-+    unsigned char *p;
-+    HASH_LONG l;
-+    size_t n;
-+
-+    if (len == 0)
-+        return 1;
-+
-+    l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
-+    /*
-+     * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai
-+     *  for pointing it out.
-+     */
-+    if (l < c->Nl)              /* overflow */
-+        c->Nh++;
-+    c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
-+                                       * 16-bit */
-+    c->Nl = l;
-+
-+    n = c->num;
-+    if (n != 0) {
-+        p = (unsigned char *)c->data;
-+
-+        if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
-+            memcpy(p + n, data, HASH_CBLOCK - n);
-+            HASH_BLOCK_DATA_ORDER(c, p, 1);
-+            n = HASH_CBLOCK - n;
-+            data += n;
-+            len -= n;
-+            c->num = 0;
-+            /*
-+             * We use memset rather than OPENSSL_cleanse() here deliberately.
-+             * Using OPENSSL_cleanse() here could be a performance issue. It
-+             * will get properly cleansed on finalisation so this isn't a
-+             * security problem.
-+             */
-+            memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
-+        } else {
-+            memcpy(p + n, data, len);
-+            c->num += (unsigned int)len;
-+            return 1;
-+        }
-+    }
-+
-+    n = len / HASH_CBLOCK;
-+    if (n > 0) {
-+        HASH_BLOCK_DATA_ORDER(c, data, n);
-+        n *= HASH_CBLOCK;
-+        data += n;
-+        len -= n;
-+    }
-+
-+    if (len != 0) {
-+        p = (unsigned char *)c->data;
-+        c->num = (unsigned int)len;
-+        memcpy(p, data, len);
-+    }
-+    return 1;
-+}
-+
-+void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
-+{
-+    HASH_BLOCK_DATA_ORDER(c, data, 1);
-+}
-+
-+int HASH_FINAL(unsigned char *md, HASH_CTX *c)
-+{
-+    unsigned char *p = (unsigned char *)c->data;
-+    size_t n = c->num;
-+
-+    p[n] = 0x80;                /* there is always room for one */
-+    n++;
-+
-+    if (n > (HASH_CBLOCK - 8)) {
-+        memset(p + n, 0, HASH_CBLOCK - n);
-+        n = 0;
-+        HASH_BLOCK_DATA_ORDER(c, p, 1);
-+    }
-+    memset(p + n, 0, HASH_CBLOCK - 8 - n);
-+
-+    p += HASH_CBLOCK - 8;
-+#if   defined(DATA_ORDER_IS_BIG_ENDIAN)
-+    (void)HOST_l2c(c->Nh, p);
-+    (void)HOST_l2c(c->Nl, p);
-+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-+    (void)HOST_l2c(c->Nl, p);
-+    (void)HOST_l2c(c->Nh, p);
-+#endif
-+    p -= HASH_CBLOCK;
-+    HASH_BLOCK_DATA_ORDER(c, p, 1);
-+    c->num = 0;
-+    OPENSSL_cleanse(p, HASH_CBLOCK);
-+
-+#ifndef HASH_MAKE_STRING
-+# error "HASH_MAKE_STRING must be defined!"
-+#else
-+    HASH_MAKE_STRING(c, md);
-+#endif
-+
-+    return 1;
-+}
-+
-+#ifndef MD32_REG_T
-+# if defined(__alpha) || defined(__sparcv9) || defined(__mips)
-+#  define MD32_REG_T long
-+/*
-+ * This comment was originally written for MD5, which is why it
-+ * discusses A-D. But it basically applies to all 32-bit digests,
-+ * which is why it was moved to common header file.
-+ *
-+ * In case you wonder why A-D are declared as long and not
-+ * as MD5_LONG. Doing so results in slight performance
-+ * boost on LP64 architectures. The catch is we don't
-+ * really care if 32 MSBs of a 64-bit register get polluted
-+ * with eventual overflows as we *save* only 32 LSBs in
-+ * *either* case. Now declaring 'em long excuses the compiler
-+ * from keeping 32 MSBs zeroed resulting in 13% performance
-+ * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
-+ * Well, to be honest it should say that this *prevents*
-+ * performance degradation.
-+ *                              
-+ */
-+# else
-+/*
-+ * Above is not absolute and there are LP64 compilers that
-+ * generate better code if MD32_REG_T is defined int. The above
-+ * pre-processor condition reflects the circumstances under which
-+ * the conclusion was made and is subject to further extension.
-+ *                              
-+ */
-+#  define MD32_REG_T int
-+# endif
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/objects.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/objects.h
-new file mode 100644
-index 0000000..76e1b4d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/objects.h
-@@ -0,0 +1,12 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+void obj_cleanup_int(void);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/poly1305.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/poly1305.h
-new file mode 100644
-index 0000000..1bc8716
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/poly1305.h
-@@ -0,0 +1,19 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#define POLY1305_BLOCK_SIZE 16
-+
-+typedef struct poly1305_context POLY1305;
-+
-+size_t Poly1305_ctx_size(void);
-+void Poly1305_Init(POLY1305 *ctx, const unsigned char key[32]);
-+void Poly1305_Update(POLY1305 *ctx, const unsigned char *inp, size_t len);
-+void Poly1305_Final(POLY1305 *ctx, unsigned char mac[16]);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/rand.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/rand.h
-new file mode 100644
-index 0000000..30887c4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/rand.h
-@@ -0,0 +1,20 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Licensed under the OpenSSL licenses, (the "License");
-+ * you may not use this file except in compliance with the License.
-+ * You may obtain a copy of the License at
-+ * https://www.openssl.org/source/license.html
-+ * or in the file LICENSE in the source distribution.
-+ */
-+
-+#include 
-+
-+void rand_cleanup_int(void);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/x509_int.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/x509_int.h
-new file mode 100644
-index 0000000..2845026
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/include/internal/x509_int.h
-@@ -0,0 +1,267 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Internal X509 structures and functions: not for application use */
-+
-+/* Note: unless otherwise stated a field pointer is mandatory and should
-+ * never be set to NULL: the ASN.1 code and accessors rely on mandatory
-+ * fields never being NULL.
-+ */
-+
-+/*
-+ * name entry structure, equivalent to AttributeTypeAndValue defined
-+ * in RFC5280 et al.
-+ */
-+struct X509_name_entry_st {
-+    ASN1_OBJECT *object;        /* AttributeType */
-+    ASN1_STRING *value;         /* AttributeValue */
-+    int set;                    /* index of RDNSequence for this entry */
-+    int size;                   /* temp variable */
-+};
-+
-+/* Name from RFC 5280. */
-+struct X509_name_st {
-+    STACK_OF(X509_NAME_ENTRY) *entries; /* DN components */
-+    int modified;               /* true if 'bytes' needs to be built */
-+    BUF_MEM *bytes;             /* cached encoding: cannot be NULL */
-+    /* canonical encoding used for rapid Name comparison */
-+    unsigned char *canon_enc;
-+    int canon_enclen;
-+} /* X509_NAME */ ;
-+
-+/* PKCS#10 certificate request */
-+
-+struct X509_req_info_st {
-+    ASN1_ENCODING enc;          /* cached encoding of signed part */
-+    ASN1_INTEGER *version;      /* version, defaults to v1(0) so can be NULL */
-+    X509_NAME *subject;         /* certificate request DN */
-+    X509_PUBKEY *pubkey;        /* public key of request */
-+    /*
-+     * Zero or more attributes.
-+     * NB: although attributes is a mandatory field some broken
-+     * encodings omit it so this may be NULL in that case.
-+     */
-+    STACK_OF(X509_ATTRIBUTE) *attributes;
-+};
-+
-+struct X509_req_st {
-+    X509_REQ_INFO req_info;     /* signed certificate request data */
-+    X509_ALGOR sig_alg;         /* signature algorithm */
-+    ASN1_BIT_STRING *signature; /* signature */
-+    int references;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+struct X509_crl_info_st {
-+    ASN1_INTEGER *version;      /* version: defaults to v1(0) so may be NULL */
-+    X509_ALGOR sig_alg;         /* signature algorithm */
-+    X509_NAME *issuer;          /* CRL issuer name */
-+    ASN1_TIME *lastUpdate;      /* lastUpdate field */
-+    ASN1_TIME *nextUpdate;      /* nextUpdate field: optional */
-+    STACK_OF(X509_REVOKED) *revoked;        /* revoked entries: optional */
-+    STACK_OF(X509_EXTENSION) *extensions;   /* extensions: optional */
-+    ASN1_ENCODING enc;                      /* encoding of signed portion of CRL */
-+};
-+
-+struct X509_crl_st {
-+    X509_CRL_INFO crl;          /* signed CRL data */
-+    X509_ALGOR sig_alg;         /* CRL signature algorithm */
-+    ASN1_BIT_STRING signature;  /* CRL signature */
-+    int references;
-+    int flags;
-+    /*
-+     * Cached copies of decoded extension values, since extensions
-+     * are optional any of these can be NULL.
-+     */
-+    AUTHORITY_KEYID *akid;
-+    ISSUING_DIST_POINT *idp;
-+    /* Convenient breakdown of IDP */
-+    int idp_flags;
-+    int idp_reasons;
-+    /* CRL and base CRL numbers for delta processing */
-+    ASN1_INTEGER *crl_number;
-+    ASN1_INTEGER *base_crl_number;
-+    STACK_OF(GENERAL_NAMES) *issuers;
-+    /* hash of CRL */
-+    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
-+    /* alternative method to handle this CRL */
-+    const X509_CRL_METHOD *meth;
-+    void *meth_data;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+struct x509_revoked_st {
-+    ASN1_INTEGER serialNumber; /* revoked entry serial number */
-+    ASN1_TIME *revocationDate;  /* revocation date */
-+    STACK_OF(X509_EXTENSION) *extensions;   /* CRL entry extensions: optional */
-+    /* decoded value of CRLissuer extension: set if indirect CRL */
-+    STACK_OF(GENERAL_NAME) *issuer;
-+    /* revocation reason: set to CRL_REASON_NONE if reason extension absent */
-+    int reason;
-+    /*
-+     * CRL entries are reordered for faster lookup of serial numbers. This
-+     * field contains the original load sequence for this entry.
-+     */
-+    int sequence;
-+};
-+
-+/*
-+ * This stuff is certificate "auxiliary info": it contains details which are
-+ * useful in certificate stores and databases. When used this is tagged onto
-+ * the end of the certificate itself. OpenSSL specific structure not defined
-+ * in any RFC.
-+ */
-+
-+struct x509_cert_aux_st {
-+    STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
-+    STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
-+    ASN1_UTF8STRING *alias;     /* "friendly name" */
-+    ASN1_OCTET_STRING *keyid;   /* key id of private key */
-+    STACK_OF(X509_ALGOR) *other; /* other unspecified info */
-+};
-+
-+struct x509_cinf_st {
-+    ASN1_INTEGER *version;      /* [ 0 ] default of v1 */
-+    ASN1_INTEGER serialNumber;
-+    X509_ALGOR signature;
-+    X509_NAME *issuer;
-+    X509_VAL validity;
-+    X509_NAME *subject;
-+    X509_PUBKEY *key;
-+    ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
-+    ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
-+    STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
-+    ASN1_ENCODING enc;
-+};
-+
-+struct x509_st {
-+    X509_CINF cert_info;
-+    X509_ALGOR sig_alg;
-+    ASN1_BIT_STRING signature;
-+    int references;
-+    CRYPTO_EX_DATA ex_data;
-+    /* These contain copies of various extension values */
-+    long ex_pathlen;
-+    long ex_pcpathlen;
-+    uint32_t ex_flags;
-+    uint32_t ex_kusage;
-+    uint32_t ex_xkusage;
-+    uint32_t ex_nscert;
-+    ASN1_OCTET_STRING *skid;
-+    AUTHORITY_KEYID *akid;
-+    X509_POLICY_CACHE *policy_cache;
-+    STACK_OF(DIST_POINT) *crldp;
-+    STACK_OF(GENERAL_NAME) *altname;
-+    NAME_CONSTRAINTS *nc;
-+#ifndef OPENSSL_NO_RFC3779
-+    STACK_OF(IPAddressFamily) *rfc3779_addr;
-+    struct ASIdentifiers_st *rfc3779_asid;
-+# endif
-+    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
-+    X509_CERT_AUX *aux;
-+    CRYPTO_RWLOCK *lock;
-+} /* X509 */ ;
-+
-+/*
-+ * This is a used when verifying cert chains.  Since the gathering of the
-+ * cert chain can take some time (and have to be 'retried', this needs to be
-+ * kept and passed around.
-+ */
-+struct x509_store_ctx_st {      /* X509_STORE_CTX */
-+    X509_STORE *ctx;
-+    /* The following are set by the caller */
-+    /* The cert to check */
-+    X509 *cert;
-+    /* chain of X509s - untrusted - passed in */
-+    STACK_OF(X509) *untrusted;
-+    /* set of CRLs passed in */
-+    STACK_OF(X509_CRL) *crls;
-+    X509_VERIFY_PARAM *param;
-+    /* Other info for use with get_issuer() */
-+    void *other_ctx;
-+    /* Callbacks for various operations */
-+    /* called to verify a certificate */
-+    int (*verify) (X509_STORE_CTX *ctx);
-+    /* error callback */
-+    int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
-+    /* get issuers cert from ctx */
-+    int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
-+    /* check issued */
-+    int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
-+    /* Check revocation status of chain */
-+    int (*check_revocation) (X509_STORE_CTX *ctx);
-+    /* retrieve CRL */
-+    int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
-+    /* Check CRL validity */
-+    int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
-+    /* Check certificate against CRL */
-+    int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
-+    /* Check policy status of the chain */
-+    int (*check_policy) (X509_STORE_CTX *ctx);
-+    STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
-+    STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
-+    int (*cleanup) (X509_STORE_CTX *ctx);
-+    /* The following is built up */
-+    /* if 0, rebuild chain */
-+    int valid;
-+    /* number of untrusted certs */
-+    int num_untrusted;
-+    /* chain of X509s - built up and trusted */
-+    STACK_OF(X509) *chain;
-+    /* Valid policy tree */
-+    X509_POLICY_TREE *tree;
-+    /* Require explicit policy value */
-+    int explicit_policy;
-+    /* When something goes wrong, this is why */
-+    int error_depth;
-+    int error;
-+    X509 *current_cert;
-+    /* cert currently being tested as valid issuer */
-+    X509 *current_issuer;
-+    /* current CRL */
-+    X509_CRL *current_crl;
-+    /* score of current CRL */
-+    int current_crl_score;
-+    /* Reason mask */
-+    unsigned int current_reasons;
-+    /* For CRL path validation: parent context */
-+    X509_STORE_CTX *parent;
-+    CRYPTO_EX_DATA ex_data;
-+    SSL_DANE *dane;
-+    /* signed via bare TA public key, rather than CA certificate */
-+    int bare_ta_signed;
-+};
-+
-+/* PKCS#8 private key info structure */
-+
-+struct pkcs8_priv_key_info_st {
-+    ASN1_INTEGER *version;
-+    X509_ALGOR *pkeyalg;
-+    ASN1_OCTET_STRING *pkey;
-+    STACK_OF(X509_ATTRIBUTE) *attributes;
-+};
-+
-+struct X509_sig_st {
-+    X509_ALGOR *algor;
-+    ASN1_OCTET_STRING *digest;
-+};
-+
-+struct x509_object_st {
-+    /* one of the above types */
-+    X509_LOOKUP_TYPE type;
-+    union {
-+        char *ptr;
-+        X509 *x509;
-+        X509_CRL *crl;
-+        EVP_PKEY *pkey;
-+    } data;
-+};
-+
-+int a2i_ipadd(unsigned char *ipout, const char *ipasc);
-+int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/init.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/init.c
-new file mode 100644
-index 0000000..c730e38
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/init.c
-@@ -0,0 +1,664 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+static int stopped = 0;
-+
-+static void ossl_init_thread_stop(struct thread_local_inits_st *locals);
-+
-+static CRYPTO_THREAD_LOCAL threadstopkey;
-+
-+static void ossl_init_thread_stop_wrap(void *local)
-+{
-+    ossl_init_thread_stop((struct thread_local_inits_st *)local);
-+}
-+
-+static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
-+{
-+    struct thread_local_inits_st *local =
-+        CRYPTO_THREAD_get_local(&threadstopkey);
-+
-+    if (local == NULL && alloc) {
-+        local = OPENSSL_zalloc(sizeof *local);
-+        CRYPTO_THREAD_set_local(&threadstopkey, local);
-+    }
-+    if (!alloc) {
-+        CRYPTO_THREAD_set_local(&threadstopkey, NULL);
-+    }
-+
-+    return local;
-+}
-+
-+typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
-+struct ossl_init_stop_st {
-+    void (*handler)(void);
-+    OPENSSL_INIT_STOP *next;
-+};
-+
-+static OPENSSL_INIT_STOP *stop_handlers = NULL;
-+static CRYPTO_RWLOCK *init_lock = NULL;
-+
-+static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
-+static int base_inited = 0;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_base)
-+{
-+#ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
-+#endif
-+    /*
-+     * We use a dummy thread local key here. We use the destructor to detect
-+     * when the thread is going to stop (where that feature is available)
-+     */
-+    CRYPTO_THREAD_init_local(&threadstopkey, ossl_init_thread_stop_wrap);
-+#ifndef OPENSSL_SYS_UEFI
-+    atexit(OPENSSL_cleanup);
-+#endif
-+    if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
-+        return 0;
-+    OPENSSL_cpuid_setup();
-+
-+    /*
-+     * BIG FAT WARNING!
-+     * Everything needed to be initialized in this function before threads
-+     * come along MUST happen before base_inited is set to 1, or we will
-+     * see race conditions.
-+     */
-+    base_inited = 1;
-+
-+#if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
-+# ifdef DSO_WIN32
-+    {
-+        HMODULE handle = NULL;
-+        BOOL ret;
-+
-+        /* We don't use the DSO route for WIN32 because there is a better way */
-+        ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
-+                                | GET_MODULE_HANDLE_EX_FLAG_PIN,
-+                                (void *)&base_inited, &handle);
-+
-+        return (ret == TRUE) ? 1 : 0;
-+    }
-+# else
-+    /*
-+     * Deliberately leak a reference to ourselves. This will force the library
-+     * to remain loaded until the atexit() handler is run a process exit.
-+     */
-+    {
-+        DSO *dso = NULL;
-+
-+        dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
-+        DSO_free(dso);
-+    }
-+# endif
-+#endif
-+
-+    return 1;
-+}
-+
-+static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
-+static int load_crypto_strings_inited = 0;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_no_load_crypto_strings)
-+{
-+    /* Do nothing in this case */
-+    return 1;
-+}
-+
-+DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
-+{
-+    int ret = 1;
-+    /*
-+     * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
-+     * pulling in all the error strings during static linking
-+     */
-+#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
-+# ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: "
-+                    "err_load_crypto_strings_int()\n");
-+# endif
-+    ret = err_load_crypto_strings_int();
-+    load_crypto_strings_inited = 1;
-+#endif    
-+    return ret;
-+}
-+
-+static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
-+{
-+    /*
-+     * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
-+     * pulling in all the ciphers during static linking
-+     */
-+#ifndef OPENSSL_NO_AUTOALGINIT
-+# ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: "
-+                    "openssl_add_all_ciphers_int()\n");
-+# endif
-+    openssl_add_all_ciphers_int();
-+#endif
-+    return 1;
-+}
-+
-+static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
-+{
-+    /*
-+     * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
-+     * pulling in all the ciphers during static linking
-+     */
-+#ifndef OPENSSL_NO_AUTOALGINIT
-+# ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: "
-+                    "openssl_add_all_digests()\n");
-+# endif
-+    openssl_add_all_digests_int();
-+#endif
-+    return 1;
-+}
-+
-+DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs)
-+{
-+    /* Do nothing */
-+    return 1;
-+}
-+
-+static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
-+static int config_inited = 0;
-+static const char *appname;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_config)
-+{
-+#ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr,
-+            "OPENSSL_INIT: ossl_init_config: openssl_config(%s)\n",
-+            appname == NULL ? "NULL" : appname);
-+#endif
-+    openssl_config_int(appname);
-+    config_inited = 1;
-+    return 1;
-+}
-+DEFINE_RUN_ONCE_STATIC(ossl_init_no_config)
-+{
-+#ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr,
-+            "OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n");
-+#endif
-+    openssl_no_config_int();
-+    config_inited = 1;
-+    return 1;
-+}
-+
-+static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
-+static int async_inited = 0;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_async)
-+{
-+#ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n");
-+#endif
-+    if (!async_init())
-+        return 0;
-+    async_inited = 1;
-+    return 1;
-+}
-+
-+#ifndef OPENSSL_NO_ENGINE
-+static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
-+{
-+# ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: "
-+                    "engine_load_openssl_int()\n");
-+# endif
-+    engine_load_openssl_int();
-+    return 1;
-+}
-+# if !defined(OPENSSL_NO_HW) && \
-+    (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
-+static CRYPTO_ONCE engine_cryptodev = CRYPTO_ONCE_STATIC_INIT;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_cryptodev)
-+{
-+#  ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_cryptodev: "
-+                    "engine_load_cryptodev_int()\n");
-+#  endif
-+    engine_load_cryptodev_int();
-+    return 1;
-+}
-+# endif
-+
-+# ifndef OPENSSL_NO_RDRAND
-+static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand)
-+{
-+#  ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: "
-+                    "engine_load_rdrand_int()\n");
-+#  endif
-+    engine_load_rdrand_int();
-+    return 1;
-+}
-+# endif
-+static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
-+{
-+# ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: "
-+                    "engine_load_dynamic_int()\n");
-+# endif
-+    engine_load_dynamic_int();
-+    return 1;
-+}
-+# ifndef OPENSSL_NO_STATIC_ENGINE
-+#  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
-+static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
-+{
-+#   ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: "
-+                    "engine_load_padlock_int()\n");
-+#   endif
-+    engine_load_padlock_int();
-+    return 1;
-+}
-+#  endif
-+#  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
-+static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi)
-+{
-+#   ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: "
-+                    "engine_load_capi_int()\n");
-+#   endif
-+    engine_load_capi_int();
-+    return 1;
-+}
-+#  endif
-+#  if !defined(OPENSSL_NO_AFALGENG)
-+static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)
-+{
-+#   ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: "
-+                    "engine_load_afalg_int()\n");
-+#   endif
-+    engine_load_afalg_int();
-+    return 1;
-+}
-+#  endif
-+# endif
-+#endif
-+
-+#ifndef OPENSSL_NO_COMP
-+static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT;
-+
-+static int zlib_inited = 0;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_zlib)
-+{
-+    /* Do nothing - we need to know about this for the later cleanup */
-+    zlib_inited = 1;
-+    return 1;
-+}
-+#endif
-+
-+static void ossl_init_thread_stop(struct thread_local_inits_st *locals)
-+{
-+    /* Can't do much about this */
-+    if (locals == NULL)
-+        return;
-+
-+    if (locals->async) {
-+#ifdef OPENSSL_INIT_DEBUG
-+        fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
-+                        "ASYNC_cleanup_thread()\n");
-+#endif
-+        ASYNC_cleanup_thread();
-+    }
-+
-+    if (locals->err_state) {
-+#ifdef OPENSSL_INIT_DEBUG
-+        fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
-+                        "err_delete_thread_state()\n");
-+#endif
-+        err_delete_thread_state();
-+    }
-+
-+    OPENSSL_free(locals);
-+}
-+
-+void OPENSSL_thread_stop(void)
-+{
-+    ossl_init_thread_stop(
-+        (struct thread_local_inits_st *)ossl_init_get_thread_local(0));
-+}
-+
-+int ossl_init_thread_start(uint64_t opts)
-+{
-+    struct thread_local_inits_st *locals = ossl_init_get_thread_local(1);
-+
-+    if (locals == NULL)
-+        return 0;
-+
-+    if (opts & OPENSSL_INIT_THREAD_ASYNC) {
-+#ifdef OPENSSL_INIT_DEBUG
-+        fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
-+                        "marking thread for async\n");
-+#endif
-+        locals->async = 1;
-+    }
-+
-+    if (opts & OPENSSL_INIT_THREAD_ERR_STATE) {
-+#ifdef OPENSSL_INIT_DEBUG
-+        fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
-+                        "marking thread for err_state\n");
-+#endif
-+        locals->err_state = 1;
-+    }
-+
-+    return 1;
-+}
-+
-+void OPENSSL_cleanup(void)
-+{
-+    OPENSSL_INIT_STOP *currhandler, *lasthandler;
-+
-+    /* If we've not been inited then no need to deinit */
-+    if (!base_inited)
-+        return;
-+
-+    /* Might be explicitly called and also by atexit */
-+    if (stopped)
-+        return;
-+    stopped = 1;
-+
-+    /*
-+     * Thread stop may not get automatically called by the thread library for
-+     * the very last thread in some situations, so call it directly.
-+     */
-+    ossl_init_thread_stop(ossl_init_get_thread_local(0));
-+
-+    currhandler = stop_handlers;
-+    while (currhandler != NULL) {
-+        currhandler->handler();
-+        lasthandler = currhandler;
-+        currhandler = currhandler->next;
-+        OPENSSL_free(lasthandler);
-+    }
-+    stop_handlers = NULL;
-+
-+    CRYPTO_THREAD_lock_free(init_lock);
-+
-+    /*
-+     * We assume we are single-threaded for this function, i.e. no race
-+     * conditions for the various "*_inited" vars below.
-+     */
-+
-+#ifndef OPENSSL_NO_COMP
-+    if (zlib_inited) {
-+#ifdef OPENSSL_INIT_DEBUG
-+        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                        "comp_zlib_cleanup_int()\n");
-+#endif
-+        comp_zlib_cleanup_int();
-+    }
-+#endif
-+
-+    if (async_inited) {
-+# ifdef OPENSSL_INIT_DEBUG
-+        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                        "async_deinit()\n");
-+# endif
-+        async_deinit();
-+    }
-+
-+    if (load_crypto_strings_inited) {
-+#ifdef OPENSSL_INIT_DEBUG
-+        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                        "err_free_strings_int()\n");
-+#endif
-+        err_free_strings_int();
-+    }
-+
-+    CRYPTO_THREAD_cleanup_local(&threadstopkey);
-+
-+#ifdef OPENSSL_INIT_DEBUG
-+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                    "rand_cleanup_int()\n");
-+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                    "conf_modules_free_int()\n");
-+#ifndef OPENSSL_NO_ENGINE
-+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                    "engine_cleanup_int()\n");
-+#endif
-+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                    "crypto_cleanup_all_ex_data_int()\n");
-+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                    "bio_sock_cleanup_int()\n");
-+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                    "bio_cleanup()\n");
-+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                    "evp_cleanup_int()\n");
-+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                    "obj_cleanup_int()\n");
-+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
-+                    "err_cleanup()\n");
-+#endif
-+    /*
-+     * Note that cleanup order is important:
-+     * - rand_cleanup_int could call an ENGINE's RAND cleanup function so
-+     * must be called before engine_cleanup_int()
-+     * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
-+     * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
-+     * - conf_modules_free_int() can end up in ENGINE code so must be called
-+     * before engine_cleanup_int()
-+     * - ENGINEs and additional EVP algorithms might use added OIDs names so
-+     * obj_cleanup_int() must be called last
-+     */
-+    rand_cleanup_int();
-+    conf_modules_free_int();
-+#ifndef OPENSSL_NO_ENGINE
-+    engine_cleanup_int();
-+#endif
-+    crypto_cleanup_all_ex_data_int();
-+    bio_cleanup();
-+    evp_cleanup_int();
-+    obj_cleanup_int();
-+    err_cleanup();
-+
-+    base_inited = 0;
-+}
-+
-+/*
-+ * If this function is called with a non NULL settings value then it must be
-+ * called prior to any threads making calls to any OpenSSL functions,
-+ * i.e. passing a non-null settings value is assumed to be single-threaded.
-+ */
-+int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
-+{
-+    static int stoperrset = 0;
-+
-+    if (stopped) {
-+        if (!stoperrset) {
-+            /*
-+             * We only ever set this once to avoid getting into an infinite
-+             * loop where the error system keeps trying to init and fails so
-+             * sets an error etc
-+             */
-+            stoperrset = 1;
-+            CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
-+        }
-+        return 0;
-+    }
-+
-+    if (!base_inited && !RUN_ONCE(&base, ossl_init_base))
-+        return 0;
-+
-+    if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
-+            && !RUN_ONCE(&load_crypto_strings,
-+                         ossl_init_no_load_crypto_strings))
-+        return 0;
-+
-+    if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
-+            && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
-+        return 0;
-+
-+    if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
-+            && !RUN_ONCE(&add_all_ciphers, ossl_init_no_add_algs))
-+        return 0;
-+
-+    if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
-+            && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
-+        return 0;
-+
-+    if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
-+            && !RUN_ONCE(&add_all_digests, ossl_init_no_add_algs))
-+        return 0;
-+
-+    if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
-+            && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
-+        return 0;
-+
-+    if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
-+            && !RUN_ONCE(&config, ossl_init_no_config))
-+        return 0;
-+
-+    if (opts & OPENSSL_INIT_LOAD_CONFIG) {
-+        int ret;
-+        CRYPTO_THREAD_write_lock(init_lock);
-+        appname = (settings == NULL) ? NULL : settings->appname;
-+        ret = RUN_ONCE(&config, ossl_init_config);
-+        CRYPTO_THREAD_unlock(init_lock);
-+        if (!ret)
-+            return 0;
-+    }
-+
-+    if ((opts & OPENSSL_INIT_ASYNC)
-+            && !RUN_ONCE(&async, ossl_init_async))
-+        return 0;
-+
-+#ifndef OPENSSL_NO_ENGINE
-+    if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
-+            && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
-+        return 0;
-+# if !defined(OPENSSL_NO_HW) && \
-+    (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
-+    if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
-+            && !RUN_ONCE(&engine_cryptodev, ossl_init_engine_cryptodev))
-+        return 0;
-+# endif
-+# ifndef OPENSSL_NO_RDRAND
-+    if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
-+            && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
-+        return 0;
-+# endif
-+    if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
-+            && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
-+        return 0;
-+# ifndef OPENSSL_NO_STATIC_ENGINE
-+#  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
-+    if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
-+            && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
-+        return 0;
-+#  endif
-+#  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
-+    if ((opts & OPENSSL_INIT_ENGINE_CAPI)
-+            && !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
-+        return 0;
-+#  endif
-+#  if !defined(OPENSSL_NO_AFALGENG)
-+    if ((opts & OPENSSL_INIT_ENGINE_AFALG)
-+            && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
-+        return 0;
-+#  endif
-+# endif
-+    if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
-+                | OPENSSL_INIT_ENGINE_OPENSSL
-+                | OPENSSL_INIT_ENGINE_AFALG)) {
-+        ENGINE_register_all_complete();
-+    }
-+#endif
-+
-+#ifndef OPENSSL_NO_COMP
-+    if ((opts & OPENSSL_INIT_ZLIB)
-+            && !RUN_ONCE(&zlib, ossl_init_zlib))
-+        return 0;
-+#endif
-+
-+    return 1;
-+}
-+
-+int OPENSSL_atexit(void (*handler)(void))
-+{
-+    OPENSSL_INIT_STOP *newhand;
-+
-+#if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
-+    {
-+        union {
-+            void *sym;
-+            void (*func)(void);
-+        } handlersym;
-+
-+        handlersym.func = handler;
-+# ifdef DSO_WIN32
-+        {
-+            HMODULE handle = NULL;
-+            BOOL ret;
-+
-+            /*
-+             * We don't use the DSO route for WIN32 because there is a better
-+             * way
-+             */
-+            ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
-+                                    | GET_MODULE_HANDLE_EX_FLAG_PIN,
-+                                    handlersym.sym, &handle);
-+
-+            if (!ret)
-+                return 0;
-+        }
-+# else
-+        /*
-+         * Deliberately leak a reference to the handler. This will force the
-+         * library/code containing the handler to remain loaded until we run the
-+         * atexit handler. If -znodelete has been used then this is
-+         * unneccessary.
-+         */
-+        {
-+            DSO *dso = NULL;
-+
-+            dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
-+            DSO_free(dso);
-+        }
-+# endif
-+    }
-+#endif
-+
-+    newhand = OPENSSL_malloc(sizeof(*newhand));
-+    if (newhand == NULL)
-+        return 0;
-+
-+    newhand->handler = handler;
-+    newhand->next = stop_handlers;
-+    stop_handlers = newhand;
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/build.info
-new file mode 100644
-index 0000000..cbe2080
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        tls1_prf.c kdf_err.c hkdf.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/hkdf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/hkdf.c
-new file mode 100644
-index 0000000..00b95b5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/hkdf.c
-@@ -0,0 +1,293 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include "internal/evp_int.h"
-+
-+#define HKDF_MAXBUF 1024
-+
-+static unsigned char *HKDF(const EVP_MD *evp_md,
-+                           const unsigned char *salt, size_t salt_len,
-+                           const unsigned char *key, size_t key_len,
-+                           const unsigned char *info, size_t info_len,
-+                           unsigned char *okm, size_t okm_len);
-+
-+static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
-+                                   const unsigned char *salt, size_t salt_len,
-+                                   const unsigned char *key, size_t key_len,
-+                                   unsigned char *prk, size_t *prk_len);
-+
-+static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
-+                                  const unsigned char *prk, size_t prk_len,
-+                                  const unsigned char *info, size_t info_len,
-+                                  unsigned char *okm, size_t okm_len);
-+
-+typedef struct {
-+    const EVP_MD *md;
-+    unsigned char *salt;
-+    size_t salt_len;
-+    unsigned char *key;
-+    size_t key_len;
-+    unsigned char info[HKDF_MAXBUF];
-+    size_t info_len;
-+} HKDF_PKEY_CTX;
-+
-+static int pkey_hkdf_init(EVP_PKEY_CTX *ctx)
-+{
-+    HKDF_PKEY_CTX *kctx;
-+
-+    kctx = OPENSSL_zalloc(sizeof(*kctx));
-+    if (kctx == NULL)
-+        return 0;
-+
-+    ctx->data = kctx;
-+
-+    return 1;
-+}
-+
-+static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx)
-+{
-+    HKDF_PKEY_CTX *kctx = ctx->data;
-+    OPENSSL_clear_free(kctx->salt, kctx->salt_len);
-+    OPENSSL_clear_free(kctx->key, kctx->key_len);
-+    OPENSSL_cleanse(kctx->info, kctx->info_len);
-+    OPENSSL_free(kctx);
-+}
-+
-+static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-+{
-+    HKDF_PKEY_CTX *kctx = ctx->data;
-+
-+    switch (type) {
-+    case EVP_PKEY_CTRL_HKDF_MD:
-+        if (p2 == NULL)
-+            return 0;
-+
-+        kctx->md = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_HKDF_SALT:
-+        if (p1 == 0 || p2 == NULL)
-+            return 1;
-+
-+        if (p1 < 0)
-+            return 0;
-+
-+        if (kctx->salt != NULL)
-+            OPENSSL_clear_free(kctx->salt, kctx->salt_len);
-+
-+        kctx->salt = OPENSSL_memdup(p2, p1);
-+        if (kctx->salt == NULL)
-+            return 0;
-+
-+        kctx->salt_len = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_HKDF_KEY:
-+        if (p1 < 0)
-+            return 0;
-+
-+        if (kctx->key != NULL)
-+            OPENSSL_clear_free(kctx->key, kctx->key_len);
-+
-+        kctx->key = OPENSSL_memdup(p2, p1);
-+        if (kctx->key == NULL)
-+            return 0;
-+
-+        kctx->key_len  = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_HKDF_INFO:
-+        if (p1 == 0 || p2 == NULL)
-+            return 1;
-+
-+        if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len))
-+            return 0;
-+
-+        memcpy(kctx->info + kctx->info_len, p2, p1);
-+        kctx->info_len += p1;
-+        return 1;
-+
-+    default:
-+        return -2;
-+
-+    }
-+}
-+
-+static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
-+                              const char *value)
-+{
-+    if (strcmp(type, "md") == 0)
-+        return EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_get_digestbyname(value));
-+
-+    if (strcmp(type, "salt") == 0)
-+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
-+
-+    if (strcmp(type, "hexsalt") == 0)
-+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
-+
-+    if (strcmp(type, "key") == 0)
-+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
-+
-+    if (strcmp(type, "hexkey") == 0)
-+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
-+
-+    if (strcmp(type, "info") == 0)
-+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
-+
-+    if (strcmp(type, "hexinfo") == 0)
-+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
-+
-+    return -2;
-+}
-+
-+static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
-+                            size_t *keylen)
-+{
-+    HKDF_PKEY_CTX *kctx = ctx->data;
-+
-+    if (kctx->md == NULL || kctx->key == NULL)
-+        return 0;
-+
-+    if (HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key, kctx->key_len,
-+             kctx->info, kctx->info_len, key, *keylen) == NULL)
-+    {
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+const EVP_PKEY_METHOD hkdf_pkey_meth = {
-+    EVP_PKEY_HKDF,
-+    0,
-+    pkey_hkdf_init,
-+    0,
-+    pkey_hkdf_cleanup,
-+
-+    0, 0,
-+    0, 0,
-+
-+    0,
-+    0,
-+
-+    0,
-+    0,
-+
-+    0, 0,
-+
-+    0, 0, 0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0,
-+    pkey_hkdf_derive,
-+    pkey_hkdf_ctrl,
-+    pkey_hkdf_ctrl_str
-+};
-+
-+static unsigned char *HKDF(const EVP_MD *evp_md,
-+                           const unsigned char *salt, size_t salt_len,
-+                           const unsigned char *key, size_t key_len,
-+                           const unsigned char *info, size_t info_len,
-+                           unsigned char *okm, size_t okm_len)
-+{
-+    unsigned char prk[EVP_MAX_MD_SIZE];
-+    size_t prk_len;
-+
-+    if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len))
-+        return NULL;
-+
-+    return HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
-+}
-+
-+static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
-+                                   const unsigned char *salt, size_t salt_len,
-+                                   const unsigned char *key, size_t key_len,
-+                                   unsigned char *prk, size_t *prk_len)
-+{
-+    unsigned int tmp_len;
-+
-+    if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len))
-+        return NULL;
-+
-+    *prk_len = tmp_len;
-+    return prk;
-+}
-+
-+static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
-+                                  const unsigned char *prk, size_t prk_len,
-+                                  const unsigned char *info, size_t info_len,
-+                                  unsigned char *okm, size_t okm_len)
-+{
-+    HMAC_CTX *hmac;
-+
-+    unsigned int i;
-+
-+    unsigned char prev[EVP_MAX_MD_SIZE];
-+
-+    size_t done_len = 0, dig_len = EVP_MD_size(evp_md);
-+
-+    size_t n = okm_len / dig_len;
-+    if (okm_len % dig_len)
-+        n++;
-+
-+    if (n > 255)
-+        return NULL;
-+
-+    if ((hmac = HMAC_CTX_new()) == NULL)
-+        return NULL;
-+
-+    if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
-+        goto err;
-+
-+    for (i = 1; i <= n; i++) {
-+        size_t copy_len;
-+        const unsigned char ctr = i;
-+
-+        if (i > 1) {
-+            if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))
-+                goto err;
-+
-+            if (!HMAC_Update(hmac, prev, dig_len))
-+                goto err;
-+        }
-+
-+        if (!HMAC_Update(hmac, info, info_len))
-+            goto err;
-+
-+        if (!HMAC_Update(hmac, &ctr, 1))
-+            goto err;
-+
-+        if (!HMAC_Final(hmac, prev, NULL))
-+            goto err;
-+
-+        copy_len = (done_len + dig_len > okm_len) ?
-+                       okm_len - done_len :
-+                       dig_len;
-+
-+        memcpy(okm + done_len, prev, copy_len);
-+
-+        done_len += copy_len;
-+    }
-+
-+    HMAC_CTX_free(hmac);
-+    return okm;
-+
-+ err:
-+    HMAC_CTX_free(hmac);
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/kdf_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/kdf_err.c
-new file mode 100644
-index 0000000..d7d71b3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/kdf_err.c
-@@ -0,0 +1,46 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_KDF,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_KDF,0,reason)
-+
-+static ERR_STRING_DATA KDF_str_functs[] = {
-+    {ERR_FUNC(KDF_F_PKEY_TLS1_PRF_CTRL_STR), "pkey_tls1_prf_ctrl_str"},
-+    {ERR_FUNC(KDF_F_PKEY_TLS1_PRF_DERIVE), "pkey_tls1_prf_derive"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA KDF_str_reasons[] = {
-+    {ERR_REASON(KDF_R_INVALID_DIGEST), "invalid digest"},
-+    {ERR_REASON(KDF_R_MISSING_PARAMETER), "missing parameter"},
-+    {ERR_REASON(KDF_R_VALUE_MISSING), "value missing"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_KDF_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(KDF_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, KDF_str_functs);
-+        ERR_load_strings(0, KDF_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/tls1_prf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/tls1_prf.c
-new file mode 100644
-index 0000000..fa13732
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/kdf/tls1_prf.c
-@@ -0,0 +1,265 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+
-+static int tls1_prf_alg(const EVP_MD *md,
-+                        const unsigned char *sec, size_t slen,
-+                        const unsigned char *seed, size_t seed_len,
-+                        unsigned char *out, size_t olen);
-+
-+#define TLS1_PRF_MAXBUF 1024
-+
-+/* TLS KDF pkey context structure */
-+
-+typedef struct {
-+    /* Digest to use for PRF */
-+    const EVP_MD *md;
-+    /* Secret value to use for PRF */
-+    unsigned char *sec;
-+    size_t seclen;
-+    /* Buffer of concatenated seed data */
-+    unsigned char seed[TLS1_PRF_MAXBUF];
-+    size_t seedlen;
-+} TLS1_PRF_PKEY_CTX;
-+
-+static int pkey_tls1_prf_init(EVP_PKEY_CTX *ctx)
-+{
-+    TLS1_PRF_PKEY_CTX *kctx;
-+
-+    kctx = OPENSSL_zalloc(sizeof(*kctx));
-+    if (kctx == NULL)
-+        return 0;
-+    ctx->data = kctx;
-+
-+    return 1;
-+}
-+
-+static void pkey_tls1_prf_cleanup(EVP_PKEY_CTX *ctx)
-+{
-+    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
-+    OPENSSL_clear_free(kctx->sec, kctx->seclen);
-+    OPENSSL_cleanse(kctx->seed, kctx->seedlen);
-+    OPENSSL_free(kctx);
-+}
-+
-+static int pkey_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-+{
-+    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
-+    switch (type) {
-+    case EVP_PKEY_CTRL_TLS_MD:
-+        kctx->md = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_TLS_SECRET:
-+        if (p1 < 0)
-+            return 0;
-+        if (kctx->sec != NULL)
-+            OPENSSL_clear_free(kctx->sec, kctx->seclen);
-+        OPENSSL_cleanse(kctx->seed, kctx->seedlen);
-+        kctx->seedlen = 0;
-+        kctx->sec = OPENSSL_memdup(p2, p1);
-+        if (kctx->sec == NULL)
-+            return 0;
-+        kctx->seclen  = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_TLS_SEED:
-+        if (p1 == 0 || p2 == NULL)
-+            return 1;
-+        if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - kctx->seedlen))
-+            return 0;
-+        memcpy(kctx->seed + kctx->seedlen, p2, p1);
-+        kctx->seedlen += p1;
-+        return 1;
-+
-+    default:
-+        return -2;
-+
-+    }
-+}
-+
-+static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx,
-+                                  const char *type, const char *value)
-+{
-+    if (value == NULL) {
-+        KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING);
-+        return 0;
-+    }
-+    if (strcmp(type, "md") == 0) {
-+        TLS1_PRF_PKEY_CTX *kctx = ctx->data;
-+
-+        const EVP_MD *md = EVP_get_digestbyname(value);
-+        if (md == NULL) {
-+            KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_INVALID_DIGEST);
-+            return 0;
-+        }
-+        kctx->md = md;
-+        return 1;
-+    }
-+    if (strcmp(type, "secret") == 0)
-+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
-+    if (strcmp(type, "hexsecret") == 0)
-+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
-+    if (strcmp(type, "seed") == 0)
-+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
-+    if (strcmp(type, "hexseed") == 0)
-+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
-+    return -2;
-+}
-+
-+static int pkey_tls1_prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
-+                                size_t *keylen)
-+{
-+    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
-+    if (kctx->md == NULL || kctx->sec == NULL || kctx->seedlen == 0) {
-+        KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_PARAMETER);
-+        return 0;
-+    }
-+    return tls1_prf_alg(kctx->md, kctx->sec, kctx->seclen,
-+                        kctx->seed, kctx->seedlen,
-+                        key, *keylen);
-+}
-+
-+const EVP_PKEY_METHOD tls1_prf_pkey_meth = {
-+    EVP_PKEY_TLS1_PRF,
-+    0,
-+    pkey_tls1_prf_init,
-+    0,
-+    pkey_tls1_prf_cleanup,
-+
-+    0, 0,
-+    0, 0,
-+
-+    0,
-+    0,
-+
-+    0,
-+    0,
-+
-+    0, 0,
-+
-+    0, 0, 0, 0,
-+
-+    0, 0,
-+
-+    0, 0,
-+
-+    0,
-+    pkey_tls1_prf_derive,
-+    pkey_tls1_prf_ctrl,
-+    pkey_tls1_prf_ctrl_str
-+};
-+
-+static int tls1_prf_P_hash(const EVP_MD *md,
-+                           const unsigned char *sec, size_t sec_len,
-+                           const unsigned char *seed, size_t seed_len,
-+                           unsigned char *out, size_t olen)
-+{
-+    int chunk;
-+    EVP_MD_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL;
-+    EVP_PKEY *mac_key = NULL;
-+    unsigned char A1[EVP_MAX_MD_SIZE];
-+    size_t A1_len;
-+    int ret = 0;
-+
-+    chunk = EVP_MD_size(md);
-+    OPENSSL_assert(chunk >= 0);
-+
-+    ctx = EVP_MD_CTX_new();
-+    ctx_tmp = EVP_MD_CTX_new();
-+    ctx_init = EVP_MD_CTX_new();
-+    if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL)
-+        goto err;
-+    EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-+    mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
-+    if (mac_key == NULL)
-+        goto err;
-+    if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key))
-+        goto err;
-+    if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
-+        goto err;
-+    if (seed != NULL && !EVP_DigestSignUpdate(ctx, seed, seed_len))
-+        goto err;
-+    if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
-+        goto err;
-+
-+    for (;;) {
-+        /* Reinit mac contexts */
-+        if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
-+            goto err;
-+        if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
-+            goto err;
-+        if (olen > (size_t)chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx))
-+            goto err;
-+        if (seed && !EVP_DigestSignUpdate(ctx, seed, seed_len))
-+            goto err;
-+
-+        if (olen > (size_t)chunk) {
-+            size_t mac_len;
-+            if (!EVP_DigestSignFinal(ctx, out, &mac_len))
-+                goto err;
-+            out += mac_len;
-+            olen -= mac_len;
-+            /* calc the next A1 value */
-+            if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len))
-+                goto err;
-+        } else {                /* last one */
-+
-+            if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
-+                goto err;
-+            memcpy(out, A1, olen);
-+            break;
-+        }
-+    }
-+    ret = 1;
-+ err:
-+    EVP_PKEY_free(mac_key);
-+    EVP_MD_CTX_free(ctx);
-+    EVP_MD_CTX_free(ctx_tmp);
-+    EVP_MD_CTX_free(ctx_init);
-+    OPENSSL_cleanse(A1, sizeof(A1));
-+    return ret;
-+}
-+
-+static int tls1_prf_alg(const EVP_MD *md,
-+                        const unsigned char *sec, size_t slen,
-+                        const unsigned char *seed, size_t seed_len,
-+                        unsigned char *out, size_t olen)
-+{
-+
-+    if (EVP_MD_type(md) == NID_md5_sha1) {
-+        size_t i;
-+        unsigned char *tmp;
-+        if (!tls1_prf_P_hash(EVP_md5(), sec, slen/2 + (slen & 1),
-+                         seed, seed_len, out, olen))
-+            return 0;
-+
-+        tmp = OPENSSL_malloc(olen);
-+        if (tmp == NULL)
-+            return 0;
-+        if (!tls1_prf_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1),
-+                         seed, seed_len, tmp, olen)) {
-+            OPENSSL_clear_free(tmp, olen);
-+            return 0;
-+        }
-+        for (i = 0; i < olen; i++)
-+            out[i] ^= tmp[i];
-+        OPENSSL_clear_free(tmp, olen);
-+        return 1;
-+    }
-+    if (!tls1_prf_P_hash(md, sec, slen, seed, seed_len, out, olen))
-+        return 0;
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/build.info
-new file mode 100644
-index 0000000..30797f2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        lhash.c lh_stats.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lh_stats.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lh_stats.c
-new file mode 100644
-index 0000000..7337832
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lh_stats.c
-@@ -0,0 +1,118 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+/*
-+ * If you wish to build this outside of OpenSSL, remove the following lines
-+ * and things should work as expected
-+ */
-+#include "internal/cryptlib.h"
-+
-+#include 
-+#include 
-+#include "lhash_lcl.h"
-+
-+# ifndef OPENSSL_NO_STDIO
-+void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp)
-+{
-+    BIO *bp;
-+
-+    bp = BIO_new(BIO_s_file());
-+    if (bp == NULL)
-+        return;
-+    BIO_set_fp(bp, fp, BIO_NOCLOSE);
-+    OPENSSL_LH_stats_bio(lh, bp);
-+    BIO_free(bp);
-+}
-+
-+void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp)
-+{
-+    BIO *bp;
-+
-+    bp = BIO_new(BIO_s_file());
-+    if (bp == NULL)
-+        return;
-+    BIO_set_fp(bp, fp, BIO_NOCLOSE);
-+    OPENSSL_LH_node_stats_bio(lh, bp);
-+    BIO_free(bp);
-+}
-+
-+void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp)
-+{
-+    BIO *bp;
-+
-+    bp = BIO_new(BIO_s_file());
-+    if (bp == NULL)
-+        return;
-+    BIO_set_fp(bp, fp, BIO_NOCLOSE);
-+    OPENSSL_LH_node_usage_stats_bio(lh, bp);
-+    BIO_free(bp);
-+}
-+
-+# endif
-+
-+void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
-+{
-+    BIO_printf(out, "num_items             = %lu\n", lh->num_items);
-+    BIO_printf(out, "num_nodes             = %u\n", lh->num_nodes);
-+    BIO_printf(out, "num_alloc_nodes       = %u\n", lh->num_alloc_nodes);
-+    BIO_printf(out, "num_expands           = %lu\n", lh->num_expands);
-+    BIO_printf(out, "num_expand_reallocs   = %lu\n", lh->num_expand_reallocs);
-+    BIO_printf(out, "num_contracts         = %lu\n", lh->num_contracts);
-+    BIO_printf(out, "num_contract_reallocs = %lu\n",
-+               lh->num_contract_reallocs);
-+    BIO_printf(out, "num_hash_calls        = %lu\n", lh->num_hash_calls);
-+    BIO_printf(out, "num_comp_calls        = %lu\n", lh->num_comp_calls);
-+    BIO_printf(out, "num_insert            = %lu\n", lh->num_insert);
-+    BIO_printf(out, "num_replace           = %lu\n", lh->num_replace);
-+    BIO_printf(out, "num_delete            = %lu\n", lh->num_delete);
-+    BIO_printf(out, "num_no_delete         = %lu\n", lh->num_no_delete);
-+    BIO_printf(out, "num_retrieve          = %lu\n", lh->num_retrieve);
-+    BIO_printf(out, "num_retrieve_miss     = %lu\n", lh->num_retrieve_miss);
-+    BIO_printf(out, "num_hash_comps        = %lu\n", lh->num_hash_comps);
-+}
-+
-+void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
-+{
-+    OPENSSL_LH_NODE *n;
-+    unsigned int i, num;
-+
-+    for (i = 0; i < lh->num_nodes; i++) {
-+        for (n = lh->b[i], num = 0; n != NULL; n = n->next)
-+            num++;
-+        BIO_printf(out, "node %6u -> %3u\n", i, num);
-+    }
-+}
-+
-+void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
-+{
-+    OPENSSL_LH_NODE *n;
-+    unsigned long num;
-+    unsigned int i;
-+    unsigned long total = 0, n_used = 0;
-+
-+    for (i = 0; i < lh->num_nodes; i++) {
-+        for (n = lh->b[i], num = 0; n != NULL; n = n->next)
-+            num++;
-+        if (num != 0) {
-+            n_used++;
-+            total += num;
-+        }
-+    }
-+    BIO_printf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes);
-+    BIO_printf(out, "%lu items\n", total);
-+    if (n_used == 0)
-+        return;
-+    BIO_printf(out, "load %d.%02d  actual load %d.%02d\n",
-+               (int)(total / lh->num_nodes),
-+               (int)((total % lh->num_nodes) * 100 / lh->num_nodes),
-+               (int)(total / n_used), (int)((total % n_used) * 100 / n_used));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lhash.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lhash.c
-new file mode 100644
-index 0000000..adde832
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lhash.c
-@@ -0,0 +1,349 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "lhash_lcl.h"
-+
-+
-+#undef MIN_NODES
-+#define MIN_NODES       16
-+#define UP_LOAD         (2*LH_LOAD_MULT) /* load times 256 (default 2) */
-+#define DOWN_LOAD       (LH_LOAD_MULT) /* load times 256 (default 1) */
-+
-+static int expand(OPENSSL_LHASH *lh);
-+static void contract(OPENSSL_LHASH *lh);
-+static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, const void *data, unsigned long *rhash);
-+
-+OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c)
-+{
-+    OPENSSL_LHASH *ret;
-+
-+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
-+        goto err0;
-+    if ((ret->b = OPENSSL_zalloc(sizeof(*ret->b) * MIN_NODES)) == NULL)
-+        goto err1;
-+    ret->comp = ((c == NULL) ? (OPENSSL_LH_COMPFUNC)strcmp : c);
-+    ret->hash = ((h == NULL) ? (OPENSSL_LH_HASHFUNC)OPENSSL_LH_strhash : h);
-+    ret->num_nodes = MIN_NODES / 2;
-+    ret->num_alloc_nodes = MIN_NODES;
-+    ret->pmax = MIN_NODES / 2;
-+    ret->up_load = UP_LOAD;
-+    ret->down_load = DOWN_LOAD;
-+    return (ret);
-+
-+ err1:
-+    OPENSSL_free(ret);
-+ err0:
-+    return (NULL);
-+}
-+
-+void OPENSSL_LH_free(OPENSSL_LHASH *lh)
-+{
-+    unsigned int i;
-+    OPENSSL_LH_NODE *n, *nn;
-+
-+    if (lh == NULL)
-+        return;
-+
-+    for (i = 0; i < lh->num_nodes; i++) {
-+        n = lh->b[i];
-+        while (n != NULL) {
-+            nn = n->next;
-+            OPENSSL_free(n);
-+            n = nn;
-+        }
-+    }
-+    OPENSSL_free(lh->b);
-+    OPENSSL_free(lh);
-+}
-+
-+void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data)
-+{
-+    unsigned long hash;
-+    OPENSSL_LH_NODE *nn, **rn;
-+    void *ret;
-+
-+    lh->error = 0;
-+    if ((lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)) && !expand(lh))
-+        return NULL;        /* 'lh->error++' already done in 'expand' */
-+
-+    rn = getrn(lh, data, &hash);
-+
-+    if (*rn == NULL) {
-+        if ((nn = OPENSSL_malloc(sizeof(*nn))) == NULL) {
-+            lh->error++;
-+            return (NULL);
-+        }
-+        nn->data = data;
-+        nn->next = NULL;
-+        nn->hash = hash;
-+        *rn = nn;
-+        ret = NULL;
-+        lh->num_insert++;
-+        lh->num_items++;
-+    } else {                    /* replace same key */
-+
-+        ret = (*rn)->data;
-+        (*rn)->data = data;
-+        lh->num_replace++;
-+    }
-+    return (ret);
-+}
-+
-+void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data)
-+{
-+    unsigned long hash;
-+    OPENSSL_LH_NODE *nn, **rn;
-+    void *ret;
-+
-+    lh->error = 0;
-+    rn = getrn(lh, data, &hash);
-+
-+    if (*rn == NULL) {
-+        lh->num_no_delete++;
-+        return (NULL);
-+    } else {
-+        nn = *rn;
-+        *rn = nn->next;
-+        ret = nn->data;
-+        OPENSSL_free(nn);
-+        lh->num_delete++;
-+    }
-+
-+    lh->num_items--;
-+    if ((lh->num_nodes > MIN_NODES) &&
-+        (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)))
-+        contract(lh);
-+
-+    return (ret);
-+}
-+
-+void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data)
-+{
-+    unsigned long hash;
-+    OPENSSL_LH_NODE **rn;
-+    void *ret;
-+
-+    lh->error = 0;
-+    rn = getrn(lh, data, &hash);
-+
-+    if (*rn == NULL) {
-+        lh->num_retrieve_miss++;
-+        return (NULL);
-+    } else {
-+        ret = (*rn)->data;
-+        lh->num_retrieve++;
-+    }
-+    return (ret);
-+}
-+
-+static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg,
-+                          OPENSSL_LH_DOALL_FUNC func,
-+                          OPENSSL_LH_DOALL_FUNCARG func_arg, void *arg)
-+{
-+    int i;
-+    OPENSSL_LH_NODE *a, *n;
-+
-+    if (lh == NULL)
-+        return;
-+
-+    /*
-+     * reverse the order so we search from 'top to bottom' We were having
-+     * memory leaks otherwise
-+     */
-+    for (i = lh->num_nodes - 1; i >= 0; i--) {
-+        a = lh->b[i];
-+        while (a != NULL) {
-+            n = a->next;
-+            if (use_arg)
-+                func_arg(a->data, arg);
-+            else
-+                func(a->data);
-+            a = n;
-+        }
-+    }
-+}
-+
-+void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func)
-+{
-+    doall_util_fn(lh, 0, func, (OPENSSL_LH_DOALL_FUNCARG)0, NULL);
-+}
-+
-+void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg)
-+{
-+    doall_util_fn(lh, 1, (OPENSSL_LH_DOALL_FUNC)0, func, arg);
-+}
-+
-+static int expand(OPENSSL_LHASH *lh)
-+{
-+    OPENSSL_LH_NODE **n, **n1, **n2, *np;
-+    unsigned int p, i, j;
-+    unsigned long hash, nni;
-+
-+    lh->num_nodes++;
-+    lh->num_expands++;
-+    p = (int)lh->p++;
-+    n1 = &(lh->b[p]);
-+    n2 = &(lh->b[p + (int)lh->pmax]);
-+    *n2 = NULL;
-+    nni = lh->num_alloc_nodes;
-+
-+    for (np = *n1; np != NULL;) {
-+        hash = np->hash;
-+        if ((hash % nni) != p) { /* move it */
-+            *n1 = (*n1)->next;
-+            np->next = *n2;
-+            *n2 = np;
-+        } else
-+            n1 = &((*n1)->next);
-+        np = *n1;
-+    }
-+
-+    if ((lh->p) >= lh->pmax) {
-+        j = (int)lh->num_alloc_nodes * 2;
-+        n = OPENSSL_realloc(lh->b, (int)(sizeof(OPENSSL_LH_NODE *) * j));
-+        if (n == NULL) {
-+            lh->error++;
-+            lh->num_nodes--;
-+            lh->p = 0;
-+            return 0;
-+        }
-+        for (i = (int)lh->num_alloc_nodes; i < j; i++) /* 26/02/92 eay */
-+            n[i] = NULL;        /* 02/03/92 eay */
-+        lh->pmax = lh->num_alloc_nodes;
-+        lh->num_alloc_nodes = j;
-+        lh->num_expand_reallocs++;
-+        lh->p = 0;
-+        lh->b = n;
-+    }
-+    return 1;
-+}
-+
-+static void contract(OPENSSL_LHASH *lh)
-+{
-+    OPENSSL_LH_NODE **n, *n1, *np;
-+
-+    np = lh->b[lh->p + lh->pmax - 1];
-+    lh->b[lh->p + lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */
-+    if (lh->p == 0) {
-+        n = OPENSSL_realloc(lh->b,
-+                            (unsigned int)(sizeof(OPENSSL_LH_NODE *) * lh->pmax));
-+        if (n == NULL) {
-+            /* fputs("realloc error in lhash",stderr); */
-+            lh->error++;
-+            return;
-+        }
-+        lh->num_contract_reallocs++;
-+        lh->num_alloc_nodes /= 2;
-+        lh->pmax /= 2;
-+        lh->p = lh->pmax - 1;
-+        lh->b = n;
-+    } else
-+        lh->p--;
-+
-+    lh->num_nodes--;
-+    lh->num_contracts++;
-+
-+    n1 = lh->b[(int)lh->p];
-+    if (n1 == NULL)
-+        lh->b[(int)lh->p] = np;
-+    else {
-+        while (n1->next != NULL)
-+            n1 = n1->next;
-+        n1->next = np;
-+    }
-+}
-+
-+static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
-+                               const void *data, unsigned long *rhash)
-+{
-+    OPENSSL_LH_NODE **ret, *n1;
-+    unsigned long hash, nn;
-+    OPENSSL_LH_COMPFUNC cf;
-+
-+    hash = (*(lh->hash)) (data);
-+    lh->num_hash_calls++;
-+    *rhash = hash;
-+
-+    nn = hash % lh->pmax;
-+    if (nn < lh->p)
-+        nn = hash % lh->num_alloc_nodes;
-+
-+    cf = lh->comp;
-+    ret = &(lh->b[(int)nn]);
-+    for (n1 = *ret; n1 != NULL; n1 = n1->next) {
-+        lh->num_hash_comps++;
-+        if (n1->hash != hash) {
-+            ret = &(n1->next);
-+            continue;
-+        }
-+        lh->num_comp_calls++;
-+        if (cf(n1->data, data) == 0)
-+            break;
-+        ret = &(n1->next);
-+    }
-+    return (ret);
-+}
-+
-+/*
-+ * The following hash seems to work very well on normal text strings no
-+ * collisions on /usr/dict/words and it distributes on %2^n quite well, not
-+ * as good as MD5, but still good.
-+ */
-+unsigned long OPENSSL_LH_strhash(const char *c)
-+{
-+    unsigned long ret = 0;
-+    long n;
-+    unsigned long v;
-+    int r;
-+
-+    if ((c == NULL) || (*c == '\0'))
-+        return (ret);
-+/*-
-+    unsigned char b[16];
-+    MD5(c,strlen(c),b);
-+    return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));
-+*/
-+
-+    n = 0x100;
-+    while (*c) {
-+        v = n | (*c);
-+        n += 0x100;
-+        r = (int)((v >> 2) ^ v) & 0x0f;
-+        ret = (ret << r) | (ret >> (32 - r));
-+        ret &= 0xFFFFFFFFL;
-+        ret ^= v * v;
-+        c++;
-+    }
-+    return ((ret >> 16) ^ ret);
-+}
-+
-+unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh)
-+{
-+    return lh ? lh->num_items : 0;
-+}
-+
-+unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh)
-+{
-+    return lh->down_load;
-+}
-+
-+void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load)
-+{
-+    lh->down_load = down_load;
-+}
-+
-+int OPENSSL_LH_error(OPENSSL_LHASH *lh)
-+{
-+    return lh->error;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lhash_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lhash_lcl.h
-new file mode 100644
-index 0000000..eb4a1a3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/lhash_lcl.h
-@@ -0,0 +1,42 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+
-+struct lhash_node_st {
-+    void *data;
-+    struct lhash_node_st *next;
-+    unsigned long hash;
-+};
-+
-+struct lhash_st {
-+    OPENSSL_LH_NODE **b;
-+    OPENSSL_LH_COMPFUNC comp;
-+    OPENSSL_LH_HASHFUNC hash;
-+    unsigned int num_nodes;
-+    unsigned int num_alloc_nodes;
-+    unsigned int p;
-+    unsigned int pmax;
-+    unsigned long up_load;      /* load times 256 */
-+    unsigned long down_load;    /* load times 256 */
-+    unsigned long num_items;
-+    unsigned long num_expands;
-+    unsigned long num_expand_reallocs;
-+    unsigned long num_contracts;
-+    unsigned long num_contract_reallocs;
-+    unsigned long num_hash_calls;
-+    unsigned long num_comp_calls;
-+    unsigned long num_insert;
-+    unsigned long num_replace;
-+    unsigned long num_delete;
-+    unsigned long num_no_delete;
-+    unsigned long num_retrieve;
-+    unsigned long num_retrieve_miss;
-+    unsigned long num_hash_comps;
-+    int error;
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/num.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/num.pl
-new file mode 100644
-index 0000000..8a8c42c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/lhash/num.pl
-@@ -0,0 +1,23 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#node     10 ->   4
-+
-+while (<>)
-+	{
-+	next unless /^node/;
-+	s|\R$||;                # Better chomp
-+	@a=split;
-+	$num{$a[3]}++;
-+	}
-+
-+@a=sort {$a <=> $b } keys %num;
-+foreach (0 .. $a[$#a])
-+	{
-+	printf "%4d:%4d\n",$_,$num{$_};
-+	}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md2/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/md2/build.info
-new file mode 100644
-index 0000000..e31948c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md2/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        md2_dgst.c md2_one.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md2/md2_dgst.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/md2/md2_dgst.c
-new file mode 100644
-index 0000000..ff062fd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md2/md2_dgst.c
-@@ -0,0 +1,173 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+/*
-+ * Implemented from RFC1319 The MD2 Message-Digest Algorithm
-+ */
-+
-+#define UCHAR   unsigned char
-+
-+static void md2_block(MD2_CTX *c, const unsigned char *d);
-+/*
-+ * The magic S table - I have converted it to hex since it is basically just
-+ * a random byte string.
-+ */
-+static const MD2_INT S[256] = {
-+    0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
-+    0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
-+    0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
-+    0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
-+    0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
-+    0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
-+    0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
-+    0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
-+    0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
-+    0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
-+    0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
-+    0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
-+    0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
-+    0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
-+    0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
-+    0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
-+    0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
-+    0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
-+    0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
-+    0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
-+    0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
-+    0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
-+    0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
-+    0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
-+    0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
-+    0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
-+    0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
-+    0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
-+    0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
-+    0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
-+    0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
-+    0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
-+};
-+
-+const char *MD2_options(void)
-+{
-+    if (sizeof(MD2_INT) == 1)
-+        return ("md2(char)");
-+    else
-+        return ("md2(int)");
-+}
-+
-+int MD2_Init(MD2_CTX *c)
-+{
-+    c->num = 0;
-+    memset(c->state, 0, sizeof(c->state));
-+    memset(c->cksm, 0, sizeof(c->cksm));
-+    memset(c->data, 0, sizeof(c->data));
-+    return 1;
-+}
-+
-+int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len)
-+{
-+    register UCHAR *p;
-+
-+    if (len == 0)
-+        return 1;
-+
-+    p = c->data;
-+    if (c->num != 0) {
-+        if ((c->num + len) >= MD2_BLOCK) {
-+            memcpy(&(p[c->num]), data, MD2_BLOCK - c->num);
-+            md2_block(c, c->data);
-+            data += (MD2_BLOCK - c->num);
-+            len -= (MD2_BLOCK - c->num);
-+            c->num = 0;
-+            /* drop through and do the rest */
-+        } else {
-+            memcpy(&(p[c->num]), data, len);
-+            /* data+=len; */
-+            c->num += (int)len;
-+            return 1;
-+        }
-+    }
-+    /*
-+     * we now can process the input data in blocks of MD2_BLOCK chars and
-+     * save the leftovers to c->data.
-+     */
-+    while (len >= MD2_BLOCK) {
-+        md2_block(c, data);
-+        data += MD2_BLOCK;
-+        len -= MD2_BLOCK;
-+    }
-+    memcpy(p, data, len);
-+    c->num = (int)len;
-+    return 1;
-+}
-+
-+static void md2_block(MD2_CTX *c, const unsigned char *d)
-+{
-+    register MD2_INT t, *sp1, *sp2;
-+    register int i, j;
-+    MD2_INT state[48];
-+
-+    sp1 = c->state;
-+    sp2 = c->cksm;
-+    j = sp2[MD2_BLOCK - 1];
-+    for (i = 0; i < 16; i++) {
-+        state[i] = sp1[i];
-+        state[i + 16] = t = d[i];
-+        state[i + 32] = (t ^ sp1[i]);
-+        j = sp2[i] ^= S[t ^ j];
-+    }
-+    t = 0;
-+    for (i = 0; i < 18; i++) {
-+        for (j = 0; j < 48; j += 8) {
-+            t = state[j + 0] ^= S[t];
-+            t = state[j + 1] ^= S[t];
-+            t = state[j + 2] ^= S[t];
-+            t = state[j + 3] ^= S[t];
-+            t = state[j + 4] ^= S[t];
-+            t = state[j + 5] ^= S[t];
-+            t = state[j + 6] ^= S[t];
-+            t = state[j + 7] ^= S[t];
-+        }
-+        t = (t + i) & 0xff;
-+    }
-+    memcpy(sp1, state, 16 * sizeof(MD2_INT));
-+    OPENSSL_cleanse(state, 48 * sizeof(MD2_INT));
-+}
-+
-+int MD2_Final(unsigned char *md, MD2_CTX *c)
-+{
-+    int i, v;
-+    register UCHAR *cp;
-+    register MD2_INT *p1, *p2;
-+
-+    cp = c->data;
-+    p1 = c->state;
-+    p2 = c->cksm;
-+    v = MD2_BLOCK - c->num;
-+    for (i = c->num; i < MD2_BLOCK; i++)
-+        cp[i] = (UCHAR) v;
-+
-+    md2_block(c, cp);
-+
-+    for (i = 0; i < MD2_BLOCK; i++)
-+        cp[i] = (UCHAR) p2[i];
-+    md2_block(c, cp);
-+
-+    for (i = 0; i < 16; i++)
-+        md[i] = (UCHAR) (p1[i] & 0xff);
-+    OPENSSL_cleanse(c, sizeof(*c));
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md2/md2_one.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/md2/md2_one.c
-new file mode 100644
-index 0000000..460f96e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md2/md2_one.c
-@@ -0,0 +1,47 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+/*
-+ * This is a separate file so that #defines in cryptlib.h can map my MD
-+ * functions to different names
-+ */
-+
-+unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md)
-+{
-+    MD2_CTX c;
-+    static unsigned char m[MD2_DIGEST_LENGTH];
-+
-+    if (md == NULL)
-+        md = m;
-+    if (!MD2_Init(&c))
-+        return NULL;
-+#ifndef CHARSET_EBCDIC
-+    MD2_Update(&c, d, n);
-+#else
-+    {
-+        char temp[1024];
-+        unsigned long chunk;
-+
-+        while (n > 0) {
-+            chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
-+            ebcdic2ascii(temp, d, chunk);
-+            MD2_Update(&c, temp, chunk);
-+            n -= chunk;
-+            d += chunk;
-+        }
-+    }
-+#endif
-+    MD2_Final(md, &c);
-+    OPENSSL_cleanse(&c, sizeof(c)); /* Security consideration */
-+    return (md);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/build.info
-new file mode 100644
-index 0000000..20846e0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        md4_dgst.c md4_one.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_dgst.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_dgst.c
-new file mode 100644
-index 0000000..5319618
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_dgst.c
-@@ -0,0 +1,147 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "md4_locl.h"
-+
-+/*
-+ * Implemented from RFC1186 The MD4 Message-Digest Algorithm
-+ */
-+
-+#define INIT_DATA_A (unsigned long)0x67452301L
-+#define INIT_DATA_B (unsigned long)0xefcdab89L
-+#define INIT_DATA_C (unsigned long)0x98badcfeL
-+#define INIT_DATA_D (unsigned long)0x10325476L
-+
-+int MD4_Init(MD4_CTX *c)
-+{
-+    memset(c, 0, sizeof(*c));
-+    c->A = INIT_DATA_A;
-+    c->B = INIT_DATA_B;
-+    c->C = INIT_DATA_C;
-+    c->D = INIT_DATA_D;
-+    return 1;
-+}
-+
-+#ifndef md4_block_data_order
-+# ifdef X
-+#  undef X
-+# endif
-+void md4_block_data_order(MD4_CTX *c, const void *data_, size_t num)
-+{
-+    const unsigned char *data = data_;
-+    register unsigned MD32_REG_T A, B, C, D, l;
-+# ifndef MD32_XARRAY
-+    /* See comment in crypto/sha/sha_locl.h for details. */
-+    unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
-+        XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
-+#  define X(i)   XX##i
-+# else
-+    MD4_LONG XX[MD4_LBLOCK];
-+#  define X(i)   XX[i]
-+# endif
-+
-+    A = c->A;
-+    B = c->B;
-+    C = c->C;
-+    D = c->D;
-+
-+    for (; num--;) {
-+        (void)HOST_c2l(data, l);
-+        X(0) = l;
-+        (void)HOST_c2l(data, l);
-+        X(1) = l;
-+        /* Round 0 */
-+        R0(A, B, C, D, X(0), 3, 0);
-+        (void)HOST_c2l(data, l);
-+        X(2) = l;
-+        R0(D, A, B, C, X(1), 7, 0);
-+        (void)HOST_c2l(data, l);
-+        X(3) = l;
-+        R0(C, D, A, B, X(2), 11, 0);
-+        (void)HOST_c2l(data, l);
-+        X(4) = l;
-+        R0(B, C, D, A, X(3), 19, 0);
-+        (void)HOST_c2l(data, l);
-+        X(5) = l;
-+        R0(A, B, C, D, X(4), 3, 0);
-+        (void)HOST_c2l(data, l);
-+        X(6) = l;
-+        R0(D, A, B, C, X(5), 7, 0);
-+        (void)HOST_c2l(data, l);
-+        X(7) = l;
-+        R0(C, D, A, B, X(6), 11, 0);
-+        (void)HOST_c2l(data, l);
-+        X(8) = l;
-+        R0(B, C, D, A, X(7), 19, 0);
-+        (void)HOST_c2l(data, l);
-+        X(9) = l;
-+        R0(A, B, C, D, X(8), 3, 0);
-+        (void)HOST_c2l(data, l);
-+        X(10) = l;
-+        R0(D, A, B, C, X(9), 7, 0);
-+        (void)HOST_c2l(data, l);
-+        X(11) = l;
-+        R0(C, D, A, B, X(10), 11, 0);
-+        (void)HOST_c2l(data, l);
-+        X(12) = l;
-+        R0(B, C, D, A, X(11), 19, 0);
-+        (void)HOST_c2l(data, l);
-+        X(13) = l;
-+        R0(A, B, C, D, X(12), 3, 0);
-+        (void)HOST_c2l(data, l);
-+        X(14) = l;
-+        R0(D, A, B, C, X(13), 7, 0);
-+        (void)HOST_c2l(data, l);
-+        X(15) = l;
-+        R0(C, D, A, B, X(14), 11, 0);
-+        R0(B, C, D, A, X(15), 19, 0);
-+        /* Round 1 */
-+        R1(A, B, C, D, X(0), 3, 0x5A827999L);
-+        R1(D, A, B, C, X(4), 5, 0x5A827999L);
-+        R1(C, D, A, B, X(8), 9, 0x5A827999L);
-+        R1(B, C, D, A, X(12), 13, 0x5A827999L);
-+        R1(A, B, C, D, X(1), 3, 0x5A827999L);
-+        R1(D, A, B, C, X(5), 5, 0x5A827999L);
-+        R1(C, D, A, B, X(9), 9, 0x5A827999L);
-+        R1(B, C, D, A, X(13), 13, 0x5A827999L);
-+        R1(A, B, C, D, X(2), 3, 0x5A827999L);
-+        R1(D, A, B, C, X(6), 5, 0x5A827999L);
-+        R1(C, D, A, B, X(10), 9, 0x5A827999L);
-+        R1(B, C, D, A, X(14), 13, 0x5A827999L);
-+        R1(A, B, C, D, X(3), 3, 0x5A827999L);
-+        R1(D, A, B, C, X(7), 5, 0x5A827999L);
-+        R1(C, D, A, B, X(11), 9, 0x5A827999L);
-+        R1(B, C, D, A, X(15), 13, 0x5A827999L);
-+        /* Round 2 */
-+        R2(A, B, C, D, X(0), 3, 0x6ED9EBA1L);
-+        R2(D, A, B, C, X(8), 9, 0x6ED9EBA1L);
-+        R2(C, D, A, B, X(4), 11, 0x6ED9EBA1L);
-+        R2(B, C, D, A, X(12), 15, 0x6ED9EBA1L);
-+        R2(A, B, C, D, X(2), 3, 0x6ED9EBA1L);
-+        R2(D, A, B, C, X(10), 9, 0x6ED9EBA1L);
-+        R2(C, D, A, B, X(6), 11, 0x6ED9EBA1L);
-+        R2(B, C, D, A, X(14), 15, 0x6ED9EBA1L);
-+        R2(A, B, C, D, X(1), 3, 0x6ED9EBA1L);
-+        R2(D, A, B, C, X(9), 9, 0x6ED9EBA1L);
-+        R2(C, D, A, B, X(5), 11, 0x6ED9EBA1L);
-+        R2(B, C, D, A, X(13), 15, 0x6ED9EBA1L);
-+        R2(A, B, C, D, X(3), 3, 0x6ED9EBA1L);
-+        R2(D, A, B, C, X(11), 9, 0x6ED9EBA1L);
-+        R2(C, D, A, B, X(7), 11, 0x6ED9EBA1L);
-+        R2(B, C, D, A, X(15), 15, 0x6ED9EBA1L);
-+
-+        A = c->A += A;
-+        B = c->B += B;
-+        C = c->C += C;
-+        D = c->D += D;
-+    }
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_locl.h
-new file mode 100644
-index 0000000..6aec556
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_locl.h
-@@ -0,0 +1,60 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+void md4_block_data_order(MD4_CTX *c, const void *p, size_t num);
-+
-+#define DATA_ORDER_IS_LITTLE_ENDIAN
-+
-+#define HASH_LONG               MD4_LONG
-+#define HASH_CTX                MD4_CTX
-+#define HASH_CBLOCK             MD4_CBLOCK
-+#define HASH_UPDATE             MD4_Update
-+#define HASH_TRANSFORM          MD4_Transform
-+#define HASH_FINAL              MD4_Final
-+#define HASH_MAKE_STRING(c,s)   do {    \
-+        unsigned long ll;               \
-+        ll=(c)->A; (void)HOST_l2c(ll,(s));      \
-+        ll=(c)->B; (void)HOST_l2c(ll,(s));      \
-+        ll=(c)->C; (void)HOST_l2c(ll,(s));      \
-+        ll=(c)->D; (void)HOST_l2c(ll,(s));      \
-+        } while (0)
-+#define HASH_BLOCK_DATA_ORDER   md4_block_data_order
-+
-+#include "internal/md32_common.h"
-+
-+/*-
-+#define F(x,y,z)        (((x) & (y))  |  ((~(x)) & (z)))
-+#define G(x,y,z)        (((x) & (y))  |  ((x) & ((z))) | ((y) & ((z))))
-+*/
-+
-+/*
-+ * As pointed out by Wei Dai , the above can be simplified
-+ * to the code below.  Wei attributes these optimizations to Peter Gutmann's
-+ * SHS code, and he attributes it to Rich Schroeppel.
-+ */
-+#define F(b,c,d)        ((((c) ^ (d)) & (b)) ^ (d))
-+#define G(b,c,d)        (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
-+#define H(b,c,d)        ((b) ^ (c) ^ (d))
-+
-+#define R0(a,b,c,d,k,s,t) { \
-+        a+=((k)+(t)+F((b),(c),(d))); \
-+        a=ROTATE(a,s); };
-+
-+#define R1(a,b,c,d,k,s,t) { \
-+        a+=((k)+(t)+G((b),(c),(d))); \
-+        a=ROTATE(a,s); };\
-+
-+#define R2(a,b,c,d,k,s,t) { \
-+        a+=((k)+(t)+H((b),(c),(d))); \
-+        a=ROTATE(a,s); };
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_one.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_one.c
-new file mode 100644
-index 0000000..9f0989f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md4/md4_one.c
-@@ -0,0 +1,47 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifdef CHARSET_EBCDIC
-+# include 
-+#endif
-+
-+unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md)
-+{
-+    MD4_CTX c;
-+    static unsigned char m[MD4_DIGEST_LENGTH];
-+
-+    if (md == NULL)
-+        md = m;
-+    if (!MD4_Init(&c))
-+        return NULL;
-+#ifndef CHARSET_EBCDIC
-+    MD4_Update(&c, d, n);
-+#else
-+    {
-+        char temp[1024];
-+        unsigned long chunk;
-+
-+        while (n > 0) {
-+            chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
-+            ebcdic2ascii(temp, d, chunk);
-+            MD4_Update(&c, temp, chunk);
-+            n -= chunk;
-+            d += chunk;
-+        }
-+    }
-+#endif
-+    MD4_Final(md, &c);
-+    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
-+    return (md);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-586.pl
-new file mode 100644
-index 0000000..24f68af
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-586.pl
-@@ -0,0 +1,318 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# Normal is the
-+# md5_block_x86(MD5_CTX *c, ULONG *X);
-+# version, non-normal is the
-+# md5_block_x86(MD5_CTX *c, ULONG *X,int blocks);
-+
-+$normal=0;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],$0);
-+
-+$A="eax";
-+$B="ebx";
-+$C="ecx";
-+$D="edx";
-+$tmp1="edi";
-+$tmp2="ebp";
-+$X="esi";
-+
-+# What we need to load into $tmp for the next round
-+%Ltmp1=("R0",&Np($C), "R1",&Np($C), "R2",&Np($C), "R3",&Np($D));
-+@xo=(
-+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,	# R0
-+ 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,	# R1
-+ 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,	# R2
-+ 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9,	# R3
-+ );
-+
-+&md5_block("md5_block_asm_data_order");
-+&asm_finish();
-+
-+close STDOUT;
-+
-+sub Np
-+	{
-+	local($p)=@_;
-+	local(%n)=($A,$D,$B,$A,$C,$B,$D,$C);
-+	return($n{$p});
-+	}
-+
-+sub R0
-+	{
-+	local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
-+
-+	&mov($tmp1,$C)  if $pos < 0;
-+	&mov($tmp2,&DWP($xo[$ki]*4,$K,"",0)) if $pos < 0; # very first one 
-+
-+	# body proper
-+
-+	&comment("R0 $ki");
-+	&xor($tmp1,$d); # F function - part 2
-+
-+	&and($tmp1,$b); # F function - part 3
-+	&lea($a,&DWP($t,$a,$tmp2,1));
-+
-+	&xor($tmp1,$d); # F function - part 4
-+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
-+
-+	&add($a,$tmp1);
-+
-+	&rotl($a,$s);
-+
-+	&mov($tmp1,&Np($c)) if $pos < 1;	# next tmp1 for R0
-+	&mov($tmp1,&Np($c)) if $pos == 1;	# next tmp1 for R1
-+
-+	&add($a,$b);
-+	}
-+
-+sub R1
-+	{
-+	local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
-+
-+	&comment("R1 $ki");
-+
-+	&xor($tmp1,$b); # G function - part 2
-+	&and($tmp1,$d); # G function - part 3
-+	&lea($a,&DWP($t,$a,$tmp2,1));
-+
-+	&xor($tmp1,$c);			# G function - part 4
-+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
-+
-+	&add($a,$tmp1);
-+	&mov($tmp1,&Np($c)) if $pos < 1;	# G function - part 1
-+	&mov($tmp1,&Np($c)) if $pos == 1;	# G function - part 1
-+
-+	&rotl($a,$s);
-+
-+	&add($a,$b);
-+	}
-+
-+sub R2
-+	{
-+	local($n,$pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
-+	# This one is different, only 3 logical operations
-+
-+if (($n & 1) == 0)
-+	{
-+	&comment("R2 $ki");
-+	# make sure to do 'D' first, not 'B', else we clash with
-+	# the last add from the previous round.
-+
-+	&xor($tmp1,$d); # H function - part 2
-+
-+	&xor($tmp1,$b); # H function - part 3
-+	&lea($a,&DWP($t,$a,$tmp2,1));
-+
-+	&add($a,$tmp1);
-+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0));
-+
-+	&rotl($a,$s);
-+
-+	&mov($tmp1,&Np($c));
-+	}
-+else
-+	{
-+	&comment("R2 $ki");
-+	# make sure to do 'D' first, not 'B', else we clash with
-+	# the last add from the previous round.
-+
-+	&add($b,$c);			# MOVED FORWARD
-+	&xor($tmp1,$d); # H function - part 2
-+
-+	&lea($a,&DWP($t,$a,$tmp2,1));
-+
-+	&xor($tmp1,$b); # H function - part 3
-+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
-+
-+	&add($a,$tmp1);
-+	&mov($tmp1,&Np($c)) if $pos < 1;	# H function - part 1
-+	&mov($tmp1,-1) if $pos == 1;		# I function - part 1
-+
-+	&rotl($a,$s);
-+
-+	&add($a,$b);
-+	}
-+	}
-+
-+sub R3
-+	{
-+	local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
-+
-+	&comment("R3 $ki");
-+
-+	# ¬($tmp1)
-+	&xor($tmp1,$d) if $pos < 0; 	# I function - part 2
-+
-+	&or($tmp1,$b);				# I function - part 3
-+	&lea($a,&DWP($t,$a,$tmp2,1));
-+
-+	&xor($tmp1,$c); 			# I function - part 4
-+	&mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0))	if $pos != 2; # load X/k value
-+	&mov($tmp2,&wparam(0)) if $pos == 2;
-+
-+	&add($a,$tmp1);
-+	&mov($tmp1,-1) if $pos < 1;	# H function - part 1
-+	&add($K,64) if $pos >=1 && !$normal;
-+
-+	&rotl($a,$s);
-+
-+	&xor($tmp1,&Np($d)) if $pos <= 0; 	# I function - part = first time
-+	&mov($tmp1,&DWP( 0,$tmp2,"",0)) if $pos > 0;
-+	&add($a,$b);
-+	}
-+
-+
-+sub md5_block
-+	{
-+	local($name)=@_;
-+
-+	&function_begin_B($name,"",3);
-+
-+	# parameter 1 is the MD5_CTX structure.
-+	# A	0
-+	# B	4
-+	# C	8
-+	# D 	12
-+
-+	&push("esi");
-+	 &push("edi");
-+	&mov($tmp1,	&wparam(0)); # edi
-+	 &mov($X,	&wparam(1)); # esi
-+	&mov($C,	&wparam(2));
-+	 &push("ebp");
-+	&shl($C,	6);
-+	&push("ebx");
-+	 &add($C,	$X); # offset we end at
-+	&sub($C,	64);
-+	 &mov($A,	&DWP( 0,$tmp1,"",0));
-+	&push($C);	# Put on the TOS
-+	 &mov($B,	&DWP( 4,$tmp1,"",0));
-+	&mov($C,	&DWP( 8,$tmp1,"",0));
-+	 &mov($D,	&DWP(12,$tmp1,"",0));
-+
-+	&set_label("start") unless $normal;
-+	&comment("");
-+	&comment("R0 section");
-+
-+	&R0(-2,$A,$B,$C,$D,$X, 0, 7,0xd76aa478);
-+	&R0( 0,$D,$A,$B,$C,$X, 1,12,0xe8c7b756);
-+	&R0( 0,$C,$D,$A,$B,$X, 2,17,0x242070db);
-+	&R0( 0,$B,$C,$D,$A,$X, 3,22,0xc1bdceee);
-+	&R0( 0,$A,$B,$C,$D,$X, 4, 7,0xf57c0faf);
-+	&R0( 0,$D,$A,$B,$C,$X, 5,12,0x4787c62a);
-+	&R0( 0,$C,$D,$A,$B,$X, 6,17,0xa8304613);
-+	&R0( 0,$B,$C,$D,$A,$X, 7,22,0xfd469501);
-+	&R0( 0,$A,$B,$C,$D,$X, 8, 7,0x698098d8);
-+	&R0( 0,$D,$A,$B,$C,$X, 9,12,0x8b44f7af);
-+	&R0( 0,$C,$D,$A,$B,$X,10,17,0xffff5bb1);
-+	&R0( 0,$B,$C,$D,$A,$X,11,22,0x895cd7be);
-+	&R0( 0,$A,$B,$C,$D,$X,12, 7,0x6b901122);
-+	&R0( 0,$D,$A,$B,$C,$X,13,12,0xfd987193);
-+	&R0( 0,$C,$D,$A,$B,$X,14,17,0xa679438e);
-+	&R0( 1,$B,$C,$D,$A,$X,15,22,0x49b40821);
-+
-+	&comment("");
-+	&comment("R1 section");
-+	&R1(-1,$A,$B,$C,$D,$X,16, 5,0xf61e2562);
-+	&R1( 0,$D,$A,$B,$C,$X,17, 9,0xc040b340);
-+	&R1( 0,$C,$D,$A,$B,$X,18,14,0x265e5a51);
-+	&R1( 0,$B,$C,$D,$A,$X,19,20,0xe9b6c7aa);
-+	&R1( 0,$A,$B,$C,$D,$X,20, 5,0xd62f105d);
-+	&R1( 0,$D,$A,$B,$C,$X,21, 9,0x02441453);
-+	&R1( 0,$C,$D,$A,$B,$X,22,14,0xd8a1e681);
-+	&R1( 0,$B,$C,$D,$A,$X,23,20,0xe7d3fbc8);
-+	&R1( 0,$A,$B,$C,$D,$X,24, 5,0x21e1cde6);
-+	&R1( 0,$D,$A,$B,$C,$X,25, 9,0xc33707d6);
-+	&R1( 0,$C,$D,$A,$B,$X,26,14,0xf4d50d87);
-+	&R1( 0,$B,$C,$D,$A,$X,27,20,0x455a14ed);
-+	&R1( 0,$A,$B,$C,$D,$X,28, 5,0xa9e3e905);
-+	&R1( 0,$D,$A,$B,$C,$X,29, 9,0xfcefa3f8);
-+	&R1( 0,$C,$D,$A,$B,$X,30,14,0x676f02d9);
-+	&R1( 1,$B,$C,$D,$A,$X,31,20,0x8d2a4c8a);
-+
-+	&comment("");
-+	&comment("R2 section");
-+	&R2( 0,-1,$A,$B,$C,$D,$X,32, 4,0xfffa3942);
-+	&R2( 1, 0,$D,$A,$B,$C,$X,33,11,0x8771f681);
-+	&R2( 2, 0,$C,$D,$A,$B,$X,34,16,0x6d9d6122);
-+	&R2( 3, 0,$B,$C,$D,$A,$X,35,23,0xfde5380c);
-+	&R2( 4, 0,$A,$B,$C,$D,$X,36, 4,0xa4beea44);
-+	&R2( 5, 0,$D,$A,$B,$C,$X,37,11,0x4bdecfa9);
-+	&R2( 6, 0,$C,$D,$A,$B,$X,38,16,0xf6bb4b60);
-+	&R2( 7, 0,$B,$C,$D,$A,$X,39,23,0xbebfbc70);
-+	&R2( 8, 0,$A,$B,$C,$D,$X,40, 4,0x289b7ec6);
-+	&R2( 9, 0,$D,$A,$B,$C,$X,41,11,0xeaa127fa);
-+	&R2(10, 0,$C,$D,$A,$B,$X,42,16,0xd4ef3085);
-+	&R2(11, 0,$B,$C,$D,$A,$X,43,23,0x04881d05);
-+	&R2(12, 0,$A,$B,$C,$D,$X,44, 4,0xd9d4d039);
-+	&R2(13, 0,$D,$A,$B,$C,$X,45,11,0xe6db99e5);
-+	&R2(14, 0,$C,$D,$A,$B,$X,46,16,0x1fa27cf8);
-+	&R2(15, 1,$B,$C,$D,$A,$X,47,23,0xc4ac5665);
-+
-+	&comment("");
-+	&comment("R3 section");
-+	&R3(-1,$A,$B,$C,$D,$X,48, 6,0xf4292244);
-+	&R3( 0,$D,$A,$B,$C,$X,49,10,0x432aff97);
-+	&R3( 0,$C,$D,$A,$B,$X,50,15,0xab9423a7);
-+	&R3( 0,$B,$C,$D,$A,$X,51,21,0xfc93a039);
-+	&R3( 0,$A,$B,$C,$D,$X,52, 6,0x655b59c3);
-+	&R3( 0,$D,$A,$B,$C,$X,53,10,0x8f0ccc92);
-+	&R3( 0,$C,$D,$A,$B,$X,54,15,0xffeff47d);
-+	&R3( 0,$B,$C,$D,$A,$X,55,21,0x85845dd1);
-+	&R3( 0,$A,$B,$C,$D,$X,56, 6,0x6fa87e4f);
-+	&R3( 0,$D,$A,$B,$C,$X,57,10,0xfe2ce6e0);
-+	&R3( 0,$C,$D,$A,$B,$X,58,15,0xa3014314);
-+	&R3( 0,$B,$C,$D,$A,$X,59,21,0x4e0811a1);
-+	&R3( 0,$A,$B,$C,$D,$X,60, 6,0xf7537e82);
-+	&R3( 0,$D,$A,$B,$C,$X,61,10,0xbd3af235);
-+	&R3( 0,$C,$D,$A,$B,$X,62,15,0x2ad7d2bb);
-+	&R3( 2,$B,$C,$D,$A,$X,63,21,0xeb86d391);
-+
-+	# &mov($tmp2,&wparam(0));	# done in the last R3
-+	# &mov($tmp1,	&DWP( 0,$tmp2,"",0)); # done is the last R3
-+
-+	&add($A,$tmp1);
-+	 &mov($tmp1,	&DWP( 4,$tmp2,"",0));
-+
-+	&add($B,$tmp1);
-+	&mov($tmp1,	&DWP( 8,$tmp2,"",0));
-+
-+	&add($C,$tmp1);
-+	&mov($tmp1,	&DWP(12,$tmp2,"",0));
-+
-+	&add($D,$tmp1);
-+	&mov(&DWP( 0,$tmp2,"",0),$A);
-+
-+	&mov(&DWP( 4,$tmp2,"",0),$B);
-+	&mov($tmp1,&swtmp(0)) unless $normal;
-+
-+	&mov(&DWP( 8,$tmp2,"",0),$C);
-+	 &mov(&DWP(12,$tmp2,"",0),$D);
-+
-+	&cmp($tmp1,$X) unless $normal;			# check count
-+	 &jae(&label("start")) unless $normal;
-+
-+	&pop("eax"); # pop the temp variable off the stack
-+	 &pop("ebx");
-+	&pop("ebp");
-+	 &pop("edi");
-+	&pop("esi");
-+	 &ret();
-+	&function_end_B($name);
-+	}
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-ia64.S b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-ia64.S
-new file mode 100644
-index 0000000..c20467b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-ia64.S
-@@ -0,0 +1,1002 @@
-+/*
-+ *
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
-+
-+Permission is hereby granted, free of charge, to any person obtaining
-+a copy of this software and associated documentation files (the
-+"Software"), to deal in the Software without restriction, including
-+without limitation the rights to use, copy, modify, merge, publish,
-+distribute, sublicense, and/or sell copies of the Software, and to
-+permit persons to whom the Software is furnished to do so, subject to
-+the following conditions:
-+
-+The above copyright notice and this permission notice shall be
-+included in all copies or substantial portions of the Software.
-+
-+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
-+
-+//	Common registers are assigned as follows:
-+//
-+//	COMMON
-+//
-+//	t0		Const Tbl Ptr	TPtr
-+//	t1		Round Constant	TRound
-+//	t4		Block residual	LenResid
-+//	t5		Residual Data	DTmp
-+//
-+//	{in,out}0	Block 0 Cycle	RotateM0
-+//	{in,out}1	Block Value 12	M12
-+//	{in,out}2	Block Value 8	M8
-+//	{in,out}3	Block Value 4	M4
-+//	{in,out}4	Block Value 0	M0
-+//	{in,out}5	Block 1 Cycle	RotateM1
-+//	{in,out}6	Block Value 13	M13
-+//	{in,out}7	Block Value 9	M9
-+//	{in,out}8	Block Value 5	M5
-+//	{in,out}9	Block Value 1	M1
-+//	{in,out}10	Block 2 Cycle	RotateM2
-+//	{in,out}11	Block Value 14	M14
-+//	{in,out}12	Block Value 10	M10
-+//	{in,out}13	Block Value 6	M6
-+//	{in,out}14	Block Value 2	M2
-+//	{in,out}15	Block 3 Cycle	RotateM3
-+//	{in,out}16	Block Value 15	M15
-+//	{in,out}17	Block Value 11	M11
-+//	{in,out}18	Block Value 7	M7
-+//	{in,out}19	Block Value 3	M3
-+//	{in,out}20	Scratch			Z
-+//	{in,out}21	Scratch			Y
-+//	{in,out}22	Scratch			X
-+//	{in,out}23	Scratch			W
-+//	{in,out}24	Digest A		A
-+//	{in,out}25	Digest B		B
-+//	{in,out}26	Digest C		C
-+//	{in,out}27	Digest D		D
-+//	{in,out}28	Active Data Ptr	DPtr
-+//	in28		Dummy Value		-
-+//	out28		Dummy Value		-
-+//	bt0			Coroutine Link	QUICK_RTN
-+//
-+///	These predicates are used for computing the padding block(s) and
-+///	are shared between the driver and digest co-routines
-+//
-+//	pt0			Extra Pad Block	pExtra
-+//	pt1			Load next word	pLoad
-+//	pt2			Skip next word	pSkip
-+//	pt3			Search for Pad	pNoPad
-+//	pt4			Pad Word 0		pPad0
-+//	pt5			Pad Word 1		pPad1
-+//	pt6			Pad Word 2		pPad2
-+//	pt7			Pad Word 3		pPad3
-+
-+#define	DTmp		r19
-+#define	LenResid	r18
-+#define	QUICK_RTN	b6
-+#define	TPtr		r14
-+#define	TRound		r15
-+#define	pExtra		p6
-+#define	pLoad		p7
-+#define	pNoPad		p9
-+#define	pPad0		p10
-+#define	pPad1		p11
-+#define	pPad2		p12
-+#define	pPad3		p13
-+#define	pSkip		p8
-+
-+#define	A_		out24
-+#define	B_		out25
-+#define	C_		out26
-+#define	D_		out27
-+#define	DPtr_		out28
-+#define	M0_		out4
-+#define	M1_		out9
-+#define	M10_		out12
-+#define	M11_		out17
-+#define	M12_		out1
-+#define	M13_		out6
-+#define	M14_		out11
-+#define	M15_		out16
-+#define	M2_		out14
-+#define	M3_		out19
-+#define	M4_		out3
-+#define	M5_		out8
-+#define	M6_		out13
-+#define	M7_		out18
-+#define	M8_		out2
-+#define	M9_		out7
-+#define	RotateM0_	out0
-+#define	RotateM1_	out5
-+#define	RotateM2_	out10
-+#define	RotateM3_	out15
-+#define	W_		out23
-+#define	X_		out22
-+#define	Y_		out21
-+#define	Z_		out20
-+
-+#define	A		in24
-+#define	B		in25
-+#define	C		in26
-+#define	D		in27
-+#define	DPtr		in28
-+#define	M0		in4
-+#define	M1		in9
-+#define	M10		in12
-+#define	M11		in17
-+#define	M12		in1
-+#define	M13		in6
-+#define	M14		in11
-+#define	M15		in16
-+#define	M2		in14
-+#define	M3		in19
-+#define	M4		in3
-+#define	M5		in8
-+#define	M6		in13
-+#define	M7		in18
-+#define	M8		in2
-+#define	M9		in7
-+#define	RotateM0	in0
-+#define	RotateM1	in5
-+#define	RotateM2	in10
-+#define	RotateM3	in15
-+#define	W		in23
-+#define	X		in22
-+#define	Y		in21
-+#define	Z		in20
-+
-+/* register stack configuration for md5_block_asm_data_order(): */
-+#define	MD5_NINP	3
-+#define	MD5_NLOC	0
-+#define MD5_NOUT	29
-+#define MD5_NROT	0
-+
-+/* register stack configuration for helpers: */
-+#define	_NINPUTS	MD5_NOUT
-+#define	_NLOCALS	0
-+#define _NOUTPUT	0
-+#define	_NROTATE	24	/* this must be <= _NINPUTS */
-+
-+#if defined(_HPUX_SOURCE) && !defined(_LP64)
-+#define	ADDP	addp4
-+#else
-+#define	ADDP	add
-+#endif
-+
-+#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
-+#define HOST_IS_BIG_ENDIAN
-+#endif
-+
-+//	Macros for getting the left and right portions of little-endian words
-+
-+#define	GETLW(dst, src, align)	dep.z dst = src, 32 - 8 * align, 8 * align
-+#define	GETRW(dst, src, align)	extr.u dst = src, 8 * align, 32 - 8 * align
-+
-+//	MD5 driver
-+//
-+//		Reads an input block, then calls the digest block
-+//		subroutine and adds the results to the accumulated
-+//		digest.  It allocates 32 outs which the subroutine
-+//		uses as it's inputs and rotating
-+//		registers. Initializes the round constant pointer and
-+//		takes care of saving/restoring ar.lc
-+//
-+///	INPUT
-+//
-+//	in0		Context Ptr		CtxPtr0
-+//	in1		Input Data Ptr		DPtrIn
-+//	in2		Integral Blocks		BlockCount
-+//	rp		Return Address		-
-+//
-+///	CODE
-+//
-+//	v2		Input Align		InAlign
-+//	t0		Shared w/digest		-
-+//	t1		Shared w/digest		-
-+//	t2		Shared w/digest		-
-+//	t3		Shared w/digest		-
-+//	t4		Shared w/digest		-
-+//	t5		Shared w/digest		-
-+//	t6		PFS Save		PFSSave
-+//	t7		ar.lc Save		LCSave
-+//	t8		Saved PR		PRSave
-+//	t9		2nd CtxPtr		CtxPtr1
-+//	t10		Table Base		CTable
-+//	t11		Table[0]		CTable0
-+//	t13		Accumulator A		AccumA
-+//	t14		Accumulator B		AccumB
-+//	t15		Accumulator C		AccumC
-+//	t16		Accumulator D		AccumD
-+//	pt0		Shared w/digest		-
-+//	pt1		Shared w/digest		-
-+//	pt2		Shared w/digest		-
-+//	pt3		Shared w/digest		-
-+//	pt4		Shared w/digest		-
-+//	pt5		Shared w/digest		-
-+//	pt6		Shared w/digest		-
-+//	pt7		Shared w/digest		-
-+//	pt8		Not Aligned		pOff
-+//	pt8		Blocks Left		pAgain
-+
-+#define	AccumA		r27
-+#define	AccumB		r28
-+#define	AccumC		r29
-+#define	AccumD		r30
-+#define	CTable		r24
-+#define	CTable0		r25
-+#define	CtxPtr0		in0
-+#define	CtxPtr1		r23
-+#define	DPtrIn		in1
-+#define	BlockCount	in2
-+#define	InAlign		r10
-+#define	LCSave		r21
-+#define	PFSSave		r20
-+#define	PRSave		r22
-+#define	pAgain		p63
-+#define	pOff		p63
-+
-+	.text
-+
-+/* md5_block_asm_data_order(MD5_CTX *c, const void *data, size_t num)
-+
-+     where:
-+      c: a pointer to a structure of this type:
-+
-+	   typedef struct MD5state_st
-+	     {
-+	       MD5_LONG A,B,C,D;
-+	       MD5_LONG Nl,Nh;
-+	       MD5_LONG data[MD5_LBLOCK];
-+	       unsigned int num;
-+	     }
-+	   MD5_CTX;
-+
-+      data: a pointer to the input data (may be misaligned)
-+      num:  the number of 16-byte blocks to hash (i.e., the length
-+            of DATA is 16*NUM.
-+
-+   */
-+
-+	.type	md5_block_asm_data_order, @function
-+	.global	md5_block_asm_data_order
-+	.align	32
-+	.proc	md5_block_asm_data_order
-+md5_block_asm_data_order:
-+.md5_block:
-+	.prologue
-+{	.mmi
-+	.save	ar.pfs, PFSSave
-+	alloc	PFSSave = ar.pfs, MD5_NINP, MD5_NLOC, MD5_NOUT, MD5_NROT
-+	ADDP	CtxPtr1 = 8, CtxPtr0
-+	mov	CTable = ip
-+}
-+{	.mmi
-+	ADDP	DPtrIn = 0, DPtrIn
-+	ADDP	CtxPtr0 = 0, CtxPtr0
-+	.save	ar.lc, LCSave
-+	mov	LCSave = ar.lc
-+}
-+;;
-+{	.mmi
-+	add	CTable = .md5_tbl_data_order#-.md5_block#, CTable
-+	and	InAlign = 0x3, DPtrIn
-+}
-+
-+{	.mmi
-+	ld4	AccumA = [CtxPtr0], 4
-+	ld4	AccumC = [CtxPtr1], 4
-+	.save pr, PRSave
-+	mov	PRSave = pr
-+	.body
-+}
-+;;
-+{	.mmi
-+	ld4	AccumB = [CtxPtr0]
-+	ld4	AccumD = [CtxPtr1]
-+	dep	DPtr_ = 0, DPtrIn, 0, 2
-+} ;;
-+#ifdef HOST_IS_BIG_ENDIAN
-+	rum	psr.be;;	// switch to little-endian
-+#endif
-+{	.mmb
-+	ld4	CTable0 = [CTable], 4
-+	cmp.ne	pOff, p0 = 0, InAlign
-+(pOff)	br.cond.spnt.many .md5_unaligned
-+} ;;
-+
-+//	The FF load/compute loop rotates values three times, so that
-+//	loading into M12 here produces the M0 value, M13 -> M1, etc.
-+
-+.md5_block_loop0:
-+{	.mmi
-+	ld4	M12_ = [DPtr_], 4
-+	mov	TPtr = CTable
-+	mov	TRound = CTable0
-+} ;;
-+{	.mmi
-+	ld4	M13_ = [DPtr_], 4
-+	mov	A_ = AccumA
-+	mov	B_ = AccumB
-+} ;;
-+{	.mmi
-+	ld4	M14_ = [DPtr_], 4
-+	mov	C_ = AccumC
-+	mov	D_ = AccumD
-+} ;;
-+{	.mmb
-+	ld4	M15_ = [DPtr_], 4
-+	add	BlockCount = -1, BlockCount
-+	br.call.sptk.many QUICK_RTN = md5_digest_block0
-+} ;;
-+
-+//	Now, we add the new digest values and do some clean-up
-+//	before checking if there's another full block to process
-+
-+{	.mmi
-+	add	AccumA = AccumA, A_
-+	add	AccumB = AccumB, B_
-+	cmp.ne	pAgain, p0 = 0, BlockCount
-+}
-+{	.mib
-+	add	AccumC = AccumC, C_
-+	add	AccumD = AccumD, D_
-+(pAgain) br.cond.dptk.many .md5_block_loop0
-+} ;;
-+
-+.md5_exit:
-+#ifdef HOST_IS_BIG_ENDIAN
-+	sum	psr.be;;	// switch back to big-endian mode
-+#endif
-+{	.mmi
-+	st4	[CtxPtr0] = AccumB, -4
-+	st4	[CtxPtr1] = AccumD, -4
-+	mov	pr = PRSave, 0x1ffff ;;
-+}
-+{	.mmi
-+	st4	[CtxPtr0] = AccumA
-+	st4	[CtxPtr1] = AccumC
-+	mov	ar.lc = LCSave
-+} ;;
-+{	.mib
-+	mov	ar.pfs = PFSSave
-+	br.ret.sptk.few	rp
-+} ;;
-+
-+#define	MD5UNALIGNED(offset)						\
-+.md5_process##offset:							\
-+{	.mib ;								\
-+	nop	0x0	;						\
-+	GETRW(DTmp, DTmp, offset) ;					\
-+} ;;									\
-+.md5_block_loop##offset:						\
-+{	.mmi ;								\
-+	ld4	Y_ = [DPtr_], 4 ;					\
-+	mov	TPtr = CTable ;						\
-+	mov	TRound = CTable0 ;					\
-+} ;;									\
-+{	.mmi ;								\
-+	ld4	M13_ = [DPtr_], 4 ;					\
-+	mov	A_ = AccumA ;						\
-+	mov	B_ = AccumB ;						\
-+} ;;									\
-+{	.mii ;								\
-+	ld4	M14_ = [DPtr_], 4 ;					\
-+	GETLW(W_, Y_, offset) ;						\
-+	mov	C_ = AccumC ;						\
-+}									\
-+{	.mmi ;								\
-+	mov	D_ = AccumD ;;						\
-+	or	M12_ = W_, DTmp ;					\
-+	GETRW(DTmp, Y_, offset) ;					\
-+}									\
-+{	.mib ;								\
-+	ld4	M15_ = [DPtr_], 4 ;					\
-+	add	BlockCount = -1, BlockCount ;				\
-+	br.call.sptk.many QUICK_RTN = md5_digest_block##offset;		\
-+} ;;									\
-+{	.mmi ;								\
-+	add	AccumA = AccumA, A_ ;					\
-+	add	AccumB = AccumB, B_ ;					\
-+	cmp.ne	pAgain, p0 = 0, BlockCount ;				\
-+}									\
-+{	.mib ;								\
-+	add	AccumC = AccumC, C_ ;					\
-+	add	AccumD = AccumD, D_ ;					\
-+(pAgain) br.cond.dptk.many .md5_block_loop##offset ;			\
-+} ;;									\
-+{	.mib ;								\
-+	nop	0x0 ;							\
-+	nop	0x0 ;							\
-+	br.cond.sptk.many .md5_exit ;					\
-+} ;;
-+
-+	.align	32
-+.md5_unaligned:
-+//
-+//	Because variable shifts are expensive, we special case each of
-+//	the four alignements. In practice, this won't hurt too much
-+//	since only one working set of code will be loaded.
-+//
-+{	.mib
-+	ld4	DTmp = [DPtr_], 4
-+	cmp.eq	pOff, p0 = 1, InAlign
-+(pOff)	br.cond.dpnt.many .md5_process1
-+} ;;
-+{	.mib
-+	cmp.eq	pOff, p0 = 2, InAlign
-+	nop	0x0
-+(pOff)	br.cond.dpnt.many .md5_process2
-+} ;;
-+	MD5UNALIGNED(3)
-+	MD5UNALIGNED(1)
-+	MD5UNALIGNED(2)
-+
-+	.endp md5_block_asm_data_order
-+
-+
-+// MD5 Perform the F function and load
-+//
-+// Passed the first 4 words (M0 - M3) and initial (A, B, C, D) values,
-+// computes the FF() round of functions, then branches to the common
-+// digest code to finish up with GG(), HH, and II().
-+//
-+// INPUT
-+//
-+// rp Return Address -
-+//
-+// CODE
-+//
-+// v0 PFS bit bucket PFS
-+// v1 Loop Trip Count LTrip
-+// pt0 Load next word pMore
-+
-+/* For F round: */
-+#define LTrip	r9
-+#define PFS	r8
-+#define pMore	p6
-+
-+/* For GHI rounds: */
-+#define T	r9
-+#define U	r10
-+#define V	r11
-+
-+#define COMPUTE(a, b, s, M, R)			\
-+{						\
-+	.mii ;					\
-+	ld4 TRound = [TPtr], 4 ;		\
-+	dep.z Y = Z, 32, 32 ;;			\
-+	shrp Z = Z, Y, 64 - s ;			\
-+} ;;						\
-+{						\
-+	.mmi ;					\
-+	add a = Z, b ;				\
-+	mov R = M ;				\
-+	nop 0x0 ;				\
-+} ;;
-+
-+#define LOOP(a, b, s, M, R, label)		\
-+{	.mii ;					\
-+	ld4 TRound = [TPtr], 4 ;		\
-+	dep.z Y = Z, 32, 32 ;;			\
-+	shrp Z = Z, Y, 64 - s ;			\
-+} ;;						\
-+{	.mib ;					\
-+	add a = Z, b ;				\
-+	mov R = M ;				\
-+	br.ctop.sptk.many label ;		\
-+} ;;
-+
-+// G(B, C, D) = (B & D) | (C & ~D)
-+
-+#define G(a, b, c, d, M)			\
-+{	.mmi ;					\
-+	add Z = M, TRound ;			\
-+	and Y = b, d ;				\
-+	andcm X = c, d ;			\
-+} ;;						\
-+{	.mii ;					\
-+	add Z = Z, a ;				\
-+	or Y = Y, X ;;				\
-+	add Z = Z, Y ;				\
-+} ;;
-+
-+// H(B, C, D) = B ^ C ^ D
-+
-+#define H(a, b, c, d, M)			\
-+{	.mmi ;					\
-+	add Z = M, TRound ;			\
-+	xor Y = b, c ;				\
-+	nop 0x0 ;				\
-+} ;;						\
-+{	.mii ;					\
-+	add Z = Z, a ;				\
-+	xor Y = Y, d ;;				\
-+	add Z = Z, Y ;				\
-+} ;;
-+
-+// I(B, C, D) = C ^ (B | ~D)
-+//
-+// However, since we have an andcm operator, we use the fact that
-+//
-+// Y ^ Z == ~Y ^ ~Z
-+//
-+// to rewrite the expression as
-+//
-+// I(B, C, D) = ~C ^ (~B & D)
-+
-+#define I(a, b, c, d, M)			\
-+{	.mmi ;					\
-+	add Z = M, TRound ;			\
-+	andcm Y = d, b ;			\
-+	andcm X = -1, c ;			\
-+} ;;						\
-+{	.mii ;					\
-+	add Z = Z, a ;				\
-+	xor Y = Y, X ;;				\
-+	add Z = Z, Y ;				\
-+} ;;
-+
-+#define GG4(label)				\
-+	G(A, B, C, D, M0)			\
-+	COMPUTE(A, B, 5, M0, RotateM0)		\
-+	G(D, A, B, C, M1)			\
-+	COMPUTE(D, A, 9, M1, RotateM1)		\
-+	G(C, D, A, B, M2)			\
-+	COMPUTE(C, D, 14, M2, RotateM2)		\
-+	G(B, C, D, A, M3)			\
-+	LOOP(B, C, 20, M3, RotateM3, label)
-+
-+#define HH4(label)				\
-+	H(A, B, C, D, M0)			\
-+	COMPUTE(A, B, 4, M0, RotateM0)		\
-+	H(D, A, B, C, M1)			\
-+	COMPUTE(D, A, 11, M1, RotateM1)		\
-+	H(C, D, A, B, M2)			\
-+	COMPUTE(C, D, 16, M2, RotateM2)		\
-+	H(B, C, D, A, M3)			\
-+	LOOP(B, C, 23, M3, RotateM3, label)
-+
-+#define II4(label)				\
-+	I(A, B, C, D, M0)			\
-+	COMPUTE(A, B, 6, M0, RotateM0)		\
-+	I(D, A, B, C, M1)			\
-+	COMPUTE(D, A, 10, M1, RotateM1)		\
-+	I(C, D, A, B, M2)			\
-+	COMPUTE(C, D, 15, M2, RotateM2)		\
-+	I(B, C, D, A, M3)			\
-+	LOOP(B, C, 21, M3, RotateM3, label)
-+
-+#define FFLOAD(a, b, c, d, M, N, s)		\
-+{	.mii ;					\
-+(pMore) ld4 N = [DPtr], 4 ;			\
-+	add Z = M, TRound ;			\
-+	and Y = c, b ;				\
-+}						\
-+{	.mmi ;					\
-+	andcm X = d, b ;;			\
-+	add Z = Z, a ;				\
-+	or Y = Y, X ;				\
-+} ;;						\
-+{	.mii ;					\
-+	ld4 TRound = [TPtr], 4 ;		\
-+	add Z = Z, Y ;;				\
-+	dep.z Y = Z, 32, 32 ;			\
-+} ;;						\
-+{	.mii ;					\
-+	nop 0x0 ;				\
-+	shrp Z = Z, Y, 64 - s ;;		\
-+	add a = Z, b ;				\
-+} ;;
-+
-+#define FFLOOP(a, b, c, d, M, N, s, dest)	\
-+{	.mii ;					\
-+(pMore)	ld4 N = [DPtr], 4 ;			\
-+	add Z = M, TRound ;			\
-+	and Y = c, b ;				\
-+}						\
-+{	.mmi ;					\
-+	andcm X = d, b ;;			\
-+	add Z = Z, a ;				\
-+	or Y = Y, X ;				\
-+} ;;						\
-+{	.mii ;					\
-+	ld4 TRound = [TPtr], 4 ;		\
-+	add Z = Z, Y ;;				\
-+	dep.z Y = Z, 32, 32 ;			\
-+} ;;						\
-+{	.mii ;					\
-+	nop 0x0 ;				\
-+	shrp Z = Z, Y, 64 - s ;;		\
-+	add a = Z, b ;				\
-+}						\
-+{	.mib ;					\
-+	cmp.ne pMore, p0 = 0, LTrip ;		\
-+	add LTrip = -1, LTrip ;			\
-+	br.ctop.dptk.many dest ;		\
-+} ;;
-+
-+	.type md5_digest_block0, @function
-+	.align 32
-+
-+	.proc md5_digest_block0
-+	.prologue
-+md5_digest_block0:
-+	.altrp QUICK_RTN
-+	.body
-+{	.mmi
-+	alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
-+	mov LTrip = 2
-+	mov ar.lc = 3
-+} ;;
-+{	.mii
-+	cmp.eq pMore, p0 = r0, r0
-+	mov ar.ec = 0
-+	nop 0x0
-+} ;;
-+
-+.md5_FF_round0:
-+	FFLOAD(A, B, C, D, M12, RotateM0, 7)
-+	FFLOAD(D, A, B, C, M13, RotateM1, 12)
-+	FFLOAD(C, D, A, B, M14, RotateM2, 17)
-+	FFLOOP(B, C, D, A, M15, RotateM3, 22, .md5_FF_round0)
-+	//
-+	// !!! Fall through to md5_digest_GHI
-+	//
-+	.endp md5_digest_block0
-+
-+	.type md5_digest_GHI, @function
-+	.align 32
-+
-+	.proc md5_digest_GHI
-+	.prologue
-+	.regstk _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
-+md5_digest_GHI:
-+	.altrp QUICK_RTN
-+	.body
-+//
-+// The following sequence shuffles the block counstants round for the
-+// next round:
-+//
-+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
-+// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12
-+//
-+{	.mmi
-+	mov Z = M0
-+	mov Y = M15
-+	mov ar.lc = 3
-+}
-+{	.mmi
-+	mov X = M2
-+	mov W = M9
-+	mov V = M4
-+} ;;
-+
-+{	.mmi
-+	mov M0 = M1
-+	mov M15 = M12
-+	mov ar.ec = 1
-+}
-+{	.mmi
-+	mov M2 = M11
-+	mov M9 = M14
-+	mov M4 = M5
-+} ;;
-+
-+{	.mmi
-+	mov M1 = M6
-+	mov M12 = M13
-+	mov U = M3
-+}
-+{	.mmi
-+	mov M11 = M8
-+	mov M14 = M7
-+	mov M5 = M10
-+} ;;
-+
-+{	.mmi
-+	mov M6 = Y
-+	mov M13 = X
-+	mov M3 = Z
-+}
-+{	.mmi
-+	mov M8 = W
-+	mov M7 = V
-+	mov M10 = U
-+} ;;
-+
-+.md5_GG_round:
-+	GG4(.md5_GG_round)
-+
-+// The following sequence shuffles the block constants round for the
-+// next round:
-+//
-+// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12
-+// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
-+
-+{	.mmi
-+	mov Z = M0
-+	mov Y = M1
-+	mov ar.lc = 3
-+}
-+{	.mmi
-+	mov X = M3
-+	mov W = M5
-+	mov V = M6
-+} ;;
-+
-+{	.mmi
-+	mov M0 = M4
-+	mov M1 = M11
-+	mov ar.ec = 1
-+}
-+{	.mmi
-+	mov M3 = M9
-+	mov U = M8
-+	mov T = M13
-+} ;;
-+
-+{	.mmi
-+	mov M4 = Z
-+	mov M11 = Y
-+	mov M5 = M7
-+}
-+{	.mmi
-+	mov M6 = M14
-+	mov M8 = M12
-+	mov M13 = M15
-+} ;;
-+
-+{	.mmi
-+	mov M7 = W
-+	mov M14 = V
-+	nop 0x0
-+}
-+{	.mmi
-+	mov M9 = X
-+	mov M12 = U
-+	mov M15 = T
-+} ;;
-+
-+.md5_HH_round:
-+	HH4(.md5_HH_round)
-+
-+// The following sequence shuffles the block constants round for the
-+// next round:
-+//
-+// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
-+// 0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9
-+
-+{	.mmi
-+	mov Z = M0
-+	mov Y = M15
-+	mov ar.lc = 3
-+}
-+{	.mmi
-+	mov X = M10
-+	mov W = M1
-+	mov V = M4
-+} ;;
-+
-+{	.mmi
-+	mov M0 = M9
-+	mov M15 = M12
-+	mov ar.ec = 1
-+}
-+{	.mmi
-+	mov M10 = M11
-+	mov M1 = M6
-+	mov M4 = M13
-+} ;;
-+
-+{	.mmi
-+	mov M9 = M14
-+	mov M12 = M5
-+	mov U = M3
-+}
-+{	.mmi
-+	mov M11 = M8
-+	mov M6 = M7
-+	mov M13 = M2
-+} ;;
-+
-+{	.mmi
-+	mov M14 = Y
-+	mov M5 = X
-+	mov M3 = Z
-+}
-+{	.mmi
-+	mov M8 = W
-+	mov M7 = V
-+	mov M2 = U
-+} ;;
-+
-+.md5_II_round:
-+	II4(.md5_II_round)
-+
-+{	.mib
-+	nop 0x0
-+	nop 0x0
-+	br.ret.sptk.many QUICK_RTN
-+} ;;
-+
-+	.endp md5_digest_GHI
-+
-+#define FFLOADU(a, b, c, d, M, P, N, s, offset)	\
-+{	.mii ;					\
-+(pMore) ld4 N = [DPtr], 4 ;			\
-+	add Z = M, TRound ;			\
-+	and Y = c, b ;				\
-+}						\
-+{	.mmi ;					\
-+	andcm X = d, b ;;			\
-+	add Z = Z, a ;				\
-+	or Y = Y, X ;				\
-+} ;;						\
-+{	.mii ;					\
-+	ld4 TRound = [TPtr], 4 ;		\
-+	GETLW(W, P, offset) ;			\
-+	add Z = Z, Y ;				\
-+} ;;						\
-+{	.mii ;					\
-+	or W = W, DTmp ;			\
-+	dep.z Y = Z, 32, 32 ;;			\
-+	shrp Z = Z, Y, 64 - s ;			\
-+} ;;						\
-+{	.mii ;					\
-+	add a = Z, b ;				\
-+	GETRW(DTmp, P, offset) ;		\
-+	mov P = W ;				\
-+} ;;
-+
-+#define FFLOOPU(a, b, c, d, M, P, N, s, offset)		\
-+{	.mii ;						\
-+(pMore) ld4 N = [DPtr], 4 ;				\
-+	add Z = M, TRound ;				\
-+	and Y = c, b ;					\
-+}							\
-+{	.mmi ;						\
-+	andcm X = d, b ;;				\
-+	add Z = Z, a ;					\
-+	or Y = Y, X ;					\
-+} ;;							\
-+{	.mii ;						\
-+	ld4 TRound = [TPtr], 4 ;			\
-+(pMore) GETLW(W, P, offset) 	;			\
-+	add Z = Z, Y ;					\
-+} ;;							\
-+{	.mii ;						\
-+(pMore) or W = W, DTmp ;				\
-+	dep.z Y = Z, 32, 32 ;;				\
-+	shrp Z = Z, Y, 64 - s ;				\
-+} ;;							\
-+{	.mii ;						\
-+	add a = Z, b ;					\
-+(pMore) GETRW(DTmp, P, offset) 	;			\
-+(pMore) mov P = W ;					\
-+}							\
-+{	.mib ;						\
-+	cmp.ne pMore, p0 = 0, LTrip ;			\
-+	add LTrip = -1, LTrip ;				\
-+	br.ctop.sptk.many .md5_FF_round##offset ;	\
-+} ;;
-+
-+#define MD5FBLOCK(offset)						\
-+	.type md5_digest_block##offset, @function ;			\
-+									\
-+	.align 32 ;							\
-+	.proc md5_digest_block##offset ;				\
-+	.prologue ;							\
-+	.altrp QUICK_RTN ;						\
-+	.body ;								\
-+md5_digest_block##offset:						\
-+{	.mmi ;								\
-+	alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE ;	\
-+	mov LTrip = 2 ;							\
-+	mov ar.lc = 3 ;							\
-+} ;;									\
-+{	.mii ;								\
-+	cmp.eq pMore, p0 = r0, r0 ;					\
-+	mov ar.ec = 0 ;							\
-+	nop 0x0 ;							\
-+} ;;									\
-+									\
-+	.pred.rel "mutex", pLoad, pSkip ;				\
-+.md5_FF_round##offset:							\
-+	FFLOADU(A, B, C, D, M12, M13, RotateM0, 7, offset)		\
-+	FFLOADU(D, A, B, C, M13, M14, RotateM1, 12, offset)		\
-+	FFLOADU(C, D, A, B, M14, M15, RotateM2, 17, offset)		\
-+	FFLOOPU(B, C, D, A, M15, RotateM0, RotateM3, 22, offset)	\
-+									\
-+{	.mib ;								\
-+	nop 0x0 ;							\
-+	nop 0x0 ;							\
-+	br.cond.sptk.many md5_digest_GHI ;				\
-+} ;;									\
-+	.endp md5_digest_block##offset
-+
-+MD5FBLOCK(1)
-+MD5FBLOCK(2)
-+MD5FBLOCK(3)
-+
-+	.align 64
-+	.type md5_constants, @object
-+md5_constants:
-+.md5_tbl_data_order:			// To ensure little-endian data
-+					// order, code as bytes.
-+	data1 0x78, 0xa4, 0x6a, 0xd7	//     0
-+	data1 0x56, 0xb7, 0xc7, 0xe8	//     1
-+	data1 0xdb, 0x70, 0x20, 0x24	//     2
-+	data1 0xee, 0xce, 0xbd, 0xc1	//     3
-+	data1 0xaf, 0x0f, 0x7c, 0xf5	//     4
-+	data1 0x2a, 0xc6, 0x87, 0x47	//     5
-+	data1 0x13, 0x46, 0x30, 0xa8	//     6
-+	data1 0x01, 0x95, 0x46, 0xfd	//     7
-+	data1 0xd8, 0x98, 0x80, 0x69	//     8
-+	data1 0xaf, 0xf7, 0x44, 0x8b	//     9
-+	data1 0xb1, 0x5b, 0xff, 0xff	//    10
-+	data1 0xbe, 0xd7, 0x5c, 0x89	//    11
-+	data1 0x22, 0x11, 0x90, 0x6b	//    12
-+	data1 0x93, 0x71, 0x98, 0xfd	//    13
-+	data1 0x8e, 0x43, 0x79, 0xa6	//    14
-+	data1 0x21, 0x08, 0xb4, 0x49	//    15
-+	data1 0x62, 0x25, 0x1e, 0xf6	//    16
-+	data1 0x40, 0xb3, 0x40, 0xc0	//    17
-+	data1 0x51, 0x5a, 0x5e, 0x26	//    18
-+	data1 0xaa, 0xc7, 0xb6, 0xe9	//    19
-+	data1 0x5d, 0x10, 0x2f, 0xd6	//    20
-+	data1 0x53, 0x14, 0x44, 0x02	//    21
-+	data1 0x81, 0xe6, 0xa1, 0xd8	//    22
-+	data1 0xc8, 0xfb, 0xd3, 0xe7	//    23
-+	data1 0xe6, 0xcd, 0xe1, 0x21	//    24
-+	data1 0xd6, 0x07, 0x37, 0xc3	//    25
-+	data1 0x87, 0x0d, 0xd5, 0xf4	//    26
-+	data1 0xed, 0x14, 0x5a, 0x45	//    27
-+	data1 0x05, 0xe9, 0xe3, 0xa9	//    28
-+	data1 0xf8, 0xa3, 0xef, 0xfc	//    29
-+	data1 0xd9, 0x02, 0x6f, 0x67	//    30
-+	data1 0x8a, 0x4c, 0x2a, 0x8d	//    31
-+	data1 0x42, 0x39, 0xfa, 0xff	//    32
-+	data1 0x81, 0xf6, 0x71, 0x87	//    33
-+	data1 0x22, 0x61, 0x9d, 0x6d	//    34
-+	data1 0x0c, 0x38, 0xe5, 0xfd	//    35
-+	data1 0x44, 0xea, 0xbe, 0xa4	//    36
-+	data1 0xa9, 0xcf, 0xde, 0x4b	//    37
-+	data1 0x60, 0x4b, 0xbb, 0xf6	//    38
-+	data1 0x70, 0xbc, 0xbf, 0xbe	//    39
-+	data1 0xc6, 0x7e, 0x9b, 0x28	//    40
-+	data1 0xfa, 0x27, 0xa1, 0xea	//    41
-+	data1 0x85, 0x30, 0xef, 0xd4	//    42
-+	data1 0x05, 0x1d, 0x88, 0x04	//    43
-+	data1 0x39, 0xd0, 0xd4, 0xd9	//    44
-+	data1 0xe5, 0x99, 0xdb, 0xe6	//    45
-+	data1 0xf8, 0x7c, 0xa2, 0x1f	//    46
-+	data1 0x65, 0x56, 0xac, 0xc4	//    47
-+	data1 0x44, 0x22, 0x29, 0xf4	//    48
-+	data1 0x97, 0xff, 0x2a, 0x43	//    49
-+	data1 0xa7, 0x23, 0x94, 0xab	//    50
-+	data1 0x39, 0xa0, 0x93, 0xfc	//    51
-+	data1 0xc3, 0x59, 0x5b, 0x65	//    52
-+	data1 0x92, 0xcc, 0x0c, 0x8f	//    53
-+	data1 0x7d, 0xf4, 0xef, 0xff	//    54
-+	data1 0xd1, 0x5d, 0x84, 0x85	//    55
-+	data1 0x4f, 0x7e, 0xa8, 0x6f	//    56
-+	data1 0xe0, 0xe6, 0x2c, 0xfe	//    57
-+	data1 0x14, 0x43, 0x01, 0xa3	//    58
-+	data1 0xa1, 0x11, 0x08, 0x4e	//    59
-+	data1 0x82, 0x7e, 0x53, 0xf7	//    60
-+	data1 0x35, 0xf2, 0x3a, 0xbd	//    61
-+	data1 0xbb, 0xd2, 0xd7, 0x2a	//    62
-+	data1 0x91, 0xd3, 0x86, 0xeb	//    63
-+.size	md5_constants#,64*4
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-sparcv9.pl
-new file mode 100644
-index 0000000..09e6d71
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-sparcv9.pl
-@@ -0,0 +1,437 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+#
-+# Hardware SPARC T4 support by David S. Miller .
-+# ====================================================================
-+
-+# MD5 for SPARCv9, 6.9 cycles per byte on UltraSPARC, >40% faster than
-+# code generated by Sun C 5.2.
-+
-+# SPARC T4 MD5 hardware achieves 3.20 cycles per byte, which is 2.1x
-+# faster than software. Multi-process benchmark saturates at 12x
-+# single-process result on 8-core processor, or ~11GBps per 2.85GHz
-+# socket.
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+use integer;
-+
-+($ctx,$inp,$len)=("%i0","%i1","%i2");	# input arguments
-+
-+# 64-bit values
-+@X=("%o0","%o1","%o2","%o3","%o4","%o5","%o7","%g1","%g2");
-+$tx="%g3";
-+($AB,$CD)=("%g4","%g5");
-+
-+# 32-bit values
-+@V=($A,$B,$C,$D)=map("%l$_",(0..3));
-+($t1,$t2,$t3,$saved_asi)=map("%l$_",(4..7));
-+($shr,$shl1,$shl2)=("%i3","%i4","%i5");
-+
-+my @K=(	0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
-+	0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
-+	0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
-+	0x6b901122,0xfd987193,0xa679438e,0x49b40821,
-+
-+	0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
-+	0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
-+	0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
-+	0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
-+
-+	0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
-+	0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
-+	0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
-+	0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
-+
-+	0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
-+	0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
-+	0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
-+	0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391, 0	);
-+
-+sub R0 {
-+  my ($i,$a,$b,$c,$d) = @_;
-+  my $rot = (7,12,17,22)[$i%4];
-+  my $j   = ($i+1)/2;
-+
-+  if ($i&1) {
-+    $code.=<<___;
-+	 srlx	@X[$j],$shr,@X[$j]	! align X[`$i+1`]
-+	and	$b,$t1,$t1		! round $i
-+	 sllx	@X[$j+1],$shl1,$tx
-+	add	$t2,$a,$a
-+	 sllx	$tx,$shl2,$tx
-+	xor	$d,$t1,$t1
-+	 or	$tx,@X[$j],@X[$j]
-+	 sethi	%hi(@K[$i+1]),$t2
-+	add	$t1,$a,$a
-+	 or	$t2,%lo(@K[$i+1]),$t2
-+	sll	$a,$rot,$t3
-+	 add	@X[$j],$t2,$t2		! X[`$i+1`]+K[`$i+1`]
-+	srl	$a,32-$rot,$a
-+	add	$b,$t3,$t3
-+	 xor	 $b,$c,$t1
-+	add	$t3,$a,$a
-+___
-+  } else {
-+    $code.=<<___;
-+	 srlx	@X[$j],32,$tx		! extract X[`2*$j+1`]
-+	and	$b,$t1,$t1		! round $i
-+	add	$t2,$a,$a
-+	xor	$d,$t1,$t1
-+	 sethi	%hi(@K[$i+1]),$t2
-+	add	$t1,$a,$a
-+	 or	$t2,%lo(@K[$i+1]),$t2
-+	sll	$a,$rot,$t3
-+	 add	$tx,$t2,$t2		! X[`2*$j+1`]+K[`$i+1`]
-+	srl	$a,32-$rot,$a
-+	add	$b,$t3,$t3
-+	 xor	 $b,$c,$t1
-+	add	$t3,$a,$a
-+___
-+  }
-+}
-+
-+sub R0_1 {
-+  my ($i,$a,$b,$c,$d) = @_;
-+  my $rot = (7,12,17,22)[$i%4];
-+
-+$code.=<<___;
-+	 srlx	@X[0],32,$tx		! extract X[1]
-+	and	$b,$t1,$t1		! round $i
-+	add	$t2,$a,$a
-+	xor	$d,$t1,$t1
-+	 sethi	%hi(@K[$i+1]),$t2
-+	add	$t1,$a,$a
-+	 or	$t2,%lo(@K[$i+1]),$t2
-+	sll	$a,$rot,$t3
-+	 add	$tx,$t2,$t2		! X[1]+K[`$i+1`]
-+	srl	$a,32-$rot,$a
-+	add	$b,$t3,$t3
-+	 andn	 $b,$c,$t1
-+	add	$t3,$a,$a
-+___
-+}
-+
-+sub R1 {
-+  my ($i,$a,$b,$c,$d) = @_;
-+  my $rot = (5,9,14,20)[$i%4];
-+  my $j   = $i<31 ? (1+5*($i+1))%16 : (5+3*($i+1))%16;
-+  my $xi  = @X[$j/2];
-+
-+$code.=<<___ if ($j&1 && ($xi=$tx));
-+	 srlx	@X[$j/2],32,$xi		! extract X[$j]
-+___
-+$code.=<<___;
-+	and	$b,$d,$t3		! round $i
-+	add	$t2,$a,$a
-+	or	$t3,$t1,$t1
-+	 sethi	%hi(@K[$i+1]),$t2
-+	add	$t1,$a,$a
-+	 or	$t2,%lo(@K[$i+1]),$t2
-+	sll	$a,$rot,$t3
-+	 add	$xi,$t2,$t2		! X[$j]+K[`$i+1`]
-+	srl	$a,32-$rot,$a
-+	add	$b,$t3,$t3
-+	 `$i<31?"andn":"xor"`	 $b,$c,$t1
-+	add	$t3,$a,$a
-+___
-+}
-+
-+sub R2 {
-+  my ($i,$a,$b,$c,$d) = @_;
-+  my $rot = (4,11,16,23)[$i%4];
-+  my $j   = $i<47 ? (5+3*($i+1))%16 : (0+7*($i+1))%16;
-+  my $xi  = @X[$j/2];
-+
-+$code.=<<___ if ($j&1 && ($xi=$tx));
-+	 srlx	@X[$j/2],32,$xi		! extract X[$j]
-+___
-+$code.=<<___;
-+	add	$t2,$a,$a		! round $i
-+	xor	$b,$t1,$t1
-+	 sethi	%hi(@K[$i+1]),$t2
-+	add	$t1,$a,$a
-+	 or	$t2,%lo(@K[$i+1]),$t2
-+	sll	$a,$rot,$t3
-+	 add	$xi,$t2,$t2		! X[$j]+K[`$i+1`]
-+	srl	$a,32-$rot,$a
-+	add	$b,$t3,$t3
-+	 xor	 $b,$c,$t1
-+	add	$t3,$a,$a
-+___
-+}
-+
-+sub R3 {
-+  my ($i,$a,$b,$c,$d) = @_;
-+  my $rot = (6,10,15,21)[$i%4];
-+  my $j   = (0+7*($i+1))%16;
-+  my $xi  = @X[$j/2];
-+
-+$code.=<<___;
-+	add	$t2,$a,$a		! round $i
-+___
-+$code.=<<___ if ($j&1 && ($xi=$tx));
-+	 srlx	@X[$j/2],32,$xi		! extract X[$j]
-+___
-+$code.=<<___;
-+	orn	$b,$d,$t1
-+	 sethi	%hi(@K[$i+1]),$t2
-+	xor	$c,$t1,$t1
-+	 or	$t2,%lo(@K[$i+1]),$t2
-+	add	$t1,$a,$a
-+	sll	$a,$rot,$t3
-+	 add	$xi,$t2,$t2		! X[$j]+K[`$i+1`]
-+	srl	$a,32-$rot,$a
-+	add	$b,$t3,$t3
-+	add	$t3,$a,$a
-+___
-+}
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#ifdef __arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+#endif
-+
-+.section	".text",#alloc,#execinstr
-+
-+#ifdef __PIC__
-+SPARC_PIC_THUNK(%g1)
-+#endif
-+
-+.globl	md5_block_asm_data_order
-+.align	32
-+md5_block_asm_data_order:
-+	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+	ld	[%g1+4],%g1		! OPENSSL_sparcv9cap_P[1]
-+
-+	andcc	%g1, CFR_MD5, %g0
-+	be	.Lsoftware
-+	nop
-+
-+	mov	4, %g1
-+	andcc	%o1, 0x7, %g0
-+	lda	[%o0 + %g0]0x88, %f0		! load context
-+	lda	[%o0 + %g1]0x88, %f1
-+	add	%o0, 8, %o0
-+	lda	[%o0 + %g0]0x88, %f2
-+	lda	[%o0 + %g1]0x88, %f3
-+	bne,pn	%icc, .Lhwunaligned
-+	sub	%o0, 8, %o0
-+
-+.Lhw_loop:
-+	ldd	[%o1 + 0x00], %f8
-+	ldd	[%o1 + 0x08], %f10
-+	ldd	[%o1 + 0x10], %f12
-+	ldd	[%o1 + 0x18], %f14
-+	ldd	[%o1 + 0x20], %f16
-+	ldd	[%o1 + 0x28], %f18
-+	ldd	[%o1 + 0x30], %f20
-+	subcc	%o2, 1, %o2		! done yet? 
-+	ldd	[%o1 + 0x38], %f22
-+	add	%o1, 0x40, %o1
-+	prefetch [%o1 + 63], 20
-+
-+	.word	0x81b02800		! MD5
-+
-+	bne,pt	SIZE_T_CC, .Lhw_loop
-+	nop
-+
-+.Lhwfinish:
-+	sta	%f0, [%o0 + %g0]0x88	! store context
-+	sta	%f1, [%o0 + %g1]0x88
-+	add	%o0, 8, %o0
-+	sta	%f2, [%o0 + %g0]0x88
-+	sta	%f3, [%o0 + %g1]0x88
-+	retl
-+	nop
-+
-+.align	8
-+.Lhwunaligned:
-+	alignaddr %o1, %g0, %o1
-+
-+	ldd	[%o1 + 0x00], %f10
-+.Lhwunaligned_loop:
-+	ldd	[%o1 + 0x08], %f12
-+	ldd	[%o1 + 0x10], %f14
-+	ldd	[%o1 + 0x18], %f16
-+	ldd	[%o1 + 0x20], %f18
-+	ldd	[%o1 + 0x28], %f20
-+	ldd	[%o1 + 0x30], %f22
-+	ldd	[%o1 + 0x38], %f24
-+	subcc	%o2, 1, %o2		! done yet?
-+	ldd	[%o1 + 0x40], %f26
-+	add	%o1, 0x40, %o1
-+	prefetch [%o1 + 63], 20
-+
-+	faligndata %f10, %f12, %f8
-+	faligndata %f12, %f14, %f10
-+	faligndata %f14, %f16, %f12
-+	faligndata %f16, %f18, %f14
-+	faligndata %f18, %f20, %f16
-+	faligndata %f20, %f22, %f18
-+	faligndata %f22, %f24, %f20
-+	faligndata %f24, %f26, %f22
-+
-+	.word	0x81b02800		! MD5
-+
-+	bne,pt	SIZE_T_CC, .Lhwunaligned_loop
-+	for	%f26, %f26, %f10	! %f10=%f26
-+
-+	ba	.Lhwfinish
-+	nop
-+
-+.align	16
-+.Lsoftware:
-+	save	%sp,-STACK_FRAME,%sp
-+
-+	rd	%asi,$saved_asi
-+	wr	%g0,0x88,%asi		! ASI_PRIMARY_LITTLE
-+	and	$inp,7,$shr
-+	andn	$inp,7,$inp
-+
-+	sll	$shr,3,$shr		! *=8
-+	mov	56,$shl2
-+	ld	[$ctx+0],$A
-+	sub	$shl2,$shr,$shl2
-+	ld	[$ctx+4],$B
-+	and	$shl2,32,$shl1
-+	add	$shl2,8,$shl2
-+	ld	[$ctx+8],$C
-+	sub	$shl2,$shl1,$shl2	! shr+shl1+shl2==64
-+	ld	[$ctx+12],$D
-+	nop
-+
-+.Loop:
-+	 cmp	$shr,0			! was inp aligned?
-+	ldxa	[$inp+0]%asi,@X[0]	! load little-endian input
-+	ldxa	[$inp+8]%asi,@X[1]
-+	ldxa	[$inp+16]%asi,@X[2]
-+	ldxa	[$inp+24]%asi,@X[3]
-+	ldxa	[$inp+32]%asi,@X[4]
-+	 sllx	$A,32,$AB		! pack A,B
-+	ldxa	[$inp+40]%asi,@X[5]
-+	 sllx	$C,32,$CD		! pack C,D
-+	ldxa	[$inp+48]%asi,@X[6]
-+	 or	$B,$AB,$AB
-+	ldxa	[$inp+56]%asi,@X[7]
-+	 or	$D,$CD,$CD
-+	bnz,a,pn	%icc,.+8
-+	ldxa	[$inp+64]%asi,@X[8]
-+
-+	srlx	@X[0],$shr,@X[0]	! align X[0]
-+	sllx	@X[1],$shl1,$tx
-+	 sethi	%hi(@K[0]),$t2
-+	sllx	$tx,$shl2,$tx
-+	 or	$t2,%lo(@K[0]),$t2
-+	or	$tx,@X[0],@X[0]
-+	 xor	$C,$D,$t1
-+	 add	@X[0],$t2,$t2		! X[0]+K[0]
-+___
-+	for ($i=0;$i<15;$i++)	{ &R0($i,@V);	unshift(@V,pop(@V)); }
-+	for (;$i<16;$i++)	{ &R0_1($i,@V);	unshift(@V,pop(@V)); }
-+	for (;$i<32;$i++)	{ &R1($i,@V);	unshift(@V,pop(@V)); }
-+	for (;$i<48;$i++)	{ &R2($i,@V);	unshift(@V,pop(@V)); }
-+	for (;$i<64;$i++)	{ &R3($i,@V);	unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	srlx	$AB,32,$t1		! unpack A,B,C,D and accumulate
-+	add	$inp,64,$inp		! advance inp
-+	srlx	$CD,32,$t2
-+	add	$t1,$A,$A
-+	subcc	$len,1,$len		! done yet?
-+	add	$AB,$B,$B
-+	add	$t2,$C,$C
-+	add	$CD,$D,$D
-+	srl	$B,0,$B			! clruw	$B
-+	bne	SIZE_T_CC,.Loop
-+	srl	$D,0,$D			! clruw	$D
-+
-+	st	$A,[$ctx+0]		! write out ctx
-+	st	$B,[$ctx+4]
-+	st	$C,[$ctx+8]
-+	st	$D,[$ctx+12]
-+
-+	wr	%g0,$saved_asi,%asi
-+	ret
-+	restore
-+.type	md5_block_asm_data_order,#function
-+.size	md5_block_asm_data_order,(.-md5_block_asm_data_order)
-+
-+.asciz	"MD5 block transform for SPARCv9, CRYPTOGAMS by "
-+.align	4
-+___
-+
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my $ref,$opf;
-+my %visopf = (	"faligndata"	=> 0x048,
-+		"for"		=> 0x07c	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+sub unalignaddr {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my $ref="$mnemonic\t$rs1,$rs2,$rd";
-+
-+    foreach ($rs1,$rs2,$rd) {
-+	if (/%([goli])([0-7])/)	{ $_=$bias{$1}+$2; }
-+	else			{ return $ref; }
-+    }
-+    return  sprintf ".word\t0x%08x !%s",
-+		    0x81b00300|$rd<<25|$rs1<<14|$rs2,
-+		    $ref;
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-+		&unvis($1,$2,$3,$4)
-+	 /ge;
-+	s/\b(alignaddr)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+		&unalignaddr($1,$2,$3,$4)
-+	 /ge;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-x86_64.pl
-new file mode 100755
-index 0000000..3f656dc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/asm/md5-x86_64.pl
-@@ -0,0 +1,380 @@
-+#! /usr/bin/env perl
-+# Author: Marc Bevand 
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+# MD5 optimized for AMD64.
-+
-+use strict;
-+
-+my $code;
-+
-+# round1_step() does:
-+#   dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s)
-+#   %r10d = X[k_next]
-+#   %r11d = z' (copy of z for the next step)
-+# Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC)
-+sub round1_step
-+{
-+    my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
-+    $code .= " mov	0*4(%rsi),	%r10d		/* (NEXT STEP) X[0] */\n" if ($pos == -1);
-+    $code .= " mov	%edx,		%r11d		/* (NEXT STEP) z' = %edx */\n" if ($pos == -1);
-+    $code .= <A
-+	mov	1*4(%rbp),	%ebx	# ebx = ctx->B
-+	mov	2*4(%rbp),	%ecx	# ecx = ctx->C
-+	mov	3*4(%rbp),	%edx	# edx = ctx->D
-+	# end is 'rdi'
-+	# ptr is 'rsi'
-+	# A is 'eax'
-+	# B is 'ebx'
-+	# C is 'ecx'
-+	# D is 'edx'
-+
-+	cmp	%rdi,		%rsi		# cmp end with ptr
-+	je	.Lend				# jmp if ptr == end
-+
-+	# BEGIN of loop over 16-word blocks
-+.Lloop:	# save old values of A, B, C, D
-+	mov	%eax,		%r8d
-+	mov	%ebx,		%r9d
-+	mov	%ecx,		%r14d
-+	mov	%edx,		%r15d
-+EOF
-+round1_step(-1,'%eax','%ebx','%ecx','%edx', '1','0xd76aa478', '7');
-+round1_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xe8c7b756','12');
-+round1_step( 0,'%ecx','%edx','%eax','%ebx', '3','0x242070db','17');
-+round1_step( 0,'%ebx','%ecx','%edx','%eax', '4','0xc1bdceee','22');
-+round1_step( 0,'%eax','%ebx','%ecx','%edx', '5','0xf57c0faf', '7');
-+round1_step( 0,'%edx','%eax','%ebx','%ecx', '6','0x4787c62a','12');
-+round1_step( 0,'%ecx','%edx','%eax','%ebx', '7','0xa8304613','17');
-+round1_step( 0,'%ebx','%ecx','%edx','%eax', '8','0xfd469501','22');
-+round1_step( 0,'%eax','%ebx','%ecx','%edx', '9','0x698098d8', '7');
-+round1_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8b44f7af','12');
-+round1_step( 0,'%ecx','%edx','%eax','%ebx','11','0xffff5bb1','17');
-+round1_step( 0,'%ebx','%ecx','%edx','%eax','12','0x895cd7be','22');
-+round1_step( 0,'%eax','%ebx','%ecx','%edx','13','0x6b901122', '7');
-+round1_step( 0,'%edx','%eax','%ebx','%ecx','14','0xfd987193','12');
-+round1_step( 0,'%ecx','%edx','%eax','%ebx','15','0xa679438e','17');
-+round1_step( 1,'%ebx','%ecx','%edx','%eax', '1','0x49b40821','22');
-+
-+round2_step(-1,'%eax','%ebx','%ecx','%edx', '6','0xf61e2562', '5');
-+round2_step( 0,'%edx','%eax','%ebx','%ecx','11','0xc040b340', '9');
-+round2_step( 0,'%ecx','%edx','%eax','%ebx', '0','0x265e5a51','14');
-+round2_step( 0,'%ebx','%ecx','%edx','%eax', '5','0xe9b6c7aa','20');
-+round2_step( 0,'%eax','%ebx','%ecx','%edx','10','0xd62f105d', '5');
-+round2_step( 0,'%edx','%eax','%ebx','%ecx','15', '0x2441453', '9');
-+round2_step( 0,'%ecx','%edx','%eax','%ebx', '4','0xd8a1e681','14');
-+round2_step( 0,'%ebx','%ecx','%edx','%eax', '9','0xe7d3fbc8','20');
-+round2_step( 0,'%eax','%ebx','%ecx','%edx','14','0x21e1cde6', '5');
-+round2_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xc33707d6', '9');
-+round2_step( 0,'%ecx','%edx','%eax','%ebx', '8','0xf4d50d87','14');
-+round2_step( 0,'%ebx','%ecx','%edx','%eax','13','0x455a14ed','20');
-+round2_step( 0,'%eax','%ebx','%ecx','%edx', '2','0xa9e3e905', '5');
-+round2_step( 0,'%edx','%eax','%ebx','%ecx', '7','0xfcefa3f8', '9');
-+round2_step( 0,'%ecx','%edx','%eax','%ebx','12','0x676f02d9','14');
-+round2_step( 1,'%ebx','%ecx','%edx','%eax', '5','0x8d2a4c8a','20');
-+
-+round3_step(-1,'%eax','%ebx','%ecx','%edx', '8','0xfffa3942', '4');
-+round3_step( 0,'%edx','%eax','%ebx','%ecx','11','0x8771f681','11');
-+round3_step( 0,'%ecx','%edx','%eax','%ebx','14','0x6d9d6122','16');
-+round3_step( 0,'%ebx','%ecx','%edx','%eax', '1','0xfde5380c','23');
-+round3_step( 0,'%eax','%ebx','%ecx','%edx', '4','0xa4beea44', '4');
-+round3_step( 0,'%edx','%eax','%ebx','%ecx', '7','0x4bdecfa9','11');
-+round3_step( 0,'%ecx','%edx','%eax','%ebx','10','0xf6bb4b60','16');
-+round3_step( 0,'%ebx','%ecx','%edx','%eax','13','0xbebfbc70','23');
-+round3_step( 0,'%eax','%ebx','%ecx','%edx', '0','0x289b7ec6', '4');
-+round3_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xeaa127fa','11');
-+round3_step( 0,'%ecx','%edx','%eax','%ebx', '6','0xd4ef3085','16');
-+round3_step( 0,'%ebx','%ecx','%edx','%eax', '9', '0x4881d05','23');
-+round3_step( 0,'%eax','%ebx','%ecx','%edx','12','0xd9d4d039', '4');
-+round3_step( 0,'%edx','%eax','%ebx','%ecx','15','0xe6db99e5','11');
-+round3_step( 0,'%ecx','%edx','%eax','%ebx', '2','0x1fa27cf8','16');
-+round3_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xc4ac5665','23');
-+
-+round4_step(-1,'%eax','%ebx','%ecx','%edx', '7','0xf4292244', '6');
-+round4_step( 0,'%edx','%eax','%ebx','%ecx','14','0x432aff97','10');
-+round4_step( 0,'%ecx','%edx','%eax','%ebx', '5','0xab9423a7','15');
-+round4_step( 0,'%ebx','%ecx','%edx','%eax','12','0xfc93a039','21');
-+round4_step( 0,'%eax','%ebx','%ecx','%edx', '3','0x655b59c3', '6');
-+round4_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8f0ccc92','10');
-+round4_step( 0,'%ecx','%edx','%eax','%ebx', '1','0xffeff47d','15');
-+round4_step( 0,'%ebx','%ecx','%edx','%eax', '8','0x85845dd1','21');
-+round4_step( 0,'%eax','%ebx','%ecx','%edx','15','0x6fa87e4f', '6');
-+round4_step( 0,'%edx','%eax','%ebx','%ecx', '6','0xfe2ce6e0','10');
-+round4_step( 0,'%ecx','%edx','%eax','%ebx','13','0xa3014314','15');
-+round4_step( 0,'%ebx','%ecx','%edx','%eax', '4','0x4e0811a1','21');
-+round4_step( 0,'%eax','%ebx','%ecx','%edx','11','0xf7537e82', '6');
-+round4_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xbd3af235','10');
-+round4_step( 0,'%ecx','%edx','%eax','%ebx', '9','0x2ad7d2bb','15');
-+round4_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xeb86d391','21');
-+$code .= <A = A
-+	mov	%ebx,		1*4(%rbp)	# ctx->B = B
-+	mov	%ecx,		2*4(%rbp)	# ctx->C = C
-+	mov	%edx,		3*4(%rbp)	# ctx->D = D
-+
-+	mov	(%rsp),%r15
-+	mov	8(%rsp),%r14
-+	mov	16(%rsp),%r12
-+	mov	24(%rsp),%rbx
-+	mov	32(%rsp),%rbp
-+	add	\$40,%rsp
-+.Lepilogue:
-+	ret
-+.size md5_block_asm_data_order,.-md5_block_asm_data_order
-+EOF
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+my $rec="%rcx";
-+my $frame="%rdx";
-+my $context="%r8";
-+my $disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lprologue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lprologue
-+	jb	.Lin_prologue
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	lea	.Lepilogue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
-+	jae	.Lin_prologue
-+
-+	lea	40(%rax),%rax
-+
-+	mov	-8(%rax),%rbp
-+	mov	-16(%rax),%rbx
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r14
-+	mov	-40(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_md5_block_asm_data_order
-+	.rva	.LSEH_end_md5_block_asm_data_order
-+	.rva	.LSEH_info_md5_block_asm_data_order
-+
-+.section	.xdata
-+.align	8
-+.LSEH_info_md5_block_asm_data_order:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+___
-+}
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/build.info
-new file mode 100644
-index 0000000..38323a3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/build.info
-@@ -0,0 +1,22 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        md5_dgst.c md5_one.c {- $target{md5_asm_src} -}
-+
-+GENERATE[md5-586.s]=asm/md5-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS)
-+
-+GENERATE[md5-x86_64.s]=asm/md5-x86_64.pl $(PERLASM_SCHEME)
-+
-+GENERATE[md5-sparcv9.S]=asm/md5-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[md5-sparcv9.o]=..
-+
-+BEGINRAW[makefile(windows)]
-+{- $builddir -}\md5-ia64.asm: {- $sourcedir -}\asm\md5-ia64.S
-+	$(CC) $(CFLAGS) -EP {- $sourcedir -}\asm\md5-ia64.S > $@.i && move /Y $@.i $@
-+ENDRAW[makefile(windows)]
-+
-+BEGINRAW[Makefile]
-+{- $builddir -}/md5-ia64.s: {- $sourcedir -}/asm/md5-ia64.S
-+	$(CC) $(CFLAGS) -E {- $sourcedir -}/asm/md5-ia64.S | \
-+	$(PERL) -ne 's/;\s+/;\n/g; print;' > $@
-+
-+ENDRAW[Makefile]
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_dgst.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_dgst.c
-new file mode 100644
-index 0000000..fbede67
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_dgst.c
-@@ -0,0 +1,164 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "md5_locl.h"
-+#include 
-+
-+/*
-+ * Implemented from RFC1321 The MD5 Message-Digest Algorithm
-+ */
-+
-+#define INIT_DATA_A (unsigned long)0x67452301L
-+#define INIT_DATA_B (unsigned long)0xefcdab89L
-+#define INIT_DATA_C (unsigned long)0x98badcfeL
-+#define INIT_DATA_D (unsigned long)0x10325476L
-+
-+int MD5_Init(MD5_CTX *c)
-+{
-+    memset(c, 0, sizeof(*c));
-+    c->A = INIT_DATA_A;
-+    c->B = INIT_DATA_B;
-+    c->C = INIT_DATA_C;
-+    c->D = INIT_DATA_D;
-+    return 1;
-+}
-+
-+#ifndef md5_block_data_order
-+# ifdef X
-+#  undef X
-+# endif
-+void md5_block_data_order(MD5_CTX *c, const void *data_, size_t num)
-+{
-+    const unsigned char *data = data_;
-+    register unsigned MD32_REG_T A, B, C, D, l;
-+# ifndef MD32_XARRAY
-+    /* See comment in crypto/sha/sha_locl.h for details. */
-+    unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
-+        XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
-+#  define X(i)   XX##i
-+# else
-+    MD5_LONG XX[MD5_LBLOCK];
-+#  define X(i)   XX[i]
-+# endif
-+
-+    A = c->A;
-+    B = c->B;
-+    C = c->C;
-+    D = c->D;
-+
-+    for (; num--;) {
-+        (void)HOST_c2l(data, l);
-+        X(0) = l;
-+        (void)HOST_c2l(data, l);
-+        X(1) = l;
-+        /* Round 0 */
-+        R0(A, B, C, D, X(0), 7, 0xd76aa478L);
-+        (void)HOST_c2l(data, l);
-+        X(2) = l;
-+        R0(D, A, B, C, X(1), 12, 0xe8c7b756L);
-+        (void)HOST_c2l(data, l);
-+        X(3) = l;
-+        R0(C, D, A, B, X(2), 17, 0x242070dbL);
-+        (void)HOST_c2l(data, l);
-+        X(4) = l;
-+        R0(B, C, D, A, X(3), 22, 0xc1bdceeeL);
-+        (void)HOST_c2l(data, l);
-+        X(5) = l;
-+        R0(A, B, C, D, X(4), 7, 0xf57c0fafL);
-+        (void)HOST_c2l(data, l);
-+        X(6) = l;
-+        R0(D, A, B, C, X(5), 12, 0x4787c62aL);
-+        (void)HOST_c2l(data, l);
-+        X(7) = l;
-+        R0(C, D, A, B, X(6), 17, 0xa8304613L);
-+        (void)HOST_c2l(data, l);
-+        X(8) = l;
-+        R0(B, C, D, A, X(7), 22, 0xfd469501L);
-+        (void)HOST_c2l(data, l);
-+        X(9) = l;
-+        R0(A, B, C, D, X(8), 7, 0x698098d8L);
-+        (void)HOST_c2l(data, l);
-+        X(10) = l;
-+        R0(D, A, B, C, X(9), 12, 0x8b44f7afL);
-+        (void)HOST_c2l(data, l);
-+        X(11) = l;
-+        R0(C, D, A, B, X(10), 17, 0xffff5bb1L);
-+        (void)HOST_c2l(data, l);
-+        X(12) = l;
-+        R0(B, C, D, A, X(11), 22, 0x895cd7beL);
-+        (void)HOST_c2l(data, l);
-+        X(13) = l;
-+        R0(A, B, C, D, X(12), 7, 0x6b901122L);
-+        (void)HOST_c2l(data, l);
-+        X(14) = l;
-+        R0(D, A, B, C, X(13), 12, 0xfd987193L);
-+        (void)HOST_c2l(data, l);
-+        X(15) = l;
-+        R0(C, D, A, B, X(14), 17, 0xa679438eL);
-+        R0(B, C, D, A, X(15), 22, 0x49b40821L);
-+        /* Round 1 */
-+        R1(A, B, C, D, X(1), 5, 0xf61e2562L);
-+        R1(D, A, B, C, X(6), 9, 0xc040b340L);
-+        R1(C, D, A, B, X(11), 14, 0x265e5a51L);
-+        R1(B, C, D, A, X(0), 20, 0xe9b6c7aaL);
-+        R1(A, B, C, D, X(5), 5, 0xd62f105dL);
-+        R1(D, A, B, C, X(10), 9, 0x02441453L);
-+        R1(C, D, A, B, X(15), 14, 0xd8a1e681L);
-+        R1(B, C, D, A, X(4), 20, 0xe7d3fbc8L);
-+        R1(A, B, C, D, X(9), 5, 0x21e1cde6L);
-+        R1(D, A, B, C, X(14), 9, 0xc33707d6L);
-+        R1(C, D, A, B, X(3), 14, 0xf4d50d87L);
-+        R1(B, C, D, A, X(8), 20, 0x455a14edL);
-+        R1(A, B, C, D, X(13), 5, 0xa9e3e905L);
-+        R1(D, A, B, C, X(2), 9, 0xfcefa3f8L);
-+        R1(C, D, A, B, X(7), 14, 0x676f02d9L);
-+        R1(B, C, D, A, X(12), 20, 0x8d2a4c8aL);
-+        /* Round 2 */
-+        R2(A, B, C, D, X(5), 4, 0xfffa3942L);
-+        R2(D, A, B, C, X(8), 11, 0x8771f681L);
-+        R2(C, D, A, B, X(11), 16, 0x6d9d6122L);
-+        R2(B, C, D, A, X(14), 23, 0xfde5380cL);
-+        R2(A, B, C, D, X(1), 4, 0xa4beea44L);
-+        R2(D, A, B, C, X(4), 11, 0x4bdecfa9L);
-+        R2(C, D, A, B, X(7), 16, 0xf6bb4b60L);
-+        R2(B, C, D, A, X(10), 23, 0xbebfbc70L);
-+        R2(A, B, C, D, X(13), 4, 0x289b7ec6L);
-+        R2(D, A, B, C, X(0), 11, 0xeaa127faL);
-+        R2(C, D, A, B, X(3), 16, 0xd4ef3085L);
-+        R2(B, C, D, A, X(6), 23, 0x04881d05L);
-+        R2(A, B, C, D, X(9), 4, 0xd9d4d039L);
-+        R2(D, A, B, C, X(12), 11, 0xe6db99e5L);
-+        R2(C, D, A, B, X(15), 16, 0x1fa27cf8L);
-+        R2(B, C, D, A, X(2), 23, 0xc4ac5665L);
-+        /* Round 3 */
-+        R3(A, B, C, D, X(0), 6, 0xf4292244L);
-+        R3(D, A, B, C, X(7), 10, 0x432aff97L);
-+        R3(C, D, A, B, X(14), 15, 0xab9423a7L);
-+        R3(B, C, D, A, X(5), 21, 0xfc93a039L);
-+        R3(A, B, C, D, X(12), 6, 0x655b59c3L);
-+        R3(D, A, B, C, X(3), 10, 0x8f0ccc92L);
-+        R3(C, D, A, B, X(10), 15, 0xffeff47dL);
-+        R3(B, C, D, A, X(1), 21, 0x85845dd1L);
-+        R3(A, B, C, D, X(8), 6, 0x6fa87e4fL);
-+        R3(D, A, B, C, X(15), 10, 0xfe2ce6e0L);
-+        R3(C, D, A, B, X(6), 15, 0xa3014314L);
-+        R3(B, C, D, A, X(13), 21, 0x4e0811a1L);
-+        R3(A, B, C, D, X(4), 6, 0xf7537e82L);
-+        R3(D, A, B, C, X(11), 10, 0xbd3af235L);
-+        R3(C, D, A, B, X(2), 15, 0x2ad7d2bbL);
-+        R3(B, C, D, A, X(9), 21, 0xeb86d391L);
-+
-+        A = c->A += A;
-+        B = c->B += B;
-+        C = c->C += C;
-+        D = c->D += D;
-+    }
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_locl.h
-new file mode 100644
-index 0000000..9c7aade
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_locl.h
-@@ -0,0 +1,80 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifdef MD5_ASM
-+# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
-+     defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
-+#  define md5_block_data_order md5_block_asm_data_order
-+# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
-+#  define md5_block_data_order md5_block_asm_data_order
-+# elif defined(__sparc) || defined(__sparc__)
-+#  define md5_block_data_order md5_block_asm_data_order
-+# endif
-+#endif
-+
-+void md5_block_data_order(MD5_CTX *c, const void *p, size_t num);
-+
-+#define DATA_ORDER_IS_LITTLE_ENDIAN
-+
-+#define HASH_LONG               MD5_LONG
-+#define HASH_CTX                MD5_CTX
-+#define HASH_CBLOCK             MD5_CBLOCK
-+#define HASH_UPDATE             MD5_Update
-+#define HASH_TRANSFORM          MD5_Transform
-+#define HASH_FINAL              MD5_Final
-+#define HASH_MAKE_STRING(c,s)   do {    \
-+        unsigned long ll;               \
-+        ll=(c)->A; (void)HOST_l2c(ll,(s));      \
-+        ll=(c)->B; (void)HOST_l2c(ll,(s));      \
-+        ll=(c)->C; (void)HOST_l2c(ll,(s));      \
-+        ll=(c)->D; (void)HOST_l2c(ll,(s));      \
-+        } while (0)
-+#define HASH_BLOCK_DATA_ORDER   md5_block_data_order
-+
-+#include "internal/md32_common.h"
-+
-+/*-
-+#define F(x,y,z)        (((x) & (y))  |  ((~(x)) & (z)))
-+#define G(x,y,z)        (((x) & (z))  |  ((y) & (~(z))))
-+*/
-+
-+/*
-+ * As pointed out by Wei Dai , the above can be simplified
-+ * to the code below.  Wei attributes these optimizations to Peter Gutmann's
-+ * SHS code, and he attributes it to Rich Schroeppel.
-+ */
-+#define F(b,c,d)        ((((c) ^ (d)) & (b)) ^ (d))
-+#define G(b,c,d)        ((((b) ^ (c)) & (d)) ^ (c))
-+#define H(b,c,d)        ((b) ^ (c) ^ (d))
-+#define I(b,c,d)        (((~(d)) | (b)) ^ (c))
-+
-+#define R0(a,b,c,d,k,s,t) { \
-+        a+=((k)+(t)+F((b),(c),(d))); \
-+        a=ROTATE(a,s); \
-+        a+=b; };\
-+
-+#define R1(a,b,c,d,k,s,t) { \
-+        a+=((k)+(t)+G((b),(c),(d))); \
-+        a=ROTATE(a,s); \
-+        a+=b; };
-+
-+#define R2(a,b,c,d,k,s,t) { \
-+        a+=((k)+(t)+H((b),(c),(d))); \
-+        a=ROTATE(a,s); \
-+        a+=b; };
-+
-+#define R3(a,b,c,d,k,s,t) { \
-+        a+=((k)+(t)+I((b),(c),(d))); \
-+        a=ROTATE(a,s); \
-+        a+=b; };
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_one.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_one.c
-new file mode 100644
-index 0000000..becd87e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/md5/md5_one.c
-@@ -0,0 +1,47 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifdef CHARSET_EBCDIC
-+# include 
-+#endif
-+
-+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)
-+{
-+    MD5_CTX c;
-+    static unsigned char m[MD5_DIGEST_LENGTH];
-+
-+    if (md == NULL)
-+        md = m;
-+    if (!MD5_Init(&c))
-+        return NULL;
-+#ifndef CHARSET_EBCDIC
-+    MD5_Update(&c, d, n);
-+#else
-+    {
-+        char temp[1024];
-+        unsigned long chunk;
-+
-+        while (n > 0) {
-+            chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
-+            ebcdic2ascii(temp, d, chunk);
-+            MD5_Update(&c, temp, chunk);
-+            n -= chunk;
-+            d += chunk;
-+        }
-+    }
-+#endif
-+    MD5_Final(md, &c);
-+    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
-+    return (md);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/build.info
-new file mode 100644
-index 0000000..8fe6878
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        mdc2dgst.c mdc2_one.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/mdc2_one.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/mdc2_one.c
-new file mode 100644
-index 0000000..472a5ec
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/mdc2_one.c
-@@ -0,0 +1,27 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md)
-+{
-+    MDC2_CTX c;
-+    static unsigned char m[MDC2_DIGEST_LENGTH];
-+
-+    if (md == NULL)
-+        md = m;
-+    if (!MDC2_Init(&c))
-+        return NULL;
-+    MDC2_Update(&c, d, n);
-+    MDC2_Final(md, &c);
-+    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
-+    return (md);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/mdc2dgst.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/mdc2dgst.c
-new file mode 100644
-index 0000000..37d99f4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/mdc2/mdc2dgst.c
-@@ -0,0 +1,147 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#undef c2l
-+#define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
-+                         l|=((DES_LONG)(*((c)++)))<< 8L, \
-+                         l|=((DES_LONG)(*((c)++)))<<16L, \
-+                         l|=((DES_LONG)(*((c)++)))<<24L)
-+
-+#undef l2c
-+#define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
-+                        *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                        *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                        *((c)++)=(unsigned char)(((l)>>24L)&0xff))
-+
-+static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len);
-+int MDC2_Init(MDC2_CTX *c)
-+{
-+    c->num = 0;
-+    c->pad_type = 1;
-+    memset(&(c->h[0]), 0x52, MDC2_BLOCK);
-+    memset(&(c->hh[0]), 0x25, MDC2_BLOCK);
-+    return 1;
-+}
-+
-+int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len)
-+{
-+    size_t i, j;
-+
-+    i = c->num;
-+    if (i != 0) {
-+        if (len < MDC2_BLOCK - i) {
-+            /* partial block */
-+            memcpy(&(c->data[i]), in, len);
-+            c->num += (int)len;
-+            return 1;
-+        } else {
-+            /* filled one */
-+            j = MDC2_BLOCK - i;
-+            memcpy(&(c->data[i]), in, j);
-+            len -= j;
-+            in += j;
-+            c->num = 0;
-+            mdc2_body(c, &(c->data[0]), MDC2_BLOCK);
-+        }
-+    }
-+    i = len & ~((size_t)MDC2_BLOCK - 1);
-+    if (i > 0)
-+        mdc2_body(c, in, i);
-+    j = len - i;
-+    if (j > 0) {
-+        memcpy(&(c->data[0]), &(in[i]), j);
-+        c->num = (int)j;
-+    }
-+    return 1;
-+}
-+
-+static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len)
-+{
-+    register DES_LONG tin0, tin1;
-+    register DES_LONG ttin0, ttin1;
-+    DES_LONG d[2], dd[2];
-+    DES_key_schedule k;
-+    unsigned char *p;
-+    size_t i;
-+
-+    for (i = 0; i < len; i += 8) {
-+        c2l(in, tin0);
-+        d[0] = dd[0] = tin0;
-+        c2l(in, tin1);
-+        d[1] = dd[1] = tin1;
-+        c->h[0] = (c->h[0] & 0x9f) | 0x40;
-+        c->hh[0] = (c->hh[0] & 0x9f) | 0x20;
-+
-+        DES_set_odd_parity(&c->h);
-+        DES_set_key_unchecked(&c->h, &k);
-+        DES_encrypt1(d, &k, 1);
-+
-+        DES_set_odd_parity(&c->hh);
-+        DES_set_key_unchecked(&c->hh, &k);
-+        DES_encrypt1(dd, &k, 1);
-+
-+        ttin0 = tin0 ^ dd[0];
-+        ttin1 = tin1 ^ dd[1];
-+        tin0 ^= d[0];
-+        tin1 ^= d[1];
-+
-+        p = c->h;
-+        l2c(tin0, p);
-+        l2c(ttin1, p);
-+        p = c->hh;
-+        l2c(ttin0, p);
-+        l2c(tin1, p);
-+    }
-+}
-+
-+int MDC2_Final(unsigned char *md, MDC2_CTX *c)
-+{
-+    unsigned int i;
-+    int j;
-+
-+    i = c->num;
-+    j = c->pad_type;
-+    if ((i > 0) || (j == 2)) {
-+        if (j == 2)
-+            c->data[i++] = 0x80;
-+        memset(&(c->data[i]), 0, MDC2_BLOCK - i);
-+        mdc2_body(c, c->data, MDC2_BLOCK);
-+    }
-+    memcpy(md, (char *)c->h, MDC2_BLOCK);
-+    memcpy(&(md[MDC2_BLOCK]), (char *)c->hh, MDC2_BLOCK);
-+    return 1;
-+}
-+
-+#undef TEST
-+
-+#ifdef TEST
-+main()
-+{
-+    unsigned char md[MDC2_DIGEST_LENGTH];
-+    int i;
-+    MDC2_CTX c;
-+    static char *text = "Now is the time for all ";
-+
-+    MDC2_Init(&c);
-+    MDC2_Update(&c, text, strlen(text));
-+    MDC2_Final(&(md[0]), &c);
-+
-+    for (i = 0; i < MDC2_DIGEST_LENGTH; i++)
-+        printf("%02X", md[i]);
-+    printf("\n");
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/mem.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/mem.c
-new file mode 100644
-index 0000000..02aa43a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/mem.c
-@@ -0,0 +1,190 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+
-+/*
-+ * the following pointers may be changed as long as 'allow_customize' is set
-+ */
-+static int allow_customize = 1;
-+
-+static void *(*malloc_impl)(size_t, const char *, int)
-+    = CRYPTO_malloc;
-+static void *(*realloc_impl)(void *, size_t, const char *, int)
-+    = CRYPTO_realloc;
-+static void (*free_impl)(void *, const char *, int)
-+    = CRYPTO_free;
-+
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+static int call_malloc_debug = 1;
-+#else
-+static int call_malloc_debug = 0;
-+#endif
-+
-+int CRYPTO_set_mem_functions(
-+        void *(*m)(size_t, const char *, int),
-+        void *(*r)(void *, size_t, const char *, int),
-+        void (*f)(void *, const char *, int))
-+{
-+    if (!allow_customize)
-+        return 0;
-+    if (m)
-+        malloc_impl = m;
-+    if (r)
-+        realloc_impl = r;
-+    if (f)
-+        free_impl = f;
-+    return 1;
-+}
-+
-+int CRYPTO_set_mem_debug(int flag)
-+{
-+    if (!allow_customize)
-+        return 0;
-+    call_malloc_debug = flag;
-+    return 1;
-+}
-+
-+void CRYPTO_get_mem_functions(
-+        void *(**m)(size_t, const char *, int),
-+        void *(**r)(void *, size_t, const char *, int),
-+        void (**f)(void *, const char *, int))
-+{
-+    if (m != NULL)
-+        *m = malloc_impl;
-+    if (r != NULL)
-+        *r = realloc_impl;
-+    if (f != NULL)
-+        *f = free_impl;
-+}
-+
-+void *CRYPTO_malloc(size_t num, const char *file, int line)
-+{
-+    void *ret = NULL;
-+
-+    if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)
-+        return malloc_impl(num, file, line);
-+
-+    if (num <= 0)
-+        return NULL;
-+
-+    allow_customize = 0;
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+    if (call_malloc_debug) {
-+        CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);
-+        ret = malloc(num);
-+        CRYPTO_mem_debug_malloc(ret, num, 1, file, line);
-+    } else {
-+        ret = malloc(num);
-+    }
-+#else
-+    osslargused(file); osslargused(line);
-+    ret = malloc(num);
-+#endif
-+
-+    return ret;
-+}
-+
-+void *CRYPTO_zalloc(size_t num, const char *file, int line)
-+{
-+    void *ret = CRYPTO_malloc(num, file, line);
-+
-+    if (ret != NULL)
-+        memset(ret, 0, num);
-+    return ret;
-+}
-+
-+void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
-+{
-+    if (realloc_impl != NULL && realloc_impl != &CRYPTO_realloc)
-+        return realloc_impl(str, num, file, line);
-+
-+    if (str == NULL)
-+        return CRYPTO_malloc(num, file, line);
-+
-+    if (num == 0) {
-+        CRYPTO_free(str, file, line);
-+        return NULL;
-+    }
-+
-+    allow_customize = 0;
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+    if (call_malloc_debug) {
-+        void *ret;
-+        CRYPTO_mem_debug_realloc(str, NULL, num, 0, file, line);
-+        ret = realloc(str, num);
-+        CRYPTO_mem_debug_realloc(str, ret, num, 1, file, line);
-+        return ret;
-+    }
-+#else
-+    osslargused(file); osslargused(line);
-+#endif
-+    return realloc(str, num);
-+
-+}
-+
-+void *CRYPTO_clear_realloc(void *str, size_t old_len, size_t num,
-+                           const char *file, int line)
-+{
-+    void *ret = NULL;
-+
-+    if (str == NULL)
-+        return CRYPTO_malloc(num, file, line);
-+
-+    if (num == 0) {
-+        CRYPTO_clear_free(str, old_len, file, line);
-+        return NULL;
-+    }
-+
-+    /* Can't shrink the buffer since memcpy below copies |old_len| bytes. */
-+    if (num < old_len) {
-+        OPENSSL_cleanse((char*)str + num, old_len - num);
-+        return str;
-+    }
-+
-+    ret = CRYPTO_malloc(num, file, line);
-+    if (ret != NULL) {
-+        memcpy(ret, str, old_len);
-+        CRYPTO_clear_free(str, old_len, file, line);
-+    }
-+    return ret;
-+}
-+
-+void CRYPTO_free(void *str, const char *file, int line)
-+{
-+    if (free_impl != NULL && free_impl != &CRYPTO_free) {
-+        free_impl(str, file, line);
-+        return;
-+    }
-+
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+    if (call_malloc_debug) {
-+        CRYPTO_mem_debug_free(str, 0, file, line);
-+        free(str);
-+        CRYPTO_mem_debug_free(str, 1, file, line);
-+    } else {
-+        free(str);
-+    }
-+#else
-+    free(str);
-+#endif
-+}
-+
-+void CRYPTO_clear_free(void *str, size_t num, const char *file, int line)
-+{
-+    if (str == NULL)
-+        return;
-+    if (num)
-+        OPENSSL_cleanse(str, num);
-+    CRYPTO_free(str, file, line);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/mem_clr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/mem_clr.c
-new file mode 100644
-index 0000000..35bfb74
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/mem_clr.c
-@@ -0,0 +1,25 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+/*
-+ * Pointer to memset is volatile so that compiler must de-reference
-+ * the pointer and can't assume that it points to any function in
-+ * particular (such as memset, which it then might further "optimize")
-+ */
-+typedef void *(*memset_t)(void *, int, size_t);
-+
-+static volatile memset_t memset_func = memset;
-+
-+void OPENSSL_cleanse(void *ptr, size_t len)
-+{
-+    memset_func(ptr, 0, len);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/mem_dbg.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/mem_dbg.c
-new file mode 100644
-index 0000000..dc3f8ff
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/mem_dbg.c
-@@ -0,0 +1,629 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include "internal/thread_once.h"
-+#include 
-+#include 
-+#include "internal/bio.h"
-+#include 
-+
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
-+# include 
-+#endif
-+
-+/*
-+ * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when
-+ * the application asks for it (usually after library initialisation for
-+ * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only
-+ * temporarily when the library thinks that certain allocations should not be
-+ * checked (e.g. the data structures used for memory checking).  It is not
-+ * suitable as an initial state: the library will unexpectedly enable memory
-+ * checking when it executes one of those sections that want to disable
-+ * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes
-+ * no sense whatsoever.
-+ */
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+static int mh_mode = CRYPTO_MEM_CHECK_OFF;
-+#endif
-+
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+static unsigned long order = 0; /* number of memory requests */
-+
-+/*-
-+ * For application-defined information (static C-string `info')
-+ * to be displayed in memory leak list.
-+ * Each thread has its own stack.  For applications, there is
-+ *   OPENSSL_mem_debug_push("...")     to push an entry,
-+ *   OPENSSL_mem_debug_pop()     to pop an entry,
-+ */
-+struct app_mem_info_st {
-+    CRYPTO_THREAD_ID threadid;
-+    const char *file;
-+    int line;
-+    const char *info;
-+    struct app_mem_info_st *next; /* tail of thread's stack */
-+    int references;
-+};
-+
-+static CRYPTO_ONCE memdbg_init = CRYPTO_ONCE_STATIC_INIT;
-+static CRYPTO_RWLOCK *malloc_lock = NULL;
-+static CRYPTO_RWLOCK *long_malloc_lock = NULL;
-+static CRYPTO_THREAD_LOCAL appinfokey;
-+
-+/* memory-block description */
-+struct mem_st {
-+    void *addr;
-+    int num;
-+    const char *file;
-+    int line;
-+    CRYPTO_THREAD_ID threadid;
-+    unsigned long order;
-+    time_t time;
-+    APP_INFO *app_info;
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
-+    void *array[30];
-+    size_t array_siz;
-+#endif
-+};
-+
-+static LHASH_OF(MEM) *mh = NULL; /* hash-table of memory requests (address as
-+                                  * key); access requires MALLOC2 lock */
-+
-+/* num_disable > 0 iff mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */
-+static unsigned int num_disable = 0;
-+
-+/*
-+ * Valid iff num_disable > 0.  long_malloc_lock is locked exactly in this
-+ * case (by the thread named in disabling_thread).
-+ */
-+static CRYPTO_THREAD_ID disabling_threadid;
-+
-+DEFINE_RUN_ONCE_STATIC(do_memdbg_init)
-+{
-+    malloc_lock = CRYPTO_THREAD_lock_new();
-+    long_malloc_lock = CRYPTO_THREAD_lock_new();
-+    if (malloc_lock == NULL || long_malloc_lock == NULL
-+        || !CRYPTO_THREAD_init_local(&appinfokey, NULL)) {
-+        CRYPTO_THREAD_lock_free(malloc_lock);
-+        malloc_lock = NULL;
-+        CRYPTO_THREAD_lock_free(long_malloc_lock);
-+        long_malloc_lock = NULL;
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+static void app_info_free(APP_INFO *inf)
-+{
-+    if (!inf)
-+        return;
-+    if (--(inf->references) <= 0) {
-+        app_info_free(inf->next);
-+        OPENSSL_free(inf);
-+    }
-+}
-+#endif
-+
-+int CRYPTO_mem_ctrl(int mode)
-+{
-+#ifdef OPENSSL_NO_CRYPTO_MDEBUG
-+    return mode - mode;
-+#else
-+    int ret = mh_mode;
-+
-+    if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
-+        return -1;
-+
-+    CRYPTO_THREAD_write_lock(malloc_lock);
-+    switch (mode) {
-+    default:
-+        break;
-+
-+    case CRYPTO_MEM_CHECK_ON:
-+        mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE;
-+        num_disable = 0;
-+        break;
-+
-+    case CRYPTO_MEM_CHECK_OFF:
-+        mh_mode = 0;
-+        num_disable = 0;
-+        break;
-+
-+    /* switch off temporarily (for library-internal use): */
-+    case CRYPTO_MEM_CHECK_DISABLE:
-+        if (mh_mode & CRYPTO_MEM_CHECK_ON) {
-+            CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id();
-+            /* see if we don't have long_malloc_lock already */
-+            if (!num_disable
-+                || !CRYPTO_THREAD_compare_id(disabling_threadid, cur)) {
-+                /*
-+                 * Long-time lock long_malloc_lock must not be claimed
-+                 * while we're holding malloc_lock, or we'll deadlock
-+                 * if somebody else holds long_malloc_lock (and cannot
-+                 * release it because we block entry to this function). Give
-+                 * them a chance, first, and then claim the locks in
-+                 * appropriate order (long-time lock first).
-+                 */
-+                CRYPTO_THREAD_unlock(malloc_lock);
-+                /*
-+                 * Note that after we have waited for long_malloc_lock and
-+                 * malloc_lock, we'll still be in the right "case" and
-+                 * "if" branch because MemCheck_start and MemCheck_stop may
-+                 * never be used while there are multiple OpenSSL threads.
-+                 */
-+                CRYPTO_THREAD_write_lock(long_malloc_lock);
-+                CRYPTO_THREAD_write_lock(malloc_lock);
-+                mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
-+                disabling_threadid = cur;
-+            }
-+            num_disable++;
-+        }
-+        break;
-+
-+    case CRYPTO_MEM_CHECK_ENABLE:
-+        if (mh_mode & CRYPTO_MEM_CHECK_ON) {
-+            if (num_disable) {  /* always true, or something is going wrong */
-+                num_disable--;
-+                if (num_disable == 0) {
-+                    mh_mode |= CRYPTO_MEM_CHECK_ENABLE;
-+                    CRYPTO_THREAD_unlock(long_malloc_lock);
-+                }
-+            }
-+        }
-+        break;
-+    }
-+    CRYPTO_THREAD_unlock(malloc_lock);
-+    return (ret);
-+#endif
-+}
-+
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
-+
-+static int mem_check_on(void)
-+{
-+    int ret = 0;
-+    CRYPTO_THREAD_ID cur;
-+
-+    if (mh_mode & CRYPTO_MEM_CHECK_ON) {
-+        if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
-+            return 0;
-+
-+        cur = CRYPTO_THREAD_get_current_id();
-+        CRYPTO_THREAD_read_lock(malloc_lock);
-+
-+        ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
-+            || !CRYPTO_THREAD_compare_id(disabling_threadid, cur);
-+
-+        CRYPTO_THREAD_unlock(malloc_lock);
-+    }
-+    return (ret);
-+}
-+
-+static int mem_cmp(const MEM *a, const MEM *b)
-+{
-+#ifdef _WIN64
-+    const char *ap = (const char *)a->addr, *bp = (const char *)b->addr;
-+    if (ap == bp)
-+        return 0;
-+    else if (ap > bp)
-+        return 1;
-+    else
-+        return -1;
-+#else
-+    return (const char *)a->addr - (const char *)b->addr;
-+#endif
-+}
-+
-+static unsigned long mem_hash(const MEM *a)
-+{
-+    size_t ret;
-+
-+    ret = (size_t)a->addr;
-+
-+    ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251;
-+    return (ret);
-+}
-+
-+/* returns 1 if there was an info to pop, 0 if the stack was empty. */
-+static int pop_info(void)
-+{
-+    APP_INFO *current = NULL;
-+
-+    if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
-+        return 0;
-+
-+    current = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
-+    if (current != NULL) {
-+        APP_INFO *next = current->next;
-+
-+        if (next != NULL) {
-+            next->references++;
-+            CRYPTO_THREAD_set_local(&appinfokey, next);
-+        } else {
-+            CRYPTO_THREAD_set_local(&appinfokey, NULL);
-+        }
-+        if (--(current->references) <= 0) {
-+            current->next = NULL;
-+            if (next != NULL)
-+                next->references--;
-+            OPENSSL_free(current);
-+        }
-+        return 1;
-+    }
-+    return 0;
-+}
-+
-+int CRYPTO_mem_debug_push(const char *info, const char *file, int line)
-+{
-+    APP_INFO *ami, *amim;
-+    int ret = 0;
-+
-+    if (mem_check_on()) {
-+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+
-+        if (!RUN_ONCE(&memdbg_init, do_memdbg_init)
-+            || (ami = OPENSSL_malloc(sizeof(*ami))) == NULL)
-+            goto err;
-+
-+        ami->threadid = CRYPTO_THREAD_get_current_id();
-+        ami->file = file;
-+        ami->line = line;
-+        ami->info = info;
-+        ami->references = 1;
-+        ami->next = NULL;
-+
-+        amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
-+        CRYPTO_THREAD_set_local(&appinfokey, ami);
-+
-+        if (amim != NULL)
-+            ami->next = amim;
-+        ret = 1;
-+ err:
-+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+    }
-+
-+    return (ret);
-+}
-+
-+int CRYPTO_mem_debug_pop(void)
-+{
-+    int ret = 0;
-+
-+    if (mem_check_on()) {
-+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+        ret = pop_info();
-+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+    }
-+    return (ret);
-+}
-+
-+static unsigned long break_order_num = 0;
-+
-+void CRYPTO_mem_debug_malloc(void *addr, size_t num, int before_p,
-+                             const char *file, int line)
-+{
-+    MEM *m, *mm;
-+    APP_INFO *amim;
-+
-+    switch (before_p & 127) {
-+    case 0:
-+        break;
-+    case 1:
-+        if (addr == NULL)
-+            break;
-+
-+        if (mem_check_on()) {
-+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+
-+            if (!RUN_ONCE(&memdbg_init, do_memdbg_init)
-+                || (m = OPENSSL_malloc(sizeof(*m))) == NULL) {
-+                OPENSSL_free(addr);
-+                CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+                return;
-+            }
-+            if (mh == NULL) {
-+                if ((mh = lh_MEM_new(mem_hash, mem_cmp)) == NULL) {
-+                    OPENSSL_free(addr);
-+                    OPENSSL_free(m);
-+                    addr = NULL;
-+                    goto err;
-+                }
-+            }
-+
-+            m->addr = addr;
-+            m->file = file;
-+            m->line = line;
-+            m->num = num;
-+            m->threadid = CRYPTO_THREAD_get_current_id();
-+
-+            if (order == break_order_num) {
-+                /* BREAK HERE */
-+                m->order = order;
-+            }
-+            m->order = order++;
-+# ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
-+            m->array_siz = backtrace(m->array, OSSL_NELEM(m->array));
-+# endif
-+            m->time = time(NULL);
-+
-+            amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
-+            m->app_info = amim;
-+            if (amim != NULL)
-+                amim->references++;
-+
-+            if ((mm = lh_MEM_insert(mh, m)) != NULL) {
-+                /* Not good, but don't sweat it */
-+                if (mm->app_info != NULL) {
-+                    mm->app_info->references--;
-+                }
-+                OPENSSL_free(mm);
-+            }
-+ err:
-+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+        }
-+        break;
-+    }
-+    return;
-+}
-+
-+void CRYPTO_mem_debug_free(void *addr, int before_p,
-+        const char *file, int line)
-+{
-+    MEM m, *mp;
-+
-+    switch (before_p) {
-+    case 0:
-+        if (addr == NULL)
-+            break;
-+
-+        if (mem_check_on() && (mh != NULL)) {
-+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+
-+            m.addr = addr;
-+            mp = lh_MEM_delete(mh, &m);
-+            if (mp != NULL) {
-+                app_info_free(mp->app_info);
-+                OPENSSL_free(mp);
-+            }
-+
-+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+        }
-+        break;
-+    case 1:
-+        break;
-+    }
-+}
-+
-+void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num,
-+                              int before_p, const char *file, int line)
-+{
-+    MEM m, *mp;
-+
-+    switch (before_p) {
-+    case 0:
-+        break;
-+    case 1:
-+        if (addr2 == NULL)
-+            break;
-+
-+        if (addr1 == NULL) {
-+            CRYPTO_mem_debug_malloc(addr2, num, 128 | before_p, file, line);
-+            break;
-+        }
-+
-+        if (mem_check_on()) {
-+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+
-+            m.addr = addr1;
-+            mp = lh_MEM_delete(mh, &m);
-+            if (mp != NULL) {
-+                mp->addr = addr2;
-+                mp->num = num;
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
-+                mp->array_siz = backtrace(mp->array, OSSL_NELEM(mp->array));
-+#endif
-+                (void)lh_MEM_insert(mh, mp);
-+            }
-+
-+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+        }
-+        break;
-+    }
-+    return;
-+}
-+
-+typedef struct mem_leak_st {
-+    BIO *bio;
-+    int chunks;
-+    long bytes;
-+} MEM_LEAK;
-+
-+static void print_leak(const MEM *m, MEM_LEAK *l)
-+{
-+    char buf[1024];
-+    char *bufp = buf;
-+    APP_INFO *amip;
-+    int ami_cnt;
-+    struct tm *lcl = NULL;
-+    /*
-+     * Convert between CRYPTO_THREAD_ID (which could be anything at all) and
-+     * a long. This may not be meaningful depending on what CRYPTO_THREAD_ID is
-+     * but hopefully should give something sensible on most platforms
-+     */
-+    union {
-+        CRYPTO_THREAD_ID tid;
-+        unsigned long ltid;
-+    } tid;
-+    CRYPTO_THREAD_ID ti;
-+
-+#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
-+
-+    lcl = localtime(&m->time);
-+    BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
-+                 lcl->tm_hour, lcl->tm_min, lcl->tm_sec);
-+    bufp += strlen(bufp);
-+
-+    BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
-+                 m->order, m->file, m->line);
-+    bufp += strlen(bufp);
-+
-+    tid.ltid = 0;
-+    tid.tid = m->threadid;
-+    BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", tid.ltid);
-+    bufp += strlen(bufp);
-+
-+    BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%p\n",
-+                 m->num, m->addr);
-+    bufp += strlen(bufp);
-+
-+    BIO_puts(l->bio, buf);
-+
-+    l->chunks++;
-+    l->bytes += m->num;
-+
-+    amip = m->app_info;
-+    ami_cnt = 0;
-+
-+    if (amip) {
-+        ti = amip->threadid;
-+
-+        do {
-+            int buf_len;
-+            int info_len;
-+
-+            ami_cnt++;
-+            memset(buf, '>', ami_cnt);
-+            tid.ltid = 0;
-+            tid.tid = amip->threadid;
-+            BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
-+                         " thread=%lu, file=%s, line=%d, info=\"",
-+                         tid.ltid, amip->file,
-+                         amip->line);
-+            buf_len = strlen(buf);
-+            info_len = strlen(amip->info);
-+            if (128 - buf_len - 3 < info_len) {
-+                memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
-+                buf_len = 128 - 3;
-+            } else {
-+                OPENSSL_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len);
-+                buf_len = strlen(buf);
-+            }
-+            BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
-+
-+            BIO_puts(l->bio, buf);
-+
-+            amip = amip->next;
-+        }
-+        while (amip && CRYPTO_THREAD_compare_id(amip->threadid, ti));
-+    }
-+
-+#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
-+    {
-+        size_t i;
-+        char **strings = backtrace_symbols(m->array, m->array_siz);
-+
-+        for (i = 0; i < m->array_siz; i++)
-+            fprintf(stderr, "##> %s\n", strings[i]);
-+        free(strings);
-+    }
-+#endif
-+}
-+
-+IMPLEMENT_LHASH_DOALL_ARG_CONST(MEM, MEM_LEAK);
-+
-+int CRYPTO_mem_leaks(BIO *b)
-+{
-+    MEM_LEAK ml;
-+
-+    /*
-+     * OPENSSL_cleanup() will free the ex_data locks so we can't have any
-+     * ex_data hanging around
-+     */
-+    bio_free_ex_data(b);
-+
-+    /* Ensure all resources are released */
-+    OPENSSL_cleanup();
-+
-+    if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
-+        return -1;
-+
-+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+
-+    ml.bio = b;
-+    ml.bytes = 0;
-+    ml.chunks = 0;
-+    if (mh != NULL)
-+        lh_MEM_doall_MEM_LEAK(mh, print_leak, &ml);
-+
-+    if (ml.chunks != 0) {
-+        BIO_printf(b, "%ld bytes leaked in %d chunks\n", ml.bytes, ml.chunks);
-+    } else {
-+        /*
-+         * Make sure that, if we found no leaks, memory-leak debugging itself
-+         * does not introduce memory leaks (which might irritate external
-+         * debugging tools). (When someone enables leak checking, but does not
-+         * call this function, we declare it to be their fault.)
-+         */
-+        int old_mh_mode;
-+
-+        CRYPTO_THREAD_write_lock(malloc_lock);
-+
-+        /*
-+         * avoid deadlock when lh_free() uses CRYPTO_mem_debug_free(), which uses
-+         * mem_check_on
-+         */
-+        old_mh_mode = mh_mode;
-+        mh_mode = CRYPTO_MEM_CHECK_OFF;
-+
-+        lh_MEM_free(mh);
-+        mh = NULL;
-+
-+        mh_mode = old_mh_mode;
-+        CRYPTO_THREAD_unlock(malloc_lock);
-+    }
-+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
-+
-+    /* Clean up locks etc */
-+    CRYPTO_THREAD_cleanup_local(&appinfokey);
-+    CRYPTO_THREAD_lock_free(malloc_lock);
-+    CRYPTO_THREAD_lock_free(long_malloc_lock);
-+    malloc_lock = NULL;
-+    long_malloc_lock = NULL;
-+
-+    return ml.chunks == 0 ? 1 : 0;
-+}
-+
-+# ifndef OPENSSL_NO_STDIO
-+int CRYPTO_mem_leaks_fp(FILE *fp)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    /*
-+     * Need to turn off memory checking when allocated BIOs ... especially as
-+     * we're creating them at a time when we're trying to check we've not
-+     * left anything un-free()'d!!
-+     */
-+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+    b = BIO_new(BIO_s_file());
-+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+    if (b == NULL)
-+        return -1;
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = CRYPTO_mem_leaks(b);
-+    BIO_free(b);
-+    return ret;
-+}
-+# endif
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/mem_sec.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/mem_sec.c
-new file mode 100644
-index 0000000..0c79b43
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/mem_sec.c
-@@ -0,0 +1,585 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Copyright 2004-2014, Akamai Technologies. All Rights Reserved.
-+ * This file is distributed under the terms of the OpenSSL license.
-+ */
-+
-+/*
-+ * This file is in two halves. The first half implements the public API
-+ * to be used by external consumers, and to be used by OpenSSL to store
-+ * data in a "secure arena." The second half implements the secure arena.
-+ * For details on that implementation, see below (look for uppercase
-+ * "SECURE HEAP IMPLEMENTATION").
-+ */
-+#include 
-+#include 
-+
-+#include 
-+
-+#if defined(OPENSSL_SYS_LINUX) || defined(OPENSSL_SYS_UNIX)
-+# define IMPLEMENTED
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+#endif
-+
-+#define CLEAR(p, s) OPENSSL_cleanse(p, s)
-+#ifndef PAGE_SIZE
-+# define PAGE_SIZE    4096
-+#endif
-+
-+#ifdef IMPLEMENTED
-+static size_t secure_mem_used;
-+
-+static int secure_mem_initialized;
-+
-+static CRYPTO_RWLOCK *sec_malloc_lock = NULL;
-+
-+/*
-+ * These are the functions that must be implemented by a secure heap (sh).
-+ */
-+static int sh_init(size_t size, int minsize);
-+static char *sh_malloc(size_t size);
-+static void sh_free(char *ptr);
-+static void sh_done(void);
-+static size_t sh_actual_size(char *ptr);
-+static int sh_allocated(const char *ptr);
-+#endif
-+
-+int CRYPTO_secure_malloc_init(size_t size, int minsize)
-+{
-+#ifdef IMPLEMENTED
-+    int ret = 0;
-+
-+    if (!secure_mem_initialized) {
-+        sec_malloc_lock = CRYPTO_THREAD_lock_new();
-+        if (sec_malloc_lock == NULL)
-+            return 0;
-+        ret = sh_init(size, minsize);
-+        secure_mem_initialized = 1;
-+    }
-+
-+    return ret;
-+#else
-+    return 0;
-+#endif /* IMPLEMENTED */
-+}
-+
-+int CRYPTO_secure_malloc_done()
-+{
-+#ifdef IMPLEMENTED
-+    if (secure_mem_used == 0) {
-+        sh_done();
-+        secure_mem_initialized = 0;
-+        CRYPTO_THREAD_lock_free(sec_malloc_lock);
-+        return 1;
-+    }
-+#endif /* IMPLEMENTED */
-+    return 0;
-+}
-+
-+int CRYPTO_secure_malloc_initialized()
-+{
-+#ifdef IMPLEMENTED
-+    return secure_mem_initialized;
-+#else
-+    return 0;
-+#endif /* IMPLEMENTED */
-+}
-+
-+void *CRYPTO_secure_malloc(size_t num, const char *file, int line)
-+{
-+#ifdef IMPLEMENTED
-+    void *ret;
-+    size_t actual_size;
-+
-+    if (!secure_mem_initialized) {
-+        return CRYPTO_malloc(num, file, line);
-+    }
-+    CRYPTO_THREAD_write_lock(sec_malloc_lock);
-+    ret = sh_malloc(num);
-+    actual_size = ret ? sh_actual_size(ret) : 0;
-+    secure_mem_used += actual_size;
-+    CRYPTO_THREAD_unlock(sec_malloc_lock);
-+    return ret;
-+#else
-+    return CRYPTO_malloc(num, file, line);
-+#endif /* IMPLEMENTED */
-+}
-+
-+void *CRYPTO_secure_zalloc(size_t num, const char *file, int line)
-+{
-+    void *ret = CRYPTO_secure_malloc(num, file, line);
-+
-+    if (ret != NULL)
-+        memset(ret, 0, num);
-+    return ret;
-+}
-+
-+void CRYPTO_secure_free(void *ptr, const char *file, int line)
-+{
-+#ifdef IMPLEMENTED
-+    size_t actual_size;
-+
-+    if (ptr == NULL)
-+        return;
-+    if (!CRYPTO_secure_allocated(ptr)) {
-+        CRYPTO_free(ptr, file, line);
-+        return;
-+    }
-+    CRYPTO_THREAD_write_lock(sec_malloc_lock);
-+    actual_size = sh_actual_size(ptr);
-+    CLEAR(ptr, actual_size);
-+    secure_mem_used -= actual_size;
-+    sh_free(ptr);
-+    CRYPTO_THREAD_unlock(sec_malloc_lock);
-+#else
-+    CRYPTO_free(ptr, file, line);
-+#endif /* IMPLEMENTED */
-+}
-+
-+int CRYPTO_secure_allocated(const void *ptr)
-+{
-+#ifdef IMPLEMENTED
-+    int ret;
-+
-+    if (!secure_mem_initialized)
-+        return 0;
-+    CRYPTO_THREAD_write_lock(sec_malloc_lock);
-+    ret = sh_allocated(ptr);
-+    CRYPTO_THREAD_unlock(sec_malloc_lock);
-+    return ret;
-+#else
-+    return 0;
-+#endif /* IMPLEMENTED */
-+}
-+
-+size_t CRYPTO_secure_used()
-+{
-+#ifdef IMPLEMENTED
-+    return secure_mem_used;
-+#else
-+    return 0;
-+#endif /* IMPLEMENTED */
-+}
-+
-+size_t CRYPTO_secure_actual_size(void *ptr)
-+{
-+#ifdef IMPLEMENTED
-+    size_t actual_size;
-+
-+    CRYPTO_THREAD_write_lock(sec_malloc_lock);
-+    actual_size = sh_actual_size(ptr);
-+    CRYPTO_THREAD_unlock(sec_malloc_lock);
-+    return actual_size;
-+#else
-+    return 0;
-+#endif
-+}
-+/* END OF PAGE ...
-+
-+   ... START OF PAGE */
-+
-+/*
-+ * SECURE HEAP IMPLEMENTATION
-+ */
-+#ifdef IMPLEMENTED
-+
-+
-+/*
-+ * The implementation provided here uses a fixed-sized mmap() heap,
-+ * which is locked into memory, not written to core files, and protected
-+ * on either side by an unmapped page, which will catch pointer overruns
-+ * (or underruns) and an attempt to read data out of the secure heap.
-+ * Free'd memory is zero'd or otherwise cleansed.
-+ *
-+ * This is a pretty standard buddy allocator.  We keep areas in a multiple
-+ * of "sh.minsize" units.  The freelist and bitmaps are kept separately,
-+ * so all (and only) data is kept in the mmap'd heap.
-+ *
-+ * This code assumes eight-bit bytes.  The numbers 3 and 7 are all over the
-+ * place.
-+ */
-+
-+#define ONE ((size_t)1)
-+
-+# define TESTBIT(t, b)  (t[(b) >> 3] &  (ONE << ((b) & 7)))
-+# define SETBIT(t, b)   (t[(b) >> 3] |= (ONE << ((b) & 7)))
-+# define CLEARBIT(t, b) (t[(b) >> 3] &= (0xFF & ~(ONE << ((b) & 7))))
-+
-+#define WITHIN_ARENA(p) \
-+    ((char*)(p) >= sh.arena && (char*)(p) < &sh.arena[sh.arena_size])
-+#define WITHIN_FREELIST(p) \
-+    ((char*)(p) >= (char*)sh.freelist && (char*)(p) < (char*)&sh.freelist[sh.freelist_size])
-+
-+
-+typedef struct sh_list_st
-+{
-+    struct sh_list_st *next;
-+    struct sh_list_st **p_next;
-+} SH_LIST;
-+
-+typedef struct sh_st
-+{
-+    char* map_result;
-+    size_t map_size;
-+    char *arena;
-+    size_t arena_size;
-+    char **freelist;
-+    ossl_ssize_t freelist_size;
-+    size_t minsize;
-+    unsigned char *bittable;
-+    unsigned char *bitmalloc;
-+    size_t bittable_size; /* size in bits */
-+} SH;
-+
-+static SH sh;
-+
-+static size_t sh_getlist(char *ptr)
-+{
-+    ossl_ssize_t list = sh.freelist_size - 1;
-+    size_t bit = (sh.arena_size + ptr - sh.arena) / sh.minsize;
-+
-+    for (; bit; bit >>= 1, list--) {
-+        if (TESTBIT(sh.bittable, bit))
-+            break;
-+        OPENSSL_assert((bit & 1) == 0);
-+    }
-+
-+    return list;
-+}
-+
-+
-+static int sh_testbit(char *ptr, int list, unsigned char *table)
-+{
-+    size_t bit;
-+
-+    OPENSSL_assert(list >= 0 && list < sh.freelist_size);
-+    OPENSSL_assert(((ptr - sh.arena) & ((sh.arena_size >> list) - 1)) == 0);
-+    bit = (ONE << list) + ((ptr - sh.arena) / (sh.arena_size >> list));
-+    OPENSSL_assert(bit > 0 && bit < sh.bittable_size);
-+    return TESTBIT(table, bit);
-+}
-+
-+static void sh_clearbit(char *ptr, int list, unsigned char *table)
-+{
-+    size_t bit;
-+
-+    OPENSSL_assert(list >= 0 && list < sh.freelist_size);
-+    OPENSSL_assert(((ptr - sh.arena) & ((sh.arena_size >> list) - 1)) == 0);
-+    bit = (ONE << list) + ((ptr - sh.arena) / (sh.arena_size >> list));
-+    OPENSSL_assert(bit > 0 && bit < sh.bittable_size);
-+    OPENSSL_assert(TESTBIT(table, bit));
-+    CLEARBIT(table, bit);
-+}
-+
-+static void sh_setbit(char *ptr, int list, unsigned char *table)
-+{
-+    size_t bit;
-+
-+    OPENSSL_assert(list >= 0 && list < sh.freelist_size);
-+    OPENSSL_assert(((ptr - sh.arena) & ((sh.arena_size >> list) - 1)) == 0);
-+    bit = (ONE << list) + ((ptr - sh.arena) / (sh.arena_size >> list));
-+    OPENSSL_assert(bit > 0 && bit < sh.bittable_size);
-+    OPENSSL_assert(!TESTBIT(table, bit));
-+    SETBIT(table, bit);
-+}
-+
-+static void sh_add_to_list(char **list, char *ptr)
-+{
-+    SH_LIST *temp;
-+
-+    OPENSSL_assert(WITHIN_FREELIST(list));
-+    OPENSSL_assert(WITHIN_ARENA(ptr));
-+
-+    temp = (SH_LIST *)ptr;
-+    temp->next = *(SH_LIST **)list;
-+    OPENSSL_assert(temp->next == NULL || WITHIN_ARENA(temp->next));
-+    temp->p_next = (SH_LIST **)list;
-+
-+    if (temp->next != NULL) {
-+        OPENSSL_assert((char **)temp->next->p_next == list);
-+        temp->next->p_next = &(temp->next);
-+    }
-+
-+    *list = ptr;
-+}
-+
-+static void sh_remove_from_list(char *ptr)
-+{
-+    SH_LIST *temp, *temp2;
-+
-+    temp = (SH_LIST *)ptr;
-+    if (temp->next != NULL)
-+        temp->next->p_next = temp->p_next;
-+    *temp->p_next = temp->next;
-+    if (temp->next == NULL)
-+        return;
-+
-+    temp2 = temp->next;
-+    OPENSSL_assert(WITHIN_FREELIST(temp2->p_next) || WITHIN_ARENA(temp2->p_next));
-+}
-+
-+
-+static int sh_init(size_t size, int minsize)
-+{
-+    int i, ret;
-+    size_t pgsize;
-+    size_t aligned;
-+
-+    memset(&sh, 0, sizeof sh);
-+
-+    /* make sure size and minsize are powers of 2 */
-+    OPENSSL_assert(size > 0);
-+    OPENSSL_assert((size & (size - 1)) == 0);
-+    OPENSSL_assert(minsize > 0);
-+    OPENSSL_assert((minsize & (minsize - 1)) == 0);
-+    if (size <= 0 || (size & (size - 1)) != 0)
-+        goto err;
-+    if (minsize <= 0 || (minsize & (minsize - 1)) != 0)
-+        goto err;
-+
-+    sh.arena_size = size;
-+    sh.minsize = minsize;
-+    sh.bittable_size = (sh.arena_size / sh.minsize) * 2;
-+
-+    /* Prevent allocations of size 0 later on */
-+    if (sh.bittable_size >> 3 == 0)
-+        goto err;
-+
-+    sh.freelist_size = -1;
-+    for (i = sh.bittable_size; i; i >>= 1)
-+        sh.freelist_size++;
-+
-+    sh.freelist = OPENSSL_zalloc(sh.freelist_size * sizeof (char *));
-+    OPENSSL_assert(sh.freelist != NULL);
-+    if (sh.freelist == NULL)
-+        goto err;
-+
-+    sh.bittable = OPENSSL_zalloc(sh.bittable_size >> 3);
-+    OPENSSL_assert(sh.bittable != NULL);
-+    if (sh.bittable == NULL)
-+        goto err;
-+
-+    sh.bitmalloc = OPENSSL_zalloc(sh.bittable_size >> 3);
-+    OPENSSL_assert(sh.bitmalloc != NULL);
-+    if (sh.bitmalloc == NULL)
-+        goto err;
-+
-+    /* Allocate space for heap, and two extra pages as guards */
-+#if defined(_SC_PAGE_SIZE) || defined (_SC_PAGESIZE)
-+    {
-+# if defined(_SC_PAGE_SIZE)
-+        long tmppgsize = sysconf(_SC_PAGE_SIZE);
-+# else
-+        long tmppgsize = sysconf(_SC_PAGESIZE);
-+# endif
-+        if (tmppgsize < 1)
-+            pgsize = PAGE_SIZE;
-+        else
-+            pgsize = (size_t)tmppgsize;
-+    }
-+#else
-+    pgsize = PAGE_SIZE;
-+#endif
-+    sh.map_size = pgsize + sh.arena_size + pgsize;
-+    if (1) {
-+#ifdef MAP_ANON
-+        sh.map_result = mmap(NULL, sh.map_size,
-+                             PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-+    } else {
-+#endif
-+        int fd;
-+
-+        sh.map_result = MAP_FAILED;
-+        if ((fd = open("/dev/zero", O_RDWR)) >= 0) {
-+            sh.map_result = mmap(NULL, sh.map_size,
-+                                 PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
-+            close(fd);
-+        }
-+    }
-+    OPENSSL_assert(sh.map_result != MAP_FAILED);
-+    if (sh.map_result == MAP_FAILED)
-+        goto err;
-+    sh.arena = (char *)(sh.map_result + pgsize);
-+    sh_setbit(sh.arena, 0, sh.bittable);
-+    sh_add_to_list(&sh.freelist[0], sh.arena);
-+
-+    /* Now try to add guard pages and lock into memory. */
-+    ret = 1;
-+
-+    /* Starting guard is already aligned from mmap. */
-+    if (mprotect(sh.map_result, pgsize, PROT_NONE) < 0)
-+        ret = 2;
-+
-+    /* Ending guard page - need to round up to page boundary */
-+    aligned = (pgsize + sh.arena_size + (pgsize - 1)) & ~(pgsize - 1);
-+    if (mprotect(sh.map_result + aligned, pgsize, PROT_NONE) < 0)
-+        ret = 2;
-+
-+    if (mlock(sh.arena, sh.arena_size) < 0)
-+        ret = 2;
-+#ifdef MADV_DONTDUMP
-+    if (madvise(sh.arena, sh.arena_size, MADV_DONTDUMP) < 0)
-+        ret = 2;
-+#endif
-+
-+    return ret;
-+
-+ err:
-+    sh_done();
-+    return 0;
-+}
-+
-+static void sh_done()
-+{
-+    OPENSSL_free(sh.freelist);
-+    OPENSSL_free(sh.bittable);
-+    OPENSSL_free(sh.bitmalloc);
-+    if (sh.map_result != NULL && sh.map_size)
-+        munmap(sh.map_result, sh.map_size);
-+    memset(&sh, 0, sizeof sh);
-+}
-+
-+static int sh_allocated(const char *ptr)
-+{
-+    return WITHIN_ARENA(ptr) ? 1 : 0;
-+}
-+
-+static char *sh_find_my_buddy(char *ptr, int list)
-+{
-+    size_t bit;
-+    char *chunk = NULL;
-+
-+    bit = (ONE << list) + (ptr - sh.arena) / (sh.arena_size >> list);
-+    bit ^= 1;
-+
-+    if (TESTBIT(sh.bittable, bit) && !TESTBIT(sh.bitmalloc, bit))
-+        chunk = sh.arena + ((bit & ((ONE << list) - 1)) * (sh.arena_size >> list));
-+
-+    return chunk;
-+}
-+
-+static char *sh_malloc(size_t size)
-+{
-+    ossl_ssize_t list, slist;
-+    size_t i;
-+    char *chunk;
-+
-+    list = sh.freelist_size - 1;
-+    for (i = sh.minsize; i < size; i <<= 1)
-+        list--;
-+    if (list < 0)
-+        return NULL;
-+
-+    /* try to find a larger entry to split */
-+    for (slist = list; slist >= 0; slist--)
-+        if (sh.freelist[slist] != NULL)
-+            break;
-+    if (slist < 0)
-+        return NULL;
-+
-+    /* split larger entry */
-+    while (slist != list) {
-+        char *temp = sh.freelist[slist];
-+
-+        /* remove from bigger list */
-+        OPENSSL_assert(!sh_testbit(temp, slist, sh.bitmalloc));
-+        sh_clearbit(temp, slist, sh.bittable);
-+        sh_remove_from_list(temp);
-+        OPENSSL_assert(temp != sh.freelist[slist]);
-+
-+        /* done with bigger list */
-+        slist++;
-+
-+        /* add to smaller list */
-+        OPENSSL_assert(!sh_testbit(temp, slist, sh.bitmalloc));
-+        sh_setbit(temp, slist, sh.bittable);
-+        sh_add_to_list(&sh.freelist[slist], temp);
-+        OPENSSL_assert(sh.freelist[slist] == temp);
-+
-+        /* split in 2 */
-+        temp += sh.arena_size >> slist;
-+        OPENSSL_assert(!sh_testbit(temp, slist, sh.bitmalloc));
-+        sh_setbit(temp, slist, sh.bittable);
-+        sh_add_to_list(&sh.freelist[slist], temp);
-+        OPENSSL_assert(sh.freelist[slist] == temp);
-+
-+        OPENSSL_assert(temp-(sh.arena_size >> slist) == sh_find_my_buddy(temp, slist));
-+    }
-+
-+    /* peel off memory to hand back */
-+    chunk = sh.freelist[list];
-+    OPENSSL_assert(sh_testbit(chunk, list, sh.bittable));
-+    sh_setbit(chunk, list, sh.bitmalloc);
-+    sh_remove_from_list(chunk);
-+
-+    OPENSSL_assert(WITHIN_ARENA(chunk));
-+
-+    return chunk;
-+}
-+
-+static void sh_free(char *ptr)
-+{
-+    size_t list;
-+    char *buddy;
-+
-+    if (ptr == NULL)
-+        return;
-+    OPENSSL_assert(WITHIN_ARENA(ptr));
-+    if (!WITHIN_ARENA(ptr))
-+        return;
-+
-+    list = sh_getlist(ptr);
-+    OPENSSL_assert(sh_testbit(ptr, list, sh.bittable));
-+    sh_clearbit(ptr, list, sh.bitmalloc);
-+    sh_add_to_list(&sh.freelist[list], ptr);
-+
-+    /* Try to coalesce two adjacent free areas. */
-+    while ((buddy = sh_find_my_buddy(ptr, list)) != NULL) {
-+        OPENSSL_assert(ptr == sh_find_my_buddy(buddy, list));
-+        OPENSSL_assert(ptr != NULL);
-+        OPENSSL_assert(!sh_testbit(ptr, list, sh.bitmalloc));
-+        sh_clearbit(ptr, list, sh.bittable);
-+        sh_remove_from_list(ptr);
-+        OPENSSL_assert(!sh_testbit(ptr, list, sh.bitmalloc));
-+        sh_clearbit(buddy, list, sh.bittable);
-+        sh_remove_from_list(buddy);
-+
-+        list--;
-+
-+        if (ptr > buddy)
-+            ptr = buddy;
-+
-+        OPENSSL_assert(!sh_testbit(ptr, list, sh.bitmalloc));
-+        sh_setbit(ptr, list, sh.bittable);
-+        sh_add_to_list(&sh.freelist[list], ptr);
-+        OPENSSL_assert(sh.freelist[list] == ptr);
-+    }
-+}
-+
-+static size_t sh_actual_size(char *ptr)
-+{
-+    int list;
-+
-+    OPENSSL_assert(WITHIN_ARENA(ptr));
-+    if (!WITHIN_ARENA(ptr))
-+        return 0;
-+    list = sh_getlist(ptr);
-+    OPENSSL_assert(sh_testbit(ptr, list, sh.bittable));
-+    return sh.arena_size / (ONE << list);
-+}
-+#endif /* IMPLEMENTED */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/aesni-gcm-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/aesni-gcm-x86_64.pl
-new file mode 100644
-index 0000000..5ad62b3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/aesni-gcm-x86_64.pl
-@@ -0,0 +1,1106 @@
-+#! /usr/bin/env perl
-+# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+#
-+# AES-NI-CTR+GHASH stitch.
-+#
-+# February 2013
-+#
-+# OpenSSL GCM implementation is organized in such way that its
-+# performance is rather close to the sum of its streamed components,
-+# in the context parallelized AES-NI CTR and modulo-scheduled
-+# PCLMULQDQ-enabled GHASH. Unfortunately, as no stitch implementation
-+# was observed to perform significantly better than the sum of the
-+# components on contemporary CPUs, the effort was deemed impossible to
-+# justify. This module is based on combination of Intel submissions,
-+# [1] and [2], with MOVBE twist suggested by Ilya Albrekht and Max
-+# Locktyukhin of Intel Corp. who verified that it reduces shuffles
-+# pressure with notable relative improvement, achieving 1.0 cycle per
-+# byte processed with 128-bit key on Haswell processor, 0.74 - on
-+# Broadwell, 0.63 - on Skylake... [Mentioned results are raw profiled
-+# measurements for favourable packet size, one divisible by 96.
-+# Applications using the EVP interface will observe a few percent
-+# worse performance.]
-+#
-+# [1] http://rt.openssl.org/Ticket/Display.html?id=2900&user=guest&pass=guest
-+# [2] http://www.intel.com/content/dam/www/public/us/en/documents/software-support/enabling-high-performance-gcm.pdf
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.20) + ($1>=2.22);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	    `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	    `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+if ($avx>1) {{{
-+
-+($inp,$out,$len,$key,$ivp,$Xip)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9");
-+
-+($Ii,$T1,$T2,$Hkey,
-+ $Z0,$Z1,$Z2,$Z3,$Xi) = map("%xmm$_",(0..8));
-+
-+($inout0,$inout1,$inout2,$inout3,$inout4,$inout5,$rndkey) = map("%xmm$_",(9..15));
-+
-+($counter,$rounds,$ret,$const,$in0,$end0)=("%ebx","%ebp","%r10","%r11","%r14","%r15");
-+
-+$code=<<___;
-+.text
-+
-+.type	_aesni_ctr32_ghash_6x,\@abi-omnipotent
-+.align	32
-+_aesni_ctr32_ghash_6x:
-+	vmovdqu		0x20($const),$T2	# borrow $T2, .Lone_msb
-+	sub		\$6,$len
-+	vpxor		$Z0,$Z0,$Z0		# $Z0   = 0
-+	vmovdqu		0x00-0x80($key),$rndkey
-+	vpaddb		$T2,$T1,$inout1
-+	vpaddb		$T2,$inout1,$inout2
-+	vpaddb		$T2,$inout2,$inout3
-+	vpaddb		$T2,$inout3,$inout4
-+	vpaddb		$T2,$inout4,$inout5
-+	vpxor		$rndkey,$T1,$inout0
-+	vmovdqu		$Z0,16+8(%rsp)		# "$Z3" = 0
-+	jmp		.Loop6x
-+
-+.align	32
-+.Loop6x:
-+	add		\$`6<<24`,$counter
-+	jc		.Lhandle_ctr32		# discard $inout[1-5]?
-+	vmovdqu		0x00-0x20($Xip),$Hkey	# $Hkey^1
-+	  vpaddb	$T2,$inout5,$T1		# next counter value
-+	  vpxor		$rndkey,$inout1,$inout1
-+	  vpxor		$rndkey,$inout2,$inout2
-+
-+.Lresume_ctr32:
-+	vmovdqu		$T1,($ivp)		# save next counter value
-+	vpclmulqdq	\$0x10,$Hkey,$Z3,$Z1
-+	  vpxor		$rndkey,$inout3,$inout3
-+	  vmovups	0x10-0x80($key),$T2	# borrow $T2 for $rndkey
-+	vpclmulqdq	\$0x01,$Hkey,$Z3,$Z2
-+
-+	# At this point, the current block of 96 (0x60) bytes has already been
-+	# loaded into registers. Concurrently with processing it, we want to
-+	# load the next 96 bytes of input for the next round. Obviously, we can
-+	# only do this if there are at least 96 more bytes of input beyond the
-+	# input we're currently processing, or else we'd read past the end of
-+	# the input buffer. Here, we set |%r12| to 96 if there are at least 96
-+	# bytes of input beyond the 96 bytes we're already processing, and we
-+	# set |%r12| to 0 otherwise. In the case where we set |%r12| to 96,
-+	# we'll read in the next block so that it is in registers for the next
-+	# loop iteration. In the case where we set |%r12| to 0, we'll re-read
-+	# the current block and then ignore what we re-read.
-+	#
-+	# At this point, |$in0| points to the current (already read into
-+	# registers) block, and |$end0| points to 2*96 bytes before the end of
-+	# the input. Thus, |$in0| > |$end0| means that we do not have the next
-+	# 96-byte block to read in, and |$in0| <= |$end0| means we do.
-+	xor		%r12,%r12
-+	cmp		$in0,$end0
-+
-+	  vaesenc	$T2,$inout0,$inout0
-+	vmovdqu		0x30+8(%rsp),$Ii	# I[4]
-+	  vpxor		$rndkey,$inout4,$inout4
-+	vpclmulqdq	\$0x00,$Hkey,$Z3,$T1
-+	  vaesenc	$T2,$inout1,$inout1
-+	  vpxor		$rndkey,$inout5,$inout5
-+	setnc		%r12b
-+	vpclmulqdq	\$0x11,$Hkey,$Z3,$Z3
-+	  vaesenc	$T2,$inout2,$inout2
-+	vmovdqu		0x10-0x20($Xip),$Hkey	# $Hkey^2
-+	neg		%r12
-+	  vaesenc	$T2,$inout3,$inout3
-+	 vpxor		$Z1,$Z2,$Z2
-+	vpclmulqdq	\$0x00,$Hkey,$Ii,$Z1
-+	 vpxor		$Z0,$Xi,$Xi		# modulo-scheduled
-+	  vaesenc	$T2,$inout4,$inout4
-+	 vpxor		$Z1,$T1,$Z0
-+	and		\$0x60,%r12
-+	  vmovups	0x20-0x80($key),$rndkey
-+	vpclmulqdq	\$0x10,$Hkey,$Ii,$T1
-+	  vaesenc	$T2,$inout5,$inout5
-+
-+	vpclmulqdq	\$0x01,$Hkey,$Ii,$T2
-+	lea		($in0,%r12),$in0
-+	  vaesenc	$rndkey,$inout0,$inout0
-+	 vpxor		16+8(%rsp),$Xi,$Xi	# modulo-scheduled [vpxor $Z3,$Xi,$Xi]
-+	vpclmulqdq	\$0x11,$Hkey,$Ii,$Hkey
-+	 vmovdqu	0x40+8(%rsp),$Ii	# I[3]
-+	  vaesenc	$rndkey,$inout1,$inout1
-+	movbe		0x58($in0),%r13
-+	  vaesenc	$rndkey,$inout2,$inout2
-+	movbe		0x50($in0),%r12
-+	  vaesenc	$rndkey,$inout3,$inout3
-+	mov		%r13,0x20+8(%rsp)
-+	  vaesenc	$rndkey,$inout4,$inout4
-+	mov		%r12,0x28+8(%rsp)
-+	vmovdqu		0x30-0x20($Xip),$Z1	# borrow $Z1 for $Hkey^3
-+	  vaesenc	$rndkey,$inout5,$inout5
-+
-+	  vmovups	0x30-0x80($key),$rndkey
-+	 vpxor		$T1,$Z2,$Z2
-+	vpclmulqdq	\$0x00,$Z1,$Ii,$T1
-+	  vaesenc	$rndkey,$inout0,$inout0
-+	 vpxor		$T2,$Z2,$Z2
-+	vpclmulqdq	\$0x10,$Z1,$Ii,$T2
-+	  vaesenc	$rndkey,$inout1,$inout1
-+	 vpxor		$Hkey,$Z3,$Z3
-+	vpclmulqdq	\$0x01,$Z1,$Ii,$Hkey
-+	  vaesenc	$rndkey,$inout2,$inout2
-+	vpclmulqdq	\$0x11,$Z1,$Ii,$Z1
-+	 vmovdqu	0x50+8(%rsp),$Ii	# I[2]
-+	  vaesenc	$rndkey,$inout3,$inout3
-+	  vaesenc	$rndkey,$inout4,$inout4
-+	 vpxor		$T1,$Z0,$Z0
-+	vmovdqu		0x40-0x20($Xip),$T1	# borrow $T1 for $Hkey^4
-+	  vaesenc	$rndkey,$inout5,$inout5
-+
-+	  vmovups	0x40-0x80($key),$rndkey
-+	 vpxor		$T2,$Z2,$Z2
-+	vpclmulqdq	\$0x00,$T1,$Ii,$T2
-+	  vaesenc	$rndkey,$inout0,$inout0
-+	 vpxor		$Hkey,$Z2,$Z2
-+	vpclmulqdq	\$0x10,$T1,$Ii,$Hkey
-+	  vaesenc	$rndkey,$inout1,$inout1
-+	movbe		0x48($in0),%r13
-+	 vpxor		$Z1,$Z3,$Z3
-+	vpclmulqdq	\$0x01,$T1,$Ii,$Z1
-+	  vaesenc	$rndkey,$inout2,$inout2
-+	movbe		0x40($in0),%r12
-+	vpclmulqdq	\$0x11,$T1,$Ii,$T1
-+	 vmovdqu	0x60+8(%rsp),$Ii	# I[1]
-+	  vaesenc	$rndkey,$inout3,$inout3
-+	mov		%r13,0x30+8(%rsp)
-+	  vaesenc	$rndkey,$inout4,$inout4
-+	mov		%r12,0x38+8(%rsp)
-+	 vpxor		$T2,$Z0,$Z0
-+	vmovdqu		0x60-0x20($Xip),$T2	# borrow $T2 for $Hkey^5
-+	  vaesenc	$rndkey,$inout5,$inout5
-+
-+	  vmovups	0x50-0x80($key),$rndkey
-+	 vpxor		$Hkey,$Z2,$Z2
-+	vpclmulqdq	\$0x00,$T2,$Ii,$Hkey
-+	  vaesenc	$rndkey,$inout0,$inout0
-+	 vpxor		$Z1,$Z2,$Z2
-+	vpclmulqdq	\$0x10,$T2,$Ii,$Z1
-+	  vaesenc	$rndkey,$inout1,$inout1
-+	movbe		0x38($in0),%r13
-+	 vpxor		$T1,$Z3,$Z3
-+	vpclmulqdq	\$0x01,$T2,$Ii,$T1
-+	 vpxor		0x70+8(%rsp),$Xi,$Xi	# accumulate I[0]
-+	  vaesenc	$rndkey,$inout2,$inout2
-+	movbe		0x30($in0),%r12
-+	vpclmulqdq	\$0x11,$T2,$Ii,$T2
-+	  vaesenc	$rndkey,$inout3,$inout3
-+	mov		%r13,0x40+8(%rsp)
-+	  vaesenc	$rndkey,$inout4,$inout4
-+	mov		%r12,0x48+8(%rsp)
-+	 vpxor		$Hkey,$Z0,$Z0
-+	 vmovdqu	0x70-0x20($Xip),$Hkey	# $Hkey^6
-+	  vaesenc	$rndkey,$inout5,$inout5
-+
-+	  vmovups	0x60-0x80($key),$rndkey
-+	 vpxor		$Z1,$Z2,$Z2
-+	vpclmulqdq	\$0x10,$Hkey,$Xi,$Z1
-+	  vaesenc	$rndkey,$inout0,$inout0
-+	 vpxor		$T1,$Z2,$Z2
-+	vpclmulqdq	\$0x01,$Hkey,$Xi,$T1
-+	  vaesenc	$rndkey,$inout1,$inout1
-+	movbe		0x28($in0),%r13
-+	 vpxor		$T2,$Z3,$Z3
-+	vpclmulqdq	\$0x00,$Hkey,$Xi,$T2
-+	  vaesenc	$rndkey,$inout2,$inout2
-+	movbe		0x20($in0),%r12
-+	vpclmulqdq	\$0x11,$Hkey,$Xi,$Xi
-+	  vaesenc	$rndkey,$inout3,$inout3
-+	mov		%r13,0x50+8(%rsp)
-+	  vaesenc	$rndkey,$inout4,$inout4
-+	mov		%r12,0x58+8(%rsp)
-+	vpxor		$Z1,$Z2,$Z2
-+	  vaesenc	$rndkey,$inout5,$inout5
-+	vpxor		$T1,$Z2,$Z2
-+
-+	  vmovups	0x70-0x80($key),$rndkey
-+	vpslldq		\$8,$Z2,$Z1
-+	vpxor		$T2,$Z0,$Z0
-+	vmovdqu		0x10($const),$Hkey	# .Lpoly
-+
-+	  vaesenc	$rndkey,$inout0,$inout0
-+	vpxor		$Xi,$Z3,$Z3
-+	  vaesenc	$rndkey,$inout1,$inout1
-+	vpxor		$Z1,$Z0,$Z0
-+	movbe		0x18($in0),%r13
-+	  vaesenc	$rndkey,$inout2,$inout2
-+	movbe		0x10($in0),%r12
-+	vpalignr	\$8,$Z0,$Z0,$Ii		# 1st phase
-+	vpclmulqdq	\$0x10,$Hkey,$Z0,$Z0
-+	mov		%r13,0x60+8(%rsp)
-+	  vaesenc	$rndkey,$inout3,$inout3
-+	mov		%r12,0x68+8(%rsp)
-+	  vaesenc	$rndkey,$inout4,$inout4
-+	  vmovups	0x80-0x80($key),$T1	# borrow $T1 for $rndkey
-+	  vaesenc	$rndkey,$inout5,$inout5
-+
-+	  vaesenc	$T1,$inout0,$inout0
-+	  vmovups	0x90-0x80($key),$rndkey
-+	  vaesenc	$T1,$inout1,$inout1
-+	vpsrldq		\$8,$Z2,$Z2
-+	  vaesenc	$T1,$inout2,$inout2
-+	vpxor		$Z2,$Z3,$Z3
-+	  vaesenc	$T1,$inout3,$inout3
-+	vpxor		$Ii,$Z0,$Z0
-+	movbe		0x08($in0),%r13
-+	  vaesenc	$T1,$inout4,$inout4
-+	movbe		0x00($in0),%r12
-+	  vaesenc	$T1,$inout5,$inout5
-+	  vmovups	0xa0-0x80($key),$T1
-+	  cmp		\$11,$rounds
-+	  jb		.Lenc_tail		# 128-bit key
-+
-+	  vaesenc	$rndkey,$inout0,$inout0
-+	  vaesenc	$rndkey,$inout1,$inout1
-+	  vaesenc	$rndkey,$inout2,$inout2
-+	  vaesenc	$rndkey,$inout3,$inout3
-+	  vaesenc	$rndkey,$inout4,$inout4
-+	  vaesenc	$rndkey,$inout5,$inout5
-+
-+	  vaesenc	$T1,$inout0,$inout0
-+	  vaesenc	$T1,$inout1,$inout1
-+	  vaesenc	$T1,$inout2,$inout2
-+	  vaesenc	$T1,$inout3,$inout3
-+	  vaesenc	$T1,$inout4,$inout4
-+	  vmovups	0xb0-0x80($key),$rndkey
-+	  vaesenc	$T1,$inout5,$inout5
-+	  vmovups	0xc0-0x80($key),$T1
-+	  je		.Lenc_tail		# 192-bit key
-+
-+	  vaesenc	$rndkey,$inout0,$inout0
-+	  vaesenc	$rndkey,$inout1,$inout1
-+	  vaesenc	$rndkey,$inout2,$inout2
-+	  vaesenc	$rndkey,$inout3,$inout3
-+	  vaesenc	$rndkey,$inout4,$inout4
-+	  vaesenc	$rndkey,$inout5,$inout5
-+
-+	  vaesenc	$T1,$inout0,$inout0
-+	  vaesenc	$T1,$inout1,$inout1
-+	  vaesenc	$T1,$inout2,$inout2
-+	  vaesenc	$T1,$inout3,$inout3
-+	  vaesenc	$T1,$inout4,$inout4
-+	  vmovups	0xd0-0x80($key),$rndkey
-+	  vaesenc	$T1,$inout5,$inout5
-+	  vmovups	0xe0-0x80($key),$T1
-+	  jmp		.Lenc_tail		# 256-bit key
-+
-+.align	32
-+.Lhandle_ctr32:
-+	vmovdqu		($const),$Ii		# borrow $Ii for .Lbswap_mask
-+	  vpshufb	$Ii,$T1,$Z2		# byte-swap counter
-+	  vmovdqu	0x30($const),$Z1	# borrow $Z1, .Ltwo_lsb
-+	  vpaddd	0x40($const),$Z2,$inout1	# .Lone_lsb
-+	  vpaddd	$Z1,$Z2,$inout2
-+	vmovdqu		0x00-0x20($Xip),$Hkey	# $Hkey^1
-+	  vpaddd	$Z1,$inout1,$inout3
-+	  vpshufb	$Ii,$inout1,$inout1
-+	  vpaddd	$Z1,$inout2,$inout4
-+	  vpshufb	$Ii,$inout2,$inout2
-+	  vpxor		$rndkey,$inout1,$inout1
-+	  vpaddd	$Z1,$inout3,$inout5
-+	  vpshufb	$Ii,$inout3,$inout3
-+	  vpxor		$rndkey,$inout2,$inout2
-+	  vpaddd	$Z1,$inout4,$T1		# byte-swapped next counter value
-+	  vpshufb	$Ii,$inout4,$inout4
-+	  vpshufb	$Ii,$inout5,$inout5
-+	  vpshufb	$Ii,$T1,$T1		# next counter value
-+	jmp		.Lresume_ctr32
-+
-+.align	32
-+.Lenc_tail:
-+	  vaesenc	$rndkey,$inout0,$inout0
-+	vmovdqu		$Z3,16+8(%rsp)		# postpone vpxor $Z3,$Xi,$Xi
-+	vpalignr	\$8,$Z0,$Z0,$Xi		# 2nd phase
-+	  vaesenc	$rndkey,$inout1,$inout1
-+	vpclmulqdq	\$0x10,$Hkey,$Z0,$Z0
-+	  vpxor		0x00($inp),$T1,$T2
-+	  vaesenc	$rndkey,$inout2,$inout2
-+	  vpxor		0x10($inp),$T1,$Ii
-+	  vaesenc	$rndkey,$inout3,$inout3
-+	  vpxor		0x20($inp),$T1,$Z1
-+	  vaesenc	$rndkey,$inout4,$inout4
-+	  vpxor		0x30($inp),$T1,$Z2
-+	  vaesenc	$rndkey,$inout5,$inout5
-+	  vpxor		0x40($inp),$T1,$Z3
-+	  vpxor		0x50($inp),$T1,$Hkey
-+	  vmovdqu	($ivp),$T1		# load next counter value
-+
-+	  vaesenclast	$T2,$inout0,$inout0
-+	  vmovdqu	0x20($const),$T2	# borrow $T2, .Lone_msb
-+	  vaesenclast	$Ii,$inout1,$inout1
-+	 vpaddb		$T2,$T1,$Ii
-+	mov		%r13,0x70+8(%rsp)
-+	lea		0x60($inp),$inp
-+	  vaesenclast	$Z1,$inout2,$inout2
-+	 vpaddb		$T2,$Ii,$Z1
-+	mov		%r12,0x78+8(%rsp)
-+	lea		0x60($out),$out
-+	  vmovdqu	0x00-0x80($key),$rndkey
-+	  vaesenclast	$Z2,$inout3,$inout3
-+	 vpaddb		$T2,$Z1,$Z2
-+	  vaesenclast	$Z3, $inout4,$inout4
-+	 vpaddb		$T2,$Z2,$Z3
-+	  vaesenclast	$Hkey,$inout5,$inout5
-+	 vpaddb		$T2,$Z3,$Hkey
-+
-+	add		\$0x60,$ret
-+	sub		\$0x6,$len
-+	jc		.L6x_done
-+
-+	  vmovups	$inout0,-0x60($out)	# save output
-+	 vpxor		$rndkey,$T1,$inout0
-+	  vmovups	$inout1,-0x50($out)
-+	 vmovdqa	$Ii,$inout1		# 0 latency
-+	  vmovups	$inout2,-0x40($out)
-+	 vmovdqa	$Z1,$inout2		# 0 latency
-+	  vmovups	$inout3,-0x30($out)
-+	 vmovdqa	$Z2,$inout3		# 0 latency
-+	  vmovups	$inout4,-0x20($out)
-+	 vmovdqa	$Z3,$inout4		# 0 latency
-+	  vmovups	$inout5,-0x10($out)
-+	 vmovdqa	$Hkey,$inout5		# 0 latency
-+	vmovdqu		0x20+8(%rsp),$Z3	# I[5]
-+	jmp		.Loop6x
-+
-+.L6x_done:
-+	vpxor		16+8(%rsp),$Xi,$Xi	# modulo-scheduled
-+	vpxor		$Z0,$Xi,$Xi		# modulo-scheduled
-+
-+	ret
-+.size	_aesni_ctr32_ghash_6x,.-_aesni_ctr32_ghash_6x
-+___
-+######################################################################
-+#
-+# size_t aesni_gcm_[en|de]crypt(const void *inp, void *out, size_t len,
-+#		const AES_KEY *key, unsigned char iv[16],
-+#		struct { u128 Xi,H,Htbl[9]; } *Xip);
-+$code.=<<___;
-+.globl	aesni_gcm_decrypt
-+.type	aesni_gcm_decrypt,\@function,6
-+.align	32
-+aesni_gcm_decrypt:
-+	xor	$ret,$ret
-+
-+	# We call |_aesni_ctr32_ghash_6x|, which requires at least 96 (0x60)
-+	# bytes of input.
-+	cmp	\$0x60,$len			# minimal accepted length
-+	jb	.Lgcm_dec_abort
-+
-+	lea	(%rsp),%rax			# save stack pointer
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,-0xd8(%rax)
-+	movaps	%xmm7,-0xc8(%rax)
-+	movaps	%xmm8,-0xb8(%rax)
-+	movaps	%xmm9,-0xa8(%rax)
-+	movaps	%xmm10,-0x98(%rax)
-+	movaps	%xmm11,-0x88(%rax)
-+	movaps	%xmm12,-0x78(%rax)
-+	movaps	%xmm13,-0x68(%rax)
-+	movaps	%xmm14,-0x58(%rax)
-+	movaps	%xmm15,-0x48(%rax)
-+.Lgcm_dec_body:
-+___
-+$code.=<<___;
-+	vzeroupper
-+
-+	vmovdqu		($ivp),$T1		# input counter value
-+	add		\$-128,%rsp
-+	mov		12($ivp),$counter
-+	lea		.Lbswap_mask(%rip),$const
-+	lea		-0x80($key),$in0	# borrow $in0
-+	mov		\$0xf80,$end0		# borrow $end0
-+	vmovdqu		($Xip),$Xi		# load Xi
-+	and		\$-128,%rsp		# ensure stack alignment
-+	vmovdqu		($const),$Ii		# borrow $Ii for .Lbswap_mask
-+	lea		0x80($key),$key		# size optimization
-+	lea		0x20+0x20($Xip),$Xip	# size optimization
-+	mov		0xf0-0x80($key),$rounds
-+	vpshufb		$Ii,$Xi,$Xi
-+
-+	and		$end0,$in0
-+	and		%rsp,$end0
-+	sub		$in0,$end0
-+	jc		.Ldec_no_key_aliasing
-+	cmp		\$768,$end0
-+	jnc		.Ldec_no_key_aliasing
-+	sub		$end0,%rsp		# avoid aliasing with key
-+.Ldec_no_key_aliasing:
-+
-+	vmovdqu		0x50($inp),$Z3		# I[5]
-+	lea		($inp),$in0
-+	vmovdqu		0x40($inp),$Z0
-+
-+	# |_aesni_ctr32_ghash_6x| requires |$end0| to point to 2*96 (0xc0)
-+	# bytes before the end of the input. Note, in particular, that this is
-+	# correct even if |$len| is not an even multiple of 96 or 16. XXX: This
-+	# seems to require that |$inp| + |$len| >= 2*96 (0xc0); i.e. |$inp| must
-+	# not be near the very beginning of the address space when |$len| < 2*96
-+	# (0xc0).
-+	lea		-0xc0($inp,$len),$end0
-+
-+	vmovdqu		0x30($inp),$Z1
-+	shr		\$4,$len
-+	xor		$ret,$ret
-+	vmovdqu		0x20($inp),$Z2
-+	 vpshufb	$Ii,$Z3,$Z3		# passed to _aesni_ctr32_ghash_6x
-+	vmovdqu		0x10($inp),$T2
-+	 vpshufb	$Ii,$Z0,$Z0
-+	vmovdqu		($inp),$Hkey
-+	 vpshufb	$Ii,$Z1,$Z1
-+	vmovdqu		$Z0,0x30(%rsp)
-+	 vpshufb	$Ii,$Z2,$Z2
-+	vmovdqu		$Z1,0x40(%rsp)
-+	 vpshufb	$Ii,$T2,$T2
-+	vmovdqu		$Z2,0x50(%rsp)
-+	 vpshufb	$Ii,$Hkey,$Hkey
-+	vmovdqu		$T2,0x60(%rsp)
-+	vmovdqu		$Hkey,0x70(%rsp)
-+
-+	call		_aesni_ctr32_ghash_6x
-+
-+	vmovups		$inout0,-0x60($out)	# save output
-+	vmovups		$inout1,-0x50($out)
-+	vmovups		$inout2,-0x40($out)
-+	vmovups		$inout3,-0x30($out)
-+	vmovups		$inout4,-0x20($out)
-+	vmovups		$inout5,-0x10($out)
-+
-+	vpshufb		($const),$Xi,$Xi	# .Lbswap_mask
-+	vmovdqu		$Xi,-0x40($Xip)		# output Xi
-+
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xd8(%rax),%xmm6
-+	movaps	-0xc8(%rax),%xmm7
-+	movaps	-0xb8(%rax),%xmm8
-+	movaps	-0xa8(%rax),%xmm9
-+	movaps	-0x98(%rax),%xmm10
-+	movaps	-0x88(%rax),%xmm11
-+	movaps	-0x78(%rax),%xmm12
-+	movaps	-0x68(%rax),%xmm13
-+	movaps	-0x58(%rax),%xmm14
-+	movaps	-0x48(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp		# restore %rsp
-+.Lgcm_dec_abort:
-+	mov	$ret,%rax		# return value
-+	ret
-+.size	aesni_gcm_decrypt,.-aesni_gcm_decrypt
-+___
-+
-+$code.=<<___;
-+.type	_aesni_ctr32_6x,\@abi-omnipotent
-+.align	32
-+_aesni_ctr32_6x:
-+	vmovdqu		0x00-0x80($key),$Z0	# borrow $Z0 for $rndkey
-+	vmovdqu		0x20($const),$T2	# borrow $T2, .Lone_msb
-+	lea		-1($rounds),%r13
-+	vmovups		0x10-0x80($key),$rndkey
-+	lea		0x20-0x80($key),%r12
-+	vpxor		$Z0,$T1,$inout0
-+	add		\$`6<<24`,$counter
-+	jc		.Lhandle_ctr32_2
-+	vpaddb		$T2,$T1,$inout1
-+	vpaddb		$T2,$inout1,$inout2
-+	vpxor		$Z0,$inout1,$inout1
-+	vpaddb		$T2,$inout2,$inout3
-+	vpxor		$Z0,$inout2,$inout2
-+	vpaddb		$T2,$inout3,$inout4
-+	vpxor		$Z0,$inout3,$inout3
-+	vpaddb		$T2,$inout4,$inout5
-+	vpxor		$Z0,$inout4,$inout4
-+	vpaddb		$T2,$inout5,$T1
-+	vpxor		$Z0,$inout5,$inout5
-+	jmp		.Loop_ctr32
-+
-+.align	16
-+.Loop_ctr32:
-+	vaesenc		$rndkey,$inout0,$inout0
-+	vaesenc		$rndkey,$inout1,$inout1
-+	vaesenc		$rndkey,$inout2,$inout2
-+	vaesenc		$rndkey,$inout3,$inout3
-+	vaesenc		$rndkey,$inout4,$inout4
-+	vaesenc		$rndkey,$inout5,$inout5
-+	vmovups		(%r12),$rndkey
-+	lea		0x10(%r12),%r12
-+	dec		%r13d
-+	jnz		.Loop_ctr32
-+
-+	vmovdqu		(%r12),$Hkey		# last round key
-+	vaesenc		$rndkey,$inout0,$inout0
-+	vpxor		0x00($inp),$Hkey,$Z0
-+	vaesenc		$rndkey,$inout1,$inout1
-+	vpxor		0x10($inp),$Hkey,$Z1
-+	vaesenc		$rndkey,$inout2,$inout2
-+	vpxor		0x20($inp),$Hkey,$Z2
-+	vaesenc		$rndkey,$inout3,$inout3
-+	vpxor		0x30($inp),$Hkey,$Xi
-+	vaesenc		$rndkey,$inout4,$inout4
-+	vpxor		0x40($inp),$Hkey,$T2
-+	vaesenc		$rndkey,$inout5,$inout5
-+	vpxor		0x50($inp),$Hkey,$Hkey
-+	lea		0x60($inp),$inp
-+
-+	vaesenclast	$Z0,$inout0,$inout0
-+	vaesenclast	$Z1,$inout1,$inout1
-+	vaesenclast	$Z2,$inout2,$inout2
-+	vaesenclast	$Xi,$inout3,$inout3
-+	vaesenclast	$T2,$inout4,$inout4
-+	vaesenclast	$Hkey,$inout5,$inout5
-+	vmovups		$inout0,0x00($out)
-+	vmovups		$inout1,0x10($out)
-+	vmovups		$inout2,0x20($out)
-+	vmovups		$inout3,0x30($out)
-+	vmovups		$inout4,0x40($out)
-+	vmovups		$inout5,0x50($out)
-+	lea		0x60($out),$out
-+
-+	ret
-+.align	32
-+.Lhandle_ctr32_2:
-+	vpshufb		$Ii,$T1,$Z2		# byte-swap counter
-+	vmovdqu		0x30($const),$Z1	# borrow $Z1, .Ltwo_lsb
-+	vpaddd		0x40($const),$Z2,$inout1	# .Lone_lsb
-+	vpaddd		$Z1,$Z2,$inout2
-+	vpaddd		$Z1,$inout1,$inout3
-+	vpshufb		$Ii,$inout1,$inout1
-+	vpaddd		$Z1,$inout2,$inout4
-+	vpshufb		$Ii,$inout2,$inout2
-+	vpxor		$Z0,$inout1,$inout1
-+	vpaddd		$Z1,$inout3,$inout5
-+	vpshufb		$Ii,$inout3,$inout3
-+	vpxor		$Z0,$inout2,$inout2
-+	vpaddd		$Z1,$inout4,$T1		# byte-swapped next counter value
-+	vpshufb		$Ii,$inout4,$inout4
-+	vpxor		$Z0,$inout3,$inout3
-+	vpshufb		$Ii,$inout5,$inout5
-+	vpxor		$Z0,$inout4,$inout4
-+	vpshufb		$Ii,$T1,$T1		# next counter value
-+	vpxor		$Z0,$inout5,$inout5
-+	jmp	.Loop_ctr32
-+.size	_aesni_ctr32_6x,.-_aesni_ctr32_6x
-+
-+.globl	aesni_gcm_encrypt
-+.type	aesni_gcm_encrypt,\@function,6
-+.align	32
-+aesni_gcm_encrypt:
-+	xor	$ret,$ret
-+
-+	# We call |_aesni_ctr32_6x| twice, each call consuming 96 bytes of
-+	# input. Then we call |_aesni_ctr32_ghash_6x|, which requires at
-+	# least 96 more bytes of input.
-+	cmp	\$0x60*3,$len			# minimal accepted length
-+	jb	.Lgcm_enc_abort
-+
-+	lea	(%rsp),%rax			# save stack pointer
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,-0xd8(%rax)
-+	movaps	%xmm7,-0xc8(%rax)
-+	movaps	%xmm8,-0xb8(%rax)
-+	movaps	%xmm9,-0xa8(%rax)
-+	movaps	%xmm10,-0x98(%rax)
-+	movaps	%xmm11,-0x88(%rax)
-+	movaps	%xmm12,-0x78(%rax)
-+	movaps	%xmm13,-0x68(%rax)
-+	movaps	%xmm14,-0x58(%rax)
-+	movaps	%xmm15,-0x48(%rax)
-+.Lgcm_enc_body:
-+___
-+$code.=<<___;
-+	vzeroupper
-+
-+	vmovdqu		($ivp),$T1		# input counter value
-+	add		\$-128,%rsp
-+	mov		12($ivp),$counter
-+	lea		.Lbswap_mask(%rip),$const
-+	lea		-0x80($key),$in0	# borrow $in0
-+	mov		\$0xf80,$end0		# borrow $end0
-+	lea		0x80($key),$key		# size optimization
-+	vmovdqu		($const),$Ii		# borrow $Ii for .Lbswap_mask
-+	and		\$-128,%rsp		# ensure stack alignment
-+	mov		0xf0-0x80($key),$rounds
-+
-+	and		$end0,$in0
-+	and		%rsp,$end0
-+	sub		$in0,$end0
-+	jc		.Lenc_no_key_aliasing
-+	cmp		\$768,$end0
-+	jnc		.Lenc_no_key_aliasing
-+	sub		$end0,%rsp		# avoid aliasing with key
-+.Lenc_no_key_aliasing:
-+
-+	lea		($out),$in0
-+
-+	# |_aesni_ctr32_ghash_6x| requires |$end0| to point to 2*96 (0xc0)
-+	# bytes before the end of the input. Note, in particular, that this is
-+	# correct even if |$len| is not an even multiple of 96 or 16. Unlike in
-+	# the decryption case, there's no caveat that |$out| must not be near
-+	# the very beginning of the address space, because we know that
-+	# |$len| >= 3*96 from the check above, and so we know
-+	# |$out| + |$len| >= 2*96 (0xc0).
-+	lea		-0xc0($out,$len),$end0
-+
-+	shr		\$4,$len
-+
-+	call		_aesni_ctr32_6x
-+	vpshufb		$Ii,$inout0,$Xi		# save bswapped output on stack
-+	vpshufb		$Ii,$inout1,$T2
-+	vmovdqu		$Xi,0x70(%rsp)
-+	vpshufb		$Ii,$inout2,$Z0
-+	vmovdqu		$T2,0x60(%rsp)
-+	vpshufb		$Ii,$inout3,$Z1
-+	vmovdqu		$Z0,0x50(%rsp)
-+	vpshufb		$Ii,$inout4,$Z2
-+	vmovdqu		$Z1,0x40(%rsp)
-+	vpshufb		$Ii,$inout5,$Z3		# passed to _aesni_ctr32_ghash_6x
-+	vmovdqu		$Z2,0x30(%rsp)
-+
-+	call		_aesni_ctr32_6x
-+
-+	vmovdqu		($Xip),$Xi		# load Xi
-+	lea		0x20+0x20($Xip),$Xip	# size optimization
-+	sub		\$12,$len
-+	mov		\$0x60*2,$ret
-+	vpshufb		$Ii,$Xi,$Xi
-+
-+	call		_aesni_ctr32_ghash_6x
-+	vmovdqu		0x20(%rsp),$Z3		# I[5]
-+	 vmovdqu	($const),$Ii		# borrow $Ii for .Lbswap_mask
-+	vmovdqu		0x00-0x20($Xip),$Hkey	# $Hkey^1
-+	vpunpckhqdq	$Z3,$Z3,$T1
-+	vmovdqu		0x20-0x20($Xip),$rndkey	# borrow $rndkey for $HK
-+	 vmovups	$inout0,-0x60($out)	# save output
-+	 vpshufb	$Ii,$inout0,$inout0	# but keep bswapped copy
-+	vpxor		$Z3,$T1,$T1
-+	 vmovups	$inout1,-0x50($out)
-+	 vpshufb	$Ii,$inout1,$inout1
-+	 vmovups	$inout2,-0x40($out)
-+	 vpshufb	$Ii,$inout2,$inout2
-+	 vmovups	$inout3,-0x30($out)
-+	 vpshufb	$Ii,$inout3,$inout3
-+	 vmovups	$inout4,-0x20($out)
-+	 vpshufb	$Ii,$inout4,$inout4
-+	 vmovups	$inout5,-0x10($out)
-+	 vpshufb	$Ii,$inout5,$inout5
-+	 vmovdqu	$inout0,0x10(%rsp)	# free $inout0
-+___
-+{ my ($HK,$T3)=($rndkey,$inout0);
-+
-+$code.=<<___;
-+	 vmovdqu	0x30(%rsp),$Z2		# I[4]
-+	 vmovdqu	0x10-0x20($Xip),$Ii	# borrow $Ii for $Hkey^2
-+	 vpunpckhqdq	$Z2,$Z2,$T2
-+	vpclmulqdq	\$0x00,$Hkey,$Z3,$Z1
-+	 vpxor		$Z2,$T2,$T2
-+	vpclmulqdq	\$0x11,$Hkey,$Z3,$Z3
-+	vpclmulqdq	\$0x00,$HK,$T1,$T1
-+
-+	 vmovdqu	0x40(%rsp),$T3		# I[3]
-+	vpclmulqdq	\$0x00,$Ii,$Z2,$Z0
-+	 vmovdqu	0x30-0x20($Xip),$Hkey	# $Hkey^3
-+	vpxor		$Z1,$Z0,$Z0
-+	 vpunpckhqdq	$T3,$T3,$Z1
-+	vpclmulqdq	\$0x11,$Ii,$Z2,$Z2
-+	 vpxor		$T3,$Z1,$Z1
-+	vpxor		$Z3,$Z2,$Z2
-+	vpclmulqdq	\$0x10,$HK,$T2,$T2
-+	 vmovdqu	0x50-0x20($Xip),$HK
-+	vpxor		$T1,$T2,$T2
-+
-+	 vmovdqu	0x50(%rsp),$T1		# I[2]
-+	vpclmulqdq	\$0x00,$Hkey,$T3,$Z3
-+	 vmovdqu	0x40-0x20($Xip),$Ii	# borrow $Ii for $Hkey^4
-+	vpxor		$Z0,$Z3,$Z3
-+	 vpunpckhqdq	$T1,$T1,$Z0
-+	vpclmulqdq	\$0x11,$Hkey,$T3,$T3
-+	 vpxor		$T1,$Z0,$Z0
-+	vpxor		$Z2,$T3,$T3
-+	vpclmulqdq	\$0x00,$HK,$Z1,$Z1
-+	vpxor		$T2,$Z1,$Z1
-+
-+	 vmovdqu	0x60(%rsp),$T2		# I[1]
-+	vpclmulqdq	\$0x00,$Ii,$T1,$Z2
-+	 vmovdqu	0x60-0x20($Xip),$Hkey	# $Hkey^5
-+	vpxor		$Z3,$Z2,$Z2
-+	 vpunpckhqdq	$T2,$T2,$Z3
-+	vpclmulqdq	\$0x11,$Ii,$T1,$T1
-+	 vpxor		$T2,$Z3,$Z3
-+	vpxor		$T3,$T1,$T1
-+	vpclmulqdq	\$0x10,$HK,$Z0,$Z0
-+	 vmovdqu	0x80-0x20($Xip),$HK
-+	vpxor		$Z1,$Z0,$Z0
-+
-+	 vpxor		0x70(%rsp),$Xi,$Xi	# accumulate I[0]
-+	vpclmulqdq	\$0x00,$Hkey,$T2,$Z1
-+	 vmovdqu	0x70-0x20($Xip),$Ii	# borrow $Ii for $Hkey^6
-+	 vpunpckhqdq	$Xi,$Xi,$T3
-+	vpxor		$Z2,$Z1,$Z1
-+	vpclmulqdq	\$0x11,$Hkey,$T2,$T2
-+	 vpxor		$Xi,$T3,$T3
-+	vpxor		$T1,$T2,$T2
-+	vpclmulqdq	\$0x00,$HK,$Z3,$Z3
-+	vpxor		$Z0,$Z3,$Z0
-+
-+	vpclmulqdq	\$0x00,$Ii,$Xi,$Z2
-+	 vmovdqu	0x00-0x20($Xip),$Hkey	# $Hkey^1
-+	 vpunpckhqdq	$inout5,$inout5,$T1
-+	vpclmulqdq	\$0x11,$Ii,$Xi,$Xi
-+	 vpxor		$inout5,$T1,$T1
-+	vpxor		$Z1,$Z2,$Z1
-+	vpclmulqdq	\$0x10,$HK,$T3,$T3
-+	 vmovdqu	0x20-0x20($Xip),$HK
-+	vpxor		$T2,$Xi,$Z3
-+	vpxor		$Z0,$T3,$Z2
-+
-+	 vmovdqu	0x10-0x20($Xip),$Ii	# borrow $Ii for $Hkey^2
-+	  vpxor		$Z1,$Z3,$T3		# aggregated Karatsuba post-processing
-+	vpclmulqdq	\$0x00,$Hkey,$inout5,$Z0
-+	  vpxor		$T3,$Z2,$Z2
-+	 vpunpckhqdq	$inout4,$inout4,$T2
-+	vpclmulqdq	\$0x11,$Hkey,$inout5,$inout5
-+	 vpxor		$inout4,$T2,$T2
-+	  vpslldq	\$8,$Z2,$T3
-+	vpclmulqdq	\$0x00,$HK,$T1,$T1
-+	  vpxor		$T3,$Z1,$Xi
-+	  vpsrldq	\$8,$Z2,$Z2
-+	  vpxor		$Z2,$Z3,$Z3
-+
-+	vpclmulqdq	\$0x00,$Ii,$inout4,$Z1
-+	 vmovdqu	0x30-0x20($Xip),$Hkey	# $Hkey^3
-+	vpxor		$Z0,$Z1,$Z1
-+	 vpunpckhqdq	$inout3,$inout3,$T3
-+	vpclmulqdq	\$0x11,$Ii,$inout4,$inout4
-+	 vpxor		$inout3,$T3,$T3
-+	vpxor		$inout5,$inout4,$inout4
-+	  vpalignr	\$8,$Xi,$Xi,$inout5	# 1st phase
-+	vpclmulqdq	\$0x10,$HK,$T2,$T2
-+	 vmovdqu	0x50-0x20($Xip),$HK
-+	vpxor		$T1,$T2,$T2
-+
-+	vpclmulqdq	\$0x00,$Hkey,$inout3,$Z0
-+	 vmovdqu	0x40-0x20($Xip),$Ii	# borrow $Ii for $Hkey^4
-+	vpxor		$Z1,$Z0,$Z0
-+	 vpunpckhqdq	$inout2,$inout2,$T1
-+	vpclmulqdq	\$0x11,$Hkey,$inout3,$inout3
-+	 vpxor		$inout2,$T1,$T1
-+	vpxor		$inout4,$inout3,$inout3
-+	  vxorps	0x10(%rsp),$Z3,$Z3	# accumulate $inout0
-+	vpclmulqdq	\$0x00,$HK,$T3,$T3
-+	vpxor		$T2,$T3,$T3
-+
-+	  vpclmulqdq	\$0x10,0x10($const),$Xi,$Xi
-+	  vxorps	$inout5,$Xi,$Xi
-+
-+	vpclmulqdq	\$0x00,$Ii,$inout2,$Z1
-+	 vmovdqu	0x60-0x20($Xip),$Hkey	# $Hkey^5
-+	vpxor		$Z0,$Z1,$Z1
-+	 vpunpckhqdq	$inout1,$inout1,$T2
-+	vpclmulqdq	\$0x11,$Ii,$inout2,$inout2
-+	 vpxor		$inout1,$T2,$T2
-+	  vpalignr	\$8,$Xi,$Xi,$inout5	# 2nd phase
-+	vpxor		$inout3,$inout2,$inout2
-+	vpclmulqdq	\$0x10,$HK,$T1,$T1
-+	 vmovdqu	0x80-0x20($Xip),$HK
-+	vpxor		$T3,$T1,$T1
-+
-+	  vxorps	$Z3,$inout5,$inout5
-+	  vpclmulqdq	\$0x10,0x10($const),$Xi,$Xi
-+	  vxorps	$inout5,$Xi,$Xi
-+
-+	vpclmulqdq	\$0x00,$Hkey,$inout1,$Z0
-+	 vmovdqu	0x70-0x20($Xip),$Ii	# borrow $Ii for $Hkey^6
-+	vpxor		$Z1,$Z0,$Z0
-+	 vpunpckhqdq	$Xi,$Xi,$T3
-+	vpclmulqdq	\$0x11,$Hkey,$inout1,$inout1
-+	 vpxor		$Xi,$T3,$T3
-+	vpxor		$inout2,$inout1,$inout1
-+	vpclmulqdq	\$0x00,$HK,$T2,$T2
-+	vpxor		$T1,$T2,$T2
-+
-+	vpclmulqdq	\$0x00,$Ii,$Xi,$Z1
-+	vpclmulqdq	\$0x11,$Ii,$Xi,$Z3
-+	vpxor		$Z0,$Z1,$Z1
-+	vpclmulqdq	\$0x10,$HK,$T3,$Z2
-+	vpxor		$inout1,$Z3,$Z3
-+	vpxor		$T2,$Z2,$Z2
-+
-+	vpxor		$Z1,$Z3,$Z0		# aggregated Karatsuba post-processing
-+	vpxor		$Z0,$Z2,$Z2
-+	vpslldq		\$8,$Z2,$T1
-+	vmovdqu		0x10($const),$Hkey	# .Lpoly
-+	vpsrldq		\$8,$Z2,$Z2
-+	vpxor		$T1,$Z1,$Xi
-+	vpxor		$Z2,$Z3,$Z3
-+
-+	vpalignr	\$8,$Xi,$Xi,$T2		# 1st phase
-+	vpclmulqdq	\$0x10,$Hkey,$Xi,$Xi
-+	vpxor		$T2,$Xi,$Xi
-+
-+	vpalignr	\$8,$Xi,$Xi,$T2		# 2nd phase
-+	vpclmulqdq	\$0x10,$Hkey,$Xi,$Xi
-+	vpxor		$Z3,$T2,$T2
-+	vpxor		$T2,$Xi,$Xi
-+___
-+}
-+$code.=<<___;
-+	vpshufb		($const),$Xi,$Xi	# .Lbswap_mask
-+	vmovdqu		$Xi,-0x40($Xip)		# output Xi
-+
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xd8(%rax),%xmm6
-+	movaps	-0xc8(%rax),%xmm7
-+	movaps	-0xb8(%rax),%xmm8
-+	movaps	-0xa8(%rax),%xmm9
-+	movaps	-0x98(%rax),%xmm10
-+	movaps	-0x88(%rax),%xmm11
-+	movaps	-0x78(%rax),%xmm12
-+	movaps	-0x68(%rax),%xmm13
-+	movaps	-0x58(%rax),%xmm14
-+	movaps	-0x48(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp		# restore %rsp
-+.Lgcm_enc_abort:
-+	mov	$ret,%rax		# return value
-+	ret
-+.size	aesni_gcm_encrypt,.-aesni_gcm_encrypt
-+___
-+
-+$code.=<<___;
-+.align	64
-+.Lbswap_mask:
-+	.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
-+.Lpoly:
-+	.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2
-+.Lone_msb:
-+	.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
-+.Ltwo_lsb:
-+	.byte	2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-+.Lone_lsb:
-+	.byte	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-+.asciz	"AES-NI GCM module for x86_64, CRYPTOGAMS by "
-+.align	64
-+___
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___
-+.extern	__imp_RtlVirtualUnwind
-+.type	gcm_se_handler,\@abi-omnipotent
-+.align	16
-+gcm_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+
-+	mov	120($context),%rax	# pull context->Rax
-+
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	mov	%r15,240($context)
-+	mov	%r14,232($context)
-+	mov	%r13,224($context)
-+	mov	%r12,216($context)
-+	mov	%rbp,160($context)
-+	mov	%rbx,144($context)
-+
-+	lea	-0xd8(%rax),%rsi	# %xmm save area
-+	lea	512($context),%rdi	# & context.Xmm6
-+	mov	\$20,%ecx		# 10*sizeof(%xmm0)/sizeof(%rax)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+.Lcommon_seh_tail:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	gcm_se_handler,.-gcm_se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_aesni_gcm_decrypt
-+	.rva	.LSEH_end_aesni_gcm_decrypt
-+	.rva	.LSEH_gcm_dec_info
-+
-+	.rva	.LSEH_begin_aesni_gcm_encrypt
-+	.rva	.LSEH_end_aesni_gcm_encrypt
-+	.rva	.LSEH_gcm_enc_info
-+.section	.xdata
-+.align	8
-+.LSEH_gcm_dec_info:
-+	.byte	9,0,0,0
-+	.rva	gcm_se_handler
-+	.rva	.Lgcm_dec_body,.Lgcm_dec_abort
-+.LSEH_gcm_enc_info:
-+	.byte	9,0,0,0
-+	.rva	gcm_se_handler
-+	.rva	.Lgcm_enc_body,.Lgcm_enc_abort
-+___
-+}
-+}}} else {{{
-+$code=<<___;	# assembler is too old
-+.text
-+
-+.globl	aesni_gcm_encrypt
-+.type	aesni_gcm_encrypt,\@abi-omnipotent
-+aesni_gcm_encrypt:
-+	xor	%eax,%eax
-+	ret
-+.size	aesni_gcm_encrypt,.-aesni_gcm_encrypt
-+
-+.globl	aesni_gcm_decrypt
-+.type	aesni_gcm_decrypt,\@abi-omnipotent
-+aesni_gcm_decrypt:
-+	xor	%eax,%eax
-+	ret
-+.size	aesni_gcm_decrypt,.-aesni_gcm_decrypt
-+___
-+}}}
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-alpha.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-alpha.pl
-new file mode 100644
-index 0000000..ccf6b2b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-alpha.pl
-@@ -0,0 +1,467 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# March 2010
-+#
-+# The module implements "4-bit" GCM GHASH function and underlying
-+# single multiplication operation in GF(2^128). "4-bit" means that it
-+# uses 256 bytes per-key table [+128 bytes shared table]. Even though
-+# loops are aggressively modulo-scheduled in respect to references to
-+# Htbl and Z.hi updates for 8 cycles per byte, measured performance is
-+# ~12 cycles per processed byte on 21264 CPU. It seems to be a dynamic
-+# scheduling "glitch," because uprofile(1) indicates uniform sample
-+# distribution, as if all instruction bundles execute in 1.5 cycles.
-+# Meaning that it could have been even faster, yet 12 cycles is ~60%
-+# better than gcc-generated code and ~80% than code generated by vendor
-+# compiler.
-+
-+$cnt="v0";	# $0
-+$t0="t0";
-+$t1="t1";
-+$t2="t2";
-+$Thi0="t3";	# $4
-+$Tlo0="t4";
-+$Thi1="t5";
-+$Tlo1="t6";
-+$rem="t7";	# $8
-+#################
-+$Xi="a0";	# $16, input argument block
-+$Htbl="a1";
-+$inp="a2";
-+$len="a3";
-+$nlo="a4";	# $20
-+$nhi="a5";
-+$Zhi="t8";
-+$Zlo="t9";
-+$Xhi="t10";	# $24
-+$Xlo="t11";
-+$remp="t12";
-+$rem_4bit="AT";	# $28
-+
-+{ my $N;
-+  sub loop() {
-+
-+	$N++;
-+$code.=<<___;
-+.align	4
-+	extbl	$Xlo,7,$nlo
-+	and	$nlo,0xf0,$nhi
-+	sll	$nlo,4,$nlo
-+	and	$nlo,0xf0,$nlo
-+
-+	addq	$nlo,$Htbl,$nlo
-+	ldq	$Zlo,8($nlo)
-+	addq	$nhi,$Htbl,$nhi
-+	ldq	$Zhi,0($nlo)
-+
-+	and	$Zlo,0x0f,$remp
-+	sll	$Zhi,60,$t0
-+	lda	$cnt,6(zero)
-+	extbl	$Xlo,6,$nlo
-+
-+	ldq	$Tlo1,8($nhi)
-+	s8addq	$remp,$rem_4bit,$remp
-+	ldq	$Thi1,0($nhi)
-+	srl	$Zlo,4,$Zlo
-+
-+	ldq	$rem,0($remp)
-+	srl	$Zhi,4,$Zhi
-+	xor	$t0,$Zlo,$Zlo
-+	and	$nlo,0xf0,$nhi
-+
-+	xor	$Tlo1,$Zlo,$Zlo
-+	sll	$nlo,4,$nlo
-+	xor	$Thi1,$Zhi,$Zhi
-+	and	$nlo,0xf0,$nlo
-+
-+	addq	$nlo,$Htbl,$nlo
-+	ldq	$Tlo0,8($nlo)
-+	addq	$nhi,$Htbl,$nhi
-+	ldq	$Thi0,0($nlo)
-+
-+.Looplo$N:
-+	and	$Zlo,0x0f,$remp
-+	sll	$Zhi,60,$t0
-+	subq	$cnt,1,$cnt
-+	srl	$Zlo,4,$Zlo
-+
-+	ldq	$Tlo1,8($nhi)
-+	xor	$rem,$Zhi,$Zhi
-+	ldq	$Thi1,0($nhi)
-+	s8addq	$remp,$rem_4bit,$remp
-+
-+	ldq	$rem,0($remp)
-+	srl	$Zhi,4,$Zhi
-+	xor	$t0,$Zlo,$Zlo
-+	extbl	$Xlo,$cnt,$nlo
-+
-+	and	$nlo,0xf0,$nhi
-+	xor	$Thi0,$Zhi,$Zhi
-+	xor	$Tlo0,$Zlo,$Zlo
-+	sll	$nlo,4,$nlo
-+
-+
-+	and	$Zlo,0x0f,$remp
-+	sll	$Zhi,60,$t0
-+	and	$nlo,0xf0,$nlo
-+	srl	$Zlo,4,$Zlo
-+
-+	s8addq	$remp,$rem_4bit,$remp
-+	xor	$rem,$Zhi,$Zhi
-+	addq	$nlo,$Htbl,$nlo
-+	addq	$nhi,$Htbl,$nhi
-+
-+	ldq	$rem,0($remp)
-+	srl	$Zhi,4,$Zhi
-+	ldq	$Tlo0,8($nlo)
-+	xor	$t0,$Zlo,$Zlo
-+
-+	xor	$Tlo1,$Zlo,$Zlo
-+	xor	$Thi1,$Zhi,$Zhi
-+	ldq	$Thi0,0($nlo)
-+	bne	$cnt,.Looplo$N
-+
-+
-+	and	$Zlo,0x0f,$remp
-+	sll	$Zhi,60,$t0
-+	lda	$cnt,7(zero)
-+	srl	$Zlo,4,$Zlo
-+
-+	ldq	$Tlo1,8($nhi)
-+	xor	$rem,$Zhi,$Zhi
-+	ldq	$Thi1,0($nhi)
-+	s8addq	$remp,$rem_4bit,$remp
-+
-+	ldq	$rem,0($remp)
-+	srl	$Zhi,4,$Zhi
-+	xor	$t0,$Zlo,$Zlo
-+	extbl	$Xhi,$cnt,$nlo
-+
-+	and	$nlo,0xf0,$nhi
-+	xor	$Thi0,$Zhi,$Zhi
-+	xor	$Tlo0,$Zlo,$Zlo
-+	sll	$nlo,4,$nlo
-+
-+	and	$Zlo,0x0f,$remp
-+	sll	$Zhi,60,$t0
-+	and	$nlo,0xf0,$nlo
-+	srl	$Zlo,4,$Zlo
-+
-+	s8addq	$remp,$rem_4bit,$remp
-+	xor	$rem,$Zhi,$Zhi
-+	addq	$nlo,$Htbl,$nlo
-+	addq	$nhi,$Htbl,$nhi
-+
-+	ldq	$rem,0($remp)
-+	srl	$Zhi,4,$Zhi
-+	ldq	$Tlo0,8($nlo)
-+	xor	$t0,$Zlo,$Zlo
-+
-+	xor	$Tlo1,$Zlo,$Zlo
-+	xor	$Thi1,$Zhi,$Zhi
-+	ldq	$Thi0,0($nlo)
-+	unop
-+
-+
-+.Loophi$N:
-+	and	$Zlo,0x0f,$remp
-+	sll	$Zhi,60,$t0
-+	subq	$cnt,1,$cnt
-+	srl	$Zlo,4,$Zlo
-+
-+	ldq	$Tlo1,8($nhi)
-+	xor	$rem,$Zhi,$Zhi
-+	ldq	$Thi1,0($nhi)
-+	s8addq	$remp,$rem_4bit,$remp
-+
-+	ldq	$rem,0($remp)
-+	srl	$Zhi,4,$Zhi
-+	xor	$t0,$Zlo,$Zlo
-+	extbl	$Xhi,$cnt,$nlo
-+
-+	and	$nlo,0xf0,$nhi
-+	xor	$Thi0,$Zhi,$Zhi
-+	xor	$Tlo0,$Zlo,$Zlo
-+	sll	$nlo,4,$nlo
-+
-+
-+	and	$Zlo,0x0f,$remp
-+	sll	$Zhi,60,$t0
-+	and	$nlo,0xf0,$nlo
-+	srl	$Zlo,4,$Zlo
-+
-+	s8addq	$remp,$rem_4bit,$remp
-+	xor	$rem,$Zhi,$Zhi
-+	addq	$nlo,$Htbl,$nlo
-+	addq	$nhi,$Htbl,$nhi
-+
-+	ldq	$rem,0($remp)
-+	srl	$Zhi,4,$Zhi
-+	ldq	$Tlo0,8($nlo)
-+	xor	$t0,$Zlo,$Zlo
-+
-+	xor	$Tlo1,$Zlo,$Zlo
-+	xor	$Thi1,$Zhi,$Zhi
-+	ldq	$Thi0,0($nlo)
-+	bne	$cnt,.Loophi$N
-+
-+
-+	and	$Zlo,0x0f,$remp
-+	sll	$Zhi,60,$t0
-+	srl	$Zlo,4,$Zlo
-+
-+	ldq	$Tlo1,8($nhi)
-+	xor	$rem,$Zhi,$Zhi
-+	ldq	$Thi1,0($nhi)
-+	s8addq	$remp,$rem_4bit,$remp
-+
-+	ldq	$rem,0($remp)
-+	srl	$Zhi,4,$Zhi
-+	xor	$t0,$Zlo,$Zlo
-+
-+	xor	$Tlo0,$Zlo,$Zlo
-+	xor	$Thi0,$Zhi,$Zhi
-+
-+	and	$Zlo,0x0f,$remp
-+	sll	$Zhi,60,$t0
-+	srl	$Zlo,4,$Zlo
-+
-+	s8addq	$remp,$rem_4bit,$remp
-+	xor	$rem,$Zhi,$Zhi
-+
-+	ldq	$rem,0($remp)
-+	srl	$Zhi,4,$Zhi
-+	xor	$Tlo1,$Zlo,$Zlo
-+	xor	$Thi1,$Zhi,$Zhi
-+	xor	$t0,$Zlo,$Zlo
-+	xor	$rem,$Zhi,$Zhi
-+___
-+}}
-+
-+$code=<<___;
-+#ifdef __linux__
-+#include 
-+#else
-+#include 
-+#include 
-+#endif
-+
-+.text
-+
-+.set	noat
-+.set	noreorder
-+.globl	gcm_gmult_4bit
-+.align	4
-+.ent	gcm_gmult_4bit
-+gcm_gmult_4bit:
-+	.frame	sp,0,ra
-+	.prologue 0
-+
-+	ldq	$Xlo,8($Xi)
-+	ldq	$Xhi,0($Xi)
-+
-+	bsr	$t0,picmeup
-+	nop
-+___
-+
-+	&loop();
-+
-+$code.=<<___;
-+	srl	$Zlo,24,$t0	# byte swap
-+	srl	$Zlo,8,$t1
-+
-+	sll	$Zlo,8,$t2
-+	sll	$Zlo,24,$Zlo
-+	zapnot	$t0,0x11,$t0
-+	zapnot	$t1,0x22,$t1
-+
-+	zapnot	$Zlo,0x88,$Zlo
-+	or	$t0,$t1,$t0
-+	zapnot	$t2,0x44,$t2
-+
-+	or	$Zlo,$t0,$Zlo
-+	srl	$Zhi,24,$t0
-+	srl	$Zhi,8,$t1
-+
-+	or	$Zlo,$t2,$Zlo
-+	sll	$Zhi,8,$t2
-+	sll	$Zhi,24,$Zhi
-+
-+	srl	$Zlo,32,$Xlo
-+	sll	$Zlo,32,$Zlo
-+
-+	zapnot	$t0,0x11,$t0
-+	zapnot	$t1,0x22,$t1
-+	or	$Zlo,$Xlo,$Xlo
-+
-+	zapnot	$Zhi,0x88,$Zhi
-+	or	$t0,$t1,$t0
-+	zapnot	$t2,0x44,$t2
-+
-+	or	$Zhi,$t0,$Zhi
-+	or	$Zhi,$t2,$Zhi
-+
-+	srl	$Zhi,32,$Xhi
-+	sll	$Zhi,32,$Zhi
-+
-+	or	$Zhi,$Xhi,$Xhi
-+	stq	$Xlo,8($Xi)
-+	stq	$Xhi,0($Xi)
-+
-+	ret	(ra)
-+.end	gcm_gmult_4bit
-+___
-+
-+$inhi="s0";
-+$inlo="s1";
-+
-+$code.=<<___;
-+.globl	gcm_ghash_4bit
-+.align	4
-+.ent	gcm_ghash_4bit
-+gcm_ghash_4bit:
-+	lda	sp,-32(sp)
-+	stq	ra,0(sp)
-+	stq	s0,8(sp)
-+	stq	s1,16(sp)
-+	.mask	0x04000600,-32
-+	.frame	sp,32,ra
-+	.prologue 0
-+
-+	ldq_u	$inhi,0($inp)
-+	ldq_u	$Thi0,7($inp)
-+	ldq_u	$inlo,8($inp)
-+	ldq_u	$Tlo0,15($inp)
-+	ldq	$Xhi,0($Xi)
-+	ldq	$Xlo,8($Xi)
-+
-+	bsr	$t0,picmeup
-+	nop
-+
-+.Louter:
-+	extql	$inhi,$inp,$inhi
-+	extqh	$Thi0,$inp,$Thi0
-+	or	$inhi,$Thi0,$inhi
-+	lda	$inp,16($inp)
-+
-+	extql	$inlo,$inp,$inlo
-+	extqh	$Tlo0,$inp,$Tlo0
-+	or	$inlo,$Tlo0,$inlo
-+	subq	$len,16,$len
-+
-+	xor	$Xlo,$inlo,$Xlo
-+	xor	$Xhi,$inhi,$Xhi
-+___
-+
-+	&loop();
-+
-+$code.=<<___;
-+	srl	$Zlo,24,$t0	# byte swap
-+	srl	$Zlo,8,$t1
-+
-+	sll	$Zlo,8,$t2
-+	sll	$Zlo,24,$Zlo
-+	zapnot	$t0,0x11,$t0
-+	zapnot	$t1,0x22,$t1
-+
-+	zapnot	$Zlo,0x88,$Zlo
-+	or	$t0,$t1,$t0
-+	zapnot	$t2,0x44,$t2
-+
-+	or	$Zlo,$t0,$Zlo
-+	srl	$Zhi,24,$t0
-+	srl	$Zhi,8,$t1
-+
-+	or	$Zlo,$t2,$Zlo
-+	sll	$Zhi,8,$t2
-+	sll	$Zhi,24,$Zhi
-+
-+	srl	$Zlo,32,$Xlo
-+	sll	$Zlo,32,$Zlo
-+	beq	$len,.Ldone
-+
-+	zapnot	$t0,0x11,$t0
-+	zapnot	$t1,0x22,$t1
-+	or	$Zlo,$Xlo,$Xlo
-+	ldq_u	$inhi,0($inp)
-+
-+	zapnot	$Zhi,0x88,$Zhi
-+	or	$t0,$t1,$t0
-+	zapnot	$t2,0x44,$t2
-+	ldq_u	$Thi0,7($inp)
-+
-+	or	$Zhi,$t0,$Zhi
-+	or	$Zhi,$t2,$Zhi
-+	ldq_u	$inlo,8($inp)
-+	ldq_u	$Tlo0,15($inp)
-+
-+	srl	$Zhi,32,$Xhi
-+	sll	$Zhi,32,$Zhi
-+
-+	or	$Zhi,$Xhi,$Xhi
-+	br	zero,.Louter
-+
-+.Ldone:
-+	zapnot	$t0,0x11,$t0
-+	zapnot	$t1,0x22,$t1
-+	or	$Zlo,$Xlo,$Xlo
-+
-+	zapnot	$Zhi,0x88,$Zhi
-+	or	$t0,$t1,$t0
-+	zapnot	$t2,0x44,$t2
-+
-+	or	$Zhi,$t0,$Zhi
-+	or	$Zhi,$t2,$Zhi
-+
-+	srl	$Zhi,32,$Xhi
-+	sll	$Zhi,32,$Zhi
-+
-+	or	$Zhi,$Xhi,$Xhi
-+
-+	stq	$Xlo,8($Xi)
-+	stq	$Xhi,0($Xi)
-+
-+	.set	noreorder
-+	/*ldq	ra,0(sp)*/
-+	ldq	s0,8(sp)
-+	ldq	s1,16(sp)
-+	lda	sp,32(sp)
-+	ret	(ra)
-+.end	gcm_ghash_4bit
-+
-+.align	4
-+.ent	picmeup
-+picmeup:
-+	.frame	sp,0,$t0
-+	.prologue 0
-+	br	$rem_4bit,.Lpic
-+.Lpic:	lda	$rem_4bit,12($rem_4bit)
-+	ret	($t0)
-+.end	picmeup
-+	nop
-+rem_4bit:
-+	.long	0,0x0000<<16, 0,0x1C20<<16, 0,0x3840<<16, 0,0x2460<<16
-+	.long	0,0x7080<<16, 0,0x6CA0<<16, 0,0x48C0<<16, 0,0x54E0<<16
-+	.long	0,0xE100<<16, 0,0xFD20<<16, 0,0xD940<<16, 0,0xC560<<16
-+	.long	0,0x9180<<16, 0,0x8DA0<<16, 0,0xA9C0<<16, 0,0xB5E0<<16
-+.ascii	"GHASH for Alpha, CRYPTOGAMS by "
-+.align	4
-+
-+___
-+$output=pop and open STDOUT,">$output";
-+print $code;
-+close STDOUT;
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-armv4.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-armv4.pl
-new file mode 100644
-index 0000000..7d880c9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-armv4.pl
-@@ -0,0 +1,554 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# April 2010
-+#
-+# The module implements "4-bit" GCM GHASH function and underlying
-+# single multiplication operation in GF(2^128). "4-bit" means that it
-+# uses 256 bytes per-key table [+32 bytes shared table]. There is no
-+# experimental performance data available yet. The only approximation
-+# that can be made at this point is based on code size. Inner loop is
-+# 32 instructions long and on single-issue core should execute in <40
-+# cycles. Having verified that gcc 3.4 didn't unroll corresponding
-+# loop, this assembler loop body was found to be ~3x smaller than
-+# compiler-generated one...
-+#
-+# July 2010
-+#
-+# Rescheduling for dual-issue pipeline resulted in 8.5% improvement on
-+# Cortex A8 core and ~25 cycles per processed byte (which was observed
-+# to be ~3 times faster than gcc-generated code:-)
-+#
-+# February 2011
-+#
-+# Profiler-assisted and platform-specific optimization resulted in 7%
-+# improvement on Cortex A8 core and ~23.5 cycles per byte.
-+#
-+# March 2011
-+#
-+# Add NEON implementation featuring polynomial multiplication, i.e. no
-+# lookup tables involved. On Cortex A8 it was measured to process one
-+# byte in 15 cycles or 55% faster than integer-only code.
-+#
-+# April 2014
-+#
-+# Switch to multiplication algorithm suggested in paper referred
-+# below and combine it with reduction algorithm from x86 module.
-+# Performance improvement over previous version varies from 65% on
-+# Snapdragon S4 to 110% on Cortex A9. In absolute terms Cortex A8
-+# processes one byte in 8.45 cycles, A9 - in 10.2, A15 - in 7.63,
-+# Snapdragon S4 - in 9.33.
-+#
-+# Câmara, D.; Gouvêa, C. P. L.; López, J. & Dahab, R.: Fast Software
-+# Polynomial Multiplication on ARM Processors using the NEON Engine.
-+# 
-+# http://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf
-+
-+# ====================================================================
-+# Note about "528B" variant. In ARM case it makes lesser sense to
-+# implement it for following reasons:
-+#
-+# - performance improvement won't be anywhere near 50%, because 128-
-+#   bit shift operation is neatly fused with 128-bit xor here, and
-+#   "538B" variant would eliminate only 4-5 instructions out of 32
-+#   in the inner loop (meaning that estimated improvement is ~15%);
-+# - ARM-based systems are often embedded ones and extra memory
-+#   consumption might be unappreciated (for so little improvement);
-+#
-+# Byte order [in]dependence. =========================================
-+#
-+# Caller is expected to maintain specific *dword* order in Htable,
-+# namely with *least* significant dword of 128-bit value at *lower*
-+# address. This differs completely from C code and has everything to
-+# do with ldm instruction and order in which dwords are "consumed" by
-+# algorithm. *Byte* order within these dwords in turn is whatever
-+# *native* byte order on current platform. See gcm128.c for working
-+# example...
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+$Xi="r0";	# argument block
-+$Htbl="r1";
-+$inp="r2";
-+$len="r3";
-+
-+$Zll="r4";	# variables
-+$Zlh="r5";
-+$Zhl="r6";
-+$Zhh="r7";
-+$Tll="r8";
-+$Tlh="r9";
-+$Thl="r10";
-+$Thh="r11";
-+$nlo="r12";
-+################# r13 is stack pointer
-+$nhi="r14";
-+################# r15 is program counter
-+
-+$rem_4bit=$inp;	# used in gcm_gmult_4bit
-+$cnt=$len;
-+
-+sub Zsmash() {
-+  my $i=12;
-+  my @args=@_;
-+  for ($Zll,$Zlh,$Zhl,$Zhh) {
-+    $code.=<<___;
-+#if __ARM_ARCH__>=7 && defined(__ARMEL__)
-+	rev	$_,$_
-+	str	$_,[$Xi,#$i]
-+#elif defined(__ARMEB__)
-+	str	$_,[$Xi,#$i]
-+#else
-+	mov	$Tlh,$_,lsr#8
-+	strb	$_,[$Xi,#$i+3]
-+	mov	$Thl,$_,lsr#16
-+	strb	$Tlh,[$Xi,#$i+2]
-+	mov	$Thh,$_,lsr#24
-+	strb	$Thl,[$Xi,#$i+1]
-+	strb	$Thh,[$Xi,#$i]
-+#endif
-+___
-+    $code.="\t".shift(@args)."\n";
-+    $i-=4;
-+  }
-+}
-+
-+$code=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+#if defined(__thumb2__) || defined(__clang__)
-+.syntax	unified
-+#endif
-+#if defined(__thumb2__)
-+.thumb
-+#else
-+.code	32
-+#endif
-+
-+#ifdef  __clang__
-+#define ldrplb  ldrbpl
-+#define ldrneb  ldrbne
-+#endif
-+
-+.type	rem_4bit,%object
-+.align	5
-+rem_4bit:
-+.short	0x0000,0x1C20,0x3840,0x2460
-+.short	0x7080,0x6CA0,0x48C0,0x54E0
-+.short	0xE100,0xFD20,0xD940,0xC560
-+.short	0x9180,0x8DA0,0xA9C0,0xB5E0
-+.size	rem_4bit,.-rem_4bit
-+
-+.type	rem_4bit_get,%function
-+rem_4bit_get:
-+#if defined(__thumb2__)
-+	adr	$rem_4bit,rem_4bit
-+#else
-+	sub	$rem_4bit,pc,#8+32	@ &rem_4bit
-+#endif
-+	b	.Lrem_4bit_got
-+	nop
-+	nop
-+.size	rem_4bit_get,.-rem_4bit_get
-+
-+.global	gcm_ghash_4bit
-+.type	gcm_ghash_4bit,%function
-+.align	4
-+gcm_ghash_4bit:
-+#if defined(__thumb2__)
-+	adr	r12,rem_4bit
-+#else
-+	sub	r12,pc,#8+48		@ &rem_4bit
-+#endif
-+	add	$len,$inp,$len		@ $len to point at the end
-+	stmdb	sp!,{r3-r11,lr}		@ save $len/end too
-+
-+	ldmia	r12,{r4-r11}		@ copy rem_4bit ...
-+	stmdb	sp!,{r4-r11}		@ ... to stack
-+
-+	ldrb	$nlo,[$inp,#15]
-+	ldrb	$nhi,[$Xi,#15]
-+.Louter:
-+	eor	$nlo,$nlo,$nhi
-+	and	$nhi,$nlo,#0xf0
-+	and	$nlo,$nlo,#0x0f
-+	mov	$cnt,#14
-+
-+	add	$Zhh,$Htbl,$nlo,lsl#4
-+	ldmia	$Zhh,{$Zll-$Zhh}	@ load Htbl[nlo]
-+	add	$Thh,$Htbl,$nhi
-+	ldrb	$nlo,[$inp,#14]
-+
-+	and	$nhi,$Zll,#0xf		@ rem
-+	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nhi]
-+	add	$nhi,$nhi,$nhi
-+	eor	$Zll,$Tll,$Zll,lsr#4
-+	ldrh	$Tll,[sp,$nhi]		@ rem_4bit[rem]
-+	eor	$Zll,$Zll,$Zlh,lsl#28
-+	ldrb	$nhi,[$Xi,#14]
-+	eor	$Zlh,$Tlh,$Zlh,lsr#4
-+	eor	$Zlh,$Zlh,$Zhl,lsl#28
-+	eor	$Zhl,$Thl,$Zhl,lsr#4
-+	eor	$Zhl,$Zhl,$Zhh,lsl#28
-+	eor	$Zhh,$Thh,$Zhh,lsr#4
-+	eor	$nlo,$nlo,$nhi
-+	and	$nhi,$nlo,#0xf0
-+	and	$nlo,$nlo,#0x0f
-+	eor	$Zhh,$Zhh,$Tll,lsl#16
-+
-+.Linner:
-+	add	$Thh,$Htbl,$nlo,lsl#4
-+	and	$nlo,$Zll,#0xf		@ rem
-+	subs	$cnt,$cnt,#1
-+	add	$nlo,$nlo,$nlo
-+	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nlo]
-+	eor	$Zll,$Tll,$Zll,lsr#4
-+	eor	$Zll,$Zll,$Zlh,lsl#28
-+	eor	$Zlh,$Tlh,$Zlh,lsr#4
-+	eor	$Zlh,$Zlh,$Zhl,lsl#28
-+	ldrh	$Tll,[sp,$nlo]		@ rem_4bit[rem]
-+	eor	$Zhl,$Thl,$Zhl,lsr#4
-+#ifdef	__thumb2__
-+	it	pl
-+#endif
-+	ldrplb	$nlo,[$inp,$cnt]
-+	eor	$Zhl,$Zhl,$Zhh,lsl#28
-+	eor	$Zhh,$Thh,$Zhh,lsr#4
-+
-+	add	$Thh,$Htbl,$nhi
-+	and	$nhi,$Zll,#0xf		@ rem
-+	eor	$Zhh,$Zhh,$Tll,lsl#16	@ ^= rem_4bit[rem]
-+	add	$nhi,$nhi,$nhi
-+	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nhi]
-+	eor	$Zll,$Tll,$Zll,lsr#4
-+#ifdef	__thumb2__
-+	it	pl
-+#endif
-+	ldrplb	$Tll,[$Xi,$cnt]
-+	eor	$Zll,$Zll,$Zlh,lsl#28
-+	eor	$Zlh,$Tlh,$Zlh,lsr#4
-+	ldrh	$Tlh,[sp,$nhi]
-+	eor	$Zlh,$Zlh,$Zhl,lsl#28
-+	eor	$Zhl,$Thl,$Zhl,lsr#4
-+	eor	$Zhl,$Zhl,$Zhh,lsl#28
-+#ifdef	__thumb2__
-+	it	pl
-+#endif
-+	eorpl	$nlo,$nlo,$Tll
-+	eor	$Zhh,$Thh,$Zhh,lsr#4
-+#ifdef	__thumb2__
-+	itt	pl
-+#endif
-+	andpl	$nhi,$nlo,#0xf0
-+	andpl	$nlo,$nlo,#0x0f
-+	eor	$Zhh,$Zhh,$Tlh,lsl#16	@ ^= rem_4bit[rem]
-+	bpl	.Linner
-+
-+	ldr	$len,[sp,#32]		@ re-load $len/end
-+	add	$inp,$inp,#16
-+	mov	$nhi,$Zll
-+___
-+	&Zsmash("cmp\t$inp,$len","\n".
-+				 "#ifdef __thumb2__\n".
-+				 "	it	ne\n".
-+				 "#endif\n".
-+				 "	ldrneb	$nlo,[$inp,#15]");
-+$code.=<<___;
-+	bne	.Louter
-+
-+	add	sp,sp,#36
-+#if __ARM_ARCH__>=5
-+	ldmia	sp!,{r4-r11,pc}
-+#else
-+	ldmia	sp!,{r4-r11,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	gcm_ghash_4bit,.-gcm_ghash_4bit
-+
-+.global	gcm_gmult_4bit
-+.type	gcm_gmult_4bit,%function
-+gcm_gmult_4bit:
-+	stmdb	sp!,{r4-r11,lr}
-+	ldrb	$nlo,[$Xi,#15]
-+	b	rem_4bit_get
-+.Lrem_4bit_got:
-+	and	$nhi,$nlo,#0xf0
-+	and	$nlo,$nlo,#0x0f
-+	mov	$cnt,#14
-+
-+	add	$Zhh,$Htbl,$nlo,lsl#4
-+	ldmia	$Zhh,{$Zll-$Zhh}	@ load Htbl[nlo]
-+	ldrb	$nlo,[$Xi,#14]
-+
-+	add	$Thh,$Htbl,$nhi
-+	and	$nhi,$Zll,#0xf		@ rem
-+	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nhi]
-+	add	$nhi,$nhi,$nhi
-+	eor	$Zll,$Tll,$Zll,lsr#4
-+	ldrh	$Tll,[$rem_4bit,$nhi]	@ rem_4bit[rem]
-+	eor	$Zll,$Zll,$Zlh,lsl#28
-+	eor	$Zlh,$Tlh,$Zlh,lsr#4
-+	eor	$Zlh,$Zlh,$Zhl,lsl#28
-+	eor	$Zhl,$Thl,$Zhl,lsr#4
-+	eor	$Zhl,$Zhl,$Zhh,lsl#28
-+	eor	$Zhh,$Thh,$Zhh,lsr#4
-+	and	$nhi,$nlo,#0xf0
-+	eor	$Zhh,$Zhh,$Tll,lsl#16
-+	and	$nlo,$nlo,#0x0f
-+
-+.Loop:
-+	add	$Thh,$Htbl,$nlo,lsl#4
-+	and	$nlo,$Zll,#0xf		@ rem
-+	subs	$cnt,$cnt,#1
-+	add	$nlo,$nlo,$nlo
-+	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nlo]
-+	eor	$Zll,$Tll,$Zll,lsr#4
-+	eor	$Zll,$Zll,$Zlh,lsl#28
-+	eor	$Zlh,$Tlh,$Zlh,lsr#4
-+	eor	$Zlh,$Zlh,$Zhl,lsl#28
-+	ldrh	$Tll,[$rem_4bit,$nlo]	@ rem_4bit[rem]
-+	eor	$Zhl,$Thl,$Zhl,lsr#4
-+#ifdef	__thumb2__
-+	it	pl
-+#endif
-+	ldrplb	$nlo,[$Xi,$cnt]
-+	eor	$Zhl,$Zhl,$Zhh,lsl#28
-+	eor	$Zhh,$Thh,$Zhh,lsr#4
-+
-+	add	$Thh,$Htbl,$nhi
-+	and	$nhi,$Zll,#0xf		@ rem
-+	eor	$Zhh,$Zhh,$Tll,lsl#16	@ ^= rem_4bit[rem]
-+	add	$nhi,$nhi,$nhi
-+	ldmia	$Thh,{$Tll-$Thh}	@ load Htbl[nhi]
-+	eor	$Zll,$Tll,$Zll,lsr#4
-+	eor	$Zll,$Zll,$Zlh,lsl#28
-+	eor	$Zlh,$Tlh,$Zlh,lsr#4
-+	ldrh	$Tll,[$rem_4bit,$nhi]	@ rem_4bit[rem]
-+	eor	$Zlh,$Zlh,$Zhl,lsl#28
-+	eor	$Zhl,$Thl,$Zhl,lsr#4
-+	eor	$Zhl,$Zhl,$Zhh,lsl#28
-+	eor	$Zhh,$Thh,$Zhh,lsr#4
-+#ifdef	__thumb2__
-+	itt	pl
-+#endif
-+	andpl	$nhi,$nlo,#0xf0
-+	andpl	$nlo,$nlo,#0x0f
-+	eor	$Zhh,$Zhh,$Tll,lsl#16	@ ^= rem_4bit[rem]
-+	bpl	.Loop
-+___
-+	&Zsmash();
-+$code.=<<___;
-+#if __ARM_ARCH__>=5
-+	ldmia	sp!,{r4-r11,pc}
-+#else
-+	ldmia	sp!,{r4-r11,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	gcm_gmult_4bit,.-gcm_gmult_4bit
-+___
-+{
-+my ($Xl,$Xm,$Xh,$IN)=map("q$_",(0..3));
-+my ($t0,$t1,$t2,$t3)=map("q$_",(8..12));
-+my ($Hlo,$Hhi,$Hhl,$k48,$k32,$k16)=map("d$_",(26..31));
-+
-+sub clmul64x64 {
-+my ($r,$a,$b)=@_;
-+$code.=<<___;
-+	vext.8		$t0#lo, $a, $a, #1	@ A1
-+	vmull.p8	$t0, $t0#lo, $b		@ F = A1*B
-+	vext.8		$r#lo, $b, $b, #1	@ B1
-+	vmull.p8	$r, $a, $r#lo		@ E = A*B1
-+	vext.8		$t1#lo, $a, $a, #2	@ A2
-+	vmull.p8	$t1, $t1#lo, $b		@ H = A2*B
-+	vext.8		$t3#lo, $b, $b, #2	@ B2
-+	vmull.p8	$t3, $a, $t3#lo		@ G = A*B2
-+	vext.8		$t2#lo, $a, $a, #3	@ A3
-+	veor		$t0, $t0, $r		@ L = E + F
-+	vmull.p8	$t2, $t2#lo, $b		@ J = A3*B
-+	vext.8		$r#lo, $b, $b, #3	@ B3
-+	veor		$t1, $t1, $t3		@ M = G + H
-+	vmull.p8	$r, $a, $r#lo		@ I = A*B3
-+	veor		$t0#lo, $t0#lo, $t0#hi	@ t0 = (L) (P0 + P1) << 8
-+	vand		$t0#hi, $t0#hi, $k48
-+	vext.8		$t3#lo, $b, $b, #4	@ B4
-+	veor		$t1#lo, $t1#lo, $t1#hi	@ t1 = (M) (P2 + P3) << 16
-+	vand		$t1#hi, $t1#hi, $k32
-+	vmull.p8	$t3, $a, $t3#lo		@ K = A*B4
-+	veor		$t2, $t2, $r		@ N = I + J
-+	veor		$t0#lo, $t0#lo, $t0#hi
-+	veor		$t1#lo, $t1#lo, $t1#hi
-+	veor		$t2#lo, $t2#lo, $t2#hi	@ t2 = (N) (P4 + P5) << 24
-+	vand		$t2#hi, $t2#hi, $k16
-+	vext.8		$t0, $t0, $t0, #15
-+	veor		$t3#lo, $t3#lo, $t3#hi	@ t3 = (K) (P6 + P7) << 32
-+	vmov.i64	$t3#hi, #0
-+	vext.8		$t1, $t1, $t1, #14
-+	veor		$t2#lo, $t2#lo, $t2#hi
-+	vmull.p8	$r, $a, $b		@ D = A*B
-+	vext.8		$t3, $t3, $t3, #12
-+	vext.8		$t2, $t2, $t2, #13
-+	veor		$t0, $t0, $t1
-+	veor		$t2, $t2, $t3
-+	veor		$r, $r, $t0
-+	veor		$r, $r, $t2
-+___
-+}
-+
-+$code.=<<___;
-+#if __ARM_MAX_ARCH__>=7
-+.arch	armv7-a
-+.fpu	neon
-+
-+.global	gcm_init_neon
-+.type	gcm_init_neon,%function
-+.align	4
-+gcm_init_neon:
-+	vld1.64		$IN#hi,[r1]!		@ load H
-+	vmov.i8		$t0,#0xe1
-+	vld1.64		$IN#lo,[r1]
-+	vshl.i64	$t0#hi,#57
-+	vshr.u64	$t0#lo,#63		@ t0=0xc2....01
-+	vdup.8		$t1,$IN#hi[7]
-+	vshr.u64	$Hlo,$IN#lo,#63
-+	vshr.s8		$t1,#7			@ broadcast carry bit
-+	vshl.i64	$IN,$IN,#1
-+	vand		$t0,$t0,$t1
-+	vorr		$IN#hi,$Hlo		@ H<<<=1
-+	veor		$IN,$IN,$t0		@ twisted H
-+	vstmia		r0,{$IN}
-+
-+	ret					@ bx lr
-+.size	gcm_init_neon,.-gcm_init_neon
-+
-+.global	gcm_gmult_neon
-+.type	gcm_gmult_neon,%function
-+.align	4
-+gcm_gmult_neon:
-+	vld1.64		$IN#hi,[$Xi]!		@ load Xi
-+	vld1.64		$IN#lo,[$Xi]!
-+	vmov.i64	$k48,#0x0000ffffffffffff
-+	vldmia		$Htbl,{$Hlo-$Hhi}	@ load twisted H
-+	vmov.i64	$k32,#0x00000000ffffffff
-+#ifdef __ARMEL__
-+	vrev64.8	$IN,$IN
-+#endif
-+	vmov.i64	$k16,#0x000000000000ffff
-+	veor		$Hhl,$Hlo,$Hhi		@ Karatsuba pre-processing
-+	mov		$len,#16
-+	b		.Lgmult_neon
-+.size	gcm_gmult_neon,.-gcm_gmult_neon
-+
-+.global	gcm_ghash_neon
-+.type	gcm_ghash_neon,%function
-+.align	4
-+gcm_ghash_neon:
-+	vld1.64		$Xl#hi,[$Xi]!		@ load Xi
-+	vld1.64		$Xl#lo,[$Xi]!
-+	vmov.i64	$k48,#0x0000ffffffffffff
-+	vldmia		$Htbl,{$Hlo-$Hhi}	@ load twisted H
-+	vmov.i64	$k32,#0x00000000ffffffff
-+#ifdef __ARMEL__
-+	vrev64.8	$Xl,$Xl
-+#endif
-+	vmov.i64	$k16,#0x000000000000ffff
-+	veor		$Hhl,$Hlo,$Hhi		@ Karatsuba pre-processing
-+
-+.Loop_neon:
-+	vld1.64		$IN#hi,[$inp]!		@ load inp
-+	vld1.64		$IN#lo,[$inp]!
-+#ifdef __ARMEL__
-+	vrev64.8	$IN,$IN
-+#endif
-+	veor		$IN,$Xl			@ inp^=Xi
-+.Lgmult_neon:
-+___
-+	&clmul64x64	($Xl,$Hlo,"$IN#lo");	# H.lo·Xi.lo
-+$code.=<<___;
-+	veor		$IN#lo,$IN#lo,$IN#hi	@ Karatsuba pre-processing
-+___
-+	&clmul64x64	($Xm,$Hhl,"$IN#lo");	# (H.lo+H.hi)·(Xi.lo+Xi.hi)
-+	&clmul64x64	($Xh,$Hhi,"$IN#hi");	# H.hi·Xi.hi
-+$code.=<<___;
-+	veor		$Xm,$Xm,$Xl		@ Karatsuba post-processing
-+	veor		$Xm,$Xm,$Xh
-+	veor		$Xl#hi,$Xl#hi,$Xm#lo
-+	veor		$Xh#lo,$Xh#lo,$Xm#hi	@ Xh|Xl - 256-bit result
-+
-+	@ equivalent of reduction_avx from ghash-x86_64.pl
-+	vshl.i64	$t1,$Xl,#57		@ 1st phase
-+	vshl.i64	$t2,$Xl,#62
-+	veor		$t2,$t2,$t1		@
-+	vshl.i64	$t1,$Xl,#63
-+	veor		$t2, $t2, $t1		@
-+ 	veor		$Xl#hi,$Xl#hi,$t2#lo	@
-+	veor		$Xh#lo,$Xh#lo,$t2#hi
-+
-+	vshr.u64	$t2,$Xl,#1		@ 2nd phase
-+	veor		$Xh,$Xh,$Xl
-+	veor		$Xl,$Xl,$t2		@
-+	vshr.u64	$t2,$t2,#6
-+	vshr.u64	$Xl,$Xl,#1		@
-+	veor		$Xl,$Xl,$Xh		@
-+	veor		$Xl,$Xl,$t2		@
-+
-+	subs		$len,#16
-+	bne		.Loop_neon
-+
-+#ifdef __ARMEL__
-+	vrev64.8	$Xl,$Xl
-+#endif
-+	sub		$Xi,#16	
-+	vst1.64		$Xl#hi,[$Xi]!		@ write out Xi
-+	vst1.64		$Xl#lo,[$Xi]
-+
-+	ret					@ bx lr
-+.size	gcm_ghash_neon,.-gcm_ghash_neon
-+#endif
-+___
-+}
-+$code.=<<___;
-+.asciz  "GHASH for ARMv4/NEON, CRYPTOGAMS by "
-+.align  2
-+___
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo	or
-+	s/\bret\b/bx	lr/go		or
-+	s/\bbx\s+lr\b/.word\t0xe12fff1e/go;    # make it possible to compile with -march=armv4
-+
-+	print $_,"\n";
-+}
-+close STDOUT; # enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-c64xplus.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-c64xplus.pl
-new file mode 100644
-index 0000000..3cadda3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-c64xplus.pl
-@@ -0,0 +1,247 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# December 2011
-+#
-+# The module implements GCM GHASH function and underlying single
-+# multiplication operation in GF(2^128). Even though subroutines
-+# have _4bit suffix, they are not using any tables, but rely on
-+# hardware Galois Field Multiply support. Streamed GHASH processes
-+# byte in ~7 cycles, which is >6x faster than "4-bit" table-driven
-+# code compiled with TI's cl6x 6.0 with -mv6400+ -o2 flags. We are
-+# comparing apples vs. oranges, but compiler surely could have done
-+# better, because theoretical [though not necessarily achievable]
-+# estimate for "4-bit" table-driven implementation is ~12 cycles.
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+($Xip,$Htable,$inp,$len)=("A4","B4","A6","B6");	# arguments
-+
-+($Z0,$Z1,$Z2,$Z3,	$H0, $H1, $H2, $H3,
-+			$H0x,$H1x,$H2x,$H3x)=map("A$_",(16..27));
-+($H01u,$H01y,$H2u,$H3u,	$H0y,$H1y,$H2y,$H3y,
-+			$H0z,$H1z,$H2z,$H3z)=map("B$_",(16..27));
-+($FF000000,$E10000)=("B30","B31");
-+($xip,$x0,$x1,$xib)=map("B$_",(6..9));	# $xip zaps $len
-+ $xia="A9";
-+($rem,$res)=("B4","B5");		# $rem zaps $Htable
-+
-+$code.=<<___;
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.asg	gcm_gmult_1bit,_gcm_gmult_1bit
-+	.asg	gcm_gmult_4bit,_gcm_gmult_4bit
-+	.asg	gcm_ghash_4bit,_gcm_ghash_4bit
-+	.endif
-+
-+	.asg	B3,RA
-+
-+	.if	0
-+	.global	_gcm_gmult_1bit
-+_gcm_gmult_1bit:
-+	ADDAD	$Htable,2,$Htable
-+	.endif
-+	.global	_gcm_gmult_4bit
-+_gcm_gmult_4bit:
-+	.asmfunc
-+	LDDW	*${Htable}[-1],$H1:$H0	; H.lo
-+	LDDW	*${Htable}[-2],$H3:$H2	; H.hi
-+||	MV	$Xip,${xip}		; reassign Xi
-+||	MVK	15,B1			; SPLOOPD constant
-+
-+	MVK	0xE1,$E10000
-+||	LDBU	*++${xip}[15],$x1	; Xi[15]
-+	MVK	0xFF,$FF000000
-+||	LDBU	*--${xip},$x0		; Xi[14]
-+	SHL	$E10000,16,$E10000	; [pre-shifted] reduction polynomial
-+	SHL	$FF000000,24,$FF000000	; upper byte mask
-+||	BNOP	ghash_loop?
-+||	MVK	1,B0			; take a single spin
-+
-+	PACKH2	$H0,$H1,$xia		; pack H0' and H1's upper bytes
-+	AND	$H2,$FF000000,$H2u	; H2's upper byte
-+	AND	$H3,$FF000000,$H3u	; H3's upper byte
-+||	SHRU	$H2u,8,$H2u
-+	SHRU	$H3u,8,$H3u
-+||	ZERO	$Z1:$Z0
-+	SHRU2	$xia,8,$H01u
-+||	ZERO	$Z3:$Z2
-+	.endasmfunc
-+
-+	.global	_gcm_ghash_4bit
-+_gcm_ghash_4bit:
-+	.asmfunc
-+	LDDW	*${Htable}[-1],$H1:$H0	; H.lo
-+||	SHRU	$len,4,B0		; reassign len
-+	LDDW	*${Htable}[-2],$H3:$H2	; H.hi
-+||	MV	$Xip,${xip}		; reassign Xi
-+||	MVK	15,B1			; SPLOOPD constant
-+
-+	MVK	0xE1,$E10000
-+|| [B0]	LDNDW	*${inp}[1],$H1x:$H0x
-+	MVK	0xFF,$FF000000
-+|| [B0]	LDNDW	*${inp}++[2],$H3x:$H2x
-+	SHL	$E10000,16,$E10000	; [pre-shifted] reduction polynomial
-+||	LDDW	*${xip}[1],$Z1:$Z0
-+	SHL	$FF000000,24,$FF000000	; upper byte mask
-+||	LDDW	*${xip}[0],$Z3:$Z2
-+
-+	PACKH2	$H0,$H1,$xia		; pack H0' and H1's upper bytes
-+	AND	$H2,$FF000000,$H2u	; H2's upper byte
-+	AND	$H3,$FF000000,$H3u	; H3's upper byte
-+||	SHRU	$H2u,8,$H2u
-+	SHRU	$H3u,8,$H3u
-+	SHRU2	$xia,8,$H01u
-+
-+|| [B0]	XOR	$H0x,$Z0,$Z0		; Xi^=inp
-+|| [B0]	XOR	$H1x,$Z1,$Z1
-+	.if	.LITTLE_ENDIAN
-+   [B0]	XOR	$H2x,$Z2,$Z2
-+|| [B0]	XOR	$H3x,$Z3,$Z3
-+|| [B0]	SHRU	$Z1,24,$xia		; Xi[15], avoid cross-path stall
-+	STDW	$Z1:$Z0,*${xip}[1]
-+|| [B0]	SHRU	$Z1,16,$x0		; Xi[14]
-+|| [B0]	ZERO	$Z1:$Z0
-+	.else
-+   [B0]	XOR	$H2x,$Z2,$Z2
-+|| [B0]	XOR	$H3x,$Z3,$Z3
-+|| [B0]	MV	$Z0,$xia		; Xi[15], avoid cross-path stall
-+	STDW	$Z1:$Z0,*${xip}[1]
-+|| [B0] SHRU	$Z0,8,$x0		; Xi[14]
-+|| [B0]	ZERO	$Z1:$Z0
-+	.endif
-+	STDW	$Z3:$Z2,*${xip}[0]
-+|| [B0]	ZERO	$Z3:$Z2
-+|| [B0]	MV	$xia,$x1
-+   [B0]	ADDK	14,${xip}
-+
-+ghash_loop?:
-+	SPLOOPD	6			; 6*16+7
-+||	MVC	B1,ILC
-+|| [B0]	SUB	B0,1,B0
-+||	ZERO	A0
-+||	ADD	$x1,$x1,$xib		; SHL	$x1,1,$xib
-+||	SHL	$x1,1,$xia
-+___
-+
-+########____________________________
-+#  0    D2.     M1          M2      |
-+#  1            M1                  |
-+#  2            M1          M2      |
-+#  3        D1. M1          M2      |
-+#  4        S1. L1                  |
-+#  5    S2  S1x L1          D2  L2  |____________________________
-+#  6/0          L1  S1      L2  S2x |D2.     M1          M2      |
-+#  7/1          L1  S1  D1x S2  M2  |        M1                  |
-+#  8/2              S1  L1x S2      |        M1          M2      |
-+#  9/3              S1  L1x         |    D1. M1          M2      |
-+# 10/4                  D1x         |    S1. L1                  |
-+# 11/5                              |S2  S1x L1          D2  L2  |____________
-+# 12/6/0                D1x       __|        L1  S1      L2  S2x |D2.     ....
-+#    7/1                                     L1  S1  D1x S2  M2  |        ....
-+#    8/2                                         S1  L1x S2      |        ....
-+#####...                                         ................|............
-+$code.=<<___;
-+	XORMPY	$H0,$xia,$H0x		; 0	; H·(Xi[i]<<1)
-+||	XORMPY	$H01u,$xib,$H01y
-+|| [A0]	LDBU	*--${xip},$x0
-+	XORMPY	$H1,$xia,$H1x		; 1
-+	XORMPY	$H2,$xia,$H2x		; 2
-+||	XORMPY	$H2u,$xib,$H2y
-+	XORMPY	$H3,$xia,$H3x		; 3
-+||	XORMPY	$H3u,$xib,$H3y
-+||[!A0]	MVK.D	15,A0				; *--${xip} counter
-+	XOR.L	$H0x,$Z0,$Z0		; 4	; Z^=H·(Xi[i]<<1)
-+|| [A0]	SUB.S	A0,1,A0
-+	XOR.L	$H1x,$Z1,$Z1		; 5
-+||	AND.D	$H01y,$FF000000,$H0z
-+||	SWAP2.L	$H01y,$H1y		;	; SHL	$H01y,16,$H1y
-+||	SHL	$x0,1,$xib
-+||	SHL	$x0,1,$xia
-+
-+	XOR.L	$H2x,$Z2,$Z2		; 6/0	; [0,0] in epilogue
-+||	SHL	$Z0,1,$rem		;	; rem=Z<<1
-+||	SHRMB.S	$Z1,$Z0,$Z0		;	; Z>>=8
-+||	AND.L	$H1y,$FF000000,$H1z
-+	XOR.L	$H3x,$Z3,$Z3		; 7/1
-+||	SHRMB.S	$Z2,$Z1,$Z1
-+||	XOR.D	$H0z,$Z0,$Z0			; merge upper byte products
-+||	AND.S	$H2y,$FF000000,$H2z
-+||	XORMPY	$E10000,$rem,$res	;	; implicit rem&0x1FE
-+	XOR.L	$H1z,$Z1,$Z1		; 8/2
-+||	SHRMB.S	$Z3,$Z2,$Z2
-+||	AND.S	$H3y,$FF000000,$H3z
-+	XOR.L	$H2z,$Z2,$Z2		; 9/3
-+||	SHRU	$Z3,8,$Z3
-+	XOR.D	$H3z,$Z3,$Z3		; 10/4
-+	NOP				; 11/5
-+
-+	SPKERNEL 0,2
-+||	XOR.D	$res,$Z3,$Z3		; 12/6/0; Z^=res
-+
-+	; input pre-fetch is possible where D1 slot is available...
-+   [B0]	LDNDW	*${inp}[1],$H1x:$H0x	; 8/-
-+   [B0]	LDNDW	*${inp}++[2],$H3x:$H2x	; 9/-
-+	NOP				; 10/-
-+	.if	.LITTLE_ENDIAN
-+	SWAP2	$Z0,$Z1			; 11/-
-+||	SWAP4	$Z1,$Z0
-+	SWAP4	$Z1,$Z1			; 12/-
-+||	SWAP2	$Z0,$Z0
-+	SWAP2	$Z2,$Z3
-+||	SWAP4	$Z3,$Z2
-+||[!B0]	BNOP	RA
-+	SWAP4	$Z3,$Z3
-+||	SWAP2	$Z2,$Z2
-+|| [B0]	BNOP	ghash_loop?
-+   [B0]	XOR	$H0x,$Z0,$Z0		; Xi^=inp
-+|| [B0]	XOR	$H1x,$Z1,$Z1
-+   [B0]	XOR	$H2x,$Z2,$Z2
-+|| [B0]	XOR	$H3x,$Z3,$Z3
-+|| [B0]	SHRU	$Z1,24,$xia		; Xi[15], avoid cross-path stall
-+	STDW	$Z1:$Z0,*${xip}[1]
-+|| [B0]	SHRU	$Z1,16,$x0		; Xi[14]
-+|| [B0]	ZERO	$Z1:$Z0
-+	.else
-+  [!B0]	BNOP	RA			; 11/-
-+   [B0]	BNOP	ghash_loop?		; 12/-
-+   [B0]	XOR	$H0x,$Z0,$Z0		; Xi^=inp
-+|| [B0]	XOR	$H1x,$Z1,$Z1
-+   [B0]	XOR	$H2x,$Z2,$Z2
-+|| [B0]	XOR	$H3x,$Z3,$Z3
-+|| [B0]	MV	$Z0,$xia		; Xi[15], avoid cross-path stall
-+	STDW	$Z1:$Z0,*${xip}[1]
-+|| [B0] SHRU	$Z0,8,$x0		; Xi[14]
-+|| [B0]	ZERO	$Z1:$Z0
-+	.endif
-+	STDW	$Z3:$Z2,*${xip}[0]
-+|| [B0]	ZERO	$Z3:$Z2
-+|| [B0]	MV	$xia,$x1
-+   [B0]	ADDK	14,${xip}
-+	.endasmfunc
-+
-+	.sect	.const
-+	.cstring "GHASH for C64x+, CRYPTOGAMS by "
-+	.align	4
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-ia64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-ia64.pl
-new file mode 100755
-index 0000000..81e75f7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-ia64.pl
-@@ -0,0 +1,470 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# March 2010
-+#
-+# The module implements "4-bit" GCM GHASH function and underlying
-+# single multiplication operation in GF(2^128). "4-bit" means that it
-+# uses 256 bytes per-key table [+128 bytes shared table]. Streamed
-+# GHASH performance was measured to be 6.67 cycles per processed byte
-+# on Itanium 2, which is >90% better than Microsoft compiler generated
-+# code. To anchor to something else sha1-ia64.pl module processes one
-+# byte in 5.7 cycles. On Itanium GHASH should run at ~8.5 cycles per
-+# byte.
-+
-+# September 2010
-+#
-+# It was originally thought that it makes lesser sense to implement
-+# "528B" variant on Itanium 2 for following reason. Because number of
-+# functional units is naturally limited, it appeared impossible to
-+# implement "528B" loop in 4 cycles, only in 5. This would mean that
-+# theoretically performance improvement couldn't be more than 20%.
-+# But occasionally you prove yourself wrong:-) I figured out a way to
-+# fold couple of instructions and having freed yet another instruction
-+# slot by unrolling the loop... Resulting performance is 4.45 cycles
-+# per processed byte and 50% better than "256B" version. On original
-+# Itanium performance should remain the same as the "256B" version,
-+# i.e. ~8.5 cycles.
-+
-+$output=pop and (open STDOUT,">$output" or die "can't open $output: $!");
-+
-+if ($^O eq "hpux") {
-+    $ADDP="addp4";
-+    for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
-+} else { $ADDP="add"; }
-+for (@ARGV)  {  $big_endian=1 if (/\-DB_ENDIAN/);
-+                $big_endian=0 if (/\-DL_ENDIAN/);  }
-+if (!defined($big_endian))
-+             {  $big_endian=(unpack('L',pack('N',1))==1);  }
-+
-+sub loop() {
-+my $label=shift;
-+my ($p16,$p17)=(shift)?("p63","p63"):("p16","p17"); # mask references to inp
-+
-+# Loop is scheduled for 6 ticks on Itanium 2 and 8 on Itanium, i.e.
-+# in scalable manner;-) Naturally assuming data in L1 cache...
-+# Special note about 'dep' instruction, which is used to construct
-+# &rem_4bit[Zlo&0xf]. It works, because rem_4bit is aligned at 128
-+# bytes boundary and lower 7 bits of its address are guaranteed to
-+# be zero.
-+$code.=<<___;
-+$label:
-+{ .mfi;	(p18)	ld8	Hlo=[Hi[1]],-8
-+	(p19)	dep	rem=Zlo,rem_4bitp,3,4	}
-+{ .mfi;	(p19)	xor	Zhi=Zhi,Hhi
-+	($p17)	xor	xi[1]=xi[1],in[1]	};;
-+{ .mfi;	(p18)	ld8	Hhi=[Hi[1]]
-+	(p19)	shrp	Zlo=Zhi,Zlo,4		}
-+{ .mfi;	(p19)	ld8	rem=[rem]
-+	(p18)	and	Hi[1]=mask0xf0,xi[2]	};;
-+{ .mmi;	($p16)	ld1	in[0]=[inp],-1
-+	(p18)	xor	Zlo=Zlo,Hlo
-+	(p19)	shr.u	Zhi=Zhi,4		}
-+{ .mib;	(p19)	xor	Hhi=Hhi,rem
-+	(p18)	add	Hi[1]=Htbl,Hi[1]	};;
-+
-+{ .mfi;	(p18)	ld8	Hlo=[Hi[1]],-8
-+	(p18)	dep	rem=Zlo,rem_4bitp,3,4	}
-+{ .mfi;	(p17)	shladd	Hi[0]=xi[1],4,r0
-+	(p18)	xor	Zhi=Zhi,Hhi		};;
-+{ .mfi;	(p18)	ld8	Hhi=[Hi[1]]
-+	(p18)	shrp	Zlo=Zhi,Zlo,4		}
-+{ .mfi;	(p18)	ld8	rem=[rem]
-+	(p17)	and	Hi[0]=mask0xf0,Hi[0]	};;
-+{ .mmi;	(p16)	ld1	xi[0]=[Xi],-1
-+	(p18)	xor	Zlo=Zlo,Hlo
-+	(p18)	shr.u	Zhi=Zhi,4		}
-+{ .mib;	(p18)	xor	Hhi=Hhi,rem
-+	(p17)	add	Hi[0]=Htbl,Hi[0]
-+	br.ctop.sptk	$label			};;
-+___
-+}
-+
-+$code=<<___;
-+.explicit
-+.text
-+
-+prevfs=r2;	prevlc=r3;	prevpr=r8;
-+mask0xf0=r21;
-+rem=r22;	rem_4bitp=r23;
-+Xi=r24;		Htbl=r25;
-+inp=r26;	end=r27;
-+Hhi=r28;	Hlo=r29;
-+Zhi=r30;	Zlo=r31;
-+
-+.align	128
-+.skip	16					// aligns loop body
-+.global	gcm_gmult_4bit#
-+.proc	gcm_gmult_4bit#
-+gcm_gmult_4bit:
-+	.prologue
-+{ .mmi;	.save	ar.pfs,prevfs
-+	alloc	prevfs=ar.pfs,2,6,0,8
-+	$ADDP	Xi=15,in0			// &Xi[15]
-+	mov	rem_4bitp=ip		}
-+{ .mii;	$ADDP	Htbl=8,in1			// &Htbl[0].lo
-+	.save	ar.lc,prevlc
-+	mov	prevlc=ar.lc
-+	.save	pr,prevpr
-+	mov	prevpr=pr		};;
-+
-+	.body
-+	.rotr	in[3],xi[3],Hi[2]
-+
-+{ .mib;	ld1	xi[2]=[Xi],-1			// Xi[15]
-+	mov	mask0xf0=0xf0
-+	brp.loop.imp	.Loop1,.Lend1-16};;
-+{ .mmi;	ld1	xi[1]=[Xi],-1			// Xi[14]
-+					};;
-+{ .mii;	shladd	Hi[1]=xi[2],4,r0
-+	mov	pr.rot=0x7<<16
-+	mov	ar.lc=13		};;
-+{ .mii;	and	Hi[1]=mask0xf0,Hi[1]
-+	mov	ar.ec=3
-+	xor	Zlo=Zlo,Zlo		};;
-+{ .mii;	add	Hi[1]=Htbl,Hi[1]		// &Htbl[nlo].lo
-+	add	rem_4bitp=rem_4bit#-gcm_gmult_4bit#,rem_4bitp
-+	xor	Zhi=Zhi,Zhi		};;
-+___
-+	&loop	(".Loop1",1);
-+$code.=<<___;
-+.Lend1:
-+{ .mib;	xor	Zhi=Zhi,Hhi		};;	// modulo-scheduling artefact
-+{ .mib;	mux1	Zlo=Zlo,\@rev		};;
-+{ .mib;	mux1	Zhi=Zhi,\@rev		};;
-+{ .mmi;	add	Hlo=9,Xi;;			// ;; is here to prevent
-+	add	Hhi=1,Xi		};;	// pipeline flush on Itanium
-+{ .mib;	st8	[Hlo]=Zlo
-+	mov	pr=prevpr,0x1ffff	};;
-+{ .mib;	st8	[Hhi]=Zhi
-+	mov	ar.lc=prevlc
-+	br.ret.sptk.many	b0	};;
-+.endp	gcm_gmult_4bit#
-+___
-+
-+######################################################################
-+# "528B" (well, "512B" actualy) streamed GHASH
-+#
-+$Xip="in0";
-+$Htbl="in1";
-+$inp="in2";
-+$len="in3";
-+$rem_8bit="loc0";
-+$mask0xff="loc1";
-+($sum,$rum) = $big_endian ? ("nop.m","nop.m") : ("sum","rum");
-+
-+sub load_htable() {
-+    for (my $i=0;$i<8;$i++) {
-+	$code.=<<___;
-+{ .mmi;	ld8	r`16+2*$i+1`=[r8],16		// Htable[$i].hi
-+	ld8	r`16+2*$i`=[r9],16	}	// Htable[$i].lo
-+{ .mmi;	ldf8	f`32+2*$i+1`=[r10],16		// Htable[`8+$i`].hi
-+	ldf8	f`32+2*$i`=[r11],16		// Htable[`8+$i`].lo
-+___
-+	$code.=shift	if (($i+$#_)==7);
-+	$code.="\t};;\n"
-+    }
-+}
-+
-+$code.=<<___;
-+prevsp=r3;
-+
-+.align	32
-+.skip	16					// aligns loop body
-+.global	gcm_ghash_4bit#
-+.proc	gcm_ghash_4bit#
-+gcm_ghash_4bit:
-+	.prologue
-+{ .mmi;	.save	ar.pfs,prevfs
-+	alloc	prevfs=ar.pfs,4,2,0,0
-+	.vframe	prevsp
-+	mov	prevsp=sp
-+	mov	$rem_8bit=ip		};;
-+	.body
-+{ .mfi;	$ADDP	r8=0+0,$Htbl
-+	$ADDP	r9=0+8,$Htbl		}
-+{ .mfi;	$ADDP	r10=128+0,$Htbl
-+	$ADDP	r11=128+8,$Htbl		};;
-+___
-+	&load_htable(
-+	"	$ADDP	$Xip=15,$Xip",		# &Xi[15]
-+	"	$ADDP	$len=$len,$inp",	# &inp[len]
-+	"	$ADDP	$inp=15,$inp",		# &inp[15]
-+	"	mov	$mask0xff=0xff",
-+	"	add	sp=-512,sp",
-+	"	andcm	sp=sp,$mask0xff",	# align stack frame
-+	"	add	r14=0,sp",
-+	"	add	r15=8,sp");
-+$code.=<<___;
-+{ .mmi;	$sum	1<<1				// go big-endian
-+	add	r8=256+0,sp
-+	add	r9=256+8,sp		}
-+{ .mmi;	add	r10=256+128+0,sp
-+	add	r11=256+128+8,sp
-+	add	$len=-17,$len		};;
-+___
-+for($i=0;$i<8;$i++) {	# generate first half of Hshr4[]
-+my ($rlo,$rhi)=("r".eval(16+2*$i),"r".eval(16+2*$i+1));
-+$code.=<<___;
-+{ .mmi;	st8	[r8]=$rlo,16			// Htable[$i].lo
-+	st8	[r9]=$rhi,16			// Htable[$i].hi
-+	shrp	$rlo=$rhi,$rlo,4	}//;;
-+{ .mmi;	stf8	[r10]=f`32+2*$i`,16		// Htable[`8+$i`].lo
-+	stf8	[r11]=f`32+2*$i+1`,16		// Htable[`8+$i`].hi
-+	shr.u	$rhi=$rhi,4		};;
-+{ .mmi;	st8	[r14]=$rlo,16			// Htable[$i].lo>>4
-+	st8	[r15]=$rhi,16		}//;;	// Htable[$i].hi>>4
-+___
-+}
-+$code.=<<___;
-+{ .mmi;	ld8	r16=[r8],16			// Htable[8].lo
-+	ld8	r17=[r9],16		};;	// Htable[8].hi
-+{ .mmi;	ld8	r18=[r8],16			// Htable[9].lo
-+	ld8	r19=[r9],16		}	// Htable[9].hi
-+{ .mmi;	rum	1<<5				// clear um.mfh
-+	shrp	r16=r17,r16,4		};;
-+___
-+for($i=0;$i<6;$i++) {	# generate second half of Hshr4[]
-+$code.=<<___;
-+{ .mmi;	ld8	r`20+2*$i`=[r8],16		// Htable[`10+$i`].lo
-+	ld8	r`20+2*$i+1`=[r9],16		// Htable[`10+$i`].hi
-+	shr.u	r`16+2*$i+1`=r`16+2*$i+1`,4	};;
-+{ .mmi;	st8	[r14]=r`16+2*$i`,16		// Htable[`8+$i`].lo>>4
-+	st8	[r15]=r`16+2*$i+1`,16		// Htable[`8+$i`].hi>>4
-+	shrp	r`18+2*$i`=r`18+2*$i+1`,r`18+2*$i`,4	}
-+___
-+}
-+$code.=<<___;
-+{ .mmi;	shr.u	r`16+2*$i+1`=r`16+2*$i+1`,4	};;
-+{ .mmi;	st8	[r14]=r`16+2*$i`,16		// Htable[`8+$i`].lo>>4
-+	st8	[r15]=r`16+2*$i+1`,16		// Htable[`8+$i`].hi>>4
-+	shrp	r`18+2*$i`=r`18+2*$i+1`,r`18+2*$i`,4	}
-+{ .mmi;	add	$Htbl=256,sp			// &Htable[0]
-+	add	$rem_8bit=rem_8bit#-gcm_ghash_4bit#,$rem_8bit
-+	shr.u	r`18+2*$i+1`=r`18+2*$i+1`,4	};;
-+{ .mmi;	st8	[r14]=r`18+2*$i`		// Htable[`8+$i`].lo>>4
-+	st8	[r15]=r`18+2*$i+1`	}	// Htable[`8+$i`].hi>>4
-+___
-+
-+$in="r15";
-+@xi=("r16","r17");
-+@rem=("r18","r19");
-+($Alo,$Ahi,$Blo,$Bhi,$Zlo,$Zhi)=("r20","r21","r22","r23","r24","r25");
-+($Atbl,$Btbl)=("r26","r27");
-+
-+$code.=<<___;	# (p16)
-+{ .mmi;	ld1	$in=[$inp],-1			//(p16) *inp--
-+	ld1	$xi[0]=[$Xip],-1		//(p16) *Xi--
-+	cmp.eq	p0,p6=r0,r0		};;	//	clear p6
-+___
-+push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
-+
-+$code.=<<___;	# (p16),(p17)
-+{ .mmi;	ld1	$xi[0]=[$Xip],-1		//(p16) *Xi--
-+	xor	$xi[1]=$xi[1],$in	};;	//(p17) xi=$xi[i]^inp[i]
-+{ .mii;	ld1	$in=[$inp],-1			//(p16) *inp--
-+	dep	$Atbl=$xi[1],$Htbl,4,4		//(p17) &Htable[nlo].lo
-+	and	$xi[1]=-16,$xi[1]	};;	//(p17) nhi=xi&0xf0
-+.align	32
-+.LOOP:
-+{ .mmi;
-+(p6)	st8	[$Xip]=$Zhi,13
-+	xor	$Zlo=$Zlo,$Zlo
-+	add	$Btbl=$xi[1],$Htbl	};;	//(p17) &Htable[nhi].lo
-+___
-+push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
-+
-+$code.=<<___;	# (p16),(p17),(p18)
-+{ .mmi;	ld8	$Alo=[$Atbl],8			//(p18) Htable[nlo].lo,&Htable[nlo].hi
-+	ld8	$rem[0]=[$Btbl],-256		//(p18) Htable[nhi].lo,&Hshr4[nhi].lo
-+	xor	$xi[1]=$xi[1],$in	};;	//(p17) xi=$xi[i]^inp[i]
-+{ .mfi;	ld8	$Ahi=[$Atbl]			//(p18) Htable[nlo].hi
-+	dep	$Atbl=$xi[1],$Htbl,4,4	}	//(p17) &Htable[nlo].lo
-+{ .mfi;	shladd	$rem[0]=$rem[0],4,r0		//(p18) Htable[nhi].lo<<4
-+	xor	$Zlo=$Zlo,$Alo		};;	//(p18) Z.lo^=Htable[nlo].lo
-+{ .mmi;	ld8	$Blo=[$Btbl],8			//(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi
-+	ld1	$in=[$inp],-1		}	//(p16) *inp--
-+{ .mmi;	xor	$rem[0]=$rem[0],$Zlo		//(p18) Z.lo^(Htable[nhi].lo<<4)
-+	mov	$Zhi=$Ahi			//(p18) Z.hi^=Htable[nlo].hi
-+	and	$xi[1]=-16,$xi[1]	};;	//(p17) nhi=xi&0xf0
-+{ .mmi;	ld8	$Bhi=[$Btbl]			//(p18) Hshr4[nhi].hi
-+	ld1	$xi[0]=[$Xip],-1		//(p16) *Xi--
-+	shrp	$Zlo=$Zhi,$Zlo,8	}	//(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8)
-+{ .mmi;	and	$rem[0]=$rem[0],$mask0xff	//(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
-+	add	$Btbl=$xi[1],$Htbl	};;	//(p17) &Htable[nhi]
-+___
-+push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
-+
-+for ($i=1;$i<14;$i++) {
-+# Above and below fragments are derived from this one by removing
-+# unsuitable (p??) instructions.
-+$code.=<<___;	# (p16),(p17),(p18),(p19)
-+{ .mmi;	ld8	$Alo=[$Atbl],8			//(p18) Htable[nlo].lo,&Htable[nlo].hi
-+	ld8	$rem[0]=[$Btbl],-256		//(p18) Htable[nhi].lo,&Hshr4[nhi].lo
-+	shr.u	$Zhi=$Zhi,8		}	//(p19) Z.hi>>=8
-+{ .mmi;	shladd	$rem[1]=$rem[1],1,$rem_8bit	//(p19) &rem_8bit[rem]
-+	xor	$Zlo=$Zlo,$Blo			//(p19) Z.lo^=Hshr4[nhi].lo
-+	xor	$xi[1]=$xi[1],$in	};;	//(p17) xi=$xi[i]^inp[i]
-+{ .mmi;	ld8	$Ahi=[$Atbl]			//(p18) Htable[nlo].hi
-+	ld2	$rem[1]=[$rem[1]]		//(p19) rem_8bit[rem]
-+	dep	$Atbl=$xi[1],$Htbl,4,4	}	//(p17) &Htable[nlo].lo
-+{ .mmi;	shladd	$rem[0]=$rem[0],4,r0		//(p18) Htable[nhi].lo<<4
-+	xor	$Zlo=$Zlo,$Alo			//(p18) Z.lo^=Htable[nlo].lo
-+	xor	$Zhi=$Zhi,$Bhi		};;	//(p19) Z.hi^=Hshr4[nhi].hi
-+{ .mmi;	ld8	$Blo=[$Btbl],8			//(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi
-+	ld1	$in=[$inp],-1			//(p16) *inp--
-+	shl	$rem[1]=$rem[1],48	}	//(p19) rem_8bit[rem]<<48
-+{ .mmi;	xor	$rem[0]=$rem[0],$Zlo		//(p18) Z.lo^(Htable[nhi].lo<<4)
-+	xor	$Zhi=$Zhi,$Ahi			//(p18) Z.hi^=Htable[nlo].hi
-+	and	$xi[1]=-16,$xi[1]	};;	//(p17) nhi=xi&0xf0
-+{ .mmi;	ld8	$Bhi=[$Btbl]			//(p18) Hshr4[nhi].hi
-+	ld1	$xi[0]=[$Xip],-1		//(p16) *Xi--
-+	shrp	$Zlo=$Zhi,$Zlo,8	}	//(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8)
-+{ .mmi;	and	$rem[0]=$rem[0],$mask0xff	//(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
-+	xor	$Zhi=$Zhi,$rem[1]		//(p19) Z.hi^=rem_8bit[rem]<<48
-+	add	$Btbl=$xi[1],$Htbl	};;	//(p17) &Htable[nhi]
-+___
-+push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
-+}
-+
-+$code.=<<___;	# (p17),(p18),(p19)
-+{ .mmi;	ld8	$Alo=[$Atbl],8			//(p18) Htable[nlo].lo,&Htable[nlo].hi
-+	ld8	$rem[0]=[$Btbl],-256		//(p18) Htable[nhi].lo,&Hshr4[nhi].lo
-+	shr.u	$Zhi=$Zhi,8		}	//(p19) Z.hi>>=8
-+{ .mmi;	shladd	$rem[1]=$rem[1],1,$rem_8bit	//(p19) &rem_8bit[rem]
-+	xor	$Zlo=$Zlo,$Blo			//(p19) Z.lo^=Hshr4[nhi].lo
-+	xor	$xi[1]=$xi[1],$in	};;	//(p17) xi=$xi[i]^inp[i]
-+{ .mmi;	ld8	$Ahi=[$Atbl]			//(p18) Htable[nlo].hi
-+	ld2	$rem[1]=[$rem[1]]		//(p19) rem_8bit[rem]
-+	dep	$Atbl=$xi[1],$Htbl,4,4	};;	//(p17) &Htable[nlo].lo
-+{ .mmi;	shladd	$rem[0]=$rem[0],4,r0		//(p18) Htable[nhi].lo<<4
-+	xor	$Zlo=$Zlo,$Alo			//(p18) Z.lo^=Htable[nlo].lo
-+	xor	$Zhi=$Zhi,$Bhi		};;	//(p19) Z.hi^=Hshr4[nhi].hi
-+{ .mmi;	ld8	$Blo=[$Btbl],8			//(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi
-+	shl	$rem[1]=$rem[1],48	}	//(p19) rem_8bit[rem]<<48
-+{ .mmi;	xor	$rem[0]=$rem[0],$Zlo		//(p18) Z.lo^(Htable[nhi].lo<<4)
-+	xor	$Zhi=$Zhi,$Ahi			//(p18) Z.hi^=Htable[nlo].hi
-+	and	$xi[1]=-16,$xi[1]	};;	//(p17) nhi=xi&0xf0
-+{ .mmi;	ld8	$Bhi=[$Btbl]			//(p18) Hshr4[nhi].hi
-+	shrp	$Zlo=$Zhi,$Zlo,8	}	//(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8)
-+{ .mmi;	and	$rem[0]=$rem[0],$mask0xff	//(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
-+	xor	$Zhi=$Zhi,$rem[1]		//(p19) Z.hi^=rem_8bit[rem]<<48
-+	add	$Btbl=$xi[1],$Htbl	};;	//(p17) &Htable[nhi]
-+___
-+push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
-+
-+$code.=<<___;	# (p18),(p19)
-+{ .mfi;	ld8	$Alo=[$Atbl],8			//(p18) Htable[nlo].lo,&Htable[nlo].hi
-+	shr.u	$Zhi=$Zhi,8		}	//(p19) Z.hi>>=8
-+{ .mfi;	shladd	$rem[1]=$rem[1],1,$rem_8bit	//(p19) &rem_8bit[rem]
-+	xor	$Zlo=$Zlo,$Blo		};;	//(p19) Z.lo^=Hshr4[nhi].lo
-+{ .mfi;	ld8	$Ahi=[$Atbl]			//(p18) Htable[nlo].hi
-+	xor	$Zlo=$Zlo,$Alo		}	//(p18) Z.lo^=Htable[nlo].lo
-+{ .mfi;	ld2	$rem[1]=[$rem[1]]		//(p19) rem_8bit[rem]
-+	xor	$Zhi=$Zhi,$Bhi		};;	//(p19) Z.hi^=Hshr4[nhi].hi
-+{ .mfi;	ld8	$Blo=[$Btbl],8			//(p18) Htable[nhi].lo,&Htable[nhi].hi
-+	shl	$rem[1]=$rem[1],48	}	//(p19) rem_8bit[rem]<<48
-+{ .mfi;	shladd	$rem[0]=$Zlo,4,r0		//(p18) Z.lo<<4
-+	xor	$Zhi=$Zhi,$Ahi		};;	//(p18) Z.hi^=Htable[nlo].hi
-+{ .mfi;	ld8	$Bhi=[$Btbl]			//(p18) Htable[nhi].hi
-+	shrp	$Zlo=$Zhi,$Zlo,4	}	//(p18) Z.lo=(Z.hi<<60)|(Z.lo>>4)
-+{ .mfi;	and	$rem[0]=$rem[0],$mask0xff	//(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff
-+	xor	$Zhi=$Zhi,$rem[1]	};;	//(p19) Z.hi^=rem_8bit[rem]<<48
-+___
-+push (@xi,shift(@xi)); push (@rem,shift(@rem));	# "rotate" registers
-+
-+$code.=<<___;	# (p19)
-+{ .mmi;	cmp.ltu	p6,p0=$inp,$len
-+	add	$inp=32,$inp
-+	shr.u	$Zhi=$Zhi,4		}	//(p19) Z.hi>>=4
-+{ .mmi;	shladd	$rem[1]=$rem[1],1,$rem_8bit	//(p19) &rem_8bit[rem]
-+	xor	$Zlo=$Zlo,$Blo			//(p19) Z.lo^=Hshr4[nhi].lo
-+	add	$Xip=9,$Xip		};;	//	&Xi.lo
-+{ .mmi;	ld2	$rem[1]=[$rem[1]]		//(p19) rem_8bit[rem]
-+(p6)	ld1	$in=[$inp],-1			//[p16] *inp--
-+(p6)	extr.u	$xi[1]=$Zlo,8,8		}	//[p17] Xi[14]
-+{ .mmi;	xor	$Zhi=$Zhi,$Bhi			//(p19) Z.hi^=Hshr4[nhi].hi
-+(p6)	and	$xi[0]=$Zlo,$mask0xff	};;	//[p16] Xi[15]
-+{ .mmi;	st8	[$Xip]=$Zlo,-8
-+(p6)	xor	$xi[0]=$xi[0],$in		//[p17] xi=$xi[i]^inp[i]
-+	shl	$rem[1]=$rem[1],48	};;	//(p19) rem_8bit[rem]<<48
-+{ .mmi;
-+(p6)	ld1	$in=[$inp],-1			//[p16] *inp--
-+	xor	$Zhi=$Zhi,$rem[1]		//(p19) Z.hi^=rem_8bit[rem]<<48
-+(p6)	dep	$Atbl=$xi[0],$Htbl,4,4	}	//[p17] &Htable[nlo].lo
-+{ .mib;
-+(p6)	and	$xi[0]=-16,$xi[0]		//[p17] nhi=xi&0xf0
-+(p6)	br.cond.dptk.many	.LOOP	};;
-+
-+{ .mib;	st8	[$Xip]=$Zhi		};;
-+{ .mib;	$rum	1<<1				// return to little-endian
-+	.restore	sp
-+	mov	sp=prevsp
-+	br.ret.sptk.many	b0	};;
-+.endp	gcm_ghash_4bit#
-+___
-+$code.=<<___;
-+.align	128
-+.type	rem_4bit#,\@object
-+rem_4bit:
-+        data8	0x0000<<48, 0x1C20<<48, 0x3840<<48, 0x2460<<48
-+        data8	0x7080<<48, 0x6CA0<<48, 0x48C0<<48, 0x54E0<<48
-+        data8	0xE100<<48, 0xFD20<<48, 0xD940<<48, 0xC560<<48
-+        data8	0x9180<<48, 0x8DA0<<48, 0xA9C0<<48, 0xB5E0<<48
-+.size	rem_4bit#,128
-+.type	rem_8bit#,\@object
-+rem_8bit:
-+	data1	0x00,0x00, 0x01,0xC2, 0x03,0x84, 0x02,0x46, 0x07,0x08, 0x06,0xCA, 0x04,0x8C, 0x05,0x4E
-+	data1	0x0E,0x10, 0x0F,0xD2, 0x0D,0x94, 0x0C,0x56, 0x09,0x18, 0x08,0xDA, 0x0A,0x9C, 0x0B,0x5E
-+	data1	0x1C,0x20, 0x1D,0xE2, 0x1F,0xA4, 0x1E,0x66, 0x1B,0x28, 0x1A,0xEA, 0x18,0xAC, 0x19,0x6E
-+	data1	0x12,0x30, 0x13,0xF2, 0x11,0xB4, 0x10,0x76, 0x15,0x38, 0x14,0xFA, 0x16,0xBC, 0x17,0x7E
-+	data1	0x38,0x40, 0x39,0x82, 0x3B,0xC4, 0x3A,0x06, 0x3F,0x48, 0x3E,0x8A, 0x3C,0xCC, 0x3D,0x0E
-+	data1	0x36,0x50, 0x37,0x92, 0x35,0xD4, 0x34,0x16, 0x31,0x58, 0x30,0x9A, 0x32,0xDC, 0x33,0x1E
-+	data1	0x24,0x60, 0x25,0xA2, 0x27,0xE4, 0x26,0x26, 0x23,0x68, 0x22,0xAA, 0x20,0xEC, 0x21,0x2E
-+	data1	0x2A,0x70, 0x2B,0xB2, 0x29,0xF4, 0x28,0x36, 0x2D,0x78, 0x2C,0xBA, 0x2E,0xFC, 0x2F,0x3E
-+	data1	0x70,0x80, 0x71,0x42, 0x73,0x04, 0x72,0xC6, 0x77,0x88, 0x76,0x4A, 0x74,0x0C, 0x75,0xCE
-+	data1	0x7E,0x90, 0x7F,0x52, 0x7D,0x14, 0x7C,0xD6, 0x79,0x98, 0x78,0x5A, 0x7A,0x1C, 0x7B,0xDE
-+	data1	0x6C,0xA0, 0x6D,0x62, 0x6F,0x24, 0x6E,0xE6, 0x6B,0xA8, 0x6A,0x6A, 0x68,0x2C, 0x69,0xEE
-+	data1	0x62,0xB0, 0x63,0x72, 0x61,0x34, 0x60,0xF6, 0x65,0xB8, 0x64,0x7A, 0x66,0x3C, 0x67,0xFE
-+	data1	0x48,0xC0, 0x49,0x02, 0x4B,0x44, 0x4A,0x86, 0x4F,0xC8, 0x4E,0x0A, 0x4C,0x4C, 0x4D,0x8E
-+	data1	0x46,0xD0, 0x47,0x12, 0x45,0x54, 0x44,0x96, 0x41,0xD8, 0x40,0x1A, 0x42,0x5C, 0x43,0x9E
-+	data1	0x54,0xE0, 0x55,0x22, 0x57,0x64, 0x56,0xA6, 0x53,0xE8, 0x52,0x2A, 0x50,0x6C, 0x51,0xAE
-+	data1	0x5A,0xF0, 0x5B,0x32, 0x59,0x74, 0x58,0xB6, 0x5D,0xF8, 0x5C,0x3A, 0x5E,0x7C, 0x5F,0xBE
-+	data1	0xE1,0x00, 0xE0,0xC2, 0xE2,0x84, 0xE3,0x46, 0xE6,0x08, 0xE7,0xCA, 0xE5,0x8C, 0xE4,0x4E
-+	data1	0xEF,0x10, 0xEE,0xD2, 0xEC,0x94, 0xED,0x56, 0xE8,0x18, 0xE9,0xDA, 0xEB,0x9C, 0xEA,0x5E
-+	data1	0xFD,0x20, 0xFC,0xE2, 0xFE,0xA4, 0xFF,0x66, 0xFA,0x28, 0xFB,0xEA, 0xF9,0xAC, 0xF8,0x6E
-+	data1	0xF3,0x30, 0xF2,0xF2, 0xF0,0xB4, 0xF1,0x76, 0xF4,0x38, 0xF5,0xFA, 0xF7,0xBC, 0xF6,0x7E
-+	data1	0xD9,0x40, 0xD8,0x82, 0xDA,0xC4, 0xDB,0x06, 0xDE,0x48, 0xDF,0x8A, 0xDD,0xCC, 0xDC,0x0E
-+	data1	0xD7,0x50, 0xD6,0x92, 0xD4,0xD4, 0xD5,0x16, 0xD0,0x58, 0xD1,0x9A, 0xD3,0xDC, 0xD2,0x1E
-+	data1	0xC5,0x60, 0xC4,0xA2, 0xC6,0xE4, 0xC7,0x26, 0xC2,0x68, 0xC3,0xAA, 0xC1,0xEC, 0xC0,0x2E
-+	data1	0xCB,0x70, 0xCA,0xB2, 0xC8,0xF4, 0xC9,0x36, 0xCC,0x78, 0xCD,0xBA, 0xCF,0xFC, 0xCE,0x3E
-+	data1	0x91,0x80, 0x90,0x42, 0x92,0x04, 0x93,0xC6, 0x96,0x88, 0x97,0x4A, 0x95,0x0C, 0x94,0xCE
-+	data1	0x9F,0x90, 0x9E,0x52, 0x9C,0x14, 0x9D,0xD6, 0x98,0x98, 0x99,0x5A, 0x9B,0x1C, 0x9A,0xDE
-+	data1	0x8D,0xA0, 0x8C,0x62, 0x8E,0x24, 0x8F,0xE6, 0x8A,0xA8, 0x8B,0x6A, 0x89,0x2C, 0x88,0xEE
-+	data1	0x83,0xB0, 0x82,0x72, 0x80,0x34, 0x81,0xF6, 0x84,0xB8, 0x85,0x7A, 0x87,0x3C, 0x86,0xFE
-+	data1	0xA9,0xC0, 0xA8,0x02, 0xAA,0x44, 0xAB,0x86, 0xAE,0xC8, 0xAF,0x0A, 0xAD,0x4C, 0xAC,0x8E
-+	data1	0xA7,0xD0, 0xA6,0x12, 0xA4,0x54, 0xA5,0x96, 0xA0,0xD8, 0xA1,0x1A, 0xA3,0x5C, 0xA2,0x9E
-+	data1	0xB5,0xE0, 0xB4,0x22, 0xB6,0x64, 0xB7,0xA6, 0xB2,0xE8, 0xB3,0x2A, 0xB1,0x6C, 0xB0,0xAE
-+	data1	0xBB,0xF0, 0xBA,0x32, 0xB8,0x74, 0xB9,0xB6, 0xBC,0xF8, 0xBD,0x3A, 0xBF,0x7C, 0xBE,0xBE
-+.size	rem_8bit#,512
-+stringz	"GHASH for IA64, CRYPTOGAMS by "
-+___
-+
-+$code =~ s/mux1(\s+)\S+\@rev/nop.i$1 0x0/gm      if ($big_endian);
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-parisc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-parisc.pl
-new file mode 100644
-index 0000000..1d62545
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-parisc.pl
-@@ -0,0 +1,738 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# April 2010
-+#
-+# The module implements "4-bit" GCM GHASH function and underlying
-+# single multiplication operation in GF(2^128). "4-bit" means that it
-+# uses 256 bytes per-key table [+128 bytes shared table]. On PA-7100LC
-+# it processes one byte in 19.6 cycles, which is more than twice as
-+# fast as code generated by gcc 3.2. PA-RISC 2.0 loop is scheduled for
-+# 8 cycles, but measured performance on PA-8600 system is ~9 cycles per
-+# processed byte. This is ~2.2x faster than 64-bit code generated by
-+# vendor compiler (which used to be very hard to beat:-).
-+#
-+# Special thanks to polarhome.com for providing HP-UX account.
-+
-+$flavour = shift;
-+$output = shift;
-+open STDOUT,">$output";
-+
-+if ($flavour =~ /64/) {
-+	$LEVEL		="2.0W";
-+	$SIZE_T		=8;
-+	$FRAME_MARKER	=80;
-+	$SAVED_RP	=16;
-+	$PUSH		="std";
-+	$PUSHMA		="std,ma";
-+	$POP		="ldd";
-+	$POPMB		="ldd,mb";
-+	$NREGS		=6;
-+} else {
-+	$LEVEL		="1.0";	#"\n\t.ALLOW\t2.0";
-+	$SIZE_T		=4;
-+	$FRAME_MARKER	=48;
-+	$SAVED_RP	=20;
-+	$PUSH		="stw";
-+	$PUSHMA		="stwm";
-+	$POP		="ldw";
-+	$POPMB		="ldwm";
-+	$NREGS		=11;
-+}
-+
-+$FRAME=10*$SIZE_T+$FRAME_MARKER;# NREGS saved regs + frame marker
-+				#                 [+ argument transfer]
-+
-+################# volatile registers
-+$Xi="%r26";	# argument block
-+$Htbl="%r25";
-+$inp="%r24";
-+$len="%r23";
-+$Hhh=$Htbl;	# variables
-+$Hll="%r22";
-+$Zhh="%r21";
-+$Zll="%r20";
-+$cnt="%r19";
-+$rem_4bit="%r28";
-+$rem="%r29";
-+$mask0xf0="%r31";
-+
-+################# preserved registers
-+$Thh="%r1";
-+$Tll="%r2";
-+$nlo="%r3";
-+$nhi="%r4";
-+$byte="%r5";
-+if ($SIZE_T==4) {
-+	$Zhl="%r6";
-+	$Zlh="%r7";
-+	$Hhl="%r8";
-+	$Hlh="%r9";
-+	$Thl="%r10";
-+	$Tlh="%r11";
-+}
-+$rem2="%r6";	# used in PA-RISC 2.0 code
-+
-+$code.=<<___;
-+	.LEVEL	$LEVEL
-+	.SPACE	\$TEXT\$
-+	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
-+
-+	.EXPORT	gcm_gmult_4bit,ENTRY,ARGW0=GR,ARGW1=GR
-+	.ALIGN	64
-+gcm_gmult_4bit
-+	.PROC
-+	.CALLINFO	FRAME=`$FRAME-10*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=$NREGS
-+	.ENTRY
-+	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
-+	$PUSHMA	%r3,$FRAME(%sp)
-+	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
-+	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
-+	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
-+	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
-+	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
-+	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
-+	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
-+___
-+$code.=<<___;
-+	blr	%r0,$rem_4bit
-+	ldi	3,$rem
-+L\$pic_gmult
-+	andcm	$rem_4bit,$rem,$rem_4bit
-+	addl	$inp,$len,$len
-+	ldo	L\$rem_4bit-L\$pic_gmult($rem_4bit),$rem_4bit
-+	ldi	0xf0,$mask0xf0
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	ldi	31,$rem
-+	mtctl	$rem,%cr11
-+	extrd,u,*= $rem,%sar,1,$rem	; executes on PA-RISC 1.0
-+	b	L\$parisc1_gmult
-+	nop
-+___
-+
-+$code.=<<___;
-+	ldb	15($Xi),$nlo
-+	ldo	8($Htbl),$Hll
-+
-+	and	$mask0xf0,$nlo,$nhi
-+	depd,z	$nlo,59,4,$nlo
-+
-+	ldd	$nlo($Hll),$Zll
-+	ldd	$nlo($Hhh),$Zhh
-+
-+	depd,z	$Zll,60,4,$rem
-+	shrpd	$Zhh,$Zll,4,$Zll
-+	extrd,u	$Zhh,59,60,$Zhh
-+	ldb	14($Xi),$nlo
-+
-+	ldd	$nhi($Hll),$Tll
-+	ldd	$nhi($Hhh),$Thh
-+	and	$mask0xf0,$nlo,$nhi
-+	depd,z	$nlo,59,4,$nlo
-+
-+	xor	$Tll,$Zll,$Zll
-+	xor	$Thh,$Zhh,$Zhh
-+	ldd	$rem($rem_4bit),$rem
-+	b	L\$oop_gmult_pa2
-+	ldi	13,$cnt
-+
-+	.ALIGN	8
-+L\$oop_gmult_pa2
-+	xor	$rem,$Zhh,$Zhh		; moved here to work around gas bug
-+	depd,z	$Zll,60,4,$rem
-+
-+	shrpd	$Zhh,$Zll,4,$Zll
-+	extrd,u	$Zhh,59,60,$Zhh
-+	ldd	$nlo($Hll),$Tll
-+	ldd	$nlo($Hhh),$Thh
-+
-+	xor	$Tll,$Zll,$Zll
-+	xor	$Thh,$Zhh,$Zhh
-+	ldd	$rem($rem_4bit),$rem
-+
-+	xor	$rem,$Zhh,$Zhh
-+	depd,z	$Zll,60,4,$rem
-+	ldbx	$cnt($Xi),$nlo
-+
-+	shrpd	$Zhh,$Zll,4,$Zll
-+	extrd,u	$Zhh,59,60,$Zhh
-+	ldd	$nhi($Hll),$Tll
-+	ldd	$nhi($Hhh),$Thh
-+
-+	and	$mask0xf0,$nlo,$nhi
-+	depd,z	$nlo,59,4,$nlo
-+	ldd	$rem($rem_4bit),$rem
-+
-+	xor	$Tll,$Zll,$Zll
-+	addib,uv -1,$cnt,L\$oop_gmult_pa2
-+	xor	$Thh,$Zhh,$Zhh
-+
-+	xor	$rem,$Zhh,$Zhh
-+	depd,z	$Zll,60,4,$rem
-+
-+	shrpd	$Zhh,$Zll,4,$Zll
-+	extrd,u	$Zhh,59,60,$Zhh
-+	ldd	$nlo($Hll),$Tll
-+	ldd	$nlo($Hhh),$Thh
-+
-+	xor	$Tll,$Zll,$Zll
-+	xor	$Thh,$Zhh,$Zhh
-+	ldd	$rem($rem_4bit),$rem
-+
-+	xor	$rem,$Zhh,$Zhh
-+	depd,z	$Zll,60,4,$rem
-+
-+	shrpd	$Zhh,$Zll,4,$Zll
-+	extrd,u	$Zhh,59,60,$Zhh
-+	ldd	$nhi($Hll),$Tll
-+	ldd	$nhi($Hhh),$Thh
-+
-+	xor	$Tll,$Zll,$Zll
-+	xor	$Thh,$Zhh,$Zhh
-+	ldd	$rem($rem_4bit),$rem
-+
-+	xor	$rem,$Zhh,$Zhh
-+	std	$Zll,8($Xi)
-+	std	$Zhh,0($Xi)
-+___
-+
-+$code.=<<___ if ($SIZE_T==4);
-+	b	L\$done_gmult
-+	nop
-+
-+L\$parisc1_gmult
-+	ldb	15($Xi),$nlo
-+	ldo	12($Htbl),$Hll
-+	ldo	8($Htbl),$Hlh
-+	ldo	4($Htbl),$Hhl
-+
-+	and	$mask0xf0,$nlo,$nhi
-+	zdep	$nlo,27,4,$nlo
-+
-+	ldwx	$nlo($Hll),$Zll
-+	ldwx	$nlo($Hlh),$Zlh
-+	ldwx	$nlo($Hhl),$Zhl
-+	ldwx	$nlo($Hhh),$Zhh
-+	zdep	$Zll,28,4,$rem
-+	ldb	14($Xi),$nlo
-+	ldwx	$rem($rem_4bit),$rem
-+	shrpw	$Zlh,$Zll,4,$Zll
-+	ldwx	$nhi($Hll),$Tll
-+	shrpw	$Zhl,$Zlh,4,$Zlh
-+	ldwx	$nhi($Hlh),$Tlh
-+	shrpw	$Zhh,$Zhl,4,$Zhl
-+	ldwx	$nhi($Hhl),$Thl
-+	extru	$Zhh,27,28,$Zhh
-+	ldwx	$nhi($Hhh),$Thh
-+	xor	$rem,$Zhh,$Zhh
-+	and	$mask0xf0,$nlo,$nhi
-+	zdep	$nlo,27,4,$nlo
-+
-+	xor	$Tll,$Zll,$Zll
-+	ldwx	$nlo($Hll),$Tll
-+	xor	$Tlh,$Zlh,$Zlh
-+	ldwx	$nlo($Hlh),$Tlh
-+	xor	$Thl,$Zhl,$Zhl
-+	b	L\$oop_gmult_pa1
-+	ldi	13,$cnt
-+
-+	.ALIGN	8
-+L\$oop_gmult_pa1
-+	zdep	$Zll,28,4,$rem
-+	ldwx	$nlo($Hhl),$Thl
-+	xor	$Thh,$Zhh,$Zhh
-+	ldwx	$rem($rem_4bit),$rem
-+	shrpw	$Zlh,$Zll,4,$Zll
-+	ldwx	$nlo($Hhh),$Thh
-+	shrpw	$Zhl,$Zlh,4,$Zlh
-+	ldbx	$cnt($Xi),$nlo
-+	xor	$Tll,$Zll,$Zll
-+	ldwx	$nhi($Hll),$Tll
-+	shrpw	$Zhh,$Zhl,4,$Zhl
-+	xor	$Tlh,$Zlh,$Zlh
-+	ldwx	$nhi($Hlh),$Tlh
-+	extru	$Zhh,27,28,$Zhh
-+	xor	$Thl,$Zhl,$Zhl
-+	ldwx	$nhi($Hhl),$Thl
-+	xor	$rem,$Zhh,$Zhh
-+	zdep	$Zll,28,4,$rem
-+	xor	$Thh,$Zhh,$Zhh
-+	ldwx	$nhi($Hhh),$Thh
-+	shrpw	$Zlh,$Zll,4,$Zll
-+	ldwx	$rem($rem_4bit),$rem
-+	shrpw	$Zhl,$Zlh,4,$Zlh
-+	shrpw	$Zhh,$Zhl,4,$Zhl
-+	and	$mask0xf0,$nlo,$nhi
-+	extru	$Zhh,27,28,$Zhh
-+	zdep	$nlo,27,4,$nlo
-+	xor	$Tll,$Zll,$Zll
-+	ldwx	$nlo($Hll),$Tll
-+	xor	$Tlh,$Zlh,$Zlh
-+	ldwx	$nlo($Hlh),$Tlh
-+	xor	$rem,$Zhh,$Zhh
-+	addib,uv -1,$cnt,L\$oop_gmult_pa1
-+	xor	$Thl,$Zhl,$Zhl
-+
-+	zdep	$Zll,28,4,$rem
-+	ldwx	$nlo($Hhl),$Thl
-+	xor	$Thh,$Zhh,$Zhh
-+	ldwx	$rem($rem_4bit),$rem
-+	shrpw	$Zlh,$Zll,4,$Zll
-+	ldwx	$nlo($Hhh),$Thh
-+	shrpw	$Zhl,$Zlh,4,$Zlh
-+	xor	$Tll,$Zll,$Zll
-+	ldwx	$nhi($Hll),$Tll
-+	shrpw	$Zhh,$Zhl,4,$Zhl
-+	xor	$Tlh,$Zlh,$Zlh
-+	ldwx	$nhi($Hlh),$Tlh
-+	extru	$Zhh,27,28,$Zhh
-+	xor	$rem,$Zhh,$Zhh
-+	xor	$Thl,$Zhl,$Zhl
-+	ldwx	$nhi($Hhl),$Thl
-+	xor	$Thh,$Zhh,$Zhh
-+	ldwx	$nhi($Hhh),$Thh
-+	zdep	$Zll,28,4,$rem
-+	ldwx	$rem($rem_4bit),$rem
-+	shrpw	$Zlh,$Zll,4,$Zll
-+	shrpw	$Zhl,$Zlh,4,$Zlh
-+	shrpw	$Zhh,$Zhl,4,$Zhl
-+	extru	$Zhh,27,28,$Zhh
-+	xor	$Tll,$Zll,$Zll
-+	xor	$Tlh,$Zlh,$Zlh
-+	xor	$rem,$Zhh,$Zhh
-+	stw	$Zll,12($Xi)
-+	xor	$Thl,$Zhl,$Zhl
-+	stw	$Zlh,8($Xi)
-+	xor	$Thh,$Zhh,$Zhh
-+	stw	$Zhl,4($Xi)
-+	stw	$Zhh,0($Xi)
-+___
-+$code.=<<___;
-+L\$done_gmult
-+	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2		; standard epilogue
-+	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
-+	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
-+	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
-+	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
-+	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
-+	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
-+	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
-+___
-+$code.=<<___;
-+	bv	(%r2)
-+	.EXIT
-+	$POPMB	-$FRAME(%sp),%r3
-+	.PROCEND
-+
-+	.EXPORT	gcm_ghash_4bit,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
-+	.ALIGN	64
-+gcm_ghash_4bit
-+	.PROC
-+	.CALLINFO	FRAME=`$FRAME-10*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=11
-+	.ENTRY
-+	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
-+	$PUSHMA	%r3,$FRAME(%sp)
-+	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
-+	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
-+	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
-+	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
-+	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
-+	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
-+	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
-+___
-+$code.=<<___;
-+	blr	%r0,$rem_4bit
-+	ldi	3,$rem
-+L\$pic_ghash
-+	andcm	$rem_4bit,$rem,$rem_4bit
-+	addl	$inp,$len,$len
-+	ldo	L\$rem_4bit-L\$pic_ghash($rem_4bit),$rem_4bit
-+	ldi	0xf0,$mask0xf0
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	ldi	31,$rem
-+	mtctl	$rem,%cr11
-+	extrd,u,*= $rem,%sar,1,$rem	; executes on PA-RISC 1.0
-+	b	L\$parisc1_ghash
-+	nop
-+___
-+
-+$code.=<<___;
-+	ldb	15($Xi),$nlo
-+	ldo	8($Htbl),$Hll
-+
-+L\$outer_ghash_pa2
-+	ldb	15($inp),$nhi
-+	xor	$nhi,$nlo,$nlo
-+	and	$mask0xf0,$nlo,$nhi
-+	depd,z	$nlo,59,4,$nlo
-+
-+	ldd	$nlo($Hll),$Zll
-+	ldd	$nlo($Hhh),$Zhh
-+
-+	depd,z	$Zll,60,4,$rem
-+	shrpd	$Zhh,$Zll,4,$Zll
-+	extrd,u	$Zhh,59,60,$Zhh
-+	ldb	14($Xi),$nlo
-+	ldb	14($inp),$byte
-+
-+	ldd	$nhi($Hll),$Tll
-+	ldd	$nhi($Hhh),$Thh
-+	xor	$byte,$nlo,$nlo
-+	and	$mask0xf0,$nlo,$nhi
-+	depd,z	$nlo,59,4,$nlo
-+
-+	xor	$Tll,$Zll,$Zll
-+	xor	$Thh,$Zhh,$Zhh
-+	ldd	$rem($rem_4bit),$rem
-+	b	L\$oop_ghash_pa2
-+	ldi	13,$cnt
-+
-+	.ALIGN	8
-+L\$oop_ghash_pa2
-+	xor	$rem,$Zhh,$Zhh		; moved here to work around gas bug
-+	depd,z	$Zll,60,4,$rem2
-+
-+	shrpd	$Zhh,$Zll,4,$Zll
-+	extrd,u	$Zhh,59,60,$Zhh
-+	ldd	$nlo($Hll),$Tll
-+	ldd	$nlo($Hhh),$Thh
-+
-+	xor	$Tll,$Zll,$Zll
-+	xor	$Thh,$Zhh,$Zhh
-+	ldbx	$cnt($Xi),$nlo
-+	ldbx	$cnt($inp),$byte
-+
-+	depd,z	$Zll,60,4,$rem
-+	shrpd	$Zhh,$Zll,4,$Zll
-+	ldd	$rem2($rem_4bit),$rem2
-+
-+	xor	$rem2,$Zhh,$Zhh
-+	xor	$byte,$nlo,$nlo
-+	ldd	$nhi($Hll),$Tll
-+	ldd	$nhi($Hhh),$Thh
-+
-+	and	$mask0xf0,$nlo,$nhi
-+	depd,z	$nlo,59,4,$nlo
-+
-+	extrd,u	$Zhh,59,60,$Zhh
-+	xor	$Tll,$Zll,$Zll
-+
-+	ldd	$rem($rem_4bit),$rem
-+	addib,uv -1,$cnt,L\$oop_ghash_pa2
-+	xor	$Thh,$Zhh,$Zhh
-+
-+	xor	$rem,$Zhh,$Zhh
-+	depd,z	$Zll,60,4,$rem2
-+
-+	shrpd	$Zhh,$Zll,4,$Zll
-+	extrd,u	$Zhh,59,60,$Zhh
-+	ldd	$nlo($Hll),$Tll
-+	ldd	$nlo($Hhh),$Thh
-+
-+	xor	$Tll,$Zll,$Zll
-+	xor	$Thh,$Zhh,$Zhh
-+
-+	depd,z	$Zll,60,4,$rem
-+	shrpd	$Zhh,$Zll,4,$Zll
-+	ldd	$rem2($rem_4bit),$rem2
-+
-+	xor	$rem2,$Zhh,$Zhh
-+	ldd	$nhi($Hll),$Tll
-+	ldd	$nhi($Hhh),$Thh
-+
-+	extrd,u	$Zhh,59,60,$Zhh
-+	xor	$Tll,$Zll,$Zll
-+	xor	$Thh,$Zhh,$Zhh
-+	ldd	$rem($rem_4bit),$rem
-+
-+	xor	$rem,$Zhh,$Zhh
-+	std	$Zll,8($Xi)
-+	ldo	16($inp),$inp
-+	std	$Zhh,0($Xi)
-+	cmpb,*<> $inp,$len,L\$outer_ghash_pa2
-+	copy	$Zll,$nlo
-+___
-+
-+$code.=<<___ if ($SIZE_T==4);
-+	b	L\$done_ghash
-+	nop
-+
-+L\$parisc1_ghash
-+	ldb	15($Xi),$nlo
-+	ldo	12($Htbl),$Hll
-+	ldo	8($Htbl),$Hlh
-+	ldo	4($Htbl),$Hhl
-+
-+L\$outer_ghash_pa1
-+	ldb	15($inp),$byte
-+	xor	$byte,$nlo,$nlo
-+	and	$mask0xf0,$nlo,$nhi
-+	zdep	$nlo,27,4,$nlo
-+
-+	ldwx	$nlo($Hll),$Zll
-+	ldwx	$nlo($Hlh),$Zlh
-+	ldwx	$nlo($Hhl),$Zhl
-+	ldwx	$nlo($Hhh),$Zhh
-+	zdep	$Zll,28,4,$rem
-+	ldb	14($Xi),$nlo
-+	ldb	14($inp),$byte
-+	ldwx	$rem($rem_4bit),$rem
-+	shrpw	$Zlh,$Zll,4,$Zll
-+	ldwx	$nhi($Hll),$Tll
-+	shrpw	$Zhl,$Zlh,4,$Zlh
-+	ldwx	$nhi($Hlh),$Tlh
-+	shrpw	$Zhh,$Zhl,4,$Zhl
-+	ldwx	$nhi($Hhl),$Thl
-+	extru	$Zhh,27,28,$Zhh
-+	ldwx	$nhi($Hhh),$Thh
-+	xor	$byte,$nlo,$nlo
-+	xor	$rem,$Zhh,$Zhh
-+	and	$mask0xf0,$nlo,$nhi
-+	zdep	$nlo,27,4,$nlo
-+
-+	xor	$Tll,$Zll,$Zll
-+	ldwx	$nlo($Hll),$Tll
-+	xor	$Tlh,$Zlh,$Zlh
-+	ldwx	$nlo($Hlh),$Tlh
-+	xor	$Thl,$Zhl,$Zhl
-+	b	L\$oop_ghash_pa1
-+	ldi	13,$cnt
-+
-+	.ALIGN	8
-+L\$oop_ghash_pa1
-+	zdep	$Zll,28,4,$rem
-+	ldwx	$nlo($Hhl),$Thl
-+	xor	$Thh,$Zhh,$Zhh
-+	ldwx	$rem($rem_4bit),$rem
-+	shrpw	$Zlh,$Zll,4,$Zll
-+	ldwx	$nlo($Hhh),$Thh
-+	shrpw	$Zhl,$Zlh,4,$Zlh
-+	ldbx	$cnt($Xi),$nlo
-+	xor	$Tll,$Zll,$Zll
-+	ldwx	$nhi($Hll),$Tll
-+	shrpw	$Zhh,$Zhl,4,$Zhl
-+	ldbx	$cnt($inp),$byte
-+	xor	$Tlh,$Zlh,$Zlh
-+	ldwx	$nhi($Hlh),$Tlh
-+	extru	$Zhh,27,28,$Zhh
-+	xor	$Thl,$Zhl,$Zhl
-+	ldwx	$nhi($Hhl),$Thl
-+	xor	$rem,$Zhh,$Zhh
-+	zdep	$Zll,28,4,$rem
-+	xor	$Thh,$Zhh,$Zhh
-+	ldwx	$nhi($Hhh),$Thh
-+	shrpw	$Zlh,$Zll,4,$Zll
-+	ldwx	$rem($rem_4bit),$rem
-+	shrpw	$Zhl,$Zlh,4,$Zlh
-+	xor	$byte,$nlo,$nlo
-+	shrpw	$Zhh,$Zhl,4,$Zhl
-+	and	$mask0xf0,$nlo,$nhi
-+	extru	$Zhh,27,28,$Zhh
-+	zdep	$nlo,27,4,$nlo
-+	xor	$Tll,$Zll,$Zll
-+	ldwx	$nlo($Hll),$Tll
-+	xor	$Tlh,$Zlh,$Zlh
-+	ldwx	$nlo($Hlh),$Tlh
-+	xor	$rem,$Zhh,$Zhh
-+	addib,uv -1,$cnt,L\$oop_ghash_pa1
-+	xor	$Thl,$Zhl,$Zhl
-+
-+	zdep	$Zll,28,4,$rem
-+	ldwx	$nlo($Hhl),$Thl
-+	xor	$Thh,$Zhh,$Zhh
-+	ldwx	$rem($rem_4bit),$rem
-+	shrpw	$Zlh,$Zll,4,$Zll
-+	ldwx	$nlo($Hhh),$Thh
-+	shrpw	$Zhl,$Zlh,4,$Zlh
-+	xor	$Tll,$Zll,$Zll
-+	ldwx	$nhi($Hll),$Tll
-+	shrpw	$Zhh,$Zhl,4,$Zhl
-+	xor	$Tlh,$Zlh,$Zlh
-+	ldwx	$nhi($Hlh),$Tlh
-+	extru	$Zhh,27,28,$Zhh
-+	xor	$rem,$Zhh,$Zhh
-+	xor	$Thl,$Zhl,$Zhl
-+	ldwx	$nhi($Hhl),$Thl
-+	xor	$Thh,$Zhh,$Zhh
-+	ldwx	$nhi($Hhh),$Thh
-+	zdep	$Zll,28,4,$rem
-+	ldwx	$rem($rem_4bit),$rem
-+	shrpw	$Zlh,$Zll,4,$Zll
-+	shrpw	$Zhl,$Zlh,4,$Zlh
-+	shrpw	$Zhh,$Zhl,4,$Zhl
-+	extru	$Zhh,27,28,$Zhh
-+	xor	$Tll,$Zll,$Zll
-+	xor	$Tlh,$Zlh,$Zlh
-+	xor	$rem,$Zhh,$Zhh
-+	stw	$Zll,12($Xi)
-+	xor	$Thl,$Zhl,$Zhl
-+	stw	$Zlh,8($Xi)
-+	xor	$Thh,$Zhh,$Zhh
-+	stw	$Zhl,4($Xi)
-+	ldo	16($inp),$inp
-+	stw	$Zhh,0($Xi)
-+	comb,<>	$inp,$len,L\$outer_ghash_pa1
-+	copy	$Zll,$nlo
-+___
-+$code.=<<___;
-+L\$done_ghash
-+	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2		; standard epilogue
-+	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
-+	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
-+	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
-+___
-+$code.=<<___ if ($SIZE_T==4);
-+	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
-+	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
-+	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
-+	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
-+	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
-+___
-+$code.=<<___;
-+	bv	(%r2)
-+	.EXIT
-+	$POPMB	-$FRAME(%sp),%r3
-+	.PROCEND
-+
-+	.ALIGN	64
-+L\$rem_4bit
-+	.WORD	`0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`,0
-+	.WORD	`0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`,0
-+	.WORD	`0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`,0
-+	.WORD	`0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`,0
-+	.STRINGZ "GHASH for PA-RISC, GRYPTOGAMS by "
-+	.ALIGN	64
-+___
-+
-+# Explicitly encode PA-RISC 2.0 instructions used in this module, so
-+# that it can be compiled with .LEVEL 1.0. It should be noted that I
-+# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0
-+# directive...
-+
-+my $ldd = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "ldd$mod\t$args";
-+
-+    if ($args =~ /%r([0-9]+)\(%r([0-9]+)\),%r([0-9]+)/)		# format 4
-+    {	my $opcode=(0x03<<26)|($2<<21)|($1<<16)|(3<<6)|$3;
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    elsif ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/)	# format 5
-+    {	my $opcode=(0x03<<26)|($2<<21)|(1<<12)|(3<<6)|$3;
-+	$opcode|=(($1&0xF)<<17)|(($1&0x10)<<12);		# encode offset
-+	$opcode|=(1<<5)  if ($mod =~ /^,m/);
-+	$opcode|=(1<<13) if ($mod =~ /^,mb/);
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $std = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "std$mod\t$args";
-+
-+    if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/) # format 3 suffices
-+    {	my $opcode=(0x1c<<26)|($3<<21)|($1<<16)|(($2&0x1FF8)<<1)|(($2>>13)&1);
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $extrd = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "extrd$mod\t$args";
-+
-+    # I only have ",u" completer, it's implicitly encoded...
-+    if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/)	# format 15
-+    {	my $opcode=(0x36<<26)|($1<<21)|($4<<16);
-+	my $len=32-$3;
-+	$opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5);		# encode pos
-+	$opcode |= (($len&0x20)<<7)|($len&0x1f);		# encode len
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/)	# format 12
-+    {	my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9);
-+	my $len=32-$2;
-+	$opcode |= (($len&0x20)<<3)|($len&0x1f);		# encode len
-+	$opcode |= (1<<13) if ($mod =~ /,\**=/);
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $shrpd = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "shrpd$mod\t$args";
-+
-+    if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/)	# format 14
-+    {	my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4;
-+	my $cpos=63-$3;
-+	$opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5);		# encode sa
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    elsif ($args =~ /%r([0-9]+),%r([0-9]+),%sar,%r([0-9]+)/)	# format 11
-+    {	sprintf "\t.WORD\t0x%08x\t; %s",
-+		(0x34<<26)|($2<<21)|($1<<16)|(1<<9)|$3,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $depd = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "depd$mod\t$args";
-+
-+    # I only have ",z" completer, it's impicitly encoded...
-+    if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/)	# format 16
-+    {	my $opcode=(0x3c<<26)|($4<<21)|($1<<16);
-+    	my $cpos=63-$2;
-+	my $len=32-$3;
-+	$opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5);		# encode pos
-+	$opcode |= (($len&0x20)<<7)|($len&0x1f);		# encode len
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+sub assemble {
-+  my ($mnemonic,$mod,$args)=@_;
-+  my $opcode = eval("\$$mnemonic");
-+
-+    ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args";
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+	if ($SIZE_T==4) {
-+		s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e;
-+		s/cmpb,\*/comb,/;
-+		s/,\*/,/;
-+	}
-+	s/\bbv\b/bve/	if ($SIZE_T==8);
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-s390x.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-s390x.pl
-new file mode 100644
-index 0000000..65ffaf9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-s390x.pl
-@@ -0,0 +1,267 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# September 2010.
-+#
-+# The module implements "4-bit" GCM GHASH function and underlying
-+# single multiplication operation in GF(2^128). "4-bit" means that it
-+# uses 256 bytes per-key table [+128 bytes shared table]. Performance
-+# was measured to be ~18 cycles per processed byte on z10, which is
-+# almost 40% better than gcc-generated code. It should be noted that
-+# 18 cycles is worse result than expected: loop is scheduled for 12
-+# and the result should be close to 12. In the lack of instruction-
-+# level profiling data it's impossible to tell why...
-+
-+# November 2010.
-+#
-+# Adapt for -m31 build. If kernel supports what's called "highgprs"
-+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
-+# instructions and achieve "64-bit" performance even in 31-bit legacy
-+# application context. The feature is not specific to any particular
-+# processor, as long as it's "z-CPU". Latter implies that the code
-+# remains z/Architecture specific. On z990 it was measured to perform
-+# 2.8x better than 32-bit code generated by gcc 4.3.
-+
-+# March 2011.
-+#
-+# Support for hardware KIMD-GHASH is verified to produce correct
-+# result and therefore is engaged. On z196 it was measured to process
-+# 8KB buffer ~7 faster than software implementation. It's not as
-+# impressive for smaller buffer sizes and for smallest 16-bytes buffer
-+# it's actually almost 2 times slower. Which is the reason why
-+# KIMD-GHASH is not used in gcm_gmult_4bit.
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /3[12]/) {
-+	$SIZE_T=4;
-+	$g="";
-+} else {
-+	$SIZE_T=8;
-+	$g="g";
-+}
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+$softonly=0;
-+
-+$Zhi="%r0";
-+$Zlo="%r1";
-+
-+$Xi="%r2";	# argument block
-+$Htbl="%r3";
-+$inp="%r4";
-+$len="%r5";
-+
-+$rem0="%r6";	# variables
-+$rem1="%r7";
-+$nlo="%r8";
-+$nhi="%r9";
-+$xi="%r10";
-+$cnt="%r11";
-+$tmp="%r12";
-+$x78="%r13";
-+$rem_4bit="%r14";
-+
-+$sp="%r15";
-+
-+$code.=<<___;
-+.text
-+
-+.globl	gcm_gmult_4bit
-+.align	32
-+gcm_gmult_4bit:
-+___
-+$code.=<<___ if(!$softonly && 0);	# hardware is slow for single block...
-+	larl	%r1,OPENSSL_s390xcap_P
-+	lg	%r0,0(%r1)
-+	tmhl	%r0,0x4000	# check for message-security-assist
-+	jz	.Lsoft_gmult
-+	lghi	%r0,0
-+	lg	%r1,24(%r1)	# load second word of kimd capabilities vector
-+	tmhh	%r1,0x4000	# check for function 65
-+	jz	.Lsoft_gmult
-+	stg	%r0,16($sp)	# arrange 16 bytes of zero input
-+	stg	%r0,24($sp)
-+	lghi	%r0,65		# function 65
-+	la	%r1,0($Xi)	# H lies right after Xi in gcm128_context
-+	la	$inp,16($sp)
-+	lghi	$len,16
-+	.long	0xb93e0004	# kimd %r0,$inp
-+	brc	1,.-4		# pay attention to "partial completion"
-+	br	%r14
-+.align	32
-+.Lsoft_gmult:
-+___
-+$code.=<<___;
-+	stm${g}	%r6,%r14,6*$SIZE_T($sp)
-+
-+	aghi	$Xi,-1
-+	lghi	$len,1
-+	lghi	$x78,`0xf<<3`
-+	larl	$rem_4bit,rem_4bit
-+
-+	lg	$Zlo,8+1($Xi)		# Xi
-+	j	.Lgmult_shortcut
-+.type	gcm_gmult_4bit,\@function
-+.size	gcm_gmult_4bit,(.-gcm_gmult_4bit)
-+
-+.globl	gcm_ghash_4bit
-+.align	32
-+gcm_ghash_4bit:
-+___
-+$code.=<<___ if(!$softonly);
-+	larl	%r1,OPENSSL_s390xcap_P
-+	lg	%r0,0(%r1)
-+	tmhl	%r0,0x4000	# check for message-security-assist
-+	jz	.Lsoft_ghash
-+	lghi	%r0,0
-+	la	%r1,16($sp)
-+	.long	0xb93e0004	# kimd %r0,%r4
-+	lg	%r1,24($sp)
-+	tmhh	%r1,0x4000	# check for function 65
-+	jz	.Lsoft_ghash
-+	lghi	%r0,65		# function 65
-+	la	%r1,0($Xi)	# H lies right after Xi in gcm128_context
-+	.long	0xb93e0004	# kimd %r0,$inp
-+	brc	1,.-4		# pay attention to "partial completion"
-+	br	%r14
-+.align	32
-+.Lsoft_ghash:
-+___
-+$code.=<<___ if ($flavour =~ /3[12]/);
-+	llgfr	$len,$len
-+___
-+$code.=<<___;
-+	stm${g}	%r6,%r14,6*$SIZE_T($sp)
-+
-+	aghi	$Xi,-1
-+	srlg	$len,$len,4
-+	lghi	$x78,`0xf<<3`
-+	larl	$rem_4bit,rem_4bit
-+
-+	lg	$Zlo,8+1($Xi)		# Xi
-+	lg	$Zhi,0+1($Xi)
-+	lghi	$tmp,0
-+.Louter:
-+	xg	$Zhi,0($inp)		# Xi ^= inp 
-+	xg	$Zlo,8($inp)
-+	xgr	$Zhi,$tmp
-+	stg	$Zlo,8+1($Xi)
-+	stg	$Zhi,0+1($Xi)
-+
-+.Lgmult_shortcut:
-+	lghi	$tmp,0xf0
-+	sllg	$nlo,$Zlo,4
-+	srlg	$xi,$Zlo,8		# extract second byte
-+	ngr	$nlo,$tmp
-+	lgr	$nhi,$Zlo
-+	lghi	$cnt,14
-+	ngr	$nhi,$tmp
-+
-+	lg	$Zlo,8($nlo,$Htbl)
-+	lg	$Zhi,0($nlo,$Htbl)
-+
-+	sllg	$nlo,$xi,4
-+	sllg	$rem0,$Zlo,3
-+	ngr	$nlo,$tmp
-+	ngr	$rem0,$x78
-+	ngr	$xi,$tmp
-+
-+	sllg	$tmp,$Zhi,60
-+	srlg	$Zlo,$Zlo,4
-+	srlg	$Zhi,$Zhi,4
-+	xg	$Zlo,8($nhi,$Htbl)
-+	xg	$Zhi,0($nhi,$Htbl)
-+	lgr	$nhi,$xi
-+	sllg	$rem1,$Zlo,3
-+	xgr	$Zlo,$tmp
-+	ngr	$rem1,$x78
-+	sllg	$tmp,$Zhi,60
-+	j	.Lghash_inner
-+.align	16
-+.Lghash_inner:
-+	srlg	$Zlo,$Zlo,4
-+	srlg	$Zhi,$Zhi,4
-+	xg	$Zlo,8($nlo,$Htbl)
-+	llgc	$xi,0($cnt,$Xi)
-+	xg	$Zhi,0($nlo,$Htbl)
-+	sllg	$nlo,$xi,4
-+	xg	$Zhi,0($rem0,$rem_4bit)
-+	nill	$nlo,0xf0
-+	sllg	$rem0,$Zlo,3
-+	xgr	$Zlo,$tmp
-+	ngr	$rem0,$x78
-+	nill	$xi,0xf0
-+
-+	sllg	$tmp,$Zhi,60
-+	srlg	$Zlo,$Zlo,4
-+	srlg	$Zhi,$Zhi,4
-+	xg	$Zlo,8($nhi,$Htbl)
-+	xg	$Zhi,0($nhi,$Htbl)
-+	lgr	$nhi,$xi
-+	xg	$Zhi,0($rem1,$rem_4bit)
-+	sllg	$rem1,$Zlo,3
-+	xgr	$Zlo,$tmp
-+	ngr	$rem1,$x78
-+	sllg	$tmp,$Zhi,60
-+	brct	$cnt,.Lghash_inner
-+
-+	srlg	$Zlo,$Zlo,4
-+	srlg	$Zhi,$Zhi,4
-+	xg	$Zlo,8($nlo,$Htbl)
-+	xg	$Zhi,0($nlo,$Htbl)
-+	sllg	$xi,$Zlo,3
-+	xg	$Zhi,0($rem0,$rem_4bit)
-+	xgr	$Zlo,$tmp
-+	ngr	$xi,$x78
-+
-+	sllg	$tmp,$Zhi,60
-+	srlg	$Zlo,$Zlo,4
-+	srlg	$Zhi,$Zhi,4
-+	xg	$Zlo,8($nhi,$Htbl)
-+	xg	$Zhi,0($nhi,$Htbl)
-+	xgr	$Zlo,$tmp
-+	xg	$Zhi,0($rem1,$rem_4bit)
-+
-+	lg	$tmp,0($xi,$rem_4bit)
-+	la	$inp,16($inp)
-+	sllg	$tmp,$tmp,4		# correct last rem_4bit[rem]
-+	brctg	$len,.Louter
-+
-+	xgr	$Zhi,$tmp
-+	stg	$Zlo,8+1($Xi)
-+	stg	$Zhi,0+1($Xi)
-+	lm${g}	%r6,%r14,6*$SIZE_T($sp)
-+	br	%r14
-+.type	gcm_ghash_4bit,\@function
-+.size	gcm_ghash_4bit,(.-gcm_ghash_4bit)
-+
-+.align	64
-+rem_4bit:
-+	.long	`0x0000<<12`,0,`0x1C20<<12`,0,`0x3840<<12`,0,`0x2460<<12`,0
-+	.long	`0x7080<<12`,0,`0x6CA0<<12`,0,`0x48C0<<12`,0,`0x54E0<<12`,0
-+	.long	`0xE100<<12`,0,`0xFD20<<12`,0,`0xD940<<12`,0,`0xC560<<12`,0
-+	.long	`0x9180<<12`,0,`0x8DA0<<12`,0,`0xA9C0<<12`,0,`0xB5E0<<12`,0
-+.type	rem_4bit,\@object
-+.size	rem_4bit,(.-rem_4bit)
-+.string	"GHASH for s390x, CRYPTOGAMS by "
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-sparcv9.pl
-new file mode 100644
-index 0000000..c4eb3b1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-sparcv9.pl
-@@ -0,0 +1,581 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# March 2010
-+#
-+# The module implements "4-bit" GCM GHASH function and underlying
-+# single multiplication operation in GF(2^128). "4-bit" means that it
-+# uses 256 bytes per-key table [+128 bytes shared table]. Performance
-+# results are for streamed GHASH subroutine on UltraSPARC pre-Tx CPU
-+# and are expressed in cycles per processed byte, less is better:
-+#
-+#		gcc 3.3.x	cc 5.2		this assembler
-+#
-+# 32-bit build	81.4		43.3		12.6	(+546%/+244%)
-+# 64-bit build	20.2		21.2		12.6	(+60%/+68%)
-+#
-+# Here is data collected on UltraSPARC T1 system running Linux:
-+#
-+#		gcc 4.4.1			this assembler
-+#
-+# 32-bit build	566				50	(+1000%)
-+# 64-bit build	56				50	(+12%)
-+#
-+# I don't quite understand why difference between 32-bit and 64-bit
-+# compiler-generated code is so big. Compilers *were* instructed to
-+# generate code for UltraSPARC and should have used 64-bit registers
-+# for Z vector (see C code) even in 32-bit build... Oh well, it only
-+# means more impressive improvement coefficients for this assembler
-+# module;-) Loops are aggressively modulo-scheduled in respect to
-+# references to input data and Z.hi updates to achieve 12 cycles
-+# timing. To anchor to something else, sha1-sparcv9.pl spends 11.6
-+# cycles to process one byte on UltraSPARC pre-Tx CPU and ~24 on T1.
-+#
-+# October 2012
-+#
-+# Add VIS3 lookup-table-free implementation using polynomial
-+# multiplication xmulx[hi] and extended addition addxc[cc]
-+# instructions. 4.52/7.63x improvement on T3/T4 or in absolute
-+# terms 7.90/2.14 cycles per byte. On T4 multi-process benchmark
-+# saturates at ~15.5x single-process result on 8-core processor,
-+# or ~20.5GBps per 2.85GHz socket.
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+$frame="STACK_FRAME";
-+$bias="STACK_BIAS";
-+
-+$Zhi="%o0";	# 64-bit values
-+$Zlo="%o1";
-+$Thi="%o2";
-+$Tlo="%o3";
-+$rem="%o4";
-+$tmp="%o5";
-+
-+$nhi="%l0";	# small values and pointers
-+$nlo="%l1";
-+$xi0="%l2";
-+$xi1="%l3";
-+$rem_4bit="%l4";
-+$remi="%l5";
-+$Htblo="%l6";
-+$cnt="%l7";
-+
-+$Xi="%i0";	# input argument block
-+$Htbl="%i1";
-+$inp="%i2";
-+$len="%i3";
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#ifdef  __arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+#endif
-+
-+.section	".text",#alloc,#execinstr
-+
-+.align	64
-+rem_4bit:
-+	.long	`0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`,0
-+	.long	`0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`,0
-+	.long	`0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`,0
-+	.long	`0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`,0
-+.type	rem_4bit,#object
-+.size	rem_4bit,(.-rem_4bit)
-+
-+.globl	gcm_ghash_4bit
-+.align	32
-+gcm_ghash_4bit:
-+	save	%sp,-$frame,%sp
-+	ldub	[$inp+15],$nlo
-+	ldub	[$Xi+15],$xi0
-+	ldub	[$Xi+14],$xi1
-+	add	$len,$inp,$len
-+	add	$Htbl,8,$Htblo
-+
-+1:	call	.+8
-+	add	%o7,rem_4bit-1b,$rem_4bit
-+
-+.Louter:
-+	xor	$xi0,$nlo,$nlo
-+	and	$nlo,0xf0,$nhi
-+	and	$nlo,0x0f,$nlo
-+	sll	$nlo,4,$nlo
-+	ldx	[$Htblo+$nlo],$Zlo
-+	ldx	[$Htbl+$nlo],$Zhi
-+
-+	ldub	[$inp+14],$nlo
-+
-+	ldx	[$Htblo+$nhi],$Tlo
-+	and	$Zlo,0xf,$remi
-+	ldx	[$Htbl+$nhi],$Thi
-+	sll	$remi,3,$remi
-+	ldx	[$rem_4bit+$remi],$rem
-+	srlx	$Zlo,4,$Zlo
-+	mov	13,$cnt
-+	sllx	$Zhi,60,$tmp
-+	xor	$Tlo,$Zlo,$Zlo
-+	srlx	$Zhi,4,$Zhi
-+	xor	$Zlo,$tmp,$Zlo
-+
-+	xor	$xi1,$nlo,$nlo
-+	and	$Zlo,0xf,$remi
-+	and	$nlo,0xf0,$nhi
-+	and	$nlo,0x0f,$nlo
-+	ba	.Lghash_inner
-+	sll	$nlo,4,$nlo
-+.align	32
-+.Lghash_inner:
-+	ldx	[$Htblo+$nlo],$Tlo
-+	sll	$remi,3,$remi
-+	xor	$Thi,$Zhi,$Zhi
-+	ldx	[$Htbl+$nlo],$Thi
-+	srlx	$Zlo,4,$Zlo
-+	xor	$rem,$Zhi,$Zhi
-+	ldx	[$rem_4bit+$remi],$rem
-+	sllx	$Zhi,60,$tmp
-+	xor	$Tlo,$Zlo,$Zlo
-+	ldub	[$inp+$cnt],$nlo
-+	srlx	$Zhi,4,$Zhi
-+	xor	$Zlo,$tmp,$Zlo
-+	ldub	[$Xi+$cnt],$xi1
-+	xor	$Thi,$Zhi,$Zhi
-+	and	$Zlo,0xf,$remi
-+
-+	ldx	[$Htblo+$nhi],$Tlo
-+	sll	$remi,3,$remi
-+	xor	$rem,$Zhi,$Zhi
-+	ldx	[$Htbl+$nhi],$Thi
-+	srlx	$Zlo,4,$Zlo
-+	ldx	[$rem_4bit+$remi],$rem
-+	sllx	$Zhi,60,$tmp
-+	xor	$xi1,$nlo,$nlo
-+	srlx	$Zhi,4,$Zhi
-+	and	$nlo,0xf0,$nhi
-+	addcc	$cnt,-1,$cnt
-+	xor	$Zlo,$tmp,$Zlo
-+	and	$nlo,0x0f,$nlo
-+	xor	$Tlo,$Zlo,$Zlo
-+	sll	$nlo,4,$nlo
-+	blu	.Lghash_inner
-+	and	$Zlo,0xf,$remi
-+
-+	ldx	[$Htblo+$nlo],$Tlo
-+	sll	$remi,3,$remi
-+	xor	$Thi,$Zhi,$Zhi
-+	ldx	[$Htbl+$nlo],$Thi
-+	srlx	$Zlo,4,$Zlo
-+	xor	$rem,$Zhi,$Zhi
-+	ldx	[$rem_4bit+$remi],$rem
-+	sllx	$Zhi,60,$tmp
-+	xor	$Tlo,$Zlo,$Zlo
-+	srlx	$Zhi,4,$Zhi
-+	xor	$Zlo,$tmp,$Zlo
-+	xor	$Thi,$Zhi,$Zhi
-+
-+	add	$inp,16,$inp
-+	cmp	$inp,$len
-+	be,pn	SIZE_T_CC,.Ldone
-+	and	$Zlo,0xf,$remi
-+
-+	ldx	[$Htblo+$nhi],$Tlo
-+	sll	$remi,3,$remi
-+	xor	$rem,$Zhi,$Zhi
-+	ldx	[$Htbl+$nhi],$Thi
-+	srlx	$Zlo,4,$Zlo
-+	ldx	[$rem_4bit+$remi],$rem
-+	sllx	$Zhi,60,$tmp
-+	xor	$Tlo,$Zlo,$Zlo
-+	ldub	[$inp+15],$nlo
-+	srlx	$Zhi,4,$Zhi
-+	xor	$Zlo,$tmp,$Zlo
-+	xor	$Thi,$Zhi,$Zhi
-+	stx	$Zlo,[$Xi+8]
-+	xor	$rem,$Zhi,$Zhi
-+	stx	$Zhi,[$Xi]
-+	srl	$Zlo,8,$xi1
-+	and	$Zlo,0xff,$xi0
-+	ba	.Louter
-+	and	$xi1,0xff,$xi1
-+.align	32
-+.Ldone:
-+	ldx	[$Htblo+$nhi],$Tlo
-+	sll	$remi,3,$remi
-+	xor	$rem,$Zhi,$Zhi
-+	ldx	[$Htbl+$nhi],$Thi
-+	srlx	$Zlo,4,$Zlo
-+	ldx	[$rem_4bit+$remi],$rem
-+	sllx	$Zhi,60,$tmp
-+	xor	$Tlo,$Zlo,$Zlo
-+	srlx	$Zhi,4,$Zhi
-+	xor	$Zlo,$tmp,$Zlo
-+	xor	$Thi,$Zhi,$Zhi
-+	stx	$Zlo,[$Xi+8]
-+	xor	$rem,$Zhi,$Zhi
-+	stx	$Zhi,[$Xi]
-+
-+	ret
-+	restore
-+.type	gcm_ghash_4bit,#function
-+.size	gcm_ghash_4bit,(.-gcm_ghash_4bit)
-+___
-+
-+undef $inp;
-+undef $len;
-+
-+$code.=<<___;
-+.globl	gcm_gmult_4bit
-+.align	32
-+gcm_gmult_4bit:
-+	save	%sp,-$frame,%sp
-+	ldub	[$Xi+15],$nlo
-+	add	$Htbl,8,$Htblo
-+
-+1:	call	.+8
-+	add	%o7,rem_4bit-1b,$rem_4bit
-+
-+	and	$nlo,0xf0,$nhi
-+	and	$nlo,0x0f,$nlo
-+	sll	$nlo,4,$nlo
-+	ldx	[$Htblo+$nlo],$Zlo
-+	ldx	[$Htbl+$nlo],$Zhi
-+
-+	ldub	[$Xi+14],$nlo
-+
-+	ldx	[$Htblo+$nhi],$Tlo
-+	and	$Zlo,0xf,$remi
-+	ldx	[$Htbl+$nhi],$Thi
-+	sll	$remi,3,$remi
-+	ldx	[$rem_4bit+$remi],$rem
-+	srlx	$Zlo,4,$Zlo
-+	mov	13,$cnt
-+	sllx	$Zhi,60,$tmp
-+	xor	$Tlo,$Zlo,$Zlo
-+	srlx	$Zhi,4,$Zhi
-+	xor	$Zlo,$tmp,$Zlo
-+
-+	and	$Zlo,0xf,$remi
-+	and	$nlo,0xf0,$nhi
-+	and	$nlo,0x0f,$nlo
-+	ba	.Lgmult_inner
-+	sll	$nlo,4,$nlo
-+.align	32
-+.Lgmult_inner:
-+	ldx	[$Htblo+$nlo],$Tlo
-+	sll	$remi,3,$remi
-+	xor	$Thi,$Zhi,$Zhi
-+	ldx	[$Htbl+$nlo],$Thi
-+	srlx	$Zlo,4,$Zlo
-+	xor	$rem,$Zhi,$Zhi
-+	ldx	[$rem_4bit+$remi],$rem
-+	sllx	$Zhi,60,$tmp
-+	xor	$Tlo,$Zlo,$Zlo
-+	ldub	[$Xi+$cnt],$nlo
-+	srlx	$Zhi,4,$Zhi
-+	xor	$Zlo,$tmp,$Zlo
-+	xor	$Thi,$Zhi,$Zhi
-+	and	$Zlo,0xf,$remi
-+
-+	ldx	[$Htblo+$nhi],$Tlo
-+	sll	$remi,3,$remi
-+	xor	$rem,$Zhi,$Zhi
-+	ldx	[$Htbl+$nhi],$Thi
-+	srlx	$Zlo,4,$Zlo
-+	ldx	[$rem_4bit+$remi],$rem
-+	sllx	$Zhi,60,$tmp
-+	srlx	$Zhi,4,$Zhi
-+	and	$nlo,0xf0,$nhi
-+	addcc	$cnt,-1,$cnt
-+	xor	$Zlo,$tmp,$Zlo
-+	and	$nlo,0x0f,$nlo
-+	xor	$Tlo,$Zlo,$Zlo
-+	sll	$nlo,4,$nlo
-+	blu	.Lgmult_inner
-+	and	$Zlo,0xf,$remi
-+
-+	ldx	[$Htblo+$nlo],$Tlo
-+	sll	$remi,3,$remi
-+	xor	$Thi,$Zhi,$Zhi
-+	ldx	[$Htbl+$nlo],$Thi
-+	srlx	$Zlo,4,$Zlo
-+	xor	$rem,$Zhi,$Zhi
-+	ldx	[$rem_4bit+$remi],$rem
-+	sllx	$Zhi,60,$tmp
-+	xor	$Tlo,$Zlo,$Zlo
-+	srlx	$Zhi,4,$Zhi
-+	xor	$Zlo,$tmp,$Zlo
-+	xor	$Thi,$Zhi,$Zhi
-+	and	$Zlo,0xf,$remi
-+
-+	ldx	[$Htblo+$nhi],$Tlo
-+	sll	$remi,3,$remi
-+	xor	$rem,$Zhi,$Zhi
-+	ldx	[$Htbl+$nhi],$Thi
-+	srlx	$Zlo,4,$Zlo
-+	ldx	[$rem_4bit+$remi],$rem
-+	sllx	$Zhi,60,$tmp
-+	xor	$Tlo,$Zlo,$Zlo
-+	srlx	$Zhi,4,$Zhi
-+	xor	$Zlo,$tmp,$Zlo
-+	xor	$Thi,$Zhi,$Zhi
-+	stx	$Zlo,[$Xi+8]
-+	xor	$rem,$Zhi,$Zhi
-+	stx	$Zhi,[$Xi]
-+
-+	ret
-+	restore
-+.type	gcm_gmult_4bit,#function
-+.size	gcm_gmult_4bit,(.-gcm_gmult_4bit)
-+___
-+
-+{{{
-+# Straightforward 128x128-bit multiplication using Karatsuba algorithm
-+# followed by pair of 64-bit reductions [with a shortcut in first one,
-+# which allowed to break dependency between reductions and remove one
-+# multiplication from critical path]. While it might be suboptimal
-+# with regard to sheer number of multiplications, other methods [such
-+# as aggregate reduction] would require more 64-bit registers, which
-+# we don't have in 32-bit application context.
-+
-+($Xip,$Htable,$inp,$len)=map("%i$_",(0..3));
-+
-+($Hhl,$Hlo,$Hhi,$Xlo,$Xhi,$xE1,$sqr, $C0,$C1,$C2,$C3,$V)=
-+	(map("%o$_",(0..5,7)),map("%g$_",(1..5)));
-+
-+($shl,$shr)=map("%l$_",(0..7));
-+
-+# For details regarding "twisted H" see ghash-x86.pl.
-+$code.=<<___;
-+.globl	gcm_init_vis3
-+.align	32
-+gcm_init_vis3:
-+	save	%sp,-$frame,%sp
-+
-+	ldx	[%i1+0],$Hhi
-+	ldx	[%i1+8],$Hlo
-+	mov	0xE1,$Xhi
-+	mov	1,$Xlo
-+	sllx	$Xhi,57,$Xhi
-+	srax	$Hhi,63,$C0		! broadcast carry
-+	addcc	$Hlo,$Hlo,$Hlo		! H<<=1
-+	addxc	$Hhi,$Hhi,$Hhi
-+	and	$C0,$Xlo,$Xlo
-+	and	$C0,$Xhi,$Xhi
-+	xor	$Xlo,$Hlo,$Hlo
-+	xor	$Xhi,$Hhi,$Hhi
-+	stx	$Hlo,[%i0+8]		! save twisted H
-+	stx	$Hhi,[%i0+0]
-+
-+	sethi	%hi(0xA0406080),$V
-+	sethi	%hi(0x20C0E000),%l0
-+	or	$V,%lo(0xA0406080),$V
-+	or	%l0,%lo(0x20C0E000),%l0
-+	sllx	$V,32,$V
-+	or	%l0,$V,$V		! (0xE0·i)&0xff=0xA040608020C0E000
-+	stx	$V,[%i0+16]
-+
-+	ret
-+	restore
-+.type	gcm_init_vis3,#function
-+.size	gcm_init_vis3,.-gcm_init_vis3
-+
-+.globl	gcm_gmult_vis3
-+.align	32
-+gcm_gmult_vis3:
-+	save	%sp,-$frame,%sp
-+
-+	ldx	[$Xip+8],$Xlo		! load Xi
-+	ldx	[$Xip+0],$Xhi
-+	ldx	[$Htable+8],$Hlo	! load twisted H
-+	ldx	[$Htable+0],$Hhi
-+
-+	mov	0xE1,%l7
-+	sllx	%l7,57,$xE1		! 57 is not a typo
-+	ldx	[$Htable+16],$V		! (0xE0·i)&0xff=0xA040608020C0E000
-+
-+	xor	$Hhi,$Hlo,$Hhl		! Karatsuba pre-processing
-+	xmulx	$Xlo,$Hlo,$C0
-+	xor	$Xlo,$Xhi,$C2		! Karatsuba pre-processing
-+	xmulx	$C2,$Hhl,$C1
-+	xmulxhi	$Xlo,$Hlo,$Xlo
-+	xmulxhi	$C2,$Hhl,$C2
-+	xmulxhi	$Xhi,$Hhi,$C3
-+	xmulx	$Xhi,$Hhi,$Xhi
-+
-+	sll	$C0,3,$sqr
-+	srlx	$V,$sqr,$sqr		! ·0xE0 [implicit &(7<<3)]
-+	xor	$C0,$sqr,$sqr
-+	sllx	$sqr,57,$sqr		! ($C0·0xE1)<<1<<56 [implicit &0x7f]
-+
-+	xor	$C0,$C1,$C1		! Karatsuba post-processing
-+	xor	$Xlo,$C2,$C2
-+	 xor	$sqr,$Xlo,$Xlo		! real destination is $C1
-+	xor	$C3,$C2,$C2
-+	xor	$Xlo,$C1,$C1
-+	xor	$Xhi,$C2,$C2
-+	xor	$Xhi,$C1,$C1
-+
-+	xmulxhi	$C0,$xE1,$Xlo		! ·0xE1<<1<<56
-+	 xor	$C0,$C2,$C2
-+	xmulx	$C1,$xE1,$C0
-+	 xor	$C1,$C3,$C3
-+	xmulxhi	$C1,$xE1,$C1
-+
-+	xor	$Xlo,$C2,$C2
-+	xor	$C0,$C2,$C2
-+	xor	$C1,$C3,$C3
-+
-+	stx	$C2,[$Xip+8]		! save Xi
-+	stx	$C3,[$Xip+0]
-+
-+	ret
-+	restore
-+.type	gcm_gmult_vis3,#function
-+.size	gcm_gmult_vis3,.-gcm_gmult_vis3
-+
-+.globl	gcm_ghash_vis3
-+.align	32
-+gcm_ghash_vis3:
-+	save	%sp,-$frame,%sp
-+	nop
-+	srln	$len,0,$len		! needed on v8+, "nop" on v9
-+
-+	ldx	[$Xip+8],$C2		! load Xi
-+	ldx	[$Xip+0],$C3
-+	ldx	[$Htable+8],$Hlo	! load twisted H
-+	ldx	[$Htable+0],$Hhi
-+
-+	mov	0xE1,%l7
-+	sllx	%l7,57,$xE1		! 57 is not a typo
-+	ldx	[$Htable+16],$V		! (0xE0·i)&0xff=0xA040608020C0E000
-+
-+	and	$inp,7,$shl
-+	andn	$inp,7,$inp
-+	sll	$shl,3,$shl
-+	prefetch [$inp+63], 20
-+	sub	%g0,$shl,$shr
-+
-+	xor	$Hhi,$Hlo,$Hhl		! Karatsuba pre-processing
-+.Loop:
-+	ldx	[$inp+8],$Xlo
-+	brz,pt	$shl,1f
-+	ldx	[$inp+0],$Xhi
-+
-+	ldx	[$inp+16],$C1		! align data
-+	srlx	$Xlo,$shr,$C0
-+	sllx	$Xlo,$shl,$Xlo
-+	sllx	$Xhi,$shl,$Xhi
-+	srlx	$C1,$shr,$C1
-+	or	$C0,$Xhi,$Xhi
-+	or	$C1,$Xlo,$Xlo
-+1:
-+	add	$inp,16,$inp
-+	sub	$len,16,$len
-+	xor	$C2,$Xlo,$Xlo
-+	xor	$C3,$Xhi,$Xhi
-+	prefetch [$inp+63], 20
-+
-+	xmulx	$Xlo,$Hlo,$C0
-+	xor	$Xlo,$Xhi,$C2		! Karatsuba pre-processing
-+	xmulx	$C2,$Hhl,$C1
-+	xmulxhi	$Xlo,$Hlo,$Xlo
-+	xmulxhi	$C2,$Hhl,$C2
-+	xmulxhi	$Xhi,$Hhi,$C3
-+	xmulx	$Xhi,$Hhi,$Xhi
-+
-+	sll	$C0,3,$sqr
-+	srlx	$V,$sqr,$sqr		! ·0xE0 [implicit &(7<<3)]
-+	xor	$C0,$sqr,$sqr
-+	sllx	$sqr,57,$sqr		! ($C0·0xE1)<<1<<56 [implicit &0x7f]
-+
-+	xor	$C0,$C1,$C1		! Karatsuba post-processing
-+	xor	$Xlo,$C2,$C2
-+	 xor	$sqr,$Xlo,$Xlo		! real destination is $C1
-+	xor	$C3,$C2,$C2
-+	xor	$Xlo,$C1,$C1
-+	xor	$Xhi,$C2,$C2
-+	xor	$Xhi,$C1,$C1
-+
-+	xmulxhi	$C0,$xE1,$Xlo		! ·0xE1<<1<<56
-+	 xor	$C0,$C2,$C2
-+	xmulx	$C1,$xE1,$C0
-+	 xor	$C1,$C3,$C3
-+	xmulxhi	$C1,$xE1,$C1
-+
-+	xor	$Xlo,$C2,$C2
-+	xor	$C0,$C2,$C2
-+	brnz,pt	$len,.Loop
-+	xor	$C1,$C3,$C3
-+
-+	stx	$C2,[$Xip+8]		! save Xi
-+	stx	$C3,[$Xip+0]
-+
-+	ret
-+	restore
-+.type	gcm_ghash_vis3,#function
-+.size	gcm_ghash_vis3,.-gcm_ghash_vis3
-+___
-+}}}
-+$code.=<<___;
-+.asciz	"GHASH for SPARCv9/VIS3, CRYPTOGAMS by "
-+.align	4
-+___
-+
-+
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis3 {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my ($ref,$opf);
-+my %visopf = (	"addxc"		=> 0x011,
-+		"addxccc"	=> 0x013,
-+		"xmulx"		=> 0x115,
-+		"xmulxhi"	=> 0x116	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%([goli])([0-9])/);
-+	    $_=$bias{$1}+$2;
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	s/\b(xmulx[hi]*|addxc[c]{0,2})\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+		&unvis3($1,$2,$3,$4)
-+	 /ge;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-x86.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-x86.pl
-new file mode 100644
-index 0000000..cd84582
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-x86.pl
-@@ -0,0 +1,1405 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# March, May, June 2010
-+#
-+# The module implements "4-bit" GCM GHASH function and underlying
-+# single multiplication operation in GF(2^128). "4-bit" means that it
-+# uses 256 bytes per-key table [+64/128 bytes fixed table]. It has two
-+# code paths: vanilla x86 and vanilla SSE. Former will be executed on
-+# 486 and Pentium, latter on all others. SSE GHASH features so called
-+# "528B" variant of "4-bit" method utilizing additional 256+16 bytes
-+# of per-key storage [+512 bytes shared table]. Performance results
-+# are for streamed GHASH subroutine and are expressed in cycles per
-+# processed byte, less is better:
-+#
-+#		gcc 2.95.3(*)	SSE assembler	x86 assembler
-+#
-+# Pentium	105/111(**)	-		50
-+# PIII		68 /75		12.2		24
-+# P4		125/125		17.8		84(***)
-+# Opteron	66 /70		10.1		30
-+# Core2		54 /67		8.4		18
-+# Atom		105/105		16.8		53
-+# VIA Nano	69 /71		13.0		27
-+#
-+# (*)	gcc 3.4.x was observed to generate few percent slower code,
-+#	which is one of reasons why 2.95.3 results were chosen,
-+#	another reason is lack of 3.4.x results for older CPUs;
-+#	comparison with SSE results is not completely fair, because C
-+#	results are for vanilla "256B" implementation, while
-+#	assembler results are for "528B";-)
-+# (**)	second number is result for code compiled with -fPIC flag,
-+#	which is actually more relevant, because assembler code is
-+#	position-independent;
-+# (***)	see comment in non-MMX routine for further details;
-+#
-+# To summarize, it's >2-5 times faster than gcc-generated code. To
-+# anchor it to something else SHA1 assembler processes one byte in
-+# ~7 cycles on contemporary x86 cores. As for choice of MMX/SSE
-+# in particular, see comment at the end of the file...
-+
-+# May 2010
-+#
-+# Add PCLMULQDQ version performing at 2.10 cycles per processed byte.
-+# The question is how close is it to theoretical limit? The pclmulqdq
-+# instruction latency appears to be 14 cycles and there can't be more
-+# than 2 of them executing at any given time. This means that single
-+# Karatsuba multiplication would take 28 cycles *plus* few cycles for
-+# pre- and post-processing. Then multiplication has to be followed by
-+# modulo-reduction. Given that aggregated reduction method [see
-+# "Carry-less Multiplication and Its Usage for Computing the GCM Mode"
-+# white paper by Intel] allows you to perform reduction only once in
-+# a while we can assume that asymptotic performance can be estimated
-+# as (28+Tmod/Naggr)/16, where Tmod is time to perform reduction
-+# and Naggr is the aggregation factor.
-+#
-+# Before we proceed to this implementation let's have closer look at
-+# the best-performing code suggested by Intel in their white paper.
-+# By tracing inter-register dependencies Tmod is estimated as ~19
-+# cycles and Naggr chosen by Intel is 4, resulting in 2.05 cycles per
-+# processed byte. As implied, this is quite optimistic estimate,
-+# because it does not account for Karatsuba pre- and post-processing,
-+# which for a single multiplication is ~5 cycles. Unfortunately Intel
-+# does not provide performance data for GHASH alone. But benchmarking
-+# AES_GCM_encrypt ripped out of Fig. 15 of the white paper with aadt
-+# alone resulted in 2.46 cycles per byte of out 16KB buffer. Note that
-+# the result accounts even for pre-computing of degrees of the hash
-+# key H, but its portion is negligible at 16KB buffer size.
-+#
-+# Moving on to the implementation in question. Tmod is estimated as
-+# ~13 cycles and Naggr is 2, giving asymptotic performance of ...
-+# 2.16. How is it possible that measured performance is better than
-+# optimistic theoretical estimate? There is one thing Intel failed
-+# to recognize. By serializing GHASH with CTR in same subroutine
-+# former's performance is really limited to above (Tmul + Tmod/Naggr)
-+# equation. But if GHASH procedure is detached, the modulo-reduction
-+# can be interleaved with Naggr-1 multiplications at instruction level
-+# and under ideal conditions even disappear from the equation. So that
-+# optimistic theoretical estimate for this implementation is ...
-+# 28/16=1.75, and not 2.16. Well, it's probably way too optimistic,
-+# at least for such small Naggr. I'd argue that (28+Tproc/Naggr),
-+# where Tproc is time required for Karatsuba pre- and post-processing,
-+# is more realistic estimate. In this case it gives ... 1.91 cycles.
-+# Or in other words, depending on how well we can interleave reduction
-+# and one of the two multiplications the performance should be between
-+# 1.91 and 2.16. As already mentioned, this implementation processes
-+# one byte out of 8KB buffer in 2.10 cycles, while x86_64 counterpart
-+# - in 2.02. x86_64 performance is better, because larger register
-+# bank allows to interleave reduction and multiplication better.
-+#
-+# Does it make sense to increase Naggr? To start with it's virtually
-+# impossible in 32-bit mode, because of limited register bank
-+# capacity. Otherwise improvement has to be weighed agiainst slower
-+# setup, as well as code size and complexity increase. As even
-+# optimistic estimate doesn't promise 30% performance improvement,
-+# there are currently no plans to increase Naggr.
-+#
-+# Special thanks to David Woodhouse  for
-+# providing access to a Westmere-based system on behalf of Intel
-+# Open Source Technology Centre.
-+
-+# January 2010
-+#
-+# Tweaked to optimize transitions between integer and FP operations
-+# on same XMM register, PCLMULQDQ subroutine was measured to process
-+# one byte in 2.07 cycles on Sandy Bridge, and in 2.12 - on Westmere.
-+# The minor regression on Westmere is outweighed by ~15% improvement
-+# on Sandy Bridge. Strangely enough attempt to modify 64-bit code in
-+# similar manner resulted in almost 20% degradation on Sandy Bridge,
-+# where original 64-bit code processes one byte in 1.95 cycles.
-+
-+#####################################################################
-+# For reference, AMD Bulldozer processes one byte in 1.98 cycles in
-+# 32-bit mode and 1.89 in 64-bit.
-+
-+# February 2013
-+#
-+# Overhaul: aggregate Karatsuba post-processing, improve ILP in
-+# reduction_alg9. Resulting performance is 1.96 cycles per byte on
-+# Westmere, 1.95 - on Sandy/Ivy Bridge, 1.76 - on Bulldozer.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"ghash-x86.pl",$x86only = $ARGV[$#ARGV] eq "386");
-+
-+$sse2=0;
-+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-+
-+($Zhh,$Zhl,$Zlh,$Zll) = ("ebp","edx","ecx","ebx");
-+$inp  = "edi";
-+$Htbl = "esi";
-+
-+$unroll = 0;	# Affects x86 loop. Folded loop performs ~7% worse
-+		# than unrolled, which has to be weighted against
-+		# 2.5x x86-specific code size reduction.
-+
-+sub x86_loop {
-+    my $off = shift;
-+    my $rem = "eax";
-+
-+	&mov	($Zhh,&DWP(4,$Htbl,$Zll));
-+	&mov	($Zhl,&DWP(0,$Htbl,$Zll));
-+	&mov	($Zlh,&DWP(12,$Htbl,$Zll));
-+	&mov	($Zll,&DWP(8,$Htbl,$Zll));
-+	&xor	($rem,$rem);	# avoid partial register stalls on PIII
-+
-+	# shrd practically kills P4, 2.5x deterioration, but P4 has
-+	# MMX code-path to execute. shrd runs tad faster [than twice
-+	# the shifts, move's and or's] on pre-MMX Pentium (as well as
-+	# PIII and Core2), *but* minimizes code size, spares register
-+	# and thus allows to fold the loop...
-+	if (!$unroll) {
-+	my $cnt = $inp;
-+	&mov	($cnt,15);
-+	&jmp	(&label("x86_loop"));
-+	&set_label("x86_loop",16);
-+	    for($i=1;$i<=2;$i++) {
-+		&mov	(&LB($rem),&LB($Zll));
-+		&shrd	($Zll,$Zlh,4);
-+		&and	(&LB($rem),0xf);
-+		&shrd	($Zlh,$Zhl,4);
-+		&shrd	($Zhl,$Zhh,4);
-+		&shr	($Zhh,4);
-+		&xor	($Zhh,&DWP($off+16,"esp",$rem,4));
-+
-+		&mov	(&LB($rem),&BP($off,"esp",$cnt));
-+		if ($i&1) {
-+			&and	(&LB($rem),0xf0);
-+		} else {
-+			&shl	(&LB($rem),4);
-+		}
-+
-+		&xor	($Zll,&DWP(8,$Htbl,$rem));
-+		&xor	($Zlh,&DWP(12,$Htbl,$rem));
-+		&xor	($Zhl,&DWP(0,$Htbl,$rem));
-+		&xor	($Zhh,&DWP(4,$Htbl,$rem));
-+
-+		if ($i&1) {
-+			&dec	($cnt);
-+			&js	(&label("x86_break"));
-+		} else {
-+			&jmp	(&label("x86_loop"));
-+		}
-+	    }
-+	&set_label("x86_break",16);
-+	} else {
-+	    for($i=1;$i<32;$i++) {
-+		&comment($i);
-+		&mov	(&LB($rem),&LB($Zll));
-+		&shrd	($Zll,$Zlh,4);
-+		&and	(&LB($rem),0xf);
-+		&shrd	($Zlh,$Zhl,4);
-+		&shrd	($Zhl,$Zhh,4);
-+		&shr	($Zhh,4);
-+		&xor	($Zhh,&DWP($off+16,"esp",$rem,4));
-+
-+		if ($i&1) {
-+			&mov	(&LB($rem),&BP($off+15-($i>>1),"esp"));
-+			&and	(&LB($rem),0xf0);
-+		} else {
-+			&mov	(&LB($rem),&BP($off+15-($i>>1),"esp"));
-+			&shl	(&LB($rem),4);
-+		}
-+
-+		&xor	($Zll,&DWP(8,$Htbl,$rem));
-+		&xor	($Zlh,&DWP(12,$Htbl,$rem));
-+		&xor	($Zhl,&DWP(0,$Htbl,$rem));
-+		&xor	($Zhh,&DWP(4,$Htbl,$rem));
-+	    }
-+	}
-+	&bswap	($Zll);
-+	&bswap	($Zlh);
-+	&bswap	($Zhl);
-+	if (!$x86only) {
-+		&bswap	($Zhh);
-+	} else {
-+		&mov	("eax",$Zhh);
-+		&bswap	("eax");
-+		&mov	($Zhh,"eax");
-+	}
-+}
-+
-+if ($unroll) {
-+    &function_begin_B("_x86_gmult_4bit_inner");
-+	&x86_loop(4);
-+	&ret	();
-+    &function_end_B("_x86_gmult_4bit_inner");
-+}
-+
-+sub deposit_rem_4bit {
-+    my $bias = shift;
-+
-+	&mov	(&DWP($bias+0, "esp"),0x0000<<16);
-+	&mov	(&DWP($bias+4, "esp"),0x1C20<<16);
-+	&mov	(&DWP($bias+8, "esp"),0x3840<<16);
-+	&mov	(&DWP($bias+12,"esp"),0x2460<<16);
-+	&mov	(&DWP($bias+16,"esp"),0x7080<<16);
-+	&mov	(&DWP($bias+20,"esp"),0x6CA0<<16);
-+	&mov	(&DWP($bias+24,"esp"),0x48C0<<16);
-+	&mov	(&DWP($bias+28,"esp"),0x54E0<<16);
-+	&mov	(&DWP($bias+32,"esp"),0xE100<<16);
-+	&mov	(&DWP($bias+36,"esp"),0xFD20<<16);
-+	&mov	(&DWP($bias+40,"esp"),0xD940<<16);
-+	&mov	(&DWP($bias+44,"esp"),0xC560<<16);
-+	&mov	(&DWP($bias+48,"esp"),0x9180<<16);
-+	&mov	(&DWP($bias+52,"esp"),0x8DA0<<16);
-+	&mov	(&DWP($bias+56,"esp"),0xA9C0<<16);
-+	&mov	(&DWP($bias+60,"esp"),0xB5E0<<16);
-+}
-+
-+$suffix = $x86only ? "" : "_x86";
-+
-+&function_begin("gcm_gmult_4bit".$suffix);
-+	&stack_push(16+4+1);			# +1 for stack alignment
-+	&mov	($inp,&wparam(0));		# load Xi
-+	&mov	($Htbl,&wparam(1));		# load Htable
-+
-+	&mov	($Zhh,&DWP(0,$inp));		# load Xi[16]
-+	&mov	($Zhl,&DWP(4,$inp));
-+	&mov	($Zlh,&DWP(8,$inp));
-+	&mov	($Zll,&DWP(12,$inp));
-+
-+	&deposit_rem_4bit(16);
-+
-+	&mov	(&DWP(0,"esp"),$Zhh);		# copy Xi[16] on stack
-+	&mov	(&DWP(4,"esp"),$Zhl);
-+	&mov	(&DWP(8,"esp"),$Zlh);
-+	&mov	(&DWP(12,"esp"),$Zll);
-+	&shr	($Zll,20);
-+	&and	($Zll,0xf0);
-+
-+	if ($unroll) {
-+		&call	("_x86_gmult_4bit_inner");
-+	} else {
-+		&x86_loop(0);
-+		&mov	($inp,&wparam(0));
-+	}
-+
-+	&mov	(&DWP(12,$inp),$Zll);
-+	&mov	(&DWP(8,$inp),$Zlh);
-+	&mov	(&DWP(4,$inp),$Zhl);
-+	&mov	(&DWP(0,$inp),$Zhh);
-+	&stack_pop(16+4+1);
-+&function_end("gcm_gmult_4bit".$suffix);
-+
-+&function_begin("gcm_ghash_4bit".$suffix);
-+	&stack_push(16+4+1);			# +1 for 64-bit alignment
-+	&mov	($Zll,&wparam(0));		# load Xi
-+	&mov	($Htbl,&wparam(1));		# load Htable
-+	&mov	($inp,&wparam(2));		# load in
-+	&mov	("ecx",&wparam(3));		# load len
-+	&add	("ecx",$inp);
-+	&mov	(&wparam(3),"ecx");
-+
-+	&mov	($Zhh,&DWP(0,$Zll));		# load Xi[16]
-+	&mov	($Zhl,&DWP(4,$Zll));
-+	&mov	($Zlh,&DWP(8,$Zll));
-+	&mov	($Zll,&DWP(12,$Zll));
-+
-+	&deposit_rem_4bit(16);
-+
-+    &set_label("x86_outer_loop",16);
-+	&xor	($Zll,&DWP(12,$inp));		# xor with input
-+	&xor	($Zlh,&DWP(8,$inp));
-+	&xor	($Zhl,&DWP(4,$inp));
-+	&xor	($Zhh,&DWP(0,$inp));
-+	&mov	(&DWP(12,"esp"),$Zll);		# dump it on stack
-+	&mov	(&DWP(8,"esp"),$Zlh);
-+	&mov	(&DWP(4,"esp"),$Zhl);
-+	&mov	(&DWP(0,"esp"),$Zhh);
-+
-+	&shr	($Zll,20);
-+	&and	($Zll,0xf0);
-+
-+	if ($unroll) {
-+		&call	("_x86_gmult_4bit_inner");
-+	} else {
-+		&x86_loop(0);
-+		&mov	($inp,&wparam(2));
-+	}
-+	&lea	($inp,&DWP(16,$inp));
-+	&cmp	($inp,&wparam(3));
-+	&mov	(&wparam(2),$inp)	if (!$unroll);
-+	&jb	(&label("x86_outer_loop"));
-+
-+	&mov	($inp,&wparam(0));	# load Xi
-+	&mov	(&DWP(12,$inp),$Zll);
-+	&mov	(&DWP(8,$inp),$Zlh);
-+	&mov	(&DWP(4,$inp),$Zhl);
-+	&mov	(&DWP(0,$inp),$Zhh);
-+	&stack_pop(16+4+1);
-+&function_end("gcm_ghash_4bit".$suffix);
-+
-+if (!$x86only) {{{
-+
-+&static_label("rem_4bit");
-+
-+if (!$sse2) {{	# pure-MMX "May" version...
-+
-+$S=12;		# shift factor for rem_4bit
-+
-+&function_begin_B("_mmx_gmult_4bit_inner");
-+# MMX version performs 3.5 times better on P4 (see comment in non-MMX
-+# routine for further details), 100% better on Opteron, ~70% better
-+# on Core2 and PIII... In other words effort is considered to be well
-+# spent... Since initial release the loop was unrolled in order to
-+# "liberate" register previously used as loop counter. Instead it's
-+# used to optimize critical path in 'Z.hi ^= rem_4bit[Z.lo&0xf]'.
-+# The path involves move of Z.lo from MMX to integer register,
-+# effective address calculation and finally merge of value to Z.hi.
-+# Reference to rem_4bit is scheduled so late that I had to >>4
-+# rem_4bit elements. This resulted in 20-45% procent improvement
-+# on contemporary µ-archs.
-+{
-+    my $cnt;
-+    my $rem_4bit = "eax";
-+    my @rem = ($Zhh,$Zll);
-+    my $nhi = $Zhl;
-+    my $nlo = $Zlh;
-+
-+    my ($Zlo,$Zhi) = ("mm0","mm1");
-+    my $tmp = "mm2";
-+
-+	&xor	($nlo,$nlo);	# avoid partial register stalls on PIII
-+	&mov	($nhi,$Zll);
-+	&mov	(&LB($nlo),&LB($nhi));
-+	&shl	(&LB($nlo),4);
-+	&and	($nhi,0xf0);
-+	&movq	($Zlo,&QWP(8,$Htbl,$nlo));
-+	&movq	($Zhi,&QWP(0,$Htbl,$nlo));
-+	&movd	($rem[0],$Zlo);
-+
-+	for ($cnt=28;$cnt>=-2;$cnt--) {
-+	    my $odd = $cnt&1;
-+	    my $nix = $odd ? $nlo : $nhi;
-+
-+		&shl	(&LB($nlo),4)			if ($odd);
-+		&psrlq	($Zlo,4);
-+		&movq	($tmp,$Zhi);
-+		&psrlq	($Zhi,4);
-+		&pxor	($Zlo,&QWP(8,$Htbl,$nix));
-+		&mov	(&LB($nlo),&BP($cnt/2,$inp))	if (!$odd && $cnt>=0);
-+		&psllq	($tmp,60);
-+		&and	($nhi,0xf0)			if ($odd);
-+		&pxor	($Zhi,&QWP(0,$rem_4bit,$rem[1],8)) if ($cnt<28);
-+		&and	($rem[0],0xf);
-+		&pxor	($Zhi,&QWP(0,$Htbl,$nix));
-+		&mov	($nhi,$nlo)			if (!$odd && $cnt>=0);
-+		&movd	($rem[1],$Zlo);
-+		&pxor	($Zlo,$tmp);
-+
-+		push	(@rem,shift(@rem));		# "rotate" registers
-+	}
-+
-+	&mov	($inp,&DWP(4,$rem_4bit,$rem[1],8));	# last rem_4bit[rem]
-+
-+	&psrlq	($Zlo,32);	# lower part of Zlo is already there
-+	&movd	($Zhl,$Zhi);
-+	&psrlq	($Zhi,32);
-+	&movd	($Zlh,$Zlo);
-+	&movd	($Zhh,$Zhi);
-+	&shl	($inp,4);	# compensate for rem_4bit[i] being >>4
-+
-+	&bswap	($Zll);
-+	&bswap	($Zhl);
-+	&bswap	($Zlh);
-+	&xor	($Zhh,$inp);
-+	&bswap	($Zhh);
-+
-+	&ret	();
-+}
-+&function_end_B("_mmx_gmult_4bit_inner");
-+
-+&function_begin("gcm_gmult_4bit_mmx");
-+	&mov	($inp,&wparam(0));	# load Xi
-+	&mov	($Htbl,&wparam(1));	# load Htable
-+
-+	&call	(&label("pic_point"));
-+	&set_label("pic_point");
-+	&blindpop("eax");
-+	&lea	("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax"));
-+
-+	&movz	($Zll,&BP(15,$inp));
-+
-+	&call	("_mmx_gmult_4bit_inner");
-+
-+	&mov	($inp,&wparam(0));	# load Xi
-+	&emms	();
-+	&mov	(&DWP(12,$inp),$Zll);
-+	&mov	(&DWP(4,$inp),$Zhl);
-+	&mov	(&DWP(8,$inp),$Zlh);
-+	&mov	(&DWP(0,$inp),$Zhh);
-+&function_end("gcm_gmult_4bit_mmx");
-+
-+# Streamed version performs 20% better on P4, 7% on Opteron,
-+# 10% on Core2 and PIII...
-+&function_begin("gcm_ghash_4bit_mmx");
-+	&mov	($Zhh,&wparam(0));	# load Xi
-+	&mov	($Htbl,&wparam(1));	# load Htable
-+	&mov	($inp,&wparam(2));	# load in
-+	&mov	($Zlh,&wparam(3));	# load len
-+
-+	&call	(&label("pic_point"));
-+	&set_label("pic_point");
-+	&blindpop("eax");
-+	&lea	("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax"));
-+
-+	&add	($Zlh,$inp);
-+	&mov	(&wparam(3),$Zlh);	# len to point at the end of input
-+	&stack_push(4+1);		# +1 for stack alignment
-+
-+	&mov	($Zll,&DWP(12,$Zhh));	# load Xi[16]
-+	&mov	($Zhl,&DWP(4,$Zhh));
-+	&mov	($Zlh,&DWP(8,$Zhh));
-+	&mov	($Zhh,&DWP(0,$Zhh));
-+	&jmp	(&label("mmx_outer_loop"));
-+
-+    &set_label("mmx_outer_loop",16);
-+	&xor	($Zll,&DWP(12,$inp));
-+	&xor	($Zhl,&DWP(4,$inp));
-+	&xor	($Zlh,&DWP(8,$inp));
-+	&xor	($Zhh,&DWP(0,$inp));
-+	&mov	(&wparam(2),$inp);
-+	&mov	(&DWP(12,"esp"),$Zll);
-+	&mov	(&DWP(4,"esp"),$Zhl);
-+	&mov	(&DWP(8,"esp"),$Zlh);
-+	&mov	(&DWP(0,"esp"),$Zhh);
-+
-+	&mov	($inp,"esp");
-+	&shr	($Zll,24);
-+
-+	&call	("_mmx_gmult_4bit_inner");
-+
-+	&mov	($inp,&wparam(2));
-+	&lea	($inp,&DWP(16,$inp));
-+	&cmp	($inp,&wparam(3));
-+	&jb	(&label("mmx_outer_loop"));
-+
-+	&mov	($inp,&wparam(0));	# load Xi
-+	&emms	();
-+	&mov	(&DWP(12,$inp),$Zll);
-+	&mov	(&DWP(4,$inp),$Zhl);
-+	&mov	(&DWP(8,$inp),$Zlh);
-+	&mov	(&DWP(0,$inp),$Zhh);
-+
-+	&stack_pop(4+1);
-+&function_end("gcm_ghash_4bit_mmx");
-+
-+}} else {{	# "June" MMX version...
-+		# ... has slower "April" gcm_gmult_4bit_mmx with folded
-+		# loop. This is done to conserve code size...
-+$S=16;		# shift factor for rem_4bit
-+
-+sub mmx_loop() {
-+# MMX version performs 2.8 times better on P4 (see comment in non-MMX
-+# routine for further details), 40% better on Opteron and Core2, 50%
-+# better on PIII... In other words effort is considered to be well
-+# spent...
-+    my $inp = shift;
-+    my $rem_4bit = shift;
-+    my $cnt = $Zhh;
-+    my $nhi = $Zhl;
-+    my $nlo = $Zlh;
-+    my $rem = $Zll;
-+
-+    my ($Zlo,$Zhi) = ("mm0","mm1");
-+    my $tmp = "mm2";
-+
-+	&xor	($nlo,$nlo);	# avoid partial register stalls on PIII
-+	&mov	($nhi,$Zll);
-+	&mov	(&LB($nlo),&LB($nhi));
-+	&mov	($cnt,14);
-+	&shl	(&LB($nlo),4);
-+	&and	($nhi,0xf0);
-+	&movq	($Zlo,&QWP(8,$Htbl,$nlo));
-+	&movq	($Zhi,&QWP(0,$Htbl,$nlo));
-+	&movd	($rem,$Zlo);
-+	&jmp	(&label("mmx_loop"));
-+
-+    &set_label("mmx_loop",16);
-+	&psrlq	($Zlo,4);
-+	&and	($rem,0xf);
-+	&movq	($tmp,$Zhi);
-+	&psrlq	($Zhi,4);
-+	&pxor	($Zlo,&QWP(8,$Htbl,$nhi));
-+	&mov	(&LB($nlo),&BP(0,$inp,$cnt));
-+	&psllq	($tmp,60);
-+	&pxor	($Zhi,&QWP(0,$rem_4bit,$rem,8));
-+	&dec	($cnt);
-+	&movd	($rem,$Zlo);
-+	&pxor	($Zhi,&QWP(0,$Htbl,$nhi));
-+	&mov	($nhi,$nlo);
-+	&pxor	($Zlo,$tmp);
-+	&js	(&label("mmx_break"));
-+
-+	&shl	(&LB($nlo),4);
-+	&and	($rem,0xf);
-+	&psrlq	($Zlo,4);
-+	&and	($nhi,0xf0);
-+	&movq	($tmp,$Zhi);
-+	&psrlq	($Zhi,4);
-+	&pxor	($Zlo,&QWP(8,$Htbl,$nlo));
-+	&psllq	($tmp,60);
-+	&pxor	($Zhi,&QWP(0,$rem_4bit,$rem,8));
-+	&movd	($rem,$Zlo);
-+	&pxor	($Zhi,&QWP(0,$Htbl,$nlo));
-+	&pxor	($Zlo,$tmp);
-+	&jmp	(&label("mmx_loop"));
-+
-+    &set_label("mmx_break",16);
-+	&shl	(&LB($nlo),4);
-+	&and	($rem,0xf);
-+	&psrlq	($Zlo,4);
-+	&and	($nhi,0xf0);
-+	&movq	($tmp,$Zhi);
-+	&psrlq	($Zhi,4);
-+	&pxor	($Zlo,&QWP(8,$Htbl,$nlo));
-+	&psllq	($tmp,60);
-+	&pxor	($Zhi,&QWP(0,$rem_4bit,$rem,8));
-+	&movd	($rem,$Zlo);
-+	&pxor	($Zhi,&QWP(0,$Htbl,$nlo));
-+	&pxor	($Zlo,$tmp);
-+
-+	&psrlq	($Zlo,4);
-+	&and	($rem,0xf);
-+	&movq	($tmp,$Zhi);
-+	&psrlq	($Zhi,4);
-+	&pxor	($Zlo,&QWP(8,$Htbl,$nhi));
-+	&psllq	($tmp,60);
-+	&pxor	($Zhi,&QWP(0,$rem_4bit,$rem,8));
-+	&movd	($rem,$Zlo);
-+	&pxor	($Zhi,&QWP(0,$Htbl,$nhi));
-+	&pxor	($Zlo,$tmp);
-+
-+	&psrlq	($Zlo,32);	# lower part of Zlo is already there
-+	&movd	($Zhl,$Zhi);
-+	&psrlq	($Zhi,32);
-+	&movd	($Zlh,$Zlo);
-+	&movd	($Zhh,$Zhi);
-+
-+	&bswap	($Zll);
-+	&bswap	($Zhl);
-+	&bswap	($Zlh);
-+	&bswap	($Zhh);
-+}
-+
-+&function_begin("gcm_gmult_4bit_mmx");
-+	&mov	($inp,&wparam(0));	# load Xi
-+	&mov	($Htbl,&wparam(1));	# load Htable
-+
-+	&call	(&label("pic_point"));
-+	&set_label("pic_point");
-+	&blindpop("eax");
-+	&lea	("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax"));
-+
-+	&movz	($Zll,&BP(15,$inp));
-+
-+	&mmx_loop($inp,"eax");
-+
-+	&emms	();
-+	&mov	(&DWP(12,$inp),$Zll);
-+	&mov	(&DWP(4,$inp),$Zhl);
-+	&mov	(&DWP(8,$inp),$Zlh);
-+	&mov	(&DWP(0,$inp),$Zhh);
-+&function_end("gcm_gmult_4bit_mmx");
-+
-+######################################################################
-+# Below subroutine is "528B" variant of "4-bit" GCM GHASH function
-+# (see gcm128.c for details). It provides further 20-40% performance
-+# improvement over above mentioned "May" version.
-+
-+&static_label("rem_8bit");
-+
-+&function_begin("gcm_ghash_4bit_mmx");
-+{ my ($Zlo,$Zhi) = ("mm7","mm6");
-+  my $rem_8bit = "esi";
-+  my $Htbl = "ebx";
-+
-+    # parameter block
-+    &mov	("eax",&wparam(0));		# Xi
-+    &mov	("ebx",&wparam(1));		# Htable
-+    &mov	("ecx",&wparam(2));		# inp
-+    &mov	("edx",&wparam(3));		# len
-+    &mov	("ebp","esp");			# original %esp
-+    &call	(&label("pic_point"));
-+    &set_label	("pic_point");
-+    &blindpop	($rem_8bit);
-+    &lea	($rem_8bit,&DWP(&label("rem_8bit")."-".&label("pic_point"),$rem_8bit));
-+
-+    &sub	("esp",512+16+16);		# allocate stack frame...
-+    &and	("esp",-64);			# ...and align it
-+    &sub	("esp",16);			# place for (u8)(H[]<<4)
-+
-+    &add	("edx","ecx");			# pointer to the end of input
-+    &mov	(&DWP(528+16+0,"esp"),"eax");	# save Xi
-+    &mov	(&DWP(528+16+8,"esp"),"edx");	# save inp+len
-+    &mov	(&DWP(528+16+12,"esp"),"ebp");	# save original %esp
-+
-+    { my @lo  = ("mm0","mm1","mm2");
-+      my @hi  = ("mm3","mm4","mm5");
-+      my @tmp = ("mm6","mm7");
-+      my ($off1,$off2,$i) = (0,0,);
-+
-+      &add	($Htbl,128);			# optimize for size
-+      &lea	("edi",&DWP(16+128,"esp"));
-+      &lea	("ebp",&DWP(16+256+128,"esp"));
-+
-+      # decompose Htable (low and high parts are kept separately),
-+      # generate Htable[]>>4, (u8)(Htable[]<<4), save to stack...
-+      for ($i=0;$i<18;$i++) {
-+
-+	&mov	("edx",&DWP(16*$i+8-128,$Htbl))		if ($i<16);
-+	&movq	($lo[0],&QWP(16*$i+8-128,$Htbl))	if ($i<16);
-+	&psllq	($tmp[1],60)				if ($i>1);
-+	&movq	($hi[0],&QWP(16*$i+0-128,$Htbl))	if ($i<16);
-+	&por	($lo[2],$tmp[1])			if ($i>1);
-+	&movq	(&QWP($off1-128,"edi"),$lo[1])		if ($i>0 && $i<17);
-+	&psrlq	($lo[1],4)				if ($i>0 && $i<17);
-+	&movq	(&QWP($off1,"edi"),$hi[1])		if ($i>0 && $i<17);
-+	&movq	($tmp[0],$hi[1])			if ($i>0 && $i<17);
-+	&movq	(&QWP($off2-128,"ebp"),$lo[2])		if ($i>1);
-+	&psrlq	($hi[1],4)				if ($i>0 && $i<17);
-+	&movq	(&QWP($off2,"ebp"),$hi[2])		if ($i>1);
-+	&shl	("edx",4)				if ($i<16);
-+	&mov	(&BP($i,"esp"),&LB("edx"))		if ($i<16);
-+
-+	unshift	(@lo,pop(@lo));			# "rotate" registers
-+	unshift	(@hi,pop(@hi));
-+	unshift	(@tmp,pop(@tmp));
-+	$off1 += 8	if ($i>0);
-+	$off2 += 8	if ($i>1);
-+      }
-+    }
-+
-+    &movq	($Zhi,&QWP(0,"eax"));
-+    &mov	("ebx",&DWP(8,"eax"));
-+    &mov	("edx",&DWP(12,"eax"));		# load Xi
-+
-+&set_label("outer",16);
-+  { my $nlo = "eax";
-+    my $dat = "edx";
-+    my @nhi = ("edi","ebp");
-+    my @rem = ("ebx","ecx");
-+    my @red = ("mm0","mm1","mm2");
-+    my $tmp = "mm3";
-+
-+    &xor	($dat,&DWP(12,"ecx"));		# merge input data
-+    &xor	("ebx",&DWP(8,"ecx"));
-+    &pxor	($Zhi,&QWP(0,"ecx"));
-+    &lea	("ecx",&DWP(16,"ecx"));		# inp+=16
-+    #&mov	(&DWP(528+12,"esp"),$dat);	# save inp^Xi
-+    &mov	(&DWP(528+8,"esp"),"ebx");
-+    &movq	(&QWP(528+0,"esp"),$Zhi);
-+    &mov	(&DWP(528+16+4,"esp"),"ecx");	# save inp
-+
-+    &xor	($nlo,$nlo);
-+    &rol	($dat,8);
-+    &mov	(&LB($nlo),&LB($dat));
-+    &mov	($nhi[1],$nlo);
-+    &and	(&LB($nlo),0x0f);
-+    &shr	($nhi[1],4);
-+    &pxor	($red[0],$red[0]);
-+    &rol	($dat,8);			# next byte
-+    &pxor	($red[1],$red[1]);
-+    &pxor	($red[2],$red[2]);
-+
-+    # Just like in "May" version modulo-schedule for critical path in
-+    # 'Z.hi ^= rem_8bit[Z.lo&0xff^((u8)H[nhi]<<4)]<<48'. Final 'pxor'
-+    # is scheduled so late that rem_8bit[] has to be shifted *right*
-+    # by 16, which is why last argument to pinsrw is 2, which
-+    # corresponds to <<32=<<48>>16...
-+    for ($j=11,$i=0;$i<15;$i++) {
-+
-+      if ($i>0) {
-+	&pxor	($Zlo,&QWP(16,"esp",$nlo,8));		# Z^=H[nlo]
-+	&rol	($dat,8);				# next byte
-+	&pxor	($Zhi,&QWP(16+128,"esp",$nlo,8));
-+
-+	&pxor	($Zlo,$tmp);
-+	&pxor	($Zhi,&QWP(16+256+128,"esp",$nhi[0],8));
-+	&xor	(&LB($rem[1]),&BP(0,"esp",$nhi[0]));	# rem^(H[nhi]<<4)
-+      } else {
-+	&movq	($Zlo,&QWP(16,"esp",$nlo,8));
-+	&movq	($Zhi,&QWP(16+128,"esp",$nlo,8));
-+      }
-+
-+	&mov	(&LB($nlo),&LB($dat));
-+	&mov	($dat,&DWP(528+$j,"esp"))		if (--$j%4==0);
-+
-+	&movd	($rem[0],$Zlo);
-+	&movz	($rem[1],&LB($rem[1]))			if ($i>0);
-+	&psrlq	($Zlo,8);				# Z>>=8
-+
-+	&movq	($tmp,$Zhi);
-+	&mov	($nhi[0],$nlo);
-+	&psrlq	($Zhi,8);
-+
-+	&pxor	($Zlo,&QWP(16+256+0,"esp",$nhi[1],8));	# Z^=H[nhi]>>4
-+	&and	(&LB($nlo),0x0f);
-+	&psllq	($tmp,56);
-+
-+	&pxor	($Zhi,$red[1])				if ($i>1);
-+	&shr	($nhi[0],4);
-+	&pinsrw	($red[0],&WP(0,$rem_8bit,$rem[1],2),2)	if ($i>0);
-+
-+	unshift	(@red,pop(@red));			# "rotate" registers
-+	unshift	(@rem,pop(@rem));
-+	unshift	(@nhi,pop(@nhi));
-+    }
-+
-+    &pxor	($Zlo,&QWP(16,"esp",$nlo,8));		# Z^=H[nlo]
-+    &pxor	($Zhi,&QWP(16+128,"esp",$nlo,8));
-+    &xor	(&LB($rem[1]),&BP(0,"esp",$nhi[0]));	# rem^(H[nhi]<<4)
-+
-+    &pxor	($Zlo,$tmp);
-+    &pxor	($Zhi,&QWP(16+256+128,"esp",$nhi[0],8));
-+    &movz	($rem[1],&LB($rem[1]));
-+
-+    &pxor	($red[2],$red[2]);			# clear 2nd word
-+    &psllq	($red[1],4);
-+
-+    &movd	($rem[0],$Zlo);
-+    &psrlq	($Zlo,4);				# Z>>=4
-+
-+    &movq	($tmp,$Zhi);
-+    &psrlq	($Zhi,4);
-+    &shl	($rem[0],4);				# rem<<4
-+
-+    &pxor	($Zlo,&QWP(16,"esp",$nhi[1],8));	# Z^=H[nhi]
-+    &psllq	($tmp,60);
-+    &movz	($rem[0],&LB($rem[0]));
-+
-+    &pxor	($Zlo,$tmp);
-+    &pxor	($Zhi,&QWP(16+128,"esp",$nhi[1],8));
-+
-+    &pinsrw	($red[0],&WP(0,$rem_8bit,$rem[1],2),2);
-+    &pxor	($Zhi,$red[1]);
-+
-+    &movd	($dat,$Zlo);
-+    &pinsrw	($red[2],&WP(0,$rem_8bit,$rem[0],2),3);	# last is <<48
-+
-+    &psllq	($red[0],12);				# correct by <<16>>4
-+    &pxor	($Zhi,$red[0]);
-+    &psrlq	($Zlo,32);
-+    &pxor	($Zhi,$red[2]);
-+
-+    &mov	("ecx",&DWP(528+16+4,"esp"));	# restore inp
-+    &movd	("ebx",$Zlo);
-+    &movq	($tmp,$Zhi);			# 01234567
-+    &psllw	($Zhi,8);			# 1.3.5.7.
-+    &psrlw	($tmp,8);			# .0.2.4.6
-+    &por	($Zhi,$tmp);			# 10325476
-+    &bswap	($dat);
-+    &pshufw	($Zhi,$Zhi,0b00011011);		# 76543210
-+    &bswap	("ebx");
-+    
-+    &cmp	("ecx",&DWP(528+16+8,"esp"));	# are we done?
-+    &jne	(&label("outer"));
-+  }
-+
-+    &mov	("eax",&DWP(528+16+0,"esp"));	# restore Xi
-+    &mov	(&DWP(12,"eax"),"edx");
-+    &mov	(&DWP(8,"eax"),"ebx");
-+    &movq	(&QWP(0,"eax"),$Zhi);
-+
-+    &mov	("esp",&DWP(528+16+12,"esp"));	# restore original %esp
-+    &emms	();
-+}
-+&function_end("gcm_ghash_4bit_mmx");
-+}}
-+
-+if ($sse2) {{
-+######################################################################
-+# PCLMULQDQ version.
-+
-+$Xip="eax";
-+$Htbl="edx";
-+$const="ecx";
-+$inp="esi";
-+$len="ebx";
-+
-+($Xi,$Xhi)=("xmm0","xmm1");	$Hkey="xmm2";
-+($T1,$T2,$T3)=("xmm3","xmm4","xmm5");
-+($Xn,$Xhn)=("xmm6","xmm7");
-+
-+&static_label("bswap");
-+
-+sub clmul64x64_T2 {	# minimal "register" pressure
-+my ($Xhi,$Xi,$Hkey,$HK)=@_;
-+
-+	&movdqa		($Xhi,$Xi);		#
-+	&pshufd		($T1,$Xi,0b01001110);
-+	&pshufd		($T2,$Hkey,0b01001110)	if (!defined($HK));
-+	&pxor		($T1,$Xi);		#
-+	&pxor		($T2,$Hkey)		if (!defined($HK));
-+			$HK=$T2			if (!defined($HK));
-+
-+	&pclmulqdq	($Xi,$Hkey,0x00);	#######
-+	&pclmulqdq	($Xhi,$Hkey,0x11);	#######
-+	&pclmulqdq	($T1,$HK,0x00);		#######
-+	&xorps		($T1,$Xi);		#
-+	&xorps		($T1,$Xhi);		#
-+
-+	&movdqa		($T2,$T1);		#
-+	&psrldq		($T1,8);
-+	&pslldq		($T2,8);		#
-+	&pxor		($Xhi,$T1);
-+	&pxor		($Xi,$T2);		#
-+}
-+
-+sub clmul64x64_T3 {
-+# Even though this subroutine offers visually better ILP, it
-+# was empirically found to be a tad slower than above version.
-+# At least in gcm_ghash_clmul context. But it's just as well,
-+# because loop modulo-scheduling is possible only thanks to
-+# minimized "register" pressure...
-+my ($Xhi,$Xi,$Hkey)=@_;
-+
-+	&movdqa		($T1,$Xi);		#
-+	&movdqa		($Xhi,$Xi);
-+	&pclmulqdq	($Xi,$Hkey,0x00);	#######
-+	&pclmulqdq	($Xhi,$Hkey,0x11);	#######
-+	&pshufd		($T2,$T1,0b01001110);	#
-+	&pshufd		($T3,$Hkey,0b01001110);
-+	&pxor		($T2,$T1);		#
-+	&pxor		($T3,$Hkey);
-+	&pclmulqdq	($T2,$T3,0x00);		#######
-+	&pxor		($T2,$Xi);		#
-+	&pxor		($T2,$Xhi);		#
-+
-+	&movdqa		($T3,$T2);		#
-+	&psrldq		($T2,8);
-+	&pslldq		($T3,8);		#
-+	&pxor		($Xhi,$T2);
-+	&pxor		($Xi,$T3);		#
-+}
-+
-+if (1) {		# Algorithm 9 with <<1 twist.
-+			# Reduction is shorter and uses only two
-+			# temporary registers, which makes it better
-+			# candidate for interleaving with 64x64
-+			# multiplication. Pre-modulo-scheduled loop
-+			# was found to be ~20% faster than Algorithm 5
-+			# below. Algorithm 9 was therefore chosen for
-+			# further optimization...
-+
-+sub reduction_alg9 {	# 17/11 times faster than Intel version
-+my ($Xhi,$Xi) = @_;
-+
-+	# 1st phase
-+	&movdqa		($T2,$Xi);		#
-+	&movdqa		($T1,$Xi);
-+	&psllq		($Xi,5);
-+	&pxor		($T1,$Xi);		#
-+	&psllq		($Xi,1);
-+	&pxor		($Xi,$T1);		#
-+	&psllq		($Xi,57);		#
-+	&movdqa		($T1,$Xi);		#
-+	&pslldq		($Xi,8);
-+	&psrldq		($T1,8);		#	
-+	&pxor		($Xi,$T2);
-+	&pxor		($Xhi,$T1);		#
-+
-+	# 2nd phase
-+	&movdqa		($T2,$Xi);
-+	&psrlq		($Xi,1);
-+	&pxor		($Xhi,$T2);		#
-+	&pxor		($T2,$Xi);
-+	&psrlq		($Xi,5);
-+	&pxor		($Xi,$T2);		#
-+	&psrlq		($Xi,1);		#
-+	&pxor		($Xi,$Xhi)		#
-+}
-+
-+&function_begin_B("gcm_init_clmul");
-+	&mov		($Htbl,&wparam(0));
-+	&mov		($Xip,&wparam(1));
-+
-+	&call		(&label("pic"));
-+&set_label("pic");
-+	&blindpop	($const);
-+	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
-+
-+	&movdqu		($Hkey,&QWP(0,$Xip));
-+	&pshufd		($Hkey,$Hkey,0b01001110);# dword swap
-+
-+	# <<1 twist
-+	&pshufd		($T2,$Hkey,0b11111111);	# broadcast uppermost dword
-+	&movdqa		($T1,$Hkey);
-+	&psllq		($Hkey,1);
-+	&pxor		($T3,$T3);		#
-+	&psrlq		($T1,63);
-+	&pcmpgtd	($T3,$T2);		# broadcast carry bit
-+	&pslldq		($T1,8);
-+	&por		($Hkey,$T1);		# H<<=1
-+
-+	# magic reduction
-+	&pand		($T3,&QWP(16,$const));	# 0x1c2_polynomial
-+	&pxor		($Hkey,$T3);		# if(carry) H^=0x1c2_polynomial
-+
-+	# calculate H^2
-+	&movdqa		($Xi,$Hkey);
-+	&clmul64x64_T2	($Xhi,$Xi,$Hkey);
-+	&reduction_alg9	($Xhi,$Xi);
-+
-+	&pshufd		($T1,$Hkey,0b01001110);
-+	&pshufd		($T2,$Xi,0b01001110);
-+	&pxor		($T1,$Hkey);		# Karatsuba pre-processing
-+	&movdqu		(&QWP(0,$Htbl),$Hkey);	# save H
-+	&pxor		($T2,$Xi);		# Karatsuba pre-processing
-+	&movdqu		(&QWP(16,$Htbl),$Xi);	# save H^2
-+	&palignr	($T2,$T1,8);		# low part is H.lo^H.hi
-+	&movdqu		(&QWP(32,$Htbl),$T2);	# save Karatsuba "salt"
-+
-+	&ret		();
-+&function_end_B("gcm_init_clmul");
-+
-+&function_begin_B("gcm_gmult_clmul");
-+	&mov		($Xip,&wparam(0));
-+	&mov		($Htbl,&wparam(1));
-+
-+	&call		(&label("pic"));
-+&set_label("pic");
-+	&blindpop	($const);
-+	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
-+
-+	&movdqu		($Xi,&QWP(0,$Xip));
-+	&movdqa		($T3,&QWP(0,$const));
-+	&movups		($Hkey,&QWP(0,$Htbl));
-+	&pshufb		($Xi,$T3);
-+	&movups		($T2,&QWP(32,$Htbl));
-+
-+	&clmul64x64_T2	($Xhi,$Xi,$Hkey,$T2);
-+	&reduction_alg9	($Xhi,$Xi);
-+
-+	&pshufb		($Xi,$T3);
-+	&movdqu		(&QWP(0,$Xip),$Xi);
-+
-+	&ret	();
-+&function_end_B("gcm_gmult_clmul");
-+
-+&function_begin("gcm_ghash_clmul");
-+	&mov		($Xip,&wparam(0));
-+	&mov		($Htbl,&wparam(1));
-+	&mov		($inp,&wparam(2));
-+	&mov		($len,&wparam(3));
-+
-+	&call		(&label("pic"));
-+&set_label("pic");
-+	&blindpop	($const);
-+	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
-+
-+	&movdqu		($Xi,&QWP(0,$Xip));
-+	&movdqa		($T3,&QWP(0,$const));
-+	&movdqu		($Hkey,&QWP(0,$Htbl));
-+	&pshufb		($Xi,$T3);
-+
-+	&sub		($len,0x10);
-+	&jz		(&label("odd_tail"));
-+
-+	#######
-+	# Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
-+	#	[(H*Ii+1) + (H*Xi+1)] mod P =
-+	#	[(H*Ii+1) + H^2*(Ii+Xi)] mod P
-+	#
-+	&movdqu		($T1,&QWP(0,$inp));	# Ii
-+	&movdqu		($Xn,&QWP(16,$inp));	# Ii+1
-+	&pshufb		($T1,$T3);
-+	&pshufb		($Xn,$T3);
-+	&movdqu		($T3,&QWP(32,$Htbl));
-+	&pxor		($Xi,$T1);		# Ii+Xi
-+
-+	&pshufd		($T1,$Xn,0b01001110);	# H*Ii+1
-+	&movdqa		($Xhn,$Xn);
-+	&pxor		($T1,$Xn);		#
-+	&lea		($inp,&DWP(32,$inp));	# i+=2
-+
-+	&pclmulqdq	($Xn,$Hkey,0x00);	#######
-+	&pclmulqdq	($Xhn,$Hkey,0x11);	#######
-+	&pclmulqdq	($T1,$T3,0x00);		#######
-+	&movups		($Hkey,&QWP(16,$Htbl));	# load H^2
-+	&nop		();
-+
-+	&sub		($len,0x20);
-+	&jbe		(&label("even_tail"));
-+	&jmp		(&label("mod_loop"));
-+
-+&set_label("mod_loop",32);
-+	&pshufd		($T2,$Xi,0b01001110);	# H^2*(Ii+Xi)
-+	&movdqa		($Xhi,$Xi);
-+	&pxor		($T2,$Xi);		#
-+	&nop		();
-+
-+	&pclmulqdq	($Xi,$Hkey,0x00);	#######
-+	&pclmulqdq	($Xhi,$Hkey,0x11);	#######
-+	&pclmulqdq	($T2,$T3,0x10);		#######
-+	&movups		($Hkey,&QWP(0,$Htbl));	# load H
-+
-+	&xorps		($Xi,$Xn);		# (H*Ii+1) + H^2*(Ii+Xi)
-+	&movdqa		($T3,&QWP(0,$const));
-+	&xorps		($Xhi,$Xhn);
-+	 &movdqu	($Xhn,&QWP(0,$inp));	# Ii
-+	&pxor		($T1,$Xi);		# aggregated Karatsuba post-processing
-+	 &movdqu	($Xn,&QWP(16,$inp));	# Ii+1
-+	&pxor		($T1,$Xhi);		#
-+
-+	 &pshufb	($Xhn,$T3);
-+	&pxor		($T2,$T1);		#
-+
-+	&movdqa		($T1,$T2);		#
-+	&psrldq		($T2,8);
-+	&pslldq		($T1,8);		#
-+	&pxor		($Xhi,$T2);
-+	&pxor		($Xi,$T1);		#
-+	 &pshufb	($Xn,$T3);
-+	 &pxor		($Xhi,$Xhn);		# "Ii+Xi", consume early
-+
-+	&movdqa		($Xhn,$Xn);		#&clmul64x64_TX	($Xhn,$Xn,$Hkey); H*Ii+1
-+	  &movdqa	($T2,$Xi);		#&reduction_alg9($Xhi,$Xi); 1st phase
-+	  &movdqa	($T1,$Xi);
-+	  &psllq	($Xi,5);
-+	  &pxor		($T1,$Xi);		#
-+	  &psllq	($Xi,1);
-+	  &pxor		($Xi,$T1);		#
-+	&pclmulqdq	($Xn,$Hkey,0x00);	#######
-+	&movups		($T3,&QWP(32,$Htbl));
-+	  &psllq	($Xi,57);		#
-+	  &movdqa	($T1,$Xi);		#
-+	  &pslldq	($Xi,8);
-+	  &psrldq	($T1,8);		#	
-+	  &pxor		($Xi,$T2);
-+	  &pxor		($Xhi,$T1);		#
-+	&pshufd		($T1,$Xhn,0b01001110);
-+	  &movdqa	($T2,$Xi);		# 2nd phase
-+	  &psrlq	($Xi,1);
-+	&pxor		($T1,$Xhn);
-+	  &pxor		($Xhi,$T2);		#
-+	&pclmulqdq	($Xhn,$Hkey,0x11);	#######
-+	&movups		($Hkey,&QWP(16,$Htbl));	# load H^2
-+	  &pxor		($T2,$Xi);
-+	  &psrlq	($Xi,5);
-+	  &pxor		($Xi,$T2);		#
-+	  &psrlq	($Xi,1);		#
-+	  &pxor		($Xi,$Xhi)		#
-+	&pclmulqdq	($T1,$T3,0x00);		#######
-+
-+	&lea		($inp,&DWP(32,$inp));
-+	&sub		($len,0x20);
-+	&ja		(&label("mod_loop"));
-+
-+&set_label("even_tail");
-+	&pshufd		($T2,$Xi,0b01001110);	# H^2*(Ii+Xi)
-+	&movdqa		($Xhi,$Xi);
-+	&pxor		($T2,$Xi);		#
-+
-+	&pclmulqdq	($Xi,$Hkey,0x00);	#######
-+	&pclmulqdq	($Xhi,$Hkey,0x11);	#######
-+	&pclmulqdq	($T2,$T3,0x10);		#######
-+	&movdqa		($T3,&QWP(0,$const));
-+
-+	&xorps		($Xi,$Xn);		# (H*Ii+1) + H^2*(Ii+Xi)
-+	&xorps		($Xhi,$Xhn);
-+	&pxor		($T1,$Xi);		# aggregated Karatsuba post-processing
-+	&pxor		($T1,$Xhi);		#
-+
-+	&pxor		($T2,$T1);		#
-+
-+	&movdqa		($T1,$T2);		#
-+	&psrldq		($T2,8);
-+	&pslldq		($T1,8);		#
-+	&pxor		($Xhi,$T2);
-+	&pxor		($Xi,$T1);		#
-+
-+	&reduction_alg9	($Xhi,$Xi);
-+
-+	&test		($len,$len);
-+	&jnz		(&label("done"));
-+
-+	&movups		($Hkey,&QWP(0,$Htbl));	# load H
-+&set_label("odd_tail");
-+	&movdqu		($T1,&QWP(0,$inp));	# Ii
-+	&pshufb		($T1,$T3);
-+	&pxor		($Xi,$T1);		# Ii+Xi
-+
-+	&clmul64x64_T2	($Xhi,$Xi,$Hkey);	# H*(Ii+Xi)
-+	&reduction_alg9	($Xhi,$Xi);
-+
-+&set_label("done");
-+	&pshufb		($Xi,$T3);
-+	&movdqu		(&QWP(0,$Xip),$Xi);
-+&function_end("gcm_ghash_clmul");
-+
-+} else {		# Algorithm 5. Kept for reference purposes.
-+
-+sub reduction_alg5 {	# 19/16 times faster than Intel version
-+my ($Xhi,$Xi)=@_;
-+
-+	# <<1
-+	&movdqa		($T1,$Xi);		#
-+	&movdqa		($T2,$Xhi);
-+	&pslld		($Xi,1);
-+	&pslld		($Xhi,1);		#
-+	&psrld		($T1,31);
-+	&psrld		($T2,31);		#
-+	&movdqa		($T3,$T1);
-+	&pslldq		($T1,4);
-+	&psrldq		($T3,12);		#
-+	&pslldq		($T2,4);
-+	&por		($Xhi,$T3);		#
-+	&por		($Xi,$T1);
-+	&por		($Xhi,$T2);		#
-+
-+	# 1st phase
-+	&movdqa		($T1,$Xi);
-+	&movdqa		($T2,$Xi);
-+	&movdqa		($T3,$Xi);		#
-+	&pslld		($T1,31);
-+	&pslld		($T2,30);
-+	&pslld		($Xi,25);		#
-+	&pxor		($T1,$T2);
-+	&pxor		($T1,$Xi);		#
-+	&movdqa		($T2,$T1);		#
-+	&pslldq		($T1,12);
-+	&psrldq		($T2,4);		#
-+	&pxor		($T3,$T1);
-+
-+	# 2nd phase
-+	&pxor		($Xhi,$T3);		#
-+	&movdqa		($Xi,$T3);
-+	&movdqa		($T1,$T3);
-+	&psrld		($Xi,1);		#
-+	&psrld		($T1,2);
-+	&psrld		($T3,7);		#
-+	&pxor		($Xi,$T1);
-+	&pxor		($Xhi,$T2);
-+	&pxor		($Xi,$T3);		#
-+	&pxor		($Xi,$Xhi);		#
-+}
-+
-+&function_begin_B("gcm_init_clmul");
-+	&mov		($Htbl,&wparam(0));
-+	&mov		($Xip,&wparam(1));
-+
-+	&call		(&label("pic"));
-+&set_label("pic");
-+	&blindpop	($const);
-+	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
-+
-+	&movdqu		($Hkey,&QWP(0,$Xip));
-+	&pshufd		($Hkey,$Hkey,0b01001110);# dword swap
-+
-+	# calculate H^2
-+	&movdqa		($Xi,$Hkey);
-+	&clmul64x64_T3	($Xhi,$Xi,$Hkey);
-+	&reduction_alg5	($Xhi,$Xi);
-+
-+	&movdqu		(&QWP(0,$Htbl),$Hkey);	# save H
-+	&movdqu		(&QWP(16,$Htbl),$Xi);	# save H^2
-+
-+	&ret		();
-+&function_end_B("gcm_init_clmul");
-+
-+&function_begin_B("gcm_gmult_clmul");
-+	&mov		($Xip,&wparam(0));
-+	&mov		($Htbl,&wparam(1));
-+
-+	&call		(&label("pic"));
-+&set_label("pic");
-+	&blindpop	($const);
-+	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
-+
-+	&movdqu		($Xi,&QWP(0,$Xip));
-+	&movdqa		($Xn,&QWP(0,$const));
-+	&movdqu		($Hkey,&QWP(0,$Htbl));
-+	&pshufb		($Xi,$Xn);
-+
-+	&clmul64x64_T3	($Xhi,$Xi,$Hkey);
-+	&reduction_alg5	($Xhi,$Xi);
-+
-+	&pshufb		($Xi,$Xn);
-+	&movdqu		(&QWP(0,$Xip),$Xi);
-+
-+	&ret	();
-+&function_end_B("gcm_gmult_clmul");
-+
-+&function_begin("gcm_ghash_clmul");
-+	&mov		($Xip,&wparam(0));
-+	&mov		($Htbl,&wparam(1));
-+	&mov		($inp,&wparam(2));
-+	&mov		($len,&wparam(3));
-+
-+	&call		(&label("pic"));
-+&set_label("pic");
-+	&blindpop	($const);
-+	&lea		($const,&DWP(&label("bswap")."-".&label("pic"),$const));
-+
-+	&movdqu		($Xi,&QWP(0,$Xip));
-+	&movdqa		($T3,&QWP(0,$const));
-+	&movdqu		($Hkey,&QWP(0,$Htbl));
-+	&pshufb		($Xi,$T3);
-+
-+	&sub		($len,0x10);
-+	&jz		(&label("odd_tail"));
-+
-+	#######
-+	# Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
-+	#	[(H*Ii+1) + (H*Xi+1)] mod P =
-+	#	[(H*Ii+1) + H^2*(Ii+Xi)] mod P
-+	#
-+	&movdqu		($T1,&QWP(0,$inp));	# Ii
-+	&movdqu		($Xn,&QWP(16,$inp));	# Ii+1
-+	&pshufb		($T1,$T3);
-+	&pshufb		($Xn,$T3);
-+	&pxor		($Xi,$T1);		# Ii+Xi
-+
-+	&clmul64x64_T3	($Xhn,$Xn,$Hkey);	# H*Ii+1
-+	&movdqu		($Hkey,&QWP(16,$Htbl));	# load H^2
-+
-+	&sub		($len,0x20);
-+	&lea		($inp,&DWP(32,$inp));	# i+=2
-+	&jbe		(&label("even_tail"));
-+
-+&set_label("mod_loop");
-+	&clmul64x64_T3	($Xhi,$Xi,$Hkey);	# H^2*(Ii+Xi)
-+	&movdqu		($Hkey,&QWP(0,$Htbl));	# load H
-+
-+	&pxor		($Xi,$Xn);		# (H*Ii+1) + H^2*(Ii+Xi)
-+	&pxor		($Xhi,$Xhn);
-+
-+	&reduction_alg5	($Xhi,$Xi);
-+
-+	#######
-+	&movdqa		($T3,&QWP(0,$const));
-+	&movdqu		($T1,&QWP(0,$inp));	# Ii
-+	&movdqu		($Xn,&QWP(16,$inp));	# Ii+1
-+	&pshufb		($T1,$T3);
-+	&pshufb		($Xn,$T3);
-+	&pxor		($Xi,$T1);		# Ii+Xi
-+
-+	&clmul64x64_T3	($Xhn,$Xn,$Hkey);	# H*Ii+1
-+	&movdqu		($Hkey,&QWP(16,$Htbl));	# load H^2
-+
-+	&sub		($len,0x20);
-+	&lea		($inp,&DWP(32,$inp));
-+	&ja		(&label("mod_loop"));
-+
-+&set_label("even_tail");
-+	&clmul64x64_T3	($Xhi,$Xi,$Hkey);	# H^2*(Ii+Xi)
-+
-+	&pxor		($Xi,$Xn);		# (H*Ii+1) + H^2*(Ii+Xi)
-+	&pxor		($Xhi,$Xhn);
-+
-+	&reduction_alg5	($Xhi,$Xi);
-+
-+	&movdqa		($T3,&QWP(0,$const));
-+	&test		($len,$len);
-+	&jnz		(&label("done"));
-+
-+	&movdqu		($Hkey,&QWP(0,$Htbl));	# load H
-+&set_label("odd_tail");
-+	&movdqu		($T1,&QWP(0,$inp));	# Ii
-+	&pshufb		($T1,$T3);
-+	&pxor		($Xi,$T1);		# Ii+Xi
-+
-+	&clmul64x64_T3	($Xhi,$Xi,$Hkey);	# H*(Ii+Xi)
-+	&reduction_alg5	($Xhi,$Xi);
-+
-+	&movdqa		($T3,&QWP(0,$const));
-+&set_label("done");
-+	&pshufb		($Xi,$T3);
-+	&movdqu		(&QWP(0,$Xip),$Xi);
-+&function_end("gcm_ghash_clmul");
-+
-+}
-+
-+&set_label("bswap",64);
-+	&data_byte(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
-+	&data_byte(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2);	# 0x1c2_polynomial
-+&set_label("rem_8bit",64);
-+	&data_short(0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E);
-+	&data_short(0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E);
-+	&data_short(0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E);
-+	&data_short(0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E);
-+	&data_short(0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E);
-+	&data_short(0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E);
-+	&data_short(0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E);
-+	&data_short(0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E);
-+	&data_short(0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE);
-+	&data_short(0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE);
-+	&data_short(0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE);
-+	&data_short(0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE);
-+	&data_short(0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E);
-+	&data_short(0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E);
-+	&data_short(0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE);
-+	&data_short(0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE);
-+	&data_short(0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E);
-+	&data_short(0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E);
-+	&data_short(0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E);
-+	&data_short(0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E);
-+	&data_short(0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E);
-+	&data_short(0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E);
-+	&data_short(0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E);
-+	&data_short(0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E);
-+	&data_short(0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE);
-+	&data_short(0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE);
-+	&data_short(0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE);
-+	&data_short(0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE);
-+	&data_short(0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E);
-+	&data_short(0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E);
-+	&data_short(0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE);
-+	&data_short(0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE);
-+}}	# $sse2
-+
-+&set_label("rem_4bit",64);
-+	&data_word(0,0x0000<<$S,0,0x1C20<<$S,0,0x3840<<$S,0,0x2460<<$S);
-+	&data_word(0,0x7080<<$S,0,0x6CA0<<$S,0,0x48C0<<$S,0,0x54E0<<$S);
-+	&data_word(0,0xE100<<$S,0,0xFD20<<$S,0,0xD940<<$S,0,0xC560<<$S);
-+	&data_word(0,0x9180<<$S,0,0x8DA0<<$S,0,0xA9C0<<$S,0,0xB5E0<<$S);
-+}}}	# !$x86only
-+
-+&asciz("GHASH for x86, CRYPTOGAMS by ");
-+&asm_finish();
-+
-+close STDOUT;
-+
-+# A question was risen about choice of vanilla MMX. Or rather why wasn't
-+# SSE2 chosen instead? In addition to the fact that MMX runs on legacy
-+# CPUs such as PIII, "4-bit" MMX version was observed to provide better
-+# performance than *corresponding* SSE2 one even on contemporary CPUs.
-+# SSE2 results were provided by Peter-Michael Hager. He maintains SSE2
-+# implementation featuring full range of lookup-table sizes, but with
-+# per-invocation lookup table setup. Latter means that table size is
-+# chosen depending on how much data is to be hashed in every given call,
-+# more data - larger table. Best reported result for Core2 is ~4 cycles
-+# per processed byte out of 64KB block. This number accounts even for
-+# 64KB table setup overhead. As discussed in gcm128.c we choose to be
-+# more conservative in respect to lookup table sizes, but how do the
-+# results compare? Minimalistic "256B" MMX version delivers ~11 cycles
-+# on same platform. As also discussed in gcm128.c, next in line "8-bit
-+# Shoup's" or "4KB" method should deliver twice the performance of
-+# "256B" one, in other words not worse than ~6 cycles per byte. It
-+# should be also be noted that in SSE2 case improvement can be "super-
-+# linear," i.e. more than twice, mostly because >>8 maps to single
-+# instruction on SSE2 register. This is unlike "4-bit" case when >>4
-+# maps to same amount of instructions in both MMX and SSE2 cases.
-+# Bottom line is that switch to SSE2 is considered to be justifiable
-+# only in case we choose to implement "8-bit" method...
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-x86_64.pl
-new file mode 100644
-index 0000000..387e3f8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghash-x86_64.pl
-@@ -0,0 +1,1762 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# March, June 2010
-+#
-+# The module implements "4-bit" GCM GHASH function and underlying
-+# single multiplication operation in GF(2^128). "4-bit" means that
-+# it uses 256 bytes per-key table [+128 bytes shared table]. GHASH
-+# function features so called "528B" variant utilizing additional
-+# 256+16 bytes of per-key storage [+512 bytes shared table].
-+# Performance results are for this streamed GHASH subroutine and are
-+# expressed in cycles per processed byte, less is better:
-+#
-+#		gcc 3.4.x(*)	assembler
-+#
-+# P4		28.6		14.0		+100%
-+# Opteron	19.3		7.7		+150%
-+# Core2		17.8		8.1(**)		+120%
-+# Atom		31.6		16.8		+88%
-+# VIA Nano	21.8		10.1		+115%
-+#
-+# (*)	comparison is not completely fair, because C results are
-+#	for vanilla "256B" implementation, while assembler results
-+#	are for "528B";-)
-+# (**)	it's mystery [to me] why Core2 result is not same as for
-+#	Opteron;
-+
-+# May 2010
-+#
-+# Add PCLMULQDQ version performing at 2.02 cycles per processed byte.
-+# See ghash-x86.pl for background information and details about coding
-+# techniques.
-+#
-+# Special thanks to David Woodhouse  for
-+# providing access to a Westmere-based system on behalf of Intel
-+# Open Source Technology Centre.
-+
-+# December 2012
-+#
-+# Overhaul: aggregate Karatsuba post-processing, improve ILP in
-+# reduction_alg9, increase reduction aggregate factor to 4x. As for
-+# the latter. ghash-x86.pl discusses that it makes lesser sense to
-+# increase aggregate factor. Then why increase here? Critical path
-+# consists of 3 independent pclmulqdq instructions, Karatsuba post-
-+# processing and reduction. "On top" of this we lay down aggregated
-+# multiplication operations, triplets of independent pclmulqdq's. As
-+# issue rate for pclmulqdq is limited, it makes lesser sense to
-+# aggregate more multiplications than it takes to perform remaining
-+# non-multiplication operations. 2x is near-optimal coefficient for
-+# contemporary Intel CPUs (therefore modest improvement coefficient),
-+# but not for Bulldozer. Latter is because logical SIMD operations
-+# are twice as slow in comparison to Intel, so that critical path is
-+# longer. A CPU with higher pclmulqdq issue rate would also benefit
-+# from higher aggregate factor...
-+#
-+# Westmere	1.78(+13%)
-+# Sandy Bridge	1.80(+8%)
-+# Ivy Bridge	1.80(+7%)
-+# Haswell	0.55(+93%) (if system doesn't support AVX)
-+# Broadwell	0.45(+110%)(if system doesn't support AVX)
-+# Skylake	0.44(+110%)(if system doesn't support AVX)
-+# Bulldozer	1.49(+27%)
-+# Silvermont	2.88(+13%)
-+# Goldmont	1.08(+24%)
-+
-+# March 2013
-+#
-+# ... 8x aggregate factor AVX code path is using reduction algorithm
-+# suggested by Shay Gueron[1]. Even though contemporary AVX-capable
-+# CPUs such as Sandy and Ivy Bridge can execute it, the code performs
-+# sub-optimally in comparison to above mentioned version. But thanks
-+# to Ilya Albrekht and Max Locktyukhin of Intel Corp. we knew that
-+# it performs in 0.41 cycles per byte on Haswell processor, in
-+# 0.29 on Broadwell, and in 0.36 on Skylake.
-+#
-+# [1] http://rt.openssl.org/Ticket/Display.html?id=2900&user=guest&pass=guest
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.20) + ($1>=2.22);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	    `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	    `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+$do4xaggr=1;
-+
-+# common register layout
-+$nlo="%rax";
-+$nhi="%rbx";
-+$Zlo="%r8";
-+$Zhi="%r9";
-+$tmp="%r10";
-+$rem_4bit = "%r11";
-+
-+$Xi="%rdi";
-+$Htbl="%rsi";
-+
-+# per-function register layout
-+$cnt="%rcx";
-+$rem="%rdx";
-+
-+sub LB() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/	or
-+			$r =~ s/%[er]([sd]i)/%\1l/	or
-+			$r =~ s/%[er](bp)/%\1l/		or
-+			$r =~ s/%(r[0-9]+)[d]?/%\1b/;   $r; }
-+
-+sub AUTOLOAD()		# thunk [simplified] 32-bit style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
-+  my $arg = pop;
-+    $arg = "\$$arg" if ($arg*1 eq $arg);
-+    $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
-+}
-+
-+{ my $N;
-+  sub loop() {
-+  my $inp = shift;
-+
-+	$N++;
-+$code.=<<___;
-+	xor	$nlo,$nlo
-+	xor	$nhi,$nhi
-+	mov	`&LB("$Zlo")`,`&LB("$nlo")`
-+	mov	`&LB("$Zlo")`,`&LB("$nhi")`
-+	shl	\$4,`&LB("$nlo")`
-+	mov	\$14,$cnt
-+	mov	8($Htbl,$nlo),$Zlo
-+	mov	($Htbl,$nlo),$Zhi
-+	and	\$0xf0,`&LB("$nhi")`
-+	mov	$Zlo,$rem
-+	jmp	.Loop$N
-+
-+.align	16
-+.Loop$N:
-+	shr	\$4,$Zlo
-+	and	\$0xf,$rem
-+	mov	$Zhi,$tmp
-+	mov	($inp,$cnt),`&LB("$nlo")`
-+	shr	\$4,$Zhi
-+	xor	8($Htbl,$nhi),$Zlo
-+	shl	\$60,$tmp
-+	xor	($Htbl,$nhi),$Zhi
-+	mov	`&LB("$nlo")`,`&LB("$nhi")`
-+	xor	($rem_4bit,$rem,8),$Zhi
-+	mov	$Zlo,$rem
-+	shl	\$4,`&LB("$nlo")`
-+	xor	$tmp,$Zlo
-+	dec	$cnt
-+	js	.Lbreak$N
-+
-+	shr	\$4,$Zlo
-+	and	\$0xf,$rem
-+	mov	$Zhi,$tmp
-+	shr	\$4,$Zhi
-+	xor	8($Htbl,$nlo),$Zlo
-+	shl	\$60,$tmp
-+	xor	($Htbl,$nlo),$Zhi
-+	and	\$0xf0,`&LB("$nhi")`
-+	xor	($rem_4bit,$rem,8),$Zhi
-+	mov	$Zlo,$rem
-+	xor	$tmp,$Zlo
-+	jmp	.Loop$N
-+
-+.align	16
-+.Lbreak$N:
-+	shr	\$4,$Zlo
-+	and	\$0xf,$rem
-+	mov	$Zhi,$tmp
-+	shr	\$4,$Zhi
-+	xor	8($Htbl,$nlo),$Zlo
-+	shl	\$60,$tmp
-+	xor	($Htbl,$nlo),$Zhi
-+	and	\$0xf0,`&LB("$nhi")`
-+	xor	($rem_4bit,$rem,8),$Zhi
-+	mov	$Zlo,$rem
-+	xor	$tmp,$Zlo
-+
-+	shr	\$4,$Zlo
-+	and	\$0xf,$rem
-+	mov	$Zhi,$tmp
-+	shr	\$4,$Zhi
-+	xor	8($Htbl,$nhi),$Zlo
-+	shl	\$60,$tmp
-+	xor	($Htbl,$nhi),$Zhi
-+	xor	$tmp,$Zlo
-+	xor	($rem_4bit,$rem,8),$Zhi
-+
-+	bswap	$Zlo
-+	bswap	$Zhi
-+___
-+}}
-+
-+$code=<<___;
-+.text
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	gcm_gmult_4bit
-+.type	gcm_gmult_4bit,\@function,2
-+.align	16
-+gcm_gmult_4bit:
-+	push	%rbx
-+	push	%rbp		# %rbp and %r12 are pushed exclusively in
-+	push	%r12		# order to reuse Win64 exception handler...
-+.Lgmult_prologue:
-+
-+	movzb	15($Xi),$Zlo
-+	lea	.Lrem_4bit(%rip),$rem_4bit
-+___
-+	&loop	($Xi);
-+$code.=<<___;
-+	mov	$Zlo,8($Xi)
-+	mov	$Zhi,($Xi)
-+
-+	mov	16(%rsp),%rbx
-+	lea	24(%rsp),%rsp
-+.Lgmult_epilogue:
-+	ret
-+.size	gcm_gmult_4bit,.-gcm_gmult_4bit
-+___
-+
-+# per-function register layout
-+$inp="%rdx";
-+$len="%rcx";
-+$rem_8bit=$rem_4bit;
-+
-+$code.=<<___;
-+.globl	gcm_ghash_4bit
-+.type	gcm_ghash_4bit,\@function,4
-+.align	16
-+gcm_ghash_4bit:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	sub	\$280,%rsp
-+.Lghash_prologue:
-+	mov	$inp,%r14		# reassign couple of args
-+	mov	$len,%r15
-+___
-+{ my $inp="%r14";
-+  my $dat="%edx";
-+  my $len="%r15";
-+  my @nhi=("%ebx","%ecx");
-+  my @rem=("%r12","%r13");
-+  my $Hshr4="%rbp";
-+
-+	&sub	($Htbl,-128);		# size optimization
-+	&lea	($Hshr4,"16+128(%rsp)");
-+	{ my @lo =($nlo,$nhi);
-+          my @hi =($Zlo,$Zhi);
-+
-+	  &xor	($dat,$dat);
-+	  for ($i=0,$j=-2;$i<18;$i++,$j++) {
-+	    &mov	("$j(%rsp)",&LB($dat))		if ($i>1);
-+	    &or		($lo[0],$tmp)			if ($i>1);
-+	    &mov	(&LB($dat),&LB($lo[1]))		if ($i>0 && $i<17);
-+	    &shr	($lo[1],4)			if ($i>0 && $i<17);
-+	    &mov	($tmp,$hi[1])			if ($i>0 && $i<17);
-+	    &shr	($hi[1],4)			if ($i>0 && $i<17);
-+	    &mov	("8*$j($Hshr4)",$hi[0])		if ($i>1);
-+	    &mov	($hi[0],"16*$i+0-128($Htbl)")	if ($i<16);
-+	    &shl	(&LB($dat),4)			if ($i>0 && $i<17);
-+	    &mov	("8*$j-128($Hshr4)",$lo[0])	if ($i>1);
-+	    &mov	($lo[0],"16*$i+8-128($Htbl)")	if ($i<16);
-+	    &shl	($tmp,60)			if ($i>0 && $i<17);
-+
-+	    push	(@lo,shift(@lo));
-+	    push	(@hi,shift(@hi));
-+	  }
-+	}
-+	&add	($Htbl,-128);
-+	&mov	($Zlo,"8($Xi)");
-+	&mov	($Zhi,"0($Xi)");
-+	&add	($len,$inp);		# pointer to the end of data
-+	&lea	($rem_8bit,".Lrem_8bit(%rip)");
-+	&jmp	(".Louter_loop");
-+
-+$code.=".align	16\n.Louter_loop:\n";
-+	&xor	($Zhi,"($inp)");
-+	&mov	("%rdx","8($inp)");
-+	&lea	($inp,"16($inp)");
-+	&xor	("%rdx",$Zlo);
-+	&mov	("($Xi)",$Zhi);
-+	&mov	("8($Xi)","%rdx");
-+	&shr	("%rdx",32);
-+
-+	&xor	($nlo,$nlo);
-+	&rol	($dat,8);
-+	&mov	(&LB($nlo),&LB($dat));
-+	&movz	($nhi[0],&LB($dat));
-+	&shl	(&LB($nlo),4);
-+	&shr	($nhi[0],4);
-+
-+	for ($j=11,$i=0;$i<15;$i++) {
-+	    &rol	($dat,8);
-+	    &xor	($Zlo,"8($Htbl,$nlo)")			if ($i>0);
-+	    &xor	($Zhi,"($Htbl,$nlo)")			if ($i>0);
-+	    &mov	($Zlo,"8($Htbl,$nlo)")			if ($i==0);
-+	    &mov	($Zhi,"($Htbl,$nlo)")			if ($i==0);
-+
-+	    &mov	(&LB($nlo),&LB($dat));
-+	    &xor	($Zlo,$tmp)				if ($i>0);
-+	    &movzw	($rem[1],"($rem_8bit,$rem[1],2)")	if ($i>0);
-+
-+	    &movz	($nhi[1],&LB($dat));
-+	    &shl	(&LB($nlo),4);
-+	    &movzb	($rem[0],"(%rsp,$nhi[0])");
-+
-+	    &shr	($nhi[1],4)				if ($i<14);
-+	    &and	($nhi[1],0xf0)				if ($i==14);
-+	    &shl	($rem[1],48)				if ($i>0);
-+	    &xor	($rem[0],$Zlo);
-+
-+	    &mov	($tmp,$Zhi);
-+	    &xor	($Zhi,$rem[1])				if ($i>0);
-+	    &shr	($Zlo,8);
-+
-+	    &movz	($rem[0],&LB($rem[0]));
-+	    &mov	($dat,"$j($Xi)")			if (--$j%4==0);
-+	    &shr	($Zhi,8);
-+
-+	    &xor	($Zlo,"-128($Hshr4,$nhi[0],8)");
-+	    &shl	($tmp,56);
-+	    &xor	($Zhi,"($Hshr4,$nhi[0],8)");
-+
-+	    unshift	(@nhi,pop(@nhi));		# "rotate" registers
-+	    unshift	(@rem,pop(@rem));
-+	}
-+	&movzw	($rem[1],"($rem_8bit,$rem[1],2)");
-+	&xor	($Zlo,"8($Htbl,$nlo)");
-+	&xor	($Zhi,"($Htbl,$nlo)");
-+
-+	&shl	($rem[1],48);
-+	&xor	($Zlo,$tmp);
-+
-+	&xor	($Zhi,$rem[1]);
-+	&movz	($rem[0],&LB($Zlo));
-+	&shr	($Zlo,4);
-+
-+	&mov	($tmp,$Zhi);
-+	&shl	(&LB($rem[0]),4);
-+	&shr	($Zhi,4);
-+
-+	&xor	($Zlo,"8($Htbl,$nhi[0])");
-+	&movzw	($rem[0],"($rem_8bit,$rem[0],2)");
-+	&shl	($tmp,60);
-+
-+	&xor	($Zhi,"($Htbl,$nhi[0])");
-+	&xor	($Zlo,$tmp);
-+	&shl	($rem[0],48);
-+
-+	&bswap	($Zlo);
-+	&xor	($Zhi,$rem[0]);
-+
-+	&bswap	($Zhi);
-+	&cmp	($inp,$len);
-+	&jb	(".Louter_loop");
-+}
-+$code.=<<___;
-+	mov	$Zlo,8($Xi)
-+	mov	$Zhi,($Xi)
-+
-+	lea	280(%rsp),%rsi
-+	mov	0(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lghash_epilogue:
-+	ret
-+.size	gcm_ghash_4bit,.-gcm_ghash_4bit
-+___
-+
-+######################################################################
-+# PCLMULQDQ version.
-+
-+@_4args=$win64?	("%rcx","%rdx","%r8", "%r9") :	# Win64 order
-+		("%rdi","%rsi","%rdx","%rcx");	# Unix order
-+
-+($Xi,$Xhi)=("%xmm0","%xmm1");	$Hkey="%xmm2";
-+($T1,$T2,$T3)=("%xmm3","%xmm4","%xmm5");
-+
-+sub clmul64x64_T2 {	# minimal register pressure
-+my ($Xhi,$Xi,$Hkey,$HK)=@_;
-+
-+if (!defined($HK)) {	$HK = $T2;
-+$code.=<<___;
-+	movdqa		$Xi,$Xhi		#
-+	pshufd		\$0b01001110,$Xi,$T1
-+	pshufd		\$0b01001110,$Hkey,$T2
-+	pxor		$Xi,$T1			#
-+	pxor		$Hkey,$T2
-+___
-+} else {
-+$code.=<<___;
-+	movdqa		$Xi,$Xhi		#
-+	pshufd		\$0b01001110,$Xi,$T1
-+	pxor		$Xi,$T1			#
-+___
-+}
-+$code.=<<___;
-+	pclmulqdq	\$0x00,$Hkey,$Xi	#######
-+	pclmulqdq	\$0x11,$Hkey,$Xhi	#######
-+	pclmulqdq	\$0x00,$HK,$T1		#######
-+	pxor		$Xi,$T1			#
-+	pxor		$Xhi,$T1		#
-+
-+	movdqa		$T1,$T2			#
-+	psrldq		\$8,$T1
-+	pslldq		\$8,$T2			#
-+	pxor		$T1,$Xhi
-+	pxor		$T2,$Xi			#
-+___
-+}
-+
-+sub reduction_alg9 {	# 17/11 times faster than Intel version
-+my ($Xhi,$Xi) = @_;
-+
-+$code.=<<___;
-+	# 1st phase
-+	movdqa		$Xi,$T2			#
-+	movdqa		$Xi,$T1
-+	psllq		\$5,$Xi
-+	pxor		$Xi,$T1			#
-+	psllq		\$1,$Xi
-+	pxor		$T1,$Xi			#
-+	psllq		\$57,$Xi		#
-+	movdqa		$Xi,$T1			#
-+	pslldq		\$8,$Xi
-+	psrldq		\$8,$T1			#	
-+	pxor		$T2,$Xi
-+	pxor		$T1,$Xhi		#
-+
-+	# 2nd phase
-+	movdqa		$Xi,$T2
-+	psrlq		\$1,$Xi
-+	pxor		$T2,$Xhi		#
-+	pxor		$Xi,$T2
-+	psrlq		\$5,$Xi
-+	pxor		$T2,$Xi			#
-+	psrlq		\$1,$Xi			#
-+	pxor		$Xhi,$Xi		#
-+___
-+}
-+
-+{ my ($Htbl,$Xip)=@_4args;
-+  my $HK="%xmm6";
-+
-+$code.=<<___;
-+.globl	gcm_init_clmul
-+.type	gcm_init_clmul,\@abi-omnipotent
-+.align	16
-+gcm_init_clmul:
-+.L_init_clmul:
-+___
-+$code.=<<___ if ($win64);
-+.LSEH_begin_gcm_init_clmul:
-+	# I can't trust assembler to use specific encoding:-(
-+	.byte	0x48,0x83,0xec,0x18		#sub	$0x18,%rsp
-+	.byte	0x0f,0x29,0x34,0x24		#movaps	%xmm6,(%rsp)
-+___
-+$code.=<<___;
-+	movdqu		($Xip),$Hkey
-+	pshufd		\$0b01001110,$Hkey,$Hkey	# dword swap
-+
-+	# <<1 twist
-+	pshufd		\$0b11111111,$Hkey,$T2	# broadcast uppermost dword
-+	movdqa		$Hkey,$T1
-+	psllq		\$1,$Hkey
-+	pxor		$T3,$T3			#
-+	psrlq		\$63,$T1
-+	pcmpgtd		$T2,$T3			# broadcast carry bit
-+	pslldq		\$8,$T1
-+	por		$T1,$Hkey		# H<<=1
-+
-+	# magic reduction
-+	pand		.L0x1c2_polynomial(%rip),$T3
-+	pxor		$T3,$Hkey		# if(carry) H^=0x1c2_polynomial
-+
-+	# calculate H^2
-+	pshufd		\$0b01001110,$Hkey,$HK
-+	movdqa		$Hkey,$Xi
-+	pxor		$Hkey,$HK
-+___
-+	&clmul64x64_T2	($Xhi,$Xi,$Hkey,$HK);
-+	&reduction_alg9	($Xhi,$Xi);
-+$code.=<<___;
-+	pshufd		\$0b01001110,$Hkey,$T1
-+	pshufd		\$0b01001110,$Xi,$T2
-+	pxor		$Hkey,$T1		# Karatsuba pre-processing
-+	movdqu		$Hkey,0x00($Htbl)	# save H
-+	pxor		$Xi,$T2			# Karatsuba pre-processing
-+	movdqu		$Xi,0x10($Htbl)		# save H^2
-+	palignr		\$8,$T1,$T2		# low part is H.lo^H.hi...
-+	movdqu		$T2,0x20($Htbl)		# save Karatsuba "salt"
-+___
-+if ($do4xaggr) {
-+	&clmul64x64_T2	($Xhi,$Xi,$Hkey,$HK);	# H^3
-+	&reduction_alg9	($Xhi,$Xi);
-+$code.=<<___;
-+	movdqa		$Xi,$T3
-+___
-+	&clmul64x64_T2	($Xhi,$Xi,$Hkey,$HK);	# H^4
-+	&reduction_alg9	($Xhi,$Xi);
-+$code.=<<___;
-+	pshufd		\$0b01001110,$T3,$T1
-+	pshufd		\$0b01001110,$Xi,$T2
-+	pxor		$T3,$T1			# Karatsuba pre-processing
-+	movdqu		$T3,0x30($Htbl)		# save H^3
-+	pxor		$Xi,$T2			# Karatsuba pre-processing
-+	movdqu		$Xi,0x40($Htbl)		# save H^4
-+	palignr		\$8,$T1,$T2		# low part is H^3.lo^H^3.hi...
-+	movdqu		$T2,0x50($Htbl)		# save Karatsuba "salt"
-+___
-+}
-+$code.=<<___ if ($win64);
-+	movaps	(%rsp),%xmm6
-+	lea	0x18(%rsp),%rsp
-+.LSEH_end_gcm_init_clmul:
-+___
-+$code.=<<___;
-+	ret
-+.size	gcm_init_clmul,.-gcm_init_clmul
-+___
-+}
-+
-+{ my ($Xip,$Htbl)=@_4args;
-+
-+$code.=<<___;
-+.globl	gcm_gmult_clmul
-+.type	gcm_gmult_clmul,\@abi-omnipotent
-+.align	16
-+gcm_gmult_clmul:
-+.L_gmult_clmul:
-+	movdqu		($Xip),$Xi
-+	movdqa		.Lbswap_mask(%rip),$T3
-+	movdqu		($Htbl),$Hkey
-+	movdqu		0x20($Htbl),$T2
-+	pshufb		$T3,$Xi
-+___
-+	&clmul64x64_T2	($Xhi,$Xi,$Hkey,$T2);
-+$code.=<<___ if (0 || (&reduction_alg9($Xhi,$Xi)&&0));
-+	# experimental alternative. special thing about is that there
-+	# no dependency between the two multiplications... 
-+	mov		\$`0xE1<<1`,%eax
-+	mov		\$0xA040608020C0E000,%r10	# ((7..0)·0xE0)&0xff
-+	mov		\$0x07,%r11d
-+	movq		%rax,$T1
-+	movq		%r10,$T2
-+	movq		%r11,$T3		# borrow $T3
-+	pand		$Xi,$T3
-+	pshufb		$T3,$T2			# ($Xi&7)·0xE0
-+	movq		%rax,$T3
-+	pclmulqdq	\$0x00,$Xi,$T1		# ·(0xE1<<1)
-+	pxor		$Xi,$T2
-+	pslldq		\$15,$T2
-+	paddd		$T2,$T2			# <<(64+56+1)
-+	pxor		$T2,$Xi
-+	pclmulqdq	\$0x01,$T3,$Xi
-+	movdqa		.Lbswap_mask(%rip),$T3	# reload $T3
-+	psrldq		\$1,$T1
-+	pxor		$T1,$Xhi
-+	pslldq		\$7,$Xi
-+	pxor		$Xhi,$Xi
-+___
-+$code.=<<___;
-+	pshufb		$T3,$Xi
-+	movdqu		$Xi,($Xip)
-+	ret
-+.size	gcm_gmult_clmul,.-gcm_gmult_clmul
-+___
-+}
-+
-+{ my ($Xip,$Htbl,$inp,$len)=@_4args;
-+  my ($Xln,$Xmn,$Xhn,$Hkey2,$HK) = map("%xmm$_",(3..7));
-+  my ($T1,$T2,$T3)=map("%xmm$_",(8..10));
-+
-+$code.=<<___;
-+.globl	gcm_ghash_clmul
-+.type	gcm_ghash_clmul,\@abi-omnipotent
-+.align	32
-+gcm_ghash_clmul:
-+.L_ghash_clmul:
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0x88(%rsp),%rax
-+.LSEH_begin_gcm_ghash_clmul:
-+	# I can't trust assembler to use specific encoding:-(
-+	.byte	0x48,0x8d,0x60,0xe0		#lea	-0x20(%rax),%rsp
-+	.byte	0x0f,0x29,0x70,0xe0		#movaps	%xmm6,-0x20(%rax)
-+	.byte	0x0f,0x29,0x78,0xf0		#movaps	%xmm7,-0x10(%rax)
-+	.byte	0x44,0x0f,0x29,0x00		#movaps	%xmm8,0(%rax)
-+	.byte	0x44,0x0f,0x29,0x48,0x10	#movaps	%xmm9,0x10(%rax)
-+	.byte	0x44,0x0f,0x29,0x50,0x20	#movaps	%xmm10,0x20(%rax)
-+	.byte	0x44,0x0f,0x29,0x58,0x30	#movaps	%xmm11,0x30(%rax)
-+	.byte	0x44,0x0f,0x29,0x60,0x40	#movaps	%xmm12,0x40(%rax)
-+	.byte	0x44,0x0f,0x29,0x68,0x50	#movaps	%xmm13,0x50(%rax)
-+	.byte	0x44,0x0f,0x29,0x70,0x60	#movaps	%xmm14,0x60(%rax)
-+	.byte	0x44,0x0f,0x29,0x78,0x70	#movaps	%xmm15,0x70(%rax)
-+___
-+$code.=<<___;
-+	movdqa		.Lbswap_mask(%rip),$T3
-+
-+	movdqu		($Xip),$Xi
-+	movdqu		($Htbl),$Hkey
-+	movdqu		0x20($Htbl),$HK
-+	pshufb		$T3,$Xi
-+
-+	sub		\$0x10,$len
-+	jz		.Lodd_tail
-+
-+	movdqu		0x10($Htbl),$Hkey2
-+___
-+if ($do4xaggr) {
-+my ($Xl,$Xm,$Xh,$Hkey3,$Hkey4)=map("%xmm$_",(11..15));
-+
-+$code.=<<___;
-+	mov		OPENSSL_ia32cap_P+4(%rip),%eax
-+	cmp		\$0x30,$len
-+	jb		.Lskip4x
-+
-+	and		\$`1<<26|1<<22`,%eax	# isolate MOVBE+XSAVE
-+	cmp		\$`1<<22`,%eax		# check for MOVBE without XSAVE
-+	je		.Lskip4x
-+
-+	sub		\$0x30,$len
-+	mov		\$0xA040608020C0E000,%rax	# ((7..0)·0xE0)&0xff
-+	movdqu		0x30($Htbl),$Hkey3
-+	movdqu		0x40($Htbl),$Hkey4
-+
-+	#######
-+	# Xi+4 =[(H*Ii+3) + (H^2*Ii+2) + (H^3*Ii+1) + H^4*(Ii+Xi)] mod P
-+	#
-+	movdqu		0x30($inp),$Xln
-+	 movdqu		0x20($inp),$Xl
-+	pshufb		$T3,$Xln
-+	 pshufb		$T3,$Xl
-+	movdqa		$Xln,$Xhn
-+	pshufd		\$0b01001110,$Xln,$Xmn
-+	pxor		$Xln,$Xmn
-+	pclmulqdq	\$0x00,$Hkey,$Xln
-+	pclmulqdq	\$0x11,$Hkey,$Xhn
-+	pclmulqdq	\$0x00,$HK,$Xmn
-+
-+	movdqa		$Xl,$Xh
-+	pshufd		\$0b01001110,$Xl,$Xm
-+	pxor		$Xl,$Xm
-+	pclmulqdq	\$0x00,$Hkey2,$Xl
-+	pclmulqdq	\$0x11,$Hkey2,$Xh
-+	pclmulqdq	\$0x10,$HK,$Xm
-+	xorps		$Xl,$Xln
-+	xorps		$Xh,$Xhn
-+	movups		0x50($Htbl),$HK
-+	xorps		$Xm,$Xmn
-+
-+	movdqu		0x10($inp),$Xl
-+	 movdqu		0($inp),$T1
-+	pshufb		$T3,$Xl
-+	 pshufb		$T3,$T1
-+	movdqa		$Xl,$Xh
-+	pshufd		\$0b01001110,$Xl,$Xm
-+	 pxor		$T1,$Xi
-+	pxor		$Xl,$Xm
-+	pclmulqdq	\$0x00,$Hkey3,$Xl
-+	 movdqa		$Xi,$Xhi
-+	 pshufd		\$0b01001110,$Xi,$T1
-+	 pxor		$Xi,$T1
-+	pclmulqdq	\$0x11,$Hkey3,$Xh
-+	pclmulqdq	\$0x00,$HK,$Xm
-+	xorps		$Xl,$Xln
-+	xorps		$Xh,$Xhn
-+
-+	lea	0x40($inp),$inp
-+	sub	\$0x40,$len
-+	jc	.Ltail4x
-+
-+	jmp	.Lmod4_loop
-+.align	32
-+.Lmod4_loop:
-+	pclmulqdq	\$0x00,$Hkey4,$Xi
-+	xorps		$Xm,$Xmn
-+	 movdqu		0x30($inp),$Xl
-+	 pshufb		$T3,$Xl
-+	pclmulqdq	\$0x11,$Hkey4,$Xhi
-+	xorps		$Xln,$Xi
-+	 movdqu		0x20($inp),$Xln
-+	 movdqa		$Xl,$Xh
-+	pclmulqdq	\$0x10,$HK,$T1
-+	 pshufd		\$0b01001110,$Xl,$Xm
-+	xorps		$Xhn,$Xhi
-+	 pxor		$Xl,$Xm
-+	 pshufb		$T3,$Xln
-+	movups		0x20($Htbl),$HK
-+	xorps		$Xmn,$T1
-+	 pclmulqdq	\$0x00,$Hkey,$Xl
-+	 pshufd		\$0b01001110,$Xln,$Xmn
-+
-+	pxor		$Xi,$T1			# aggregated Karatsuba post-processing
-+	 movdqa		$Xln,$Xhn
-+	pxor		$Xhi,$T1		#
-+	 pxor		$Xln,$Xmn
-+	movdqa		$T1,$T2			#
-+	 pclmulqdq	\$0x11,$Hkey,$Xh
-+	pslldq		\$8,$T1
-+	psrldq		\$8,$T2			#
-+	pxor		$T1,$Xi
-+	movdqa		.L7_mask(%rip),$T1
-+	pxor		$T2,$Xhi		#
-+	movq		%rax,$T2
-+
-+	pand		$Xi,$T1			# 1st phase
-+	pshufb		$T1,$T2			#
-+	pxor		$Xi,$T2			#
-+	 pclmulqdq	\$0x00,$HK,$Xm
-+	psllq		\$57,$T2		#
-+	movdqa		$T2,$T1			#
-+	pslldq		\$8,$T2
-+	 pclmulqdq	\$0x00,$Hkey2,$Xln
-+	psrldq		\$8,$T1			#	
-+	pxor		$T2,$Xi
-+	pxor		$T1,$Xhi		#
-+	movdqu		0($inp),$T1
-+
-+	movdqa		$Xi,$T2			# 2nd phase
-+	psrlq		\$1,$Xi
-+	 pclmulqdq	\$0x11,$Hkey2,$Xhn
-+	 xorps		$Xl,$Xln
-+	 movdqu		0x10($inp),$Xl
-+	 pshufb		$T3,$Xl
-+	 pclmulqdq	\$0x10,$HK,$Xmn
-+	 xorps		$Xh,$Xhn
-+	 movups		0x50($Htbl),$HK
-+	pshufb		$T3,$T1
-+	pxor		$T2,$Xhi		#
-+	pxor		$Xi,$T2
-+	psrlq		\$5,$Xi
-+
-+	 movdqa		$Xl,$Xh
-+	 pxor		$Xm,$Xmn
-+	 pshufd		\$0b01001110,$Xl,$Xm
-+	pxor		$T2,$Xi			#
-+	pxor		$T1,$Xhi
-+	 pxor		$Xl,$Xm
-+	 pclmulqdq	\$0x00,$Hkey3,$Xl
-+	psrlq		\$1,$Xi			#
-+	pxor		$Xhi,$Xi		#
-+	movdqa		$Xi,$Xhi
-+	 pclmulqdq	\$0x11,$Hkey3,$Xh
-+	 xorps		$Xl,$Xln
-+	pshufd		\$0b01001110,$Xi,$T1
-+	pxor		$Xi,$T1
-+
-+	 pclmulqdq	\$0x00,$HK,$Xm
-+	 xorps		$Xh,$Xhn
-+
-+	lea	0x40($inp),$inp
-+	sub	\$0x40,$len
-+	jnc	.Lmod4_loop
-+
-+.Ltail4x:
-+	pclmulqdq	\$0x00,$Hkey4,$Xi
-+	pclmulqdq	\$0x11,$Hkey4,$Xhi
-+	pclmulqdq	\$0x10,$HK,$T1
-+	xorps		$Xm,$Xmn
-+	xorps		$Xln,$Xi
-+	xorps		$Xhn,$Xhi
-+	pxor		$Xi,$Xhi		# aggregated Karatsuba post-processing
-+	pxor		$Xmn,$T1
-+
-+	pxor		$Xhi,$T1		#
-+	pxor		$Xi,$Xhi
-+
-+	movdqa		$T1,$T2			#
-+	psrldq		\$8,$T1
-+	pslldq		\$8,$T2			#
-+	pxor		$T1,$Xhi
-+	pxor		$T2,$Xi			#
-+___
-+	&reduction_alg9($Xhi,$Xi);
-+$code.=<<___;
-+	add	\$0x40,$len
-+	jz	.Ldone
-+	movdqu	0x20($Htbl),$HK
-+	sub	\$0x10,$len
-+	jz	.Lodd_tail
-+.Lskip4x:
-+___
-+}
-+$code.=<<___;
-+	#######
-+	# Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
-+	#	[(H*Ii+1) + (H*Xi+1)] mod P =
-+	#	[(H*Ii+1) + H^2*(Ii+Xi)] mod P
-+	#
-+	movdqu		($inp),$T1		# Ii
-+	movdqu		16($inp),$Xln		# Ii+1
-+	pshufb		$T3,$T1
-+	pshufb		$T3,$Xln
-+	pxor		$T1,$Xi			# Ii+Xi
-+
-+	movdqa		$Xln,$Xhn
-+	pshufd		\$0b01001110,$Xln,$Xmn
-+	pxor		$Xln,$Xmn
-+	pclmulqdq	\$0x00,$Hkey,$Xln
-+	pclmulqdq	\$0x11,$Hkey,$Xhn
-+	pclmulqdq	\$0x00,$HK,$Xmn
-+
-+	lea		32($inp),$inp		# i+=2
-+	nop
-+	sub		\$0x20,$len
-+	jbe		.Leven_tail
-+	nop
-+	jmp		.Lmod_loop
-+
-+.align	32
-+.Lmod_loop:
-+	movdqa		$Xi,$Xhi
-+	movdqa		$Xmn,$T1
-+	pshufd		\$0b01001110,$Xi,$Xmn	#
-+	pxor		$Xi,$Xmn		#
-+
-+	pclmulqdq	\$0x00,$Hkey2,$Xi
-+	pclmulqdq	\$0x11,$Hkey2,$Xhi
-+	pclmulqdq	\$0x10,$HK,$Xmn
-+
-+	pxor		$Xln,$Xi		# (H*Ii+1) + H^2*(Ii+Xi)
-+	pxor		$Xhn,$Xhi
-+	  movdqu	($inp),$T2		# Ii
-+	pxor		$Xi,$T1			# aggregated Karatsuba post-processing
-+	  pshufb	$T3,$T2
-+	  movdqu	16($inp),$Xln		# Ii+1
-+
-+	pxor		$Xhi,$T1
-+	  pxor		$T2,$Xhi		# "Ii+Xi", consume early
-+	pxor		$T1,$Xmn
-+	 pshufb		$T3,$Xln
-+	movdqa		$Xmn,$T1		#
-+	psrldq		\$8,$T1
-+	pslldq		\$8,$Xmn		#
-+	pxor		$T1,$Xhi
-+	pxor		$Xmn,$Xi		#
-+
-+	movdqa		$Xln,$Xhn		#
-+
-+	  movdqa	$Xi,$T2			# 1st phase
-+	  movdqa	$Xi,$T1
-+	  psllq		\$5,$Xi
-+	  pxor		$Xi,$T1			#
-+	pclmulqdq	\$0x00,$Hkey,$Xln	#######
-+	  psllq		\$1,$Xi
-+	  pxor		$T1,$Xi			#
-+	  psllq		\$57,$Xi		#
-+	  movdqa	$Xi,$T1			#
-+	  pslldq	\$8,$Xi
-+	  psrldq	\$8,$T1			#	
-+	  pxor		$T2,$Xi
-+	pshufd		\$0b01001110,$Xhn,$Xmn
-+	  pxor		$T1,$Xhi		#
-+	pxor		$Xhn,$Xmn		#
-+
-+	  movdqa	$Xi,$T2			# 2nd phase
-+	  psrlq		\$1,$Xi
-+	pclmulqdq	\$0x11,$Hkey,$Xhn	#######
-+	  pxor		$T2,$Xhi		#
-+	  pxor		$Xi,$T2
-+	  psrlq		\$5,$Xi
-+	  pxor		$T2,$Xi			#
-+	lea		32($inp),$inp
-+	  psrlq		\$1,$Xi			#
-+	pclmulqdq	\$0x00,$HK,$Xmn		#######
-+	  pxor		$Xhi,$Xi		#
-+
-+	sub		\$0x20,$len
-+	ja		.Lmod_loop
-+
-+.Leven_tail:
-+	 movdqa		$Xi,$Xhi
-+	 movdqa		$Xmn,$T1
-+	 pshufd		\$0b01001110,$Xi,$Xmn	#
-+	 pxor		$Xi,$Xmn		#
-+
-+	pclmulqdq	\$0x00,$Hkey2,$Xi
-+	pclmulqdq	\$0x11,$Hkey2,$Xhi
-+	pclmulqdq	\$0x10,$HK,$Xmn
-+
-+	pxor		$Xln,$Xi		# (H*Ii+1) + H^2*(Ii+Xi)
-+	pxor		$Xhn,$Xhi
-+	pxor		$Xi,$T1
-+	pxor		$Xhi,$T1
-+	pxor		$T1,$Xmn
-+	movdqa		$Xmn,$T1		#
-+	psrldq		\$8,$T1
-+	pslldq		\$8,$Xmn		#
-+	pxor		$T1,$Xhi
-+	pxor		$Xmn,$Xi		#
-+___
-+	&reduction_alg9	($Xhi,$Xi);
-+$code.=<<___;
-+	test		$len,$len
-+	jnz		.Ldone
-+
-+.Lodd_tail:
-+	movdqu		($inp),$T1		# Ii
-+	pshufb		$T3,$T1
-+	pxor		$T1,$Xi			# Ii+Xi
-+___
-+	&clmul64x64_T2	($Xhi,$Xi,$Hkey,$HK);	# H*(Ii+Xi)
-+	&reduction_alg9	($Xhi,$Xi);
-+$code.=<<___;
-+.Ldone:
-+	pshufb		$T3,$Xi
-+	movdqu		$Xi,($Xip)
-+___
-+$code.=<<___ if ($win64);
-+	movaps	(%rsp),%xmm6
-+	movaps	0x10(%rsp),%xmm7
-+	movaps	0x20(%rsp),%xmm8
-+	movaps	0x30(%rsp),%xmm9
-+	movaps	0x40(%rsp),%xmm10
-+	movaps	0x50(%rsp),%xmm11
-+	movaps	0x60(%rsp),%xmm12
-+	movaps	0x70(%rsp),%xmm13
-+	movaps	0x80(%rsp),%xmm14
-+	movaps	0x90(%rsp),%xmm15
-+	lea	0xa8(%rsp),%rsp
-+.LSEH_end_gcm_ghash_clmul:
-+___
-+$code.=<<___;
-+	ret
-+.size	gcm_ghash_clmul,.-gcm_ghash_clmul
-+___
-+}
-+
-+$code.=<<___;
-+.globl	gcm_init_avx
-+.type	gcm_init_avx,\@abi-omnipotent
-+.align	32
-+gcm_init_avx:
-+___
-+if ($avx) {
-+my ($Htbl,$Xip)=@_4args;
-+my $HK="%xmm6";
-+
-+$code.=<<___ if ($win64);
-+.LSEH_begin_gcm_init_avx:
-+	# I can't trust assembler to use specific encoding:-(
-+	.byte	0x48,0x83,0xec,0x18		#sub	$0x18,%rsp
-+	.byte	0x0f,0x29,0x34,0x24		#movaps	%xmm6,(%rsp)
-+___
-+$code.=<<___;
-+	vzeroupper
-+
-+	vmovdqu		($Xip),$Hkey
-+	vpshufd		\$0b01001110,$Hkey,$Hkey	# dword swap
-+
-+	# <<1 twist
-+	vpshufd		\$0b11111111,$Hkey,$T2	# broadcast uppermost dword
-+	vpsrlq		\$63,$Hkey,$T1
-+	vpsllq		\$1,$Hkey,$Hkey
-+	vpxor		$T3,$T3,$T3		#
-+	vpcmpgtd	$T2,$T3,$T3		# broadcast carry bit
-+	vpslldq		\$8,$T1,$T1
-+	vpor		$T1,$Hkey,$Hkey		# H<<=1
-+
-+	# magic reduction
-+	vpand		.L0x1c2_polynomial(%rip),$T3,$T3
-+	vpxor		$T3,$Hkey,$Hkey		# if(carry) H^=0x1c2_polynomial
-+
-+	vpunpckhqdq	$Hkey,$Hkey,$HK
-+	vmovdqa		$Hkey,$Xi
-+	vpxor		$Hkey,$HK,$HK
-+	mov		\$4,%r10		# up to H^8
-+	jmp		.Linit_start_avx
-+___
-+
-+sub clmul64x64_avx {
-+my ($Xhi,$Xi,$Hkey,$HK)=@_;
-+
-+if (!defined($HK)) {	$HK = $T2;
-+$code.=<<___;
-+	vpunpckhqdq	$Xi,$Xi,$T1
-+	vpunpckhqdq	$Hkey,$Hkey,$T2
-+	vpxor		$Xi,$T1,$T1		#
-+	vpxor		$Hkey,$T2,$T2
-+___
-+} else {
-+$code.=<<___;
-+	vpunpckhqdq	$Xi,$Xi,$T1
-+	vpxor		$Xi,$T1,$T1		#
-+___
-+}
-+$code.=<<___;
-+	vpclmulqdq	\$0x11,$Hkey,$Xi,$Xhi	#######
-+	vpclmulqdq	\$0x00,$Hkey,$Xi,$Xi	#######
-+	vpclmulqdq	\$0x00,$HK,$T1,$T1	#######
-+	vpxor		$Xi,$Xhi,$T2		#
-+	vpxor		$T2,$T1,$T1		#
-+
-+	vpslldq		\$8,$T1,$T2		#
-+	vpsrldq		\$8,$T1,$T1
-+	vpxor		$T2,$Xi,$Xi		#
-+	vpxor		$T1,$Xhi,$Xhi
-+___
-+}
-+
-+sub reduction_avx {
-+my ($Xhi,$Xi) = @_;
-+
-+$code.=<<___;
-+	vpsllq		\$57,$Xi,$T1		# 1st phase
-+	vpsllq		\$62,$Xi,$T2
-+	vpxor		$T1,$T2,$T2		#
-+	vpsllq		\$63,$Xi,$T1
-+	vpxor		$T1,$T2,$T2		#
-+	vpslldq		\$8,$T2,$T1		#
-+	vpsrldq		\$8,$T2,$T2
-+	vpxor		$T1,$Xi,$Xi		#
-+	vpxor		$T2,$Xhi,$Xhi
-+
-+	vpsrlq		\$1,$Xi,$T2		# 2nd phase
-+	vpxor		$Xi,$Xhi,$Xhi
-+	vpxor		$T2,$Xi,$Xi		#
-+	vpsrlq		\$5,$T2,$T2
-+	vpxor		$T2,$Xi,$Xi		#
-+	vpsrlq		\$1,$Xi,$Xi		#
-+	vpxor		$Xhi,$Xi,$Xi		#
-+___
-+}
-+
-+$code.=<<___;
-+.align	32
-+.Linit_loop_avx:
-+	vpalignr	\$8,$T1,$T2,$T3		# low part is H.lo^H.hi...
-+	vmovdqu		$T3,-0x10($Htbl)	# save Karatsuba "salt"
-+___
-+	&clmul64x64_avx	($Xhi,$Xi,$Hkey,$HK);	# calculate H^3,5,7
-+	&reduction_avx	($Xhi,$Xi);
-+$code.=<<___;
-+.Linit_start_avx:
-+	vmovdqa		$Xi,$T3
-+___
-+	&clmul64x64_avx	($Xhi,$Xi,$Hkey,$HK);	# calculate H^2,4,6,8
-+	&reduction_avx	($Xhi,$Xi);
-+$code.=<<___;
-+	vpshufd		\$0b01001110,$T3,$T1
-+	vpshufd		\$0b01001110,$Xi,$T2
-+	vpxor		$T3,$T1,$T1		# Karatsuba pre-processing
-+	vmovdqu		$T3,0x00($Htbl)		# save H^1,3,5,7
-+	vpxor		$Xi,$T2,$T2		# Karatsuba pre-processing
-+	vmovdqu		$Xi,0x10($Htbl)		# save H^2,4,6,8
-+	lea		0x30($Htbl),$Htbl
-+	sub		\$1,%r10
-+	jnz		.Linit_loop_avx
-+
-+	vpalignr	\$8,$T2,$T1,$T3		# last "salt" is flipped
-+	vmovdqu		$T3,-0x10($Htbl)
-+
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	(%rsp),%xmm6
-+	lea	0x18(%rsp),%rsp
-+.LSEH_end_gcm_init_avx:
-+___
-+$code.=<<___;
-+	ret
-+.size	gcm_init_avx,.-gcm_init_avx
-+___
-+} else {
-+$code.=<<___;
-+	jmp	.L_init_clmul
-+.size	gcm_init_avx,.-gcm_init_avx
-+___
-+}
-+
-+$code.=<<___;
-+.globl	gcm_gmult_avx
-+.type	gcm_gmult_avx,\@abi-omnipotent
-+.align	32
-+gcm_gmult_avx:
-+	jmp	.L_gmult_clmul
-+.size	gcm_gmult_avx,.-gcm_gmult_avx
-+___
-+
-+$code.=<<___;
-+.globl	gcm_ghash_avx
-+.type	gcm_ghash_avx,\@abi-omnipotent
-+.align	32
-+gcm_ghash_avx:
-+___
-+if ($avx) {
-+my ($Xip,$Htbl,$inp,$len)=@_4args;
-+my ($Xlo,$Xhi,$Xmi,
-+    $Zlo,$Zhi,$Zmi,
-+    $Hkey,$HK,$T1,$T2,
-+    $Xi,$Xo,$Tred,$bswap,$Ii,$Ij) = map("%xmm$_",(0..15));
-+
-+$code.=<<___ if ($win64);
-+	lea	-0x88(%rsp),%rax
-+.LSEH_begin_gcm_ghash_avx:
-+	# I can't trust assembler to use specific encoding:-(
-+	.byte	0x48,0x8d,0x60,0xe0		#lea	-0x20(%rax),%rsp
-+	.byte	0x0f,0x29,0x70,0xe0		#movaps	%xmm6,-0x20(%rax)
-+	.byte	0x0f,0x29,0x78,0xf0		#movaps	%xmm7,-0x10(%rax)
-+	.byte	0x44,0x0f,0x29,0x00		#movaps	%xmm8,0(%rax)
-+	.byte	0x44,0x0f,0x29,0x48,0x10	#movaps	%xmm9,0x10(%rax)
-+	.byte	0x44,0x0f,0x29,0x50,0x20	#movaps	%xmm10,0x20(%rax)
-+	.byte	0x44,0x0f,0x29,0x58,0x30	#movaps	%xmm11,0x30(%rax)
-+	.byte	0x44,0x0f,0x29,0x60,0x40	#movaps	%xmm12,0x40(%rax)
-+	.byte	0x44,0x0f,0x29,0x68,0x50	#movaps	%xmm13,0x50(%rax)
-+	.byte	0x44,0x0f,0x29,0x70,0x60	#movaps	%xmm14,0x60(%rax)
-+	.byte	0x44,0x0f,0x29,0x78,0x70	#movaps	%xmm15,0x70(%rax)
-+___
-+$code.=<<___;
-+	vzeroupper
-+
-+	vmovdqu		($Xip),$Xi		# load $Xi
-+	lea		.L0x1c2_polynomial(%rip),%r10
-+	lea		0x40($Htbl),$Htbl	# size optimization
-+	vmovdqu		.Lbswap_mask(%rip),$bswap
-+	vpshufb		$bswap,$Xi,$Xi
-+	cmp		\$0x80,$len
-+	jb		.Lshort_avx
-+	sub		\$0x80,$len
-+
-+	vmovdqu		0x70($inp),$Ii		# I[7]
-+	vmovdqu		0x00-0x40($Htbl),$Hkey	# $Hkey^1
-+	vpshufb		$bswap,$Ii,$Ii
-+	vmovdqu		0x20-0x40($Htbl),$HK
-+
-+	vpunpckhqdq	$Ii,$Ii,$T2
-+	 vmovdqu	0x60($inp),$Ij		# I[6]
-+	vpclmulqdq	\$0x00,$Hkey,$Ii,$Xlo
-+	vpxor		$Ii,$T2,$T2
-+	 vpshufb	$bswap,$Ij,$Ij
-+	vpclmulqdq	\$0x11,$Hkey,$Ii,$Xhi
-+	 vmovdqu	0x10-0x40($Htbl),$Hkey	# $Hkey^2
-+	 vpunpckhqdq	$Ij,$Ij,$T1
-+	 vmovdqu	0x50($inp),$Ii		# I[5]
-+	vpclmulqdq	\$0x00,$HK,$T2,$Xmi
-+	 vpxor		$Ij,$T1,$T1
-+
-+	 vpshufb	$bswap,$Ii,$Ii
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Zlo
-+	 vpunpckhqdq	$Ii,$Ii,$T2
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Zhi
-+	 vmovdqu	0x30-0x40($Htbl),$Hkey	# $Hkey^3
-+	 vpxor		$Ii,$T2,$T2
-+	 vmovdqu	0x40($inp),$Ij		# I[4]
-+	vpclmulqdq	\$0x10,$HK,$T1,$Zmi
-+	 vmovdqu	0x50-0x40($Htbl),$HK
-+
-+	 vpshufb	$bswap,$Ij,$Ij
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ii,$Xlo
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	 vpunpckhqdq	$Ij,$Ij,$T1
-+	vpclmulqdq	\$0x11,$Hkey,$Ii,$Xhi
-+	 vmovdqu	0x40-0x40($Htbl),$Hkey	# $Hkey^4
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	vpclmulqdq	\$0x00,$HK,$T2,$Xmi
-+	 vpxor		$Ij,$T1,$T1
-+
-+	 vmovdqu	0x30($inp),$Ii		# I[3]
-+	vpxor		$Zlo,$Xlo,$Xlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Zlo
-+	vpxor		$Zhi,$Xhi,$Xhi
-+	 vpshufb	$bswap,$Ii,$Ii
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Zhi
-+	 vmovdqu	0x60-0x40($Htbl),$Hkey	# $Hkey^5
-+	vpxor		$Zmi,$Xmi,$Xmi
-+	 vpunpckhqdq	$Ii,$Ii,$T2
-+	vpclmulqdq	\$0x10,$HK,$T1,$Zmi
-+	 vmovdqu	0x80-0x40($Htbl),$HK
-+	 vpxor		$Ii,$T2,$T2
-+
-+	 vmovdqu	0x20($inp),$Ij		# I[2]
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ii,$Xlo
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	 vpshufb	$bswap,$Ij,$Ij
-+	vpclmulqdq	\$0x11,$Hkey,$Ii,$Xhi
-+	 vmovdqu	0x70-0x40($Htbl),$Hkey	# $Hkey^6
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	 vpunpckhqdq	$Ij,$Ij,$T1
-+	vpclmulqdq	\$0x00,$HK,$T2,$Xmi
-+	 vpxor		$Ij,$T1,$T1
-+
-+	 vmovdqu	0x10($inp),$Ii		# I[1]
-+	vpxor		$Zlo,$Xlo,$Xlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Zlo
-+	vpxor		$Zhi,$Xhi,$Xhi
-+	 vpshufb	$bswap,$Ii,$Ii
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Zhi
-+	 vmovdqu	0x90-0x40($Htbl),$Hkey	# $Hkey^7
-+	vpxor		$Zmi,$Xmi,$Xmi
-+	 vpunpckhqdq	$Ii,$Ii,$T2
-+	vpclmulqdq	\$0x10,$HK,$T1,$Zmi
-+	 vmovdqu	0xb0-0x40($Htbl),$HK
-+	 vpxor		$Ii,$T2,$T2
-+
-+	 vmovdqu	($inp),$Ij		# I[0]
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ii,$Xlo
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	 vpshufb	$bswap,$Ij,$Ij
-+	vpclmulqdq	\$0x11,$Hkey,$Ii,$Xhi
-+	 vmovdqu	0xa0-0x40($Htbl),$Hkey	# $Hkey^8
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	vpclmulqdq	\$0x10,$HK,$T2,$Xmi
-+
-+	lea		0x80($inp),$inp
-+	cmp		\$0x80,$len
-+	jb		.Ltail_avx
-+
-+	vpxor		$Xi,$Ij,$Ij		# accumulate $Xi
-+	sub		\$0x80,$len
-+	jmp		.Loop8x_avx
-+
-+.align	32
-+.Loop8x_avx:
-+	vpunpckhqdq	$Ij,$Ij,$T1
-+	 vmovdqu	0x70($inp),$Ii		# I[7]
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpxor		$Ij,$T1,$T1
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Xi
-+	 vpshufb	$bswap,$Ii,$Ii
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Xo
-+	 vmovdqu	0x00-0x40($Htbl),$Hkey	# $Hkey^1
-+	 vpunpckhqdq	$Ii,$Ii,$T2
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	vpclmulqdq	\$0x00,$HK,$T1,$Tred
-+	 vmovdqu	0x20-0x40($Htbl),$HK
-+	 vpxor		$Ii,$T2,$T2
-+
-+	  vmovdqu	0x60($inp),$Ij		# I[6]
-+	 vpclmulqdq	\$0x00,$Hkey,$Ii,$Xlo
-+	vpxor		$Zlo,$Xi,$Xi		# collect result
-+	  vpshufb	$bswap,$Ij,$Ij
-+	 vpclmulqdq	\$0x11,$Hkey,$Ii,$Xhi
-+	vxorps		$Zhi,$Xo,$Xo
-+	  vmovdqu	0x10-0x40($Htbl),$Hkey	# $Hkey^2
-+	 vpunpckhqdq	$Ij,$Ij,$T1
-+	 vpclmulqdq	\$0x00,$HK,  $T2,$Xmi
-+	vpxor		$Zmi,$Tred,$Tred
-+	 vxorps		$Ij,$T1,$T1
-+
-+	  vmovdqu	0x50($inp),$Ii		# I[5]
-+	vpxor		$Xi,$Tred,$Tred		# aggregated Karatsuba post-processing
-+	 vpclmulqdq	\$0x00,$Hkey,$Ij,$Zlo
-+	vpxor		$Xo,$Tred,$Tred
-+	vpslldq		\$8,$Tred,$T2
-+	 vpxor		$Xlo,$Zlo,$Zlo
-+	 vpclmulqdq	\$0x11,$Hkey,$Ij,$Zhi
-+	vpsrldq		\$8,$Tred,$Tred
-+	vpxor		$T2, $Xi, $Xi
-+	  vmovdqu	0x30-0x40($Htbl),$Hkey	# $Hkey^3
-+	  vpshufb	$bswap,$Ii,$Ii
-+	vxorps		$Tred,$Xo, $Xo
-+	 vpxor		$Xhi,$Zhi,$Zhi
-+	 vpunpckhqdq	$Ii,$Ii,$T2
-+	 vpclmulqdq	\$0x10,$HK,  $T1,$Zmi
-+	  vmovdqu	0x50-0x40($Htbl),$HK
-+	 vpxor		$Ii,$T2,$T2
-+	 vpxor		$Xmi,$Zmi,$Zmi
-+
-+	  vmovdqu	0x40($inp),$Ij		# I[4]
-+	vpalignr	\$8,$Xi,$Xi,$Tred	# 1st phase
-+	 vpclmulqdq	\$0x00,$Hkey,$Ii,$Xlo
-+	  vpshufb	$bswap,$Ij,$Ij
-+	 vpxor		$Zlo,$Xlo,$Xlo
-+	 vpclmulqdq	\$0x11,$Hkey,$Ii,$Xhi
-+	  vmovdqu	0x40-0x40($Htbl),$Hkey	# $Hkey^4
-+	 vpunpckhqdq	$Ij,$Ij,$T1
-+	 vpxor		$Zhi,$Xhi,$Xhi
-+	 vpclmulqdq	\$0x00,$HK,  $T2,$Xmi
-+	 vxorps		$Ij,$T1,$T1
-+	 vpxor		$Zmi,$Xmi,$Xmi
-+
-+	  vmovdqu	0x30($inp),$Ii		# I[3]
-+	vpclmulqdq	\$0x10,(%r10),$Xi,$Xi
-+	 vpclmulqdq	\$0x00,$Hkey,$Ij,$Zlo
-+	  vpshufb	$bswap,$Ii,$Ii
-+	 vpxor		$Xlo,$Zlo,$Zlo
-+	 vpclmulqdq	\$0x11,$Hkey,$Ij,$Zhi
-+	  vmovdqu	0x60-0x40($Htbl),$Hkey	# $Hkey^5
-+	 vpunpckhqdq	$Ii,$Ii,$T2
-+	 vpxor		$Xhi,$Zhi,$Zhi
-+	 vpclmulqdq	\$0x10,$HK,  $T1,$Zmi
-+	  vmovdqu	0x80-0x40($Htbl),$HK
-+	 vpxor		$Ii,$T2,$T2
-+	 vpxor		$Xmi,$Zmi,$Zmi
-+
-+	  vmovdqu	0x20($inp),$Ij		# I[2]
-+	 vpclmulqdq	\$0x00,$Hkey,$Ii,$Xlo
-+	  vpshufb	$bswap,$Ij,$Ij
-+	 vpxor		$Zlo,$Xlo,$Xlo
-+	 vpclmulqdq	\$0x11,$Hkey,$Ii,$Xhi
-+	  vmovdqu	0x70-0x40($Htbl),$Hkey	# $Hkey^6
-+	 vpunpckhqdq	$Ij,$Ij,$T1
-+	 vpxor		$Zhi,$Xhi,$Xhi
-+	 vpclmulqdq	\$0x00,$HK,  $T2,$Xmi
-+	 vpxor		$Ij,$T1,$T1
-+	 vpxor		$Zmi,$Xmi,$Xmi
-+	vxorps		$Tred,$Xi,$Xi
-+
-+	  vmovdqu	0x10($inp),$Ii		# I[1]
-+	vpalignr	\$8,$Xi,$Xi,$Tred	# 2nd phase
-+	 vpclmulqdq	\$0x00,$Hkey,$Ij,$Zlo
-+	  vpshufb	$bswap,$Ii,$Ii
-+	 vpxor		$Xlo,$Zlo,$Zlo
-+	 vpclmulqdq	\$0x11,$Hkey,$Ij,$Zhi
-+	  vmovdqu	0x90-0x40($Htbl),$Hkey	# $Hkey^7
-+	vpclmulqdq	\$0x10,(%r10),$Xi,$Xi
-+	vxorps		$Xo,$Tred,$Tred
-+	 vpunpckhqdq	$Ii,$Ii,$T2
-+	 vpxor		$Xhi,$Zhi,$Zhi
-+	 vpclmulqdq	\$0x10,$HK,  $T1,$Zmi
-+	  vmovdqu	0xb0-0x40($Htbl),$HK
-+	 vpxor		$Ii,$T2,$T2
-+	 vpxor		$Xmi,$Zmi,$Zmi
-+
-+	  vmovdqu	($inp),$Ij		# I[0]
-+	 vpclmulqdq	\$0x00,$Hkey,$Ii,$Xlo
-+	  vpshufb	$bswap,$Ij,$Ij
-+	 vpclmulqdq	\$0x11,$Hkey,$Ii,$Xhi
-+	  vmovdqu	0xa0-0x40($Htbl),$Hkey	# $Hkey^8
-+	vpxor		$Tred,$Ij,$Ij
-+	 vpclmulqdq	\$0x10,$HK,  $T2,$Xmi
-+	vpxor		$Xi,$Ij,$Ij		# accumulate $Xi
-+
-+	lea		0x80($inp),$inp
-+	sub		\$0x80,$len
-+	jnc		.Loop8x_avx
-+
-+	add		\$0x80,$len
-+	jmp		.Ltail_no_xor_avx
-+
-+.align	32
-+.Lshort_avx:
-+	vmovdqu		-0x10($inp,$len),$Ii	# very last word
-+	lea		($inp,$len),$inp
-+	vmovdqu		0x00-0x40($Htbl),$Hkey	# $Hkey^1
-+	vmovdqu		0x20-0x40($Htbl),$HK
-+	vpshufb		$bswap,$Ii,$Ij
-+
-+	vmovdqa		$Xlo,$Zlo		# subtle way to zero $Zlo,
-+	vmovdqa		$Xhi,$Zhi		# $Zhi and
-+	vmovdqa		$Xmi,$Zmi		# $Zmi
-+	sub		\$0x10,$len
-+	jz		.Ltail_avx
-+
-+	vpunpckhqdq	$Ij,$Ij,$T1
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Xlo
-+	vpxor		$Ij,$T1,$T1
-+	 vmovdqu	-0x20($inp),$Ii
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Xhi
-+	vmovdqu		0x10-0x40($Htbl),$Hkey	# $Hkey^2
-+	 vpshufb	$bswap,$Ii,$Ij
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	vpclmulqdq	\$0x00,$HK,$T1,$Xmi
-+	vpsrldq		\$8,$HK,$HK
-+	sub		\$0x10,$len
-+	jz		.Ltail_avx
-+
-+	vpunpckhqdq	$Ij,$Ij,$T1
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Xlo
-+	vpxor		$Ij,$T1,$T1
-+	 vmovdqu	-0x30($inp),$Ii
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Xhi
-+	vmovdqu		0x30-0x40($Htbl),$Hkey	# $Hkey^3
-+	 vpshufb	$bswap,$Ii,$Ij
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	vpclmulqdq	\$0x00,$HK,$T1,$Xmi
-+	vmovdqu		0x50-0x40($Htbl),$HK
-+	sub		\$0x10,$len
-+	jz		.Ltail_avx
-+
-+	vpunpckhqdq	$Ij,$Ij,$T1
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Xlo
-+	vpxor		$Ij,$T1,$T1
-+	 vmovdqu	-0x40($inp),$Ii
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Xhi
-+	vmovdqu		0x40-0x40($Htbl),$Hkey	# $Hkey^4
-+	 vpshufb	$bswap,$Ii,$Ij
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	vpclmulqdq	\$0x00,$HK,$T1,$Xmi
-+	vpsrldq		\$8,$HK,$HK
-+	sub		\$0x10,$len
-+	jz		.Ltail_avx
-+
-+	vpunpckhqdq	$Ij,$Ij,$T1
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Xlo
-+	vpxor		$Ij,$T1,$T1
-+	 vmovdqu	-0x50($inp),$Ii
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Xhi
-+	vmovdqu		0x60-0x40($Htbl),$Hkey	# $Hkey^5
-+	 vpshufb	$bswap,$Ii,$Ij
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	vpclmulqdq	\$0x00,$HK,$T1,$Xmi
-+	vmovdqu		0x80-0x40($Htbl),$HK
-+	sub		\$0x10,$len
-+	jz		.Ltail_avx
-+
-+	vpunpckhqdq	$Ij,$Ij,$T1
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Xlo
-+	vpxor		$Ij,$T1,$T1
-+	 vmovdqu	-0x60($inp),$Ii
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Xhi
-+	vmovdqu		0x70-0x40($Htbl),$Hkey	# $Hkey^6
-+	 vpshufb	$bswap,$Ii,$Ij
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	vpclmulqdq	\$0x00,$HK,$T1,$Xmi
-+	vpsrldq		\$8,$HK,$HK
-+	sub		\$0x10,$len
-+	jz		.Ltail_avx
-+
-+	vpunpckhqdq	$Ij,$Ij,$T1
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Xlo
-+	vpxor		$Ij,$T1,$T1
-+	 vmovdqu	-0x70($inp),$Ii
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Xhi
-+	vmovdqu		0x90-0x40($Htbl),$Hkey	# $Hkey^7
-+	 vpshufb	$bswap,$Ii,$Ij
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	vpclmulqdq	\$0x00,$HK,$T1,$Xmi
-+	vmovq		0xb8-0x40($Htbl),$HK
-+	sub		\$0x10,$len
-+	jmp		.Ltail_avx
-+
-+.align	32
-+.Ltail_avx:
-+	vpxor		$Xi,$Ij,$Ij		# accumulate $Xi
-+.Ltail_no_xor_avx:
-+	vpunpckhqdq	$Ij,$Ij,$T1
-+	vpxor		$Xlo,$Zlo,$Zlo
-+	vpclmulqdq	\$0x00,$Hkey,$Ij,$Xlo
-+	vpxor		$Ij,$T1,$T1
-+	vpxor		$Xhi,$Zhi,$Zhi
-+	vpclmulqdq	\$0x11,$Hkey,$Ij,$Xhi
-+	vpxor		$Xmi,$Zmi,$Zmi
-+	vpclmulqdq	\$0x00,$HK,$T1,$Xmi
-+
-+	vmovdqu		(%r10),$Tred
-+
-+	vpxor		$Xlo,$Zlo,$Xi
-+	vpxor		$Xhi,$Zhi,$Xo
-+	vpxor		$Xmi,$Zmi,$Zmi
-+
-+	vpxor		$Xi, $Zmi,$Zmi		# aggregated Karatsuba post-processing
-+	vpxor		$Xo, $Zmi,$Zmi
-+	vpslldq		\$8, $Zmi,$T2
-+	vpsrldq		\$8, $Zmi,$Zmi
-+	vpxor		$T2, $Xi, $Xi
-+	vpxor		$Zmi,$Xo, $Xo
-+
-+	vpclmulqdq	\$0x10,$Tred,$Xi,$T2	# 1st phase
-+	vpalignr	\$8,$Xi,$Xi,$Xi
-+	vpxor		$T2,$Xi,$Xi
-+
-+	vpclmulqdq	\$0x10,$Tred,$Xi,$T2	# 2nd phase
-+	vpalignr	\$8,$Xi,$Xi,$Xi
-+	vpxor		$Xo,$Xi,$Xi
-+	vpxor		$T2,$Xi,$Xi
-+
-+	cmp		\$0,$len
-+	jne		.Lshort_avx
-+
-+	vpshufb		$bswap,$Xi,$Xi
-+	vmovdqu		$Xi,($Xip)
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	(%rsp),%xmm6
-+	movaps	0x10(%rsp),%xmm7
-+	movaps	0x20(%rsp),%xmm8
-+	movaps	0x30(%rsp),%xmm9
-+	movaps	0x40(%rsp),%xmm10
-+	movaps	0x50(%rsp),%xmm11
-+	movaps	0x60(%rsp),%xmm12
-+	movaps	0x70(%rsp),%xmm13
-+	movaps	0x80(%rsp),%xmm14
-+	movaps	0x90(%rsp),%xmm15
-+	lea	0xa8(%rsp),%rsp
-+.LSEH_end_gcm_ghash_avx:
-+___
-+$code.=<<___;
-+	ret
-+.size	gcm_ghash_avx,.-gcm_ghash_avx
-+___
-+} else {
-+$code.=<<___;
-+	jmp	.L_ghash_clmul
-+.size	gcm_ghash_avx,.-gcm_ghash_avx
-+___
-+}
-+
-+$code.=<<___;
-+.align	64
-+.Lbswap_mask:
-+	.byte	15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
-+.L0x1c2_polynomial:
-+	.byte	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2
-+.L7_mask:
-+	.long	7,0,7,0
-+.L7_mask_poly:
-+	.long	7,0,`0xE1<<1`,0
-+.align	64
-+.type	.Lrem_4bit,\@object
-+.Lrem_4bit:
-+	.long	0,`0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`
-+	.long	0,`0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`
-+	.long	0,`0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`
-+	.long	0,`0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`
-+.type	.Lrem_8bit,\@object
-+.Lrem_8bit:
-+	.value	0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E
-+	.value	0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E
-+	.value	0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E
-+	.value	0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E
-+	.value	0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E
-+	.value	0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E
-+	.value	0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E
-+	.value	0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E
-+	.value	0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE
-+	.value	0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE
-+	.value	0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE
-+	.value	0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE
-+	.value	0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E
-+	.value	0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E
-+	.value	0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE
-+	.value	0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE
-+	.value	0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E
-+	.value	0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E
-+	.value	0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E
-+	.value	0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E
-+	.value	0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E
-+	.value	0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E
-+	.value	0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E
-+	.value	0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E
-+	.value	0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE
-+	.value	0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE
-+	.value	0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE
-+	.value	0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE
-+	.value	0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E
-+	.value	0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E
-+	.value	0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE
-+	.value	0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE
-+
-+.asciz	"GHASH for x86_64, CRYPTOGAMS by "
-+.align	64
-+___
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_prologue
-+
-+	lea	24(%rax),%rax		# adjust "rsp"
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_gcm_gmult_4bit
-+	.rva	.LSEH_end_gcm_gmult_4bit
-+	.rva	.LSEH_info_gcm_gmult_4bit
-+
-+	.rva	.LSEH_begin_gcm_ghash_4bit
-+	.rva	.LSEH_end_gcm_ghash_4bit
-+	.rva	.LSEH_info_gcm_ghash_4bit
-+
-+	.rva	.LSEH_begin_gcm_init_clmul
-+	.rva	.LSEH_end_gcm_init_clmul
-+	.rva	.LSEH_info_gcm_init_clmul
-+
-+	.rva	.LSEH_begin_gcm_ghash_clmul
-+	.rva	.LSEH_end_gcm_ghash_clmul
-+	.rva	.LSEH_info_gcm_ghash_clmul
-+___
-+$code.=<<___	if ($avx);
-+	.rva	.LSEH_begin_gcm_init_avx
-+	.rva	.LSEH_end_gcm_init_avx
-+	.rva	.LSEH_info_gcm_init_clmul
-+
-+	.rva	.LSEH_begin_gcm_ghash_avx
-+	.rva	.LSEH_end_gcm_ghash_avx
-+	.rva	.LSEH_info_gcm_ghash_clmul
-+___
-+$code.=<<___;
-+.section	.xdata
-+.align	8
-+.LSEH_info_gcm_gmult_4bit:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lgmult_prologue,.Lgmult_epilogue	# HandlerData
-+.LSEH_info_gcm_ghash_4bit:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lghash_prologue,.Lghash_epilogue	# HandlerData
-+.LSEH_info_gcm_init_clmul:
-+	.byte	0x01,0x08,0x03,0x00
-+	.byte	0x08,0x68,0x00,0x00	#movaps	0x00(rsp),xmm6
-+	.byte	0x04,0x22,0x00,0x00	#sub	rsp,0x18
-+.LSEH_info_gcm_ghash_clmul:
-+	.byte	0x01,0x33,0x16,0x00
-+	.byte	0x33,0xf8,0x09,0x00	#movaps 0x90(rsp),xmm15
-+	.byte	0x2e,0xe8,0x08,0x00	#movaps 0x80(rsp),xmm14
-+	.byte	0x29,0xd8,0x07,0x00	#movaps 0x70(rsp),xmm13
-+	.byte	0x24,0xc8,0x06,0x00	#movaps 0x60(rsp),xmm12
-+	.byte	0x1f,0xb8,0x05,0x00	#movaps 0x50(rsp),xmm11
-+	.byte	0x1a,0xa8,0x04,0x00	#movaps 0x40(rsp),xmm10
-+	.byte	0x15,0x98,0x03,0x00	#movaps 0x30(rsp),xmm9
-+	.byte	0x10,0x88,0x02,0x00	#movaps 0x20(rsp),xmm8
-+	.byte	0x0c,0x78,0x01,0x00	#movaps 0x10(rsp),xmm7
-+	.byte	0x08,0x68,0x00,0x00	#movaps 0x00(rsp),xmm6
-+	.byte	0x04,0x01,0x15,0x00	#sub	rsp,0xa8
-+___
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghashp8-ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghashp8-ppc.pl
-new file mode 100755
-index 0000000..f0598cb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghashp8-ppc.pl
-@@ -0,0 +1,670 @@
-+#! /usr/bin/env perl
-+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# GHASH for for PowerISA v2.07.
-+#
-+# July 2014
-+#
-+# Accurate performance measurements are problematic, because it's
-+# always virtualized setup with possibly throttled processor.
-+# Relative comparison is therefore more informative. This initial
-+# version is ~2.1x slower than hardware-assisted AES-128-CTR, ~12x
-+# faster than "4-bit" integer-only compiler-generated 64-bit code.
-+# "Initial version" means that there is room for futher improvement.
-+
-+# May 2016
-+#
-+# 2x aggregated reduction improves performance by 50% (resulting
-+# performance on POWER8 is 1 cycle per processed byte), and 4x
-+# aggregated reduction - by 170% or 2.7x (resulting in 0.55 cpb).
-+
-+$flavour=shift;
-+$output =shift;
-+
-+if ($flavour =~ /64/) {
-+	$SIZE_T=8;
-+	$LRSAVE=2*$SIZE_T;
-+	$STU="stdu";
-+	$POP="ld";
-+	$PUSH="std";
-+	$UCMP="cmpld";
-+	$SHRI="srdi";
-+} elsif ($flavour =~ /32/) {
-+	$SIZE_T=4;
-+	$LRSAVE=$SIZE_T;
-+	$STU="stwu";
-+	$POP="lwz";
-+	$PUSH="stw";
-+	$UCMP="cmplw";
-+	$SHRI="srwi";
-+} else { die "nonsense $flavour"; }
-+
-+$sp="r1";
-+$FRAME=6*$SIZE_T+13*16;	# 13*16 is for v20-v31 offload
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!";
-+
-+my ($Xip,$Htbl,$inp,$len)=map("r$_",(3..6));	# argument block
-+
-+my ($Xl,$Xm,$Xh,$IN)=map("v$_",(0..3));
-+my ($zero,$t0,$t1,$t2,$xC2,$H,$Hh,$Hl,$lemask)=map("v$_",(4..12));
-+my ($Xl1,$Xm1,$Xh1,$IN1,$H2,$H2h,$H2l)=map("v$_",(13..19));
-+my $vrsave="r12";
-+
-+$code=<<___;
-+.machine	"any"
-+
-+.text
-+
-+.globl	.gcm_init_p8
-+.align	5
-+.gcm_init_p8:
-+	li		r0,-4096
-+	li		r8,0x10
-+	mfspr		$vrsave,256
-+	li		r9,0x20
-+	mtspr		256,r0
-+	li		r10,0x30
-+	lvx_u		$H,0,r4			# load H
-+
-+	vspltisb	$xC2,-16		# 0xf0
-+	vspltisb	$t0,1			# one
-+	vaddubm		$xC2,$xC2,$xC2		# 0xe0
-+	vxor		$zero,$zero,$zero
-+	vor		$xC2,$xC2,$t0		# 0xe1
-+	vsldoi		$xC2,$xC2,$zero,15	# 0xe1...
-+	vsldoi		$t1,$zero,$t0,1		# ...1
-+	vaddubm		$xC2,$xC2,$xC2		# 0xc2...
-+	vspltisb	$t2,7
-+	vor		$xC2,$xC2,$t1		# 0xc2....01
-+	vspltb		$t1,$H,0		# most significant byte
-+	vsl		$H,$H,$t0		# H<<=1
-+	vsrab		$t1,$t1,$t2		# broadcast carry bit
-+	vand		$t1,$t1,$xC2
-+	vxor		$IN,$H,$t1		# twisted H
-+
-+	vsldoi		$H,$IN,$IN,8		# twist even more ...
-+	vsldoi		$xC2,$zero,$xC2,8	# 0xc2.0
-+	vsldoi		$Hl,$zero,$H,8		# ... and split
-+	vsldoi		$Hh,$H,$zero,8
-+
-+	stvx_u		$xC2,0,r3		# save pre-computed table
-+	stvx_u		$Hl,r8,r3
-+	li		r8,0x40
-+	stvx_u		$H, r9,r3
-+	li		r9,0x50
-+	stvx_u		$Hh,r10,r3
-+	li		r10,0x60
-+
-+	vpmsumd		$Xl,$IN,$Hl		# H.lo·H.lo
-+	vpmsumd		$Xm,$IN,$H		# H.hi·H.lo+H.lo·H.hi
-+	vpmsumd		$Xh,$IN,$Hh		# H.hi·H.hi
-+
-+	vpmsumd		$t2,$Xl,$xC2		# 1st reduction phase
-+
-+	vsldoi		$t0,$Xm,$zero,8
-+	vsldoi		$t1,$zero,$Xm,8
-+	vxor		$Xl,$Xl,$t0
-+	vxor		$Xh,$Xh,$t1
-+
-+	vsldoi		$Xl,$Xl,$Xl,8
-+	vxor		$Xl,$Xl,$t2
-+
-+	vsldoi		$t1,$Xl,$Xl,8		# 2nd reduction phase
-+	vpmsumd		$Xl,$Xl,$xC2
-+	vxor		$t1,$t1,$Xh
-+	vxor		$IN1,$Xl,$t1
-+
-+	vsldoi		$H2,$IN1,$IN1,8
-+	vsldoi		$H2l,$zero,$H2,8
-+	vsldoi		$H2h,$H2,$zero,8
-+
-+	stvx_u		$H2l,r8,r3		# save H^2
-+	li		r8,0x70
-+	stvx_u		$H2,r9,r3
-+	li		r9,0x80
-+	stvx_u		$H2h,r10,r3
-+	li		r10,0x90
-+___
-+{
-+my ($t4,$t5,$t6) = ($Hl,$H,$Hh);
-+$code.=<<___;
-+	vpmsumd		$Xl,$IN,$H2l		# H.lo·H^2.lo
-+	 vpmsumd	$Xl1,$IN1,$H2l		# H^2.lo·H^2.lo
-+	vpmsumd		$Xm,$IN,$H2		# H.hi·H^2.lo+H.lo·H^2.hi
-+	 vpmsumd	$Xm1,$IN1,$H2		# H^2.hi·H^2.lo+H^2.lo·H^2.hi
-+	vpmsumd		$Xh,$IN,$H2h		# H.hi·H^2.hi
-+	 vpmsumd	$Xh1,$IN1,$H2h		# H^2.hi·H^2.hi
-+
-+	vpmsumd		$t2,$Xl,$xC2		# 1st reduction phase
-+	 vpmsumd	$t6,$Xl1,$xC2		# 1st reduction phase
-+
-+	vsldoi		$t0,$Xm,$zero,8
-+	vsldoi		$t1,$zero,$Xm,8
-+	 vsldoi		$t4,$Xm1,$zero,8
-+	 vsldoi		$t5,$zero,$Xm1,8
-+	vxor		$Xl,$Xl,$t0
-+	vxor		$Xh,$Xh,$t1
-+	 vxor		$Xl1,$Xl1,$t4
-+	 vxor		$Xh1,$Xh1,$t5
-+
-+	vsldoi		$Xl,$Xl,$Xl,8
-+	 vsldoi		$Xl1,$Xl1,$Xl1,8
-+	vxor		$Xl,$Xl,$t2
-+	 vxor		$Xl1,$Xl1,$t6
-+
-+	vsldoi		$t1,$Xl,$Xl,8		# 2nd reduction phase
-+	 vsldoi		$t5,$Xl1,$Xl1,8		# 2nd reduction phase
-+	vpmsumd		$Xl,$Xl,$xC2
-+	 vpmsumd	$Xl1,$Xl1,$xC2
-+	vxor		$t1,$t1,$Xh
-+	 vxor		$t5,$t5,$Xh1
-+	vxor		$Xl,$Xl,$t1
-+	 vxor		$Xl1,$Xl1,$t5
-+
-+	vsldoi		$H,$Xl,$Xl,8
-+	 vsldoi		$H2,$Xl1,$Xl1,8
-+	vsldoi		$Hl,$zero,$H,8
-+	vsldoi		$Hh,$H,$zero,8
-+	 vsldoi		$H2l,$zero,$H2,8
-+	 vsldoi		$H2h,$H2,$zero,8
-+
-+	stvx_u		$Hl,r8,r3		# save H^3
-+	li		r8,0xa0
-+	stvx_u		$H,r9,r3
-+	li		r9,0xb0
-+	stvx_u		$Hh,r10,r3
-+	li		r10,0xc0
-+	 stvx_u		$H2l,r8,r3		# save H^4
-+	 stvx_u		$H2,r9,r3
-+	 stvx_u		$H2h,r10,r3
-+
-+	mtspr		256,$vrsave
-+	blr
-+	.long		0
-+	.byte		0,12,0x14,0,0,0,2,0
-+	.long		0
-+.size	.gcm_init_p8,.-.gcm_init_p8
-+___
-+}
-+$code.=<<___;
-+.globl	.gcm_gmult_p8
-+.align	5
-+.gcm_gmult_p8:
-+	lis		r0,0xfff8
-+	li		r8,0x10
-+	mfspr		$vrsave,256
-+	li		r9,0x20
-+	mtspr		256,r0
-+	li		r10,0x30
-+	lvx_u		$IN,0,$Xip		# load Xi
-+
-+	lvx_u		$Hl,r8,$Htbl		# load pre-computed table
-+	 le?lvsl	$lemask,r0,r0
-+	lvx_u		$H, r9,$Htbl
-+	 le?vspltisb	$t0,0x07
-+	lvx_u		$Hh,r10,$Htbl
-+	 le?vxor	$lemask,$lemask,$t0
-+	lvx_u		$xC2,0,$Htbl
-+	 le?vperm	$IN,$IN,$IN,$lemask
-+	vxor		$zero,$zero,$zero
-+
-+	vpmsumd		$Xl,$IN,$Hl		# H.lo·Xi.lo
-+	vpmsumd		$Xm,$IN,$H		# H.hi·Xi.lo+H.lo·Xi.hi
-+	vpmsumd		$Xh,$IN,$Hh		# H.hi·Xi.hi
-+
-+	vpmsumd		$t2,$Xl,$xC2		# 1st reduction phase
-+
-+	vsldoi		$t0,$Xm,$zero,8
-+	vsldoi		$t1,$zero,$Xm,8
-+	vxor		$Xl,$Xl,$t0
-+	vxor		$Xh,$Xh,$t1
-+
-+	vsldoi		$Xl,$Xl,$Xl,8
-+	vxor		$Xl,$Xl,$t2
-+
-+	vsldoi		$t1,$Xl,$Xl,8		# 2nd reduction phase
-+	vpmsumd		$Xl,$Xl,$xC2
-+	vxor		$t1,$t1,$Xh
-+	vxor		$Xl,$Xl,$t1
-+
-+	le?vperm	$Xl,$Xl,$Xl,$lemask
-+	stvx_u		$Xl,0,$Xip		# write out Xi
-+
-+	mtspr		256,$vrsave
-+	blr
-+	.long		0
-+	.byte		0,12,0x14,0,0,0,2,0
-+	.long		0
-+.size	.gcm_gmult_p8,.-.gcm_gmult_p8
-+
-+.globl	.gcm_ghash_p8
-+.align	5
-+.gcm_ghash_p8:
-+	li		r0,-4096
-+	li		r8,0x10
-+	mfspr		$vrsave,256
-+	li		r9,0x20
-+	mtspr		256,r0
-+	li		r10,0x30
-+	lvx_u		$Xl,0,$Xip		# load Xi
-+
-+	lvx_u		$Hl,r8,$Htbl		# load pre-computed table
-+	li		r8,0x40
-+	 le?lvsl	$lemask,r0,r0
-+	lvx_u		$H, r9,$Htbl
-+	li		r9,0x50
-+	 le?vspltisb	$t0,0x07
-+	lvx_u		$Hh,r10,$Htbl
-+	li		r10,0x60
-+	 le?vxor	$lemask,$lemask,$t0
-+	lvx_u		$xC2,0,$Htbl
-+	 le?vperm	$Xl,$Xl,$Xl,$lemask
-+	vxor		$zero,$zero,$zero
-+
-+	${UCMP}i	$len,64
-+	bge		Lgcm_ghash_p8_4x
-+
-+	lvx_u		$IN,0,$inp
-+	addi		$inp,$inp,16
-+	subic.		$len,$len,16
-+	 le?vperm	$IN,$IN,$IN,$lemask
-+	vxor		$IN,$IN,$Xl
-+	beq		Lshort
-+
-+	lvx_u		$H2l,r8,$Htbl		# load H^2
-+	li		r8,16
-+	lvx_u		$H2, r9,$Htbl
-+	add		r9,$inp,$len		# end of input
-+	lvx_u		$H2h,r10,$Htbl
-+	be?b		Loop_2x
-+
-+.align	5
-+Loop_2x:
-+	lvx_u		$IN1,0,$inp
-+	le?vperm	$IN1,$IN1,$IN1,$lemask
-+
-+	 subic		$len,$len,32
-+	vpmsumd		$Xl,$IN,$H2l		# H^2.lo·Xi.lo
-+	 vpmsumd	$Xl1,$IN1,$Hl		# H.lo·Xi+1.lo
-+	 subfe		r0,r0,r0		# borrow?-1:0
-+	vpmsumd		$Xm,$IN,$H2		# H^2.hi·Xi.lo+H^2.lo·Xi.hi
-+	 vpmsumd	$Xm1,$IN1,$H		# H.hi·Xi+1.lo+H.lo·Xi+1.hi
-+	 and		r0,r0,$len
-+	vpmsumd		$Xh,$IN,$H2h		# H^2.hi·Xi.hi
-+	 vpmsumd	$Xh1,$IN1,$Hh		# H.hi·Xi+1.hi
-+	 add		$inp,$inp,r0
-+
-+	vxor		$Xl,$Xl,$Xl1
-+	vxor		$Xm,$Xm,$Xm1
-+
-+	vpmsumd		$t2,$Xl,$xC2		# 1st reduction phase
-+
-+	vsldoi		$t0,$Xm,$zero,8
-+	vsldoi		$t1,$zero,$Xm,8
-+	 vxor		$Xh,$Xh,$Xh1
-+	vxor		$Xl,$Xl,$t0
-+	vxor		$Xh,$Xh,$t1
-+
-+	vsldoi		$Xl,$Xl,$Xl,8
-+	vxor		$Xl,$Xl,$t2
-+	 lvx_u		$IN,r8,$inp
-+	 addi		$inp,$inp,32
-+
-+	vsldoi		$t1,$Xl,$Xl,8		# 2nd reduction phase
-+	vpmsumd		$Xl,$Xl,$xC2
-+	 le?vperm	$IN,$IN,$IN,$lemask
-+	vxor		$t1,$t1,$Xh
-+	vxor		$IN,$IN,$t1
-+	vxor		$IN,$IN,$Xl
-+	$UCMP		r9,$inp
-+	bgt		Loop_2x			# done yet?
-+
-+	cmplwi		$len,0
-+	bne		Leven
-+
-+Lshort:
-+	vpmsumd		$Xl,$IN,$Hl		# H.lo·Xi.lo
-+	vpmsumd		$Xm,$IN,$H		# H.hi·Xi.lo+H.lo·Xi.hi
-+	vpmsumd		$Xh,$IN,$Hh		# H.hi·Xi.hi
-+
-+	vpmsumd		$t2,$Xl,$xC2		# 1st reduction phase
-+
-+	vsldoi		$t0,$Xm,$zero,8
-+	vsldoi		$t1,$zero,$Xm,8
-+	vxor		$Xl,$Xl,$t0
-+	vxor		$Xh,$Xh,$t1
-+
-+	vsldoi		$Xl,$Xl,$Xl,8
-+	vxor		$Xl,$Xl,$t2
-+
-+	vsldoi		$t1,$Xl,$Xl,8		# 2nd reduction phase
-+	vpmsumd		$Xl,$Xl,$xC2
-+	vxor		$t1,$t1,$Xh
-+
-+Leven:
-+	vxor		$Xl,$Xl,$t1
-+	le?vperm	$Xl,$Xl,$Xl,$lemask
-+	stvx_u		$Xl,0,$Xip		# write out Xi
-+
-+	mtspr		256,$vrsave
-+	blr
-+	.long		0
-+	.byte		0,12,0x14,0,0,0,4,0
-+	.long		0
-+___
-+{
-+my ($Xl3,$Xm2,$IN2,$H3l,$H3,$H3h,
-+    $Xh3,$Xm3,$IN3,$H4l,$H4,$H4h) = map("v$_",(20..31));
-+my $IN0=$IN;
-+my ($H21l,$H21h,$loperm,$hiperm) = ($Hl,$Hh,$H2l,$H2h);
-+
-+$code.=<<___;
-+.align	5
-+.gcm_ghash_p8_4x:
-+Lgcm_ghash_p8_4x:
-+	$STU		$sp,-$FRAME($sp)
-+	li		r10,`15+6*$SIZE_T`
-+	li		r11,`31+6*$SIZE_T`
-+	stvx		v20,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v21,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v22,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v23,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v24,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v25,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v26,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v27,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v28,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v29,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v30,r10,$sp
-+	li		r10,0x60
-+	stvx		v31,r11,$sp
-+	li		r0,-1
-+	stw		$vrsave,`$FRAME-4`($sp)	# save vrsave
-+	mtspr		256,r0			# preserve all AltiVec registers
-+
-+	lvsl		$t0,0,r8		# 0x0001..0e0f
-+	#lvx_u		$H2l,r8,$Htbl		# load H^2
-+	li		r8,0x70
-+	lvx_u		$H2, r9,$Htbl
-+	li		r9,0x80
-+	vspltisb	$t1,8			# 0x0808..0808
-+	#lvx_u		$H2h,r10,$Htbl
-+	li		r10,0x90
-+	lvx_u		$H3l,r8,$Htbl		# load H^3
-+	li		r8,0xa0
-+	lvx_u		$H3, r9,$Htbl
-+	li		r9,0xb0
-+	lvx_u		$H3h,r10,$Htbl
-+	li		r10,0xc0
-+	lvx_u		$H4l,r8,$Htbl		# load H^4
-+	li		r8,0x10
-+	lvx_u		$H4, r9,$Htbl
-+	li		r9,0x20
-+	lvx_u		$H4h,r10,$Htbl
-+	li		r10,0x30
-+
-+	vsldoi		$t2,$zero,$t1,8		# 0x0000..0808
-+	vaddubm		$hiperm,$t0,$t2		# 0x0001..1617
-+	vaddubm		$loperm,$t1,$hiperm	# 0x0809..1e1f
-+
-+	$SHRI		$len,$len,4		# this allows to use sign bit
-+						# as carry
-+	lvx_u		$IN0,0,$inp		# load input
-+	lvx_u		$IN1,r8,$inp
-+	subic.		$len,$len,8
-+	lvx_u		$IN2,r9,$inp
-+	lvx_u		$IN3,r10,$inp
-+	addi		$inp,$inp,0x40
-+	le?vperm	$IN0,$IN0,$IN0,$lemask
-+	le?vperm	$IN1,$IN1,$IN1,$lemask
-+	le?vperm	$IN2,$IN2,$IN2,$lemask
-+	le?vperm	$IN3,$IN3,$IN3,$lemask
-+
-+	vxor		$Xh,$IN0,$Xl
-+
-+	 vpmsumd	$Xl1,$IN1,$H3l
-+	 vpmsumd	$Xm1,$IN1,$H3
-+	 vpmsumd	$Xh1,$IN1,$H3h
-+
-+	 vperm		$H21l,$H2,$H,$hiperm
-+	 vperm		$t0,$IN2,$IN3,$loperm
-+	 vperm		$H21h,$H2,$H,$loperm
-+	 vperm		$t1,$IN2,$IN3,$hiperm
-+	 vpmsumd	$Xm2,$IN2,$H2		# H^2.lo·Xi+2.hi+H^2.hi·Xi+2.lo
-+	 vpmsumd	$Xl3,$t0,$H21l		# H^2.lo·Xi+2.lo+H.lo·Xi+3.lo
-+	 vpmsumd	$Xm3,$IN3,$H		# H.hi·Xi+3.lo  +H.lo·Xi+3.hi
-+	 vpmsumd	$Xh3,$t1,$H21h		# H^2.hi·Xi+2.hi+H.hi·Xi+3.hi
-+
-+	 vxor		$Xm2,$Xm2,$Xm1
-+	 vxor		$Xl3,$Xl3,$Xl1
-+	 vxor		$Xm3,$Xm3,$Xm2
-+	 vxor		$Xh3,$Xh3,$Xh1
-+
-+	blt		Ltail_4x
-+
-+Loop_4x:
-+	lvx_u		$IN0,0,$inp
-+	lvx_u		$IN1,r8,$inp
-+	subic.		$len,$len,4
-+	lvx_u		$IN2,r9,$inp
-+	lvx_u		$IN3,r10,$inp
-+	addi		$inp,$inp,0x40
-+	le?vperm	$IN1,$IN1,$IN1,$lemask
-+	le?vperm	$IN2,$IN2,$IN2,$lemask
-+	le?vperm	$IN3,$IN3,$IN3,$lemask
-+	le?vperm	$IN0,$IN0,$IN0,$lemask
-+
-+	vpmsumd		$Xl,$Xh,$H4l		# H^4.lo·Xi.lo
-+	vpmsumd		$Xm,$Xh,$H4		# H^4.hi·Xi.lo+H^4.lo·Xi.hi
-+	vpmsumd		$Xh,$Xh,$H4h		# H^4.hi·Xi.hi
-+	 vpmsumd	$Xl1,$IN1,$H3l
-+	 vpmsumd	$Xm1,$IN1,$H3
-+	 vpmsumd	$Xh1,$IN1,$H3h
-+
-+	vxor		$Xl,$Xl,$Xl3
-+	vxor		$Xm,$Xm,$Xm3
-+	vxor		$Xh,$Xh,$Xh3
-+	 vperm		$t0,$IN2,$IN3,$loperm
-+	 vperm		$t1,$IN2,$IN3,$hiperm
-+
-+	vpmsumd		$t2,$Xl,$xC2		# 1st reduction phase
-+	 vpmsumd	$Xl3,$t0,$H21l		# H.lo·Xi+3.lo  +H^2.lo·Xi+2.lo
-+	 vpmsumd	$Xh3,$t1,$H21h		# H.hi·Xi+3.hi  +H^2.hi·Xi+2.hi
-+
-+	vsldoi		$t0,$Xm,$zero,8
-+	vsldoi		$t1,$zero,$Xm,8
-+	vxor		$Xl,$Xl,$t0
-+	vxor		$Xh,$Xh,$t1
-+
-+	vsldoi		$Xl,$Xl,$Xl,8
-+	vxor		$Xl,$Xl,$t2
-+
-+	vsldoi		$t1,$Xl,$Xl,8		# 2nd reduction phase
-+	 vpmsumd	$Xm2,$IN2,$H2		# H^2.hi·Xi+2.lo+H^2.lo·Xi+2.hi
-+	 vpmsumd	$Xm3,$IN3,$H		# H.hi·Xi+3.lo  +H.lo·Xi+3.hi
-+	vpmsumd		$Xl,$Xl,$xC2
-+
-+	 vxor		$Xl3,$Xl3,$Xl1
-+	 vxor		$Xh3,$Xh3,$Xh1
-+	vxor		$Xh,$Xh,$IN0
-+	 vxor		$Xm2,$Xm2,$Xm1
-+	vxor		$Xh,$Xh,$t1
-+	 vxor		$Xm3,$Xm3,$Xm2
-+	vxor		$Xh,$Xh,$Xl
-+	bge		Loop_4x
-+
-+Ltail_4x:
-+	vpmsumd		$Xl,$Xh,$H4l		# H^4.lo·Xi.lo
-+	vpmsumd		$Xm,$Xh,$H4		# H^4.hi·Xi.lo+H^4.lo·Xi.hi
-+	vpmsumd		$Xh,$Xh,$H4h		# H^4.hi·Xi.hi
-+
-+	vxor		$Xl,$Xl,$Xl3
-+	vxor		$Xm,$Xm,$Xm3
-+
-+	vpmsumd		$t2,$Xl,$xC2		# 1st reduction phase
-+
-+	vsldoi		$t0,$Xm,$zero,8
-+	vsldoi		$t1,$zero,$Xm,8
-+	 vxor		$Xh,$Xh,$Xh3
-+	vxor		$Xl,$Xl,$t0
-+	vxor		$Xh,$Xh,$t1
-+
-+	vsldoi		$Xl,$Xl,$Xl,8
-+	vxor		$Xl,$Xl,$t2
-+
-+	vsldoi		$t1,$Xl,$Xl,8		# 2nd reduction phase
-+	vpmsumd		$Xl,$Xl,$xC2
-+	vxor		$t1,$t1,$Xh
-+	vxor		$Xl,$Xl,$t1
-+
-+	addic.		$len,$len,4
-+	beq		Ldone_4x
-+
-+	lvx_u		$IN0,0,$inp
-+	${UCMP}i	$len,2
-+	li		$len,-4
-+	blt		Lone
-+	lvx_u		$IN1,r8,$inp
-+	beq		Ltwo
-+
-+Lthree:
-+	lvx_u		$IN2,r9,$inp
-+	le?vperm	$IN0,$IN0,$IN0,$lemask
-+	le?vperm	$IN1,$IN1,$IN1,$lemask
-+	le?vperm	$IN2,$IN2,$IN2,$lemask
-+
-+	vxor		$Xh,$IN0,$Xl
-+	vmr		$H4l,$H3l
-+	vmr		$H4, $H3
-+	vmr		$H4h,$H3h
-+
-+	vperm		$t0,$IN1,$IN2,$loperm
-+	vperm		$t1,$IN1,$IN2,$hiperm
-+	vpmsumd		$Xm2,$IN1,$H2		# H^2.lo·Xi+1.hi+H^2.hi·Xi+1.lo
-+	vpmsumd		$Xm3,$IN2,$H		# H.hi·Xi+2.lo  +H.lo·Xi+2.hi
-+	vpmsumd		$Xl3,$t0,$H21l		# H^2.lo·Xi+1.lo+H.lo·Xi+2.lo
-+	vpmsumd		$Xh3,$t1,$H21h		# H^2.hi·Xi+1.hi+H.hi·Xi+2.hi
-+
-+	vxor		$Xm3,$Xm3,$Xm2
-+	b		Ltail_4x
-+
-+.align	4
-+Ltwo:
-+	le?vperm	$IN0,$IN0,$IN0,$lemask
-+	le?vperm	$IN1,$IN1,$IN1,$lemask
-+
-+	vxor		$Xh,$IN0,$Xl
-+	vperm		$t0,$zero,$IN1,$loperm
-+	vperm		$t1,$zero,$IN1,$hiperm
-+
-+	vsldoi		$H4l,$zero,$H2,8
-+	vmr		$H4, $H2
-+	vsldoi		$H4h,$H2,$zero,8
-+
-+	vpmsumd		$Xl3,$t0, $H21l		# H.lo·Xi+1.lo
-+	vpmsumd		$Xm3,$IN1,$H		# H.hi·Xi+1.lo+H.lo·Xi+2.hi
-+	vpmsumd		$Xh3,$t1, $H21h		# H.hi·Xi+1.hi
-+
-+	b		Ltail_4x
-+
-+.align	4
-+Lone:
-+	le?vperm	$IN0,$IN0,$IN0,$lemask
-+
-+	vsldoi		$H4l,$zero,$H,8
-+	vmr		$H4, $H
-+	vsldoi		$H4h,$H,$zero,8
-+
-+	vxor		$Xh,$IN0,$Xl
-+	vxor		$Xl3,$Xl3,$Xl3
-+	vxor		$Xm3,$Xm3,$Xm3
-+	vxor		$Xh3,$Xh3,$Xh3
-+
-+	b		Ltail_4x
-+
-+Ldone_4x:
-+	le?vperm	$Xl,$Xl,$Xl,$lemask
-+	stvx_u		$Xl,0,$Xip		# write out Xi
-+
-+	li		r10,`15+6*$SIZE_T`
-+	li		r11,`31+6*$SIZE_T`
-+	mtspr		256,$vrsave
-+	lvx		v20,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v21,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v22,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v23,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v24,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v25,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v26,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v27,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v28,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v29,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v30,r10,$sp
-+	lvx		v31,r11,$sp
-+	addi		$sp,$sp,$FRAME
-+	blr
-+	.long		0
-+	.byte		0,12,0x04,0,0x80,0,4,0
-+	.long		0
-+___
-+}
-+$code.=<<___;
-+.size	.gcm_ghash_p8,.-.gcm_ghash_p8
-+
-+.asciz  "GHASH for PowerISA 2.07, CRYPTOGAMS by "
-+.align  2
-+___
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	if ($flavour =~ /le$/o) {	# little-endian
-+	    s/le\?//o		or
-+	    s/be\?/#be#/o;
-+	} else {
-+	    s/le\?/#le#/o	or
-+	    s/be\?//o;
-+	}
-+	print $_,"\n";
-+}
-+
-+close STDOUT; # enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghashv8-armx.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghashv8-armx.pl
-new file mode 100644
-index 0000000..dcd5f59
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/asm/ghashv8-armx.pl
-@@ -0,0 +1,430 @@
-+#! /usr/bin/env perl
-+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# GHASH for ARMv8 Crypto Extension, 64-bit polynomial multiplication.
-+#
-+# June 2014
-+#
-+# Initial version was developed in tight cooperation with Ard
-+# Biesheuvel  from bits-n-pieces from
-+# other assembly modules. Just like aesv8-armx.pl this module
-+# supports both AArch32 and AArch64 execution modes.
-+#
-+# July 2014
-+#
-+# Implement 2x aggregated reduction [see ghash-x86.pl for background
-+# information].
-+#
-+# Current performance in cycles per processed byte:
-+#
-+#		PMULL[2]	32-bit NEON(*)
-+# Apple A7	0.92		5.62
-+# Cortex-A53	1.01		8.39
-+# Cortex-A57	1.17		7.61
-+# Denver	0.71		6.02
-+# Mongoose	1.10		8.06
-+#
-+# (*)	presented for reference/comparison purposes;
-+
-+$flavour = shift;
-+$output  = shift;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+$Xi="x0";	# argument block
-+$Htbl="x1";
-+$inp="x2";
-+$len="x3";
-+
-+$inc="x12";
-+
-+{
-+my ($Xl,$Xm,$Xh,$IN)=map("q$_",(0..3));
-+my ($t0,$t1,$t2,$xC2,$H,$Hhl,$H2)=map("q$_",(8..14));
-+
-+$code=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+___
-+$code.=".arch	armv8-a+crypto\n"	if ($flavour =~ /64/);
-+$code.=<<___				if ($flavour !~ /64/);
-+.fpu	neon
-+.code	32
-+#undef	__thumb2__
-+___
-+
-+################################################################################
-+# void gcm_init_v8(u128 Htable[16],const u64 H[2]);
-+#
-+# input:	128-bit H - secret parameter E(K,0^128)
-+# output:	precomputed table filled with degrees of twisted H;
-+#		H is twisted to handle reverse bitness of GHASH;
-+#		only few of 16 slots of Htable[16] are used;
-+#		data is opaque to outside world (which allows to
-+#		optimize the code independently);
-+#
-+$code.=<<___;
-+.global	gcm_init_v8
-+.type	gcm_init_v8,%function
-+.align	4
-+gcm_init_v8:
-+	vld1.64		{$t1},[x1]		@ load input H
-+	vmov.i8		$xC2,#0xe1
-+	vshl.i64	$xC2,$xC2,#57		@ 0xc2.0
-+	vext.8		$IN,$t1,$t1,#8
-+	vshr.u64	$t2,$xC2,#63
-+	vdup.32		$t1,${t1}[1]
-+	vext.8		$t0,$t2,$xC2,#8		@ t0=0xc2....01
-+	vshr.u64	$t2,$IN,#63
-+	vshr.s32	$t1,$t1,#31		@ broadcast carry bit
-+	vand		$t2,$t2,$t0
-+	vshl.i64	$IN,$IN,#1
-+	vext.8		$t2,$t2,$t2,#8
-+	vand		$t0,$t0,$t1
-+	vorr		$IN,$IN,$t2		@ H<<<=1
-+	veor		$H,$IN,$t0		@ twisted H
-+	vst1.64		{$H},[x0],#16		@ store Htable[0]
-+
-+	@ calculate H^2
-+	vext.8		$t0,$H,$H,#8		@ Karatsuba pre-processing
-+	vpmull.p64	$Xl,$H,$H
-+	veor		$t0,$t0,$H
-+	vpmull2.p64	$Xh,$H,$H
-+	vpmull.p64	$Xm,$t0,$t0
-+
-+	vext.8		$t1,$Xl,$Xh,#8		@ Karatsuba post-processing
-+	veor		$t2,$Xl,$Xh
-+	veor		$Xm,$Xm,$t1
-+	veor		$Xm,$Xm,$t2
-+	vpmull.p64	$t2,$Xl,$xC2		@ 1st phase
-+
-+	vmov		$Xh#lo,$Xm#hi		@ Xh|Xm - 256-bit result
-+	vmov		$Xm#hi,$Xl#lo		@ Xm is rotated Xl
-+	veor		$Xl,$Xm,$t2
-+
-+	vext.8		$t2,$Xl,$Xl,#8		@ 2nd phase
-+	vpmull.p64	$Xl,$Xl,$xC2
-+	veor		$t2,$t2,$Xh
-+	veor		$H2,$Xl,$t2
-+
-+	vext.8		$t1,$H2,$H2,#8		@ Karatsuba pre-processing
-+	veor		$t1,$t1,$H2
-+	vext.8		$Hhl,$t0,$t1,#8		@ pack Karatsuba pre-processed
-+	vst1.64		{$Hhl-$H2},[x0]		@ store Htable[1..2]
-+
-+	ret
-+.size	gcm_init_v8,.-gcm_init_v8
-+___
-+################################################################################
-+# void gcm_gmult_v8(u64 Xi[2],const u128 Htable[16]);
-+#
-+# input:	Xi - current hash value;
-+#		Htable - table precomputed in gcm_init_v8;
-+# output:	Xi - next hash value Xi;
-+#
-+$code.=<<___;
-+.global	gcm_gmult_v8
-+.type	gcm_gmult_v8,%function
-+.align	4
-+gcm_gmult_v8:
-+	vld1.64		{$t1},[$Xi]		@ load Xi
-+	vmov.i8		$xC2,#0xe1
-+	vld1.64		{$H-$Hhl},[$Htbl]	@ load twisted H, ...
-+	vshl.u64	$xC2,$xC2,#57
-+#ifndef __ARMEB__
-+	vrev64.8	$t1,$t1
-+#endif
-+	vext.8		$IN,$t1,$t1,#8
-+
-+	vpmull.p64	$Xl,$H,$IN		@ H.lo·Xi.lo
-+	veor		$t1,$t1,$IN		@ Karatsuba pre-processing
-+	vpmull2.p64	$Xh,$H,$IN		@ H.hi·Xi.hi
-+	vpmull.p64	$Xm,$Hhl,$t1		@ (H.lo+H.hi)·(Xi.lo+Xi.hi)
-+
-+	vext.8		$t1,$Xl,$Xh,#8		@ Karatsuba post-processing
-+	veor		$t2,$Xl,$Xh
-+	veor		$Xm,$Xm,$t1
-+	veor		$Xm,$Xm,$t2
-+	vpmull.p64	$t2,$Xl,$xC2		@ 1st phase of reduction
-+
-+	vmov		$Xh#lo,$Xm#hi		@ Xh|Xm - 256-bit result
-+	vmov		$Xm#hi,$Xl#lo		@ Xm is rotated Xl
-+	veor		$Xl,$Xm,$t2
-+
-+	vext.8		$t2,$Xl,$Xl,#8		@ 2nd phase of reduction
-+	vpmull.p64	$Xl,$Xl,$xC2
-+	veor		$t2,$t2,$Xh
-+	veor		$Xl,$Xl,$t2
-+
-+#ifndef __ARMEB__
-+	vrev64.8	$Xl,$Xl
-+#endif
-+	vext.8		$Xl,$Xl,$Xl,#8
-+	vst1.64		{$Xl},[$Xi]		@ write out Xi
-+
-+	ret
-+.size	gcm_gmult_v8,.-gcm_gmult_v8
-+___
-+################################################################################
-+# void gcm_ghash_v8(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
-+#
-+# input:	table precomputed in gcm_init_v8;
-+#		current hash value Xi;
-+#		pointer to input data;
-+#		length of input data in bytes, but divisible by block size;
-+# output:	next hash value Xi;
-+#
-+$code.=<<___;
-+.global	gcm_ghash_v8
-+.type	gcm_ghash_v8,%function
-+.align	4
-+gcm_ghash_v8:
-+___
-+$code.=<<___		if ($flavour !~ /64/);
-+	vstmdb		sp!,{d8-d15}		@ 32-bit ABI says so
-+___
-+$code.=<<___;
-+	vld1.64		{$Xl},[$Xi]		@ load [rotated] Xi
-+						@ "[rotated]" means that
-+						@ loaded value would have
-+						@ to be rotated in order to
-+						@ make it appear as in
-+						@ alorithm specification
-+	subs		$len,$len,#32		@ see if $len is 32 or larger
-+	mov		$inc,#16		@ $inc is used as post-
-+						@ increment for input pointer;
-+						@ as loop is modulo-scheduled
-+						@ $inc is zeroed just in time
-+						@ to preclude oversteping
-+						@ inp[len], which means that
-+						@ last block[s] are actually
-+						@ loaded twice, but last
-+						@ copy is not processed
-+	vld1.64		{$H-$Hhl},[$Htbl],#32	@ load twisted H, ..., H^2
-+	vmov.i8		$xC2,#0xe1
-+	vld1.64		{$H2},[$Htbl]
-+	cclr		$inc,eq			@ is it time to zero $inc?
-+	vext.8		$Xl,$Xl,$Xl,#8		@ rotate Xi
-+	vld1.64		{$t0},[$inp],#16	@ load [rotated] I[0]
-+	vshl.u64	$xC2,$xC2,#57		@ compose 0xc2.0 constant
-+#ifndef __ARMEB__
-+	vrev64.8	$t0,$t0
-+	vrev64.8	$Xl,$Xl
-+#endif
-+	vext.8		$IN,$t0,$t0,#8		@ rotate I[0]
-+	b.lo		.Lodd_tail_v8		@ $len was less than 32
-+___
-+{ my ($Xln,$Xmn,$Xhn,$In) = map("q$_",(4..7));
-+	#######
-+	# Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
-+	#	[(H*Ii+1) + (H*Xi+1)] mod P =
-+	#	[(H*Ii+1) + H^2*(Ii+Xi)] mod P
-+	#
-+$code.=<<___;
-+	vld1.64		{$t1},[$inp],$inc	@ load [rotated] I[1]
-+#ifndef __ARMEB__
-+	vrev64.8	$t1,$t1
-+#endif
-+	vext.8		$In,$t1,$t1,#8
-+	veor		$IN,$IN,$Xl		@ I[i]^=Xi
-+	vpmull.p64	$Xln,$H,$In		@ H·Ii+1
-+	veor		$t1,$t1,$In		@ Karatsuba pre-processing
-+	vpmull2.p64	$Xhn,$H,$In
-+	b		.Loop_mod2x_v8
-+
-+.align	4
-+.Loop_mod2x_v8:
-+	vext.8		$t2,$IN,$IN,#8
-+	subs		$len,$len,#32		@ is there more data?
-+	vpmull.p64	$Xl,$H2,$IN		@ H^2.lo·Xi.lo
-+	cclr		$inc,lo			@ is it time to zero $inc?
-+
-+	 vpmull.p64	$Xmn,$Hhl,$t1
-+	veor		$t2,$t2,$IN		@ Karatsuba pre-processing
-+	vpmull2.p64	$Xh,$H2,$IN		@ H^2.hi·Xi.hi
-+	veor		$Xl,$Xl,$Xln		@ accumulate
-+	vpmull2.p64	$Xm,$Hhl,$t2		@ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
-+	 vld1.64	{$t0},[$inp],$inc	@ load [rotated] I[i+2]
-+
-+	veor		$Xh,$Xh,$Xhn
-+	 cclr		$inc,eq			@ is it time to zero $inc?
-+	veor		$Xm,$Xm,$Xmn
-+
-+	vext.8		$t1,$Xl,$Xh,#8		@ Karatsuba post-processing
-+	veor		$t2,$Xl,$Xh
-+	veor		$Xm,$Xm,$t1
-+	 vld1.64	{$t1},[$inp],$inc	@ load [rotated] I[i+3]
-+#ifndef __ARMEB__
-+	 vrev64.8	$t0,$t0
-+#endif
-+	veor		$Xm,$Xm,$t2
-+	vpmull.p64	$t2,$Xl,$xC2		@ 1st phase of reduction
-+
-+#ifndef __ARMEB__
-+	 vrev64.8	$t1,$t1
-+#endif
-+	vmov		$Xh#lo,$Xm#hi		@ Xh|Xm - 256-bit result
-+	vmov		$Xm#hi,$Xl#lo		@ Xm is rotated Xl
-+	 vext.8		$In,$t1,$t1,#8
-+	 vext.8		$IN,$t0,$t0,#8
-+	veor		$Xl,$Xm,$t2
-+	 vpmull.p64	$Xln,$H,$In		@ H·Ii+1
-+	veor		$IN,$IN,$Xh		@ accumulate $IN early
-+
-+	vext.8		$t2,$Xl,$Xl,#8		@ 2nd phase of reduction
-+	vpmull.p64	$Xl,$Xl,$xC2
-+	veor		$IN,$IN,$t2
-+	 veor		$t1,$t1,$In		@ Karatsuba pre-processing
-+	veor		$IN,$IN,$Xl
-+	 vpmull2.p64	$Xhn,$H,$In
-+	b.hs		.Loop_mod2x_v8		@ there was at least 32 more bytes
-+
-+	veor		$Xh,$Xh,$t2
-+	vext.8		$IN,$t0,$t0,#8		@ re-construct $IN
-+	adds		$len,$len,#32		@ re-construct $len
-+	veor		$Xl,$Xl,$Xh		@ re-construct $Xl
-+	b.eq		.Ldone_v8		@ is $len zero?
-+___
-+}
-+$code.=<<___;
-+.Lodd_tail_v8:
-+	vext.8		$t2,$Xl,$Xl,#8
-+	veor		$IN,$IN,$Xl		@ inp^=Xi
-+	veor		$t1,$t0,$t2		@ $t1 is rotated inp^Xi
-+
-+	vpmull.p64	$Xl,$H,$IN		@ H.lo·Xi.lo
-+	veor		$t1,$t1,$IN		@ Karatsuba pre-processing
-+	vpmull2.p64	$Xh,$H,$IN		@ H.hi·Xi.hi
-+	vpmull.p64	$Xm,$Hhl,$t1		@ (H.lo+H.hi)·(Xi.lo+Xi.hi)
-+
-+	vext.8		$t1,$Xl,$Xh,#8		@ Karatsuba post-processing
-+	veor		$t2,$Xl,$Xh
-+	veor		$Xm,$Xm,$t1
-+	veor		$Xm,$Xm,$t2
-+	vpmull.p64	$t2,$Xl,$xC2		@ 1st phase of reduction
-+
-+	vmov		$Xh#lo,$Xm#hi		@ Xh|Xm - 256-bit result
-+	vmov		$Xm#hi,$Xl#lo		@ Xm is rotated Xl
-+	veor		$Xl,$Xm,$t2
-+
-+	vext.8		$t2,$Xl,$Xl,#8		@ 2nd phase of reduction
-+	vpmull.p64	$Xl,$Xl,$xC2
-+	veor		$t2,$t2,$Xh
-+	veor		$Xl,$Xl,$t2
-+
-+.Ldone_v8:
-+#ifndef __ARMEB__
-+	vrev64.8	$Xl,$Xl
-+#endif
-+	vext.8		$Xl,$Xl,$Xl,#8
-+	vst1.64		{$Xl},[$Xi]		@ write out Xi
-+
-+___
-+$code.=<<___		if ($flavour !~ /64/);
-+	vldmia		sp!,{d8-d15}		@ 32-bit ABI says so
-+___
-+$code.=<<___;
-+	ret
-+.size	gcm_ghash_v8,.-gcm_ghash_v8
-+___
-+}
-+$code.=<<___;
-+.asciz  "GHASH for ARMv8, CRYPTOGAMS by "
-+.align  2
-+___
-+
-+if ($flavour =~ /64/) {			######## 64-bit code
-+    sub unvmov {
-+	my $arg=shift;
-+
-+	$arg =~ m/q([0-9]+)#(lo|hi),\s*q([0-9]+)#(lo|hi)/o &&
-+	sprintf	"ins	v%d.d[%d],v%d.d[%d]",$1,($2 eq "lo")?0:1,$3,($4 eq "lo")?0:1;
-+    }
-+    foreach(split("\n",$code)) {
-+	s/cclr\s+([wx])([^,]+),\s*([a-z]+)/csel	$1$2,$1zr,$1$2,$3/o	or
-+	s/vmov\.i8/movi/o		or	# fix up legacy mnemonics
-+	s/vmov\s+(.*)/unvmov($1)/geo	or
-+	s/vext\.8/ext/o			or
-+	s/vshr\.s/sshr\.s/o		or
-+	s/vshr/ushr/o			or
-+	s/^(\s+)v/$1/o			or	# strip off v prefix
-+	s/\bbx\s+lr\b/ret/o;
-+
-+	s/\bq([0-9]+)\b/"v".($1<8?$1:$1+8).".16b"/geo;	# old->new registers
-+	s/@\s/\/\//o;				# old->new style commentary
-+
-+	# fix up remainig legacy suffixes
-+	s/\.[ui]?8(\s)/$1/o;
-+	s/\.[uis]?32//o and s/\.16b/\.4s/go;
-+	m/\.p64/o and s/\.16b/\.1q/o;		# 1st pmull argument
-+	m/l\.p64/o and s/\.16b/\.1d/go;		# 2nd and 3rd pmull arguments
-+	s/\.[uisp]?64//o and s/\.16b/\.2d/go;
-+	s/\.[42]([sd])\[([0-3])\]/\.$1\[$2\]/o;
-+
-+	print $_,"\n";
-+    }
-+} else {				######## 32-bit code
-+    sub unvdup32 {
-+	my $arg=shift;
-+
-+	$arg =~ m/q([0-9]+),\s*q([0-9]+)\[([0-3])\]/o &&
-+	sprintf	"vdup.32	q%d,d%d[%d]",$1,2*$2+($3>>1),$3&1;
-+    }
-+    sub unvpmullp64 {
-+	my ($mnemonic,$arg)=@_;
-+
-+	if ($arg =~ m/q([0-9]+),\s*q([0-9]+),\s*q([0-9]+)/o) {
-+	    my $word = 0xf2a00e00|(($1&7)<<13)|(($1&8)<<19)
-+				 |(($2&7)<<17)|(($2&8)<<4)
-+				 |(($3&7)<<1) |(($3&8)<<2);
-+	    $word |= 0x00010001	 if ($mnemonic =~ "2");
-+	    # since ARMv7 instructions are always encoded little-endian.
-+	    # correct solution is to use .inst directive, but older
-+	    # assemblers don't implement it:-(
-+	    sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s",
-+			$word&0xff,($word>>8)&0xff,
-+			($word>>16)&0xff,($word>>24)&0xff,
-+			$mnemonic,$arg;
-+	}
-+    }
-+
-+    foreach(split("\n",$code)) {
-+	s/\b[wx]([0-9]+)\b/r$1/go;		# new->old registers
-+	s/\bv([0-9])\.[12468]+[bsd]\b/q$1/go;	# new->old registers
-+	s/\/\/\s?/@ /o;				# new->old style commentary
-+
-+	# fix up remainig new-style suffixes
-+	s/\],#[0-9]+/]!/o;
-+
-+	s/cclr\s+([^,]+),\s*([a-z]+)/mov$2	$1,#0/o			or
-+	s/vdup\.32\s+(.*)/unvdup32($1)/geo				or
-+	s/v?(pmull2?)\.p64\s+(.*)/unvpmullp64($1,$2)/geo		or
-+	s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo	or
-+	s/^(\s+)b\./$1b/o						or
-+	s/^(\s+)ret/$1bx\tlr/o;
-+
-+	print $_,"\n";
-+    }
-+}
-+
-+close STDOUT; # enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/build.info
-new file mode 100644
-index 0000000..38195c4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/build.info
-@@ -0,0 +1,27 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c \
-+        ccm128.c xts128.c wrap128.c ocb128.c \
-+        {- $target{modes_asm_src} -}
-+
-+INCLUDE[gcm128.o]=..
-+
-+GENERATE[ghash-ia64.s]=asm/ghash-ia64.pl $(CFLAGS) $(LIB_CFLAGS)
-+GENERATE[ghash-x86.s]=asm/ghash-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+GENERATE[ghash-x86_64.s]=asm/ghash-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[aesni-gcm-x86_64.s]=asm/aesni-gcm-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[ghash-sparcv9.S]=asm/ghash-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[ghash-sparcv9.o]=..
-+GENERATE[ghash-alpha.S]=asm/ghash-alpha.pl $(PERLASM_SCHEME)
-+GENERATE[ghash-parisc.s]=asm/ghash-parisc.pl $(PERLASM_SCHEME)
-+GENERATE[ghashp8-ppc.s]=asm/ghashp8-ppc.pl $(PERLASM_SCHEME)
-+GENERATE[ghash-armv4.S]=asm/ghash-armv4.pl $(PERLASM_SCHEME)
-+INCLUDE[ghash-armv4.o]=..
-+GENERATE[ghashv8-armx.S]=asm/ghashv8-armx.pl $(PERLASM_SCHEME)
-+INCLUDE[ghashv8-armx.o]=..
-+
-+BEGINRAW[Makefile]
-+# GNU make "catch all"
-+{- $builddir -}/ghash-%.S:	{- $sourcedir -}/asm/ghash-%.pl
-+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-+ENDRAW[Makefile]
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cbc128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cbc128.c
-new file mode 100644
-index 0000000..4c9bc85
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cbc128.c
-@@ -0,0 +1,155 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "modes_lcl.h"
-+#include 
-+
-+#if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC)
-+# define STRICT_ALIGNMENT 0
-+#endif
-+
-+void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const void *key,
-+                           unsigned char ivec[16], block128_f block)
-+{
-+    size_t n;
-+    const unsigned char *iv = ivec;
-+
-+#if !defined(OPENSSL_SMALL_FOOTPRINT)
-+    if (STRICT_ALIGNMENT &&
-+        ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
-+        while (len >= 16) {
-+            for (n = 0; n < 16; ++n)
-+                out[n] = in[n] ^ iv[n];
-+            (*block) (out, out, key);
-+            iv = out;
-+            len -= 16;
-+            in += 16;
-+            out += 16;
-+        }
-+    } else {
-+        while (len >= 16) {
-+            for (n = 0; n < 16; n += sizeof(size_t))
-+                *(size_t *)(out + n) =
-+                    *(size_t *)(in + n) ^ *(size_t *)(iv + n);
-+            (*block) (out, out, key);
-+            iv = out;
-+            len -= 16;
-+            in += 16;
-+            out += 16;
-+        }
-+    }
-+#endif
-+    while (len) {
-+        for (n = 0; n < 16 && n < len; ++n)
-+            out[n] = in[n] ^ iv[n];
-+        for (; n < 16; ++n)
-+            out[n] = iv[n];
-+        (*block) (out, out, key);
-+        iv = out;
-+        if (len <= 16)
-+            break;
-+        len -= 16;
-+        in += 16;
-+        out += 16;
-+    }
-+    memcpy(ivec, iv, 16);
-+}
-+
-+void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const void *key,
-+                           unsigned char ivec[16], block128_f block)
-+{
-+    size_t n;
-+    union {
-+        size_t t[16 / sizeof(size_t)];
-+        unsigned char c[16];
-+    } tmp;
-+
-+#if !defined(OPENSSL_SMALL_FOOTPRINT)
-+    if (in != out) {
-+        const unsigned char *iv = ivec;
-+
-+        if (STRICT_ALIGNMENT &&
-+            ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
-+            while (len >= 16) {
-+                (*block) (in, out, key);
-+                for (n = 0; n < 16; ++n)
-+                    out[n] ^= iv[n];
-+                iv = in;
-+                len -= 16;
-+                in += 16;
-+                out += 16;
-+            }
-+        } else if (16 % sizeof(size_t) == 0) { /* always true */
-+            while (len >= 16) {
-+                size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv;
-+
-+                (*block) (in, out, key);
-+                for (n = 0; n < 16 / sizeof(size_t); n++)
-+                    out_t[n] ^= iv_t[n];
-+                iv = in;
-+                len -= 16;
-+                in += 16;
-+                out += 16;
-+            }
-+        }
-+        memcpy(ivec, iv, 16);
-+    } else {
-+        if (STRICT_ALIGNMENT &&
-+            ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
-+            unsigned char c;
-+            while (len >= 16) {
-+                (*block) (in, tmp.c, key);
-+                for (n = 0; n < 16; ++n) {
-+                    c = in[n];
-+                    out[n] = tmp.c[n] ^ ivec[n];
-+                    ivec[n] = c;
-+                }
-+                len -= 16;
-+                in += 16;
-+                out += 16;
-+            }
-+        } else if (16 % sizeof(size_t) == 0) { /* always true */
-+            while (len >= 16) {
-+                size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec;
-+                const size_t *in_t = (const size_t *)in;
-+
-+                (*block) (in, tmp.c, key);
-+                for (n = 0; n < 16 / sizeof(size_t); n++) {
-+                    c = in_t[n];
-+                    out_t[n] = tmp.t[n] ^ ivec_t[n];
-+                    ivec_t[n] = c;
-+                }
-+                len -= 16;
-+                in += 16;
-+                out += 16;
-+            }
-+        }
-+    }
-+#endif
-+    while (len) {
-+        unsigned char c;
-+        (*block) (in, tmp.c, key);
-+        for (n = 0; n < 16 && n < len; ++n) {
-+            c = in[n];
-+            out[n] = tmp.c[n] ^ ivec[n];
-+            ivec[n] = c;
-+        }
-+        if (len <= 16) {
-+            for (; n < 16; ++n)
-+                ivec[n] = in[n];
-+            break;
-+        }
-+        len -= 16;
-+        in += 16;
-+        out += 16;
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ccm128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ccm128.c
-new file mode 100644
-index 0000000..85ce84f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ccm128.c
-@@ -0,0 +1,432 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "modes_lcl.h"
-+#include 
-+
-+/*
-+ * First you setup M and L parameters and pass the key schedule. This is
-+ * called once per session setup...
-+ */
-+void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
-+                        unsigned int M, unsigned int L, void *key,
-+                        block128_f block)
-+{
-+    memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c));
-+    ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3;
-+    ctx->blocks = 0;
-+    ctx->block = block;
-+    ctx->key = key;
-+}
-+
-+/* !!! Following interfaces are to be called *once* per packet !!! */
-+
-+/* Then you setup per-message nonce and pass the length of the message */
-+int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
-+                        const unsigned char *nonce, size_t nlen, size_t mlen)
-+{
-+    unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */
-+
-+    if (nlen < (14 - L))
-+        return -1;              /* nonce is too short */
-+
-+    if (sizeof(mlen) == 8 && L >= 3) {
-+        ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8)));
-+        ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8)));
-+        ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8)));
-+        ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8)));
-+    } else
-+        ctx->nonce.u[1] = 0;
-+
-+    ctx->nonce.c[12] = (u8)(mlen >> 24);
-+    ctx->nonce.c[13] = (u8)(mlen >> 16);
-+    ctx->nonce.c[14] = (u8)(mlen >> 8);
-+    ctx->nonce.c[15] = (u8)mlen;
-+
-+    ctx->nonce.c[0] &= ~0x40;   /* clear Adata flag */
-+    memcpy(&ctx->nonce.c[1], nonce, 14 - L);
-+
-+    return 0;
-+}
-+
-+/* Then you pass additional authentication data, this is optional */
-+void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
-+                       const unsigned char *aad, size_t alen)
-+{
-+    unsigned int i;
-+    block128_f block = ctx->block;
-+
-+    if (alen == 0)
-+        return;
-+
-+    ctx->nonce.c[0] |= 0x40;    /* set Adata flag */
-+    (*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++;
-+
-+    if (alen < (0x10000 - 0x100)) {
-+        ctx->cmac.c[0] ^= (u8)(alen >> 8);
-+        ctx->cmac.c[1] ^= (u8)alen;
-+        i = 2;
-+    } else if (sizeof(alen) == 8
-+               && alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) {
-+        ctx->cmac.c[0] ^= 0xFF;
-+        ctx->cmac.c[1] ^= 0xFF;
-+        ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8)));
-+        ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8)));
-+        ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8)));
-+        ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8)));
-+        ctx->cmac.c[6] ^= (u8)(alen >> 24);
-+        ctx->cmac.c[7] ^= (u8)(alen >> 16);
-+        ctx->cmac.c[8] ^= (u8)(alen >> 8);
-+        ctx->cmac.c[9] ^= (u8)alen;
-+        i = 10;
-+    } else {
-+        ctx->cmac.c[0] ^= 0xFF;
-+        ctx->cmac.c[1] ^= 0xFE;
-+        ctx->cmac.c[2] ^= (u8)(alen >> 24);
-+        ctx->cmac.c[3] ^= (u8)(alen >> 16);
-+        ctx->cmac.c[4] ^= (u8)(alen >> 8);
-+        ctx->cmac.c[5] ^= (u8)alen;
-+        i = 6;
-+    }
-+
-+    do {
-+        for (; i < 16 && alen; ++i, ++aad, --alen)
-+            ctx->cmac.c[i] ^= *aad;
-+        (*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++;
-+        i = 0;
-+    } while (alen);
-+}
-+
-+/* Finally you encrypt or decrypt the message */
-+
-+/*
-+ * counter part of nonce may not be larger than L*8 bits, L is not larger
-+ * than 8, therefore 64-bit counter...
-+ */
-+static void ctr64_inc(unsigned char *counter)
-+{
-+    unsigned int n = 8;
-+    u8 c;
-+
-+    counter += 8;
-+    do {
-+        --n;
-+        c = counter[n];
-+        ++c;
-+        counter[n] = c;
-+        if (c)
-+            return;
-+    } while (n);
-+}
-+
-+int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
-+                          const unsigned char *inp, unsigned char *out,
-+                          size_t len)
-+{
-+    size_t n;
-+    unsigned int i, L;
-+    unsigned char flags0 = ctx->nonce.c[0];
-+    block128_f block = ctx->block;
-+    void *key = ctx->key;
-+    union {
-+        u64 u[2];
-+        u8 c[16];
-+    } scratch;
-+
-+    if (!(flags0 & 0x40))
-+        (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
-+
-+    ctx->nonce.c[0] = L = flags0 & 7;
-+    for (n = 0, i = 15 - L; i < 15; ++i) {
-+        n |= ctx->nonce.c[i];
-+        ctx->nonce.c[i] = 0;
-+        n <<= 8;
-+    }
-+    n |= ctx->nonce.c[15];      /* reconstructed length */
-+    ctx->nonce.c[15] = 1;
-+
-+    if (n != len)
-+        return -1;              /* length mismatch */
-+
-+    ctx->blocks += ((len + 15) >> 3) | 1;
-+    if (ctx->blocks > (U64(1) << 61))
-+        return -2;              /* too much data */
-+
-+    while (len >= 16) {
-+#if defined(STRICT_ALIGNMENT)
-+        union {
-+            u64 u[2];
-+            u8 c[16];
-+        } temp;
-+
-+        memcpy(temp.c, inp, 16);
-+        ctx->cmac.u[0] ^= temp.u[0];
-+        ctx->cmac.u[1] ^= temp.u[1];
-+#else
-+        ctx->cmac.u[0] ^= ((u64 *)inp)[0];
-+        ctx->cmac.u[1] ^= ((u64 *)inp)[1];
-+#endif
-+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
-+        (*block) (ctx->nonce.c, scratch.c, key);
-+        ctr64_inc(ctx->nonce.c);
-+#if defined(STRICT_ALIGNMENT)
-+        temp.u[0] ^= scratch.u[0];
-+        temp.u[1] ^= scratch.u[1];
-+        memcpy(out, temp.c, 16);
-+#else
-+        ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0];
-+        ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1];
-+#endif
-+        inp += 16;
-+        out += 16;
-+        len -= 16;
-+    }
-+
-+    if (len) {
-+        for (i = 0; i < len; ++i)
-+            ctx->cmac.c[i] ^= inp[i];
-+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
-+        (*block) (ctx->nonce.c, scratch.c, key);
-+        for (i = 0; i < len; ++i)
-+            out[i] = scratch.c[i] ^ inp[i];
-+    }
-+
-+    for (i = 15 - L; i < 16; ++i)
-+        ctx->nonce.c[i] = 0;
-+
-+    (*block) (ctx->nonce.c, scratch.c, key);
-+    ctx->cmac.u[0] ^= scratch.u[0];
-+    ctx->cmac.u[1] ^= scratch.u[1];
-+
-+    ctx->nonce.c[0] = flags0;
-+
-+    return 0;
-+}
-+
-+int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
-+                          const unsigned char *inp, unsigned char *out,
-+                          size_t len)
-+{
-+    size_t n;
-+    unsigned int i, L;
-+    unsigned char flags0 = ctx->nonce.c[0];
-+    block128_f block = ctx->block;
-+    void *key = ctx->key;
-+    union {
-+        u64 u[2];
-+        u8 c[16];
-+    } scratch;
-+
-+    if (!(flags0 & 0x40))
-+        (*block) (ctx->nonce.c, ctx->cmac.c, key);
-+
-+    ctx->nonce.c[0] = L = flags0 & 7;
-+    for (n = 0, i = 15 - L; i < 15; ++i) {
-+        n |= ctx->nonce.c[i];
-+        ctx->nonce.c[i] = 0;
-+        n <<= 8;
-+    }
-+    n |= ctx->nonce.c[15];      /* reconstructed length */
-+    ctx->nonce.c[15] = 1;
-+
-+    if (n != len)
-+        return -1;
-+
-+    while (len >= 16) {
-+#if defined(STRICT_ALIGNMENT)
-+        union {
-+            u64 u[2];
-+            u8 c[16];
-+        } temp;
-+#endif
-+        (*block) (ctx->nonce.c, scratch.c, key);
-+        ctr64_inc(ctx->nonce.c);
-+#if defined(STRICT_ALIGNMENT)
-+        memcpy(temp.c, inp, 16);
-+        ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
-+        ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
-+        memcpy(out, scratch.c, 16);
-+#else
-+        ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]);
-+        ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]);
-+#endif
-+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
-+
-+        inp += 16;
-+        out += 16;
-+        len -= 16;
-+    }
-+
-+    if (len) {
-+        (*block) (ctx->nonce.c, scratch.c, key);
-+        for (i = 0; i < len; ++i)
-+            ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
-+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
-+    }
-+
-+    for (i = 15 - L; i < 16; ++i)
-+        ctx->nonce.c[i] = 0;
-+
-+    (*block) (ctx->nonce.c, scratch.c, key);
-+    ctx->cmac.u[0] ^= scratch.u[0];
-+    ctx->cmac.u[1] ^= scratch.u[1];
-+
-+    ctx->nonce.c[0] = flags0;
-+
-+    return 0;
-+}
-+
-+static void ctr64_add(unsigned char *counter, size_t inc)
-+{
-+    size_t n = 8, val = 0;
-+
-+    counter += 8;
-+    do {
-+        --n;
-+        val += counter[n] + (inc & 0xff);
-+        counter[n] = (unsigned char)val;
-+        val >>= 8;              /* carry bit */
-+        inc >>= 8;
-+    } while (n && (inc || val));
-+}
-+
-+int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
-+                                const unsigned char *inp, unsigned char *out,
-+                                size_t len, ccm128_f stream)
-+{
-+    size_t n;
-+    unsigned int i, L;
-+    unsigned char flags0 = ctx->nonce.c[0];
-+    block128_f block = ctx->block;
-+    void *key = ctx->key;
-+    union {
-+        u64 u[2];
-+        u8 c[16];
-+    } scratch;
-+
-+    if (!(flags0 & 0x40))
-+        (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
-+
-+    ctx->nonce.c[0] = L = flags0 & 7;
-+    for (n = 0, i = 15 - L; i < 15; ++i) {
-+        n |= ctx->nonce.c[i];
-+        ctx->nonce.c[i] = 0;
-+        n <<= 8;
-+    }
-+    n |= ctx->nonce.c[15];      /* reconstructed length */
-+    ctx->nonce.c[15] = 1;
-+
-+    if (n != len)
-+        return -1;              /* length mismatch */
-+
-+    ctx->blocks += ((len + 15) >> 3) | 1;
-+    if (ctx->blocks > (U64(1) << 61))
-+        return -2;              /* too much data */
-+
-+    if ((n = len / 16)) {
-+        (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
-+        n *= 16;
-+        inp += n;
-+        out += n;
-+        len -= n;
-+        if (len)
-+            ctr64_add(ctx->nonce.c, n / 16);
-+    }
-+
-+    if (len) {
-+        for (i = 0; i < len; ++i)
-+            ctx->cmac.c[i] ^= inp[i];
-+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
-+        (*block) (ctx->nonce.c, scratch.c, key);
-+        for (i = 0; i < len; ++i)
-+            out[i] = scratch.c[i] ^ inp[i];
-+    }
-+
-+    for (i = 15 - L; i < 16; ++i)
-+        ctx->nonce.c[i] = 0;
-+
-+    (*block) (ctx->nonce.c, scratch.c, key);
-+    ctx->cmac.u[0] ^= scratch.u[0];
-+    ctx->cmac.u[1] ^= scratch.u[1];
-+
-+    ctx->nonce.c[0] = flags0;
-+
-+    return 0;
-+}
-+
-+int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
-+                                const unsigned char *inp, unsigned char *out,
-+                                size_t len, ccm128_f stream)
-+{
-+    size_t n;
-+    unsigned int i, L;
-+    unsigned char flags0 = ctx->nonce.c[0];
-+    block128_f block = ctx->block;
-+    void *key = ctx->key;
-+    union {
-+        u64 u[2];
-+        u8 c[16];
-+    } scratch;
-+
-+    if (!(flags0 & 0x40))
-+        (*block) (ctx->nonce.c, ctx->cmac.c, key);
-+
-+    ctx->nonce.c[0] = L = flags0 & 7;
-+    for (n = 0, i = 15 - L; i < 15; ++i) {
-+        n |= ctx->nonce.c[i];
-+        ctx->nonce.c[i] = 0;
-+        n <<= 8;
-+    }
-+    n |= ctx->nonce.c[15];      /* reconstructed length */
-+    ctx->nonce.c[15] = 1;
-+
-+    if (n != len)
-+        return -1;
-+
-+    if ((n = len / 16)) {
-+        (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
-+        n *= 16;
-+        inp += n;
-+        out += n;
-+        len -= n;
-+        if (len)
-+            ctr64_add(ctx->nonce.c, n / 16);
-+    }
-+
-+    if (len) {
-+        (*block) (ctx->nonce.c, scratch.c, key);
-+        for (i = 0; i < len; ++i)
-+            ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
-+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
-+    }
-+
-+    for (i = 15 - L; i < 16; ++i)
-+        ctx->nonce.c[i] = 0;
-+
-+    (*block) (ctx->nonce.c, scratch.c, key);
-+    ctx->cmac.u[0] ^= scratch.u[0];
-+    ctx->cmac.u[1] ^= scratch.u[1];
-+
-+    ctx->nonce.c[0] = flags0;
-+
-+    return 0;
-+}
-+
-+size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
-+{
-+    unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */
-+
-+    M *= 2;
-+    M += 2;
-+    if (len < M)
-+        return 0;
-+    memcpy(tag, ctx->cmac.c, M);
-+    return M;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cfb128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cfb128.c
-new file mode 100644
-index 0000000..e439567
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cfb128.c
-@@ -0,0 +1,198 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "modes_lcl.h"
-+#include 
-+
-+/*
-+ * The input and output encrypted as though 128bit cfb mode is being used.
-+ * The extra state information to record how much of the 128bit block we have
-+ * used is contained in *num;
-+ */
-+void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const void *key,
-+                           unsigned char ivec[16], int *num,
-+                           int enc, block128_f block)
-+{
-+    unsigned int n;
-+    size_t l = 0;
-+
-+    n = *num;
-+
-+    if (enc) {
-+#if !defined(OPENSSL_SMALL_FOOTPRINT)
-+        if (16 % sizeof(size_t) == 0) { /* always true actually */
-+            do {
-+                while (n && len) {
-+                    *(out++) = ivec[n] ^= *(in++);
-+                    --len;
-+                    n = (n + 1) % 16;
-+                }
-+# if defined(STRICT_ALIGNMENT)
-+                if (((size_t)in | (size_t)out | (size_t)ivec) %
-+                    sizeof(size_t) != 0)
-+                    break;
-+# endif
-+                while (len >= 16) {
-+                    (*block) (ivec, ivec, key);
-+                    for (; n < 16; n += sizeof(size_t)) {
-+                        *(size_t *)(out + n) =
-+                            *(size_t *)(ivec + n) ^= *(size_t *)(in + n);
-+                    }
-+                    len -= 16;
-+                    out += 16;
-+                    in += 16;
-+                    n = 0;
-+                }
-+                if (len) {
-+                    (*block) (ivec, ivec, key);
-+                    while (len--) {
-+                        out[n] = ivec[n] ^= in[n];
-+                        ++n;
-+                    }
-+                }
-+                *num = n;
-+                return;
-+            } while (0);
-+        }
-+        /* the rest would be commonly eliminated by x86* compiler */
-+#endif
-+        while (l < len) {
-+            if (n == 0) {
-+                (*block) (ivec, ivec, key);
-+            }
-+            out[l] = ivec[n] ^= in[l];
-+            ++l;
-+            n = (n + 1) % 16;
-+        }
-+        *num = n;
-+    } else {
-+#if !defined(OPENSSL_SMALL_FOOTPRINT)
-+        if (16 % sizeof(size_t) == 0) { /* always true actually */
-+            do {
-+                while (n && len) {
-+                    unsigned char c;
-+                    *(out++) = ivec[n] ^ (c = *(in++));
-+                    ivec[n] = c;
-+                    --len;
-+                    n = (n + 1) % 16;
-+                }
-+# if defined(STRICT_ALIGNMENT)
-+                if (((size_t)in | (size_t)out | (size_t)ivec) %
-+                    sizeof(size_t) != 0)
-+                    break;
-+# endif
-+                while (len >= 16) {
-+                    (*block) (ivec, ivec, key);
-+                    for (; n < 16; n += sizeof(size_t)) {
-+                        size_t t = *(size_t *)(in + n);
-+                        *(size_t *)(out + n) = *(size_t *)(ivec + n) ^ t;
-+                        *(size_t *)(ivec + n) = t;
-+                    }
-+                    len -= 16;
-+                    out += 16;
-+                    in += 16;
-+                    n = 0;
-+                }
-+                if (len) {
-+                    (*block) (ivec, ivec, key);
-+                    while (len--) {
-+                        unsigned char c;
-+                        out[n] = ivec[n] ^ (c = in[n]);
-+                        ivec[n] = c;
-+                        ++n;
-+                    }
-+                }
-+                *num = n;
-+                return;
-+            } while (0);
-+        }
-+        /* the rest would be commonly eliminated by x86* compiler */
-+#endif
-+        while (l < len) {
-+            unsigned char c;
-+            if (n == 0) {
-+                (*block) (ivec, ivec, key);
-+            }
-+            out[l] = ivec[n] ^ (c = in[l]);
-+            ivec[n] = c;
-+            ++l;
-+            n = (n + 1) % 16;
-+        }
-+        *num = n;
-+    }
-+}
-+
-+/*
-+ * This expects a single block of size nbits for both in and out. Note that
-+ * it corrupts any extra bits in the last byte of out
-+ */
-+static void cfbr_encrypt_block(const unsigned char *in, unsigned char *out,
-+                               int nbits, const void *key,
-+                               unsigned char ivec[16], int enc,
-+                               block128_f block)
-+{
-+    int n, rem, num;
-+    unsigned char ovec[16 * 2 + 1]; /* +1 because we dereference (but don't
-+                                     * use) one byte off the end */
-+
-+    if (nbits <= 0 || nbits > 128)
-+        return;
-+
-+    /* fill in the first half of the new IV with the current IV */
-+    memcpy(ovec, ivec, 16);
-+    /* construct the new IV */
-+    (*block) (ivec, ivec, key);
-+    num = (nbits + 7) / 8;
-+    if (enc)                    /* encrypt the input */
-+        for (n = 0; n < num; ++n)
-+            out[n] = (ovec[16 + n] = in[n] ^ ivec[n]);
-+    else                        /* decrypt the input */
-+        for (n = 0; n < num; ++n)
-+            out[n] = (ovec[16 + n] = in[n]) ^ ivec[n];
-+    /* shift ovec left... */
-+    rem = nbits % 8;
-+    num = nbits / 8;
-+    if (rem == 0)
-+        memcpy(ivec, ovec + num, 16);
-+    else
-+        for (n = 0; n < 16; ++n)
-+            ivec[n] = ovec[n + num] << rem | ovec[n + num + 1] >> (8 - rem);
-+
-+    /* it is not necessary to cleanse ovec, since the IV is not secret */
-+}
-+
-+/* N.B. This expects the input to be packed, MS bit first */
-+void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
-+                             size_t bits, const void *key,
-+                             unsigned char ivec[16], int *num,
-+                             int enc, block128_f block)
-+{
-+    size_t n;
-+    unsigned char c[1], d[1];
-+
-+    for (n = 0; n < bits; ++n) {
-+        c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
-+        cfbr_encrypt_block(c, d, 1, key, ivec, enc, block);
-+        out[n / 8] = (out[n / 8] & ~(1 << (unsigned int)(7 - n % 8))) |
-+            ((d[0] & 0x80) >> (unsigned int)(n % 8));
-+    }
-+}
-+
-+void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
-+                             size_t length, const void *key,
-+                             unsigned char ivec[16], int *num,
-+                             int enc, block128_f block)
-+{
-+    size_t n;
-+
-+    for (n = 0; n < length; ++n)
-+        cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ctr128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ctr128.c
-new file mode 100644
-index 0000000..03920b4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ctr128.c
-@@ -0,0 +1,209 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "modes_lcl.h"
-+#include 
-+
-+/*
-+ * NOTE: the IV/counter CTR mode is big-endian.  The code itself is
-+ * endian-neutral.
-+ */
-+
-+/* increment counter (128-bit int) by 1 */
-+static void ctr128_inc(unsigned char *counter)
-+{
-+    u32 n = 16, c = 1;
-+
-+    do {
-+        --n;
-+        c += counter[n];
-+        counter[n] = (u8)c;
-+        c >>= 8;
-+    } while (n);
-+}
-+
-+#if !defined(OPENSSL_SMALL_FOOTPRINT)
-+static void ctr128_inc_aligned(unsigned char *counter)
-+{
-+    size_t *data, c, d, n;
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = {
-+        1
-+    };
-+
-+    if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) {
-+        ctr128_inc(counter);
-+        return;
-+    }
-+
-+    data = (size_t *)counter;
-+    c = 1;
-+    n = 16 / sizeof(size_t);
-+    do {
-+        --n;
-+        d = data[n] += c;
-+        /* did addition carry? */
-+        c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1);
-+    } while (n);
-+}
-+#endif
-+
-+/*
-+ * The input encrypted as though 128bit counter mode is being used.  The
-+ * extra state information to record how much of the 128bit block we have
-+ * used is contained in *num, and the encrypted counter is kept in
-+ * ecount_buf.  Both *num and ecount_buf must be initialised with zeros
-+ * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes
-+ * that the counter is in the x lower bits of the IV (ivec), and that the
-+ * application has full control over overflow and the rest of the IV.  This
-+ * implementation takes NO responsibility for checking that the counter
-+ * doesn't overflow into the rest of the IV when incremented.
-+ */
-+void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const void *key,
-+                           unsigned char ivec[16],
-+                           unsigned char ecount_buf[16], unsigned int *num,
-+                           block128_f block)
-+{
-+    unsigned int n;
-+    size_t l = 0;
-+
-+    n = *num;
-+
-+#if !defined(OPENSSL_SMALL_FOOTPRINT)
-+    if (16 % sizeof(size_t) == 0) { /* always true actually */
-+        do {
-+            while (n && len) {
-+                *(out++) = *(in++) ^ ecount_buf[n];
-+                --len;
-+                n = (n + 1) % 16;
-+            }
-+
-+# if defined(STRICT_ALIGNMENT)
-+            if (((size_t)in | (size_t)out | (size_t)ecount_buf)
-+                % sizeof(size_t) != 0)
-+                break;
-+# endif
-+            while (len >= 16) {
-+                (*block) (ivec, ecount_buf, key);
-+                ctr128_inc_aligned(ivec);
-+                for (n = 0; n < 16; n += sizeof(size_t))
-+                    *(size_t *)(out + n) =
-+                        *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
-+                len -= 16;
-+                out += 16;
-+                in += 16;
-+                n = 0;
-+            }
-+            if (len) {
-+                (*block) (ivec, ecount_buf, key);
-+                ctr128_inc_aligned(ivec);
-+                while (len--) {
-+                    out[n] = in[n] ^ ecount_buf[n];
-+                    ++n;
-+                }
-+            }
-+            *num = n;
-+            return;
-+        } while (0);
-+    }
-+    /* the rest would be commonly eliminated by x86* compiler */
-+#endif
-+    while (l < len) {
-+        if (n == 0) {
-+            (*block) (ivec, ecount_buf, key);
-+            ctr128_inc(ivec);
-+        }
-+        out[l] = in[l] ^ ecount_buf[n];
-+        ++l;
-+        n = (n + 1) % 16;
-+    }
-+
-+    *num = n;
-+}
-+
-+/* increment upper 96 bits of 128-bit counter by 1 */
-+static void ctr96_inc(unsigned char *counter)
-+{
-+    u32 n = 12, c = 1;
-+
-+    do {
-+        --n;
-+        c += counter[n];
-+        counter[n] = (u8)c;
-+        c >>= 8;
-+    } while (n);
-+}
-+
-+void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
-+                                 size_t len, const void *key,
-+                                 unsigned char ivec[16],
-+                                 unsigned char ecount_buf[16],
-+                                 unsigned int *num, ctr128_f func)
-+{
-+    unsigned int n, ctr32;
-+
-+    n = *num;
-+
-+    while (n && len) {
-+        *(out++) = *(in++) ^ ecount_buf[n];
-+        --len;
-+        n = (n + 1) % 16;
-+    }
-+
-+    ctr32 = GETU32(ivec + 12);
-+    while (len >= 16) {
-+        size_t blocks = len / 16;
-+        /*
-+         * 1<<28 is just a not-so-small yet not-so-large number...
-+         * Below condition is practically never met, but it has to
-+         * be checked for code correctness.
-+         */
-+        if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28))
-+            blocks = (1U << 28);
-+        /*
-+         * As (*func) operates on 32-bit counter, caller
-+         * has to handle overflow. 'if' below detects the
-+         * overflow, which is then handled by limiting the
-+         * amount of blocks to the exact overflow point...
-+         */
-+        ctr32 += (u32)blocks;
-+        if (ctr32 < blocks) {
-+            blocks -= ctr32;
-+            ctr32 = 0;
-+        }
-+        (*func) (in, out, blocks, key, ivec);
-+        /* (*ctr) does not update ivec, caller does: */
-+        PUTU32(ivec + 12, ctr32);
-+        /* ... overflow was detected, propagate carry. */
-+        if (ctr32 == 0)
-+            ctr96_inc(ivec);
-+        blocks *= 16;
-+        len -= blocks;
-+        out += blocks;
-+        in += blocks;
-+    }
-+    if (len) {
-+        memset(ecount_buf, 0, 16);
-+        (*func) (ecount_buf, ecount_buf, 1, key, ivec);
-+        ++ctr32;
-+        PUTU32(ivec + 12, ctr32);
-+        if (ctr32 == 0)
-+            ctr96_inc(ivec);
-+        while (len--) {
-+            out[n] = in[n] ^ ecount_buf[n];
-+            ++n;
-+        }
-+    }
-+
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cts128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cts128.c
-new file mode 100644
-index 0000000..77ec994
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/cts128.c
-@@ -0,0 +1,523 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "modes_lcl.h"
-+#include 
-+
-+/*
-+ * Trouble with Ciphertext Stealing, CTS, mode is that there is no
-+ * common official specification, but couple of cipher/application
-+ * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to
-+ * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which
-+ * deviates from mentioned RFCs. Most notably it allows input to be
-+ * of block length and it doesn't flip the order of the last two
-+ * blocks. CTS is being discussed even in ECB context, but it's not
-+ * adopted for any known application. This implementation provides
-+ * two interfaces: one compliant with above mentioned RFCs and one
-+ * compliant with the NIST proposal, both extending CBC mode.
-+ */
-+
-+size_t CRYPTO_cts128_encrypt_block(const unsigned char *in,
-+                                   unsigned char *out, size_t len,
-+                                   const void *key, unsigned char ivec[16],
-+                                   block128_f block)
-+{
-+    size_t residue, n;
-+
-+    if (len <= 16)
-+        return 0;
-+
-+    if ((residue = len % 16) == 0)
-+        residue = 16;
-+
-+    len -= residue;
-+
-+    CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block);
-+
-+    in += len;
-+    out += len;
-+
-+    for (n = 0; n < residue; ++n)
-+        ivec[n] ^= in[n];
-+    (*block) (ivec, ivec, key);
-+    memcpy(out, out - 16, residue);
-+    memcpy(out - 16, ivec, 16);
-+
-+    return len + residue;
-+}
-+
-+size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in,
-+                                       unsigned char *out, size_t len,
-+                                       const void *key,
-+                                       unsigned char ivec[16],
-+                                       block128_f block)
-+{
-+    size_t residue, n;
-+
-+    if (len < 16)
-+        return 0;
-+
-+    residue = len % 16;
-+
-+    len -= residue;
-+
-+    CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block);
-+
-+    if (residue == 0)
-+        return len;
-+
-+    in += len;
-+    out += len;
-+
-+    for (n = 0; n < residue; ++n)
-+        ivec[n] ^= in[n];
-+    (*block) (ivec, ivec, key);
-+    memcpy(out - 16 + residue, ivec, 16);
-+
-+    return len + residue;
-+}
-+
-+size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
-+                             size_t len, const void *key,
-+                             unsigned char ivec[16], cbc128_f cbc)
-+{
-+    size_t residue;
-+    union {
-+        size_t align;
-+        unsigned char c[16];
-+    } tmp;
-+
-+    if (len <= 16)
-+        return 0;
-+
-+    if ((residue = len % 16) == 0)
-+        residue = 16;
-+
-+    len -= residue;
-+
-+    (*cbc) (in, out, len, key, ivec, 1);
-+
-+    in += len;
-+    out += len;
-+
-+#if defined(CBC_HANDLES_TRUNCATED_IO)
-+    memcpy(tmp.c, out - 16, 16);
-+    (*cbc) (in, out - 16, residue, key, ivec, 1);
-+    memcpy(out, tmp.c, residue);
-+#else
-+    memset(tmp.c, 0, sizeof(tmp));
-+    memcpy(tmp.c, in, residue);
-+    memcpy(out, out - 16, residue);
-+    (*cbc) (tmp.c, out - 16, 16, key, ivec, 1);
-+#endif
-+    return len + residue;
-+}
-+
-+size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
-+                                 size_t len, const void *key,
-+                                 unsigned char ivec[16], cbc128_f cbc)
-+{
-+    size_t residue;
-+    union {
-+        size_t align;
-+        unsigned char c[16];
-+    } tmp;
-+
-+    if (len < 16)
-+        return 0;
-+
-+    residue = len % 16;
-+
-+    len -= residue;
-+
-+    (*cbc) (in, out, len, key, ivec, 1);
-+
-+    if (residue == 0)
-+        return len;
-+
-+    in += len;
-+    out += len;
-+
-+#if defined(CBC_HANDLES_TRUNCATED_IO)
-+    (*cbc) (in, out - 16 + residue, residue, key, ivec, 1);
-+#else
-+    memset(tmp.c, 0, sizeof(tmp));
-+    memcpy(tmp.c, in, residue);
-+    (*cbc) (tmp.c, out - 16 + residue, 16, key, ivec, 1);
-+#endif
-+    return len + residue;
-+}
-+
-+size_t CRYPTO_cts128_decrypt_block(const unsigned char *in,
-+                                   unsigned char *out, size_t len,
-+                                   const void *key, unsigned char ivec[16],
-+                                   block128_f block)
-+{
-+    size_t residue, n;
-+    union {
-+        size_t align;
-+        unsigned char c[32];
-+    } tmp;
-+
-+    if (len <= 16)
-+        return 0;
-+
-+    if ((residue = len % 16) == 0)
-+        residue = 16;
-+
-+    len -= 16 + residue;
-+
-+    if (len) {
-+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
-+        in += len;
-+        out += len;
-+    }
-+
-+    (*block) (in, tmp.c + 16, key);
-+
-+    memcpy(tmp.c, tmp.c + 16, 16);
-+    memcpy(tmp.c, in + 16, residue);
-+    (*block) (tmp.c, tmp.c, key);
-+
-+    for (n = 0; n < 16; ++n) {
-+        unsigned char c = in[n];
-+        out[n] = tmp.c[n] ^ ivec[n];
-+        ivec[n] = c;
-+    }
-+    for (residue += 16; n < residue; ++n)
-+        out[n] = tmp.c[n] ^ in[n];
-+
-+    return 16 + len + residue;
-+}
-+
-+size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in,
-+                                       unsigned char *out, size_t len,
-+                                       const void *key,
-+                                       unsigned char ivec[16],
-+                                       block128_f block)
-+{
-+    size_t residue, n;
-+    union {
-+        size_t align;
-+        unsigned char c[32];
-+    } tmp;
-+
-+    if (len < 16)
-+        return 0;
-+
-+    residue = len % 16;
-+
-+    if (residue == 0) {
-+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
-+        return len;
-+    }
-+
-+    len -= 16 + residue;
-+
-+    if (len) {
-+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
-+        in += len;
-+        out += len;
-+    }
-+
-+    (*block) (in + residue, tmp.c + 16, key);
-+
-+    memcpy(tmp.c, tmp.c + 16, 16);
-+    memcpy(tmp.c, in, residue);
-+    (*block) (tmp.c, tmp.c, key);
-+
-+    for (n = 0; n < 16; ++n) {
-+        unsigned char c = in[n];
-+        out[n] = tmp.c[n] ^ ivec[n];
-+        ivec[n] = in[n + residue];
-+        tmp.c[n] = c;
-+    }
-+    for (residue += 16; n < residue; ++n)
-+        out[n] = tmp.c[n] ^ tmp.c[n - 16];
-+
-+    return 16 + len + residue;
-+}
-+
-+size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
-+                             size_t len, const void *key,
-+                             unsigned char ivec[16], cbc128_f cbc)
-+{
-+    size_t residue;
-+    union {
-+        size_t align;
-+        unsigned char c[32];
-+    } tmp;
-+
-+    if (len <= 16)
-+        return 0;
-+
-+    if ((residue = len % 16) == 0)
-+        residue = 16;
-+
-+    len -= 16 + residue;
-+
-+    if (len) {
-+        (*cbc) (in, out, len, key, ivec, 0);
-+        in += len;
-+        out += len;
-+    }
-+
-+    memset(tmp.c, 0, sizeof(tmp));
-+    /*
-+     * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0]
-+     */
-+    (*cbc) (in, tmp.c, 16, key, tmp.c + 16, 0);
-+
-+    memcpy(tmp.c, in + 16, residue);
-+#if defined(CBC_HANDLES_TRUNCATED_IO)
-+    (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0);
-+#else
-+    (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0);
-+    memcpy(out, tmp.c, 16 + residue);
-+#endif
-+    return 16 + len + residue;
-+}
-+
-+size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
-+                                 size_t len, const void *key,
-+                                 unsigned char ivec[16], cbc128_f cbc)
-+{
-+    size_t residue;
-+    union {
-+        size_t align;
-+        unsigned char c[32];
-+    } tmp;
-+
-+    if (len < 16)
-+        return 0;
-+
-+    residue = len % 16;
-+
-+    if (residue == 0) {
-+        (*cbc) (in, out, len, key, ivec, 0);
-+        return len;
-+    }
-+
-+    len -= 16 + residue;
-+
-+    if (len) {
-+        (*cbc) (in, out, len, key, ivec, 0);
-+        in += len;
-+        out += len;
-+    }
-+
-+    memset(tmp.c, 0, sizeof(tmp));
-+    /*
-+     * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0]
-+     */
-+    (*cbc) (in + residue, tmp.c, 16, key, tmp.c + 16, 0);
-+
-+    memcpy(tmp.c, in, residue);
-+#if defined(CBC_HANDLES_TRUNCATED_IO)
-+    (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0);
-+#else
-+    (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0);
-+    memcpy(out, tmp.c, 16 + residue);
-+#endif
-+    return 16 + len + residue;
-+}
-+
-+#if defined(SELFTEST)
-+# include 
-+# include 
-+
-+/* test vectors from RFC 3962 */
-+static const unsigned char test_key[16] = "chicken teriyaki";
-+static const unsigned char test_input[64] =
-+    "I would like the" " General Gau's C"
-+    "hicken, please, " "and wonton soup.";
-+static const unsigned char test_iv[16] =
-+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-+
-+static const unsigned char vector_17[17] = {
-+    0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4,
-+    0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f,
-+    0x97
-+};
-+
-+static const unsigned char vector_31[31] = {
-+    0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1,
-+    0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22,
-+    0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
-+    0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5
-+};
-+
-+static const unsigned char vector_32[32] = {
-+    0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
-+    0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8,
-+    0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
-+    0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84
-+};
-+
-+static const unsigned char vector_47[47] = {
-+    0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
-+    0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
-+    0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c,
-+    0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e,
-+    0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
-+    0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5
-+};
-+
-+static const unsigned char vector_48[48] = {
-+    0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
-+    0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
-+    0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
-+    0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8,
-+    0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
-+    0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8
-+};
-+
-+static const unsigned char vector_64[64] = {
-+    0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
-+    0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
-+    0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
-+    0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8,
-+    0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5,
-+    0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40,
-+    0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
-+    0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8
-+};
-+
-+static AES_KEY encks, decks;
-+
-+void test_vector(const unsigned char *vector, size_t len)
-+{
-+    unsigned char iv[sizeof(test_iv)];
-+    unsigned char cleartext[64], ciphertext[64];
-+    size_t tail;
-+
-+    printf("vector_%d\n", len);
-+    fflush(stdout);
-+
-+    if ((tail = len % 16) == 0)
-+        tail = 16;
-+    tail += 16;
-+
-+    /* test block-based encryption */
-+    memcpy(iv, test_iv, sizeof(test_iv));
-+    CRYPTO_cts128_encrypt_block(test_input, ciphertext, len, &encks, iv,
-+                                (block128_f) AES_encrypt);
-+    if (memcmp(ciphertext, vector, len))
-+        fprintf(stderr, "output_%d mismatch\n", len), exit(1);
-+    if (memcmp(iv, vector + len - tail, sizeof(iv)))
-+        fprintf(stderr, "iv_%d mismatch\n", len), exit(1);
-+
-+    /* test block-based decryption */
-+    memcpy(iv, test_iv, sizeof(test_iv));
-+    CRYPTO_cts128_decrypt_block(ciphertext, cleartext, len, &decks, iv,
-+                                (block128_f) AES_decrypt);
-+    if (memcmp(cleartext, test_input, len))
-+        fprintf(stderr, "input_%d mismatch\n", len), exit(2);
-+    if (memcmp(iv, vector + len - tail, sizeof(iv)))
-+        fprintf(stderr, "iv_%d mismatch\n", len), exit(2);
-+
-+    /* test streamed encryption */
-+    memcpy(iv, test_iv, sizeof(test_iv));
-+    CRYPTO_cts128_encrypt(test_input, ciphertext, len, &encks, iv,
-+                          (cbc128_f) AES_cbc_encrypt);
-+    if (memcmp(ciphertext, vector, len))
-+        fprintf(stderr, "output_%d mismatch\n", len), exit(3);
-+    if (memcmp(iv, vector + len - tail, sizeof(iv)))
-+        fprintf(stderr, "iv_%d mismatch\n", len), exit(3);
-+
-+    /* test streamed decryption */
-+    memcpy(iv, test_iv, sizeof(test_iv));
-+    CRYPTO_cts128_decrypt(ciphertext, cleartext, len, &decks, iv,
-+                          (cbc128_f) AES_cbc_encrypt);
-+    if (memcmp(cleartext, test_input, len))
-+        fprintf(stderr, "input_%d mismatch\n", len), exit(4);
-+    if (memcmp(iv, vector + len - tail, sizeof(iv)))
-+        fprintf(stderr, "iv_%d mismatch\n", len), exit(4);
-+}
-+
-+void test_nistvector(const unsigned char *vector, size_t len)
-+{
-+    unsigned char iv[sizeof(test_iv)];
-+    unsigned char cleartext[64], ciphertext[64], nistvector[64];
-+    size_t tail;
-+
-+    printf("nistvector_%d\n", len);
-+    fflush(stdout);
-+
-+    if ((tail = len % 16) == 0)
-+        tail = 16;
-+
-+    len -= 16 + tail;
-+    memcpy(nistvector, vector, len);
-+    /* flip two last blocks */
-+    memcpy(nistvector + len, vector + len + 16, tail);
-+    memcpy(nistvector + len + tail, vector + len, 16);
-+    len += 16 + tail;
-+    tail = 16;
-+
-+    /* test block-based encryption */
-+    memcpy(iv, test_iv, sizeof(test_iv));
-+    CRYPTO_nistcts128_encrypt_block(test_input, ciphertext, len, &encks, iv,
-+                                    (block128_f) AES_encrypt);
-+    if (memcmp(ciphertext, nistvector, len))
-+        fprintf(stderr, "output_%d mismatch\n", len), exit(1);
-+    if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
-+        fprintf(stderr, "iv_%d mismatch\n", len), exit(1);
-+
-+    /* test block-based decryption */
-+    memcpy(iv, test_iv, sizeof(test_iv));
-+    CRYPTO_nistcts128_decrypt_block(ciphertext, cleartext, len, &decks, iv,
-+                                    (block128_f) AES_decrypt);
-+    if (memcmp(cleartext, test_input, len))
-+        fprintf(stderr, "input_%d mismatch\n", len), exit(2);
-+    if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
-+        fprintf(stderr, "iv_%d mismatch\n", len), exit(2);
-+
-+    /* test streamed encryption */
-+    memcpy(iv, test_iv, sizeof(test_iv));
-+    CRYPTO_nistcts128_encrypt(test_input, ciphertext, len, &encks, iv,
-+                              (cbc128_f) AES_cbc_encrypt);
-+    if (memcmp(ciphertext, nistvector, len))
-+        fprintf(stderr, "output_%d mismatch\n", len), exit(3);
-+    if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
-+        fprintf(stderr, "iv_%d mismatch\n", len), exit(3);
-+
-+    /* test streamed decryption */
-+    memcpy(iv, test_iv, sizeof(test_iv));
-+    CRYPTO_nistcts128_decrypt(ciphertext, cleartext, len, &decks, iv,
-+                              (cbc128_f) AES_cbc_encrypt);
-+    if (memcmp(cleartext, test_input, len))
-+        fprintf(stderr, "input_%d mismatch\n", len), exit(4);
-+    if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
-+        fprintf(stderr, "iv_%d mismatch\n", len), exit(4);
-+}
-+
-+int main()
-+{
-+    AES_set_encrypt_key(test_key, 128, &encks);
-+    AES_set_decrypt_key(test_key, 128, &decks);
-+
-+    test_vector(vector_17, sizeof(vector_17));
-+    test_vector(vector_31, sizeof(vector_31));
-+    test_vector(vector_32, sizeof(vector_32));
-+    test_vector(vector_47, sizeof(vector_47));
-+    test_vector(vector_48, sizeof(vector_48));
-+    test_vector(vector_64, sizeof(vector_64));
-+
-+    test_nistvector(vector_17, sizeof(vector_17));
-+    test_nistvector(vector_31, sizeof(vector_31));
-+    test_nistvector(vector_32, sizeof(vector_32));
-+    test_nistvector(vector_47, sizeof(vector_47));
-+    test_nistvector(vector_48, sizeof(vector_48));
-+    test_nistvector(vector_64, sizeof(vector_64));
-+
-+    return 0;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/gcm128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/gcm128.c
-new file mode 100644
-index 0000000..df9f654
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/gcm128.c
-@@ -0,0 +1,2302 @@
-+/*
-+ * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "modes_lcl.h"
-+#include 
-+
-+#if defined(BSWAP4) && defined(STRICT_ALIGNMENT)
-+/* redefine, because alignment is ensured */
-+# undef  GETU32
-+# define GETU32(p)       BSWAP4(*(const u32 *)(p))
-+# undef  PUTU32
-+# define PUTU32(p,v)     *(u32 *)(p) = BSWAP4(v)
-+#endif
-+
-+#define PACK(s)         ((size_t)(s)<<(sizeof(size_t)*8-16))
-+#define REDUCE1BIT(V)   do { \
-+        if (sizeof(size_t)==8) { \
-+                u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \
-+                V.lo  = (V.hi<<63)|(V.lo>>1); \
-+                V.hi  = (V.hi>>1 )^T; \
-+        } \
-+        else { \
-+                u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \
-+                V.lo  = (V.hi<<63)|(V.lo>>1); \
-+                V.hi  = (V.hi>>1 )^((u64)T<<32); \
-+        } \
-+} while(0)
-+
-+/*-
-+ * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
-+ * never be set to 8. 8 is effectively reserved for testing purposes.
-+ * TABLE_BITS>1 are lookup-table-driven implementations referred to as
-+ * "Shoup's" in GCM specification. In other words OpenSSL does not cover
-+ * whole spectrum of possible table driven implementations. Why? In
-+ * non-"Shoup's" case memory access pattern is segmented in such manner,
-+ * that it's trivial to see that cache timing information can reveal
-+ * fair portion of intermediate hash value. Given that ciphertext is
-+ * always available to attacker, it's possible for him to attempt to
-+ * deduce secret parameter H and if successful, tamper with messages
-+ * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's
-+ * not as trivial, but there is no reason to believe that it's resistant
-+ * to cache-timing attack. And the thing about "8-bit" implementation is
-+ * that it consumes 16 (sixteen) times more memory, 4KB per individual
-+ * key + 1KB shared. Well, on pros side it should be twice as fast as
-+ * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version
-+ * was observed to run ~75% faster, closer to 100% for commercial
-+ * compilers... Yet "4-bit" procedure is preferred, because it's
-+ * believed to provide better security-performance balance and adequate
-+ * all-round performance. "All-round" refers to things like:
-+ *
-+ * - shorter setup time effectively improves overall timing for
-+ *   handling short messages;
-+ * - larger table allocation can become unbearable because of VM
-+ *   subsystem penalties (for example on Windows large enough free
-+ *   results in VM working set trimming, meaning that consequent
-+ *   malloc would immediately incur working set expansion);
-+ * - larger table has larger cache footprint, which can affect
-+ *   performance of other code paths (not necessarily even from same
-+ *   thread in Hyper-Threading world);
-+ *
-+ * Value of 1 is not appropriate for performance reasons.
-+ */
-+#if     TABLE_BITS==8
-+
-+static void gcm_init_8bit(u128 Htable[256], u64 H[2])
-+{
-+    int i, j;
-+    u128 V;
-+
-+    Htable[0].hi = 0;
-+    Htable[0].lo = 0;
-+    V.hi = H[0];
-+    V.lo = H[1];
-+
-+    for (Htable[128] = V, i = 64; i > 0; i >>= 1) {
-+        REDUCE1BIT(V);
-+        Htable[i] = V;
-+    }
-+
-+    for (i = 2; i < 256; i <<= 1) {
-+        u128 *Hi = Htable + i, H0 = *Hi;
-+        for (j = 1; j < i; ++j) {
-+            Hi[j].hi = H0.hi ^ Htable[j].hi;
-+            Hi[j].lo = H0.lo ^ Htable[j].lo;
-+        }
-+    }
-+}
-+
-+static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256])
-+{
-+    u128 Z = { 0, 0 };
-+    const u8 *xi = (const u8 *)Xi + 15;
-+    size_t rem, n = *xi;
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+    static const size_t rem_8bit[256] = {
-+        PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246),
-+        PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E),
-+        PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56),
-+        PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E),
-+        PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66),
-+        PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E),
-+        PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076),
-+        PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E),
-+        PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06),
-+        PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E),
-+        PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416),
-+        PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E),
-+        PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626),
-+        PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E),
-+        PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836),
-+        PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E),
-+        PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6),
-+        PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE),
-+        PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6),
-+        PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE),
-+        PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6),
-+        PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE),
-+        PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6),
-+        PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE),
-+        PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86),
-+        PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E),
-+        PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496),
-+        PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E),
-+        PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6),
-+        PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE),
-+        PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6),
-+        PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE),
-+        PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346),
-+        PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E),
-+        PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56),
-+        PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E),
-+        PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66),
-+        PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E),
-+        PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176),
-+        PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E),
-+        PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06),
-+        PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E),
-+        PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516),
-+        PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E),
-+        PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726),
-+        PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E),
-+        PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936),
-+        PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E),
-+        PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6),
-+        PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE),
-+        PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6),
-+        PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE),
-+        PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6),
-+        PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE),
-+        PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6),
-+        PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE),
-+        PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86),
-+        PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E),
-+        PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596),
-+        PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E),
-+        PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6),
-+        PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE),
-+        PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6),
-+        PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE)
-+    };
-+
-+    while (1) {
-+        Z.hi ^= Htable[n].hi;
-+        Z.lo ^= Htable[n].lo;
-+
-+        if ((u8 *)Xi == xi)
-+            break;
-+
-+        n = *(--xi);
-+
-+        rem = (size_t)Z.lo & 0xff;
-+        Z.lo = (Z.hi << 56) | (Z.lo >> 8);
-+        Z.hi = (Z.hi >> 8);
-+        if (sizeof(size_t) == 8)
-+            Z.hi ^= rem_8bit[rem];
-+        else
-+            Z.hi ^= (u64)rem_8bit[rem] << 32;
-+    }
-+
-+    if (is_endian.little) {
-+# ifdef BSWAP8
-+        Xi[0] = BSWAP8(Z.hi);
-+        Xi[1] = BSWAP8(Z.lo);
-+# else
-+        u8 *p = (u8 *)Xi;
-+        u32 v;
-+        v = (u32)(Z.hi >> 32);
-+        PUTU32(p, v);
-+        v = (u32)(Z.hi);
-+        PUTU32(p + 4, v);
-+        v = (u32)(Z.lo >> 32);
-+        PUTU32(p + 8, v);
-+        v = (u32)(Z.lo);
-+        PUTU32(p + 12, v);
-+# endif
-+    } else {
-+        Xi[0] = Z.hi;
-+        Xi[1] = Z.lo;
-+    }
-+}
-+
-+# define GCM_MUL(ctx,Xi)   gcm_gmult_8bit(ctx->Xi.u,ctx->Htable)
-+
-+#elif   TABLE_BITS==4
-+
-+static void gcm_init_4bit(u128 Htable[16], u64 H[2])
-+{
-+    u128 V;
-+# if defined(OPENSSL_SMALL_FOOTPRINT)
-+    int i;
-+# endif
-+
-+    Htable[0].hi = 0;
-+    Htable[0].lo = 0;
-+    V.hi = H[0];
-+    V.lo = H[1];
-+
-+# if defined(OPENSSL_SMALL_FOOTPRINT)
-+    for (Htable[8] = V, i = 4; i > 0; i >>= 1) {
-+        REDUCE1BIT(V);
-+        Htable[i] = V;
-+    }
-+
-+    for (i = 2; i < 16; i <<= 1) {
-+        u128 *Hi = Htable + i;
-+        int j;
-+        for (V = *Hi, j = 1; j < i; ++j) {
-+            Hi[j].hi = V.hi ^ Htable[j].hi;
-+            Hi[j].lo = V.lo ^ Htable[j].lo;
-+        }
-+    }
-+# else
-+    Htable[8] = V;
-+    REDUCE1BIT(V);
-+    Htable[4] = V;
-+    REDUCE1BIT(V);
-+    Htable[2] = V;
-+    REDUCE1BIT(V);
-+    Htable[1] = V;
-+    Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo;
-+    V = Htable[4];
-+    Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo;
-+    Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo;
-+    Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo;
-+    V = Htable[8];
-+    Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo;
-+    Htable[10].hi = V.hi ^ Htable[2].hi, Htable[10].lo = V.lo ^ Htable[2].lo;
-+    Htable[11].hi = V.hi ^ Htable[3].hi, Htable[11].lo = V.lo ^ Htable[3].lo;
-+    Htable[12].hi = V.hi ^ Htable[4].hi, Htable[12].lo = V.lo ^ Htable[4].lo;
-+    Htable[13].hi = V.hi ^ Htable[5].hi, Htable[13].lo = V.lo ^ Htable[5].lo;
-+    Htable[14].hi = V.hi ^ Htable[6].hi, Htable[14].lo = V.lo ^ Htable[6].lo;
-+    Htable[15].hi = V.hi ^ Htable[7].hi, Htable[15].lo = V.lo ^ Htable[7].lo;
-+# endif
-+# if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm))
-+    /*
-+     * ARM assembler expects specific dword order in Htable.
-+     */
-+    {
-+        int j;
-+        const union {
-+            long one;
-+            char little;
-+        } is_endian = { 1 };
-+
-+        if (is_endian.little)
-+            for (j = 0; j < 16; ++j) {
-+                V = Htable[j];
-+                Htable[j].hi = V.lo;
-+                Htable[j].lo = V.hi;
-+        } else
-+            for (j = 0; j < 16; ++j) {
-+                V = Htable[j];
-+                Htable[j].hi = V.lo << 32 | V.lo >> 32;
-+                Htable[j].lo = V.hi << 32 | V.hi >> 32;
-+            }
-+    }
-+# endif
-+}
-+
-+# ifndef GHASH_ASM
-+static const size_t rem_4bit[16] = {
-+    PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460),
-+    PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0),
-+    PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560),
-+    PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0)
-+};
-+
-+static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16])
-+{
-+    u128 Z;
-+    int cnt = 15;
-+    size_t rem, nlo, nhi;
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+
-+    nlo = ((const u8 *)Xi)[15];
-+    nhi = nlo >> 4;
-+    nlo &= 0xf;
-+
-+    Z.hi = Htable[nlo].hi;
-+    Z.lo = Htable[nlo].lo;
-+
-+    while (1) {
-+        rem = (size_t)Z.lo & 0xf;
-+        Z.lo = (Z.hi << 60) | (Z.lo >> 4);
-+        Z.hi = (Z.hi >> 4);
-+        if (sizeof(size_t) == 8)
-+            Z.hi ^= rem_4bit[rem];
-+        else
-+            Z.hi ^= (u64)rem_4bit[rem] << 32;
-+
-+        Z.hi ^= Htable[nhi].hi;
-+        Z.lo ^= Htable[nhi].lo;
-+
-+        if (--cnt < 0)
-+            break;
-+
-+        nlo = ((const u8 *)Xi)[cnt];
-+        nhi = nlo >> 4;
-+        nlo &= 0xf;
-+
-+        rem = (size_t)Z.lo & 0xf;
-+        Z.lo = (Z.hi << 60) | (Z.lo >> 4);
-+        Z.hi = (Z.hi >> 4);
-+        if (sizeof(size_t) == 8)
-+            Z.hi ^= rem_4bit[rem];
-+        else
-+            Z.hi ^= (u64)rem_4bit[rem] << 32;
-+
-+        Z.hi ^= Htable[nlo].hi;
-+        Z.lo ^= Htable[nlo].lo;
-+    }
-+
-+    if (is_endian.little) {
-+#  ifdef BSWAP8
-+        Xi[0] = BSWAP8(Z.hi);
-+        Xi[1] = BSWAP8(Z.lo);
-+#  else
-+        u8 *p = (u8 *)Xi;
-+        u32 v;
-+        v = (u32)(Z.hi >> 32);
-+        PUTU32(p, v);
-+        v = (u32)(Z.hi);
-+        PUTU32(p + 4, v);
-+        v = (u32)(Z.lo >> 32);
-+        PUTU32(p + 8, v);
-+        v = (u32)(Z.lo);
-+        PUTU32(p + 12, v);
-+#  endif
-+    } else {
-+        Xi[0] = Z.hi;
-+        Xi[1] = Z.lo;
-+    }
-+}
-+
-+#  if !defined(OPENSSL_SMALL_FOOTPRINT)
-+/*
-+ * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for
-+ * details... Compiler-generated code doesn't seem to give any
-+ * performance improvement, at least not on x86[_64]. It's here
-+ * mostly as reference and a placeholder for possible future
-+ * non-trivial optimization[s]...
-+ */
-+static void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16],
-+                           const u8 *inp, size_t len)
-+{
-+    u128 Z;
-+    int cnt;
-+    size_t rem, nlo, nhi;
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+
-+#   if 1
-+    do {
-+        cnt = 15;
-+        nlo = ((const u8 *)Xi)[15];
-+        nlo ^= inp[15];
-+        nhi = nlo >> 4;
-+        nlo &= 0xf;
-+
-+        Z.hi = Htable[nlo].hi;
-+        Z.lo = Htable[nlo].lo;
-+
-+        while (1) {
-+            rem = (size_t)Z.lo & 0xf;
-+            Z.lo = (Z.hi << 60) | (Z.lo >> 4);
-+            Z.hi = (Z.hi >> 4);
-+            if (sizeof(size_t) == 8)
-+                Z.hi ^= rem_4bit[rem];
-+            else
-+                Z.hi ^= (u64)rem_4bit[rem] << 32;
-+
-+            Z.hi ^= Htable[nhi].hi;
-+            Z.lo ^= Htable[nhi].lo;
-+
-+            if (--cnt < 0)
-+                break;
-+
-+            nlo = ((const u8 *)Xi)[cnt];
-+            nlo ^= inp[cnt];
-+            nhi = nlo >> 4;
-+            nlo &= 0xf;
-+
-+            rem = (size_t)Z.lo & 0xf;
-+            Z.lo = (Z.hi << 60) | (Z.lo >> 4);
-+            Z.hi = (Z.hi >> 4);
-+            if (sizeof(size_t) == 8)
-+                Z.hi ^= rem_4bit[rem];
-+            else
-+                Z.hi ^= (u64)rem_4bit[rem] << 32;
-+
-+            Z.hi ^= Htable[nlo].hi;
-+            Z.lo ^= Htable[nlo].lo;
-+        }
-+#   else
-+    /*
-+     * Extra 256+16 bytes per-key plus 512 bytes shared tables
-+     * [should] give ~50% improvement... One could have PACK()-ed
-+     * the rem_8bit even here, but the priority is to minimize
-+     * cache footprint...
-+     */
-+    u128 Hshr4[16];             /* Htable shifted right by 4 bits */
-+    u8 Hshl4[16];               /* Htable shifted left by 4 bits */
-+    static const unsigned short rem_8bit[256] = {
-+        0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E,
-+        0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E,
-+        0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E,
-+        0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E,
-+        0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E,
-+        0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E,
-+        0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E,
-+        0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E,
-+        0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE,
-+        0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE,
-+        0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE,
-+        0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE,
-+        0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E,
-+        0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E,
-+        0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE,
-+        0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE,
-+        0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E,
-+        0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E,
-+        0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E,
-+        0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E,
-+        0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E,
-+        0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E,
-+        0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E,
-+        0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E,
-+        0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE,
-+        0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE,
-+        0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE,
-+        0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE,
-+        0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E,
-+        0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E,
-+        0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE,
-+        0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE
-+    };
-+    /*
-+     * This pre-processing phase slows down procedure by approximately
-+     * same time as it makes each loop spin faster. In other words
-+     * single block performance is approximately same as straightforward
-+     * "4-bit" implementation, and then it goes only faster...
-+     */
-+    for (cnt = 0; cnt < 16; ++cnt) {
-+        Z.hi = Htable[cnt].hi;
-+        Z.lo = Htable[cnt].lo;
-+        Hshr4[cnt].lo = (Z.hi << 60) | (Z.lo >> 4);
-+        Hshr4[cnt].hi = (Z.hi >> 4);
-+        Hshl4[cnt] = (u8)(Z.lo << 4);
-+    }
-+
-+    do {
-+        for (Z.lo = 0, Z.hi = 0, cnt = 15; cnt; --cnt) {
-+            nlo = ((const u8 *)Xi)[cnt];
-+            nlo ^= inp[cnt];
-+            nhi = nlo >> 4;
-+            nlo &= 0xf;
-+
-+            Z.hi ^= Htable[nlo].hi;
-+            Z.lo ^= Htable[nlo].lo;
-+
-+            rem = (size_t)Z.lo & 0xff;
-+
-+            Z.lo = (Z.hi << 56) | (Z.lo >> 8);
-+            Z.hi = (Z.hi >> 8);
-+
-+            Z.hi ^= Hshr4[nhi].hi;
-+            Z.lo ^= Hshr4[nhi].lo;
-+            Z.hi ^= (u64)rem_8bit[rem ^ Hshl4[nhi]] << 48;
-+        }
-+
-+        nlo = ((const u8 *)Xi)[0];
-+        nlo ^= inp[0];
-+        nhi = nlo >> 4;
-+        nlo &= 0xf;
-+
-+        Z.hi ^= Htable[nlo].hi;
-+        Z.lo ^= Htable[nlo].lo;
-+
-+        rem = (size_t)Z.lo & 0xf;
-+
-+        Z.lo = (Z.hi << 60) | (Z.lo >> 4);
-+        Z.hi = (Z.hi >> 4);
-+
-+        Z.hi ^= Htable[nhi].hi;
-+        Z.lo ^= Htable[nhi].lo;
-+        Z.hi ^= ((u64)rem_8bit[rem << 4]) << 48;
-+#   endif
-+
-+        if (is_endian.little) {
-+#   ifdef BSWAP8
-+            Xi[0] = BSWAP8(Z.hi);
-+            Xi[1] = BSWAP8(Z.lo);
-+#   else
-+            u8 *p = (u8 *)Xi;
-+            u32 v;
-+            v = (u32)(Z.hi >> 32);
-+            PUTU32(p, v);
-+            v = (u32)(Z.hi);
-+            PUTU32(p + 4, v);
-+            v = (u32)(Z.lo >> 32);
-+            PUTU32(p + 8, v);
-+            v = (u32)(Z.lo);
-+            PUTU32(p + 12, v);
-+#   endif
-+        } else {
-+            Xi[0] = Z.hi;
-+            Xi[1] = Z.lo;
-+        }
-+    } while (inp += 16, len -= 16);
-+}
-+#  endif
-+# else
-+void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]);
-+void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const u8 *inp,
-+                    size_t len);
-+# endif
-+
-+# define GCM_MUL(ctx,Xi)   gcm_gmult_4bit(ctx->Xi.u,ctx->Htable)
-+# if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT)
-+#  define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len)
-+/*
-+ * GHASH_CHUNK is "stride parameter" missioned to mitigate cache trashing
-+ * effect. In other words idea is to hash data while it's still in L1 cache
-+ * after encryption pass...
-+ */
-+#  define GHASH_CHUNK       (3*1024)
-+# endif
-+
-+#else                           /* TABLE_BITS */
-+
-+static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2])
-+{
-+    u128 V, Z = { 0, 0 };
-+    long X;
-+    int i, j;
-+    const long *xi = (const long *)Xi;
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+
-+    V.hi = H[0];                /* H is in host byte order, no byte swapping */
-+    V.lo = H[1];
-+
-+    for (j = 0; j < 16 / sizeof(long); ++j) {
-+        if (is_endian.little) {
-+            if (sizeof(long) == 8) {
-+# ifdef BSWAP8
-+                X = (long)(BSWAP8(xi[j]));
-+# else
-+                const u8 *p = (const u8 *)(xi + j);
-+                X = (long)((u64)GETU32(p) << 32 | GETU32(p + 4));
-+# endif
-+            } else {
-+                const u8 *p = (const u8 *)(xi + j);
-+                X = (long)GETU32(p);
-+            }
-+        } else
-+            X = xi[j];
-+
-+        for (i = 0; i < 8 * sizeof(long); ++i, X <<= 1) {
-+            u64 M = (u64)(X >> (8 * sizeof(long) - 1));
-+            Z.hi ^= V.hi & M;
-+            Z.lo ^= V.lo & M;
-+
-+            REDUCE1BIT(V);
-+        }
-+    }
-+
-+    if (is_endian.little) {
-+# ifdef BSWAP8
-+        Xi[0] = BSWAP8(Z.hi);
-+        Xi[1] = BSWAP8(Z.lo);
-+# else
-+        u8 *p = (u8 *)Xi;
-+        u32 v;
-+        v = (u32)(Z.hi >> 32);
-+        PUTU32(p, v);
-+        v = (u32)(Z.hi);
-+        PUTU32(p + 4, v);
-+        v = (u32)(Z.lo >> 32);
-+        PUTU32(p + 8, v);
-+        v = (u32)(Z.lo);
-+        PUTU32(p + 12, v);
-+# endif
-+    } else {
-+        Xi[0] = Z.hi;
-+        Xi[1] = Z.lo;
-+    }
-+}
-+
-+# define GCM_MUL(ctx,Xi)   gcm_gmult_1bit(ctx->Xi.u,ctx->H.u)
-+
-+#endif
-+
-+#if     TABLE_BITS==4 && (defined(GHASH_ASM) || defined(OPENSSL_CPUID_OBJ))
-+# if    !defined(I386_ONLY) && \
-+        (defined(__i386)        || defined(__i386__)    || \
-+         defined(__x86_64)      || defined(__x86_64__)  || \
-+         defined(_M_IX86)       || defined(_M_AMD64)    || defined(_M_X64))
-+#  define GHASH_ASM_X86_OR_64
-+#  define GCM_FUNCREF_4BIT
-+extern unsigned int OPENSSL_ia32cap_P[];
-+
-+void gcm_init_clmul(u128 Htable[16], const u64 Xi[2]);
-+void gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]);
-+void gcm_ghash_clmul(u64 Xi[2], const u128 Htable[16], const u8 *inp,
-+                     size_t len);
-+
-+#  if defined(__i386) || defined(__i386__) || defined(_M_IX86)
-+#   define gcm_init_avx   gcm_init_clmul
-+#   define gcm_gmult_avx  gcm_gmult_clmul
-+#   define gcm_ghash_avx  gcm_ghash_clmul
-+#  else
-+void gcm_init_avx(u128 Htable[16], const u64 Xi[2]);
-+void gcm_gmult_avx(u64 Xi[2], const u128 Htable[16]);
-+void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *inp,
-+                   size_t len);
-+#  endif
-+
-+#  if   defined(__i386) || defined(__i386__) || defined(_M_IX86)
-+#   define GHASH_ASM_X86
-+void gcm_gmult_4bit_mmx(u64 Xi[2], const u128 Htable[16]);
-+void gcm_ghash_4bit_mmx(u64 Xi[2], const u128 Htable[16], const u8 *inp,
-+                        size_t len);
-+
-+void gcm_gmult_4bit_x86(u64 Xi[2], const u128 Htable[16]);
-+void gcm_ghash_4bit_x86(u64 Xi[2], const u128 Htable[16], const u8 *inp,
-+                        size_t len);
-+#  endif
-+# elif defined(__arm__) || defined(__arm) || defined(__aarch64__)
-+#  include "arm_arch.h"
-+#  if __ARM_MAX_ARCH__>=7
-+#   define GHASH_ASM_ARM
-+#   define GCM_FUNCREF_4BIT
-+#   define PMULL_CAPABLE        (OPENSSL_armcap_P & ARMV8_PMULL)
-+#   if defined(__arm__) || defined(__arm)
-+#    define NEON_CAPABLE        (OPENSSL_armcap_P & ARMV7_NEON)
-+#   endif
-+void gcm_init_neon(u128 Htable[16], const u64 Xi[2]);
-+void gcm_gmult_neon(u64 Xi[2], const u128 Htable[16]);
-+void gcm_ghash_neon(u64 Xi[2], const u128 Htable[16], const u8 *inp,
-+                    size_t len);
-+void gcm_init_v8(u128 Htable[16], const u64 Xi[2]);
-+void gcm_gmult_v8(u64 Xi[2], const u128 Htable[16]);
-+void gcm_ghash_v8(u64 Xi[2], const u128 Htable[16], const u8 *inp,
-+                  size_t len);
-+#  endif
-+# elif defined(__sparc__) || defined(__sparc)
-+#  include "sparc_arch.h"
-+#  define GHASH_ASM_SPARC
-+#  define GCM_FUNCREF_4BIT
-+extern unsigned int OPENSSL_sparcv9cap_P[];
-+void gcm_init_vis3(u128 Htable[16], const u64 Xi[2]);
-+void gcm_gmult_vis3(u64 Xi[2], const u128 Htable[16]);
-+void gcm_ghash_vis3(u64 Xi[2], const u128 Htable[16], const u8 *inp,
-+                    size_t len);
-+# elif defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
-+#  include "ppc_arch.h"
-+#  define GHASH_ASM_PPC
-+#  define GCM_FUNCREF_4BIT
-+void gcm_init_p8(u128 Htable[16], const u64 Xi[2]);
-+void gcm_gmult_p8(u64 Xi[2], const u128 Htable[16]);
-+void gcm_ghash_p8(u64 Xi[2], const u128 Htable[16], const u8 *inp,
-+                  size_t len);
-+# endif
-+#endif
-+
-+#ifdef GCM_FUNCREF_4BIT
-+# undef  GCM_MUL
-+# define GCM_MUL(ctx,Xi)        (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable)
-+# ifdef GHASH
-+#  undef  GHASH
-+#  define GHASH(ctx,in,len)     (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len)
-+# endif
-+#endif
-+
-+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+
-+    memset(ctx, 0, sizeof(*ctx));
-+    ctx->block = block;
-+    ctx->key = key;
-+
-+    (*block) (ctx->H.c, ctx->H.c, key);
-+
-+    if (is_endian.little) {
-+        /* H is stored in host byte order */
-+#ifdef BSWAP8
-+        ctx->H.u[0] = BSWAP8(ctx->H.u[0]);
-+        ctx->H.u[1] = BSWAP8(ctx->H.u[1]);
-+#else
-+        u8 *p = ctx->H.c;
-+        u64 hi, lo;
-+        hi = (u64)GETU32(p) << 32 | GETU32(p + 4);
-+        lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
-+        ctx->H.u[0] = hi;
-+        ctx->H.u[1] = lo;
-+#endif
-+    }
-+#if     TABLE_BITS==8
-+    gcm_init_8bit(ctx->Htable, ctx->H.u);
-+#elif   TABLE_BITS==4
-+# if    defined(GHASH)
-+#  define CTX__GHASH(f) (ctx->ghash = (f))
-+# else
-+#  define CTX__GHASH(f) (ctx->ghash = NULL)
-+# endif
-+# if    defined(GHASH_ASM_X86_OR_64)
-+#  if   !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2)
-+    if (OPENSSL_ia32cap_P[0] & (1 << 24) && /* check FXSR bit */
-+        OPENSSL_ia32cap_P[1] & (1 << 1)) { /* check PCLMULQDQ bit */
-+        if (((OPENSSL_ia32cap_P[1] >> 22) & 0x41) == 0x41) { /* AVX+MOVBE */
-+            gcm_init_avx(ctx->Htable, ctx->H.u);
-+            ctx->gmult = gcm_gmult_avx;
-+            CTX__GHASH(gcm_ghash_avx);
-+        } else {
-+            gcm_init_clmul(ctx->Htable, ctx->H.u);
-+            ctx->gmult = gcm_gmult_clmul;
-+            CTX__GHASH(gcm_ghash_clmul);
-+        }
-+        return;
-+    }
-+#  endif
-+    gcm_init_4bit(ctx->Htable, ctx->H.u);
-+#  if   defined(GHASH_ASM_X86)  /* x86 only */
-+#   if  defined(OPENSSL_IA32_SSE2)
-+    if (OPENSSL_ia32cap_P[0] & (1 << 25)) { /* check SSE bit */
-+#   else
-+    if (OPENSSL_ia32cap_P[0] & (1 << 23)) { /* check MMX bit */
-+#   endif
-+        ctx->gmult = gcm_gmult_4bit_mmx;
-+        CTX__GHASH(gcm_ghash_4bit_mmx);
-+    } else {
-+        ctx->gmult = gcm_gmult_4bit_x86;
-+        CTX__GHASH(gcm_ghash_4bit_x86);
-+    }
-+#  else
-+    ctx->gmult = gcm_gmult_4bit;
-+    CTX__GHASH(gcm_ghash_4bit);
-+#  endif
-+# elif  defined(GHASH_ASM_ARM)
-+#  ifdef PMULL_CAPABLE
-+    if (PMULL_CAPABLE) {
-+        gcm_init_v8(ctx->Htable, ctx->H.u);
-+        ctx->gmult = gcm_gmult_v8;
-+        CTX__GHASH(gcm_ghash_v8);
-+    } else
-+#  endif
-+#  ifdef NEON_CAPABLE
-+    if (NEON_CAPABLE) {
-+        gcm_init_neon(ctx->Htable, ctx->H.u);
-+        ctx->gmult = gcm_gmult_neon;
-+        CTX__GHASH(gcm_ghash_neon);
-+    } else
-+#  endif
-+    {
-+        gcm_init_4bit(ctx->Htable, ctx->H.u);
-+        ctx->gmult = gcm_gmult_4bit;
-+        CTX__GHASH(gcm_ghash_4bit);
-+    }
-+# elif  defined(GHASH_ASM_SPARC)
-+    if (OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3) {
-+        gcm_init_vis3(ctx->Htable, ctx->H.u);
-+        ctx->gmult = gcm_gmult_vis3;
-+        CTX__GHASH(gcm_ghash_vis3);
-+    } else {
-+        gcm_init_4bit(ctx->Htable, ctx->H.u);
-+        ctx->gmult = gcm_gmult_4bit;
-+        CTX__GHASH(gcm_ghash_4bit);
-+    }
-+# elif  defined(GHASH_ASM_PPC)
-+    if (OPENSSL_ppccap_P & PPC_CRYPTO207) {
-+        gcm_init_p8(ctx->Htable, ctx->H.u);
-+        ctx->gmult = gcm_gmult_p8;
-+        CTX__GHASH(gcm_ghash_p8);
-+    } else {
-+        gcm_init_4bit(ctx->Htable, ctx->H.u);
-+        ctx->gmult = gcm_gmult_4bit;
-+        CTX__GHASH(gcm_ghash_4bit);
-+    }
-+# else
-+    gcm_init_4bit(ctx->Htable, ctx->H.u);
-+# endif
-+# undef CTX__GHASH
-+#endif
-+}
-+
-+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv,
-+                         size_t len)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+    unsigned int ctr;
-+#ifdef GCM_FUNCREF_4BIT
-+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
-+#endif
-+
-+    ctx->Yi.u[0] = 0;
-+    ctx->Yi.u[1] = 0;
-+    ctx->Xi.u[0] = 0;
-+    ctx->Xi.u[1] = 0;
-+    ctx->len.u[0] = 0;          /* AAD length */
-+    ctx->len.u[1] = 0;          /* message length */
-+    ctx->ares = 0;
-+    ctx->mres = 0;
-+
-+    if (len == 12) {
-+        memcpy(ctx->Yi.c, iv, 12);
-+        ctx->Yi.c[15] = 1;
-+        ctr = 1;
-+    } else {
-+        size_t i;
-+        u64 len0 = len;
-+
-+        while (len >= 16) {
-+            for (i = 0; i < 16; ++i)
-+                ctx->Yi.c[i] ^= iv[i];
-+            GCM_MUL(ctx, Yi);
-+            iv += 16;
-+            len -= 16;
-+        }
-+        if (len) {
-+            for (i = 0; i < len; ++i)
-+                ctx->Yi.c[i] ^= iv[i];
-+            GCM_MUL(ctx, Yi);
-+        }
-+        len0 <<= 3;
-+        if (is_endian.little) {
-+#ifdef BSWAP8
-+            ctx->Yi.u[1] ^= BSWAP8(len0);
-+#else
-+            ctx->Yi.c[8] ^= (u8)(len0 >> 56);
-+            ctx->Yi.c[9] ^= (u8)(len0 >> 48);
-+            ctx->Yi.c[10] ^= (u8)(len0 >> 40);
-+            ctx->Yi.c[11] ^= (u8)(len0 >> 32);
-+            ctx->Yi.c[12] ^= (u8)(len0 >> 24);
-+            ctx->Yi.c[13] ^= (u8)(len0 >> 16);
-+            ctx->Yi.c[14] ^= (u8)(len0 >> 8);
-+            ctx->Yi.c[15] ^= (u8)(len0);
-+#endif
-+        } else
-+            ctx->Yi.u[1] ^= len0;
-+
-+        GCM_MUL(ctx, Yi);
-+
-+        if (is_endian.little)
-+#ifdef BSWAP4
-+            ctr = BSWAP4(ctx->Yi.d[3]);
-+#else
-+            ctr = GETU32(ctx->Yi.c + 12);
-+#endif
-+        else
-+            ctr = ctx->Yi.d[3];
-+    }
-+
-+    (*ctx->block) (ctx->Yi.c, ctx->EK0.c, ctx->key);
-+    ++ctr;
-+    if (is_endian.little)
-+#ifdef BSWAP4
-+        ctx->Yi.d[3] = BSWAP4(ctr);
-+#else
-+        PUTU32(ctx->Yi.c + 12, ctr);
-+#endif
-+    else
-+        ctx->Yi.d[3] = ctr;
-+}
-+
-+int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad,
-+                      size_t len)
-+{
-+    size_t i;
-+    unsigned int n;
-+    u64 alen = ctx->len.u[0];
-+#ifdef GCM_FUNCREF_4BIT
-+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
-+# ifdef GHASH
-+    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
-+                         const u8 *inp, size_t len) = ctx->ghash;
-+# endif
-+#endif
-+
-+    if (ctx->len.u[1])
-+        return -2;
-+
-+    alen += len;
-+    if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len))
-+        return -1;
-+    ctx->len.u[0] = alen;
-+
-+    n = ctx->ares;
-+    if (n) {
-+        while (n && len) {
-+            ctx->Xi.c[n] ^= *(aad++);
-+            --len;
-+            n = (n + 1) % 16;
-+        }
-+        if (n == 0)
-+            GCM_MUL(ctx, Xi);
-+        else {
-+            ctx->ares = n;
-+            return 0;
-+        }
-+    }
-+#ifdef GHASH
-+    if ((i = (len & (size_t)-16))) {
-+        GHASH(ctx, aad, i);
-+        aad += i;
-+        len -= i;
-+    }
-+#else
-+    while (len >= 16) {
-+        for (i = 0; i < 16; ++i)
-+            ctx->Xi.c[i] ^= aad[i];
-+        GCM_MUL(ctx, Xi);
-+        aad += 16;
-+        len -= 16;
-+    }
-+#endif
-+    if (len) {
-+        n = (unsigned int)len;
-+        for (i = 0; i < len; ++i)
-+            ctx->Xi.c[i] ^= aad[i];
-+    }
-+
-+    ctx->ares = n;
-+    return 0;
-+}
-+
-+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
-+                          const unsigned char *in, unsigned char *out,
-+                          size_t len)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+    unsigned int n, ctr;
-+    size_t i;
-+    u64 mlen = ctx->len.u[1];
-+    block128_f block = ctx->block;
-+    void *key = ctx->key;
-+#ifdef GCM_FUNCREF_4BIT
-+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
-+# if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
-+    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
-+                         const u8 *inp, size_t len) = ctx->ghash;
-+# endif
-+#endif
-+
-+    mlen += len;
-+    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
-+        return -1;
-+    ctx->len.u[1] = mlen;
-+
-+    if (ctx->ares) {
-+        /* First call to encrypt finalizes GHASH(AAD) */
-+        GCM_MUL(ctx, Xi);
-+        ctx->ares = 0;
-+    }
-+
-+    if (is_endian.little)
-+#ifdef BSWAP4
-+        ctr = BSWAP4(ctx->Yi.d[3]);
-+#else
-+        ctr = GETU32(ctx->Yi.c + 12);
-+#endif
-+    else
-+        ctr = ctx->Yi.d[3];
-+
-+    n = ctx->mres;
-+#if !defined(OPENSSL_SMALL_FOOTPRINT)
-+    if (16 % sizeof(size_t) == 0) { /* always true actually */
-+        do {
-+            if (n) {
-+                while (n && len) {
-+                    ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n];
-+                    --len;
-+                    n = (n + 1) % 16;
-+                }
-+                if (n == 0)
-+                    GCM_MUL(ctx, Xi);
-+                else {
-+                    ctx->mres = n;
-+                    return 0;
-+                }
-+            }
-+# if defined(STRICT_ALIGNMENT)
-+            if (((size_t)in | (size_t)out) % sizeof(size_t) != 0)
-+                break;
-+# endif
-+# if defined(GHASH)
-+#  if defined(GHASH_CHUNK)
-+            while (len >= GHASH_CHUNK) {
-+                size_t j = GHASH_CHUNK;
-+
-+                while (j) {
-+                    size_t *out_t = (size_t *)out;
-+                    const size_t *in_t = (const size_t *)in;
-+
-+                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
-+                    ++ctr;
-+                    if (is_endian.little)
-+#   ifdef BSWAP4
-+                        ctx->Yi.d[3] = BSWAP4(ctr);
-+#   else
-+                        PUTU32(ctx->Yi.c + 12, ctr);
-+#   endif
-+                    else
-+                        ctx->Yi.d[3] = ctr;
-+                    for (i = 0; i < 16 / sizeof(size_t); ++i)
-+                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
-+                    out += 16;
-+                    in += 16;
-+                    j -= 16;
-+                }
-+                GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK);
-+                len -= GHASH_CHUNK;
-+            }
-+#  endif
-+            if ((i = (len & (size_t)-16))) {
-+                size_t j = i;
-+
-+                while (len >= 16) {
-+                    size_t *out_t = (size_t *)out;
-+                    const size_t *in_t = (const size_t *)in;
-+
-+                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
-+                    ++ctr;
-+                    if (is_endian.little)
-+#  ifdef BSWAP4
-+                        ctx->Yi.d[3] = BSWAP4(ctr);
-+#  else
-+                        PUTU32(ctx->Yi.c + 12, ctr);
-+#  endif
-+                    else
-+                        ctx->Yi.d[3] = ctr;
-+                    for (i = 0; i < 16 / sizeof(size_t); ++i)
-+                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
-+                    out += 16;
-+                    in += 16;
-+                    len -= 16;
-+                }
-+                GHASH(ctx, out - j, j);
-+            }
-+# else
-+            while (len >= 16) {
-+                size_t *out_t = (size_t *)out;
-+                const size_t *in_t = (const size_t *)in;
-+
-+                (*block) (ctx->Yi.c, ctx->EKi.c, key);
-+                ++ctr;
-+                if (is_endian.little)
-+#  ifdef BSWAP4
-+                    ctx->Yi.d[3] = BSWAP4(ctr);
-+#  else
-+                    PUTU32(ctx->Yi.c + 12, ctr);
-+#  endif
-+                else
-+                    ctx->Yi.d[3] = ctr;
-+                for (i = 0; i < 16 / sizeof(size_t); ++i)
-+                    ctx->Xi.t[i] ^= out_t[i] = in_t[i] ^ ctx->EKi.t[i];
-+                GCM_MUL(ctx, Xi);
-+                out += 16;
-+                in += 16;
-+                len -= 16;
-+            }
-+# endif
-+            if (len) {
-+                (*block) (ctx->Yi.c, ctx->EKi.c, key);
-+                ++ctr;
-+                if (is_endian.little)
-+# ifdef BSWAP4
-+                    ctx->Yi.d[3] = BSWAP4(ctr);
-+# else
-+                    PUTU32(ctx->Yi.c + 12, ctr);
-+# endif
-+                else
-+                    ctx->Yi.d[3] = ctr;
-+                while (len--) {
-+                    ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n];
-+                    ++n;
-+                }
-+            }
-+
-+            ctx->mres = n;
-+            return 0;
-+        } while (0);
-+    }
-+#endif
-+    for (i = 0; i < len; ++i) {
-+        if (n == 0) {
-+            (*block) (ctx->Yi.c, ctx->EKi.c, key);
-+            ++ctr;
-+            if (is_endian.little)
-+#ifdef BSWAP4
-+                ctx->Yi.d[3] = BSWAP4(ctr);
-+#else
-+                PUTU32(ctx->Yi.c + 12, ctr);
-+#endif
-+            else
-+                ctx->Yi.d[3] = ctr;
-+        }
-+        ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n];
-+        n = (n + 1) % 16;
-+        if (n == 0)
-+            GCM_MUL(ctx, Xi);
-+    }
-+
-+    ctx->mres = n;
-+    return 0;
-+}
-+
-+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
-+                          const unsigned char *in, unsigned char *out,
-+                          size_t len)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+    unsigned int n, ctr;
-+    size_t i;
-+    u64 mlen = ctx->len.u[1];
-+    block128_f block = ctx->block;
-+    void *key = ctx->key;
-+#ifdef GCM_FUNCREF_4BIT
-+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
-+# if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
-+    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
-+                         const u8 *inp, size_t len) = ctx->ghash;
-+# endif
-+#endif
-+
-+    mlen += len;
-+    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
-+        return -1;
-+    ctx->len.u[1] = mlen;
-+
-+    if (ctx->ares) {
-+        /* First call to decrypt finalizes GHASH(AAD) */
-+        GCM_MUL(ctx, Xi);
-+        ctx->ares = 0;
-+    }
-+
-+    if (is_endian.little)
-+#ifdef BSWAP4
-+        ctr = BSWAP4(ctx->Yi.d[3]);
-+#else
-+        ctr = GETU32(ctx->Yi.c + 12);
-+#endif
-+    else
-+        ctr = ctx->Yi.d[3];
-+
-+    n = ctx->mres;
-+#if !defined(OPENSSL_SMALL_FOOTPRINT)
-+    if (16 % sizeof(size_t) == 0) { /* always true actually */
-+        do {
-+            if (n) {
-+                while (n && len) {
-+                    u8 c = *(in++);
-+                    *(out++) = c ^ ctx->EKi.c[n];
-+                    ctx->Xi.c[n] ^= c;
-+                    --len;
-+                    n = (n + 1) % 16;
-+                }
-+                if (n == 0)
-+                    GCM_MUL(ctx, Xi);
-+                else {
-+                    ctx->mres = n;
-+                    return 0;
-+                }
-+            }
-+# if defined(STRICT_ALIGNMENT)
-+            if (((size_t)in | (size_t)out) % sizeof(size_t) != 0)
-+                break;
-+# endif
-+# if defined(GHASH)
-+#  if defined(GHASH_CHUNK)
-+            while (len >= GHASH_CHUNK) {
-+                size_t j = GHASH_CHUNK;
-+
-+                GHASH(ctx, in, GHASH_CHUNK);
-+                while (j) {
-+                    size_t *out_t = (size_t *)out;
-+                    const size_t *in_t = (const size_t *)in;
-+
-+                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
-+                    ++ctr;
-+                    if (is_endian.little)
-+#   ifdef BSWAP4
-+                        ctx->Yi.d[3] = BSWAP4(ctr);
-+#   else
-+                        PUTU32(ctx->Yi.c + 12, ctr);
-+#   endif
-+                    else
-+                        ctx->Yi.d[3] = ctr;
-+                    for (i = 0; i < 16 / sizeof(size_t); ++i)
-+                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
-+                    out += 16;
-+                    in += 16;
-+                    j -= 16;
-+                }
-+                len -= GHASH_CHUNK;
-+            }
-+#  endif
-+            if ((i = (len & (size_t)-16))) {
-+                GHASH(ctx, in, i);
-+                while (len >= 16) {
-+                    size_t *out_t = (size_t *)out;
-+                    const size_t *in_t = (const size_t *)in;
-+
-+                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
-+                    ++ctr;
-+                    if (is_endian.little)
-+#  ifdef BSWAP4
-+                        ctx->Yi.d[3] = BSWAP4(ctr);
-+#  else
-+                        PUTU32(ctx->Yi.c + 12, ctr);
-+#  endif
-+                    else
-+                        ctx->Yi.d[3] = ctr;
-+                    for (i = 0; i < 16 / sizeof(size_t); ++i)
-+                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
-+                    out += 16;
-+                    in += 16;
-+                    len -= 16;
-+                }
-+            }
-+# else
-+            while (len >= 16) {
-+                size_t *out_t = (size_t *)out;
-+                const size_t *in_t = (const size_t *)in;
-+
-+                (*block) (ctx->Yi.c, ctx->EKi.c, key);
-+                ++ctr;
-+                if (is_endian.little)
-+#  ifdef BSWAP4
-+                    ctx->Yi.d[3] = BSWAP4(ctr);
-+#  else
-+                    PUTU32(ctx->Yi.c + 12, ctr);
-+#  endif
-+                else
-+                    ctx->Yi.d[3] = ctr;
-+                for (i = 0; i < 16 / sizeof(size_t); ++i) {
-+                    size_t c = in[i];
-+                    out[i] = c ^ ctx->EKi.t[i];
-+                    ctx->Xi.t[i] ^= c;
-+                }
-+                GCM_MUL(ctx, Xi);
-+                out += 16;
-+                in += 16;
-+                len -= 16;
-+            }
-+# endif
-+            if (len) {
-+                (*block) (ctx->Yi.c, ctx->EKi.c, key);
-+                ++ctr;
-+                if (is_endian.little)
-+# ifdef BSWAP4
-+                    ctx->Yi.d[3] = BSWAP4(ctr);
-+# else
-+                    PUTU32(ctx->Yi.c + 12, ctr);
-+# endif
-+                else
-+                    ctx->Yi.d[3] = ctr;
-+                while (len--) {
-+                    u8 c = in[n];
-+                    ctx->Xi.c[n] ^= c;
-+                    out[n] = c ^ ctx->EKi.c[n];
-+                    ++n;
-+                }
-+            }
-+
-+            ctx->mres = n;
-+            return 0;
-+        } while (0);
-+    }
-+#endif
-+    for (i = 0; i < len; ++i) {
-+        u8 c;
-+        if (n == 0) {
-+            (*block) (ctx->Yi.c, ctx->EKi.c, key);
-+            ++ctr;
-+            if (is_endian.little)
-+#ifdef BSWAP4
-+                ctx->Yi.d[3] = BSWAP4(ctr);
-+#else
-+                PUTU32(ctx->Yi.c + 12, ctr);
-+#endif
-+            else
-+                ctx->Yi.d[3] = ctr;
-+        }
-+        c = in[i];
-+        out[i] = c ^ ctx->EKi.c[n];
-+        ctx->Xi.c[n] ^= c;
-+        n = (n + 1) % 16;
-+        if (n == 0)
-+            GCM_MUL(ctx, Xi);
-+    }
-+
-+    ctx->mres = n;
-+    return 0;
-+}
-+
-+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
-+                                const unsigned char *in, unsigned char *out,
-+                                size_t len, ctr128_f stream)
-+{
-+#if defined(OPENSSL_SMALL_FOOTPRINT)
-+    return CRYPTO_gcm128_encrypt(ctx, in, out, len);
-+#else
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+    unsigned int n, ctr;
-+    size_t i;
-+    u64 mlen = ctx->len.u[1];
-+    void *key = ctx->key;
-+# ifdef GCM_FUNCREF_4BIT
-+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
-+#  ifdef GHASH
-+    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
-+                         const u8 *inp, size_t len) = ctx->ghash;
-+#  endif
-+# endif
-+
-+    mlen += len;
-+    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
-+        return -1;
-+    ctx->len.u[1] = mlen;
-+
-+    if (ctx->ares) {
-+        /* First call to encrypt finalizes GHASH(AAD) */
-+        GCM_MUL(ctx, Xi);
-+        ctx->ares = 0;
-+    }
-+
-+    if (is_endian.little)
-+# ifdef BSWAP4
-+        ctr = BSWAP4(ctx->Yi.d[3]);
-+# else
-+        ctr = GETU32(ctx->Yi.c + 12);
-+# endif
-+    else
-+        ctr = ctx->Yi.d[3];
-+
-+    n = ctx->mres;
-+    if (n) {
-+        while (n && len) {
-+            ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n];
-+            --len;
-+            n = (n + 1) % 16;
-+        }
-+        if (n == 0)
-+            GCM_MUL(ctx, Xi);
-+        else {
-+            ctx->mres = n;
-+            return 0;
-+        }
-+    }
-+# if defined(GHASH) && defined(GHASH_CHUNK)
-+    while (len >= GHASH_CHUNK) {
-+        (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c);
-+        ctr += GHASH_CHUNK / 16;
-+        if (is_endian.little)
-+#  ifdef BSWAP4
-+            ctx->Yi.d[3] = BSWAP4(ctr);
-+#  else
-+            PUTU32(ctx->Yi.c + 12, ctr);
-+#  endif
-+        else
-+            ctx->Yi.d[3] = ctr;
-+        GHASH(ctx, out, GHASH_CHUNK);
-+        out += GHASH_CHUNK;
-+        in += GHASH_CHUNK;
-+        len -= GHASH_CHUNK;
-+    }
-+# endif
-+    if ((i = (len & (size_t)-16))) {
-+        size_t j = i / 16;
-+
-+        (*stream) (in, out, j, key, ctx->Yi.c);
-+        ctr += (unsigned int)j;
-+        if (is_endian.little)
-+# ifdef BSWAP4
-+            ctx->Yi.d[3] = BSWAP4(ctr);
-+# else
-+            PUTU32(ctx->Yi.c + 12, ctr);
-+# endif
-+        else
-+            ctx->Yi.d[3] = ctr;
-+        in += i;
-+        len -= i;
-+# if defined(GHASH)
-+        GHASH(ctx, out, i);
-+        out += i;
-+# else
-+        while (j--) {
-+            for (i = 0; i < 16; ++i)
-+                ctx->Xi.c[i] ^= out[i];
-+            GCM_MUL(ctx, Xi);
-+            out += 16;
-+        }
-+# endif
-+    }
-+    if (len) {
-+        (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key);
-+        ++ctr;
-+        if (is_endian.little)
-+# ifdef BSWAP4
-+            ctx->Yi.d[3] = BSWAP4(ctr);
-+# else
-+            PUTU32(ctx->Yi.c + 12, ctr);
-+# endif
-+        else
-+            ctx->Yi.d[3] = ctr;
-+        while (len--) {
-+            ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n];
-+            ++n;
-+        }
-+    }
-+
-+    ctx->mres = n;
-+    return 0;
-+#endif
-+}
-+
-+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
-+                                const unsigned char *in, unsigned char *out,
-+                                size_t len, ctr128_f stream)
-+{
-+#if defined(OPENSSL_SMALL_FOOTPRINT)
-+    return CRYPTO_gcm128_decrypt(ctx, in, out, len);
-+#else
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+    unsigned int n, ctr;
-+    size_t i;
-+    u64 mlen = ctx->len.u[1];
-+    void *key = ctx->key;
-+# ifdef GCM_FUNCREF_4BIT
-+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
-+#  ifdef GHASH
-+    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
-+                         const u8 *inp, size_t len) = ctx->ghash;
-+#  endif
-+# endif
-+
-+    mlen += len;
-+    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
-+        return -1;
-+    ctx->len.u[1] = mlen;
-+
-+    if (ctx->ares) {
-+        /* First call to decrypt finalizes GHASH(AAD) */
-+        GCM_MUL(ctx, Xi);
-+        ctx->ares = 0;
-+    }
-+
-+    if (is_endian.little)
-+# ifdef BSWAP4
-+        ctr = BSWAP4(ctx->Yi.d[3]);
-+# else
-+        ctr = GETU32(ctx->Yi.c + 12);
-+# endif
-+    else
-+        ctr = ctx->Yi.d[3];
-+
-+    n = ctx->mres;
-+    if (n) {
-+        while (n && len) {
-+            u8 c = *(in++);
-+            *(out++) = c ^ ctx->EKi.c[n];
-+            ctx->Xi.c[n] ^= c;
-+            --len;
-+            n = (n + 1) % 16;
-+        }
-+        if (n == 0)
-+            GCM_MUL(ctx, Xi);
-+        else {
-+            ctx->mres = n;
-+            return 0;
-+        }
-+    }
-+# if defined(GHASH) && defined(GHASH_CHUNK)
-+    while (len >= GHASH_CHUNK) {
-+        GHASH(ctx, in, GHASH_CHUNK);
-+        (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c);
-+        ctr += GHASH_CHUNK / 16;
-+        if (is_endian.little)
-+#  ifdef BSWAP4
-+            ctx->Yi.d[3] = BSWAP4(ctr);
-+#  else
-+            PUTU32(ctx->Yi.c + 12, ctr);
-+#  endif
-+        else
-+            ctx->Yi.d[3] = ctr;
-+        out += GHASH_CHUNK;
-+        in += GHASH_CHUNK;
-+        len -= GHASH_CHUNK;
-+    }
-+# endif
-+    if ((i = (len & (size_t)-16))) {
-+        size_t j = i / 16;
-+
-+# if defined(GHASH)
-+        GHASH(ctx, in, i);
-+# else
-+        while (j--) {
-+            size_t k;
-+            for (k = 0; k < 16; ++k)
-+                ctx->Xi.c[k] ^= in[k];
-+            GCM_MUL(ctx, Xi);
-+            in += 16;
-+        }
-+        j = i / 16;
-+        in -= i;
-+# endif
-+        (*stream) (in, out, j, key, ctx->Yi.c);
-+        ctr += (unsigned int)j;
-+        if (is_endian.little)
-+# ifdef BSWAP4
-+            ctx->Yi.d[3] = BSWAP4(ctr);
-+# else
-+            PUTU32(ctx->Yi.c + 12, ctr);
-+# endif
-+        else
-+            ctx->Yi.d[3] = ctr;
-+        out += i;
-+        in += i;
-+        len -= i;
-+    }
-+    if (len) {
-+        (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key);
-+        ++ctr;
-+        if (is_endian.little)
-+# ifdef BSWAP4
-+            ctx->Yi.d[3] = BSWAP4(ctr);
-+# else
-+            PUTU32(ctx->Yi.c + 12, ctr);
-+# endif
-+        else
-+            ctx->Yi.d[3] = ctr;
-+        while (len--) {
-+            u8 c = in[n];
-+            ctx->Xi.c[n] ^= c;
-+            out[n] = c ^ ctx->EKi.c[n];
-+            ++n;
-+        }
-+    }
-+
-+    ctx->mres = n;
-+    return 0;
-+#endif
-+}
-+
-+int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
-+                         size_t len)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = { 1 };
-+    u64 alen = ctx->len.u[0] << 3;
-+    u64 clen = ctx->len.u[1] << 3;
-+#ifdef GCM_FUNCREF_4BIT
-+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
-+#endif
-+
-+    if (ctx->mres || ctx->ares)
-+        GCM_MUL(ctx, Xi);
-+
-+    if (is_endian.little) {
-+#ifdef BSWAP8
-+        alen = BSWAP8(alen);
-+        clen = BSWAP8(clen);
-+#else
-+        u8 *p = ctx->len.c;
-+
-+        ctx->len.u[0] = alen;
-+        ctx->len.u[1] = clen;
-+
-+        alen = (u64)GETU32(p) << 32 | GETU32(p + 4);
-+        clen = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
-+#endif
-+    }
-+
-+    ctx->Xi.u[0] ^= alen;
-+    ctx->Xi.u[1] ^= clen;
-+    GCM_MUL(ctx, Xi);
-+
-+    ctx->Xi.u[0] ^= ctx->EK0.u[0];
-+    ctx->Xi.u[1] ^= ctx->EK0.u[1];
-+
-+    if (tag && len <= sizeof(ctx->Xi))
-+        return CRYPTO_memcmp(ctx->Xi.c, tag, len);
-+    else
-+        return -1;
-+}
-+
-+void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
-+{
-+    CRYPTO_gcm128_finish(ctx, NULL, 0);
-+    memcpy(tag, ctx->Xi.c,
-+           len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c));
-+}
-+
-+GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block)
-+{
-+    GCM128_CONTEXT *ret;
-+
-+    if ((ret = OPENSSL_malloc(sizeof(*ret))) != NULL)
-+        CRYPTO_gcm128_init(ret, key, block);
-+
-+    return ret;
-+}
-+
-+void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx)
-+{
-+    OPENSSL_clear_free(ctx, sizeof(*ctx));
-+}
-+
-+#if defined(SELFTEST)
-+# include 
-+# include 
-+
-+/* Test Case 1 */
-+static const u8 K1[16], *P1 = NULL, *A1 = NULL, IV1[12], *C1 = NULL;
-+static const u8 T1[] = {
-+    0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
-+    0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a
-+};
-+
-+/* Test Case 2 */
-+# define K2 K1
-+# define A2 A1
-+# define IV2 IV1
-+static const u8 P2[16];
-+static const u8 C2[] = {
-+    0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
-+    0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78
-+};
-+
-+static const u8 T2[] = {
-+    0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
-+    0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf
-+};
-+
-+/* Test Case 3 */
-+# define A3 A2
-+static const u8 K3[] = {
-+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
-+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
-+};
-+
-+static const u8 P3[] = {
-+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
-+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
-+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
-+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
-+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
-+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
-+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
-+    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
-+};
-+
-+static const u8 IV3[] = {
-+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
-+    0xde, 0xca, 0xf8, 0x88
-+};
-+
-+static const u8 C3[] = {
-+    0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
-+    0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
-+    0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
-+    0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
-+    0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
-+    0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
-+    0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
-+    0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85
-+};
-+
-+static const u8 T3[] = {
-+    0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
-+    0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4
-+};
-+
-+/* Test Case 4 */
-+# define K4 K3
-+# define IV4 IV3
-+static const u8 P4[] = {
-+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
-+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
-+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
-+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
-+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
-+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
-+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
-+    0xba, 0x63, 0x7b, 0x39
-+};
-+
-+static const u8 A4[] = {
-+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
-+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
-+    0xab, 0xad, 0xda, 0xd2
-+};
-+
-+static const u8 C4[] = {
-+    0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
-+    0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
-+    0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
-+    0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
-+    0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
-+    0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
-+    0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
-+    0x3d, 0x58, 0xe0, 0x91
-+};
-+
-+static const u8 T4[] = {
-+    0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
-+    0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47
-+};
-+
-+/* Test Case 5 */
-+# define K5 K4
-+# define P5 P4
-+# define A5 A4
-+static const u8 IV5[] = {
-+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad
-+};
-+
-+static const u8 C5[] = {
-+    0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
-+    0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
-+    0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
-+    0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
-+    0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
-+    0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
-+    0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
-+    0xc2, 0x3f, 0x45, 0x98
-+};
-+
-+static const u8 T5[] = {
-+    0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
-+    0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb
-+};
-+
-+/* Test Case 6 */
-+# define K6 K5
-+# define P6 P5
-+# define A6 A5
-+static const u8 IV6[] = {
-+    0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
-+    0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
-+    0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
-+    0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
-+    0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
-+    0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
-+    0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
-+    0xa6, 0x37, 0xb3, 0x9b
-+};
-+
-+static const u8 C6[] = {
-+    0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
-+    0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
-+    0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
-+    0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
-+    0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
-+    0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
-+    0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
-+    0x4c, 0x34, 0xae, 0xe5
-+};
-+
-+static const u8 T6[] = {
-+    0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
-+    0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50
-+};
-+
-+/* Test Case 7 */
-+static const u8 K7[24], *P7 = NULL, *A7 = NULL, IV7[12], *C7 = NULL;
-+static const u8 T7[] = {
-+    0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
-+    0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35
-+};
-+
-+/* Test Case 8 */
-+# define K8 K7
-+# define IV8 IV7
-+# define A8 A7
-+static const u8 P8[16];
-+static const u8 C8[] = {
-+    0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
-+    0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00
-+};
-+
-+static const u8 T8[] = {
-+    0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
-+    0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb
-+};
-+
-+/* Test Case 9 */
-+# define A9 A8
-+static const u8 K9[] = {
-+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
-+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
-+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c
-+};
-+
-+static const u8 P9[] = {
-+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
-+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
-+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
-+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
-+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
-+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
-+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
-+    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
-+};
-+
-+static const u8 IV9[] = {
-+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
-+    0xde, 0xca, 0xf8, 0x88
-+};
-+
-+static const u8 C9[] = {
-+    0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
-+    0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
-+    0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
-+    0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
-+    0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
-+    0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
-+    0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
-+    0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56
-+};
-+
-+static const u8 T9[] = {
-+    0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
-+    0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14
-+};
-+
-+/* Test Case 10 */
-+# define K10 K9
-+# define IV10 IV9
-+static const u8 P10[] = {
-+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
-+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
-+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
-+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
-+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
-+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
-+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
-+    0xba, 0x63, 0x7b, 0x39
-+};
-+
-+static const u8 A10[] = {
-+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
-+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
-+    0xab, 0xad, 0xda, 0xd2
-+};
-+
-+static const u8 C10[] = {
-+    0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
-+    0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
-+    0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
-+    0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
-+    0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
-+    0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
-+    0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
-+    0xcc, 0xda, 0x27, 0x10
-+};
-+
-+static const u8 T10[] = {
-+    0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
-+    0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c
-+};
-+
-+/* Test Case 11 */
-+# define K11 K10
-+# define P11 P10
-+# define A11 A10
-+static const u8 IV11[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
-+
-+static const u8 C11[] = {
-+    0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
-+    0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
-+    0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
-+    0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
-+    0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
-+    0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
-+    0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
-+    0xa0, 0xf0, 0x62, 0xf7
-+};
-+
-+static const u8 T11[] = {
-+    0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
-+    0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8
-+};
-+
-+/* Test Case 12 */
-+# define K12 K11
-+# define P12 P11
-+# define A12 A11
-+static const u8 IV12[] = {
-+    0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
-+    0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
-+    0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
-+    0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
-+    0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
-+    0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
-+    0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
-+    0xa6, 0x37, 0xb3, 0x9b
-+};
-+
-+static const u8 C12[] = {
-+    0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
-+    0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
-+    0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
-+    0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
-+    0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
-+    0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
-+    0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
-+    0xe9, 0xb7, 0x37, 0x3b
-+};
-+
-+static const u8 T12[] = {
-+    0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
-+    0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9
-+};
-+
-+/* Test Case 13 */
-+static const u8 K13[32], *P13 = NULL, *A13 = NULL, IV13[12], *C13 = NULL;
-+static const u8 T13[] = {
-+    0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
-+    0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b
-+};
-+
-+/* Test Case 14 */
-+# define K14 K13
-+# define A14 A13
-+static const u8 P14[16], IV14[12];
-+static const u8 C14[] = {
-+    0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
-+    0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18
-+};
-+
-+static const u8 T14[] = {
-+    0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
-+    0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19
-+};
-+
-+/* Test Case 15 */
-+# define A15 A14
-+static const u8 K15[] = {
-+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
-+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
-+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
-+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
-+};
-+
-+static const u8 P15[] = {
-+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
-+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
-+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
-+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
-+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
-+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
-+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
-+    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
-+};
-+
-+static const u8 IV15[] = {
-+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
-+    0xde, 0xca, 0xf8, 0x88
-+};
-+
-+static const u8 C15[] = {
-+    0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
-+    0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
-+    0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
-+    0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
-+    0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
-+    0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
-+    0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
-+    0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad
-+};
-+
-+static const u8 T15[] = {
-+    0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
-+    0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c
-+};
-+
-+/* Test Case 16 */
-+# define K16 K15
-+# define IV16 IV15
-+static const u8 P16[] = {
-+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
-+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
-+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
-+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
-+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
-+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
-+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
-+    0xba, 0x63, 0x7b, 0x39
-+};
-+
-+static const u8 A16[] = {
-+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
-+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
-+    0xab, 0xad, 0xda, 0xd2
-+};
-+
-+static const u8 C16[] = {
-+    0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
-+    0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
-+    0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
-+    0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
-+    0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
-+    0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
-+    0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
-+    0xbc, 0xc9, 0xf6, 0x62
-+};
-+
-+static const u8 T16[] = {
-+    0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
-+    0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b
-+};
-+
-+/* Test Case 17 */
-+# define K17 K16
-+# define P17 P16
-+# define A17 A16
-+static const u8 IV17[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
-+
-+static const u8 C17[] = {
-+    0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
-+    0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
-+    0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
-+    0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
-+    0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
-+    0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
-+    0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
-+    0xf4, 0x7c, 0x9b, 0x1f
-+};
-+
-+static const u8 T17[] = {
-+    0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
-+    0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2
-+};
-+
-+/* Test Case 18 */
-+# define K18 K17
-+# define P18 P17
-+# define A18 A17
-+static const u8 IV18[] = {
-+    0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
-+    0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
-+    0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
-+    0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
-+    0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
-+    0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
-+    0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
-+    0xa6, 0x37, 0xb3, 0x9b
-+};
-+
-+static const u8 C18[] = {
-+    0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
-+    0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
-+    0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
-+    0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
-+    0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
-+    0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
-+    0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
-+    0x44, 0xae, 0x7e, 0x3f
-+};
-+
-+static const u8 T18[] = {
-+    0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
-+    0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a
-+};
-+
-+/* Test Case 19 */
-+# define K19 K1
-+# define P19 P1
-+# define IV19 IV1
-+# define C19 C1
-+static const u8 A19[] = {
-+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
-+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
-+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
-+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
-+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
-+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
-+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
-+    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
-+    0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
-+    0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
-+    0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
-+    0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
-+    0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
-+    0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
-+    0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
-+    0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad
-+};
-+
-+static const u8 T19[] = {
-+    0x5f, 0xea, 0x79, 0x3a, 0x2d, 0x6f, 0x97, 0x4d,
-+    0x37, 0xe6, 0x8e, 0x0c, 0xb8, 0xff, 0x94, 0x92
-+};
-+
-+/* Test Case 20 */
-+# define K20 K1
-+# define A20 A1
-+/* this results in 0xff in counter LSB */
-+static const u8 IV20[64] = { 0xff, 0xff, 0xff, 0xff };
-+
-+static const u8 P20[288];
-+static const u8 C20[] = {
-+    0x56, 0xb3, 0x37, 0x3c, 0xa9, 0xef, 0x6e, 0x4a,
-+    0x2b, 0x64, 0xfe, 0x1e, 0x9a, 0x17, 0xb6, 0x14,
-+    0x25, 0xf1, 0x0d, 0x47, 0xa7, 0x5a, 0x5f, 0xce,
-+    0x13, 0xef, 0xc6, 0xbc, 0x78, 0x4a, 0xf2, 0x4f,
-+    0x41, 0x41, 0xbd, 0xd4, 0x8c, 0xf7, 0xc7, 0x70,
-+    0x88, 0x7a, 0xfd, 0x57, 0x3c, 0xca, 0x54, 0x18,
-+    0xa9, 0xae, 0xff, 0xcd, 0x7c, 0x5c, 0xed, 0xdf,
-+    0xc6, 0xa7, 0x83, 0x97, 0xb9, 0xa8, 0x5b, 0x49,
-+    0x9d, 0xa5, 0x58, 0x25, 0x72, 0x67, 0xca, 0xab,
-+    0x2a, 0xd0, 0xb2, 0x3c, 0xa4, 0x76, 0xa5, 0x3c,
-+    0xb1, 0x7f, 0xb4, 0x1c, 0x4b, 0x8b, 0x47, 0x5c,
-+    0xb4, 0xf3, 0xf7, 0x16, 0x50, 0x94, 0xc2, 0x29,
-+    0xc9, 0xe8, 0xc4, 0xdc, 0x0a, 0x2a, 0x5f, 0xf1,
-+    0x90, 0x3e, 0x50, 0x15, 0x11, 0x22, 0x13, 0x76,
-+    0xa1, 0xcd, 0xb8, 0x36, 0x4c, 0x50, 0x61, 0xa2,
-+    0x0c, 0xae, 0x74, 0xbc, 0x4a, 0xcd, 0x76, 0xce,
-+    0xb0, 0xab, 0xc9, 0xfd, 0x32, 0x17, 0xef, 0x9f,
-+    0x8c, 0x90, 0xbe, 0x40, 0x2d, 0xdf, 0x6d, 0x86,
-+    0x97, 0xf4, 0xf8, 0x80, 0xdf, 0xf1, 0x5b, 0xfb,
-+    0x7a, 0x6b, 0x28, 0x24, 0x1e, 0xc8, 0xfe, 0x18,
-+    0x3c, 0x2d, 0x59, 0xe3, 0xf9, 0xdf, 0xff, 0x65,
-+    0x3c, 0x71, 0x26, 0xf0, 0xac, 0xb9, 0xe6, 0x42,
-+    0x11, 0xf4, 0x2b, 0xae, 0x12, 0xaf, 0x46, 0x2b,
-+    0x10, 0x70, 0xbe, 0xf1, 0xab, 0x5e, 0x36, 0x06,
-+    0x87, 0x2c, 0xa1, 0x0d, 0xee, 0x15, 0xb3, 0x24,
-+    0x9b, 0x1a, 0x1b, 0x95, 0x8f, 0x23, 0x13, 0x4c,
-+    0x4b, 0xcc, 0xb7, 0xd0, 0x32, 0x00, 0xbc, 0xe4,
-+    0x20, 0xa2, 0xf8, 0xeb, 0x66, 0xdc, 0xf3, 0x64,
-+    0x4d, 0x14, 0x23, 0xc1, 0xb5, 0x69, 0x90, 0x03,
-+    0xc1, 0x3e, 0xce, 0xf4, 0xbf, 0x38, 0xa3, 0xb6,
-+    0x0e, 0xed, 0xc3, 0x40, 0x33, 0xba, 0xc1, 0x90,
-+    0x27, 0x83, 0xdc, 0x6d, 0x89, 0xe2, 0xe7, 0x74,
-+    0x18, 0x8a, 0x43, 0x9c, 0x7e, 0xbc, 0xc0, 0x67,
-+    0x2d, 0xbd, 0xa4, 0xdd, 0xcf, 0xb2, 0x79, 0x46,
-+    0x13, 0xb0, 0xbe, 0x41, 0x31, 0x5e, 0xf7, 0x78,
-+    0x70, 0x8a, 0x70, 0xee, 0x7d, 0x75, 0x16, 0x5c
-+};
-+
-+static const u8 T20[] = {
-+    0x8b, 0x30, 0x7f, 0x6b, 0x33, 0x28, 0x6d, 0x0a,
-+    0xb0, 0x26, 0xa9, 0xed, 0x3f, 0xe1, 0xe8, 0x5f
-+};
-+
-+# define TEST_CASE(n)    do {                                    \
-+        u8 out[sizeof(P##n)];                                   \
-+        AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key);          \
-+        CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt);  \
-+        CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));          \
-+        memset(out,0,sizeof(out));                              \
-+        if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));    \
-+        if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out));     \
-+        if (CRYPTO_gcm128_finish(&ctx,T##n,16) ||               \
-+            (C##n && memcmp(out,C##n,sizeof(out))))             \
-+                ret++, printf ("encrypt test#%d failed.\n",n);  \
-+        CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));          \
-+        memset(out,0,sizeof(out));                              \
-+        if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));    \
-+        if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out));     \
-+        if (CRYPTO_gcm128_finish(&ctx,T##n,16) ||               \
-+            (P##n && memcmp(out,P##n,sizeof(out))))             \
-+                ret++, printf ("decrypt test#%d failed.\n",n);  \
-+        } while(0)
-+
-+int main()
-+{
-+    GCM128_CONTEXT ctx;
-+    AES_KEY key;
-+    int ret = 0;
-+
-+    TEST_CASE(1);
-+    TEST_CASE(2);
-+    TEST_CASE(3);
-+    TEST_CASE(4);
-+    TEST_CASE(5);
-+    TEST_CASE(6);
-+    TEST_CASE(7);
-+    TEST_CASE(8);
-+    TEST_CASE(9);
-+    TEST_CASE(10);
-+    TEST_CASE(11);
-+    TEST_CASE(12);
-+    TEST_CASE(13);
-+    TEST_CASE(14);
-+    TEST_CASE(15);
-+    TEST_CASE(16);
-+    TEST_CASE(17);
-+    TEST_CASE(18);
-+    TEST_CASE(19);
-+    TEST_CASE(20);
-+
-+# ifdef OPENSSL_CPUID_OBJ
-+    {
-+        size_t start, stop, gcm_t, ctr_t, OPENSSL_rdtsc();
-+        union {
-+            u64 u;
-+            u8 c[1024];
-+        } buf;
-+        int i;
-+
-+        AES_set_encrypt_key(K1, sizeof(K1) * 8, &key);
-+        CRYPTO_gcm128_init(&ctx, &key, (block128_f) AES_encrypt);
-+        CRYPTO_gcm128_setiv(&ctx, IV1, sizeof(IV1));
-+
-+        CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
-+        start = OPENSSL_rdtsc();
-+        CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
-+        gcm_t = OPENSSL_rdtsc() - start;
-+
-+        CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
-+                              &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
-+                              (block128_f) AES_encrypt);
-+        start = OPENSSL_rdtsc();
-+        CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
-+                              &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
-+                              (block128_f) AES_encrypt);
-+        ctr_t = OPENSSL_rdtsc() - start;
-+
-+        printf("%.2f-%.2f=%.2f\n",
-+               gcm_t / (double)sizeof(buf),
-+               ctr_t / (double)sizeof(buf),
-+               (gcm_t - ctr_t) / (double)sizeof(buf));
-+#  ifdef GHASH
-+        {
-+            void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
-+                                 const u8 *inp, size_t len) = ctx.ghash;
-+
-+            GHASH((&ctx), buf.c, sizeof(buf));
-+            start = OPENSSL_rdtsc();
-+            for (i = 0; i < 100; ++i)
-+                GHASH((&ctx), buf.c, sizeof(buf));
-+            gcm_t = OPENSSL_rdtsc() - start;
-+            printf("%.2f\n", gcm_t / (double)sizeof(buf) / (double)i);
-+        }
-+#  endif
-+    }
-+# endif
-+
-+    return ret;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/modes_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/modes_lcl.h
-new file mode 100644
-index 0000000..7a1603b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/modes_lcl.h
-@@ -0,0 +1,185 @@
-+/*
-+ * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
-+typedef __int64 i64;
-+typedef unsigned __int64 u64;
-+# define U64(C) C##UI64
-+#elif defined(__arch64__)
-+typedef long i64;
-+typedef unsigned long u64;
-+# define U64(C) C##UL
-+#else
-+typedef long long i64;
-+typedef unsigned long long u64;
-+# define U64(C) C##ULL
-+#endif
-+
-+typedef unsigned int u32;
-+typedef unsigned char u8;
-+
-+#define STRICT_ALIGNMENT 1
-+#ifndef PEDANTIC
-+# if defined(__i386)    || defined(__i386__)    || \
-+     defined(__x86_64)  || defined(__x86_64__)  || \
-+     defined(_M_IX86)   || defined(_M_AMD64)    || defined(_M_X64) || \
-+     defined(__aarch64__)                       || \
-+     defined(__s390__)  || defined(__s390x__)
-+#  undef STRICT_ALIGNMENT
-+# endif
-+#endif
-+
-+#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
-+# if defined(__GNUC__) && __GNUC__>=2
-+#  if defined(__x86_64) || defined(__x86_64__)
-+#   define BSWAP8(x) ({ u64 ret_=(x);                   \
-+                        asm ("bswapq %0"                \
-+                        : "+r"(ret_));   ret_;          })
-+#   define BSWAP4(x) ({ u32 ret_=(x);                   \
-+                        asm ("bswapl %0"                \
-+                        : "+r"(ret_));   ret_;          })
-+#  elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)
-+#   define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x);   \
-+                        asm ("bswapl %0; bswapl %1"     \
-+                        : "+r"(hi_),"+r"(lo_));         \
-+                        (u64)hi_<<32|lo_;               })
-+#   define BSWAP4(x) ({ u32 ret_=(x);                   \
-+                        asm ("bswapl %0"                \
-+                        : "+r"(ret_));   ret_;          })
-+#  elif defined(__aarch64__)
-+#   define BSWAP8(x) ({ u64 ret_;                       \
-+                        asm ("rev %0,%1"                \
-+                        : "=r"(ret_) : "r"(x)); ret_;   })
-+#   define BSWAP4(x) ({ u32 ret_;                       \
-+                        asm ("rev %w0,%w1"              \
-+                        : "=r"(ret_) : "r"(x)); ret_;   })
-+#  elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT)
-+#   define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x);   \
-+                        asm ("rev %0,%0; rev %1,%1"     \
-+                        : "+r"(hi_),"+r"(lo_));         \
-+                        (u64)hi_<<32|lo_;               })
-+#   define BSWAP4(x) ({ u32 ret_;                       \
-+                        asm ("rev %0,%1"                \
-+                        : "=r"(ret_) : "r"((u32)(x)));  \
-+                        ret_;                           })
-+#  endif
-+# elif defined(_MSC_VER)
-+#  if _MSC_VER>=1300
-+#   pragma intrinsic(_byteswap_uint64,_byteswap_ulong)
-+#   define BSWAP8(x)    _byteswap_uint64((u64)(x))
-+#   define BSWAP4(x)    _byteswap_ulong((u32)(x))
-+#  elif defined(_M_IX86)
-+__inline u32 _bswap4(u32 val)
-+{
-+_asm mov eax, val _asm bswap eax}
-+#   define BSWAP4(x)    _bswap4(x)
-+#  endif
-+# endif
-+#endif
-+#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT)
-+# define GETU32(p)       BSWAP4(*(const u32 *)(p))
-+# define PUTU32(p,v)     *(u32 *)(p) = BSWAP4(v)
-+#else
-+# define GETU32(p)       ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3])
-+# define PUTU32(p,v)     ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
-+#endif
-+/*- GCM definitions */ typedef struct {
-+    u64 hi, lo;
-+} u128;
-+
-+#ifdef  TABLE_BITS
-+# undef  TABLE_BITS
-+#endif
-+/*
-+ * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
-+ * never be set to 8 [or 1]. For further information see gcm128.c.
-+ */
-+#define TABLE_BITS 4
-+
-+struct gcm128_context {
-+    /* Following 6 names follow names in GCM specification */
-+    union {
-+        u64 u[2];
-+        u32 d[4];
-+        u8 c[16];
-+        size_t t[16 / sizeof(size_t)];
-+    } Yi, EKi, EK0, len, Xi, H;
-+    /*
-+     * Relative position of Xi, H and pre-computed Htable is used in some
-+     * assembler modules, i.e. don't change the order!
-+     */
-+#if TABLE_BITS==8
-+    u128 Htable[256];
-+#else
-+    u128 Htable[16];
-+    void (*gmult) (u64 Xi[2], const u128 Htable[16]);
-+    void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp,
-+                   size_t len);
-+#endif
-+    unsigned int mres, ares;
-+    block128_f block;
-+    void *key;
-+};
-+
-+struct xts128_context {
-+    void *key1, *key2;
-+    block128_f block1, block2;
-+};
-+
-+struct ccm128_context {
-+    union {
-+        u64 u[2];
-+        u8 c[16];
-+    } nonce, cmac;
-+    u64 blocks;
-+    block128_f block;
-+    void *key;
-+};
-+
-+#ifndef OPENSSL_NO_OCB
-+
-+typedef union {
-+    u64 a[2];
-+    unsigned char c[16];
-+} OCB_BLOCK;
-+# define ocb_block16_xor(in1,in2,out) \
-+    ( (out)->a[0]=(in1)->a[0]^(in2)->a[0], \
-+      (out)->a[1]=(in1)->a[1]^(in2)->a[1] )
-+# if STRICT_ALIGNMENT
-+#  define ocb_block16_xor_misaligned(in1,in2,out) \
-+    ocb_block_xor((in1)->c,(in2)->c,16,(out)->c)
-+# else
-+#  define ocb_block16_xor_misaligned ocb_block16_xor
-+# endif
-+
-+struct ocb128_context {
-+    /* Need both encrypt and decrypt key schedules for decryption */
-+    block128_f encrypt;
-+    block128_f decrypt;
-+    void *keyenc;
-+    void *keydec;
-+    ocb128_f stream;    /* direction dependent */
-+    /* Key dependent variables. Can be reused if key remains the same */
-+    size_t l_index;
-+    size_t max_l_index;
-+    OCB_BLOCK l_star;
-+    OCB_BLOCK l_dollar;
-+    OCB_BLOCK *l;
-+    /* Must be reset for each session */
-+    u64 blocks_hashed;
-+    u64 blocks_processed;
-+    OCB_BLOCK tag;
-+    OCB_BLOCK offset_aad;
-+    OCB_BLOCK sum;
-+    OCB_BLOCK offset;
-+    OCB_BLOCK checksum;
-+};
-+#endif                          /* OPENSSL_NO_OCB */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ocb128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ocb128.c
-new file mode 100644
-index 0000000..c3bd13b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ocb128.c
-@@ -0,0 +1,568 @@
-+/*
-+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "modes_lcl.h"
-+
-+#ifndef OPENSSL_NO_OCB
-+
-+/*
-+ * Calculate the number of binary trailing zero's in any given number
-+ */
-+static u32 ocb_ntz(u64 n)
-+{
-+    u32 cnt = 0;
-+
-+    /*
-+     * We do a right-to-left simple sequential search. This is surprisingly
-+     * efficient as the distribution of trailing zeros is not uniform,
-+     * e.g. the number of possible inputs with no trailing zeros is equal to
-+     * the number with 1 or more; the number with exactly 1 is equal to the
-+     * number with 2 or more, etc. Checking the last two bits covers 75% of
-+     * all numbers. Checking the last three covers 87.5%
-+     */
-+    while (!(n & 1)) {
-+        n >>= 1;
-+        cnt++;
-+    }
-+    return cnt;
-+}
-+
-+/*
-+ * Shift a block of 16 bytes left by shift bits
-+ */
-+static void ocb_block_lshift(const unsigned char *in, size_t shift,
-+                             unsigned char *out)
-+{
-+    unsigned char shift_mask;
-+    int i;
-+    unsigned char mask[15];
-+
-+    shift_mask = 0xff;
-+    shift_mask <<= (8 - shift);
-+    for (i = 15; i >= 0; i--) {
-+        if (i > 0) {
-+            mask[i - 1] = in[i] & shift_mask;
-+            mask[i - 1] >>= 8 - shift;
-+        }
-+        out[i] = in[i] << shift;
-+
-+        if (i != 15) {
-+            out[i] ^= mask[i];
-+        }
-+    }
-+}
-+
-+/*
-+ * Perform a "double" operation as per OCB spec
-+ */
-+static void ocb_double(OCB_BLOCK *in, OCB_BLOCK *out)
-+{
-+    unsigned char mask;
-+
-+    /*
-+     * Calculate the mask based on the most significant bit. There are more
-+     * efficient ways to do this - but this way is constant time
-+     */
-+    mask = in->c[0] & 0x80;
-+    mask >>= 7;
-+    mask *= 135;
-+
-+    ocb_block_lshift(in->c, 1, out->c);
-+
-+    out->c[15] ^= mask;
-+}
-+
-+/*
-+ * Perform an xor on in1 and in2 - each of len bytes. Store result in out
-+ */
-+static void ocb_block_xor(const unsigned char *in1,
-+                          const unsigned char *in2, size_t len,
-+                          unsigned char *out)
-+{
-+    size_t i;
-+    for (i = 0; i < len; i++) {
-+        out[i] = in1[i] ^ in2[i];
-+    }
-+}
-+
-+/*
-+ * Lookup L_index in our lookup table. If we haven't already got it we need to
-+ * calculate it
-+ */
-+static OCB_BLOCK *ocb_lookup_l(OCB128_CONTEXT *ctx, size_t idx)
-+{
-+    size_t l_index = ctx->l_index;
-+
-+    if (idx <= l_index) {
-+        return ctx->l + idx;
-+    }
-+
-+    /* We don't have it - so calculate it */
-+    if (idx >= ctx->max_l_index) {
-+        void *tmp_ptr;
-+        /*
-+         * Each additional entry allows to process almost double as
-+         * much data, so that in linear world the table will need to
-+         * be expanded with smaller and smaller increments. Originally
-+         * it was doubling in size, which was a waste. Growing it
-+         * linearly is not formally optimal, but is simpler to implement.
-+         * We grow table by minimally required 4*n that would accommodate
-+         * the index.
-+         */
-+        ctx->max_l_index += (idx - ctx->max_l_index + 4) & ~3;
-+        tmp_ptr =
-+            OPENSSL_realloc(ctx->l, ctx->max_l_index * sizeof(OCB_BLOCK));
-+        if (tmp_ptr == NULL) /* prevent ctx->l from being clobbered */
-+            return NULL;
-+        ctx->l = tmp_ptr;
-+    }
-+    while (l_index < idx) {
-+        ocb_double(ctx->l + l_index, ctx->l + l_index + 1);
-+        l_index++;
-+    }
-+    ctx->l_index = l_index;
-+
-+    return ctx->l + idx;
-+}
-+
-+/*
-+ * Create a new OCB128_CONTEXT
-+ */
-+OCB128_CONTEXT *CRYPTO_ocb128_new(void *keyenc, void *keydec,
-+                                  block128_f encrypt, block128_f decrypt,
-+                                  ocb128_f stream)
-+{
-+    OCB128_CONTEXT *octx;
-+    int ret;
-+
-+    if ((octx = OPENSSL_malloc(sizeof(*octx))) != NULL) {
-+        ret = CRYPTO_ocb128_init(octx, keyenc, keydec, encrypt, decrypt,
-+                                 stream);
-+        if (ret)
-+            return octx;
-+        OPENSSL_free(octx);
-+    }
-+
-+    return NULL;
-+}
-+
-+/*
-+ * Initialise an existing OCB128_CONTEXT
-+ */
-+int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec,
-+                       block128_f encrypt, block128_f decrypt,
-+                       ocb128_f stream)
-+{
-+    memset(ctx, 0, sizeof(*ctx));
-+    ctx->l_index = 0;
-+    ctx->max_l_index = 5;
-+    ctx->l = OPENSSL_malloc(ctx->max_l_index * 16);
-+    if (ctx->l == NULL)
-+        return 0;
-+
-+    /*
-+     * We set both the encryption and decryption key schedules - decryption
-+     * needs both. Don't really need decryption schedule if only doing
-+     * encryption - but it simplifies things to take it anyway
-+     */
-+    ctx->encrypt = encrypt;
-+    ctx->decrypt = decrypt;
-+    ctx->stream = stream;
-+    ctx->keyenc = keyenc;
-+    ctx->keydec = keydec;
-+
-+    /* L_* = ENCIPHER(K, zeros(128)) */
-+    ctx->encrypt(ctx->l_star.c, ctx->l_star.c, ctx->keyenc);
-+
-+    /* L_$ = double(L_*) */
-+    ocb_double(&ctx->l_star, &ctx->l_dollar);
-+
-+    /* L_0 = double(L_$) */
-+    ocb_double(&ctx->l_dollar, ctx->l);
-+
-+    /* L_{i} = double(L_{i-1}) */
-+    ocb_double(ctx->l, ctx->l+1);
-+    ocb_double(ctx->l+1, ctx->l+2);
-+    ocb_double(ctx->l+2, ctx->l+3);
-+    ocb_double(ctx->l+3, ctx->l+4);
-+    ctx->l_index = 4;   /* enough to process up to 496 bytes */
-+
-+    return 1;
-+}
-+
-+/*
-+ * Copy an OCB128_CONTEXT object
-+ */
-+int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src,
-+                           void *keyenc, void *keydec)
-+{
-+    memcpy(dest, src, sizeof(OCB128_CONTEXT));
-+    if (keyenc)
-+        dest->keyenc = keyenc;
-+    if (keydec)
-+        dest->keydec = keydec;
-+    if (src->l) {
-+        dest->l = OPENSSL_malloc(src->max_l_index * 16);
-+        if (dest->l == NULL)
-+            return 0;
-+        memcpy(dest->l, src->l, (src->l_index + 1) * 16);
-+    }
-+    return 1;
-+}
-+
-+/*
-+ * Set the IV to be used for this operation. Must be 1 - 15 bytes.
-+ */
-+int CRYPTO_ocb128_setiv(OCB128_CONTEXT *ctx, const unsigned char *iv,
-+                        size_t len, size_t taglen)
-+{
-+    unsigned char ktop[16], tmp[16], mask;
-+    unsigned char stretch[24], nonce[16];
-+    size_t bottom, shift;
-+
-+    /*
-+     * Spec says IV is 120 bits or fewer - it allows non byte aligned lengths.
-+     * We don't support this at this stage
-+     */
-+    if ((len > 15) || (len < 1) || (taglen > 16) || (taglen < 1)) {
-+        return -1;
-+    }
-+
-+    /* Nonce = num2str(TAGLEN mod 128,7) || zeros(120-bitlen(N)) || 1 || N */
-+    nonce[0] = ((taglen * 8) % 128) << 1;
-+    memset(nonce + 1, 0, 15);
-+    memcpy(nonce + 16 - len, iv, len);
-+    nonce[15 - len] |= 1;
-+
-+    /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */
-+    memcpy(tmp, nonce, 16);
-+    tmp[15] &= 0xc0;
-+    ctx->encrypt(tmp, ktop, ctx->keyenc);
-+
-+    /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
-+    memcpy(stretch, ktop, 16);
-+    ocb_block_xor(ktop, ktop + 1, 8, stretch + 16);
-+
-+    /* bottom = str2num(Nonce[123..128]) */
-+    bottom = nonce[15] & 0x3f;
-+
-+    /* Offset_0 = Stretch[1+bottom..128+bottom] */
-+    shift = bottom % 8;
-+    ocb_block_lshift(stretch + (bottom / 8), shift, ctx->offset.c);
-+    mask = 0xff;
-+    mask <<= 8 - shift;
-+    ctx->offset.c[15] |=
-+        (*(stretch + (bottom / 8) + 16) & mask) >> (8 - shift);
-+
-+    return 1;
-+}
-+
-+/*
-+ * Provide any AAD. This can be called multiple times. Only the final time can
-+ * have a partial block
-+ */
-+int CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad,
-+                      size_t len)
-+{
-+    u64 i, all_num_blocks;
-+    size_t num_blocks, last_len;
-+    OCB_BLOCK tmp1;
-+    OCB_BLOCK tmp2;
-+
-+    /* Calculate the number of blocks of AAD provided now, and so far */
-+    num_blocks = len / 16;
-+    all_num_blocks = num_blocks + ctx->blocks_hashed;
-+
-+    /* Loop through all full blocks of AAD */
-+    for (i = ctx->blocks_hashed + 1; i <= all_num_blocks; i++) {
-+        OCB_BLOCK *lookup;
-+        OCB_BLOCK *aad_block;
-+
-+        /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-+        lookup = ocb_lookup_l(ctx, ocb_ntz(i));
-+        if (lookup == NULL)
-+            return 0;
-+        ocb_block16_xor(&ctx->offset_aad, lookup, &ctx->offset_aad);
-+
-+        /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
-+        aad_block = (OCB_BLOCK *)(aad + ((i - ctx->blocks_hashed - 1) * 16));
-+        ocb_block16_xor(&ctx->offset_aad, aad_block, &tmp1);
-+        ctx->encrypt(tmp1.c, tmp2.c, ctx->keyenc);
-+        ocb_block16_xor(&ctx->sum, &tmp2, &ctx->sum);
-+    }
-+
-+    /*
-+     * Check if we have any partial blocks left over. This is only valid in the
-+     * last call to this function
-+     */
-+    last_len = len % 16;
-+
-+    if (last_len > 0) {
-+        /* Offset_* = Offset_m xor L_* */
-+        ocb_block16_xor(&ctx->offset_aad, &ctx->l_star, &ctx->offset_aad);
-+
-+        /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
-+        memset(&tmp1, 0, 16);
-+        memcpy(&tmp1, aad + (num_blocks * 16), last_len);
-+        ((unsigned char *)&tmp1)[last_len] = 0x80;
-+        ocb_block16_xor(&ctx->offset_aad, &tmp1, &tmp2);
-+
-+        /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
-+        ctx->encrypt(tmp2.c, tmp1.c, ctx->keyenc);
-+        ocb_block16_xor(&ctx->sum, &tmp1, &ctx->sum);
-+    }
-+
-+    ctx->blocks_hashed = all_num_blocks;
-+
-+    return 1;
-+}
-+
-+/*
-+ * Provide any data to be encrypted. This can be called multiple times. Only
-+ * the final time can have a partial block
-+ */
-+int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx,
-+                          const unsigned char *in, unsigned char *out,
-+                          size_t len)
-+{
-+    u64 i, all_num_blocks;
-+    size_t num_blocks, last_len;
-+    OCB_BLOCK tmp1;
-+    OCB_BLOCK tmp2;
-+    OCB_BLOCK pad;
-+
-+    /*
-+     * Calculate the number of blocks of data to be encrypted provided now, and
-+     * so far
-+     */
-+    num_blocks = len / 16;
-+    all_num_blocks = num_blocks + ctx->blocks_processed;
-+
-+    if (num_blocks && all_num_blocks == (size_t)all_num_blocks
-+        && ctx->stream != NULL) {
-+        size_t max_idx = 0, top = (size_t)all_num_blocks;
-+
-+        /*
-+         * See how many L_{i} entries we need to process data at hand
-+         * and pre-compute missing entries in the table [if any]...
-+         */
-+        while (top >>= 1)
-+            max_idx++;
-+        if (ocb_lookup_l(ctx, max_idx) == NULL)
-+            return 0;
-+
-+        ctx->stream(in, out, num_blocks, ctx->keyenc,
-+                    (size_t)ctx->blocks_processed + 1, ctx->offset.c,
-+                    (const unsigned char (*)[16])ctx->l, ctx->checksum.c);
-+    } else {
-+        /* Loop through all full blocks to be encrypted */
-+        for (i = ctx->blocks_processed + 1; i <= all_num_blocks; i++) {
-+            OCB_BLOCK *lookup;
-+            OCB_BLOCK *inblock;
-+            OCB_BLOCK *outblock;
-+
-+            /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-+            lookup = ocb_lookup_l(ctx, ocb_ntz(i));
-+            if (lookup == NULL)
-+                return 0;
-+            ocb_block16_xor(&ctx->offset, lookup, &ctx->offset);
-+
-+            /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
-+            inblock =
-+                (OCB_BLOCK *)(in + ((i - ctx->blocks_processed - 1) * 16));
-+            ocb_block16_xor_misaligned(&ctx->offset, inblock, &tmp1);
-+            /* Checksum_i = Checksum_{i-1} xor P_i */
-+            ocb_block16_xor_misaligned(&ctx->checksum, inblock, &ctx->checksum);
-+            ctx->encrypt(tmp1.c, tmp2.c, ctx->keyenc);
-+            outblock =
-+                (OCB_BLOCK *)(out + ((i - ctx->blocks_processed - 1) * 16));
-+            ocb_block16_xor_misaligned(&ctx->offset, &tmp2, outblock);
-+        }
-+    }
-+
-+    /*
-+     * Check if we have any partial blocks left over. This is only valid in the
-+     * last call to this function
-+     */
-+    last_len = len % 16;
-+
-+    if (last_len > 0) {
-+        /* Offset_* = Offset_m xor L_* */
-+        ocb_block16_xor(&ctx->offset, &ctx->l_star, &ctx->offset);
-+
-+        /* Pad = ENCIPHER(K, Offset_*) */
-+        ctx->encrypt(ctx->offset.c, pad.c, ctx->keyenc);
-+
-+        /* C_* = P_* xor Pad[1..bitlen(P_*)] */
-+        ocb_block_xor(in + (len / 16) * 16, (unsigned char *)&pad, last_len,
-+                      out + (num_blocks * 16));
-+
-+        /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
-+        memset(&tmp1, 0, 16);
-+        memcpy(&tmp1, in + (len / 16) * 16, last_len);
-+        ((unsigned char *)(&tmp1))[last_len] = 0x80;
-+        ocb_block16_xor(&ctx->checksum, &tmp1, &ctx->checksum);
-+    }
-+
-+    ctx->blocks_processed = all_num_blocks;
-+
-+    return 1;
-+}
-+
-+/*
-+ * Provide any data to be decrypted. This can be called multiple times. Only
-+ * the final time can have a partial block
-+ */
-+int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx,
-+                          const unsigned char *in, unsigned char *out,
-+                          size_t len)
-+{
-+    u64 i, all_num_blocks;
-+    size_t num_blocks, last_len;
-+    OCB_BLOCK tmp1;
-+    OCB_BLOCK tmp2;
-+    OCB_BLOCK pad;
-+
-+    /*
-+     * Calculate the number of blocks of data to be decrypted provided now, and
-+     * so far
-+     */
-+    num_blocks = len / 16;
-+    all_num_blocks = num_blocks + ctx->blocks_processed;
-+
-+    if (num_blocks && all_num_blocks == (size_t)all_num_blocks
-+        && ctx->stream != NULL) {
-+        size_t max_idx = 0, top = (size_t)all_num_blocks;
-+
-+        /*
-+         * See how many L_{i} entries we need to process data at hand
-+         * and pre-compute missing entries in the table [if any]...
-+         */
-+        while (top >>= 1)
-+            max_idx++;
-+        if (ocb_lookup_l(ctx, max_idx) == NULL)
-+            return 0;
-+
-+        ctx->stream(in, out, num_blocks, ctx->keydec,
-+                    (size_t)ctx->blocks_processed + 1, ctx->offset.c,
-+                    (const unsigned char (*)[16])ctx->l, ctx->checksum.c);
-+    } else {
-+        /* Loop through all full blocks to be decrypted */
-+        for (i = ctx->blocks_processed + 1; i <= all_num_blocks; i++) {
-+            OCB_BLOCK *inblock;
-+            OCB_BLOCK *outblock;
-+
-+            /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
-+            OCB_BLOCK *lookup = ocb_lookup_l(ctx, ocb_ntz(i));
-+            if (lookup == NULL)
-+                return 0;
-+            ocb_block16_xor(&ctx->offset, lookup, &ctx->offset);
-+
-+            /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
-+            inblock =
-+                (OCB_BLOCK *)(in + ((i - ctx->blocks_processed - 1) * 16));
-+            ocb_block16_xor_misaligned(&ctx->offset, inblock, &tmp1);
-+            ctx->decrypt(tmp1.c, tmp2.c, ctx->keydec);
-+            outblock =
-+                (OCB_BLOCK *)(out + ((i - ctx->blocks_processed - 1) * 16));
-+            ocb_block16_xor_misaligned(&ctx->offset, &tmp2, outblock);
-+
-+            /* Checksum_i = Checksum_{i-1} xor P_i */
-+            ocb_block16_xor_misaligned(&ctx->checksum, outblock, &ctx->checksum);
-+        }
-+    }
-+
-+    /*
-+     * Check if we have any partial blocks left over. This is only valid in the
-+     * last call to this function
-+     */
-+    last_len = len % 16;
-+
-+    if (last_len > 0) {
-+        /* Offset_* = Offset_m xor L_* */
-+        ocb_block16_xor(&ctx->offset, &ctx->l_star, &ctx->offset);
-+
-+        /* Pad = ENCIPHER(K, Offset_*) */
-+        ctx->encrypt(ctx->offset.c, pad.c, ctx->keyenc);
-+
-+        /* P_* = C_* xor Pad[1..bitlen(C_*)] */
-+        ocb_block_xor(in + (len / 16) * 16, (unsigned char *)&pad, last_len,
-+                      out + (num_blocks * 16));
-+
-+        /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
-+        memset(&tmp1, 0, 16);
-+        memcpy(&tmp1, out + (len / 16) * 16, last_len);
-+        ((unsigned char *)(&tmp1))[last_len] = 0x80;
-+        ocb_block16_xor(&ctx->checksum, &tmp1, &ctx->checksum);
-+    }
-+
-+    ctx->blocks_processed = all_num_blocks;
-+
-+    return 1;
-+}
-+
-+/*
-+ * Calculate the tag and verify it against the supplied tag
-+ */
-+int CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag,
-+                         size_t len)
-+{
-+    OCB_BLOCK tmp1, tmp2;
-+
-+    /*
-+     * Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A)
-+     */
-+    ocb_block16_xor(&ctx->checksum, &ctx->offset, &tmp1);
-+    ocb_block16_xor(&tmp1, &ctx->l_dollar, &tmp2);
-+    ctx->encrypt(tmp2.c, tmp1.c, ctx->keyenc);
-+    ocb_block16_xor(&tmp1, &ctx->sum, &ctx->tag);
-+
-+    if (len > 16 || len < 1) {
-+        return -1;
-+    }
-+
-+    /* Compare the tag if we've been given one */
-+    if (tag)
-+        return CRYPTO_memcmp(&ctx->tag, tag, len);
-+    else
-+        return -1;
-+}
-+
-+/*
-+ * Retrieve the calculated tag
-+ */
-+int CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len)
-+{
-+    if (len > 16 || len < 1) {
-+        return -1;
-+    }
-+
-+    /* Calculate the tag */
-+    CRYPTO_ocb128_finish(ctx, NULL, 0);
-+
-+    /* Copy the tag into the supplied buffer */
-+    memcpy(tag, &ctx->tag, len);
-+
-+    return 1;
-+}
-+
-+/*
-+ * Release all resources
-+ */
-+void CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx)
-+{
-+    if (ctx) {
-+        OPENSSL_clear_free(ctx->l, ctx->max_l_index * 16);
-+        OPENSSL_cleanse(ctx, sizeof(*ctx));
-+    }
-+}
-+
-+#endif                          /* OPENSSL_NO_OCB */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ofb128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ofb128.c
-new file mode 100644
-index 0000000..8309256
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/ofb128.c
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "modes_lcl.h"
-+#include 
-+
-+/*
-+ * The input and output encrypted as though 128bit ofb mode is being used.
-+ * The extra state information to record how much of the 128bit block we have
-+ * used is contained in *num;
-+ */
-+void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
-+                           size_t len, const void *key,
-+                           unsigned char ivec[16], int *num, block128_f block)
-+{
-+    unsigned int n;
-+    size_t l = 0;
-+
-+    n = *num;
-+
-+#if !defined(OPENSSL_SMALL_FOOTPRINT)
-+    if (16 % sizeof(size_t) == 0) { /* always true actually */
-+        do {
-+            while (n && len) {
-+                *(out++) = *(in++) ^ ivec[n];
-+                --len;
-+                n = (n + 1) % 16;
-+            }
-+# if defined(STRICT_ALIGNMENT)
-+            if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) !=
-+                0)
-+                break;
-+# endif
-+            while (len >= 16) {
-+                (*block) (ivec, ivec, key);
-+                for (; n < 16; n += sizeof(size_t))
-+                    *(size_t *)(out + n) =
-+                        *(size_t *)(in + n) ^ *(size_t *)(ivec + n);
-+                len -= 16;
-+                out += 16;
-+                in += 16;
-+                n = 0;
-+            }
-+            if (len) {
-+                (*block) (ivec, ivec, key);
-+                while (len--) {
-+                    out[n] = in[n] ^ ivec[n];
-+                    ++n;
-+                }
-+            }
-+            *num = n;
-+            return;
-+        } while (0);
-+    }
-+    /* the rest would be commonly eliminated by x86* compiler */
-+#endif
-+    while (l < len) {
-+        if (n == 0) {
-+            (*block) (ivec, ivec, key);
-+        }
-+        out[l] = in[l] ^ ivec[n];
-+        ++l;
-+        n = (n + 1) % 16;
-+    }
-+
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/wrap128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/wrap128.c
-new file mode 100644
-index 0000000..46809a0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/wrap128.c
-@@ -0,0 +1,329 @@
-+/*
-+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/**  Beware!
-+ *
-+ *  Following wrapping modes were designed for AES but this implementation
-+ *  allows you to use them for any 128 bit block cipher.
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+
-+/** RFC 3394 section 2.2.3.1 Default Initial Value */
-+static const unsigned char default_iv[] = {
-+    0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
-+};
-+
-+/** RFC 5649 section 3 Alternative Initial Value 32-bit constant */
-+static const unsigned char default_aiv[] = {
-+    0xA6, 0x59, 0x59, 0xA6
-+};
-+
-+/** Input size limit: lower than maximum of standards but far larger than
-+ *  anything that will be used in practice.
-+ */
-+#define CRYPTO128_WRAP_MAX (1UL << 31)
-+
-+/** Wrapping according to RFC 3394 section 2.2.1.
-+ *
-+ *  @param[in]  key    Key value.
-+ *  @param[in]  iv     IV value. Length = 8 bytes. NULL = use default_iv.
-+ *  @param[in]  in     Plaintext as n 64-bit blocks, n >= 2.
-+ *  @param[in]  inlen  Length of in.
-+ *  @param[out] out    Ciphertext. Minimal buffer length = (inlen + 8) bytes.
-+ *                     Input and output buffers can overlap if block function
-+ *                     supports that.
-+ *  @param[in]  block  Block processing function.
-+ *  @return            0 if inlen does not consist of n 64-bit blocks, n >= 2.
-+ *                     or if inlen > CRYPTO128_WRAP_MAX.
-+ *                     Output length if wrapping succeeded.
-+ */
-+size_t CRYPTO_128_wrap(void *key, const unsigned char *iv,
-+                       unsigned char *out,
-+                       const unsigned char *in, size_t inlen,
-+                       block128_f block)
-+{
-+    unsigned char *A, B[16], *R;
-+    size_t i, j, t;
-+    if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
-+        return 0;
-+    A = B;
-+    t = 1;
-+    memmove(out + 8, in, inlen);
-+    if (!iv)
-+        iv = default_iv;
-+
-+    memcpy(A, iv, 8);
-+
-+    for (j = 0; j < 6; j++) {
-+        R = out + 8;
-+        for (i = 0; i < inlen; i += 8, t++, R += 8) {
-+            memcpy(B + 8, R, 8);
-+            block(B, B, key);
-+            A[7] ^= (unsigned char)(t & 0xff);
-+            if (t > 0xff) {
-+                A[6] ^= (unsigned char)((t >> 8) & 0xff);
-+                A[5] ^= (unsigned char)((t >> 16) & 0xff);
-+                A[4] ^= (unsigned char)((t >> 24) & 0xff);
-+            }
-+            memcpy(R, B + 8, 8);
-+        }
-+    }
-+    memcpy(out, A, 8);
-+    return inlen + 8;
-+}
-+
-+/** Unwrapping according to RFC 3394 section 2.2.2 steps 1-2.
-+ *  The IV check (step 3) is responsibility of the caller.
-+ *
-+ *  @param[in]  key    Key value.
-+ *  @param[out] iv     Unchecked IV value. Minimal buffer length = 8 bytes.
-+ *  @param[out] out    Plaintext without IV.
-+ *                     Minimal buffer length = (inlen - 8) bytes.
-+ *                     Input and output buffers can overlap if block function
-+ *                     supports that.
-+ *  @param[in]  in     Ciphertext as n 64-bit blocks.
-+ *  @param[in]  inlen  Length of in.
-+ *  @param[in]  block  Block processing function.
-+ *  @return            0 if inlen is out of range [24, CRYPTO128_WRAP_MAX]
-+ *                     or if inlen is not a multiple of 8.
-+ *                     Output length otherwise.
-+ */
-+static size_t crypto_128_unwrap_raw(void *key, unsigned char *iv,
-+                                    unsigned char *out,
-+                                    const unsigned char *in, size_t inlen,
-+                                    block128_f block)
-+{
-+    unsigned char *A, B[16], *R;
-+    size_t i, j, t;
-+    inlen -= 8;
-+    if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
-+        return 0;
-+    A = B;
-+    t = 6 * (inlen >> 3);
-+    memcpy(A, in, 8);
-+    memmove(out, in + 8, inlen);
-+    for (j = 0; j < 6; j++) {
-+        R = out + inlen - 8;
-+        for (i = 0; i < inlen; i += 8, t--, R -= 8) {
-+            A[7] ^= (unsigned char)(t & 0xff);
-+            if (t > 0xff) {
-+                A[6] ^= (unsigned char)((t >> 8) & 0xff);
-+                A[5] ^= (unsigned char)((t >> 16) & 0xff);
-+                A[4] ^= (unsigned char)((t >> 24) & 0xff);
-+            }
-+            memcpy(B + 8, R, 8);
-+            block(B, B, key);
-+            memcpy(R, B + 8, 8);
-+        }
-+    }
-+    memcpy(iv, A, 8);
-+    return inlen;
-+}
-+
-+/** Unwrapping according to RFC 3394 section 2.2.2, including the IV check.
-+ *  The first block of plaintext has to match the supplied IV, otherwise an
-+ *  error is returned.
-+ *
-+ *  @param[in]  key    Key value.
-+ *  @param[out] iv     IV value to match against. Length = 8 bytes.
-+ *                     NULL = use default_iv.
-+ *  @param[out] out    Plaintext without IV.
-+ *                     Minimal buffer length = (inlen - 8) bytes.
-+ *                     Input and output buffers can overlap if block function
-+ *                     supports that.
-+ *  @param[in]  in     Ciphertext as n 64-bit blocks.
-+ *  @param[in]  inlen  Length of in.
-+ *  @param[in]  block  Block processing function.
-+ *  @return            0 if inlen is out of range [24, CRYPTO128_WRAP_MAX]
-+ *                     or if inlen is not a multiple of 8
-+ *                     or if IV doesn't match expected value.
-+ *                     Output length otherwise.
-+ */
-+size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv,
-+                         unsigned char *out, const unsigned char *in,
-+                         size_t inlen, block128_f block)
-+{
-+    size_t ret;
-+    unsigned char got_iv[8];
-+
-+    ret = crypto_128_unwrap_raw(key, got_iv, out, in, inlen, block);
-+    if (ret == 0)
-+        return 0;
-+
-+    if (!iv)
-+        iv = default_iv;
-+    if (CRYPTO_memcmp(got_iv, iv, 8)) {
-+        OPENSSL_cleanse(out, ret);
-+        return 0;
-+    }
-+    return ret;
-+}
-+
-+/** Wrapping according to RFC 5649 section 4.1.
-+ *
-+ *  @param[in]  key    Key value.
-+ *  @param[in]  icv    (Non-standard) IV, 4 bytes. NULL = use default_aiv.
-+ *  @param[out] out    Ciphertext. Minimal buffer length = (inlen + 15) bytes.
-+ *                     Input and output buffers can overlap if block function
-+ *                     supports that.
-+ *  @param[in]  in     Plaintext as n 64-bit blocks, n >= 2.
-+ *  @param[in]  inlen  Length of in.
-+ *  @param[in]  block  Block processing function.
-+ *  @return            0 if inlen is out of range [1, CRYPTO128_WRAP_MAX].
-+ *                     Output length if wrapping succeeded.
-+ */
-+size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv,
-+                           unsigned char *out,
-+                           const unsigned char *in, size_t inlen,
-+                           block128_f block)
-+{
-+    /* n: number of 64-bit blocks in the padded key data
-+     *
-+     * If length of plain text is not a multiple of 8, pad the plain text octet
-+     * string on the right with octets of zeros, where final length is the
-+     * smallest multiple of 8 that is greater than length of plain text.
-+     * If length of plain text is a multiple of 8, then there is no padding. */
-+    const size_t blocks_padded = (inlen + 7) / 8; /* CEILING(m/8) */
-+    const size_t padded_len = blocks_padded * 8;
-+    const size_t padding_len = padded_len - inlen;
-+    /* RFC 5649 section 3: Alternative Initial Value */
-+    unsigned char aiv[8];
-+    int ret;
-+
-+    /* Section 1: use 32-bit fixed field for plaintext octet length */
-+    if (inlen == 0 || inlen >= CRYPTO128_WRAP_MAX)
-+        return 0;
-+
-+    /* Section 3: Alternative Initial Value */
-+    if (!icv)
-+        memcpy(aiv, default_aiv, 4);
-+    else
-+        memcpy(aiv, icv, 4);    /* Standard doesn't mention this. */
-+
-+    aiv[4] = (inlen >> 24) & 0xFF;
-+    aiv[5] = (inlen >> 16) & 0xFF;
-+    aiv[6] = (inlen >> 8) & 0xFF;
-+    aiv[7] = inlen & 0xFF;
-+
-+    if (padded_len == 8) {
-+        /*
-+         * Section 4.1 - special case in step 2: If the padded plaintext
-+         * contains exactly eight octets, then prepend the AIV and encrypt
-+         * the resulting 128-bit block using AES in ECB mode.
-+         */
-+        memmove(out + 8, in, inlen);
-+        memcpy(out, aiv, 8);
-+        memset(out + 8 + inlen, 0, padding_len);
-+        block(out, out, key);
-+        ret = 16;               /* AIV + padded input */
-+    } else {
-+        memmove(out, in, inlen);
-+        memset(out + inlen, 0, padding_len); /* Section 4.1 step 1 */
-+        ret = CRYPTO_128_wrap(key, aiv, out, out, padded_len, block);
-+    }
-+
-+    return ret;
-+}
-+
-+/** Unwrapping according to RFC 5649 section 4.2.
-+ *
-+ *  @param[in]  key    Key value.
-+ *  @param[in]  icv    (Non-standard) IV, 4 bytes. NULL = use default_aiv.
-+ *  @param[out] out    Plaintext. Minimal buffer length = inlen bytes.
-+ *                     Input and output buffers can overlap if block function
-+ *                     supports that.
-+ *  @param[in]  in     Ciphertext as n 64-bit blocks.
-+ *  @param[in]  inlen  Length of in.
-+ *  @param[in]  block  Block processing function.
-+ *  @return            0 if inlen is out of range [16, CRYPTO128_WRAP_MAX],
-+ *                     or if inlen is not a multiple of 8
-+ *                     or if IV and message length indicator doesn't match.
-+ *                     Output length if unwrapping succeeded and IV matches.
-+ */
-+size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv,
-+                             unsigned char *out,
-+                             const unsigned char *in, size_t inlen,
-+                             block128_f block)
-+{
-+    /* n: number of 64-bit blocks in the padded key data */
-+    size_t n = inlen / 8 - 1;
-+    size_t padded_len;
-+    size_t padding_len;
-+    size_t ptext_len;
-+    /* RFC 5649 section 3: Alternative Initial Value */
-+    unsigned char aiv[8];
-+    static unsigned char zeros[8] = { 0x0 };
-+    size_t ret;
-+
-+    /* Section 4.2: Ciphertext length has to be (n+1) 64-bit blocks. */
-+    if ((inlen & 0x7) != 0 || inlen < 16 || inlen >= CRYPTO128_WRAP_MAX)
-+        return 0;
-+
-+    memmove(out, in, inlen);
-+    if (inlen == 16) {
-+        /*
-+         * Section 4.2 - special case in step 1: When n=1, the ciphertext
-+         * contains exactly two 64-bit blocks and they are decrypted as a
-+         * single AES block using AES in ECB mode: AIV | P[1] = DEC(K, C[0] |
-+         * C[1])
-+         */
-+        block(out, out, key);
-+        memcpy(aiv, out, 8);
-+        /* Remove AIV */
-+        memmove(out, out + 8, 8);
-+        padded_len = 8;
-+    } else {
-+        padded_len = inlen - 8;
-+        ret = crypto_128_unwrap_raw(key, aiv, out, out, inlen, block);
-+        if (padded_len != ret) {
-+            OPENSSL_cleanse(out, inlen);
-+            return 0;
-+        }
-+    }
-+
-+    /*
-+     * Section 3: AIV checks: Check that MSB(32,A) = A65959A6. Optionally a
-+     * user-supplied value can be used (even if standard doesn't mention
-+     * this).
-+     */
-+    if ((!icv && CRYPTO_memcmp(aiv, default_aiv, 4))
-+        || (icv && CRYPTO_memcmp(aiv, icv, 4))) {
-+        OPENSSL_cleanse(out, inlen);
-+        return 0;
-+    }
-+
-+    /*
-+     * Check that 8*(n-1) < LSB(32,AIV) <= 8*n. If so, let ptext_len =
-+     * LSB(32,AIV).
-+     */
-+
-+    ptext_len =   ((unsigned int)aiv[4] << 24)
-+                | ((unsigned int)aiv[5] << 16)
-+                | ((unsigned int)aiv[6] <<  8)
-+                |  (unsigned int)aiv[7];
-+    if (8 * (n - 1) >= ptext_len || ptext_len > 8 * n) {
-+        OPENSSL_cleanse(out, inlen);
-+        return 0;
-+    }
-+
-+    /*
-+     * Check that the rightmost padding_len octets of the output data are
-+     * zero.
-+     */
-+    padding_len = padded_len - ptext_len;
-+    if (CRYPTO_memcmp(out + ptext_len, zeros, padding_len) != 0) {
-+        OPENSSL_cleanse(out, inlen);
-+        return 0;
-+    }
-+
-+    /* Section 4.2 step 3: Remove padding */
-+    return ptext_len;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/xts128.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/xts128.c
-new file mode 100644
-index 0000000..81b1eac
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/modes/xts128.c
-@@ -0,0 +1,157 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "modes_lcl.h"
-+#include 
-+
-+int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
-+                          const unsigned char iv[16],
-+                          const unsigned char *inp, unsigned char *out,
-+                          size_t len, int enc)
-+{
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = {
-+        1
-+    };
-+    union {
-+        u64 u[2];
-+        u32 d[4];
-+        u8 c[16];
-+    } tweak, scratch;
-+    unsigned int i;
-+
-+    if (len < 16)
-+        return -1;
-+
-+    memcpy(tweak.c, iv, 16);
-+
-+    (*ctx->block2) (tweak.c, tweak.c, ctx->key2);
-+
-+    if (!enc && (len % 16))
-+        len -= 16;
-+
-+    while (len >= 16) {
-+#if defined(STRICT_ALIGNMENT)
-+        memcpy(scratch.c, inp, 16);
-+        scratch.u[0] ^= tweak.u[0];
-+        scratch.u[1] ^= tweak.u[1];
-+#else
-+        scratch.u[0] = ((u64 *)inp)[0] ^ tweak.u[0];
-+        scratch.u[1] = ((u64 *)inp)[1] ^ tweak.u[1];
-+#endif
-+        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
-+#if defined(STRICT_ALIGNMENT)
-+        scratch.u[0] ^= tweak.u[0];
-+        scratch.u[1] ^= tweak.u[1];
-+        memcpy(out, scratch.c, 16);
-+#else
-+        ((u64 *)out)[0] = scratch.u[0] ^= tweak.u[0];
-+        ((u64 *)out)[1] = scratch.u[1] ^= tweak.u[1];
-+#endif
-+        inp += 16;
-+        out += 16;
-+        len -= 16;
-+
-+        if (len == 0)
-+            return 0;
-+
-+        if (is_endian.little) {
-+            unsigned int carry, res;
-+
-+            res = 0x87 & (((int)tweak.d[3]) >> 31);
-+            carry = (unsigned int)(tweak.u[0] >> 63);
-+            tweak.u[0] = (tweak.u[0] << 1) ^ res;
-+            tweak.u[1] = (tweak.u[1] << 1) | carry;
-+        } else {
-+            size_t c;
-+
-+            for (c = 0, i = 0; i < 16; ++i) {
-+                /*
-+                 * + substitutes for |, because c is 1 bit
-+                 */
-+                c += ((size_t)tweak.c[i]) << 1;
-+                tweak.c[i] = (u8)c;
-+                c = c >> 8;
-+            }
-+            tweak.c[0] ^= (u8)(0x87 & (0 - c));
-+        }
-+    }
-+    if (enc) {
-+        for (i = 0; i < len; ++i) {
-+            u8 c = inp[i];
-+            out[i] = scratch.c[i];
-+            scratch.c[i] = c;
-+        }
-+        scratch.u[0] ^= tweak.u[0];
-+        scratch.u[1] ^= tweak.u[1];
-+        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
-+        scratch.u[0] ^= tweak.u[0];
-+        scratch.u[1] ^= tweak.u[1];
-+        memcpy(out - 16, scratch.c, 16);
-+    } else {
-+        union {
-+            u64 u[2];
-+            u8 c[16];
-+        } tweak1;
-+
-+        if (is_endian.little) {
-+            unsigned int carry, res;
-+
-+            res = 0x87 & (((int)tweak.d[3]) >> 31);
-+            carry = (unsigned int)(tweak.u[0] >> 63);
-+            tweak1.u[0] = (tweak.u[0] << 1) ^ res;
-+            tweak1.u[1] = (tweak.u[1] << 1) | carry;
-+        } else {
-+            size_t c;
-+
-+            for (c = 0, i = 0; i < 16; ++i) {
-+                /*
-+                 * + substitutes for |, because c is 1 bit
-+                 */
-+                c += ((size_t)tweak.c[i]) << 1;
-+                tweak1.c[i] = (u8)c;
-+                c = c >> 8;
-+            }
-+            tweak1.c[0] ^= (u8)(0x87 & (0 - c));
-+        }
-+#if defined(STRICT_ALIGNMENT)
-+        memcpy(scratch.c, inp, 16);
-+        scratch.u[0] ^= tweak1.u[0];
-+        scratch.u[1] ^= tweak1.u[1];
-+#else
-+        scratch.u[0] = ((u64 *)inp)[0] ^ tweak1.u[0];
-+        scratch.u[1] = ((u64 *)inp)[1] ^ tweak1.u[1];
-+#endif
-+        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
-+        scratch.u[0] ^= tweak1.u[0];
-+        scratch.u[1] ^= tweak1.u[1];
-+
-+        for (i = 0; i < len; ++i) {
-+            u8 c = inp[16 + i];
-+            out[16 + i] = scratch.c[i];
-+            scratch.c[i] = c;
-+        }
-+        scratch.u[0] ^= tweak.u[0];
-+        scratch.u[1] ^= tweak.u[1];
-+        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
-+#if defined(STRICT_ALIGNMENT)
-+        scratch.u[0] ^= tweak.u[0];
-+        scratch.u[1] ^= tweak.u[1];
-+        memcpy(out, scratch.c, 16);
-+#else
-+        ((u64 *)out)[0] = scratch.u[0] ^ tweak.u[0];
-+        ((u64 *)out)[1] = scratch.u[1] ^ tweak.u[1];
-+#endif
-+    }
-+
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/o_dir.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_dir.c
-new file mode 100644
-index 0000000..89c8c5c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_dir.c
-@@ -0,0 +1,36 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+/*
-+ * The routines really come from the Levitte Programming, so to make life
-+ * simple, let's just use the raw files and hack the symbols to fit our
-+ * namespace.
-+ */
-+#define LP_DIR_CTX OPENSSL_DIR_CTX
-+#define LP_dir_context_st OPENSSL_dir_context_st
-+#define LP_find_file OPENSSL_DIR_read
-+#define LP_find_file_end OPENSSL_DIR_end
-+
-+#include "internal/o_dir.h"
-+
-+#define LPDIR_H
-+#if defined OPENSSL_SYS_UNIX || defined DJGPP
-+# include "LPdir_unix.c"
-+#elif defined OPENSSL_SYS_VMS
-+# include "LPdir_vms.c"
-+#elif defined OPENSSL_SYS_WIN32
-+# include "LPdir_win32.c"
-+#elif defined OPENSSL_SYS_WINCE
-+# include "LPdir_wince.c"
-+#else
-+# include "LPdir_nyi.c"
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/o_fips.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_fips.c
-new file mode 100644
-index 0000000..bf6db65
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_fips.c
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#ifdef OPENSSL_FIPS
-+# include 
-+#endif
-+
-+int FIPS_mode(void)
-+{
-+#ifdef OPENSSL_FIPS
-+    return FIPS_module_mode();
-+#else
-+    return 0;
-+#endif
-+}
-+
-+int FIPS_mode_set(int r)
-+{
-+#ifdef OPENSSL_FIPS
-+    return FIPS_module_mode_set(r);
-+#else
-+    if (r == 0)
-+        return 1;
-+    CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED);
-+    return 0;
-+#endif
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/o_fopen.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_fopen.c
-new file mode 100644
-index 0000000..a3a0065
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_fopen.c
-@@ -0,0 +1,103 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+
-+#if !defined(OPENSSL_NO_STDIO)
-+
-+# include 
-+
-+FILE *openssl_fopen(const char *filename, const char *mode)
-+{
-+    FILE *file = NULL;
-+# if defined(_WIN32) && defined(CP_UTF8)
-+    int sz, len_0 = (int)strlen(filename) + 1;
-+    DWORD flags;
-+
-+    /*
-+     * Basically there are three cases to cover: a) filename is
-+     * pure ASCII string; b) actual UTF-8 encoded string and
-+     * c) locale-ized string, i.e. one containing 8-bit
-+     * characters that are meaningful in current system locale.
-+     * If filename is pure ASCII or real UTF-8 encoded string,
-+     * MultiByteToWideChar succeeds and _wfopen works. If
-+     * filename is locale-ized string, chances are that
-+     * MultiByteToWideChar fails reporting
-+     * ERROR_NO_UNICODE_TRANSLATION, in which case we fall
-+     * back to fopen...
-+     */
-+    if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS),
-+                                  filename, len_0, NULL, 0)) > 0 ||
-+        (GetLastError() == ERROR_INVALID_FLAGS &&
-+         (sz = MultiByteToWideChar(CP_UTF8, (flags = 0),
-+                                   filename, len_0, NULL, 0)) > 0)
-+        ) {
-+        WCHAR wmode[8];
-+        WCHAR *wfilename = _alloca(sz * sizeof(WCHAR));
-+
-+        if (MultiByteToWideChar(CP_UTF8, flags,
-+                                filename, len_0, wfilename, sz) &&
-+            MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1,
-+                                wmode, OSSL_NELEM(wmode)) &&
-+            (file = _wfopen(wfilename, wmode)) == NULL &&
-+            (errno == ENOENT || errno == EBADF)
-+            ) {
-+            /*
-+             * UTF-8 decode succeeded, but no file, filename
-+             * could still have been locale-ized...
-+             */
-+            file = fopen(filename, mode);
-+        }
-+    } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
-+        file = fopen(filename, mode);
-+    }
-+# elif defined(__DJGPP__)
-+    {
-+        char *newname = NULL;
-+
-+        if (!HAS_LFN_SUPPORT(filename)) {
-+            char *iterator;
-+            char lastchar;
-+
-+            newname = OPENSSL_malloc(strlen(filename) + 1);
-+            if (newname == NULL)
-+                return NULL;
-+
-+            for (iterator = newname, lastchar = '\0';
-+                *filename; filename++, iterator++) {
-+                if (lastchar == '/' && filename[0] == '.'
-+                    && filename[1] != '.' && filename[1] != '/') {
-+                    /* Leading dots are not permitted in plain DOS. */
-+                    *iterator = '_';
-+                } else {
-+                    *iterator = *filename;
-+                }
-+                lastchar = *filename;
-+            }
-+            *iterator = '\0';
-+            filename = newname;
-+        }
-+        file = fopen(filename, mode);
-+
-+        OPENSSL_free(newname);
-+    }
-+# else
-+    file = fopen(filename, mode);
-+# endif
-+    return file;
-+}
-+
-+#else
-+
-+void *openssl_fopen(const char *filename, const char *mode)
-+{
-+    return NULL;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/o_init.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_init.c
-new file mode 100644
-index 0000000..2e0c126
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_init.c
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#ifdef OPENSSL_FIPS
-+# include 
-+# include 
-+#endif
-+
-+/*
-+ * Perform any essential OpenSSL initialization operations. Currently only
-+ * sets FIPS callbacks
-+ */
-+
-+void OPENSSL_init(void)
-+{
-+    static int done = 0;
-+    if (done)
-+        return;
-+    done = 1;
-+#ifdef OPENSSL_FIPS
-+    FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock);
-+    FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata);
-+    FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free);
-+    RAND_init_fips();
-+#endif
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/o_str.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_str.c
-new file mode 100644
-index 0000000..beabec0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_str.c
-@@ -0,0 +1,250 @@
-+/*
-+ * Copyright 2003-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include "internal/o_str.h"
-+
-+int OPENSSL_memcmp(const void *v1, const void *v2, size_t n)
-+{
-+    const unsigned char *c1 = v1, *c2 = v2;
-+    int ret = 0;
-+
-+    while (n && (ret = *c1 - *c2) == 0)
-+        n--, c1++, c2++;
-+
-+    return ret;
-+}
-+
-+char *CRYPTO_strdup(const char *str, const char* file, int line)
-+{
-+    char *ret;
-+    size_t size;
-+
-+    if (str == NULL)
-+        return NULL;
-+    size = strlen(str) + 1;
-+    ret = CRYPTO_malloc(size, file, line);
-+    if (ret != NULL)
-+        memcpy(ret, str, size);
-+    return ret;
-+}
-+
-+char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line)
-+{
-+    size_t maxlen;
-+    char *ret;
-+
-+    if (str == NULL)
-+        return NULL;
-+
-+    maxlen = OPENSSL_strnlen(str, s);
-+
-+    ret = CRYPTO_malloc(maxlen + 1, file, line);
-+    if (ret) {
-+        memcpy(ret, str, maxlen);
-+        ret[maxlen] = '\0';
-+    }
-+    return ret;
-+}
-+
-+void *CRYPTO_memdup(const void *data, size_t siz, const char* file, int line)
-+{
-+    void *ret;
-+
-+    if (data == NULL || siz >= INT_MAX)
-+        return NULL;
-+
-+    ret = CRYPTO_malloc(siz, file, line);
-+    if (ret == NULL) {
-+        CRYPTOerr(CRYPTO_F_CRYPTO_MEMDUP, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    return memcpy(ret, data, siz);
-+}
-+
-+size_t OPENSSL_strnlen(const char *str, size_t maxlen)
-+{
-+    const char *p;
-+
-+    for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ;
-+
-+    return p - str;
-+}
-+
-+size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size)
-+{
-+    size_t l = 0;
-+    for (; size > 1 && *src; size--) {
-+        *dst++ = *src++;
-+        l++;
-+    }
-+    if (size)
-+        *dst = '\0';
-+    return l + strlen(src);
-+}
-+
-+size_t OPENSSL_strlcat(char *dst, const char *src, size_t size)
-+{
-+    size_t l = 0;
-+    for (; size > 0 && *dst; size--, dst++)
-+        l++;
-+    return l + OPENSSL_strlcpy(dst, src, size);
-+}
-+
-+int OPENSSL_hexchar2int(unsigned char c)
-+{
-+#ifdef CHARSET_EBCDIC
-+    c = os_toebcdic[c];
-+#endif
-+
-+    switch (c) {
-+    case '0':
-+        return 0;
-+    case '1':
-+        return 1;
-+    case '2':
-+        return 2;
-+    case '3':
-+        return 3;
-+    case '4':
-+          return 4;
-+    case '5':
-+          return 5;
-+    case '6':
-+          return 6;
-+    case '7':
-+          return 7;
-+    case '8':
-+          return 8;
-+    case '9':
-+          return 9;
-+    case 'a': case 'A':
-+          return 0x0A;
-+    case 'b': case 'B':
-+          return 0x0B;
-+    case 'c': case 'C':
-+          return 0x0C;
-+    case 'd': case 'D':
-+          return 0x0D;
-+    case 'e': case 'E':
-+          return 0x0E;
-+    case 'f': case 'F':
-+          return 0x0F;
-+    }
-+    return -1;
-+}
-+
-+/*
-+ * Give a string of hex digits convert to a buffer
-+ */
-+unsigned char *OPENSSL_hexstr2buf(const char *str, long *len)
-+{
-+    unsigned char *hexbuf, *q;
-+    unsigned char ch, cl;
-+    int chi, cli;
-+    const unsigned char *p;
-+    size_t s;
-+
-+    s = strlen(str);
-+    if ((hexbuf = OPENSSL_malloc(s >> 1)) == NULL) {
-+        CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    for (p = (const unsigned char *)str, q = hexbuf; *p; ) {
-+        ch = *p++;
-+        if (ch == ':')
-+            continue;
-+        cl = *p++;
-+        if (!cl) {
-+            CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF,
-+                      CRYPTO_R_ODD_NUMBER_OF_DIGITS);
-+            OPENSSL_free(hexbuf);
-+            return NULL;
-+        }
-+        cli = OPENSSL_hexchar2int(cl);
-+        chi = OPENSSL_hexchar2int(ch);
-+        if (cli < 0 || chi < 0) {
-+            OPENSSL_free(hexbuf);
-+            CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT);
-+            return NULL;
-+        }
-+        *q++ = (unsigned char)((chi << 4) | cli);
-+    }
-+
-+    if (len)
-+        *len = q - hexbuf;
-+    return hexbuf;
-+}
-+
-+/*
-+ * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
-+ * hex representation @@@ (Contents of buffer are always kept in ASCII, also
-+ * on EBCDIC machines)
-+ */
-+char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len)
-+{
-+    const static char hexdig[] = "0123456789ABCDEF";
-+    char *tmp, *q;
-+    const unsigned char *p;
-+    int i;
-+
-+    if (len == 0)
-+    {
-+        return OPENSSL_zalloc(1);
-+    }
-+
-+    if ((tmp = OPENSSL_malloc(len * 3)) == NULL) {
-+        CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    q = tmp;
-+    for (i = 0, p = buffer; i < len; i++, p++) {
-+        *q++ = hexdig[(*p >> 4) & 0xf];
-+        *q++ = hexdig[*p & 0xf];
-+        *q++ = ':';
-+    }
-+    q[-1] = 0;
-+#ifdef CHARSET_EBCDIC
-+    ebcdic2ascii(tmp, tmp, q - tmp - 1);
-+#endif
-+
-+    return tmp;
-+}
-+
-+int openssl_strerror_r(int errnum, char *buf, size_t buflen)
-+{
-+#if defined(_MSC_VER) && _MSC_VER>=1400
-+    return !strerror_s(buf, buflen, errnum);
-+#elif defined(_GNU_SOURCE)
-+    return strerror_r(errnum, buf, buflen) != NULL;
-+#elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
-+    /*
-+     * We can use "real" strerror_r. The OpenSSL version differs in that it
-+     * gives 1 on success and 0 on failure for consistency with other OpenSSL
-+     * functions. Real strerror_r does it the other way around
-+     */
-+    return !strerror_r(errnum, buf, buflen);
-+#else
-+    char *err;
-+    /* Fall back to non-thread safe strerror()...its all we can do */
-+    if (buflen < 2)
-+        return 0;
-+    err = strerror(errnum);
-+    /* Can this ever happen? */
-+    if (err == NULL)
-+        return 0;
-+    strncpy(buf, err, buflen - 1);
-+    buf[buflen - 1] = '\0';
-+    return 1;
-+#endif
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/o_time.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_time.c
-new file mode 100755
-index 0000000..4b902e0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/o_time.c
-@@ -0,0 +1,360 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+#ifdef OPENSSL_SYS_VMS
-+# if __CRTL_VER >= 70000000 && \
-+     (defined _POSIX_C_SOURCE || !defined _ANSI_C_SOURCE)
-+#  define VMS_GMTIME_OK
-+# endif
-+# ifndef VMS_GMTIME_OK
-+#  include 
-+#  include 
-+#  include 
-+#  include 
-+#  include 
-+#  include 
-+# endif                         /* ndef VMS_GMTIME_OK */
-+
-+
-+/*
-+ * Needed to pick up the correct definitions and declarations in some of the
-+ * DEC C Header Files (*.H).
-+ */
-+# define __NEW_STARLET 1
-+
-+# if (defined(__alpha) || defined(__ia64))
-+#  include 
-+# else
-+
-+/* VAX */
-+typedef struct _ile3 {          /* Copied from ILEDEF.H for Alpha   */
-+#  pragma __nomember_alignment
-+    unsigned short int ile3$w_length;        /* Length of buffer in bytes */
-+    unsigned short int ile3$w_code;          /* Item code value */
-+    void *ile3$ps_bufaddr;                   /* Buffer address */
-+    unsigned short int *ile3$ps_retlen_addr; /* Address of word for returned length */
-+} ILE3;
-+# endif   /* alpha || ia64    */
-+#endif    /* OPENSSL_SYS_VMS  */
-+
-+struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
-+{
-+    struct tm *ts = NULL;
-+
-+#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX)
-+    if (gmtime_r(timer, result) == NULL)
-+        return NULL;
-+    ts = result;
-+#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK)
-+    ts = gmtime(timer);
-+    if (ts == NULL)
-+        return NULL;
-+
-+    memcpy(result, ts, sizeof(struct tm));
-+    ts = result;
-+#endif
-+#if defined( OPENSSL_SYS_VMS) && !defined( VMS_GMTIME_OK)
-+    if (ts == NULL) {
-+        static $DESCRIPTOR(tabnam, "LNM$DCL_LOGICAL");
-+        static $DESCRIPTOR(lognam, "SYS$TIMEZONE_DIFFERENTIAL");
-+        char logvalue[256];
-+        unsigned int reslen = 0;
-+# if __INITIAL_POINTER_SIZE == 64
-+        ILEB_64 itemlist[2], *pitem;
-+# else
-+        ILE3 itemlist[2], *pitem;
-+# endif
-+        int status;
-+        time_t t;
-+
-+
-+        /*
-+         * Setup an itemlist for the call to $TRNLNM - Translate Logical Name.
-+         */
-+        pitem = itemlist;
-+
-+# if __INITIAL_POINTER_SIZE == 64
-+        pitem->ileb_64$w_mbo = 1;
-+        pitem->ileb_64$w_code = LNM$_STRING;
-+        pitem->ileb_64$l_mbmo = -1;
-+        pitem->ileb_64$q_length = sizeof (logvalue);
-+        pitem->ileb_64$pq_bufaddr = logvalue;
-+        pitem->ileb_64$pq_retlen_addr = (unsigned __int64 *) &reslen;
-+        pitem++;
-+        /* Last item of the item list is null terminated */
-+        pitem->ileb_64$q_length = pitem->ileb_64$w_code = 0;
-+# else
-+        pitem->ile3$w_length = sizeof (logvalue);
-+        pitem->ile3$w_code = LNM$_STRING;
-+        pitem->ile3$ps_bufaddr = logvalue;
-+        pitem->ile3$ps_retlen_addr = (unsigned short int *) &reslen;
-+        pitem++;
-+        /* Last item of the item list is null terminated */
-+        pitem->ile3$w_length = pitem->ile3$w_code = 0;
-+# endif
-+
-+
-+        /* Get the value for SYS$TIMEZONE_DIFFERENTIAL */
-+        status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist);
-+        if (!(status & 1))
-+            return NULL;
-+        logvalue[reslen] = '\0';
-+
-+        t = *timer;
-+
-+        /* The following is extracted from the DEC C header time.h */
-+        /*
-+         **  Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime
-+         **  have two implementations.  One implementation is provided
-+         **  for compatibility and deals with time in terms of local time,
-+         **  the other __utc_* deals with time in terms of UTC.
-+         */
-+        /*
-+         * We use the same conditions as in said time.h to check if we should
-+         * assume that t contains local time (and should therefore be
-+         * adjusted) or UTC (and should therefore be left untouched).
-+         */
-+# if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE
-+        /* Get the numerical value of the equivalence string */
-+        status = atoi(logvalue);
-+
-+        /* and use it to move time to GMT */
-+        t -= status;
-+# endif
-+
-+        /* then convert the result to the time structure */
-+
-+        /*
-+         * Since there was no gmtime_r() to do this stuff for us, we have to
-+         * do it the hard way.
-+         */
-+        {
-+            /*-
-+             * The VMS epoch is the astronomical Smithsonian date,
-+               if I remember correctly, which is November 17, 1858.
-+               Furthermore, time is measure in tenths of microseconds
-+               and stored in quadwords (64 bit integers).  unix_epoch
-+               below is January 1st 1970 expressed as a VMS time.  The
-+               following code was used to get this number:
-+
-+               #include 
-+               #include 
-+               #include 
-+               #include 
-+
-+               main()
-+               {
-+                 unsigned long systime[2];
-+                 unsigned short epoch_values[7] =
-+                   { 1970, 1, 1, 0, 0, 0, 0 };
-+
-+                 lib$cvt_vectim(epoch_values, systime);
-+
-+                 printf("%u %u", systime[0], systime[1]);
-+               }
-+            */
-+            unsigned long unix_epoch[2] = { 1273708544, 8164711 };
-+            unsigned long deltatime[2];
-+            unsigned long systime[2];
-+            struct vms_vectime {
-+                short year, month, day, hour, minute, second, centi_second;
-+            } time_values;
-+            long operation;
-+
-+            /*
-+             * Turn the number of seconds since January 1st 1970 to an
-+             * internal delta time. Note that lib$cvt_to_internal_time() will
-+             * assume that t is signed, and will therefore break on 32-bit
-+             * systems some time in 2038.
-+             */
-+            operation = LIB$K_DELTA_SECONDS;
-+            status = lib$cvt_to_internal_time(&operation, &t, deltatime);
-+
-+            /*
-+             * Add the delta time with the Unix epoch and we have the current
-+             * UTC time in internal format
-+             */
-+            status = lib$add_times(unix_epoch, deltatime, systime);
-+
-+            /* Turn the internal time into a time vector */
-+            status = sys$numtim(&time_values, systime);
-+
-+            /* Fill in the struct tm with the result */
-+            result->tm_sec = time_values.second;
-+            result->tm_min = time_values.minute;
-+            result->tm_hour = time_values.hour;
-+            result->tm_mday = time_values.day;
-+            result->tm_mon = time_values.month - 1;
-+            result->tm_year = time_values.year - 1900;
-+
-+            operation = LIB$K_DAY_OF_WEEK;
-+            status = lib$cvt_from_internal_time(&operation,
-+                                                &result->tm_wday, systime);
-+            result->tm_wday %= 7;
-+
-+            operation = LIB$K_DAY_OF_YEAR;
-+            status = lib$cvt_from_internal_time(&operation,
-+                                                &result->tm_yday, systime);
-+            result->tm_yday--;
-+
-+            result->tm_isdst = 0; /* There's no way to know... */
-+
-+            ts = result;
-+        }
-+    }
-+#endif
-+    return ts;
-+}
-+
-+/*
-+ * Take a tm structure and add an offset to it. This avoids any OS issues
-+ * with restricted date types and overflows which cause the year 2038
-+ * problem.
-+ */
-+
-+#define SECS_PER_DAY (24 * 60 * 60)
-+
-+static long date_to_julian(int y, int m, int d);
-+static void julian_to_date(long jd, int *y, int *m, int *d);
-+static int julian_adj(const struct tm *tm, int off_day, long offset_sec,
-+                      long *pday, int *psec);
-+
-+int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec)
-+{
-+    int time_sec, time_year, time_month, time_day;
-+    long time_jd;
-+
-+    /* Convert time and offset into Julian day and seconds */
-+    if (!julian_adj(tm, off_day, offset_sec, &time_jd, &time_sec))
-+        return 0;
-+
-+    /* Convert Julian day back to date */
-+
-+    julian_to_date(time_jd, &time_year, &time_month, &time_day);
-+
-+    if (time_year < 1900 || time_year > 9999)
-+        return 0;
-+
-+    /* Update tm structure */
-+
-+    tm->tm_year = time_year - 1900;
-+    tm->tm_mon = time_month - 1;
-+    tm->tm_mday = time_day;
-+
-+    tm->tm_hour = time_sec / 3600;
-+    tm->tm_min = (time_sec / 60) % 60;
-+    tm->tm_sec = time_sec % 60;
-+
-+    return 1;
-+
-+}
-+
-+int OPENSSL_gmtime_diff(int *pday, int *psec,
-+                        const struct tm *from, const struct tm *to)
-+{
-+    int from_sec, to_sec, diff_sec;
-+    long from_jd, to_jd, diff_day;
-+    if (!julian_adj(from, 0, 0, &from_jd, &from_sec))
-+        return 0;
-+    if (!julian_adj(to, 0, 0, &to_jd, &to_sec))
-+        return 0;
-+    diff_day = to_jd - from_jd;
-+    diff_sec = to_sec - from_sec;
-+    /* Adjust differences so both positive or both negative */
-+    if (diff_day > 0 && diff_sec < 0) {
-+        diff_day--;
-+        diff_sec += SECS_PER_DAY;
-+    }
-+    if (diff_day < 0 && diff_sec > 0) {
-+        diff_day++;
-+        diff_sec -= SECS_PER_DAY;
-+    }
-+
-+    if (pday)
-+        *pday = (int)diff_day;
-+    if (psec)
-+        *psec = diff_sec;
-+
-+    return 1;
-+
-+}
-+
-+/* Convert tm structure and offset into julian day and seconds */
-+static int julian_adj(const struct tm *tm, int off_day, long offset_sec,
-+                      long *pday, int *psec)
-+{
-+    int offset_hms, offset_day;
-+    long time_jd;
-+    int time_year, time_month, time_day;
-+    /* split offset into days and day seconds */
-+    offset_day = offset_sec / SECS_PER_DAY;
-+    /* Avoid sign issues with % operator */
-+    offset_hms = offset_sec - (offset_day * SECS_PER_DAY);
-+    offset_day += off_day;
-+    /* Add current time seconds to offset */
-+    offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
-+    /* Adjust day seconds if overflow */
-+    if (offset_hms >= SECS_PER_DAY) {
-+        offset_day++;
-+        offset_hms -= SECS_PER_DAY;
-+    } else if (offset_hms < 0) {
-+        offset_day--;
-+        offset_hms += SECS_PER_DAY;
-+    }
-+
-+    /*
-+     * Convert date of time structure into a Julian day number.
-+     */
-+
-+    time_year = tm->tm_year + 1900;
-+    time_month = tm->tm_mon + 1;
-+    time_day = tm->tm_mday;
-+
-+    time_jd = date_to_julian(time_year, time_month, time_day);
-+
-+    /* Work out Julian day of new date */
-+    time_jd += offset_day;
-+
-+    if (time_jd < 0)
-+        return 0;
-+
-+    *pday = time_jd;
-+    *psec = offset_hms;
-+    return 1;
-+}
-+
-+/*
-+ * Convert date to and from julian day Uses Fliegel & Van Flandern algorithm
-+ */
-+static long date_to_julian(int y, int m, int d)
-+{
-+    return (1461 * (y + 4800 + (m - 14) / 12)) / 4 +
-+        (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 -
-+        (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + d - 32075;
-+}
-+
-+static void julian_to_date(long jd, int *y, int *m, int *d)
-+{
-+    long L = jd + 68569;
-+    long n = (4 * L) / 146097;
-+    long i, j;
-+
-+    L = L - (146097 * n + 3) / 4;
-+    i = (4000 * (L + 1)) / 1461001;
-+    L = L - (1461 * i) / 4 + 31;
-+    j = (80 * L) / 2447;
-+    *d = L - (2447 * j) / 80;
-+    L = j / 11;
-+    *m = j + 2 - (12 * L);
-+    *y = 100 * (n - 49) + i + L;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/README b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/README
-new file mode 100644
-index 0000000..cb1d216
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/README
-@@ -0,0 +1,44 @@
-+objects.txt syntax
-+------------------
-+
-+To cover all the naming hacks that were previously in objects.h needed some
-+kind of hacks in objects.txt.
-+
-+The basic syntax for adding an object is as follows:
-+
-+	1 2 3 4		: shortName	: Long Name
-+
-+		If Long Name contains only word characters and hyphen-minus
-+		(0x2D) or full stop (0x2E) then Long Name is used as basis
-+		for the base name in C. Otherwise, the shortName is used.
-+
-+		The base name (let's call it 'base') will then be used to
-+		create the C macros SN_base, LN_base, NID_base and OBJ_base.
-+
-+		Note that if the base name contains spaces, dashes or periods,
-+		those will be converte to underscore.
-+
-+Then there are some extra commands:
-+
-+	!Alias foo 1 2 3 4
-+
-+		This just makes a name foo for an OID.  The C macro
-+		OBJ_foo will be created as a result.
-+
-+	!Cname foo
-+
-+		This makes sure that the name foo will be used as base name
-+		in C.
-+
-+	!module foo
-+	1 2 3 4		: shortName	: Long Name
-+	!global
-+
-+		The !module command was meant to define a kind of modularity.
-+		What it does is to make sure the module name is prepended
-+		to the base name.  !global turns this off.  This construction
-+		is not recursive.
-+
-+Lines starting with # are treated as comments, as well as any line starting
-+with ! and not matching the commands above.
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/build.info
-new file mode 100644
-index 0000000..38e2907
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        o_names.c obj_dat.c obj_lib.c obj_err.c obj_xref.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/o_names.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/o_names.c
-new file mode 100644
-index 0000000..ed98df8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/o_names.c
-@@ -0,0 +1,370 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "obj_lcl.h"
-+
-+/*
-+ * We define this wrapper for two reasons. Firstly, later versions of
-+ * DEC C add linkage information to certain functions, which makes it
-+ * tricky to use them as values to regular function pointers.
-+ * Secondly, in the EDK2 build environment, the strcmp function is
-+ * actually an external function (AsciiStrCmp) with the Microsoft ABI,
-+ * so we can't transparently assign function pointers to it.
-+ * Arguably the latter is a stupidity of the UEFI environment, but
-+ * since the wrapper solves the DEC C issue too, let's just use the
-+ * same solution.
-+ */
-+#if defined(OPENSSL_SYS_VMS_DECC) || defined(OPENSSL_SYS_UEFI)
-+static int obj_strcmp(const char *a, const char *b)
-+{
-+    return strcmp(a, b);
-+}
-+#else
-+#define obj_strcmp strcmp
-+#endif
-+
-+/*
-+ * I use the ex_data stuff to manage the identifiers for the obj_name_types
-+ * that applications may define.  I only really use the free function field.
-+ */
-+static LHASH_OF(OBJ_NAME) *names_lh = NULL;
-+static int names_type_num = OBJ_NAME_TYPE_NUM;
-+
-+struct name_funcs_st {
-+    unsigned long (*hash_func) (const char *name);
-+    int (*cmp_func) (const char *a, const char *b);
-+    void (*free_func) (const char *, int, const char *);
-+};
-+
-+static STACK_OF(NAME_FUNCS) *name_funcs_stack;
-+
-+/*
-+ * The LHASH callbacks now use the raw "void *" prototypes and do
-+ * per-variable casting in the functions. This prevents function pointer
-+ * casting without the need for macro-generated wrapper functions.
-+ */
-+
-+static unsigned long obj_name_hash(const OBJ_NAME *a);
-+static int obj_name_cmp(const OBJ_NAME *a, const OBJ_NAME *b);
-+
-+int OBJ_NAME_init(void)
-+{
-+    if (names_lh != NULL)
-+        return (1);
-+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+    names_lh = lh_OBJ_NAME_new(obj_name_hash, obj_name_cmp);
-+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+    return (names_lh != NULL);
-+}
-+
-+int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *),
-+                       int (*cmp_func) (const char *, const char *),
-+                       void (*free_func) (const char *, int, const char *))
-+{
-+    int ret, i, push;
-+    NAME_FUNCS *name_funcs;
-+
-+    if (name_funcs_stack == NULL) {
-+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+        name_funcs_stack = sk_NAME_FUNCS_new_null();
-+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+    }
-+    if (name_funcs_stack == NULL) {
-+        /* ERROR */
-+        return (0);
-+    }
-+    ret = names_type_num;
-+    names_type_num++;
-+    for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) {
-+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+        name_funcs = OPENSSL_zalloc(sizeof(*name_funcs));
-+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+        if (name_funcs == NULL) {
-+            OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE);
-+            return (0);
-+        }
-+        name_funcs->hash_func = OPENSSL_LH_strhash;
-+        name_funcs->cmp_func = obj_strcmp;
-+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
-+
-+        push = sk_NAME_FUNCS_push(name_funcs_stack, name_funcs);
-+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
-+
-+        if (!push) {
-+            OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE);
-+            OPENSSL_free(name_funcs);
-+            return 0;
-+        }
-+    }
-+    name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
-+    if (hash_func != NULL)
-+        name_funcs->hash_func = hash_func;
-+    if (cmp_func != NULL)
-+        name_funcs->cmp_func = cmp_func;
-+    if (free_func != NULL)
-+        name_funcs->free_func = free_func;
-+    return (ret);
-+}
-+
-+static int obj_name_cmp(const OBJ_NAME *a, const OBJ_NAME *b)
-+{
-+    int ret;
-+
-+    ret = a->type - b->type;
-+    if (ret == 0) {
-+        if ((name_funcs_stack != NULL)
-+            && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) {
-+            ret = sk_NAME_FUNCS_value(name_funcs_stack,
-+                                      a->type)->cmp_func(a->name, b->name);
-+        } else
-+            ret = strcmp(a->name, b->name);
-+    }
-+    return (ret);
-+}
-+
-+static unsigned long obj_name_hash(const OBJ_NAME *a)
-+{
-+    unsigned long ret;
-+
-+    if ((name_funcs_stack != NULL)
-+        && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) {
-+        ret =
-+            sk_NAME_FUNCS_value(name_funcs_stack,
-+                                a->type)->hash_func(a->name);
-+    } else {
-+        ret = OPENSSL_LH_strhash(a->name);
-+    }
-+    ret ^= a->type;
-+    return (ret);
-+}
-+
-+const char *OBJ_NAME_get(const char *name, int type)
-+{
-+    OBJ_NAME on, *ret;
-+    int num = 0, alias;
-+
-+    if (name == NULL)
-+        return (NULL);
-+    if ((names_lh == NULL) && !OBJ_NAME_init())
-+        return (NULL);
-+
-+    alias = type & OBJ_NAME_ALIAS;
-+    type &= ~OBJ_NAME_ALIAS;
-+
-+    on.name = name;
-+    on.type = type;
-+
-+    for (;;) {
-+        ret = lh_OBJ_NAME_retrieve(names_lh, &on);
-+        if (ret == NULL)
-+            return (NULL);
-+        if ((ret->alias) && !alias) {
-+            if (++num > 10)
-+                return (NULL);
-+            on.name = ret->data;
-+        } else {
-+            return (ret->data);
-+        }
-+    }
-+}
-+
-+int OBJ_NAME_add(const char *name, int type, const char *data)
-+{
-+    OBJ_NAME *onp, *ret;
-+    int alias;
-+
-+    if ((names_lh == NULL) && !OBJ_NAME_init())
-+        return (0);
-+
-+    alias = type & OBJ_NAME_ALIAS;
-+    type &= ~OBJ_NAME_ALIAS;
-+
-+    onp = OPENSSL_malloc(sizeof(*onp));
-+    if (onp == NULL) {
-+        /* ERROR */
-+        return 0;
-+    }
-+
-+    onp->name = name;
-+    onp->alias = alias;
-+    onp->type = type;
-+    onp->data = data;
-+
-+    ret = lh_OBJ_NAME_insert(names_lh, onp);
-+    if (ret != NULL) {
-+        /* free things */
-+        if ((name_funcs_stack != NULL)
-+            && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) {
-+            /*
-+             * XXX: I'm not sure I understand why the free function should
-+             * get three arguments... -- Richard Levitte
-+             */
-+            sk_NAME_FUNCS_value(name_funcs_stack,
-+                                ret->type)->free_func(ret->name, ret->type,
-+                                                      ret->data);
-+        }
-+        OPENSSL_free(ret);
-+    } else {
-+        if (lh_OBJ_NAME_error(names_lh)) {
-+            /* ERROR */
-+            OPENSSL_free(onp);
-+            return 0;
-+        }
-+    }
-+    return 1;
-+}
-+
-+int OBJ_NAME_remove(const char *name, int type)
-+{
-+    OBJ_NAME on, *ret;
-+
-+    if (names_lh == NULL)
-+        return (0);
-+
-+    type &= ~OBJ_NAME_ALIAS;
-+    on.name = name;
-+    on.type = type;
-+    ret = lh_OBJ_NAME_delete(names_lh, &on);
-+    if (ret != NULL) {
-+        /* free things */
-+        if ((name_funcs_stack != NULL)
-+            && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) {
-+            /*
-+             * XXX: I'm not sure I understand why the free function should
-+             * get three arguments... -- Richard Levitte
-+             */
-+            sk_NAME_FUNCS_value(name_funcs_stack,
-+                                ret->type)->free_func(ret->name, ret->type,
-+                                                      ret->data);
-+        }
-+        OPENSSL_free(ret);
-+        return (1);
-+    } else
-+        return (0);
-+}
-+
-+typedef struct {
-+    int type;
-+    void (*fn) (const OBJ_NAME *, void *arg);
-+    void *arg;
-+} OBJ_DOALL;
-+
-+static void do_all_fn(const OBJ_NAME *name, OBJ_DOALL *d)
-+{
-+    if (name->type == d->type)
-+        d->fn(name, d->arg);
-+}
-+
-+IMPLEMENT_LHASH_DOALL_ARG_CONST(OBJ_NAME, OBJ_DOALL);
-+
-+void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg),
-+                     void *arg)
-+{
-+    OBJ_DOALL d;
-+
-+    d.type = type;
-+    d.fn = fn;
-+    d.arg = arg;
-+
-+    lh_OBJ_NAME_doall_OBJ_DOALL(names_lh, do_all_fn, &d);
-+}
-+
-+struct doall_sorted {
-+    int type;
-+    int n;
-+    const OBJ_NAME **names;
-+};
-+
-+static void do_all_sorted_fn(const OBJ_NAME *name, void *d_)
-+{
-+    struct doall_sorted *d = d_;
-+
-+    if (name->type != d->type)
-+        return;
-+
-+    d->names[d->n++] = name;
-+}
-+
-+static int do_all_sorted_cmp(const void *n1_, const void *n2_)
-+{
-+    const OBJ_NAME *const *n1 = n1_;
-+    const OBJ_NAME *const *n2 = n2_;
-+
-+    return strcmp((*n1)->name, (*n2)->name);
-+}
-+
-+void OBJ_NAME_do_all_sorted(int type,
-+                            void (*fn) (const OBJ_NAME *, void *arg),
-+                            void *arg)
-+{
-+    struct doall_sorted d;
-+    int n;
-+
-+    d.type = type;
-+    d.names =
-+        OPENSSL_malloc(sizeof(*d.names) * lh_OBJ_NAME_num_items(names_lh));
-+    /* Really should return an error if !d.names...but its a void function! */
-+    if (d.names != NULL) {
-+        d.n = 0;
-+        OBJ_NAME_do_all(type, do_all_sorted_fn, &d);
-+
-+        qsort((void *)d.names, d.n, sizeof(*d.names), do_all_sorted_cmp);
-+
-+        for (n = 0; n < d.n; ++n)
-+            fn(d.names[n], arg);
-+
-+        OPENSSL_free((void *)d.names);
-+    }
-+}
-+
-+static int free_type;
-+
-+static void names_lh_free_doall(OBJ_NAME *onp)
-+{
-+    if (onp == NULL)
-+        return;
-+
-+    if (free_type < 0 || free_type == onp->type)
-+        OBJ_NAME_remove(onp->name, onp->type);
-+}
-+
-+static void name_funcs_free(NAME_FUNCS *ptr)
-+{
-+    OPENSSL_free(ptr);
-+}
-+
-+void OBJ_NAME_cleanup(int type)
-+{
-+    unsigned long down_load;
-+
-+    if (names_lh == NULL)
-+        return;
-+
-+    free_type = type;
-+    down_load = lh_OBJ_NAME_get_down_load(names_lh);
-+    lh_OBJ_NAME_set_down_load(names_lh, 0);
-+
-+    lh_OBJ_NAME_doall(names_lh, names_lh_free_doall);
-+    if (type < 0) {
-+        lh_OBJ_NAME_free(names_lh);
-+        sk_NAME_FUNCS_pop_free(name_funcs_stack, name_funcs_free);
-+        names_lh = NULL;
-+        name_funcs_stack = NULL;
-+    } else
-+        lh_OBJ_NAME_set_down_load(names_lh, down_load);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.c
-new file mode 100644
-index 0000000..259851b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.c
-@@ -0,0 +1,728 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/objects.h"
-+#include 
-+#include "internal/asn1_int.h"
-+#include "obj_lcl.h"
-+
-+/* obj_dat.h is generated from objects.h by obj_dat.pl */
-+#include "obj_dat.h"
-+
-+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
-+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
-+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
-+
-+#define ADDED_DATA      0
-+#define ADDED_SNAME     1
-+#define ADDED_LNAME     2
-+#define ADDED_NID       3
-+
-+struct added_obj_st {
-+    int type;
-+    ASN1_OBJECT *obj;
-+};
-+
-+static int new_nid = NUM_NID;
-+static LHASH_OF(ADDED_OBJ) *added = NULL;
-+
-+static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
-+{
-+    return (strcmp((*a)->sn, nid_objs[*b].sn));
-+}
-+
-+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
-+
-+static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
-+{
-+    return (strcmp((*a)->ln, nid_objs[*b].ln));
-+}
-+
-+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
-+
-+static unsigned long added_obj_hash(const ADDED_OBJ *ca)
-+{
-+    const ASN1_OBJECT *a;
-+    int i;
-+    unsigned long ret = 0;
-+    unsigned char *p;
-+
-+    a = ca->obj;
-+    switch (ca->type) {
-+    case ADDED_DATA:
-+        ret = a->length << 20L;
-+        p = (unsigned char *)a->data;
-+        for (i = 0; i < a->length; i++)
-+            ret ^= p[i] << ((i * 3) % 24);
-+        break;
-+    case ADDED_SNAME:
-+        ret = OPENSSL_LH_strhash(a->sn);
-+        break;
-+    case ADDED_LNAME:
-+        ret = OPENSSL_LH_strhash(a->ln);
-+        break;
-+    case ADDED_NID:
-+        ret = a->nid;
-+        break;
-+    default:
-+        /* abort(); */
-+        return 0;
-+    }
-+    ret &= 0x3fffffffL;
-+    ret |= ((unsigned long)ca->type) << 30L;
-+    return (ret);
-+}
-+
-+static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
-+{
-+    ASN1_OBJECT *a, *b;
-+    int i;
-+
-+    i = ca->type - cb->type;
-+    if (i)
-+        return (i);
-+    a = ca->obj;
-+    b = cb->obj;
-+    switch (ca->type) {
-+    case ADDED_DATA:
-+        i = (a->length - b->length);
-+        if (i)
-+            return (i);
-+        return (memcmp(a->data, b->data, (size_t)a->length));
-+    case ADDED_SNAME:
-+        if (a->sn == NULL)
-+            return (-1);
-+        else if (b->sn == NULL)
-+            return (1);
-+        else
-+            return (strcmp(a->sn, b->sn));
-+    case ADDED_LNAME:
-+        if (a->ln == NULL)
-+            return (-1);
-+        else if (b->ln == NULL)
-+            return (1);
-+        else
-+            return (strcmp(a->ln, b->ln));
-+    case ADDED_NID:
-+        return (a->nid - b->nid);
-+    default:
-+        /* abort(); */
-+        return 0;
-+    }
-+}
-+
-+static int init_added(void)
-+{
-+    if (added != NULL)
-+        return (1);
-+    added = lh_ADDED_OBJ_new(added_obj_hash, added_obj_cmp);
-+    return (added != NULL);
-+}
-+
-+static void cleanup1_doall(ADDED_OBJ *a)
-+{
-+    a->obj->nid = 0;
-+    a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC |
-+        ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA;
-+}
-+
-+static void cleanup2_doall(ADDED_OBJ *a)
-+{
-+    a->obj->nid++;
-+}
-+
-+static void cleanup3_doall(ADDED_OBJ *a)
-+{
-+    if (--a->obj->nid == 0)
-+        ASN1_OBJECT_free(a->obj);
-+    OPENSSL_free(a);
-+}
-+
-+void obj_cleanup_int(void)
-+{
-+    if (added == NULL)
-+        return;
-+    lh_ADDED_OBJ_set_down_load(added, 0);
-+    lh_ADDED_OBJ_doall(added, cleanup1_doall); /* zero counters */
-+    lh_ADDED_OBJ_doall(added, cleanup2_doall); /* set counters */
-+    lh_ADDED_OBJ_doall(added, cleanup3_doall); /* free objects */
-+    lh_ADDED_OBJ_free(added);
-+    added = NULL;
-+}
-+
-+int OBJ_new_nid(int num)
-+{
-+    int i;
-+
-+    i = new_nid;
-+    new_nid += num;
-+    return (i);
-+}
-+
-+int OBJ_add_object(const ASN1_OBJECT *obj)
-+{
-+    ASN1_OBJECT *o;
-+    ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop;
-+    int i;
-+
-+    if (added == NULL)
-+        if (!init_added())
-+            return (0);
-+    if ((o = OBJ_dup(obj)) == NULL)
-+        goto err;
-+    if ((ao[ADDED_NID] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
-+        goto err2;
-+    if ((o->length != 0) && (obj->data != NULL))
-+        if ((ao[ADDED_DATA] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
-+            goto err2;
-+    if (o->sn != NULL)
-+        if ((ao[ADDED_SNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
-+            goto err2;
-+    if (o->ln != NULL)
-+        if ((ao[ADDED_LNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
-+            goto err2;
-+
-+    for (i = ADDED_DATA; i <= ADDED_NID; i++) {
-+        if (ao[i] != NULL) {
-+            ao[i]->type = i;
-+            ao[i]->obj = o;
-+            aop = lh_ADDED_OBJ_insert(added, ao[i]);
-+            /* memory leak, but should not normally matter */
-+            OPENSSL_free(aop);
-+        }
-+    }
-+    o->flags &=
-+        ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
-+          ASN1_OBJECT_FLAG_DYNAMIC_DATA);
-+
-+    return (o->nid);
-+ err2:
-+    OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE);
-+ err:
-+    for (i = ADDED_DATA; i <= ADDED_NID; i++)
-+        OPENSSL_free(ao[i]);
-+    OPENSSL_free(o);
-+    return (NID_undef);
-+}
-+
-+ASN1_OBJECT *OBJ_nid2obj(int n)
-+{
-+    ADDED_OBJ ad, *adp;
-+    ASN1_OBJECT ob;
-+
-+    if ((n >= 0) && (n < NUM_NID)) {
-+        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
-+            OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
-+            return (NULL);
-+        }
-+        return ((ASN1_OBJECT *)&(nid_objs[n]));
-+    } else if (added == NULL)
-+        return (NULL);
-+    else {
-+        ad.type = ADDED_NID;
-+        ad.obj = &ob;
-+        ob.nid = n;
-+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
-+        if (adp != NULL)
-+            return (adp->obj);
-+        else {
-+            OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
-+            return (NULL);
-+        }
-+    }
-+}
-+
-+const char *OBJ_nid2sn(int n)
-+{
-+    ADDED_OBJ ad, *adp;
-+    ASN1_OBJECT ob;
-+
-+    if ((n >= 0) && (n < NUM_NID)) {
-+        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
-+            OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
-+            return (NULL);
-+        }
-+        return (nid_objs[n].sn);
-+    } else if (added == NULL)
-+        return (NULL);
-+    else {
-+        ad.type = ADDED_NID;
-+        ad.obj = &ob;
-+        ob.nid = n;
-+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
-+        if (adp != NULL)
-+            return (adp->obj->sn);
-+        else {
-+            OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
-+            return (NULL);
-+        }
-+    }
-+}
-+
-+const char *OBJ_nid2ln(int n)
-+{
-+    ADDED_OBJ ad, *adp;
-+    ASN1_OBJECT ob;
-+
-+    if ((n >= 0) && (n < NUM_NID)) {
-+        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
-+            OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
-+            return (NULL);
-+        }
-+        return (nid_objs[n].ln);
-+    } else if (added == NULL)
-+        return (NULL);
-+    else {
-+        ad.type = ADDED_NID;
-+        ad.obj = &ob;
-+        ob.nid = n;
-+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
-+        if (adp != NULL)
-+            return (adp->obj->ln);
-+        else {
-+            OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
-+            return (NULL);
-+        }
-+    }
-+}
-+
-+static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp)
-+{
-+    int j;
-+    const ASN1_OBJECT *a = *ap;
-+    const ASN1_OBJECT *b = &nid_objs[*bp];
-+
-+    j = (a->length - b->length);
-+    if (j)
-+        return (j);
-+    if (a->length == 0)
-+        return 0;
-+    return (memcmp(a->data, b->data, a->length));
-+}
-+
-+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
-+
-+int OBJ_obj2nid(const ASN1_OBJECT *a)
-+{
-+    const unsigned int *op;
-+    ADDED_OBJ ad, *adp;
-+
-+    if (a == NULL)
-+        return (NID_undef);
-+    if (a->nid != 0)
-+        return (a->nid);
-+
-+    if (a->length == 0)
-+        return NID_undef;
-+
-+    if (added != NULL) {
-+        ad.type = ADDED_DATA;
-+        ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */
-+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
-+        if (adp != NULL)
-+            return (adp->obj->nid);
-+    }
-+    op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
-+    if (op == NULL)
-+        return (NID_undef);
-+    return (nid_objs[*op].nid);
-+}
-+
-+/*
-+ * Convert an object name into an ASN1_OBJECT if "noname" is not set then
-+ * search for short and long names first. This will convert the "dotted" form
-+ * into an object: unlike OBJ_txt2nid it can be used with any objects, not
-+ * just registered ones.
-+ */
-+
-+ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
-+{
-+    int nid = NID_undef;
-+    ASN1_OBJECT *op = NULL;
-+    unsigned char *buf;
-+    unsigned char *p;
-+    const unsigned char *cp;
-+    int i, j;
-+
-+    if (!no_name) {
-+        if (((nid = OBJ_sn2nid(s)) != NID_undef) ||
-+            ((nid = OBJ_ln2nid(s)) != NID_undef))
-+            return OBJ_nid2obj(nid);
-+    }
-+
-+    /* Work out size of content octets */
-+    i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
-+    if (i <= 0) {
-+        /* Don't clear the error */
-+        /*
-+         * ERR_clear_error();
-+         */
-+        return NULL;
-+    }
-+    /* Work out total size */
-+    j = ASN1_object_size(0, i, V_ASN1_OBJECT);
-+    if (j < 0)
-+        return NULL;
-+
-+    if ((buf = OPENSSL_malloc(j)) == NULL)
-+        return NULL;
-+
-+    p = buf;
-+    /* Write out tag+length */
-+    ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
-+    /* Write out contents */
-+    a2d_ASN1_OBJECT(p, i, s, -1);
-+
-+    cp = buf;
-+    op = d2i_ASN1_OBJECT(NULL, &cp, j);
-+    OPENSSL_free(buf);
-+    return op;
-+}
-+
-+int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
-+{
-+    int i, n = 0, len, nid, first, use_bn;
-+    BIGNUM *bl;
-+    unsigned long l;
-+    const unsigned char *p;
-+    char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
-+
-+    /* Ensure that, at every state, |buf| is NUL-terminated. */
-+    if (buf && buf_len > 0)
-+        buf[0] = '\0';
-+
-+    if ((a == NULL) || (a->data == NULL))
-+        return (0);
-+
-+    if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
-+        const char *s;
-+        s = OBJ_nid2ln(nid);
-+        if (s == NULL)
-+            s = OBJ_nid2sn(nid);
-+        if (s) {
-+            if (buf)
-+                OPENSSL_strlcpy(buf, s, buf_len);
-+            n = strlen(s);
-+            return n;
-+        }
-+    }
-+
-+    len = a->length;
-+    p = a->data;
-+
-+    first = 1;
-+    bl = NULL;
-+
-+    while (len > 0) {
-+        l = 0;
-+        use_bn = 0;
-+        for (;;) {
-+            unsigned char c = *p++;
-+            len--;
-+            if ((len == 0) && (c & 0x80))
-+                goto err;
-+            if (use_bn) {
-+                if (!BN_add_word(bl, c & 0x7f))
-+                    goto err;
-+            } else
-+                l |= c & 0x7f;
-+            if (!(c & 0x80))
-+                break;
-+            if (!use_bn && (l > (ULONG_MAX >> 7L))) {
-+                if (bl == NULL && (bl = BN_new()) == NULL)
-+                    goto err;
-+                if (!BN_set_word(bl, l))
-+                    goto err;
-+                use_bn = 1;
-+            }
-+            if (use_bn) {
-+                if (!BN_lshift(bl, bl, 7))
-+                    goto err;
-+            } else
-+                l <<= 7L;
-+        }
-+
-+        if (first) {
-+            first = 0;
-+            if (l >= 80) {
-+                i = 2;
-+                if (use_bn) {
-+                    if (!BN_sub_word(bl, 80))
-+                        goto err;
-+                } else
-+                    l -= 80;
-+            } else {
-+                i = (int)(l / 40);
-+                l -= (long)(i * 40);
-+            }
-+            if (buf && (buf_len > 1)) {
-+                *buf++ = i + '0';
-+                *buf = '\0';
-+                buf_len--;
-+            }
-+            n++;
-+        }
-+
-+        if (use_bn) {
-+            char *bndec;
-+            bndec = BN_bn2dec(bl);
-+            if (!bndec)
-+                goto err;
-+            i = strlen(bndec);
-+            if (buf) {
-+                if (buf_len > 1) {
-+                    *buf++ = '.';
-+                    *buf = '\0';
-+                    buf_len--;
-+                }
-+                OPENSSL_strlcpy(buf, bndec, buf_len);
-+                if (i > buf_len) {
-+                    buf += buf_len;
-+                    buf_len = 0;
-+                } else {
-+                    buf += i;
-+                    buf_len -= i;
-+                }
-+            }
-+            n++;
-+            n += i;
-+            OPENSSL_free(bndec);
-+        } else {
-+            BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l);
-+            i = strlen(tbuf);
-+            if (buf && (buf_len > 0)) {
-+                OPENSSL_strlcpy(buf, tbuf, buf_len);
-+                if (i > buf_len) {
-+                    buf += buf_len;
-+                    buf_len = 0;
-+                } else {
-+                    buf += i;
-+                    buf_len -= i;
-+                }
-+            }
-+            n += i;
-+            l = 0;
-+        }
-+    }
-+
-+    BN_free(bl);
-+    return n;
-+
-+ err:
-+    BN_free(bl);
-+    return -1;
-+}
-+
-+int OBJ_txt2nid(const char *s)
-+{
-+    ASN1_OBJECT *obj;
-+    int nid;
-+    obj = OBJ_txt2obj(s, 0);
-+    nid = OBJ_obj2nid(obj);
-+    ASN1_OBJECT_free(obj);
-+    return nid;
-+}
-+
-+int OBJ_ln2nid(const char *s)
-+{
-+    ASN1_OBJECT o;
-+    const ASN1_OBJECT *oo = &o;
-+    ADDED_OBJ ad, *adp;
-+    const unsigned int *op;
-+
-+    o.ln = s;
-+    if (added != NULL) {
-+        ad.type = ADDED_LNAME;
-+        ad.obj = &o;
-+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
-+        if (adp != NULL)
-+            return (adp->obj->nid);
-+    }
-+    op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
-+    if (op == NULL)
-+        return (NID_undef);
-+    return (nid_objs[*op].nid);
-+}
-+
-+int OBJ_sn2nid(const char *s)
-+{
-+    ASN1_OBJECT o;
-+    const ASN1_OBJECT *oo = &o;
-+    ADDED_OBJ ad, *adp;
-+    const unsigned int *op;
-+
-+    o.sn = s;
-+    if (added != NULL) {
-+        ad.type = ADDED_SNAME;
-+        ad.obj = &o;
-+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
-+        if (adp != NULL)
-+            return (adp->obj->nid);
-+    }
-+    op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
-+    if (op == NULL)
-+        return (NID_undef);
-+    return (nid_objs[*op].nid);
-+}
-+
-+const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
-+                         int (*cmp) (const void *, const void *))
-+{
-+    return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
-+}
-+
-+const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
-+                            int size,
-+                            int (*cmp) (const void *, const void *),
-+                            int flags)
-+{
-+    const char *base = base_;
-+    int l, h, i = 0, c = 0;
-+    const char *p = NULL;
-+
-+    if (num == 0)
-+        return (NULL);
-+    l = 0;
-+    h = num;
-+    while (l < h) {
-+        i = (l + h) / 2;
-+        p = &(base[i * size]);
-+        c = (*cmp) (key, p);
-+        if (c < 0)
-+            h = i;
-+        else if (c > 0)
-+            l = i + 1;
-+        else
-+            break;
-+    }
-+#ifdef CHARSET_EBCDIC
-+    /*
-+     * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
-+     * don't have perl (yet), we revert to a *LINEAR* search when the object
-+     * wasn't found in the binary search.
-+     */
-+    if (c != 0) {
-+        for (i = 0; i < num; ++i) {
-+            p = &(base[i * size]);
-+            c = (*cmp) (key, p);
-+            if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
-+                return p;
-+        }
-+    }
-+#endif
-+    if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
-+        p = NULL;
-+    else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
-+        while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0)
-+            i--;
-+        p = &(base[i * size]);
-+    }
-+    return (p);
-+}
-+
-+int OBJ_create_objects(BIO *in)
-+{
-+    char buf[512];
-+    int i, num = 0;
-+    char *o, *s, *l = NULL;
-+
-+    for (;;) {
-+        s = o = NULL;
-+        i = BIO_gets(in, buf, 512);
-+        if (i <= 0)
-+            return (num);
-+        buf[i - 1] = '\0';
-+        if (!isalnum((unsigned char)buf[0]))
-+            return (num);
-+        o = s = buf;
-+        while (isdigit((unsigned char)*s) || (*s == '.'))
-+            s++;
-+        if (*s != '\0') {
-+            *(s++) = '\0';
-+            while (isspace((unsigned char)*s))
-+                s++;
-+            if (*s == '\0')
-+                s = NULL;
-+            else {
-+                l = s;
-+                while ((*l != '\0') && !isspace((unsigned char)*l))
-+                    l++;
-+                if (*l != '\0') {
-+                    *(l++) = '\0';
-+                    while (isspace((unsigned char)*l))
-+                        l++;
-+                    if (*l == '\0')
-+                        l = NULL;
-+                } else
-+                    l = NULL;
-+            }
-+        } else
-+            s = NULL;
-+        if ((o == NULL) || (*o == '\0'))
-+            return (num);
-+        if (!OBJ_create(o, s, l))
-+            return (num);
-+        num++;
-+    }
-+    /* return(num); */
-+}
-+
-+int OBJ_create(const char *oid, const char *sn, const char *ln)
-+{
-+    ASN1_OBJECT *tmpoid = NULL;
-+    int ok = 0;
-+
-+    /* Check to see if short or long name already present */
-+    if (OBJ_sn2nid(sn) != NID_undef || OBJ_ln2nid(ln) != NID_undef) {
-+        OBJerr(OBJ_F_OBJ_CREATE, OBJ_R_OID_EXISTS);
-+        return 0;
-+    }
-+
-+    /* Convert numerical OID string to an ASN1_OBJECT structure */
-+    tmpoid = OBJ_txt2obj(oid, 1);
-+
-+    /* If NID is not NID_undef then object already exists */
-+    if (OBJ_obj2nid(tmpoid) != NID_undef) {
-+        OBJerr(OBJ_F_OBJ_CREATE, OBJ_R_OID_EXISTS);
-+        goto err;
-+    }
-+
-+    tmpoid->nid = OBJ_new_nid(1);
-+    tmpoid->sn = (char *)sn;
-+    tmpoid->ln = (char *)ln;
-+
-+    ok = OBJ_add_object(tmpoid);
-+
-+    tmpoid->sn = NULL;
-+    tmpoid->ln = NULL;
-+
-+ err:
-+    ASN1_OBJECT_free(tmpoid);
-+    return ok;
-+}
-+
-+size_t OBJ_length(const ASN1_OBJECT *obj)
-+{
-+    if (obj == NULL)
-+        return 0;
-+    return obj->length;
-+}
-+
-+const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj)
-+{
-+    if (obj == NULL)
-+        return NULL;
-+    return obj->data;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.h
-new file mode 100644
-index 0000000..e1fc64f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.h
-@@ -0,0 +1,5101 @@
-+/*
-+ * WARNING: do not edit!
-+ * Generated by crypto/objects/obj_dat.pl
-+ *
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Serialized OID's */
-+static const unsigned char so[6765] = {
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,                 /* [    0] OBJ_rsadsi */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,            /* [    6] OBJ_pkcs */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,       /* [   13] OBJ_md2 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05,       /* [   21] OBJ_md5 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04,       /* [   29] OBJ_rc4 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,  /* [   37] OBJ_rsaEncryption */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02,  /* [   46] OBJ_md2WithRSAEncryption */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,  /* [   55] OBJ_md5WithRSAEncryption */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01,  /* [   64] OBJ_pbeWithMD2AndDES_CBC */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03,  /* [   73] OBJ_pbeWithMD5AndDES_CBC */
-+    0x55,                                          /* [   82] OBJ_X500 */
-+    0x55,0x04,                                     /* [   83] OBJ_X509 */
-+    0x55,0x04,0x03,                                /* [   85] OBJ_commonName */
-+    0x55,0x04,0x06,                                /* [   88] OBJ_countryName */
-+    0x55,0x04,0x07,                                /* [   91] OBJ_localityName */
-+    0x55,0x04,0x08,                                /* [   94] OBJ_stateOrProvinceName */
-+    0x55,0x04,0x0A,                                /* [   97] OBJ_organizationName */
-+    0x55,0x04,0x0B,                                /* [  100] OBJ_organizationalUnitName */
-+    0x55,0x08,0x01,0x01,                           /* [  103] OBJ_rsa */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,       /* [  107] OBJ_pkcs7 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01,  /* [  115] OBJ_pkcs7_data */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02,  /* [  124] OBJ_pkcs7_signed */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03,  /* [  133] OBJ_pkcs7_enveloped */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04,  /* [  142] OBJ_pkcs7_signedAndEnveloped */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05,  /* [  151] OBJ_pkcs7_digest */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06,  /* [  160] OBJ_pkcs7_encrypted */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,       /* [  169] OBJ_pkcs3 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01,  /* [  177] OBJ_dhKeyAgreement */
-+    0x2B,0x0E,0x03,0x02,0x06,                      /* [  186] OBJ_des_ecb */
-+    0x2B,0x0E,0x03,0x02,0x09,                      /* [  191] OBJ_des_cfb64 */
-+    0x2B,0x0E,0x03,0x02,0x07,                      /* [  196] OBJ_des_cbc */
-+    0x2B,0x0E,0x03,0x02,0x11,                      /* [  201] OBJ_des_ede_ecb */
-+    0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02,  /* [  206] OBJ_idea_cbc */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02,       /* [  217] OBJ_rc2_cbc */
-+    0x2B,0x0E,0x03,0x02,0x12,                      /* [  225] OBJ_sha */
-+    0x2B,0x0E,0x03,0x02,0x0F,                      /* [  230] OBJ_shaWithRSAEncryption */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07,       /* [  235] OBJ_des_ede3_cbc */
-+    0x2B,0x0E,0x03,0x02,0x08,                      /* [  243] OBJ_des_ofb64 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,       /* [  248] OBJ_pkcs9 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,  /* [  256] OBJ_pkcs9_emailAddress */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02,  /* [  265] OBJ_pkcs9_unstructuredName */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03,  /* [  274] OBJ_pkcs9_contentType */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04,  /* [  283] OBJ_pkcs9_messageDigest */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05,  /* [  292] OBJ_pkcs9_signingTime */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06,  /* [  301] OBJ_pkcs9_countersignature */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07,  /* [  310] OBJ_pkcs9_challengePassword */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08,  /* [  319] OBJ_pkcs9_unstructuredAddress */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09,  /* [  328] OBJ_pkcs9_extCertAttributes */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,            /* [  337] OBJ_netscape */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,       /* [  344] OBJ_netscape_cert_extension */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,       /* [  352] OBJ_netscape_data_type */
-+    0x2B,0x0E,0x03,0x02,0x1A,                      /* [  360] OBJ_sha1 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,  /* [  365] OBJ_sha1WithRSAEncryption */
-+    0x2B,0x0E,0x03,0x02,0x0D,                      /* [  374] OBJ_dsaWithSHA */
-+    0x2B,0x0E,0x03,0x02,0x0C,                      /* [  379] OBJ_dsa_2 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B,  /* [  384] OBJ_pbeWithSHA1AndRC2_CBC */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C,  /* [  393] OBJ_id_pbkdf2 */
-+    0x2B,0x0E,0x03,0x02,0x1B,                      /* [  402] OBJ_dsaWithSHA1_2 */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,  /* [  407] OBJ_netscape_cert_type */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02,  /* [  416] OBJ_netscape_base_url */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03,  /* [  425] OBJ_netscape_revocation_url */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,  /* [  434] OBJ_netscape_ca_revocation_url */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07,  /* [  443] OBJ_netscape_renewal_url */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08,  /* [  452] OBJ_netscape_ca_policy_url */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C,  /* [  461] OBJ_netscape_ssl_server_name */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,  /* [  470] OBJ_netscape_comment */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05,  /* [  479] OBJ_netscape_cert_sequence */
-+    0x55,0x1D,                                     /* [  488] OBJ_id_ce */
-+    0x55,0x1D,0x0E,                                /* [  490] OBJ_subject_key_identifier */
-+    0x55,0x1D,0x0F,                                /* [  493] OBJ_key_usage */
-+    0x55,0x1D,0x10,                                /* [  496] OBJ_private_key_usage_period */
-+    0x55,0x1D,0x11,                                /* [  499] OBJ_subject_alt_name */
-+    0x55,0x1D,0x12,                                /* [  502] OBJ_issuer_alt_name */
-+    0x55,0x1D,0x13,                                /* [  505] OBJ_basic_constraints */
-+    0x55,0x1D,0x14,                                /* [  508] OBJ_crl_number */
-+    0x55,0x1D,0x20,                                /* [  511] OBJ_certificate_policies */
-+    0x55,0x1D,0x23,                                /* [  514] OBJ_authority_key_identifier */
-+    0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02,  /* [  517] OBJ_bf_cbc */
-+    0x55,0x08,0x03,0x65,                           /* [  526] OBJ_mdc2 */
-+    0x55,0x08,0x03,0x64,                           /* [  530] OBJ_mdc2WithRSA */
-+    0x55,0x04,0x2A,                                /* [  534] OBJ_givenName */
-+    0x55,0x04,0x04,                                /* [  537] OBJ_surname */
-+    0x55,0x04,0x2B,                                /* [  540] OBJ_initials */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2C,  /* [  543] OBJ_uniqueIdentifier */
-+    0x55,0x1D,0x1F,                                /* [  553] OBJ_crl_distribution_points */
-+    0x2B,0x0E,0x03,0x02,0x03,                      /* [  556] OBJ_md5WithRSA */
-+    0x55,0x04,0x05,                                /* [  561] OBJ_serialNumber */
-+    0x55,0x04,0x0C,                                /* [  564] OBJ_title */
-+    0x55,0x04,0x0D,                                /* [  567] OBJ_description */
-+    0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A,  /* [  570] OBJ_cast5_cbc */
-+    0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C,  /* [  579] OBJ_pbeWithMD5AndCast5_CBC */
-+    0x2A,0x86,0x48,0xCE,0x38,0x04,0x03,            /* [  588] OBJ_dsaWithSHA1 */
-+    0x2B,0x0E,0x03,0x02,0x1D,                      /* [  595] OBJ_sha1WithRSA */
-+    0x2A,0x86,0x48,0xCE,0x38,0x04,0x01,            /* [  600] OBJ_dsa */
-+    0x2B,0x24,0x03,0x02,0x01,                      /* [  607] OBJ_ripemd160 */
-+    0x2B,0x24,0x03,0x03,0x01,0x02,                 /* [  612] OBJ_ripemd160WithRSA */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08,       /* [  618] OBJ_rc5_cbc */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,  /* [  626] OBJ_zlib_compression */
-+    0x55,0x1D,0x25,                                /* [  637] OBJ_ext_key_usage */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,                 /* [  640] OBJ_id_pkix */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,            /* [  646] OBJ_id_kp */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,       /* [  653] OBJ_server_auth */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,       /* [  661] OBJ_client_auth */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,       /* [  669] OBJ_code_sign */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04,       /* [  677] OBJ_email_protect */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08,       /* [  685] OBJ_time_stamp */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,  /* [  693] OBJ_ms_code_ind */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,  /* [  703] OBJ_ms_code_com */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,  /* [  713] OBJ_ms_ctl_sign */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,  /* [  723] OBJ_ms_sgc */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,  /* [  733] OBJ_ms_efs */
-+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,  /* [  743] OBJ_ns_sgc */
-+    0x55,0x1D,0x1B,                                /* [  752] OBJ_delta_crl */
-+    0x55,0x1D,0x15,                                /* [  755] OBJ_crl_reason */
-+    0x55,0x1D,0x18,                                /* [  758] OBJ_invalidity_date */
-+    0x2B,0x65,0x01,0x04,0x01,                      /* [  761] OBJ_sxnet */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,  /* [  766] OBJ_pbe_WithSHA1And128BitRC4 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,  /* [  776] OBJ_pbe_WithSHA1And40BitRC4 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,  /* [  786] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,  /* [  796] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,  /* [  806] OBJ_pbe_WithSHA1And128BitRC2_CBC */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,  /* [  816] OBJ_pbe_WithSHA1And40BitRC2_CBC */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,  /* [  826] OBJ_keyBag */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,  /* [  837] OBJ_pkcs8ShroudedKeyBag */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,  /* [  848] OBJ_certBag */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,  /* [  859] OBJ_crlBag */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,  /* [  870] OBJ_secretBag */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,  /* [  881] OBJ_safeContentsBag */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,  /* [  892] OBJ_friendlyName */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,  /* [  901] OBJ_localKeyID */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,  /* [  910] OBJ_x509Certificate */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,  /* [  920] OBJ_sdsiCertificate */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,  /* [  930] OBJ_x509Crl */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,  /* [  940] OBJ_pbes2 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,  /* [  949] OBJ_pbmac1 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07,       /* [  958] OBJ_hmacWithSHA1 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,       /* [  966] OBJ_id_qt_cps */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,       /* [  974] OBJ_id_qt_unotice */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,  /* [  982] OBJ_SMIMECapabilities */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,  /* [  991] OBJ_pbeWithMD2AndRC2_CBC */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,  /* [ 1000] OBJ_pbeWithMD5AndRC2_CBC */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,  /* [ 1009] OBJ_pbeWithSHA1AndDES_CBC */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,  /* [ 1018] OBJ_ms_ext_req */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,  /* [ 1028] OBJ_ext_req */
-+    0x55,0x04,0x29,                                /* [ 1037] OBJ_name */
-+    0x55,0x04,0x2E,                                /* [ 1040] OBJ_dnQualifier */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,            /* [ 1043] OBJ_id_pe */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,            /* [ 1050] OBJ_id_ad */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,       /* [ 1057] OBJ_info_access */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,       /* [ 1065] OBJ_ad_OCSP */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,       /* [ 1073] OBJ_ad_ca_issuers */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,       /* [ 1081] OBJ_OCSP_sign */
-+    0x2A,                                          /* [ 1089] OBJ_member_body */
-+    0x2A,0x86,0x48,                                /* [ 1090] OBJ_ISO_US */
-+    0x2A,0x86,0x48,0xCE,0x38,                      /* [ 1093] OBJ_X9_57 */
-+    0x2A,0x86,0x48,0xCE,0x38,0x04,                 /* [ 1098] OBJ_X9cm */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,       /* [ 1104] OBJ_pkcs1 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,       /* [ 1112] OBJ_pkcs5 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,  /* [ 1120] OBJ_SMIME */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,  /* [ 1129] OBJ_id_smime_mod */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,  /* [ 1139] OBJ_id_smime_ct */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,  /* [ 1149] OBJ_id_smime_aa */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,  /* [ 1159] OBJ_id_smime_alg */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,  /* [ 1169] OBJ_id_smime_cd */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,  /* [ 1179] OBJ_id_smime_spq */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,  /* [ 1189] OBJ_id_smime_cti */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,  /* [ 1199] OBJ_id_smime_mod_cms */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,  /* [ 1210] OBJ_id_smime_mod_ess */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,  /* [ 1221] OBJ_id_smime_mod_oid */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,  /* [ 1232] OBJ_id_smime_mod_msg_v3 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,  /* [ 1243] OBJ_id_smime_mod_ets_eSignature_88 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,  /* [ 1254] OBJ_id_smime_mod_ets_eSignature_97 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,  /* [ 1265] OBJ_id_smime_mod_ets_eSigPolicy_88 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,  /* [ 1276] OBJ_id_smime_mod_ets_eSigPolicy_97 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,  /* [ 1287] OBJ_id_smime_ct_receipt */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,  /* [ 1298] OBJ_id_smime_ct_authData */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,  /* [ 1309] OBJ_id_smime_ct_publishCert */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,  /* [ 1320] OBJ_id_smime_ct_TSTInfo */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,  /* [ 1331] OBJ_id_smime_ct_TDTInfo */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,  /* [ 1342] OBJ_id_smime_ct_contentInfo */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,  /* [ 1353] OBJ_id_smime_ct_DVCSRequestData */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,  /* [ 1364] OBJ_id_smime_ct_DVCSResponseData */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,  /* [ 1375] OBJ_id_smime_aa_receiptRequest */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,  /* [ 1386] OBJ_id_smime_aa_securityLabel */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,  /* [ 1397] OBJ_id_smime_aa_mlExpandHistory */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,  /* [ 1408] OBJ_id_smime_aa_contentHint */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,  /* [ 1419] OBJ_id_smime_aa_msgSigDigest */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,  /* [ 1430] OBJ_id_smime_aa_encapContentType */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,  /* [ 1441] OBJ_id_smime_aa_contentIdentifier */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,  /* [ 1452] OBJ_id_smime_aa_macValue */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,  /* [ 1463] OBJ_id_smime_aa_equivalentLabels */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,  /* [ 1474] OBJ_id_smime_aa_contentReference */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,  /* [ 1485] OBJ_id_smime_aa_encrypKeyPref */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,  /* [ 1496] OBJ_id_smime_aa_signingCertificate */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,  /* [ 1507] OBJ_id_smime_aa_smimeEncryptCerts */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,  /* [ 1518] OBJ_id_smime_aa_timeStampToken */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,  /* [ 1529] OBJ_id_smime_aa_ets_sigPolicyId */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,  /* [ 1540] OBJ_id_smime_aa_ets_commitmentType */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,  /* [ 1551] OBJ_id_smime_aa_ets_signerLocation */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,  /* [ 1562] OBJ_id_smime_aa_ets_signerAttr */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,  /* [ 1573] OBJ_id_smime_aa_ets_otherSigCert */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,  /* [ 1584] OBJ_id_smime_aa_ets_contentTimestamp */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,  /* [ 1595] OBJ_id_smime_aa_ets_CertificateRefs */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,  /* [ 1606] OBJ_id_smime_aa_ets_RevocationRefs */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,  /* [ 1617] OBJ_id_smime_aa_ets_certValues */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,  /* [ 1628] OBJ_id_smime_aa_ets_revocationValues */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,  /* [ 1639] OBJ_id_smime_aa_ets_escTimeStamp */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,  /* [ 1650] OBJ_id_smime_aa_ets_certCRLTimestamp */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,  /* [ 1661] OBJ_id_smime_aa_ets_archiveTimeStamp */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,  /* [ 1672] OBJ_id_smime_aa_signatureType */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,  /* [ 1683] OBJ_id_smime_aa_dvcs_dvc */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,  /* [ 1694] OBJ_id_smime_alg_ESDHwith3DES */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,  /* [ 1705] OBJ_id_smime_alg_ESDHwithRC2 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,  /* [ 1716] OBJ_id_smime_alg_3DESwrap */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,  /* [ 1727] OBJ_id_smime_alg_RC2wrap */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,  /* [ 1738] OBJ_id_smime_alg_ESDH */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,  /* [ 1749] OBJ_id_smime_alg_CMS3DESwrap */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,  /* [ 1760] OBJ_id_smime_alg_CMSRC2wrap */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,  /* [ 1771] OBJ_id_smime_cd_ldap */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,  /* [ 1782] OBJ_id_smime_spq_ets_sqt_uri */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,  /* [ 1793] OBJ_id_smime_spq_ets_sqt_unotice */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,  /* [ 1804] OBJ_id_smime_cti_ets_proofOfOrigin */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,  /* [ 1815] OBJ_id_smime_cti_ets_proofOfReceipt */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,  /* [ 1826] OBJ_id_smime_cti_ets_proofOfDelivery */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,  /* [ 1837] OBJ_id_smime_cti_ets_proofOfSender */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,  /* [ 1848] OBJ_id_smime_cti_ets_proofOfApproval */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,  /* [ 1859] OBJ_id_smime_cti_ets_proofOfCreation */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04,       /* [ 1870] OBJ_md4 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,            /* [ 1878] OBJ_id_pkix_mod */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x02,            /* [ 1885] OBJ_id_qt */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,            /* [ 1892] OBJ_id_it */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,            /* [ 1899] OBJ_id_pkip */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x06,            /* [ 1906] OBJ_id_alg */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,            /* [ 1913] OBJ_id_cmc */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x08,            /* [ 1920] OBJ_id_on */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,            /* [ 1927] OBJ_id_pda */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,            /* [ 1934] OBJ_id_aca */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,            /* [ 1941] OBJ_id_qcs */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,            /* [ 1948] OBJ_id_cct */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01,       /* [ 1955] OBJ_id_pkix1_explicit_88 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02,       /* [ 1963] OBJ_id_pkix1_implicit_88 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03,       /* [ 1971] OBJ_id_pkix1_explicit_93 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04,       /* [ 1979] OBJ_id_pkix1_implicit_93 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05,       /* [ 1987] OBJ_id_mod_crmf */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06,       /* [ 1995] OBJ_id_mod_cmc */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07,       /* [ 2003] OBJ_id_mod_kea_profile_88 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08,       /* [ 2011] OBJ_id_mod_kea_profile_93 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09,       /* [ 2019] OBJ_id_mod_cmp */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A,       /* [ 2027] OBJ_id_mod_qualified_cert_88 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B,       /* [ 2035] OBJ_id_mod_qualified_cert_93 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C,       /* [ 2043] OBJ_id_mod_attribute_cert */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D,       /* [ 2051] OBJ_id_mod_timestamp_protocol */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E,       /* [ 2059] OBJ_id_mod_ocsp */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F,       /* [ 2067] OBJ_id_mod_dvcs */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10,       /* [ 2075] OBJ_id_mod_cmp2000 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02,       /* [ 2083] OBJ_biometricInfo */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03,       /* [ 2091] OBJ_qcStatements */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04,       /* [ 2099] OBJ_ac_auditEntity */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05,       /* [ 2107] OBJ_ac_targeting */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06,       /* [ 2115] OBJ_aaControls */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07,       /* [ 2123] OBJ_sbgp_ipAddrBlock */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08,       /* [ 2131] OBJ_sbgp_autonomousSysNum */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09,       /* [ 2139] OBJ_sbgp_routerIdentifier */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03,       /* [ 2147] OBJ_textNotice */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05,       /* [ 2155] OBJ_ipsecEndSystem */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06,       /* [ 2163] OBJ_ipsecTunnel */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,       /* [ 2171] OBJ_ipsecUser */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A,       /* [ 2179] OBJ_dvcs */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01,       /* [ 2187] OBJ_id_it_caProtEncCert */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02,       /* [ 2195] OBJ_id_it_signKeyPairTypes */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03,       /* [ 2203] OBJ_id_it_encKeyPairTypes */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04,       /* [ 2211] OBJ_id_it_preferredSymmAlg */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05,       /* [ 2219] OBJ_id_it_caKeyUpdateInfo */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06,       /* [ 2227] OBJ_id_it_currentCRL */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07,       /* [ 2235] OBJ_id_it_unsupportedOIDs */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08,       /* [ 2243] OBJ_id_it_subscriptionRequest */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09,       /* [ 2251] OBJ_id_it_subscriptionResponse */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A,       /* [ 2259] OBJ_id_it_keyPairParamReq */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B,       /* [ 2267] OBJ_id_it_keyPairParamRep */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C,       /* [ 2275] OBJ_id_it_revPassphrase */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D,       /* [ 2283] OBJ_id_it_implicitConfirm */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E,       /* [ 2291] OBJ_id_it_confirmWaitTime */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F,       /* [ 2299] OBJ_id_it_origPKIMessage */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,       /* [ 2307] OBJ_id_regCtrl */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,       /* [ 2315] OBJ_id_regInfo */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,  /* [ 2323] OBJ_id_regCtrl_regToken */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,  /* [ 2332] OBJ_id_regCtrl_authenticator */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,  /* [ 2341] OBJ_id_regCtrl_pkiPublicationInfo */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,  /* [ 2350] OBJ_id_regCtrl_pkiArchiveOptions */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,  /* [ 2359] OBJ_id_regCtrl_oldCertID */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,  /* [ 2368] OBJ_id_regCtrl_protocolEncrKey */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,  /* [ 2377] OBJ_id_regInfo_utf8Pairs */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,  /* [ 2386] OBJ_id_regInfo_certReq */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01,       /* [ 2395] OBJ_id_alg_des40 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02,       /* [ 2403] OBJ_id_alg_noSignature */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03,       /* [ 2411] OBJ_id_alg_dh_sig_hmac_sha1 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04,       /* [ 2419] OBJ_id_alg_dh_pop */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01,       /* [ 2427] OBJ_id_cmc_statusInfo */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02,       /* [ 2435] OBJ_id_cmc_identification */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03,       /* [ 2443] OBJ_id_cmc_identityProof */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04,       /* [ 2451] OBJ_id_cmc_dataReturn */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05,       /* [ 2459] OBJ_id_cmc_transactionId */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06,       /* [ 2467] OBJ_id_cmc_senderNonce */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07,       /* [ 2475] OBJ_id_cmc_recipientNonce */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08,       /* [ 2483] OBJ_id_cmc_addExtensions */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09,       /* [ 2491] OBJ_id_cmc_encryptedPOP */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A,       /* [ 2499] OBJ_id_cmc_decryptedPOP */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B,       /* [ 2507] OBJ_id_cmc_lraPOPWitness */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F,       /* [ 2515] OBJ_id_cmc_getCert */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10,       /* [ 2523] OBJ_id_cmc_getCRL */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11,       /* [ 2531] OBJ_id_cmc_revokeRequest */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12,       /* [ 2539] OBJ_id_cmc_regInfo */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13,       /* [ 2547] OBJ_id_cmc_responseInfo */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15,       /* [ 2555] OBJ_id_cmc_queryPending */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16,       /* [ 2563] OBJ_id_cmc_popLinkRandom */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17,       /* [ 2571] OBJ_id_cmc_popLinkWitness */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18,       /* [ 2579] OBJ_id_cmc_confirmCertAcceptance */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01,       /* [ 2587] OBJ_id_on_personalData */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01,       /* [ 2595] OBJ_id_pda_dateOfBirth */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02,       /* [ 2603] OBJ_id_pda_placeOfBirth */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03,       /* [ 2611] OBJ_id_pda_gender */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04,       /* [ 2619] OBJ_id_pda_countryOfCitizenship */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05,       /* [ 2627] OBJ_id_pda_countryOfResidence */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01,       /* [ 2635] OBJ_id_aca_authenticationInfo */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02,       /* [ 2643] OBJ_id_aca_accessIdentity */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03,       /* [ 2651] OBJ_id_aca_chargingIdentity */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04,       /* [ 2659] OBJ_id_aca_group */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05,       /* [ 2667] OBJ_id_aca_role */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01,       /* [ 2675] OBJ_id_qcs_pkixQCSyntax_v1 */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01,       /* [ 2683] OBJ_id_cct_crs */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02,       /* [ 2691] OBJ_id_cct_PKIData */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03,       /* [ 2699] OBJ_id_cct_PKIResponse */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03,       /* [ 2707] OBJ_ad_timeStamping */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04,       /* [ 2715] OBJ_ad_dvcs */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,  /* [ 2723] OBJ_id_pkix_OCSP_basic */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,  /* [ 2732] OBJ_id_pkix_OCSP_Nonce */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,  /* [ 2741] OBJ_id_pkix_OCSP_CrlID */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,  /* [ 2750] OBJ_id_pkix_OCSP_acceptableResponses */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,  /* [ 2759] OBJ_id_pkix_OCSP_noCheck */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,  /* [ 2768] OBJ_id_pkix_OCSP_archiveCutoff */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,  /* [ 2777] OBJ_id_pkix_OCSP_serviceLocator */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,  /* [ 2786] OBJ_id_pkix_OCSP_extendedStatus */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,  /* [ 2795] OBJ_id_pkix_OCSP_valid */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,  /* [ 2804] OBJ_id_pkix_OCSP_path */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,  /* [ 2813] OBJ_id_pkix_OCSP_trustRoot */
-+    0x2B,0x0E,0x03,0x02,                           /* [ 2822] OBJ_algorithm */
-+    0x2B,0x0E,0x03,0x02,0x0B,                      /* [ 2826] OBJ_rsaSignature */
-+    0x55,0x08,                                     /* [ 2831] OBJ_X500algorithms */
-+    0x2B,                                          /* [ 2833] OBJ_org */
-+    0x2B,0x06,                                     /* [ 2834] OBJ_dod */
-+    0x2B,0x06,0x01,                                /* [ 2836] OBJ_iana */
-+    0x2B,0x06,0x01,0x01,                           /* [ 2839] OBJ_Directory */
-+    0x2B,0x06,0x01,0x02,                           /* [ 2843] OBJ_Management */
-+    0x2B,0x06,0x01,0x03,                           /* [ 2847] OBJ_Experimental */
-+    0x2B,0x06,0x01,0x04,                           /* [ 2851] OBJ_Private */
-+    0x2B,0x06,0x01,0x05,                           /* [ 2855] OBJ_Security */
-+    0x2B,0x06,0x01,0x06,                           /* [ 2859] OBJ_SNMPv2 */
-+    0x2B,0x06,0x01,0x07,                           /* [ 2863] OBJ_Mail */
-+    0x2B,0x06,0x01,0x04,0x01,                      /* [ 2867] OBJ_Enterprises */
-+    0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,  /* [ 2872] OBJ_dcObject */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,  /* [ 2881] OBJ_domainComponent */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,  /* [ 2891] OBJ_Domain */
-+    0x55,0x01,0x05,                                /* [ 2901] OBJ_selected_attribute_types */
-+    0x55,0x01,0x05,0x37,                           /* [ 2904] OBJ_clearance */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,  /* [ 2908] OBJ_md4WithRSAEncryption */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A,       /* [ 2917] OBJ_ac_proxying */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B,       /* [ 2925] OBJ_sinfo_access */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06,       /* [ 2933] OBJ_id_aca_encAttrs */
-+    0x55,0x04,0x48,                                /* [ 2941] OBJ_role */
-+    0x55,0x1D,0x24,                                /* [ 2944] OBJ_policy_constraints */
-+    0x55,0x1D,0x37,                                /* [ 2947] OBJ_target_information */
-+    0x55,0x1D,0x38,                                /* [ 2950] OBJ_no_rev_avail */
-+    0x2A,0x86,0x48,0xCE,0x3D,                      /* [ 2953] OBJ_ansi_X9_62 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01,            /* [ 2958] OBJ_X9_62_prime_field */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,            /* [ 2965] OBJ_X9_62_characteristic_two_field */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,            /* [ 2972] OBJ_X9_62_id_ecPublicKey */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,       /* [ 2979] OBJ_X9_62_prime192v1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02,       /* [ 2987] OBJ_X9_62_prime192v2 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03,       /* [ 2995] OBJ_X9_62_prime192v3 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04,       /* [ 3003] OBJ_X9_62_prime239v1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05,       /* [ 3011] OBJ_X9_62_prime239v2 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06,       /* [ 3019] OBJ_X9_62_prime239v3 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,       /* [ 3027] OBJ_X9_62_prime256v1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,            /* [ 3035] OBJ_ecdsa_with_SHA1 */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,  /* [ 3042] OBJ_ms_csp_name */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,  /* [ 3051] OBJ_aes_128_ecb */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,  /* [ 3060] OBJ_aes_128_cbc */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,  /* [ 3069] OBJ_aes_128_ofb128 */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,  /* [ 3078] OBJ_aes_128_cfb128 */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,  /* [ 3087] OBJ_aes_192_ecb */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,  /* [ 3096] OBJ_aes_192_cbc */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,  /* [ 3105] OBJ_aes_192_ofb128 */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,  /* [ 3114] OBJ_aes_192_cfb128 */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,  /* [ 3123] OBJ_aes_256_ecb */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,  /* [ 3132] OBJ_aes_256_cbc */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,  /* [ 3141] OBJ_aes_256_ofb128 */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,  /* [ 3150] OBJ_aes_256_cfb128 */
-+    0x55,0x1D,0x17,                                /* [ 3159] OBJ_hold_instruction_code */
-+    0x2A,0x86,0x48,0xCE,0x38,0x02,0x01,            /* [ 3162] OBJ_hold_instruction_none */
-+    0x2A,0x86,0x48,0xCE,0x38,0x02,0x02,            /* [ 3169] OBJ_hold_instruction_call_issuer */
-+    0x2A,0x86,0x48,0xCE,0x38,0x02,0x03,            /* [ 3176] OBJ_hold_instruction_reject */
-+    0x09,                                          /* [ 3183] OBJ_data */
-+    0x09,0x92,0x26,                                /* [ 3184] OBJ_pss */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,            /* [ 3187] OBJ_ucl */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,       /* [ 3194] OBJ_pilot */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,  /* [ 3202] OBJ_pilotAttributeType */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,  /* [ 3211] OBJ_pilotAttributeSyntax */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,  /* [ 3220] OBJ_pilotObjectClass */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,  /* [ 3229] OBJ_pilotGroups */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,  /* [ 3238] OBJ_iA5StringSyntax */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,  /* [ 3248] OBJ_caseIgnoreIA5StringSyntax */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,  /* [ 3258] OBJ_pilotObject */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,  /* [ 3268] OBJ_pilotPerson */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,  /* [ 3278] OBJ_account */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,  /* [ 3288] OBJ_document */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,  /* [ 3298] OBJ_room */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,  /* [ 3308] OBJ_documentSeries */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,  /* [ 3318] OBJ_rFC822localPart */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,  /* [ 3328] OBJ_dNSDomain */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,  /* [ 3338] OBJ_domainRelatedObject */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,  /* [ 3348] OBJ_friendlyCountry */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,  /* [ 3358] OBJ_simpleSecurityObject */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,  /* [ 3368] OBJ_pilotOrganization */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,  /* [ 3378] OBJ_pilotDSA */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,  /* [ 3388] OBJ_qualityLabelledData */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,  /* [ 3398] OBJ_userId */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,  /* [ 3408] OBJ_textEncodedORAddress */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,  /* [ 3418] OBJ_rfc822Mailbox */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,  /* [ 3428] OBJ_info */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,  /* [ 3438] OBJ_favouriteDrink */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,  /* [ 3448] OBJ_roomNumber */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,  /* [ 3458] OBJ_photo */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,  /* [ 3468] OBJ_userClass */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,  /* [ 3478] OBJ_host */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,  /* [ 3488] OBJ_manager */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,  /* [ 3498] OBJ_documentIdentifier */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,  /* [ 3508] OBJ_documentTitle */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,  /* [ 3518] OBJ_documentVersion */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,  /* [ 3528] OBJ_documentAuthor */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,  /* [ 3538] OBJ_documentLocation */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,  /* [ 3548] OBJ_homeTelephoneNumber */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,  /* [ 3558] OBJ_secretary */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,  /* [ 3568] OBJ_otherMailbox */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,  /* [ 3578] OBJ_lastModifiedTime */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,  /* [ 3588] OBJ_lastModifiedBy */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,  /* [ 3598] OBJ_aRecord */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,  /* [ 3608] OBJ_pilotAttributeType27 */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,  /* [ 3618] OBJ_mXRecord */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,  /* [ 3628] OBJ_nSRecord */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,  /* [ 3638] OBJ_sOARecord */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,  /* [ 3648] OBJ_cNAMERecord */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,  /* [ 3658] OBJ_associatedDomain */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,  /* [ 3668] OBJ_associatedName */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,  /* [ 3678] OBJ_homePostalAddress */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,  /* [ 3688] OBJ_personalTitle */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,  /* [ 3698] OBJ_mobileTelephoneNumber */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,  /* [ 3708] OBJ_pagerTelephoneNumber */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,  /* [ 3718] OBJ_friendlyCountryName */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,  /* [ 3728] OBJ_organizationalStatus */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,  /* [ 3738] OBJ_janetMailbox */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,  /* [ 3748] OBJ_mailPreferenceOption */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,  /* [ 3758] OBJ_buildingName */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,  /* [ 3768] OBJ_dSAQuality */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,  /* [ 3778] OBJ_singleLevelQuality */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,  /* [ 3788] OBJ_subtreeMinimumQuality */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,  /* [ 3798] OBJ_subtreeMaximumQuality */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,  /* [ 3808] OBJ_personalSignature */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,  /* [ 3818] OBJ_dITRedirect */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,  /* [ 3828] OBJ_audio */
-+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,  /* [ 3838] OBJ_documentPublisher */
-+    0x55,0x04,0x2D,                                /* [ 3848] OBJ_x500UniqueIdentifier */
-+    0x2B,0x06,0x01,0x07,0x01,                      /* [ 3851] OBJ_mime_mhs */
-+    0x2B,0x06,0x01,0x07,0x01,0x01,                 /* [ 3856] OBJ_mime_mhs_headings */
-+    0x2B,0x06,0x01,0x07,0x01,0x02,                 /* [ 3862] OBJ_mime_mhs_bodies */
-+    0x2B,0x06,0x01,0x07,0x01,0x01,0x01,            /* [ 3868] OBJ_id_hex_partial_message */
-+    0x2B,0x06,0x01,0x07,0x01,0x01,0x02,            /* [ 3875] OBJ_id_hex_multipart_message */
-+    0x55,0x04,0x2C,                                /* [ 3882] OBJ_generationQualifier */
-+    0x55,0x04,0x41,                                /* [ 3885] OBJ_pseudonym */
-+    0x67,0x2A,                                     /* [ 3888] OBJ_id_set */
-+    0x67,0x2A,0x00,                                /* [ 3890] OBJ_set_ctype */
-+    0x67,0x2A,0x01,                                /* [ 3893] OBJ_set_msgExt */
-+    0x67,0x2A,0x03,                                /* [ 3896] OBJ_set_attr */
-+    0x67,0x2A,0x05,                                /* [ 3899] OBJ_set_policy */
-+    0x67,0x2A,0x07,                                /* [ 3902] OBJ_set_certExt */
-+    0x67,0x2A,0x08,                                /* [ 3905] OBJ_set_brand */
-+    0x67,0x2A,0x00,0x00,                           /* [ 3908] OBJ_setct_PANData */
-+    0x67,0x2A,0x00,0x01,                           /* [ 3912] OBJ_setct_PANToken */
-+    0x67,0x2A,0x00,0x02,                           /* [ 3916] OBJ_setct_PANOnly */
-+    0x67,0x2A,0x00,0x03,                           /* [ 3920] OBJ_setct_OIData */
-+    0x67,0x2A,0x00,0x04,                           /* [ 3924] OBJ_setct_PI */
-+    0x67,0x2A,0x00,0x05,                           /* [ 3928] OBJ_setct_PIData */
-+    0x67,0x2A,0x00,0x06,                           /* [ 3932] OBJ_setct_PIDataUnsigned */
-+    0x67,0x2A,0x00,0x07,                           /* [ 3936] OBJ_setct_HODInput */
-+    0x67,0x2A,0x00,0x08,                           /* [ 3940] OBJ_setct_AuthResBaggage */
-+    0x67,0x2A,0x00,0x09,                           /* [ 3944] OBJ_setct_AuthRevReqBaggage */
-+    0x67,0x2A,0x00,0x0A,                           /* [ 3948] OBJ_setct_AuthRevResBaggage */
-+    0x67,0x2A,0x00,0x0B,                           /* [ 3952] OBJ_setct_CapTokenSeq */
-+    0x67,0x2A,0x00,0x0C,                           /* [ 3956] OBJ_setct_PInitResData */
-+    0x67,0x2A,0x00,0x0D,                           /* [ 3960] OBJ_setct_PI_TBS */
-+    0x67,0x2A,0x00,0x0E,                           /* [ 3964] OBJ_setct_PResData */
-+    0x67,0x2A,0x00,0x10,                           /* [ 3968] OBJ_setct_AuthReqTBS */
-+    0x67,0x2A,0x00,0x11,                           /* [ 3972] OBJ_setct_AuthResTBS */
-+    0x67,0x2A,0x00,0x12,                           /* [ 3976] OBJ_setct_AuthResTBSX */
-+    0x67,0x2A,0x00,0x13,                           /* [ 3980] OBJ_setct_AuthTokenTBS */
-+    0x67,0x2A,0x00,0x14,                           /* [ 3984] OBJ_setct_CapTokenData */
-+    0x67,0x2A,0x00,0x15,                           /* [ 3988] OBJ_setct_CapTokenTBS */
-+    0x67,0x2A,0x00,0x16,                           /* [ 3992] OBJ_setct_AcqCardCodeMsg */
-+    0x67,0x2A,0x00,0x17,                           /* [ 3996] OBJ_setct_AuthRevReqTBS */
-+    0x67,0x2A,0x00,0x18,                           /* [ 4000] OBJ_setct_AuthRevResData */
-+    0x67,0x2A,0x00,0x19,                           /* [ 4004] OBJ_setct_AuthRevResTBS */
-+    0x67,0x2A,0x00,0x1A,                           /* [ 4008] OBJ_setct_CapReqTBS */
-+    0x67,0x2A,0x00,0x1B,                           /* [ 4012] OBJ_setct_CapReqTBSX */
-+    0x67,0x2A,0x00,0x1C,                           /* [ 4016] OBJ_setct_CapResData */
-+    0x67,0x2A,0x00,0x1D,                           /* [ 4020] OBJ_setct_CapRevReqTBS */
-+    0x67,0x2A,0x00,0x1E,                           /* [ 4024] OBJ_setct_CapRevReqTBSX */
-+    0x67,0x2A,0x00,0x1F,                           /* [ 4028] OBJ_setct_CapRevResData */
-+    0x67,0x2A,0x00,0x20,                           /* [ 4032] OBJ_setct_CredReqTBS */
-+    0x67,0x2A,0x00,0x21,                           /* [ 4036] OBJ_setct_CredReqTBSX */
-+    0x67,0x2A,0x00,0x22,                           /* [ 4040] OBJ_setct_CredResData */
-+    0x67,0x2A,0x00,0x23,                           /* [ 4044] OBJ_setct_CredRevReqTBS */
-+    0x67,0x2A,0x00,0x24,                           /* [ 4048] OBJ_setct_CredRevReqTBSX */
-+    0x67,0x2A,0x00,0x25,                           /* [ 4052] OBJ_setct_CredRevResData */
-+    0x67,0x2A,0x00,0x26,                           /* [ 4056] OBJ_setct_PCertReqData */
-+    0x67,0x2A,0x00,0x27,                           /* [ 4060] OBJ_setct_PCertResTBS */
-+    0x67,0x2A,0x00,0x28,                           /* [ 4064] OBJ_setct_BatchAdminReqData */
-+    0x67,0x2A,0x00,0x29,                           /* [ 4068] OBJ_setct_BatchAdminResData */
-+    0x67,0x2A,0x00,0x2A,                           /* [ 4072] OBJ_setct_CardCInitResTBS */
-+    0x67,0x2A,0x00,0x2B,                           /* [ 4076] OBJ_setct_MeAqCInitResTBS */
-+    0x67,0x2A,0x00,0x2C,                           /* [ 4080] OBJ_setct_RegFormResTBS */
-+    0x67,0x2A,0x00,0x2D,                           /* [ 4084] OBJ_setct_CertReqData */
-+    0x67,0x2A,0x00,0x2E,                           /* [ 4088] OBJ_setct_CertReqTBS */
-+    0x67,0x2A,0x00,0x2F,                           /* [ 4092] OBJ_setct_CertResData */
-+    0x67,0x2A,0x00,0x30,                           /* [ 4096] OBJ_setct_CertInqReqTBS */
-+    0x67,0x2A,0x00,0x31,                           /* [ 4100] OBJ_setct_ErrorTBS */
-+    0x67,0x2A,0x00,0x32,                           /* [ 4104] OBJ_setct_PIDualSignedTBE */
-+    0x67,0x2A,0x00,0x33,                           /* [ 4108] OBJ_setct_PIUnsignedTBE */
-+    0x67,0x2A,0x00,0x34,                           /* [ 4112] OBJ_setct_AuthReqTBE */
-+    0x67,0x2A,0x00,0x35,                           /* [ 4116] OBJ_setct_AuthResTBE */
-+    0x67,0x2A,0x00,0x36,                           /* [ 4120] OBJ_setct_AuthResTBEX */
-+    0x67,0x2A,0x00,0x37,                           /* [ 4124] OBJ_setct_AuthTokenTBE */
-+    0x67,0x2A,0x00,0x38,                           /* [ 4128] OBJ_setct_CapTokenTBE */
-+    0x67,0x2A,0x00,0x39,                           /* [ 4132] OBJ_setct_CapTokenTBEX */
-+    0x67,0x2A,0x00,0x3A,                           /* [ 4136] OBJ_setct_AcqCardCodeMsgTBE */
-+    0x67,0x2A,0x00,0x3B,                           /* [ 4140] OBJ_setct_AuthRevReqTBE */
-+    0x67,0x2A,0x00,0x3C,                           /* [ 4144] OBJ_setct_AuthRevResTBE */
-+    0x67,0x2A,0x00,0x3D,                           /* [ 4148] OBJ_setct_AuthRevResTBEB */
-+    0x67,0x2A,0x00,0x3E,                           /* [ 4152] OBJ_setct_CapReqTBE */
-+    0x67,0x2A,0x00,0x3F,                           /* [ 4156] OBJ_setct_CapReqTBEX */
-+    0x67,0x2A,0x00,0x40,                           /* [ 4160] OBJ_setct_CapResTBE */
-+    0x67,0x2A,0x00,0x41,                           /* [ 4164] OBJ_setct_CapRevReqTBE */
-+    0x67,0x2A,0x00,0x42,                           /* [ 4168] OBJ_setct_CapRevReqTBEX */
-+    0x67,0x2A,0x00,0x43,                           /* [ 4172] OBJ_setct_CapRevResTBE */
-+    0x67,0x2A,0x00,0x44,                           /* [ 4176] OBJ_setct_CredReqTBE */
-+    0x67,0x2A,0x00,0x45,                           /* [ 4180] OBJ_setct_CredReqTBEX */
-+    0x67,0x2A,0x00,0x46,                           /* [ 4184] OBJ_setct_CredResTBE */
-+    0x67,0x2A,0x00,0x47,                           /* [ 4188] OBJ_setct_CredRevReqTBE */
-+    0x67,0x2A,0x00,0x48,                           /* [ 4192] OBJ_setct_CredRevReqTBEX */
-+    0x67,0x2A,0x00,0x49,                           /* [ 4196] OBJ_setct_CredRevResTBE */
-+    0x67,0x2A,0x00,0x4A,                           /* [ 4200] OBJ_setct_BatchAdminReqTBE */
-+    0x67,0x2A,0x00,0x4B,                           /* [ 4204] OBJ_setct_BatchAdminResTBE */
-+    0x67,0x2A,0x00,0x4C,                           /* [ 4208] OBJ_setct_RegFormReqTBE */
-+    0x67,0x2A,0x00,0x4D,                           /* [ 4212] OBJ_setct_CertReqTBE */
-+    0x67,0x2A,0x00,0x4E,                           /* [ 4216] OBJ_setct_CertReqTBEX */
-+    0x67,0x2A,0x00,0x4F,                           /* [ 4220] OBJ_setct_CertResTBE */
-+    0x67,0x2A,0x00,0x50,                           /* [ 4224] OBJ_setct_CRLNotificationTBS */
-+    0x67,0x2A,0x00,0x51,                           /* [ 4228] OBJ_setct_CRLNotificationResTBS */
-+    0x67,0x2A,0x00,0x52,                           /* [ 4232] OBJ_setct_BCIDistributionTBS */
-+    0x67,0x2A,0x01,0x01,                           /* [ 4236] OBJ_setext_genCrypt */
-+    0x67,0x2A,0x01,0x03,                           /* [ 4240] OBJ_setext_miAuth */
-+    0x67,0x2A,0x01,0x04,                           /* [ 4244] OBJ_setext_pinSecure */
-+    0x67,0x2A,0x01,0x05,                           /* [ 4248] OBJ_setext_pinAny */
-+    0x67,0x2A,0x01,0x07,                           /* [ 4252] OBJ_setext_track2 */
-+    0x67,0x2A,0x01,0x08,                           /* [ 4256] OBJ_setext_cv */
-+    0x67,0x2A,0x05,0x00,                           /* [ 4260] OBJ_set_policy_root */
-+    0x67,0x2A,0x07,0x00,                           /* [ 4264] OBJ_setCext_hashedRoot */
-+    0x67,0x2A,0x07,0x01,                           /* [ 4268] OBJ_setCext_certType */
-+    0x67,0x2A,0x07,0x02,                           /* [ 4272] OBJ_setCext_merchData */
-+    0x67,0x2A,0x07,0x03,                           /* [ 4276] OBJ_setCext_cCertRequired */
-+    0x67,0x2A,0x07,0x04,                           /* [ 4280] OBJ_setCext_tunneling */
-+    0x67,0x2A,0x07,0x05,                           /* [ 4284] OBJ_setCext_setExt */
-+    0x67,0x2A,0x07,0x06,                           /* [ 4288] OBJ_setCext_setQualf */
-+    0x67,0x2A,0x07,0x07,                           /* [ 4292] OBJ_setCext_PGWYcapabilities */
-+    0x67,0x2A,0x07,0x08,                           /* [ 4296] OBJ_setCext_TokenIdentifier */
-+    0x67,0x2A,0x07,0x09,                           /* [ 4300] OBJ_setCext_Track2Data */
-+    0x67,0x2A,0x07,0x0A,                           /* [ 4304] OBJ_setCext_TokenType */
-+    0x67,0x2A,0x07,0x0B,                           /* [ 4308] OBJ_setCext_IssuerCapabilities */
-+    0x67,0x2A,0x03,0x00,                           /* [ 4312] OBJ_setAttr_Cert */
-+    0x67,0x2A,0x03,0x01,                           /* [ 4316] OBJ_setAttr_PGWYcap */
-+    0x67,0x2A,0x03,0x02,                           /* [ 4320] OBJ_setAttr_TokenType */
-+    0x67,0x2A,0x03,0x03,                           /* [ 4324] OBJ_setAttr_IssCap */
-+    0x67,0x2A,0x03,0x00,0x00,                      /* [ 4328] OBJ_set_rootKeyThumb */
-+    0x67,0x2A,0x03,0x00,0x01,                      /* [ 4333] OBJ_set_addPolicy */
-+    0x67,0x2A,0x03,0x02,0x01,                      /* [ 4338] OBJ_setAttr_Token_EMV */
-+    0x67,0x2A,0x03,0x02,0x02,                      /* [ 4343] OBJ_setAttr_Token_B0Prime */
-+    0x67,0x2A,0x03,0x03,0x03,                      /* [ 4348] OBJ_setAttr_IssCap_CVM */
-+    0x67,0x2A,0x03,0x03,0x04,                      /* [ 4353] OBJ_setAttr_IssCap_T2 */
-+    0x67,0x2A,0x03,0x03,0x05,                      /* [ 4358] OBJ_setAttr_IssCap_Sig */
-+    0x67,0x2A,0x03,0x03,0x03,0x01,                 /* [ 4363] OBJ_setAttr_GenCryptgrm */
-+    0x67,0x2A,0x03,0x03,0x04,0x01,                 /* [ 4369] OBJ_setAttr_T2Enc */
-+    0x67,0x2A,0x03,0x03,0x04,0x02,                 /* [ 4375] OBJ_setAttr_T2cleartxt */
-+    0x67,0x2A,0x03,0x03,0x05,0x01,                 /* [ 4381] OBJ_setAttr_TokICCsig */
-+    0x67,0x2A,0x03,0x03,0x05,0x02,                 /* [ 4387] OBJ_setAttr_SecDevSig */
-+    0x67,0x2A,0x08,0x01,                           /* [ 4393] OBJ_set_brand_IATA_ATA */
-+    0x67,0x2A,0x08,0x1E,                           /* [ 4397] OBJ_set_brand_Diners */
-+    0x67,0x2A,0x08,0x22,                           /* [ 4401] OBJ_set_brand_AmericanExpress */
-+    0x67,0x2A,0x08,0x23,                           /* [ 4405] OBJ_set_brand_JCB */
-+    0x67,0x2A,0x08,0x04,                           /* [ 4409] OBJ_set_brand_Visa */
-+    0x67,0x2A,0x08,0x05,                           /* [ 4413] OBJ_set_brand_MasterCard */
-+    0x67,0x2A,0x08,0xAE,0x7B,                      /* [ 4417] OBJ_set_brand_Novus */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A,       /* [ 4422] OBJ_des_cdmf */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,  /* [ 4430] OBJ_rsaOAEPEncryptionSET */
-+    0x67,                                          /* [ 4439] OBJ_international_organizations */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,  /* [ 4440] OBJ_ms_smartcard_login */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,  /* [ 4450] OBJ_ms_upn */
-+    0x55,0x04,0x09,                                /* [ 4460] OBJ_streetAddress */
-+    0x55,0x04,0x11,                                /* [ 4463] OBJ_postalCode */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x15,            /* [ 4466] OBJ_id_ppl */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E,       /* [ 4473] OBJ_proxyCertInfo */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00,       /* [ 4481] OBJ_id_ppl_anyLanguage */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01,       /* [ 4489] OBJ_id_ppl_inheritAll */
-+    0x55,0x1D,0x1E,                                /* [ 4497] OBJ_name_constraints */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02,       /* [ 4500] OBJ_Independent */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,  /* [ 4508] OBJ_sha256WithRSAEncryption */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,  /* [ 4517] OBJ_sha384WithRSAEncryption */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,  /* [ 4526] OBJ_sha512WithRSAEncryption */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,  /* [ 4535] OBJ_sha224WithRSAEncryption */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,  /* [ 4544] OBJ_sha256 */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,  /* [ 4553] OBJ_sha384 */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,  /* [ 4562] OBJ_sha512 */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,  /* [ 4571] OBJ_sha224 */
-+    0x2B,                                          /* [ 4580] OBJ_identified_organization */
-+    0x2B,0x81,0x04,                                /* [ 4581] OBJ_certicom_arc */
-+    0x67,0x2B,                                     /* [ 4584] OBJ_wap */
-+    0x67,0x2B,0x01,                                /* [ 4586] OBJ_wap_wsg */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,       /* [ 4589] OBJ_X9_62_id_characteristic_two_basis */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,  /* [ 4597] OBJ_X9_62_onBasis */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,  /* [ 4606] OBJ_X9_62_tpBasis */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,  /* [ 4615] OBJ_X9_62_ppBasis */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01,       /* [ 4624] OBJ_X9_62_c2pnb163v1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02,       /* [ 4632] OBJ_X9_62_c2pnb163v2 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03,       /* [ 4640] OBJ_X9_62_c2pnb163v3 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04,       /* [ 4648] OBJ_X9_62_c2pnb176v1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05,       /* [ 4656] OBJ_X9_62_c2tnb191v1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06,       /* [ 4664] OBJ_X9_62_c2tnb191v2 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07,       /* [ 4672] OBJ_X9_62_c2tnb191v3 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08,       /* [ 4680] OBJ_X9_62_c2onb191v4 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09,       /* [ 4688] OBJ_X9_62_c2onb191v5 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A,       /* [ 4696] OBJ_X9_62_c2pnb208w1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B,       /* [ 4704] OBJ_X9_62_c2tnb239v1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C,       /* [ 4712] OBJ_X9_62_c2tnb239v2 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D,       /* [ 4720] OBJ_X9_62_c2tnb239v3 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E,       /* [ 4728] OBJ_X9_62_c2onb239v4 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F,       /* [ 4736] OBJ_X9_62_c2onb239v5 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10,       /* [ 4744] OBJ_X9_62_c2pnb272w1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11,       /* [ 4752] OBJ_X9_62_c2pnb304w1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12,       /* [ 4760] OBJ_X9_62_c2tnb359v1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13,       /* [ 4768] OBJ_X9_62_c2pnb368w1 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14,       /* [ 4776] OBJ_X9_62_c2tnb431r1 */
-+    0x2B,0x81,0x04,0x00,0x06,                      /* [ 4784] OBJ_secp112r1 */
-+    0x2B,0x81,0x04,0x00,0x07,                      /* [ 4789] OBJ_secp112r2 */
-+    0x2B,0x81,0x04,0x00,0x1C,                      /* [ 4794] OBJ_secp128r1 */
-+    0x2B,0x81,0x04,0x00,0x1D,                      /* [ 4799] OBJ_secp128r2 */
-+    0x2B,0x81,0x04,0x00,0x09,                      /* [ 4804] OBJ_secp160k1 */
-+    0x2B,0x81,0x04,0x00,0x08,                      /* [ 4809] OBJ_secp160r1 */
-+    0x2B,0x81,0x04,0x00,0x1E,                      /* [ 4814] OBJ_secp160r2 */
-+    0x2B,0x81,0x04,0x00,0x1F,                      /* [ 4819] OBJ_secp192k1 */
-+    0x2B,0x81,0x04,0x00,0x20,                      /* [ 4824] OBJ_secp224k1 */
-+    0x2B,0x81,0x04,0x00,0x21,                      /* [ 4829] OBJ_secp224r1 */
-+    0x2B,0x81,0x04,0x00,0x0A,                      /* [ 4834] OBJ_secp256k1 */
-+    0x2B,0x81,0x04,0x00,0x22,                      /* [ 4839] OBJ_secp384r1 */
-+    0x2B,0x81,0x04,0x00,0x23,                      /* [ 4844] OBJ_secp521r1 */
-+    0x2B,0x81,0x04,0x00,0x04,                      /* [ 4849] OBJ_sect113r1 */
-+    0x2B,0x81,0x04,0x00,0x05,                      /* [ 4854] OBJ_sect113r2 */
-+    0x2B,0x81,0x04,0x00,0x16,                      /* [ 4859] OBJ_sect131r1 */
-+    0x2B,0x81,0x04,0x00,0x17,                      /* [ 4864] OBJ_sect131r2 */
-+    0x2B,0x81,0x04,0x00,0x01,                      /* [ 4869] OBJ_sect163k1 */
-+    0x2B,0x81,0x04,0x00,0x02,                      /* [ 4874] OBJ_sect163r1 */
-+    0x2B,0x81,0x04,0x00,0x0F,                      /* [ 4879] OBJ_sect163r2 */
-+    0x2B,0x81,0x04,0x00,0x18,                      /* [ 4884] OBJ_sect193r1 */
-+    0x2B,0x81,0x04,0x00,0x19,                      /* [ 4889] OBJ_sect193r2 */
-+    0x2B,0x81,0x04,0x00,0x1A,                      /* [ 4894] OBJ_sect233k1 */
-+    0x2B,0x81,0x04,0x00,0x1B,                      /* [ 4899] OBJ_sect233r1 */
-+    0x2B,0x81,0x04,0x00,0x03,                      /* [ 4904] OBJ_sect239k1 */
-+    0x2B,0x81,0x04,0x00,0x10,                      /* [ 4909] OBJ_sect283k1 */
-+    0x2B,0x81,0x04,0x00,0x11,                      /* [ 4914] OBJ_sect283r1 */
-+    0x2B,0x81,0x04,0x00,0x24,                      /* [ 4919] OBJ_sect409k1 */
-+    0x2B,0x81,0x04,0x00,0x25,                      /* [ 4924] OBJ_sect409r1 */
-+    0x2B,0x81,0x04,0x00,0x26,                      /* [ 4929] OBJ_sect571k1 */
-+    0x2B,0x81,0x04,0x00,0x27,                      /* [ 4934] OBJ_sect571r1 */
-+    0x67,0x2B,0x01,0x04,0x01,                      /* [ 4939] OBJ_wap_wsg_idm_ecid_wtls1 */
-+    0x67,0x2B,0x01,0x04,0x03,                      /* [ 4944] OBJ_wap_wsg_idm_ecid_wtls3 */
-+    0x67,0x2B,0x01,0x04,0x04,                      /* [ 4949] OBJ_wap_wsg_idm_ecid_wtls4 */
-+    0x67,0x2B,0x01,0x04,0x05,                      /* [ 4954] OBJ_wap_wsg_idm_ecid_wtls5 */
-+    0x67,0x2B,0x01,0x04,0x06,                      /* [ 4959] OBJ_wap_wsg_idm_ecid_wtls6 */
-+    0x67,0x2B,0x01,0x04,0x07,                      /* [ 4964] OBJ_wap_wsg_idm_ecid_wtls7 */
-+    0x67,0x2B,0x01,0x04,0x08,                      /* [ 4969] OBJ_wap_wsg_idm_ecid_wtls8 */
-+    0x67,0x2B,0x01,0x04,0x09,                      /* [ 4974] OBJ_wap_wsg_idm_ecid_wtls9 */
-+    0x67,0x2B,0x01,0x04,0x0A,                      /* [ 4979] OBJ_wap_wsg_idm_ecid_wtls10 */
-+    0x67,0x2B,0x01,0x04,0x0B,                      /* [ 4984] OBJ_wap_wsg_idm_ecid_wtls11 */
-+    0x67,0x2B,0x01,0x04,0x0C,                      /* [ 4989] OBJ_wap_wsg_idm_ecid_wtls12 */
-+    0x55,0x1D,0x20,0x00,                           /* [ 4994] OBJ_any_policy */
-+    0x55,0x1D,0x21,                                /* [ 4998] OBJ_policy_mappings */
-+    0x55,0x1D,0x36,                                /* [ 5001] OBJ_inhibit_any_policy */
-+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,  /* [ 5004] OBJ_camellia_128_cbc */
-+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,  /* [ 5015] OBJ_camellia_192_cbc */
-+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,  /* [ 5026] OBJ_camellia_256_cbc */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01,       /* [ 5037] OBJ_camellia_128_ecb */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15,       /* [ 5045] OBJ_camellia_192_ecb */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29,       /* [ 5053] OBJ_camellia_256_ecb */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04,       /* [ 5061] OBJ_camellia_128_cfb128 */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18,       /* [ 5069] OBJ_camellia_192_cfb128 */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C,       /* [ 5077] OBJ_camellia_256_cfb128 */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03,       /* [ 5085] OBJ_camellia_128_ofb128 */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17,       /* [ 5093] OBJ_camellia_192_ofb128 */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B,       /* [ 5101] OBJ_camellia_256_ofb128 */
-+    0x55,0x1D,0x09,                                /* [ 5109] OBJ_subject_directory_attributes */
-+    0x55,0x1D,0x1C,                                /* [ 5112] OBJ_issuing_distribution_point */
-+    0x55,0x1D,0x1D,                                /* [ 5115] OBJ_certificate_issuer */
-+    0x2A,0x83,0x1A,0x8C,0x9A,0x44,                 /* [ 5118] OBJ_kisa */
-+    0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03,       /* [ 5124] OBJ_seed_ecb */
-+    0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04,       /* [ 5132] OBJ_seed_cbc */
-+    0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06,       /* [ 5140] OBJ_seed_ofb128 */
-+    0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05,       /* [ 5148] OBJ_seed_cfb128 */
-+    0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01,       /* [ 5156] OBJ_hmac_md5 */
-+    0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02,       /* [ 5164] OBJ_hmac_sha1 */
-+    0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,  /* [ 5172] OBJ_id_PasswordBasedMAC */
-+    0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,  /* [ 5181] OBJ_id_DHBasedMac */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10,       /* [ 5190] OBJ_id_it_suppLangTags */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05,       /* [ 5198] OBJ_caRepository */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,  /* [ 5206] OBJ_id_smime_ct_compressedData */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,  /* [ 5217] OBJ_id_ct_asciiTextWithCRLF */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,  /* [ 5228] OBJ_id_aes128_wrap */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,  /* [ 5237] OBJ_id_aes192_wrap */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,  /* [ 5246] OBJ_id_aes256_wrap */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02,            /* [ 5255] OBJ_ecdsa_with_Recommended */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,            /* [ 5262] OBJ_ecdsa_with_Specified */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01,       /* [ 5269] OBJ_ecdsa_with_SHA224 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,       /* [ 5277] OBJ_ecdsa_with_SHA256 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,       /* [ 5285] OBJ_ecdsa_with_SHA384 */
-+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,       /* [ 5293] OBJ_ecdsa_with_SHA512 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06,       /* [ 5301] OBJ_hmacWithMD5 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08,       /* [ 5309] OBJ_hmacWithSHA224 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09,       /* [ 5317] OBJ_hmacWithSHA256 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A,       /* [ 5325] OBJ_hmacWithSHA384 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B,       /* [ 5333] OBJ_hmacWithSHA512 */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,  /* [ 5341] OBJ_dsa_with_SHA224 */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,  /* [ 5350] OBJ_dsa_with_SHA256 */
-+    0x28,0xCF,0x06,0x03,0x00,0x37,                 /* [ 5359] OBJ_whirlpool */
-+    0x2A,0x85,0x03,0x02,0x02,                      /* [ 5365] OBJ_cryptopro */
-+    0x2A,0x85,0x03,0x02,0x09,                      /* [ 5370] OBJ_cryptocom */
-+    0x2A,0x85,0x03,0x02,0x02,0x03,                 /* [ 5375] OBJ_id_GostR3411_94_with_GostR3410_2001 */
-+    0x2A,0x85,0x03,0x02,0x02,0x04,                 /* [ 5381] OBJ_id_GostR3411_94_with_GostR3410_94 */
-+    0x2A,0x85,0x03,0x02,0x02,0x09,                 /* [ 5387] OBJ_id_GostR3411_94 */
-+    0x2A,0x85,0x03,0x02,0x02,0x0A,                 /* [ 5393] OBJ_id_HMACGostR3411_94 */
-+    0x2A,0x85,0x03,0x02,0x02,0x13,                 /* [ 5399] OBJ_id_GostR3410_2001 */
-+    0x2A,0x85,0x03,0x02,0x02,0x14,                 /* [ 5405] OBJ_id_GostR3410_94 */
-+    0x2A,0x85,0x03,0x02,0x02,0x15,                 /* [ 5411] OBJ_id_Gost28147_89 */
-+    0x2A,0x85,0x03,0x02,0x02,0x16,                 /* [ 5417] OBJ_id_Gost28147_89_MAC */
-+    0x2A,0x85,0x03,0x02,0x02,0x17,                 /* [ 5423] OBJ_id_GostR3411_94_prf */
-+    0x2A,0x85,0x03,0x02,0x02,0x62,                 /* [ 5429] OBJ_id_GostR3410_2001DH */
-+    0x2A,0x85,0x03,0x02,0x02,0x63,                 /* [ 5435] OBJ_id_GostR3410_94DH */
-+    0x2A,0x85,0x03,0x02,0x02,0x0E,0x01,            /* [ 5441] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */
-+    0x2A,0x85,0x03,0x02,0x02,0x0E,0x00,            /* [ 5448] OBJ_id_Gost28147_89_None_KeyMeshing */
-+    0x2A,0x85,0x03,0x02,0x02,0x1E,0x00,            /* [ 5455] OBJ_id_GostR3411_94_TestParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x1E,0x01,            /* [ 5462] OBJ_id_GostR3411_94_CryptoProParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x00,            /* [ 5469] OBJ_id_Gost28147_89_TestParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x01,            /* [ 5476] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x02,            /* [ 5483] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x03,            /* [ 5490] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x04,            /* [ 5497] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x05,            /* [ 5504] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x06,            /* [ 5511] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x07,            /* [ 5518] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x20,0x00,            /* [ 5525] OBJ_id_GostR3410_94_TestParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x20,0x02,            /* [ 5532] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x20,0x03,            /* [ 5539] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x20,0x04,            /* [ 5546] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x20,0x05,            /* [ 5553] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x21,0x01,            /* [ 5560] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x21,0x02,            /* [ 5567] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x21,0x03,            /* [ 5574] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x23,0x00,            /* [ 5581] OBJ_id_GostR3410_2001_TestParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x23,0x01,            /* [ 5588] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x23,0x02,            /* [ 5595] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x23,0x03,            /* [ 5602] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x24,0x00,            /* [ 5609] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x24,0x01,            /* [ 5616] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */
-+    0x2A,0x85,0x03,0x02,0x02,0x14,0x01,            /* [ 5623] OBJ_id_GostR3410_94_a */
-+    0x2A,0x85,0x03,0x02,0x02,0x14,0x02,            /* [ 5630] OBJ_id_GostR3410_94_aBis */
-+    0x2A,0x85,0x03,0x02,0x02,0x14,0x03,            /* [ 5637] OBJ_id_GostR3410_94_b */
-+    0x2A,0x85,0x03,0x02,0x02,0x14,0x04,            /* [ 5644] OBJ_id_GostR3410_94_bBis */
-+    0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01,       /* [ 5651] OBJ_id_Gost28147_89_cc */
-+    0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03,       /* [ 5659] OBJ_id_GostR3410_94_cc */
-+    0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04,       /* [ 5667] OBJ_id_GostR3410_2001_cc */
-+    0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03,       /* [ 5675] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
-+    0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04,       /* [ 5683] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
-+    0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01,       /* [ 5691] OBJ_id_GostR3410_2001_ParamSet_cc */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,  /* [ 5699] OBJ_LocalKeySet */
-+    0x55,0x1D,0x2E,                                /* [ 5708] OBJ_freshest_crl */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03,       /* [ 5711] OBJ_id_on_permanentIdentifier */
-+    0x55,0x04,0x0E,                                /* [ 5719] OBJ_searchGuide */
-+    0x55,0x04,0x0F,                                /* [ 5722] OBJ_businessCategory */
-+    0x55,0x04,0x10,                                /* [ 5725] OBJ_postalAddress */
-+    0x55,0x04,0x12,                                /* [ 5728] OBJ_postOfficeBox */
-+    0x55,0x04,0x13,                                /* [ 5731] OBJ_physicalDeliveryOfficeName */
-+    0x55,0x04,0x14,                                /* [ 5734] OBJ_telephoneNumber */
-+    0x55,0x04,0x15,                                /* [ 5737] OBJ_telexNumber */
-+    0x55,0x04,0x16,                                /* [ 5740] OBJ_teletexTerminalIdentifier */
-+    0x55,0x04,0x17,                                /* [ 5743] OBJ_facsimileTelephoneNumber */
-+    0x55,0x04,0x18,                                /* [ 5746] OBJ_x121Address */
-+    0x55,0x04,0x19,                                /* [ 5749] OBJ_internationaliSDNNumber */
-+    0x55,0x04,0x1A,                                /* [ 5752] OBJ_registeredAddress */
-+    0x55,0x04,0x1B,                                /* [ 5755] OBJ_destinationIndicator */
-+    0x55,0x04,0x1C,                                /* [ 5758] OBJ_preferredDeliveryMethod */
-+    0x55,0x04,0x1D,                                /* [ 5761] OBJ_presentationAddress */
-+    0x55,0x04,0x1E,                                /* [ 5764] OBJ_supportedApplicationContext */
-+    0x55,0x04,0x1F,                                /* [ 5767] OBJ_member */
-+    0x55,0x04,0x20,                                /* [ 5770] OBJ_owner */
-+    0x55,0x04,0x21,                                /* [ 5773] OBJ_roleOccupant */
-+    0x55,0x04,0x22,                                /* [ 5776] OBJ_seeAlso */
-+    0x55,0x04,0x23,                                /* [ 5779] OBJ_userPassword */
-+    0x55,0x04,0x24,                                /* [ 5782] OBJ_userCertificate */
-+    0x55,0x04,0x25,                                /* [ 5785] OBJ_cACertificate */
-+    0x55,0x04,0x26,                                /* [ 5788] OBJ_authorityRevocationList */
-+    0x55,0x04,0x27,                                /* [ 5791] OBJ_certificateRevocationList */
-+    0x55,0x04,0x28,                                /* [ 5794] OBJ_crossCertificatePair */
-+    0x55,0x04,0x2F,                                /* [ 5797] OBJ_enhancedSearchGuide */
-+    0x55,0x04,0x30,                                /* [ 5800] OBJ_protocolInformation */
-+    0x55,0x04,0x31,                                /* [ 5803] OBJ_distinguishedName */
-+    0x55,0x04,0x32,                                /* [ 5806] OBJ_uniqueMember */
-+    0x55,0x04,0x33,                                /* [ 5809] OBJ_houseIdentifier */
-+    0x55,0x04,0x34,                                /* [ 5812] OBJ_supportedAlgorithms */
-+    0x55,0x04,0x35,                                /* [ 5815] OBJ_deltaRevocationList */
-+    0x55,0x04,0x36,                                /* [ 5818] OBJ_dmdName */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,  /* [ 5821] OBJ_id_alg_PWRI_KEK */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,  /* [ 5832] OBJ_aes_128_gcm */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,  /* [ 5841] OBJ_aes_128_ccm */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,  /* [ 5850] OBJ_id_aes128_wrap_pad */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,  /* [ 5859] OBJ_aes_192_gcm */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,  /* [ 5868] OBJ_aes_192_ccm */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,  /* [ 5877] OBJ_id_aes192_wrap_pad */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,  /* [ 5886] OBJ_aes_256_gcm */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,  /* [ 5895] OBJ_aes_256_ccm */
-+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,  /* [ 5904] OBJ_id_aes256_wrap_pad */
-+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,  /* [ 5913] OBJ_id_camellia128_wrap */
-+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,  /* [ 5924] OBJ_id_camellia192_wrap */
-+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,  /* [ 5935] OBJ_id_camellia256_wrap */
-+    0x55,0x1D,0x25,0x00,                           /* [ 5946] OBJ_anyExtendedKeyUsage */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,  /* [ 5950] OBJ_mgf1 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,  /* [ 5959] OBJ_rsassaPss */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,  /* [ 5968] OBJ_rsaesOaep */
-+    0x2A,0x86,0x48,0xCE,0x3E,0x02,0x01,            /* [ 5977] OBJ_dhpublicnumber */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01,  /* [ 5984] OBJ_brainpoolP160r1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x02,  /* [ 5993] OBJ_brainpoolP160t1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03,  /* [ 6002] OBJ_brainpoolP192r1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x04,  /* [ 6011] OBJ_brainpoolP192t1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05,  /* [ 6020] OBJ_brainpoolP224r1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x06,  /* [ 6029] OBJ_brainpoolP224t1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07,  /* [ 6038] OBJ_brainpoolP256r1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08,  /* [ 6047] OBJ_brainpoolP256t1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09,  /* [ 6056] OBJ_brainpoolP320r1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0A,  /* [ 6065] OBJ_brainpoolP320t1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B,  /* [ 6074] OBJ_brainpoolP384r1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0C,  /* [ 6083] OBJ_brainpoolP384t1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D,  /* [ 6092] OBJ_brainpoolP512r1 */
-+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0E,  /* [ 6101] OBJ_brainpoolP512t1 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x09,  /* [ 6110] OBJ_pSpecified */
-+    0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x02,  /* [ 6119] OBJ_dhSinglePass_stdDH_sha1kdf_scheme */
-+    0x2B,0x81,0x04,0x01,0x0B,0x00,                 /* [ 6128] OBJ_dhSinglePass_stdDH_sha224kdf_scheme */
-+    0x2B,0x81,0x04,0x01,0x0B,0x01,                 /* [ 6134] OBJ_dhSinglePass_stdDH_sha256kdf_scheme */
-+    0x2B,0x81,0x04,0x01,0x0B,0x02,                 /* [ 6140] OBJ_dhSinglePass_stdDH_sha384kdf_scheme */
-+    0x2B,0x81,0x04,0x01,0x0B,0x03,                 /* [ 6146] OBJ_dhSinglePass_stdDH_sha512kdf_scheme */
-+    0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x03,  /* [ 6152] OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme */
-+    0x2B,0x81,0x04,0x01,0x0E,0x00,                 /* [ 6161] OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme */
-+    0x2B,0x81,0x04,0x01,0x0E,0x01,                 /* [ 6167] OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme */
-+    0x2B,0x81,0x04,0x01,0x0E,0x02,                 /* [ 6173] OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme */
-+    0x2B,0x81,0x04,0x01,0x0E,0x03,                 /* [ 6179] OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme */
-+    0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,  /* [ 6185] OBJ_ct_precert_scts */
-+    0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x03,  /* [ 6195] OBJ_ct_precert_poison */
-+    0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x04,  /* [ 6205] OBJ_ct_precert_signer */
-+    0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x05,  /* [ 6215] OBJ_ct_cert_scts */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,  /* [ 6225] OBJ_jurisdictionLocalityName */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,  /* [ 6236] OBJ_jurisdictionStateOrProvinceName */
-+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,  /* [ 6247] OBJ_jurisdictionCountryName */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x06,       /* [ 6258] OBJ_camellia_128_gcm */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x07,       /* [ 6266] OBJ_camellia_128_ccm */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x09,       /* [ 6274] OBJ_camellia_128_ctr */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x0A,       /* [ 6282] OBJ_camellia_128_cmac */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1A,       /* [ 6290] OBJ_camellia_192_gcm */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1B,       /* [ 6298] OBJ_camellia_192_ccm */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1D,       /* [ 6306] OBJ_camellia_192_ctr */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1E,       /* [ 6314] OBJ_camellia_192_cmac */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2E,       /* [ 6322] OBJ_camellia_256_gcm */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2F,       /* [ 6330] OBJ_camellia_256_ccm */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x31,       /* [ 6338] OBJ_camellia_256_ctr */
-+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x32,       /* [ 6346] OBJ_camellia_256_cmac */
-+    0x2B,0x06,0x01,0x04,0x01,0xDA,0x47,0x04,0x0B,  /* [ 6354] OBJ_id_scrypt */
-+    0x2A,0x85,0x03,0x07,0x01,                      /* [ 6363] OBJ_id_tc26 */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,                 /* [ 6368] OBJ_id_tc26_algorithms */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x01,            /* [ 6374] OBJ_id_tc26_sign */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x01,0x01,       /* [ 6381] OBJ_id_GostR3410_2012_256 */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x01,0x02,       /* [ 6389] OBJ_id_GostR3410_2012_512 */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x02,            /* [ 6397] OBJ_id_tc26_digest */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x02,0x02,       /* [ 6404] OBJ_id_GostR3411_2012_256 */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x02,0x03,       /* [ 6412] OBJ_id_GostR3411_2012_512 */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x03,            /* [ 6420] OBJ_id_tc26_signwithdigest */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x03,0x02,       /* [ 6427] OBJ_id_tc26_signwithdigest_gost3410_2012_256 */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x03,0x03,       /* [ 6435] OBJ_id_tc26_signwithdigest_gost3410_2012_512 */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x04,            /* [ 6443] OBJ_id_tc26_mac */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x04,0x01,       /* [ 6450] OBJ_id_tc26_hmac_gost_3411_2012_256 */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x04,0x02,       /* [ 6458] OBJ_id_tc26_hmac_gost_3411_2012_512 */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x05,            /* [ 6466] OBJ_id_tc26_cipher */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x06,            /* [ 6473] OBJ_id_tc26_agreement */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x06,0x01,       /* [ 6480] OBJ_id_tc26_agreement_gost_3410_2012_256 */
-+    0x2A,0x85,0x03,0x07,0x01,0x01,0x06,0x02,       /* [ 6488] OBJ_id_tc26_agreement_gost_3410_2012_512 */
-+    0x2A,0x85,0x03,0x07,0x01,0x02,                 /* [ 6496] OBJ_id_tc26_constants */
-+    0x2A,0x85,0x03,0x07,0x01,0x02,0x01,            /* [ 6502] OBJ_id_tc26_sign_constants */
-+    0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,       /* [ 6509] OBJ_id_tc26_gost_3410_2012_512_constants */
-+    0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x00,  /* [ 6517] OBJ_id_tc26_gost_3410_2012_512_paramSetTest */
-+    0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x01,  /* [ 6526] OBJ_id_tc26_gost_3410_2012_512_paramSetA */
-+    0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x02,  /* [ 6535] OBJ_id_tc26_gost_3410_2012_512_paramSetB */
-+    0x2A,0x85,0x03,0x07,0x01,0x02,0x02,            /* [ 6544] OBJ_id_tc26_digest_constants */
-+    0x2A,0x85,0x03,0x07,0x01,0x02,0x05,            /* [ 6551] OBJ_id_tc26_cipher_constants */
-+    0x2A,0x85,0x03,0x07,0x01,0x02,0x05,0x01,       /* [ 6558] OBJ_id_tc26_gost_28147_constants */
-+    0x2A,0x85,0x03,0x07,0x01,0x02,0x05,0x01,0x01,  /* [ 6566] OBJ_id_tc26_gost_28147_param_Z */
-+    0x2A,0x85,0x03,0x03,0x81,0x03,0x01,0x01,       /* [ 6575] OBJ_INN */
-+    0x2A,0x85,0x03,0x64,0x01,                      /* [ 6583] OBJ_OGRN */
-+    0x2A,0x85,0x03,0x64,0x03,                      /* [ 6588] OBJ_SNILS */
-+    0x2A,0x85,0x03,0x64,0x6F,                      /* [ 6593] OBJ_subjectSignTool */
-+    0x2A,0x85,0x03,0x64,0x70,                      /* [ 6598] OBJ_issuerSignTool */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x18,       /* [ 6603] OBJ_tlsfeature */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x11,       /* [ 6611] OBJ_ipsec_IKE */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x12,       /* [ 6619] OBJ_capwapAC */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x13,       /* [ 6627] OBJ_capwapWTP */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x15,       /* [ 6635] OBJ_sshClient */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x16,       /* [ 6643] OBJ_sshServer */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x17,       /* [ 6651] OBJ_sendRouter */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x18,       /* [ 6659] OBJ_sendProxiedRouter */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x19,       /* [ 6667] OBJ_sendOwner */
-+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1A,       /* [ 6675] OBJ_sendProxiedOwner */
-+    0x2B,0x06,0x01,0x05,0x02,0x03,                 /* [ 6683] OBJ_id_pkinit */
-+    0x2B,0x06,0x01,0x05,0x02,0x03,0x04,            /* [ 6689] OBJ_pkInitClientAuth */
-+    0x2B,0x06,0x01,0x05,0x02,0x03,0x05,            /* [ 6696] OBJ_pkInitKDC */
-+    0x2B,0x65,0x6E,                                /* [ 6703] OBJ_X25519 */
-+    0x2B,0x65,0x6F,                                /* [ 6706] OBJ_X448 */
-+    0x2B,0x06,0x01,0x04,0x01,0x8D,0x3A,0x0C,0x02,0x01,0x10,  /* [ 6709] OBJ_blake2b512 */
-+    0x2B,0x06,0x01,0x04,0x01,0x8D,0x3A,0x0C,0x02,0x02,0x08,  /* [ 6720] OBJ_blake2s256 */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x13,  /* [ 6731] OBJ_id_smime_ct_contentCollection */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x17,  /* [ 6742] OBJ_id_smime_ct_authEnvelopedData */
-+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1C,  /* [ 6753] OBJ_id_ct_xml */
-+};
-+
-+#define NUM_NID 1061
-+static const ASN1_OBJECT nid_objs[NUM_NID] = {
-+    {"UNDEF", "undefined", NID_undef},
-+    {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
-+    {"pkcs", "RSA Data Security, Inc. PKCS", NID_pkcs, 7, &so[6]},
-+    {"MD2", "md2", NID_md2, 8, &so[13]},
-+    {"MD5", "md5", NID_md5, 8, &so[21]},
-+    {"RC4", "rc4", NID_rc4, 8, &so[29]},
-+    {"rsaEncryption", "rsaEncryption", NID_rsaEncryption, 9, &so[37]},
-+    {"RSA-MD2", "md2WithRSAEncryption", NID_md2WithRSAEncryption, 9, &so[46]},
-+    {"RSA-MD5", "md5WithRSAEncryption", NID_md5WithRSAEncryption, 9, &so[55]},
-+    {"PBE-MD2-DES", "pbeWithMD2AndDES-CBC", NID_pbeWithMD2AndDES_CBC, 9, &so[64]},
-+    {"PBE-MD5-DES", "pbeWithMD5AndDES-CBC", NID_pbeWithMD5AndDES_CBC, 9, &so[73]},
-+    {"X500", "directory services (X.500)", NID_X500, 1, &so[82]},
-+    {"X509", "X509", NID_X509, 2, &so[83]},
-+    {"CN", "commonName", NID_commonName, 3, &so[85]},
-+    {"C", "countryName", NID_countryName, 3, &so[88]},
-+    {"L", "localityName", NID_localityName, 3, &so[91]},
-+    {"ST", "stateOrProvinceName", NID_stateOrProvinceName, 3, &so[94]},
-+    {"O", "organizationName", NID_organizationName, 3, &so[97]},
-+    {"OU", "organizationalUnitName", NID_organizationalUnitName, 3, &so[100]},
-+    {"RSA", "rsa", NID_rsa, 4, &so[103]},
-+    {"pkcs7", "pkcs7", NID_pkcs7, 8, &so[107]},
-+    {"pkcs7-data", "pkcs7-data", NID_pkcs7_data, 9, &so[115]},
-+    {"pkcs7-signedData", "pkcs7-signedData", NID_pkcs7_signed, 9, &so[124]},
-+    {"pkcs7-envelopedData", "pkcs7-envelopedData", NID_pkcs7_enveloped, 9, &so[133]},
-+    {"pkcs7-signedAndEnvelopedData", "pkcs7-signedAndEnvelopedData", NID_pkcs7_signedAndEnveloped, 9, &so[142]},
-+    {"pkcs7-digestData", "pkcs7-digestData", NID_pkcs7_digest, 9, &so[151]},
-+    {"pkcs7-encryptedData", "pkcs7-encryptedData", NID_pkcs7_encrypted, 9, &so[160]},
-+    {"pkcs3", "pkcs3", NID_pkcs3, 8, &so[169]},
-+    {"dhKeyAgreement", "dhKeyAgreement", NID_dhKeyAgreement, 9, &so[177]},
-+    {"DES-ECB", "des-ecb", NID_des_ecb, 5, &so[186]},
-+    {"DES-CFB", "des-cfb", NID_des_cfb64, 5, &so[191]},
-+    {"DES-CBC", "des-cbc", NID_des_cbc, 5, &so[196]},
-+    {"DES-EDE", "des-ede", NID_des_ede_ecb, 5, &so[201]},
-+    {"DES-EDE3", "des-ede3", NID_des_ede3_ecb},
-+    {"IDEA-CBC", "idea-cbc", NID_idea_cbc, 11, &so[206]},
-+    {"IDEA-CFB", "idea-cfb", NID_idea_cfb64},
-+    {"IDEA-ECB", "idea-ecb", NID_idea_ecb},
-+    {"RC2-CBC", "rc2-cbc", NID_rc2_cbc, 8, &so[217]},
-+    {"RC2-ECB", "rc2-ecb", NID_rc2_ecb},
-+    {"RC2-CFB", "rc2-cfb", NID_rc2_cfb64},
-+    {"RC2-OFB", "rc2-ofb", NID_rc2_ofb64},
-+    {"SHA", "sha", NID_sha, 5, &so[225]},
-+    {"RSA-SHA", "shaWithRSAEncryption", NID_shaWithRSAEncryption, 5, &so[230]},
-+    {"DES-EDE-CBC", "des-ede-cbc", NID_des_ede_cbc},
-+    {"DES-EDE3-CBC", "des-ede3-cbc", NID_des_ede3_cbc, 8, &so[235]},
-+    {"DES-OFB", "des-ofb", NID_des_ofb64, 5, &so[243]},
-+    {"IDEA-OFB", "idea-ofb", NID_idea_ofb64},
-+    {"pkcs9", "pkcs9", NID_pkcs9, 8, &so[248]},
-+    {"emailAddress", "emailAddress", NID_pkcs9_emailAddress, 9, &so[256]},
-+    {"unstructuredName", "unstructuredName", NID_pkcs9_unstructuredName, 9, &so[265]},
-+    {"contentType", "contentType", NID_pkcs9_contentType, 9, &so[274]},
-+    {"messageDigest", "messageDigest", NID_pkcs9_messageDigest, 9, &so[283]},
-+    {"signingTime", "signingTime", NID_pkcs9_signingTime, 9, &so[292]},
-+    {"countersignature", "countersignature", NID_pkcs9_countersignature, 9, &so[301]},
-+    {"challengePassword", "challengePassword", NID_pkcs9_challengePassword, 9, &so[310]},
-+    {"unstructuredAddress", "unstructuredAddress", NID_pkcs9_unstructuredAddress, 9, &so[319]},
-+    {"extendedCertificateAttributes", "extendedCertificateAttributes", NID_pkcs9_extCertAttributes, 9, &so[328]},
-+    {"Netscape", "Netscape Communications Corp.", NID_netscape, 7, &so[337]},
-+    {"nsCertExt", "Netscape Certificate Extension", NID_netscape_cert_extension, 8, &so[344]},
-+    {"nsDataType", "Netscape Data Type", NID_netscape_data_type, 8, &so[352]},
-+    {"DES-EDE-CFB", "des-ede-cfb", NID_des_ede_cfb64},
-+    {"DES-EDE3-CFB", "des-ede3-cfb", NID_des_ede3_cfb64},
-+    {"DES-EDE-OFB", "des-ede-ofb", NID_des_ede_ofb64},
-+    {"DES-EDE3-OFB", "des-ede3-ofb", NID_des_ede3_ofb64},
-+    {"SHA1", "sha1", NID_sha1, 5, &so[360]},
-+    {"RSA-SHA1", "sha1WithRSAEncryption", NID_sha1WithRSAEncryption, 9, &so[365]},
-+    {"DSA-SHA", "dsaWithSHA", NID_dsaWithSHA, 5, &so[374]},
-+    {"DSA-old", "dsaEncryption-old", NID_dsa_2, 5, &so[379]},
-+    {"PBE-SHA1-RC2-64", "pbeWithSHA1AndRC2-CBC", NID_pbeWithSHA1AndRC2_CBC, 9, &so[384]},
-+    {"PBKDF2", "PBKDF2", NID_id_pbkdf2, 9, &so[393]},
-+    {"DSA-SHA1-old", "dsaWithSHA1-old", NID_dsaWithSHA1_2, 5, &so[402]},
-+    {"nsCertType", "Netscape Cert Type", NID_netscape_cert_type, 9, &so[407]},
-+    {"nsBaseUrl", "Netscape Base Url", NID_netscape_base_url, 9, &so[416]},
-+    {"nsRevocationUrl", "Netscape Revocation Url", NID_netscape_revocation_url, 9, &so[425]},
-+    {"nsCaRevocationUrl", "Netscape CA Revocation Url", NID_netscape_ca_revocation_url, 9, &so[434]},
-+    {"nsRenewalUrl", "Netscape Renewal Url", NID_netscape_renewal_url, 9, &so[443]},
-+    {"nsCaPolicyUrl", "Netscape CA Policy Url", NID_netscape_ca_policy_url, 9, &so[452]},
-+    {"nsSslServerName", "Netscape SSL Server Name", NID_netscape_ssl_server_name, 9, &so[461]},
-+    {"nsComment", "Netscape Comment", NID_netscape_comment, 9, &so[470]},
-+    {"nsCertSequence", "Netscape Certificate Sequence", NID_netscape_cert_sequence, 9, &so[479]},
-+    {"DESX-CBC", "desx-cbc", NID_desx_cbc},
-+    {"id-ce", "id-ce", NID_id_ce, 2, &so[488]},
-+    {"subjectKeyIdentifier", "X509v3 Subject Key Identifier", NID_subject_key_identifier, 3, &so[490]},
-+    {"keyUsage", "X509v3 Key Usage", NID_key_usage, 3, &so[493]},
-+    {"privateKeyUsagePeriod", "X509v3 Private Key Usage Period", NID_private_key_usage_period, 3, &so[496]},
-+    {"subjectAltName", "X509v3 Subject Alternative Name", NID_subject_alt_name, 3, &so[499]},
-+    {"issuerAltName", "X509v3 Issuer Alternative Name", NID_issuer_alt_name, 3, &so[502]},
-+    {"basicConstraints", "X509v3 Basic Constraints", NID_basic_constraints, 3, &so[505]},
-+    {"crlNumber", "X509v3 CRL Number", NID_crl_number, 3, &so[508]},
-+    {"certificatePolicies", "X509v3 Certificate Policies", NID_certificate_policies, 3, &so[511]},
-+    {"authorityKeyIdentifier", "X509v3 Authority Key Identifier", NID_authority_key_identifier, 3, &so[514]},
-+    {"BF-CBC", "bf-cbc", NID_bf_cbc, 9, &so[517]},
-+    {"BF-ECB", "bf-ecb", NID_bf_ecb},
-+    {"BF-CFB", "bf-cfb", NID_bf_cfb64},
-+    {"BF-OFB", "bf-ofb", NID_bf_ofb64},
-+    {"MDC2", "mdc2", NID_mdc2, 4, &so[526]},
-+    {"RSA-MDC2", "mdc2WithRSA", NID_mdc2WithRSA, 4, &so[530]},
-+    {"RC4-40", "rc4-40", NID_rc4_40},
-+    {"RC2-40-CBC", "rc2-40-cbc", NID_rc2_40_cbc},
-+    {"GN", "givenName", NID_givenName, 3, &so[534]},
-+    {"SN", "surname", NID_surname, 3, &so[537]},
-+    {"initials", "initials", NID_initials, 3, &so[540]},
-+    {"uid", "uniqueIdentifier", NID_uniqueIdentifier, 10, &so[543]},
-+    {"crlDistributionPoints", "X509v3 CRL Distribution Points", NID_crl_distribution_points, 3, &so[553]},
-+    {"RSA-NP-MD5", "md5WithRSA", NID_md5WithRSA, 5, &so[556]},
-+    {"serialNumber", "serialNumber", NID_serialNumber, 3, &so[561]},
-+    {"title", "title", NID_title, 3, &so[564]},
-+    {"description", "description", NID_description, 3, &so[567]},
-+    {"CAST5-CBC", "cast5-cbc", NID_cast5_cbc, 9, &so[570]},
-+    {"CAST5-ECB", "cast5-ecb", NID_cast5_ecb},
-+    {"CAST5-CFB", "cast5-cfb", NID_cast5_cfb64},
-+    {"CAST5-OFB", "cast5-ofb", NID_cast5_ofb64},
-+    {"pbeWithMD5AndCast5CBC", "pbeWithMD5AndCast5CBC", NID_pbeWithMD5AndCast5_CBC, 9, &so[579]},
-+    {"DSA-SHA1", "dsaWithSHA1", NID_dsaWithSHA1, 7, &so[588]},
-+    {"MD5-SHA1", "md5-sha1", NID_md5_sha1},
-+    {"RSA-SHA1-2", "sha1WithRSA", NID_sha1WithRSA, 5, &so[595]},
-+    {"DSA", "dsaEncryption", NID_dsa, 7, &so[600]},
-+    {"RIPEMD160", "ripemd160", NID_ripemd160, 5, &so[607]},
-+    { NULL, NULL, NID_undef },
-+    {"RSA-RIPEMD160", "ripemd160WithRSA", NID_ripemd160WithRSA, 6, &so[612]},
-+    {"RC5-CBC", "rc5-cbc", NID_rc5_cbc, 8, &so[618]},
-+    {"RC5-ECB", "rc5-ecb", NID_rc5_ecb},
-+    {"RC5-CFB", "rc5-cfb", NID_rc5_cfb64},
-+    {"RC5-OFB", "rc5-ofb", NID_rc5_ofb64},
-+    { NULL, NULL, NID_undef },
-+    {"ZLIB", "zlib compression", NID_zlib_compression, 11, &so[626]},
-+    {"extendedKeyUsage", "X509v3 Extended Key Usage", NID_ext_key_usage, 3, &so[637]},
-+    {"PKIX", "PKIX", NID_id_pkix, 6, &so[640]},
-+    {"id-kp", "id-kp", NID_id_kp, 7, &so[646]},
-+    {"serverAuth", "TLS Web Server Authentication", NID_server_auth, 8, &so[653]},
-+    {"clientAuth", "TLS Web Client Authentication", NID_client_auth, 8, &so[661]},
-+    {"codeSigning", "Code Signing", NID_code_sign, 8, &so[669]},
-+    {"emailProtection", "E-mail Protection", NID_email_protect, 8, &so[677]},
-+    {"timeStamping", "Time Stamping", NID_time_stamp, 8, &so[685]},
-+    {"msCodeInd", "Microsoft Individual Code Signing", NID_ms_code_ind, 10, &so[693]},
-+    {"msCodeCom", "Microsoft Commercial Code Signing", NID_ms_code_com, 10, &so[703]},
-+    {"msCTLSign", "Microsoft Trust List Signing", NID_ms_ctl_sign, 10, &so[713]},
-+    {"msSGC", "Microsoft Server Gated Crypto", NID_ms_sgc, 10, &so[723]},
-+    {"msEFS", "Microsoft Encrypted File System", NID_ms_efs, 10, &so[733]},
-+    {"nsSGC", "Netscape Server Gated Crypto", NID_ns_sgc, 9, &so[743]},
-+    {"deltaCRL", "X509v3 Delta CRL Indicator", NID_delta_crl, 3, &so[752]},
-+    {"CRLReason", "X509v3 CRL Reason Code", NID_crl_reason, 3, &so[755]},
-+    {"invalidityDate", "Invalidity Date", NID_invalidity_date, 3, &so[758]},
-+    {"SXNetID", "Strong Extranet ID", NID_sxnet, 5, &so[761]},
-+    {"PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4", NID_pbe_WithSHA1And128BitRC4, 10, &so[766]},
-+    {"PBE-SHA1-RC4-40", "pbeWithSHA1And40BitRC4", NID_pbe_WithSHA1And40BitRC4, 10, &so[776]},
-+    {"PBE-SHA1-3DES", "pbeWithSHA1And3-KeyTripleDES-CBC", NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 10, &so[786]},
-+    {"PBE-SHA1-2DES", "pbeWithSHA1And2-KeyTripleDES-CBC", NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 10, &so[796]},
-+    {"PBE-SHA1-RC2-128", "pbeWithSHA1And128BitRC2-CBC", NID_pbe_WithSHA1And128BitRC2_CBC, 10, &so[806]},
-+    {"PBE-SHA1-RC2-40", "pbeWithSHA1And40BitRC2-CBC", NID_pbe_WithSHA1And40BitRC2_CBC, 10, &so[816]},
-+    {"keyBag", "keyBag", NID_keyBag, 11, &so[826]},
-+    {"pkcs8ShroudedKeyBag", "pkcs8ShroudedKeyBag", NID_pkcs8ShroudedKeyBag, 11, &so[837]},
-+    {"certBag", "certBag", NID_certBag, 11, &so[848]},
-+    {"crlBag", "crlBag", NID_crlBag, 11, &so[859]},
-+    {"secretBag", "secretBag", NID_secretBag, 11, &so[870]},
-+    {"safeContentsBag", "safeContentsBag", NID_safeContentsBag, 11, &so[881]},
-+    {"friendlyName", "friendlyName", NID_friendlyName, 9, &so[892]},
-+    {"localKeyID", "localKeyID", NID_localKeyID, 9, &so[901]},
-+    {"x509Certificate", "x509Certificate", NID_x509Certificate, 10, &so[910]},
-+    {"sdsiCertificate", "sdsiCertificate", NID_sdsiCertificate, 10, &so[920]},
-+    {"x509Crl", "x509Crl", NID_x509Crl, 10, &so[930]},
-+    {"PBES2", "PBES2", NID_pbes2, 9, &so[940]},
-+    {"PBMAC1", "PBMAC1", NID_pbmac1, 9, &so[949]},
-+    {"hmacWithSHA1", "hmacWithSHA1", NID_hmacWithSHA1, 8, &so[958]},
-+    {"id-qt-cps", "Policy Qualifier CPS", NID_id_qt_cps, 8, &so[966]},
-+    {"id-qt-unotice", "Policy Qualifier User Notice", NID_id_qt_unotice, 8, &so[974]},
-+    {"RC2-64-CBC", "rc2-64-cbc", NID_rc2_64_cbc},
-+    {"SMIME-CAPS", "S/MIME Capabilities", NID_SMIMECapabilities, 9, &so[982]},
-+    {"PBE-MD2-RC2-64", "pbeWithMD2AndRC2-CBC", NID_pbeWithMD2AndRC2_CBC, 9, &so[991]},
-+    {"PBE-MD5-RC2-64", "pbeWithMD5AndRC2-CBC", NID_pbeWithMD5AndRC2_CBC, 9, &so[1000]},
-+    {"PBE-SHA1-DES", "pbeWithSHA1AndDES-CBC", NID_pbeWithSHA1AndDES_CBC, 9, &so[1009]},
-+    {"msExtReq", "Microsoft Extension Request", NID_ms_ext_req, 10, &so[1018]},
-+    {"extReq", "Extension Request", NID_ext_req, 9, &so[1028]},
-+    {"name", "name", NID_name, 3, &so[1037]},
-+    {"dnQualifier", "dnQualifier", NID_dnQualifier, 3, &so[1040]},
-+    {"id-pe", "id-pe", NID_id_pe, 7, &so[1043]},
-+    {"id-ad", "id-ad", NID_id_ad, 7, &so[1050]},
-+    {"authorityInfoAccess", "Authority Information Access", NID_info_access, 8, &so[1057]},
-+    {"OCSP", "OCSP", NID_ad_OCSP, 8, &so[1065]},
-+    {"caIssuers", "CA Issuers", NID_ad_ca_issuers, 8, &so[1073]},
-+    {"OCSPSigning", "OCSP Signing", NID_OCSP_sign, 8, &so[1081]},
-+    {"ISO", "iso", NID_iso},
-+    {"member-body", "ISO Member Body", NID_member_body, 1, &so[1089]},
-+    {"ISO-US", "ISO US Member Body", NID_ISO_US, 3, &so[1090]},
-+    {"X9-57", "X9.57", NID_X9_57, 5, &so[1093]},
-+    {"X9cm", "X9.57 CM ?", NID_X9cm, 6, &so[1098]},
-+    {"pkcs1", "pkcs1", NID_pkcs1, 8, &so[1104]},
-+    {"pkcs5", "pkcs5", NID_pkcs5, 8, &so[1112]},
-+    {"SMIME", "S/MIME", NID_SMIME, 9, &so[1120]},
-+    {"id-smime-mod", "id-smime-mod", NID_id_smime_mod, 10, &so[1129]},
-+    {"id-smime-ct", "id-smime-ct", NID_id_smime_ct, 10, &so[1139]},
-+    {"id-smime-aa", "id-smime-aa", NID_id_smime_aa, 10, &so[1149]},
-+    {"id-smime-alg", "id-smime-alg", NID_id_smime_alg, 10, &so[1159]},
-+    {"id-smime-cd", "id-smime-cd", NID_id_smime_cd, 10, &so[1169]},
-+    {"id-smime-spq", "id-smime-spq", NID_id_smime_spq, 10, &so[1179]},
-+    {"id-smime-cti", "id-smime-cti", NID_id_smime_cti, 10, &so[1189]},
-+    {"id-smime-mod-cms", "id-smime-mod-cms", NID_id_smime_mod_cms, 11, &so[1199]},
-+    {"id-smime-mod-ess", "id-smime-mod-ess", NID_id_smime_mod_ess, 11, &so[1210]},
-+    {"id-smime-mod-oid", "id-smime-mod-oid", NID_id_smime_mod_oid, 11, &so[1221]},
-+    {"id-smime-mod-msg-v3", "id-smime-mod-msg-v3", NID_id_smime_mod_msg_v3, 11, &so[1232]},
-+    {"id-smime-mod-ets-eSignature-88", "id-smime-mod-ets-eSignature-88", NID_id_smime_mod_ets_eSignature_88, 11, &so[1243]},
-+    {"id-smime-mod-ets-eSignature-97", "id-smime-mod-ets-eSignature-97", NID_id_smime_mod_ets_eSignature_97, 11, &so[1254]},
-+    {"id-smime-mod-ets-eSigPolicy-88", "id-smime-mod-ets-eSigPolicy-88", NID_id_smime_mod_ets_eSigPolicy_88, 11, &so[1265]},
-+    {"id-smime-mod-ets-eSigPolicy-97", "id-smime-mod-ets-eSigPolicy-97", NID_id_smime_mod_ets_eSigPolicy_97, 11, &so[1276]},
-+    {"id-smime-ct-receipt", "id-smime-ct-receipt", NID_id_smime_ct_receipt, 11, &so[1287]},
-+    {"id-smime-ct-authData", "id-smime-ct-authData", NID_id_smime_ct_authData, 11, &so[1298]},
-+    {"id-smime-ct-publishCert", "id-smime-ct-publishCert", NID_id_smime_ct_publishCert, 11, &so[1309]},
-+    {"id-smime-ct-TSTInfo", "id-smime-ct-TSTInfo", NID_id_smime_ct_TSTInfo, 11, &so[1320]},
-+    {"id-smime-ct-TDTInfo", "id-smime-ct-TDTInfo", NID_id_smime_ct_TDTInfo, 11, &so[1331]},
-+    {"id-smime-ct-contentInfo", "id-smime-ct-contentInfo", NID_id_smime_ct_contentInfo, 11, &so[1342]},
-+    {"id-smime-ct-DVCSRequestData", "id-smime-ct-DVCSRequestData", NID_id_smime_ct_DVCSRequestData, 11, &so[1353]},
-+    {"id-smime-ct-DVCSResponseData", "id-smime-ct-DVCSResponseData", NID_id_smime_ct_DVCSResponseData, 11, &so[1364]},
-+    {"id-smime-aa-receiptRequest", "id-smime-aa-receiptRequest", NID_id_smime_aa_receiptRequest, 11, &so[1375]},
-+    {"id-smime-aa-securityLabel", "id-smime-aa-securityLabel", NID_id_smime_aa_securityLabel, 11, &so[1386]},
-+    {"id-smime-aa-mlExpandHistory", "id-smime-aa-mlExpandHistory", NID_id_smime_aa_mlExpandHistory, 11, &so[1397]},
-+    {"id-smime-aa-contentHint", "id-smime-aa-contentHint", NID_id_smime_aa_contentHint, 11, &so[1408]},
-+    {"id-smime-aa-msgSigDigest", "id-smime-aa-msgSigDigest", NID_id_smime_aa_msgSigDigest, 11, &so[1419]},
-+    {"id-smime-aa-encapContentType", "id-smime-aa-encapContentType", NID_id_smime_aa_encapContentType, 11, &so[1430]},
-+    {"id-smime-aa-contentIdentifier", "id-smime-aa-contentIdentifier", NID_id_smime_aa_contentIdentifier, 11, &so[1441]},
-+    {"id-smime-aa-macValue", "id-smime-aa-macValue", NID_id_smime_aa_macValue, 11, &so[1452]},
-+    {"id-smime-aa-equivalentLabels", "id-smime-aa-equivalentLabels", NID_id_smime_aa_equivalentLabels, 11, &so[1463]},
-+    {"id-smime-aa-contentReference", "id-smime-aa-contentReference", NID_id_smime_aa_contentReference, 11, &so[1474]},
-+    {"id-smime-aa-encrypKeyPref", "id-smime-aa-encrypKeyPref", NID_id_smime_aa_encrypKeyPref, 11, &so[1485]},
-+    {"id-smime-aa-signingCertificate", "id-smime-aa-signingCertificate", NID_id_smime_aa_signingCertificate, 11, &so[1496]},
-+    {"id-smime-aa-smimeEncryptCerts", "id-smime-aa-smimeEncryptCerts", NID_id_smime_aa_smimeEncryptCerts, 11, &so[1507]},
-+    {"id-smime-aa-timeStampToken", "id-smime-aa-timeStampToken", NID_id_smime_aa_timeStampToken, 11, &so[1518]},
-+    {"id-smime-aa-ets-sigPolicyId", "id-smime-aa-ets-sigPolicyId", NID_id_smime_aa_ets_sigPolicyId, 11, &so[1529]},
-+    {"id-smime-aa-ets-commitmentType", "id-smime-aa-ets-commitmentType", NID_id_smime_aa_ets_commitmentType, 11, &so[1540]},
-+    {"id-smime-aa-ets-signerLocation", "id-smime-aa-ets-signerLocation", NID_id_smime_aa_ets_signerLocation, 11, &so[1551]},
-+    {"id-smime-aa-ets-signerAttr", "id-smime-aa-ets-signerAttr", NID_id_smime_aa_ets_signerAttr, 11, &so[1562]},
-+    {"id-smime-aa-ets-otherSigCert", "id-smime-aa-ets-otherSigCert", NID_id_smime_aa_ets_otherSigCert, 11, &so[1573]},
-+    {"id-smime-aa-ets-contentTimestamp", "id-smime-aa-ets-contentTimestamp", NID_id_smime_aa_ets_contentTimestamp, 11, &so[1584]},
-+    {"id-smime-aa-ets-CertificateRefs", "id-smime-aa-ets-CertificateRefs", NID_id_smime_aa_ets_CertificateRefs, 11, &so[1595]},
-+    {"id-smime-aa-ets-RevocationRefs", "id-smime-aa-ets-RevocationRefs", NID_id_smime_aa_ets_RevocationRefs, 11, &so[1606]},
-+    {"id-smime-aa-ets-certValues", "id-smime-aa-ets-certValues", NID_id_smime_aa_ets_certValues, 11, &so[1617]},
-+    {"id-smime-aa-ets-revocationValues", "id-smime-aa-ets-revocationValues", NID_id_smime_aa_ets_revocationValues, 11, &so[1628]},
-+    {"id-smime-aa-ets-escTimeStamp", "id-smime-aa-ets-escTimeStamp", NID_id_smime_aa_ets_escTimeStamp, 11, &so[1639]},
-+    {"id-smime-aa-ets-certCRLTimestamp", "id-smime-aa-ets-certCRLTimestamp", NID_id_smime_aa_ets_certCRLTimestamp, 11, &so[1650]},
-+    {"id-smime-aa-ets-archiveTimeStamp", "id-smime-aa-ets-archiveTimeStamp", NID_id_smime_aa_ets_archiveTimeStamp, 11, &so[1661]},
-+    {"id-smime-aa-signatureType", "id-smime-aa-signatureType", NID_id_smime_aa_signatureType, 11, &so[1672]},
-+    {"id-smime-aa-dvcs-dvc", "id-smime-aa-dvcs-dvc", NID_id_smime_aa_dvcs_dvc, 11, &so[1683]},
-+    {"id-smime-alg-ESDHwith3DES", "id-smime-alg-ESDHwith3DES", NID_id_smime_alg_ESDHwith3DES, 11, &so[1694]},
-+    {"id-smime-alg-ESDHwithRC2", "id-smime-alg-ESDHwithRC2", NID_id_smime_alg_ESDHwithRC2, 11, &so[1705]},
-+    {"id-smime-alg-3DESwrap", "id-smime-alg-3DESwrap", NID_id_smime_alg_3DESwrap, 11, &so[1716]},
-+    {"id-smime-alg-RC2wrap", "id-smime-alg-RC2wrap", NID_id_smime_alg_RC2wrap, 11, &so[1727]},
-+    {"id-smime-alg-ESDH", "id-smime-alg-ESDH", NID_id_smime_alg_ESDH, 11, &so[1738]},
-+    {"id-smime-alg-CMS3DESwrap", "id-smime-alg-CMS3DESwrap", NID_id_smime_alg_CMS3DESwrap, 11, &so[1749]},
-+    {"id-smime-alg-CMSRC2wrap", "id-smime-alg-CMSRC2wrap", NID_id_smime_alg_CMSRC2wrap, 11, &so[1760]},
-+    {"id-smime-cd-ldap", "id-smime-cd-ldap", NID_id_smime_cd_ldap, 11, &so[1771]},
-+    {"id-smime-spq-ets-sqt-uri", "id-smime-spq-ets-sqt-uri", NID_id_smime_spq_ets_sqt_uri, 11, &so[1782]},
-+    {"id-smime-spq-ets-sqt-unotice", "id-smime-spq-ets-sqt-unotice", NID_id_smime_spq_ets_sqt_unotice, 11, &so[1793]},
-+    {"id-smime-cti-ets-proofOfOrigin", "id-smime-cti-ets-proofOfOrigin", NID_id_smime_cti_ets_proofOfOrigin, 11, &so[1804]},
-+    {"id-smime-cti-ets-proofOfReceipt", "id-smime-cti-ets-proofOfReceipt", NID_id_smime_cti_ets_proofOfReceipt, 11, &so[1815]},
-+    {"id-smime-cti-ets-proofOfDelivery", "id-smime-cti-ets-proofOfDelivery", NID_id_smime_cti_ets_proofOfDelivery, 11, &so[1826]},
-+    {"id-smime-cti-ets-proofOfSender", "id-smime-cti-ets-proofOfSender", NID_id_smime_cti_ets_proofOfSender, 11, &so[1837]},
-+    {"id-smime-cti-ets-proofOfApproval", "id-smime-cti-ets-proofOfApproval", NID_id_smime_cti_ets_proofOfApproval, 11, &so[1848]},
-+    {"id-smime-cti-ets-proofOfCreation", "id-smime-cti-ets-proofOfCreation", NID_id_smime_cti_ets_proofOfCreation, 11, &so[1859]},
-+    {"MD4", "md4", NID_md4, 8, &so[1870]},
-+    {"id-pkix-mod", "id-pkix-mod", NID_id_pkix_mod, 7, &so[1878]},
-+    {"id-qt", "id-qt", NID_id_qt, 7, &so[1885]},
-+    {"id-it", "id-it", NID_id_it, 7, &so[1892]},
-+    {"id-pkip", "id-pkip", NID_id_pkip, 7, &so[1899]},
-+    {"id-alg", "id-alg", NID_id_alg, 7, &so[1906]},
-+    {"id-cmc", "id-cmc", NID_id_cmc, 7, &so[1913]},
-+    {"id-on", "id-on", NID_id_on, 7, &so[1920]},
-+    {"id-pda", "id-pda", NID_id_pda, 7, &so[1927]},
-+    {"id-aca", "id-aca", NID_id_aca, 7, &so[1934]},
-+    {"id-qcs", "id-qcs", NID_id_qcs, 7, &so[1941]},
-+    {"id-cct", "id-cct", NID_id_cct, 7, &so[1948]},
-+    {"id-pkix1-explicit-88", "id-pkix1-explicit-88", NID_id_pkix1_explicit_88, 8, &so[1955]},
-+    {"id-pkix1-implicit-88", "id-pkix1-implicit-88", NID_id_pkix1_implicit_88, 8, &so[1963]},
-+    {"id-pkix1-explicit-93", "id-pkix1-explicit-93", NID_id_pkix1_explicit_93, 8, &so[1971]},
-+    {"id-pkix1-implicit-93", "id-pkix1-implicit-93", NID_id_pkix1_implicit_93, 8, &so[1979]},
-+    {"id-mod-crmf", "id-mod-crmf", NID_id_mod_crmf, 8, &so[1987]},
-+    {"id-mod-cmc", "id-mod-cmc", NID_id_mod_cmc, 8, &so[1995]},
-+    {"id-mod-kea-profile-88", "id-mod-kea-profile-88", NID_id_mod_kea_profile_88, 8, &so[2003]},
-+    {"id-mod-kea-profile-93", "id-mod-kea-profile-93", NID_id_mod_kea_profile_93, 8, &so[2011]},
-+    {"id-mod-cmp", "id-mod-cmp", NID_id_mod_cmp, 8, &so[2019]},
-+    {"id-mod-qualified-cert-88", "id-mod-qualified-cert-88", NID_id_mod_qualified_cert_88, 8, &so[2027]},
-+    {"id-mod-qualified-cert-93", "id-mod-qualified-cert-93", NID_id_mod_qualified_cert_93, 8, &so[2035]},
-+    {"id-mod-attribute-cert", "id-mod-attribute-cert", NID_id_mod_attribute_cert, 8, &so[2043]},
-+    {"id-mod-timestamp-protocol", "id-mod-timestamp-protocol", NID_id_mod_timestamp_protocol, 8, &so[2051]},
-+    {"id-mod-ocsp", "id-mod-ocsp", NID_id_mod_ocsp, 8, &so[2059]},
-+    {"id-mod-dvcs", "id-mod-dvcs", NID_id_mod_dvcs, 8, &so[2067]},
-+    {"id-mod-cmp2000", "id-mod-cmp2000", NID_id_mod_cmp2000, 8, &so[2075]},
-+    {"biometricInfo", "Biometric Info", NID_biometricInfo, 8, &so[2083]},
-+    {"qcStatements", "qcStatements", NID_qcStatements, 8, &so[2091]},
-+    {"ac-auditEntity", "ac-auditEntity", NID_ac_auditEntity, 8, &so[2099]},
-+    {"ac-targeting", "ac-targeting", NID_ac_targeting, 8, &so[2107]},
-+    {"aaControls", "aaControls", NID_aaControls, 8, &so[2115]},
-+    {"sbgp-ipAddrBlock", "sbgp-ipAddrBlock", NID_sbgp_ipAddrBlock, 8, &so[2123]},
-+    {"sbgp-autonomousSysNum", "sbgp-autonomousSysNum", NID_sbgp_autonomousSysNum, 8, &so[2131]},
-+    {"sbgp-routerIdentifier", "sbgp-routerIdentifier", NID_sbgp_routerIdentifier, 8, &so[2139]},
-+    {"textNotice", "textNotice", NID_textNotice, 8, &so[2147]},
-+    {"ipsecEndSystem", "IPSec End System", NID_ipsecEndSystem, 8, &so[2155]},
-+    {"ipsecTunnel", "IPSec Tunnel", NID_ipsecTunnel, 8, &so[2163]},
-+    {"ipsecUser", "IPSec User", NID_ipsecUser, 8, &so[2171]},
-+    {"DVCS", "dvcs", NID_dvcs, 8, &so[2179]},
-+    {"id-it-caProtEncCert", "id-it-caProtEncCert", NID_id_it_caProtEncCert, 8, &so[2187]},
-+    {"id-it-signKeyPairTypes", "id-it-signKeyPairTypes", NID_id_it_signKeyPairTypes, 8, &so[2195]},
-+    {"id-it-encKeyPairTypes", "id-it-encKeyPairTypes", NID_id_it_encKeyPairTypes, 8, &so[2203]},
-+    {"id-it-preferredSymmAlg", "id-it-preferredSymmAlg", NID_id_it_preferredSymmAlg, 8, &so[2211]},
-+    {"id-it-caKeyUpdateInfo", "id-it-caKeyUpdateInfo", NID_id_it_caKeyUpdateInfo, 8, &so[2219]},
-+    {"id-it-currentCRL", "id-it-currentCRL", NID_id_it_currentCRL, 8, &so[2227]},
-+    {"id-it-unsupportedOIDs", "id-it-unsupportedOIDs", NID_id_it_unsupportedOIDs, 8, &so[2235]},
-+    {"id-it-subscriptionRequest", "id-it-subscriptionRequest", NID_id_it_subscriptionRequest, 8, &so[2243]},
-+    {"id-it-subscriptionResponse", "id-it-subscriptionResponse", NID_id_it_subscriptionResponse, 8, &so[2251]},
-+    {"id-it-keyPairParamReq", "id-it-keyPairParamReq", NID_id_it_keyPairParamReq, 8, &so[2259]},
-+    {"id-it-keyPairParamRep", "id-it-keyPairParamRep", NID_id_it_keyPairParamRep, 8, &so[2267]},
-+    {"id-it-revPassphrase", "id-it-revPassphrase", NID_id_it_revPassphrase, 8, &so[2275]},
-+    {"id-it-implicitConfirm", "id-it-implicitConfirm", NID_id_it_implicitConfirm, 8, &so[2283]},
-+    {"id-it-confirmWaitTime", "id-it-confirmWaitTime", NID_id_it_confirmWaitTime, 8, &so[2291]},
-+    {"id-it-origPKIMessage", "id-it-origPKIMessage", NID_id_it_origPKIMessage, 8, &so[2299]},
-+    {"id-regCtrl", "id-regCtrl", NID_id_regCtrl, 8, &so[2307]},
-+    {"id-regInfo", "id-regInfo", NID_id_regInfo, 8, &so[2315]},
-+    {"id-regCtrl-regToken", "id-regCtrl-regToken", NID_id_regCtrl_regToken, 9, &so[2323]},
-+    {"id-regCtrl-authenticator", "id-regCtrl-authenticator", NID_id_regCtrl_authenticator, 9, &so[2332]},
-+    {"id-regCtrl-pkiPublicationInfo", "id-regCtrl-pkiPublicationInfo", NID_id_regCtrl_pkiPublicationInfo, 9, &so[2341]},
-+    {"id-regCtrl-pkiArchiveOptions", "id-regCtrl-pkiArchiveOptions", NID_id_regCtrl_pkiArchiveOptions, 9, &so[2350]},
-+    {"id-regCtrl-oldCertID", "id-regCtrl-oldCertID", NID_id_regCtrl_oldCertID, 9, &so[2359]},
-+    {"id-regCtrl-protocolEncrKey", "id-regCtrl-protocolEncrKey", NID_id_regCtrl_protocolEncrKey, 9, &so[2368]},
-+    {"id-regInfo-utf8Pairs", "id-regInfo-utf8Pairs", NID_id_regInfo_utf8Pairs, 9, &so[2377]},
-+    {"id-regInfo-certReq", "id-regInfo-certReq", NID_id_regInfo_certReq, 9, &so[2386]},
-+    {"id-alg-des40", "id-alg-des40", NID_id_alg_des40, 8, &so[2395]},
-+    {"id-alg-noSignature", "id-alg-noSignature", NID_id_alg_noSignature, 8, &so[2403]},
-+    {"id-alg-dh-sig-hmac-sha1", "id-alg-dh-sig-hmac-sha1", NID_id_alg_dh_sig_hmac_sha1, 8, &so[2411]},
-+    {"id-alg-dh-pop", "id-alg-dh-pop", NID_id_alg_dh_pop, 8, &so[2419]},
-+    {"id-cmc-statusInfo", "id-cmc-statusInfo", NID_id_cmc_statusInfo, 8, &so[2427]},
-+    {"id-cmc-identification", "id-cmc-identification", NID_id_cmc_identification, 8, &so[2435]},
-+    {"id-cmc-identityProof", "id-cmc-identityProof", NID_id_cmc_identityProof, 8, &so[2443]},
-+    {"id-cmc-dataReturn", "id-cmc-dataReturn", NID_id_cmc_dataReturn, 8, &so[2451]},
-+    {"id-cmc-transactionId", "id-cmc-transactionId", NID_id_cmc_transactionId, 8, &so[2459]},
-+    {"id-cmc-senderNonce", "id-cmc-senderNonce", NID_id_cmc_senderNonce, 8, &so[2467]},
-+    {"id-cmc-recipientNonce", "id-cmc-recipientNonce", NID_id_cmc_recipientNonce, 8, &so[2475]},
-+    {"id-cmc-addExtensions", "id-cmc-addExtensions", NID_id_cmc_addExtensions, 8, &so[2483]},
-+    {"id-cmc-encryptedPOP", "id-cmc-encryptedPOP", NID_id_cmc_encryptedPOP, 8, &so[2491]},
-+    {"id-cmc-decryptedPOP", "id-cmc-decryptedPOP", NID_id_cmc_decryptedPOP, 8, &so[2499]},
-+    {"id-cmc-lraPOPWitness", "id-cmc-lraPOPWitness", NID_id_cmc_lraPOPWitness, 8, &so[2507]},
-+    {"id-cmc-getCert", "id-cmc-getCert", NID_id_cmc_getCert, 8, &so[2515]},
-+    {"id-cmc-getCRL", "id-cmc-getCRL", NID_id_cmc_getCRL, 8, &so[2523]},
-+    {"id-cmc-revokeRequest", "id-cmc-revokeRequest", NID_id_cmc_revokeRequest, 8, &so[2531]},
-+    {"id-cmc-regInfo", "id-cmc-regInfo", NID_id_cmc_regInfo, 8, &so[2539]},
-+    {"id-cmc-responseInfo", "id-cmc-responseInfo", NID_id_cmc_responseInfo, 8, &so[2547]},
-+    {"id-cmc-queryPending", "id-cmc-queryPending", NID_id_cmc_queryPending, 8, &so[2555]},
-+    {"id-cmc-popLinkRandom", "id-cmc-popLinkRandom", NID_id_cmc_popLinkRandom, 8, &so[2563]},
-+    {"id-cmc-popLinkWitness", "id-cmc-popLinkWitness", NID_id_cmc_popLinkWitness, 8, &so[2571]},
-+    {"id-cmc-confirmCertAcceptance", "id-cmc-confirmCertAcceptance", NID_id_cmc_confirmCertAcceptance, 8, &so[2579]},
-+    {"id-on-personalData", "id-on-personalData", NID_id_on_personalData, 8, &so[2587]},
-+    {"id-pda-dateOfBirth", "id-pda-dateOfBirth", NID_id_pda_dateOfBirth, 8, &so[2595]},
-+    {"id-pda-placeOfBirth", "id-pda-placeOfBirth", NID_id_pda_placeOfBirth, 8, &so[2603]},
-+    { NULL, NULL, NID_undef },
-+    {"id-pda-gender", "id-pda-gender", NID_id_pda_gender, 8, &so[2611]},
-+    {"id-pda-countryOfCitizenship", "id-pda-countryOfCitizenship", NID_id_pda_countryOfCitizenship, 8, &so[2619]},
-+    {"id-pda-countryOfResidence", "id-pda-countryOfResidence", NID_id_pda_countryOfResidence, 8, &so[2627]},
-+    {"id-aca-authenticationInfo", "id-aca-authenticationInfo", NID_id_aca_authenticationInfo, 8, &so[2635]},
-+    {"id-aca-accessIdentity", "id-aca-accessIdentity", NID_id_aca_accessIdentity, 8, &so[2643]},
-+    {"id-aca-chargingIdentity", "id-aca-chargingIdentity", NID_id_aca_chargingIdentity, 8, &so[2651]},
-+    {"id-aca-group", "id-aca-group", NID_id_aca_group, 8, &so[2659]},
-+    {"id-aca-role", "id-aca-role", NID_id_aca_role, 8, &so[2667]},
-+    {"id-qcs-pkixQCSyntax-v1", "id-qcs-pkixQCSyntax-v1", NID_id_qcs_pkixQCSyntax_v1, 8, &so[2675]},
-+    {"id-cct-crs", "id-cct-crs", NID_id_cct_crs, 8, &so[2683]},
-+    {"id-cct-PKIData", "id-cct-PKIData", NID_id_cct_PKIData, 8, &so[2691]},
-+    {"id-cct-PKIResponse", "id-cct-PKIResponse", NID_id_cct_PKIResponse, 8, &so[2699]},
-+    {"ad_timestamping", "AD Time Stamping", NID_ad_timeStamping, 8, &so[2707]},
-+    {"AD_DVCS", "ad dvcs", NID_ad_dvcs, 8, &so[2715]},
-+    {"basicOCSPResponse", "Basic OCSP Response", NID_id_pkix_OCSP_basic, 9, &so[2723]},
-+    {"Nonce", "OCSP Nonce", NID_id_pkix_OCSP_Nonce, 9, &so[2732]},
-+    {"CrlID", "OCSP CRL ID", NID_id_pkix_OCSP_CrlID, 9, &so[2741]},
-+    {"acceptableResponses", "Acceptable OCSP Responses", NID_id_pkix_OCSP_acceptableResponses, 9, &so[2750]},
-+    {"noCheck", "OCSP No Check", NID_id_pkix_OCSP_noCheck, 9, &so[2759]},
-+    {"archiveCutoff", "OCSP Archive Cutoff", NID_id_pkix_OCSP_archiveCutoff, 9, &so[2768]},
-+    {"serviceLocator", "OCSP Service Locator", NID_id_pkix_OCSP_serviceLocator, 9, &so[2777]},
-+    {"extendedStatus", "Extended OCSP Status", NID_id_pkix_OCSP_extendedStatus, 9, &so[2786]},
-+    {"valid", "valid", NID_id_pkix_OCSP_valid, 9, &so[2795]},
-+    {"path", "path", NID_id_pkix_OCSP_path, 9, &so[2804]},
-+    {"trustRoot", "Trust Root", NID_id_pkix_OCSP_trustRoot, 9, &so[2813]},
-+    {"algorithm", "algorithm", NID_algorithm, 4, &so[2822]},
-+    {"rsaSignature", "rsaSignature", NID_rsaSignature, 5, &so[2826]},
-+    {"X500algorithms", "directory services - algorithms", NID_X500algorithms, 2, &so[2831]},
-+    {"ORG", "org", NID_org, 1, &so[2833]},
-+    {"DOD", "dod", NID_dod, 2, &so[2834]},
-+    {"IANA", "iana", NID_iana, 3, &so[2836]},
-+    {"directory", "Directory", NID_Directory, 4, &so[2839]},
-+    {"mgmt", "Management", NID_Management, 4, &so[2843]},
-+    {"experimental", "Experimental", NID_Experimental, 4, &so[2847]},
-+    {"private", "Private", NID_Private, 4, &so[2851]},
-+    {"security", "Security", NID_Security, 4, &so[2855]},
-+    {"snmpv2", "SNMPv2", NID_SNMPv2, 4, &so[2859]},
-+    {"Mail", "Mail", NID_Mail, 4, &so[2863]},
-+    {"enterprises", "Enterprises", NID_Enterprises, 5, &so[2867]},
-+    {"dcobject", "dcObject", NID_dcObject, 9, &so[2872]},
-+    {"DC", "domainComponent", NID_domainComponent, 10, &so[2881]},
-+    {"domain", "Domain", NID_Domain, 10, &so[2891]},
-+    {"NULL", "NULL", NID_joint_iso_ccitt},
-+    {"selected-attribute-types", "Selected Attribute Types", NID_selected_attribute_types, 3, &so[2901]},
-+    {"clearance", "clearance", NID_clearance, 4, &so[2904]},
-+    {"RSA-MD4", "md4WithRSAEncryption", NID_md4WithRSAEncryption, 9, &so[2908]},
-+    {"ac-proxying", "ac-proxying", NID_ac_proxying, 8, &so[2917]},
-+    {"subjectInfoAccess", "Subject Information Access", NID_sinfo_access, 8, &so[2925]},
-+    {"id-aca-encAttrs", "id-aca-encAttrs", NID_id_aca_encAttrs, 8, &so[2933]},
-+    {"role", "role", NID_role, 3, &so[2941]},
-+    {"policyConstraints", "X509v3 Policy Constraints", NID_policy_constraints, 3, &so[2944]},
-+    {"targetInformation", "X509v3 AC Targeting", NID_target_information, 3, &so[2947]},
-+    {"noRevAvail", "X509v3 No Revocation Available", NID_no_rev_avail, 3, &so[2950]},
-+    {"NULL", "NULL", NID_ccitt},
-+    {"ansi-X9-62", "ANSI X9.62", NID_ansi_X9_62, 5, &so[2953]},
-+    {"prime-field", "prime-field", NID_X9_62_prime_field, 7, &so[2958]},
-+    {"characteristic-two-field", "characteristic-two-field", NID_X9_62_characteristic_two_field, 7, &so[2965]},
-+    {"id-ecPublicKey", "id-ecPublicKey", NID_X9_62_id_ecPublicKey, 7, &so[2972]},
-+    {"prime192v1", "prime192v1", NID_X9_62_prime192v1, 8, &so[2979]},
-+    {"prime192v2", "prime192v2", NID_X9_62_prime192v2, 8, &so[2987]},
-+    {"prime192v3", "prime192v3", NID_X9_62_prime192v3, 8, &so[2995]},
-+    {"prime239v1", "prime239v1", NID_X9_62_prime239v1, 8, &so[3003]},
-+    {"prime239v2", "prime239v2", NID_X9_62_prime239v2, 8, &so[3011]},
-+    {"prime239v3", "prime239v3", NID_X9_62_prime239v3, 8, &so[3019]},
-+    {"prime256v1", "prime256v1", NID_X9_62_prime256v1, 8, &so[3027]},
-+    {"ecdsa-with-SHA1", "ecdsa-with-SHA1", NID_ecdsa_with_SHA1, 7, &so[3035]},
-+    {"CSPName", "Microsoft CSP Name", NID_ms_csp_name, 9, &so[3042]},
-+    {"AES-128-ECB", "aes-128-ecb", NID_aes_128_ecb, 9, &so[3051]},
-+    {"AES-128-CBC", "aes-128-cbc", NID_aes_128_cbc, 9, &so[3060]},
-+    {"AES-128-OFB", "aes-128-ofb", NID_aes_128_ofb128, 9, &so[3069]},
-+    {"AES-128-CFB", "aes-128-cfb", NID_aes_128_cfb128, 9, &so[3078]},
-+    {"AES-192-ECB", "aes-192-ecb", NID_aes_192_ecb, 9, &so[3087]},
-+    {"AES-192-CBC", "aes-192-cbc", NID_aes_192_cbc, 9, &so[3096]},
-+    {"AES-192-OFB", "aes-192-ofb", NID_aes_192_ofb128, 9, &so[3105]},
-+    {"AES-192-CFB", "aes-192-cfb", NID_aes_192_cfb128, 9, &so[3114]},
-+    {"AES-256-ECB", "aes-256-ecb", NID_aes_256_ecb, 9, &so[3123]},
-+    {"AES-256-CBC", "aes-256-cbc", NID_aes_256_cbc, 9, &so[3132]},
-+    {"AES-256-OFB", "aes-256-ofb", NID_aes_256_ofb128, 9, &so[3141]},
-+    {"AES-256-CFB", "aes-256-cfb", NID_aes_256_cfb128, 9, &so[3150]},
-+    {"holdInstructionCode", "Hold Instruction Code", NID_hold_instruction_code, 3, &so[3159]},
-+    {"holdInstructionNone", "Hold Instruction None", NID_hold_instruction_none, 7, &so[3162]},
-+    {"holdInstructionCallIssuer", "Hold Instruction Call Issuer", NID_hold_instruction_call_issuer, 7, &so[3169]},
-+    {"holdInstructionReject", "Hold Instruction Reject", NID_hold_instruction_reject, 7, &so[3176]},
-+    {"data", "data", NID_data, 1, &so[3183]},
-+    {"pss", "pss", NID_pss, 3, &so[3184]},
-+    {"ucl", "ucl", NID_ucl, 7, &so[3187]},
-+    {"pilot", "pilot", NID_pilot, 8, &so[3194]},
-+    {"pilotAttributeType", "pilotAttributeType", NID_pilotAttributeType, 9, &so[3202]},
-+    {"pilotAttributeSyntax", "pilotAttributeSyntax", NID_pilotAttributeSyntax, 9, &so[3211]},
-+    {"pilotObjectClass", "pilotObjectClass", NID_pilotObjectClass, 9, &so[3220]},
-+    {"pilotGroups", "pilotGroups", NID_pilotGroups, 9, &so[3229]},
-+    {"iA5StringSyntax", "iA5StringSyntax", NID_iA5StringSyntax, 10, &so[3238]},
-+    {"caseIgnoreIA5StringSyntax", "caseIgnoreIA5StringSyntax", NID_caseIgnoreIA5StringSyntax, 10, &so[3248]},
-+    {"pilotObject", "pilotObject", NID_pilotObject, 10, &so[3258]},
-+    {"pilotPerson", "pilotPerson", NID_pilotPerson, 10, &so[3268]},
-+    {"account", "account", NID_account, 10, &so[3278]},
-+    {"document", "document", NID_document, 10, &so[3288]},
-+    {"room", "room", NID_room, 10, &so[3298]},
-+    {"documentSeries", "documentSeries", NID_documentSeries, 10, &so[3308]},
-+    {"rFC822localPart", "rFC822localPart", NID_rFC822localPart, 10, &so[3318]},
-+    {"dNSDomain", "dNSDomain", NID_dNSDomain, 10, &so[3328]},
-+    {"domainRelatedObject", "domainRelatedObject", NID_domainRelatedObject, 10, &so[3338]},
-+    {"friendlyCountry", "friendlyCountry", NID_friendlyCountry, 10, &so[3348]},
-+    {"simpleSecurityObject", "simpleSecurityObject", NID_simpleSecurityObject, 10, &so[3358]},
-+    {"pilotOrganization", "pilotOrganization", NID_pilotOrganization, 10, &so[3368]},
-+    {"pilotDSA", "pilotDSA", NID_pilotDSA, 10, &so[3378]},
-+    {"qualityLabelledData", "qualityLabelledData", NID_qualityLabelledData, 10, &so[3388]},
-+    {"UID", "userId", NID_userId, 10, &so[3398]},
-+    {"textEncodedORAddress", "textEncodedORAddress", NID_textEncodedORAddress, 10, &so[3408]},
-+    {"mail", "rfc822Mailbox", NID_rfc822Mailbox, 10, &so[3418]},
-+    {"info", "info", NID_info, 10, &so[3428]},
-+    {"favouriteDrink", "favouriteDrink", NID_favouriteDrink, 10, &so[3438]},
-+    {"roomNumber", "roomNumber", NID_roomNumber, 10, &so[3448]},
-+    {"photo", "photo", NID_photo, 10, &so[3458]},
-+    {"userClass", "userClass", NID_userClass, 10, &so[3468]},
-+    {"host", "host", NID_host, 10, &so[3478]},
-+    {"manager", "manager", NID_manager, 10, &so[3488]},
-+    {"documentIdentifier", "documentIdentifier", NID_documentIdentifier, 10, &so[3498]},
-+    {"documentTitle", "documentTitle", NID_documentTitle, 10, &so[3508]},
-+    {"documentVersion", "documentVersion", NID_documentVersion, 10, &so[3518]},
-+    {"documentAuthor", "documentAuthor", NID_documentAuthor, 10, &so[3528]},
-+    {"documentLocation", "documentLocation", NID_documentLocation, 10, &so[3538]},
-+    {"homeTelephoneNumber", "homeTelephoneNumber", NID_homeTelephoneNumber, 10, &so[3548]},
-+    {"secretary", "secretary", NID_secretary, 10, &so[3558]},
-+    {"otherMailbox", "otherMailbox", NID_otherMailbox, 10, &so[3568]},
-+    {"lastModifiedTime", "lastModifiedTime", NID_lastModifiedTime, 10, &so[3578]},
-+    {"lastModifiedBy", "lastModifiedBy", NID_lastModifiedBy, 10, &so[3588]},
-+    {"aRecord", "aRecord", NID_aRecord, 10, &so[3598]},
-+    {"pilotAttributeType27", "pilotAttributeType27", NID_pilotAttributeType27, 10, &so[3608]},
-+    {"mXRecord", "mXRecord", NID_mXRecord, 10, &so[3618]},
-+    {"nSRecord", "nSRecord", NID_nSRecord, 10, &so[3628]},
-+    {"sOARecord", "sOARecord", NID_sOARecord, 10, &so[3638]},
-+    {"cNAMERecord", "cNAMERecord", NID_cNAMERecord, 10, &so[3648]},
-+    {"associatedDomain", "associatedDomain", NID_associatedDomain, 10, &so[3658]},
-+    {"associatedName", "associatedName", NID_associatedName, 10, &so[3668]},
-+    {"homePostalAddress", "homePostalAddress", NID_homePostalAddress, 10, &so[3678]},
-+    {"personalTitle", "personalTitle", NID_personalTitle, 10, &so[3688]},
-+    {"mobileTelephoneNumber", "mobileTelephoneNumber", NID_mobileTelephoneNumber, 10, &so[3698]},
-+    {"pagerTelephoneNumber", "pagerTelephoneNumber", NID_pagerTelephoneNumber, 10, &so[3708]},
-+    {"friendlyCountryName", "friendlyCountryName", NID_friendlyCountryName, 10, &so[3718]},
-+    {"organizationalStatus", "organizationalStatus", NID_organizationalStatus, 10, &so[3728]},
-+    {"janetMailbox", "janetMailbox", NID_janetMailbox, 10, &so[3738]},
-+    {"mailPreferenceOption", "mailPreferenceOption", NID_mailPreferenceOption, 10, &so[3748]},
-+    {"buildingName", "buildingName", NID_buildingName, 10, &so[3758]},
-+    {"dSAQuality", "dSAQuality", NID_dSAQuality, 10, &so[3768]},
-+    {"singleLevelQuality", "singleLevelQuality", NID_singleLevelQuality, 10, &so[3778]},
-+    {"subtreeMinimumQuality", "subtreeMinimumQuality", NID_subtreeMinimumQuality, 10, &so[3788]},
-+    {"subtreeMaximumQuality", "subtreeMaximumQuality", NID_subtreeMaximumQuality, 10, &so[3798]},
-+    {"personalSignature", "personalSignature", NID_personalSignature, 10, &so[3808]},
-+    {"dITRedirect", "dITRedirect", NID_dITRedirect, 10, &so[3818]},
-+    {"audio", "audio", NID_audio, 10, &so[3828]},
-+    {"documentPublisher", "documentPublisher", NID_documentPublisher, 10, &so[3838]},
-+    {"x500UniqueIdentifier", "x500UniqueIdentifier", NID_x500UniqueIdentifier, 3, &so[3848]},
-+    {"mime-mhs", "MIME MHS", NID_mime_mhs, 5, &so[3851]},
-+    {"mime-mhs-headings", "mime-mhs-headings", NID_mime_mhs_headings, 6, &so[3856]},
-+    {"mime-mhs-bodies", "mime-mhs-bodies", NID_mime_mhs_bodies, 6, &so[3862]},
-+    {"id-hex-partial-message", "id-hex-partial-message", NID_id_hex_partial_message, 7, &so[3868]},
-+    {"id-hex-multipart-message", "id-hex-multipart-message", NID_id_hex_multipart_message, 7, &so[3875]},
-+    {"generationQualifier", "generationQualifier", NID_generationQualifier, 3, &so[3882]},
-+    {"pseudonym", "pseudonym", NID_pseudonym, 3, &so[3885]},
-+    { NULL, NULL, NID_undef },
-+    {"id-set", "Secure Electronic Transactions", NID_id_set, 2, &so[3888]},
-+    {"set-ctype", "content types", NID_set_ctype, 3, &so[3890]},
-+    {"set-msgExt", "message extensions", NID_set_msgExt, 3, &so[3893]},
-+    {"set-attr", "set-attr", NID_set_attr, 3, &so[3896]},
-+    {"set-policy", "set-policy", NID_set_policy, 3, &so[3899]},
-+    {"set-certExt", "certificate extensions", NID_set_certExt, 3, &so[3902]},
-+    {"set-brand", "set-brand", NID_set_brand, 3, &so[3905]},
-+    {"setct-PANData", "setct-PANData", NID_setct_PANData, 4, &so[3908]},
-+    {"setct-PANToken", "setct-PANToken", NID_setct_PANToken, 4, &so[3912]},
-+    {"setct-PANOnly", "setct-PANOnly", NID_setct_PANOnly, 4, &so[3916]},
-+    {"setct-OIData", "setct-OIData", NID_setct_OIData, 4, &so[3920]},
-+    {"setct-PI", "setct-PI", NID_setct_PI, 4, &so[3924]},
-+    {"setct-PIData", "setct-PIData", NID_setct_PIData, 4, &so[3928]},
-+    {"setct-PIDataUnsigned", "setct-PIDataUnsigned", NID_setct_PIDataUnsigned, 4, &so[3932]},
-+    {"setct-HODInput", "setct-HODInput", NID_setct_HODInput, 4, &so[3936]},
-+    {"setct-AuthResBaggage", "setct-AuthResBaggage", NID_setct_AuthResBaggage, 4, &so[3940]},
-+    {"setct-AuthRevReqBaggage", "setct-AuthRevReqBaggage", NID_setct_AuthRevReqBaggage, 4, &so[3944]},
-+    {"setct-AuthRevResBaggage", "setct-AuthRevResBaggage", NID_setct_AuthRevResBaggage, 4, &so[3948]},
-+    {"setct-CapTokenSeq", "setct-CapTokenSeq", NID_setct_CapTokenSeq, 4, &so[3952]},
-+    {"setct-PInitResData", "setct-PInitResData", NID_setct_PInitResData, 4, &so[3956]},
-+    {"setct-PI-TBS", "setct-PI-TBS", NID_setct_PI_TBS, 4, &so[3960]},
-+    {"setct-PResData", "setct-PResData", NID_setct_PResData, 4, &so[3964]},
-+    {"setct-AuthReqTBS", "setct-AuthReqTBS", NID_setct_AuthReqTBS, 4, &so[3968]},
-+    {"setct-AuthResTBS", "setct-AuthResTBS", NID_setct_AuthResTBS, 4, &so[3972]},
-+    {"setct-AuthResTBSX", "setct-AuthResTBSX", NID_setct_AuthResTBSX, 4, &so[3976]},
-+    {"setct-AuthTokenTBS", "setct-AuthTokenTBS", NID_setct_AuthTokenTBS, 4, &so[3980]},
-+    {"setct-CapTokenData", "setct-CapTokenData", NID_setct_CapTokenData, 4, &so[3984]},
-+    {"setct-CapTokenTBS", "setct-CapTokenTBS", NID_setct_CapTokenTBS, 4, &so[3988]},
-+    {"setct-AcqCardCodeMsg", "setct-AcqCardCodeMsg", NID_setct_AcqCardCodeMsg, 4, &so[3992]},
-+    {"setct-AuthRevReqTBS", "setct-AuthRevReqTBS", NID_setct_AuthRevReqTBS, 4, &so[3996]},
-+    {"setct-AuthRevResData", "setct-AuthRevResData", NID_setct_AuthRevResData, 4, &so[4000]},
-+    {"setct-AuthRevResTBS", "setct-AuthRevResTBS", NID_setct_AuthRevResTBS, 4, &so[4004]},
-+    {"setct-CapReqTBS", "setct-CapReqTBS", NID_setct_CapReqTBS, 4, &so[4008]},
-+    {"setct-CapReqTBSX", "setct-CapReqTBSX", NID_setct_CapReqTBSX, 4, &so[4012]},
-+    {"setct-CapResData", "setct-CapResData", NID_setct_CapResData, 4, &so[4016]},
-+    {"setct-CapRevReqTBS", "setct-CapRevReqTBS", NID_setct_CapRevReqTBS, 4, &so[4020]},
-+    {"setct-CapRevReqTBSX", "setct-CapRevReqTBSX", NID_setct_CapRevReqTBSX, 4, &so[4024]},
-+    {"setct-CapRevResData", "setct-CapRevResData", NID_setct_CapRevResData, 4, &so[4028]},
-+    {"setct-CredReqTBS", "setct-CredReqTBS", NID_setct_CredReqTBS, 4, &so[4032]},
-+    {"setct-CredReqTBSX", "setct-CredReqTBSX", NID_setct_CredReqTBSX, 4, &so[4036]},
-+    {"setct-CredResData", "setct-CredResData", NID_setct_CredResData, 4, &so[4040]},
-+    {"setct-CredRevReqTBS", "setct-CredRevReqTBS", NID_setct_CredRevReqTBS, 4, &so[4044]},
-+    {"setct-CredRevReqTBSX", "setct-CredRevReqTBSX", NID_setct_CredRevReqTBSX, 4, &so[4048]},
-+    {"setct-CredRevResData", "setct-CredRevResData", NID_setct_CredRevResData, 4, &so[4052]},
-+    {"setct-PCertReqData", "setct-PCertReqData", NID_setct_PCertReqData, 4, &so[4056]},
-+    {"setct-PCertResTBS", "setct-PCertResTBS", NID_setct_PCertResTBS, 4, &so[4060]},
-+    {"setct-BatchAdminReqData", "setct-BatchAdminReqData", NID_setct_BatchAdminReqData, 4, &so[4064]},
-+    {"setct-BatchAdminResData", "setct-BatchAdminResData", NID_setct_BatchAdminResData, 4, &so[4068]},
-+    {"setct-CardCInitResTBS", "setct-CardCInitResTBS", NID_setct_CardCInitResTBS, 4, &so[4072]},
-+    {"setct-MeAqCInitResTBS", "setct-MeAqCInitResTBS", NID_setct_MeAqCInitResTBS, 4, &so[4076]},
-+    {"setct-RegFormResTBS", "setct-RegFormResTBS", NID_setct_RegFormResTBS, 4, &so[4080]},
-+    {"setct-CertReqData", "setct-CertReqData", NID_setct_CertReqData, 4, &so[4084]},
-+    {"setct-CertReqTBS", "setct-CertReqTBS", NID_setct_CertReqTBS, 4, &so[4088]},
-+    {"setct-CertResData", "setct-CertResData", NID_setct_CertResData, 4, &so[4092]},
-+    {"setct-CertInqReqTBS", "setct-CertInqReqTBS", NID_setct_CertInqReqTBS, 4, &so[4096]},
-+    {"setct-ErrorTBS", "setct-ErrorTBS", NID_setct_ErrorTBS, 4, &so[4100]},
-+    {"setct-PIDualSignedTBE", "setct-PIDualSignedTBE", NID_setct_PIDualSignedTBE, 4, &so[4104]},
-+    {"setct-PIUnsignedTBE", "setct-PIUnsignedTBE", NID_setct_PIUnsignedTBE, 4, &so[4108]},
-+    {"setct-AuthReqTBE", "setct-AuthReqTBE", NID_setct_AuthReqTBE, 4, &so[4112]},
-+    {"setct-AuthResTBE", "setct-AuthResTBE", NID_setct_AuthResTBE, 4, &so[4116]},
-+    {"setct-AuthResTBEX", "setct-AuthResTBEX", NID_setct_AuthResTBEX, 4, &so[4120]},
-+    {"setct-AuthTokenTBE", "setct-AuthTokenTBE", NID_setct_AuthTokenTBE, 4, &so[4124]},
-+    {"setct-CapTokenTBE", "setct-CapTokenTBE", NID_setct_CapTokenTBE, 4, &so[4128]},
-+    {"setct-CapTokenTBEX", "setct-CapTokenTBEX", NID_setct_CapTokenTBEX, 4, &so[4132]},
-+    {"setct-AcqCardCodeMsgTBE", "setct-AcqCardCodeMsgTBE", NID_setct_AcqCardCodeMsgTBE, 4, &so[4136]},
-+    {"setct-AuthRevReqTBE", "setct-AuthRevReqTBE", NID_setct_AuthRevReqTBE, 4, &so[4140]},
-+    {"setct-AuthRevResTBE", "setct-AuthRevResTBE", NID_setct_AuthRevResTBE, 4, &so[4144]},
-+    {"setct-AuthRevResTBEB", "setct-AuthRevResTBEB", NID_setct_AuthRevResTBEB, 4, &so[4148]},
-+    {"setct-CapReqTBE", "setct-CapReqTBE", NID_setct_CapReqTBE, 4, &so[4152]},
-+    {"setct-CapReqTBEX", "setct-CapReqTBEX", NID_setct_CapReqTBEX, 4, &so[4156]},
-+    {"setct-CapResTBE", "setct-CapResTBE", NID_setct_CapResTBE, 4, &so[4160]},
-+    {"setct-CapRevReqTBE", "setct-CapRevReqTBE", NID_setct_CapRevReqTBE, 4, &so[4164]},
-+    {"setct-CapRevReqTBEX", "setct-CapRevReqTBEX", NID_setct_CapRevReqTBEX, 4, &so[4168]},
-+    {"setct-CapRevResTBE", "setct-CapRevResTBE", NID_setct_CapRevResTBE, 4, &so[4172]},
-+    {"setct-CredReqTBE", "setct-CredReqTBE", NID_setct_CredReqTBE, 4, &so[4176]},
-+    {"setct-CredReqTBEX", "setct-CredReqTBEX", NID_setct_CredReqTBEX, 4, &so[4180]},
-+    {"setct-CredResTBE", "setct-CredResTBE", NID_setct_CredResTBE, 4, &so[4184]},
-+    {"setct-CredRevReqTBE", "setct-CredRevReqTBE", NID_setct_CredRevReqTBE, 4, &so[4188]},
-+    {"setct-CredRevReqTBEX", "setct-CredRevReqTBEX", NID_setct_CredRevReqTBEX, 4, &so[4192]},
-+    {"setct-CredRevResTBE", "setct-CredRevResTBE", NID_setct_CredRevResTBE, 4, &so[4196]},
-+    {"setct-BatchAdminReqTBE", "setct-BatchAdminReqTBE", NID_setct_BatchAdminReqTBE, 4, &so[4200]},
-+    {"setct-BatchAdminResTBE", "setct-BatchAdminResTBE", NID_setct_BatchAdminResTBE, 4, &so[4204]},
-+    {"setct-RegFormReqTBE", "setct-RegFormReqTBE", NID_setct_RegFormReqTBE, 4, &so[4208]},
-+    {"setct-CertReqTBE", "setct-CertReqTBE", NID_setct_CertReqTBE, 4, &so[4212]},
-+    {"setct-CertReqTBEX", "setct-CertReqTBEX", NID_setct_CertReqTBEX, 4, &so[4216]},
-+    {"setct-CertResTBE", "setct-CertResTBE", NID_setct_CertResTBE, 4, &so[4220]},
-+    {"setct-CRLNotificationTBS", "setct-CRLNotificationTBS", NID_setct_CRLNotificationTBS, 4, &so[4224]},
-+    {"setct-CRLNotificationResTBS", "setct-CRLNotificationResTBS", NID_setct_CRLNotificationResTBS, 4, &so[4228]},
-+    {"setct-BCIDistributionTBS", "setct-BCIDistributionTBS", NID_setct_BCIDistributionTBS, 4, &so[4232]},
-+    {"setext-genCrypt", "generic cryptogram", NID_setext_genCrypt, 4, &so[4236]},
-+    {"setext-miAuth", "merchant initiated auth", NID_setext_miAuth, 4, &so[4240]},
-+    {"setext-pinSecure", "setext-pinSecure", NID_setext_pinSecure, 4, &so[4244]},
-+    {"setext-pinAny", "setext-pinAny", NID_setext_pinAny, 4, &so[4248]},
-+    {"setext-track2", "setext-track2", NID_setext_track2, 4, &so[4252]},
-+    {"setext-cv", "additional verification", NID_setext_cv, 4, &so[4256]},
-+    {"set-policy-root", "set-policy-root", NID_set_policy_root, 4, &so[4260]},
-+    {"setCext-hashedRoot", "setCext-hashedRoot", NID_setCext_hashedRoot, 4, &so[4264]},
-+    {"setCext-certType", "setCext-certType", NID_setCext_certType, 4, &so[4268]},
-+    {"setCext-merchData", "setCext-merchData", NID_setCext_merchData, 4, &so[4272]},
-+    {"setCext-cCertRequired", "setCext-cCertRequired", NID_setCext_cCertRequired, 4, &so[4276]},
-+    {"setCext-tunneling", "setCext-tunneling", NID_setCext_tunneling, 4, &so[4280]},
-+    {"setCext-setExt", "setCext-setExt", NID_setCext_setExt, 4, &so[4284]},
-+    {"setCext-setQualf", "setCext-setQualf", NID_setCext_setQualf, 4, &so[4288]},
-+    {"setCext-PGWYcapabilities", "setCext-PGWYcapabilities", NID_setCext_PGWYcapabilities, 4, &so[4292]},
-+    {"setCext-TokenIdentifier", "setCext-TokenIdentifier", NID_setCext_TokenIdentifier, 4, &so[4296]},
-+    {"setCext-Track2Data", "setCext-Track2Data", NID_setCext_Track2Data, 4, &so[4300]},
-+    {"setCext-TokenType", "setCext-TokenType", NID_setCext_TokenType, 4, &so[4304]},
-+    {"setCext-IssuerCapabilities", "setCext-IssuerCapabilities", NID_setCext_IssuerCapabilities, 4, &so[4308]},
-+    {"setAttr-Cert", "setAttr-Cert", NID_setAttr_Cert, 4, &so[4312]},
-+    {"setAttr-PGWYcap", "payment gateway capabilities", NID_setAttr_PGWYcap, 4, &so[4316]},
-+    {"setAttr-TokenType", "setAttr-TokenType", NID_setAttr_TokenType, 4, &so[4320]},
-+    {"setAttr-IssCap", "issuer capabilities", NID_setAttr_IssCap, 4, &so[4324]},
-+    {"set-rootKeyThumb", "set-rootKeyThumb", NID_set_rootKeyThumb, 5, &so[4328]},
-+    {"set-addPolicy", "set-addPolicy", NID_set_addPolicy, 5, &so[4333]},
-+    {"setAttr-Token-EMV", "setAttr-Token-EMV", NID_setAttr_Token_EMV, 5, &so[4338]},
-+    {"setAttr-Token-B0Prime", "setAttr-Token-B0Prime", NID_setAttr_Token_B0Prime, 5, &so[4343]},
-+    {"setAttr-IssCap-CVM", "setAttr-IssCap-CVM", NID_setAttr_IssCap_CVM, 5, &so[4348]},
-+    {"setAttr-IssCap-T2", "setAttr-IssCap-T2", NID_setAttr_IssCap_T2, 5, &so[4353]},
-+    {"setAttr-IssCap-Sig", "setAttr-IssCap-Sig", NID_setAttr_IssCap_Sig, 5, &so[4358]},
-+    {"setAttr-GenCryptgrm", "generate cryptogram", NID_setAttr_GenCryptgrm, 6, &so[4363]},
-+    {"setAttr-T2Enc", "encrypted track 2", NID_setAttr_T2Enc, 6, &so[4369]},
-+    {"setAttr-T2cleartxt", "cleartext track 2", NID_setAttr_T2cleartxt, 6, &so[4375]},
-+    {"setAttr-TokICCsig", "ICC or token signature", NID_setAttr_TokICCsig, 6, &so[4381]},
-+    {"setAttr-SecDevSig", "secure device signature", NID_setAttr_SecDevSig, 6, &so[4387]},
-+    {"set-brand-IATA-ATA", "set-brand-IATA-ATA", NID_set_brand_IATA_ATA, 4, &so[4393]},
-+    {"set-brand-Diners", "set-brand-Diners", NID_set_brand_Diners, 4, &so[4397]},
-+    {"set-brand-AmericanExpress", "set-brand-AmericanExpress", NID_set_brand_AmericanExpress, 4, &so[4401]},
-+    {"set-brand-JCB", "set-brand-JCB", NID_set_brand_JCB, 4, &so[4405]},
-+    {"set-brand-Visa", "set-brand-Visa", NID_set_brand_Visa, 4, &so[4409]},
-+    {"set-brand-MasterCard", "set-brand-MasterCard", NID_set_brand_MasterCard, 4, &so[4413]},
-+    {"set-brand-Novus", "set-brand-Novus", NID_set_brand_Novus, 5, &so[4417]},
-+    {"DES-CDMF", "des-cdmf", NID_des_cdmf, 8, &so[4422]},
-+    {"rsaOAEPEncryptionSET", "rsaOAEPEncryptionSET", NID_rsaOAEPEncryptionSET, 9, &so[4430]},
-+    {"ITU-T", "itu-t", NID_itu_t},
-+    {"JOINT-ISO-ITU-T", "joint-iso-itu-t", NID_joint_iso_itu_t},
-+    {"international-organizations", "International Organizations", NID_international_organizations, 1, &so[4439]},
-+    {"msSmartcardLogin", "Microsoft Smartcardlogin", NID_ms_smartcard_login, 10, &so[4440]},
-+    {"msUPN", "Microsoft Universal Principal Name", NID_ms_upn, 10, &so[4450]},
-+    {"AES-128-CFB1", "aes-128-cfb1", NID_aes_128_cfb1},
-+    {"AES-192-CFB1", "aes-192-cfb1", NID_aes_192_cfb1},
-+    {"AES-256-CFB1", "aes-256-cfb1", NID_aes_256_cfb1},
-+    {"AES-128-CFB8", "aes-128-cfb8", NID_aes_128_cfb8},
-+    {"AES-192-CFB8", "aes-192-cfb8", NID_aes_192_cfb8},
-+    {"AES-256-CFB8", "aes-256-cfb8", NID_aes_256_cfb8},
-+    {"DES-CFB1", "des-cfb1", NID_des_cfb1},
-+    {"DES-CFB8", "des-cfb8", NID_des_cfb8},
-+    {"DES-EDE3-CFB1", "des-ede3-cfb1", NID_des_ede3_cfb1},
-+    {"DES-EDE3-CFB8", "des-ede3-cfb8", NID_des_ede3_cfb8},
-+    {"street", "streetAddress", NID_streetAddress, 3, &so[4460]},
-+    {"postalCode", "postalCode", NID_postalCode, 3, &so[4463]},
-+    {"id-ppl", "id-ppl", NID_id_ppl, 7, &so[4466]},
-+    {"proxyCertInfo", "Proxy Certificate Information", NID_proxyCertInfo, 8, &so[4473]},
-+    {"id-ppl-anyLanguage", "Any language", NID_id_ppl_anyLanguage, 8, &so[4481]},
-+    {"id-ppl-inheritAll", "Inherit all", NID_id_ppl_inheritAll, 8, &so[4489]},
-+    {"nameConstraints", "X509v3 Name Constraints", NID_name_constraints, 3, &so[4497]},
-+    {"id-ppl-independent", "Independent", NID_Independent, 8, &so[4500]},
-+    {"RSA-SHA256", "sha256WithRSAEncryption", NID_sha256WithRSAEncryption, 9, &so[4508]},
-+    {"RSA-SHA384", "sha384WithRSAEncryption", NID_sha384WithRSAEncryption, 9, &so[4517]},
-+    {"RSA-SHA512", "sha512WithRSAEncryption", NID_sha512WithRSAEncryption, 9, &so[4526]},
-+    {"RSA-SHA224", "sha224WithRSAEncryption", NID_sha224WithRSAEncryption, 9, &so[4535]},
-+    {"SHA256", "sha256", NID_sha256, 9, &so[4544]},
-+    {"SHA384", "sha384", NID_sha384, 9, &so[4553]},
-+    {"SHA512", "sha512", NID_sha512, 9, &so[4562]},
-+    {"SHA224", "sha224", NID_sha224, 9, &so[4571]},
-+    {"identified-organization", "identified-organization", NID_identified_organization, 1, &so[4580]},
-+    {"certicom-arc", "certicom-arc", NID_certicom_arc, 3, &so[4581]},
-+    {"wap", "wap", NID_wap, 2, &so[4584]},
-+    {"wap-wsg", "wap-wsg", NID_wap_wsg, 3, &so[4586]},
-+    {"id-characteristic-two-basis", "id-characteristic-two-basis", NID_X9_62_id_characteristic_two_basis, 8, &so[4589]},
-+    {"onBasis", "onBasis", NID_X9_62_onBasis, 9, &so[4597]},
-+    {"tpBasis", "tpBasis", NID_X9_62_tpBasis, 9, &so[4606]},
-+    {"ppBasis", "ppBasis", NID_X9_62_ppBasis, 9, &so[4615]},
-+    {"c2pnb163v1", "c2pnb163v1", NID_X9_62_c2pnb163v1, 8, &so[4624]},
-+    {"c2pnb163v2", "c2pnb163v2", NID_X9_62_c2pnb163v2, 8, &so[4632]},
-+    {"c2pnb163v3", "c2pnb163v3", NID_X9_62_c2pnb163v3, 8, &so[4640]},
-+    {"c2pnb176v1", "c2pnb176v1", NID_X9_62_c2pnb176v1, 8, &so[4648]},
-+    {"c2tnb191v1", "c2tnb191v1", NID_X9_62_c2tnb191v1, 8, &so[4656]},
-+    {"c2tnb191v2", "c2tnb191v2", NID_X9_62_c2tnb191v2, 8, &so[4664]},
-+    {"c2tnb191v3", "c2tnb191v3", NID_X9_62_c2tnb191v3, 8, &so[4672]},
-+    {"c2onb191v4", "c2onb191v4", NID_X9_62_c2onb191v4, 8, &so[4680]},
-+    {"c2onb191v5", "c2onb191v5", NID_X9_62_c2onb191v5, 8, &so[4688]},
-+    {"c2pnb208w1", "c2pnb208w1", NID_X9_62_c2pnb208w1, 8, &so[4696]},
-+    {"c2tnb239v1", "c2tnb239v1", NID_X9_62_c2tnb239v1, 8, &so[4704]},
-+    {"c2tnb239v2", "c2tnb239v2", NID_X9_62_c2tnb239v2, 8, &so[4712]},
-+    {"c2tnb239v3", "c2tnb239v3", NID_X9_62_c2tnb239v3, 8, &so[4720]},
-+    {"c2onb239v4", "c2onb239v4", NID_X9_62_c2onb239v4, 8, &so[4728]},
-+    {"c2onb239v5", "c2onb239v5", NID_X9_62_c2onb239v5, 8, &so[4736]},
-+    {"c2pnb272w1", "c2pnb272w1", NID_X9_62_c2pnb272w1, 8, &so[4744]},
-+    {"c2pnb304w1", "c2pnb304w1", NID_X9_62_c2pnb304w1, 8, &so[4752]},
-+    {"c2tnb359v1", "c2tnb359v1", NID_X9_62_c2tnb359v1, 8, &so[4760]},
-+    {"c2pnb368w1", "c2pnb368w1", NID_X9_62_c2pnb368w1, 8, &so[4768]},
-+    {"c2tnb431r1", "c2tnb431r1", NID_X9_62_c2tnb431r1, 8, &so[4776]},
-+    {"secp112r1", "secp112r1", NID_secp112r1, 5, &so[4784]},
-+    {"secp112r2", "secp112r2", NID_secp112r2, 5, &so[4789]},
-+    {"secp128r1", "secp128r1", NID_secp128r1, 5, &so[4794]},
-+    {"secp128r2", "secp128r2", NID_secp128r2, 5, &so[4799]},
-+    {"secp160k1", "secp160k1", NID_secp160k1, 5, &so[4804]},
-+    {"secp160r1", "secp160r1", NID_secp160r1, 5, &so[4809]},
-+    {"secp160r2", "secp160r2", NID_secp160r2, 5, &so[4814]},
-+    {"secp192k1", "secp192k1", NID_secp192k1, 5, &so[4819]},
-+    {"secp224k1", "secp224k1", NID_secp224k1, 5, &so[4824]},
-+    {"secp224r1", "secp224r1", NID_secp224r1, 5, &so[4829]},
-+    {"secp256k1", "secp256k1", NID_secp256k1, 5, &so[4834]},
-+    {"secp384r1", "secp384r1", NID_secp384r1, 5, &so[4839]},
-+    {"secp521r1", "secp521r1", NID_secp521r1, 5, &so[4844]},
-+    {"sect113r1", "sect113r1", NID_sect113r1, 5, &so[4849]},
-+    {"sect113r2", "sect113r2", NID_sect113r2, 5, &so[4854]},
-+    {"sect131r1", "sect131r1", NID_sect131r1, 5, &so[4859]},
-+    {"sect131r2", "sect131r2", NID_sect131r2, 5, &so[4864]},
-+    {"sect163k1", "sect163k1", NID_sect163k1, 5, &so[4869]},
-+    {"sect163r1", "sect163r1", NID_sect163r1, 5, &so[4874]},
-+    {"sect163r2", "sect163r2", NID_sect163r2, 5, &so[4879]},
-+    {"sect193r1", "sect193r1", NID_sect193r1, 5, &so[4884]},
-+    {"sect193r2", "sect193r2", NID_sect193r2, 5, &so[4889]},
-+    {"sect233k1", "sect233k1", NID_sect233k1, 5, &so[4894]},
-+    {"sect233r1", "sect233r1", NID_sect233r1, 5, &so[4899]},
-+    {"sect239k1", "sect239k1", NID_sect239k1, 5, &so[4904]},
-+    {"sect283k1", "sect283k1", NID_sect283k1, 5, &so[4909]},
-+    {"sect283r1", "sect283r1", NID_sect283r1, 5, &so[4914]},
-+    {"sect409k1", "sect409k1", NID_sect409k1, 5, &so[4919]},
-+    {"sect409r1", "sect409r1", NID_sect409r1, 5, &so[4924]},
-+    {"sect571k1", "sect571k1", NID_sect571k1, 5, &so[4929]},
-+    {"sect571r1", "sect571r1", NID_sect571r1, 5, &so[4934]},
-+    {"wap-wsg-idm-ecid-wtls1", "wap-wsg-idm-ecid-wtls1", NID_wap_wsg_idm_ecid_wtls1, 5, &so[4939]},
-+    {"wap-wsg-idm-ecid-wtls3", "wap-wsg-idm-ecid-wtls3", NID_wap_wsg_idm_ecid_wtls3, 5, &so[4944]},
-+    {"wap-wsg-idm-ecid-wtls4", "wap-wsg-idm-ecid-wtls4", NID_wap_wsg_idm_ecid_wtls4, 5, &so[4949]},
-+    {"wap-wsg-idm-ecid-wtls5", "wap-wsg-idm-ecid-wtls5", NID_wap_wsg_idm_ecid_wtls5, 5, &so[4954]},
-+    {"wap-wsg-idm-ecid-wtls6", "wap-wsg-idm-ecid-wtls6", NID_wap_wsg_idm_ecid_wtls6, 5, &so[4959]},
-+    {"wap-wsg-idm-ecid-wtls7", "wap-wsg-idm-ecid-wtls7", NID_wap_wsg_idm_ecid_wtls7, 5, &so[4964]},
-+    {"wap-wsg-idm-ecid-wtls8", "wap-wsg-idm-ecid-wtls8", NID_wap_wsg_idm_ecid_wtls8, 5, &so[4969]},
-+    {"wap-wsg-idm-ecid-wtls9", "wap-wsg-idm-ecid-wtls9", NID_wap_wsg_idm_ecid_wtls9, 5, &so[4974]},
-+    {"wap-wsg-idm-ecid-wtls10", "wap-wsg-idm-ecid-wtls10", NID_wap_wsg_idm_ecid_wtls10, 5, &so[4979]},
-+    {"wap-wsg-idm-ecid-wtls11", "wap-wsg-idm-ecid-wtls11", NID_wap_wsg_idm_ecid_wtls11, 5, &so[4984]},
-+    {"wap-wsg-idm-ecid-wtls12", "wap-wsg-idm-ecid-wtls12", NID_wap_wsg_idm_ecid_wtls12, 5, &so[4989]},
-+    {"anyPolicy", "X509v3 Any Policy", NID_any_policy, 4, &so[4994]},
-+    {"policyMappings", "X509v3 Policy Mappings", NID_policy_mappings, 3, &so[4998]},
-+    {"inhibitAnyPolicy", "X509v3 Inhibit Any Policy", NID_inhibit_any_policy, 3, &so[5001]},
-+    {"Oakley-EC2N-3", "ipsec3", NID_ipsec3},
-+    {"Oakley-EC2N-4", "ipsec4", NID_ipsec4},
-+    {"CAMELLIA-128-CBC", "camellia-128-cbc", NID_camellia_128_cbc, 11, &so[5004]},
-+    {"CAMELLIA-192-CBC", "camellia-192-cbc", NID_camellia_192_cbc, 11, &so[5015]},
-+    {"CAMELLIA-256-CBC", "camellia-256-cbc", NID_camellia_256_cbc, 11, &so[5026]},
-+    {"CAMELLIA-128-ECB", "camellia-128-ecb", NID_camellia_128_ecb, 8, &so[5037]},
-+    {"CAMELLIA-192-ECB", "camellia-192-ecb", NID_camellia_192_ecb, 8, &so[5045]},
-+    {"CAMELLIA-256-ECB", "camellia-256-ecb", NID_camellia_256_ecb, 8, &so[5053]},
-+    {"CAMELLIA-128-CFB", "camellia-128-cfb", NID_camellia_128_cfb128, 8, &so[5061]},
-+    {"CAMELLIA-192-CFB", "camellia-192-cfb", NID_camellia_192_cfb128, 8, &so[5069]},
-+    {"CAMELLIA-256-CFB", "camellia-256-cfb", NID_camellia_256_cfb128, 8, &so[5077]},
-+    {"CAMELLIA-128-CFB1", "camellia-128-cfb1", NID_camellia_128_cfb1},
-+    {"CAMELLIA-192-CFB1", "camellia-192-cfb1", NID_camellia_192_cfb1},
-+    {"CAMELLIA-256-CFB1", "camellia-256-cfb1", NID_camellia_256_cfb1},
-+    {"CAMELLIA-128-CFB8", "camellia-128-cfb8", NID_camellia_128_cfb8},
-+    {"CAMELLIA-192-CFB8", "camellia-192-cfb8", NID_camellia_192_cfb8},
-+    {"CAMELLIA-256-CFB8", "camellia-256-cfb8", NID_camellia_256_cfb8},
-+    {"CAMELLIA-128-OFB", "camellia-128-ofb", NID_camellia_128_ofb128, 8, &so[5085]},
-+    {"CAMELLIA-192-OFB", "camellia-192-ofb", NID_camellia_192_ofb128, 8, &so[5093]},
-+    {"CAMELLIA-256-OFB", "camellia-256-ofb", NID_camellia_256_ofb128, 8, &so[5101]},
-+    {"subjectDirectoryAttributes", "X509v3 Subject Directory Attributes", NID_subject_directory_attributes, 3, &so[5109]},
-+    {"issuingDistributionPoint", "X509v3 Issuing Distribution Point", NID_issuing_distribution_point, 3, &so[5112]},
-+    {"certificateIssuer", "X509v3 Certificate Issuer", NID_certificate_issuer, 3, &so[5115]},
-+    { NULL, NULL, NID_undef },
-+    {"KISA", "kisa", NID_kisa, 6, &so[5118]},
-+    { NULL, NULL, NID_undef },
-+    { NULL, NULL, NID_undef },
-+    {"SEED-ECB", "seed-ecb", NID_seed_ecb, 8, &so[5124]},
-+    {"SEED-CBC", "seed-cbc", NID_seed_cbc, 8, &so[5132]},
-+    {"SEED-OFB", "seed-ofb", NID_seed_ofb128, 8, &so[5140]},
-+    {"SEED-CFB", "seed-cfb", NID_seed_cfb128, 8, &so[5148]},
-+    {"HMAC-MD5", "hmac-md5", NID_hmac_md5, 8, &so[5156]},
-+    {"HMAC-SHA1", "hmac-sha1", NID_hmac_sha1, 8, &so[5164]},
-+    {"id-PasswordBasedMAC", "password based MAC", NID_id_PasswordBasedMAC, 9, &so[5172]},
-+    {"id-DHBasedMac", "Diffie-Hellman based MAC", NID_id_DHBasedMac, 9, &so[5181]},
-+    {"id-it-suppLangTags", "id-it-suppLangTags", NID_id_it_suppLangTags, 8, &so[5190]},
-+    {"caRepository", "CA Repository", NID_caRepository, 8, &so[5198]},
-+    {"id-smime-ct-compressedData", "id-smime-ct-compressedData", NID_id_smime_ct_compressedData, 11, &so[5206]},
-+    {"id-ct-asciiTextWithCRLF", "id-ct-asciiTextWithCRLF", NID_id_ct_asciiTextWithCRLF, 11, &so[5217]},
-+    {"id-aes128-wrap", "id-aes128-wrap", NID_id_aes128_wrap, 9, &so[5228]},
-+    {"id-aes192-wrap", "id-aes192-wrap", NID_id_aes192_wrap, 9, &so[5237]},
-+    {"id-aes256-wrap", "id-aes256-wrap", NID_id_aes256_wrap, 9, &so[5246]},
-+    {"ecdsa-with-Recommended", "ecdsa-with-Recommended", NID_ecdsa_with_Recommended, 7, &so[5255]},
-+    {"ecdsa-with-Specified", "ecdsa-with-Specified", NID_ecdsa_with_Specified, 7, &so[5262]},
-+    {"ecdsa-with-SHA224", "ecdsa-with-SHA224", NID_ecdsa_with_SHA224, 8, &so[5269]},
-+    {"ecdsa-with-SHA256", "ecdsa-with-SHA256", NID_ecdsa_with_SHA256, 8, &so[5277]},
-+    {"ecdsa-with-SHA384", "ecdsa-with-SHA384", NID_ecdsa_with_SHA384, 8, &so[5285]},
-+    {"ecdsa-with-SHA512", "ecdsa-with-SHA512", NID_ecdsa_with_SHA512, 8, &so[5293]},
-+    {"hmacWithMD5", "hmacWithMD5", NID_hmacWithMD5, 8, &so[5301]},
-+    {"hmacWithSHA224", "hmacWithSHA224", NID_hmacWithSHA224, 8, &so[5309]},
-+    {"hmacWithSHA256", "hmacWithSHA256", NID_hmacWithSHA256, 8, &so[5317]},
-+    {"hmacWithSHA384", "hmacWithSHA384", NID_hmacWithSHA384, 8, &so[5325]},
-+    {"hmacWithSHA512", "hmacWithSHA512", NID_hmacWithSHA512, 8, &so[5333]},
-+    {"dsa_with_SHA224", "dsa_with_SHA224", NID_dsa_with_SHA224, 9, &so[5341]},
-+    {"dsa_with_SHA256", "dsa_with_SHA256", NID_dsa_with_SHA256, 9, &so[5350]},
-+    {"whirlpool", "whirlpool", NID_whirlpool, 6, &so[5359]},
-+    {"cryptopro", "cryptopro", NID_cryptopro, 5, &so[5365]},
-+    {"cryptocom", "cryptocom", NID_cryptocom, 5, &so[5370]},
-+    {"id-GostR3411-94-with-GostR3410-2001", "GOST R 34.11-94 with GOST R 34.10-2001", NID_id_GostR3411_94_with_GostR3410_2001, 6, &so[5375]},
-+    {"id-GostR3411-94-with-GostR3410-94", "GOST R 34.11-94 with GOST R 34.10-94", NID_id_GostR3411_94_with_GostR3410_94, 6, &so[5381]},
-+    {"md_gost94", "GOST R 34.11-94", NID_id_GostR3411_94, 6, &so[5387]},
-+    {"id-HMACGostR3411-94", "HMAC GOST 34.11-94", NID_id_HMACGostR3411_94, 6, &so[5393]},
-+    {"gost2001", "GOST R 34.10-2001", NID_id_GostR3410_2001, 6, &so[5399]},
-+    {"gost94", "GOST R 34.10-94", NID_id_GostR3410_94, 6, &so[5405]},
-+    {"gost89", "GOST 28147-89", NID_id_Gost28147_89, 6, &so[5411]},
-+    {"gost89-cnt", "gost89-cnt", NID_gost89_cnt},
-+    {"gost-mac", "GOST 28147-89 MAC", NID_id_Gost28147_89_MAC, 6, &so[5417]},
-+    {"prf-gostr3411-94", "GOST R 34.11-94 PRF", NID_id_GostR3411_94_prf, 6, &so[5423]},
-+    {"id-GostR3410-2001DH", "GOST R 34.10-2001 DH", NID_id_GostR3410_2001DH, 6, &so[5429]},
-+    {"id-GostR3410-94DH", "GOST R 34.10-94 DH", NID_id_GostR3410_94DH, 6, &so[5435]},
-+    {"id-Gost28147-89-CryptoPro-KeyMeshing", "id-Gost28147-89-CryptoPro-KeyMeshing", NID_id_Gost28147_89_CryptoPro_KeyMeshing, 7, &so[5441]},
-+    {"id-Gost28147-89-None-KeyMeshing", "id-Gost28147-89-None-KeyMeshing", NID_id_Gost28147_89_None_KeyMeshing, 7, &so[5448]},
-+    {"id-GostR3411-94-TestParamSet", "id-GostR3411-94-TestParamSet", NID_id_GostR3411_94_TestParamSet, 7, &so[5455]},
-+    {"id-GostR3411-94-CryptoProParamSet", "id-GostR3411-94-CryptoProParamSet", NID_id_GostR3411_94_CryptoProParamSet, 7, &so[5462]},
-+    {"id-Gost28147-89-TestParamSet", "id-Gost28147-89-TestParamSet", NID_id_Gost28147_89_TestParamSet, 7, &so[5469]},
-+    {"id-Gost28147-89-CryptoPro-A-ParamSet", "id-Gost28147-89-CryptoPro-A-ParamSet", NID_id_Gost28147_89_CryptoPro_A_ParamSet, 7, &so[5476]},
-+    {"id-Gost28147-89-CryptoPro-B-ParamSet", "id-Gost28147-89-CryptoPro-B-ParamSet", NID_id_Gost28147_89_CryptoPro_B_ParamSet, 7, &so[5483]},
-+    {"id-Gost28147-89-CryptoPro-C-ParamSet", "id-Gost28147-89-CryptoPro-C-ParamSet", NID_id_Gost28147_89_CryptoPro_C_ParamSet, 7, &so[5490]},
-+    {"id-Gost28147-89-CryptoPro-D-ParamSet", "id-Gost28147-89-CryptoPro-D-ParamSet", NID_id_Gost28147_89_CryptoPro_D_ParamSet, 7, &so[5497]},
-+    {"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet, 7, &so[5504]},
-+    {"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet, 7, &so[5511]},
-+    {"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet, 7, &so[5518]},
-+    {"id-GostR3410-94-TestParamSet", "id-GostR3410-94-TestParamSet", NID_id_GostR3410_94_TestParamSet, 7, &so[5525]},
-+    {"id-GostR3410-94-CryptoPro-A-ParamSet", "id-GostR3410-94-CryptoPro-A-ParamSet", NID_id_GostR3410_94_CryptoPro_A_ParamSet, 7, &so[5532]},
-+    {"id-GostR3410-94-CryptoPro-B-ParamSet", "id-GostR3410-94-CryptoPro-B-ParamSet", NID_id_GostR3410_94_CryptoPro_B_ParamSet, 7, &so[5539]},
-+    {"id-GostR3410-94-CryptoPro-C-ParamSet", "id-GostR3410-94-CryptoPro-C-ParamSet", NID_id_GostR3410_94_CryptoPro_C_ParamSet, 7, &so[5546]},
-+    {"id-GostR3410-94-CryptoPro-D-ParamSet", "id-GostR3410-94-CryptoPro-D-ParamSet", NID_id_GostR3410_94_CryptoPro_D_ParamSet, 7, &so[5553]},
-+    {"id-GostR3410-94-CryptoPro-XchA-ParamSet", "id-GostR3410-94-CryptoPro-XchA-ParamSet", NID_id_GostR3410_94_CryptoPro_XchA_ParamSet, 7, &so[5560]},
-+    {"id-GostR3410-94-CryptoPro-XchB-ParamSet", "id-GostR3410-94-CryptoPro-XchB-ParamSet", NID_id_GostR3410_94_CryptoPro_XchB_ParamSet, 7, &so[5567]},
-+    {"id-GostR3410-94-CryptoPro-XchC-ParamSet", "id-GostR3410-94-CryptoPro-XchC-ParamSet", NID_id_GostR3410_94_CryptoPro_XchC_ParamSet, 7, &so[5574]},
-+    {"id-GostR3410-2001-TestParamSet", "id-GostR3410-2001-TestParamSet", NID_id_GostR3410_2001_TestParamSet, 7, &so[5581]},
-+    {"id-GostR3410-2001-CryptoPro-A-ParamSet", "id-GostR3410-2001-CryptoPro-A-ParamSet", NID_id_GostR3410_2001_CryptoPro_A_ParamSet, 7, &so[5588]},
-+    {"id-GostR3410-2001-CryptoPro-B-ParamSet", "id-GostR3410-2001-CryptoPro-B-ParamSet", NID_id_GostR3410_2001_CryptoPro_B_ParamSet, 7, &so[5595]},
-+    {"id-GostR3410-2001-CryptoPro-C-ParamSet", "id-GostR3410-2001-CryptoPro-C-ParamSet", NID_id_GostR3410_2001_CryptoPro_C_ParamSet, 7, &so[5602]},
-+    {"id-GostR3410-2001-CryptoPro-XchA-ParamSet", "id-GostR3410-2001-CryptoPro-XchA-ParamSet", NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, 7, &so[5609]},
-+    {"id-GostR3410-2001-CryptoPro-XchB-ParamSet", "id-GostR3410-2001-CryptoPro-XchB-ParamSet", NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, 7, &so[5616]},
-+    {"id-GostR3410-94-a", "id-GostR3410-94-a", NID_id_GostR3410_94_a, 7, &so[5623]},
-+    {"id-GostR3410-94-aBis", "id-GostR3410-94-aBis", NID_id_GostR3410_94_aBis, 7, &so[5630]},
-+    {"id-GostR3410-94-b", "id-GostR3410-94-b", NID_id_GostR3410_94_b, 7, &so[5637]},
-+    {"id-GostR3410-94-bBis", "id-GostR3410-94-bBis", NID_id_GostR3410_94_bBis, 7, &so[5644]},
-+    {"id-Gost28147-89-cc", "GOST 28147-89 Cryptocom ParamSet", NID_id_Gost28147_89_cc, 8, &so[5651]},
-+    {"gost94cc", "GOST 34.10-94 Cryptocom", NID_id_GostR3410_94_cc, 8, &so[5659]},
-+    {"gost2001cc", "GOST 34.10-2001 Cryptocom", NID_id_GostR3410_2001_cc, 8, &so[5667]},
-+    {"id-GostR3411-94-with-GostR3410-94-cc", "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom", NID_id_GostR3411_94_with_GostR3410_94_cc, 8, &so[5675]},
-+    {"id-GostR3411-94-with-GostR3410-2001-cc", "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom", NID_id_GostR3411_94_with_GostR3410_2001_cc, 8, &so[5683]},
-+    {"id-GostR3410-2001-ParamSet-cc", "GOST R 3410-2001 Parameter Set Cryptocom", NID_id_GostR3410_2001_ParamSet_cc, 8, &so[5691]},
-+    {"HMAC", "hmac", NID_hmac},
-+    {"LocalKeySet", "Microsoft Local Key set", NID_LocalKeySet, 9, &so[5699]},
-+    {"freshestCRL", "X509v3 Freshest CRL", NID_freshest_crl, 3, &so[5708]},
-+    {"id-on-permanentIdentifier", "Permanent Identifier", NID_id_on_permanentIdentifier, 8, &so[5711]},
-+    {"searchGuide", "searchGuide", NID_searchGuide, 3, &so[5719]},
-+    {"businessCategory", "businessCategory", NID_businessCategory, 3, &so[5722]},
-+    {"postalAddress", "postalAddress", NID_postalAddress, 3, &so[5725]},
-+    {"postOfficeBox", "postOfficeBox", NID_postOfficeBox, 3, &so[5728]},
-+    {"physicalDeliveryOfficeName", "physicalDeliveryOfficeName", NID_physicalDeliveryOfficeName, 3, &so[5731]},
-+    {"telephoneNumber", "telephoneNumber", NID_telephoneNumber, 3, &so[5734]},
-+    {"telexNumber", "telexNumber", NID_telexNumber, 3, &so[5737]},
-+    {"teletexTerminalIdentifier", "teletexTerminalIdentifier", NID_teletexTerminalIdentifier, 3, &so[5740]},
-+    {"facsimileTelephoneNumber", "facsimileTelephoneNumber", NID_facsimileTelephoneNumber, 3, &so[5743]},
-+    {"x121Address", "x121Address", NID_x121Address, 3, &so[5746]},
-+    {"internationaliSDNNumber", "internationaliSDNNumber", NID_internationaliSDNNumber, 3, &so[5749]},
-+    {"registeredAddress", "registeredAddress", NID_registeredAddress, 3, &so[5752]},
-+    {"destinationIndicator", "destinationIndicator", NID_destinationIndicator, 3, &so[5755]},
-+    {"preferredDeliveryMethod", "preferredDeliveryMethod", NID_preferredDeliveryMethod, 3, &so[5758]},
-+    {"presentationAddress", "presentationAddress", NID_presentationAddress, 3, &so[5761]},
-+    {"supportedApplicationContext", "supportedApplicationContext", NID_supportedApplicationContext, 3, &so[5764]},
-+    {"member", "member", NID_member, 3, &so[5767]},
-+    {"owner", "owner", NID_owner, 3, &so[5770]},
-+    {"roleOccupant", "roleOccupant", NID_roleOccupant, 3, &so[5773]},
-+    {"seeAlso", "seeAlso", NID_seeAlso, 3, &so[5776]},
-+    {"userPassword", "userPassword", NID_userPassword, 3, &so[5779]},
-+    {"userCertificate", "userCertificate", NID_userCertificate, 3, &so[5782]},
-+    {"cACertificate", "cACertificate", NID_cACertificate, 3, &so[5785]},
-+    {"authorityRevocationList", "authorityRevocationList", NID_authorityRevocationList, 3, &so[5788]},
-+    {"certificateRevocationList", "certificateRevocationList", NID_certificateRevocationList, 3, &so[5791]},
-+    {"crossCertificatePair", "crossCertificatePair", NID_crossCertificatePair, 3, &so[5794]},
-+    {"enhancedSearchGuide", "enhancedSearchGuide", NID_enhancedSearchGuide, 3, &so[5797]},
-+    {"protocolInformation", "protocolInformation", NID_protocolInformation, 3, &so[5800]},
-+    {"distinguishedName", "distinguishedName", NID_distinguishedName, 3, &so[5803]},
-+    {"uniqueMember", "uniqueMember", NID_uniqueMember, 3, &so[5806]},
-+    {"houseIdentifier", "houseIdentifier", NID_houseIdentifier, 3, &so[5809]},
-+    {"supportedAlgorithms", "supportedAlgorithms", NID_supportedAlgorithms, 3, &so[5812]},
-+    {"deltaRevocationList", "deltaRevocationList", NID_deltaRevocationList, 3, &so[5815]},
-+    {"dmdName", "dmdName", NID_dmdName, 3, &so[5818]},
-+    {"id-alg-PWRI-KEK", "id-alg-PWRI-KEK", NID_id_alg_PWRI_KEK, 11, &so[5821]},
-+    {"CMAC", "cmac", NID_cmac},
-+    {"id-aes128-GCM", "aes-128-gcm", NID_aes_128_gcm, 9, &so[5832]},
-+    {"id-aes128-CCM", "aes-128-ccm", NID_aes_128_ccm, 9, &so[5841]},
-+    {"id-aes128-wrap-pad", "id-aes128-wrap-pad", NID_id_aes128_wrap_pad, 9, &so[5850]},
-+    {"id-aes192-GCM", "aes-192-gcm", NID_aes_192_gcm, 9, &so[5859]},
-+    {"id-aes192-CCM", "aes-192-ccm", NID_aes_192_ccm, 9, &so[5868]},
-+    {"id-aes192-wrap-pad", "id-aes192-wrap-pad", NID_id_aes192_wrap_pad, 9, &so[5877]},
-+    {"id-aes256-GCM", "aes-256-gcm", NID_aes_256_gcm, 9, &so[5886]},
-+    {"id-aes256-CCM", "aes-256-ccm", NID_aes_256_ccm, 9, &so[5895]},
-+    {"id-aes256-wrap-pad", "id-aes256-wrap-pad", NID_id_aes256_wrap_pad, 9, &so[5904]},
-+    {"AES-128-CTR", "aes-128-ctr", NID_aes_128_ctr},
-+    {"AES-192-CTR", "aes-192-ctr", NID_aes_192_ctr},
-+    {"AES-256-CTR", "aes-256-ctr", NID_aes_256_ctr},
-+    {"id-camellia128-wrap", "id-camellia128-wrap", NID_id_camellia128_wrap, 11, &so[5913]},
-+    {"id-camellia192-wrap", "id-camellia192-wrap", NID_id_camellia192_wrap, 11, &so[5924]},
-+    {"id-camellia256-wrap", "id-camellia256-wrap", NID_id_camellia256_wrap, 11, &so[5935]},
-+    {"anyExtendedKeyUsage", "Any Extended Key Usage", NID_anyExtendedKeyUsage, 4, &so[5946]},
-+    {"MGF1", "mgf1", NID_mgf1, 9, &so[5950]},
-+    {"RSASSA-PSS", "rsassaPss", NID_rsassaPss, 9, &so[5959]},
-+    {"AES-128-XTS", "aes-128-xts", NID_aes_128_xts},
-+    {"AES-256-XTS", "aes-256-xts", NID_aes_256_xts},
-+    {"RC4-HMAC-MD5", "rc4-hmac-md5", NID_rc4_hmac_md5},
-+    {"AES-128-CBC-HMAC-SHA1", "aes-128-cbc-hmac-sha1", NID_aes_128_cbc_hmac_sha1},
-+    {"AES-192-CBC-HMAC-SHA1", "aes-192-cbc-hmac-sha1", NID_aes_192_cbc_hmac_sha1},
-+    {"AES-256-CBC-HMAC-SHA1", "aes-256-cbc-hmac-sha1", NID_aes_256_cbc_hmac_sha1},
-+    {"RSAES-OAEP", "rsaesOaep", NID_rsaesOaep, 9, &so[5968]},
-+    {"dhpublicnumber", "X9.42 DH", NID_dhpublicnumber, 7, &so[5977]},
-+    {"brainpoolP160r1", "brainpoolP160r1", NID_brainpoolP160r1, 9, &so[5984]},
-+    {"brainpoolP160t1", "brainpoolP160t1", NID_brainpoolP160t1, 9, &so[5993]},
-+    {"brainpoolP192r1", "brainpoolP192r1", NID_brainpoolP192r1, 9, &so[6002]},
-+    {"brainpoolP192t1", "brainpoolP192t1", NID_brainpoolP192t1, 9, &so[6011]},
-+    {"brainpoolP224r1", "brainpoolP224r1", NID_brainpoolP224r1, 9, &so[6020]},
-+    {"brainpoolP224t1", "brainpoolP224t1", NID_brainpoolP224t1, 9, &so[6029]},
-+    {"brainpoolP256r1", "brainpoolP256r1", NID_brainpoolP256r1, 9, &so[6038]},
-+    {"brainpoolP256t1", "brainpoolP256t1", NID_brainpoolP256t1, 9, &so[6047]},
-+    {"brainpoolP320r1", "brainpoolP320r1", NID_brainpoolP320r1, 9, &so[6056]},
-+    {"brainpoolP320t1", "brainpoolP320t1", NID_brainpoolP320t1, 9, &so[6065]},
-+    {"brainpoolP384r1", "brainpoolP384r1", NID_brainpoolP384r1, 9, &so[6074]},
-+    {"brainpoolP384t1", "brainpoolP384t1", NID_brainpoolP384t1, 9, &so[6083]},
-+    {"brainpoolP512r1", "brainpoolP512r1", NID_brainpoolP512r1, 9, &so[6092]},
-+    {"brainpoolP512t1", "brainpoolP512t1", NID_brainpoolP512t1, 9, &so[6101]},
-+    {"PSPECIFIED", "pSpecified", NID_pSpecified, 9, &so[6110]},
-+    {"dhSinglePass-stdDH-sha1kdf-scheme", "dhSinglePass-stdDH-sha1kdf-scheme", NID_dhSinglePass_stdDH_sha1kdf_scheme, 9, &so[6119]},
-+    {"dhSinglePass-stdDH-sha224kdf-scheme", "dhSinglePass-stdDH-sha224kdf-scheme", NID_dhSinglePass_stdDH_sha224kdf_scheme, 6, &so[6128]},
-+    {"dhSinglePass-stdDH-sha256kdf-scheme", "dhSinglePass-stdDH-sha256kdf-scheme", NID_dhSinglePass_stdDH_sha256kdf_scheme, 6, &so[6134]},
-+    {"dhSinglePass-stdDH-sha384kdf-scheme", "dhSinglePass-stdDH-sha384kdf-scheme", NID_dhSinglePass_stdDH_sha384kdf_scheme, 6, &so[6140]},
-+    {"dhSinglePass-stdDH-sha512kdf-scheme", "dhSinglePass-stdDH-sha512kdf-scheme", NID_dhSinglePass_stdDH_sha512kdf_scheme, 6, &so[6146]},
-+    {"dhSinglePass-cofactorDH-sha1kdf-scheme", "dhSinglePass-cofactorDH-sha1kdf-scheme", NID_dhSinglePass_cofactorDH_sha1kdf_scheme, 9, &so[6152]},
-+    {"dhSinglePass-cofactorDH-sha224kdf-scheme", "dhSinglePass-cofactorDH-sha224kdf-scheme", NID_dhSinglePass_cofactorDH_sha224kdf_scheme, 6, &so[6161]},
-+    {"dhSinglePass-cofactorDH-sha256kdf-scheme", "dhSinglePass-cofactorDH-sha256kdf-scheme", NID_dhSinglePass_cofactorDH_sha256kdf_scheme, 6, &so[6167]},
-+    {"dhSinglePass-cofactorDH-sha384kdf-scheme", "dhSinglePass-cofactorDH-sha384kdf-scheme", NID_dhSinglePass_cofactorDH_sha384kdf_scheme, 6, &so[6173]},
-+    {"dhSinglePass-cofactorDH-sha512kdf-scheme", "dhSinglePass-cofactorDH-sha512kdf-scheme", NID_dhSinglePass_cofactorDH_sha512kdf_scheme, 6, &so[6179]},
-+    {"dh-std-kdf", "dh-std-kdf", NID_dh_std_kdf},
-+    {"dh-cofactor-kdf", "dh-cofactor-kdf", NID_dh_cofactor_kdf},
-+    {"AES-128-CBC-HMAC-SHA256", "aes-128-cbc-hmac-sha256", NID_aes_128_cbc_hmac_sha256},
-+    {"AES-192-CBC-HMAC-SHA256", "aes-192-cbc-hmac-sha256", NID_aes_192_cbc_hmac_sha256},
-+    {"AES-256-CBC-HMAC-SHA256", "aes-256-cbc-hmac-sha256", NID_aes_256_cbc_hmac_sha256},
-+    {"ct_precert_scts", "CT Precertificate SCTs", NID_ct_precert_scts, 10, &so[6185]},
-+    {"ct_precert_poison", "CT Precertificate Poison", NID_ct_precert_poison, 10, &so[6195]},
-+    {"ct_precert_signer", "CT Precertificate Signer", NID_ct_precert_signer, 10, &so[6205]},
-+    {"ct_cert_scts", "CT Certificate SCTs", NID_ct_cert_scts, 10, &so[6215]},
-+    {"jurisdictionL", "jurisdictionLocalityName", NID_jurisdictionLocalityName, 11, &so[6225]},
-+    {"jurisdictionST", "jurisdictionStateOrProvinceName", NID_jurisdictionStateOrProvinceName, 11, &so[6236]},
-+    {"jurisdictionC", "jurisdictionCountryName", NID_jurisdictionCountryName, 11, &so[6247]},
-+    {"AES-128-OCB", "aes-128-ocb", NID_aes_128_ocb},
-+    {"AES-192-OCB", "aes-192-ocb", NID_aes_192_ocb},
-+    {"AES-256-OCB", "aes-256-ocb", NID_aes_256_ocb},
-+    {"CAMELLIA-128-GCM", "camellia-128-gcm", NID_camellia_128_gcm, 8, &so[6258]},
-+    {"CAMELLIA-128-CCM", "camellia-128-ccm", NID_camellia_128_ccm, 8, &so[6266]},
-+    {"CAMELLIA-128-CTR", "camellia-128-ctr", NID_camellia_128_ctr, 8, &so[6274]},
-+    {"CAMELLIA-128-CMAC", "camellia-128-cmac", NID_camellia_128_cmac, 8, &so[6282]},
-+    {"CAMELLIA-192-GCM", "camellia-192-gcm", NID_camellia_192_gcm, 8, &so[6290]},
-+    {"CAMELLIA-192-CCM", "camellia-192-ccm", NID_camellia_192_ccm, 8, &so[6298]},
-+    {"CAMELLIA-192-CTR", "camellia-192-ctr", NID_camellia_192_ctr, 8, &so[6306]},
-+    {"CAMELLIA-192-CMAC", "camellia-192-cmac", NID_camellia_192_cmac, 8, &so[6314]},
-+    {"CAMELLIA-256-GCM", "camellia-256-gcm", NID_camellia_256_gcm, 8, &so[6322]},
-+    {"CAMELLIA-256-CCM", "camellia-256-ccm", NID_camellia_256_ccm, 8, &so[6330]},
-+    {"CAMELLIA-256-CTR", "camellia-256-ctr", NID_camellia_256_ctr, 8, &so[6338]},
-+    {"CAMELLIA-256-CMAC", "camellia-256-cmac", NID_camellia_256_cmac, 8, &so[6346]},
-+    {"id-scrypt", "id-scrypt", NID_id_scrypt, 9, &so[6354]},
-+    {"id-tc26", "id-tc26", NID_id_tc26, 5, &so[6363]},
-+    {"gost89-cnt-12", "gost89-cnt-12", NID_gost89_cnt_12},
-+    {"gost-mac-12", "gost-mac-12", NID_gost_mac_12},
-+    {"id-tc26-algorithms", "id-tc26-algorithms", NID_id_tc26_algorithms, 6, &so[6368]},
-+    {"id-tc26-sign", "id-tc26-sign", NID_id_tc26_sign, 7, &so[6374]},
-+    {"gost2012_256", "GOST R 34.10-2012 with 256 bit modulus", NID_id_GostR3410_2012_256, 8, &so[6381]},
-+    {"gost2012_512", "GOST R 34.10-2012 with 512 bit modulus", NID_id_GostR3410_2012_512, 8, &so[6389]},
-+    {"id-tc26-digest", "id-tc26-digest", NID_id_tc26_digest, 7, &so[6397]},
-+    {"md_gost12_256", "GOST R 34.11-2012 with 256 bit hash", NID_id_GostR3411_2012_256, 8, &so[6404]},
-+    {"md_gost12_512", "GOST R 34.11-2012 with 512 bit hash", NID_id_GostR3411_2012_512, 8, &so[6412]},
-+    {"id-tc26-signwithdigest", "id-tc26-signwithdigest", NID_id_tc26_signwithdigest, 7, &so[6420]},
-+    {"id-tc26-signwithdigest-gost3410-2012-256", "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)", NID_id_tc26_signwithdigest_gost3410_2012_256, 8, &so[6427]},
-+    {"id-tc26-signwithdigest-gost3410-2012-512", "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)", NID_id_tc26_signwithdigest_gost3410_2012_512, 8, &so[6435]},
-+    {"id-tc26-mac", "id-tc26-mac", NID_id_tc26_mac, 7, &so[6443]},
-+    {"id-tc26-hmac-gost-3411-2012-256", "HMAC GOST 34.11-2012 256 bit", NID_id_tc26_hmac_gost_3411_2012_256, 8, &so[6450]},
-+    {"id-tc26-hmac-gost-3411-2012-512", "HMAC GOST 34.11-2012 512 bit", NID_id_tc26_hmac_gost_3411_2012_512, 8, &so[6458]},
-+    {"id-tc26-cipher", "id-tc26-cipher", NID_id_tc26_cipher, 7, &so[6466]},
-+    {"id-tc26-agreement", "id-tc26-agreement", NID_id_tc26_agreement, 7, &so[6473]},
-+    {"id-tc26-agreement-gost-3410-2012-256", "id-tc26-agreement-gost-3410-2012-256", NID_id_tc26_agreement_gost_3410_2012_256, 8, &so[6480]},
-+    {"id-tc26-agreement-gost-3410-2012-512", "id-tc26-agreement-gost-3410-2012-512", NID_id_tc26_agreement_gost_3410_2012_512, 8, &so[6488]},
-+    {"id-tc26-constants", "id-tc26-constants", NID_id_tc26_constants, 6, &so[6496]},
-+    {"id-tc26-sign-constants", "id-tc26-sign-constants", NID_id_tc26_sign_constants, 7, &so[6502]},
-+    {"id-tc26-gost-3410-2012-512-constants", "id-tc26-gost-3410-2012-512-constants", NID_id_tc26_gost_3410_2012_512_constants, 8, &so[6509]},
-+    {"id-tc26-gost-3410-2012-512-paramSetTest", "GOST R 34.10-2012 (512 bit) testing parameter set", NID_id_tc26_gost_3410_2012_512_paramSetTest, 9, &so[6517]},
-+    {"id-tc26-gost-3410-2012-512-paramSetA", "GOST R 34.10-2012 (512 bit) ParamSet A", NID_id_tc26_gost_3410_2012_512_paramSetA, 9, &so[6526]},
-+    {"id-tc26-gost-3410-2012-512-paramSetB", "GOST R 34.10-2012 (512 bit) ParamSet B", NID_id_tc26_gost_3410_2012_512_paramSetB, 9, &so[6535]},
-+    {"id-tc26-digest-constants", "id-tc26-digest-constants", NID_id_tc26_digest_constants, 7, &so[6544]},
-+    {"id-tc26-cipher-constants", "id-tc26-cipher-constants", NID_id_tc26_cipher_constants, 7, &so[6551]},
-+    {"id-tc26-gost-28147-constants", "id-tc26-gost-28147-constants", NID_id_tc26_gost_28147_constants, 8, &so[6558]},
-+    {"id-tc26-gost-28147-param-Z", "GOST 28147-89 TC26 parameter set", NID_id_tc26_gost_28147_param_Z, 9, &so[6566]},
-+    {"INN", "INN", NID_INN, 8, &so[6575]},
-+    {"OGRN", "OGRN", NID_OGRN, 5, &so[6583]},
-+    {"SNILS", "SNILS", NID_SNILS, 5, &so[6588]},
-+    {"subjectSignTool", "Signing Tool of Subject", NID_subjectSignTool, 5, &so[6593]},
-+    {"issuerSignTool", "Signing Tool of Issuer", NID_issuerSignTool, 5, &so[6598]},
-+    {"gost89-cbc", "gost89-cbc", NID_gost89_cbc},
-+    {"gost89-ecb", "gost89-ecb", NID_gost89_ecb},
-+    {"gost89-ctr", "gost89-ctr", NID_gost89_ctr},
-+    {"grasshopper-ecb", "grasshopper-ecb", NID_grasshopper_ecb},
-+    {"grasshopper-ctr", "grasshopper-ctr", NID_grasshopper_ctr},
-+    {"grasshopper-ofb", "grasshopper-ofb", NID_grasshopper_ofb},
-+    {"grasshopper-cbc", "grasshopper-cbc", NID_grasshopper_cbc},
-+    {"grasshopper-cfb", "grasshopper-cfb", NID_grasshopper_cfb},
-+    {"grasshopper-mac", "grasshopper-mac", NID_grasshopper_mac},
-+    {"ChaCha20-Poly1305", "chacha20-poly1305", NID_chacha20_poly1305},
-+    {"ChaCha20", "chacha20", NID_chacha20},
-+    {"tlsfeature", "TLS Feature", NID_tlsfeature, 8, &so[6603]},
-+    {"TLS1-PRF", "tls1-prf", NID_tls1_prf},
-+    {"ipsecIKE", "ipsec Internet Key Exchange", NID_ipsec_IKE, 8, &so[6611]},
-+    {"capwapAC", "Ctrl/provision WAP Access", NID_capwapAC, 8, &so[6619]},
-+    {"capwapWTP", "Ctrl/Provision WAP Termination", NID_capwapWTP, 8, &so[6627]},
-+    {"secureShellClient", "SSH Client", NID_sshClient, 8, &so[6635]},
-+    {"secureShellServer", "SSH Server", NID_sshServer, 8, &so[6643]},
-+    {"sendRouter", "Send Router", NID_sendRouter, 8, &so[6651]},
-+    {"sendProxiedRouter", "Send Proxied Router", NID_sendProxiedRouter, 8, &so[6659]},
-+    {"sendOwner", "Send Owner", NID_sendOwner, 8, &so[6667]},
-+    {"sendProxiedOwner", "Send Proxied Owner", NID_sendProxiedOwner, 8, &so[6675]},
-+    {"id-pkinit", "id-pkinit", NID_id_pkinit, 6, &so[6683]},
-+    {"pkInitClientAuth", "PKINIT Client Auth", NID_pkInitClientAuth, 7, &so[6689]},
-+    {"pkInitKDC", "Signing KDC Response", NID_pkInitKDC, 7, &so[6696]},
-+    {"X25519", "X25519", NID_X25519, 3, &so[6703]},
-+    {"X448", "X448", NID_X448, 3, &so[6706]},
-+    {"HKDF", "hkdf", NID_hkdf},
-+    {"KxRSA", "kx-rsa", NID_kx_rsa},
-+    {"KxECDHE", "kx-ecdhe", NID_kx_ecdhe},
-+    {"KxDHE", "kx-dhe", NID_kx_dhe},
-+    {"KxECDHE-PSK", "kx-ecdhe-psk", NID_kx_ecdhe_psk},
-+    {"KxDHE-PSK", "kx-dhe-psk", NID_kx_dhe_psk},
-+    {"KxRSA_PSK", "kx-rsa-psk", NID_kx_rsa_psk},
-+    {"KxPSK", "kx-psk", NID_kx_psk},
-+    {"KxSRP", "kx-srp", NID_kx_srp},
-+    {"KxGOST", "kx-gost", NID_kx_gost},
-+    {"AuthRSA", "auth-rsa", NID_auth_rsa},
-+    {"AuthECDSA", "auth-ecdsa", NID_auth_ecdsa},
-+    {"AuthPSK", "auth-psk", NID_auth_psk},
-+    {"AuthDSS", "auth-dss", NID_auth_dss},
-+    {"AuthGOST01", "auth-gost01", NID_auth_gost01},
-+    {"AuthGOST12", "auth-gost12", NID_auth_gost12},
-+    {"AuthSRP", "auth-srp", NID_auth_srp},
-+    {"AuthNULL", "auth-null", NID_auth_null},
-+    { NULL, NULL, NID_undef },
-+    { NULL, NULL, NID_undef },
-+    {"BLAKE2b512", "blake2b512", NID_blake2b512, 11, &so[6709]},
-+    {"BLAKE2s256", "blake2s256", NID_blake2s256, 11, &so[6720]},
-+    {"id-smime-ct-contentCollection", "id-smime-ct-contentCollection", NID_id_smime_ct_contentCollection, 11, &so[6731]},
-+    {"id-smime-ct-authEnvelopedData", "id-smime-ct-authEnvelopedData", NID_id_smime_ct_authEnvelopedData, 11, &so[6742]},
-+    {"id-ct-xml", "id-ct-xml", NID_id_ct_xml, 11, &so[6753]},
-+};
-+
-+#define NUM_SN 1052
-+static const unsigned int sn_objs[NUM_SN] = {
-+     364,    /* "AD_DVCS" */
-+     419,    /* "AES-128-CBC" */
-+     916,    /* "AES-128-CBC-HMAC-SHA1" */
-+     948,    /* "AES-128-CBC-HMAC-SHA256" */
-+     421,    /* "AES-128-CFB" */
-+     650,    /* "AES-128-CFB1" */
-+     653,    /* "AES-128-CFB8" */
-+     904,    /* "AES-128-CTR" */
-+     418,    /* "AES-128-ECB" */
-+     958,    /* "AES-128-OCB" */
-+     420,    /* "AES-128-OFB" */
-+     913,    /* "AES-128-XTS" */
-+     423,    /* "AES-192-CBC" */
-+     917,    /* "AES-192-CBC-HMAC-SHA1" */
-+     949,    /* "AES-192-CBC-HMAC-SHA256" */
-+     425,    /* "AES-192-CFB" */
-+     651,    /* "AES-192-CFB1" */
-+     654,    /* "AES-192-CFB8" */
-+     905,    /* "AES-192-CTR" */
-+     422,    /* "AES-192-ECB" */
-+     959,    /* "AES-192-OCB" */
-+     424,    /* "AES-192-OFB" */
-+     427,    /* "AES-256-CBC" */
-+     918,    /* "AES-256-CBC-HMAC-SHA1" */
-+     950,    /* "AES-256-CBC-HMAC-SHA256" */
-+     429,    /* "AES-256-CFB" */
-+     652,    /* "AES-256-CFB1" */
-+     655,    /* "AES-256-CFB8" */
-+     906,    /* "AES-256-CTR" */
-+     426,    /* "AES-256-ECB" */
-+     960,    /* "AES-256-OCB" */
-+     428,    /* "AES-256-OFB" */
-+     914,    /* "AES-256-XTS" */
-+    1049,    /* "AuthDSS" */
-+    1047,    /* "AuthECDSA" */
-+    1050,    /* "AuthGOST01" */
-+    1051,    /* "AuthGOST12" */
-+    1053,    /* "AuthNULL" */
-+    1048,    /* "AuthPSK" */
-+    1046,    /* "AuthRSA" */
-+    1052,    /* "AuthSRP" */
-+      91,    /* "BF-CBC" */
-+      93,    /* "BF-CFB" */
-+      92,    /* "BF-ECB" */
-+      94,    /* "BF-OFB" */
-+    1056,    /* "BLAKE2b512" */
-+    1057,    /* "BLAKE2s256" */
-+      14,    /* "C" */
-+     751,    /* "CAMELLIA-128-CBC" */
-+     962,    /* "CAMELLIA-128-CCM" */
-+     757,    /* "CAMELLIA-128-CFB" */
-+     760,    /* "CAMELLIA-128-CFB1" */
-+     763,    /* "CAMELLIA-128-CFB8" */
-+     964,    /* "CAMELLIA-128-CMAC" */
-+     963,    /* "CAMELLIA-128-CTR" */
-+     754,    /* "CAMELLIA-128-ECB" */
-+     961,    /* "CAMELLIA-128-GCM" */
-+     766,    /* "CAMELLIA-128-OFB" */
-+     752,    /* "CAMELLIA-192-CBC" */
-+     966,    /* "CAMELLIA-192-CCM" */
-+     758,    /* "CAMELLIA-192-CFB" */
-+     761,    /* "CAMELLIA-192-CFB1" */
-+     764,    /* "CAMELLIA-192-CFB8" */
-+     968,    /* "CAMELLIA-192-CMAC" */
-+     967,    /* "CAMELLIA-192-CTR" */
-+     755,    /* "CAMELLIA-192-ECB" */
-+     965,    /* "CAMELLIA-192-GCM" */
-+     767,    /* "CAMELLIA-192-OFB" */
-+     753,    /* "CAMELLIA-256-CBC" */
-+     970,    /* "CAMELLIA-256-CCM" */
-+     759,    /* "CAMELLIA-256-CFB" */
-+     762,    /* "CAMELLIA-256-CFB1" */
-+     765,    /* "CAMELLIA-256-CFB8" */
-+     972,    /* "CAMELLIA-256-CMAC" */
-+     971,    /* "CAMELLIA-256-CTR" */
-+     756,    /* "CAMELLIA-256-ECB" */
-+     969,    /* "CAMELLIA-256-GCM" */
-+     768,    /* "CAMELLIA-256-OFB" */
-+     108,    /* "CAST5-CBC" */
-+     110,    /* "CAST5-CFB" */
-+     109,    /* "CAST5-ECB" */
-+     111,    /* "CAST5-OFB" */
-+     894,    /* "CMAC" */
-+      13,    /* "CN" */
-+     141,    /* "CRLReason" */
-+     417,    /* "CSPName" */
-+    1019,    /* "ChaCha20" */
-+    1018,    /* "ChaCha20-Poly1305" */
-+     367,    /* "CrlID" */
-+     391,    /* "DC" */
-+      31,    /* "DES-CBC" */
-+     643,    /* "DES-CDMF" */
-+      30,    /* "DES-CFB" */
-+     656,    /* "DES-CFB1" */
-+     657,    /* "DES-CFB8" */
-+      29,    /* "DES-ECB" */
-+      32,    /* "DES-EDE" */
-+      43,    /* "DES-EDE-CBC" */
-+      60,    /* "DES-EDE-CFB" */
-+      62,    /* "DES-EDE-OFB" */
-+      33,    /* "DES-EDE3" */
-+      44,    /* "DES-EDE3-CBC" */
-+      61,    /* "DES-EDE3-CFB" */
-+     658,    /* "DES-EDE3-CFB1" */
-+     659,    /* "DES-EDE3-CFB8" */
-+      63,    /* "DES-EDE3-OFB" */
-+      45,    /* "DES-OFB" */
-+      80,    /* "DESX-CBC" */
-+     380,    /* "DOD" */
-+     116,    /* "DSA" */
-+      66,    /* "DSA-SHA" */
-+     113,    /* "DSA-SHA1" */
-+      70,    /* "DSA-SHA1-old" */
-+      67,    /* "DSA-old" */
-+     297,    /* "DVCS" */
-+      99,    /* "GN" */
-+    1036,    /* "HKDF" */
-+     855,    /* "HMAC" */
-+     780,    /* "HMAC-MD5" */
-+     781,    /* "HMAC-SHA1" */
-+     381,    /* "IANA" */
-+      34,    /* "IDEA-CBC" */
-+      35,    /* "IDEA-CFB" */
-+      36,    /* "IDEA-ECB" */
-+      46,    /* "IDEA-OFB" */
-+    1004,    /* "INN" */
-+     181,    /* "ISO" */
-+     183,    /* "ISO-US" */
-+     645,    /* "ITU-T" */
-+     646,    /* "JOINT-ISO-ITU-T" */
-+     773,    /* "KISA" */
-+    1039,    /* "KxDHE" */
-+    1041,    /* "KxDHE-PSK" */
-+    1038,    /* "KxECDHE" */
-+    1040,    /* "KxECDHE-PSK" */
-+    1045,    /* "KxGOST" */
-+    1043,    /* "KxPSK" */
-+    1037,    /* "KxRSA" */
-+    1042,    /* "KxRSA_PSK" */
-+    1044,    /* "KxSRP" */
-+      15,    /* "L" */
-+     856,    /* "LocalKeySet" */
-+       3,    /* "MD2" */
-+     257,    /* "MD4" */
-+       4,    /* "MD5" */
-+     114,    /* "MD5-SHA1" */
-+      95,    /* "MDC2" */
-+     911,    /* "MGF1" */
-+     388,    /* "Mail" */
-+     393,    /* "NULL" */
-+     404,    /* "NULL" */
-+      57,    /* "Netscape" */
-+     366,    /* "Nonce" */
-+      17,    /* "O" */
-+     178,    /* "OCSP" */
-+     180,    /* "OCSPSigning" */
-+    1005,    /* "OGRN" */
-+     379,    /* "ORG" */
-+      18,    /* "OU" */
-+     749,    /* "Oakley-EC2N-3" */
-+     750,    /* "Oakley-EC2N-4" */
-+       9,    /* "PBE-MD2-DES" */
-+     168,    /* "PBE-MD2-RC2-64" */
-+      10,    /* "PBE-MD5-DES" */
-+     169,    /* "PBE-MD5-RC2-64" */
-+     147,    /* "PBE-SHA1-2DES" */
-+     146,    /* "PBE-SHA1-3DES" */
-+     170,    /* "PBE-SHA1-DES" */
-+     148,    /* "PBE-SHA1-RC2-128" */
-+     149,    /* "PBE-SHA1-RC2-40" */
-+      68,    /* "PBE-SHA1-RC2-64" */
-+     144,    /* "PBE-SHA1-RC4-128" */
-+     145,    /* "PBE-SHA1-RC4-40" */
-+     161,    /* "PBES2" */
-+      69,    /* "PBKDF2" */
-+     162,    /* "PBMAC1" */
-+     127,    /* "PKIX" */
-+     935,    /* "PSPECIFIED" */
-+      98,    /* "RC2-40-CBC" */
-+     166,    /* "RC2-64-CBC" */
-+      37,    /* "RC2-CBC" */
-+      39,    /* "RC2-CFB" */
-+      38,    /* "RC2-ECB" */
-+      40,    /* "RC2-OFB" */
-+       5,    /* "RC4" */
-+      97,    /* "RC4-40" */
-+     915,    /* "RC4-HMAC-MD5" */
-+     120,    /* "RC5-CBC" */
-+     122,    /* "RC5-CFB" */
-+     121,    /* "RC5-ECB" */
-+     123,    /* "RC5-OFB" */
-+     117,    /* "RIPEMD160" */
-+      19,    /* "RSA" */
-+       7,    /* "RSA-MD2" */
-+     396,    /* "RSA-MD4" */
-+       8,    /* "RSA-MD5" */
-+      96,    /* "RSA-MDC2" */
-+     104,    /* "RSA-NP-MD5" */
-+     119,    /* "RSA-RIPEMD160" */
-+      42,    /* "RSA-SHA" */
-+      65,    /* "RSA-SHA1" */
-+     115,    /* "RSA-SHA1-2" */
-+     671,    /* "RSA-SHA224" */
-+     668,    /* "RSA-SHA256" */
-+     669,    /* "RSA-SHA384" */
-+     670,    /* "RSA-SHA512" */
-+     919,    /* "RSAES-OAEP" */
-+     912,    /* "RSASSA-PSS" */
-+     777,    /* "SEED-CBC" */
-+     779,    /* "SEED-CFB" */
-+     776,    /* "SEED-ECB" */
-+     778,    /* "SEED-OFB" */
-+      41,    /* "SHA" */
-+      64,    /* "SHA1" */
-+     675,    /* "SHA224" */
-+     672,    /* "SHA256" */
-+     673,    /* "SHA384" */
-+     674,    /* "SHA512" */
-+     188,    /* "SMIME" */
-+     167,    /* "SMIME-CAPS" */
-+     100,    /* "SN" */
-+    1006,    /* "SNILS" */
-+      16,    /* "ST" */
-+     143,    /* "SXNetID" */
-+    1021,    /* "TLS1-PRF" */
-+     458,    /* "UID" */
-+       0,    /* "UNDEF" */
-+    1034,    /* "X25519" */
-+    1035,    /* "X448" */
-+      11,    /* "X500" */
-+     378,    /* "X500algorithms" */
-+      12,    /* "X509" */
-+     184,    /* "X9-57" */
-+     185,    /* "X9cm" */
-+     125,    /* "ZLIB" */
-+     478,    /* "aRecord" */
-+     289,    /* "aaControls" */
-+     287,    /* "ac-auditEntity" */
-+     397,    /* "ac-proxying" */
-+     288,    /* "ac-targeting" */
-+     368,    /* "acceptableResponses" */
-+     446,    /* "account" */
-+     363,    /* "ad_timestamping" */
-+     376,    /* "algorithm" */
-+     405,    /* "ansi-X9-62" */
-+     910,    /* "anyExtendedKeyUsage" */
-+     746,    /* "anyPolicy" */
-+     370,    /* "archiveCutoff" */
-+     484,    /* "associatedDomain" */
-+     485,    /* "associatedName" */
-+     501,    /* "audio" */
-+     177,    /* "authorityInfoAccess" */
-+      90,    /* "authorityKeyIdentifier" */
-+     882,    /* "authorityRevocationList" */
-+      87,    /* "basicConstraints" */
-+     365,    /* "basicOCSPResponse" */
-+     285,    /* "biometricInfo" */
-+     921,    /* "brainpoolP160r1" */
-+     922,    /* "brainpoolP160t1" */
-+     923,    /* "brainpoolP192r1" */
-+     924,    /* "brainpoolP192t1" */
-+     925,    /* "brainpoolP224r1" */
-+     926,    /* "brainpoolP224t1" */
-+     927,    /* "brainpoolP256r1" */
-+     928,    /* "brainpoolP256t1" */
-+     929,    /* "brainpoolP320r1" */
-+     930,    /* "brainpoolP320t1" */
-+     931,    /* "brainpoolP384r1" */
-+     932,    /* "brainpoolP384t1" */
-+     933,    /* "brainpoolP512r1" */
-+     934,    /* "brainpoolP512t1" */
-+     494,    /* "buildingName" */
-+     860,    /* "businessCategory" */
-+     691,    /* "c2onb191v4" */
-+     692,    /* "c2onb191v5" */
-+     697,    /* "c2onb239v4" */
-+     698,    /* "c2onb239v5" */
-+     684,    /* "c2pnb163v1" */
-+     685,    /* "c2pnb163v2" */
-+     686,    /* "c2pnb163v3" */
-+     687,    /* "c2pnb176v1" */
-+     693,    /* "c2pnb208w1" */
-+     699,    /* "c2pnb272w1" */
-+     700,    /* "c2pnb304w1" */
-+     702,    /* "c2pnb368w1" */
-+     688,    /* "c2tnb191v1" */
-+     689,    /* "c2tnb191v2" */
-+     690,    /* "c2tnb191v3" */
-+     694,    /* "c2tnb239v1" */
-+     695,    /* "c2tnb239v2" */
-+     696,    /* "c2tnb239v3" */
-+     701,    /* "c2tnb359v1" */
-+     703,    /* "c2tnb431r1" */
-+     881,    /* "cACertificate" */
-+     483,    /* "cNAMERecord" */
-+     179,    /* "caIssuers" */
-+     785,    /* "caRepository" */
-+    1023,    /* "capwapAC" */
-+    1024,    /* "capwapWTP" */
-+     443,    /* "caseIgnoreIA5StringSyntax" */
-+     152,    /* "certBag" */
-+     677,    /* "certicom-arc" */
-+     771,    /* "certificateIssuer" */
-+      89,    /* "certificatePolicies" */
-+     883,    /* "certificateRevocationList" */
-+      54,    /* "challengePassword" */
-+     407,    /* "characteristic-two-field" */
-+     395,    /* "clearance" */
-+     130,    /* "clientAuth" */
-+     131,    /* "codeSigning" */
-+      50,    /* "contentType" */
-+      53,    /* "countersignature" */
-+     153,    /* "crlBag" */
-+     103,    /* "crlDistributionPoints" */
-+      88,    /* "crlNumber" */
-+     884,    /* "crossCertificatePair" */
-+     806,    /* "cryptocom" */
-+     805,    /* "cryptopro" */
-+     954,    /* "ct_cert_scts" */
-+     952,    /* "ct_precert_poison" */
-+     951,    /* "ct_precert_scts" */
-+     953,    /* "ct_precert_signer" */
-+     500,    /* "dITRedirect" */
-+     451,    /* "dNSDomain" */
-+     495,    /* "dSAQuality" */
-+     434,    /* "data" */
-+     390,    /* "dcobject" */
-+     140,    /* "deltaCRL" */
-+     891,    /* "deltaRevocationList" */
-+     107,    /* "description" */
-+     871,    /* "destinationIndicator" */
-+     947,    /* "dh-cofactor-kdf" */
-+     946,    /* "dh-std-kdf" */
-+      28,    /* "dhKeyAgreement" */
-+     941,    /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */
-+     942,    /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */
-+     943,    /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */
-+     944,    /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */
-+     945,    /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */
-+     936,    /* "dhSinglePass-stdDH-sha1kdf-scheme" */
-+     937,    /* "dhSinglePass-stdDH-sha224kdf-scheme" */
-+     938,    /* "dhSinglePass-stdDH-sha256kdf-scheme" */
-+     939,    /* "dhSinglePass-stdDH-sha384kdf-scheme" */
-+     940,    /* "dhSinglePass-stdDH-sha512kdf-scheme" */
-+     920,    /* "dhpublicnumber" */
-+     382,    /* "directory" */
-+     887,    /* "distinguishedName" */
-+     892,    /* "dmdName" */
-+     174,    /* "dnQualifier" */
-+     447,    /* "document" */
-+     471,    /* "documentAuthor" */
-+     468,    /* "documentIdentifier" */
-+     472,    /* "documentLocation" */
-+     502,    /* "documentPublisher" */
-+     449,    /* "documentSeries" */
-+     469,    /* "documentTitle" */
-+     470,    /* "documentVersion" */
-+     392,    /* "domain" */
-+     452,    /* "domainRelatedObject" */
-+     802,    /* "dsa_with_SHA224" */
-+     803,    /* "dsa_with_SHA256" */
-+     791,    /* "ecdsa-with-Recommended" */
-+     416,    /* "ecdsa-with-SHA1" */
-+     793,    /* "ecdsa-with-SHA224" */
-+     794,    /* "ecdsa-with-SHA256" */
-+     795,    /* "ecdsa-with-SHA384" */
-+     796,    /* "ecdsa-with-SHA512" */
-+     792,    /* "ecdsa-with-Specified" */
-+      48,    /* "emailAddress" */
-+     132,    /* "emailProtection" */
-+     885,    /* "enhancedSearchGuide" */
-+     389,    /* "enterprises" */
-+     384,    /* "experimental" */
-+     172,    /* "extReq" */
-+      56,    /* "extendedCertificateAttributes" */
-+     126,    /* "extendedKeyUsage" */
-+     372,    /* "extendedStatus" */
-+     867,    /* "facsimileTelephoneNumber" */
-+     462,    /* "favouriteDrink" */
-+     857,    /* "freshestCRL" */
-+     453,    /* "friendlyCountry" */
-+     490,    /* "friendlyCountryName" */
-+     156,    /* "friendlyName" */
-+     509,    /* "generationQualifier" */
-+     815,    /* "gost-mac" */
-+     976,    /* "gost-mac-12" */
-+     811,    /* "gost2001" */
-+     851,    /* "gost2001cc" */
-+     979,    /* "gost2012_256" */
-+     980,    /* "gost2012_512" */
-+     813,    /* "gost89" */
-+    1009,    /* "gost89-cbc" */
-+     814,    /* "gost89-cnt" */
-+     975,    /* "gost89-cnt-12" */
-+    1011,    /* "gost89-ctr" */
-+    1010,    /* "gost89-ecb" */
-+     812,    /* "gost94" */
-+     850,    /* "gost94cc" */
-+    1015,    /* "grasshopper-cbc" */
-+    1016,    /* "grasshopper-cfb" */
-+    1013,    /* "grasshopper-ctr" */
-+    1012,    /* "grasshopper-ecb" */
-+    1017,    /* "grasshopper-mac" */
-+    1014,    /* "grasshopper-ofb" */
-+     797,    /* "hmacWithMD5" */
-+     163,    /* "hmacWithSHA1" */
-+     798,    /* "hmacWithSHA224" */
-+     799,    /* "hmacWithSHA256" */
-+     800,    /* "hmacWithSHA384" */
-+     801,    /* "hmacWithSHA512" */
-+     432,    /* "holdInstructionCallIssuer" */
-+     430,    /* "holdInstructionCode" */
-+     431,    /* "holdInstructionNone" */
-+     433,    /* "holdInstructionReject" */
-+     486,    /* "homePostalAddress" */
-+     473,    /* "homeTelephoneNumber" */
-+     466,    /* "host" */
-+     889,    /* "houseIdentifier" */
-+     442,    /* "iA5StringSyntax" */
-+     783,    /* "id-DHBasedMac" */
-+     824,    /* "id-Gost28147-89-CryptoPro-A-ParamSet" */
-+     825,    /* "id-Gost28147-89-CryptoPro-B-ParamSet" */
-+     826,    /* "id-Gost28147-89-CryptoPro-C-ParamSet" */
-+     827,    /* "id-Gost28147-89-CryptoPro-D-ParamSet" */
-+     819,    /* "id-Gost28147-89-CryptoPro-KeyMeshing" */
-+     829,    /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
-+     828,    /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
-+     830,    /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
-+     820,    /* "id-Gost28147-89-None-KeyMeshing" */
-+     823,    /* "id-Gost28147-89-TestParamSet" */
-+     849,    /* "id-Gost28147-89-cc" */
-+     840,    /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
-+     841,    /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
-+     842,    /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
-+     843,    /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
-+     844,    /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
-+     854,    /* "id-GostR3410-2001-ParamSet-cc" */
-+     839,    /* "id-GostR3410-2001-TestParamSet" */
-+     817,    /* "id-GostR3410-2001DH" */
-+     832,    /* "id-GostR3410-94-CryptoPro-A-ParamSet" */
-+     833,    /* "id-GostR3410-94-CryptoPro-B-ParamSet" */
-+     834,    /* "id-GostR3410-94-CryptoPro-C-ParamSet" */
-+     835,    /* "id-GostR3410-94-CryptoPro-D-ParamSet" */
-+     836,    /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
-+     837,    /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
-+     838,    /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
-+     831,    /* "id-GostR3410-94-TestParamSet" */
-+     845,    /* "id-GostR3410-94-a" */
-+     846,    /* "id-GostR3410-94-aBis" */
-+     847,    /* "id-GostR3410-94-b" */
-+     848,    /* "id-GostR3410-94-bBis" */
-+     818,    /* "id-GostR3410-94DH" */
-+     822,    /* "id-GostR3411-94-CryptoProParamSet" */
-+     821,    /* "id-GostR3411-94-TestParamSet" */
-+     807,    /* "id-GostR3411-94-with-GostR3410-2001" */
-+     853,    /* "id-GostR3411-94-with-GostR3410-2001-cc" */
-+     808,    /* "id-GostR3411-94-with-GostR3410-94" */
-+     852,    /* "id-GostR3411-94-with-GostR3410-94-cc" */
-+     810,    /* "id-HMACGostR3411-94" */
-+     782,    /* "id-PasswordBasedMAC" */
-+     266,    /* "id-aca" */
-+     355,    /* "id-aca-accessIdentity" */
-+     354,    /* "id-aca-authenticationInfo" */
-+     356,    /* "id-aca-chargingIdentity" */
-+     399,    /* "id-aca-encAttrs" */
-+     357,    /* "id-aca-group" */
-+     358,    /* "id-aca-role" */
-+     176,    /* "id-ad" */
-+     896,    /* "id-aes128-CCM" */
-+     895,    /* "id-aes128-GCM" */
-+     788,    /* "id-aes128-wrap" */
-+     897,    /* "id-aes128-wrap-pad" */
-+     899,    /* "id-aes192-CCM" */
-+     898,    /* "id-aes192-GCM" */
-+     789,    /* "id-aes192-wrap" */
-+     900,    /* "id-aes192-wrap-pad" */
-+     902,    /* "id-aes256-CCM" */
-+     901,    /* "id-aes256-GCM" */
-+     790,    /* "id-aes256-wrap" */
-+     903,    /* "id-aes256-wrap-pad" */
-+     262,    /* "id-alg" */
-+     893,    /* "id-alg-PWRI-KEK" */
-+     323,    /* "id-alg-des40" */
-+     326,    /* "id-alg-dh-pop" */
-+     325,    /* "id-alg-dh-sig-hmac-sha1" */
-+     324,    /* "id-alg-noSignature" */
-+     907,    /* "id-camellia128-wrap" */
-+     908,    /* "id-camellia192-wrap" */
-+     909,    /* "id-camellia256-wrap" */
-+     268,    /* "id-cct" */
-+     361,    /* "id-cct-PKIData" */
-+     362,    /* "id-cct-PKIResponse" */
-+     360,    /* "id-cct-crs" */
-+      81,    /* "id-ce" */
-+     680,    /* "id-characteristic-two-basis" */
-+     263,    /* "id-cmc" */
-+     334,    /* "id-cmc-addExtensions" */
-+     346,    /* "id-cmc-confirmCertAcceptance" */
-+     330,    /* "id-cmc-dataReturn" */
-+     336,    /* "id-cmc-decryptedPOP" */
-+     335,    /* "id-cmc-encryptedPOP" */
-+     339,    /* "id-cmc-getCRL" */
-+     338,    /* "id-cmc-getCert" */
-+     328,    /* "id-cmc-identification" */
-+     329,    /* "id-cmc-identityProof" */
-+     337,    /* "id-cmc-lraPOPWitness" */
-+     344,    /* "id-cmc-popLinkRandom" */
-+     345,    /* "id-cmc-popLinkWitness" */
-+     343,    /* "id-cmc-queryPending" */
-+     333,    /* "id-cmc-recipientNonce" */
-+     341,    /* "id-cmc-regInfo" */
-+     342,    /* "id-cmc-responseInfo" */
-+     340,    /* "id-cmc-revokeRequest" */
-+     332,    /* "id-cmc-senderNonce" */
-+     327,    /* "id-cmc-statusInfo" */
-+     331,    /* "id-cmc-transactionId" */
-+     787,    /* "id-ct-asciiTextWithCRLF" */
-+    1060,    /* "id-ct-xml" */
-+     408,    /* "id-ecPublicKey" */
-+     508,    /* "id-hex-multipart-message" */
-+     507,    /* "id-hex-partial-message" */
-+     260,    /* "id-it" */
-+     302,    /* "id-it-caKeyUpdateInfo" */
-+     298,    /* "id-it-caProtEncCert" */
-+     311,    /* "id-it-confirmWaitTime" */
-+     303,    /* "id-it-currentCRL" */
-+     300,    /* "id-it-encKeyPairTypes" */
-+     310,    /* "id-it-implicitConfirm" */
-+     308,    /* "id-it-keyPairParamRep" */
-+     307,    /* "id-it-keyPairParamReq" */
-+     312,    /* "id-it-origPKIMessage" */
-+     301,    /* "id-it-preferredSymmAlg" */
-+     309,    /* "id-it-revPassphrase" */
-+     299,    /* "id-it-signKeyPairTypes" */
-+     305,    /* "id-it-subscriptionRequest" */
-+     306,    /* "id-it-subscriptionResponse" */
-+     784,    /* "id-it-suppLangTags" */
-+     304,    /* "id-it-unsupportedOIDs" */
-+     128,    /* "id-kp" */
-+     280,    /* "id-mod-attribute-cert" */
-+     274,    /* "id-mod-cmc" */
-+     277,    /* "id-mod-cmp" */
-+     284,    /* "id-mod-cmp2000" */
-+     273,    /* "id-mod-crmf" */
-+     283,    /* "id-mod-dvcs" */
-+     275,    /* "id-mod-kea-profile-88" */
-+     276,    /* "id-mod-kea-profile-93" */
-+     282,    /* "id-mod-ocsp" */
-+     278,    /* "id-mod-qualified-cert-88" */
-+     279,    /* "id-mod-qualified-cert-93" */
-+     281,    /* "id-mod-timestamp-protocol" */
-+     264,    /* "id-on" */
-+     858,    /* "id-on-permanentIdentifier" */
-+     347,    /* "id-on-personalData" */
-+     265,    /* "id-pda" */
-+     352,    /* "id-pda-countryOfCitizenship" */
-+     353,    /* "id-pda-countryOfResidence" */
-+     348,    /* "id-pda-dateOfBirth" */
-+     351,    /* "id-pda-gender" */
-+     349,    /* "id-pda-placeOfBirth" */
-+     175,    /* "id-pe" */
-+    1031,    /* "id-pkinit" */
-+     261,    /* "id-pkip" */
-+     258,    /* "id-pkix-mod" */
-+     269,    /* "id-pkix1-explicit-88" */
-+     271,    /* "id-pkix1-explicit-93" */
-+     270,    /* "id-pkix1-implicit-88" */
-+     272,    /* "id-pkix1-implicit-93" */
-+     662,    /* "id-ppl" */
-+     664,    /* "id-ppl-anyLanguage" */
-+     667,    /* "id-ppl-independent" */
-+     665,    /* "id-ppl-inheritAll" */
-+     267,    /* "id-qcs" */
-+     359,    /* "id-qcs-pkixQCSyntax-v1" */
-+     259,    /* "id-qt" */
-+     164,    /* "id-qt-cps" */
-+     165,    /* "id-qt-unotice" */
-+     313,    /* "id-regCtrl" */
-+     316,    /* "id-regCtrl-authenticator" */
-+     319,    /* "id-regCtrl-oldCertID" */
-+     318,    /* "id-regCtrl-pkiArchiveOptions" */
-+     317,    /* "id-regCtrl-pkiPublicationInfo" */
-+     320,    /* "id-regCtrl-protocolEncrKey" */
-+     315,    /* "id-regCtrl-regToken" */
-+     314,    /* "id-regInfo" */
-+     322,    /* "id-regInfo-certReq" */
-+     321,    /* "id-regInfo-utf8Pairs" */
-+     973,    /* "id-scrypt" */
-+     512,    /* "id-set" */
-+     191,    /* "id-smime-aa" */
-+     215,    /* "id-smime-aa-contentHint" */
-+     218,    /* "id-smime-aa-contentIdentifier" */
-+     221,    /* "id-smime-aa-contentReference" */
-+     240,    /* "id-smime-aa-dvcs-dvc" */
-+     217,    /* "id-smime-aa-encapContentType" */
-+     222,    /* "id-smime-aa-encrypKeyPref" */
-+     220,    /* "id-smime-aa-equivalentLabels" */
-+     232,    /* "id-smime-aa-ets-CertificateRefs" */
-+     233,    /* "id-smime-aa-ets-RevocationRefs" */
-+     238,    /* "id-smime-aa-ets-archiveTimeStamp" */
-+     237,    /* "id-smime-aa-ets-certCRLTimestamp" */
-+     234,    /* "id-smime-aa-ets-certValues" */
-+     227,    /* "id-smime-aa-ets-commitmentType" */
-+     231,    /* "id-smime-aa-ets-contentTimestamp" */
-+     236,    /* "id-smime-aa-ets-escTimeStamp" */
-+     230,    /* "id-smime-aa-ets-otherSigCert" */
-+     235,    /* "id-smime-aa-ets-revocationValues" */
-+     226,    /* "id-smime-aa-ets-sigPolicyId" */
-+     229,    /* "id-smime-aa-ets-signerAttr" */
-+     228,    /* "id-smime-aa-ets-signerLocation" */
-+     219,    /* "id-smime-aa-macValue" */
-+     214,    /* "id-smime-aa-mlExpandHistory" */
-+     216,    /* "id-smime-aa-msgSigDigest" */
-+     212,    /* "id-smime-aa-receiptRequest" */
-+     213,    /* "id-smime-aa-securityLabel" */
-+     239,    /* "id-smime-aa-signatureType" */
-+     223,    /* "id-smime-aa-signingCertificate" */
-+     224,    /* "id-smime-aa-smimeEncryptCerts" */
-+     225,    /* "id-smime-aa-timeStampToken" */
-+     192,    /* "id-smime-alg" */
-+     243,    /* "id-smime-alg-3DESwrap" */
-+     246,    /* "id-smime-alg-CMS3DESwrap" */
-+     247,    /* "id-smime-alg-CMSRC2wrap" */
-+     245,    /* "id-smime-alg-ESDH" */
-+     241,    /* "id-smime-alg-ESDHwith3DES" */
-+     242,    /* "id-smime-alg-ESDHwithRC2" */
-+     244,    /* "id-smime-alg-RC2wrap" */
-+     193,    /* "id-smime-cd" */
-+     248,    /* "id-smime-cd-ldap" */
-+     190,    /* "id-smime-ct" */
-+     210,    /* "id-smime-ct-DVCSRequestData" */
-+     211,    /* "id-smime-ct-DVCSResponseData" */
-+     208,    /* "id-smime-ct-TDTInfo" */
-+     207,    /* "id-smime-ct-TSTInfo" */
-+     205,    /* "id-smime-ct-authData" */
-+    1059,    /* "id-smime-ct-authEnvelopedData" */
-+     786,    /* "id-smime-ct-compressedData" */
-+    1058,    /* "id-smime-ct-contentCollection" */
-+     209,    /* "id-smime-ct-contentInfo" */
-+     206,    /* "id-smime-ct-publishCert" */
-+     204,    /* "id-smime-ct-receipt" */
-+     195,    /* "id-smime-cti" */
-+     255,    /* "id-smime-cti-ets-proofOfApproval" */
-+     256,    /* "id-smime-cti-ets-proofOfCreation" */
-+     253,    /* "id-smime-cti-ets-proofOfDelivery" */
-+     251,    /* "id-smime-cti-ets-proofOfOrigin" */
-+     252,    /* "id-smime-cti-ets-proofOfReceipt" */
-+     254,    /* "id-smime-cti-ets-proofOfSender" */
-+     189,    /* "id-smime-mod" */
-+     196,    /* "id-smime-mod-cms" */
-+     197,    /* "id-smime-mod-ess" */
-+     202,    /* "id-smime-mod-ets-eSigPolicy-88" */
-+     203,    /* "id-smime-mod-ets-eSigPolicy-97" */
-+     200,    /* "id-smime-mod-ets-eSignature-88" */
-+     201,    /* "id-smime-mod-ets-eSignature-97" */
-+     199,    /* "id-smime-mod-msg-v3" */
-+     198,    /* "id-smime-mod-oid" */
-+     194,    /* "id-smime-spq" */
-+     250,    /* "id-smime-spq-ets-sqt-unotice" */
-+     249,    /* "id-smime-spq-ets-sqt-uri" */
-+     974,    /* "id-tc26" */
-+     991,    /* "id-tc26-agreement" */
-+     992,    /* "id-tc26-agreement-gost-3410-2012-256" */
-+     993,    /* "id-tc26-agreement-gost-3410-2012-512" */
-+     977,    /* "id-tc26-algorithms" */
-+     990,    /* "id-tc26-cipher" */
-+    1001,    /* "id-tc26-cipher-constants" */
-+     994,    /* "id-tc26-constants" */
-+     981,    /* "id-tc26-digest" */
-+    1000,    /* "id-tc26-digest-constants" */
-+    1002,    /* "id-tc26-gost-28147-constants" */
-+    1003,    /* "id-tc26-gost-28147-param-Z" */
-+     996,    /* "id-tc26-gost-3410-2012-512-constants" */
-+     998,    /* "id-tc26-gost-3410-2012-512-paramSetA" */
-+     999,    /* "id-tc26-gost-3410-2012-512-paramSetB" */
-+     997,    /* "id-tc26-gost-3410-2012-512-paramSetTest" */
-+     988,    /* "id-tc26-hmac-gost-3411-2012-256" */
-+     989,    /* "id-tc26-hmac-gost-3411-2012-512" */
-+     987,    /* "id-tc26-mac" */
-+     978,    /* "id-tc26-sign" */
-+     995,    /* "id-tc26-sign-constants" */
-+     984,    /* "id-tc26-signwithdigest" */
-+     985,    /* "id-tc26-signwithdigest-gost3410-2012-256" */
-+     986,    /* "id-tc26-signwithdigest-gost3410-2012-512" */
-+     676,    /* "identified-organization" */
-+     461,    /* "info" */
-+     748,    /* "inhibitAnyPolicy" */
-+     101,    /* "initials" */
-+     647,    /* "international-organizations" */
-+     869,    /* "internationaliSDNNumber" */
-+     142,    /* "invalidityDate" */
-+     294,    /* "ipsecEndSystem" */
-+    1022,    /* "ipsecIKE" */
-+     295,    /* "ipsecTunnel" */
-+     296,    /* "ipsecUser" */
-+      86,    /* "issuerAltName" */
-+    1008,    /* "issuerSignTool" */
-+     770,    /* "issuingDistributionPoint" */
-+     492,    /* "janetMailbox" */
-+     957,    /* "jurisdictionC" */
-+     955,    /* "jurisdictionL" */
-+     956,    /* "jurisdictionST" */
-+     150,    /* "keyBag" */
-+      83,    /* "keyUsage" */
-+     477,    /* "lastModifiedBy" */
-+     476,    /* "lastModifiedTime" */
-+     157,    /* "localKeyID" */
-+     480,    /* "mXRecord" */
-+     460,    /* "mail" */
-+     493,    /* "mailPreferenceOption" */
-+     467,    /* "manager" */
-+     982,    /* "md_gost12_256" */
-+     983,    /* "md_gost12_512" */
-+     809,    /* "md_gost94" */
-+     875,    /* "member" */
-+     182,    /* "member-body" */
-+      51,    /* "messageDigest" */
-+     383,    /* "mgmt" */
-+     504,    /* "mime-mhs" */
-+     506,    /* "mime-mhs-bodies" */
-+     505,    /* "mime-mhs-headings" */
-+     488,    /* "mobileTelephoneNumber" */
-+     136,    /* "msCTLSign" */
-+     135,    /* "msCodeCom" */
-+     134,    /* "msCodeInd" */
-+     138,    /* "msEFS" */
-+     171,    /* "msExtReq" */
-+     137,    /* "msSGC" */
-+     648,    /* "msSmartcardLogin" */
-+     649,    /* "msUPN" */
-+     481,    /* "nSRecord" */
-+     173,    /* "name" */
-+     666,    /* "nameConstraints" */
-+     369,    /* "noCheck" */
-+     403,    /* "noRevAvail" */
-+      72,    /* "nsBaseUrl" */
-+      76,    /* "nsCaPolicyUrl" */
-+      74,    /* "nsCaRevocationUrl" */
-+      58,    /* "nsCertExt" */
-+      79,    /* "nsCertSequence" */
-+      71,    /* "nsCertType" */
-+      78,    /* "nsComment" */
-+      59,    /* "nsDataType" */
-+      75,    /* "nsRenewalUrl" */
-+      73,    /* "nsRevocationUrl" */
-+     139,    /* "nsSGC" */
-+      77,    /* "nsSslServerName" */
-+     681,    /* "onBasis" */
-+     491,    /* "organizationalStatus" */
-+     475,    /* "otherMailbox" */
-+     876,    /* "owner" */
-+     489,    /* "pagerTelephoneNumber" */
-+     374,    /* "path" */
-+     112,    /* "pbeWithMD5AndCast5CBC" */
-+     499,    /* "personalSignature" */
-+     487,    /* "personalTitle" */
-+     464,    /* "photo" */
-+     863,    /* "physicalDeliveryOfficeName" */
-+     437,    /* "pilot" */
-+     439,    /* "pilotAttributeSyntax" */
-+     438,    /* "pilotAttributeType" */
-+     479,    /* "pilotAttributeType27" */
-+     456,    /* "pilotDSA" */
-+     441,    /* "pilotGroups" */
-+     444,    /* "pilotObject" */
-+     440,    /* "pilotObjectClass" */
-+     455,    /* "pilotOrganization" */
-+     445,    /* "pilotPerson" */
-+    1032,    /* "pkInitClientAuth" */
-+    1033,    /* "pkInitKDC" */
-+       2,    /* "pkcs" */
-+     186,    /* "pkcs1" */
-+      27,    /* "pkcs3" */
-+     187,    /* "pkcs5" */
-+      20,    /* "pkcs7" */
-+      21,    /* "pkcs7-data" */
-+      25,    /* "pkcs7-digestData" */
-+      26,    /* "pkcs7-encryptedData" */
-+      23,    /* "pkcs7-envelopedData" */
-+      24,    /* "pkcs7-signedAndEnvelopedData" */
-+      22,    /* "pkcs7-signedData" */
-+     151,    /* "pkcs8ShroudedKeyBag" */
-+      47,    /* "pkcs9" */
-+     401,    /* "policyConstraints" */
-+     747,    /* "policyMappings" */
-+     862,    /* "postOfficeBox" */
-+     861,    /* "postalAddress" */
-+     661,    /* "postalCode" */
-+     683,    /* "ppBasis" */
-+     872,    /* "preferredDeliveryMethod" */
-+     873,    /* "presentationAddress" */
-+     816,    /* "prf-gostr3411-94" */
-+     406,    /* "prime-field" */
-+     409,    /* "prime192v1" */
-+     410,    /* "prime192v2" */
-+     411,    /* "prime192v3" */
-+     412,    /* "prime239v1" */
-+     413,    /* "prime239v2" */
-+     414,    /* "prime239v3" */
-+     415,    /* "prime256v1" */
-+     385,    /* "private" */
-+      84,    /* "privateKeyUsagePeriod" */
-+     886,    /* "protocolInformation" */
-+     663,    /* "proxyCertInfo" */
-+     510,    /* "pseudonym" */
-+     435,    /* "pss" */
-+     286,    /* "qcStatements" */
-+     457,    /* "qualityLabelledData" */
-+     450,    /* "rFC822localPart" */
-+     870,    /* "registeredAddress" */
-+     400,    /* "role" */
-+     877,    /* "roleOccupant" */
-+     448,    /* "room" */
-+     463,    /* "roomNumber" */
-+       6,    /* "rsaEncryption" */
-+     644,    /* "rsaOAEPEncryptionSET" */
-+     377,    /* "rsaSignature" */
-+       1,    /* "rsadsi" */
-+     482,    /* "sOARecord" */
-+     155,    /* "safeContentsBag" */
-+     291,    /* "sbgp-autonomousSysNum" */
-+     290,    /* "sbgp-ipAddrBlock" */
-+     292,    /* "sbgp-routerIdentifier" */
-+     159,    /* "sdsiCertificate" */
-+     859,    /* "searchGuide" */
-+     704,    /* "secp112r1" */
-+     705,    /* "secp112r2" */
-+     706,    /* "secp128r1" */
-+     707,    /* "secp128r2" */
-+     708,    /* "secp160k1" */
-+     709,    /* "secp160r1" */
-+     710,    /* "secp160r2" */
-+     711,    /* "secp192k1" */
-+     712,    /* "secp224k1" */
-+     713,    /* "secp224r1" */
-+     714,    /* "secp256k1" */
-+     715,    /* "secp384r1" */
-+     716,    /* "secp521r1" */
-+     154,    /* "secretBag" */
-+     474,    /* "secretary" */
-+     717,    /* "sect113r1" */
-+     718,    /* "sect113r2" */
-+     719,    /* "sect131r1" */
-+     720,    /* "sect131r2" */
-+     721,    /* "sect163k1" */
-+     722,    /* "sect163r1" */
-+     723,    /* "sect163r2" */
-+     724,    /* "sect193r1" */
-+     725,    /* "sect193r2" */
-+     726,    /* "sect233k1" */
-+     727,    /* "sect233r1" */
-+     728,    /* "sect239k1" */
-+     729,    /* "sect283k1" */
-+     730,    /* "sect283r1" */
-+     731,    /* "sect409k1" */
-+     732,    /* "sect409r1" */
-+     733,    /* "sect571k1" */
-+     734,    /* "sect571r1" */
-+    1025,    /* "secureShellClient" */
-+    1026,    /* "secureShellServer" */
-+     386,    /* "security" */
-+     878,    /* "seeAlso" */
-+     394,    /* "selected-attribute-types" */
-+    1029,    /* "sendOwner" */
-+    1030,    /* "sendProxiedOwner" */
-+    1028,    /* "sendProxiedRouter" */
-+    1027,    /* "sendRouter" */
-+     105,    /* "serialNumber" */
-+     129,    /* "serverAuth" */
-+     371,    /* "serviceLocator" */
-+     625,    /* "set-addPolicy" */
-+     515,    /* "set-attr" */
-+     518,    /* "set-brand" */
-+     638,    /* "set-brand-AmericanExpress" */
-+     637,    /* "set-brand-Diners" */
-+     636,    /* "set-brand-IATA-ATA" */
-+     639,    /* "set-brand-JCB" */
-+     641,    /* "set-brand-MasterCard" */
-+     642,    /* "set-brand-Novus" */
-+     640,    /* "set-brand-Visa" */
-+     517,    /* "set-certExt" */
-+     513,    /* "set-ctype" */
-+     514,    /* "set-msgExt" */
-+     516,    /* "set-policy" */
-+     607,    /* "set-policy-root" */
-+     624,    /* "set-rootKeyThumb" */
-+     620,    /* "setAttr-Cert" */
-+     631,    /* "setAttr-GenCryptgrm" */
-+     623,    /* "setAttr-IssCap" */
-+     628,    /* "setAttr-IssCap-CVM" */
-+     630,    /* "setAttr-IssCap-Sig" */
-+     629,    /* "setAttr-IssCap-T2" */
-+     621,    /* "setAttr-PGWYcap" */
-+     635,    /* "setAttr-SecDevSig" */
-+     632,    /* "setAttr-T2Enc" */
-+     633,    /* "setAttr-T2cleartxt" */
-+     634,    /* "setAttr-TokICCsig" */
-+     627,    /* "setAttr-Token-B0Prime" */
-+     626,    /* "setAttr-Token-EMV" */
-+     622,    /* "setAttr-TokenType" */
-+     619,    /* "setCext-IssuerCapabilities" */
-+     615,    /* "setCext-PGWYcapabilities" */
-+     616,    /* "setCext-TokenIdentifier" */
-+     618,    /* "setCext-TokenType" */
-+     617,    /* "setCext-Track2Data" */
-+     611,    /* "setCext-cCertRequired" */
-+     609,    /* "setCext-certType" */
-+     608,    /* "setCext-hashedRoot" */
-+     610,    /* "setCext-merchData" */
-+     613,    /* "setCext-setExt" */
-+     614,    /* "setCext-setQualf" */
-+     612,    /* "setCext-tunneling" */
-+     540,    /* "setct-AcqCardCodeMsg" */
-+     576,    /* "setct-AcqCardCodeMsgTBE" */
-+     570,    /* "setct-AuthReqTBE" */
-+     534,    /* "setct-AuthReqTBS" */
-+     527,    /* "setct-AuthResBaggage" */
-+     571,    /* "setct-AuthResTBE" */
-+     572,    /* "setct-AuthResTBEX" */
-+     535,    /* "setct-AuthResTBS" */
-+     536,    /* "setct-AuthResTBSX" */
-+     528,    /* "setct-AuthRevReqBaggage" */
-+     577,    /* "setct-AuthRevReqTBE" */
-+     541,    /* "setct-AuthRevReqTBS" */
-+     529,    /* "setct-AuthRevResBaggage" */
-+     542,    /* "setct-AuthRevResData" */
-+     578,    /* "setct-AuthRevResTBE" */
-+     579,    /* "setct-AuthRevResTBEB" */
-+     543,    /* "setct-AuthRevResTBS" */
-+     573,    /* "setct-AuthTokenTBE" */
-+     537,    /* "setct-AuthTokenTBS" */
-+     600,    /* "setct-BCIDistributionTBS" */
-+     558,    /* "setct-BatchAdminReqData" */
-+     592,    /* "setct-BatchAdminReqTBE" */
-+     559,    /* "setct-BatchAdminResData" */
-+     593,    /* "setct-BatchAdminResTBE" */
-+     599,    /* "setct-CRLNotificationResTBS" */
-+     598,    /* "setct-CRLNotificationTBS" */
-+     580,    /* "setct-CapReqTBE" */
-+     581,    /* "setct-CapReqTBEX" */
-+     544,    /* "setct-CapReqTBS" */
-+     545,    /* "setct-CapReqTBSX" */
-+     546,    /* "setct-CapResData" */
-+     582,    /* "setct-CapResTBE" */
-+     583,    /* "setct-CapRevReqTBE" */
-+     584,    /* "setct-CapRevReqTBEX" */
-+     547,    /* "setct-CapRevReqTBS" */
-+     548,    /* "setct-CapRevReqTBSX" */
-+     549,    /* "setct-CapRevResData" */
-+     585,    /* "setct-CapRevResTBE" */
-+     538,    /* "setct-CapTokenData" */
-+     530,    /* "setct-CapTokenSeq" */
-+     574,    /* "setct-CapTokenTBE" */
-+     575,    /* "setct-CapTokenTBEX" */
-+     539,    /* "setct-CapTokenTBS" */
-+     560,    /* "setct-CardCInitResTBS" */
-+     566,    /* "setct-CertInqReqTBS" */
-+     563,    /* "setct-CertReqData" */
-+     595,    /* "setct-CertReqTBE" */
-+     596,    /* "setct-CertReqTBEX" */
-+     564,    /* "setct-CertReqTBS" */
-+     565,    /* "setct-CertResData" */
-+     597,    /* "setct-CertResTBE" */
-+     586,    /* "setct-CredReqTBE" */
-+     587,    /* "setct-CredReqTBEX" */
-+     550,    /* "setct-CredReqTBS" */
-+     551,    /* "setct-CredReqTBSX" */
-+     552,    /* "setct-CredResData" */
-+     588,    /* "setct-CredResTBE" */
-+     589,    /* "setct-CredRevReqTBE" */
-+     590,    /* "setct-CredRevReqTBEX" */
-+     553,    /* "setct-CredRevReqTBS" */
-+     554,    /* "setct-CredRevReqTBSX" */
-+     555,    /* "setct-CredRevResData" */
-+     591,    /* "setct-CredRevResTBE" */
-+     567,    /* "setct-ErrorTBS" */
-+     526,    /* "setct-HODInput" */
-+     561,    /* "setct-MeAqCInitResTBS" */
-+     522,    /* "setct-OIData" */
-+     519,    /* "setct-PANData" */
-+     521,    /* "setct-PANOnly" */
-+     520,    /* "setct-PANToken" */
-+     556,    /* "setct-PCertReqData" */
-+     557,    /* "setct-PCertResTBS" */
-+     523,    /* "setct-PI" */
-+     532,    /* "setct-PI-TBS" */
-+     524,    /* "setct-PIData" */
-+     525,    /* "setct-PIDataUnsigned" */
-+     568,    /* "setct-PIDualSignedTBE" */
-+     569,    /* "setct-PIUnsignedTBE" */
-+     531,    /* "setct-PInitResData" */
-+     533,    /* "setct-PResData" */
-+     594,    /* "setct-RegFormReqTBE" */
-+     562,    /* "setct-RegFormResTBS" */
-+     606,    /* "setext-cv" */
-+     601,    /* "setext-genCrypt" */
-+     602,    /* "setext-miAuth" */
-+     604,    /* "setext-pinAny" */
-+     603,    /* "setext-pinSecure" */
-+     605,    /* "setext-track2" */
-+      52,    /* "signingTime" */
-+     454,    /* "simpleSecurityObject" */
-+     496,    /* "singleLevelQuality" */
-+     387,    /* "snmpv2" */
-+     660,    /* "street" */
-+      85,    /* "subjectAltName" */
-+     769,    /* "subjectDirectoryAttributes" */
-+     398,    /* "subjectInfoAccess" */
-+      82,    /* "subjectKeyIdentifier" */
-+    1007,    /* "subjectSignTool" */
-+     498,    /* "subtreeMaximumQuality" */
-+     497,    /* "subtreeMinimumQuality" */
-+     890,    /* "supportedAlgorithms" */
-+     874,    /* "supportedApplicationContext" */
-+     402,    /* "targetInformation" */
-+     864,    /* "telephoneNumber" */
-+     866,    /* "teletexTerminalIdentifier" */
-+     865,    /* "telexNumber" */
-+     459,    /* "textEncodedORAddress" */
-+     293,    /* "textNotice" */
-+     133,    /* "timeStamping" */
-+     106,    /* "title" */
-+    1020,    /* "tlsfeature" */
-+     682,    /* "tpBasis" */
-+     375,    /* "trustRoot" */
-+     436,    /* "ucl" */
-+     102,    /* "uid" */
-+     888,    /* "uniqueMember" */
-+      55,    /* "unstructuredAddress" */
-+      49,    /* "unstructuredName" */
-+     880,    /* "userCertificate" */
-+     465,    /* "userClass" */
-+     879,    /* "userPassword" */
-+     373,    /* "valid" */
-+     678,    /* "wap" */
-+     679,    /* "wap-wsg" */
-+     735,    /* "wap-wsg-idm-ecid-wtls1" */
-+     743,    /* "wap-wsg-idm-ecid-wtls10" */
-+     744,    /* "wap-wsg-idm-ecid-wtls11" */
-+     745,    /* "wap-wsg-idm-ecid-wtls12" */
-+     736,    /* "wap-wsg-idm-ecid-wtls3" */
-+     737,    /* "wap-wsg-idm-ecid-wtls4" */
-+     738,    /* "wap-wsg-idm-ecid-wtls5" */
-+     739,    /* "wap-wsg-idm-ecid-wtls6" */
-+     740,    /* "wap-wsg-idm-ecid-wtls7" */
-+     741,    /* "wap-wsg-idm-ecid-wtls8" */
-+     742,    /* "wap-wsg-idm-ecid-wtls9" */
-+     804,    /* "whirlpool" */
-+     868,    /* "x121Address" */
-+     503,    /* "x500UniqueIdentifier" */
-+     158,    /* "x509Certificate" */
-+     160,    /* "x509Crl" */
-+};
-+
-+#define NUM_LN 1052
-+static const unsigned int ln_objs[NUM_LN] = {
-+     363,    /* "AD Time Stamping" */
-+     405,    /* "ANSI X9.62" */
-+     368,    /* "Acceptable OCSP Responses" */
-+     910,    /* "Any Extended Key Usage" */
-+     664,    /* "Any language" */
-+     177,    /* "Authority Information Access" */
-+     365,    /* "Basic OCSP Response" */
-+     285,    /* "Biometric Info" */
-+     179,    /* "CA Issuers" */
-+     785,    /* "CA Repository" */
-+     954,    /* "CT Certificate SCTs" */
-+     952,    /* "CT Precertificate Poison" */
-+     951,    /* "CT Precertificate SCTs" */
-+     953,    /* "CT Precertificate Signer" */
-+     131,    /* "Code Signing" */
-+    1024,    /* "Ctrl/Provision WAP Termination" */
-+    1023,    /* "Ctrl/provision WAP Access" */
-+     783,    /* "Diffie-Hellman based MAC" */
-+     382,    /* "Directory" */
-+     392,    /* "Domain" */
-+     132,    /* "E-mail Protection" */
-+     389,    /* "Enterprises" */
-+     384,    /* "Experimental" */
-+     372,    /* "Extended OCSP Status" */
-+     172,    /* "Extension Request" */
-+     813,    /* "GOST 28147-89" */
-+     849,    /* "GOST 28147-89 Cryptocom ParamSet" */
-+     815,    /* "GOST 28147-89 MAC" */
-+    1003,    /* "GOST 28147-89 TC26 parameter set" */
-+     851,    /* "GOST 34.10-2001 Cryptocom" */
-+     850,    /* "GOST 34.10-94 Cryptocom" */
-+     811,    /* "GOST R 34.10-2001" */
-+     817,    /* "GOST R 34.10-2001 DH" */
-+     998,    /* "GOST R 34.10-2012 (512 bit) ParamSet A" */
-+     999,    /* "GOST R 34.10-2012 (512 bit) ParamSet B" */
-+     997,    /* "GOST R 34.10-2012 (512 bit) testing parameter set" */
-+     979,    /* "GOST R 34.10-2012 with 256 bit modulus" */
-+     980,    /* "GOST R 34.10-2012 with 512 bit modulus" */
-+     985,    /* "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)" */
-+     986,    /* "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)" */
-+     812,    /* "GOST R 34.10-94" */
-+     818,    /* "GOST R 34.10-94 DH" */
-+     982,    /* "GOST R 34.11-2012 with 256 bit hash" */
-+     983,    /* "GOST R 34.11-2012 with 512 bit hash" */
-+     809,    /* "GOST R 34.11-94" */
-+     816,    /* "GOST R 34.11-94 PRF" */
-+     807,    /* "GOST R 34.11-94 with GOST R 34.10-2001" */
-+     853,    /* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */
-+     808,    /* "GOST R 34.11-94 with GOST R 34.10-94" */
-+     852,    /* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */
-+     854,    /* "GOST R 3410-2001 Parameter Set Cryptocom" */
-+     988,    /* "HMAC GOST 34.11-2012 256 bit" */
-+     989,    /* "HMAC GOST 34.11-2012 512 bit" */
-+     810,    /* "HMAC GOST 34.11-94" */
-+     432,    /* "Hold Instruction Call Issuer" */
-+     430,    /* "Hold Instruction Code" */
-+     431,    /* "Hold Instruction None" */
-+     433,    /* "Hold Instruction Reject" */
-+     634,    /* "ICC or token signature" */
-+    1004,    /* "INN" */
-+     294,    /* "IPSec End System" */
-+     295,    /* "IPSec Tunnel" */
-+     296,    /* "IPSec User" */
-+     182,    /* "ISO Member Body" */
-+     183,    /* "ISO US Member Body" */
-+     667,    /* "Independent" */
-+     665,    /* "Inherit all" */
-+     647,    /* "International Organizations" */
-+     142,    /* "Invalidity Date" */
-+     504,    /* "MIME MHS" */
-+     388,    /* "Mail" */
-+     383,    /* "Management" */
-+     417,    /* "Microsoft CSP Name" */
-+     135,    /* "Microsoft Commercial Code Signing" */
-+     138,    /* "Microsoft Encrypted File System" */
-+     171,    /* "Microsoft Extension Request" */
-+     134,    /* "Microsoft Individual Code Signing" */
-+     856,    /* "Microsoft Local Key set" */
-+     137,    /* "Microsoft Server Gated Crypto" */
-+     648,    /* "Microsoft Smartcardlogin" */
-+     136,    /* "Microsoft Trust List Signing" */
-+     649,    /* "Microsoft Universal Principal Name" */
-+     393,    /* "NULL" */
-+     404,    /* "NULL" */
-+      72,    /* "Netscape Base Url" */
-+      76,    /* "Netscape CA Policy Url" */
-+      74,    /* "Netscape CA Revocation Url" */
-+      71,    /* "Netscape Cert Type" */
-+      58,    /* "Netscape Certificate Extension" */
-+      79,    /* "Netscape Certificate Sequence" */
-+      78,    /* "Netscape Comment" */
-+      57,    /* "Netscape Communications Corp." */
-+      59,    /* "Netscape Data Type" */
-+      75,    /* "Netscape Renewal Url" */
-+      73,    /* "Netscape Revocation Url" */
-+      77,    /* "Netscape SSL Server Name" */
-+     139,    /* "Netscape Server Gated Crypto" */
-+     178,    /* "OCSP" */
-+     370,    /* "OCSP Archive Cutoff" */
-+     367,    /* "OCSP CRL ID" */
-+     369,    /* "OCSP No Check" */
-+     366,    /* "OCSP Nonce" */
-+     371,    /* "OCSP Service Locator" */
-+     180,    /* "OCSP Signing" */
-+    1005,    /* "OGRN" */
-+     161,    /* "PBES2" */
-+      69,    /* "PBKDF2" */
-+     162,    /* "PBMAC1" */
-+    1032,    /* "PKINIT Client Auth" */
-+     127,    /* "PKIX" */
-+     858,    /* "Permanent Identifier" */
-+     164,    /* "Policy Qualifier CPS" */
-+     165,    /* "Policy Qualifier User Notice" */
-+     385,    /* "Private" */
-+     663,    /* "Proxy Certificate Information" */
-+       1,    /* "RSA Data Security, Inc." */
-+       2,    /* "RSA Data Security, Inc. PKCS" */
-+     188,    /* "S/MIME" */
-+     167,    /* "S/MIME Capabilities" */
-+    1006,    /* "SNILS" */
-+     387,    /* "SNMPv2" */
-+    1025,    /* "SSH Client" */
-+    1026,    /* "SSH Server" */
-+     512,    /* "Secure Electronic Transactions" */
-+     386,    /* "Security" */
-+     394,    /* "Selected Attribute Types" */
-+    1029,    /* "Send Owner" */
-+    1030,    /* "Send Proxied Owner" */
-+    1028,    /* "Send Proxied Router" */
-+    1027,    /* "Send Router" */
-+    1033,    /* "Signing KDC Response" */
-+    1008,    /* "Signing Tool of Issuer" */
-+    1007,    /* "Signing Tool of Subject" */
-+     143,    /* "Strong Extranet ID" */
-+     398,    /* "Subject Information Access" */
-+    1020,    /* "TLS Feature" */
-+     130,    /* "TLS Web Client Authentication" */
-+     129,    /* "TLS Web Server Authentication" */
-+     133,    /* "Time Stamping" */
-+     375,    /* "Trust Root" */
-+    1034,    /* "X25519" */
-+    1035,    /* "X448" */
-+      12,    /* "X509" */
-+     402,    /* "X509v3 AC Targeting" */
-+     746,    /* "X509v3 Any Policy" */
-+      90,    /* "X509v3 Authority Key Identifier" */
-+      87,    /* "X509v3 Basic Constraints" */
-+     103,    /* "X509v3 CRL Distribution Points" */
-+      88,    /* "X509v3 CRL Number" */
-+     141,    /* "X509v3 CRL Reason Code" */
-+     771,    /* "X509v3 Certificate Issuer" */
-+      89,    /* "X509v3 Certificate Policies" */
-+     140,    /* "X509v3 Delta CRL Indicator" */
-+     126,    /* "X509v3 Extended Key Usage" */
-+     857,    /* "X509v3 Freshest CRL" */
-+     748,    /* "X509v3 Inhibit Any Policy" */
-+      86,    /* "X509v3 Issuer Alternative Name" */
-+     770,    /* "X509v3 Issuing Distribution Point" */
-+      83,    /* "X509v3 Key Usage" */
-+     666,    /* "X509v3 Name Constraints" */
-+     403,    /* "X509v3 No Revocation Available" */
-+     401,    /* "X509v3 Policy Constraints" */
-+     747,    /* "X509v3 Policy Mappings" */
-+      84,    /* "X509v3 Private Key Usage Period" */
-+      85,    /* "X509v3 Subject Alternative Name" */
-+     769,    /* "X509v3 Subject Directory Attributes" */
-+      82,    /* "X509v3 Subject Key Identifier" */
-+     920,    /* "X9.42 DH" */
-+     184,    /* "X9.57" */
-+     185,    /* "X9.57 CM ?" */
-+     478,    /* "aRecord" */
-+     289,    /* "aaControls" */
-+     287,    /* "ac-auditEntity" */
-+     397,    /* "ac-proxying" */
-+     288,    /* "ac-targeting" */
-+     446,    /* "account" */
-+     364,    /* "ad dvcs" */
-+     606,    /* "additional verification" */
-+     419,    /* "aes-128-cbc" */
-+     916,    /* "aes-128-cbc-hmac-sha1" */
-+     948,    /* "aes-128-cbc-hmac-sha256" */
-+     896,    /* "aes-128-ccm" */
-+     421,    /* "aes-128-cfb" */
-+     650,    /* "aes-128-cfb1" */
-+     653,    /* "aes-128-cfb8" */
-+     904,    /* "aes-128-ctr" */
-+     418,    /* "aes-128-ecb" */
-+     895,    /* "aes-128-gcm" */
-+     958,    /* "aes-128-ocb" */
-+     420,    /* "aes-128-ofb" */
-+     913,    /* "aes-128-xts" */
-+     423,    /* "aes-192-cbc" */
-+     917,    /* "aes-192-cbc-hmac-sha1" */
-+     949,    /* "aes-192-cbc-hmac-sha256" */
-+     899,    /* "aes-192-ccm" */
-+     425,    /* "aes-192-cfb" */
-+     651,    /* "aes-192-cfb1" */
-+     654,    /* "aes-192-cfb8" */
-+     905,    /* "aes-192-ctr" */
-+     422,    /* "aes-192-ecb" */
-+     898,    /* "aes-192-gcm" */
-+     959,    /* "aes-192-ocb" */
-+     424,    /* "aes-192-ofb" */
-+     427,    /* "aes-256-cbc" */
-+     918,    /* "aes-256-cbc-hmac-sha1" */
-+     950,    /* "aes-256-cbc-hmac-sha256" */
-+     902,    /* "aes-256-ccm" */
-+     429,    /* "aes-256-cfb" */
-+     652,    /* "aes-256-cfb1" */
-+     655,    /* "aes-256-cfb8" */
-+     906,    /* "aes-256-ctr" */
-+     426,    /* "aes-256-ecb" */
-+     901,    /* "aes-256-gcm" */
-+     960,    /* "aes-256-ocb" */
-+     428,    /* "aes-256-ofb" */
-+     914,    /* "aes-256-xts" */
-+     376,    /* "algorithm" */
-+     484,    /* "associatedDomain" */
-+     485,    /* "associatedName" */
-+     501,    /* "audio" */
-+    1049,    /* "auth-dss" */
-+    1047,    /* "auth-ecdsa" */
-+    1050,    /* "auth-gost01" */
-+    1051,    /* "auth-gost12" */
-+    1053,    /* "auth-null" */
-+    1048,    /* "auth-psk" */
-+    1046,    /* "auth-rsa" */
-+    1052,    /* "auth-srp" */
-+     882,    /* "authorityRevocationList" */
-+      91,    /* "bf-cbc" */
-+      93,    /* "bf-cfb" */
-+      92,    /* "bf-ecb" */
-+      94,    /* "bf-ofb" */
-+    1056,    /* "blake2b512" */
-+    1057,    /* "blake2s256" */
-+     921,    /* "brainpoolP160r1" */
-+     922,    /* "brainpoolP160t1" */
-+     923,    /* "brainpoolP192r1" */
-+     924,    /* "brainpoolP192t1" */
-+     925,    /* "brainpoolP224r1" */
-+     926,    /* "brainpoolP224t1" */
-+     927,    /* "brainpoolP256r1" */
-+     928,    /* "brainpoolP256t1" */
-+     929,    /* "brainpoolP320r1" */
-+     930,    /* "brainpoolP320t1" */
-+     931,    /* "brainpoolP384r1" */
-+     932,    /* "brainpoolP384t1" */
-+     933,    /* "brainpoolP512r1" */
-+     934,    /* "brainpoolP512t1" */
-+     494,    /* "buildingName" */
-+     860,    /* "businessCategory" */
-+     691,    /* "c2onb191v4" */
-+     692,    /* "c2onb191v5" */
-+     697,    /* "c2onb239v4" */
-+     698,    /* "c2onb239v5" */
-+     684,    /* "c2pnb163v1" */
-+     685,    /* "c2pnb163v2" */
-+     686,    /* "c2pnb163v3" */
-+     687,    /* "c2pnb176v1" */
-+     693,    /* "c2pnb208w1" */
-+     699,    /* "c2pnb272w1" */
-+     700,    /* "c2pnb304w1" */
-+     702,    /* "c2pnb368w1" */
-+     688,    /* "c2tnb191v1" */
-+     689,    /* "c2tnb191v2" */
-+     690,    /* "c2tnb191v3" */
-+     694,    /* "c2tnb239v1" */
-+     695,    /* "c2tnb239v2" */
-+     696,    /* "c2tnb239v3" */
-+     701,    /* "c2tnb359v1" */
-+     703,    /* "c2tnb431r1" */
-+     881,    /* "cACertificate" */
-+     483,    /* "cNAMERecord" */
-+     751,    /* "camellia-128-cbc" */
-+     962,    /* "camellia-128-ccm" */
-+     757,    /* "camellia-128-cfb" */
-+     760,    /* "camellia-128-cfb1" */
-+     763,    /* "camellia-128-cfb8" */
-+     964,    /* "camellia-128-cmac" */
-+     963,    /* "camellia-128-ctr" */
-+     754,    /* "camellia-128-ecb" */
-+     961,    /* "camellia-128-gcm" */
-+     766,    /* "camellia-128-ofb" */
-+     752,    /* "camellia-192-cbc" */
-+     966,    /* "camellia-192-ccm" */
-+     758,    /* "camellia-192-cfb" */
-+     761,    /* "camellia-192-cfb1" */
-+     764,    /* "camellia-192-cfb8" */
-+     968,    /* "camellia-192-cmac" */
-+     967,    /* "camellia-192-ctr" */
-+     755,    /* "camellia-192-ecb" */
-+     965,    /* "camellia-192-gcm" */
-+     767,    /* "camellia-192-ofb" */
-+     753,    /* "camellia-256-cbc" */
-+     970,    /* "camellia-256-ccm" */
-+     759,    /* "camellia-256-cfb" */
-+     762,    /* "camellia-256-cfb1" */
-+     765,    /* "camellia-256-cfb8" */
-+     972,    /* "camellia-256-cmac" */
-+     971,    /* "camellia-256-ctr" */
-+     756,    /* "camellia-256-ecb" */
-+     969,    /* "camellia-256-gcm" */
-+     768,    /* "camellia-256-ofb" */
-+     443,    /* "caseIgnoreIA5StringSyntax" */
-+     108,    /* "cast5-cbc" */
-+     110,    /* "cast5-cfb" */
-+     109,    /* "cast5-ecb" */
-+     111,    /* "cast5-ofb" */
-+     152,    /* "certBag" */
-+     677,    /* "certicom-arc" */
-+     517,    /* "certificate extensions" */
-+     883,    /* "certificateRevocationList" */
-+    1019,    /* "chacha20" */
-+    1018,    /* "chacha20-poly1305" */
-+      54,    /* "challengePassword" */
-+     407,    /* "characteristic-two-field" */
-+     395,    /* "clearance" */
-+     633,    /* "cleartext track 2" */
-+     894,    /* "cmac" */
-+      13,    /* "commonName" */
-+     513,    /* "content types" */
-+      50,    /* "contentType" */
-+      53,    /* "countersignature" */
-+      14,    /* "countryName" */
-+     153,    /* "crlBag" */
-+     884,    /* "crossCertificatePair" */
-+     806,    /* "cryptocom" */
-+     805,    /* "cryptopro" */
-+     500,    /* "dITRedirect" */
-+     451,    /* "dNSDomain" */
-+     495,    /* "dSAQuality" */
-+     434,    /* "data" */
-+     390,    /* "dcObject" */
-+     891,    /* "deltaRevocationList" */
-+      31,    /* "des-cbc" */
-+     643,    /* "des-cdmf" */
-+      30,    /* "des-cfb" */
-+     656,    /* "des-cfb1" */
-+     657,    /* "des-cfb8" */
-+      29,    /* "des-ecb" */
-+      32,    /* "des-ede" */
-+      43,    /* "des-ede-cbc" */
-+      60,    /* "des-ede-cfb" */
-+      62,    /* "des-ede-ofb" */
-+      33,    /* "des-ede3" */
-+      44,    /* "des-ede3-cbc" */
-+      61,    /* "des-ede3-cfb" */
-+     658,    /* "des-ede3-cfb1" */
-+     659,    /* "des-ede3-cfb8" */
-+      63,    /* "des-ede3-ofb" */
-+      45,    /* "des-ofb" */
-+     107,    /* "description" */
-+     871,    /* "destinationIndicator" */
-+      80,    /* "desx-cbc" */
-+     947,    /* "dh-cofactor-kdf" */
-+     946,    /* "dh-std-kdf" */
-+      28,    /* "dhKeyAgreement" */
-+     941,    /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */
-+     942,    /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */
-+     943,    /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */
-+     944,    /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */
-+     945,    /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */
-+     936,    /* "dhSinglePass-stdDH-sha1kdf-scheme" */
-+     937,    /* "dhSinglePass-stdDH-sha224kdf-scheme" */
-+     938,    /* "dhSinglePass-stdDH-sha256kdf-scheme" */
-+     939,    /* "dhSinglePass-stdDH-sha384kdf-scheme" */
-+     940,    /* "dhSinglePass-stdDH-sha512kdf-scheme" */
-+      11,    /* "directory services (X.500)" */
-+     378,    /* "directory services - algorithms" */
-+     887,    /* "distinguishedName" */
-+     892,    /* "dmdName" */
-+     174,    /* "dnQualifier" */
-+     447,    /* "document" */
-+     471,    /* "documentAuthor" */
-+     468,    /* "documentIdentifier" */
-+     472,    /* "documentLocation" */
-+     502,    /* "documentPublisher" */
-+     449,    /* "documentSeries" */
-+     469,    /* "documentTitle" */
-+     470,    /* "documentVersion" */
-+     380,    /* "dod" */
-+     391,    /* "domainComponent" */
-+     452,    /* "domainRelatedObject" */
-+     116,    /* "dsaEncryption" */
-+      67,    /* "dsaEncryption-old" */
-+      66,    /* "dsaWithSHA" */
-+     113,    /* "dsaWithSHA1" */
-+      70,    /* "dsaWithSHA1-old" */
-+     802,    /* "dsa_with_SHA224" */
-+     803,    /* "dsa_with_SHA256" */
-+     297,    /* "dvcs" */
-+     791,    /* "ecdsa-with-Recommended" */
-+     416,    /* "ecdsa-with-SHA1" */
-+     793,    /* "ecdsa-with-SHA224" */
-+     794,    /* "ecdsa-with-SHA256" */
-+     795,    /* "ecdsa-with-SHA384" */
-+     796,    /* "ecdsa-with-SHA512" */
-+     792,    /* "ecdsa-with-Specified" */
-+      48,    /* "emailAddress" */
-+     632,    /* "encrypted track 2" */
-+     885,    /* "enhancedSearchGuide" */
-+      56,    /* "extendedCertificateAttributes" */
-+     867,    /* "facsimileTelephoneNumber" */
-+     462,    /* "favouriteDrink" */
-+     453,    /* "friendlyCountry" */
-+     490,    /* "friendlyCountryName" */
-+     156,    /* "friendlyName" */
-+     631,    /* "generate cryptogram" */
-+     509,    /* "generationQualifier" */
-+     601,    /* "generic cryptogram" */
-+      99,    /* "givenName" */
-+     976,    /* "gost-mac-12" */
-+    1009,    /* "gost89-cbc" */
-+     814,    /* "gost89-cnt" */
-+     975,    /* "gost89-cnt-12" */
-+    1011,    /* "gost89-ctr" */
-+    1010,    /* "gost89-ecb" */
-+    1015,    /* "grasshopper-cbc" */
-+    1016,    /* "grasshopper-cfb" */
-+    1013,    /* "grasshopper-ctr" */
-+    1012,    /* "grasshopper-ecb" */
-+    1017,    /* "grasshopper-mac" */
-+    1014,    /* "grasshopper-ofb" */
-+    1036,    /* "hkdf" */
-+     855,    /* "hmac" */
-+     780,    /* "hmac-md5" */
-+     781,    /* "hmac-sha1" */
-+     797,    /* "hmacWithMD5" */
-+     163,    /* "hmacWithSHA1" */
-+     798,    /* "hmacWithSHA224" */
-+     799,    /* "hmacWithSHA256" */
-+     800,    /* "hmacWithSHA384" */
-+     801,    /* "hmacWithSHA512" */
-+     486,    /* "homePostalAddress" */
-+     473,    /* "homeTelephoneNumber" */
-+     466,    /* "host" */
-+     889,    /* "houseIdentifier" */
-+     442,    /* "iA5StringSyntax" */
-+     381,    /* "iana" */
-+     824,    /* "id-Gost28147-89-CryptoPro-A-ParamSet" */
-+     825,    /* "id-Gost28147-89-CryptoPro-B-ParamSet" */
-+     826,    /* "id-Gost28147-89-CryptoPro-C-ParamSet" */
-+     827,    /* "id-Gost28147-89-CryptoPro-D-ParamSet" */
-+     819,    /* "id-Gost28147-89-CryptoPro-KeyMeshing" */
-+     829,    /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
-+     828,    /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
-+     830,    /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
-+     820,    /* "id-Gost28147-89-None-KeyMeshing" */
-+     823,    /* "id-Gost28147-89-TestParamSet" */
-+     840,    /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
-+     841,    /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
-+     842,    /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
-+     843,    /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
-+     844,    /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
-+     839,    /* "id-GostR3410-2001-TestParamSet" */
-+     832,    /* "id-GostR3410-94-CryptoPro-A-ParamSet" */
-+     833,    /* "id-GostR3410-94-CryptoPro-B-ParamSet" */
-+     834,    /* "id-GostR3410-94-CryptoPro-C-ParamSet" */
-+     835,    /* "id-GostR3410-94-CryptoPro-D-ParamSet" */
-+     836,    /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
-+     837,    /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
-+     838,    /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
-+     831,    /* "id-GostR3410-94-TestParamSet" */
-+     845,    /* "id-GostR3410-94-a" */
-+     846,    /* "id-GostR3410-94-aBis" */
-+     847,    /* "id-GostR3410-94-b" */
-+     848,    /* "id-GostR3410-94-bBis" */
-+     822,    /* "id-GostR3411-94-CryptoProParamSet" */
-+     821,    /* "id-GostR3411-94-TestParamSet" */
-+     266,    /* "id-aca" */
-+     355,    /* "id-aca-accessIdentity" */
-+     354,    /* "id-aca-authenticationInfo" */
-+     356,    /* "id-aca-chargingIdentity" */
-+     399,    /* "id-aca-encAttrs" */
-+     357,    /* "id-aca-group" */
-+     358,    /* "id-aca-role" */
-+     176,    /* "id-ad" */
-+     788,    /* "id-aes128-wrap" */
-+     897,    /* "id-aes128-wrap-pad" */
-+     789,    /* "id-aes192-wrap" */
-+     900,    /* "id-aes192-wrap-pad" */
-+     790,    /* "id-aes256-wrap" */
-+     903,    /* "id-aes256-wrap-pad" */
-+     262,    /* "id-alg" */
-+     893,    /* "id-alg-PWRI-KEK" */
-+     323,    /* "id-alg-des40" */
-+     326,    /* "id-alg-dh-pop" */
-+     325,    /* "id-alg-dh-sig-hmac-sha1" */
-+     324,    /* "id-alg-noSignature" */
-+     907,    /* "id-camellia128-wrap" */
-+     908,    /* "id-camellia192-wrap" */
-+     909,    /* "id-camellia256-wrap" */
-+     268,    /* "id-cct" */
-+     361,    /* "id-cct-PKIData" */
-+     362,    /* "id-cct-PKIResponse" */
-+     360,    /* "id-cct-crs" */
-+      81,    /* "id-ce" */
-+     680,    /* "id-characteristic-two-basis" */
-+     263,    /* "id-cmc" */
-+     334,    /* "id-cmc-addExtensions" */
-+     346,    /* "id-cmc-confirmCertAcceptance" */
-+     330,    /* "id-cmc-dataReturn" */
-+     336,    /* "id-cmc-decryptedPOP" */
-+     335,    /* "id-cmc-encryptedPOP" */
-+     339,    /* "id-cmc-getCRL" */
-+     338,    /* "id-cmc-getCert" */
-+     328,    /* "id-cmc-identification" */
-+     329,    /* "id-cmc-identityProof" */
-+     337,    /* "id-cmc-lraPOPWitness" */
-+     344,    /* "id-cmc-popLinkRandom" */
-+     345,    /* "id-cmc-popLinkWitness" */
-+     343,    /* "id-cmc-queryPending" */
-+     333,    /* "id-cmc-recipientNonce" */
-+     341,    /* "id-cmc-regInfo" */
-+     342,    /* "id-cmc-responseInfo" */
-+     340,    /* "id-cmc-revokeRequest" */
-+     332,    /* "id-cmc-senderNonce" */
-+     327,    /* "id-cmc-statusInfo" */
-+     331,    /* "id-cmc-transactionId" */
-+     787,    /* "id-ct-asciiTextWithCRLF" */
-+    1060,    /* "id-ct-xml" */
-+     408,    /* "id-ecPublicKey" */
-+     508,    /* "id-hex-multipart-message" */
-+     507,    /* "id-hex-partial-message" */
-+     260,    /* "id-it" */
-+     302,    /* "id-it-caKeyUpdateInfo" */
-+     298,    /* "id-it-caProtEncCert" */
-+     311,    /* "id-it-confirmWaitTime" */
-+     303,    /* "id-it-currentCRL" */
-+     300,    /* "id-it-encKeyPairTypes" */
-+     310,    /* "id-it-implicitConfirm" */
-+     308,    /* "id-it-keyPairParamRep" */
-+     307,    /* "id-it-keyPairParamReq" */
-+     312,    /* "id-it-origPKIMessage" */
-+     301,    /* "id-it-preferredSymmAlg" */
-+     309,    /* "id-it-revPassphrase" */
-+     299,    /* "id-it-signKeyPairTypes" */
-+     305,    /* "id-it-subscriptionRequest" */
-+     306,    /* "id-it-subscriptionResponse" */
-+     784,    /* "id-it-suppLangTags" */
-+     304,    /* "id-it-unsupportedOIDs" */
-+     128,    /* "id-kp" */
-+     280,    /* "id-mod-attribute-cert" */
-+     274,    /* "id-mod-cmc" */
-+     277,    /* "id-mod-cmp" */
-+     284,    /* "id-mod-cmp2000" */
-+     273,    /* "id-mod-crmf" */
-+     283,    /* "id-mod-dvcs" */
-+     275,    /* "id-mod-kea-profile-88" */
-+     276,    /* "id-mod-kea-profile-93" */
-+     282,    /* "id-mod-ocsp" */
-+     278,    /* "id-mod-qualified-cert-88" */
-+     279,    /* "id-mod-qualified-cert-93" */
-+     281,    /* "id-mod-timestamp-protocol" */
-+     264,    /* "id-on" */
-+     347,    /* "id-on-personalData" */
-+     265,    /* "id-pda" */
-+     352,    /* "id-pda-countryOfCitizenship" */
-+     353,    /* "id-pda-countryOfResidence" */
-+     348,    /* "id-pda-dateOfBirth" */
-+     351,    /* "id-pda-gender" */
-+     349,    /* "id-pda-placeOfBirth" */
-+     175,    /* "id-pe" */
-+    1031,    /* "id-pkinit" */
-+     261,    /* "id-pkip" */
-+     258,    /* "id-pkix-mod" */
-+     269,    /* "id-pkix1-explicit-88" */
-+     271,    /* "id-pkix1-explicit-93" */
-+     270,    /* "id-pkix1-implicit-88" */
-+     272,    /* "id-pkix1-implicit-93" */
-+     662,    /* "id-ppl" */
-+     267,    /* "id-qcs" */
-+     359,    /* "id-qcs-pkixQCSyntax-v1" */
-+     259,    /* "id-qt" */
-+     313,    /* "id-regCtrl" */
-+     316,    /* "id-regCtrl-authenticator" */
-+     319,    /* "id-regCtrl-oldCertID" */
-+     318,    /* "id-regCtrl-pkiArchiveOptions" */
-+     317,    /* "id-regCtrl-pkiPublicationInfo" */
-+     320,    /* "id-regCtrl-protocolEncrKey" */
-+     315,    /* "id-regCtrl-regToken" */
-+     314,    /* "id-regInfo" */
-+     322,    /* "id-regInfo-certReq" */
-+     321,    /* "id-regInfo-utf8Pairs" */
-+     973,    /* "id-scrypt" */
-+     191,    /* "id-smime-aa" */
-+     215,    /* "id-smime-aa-contentHint" */
-+     218,    /* "id-smime-aa-contentIdentifier" */
-+     221,    /* "id-smime-aa-contentReference" */
-+     240,    /* "id-smime-aa-dvcs-dvc" */
-+     217,    /* "id-smime-aa-encapContentType" */
-+     222,    /* "id-smime-aa-encrypKeyPref" */
-+     220,    /* "id-smime-aa-equivalentLabels" */
-+     232,    /* "id-smime-aa-ets-CertificateRefs" */
-+     233,    /* "id-smime-aa-ets-RevocationRefs" */
-+     238,    /* "id-smime-aa-ets-archiveTimeStamp" */
-+     237,    /* "id-smime-aa-ets-certCRLTimestamp" */
-+     234,    /* "id-smime-aa-ets-certValues" */
-+     227,    /* "id-smime-aa-ets-commitmentType" */
-+     231,    /* "id-smime-aa-ets-contentTimestamp" */
-+     236,    /* "id-smime-aa-ets-escTimeStamp" */
-+     230,    /* "id-smime-aa-ets-otherSigCert" */
-+     235,    /* "id-smime-aa-ets-revocationValues" */
-+     226,    /* "id-smime-aa-ets-sigPolicyId" */
-+     229,    /* "id-smime-aa-ets-signerAttr" */
-+     228,    /* "id-smime-aa-ets-signerLocation" */
-+     219,    /* "id-smime-aa-macValue" */
-+     214,    /* "id-smime-aa-mlExpandHistory" */
-+     216,    /* "id-smime-aa-msgSigDigest" */
-+     212,    /* "id-smime-aa-receiptRequest" */
-+     213,    /* "id-smime-aa-securityLabel" */
-+     239,    /* "id-smime-aa-signatureType" */
-+     223,    /* "id-smime-aa-signingCertificate" */
-+     224,    /* "id-smime-aa-smimeEncryptCerts" */
-+     225,    /* "id-smime-aa-timeStampToken" */
-+     192,    /* "id-smime-alg" */
-+     243,    /* "id-smime-alg-3DESwrap" */
-+     246,    /* "id-smime-alg-CMS3DESwrap" */
-+     247,    /* "id-smime-alg-CMSRC2wrap" */
-+     245,    /* "id-smime-alg-ESDH" */
-+     241,    /* "id-smime-alg-ESDHwith3DES" */
-+     242,    /* "id-smime-alg-ESDHwithRC2" */
-+     244,    /* "id-smime-alg-RC2wrap" */
-+     193,    /* "id-smime-cd" */
-+     248,    /* "id-smime-cd-ldap" */
-+     190,    /* "id-smime-ct" */
-+     210,    /* "id-smime-ct-DVCSRequestData" */
-+     211,    /* "id-smime-ct-DVCSResponseData" */
-+     208,    /* "id-smime-ct-TDTInfo" */
-+     207,    /* "id-smime-ct-TSTInfo" */
-+     205,    /* "id-smime-ct-authData" */
-+    1059,    /* "id-smime-ct-authEnvelopedData" */
-+     786,    /* "id-smime-ct-compressedData" */
-+    1058,    /* "id-smime-ct-contentCollection" */
-+     209,    /* "id-smime-ct-contentInfo" */
-+     206,    /* "id-smime-ct-publishCert" */
-+     204,    /* "id-smime-ct-receipt" */
-+     195,    /* "id-smime-cti" */
-+     255,    /* "id-smime-cti-ets-proofOfApproval" */
-+     256,    /* "id-smime-cti-ets-proofOfCreation" */
-+     253,    /* "id-smime-cti-ets-proofOfDelivery" */
-+     251,    /* "id-smime-cti-ets-proofOfOrigin" */
-+     252,    /* "id-smime-cti-ets-proofOfReceipt" */
-+     254,    /* "id-smime-cti-ets-proofOfSender" */
-+     189,    /* "id-smime-mod" */
-+     196,    /* "id-smime-mod-cms" */
-+     197,    /* "id-smime-mod-ess" */
-+     202,    /* "id-smime-mod-ets-eSigPolicy-88" */
-+     203,    /* "id-smime-mod-ets-eSigPolicy-97" */
-+     200,    /* "id-smime-mod-ets-eSignature-88" */
-+     201,    /* "id-smime-mod-ets-eSignature-97" */
-+     199,    /* "id-smime-mod-msg-v3" */
-+     198,    /* "id-smime-mod-oid" */
-+     194,    /* "id-smime-spq" */
-+     250,    /* "id-smime-spq-ets-sqt-unotice" */
-+     249,    /* "id-smime-spq-ets-sqt-uri" */
-+     974,    /* "id-tc26" */
-+     991,    /* "id-tc26-agreement" */
-+     992,    /* "id-tc26-agreement-gost-3410-2012-256" */
-+     993,    /* "id-tc26-agreement-gost-3410-2012-512" */
-+     977,    /* "id-tc26-algorithms" */
-+     990,    /* "id-tc26-cipher" */
-+    1001,    /* "id-tc26-cipher-constants" */
-+     994,    /* "id-tc26-constants" */
-+     981,    /* "id-tc26-digest" */
-+    1000,    /* "id-tc26-digest-constants" */
-+    1002,    /* "id-tc26-gost-28147-constants" */
-+     996,    /* "id-tc26-gost-3410-2012-512-constants" */
-+     987,    /* "id-tc26-mac" */
-+     978,    /* "id-tc26-sign" */
-+     995,    /* "id-tc26-sign-constants" */
-+     984,    /* "id-tc26-signwithdigest" */
-+      34,    /* "idea-cbc" */
-+      35,    /* "idea-cfb" */
-+      36,    /* "idea-ecb" */
-+      46,    /* "idea-ofb" */
-+     676,    /* "identified-organization" */
-+     461,    /* "info" */
-+     101,    /* "initials" */
-+     869,    /* "internationaliSDNNumber" */
-+    1022,    /* "ipsec Internet Key Exchange" */
-+     749,    /* "ipsec3" */
-+     750,    /* "ipsec4" */
-+     181,    /* "iso" */
-+     623,    /* "issuer capabilities" */
-+     645,    /* "itu-t" */
-+     492,    /* "janetMailbox" */
-+     646,    /* "joint-iso-itu-t" */
-+     957,    /* "jurisdictionCountryName" */
-+     955,    /* "jurisdictionLocalityName" */
-+     956,    /* "jurisdictionStateOrProvinceName" */
-+     150,    /* "keyBag" */
-+     773,    /* "kisa" */
-+    1039,    /* "kx-dhe" */
-+    1041,    /* "kx-dhe-psk" */
-+    1038,    /* "kx-ecdhe" */
-+    1040,    /* "kx-ecdhe-psk" */
-+    1045,    /* "kx-gost" */
-+    1043,    /* "kx-psk" */
-+    1037,    /* "kx-rsa" */
-+    1042,    /* "kx-rsa-psk" */
-+    1044,    /* "kx-srp" */
-+     477,    /* "lastModifiedBy" */
-+     476,    /* "lastModifiedTime" */
-+     157,    /* "localKeyID" */
-+      15,    /* "localityName" */
-+     480,    /* "mXRecord" */
-+     493,    /* "mailPreferenceOption" */
-+     467,    /* "manager" */
-+       3,    /* "md2" */
-+       7,    /* "md2WithRSAEncryption" */
-+     257,    /* "md4" */
-+     396,    /* "md4WithRSAEncryption" */
-+       4,    /* "md5" */
-+     114,    /* "md5-sha1" */
-+     104,    /* "md5WithRSA" */
-+       8,    /* "md5WithRSAEncryption" */
-+      95,    /* "mdc2" */
-+      96,    /* "mdc2WithRSA" */
-+     875,    /* "member" */
-+     602,    /* "merchant initiated auth" */
-+     514,    /* "message extensions" */
-+      51,    /* "messageDigest" */
-+     911,    /* "mgf1" */
-+     506,    /* "mime-mhs-bodies" */
-+     505,    /* "mime-mhs-headings" */
-+     488,    /* "mobileTelephoneNumber" */
-+     481,    /* "nSRecord" */
-+     173,    /* "name" */
-+     681,    /* "onBasis" */
-+     379,    /* "org" */
-+      17,    /* "organizationName" */
-+     491,    /* "organizationalStatus" */
-+      18,    /* "organizationalUnitName" */
-+     475,    /* "otherMailbox" */
-+     876,    /* "owner" */
-+     935,    /* "pSpecified" */
-+     489,    /* "pagerTelephoneNumber" */
-+     782,    /* "password based MAC" */
-+     374,    /* "path" */
-+     621,    /* "payment gateway capabilities" */
-+       9,    /* "pbeWithMD2AndDES-CBC" */
-+     168,    /* "pbeWithMD2AndRC2-CBC" */
-+     112,    /* "pbeWithMD5AndCast5CBC" */
-+      10,    /* "pbeWithMD5AndDES-CBC" */
-+     169,    /* "pbeWithMD5AndRC2-CBC" */
-+     148,    /* "pbeWithSHA1And128BitRC2-CBC" */
-+     144,    /* "pbeWithSHA1And128BitRC4" */
-+     147,    /* "pbeWithSHA1And2-KeyTripleDES-CBC" */
-+     146,    /* "pbeWithSHA1And3-KeyTripleDES-CBC" */
-+     149,    /* "pbeWithSHA1And40BitRC2-CBC" */
-+     145,    /* "pbeWithSHA1And40BitRC4" */
-+     170,    /* "pbeWithSHA1AndDES-CBC" */
-+      68,    /* "pbeWithSHA1AndRC2-CBC" */
-+     499,    /* "personalSignature" */
-+     487,    /* "personalTitle" */
-+     464,    /* "photo" */
-+     863,    /* "physicalDeliveryOfficeName" */
-+     437,    /* "pilot" */
-+     439,    /* "pilotAttributeSyntax" */
-+     438,    /* "pilotAttributeType" */
-+     479,    /* "pilotAttributeType27" */
-+     456,    /* "pilotDSA" */
-+     441,    /* "pilotGroups" */
-+     444,    /* "pilotObject" */
-+     440,    /* "pilotObjectClass" */
-+     455,    /* "pilotOrganization" */
-+     445,    /* "pilotPerson" */
-+     186,    /* "pkcs1" */
-+      27,    /* "pkcs3" */
-+     187,    /* "pkcs5" */
-+      20,    /* "pkcs7" */
-+      21,    /* "pkcs7-data" */
-+      25,    /* "pkcs7-digestData" */
-+      26,    /* "pkcs7-encryptedData" */
-+      23,    /* "pkcs7-envelopedData" */
-+      24,    /* "pkcs7-signedAndEnvelopedData" */
-+      22,    /* "pkcs7-signedData" */
-+     151,    /* "pkcs8ShroudedKeyBag" */
-+      47,    /* "pkcs9" */
-+     862,    /* "postOfficeBox" */
-+     861,    /* "postalAddress" */
-+     661,    /* "postalCode" */
-+     683,    /* "ppBasis" */
-+     872,    /* "preferredDeliveryMethod" */
-+     873,    /* "presentationAddress" */
-+     406,    /* "prime-field" */
-+     409,    /* "prime192v1" */
-+     410,    /* "prime192v2" */
-+     411,    /* "prime192v3" */
-+     412,    /* "prime239v1" */
-+     413,    /* "prime239v2" */
-+     414,    /* "prime239v3" */
-+     415,    /* "prime256v1" */
-+     886,    /* "protocolInformation" */
-+     510,    /* "pseudonym" */
-+     435,    /* "pss" */
-+     286,    /* "qcStatements" */
-+     457,    /* "qualityLabelledData" */
-+     450,    /* "rFC822localPart" */
-+      98,    /* "rc2-40-cbc" */
-+     166,    /* "rc2-64-cbc" */
-+      37,    /* "rc2-cbc" */
-+      39,    /* "rc2-cfb" */
-+      38,    /* "rc2-ecb" */
-+      40,    /* "rc2-ofb" */
-+       5,    /* "rc4" */
-+      97,    /* "rc4-40" */
-+     915,    /* "rc4-hmac-md5" */
-+     120,    /* "rc5-cbc" */
-+     122,    /* "rc5-cfb" */
-+     121,    /* "rc5-ecb" */
-+     123,    /* "rc5-ofb" */
-+     870,    /* "registeredAddress" */
-+     460,    /* "rfc822Mailbox" */
-+     117,    /* "ripemd160" */
-+     119,    /* "ripemd160WithRSA" */
-+     400,    /* "role" */
-+     877,    /* "roleOccupant" */
-+     448,    /* "room" */
-+     463,    /* "roomNumber" */
-+      19,    /* "rsa" */
-+       6,    /* "rsaEncryption" */
-+     644,    /* "rsaOAEPEncryptionSET" */
-+     377,    /* "rsaSignature" */
-+     919,    /* "rsaesOaep" */
-+     912,    /* "rsassaPss" */
-+     482,    /* "sOARecord" */
-+     155,    /* "safeContentsBag" */
-+     291,    /* "sbgp-autonomousSysNum" */
-+     290,    /* "sbgp-ipAddrBlock" */
-+     292,    /* "sbgp-routerIdentifier" */
-+     159,    /* "sdsiCertificate" */
-+     859,    /* "searchGuide" */
-+     704,    /* "secp112r1" */
-+     705,    /* "secp112r2" */
-+     706,    /* "secp128r1" */
-+     707,    /* "secp128r2" */
-+     708,    /* "secp160k1" */
-+     709,    /* "secp160r1" */
-+     710,    /* "secp160r2" */
-+     711,    /* "secp192k1" */
-+     712,    /* "secp224k1" */
-+     713,    /* "secp224r1" */
-+     714,    /* "secp256k1" */
-+     715,    /* "secp384r1" */
-+     716,    /* "secp521r1" */
-+     154,    /* "secretBag" */
-+     474,    /* "secretary" */
-+     717,    /* "sect113r1" */
-+     718,    /* "sect113r2" */
-+     719,    /* "sect131r1" */
-+     720,    /* "sect131r2" */
-+     721,    /* "sect163k1" */
-+     722,    /* "sect163r1" */
-+     723,    /* "sect163r2" */
-+     724,    /* "sect193r1" */
-+     725,    /* "sect193r2" */
-+     726,    /* "sect233k1" */
-+     727,    /* "sect233r1" */
-+     728,    /* "sect239k1" */
-+     729,    /* "sect283k1" */
-+     730,    /* "sect283r1" */
-+     731,    /* "sect409k1" */
-+     732,    /* "sect409r1" */
-+     733,    /* "sect571k1" */
-+     734,    /* "sect571r1" */
-+     635,    /* "secure device signature" */
-+     878,    /* "seeAlso" */
-+     777,    /* "seed-cbc" */
-+     779,    /* "seed-cfb" */
-+     776,    /* "seed-ecb" */
-+     778,    /* "seed-ofb" */
-+     105,    /* "serialNumber" */
-+     625,    /* "set-addPolicy" */
-+     515,    /* "set-attr" */
-+     518,    /* "set-brand" */
-+     638,    /* "set-brand-AmericanExpress" */
-+     637,    /* "set-brand-Diners" */
-+     636,    /* "set-brand-IATA-ATA" */
-+     639,    /* "set-brand-JCB" */
-+     641,    /* "set-brand-MasterCard" */
-+     642,    /* "set-brand-Novus" */
-+     640,    /* "set-brand-Visa" */
-+     516,    /* "set-policy" */
-+     607,    /* "set-policy-root" */
-+     624,    /* "set-rootKeyThumb" */
-+     620,    /* "setAttr-Cert" */
-+     628,    /* "setAttr-IssCap-CVM" */
-+     630,    /* "setAttr-IssCap-Sig" */
-+     629,    /* "setAttr-IssCap-T2" */
-+     627,    /* "setAttr-Token-B0Prime" */
-+     626,    /* "setAttr-Token-EMV" */
-+     622,    /* "setAttr-TokenType" */
-+     619,    /* "setCext-IssuerCapabilities" */
-+     615,    /* "setCext-PGWYcapabilities" */
-+     616,    /* "setCext-TokenIdentifier" */
-+     618,    /* "setCext-TokenType" */
-+     617,    /* "setCext-Track2Data" */
-+     611,    /* "setCext-cCertRequired" */
-+     609,    /* "setCext-certType" */
-+     608,    /* "setCext-hashedRoot" */
-+     610,    /* "setCext-merchData" */
-+     613,    /* "setCext-setExt" */
-+     614,    /* "setCext-setQualf" */
-+     612,    /* "setCext-tunneling" */
-+     540,    /* "setct-AcqCardCodeMsg" */
-+     576,    /* "setct-AcqCardCodeMsgTBE" */
-+     570,    /* "setct-AuthReqTBE" */
-+     534,    /* "setct-AuthReqTBS" */
-+     527,    /* "setct-AuthResBaggage" */
-+     571,    /* "setct-AuthResTBE" */
-+     572,    /* "setct-AuthResTBEX" */
-+     535,    /* "setct-AuthResTBS" */
-+     536,    /* "setct-AuthResTBSX" */
-+     528,    /* "setct-AuthRevReqBaggage" */
-+     577,    /* "setct-AuthRevReqTBE" */
-+     541,    /* "setct-AuthRevReqTBS" */
-+     529,    /* "setct-AuthRevResBaggage" */
-+     542,    /* "setct-AuthRevResData" */
-+     578,    /* "setct-AuthRevResTBE" */
-+     579,    /* "setct-AuthRevResTBEB" */
-+     543,    /* "setct-AuthRevResTBS" */
-+     573,    /* "setct-AuthTokenTBE" */
-+     537,    /* "setct-AuthTokenTBS" */
-+     600,    /* "setct-BCIDistributionTBS" */
-+     558,    /* "setct-BatchAdminReqData" */
-+     592,    /* "setct-BatchAdminReqTBE" */
-+     559,    /* "setct-BatchAdminResData" */
-+     593,    /* "setct-BatchAdminResTBE" */
-+     599,    /* "setct-CRLNotificationResTBS" */
-+     598,    /* "setct-CRLNotificationTBS" */
-+     580,    /* "setct-CapReqTBE" */
-+     581,    /* "setct-CapReqTBEX" */
-+     544,    /* "setct-CapReqTBS" */
-+     545,    /* "setct-CapReqTBSX" */
-+     546,    /* "setct-CapResData" */
-+     582,    /* "setct-CapResTBE" */
-+     583,    /* "setct-CapRevReqTBE" */
-+     584,    /* "setct-CapRevReqTBEX" */
-+     547,    /* "setct-CapRevReqTBS" */
-+     548,    /* "setct-CapRevReqTBSX" */
-+     549,    /* "setct-CapRevResData" */
-+     585,    /* "setct-CapRevResTBE" */
-+     538,    /* "setct-CapTokenData" */
-+     530,    /* "setct-CapTokenSeq" */
-+     574,    /* "setct-CapTokenTBE" */
-+     575,    /* "setct-CapTokenTBEX" */
-+     539,    /* "setct-CapTokenTBS" */
-+     560,    /* "setct-CardCInitResTBS" */
-+     566,    /* "setct-CertInqReqTBS" */
-+     563,    /* "setct-CertReqData" */
-+     595,    /* "setct-CertReqTBE" */
-+     596,    /* "setct-CertReqTBEX" */
-+     564,    /* "setct-CertReqTBS" */
-+     565,    /* "setct-CertResData" */
-+     597,    /* "setct-CertResTBE" */
-+     586,    /* "setct-CredReqTBE" */
-+     587,    /* "setct-CredReqTBEX" */
-+     550,    /* "setct-CredReqTBS" */
-+     551,    /* "setct-CredReqTBSX" */
-+     552,    /* "setct-CredResData" */
-+     588,    /* "setct-CredResTBE" */
-+     589,    /* "setct-CredRevReqTBE" */
-+     590,    /* "setct-CredRevReqTBEX" */
-+     553,    /* "setct-CredRevReqTBS" */
-+     554,    /* "setct-CredRevReqTBSX" */
-+     555,    /* "setct-CredRevResData" */
-+     591,    /* "setct-CredRevResTBE" */
-+     567,    /* "setct-ErrorTBS" */
-+     526,    /* "setct-HODInput" */
-+     561,    /* "setct-MeAqCInitResTBS" */
-+     522,    /* "setct-OIData" */
-+     519,    /* "setct-PANData" */
-+     521,    /* "setct-PANOnly" */
-+     520,    /* "setct-PANToken" */
-+     556,    /* "setct-PCertReqData" */
-+     557,    /* "setct-PCertResTBS" */
-+     523,    /* "setct-PI" */
-+     532,    /* "setct-PI-TBS" */
-+     524,    /* "setct-PIData" */
-+     525,    /* "setct-PIDataUnsigned" */
-+     568,    /* "setct-PIDualSignedTBE" */
-+     569,    /* "setct-PIUnsignedTBE" */
-+     531,    /* "setct-PInitResData" */
-+     533,    /* "setct-PResData" */
-+     594,    /* "setct-RegFormReqTBE" */
-+     562,    /* "setct-RegFormResTBS" */
-+     604,    /* "setext-pinAny" */
-+     603,    /* "setext-pinSecure" */
-+     605,    /* "setext-track2" */
-+      41,    /* "sha" */
-+      64,    /* "sha1" */
-+     115,    /* "sha1WithRSA" */
-+      65,    /* "sha1WithRSAEncryption" */
-+     675,    /* "sha224" */
-+     671,    /* "sha224WithRSAEncryption" */
-+     672,    /* "sha256" */
-+     668,    /* "sha256WithRSAEncryption" */
-+     673,    /* "sha384" */
-+     669,    /* "sha384WithRSAEncryption" */
-+     674,    /* "sha512" */
-+     670,    /* "sha512WithRSAEncryption" */
-+      42,    /* "shaWithRSAEncryption" */
-+      52,    /* "signingTime" */
-+     454,    /* "simpleSecurityObject" */
-+     496,    /* "singleLevelQuality" */
-+      16,    /* "stateOrProvinceName" */
-+     660,    /* "streetAddress" */
-+     498,    /* "subtreeMaximumQuality" */
-+     497,    /* "subtreeMinimumQuality" */
-+     890,    /* "supportedAlgorithms" */
-+     874,    /* "supportedApplicationContext" */
-+     100,    /* "surname" */
-+     864,    /* "telephoneNumber" */
-+     866,    /* "teletexTerminalIdentifier" */
-+     865,    /* "telexNumber" */
-+     459,    /* "textEncodedORAddress" */
-+     293,    /* "textNotice" */
-+     106,    /* "title" */
-+    1021,    /* "tls1-prf" */
-+     682,    /* "tpBasis" */
-+     436,    /* "ucl" */
-+       0,    /* "undefined" */
-+     102,    /* "uniqueIdentifier" */
-+     888,    /* "uniqueMember" */
-+      55,    /* "unstructuredAddress" */
-+      49,    /* "unstructuredName" */
-+     880,    /* "userCertificate" */
-+     465,    /* "userClass" */
-+     458,    /* "userId" */
-+     879,    /* "userPassword" */
-+     373,    /* "valid" */
-+     678,    /* "wap" */
-+     679,    /* "wap-wsg" */
-+     735,    /* "wap-wsg-idm-ecid-wtls1" */
-+     743,    /* "wap-wsg-idm-ecid-wtls10" */
-+     744,    /* "wap-wsg-idm-ecid-wtls11" */
-+     745,    /* "wap-wsg-idm-ecid-wtls12" */
-+     736,    /* "wap-wsg-idm-ecid-wtls3" */
-+     737,    /* "wap-wsg-idm-ecid-wtls4" */
-+     738,    /* "wap-wsg-idm-ecid-wtls5" */
-+     739,    /* "wap-wsg-idm-ecid-wtls6" */
-+     740,    /* "wap-wsg-idm-ecid-wtls7" */
-+     741,    /* "wap-wsg-idm-ecid-wtls8" */
-+     742,    /* "wap-wsg-idm-ecid-wtls9" */
-+     804,    /* "whirlpool" */
-+     868,    /* "x121Address" */
-+     503,    /* "x500UniqueIdentifier" */
-+     158,    /* "x509Certificate" */
-+     160,    /* "x509Crl" */
-+     125,    /* "zlib compression" */
-+};
-+
-+#define NUM_OBJ 956
-+static const unsigned int obj_objs[NUM_OBJ] = {
-+       0,    /* OBJ_undef                        0 */
-+     181,    /* OBJ_iso                          1 */
-+     393,    /* OBJ_joint_iso_ccitt              OBJ_joint_iso_itu_t */
-+     404,    /* OBJ_ccitt                        OBJ_itu_t */
-+     645,    /* OBJ_itu_t                        0 */
-+     646,    /* OBJ_joint_iso_itu_t              2 */
-+     434,    /* OBJ_data                         0 9 */
-+     182,    /* OBJ_member_body                  1 2 */
-+     379,    /* OBJ_org                          1 3 */
-+     676,    /* OBJ_identified_organization      1 3 */
-+      11,    /* OBJ_X500                         2 5 */
-+     647,    /* OBJ_international_organizations  2 23 */
-+     380,    /* OBJ_dod                          1 3 6 */
-+      12,    /* OBJ_X509                         2 5 4 */
-+     378,    /* OBJ_X500algorithms               2 5 8 */
-+      81,    /* OBJ_id_ce                        2 5 29 */
-+     512,    /* OBJ_id_set                       2 23 42 */
-+     678,    /* OBJ_wap                          2 23 43 */
-+     435,    /* OBJ_pss                          0 9 2342 */
-+     183,    /* OBJ_ISO_US                       1 2 840 */
-+     381,    /* OBJ_iana                         1 3 6 1 */
-+    1034,    /* OBJ_X25519                       1 3 101 110 */
-+    1035,    /* OBJ_X448                         1 3 101 111 */
-+     677,    /* OBJ_certicom_arc                 1 3 132 */
-+     394,    /* OBJ_selected_attribute_types     2 5 1 5 */
-+      13,    /* OBJ_commonName                   2 5 4 3 */
-+     100,    /* OBJ_surname                      2 5 4 4 */
-+     105,    /* OBJ_serialNumber                 2 5 4 5 */
-+      14,    /* OBJ_countryName                  2 5 4 6 */
-+      15,    /* OBJ_localityName                 2 5 4 7 */
-+      16,    /* OBJ_stateOrProvinceName          2 5 4 8 */
-+     660,    /* OBJ_streetAddress                2 5 4 9 */
-+      17,    /* OBJ_organizationName             2 5 4 10 */
-+      18,    /* OBJ_organizationalUnitName       2 5 4 11 */
-+     106,    /* OBJ_title                        2 5 4 12 */
-+     107,    /* OBJ_description                  2 5 4 13 */
-+     859,    /* OBJ_searchGuide                  2 5 4 14 */
-+     860,    /* OBJ_businessCategory             2 5 4 15 */
-+     861,    /* OBJ_postalAddress                2 5 4 16 */
-+     661,    /* OBJ_postalCode                   2 5 4 17 */
-+     862,    /* OBJ_postOfficeBox                2 5 4 18 */
-+     863,    /* OBJ_physicalDeliveryOfficeName   2 5 4 19 */
-+     864,    /* OBJ_telephoneNumber              2 5 4 20 */
-+     865,    /* OBJ_telexNumber                  2 5 4 21 */
-+     866,    /* OBJ_teletexTerminalIdentifier    2 5 4 22 */
-+     867,    /* OBJ_facsimileTelephoneNumber     2 5 4 23 */
-+     868,    /* OBJ_x121Address                  2 5 4 24 */
-+     869,    /* OBJ_internationaliSDNNumber      2 5 4 25 */
-+     870,    /* OBJ_registeredAddress            2 5 4 26 */
-+     871,    /* OBJ_destinationIndicator         2 5 4 27 */
-+     872,    /* OBJ_preferredDeliveryMethod      2 5 4 28 */
-+     873,    /* OBJ_presentationAddress          2 5 4 29 */
-+     874,    /* OBJ_supportedApplicationContext  2 5 4 30 */
-+     875,    /* OBJ_member                       2 5 4 31 */
-+     876,    /* OBJ_owner                        2 5 4 32 */
-+     877,    /* OBJ_roleOccupant                 2 5 4 33 */
-+     878,    /* OBJ_seeAlso                      2 5 4 34 */
-+     879,    /* OBJ_userPassword                 2 5 4 35 */
-+     880,    /* OBJ_userCertificate              2 5 4 36 */
-+     881,    /* OBJ_cACertificate                2 5 4 37 */
-+     882,    /* OBJ_authorityRevocationList      2 5 4 38 */
-+     883,    /* OBJ_certificateRevocationList    2 5 4 39 */
-+     884,    /* OBJ_crossCertificatePair         2 5 4 40 */
-+     173,    /* OBJ_name                         2 5 4 41 */
-+      99,    /* OBJ_givenName                    2 5 4 42 */
-+     101,    /* OBJ_initials                     2 5 4 43 */
-+     509,    /* OBJ_generationQualifier          2 5 4 44 */
-+     503,    /* OBJ_x500UniqueIdentifier         2 5 4 45 */
-+     174,    /* OBJ_dnQualifier                  2 5 4 46 */
-+     885,    /* OBJ_enhancedSearchGuide          2 5 4 47 */
-+     886,    /* OBJ_protocolInformation          2 5 4 48 */
-+     887,    /* OBJ_distinguishedName            2 5 4 49 */
-+     888,    /* OBJ_uniqueMember                 2 5 4 50 */
-+     889,    /* OBJ_houseIdentifier              2 5 4 51 */
-+     890,    /* OBJ_supportedAlgorithms          2 5 4 52 */
-+     891,    /* OBJ_deltaRevocationList          2 5 4 53 */
-+     892,    /* OBJ_dmdName                      2 5 4 54 */
-+     510,    /* OBJ_pseudonym                    2 5 4 65 */
-+     400,    /* OBJ_role                         2 5 4 72 */
-+     769,    /* OBJ_subject_directory_attributes 2 5 29 9 */
-+      82,    /* OBJ_subject_key_identifier       2 5 29 14 */
-+      83,    /* OBJ_key_usage                    2 5 29 15 */
-+      84,    /* OBJ_private_key_usage_period     2 5 29 16 */
-+      85,    /* OBJ_subject_alt_name             2 5 29 17 */
-+      86,    /* OBJ_issuer_alt_name              2 5 29 18 */
-+      87,    /* OBJ_basic_constraints            2 5 29 19 */
-+      88,    /* OBJ_crl_number                   2 5 29 20 */
-+     141,    /* OBJ_crl_reason                   2 5 29 21 */
-+     430,    /* OBJ_hold_instruction_code        2 5 29 23 */
-+     142,    /* OBJ_invalidity_date              2 5 29 24 */
-+     140,    /* OBJ_delta_crl                    2 5 29 27 */
-+     770,    /* OBJ_issuing_distribution_point   2 5 29 28 */
-+     771,    /* OBJ_certificate_issuer           2 5 29 29 */
-+     666,    /* OBJ_name_constraints             2 5 29 30 */
-+     103,    /* OBJ_crl_distribution_points      2 5 29 31 */
-+      89,    /* OBJ_certificate_policies         2 5 29 32 */
-+     747,    /* OBJ_policy_mappings              2 5 29 33 */
-+      90,    /* OBJ_authority_key_identifier     2 5 29 35 */
-+     401,    /* OBJ_policy_constraints           2 5 29 36 */
-+     126,    /* OBJ_ext_key_usage                2 5 29 37 */
-+     857,    /* OBJ_freshest_crl                 2 5 29 46 */
-+     748,    /* OBJ_inhibit_any_policy           2 5 29 54 */
-+     402,    /* OBJ_target_information           2 5 29 55 */
-+     403,    /* OBJ_no_rev_avail                 2 5 29 56 */
-+     513,    /* OBJ_set_ctype                    2 23 42 0 */
-+     514,    /* OBJ_set_msgExt                   2 23 42 1 */
-+     515,    /* OBJ_set_attr                     2 23 42 3 */
-+     516,    /* OBJ_set_policy                   2 23 42 5 */
-+     517,    /* OBJ_set_certExt                  2 23 42 7 */
-+     518,    /* OBJ_set_brand                    2 23 42 8 */
-+     679,    /* OBJ_wap_wsg                      2 23 43 1 */
-+     382,    /* OBJ_Directory                    1 3 6 1 1 */
-+     383,    /* OBJ_Management                   1 3 6 1 2 */
-+     384,    /* OBJ_Experimental                 1 3 6 1 3 */
-+     385,    /* OBJ_Private                      1 3 6 1 4 */
-+     386,    /* OBJ_Security                     1 3 6 1 5 */
-+     387,    /* OBJ_SNMPv2                       1 3 6 1 6 */
-+     388,    /* OBJ_Mail                         1 3 6 1 7 */
-+     376,    /* OBJ_algorithm                    1 3 14 3 2 */
-+     395,    /* OBJ_clearance                    2 5 1 5 55 */
-+      19,    /* OBJ_rsa                          2 5 8 1 1 */
-+      96,    /* OBJ_mdc2WithRSA                  2 5 8 3 100 */
-+      95,    /* OBJ_mdc2                         2 5 8 3 101 */
-+     746,    /* OBJ_any_policy                   2 5 29 32 0 */
-+     910,    /* OBJ_anyExtendedKeyUsage          2 5 29 37 0 */
-+     519,    /* OBJ_setct_PANData                2 23 42 0 0 */
-+     520,    /* OBJ_setct_PANToken               2 23 42 0 1 */
-+     521,    /* OBJ_setct_PANOnly                2 23 42 0 2 */
-+     522,    /* OBJ_setct_OIData                 2 23 42 0 3 */
-+     523,    /* OBJ_setct_PI                     2 23 42 0 4 */
-+     524,    /* OBJ_setct_PIData                 2 23 42 0 5 */
-+     525,    /* OBJ_setct_PIDataUnsigned         2 23 42 0 6 */
-+     526,    /* OBJ_setct_HODInput               2 23 42 0 7 */
-+     527,    /* OBJ_setct_AuthResBaggage         2 23 42 0 8 */
-+     528,    /* OBJ_setct_AuthRevReqBaggage      2 23 42 0 9 */
-+     529,    /* OBJ_setct_AuthRevResBaggage      2 23 42 0 10 */
-+     530,    /* OBJ_setct_CapTokenSeq            2 23 42 0 11 */
-+     531,    /* OBJ_setct_PInitResData           2 23 42 0 12 */
-+     532,    /* OBJ_setct_PI_TBS                 2 23 42 0 13 */
-+     533,    /* OBJ_setct_PResData               2 23 42 0 14 */
-+     534,    /* OBJ_setct_AuthReqTBS             2 23 42 0 16 */
-+     535,    /* OBJ_setct_AuthResTBS             2 23 42 0 17 */
-+     536,    /* OBJ_setct_AuthResTBSX            2 23 42 0 18 */
-+     537,    /* OBJ_setct_AuthTokenTBS           2 23 42 0 19 */
-+     538,    /* OBJ_setct_CapTokenData           2 23 42 0 20 */
-+     539,    /* OBJ_setct_CapTokenTBS            2 23 42 0 21 */
-+     540,    /* OBJ_setct_AcqCardCodeMsg         2 23 42 0 22 */
-+     541,    /* OBJ_setct_AuthRevReqTBS          2 23 42 0 23 */
-+     542,    /* OBJ_setct_AuthRevResData         2 23 42 0 24 */
-+     543,    /* OBJ_setct_AuthRevResTBS          2 23 42 0 25 */
-+     544,    /* OBJ_setct_CapReqTBS              2 23 42 0 26 */
-+     545,    /* OBJ_setct_CapReqTBSX             2 23 42 0 27 */
-+     546,    /* OBJ_setct_CapResData             2 23 42 0 28 */
-+     547,    /* OBJ_setct_CapRevReqTBS           2 23 42 0 29 */
-+     548,    /* OBJ_setct_CapRevReqTBSX          2 23 42 0 30 */
-+     549,    /* OBJ_setct_CapRevResData          2 23 42 0 31 */
-+     550,    /* OBJ_setct_CredReqTBS             2 23 42 0 32 */
-+     551,    /* OBJ_setct_CredReqTBSX            2 23 42 0 33 */
-+     552,    /* OBJ_setct_CredResData            2 23 42 0 34 */
-+     553,    /* OBJ_setct_CredRevReqTBS          2 23 42 0 35 */
-+     554,    /* OBJ_setct_CredRevReqTBSX         2 23 42 0 36 */
-+     555,    /* OBJ_setct_CredRevResData         2 23 42 0 37 */
-+     556,    /* OBJ_setct_PCertReqData           2 23 42 0 38 */
-+     557,    /* OBJ_setct_PCertResTBS            2 23 42 0 39 */
-+     558,    /* OBJ_setct_BatchAdminReqData      2 23 42 0 40 */
-+     559,    /* OBJ_setct_BatchAdminResData      2 23 42 0 41 */
-+     560,    /* OBJ_setct_CardCInitResTBS        2 23 42 0 42 */
-+     561,    /* OBJ_setct_MeAqCInitResTBS        2 23 42 0 43 */
-+     562,    /* OBJ_setct_RegFormResTBS          2 23 42 0 44 */
-+     563,    /* OBJ_setct_CertReqData            2 23 42 0 45 */
-+     564,    /* OBJ_setct_CertReqTBS             2 23 42 0 46 */
-+     565,    /* OBJ_setct_CertResData            2 23 42 0 47 */
-+     566,    /* OBJ_setct_CertInqReqTBS          2 23 42 0 48 */
-+     567,    /* OBJ_setct_ErrorTBS               2 23 42 0 49 */
-+     568,    /* OBJ_setct_PIDualSignedTBE        2 23 42 0 50 */
-+     569,    /* OBJ_setct_PIUnsignedTBE          2 23 42 0 51 */
-+     570,    /* OBJ_setct_AuthReqTBE             2 23 42 0 52 */
-+     571,    /* OBJ_setct_AuthResTBE             2 23 42 0 53 */
-+     572,    /* OBJ_setct_AuthResTBEX            2 23 42 0 54 */
-+     573,    /* OBJ_setct_AuthTokenTBE           2 23 42 0 55 */
-+     574,    /* OBJ_setct_CapTokenTBE            2 23 42 0 56 */
-+     575,    /* OBJ_setct_CapTokenTBEX           2 23 42 0 57 */
-+     576,    /* OBJ_setct_AcqCardCodeMsgTBE      2 23 42 0 58 */
-+     577,    /* OBJ_setct_AuthRevReqTBE          2 23 42 0 59 */
-+     578,    /* OBJ_setct_AuthRevResTBE          2 23 42 0 60 */
-+     579,    /* OBJ_setct_AuthRevResTBEB         2 23 42 0 61 */
-+     580,    /* OBJ_setct_CapReqTBE              2 23 42 0 62 */
-+     581,    /* OBJ_setct_CapReqTBEX             2 23 42 0 63 */
-+     582,    /* OBJ_setct_CapResTBE              2 23 42 0 64 */
-+     583,    /* OBJ_setct_CapRevReqTBE           2 23 42 0 65 */
-+     584,    /* OBJ_setct_CapRevReqTBEX          2 23 42 0 66 */
-+     585,    /* OBJ_setct_CapRevResTBE           2 23 42 0 67 */
-+     586,    /* OBJ_setct_CredReqTBE             2 23 42 0 68 */
-+     587,    /* OBJ_setct_CredReqTBEX            2 23 42 0 69 */
-+     588,    /* OBJ_setct_CredResTBE             2 23 42 0 70 */
-+     589,    /* OBJ_setct_CredRevReqTBE          2 23 42 0 71 */
-+     590,    /* OBJ_setct_CredRevReqTBEX         2 23 42 0 72 */
-+     591,    /* OBJ_setct_CredRevResTBE          2 23 42 0 73 */
-+     592,    /* OBJ_setct_BatchAdminReqTBE       2 23 42 0 74 */
-+     593,    /* OBJ_setct_BatchAdminResTBE       2 23 42 0 75 */
-+     594,    /* OBJ_setct_RegFormReqTBE          2 23 42 0 76 */
-+     595,    /* OBJ_setct_CertReqTBE             2 23 42 0 77 */
-+     596,    /* OBJ_setct_CertReqTBEX            2 23 42 0 78 */
-+     597,    /* OBJ_setct_CertResTBE             2 23 42 0 79 */
-+     598,    /* OBJ_setct_CRLNotificationTBS     2 23 42 0 80 */
-+     599,    /* OBJ_setct_CRLNotificationResTBS  2 23 42 0 81 */
-+     600,    /* OBJ_setct_BCIDistributionTBS     2 23 42 0 82 */
-+     601,    /* OBJ_setext_genCrypt              2 23 42 1 1 */
-+     602,    /* OBJ_setext_miAuth                2 23 42 1 3 */
-+     603,    /* OBJ_setext_pinSecure             2 23 42 1 4 */
-+     604,    /* OBJ_setext_pinAny                2 23 42 1 5 */
-+     605,    /* OBJ_setext_track2                2 23 42 1 7 */
-+     606,    /* OBJ_setext_cv                    2 23 42 1 8 */
-+     620,    /* OBJ_setAttr_Cert                 2 23 42 3 0 */
-+     621,    /* OBJ_setAttr_PGWYcap              2 23 42 3 1 */
-+     622,    /* OBJ_setAttr_TokenType            2 23 42 3 2 */
-+     623,    /* OBJ_setAttr_IssCap               2 23 42 3 3 */
-+     607,    /* OBJ_set_policy_root              2 23 42 5 0 */
-+     608,    /* OBJ_setCext_hashedRoot           2 23 42 7 0 */
-+     609,    /* OBJ_setCext_certType             2 23 42 7 1 */
-+     610,    /* OBJ_setCext_merchData            2 23 42 7 2 */
-+     611,    /* OBJ_setCext_cCertRequired        2 23 42 7 3 */
-+     612,    /* OBJ_setCext_tunneling            2 23 42 7 4 */
-+     613,    /* OBJ_setCext_setExt               2 23 42 7 5 */
-+     614,    /* OBJ_setCext_setQualf             2 23 42 7 6 */
-+     615,    /* OBJ_setCext_PGWYcapabilities     2 23 42 7 7 */
-+     616,    /* OBJ_setCext_TokenIdentifier      2 23 42 7 8 */
-+     617,    /* OBJ_setCext_Track2Data           2 23 42 7 9 */
-+     618,    /* OBJ_setCext_TokenType            2 23 42 7 10 */
-+     619,    /* OBJ_setCext_IssuerCapabilities   2 23 42 7 11 */
-+     636,    /* OBJ_set_brand_IATA_ATA           2 23 42 8 1 */
-+     640,    /* OBJ_set_brand_Visa               2 23 42 8 4 */
-+     641,    /* OBJ_set_brand_MasterCard         2 23 42 8 5 */
-+     637,    /* OBJ_set_brand_Diners             2 23 42 8 30 */
-+     638,    /* OBJ_set_brand_AmericanExpress    2 23 42 8 34 */
-+     639,    /* OBJ_set_brand_JCB                2 23 42 8 35 */
-+     805,    /* OBJ_cryptopro                    1 2 643 2 2 */
-+     806,    /* OBJ_cryptocom                    1 2 643 2 9 */
-+     974,    /* OBJ_id_tc26                      1 2 643 7 1 */
-+    1005,    /* OBJ_OGRN                         1 2 643 100 1 */
-+    1006,    /* OBJ_SNILS                        1 2 643 100 3 */
-+    1007,    /* OBJ_subjectSignTool              1 2 643 100 111 */
-+    1008,    /* OBJ_issuerSignTool               1 2 643 100 112 */
-+     184,    /* OBJ_X9_57                        1 2 840 10040 */
-+     405,    /* OBJ_ansi_X9_62                   1 2 840 10045 */
-+     389,    /* OBJ_Enterprises                  1 3 6 1 4 1 */
-+     504,    /* OBJ_mime_mhs                     1 3 6 1 7 1 */
-+     104,    /* OBJ_md5WithRSA                   1 3 14 3 2 3 */
-+      29,    /* OBJ_des_ecb                      1 3 14 3 2 6 */
-+      31,    /* OBJ_des_cbc                      1 3 14 3 2 7 */
-+      45,    /* OBJ_des_ofb64                    1 3 14 3 2 8 */
-+      30,    /* OBJ_des_cfb64                    1 3 14 3 2 9 */
-+     377,    /* OBJ_rsaSignature                 1 3 14 3 2 11 */
-+      67,    /* OBJ_dsa_2                        1 3 14 3 2 12 */
-+      66,    /* OBJ_dsaWithSHA                   1 3 14 3 2 13 */
-+      42,    /* OBJ_shaWithRSAEncryption         1 3 14 3 2 15 */
-+      32,    /* OBJ_des_ede_ecb                  1 3 14 3 2 17 */
-+      41,    /* OBJ_sha                          1 3 14 3 2 18 */
-+      64,    /* OBJ_sha1                         1 3 14 3 2 26 */
-+      70,    /* OBJ_dsaWithSHA1_2                1 3 14 3 2 27 */
-+     115,    /* OBJ_sha1WithRSA                  1 3 14 3 2 29 */
-+     117,    /* OBJ_ripemd160                    1 3 36 3 2 1 */
-+     143,    /* OBJ_sxnet                        1 3 101 1 4 1 */
-+     721,    /* OBJ_sect163k1                    1 3 132 0 1 */
-+     722,    /* OBJ_sect163r1                    1 3 132 0 2 */
-+     728,    /* OBJ_sect239k1                    1 3 132 0 3 */
-+     717,    /* OBJ_sect113r1                    1 3 132 0 4 */
-+     718,    /* OBJ_sect113r2                    1 3 132 0 5 */
-+     704,    /* OBJ_secp112r1                    1 3 132 0 6 */
-+     705,    /* OBJ_secp112r2                    1 3 132 0 7 */
-+     709,    /* OBJ_secp160r1                    1 3 132 0 8 */
-+     708,    /* OBJ_secp160k1                    1 3 132 0 9 */
-+     714,    /* OBJ_secp256k1                    1 3 132 0 10 */
-+     723,    /* OBJ_sect163r2                    1 3 132 0 15 */
-+     729,    /* OBJ_sect283k1                    1 3 132 0 16 */
-+     730,    /* OBJ_sect283r1                    1 3 132 0 17 */
-+     719,    /* OBJ_sect131r1                    1 3 132 0 22 */
-+     720,    /* OBJ_sect131r2                    1 3 132 0 23 */
-+     724,    /* OBJ_sect193r1                    1 3 132 0 24 */
-+     725,    /* OBJ_sect193r2                    1 3 132 0 25 */
-+     726,    /* OBJ_sect233k1                    1 3 132 0 26 */
-+     727,    /* OBJ_sect233r1                    1 3 132 0 27 */
-+     706,    /* OBJ_secp128r1                    1 3 132 0 28 */
-+     707,    /* OBJ_secp128r2                    1 3 132 0 29 */
-+     710,    /* OBJ_secp160r2                    1 3 132 0 30 */
-+     711,    /* OBJ_secp192k1                    1 3 132 0 31 */
-+     712,    /* OBJ_secp224k1                    1 3 132 0 32 */
-+     713,    /* OBJ_secp224r1                    1 3 132 0 33 */
-+     715,    /* OBJ_secp384r1                    1 3 132 0 34 */
-+     716,    /* OBJ_secp521r1                    1 3 132 0 35 */
-+     731,    /* OBJ_sect409k1                    1 3 132 0 36 */
-+     732,    /* OBJ_sect409r1                    1 3 132 0 37 */
-+     733,    /* OBJ_sect571k1                    1 3 132 0 38 */
-+     734,    /* OBJ_sect571r1                    1 3 132 0 39 */
-+     624,    /* OBJ_set_rootKeyThumb             2 23 42 3 0 0 */
-+     625,    /* OBJ_set_addPolicy                2 23 42 3 0 1 */
-+     626,    /* OBJ_setAttr_Token_EMV            2 23 42 3 2 1 */
-+     627,    /* OBJ_setAttr_Token_B0Prime        2 23 42 3 2 2 */
-+     628,    /* OBJ_setAttr_IssCap_CVM           2 23 42 3 3 3 */
-+     629,    /* OBJ_setAttr_IssCap_T2            2 23 42 3 3 4 */
-+     630,    /* OBJ_setAttr_IssCap_Sig           2 23 42 3 3 5 */
-+     642,    /* OBJ_set_brand_Novus              2 23 42 8 6011 */
-+     735,    /* OBJ_wap_wsg_idm_ecid_wtls1       2 23 43 1 4 1 */
-+     736,    /* OBJ_wap_wsg_idm_ecid_wtls3       2 23 43 1 4 3 */
-+     737,    /* OBJ_wap_wsg_idm_ecid_wtls4       2 23 43 1 4 4 */
-+     738,    /* OBJ_wap_wsg_idm_ecid_wtls5       2 23 43 1 4 5 */
-+     739,    /* OBJ_wap_wsg_idm_ecid_wtls6       2 23 43 1 4 6 */
-+     740,    /* OBJ_wap_wsg_idm_ecid_wtls7       2 23 43 1 4 7 */
-+     741,    /* OBJ_wap_wsg_idm_ecid_wtls8       2 23 43 1 4 8 */
-+     742,    /* OBJ_wap_wsg_idm_ecid_wtls9       2 23 43 1 4 9 */
-+     743,    /* OBJ_wap_wsg_idm_ecid_wtls10      2 23 43 1 4 10 */
-+     744,    /* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 1 4 11 */
-+     745,    /* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 1 4 12 */
-+     804,    /* OBJ_whirlpool                    1 0 10118 3 0 55 */
-+     773,    /* OBJ_kisa                         1 2 410 200004 */
-+     807,    /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */
-+     808,    /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */
-+     809,    /* OBJ_id_GostR3411_94              1 2 643 2 2 9 */
-+     810,    /* OBJ_id_HMACGostR3411_94          1 2 643 2 2 10 */
-+     811,    /* OBJ_id_GostR3410_2001            1 2 643 2 2 19 */
-+     812,    /* OBJ_id_GostR3410_94              1 2 643 2 2 20 */
-+     813,    /* OBJ_id_Gost28147_89              1 2 643 2 2 21 */
-+     815,    /* OBJ_id_Gost28147_89_MAC          1 2 643 2 2 22 */
-+     816,    /* OBJ_id_GostR3411_94_prf          1 2 643 2 2 23 */
-+     817,    /* OBJ_id_GostR3410_2001DH          1 2 643 2 2 98 */
-+     818,    /* OBJ_id_GostR3410_94DH            1 2 643 2 2 99 */
-+     977,    /* OBJ_id_tc26_algorithms           1 2 643 7 1 1 */
-+     994,    /* OBJ_id_tc26_constants            1 2 643 7 1 2 */
-+       1,    /* OBJ_rsadsi                       1 2 840 113549 */
-+     185,    /* OBJ_X9cm                         1 2 840 10040 4 */
-+    1031,    /* OBJ_id_pkinit                    1 3 6 1 5 2 3 */
-+     127,    /* OBJ_id_pkix                      1 3 6 1 5 5 7 */
-+     505,    /* OBJ_mime_mhs_headings            1 3 6 1 7 1 1 */
-+     506,    /* OBJ_mime_mhs_bodies              1 3 6 1 7 1 2 */
-+     119,    /* OBJ_ripemd160WithRSA             1 3 36 3 3 1 2 */
-+     937,    /* OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1 3 132 1 11 0 */
-+     938,    /* OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1 3 132 1 11 1 */
-+     939,    /* OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1 3 132 1 11 2 */
-+     940,    /* OBJ_dhSinglePass_stdDH_sha512kdf_scheme 1 3 132 1 11 3 */
-+     942,    /* OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1 3 132 1 14 0 */
-+     943,    /* OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme 1 3 132 1 14 1 */
-+     944,    /* OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme 1 3 132 1 14 2 */
-+     945,    /* OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme 1 3 132 1 14 3 */
-+     631,    /* OBJ_setAttr_GenCryptgrm          2 23 42 3 3 3 1 */
-+     632,    /* OBJ_setAttr_T2Enc                2 23 42 3 3 4 1 */
-+     633,    /* OBJ_setAttr_T2cleartxt           2 23 42 3 3 4 2 */
-+     634,    /* OBJ_setAttr_TokICCsig            2 23 42 3 3 5 1 */
-+     635,    /* OBJ_setAttr_SecDevSig            2 23 42 3 3 5 2 */
-+     436,    /* OBJ_ucl                          0 9 2342 19200300 */
-+     820,    /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */
-+     819,    /* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */
-+     845,    /* OBJ_id_GostR3410_94_a            1 2 643 2 2 20 1 */
-+     846,    /* OBJ_id_GostR3410_94_aBis         1 2 643 2 2 20 2 */
-+     847,    /* OBJ_id_GostR3410_94_b            1 2 643 2 2 20 3 */
-+     848,    /* OBJ_id_GostR3410_94_bBis         1 2 643 2 2 20 4 */
-+     821,    /* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */
-+     822,    /* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */
-+     823,    /* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */
-+     824,    /* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */
-+     825,    /* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */
-+     826,    /* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */
-+     827,    /* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */
-+     828,    /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */
-+     829,    /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */
-+     830,    /* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */
-+     831,    /* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */
-+     832,    /* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */
-+     833,    /* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */
-+     834,    /* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */
-+     835,    /* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */
-+     836,    /* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */
-+     837,    /* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */
-+     838,    /* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */
-+     839,    /* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */
-+     840,    /* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */
-+     841,    /* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */
-+     842,    /* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */
-+     843,    /* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */
-+     844,    /* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */
-+     978,    /* OBJ_id_tc26_sign                 1 2 643 7 1 1 1 */
-+     981,    /* OBJ_id_tc26_digest               1 2 643 7 1 1 2 */
-+     984,    /* OBJ_id_tc26_signwithdigest       1 2 643 7 1 1 3 */
-+     987,    /* OBJ_id_tc26_mac                  1 2 643 7 1 1 4 */
-+     990,    /* OBJ_id_tc26_cipher               1 2 643 7 1 1 5 */
-+     991,    /* OBJ_id_tc26_agreement            1 2 643 7 1 1 6 */
-+     995,    /* OBJ_id_tc26_sign_constants       1 2 643 7 1 2 1 */
-+    1000,    /* OBJ_id_tc26_digest_constants     1 2 643 7 1 2 2 */
-+    1001,    /* OBJ_id_tc26_cipher_constants     1 2 643 7 1 2 5 */
-+       2,    /* OBJ_pkcs                         1 2 840 113549 1 */
-+     431,    /* OBJ_hold_instruction_none        1 2 840 10040 2 1 */
-+     432,    /* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */
-+     433,    /* OBJ_hold_instruction_reject      1 2 840 10040 2 3 */
-+     116,    /* OBJ_dsa                          1 2 840 10040 4 1 */
-+     113,    /* OBJ_dsaWithSHA1                  1 2 840 10040 4 3 */
-+     406,    /* OBJ_X9_62_prime_field            1 2 840 10045 1 1 */
-+     407,    /* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */
-+     408,    /* OBJ_X9_62_id_ecPublicKey         1 2 840 10045 2 1 */
-+     416,    /* OBJ_ecdsa_with_SHA1              1 2 840 10045 4 1 */
-+     791,    /* OBJ_ecdsa_with_Recommended       1 2 840 10045 4 2 */
-+     792,    /* OBJ_ecdsa_with_Specified         1 2 840 10045 4 3 */
-+     920,    /* OBJ_dhpublicnumber               1 2 840 10046 2 1 */
-+    1032,    /* OBJ_pkInitClientAuth             1 3 6 1 5 2 3 4 */
-+    1033,    /* OBJ_pkInitKDC                    1 3 6 1 5 2 3 5 */
-+     258,    /* OBJ_id_pkix_mod                  1 3 6 1 5 5 7 0 */
-+     175,    /* OBJ_id_pe                        1 3 6 1 5 5 7 1 */
-+     259,    /* OBJ_id_qt                        1 3 6 1 5 5 7 2 */
-+     128,    /* OBJ_id_kp                        1 3 6 1 5 5 7 3 */
-+     260,    /* OBJ_id_it                        1 3 6 1 5 5 7 4 */
-+     261,    /* OBJ_id_pkip                      1 3 6 1 5 5 7 5 */
-+     262,    /* OBJ_id_alg                       1 3 6 1 5 5 7 6 */
-+     263,    /* OBJ_id_cmc                       1 3 6 1 5 5 7 7 */
-+     264,    /* OBJ_id_on                        1 3 6 1 5 5 7 8 */
-+     265,    /* OBJ_id_pda                       1 3 6 1 5 5 7 9 */
-+     266,    /* OBJ_id_aca                       1 3 6 1 5 5 7 10 */
-+     267,    /* OBJ_id_qcs                       1 3 6 1 5 5 7 11 */
-+     268,    /* OBJ_id_cct                       1 3 6 1 5 5 7 12 */
-+     662,    /* OBJ_id_ppl                       1 3 6 1 5 5 7 21 */
-+     176,    /* OBJ_id_ad                        1 3 6 1 5 5 7 48 */
-+     507,    /* OBJ_id_hex_partial_message       1 3 6 1 7 1 1 1 */
-+     508,    /* OBJ_id_hex_multipart_message     1 3 6 1 7 1 1 2 */
-+      57,    /* OBJ_netscape                     2 16 840 1 113730 */
-+     754,    /* OBJ_camellia_128_ecb             0 3 4401 5 3 1 9 1 */
-+     766,    /* OBJ_camellia_128_ofb128          0 3 4401 5 3 1 9 3 */
-+     757,    /* OBJ_camellia_128_cfb128          0 3 4401 5 3 1 9 4 */
-+     961,    /* OBJ_camellia_128_gcm             0 3 4401 5 3 1 9 6 */
-+     962,    /* OBJ_camellia_128_ccm             0 3 4401 5 3 1 9 7 */
-+     963,    /* OBJ_camellia_128_ctr             0 3 4401 5 3 1 9 9 */
-+     964,    /* OBJ_camellia_128_cmac            0 3 4401 5 3 1 9 10 */
-+     755,    /* OBJ_camellia_192_ecb             0 3 4401 5 3 1 9 21 */
-+     767,    /* OBJ_camellia_192_ofb128          0 3 4401 5 3 1 9 23 */
-+     758,    /* OBJ_camellia_192_cfb128          0 3 4401 5 3 1 9 24 */
-+     965,    /* OBJ_camellia_192_gcm             0 3 4401 5 3 1 9 26 */
-+     966,    /* OBJ_camellia_192_ccm             0 3 4401 5 3 1 9 27 */
-+     967,    /* OBJ_camellia_192_ctr             0 3 4401 5 3 1 9 29 */
-+     968,    /* OBJ_camellia_192_cmac            0 3 4401 5 3 1 9 30 */
-+     756,    /* OBJ_camellia_256_ecb             0 3 4401 5 3 1 9 41 */
-+     768,    /* OBJ_camellia_256_ofb128          0 3 4401 5 3 1 9 43 */
-+     759,    /* OBJ_camellia_256_cfb128          0 3 4401 5 3 1 9 44 */
-+     969,    /* OBJ_camellia_256_gcm             0 3 4401 5 3 1 9 46 */
-+     970,    /* OBJ_camellia_256_ccm             0 3 4401 5 3 1 9 47 */
-+     971,    /* OBJ_camellia_256_ctr             0 3 4401 5 3 1 9 49 */
-+     972,    /* OBJ_camellia_256_cmac            0 3 4401 5 3 1 9 50 */
-+     437,    /* OBJ_pilot                        0 9 2342 19200300 100 */
-+     776,    /* OBJ_seed_ecb                     1 2 410 200004 1 3 */
-+     777,    /* OBJ_seed_cbc                     1 2 410 200004 1 4 */
-+     779,    /* OBJ_seed_cfb128                  1 2 410 200004 1 5 */
-+     778,    /* OBJ_seed_ofb128                  1 2 410 200004 1 6 */
-+     852,    /* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */
-+     853,    /* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */
-+     850,    /* OBJ_id_GostR3410_94_cc           1 2 643 2 9 1 5 3 */
-+     851,    /* OBJ_id_GostR3410_2001_cc         1 2 643 2 9 1 5 4 */
-+     849,    /* OBJ_id_Gost28147_89_cc           1 2 643 2 9 1 6 1 */
-+     854,    /* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */
-+    1004,    /* OBJ_INN                          1 2 643 3 131 1 1 */
-+     979,    /* OBJ_id_GostR3410_2012_256        1 2 643 7 1 1 1 1 */
-+     980,    /* OBJ_id_GostR3410_2012_512        1 2 643 7 1 1 1 2 */
-+     982,    /* OBJ_id_GostR3411_2012_256        1 2 643 7 1 1 2 2 */
-+     983,    /* OBJ_id_GostR3411_2012_512        1 2 643 7 1 1 2 3 */
-+     985,    /* OBJ_id_tc26_signwithdigest_gost3410_2012_256 1 2 643 7 1 1 3 2 */
-+     986,    /* OBJ_id_tc26_signwithdigest_gost3410_2012_512 1 2 643 7 1 1 3 3 */
-+     988,    /* OBJ_id_tc26_hmac_gost_3411_2012_256 1 2 643 7 1 1 4 1 */
-+     989,    /* OBJ_id_tc26_hmac_gost_3411_2012_512 1 2 643 7 1 1 4 2 */
-+     992,    /* OBJ_id_tc26_agreement_gost_3410_2012_256 1 2 643 7 1 1 6 1 */
-+     993,    /* OBJ_id_tc26_agreement_gost_3410_2012_512 1 2 643 7 1 1 6 2 */
-+     996,    /* OBJ_id_tc26_gost_3410_2012_512_constants 1 2 643 7 1 2 1 2 */
-+    1002,    /* OBJ_id_tc26_gost_28147_constants 1 2 643 7 1 2 5 1 */
-+     186,    /* OBJ_pkcs1                        1 2 840 113549 1 1 */
-+      27,    /* OBJ_pkcs3                        1 2 840 113549 1 3 */
-+     187,    /* OBJ_pkcs5                        1 2 840 113549 1 5 */
-+      20,    /* OBJ_pkcs7                        1 2 840 113549 1 7 */
-+      47,    /* OBJ_pkcs9                        1 2 840 113549 1 9 */
-+       3,    /* OBJ_md2                          1 2 840 113549 2 2 */
-+     257,    /* OBJ_md4                          1 2 840 113549 2 4 */
-+       4,    /* OBJ_md5                          1 2 840 113549 2 5 */
-+     797,    /* OBJ_hmacWithMD5                  1 2 840 113549 2 6 */
-+     163,    /* OBJ_hmacWithSHA1                 1 2 840 113549 2 7 */
-+     798,    /* OBJ_hmacWithSHA224               1 2 840 113549 2 8 */
-+     799,    /* OBJ_hmacWithSHA256               1 2 840 113549 2 9 */
-+     800,    /* OBJ_hmacWithSHA384               1 2 840 113549 2 10 */
-+     801,    /* OBJ_hmacWithSHA512               1 2 840 113549 2 11 */
-+      37,    /* OBJ_rc2_cbc                      1 2 840 113549 3 2 */
-+       5,    /* OBJ_rc4                          1 2 840 113549 3 4 */
-+      44,    /* OBJ_des_ede3_cbc                 1 2 840 113549 3 7 */
-+     120,    /* OBJ_rc5_cbc                      1 2 840 113549 3 8 */
-+     643,    /* OBJ_des_cdmf                     1 2 840 113549 3 10 */
-+     680,    /* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */
-+     684,    /* OBJ_X9_62_c2pnb163v1             1 2 840 10045 3 0 1 */
-+     685,    /* OBJ_X9_62_c2pnb163v2             1 2 840 10045 3 0 2 */
-+     686,    /* OBJ_X9_62_c2pnb163v3             1 2 840 10045 3 0 3 */
-+     687,    /* OBJ_X9_62_c2pnb176v1             1 2 840 10045 3 0 4 */
-+     688,    /* OBJ_X9_62_c2tnb191v1             1 2 840 10045 3 0 5 */
-+     689,    /* OBJ_X9_62_c2tnb191v2             1 2 840 10045 3 0 6 */
-+     690,    /* OBJ_X9_62_c2tnb191v3             1 2 840 10045 3 0 7 */
-+     691,    /* OBJ_X9_62_c2onb191v4             1 2 840 10045 3 0 8 */
-+     692,    /* OBJ_X9_62_c2onb191v5             1 2 840 10045 3 0 9 */
-+     693,    /* OBJ_X9_62_c2pnb208w1             1 2 840 10045 3 0 10 */
-+     694,    /* OBJ_X9_62_c2tnb239v1             1 2 840 10045 3 0 11 */
-+     695,    /* OBJ_X9_62_c2tnb239v2             1 2 840 10045 3 0 12 */
-+     696,    /* OBJ_X9_62_c2tnb239v3             1 2 840 10045 3 0 13 */
-+     697,    /* OBJ_X9_62_c2onb239v4             1 2 840 10045 3 0 14 */
-+     698,    /* OBJ_X9_62_c2onb239v5             1 2 840 10045 3 0 15 */
-+     699,    /* OBJ_X9_62_c2pnb272w1             1 2 840 10045 3 0 16 */
-+     700,    /* OBJ_X9_62_c2pnb304w1             1 2 840 10045 3 0 17 */
-+     701,    /* OBJ_X9_62_c2tnb359v1             1 2 840 10045 3 0 18 */
-+     702,    /* OBJ_X9_62_c2pnb368w1             1 2 840 10045 3 0 19 */
-+     703,    /* OBJ_X9_62_c2tnb431r1             1 2 840 10045 3 0 20 */
-+     409,    /* OBJ_X9_62_prime192v1             1 2 840 10045 3 1 1 */
-+     410,    /* OBJ_X9_62_prime192v2             1 2 840 10045 3 1 2 */
-+     411,    /* OBJ_X9_62_prime192v3             1 2 840 10045 3 1 3 */
-+     412,    /* OBJ_X9_62_prime239v1             1 2 840 10045 3 1 4 */
-+     413,    /* OBJ_X9_62_prime239v2             1 2 840 10045 3 1 5 */
-+     414,    /* OBJ_X9_62_prime239v3             1 2 840 10045 3 1 6 */
-+     415,    /* OBJ_X9_62_prime256v1             1 2 840 10045 3 1 7 */
-+     793,    /* OBJ_ecdsa_with_SHA224            1 2 840 10045 4 3 1 */
-+     794,    /* OBJ_ecdsa_with_SHA256            1 2 840 10045 4 3 2 */
-+     795,    /* OBJ_ecdsa_with_SHA384            1 2 840 10045 4 3 3 */
-+     796,    /* OBJ_ecdsa_with_SHA512            1 2 840 10045 4 3 4 */
-+     269,    /* OBJ_id_pkix1_explicit_88         1 3 6 1 5 5 7 0 1 */
-+     270,    /* OBJ_id_pkix1_implicit_88         1 3 6 1 5 5 7 0 2 */
-+     271,    /* OBJ_id_pkix1_explicit_93         1 3 6 1 5 5 7 0 3 */
-+     272,    /* OBJ_id_pkix1_implicit_93         1 3 6 1 5 5 7 0 4 */
-+     273,    /* OBJ_id_mod_crmf                  1 3 6 1 5 5 7 0 5 */
-+     274,    /* OBJ_id_mod_cmc                   1 3 6 1 5 5 7 0 6 */
-+     275,    /* OBJ_id_mod_kea_profile_88        1 3 6 1 5 5 7 0 7 */
-+     276,    /* OBJ_id_mod_kea_profile_93        1 3 6 1 5 5 7 0 8 */
-+     277,    /* OBJ_id_mod_cmp                   1 3 6 1 5 5 7 0 9 */
-+     278,    /* OBJ_id_mod_qualified_cert_88     1 3 6 1 5 5 7 0 10 */
-+     279,    /* OBJ_id_mod_qualified_cert_93     1 3 6 1 5 5 7 0 11 */
-+     280,    /* OBJ_id_mod_attribute_cert        1 3 6 1 5 5 7 0 12 */
-+     281,    /* OBJ_id_mod_timestamp_protocol    1 3 6 1 5 5 7 0 13 */
-+     282,    /* OBJ_id_mod_ocsp                  1 3 6 1 5 5 7 0 14 */
-+     283,    /* OBJ_id_mod_dvcs                  1 3 6 1 5 5 7 0 15 */
-+     284,    /* OBJ_id_mod_cmp2000               1 3 6 1 5 5 7 0 16 */
-+     177,    /* OBJ_info_access                  1 3 6 1 5 5 7 1 1 */
-+     285,    /* OBJ_biometricInfo                1 3 6 1 5 5 7 1 2 */
-+     286,    /* OBJ_qcStatements                 1 3 6 1 5 5 7 1 3 */
-+     287,    /* OBJ_ac_auditEntity               1 3 6 1 5 5 7 1 4 */
-+     288,    /* OBJ_ac_targeting                 1 3 6 1 5 5 7 1 5 */
-+     289,    /* OBJ_aaControls                   1 3 6 1 5 5 7 1 6 */
-+     290,    /* OBJ_sbgp_ipAddrBlock             1 3 6 1 5 5 7 1 7 */
-+     291,    /* OBJ_sbgp_autonomousSysNum        1 3 6 1 5 5 7 1 8 */
-+     292,    /* OBJ_sbgp_routerIdentifier        1 3 6 1 5 5 7 1 9 */
-+     397,    /* OBJ_ac_proxying                  1 3 6 1 5 5 7 1 10 */
-+     398,    /* OBJ_sinfo_access                 1 3 6 1 5 5 7 1 11 */
-+     663,    /* OBJ_proxyCertInfo                1 3 6 1 5 5 7 1 14 */
-+    1020,    /* OBJ_tlsfeature                   1 3 6 1 5 5 7 1 24 */
-+     164,    /* OBJ_id_qt_cps                    1 3 6 1 5 5 7 2 1 */
-+     165,    /* OBJ_id_qt_unotice                1 3 6 1 5 5 7 2 2 */
-+     293,    /* OBJ_textNotice                   1 3 6 1 5 5 7 2 3 */
-+     129,    /* OBJ_server_auth                  1 3 6 1 5 5 7 3 1 */
-+     130,    /* OBJ_client_auth                  1 3 6 1 5 5 7 3 2 */
-+     131,    /* OBJ_code_sign                    1 3 6 1 5 5 7 3 3 */
-+     132,    /* OBJ_email_protect                1 3 6 1 5 5 7 3 4 */
-+     294,    /* OBJ_ipsecEndSystem               1 3 6 1 5 5 7 3 5 */
-+     295,    /* OBJ_ipsecTunnel                  1 3 6 1 5 5 7 3 6 */
-+     296,    /* OBJ_ipsecUser                    1 3 6 1 5 5 7 3 7 */
-+     133,    /* OBJ_time_stamp                   1 3 6 1 5 5 7 3 8 */
-+     180,    /* OBJ_OCSP_sign                    1 3 6 1 5 5 7 3 9 */
-+     297,    /* OBJ_dvcs                         1 3 6 1 5 5 7 3 10 */
-+    1022,    /* OBJ_ipsec_IKE                    1 3 6 1 5 5 7 3 17 */
-+    1023,    /* OBJ_capwapAC                     1 3 6 1 5 5 7 3 18 */
-+    1024,    /* OBJ_capwapWTP                    1 3 6 1 5 5 7 3 19 */
-+    1025,    /* OBJ_sshClient                    1 3 6 1 5 5 7 3 21 */
-+    1026,    /* OBJ_sshServer                    1 3 6 1 5 5 7 3 22 */
-+    1027,    /* OBJ_sendRouter                   1 3 6 1 5 5 7 3 23 */
-+    1028,    /* OBJ_sendProxiedRouter            1 3 6 1 5 5 7 3 24 */
-+    1029,    /* OBJ_sendOwner                    1 3 6 1 5 5 7 3 25 */
-+    1030,    /* OBJ_sendProxiedOwner             1 3 6 1 5 5 7 3 26 */
-+     298,    /* OBJ_id_it_caProtEncCert          1 3 6 1 5 5 7 4 1 */
-+     299,    /* OBJ_id_it_signKeyPairTypes       1 3 6 1 5 5 7 4 2 */
-+     300,    /* OBJ_id_it_encKeyPairTypes        1 3 6 1 5 5 7 4 3 */
-+     301,    /* OBJ_id_it_preferredSymmAlg       1 3 6 1 5 5 7 4 4 */
-+     302,    /* OBJ_id_it_caKeyUpdateInfo        1 3 6 1 5 5 7 4 5 */
-+     303,    /* OBJ_id_it_currentCRL             1 3 6 1 5 5 7 4 6 */
-+     304,    /* OBJ_id_it_unsupportedOIDs        1 3 6 1 5 5 7 4 7 */
-+     305,    /* OBJ_id_it_subscriptionRequest    1 3 6 1 5 5 7 4 8 */
-+     306,    /* OBJ_id_it_subscriptionResponse   1 3 6 1 5 5 7 4 9 */
-+     307,    /* OBJ_id_it_keyPairParamReq        1 3 6 1 5 5 7 4 10 */
-+     308,    /* OBJ_id_it_keyPairParamRep        1 3 6 1 5 5 7 4 11 */
-+     309,    /* OBJ_id_it_revPassphrase          1 3 6 1 5 5 7 4 12 */
-+     310,    /* OBJ_id_it_implicitConfirm        1 3 6 1 5 5 7 4 13 */
-+     311,    /* OBJ_id_it_confirmWaitTime        1 3 6 1 5 5 7 4 14 */
-+     312,    /* OBJ_id_it_origPKIMessage         1 3 6 1 5 5 7 4 15 */
-+     784,    /* OBJ_id_it_suppLangTags           1 3 6 1 5 5 7 4 16 */
-+     313,    /* OBJ_id_regCtrl                   1 3 6 1 5 5 7 5 1 */
-+     314,    /* OBJ_id_regInfo                   1 3 6 1 5 5 7 5 2 */
-+     323,    /* OBJ_id_alg_des40                 1 3 6 1 5 5 7 6 1 */
-+     324,    /* OBJ_id_alg_noSignature           1 3 6 1 5 5 7 6 2 */
-+     325,    /* OBJ_id_alg_dh_sig_hmac_sha1      1 3 6 1 5 5 7 6 3 */
-+     326,    /* OBJ_id_alg_dh_pop                1 3 6 1 5 5 7 6 4 */
-+     327,    /* OBJ_id_cmc_statusInfo            1 3 6 1 5 5 7 7 1 */
-+     328,    /* OBJ_id_cmc_identification        1 3 6 1 5 5 7 7 2 */
-+     329,    /* OBJ_id_cmc_identityProof         1 3 6 1 5 5 7 7 3 */
-+     330,    /* OBJ_id_cmc_dataReturn            1 3 6 1 5 5 7 7 4 */
-+     331,    /* OBJ_id_cmc_transactionId         1 3 6 1 5 5 7 7 5 */
-+     332,    /* OBJ_id_cmc_senderNonce           1 3 6 1 5 5 7 7 6 */
-+     333,    /* OBJ_id_cmc_recipientNonce        1 3 6 1 5 5 7 7 7 */
-+     334,    /* OBJ_id_cmc_addExtensions         1 3 6 1 5 5 7 7 8 */
-+     335,    /* OBJ_id_cmc_encryptedPOP          1 3 6 1 5 5 7 7 9 */
-+     336,    /* OBJ_id_cmc_decryptedPOP          1 3 6 1 5 5 7 7 10 */
-+     337,    /* OBJ_id_cmc_lraPOPWitness         1 3 6 1 5 5 7 7 11 */
-+     338,    /* OBJ_id_cmc_getCert               1 3 6 1 5 5 7 7 15 */
-+     339,    /* OBJ_id_cmc_getCRL                1 3 6 1 5 5 7 7 16 */
-+     340,    /* OBJ_id_cmc_revokeRequest         1 3 6 1 5 5 7 7 17 */
-+     341,    /* OBJ_id_cmc_regInfo               1 3 6 1 5 5 7 7 18 */
-+     342,    /* OBJ_id_cmc_responseInfo          1 3 6 1 5 5 7 7 19 */
-+     343,    /* OBJ_id_cmc_queryPending          1 3 6 1 5 5 7 7 21 */
-+     344,    /* OBJ_id_cmc_popLinkRandom         1 3 6 1 5 5 7 7 22 */
-+     345,    /* OBJ_id_cmc_popLinkWitness        1 3 6 1 5 5 7 7 23 */
-+     346,    /* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */
-+     347,    /* OBJ_id_on_personalData           1 3 6 1 5 5 7 8 1 */
-+     858,    /* OBJ_id_on_permanentIdentifier    1 3 6 1 5 5 7 8 3 */
-+     348,    /* OBJ_id_pda_dateOfBirth           1 3 6 1 5 5 7 9 1 */
-+     349,    /* OBJ_id_pda_placeOfBirth          1 3 6 1 5 5 7 9 2 */
-+     351,    /* OBJ_id_pda_gender                1 3 6 1 5 5 7 9 3 */
-+     352,    /* OBJ_id_pda_countryOfCitizenship  1 3 6 1 5 5 7 9 4 */
-+     353,    /* OBJ_id_pda_countryOfResidence    1 3 6 1 5 5 7 9 5 */
-+     354,    /* OBJ_id_aca_authenticationInfo    1 3 6 1 5 5 7 10 1 */
-+     355,    /* OBJ_id_aca_accessIdentity        1 3 6 1 5 5 7 10 2 */
-+     356,    /* OBJ_id_aca_chargingIdentity      1 3 6 1 5 5 7 10 3 */
-+     357,    /* OBJ_id_aca_group                 1 3 6 1 5 5 7 10 4 */
-+     358,    /* OBJ_id_aca_role                  1 3 6 1 5 5 7 10 5 */
-+     399,    /* OBJ_id_aca_encAttrs              1 3 6 1 5 5 7 10 6 */
-+     359,    /* OBJ_id_qcs_pkixQCSyntax_v1       1 3 6 1 5 5 7 11 1 */
-+     360,    /* OBJ_id_cct_crs                   1 3 6 1 5 5 7 12 1 */
-+     361,    /* OBJ_id_cct_PKIData               1 3 6 1 5 5 7 12 2 */
-+     362,    /* OBJ_id_cct_PKIResponse           1 3 6 1 5 5 7 12 3 */
-+     664,    /* OBJ_id_ppl_anyLanguage           1 3 6 1 5 5 7 21 0 */
-+     665,    /* OBJ_id_ppl_inheritAll            1 3 6 1 5 5 7 21 1 */
-+     667,    /* OBJ_Independent                  1 3 6 1 5 5 7 21 2 */
-+     178,    /* OBJ_ad_OCSP                      1 3 6 1 5 5 7 48 1 */
-+     179,    /* OBJ_ad_ca_issuers                1 3 6 1 5 5 7 48 2 */
-+     363,    /* OBJ_ad_timeStamping              1 3 6 1 5 5 7 48 3 */
-+     364,    /* OBJ_ad_dvcs                      1 3 6 1 5 5 7 48 4 */
-+     785,    /* OBJ_caRepository                 1 3 6 1 5 5 7 48 5 */
-+     780,    /* OBJ_hmac_md5                     1 3 6 1 5 5 8 1 1 */
-+     781,    /* OBJ_hmac_sha1                    1 3 6 1 5 5 8 1 2 */
-+      58,    /* OBJ_netscape_cert_extension      2 16 840 1 113730 1 */
-+      59,    /* OBJ_netscape_data_type           2 16 840 1 113730 2 */
-+     438,    /* OBJ_pilotAttributeType           0 9 2342 19200300 100 1 */
-+     439,    /* OBJ_pilotAttributeSyntax         0 9 2342 19200300 100 3 */
-+     440,    /* OBJ_pilotObjectClass             0 9 2342 19200300 100 4 */
-+     441,    /* OBJ_pilotGroups                  0 9 2342 19200300 100 10 */
-+     997,    /* OBJ_id_tc26_gost_3410_2012_512_paramSetTest 1 2 643 7 1 2 1 2 0 */
-+     998,    /* OBJ_id_tc26_gost_3410_2012_512_paramSetA 1 2 643 7 1 2 1 2 1 */
-+     999,    /* OBJ_id_tc26_gost_3410_2012_512_paramSetB 1 2 643 7 1 2 1 2 2 */
-+    1003,    /* OBJ_id_tc26_gost_28147_param_Z   1 2 643 7 1 2 5 1 1 */
-+     108,    /* OBJ_cast5_cbc                    1 2 840 113533 7 66 10 */
-+     112,    /* OBJ_pbeWithMD5AndCast5_CBC       1 2 840 113533 7 66 12 */
-+     782,    /* OBJ_id_PasswordBasedMAC          1 2 840 113533 7 66 13 */
-+     783,    /* OBJ_id_DHBasedMac                1 2 840 113533 7 66 30 */
-+       6,    /* OBJ_rsaEncryption                1 2 840 113549 1 1 1 */
-+       7,    /* OBJ_md2WithRSAEncryption         1 2 840 113549 1 1 2 */
-+     396,    /* OBJ_md4WithRSAEncryption         1 2 840 113549 1 1 3 */
-+       8,    /* OBJ_md5WithRSAEncryption         1 2 840 113549 1 1 4 */
-+      65,    /* OBJ_sha1WithRSAEncryption        1 2 840 113549 1 1 5 */
-+     644,    /* OBJ_rsaOAEPEncryptionSET         1 2 840 113549 1 1 6 */
-+     919,    /* OBJ_rsaesOaep                    1 2 840 113549 1 1 7 */
-+     911,    /* OBJ_mgf1                         1 2 840 113549 1 1 8 */
-+     935,    /* OBJ_pSpecified                   1 2 840 113549 1 1 9 */
-+     912,    /* OBJ_rsassaPss                    1 2 840 113549 1 1 10 */
-+     668,    /* OBJ_sha256WithRSAEncryption      1 2 840 113549 1 1 11 */
-+     669,    /* OBJ_sha384WithRSAEncryption      1 2 840 113549 1 1 12 */
-+     670,    /* OBJ_sha512WithRSAEncryption      1 2 840 113549 1 1 13 */
-+     671,    /* OBJ_sha224WithRSAEncryption      1 2 840 113549 1 1 14 */
-+      28,    /* OBJ_dhKeyAgreement               1 2 840 113549 1 3 1 */
-+       9,    /* OBJ_pbeWithMD2AndDES_CBC         1 2 840 113549 1 5 1 */
-+      10,    /* OBJ_pbeWithMD5AndDES_CBC         1 2 840 113549 1 5 3 */
-+     168,    /* OBJ_pbeWithMD2AndRC2_CBC         1 2 840 113549 1 5 4 */
-+     169,    /* OBJ_pbeWithMD5AndRC2_CBC         1 2 840 113549 1 5 6 */
-+     170,    /* OBJ_pbeWithSHA1AndDES_CBC        1 2 840 113549 1 5 10 */
-+      68,    /* OBJ_pbeWithSHA1AndRC2_CBC        1 2 840 113549 1 5 11 */
-+      69,    /* OBJ_id_pbkdf2                    1 2 840 113549 1 5 12 */
-+     161,    /* OBJ_pbes2                        1 2 840 113549 1 5 13 */
-+     162,    /* OBJ_pbmac1                       1 2 840 113549 1 5 14 */
-+      21,    /* OBJ_pkcs7_data                   1 2 840 113549 1 7 1 */
-+      22,    /* OBJ_pkcs7_signed                 1 2 840 113549 1 7 2 */
-+      23,    /* OBJ_pkcs7_enveloped              1 2 840 113549 1 7 3 */
-+      24,    /* OBJ_pkcs7_signedAndEnveloped     1 2 840 113549 1 7 4 */
-+      25,    /* OBJ_pkcs7_digest                 1 2 840 113549 1 7 5 */
-+      26,    /* OBJ_pkcs7_encrypted              1 2 840 113549 1 7 6 */
-+      48,    /* OBJ_pkcs9_emailAddress           1 2 840 113549 1 9 1 */
-+      49,    /* OBJ_pkcs9_unstructuredName       1 2 840 113549 1 9 2 */
-+      50,    /* OBJ_pkcs9_contentType            1 2 840 113549 1 9 3 */
-+      51,    /* OBJ_pkcs9_messageDigest          1 2 840 113549 1 9 4 */
-+      52,    /* OBJ_pkcs9_signingTime            1 2 840 113549 1 9 5 */
-+      53,    /* OBJ_pkcs9_countersignature       1 2 840 113549 1 9 6 */
-+      54,    /* OBJ_pkcs9_challengePassword      1 2 840 113549 1 9 7 */
-+      55,    /* OBJ_pkcs9_unstructuredAddress    1 2 840 113549 1 9 8 */
-+      56,    /* OBJ_pkcs9_extCertAttributes      1 2 840 113549 1 9 9 */
-+     172,    /* OBJ_ext_req                      1 2 840 113549 1 9 14 */
-+     167,    /* OBJ_SMIMECapabilities            1 2 840 113549 1 9 15 */
-+     188,    /* OBJ_SMIME                        1 2 840 113549 1 9 16 */
-+     156,    /* OBJ_friendlyName                 1 2 840 113549 1 9 20 */
-+     157,    /* OBJ_localKeyID                   1 2 840 113549 1 9 21 */
-+     681,    /* OBJ_X9_62_onBasis                1 2 840 10045 1 2 3 1 */
-+     682,    /* OBJ_X9_62_tpBasis                1 2 840 10045 1 2 3 2 */
-+     683,    /* OBJ_X9_62_ppBasis                1 2 840 10045 1 2 3 3 */
-+     417,    /* OBJ_ms_csp_name                  1 3 6 1 4 1 311 17 1 */
-+     856,    /* OBJ_LocalKeySet                  1 3 6 1 4 1 311 17 2 */
-+     390,    /* OBJ_dcObject                     1 3 6 1 4 1 1466 344 */
-+      91,    /* OBJ_bf_cbc                       1 3 6 1 4 1 3029 1 2 */
-+     973,    /* OBJ_id_scrypt                    1 3 6 1 4 1 11591 4 11 */
-+     315,    /* OBJ_id_regCtrl_regToken          1 3 6 1 5 5 7 5 1 1 */
-+     316,    /* OBJ_id_regCtrl_authenticator     1 3 6 1 5 5 7 5 1 2 */
-+     317,    /* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */
-+     318,    /* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */
-+     319,    /* OBJ_id_regCtrl_oldCertID         1 3 6 1 5 5 7 5 1 5 */
-+     320,    /* OBJ_id_regCtrl_protocolEncrKey   1 3 6 1 5 5 7 5 1 6 */
-+     321,    /* OBJ_id_regInfo_utf8Pairs         1 3 6 1 5 5 7 5 2 1 */
-+     322,    /* OBJ_id_regInfo_certReq           1 3 6 1 5 5 7 5 2 2 */
-+     365,    /* OBJ_id_pkix_OCSP_basic           1 3 6 1 5 5 7 48 1 1 */
-+     366,    /* OBJ_id_pkix_OCSP_Nonce           1 3 6 1 5 5 7 48 1 2 */
-+     367,    /* OBJ_id_pkix_OCSP_CrlID           1 3 6 1 5 5 7 48 1 3 */
-+     368,    /* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */
-+     369,    /* OBJ_id_pkix_OCSP_noCheck         1 3 6 1 5 5 7 48 1 5 */
-+     370,    /* OBJ_id_pkix_OCSP_archiveCutoff   1 3 6 1 5 5 7 48 1 6 */
-+     371,    /* OBJ_id_pkix_OCSP_serviceLocator  1 3 6 1 5 5 7 48 1 7 */
-+     372,    /* OBJ_id_pkix_OCSP_extendedStatus  1 3 6 1 5 5 7 48 1 8 */
-+     373,    /* OBJ_id_pkix_OCSP_valid           1 3 6 1 5 5 7 48 1 9 */
-+     374,    /* OBJ_id_pkix_OCSP_path            1 3 6 1 5 5 7 48 1 10 */
-+     375,    /* OBJ_id_pkix_OCSP_trustRoot       1 3 6 1 5 5 7 48 1 11 */
-+     921,    /* OBJ_brainpoolP160r1              1 3 36 3 3 2 8 1 1 1 */
-+     922,    /* OBJ_brainpoolP160t1              1 3 36 3 3 2 8 1 1 2 */
-+     923,    /* OBJ_brainpoolP192r1              1 3 36 3 3 2 8 1 1 3 */
-+     924,    /* OBJ_brainpoolP192t1              1 3 36 3 3 2 8 1 1 4 */
-+     925,    /* OBJ_brainpoolP224r1              1 3 36 3 3 2 8 1 1 5 */
-+     926,    /* OBJ_brainpoolP224t1              1 3 36 3 3 2 8 1 1 6 */
-+     927,    /* OBJ_brainpoolP256r1              1 3 36 3 3 2 8 1 1 7 */
-+     928,    /* OBJ_brainpoolP256t1              1 3 36 3 3 2 8 1 1 8 */
-+     929,    /* OBJ_brainpoolP320r1              1 3 36 3 3 2 8 1 1 9 */
-+     930,    /* OBJ_brainpoolP320t1              1 3 36 3 3 2 8 1 1 10 */
-+     931,    /* OBJ_brainpoolP384r1              1 3 36 3 3 2 8 1 1 11 */
-+     932,    /* OBJ_brainpoolP384t1              1 3 36 3 3 2 8 1 1 12 */
-+     933,    /* OBJ_brainpoolP512r1              1 3 36 3 3 2 8 1 1 13 */
-+     934,    /* OBJ_brainpoolP512t1              1 3 36 3 3 2 8 1 1 14 */
-+     936,    /* OBJ_dhSinglePass_stdDH_sha1kdf_scheme 1 3 133 16 840 63 0 2 */
-+     941,    /* OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme 1 3 133 16 840 63 0 3 */
-+     418,    /* OBJ_aes_128_ecb                  2 16 840 1 101 3 4 1 1 */
-+     419,    /* OBJ_aes_128_cbc                  2 16 840 1 101 3 4 1 2 */
-+     420,    /* OBJ_aes_128_ofb128               2 16 840 1 101 3 4 1 3 */
-+     421,    /* OBJ_aes_128_cfb128               2 16 840 1 101 3 4 1 4 */
-+     788,    /* OBJ_id_aes128_wrap               2 16 840 1 101 3 4 1 5 */
-+     895,    /* OBJ_aes_128_gcm                  2 16 840 1 101 3 4 1 6 */
-+     896,    /* OBJ_aes_128_ccm                  2 16 840 1 101 3 4 1 7 */
-+     897,    /* OBJ_id_aes128_wrap_pad           2 16 840 1 101 3 4 1 8 */
-+     422,    /* OBJ_aes_192_ecb                  2 16 840 1 101 3 4 1 21 */
-+     423,    /* OBJ_aes_192_cbc                  2 16 840 1 101 3 4 1 22 */
-+     424,    /* OBJ_aes_192_ofb128               2 16 840 1 101 3 4 1 23 */
-+     425,    /* OBJ_aes_192_cfb128               2 16 840 1 101 3 4 1 24 */
-+     789,    /* OBJ_id_aes192_wrap               2 16 840 1 101 3 4 1 25 */
-+     898,    /* OBJ_aes_192_gcm                  2 16 840 1 101 3 4 1 26 */
-+     899,    /* OBJ_aes_192_ccm                  2 16 840 1 101 3 4 1 27 */
-+     900,    /* OBJ_id_aes192_wrap_pad           2 16 840 1 101 3 4 1 28 */
-+     426,    /* OBJ_aes_256_ecb                  2 16 840 1 101 3 4 1 41 */
-+     427,    /* OBJ_aes_256_cbc                  2 16 840 1 101 3 4 1 42 */
-+     428,    /* OBJ_aes_256_ofb128               2 16 840 1 101 3 4 1 43 */
-+     429,    /* OBJ_aes_256_cfb128               2 16 840 1 101 3 4 1 44 */
-+     790,    /* OBJ_id_aes256_wrap               2 16 840 1 101 3 4 1 45 */
-+     901,    /* OBJ_aes_256_gcm                  2 16 840 1 101 3 4 1 46 */
-+     902,    /* OBJ_aes_256_ccm                  2 16 840 1 101 3 4 1 47 */
-+     903,    /* OBJ_id_aes256_wrap_pad           2 16 840 1 101 3 4 1 48 */
-+     672,    /* OBJ_sha256                       2 16 840 1 101 3 4 2 1 */
-+     673,    /* OBJ_sha384                       2 16 840 1 101 3 4 2 2 */
-+     674,    /* OBJ_sha512                       2 16 840 1 101 3 4 2 3 */
-+     675,    /* OBJ_sha224                       2 16 840 1 101 3 4 2 4 */
-+     802,    /* OBJ_dsa_with_SHA224              2 16 840 1 101 3 4 3 1 */
-+     803,    /* OBJ_dsa_with_SHA256              2 16 840 1 101 3 4 3 2 */
-+      71,    /* OBJ_netscape_cert_type           2 16 840 1 113730 1 1 */
-+      72,    /* OBJ_netscape_base_url            2 16 840 1 113730 1 2 */
-+      73,    /* OBJ_netscape_revocation_url      2 16 840 1 113730 1 3 */
-+      74,    /* OBJ_netscape_ca_revocation_url   2 16 840 1 113730 1 4 */
-+      75,    /* OBJ_netscape_renewal_url         2 16 840 1 113730 1 7 */
-+      76,    /* OBJ_netscape_ca_policy_url       2 16 840 1 113730 1 8 */
-+      77,    /* OBJ_netscape_ssl_server_name     2 16 840 1 113730 1 12 */
-+      78,    /* OBJ_netscape_comment             2 16 840 1 113730 1 13 */
-+      79,    /* OBJ_netscape_cert_sequence       2 16 840 1 113730 2 5 */
-+     139,    /* OBJ_ns_sgc                       2 16 840 1 113730 4 1 */
-+     458,    /* OBJ_userId                       0 9 2342 19200300 100 1 1 */
-+     459,    /* OBJ_textEncodedORAddress         0 9 2342 19200300 100 1 2 */
-+     460,    /* OBJ_rfc822Mailbox                0 9 2342 19200300 100 1 3 */
-+     461,    /* OBJ_info                         0 9 2342 19200300 100 1 4 */
-+     462,    /* OBJ_favouriteDrink               0 9 2342 19200300 100 1 5 */
-+     463,    /* OBJ_roomNumber                   0 9 2342 19200300 100 1 6 */
-+     464,    /* OBJ_photo                        0 9 2342 19200300 100 1 7 */
-+     465,    /* OBJ_userClass                    0 9 2342 19200300 100 1 8 */
-+     466,    /* OBJ_host                         0 9 2342 19200300 100 1 9 */
-+     467,    /* OBJ_manager                      0 9 2342 19200300 100 1 10 */
-+     468,    /* OBJ_documentIdentifier           0 9 2342 19200300 100 1 11 */
-+     469,    /* OBJ_documentTitle                0 9 2342 19200300 100 1 12 */
-+     470,    /* OBJ_documentVersion              0 9 2342 19200300 100 1 13 */
-+     471,    /* OBJ_documentAuthor               0 9 2342 19200300 100 1 14 */
-+     472,    /* OBJ_documentLocation             0 9 2342 19200300 100 1 15 */
-+     473,    /* OBJ_homeTelephoneNumber          0 9 2342 19200300 100 1 20 */
-+     474,    /* OBJ_secretary                    0 9 2342 19200300 100 1 21 */
-+     475,    /* OBJ_otherMailbox                 0 9 2342 19200300 100 1 22 */
-+     476,    /* OBJ_lastModifiedTime             0 9 2342 19200300 100 1 23 */
-+     477,    /* OBJ_lastModifiedBy               0 9 2342 19200300 100 1 24 */
-+     391,    /* OBJ_domainComponent              0 9 2342 19200300 100 1 25 */
-+     478,    /* OBJ_aRecord                      0 9 2342 19200300 100 1 26 */
-+     479,    /* OBJ_pilotAttributeType27         0 9 2342 19200300 100 1 27 */
-+     480,    /* OBJ_mXRecord                     0 9 2342 19200300 100 1 28 */
-+     481,    /* OBJ_nSRecord                     0 9 2342 19200300 100 1 29 */
-+     482,    /* OBJ_sOARecord                    0 9 2342 19200300 100 1 30 */
-+     483,    /* OBJ_cNAMERecord                  0 9 2342 19200300 100 1 31 */
-+     484,    /* OBJ_associatedDomain             0 9 2342 19200300 100 1 37 */
-+     485,    /* OBJ_associatedName               0 9 2342 19200300 100 1 38 */
-+     486,    /* OBJ_homePostalAddress            0 9 2342 19200300 100 1 39 */
-+     487,    /* OBJ_personalTitle                0 9 2342 19200300 100 1 40 */
-+     488,    /* OBJ_mobileTelephoneNumber        0 9 2342 19200300 100 1 41 */
-+     489,    /* OBJ_pagerTelephoneNumber         0 9 2342 19200300 100 1 42 */
-+     490,    /* OBJ_friendlyCountryName          0 9 2342 19200300 100 1 43 */
-+     102,    /* OBJ_uniqueIdentifier             0 9 2342 19200300 100 1 44 */
-+     491,    /* OBJ_organizationalStatus         0 9 2342 19200300 100 1 45 */
-+     492,    /* OBJ_janetMailbox                 0 9 2342 19200300 100 1 46 */
-+     493,    /* OBJ_mailPreferenceOption         0 9 2342 19200300 100 1 47 */
-+     494,    /* OBJ_buildingName                 0 9 2342 19200300 100 1 48 */
-+     495,    /* OBJ_dSAQuality                   0 9 2342 19200300 100 1 49 */
-+     496,    /* OBJ_singleLevelQuality           0 9 2342 19200300 100 1 50 */
-+     497,    /* OBJ_subtreeMinimumQuality        0 9 2342 19200300 100 1 51 */
-+     498,    /* OBJ_subtreeMaximumQuality        0 9 2342 19200300 100 1 52 */
-+     499,    /* OBJ_personalSignature            0 9 2342 19200300 100 1 53 */
-+     500,    /* OBJ_dITRedirect                  0 9 2342 19200300 100 1 54 */
-+     501,    /* OBJ_audio                        0 9 2342 19200300 100 1 55 */
-+     502,    /* OBJ_documentPublisher            0 9 2342 19200300 100 1 56 */
-+     442,    /* OBJ_iA5StringSyntax              0 9 2342 19200300 100 3 4 */
-+     443,    /* OBJ_caseIgnoreIA5StringSyntax    0 9 2342 19200300 100 3 5 */
-+     444,    /* OBJ_pilotObject                  0 9 2342 19200300 100 4 3 */
-+     445,    /* OBJ_pilotPerson                  0 9 2342 19200300 100 4 4 */
-+     446,    /* OBJ_account                      0 9 2342 19200300 100 4 5 */
-+     447,    /* OBJ_document                     0 9 2342 19200300 100 4 6 */
-+     448,    /* OBJ_room                         0 9 2342 19200300 100 4 7 */
-+     449,    /* OBJ_documentSeries               0 9 2342 19200300 100 4 9 */
-+     392,    /* OBJ_Domain                       0 9 2342 19200300 100 4 13 */
-+     450,    /* OBJ_rFC822localPart              0 9 2342 19200300 100 4 14 */
-+     451,    /* OBJ_dNSDomain                    0 9 2342 19200300 100 4 15 */
-+     452,    /* OBJ_domainRelatedObject          0 9 2342 19200300 100 4 17 */
-+     453,    /* OBJ_friendlyCountry              0 9 2342 19200300 100 4 18 */
-+     454,    /* OBJ_simpleSecurityObject         0 9 2342 19200300 100 4 19 */
-+     455,    /* OBJ_pilotOrganization            0 9 2342 19200300 100 4 20 */
-+     456,    /* OBJ_pilotDSA                     0 9 2342 19200300 100 4 21 */
-+     457,    /* OBJ_qualityLabelledData          0 9 2342 19200300 100 4 22 */
-+     189,    /* OBJ_id_smime_mod                 1 2 840 113549 1 9 16 0 */
-+     190,    /* OBJ_id_smime_ct                  1 2 840 113549 1 9 16 1 */
-+     191,    /* OBJ_id_smime_aa                  1 2 840 113549 1 9 16 2 */
-+     192,    /* OBJ_id_smime_alg                 1 2 840 113549 1 9 16 3 */
-+     193,    /* OBJ_id_smime_cd                  1 2 840 113549 1 9 16 4 */
-+     194,    /* OBJ_id_smime_spq                 1 2 840 113549 1 9 16 5 */
-+     195,    /* OBJ_id_smime_cti                 1 2 840 113549 1 9 16 6 */
-+     158,    /* OBJ_x509Certificate              1 2 840 113549 1 9 22 1 */
-+     159,    /* OBJ_sdsiCertificate              1 2 840 113549 1 9 22 2 */
-+     160,    /* OBJ_x509Crl                      1 2 840 113549 1 9 23 1 */
-+     144,    /* OBJ_pbe_WithSHA1And128BitRC4     1 2 840 113549 1 12 1 1 */
-+     145,    /* OBJ_pbe_WithSHA1And40BitRC4      1 2 840 113549 1 12 1 2 */
-+     146,    /* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */
-+     147,    /* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */
-+     148,    /* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */
-+     149,    /* OBJ_pbe_WithSHA1And40BitRC2_CBC  1 2 840 113549 1 12 1 6 */
-+     171,    /* OBJ_ms_ext_req                   1 3 6 1 4 1 311 2 1 14 */
-+     134,    /* OBJ_ms_code_ind                  1 3 6 1 4 1 311 2 1 21 */
-+     135,    /* OBJ_ms_code_com                  1 3 6 1 4 1 311 2 1 22 */
-+     136,    /* OBJ_ms_ctl_sign                  1 3 6 1 4 1 311 10 3 1 */
-+     137,    /* OBJ_ms_sgc                       1 3 6 1 4 1 311 10 3 3 */
-+     138,    /* OBJ_ms_efs                       1 3 6 1 4 1 311 10 3 4 */
-+     648,    /* OBJ_ms_smartcard_login           1 3 6 1 4 1 311 20 2 2 */
-+     649,    /* OBJ_ms_upn                       1 3 6 1 4 1 311 20 2 3 */
-+     951,    /* OBJ_ct_precert_scts              1 3 6 1 4 1 11129 2 4 2 */
-+     952,    /* OBJ_ct_precert_poison            1 3 6 1 4 1 11129 2 4 3 */
-+     953,    /* OBJ_ct_precert_signer            1 3 6 1 4 1 11129 2 4 4 */
-+     954,    /* OBJ_ct_cert_scts                 1 3 6 1 4 1 11129 2 4 5 */
-+     751,    /* OBJ_camellia_128_cbc             1 2 392 200011 61 1 1 1 2 */
-+     752,    /* OBJ_camellia_192_cbc             1 2 392 200011 61 1 1 1 3 */
-+     753,    /* OBJ_camellia_256_cbc             1 2 392 200011 61 1 1 1 4 */
-+     907,    /* OBJ_id_camellia128_wrap          1 2 392 200011 61 1 1 3 2 */
-+     908,    /* OBJ_id_camellia192_wrap          1 2 392 200011 61 1 1 3 3 */
-+     909,    /* OBJ_id_camellia256_wrap          1 2 392 200011 61 1 1 3 4 */
-+     196,    /* OBJ_id_smime_mod_cms             1 2 840 113549 1 9 16 0 1 */
-+     197,    /* OBJ_id_smime_mod_ess             1 2 840 113549 1 9 16 0 2 */
-+     198,    /* OBJ_id_smime_mod_oid             1 2 840 113549 1 9 16 0 3 */
-+     199,    /* OBJ_id_smime_mod_msg_v3          1 2 840 113549 1 9 16 0 4 */
-+     200,    /* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */
-+     201,    /* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */
-+     202,    /* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */
-+     203,    /* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */
-+     204,    /* OBJ_id_smime_ct_receipt          1 2 840 113549 1 9 16 1 1 */
-+     205,    /* OBJ_id_smime_ct_authData         1 2 840 113549 1 9 16 1 2 */
-+     206,    /* OBJ_id_smime_ct_publishCert      1 2 840 113549 1 9 16 1 3 */
-+     207,    /* OBJ_id_smime_ct_TSTInfo          1 2 840 113549 1 9 16 1 4 */
-+     208,    /* OBJ_id_smime_ct_TDTInfo          1 2 840 113549 1 9 16 1 5 */
-+     209,    /* OBJ_id_smime_ct_contentInfo      1 2 840 113549 1 9 16 1 6 */
-+     210,    /* OBJ_id_smime_ct_DVCSRequestData  1 2 840 113549 1 9 16 1 7 */
-+     211,    /* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */
-+     786,    /* OBJ_id_smime_ct_compressedData   1 2 840 113549 1 9 16 1 9 */
-+    1058,    /* OBJ_id_smime_ct_contentCollection 1 2 840 113549 1 9 16 1 19 */
-+    1059,    /* OBJ_id_smime_ct_authEnvelopedData 1 2 840 113549 1 9 16 1 23 */
-+     787,    /* OBJ_id_ct_asciiTextWithCRLF      1 2 840 113549 1 9 16 1 27 */
-+    1060,    /* OBJ_id_ct_xml                    1 2 840 113549 1 9 16 1 28 */
-+     212,    /* OBJ_id_smime_aa_receiptRequest   1 2 840 113549 1 9 16 2 1 */
-+     213,    /* OBJ_id_smime_aa_securityLabel    1 2 840 113549 1 9 16 2 2 */
-+     214,    /* OBJ_id_smime_aa_mlExpandHistory  1 2 840 113549 1 9 16 2 3 */
-+     215,    /* OBJ_id_smime_aa_contentHint      1 2 840 113549 1 9 16 2 4 */
-+     216,    /* OBJ_id_smime_aa_msgSigDigest     1 2 840 113549 1 9 16 2 5 */
-+     217,    /* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */
-+     218,    /* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */
-+     219,    /* OBJ_id_smime_aa_macValue         1 2 840 113549 1 9 16 2 8 */
-+     220,    /* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */
-+     221,    /* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */
-+     222,    /* OBJ_id_smime_aa_encrypKeyPref    1 2 840 113549 1 9 16 2 11 */
-+     223,    /* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */
-+     224,    /* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */
-+     225,    /* OBJ_id_smime_aa_timeStampToken   1 2 840 113549 1 9 16 2 14 */
-+     226,    /* OBJ_id_smime_aa_ets_sigPolicyId  1 2 840 113549 1 9 16 2 15 */
-+     227,    /* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */
-+     228,    /* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */
-+     229,    /* OBJ_id_smime_aa_ets_signerAttr   1 2 840 113549 1 9 16 2 18 */
-+     230,    /* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */
-+     231,    /* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */
-+     232,    /* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */
-+     233,    /* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */
-+     234,    /* OBJ_id_smime_aa_ets_certValues   1 2 840 113549 1 9 16 2 23 */
-+     235,    /* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */
-+     236,    /* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */
-+     237,    /* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */
-+     238,    /* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */
-+     239,    /* OBJ_id_smime_aa_signatureType    1 2 840 113549 1 9 16 2 28 */
-+     240,    /* OBJ_id_smime_aa_dvcs_dvc         1 2 840 113549 1 9 16 2 29 */
-+     241,    /* OBJ_id_smime_alg_ESDHwith3DES    1 2 840 113549 1 9 16 3 1 */
-+     242,    /* OBJ_id_smime_alg_ESDHwithRC2     1 2 840 113549 1 9 16 3 2 */
-+     243,    /* OBJ_id_smime_alg_3DESwrap        1 2 840 113549 1 9 16 3 3 */
-+     244,    /* OBJ_id_smime_alg_RC2wrap         1 2 840 113549 1 9 16 3 4 */
-+     245,    /* OBJ_id_smime_alg_ESDH            1 2 840 113549 1 9 16 3 5 */
-+     246,    /* OBJ_id_smime_alg_CMS3DESwrap     1 2 840 113549 1 9 16 3 6 */
-+     247,    /* OBJ_id_smime_alg_CMSRC2wrap      1 2 840 113549 1 9 16 3 7 */
-+     125,    /* OBJ_zlib_compression             1 2 840 113549 1 9 16 3 8 */
-+     893,    /* OBJ_id_alg_PWRI_KEK              1 2 840 113549 1 9 16 3 9 */
-+     248,    /* OBJ_id_smime_cd_ldap             1 2 840 113549 1 9 16 4 1 */
-+     249,    /* OBJ_id_smime_spq_ets_sqt_uri     1 2 840 113549 1 9 16 5 1 */
-+     250,    /* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */
-+     251,    /* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */
-+     252,    /* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */
-+     253,    /* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */
-+     254,    /* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */
-+     255,    /* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */
-+     256,    /* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */
-+     150,    /* OBJ_keyBag                       1 2 840 113549 1 12 10 1 1 */
-+     151,    /* OBJ_pkcs8ShroudedKeyBag          1 2 840 113549 1 12 10 1 2 */
-+     152,    /* OBJ_certBag                      1 2 840 113549 1 12 10 1 3 */
-+     153,    /* OBJ_crlBag                       1 2 840 113549 1 12 10 1 4 */
-+     154,    /* OBJ_secretBag                    1 2 840 113549 1 12 10 1 5 */
-+     155,    /* OBJ_safeContentsBag              1 2 840 113549 1 12 10 1 6 */
-+      34,    /* OBJ_idea_cbc                     1 3 6 1 4 1 188 7 1 1 2 */
-+     955,    /* OBJ_jurisdictionLocalityName     1 3 6 1 4 1 311 60 2 1 1 */
-+     956,    /* OBJ_jurisdictionStateOrProvinceName 1 3 6 1 4 1 311 60 2 1 2 */
-+     957,    /* OBJ_jurisdictionCountryName      1 3 6 1 4 1 311 60 2 1 3 */
-+    1056,    /* OBJ_blake2b512                   1 3 6 1 4 1 1722 12 2 1 16 */
-+    1057,    /* OBJ_blake2s256                   1 3 6 1 4 1 1722 12 2 2 8 */
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.pl
-new file mode 100644
-index 0000000..1cb3d1c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_dat.pl
-@@ -0,0 +1,227 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+use integer;
-+use strict;
-+use warnings;
-+
-+# Generate the DER encoding for the given OID.
-+sub der_it
-+{
-+    # Prologue
-+    my ($v) = @_;
-+    my @a = split(/\s+/, $v);
-+    my $ret = pack("C*", $a[0] * 40 + $a[1]);
-+    shift @a;
-+    shift @a;
-+
-+    # Loop over rest of bytes; or in 0x80 for multi-byte numbers.
-+    my $t;
-+    foreach (@a) {
-+        my @r = ();
-+        $t = 0;
-+        while ($_ >= 128) {
-+            my $x = $_ % 128;
-+            $_ /= 128;
-+            push(@r, ($t++ ? 0x80 : 0) | $x);
-+        }
-+        push(@r, ($t++ ? 0x80 : 0) | $_);
-+        $ret .= pack("C*", reverse(@r));
-+    }
-+    return $ret;
-+}
-+
-+
-+# Read input, parse all #define's into OID name and value.
-+# Populate %ln and %sn with long and short names (%dupln and %dupsn)
-+# are used to watch for duplicates.  Also %nid and %obj get the
-+# NID and OBJ entries.
-+my %ln;
-+my %sn;
-+my %dupln;
-+my %dupsn;
-+my %nid;
-+my %obj;
-+my %objd;
-+open(IN, "$ARGV[0]") || die "Can't open input file $ARGV[0], $!";
-+while () {
-+    next unless /^\#define\s+(\S+)\s+(.*)$/;
-+    my $v = $1;
-+    my $d = $2;
-+    $d =~ s/^\"//;
-+    $d =~ s/\"$//;
-+    if ($v =~ /^SN_(.*)$/) {
-+        if (defined $dupsn{$d}) {
-+            print "WARNING: Duplicate short name \"$d\"\n";
-+        } else {
-+            $dupsn{$d} = 1;
-+        }
-+        $sn{$1} = $d;
-+    }
-+    elsif ($v =~ /^LN_(.*)$/) {
-+        if (defined $dupln{$d}) {
-+            print "WARNING: Duplicate long name \"$d\"\n";
-+        } else {
-+            $dupln{$d} = 1;
-+        }
-+        $ln{$1} = $d;
-+    }
-+    elsif ($v =~ /^NID_(.*)$/) {
-+        $nid{$d} = $1;
-+    }
-+    elsif ($v =~ /^OBJ_(.*)$/) {
-+        $obj{$1} = $v;
-+        $objd{$v} = $d;
-+    }
-+}
-+close IN;
-+
-+# For every value in %obj, recursively expand OBJ_xxx values.  That is:
-+#     #define OBJ_iso 1L
-+#     #define OBJ_identified_organization OBJ_iso,3L
-+# Modify %objd values in-place.  Create an %objn array that has
-+my $changed;
-+do {
-+    $changed = 0;
-+    foreach my $k (keys %objd) {
-+        $changed = 1 if $objd{$k} =~ s/(OBJ_[^,]+),/$objd{$1},/;
-+    }
-+} while ($changed);
-+
-+my @a = sort { $a <=> $b } keys %nid;
-+my $n = $a[$#a] + 1;
-+my @lvalues = ();
-+my $lvalues = 0;
-+
-+# Scan all defined objects, building up the @out array.
-+# %obj_der holds the DER encoding as an array of bytes, and %obj_len
-+# holds the length in bytes.
-+my @out;
-+my %obj_der;
-+my %obj_len;
-+for (my $i = 0; $i < $n; $i++) {
-+    if (!defined $nid{$i}) {
-+        push(@out, "    { NULL, NULL, NID_undef },\n");
-+        next;
-+    }
-+
-+    my $sn = defined $sn{$nid{$i}} ? "$sn{$nid{$i}}" : "NULL";
-+    my $ln = defined $ln{$nid{$i}} ? "$ln{$nid{$i}}" : "NULL";
-+    if ($sn eq "NULL") {
-+        $sn = $ln;
-+        $sn{$nid{$i}} = $ln;
-+    }
-+    if ($ln eq "NULL") {
-+        $ln = $sn;
-+        $ln{$nid{$i}} = $sn;
-+    }
-+
-+    my $out = "    {\"$sn\", \"$ln\", NID_$nid{$i}";
-+    if (defined $obj{$nid{$i}} && $objd{$obj{$nid{$i}}} =~ /,/) {
-+        my $v = $objd{$obj{$nid{$i}}};
-+        $v =~ s/L//g;
-+        $v =~ s/,/ /g;
-+        my $r = &der_it($v);
-+        my $z = "";
-+        my $length = 0;
-+        # Format using fixed-with because we use strcmp later.
-+        foreach (unpack("C*",$r)) {
-+            $z .= sprintf("0x%02X,", $_);
-+            $length++;
-+        }
-+        $obj_der{$obj{$nid{$i}}} = $z;
-+        $obj_len{$obj{$nid{$i}}} = $length;
-+
-+        push(@lvalues,
-+            sprintf("    %-45s  /* [%5d] %s */\n",
-+                $z, $lvalues, $obj{$nid{$i}}));
-+        $out .= ", $length, &so[$lvalues]";
-+        $lvalues += $length;
-+    }
-+    $out .= "},\n";
-+    push(@out, $out);
-+}
-+
-+# Finally ready to generate the output.
-+open(OUT, ">$ARGV[1]") || die "Can't open output file $ARGV[1], $!";
-+print OUT <<'EOF';
-+/*
-+ * WARNING: do not edit!
-+ * Generated by crypto/objects/obj_dat.pl
-+ *
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+EOF
-+
-+print OUT "/* Serialized OID's */\n";
-+printf OUT "static const unsigned char so[%d] = {\n", $lvalues + 1;
-+print OUT @lvalues;
-+print OUT "};\n\n";
-+
-+printf OUT "#define NUM_NID %d\n", $n;
-+printf OUT "static const ASN1_OBJECT nid_objs[NUM_NID] = {\n";
-+print OUT @out;
-+print  OUT "};\n\n";
-+
-+{
-+    no warnings "uninitialized";
-+    @a = grep(defined $sn{$nid{$_}}, 0 .. $n);
-+}
-+printf OUT "#define NUM_SN %d\n", $#a + 1;
-+printf OUT "static const unsigned int sn_objs[NUM_SN] = {\n";
-+foreach (sort { $sn{$nid{$a}} cmp $sn{$nid{$b}} } @a) {
-+    printf OUT "    %4d,    /* \"$sn{$nid{$_}}\" */\n", $_;
-+}
-+print  OUT "};\n\n";
-+
-+{
-+    no warnings "uninitialized";
-+    @a = grep(defined $ln{$nid{$_}}, 0 .. $n);
-+}
-+printf OUT "#define NUM_LN %d\n", $#a + 1;
-+printf OUT "static const unsigned int ln_objs[NUM_LN] = {\n";
-+foreach (sort { $ln{$nid{$a}} cmp $ln{$nid{$b}} } @a) {
-+    printf OUT "    %4d,    /* \"$ln{$nid{$_}}\" */\n", $_;
-+}
-+print  OUT "};\n\n";
-+
-+{
-+    no warnings "uninitialized";
-+    @a = grep(defined $obj{$nid{$_}}, 0 .. $n);
-+}
-+printf OUT "#define NUM_OBJ %d\n", $#a + 1;
-+printf OUT "static const unsigned int obj_objs[NUM_OBJ] = {\n";
-+
-+# Compare DER; prefer shorter; if some length, use the "smaller" encoding.
-+sub obj_cmp
-+{
-+    no warnings "uninitialized";
-+    my $A = $obj_len{$obj{$nid{$a}}};
-+    my $B = $obj_len{$obj{$nid{$b}}};
-+    my $r = $A - $B;
-+    return $r if $r != 0;
-+
-+    $A = $obj_der{$obj{$nid{$a}}};
-+    $B = $obj_der{$obj{$nid{$b}}};
-+    return $A cmp $B;
-+}
-+foreach (sort obj_cmp @a) {
-+    my $m = $obj{$nid{$_}};
-+    my $v = $objd{$m};
-+    $v =~ s/L//g;
-+    $v =~ s/,/ /g;
-+    printf OUT "    %4d,    /* %-32s %s */\n", $_, $m, $v;
-+}
-+print  OUT "};\n";
-+
-+close OUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_err.c
-new file mode 100644
-index 0000000..4677b67
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_err.c
-@@ -0,0 +1,50 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OBJ,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OBJ,0,reason)
-+
-+static ERR_STRING_DATA OBJ_str_functs[] = {
-+    {ERR_FUNC(OBJ_F_OBJ_ADD_OBJECT), "OBJ_add_object"},
-+    {ERR_FUNC(OBJ_F_OBJ_CREATE), "OBJ_create"},
-+    {ERR_FUNC(OBJ_F_OBJ_DUP), "OBJ_dup"},
-+    {ERR_FUNC(OBJ_F_OBJ_NAME_NEW_INDEX), "OBJ_NAME_new_index"},
-+    {ERR_FUNC(OBJ_F_OBJ_NID2LN), "OBJ_nid2ln"},
-+    {ERR_FUNC(OBJ_F_OBJ_NID2OBJ), "OBJ_nid2obj"},
-+    {ERR_FUNC(OBJ_F_OBJ_NID2SN), "OBJ_nid2sn"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA OBJ_str_reasons[] = {
-+    {ERR_REASON(OBJ_R_OID_EXISTS), "oid exists"},
-+    {ERR_REASON(OBJ_R_UNKNOWN_NID), "unknown nid"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_OBJ_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, OBJ_str_functs);
-+        ERR_load_strings(0, OBJ_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_lcl.h
-new file mode 100644
-index 0000000..a417f7c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_lcl.h
-@@ -0,0 +1,14 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+typedef struct name_funcs_st NAME_FUNCS;
-+DEFINE_STACK_OF(NAME_FUNCS)
-+DEFINE_LHASH_OF(OBJ_NAME);
-+typedef struct added_obj_st ADDED_OBJ;
-+DEFINE_LHASH_OF(ADDED_OBJ);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_lib.c
-new file mode 100644
-index 0000000..33075e6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_lib.c
-@@ -0,0 +1,66 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+
-+ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o)
-+{
-+    ASN1_OBJECT *r;
-+
-+    if (o == NULL)
-+        return NULL;
-+    /* If object isn't dynamic it's an internal OID which is never freed */
-+    if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC))
-+        return ((ASN1_OBJECT *)o);
-+
-+    r = ASN1_OBJECT_new();
-+    if (r == NULL) {
-+        OBJerr(OBJ_F_OBJ_DUP, ERR_R_ASN1_LIB);
-+        return (NULL);
-+    }
-+
-+    /* Set dynamic flags so everything gets freed up on error */
-+
-+    r->flags = o->flags | (ASN1_OBJECT_FLAG_DYNAMIC |
-+                           ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
-+                           ASN1_OBJECT_FLAG_DYNAMIC_DATA);
-+
-+    if (o->length > 0 && (r->data = OPENSSL_memdup(o->data, o->length)) == NULL)
-+        goto err;
-+
-+    r->length = o->length;
-+    r->nid = o->nid;
-+
-+    if (o->ln != NULL && (r->ln = OPENSSL_strdup(o->ln)) == NULL)
-+        goto err;
-+
-+    if (o->sn != NULL && (r->sn = OPENSSL_strdup(o->sn)) == NULL)
-+        goto err;
-+
-+    return r;
-+ err:
-+    ASN1_OBJECT_free(r);
-+    OBJerr(OBJ_F_OBJ_DUP, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b)
-+{
-+    int ret;
-+
-+    ret = (a->length - b->length);
-+    if (ret)
-+        return (ret);
-+    return (memcmp(a->data, b->data, a->length));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_mac.num b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_mac.num
-new file mode 100644
-index 0000000..a5995a5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_mac.num
-@@ -0,0 +1,1060 @@
-+undef		0
-+rsadsi		1
-+pkcs		2
-+md2		3
-+md5		4
-+rc4		5
-+rsaEncryption		6
-+md2WithRSAEncryption		7
-+md5WithRSAEncryption		8
-+pbeWithMD2AndDES_CBC		9
-+pbeWithMD5AndDES_CBC		10
-+X500		11
-+X509		12
-+commonName		13
-+countryName		14
-+localityName		15
-+stateOrProvinceName		16
-+organizationName		17
-+organizationalUnitName		18
-+rsa		19
-+pkcs7		20
-+pkcs7_data		21
-+pkcs7_signed		22
-+pkcs7_enveloped		23
-+pkcs7_signedAndEnveloped		24
-+pkcs7_digest		25
-+pkcs7_encrypted		26
-+pkcs3		27
-+dhKeyAgreement		28
-+des_ecb		29
-+des_cfb64		30
-+des_cbc		31
-+des_ede_ecb		32
-+des_ede3_ecb		33
-+idea_cbc		34
-+idea_cfb64		35
-+idea_ecb		36
-+rc2_cbc		37
-+rc2_ecb		38
-+rc2_cfb64		39
-+rc2_ofb64		40
-+sha		41
-+shaWithRSAEncryption		42
-+des_ede_cbc		43
-+des_ede3_cbc		44
-+des_ofb64		45
-+idea_ofb64		46
-+pkcs9		47
-+pkcs9_emailAddress		48
-+pkcs9_unstructuredName		49
-+pkcs9_contentType		50
-+pkcs9_messageDigest		51
-+pkcs9_signingTime		52
-+pkcs9_countersignature		53
-+pkcs9_challengePassword		54
-+pkcs9_unstructuredAddress		55
-+pkcs9_extCertAttributes		56
-+netscape		57
-+netscape_cert_extension		58
-+netscape_data_type		59
-+des_ede_cfb64		60
-+des_ede3_cfb64		61
-+des_ede_ofb64		62
-+des_ede3_ofb64		63
-+sha1		64
-+sha1WithRSAEncryption		65
-+dsaWithSHA		66
-+dsa_2		67
-+pbeWithSHA1AndRC2_CBC		68
-+id_pbkdf2		69
-+dsaWithSHA1_2		70
-+netscape_cert_type		71
-+netscape_base_url		72
-+netscape_revocation_url		73
-+netscape_ca_revocation_url		74
-+netscape_renewal_url		75
-+netscape_ca_policy_url		76
-+netscape_ssl_server_name		77
-+netscape_comment		78
-+netscape_cert_sequence		79
-+desx_cbc		80
-+id_ce		81
-+subject_key_identifier		82
-+key_usage		83
-+private_key_usage_period		84
-+subject_alt_name		85
-+issuer_alt_name		86
-+basic_constraints		87
-+crl_number		88
-+certificate_policies		89
-+authority_key_identifier		90
-+bf_cbc		91
-+bf_ecb		92
-+bf_cfb64		93
-+bf_ofb64		94
-+mdc2		95
-+mdc2WithRSA		96
-+rc4_40		97
-+rc2_40_cbc		98
-+givenName		99
-+surname		100
-+initials		101
-+uniqueIdentifier		102
-+crl_distribution_points		103
-+md5WithRSA		104
-+serialNumber		105
-+title		106
-+description		107
-+cast5_cbc		108
-+cast5_ecb		109
-+cast5_cfb64		110
-+cast5_ofb64		111
-+pbeWithMD5AndCast5_CBC		112
-+dsaWithSHA1		113
-+md5_sha1		114
-+sha1WithRSA		115
-+dsa		116
-+ripemd160		117
-+ripemd160WithRSA		119
-+rc5_cbc		120
-+rc5_ecb		121
-+rc5_cfb64		122
-+rc5_ofb64		123
-+rle_compression		124
-+zlib_compression		125
-+ext_key_usage		126
-+id_pkix		127
-+id_kp		128
-+server_auth		129
-+client_auth		130
-+code_sign		131
-+email_protect		132
-+time_stamp		133
-+ms_code_ind		134
-+ms_code_com		135
-+ms_ctl_sign		136
-+ms_sgc		137
-+ms_efs		138
-+ns_sgc		139
-+delta_crl		140
-+crl_reason		141
-+invalidity_date		142
-+sxnet		143
-+pbe_WithSHA1And128BitRC4		144
-+pbe_WithSHA1And40BitRC4		145
-+pbe_WithSHA1And3_Key_TripleDES_CBC		146
-+pbe_WithSHA1And2_Key_TripleDES_CBC		147
-+pbe_WithSHA1And128BitRC2_CBC		148
-+pbe_WithSHA1And40BitRC2_CBC		149
-+keyBag		150
-+pkcs8ShroudedKeyBag		151
-+certBag		152
-+crlBag		153
-+secretBag		154
-+safeContentsBag		155
-+friendlyName		156
-+localKeyID		157
-+x509Certificate		158
-+sdsiCertificate		159
-+x509Crl		160
-+pbes2		161
-+pbmac1		162
-+hmacWithSHA1		163
-+id_qt_cps		164
-+id_qt_unotice		165
-+rc2_64_cbc		166
-+SMIMECapabilities		167
-+pbeWithMD2AndRC2_CBC		168
-+pbeWithMD5AndRC2_CBC		169
-+pbeWithSHA1AndDES_CBC		170
-+ms_ext_req		171
-+ext_req		172
-+name		173
-+dnQualifier		174
-+id_pe		175
-+id_ad		176
-+info_access		177
-+ad_OCSP		178
-+ad_ca_issuers		179
-+OCSP_sign		180
-+iso		181
-+member_body		182
-+ISO_US		183
-+X9_57		184
-+X9cm		185
-+pkcs1		186
-+pkcs5		187
-+SMIME		188
-+id_smime_mod		189
-+id_smime_ct		190
-+id_smime_aa		191
-+id_smime_alg		192
-+id_smime_cd		193
-+id_smime_spq		194
-+id_smime_cti		195
-+id_smime_mod_cms		196
-+id_smime_mod_ess		197
-+id_smime_mod_oid		198
-+id_smime_mod_msg_v3		199
-+id_smime_mod_ets_eSignature_88		200
-+id_smime_mod_ets_eSignature_97		201
-+id_smime_mod_ets_eSigPolicy_88		202
-+id_smime_mod_ets_eSigPolicy_97		203
-+id_smime_ct_receipt		204
-+id_smime_ct_authData		205
-+id_smime_ct_publishCert		206
-+id_smime_ct_TSTInfo		207
-+id_smime_ct_TDTInfo		208
-+id_smime_ct_contentInfo		209
-+id_smime_ct_DVCSRequestData		210
-+id_smime_ct_DVCSResponseData		211
-+id_smime_aa_receiptRequest		212
-+id_smime_aa_securityLabel		213
-+id_smime_aa_mlExpandHistory		214
-+id_smime_aa_contentHint		215
-+id_smime_aa_msgSigDigest		216
-+id_smime_aa_encapContentType		217
-+id_smime_aa_contentIdentifier		218
-+id_smime_aa_macValue		219
-+id_smime_aa_equivalentLabels		220
-+id_smime_aa_contentReference		221
-+id_smime_aa_encrypKeyPref		222
-+id_smime_aa_signingCertificate		223
-+id_smime_aa_smimeEncryptCerts		224
-+id_smime_aa_timeStampToken		225
-+id_smime_aa_ets_sigPolicyId		226
-+id_smime_aa_ets_commitmentType		227
-+id_smime_aa_ets_signerLocation		228
-+id_smime_aa_ets_signerAttr		229
-+id_smime_aa_ets_otherSigCert		230
-+id_smime_aa_ets_contentTimestamp		231
-+id_smime_aa_ets_CertificateRefs		232
-+id_smime_aa_ets_RevocationRefs		233
-+id_smime_aa_ets_certValues		234
-+id_smime_aa_ets_revocationValues		235
-+id_smime_aa_ets_escTimeStamp		236
-+id_smime_aa_ets_certCRLTimestamp		237
-+id_smime_aa_ets_archiveTimeStamp		238
-+id_smime_aa_signatureType		239
-+id_smime_aa_dvcs_dvc		240
-+id_smime_alg_ESDHwith3DES		241
-+id_smime_alg_ESDHwithRC2		242
-+id_smime_alg_3DESwrap		243
-+id_smime_alg_RC2wrap		244
-+id_smime_alg_ESDH		245
-+id_smime_alg_CMS3DESwrap		246
-+id_smime_alg_CMSRC2wrap		247
-+id_smime_cd_ldap		248
-+id_smime_spq_ets_sqt_uri		249
-+id_smime_spq_ets_sqt_unotice		250
-+id_smime_cti_ets_proofOfOrigin		251
-+id_smime_cti_ets_proofOfReceipt		252
-+id_smime_cti_ets_proofOfDelivery		253
-+id_smime_cti_ets_proofOfSender		254
-+id_smime_cti_ets_proofOfApproval		255
-+id_smime_cti_ets_proofOfCreation		256
-+md4		257
-+id_pkix_mod		258
-+id_qt		259
-+id_it		260
-+id_pkip		261
-+id_alg		262
-+id_cmc		263
-+id_on		264
-+id_pda		265
-+id_aca		266
-+id_qcs		267
-+id_cct		268
-+id_pkix1_explicit_88		269
-+id_pkix1_implicit_88		270
-+id_pkix1_explicit_93		271
-+id_pkix1_implicit_93		272
-+id_mod_crmf		273
-+id_mod_cmc		274
-+id_mod_kea_profile_88		275
-+id_mod_kea_profile_93		276
-+id_mod_cmp		277
-+id_mod_qualified_cert_88		278
-+id_mod_qualified_cert_93		279
-+id_mod_attribute_cert		280
-+id_mod_timestamp_protocol		281
-+id_mod_ocsp		282
-+id_mod_dvcs		283
-+id_mod_cmp2000		284
-+biometricInfo		285
-+qcStatements		286
-+ac_auditEntity		287
-+ac_targeting		288
-+aaControls		289
-+sbgp_ipAddrBlock		290
-+sbgp_autonomousSysNum		291
-+sbgp_routerIdentifier		292
-+textNotice		293
-+ipsecEndSystem		294
-+ipsecTunnel		295
-+ipsecUser		296
-+dvcs		297
-+id_it_caProtEncCert		298
-+id_it_signKeyPairTypes		299
-+id_it_encKeyPairTypes		300
-+id_it_preferredSymmAlg		301
-+id_it_caKeyUpdateInfo		302
-+id_it_currentCRL		303
-+id_it_unsupportedOIDs		304
-+id_it_subscriptionRequest		305
-+id_it_subscriptionResponse		306
-+id_it_keyPairParamReq		307
-+id_it_keyPairParamRep		308
-+id_it_revPassphrase		309
-+id_it_implicitConfirm		310
-+id_it_confirmWaitTime		311
-+id_it_origPKIMessage		312
-+id_regCtrl		313
-+id_regInfo		314
-+id_regCtrl_regToken		315
-+id_regCtrl_authenticator		316
-+id_regCtrl_pkiPublicationInfo		317
-+id_regCtrl_pkiArchiveOptions		318
-+id_regCtrl_oldCertID		319
-+id_regCtrl_protocolEncrKey		320
-+id_regInfo_utf8Pairs		321
-+id_regInfo_certReq		322
-+id_alg_des40		323
-+id_alg_noSignature		324
-+id_alg_dh_sig_hmac_sha1		325
-+id_alg_dh_pop		326
-+id_cmc_statusInfo		327
-+id_cmc_identification		328
-+id_cmc_identityProof		329
-+id_cmc_dataReturn		330
-+id_cmc_transactionId		331
-+id_cmc_senderNonce		332
-+id_cmc_recipientNonce		333
-+id_cmc_addExtensions		334
-+id_cmc_encryptedPOP		335
-+id_cmc_decryptedPOP		336
-+id_cmc_lraPOPWitness		337
-+id_cmc_getCert		338
-+id_cmc_getCRL		339
-+id_cmc_revokeRequest		340
-+id_cmc_regInfo		341
-+id_cmc_responseInfo		342
-+id_cmc_queryPending		343
-+id_cmc_popLinkRandom		344
-+id_cmc_popLinkWitness		345
-+id_cmc_confirmCertAcceptance		346
-+id_on_personalData		347
-+id_pda_dateOfBirth		348
-+id_pda_placeOfBirth		349
-+id_pda_pseudonym		350
-+id_pda_gender		351
-+id_pda_countryOfCitizenship		352
-+id_pda_countryOfResidence		353
-+id_aca_authenticationInfo		354
-+id_aca_accessIdentity		355
-+id_aca_chargingIdentity		356
-+id_aca_group		357
-+id_aca_role		358
-+id_qcs_pkixQCSyntax_v1		359
-+id_cct_crs		360
-+id_cct_PKIData		361
-+id_cct_PKIResponse		362
-+ad_timeStamping		363
-+ad_dvcs		364
-+id_pkix_OCSP_basic		365
-+id_pkix_OCSP_Nonce		366
-+id_pkix_OCSP_CrlID		367
-+id_pkix_OCSP_acceptableResponses		368
-+id_pkix_OCSP_noCheck		369
-+id_pkix_OCSP_archiveCutoff		370
-+id_pkix_OCSP_serviceLocator		371
-+id_pkix_OCSP_extendedStatus		372
-+id_pkix_OCSP_valid		373
-+id_pkix_OCSP_path		374
-+id_pkix_OCSP_trustRoot		375
-+algorithm		376
-+rsaSignature		377
-+X500algorithms		378
-+org		379
-+dod		380
-+iana		381
-+Directory		382
-+Management		383
-+Experimental		384
-+Private		385
-+Security		386
-+SNMPv2		387
-+Mail		388
-+Enterprises		389
-+dcObject		390
-+domainComponent		391
-+Domain		392
-+joint_iso_ccitt		393
-+selected_attribute_types		394
-+clearance		395
-+md4WithRSAEncryption		396
-+ac_proxying		397
-+sinfo_access		398
-+id_aca_encAttrs		399
-+role		400
-+policy_constraints		401
-+target_information		402
-+no_rev_avail		403
-+ccitt		404
-+ansi_X9_62		405
-+X9_62_prime_field		406
-+X9_62_characteristic_two_field		407
-+X9_62_id_ecPublicKey		408
-+X9_62_prime192v1		409
-+X9_62_prime192v2		410
-+X9_62_prime192v3		411
-+X9_62_prime239v1		412
-+X9_62_prime239v2		413
-+X9_62_prime239v3		414
-+X9_62_prime256v1		415
-+ecdsa_with_SHA1		416
-+ms_csp_name		417
-+aes_128_ecb		418
-+aes_128_cbc		419
-+aes_128_ofb128		420
-+aes_128_cfb128		421
-+aes_192_ecb		422
-+aes_192_cbc		423
-+aes_192_ofb128		424
-+aes_192_cfb128		425
-+aes_256_ecb		426
-+aes_256_cbc		427
-+aes_256_ofb128		428
-+aes_256_cfb128		429
-+hold_instruction_code		430
-+hold_instruction_none		431
-+hold_instruction_call_issuer		432
-+hold_instruction_reject		433
-+data		434
-+pss		435
-+ucl		436
-+pilot		437
-+pilotAttributeType		438
-+pilotAttributeSyntax		439
-+pilotObjectClass		440
-+pilotGroups		441
-+iA5StringSyntax		442
-+caseIgnoreIA5StringSyntax		443
-+pilotObject		444
-+pilotPerson		445
-+account		446
-+document		447
-+room		448
-+documentSeries		449
-+rFC822localPart		450
-+dNSDomain		451
-+domainRelatedObject		452
-+friendlyCountry		453
-+simpleSecurityObject		454
-+pilotOrganization		455
-+pilotDSA		456
-+qualityLabelledData		457
-+userId		458
-+textEncodedORAddress		459
-+rfc822Mailbox		460
-+info		461
-+favouriteDrink		462
-+roomNumber		463
-+photo		464
-+userClass		465
-+host		466
-+manager		467
-+documentIdentifier		468
-+documentTitle		469
-+documentVersion		470
-+documentAuthor		471
-+documentLocation		472
-+homeTelephoneNumber		473
-+secretary		474
-+otherMailbox		475
-+lastModifiedTime		476
-+lastModifiedBy		477
-+aRecord		478
-+pilotAttributeType27		479
-+mXRecord		480
-+nSRecord		481
-+sOARecord		482
-+cNAMERecord		483
-+associatedDomain		484
-+associatedName		485
-+homePostalAddress		486
-+personalTitle		487
-+mobileTelephoneNumber		488
-+pagerTelephoneNumber		489
-+friendlyCountryName		490
-+organizationalStatus		491
-+janetMailbox		492
-+mailPreferenceOption		493
-+buildingName		494
-+dSAQuality		495
-+singleLevelQuality		496
-+subtreeMinimumQuality		497
-+subtreeMaximumQuality		498
-+personalSignature		499
-+dITRedirect		500
-+audio		501
-+documentPublisher		502
-+x500UniqueIdentifier		503
-+mime_mhs		504
-+mime_mhs_headings		505
-+mime_mhs_bodies		506
-+id_hex_partial_message		507
-+id_hex_multipart_message		508
-+generationQualifier		509
-+pseudonym		510
-+InternationalRA		511
-+id_set		512
-+set_ctype		513
-+set_msgExt		514
-+set_attr		515
-+set_policy		516
-+set_certExt		517
-+set_brand		518
-+setct_PANData		519
-+setct_PANToken		520
-+setct_PANOnly		521
-+setct_OIData		522
-+setct_PI		523
-+setct_PIData		524
-+setct_PIDataUnsigned		525
-+setct_HODInput		526
-+setct_AuthResBaggage		527
-+setct_AuthRevReqBaggage		528
-+setct_AuthRevResBaggage		529
-+setct_CapTokenSeq		530
-+setct_PInitResData		531
-+setct_PI_TBS		532
-+setct_PResData		533
-+setct_AuthReqTBS		534
-+setct_AuthResTBS		535
-+setct_AuthResTBSX		536
-+setct_AuthTokenTBS		537
-+setct_CapTokenData		538
-+setct_CapTokenTBS		539
-+setct_AcqCardCodeMsg		540
-+setct_AuthRevReqTBS		541
-+setct_AuthRevResData		542
-+setct_AuthRevResTBS		543
-+setct_CapReqTBS		544
-+setct_CapReqTBSX		545
-+setct_CapResData		546
-+setct_CapRevReqTBS		547
-+setct_CapRevReqTBSX		548
-+setct_CapRevResData		549
-+setct_CredReqTBS		550
-+setct_CredReqTBSX		551
-+setct_CredResData		552
-+setct_CredRevReqTBS		553
-+setct_CredRevReqTBSX		554
-+setct_CredRevResData		555
-+setct_PCertReqData		556
-+setct_PCertResTBS		557
-+setct_BatchAdminReqData		558
-+setct_BatchAdminResData		559
-+setct_CardCInitResTBS		560
-+setct_MeAqCInitResTBS		561
-+setct_RegFormResTBS		562
-+setct_CertReqData		563
-+setct_CertReqTBS		564
-+setct_CertResData		565
-+setct_CertInqReqTBS		566
-+setct_ErrorTBS		567
-+setct_PIDualSignedTBE		568
-+setct_PIUnsignedTBE		569
-+setct_AuthReqTBE		570
-+setct_AuthResTBE		571
-+setct_AuthResTBEX		572
-+setct_AuthTokenTBE		573
-+setct_CapTokenTBE		574
-+setct_CapTokenTBEX		575
-+setct_AcqCardCodeMsgTBE		576
-+setct_AuthRevReqTBE		577
-+setct_AuthRevResTBE		578
-+setct_AuthRevResTBEB		579
-+setct_CapReqTBE		580
-+setct_CapReqTBEX		581
-+setct_CapResTBE		582
-+setct_CapRevReqTBE		583
-+setct_CapRevReqTBEX		584
-+setct_CapRevResTBE		585
-+setct_CredReqTBE		586
-+setct_CredReqTBEX		587
-+setct_CredResTBE		588
-+setct_CredRevReqTBE		589
-+setct_CredRevReqTBEX		590
-+setct_CredRevResTBE		591
-+setct_BatchAdminReqTBE		592
-+setct_BatchAdminResTBE		593
-+setct_RegFormReqTBE		594
-+setct_CertReqTBE		595
-+setct_CertReqTBEX		596
-+setct_CertResTBE		597
-+setct_CRLNotificationTBS		598
-+setct_CRLNotificationResTBS		599
-+setct_BCIDistributionTBS		600
-+setext_genCrypt		601
-+setext_miAuth		602
-+setext_pinSecure		603
-+setext_pinAny		604
-+setext_track2		605
-+setext_cv		606
-+set_policy_root		607
-+setCext_hashedRoot		608
-+setCext_certType		609
-+setCext_merchData		610
-+setCext_cCertRequired		611
-+setCext_tunneling		612
-+setCext_setExt		613
-+setCext_setQualf		614
-+setCext_PGWYcapabilities		615
-+setCext_TokenIdentifier		616
-+setCext_Track2Data		617
-+setCext_TokenType		618
-+setCext_IssuerCapabilities		619
-+setAttr_Cert		620
-+setAttr_PGWYcap		621
-+setAttr_TokenType		622
-+setAttr_IssCap		623
-+set_rootKeyThumb		624
-+set_addPolicy		625
-+setAttr_Token_EMV		626
-+setAttr_Token_B0Prime		627
-+setAttr_IssCap_CVM		628
-+setAttr_IssCap_T2		629
-+setAttr_IssCap_Sig		630
-+setAttr_GenCryptgrm		631
-+setAttr_T2Enc		632
-+setAttr_T2cleartxt		633
-+setAttr_TokICCsig		634
-+setAttr_SecDevSig		635
-+set_brand_IATA_ATA		636
-+set_brand_Diners		637
-+set_brand_AmericanExpress		638
-+set_brand_JCB		639
-+set_brand_Visa		640
-+set_brand_MasterCard		641
-+set_brand_Novus		642
-+des_cdmf		643
-+rsaOAEPEncryptionSET		644
-+itu_t		645
-+joint_iso_itu_t		646
-+international_organizations		647
-+ms_smartcard_login		648
-+ms_upn		649
-+aes_128_cfb1		650
-+aes_192_cfb1		651
-+aes_256_cfb1		652
-+aes_128_cfb8		653
-+aes_192_cfb8		654
-+aes_256_cfb8		655
-+des_cfb1		656
-+des_cfb8		657
-+des_ede3_cfb1		658
-+des_ede3_cfb8		659
-+streetAddress		660
-+postalCode		661
-+id_ppl		662
-+proxyCertInfo		663
-+id_ppl_anyLanguage		664
-+id_ppl_inheritAll		665
-+name_constraints		666
-+Independent		667
-+sha256WithRSAEncryption		668
-+sha384WithRSAEncryption		669
-+sha512WithRSAEncryption		670
-+sha224WithRSAEncryption		671
-+sha256		672
-+sha384		673
-+sha512		674
-+sha224		675
-+identified_organization		676
-+certicom_arc		677
-+wap		678
-+wap_wsg		679
-+X9_62_id_characteristic_two_basis		680
-+X9_62_onBasis		681
-+X9_62_tpBasis		682
-+X9_62_ppBasis		683
-+X9_62_c2pnb163v1		684
-+X9_62_c2pnb163v2		685
-+X9_62_c2pnb163v3		686
-+X9_62_c2pnb176v1		687
-+X9_62_c2tnb191v1		688
-+X9_62_c2tnb191v2		689
-+X9_62_c2tnb191v3		690
-+X9_62_c2onb191v4		691
-+X9_62_c2onb191v5		692
-+X9_62_c2pnb208w1		693
-+X9_62_c2tnb239v1		694
-+X9_62_c2tnb239v2		695
-+X9_62_c2tnb239v3		696
-+X9_62_c2onb239v4		697
-+X9_62_c2onb239v5		698
-+X9_62_c2pnb272w1		699
-+X9_62_c2pnb304w1		700
-+X9_62_c2tnb359v1		701
-+X9_62_c2pnb368w1		702
-+X9_62_c2tnb431r1		703
-+secp112r1		704
-+secp112r2		705
-+secp128r1		706
-+secp128r2		707
-+secp160k1		708
-+secp160r1		709
-+secp160r2		710
-+secp192k1		711
-+secp224k1		712
-+secp224r1		713
-+secp256k1		714
-+secp384r1		715
-+secp521r1		716
-+sect113r1		717
-+sect113r2		718
-+sect131r1		719
-+sect131r2		720
-+sect163k1		721
-+sect163r1		722
-+sect163r2		723
-+sect193r1		724
-+sect193r2		725
-+sect233k1		726
-+sect233r1		727
-+sect239k1		728
-+sect283k1		729
-+sect283r1		730
-+sect409k1		731
-+sect409r1		732
-+sect571k1		733
-+sect571r1		734
-+wap_wsg_idm_ecid_wtls1		735
-+wap_wsg_idm_ecid_wtls3		736
-+wap_wsg_idm_ecid_wtls4		737
-+wap_wsg_idm_ecid_wtls5		738
-+wap_wsg_idm_ecid_wtls6		739
-+wap_wsg_idm_ecid_wtls7		740
-+wap_wsg_idm_ecid_wtls8		741
-+wap_wsg_idm_ecid_wtls9		742
-+wap_wsg_idm_ecid_wtls10		743
-+wap_wsg_idm_ecid_wtls11		744
-+wap_wsg_idm_ecid_wtls12		745
-+any_policy		746
-+policy_mappings		747
-+inhibit_any_policy		748
-+ipsec3		749
-+ipsec4		750
-+camellia_128_cbc		751
-+camellia_192_cbc		752
-+camellia_256_cbc		753
-+camellia_128_ecb		754
-+camellia_192_ecb		755
-+camellia_256_ecb		756
-+camellia_128_cfb128		757
-+camellia_192_cfb128		758
-+camellia_256_cfb128		759
-+camellia_128_cfb1		760
-+camellia_192_cfb1		761
-+camellia_256_cfb1		762
-+camellia_128_cfb8		763
-+camellia_192_cfb8		764
-+camellia_256_cfb8		765
-+camellia_128_ofb128		766
-+camellia_192_ofb128		767
-+camellia_256_ofb128		768
-+subject_directory_attributes		769
-+issuing_distribution_point		770
-+certificate_issuer		771
-+korea		772
-+kisa		773
-+kftc		774
-+npki_alg		775
-+seed_ecb		776
-+seed_cbc		777
-+seed_ofb128		778
-+seed_cfb128		779
-+hmac_md5		780
-+hmac_sha1		781
-+id_PasswordBasedMAC		782
-+id_DHBasedMac		783
-+id_it_suppLangTags		784
-+caRepository		785
-+id_smime_ct_compressedData		786
-+id_ct_asciiTextWithCRLF		787
-+id_aes128_wrap		788
-+id_aes192_wrap		789
-+id_aes256_wrap		790
-+ecdsa_with_Recommended		791
-+ecdsa_with_Specified		792
-+ecdsa_with_SHA224		793
-+ecdsa_with_SHA256		794
-+ecdsa_with_SHA384		795
-+ecdsa_with_SHA512		796
-+hmacWithMD5		797
-+hmacWithSHA224		798
-+hmacWithSHA256		799
-+hmacWithSHA384		800
-+hmacWithSHA512		801
-+dsa_with_SHA224		802
-+dsa_with_SHA256		803
-+whirlpool		804
-+cryptopro		805
-+cryptocom		806
-+id_GostR3411_94_with_GostR3410_2001		807
-+id_GostR3411_94_with_GostR3410_94		808
-+id_GostR3411_94		809
-+id_HMACGostR3411_94		810
-+id_GostR3410_2001		811
-+id_GostR3410_94		812
-+id_Gost28147_89		813
-+gost89_cnt		814
-+id_Gost28147_89_MAC		815
-+id_GostR3411_94_prf		816
-+id_GostR3410_2001DH		817
-+id_GostR3410_94DH		818
-+id_Gost28147_89_CryptoPro_KeyMeshing		819
-+id_Gost28147_89_None_KeyMeshing		820
-+id_GostR3411_94_TestParamSet		821
-+id_GostR3411_94_CryptoProParamSet		822
-+id_Gost28147_89_TestParamSet		823
-+id_Gost28147_89_CryptoPro_A_ParamSet		824
-+id_Gost28147_89_CryptoPro_B_ParamSet		825
-+id_Gost28147_89_CryptoPro_C_ParamSet		826
-+id_Gost28147_89_CryptoPro_D_ParamSet		827
-+id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		828
-+id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		829
-+id_Gost28147_89_CryptoPro_RIC_1_ParamSet		830
-+id_GostR3410_94_TestParamSet		831
-+id_GostR3410_94_CryptoPro_A_ParamSet		832
-+id_GostR3410_94_CryptoPro_B_ParamSet		833
-+id_GostR3410_94_CryptoPro_C_ParamSet		834
-+id_GostR3410_94_CryptoPro_D_ParamSet		835
-+id_GostR3410_94_CryptoPro_XchA_ParamSet		836
-+id_GostR3410_94_CryptoPro_XchB_ParamSet		837
-+id_GostR3410_94_CryptoPro_XchC_ParamSet		838
-+id_GostR3410_2001_TestParamSet		839
-+id_GostR3410_2001_CryptoPro_A_ParamSet		840
-+id_GostR3410_2001_CryptoPro_B_ParamSet		841
-+id_GostR3410_2001_CryptoPro_C_ParamSet		842
-+id_GostR3410_2001_CryptoPro_XchA_ParamSet		843
-+id_GostR3410_2001_CryptoPro_XchB_ParamSet		844
-+id_GostR3410_94_a		845
-+id_GostR3410_94_aBis		846
-+id_GostR3410_94_b		847
-+id_GostR3410_94_bBis		848
-+id_Gost28147_89_cc		849
-+id_GostR3410_94_cc		850
-+id_GostR3410_2001_cc		851
-+id_GostR3411_94_with_GostR3410_94_cc		852
-+id_GostR3411_94_with_GostR3410_2001_cc		853
-+id_GostR3410_2001_ParamSet_cc		854
-+hmac		855
-+LocalKeySet		856
-+freshest_crl		857
-+id_on_permanentIdentifier		858
-+searchGuide		859
-+businessCategory		860
-+postalAddress		861
-+postOfficeBox		862
-+physicalDeliveryOfficeName		863
-+telephoneNumber		864
-+telexNumber		865
-+teletexTerminalIdentifier		866
-+facsimileTelephoneNumber		867
-+x121Address		868
-+internationaliSDNNumber		869
-+registeredAddress		870
-+destinationIndicator		871
-+preferredDeliveryMethod		872
-+presentationAddress		873
-+supportedApplicationContext		874
-+member		875
-+owner		876
-+roleOccupant		877
-+seeAlso		878
-+userPassword		879
-+userCertificate		880
-+cACertificate		881
-+authorityRevocationList		882
-+certificateRevocationList		883
-+crossCertificatePair		884
-+enhancedSearchGuide		885
-+protocolInformation		886
-+distinguishedName		887
-+uniqueMember		888
-+houseIdentifier		889
-+supportedAlgorithms		890
-+deltaRevocationList		891
-+dmdName		892
-+id_alg_PWRI_KEK		893
-+cmac		894
-+aes_128_gcm		895
-+aes_128_ccm		896
-+id_aes128_wrap_pad		897
-+aes_192_gcm		898
-+aes_192_ccm		899
-+id_aes192_wrap_pad		900
-+aes_256_gcm		901
-+aes_256_ccm		902
-+id_aes256_wrap_pad		903
-+aes_128_ctr		904
-+aes_192_ctr		905
-+aes_256_ctr		906
-+id_camellia128_wrap		907
-+id_camellia192_wrap		908
-+id_camellia256_wrap		909
-+anyExtendedKeyUsage		910
-+mgf1		911
-+rsassaPss		912
-+aes_128_xts		913
-+aes_256_xts		914
-+rc4_hmac_md5		915
-+aes_128_cbc_hmac_sha1		916
-+aes_192_cbc_hmac_sha1		917
-+aes_256_cbc_hmac_sha1		918
-+rsaesOaep		919
-+dhpublicnumber		920
-+brainpoolP160r1		921
-+brainpoolP160t1		922
-+brainpoolP192r1		923
-+brainpoolP192t1		924
-+brainpoolP224r1		925
-+brainpoolP224t1		926
-+brainpoolP256r1		927
-+brainpoolP256t1		928
-+brainpoolP320r1		929
-+brainpoolP320t1		930
-+brainpoolP384r1		931
-+brainpoolP384t1		932
-+brainpoolP512r1		933
-+brainpoolP512t1		934
-+pSpecified		935
-+dhSinglePass_stdDH_sha1kdf_scheme		936
-+dhSinglePass_stdDH_sha224kdf_scheme		937
-+dhSinglePass_stdDH_sha256kdf_scheme		938
-+dhSinglePass_stdDH_sha384kdf_scheme		939
-+dhSinglePass_stdDH_sha512kdf_scheme		940
-+dhSinglePass_cofactorDH_sha1kdf_scheme		941
-+dhSinglePass_cofactorDH_sha224kdf_scheme		942
-+dhSinglePass_cofactorDH_sha256kdf_scheme		943
-+dhSinglePass_cofactorDH_sha384kdf_scheme		944
-+dhSinglePass_cofactorDH_sha512kdf_scheme		945
-+dh_std_kdf		946
-+dh_cofactor_kdf		947
-+aes_128_cbc_hmac_sha256		948
-+aes_192_cbc_hmac_sha256		949
-+aes_256_cbc_hmac_sha256		950
-+ct_precert_scts		951
-+ct_precert_poison		952
-+ct_precert_signer		953
-+ct_cert_scts		954
-+jurisdictionLocalityName		955
-+jurisdictionStateOrProvinceName		956
-+jurisdictionCountryName		957
-+aes_128_ocb		958
-+aes_192_ocb		959
-+aes_256_ocb		960
-+camellia_128_gcm		961
-+camellia_128_ccm		962
-+camellia_128_ctr		963
-+camellia_128_cmac		964
-+camellia_192_gcm		965
-+camellia_192_ccm		966
-+camellia_192_ctr		967
-+camellia_192_cmac		968
-+camellia_256_gcm		969
-+camellia_256_ccm		970
-+camellia_256_ctr		971
-+camellia_256_cmac		972
-+id_scrypt		973
-+id_tc26		974
-+gost89_cnt_12		975
-+gost_mac_12		976
-+id_tc26_algorithms		977
-+id_tc26_sign		978
-+id_GostR3410_2012_256		979
-+id_GostR3410_2012_512		980
-+id_tc26_digest		981
-+id_GostR3411_2012_256		982
-+id_GostR3411_2012_512		983
-+id_tc26_signwithdigest		984
-+id_tc26_signwithdigest_gost3410_2012_256		985
-+id_tc26_signwithdigest_gost3410_2012_512		986
-+id_tc26_mac		987
-+id_tc26_hmac_gost_3411_2012_256		988
-+id_tc26_hmac_gost_3411_2012_512		989
-+id_tc26_cipher		990
-+id_tc26_agreement		991
-+id_tc26_agreement_gost_3410_2012_256		992
-+id_tc26_agreement_gost_3410_2012_512		993
-+id_tc26_constants		994
-+id_tc26_sign_constants		995
-+id_tc26_gost_3410_2012_512_constants		996
-+id_tc26_gost_3410_2012_512_paramSetTest		997
-+id_tc26_gost_3410_2012_512_paramSetA		998
-+id_tc26_gost_3410_2012_512_paramSetB		999
-+id_tc26_digest_constants		1000
-+id_tc26_cipher_constants		1001
-+id_tc26_gost_28147_constants		1002
-+id_tc26_gost_28147_param_Z		1003
-+INN		1004
-+OGRN		1005
-+SNILS		1006
-+subjectSignTool		1007
-+issuerSignTool		1008
-+gost89_cbc		1009
-+gost89_ecb		1010
-+gost89_ctr		1011
-+grasshopper_ecb		1012
-+grasshopper_ctr		1013
-+grasshopper_ofb		1014
-+grasshopper_cbc		1015
-+grasshopper_cfb		1016
-+grasshopper_mac		1017
-+chacha20_poly1305		1018
-+chacha20		1019
-+tlsfeature		1020
-+tls1_prf		1021
-+ipsec_IKE		1022
-+capwapAC		1023
-+capwapWTP		1024
-+sshClient		1025
-+sshServer		1026
-+sendRouter		1027
-+sendProxiedRouter		1028
-+sendOwner		1029
-+sendProxiedOwner		1030
-+id_pkinit		1031
-+pkInitClientAuth		1032
-+pkInitKDC		1033
-+X25519		1034
-+X448		1035
-+hkdf		1036
-+kx_rsa		1037
-+kx_ecdhe		1038
-+kx_dhe		1039
-+kx_ecdhe_psk		1040
-+kx_dhe_psk		1041
-+kx_rsa_psk		1042
-+kx_psk		1043
-+kx_srp		1044
-+kx_gost		1045
-+auth_rsa		1046
-+auth_ecdsa		1047
-+auth_psk		1048
-+auth_dss		1049
-+auth_gost01		1050
-+auth_gost12		1051
-+auth_srp		1052
-+auth_null		1053
-+fips_none		1054
-+fips_140_2		1055
-+blake2b512		1056
-+blake2s256		1057
-+id_smime_ct_contentCollection		1058
-+id_smime_ct_authEnvelopedData		1059
-+id_ct_xml		1060
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.c
-new file mode 100644
-index 0000000..627f5bc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.c
-@@ -0,0 +1,165 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "obj_xref.h"
-+#include "e_os.h"
-+
-+static STACK_OF(nid_triple) *sig_app, *sigx_app;
-+
-+static int sig_cmp(const nid_triple *a, const nid_triple *b)
-+{
-+    return a->sign_id - b->sign_id;
-+}
-+
-+DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
-+IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
-+
-+static int sig_sk_cmp(const nid_triple *const *a, const nid_triple *const *b)
-+{
-+    return (*a)->sign_id - (*b)->sign_id;
-+}
-+
-+DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
-+
-+static int sigx_cmp(const nid_triple *const *a, const nid_triple *const *b)
-+{
-+    int ret;
-+    ret = (*a)->hash_id - (*b)->hash_id;
-+    if (ret)
-+        return ret;
-+    return (*a)->pkey_id - (*b)->pkey_id;
-+}
-+
-+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
-+
-+int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid)
-+{
-+    nid_triple tmp;
-+    const nid_triple *rv = NULL;
-+    tmp.sign_id = signid;
-+
-+    if (sig_app) {
-+        int idx = sk_nid_triple_find(sig_app, &tmp);
-+        if (idx >= 0)
-+            rv = sk_nid_triple_value(sig_app, idx);
-+    }
-+#ifndef OBJ_XREF_TEST2
-+    if (rv == NULL) {
-+        rv = OBJ_bsearch_sig(&tmp, sigoid_srt, OSSL_NELEM(sigoid_srt));
-+    }
-+#endif
-+    if (rv == NULL)
-+        return 0;
-+    if (pdig_nid)
-+        *pdig_nid = rv->hash_id;
-+    if (ppkey_nid)
-+        *ppkey_nid = rv->pkey_id;
-+    return 1;
-+}
-+
-+int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid)
-+{
-+    nid_triple tmp;
-+    const nid_triple *t = &tmp;
-+    const nid_triple **rv = NULL;
-+
-+    tmp.hash_id = dig_nid;
-+    tmp.pkey_id = pkey_nid;
-+
-+    if (sigx_app) {
-+        int idx = sk_nid_triple_find(sigx_app, &tmp);
-+        if (idx >= 0) {
-+            t = sk_nid_triple_value(sigx_app, idx);
-+            rv = &t;
-+        }
-+    }
-+#ifndef OBJ_XREF_TEST2
-+    if (rv == NULL) {
-+        rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref, OSSL_NELEM(sigoid_srt_xref));
-+    }
-+#endif
-+    if (rv == NULL)
-+        return 0;
-+    if (psignid)
-+        *psignid = (*rv)->sign_id;
-+    return 1;
-+}
-+
-+int OBJ_add_sigid(int signid, int dig_id, int pkey_id)
-+{
-+    nid_triple *ntr;
-+    if (sig_app == NULL)
-+        sig_app = sk_nid_triple_new(sig_sk_cmp);
-+    if (sig_app == NULL)
-+        return 0;
-+    if (sigx_app == NULL)
-+        sigx_app = sk_nid_triple_new(sigx_cmp);
-+    if (sigx_app == NULL)
-+        return 0;
-+    ntr = OPENSSL_malloc(sizeof(*ntr));
-+    if (ntr == NULL)
-+        return 0;
-+    ntr->sign_id = signid;
-+    ntr->hash_id = dig_id;
-+    ntr->pkey_id = pkey_id;
-+
-+    if (!sk_nid_triple_push(sig_app, ntr)) {
-+        OPENSSL_free(ntr);
-+        return 0;
-+    }
-+
-+    if (!sk_nid_triple_push(sigx_app, ntr))
-+        return 0;
-+
-+    sk_nid_triple_sort(sig_app);
-+    sk_nid_triple_sort(sigx_app);
-+
-+    return 1;
-+}
-+
-+static void sid_free(nid_triple *tt)
-+{
-+    OPENSSL_free(tt);
-+}
-+
-+void OBJ_sigid_free(void)
-+{
-+    sk_nid_triple_pop_free(sig_app, sid_free);
-+    sig_app = NULL;
-+    sk_nid_triple_free(sigx_app);
-+    sigx_app = NULL;
-+}
-+
-+#ifdef OBJ_XREF_TEST
-+
-+main()
-+{
-+    int n1, n2, n3;
-+
-+    int i, rv;
-+# ifdef OBJ_XREF_TEST2
-+    for (i = 0; i < OSSL_NELEM(sigoid_srt); i++) {
-+        OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1], sigoid_srt[i][2]);
-+    }
-+# endif
-+
-+    for (i = 0; i < OSSL_NELEM(sigoid_srt); i++) {
-+        n1 = sigoid_srt[i][0];
-+        rv = OBJ_find_sigid_algs(n1, &n2, &n3);
-+        printf("Forward: %d, %s %s %s\n", rv,
-+               OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
-+        n1 = 0;
-+        rv = OBJ_find_sigid_by_algs(&n1, n2, n3);
-+        printf("Reverse: %d, %s %s %s\n", rv,
-+               OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
-+    }
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.h
-new file mode 100644
-index 0000000..d09aa71
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.h
-@@ -0,0 +1,118 @@
-+/*
-+ * WARNING: do not edit!
-+ * Generated by objxref.pl
-+ *
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+
-+typedef struct {
-+    int sign_id;
-+    int hash_id;
-+    int pkey_id;
-+} nid_triple;
-+
-+DEFINE_STACK_OF(nid_triple)
-+
-+static const nid_triple sigoid_srt[] = {
-+    {NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption},
-+    {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption},
-+    {NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption},
-+    {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption},
-+    {NID_dsaWithSHA, NID_sha, NID_dsa},
-+    {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2},
-+    {NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption},
-+    {NID_md5WithRSA, NID_md5, NID_rsa},
-+    {NID_dsaWithSHA1, NID_sha1, NID_dsa},
-+    {NID_sha1WithRSA, NID_sha1, NID_rsa},
-+    {NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption},
-+    {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption},
-+    {NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey},
-+    {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption},
-+    {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption},
-+    {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption},
-+    {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption},
-+    {NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey},
-+    {NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey},
-+    {NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey},
-+    {NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey},
-+    {NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey},
-+    {NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey},
-+    {NID_dsa_with_SHA224, NID_sha224, NID_dsa},
-+    {NID_dsa_with_SHA256, NID_sha256, NID_dsa},
-+    {NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94,
-+     NID_id_GostR3410_2001},
-+    {NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94,
-+     NID_id_GostR3410_94},
-+    {NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94,
-+     NID_id_GostR3410_94_cc},
-+    {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94,
-+     NID_id_GostR3410_2001_cc},
-+    {NID_rsassaPss, NID_undef, NID_rsaEncryption},
-+    {NID_dhSinglePass_stdDH_sha1kdf_scheme, NID_sha1, NID_dh_std_kdf},
-+    {NID_dhSinglePass_stdDH_sha224kdf_scheme, NID_sha224, NID_dh_std_kdf},
-+    {NID_dhSinglePass_stdDH_sha256kdf_scheme, NID_sha256, NID_dh_std_kdf},
-+    {NID_dhSinglePass_stdDH_sha384kdf_scheme, NID_sha384, NID_dh_std_kdf},
-+    {NID_dhSinglePass_stdDH_sha512kdf_scheme, NID_sha512, NID_dh_std_kdf},
-+    {NID_dhSinglePass_cofactorDH_sha1kdf_scheme, NID_sha1,
-+     NID_dh_cofactor_kdf},
-+    {NID_dhSinglePass_cofactorDH_sha224kdf_scheme, NID_sha224,
-+     NID_dh_cofactor_kdf},
-+    {NID_dhSinglePass_cofactorDH_sha256kdf_scheme, NID_sha256,
-+     NID_dh_cofactor_kdf},
-+    {NID_dhSinglePass_cofactorDH_sha384kdf_scheme, NID_sha384,
-+     NID_dh_cofactor_kdf},
-+    {NID_dhSinglePass_cofactorDH_sha512kdf_scheme, NID_sha512,
-+     NID_dh_cofactor_kdf},
-+    {NID_id_tc26_signwithdigest_gost3410_2012_256, NID_id_GostR3411_2012_256,
-+     NID_id_GostR3410_2012_256},
-+    {NID_id_tc26_signwithdigest_gost3410_2012_512, NID_id_GostR3411_2012_512,
-+     NID_id_GostR3410_2012_512},
-+};
-+
-+static const nid_triple *const sigoid_srt_xref[] = {
-+    &sigoid_srt[0],
-+    &sigoid_srt[1],
-+    &sigoid_srt[7],
-+    &sigoid_srt[2],
-+    &sigoid_srt[4],
-+    &sigoid_srt[3],
-+    &sigoid_srt[9],
-+    &sigoid_srt[5],
-+    &sigoid_srt[8],
-+    &sigoid_srt[12],
-+    &sigoid_srt[30],
-+    &sigoid_srt[35],
-+    &sigoid_srt[6],
-+    &sigoid_srt[10],
-+    &sigoid_srt[11],
-+    &sigoid_srt[13],
-+    &sigoid_srt[24],
-+    &sigoid_srt[20],
-+    &sigoid_srt[32],
-+    &sigoid_srt[37],
-+    &sigoid_srt[14],
-+    &sigoid_srt[21],
-+    &sigoid_srt[33],
-+    &sigoid_srt[38],
-+    &sigoid_srt[15],
-+    &sigoid_srt[22],
-+    &sigoid_srt[34],
-+    &sigoid_srt[39],
-+    &sigoid_srt[16],
-+    &sigoid_srt[23],
-+    &sigoid_srt[19],
-+    &sigoid_srt[31],
-+    &sigoid_srt[36],
-+    &sigoid_srt[25],
-+    &sigoid_srt[26],
-+    &sigoid_srt[27],
-+    &sigoid_srt[28],
-+    &sigoid_srt[40],
-+    &sigoid_srt[41],
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.txt b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.txt
-new file mode 100644
-index 0000000..981103b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/obj_xref.txt
-@@ -0,0 +1,60 @@
-+# OID cross reference table.
-+# Links signatures OIDs to their corresponding public key algorithms
-+# and digests.
-+
-+md2WithRSAEncryption	md2	rsaEncryption
-+md5WithRSAEncryption	md5	rsaEncryption
-+shaWithRSAEncryption	sha	rsaEncryption
-+sha1WithRSAEncryption	sha1	rsaEncryption
-+md4WithRSAEncryption	md4	rsaEncryption
-+sha256WithRSAEncryption sha256	rsaEncryption
-+sha384WithRSAEncryption	sha384	rsaEncryption
-+sha512WithRSAEncryption	sha512	rsaEncryption
-+sha224WithRSAEncryption	sha224	rsaEncryption
-+mdc2WithRSA		mdc2	rsaEncryption
-+ripemd160WithRSA	ripemd160 rsaEncryption
-+# For PSS the digest algorithm can vary and depends on the included
-+# AlgorithmIdentifier. The digest "undef" indicates the public key
-+# method should handle this explicitly.
-+rsassaPss		undef	rsaEncryption
-+
-+# Alternative deprecated OIDs. By using the older "rsa" OID this
-+# type will be recognized by not normally used.
-+
-+md5WithRSA		md5	rsa
-+sha1WithRSA		sha1	rsa
-+
-+dsaWithSHA		sha	dsa
-+dsaWithSHA1		sha1	dsa
-+
-+dsaWithSHA1_2		sha1	dsa_2
-+
-+ecdsa_with_SHA1		sha1	X9_62_id_ecPublicKey
-+ecdsa_with_SHA224	sha224	X9_62_id_ecPublicKey
-+ecdsa_with_SHA256	sha256	X9_62_id_ecPublicKey
-+ecdsa_with_SHA384	sha384	X9_62_id_ecPublicKey
-+ecdsa_with_SHA512	sha512	X9_62_id_ecPublicKey
-+ecdsa_with_Recommended	undef	X9_62_id_ecPublicKey
-+ecdsa_with_Specified	undef	X9_62_id_ecPublicKey
-+
-+dsa_with_SHA224		sha224	dsa
-+dsa_with_SHA256		sha256	dsa
-+
-+id_GostR3411_94_with_GostR3410_2001	id_GostR3411_94 id_GostR3410_2001
-+id_GostR3411_94_with_GostR3410_94	id_GostR3411_94 id_GostR3410_94
-+id_GostR3411_94_with_GostR3410_94_cc	id_GostR3411_94 id_GostR3410_94_cc
-+id_GostR3411_94_with_GostR3410_2001_cc	id_GostR3411_94 id_GostR3410_2001_cc
-+id_tc26_signwithdigest_gost3410_2012_256 id_GostR3411_2012_256 id_GostR3410_2012_256
-+id_tc26_signwithdigest_gost3410_2012_512 id_GostR3411_2012_512 id_GostR3410_2012_512
-+# ECDH KDFs and their corresponding message digests and schemes
-+dhSinglePass_stdDH_sha1kdf_scheme		sha1	dh_std_kdf
-+dhSinglePass_stdDH_sha224kdf_scheme		sha224	dh_std_kdf
-+dhSinglePass_stdDH_sha256kdf_scheme		sha256	dh_std_kdf
-+dhSinglePass_stdDH_sha384kdf_scheme		sha384	dh_std_kdf
-+dhSinglePass_stdDH_sha512kdf_scheme		sha512	dh_std_kdf
-+
-+dhSinglePass_cofactorDH_sha1kdf_scheme		sha1	dh_cofactor_kdf
-+dhSinglePass_cofactorDH_sha224kdf_scheme	sha224	dh_cofactor_kdf
-+dhSinglePass_cofactorDH_sha256kdf_scheme	sha256	dh_cofactor_kdf
-+dhSinglePass_cofactorDH_sha384kdf_scheme	sha384	dh_cofactor_kdf
-+dhSinglePass_cofactorDH_sha512kdf_scheme	sha512	dh_cofactor_kdf
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objects.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objects.pl
-new file mode 100644
-index 0000000..3b40277
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objects.pl
-@@ -0,0 +1,193 @@
-+#! /usr/bin/env perl
-+# Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+open (NUMIN,"$ARGV[1]") || die "Can't open number file $ARGV[1]";
-+$max_nid=0;
-+$o=0;
-+while()
-+	{
-+	s|\R$||;
-+	$o++;
-+	s/#.*$//;
-+	next if /^\s*$/;
-+	$_ = 'X'.$_;
-+	($Cname,$mynum) = split;
-+	$Cname =~ s/^X//;
-+	if (defined($nidn{$mynum}))
-+		{ die "$ARGV[1]:$o:There's already an object with NID ",$mynum," on line ",$order{$mynum},"\n"; }
-+	if (defined($nid{$Cname}))
-+		{ die "$ARGV[1]:$o:There's already an object with name ",$Cname," on line ",$order{$nid{$Cname}},"\n"; }
-+	$nid{$Cname} = $mynum;
-+	$nidn{$mynum} = $Cname;
-+	$order{$mynum} = $o;
-+	$max_nid = $mynum if $mynum > $max_nid;
-+	}
-+close NUMIN;
-+
-+open (IN,"$ARGV[0]") || die "Can't open input file $ARGV[0]";
-+$Cname="";
-+$o=0;
-+while ()
-+	{
-+	s|\R$||;
-+	$o++;
-+        if (/^!module\s+(.*)$/)
-+		{
-+		$module = $1."-";
-+		$module =~ s/\./_/g;
-+		$module =~ s/-/_/g;
-+		}
-+        if (/^!global$/)
-+		{ $module = ""; }
-+	if (/^!Cname\s+(.*)$/)
-+		{ $Cname = $1; }
-+	if (/^!Alias\s+(.+?)\s+(.*)$/)
-+		{
-+		$Cname = $module.$1;
-+		$myoid = $2;
-+		$myoid = &process_oid($myoid);
-+		$Cname =~ s/-/_/g;
-+		$ordern{$o} = $Cname;
-+		$order{$Cname} = $o;
-+		$obj{$Cname} = $myoid;
-+		$_ = "";
-+		$Cname = "";
-+		}
-+	s/!.*$//;
-+	s/#.*$//;
-+	next if /^\s*$/;
-+	($myoid,$mysn,$myln) = split ':';
-+	$mysn =~ s/^\s*//;
-+	$mysn =~ s/\s*$//;
-+	$myln =~ s/^\s*//;
-+	$myln =~ s/\s*$//;
-+	$myoid =~ s/^\s*//;
-+	$myoid =~ s/\s*$//;
-+	if ($myoid ne "")
-+		{
-+		$myoid = &process_oid($myoid);
-+		}
-+
-+	if ($Cname eq "" && ($myln =~ /^[_A-Za-z][\w.-]*$/ ))
-+		{
-+		$Cname = $myln;
-+		$Cname =~ s/\./_/g;
-+		$Cname =~ s/-/_/g;
-+		if ($Cname ne "" && defined($ln{$module.$Cname}))
-+			{ die "objects.txt:$o:There's already an object with long name ",$ln{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; }
-+		}
-+	if ($Cname eq "")
-+		{
-+		$Cname = $mysn;
-+		$Cname =~ s/-/_/g;
-+		if ($Cname ne "" && defined($sn{$module.$Cname}))
-+			{ die "objects.txt:$o:There's already an object with short name ",$sn{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; }
-+		}
-+	if ($Cname eq "")
-+		{
-+		$Cname = $myln;
-+		$Cname =~ s/-/_/g;
-+		$Cname =~ s/\./_/g;
-+		$Cname =~ s/ /_/g;
-+		if ($Cname ne "" && defined($ln{$module.$Cname}))
-+			{ die "objects.txt:$o:There's already an object with long name ",$ln{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; }
-+		}
-+	$Cname =~ s/\./_/g;
-+	$Cname =~ s/-/_/g;
-+	$Cname = $module.$Cname;
-+	$ordern{$o} = $Cname;
-+	$order{$Cname} = $o;
-+	$sn{$Cname} = $mysn;
-+	$ln{$Cname} = $myln;
-+	$obj{$Cname} = $myoid;
-+	if (!defined($nid{$Cname}))
-+		{
-+		$max_nid++;
-+		$nid{$Cname} = $max_nid;
-+		$nidn{$max_nid} = $Cname;
-+print STDERR "Added OID $Cname\n";
-+		}
-+	$Cname="";
-+	}
-+close IN;
-+
-+open (NUMOUT,">$ARGV[1]") || die "Can't open output file $ARGV[1]";
-+foreach (sort { $a <=> $b } keys %nidn)
-+	{
-+	print NUMOUT $nidn{$_},"\t\t",$_,"\n";
-+	}
-+close NUMOUT;
-+
-+open (OUT,">$ARGV[2]") || die "Can't open output file $ARGV[2]";
-+print OUT <<'EOF';
-+/*
-+ * WARNING: do not edit!
-+ * Generated by crypto/objects/objects.pl
-+ *
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#define SN_undef                        "UNDEF"
-+#define LN_undef                        "undefined"
-+#define NID_undef                       0
-+#define OBJ_undef                       0L
-+EOF
-+
-+sub expand
-+	{
-+	my $string = shift;
-+
-+	1 while $string =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
-+
-+	return $string;
-+	}
-+
-+foreach (sort { $a <=> $b } keys %ordern)
-+	{
-+	$Cname=$ordern{$_};
-+	print OUT "\n";
-+	print OUT expand("#define SN_$Cname\t\t\"$sn{$Cname}\"\n") if $sn{$Cname} ne "";
-+	print OUT expand("#define LN_$Cname\t\t\"$ln{$Cname}\"\n") if $ln{$Cname} ne "";
-+	print OUT expand("#define NID_$Cname\t\t$nid{$Cname}\n") if $nid{$Cname} ne "";
-+	print OUT expand("#define OBJ_$Cname\t\t$obj{$Cname}\n") if $obj{$Cname} ne "";
-+	}
-+
-+close OUT;
-+
-+sub process_oid
-+	{
-+	local($oid)=@_;
-+	local(@a,$oid_pref);
-+
-+	@a = split(/\s+/,$myoid);
-+	$pref_oid = "";
-+	$pref_sep = "";
-+	if (!($a[0] =~ /^[0-9]+$/))
-+		{
-+		$a[0] =~ s/-/_/g;
-+		if (!defined($obj{$a[0]}))
-+			{ die "$ARGV[0]:$o:Undefined identifier ",$a[0],"\n"; }
-+		$pref_oid = "OBJ_" . $a[0];
-+		$pref_sep = ",";
-+		shift @a;
-+		}
-+	$oids = join('L,',@a) . "L";
-+	if ($oids ne "L")
-+		{
-+		$oids = $pref_oid . $pref_sep . $oids;
-+		}
-+	else
-+		{
-+		$oids = $pref_oid;
-+		}
-+	return($oids);
-+	}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objects.txt b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objects.txt
-new file mode 100644
-index 0000000..fc0781d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objects.txt
-@@ -0,0 +1,1485 @@
-+# CCITT was renamed to ITU-T quite some time ago
-+0			: ITU-T			: itu-t
-+!Alias ccitt itu-t
-+
-+1			: ISO			: iso
-+
-+2			: JOINT-ISO-ITU-T	: joint-iso-itu-t
-+!Alias joint-iso-ccitt joint-iso-itu-t
-+
-+iso 2			: member-body		: ISO Member Body
-+
-+iso 3			: identified-organization
-+
-+# HMAC OIDs
-+identified-organization 6 1 5 5 8 1 1	: HMAC-MD5	: hmac-md5
-+identified-organization 6 1 5 5 8 1 2	: HMAC-SHA1	: hmac-sha1
-+
-+identified-organization 132	: certicom-arc
-+
-+joint-iso-itu-t 23	: international-organizations	: International Organizations
-+
-+international-organizations 43	: wap
-+wap 1			: wap-wsg
-+
-+joint-iso-itu-t 5 1 5	: selected-attribute-types	: Selected Attribute Types
-+
-+selected-attribute-types 55	: clearance
-+
-+member-body 840		: ISO-US		: ISO US Member Body
-+ISO-US 10040		: X9-57			: X9.57
-+X9-57 4			: X9cm			: X9.57 CM ?
-+
-+!Cname dsa
-+X9cm 1			: DSA			: dsaEncryption
-+X9cm 3			: DSA-SHA1		: dsaWithSHA1
-+
-+
-+ISO-US 10045		: ansi-X9-62		: ANSI X9.62
-+!module X9-62
-+!Alias id-fieldType ansi-X9-62 1
-+X9-62_id-fieldType 1		: prime-field
-+X9-62_id-fieldType 2		: characteristic-two-field
-+X9-62_characteristic-two-field 3 : id-characteristic-two-basis
-+X9-62_id-characteristic-two-basis 1 : onBasis
-+X9-62_id-characteristic-two-basis 2 : tpBasis
-+X9-62_id-characteristic-two-basis 3 : ppBasis
-+!Alias id-publicKeyType ansi-X9-62 2
-+X9-62_id-publicKeyType 1	: id-ecPublicKey
-+!Alias ellipticCurve ansi-X9-62 3
-+!Alias c-TwoCurve X9-62_ellipticCurve 0
-+X9-62_c-TwoCurve 1		: c2pnb163v1
-+X9-62_c-TwoCurve 2		: c2pnb163v2
-+X9-62_c-TwoCurve 3		: c2pnb163v3
-+X9-62_c-TwoCurve 4		: c2pnb176v1
-+X9-62_c-TwoCurve 5		: c2tnb191v1
-+X9-62_c-TwoCurve 6		: c2tnb191v2
-+X9-62_c-TwoCurve 7		: c2tnb191v3
-+X9-62_c-TwoCurve 8		: c2onb191v4
-+X9-62_c-TwoCurve 9		: c2onb191v5
-+X9-62_c-TwoCurve 10		: c2pnb208w1
-+X9-62_c-TwoCurve 11		: c2tnb239v1
-+X9-62_c-TwoCurve 12		: c2tnb239v2
-+X9-62_c-TwoCurve 13		: c2tnb239v3
-+X9-62_c-TwoCurve 14		: c2onb239v4
-+X9-62_c-TwoCurve 15		: c2onb239v5
-+X9-62_c-TwoCurve 16		: c2pnb272w1
-+X9-62_c-TwoCurve 17		: c2pnb304w1
-+X9-62_c-TwoCurve 18		: c2tnb359v1
-+X9-62_c-TwoCurve 19		: c2pnb368w1
-+X9-62_c-TwoCurve 20		: c2tnb431r1
-+!Alias primeCurve X9-62_ellipticCurve 1
-+X9-62_primeCurve 1	 	: prime192v1
-+X9-62_primeCurve 2	 	: prime192v2
-+X9-62_primeCurve 3	 	: prime192v3
-+X9-62_primeCurve 4	 	: prime239v1
-+X9-62_primeCurve 5	 	: prime239v2
-+X9-62_primeCurve 6	 	: prime239v3
-+X9-62_primeCurve 7	 	: prime256v1
-+!Alias id-ecSigType ansi-X9-62 4
-+!global
-+X9-62_id-ecSigType 1		: ecdsa-with-SHA1
-+X9-62_id-ecSigType 2		: ecdsa-with-Recommended
-+X9-62_id-ecSigType 3		: ecdsa-with-Specified
-+ecdsa-with-Specified 1		: ecdsa-with-SHA224
-+ecdsa-with-Specified 2		: ecdsa-with-SHA256
-+ecdsa-with-Specified 3		: ecdsa-with-SHA384
-+ecdsa-with-Specified 4		: ecdsa-with-SHA512
-+
-+# SECG curve OIDs from "SEC 2: Recommended Elliptic Curve Domain Parameters"
-+# (http://www.secg.org/)
-+!Alias secg_ellipticCurve certicom-arc 0
-+# SECG prime curves OIDs
-+secg-ellipticCurve 6		: secp112r1
-+secg-ellipticCurve 7		: secp112r2
-+secg-ellipticCurve 28		: secp128r1
-+secg-ellipticCurve 29		: secp128r2
-+secg-ellipticCurve 9		: secp160k1
-+secg-ellipticCurve 8		: secp160r1
-+secg-ellipticCurve 30		: secp160r2
-+secg-ellipticCurve 31		: secp192k1
-+# NOTE: the curve secp192r1 is the same as prime192v1 defined above
-+#       and is therefore omitted
-+secg-ellipticCurve 32		: secp224k1
-+secg-ellipticCurve 33		: secp224r1
-+secg-ellipticCurve 10		: secp256k1
-+# NOTE: the curve secp256r1 is the same as prime256v1 defined above
-+#       and is therefore omitted
-+secg-ellipticCurve 34		: secp384r1
-+secg-ellipticCurve 35		: secp521r1
-+# SECG characteristic two curves OIDs
-+secg-ellipticCurve 4		: sect113r1
-+secg-ellipticCurve 5		: sect113r2
-+secg-ellipticCurve 22		: sect131r1
-+secg-ellipticCurve 23		: sect131r2
-+secg-ellipticCurve 1		: sect163k1
-+secg-ellipticCurve 2		: sect163r1
-+secg-ellipticCurve 15		: sect163r2
-+secg-ellipticCurve 24		: sect193r1
-+secg-ellipticCurve 25		: sect193r2
-+secg-ellipticCurve 26		: sect233k1
-+secg-ellipticCurve 27		: sect233r1
-+secg-ellipticCurve 3		: sect239k1
-+secg-ellipticCurve 16		: sect283k1
-+secg-ellipticCurve 17		: sect283r1
-+secg-ellipticCurve 36		: sect409k1
-+secg-ellipticCurve 37		: sect409r1
-+secg-ellipticCurve 38		: sect571k1
-+secg-ellipticCurve 39		: sect571r1
-+
-+# WAP/TLS curve OIDs (http://www.wapforum.org/)
-+!Alias wap-wsg-idm-ecid wap-wsg 4
-+wap-wsg-idm-ecid 1	: wap-wsg-idm-ecid-wtls1
-+wap-wsg-idm-ecid 3	: wap-wsg-idm-ecid-wtls3
-+wap-wsg-idm-ecid 4	: wap-wsg-idm-ecid-wtls4
-+wap-wsg-idm-ecid 5	: wap-wsg-idm-ecid-wtls5
-+wap-wsg-idm-ecid 6	: wap-wsg-idm-ecid-wtls6
-+wap-wsg-idm-ecid 7	: wap-wsg-idm-ecid-wtls7
-+wap-wsg-idm-ecid 8	: wap-wsg-idm-ecid-wtls8
-+wap-wsg-idm-ecid 9	: wap-wsg-idm-ecid-wtls9
-+wap-wsg-idm-ecid 10	: wap-wsg-idm-ecid-wtls10
-+wap-wsg-idm-ecid 11	: wap-wsg-idm-ecid-wtls11
-+wap-wsg-idm-ecid 12	: wap-wsg-idm-ecid-wtls12
-+
-+
-+ISO-US 113533 7 66 10	: CAST5-CBC		: cast5-cbc
-+			: CAST5-ECB		: cast5-ecb
-+!Cname cast5-cfb64
-+			: CAST5-CFB		: cast5-cfb
-+!Cname cast5-ofb64
-+			: CAST5-OFB		: cast5-ofb
-+!Cname pbeWithMD5AndCast5-CBC
-+ISO-US 113533 7 66 12	:			: pbeWithMD5AndCast5CBC
-+
-+# Macs for CMP and CRMF
-+ISO-US 113533 7 66 13	: id-PasswordBasedMAC	: password based MAC
-+ISO-US 113533 7 66 30	: id-DHBasedMac		: Diffie-Hellman based MAC
-+
-+ISO-US 113549		: rsadsi		: RSA Data Security, Inc.
-+
-+rsadsi 1		: pkcs			: RSA Data Security, Inc. PKCS
-+
-+pkcs 1			: pkcs1
-+pkcs1 1			:			: rsaEncryption
-+pkcs1 2			: RSA-MD2		: md2WithRSAEncryption
-+pkcs1 3			: RSA-MD4		: md4WithRSAEncryption
-+pkcs1 4			: RSA-MD5		: md5WithRSAEncryption
-+pkcs1 5			: RSA-SHA1		: sha1WithRSAEncryption
-+# According to PKCS #1 version 2.1
-+pkcs1 7			: RSAES-OAEP		: rsaesOaep
-+pkcs1 8			: MGF1			: mgf1
-+pkcs1 9			: PSPECIFIED		: pSpecified
-+pkcs1 10		: RSASSA-PSS		: rsassaPss
-+
-+pkcs1 11		: RSA-SHA256		: sha256WithRSAEncryption
-+pkcs1 12		: RSA-SHA384		: sha384WithRSAEncryption
-+pkcs1 13		: RSA-SHA512		: sha512WithRSAEncryption
-+pkcs1 14		: RSA-SHA224		: sha224WithRSAEncryption
-+
-+pkcs 3			: pkcs3
-+pkcs3 1			:			: dhKeyAgreement
-+
-+pkcs 5			: pkcs5
-+pkcs5 1			: PBE-MD2-DES		: pbeWithMD2AndDES-CBC
-+pkcs5 3			: PBE-MD5-DES		: pbeWithMD5AndDES-CBC
-+pkcs5 4			: PBE-MD2-RC2-64	: pbeWithMD2AndRC2-CBC
-+pkcs5 6			: PBE-MD5-RC2-64	: pbeWithMD5AndRC2-CBC
-+pkcs5 10		: PBE-SHA1-DES		: pbeWithSHA1AndDES-CBC
-+pkcs5 11		: PBE-SHA1-RC2-64	: pbeWithSHA1AndRC2-CBC
-+!Cname id_pbkdf2
-+pkcs5 12		:			: PBKDF2
-+!Cname pbes2
-+pkcs5 13		:			: PBES2
-+!Cname pbmac1
-+pkcs5 14		:			: PBMAC1
-+
-+pkcs 7			: pkcs7
-+pkcs7 1			:			: pkcs7-data
-+!Cname pkcs7-signed
-+pkcs7 2			:			: pkcs7-signedData
-+!Cname pkcs7-enveloped
-+pkcs7 3			:			: pkcs7-envelopedData
-+!Cname pkcs7-signedAndEnveloped
-+pkcs7 4			:			: pkcs7-signedAndEnvelopedData
-+!Cname pkcs7-digest
-+pkcs7 5			:			: pkcs7-digestData
-+!Cname pkcs7-encrypted
-+pkcs7 6			:			: pkcs7-encryptedData
-+
-+pkcs 9			: pkcs9
-+!module pkcs9
-+pkcs9 1			: 			: emailAddress
-+pkcs9 2			:			: unstructuredName
-+pkcs9 3			:			: contentType
-+pkcs9 4			:			: messageDigest
-+pkcs9 5			:			: signingTime
-+pkcs9 6			:			: countersignature
-+pkcs9 7			:			: challengePassword
-+pkcs9 8			:			: unstructuredAddress
-+!Cname extCertAttributes
-+pkcs9 9			:			: extendedCertificateAttributes
-+!global
-+
-+!Cname ext-req
-+pkcs9 14		: extReq		: Extension Request
-+
-+!Cname SMIMECapabilities
-+pkcs9 15		: SMIME-CAPS		: S/MIME Capabilities
-+
-+# S/MIME
-+!Cname SMIME
-+pkcs9 16		: SMIME			: S/MIME
-+SMIME 0			: id-smime-mod
-+SMIME 1			: id-smime-ct
-+SMIME 2			: id-smime-aa
-+SMIME 3			: id-smime-alg
-+SMIME 4			: id-smime-cd
-+SMIME 5			: id-smime-spq
-+SMIME 6			: id-smime-cti
-+
-+# S/MIME Modules
-+id-smime-mod 1		: id-smime-mod-cms
-+id-smime-mod 2		: id-smime-mod-ess
-+id-smime-mod 3		: id-smime-mod-oid
-+id-smime-mod 4		: id-smime-mod-msg-v3
-+id-smime-mod 5		: id-smime-mod-ets-eSignature-88
-+id-smime-mod 6		: id-smime-mod-ets-eSignature-97
-+id-smime-mod 7		: id-smime-mod-ets-eSigPolicy-88
-+id-smime-mod 8		: id-smime-mod-ets-eSigPolicy-97
-+
-+# S/MIME Content Types
-+id-smime-ct 1		: id-smime-ct-receipt
-+id-smime-ct 2		: id-smime-ct-authData
-+id-smime-ct 3		: id-smime-ct-publishCert
-+id-smime-ct 4		: id-smime-ct-TSTInfo
-+id-smime-ct 5		: id-smime-ct-TDTInfo
-+id-smime-ct 6		: id-smime-ct-contentInfo
-+id-smime-ct 7		: id-smime-ct-DVCSRequestData
-+id-smime-ct 8		: id-smime-ct-DVCSResponseData
-+id-smime-ct 9		: id-smime-ct-compressedData
-+id-smime-ct 19		: id-smime-ct-contentCollection
-+id-smime-ct 23		: id-smime-ct-authEnvelopedData
-+id-smime-ct 27		: id-ct-asciiTextWithCRLF
-+id-smime-ct 28		: id-ct-xml
-+
-+# S/MIME Attributes
-+id-smime-aa 1		: id-smime-aa-receiptRequest
-+id-smime-aa 2		: id-smime-aa-securityLabel
-+id-smime-aa 3		: id-smime-aa-mlExpandHistory
-+id-smime-aa 4		: id-smime-aa-contentHint
-+id-smime-aa 5		: id-smime-aa-msgSigDigest
-+# obsolete
-+id-smime-aa 6		: id-smime-aa-encapContentType
-+id-smime-aa 7		: id-smime-aa-contentIdentifier
-+# obsolete
-+id-smime-aa 8		: id-smime-aa-macValue
-+id-smime-aa 9		: id-smime-aa-equivalentLabels
-+id-smime-aa 10		: id-smime-aa-contentReference
-+id-smime-aa 11		: id-smime-aa-encrypKeyPref
-+id-smime-aa 12		: id-smime-aa-signingCertificate
-+id-smime-aa 13		: id-smime-aa-smimeEncryptCerts
-+id-smime-aa 14		: id-smime-aa-timeStampToken
-+id-smime-aa 15		: id-smime-aa-ets-sigPolicyId
-+id-smime-aa 16		: id-smime-aa-ets-commitmentType
-+id-smime-aa 17		: id-smime-aa-ets-signerLocation
-+id-smime-aa 18		: id-smime-aa-ets-signerAttr
-+id-smime-aa 19		: id-smime-aa-ets-otherSigCert
-+id-smime-aa 20		: id-smime-aa-ets-contentTimestamp
-+id-smime-aa 21		: id-smime-aa-ets-CertificateRefs
-+id-smime-aa 22		: id-smime-aa-ets-RevocationRefs
-+id-smime-aa 23		: id-smime-aa-ets-certValues
-+id-smime-aa 24		: id-smime-aa-ets-revocationValues
-+id-smime-aa 25		: id-smime-aa-ets-escTimeStamp
-+id-smime-aa 26		: id-smime-aa-ets-certCRLTimestamp
-+id-smime-aa 27		: id-smime-aa-ets-archiveTimeStamp
-+id-smime-aa 28		: id-smime-aa-signatureType
-+id-smime-aa 29		: id-smime-aa-dvcs-dvc
-+
-+# S/MIME Algorithm Identifiers
-+# obsolete
-+id-smime-alg 1		: id-smime-alg-ESDHwith3DES
-+# obsolete
-+id-smime-alg 2		: id-smime-alg-ESDHwithRC2
-+# obsolete
-+id-smime-alg 3		: id-smime-alg-3DESwrap
-+# obsolete
-+id-smime-alg 4		: id-smime-alg-RC2wrap
-+id-smime-alg 5		: id-smime-alg-ESDH
-+id-smime-alg 6		: id-smime-alg-CMS3DESwrap
-+id-smime-alg 7		: id-smime-alg-CMSRC2wrap
-+id-smime-alg 9		: id-alg-PWRI-KEK
-+
-+# S/MIME Certificate Distribution
-+id-smime-cd 1		: id-smime-cd-ldap
-+
-+# S/MIME Signature Policy Qualifier
-+id-smime-spq 1		: id-smime-spq-ets-sqt-uri
-+id-smime-spq 2		: id-smime-spq-ets-sqt-unotice
-+
-+# S/MIME Commitment Type Identifier
-+id-smime-cti 1		: id-smime-cti-ets-proofOfOrigin
-+id-smime-cti 2		: id-smime-cti-ets-proofOfReceipt
-+id-smime-cti 3		: id-smime-cti-ets-proofOfDelivery
-+id-smime-cti 4		: id-smime-cti-ets-proofOfSender
-+id-smime-cti 5		: id-smime-cti-ets-proofOfApproval
-+id-smime-cti 6		: id-smime-cti-ets-proofOfCreation
-+
-+pkcs9 20		:			: friendlyName
-+pkcs9 21		:			: localKeyID
-+!Cname ms-csp-name
-+1 3 6 1 4 1 311 17 1	: CSPName		: Microsoft CSP Name
-+1 3 6 1 4 1 311 17 2	: LocalKeySet		: Microsoft Local Key set
-+!Alias certTypes pkcs9 22
-+certTypes 1		:			: x509Certificate
-+certTypes 2		:			: sdsiCertificate
-+!Alias crlTypes pkcs9 23
-+crlTypes 1		:			: x509Crl
-+
-+!Alias pkcs12 pkcs 12
-+!Alias pkcs12-pbeids pkcs12 1
-+
-+!Cname pbe-WithSHA1And128BitRC4
-+pkcs12-pbeids 1		: PBE-SHA1-RC4-128	: pbeWithSHA1And128BitRC4
-+!Cname pbe-WithSHA1And40BitRC4
-+pkcs12-pbeids 2		: PBE-SHA1-RC4-40	: pbeWithSHA1And40BitRC4
-+!Cname pbe-WithSHA1And3_Key_TripleDES-CBC
-+pkcs12-pbeids 3		: PBE-SHA1-3DES		: pbeWithSHA1And3-KeyTripleDES-CBC
-+!Cname pbe-WithSHA1And2_Key_TripleDES-CBC
-+pkcs12-pbeids 4		: PBE-SHA1-2DES		: pbeWithSHA1And2-KeyTripleDES-CBC
-+!Cname pbe-WithSHA1And128BitRC2-CBC
-+pkcs12-pbeids 5		: PBE-SHA1-RC2-128	: pbeWithSHA1And128BitRC2-CBC
-+!Cname pbe-WithSHA1And40BitRC2-CBC
-+pkcs12-pbeids 6		: PBE-SHA1-RC2-40	: pbeWithSHA1And40BitRC2-CBC
-+
-+!Alias pkcs12-Version1 pkcs12 10
-+!Alias pkcs12-BagIds pkcs12-Version1 1
-+pkcs12-BagIds 1		:			: keyBag
-+pkcs12-BagIds 2		:			: pkcs8ShroudedKeyBag
-+pkcs12-BagIds 3		:			: certBag
-+pkcs12-BagIds 4		:			: crlBag
-+pkcs12-BagIds 5		:			: secretBag
-+pkcs12-BagIds 6		:			: safeContentsBag
-+
-+rsadsi 2 2		: MD2			: md2
-+rsadsi 2 4		: MD4			: md4
-+rsadsi 2 5		: MD5			: md5
-+			: MD5-SHA1		: md5-sha1
-+rsadsi 2 6		:			: hmacWithMD5
-+rsadsi 2 7		:			: hmacWithSHA1
-+
-+# From RFC4231
-+rsadsi 2 8		:			: hmacWithSHA224
-+rsadsi 2 9		:			: hmacWithSHA256
-+rsadsi 2 10		:			: hmacWithSHA384
-+rsadsi 2 11		:			: hmacWithSHA512
-+
-+rsadsi 3 2		: RC2-CBC		: rc2-cbc
-+			: RC2-ECB		: rc2-ecb
-+!Cname rc2-cfb64
-+			: RC2-CFB		: rc2-cfb
-+!Cname rc2-ofb64
-+			: RC2-OFB		: rc2-ofb
-+			: RC2-40-CBC		: rc2-40-cbc
-+			: RC2-64-CBC		: rc2-64-cbc
-+rsadsi 3 4		: RC4			: rc4
-+			: RC4-40		: rc4-40
-+rsadsi 3 7		: DES-EDE3-CBC		: des-ede3-cbc
-+rsadsi 3 8		: RC5-CBC		: rc5-cbc
-+			: RC5-ECB		: rc5-ecb
-+!Cname rc5-cfb64
-+			: RC5-CFB		: rc5-cfb
-+!Cname rc5-ofb64
-+			: RC5-OFB		: rc5-ofb
-+
-+!Cname ms-ext-req
-+1 3 6 1 4 1 311 2 1 14	: msExtReq		: Microsoft Extension Request
-+!Cname ms-code-ind
-+1 3 6 1 4 1 311 2 1 21	: msCodeInd		: Microsoft Individual Code Signing
-+!Cname ms-code-com
-+1 3 6 1 4 1 311 2 1 22	: msCodeCom		: Microsoft Commercial Code Signing
-+!Cname ms-ctl-sign
-+1 3 6 1 4 1 311 10 3 1	: msCTLSign		: Microsoft Trust List Signing
-+!Cname ms-sgc
-+1 3 6 1 4 1 311 10 3 3	: msSGC			: Microsoft Server Gated Crypto
-+!Cname ms-efs
-+1 3 6 1 4 1 311 10 3 4	: msEFS			: Microsoft Encrypted File System
-+!Cname ms-smartcard-login
-+1 3 6 1 4 1 311 20 2 2	: msSmartcardLogin	: Microsoft Smartcardlogin
-+!Cname ms-upn
-+1 3 6 1 4 1 311 20 2 3	: msUPN			: Microsoft Universal Principal Name
-+
-+1 3 6 1 4 1 188 7 1 1 2	: IDEA-CBC		: idea-cbc
-+			: IDEA-ECB		: idea-ecb
-+!Cname idea-cfb64
-+			: IDEA-CFB		: idea-cfb
-+!Cname idea-ofb64
-+			: IDEA-OFB		: idea-ofb
-+
-+1 3 6 1 4 1 3029 1 2	: BF-CBC		: bf-cbc
-+			: BF-ECB		: bf-ecb
-+!Cname bf-cfb64
-+			: BF-CFB		: bf-cfb
-+!Cname bf-ofb64
-+			: BF-OFB		: bf-ofb
-+
-+!Cname id-pkix
-+1 3 6 1 5 5 7		: PKIX
-+
-+# PKIX Arcs
-+id-pkix 0		: id-pkix-mod
-+id-pkix 1		: id-pe
-+id-pkix 2		: id-qt
-+id-pkix 3		: id-kp
-+id-pkix 4		: id-it
-+id-pkix 5		: id-pkip
-+id-pkix 6		: id-alg
-+id-pkix 7		: id-cmc
-+id-pkix 8		: id-on
-+id-pkix 9		: id-pda
-+id-pkix 10		: id-aca
-+id-pkix 11		: id-qcs
-+id-pkix 12		: id-cct
-+id-pkix 21		: id-ppl
-+id-pkix 48		: id-ad
-+
-+# PKIX Modules
-+id-pkix-mod 1		: id-pkix1-explicit-88
-+id-pkix-mod 2		: id-pkix1-implicit-88
-+id-pkix-mod 3		: id-pkix1-explicit-93
-+id-pkix-mod 4		: id-pkix1-implicit-93
-+id-pkix-mod 5		: id-mod-crmf
-+id-pkix-mod 6		: id-mod-cmc
-+id-pkix-mod 7		: id-mod-kea-profile-88
-+id-pkix-mod 8		: id-mod-kea-profile-93
-+id-pkix-mod 9		: id-mod-cmp
-+id-pkix-mod 10		: id-mod-qualified-cert-88
-+id-pkix-mod 11		: id-mod-qualified-cert-93
-+id-pkix-mod 12		: id-mod-attribute-cert
-+id-pkix-mod 13		: id-mod-timestamp-protocol
-+id-pkix-mod 14		: id-mod-ocsp
-+id-pkix-mod 15		: id-mod-dvcs
-+id-pkix-mod 16		: id-mod-cmp2000
-+
-+# PKIX Private Extensions
-+!Cname info-access
-+id-pe 1			: authorityInfoAccess	: Authority Information Access
-+id-pe 2			: biometricInfo		: Biometric Info
-+id-pe 3			: qcStatements
-+id-pe 4			: ac-auditEntity
-+id-pe 5			: ac-targeting
-+id-pe 6			: aaControls
-+id-pe 7			: sbgp-ipAddrBlock
-+id-pe 8			: sbgp-autonomousSysNum
-+id-pe 9			: sbgp-routerIdentifier
-+id-pe 10		: ac-proxying
-+!Cname sinfo-access
-+id-pe 11		: subjectInfoAccess	: Subject Information Access
-+id-pe 14		: proxyCertInfo		: Proxy Certificate Information
-+id-pe 24		: tlsfeature		: TLS Feature
-+
-+# PKIX policyQualifiers for Internet policy qualifiers
-+id-qt 1			: id-qt-cps		: Policy Qualifier CPS
-+id-qt 2			: id-qt-unotice		: Policy Qualifier User Notice
-+id-qt 3			: textNotice
-+
-+# PKIX key purpose identifiers
-+!Cname server-auth
-+id-kp 1			: serverAuth		: TLS Web Server Authentication
-+!Cname client-auth
-+id-kp 2			: clientAuth		: TLS Web Client Authentication
-+!Cname code-sign
-+id-kp 3			: codeSigning		: Code Signing
-+!Cname email-protect
-+id-kp 4			: emailProtection	: E-mail Protection
-+id-kp 5			: ipsecEndSystem	: IPSec End System
-+id-kp 6			: ipsecTunnel		: IPSec Tunnel
-+id-kp 7			: ipsecUser		: IPSec User
-+!Cname time-stamp
-+id-kp 8			: timeStamping		: Time Stamping
-+# From OCSP spec RFC2560
-+!Cname OCSP-sign
-+id-kp 9			: OCSPSigning		: OCSP Signing
-+id-kp 10		: DVCS			: dvcs
-+!Cname ipsec-IKE
-+id-kp 17                : ipsecIKE              : ipsec Internet Key Exchange
-+id-kp 18                : capwapAC              : Ctrl/provision WAP Access
-+id-kp 19                : capwapWTP             : Ctrl/Provision WAP Termination
-+!Cname sshClient
-+id-kp 21                : secureShellClient     : SSH Client
-+!Cname sshServer
-+id-kp 22                : secureShellServer     : SSH Server
-+id-kp 23                : sendRouter            : Send Router
-+id-kp 24                : sendProxiedRouter     : Send Proxied Router
-+id-kp 25                : sendOwner             : Send Owner
-+id-kp 26                : sendProxiedOwner      : Send Proxied Owner
-+
-+# CMP information types
-+id-it 1			: id-it-caProtEncCert
-+id-it 2			: id-it-signKeyPairTypes
-+id-it 3			: id-it-encKeyPairTypes
-+id-it 4			: id-it-preferredSymmAlg
-+id-it 5			: id-it-caKeyUpdateInfo
-+id-it 6			: id-it-currentCRL
-+id-it 7			: id-it-unsupportedOIDs
-+# obsolete
-+id-it 8			: id-it-subscriptionRequest
-+# obsolete
-+id-it 9			: id-it-subscriptionResponse
-+id-it 10		: id-it-keyPairParamReq
-+id-it 11		: id-it-keyPairParamRep
-+id-it 12		: id-it-revPassphrase
-+id-it 13		: id-it-implicitConfirm
-+id-it 14		: id-it-confirmWaitTime
-+id-it 15		: id-it-origPKIMessage
-+id-it 16		: id-it-suppLangTags
-+
-+# CRMF registration
-+id-pkip 1		: id-regCtrl
-+id-pkip 2		: id-regInfo
-+
-+# CRMF registration controls
-+id-regCtrl 1		: id-regCtrl-regToken
-+id-regCtrl 2		: id-regCtrl-authenticator
-+id-regCtrl 3		: id-regCtrl-pkiPublicationInfo
-+id-regCtrl 4		: id-regCtrl-pkiArchiveOptions
-+id-regCtrl 5		: id-regCtrl-oldCertID
-+id-regCtrl 6		: id-regCtrl-protocolEncrKey
-+
-+# CRMF registration information
-+id-regInfo 1		: id-regInfo-utf8Pairs
-+id-regInfo 2		: id-regInfo-certReq
-+
-+# algorithms
-+id-alg 1		: id-alg-des40
-+id-alg 2		: id-alg-noSignature
-+id-alg 3		: id-alg-dh-sig-hmac-sha1
-+id-alg 4		: id-alg-dh-pop
-+
-+# CMC controls
-+id-cmc 1		: id-cmc-statusInfo
-+id-cmc 2		: id-cmc-identification
-+id-cmc 3		: id-cmc-identityProof
-+id-cmc 4		: id-cmc-dataReturn
-+id-cmc 5		: id-cmc-transactionId
-+id-cmc 6		: id-cmc-senderNonce
-+id-cmc 7		: id-cmc-recipientNonce
-+id-cmc 8		: id-cmc-addExtensions
-+id-cmc 9		: id-cmc-encryptedPOP
-+id-cmc 10		: id-cmc-decryptedPOP
-+id-cmc 11		: id-cmc-lraPOPWitness
-+id-cmc 15		: id-cmc-getCert
-+id-cmc 16		: id-cmc-getCRL
-+id-cmc 17		: id-cmc-revokeRequest
-+id-cmc 18		: id-cmc-regInfo
-+id-cmc 19		: id-cmc-responseInfo
-+id-cmc 21		: id-cmc-queryPending
-+id-cmc 22		: id-cmc-popLinkRandom
-+id-cmc 23		: id-cmc-popLinkWitness
-+id-cmc 24		: id-cmc-confirmCertAcceptance 
-+
-+# other names
-+id-on 1			: id-on-personalData
-+id-on 3			: id-on-permanentIdentifier : Permanent Identifier
-+
-+# personal data attributes
-+id-pda 1		: id-pda-dateOfBirth
-+id-pda 2		: id-pda-placeOfBirth
-+id-pda 3		: id-pda-gender
-+id-pda 4		: id-pda-countryOfCitizenship
-+id-pda 5		: id-pda-countryOfResidence
-+
-+# attribute certificate attributes
-+id-aca 1		: id-aca-authenticationInfo
-+id-aca 2		: id-aca-accessIdentity
-+id-aca 3		: id-aca-chargingIdentity
-+id-aca 4		: id-aca-group
-+# attention : the following seems to be obsolete, replace by 'role'
-+id-aca 5		: id-aca-role
-+id-aca 6		: id-aca-encAttrs
-+
-+# qualified certificate statements
-+id-qcs 1		: id-qcs-pkixQCSyntax-v1
-+
-+# CMC content types
-+id-cct 1		: id-cct-crs
-+id-cct 2		: id-cct-PKIData
-+id-cct 3		: id-cct-PKIResponse
-+
-+# Predefined Proxy Certificate policy languages
-+id-ppl 0		: id-ppl-anyLanguage	: Any language
-+id-ppl 1		: id-ppl-inheritAll	: Inherit all
-+id-ppl 2		: id-ppl-independent	: Independent
-+
-+# access descriptors for authority info access extension
-+!Cname ad-OCSP
-+id-ad 1			: OCSP			: OCSP
-+!Cname ad-ca-issuers
-+id-ad 2			: caIssuers		: CA Issuers
-+!Cname ad-timeStamping
-+id-ad 3			: ad_timestamping	: AD Time Stamping
-+!Cname ad-dvcs
-+id-ad 4			: AD_DVCS		: ad dvcs
-+id-ad 5			: caRepository		: CA Repository
-+
-+
-+!Alias id-pkix-OCSP ad-OCSP
-+!module id-pkix-OCSP
-+!Cname basic
-+id-pkix-OCSP 1		: basicOCSPResponse	: Basic OCSP Response
-+id-pkix-OCSP 2		: Nonce			: OCSP Nonce
-+id-pkix-OCSP 3		: CrlID			: OCSP CRL ID
-+id-pkix-OCSP 4		: acceptableResponses	: Acceptable OCSP Responses
-+id-pkix-OCSP 5		: noCheck		: OCSP No Check
-+id-pkix-OCSP 6		: archiveCutoff		: OCSP Archive Cutoff
-+id-pkix-OCSP 7		: serviceLocator	: OCSP Service Locator
-+id-pkix-OCSP 8		: extendedStatus	: Extended OCSP Status
-+id-pkix-OCSP 9		: valid
-+id-pkix-OCSP 10		: path
-+id-pkix-OCSP 11		: trustRoot		: Trust Root
-+!global
-+
-+1 3 14 3 2		: algorithm		: algorithm
-+algorithm 3		: RSA-NP-MD5		: md5WithRSA
-+algorithm 6		: DES-ECB		: des-ecb
-+algorithm 7		: DES-CBC		: des-cbc
-+!Cname des-ofb64
-+algorithm 8		: DES-OFB		: des-ofb
-+!Cname des-cfb64
-+algorithm 9		: DES-CFB		: des-cfb
-+algorithm 11		: rsaSignature
-+!Cname dsa-2
-+algorithm 12		: DSA-old		: dsaEncryption-old
-+algorithm 13		: DSA-SHA		: dsaWithSHA
-+algorithm 15		: RSA-SHA		: shaWithRSAEncryption
-+!Cname des-ede-ecb
-+algorithm 17		: DES-EDE		: des-ede
-+!Cname des-ede3-ecb
-+			: DES-EDE3		: des-ede3
-+			: DES-EDE-CBC		: des-ede-cbc
-+!Cname des-ede-cfb64
-+			: DES-EDE-CFB		: des-ede-cfb
-+!Cname des-ede3-cfb64
-+			: DES-EDE3-CFB		: des-ede3-cfb
-+!Cname des-ede-ofb64
-+			: DES-EDE-OFB		: des-ede-ofb
-+!Cname des-ede3-ofb64
-+			: DES-EDE3-OFB		: des-ede3-ofb
-+			: DESX-CBC		: desx-cbc
-+algorithm 18		: SHA			: sha
-+algorithm 26		: SHA1			: sha1
-+!Cname dsaWithSHA1-2
-+algorithm 27		: DSA-SHA1-old		: dsaWithSHA1-old
-+algorithm 29		: RSA-SHA1-2		: sha1WithRSA
-+
-+1 3 36 3 2 1		: RIPEMD160		: ripemd160
-+1 3 36 3 3 1 2		: RSA-RIPEMD160		: ripemd160WithRSA
-+
-+1 3 6 1 4 1 1722 12 2 1 16 : BLAKE2b512        : blake2b512
-+1 3 6 1 4 1 1722 12 2 2 8  : BLAKE2s256        : blake2s256
-+
-+!Cname sxnet
-+1 3 101 1 4 1		: SXNetID		: Strong Extranet ID
-+
-+2 5			: X500			: directory services (X.500)
-+
-+X500 4			: X509
-+X509 3			: CN			: commonName
-+X509 4			: SN			: surname
-+X509 5			: 			: serialNumber
-+X509 6			: C			: countryName
-+X509 7			: L			: localityName
-+X509 8			: ST			: stateOrProvinceName
-+X509 9			: street		: streetAddress
-+X509 10			: O			: organizationName
-+X509 11			: OU			: organizationalUnitName
-+X509 12			: title			: title
-+X509 13			: 			: description
-+X509 14			: 			: searchGuide
-+X509 15			: 			: businessCategory
-+X509 16			: 			: postalAddress
-+X509 17			: 			: postalCode
-+X509 18			: 			: postOfficeBox
-+X509 19			: 			: physicalDeliveryOfficeName
-+X509 20			: 			: telephoneNumber
-+X509 21			: 			: telexNumber
-+X509 22			: 			: teletexTerminalIdentifier
-+X509 23			: 			: facsimileTelephoneNumber
-+X509 24			: 			: x121Address
-+X509 25			: 			: internationaliSDNNumber
-+X509 26			: 			: registeredAddress
-+X509 27			: 			: destinationIndicator
-+X509 28			: 			: preferredDeliveryMethod
-+X509 29			: 			: presentationAddress
-+X509 30			: 			: supportedApplicationContext
-+X509 31			: member		:
-+X509 32			: owner			:
-+X509 33			: 			: roleOccupant
-+X509 34			: seeAlso		:
-+X509 35			: 			: userPassword
-+X509 36			: 			: userCertificate
-+X509 37			: 			: cACertificate
-+X509 38			: 			: authorityRevocationList
-+X509 39			: 			: certificateRevocationList
-+X509 40			: 			: crossCertificatePair
-+X509 41			: name			: name
-+X509 42			: GN			: givenName
-+X509 43			: initials		: initials
-+X509 44			: 			: generationQualifier
-+X509 45			: 			: x500UniqueIdentifier
-+X509 46			: dnQualifier		: dnQualifier
-+X509 47			: 			: enhancedSearchGuide
-+X509 48			: 			: protocolInformation
-+X509 49			: 			: distinguishedName
-+X509 50			: 			: uniqueMember
-+X509 51			: 			: houseIdentifier
-+X509 52			: 			: supportedAlgorithms
-+X509 53			: 			: deltaRevocationList
-+X509 54			: dmdName		:
-+X509 65			:			: pseudonym
-+X509 72			: role			: role
-+
-+X500 8			: X500algorithms	: directory services - algorithms
-+X500algorithms 1 1	: RSA			: rsa
-+X500algorithms 3 100	: RSA-MDC2		: mdc2WithRSA
-+X500algorithms 3 101	: MDC2			: mdc2
-+
-+X500 29			: id-ce
-+!Cname subject-directory-attributes
-+id-ce 9			: subjectDirectoryAttributes : X509v3 Subject Directory Attributes
-+!Cname subject-key-identifier
-+id-ce 14		: subjectKeyIdentifier	: X509v3 Subject Key Identifier
-+!Cname key-usage
-+id-ce 15		: keyUsage		: X509v3 Key Usage
-+!Cname private-key-usage-period
-+id-ce 16		: privateKeyUsagePeriod	: X509v3 Private Key Usage Period
-+!Cname subject-alt-name
-+id-ce 17		: subjectAltName	: X509v3 Subject Alternative Name
-+!Cname issuer-alt-name
-+id-ce 18		: issuerAltName		: X509v3 Issuer Alternative Name
-+!Cname basic-constraints
-+id-ce 19		: basicConstraints	: X509v3 Basic Constraints
-+!Cname crl-number
-+id-ce 20		: crlNumber		: X509v3 CRL Number
-+!Cname crl-reason
-+id-ce 21		: CRLReason		: X509v3 CRL Reason Code
-+!Cname invalidity-date
-+id-ce 24		: invalidityDate	: Invalidity Date
-+!Cname delta-crl
-+id-ce 27		: deltaCRL		: X509v3 Delta CRL Indicator
-+!Cname issuing-distribution-point
-+id-ce 28		: issuingDistributionPoint : X509v3 Issuing Distribution Point
-+!Cname certificate-issuer
-+id-ce 29		: certificateIssuer	: X509v3 Certificate Issuer
-+!Cname name-constraints
-+id-ce 30		: nameConstraints	: X509v3 Name Constraints
-+!Cname crl-distribution-points
-+id-ce 31		: crlDistributionPoints	: X509v3 CRL Distribution Points
-+!Cname certificate-policies
-+id-ce 32		: certificatePolicies	: X509v3 Certificate Policies
-+!Cname any-policy
-+certificate-policies 0	: anyPolicy		: X509v3 Any Policy
-+!Cname policy-mappings
-+id-ce 33		: policyMappings	: X509v3 Policy Mappings
-+!Cname authority-key-identifier
-+id-ce 35		: authorityKeyIdentifier : X509v3 Authority Key Identifier
-+!Cname policy-constraints
-+id-ce 36		: policyConstraints	: X509v3 Policy Constraints
-+!Cname ext-key-usage
-+id-ce 37		: extendedKeyUsage	: X509v3 Extended Key Usage
-+!Cname freshest-crl
-+id-ce 46		: freshestCRL		: X509v3 Freshest CRL
-+!Cname inhibit-any-policy
-+id-ce 54		: inhibitAnyPolicy	: X509v3 Inhibit Any Policy
-+!Cname target-information
-+id-ce 55		: targetInformation	: X509v3 AC Targeting
-+!Cname no-rev-avail
-+id-ce 56		: noRevAvail		: X509v3 No Revocation Available
-+
-+# From RFC5280
-+ext-key-usage 0		: anyExtendedKeyUsage	: Any Extended Key Usage
-+
-+
-+!Cname netscape
-+2 16 840 1 113730	: Netscape		: Netscape Communications Corp.
-+!Cname netscape-cert-extension
-+netscape 1		: nsCertExt		: Netscape Certificate Extension
-+!Cname netscape-data-type
-+netscape 2		: nsDataType		: Netscape Data Type
-+!Cname netscape-cert-type
-+netscape-cert-extension 1 : nsCertType		: Netscape Cert Type
-+!Cname netscape-base-url
-+netscape-cert-extension 2 : nsBaseUrl		: Netscape Base Url
-+!Cname netscape-revocation-url
-+netscape-cert-extension 3 : nsRevocationUrl	: Netscape Revocation Url
-+!Cname netscape-ca-revocation-url
-+netscape-cert-extension 4 : nsCaRevocationUrl	: Netscape CA Revocation Url
-+!Cname netscape-renewal-url
-+netscape-cert-extension 7 : nsRenewalUrl	: Netscape Renewal Url
-+!Cname netscape-ca-policy-url
-+netscape-cert-extension 8 : nsCaPolicyUrl	: Netscape CA Policy Url
-+!Cname netscape-ssl-server-name
-+netscape-cert-extension 12 : nsSslServerName	: Netscape SSL Server Name
-+!Cname netscape-comment
-+netscape-cert-extension 13 : nsComment		: Netscape Comment
-+!Cname netscape-cert-sequence
-+netscape-data-type 5	: nsCertSequence	: Netscape Certificate Sequence
-+!Cname ns-sgc
-+netscape 4 1		: nsSGC			: Netscape Server Gated Crypto
-+
-+# iso(1)
-+iso 3			: ORG			: org
-+org 6			: DOD			: dod
-+dod 1			: IANA			: iana
-+!Alias internet iana
-+
-+internet 1		: directory		: Directory
-+internet 2		: mgmt			: Management
-+internet 3		: experimental		: Experimental
-+internet 4		: private		: Private
-+internet 5		: security		: Security
-+internet 6		: snmpv2		: SNMPv2
-+# Documents refer to "internet 7" as "mail". This however leads to ambiguities
-+# with RFC2798, Section 9.1.3, where "mail" is defined as the short name for
-+# rfc822Mailbox. The short name is therefore here left out for a reason.
-+# Subclasses of "mail", e.g. "MIME MHS" don't consitute a problem, as
-+# references are realized via long name "Mail" (with capital M).
-+internet 7		:			: Mail
-+
-+Private 1		: enterprises		: Enterprises
-+
-+# RFC 2247
-+Enterprises 1466 344	: dcobject		: dcObject
-+
-+# RFC 1495
-+Mail 1			: mime-mhs		: MIME MHS
-+mime-mhs 1		: mime-mhs-headings	: mime-mhs-headings
-+mime-mhs 2		: mime-mhs-bodies	: mime-mhs-bodies
-+mime-mhs-headings 1	: id-hex-partial-message : id-hex-partial-message
-+mime-mhs-headings 2	: id-hex-multipart-message : id-hex-multipart-message
-+
-+# RFC 3274
-+!Cname zlib-compression
-+id-smime-alg 8		: ZLIB			: zlib compression
-+
-+# AES aka Rijndael
-+
-+!Alias csor 2 16 840 1 101 3
-+!Alias nistAlgorithms csor 4
-+!Alias aes nistAlgorithms 1
-+
-+aes 1			: AES-128-ECB		: aes-128-ecb
-+aes 2			: AES-128-CBC		: aes-128-cbc
-+!Cname aes-128-ofb128
-+aes 3			: AES-128-OFB		: aes-128-ofb
-+!Cname aes-128-cfb128
-+aes 4			: AES-128-CFB		: aes-128-cfb
-+aes 5			: id-aes128-wrap
-+aes 6			: id-aes128-GCM		: aes-128-gcm
-+aes 7			: id-aes128-CCM		: aes-128-ccm
-+aes 8			: id-aes128-wrap-pad
-+
-+aes 21			: AES-192-ECB		: aes-192-ecb
-+aes 22			: AES-192-CBC		: aes-192-cbc
-+!Cname aes-192-ofb128
-+aes 23			: AES-192-OFB		: aes-192-ofb
-+!Cname aes-192-cfb128
-+aes 24			: AES-192-CFB		: aes-192-cfb
-+aes 25			: id-aes192-wrap
-+aes 26			: id-aes192-GCM		: aes-192-gcm
-+aes 27			: id-aes192-CCM		: aes-192-ccm
-+aes 28			: id-aes192-wrap-pad
-+
-+aes 41			: AES-256-ECB		: aes-256-ecb
-+aes 42			: AES-256-CBC		: aes-256-cbc
-+!Cname aes-256-ofb128
-+aes 43			: AES-256-OFB		: aes-256-ofb
-+!Cname aes-256-cfb128
-+aes 44			: AES-256-CFB		: aes-256-cfb
-+aes 45			: id-aes256-wrap
-+aes 46			: id-aes256-GCM		: aes-256-gcm
-+aes 47			: id-aes256-CCM		: aes-256-ccm
-+aes 48			: id-aes256-wrap-pad
-+
-+# There are no OIDs for these modes...
-+
-+			: AES-128-CFB1		: aes-128-cfb1
-+			: AES-192-CFB1		: aes-192-cfb1
-+			: AES-256-CFB1		: aes-256-cfb1
-+			: AES-128-CFB8		: aes-128-cfb8
-+			: AES-192-CFB8		: aes-192-cfb8
-+			: AES-256-CFB8		: aes-256-cfb8
-+			: AES-128-CTR		: aes-128-ctr
-+			: AES-192-CTR		: aes-192-ctr
-+			: AES-256-CTR		: aes-256-ctr
-+			: AES-128-OCB		: aes-128-ocb
-+			: AES-192-OCB		: aes-192-ocb
-+			: AES-256-OCB		: aes-256-ocb
-+			: AES-128-XTS		: aes-128-xts
-+			: AES-256-XTS		: aes-256-xts
-+			: DES-CFB1		: des-cfb1
-+			: DES-CFB8		: des-cfb8
-+			: DES-EDE3-CFB1		: des-ede3-cfb1
-+			: DES-EDE3-CFB8		: des-ede3-cfb8
-+
-+# OIDs for SHA224, SHA256, SHA385 and SHA512, according to x9.84.
-+!Alias nist_hashalgs nistAlgorithms 2
-+nist_hashalgs 1		: SHA256		: sha256
-+nist_hashalgs 2		: SHA384		: sha384
-+nist_hashalgs 3		: SHA512		: sha512
-+nist_hashalgs 4		: SHA224		: sha224
-+
-+# OIDs for dsa-with-sha224 and dsa-with-sha256
-+!Alias dsa_with_sha2 nistAlgorithms 3
-+dsa_with_sha2 1		: dsa_with_SHA224
-+dsa_with_sha2 2		: dsa_with_SHA256
-+
-+# Hold instruction CRL entry extension
-+!Cname hold-instruction-code
-+id-ce 23		: holdInstructionCode	: Hold Instruction Code
-+!Alias holdInstruction	X9-57 2
-+!Cname hold-instruction-none
-+holdInstruction 1	: holdInstructionNone	: Hold Instruction None
-+!Cname hold-instruction-call-issuer
-+holdInstruction 2	: holdInstructionCallIssuer : Hold Instruction Call Issuer
-+!Cname hold-instruction-reject
-+holdInstruction 3	: holdInstructionReject	: Hold Instruction Reject
-+
-+# OID's from ITU-T.  Most of this is defined in RFC 1274.  A couple of
-+# them are also mentioned in RFC 2247
-+itu-t 9			: data
-+data 2342		: pss
-+pss 19200300		: ucl
-+ucl 100			: pilot
-+pilot 1			:			: pilotAttributeType
-+pilot 3			:			: pilotAttributeSyntax
-+pilot 4			:			: pilotObjectClass
-+pilot 10		:			: pilotGroups
-+pilotAttributeSyntax 4	:			: iA5StringSyntax
-+pilotAttributeSyntax 5	:			: caseIgnoreIA5StringSyntax
-+pilotObjectClass 3	:			: pilotObject
-+pilotObjectClass 4	:			: pilotPerson
-+pilotObjectClass 5	: account
-+pilotObjectClass 6	: document
-+pilotObjectClass 7	: room
-+pilotObjectClass 9	:			: documentSeries
-+pilotObjectClass 13	: domain		: Domain
-+pilotObjectClass 14	:			: rFC822localPart
-+pilotObjectClass 15	:			: dNSDomain
-+pilotObjectClass 17	:			: domainRelatedObject
-+pilotObjectClass 18	:			: friendlyCountry
-+pilotObjectClass 19	:			: simpleSecurityObject
-+pilotObjectClass 20	:			: pilotOrganization
-+pilotObjectClass 21	:			: pilotDSA
-+pilotObjectClass 22	:			: qualityLabelledData
-+pilotAttributeType 1	: UID			: userId
-+pilotAttributeType 2	:			: textEncodedORAddress
-+pilotAttributeType 3	: mail			: rfc822Mailbox
-+pilotAttributeType 4	: info
-+pilotAttributeType 5	:			: favouriteDrink
-+pilotAttributeType 6	:			: roomNumber
-+pilotAttributeType 7	: photo
-+pilotAttributeType 8	:			: userClass
-+pilotAttributeType 9	: host
-+pilotAttributeType 10	: manager
-+pilotAttributeType 11	:			: documentIdentifier
-+pilotAttributeType 12	:			: documentTitle
-+pilotAttributeType 13	:			: documentVersion
-+pilotAttributeType 14	:			: documentAuthor
-+pilotAttributeType 15	:			: documentLocation
-+pilotAttributeType 20	:			: homeTelephoneNumber
-+pilotAttributeType 21	: secretary
-+pilotAttributeType 22	:			: otherMailbox
-+pilotAttributeType 23	:			: lastModifiedTime
-+pilotAttributeType 24	:			: lastModifiedBy
-+pilotAttributeType 25	: DC			: domainComponent
-+pilotAttributeType 26	:			: aRecord
-+pilotAttributeType 27	:			: pilotAttributeType27
-+pilotAttributeType 28	:			: mXRecord
-+pilotAttributeType 29	:			: nSRecord
-+pilotAttributeType 30	:			: sOARecord
-+pilotAttributeType 31	:			: cNAMERecord
-+pilotAttributeType 37	:			: associatedDomain
-+pilotAttributeType 38	:			: associatedName
-+pilotAttributeType 39	:			: homePostalAddress
-+pilotAttributeType 40	:			: personalTitle
-+pilotAttributeType 41	:			: mobileTelephoneNumber
-+pilotAttributeType 42	:			: pagerTelephoneNumber
-+pilotAttributeType 43	:			: friendlyCountryName
-+pilotAttributeType 44	: uid			: uniqueIdentifier
-+pilotAttributeType 45	:			: organizationalStatus
-+pilotAttributeType 46	:			: janetMailbox
-+pilotAttributeType 47	:			: mailPreferenceOption
-+pilotAttributeType 48	:			: buildingName
-+pilotAttributeType 49	:			: dSAQuality
-+pilotAttributeType 50	:			: singleLevelQuality
-+pilotAttributeType 51	:			: subtreeMinimumQuality
-+pilotAttributeType 52	:			: subtreeMaximumQuality
-+pilotAttributeType 53	:			: personalSignature
-+pilotAttributeType 54	:			: dITRedirect
-+pilotAttributeType 55	: audio
-+pilotAttributeType 56	:			: documentPublisher
-+
-+international-organizations 42	: id-set	: Secure Electronic Transactions
-+
-+id-set 0		: set-ctype		: content types
-+id-set 1		: set-msgExt		: message extensions
-+id-set 3		: set-attr
-+id-set 5		: set-policy
-+id-set 7		: set-certExt		: certificate extensions
-+id-set 8		: set-brand
-+
-+set-ctype 0		: setct-PANData
-+set-ctype 1		: setct-PANToken
-+set-ctype 2		: setct-PANOnly
-+set-ctype 3		: setct-OIData
-+set-ctype 4		: setct-PI
-+set-ctype 5		: setct-PIData
-+set-ctype 6		: setct-PIDataUnsigned
-+set-ctype 7		: setct-HODInput
-+set-ctype 8		: setct-AuthResBaggage
-+set-ctype 9		: setct-AuthRevReqBaggage
-+set-ctype 10		: setct-AuthRevResBaggage
-+set-ctype 11		: setct-CapTokenSeq
-+set-ctype 12		: setct-PInitResData
-+set-ctype 13		: setct-PI-TBS
-+set-ctype 14		: setct-PResData
-+set-ctype 16		: setct-AuthReqTBS
-+set-ctype 17		: setct-AuthResTBS
-+set-ctype 18		: setct-AuthResTBSX
-+set-ctype 19		: setct-AuthTokenTBS
-+set-ctype 20		: setct-CapTokenData
-+set-ctype 21		: setct-CapTokenTBS
-+set-ctype 22		: setct-AcqCardCodeMsg
-+set-ctype 23		: setct-AuthRevReqTBS
-+set-ctype 24		: setct-AuthRevResData
-+set-ctype 25		: setct-AuthRevResTBS
-+set-ctype 26		: setct-CapReqTBS
-+set-ctype 27		: setct-CapReqTBSX
-+set-ctype 28		: setct-CapResData
-+set-ctype 29		: setct-CapRevReqTBS
-+set-ctype 30		: setct-CapRevReqTBSX
-+set-ctype 31		: setct-CapRevResData
-+set-ctype 32		: setct-CredReqTBS
-+set-ctype 33		: setct-CredReqTBSX
-+set-ctype 34		: setct-CredResData
-+set-ctype 35		: setct-CredRevReqTBS
-+set-ctype 36		: setct-CredRevReqTBSX
-+set-ctype 37		: setct-CredRevResData
-+set-ctype 38		: setct-PCertReqData
-+set-ctype 39		: setct-PCertResTBS
-+set-ctype 40		: setct-BatchAdminReqData
-+set-ctype 41		: setct-BatchAdminResData
-+set-ctype 42		: setct-CardCInitResTBS
-+set-ctype 43		: setct-MeAqCInitResTBS
-+set-ctype 44		: setct-RegFormResTBS
-+set-ctype 45		: setct-CertReqData
-+set-ctype 46		: setct-CertReqTBS
-+set-ctype 47		: setct-CertResData
-+set-ctype 48		: setct-CertInqReqTBS
-+set-ctype 49		: setct-ErrorTBS
-+set-ctype 50		: setct-PIDualSignedTBE
-+set-ctype 51		: setct-PIUnsignedTBE
-+set-ctype 52		: setct-AuthReqTBE
-+set-ctype 53		: setct-AuthResTBE
-+set-ctype 54		: setct-AuthResTBEX
-+set-ctype 55		: setct-AuthTokenTBE
-+set-ctype 56		: setct-CapTokenTBE
-+set-ctype 57		: setct-CapTokenTBEX
-+set-ctype 58		: setct-AcqCardCodeMsgTBE
-+set-ctype 59		: setct-AuthRevReqTBE
-+set-ctype 60		: setct-AuthRevResTBE
-+set-ctype 61		: setct-AuthRevResTBEB
-+set-ctype 62		: setct-CapReqTBE
-+set-ctype 63		: setct-CapReqTBEX
-+set-ctype 64		: setct-CapResTBE
-+set-ctype 65		: setct-CapRevReqTBE
-+set-ctype 66		: setct-CapRevReqTBEX
-+set-ctype 67		: setct-CapRevResTBE
-+set-ctype 68		: setct-CredReqTBE
-+set-ctype 69		: setct-CredReqTBEX
-+set-ctype 70		: setct-CredResTBE
-+set-ctype 71		: setct-CredRevReqTBE
-+set-ctype 72		: setct-CredRevReqTBEX
-+set-ctype 73		: setct-CredRevResTBE
-+set-ctype 74		: setct-BatchAdminReqTBE
-+set-ctype 75		: setct-BatchAdminResTBE
-+set-ctype 76		: setct-RegFormReqTBE
-+set-ctype 77		: setct-CertReqTBE
-+set-ctype 78		: setct-CertReqTBEX
-+set-ctype 79		: setct-CertResTBE
-+set-ctype 80		: setct-CRLNotificationTBS
-+set-ctype 81		: setct-CRLNotificationResTBS
-+set-ctype 82		: setct-BCIDistributionTBS
-+
-+set-msgExt 1		: setext-genCrypt	: generic cryptogram
-+set-msgExt 3		: setext-miAuth		: merchant initiated auth
-+set-msgExt 4		: setext-pinSecure
-+set-msgExt 5		: setext-pinAny
-+set-msgExt 7		: setext-track2
-+set-msgExt 8		: setext-cv		: additional verification
-+
-+set-policy 0		: set-policy-root
-+
-+set-certExt 0		: setCext-hashedRoot
-+set-certExt 1		: setCext-certType
-+set-certExt 2		: setCext-merchData
-+set-certExt 3		: setCext-cCertRequired
-+set-certExt 4		: setCext-tunneling
-+set-certExt 5		: setCext-setExt
-+set-certExt 6		: setCext-setQualf
-+set-certExt 7		: setCext-PGWYcapabilities
-+set-certExt 8		: setCext-TokenIdentifier
-+set-certExt 9		: setCext-Track2Data
-+set-certExt 10		: setCext-TokenType
-+set-certExt 11		: setCext-IssuerCapabilities
-+
-+set-attr 0		: setAttr-Cert
-+set-attr 1		: setAttr-PGWYcap	: payment gateway capabilities
-+set-attr 2		: setAttr-TokenType
-+set-attr 3		: setAttr-IssCap	: issuer capabilities
-+
-+setAttr-Cert 0		: set-rootKeyThumb
-+setAttr-Cert 1		: set-addPolicy
-+
-+setAttr-TokenType 1	: setAttr-Token-EMV
-+setAttr-TokenType 2	: setAttr-Token-B0Prime
-+
-+setAttr-IssCap 3	: setAttr-IssCap-CVM
-+setAttr-IssCap 4	: setAttr-IssCap-T2
-+setAttr-IssCap 5	: setAttr-IssCap-Sig
-+
-+setAttr-IssCap-CVM 1	: setAttr-GenCryptgrm	: generate cryptogram
-+setAttr-IssCap-T2 1	: setAttr-T2Enc		: encrypted track 2
-+setAttr-IssCap-T2 2	: setAttr-T2cleartxt	: cleartext track 2
-+
-+setAttr-IssCap-Sig 1	: setAttr-TokICCsig	: ICC or token signature
-+setAttr-IssCap-Sig 2	: setAttr-SecDevSig	: secure device signature
-+
-+set-brand 1		: set-brand-IATA-ATA
-+set-brand 30		: set-brand-Diners
-+set-brand 34		: set-brand-AmericanExpress
-+set-brand 35		: set-brand-JCB
-+set-brand 4		: set-brand-Visa
-+set-brand 5		: set-brand-MasterCard
-+set-brand 6011		: set-brand-Novus
-+
-+rsadsi 3 10		: DES-CDMF		: des-cdmf
-+rsadsi 1 1 6		: rsaOAEPEncryptionSET
-+
-+			: Oakley-EC2N-3		: ipsec3
-+			: Oakley-EC2N-4		: ipsec4
-+
-+iso 0 10118 3 0 55	: whirlpool
-+
-+# GOST OIDs
-+
-+member-body 643 2 2	: cryptopro
-+member-body 643 2 9	: cryptocom
-+member-body 643 7 1	: id-tc26
-+
-+cryptopro 3		: id-GostR3411-94-with-GostR3410-2001 : GOST R 34.11-94 with GOST R 34.10-2001
-+cryptopro 4		: id-GostR3411-94-with-GostR3410-94 : GOST R 34.11-94 with GOST R 34.10-94
-+!Cname id-GostR3411-94
-+cryptopro 9		: md_gost94		: GOST R 34.11-94
-+cryptopro 10		: id-HMACGostR3411-94	: HMAC GOST 34.11-94
-+!Cname id-GostR3410-2001
-+cryptopro 19		: gost2001	: GOST R 34.10-2001
-+!Cname id-GostR3410-94
-+cryptopro 20		: gost94	: GOST R 34.10-94
-+!Cname id-Gost28147-89
-+cryptopro 21		: gost89 		: GOST 28147-89
-+			: gost89-cnt
-+			: gost89-cnt-12
-+			: gost89-cbc
-+			: gost89-ecb
-+			: gost89-ctr
-+!Cname id-Gost28147-89-MAC
-+cryptopro 22		: gost-mac	: GOST 28147-89 MAC
-+			: gost-mac-12
-+!Cname id-GostR3411-94-prf
-+cryptopro 23		: prf-gostr3411-94	: GOST R 34.11-94 PRF
-+cryptopro 98		: id-GostR3410-2001DH	: GOST R 34.10-2001 DH
-+cryptopro 99		: id-GostR3410-94DH	: GOST R 34.10-94 DH
-+
-+cryptopro 14 1		: id-Gost28147-89-CryptoPro-KeyMeshing
-+cryptopro 14 0		: id-Gost28147-89-None-KeyMeshing
-+
-+# GOST parameter set OIDs
-+
-+cryptopro 30 0		: id-GostR3411-94-TestParamSet
-+cryptopro 30 1		: id-GostR3411-94-CryptoProParamSet
-+
-+cryptopro 31 0		: id-Gost28147-89-TestParamSet
-+cryptopro 31 1		: id-Gost28147-89-CryptoPro-A-ParamSet
-+cryptopro 31 2		: id-Gost28147-89-CryptoPro-B-ParamSet
-+cryptopro 31 3		: id-Gost28147-89-CryptoPro-C-ParamSet
-+cryptopro 31 4		: id-Gost28147-89-CryptoPro-D-ParamSet
-+cryptopro 31 5		: id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet
-+cryptopro 31 6		: id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet
-+cryptopro 31 7		: id-Gost28147-89-CryptoPro-RIC-1-ParamSet
-+
-+cryptopro 32 0		: id-GostR3410-94-TestParamSet
-+cryptopro 32 2		: id-GostR3410-94-CryptoPro-A-ParamSet
-+cryptopro 32 3		: id-GostR3410-94-CryptoPro-B-ParamSet
-+cryptopro 32 4		: id-GostR3410-94-CryptoPro-C-ParamSet
-+cryptopro 32 5		: id-GostR3410-94-CryptoPro-D-ParamSet
-+
-+cryptopro 33 1		: id-GostR3410-94-CryptoPro-XchA-ParamSet
-+cryptopro 33 2		: id-GostR3410-94-CryptoPro-XchB-ParamSet
-+cryptopro 33 3		: id-GostR3410-94-CryptoPro-XchC-ParamSet
-+
-+cryptopro 35 0		: id-GostR3410-2001-TestParamSet
-+cryptopro 35 1		: id-GostR3410-2001-CryptoPro-A-ParamSet
-+cryptopro 35 2		: id-GostR3410-2001-CryptoPro-B-ParamSet
-+cryptopro 35 3		: id-GostR3410-2001-CryptoPro-C-ParamSet
-+
-+cryptopro 36 0		: id-GostR3410-2001-CryptoPro-XchA-ParamSet
-+cryptopro 36 1		: id-GostR3410-2001-CryptoPro-XchB-ParamSet
-+
-+id-GostR3410-94 1	: id-GostR3410-94-a
-+id-GostR3410-94 2	: id-GostR3410-94-aBis
-+id-GostR3410-94 3	: id-GostR3410-94-b
-+id-GostR3410-94 4	: id-GostR3410-94-bBis
-+
-+# Cryptocom LTD GOST OIDs
-+
-+cryptocom 1 6 1		: id-Gost28147-89-cc	: GOST 28147-89 Cryptocom ParamSet
-+!Cname id-GostR3410-94-cc
-+cryptocom 1 5 3		: gost94cc	: GOST 34.10-94 Cryptocom
-+!Cname id-GostR3410-2001-cc
-+cryptocom 1 5 4		: gost2001cc	: GOST 34.10-2001 Cryptocom
-+
-+cryptocom 1 3 3		: id-GostR3411-94-with-GostR3410-94-cc : GOST R 34.11-94 with GOST R 34.10-94 Cryptocom
-+cryptocom 1 3 4		: id-GostR3411-94-with-GostR3410-2001-cc : GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom
-+
-+cryptocom 1 8 1		: id-GostR3410-2001-ParamSet-cc : GOST R 3410-2001 Parameter Set Cryptocom
-+
-+# TC26 GOST OIDs
-+
-+id-tc26 1 		: id-tc26-algorithms
-+id-tc26-algorithms 1	: id-tc26-sign
-+!Cname id-GostR3410-2012-256
-+id-tc26-sign 1		: gost2012_256: GOST R 34.10-2012 with 256 bit modulus
-+!Cname id-GostR3410-2012-512
-+id-tc26-sign 2		: gost2012_512: GOST R 34.10-2012 with 512 bit modulus
-+
-+id-tc26-algorithms 2	: id-tc26-digest
-+!Cname id-GostR3411-2012-256
-+id-tc26-digest 2	: md_gost12_256: GOST R 34.11-2012 with 256 bit hash
-+!Cname id-GostR3411-2012-512
-+id-tc26-digest 3	: md_gost12_512: GOST R 34.11-2012 with 512 bit hash
-+
-+id-tc26-algorithms 3	: id-tc26-signwithdigest
-+id-tc26-signwithdigest 2: id-tc26-signwithdigest-gost3410-2012-256: GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)
-+id-tc26-signwithdigest 3: id-tc26-signwithdigest-gost3410-2012-512: GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)
-+
-+id-tc26-algorithms 4	: id-tc26-mac
-+id-tc26-mac 1		: id-tc26-hmac-gost-3411-2012-256 : HMAC GOST 34.11-2012 256 bit
-+id-tc26-mac 2		: id-tc26-hmac-gost-3411-2012-512 : HMAC GOST 34.11-2012 512 bit
-+
-+id-tc26-algorithms 5	: id-tc26-cipher
-+
-+id-tc26-algorithms 6	: id-tc26-agreement
-+id-tc26-agreement 1	: id-tc26-agreement-gost-3410-2012-256
-+id-tc26-agreement 2	: id-tc26-agreement-gost-3410-2012-512
-+
-+id-tc26 2 		: id-tc26-constants
-+
-+id-tc26-constants 1	: id-tc26-sign-constants
-+id-tc26-sign-constants 2: id-tc26-gost-3410-2012-512-constants
-+id-tc26-gost-3410-2012-512-constants 0	: id-tc26-gost-3410-2012-512-paramSetTest: GOST R 34.10-2012 (512 bit) testing parameter set
-+id-tc26-gost-3410-2012-512-constants 1	: id-tc26-gost-3410-2012-512-paramSetA: GOST R 34.10-2012 (512 bit) ParamSet A
-+id-tc26-gost-3410-2012-512-constants 2	: id-tc26-gost-3410-2012-512-paramSetB: GOST R 34.10-2012 (512 bit) ParamSet B
-+
-+id-tc26-constants 2     : id-tc26-digest-constants
-+id-tc26-constants 5     : id-tc26-cipher-constants
-+id-tc26-cipher-constants 1	: id-tc26-gost-28147-constants
-+id-tc26-gost-28147-constants 1	: id-tc26-gost-28147-param-Z : GOST 28147-89 TC26 parameter set
-+
-+member-body 643 3 131 1 1	: INN	: INN
-+member-body 643 100 1		: OGRN	: OGRN
-+member-body 643 100 3		: SNILS	: SNILS
-+member-body 643 100 111	: subjectSignTool	: Signing Tool of Subject
-+member-body 643 100 112	: issuerSignTool	: Signing Tool of Issuer
-+
-+#GOST R34.13-2015 Grasshopper "Kuznechik"
-+			: grasshopper-ecb
-+			: grasshopper-ctr
-+			: grasshopper-ofb
-+			: grasshopper-cbc
-+			: grasshopper-cfb
-+			: grasshopper-mac
-+
-+# Definitions for Camellia cipher - CBC MODE
-+
-+1 2 392 200011 61 1 1 1 2 : CAMELLIA-128-CBC		: camellia-128-cbc
-+1 2 392 200011 61 1 1 1 3 : CAMELLIA-192-CBC		: camellia-192-cbc
-+1 2 392 200011 61 1 1 1 4 : CAMELLIA-256-CBC		: camellia-256-cbc
-+1 2 392 200011 61 1 1 3 2 : id-camellia128-wrap
-+1 2 392 200011 61 1 1 3 3 : id-camellia192-wrap
-+1 2 392 200011 61 1 1 3 4 : id-camellia256-wrap
-+
-+# Definitions for Camellia cipher - ECB, CFB, OFB MODE
-+
-+!Alias ntt-ds 0 3 4401 5
-+!Alias camellia ntt-ds 3 1 9 
-+
-+camellia 1		: CAMELLIA-128-ECB		: camellia-128-ecb
-+!Cname camellia-128-ofb128
-+camellia 3		: CAMELLIA-128-OFB		: camellia-128-ofb
-+!Cname camellia-128-cfb128
-+camellia 4		: CAMELLIA-128-CFB		: camellia-128-cfb
-+camellia 6		: CAMELLIA-128-GCM		: camellia-128-gcm
-+camellia 7		: CAMELLIA-128-CCM		: camellia-128-ccm
-+camellia 9		: CAMELLIA-128-CTR		: camellia-128-ctr
-+camellia 10		: CAMELLIA-128-CMAC		: camellia-128-cmac
-+
-+camellia 21		: CAMELLIA-192-ECB		: camellia-192-ecb
-+!Cname camellia-192-ofb128
-+camellia 23		: CAMELLIA-192-OFB		: camellia-192-ofb
-+!Cname camellia-192-cfb128
-+camellia 24		: CAMELLIA-192-CFB		: camellia-192-cfb
-+camellia 26		: CAMELLIA-192-GCM		: camellia-192-gcm
-+camellia 27		: CAMELLIA-192-CCM		: camellia-192-ccm
-+camellia 29		: CAMELLIA-192-CTR		: camellia-192-ctr
-+camellia 30		: CAMELLIA-192-CMAC		: camellia-192-cmac
-+
-+camellia 41		: CAMELLIA-256-ECB		: camellia-256-ecb
-+!Cname camellia-256-ofb128
-+camellia 43		: CAMELLIA-256-OFB		: camellia-256-ofb
-+!Cname camellia-256-cfb128
-+camellia 44		: CAMELLIA-256-CFB		: camellia-256-cfb
-+camellia 46		: CAMELLIA-256-GCM		: camellia-256-gcm
-+camellia 47		: CAMELLIA-256-CCM		: camellia-256-ccm
-+camellia 49		: CAMELLIA-256-CTR		: camellia-256-ctr
-+camellia 50		: CAMELLIA-256-CMAC		: camellia-256-cmac
-+
-+# There are no OIDs for these modes...
-+
-+			: CAMELLIA-128-CFB1		: camellia-128-cfb1
-+			: CAMELLIA-192-CFB1		: camellia-192-cfb1
-+			: CAMELLIA-256-CFB1		: camellia-256-cfb1
-+			: CAMELLIA-128-CFB8		: camellia-128-cfb8
-+			: CAMELLIA-192-CFB8		: camellia-192-cfb8
-+			: CAMELLIA-256-CFB8		: camellia-256-cfb8
-+
-+# Definitions for SEED cipher - ECB, CBC, OFB mode
-+
-+member-body 410 200004  : KISA          : kisa
-+kisa 1 3                : SEED-ECB      : seed-ecb
-+kisa 1 4                : SEED-CBC      : seed-cbc
-+!Cname seed-cfb128
-+kisa 1 5                : SEED-CFB      : seed-cfb
-+!Cname seed-ofb128
-+kisa 1 6                : SEED-OFB      : seed-ofb
-+
-+# There is no OID that just denotes "HMAC" oddly enough...
-+
-+			: HMAC				: hmac
-+# Nor CMAC either
-+			: CMAC				: cmac
-+
-+# Synthetic composite ciphersuites
-+			: RC4-HMAC-MD5			: rc4-hmac-md5
-+			: AES-128-CBC-HMAC-SHA1		: aes-128-cbc-hmac-sha1
-+			: AES-192-CBC-HMAC-SHA1		: aes-192-cbc-hmac-sha1
-+			: AES-256-CBC-HMAC-SHA1		: aes-256-cbc-hmac-sha1
-+			: AES-128-CBC-HMAC-SHA256	: aes-128-cbc-hmac-sha256
-+			: AES-192-CBC-HMAC-SHA256	: aes-192-cbc-hmac-sha256
-+			: AES-256-CBC-HMAC-SHA256	: aes-256-cbc-hmac-sha256
-+			: ChaCha20-Poly1305		: chacha20-poly1305
-+			: ChaCha20			: chacha20
-+
-+ISO-US 10046 2 1	: dhpublicnumber		: X9.42 DH
-+
-+# RFC 5639 curve OIDs (see http://www.ietf.org/rfc/rfc5639.txt)
-+# versionOne OBJECT IDENTIFIER ::= {
-+# iso(1) identifified-organization(3) teletrust(36) algorithm(3)
-+# signature-algorithm(3) ecSign(2) ecStdCurvesAndGeneration(8)
-+# ellipticCurve(1) 1 }
-+1 3 36 3 3 2 8 1 1 1 : brainpoolP160r1
-+1 3 36 3 3 2 8 1 1 2 : brainpoolP160t1
-+1 3 36 3 3 2 8 1 1 3 : brainpoolP192r1
-+1 3 36 3 3 2 8 1 1 4 : brainpoolP192t1
-+1 3 36 3 3 2 8 1 1 5 : brainpoolP224r1
-+1 3 36 3 3 2 8 1 1 6 : brainpoolP224t1
-+1 3 36 3 3 2 8 1 1 7 : brainpoolP256r1
-+1 3 36 3 3 2 8 1 1 8 : brainpoolP256t1
-+1 3 36 3 3 2 8 1 1 9 : brainpoolP320r1
-+1 3 36 3 3 2 8 1 1 10 : brainpoolP320t1
-+1 3 36 3 3 2 8 1 1 11 : brainpoolP384r1
-+1 3 36 3 3 2 8 1 1 12 : brainpoolP384t1
-+1 3 36 3 3 2 8 1 1 13 : brainpoolP512r1
-+1 3 36 3 3 2 8 1 1 14 : brainpoolP512t1            
-+
-+# ECDH schemes from RFC5753
-+!Alias x9-63-scheme 1 3 133 16 840 63 0
-+!Alias secg-scheme certicom-arc 1
-+
-+x9-63-scheme 2   : dhSinglePass-stdDH-sha1kdf-scheme
-+secg-scheme 11 0 : dhSinglePass-stdDH-sha224kdf-scheme
-+secg-scheme 11 1 : dhSinglePass-stdDH-sha256kdf-scheme
-+secg-scheme 11 2 : dhSinglePass-stdDH-sha384kdf-scheme
-+secg-scheme 11 3 : dhSinglePass-stdDH-sha512kdf-scheme
-+
-+x9-63-scheme 3   : dhSinglePass-cofactorDH-sha1kdf-scheme
-+secg-scheme 14 0 : dhSinglePass-cofactorDH-sha224kdf-scheme
-+secg-scheme 14 1 : dhSinglePass-cofactorDH-sha256kdf-scheme
-+secg-scheme 14 2 : dhSinglePass-cofactorDH-sha384kdf-scheme
-+secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme
-+# NIDs for use with lookup tables.
-+                 : dh-std-kdf
-+                 : dh-cofactor-kdf
-+
-+# RFC 6962 Extension OIDs (see http://www.ietf.org/rfc/rfc6962.txt)
-+1 3 6 1 4 1 11129 2 4 2	: ct_precert_scts		: CT Precertificate SCTs
-+1 3 6 1 4 1 11129 2 4 3	: ct_precert_poison		: CT Precertificate Poison
-+1 3 6 1 4 1 11129 2 4 4	: ct_precert_signer		: CT Precertificate Signer
-+1 3 6 1 4 1 11129 2 4 5	: ct_cert_scts			: CT Certificate SCTs
-+
-+# CABForum EV SSL Certificate Guidelines
-+# (see https://cabforum.org/extended-validation/)
-+# OIDs for Subject Jurisdiction of Incorporation or Registration
-+1 3 6 1 4 1 311 60 2 1 1	: jurisdictionL		: jurisdictionLocalityName
-+1 3 6 1 4 1 311 60 2 1 2	: jurisdictionST	: jurisdictionStateOrProvinceName
-+1 3 6 1 4 1 311 60 2 1 3	: jurisdictionC		: jurisdictionCountryName
-+
-+# SCRYPT algorithm
-+1 3 6 1 4 1 11591 4 11		: id-scrypt
-+
-+# NID for TLS1 PRF
-+                            : TLS1-PRF          : tls1-prf
-+
-+# NID for HKDF
-+                            : HKDF              : hkdf
-+
-+# RFC 4556
-+1 3 6 1 5 2 3 : id-pkinit
-+id-pkinit 4                     : pkInitClientAuth      : PKINIT Client Auth
-+id-pkinit 5                     : pkInitKDC             : Signing KDC Response
-+
-+# New curves from draft-ietf-curdle-pkix-00
-+1 3 101 110 : X25519
-+1 3 101 111 : X448
-+
-+# NIDs for cipher key exchange
-+                            : KxRSA        : kx-rsa
-+                            : KxECDHE      : kx-ecdhe
-+                            : KxDHE        : kx-dhe
-+                            : KxECDHE-PSK  : kx-ecdhe-psk
-+                            : KxDHE-PSK    : kx-dhe-psk
-+                            : KxRSA_PSK    : kx-rsa-psk
-+                            : KxPSK        : kx-psk
-+                            : KxSRP        : kx-srp
-+                            : KxGOST       : kx-gost
-+
-+# NIDs for cipher authentication
-+                            : AuthRSA      : auth-rsa
-+                            : AuthECDSA    : auth-ecdsa
-+                            : AuthPSK      : auth-psk
-+                            : AuthDSS      : auth-dss
-+                            : AuthGOST01   : auth-gost01
-+                            : AuthGOST12   : auth-gost12
-+                            : AuthSRP      : auth-srp
-+                            : AuthNULL     : auth-null
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objxref.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objxref.pl
-new file mode 100644
-index 0000000..53f9bd6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/objects/objxref.pl
-@@ -0,0 +1,135 @@
-+#! /usr/bin/env perl
-+# Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+use strict;
-+
-+my %xref_tbl;
-+my %oid_tbl;
-+
-+my ($mac_file, $xref_file) = @ARGV;
-+
-+open(IN, $mac_file) || die "Can't open $mac_file, $!\n";
-+
-+# Read in OID nid values for a lookup table.
-+
-+while ()
-+	{
-+	s|\R$||;                # Better chomp
-+	my ($name, $num) = /^(\S+)\s+(\S+)$/;
-+	$oid_tbl{$name} = $num;
-+	}
-+close IN;
-+
-+open(IN, $xref_file) || die "Can't open $xref_file, $!\n";
-+
-+my $ln = 1;
-+
-+while ()
-+	{
-+	s|\R$||;                # Better chomp
-+	s/#.*$//;
-+	next if (/^\S*$/);
-+	my ($xr, $p1, $p2) = /^(\S+)\s+(\S+)\s+(\S+)/;
-+	check_oid($xr);
-+	check_oid($p1);
-+	check_oid($p2);
-+	$xref_tbl{$xr} = [$p1, $p2, $ln];
-+	}
-+
-+my @xrkeys = keys %xref_tbl;
-+
-+my @srt1 = sort { $oid_tbl{$a} <=> $oid_tbl{$b}} @xrkeys;
-+
-+my $i;
-+for($i = 0; $i <= $#srt1; $i++)
-+	{
-+	$xref_tbl{$srt1[$i]}[2] = $i;
-+	}
-+
-+my @srt2 = sort
-+	{
-+	my$ap1 = $oid_tbl{$xref_tbl{$a}[0]};
-+	my$bp1 = $oid_tbl{$xref_tbl{$b}[0]};
-+	return $ap1 - $bp1 if ($ap1 != $bp1);
-+	my$ap2 = $oid_tbl{$xref_tbl{$a}[1]};
-+	my$bp2 = $oid_tbl{$xref_tbl{$b}[1]};
-+
-+	return $ap2 - $bp2;
-+	} @xrkeys;
-+
-+my $pname = $0;
-+$pname =~ s|.*/||;
-+
-+print <
-+#include 
-+#include 
-+#include "ocsp_lcl.h"
-+
-+ASN1_SEQUENCE(OCSP_SIGNATURE) = {
-+        ASN1_EMBED(OCSP_SIGNATURE, signatureAlgorithm, X509_ALGOR),
-+        ASN1_SIMPLE(OCSP_SIGNATURE, signature, ASN1_BIT_STRING),
-+        ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SIGNATURE, certs, X509, 0)
-+} ASN1_SEQUENCE_END(OCSP_SIGNATURE)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SIGNATURE)
-+
-+ASN1_SEQUENCE(OCSP_CERTID) = {
-+        ASN1_EMBED(OCSP_CERTID, hashAlgorithm, X509_ALGOR),
-+        ASN1_EMBED(OCSP_CERTID, issuerNameHash, ASN1_OCTET_STRING),
-+        ASN1_EMBED(OCSP_CERTID, issuerKeyHash, ASN1_OCTET_STRING),
-+        ASN1_EMBED(OCSP_CERTID, serialNumber, ASN1_INTEGER)
-+} ASN1_SEQUENCE_END(OCSP_CERTID)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTID)
-+
-+ASN1_SEQUENCE(OCSP_ONEREQ) = {
-+        ASN1_SIMPLE(OCSP_ONEREQ, reqCert, OCSP_CERTID),
-+        ASN1_EXP_SEQUENCE_OF_OPT(OCSP_ONEREQ, singleRequestExtensions, X509_EXTENSION, 0)
-+} ASN1_SEQUENCE_END(OCSP_ONEREQ)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_ONEREQ)
-+
-+ASN1_SEQUENCE(OCSP_REQINFO) = {
-+        ASN1_EXP_OPT(OCSP_REQINFO, version, ASN1_INTEGER, 0),
-+        ASN1_EXP_OPT(OCSP_REQINFO, requestorName, GENERAL_NAME, 1),
-+        ASN1_SEQUENCE_OF(OCSP_REQINFO, requestList, OCSP_ONEREQ),
-+        ASN1_EXP_SEQUENCE_OF_OPT(OCSP_REQINFO, requestExtensions, X509_EXTENSION, 2)
-+} ASN1_SEQUENCE_END(OCSP_REQINFO)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQINFO)
-+
-+ASN1_SEQUENCE(OCSP_REQUEST) = {
-+        ASN1_EMBED(OCSP_REQUEST, tbsRequest, OCSP_REQINFO),
-+        ASN1_EXP_OPT(OCSP_REQUEST, optionalSignature, OCSP_SIGNATURE, 0)
-+} ASN1_SEQUENCE_END(OCSP_REQUEST)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQUEST)
-+
-+/* OCSP_RESPONSE templates */
-+
-+ASN1_SEQUENCE(OCSP_RESPBYTES) = {
-+            ASN1_SIMPLE(OCSP_RESPBYTES, responseType, ASN1_OBJECT),
-+            ASN1_SIMPLE(OCSP_RESPBYTES, response, ASN1_OCTET_STRING)
-+} ASN1_SEQUENCE_END(OCSP_RESPBYTES)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPBYTES)
-+
-+ASN1_SEQUENCE(OCSP_RESPONSE) = {
-+        ASN1_SIMPLE(OCSP_RESPONSE, responseStatus, ASN1_ENUMERATED),
-+        ASN1_EXP_OPT(OCSP_RESPONSE, responseBytes, OCSP_RESPBYTES, 0)
-+} ASN1_SEQUENCE_END(OCSP_RESPONSE)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPONSE)
-+
-+ASN1_CHOICE(OCSP_RESPID) = {
-+           ASN1_EXP(OCSP_RESPID, value.byName, X509_NAME, 1),
-+           ASN1_EXP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2)
-+} ASN1_CHOICE_END(OCSP_RESPID)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPID)
-+
-+ASN1_SEQUENCE(OCSP_REVOKEDINFO) = {
-+        ASN1_SIMPLE(OCSP_REVOKEDINFO, revocationTime, ASN1_GENERALIZEDTIME),
-+        ASN1_EXP_OPT(OCSP_REVOKEDINFO, revocationReason, ASN1_ENUMERATED, 0)
-+} ASN1_SEQUENCE_END(OCSP_REVOKEDINFO)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
-+
-+ASN1_CHOICE(OCSP_CERTSTATUS) = {
-+        ASN1_IMP(OCSP_CERTSTATUS, value.good, ASN1_NULL, 0),
-+        ASN1_IMP(OCSP_CERTSTATUS, value.revoked, OCSP_REVOKEDINFO, 1),
-+        ASN1_IMP(OCSP_CERTSTATUS, value.unknown, ASN1_NULL, 2)
-+} ASN1_CHOICE_END(OCSP_CERTSTATUS)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
-+
-+ASN1_SEQUENCE(OCSP_SINGLERESP) = {
-+           ASN1_SIMPLE(OCSP_SINGLERESP, certId, OCSP_CERTID),
-+           ASN1_SIMPLE(OCSP_SINGLERESP, certStatus, OCSP_CERTSTATUS),
-+           ASN1_SIMPLE(OCSP_SINGLERESP, thisUpdate, ASN1_GENERALIZEDTIME),
-+           ASN1_EXP_OPT(OCSP_SINGLERESP, nextUpdate, ASN1_GENERALIZEDTIME, 0),
-+           ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SINGLERESP, singleExtensions, X509_EXTENSION, 1)
-+} ASN1_SEQUENCE_END(OCSP_SINGLERESP)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SINGLERESP)
-+
-+ASN1_SEQUENCE(OCSP_RESPDATA) = {
-+           ASN1_EXP_OPT(OCSP_RESPDATA, version, ASN1_INTEGER, 0),
-+           ASN1_EMBED(OCSP_RESPDATA, responderId, OCSP_RESPID),
-+           ASN1_SIMPLE(OCSP_RESPDATA, producedAt, ASN1_GENERALIZEDTIME),
-+           ASN1_SEQUENCE_OF(OCSP_RESPDATA, responses, OCSP_SINGLERESP),
-+           ASN1_EXP_SEQUENCE_OF_OPT(OCSP_RESPDATA, responseExtensions, X509_EXTENSION, 1)
-+} ASN1_SEQUENCE_END(OCSP_RESPDATA)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPDATA)
-+
-+ASN1_SEQUENCE(OCSP_BASICRESP) = {
-+           ASN1_EMBED(OCSP_BASICRESP, tbsResponseData, OCSP_RESPDATA),
-+           ASN1_EMBED(OCSP_BASICRESP, signatureAlgorithm, X509_ALGOR),
-+           ASN1_SIMPLE(OCSP_BASICRESP, signature, ASN1_BIT_STRING),
-+           ASN1_EXP_SEQUENCE_OF_OPT(OCSP_BASICRESP, certs, X509, 0)
-+} ASN1_SEQUENCE_END(OCSP_BASICRESP)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_BASICRESP)
-+
-+ASN1_SEQUENCE(OCSP_CRLID) = {
-+           ASN1_EXP_OPT(OCSP_CRLID, crlUrl, ASN1_IA5STRING, 0),
-+           ASN1_EXP_OPT(OCSP_CRLID, crlNum, ASN1_INTEGER, 1),
-+           ASN1_EXP_OPT(OCSP_CRLID, crlTime, ASN1_GENERALIZEDTIME, 2)
-+} ASN1_SEQUENCE_END(OCSP_CRLID)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CRLID)
-+
-+ASN1_SEQUENCE(OCSP_SERVICELOC) = {
-+        ASN1_SIMPLE(OCSP_SERVICELOC, issuer, X509_NAME),
-+        ASN1_SEQUENCE_OF_OPT(OCSP_SERVICELOC, locator, ACCESS_DESCRIPTION)
-+} ASN1_SEQUENCE_END(OCSP_SERVICELOC)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SERVICELOC)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_cl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_cl.c
-new file mode 100644
-index 0000000..a42b80f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_cl.c
-@@ -0,0 +1,365 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "ocsp_lcl.h"
-+
-+/*
-+ * Utility functions related to sending OCSP requests and extracting relevant
-+ * information from the response.
-+ */
-+
-+/*
-+ * Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ pointer:
-+ * useful if we want to add extensions.
-+ */
-+
-+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
-+{
-+    OCSP_ONEREQ *one = NULL;
-+
-+    if ((one = OCSP_ONEREQ_new()) == NULL)
-+        return NULL;
-+    OCSP_CERTID_free(one->reqCert);
-+    one->reqCert = cid;
-+    if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest.requestList, one)) {
-+        one->reqCert = NULL; /* do not free on error */
-+        goto err;
-+    }
-+    return one;
-+ err:
-+    OCSP_ONEREQ_free(one);
-+    return NULL;
-+}
-+
-+/* Set requestorName from an X509_NAME structure */
-+
-+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm)
-+{
-+    GENERAL_NAME *gen;
-+
-+    gen = GENERAL_NAME_new();
-+    if (gen == NULL)
-+        return 0;
-+    if (!X509_NAME_set(&gen->d.directoryName, nm)) {
-+        GENERAL_NAME_free(gen);
-+        return 0;
-+    }
-+    gen->type = GEN_DIRNAME;
-+    GENERAL_NAME_free(req->tbsRequest.requestorName);
-+    req->tbsRequest.requestorName = gen;
-+    return 1;
-+}
-+
-+/* Add a certificate to an OCSP request */
-+
-+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
-+{
-+    OCSP_SIGNATURE *sig;
-+    if (req->optionalSignature == NULL)
-+        req->optionalSignature = OCSP_SIGNATURE_new();
-+    sig = req->optionalSignature;
-+    if (sig == NULL)
-+        return 0;
-+    if (cert == NULL)
-+        return 1;
-+    if (sig->certs == NULL
-+        && (sig->certs = sk_X509_new_null()) == NULL)
-+        return 0;
-+
-+    if (!sk_X509_push(sig->certs, cert))
-+        return 0;
-+    X509_up_ref(cert);
-+    return 1;
-+}
-+
-+/*
-+ * Sign an OCSP request set the requestorName to the subject name of an
-+ * optional signers certificate and include one or more optional certificates
-+ * in the request. Behaves like PKCS7_sign().
-+ */
-+
-+int OCSP_request_sign(OCSP_REQUEST *req,
-+                      X509 *signer,
-+                      EVP_PKEY *key,
-+                      const EVP_MD *dgst,
-+                      STACK_OF(X509) *certs, unsigned long flags)
-+{
-+    int i;
-+    X509 *x;
-+
-+    if (!OCSP_request_set1_name(req, X509_get_subject_name(signer)))
-+        goto err;
-+
-+    if ((req->optionalSignature = OCSP_SIGNATURE_new()) == NULL)
-+        goto err;
-+    if (key) {
-+        if (!X509_check_private_key(signer, key)) {
-+            OCSPerr(OCSP_F_OCSP_REQUEST_SIGN,
-+                    OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
-+            goto err;
-+        }
-+        if (!OCSP_REQUEST_sign(req, key, dgst))
-+            goto err;
-+    }
-+
-+    if (!(flags & OCSP_NOCERTS)) {
-+        if (!OCSP_request_add1_cert(req, signer))
-+            goto err;
-+        for (i = 0; i < sk_X509_num(certs); i++) {
-+            x = sk_X509_value(certs, i);
-+            if (!OCSP_request_add1_cert(req, x))
-+                goto err;
-+        }
-+    }
-+
-+    return 1;
-+ err:
-+    OCSP_SIGNATURE_free(req->optionalSignature);
-+    req->optionalSignature = NULL;
-+    return 0;
-+}
-+
-+/* Get response status */
-+
-+int OCSP_response_status(OCSP_RESPONSE *resp)
-+{
-+    return ASN1_ENUMERATED_get(resp->responseStatus);
-+}
-+
-+/*
-+ * Extract basic response from OCSP_RESPONSE or NULL if no basic response
-+ * present.
-+ */
-+
-+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp)
-+{
-+    OCSP_RESPBYTES *rb;
-+    rb = resp->responseBytes;
-+    if (!rb) {
-+        OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA);
-+        return NULL;
-+    }
-+    if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
-+        OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE);
-+        return NULL;
-+    }
-+
-+    return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP));
-+}
-+
-+const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs)
-+{
-+    return bs->signature;
-+}
-+
-+/*
-+ * Return number of OCSP_SINGLERESP responses present in a basic response.
-+ */
-+
-+int OCSP_resp_count(OCSP_BASICRESP *bs)
-+{
-+    if (!bs)
-+        return -1;
-+    return sk_OCSP_SINGLERESP_num(bs->tbsResponseData.responses);
-+}
-+
-+/* Extract an OCSP_SINGLERESP response with a given index */
-+
-+OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
-+{
-+    if (!bs)
-+        return NULL;
-+    return sk_OCSP_SINGLERESP_value(bs->tbsResponseData.responses, idx);
-+}
-+
-+const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs)
-+{
-+    return bs->tbsResponseData.producedAt;
-+}
-+
-+const STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs)
-+{
-+    return bs->certs;
-+}
-+
-+int OCSP_resp_get0_id(const OCSP_BASICRESP *bs,
-+                      const ASN1_OCTET_STRING **pid,
-+                      const X509_NAME **pname)
-+
-+{
-+    const OCSP_RESPID *rid = &bs->tbsResponseData.responderId;
-+    if (rid->type == V_OCSP_RESPID_NAME) {
-+        *pname = rid->value.byName;
-+        *pid = NULL;
-+    } else if (rid->type == V_OCSP_RESPID_KEY) {
-+        *pid = rid->value.byKey;
-+        *pname = NULL;
-+    } else {
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+/* Look single response matching a given certificate ID */
-+
-+int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
-+{
-+    int i;
-+    STACK_OF(OCSP_SINGLERESP) *sresp;
-+    OCSP_SINGLERESP *single;
-+    if (!bs)
-+        return -1;
-+    if (last < 0)
-+        last = 0;
-+    else
-+        last++;
-+    sresp = bs->tbsResponseData.responses;
-+    for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
-+        single = sk_OCSP_SINGLERESP_value(sresp, i);
-+        if (!OCSP_id_cmp(id, single->certId))
-+            return i;
-+    }
-+    return -1;
-+}
-+
-+/*
-+ * Extract status information from an OCSP_SINGLERESP structure. Note: the
-+ * revtime and reason values are only set if the certificate status is
-+ * revoked. Returns numerical value of status.
-+ */
-+
-+int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
-+                            ASN1_GENERALIZEDTIME **revtime,
-+                            ASN1_GENERALIZEDTIME **thisupd,
-+                            ASN1_GENERALIZEDTIME **nextupd)
-+{
-+    int ret;
-+    OCSP_CERTSTATUS *cst;
-+    if (!single)
-+        return -1;
-+    cst = single->certStatus;
-+    ret = cst->type;
-+    if (ret == V_OCSP_CERTSTATUS_REVOKED) {
-+        OCSP_REVOKEDINFO *rev = cst->value.revoked;
-+        if (revtime)
-+            *revtime = rev->revocationTime;
-+        if (reason) {
-+            if (rev->revocationReason)
-+                *reason = ASN1_ENUMERATED_get(rev->revocationReason);
-+            else
-+                *reason = -1;
-+        }
-+    }
-+    if (thisupd)
-+        *thisupd = single->thisUpdate;
-+    if (nextupd)
-+        *nextupd = single->nextUpdate;
-+    return ret;
-+}
-+
-+/*
-+ * This function combines the previous ones: look up a certificate ID and if
-+ * found extract status information. Return 0 is successful.
-+ */
-+
-+int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
-+                          int *reason,
-+                          ASN1_GENERALIZEDTIME **revtime,
-+                          ASN1_GENERALIZEDTIME **thisupd,
-+                          ASN1_GENERALIZEDTIME **nextupd)
-+{
-+    int i;
-+    OCSP_SINGLERESP *single;
-+    i = OCSP_resp_find(bs, id, -1);
-+    /* Maybe check for multiple responses and give an error? */
-+    if (i < 0)
-+        return 0;
-+    single = OCSP_resp_get0(bs, i);
-+    i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
-+    if (status)
-+        *status = i;
-+    return 1;
-+}
-+
-+/*
-+ * Check validity of thisUpdate and nextUpdate fields. It is possible that
-+ * the request will take a few seconds to process and/or the time won't be
-+ * totally accurate. Therefore to avoid rejecting otherwise valid time we
-+ * allow the times to be within 'nsec' of the current time. Also to avoid
-+ * accepting very old responses without a nextUpdate field an optional maxage
-+ * parameter specifies the maximum age the thisUpdate field can be.
-+ */
-+
-+int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
-+                        ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
-+{
-+    int ret = 1;
-+    time_t t_now, t_tmp;
-+    time(&t_now);
-+    /* Check thisUpdate is valid and not more than nsec in the future */
-+    if (!ASN1_GENERALIZEDTIME_check(thisupd)) {
-+        OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
-+        ret = 0;
-+    } else {
-+        t_tmp = t_now + nsec;
-+        if (X509_cmp_time(thisupd, &t_tmp) > 0) {
-+            OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID);
-+            ret = 0;
-+        }
-+
-+        /*
-+         * If maxsec specified check thisUpdate is not more than maxsec in
-+         * the past
-+         */
-+        if (maxsec >= 0) {
-+            t_tmp = t_now - maxsec;
-+            if (X509_cmp_time(thisupd, &t_tmp) < 0) {
-+                OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD);
-+                ret = 0;
-+            }
-+        }
-+    }
-+
-+    if (!nextupd)
-+        return ret;
-+
-+    /* Check nextUpdate is valid and not more than nsec in the past */
-+    if (!ASN1_GENERALIZEDTIME_check(nextupd)) {
-+        OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
-+        ret = 0;
-+    } else {
-+        t_tmp = t_now - nsec;
-+        if (X509_cmp_time(nextupd, &t_tmp) < 0) {
-+            OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED);
-+            ret = 0;
-+        }
-+    }
-+
-+    /* Also don't allow nextUpdate to precede thisUpdate */
-+    if (ASN1_STRING_cmp(nextupd, thisupd) < 0) {
-+        OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
-+                OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
-+        ret = 0;
-+    }
-+
-+    return ret;
-+}
-+
-+const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single)
-+{
-+    return single->certId;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_err.c
-new file mode 100644
-index 0000000..a2d96e9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_err.c
-@@ -0,0 +1,91 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OCSP,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OCSP,0,reason)
-+
-+static ERR_STRING_DATA OCSP_str_functs[] = {
-+    {ERR_FUNC(OCSP_F_D2I_OCSP_NONCE), "d2i_ocsp_nonce"},
-+    {ERR_FUNC(OCSP_F_OCSP_BASIC_ADD1_STATUS), "OCSP_basic_add1_status"},
-+    {ERR_FUNC(OCSP_F_OCSP_BASIC_SIGN), "OCSP_basic_sign"},
-+    {ERR_FUNC(OCSP_F_OCSP_BASIC_VERIFY), "OCSP_basic_verify"},
-+    {ERR_FUNC(OCSP_F_OCSP_CERT_ID_NEW), "OCSP_cert_id_new"},
-+    {ERR_FUNC(OCSP_F_OCSP_CHECK_DELEGATED), "ocsp_check_delegated"},
-+    {ERR_FUNC(OCSP_F_OCSP_CHECK_IDS), "ocsp_check_ids"},
-+    {ERR_FUNC(OCSP_F_OCSP_CHECK_ISSUER), "ocsp_check_issuer"},
-+    {ERR_FUNC(OCSP_F_OCSP_CHECK_VALIDITY), "OCSP_check_validity"},
-+    {ERR_FUNC(OCSP_F_OCSP_MATCH_ISSUERID), "ocsp_match_issuerid"},
-+    {ERR_FUNC(OCSP_F_OCSP_PARSE_URL), "OCSP_parse_url"},
-+    {ERR_FUNC(OCSP_F_OCSP_REQUEST_SIGN), "OCSP_request_sign"},
-+    {ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY), "OCSP_request_verify"},
-+    {ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC), "OCSP_response_get1_basic"},
-+    {ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1), "parse_http_line1"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA OCSP_str_reasons[] = {
-+    {ERR_REASON(OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
-+    {ERR_REASON(OCSP_R_DIGEST_ERR), "digest err"},
-+    {ERR_REASON(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD),
-+     "error in nextupdate field"},
-+    {ERR_REASON(OCSP_R_ERROR_IN_THISUPDATE_FIELD),
-+     "error in thisupdate field"},
-+    {ERR_REASON(OCSP_R_ERROR_PARSING_URL), "error parsing url"},
-+    {ERR_REASON(OCSP_R_MISSING_OCSPSIGNING_USAGE),
-+     "missing ocspsigning usage"},
-+    {ERR_REASON(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE),
-+     "nextupdate before thisupdate"},
-+    {ERR_REASON(OCSP_R_NOT_BASIC_RESPONSE), "not basic response"},
-+    {ERR_REASON(OCSP_R_NO_CERTIFICATES_IN_CHAIN), "no certificates in chain"},
-+    {ERR_REASON(OCSP_R_NO_RESPONSE_DATA), "no response data"},
-+    {ERR_REASON(OCSP_R_NO_REVOKED_TIME), "no revoked time"},
-+    {ERR_REASON(OCSP_R_NO_SIGNER_KEY), "no signer key"},
-+    {ERR_REASON(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
-+     "private key does not match certificate"},
-+    {ERR_REASON(OCSP_R_REQUEST_NOT_SIGNED), "request not signed"},
-+    {ERR_REASON(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA),
-+     "response contains no revocation data"},
-+    {ERR_REASON(OCSP_R_ROOT_CA_NOT_TRUSTED), "root ca not trusted"},
-+    {ERR_REASON(OCSP_R_SERVER_RESPONSE_ERROR), "server response error"},
-+    {ERR_REASON(OCSP_R_SERVER_RESPONSE_PARSE_ERROR),
-+     "server response parse error"},
-+    {ERR_REASON(OCSP_R_SIGNATURE_FAILURE), "signature failure"},
-+    {ERR_REASON(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND),
-+     "signer certificate not found"},
-+    {ERR_REASON(OCSP_R_STATUS_EXPIRED), "status expired"},
-+    {ERR_REASON(OCSP_R_STATUS_NOT_YET_VALID), "status not yet valid"},
-+    {ERR_REASON(OCSP_R_STATUS_TOO_OLD), "status too old"},
-+    {ERR_REASON(OCSP_R_UNKNOWN_MESSAGE_DIGEST), "unknown message digest"},
-+    {ERR_REASON(OCSP_R_UNKNOWN_NID), "unknown nid"},
-+    {ERR_REASON(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE),
-+     "unsupported requestorname type"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_OCSP_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, OCSP_str_functs);
-+        ERR_load_strings(0, OCSP_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_ext.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_ext.c
-new file mode 100644
-index 0000000..b829b2e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_ext.c
-@@ -0,0 +1,472 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "ocsp_lcl.h"
-+#include 
-+#include 
-+
-+/* Standard wrapper functions for extensions */
-+
-+/* OCSP request extensions */
-+
-+int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
-+{
-+    return (X509v3_get_ext_count(x->tbsRequest.requestExtensions));
-+}
-+
-+int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
-+{
-+    return (X509v3_get_ext_by_NID
-+            (x->tbsRequest.requestExtensions, nid, lastpos));
-+}
-+
-+int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj,
-+                                int lastpos)
-+{
-+    return (X509v3_get_ext_by_OBJ
-+            (x->tbsRequest.requestExtensions, obj, lastpos));
-+}
-+
-+int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
-+{
-+    return (X509v3_get_ext_by_critical
-+            (x->tbsRequest.requestExtensions, crit, lastpos));
-+}
-+
-+X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
-+{
-+    return (X509v3_get_ext(x->tbsRequest.requestExtensions, loc));
-+}
-+
-+X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
-+{
-+    return (X509v3_delete_ext(x->tbsRequest.requestExtensions, loc));
-+}
-+
-+void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
-+{
-+    return X509V3_get_d2i(x->tbsRequest.requestExtensions, nid, crit, idx);
-+}
-+
-+int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
-+                              unsigned long flags)
-+{
-+    return X509V3_add1_i2d(&x->tbsRequest.requestExtensions, nid, value,
-+                           crit, flags);
-+}
-+
-+int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
-+{
-+    return (X509v3_add_ext(&(x->tbsRequest.requestExtensions), ex, loc) !=
-+            NULL);
-+}
-+
-+/* Single extensions */
-+
-+int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
-+{
-+    return (X509v3_get_ext_count(x->singleRequestExtensions));
-+}
-+
-+int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
-+{
-+    return (X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos));
-+}
-+
-+int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj,
-+                               int lastpos)
-+{
-+    return (X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos));
-+}
-+
-+int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
-+{
-+    return (X509v3_get_ext_by_critical
-+            (x->singleRequestExtensions, crit, lastpos));
-+}
-+
-+X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
-+{
-+    return (X509v3_get_ext(x->singleRequestExtensions, loc));
-+}
-+
-+X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
-+{
-+    return (X509v3_delete_ext(x->singleRequestExtensions, loc));
-+}
-+
-+void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
-+{
-+    return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
-+}
-+
-+int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
-+                             unsigned long flags)
-+{
-+    return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit,
-+                           flags);
-+}
-+
-+int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
-+{
-+    return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL);
-+}
-+
-+/* OCSP Basic response */
-+
-+int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
-+{
-+    return (X509v3_get_ext_count(x->tbsResponseData.responseExtensions));
-+}
-+
-+int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
-+{
-+    return (X509v3_get_ext_by_NID
-+            (x->tbsResponseData.responseExtensions, nid, lastpos));
-+}
-+
-+int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj,
-+                                  int lastpos)
-+{
-+    return (X509v3_get_ext_by_OBJ
-+            (x->tbsResponseData.responseExtensions, obj, lastpos));
-+}
-+
-+int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit,
-+                                       int lastpos)
-+{
-+    return (X509v3_get_ext_by_critical
-+            (x->tbsResponseData.responseExtensions, crit, lastpos));
-+}
-+
-+X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
-+{
-+    return (X509v3_get_ext(x->tbsResponseData.responseExtensions, loc));
-+}
-+
-+X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
-+{
-+    return (X509v3_delete_ext(x->tbsResponseData.responseExtensions, loc));
-+}
-+
-+void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit,
-+                                  int *idx)
-+{
-+    return X509V3_get_d2i(x->tbsResponseData.responseExtensions, nid, crit,
-+                          idx);
-+}
-+
-+int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value,
-+                                int crit, unsigned long flags)
-+{
-+    return X509V3_add1_i2d(&x->tbsResponseData.responseExtensions, nid,
-+                           value, crit, flags);
-+}
-+
-+int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
-+{
-+    return (X509v3_add_ext(&(x->tbsResponseData.responseExtensions), ex, loc)
-+            != NULL);
-+}
-+
-+/* OCSP single response extensions */
-+
-+int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
-+{
-+    return (X509v3_get_ext_count(x->singleExtensions));
-+}
-+
-+int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
-+{
-+    return (X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos));
-+}
-+
-+int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj,
-+                                   int lastpos)
-+{
-+    return (X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos));
-+}
-+
-+int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit,
-+                                        int lastpos)
-+{
-+    return (X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos));
-+}
-+
-+X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
-+{
-+    return (X509v3_get_ext(x->singleExtensions, loc));
-+}
-+
-+X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
-+{
-+    return (X509v3_delete_ext(x->singleExtensions, loc));
-+}
-+
-+void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit,
-+                                   int *idx)
-+{
-+    return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
-+}
-+
-+int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value,
-+                                 int crit, unsigned long flags)
-+{
-+    return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
-+}
-+
-+int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
-+{
-+    return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL);
-+}
-+
-+/* also CRL Entry Extensions */
-+
-+/* Nonce handling functions */
-+
-+/*
-+ * Add a nonce to an extension stack. A nonce can be specified or if NULL a
-+ * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an
-+ * OCTET STRING containing the nonce, previous versions used the raw nonce.
-+ */
-+
-+static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts,
-+                           unsigned char *val, int len)
-+{
-+    unsigned char *tmpval;
-+    ASN1_OCTET_STRING os;
-+    int ret = 0;
-+    if (len <= 0)
-+        len = OCSP_DEFAULT_NONCE_LENGTH;
-+    /*
-+     * Create the OCTET STRING manually by writing out the header and
-+     * appending the content octets. This avoids an extra memory allocation
-+     * operation in some cases. Applications should *NOT* do this because it
-+     * relies on library internals.
-+     */
-+    os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
-+    if (os.length < 0)
-+        return 0;
-+
-+    os.data = OPENSSL_malloc(os.length);
-+    if (os.data == NULL)
-+        goto err;
-+    tmpval = os.data;
-+    ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
-+    if (val)
-+        memcpy(tmpval, val, len);
-+    else if (RAND_bytes(tmpval, len) <= 0)
-+        goto err;
-+    if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
-+                         &os, 0, X509V3_ADD_REPLACE))
-+        goto err;
-+    ret = 1;
-+ err:
-+    OPENSSL_free(os.data);
-+    return ret;
-+}
-+
-+/* Add nonce to an OCSP request */
-+
-+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
-+{
-+    return ocsp_add1_nonce(&req->tbsRequest.requestExtensions, val, len);
-+}
-+
-+/* Same as above but for a response */
-+
-+int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
-+{
-+    return ocsp_add1_nonce(&resp->tbsResponseData.responseExtensions, val,
-+                           len);
-+}
-+
-+/*-
-+ * Check nonce validity in a request and response.
-+ * Return value reflects result:
-+ *  1: nonces present and equal.
-+ *  2: nonces both absent.
-+ *  3: nonce present in response only.
-+ *  0: nonces both present and not equal.
-+ * -1: nonce in request only.
-+ *
-+ *  For most responders clients can check return > 0.
-+ *  If responder doesn't handle nonces return != 0 may be
-+ *  necessary. return == 0 is always an error.
-+ */
-+
-+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
-+{
-+    /*
-+     * Since we are only interested in the presence or absence of
-+     * the nonce and comparing its value there is no need to use
-+     * the X509V3 routines: this way we can avoid them allocating an
-+     * ASN1_OCTET_STRING structure for the value which would be
-+     * freed immediately anyway.
-+     */
-+
-+    int req_idx, resp_idx;
-+    X509_EXTENSION *req_ext, *resp_ext;
-+    req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
-+    resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
-+    /* Check both absent */
-+    if ((req_idx < 0) && (resp_idx < 0))
-+        return 2;
-+    /* Check in request only */
-+    if ((req_idx >= 0) && (resp_idx < 0))
-+        return -1;
-+    /* Check in response but not request */
-+    if ((req_idx < 0) && (resp_idx >= 0))
-+        return 3;
-+    /*
-+     * Otherwise nonce in request and response so retrieve the extensions
-+     */
-+    req_ext = OCSP_REQUEST_get_ext(req, req_idx);
-+    resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
-+    if (ASN1_OCTET_STRING_cmp(X509_EXTENSION_get_data(req_ext),
-+                              X509_EXTENSION_get_data(resp_ext)))
-+        return 0;
-+    return 1;
-+}
-+
-+/*
-+ * Copy the nonce value (if any) from an OCSP request to a response.
-+ */
-+
-+int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
-+{
-+    X509_EXTENSION *req_ext;
-+    int req_idx;
-+    /* Check for nonce in request */
-+    req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
-+    /* If no nonce that's OK */
-+    if (req_idx < 0)
-+        return 2;
-+    req_ext = OCSP_REQUEST_get_ext(req, req_idx);
-+    return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
-+}
-+
-+X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim)
-+{
-+    X509_EXTENSION *x = NULL;
-+    OCSP_CRLID *cid = NULL;
-+
-+    if ((cid = OCSP_CRLID_new()) == NULL)
-+        goto err;
-+    if (url) {
-+        if ((cid->crlUrl = ASN1_IA5STRING_new()) == NULL)
-+            goto err;
-+        if (!(ASN1_STRING_set(cid->crlUrl, url, -1)))
-+            goto err;
-+    }
-+    if (n) {
-+        if ((cid->crlNum = ASN1_INTEGER_new()) == NULL)
-+            goto err;
-+        if (!(ASN1_INTEGER_set(cid->crlNum, *n)))
-+            goto err;
-+    }
-+    if (tim) {
-+        if ((cid->crlTime = ASN1_GENERALIZEDTIME_new()) == NULL)
-+            goto err;
-+        if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim)))
-+            goto err;
-+    }
-+    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
-+ err:
-+    OCSP_CRLID_free(cid);
-+    return x;
-+}
-+
-+/*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
-+X509_EXTENSION *OCSP_accept_responses_new(char **oids)
-+{
-+    int nid;
-+    STACK_OF(ASN1_OBJECT) *sk = NULL;
-+    ASN1_OBJECT *o = NULL;
-+    X509_EXTENSION *x = NULL;
-+
-+    if ((sk = sk_ASN1_OBJECT_new_null()) == NULL)
-+        goto err;
-+    while (oids && *oids) {
-+        if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid)))
-+            sk_ASN1_OBJECT_push(sk, o);
-+        oids++;
-+    }
-+    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
-+ err:
-+    sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
-+    return x;
-+}
-+
-+/*  ArchiveCutoff ::= GeneralizedTime */
-+X509_EXTENSION *OCSP_archive_cutoff_new(char *tim)
-+{
-+    X509_EXTENSION *x = NULL;
-+    ASN1_GENERALIZEDTIME *gt = NULL;
-+
-+    if ((gt = ASN1_GENERALIZEDTIME_new()) == NULL)
-+        goto err;
-+    if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim)))
-+        goto err;
-+    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
-+ err:
-+    ASN1_GENERALIZEDTIME_free(gt);
-+    return x;
-+}
-+
-+/*
-+ * per ACCESS_DESCRIPTION parameter are oids, of which there are currently
-+ * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value.  This method
-+ * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
-+ */
-+X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, const char **urls)
-+{
-+    X509_EXTENSION *x = NULL;
-+    ASN1_IA5STRING *ia5 = NULL;
-+    OCSP_SERVICELOC *sloc = NULL;
-+    ACCESS_DESCRIPTION *ad = NULL;
-+
-+    if ((sloc = OCSP_SERVICELOC_new()) == NULL)
-+        goto err;
-+    if ((sloc->issuer = X509_NAME_dup(issuer)) == NULL)
-+        goto err;
-+    if (urls && *urls
-+        && (sloc->locator = sk_ACCESS_DESCRIPTION_new_null()) == NULL)
-+        goto err;
-+    while (urls && *urls) {
-+        if ((ad = ACCESS_DESCRIPTION_new()) == NULL)
-+            goto err;
-+        if ((ad->method = OBJ_nid2obj(NID_ad_OCSP)) == NULL)
-+            goto err;
-+        if ((ad->location = GENERAL_NAME_new()) == NULL)
-+            goto err;
-+        if ((ia5 = ASN1_IA5STRING_new()) == NULL)
-+            goto err;
-+        if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1))
-+            goto err;
-+        ad->location->type = GEN_URI;
-+        ad->location->d.ia5 = ia5;
-+        ia5 = NULL;
-+        if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad))
-+            goto err;
-+        ad = NULL;
-+        urls++;
-+    }
-+    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
-+ err:
-+    ASN1_IA5STRING_free(ia5);
-+    ACCESS_DESCRIPTION_free(ad);
-+    OCSP_SERVICELOC_free(sloc);
-+    return x;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_ht.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_ht.c
-new file mode 100644
-index 0000000..680edfa
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_ht.c
-@@ -0,0 +1,499 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "e_os.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+/* Stateful OCSP request code, supporting non-blocking I/O */
-+
-+/* Opaque OCSP request status structure */
-+
-+struct ocsp_req_ctx_st {
-+    int state;                  /* Current I/O state */
-+    unsigned char *iobuf;       /* Line buffer */
-+    int iobuflen;               /* Line buffer length */
-+    BIO *io;                    /* BIO to perform I/O with */
-+    BIO *mem;                   /* Memory BIO response is built into */
-+    unsigned long asn1_len;     /* ASN1 length of response */
-+    unsigned long max_resp_len; /* Maximum length of response */
-+};
-+
-+#define OCSP_MAX_RESP_LENGTH    (100 * 1024)
-+#define OCSP_MAX_LINE_LEN       4096;
-+
-+/* OCSP states */
-+
-+/* If set no reading should be performed */
-+#define OHS_NOREAD              0x1000
-+/* Error condition */
-+#define OHS_ERROR               (0 | OHS_NOREAD)
-+/* First line being read */
-+#define OHS_FIRSTLINE           1
-+/* MIME headers being read */
-+#define OHS_HEADERS             2
-+/* OCSP initial header (tag + length) being read */
-+#define OHS_ASN1_HEADER         3
-+/* OCSP content octets being read */
-+#define OHS_ASN1_CONTENT        4
-+/* First call: ready to start I/O */
-+#define OHS_ASN1_WRITE_INIT     (5 | OHS_NOREAD)
-+/* Request being sent */
-+#define OHS_ASN1_WRITE          (6 | OHS_NOREAD)
-+/* Request being flushed */
-+#define OHS_ASN1_FLUSH          (7 | OHS_NOREAD)
-+/* Completed */
-+#define OHS_DONE                (8 | OHS_NOREAD)
-+/* Headers set, no final \r\n included */
-+#define OHS_HTTP_HEADER         (9 | OHS_NOREAD)
-+
-+static int parse_http_line1(char *line);
-+
-+OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline)
-+{
-+    OCSP_REQ_CTX *rctx = OPENSSL_zalloc(sizeof(*rctx));
-+
-+    if (rctx == NULL)
-+        return NULL;
-+    rctx->state = OHS_ERROR;
-+    rctx->max_resp_len = OCSP_MAX_RESP_LENGTH;
-+    rctx->mem = BIO_new(BIO_s_mem());
-+    rctx->io = io;
-+    if (maxline > 0)
-+        rctx->iobuflen = maxline;
-+    else
-+        rctx->iobuflen = OCSP_MAX_LINE_LEN;
-+    rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
-+    if (rctx->iobuf == NULL || rctx->mem == NULL) {
-+        OCSP_REQ_CTX_free(rctx);
-+        return NULL;
-+    }
-+    return rctx;
-+}
-+
-+void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx)
-+{
-+    if (!rctx)
-+        return;
-+    BIO_free(rctx->mem);
-+    OPENSSL_free(rctx->iobuf);
-+    OPENSSL_free(rctx);
-+}
-+
-+BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx)
-+{
-+    return rctx->mem;
-+}
-+
-+void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len)
-+{
-+    if (len == 0)
-+        rctx->max_resp_len = OCSP_MAX_RESP_LENGTH;
-+    else
-+        rctx->max_resp_len = len;
-+}
-+
-+int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, ASN1_VALUE *val)
-+{
-+    static const char req_hdr[] =
-+        "Content-Type: application/ocsp-request\r\n"
-+        "Content-Length: %d\r\n\r\n";
-+    int reqlen = ASN1_item_i2d(val, NULL, it);
-+    if (BIO_printf(rctx->mem, req_hdr, reqlen) <= 0)
-+        return 0;
-+    if (ASN1_item_i2d_bio(it, rctx->mem, val) <= 0)
-+        return 0;
-+    rctx->state = OHS_ASN1_WRITE_INIT;
-+    return 1;
-+}
-+
-+int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx,
-+                          ASN1_VALUE **pval, const ASN1_ITEM *it)
-+{
-+    int rv, len;
-+    const unsigned char *p;
-+
-+    rv = OCSP_REQ_CTX_nbio(rctx);
-+    if (rv != 1)
-+        return rv;
-+
-+    len = BIO_get_mem_data(rctx->mem, &p);
-+    *pval = ASN1_item_d2i(NULL, &p, len, it);
-+    if (*pval == NULL) {
-+        rctx->state = OHS_ERROR;
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path)
-+{
-+    static const char http_hdr[] = "%s %s HTTP/1.0\r\n";
-+
-+    if (!path)
-+        path = "/";
-+
-+    if (BIO_printf(rctx->mem, http_hdr, op, path) <= 0)
-+        return 0;
-+    rctx->state = OHS_HTTP_HEADER;
-+    return 1;
-+}
-+
-+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req)
-+{
-+    return OCSP_REQ_CTX_i2d(rctx, ASN1_ITEM_rptr(OCSP_REQUEST),
-+                            (ASN1_VALUE *)req);
-+}
-+
-+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
-+                             const char *name, const char *value)
-+{
-+    if (!name)
-+        return 0;
-+    if (BIO_puts(rctx->mem, name) <= 0)
-+        return 0;
-+    if (value) {
-+        if (BIO_write(rctx->mem, ": ", 2) != 2)
-+            return 0;
-+        if (BIO_puts(rctx->mem, value) <= 0)
-+            return 0;
-+    }
-+    if (BIO_write(rctx->mem, "\r\n", 2) != 2)
-+        return 0;
-+    rctx->state = OHS_HTTP_HEADER;
-+    return 1;
-+}
-+
-+OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req,
-+                               int maxline)
-+{
-+
-+    OCSP_REQ_CTX *rctx = NULL;
-+    rctx = OCSP_REQ_CTX_new(io, maxline);
-+    if (rctx == NULL)
-+        return NULL;
-+
-+    if (!OCSP_REQ_CTX_http(rctx, "POST", path))
-+        goto err;
-+
-+    if (req && !OCSP_REQ_CTX_set1_req(rctx, req))
-+        goto err;
-+
-+    return rctx;
-+
-+ err:
-+    OCSP_REQ_CTX_free(rctx);
-+    return NULL;
-+}
-+
-+/*
-+ * Parse the HTTP response. This will look like this: "HTTP/1.0 200 OK". We
-+ * need to obtain the numeric code and (optional) informational message.
-+ */
-+
-+static int parse_http_line1(char *line)
-+{
-+    int retcode;
-+    char *p, *q, *r;
-+    /* Skip to first white space (passed protocol info) */
-+
-+    for (p = line; *p && !isspace((unsigned char)*p); p++)
-+        continue;
-+    if (!*p) {
-+        OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
-+        return 0;
-+    }
-+
-+    /* Skip past white space to start of response code */
-+    while (*p && isspace((unsigned char)*p))
-+        p++;
-+
-+    if (!*p) {
-+        OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
-+        return 0;
-+    }
-+
-+    /* Find end of response code: first whitespace after start of code */
-+    for (q = p; *q && !isspace((unsigned char)*q); q++)
-+        continue;
-+
-+    if (!*q) {
-+        OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
-+        return 0;
-+    }
-+
-+    /* Set end of response code and start of message */
-+    *q++ = 0;
-+
-+    /* Attempt to parse numeric code */
-+    retcode = strtoul(p, &r, 10);
-+
-+    if (*r)
-+        return 0;
-+
-+    /* Skip over any leading white space in message */
-+    while (*q && isspace((unsigned char)*q))
-+        q++;
-+
-+    if (*q) {
-+        /*
-+         * Finally zap any trailing white space in message (include CRLF)
-+         */
-+
-+        /* We know q has a non white space character so this is OK */
-+        for (r = q + strlen(q) - 1; isspace((unsigned char)*r); r--)
-+            *r = 0;
-+    }
-+    if (retcode != 200) {
-+        OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR);
-+        if (!*q)
-+            ERR_add_error_data(2, "Code=", p);
-+        else
-+            ERR_add_error_data(4, "Code=", p, ",Reason=", q);
-+        return 0;
-+    }
-+
-+    return 1;
-+
-+}
-+
-+int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx)
-+{
-+    int i, n;
-+    const unsigned char *p;
-+ next_io:
-+    if (!(rctx->state & OHS_NOREAD)) {
-+        n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen);
-+
-+        if (n <= 0) {
-+            if (BIO_should_retry(rctx->io))
-+                return -1;
-+            return 0;
-+        }
-+
-+        /* Write data to memory BIO */
-+
-+        if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
-+            return 0;
-+    }
-+
-+    switch (rctx->state) {
-+    case OHS_HTTP_HEADER:
-+        /* Last operation was adding headers: need a final \r\n */
-+        if (BIO_write(rctx->mem, "\r\n", 2) != 2) {
-+            rctx->state = OHS_ERROR;
-+            return 0;
-+        }
-+        rctx->state = OHS_ASN1_WRITE_INIT;
-+
-+    case OHS_ASN1_WRITE_INIT:
-+        rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
-+        rctx->state = OHS_ASN1_WRITE;
-+
-+    case OHS_ASN1_WRITE:
-+        n = BIO_get_mem_data(rctx->mem, &p);
-+
-+        i = BIO_write(rctx->io, p + (n - rctx->asn1_len), rctx->asn1_len);
-+
-+        if (i <= 0) {
-+            if (BIO_should_retry(rctx->io))
-+                return -1;
-+            rctx->state = OHS_ERROR;
-+            return 0;
-+        }
-+
-+        rctx->asn1_len -= i;
-+
-+        if (rctx->asn1_len > 0)
-+            goto next_io;
-+
-+        rctx->state = OHS_ASN1_FLUSH;
-+
-+        (void)BIO_reset(rctx->mem);
-+
-+    case OHS_ASN1_FLUSH:
-+
-+        i = BIO_flush(rctx->io);
-+
-+        if (i > 0) {
-+            rctx->state = OHS_FIRSTLINE;
-+            goto next_io;
-+        }
-+
-+        if (BIO_should_retry(rctx->io))
-+            return -1;
-+
-+        rctx->state = OHS_ERROR;
-+        return 0;
-+
-+    case OHS_ERROR:
-+        return 0;
-+
-+    case OHS_FIRSTLINE:
-+    case OHS_HEADERS:
-+
-+        /* Attempt to read a line in */
-+
-+ next_line:
-+        /*
-+         * Due to &%^*$" memory BIO behaviour with BIO_gets we have to check
-+         * there's a complete line in there before calling BIO_gets or we'll
-+         * just get a partial read.
-+         */
-+        n = BIO_get_mem_data(rctx->mem, &p);
-+        if ((n <= 0) || !memchr(p, '\n', n)) {
-+            if (n >= rctx->iobuflen) {
-+                rctx->state = OHS_ERROR;
-+                return 0;
-+            }
-+            goto next_io;
-+        }
-+        n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
-+
-+        if (n <= 0) {
-+            if (BIO_should_retry(rctx->mem))
-+                goto next_io;
-+            rctx->state = OHS_ERROR;
-+            return 0;
-+        }
-+
-+        /* Don't allow excessive lines */
-+        if (n == rctx->iobuflen) {
-+            rctx->state = OHS_ERROR;
-+            return 0;
-+        }
-+
-+        /* First line */
-+        if (rctx->state == OHS_FIRSTLINE) {
-+            if (parse_http_line1((char *)rctx->iobuf)) {
-+                rctx->state = OHS_HEADERS;
-+                goto next_line;
-+            } else {
-+                rctx->state = OHS_ERROR;
-+                return 0;
-+            }
-+        } else {
-+            /* Look for blank line: end of headers */
-+            for (p = rctx->iobuf; *p; p++) {
-+                if ((*p != '\r') && (*p != '\n'))
-+                    break;
-+            }
-+            if (*p)
-+                goto next_line;
-+
-+            rctx->state = OHS_ASN1_HEADER;
-+
-+        }
-+
-+        /* Fall thru */
-+
-+    case OHS_ASN1_HEADER:
-+        /*
-+         * Now reading ASN1 header: can read at least 2 bytes which is enough
-+         * for ASN1 SEQUENCE header and either length field or at least the
-+         * length of the length field.
-+         */
-+        n = BIO_get_mem_data(rctx->mem, &p);
-+        if (n < 2)
-+            goto next_io;
-+
-+        /* Check it is an ASN1 SEQUENCE */
-+        if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
-+            rctx->state = OHS_ERROR;
-+            return 0;
-+        }
-+
-+        /* Check out length field */
-+        if (*p & 0x80) {
-+            /*
-+             * If MSB set on initial length octet we can now always read 6
-+             * octets: make sure we have them.
-+             */
-+            if (n < 6)
-+                goto next_io;
-+            n = *p & 0x7F;
-+            /* Not NDEF or excessive length */
-+            if (!n || (n > 4)) {
-+                rctx->state = OHS_ERROR;
-+                return 0;
-+            }
-+            p++;
-+            rctx->asn1_len = 0;
-+            for (i = 0; i < n; i++) {
-+                rctx->asn1_len <<= 8;
-+                rctx->asn1_len |= *p++;
-+            }
-+
-+            if (rctx->asn1_len > rctx->max_resp_len) {
-+                rctx->state = OHS_ERROR;
-+                return 0;
-+            }
-+
-+            rctx->asn1_len += n + 2;
-+        } else
-+            rctx->asn1_len = *p + 2;
-+
-+        rctx->state = OHS_ASN1_CONTENT;
-+
-+        /* Fall thru */
-+
-+    case OHS_ASN1_CONTENT:
-+        n = BIO_get_mem_data(rctx->mem, NULL);
-+        if (n < (int)rctx->asn1_len)
-+            goto next_io;
-+
-+        rctx->state = OHS_DONE;
-+        return 1;
-+
-+    case OHS_DONE:
-+        return 1;
-+
-+    }
-+
-+    return 0;
-+
-+}
-+
-+int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx)
-+{
-+    return OCSP_REQ_CTX_nbio_d2i(rctx,
-+                                 (ASN1_VALUE **)presp,
-+                                 ASN1_ITEM_rptr(OCSP_RESPONSE));
-+}
-+
-+/* Blocking OCSP request handler: now a special case of non-blocking I/O */
-+
-+OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req)
-+{
-+    OCSP_RESPONSE *resp = NULL;
-+    OCSP_REQ_CTX *ctx;
-+    int rv;
-+
-+    ctx = OCSP_sendreq_new(b, path, req, -1);
-+
-+    if (ctx == NULL)
-+        return NULL;
-+
-+    do {
-+        rv = OCSP_sendreq_nbio(&resp, ctx);
-+    } while ((rv == -1) && BIO_should_retry(b));
-+
-+    OCSP_REQ_CTX_free(ctx);
-+
-+    if (rv)
-+        return resp;
-+
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_lcl.h
-new file mode 100644
-index 0000000..f93a268
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_lcl.h
-@@ -0,0 +1,216 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*-  CertID ::= SEQUENCE {
-+ *       hashAlgorithm            AlgorithmIdentifier,
-+ *       issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
-+ *       issuerKeyHash      OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields)
-+ *       serialNumber       CertificateSerialNumber }
-+ */
-+struct ocsp_cert_id_st {
-+    X509_ALGOR hashAlgorithm;
-+    ASN1_OCTET_STRING issuerNameHash;
-+    ASN1_OCTET_STRING issuerKeyHash;
-+    ASN1_INTEGER serialNumber;
-+};
-+
-+/*-  Request ::=     SEQUENCE {
-+ *       reqCert                    CertID,
-+ *       singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
-+ */
-+struct ocsp_one_request_st {
-+    OCSP_CERTID *reqCert;
-+    STACK_OF(X509_EXTENSION) *singleRequestExtensions;
-+};
-+
-+/*-  TBSRequest      ::=     SEQUENCE {
-+ *       version             [0] EXPLICIT Version DEFAULT v1,
-+ *       requestorName       [1] EXPLICIT GeneralName OPTIONAL,
-+ *       requestList             SEQUENCE OF Request,
-+ *       requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
-+ */
-+struct ocsp_req_info_st {
-+    ASN1_INTEGER *version;
-+    GENERAL_NAME *requestorName;
-+    STACK_OF(OCSP_ONEREQ) *requestList;
-+    STACK_OF(X509_EXTENSION) *requestExtensions;
-+};
-+
-+/*-  Signature       ::=     SEQUENCE {
-+ *       signatureAlgorithm   AlgorithmIdentifier,
-+ *       signature            BIT STRING,
-+ *       certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
-+ */
-+struct ocsp_signature_st {
-+    X509_ALGOR signatureAlgorithm;
-+    ASN1_BIT_STRING *signature;
-+    STACK_OF(X509) *certs;
-+};
-+
-+/*-  OCSPRequest     ::=     SEQUENCE {
-+ *       tbsRequest                  TBSRequest,
-+ *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
-+ */
-+struct ocsp_request_st {
-+    OCSP_REQINFO tbsRequest;
-+    OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */
-+};
-+
-+/*-  OCSPResponseStatus ::= ENUMERATED {
-+ *       successful            (0),      --Response has valid confirmations
-+ *       malformedRequest      (1),      --Illegal confirmation request
-+ *       internalError         (2),      --Internal error in issuer
-+ *       tryLater              (3),      --Try again later
-+ *                                       --(4) is not used
-+ *       sigRequired           (5),      --Must sign the request
-+ *       unauthorized          (6)       --Request unauthorized
-+ *   }
-+ */
-+
-+/*-  ResponseBytes ::=       SEQUENCE {
-+ *       responseType   OBJECT IDENTIFIER,
-+ *       response       OCTET STRING }
-+ */
-+struct ocsp_resp_bytes_st {
-+    ASN1_OBJECT *responseType;
-+    ASN1_OCTET_STRING *response;
-+};
-+
-+/*-  OCSPResponse ::= SEQUENCE {
-+ *      responseStatus         OCSPResponseStatus,
-+ *      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
-+ */
-+struct ocsp_response_st {
-+    ASN1_ENUMERATED *responseStatus;
-+    OCSP_RESPBYTES *responseBytes;
-+};
-+
-+/*-  ResponderID ::= CHOICE {
-+ *      byName   [1] Name,
-+ *      byKey    [2] KeyHash }
-+ */
-+struct ocsp_responder_id_st {
-+    int type;
-+    union {
-+        X509_NAME *byName;
-+        ASN1_OCTET_STRING *byKey;
-+    } value;
-+};
-+
-+/*-  KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
-+ *                            --(excluding the tag and length fields)
-+ */
-+
-+/*-  RevokedInfo ::= SEQUENCE {
-+ *       revocationTime              GeneralizedTime,
-+ *       revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
-+ */
-+struct ocsp_revoked_info_st {
-+    ASN1_GENERALIZEDTIME *revocationTime;
-+    ASN1_ENUMERATED *revocationReason;
-+};
-+
-+/*-  CertStatus ::= CHOICE {
-+ *       good                [0]     IMPLICIT NULL,
-+ *       revoked             [1]     IMPLICIT RevokedInfo,
-+ *       unknown             [2]     IMPLICIT UnknownInfo }
-+ */
-+struct ocsp_cert_status_st {
-+    int type;
-+    union {
-+        ASN1_NULL *good;
-+        OCSP_REVOKEDINFO *revoked;
-+        ASN1_NULL *unknown;
-+    } value;
-+};
-+
-+/*-  SingleResponse ::= SEQUENCE {
-+ *      certID                       CertID,
-+ *      certStatus                   CertStatus,
-+ *      thisUpdate                   GeneralizedTime,
-+ *      nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
-+ *      singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
-+ */
-+struct ocsp_single_response_st {
-+    OCSP_CERTID *certId;
-+    OCSP_CERTSTATUS *certStatus;
-+    ASN1_GENERALIZEDTIME *thisUpdate;
-+    ASN1_GENERALIZEDTIME *nextUpdate;
-+    STACK_OF(X509_EXTENSION) *singleExtensions;
-+};
-+
-+/*-  ResponseData ::= SEQUENCE {
-+ *      version              [0] EXPLICIT Version DEFAULT v1,
-+ *      responderID              ResponderID,
-+ *      producedAt               GeneralizedTime,
-+ *      responses                SEQUENCE OF SingleResponse,
-+ *      responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
-+ */
-+struct ocsp_response_data_st {
-+    ASN1_INTEGER *version;
-+    OCSP_RESPID responderId;
-+    ASN1_GENERALIZEDTIME *producedAt;
-+    STACK_OF(OCSP_SINGLERESP) *responses;
-+    STACK_OF(X509_EXTENSION) *responseExtensions;
-+};
-+
-+/*-  BasicOCSPResponse       ::= SEQUENCE {
-+ *      tbsResponseData      ResponseData,
-+ *      signatureAlgorithm   AlgorithmIdentifier,
-+ *      signature            BIT STRING,
-+ *      certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
-+ */
-+  /*
-+   * Note 1: The value for "signature" is specified in the OCSP rfc2560 as
-+   * follows: "The value for the signature SHALL be computed on the hash of
-+   * the DER encoding ResponseData." This means that you must hash the
-+   * DER-encoded tbsResponseData, and then run it through a crypto-signing
-+   * function, which will (at least w/RSA) do a hash-'n'-private-encrypt
-+   * operation.  This seems a bit odd, but that's the spec.  Also note that
-+   * the data structures do not leave anywhere to independently specify the
-+   * algorithm used for the initial hash. So, we look at the
-+   * signature-specification algorithm, and try to do something intelligent.
-+   * -- Kathy Weinhold, CertCo
-+   */
-+  /*
-+   * Note 2: It seems that the mentioned passage from RFC 2560 (section
-+   * 4.2.1) is open for interpretation.  I've done tests against another
-+   * responder, and found that it doesn't do the double hashing that the RFC
-+   * seems to say one should.  Therefore, all relevant functions take a flag
-+   * saying which variant should be used.  -- Richard Levitte, OpenSSL team
-+   * and CeloCom
-+   */
-+struct ocsp_basic_response_st {
-+    OCSP_RESPDATA tbsResponseData;
-+    X509_ALGOR signatureAlgorithm;
-+    ASN1_BIT_STRING *signature;
-+    STACK_OF(X509) *certs;
-+};
-+
-+/*-
-+ * CrlID ::= SEQUENCE {
-+ *     crlUrl               [0]     EXPLICIT IA5String OPTIONAL,
-+ *     crlNum               [1]     EXPLICIT INTEGER OPTIONAL,
-+ *     crlTime              [2]     EXPLICIT GeneralizedTime OPTIONAL }
-+ */
-+struct ocsp_crl_id_st {
-+    ASN1_IA5STRING *crlUrl;
-+    ASN1_INTEGER *crlNum;
-+    ASN1_GENERALIZEDTIME *crlTime;
-+};
-+
-+/*-
-+ * ServiceLocator ::= SEQUENCE {
-+ *      issuer    Name,
-+ *      locator   AuthorityInfoAccessSyntax OPTIONAL }
-+ */
-+struct ocsp_service_locator_st {
-+    X509_NAME *issuer;
-+    STACK_OF(ACCESS_DESCRIPTION) *locator;
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_lib.c
-new file mode 100644
-index 0000000..8edd70a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_lib.c
-@@ -0,0 +1,222 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "ocsp_lcl.h"
-+#include 
-+
-+/* Convert a certificate and its issuer to an OCSP_CERTID */
-+
-+OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject,
-+                             const X509 *issuer)
-+{
-+    X509_NAME *iname;
-+    const ASN1_INTEGER *serial;
-+    ASN1_BIT_STRING *ikey;
-+    if (!dgst)
-+        dgst = EVP_sha1();
-+    if (subject) {
-+        iname = X509_get_issuer_name(subject);
-+        serial = X509_get0_serialNumber(subject);
-+    } else {
-+        iname = X509_get_subject_name(issuer);
-+        serial = NULL;
-+    }
-+    ikey = X509_get0_pubkey_bitstr(issuer);
-+    return OCSP_cert_id_new(dgst, iname, ikey, serial);
-+}
-+
-+OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
-+                              const X509_NAME *issuerName,
-+                              const ASN1_BIT_STRING *issuerKey,
-+                              const ASN1_INTEGER *serialNumber)
-+{
-+    int nid;
-+    unsigned int i;
-+    X509_ALGOR *alg;
-+    OCSP_CERTID *cid = NULL;
-+    unsigned char md[EVP_MAX_MD_SIZE];
-+
-+    if ((cid = OCSP_CERTID_new()) == NULL)
-+        goto err;
-+
-+    alg = &cid->hashAlgorithm;
-+    ASN1_OBJECT_free(alg->algorithm);
-+    if ((nid = EVP_MD_type(dgst)) == NID_undef) {
-+        OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID);
-+        goto err;
-+    }
-+    if ((alg->algorithm = OBJ_nid2obj(nid)) == NULL)
-+        goto err;
-+    if ((alg->parameter = ASN1_TYPE_new()) == NULL)
-+        goto err;
-+    alg->parameter->type = V_ASN1_NULL;
-+
-+    if (!X509_NAME_digest(issuerName, dgst, md, &i))
-+        goto digerr;
-+    if (!(ASN1_OCTET_STRING_set(&cid->issuerNameHash, md, i)))
-+        goto err;
-+
-+    /* Calculate the issuerKey hash, excluding tag and length */
-+    if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL))
-+        goto err;
-+
-+    if (!(ASN1_OCTET_STRING_set(&cid->issuerKeyHash, md, i)))
-+        goto err;
-+
-+    if (serialNumber) {
-+        if (ASN1_STRING_copy(&cid->serialNumber, serialNumber) == 0)
-+            goto err;
-+    }
-+    return cid;
-+ digerr:
-+    OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR);
-+ err:
-+    OCSP_CERTID_free(cid);
-+    return NULL;
-+}
-+
-+int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
-+{
-+    int ret;
-+    ret = OBJ_cmp(a->hashAlgorithm.algorithm, b->hashAlgorithm.algorithm);
-+    if (ret)
-+        return ret;
-+    ret = ASN1_OCTET_STRING_cmp(&a->issuerNameHash, &b->issuerNameHash);
-+    if (ret)
-+        return ret;
-+    return ASN1_OCTET_STRING_cmp(&a->issuerKeyHash, &b->issuerKeyHash);
-+}
-+
-+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
-+{
-+    int ret;
-+    ret = OCSP_id_issuer_cmp(a, b);
-+    if (ret)
-+        return ret;
-+    return ASN1_INTEGER_cmp(&a->serialNumber, &b->serialNumber);
-+}
-+
-+/*
-+ * Parse a URL and split it up into host, port and path components and
-+ * whether it is SSL.
-+ */
-+
-+int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath,
-+                   int *pssl)
-+{
-+    char *p, *buf;
-+
-+    char *host, *port;
-+
-+    *phost = NULL;
-+    *pport = NULL;
-+    *ppath = NULL;
-+
-+    /* dup the buffer since we are going to mess with it */
-+    buf = OPENSSL_strdup(url);
-+    if (!buf)
-+        goto mem_err;
-+
-+    /* Check for initial colon */
-+    p = strchr(buf, ':');
-+
-+    if (!p)
-+        goto parse_err;
-+
-+    *(p++) = '\0';
-+
-+    if (strcmp(buf, "http") == 0) {
-+        *pssl = 0;
-+        port = "80";
-+    } else if (strcmp(buf, "https") == 0) {
-+        *pssl = 1;
-+        port = "443";
-+    } else
-+        goto parse_err;
-+
-+    /* Check for double slash */
-+    if ((p[0] != '/') || (p[1] != '/'))
-+        goto parse_err;
-+
-+    p += 2;
-+
-+    host = p;
-+
-+    /* Check for trailing part of path */
-+
-+    p = strchr(p, '/');
-+
-+    if (!p)
-+        *ppath = OPENSSL_strdup("/");
-+    else {
-+        *ppath = OPENSSL_strdup(p);
-+        /* Set start of path to 0 so hostname is valid */
-+        *p = '\0';
-+    }
-+
-+    if (!*ppath)
-+        goto mem_err;
-+
-+    p = host;
-+    if (host[0] == '[') {
-+        /* ipv6 literal */
-+        host++;
-+        p = strchr(host, ']');
-+        if (!p)
-+            goto parse_err;
-+        *p = '\0';
-+        p++;
-+    }
-+
-+    /* Look for optional ':' for port number */
-+    if ((p = strchr(p, ':'))) {
-+        *p = 0;
-+        port = p + 1;
-+    }
-+
-+    *pport = OPENSSL_strdup(port);
-+    if (!*pport)
-+        goto mem_err;
-+
-+    *phost = OPENSSL_strdup(host);
-+
-+    if (!*phost)
-+        goto mem_err;
-+
-+    OPENSSL_free(buf);
-+
-+    return 1;
-+
-+ mem_err:
-+    OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE);
-+    goto err;
-+
-+ parse_err:
-+    OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL);
-+
-+ err:
-+    OPENSSL_free(buf);
-+    OPENSSL_free(*ppath);
-+    *ppath = NULL;
-+    OPENSSL_free(*pport);
-+    *pport = NULL;
-+    OPENSSL_free(*phost);
-+    *phost = NULL;
-+    return 0;
-+
-+}
-+
-+IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_prn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_prn.c
-new file mode 100644
-index 0000000..5605812
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_prn.c
-@@ -0,0 +1,246 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "ocsp_lcl.h"
-+#include "internal/cryptlib.h"
-+#include 
-+
-+static int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent)
-+{
-+    BIO_printf(bp, "%*sCertificate ID:\n", indent, "");
-+    indent += 2;
-+    BIO_printf(bp, "%*sHash Algorithm: ", indent, "");
-+    i2a_ASN1_OBJECT(bp, a->hashAlgorithm.algorithm);
-+    BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, "");
-+    i2a_ASN1_STRING(bp, &a->issuerNameHash, 0);
-+    BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, "");
-+    i2a_ASN1_STRING(bp, &a->issuerKeyHash, 0);
-+    BIO_printf(bp, "\n%*sSerial Number: ", indent, "");
-+    i2a_ASN1_INTEGER(bp, &a->serialNumber);
-+    BIO_printf(bp, "\n");
-+    return 1;
-+}
-+
-+typedef struct {
-+    long t;
-+    const char *m;
-+} OCSP_TBLSTR;
-+
-+static const char *do_table2string(long s, const OCSP_TBLSTR *ts, size_t len)
-+{
-+    size_t i;
-+    for (i = 0; i < len; i++, ts++)
-+        if (ts->t == s)
-+            return ts->m;
-+    return "(UNKNOWN)";
-+}
-+
-+#define table2string(s, tbl) do_table2string(s, tbl, OSSL_NELEM(tbl))
-+
-+const char *OCSP_response_status_str(long s)
-+{
-+    static const OCSP_TBLSTR rstat_tbl[] = {
-+        {OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful"},
-+        {OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest"},
-+        {OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror"},
-+        {OCSP_RESPONSE_STATUS_TRYLATER, "trylater"},
-+        {OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired"},
-+        {OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized"}
-+    };
-+    return table2string(s, rstat_tbl);
-+}
-+
-+const char *OCSP_cert_status_str(long s)
-+{
-+    static const OCSP_TBLSTR cstat_tbl[] = {
-+        {V_OCSP_CERTSTATUS_GOOD, "good"},
-+        {V_OCSP_CERTSTATUS_REVOKED, "revoked"},
-+        {V_OCSP_CERTSTATUS_UNKNOWN, "unknown"}
-+    };
-+    return table2string(s, cstat_tbl);
-+}
-+
-+const char *OCSP_crl_reason_str(long s)
-+{
-+    static const OCSP_TBLSTR reason_tbl[] = {
-+        {OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified"},
-+        {OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise"},
-+        {OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise"},
-+        {OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged"},
-+        {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"},
-+        {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"},
-+        {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"},
-+        {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"}
-+    };
-+    return table2string(s, reason_tbl);
-+}
-+
-+int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *o, unsigned long flags)
-+{
-+    int i;
-+    long l;
-+    OCSP_CERTID *cid = NULL;
-+    OCSP_ONEREQ *one = NULL;
-+    OCSP_REQINFO *inf = &o->tbsRequest;
-+    OCSP_SIGNATURE *sig = o->optionalSignature;
-+
-+    if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0)
-+        goto err;
-+    l = ASN1_INTEGER_get(inf->version);
-+    if (BIO_printf(bp, "    Version: %lu (0x%lx)", l + 1, l) <= 0)
-+        goto err;
-+    if (inf->requestorName != NULL) {
-+        if (BIO_write(bp, "\n    Requestor Name: ", 21) <= 0)
-+            goto err;
-+        GENERAL_NAME_print(bp, inf->requestorName);
-+    }
-+    if (BIO_write(bp, "\n    Requestor List:\n", 21) <= 0)
-+        goto err;
-+    for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) {
-+        one = sk_OCSP_ONEREQ_value(inf->requestList, i);
-+        cid = one->reqCert;
-+        ocsp_certid_print(bp, cid, 8);
-+        if (!X509V3_extensions_print(bp,
-+                                     "Request Single Extensions",
-+                                     one->singleRequestExtensions, flags, 8))
-+            goto err;
-+    }
-+    if (!X509V3_extensions_print(bp, "Request Extensions",
-+                                 inf->requestExtensions, flags, 4))
-+        goto err;
-+    if (sig) {
-+        X509_signature_print(bp, &sig->signatureAlgorithm, sig->signature);
-+        for (i = 0; i < sk_X509_num(sig->certs); i++) {
-+            X509_print(bp, sk_X509_value(sig->certs, i));
-+            PEM_write_bio_X509(bp, sk_X509_value(sig->certs, i));
-+        }
-+    }
-+    return 1;
-+ err:
-+    return 0;
-+}
-+
-+int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags)
-+{
-+    int i, ret = 0;
-+    long l;
-+    OCSP_CERTID *cid = NULL;
-+    OCSP_BASICRESP *br = NULL;
-+    OCSP_RESPID *rid = NULL;
-+    OCSP_RESPDATA *rd = NULL;
-+    OCSP_CERTSTATUS *cst = NULL;
-+    OCSP_REVOKEDINFO *rev = NULL;
-+    OCSP_SINGLERESP *single = NULL;
-+    OCSP_RESPBYTES *rb = o->responseBytes;
-+
-+    if (BIO_puts(bp, "OCSP Response Data:\n") <= 0)
-+        goto err;
-+    l = ASN1_ENUMERATED_get(o->responseStatus);
-+    if (BIO_printf(bp, "    OCSP Response Status: %s (0x%lx)\n",
-+                   OCSP_response_status_str(l), l) <= 0)
-+        goto err;
-+    if (rb == NULL)
-+        return 1;
-+    if (BIO_puts(bp, "    Response Type: ") <= 0)
-+        goto err;
-+    if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0)
-+        goto err;
-+    if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
-+        BIO_puts(bp, " (unknown response type)\n");
-+        return 1;
-+    }
-+
-+    if ((br = OCSP_response_get1_basic(o)) == NULL)
-+        goto err;
-+    rd = &br->tbsResponseData;
-+    l = ASN1_INTEGER_get(rd->version);
-+    if (BIO_printf(bp, "\n    Version: %lu (0x%lx)\n", l + 1, l) <= 0)
-+        goto err;
-+    if (BIO_puts(bp, "    Responder Id: ") <= 0)
-+        goto err;
-+
-+    rid = &rd->responderId;
-+    switch (rid->type) {
-+    case V_OCSP_RESPID_NAME:
-+        X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE);
-+        break;
-+    case V_OCSP_RESPID_KEY:
-+        i2a_ASN1_STRING(bp, rid->value.byKey, 0);
-+        break;
-+    }
-+
-+    if (BIO_printf(bp, "\n    Produced At: ") <= 0)
-+        goto err;
-+    if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt))
-+        goto err;
-+    if (BIO_printf(bp, "\n    Responses:\n") <= 0)
-+        goto err;
-+    for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) {
-+        if (!sk_OCSP_SINGLERESP_value(rd->responses, i))
-+            continue;
-+        single = sk_OCSP_SINGLERESP_value(rd->responses, i);
-+        cid = single->certId;
-+        if (ocsp_certid_print(bp, cid, 4) <= 0)
-+            goto err;
-+        cst = single->certStatus;
-+        if (BIO_printf(bp, "    Cert Status: %s",
-+                       OCSP_cert_status_str(cst->type)) <= 0)
-+            goto err;
-+        if (cst->type == V_OCSP_CERTSTATUS_REVOKED) {
-+            rev = cst->value.revoked;
-+            if (BIO_printf(bp, "\n    Revocation Time: ") <= 0)
-+                goto err;
-+            if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime))
-+                goto err;
-+            if (rev->revocationReason) {
-+                l = ASN1_ENUMERATED_get(rev->revocationReason);
-+                if (BIO_printf(bp,
-+                               "\n    Revocation Reason: %s (0x%lx)",
-+                               OCSP_crl_reason_str(l), l) <= 0)
-+                    goto err;
-+            }
-+        }
-+        if (BIO_printf(bp, "\n    This Update: ") <= 0)
-+            goto err;
-+        if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate))
-+            goto err;
-+        if (single->nextUpdate) {
-+            if (BIO_printf(bp, "\n    Next Update: ") <= 0)
-+                goto err;
-+            if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate))
-+                goto err;
-+        }
-+        if (BIO_write(bp, "\n", 1) <= 0)
-+            goto err;
-+        if (!X509V3_extensions_print(bp,
-+                                     "Response Single Extensions",
-+                                     single->singleExtensions, flags, 8))
-+            goto err;
-+        if (BIO_write(bp, "\n", 1) <= 0)
-+            goto err;
-+    }
-+    if (!X509V3_extensions_print(bp, "Response Extensions",
-+                                 rd->responseExtensions, flags, 4))
-+        goto err;
-+    if (X509_signature_print(bp, &br->signatureAlgorithm, br->signature) <= 0)
-+        goto err;
-+
-+    for (i = 0; i < sk_X509_num(br->certs); i++) {
-+        X509_print(bp, sk_X509_value(br->certs, i));
-+        PEM_write_bio_X509(bp, sk_X509_value(br->certs, i));
-+    }
-+
-+    ret = 1;
-+ err:
-+    OCSP_BASICRESP_free(br);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_srv.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_srv.c
-new file mode 100644
-index 0000000..46a4bf7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_srv.c
-@@ -0,0 +1,277 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "ocsp_lcl.h"
-+
-+/*
-+ * Utility functions related to sending OCSP responses and extracting
-+ * relevant information from the request.
-+ */
-+
-+int OCSP_request_onereq_count(OCSP_REQUEST *req)
-+{
-+    return sk_OCSP_ONEREQ_num(req->tbsRequest.requestList);
-+}
-+
-+OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i)
-+{
-+    return sk_OCSP_ONEREQ_value(req->tbsRequest.requestList, i);
-+}
-+
-+OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one)
-+{
-+    return one->reqCert;
-+}
-+
-+int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
-+                      ASN1_OCTET_STRING **pikeyHash,
-+                      ASN1_INTEGER **pserial, OCSP_CERTID *cid)
-+{
-+    if (!cid)
-+        return 0;
-+    if (pmd)
-+        *pmd = cid->hashAlgorithm.algorithm;
-+    if (piNameHash)
-+        *piNameHash = &cid->issuerNameHash;
-+    if (pikeyHash)
-+        *pikeyHash = &cid->issuerKeyHash;
-+    if (pserial)
-+        *pserial = &cid->serialNumber;
-+    return 1;
-+}
-+
-+int OCSP_request_is_signed(OCSP_REQUEST *req)
-+{
-+    if (req->optionalSignature)
-+        return 1;
-+    return 0;
-+}
-+
-+/* Create an OCSP response and encode an optional basic response */
-+OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs)
-+{
-+    OCSP_RESPONSE *rsp = NULL;
-+
-+    if ((rsp = OCSP_RESPONSE_new()) == NULL)
-+        goto err;
-+    if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status)))
-+        goto err;
-+    if (!bs)
-+        return rsp;
-+    if ((rsp->responseBytes = OCSP_RESPBYTES_new()) == NULL)
-+        goto err;
-+    rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic);
-+    if (!ASN1_item_pack
-+        (bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response))
-+         goto err;
-+    return rsp;
-+ err:
-+    OCSP_RESPONSE_free(rsp);
-+    return NULL;
-+}
-+
-+OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
-+                                        OCSP_CERTID *cid,
-+                                        int status, int reason,
-+                                        ASN1_TIME *revtime,
-+                                        ASN1_TIME *thisupd,
-+                                        ASN1_TIME *nextupd)
-+{
-+    OCSP_SINGLERESP *single = NULL;
-+    OCSP_CERTSTATUS *cs;
-+    OCSP_REVOKEDINFO *ri;
-+
-+    if (rsp->tbsResponseData.responses == NULL
-+        && (rsp->tbsResponseData.responses
-+                = sk_OCSP_SINGLERESP_new_null()) == NULL)
-+        goto err;
-+
-+    if ((single = OCSP_SINGLERESP_new()) == NULL)
-+        goto err;
-+
-+    if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate))
-+        goto err;
-+    if (nextupd &&
-+        !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate))
-+        goto err;
-+
-+    OCSP_CERTID_free(single->certId);
-+
-+    if ((single->certId = OCSP_CERTID_dup(cid)) == NULL)
-+        goto err;
-+
-+    cs = single->certStatus;
-+    switch (cs->type = status) {
-+    case V_OCSP_CERTSTATUS_REVOKED:
-+        if (!revtime) {
-+            OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS, OCSP_R_NO_REVOKED_TIME);
-+            goto err;
-+        }
-+        if ((cs->value.revoked = ri = OCSP_REVOKEDINFO_new()) == NULL)
-+            goto err;
-+        if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime))
-+            goto err;
-+        if (reason != OCSP_REVOKED_STATUS_NOSTATUS) {
-+            if ((ri->revocationReason = ASN1_ENUMERATED_new()) == NULL)
-+                goto err;
-+            if (!(ASN1_ENUMERATED_set(ri->revocationReason, reason)))
-+                goto err;
-+        }
-+        break;
-+
-+    case V_OCSP_CERTSTATUS_GOOD:
-+        if ((cs->value.good = ASN1_NULL_new()) == NULL)
-+            goto err;
-+        break;
-+
-+    case V_OCSP_CERTSTATUS_UNKNOWN:
-+        if ((cs->value.unknown = ASN1_NULL_new()) == NULL)
-+            goto err;
-+        break;
-+
-+    default:
-+        goto err;
-+
-+    }
-+    if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData.responses, single)))
-+        goto err;
-+    return single;
-+ err:
-+    OCSP_SINGLERESP_free(single);
-+    return NULL;
-+}
-+
-+/* Add a certificate to an OCSP request */
-+
-+int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert)
-+{
-+    if (resp->certs == NULL
-+        && (resp->certs = sk_X509_new_null()) == NULL)
-+        return 0;
-+
-+    if (!sk_X509_push(resp->certs, cert))
-+        return 0;
-+    X509_up_ref(cert);
-+    return 1;
-+}
-+
-+int OCSP_basic_sign(OCSP_BASICRESP *brsp,
-+                    X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
-+                    STACK_OF(X509) *certs, unsigned long flags)
-+{
-+    int i;
-+    OCSP_RESPID *rid;
-+
-+    if (!X509_check_private_key(signer, key)) {
-+        OCSPerr(OCSP_F_OCSP_BASIC_SIGN,
-+                OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
-+        goto err;
-+    }
-+
-+    if (!(flags & OCSP_NOCERTS)) {
-+        if (!OCSP_basic_add1_cert(brsp, signer))
-+            goto err;
-+        for (i = 0; i < sk_X509_num(certs); i++) {
-+            X509 *tmpcert = sk_X509_value(certs, i);
-+            if (!OCSP_basic_add1_cert(brsp, tmpcert))
-+                goto err;
-+        }
-+    }
-+
-+    rid = &brsp->tbsResponseData.responderId;
-+    if (flags & OCSP_RESPID_KEY) {
-+        if (!OCSP_RESPID_set_by_key(rid, signer))
-+            goto err;
-+    } else if (!OCSP_RESPID_set_by_name(rid, signer)) {
-+        goto err;
-+    }
-+
-+    if (!(flags & OCSP_NOTIME) &&
-+        !X509_gmtime_adj(brsp->tbsResponseData.producedAt, 0))
-+        goto err;
-+
-+    /*
-+     * Right now, I think that not doing double hashing is the right thing.
-+     * -- Richard Levitte
-+     */
-+
-+    if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0))
-+        goto err;
-+
-+    return 1;
-+ err:
-+    return 0;
-+}
-+
-+int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert)
-+{
-+    if (!X509_NAME_set(&respid->value.byName, X509_get_subject_name(cert)))
-+        return 0;
-+
-+    respid->type = V_OCSP_RESPID_NAME;
-+
-+    return 1;
-+}
-+
-+int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert)
-+{
-+    ASN1_OCTET_STRING *byKey = NULL;
-+    unsigned char md[SHA_DIGEST_LENGTH];
-+
-+    /* RFC2560 requires SHA1 */
-+    if (!X509_pubkey_digest(cert, EVP_sha1(), md, NULL))
-+        return 0;
-+
-+    byKey = ASN1_OCTET_STRING_new();
-+    if (byKey == NULL)
-+        return 0;
-+
-+    if (!(ASN1_OCTET_STRING_set(byKey, md, SHA_DIGEST_LENGTH))) {
-+        ASN1_OCTET_STRING_free(byKey);
-+        return 0;
-+    }
-+
-+    respid->type = V_OCSP_RESPID_KEY;
-+    respid->value.byKey = byKey;
-+
-+    return 1;
-+}
-+
-+int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert)
-+{
-+    if (respid->type == V_OCSP_RESPID_KEY) {
-+        unsigned char md[SHA_DIGEST_LENGTH];
-+
-+        if (respid->value.byKey == NULL)
-+            return 0;
-+
-+        /* RFC2560 requires SHA1 */
-+        if (!X509_pubkey_digest(cert, EVP_sha1(), md, NULL))
-+            return 0;
-+
-+        return (ASN1_STRING_length(respid->value.byKey) == SHA_DIGEST_LENGTH)
-+            && (memcmp(ASN1_STRING_get0_data(respid->value.byKey), md,
-+                       SHA_DIGEST_LENGTH) == 0);
-+    } else if(respid->type == V_OCSP_RESPID_NAME) {
-+        if (respid->value.byName == NULL)
-+            return 0;
-+
-+        return X509_NAME_cmp(respid->value.byName,
-+                             X509_get_subject_name(cert)) == 0;
-+    }
-+
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_vfy.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_vfy.c
-new file mode 100644
-index 0000000..e2cfa6d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/ocsp_vfy.c
-@@ -0,0 +1,424 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "ocsp_lcl.h"
-+#include 
-+#include 
-+
-+static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
-+                            STACK_OF(X509) *certs, unsigned long flags);
-+static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
-+static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain);
-+static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp,
-+                          OCSP_CERTID **ret);
-+static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
-+                               STACK_OF(OCSP_SINGLERESP) *sresp);
-+static int ocsp_check_delegated(X509 *x);
-+static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
-+                                X509_NAME *nm, STACK_OF(X509) *certs,
-+                                unsigned long flags);
-+
-+/* Verify a basic response message */
-+
-+int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
-+                      X509_STORE *st, unsigned long flags)
-+{
-+    X509 *signer, *x;
-+    STACK_OF(X509) *chain = NULL;
-+    STACK_OF(X509) *untrusted = NULL;
-+    X509_STORE_CTX *ctx = NULL;
-+    int i, ret = ocsp_find_signer(&signer, bs, certs, flags);
-+
-+    if (!ret) {
-+        OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
-+                OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
-+        goto end;
-+    }
-+    ctx = X509_STORE_CTX_new();
-+    if (ctx == NULL) {
-+        OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE);
-+        goto f_err;
-+    }
-+    if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
-+        flags |= OCSP_NOVERIFY;
-+    if (!(flags & OCSP_NOSIGS)) {
-+        EVP_PKEY *skey;
-+        skey = X509_get0_pubkey(signer);
-+        if (skey == NULL) {
-+            OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_NO_SIGNER_KEY);
-+            goto err;
-+        }
-+        ret = OCSP_BASICRESP_verify(bs, skey, 0);
-+        if (ret <= 0) {
-+            OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
-+            goto end;
-+        }
-+    }
-+    if (!(flags & OCSP_NOVERIFY)) {
-+        int init_res;
-+        if (flags & OCSP_NOCHAIN) {
-+            untrusted = NULL;
-+        } else if (bs->certs && certs) {
-+            untrusted = sk_X509_dup(bs->certs);
-+            for (i = 0; i < sk_X509_num(certs); i++) {
-+                if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) {
-+                    OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE);
-+                    goto f_err;
-+                }
-+            }
-+        } else {
-+            untrusted = bs->certs;
-+        }
-+        init_res = X509_STORE_CTX_init(ctx, st, signer, untrusted);
-+        if (!init_res) {
-+            OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB);
-+            goto f_err;
-+        }
-+
-+        X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER);
-+        ret = X509_verify_cert(ctx);
-+        chain = X509_STORE_CTX_get1_chain(ctx);
-+        if (ret <= 0) {
-+            i = X509_STORE_CTX_get_error(ctx);
-+            OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
-+                    OCSP_R_CERTIFICATE_VERIFY_ERROR);
-+            ERR_add_error_data(2, "Verify error:",
-+                               X509_verify_cert_error_string(i));
-+            goto end;
-+        }
-+        if (flags & OCSP_NOCHECKS) {
-+            ret = 1;
-+            goto end;
-+        }
-+        /*
-+         * At this point we have a valid certificate chain need to verify it
-+         * against the OCSP issuer criteria.
-+         */
-+        ret = ocsp_check_issuer(bs, chain);
-+
-+        /* If fatal error or valid match then finish */
-+        if (ret != 0)
-+            goto end;
-+
-+        /*
-+         * Easy case: explicitly trusted. Get root CA and check for explicit
-+         * trust
-+         */
-+        if (flags & OCSP_NOEXPLICIT)
-+            goto end;
-+
-+        x = sk_X509_value(chain, sk_X509_num(chain) - 1);
-+        if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) {
-+            OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED);
-+            goto err;
-+        }
-+        ret = 1;
-+    }
-+ end:
-+    X509_STORE_CTX_free(ctx);
-+    sk_X509_pop_free(chain, X509_free);
-+    if (bs->certs && certs)
-+        sk_X509_free(untrusted);
-+    return ret;
-+
-+ err:
-+    ret = 0;
-+    goto end;
-+ f_err:
-+    ret = -1;
-+    goto end;
-+}
-+
-+static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
-+                            STACK_OF(X509) *certs, unsigned long flags)
-+{
-+    X509 *signer;
-+    OCSP_RESPID *rid = &bs->tbsResponseData.responderId;
-+    if ((signer = ocsp_find_signer_sk(certs, rid))) {
-+        *psigner = signer;
-+        return 2;
-+    }
-+    if (!(flags & OCSP_NOINTERN) &&
-+        (signer = ocsp_find_signer_sk(bs->certs, rid))) {
-+        *psigner = signer;
-+        return 1;
-+    }
-+    /* Maybe lookup from store if by subject name */
-+
-+    *psigner = NULL;
-+    return 0;
-+}
-+
-+static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
-+{
-+    int i;
-+    unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
-+    X509 *x;
-+
-+    /* Easy if lookup by name */
-+    if (id->type == V_OCSP_RESPID_NAME)
-+        return X509_find_by_subject(certs, id->value.byName);
-+
-+    /* Lookup by key hash */
-+
-+    /* If key hash isn't SHA1 length then forget it */
-+    if (id->value.byKey->length != SHA_DIGEST_LENGTH)
-+        return NULL;
-+    keyhash = id->value.byKey->data;
-+    /* Calculate hash of each key and compare */
-+    for (i = 0; i < sk_X509_num(certs); i++) {
-+        x = sk_X509_value(certs, i);
-+        X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
-+        if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
-+            return x;
-+    }
-+    return NULL;
-+}
-+
-+static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain)
-+{
-+    STACK_OF(OCSP_SINGLERESP) *sresp;
-+    X509 *signer, *sca;
-+    OCSP_CERTID *caid = NULL;
-+    int i;
-+    sresp = bs->tbsResponseData.responses;
-+
-+    if (sk_X509_num(chain) <= 0) {
-+        OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN);
-+        return -1;
-+    }
-+
-+    /* See if the issuer IDs match. */
-+    i = ocsp_check_ids(sresp, &caid);
-+
-+    /* If ID mismatch or other error then return */
-+    if (i <= 0)
-+        return i;
-+
-+    signer = sk_X509_value(chain, 0);
-+    /* Check to see if OCSP responder CA matches request CA */
-+    if (sk_X509_num(chain) > 1) {
-+        sca = sk_X509_value(chain, 1);
-+        i = ocsp_match_issuerid(sca, caid, sresp);
-+        if (i < 0)
-+            return i;
-+        if (i) {
-+            /* We have a match, if extensions OK then success */
-+            if (ocsp_check_delegated(signer))
-+                return 1;
-+            return 0;
-+        }
-+    }
-+
-+    /* Otherwise check if OCSP request signed directly by request CA */
-+    return ocsp_match_issuerid(signer, caid, sresp);
-+}
-+
-+/*
-+ * Check the issuer certificate IDs for equality. If there is a mismatch with
-+ * the same algorithm then there's no point trying to match any certificates
-+ * against the issuer. If the issuer IDs all match then we just need to check
-+ * equality against one of them.
-+ */
-+
-+static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret)
-+{
-+    OCSP_CERTID *tmpid, *cid;
-+    int i, idcount;
-+
-+    idcount = sk_OCSP_SINGLERESP_num(sresp);
-+    if (idcount <= 0) {
-+        OCSPerr(OCSP_F_OCSP_CHECK_IDS,
-+                OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
-+        return -1;
-+    }
-+
-+    cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
-+
-+    *ret = NULL;
-+
-+    for (i = 1; i < idcount; i++) {
-+        tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
-+        /* Check to see if IDs match */
-+        if (OCSP_id_issuer_cmp(cid, tmpid)) {
-+            /* If algorithm mismatch let caller deal with it */
-+            if (OBJ_cmp(tmpid->hashAlgorithm.algorithm,
-+                        cid->hashAlgorithm.algorithm))
-+                return 2;
-+            /* Else mismatch */
-+            return 0;
-+        }
-+    }
-+
-+    /* All IDs match: only need to check one ID */
-+    *ret = cid;
-+    return 1;
-+}
-+
-+static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
-+                               STACK_OF(OCSP_SINGLERESP) *sresp)
-+{
-+    /* If only one ID to match then do it */
-+    if (cid) {
-+        const EVP_MD *dgst;
-+        X509_NAME *iname;
-+        int mdlen;
-+        unsigned char md[EVP_MAX_MD_SIZE];
-+        if ((dgst = EVP_get_digestbyobj(cid->hashAlgorithm.algorithm))
-+                == NULL) {
-+            OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID,
-+                    OCSP_R_UNKNOWN_MESSAGE_DIGEST);
-+            return -1;
-+        }
-+
-+        mdlen = EVP_MD_size(dgst);
-+        if (mdlen < 0)
-+            return -1;
-+        if ((cid->issuerNameHash.length != mdlen) ||
-+            (cid->issuerKeyHash.length != mdlen))
-+            return 0;
-+        iname = X509_get_subject_name(cert);
-+        if (!X509_NAME_digest(iname, dgst, md, NULL))
-+            return -1;
-+        if (memcmp(md, cid->issuerNameHash.data, mdlen))
-+            return 0;
-+        X509_pubkey_digest(cert, dgst, md, NULL);
-+        if (memcmp(md, cid->issuerKeyHash.data, mdlen))
-+            return 0;
-+
-+        return 1;
-+
-+    } else {
-+        /* We have to match the whole lot */
-+        int i, ret;
-+        OCSP_CERTID *tmpid;
-+        for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
-+            tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
-+            ret = ocsp_match_issuerid(cert, tmpid, NULL);
-+            if (ret <= 0)
-+                return ret;
-+        }
-+        return 1;
-+    }
-+
-+}
-+
-+static int ocsp_check_delegated(X509 *x)
-+{
-+    if ((X509_get_extension_flags(x) & EXFLAG_XKUSAGE)
-+        && (X509_get_extended_key_usage(x) & XKU_OCSP_SIGN))
-+        return 1;
-+    OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE);
-+    return 0;
-+}
-+
-+/*
-+ * Verify an OCSP request. This is fortunately much easier than OCSP response
-+ * verify. Just find the signers certificate and verify it against a given
-+ * trust value.
-+ */
-+
-+int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
-+                        X509_STORE *store, unsigned long flags)
-+{
-+    X509 *signer;
-+    X509_NAME *nm;
-+    GENERAL_NAME *gen;
-+    int ret = 0;
-+    X509_STORE_CTX *ctx = X509_STORE_CTX_new();
-+
-+    if (ctx == NULL) {
-+        OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (!req->optionalSignature) {
-+        OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED);
-+        goto err;
-+    }
-+    gen = req->tbsRequest.requestorName;
-+    if (!gen || gen->type != GEN_DIRNAME) {
-+        OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
-+                OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
-+        goto err;
-+    }
-+    nm = gen->d.directoryName;
-+    ret = ocsp_req_find_signer(&signer, req, nm, certs, flags);
-+    if (ret <= 0) {
-+        OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
-+                OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
-+        goto err;
-+    }
-+    if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
-+        flags |= OCSP_NOVERIFY;
-+    if (!(flags & OCSP_NOSIGS)) {
-+        EVP_PKEY *skey;
-+        skey = X509_get0_pubkey(signer);
-+        ret = OCSP_REQUEST_verify(req, skey);
-+        if (ret <= 0) {
-+            OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE);
-+            goto err;
-+        }
-+    }
-+    if (!(flags & OCSP_NOVERIFY)) {
-+        int init_res;
-+        if (flags & OCSP_NOCHAIN)
-+            init_res = X509_STORE_CTX_init(ctx, store, signer, NULL);
-+        else
-+            init_res = X509_STORE_CTX_init(ctx, store, signer,
-+                                           req->optionalSignature->certs);
-+        if (!init_res) {
-+            OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB);
-+            goto err;
-+        }
-+
-+        X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER);
-+        X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST);
-+        ret = X509_verify_cert(ctx);
-+        if (ret <= 0) {
-+            ret = X509_STORE_CTX_get_error(ctx);
-+            OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
-+                    OCSP_R_CERTIFICATE_VERIFY_ERROR);
-+            ERR_add_error_data(2, "Verify error:",
-+                               X509_verify_cert_error_string(ret));
-+            goto err;
-+        }
-+    }
-+    ret = 1;
-+    goto end;
-+
-+err:
-+    ret = 0;
-+end:
-+    X509_STORE_CTX_free(ctx);
-+    return ret;
-+
-+}
-+
-+static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
-+                                X509_NAME *nm, STACK_OF(X509) *certs,
-+                                unsigned long flags)
-+{
-+    X509 *signer;
-+    if (!(flags & OCSP_NOINTERN)) {
-+        signer = X509_find_by_subject(req->optionalSignature->certs, nm);
-+        if (signer) {
-+            *psigner = signer;
-+            return 1;
-+        }
-+    }
-+
-+    signer = X509_find_by_subject(certs, nm);
-+    if (signer) {
-+        *psigner = signer;
-+        return 2;
-+    }
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/v3_ocsp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/v3_ocsp.c
-new file mode 100644
-index 0000000..2d425a8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ocsp/v3_ocsp.c
-@@ -0,0 +1,264 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+# include 
-+# include "internal/cryptlib.h"
-+# include 
-+# include 
-+# include 
-+# include "ocsp_lcl.h"
-+# include 
-+# include "../x509v3/ext_dat.h"
-+
-+/*
-+ * OCSP extensions and a couple of CRL entry extensions
-+ */
-+
-+static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
-+                          BIO *out, int indent);
-+static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
-+                            BIO *out, int indent);
-+static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
-+                      int indent);
-+
-+static void *ocsp_nonce_new(void);
-+static int i2d_ocsp_nonce(void *a, unsigned char **pp);
-+static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
-+static void ocsp_nonce_free(void *a);
-+static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
-+                          BIO *out, int indent);
-+
-+static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
-+                            void *nocheck, BIO *out, int indent);
-+static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method,
-+                              X509V3_CTX *ctx, const char *str);
-+static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
-+                               BIO *bp, int ind);
-+
-+const X509V3_EXT_METHOD v3_ocsp_crlid = {
-+    NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
-+    0, 0, 0, 0,
-+    0, 0,
-+    0, 0,
-+    i2r_ocsp_crlid, 0,
-+    NULL
-+};
-+
-+const X509V3_EXT_METHOD v3_ocsp_acutoff = {
-+    NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
-+    0, 0, 0, 0,
-+    0, 0,
-+    0, 0,
-+    i2r_ocsp_acutoff, 0,
-+    NULL
-+};
-+
-+const X509V3_EXT_METHOD v3_crl_invdate = {
-+    NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
-+    0, 0, 0, 0,
-+    0, 0,
-+    0, 0,
-+    i2r_ocsp_acutoff, 0,
-+    NULL
-+};
-+
-+const X509V3_EXT_METHOD v3_crl_hold = {
-+    NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT),
-+    0, 0, 0, 0,
-+    0, 0,
-+    0, 0,
-+    i2r_object, 0,
-+    NULL
-+};
-+
-+const X509V3_EXT_METHOD v3_ocsp_nonce = {
-+    NID_id_pkix_OCSP_Nonce, 0, NULL,
-+    ocsp_nonce_new,
-+    ocsp_nonce_free,
-+    d2i_ocsp_nonce,
-+    i2d_ocsp_nonce,
-+    0, 0,
-+    0, 0,
-+    i2r_ocsp_nonce, 0,
-+    NULL
-+};
-+
-+const X509V3_EXT_METHOD v3_ocsp_nocheck = {
-+    NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL),
-+    0, 0, 0, 0,
-+    0, s2i_ocsp_nocheck,
-+    0, 0,
-+    i2r_ocsp_nocheck, 0,
-+    NULL
-+};
-+
-+const X509V3_EXT_METHOD v3_ocsp_serviceloc = {
-+    NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC),
-+    0, 0, 0, 0,
-+    0, 0,
-+    0, 0,
-+    i2r_ocsp_serviceloc, 0,
-+    NULL
-+};
-+
-+static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp,
-+                          int ind)
-+{
-+    OCSP_CRLID *a = in;
-+    if (a->crlUrl) {
-+        if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0)
-+            goto err;
-+        if (!ASN1_STRING_print(bp, (ASN1_STRING *)a->crlUrl))
-+            goto err;
-+        if (BIO_write(bp, "\n", 1) <= 0)
-+            goto err;
-+    }
-+    if (a->crlNum) {
-+        if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0)
-+            goto err;
-+        if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0)
-+            goto err;
-+        if (BIO_write(bp, "\n", 1) <= 0)
-+            goto err;
-+    }
-+    if (a->crlTime) {
-+        if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0)
-+            goto err;
-+        if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime))
-+            goto err;
-+        if (BIO_write(bp, "\n", 1) <= 0)
-+            goto err;
-+    }
-+    return 1;
-+ err:
-+    return 0;
-+}
-+
-+static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff,
-+                            BIO *bp, int ind)
-+{
-+    if (BIO_printf(bp, "%*s", ind, "") <= 0)
-+        return 0;
-+    if (!ASN1_GENERALIZEDTIME_print(bp, cutoff))
-+        return 0;
-+    return 1;
-+}
-+
-+static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp,
-+                      int ind)
-+{
-+    if (BIO_printf(bp, "%*s", ind, "") <= 0)
-+        return 0;
-+    if (i2a_ASN1_OBJECT(bp, oid) <= 0)
-+        return 0;
-+    return 1;
-+}
-+
-+/*
-+ * OCSP nonce. This is needs special treatment because it doesn't have an
-+ * ASN1 encoding at all: it just contains arbitrary data.
-+ */
-+
-+static void *ocsp_nonce_new(void)
-+{
-+    return ASN1_OCTET_STRING_new();
-+}
-+
-+static int i2d_ocsp_nonce(void *a, unsigned char **pp)
-+{
-+    ASN1_OCTET_STRING *os = a;
-+    if (pp) {
-+        memcpy(*pp, os->data, os->length);
-+        *pp += os->length;
-+    }
-+    return os->length;
-+}
-+
-+static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
-+{
-+    ASN1_OCTET_STRING *os, **pos;
-+    pos = a;
-+    if (pos == NULL || *pos == NULL) {
-+        os = ASN1_OCTET_STRING_new();
-+        if (os == NULL)
-+            goto err;
-+    } else {
-+        os = *pos;
-+    }
-+    if (!ASN1_OCTET_STRING_set(os, *pp, length))
-+        goto err;
-+
-+    *pp += length;
-+
-+    if (pos)
-+        *pos = os;
-+    return os;
-+
-+ err:
-+    if ((pos == NULL) || (*pos != os))
-+        ASN1_OCTET_STRING_free(os);
-+    OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+static void ocsp_nonce_free(void *a)
-+{
-+    ASN1_OCTET_STRING_free(a);
-+}
-+
-+static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
-+                          BIO *out, int indent)
-+{
-+    if (BIO_printf(out, "%*s", indent, "") <= 0)
-+        return 0;
-+    if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0)
-+        return 0;
-+    return 1;
-+}
-+
-+/* Nocheck is just a single NULL. Don't print anything and always set it */
-+
-+static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck,
-+                            BIO *out, int indent)
-+{
-+    return 1;
-+}
-+
-+static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method,
-+                              X509V3_CTX *ctx, const char *str)
-+{
-+    return ASN1_NULL_new();
-+}
-+
-+static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
-+                               BIO *bp, int ind)
-+{
-+    int i;
-+    OCSP_SERVICELOC *a = in;
-+    ACCESS_DESCRIPTION *ad;
-+
-+    if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0)
-+        goto err;
-+    if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0)
-+        goto err;
-+    for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) {
-+        ad = sk_ACCESS_DESCRIPTION_value(a->locator, i);
-+        if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0)
-+            goto err;
-+        if (i2a_ASN1_OBJECT(bp, ad->method) <= 0)
-+            goto err;
-+        if (BIO_puts(bp, " - ") <= 0)
-+            goto err;
-+        if (GENERAL_NAME_print(bp, ad->location) <= 0)
-+            goto err;
-+    }
-+    return 1;
-+ err:
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pariscid.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/pariscid.pl
-new file mode 100644
-index 0000000..f82e27a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pariscid.pl
-@@ -0,0 +1,263 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+$flavour = shift;
-+$output = shift;
-+open STDOUT,">$output";
-+
-+if ($flavour =~ /64/) {
-+	$LEVEL		="2.0W";
-+	$SIZE_T		=8;
-+	$ST		="std";
-+} else {
-+	$LEVEL		="1.1";
-+	$SIZE_T		=4;
-+	$ST		="stw";
-+}
-+
-+$rp="%r2";
-+$sp="%r30";
-+$rv="%r28";
-+
-+$code=<<___;
-+	.LEVEL	$LEVEL
-+	.SPACE	\$TEXT\$
-+	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
-+
-+	.EXPORT	OPENSSL_cpuid_setup,ENTRY
-+	.ALIGN	8
-+OPENSSL_cpuid_setup
-+	.PROC
-+	.CALLINFO	NO_CALLS
-+	.ENTRY
-+	bv	($rp)
-+	.EXIT
-+	nop
-+	.PROCEND
-+
-+	.EXPORT	OPENSSL_rdtsc,ENTRY
-+	.ALIGN	8
-+OPENSSL_rdtsc
-+	.PROC
-+	.CALLINFO	NO_CALLS
-+	.ENTRY
-+	mfctl	%cr16,$rv
-+	bv	($rp)
-+	.EXIT
-+	nop
-+	.PROCEND
-+
-+	.EXPORT	OPENSSL_wipe_cpu,ENTRY
-+	.ALIGN	8
-+OPENSSL_wipe_cpu
-+	.PROC
-+	.CALLINFO	NO_CALLS
-+	.ENTRY
-+	xor		%r0,%r0,%r1
-+	fcpy,dbl	%fr0,%fr4
-+	xor		%r0,%r0,%r19
-+	fcpy,dbl	%fr0,%fr5
-+	xor		%r0,%r0,%r20
-+	fcpy,dbl	%fr0,%fr6
-+	xor		%r0,%r0,%r21
-+	fcpy,dbl	%fr0,%fr7
-+	xor		%r0,%r0,%r22
-+	fcpy,dbl	%fr0,%fr8
-+	xor		%r0,%r0,%r23
-+	fcpy,dbl	%fr0,%fr9
-+	xor		%r0,%r0,%r24
-+	fcpy,dbl	%fr0,%fr10
-+	xor		%r0,%r0,%r25
-+	fcpy,dbl	%fr0,%fr11
-+	xor		%r0,%r0,%r26
-+	fcpy,dbl	%fr0,%fr22
-+	xor		%r0,%r0,%r29
-+	fcpy,dbl	%fr0,%fr23
-+	xor		%r0,%r0,%r31
-+	fcpy,dbl	%fr0,%fr24
-+	fcpy,dbl	%fr0,%fr25
-+	fcpy,dbl	%fr0,%fr26
-+	fcpy,dbl	%fr0,%fr27
-+	fcpy,dbl	%fr0,%fr28
-+	fcpy,dbl	%fr0,%fr29
-+	fcpy,dbl	%fr0,%fr30
-+	fcpy,dbl	%fr0,%fr31
-+	bv		($rp)
-+	.EXIT
-+	ldo		0($sp),$rv
-+	.PROCEND
-+___
-+{
-+my $inp="%r26";
-+my $len="%r25";
-+
-+$code.=<<___;
-+	.EXPORT	OPENSSL_cleanse,ENTRY,ARGW0=GR,ARGW1=GR
-+	.ALIGN	8
-+OPENSSL_cleanse
-+	.PROC
-+	.CALLINFO	NO_CALLS
-+	.ENTRY
-+	cmpib,*=	0,$len,L\$done
-+	nop
-+	cmpib,*>>=	15,$len,L\$ittle
-+	ldi		$SIZE_T-1,%r1
-+
-+L\$align
-+	and,*<>		$inp,%r1,%r28
-+	b,n		L\$aligned
-+	stb		%r0,0($inp)
-+	ldo		-1($len),$len
-+	b		L\$align
-+	ldo		1($inp),$inp
-+
-+L\$aligned
-+	andcm		$len,%r1,%r28
-+L\$ot
-+	$ST		%r0,0($inp)
-+	addib,*<>	-$SIZE_T,%r28,L\$ot
-+	ldo		$SIZE_T($inp),$inp
-+
-+	and,*<>		$len,%r1,$len
-+	b,n		L\$done
-+L\$ittle
-+	stb		%r0,0($inp)
-+	addib,*<>	-1,$len,L\$ittle
-+	ldo		1($inp),$inp
-+L\$done
-+	bv		($rp)
-+	.EXIT
-+	nop
-+	.PROCEND
-+___
-+}
-+{
-+my ($in1,$in2,$len)=("%r26","%r25","%r24");
-+
-+$code.=<<___;
-+	.EXPORT	CRYPTO_memcmp,ENTRY,ARGW0=GR,ARGW1=GR,ARGW1=GR
-+	.ALIGN	8
-+CRYPTO_memcmp
-+	.PROC
-+	.CALLINFO	NO_CALLS
-+	.ENTRY
-+	cmpib,*=	0,$len,L\$no_data
-+	xor		$rv,$rv,$rv
-+
-+L\$oop_cmp
-+	ldb		0($in1),%r19
-+	ldb		0($in2),%r20
-+	ldo		1($in1),$in1
-+	ldo		1($in2),$in2
-+	xor		%r19,%r20,%r29
-+	addib,*<>	-1,$len,L\$oop_cmp
-+	or		%r29,$rv,$rv
-+
-+	sub		%r0,$rv,%r29
-+	extru		%r29,31,1,$rv
-+L\$no_data
-+	bv		($rp)
-+	.EXIT
-+	nop
-+	.PROCEND
-+___
-+}
-+{
-+my ($out,$cnt,$max)=("%r26","%r25","%r24");
-+my ($tick,$lasttick)=("%r23","%r22");
-+my ($diff,$lastdiff)=("%r21","%r20");
-+
-+$code.=<<___;
-+	.EXPORT	OPENSSL_instrument_bus,ENTRY,ARGW0=GR,ARGW1=GR
-+	.ALIGN	8
-+OPENSSL_instrument_bus
-+	.PROC
-+	.CALLINFO	NO_CALLS
-+	.ENTRY
-+	copy		$cnt,$rv
-+	mfctl		%cr16,$tick
-+	copy		$tick,$lasttick
-+	ldi		0,$diff
-+
-+	fdc		0($out)
-+	ldw		0($out),$tick
-+	add		$diff,$tick,$tick
-+	stw		$tick,0($out)
-+L\$oop
-+	mfctl		%cr16,$tick
-+	sub		$tick,$lasttick,$diff
-+	copy		$tick,$lasttick
-+
-+	fdc		0($out)
-+	ldw		0($out),$tick
-+	add		$diff,$tick,$tick
-+	stw		$tick,0($out)
-+
-+	addib,<>	-1,$cnt,L\$oop
-+	addi		4,$out,$out
-+
-+	bv		($rp)
-+	.EXIT
-+	sub		$rv,$cnt,$rv
-+	.PROCEND
-+
-+	.EXPORT	OPENSSL_instrument_bus2,ENTRY,ARGW0=GR,ARGW1=GR
-+	.ALIGN	8
-+OPENSSL_instrument_bus2
-+	.PROC
-+	.CALLINFO	NO_CALLS
-+	.ENTRY
-+	copy		$cnt,$rv
-+	sub		%r0,$cnt,$cnt
-+
-+	mfctl		%cr16,$tick
-+	copy		$tick,$lasttick
-+	ldi		0,$diff
-+
-+	fdc		0($out)
-+	ldw		0($out),$tick
-+	add		$diff,$tick,$tick
-+	stw		$tick,0($out)
-+
-+	mfctl		%cr16,$tick
-+	sub		$tick,$lasttick,$diff
-+	copy		$tick,$lasttick
-+L\$oop2
-+	copy		$diff,$lastdiff
-+	fdc		0($out)
-+	ldw		0($out),$tick
-+	add		$diff,$tick,$tick
-+	stw		$tick,0($out)
-+
-+	addib,=		-1,$max,L\$done2
-+	nop
-+
-+	mfctl		%cr16,$tick
-+	sub		$tick,$lasttick,$diff
-+	copy		$tick,$lasttick
-+	cmpclr,<>	$lastdiff,$diff,$tick
-+	ldi		1,$tick
-+
-+	ldi		1,%r1
-+	xor		%r1,$tick,$tick
-+	addb,<>		$tick,$cnt,L\$oop2
-+	shladd,l	$tick,2,$out,$out
-+L\$done2
-+	bv		($rp)
-+	.EXIT
-+	add		$rv,$cnt,$rv
-+	.PROCEND
-+___
-+}
-+$code =~ s/cmpib,\*/comib,/gm	if ($SIZE_T==4);
-+$code =~ s/,\*/,/gm		if ($SIZE_T==4);
-+$code =~ s/\bbv\b/bve/gm	if ($SIZE_T==8);
-+print $code;
-+close STDOUT;
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/build.info
-new file mode 100644
-index 0000000..357b328
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/build.info
-@@ -0,0 +1,4 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        pem_sign.c pem_info.c pem_lib.c pem_all.c pem_err.c \
-+        pem_x509.c pem_xaux.c pem_oth.c pem_pk8.c pem_pkey.c pvkfmt.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_all.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_all.c
-new file mode 100644
-index 0000000..0e71813
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_all.c
-@@ -0,0 +1,181 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifndef OPENSSL_NO_RSA
-+static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
-+#endif
-+
-+#ifndef OPENSSL_NO_EC
-+static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
-+#endif
-+
-+IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
-+
-+IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
-+IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
-+IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
-+
-+IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE,
-+                 PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE)
-+#ifndef OPENSSL_NO_RSA
-+/*
-+ * We treat RSA or DSA private keys as a special case. For private keys we
-+ * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract
-+ * the relevant private key: this means can handle "traditional" and PKCS#8
-+ * formats transparently.
-+ */
-+static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
-+{
-+    RSA *rtmp;
-+    if (!key)
-+        return NULL;
-+    rtmp = EVP_PKEY_get1_RSA(key);
-+    EVP_PKEY_free(key);
-+    if (!rtmp)
-+        return NULL;
-+    if (rsa) {
-+        RSA_free(*rsa);
-+        *rsa = rtmp;
-+    }
-+    return rtmp;
-+}
-+
-+RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
-+                                void *u)
-+{
-+    EVP_PKEY *pktmp;
-+    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
-+    return pkey_get_rsa(pktmp, rsa);
-+}
-+
-+# ifndef OPENSSL_NO_STDIO
-+
-+RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u)
-+{
-+    EVP_PKEY *pktmp;
-+    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
-+    return pkey_get_rsa(pktmp, rsa);
-+}
-+
-+# endif
-+
-+IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA,
-+                             RSAPrivateKey)
-+
-+
-+IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC,
-+                       RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA,
-+                                                      PEM_STRING_PUBLIC,
-+                                                      RSA_PUBKEY)
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
-+{
-+    DSA *dtmp;
-+    if (!key)
-+        return NULL;
-+    dtmp = EVP_PKEY_get1_DSA(key);
-+    EVP_PKEY_free(key);
-+    if (!dtmp)
-+        return NULL;
-+    if (dsa) {
-+        DSA_free(*dsa);
-+        *dsa = dtmp;
-+    }
-+    return dtmp;
-+}
-+
-+DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
-+                                void *u)
-+{
-+    EVP_PKEY *pktmp;
-+    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
-+    return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
-+}
-+
-+IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA,
-+                             DSAPrivateKey)
-+    IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
-+# ifndef OPENSSL_NO_STDIO
-+DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u)
-+{
-+    EVP_PKEY *pktmp;
-+    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
-+    return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
-+}
-+
-+# endif
-+
-+IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
-+#endif
-+#ifndef OPENSSL_NO_EC
-+static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
-+{
-+    EC_KEY *dtmp;
-+    if (!key)
-+        return NULL;
-+    dtmp = EVP_PKEY_get1_EC_KEY(key);
-+    EVP_PKEY_free(key);
-+    if (!dtmp)
-+        return NULL;
-+    if (eckey) {
-+        EC_KEY_free(*eckey);
-+        *eckey = dtmp;
-+    }
-+    return dtmp;
-+}
-+
-+EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
-+                                  void *u)
-+{
-+    EVP_PKEY *pktmp;
-+    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
-+    return pkey_get_eckey(pktmp, key); /* will free pktmp */
-+}
-+
-+IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS,
-+                       ECPKParameters)
-+
-+
-+IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY,
-+                       ECPrivateKey)
-+IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
-+# ifndef OPENSSL_NO_STDIO
-+EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
-+                              void *u)
-+{
-+    EVP_PKEY *pktmp;
-+    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
-+    return pkey_get_eckey(pktmp, eckey); /* will free pktmp */
-+}
-+
-+# endif
-+
-+#endif
-+
-+#ifndef OPENSSL_NO_DH
-+
-+IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
-+    IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams)
-+#endif
-+IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_err.c
-new file mode 100644
-index 0000000..f36d893
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_err.c
-@@ -0,0 +1,115 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason)
-+
-+static ERR_STRING_DATA PEM_str_functs[] = {
-+    {ERR_FUNC(PEM_F_B2I_DSS), "b2i_dss"},
-+    {ERR_FUNC(PEM_F_B2I_PVK_BIO), "b2i_PVK_bio"},
-+    {ERR_FUNC(PEM_F_B2I_RSA), "b2i_rsa"},
-+    {ERR_FUNC(PEM_F_CHECK_BITLEN_DSA), "check_bitlen_dsa"},
-+    {ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "check_bitlen_rsa"},
-+    {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO), "d2i_PKCS8PrivateKey_bio"},
-+    {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP), "d2i_PKCS8PrivateKey_fp"},
-+    {ERR_FUNC(PEM_F_DO_B2I), "do_b2i"},
-+    {ERR_FUNC(PEM_F_DO_B2I_BIO), "do_b2i_bio"},
-+    {ERR_FUNC(PEM_F_DO_BLOB_HEADER), "do_blob_header"},
-+    {ERR_FUNC(PEM_F_DO_PK8PKEY), "do_pk8pkey"},
-+    {ERR_FUNC(PEM_F_DO_PK8PKEY_FP), "do_pk8pkey_fp"},
-+    {ERR_FUNC(PEM_F_DO_PVK_BODY), "do_PVK_body"},
-+    {ERR_FUNC(PEM_F_DO_PVK_HEADER), "do_PVK_header"},
-+    {ERR_FUNC(PEM_F_I2B_PVK), "i2b_PVK"},
-+    {ERR_FUNC(PEM_F_I2B_PVK_BIO), "i2b_PVK_bio"},
-+    {ERR_FUNC(PEM_F_LOAD_IV), "load_iv"},
-+    {ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"},
-+    {ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"},
-+    {ERR_FUNC(PEM_F_PEM_ASN1_WRITE), "PEM_ASN1_write"},
-+    {ERR_FUNC(PEM_F_PEM_ASN1_WRITE_BIO), "PEM_ASN1_write_bio"},
-+    {ERR_FUNC(PEM_F_PEM_DEF_CALLBACK), "PEM_def_callback"},
-+    {ERR_FUNC(PEM_F_PEM_DO_HEADER), "PEM_do_header"},
-+    {ERR_FUNC(PEM_F_PEM_GET_EVP_CIPHER_INFO), "PEM_get_EVP_CIPHER_INFO"},
-+    {ERR_FUNC(PEM_F_PEM_READ), "PEM_read"},
-+    {ERR_FUNC(PEM_F_PEM_READ_BIO), "PEM_read_bio"},
-+    {ERR_FUNC(PEM_F_PEM_READ_BIO_DHPARAMS), "PEM_read_bio_DHparams"},
-+    {ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS), "PEM_read_bio_Parameters"},
-+    {ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY), "PEM_read_bio_PrivateKey"},
-+    {ERR_FUNC(PEM_F_PEM_READ_DHPARAMS), "PEM_read_DHparams"},
-+    {ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_read_PrivateKey"},
-+    {ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"},
-+    {ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"},
-+    {ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"},
-+    {ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY), "PEM_write_PrivateKey"},
-+    {ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_read"},
-+    {ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"},
-+    {ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA PEM_str_reasons[] = {
-+    {ERR_REASON(PEM_R_BAD_BASE64_DECODE), "bad base64 decode"},
-+    {ERR_REASON(PEM_R_BAD_DECRYPT), "bad decrypt"},
-+    {ERR_REASON(PEM_R_BAD_END_LINE), "bad end line"},
-+    {ERR_REASON(PEM_R_BAD_IV_CHARS), "bad iv chars"},
-+    {ERR_REASON(PEM_R_BAD_MAGIC_NUMBER), "bad magic number"},
-+    {ERR_REASON(PEM_R_BAD_PASSWORD_READ), "bad password read"},
-+    {ERR_REASON(PEM_R_BAD_VERSION_NUMBER), "bad version number"},
-+    {ERR_REASON(PEM_R_BIO_WRITE_FAILURE), "bio write failure"},
-+    {ERR_REASON(PEM_R_CIPHER_IS_NULL), "cipher is null"},
-+    {ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY),
-+     "error converting private key"},
-+    {ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB),
-+     "expecting private key blob"},
-+    {ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB),
-+     "expecting public key blob"},
-+    {ERR_REASON(PEM_R_HEADER_TOO_LONG), "header too long"},
-+    {ERR_REASON(PEM_R_INCONSISTENT_HEADER), "inconsistent header"},
-+    {ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR),
-+     "keyblob header parse error"},
-+    {ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT), "keyblob too short"},
-+    {ERR_REASON(PEM_R_MISSING_DEK_IV), "missing dek iv"},
-+    {ERR_REASON(PEM_R_NOT_DEK_INFO), "not dek info"},
-+    {ERR_REASON(PEM_R_NOT_ENCRYPTED), "not encrypted"},
-+    {ERR_REASON(PEM_R_NOT_PROC_TYPE), "not proc type"},
-+    {ERR_REASON(PEM_R_NO_START_LINE), "no start line"},
-+    {ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD),
-+     "problems getting password"},
-+    {ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT), "pvk data too short"},
-+    {ERR_REASON(PEM_R_PVK_TOO_SHORT), "pvk too short"},
-+    {ERR_REASON(PEM_R_READ_KEY), "read key"},
-+    {ERR_REASON(PEM_R_SHORT_HEADER), "short header"},
-+    {ERR_REASON(PEM_R_UNEXPECTED_DEK_IV), "unexpected dek iv"},
-+    {ERR_REASON(PEM_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
-+    {ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION), "unsupported encryption"},
-+    {ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS),
-+     "unsupported key components"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_PEM_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, PEM_str_functs);
-+        ERR_load_strings(0, PEM_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_info.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_info.c
-new file mode 100644
-index 0000000..dd493c8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_info.c
-@@ -0,0 +1,334 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#ifndef OPENSSL_NO_STDIO
-+STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
-+                                        pem_password_cb *cb, void *u)
-+{
-+    BIO *b;
-+    STACK_OF(X509_INFO) *ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = PEM_X509_INFO_read_bio(b, sk, cb, u);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-+
-+STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
-+                                            pem_password_cb *cb, void *u)
-+{
-+    X509_INFO *xi = NULL;
-+    char *name = NULL, *header = NULL;
-+    void *pp;
-+    unsigned char *data = NULL;
-+    const unsigned char *p;
-+    long len, error = 0;
-+    int ok = 0;
-+    STACK_OF(X509_INFO) *ret = NULL;
-+    unsigned int i, raw, ptype;
-+    d2i_of_void *d2i = 0;
-+
-+    if (sk == NULL) {
-+        if ((ret = sk_X509_INFO_new_null()) == NULL) {
-+            PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    } else
-+        ret = sk;
-+
-+    if ((xi = X509_INFO_new()) == NULL)
-+        goto err;
-+    for (;;) {
-+        raw = 0;
-+        ptype = 0;
-+        i = PEM_read_bio(bp, &name, &header, &data, &len);
-+        if (i == 0) {
-+            error = ERR_GET_REASON(ERR_peek_last_error());
-+            if (error == PEM_R_NO_START_LINE) {
-+                ERR_clear_error();
-+                break;
-+            }
-+            goto err;
-+        }
-+ start:
-+        if ((strcmp(name, PEM_STRING_X509) == 0) ||
-+            (strcmp(name, PEM_STRING_X509_OLD) == 0)) {
-+            d2i = (D2I_OF(void)) d2i_X509;
-+            if (xi->x509 != NULL) {
-+                if (!sk_X509_INFO_push(ret, xi))
-+                    goto err;
-+                if ((xi = X509_INFO_new()) == NULL)
-+                    goto err;
-+                goto start;
-+            }
-+            pp = &(xi->x509);
-+        } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
-+            d2i = (D2I_OF(void)) d2i_X509_AUX;
-+            if (xi->x509 != NULL) {
-+                if (!sk_X509_INFO_push(ret, xi))
-+                    goto err;
-+                if ((xi = X509_INFO_new()) == NULL)
-+                    goto err;
-+                goto start;
-+            }
-+            pp = &(xi->x509);
-+        } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) {
-+            d2i = (D2I_OF(void)) d2i_X509_CRL;
-+            if (xi->crl != NULL) {
-+                if (!sk_X509_INFO_push(ret, xi))
-+                    goto err;
-+                if ((xi = X509_INFO_new()) == NULL)
-+                    goto err;
-+                goto start;
-+            }
-+            pp = &(xi->crl);
-+        } else
-+#ifndef OPENSSL_NO_RSA
-+        if (strcmp(name, PEM_STRING_RSA) == 0) {
-+            d2i = (D2I_OF(void)) d2i_RSAPrivateKey;
-+            if (xi->x_pkey != NULL) {
-+                if (!sk_X509_INFO_push(ret, xi))
-+                    goto err;
-+                if ((xi = X509_INFO_new()) == NULL)
-+                    goto err;
-+                goto start;
-+            }
-+
-+            xi->enc_data = NULL;
-+            xi->enc_len = 0;
-+
-+            xi->x_pkey = X509_PKEY_new();
-+            if (xi->x_pkey == NULL)
-+                goto err;
-+            ptype = EVP_PKEY_RSA;
-+            pp = &xi->x_pkey->dec_pkey;
-+            if ((int)strlen(header) > 10) /* assume encrypted */
-+                raw = 1;
-+        } else
-+#endif
-+#ifndef OPENSSL_NO_DSA
-+        if (strcmp(name, PEM_STRING_DSA) == 0) {
-+            d2i = (D2I_OF(void)) d2i_DSAPrivateKey;
-+            if (xi->x_pkey != NULL) {
-+                if (!sk_X509_INFO_push(ret, xi))
-+                    goto err;
-+                if ((xi = X509_INFO_new()) == NULL)
-+                    goto err;
-+                goto start;
-+            }
-+
-+            xi->enc_data = NULL;
-+            xi->enc_len = 0;
-+
-+            xi->x_pkey = X509_PKEY_new();
-+            if (xi->x_pkey == NULL)
-+                goto err;
-+            ptype = EVP_PKEY_DSA;
-+            pp = &xi->x_pkey->dec_pkey;
-+            if ((int)strlen(header) > 10) /* assume encrypted */
-+                raw = 1;
-+        } else
-+#endif
-+#ifndef OPENSSL_NO_EC
-+        if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) {
-+            d2i = (D2I_OF(void)) d2i_ECPrivateKey;
-+            if (xi->x_pkey != NULL) {
-+                if (!sk_X509_INFO_push(ret, xi))
-+                    goto err;
-+                if ((xi = X509_INFO_new()) == NULL)
-+                    goto err;
-+                goto start;
-+            }
-+
-+            xi->enc_data = NULL;
-+            xi->enc_len = 0;
-+
-+            xi->x_pkey = X509_PKEY_new();
-+            if (xi->x_pkey == NULL)
-+                goto err;
-+            ptype = EVP_PKEY_EC;
-+            pp = &xi->x_pkey->dec_pkey;
-+            if ((int)strlen(header) > 10) /* assume encrypted */
-+                raw = 1;
-+        } else
-+#endif
-+        {
-+            d2i = NULL;
-+            pp = NULL;
-+        }
-+
-+        if (d2i != NULL) {
-+            if (!raw) {
-+                EVP_CIPHER_INFO cipher;
-+
-+                if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
-+                    goto err;
-+                if (!PEM_do_header(&cipher, data, &len, cb, u))
-+                    goto err;
-+                p = data;
-+                if (ptype) {
-+                    if (!d2i_PrivateKey(ptype, pp, &p, len)) {
-+                        PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB);
-+                        goto err;
-+                    }
-+                } else if (d2i(pp, &p, len) == NULL) {
-+                    PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB);
-+                    goto err;
-+                }
-+            } else {            /* encrypted RSA data */
-+                if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher))
-+                    goto err;
-+                xi->enc_data = (char *)data;
-+                xi->enc_len = (int)len;
-+                data = NULL;
-+            }
-+        } else {
-+            /* unknown */
-+        }
-+        OPENSSL_free(name);
-+        name = NULL;
-+        OPENSSL_free(header);
-+        header = NULL;
-+        OPENSSL_free(data);
-+        data = NULL;
-+    }
-+
-+    /*
-+     * if the last one hasn't been pushed yet and there is anything in it
-+     * then add it to the stack ...
-+     */
-+    if ((xi->x509 != NULL) || (xi->crl != NULL) ||
-+        (xi->x_pkey != NULL) || (xi->enc_data != NULL)) {
-+        if (!sk_X509_INFO_push(ret, xi))
-+            goto err;
-+        xi = NULL;
-+    }
-+    ok = 1;
-+ err:
-+    X509_INFO_free(xi);
-+    if (!ok) {
-+        for (i = 0; ((int)i) < sk_X509_INFO_num(ret); i++) {
-+            xi = sk_X509_INFO_value(ret, i);
-+            X509_INFO_free(xi);
-+        }
-+        if (ret != sk)
-+            sk_X509_INFO_free(ret);
-+        ret = NULL;
-+    }
-+
-+    OPENSSL_free(name);
-+    OPENSSL_free(header);
-+    OPENSSL_free(data);
-+    return (ret);
-+}
-+
-+/* A TJH addition */
-+int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
-+                            unsigned char *kstr, int klen,
-+                            pem_password_cb *cb, void *u)
-+{
-+    int i, ret = 0;
-+    unsigned char *data = NULL;
-+    const char *objstr = NULL;
-+    char buf[PEM_BUFSIZE];
-+    unsigned char *iv = NULL;
-+
-+    if (enc != NULL) {
-+        objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
-+        if (objstr == NULL) {
-+            PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER);
-+            goto err;
-+        }
-+    }
-+
-+    /*
-+     * now for the fun part ... if we have a private key then we have to be
-+     * able to handle a not-yet-decrypted key being written out correctly ...
-+     * if it is decrypted or it is non-encrypted then we use the base code
-+     */
-+    if (xi->x_pkey != NULL) {
-+        if ((xi->enc_data != NULL) && (xi->enc_len > 0)) {
-+            if (enc == NULL) {
-+                PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_CIPHER_IS_NULL);
-+                goto err;
-+            }
-+
-+            /* copy from weirdo names into more normal things */
-+            iv = xi->enc_cipher.iv;
-+            data = (unsigned char *)xi->enc_data;
-+            i = xi->enc_len;
-+
-+            /*
-+             * we take the encryption data from the internal stuff rather
-+             * than what the user has passed us ... as we have to match
-+             * exactly for some strange reason
-+             */
-+            objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher));
-+            if (objstr == NULL) {
-+                PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,
-+                       PEM_R_UNSUPPORTED_CIPHER);
-+                goto err;
-+            }
-+
-+            /* create the right magic header stuff */
-+            OPENSSL_assert(strlen(objstr) + 23
-+                           + 2 * EVP_CIPHER_iv_length(enc) + 13 <=
-+                           sizeof buf);
-+            buf[0] = '\0';
-+            PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
-+            PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc),
-+                         (char *)iv);
-+
-+            /* use the normal code to write things out */
-+            i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i);
-+            if (i <= 0)
-+                goto err;
-+        } else {
-+            /* Add DSA/DH */
-+#ifndef OPENSSL_NO_RSA
-+            /* normal optionally encrypted stuff */
-+            if (PEM_write_bio_RSAPrivateKey(bp,
-+                                            EVP_PKEY_get0_RSA(xi->x_pkey->dec_pkey),
-+                                            enc, kstr, klen, cb, u) <= 0)
-+                goto err;
-+#endif
-+        }
-+    }
-+
-+    /* if we have a certificate then write it out now */
-+    if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0))
-+        goto err;
-+
-+    /*
-+     * we are ignoring anything else that is loaded into the X509_INFO
-+     * structure for the moment ... as I don't need it so I'm not coding it
-+     * here and Eric can do it when this makes it into the base library --tjh
-+     */
-+
-+    ret = 1;
-+
-+ err:
-+    OPENSSL_cleanse(buf, PEM_BUFSIZE);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_lib.c
-new file mode 100644
-index 0000000..2792593
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_lib.c
-@@ -0,0 +1,857 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include 
-+#include 
-+
-+#define MIN_LENGTH      4
-+
-+static int load_iv(char **fromp, unsigned char *to, int num);
-+static int check_pem(const char *nm, const char *name);
-+int pem_check_suffix(const char *pem_str, const char *suffix);
-+
-+int PEM_def_callback(char *buf, int num, int w, void *key)
-+{
-+#if defined(OPENSSL_NO_STDIO) || defined(OPENSSL_NO_UI)
-+    int i;
-+#else
-+    int i, j;
-+    const char *prompt;
-+#endif
-+
-+    if (key) {
-+        i = strlen(key);
-+        i = (i > num) ? num : i;
-+        memcpy(buf, key, i);
-+        return i;
-+    }
-+
-+#if defined(OPENSSL_NO_STDIO) || defined(OPENSSL_NO_UI)
-+    PEMerr(PEM_F_PEM_DEF_CALLBACK, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-+    return -1;
-+#else
-+    prompt = EVP_get_pw_prompt();
-+    if (prompt == NULL)
-+        prompt = "Enter PEM pass phrase:";
-+
-+    for (;;) {
-+        /*
-+         * We assume that w == 0 means decryption,
-+         * while w == 1 means encryption
-+         */
-+        int min_len = w ? MIN_LENGTH : 0;
-+
-+        i = EVP_read_pw_string_min(buf, min_len, num, prompt, w);
-+        if (i != 0) {
-+            PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD);
-+            memset(buf, 0, (unsigned int)num);
-+            return -1;
-+        }
-+        j = strlen(buf);
-+        if (min_len && j < min_len) {
-+            fprintf(stderr,
-+                    "phrase is too short, needs to be at least %d chars\n",
-+                    min_len);
-+        } else
-+            break;
-+    }
-+    return j;
-+#endif
-+}
-+
-+void PEM_proc_type(char *buf, int type)
-+{
-+    const char *str;
-+
-+    if (type == PEM_TYPE_ENCRYPTED)
-+        str = "ENCRYPTED";
-+    else if (type == PEM_TYPE_MIC_CLEAR)
-+        str = "MIC-CLEAR";
-+    else if (type == PEM_TYPE_MIC_ONLY)
-+        str = "MIC-ONLY";
-+    else
-+        str = "BAD-TYPE";
-+
-+    OPENSSL_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE);
-+    OPENSSL_strlcat(buf, str, PEM_BUFSIZE);
-+    OPENSSL_strlcat(buf, "\n", PEM_BUFSIZE);
-+}
-+
-+void PEM_dek_info(char *buf, const char *type, int len, char *str)
-+{
-+    static const unsigned char map[17] = "0123456789ABCDEF";
-+    long i;
-+    int j;
-+
-+    OPENSSL_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE);
-+    OPENSSL_strlcat(buf, type, PEM_BUFSIZE);
-+    OPENSSL_strlcat(buf, ",", PEM_BUFSIZE);
-+    j = strlen(buf);
-+    if (j + (len * 2) + 1 > PEM_BUFSIZE)
-+        return;
-+    for (i = 0; i < len; i++) {
-+        buf[j + i * 2] = map[(str[i] >> 4) & 0x0f];
-+        buf[j + i * 2 + 1] = map[(str[i]) & 0x0f];
-+    }
-+    buf[j + i * 2] = '\n';
-+    buf[j + i * 2 + 1] = '\0';
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
-+                    pem_password_cb *cb, void *u)
-+{
-+    BIO *b;
-+    void *ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        PEMerr(PEM_F_PEM_ASN1_READ, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-+
-+static int check_pem(const char *nm, const char *name)
-+{
-+    /* Normal matching nm and name */
-+    if (strcmp(nm, name) == 0)
-+        return 1;
-+
-+    /* Make PEM_STRING_EVP_PKEY match any private key */
-+
-+    if (strcmp(name, PEM_STRING_EVP_PKEY) == 0) {
-+        int slen;
-+        const EVP_PKEY_ASN1_METHOD *ameth;
-+        if (strcmp(nm, PEM_STRING_PKCS8) == 0)
-+            return 1;
-+        if (strcmp(nm, PEM_STRING_PKCS8INF) == 0)
-+            return 1;
-+        slen = pem_check_suffix(nm, "PRIVATE KEY");
-+        if (slen > 0) {
-+            /*
-+             * NB: ENGINE implementations won't contain a deprecated old
-+             * private key decode function so don't look for them.
-+             */
-+            ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
-+            if (ameth && ameth->old_priv_decode)
-+                return 1;
-+        }
-+        return 0;
-+    }
-+
-+    if (strcmp(name, PEM_STRING_PARAMETERS) == 0) {
-+        int slen;
-+        const EVP_PKEY_ASN1_METHOD *ameth;
-+        slen = pem_check_suffix(nm, "PARAMETERS");
-+        if (slen > 0) {
-+            ENGINE *e;
-+            ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
-+            if (ameth) {
-+                int r;
-+                if (ameth->param_decode)
-+                    r = 1;
-+                else
-+                    r = 0;
-+#ifndef OPENSSL_NO_ENGINE
-+                ENGINE_finish(e);
-+#endif
-+                return r;
-+            }
-+        }
-+        return 0;
-+    }
-+    /* If reading DH parameters handle X9.42 DH format too */
-+    if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0
-+        && strcmp(name, PEM_STRING_DHPARAMS) == 0)
-+        return 1;
-+
-+    /* Permit older strings */
-+
-+    if (strcmp(nm, PEM_STRING_X509_OLD) == 0
-+        && strcmp(name, PEM_STRING_X509) == 0)
-+        return 1;
-+
-+    if (strcmp(nm, PEM_STRING_X509_REQ_OLD) == 0
-+        && strcmp(name, PEM_STRING_X509_REQ) == 0)
-+        return 1;
-+
-+    /* Allow normal certs to be read as trusted certs */
-+    if (strcmp(nm, PEM_STRING_X509) == 0
-+        && strcmp(name, PEM_STRING_X509_TRUSTED) == 0)
-+        return 1;
-+
-+    if (strcmp(nm, PEM_STRING_X509_OLD) == 0
-+        && strcmp(name, PEM_STRING_X509_TRUSTED) == 0)
-+        return 1;
-+
-+    /* Some CAs use PKCS#7 with CERTIFICATE headers */
-+    if (strcmp(nm, PEM_STRING_X509) == 0
-+        && strcmp(name, PEM_STRING_PKCS7) == 0)
-+        return 1;
-+
-+    if (strcmp(nm, PEM_STRING_PKCS7_SIGNED) == 0
-+        && strcmp(name, PEM_STRING_PKCS7) == 0)
-+        return 1;
-+
-+#ifndef OPENSSL_NO_CMS
-+    if (strcmp(nm, PEM_STRING_X509) == 0
-+        && strcmp(name, PEM_STRING_CMS) == 0)
-+        return 1;
-+    /* Allow CMS to be read from PKCS#7 headers */
-+    if (strcmp(nm, PEM_STRING_PKCS7) == 0
-+        && strcmp(name, PEM_STRING_CMS) == 0)
-+        return 1;
-+#endif
-+
-+    return 0;
-+}
-+
-+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
-+                       const char *name, BIO *bp, pem_password_cb *cb,
-+                       void *u)
-+{
-+    EVP_CIPHER_INFO cipher;
-+    char *nm = NULL, *header = NULL;
-+    unsigned char *data = NULL;
-+    long len;
-+    int ret = 0;
-+
-+    for (;;) {
-+        if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
-+            if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE)
-+                ERR_add_error_data(2, "Expecting: ", name);
-+            return 0;
-+        }
-+        if (check_pem(nm, name))
-+            break;
-+        OPENSSL_free(nm);
-+        OPENSSL_free(header);
-+        OPENSSL_free(data);
-+    }
-+    if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
-+        goto err;
-+    if (!PEM_do_header(&cipher, data, &len, cb, u))
-+        goto err;
-+
-+    *pdata = data;
-+    *plen = len;
-+
-+    if (pnm)
-+        *pnm = nm;
-+
-+    ret = 1;
-+
-+ err:
-+    if (!ret || !pnm)
-+        OPENSSL_free(nm);
-+    OPENSSL_free(header);
-+    if (!ret)
-+        OPENSSL_free(data);
-+    return ret;
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
-+                   void *x, const EVP_CIPHER *enc, unsigned char *kstr,
-+                   int klen, pem_password_cb *callback, void *u)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        PEMerr(PEM_F_PEM_ASN1_WRITE, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-+
-+int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
-+                       void *x, const EVP_CIPHER *enc, unsigned char *kstr,
-+                       int klen, pem_password_cb *callback, void *u)
-+{
-+    EVP_CIPHER_CTX *ctx = NULL;
-+    int dsize = 0, i = 0, j = 0, ret = 0;
-+    unsigned char *p, *data = NULL;
-+    const char *objstr = NULL;
-+    char buf[PEM_BUFSIZE];
-+    unsigned char key[EVP_MAX_KEY_LENGTH];
-+    unsigned char iv[EVP_MAX_IV_LENGTH];
-+
-+    if (enc != NULL) {
-+        objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
-+        if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0) {
-+            PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER);
-+            goto err;
-+        }
-+    }
-+
-+    if ((dsize = i2d(x, NULL)) < 0) {
-+        PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB);
-+        dsize = 0;
-+        goto err;
-+    }
-+    /* dzise + 8 bytes are needed */
-+    /* actually it needs the cipher block size extra... */
-+    data = OPENSSL_malloc((unsigned int)dsize + 20);
-+    if (data == NULL) {
-+        PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    p = data;
-+    i = i2d(x, &p);
-+
-+    if (enc != NULL) {
-+        if (kstr == NULL) {
-+            if (callback == NULL)
-+                klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
-+            else
-+                klen = (*callback) (buf, PEM_BUFSIZE, 1, u);
-+            if (klen <= 0) {
-+                PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY);
-+                goto err;
-+            }
-+#ifdef CHARSET_EBCDIC
-+            /* Convert the pass phrase from EBCDIC */
-+            ebcdic2ascii(buf, buf, klen);
-+#endif
-+            kstr = (unsigned char *)buf;
-+        }
-+        RAND_add(data, i, 0);   /* put in the RSA key. */
-+        OPENSSL_assert(EVP_CIPHER_iv_length(enc) <= (int)sizeof(iv));
-+        if (RAND_bytes(iv, EVP_CIPHER_iv_length(enc)) <= 0) /* Generate a salt */
-+            goto err;
-+        /*
-+         * The 'iv' is used as the iv and as a salt.  It is NOT taken from
-+         * the BytesToKey function
-+         */
-+        if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL))
-+            goto err;
-+
-+        if (kstr == (unsigned char *)buf)
-+            OPENSSL_cleanse(buf, PEM_BUFSIZE);
-+
-+        OPENSSL_assert(strlen(objstr) + 23 + 2 * EVP_CIPHER_iv_length(enc) + 13
-+                       <= sizeof buf);
-+
-+        buf[0] = '\0';
-+        PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
-+        PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc), (char *)iv);
-+        /* k=strlen(buf); */
-+
-+        ret = 1;
-+        if ((ctx = EVP_CIPHER_CTX_new()) == NULL
-+            || !EVP_EncryptInit_ex(ctx, enc, NULL, key, iv)
-+            || !EVP_EncryptUpdate(ctx, data, &j, data, i)
-+            || !EVP_EncryptFinal_ex(ctx, &(data[j]), &i))
-+            ret = 0;
-+        if (ret == 0)
-+            goto err;
-+        i += j;
-+    } else {
-+        ret = 1;
-+        buf[0] = '\0';
-+    }
-+    i = PEM_write_bio(bp, name, buf, data, i);
-+    if (i <= 0)
-+        ret = 0;
-+ err:
-+    OPENSSL_cleanse(key, sizeof(key));
-+    OPENSSL_cleanse(iv, sizeof(iv));
-+    EVP_CIPHER_CTX_free(ctx);
-+    OPENSSL_cleanse(buf, PEM_BUFSIZE);
-+    OPENSSL_clear_free(data, (unsigned int)dsize);
-+    return (ret);
-+}
-+
-+int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
-+                  pem_password_cb *callback, void *u)
-+{
-+    int ok;
-+    int keylen;
-+    long len = *plen;
-+    int ilen = (int) len;       /* EVP_DecryptUpdate etc. take int lengths */
-+    EVP_CIPHER_CTX *ctx;
-+    unsigned char key[EVP_MAX_KEY_LENGTH];
-+    char buf[PEM_BUFSIZE];
-+
-+#if LONG_MAX > INT_MAX
-+    /* Check that we did not truncate the length */
-+    if (len > INT_MAX) {
-+        PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_HEADER_TOO_LONG);
-+        return 0;
-+    }
-+#endif
-+
-+    if (cipher->cipher == NULL)
-+        return 1;
-+    if (callback == NULL)
-+        keylen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u);
-+    else
-+        keylen = callback(buf, PEM_BUFSIZE, 0, u);
-+    if (keylen <= 0) {
-+        PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ);
-+        return 0;
-+    }
-+#ifdef CHARSET_EBCDIC
-+    /* Convert the pass phrase from EBCDIC */
-+    ebcdic2ascii(buf, buf, keylen);
-+#endif
-+
-+    if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]),
-+                        (unsigned char *)buf, keylen, 1, key, NULL))
-+        return 0;
-+
-+    ctx = EVP_CIPHER_CTX_new();
-+    if (ctx == NULL)
-+        return 0;
-+
-+    ok = EVP_DecryptInit_ex(ctx, cipher->cipher, NULL, key, &(cipher->iv[0]));
-+    if (ok)
-+        ok = EVP_DecryptUpdate(ctx, data, &ilen, data, ilen);
-+    if (ok) {
-+        /* Squirrel away the length of data decrypted so far. */
-+        *plen = ilen;
-+        ok = EVP_DecryptFinal_ex(ctx, &(data[ilen]), &ilen);
-+    }
-+    if (ok)
-+        *plen += ilen;
-+    else
-+        PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT);
-+
-+    EVP_CIPHER_CTX_free(ctx);
-+    OPENSSL_cleanse((char *)buf, sizeof(buf));
-+    OPENSSL_cleanse((char *)key, sizeof(key));
-+    return ok;
-+}
-+
-+/*
-+ * This implements a very limited PEM header parser that does not support the
-+ * full grammar of rfc1421.  In particular, folded headers are not supported,
-+ * nor is additional whitespace.
-+ *
-+ * A robust implementation would make use of a library that turns the headers
-+ * into a BIO from which one folded line is read at a time, and is then split
-+ * into a header label and content.  We would then parse the content of the
-+ * headers we care about.  This is overkill for just this limited use-case, but
-+ * presumably we also parse rfc822-style headers for S/MIME, so a common
-+ * abstraction might well be more generally useful.
-+ */
-+int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
-+{
-+    static const char ProcType[] = "Proc-Type:";
-+    static const char ENCRYPTED[] = "ENCRYPTED";
-+    static const char DEKInfo[] = "DEK-Info:";
-+    const EVP_CIPHER *enc = NULL;
-+    int ivlen;
-+    char *dekinfostart, c;
-+
-+    cipher->cipher = NULL;
-+    if ((header == NULL) || (*header == '\0') || (*header == '\n'))
-+        return 1;
-+
-+    if (strncmp(header, ProcType, sizeof(ProcType)-1) != 0) {
-+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE);
-+        return 0;
-+    }
-+    header += sizeof(ProcType)-1;
-+    header += strspn(header, " \t");
-+
-+    if (*header++ != '4' || *header++ != ',')
-+        return 0;
-+    header += strspn(header, " \t");
-+
-+    /* We expect "ENCRYPTED" followed by optional white-space + line break */
-+    if (strncmp(header, ENCRYPTED, sizeof(ENCRYPTED)-1) != 0 ||
-+        strspn(header+sizeof(ENCRYPTED)-1, " \t\r\n") == 0) {
-+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED);
-+        return 0;
-+    }
-+    header += sizeof(ENCRYPTED)-1;
-+    header += strspn(header, " \t\r");
-+    if (*header++ != '\n') {
-+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER);
-+        return 0;
-+    }
-+
-+    /*-
-+     * https://tools.ietf.org/html/rfc1421#section-4.6.1.3
-+     * We expect "DEK-Info: algo[,hex-parameters]"
-+     */
-+    if (strncmp(header, DEKInfo, sizeof(DEKInfo)-1) != 0) {
-+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO);
-+        return 0;
-+    }
-+    header += sizeof(DEKInfo)-1;
-+    header += strspn(header, " \t");
-+
-+    /*
-+     * DEK-INFO is a comma-separated combination of algorithm name and optional
-+     * parameters.
-+     */
-+    dekinfostart = header;
-+    header += strcspn(header, " \t,");
-+    c = *header;
-+    *header = '\0';
-+    cipher->cipher = enc = EVP_get_cipherbyname(dekinfostart);
-+    *header = c;
-+    header += strspn(header, " \t");
-+
-+    if (enc == NULL) {
-+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNSUPPORTED_ENCRYPTION);
-+        return 0;
-+    }
-+    ivlen = EVP_CIPHER_iv_length(enc);
-+    if (ivlen > 0 && *header++ != ',') {
-+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_MISSING_DEK_IV);
-+        return 0;
-+    } else if (ivlen == 0 && *header == ',') {
-+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNEXPECTED_DEK_IV);
-+        return 0;
-+    }
-+
-+    if (!load_iv(&header, cipher->iv, EVP_CIPHER_iv_length(enc)))
-+        return 0;
-+
-+    return 1;
-+}
-+
-+static int load_iv(char **fromp, unsigned char *to, int num)
-+{
-+    int v, i;
-+    char *from;
-+
-+    from = *fromp;
-+    for (i = 0; i < num; i++)
-+        to[i] = 0;
-+    num *= 2;
-+    for (i = 0; i < num; i++) {
-+        v = OPENSSL_hexchar2int(*from);
-+        if (v < 0) {
-+            PEMerr(PEM_F_LOAD_IV, PEM_R_BAD_IV_CHARS);
-+            return (0);
-+        }
-+        from++;
-+        to[i / 2] |= v << (long)((!(i & 1)) * 4);
-+    }
-+
-+    *fromp = from;
-+    return (1);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+int PEM_write(FILE *fp, const char *name, const char *header,
-+              const unsigned char *data, long len)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        PEMerr(PEM_F_PEM_WRITE, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = PEM_write_bio(b, name, header, data, len);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-+
-+int PEM_write_bio(BIO *bp, const char *name, const char *header,
-+                  const unsigned char *data, long len)
-+{
-+    int nlen, n, i, j, outl;
-+    unsigned char *buf = NULL;
-+    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
-+    int reason = ERR_R_BUF_LIB;
-+
-+    if (ctx == NULL) {
-+        reason = ERR_R_MALLOC_FAILURE;
-+        goto err;
-+    }
-+
-+    EVP_EncodeInit(ctx);
-+    nlen = strlen(name);
-+
-+    if ((BIO_write(bp, "-----BEGIN ", 11) != 11) ||
-+        (BIO_write(bp, name, nlen) != nlen) ||
-+        (BIO_write(bp, "-----\n", 6) != 6))
-+        goto err;
-+
-+    i = strlen(header);
-+    if (i > 0) {
-+        if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1))
-+            goto err;
-+    }
-+
-+    buf = OPENSSL_malloc(PEM_BUFSIZE * 8);
-+    if (buf == NULL) {
-+        reason = ERR_R_MALLOC_FAILURE;
-+        goto err;
-+    }
-+
-+    i = j = 0;
-+    while (len > 0) {
-+        n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len);
-+        if (!EVP_EncodeUpdate(ctx, buf, &outl, &(data[j]), n))
-+            goto err;
-+        if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl))
-+            goto err;
-+        i += outl;
-+        len -= n;
-+        j += n;
-+    }
-+    EVP_EncodeFinal(ctx, buf, &outl);
-+    if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl))
-+        goto err;
-+    if ((BIO_write(bp, "-----END ", 9) != 9) ||
-+        (BIO_write(bp, name, nlen) != nlen) ||
-+        (BIO_write(bp, "-----\n", 6) != 6))
-+        goto err;
-+    OPENSSL_clear_free(buf, PEM_BUFSIZE * 8);
-+    EVP_ENCODE_CTX_free(ctx);
-+    return (i + outl);
-+ err:
-+    OPENSSL_clear_free(buf, PEM_BUFSIZE * 8);
-+    EVP_ENCODE_CTX_free(ctx);
-+    PEMerr(PEM_F_PEM_WRITE_BIO, reason);
-+    return (0);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
-+             long *len)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        PEMerr(PEM_F_PEM_READ, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = PEM_read_bio(b, name, header, data, len);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-+
-+int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
-+                 long *len)
-+{
-+    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
-+    int end = 0, i, k, bl = 0, hl = 0, nohead = 0;
-+    char buf[256];
-+    BUF_MEM *nameB;
-+    BUF_MEM *headerB;
-+    BUF_MEM *dataB, *tmpB;
-+
-+    if (ctx == NULL) {
-+        PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
-+        return (0);
-+    }
-+
-+    nameB = BUF_MEM_new();
-+    headerB = BUF_MEM_new();
-+    dataB = BUF_MEM_new();
-+    if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) {
-+        goto err;
-+    }
-+
-+    buf[254] = '\0';
-+    for (;;) {
-+        i = BIO_gets(bp, buf, 254);
-+
-+        if (i <= 0) {
-+            PEMerr(PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE);
-+            goto err;
-+        }
-+
-+        while ((i >= 0) && (buf[i] <= ' '))
-+            i--;
-+        buf[++i] = '\n';
-+        buf[++i] = '\0';
-+
-+        if (strncmp(buf, "-----BEGIN ", 11) == 0) {
-+            i = strlen(&(buf[11]));
-+
-+            if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0)
-+                continue;
-+            if (!BUF_MEM_grow(nameB, i + 9)) {
-+                PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            memcpy(nameB->data, &(buf[11]), i - 6);
-+            nameB->data[i - 6] = '\0';
-+            break;
-+        }
-+    }
-+    hl = 0;
-+    if (!BUF_MEM_grow(headerB, 256)) {
-+        PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    headerB->data[0] = '\0';
-+    for (;;) {
-+        i = BIO_gets(bp, buf, 254);
-+        if (i <= 0)
-+            break;
-+
-+        while ((i >= 0) && (buf[i] <= ' '))
-+            i--;
-+        buf[++i] = '\n';
-+        buf[++i] = '\0';
-+
-+        if (buf[0] == '\n')
-+            break;
-+        if (!BUF_MEM_grow(headerB, hl + i + 9)) {
-+            PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (strncmp(buf, "-----END ", 9) == 0) {
-+            nohead = 1;
-+            break;
-+        }
-+        memcpy(&(headerB->data[hl]), buf, i);
-+        headerB->data[hl + i] = '\0';
-+        hl += i;
-+    }
-+
-+    bl = 0;
-+    if (!BUF_MEM_grow(dataB, 1024)) {
-+        PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    dataB->data[0] = '\0';
-+    if (!nohead) {
-+        for (;;) {
-+            i = BIO_gets(bp, buf, 254);
-+            if (i <= 0)
-+                break;
-+
-+            while ((i >= 0) && (buf[i] <= ' '))
-+                i--;
-+            buf[++i] = '\n';
-+            buf[++i] = '\0';
-+
-+            if (i != 65)
-+                end = 1;
-+            if (strncmp(buf, "-----END ", 9) == 0)
-+                break;
-+            if (i > 65)
-+                break;
-+            if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) {
-+                PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            memcpy(&(dataB->data[bl]), buf, i);
-+            dataB->data[bl + i] = '\0';
-+            bl += i;
-+            if (end) {
-+                buf[0] = '\0';
-+                i = BIO_gets(bp, buf, 254);
-+                if (i <= 0)
-+                    break;
-+
-+                while ((i >= 0) && (buf[i] <= ' '))
-+                    i--;
-+                buf[++i] = '\n';
-+                buf[++i] = '\0';
-+
-+                break;
-+            }
-+        }
-+    } else {
-+        tmpB = headerB;
-+        headerB = dataB;
-+        dataB = tmpB;
-+        bl = hl;
-+    }
-+    i = strlen(nameB->data);
-+    if ((strncmp(buf, "-----END ", 9) != 0) ||
-+        (strncmp(nameB->data, &(buf[9]), i) != 0) ||
-+        (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) {
-+        PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_END_LINE);
-+        goto err;
-+    }
-+
-+    EVP_DecodeInit(ctx);
-+    i = EVP_DecodeUpdate(ctx,
-+                         (unsigned char *)dataB->data, &bl,
-+                         (unsigned char *)dataB->data, bl);
-+    if (i < 0) {
-+        PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
-+        goto err;
-+    }
-+    i = EVP_DecodeFinal(ctx, (unsigned char *)&(dataB->data[bl]), &k);
-+    if (i < 0) {
-+        PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
-+        goto err;
-+    }
-+    bl += k;
-+
-+    if (bl == 0)
-+        goto err;
-+    *name = nameB->data;
-+    *header = headerB->data;
-+    *data = (unsigned char *)dataB->data;
-+    *len = bl;
-+    OPENSSL_free(nameB);
-+    OPENSSL_free(headerB);
-+    OPENSSL_free(dataB);
-+    EVP_ENCODE_CTX_free(ctx);
-+    return (1);
-+ err:
-+    BUF_MEM_free(nameB);
-+    BUF_MEM_free(headerB);
-+    BUF_MEM_free(dataB);
-+    EVP_ENCODE_CTX_free(ctx);
-+    return (0);
-+}
-+
-+/*
-+ * Check pem string and return prefix length. If for example the pem_str ==
-+ * "RSA PRIVATE KEY" and suffix = "PRIVATE KEY" the return value is 3 for the
-+ * string "RSA".
-+ */
-+
-+int pem_check_suffix(const char *pem_str, const char *suffix)
-+{
-+    int pem_len = strlen(pem_str);
-+    int suffix_len = strlen(suffix);
-+    const char *p;
-+    if (suffix_len + 1 >= pem_len)
-+        return 0;
-+    p = pem_str + pem_len - suffix_len;
-+    if (strcmp(p, suffix))
-+        return 0;
-+    p--;
-+    if (*p != ' ')
-+        return 0;
-+    return p - pem_str;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_oth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_oth.c
-new file mode 100644
-index 0000000..cc7a8db
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_oth.c
-@@ -0,0 +1,36 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+/* Handle 'other' PEMs: not private keys */
-+
-+void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
-+                        pem_password_cb *cb, void *u)
-+{
-+    const unsigned char *p = NULL;
-+    unsigned char *data = NULL;
-+    long len;
-+    char *ret = NULL;
-+
-+    if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
-+        return NULL;
-+    p = data;
-+    ret = d2i(x, &p, len);
-+    if (ret == NULL)
-+        PEMerr(PEM_F_PEM_ASN1_READ_BIO, ERR_R_ASN1_LIB);
-+    OPENSSL_free(data);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_pk8.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_pk8.c
-new file mode 100644
-index 0000000..993c595
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_pk8.c
-@@ -0,0 +1,213 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
-+                      int nid, const EVP_CIPHER *enc,
-+                      char *kstr, int klen, pem_password_cb *cb, void *u);
-+
-+#ifndef OPENSSL_NO_STDIO
-+static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
-+                         int nid, const EVP_CIPHER *enc,
-+                         char *kstr, int klen, pem_password_cb *cb, void *u);
-+#endif
-+/*
-+ * These functions write a private key in PKCS#8 format: it is a "drop in"
-+ * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
-+ * is NULL then it uses the unencrypted private key form. The 'nid' versions
-+ * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
-+ */
-+
-+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
-+                                      char *kstr, int klen,
-+                                      pem_password_cb *cb, void *u)
-+{
-+    return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
-+}
-+
-+int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
-+                                  char *kstr, int klen,
-+                                  pem_password_cb *cb, void *u)
-+{
-+    return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
-+}
-+
-+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
-+                            char *kstr, int klen,
-+                            pem_password_cb *cb, void *u)
-+{
-+    return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
-+}
-+
-+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
-+                                char *kstr, int klen,
-+                                pem_password_cb *cb, void *u)
-+{
-+    return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
-+}
-+
-+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid,
-+                      const EVP_CIPHER *enc, char *kstr, int klen,
-+                      pem_password_cb *cb, void *u)
-+{
-+    X509_SIG *p8;
-+    PKCS8_PRIV_KEY_INFO *p8inf;
-+    char buf[PEM_BUFSIZE];
-+    int ret;
-+
-+    if ((p8inf = EVP_PKEY2PKCS8(x)) == NULL) {
-+        PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
-+        return 0;
-+    }
-+    if (enc || (nid != -1)) {
-+        if (!kstr) {
-+            if (!cb)
-+                klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
-+            else
-+                klen = cb(buf, PEM_BUFSIZE, 1, u);
-+            if (klen <= 0) {
-+                PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY);
-+                PKCS8_PRIV_KEY_INFO_free(p8inf);
-+                return 0;
-+            }
-+
-+            kstr = buf;
-+        }
-+        p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
-+        if (kstr == buf)
-+            OPENSSL_cleanse(buf, klen);
-+        PKCS8_PRIV_KEY_INFO_free(p8inf);
-+        if (p8 == NULL)
-+            return 0;
-+        if (isder)
-+            ret = i2d_PKCS8_bio(bp, p8);
-+        else
-+            ret = PEM_write_bio_PKCS8(bp, p8);
-+        X509_SIG_free(p8);
-+        return ret;
-+    } else {
-+        if (isder)
-+            ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
-+        else
-+            ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
-+        PKCS8_PRIV_KEY_INFO_free(p8inf);
-+        return ret;
-+    }
-+}
-+
-+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
-+                                  void *u)
-+{
-+    PKCS8_PRIV_KEY_INFO *p8inf = NULL;
-+    X509_SIG *p8 = NULL;
-+    int klen;
-+    EVP_PKEY *ret;
-+    char psbuf[PEM_BUFSIZE];
-+    p8 = d2i_PKCS8_bio(bp, NULL);
-+    if (!p8)
-+        return NULL;
-+    if (cb)
-+        klen = cb(psbuf, PEM_BUFSIZE, 0, u);
-+    else
-+        klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
-+    if (klen <= 0) {
-+        PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ);
-+        X509_SIG_free(p8);
-+        return NULL;
-+    }
-+    p8inf = PKCS8_decrypt(p8, psbuf, klen);
-+    X509_SIG_free(p8);
-+    if (!p8inf)
-+        return NULL;
-+    ret = EVP_PKCS82PKEY(p8inf);
-+    PKCS8_PRIV_KEY_INFO_free(p8inf);
-+    if (!ret)
-+        return NULL;
-+    if (x) {
-+        EVP_PKEY_free(*x);
-+        *x = ret;
-+    }
-+    return ret;
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+
-+int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
-+                           char *kstr, int klen, pem_password_cb *cb, void *u)
-+{
-+    return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
-+}
-+
-+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
-+                               char *kstr, int klen,
-+                               pem_password_cb *cb, void *u)
-+{
-+    return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
-+}
-+
-+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
-+                                  char *kstr, int klen,
-+                                  pem_password_cb *cb, void *u)
-+{
-+    return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
-+}
-+
-+int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
-+                              char *kstr, int klen, pem_password_cb *cb,
-+                              void *u)
-+{
-+    return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
-+}
-+
-+static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid,
-+                         const EVP_CIPHER *enc, char *kstr, int klen,
-+                         pem_password_cb *cb, void *u)
-+{
-+    BIO *bp;
-+    int ret;
-+
-+    if ((bp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
-+        PEMerr(PEM_F_DO_PK8PKEY_FP, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
-+    BIO_free(bp);
-+    return ret;
-+}
-+
-+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
-+                                 void *u)
-+{
-+    BIO *bp;
-+    EVP_PKEY *ret;
-+
-+    if ((bp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
-+        PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP, ERR_R_BUF_LIB);
-+        return NULL;
-+    }
-+    ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
-+    BIO_free(bp);
-+    return ret;
-+}
-+
-+#endif
-+
-+IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
-+
-+
-+IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
-+             PKCS8_PRIV_KEY_INFO)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_pkey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_pkey.c
-new file mode 100644
-index 0000000..6308622
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_pkey.c
-@@ -0,0 +1,243 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+int pem_check_suffix(const char *pem_str, const char *suffix);
-+
-+EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
-+                                  void *u)
-+{
-+    char *nm = NULL;
-+    const unsigned char *p = NULL;
-+    unsigned char *data = NULL;
-+    long len;
-+    int slen;
-+    EVP_PKEY *ret = NULL;
-+
-+    if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
-+        return NULL;
-+    p = data;
-+
-+    if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) {
-+        PKCS8_PRIV_KEY_INFO *p8inf;
-+        p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
-+        if (!p8inf)
-+            goto p8err;
-+        ret = EVP_PKCS82PKEY(p8inf);
-+        if (x) {
-+            EVP_PKEY_free((EVP_PKEY *)*x);
-+            *x = ret;
-+        }
-+        PKCS8_PRIV_KEY_INFO_free(p8inf);
-+    } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) {
-+        PKCS8_PRIV_KEY_INFO *p8inf;
-+        X509_SIG *p8;
-+        int klen;
-+        char psbuf[PEM_BUFSIZE];
-+        p8 = d2i_X509_SIG(NULL, &p, len);
-+        if (!p8)
-+            goto p8err;
-+        if (cb)
-+            klen = cb(psbuf, PEM_BUFSIZE, 0, u);
-+        else
-+            klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
-+        if (klen <= 0) {
-+            PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ);
-+            X509_SIG_free(p8);
-+            goto err;
-+        }
-+        p8inf = PKCS8_decrypt(p8, psbuf, klen);
-+        X509_SIG_free(p8);
-+        if (!p8inf)
-+            goto p8err;
-+        ret = EVP_PKCS82PKEY(p8inf);
-+        if (x) {
-+            EVP_PKEY_free((EVP_PKEY *)*x);
-+            *x = ret;
-+        }
-+        PKCS8_PRIV_KEY_INFO_free(p8inf);
-+    } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) {
-+        const EVP_PKEY_ASN1_METHOD *ameth;
-+        ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
-+        if (!ameth || !ameth->old_priv_decode)
-+            goto p8err;
-+        ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len);
-+    }
-+ p8err:
-+    if (ret == NULL)
-+        PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB);
-+ err:
-+    OPENSSL_free(nm);
-+    OPENSSL_clear_free(data, len);
-+    return (ret);
-+}
-+
-+int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
-+                             unsigned char *kstr, int klen,
-+                             pem_password_cb *cb, void *u)
-+{
-+    if (x->ameth == NULL || x->ameth->priv_encode != NULL)
-+        return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
-+                                             (char *)kstr, klen, cb, u);
-+    return PEM_write_bio_PrivateKey_traditional(bp, x, enc, kstr, klen, cb, u);
-+}
-+
-+int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x,
-+                                         const EVP_CIPHER *enc,
-+                                         unsigned char *kstr, int klen,
-+                                         pem_password_cb *cb, void *u)
-+{
-+    char pem_str[80];
-+    BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str);
-+    return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
-+                              pem_str, bp, x, enc, kstr, klen, cb, u);
-+}
-+
-+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
-+{
-+    char *nm = NULL;
-+    const unsigned char *p = NULL;
-+    unsigned char *data = NULL;
-+    long len;
-+    int slen;
-+    EVP_PKEY *ret = NULL;
-+
-+    if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
-+                            bp, 0, NULL))
-+        return NULL;
-+    p = data;
-+
-+    if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) {
-+        ret = EVP_PKEY_new();
-+        if (ret == NULL)
-+            goto err;
-+        if (!EVP_PKEY_set_type_str(ret, nm, slen)
-+            || !ret->ameth->param_decode
-+            || !ret->ameth->param_decode(ret, &p, len)) {
-+            EVP_PKEY_free(ret);
-+            ret = NULL;
-+            goto err;
-+        }
-+        if (x) {
-+            EVP_PKEY_free((EVP_PKEY *)*x);
-+            *x = ret;
-+        }
-+    }
-+ err:
-+    if (ret == NULL)
-+        PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS, ERR_R_ASN1_LIB);
-+    OPENSSL_free(nm);
-+    OPENSSL_free(data);
-+    return (ret);
-+}
-+
-+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
-+{
-+    char pem_str[80];
-+    if (!x->ameth || !x->ameth->param_encode)
-+        return 0;
-+
-+    BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str);
-+    return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode,
-+                              pem_str, bp, x, NULL, NULL, 0, 0, NULL);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
-+                              void *u)
-+{
-+    BIO *b;
-+    EVP_PKEY *ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = PEM_read_bio_PrivateKey(b, x, cb, u);
-+    BIO_free(b);
-+    return (ret);
-+}
-+
-+int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
-+                         unsigned char *kstr, int klen,
-+                         pem_password_cb *cb, void *u)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
-+        PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY, ERR_R_BUF_LIB);
-+        return 0;
-+    }
-+    ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
-+    BIO_free(b);
-+    return ret;
-+}
-+
-+#endif
-+
-+#ifndef OPENSSL_NO_DH
-+
-+/* Transparently read in PKCS#3 or X9.42 DH parameters */
-+
-+DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
-+{
-+    char *nm = NULL;
-+    const unsigned char *p = NULL;
-+    unsigned char *data = NULL;
-+    long len;
-+    DH *ret = NULL;
-+
-+    if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u))
-+        return NULL;
-+    p = data;
-+
-+    if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0)
-+        ret = d2i_DHxparams(x, &p, len);
-+    else
-+        ret = d2i_DHparams(x, &p, len);
-+
-+    if (ret == NULL)
-+        PEMerr(PEM_F_PEM_READ_BIO_DHPARAMS, ERR_R_ASN1_LIB);
-+    OPENSSL_free(nm);
-+    OPENSSL_free(data);
-+    return ret;
-+}
-+
-+# ifndef OPENSSL_NO_STDIO
-+DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u)
-+{
-+    BIO *b;
-+    DH *ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        PEMerr(PEM_F_PEM_READ_DHPARAMS, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = PEM_read_bio_DHparams(b, x, cb, u);
-+    BIO_free(b);
-+    return (ret);
-+}
-+# endif
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_sign.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_sign.c
-new file mode 100644
-index 0000000..12ad974
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_sign.c
-@@ -0,0 +1,50 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
-+{
-+    return EVP_DigestInit_ex(ctx, type, NULL);
-+}
-+
-+int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count)
-+{
-+    return EVP_DigestUpdate(ctx, data, count);
-+}
-+
-+int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
-+                  unsigned int *siglen, EVP_PKEY *pkey)
-+{
-+    unsigned char *m;
-+    int i, ret = 0;
-+    unsigned int m_len;
-+
-+    m = OPENSSL_malloc(EVP_PKEY_size(pkey) + 2);
-+    if (m == NULL) {
-+        PEMerr(PEM_F_PEM_SIGNFINAL, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0)
-+        goto err;
-+
-+    i = EVP_EncodeBlock(sigret, m, m_len);
-+    *siglen = i;
-+    ret = 1;
-+ err:
-+    /* ctx has been zeroed by EVP_SignFinal() */
-+    OPENSSL_free(m);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_x509.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_x509.c
-new file mode 100644
-index 0000000..3a99756
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_x509.c
-@@ -0,0 +1,18 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_xaux.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_xaux.c
-new file mode 100644
-index 0000000..6d7e1db
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pem_xaux.c
-@@ -0,0 +1,18 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pvkfmt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pvkfmt.c
-new file mode 100644
-index 0000000..248704e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pem/pvkfmt.c
-@@ -0,0 +1,869 @@
-+/*
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Support for PVK format keys and related structures (such a PUBLICKEYBLOB
-+ * and PRIVATEKEYBLOB).
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
-+# include 
-+# include 
-+
-+/*
-+ * Utility function: read a DWORD (4 byte unsigned integer) in little endian
-+ * format
-+ */
-+
-+static unsigned int read_ledword(const unsigned char **in)
-+{
-+    const unsigned char *p = *in;
-+    unsigned int ret;
-+    ret = *p++;
-+    ret |= (*p++ << 8);
-+    ret |= (*p++ << 16);
-+    ret |= (*p++ << 24);
-+    *in = p;
-+    return ret;
-+}
-+
-+/*
-+ * Read a BIGNUM in little endian format. The docs say that this should take
-+ * up bitlen/8 bytes.
-+ */
-+
-+static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
-+{
-+    *r = BN_lebin2bn(*in, nbyte, NULL);
-+    if (*r == NULL)
-+        return 0;
-+    *in += nbyte;
-+    return 1;
-+}
-+
-+/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
-+
-+# define MS_PUBLICKEYBLOB        0x6
-+# define MS_PRIVATEKEYBLOB       0x7
-+# define MS_RSA1MAGIC            0x31415352L
-+# define MS_RSA2MAGIC            0x32415352L
-+# define MS_DSS1MAGIC            0x31535344L
-+# define MS_DSS2MAGIC            0x32535344L
-+
-+# define MS_KEYALG_RSA_KEYX      0xa400
-+# define MS_KEYALG_DSS_SIGN      0x2200
-+
-+# define MS_KEYTYPE_KEYX         0x1
-+# define MS_KEYTYPE_SIGN         0x2
-+
-+/* Maximum length of a blob after header */
-+# define BLOB_MAX_LENGTH          102400
-+
-+/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
-+# define MS_PVKMAGIC             0xb0b5f11eL
-+/* Salt length for PVK files */
-+# define PVK_SALTLEN             0x10
-+/* Maximum length in PVK header */
-+# define PVK_MAX_KEYLEN          102400
-+/* Maximum salt length */
-+# define PVK_MAX_SALTLEN         10240
-+
-+static EVP_PKEY *b2i_rsa(const unsigned char **in,
-+                         unsigned int bitlen, int ispub);
-+static EVP_PKEY *b2i_dss(const unsigned char **in,
-+                         unsigned int bitlen, int ispub);
-+
-+static int do_blob_header(const unsigned char **in, unsigned int length,
-+                          unsigned int *pmagic, unsigned int *pbitlen,
-+                          int *pisdss, int *pispub)
-+{
-+    const unsigned char *p = *in;
-+    if (length < 16)
-+        return 0;
-+    /* bType */
-+    if (*p == MS_PUBLICKEYBLOB) {
-+        if (*pispub == 0) {
-+            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
-+            return 0;
-+        }
-+        *pispub = 1;
-+    } else if (*p == MS_PRIVATEKEYBLOB) {
-+        if (*pispub == 1) {
-+            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
-+            return 0;
-+        }
-+        *pispub = 0;
-+    } else
-+        return 0;
-+    p++;
-+    /* Version */
-+    if (*p++ != 0x2) {
-+        PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
-+        return 0;
-+    }
-+    /* Ignore reserved, aiKeyAlg */
-+    p += 6;
-+    *pmagic = read_ledword(&p);
-+    *pbitlen = read_ledword(&p);
-+    *pisdss = 0;
-+    switch (*pmagic) {
-+
-+    case MS_DSS1MAGIC:
-+        *pisdss = 1;
-+    case MS_RSA1MAGIC:
-+        if (*pispub == 0) {
-+            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
-+            return 0;
-+        }
-+        break;
-+
-+    case MS_DSS2MAGIC:
-+        *pisdss = 1;
-+    case MS_RSA2MAGIC:
-+        if (*pispub == 1) {
-+            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
-+            return 0;
-+        }
-+        break;
-+
-+    default:
-+        PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
-+        return -1;
-+    }
-+    *in = p;
-+    return 1;
-+}
-+
-+static unsigned int blob_length(unsigned bitlen, int isdss, int ispub)
-+{
-+    unsigned int nbyte, hnbyte;
-+    nbyte = (bitlen + 7) >> 3;
-+    hnbyte = (bitlen + 15) >> 4;
-+    if (isdss) {
-+
-+        /*
-+         * Expected length: 20 for q + 3 components bitlen each + 24 for seed
-+         * structure.
-+         */
-+        if (ispub)
-+            return 44 + 3 * nbyte;
-+        /*
-+         * Expected length: 20 for q, priv, 2 bitlen components + 24 for seed
-+         * structure.
-+         */
-+        else
-+            return 64 + 2 * nbyte;
-+    } else {
-+        /* Expected length: 4 for 'e' + 'n' */
-+        if (ispub)
-+            return 4 + nbyte;
-+        else
-+            /*
-+             * Expected length: 4 for 'e' and 7 other components. 2
-+             * components are bitlen size, 5 are bitlen/2
-+             */
-+            return 4 + 2 * nbyte + 5 * hnbyte;
-+    }
-+
-+}
-+
-+static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length,
-+                        int ispub)
-+{
-+    const unsigned char *p = *in;
-+    unsigned int bitlen, magic;
-+    int isdss;
-+    if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) {
-+        PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
-+        return NULL;
-+    }
-+    length -= 16;
-+    if (length < blob_length(bitlen, isdss, ispub)) {
-+        PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT);
-+        return NULL;
-+    }
-+    if (isdss)
-+        return b2i_dss(&p, bitlen, ispub);
-+    else
-+        return b2i_rsa(&p, bitlen, ispub);
-+}
-+
-+static EVP_PKEY *do_b2i_bio(BIO *in, int ispub)
-+{
-+    const unsigned char *p;
-+    unsigned char hdr_buf[16], *buf = NULL;
-+    unsigned int bitlen, magic, length;
-+    int isdss;
-+    EVP_PKEY *ret = NULL;
-+    if (BIO_read(in, hdr_buf, 16) != 16) {
-+        PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
-+        return NULL;
-+    }
-+    p = hdr_buf;
-+    if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
-+        return NULL;
-+
-+    length = blob_length(bitlen, isdss, ispub);
-+    if (length > BLOB_MAX_LENGTH) {
-+        PEMerr(PEM_F_DO_B2I_BIO, PEM_R_HEADER_TOO_LONG);
-+        return NULL;
-+    }
-+    buf = OPENSSL_malloc(length);
-+    if (buf == NULL) {
-+        PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    p = buf;
-+    if (BIO_read(in, buf, length) != (int)length) {
-+        PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
-+        goto err;
-+    }
-+
-+    if (isdss)
-+        ret = b2i_dss(&p, bitlen, ispub);
-+    else
-+        ret = b2i_rsa(&p, bitlen, ispub);
-+
-+ err:
-+    OPENSSL_free(buf);
-+    return ret;
-+}
-+
-+static EVP_PKEY *b2i_dss(const unsigned char **in,
-+                         unsigned int bitlen, int ispub)
-+{
-+    const unsigned char *p = *in;
-+    EVP_PKEY *ret = NULL;
-+    DSA *dsa = NULL;
-+    BN_CTX *ctx = NULL;
-+    unsigned int nbyte;
-+    BIGNUM *pbn = NULL, *qbn = NULL, *gbn = NULL, *priv_key = NULL;
-+    BIGNUM *pub_key = NULL;
-+
-+    nbyte = (bitlen + 7) >> 3;
-+
-+    dsa = DSA_new();
-+    ret = EVP_PKEY_new();
-+    if (dsa == NULL || ret == NULL)
-+        goto memerr;
-+    if (!read_lebn(&p, nbyte, &pbn))
-+        goto memerr;
-+
-+    if (!read_lebn(&p, 20, &qbn))
-+        goto memerr;
-+
-+    if (!read_lebn(&p, nbyte, &gbn))
-+        goto memerr;
-+
-+    if (ispub) {
-+        if (!read_lebn(&p, nbyte, &pub_key))
-+            goto memerr;
-+    } else {
-+        if (!read_lebn(&p, 20, &priv_key))
-+            goto memerr;
-+
-+        /* Calculate public key */
-+        pub_key = BN_new();
-+        if (pub_key == NULL)
-+            goto memerr;
-+        if ((ctx = BN_CTX_new()) == NULL)
-+            goto memerr;
-+
-+        if (!BN_mod_exp(pub_key, gbn, priv_key, pbn, ctx))
-+            goto memerr;
-+
-+        BN_CTX_free(ctx);
-+    }
-+    if (!DSA_set0_pqg(dsa, pbn, qbn, gbn))
-+        goto memerr;
-+    pbn = qbn = gbn = NULL;
-+    if (!DSA_set0_key(dsa, pub_key, priv_key))
-+        goto memerr;
-+
-+    EVP_PKEY_set1_DSA(ret, dsa);
-+    DSA_free(dsa);
-+    *in = p;
-+    return ret;
-+
-+ memerr:
-+    PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
-+    DSA_free(dsa);
-+    BN_free(pbn);
-+    BN_free(qbn);
-+    BN_free(gbn);
-+    BN_free(pub_key);
-+    BN_free(priv_key);
-+    EVP_PKEY_free(ret);
-+    BN_CTX_free(ctx);
-+    return NULL;
-+}
-+
-+static EVP_PKEY *b2i_rsa(const unsigned char **in,
-+                         unsigned int bitlen, int ispub)
-+{
-+    const unsigned char *pin = *in;
-+    EVP_PKEY *ret = NULL;
-+    BIGNUM *e = NULL, *n = NULL, *d = NULL;
-+    BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
-+    RSA *rsa = NULL;
-+    unsigned int nbyte, hnbyte;
-+    nbyte = (bitlen + 7) >> 3;
-+    hnbyte = (bitlen + 15) >> 4;
-+    rsa = RSA_new();
-+    ret = EVP_PKEY_new();
-+    if (rsa == NULL || ret == NULL)
-+        goto memerr;
-+    e = BN_new();
-+    if (e == NULL)
-+        goto memerr;
-+    if (!BN_set_word(e, read_ledword(&pin)))
-+        goto memerr;
-+    if (!read_lebn(&pin, nbyte, &n))
-+        goto memerr;
-+    if (!ispub) {
-+        if (!read_lebn(&pin, hnbyte, &p))
-+            goto memerr;
-+        if (!read_lebn(&pin, hnbyte, &q))
-+            goto memerr;
-+        if (!read_lebn(&pin, hnbyte, &dmp1))
-+            goto memerr;
-+        if (!read_lebn(&pin, hnbyte, &dmq1))
-+            goto memerr;
-+        if (!read_lebn(&pin, hnbyte, &iqmp))
-+            goto memerr;
-+        if (!read_lebn(&pin, nbyte, &d))
-+            goto memerr;
-+        RSA_set0_factors(rsa, p, q);
-+        RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
-+    }
-+    RSA_set0_key(rsa, n, e, d);
-+
-+    EVP_PKEY_set1_RSA(ret, rsa);
-+    RSA_free(rsa);
-+    *in = pin;
-+    return ret;
-+ memerr:
-+    PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE);
-+    BN_free(e);
-+    BN_free(n);
-+    BN_free(p);
-+    BN_free(q);
-+    BN_free(dmp1);
-+    BN_free(dmq1);
-+    BN_free(iqmp);
-+    BN_free(d);
-+    RSA_free(rsa);
-+    EVP_PKEY_free(ret);
-+    return NULL;
-+}
-+
-+EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length)
-+{
-+    return do_b2i(in, length, 0);
-+}
-+
-+EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length)
-+{
-+    return do_b2i(in, length, 1);
-+}
-+
-+EVP_PKEY *b2i_PrivateKey_bio(BIO *in)
-+{
-+    return do_b2i_bio(in, 0);
-+}
-+
-+EVP_PKEY *b2i_PublicKey_bio(BIO *in)
-+{
-+    return do_b2i_bio(in, 1);
-+}
-+
-+static void write_ledword(unsigned char **out, unsigned int dw)
-+{
-+    unsigned char *p = *out;
-+    *p++ = dw & 0xff;
-+    *p++ = (dw >> 8) & 0xff;
-+    *p++ = (dw >> 16) & 0xff;
-+    *p++ = (dw >> 24) & 0xff;
-+    *out = p;
-+}
-+
-+static void write_lebn(unsigned char **out, const BIGNUM *bn, int len)
-+{
-+    BN_bn2lebinpad(bn, *out, len);
-+    *out += len;
-+}
-+
-+static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
-+static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
-+
-+static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
-+static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
-+
-+static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
-+{
-+    unsigned char *p;
-+    unsigned int bitlen, magic = 0, keyalg;
-+    int outlen, noinc = 0;
-+    int pktype = EVP_PKEY_id(pk);
-+    if (pktype == EVP_PKEY_DSA) {
-+        bitlen = check_bitlen_dsa(EVP_PKEY_get0_DSA(pk), ispub, &magic);
-+        keyalg = MS_KEYALG_DSS_SIGN;
-+    } else if (pktype == EVP_PKEY_RSA) {
-+        bitlen = check_bitlen_rsa(EVP_PKEY_get0_RSA(pk), ispub, &magic);
-+        keyalg = MS_KEYALG_RSA_KEYX;
-+    } else
-+        return -1;
-+    if (bitlen == 0)
-+        return -1;
-+    outlen = 16 + blob_length(bitlen,
-+                              keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
-+    if (out == NULL)
-+        return outlen;
-+    if (*out)
-+        p = *out;
-+    else {
-+        p = OPENSSL_malloc(outlen);
-+        if (p == NULL)
-+            return -1;
-+        *out = p;
-+        noinc = 1;
-+    }
-+    if (ispub)
-+        *p++ = MS_PUBLICKEYBLOB;
-+    else
-+        *p++ = MS_PRIVATEKEYBLOB;
-+    *p++ = 0x2;
-+    *p++ = 0;
-+    *p++ = 0;
-+    write_ledword(&p, keyalg);
-+    write_ledword(&p, magic);
-+    write_ledword(&p, bitlen);
-+    if (keyalg == MS_KEYALG_DSS_SIGN)
-+        write_dsa(&p, EVP_PKEY_get0_DSA(pk), ispub);
-+    else
-+        write_rsa(&p, EVP_PKEY_get0_RSA(pk), ispub);
-+    if (!noinc)
-+        *out += outlen;
-+    return outlen;
-+}
-+
-+static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
-+{
-+    unsigned char *tmp = NULL;
-+    int outlen, wrlen;
-+    outlen = do_i2b(&tmp, pk, ispub);
-+    if (outlen < 0)
-+        return -1;
-+    wrlen = BIO_write(out, tmp, outlen);
-+    OPENSSL_free(tmp);
-+    if (wrlen == outlen)
-+        return outlen;
-+    return -1;
-+}
-+
-+static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
-+{
-+    int bitlen;
-+    const BIGNUM *p = NULL, *q = NULL, *g = NULL;
-+    const BIGNUM *pub_key = NULL, *priv_key = NULL;
-+
-+    DSA_get0_pqg(dsa, &p, &q, &g);
-+    DSA_get0_key(dsa, &pub_key, &priv_key);
-+    bitlen = BN_num_bits(p);
-+    if ((bitlen & 7) || (BN_num_bits(q) != 160)
-+        || (BN_num_bits(g) > bitlen))
-+        goto badkey;
-+    if (ispub) {
-+        if (BN_num_bits(pub_key) > bitlen)
-+            goto badkey;
-+        *pmagic = MS_DSS1MAGIC;
-+    } else {
-+        if (BN_num_bits(priv_key) > 160)
-+            goto badkey;
-+        *pmagic = MS_DSS2MAGIC;
-+    }
-+
-+    return bitlen;
-+ badkey:
-+    PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
-+    return 0;
-+}
-+
-+static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
-+{
-+    int nbyte, hnbyte, bitlen;
-+    const BIGNUM *e;
-+
-+    RSA_get0_key(rsa, NULL, &e, NULL);
-+    if (BN_num_bits(e) > 32)
-+        goto badkey;
-+    bitlen = RSA_bits(rsa);
-+    nbyte = RSA_size(rsa);
-+    hnbyte = (bitlen + 15) >> 4;
-+    if (ispub) {
-+        *pmagic = MS_RSA1MAGIC;
-+        return bitlen;
-+    } else {
-+        const BIGNUM *d, *p, *q, *iqmp, *dmp1, *dmq1;
-+
-+        *pmagic = MS_RSA2MAGIC;
-+
-+        /*
-+         * For private key each component must fit within nbyte or hnbyte.
-+         */
-+        RSA_get0_key(rsa, NULL, NULL, &d);
-+        if (BN_num_bytes(d) > nbyte)
-+            goto badkey;
-+        RSA_get0_factors(rsa, &p, &q);
-+        RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
-+        if ((BN_num_bytes(iqmp) > hnbyte)
-+            || (BN_num_bytes(p) > hnbyte)
-+            || (BN_num_bytes(q) > hnbyte)
-+            || (BN_num_bytes(dmp1) > hnbyte)
-+            || (BN_num_bytes(dmq1) > hnbyte))
-+            goto badkey;
-+    }
-+    return bitlen;
-+ badkey:
-+    PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
-+    return 0;
-+}
-+
-+static void write_rsa(unsigned char **out, RSA *rsa, int ispub)
-+{
-+    int nbyte, hnbyte;
-+    const BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1;
-+
-+    nbyte = RSA_size(rsa);
-+    hnbyte = (RSA_bits(rsa) + 15) >> 4;
-+    RSA_get0_key(rsa, &n, &e, &d);
-+    write_lebn(out, e, 4);
-+    write_lebn(out, n, nbyte);
-+    if (ispub)
-+        return;
-+    RSA_get0_factors(rsa, &p, &q);
-+    RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
-+    write_lebn(out, p, hnbyte);
-+    write_lebn(out, q, hnbyte);
-+    write_lebn(out, dmp1, hnbyte);
-+    write_lebn(out, dmq1, hnbyte);
-+    write_lebn(out, iqmp, hnbyte);
-+    write_lebn(out, d, nbyte);
-+}
-+
-+static void write_dsa(unsigned char **out, DSA *dsa, int ispub)
-+{
-+    int nbyte;
-+    const BIGNUM *p = NULL, *q = NULL, *g = NULL;
-+    const BIGNUM *pub_key = NULL, *priv_key = NULL;
-+
-+    DSA_get0_pqg(dsa, &p, &q, &g);
-+    DSA_get0_key(dsa, &pub_key, &priv_key);
-+    nbyte = BN_num_bytes(p);
-+    write_lebn(out, p, nbyte);
-+    write_lebn(out, q, 20);
-+    write_lebn(out, g, nbyte);
-+    if (ispub)
-+        write_lebn(out, pub_key, nbyte);
-+    else
-+        write_lebn(out, priv_key, 20);
-+    /* Set "invalid" for seed structure values */
-+    memset(*out, 0xff, 24);
-+    *out += 24;
-+    return;
-+}
-+
-+int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
-+{
-+    return do_i2b_bio(out, pk, 0);
-+}
-+
-+int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
-+{
-+    return do_i2b_bio(out, pk, 1);
-+}
-+
-+# ifndef OPENSSL_NO_RC4
-+
-+static int do_PVK_header(const unsigned char **in, unsigned int length,
-+                         int skip_magic,
-+                         unsigned int *psaltlen, unsigned int *pkeylen)
-+{
-+    const unsigned char *p = *in;
-+    unsigned int pvk_magic, is_encrypted;
-+    if (skip_magic) {
-+        if (length < 20) {
-+            PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
-+            return 0;
-+        }
-+    } else {
-+        if (length < 24) {
-+            PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
-+            return 0;
-+        }
-+        pvk_magic = read_ledword(&p);
-+        if (pvk_magic != MS_PVKMAGIC) {
-+            PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
-+            return 0;
-+        }
-+    }
-+    /* Skip reserved */
-+    p += 4;
-+    /*
-+     * keytype =
-+     */ read_ledword(&p);
-+    is_encrypted = read_ledword(&p);
-+    *psaltlen = read_ledword(&p);
-+    *pkeylen = read_ledword(&p);
-+
-+    if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN)
-+        return 0;
-+
-+    if (is_encrypted && !*psaltlen) {
-+        PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
-+        return 0;
-+    }
-+
-+    *in = p;
-+    return 1;
-+}
-+
-+static int derive_pvk_key(unsigned char *key,
-+                          const unsigned char *salt, unsigned int saltlen,
-+                          const unsigned char *pass, int passlen)
-+{
-+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-+    int rv = 1;
-+    if (mctx == NULL
-+        || !EVP_DigestInit_ex(mctx, EVP_sha1(), NULL)
-+        || !EVP_DigestUpdate(mctx, salt, saltlen)
-+        || !EVP_DigestUpdate(mctx, pass, passlen)
-+        || !EVP_DigestFinal_ex(mctx, key, NULL))
-+        rv = 0;
-+
-+    EVP_MD_CTX_free(mctx);
-+    return rv;
-+}
-+
-+static EVP_PKEY *do_PVK_body(const unsigned char **in,
-+                             unsigned int saltlen, unsigned int keylen,
-+                             pem_password_cb *cb, void *u)
-+{
-+    EVP_PKEY *ret = NULL;
-+    const unsigned char *p = *in;
-+    unsigned int magic;
-+    unsigned char *enctmp = NULL, *q;
-+
-+    EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new();
-+    if (saltlen) {
-+        char psbuf[PEM_BUFSIZE];
-+        unsigned char keybuf[20];
-+        int enctmplen, inlen;
-+        if (cb)
-+            inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
-+        else
-+            inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
-+        if (inlen <= 0) {
-+            PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ);
-+            goto err;
-+        }
-+        enctmp = OPENSSL_malloc(keylen + 8);
-+        if (enctmp == NULL) {
-+            PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (!derive_pvk_key(keybuf, p, saltlen,
-+                            (unsigned char *)psbuf, inlen))
-+            goto err;
-+        p += saltlen;
-+        /* Copy BLOBHEADER across, decrypt rest */
-+        memcpy(enctmp, p, 8);
-+        p += 8;
-+        if (keylen < 8) {
-+            PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT);
-+            goto err;
-+        }
-+        inlen = keylen - 8;
-+        q = enctmp + 8;
-+        if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
-+            goto err;
-+        if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
-+            goto err;
-+        if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen))
-+            goto err;
-+        magic = read_ledword((const unsigned char **)&q);
-+        if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
-+            q = enctmp + 8;
-+            memset(keybuf + 5, 0, 11);
-+            if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
-+                goto err;
-+            OPENSSL_cleanse(keybuf, 20);
-+            if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
-+                goto err;
-+            if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen))
-+                goto err;
-+            magic = read_ledword((const unsigned char **)&q);
-+            if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
-+                PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
-+                goto err;
-+            }
-+        } else
-+            OPENSSL_cleanse(keybuf, 20);
-+        p = enctmp;
-+    }
-+
-+    ret = b2i_PrivateKey(&p, keylen);
-+ err:
-+    EVP_CIPHER_CTX_free(cctx);
-+    OPENSSL_free(enctmp);
-+    return ret;
-+}
-+
-+EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
-+{
-+    unsigned char pvk_hdr[24], *buf = NULL;
-+    const unsigned char *p;
-+    int buflen;
-+    EVP_PKEY *ret = NULL;
-+    unsigned int saltlen, keylen;
-+    if (BIO_read(in, pvk_hdr, 24) != 24) {
-+        PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
-+        return NULL;
-+    }
-+    p = pvk_hdr;
-+
-+    if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
-+        return 0;
-+    buflen = (int)keylen + saltlen;
-+    buf = OPENSSL_malloc(buflen);
-+    if (buf == NULL) {
-+        PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    p = buf;
-+    if (BIO_read(in, buf, buflen) != buflen) {
-+        PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
-+        goto err;
-+    }
-+    ret = do_PVK_body(&p, saltlen, keylen, cb, u);
-+
-+ err:
-+    OPENSSL_clear_free(buf, buflen);
-+    return ret;
-+}
-+
-+static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel,
-+                   pem_password_cb *cb, void *u)
-+{
-+    int outlen = 24, pklen;
-+    unsigned char *p = NULL, *start = NULL, *salt = NULL;
-+    EVP_CIPHER_CTX *cctx = NULL;
-+    if (enclevel)
-+        outlen += PVK_SALTLEN;
-+    pklen = do_i2b(NULL, pk, 0);
-+    if (pklen < 0)
-+        return -1;
-+    outlen += pklen;
-+    if (out == NULL)
-+        return outlen;
-+    if (*out != NULL) {
-+        p = *out;
-+    } else {
-+        start = p = OPENSSL_malloc(outlen);
-+        if (p == NULL) {
-+            PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE);
-+            return -1;
-+        }
-+    }
-+
-+    cctx = EVP_CIPHER_CTX_new();
-+    if (cctx == NULL)
-+        goto error;
-+
-+    write_ledword(&p, MS_PVKMAGIC);
-+    write_ledword(&p, 0);
-+    if (EVP_PKEY_id(pk) == EVP_PKEY_DSA)
-+        write_ledword(&p, MS_KEYTYPE_SIGN);
-+    else
-+        write_ledword(&p, MS_KEYTYPE_KEYX);
-+    write_ledword(&p, enclevel ? 1 : 0);
-+    write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
-+    write_ledword(&p, pklen);
-+    if (enclevel) {
-+        if (RAND_bytes(p, PVK_SALTLEN) <= 0)
-+            goto error;
-+        salt = p;
-+        p += PVK_SALTLEN;
-+    }
-+    do_i2b(&p, pk, 0);
-+    if (enclevel != 0) {
-+        char psbuf[PEM_BUFSIZE];
-+        unsigned char keybuf[20];
-+        int enctmplen, inlen;
-+        if (cb)
-+            inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
-+        else
-+            inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
-+        if (inlen <= 0) {
-+            PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ);
-+            goto error;
-+        }
-+        if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
-+                            (unsigned char *)psbuf, inlen))
-+            goto error;
-+        if (enclevel == 1)
-+            memset(keybuf + 5, 0, 11);
-+        p = salt + PVK_SALTLEN + 8;
-+        if (!EVP_EncryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
-+            goto error;
-+        OPENSSL_cleanse(keybuf, 20);
-+        if (!EVP_DecryptUpdate(cctx, p, &enctmplen, p, pklen - 8))
-+            goto error;
-+        if (!EVP_DecryptFinal_ex(cctx, p + enctmplen, &enctmplen))
-+            goto error;
-+    }
-+
-+    EVP_CIPHER_CTX_free(cctx);
-+
-+    if (*out == NULL)
-+        *out = start;
-+
-+    return outlen;
-+
-+ error:
-+    EVP_CIPHER_CTX_free(cctx);
-+    if (*out == NULL)
-+        OPENSSL_free(start);
-+    return -1;
-+}
-+
-+int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
-+                pem_password_cb *cb, void *u)
-+{
-+    unsigned char *tmp = NULL;
-+    int outlen, wrlen;
-+    outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
-+    if (outlen < 0)
-+        return -1;
-+    wrlen = BIO_write(out, tmp, outlen);
-+    OPENSSL_free(tmp);
-+    if (wrlen == outlen) {
-+        PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
-+        return outlen;
-+    }
-+    return -1;
-+}
-+
-+# endif
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/README b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/README
-new file mode 100644
-index 0000000..e90bd8e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/README
-@@ -0,0 +1,124 @@
-+The perl scripts in this directory are my 'hack' to generate
-+multiple different assembler formats via the one original script.
-+
-+The way to use this library is to start with adding the path to this directory
-+and then include it.
-+
-+push(@INC,"perlasm","../../perlasm");
-+require "x86asm.pl";
-+
-+The first thing we do is setup the file and type of assembler
-+
-+&asm_init($ARGV[0],$0);
-+
-+The first argument is the 'type'.  Currently
-+'cpp', 'sol', 'a.out', 'elf' or 'win32'.
-+Argument 2 is the file name.
-+
-+The reciprocal function is
-+&asm_finish() which should be called at the end.
-+
-+There are 2 main 'packages'. x86ms.pl, which is the Microsoft assembler,
-+and x86unix.pl which is the unix (gas) version.
-+
-+Functions of interest are:
-+&external_label("des_SPtrans");	declare and external variable
-+&LB(reg);			Low byte for a register
-+&HB(reg);			High byte for a register
-+&BP(off,base,index,scale)	Byte pointer addressing
-+&DWP(off,base,index,scale)	Word pointer addressing
-+&stack_push(num)		Basically a 'sub esp, num*4' with extra
-+&stack_pop(num)			inverse of stack_push
-+&function_begin(name,extra)	Start a function with pushing of
-+				edi, esi, ebx and ebp.  extra is extra win32
-+				external info that may be required.
-+&function_begin_B(name,extra)	Same as normal function_begin but no pushing.
-+&function_end(name)		Call at end of function.
-+&function_end_A(name)		Standard pop and ret, for use inside functions
-+&function_end_B(name)		Call at end but with poping or 'ret'.
-+&swtmp(num)			Address on stack temp word.
-+&wparam(num)			Parameter number num, that was push
-+				in C convention.  This all works over pushes
-+				and pops.
-+&comment("hello there")		Put in a comment.
-+&label("loop")			Refer to a label, normally a jmp target.
-+&set_label("loop")		Set a label at this point.
-+&data_word(word)		Put in a word of data.
-+
-+So how does this all hold together?  Given
-+
-+int calc(int len, int *data)
-+	{
-+	int i,j=0;
-+
-+	for (i=0; i$output" || die "can't open $output: $!";
-+
-+$flavour = "linux32" if (!$flavour or $flavour eq "void");
-+
-+my %GLOBALS;
-+my $dotinlocallabels=($flavour=~/linux/)?1:0;
-+
-+################################################################
-+# directives which need special treatment on different platforms
-+################################################################
-+my $arch = sub {
-+    if ($flavour =~ /linux/)	{ ".arch\t".join(',',@_); }
-+    else			{ ""; }
-+};
-+my $fpu = sub {
-+    if ($flavour =~ /linux/)	{ ".fpu\t".join(',',@_); }
-+    else			{ ""; }
-+};
-+my $hidden = sub {
-+    if ($flavour =~ /ios/)	{ ".private_extern\t".join(',',@_); }
-+    else			{ ".hidden\t".join(',',@_); }
-+};
-+my $comm = sub {
-+    my @args = split(/,\s*/,shift);
-+    my $name = @args[0];
-+    my $global = \$GLOBALS{$name};
-+    my $ret;
-+
-+    if ($flavour =~ /ios32/)	{
-+	$ret = ".comm\t_$name,@args[1]\n";
-+	$ret .= ".non_lazy_symbol_pointer\n";
-+	$ret .= "$name:\n";
-+	$ret .= ".indirect_symbol\t_$name\n";
-+	$ret .= ".long\t0";
-+	$name = "_$name";
-+    } else			{ $ret = ".comm\t".join(',',@args); }
-+
-+    $$global = $name;
-+    $ret;
-+};
-+my $globl = sub {
-+    my $name = shift;
-+    my $global = \$GLOBALS{$name};
-+    my $ret;
-+
-+    SWITCH: for ($flavour) {
-+	/ios/		&& do { $name = "_$name";
-+				last;
-+			      };
-+    }
-+
-+    $ret = ".globl	$name" if (!$ret);
-+    $$global = $name;
-+    $ret;
-+};
-+my $global = $globl;
-+my $extern = sub {
-+    &$globl(@_);
-+    return;	# return nothing
-+};
-+my $type = sub {
-+    if ($flavour =~ /linux/)	{ ".type\t".join(',',@_); }
-+    elsif ($flavour =~ /ios32/)	{ if (join(',',@_) =~ /(\w+),%function/) {
-+					"#ifdef __thumb2__\n".
-+					".thumb_func	$1\n".
-+					"#endif";
-+				  }
-+			        }
-+    else			{ ""; }
-+};
-+my $size = sub {
-+    if ($flavour =~ /linux/)	{ ".size\t".join(',',@_); }
-+    else			{ ""; }
-+};
-+my $inst = sub {
-+    if ($flavour =~ /linux/)    { ".inst\t".join(',',@_); }
-+    else                        { ".long\t".join(',',@_); }
-+};
-+my $asciz = sub {
-+    my $line = join(",",@_);
-+    if ($line =~ /^"(.*)"$/)
-+    {	".byte	" . join(",",unpack("C*",$1),0) . "\n.align	2";	}
-+    else
-+    {	"";	}
-+};
-+
-+sub range {
-+  my ($r,$sfx,$start,$end) = @_;
-+
-+    join(",",map("$r$_$sfx",($start..$end)));
-+}
-+
-+sub expand_line {
-+  my $line = shift;
-+  my @ret = ();
-+
-+    pos($line)=0;
-+
-+    while ($line =~ m/\G[^@\/\{\"]*/g) {
-+	if ($line =~ m/\G(@|\/\/|$)/gc) {
-+	    last;
-+	}
-+	elsif ($line =~ m/\G\{/gc) {
-+	    my $saved_pos = pos($line);
-+	    $line =~ s/\G([rdqv])([0-9]+)([^\-]*)\-\1([0-9]+)\3/range($1,$3,$2,$4)/e;
-+	    pos($line) = $saved_pos;
-+	    $line =~ m/\G[^\}]*\}/g;
-+	}
-+	elsif ($line =~ m/\G\"/gc) {
-+	    $line =~ m/\G[^\"]*\"/g;
-+	}
-+    }
-+
-+    $line =~ s/\b(\w+)/$GLOBALS{$1} or $1/ge;
-+
-+    return $line;
-+}
-+
-+while(my $line=<>) {
-+
-+    if ($line =~ m/^\s*(#|@|\/\/)/)	{ print $line; next; }
-+
-+    $line =~ s|/\*.*\*/||;	# get rid of C-style comments...
-+    $line =~ s|^\s+||;		# ... and skip white spaces in beginning...
-+    $line =~ s|\s+$||;		# ... and at the end
-+
-+    {
-+	$line =~ s|[\b\.]L(\w{2,})|L$1|g;	# common denominator for Locallabel
-+	$line =~ s|\bL(\w{2,})|\.L$1|g	if ($dotinlocallabels);
-+    }
-+
-+    {
-+	$line =~ s|(^[\.\w]+)\:\s*||;
-+	my $label = $1;
-+	if ($label) {
-+	    printf "%s:",($GLOBALS{$label} or $label);
-+	}
-+    }
-+
-+    if ($line !~ m/^[#@]/) {
-+	$line =~ s|^\s*(\.?)(\S+)\s*||;
-+	my $c = $1; $c = "\t" if ($c eq "");
-+	my $mnemonic = $2;
-+	my $opcode;
-+	if ($mnemonic =~ m/([^\.]+)\.([^\.]+)/) {
-+	    $opcode = eval("\$$1_$2");
-+	} else {
-+	    $opcode = eval("\$$mnemonic");
-+	}
-+
-+	my $arg=expand_line($line);
-+
-+	if (ref($opcode) eq 'CODE') {
-+		$line = &$opcode($arg);
-+	} elsif ($mnemonic)         {
-+		$line = $c.$mnemonic;
-+		$line.= "\t$arg" if ($arg ne "");
-+	}
-+    }
-+
-+    print $line if ($line);
-+    print "\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/cbc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/cbc.pl
-new file mode 100644
-index 0000000..ad79b24
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/cbc.pl
-@@ -0,0 +1,356 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
-+# des_cblock (*input);
-+# des_cblock (*output);
-+# long length;
-+# des_key_schedule schedule;
-+# des_cblock (*ivec);
-+# int enc;
-+#
-+# calls 
-+# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+#
-+
-+#&cbc("des_ncbc_encrypt","des_encrypt",0);
-+#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
-+#	1,4,5,3,5,-1);
-+#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
-+#	0,4,5,3,5,-1);
-+#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
-+#	0,6,7,3,4,5);
-+#
-+# When doing a cipher that needs bigendian order,
-+# for encrypt, the iv is kept in bigendian form,
-+# while for decrypt, it is kept in little endian.
-+sub cbc
-+	{
-+	local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
-+	# name is the function name
-+	# enc_func and dec_func and the functions to call for encrypt/decrypt
-+	# swap is true if byte order needs to be reversed
-+	# iv_off is parameter number for the iv 
-+	# enc_off is parameter number for the encrypt/decrypt flag
-+	# p1,p2,p3 are the offsets for parameters to be passed to the
-+	# underlying calls.
-+
-+	&function_begin_B($name,"");
-+	&comment("");
-+
-+	$in="esi";
-+	$out="edi";
-+	$count="ebp";
-+
-+	&push("ebp");
-+	&push("ebx");
-+	&push("esi");
-+	&push("edi");
-+
-+	$data_off=4;
-+	$data_off+=4 if ($p1 > 0);
-+	$data_off+=4 if ($p2 > 0);
-+	$data_off+=4 if ($p3 > 0);
-+
-+	&mov($count,	&wparam(2));	# length
-+
-+	&comment("getting iv ptr from parameter $iv_off");
-+	&mov("ebx",	&wparam($iv_off));	# Get iv ptr
-+
-+	&mov($in,	&DWP(0,"ebx","",0));#	iv[0]
-+	&mov($out,	&DWP(4,"ebx","",0));#	iv[1]
-+
-+	&push($out);
-+	&push($in);
-+	&push($out);	# used in decrypt for iv[1]
-+	&push($in);	# used in decrypt for iv[0]
-+
-+	&mov("ebx",	"esp");		# This is the address of tin[2]
-+
-+	&mov($in,	&wparam(0));	# in
-+	&mov($out,	&wparam(1));	# out
-+
-+	# We have loaded them all, how lets push things
-+	&comment("getting encrypt flag from parameter $enc_off");
-+	&mov("ecx",	&wparam($enc_off));	# Get enc flag
-+	if ($p3 > 0)
-+		{
-+		&comment("get and push parameter $p3");
-+		if ($enc_off != $p3)
-+			{ &mov("eax",	&wparam($p3)); &push("eax"); }
-+		else	{ &push("ecx"); }
-+		}
-+	if ($p2 > 0)
-+		{
-+		&comment("get and push parameter $p2");
-+		if ($enc_off != $p2)
-+			{ &mov("eax",	&wparam($p2)); &push("eax"); }
-+		else	{ &push("ecx"); }
-+		}
-+	if ($p1 > 0)
-+		{
-+		&comment("get and push parameter $p1");
-+		if ($enc_off != $p1)
-+			{ &mov("eax",	&wparam($p1)); &push("eax"); }
-+		else	{ &push("ecx"); }
-+		}
-+	&push("ebx");		# push data/iv
-+
-+	&cmp("ecx",0);
-+	&jz(&label("decrypt"));
-+
-+	&and($count,0xfffffff8);
-+	&mov("eax",	&DWP($data_off,"esp","",0));	# load iv[0]
-+	&mov("ebx",	&DWP($data_off+4,"esp","",0));	# load iv[1]
-+
-+	&jz(&label("encrypt_finish"));
-+
-+	#############################################################
-+
-+	&set_label("encrypt_loop");
-+	# encrypt start 
-+	# "eax" and "ebx" hold iv (or the last cipher text)
-+
-+	&mov("ecx",	&DWP(0,$in,"",0));	# load first 4 bytes
-+	&mov("edx",	&DWP(4,$in,"",0));	# second 4 bytes
-+
-+	&xor("eax",	"ecx");
-+	&xor("ebx",	"edx");
-+
-+	&bswap("eax")	if $swap;
-+	&bswap("ebx")	if $swap;
-+
-+	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
-+	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
-+
-+	&call($enc_func);
-+
-+	&mov("eax",	&DWP($data_off,"esp","",0));
-+	&mov("ebx",	&DWP($data_off+4,"esp","",0));
-+
-+	&bswap("eax")	if $swap;
-+	&bswap("ebx")	if $swap;
-+
-+	&mov(&DWP(0,$out,"",0),"eax");
-+	&mov(&DWP(4,$out,"",0),"ebx");
-+
-+	# eax and ebx are the next iv.
-+
-+	&add($in,	8);
-+	&add($out,	8);
-+
-+	&sub($count,	8);
-+	&jnz(&label("encrypt_loop"));
-+
-+###################################################################3
-+	&set_label("encrypt_finish");
-+	&mov($count,	&wparam(2));	# length
-+	&and($count,	7);
-+	&jz(&label("finish"));
-+	&call(&label("PIC_point"));
-+&set_label("PIC_point");
-+	&blindpop("edx");
-+	&lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx"));
-+	&mov($count,&DWP(0,"ecx",$count,4));
-+	&add($count,"edx");
-+	&xor("ecx","ecx");
-+	&xor("edx","edx");
-+	#&mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
-+	&jmp_ptr($count);
-+
-+&set_label("ej7");
-+	&movb(&HB("edx"),	&BP(6,$in,"",0));
-+	&shl("edx",8);
-+&set_label("ej6");
-+	&movb(&HB("edx"),	&BP(5,$in,"",0));
-+&set_label("ej5");
-+	&movb(&LB("edx"),	&BP(4,$in,"",0));
-+&set_label("ej4");
-+	&mov("ecx",		&DWP(0,$in,"",0));
-+	&jmp(&label("ejend"));
-+&set_label("ej3");
-+	&movb(&HB("ecx"),	&BP(2,$in,"",0));
-+	&shl("ecx",8);
-+&set_label("ej2");
-+	&movb(&HB("ecx"),	&BP(1,$in,"",0));
-+&set_label("ej1");
-+	&movb(&LB("ecx"),	&BP(0,$in,"",0));
-+&set_label("ejend");
-+
-+	&xor("eax",	"ecx");
-+	&xor("ebx",	"edx");
-+
-+	&bswap("eax")	if $swap;
-+	&bswap("ebx")	if $swap;
-+
-+	&mov(&DWP($data_off,"esp","",0),	"eax");	# put in array for call
-+	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
-+
-+	&call($enc_func);
-+
-+	&mov("eax",	&DWP($data_off,"esp","",0));
-+	&mov("ebx",	&DWP($data_off+4,"esp","",0));
-+
-+	&bswap("eax")	if $swap;
-+	&bswap("ebx")	if $swap;
-+
-+	&mov(&DWP(0,$out,"",0),"eax");
-+	&mov(&DWP(4,$out,"",0),"ebx");
-+
-+	&jmp(&label("finish"));
-+
-+	#############################################################
-+	#############################################################
-+	&set_label("decrypt",1);
-+	# decrypt start 
-+	&and($count,0xfffffff8);
-+	# The next 2 instructions are only for if the jz is taken
-+	&mov("eax",	&DWP($data_off+8,"esp","",0));	# get iv[0]
-+	&mov("ebx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
-+	&jz(&label("decrypt_finish"));
-+
-+	&set_label("decrypt_loop");
-+	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
-+	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
-+
-+	&bswap("eax")	if $swap;
-+	&bswap("ebx")	if $swap;
-+
-+	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
-+	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
-+
-+	&call($dec_func);
-+
-+	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
-+	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
-+
-+	&bswap("eax")	if $swap;
-+	&bswap("ebx")	if $swap;
-+
-+	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
-+	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
-+
-+	&xor("ecx",	"eax");
-+	&xor("edx",	"ebx");
-+
-+	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
-+	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
-+
-+	&mov(&DWP(0,$out,"",0),"ecx");
-+	&mov(&DWP(4,$out,"",0),"edx");
-+
-+	&mov(&DWP($data_off+8,"esp","",0),	"eax");	# save iv
-+	&mov(&DWP($data_off+12,"esp","",0),	"ebx");	#
-+
-+	&add($in,	8);
-+	&add($out,	8);
-+
-+	&sub($count,	8);
-+	&jnz(&label("decrypt_loop"));
-+############################ ENDIT #######################3
-+	&set_label("decrypt_finish");
-+	&mov($count,	&wparam(2));	# length
-+	&and($count,	7);
-+	&jz(&label("finish"));
-+
-+	&mov("eax",	&DWP(0,$in,"",0));	# load first 4 bytes
-+	&mov("ebx",	&DWP(4,$in,"",0));	# second 4 bytes
-+
-+	&bswap("eax")	if $swap;
-+	&bswap("ebx")	if $swap;
-+
-+	&mov(&DWP($data_off,"esp","",0),	"eax");	# put back
-+	&mov(&DWP($data_off+4,"esp","",0),	"ebx");	#
-+
-+	&call($dec_func);
-+
-+	&mov("eax",	&DWP($data_off,"esp","",0));	# get return
-+	&mov("ebx",	&DWP($data_off+4,"esp","",0));	#
-+
-+	&bswap("eax")	if $swap;
-+	&bswap("ebx")	if $swap;
-+
-+	&mov("ecx",	&DWP($data_off+8,"esp","",0));	# get iv[0]
-+	&mov("edx",	&DWP($data_off+12,"esp","",0));	# get iv[1]
-+
-+	&xor("ecx",	"eax");
-+	&xor("edx",	"ebx");
-+
-+	# this is for when we exit
-+	&mov("eax",	&DWP(0,$in,"",0));	# get old cipher text,
-+	&mov("ebx",	&DWP(4,$in,"",0));	# next iv actually
-+
-+&set_label("dj7");
-+	&rotr("edx",	16);
-+	&movb(&BP(6,$out,"",0),	&LB("edx"));
-+	&shr("edx",16);
-+&set_label("dj6");
-+	&movb(&BP(5,$out,"",0),	&HB("edx"));
-+&set_label("dj5");
-+	&movb(&BP(4,$out,"",0),	&LB("edx"));
-+&set_label("dj4");
-+	&mov(&DWP(0,$out,"",0),	"ecx");
-+	&jmp(&label("djend"));
-+&set_label("dj3");
-+	&rotr("ecx",	16);
-+	&movb(&BP(2,$out,"",0),	&LB("ecx"));
-+	&shl("ecx",16);
-+&set_label("dj2");
-+	&movb(&BP(1,$in,"",0),	&HB("ecx"));
-+&set_label("dj1");
-+	&movb(&BP(0,$in,"",0),	&LB("ecx"));
-+&set_label("djend");
-+
-+	# final iv is still in eax:ebx
-+	&jmp(&label("finish"));
-+
-+
-+############################ FINISH #######################3
-+	&set_label("finish",1);
-+	&mov("ecx",	&wparam($iv_off));	# Get iv ptr
-+
-+	#################################################
-+	$total=16+4;
-+	$total+=4 if ($p1 > 0);
-+	$total+=4 if ($p2 > 0);
-+	$total+=4 if ($p3 > 0);
-+	&add("esp",$total);
-+
-+	&mov(&DWP(0,"ecx","",0),	"eax");	# save iv
-+	&mov(&DWP(4,"ecx","",0),	"ebx");	# save iv
-+
-+	&function_end_A($name);
-+
-+	&align(64);
-+	&set_label("cbc_enc_jmp_table");
-+	&data_word("0");
-+	&data_word(&label("ej1")."-".&label("PIC_point"));
-+	&data_word(&label("ej2")."-".&label("PIC_point"));
-+	&data_word(&label("ej3")."-".&label("PIC_point"));
-+	&data_word(&label("ej4")."-".&label("PIC_point"));
-+	&data_word(&label("ej5")."-".&label("PIC_point"));
-+	&data_word(&label("ej6")."-".&label("PIC_point"));
-+	&data_word(&label("ej7")."-".&label("PIC_point"));
-+	# not used
-+	#&set_label("cbc_dec_jmp_table",1);
-+	#&data_word("0");
-+	#&data_word(&label("dj1")."-".&label("PIC_point"));
-+	#&data_word(&label("dj2")."-".&label("PIC_point"));
-+	#&data_word(&label("dj3")."-".&label("PIC_point"));
-+	#&data_word(&label("dj4")."-".&label("PIC_point"));
-+	#&data_word(&label("dj5")."-".&label("PIC_point"));
-+	#&data_word(&label("dj6")."-".&label("PIC_point"));
-+	#&data_word(&label("dj7")."-".&label("PIC_point"));
-+	&align(64);
-+
-+	&function_end_B($name);
-+	
-+	}
-+
-+1;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/ppc-xlate.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/ppc-xlate.pl
-new file mode 100755
-index 0000000..2d46e24
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/ppc-xlate.pl
-@@ -0,0 +1,265 @@
-+#! /usr/bin/env perl
-+# Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+my $flavour = shift;
-+my $output = shift;
-+open STDOUT,">$output" || die "can't open $output: $!";
-+
-+my %GLOBALS;
-+my $dotinlocallabels=($flavour=~/linux/)?1:0;
-+
-+################################################################
-+# directives which need special treatment on different platforms
-+################################################################
-+my $globl = sub {
-+    my $junk = shift;
-+    my $name = shift;
-+    my $global = \$GLOBALS{$name};
-+    my $ret;
-+
-+    $name =~ s|^[\.\_]||;
-+ 
-+    SWITCH: for ($flavour) {
-+	/aix/		&& do { $name = ".$name";
-+				last;
-+			      };
-+	/osx/		&& do { $name = "_$name";
-+				last;
-+			      };
-+	/linux.*(32|64le)/
-+			&& do {	$ret .= ".globl	$name\n";
-+				$ret .= ".type	$name,\@function";
-+				last;
-+			      };
-+	/linux.*64/	&& do {	$ret .= ".globl	$name\n";
-+				$ret .= ".type	$name,\@function\n";
-+				$ret .= ".section	\".opd\",\"aw\"\n";
-+				$ret .= ".align	3\n";
-+				$ret .= "$name:\n";
-+				$ret .= ".quad	.$name,.TOC.\@tocbase,0\n";
-+				$ret .= ".previous\n";
-+
-+				$name = ".$name";
-+				last;
-+			      };
-+    }
-+
-+    $ret = ".globl	$name" if (!$ret);
-+    $$global = $name;
-+    $ret;
-+};
-+my $text = sub {
-+    my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text";
-+    $ret = ".abiversion	2\n".$ret	if ($flavour =~ /linux.*64le/);
-+    $ret;
-+};
-+my $machine = sub {
-+    my $junk = shift;
-+    my $arch = shift;
-+    if ($flavour =~ /osx/)
-+    {	$arch =~ s/\"//g;
-+	$arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any");
-+    }
-+    ".machine	$arch";
-+};
-+my $size = sub {
-+    if ($flavour =~ /linux/)
-+    {	shift;
-+	my $name = shift; $name =~ s|^[\.\_]||;
-+	my $ret  = ".size	$name,.-".($flavour=~/64$/?".":"").$name;
-+	$ret .= "\n.size	.$name,.-.$name" if ($flavour=~/64$/);
-+	$ret;
-+    }
-+    else
-+    {	"";	}
-+};
-+my $asciz = sub {
-+    shift;
-+    my $line = join(",",@_);
-+    if ($line =~ /^"(.*)"$/)
-+    {	".byte	" . join(",",unpack("C*",$1),0) . "\n.align	2";	}
-+    else
-+    {	"";	}
-+};
-+my $quad = sub {
-+    shift;
-+    my @ret;
-+    my ($hi,$lo);
-+    for (@_) {
-+	if (/^0x([0-9a-f]*?)([0-9a-f]{1,8})$/io)
-+	{  $hi=$1?"0x$1":"0"; $lo="0x$2";  }
-+	elsif (/^([0-9]+)$/o)
-+	{  $hi=$1>>32; $lo=$1&0xffffffff;  } # error-prone with 32-bit perl
-+	else
-+	{  $hi=undef; $lo=$_; }
-+
-+	if (defined($hi))
-+	{  push(@ret,$flavour=~/le$/o?".long\t$lo,$hi":".long\t$hi,$lo");  }
-+	else
-+	{  push(@ret,".quad	$lo");  }
-+    }
-+    join("\n",@ret);
-+};
-+
-+################################################################
-+# simplified mnemonics not handled by at least one assembler
-+################################################################
-+my $cmplw = sub {
-+    my $f = shift;
-+    my $cr = 0; $cr = shift if ($#_>1);
-+    # Some out-of-date 32-bit GNU assembler just can't handle cmplw...
-+    ($flavour =~ /linux.*32/) ?
-+	"	.long	".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 :
-+	"	cmplw	".join(',',$cr,@_);
-+};
-+my $bdnz = sub {
-+    my $f = shift;
-+    my $bo = $f=~/[\+\-]/ ? 16+9 : 16;	# optional "to be taken" hint
-+    "	bc	$bo,0,".shift;
-+} if ($flavour!~/linux/);
-+my $bltlr = sub {
-+    my $f = shift;
-+    my $bo = $f=~/\-/ ? 12+2 : 12;	# optional "not to be taken" hint
-+    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
-+	"	.long	".sprintf "0x%x",19<<26|$bo<<21|16<<1 :
-+	"	bclr	$bo,0";
-+};
-+my $bnelr = sub {
-+    my $f = shift;
-+    my $bo = $f=~/\-/ ? 4+2 : 4;	# optional "not to be taken" hint
-+    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
-+	"	.long	".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 :
-+	"	bclr	$bo,2";
-+};
-+my $beqlr = sub {
-+    my $f = shift;
-+    my $bo = $f=~/-/ ? 12+2 : 12;	# optional "not to be taken" hint
-+    ($flavour =~ /linux/) ?		# GNU as doesn't allow most recent hints
-+	"	.long	".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 :
-+	"	bclr	$bo,2";
-+};
-+# GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two
-+# arguments is 64, with "operand out of range" error.
-+my $extrdi = sub {
-+    my ($f,$ra,$rs,$n,$b) = @_;
-+    $b = ($b+$n)&63; $n = 64-$n;
-+    "	rldicl	$ra,$rs,$b,$n";
-+};
-+my $vmr = sub {
-+    my ($f,$vx,$vy) = @_;
-+    "	vor	$vx,$vy,$vy";
-+};
-+
-+# Some ABIs specify vrsave, special-purpose register #256, as reserved
-+# for system use.
-+my $no_vrsave = ($flavour =~ /aix|linux64le/);
-+my $mtspr = sub {
-+    my ($f,$idx,$ra) = @_;
-+    if ($idx == 256 && $no_vrsave) {
-+	"	or	$ra,$ra,$ra";
-+    } else {
-+	"	mtspr	$idx,$ra";
-+    }
-+};
-+my $mfspr = sub {
-+    my ($f,$rd,$idx) = @_;
-+    if ($idx == 256 && $no_vrsave) {
-+	"	li	$rd,-1";
-+    } else {
-+	"	mfspr	$rd,$idx";
-+    }
-+};
-+
-+# PowerISA 2.06 stuff
-+sub vsxmem_op {
-+    my ($f, $vrt, $ra, $rb, $op) = @_;
-+    "	.long	".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|($rb<<11)|($op*2+1);
-+}
-+# made-up unaligned memory reference AltiVec/VMX instructions
-+my $lvx_u	= sub {	vsxmem_op(@_, 844); };	# lxvd2x
-+my $stvx_u	= sub {	vsxmem_op(@_, 972); };	# stxvd2x
-+my $lvdx_u	= sub {	vsxmem_op(@_, 588); };	# lxsdx
-+my $stvdx_u	= sub {	vsxmem_op(@_, 716); };	# stxsdx
-+my $lvx_4w	= sub { vsxmem_op(@_, 780); };	# lxvw4x
-+my $stvx_4w	= sub { vsxmem_op(@_, 908); };	# stxvw4x
-+
-+# PowerISA 2.07 stuff
-+sub vcrypto_op {
-+    my ($f, $vrt, $vra, $vrb, $op) = @_;
-+    "	.long	".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|$op;
-+}
-+my $vcipher	= sub { vcrypto_op(@_, 1288); };
-+my $vcipherlast	= sub { vcrypto_op(@_, 1289); };
-+my $vncipher	= sub { vcrypto_op(@_, 1352); };
-+my $vncipherlast= sub { vcrypto_op(@_, 1353); };
-+my $vsbox	= sub { vcrypto_op(@_, 0, 1480); };
-+my $vshasigmad	= sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1730); };
-+my $vshasigmaw	= sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1666); };
-+my $vpmsumb	= sub { vcrypto_op(@_, 1032); };
-+my $vpmsumd	= sub { vcrypto_op(@_, 1224); };
-+my $vpmsubh	= sub { vcrypto_op(@_, 1096); };
-+my $vpmsumw	= sub { vcrypto_op(@_, 1160); };
-+my $vaddudm	= sub { vcrypto_op(@_, 192);  };
-+
-+my $mtsle	= sub {
-+    my ($f, $arg) = @_;
-+    "	.long	".sprintf "0x%X",(31<<26)|($arg<<21)|(147*2);
-+};
-+
-+# PowerISA 3.0 stuff
-+my $maddhdu = sub {
-+    my ($f, $rt, $ra, $rb, $rc) = @_;
-+    "	.long	".sprintf "0x%X",(4<<26)|($rt<<21)|($ra<<16)|($rb<<11)|($rc<<6)|49;
-+};
-+my $maddld = sub {
-+    my ($f, $rt, $ra, $rb, $rc) = @_;
-+    "	.long	".sprintf "0x%X",(4<<26)|($rt<<21)|($ra<<16)|($rb<<11)|($rc<<6)|51;
-+};
-+
-+my $darn = sub {
-+    my ($f, $rt, $l) = @_;
-+    "	.long	".sprintf "0x%X",(31<<26)|($rt<<21)|($l<<16)|(755<<1);
-+};
-+
-+while($line=<>) {
-+
-+    $line =~ s|[#!;].*$||;	# get rid of asm-style comments...
-+    $line =~ s|/\*.*\*/||;	# ... and C-style comments...
-+    $line =~ s|^\s+||;		# ... and skip white spaces in beginning...
-+    $line =~ s|\s+$||;		# ... and at the end
-+
-+    {
-+	$line =~ s|\b\.L(\w+)|L$1|g;	# common denominator for Locallabel
-+	$line =~ s|\bL(\w+)|\.L$1|g	if ($dotinlocallabels);
-+    }
-+
-+    {
-+	$line =~ s|(^[\.\w]+)\:\s*||;
-+	my $label = $1;
-+	if ($label) {
-+	    printf "%s:",($GLOBALS{$label} or $label);
-+	    printf "\n.localentry\t$GLOBALS{$label},0"	if ($GLOBALS{$label} && $flavour =~ /linux.*64le/);
-+	}
-+    }
-+
-+    {
-+	$line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||;
-+	my $c = $1; $c = "\t" if ($c eq "");
-+	my $mnemonic = $2;
-+	my $f = $3;
-+	my $opcode = eval("\$$mnemonic");
-+	$line =~ s/\b(c?[rf]|v|vs)([0-9]+)\b/$2/g if ($c ne "." and $flavour !~ /osx/);
-+	if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); }
-+	elsif ($mnemonic)           { $line = $c.$mnemonic.$f."\t".$line; }
-+    }
-+
-+    print $line if ($line);
-+    print "\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/sparcv9_modes.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/sparcv9_modes.pl
-new file mode 100644
-index 0000000..bfdada8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/sparcv9_modes.pl
-@@ -0,0 +1,1702 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# Specific modes implementations for SPARC Architecture 2011. There
-+# is T4 dependency though, an ASI value that is not specified in the
-+# Architecture Manual. But as SPARC universe is rather monocultural,
-+# we imply that processor capable of executing crypto instructions
-+# can handle the ASI in question as well. This means that we ought to
-+# keep eyes open when new processors emerge...
-+#
-+# As for above mentioned ASI. It's so called "block initializing
-+# store" which cancels "read" in "read-update-write" on cache lines.
-+# This is "cooperative" optimization, as it reduces overall pressure
-+# on memory interface. Benefits can't be observed/quantified with
-+# usual benchmarks, on the contrary you can notice that single-thread
-+# performance for parallelizable modes is ~1.5% worse for largest
-+# block sizes [though few percent better for not so long ones]. All
-+# this based on suggestions from David Miller.
-+
-+$::bias="STACK_BIAS";
-+$::frame="STACK_FRAME";
-+$::size_t_cc="SIZE_T_CC";
-+
-+sub asm_init {		# to be called with @ARGV as argument
-+    for (@_)		{ $::abibits=64 if (/\-m64/ || /\-xarch\=v9/); }
-+    if ($::abibits==64)	{ $::bias=2047; $::frame=192; $::size_t_cc="%xcc"; }
-+    else		{ $::bias=0;    $::frame=112; $::size_t_cc="%icc"; }
-+}
-+
-+# unified interface
-+my ($inp,$out,$len,$key,$ivec)=map("%i$_",(0..5));
-+# local variables
-+my ($ileft,$iright,$ooff,$omask,$ivoff,$blk_init)=map("%l$_",(0..7));
-+
-+sub alg_cbc_encrypt_implement {
-+my ($alg,$bits) = @_;
-+
-+$::code.=<<___;
-+.globl	${alg}${bits}_t4_cbc_encrypt
-+.align	32
-+${alg}${bits}_t4_cbc_encrypt:
-+	save		%sp, -$::frame, %sp
-+	cmp		$len, 0
-+	be,pn		$::size_t_cc, .L${bits}_cbc_enc_abort
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
-+	sub		$inp, $out, $blk_init	! $inp!=$out
-+___
-+$::code.=<<___ if (!$::evp);
-+	andcc		$ivec, 7, $ivoff
-+	alignaddr	$ivec, %g0, $ivec
-+
-+	ldd		[$ivec + 0], %f0	! load ivec
-+	bz,pt		%icc, 1f
-+	ldd		[$ivec + 8], %f2
-+	ldd		[$ivec + 16], %f4
-+	faligndata	%f0, %f2, %f0
-+	faligndata	%f2, %f4, %f2
-+1:
-+___
-+$::code.=<<___ if ($::evp);
-+	ld		[$ivec + 0], %f0
-+	ld		[$ivec + 4], %f1
-+	ld		[$ivec + 8], %f2
-+	ld		[$ivec + 12], %f3
-+___
-+$::code.=<<___;
-+	prefetch	[$inp], 20
-+	prefetch	[$inp + 63], 20
-+	call		_${alg}${bits}_load_enckey
-+	and		$inp, 7, $ileft
-+	andn		$inp, 7, $inp
-+	sll		$ileft, 3, $ileft
-+	mov		64, $iright
-+	mov		0xff, $omask
-+	sub		$iright, $ileft, $iright
-+	and		$out, 7, $ooff
-+	cmp		$len, 127
-+	movrnz		$ooff, 0, $blk_init		! if (	$out&7 ||
-+	movleu		$::size_t_cc, 0, $blk_init	!	$len<128 ||
-+	brnz,pn		$blk_init, .L${bits}cbc_enc_blk	!	$inp==$out)
-+	srl		$omask, $ooff, $omask
-+
-+	alignaddrl	$out, %g0, $out
-+	srlx		$len, 4, $len
-+	prefetch	[$out], 22
-+
-+.L${bits}_cbc_enc_loop:
-+	ldx		[$inp + 0], %o0
-+	brz,pt		$ileft, 4f
-+	ldx		[$inp + 8], %o1
-+
-+	ldx		[$inp + 16], %o2
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	sllx		%o1, $ileft, %o1
-+	or		%g1, %o0, %o0
-+	srlx		%o2, $iright, %o2
-+	or		%o2, %o1, %o1
-+4:
-+	xor		%g4, %o0, %o0		! ^= rk[0]
-+	xor		%g5, %o1, %o1
-+	movxtod		%o0, %f12
-+	movxtod		%o1, %f14
-+
-+	fxor		%f12, %f0, %f0		! ^= ivec
-+	fxor		%f14, %f2, %f2
-+	prefetch	[$out + 63], 22
-+	prefetch	[$inp + 16+63], 20
-+	call		_${alg}${bits}_encrypt_1x
-+	add		$inp, 16, $inp
-+
-+	brnz,pn		$ooff, 2f
-+	sub		$len, 1, $len
-+		
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	brnz,pt		$len, .L${bits}_cbc_enc_loop
-+	add		$out, 16, $out
-+___
-+$::code.=<<___ if ($::evp);
-+	st		%f0, [$ivec + 0]
-+	st		%f1, [$ivec + 4]
-+	st		%f2, [$ivec + 8]
-+	st		%f3, [$ivec + 12]
-+___
-+$::code.=<<___ if (!$::evp);
-+	brnz,pn		$ivoff, 3f
-+	nop
-+
-+	std		%f0, [$ivec + 0]	! write out ivec
-+	std		%f2, [$ivec + 8]
-+___
-+$::code.=<<___;
-+.L${bits}_cbc_enc_abort:
-+	ret
-+	restore
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-+						! and ~3x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f4		! handle unaligned output
-+	faligndata	%f0, %f2, %f6
-+	faligndata	%f2, %f2, %f8
-+
-+	stda		%f4, [$out + $omask]0xc0	! partial store
-+	std		%f6, [$out + 8]
-+	add		$out, 16, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f8, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .L${bits}_cbc_enc_loop+4
-+	orn		%g0, $omask, $omask
-+___
-+$::code.=<<___ if ($::evp);
-+	st		%f0, [$ivec + 0]
-+	st		%f1, [$ivec + 4]
-+	st		%f2, [$ivec + 8]
-+	st		%f3, [$ivec + 12]
-+___
-+$::code.=<<___ if (!$::evp);
-+	brnz,pn		$ivoff, 3f
-+	nop
-+
-+	std		%f0, [$ivec + 0]	! write out ivec
-+	std		%f2, [$ivec + 8]
-+	ret
-+	restore
-+
-+.align	16
-+3:	alignaddrl	$ivec, $ivoff, %g0	! handle unaligned ivec
-+	mov		0xff, $omask
-+	srl		$omask, $ivoff, $omask
-+	faligndata	%f0, %f0, %f4
-+	faligndata	%f0, %f2, %f6
-+	faligndata	%f2, %f2, %f8
-+	stda		%f4, [$ivec + $omask]0xc0
-+	std		%f6, [$ivec + 8]
-+	add		$ivec, 16, $ivec
-+	orn		%g0, $omask, $omask
-+	stda		%f8, [$ivec + $omask]0xc0
-+___
-+$::code.=<<___;
-+	ret
-+	restore
-+
-+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+.align	32
-+.L${bits}cbc_enc_blk:
-+	add	$out, $len, $blk_init
-+	and	$blk_init, 63, $blk_init	! tail
-+	sub	$len, $blk_init, $len
-+	add	$blk_init, 15, $blk_init	! round up to 16n
-+	srlx	$len, 4, $len
-+	srl	$blk_init, 4, $blk_init
-+
-+.L${bits}_cbc_enc_blk_loop:
-+	ldx		[$inp + 0], %o0
-+	brz,pt		$ileft, 5f
-+	ldx		[$inp + 8], %o1
-+
-+	ldx		[$inp + 16], %o2
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	sllx		%o1, $ileft, %o1
-+	or		%g1, %o0, %o0
-+	srlx		%o2, $iright, %o2
-+	or		%o2, %o1, %o1
-+5:
-+	xor		%g4, %o0, %o0		! ^= rk[0]
-+	xor		%g5, %o1, %o1
-+	movxtod		%o0, %f12
-+	movxtod		%o1, %f14
-+
-+	fxor		%f12, %f0, %f0		! ^= ivec
-+	fxor		%f14, %f2, %f2
-+	prefetch	[$inp + 16+63], 20
-+	call		_${alg}${bits}_encrypt_1x
-+	add		$inp, 16, $inp
-+	sub		$len, 1, $len
-+		
-+	stda		%f0, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	add		$out, 8, $out
-+	stda		%f2, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	brnz,pt		$len, .L${bits}_cbc_enc_blk_loop
-+	add		$out, 8, $out
-+
-+	membar		#StoreLoad|#StoreStore
-+	brnz,pt		$blk_init, .L${bits}_cbc_enc_loop
-+	mov		$blk_init, $len
-+___
-+$::code.=<<___ if ($::evp);
-+	st		%f0, [$ivec + 0]
-+	st		%f1, [$ivec + 4]
-+	st		%f2, [$ivec + 8]
-+	st		%f3, [$ivec + 12]
-+___
-+$::code.=<<___ if (!$::evp);
-+	brnz,pn		$ivoff, 3b
-+	nop
-+
-+	std		%f0, [$ivec + 0]	! write out ivec
-+	std		%f2, [$ivec + 8]
-+___
-+$::code.=<<___;
-+	ret
-+	restore
-+.type	${alg}${bits}_t4_cbc_encrypt,#function
-+.size	${alg}${bits}_t4_cbc_encrypt,.-${alg}${bits}_t4_cbc_encrypt
-+___
-+}
-+
-+sub alg_cbc_decrypt_implement {
-+my ($alg,$bits) = @_;
-+
-+$::code.=<<___;
-+.globl	${alg}${bits}_t4_cbc_decrypt
-+.align	32
-+${alg}${bits}_t4_cbc_decrypt:
-+	save		%sp, -$::frame, %sp
-+	cmp		$len, 0
-+	be,pn		$::size_t_cc, .L${bits}_cbc_dec_abort
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
-+	sub		$inp, $out, $blk_init	! $inp!=$out
-+___
-+$::code.=<<___ if (!$::evp);
-+	andcc		$ivec, 7, $ivoff
-+	alignaddr	$ivec, %g0, $ivec
-+
-+	ldd		[$ivec + 0], %f12	! load ivec
-+	bz,pt		%icc, 1f
-+	ldd		[$ivec + 8], %f14
-+	ldd		[$ivec + 16], %f0
-+	faligndata	%f12, %f14, %f12
-+	faligndata	%f14, %f0, %f14
-+1:
-+___
-+$::code.=<<___ if ($::evp);
-+	ld		[$ivec + 0], %f12	! load ivec
-+	ld		[$ivec + 4], %f13
-+	ld		[$ivec + 8], %f14
-+	ld		[$ivec + 12], %f15
-+___
-+$::code.=<<___;
-+	prefetch	[$inp], 20
-+	prefetch	[$inp + 63], 20
-+	call		_${alg}${bits}_load_deckey
-+	and		$inp, 7, $ileft
-+	andn		$inp, 7, $inp
-+	sll		$ileft, 3, $ileft
-+	mov		64, $iright
-+	mov		0xff, $omask
-+	sub		$iright, $ileft, $iright
-+	and		$out, 7, $ooff
-+	cmp		$len, 255
-+	movrnz		$ooff, 0, $blk_init		! if (	$out&7 ||
-+	movleu		$::size_t_cc, 0, $blk_init	!	$len<256 ||
-+	brnz,pn		$blk_init, .L${bits}cbc_dec_blk	!	$inp==$out)
-+	srl		$omask, $ooff, $omask
-+
-+	andcc		$len, 16, %g0		! is number of blocks even?
-+	srlx		$len, 4, $len
-+	alignaddrl	$out, %g0, $out
-+	bz		%icc, .L${bits}_cbc_dec_loop2x
-+	prefetch	[$out], 22
-+.L${bits}_cbc_dec_loop:
-+	ldx		[$inp + 0], %o0
-+	brz,pt		$ileft, 4f
-+	ldx		[$inp + 8], %o1
-+
-+	ldx		[$inp + 16], %o2
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	sllx		%o1, $ileft, %o1
-+	or		%g1, %o0, %o0
-+	srlx		%o2, $iright, %o2
-+	or		%o2, %o1, %o1
-+4:
-+	xor		%g4, %o0, %o2		! ^= rk[0]
-+	xor		%g5, %o1, %o3
-+	movxtod		%o2, %f0
-+	movxtod		%o3, %f2
-+
-+	prefetch	[$out + 63], 22
-+	prefetch	[$inp + 16+63], 20
-+	call		_${alg}${bits}_decrypt_1x
-+	add		$inp, 16, $inp
-+
-+	fxor		%f12, %f0, %f0		! ^= ivec
-+	fxor		%f14, %f2, %f2
-+	movxtod		%o0, %f12
-+	movxtod		%o1, %f14
-+
-+	brnz,pn		$ooff, 2f
-+	sub		$len, 1, $len
-+		
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	brnz,pt		$len, .L${bits}_cbc_dec_loop2x
-+	add		$out, 16, $out
-+___
-+$::code.=<<___ if ($::evp);
-+	st		%f12, [$ivec + 0]
-+	st		%f13, [$ivec + 4]
-+	st		%f14, [$ivec + 8]
-+	st		%f15, [$ivec + 12]
-+___
-+$::code.=<<___ if (!$::evp);
-+	brnz,pn		$ivoff, .L${bits}_cbc_dec_unaligned_ivec
-+	nop
-+
-+	std		%f12, [$ivec + 0]	! write out ivec
-+	std		%f14, [$ivec + 8]
-+___
-+$::code.=<<___;
-+.L${bits}_cbc_dec_abort:
-+	ret
-+	restore
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-+						! and ~3x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f4		! handle unaligned output
-+	faligndata	%f0, %f2, %f6
-+	faligndata	%f2, %f2, %f8
-+
-+	stda		%f4, [$out + $omask]0xc0	! partial store
-+	std		%f6, [$out + 8]
-+	add		$out, 16, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f8, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .L${bits}_cbc_dec_loop2x+4
-+	orn		%g0, $omask, $omask
-+___
-+$::code.=<<___ if ($::evp);
-+	st		%f12, [$ivec + 0]
-+	st		%f13, [$ivec + 4]
-+	st		%f14, [$ivec + 8]
-+	st		%f15, [$ivec + 12]
-+___
-+$::code.=<<___ if (!$::evp);
-+	brnz,pn		$ivoff, .L${bits}_cbc_dec_unaligned_ivec
-+	nop
-+
-+	std		%f12, [$ivec + 0]	! write out ivec
-+	std		%f14, [$ivec + 8]
-+___
-+$::code.=<<___;
-+	ret
-+	restore
-+
-+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+.align	32
-+.L${bits}_cbc_dec_loop2x:
-+	ldx		[$inp + 0], %o0
-+	ldx		[$inp + 8], %o1
-+	ldx		[$inp + 16], %o2
-+	brz,pt		$ileft, 4f
-+	ldx		[$inp + 24], %o3
-+
-+	ldx		[$inp + 32], %o4
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	or		%g1, %o0, %o0
-+	sllx		%o1, $ileft, %o1
-+	srlx		%o2, $iright, %g1
-+	or		%g1, %o1, %o1
-+	sllx		%o2, $ileft, %o2
-+	srlx		%o3, $iright, %g1
-+	or		%g1, %o2, %o2
-+	sllx		%o3, $ileft, %o3
-+	srlx		%o4, $iright, %o4
-+	or		%o4, %o3, %o3
-+4:
-+	xor		%g4, %o0, %o4		! ^= rk[0]
-+	xor		%g5, %o1, %o5
-+	movxtod		%o4, %f0
-+	movxtod		%o5, %f2
-+	xor		%g4, %o2, %o4
-+	xor		%g5, %o3, %o5
-+	movxtod		%o4, %f4
-+	movxtod		%o5, %f6
-+
-+	prefetch	[$out + 63], 22
-+	prefetch	[$inp + 32+63], 20
-+	call		_${alg}${bits}_decrypt_2x
-+	add		$inp, 32, $inp
-+
-+	movxtod		%o0, %f8
-+	movxtod		%o1, %f10
-+	fxor		%f12, %f0, %f0		! ^= ivec
-+	fxor		%f14, %f2, %f2
-+	movxtod		%o2, %f12
-+	movxtod		%o3, %f14
-+	fxor		%f8, %f4, %f4
-+	fxor		%f10, %f6, %f6
-+
-+	brnz,pn		$ooff, 2f
-+	sub		$len, 2, $len
-+		
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	std		%f4, [$out + 16]
-+	std		%f6, [$out + 24]
-+	brnz,pt		$len, .L${bits}_cbc_dec_loop2x
-+	add		$out, 32, $out
-+___
-+$::code.=<<___ if ($::evp);
-+	st		%f12, [$ivec + 0]
-+	st		%f13, [$ivec + 4]
-+	st		%f14, [$ivec + 8]
-+	st		%f15, [$ivec + 12]
-+___
-+$::code.=<<___ if (!$::evp);
-+	brnz,pn		$ivoff, .L${bits}_cbc_dec_unaligned_ivec
-+	nop
-+
-+	std		%f12, [$ivec + 0]	! write out ivec
-+	std		%f14, [$ivec + 8]
-+___
-+$::code.=<<___;
-+	ret
-+	restore
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-+						! and ~3x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f8		! handle unaligned output
-+	faligndata	%f0, %f2, %f0
-+	faligndata	%f2, %f4, %f2
-+	faligndata	%f4, %f6, %f4
-+	faligndata	%f6, %f6, %f6
-+	stda		%f8, [$out + $omask]0xc0	! partial store
-+	std		%f0, [$out + 8]
-+	std		%f2, [$out + 16]
-+	std		%f4, [$out + 24]
-+	add		$out, 32, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f6, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .L${bits}_cbc_dec_loop2x+4
-+	orn		%g0, $omask, $omask
-+___
-+$::code.=<<___ if ($::evp);
-+	st		%f12, [$ivec + 0]
-+	st		%f13, [$ivec + 4]
-+	st		%f14, [$ivec + 8]
-+	st		%f15, [$ivec + 12]
-+___
-+$::code.=<<___ if (!$::evp);
-+	brnz,pn		$ivoff, .L${bits}_cbc_dec_unaligned_ivec
-+	nop
-+
-+	std		%f12, [$ivec + 0]	! write out ivec
-+	std		%f14, [$ivec + 8]
-+	ret
-+	restore
-+
-+.align	16
-+.L${bits}_cbc_dec_unaligned_ivec:
-+	alignaddrl	$ivec, $ivoff, %g0	! handle unaligned ivec
-+	mov		0xff, $omask
-+	srl		$omask, $ivoff, $omask
-+	faligndata	%f12, %f12, %f0
-+	faligndata	%f12, %f14, %f2
-+	faligndata	%f14, %f14, %f4
-+	stda		%f0, [$ivec + $omask]0xc0
-+	std		%f2, [$ivec + 8]
-+	add		$ivec, 16, $ivec
-+	orn		%g0, $omask, $omask
-+	stda		%f4, [$ivec + $omask]0xc0
-+___
-+$::code.=<<___;
-+	ret
-+	restore
-+
-+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+.align	32
-+.L${bits}cbc_dec_blk:
-+	add	$out, $len, $blk_init
-+	and	$blk_init, 63, $blk_init	! tail
-+	sub	$len, $blk_init, $len
-+	add	$blk_init, 15, $blk_init	! round up to 16n
-+	srlx	$len, 4, $len
-+	srl	$blk_init, 4, $blk_init
-+	sub	$len, 1, $len
-+	add	$blk_init, 1, $blk_init
-+
-+.L${bits}_cbc_dec_blk_loop2x:
-+	ldx		[$inp + 0], %o0
-+	ldx		[$inp + 8], %o1
-+	ldx		[$inp + 16], %o2
-+	brz,pt		$ileft, 5f
-+	ldx		[$inp + 24], %o3
-+
-+	ldx		[$inp + 32], %o4
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	or		%g1, %o0, %o0
-+	sllx		%o1, $ileft, %o1
-+	srlx		%o2, $iright, %g1
-+	or		%g1, %o1, %o1
-+	sllx		%o2, $ileft, %o2
-+	srlx		%o3, $iright, %g1
-+	or		%g1, %o2, %o2
-+	sllx		%o3, $ileft, %o3
-+	srlx		%o4, $iright, %o4
-+	or		%o4, %o3, %o3
-+5:
-+	xor		%g4, %o0, %o4		! ^= rk[0]
-+	xor		%g5, %o1, %o5
-+	movxtod		%o4, %f0
-+	movxtod		%o5, %f2
-+	xor		%g4, %o2, %o4
-+	xor		%g5, %o3, %o5
-+	movxtod		%o4, %f4
-+	movxtod		%o5, %f6
-+
-+	prefetch	[$inp + 32+63], 20
-+	call		_${alg}${bits}_decrypt_2x
-+	add		$inp, 32, $inp
-+	subcc		$len, 2, $len
-+
-+	movxtod		%o0, %f8
-+	movxtod		%o1, %f10
-+	fxor		%f12, %f0, %f0		! ^= ivec
-+	fxor		%f14, %f2, %f2
-+	movxtod		%o2, %f12
-+	movxtod		%o3, %f14
-+	fxor		%f8, %f4, %f4
-+	fxor		%f10, %f6, %f6
-+
-+	stda		%f0, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	add		$out, 8, $out
-+	stda		%f2, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	add		$out, 8, $out
-+	stda		%f4, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	add		$out, 8, $out
-+	stda		%f6, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	bgu,pt		$::size_t_cc, .L${bits}_cbc_dec_blk_loop2x
-+	add		$out, 8, $out
-+
-+	add		$blk_init, $len, $len
-+	andcc		$len, 1, %g0		! is number of blocks even?
-+	membar		#StoreLoad|#StoreStore
-+	bnz,pt		%icc, .L${bits}_cbc_dec_loop
-+	srl		$len, 0, $len
-+	brnz,pn		$len, .L${bits}_cbc_dec_loop2x
-+	nop
-+___
-+$::code.=<<___ if ($::evp);
-+	st		%f12, [$ivec + 0]	! write out ivec
-+	st		%f13, [$ivec + 4]
-+	st		%f14, [$ivec + 8]
-+	st		%f15, [$ivec + 12]
-+___
-+$::code.=<<___ if (!$::evp);
-+	brnz,pn		$ivoff, 3b
-+	nop
-+
-+	std		%f12, [$ivec + 0]	! write out ivec
-+	std		%f14, [$ivec + 8]
-+___
-+$::code.=<<___;
-+	ret
-+	restore
-+.type	${alg}${bits}_t4_cbc_decrypt,#function
-+.size	${alg}${bits}_t4_cbc_decrypt,.-${alg}${bits}_t4_cbc_decrypt
-+___
-+}
-+
-+sub alg_ctr32_implement {
-+my ($alg,$bits) = @_;
-+
-+$::code.=<<___;
-+.globl	${alg}${bits}_t4_ctr32_encrypt
-+.align	32
-+${alg}${bits}_t4_ctr32_encrypt:
-+	save		%sp, -$::frame, %sp
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
-+
-+	prefetch	[$inp], 20
-+	prefetch	[$inp + 63], 20
-+	call		_${alg}${bits}_load_enckey
-+	sllx		$len, 4, $len
-+
-+	ld		[$ivec + 0], %l4	! counter
-+	ld		[$ivec + 4], %l5
-+	ld		[$ivec + 8], %l6
-+	ld		[$ivec + 12], %l7
-+
-+	sllx		%l4, 32, %o5
-+	or		%l5, %o5, %o5
-+	sllx		%l6, 32, %g1
-+	xor		%o5, %g4, %g4		! ^= rk[0]
-+	xor		%g1, %g5, %g5
-+	movxtod		%g4, %f14		! most significant 64 bits
-+
-+	sub		$inp, $out, $blk_init	! $inp!=$out
-+	and		$inp, 7, $ileft
-+	andn		$inp, 7, $inp
-+	sll		$ileft, 3, $ileft
-+	mov		64, $iright
-+	mov		0xff, $omask
-+	sub		$iright, $ileft, $iright
-+	and		$out, 7, $ooff
-+	cmp		$len, 255
-+	movrnz		$ooff, 0, $blk_init		! if (	$out&7 ||
-+	movleu		$::size_t_cc, 0, $blk_init	!	$len<256 ||
-+	brnz,pn		$blk_init, .L${bits}_ctr32_blk	!	$inp==$out)
-+	srl		$omask, $ooff, $omask
-+
-+	andcc		$len, 16, %g0		! is number of blocks even?
-+	alignaddrl	$out, %g0, $out
-+	bz		%icc, .L${bits}_ctr32_loop2x
-+	srlx		$len, 4, $len
-+.L${bits}_ctr32_loop:
-+	ldx		[$inp + 0], %o0
-+	brz,pt		$ileft, 4f
-+	ldx		[$inp + 8], %o1
-+
-+	ldx		[$inp + 16], %o2
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	sllx		%o1, $ileft, %o1
-+	or		%g1, %o0, %o0
-+	srlx		%o2, $iright, %o2
-+	or		%o2, %o1, %o1
-+4:
-+	xor		%g5, %l7, %g1		! ^= rk[0]
-+	add		%l7, 1, %l7
-+	movxtod		%g1, %f2
-+	srl		%l7, 0, %l7		! clruw
-+	prefetch	[$out + 63], 22
-+	prefetch	[$inp + 16+63], 20
-+___
-+$::code.=<<___ if ($alg eq "aes");
-+	aes_eround01	%f16, %f14, %f2, %f4
-+	aes_eround23	%f18, %f14, %f2, %f2
-+___
-+$::code.=<<___ if ($alg eq "cmll");
-+	camellia_f	%f16, %f2, %f14, %f2
-+	camellia_f	%f18, %f14, %f2, %f0
-+___
-+$::code.=<<___;
-+	call		_${alg}${bits}_encrypt_1x+8
-+	add		$inp, 16, $inp
-+
-+	movxtod		%o0, %f10
-+	movxtod		%o1, %f12
-+	fxor		%f10, %f0, %f0		! ^= inp
-+	fxor		%f12, %f2, %f2
-+
-+	brnz,pn		$ooff, 2f
-+	sub		$len, 1, $len
-+		
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	brnz,pt		$len, .L${bits}_ctr32_loop2x
-+	add		$out, 16, $out
-+
-+	ret
-+	restore
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-+						! and ~3x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f4		! handle unaligned output
-+	faligndata	%f0, %f2, %f6
-+	faligndata	%f2, %f2, %f8
-+	stda		%f4, [$out + $omask]0xc0	! partial store
-+	std		%f6, [$out + 8]
-+	add		$out, 16, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f8, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .L${bits}_ctr32_loop2x+4
-+	orn		%g0, $omask, $omask
-+
-+	ret
-+	restore
-+
-+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+.align	32
-+.L${bits}_ctr32_loop2x:
-+	ldx		[$inp + 0], %o0
-+	ldx		[$inp + 8], %o1
-+	ldx		[$inp + 16], %o2
-+	brz,pt		$ileft, 4f
-+	ldx		[$inp + 24], %o3
-+
-+	ldx		[$inp + 32], %o4
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	or		%g1, %o0, %o0
-+	sllx		%o1, $ileft, %o1
-+	srlx		%o2, $iright, %g1
-+	or		%g1, %o1, %o1
-+	sllx		%o2, $ileft, %o2
-+	srlx		%o3, $iright, %g1
-+	or		%g1, %o2, %o2
-+	sllx		%o3, $ileft, %o3
-+	srlx		%o4, $iright, %o4
-+	or		%o4, %o3, %o3
-+4:
-+	xor		%g5, %l7, %g1		! ^= rk[0]
-+	add		%l7, 1, %l7
-+	movxtod		%g1, %f2
-+	srl		%l7, 0, %l7		! clruw
-+	xor		%g5, %l7, %g1
-+	add		%l7, 1, %l7
-+	movxtod		%g1, %f6
-+	srl		%l7, 0, %l7		! clruw
-+	prefetch	[$out + 63], 22
-+	prefetch	[$inp + 32+63], 20
-+___
-+$::code.=<<___ if ($alg eq "aes");
-+	aes_eround01	%f16, %f14, %f2, %f8
-+	aes_eround23	%f18, %f14, %f2, %f2
-+	aes_eround01	%f16, %f14, %f6, %f10
-+	aes_eround23	%f18, %f14, %f6, %f6
-+___
-+$::code.=<<___ if ($alg eq "cmll");
-+	camellia_f	%f16, %f2, %f14, %f2
-+	camellia_f	%f16, %f6, %f14, %f6
-+	camellia_f	%f18, %f14, %f2, %f0
-+	camellia_f	%f18, %f14, %f6, %f4
-+___
-+$::code.=<<___;
-+	call		_${alg}${bits}_encrypt_2x+16
-+	add		$inp, 32, $inp
-+
-+	movxtod		%o0, %f8
-+	movxtod		%o1, %f10
-+	movxtod		%o2, %f12
-+	fxor		%f8, %f0, %f0		! ^= inp
-+	movxtod		%o3, %f8
-+	fxor		%f10, %f2, %f2
-+	fxor		%f12, %f4, %f4
-+	fxor		%f8, %f6, %f6
-+
-+	brnz,pn		$ooff, 2f
-+	sub		$len, 2, $len
-+		
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	std		%f4, [$out + 16]
-+	std		%f6, [$out + 24]
-+	brnz,pt		$len, .L${bits}_ctr32_loop2x
-+	add		$out, 32, $out
-+
-+	ret
-+	restore
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-+						! and ~3x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f8		! handle unaligned output
-+	faligndata	%f0, %f2, %f0
-+	faligndata	%f2, %f4, %f2
-+	faligndata	%f4, %f6, %f4
-+	faligndata	%f6, %f6, %f6
-+
-+	stda		%f8, [$out + $omask]0xc0	! partial store
-+	std		%f0, [$out + 8]
-+	std		%f2, [$out + 16]
-+	std		%f4, [$out + 24]
-+	add		$out, 32, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f6, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .L${bits}_ctr32_loop2x+4
-+	orn		%g0, $omask, $omask
-+
-+	ret
-+	restore
-+
-+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+.align	32
-+.L${bits}_ctr32_blk:
-+	add	$out, $len, $blk_init
-+	and	$blk_init, 63, $blk_init	! tail
-+	sub	$len, $blk_init, $len
-+	add	$blk_init, 15, $blk_init	! round up to 16n
-+	srlx	$len, 4, $len
-+	srl	$blk_init, 4, $blk_init
-+	sub	$len, 1, $len
-+	add	$blk_init, 1, $blk_init
-+
-+.L${bits}_ctr32_blk_loop2x:
-+	ldx		[$inp + 0], %o0
-+	ldx		[$inp + 8], %o1
-+	ldx		[$inp + 16], %o2
-+	brz,pt		$ileft, 5f
-+	ldx		[$inp + 24], %o3
-+
-+	ldx		[$inp + 32], %o4
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	or		%g1, %o0, %o0
-+	sllx		%o1, $ileft, %o1
-+	srlx		%o2, $iright, %g1
-+	or		%g1, %o1, %o1
-+	sllx		%o2, $ileft, %o2
-+	srlx		%o3, $iright, %g1
-+	or		%g1, %o2, %o2
-+	sllx		%o3, $ileft, %o3
-+	srlx		%o4, $iright, %o4
-+	or		%o4, %o3, %o3
-+5:
-+	xor		%g5, %l7, %g1		! ^= rk[0]
-+	add		%l7, 1, %l7
-+	movxtod		%g1, %f2
-+	srl		%l7, 0, %l7		! clruw
-+	xor		%g5, %l7, %g1
-+	add		%l7, 1, %l7
-+	movxtod		%g1, %f6
-+	srl		%l7, 0, %l7		! clruw
-+	prefetch	[$inp + 32+63], 20
-+___
-+$::code.=<<___ if ($alg eq "aes");
-+	aes_eround01	%f16, %f14, %f2, %f8
-+	aes_eround23	%f18, %f14, %f2, %f2
-+	aes_eround01	%f16, %f14, %f6, %f10
-+	aes_eround23	%f18, %f14, %f6, %f6
-+___
-+$::code.=<<___ if ($alg eq "cmll");
-+	camellia_f	%f16, %f2, %f14, %f2
-+	camellia_f	%f16, %f6, %f14, %f6
-+	camellia_f	%f18, %f14, %f2, %f0
-+	camellia_f	%f18, %f14, %f6, %f4
-+___
-+$::code.=<<___;
-+	call		_${alg}${bits}_encrypt_2x+16
-+	add		$inp, 32, $inp
-+	subcc		$len, 2, $len
-+
-+	movxtod		%o0, %f8
-+	movxtod		%o1, %f10
-+	movxtod		%o2, %f12
-+	fxor		%f8, %f0, %f0		! ^= inp
-+	movxtod		%o3, %f8
-+	fxor		%f10, %f2, %f2
-+	fxor		%f12, %f4, %f4
-+	fxor		%f8, %f6, %f6
-+
-+	stda		%f0, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	add		$out, 8, $out
-+	stda		%f2, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	add		$out, 8, $out
-+	stda		%f4, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	add		$out, 8, $out
-+	stda		%f6, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	bgu,pt		$::size_t_cc, .L${bits}_ctr32_blk_loop2x
-+	add		$out, 8, $out
-+
-+	add		$blk_init, $len, $len
-+	andcc		$len, 1, %g0		! is number of blocks even?
-+	membar		#StoreLoad|#StoreStore
-+	bnz,pt		%icc, .L${bits}_ctr32_loop
-+	srl		$len, 0, $len
-+	brnz,pn		$len, .L${bits}_ctr32_loop2x
-+	nop
-+
-+	ret
-+	restore
-+.type	${alg}${bits}_t4_ctr32_encrypt,#function
-+.size	${alg}${bits}_t4_ctr32_encrypt,.-${alg}${bits}_t4_ctr32_encrypt
-+___
-+}
-+
-+sub alg_xts_implement {
-+my ($alg,$bits,$dir) = @_;
-+my ($inp,$out,$len,$key1,$key2,$ivec)=map("%i$_",(0..5));
-+my $rem=$ivec;
-+
-+$::code.=<<___;
-+.globl	${alg}${bits}_t4_xts_${dir}crypt
-+.align	32
-+${alg}${bits}_t4_xts_${dir}crypt:
-+	save		%sp, -$::frame-16, %sp
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
-+
-+	mov		$ivec, %o0
-+	add		%fp, $::bias-16, %o1
-+	call		${alg}_t4_encrypt
-+	mov		$key2, %o2
-+
-+	add		%fp, $::bias-16, %l7
-+	ldxa		[%l7]0x88, %g2
-+	add		%fp, $::bias-8, %l7
-+	ldxa		[%l7]0x88, %g3		! %g3:%g2 is tweak
-+
-+	sethi		%hi(0x76543210), %l7
-+	or		%l7, %lo(0x76543210), %l7
-+	bmask		%l7, %g0, %g0		! byte swap mask
-+
-+	prefetch	[$inp], 20
-+	prefetch	[$inp + 63], 20
-+	call		_${alg}${bits}_load_${dir}ckey
-+	and		$len, 15,  $rem
-+	and		$len, -16, $len
-+___
-+$code.=<<___ if ($dir eq "de");
-+	mov		0, %l7
-+	movrnz		$rem, 16,  %l7
-+	sub		$len, %l7, $len
-+___
-+$code.=<<___;
-+
-+	sub		$inp, $out, $blk_init	! $inp!=$out
-+	and		$inp, 7, $ileft
-+	andn		$inp, 7, $inp
-+	sll		$ileft, 3, $ileft
-+	mov		64, $iright
-+	mov		0xff, $omask
-+	sub		$iright, $ileft, $iright
-+	and		$out, 7, $ooff
-+	cmp		$len, 255
-+	movrnz		$ooff, 0, $blk_init		! if (	$out&7 ||
-+	movleu		$::size_t_cc, 0, $blk_init	!	$len<256 ||
-+	brnz,pn		$blk_init, .L${bits}_xts_${dir}blk !	$inp==$out)
-+	srl		$omask, $ooff, $omask
-+
-+	andcc		$len, 16, %g0		! is number of blocks even?
-+___
-+$code.=<<___ if ($dir eq "de");
-+	brz,pn		$len, .L${bits}_xts_${dir}steal
-+___
-+$code.=<<___;
-+	alignaddrl	$out, %g0, $out
-+	bz		%icc, .L${bits}_xts_${dir}loop2x
-+	srlx		$len, 4, $len
-+.L${bits}_xts_${dir}loop:
-+	ldx		[$inp + 0], %o0
-+	brz,pt		$ileft, 4f
-+	ldx		[$inp + 8], %o1
-+
-+	ldx		[$inp + 16], %o2
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	sllx		%o1, $ileft, %o1
-+	or		%g1, %o0, %o0
-+	srlx		%o2, $iright, %o2
-+	or		%o2, %o1, %o1
-+4:
-+	movxtod		%g2, %f12
-+	movxtod		%g3, %f14
-+	bshuffle	%f12, %f12, %f12
-+	bshuffle	%f14, %f14, %f14
-+
-+	xor		%g4, %o0, %o0		! ^= rk[0]
-+	xor		%g5, %o1, %o1
-+	movxtod		%o0, %f0
-+	movxtod		%o1, %f2
-+
-+	fxor		%f12, %f0, %f0		! ^= tweak[0]
-+	fxor		%f14, %f2, %f2
-+
-+	prefetch	[$out + 63], 22
-+	prefetch	[$inp + 16+63], 20
-+	call		_${alg}${bits}_${dir}crypt_1x
-+	add		$inp, 16, $inp
-+
-+	fxor		%f12, %f0, %f0		! ^= tweak[0]
-+	fxor		%f14, %f2, %f2
-+
-+	srax		%g3, 63, %l7		! next tweak value
-+	addcc		%g2, %g2, %g2
-+	and		%l7, 0x87, %l7
-+	addxc		%g3, %g3, %g3
-+	xor		%l7, %g2, %g2
-+
-+	brnz,pn		$ooff, 2f
-+	sub		$len, 1, $len
-+		
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	brnz,pt		$len, .L${bits}_xts_${dir}loop2x
-+	add		$out, 16, $out
-+
-+	brnz,pn		$rem, .L${bits}_xts_${dir}steal
-+	nop
-+
-+	ret
-+	restore
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-+						! and ~3x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f4		! handle unaligned output
-+	faligndata	%f0, %f2, %f6
-+	faligndata	%f2, %f2, %f8
-+	stda		%f4, [$out + $omask]0xc0	! partial store
-+	std		%f6, [$out + 8]
-+	add		$out, 16, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f8, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .L${bits}_xts_${dir}loop2x+4
-+	orn		%g0, $omask, $omask
-+
-+	brnz,pn		$rem, .L${bits}_xts_${dir}steal
-+	nop
-+
-+	ret
-+	restore
-+
-+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+.align	32
-+.L${bits}_xts_${dir}loop2x:
-+	ldx		[$inp + 0], %o0
-+	ldx		[$inp + 8], %o1
-+	ldx		[$inp + 16], %o2
-+	brz,pt		$ileft, 4f
-+	ldx		[$inp + 24], %o3
-+
-+	ldx		[$inp + 32], %o4
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	or		%g1, %o0, %o0
-+	sllx		%o1, $ileft, %o1
-+	srlx		%o2, $iright, %g1
-+	or		%g1, %o1, %o1
-+	sllx		%o2, $ileft, %o2
-+	srlx		%o3, $iright, %g1
-+	or		%g1, %o2, %o2
-+	sllx		%o3, $ileft, %o3
-+	srlx		%o4, $iright, %o4
-+	or		%o4, %o3, %o3
-+4:
-+	movxtod		%g2, %f12
-+	movxtod		%g3, %f14
-+	bshuffle	%f12, %f12, %f12
-+	bshuffle	%f14, %f14, %f14
-+
-+	srax		%g3, 63, %l7		! next tweak value
-+	addcc		%g2, %g2, %g2
-+	and		%l7, 0x87, %l7
-+	addxc		%g3, %g3, %g3
-+	xor		%l7, %g2, %g2
-+
-+	movxtod		%g2, %f8
-+	movxtod		%g3, %f10
-+	bshuffle	%f8,  %f8,  %f8
-+	bshuffle	%f10, %f10, %f10
-+
-+	xor		%g4, %o0, %o0		! ^= rk[0]
-+	xor		%g5, %o1, %o1
-+	xor		%g4, %o2, %o2		! ^= rk[0]
-+	xor		%g5, %o3, %o3
-+	movxtod		%o0, %f0
-+	movxtod		%o1, %f2
-+	movxtod		%o2, %f4
-+	movxtod		%o3, %f6
-+
-+	fxor		%f12, %f0, %f0		! ^= tweak[0]
-+	fxor		%f14, %f2, %f2
-+	fxor		%f8,  %f4, %f4		! ^= tweak[0]
-+	fxor		%f10, %f6, %f6
-+
-+	prefetch	[$out + 63], 22
-+	prefetch	[$inp + 32+63], 20
-+	call		_${alg}${bits}_${dir}crypt_2x
-+	add		$inp, 32, $inp
-+
-+	movxtod		%g2, %f8
-+	movxtod		%g3, %f10
-+
-+	srax		%g3, 63, %l7		! next tweak value
-+	addcc		%g2, %g2, %g2
-+	and		%l7, 0x87, %l7
-+	addxc		%g3, %g3, %g3
-+	xor		%l7, %g2, %g2
-+
-+	bshuffle	%f8,  %f8,  %f8
-+	bshuffle	%f10, %f10, %f10
-+
-+	fxor		%f12, %f0, %f0		! ^= tweak[0]
-+	fxor		%f14, %f2, %f2
-+	fxor		%f8,  %f4, %f4
-+	fxor		%f10, %f6, %f6
-+
-+	brnz,pn		$ooff, 2f
-+	sub		$len, 2, $len
-+		
-+	std		%f0, [$out + 0]
-+	std		%f2, [$out + 8]
-+	std		%f4, [$out + 16]
-+	std		%f6, [$out + 24]
-+	brnz,pt		$len, .L${bits}_xts_${dir}loop2x
-+	add		$out, 32, $out
-+
-+	fsrc2		%f4, %f0
-+	fsrc2		%f6, %f2
-+	brnz,pn		$rem, .L${bits}_xts_${dir}steal
-+	nop
-+
-+	ret
-+	restore
-+
-+.align	16
-+2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-+						! and ~3x deterioration
-+						! in inp==out case
-+	faligndata	%f0, %f0, %f8		! handle unaligned output
-+	faligndata	%f0, %f2, %f10
-+	faligndata	%f2, %f4, %f12
-+	faligndata	%f4, %f6, %f14
-+	faligndata	%f6, %f6, %f0
-+
-+	stda		%f8, [$out + $omask]0xc0	! partial store
-+	std		%f10, [$out + 8]
-+	std		%f12, [$out + 16]
-+	std		%f14, [$out + 24]
-+	add		$out, 32, $out
-+	orn		%g0, $omask, $omask
-+	stda		%f0, [$out + $omask]0xc0	! partial store
-+
-+	brnz,pt		$len, .L${bits}_xts_${dir}loop2x+4
-+	orn		%g0, $omask, $omask
-+
-+	fsrc2		%f4, %f0
-+	fsrc2		%f6, %f2
-+	brnz,pn		$rem, .L${bits}_xts_${dir}steal
-+	nop
-+
-+	ret
-+	restore
-+
-+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+.align	32
-+.L${bits}_xts_${dir}blk:
-+	add	$out, $len, $blk_init
-+	and	$blk_init, 63, $blk_init	! tail
-+	sub	$len, $blk_init, $len
-+	add	$blk_init, 15, $blk_init	! round up to 16n
-+	srlx	$len, 4, $len
-+	srl	$blk_init, 4, $blk_init
-+	sub	$len, 1, $len
-+	add	$blk_init, 1, $blk_init
-+
-+.L${bits}_xts_${dir}blk2x:
-+	ldx		[$inp + 0], %o0
-+	ldx		[$inp + 8], %o1
-+	ldx		[$inp + 16], %o2
-+	brz,pt		$ileft, 5f
-+	ldx		[$inp + 24], %o3
-+
-+	ldx		[$inp + 32], %o4
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	or		%g1, %o0, %o0
-+	sllx		%o1, $ileft, %o1
-+	srlx		%o2, $iright, %g1
-+	or		%g1, %o1, %o1
-+	sllx		%o2, $ileft, %o2
-+	srlx		%o3, $iright, %g1
-+	or		%g1, %o2, %o2
-+	sllx		%o3, $ileft, %o3
-+	srlx		%o4, $iright, %o4
-+	or		%o4, %o3, %o3
-+5:
-+	movxtod		%g2, %f12
-+	movxtod		%g3, %f14
-+	bshuffle	%f12, %f12, %f12
-+	bshuffle	%f14, %f14, %f14
-+
-+	srax		%g3, 63, %l7		! next tweak value
-+	addcc		%g2, %g2, %g2
-+	and		%l7, 0x87, %l7
-+	addxc		%g3, %g3, %g3
-+	xor		%l7, %g2, %g2
-+
-+	movxtod		%g2, %f8
-+	movxtod		%g3, %f10
-+	bshuffle	%f8,  %f8,  %f8
-+	bshuffle	%f10, %f10, %f10
-+
-+	xor		%g4, %o0, %o0		! ^= rk[0]
-+	xor		%g5, %o1, %o1
-+	xor		%g4, %o2, %o2		! ^= rk[0]
-+	xor		%g5, %o3, %o3
-+	movxtod		%o0, %f0
-+	movxtod		%o1, %f2
-+	movxtod		%o2, %f4
-+	movxtod		%o3, %f6
-+
-+	fxor		%f12, %f0, %f0		! ^= tweak[0]
-+	fxor		%f14, %f2, %f2
-+	fxor		%f8,  %f4, %f4		! ^= tweak[0]
-+	fxor		%f10, %f6, %f6
-+
-+	prefetch	[$inp + 32+63], 20
-+	call		_${alg}${bits}_${dir}crypt_2x
-+	add		$inp, 32, $inp
-+
-+	movxtod		%g2, %f8
-+	movxtod		%g3, %f10
-+
-+	srax		%g3, 63, %l7		! next tweak value
-+	addcc		%g2, %g2, %g2
-+	and		%l7, 0x87, %l7
-+	addxc		%g3, %g3, %g3
-+	xor		%l7, %g2, %g2
-+
-+	bshuffle	%f8,  %f8,  %f8
-+	bshuffle	%f10, %f10, %f10
-+
-+	fxor		%f12, %f0, %f0		! ^= tweak[0]
-+	fxor		%f14, %f2, %f2
-+	fxor		%f8,  %f4, %f4
-+	fxor		%f10, %f6, %f6
-+
-+	subcc		$len, 2, $len
-+	stda		%f0, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	add		$out, 8, $out
-+	stda		%f2, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	add		$out, 8, $out
-+	stda		%f4, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	add		$out, 8, $out
-+	stda		%f6, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-+	bgu,pt		$::size_t_cc, .L${bits}_xts_${dir}blk2x
-+	add		$out, 8, $out
-+
-+	add		$blk_init, $len, $len
-+	andcc		$len, 1, %g0		! is number of blocks even?
-+	membar		#StoreLoad|#StoreStore
-+	bnz,pt		%icc, .L${bits}_xts_${dir}loop
-+	srl		$len, 0, $len
-+	brnz,pn		$len, .L${bits}_xts_${dir}loop2x
-+	nop
-+
-+	fsrc2		%f4, %f0
-+	fsrc2		%f6, %f2
-+	brnz,pn		$rem, .L${bits}_xts_${dir}steal
-+	nop
-+
-+	ret
-+	restore
-+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+___
-+$code.=<<___ if ($dir eq "en");
-+.align	32
-+.L${bits}_xts_${dir}steal:
-+	std		%f0, [%fp + $::bias-16]	! copy of output
-+	std		%f2, [%fp + $::bias-8]
-+
-+	srl		$ileft, 3, $ileft
-+	add		%fp, $::bias-16, %l7
-+	add		$inp, $ileft, $inp	! original $inp+$len&-15
-+	add		$out, $ooff, $out	! original $out+$len&-15
-+	mov		0, $ileft
-+	nop					! align
-+
-+.L${bits}_xts_${dir}stealing:
-+	ldub		[$inp + $ileft], %o0
-+	ldub		[%l7  + $ileft], %o1
-+	dec		$rem
-+	stb		%o0, [%l7  + $ileft]
-+	stb		%o1, [$out + $ileft]
-+	brnz		$rem, .L${bits}_xts_${dir}stealing
-+	inc		$ileft
-+
-+	mov		%l7, $inp
-+	sub		$out, 16, $out
-+	mov		0, $ileft
-+	sub		$out, $ooff, $out
-+	ba		.L${bits}_xts_${dir}loop	! one more time
-+	mov		1, $len				! $rem is 0
-+___
-+$code.=<<___ if ($dir eq "de");
-+.align	32
-+.L${bits}_xts_${dir}steal:
-+	ldx		[$inp + 0], %o0
-+	brz,pt		$ileft, 8f
-+	ldx		[$inp + 8], %o1
-+
-+	ldx		[$inp + 16], %o2
-+	sllx		%o0, $ileft, %o0
-+	srlx		%o1, $iright, %g1
-+	sllx		%o1, $ileft, %o1
-+	or		%g1, %o0, %o0
-+	srlx		%o2, $iright, %o2
-+	or		%o2, %o1, %o1
-+8:
-+	srax		%g3, 63, %l7		! next tweak value
-+	addcc		%g2, %g2, %o2
-+	and		%l7, 0x87, %l7
-+	addxc		%g3, %g3, %o3
-+	xor		%l7, %o2, %o2
-+
-+	movxtod		%o2, %f12
-+	movxtod		%o3, %f14
-+	bshuffle	%f12, %f12, %f12
-+	bshuffle	%f14, %f14, %f14
-+
-+	xor		%g4, %o0, %o0		! ^= rk[0]
-+	xor		%g5, %o1, %o1
-+	movxtod		%o0, %f0
-+	movxtod		%o1, %f2
-+
-+	fxor		%f12, %f0, %f0		! ^= tweak[0]
-+	fxor		%f14, %f2, %f2
-+
-+	call		_${alg}${bits}_${dir}crypt_1x
-+	add		$inp, 16, $inp
-+
-+	fxor		%f12, %f0, %f0		! ^= tweak[0]
-+	fxor		%f14, %f2, %f2
-+
-+	std		%f0, [%fp + $::bias-16]
-+	std		%f2, [%fp + $::bias-8]
-+
-+	srl		$ileft, 3, $ileft
-+	add		%fp, $::bias-16, %l7
-+	add		$inp, $ileft, $inp	! original $inp+$len&-15
-+	add		$out, $ooff, $out	! original $out+$len&-15
-+	mov		0, $ileft
-+	add		$out, 16, $out
-+	nop					! align
-+
-+.L${bits}_xts_${dir}stealing:
-+	ldub		[$inp + $ileft], %o0
-+	ldub		[%l7  + $ileft], %o1
-+	dec		$rem
-+	stb		%o0, [%l7  + $ileft]
-+	stb		%o1, [$out + $ileft]
-+	brnz		$rem, .L${bits}_xts_${dir}stealing
-+	inc		$ileft
-+
-+	mov		%l7, $inp
-+	sub		$out, 16, $out
-+	mov		0, $ileft
-+	sub		$out, $ooff, $out
-+	ba		.L${bits}_xts_${dir}loop	! one more time
-+	mov		1, $len				! $rem is 0
-+___
-+$code.=<<___;
-+	ret
-+	restore
-+.type	${alg}${bits}_t4_xts_${dir}crypt,#function
-+.size	${alg}${bits}_t4_xts_${dir}crypt,.-${alg}${bits}_t4_xts_${dir}crypt
-+___
-+}
-+
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my ($ref,$opf);
-+my %visopf = (	"faligndata"	=> 0x048,
-+		"bshuffle"	=> 0x04c,
-+		"fnot2"		=> 0x066,
-+		"fxor"		=> 0x06c,
-+		"fsrc2"		=> 0x078	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub unvis3 {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my ($ref,$opf);
-+my %visopf = (	"addxc"		=> 0x011,
-+		"addxccc"	=> 0x013,
-+		"umulxhi"	=> 0x016,
-+		"alignaddr"	=> 0x018,
-+		"bmask"		=> 0x019,
-+		"alignaddrl"	=> 0x01a	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%([goli])([0-9])/);
-+	    $_=$bias{$1}+$2;
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub unaes_round {	# 4-argument instructions
-+my ($mnemonic,$rs1,$rs2,$rs3,$rd)=@_;
-+my ($ref,$opf);
-+my %aesopf = (	"aes_eround01"	=> 0,
-+		"aes_eround23"	=> 1,
-+		"aes_dround01"	=> 2,
-+		"aes_dround23"	=> 3,
-+		"aes_eround01_l"=> 4,
-+		"aes_eround23_l"=> 5,
-+		"aes_dround01_l"=> 6,
-+		"aes_dround23_l"=> 7,
-+		"aes_kexpand1"	=> 8	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rs3,$rd";
-+
-+    if (defined($opf=$aesopf{$mnemonic})) {
-+	$rs3 = ($rs3 =~ /%f([0-6]*[02468])/) ? (($1|$1>>5)&31) : $rs3;
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			2<<30|$rd<<25|0x19<<19|$rs1<<14|$rs3<<9|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub unaes_kexpand {	# 3-argument instructions
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my ($ref,$opf);
-+my %aesopf = (	"aes_kexpand0"	=> 0x130,
-+		"aes_kexpand2"	=> 0x131	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if (defined($opf=$aesopf{$mnemonic})) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			2<<30|$rd<<25|0x36<<19|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub uncamellia_f {	# 4-argument instructions
-+my ($mnemonic,$rs1,$rs2,$rs3,$rd)=@_;
-+my ($ref,$opf);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rs3,$rd";
-+
-+    if (1) {
-+	$rs3 = ($rs3 =~ /%f([0-6]*[02468])/) ? (($1|$1>>5)&31) : $rs3;
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			2<<30|$rd<<25|0x19<<19|$rs1<<14|$rs3<<9|0xc<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub uncamellia3 {	# 3-argument instructions
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my ($ref,$opf);
-+my %cmllopf = (	"camellia_fl"	=> 0x13c,
-+		"camellia_fli"	=> 0x13d	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if (defined($opf=$cmllopf{$mnemonic})) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			2<<30|$rd<<25|0x36<<19|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub unmovxtox {		# 2-argument instructions
-+my ($mnemonic,$rs,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24, "f" => 0 );
-+my ($ref,$opf);
-+my %movxopf = (	"movdtox"	=> 0x110,
-+		"movstouw"	=> 0x111,
-+		"movstosw"	=> 0x113,
-+		"movxtod"	=> 0x118,
-+		"movwtos"	=> 0x119	);
-+
-+    $ref = "$mnemonic\t$rs,$rd";
-+
-+    if (defined($opf=$movxopf{$mnemonic})) {
-+	foreach ($rs,$rd) {
-+	    return $ref if (!/%([fgoli])([0-9]{1,2})/);
-+	    $_=$bias{$1}+$2;
-+	    if ($2>=32) {
-+		return $ref if ($2&1);
-+		# re-encode for upper double register addressing
-+		$_=($2|$2>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			2<<30|$rd<<25|0x36<<19|$opf<<5|$rs,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub undes {
-+my ($mnemonic)=shift;
-+my @args=@_;
-+my ($ref,$opf);
-+my %desopf = (	"des_round"	=> 0b1001,
-+		"des_ip"	=> 0b100110100,
-+		"des_iip"	=> 0b100110101,
-+		"des_kexpand"	=> 0b100110110	);
-+
-+    $ref = "$mnemonic\t".join(",",@_);
-+
-+    if (defined($opf=$desopf{$mnemonic})) {	# 4-arg
-+	if ($mnemonic eq "des_round") {
-+	    foreach (@args[0..3]) {
-+		return $ref if (!/%f([0-9]{1,2})/);
-+		$_=$1;
-+		if ($1>=32) {
-+		    return $ref if ($1&1);
-+		    # re-encode for upper double register addressing
-+		    $_=($1|$1>>5)&31;
-+		}
-+	    }
-+	    return  sprintf ".word\t0x%08x !%s",
-+			    2<<30|0b011001<<19|$opf<<5|$args[0]<<14|$args[1]|$args[2]<<9|$args[3]<<25,
-+			    $ref;
-+	} elsif ($mnemonic eq "des_kexpand") {	# 3-arg
-+	    foreach (@args[0..2]) {
-+		return $ref if (!/(%f)?([0-9]{1,2})/);
-+		$_=$2;
-+		if ($2>=32) {
-+		    return $ref if ($2&1);
-+		    # re-encode for upper double register addressing
-+		    $_=($2|$2>>5)&31;
-+		}
-+	    }
-+	    return  sprintf ".word\t0x%08x !%s",
-+			    2<<30|0b110110<<19|$opf<<5|$args[0]<<14|$args[1]|$args[2]<<25,
-+			    $ref;
-+	} else {				# 2-arg
-+	    foreach (@args[0..1]) {
-+		return $ref if (!/%f([0-9]{1,2})/);
-+		$_=$1;
-+		if ($1>=32) {
-+		    return $ref if ($2&1);
-+		    # re-encode for upper double register addressing
-+		    $_=($1|$1>>5)&31;
-+		}
-+	    }
-+	    return  sprintf ".word\t0x%08x !%s",
-+			    2<<30|0b110110<<19|$opf<<5|$args[0]<<14|$args[1]<<25,
-+			    $ref;
-+	}
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub emit_assembler {
-+    foreach (split("\n",$::code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	s/\b(f[a-z]+2[sd]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})\s*$/$1\t%f0,$2,$3/go;
-+
-+	s/\b(aes_[edk][^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*([%fx0-9]+),\s*(%f[0-9]{1,2})/
-+		&unaes_round($1,$2,$3,$4,$5)
-+	 /geo or
-+	s/\b(aes_kexpand[02])\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-+		&unaes_kexpand($1,$2,$3,$4)
-+	 /geo or
-+	s/\b(camellia_f)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*([%fx0-9]+),\s*(%f[0-9]{1,2})/
-+		&uncamellia_f($1,$2,$3,$4,$5)
-+	 /geo or
-+	s/\b(camellia_[^s]+)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-+		&uncamellia3($1,$2,$3,$4)
-+	 /geo or
-+	s/\b(des_\w+)\s+(%f[0-9]{1,2}),\s*([%fx0-9]+)(?:,\s*(%f[0-9]{1,2})(?:,\s*(%f[0-9]{1,2}))?)?/
-+		&undes($1,$2,$3,$4,$5)
-+	 /geo or
-+	s/\b(mov[ds]to\w+)\s+(%f[0-9]{1,2}),\s*(%[goli][0-7])/
-+		&unmovxtox($1,$2,$3)
-+	 /geo or
-+	s/\b(mov[xw]to[ds])\s+(%[goli][0-7]),\s*(%f[0-9]{1,2})/
-+		&unmovxtox($1,$2,$3)
-+	 /geo or
-+	s/\b([fb][^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-+		&unvis($1,$2,$3,$4)
-+	 /geo or
-+	s/\b(umulxhi|bmask|addxc[c]{0,2}|alignaddr[l]*)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+		&unvis3($1,$2,$3,$4)
-+	 /geo;
-+
-+	print $_,"\n";
-+    }
-+}
-+
-+1;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86_64-xlate.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86_64-xlate.pl
-new file mode 100755
-index 0000000..425cd29
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86_64-xlate.pl
-@@ -0,0 +1,1185 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# Ascetic x86_64 AT&T to MASM/NASM assembler translator by .
-+#
-+# Why AT&T to MASM and not vice versa? Several reasons. Because AT&T
-+# format is way easier to parse. Because it's simpler to "gear" from
-+# Unix ABI to Windows one [see cross-reference "card" at the end of
-+# file]. Because Linux targets were available first...
-+#
-+# In addition the script also "distills" code suitable for GNU
-+# assembler, so that it can be compiled with more rigid assemblers,
-+# such as Solaris /usr/ccs/bin/as.
-+#
-+# This translator is not designed to convert *arbitrary* assembler
-+# code from AT&T format to MASM one. It's designed to convert just
-+# enough to provide for dual-ABI OpenSSL modules development...
-+# There *are* limitations and you might have to modify your assembler
-+# code or this script to achieve the desired result...
-+#
-+# Currently recognized limitations:
-+#
-+# - can't use multiple ops per line;
-+#
-+# Dual-ABI styling rules.
-+#
-+# 1. Adhere to Unix register and stack layout [see cross-reference
-+#    ABI "card" at the end for explanation].
-+# 2. Forget about "red zone," stick to more traditional blended
-+#    stack frame allocation. If volatile storage is actually required
-+#    that is. If not, just leave the stack as is.
-+# 3. Functions tagged with ".type name,@function" get crafted with
-+#    unified Win64 prologue and epilogue automatically. If you want
-+#    to take care of ABI differences yourself, tag functions as
-+#    ".type name,@abi-omnipotent" instead.
-+# 4. To optimize the Win64 prologue you can specify number of input
-+#    arguments as ".type name,@function,N." Keep in mind that if N is
-+#    larger than 6, then you *have to* write "abi-omnipotent" code,
-+#    because >6 cases can't be addressed with unified prologue.
-+# 5. Name local labels as .L*, do *not* use dynamic labels such as 1:
-+#    (sorry about latter).
-+# 6. Don't use [or hand-code with .byte] "rep ret." "ret" mnemonic is
-+#    required to identify the spots, where to inject Win64 epilogue!
-+#    But on the pros, it's then prefixed with rep automatically:-)
-+# 7. Stick to explicit ip-relative addressing. If you have to use
-+#    GOTPCREL addressing, stick to mov symbol@GOTPCREL(%rip),%r??.
-+#    Both are recognized and translated to proper Win64 addressing
-+#    modes. To support legacy code a synthetic directive, .picmeup,
-+#    is implemented. It puts address of the *next* instruction into
-+#    target register, e.g.:
-+#
-+#		.picmeup	%rax
-+#		lea		.Label-.(%rax),%rax
-+#
-+# 8. In order to provide for structured exception handling unified
-+#    Win64 prologue copies %rsp value to %rax. For further details
-+#    see SEH paragraph at the end.
-+# 9. .init segment is allowed to contain calls to functions only.
-+# a. If function accepts more than 4 arguments *and* >4th argument
-+#    is declared as non 64-bit value, do clear its upper part.
-+
-+
-+use strict;
-+
-+my $flavour = shift;
-+my $output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+open STDOUT,">$output" || die "can't open $output: $!"
-+	if (defined($output));
-+
-+my $gas=1;	$gas=0 if ($output =~ /\.asm$/);
-+my $elf=1;	$elf=0 if (!$gas);
-+my $win64=0;
-+my $prefix="";
-+my $decor=".L";
-+
-+my $masmref=8 + 50727*2**-32;	# 8.00.50727 shipped with VS2005
-+my $masm=0;
-+my $PTR=" PTR";
-+
-+my $nasmref=2.03;
-+my $nasm=0;
-+
-+if    ($flavour eq "mingw64")	{ $gas=1; $elf=0; $win64=1;
-+				  $prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`;
-+				  $prefix =~ s|\R$||; # Better chomp
-+				}
-+elsif ($flavour eq "macosx")	{ $gas=1; $elf=0; $prefix="_"; $decor="L\$"; }
-+elsif ($flavour eq "masm")	{ $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; }
-+elsif ($flavour eq "nasm")	{ $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; }
-+elsif (!$gas)
-+{   if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i)
-+    {	$nasm = $1 + $2*0.01; $PTR="";  }
-+    elsif (`ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
-+    {	$masm = $1 + $2*2**-16 + $4*2**-32;   }
-+    die "no assembler found on %PATH" if (!($nasm || $masm));
-+    $win64=1;
-+    $elf=0;
-+    $decor="\$L\$";
-+}
-+
-+my $current_segment;
-+my $current_function;
-+my %globals;
-+
-+{ package opcode;	# pick up opcodes
-+    sub re {
-+	my	($class, $line) = @_;
-+	my	$self = {};
-+	my	$ret;
-+
-+	if ($$line =~ /^([a-z][a-z0-9]*)/i) {
-+	    bless $self,$class;
-+	    $self->{op} = $1;
-+	    $ret = $self;
-+	    $$line = substr($$line,@+[0]); $$line =~ s/^\s+//;
-+
-+	    undef $self->{sz};
-+	    if ($self->{op} =~ /^(movz)x?([bw]).*/) {	# movz is pain...
-+		$self->{op} = $1;
-+		$self->{sz} = $2;
-+	    } elsif ($self->{op} =~ /call|jmp/) {
-+		$self->{sz} = "";
-+	    } elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op|insrw)/) { # SSEn
-+		$self->{sz} = "";
-+	    } elsif ($self->{op} =~ /^v/) { # VEX
-+		$self->{sz} = "";
-+	    } elsif ($self->{op} =~ /mov[dq]/ && $$line =~ /%xmm/) {
-+		$self->{sz} = "";
-+	    } elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) {
-+		$self->{op} = $1;
-+		$self->{sz} = $2;
-+	    }
-+	}
-+	$ret;
-+    }
-+    sub size {
-+	my ($self, $sz) = @_;
-+	$self->{sz} = $sz if (defined($sz) && !defined($self->{sz}));
-+	$self->{sz};
-+    }
-+    sub out {
-+	my $self = shift;
-+	if ($gas) {
-+	    if ($self->{op} eq "movz") {	# movz is pain...
-+		sprintf "%s%s%s",$self->{op},$self->{sz},shift;
-+	    } elsif ($self->{op} =~ /^set/) { 
-+		"$self->{op}";
-+	    } elsif ($self->{op} eq "ret") {
-+		my $epilogue = "";
-+		if ($win64 && $current_function->{abi} eq "svr4") {
-+		    $epilogue = "movq	8(%rsp),%rdi\n\t" .
-+				"movq	16(%rsp),%rsi\n\t";
-+		}
-+	    	$epilogue . ".byte	0xf3,0xc3";
-+	    } elsif ($self->{op} eq "call" && !$elf && $current_segment eq ".init") {
-+		".p2align\t3\n\t.quad";
-+	    } else {
-+		"$self->{op}$self->{sz}";
-+	    }
-+	} else {
-+	    $self->{op} =~ s/^movz/movzx/;
-+	    if ($self->{op} eq "ret") {
-+		$self->{op} = "";
-+		if ($win64 && $current_function->{abi} eq "svr4") {
-+		    $self->{op} = "mov	rdi,QWORD$PTR\[8+rsp\]\t;WIN64 epilogue\n\t".
-+				  "mov	rsi,QWORD$PTR\[16+rsp\]\n\t";
-+	    	}
-+		$self->{op} .= "DB\t0F3h,0C3h\t\t;repret";
-+	    } elsif ($self->{op} =~ /^(pop|push)f/) {
-+		$self->{op} .= $self->{sz};
-+	    } elsif ($self->{op} eq "call" && $current_segment eq ".CRT\$XCU") {
-+		$self->{op} = "\tDQ";
-+	    } 
-+	    $self->{op};
-+	}
-+    }
-+    sub mnemonic {
-+	my ($self, $op) = @_;
-+	$self->{op}=$op if (defined($op));
-+	$self->{op};
-+    }
-+}
-+{ package const;	# pick up constants, which start with $
-+    sub re {
-+	my	($class, $line) = @_;
-+	my	$self = {};
-+	my	$ret;
-+
-+	if ($$line =~ /^\$([^,]+)/) {
-+	    bless $self, $class;
-+	    $self->{value} = $1;
-+	    $ret = $self;
-+	    $$line = substr($$line,@+[0]); $$line =~ s/^\s+//;
-+	}
-+	$ret;
-+    }
-+    sub out {
-+    	my $self = shift;
-+
-+	$self->{value} =~ s/\b(0b[0-1]+)/oct($1)/eig;
-+	if ($gas) {
-+	    # Solaris /usr/ccs/bin/as can't handle multiplications
-+	    # in $self->{value}
-+	    my $value = $self->{value};
-+	    no warnings;    # oct might complain about overflow, ignore here...
-+	    $value =~ s/(?{value} = $value;
-+	    }
-+	    sprintf "\$%s",$self->{value};
-+	} else {
-+	    $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig if ($masm);
-+	    sprintf "%s",$self->{value};
-+	}
-+    }
-+}
-+{ package ea;		# pick up effective addresses: expr(%reg,%reg,scale)
-+    sub re {
-+	my	($class, $line, $opcode) = @_;
-+	my	$self = {};
-+	my	$ret;
-+
-+	# optional * ----vvv--- appears in indirect jmp/call
-+	if ($$line =~ /^(\*?)([^\(,]*)\(([%\w,]+)\)/) {
-+	    bless $self, $class;
-+	    $self->{asterisk} = $1;
-+	    $self->{label} = $2;
-+	    ($self->{base},$self->{index},$self->{scale})=split(/,/,$3);
-+	    $self->{scale} = 1 if (!defined($self->{scale}));
-+	    $ret = $self;
-+	    $$line = substr($$line,@+[0]); $$line =~ s/^\s+//;
-+
-+	    if ($win64 && $self->{label} =~ s/\@GOTPCREL//) {
-+		die if ($opcode->mnemonic() ne "mov");
-+		$opcode->mnemonic("lea");
-+	    }
-+	    $self->{base}  =~ s/^%//;
-+	    $self->{index} =~ s/^%// if (defined($self->{index}));
-+	    $self->{opcode} = $opcode;
-+	}
-+	$ret;
-+    }
-+    sub size {}
-+    sub out {
-+	my ($self, $sz) = @_;
-+
-+	$self->{label} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
-+	$self->{label} =~ s/\.L/$decor/g;
-+
-+	# Silently convert all EAs to 64-bit. This is required for
-+	# elder GNU assembler and results in more compact code,
-+	# *but* most importantly AES module depends on this feature!
-+	$self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
-+	$self->{base}  =~ s/^[er](.?[0-9xpi])[d]?$/r\1/;
-+
-+	# Solaris /usr/ccs/bin/as can't handle multiplications
-+	# in $self->{label}...
-+	use integer;
-+	$self->{label} =~ s/(?{label} =~ s/\b([0-9]+\s*[\*\/\%]\s*[0-9]+)\b/eval($1)/eg;
-+
-+	# Some assemblers insist on signed presentation of 32-bit
-+	# offsets, but sign extension is a tricky business in perl...
-+	if ((1<<31)<<1) {
-+	    $self->{label} =~ s/\b([0-9]+)\b/$1<<32>>32/eg;
-+	} else {
-+	    $self->{label} =~ s/\b([0-9]+)\b/$1>>0/eg;
-+	}
-+
-+	if (!$self->{label} && $self->{index} && $self->{scale}==1 &&
-+	    $self->{base} =~ /(rbp|r13)/) {
-+		$self->{base} = $self->{index}; $self->{index} = $1;
-+	}
-+
-+	if ($gas) {
-+	    $self->{label} =~ s/^___imp_/__imp__/   if ($flavour eq "mingw64");
-+
-+	    if (defined($self->{index})) {
-+		sprintf "%s%s(%s,%%%s,%d)",$self->{asterisk},
-+					$self->{label},
-+					$self->{base}?"%$self->{base}":"",
-+					$self->{index},$self->{scale};
-+	    } else {
-+		sprintf "%s%s(%%%s)",	$self->{asterisk},$self->{label},$self->{base};
-+	    }
-+	} else {
-+	    my %szmap = (	b=>"BYTE$PTR",  w=>"WORD$PTR",
-+			l=>"DWORD$PTR", d=>"DWORD$PTR",
-+	    		q=>"QWORD$PTR", o=>"OWORD$PTR",
-+			x=>"XMMWORD$PTR", y=>"YMMWORD$PTR", z=>"ZMMWORD$PTR" );
-+
-+	    $self->{label} =~ s/\./\$/g;
-+	    $self->{label} =~ s/(?{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/);
-+
-+	    my $mnemonic = $self->{opcode}->mnemonic();
-+	    ($self->{asterisk})				&& ($sz="q") ||
-+	    ($mnemonic =~ /^v?mov([qd])$/)		&& ($sz=$1)  ||
-+	    ($mnemonic =~ /^v?pinsr([qdwb])$/)		&& ($sz=$1)  ||
-+	    ($mnemonic =~ /^vpbroadcast([qdwb])$/)	&& ($sz=$1)  ||
-+	    ($mnemonic =~ /^v(?!perm)[a-z]+[fi]128$/)	&& ($sz="x");
-+
-+	    if (defined($self->{index})) {
-+		sprintf "%s[%s%s*%d%s]",$szmap{$sz},
-+					$self->{label}?"$self->{label}+":"",
-+					$self->{index},$self->{scale},
-+					$self->{base}?"+$self->{base}":"";
-+	    } elsif ($self->{base} eq "rip") {
-+		sprintf "%s[%s]",$szmap{$sz},$self->{label};
-+	    } else {
-+		sprintf "%s[%s%s]",$szmap{$sz},
-+					$self->{label}?"$self->{label}+":"",
-+					$self->{base};
-+	    }
-+	}
-+    }
-+}
-+{ package register;	# pick up registers, which start with %.
-+    sub re {
-+	my	($class, $line, $opcode) = @_;
-+	my	$self = {};
-+	my	$ret;
-+
-+	# optional * ----vvv--- appears in indirect jmp/call
-+	if ($$line =~ /^(\*?)%(\w+)/) {
-+	    bless $self,$class;
-+	    $self->{asterisk} = $1;
-+	    $self->{value} = $2;
-+	    $opcode->size($self->size());
-+	    $ret = $self;
-+	    $$line = substr($$line,@+[0]); $$line =~ s/^\s+//;
-+	}
-+	$ret;
-+    }
-+    sub size {
-+	my	$self = shift;
-+	my	$ret;
-+
-+	if    ($self->{value} =~ /^r[\d]+b$/i)	{ $ret="b"; }
-+	elsif ($self->{value} =~ /^r[\d]+w$/i)	{ $ret="w"; }
-+	elsif ($self->{value} =~ /^r[\d]+d$/i)	{ $ret="l"; }
-+	elsif ($self->{value} =~ /^r[\w]+$/i)	{ $ret="q"; }
-+	elsif ($self->{value} =~ /^[a-d][hl]$/i){ $ret="b"; }
-+	elsif ($self->{value} =~ /^[\w]{2}l$/i)	{ $ret="b"; }
-+	elsif ($self->{value} =~ /^[\w]{2}$/i)	{ $ret="w"; }
-+	elsif ($self->{value} =~ /^e[a-z]{2}$/i){ $ret="l"; }
-+
-+	$ret;
-+    }
-+    sub out {
-+    	my $self = shift;
-+	if ($gas)	{ sprintf "%s%%%s",$self->{asterisk},$self->{value}; }
-+	else		{ $self->{value}; }
-+    }
-+}
-+{ package label;	# pick up labels, which end with :
-+    sub re {
-+	my	($class, $line) = @_;
-+	my	$self = {};
-+	my	$ret;
-+
-+	if ($$line =~ /(^[\.\w]+)\:/) {
-+	    bless $self,$class;
-+	    $self->{value} = $1;
-+	    $ret = $self;
-+	    $$line = substr($$line,@+[0]); $$line =~ s/^\s+//;
-+
-+	    $self->{value} =~ s/^\.L/$decor/;
-+	}
-+	$ret;
-+    }
-+    sub out {
-+	my $self = shift;
-+
-+	if ($gas) {
-+	    my $func = ($globals{$self->{value}} or $self->{value}) . ":";
-+	    if ($win64	&&
-+			$current_function->{name} eq $self->{value} &&
-+			$current_function->{abi} eq "svr4") {
-+		$func .= "\n";
-+		$func .= "	movq	%rdi,8(%rsp)\n";
-+		$func .= "	movq	%rsi,16(%rsp)\n";
-+		$func .= "	movq	%rsp,%rax\n";
-+		$func .= "${decor}SEH_begin_$current_function->{name}:\n";
-+		my $narg = $current_function->{narg};
-+		$narg=6 if (!defined($narg));
-+		$func .= "	movq	%rcx,%rdi\n" if ($narg>0);
-+		$func .= "	movq	%rdx,%rsi\n" if ($narg>1);
-+		$func .= "	movq	%r8,%rdx\n"  if ($narg>2);
-+		$func .= "	movq	%r9,%rcx\n"  if ($narg>3);
-+		$func .= "	movq	40(%rsp),%r8\n" if ($narg>4);
-+		$func .= "	movq	48(%rsp),%r9\n" if ($narg>5);
-+	    }
-+	    $func;
-+	} elsif ($self->{value} ne "$current_function->{name}") {
-+	    # Make all labels in masm global.
-+	    $self->{value} .= ":" if ($masm);
-+	    $self->{value} . ":";
-+	} elsif ($win64 && $current_function->{abi} eq "svr4") {
-+	    my $func =	"$current_function->{name}" .
-+			($nasm ? ":" : "\tPROC $current_function->{scope}") .
-+			"\n";
-+	    $func .= "	mov	QWORD$PTR\[8+rsp\],rdi\t;WIN64 prologue\n";
-+	    $func .= "	mov	QWORD$PTR\[16+rsp\],rsi\n";
-+	    $func .= "	mov	rax,rsp\n";
-+	    $func .= "${decor}SEH_begin_$current_function->{name}:";
-+	    $func .= ":" if ($masm);
-+	    $func .= "\n";
-+	    my $narg = $current_function->{narg};
-+	    $narg=6 if (!defined($narg));
-+	    $func .= "	mov	rdi,rcx\n" if ($narg>0);
-+	    $func .= "	mov	rsi,rdx\n" if ($narg>1);
-+	    $func .= "	mov	rdx,r8\n"  if ($narg>2);
-+	    $func .= "	mov	rcx,r9\n"  if ($narg>3);
-+	    $func .= "	mov	r8,QWORD$PTR\[40+rsp\]\n" if ($narg>4);
-+	    $func .= "	mov	r9,QWORD$PTR\[48+rsp\]\n" if ($narg>5);
-+	    $func .= "\n";
-+	} else {
-+	   "$current_function->{name}".
-+			($nasm ? ":" : "\tPROC $current_function->{scope}");
-+	}
-+    }
-+}
-+{ package expr;		# pick up expressions
-+    sub re {
-+	my	($class, $line, $opcode) = @_;
-+	my	$self = {};
-+	my	$ret;
-+
-+	if ($$line =~ /(^[^,]+)/) {
-+	    bless $self,$class;
-+	    $self->{value} = $1;
-+	    $ret = $self;
-+	    $$line = substr($$line,@+[0]); $$line =~ s/^\s+//;
-+
-+	    $self->{value} =~ s/\@PLT// if (!$elf);
-+	    $self->{value} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
-+	    $self->{value} =~ s/\.L/$decor/g;
-+	    $self->{opcode} = $opcode;
-+	}
-+	$ret;
-+    }
-+    sub out {
-+	my $self = shift;
-+	if ($nasm && $self->{opcode}->mnemonic()=~m/^j(?![re]cxz)/) {
-+	    "NEAR ".$self->{value};
-+	} else {
-+	    $self->{value};
-+	}
-+    }
-+}
-+{ package directive;	# pick up directives, which start with .
-+    sub re {
-+	my	($class, $line) = @_;
-+	my	$self = {};
-+	my	$ret;
-+	my	$dir;
-+	my	%opcode =	# lea 2f-1f(%rip),%dst; 1: nop; 2:
-+		(	"%rax"=>0x01058d48,	"%rcx"=>0x010d8d48,
-+			"%rdx"=>0x01158d48,	"%rbx"=>0x011d8d48,
-+			"%rsp"=>0x01258d48,	"%rbp"=>0x012d8d48,
-+			"%rsi"=>0x01358d48,	"%rdi"=>0x013d8d48,
-+			"%r8" =>0x01058d4c,	"%r9" =>0x010d8d4c,
-+			"%r10"=>0x01158d4c,	"%r11"=>0x011d8d4c,
-+			"%r12"=>0x01258d4c,	"%r13"=>0x012d8d4c,
-+			"%r14"=>0x01358d4c,	"%r15"=>0x013d8d4c	);
-+
-+	if ($$line =~ /^\s*(\.\w+)/) {
-+	    bless $self,$class;
-+	    $dir = $1;
-+	    $ret = $self;
-+	    undef $self->{value};
-+	    $$line = substr($$line,@+[0]); $$line =~ s/^\s+//;
-+
-+	    SWITCH: for ($dir) {
-+		/\.picmeup/ && do { if ($$line =~ /(%r[\w]+)/i) {
-+			    		$dir="\t.long";
-+					$$line=sprintf "0x%x,0x90000000",$opcode{$1};
-+				    }
-+				    last;
-+				  };
-+		/\.global|\.globl|\.extern/
-+			    && do { $globals{$$line} = $prefix . $$line;
-+				    $$line = $globals{$$line} if ($prefix);
-+				    last;
-+				  };
-+		/\.type/    && do { my ($sym,$type,$narg) = split(',',$$line);
-+				    if ($type eq "\@function") {
-+					undef $current_function;
-+					$current_function->{name} = $sym;
-+					$current_function->{abi}  = "svr4";
-+					$current_function->{narg} = $narg;
-+					$current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
-+				    } elsif ($type eq "\@abi-omnipotent") {
-+					undef $current_function;
-+					$current_function->{name} = $sym;
-+					$current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE";
-+				    }
-+				    $$line =~ s/\@abi\-omnipotent/\@function/;
-+				    $$line =~ s/\@function.*/\@function/;
-+				    last;
-+				  };
-+		/\.asciz/   && do { if ($$line =~ /^"(.*)"$/) {
-+					$dir  = ".byte";
-+					$$line = join(",",unpack("C*",$1),0);
-+				    }
-+				    last;
-+				  };
-+		/\.rva|\.long|\.quad/
-+			    && do { $$line =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei;
-+				    $$line =~ s/\.L/$decor/g;
-+				    last;
-+				  };
-+	    }
-+
-+	    if ($gas) {
-+		$self->{value} = $dir . "\t" . $$line;
-+
-+		if ($dir =~ /\.extern/) {
-+		    $self->{value} = ""; # swallow extern
-+		} elsif (!$elf && $dir =~ /\.type/) {
-+		    $self->{value} = "";
-+		    $self->{value} = ".def\t" . ($globals{$1} or $1) . ";\t" .
-+				(defined($globals{$1})?".scl 2;":".scl 3;") .
-+				"\t.type 32;\t.endef"
-+				if ($win64 && $$line =~ /([^,]+),\@function/);
-+		} elsif (!$elf && $dir =~ /\.size/) {
-+		    $self->{value} = "";
-+		    if (defined($current_function)) {
-+			$self->{value} .= "${decor}SEH_end_$current_function->{name}:"
-+				if ($win64 && $current_function->{abi} eq "svr4");
-+			undef $current_function;
-+		    }
-+		} elsif (!$elf && $dir =~ /\.align/) {
-+		    $self->{value} = ".p2align\t" . (log($$line)/log(2));
-+		} elsif ($dir eq ".section") {
-+		    $current_segment=$$line;
-+		    if (!$elf && $current_segment eq ".init") {
-+			if	($flavour eq "macosx")	{ $self->{value} = ".mod_init_func"; }
-+			elsif	($flavour eq "mingw64")	{ $self->{value} = ".section\t.ctors"; }
-+		    }
-+		} elsif ($dir =~ /\.(text|data)/) {
-+		    $current_segment=".$1";
-+		} elsif ($dir =~ /\.hidden/) {
-+		    if    ($flavour eq "macosx")  { $self->{value} = ".private_extern\t$prefix$$line"; }
-+		    elsif ($flavour eq "mingw64") { $self->{value} = ""; }
-+		} elsif ($dir =~ /\.comm/) {
-+		    $self->{value} = "$dir\t$prefix$$line";
-+		    $self->{value} =~ s|,([0-9]+),([0-9]+)$|",$1,".log($2)/log(2)|e if ($flavour eq "macosx");
-+		}
-+		$$line = "";
-+		return $self;
-+	    }
-+
-+	    # non-gas case or nasm/masm
-+	    SWITCH: for ($dir) {
-+		/\.text/    && do { my $v=undef;
-+				    if ($nasm) {
-+					$v="section	.text code align=64\n";
-+				    } else {
-+					$v="$current_segment\tENDS\n" if ($current_segment);
-+					$current_segment = ".text\$";
-+					$v.="$current_segment\tSEGMENT ";
-+					$v.=$masm>=$masmref ? "ALIGN(256)" : "PAGE";
-+					$v.=" 'CODE'";
-+				    }
-+				    $self->{value} = $v;
-+				    last;
-+				  };
-+		/\.data/    && do { my $v=undef;
-+				    if ($nasm) {
-+					$v="section	.data data align=8\n";
-+				    } else {
-+					$v="$current_segment\tENDS\n" if ($current_segment);
-+					$current_segment = "_DATA";
-+					$v.="$current_segment\tSEGMENT";
-+				    }
-+				    $self->{value} = $v;
-+				    last;
-+				  };
-+		/\.section/ && do { my $v=undef;
-+				    $$line =~ s/([^,]*).*/$1/;
-+				    $$line = ".CRT\$XCU" if ($$line eq ".init");
-+				    if ($nasm) {
-+					$v="section	$$line";
-+					if ($$line=~/\.([px])data/) {
-+					    $v.=" rdata align=";
-+					    $v.=$1 eq "p"? 4 : 8;
-+					} elsif ($$line=~/\.CRT\$/i) {
-+					    $v.=" rdata align=8";
-+					}
-+				    } else {
-+					$v="$current_segment\tENDS\n" if ($current_segment);
-+					$v.="$$line\tSEGMENT";
-+					if ($$line=~/\.([px])data/) {
-+					    $v.=" READONLY";
-+					    $v.=" ALIGN(".($1 eq "p" ? 4 : 8).")" if ($masm>=$masmref);
-+					} elsif ($$line=~/\.CRT\$/i) {
-+					    $v.=" READONLY ";
-+					    $v.=$masm>=$masmref ? "ALIGN(8)" : "DWORD";
-+					}
-+				    }
-+				    $current_segment = $$line;
-+				    $self->{value} = $v;
-+				    last;
-+				  };
-+		/\.extern/  && do { $self->{value}  = "EXTERN\t".$$line;
-+				    $self->{value} .= ":NEAR" if ($masm);
-+				    last;
-+				  };
-+		/\.globl|.global/
-+			    && do { $self->{value}  = $masm?"PUBLIC":"global";
-+				    $self->{value} .= "\t".$$line;
-+				    last;
-+				  };
-+		/\.size/    && do { if (defined($current_function)) {
-+					undef $self->{value};
-+					if ($current_function->{abi} eq "svr4") {
-+					    $self->{value}="${decor}SEH_end_$current_function->{name}:";
-+					    $self->{value}.=":\n" if($masm);
-+					}
-+					$self->{value}.="$current_function->{name}\tENDP" if($masm && $current_function->{name});
-+					undef $current_function;
-+				    }
-+				    last;
-+				  };
-+		/\.align/   && do { my $max = ($masm && $masm>=$masmref) ? 256 : 4096;
-+				    $self->{value} = "ALIGN\t".($$line>$max?$max:$$line);
-+				    last;
-+				  };
-+		/\.(value|long|rva|quad)/
-+			    && do { my $sz  = substr($1,0,1);
-+				    my @arr = split(/,\s*/,$$line);
-+				    my $last = pop(@arr);
-+				    my $conv = sub  {	my $var=shift;
-+							$var=~s/^(0b[0-1]+)/oct($1)/eig;
-+							$var=~s/^0x([0-9a-f]+)/0$1h/ig if ($masm);
-+							if ($sz eq "D" && ($current_segment=~/.[px]data/ || $dir eq ".rva"))
-+							{ $var=~s/([_a-z\$\@][_a-z0-9\$\@]*)/$nasm?"$1 wrt ..imagebase":"imagerel $1"/egi; }
-+							$var;
-+						    };  
-+
-+				    $sz =~ tr/bvlrq/BWDDQ/;
-+				    $self->{value} = "\tD$sz\t";
-+				    for (@arr) { $self->{value} .= &$conv($_).","; }
-+				    $self->{value} .= &$conv($last);
-+				    last;
-+				  };
-+		/\.byte/    && do { my @str=split(/,\s*/,$$line);
-+				    map(s/(0b[0-1]+)/oct($1)/eig,@str);
-+				    map(s/0x([0-9a-f]+)/0$1h/ig,@str) if ($masm);	
-+				    while ($#str>15) {
-+					$self->{value}.="DB\t"
-+						.join(",",@str[0..15])."\n";
-+					foreach (0..15) { shift @str; }
-+				    }
-+				    $self->{value}.="DB\t"
-+						.join(",",@str) if (@str);
-+				    last;
-+				  };
-+		/\.comm/    && do { my @str=split(/,\s*/,$$line);
-+				    my $v=undef;
-+				    if ($nasm) {
-+					$v.="common	$prefix@str[0] @str[1]";
-+				    } else {
-+					$v="$current_segment\tENDS\n" if ($current_segment);
-+					$current_segment = "_DATA";
-+					$v.="$current_segment\tSEGMENT\n";
-+					$v.="COMM	@str[0]:DWORD:".@str[1]/4;
-+				    }
-+				    $self->{value} = $v;
-+				    last;
-+				  };
-+	    }
-+	    $$line = "";
-+	}
-+
-+	$ret;
-+    }
-+    sub out {
-+	my $self = shift;
-+	$self->{value};
-+    }
-+}
-+
-+sub rex {
-+ my $opcode=shift;
-+ my ($dst,$src,$rex)=@_;
-+
-+   $rex|=0x04 if($dst>=8);
-+   $rex|=0x01 if($src>=8);
-+   push @$opcode,($rex|0x40) if ($rex);
-+}
-+
-+# Upon initial x86_64 introduction SSE>2 extensions were not introduced
-+# yet. In order not to be bothered by tracing exact assembler versions,
-+# but at the same time to provide a bare security minimum of AES-NI, we
-+# hard-code some instructions. Extensions past AES-NI on the other hand
-+# are traced by examining assembler version in individual perlasm
-+# modules...
-+
-+my %regrm = (	"%eax"=>0, "%ecx"=>1, "%edx"=>2, "%ebx"=>3,
-+		"%esp"=>4, "%ebp"=>5, "%esi"=>6, "%edi"=>7	);
-+
-+my $movq = sub {	# elderly gas can't handle inter-register movq
-+  my $arg = shift;
-+  my @opcode=(0x66);
-+    if ($arg =~ /%xmm([0-9]+),\s*%r(\w+)/) {
-+	my ($src,$dst)=($1,$2);
-+	if ($dst !~ /[0-9]+/)	{ $dst = $regrm{"%e$dst"}; }
-+	rex(\@opcode,$src,$dst,0x8);
-+	push @opcode,0x0f,0x7e;
-+	push @opcode,0xc0|(($src&7)<<3)|($dst&7);	# ModR/M
-+	@opcode;
-+    } elsif ($arg =~ /%r(\w+),\s*%xmm([0-9]+)/) {
-+	my ($src,$dst)=($2,$1);
-+	if ($dst !~ /[0-9]+/)	{ $dst = $regrm{"%e$dst"}; }
-+	rex(\@opcode,$src,$dst,0x8);
-+	push @opcode,0x0f,0x6e;
-+	push @opcode,0xc0|(($src&7)<<3)|($dst&7);	# ModR/M
-+	@opcode;
-+    } else {
-+	();
-+    }
-+};
-+
-+my $pextrd = sub {
-+    if (shift =~ /\$([0-9]+),\s*%xmm([0-9]+),\s*(%\w+)/) {
-+      my @opcode=(0x66);
-+	my $imm=$1;
-+	my $src=$2;
-+	my $dst=$3;
-+	if ($dst =~ /%r([0-9]+)d/)	{ $dst = $1; }
-+	elsif ($dst =~ /%e/)		{ $dst = $regrm{$dst}; }
-+	rex(\@opcode,$src,$dst);
-+	push @opcode,0x0f,0x3a,0x16;
-+	push @opcode,0xc0|(($src&7)<<3)|($dst&7);	# ModR/M
-+	push @opcode,$imm;
-+	@opcode;
-+    } else {
-+	();
-+    }
-+};
-+
-+my $pinsrd = sub {
-+    if (shift =~ /\$([0-9]+),\s*(%\w+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x66);
-+	my $imm=$1;
-+	my $src=$2;
-+	my $dst=$3;
-+	if ($src =~ /%r([0-9]+)/)	{ $src = $1; }
-+	elsif ($src =~ /%e/)		{ $src = $regrm{$src}; }
-+	rex(\@opcode,$dst,$src);
-+	push @opcode,0x0f,0x3a,0x22;
-+	push @opcode,0xc0|(($dst&7)<<3)|($src&7);	# ModR/M
-+	push @opcode,$imm;
-+	@opcode;
-+    } else {
-+	();
-+    }
-+};
-+
-+my $pshufb = sub {
-+    if (shift =~ /%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x66);
-+	rex(\@opcode,$2,$1);
-+	push @opcode,0x0f,0x38,0x00;
-+	push @opcode,0xc0|($1&7)|(($2&7)<<3);		# ModR/M
-+	@opcode;
-+    } else {
-+	();
-+    }
-+};
-+
-+my $palignr = sub {
-+    if (shift =~ /\$([0-9]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x66);
-+	rex(\@opcode,$3,$2);
-+	push @opcode,0x0f,0x3a,0x0f;
-+	push @opcode,0xc0|($2&7)|(($3&7)<<3);		# ModR/M
-+	push @opcode,$1;
-+	@opcode;
-+    } else {
-+	();
-+    }
-+};
-+
-+my $pclmulqdq = sub {
-+    if (shift =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x66);
-+	rex(\@opcode,$3,$2);
-+	push @opcode,0x0f,0x3a,0x44;
-+	push @opcode,0xc0|($2&7)|(($3&7)<<3);		# ModR/M
-+	my $c=$1;
-+	push @opcode,$c=~/^0/?oct($c):$c;
-+	@opcode;
-+    } else {
-+	();
-+    }
-+};
-+
-+my $rdrand = sub {
-+    if (shift =~ /%[er](\w+)/) {
-+      my @opcode=();
-+      my $dst=$1;
-+	if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
-+	rex(\@opcode,0,$dst,8);
-+	push @opcode,0x0f,0xc7,0xf0|($dst&7);
-+	@opcode;
-+    } else {
-+	();
-+    }
-+};
-+
-+my $rdseed = sub {
-+    if (shift =~ /%[er](\w+)/) {
-+      my @opcode=();
-+      my $dst=$1;
-+	if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
-+	rex(\@opcode,0,$dst,8);
-+	push @opcode,0x0f,0xc7,0xf8|($dst&7);
-+	@opcode;
-+    } else {
-+	();
-+    }
-+};
-+
-+sub rxb {
-+ my $opcode=shift;
-+ my ($dst,$src1,$src2,$rxb)=@_;
-+
-+   $rxb|=0x7<<5;
-+   $rxb&=~(0x04<<5) if($dst>=8);
-+   $rxb&=~(0x01<<5) if($src1>=8);
-+   $rxb&=~(0x02<<5) if($src2>=8);
-+   push @$opcode,$rxb;
-+}
-+
-+my $vprotd = sub {
-+    if (shift =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x8f);
-+	rxb(\@opcode,$3,$2,-1,0x08);
-+	push @opcode,0x78,0xc2;
-+	push @opcode,0xc0|($2&7)|(($3&7)<<3);		# ModR/M
-+	my $c=$1;
-+	push @opcode,$c=~/^0/?oct($c):$c;
-+	@opcode;
-+    } else {
-+	();
-+    }
-+};
-+
-+my $vprotq = sub {
-+    if (shift =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x8f);
-+	rxb(\@opcode,$3,$2,-1,0x08);
-+	push @opcode,0x78,0xc3;
-+	push @opcode,0xc0|($2&7)|(($3&7)<<3);		# ModR/M
-+	my $c=$1;
-+	push @opcode,$c=~/^0/?oct($c):$c;
-+	@opcode;
-+    } else {
-+	();
-+    }
-+};
-+
-+my $endbranch = sub {
-+    (0xf3,0x0f,0x1e,0xfa);
-+};
-+
-+if ($nasm) {
-+    print <<___;
-+default	rel
-+%define XMMWORD
-+%define YMMWORD
-+%define ZMMWORD
-+___
-+} elsif ($masm) {
-+    print <<___;
-+OPTION	DOTNAME
-+___
-+}
-+while(defined(my $line=<>)) {
-+
-+    $line =~ s|\R$||;           # Better chomp
-+
-+    $line =~ s|[#!].*$||;	# get rid of asm-style comments...
-+    $line =~ s|/\*.*\*/||;	# ... and C-style comments...
-+    $line =~ s|^\s+||;		# ... and skip white spaces in beginning
-+    $line =~ s|\s+$||;		# ... and at the end
-+
-+    if (my $label=label->re(\$line))	{ print $label->out(); }
-+
-+    if (my $directive=directive->re(\$line)) {
-+	printf "%s",$directive->out();
-+    } elsif (my $opcode=opcode->re(\$line)) {
-+	my $asm = eval("\$".$opcode->mnemonic());
-+	
-+	if ((ref($asm) eq 'CODE') && scalar(my @bytes=&$asm($line))) {
-+	    print $gas?".byte\t":"DB\t",join(',',@bytes),"\n";
-+	    next;
-+	}
-+
-+	my @args;
-+	ARGUMENT: while (1) {
-+	    my $arg;
-+
-+	    ($arg=register->re(\$line, $opcode))||
-+	    ($arg=const->re(\$line))		||
-+	    ($arg=ea->re(\$line, $opcode))	||
-+	    ($arg=expr->re(\$line, $opcode))	||
-+	    last ARGUMENT;
-+
-+	    push @args,$arg;
-+
-+	    last ARGUMENT if ($line !~ /^,/);
-+
-+	    $line =~ s/^,\s*//;
-+	} # ARGUMENT:
-+
-+	if ($#args>=0) {
-+	    my $insn;
-+	    my $sz=$opcode->size();
-+
-+	    if ($gas) {
-+		$insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
-+		@args = map($_->out($sz),@args);
-+		printf "\t%s\t%s",$insn,join(",",@args);
-+	    } else {
-+		$insn = $opcode->out();
-+		foreach (@args) {
-+		    my $arg = $_->out();
-+		    # $insn.=$sz compensates for movq, pinsrw, ...
-+		    if ($arg =~ /^xmm[0-9]+$/) { $insn.=$sz; $sz="x" if(!$sz); last; }
-+		    if ($arg =~ /^ymm[0-9]+$/) { $insn.=$sz; $sz="y" if(!$sz); last; }
-+		    if ($arg =~ /^zmm[0-9]+$/) { $insn.=$sz; $sz="z" if(!$sz); last; }
-+		    if ($arg =~ /^mm[0-9]+$/)  { $insn.=$sz; $sz="q" if(!$sz); last; }
-+		}
-+		@args = reverse(@args);
-+		undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
-+		printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
-+	    }
-+	} else {
-+	    printf "\t%s",$opcode->out();
-+	}
-+    }
-+
-+    print $line,"\n";
-+}
-+
-+print "\n$current_segment\tENDS\n"	if ($current_segment && $masm);
-+print "END\n"				if ($masm);
-+
-+close STDOUT;
-+
-+#################################################
-+# Cross-reference x86_64 ABI "card"
-+#
-+# 		Unix		Win64
-+# %rax		*		*
-+# %rbx		-		-
-+# %rcx		#4		#1
-+# %rdx		#3		#2
-+# %rsi		#2		-
-+# %rdi		#1		-
-+# %rbp		-		-
-+# %rsp		-		-
-+# %r8		#5		#3
-+# %r9		#6		#4
-+# %r10		*		*
-+# %r11		*		*
-+# %r12		-		-
-+# %r13		-		-
-+# %r14		-		-
-+# %r15		-		-
-+# 
-+# (*)	volatile register
-+# (-)	preserved by callee
-+# (#)	Nth argument, volatile
-+#
-+# In Unix terms top of stack is argument transfer area for arguments
-+# which could not be accommodated in registers. Or in other words 7th
-+# [integer] argument resides at 8(%rsp) upon function entry point.
-+# 128 bytes above %rsp constitute a "red zone" which is not touched
-+# by signal handlers and can be used as temporal storage without
-+# allocating a frame.
-+#
-+# In Win64 terms N*8 bytes on top of stack is argument transfer area,
-+# which belongs to/can be overwritten by callee. N is the number of
-+# arguments passed to callee, *but* not less than 4! This means that
-+# upon function entry point 5th argument resides at 40(%rsp), as well
-+# as that 32 bytes from 8(%rsp) can always be used as temporal
-+# storage [without allocating a frame]. One can actually argue that
-+# one can assume a "red zone" above stack pointer under Win64 as well.
-+# Point is that at apparently no occasion Windows kernel would alter
-+# the area above user stack pointer in true asynchronous manner...
-+#
-+# All the above means that if assembler programmer adheres to Unix
-+# register and stack layout, but disregards the "red zone" existence,
-+# it's possible to use following prologue and epilogue to "gear" from
-+# Unix to Win64 ABI in leaf functions with not more than 6 arguments.
-+#
-+# omnipotent_function:
-+# ifdef WIN64
-+#	movq	%rdi,8(%rsp)
-+#	movq	%rsi,16(%rsp)
-+#	movq	%rcx,%rdi	; if 1st argument is actually present
-+#	movq	%rdx,%rsi	; if 2nd argument is actually ...
-+#	movq	%r8,%rdx	; if 3rd argument is ...
-+#	movq	%r9,%rcx	; if 4th argument ...
-+#	movq	40(%rsp),%r8	; if 5th ...
-+#	movq	48(%rsp),%r9	; if 6th ...
-+# endif
-+#	...
-+# ifdef WIN64
-+#	movq	8(%rsp),%rdi
-+#	movq	16(%rsp),%rsi
-+# endif
-+#	ret
-+#
-+#################################################
-+# Win64 SEH, Structured Exception Handling.
-+#
-+# Unlike on Unix systems(*) lack of Win64 stack unwinding information
-+# has undesired side-effect at run-time: if an exception is raised in
-+# assembler subroutine such as those in question (basically we're
-+# referring to segmentation violations caused by malformed input
-+# parameters), the application is briskly terminated without invoking
-+# any exception handlers, most notably without generating memory dump
-+# or any user notification whatsoever. This poses a problem. It's
-+# possible to address it by registering custom language-specific
-+# handler that would restore processor context to the state at
-+# subroutine entry point and return "exception is not handled, keep
-+# unwinding" code. Writing such handler can be a challenge... But it's
-+# doable, though requires certain coding convention. Consider following
-+# snippet:
-+#
-+# .type	function,@function
-+# function:
-+#	movq	%rsp,%rax	# copy rsp to volatile register
-+#	pushq	%r15		# save non-volatile registers
-+#	pushq	%rbx
-+#	pushq	%rbp
-+#	movq	%rsp,%r11
-+#	subq	%rdi,%r11	# prepare [variable] stack frame
-+#	andq	$-64,%r11
-+#	movq	%rax,0(%r11)	# check for exceptions
-+#	movq	%r11,%rsp	# allocate [variable] stack frame
-+#	movq	%rax,0(%rsp)	# save original rsp value
-+# magic_point:
-+#	...
-+#	movq	0(%rsp),%rcx	# pull original rsp value
-+#	movq	-24(%rcx),%rbp	# restore non-volatile registers
-+#	movq	-16(%rcx),%rbx
-+#	movq	-8(%rcx),%r15
-+#	movq	%rcx,%rsp	# restore original rsp
-+#	ret
-+# .size function,.-function
-+#
-+# The key is that up to magic_point copy of original rsp value remains
-+# in chosen volatile register and no non-volatile register, except for
-+# rsp, is modified. While past magic_point rsp remains constant till
-+# the very end of the function. In this case custom language-specific
-+# exception handler would look like this:
-+#
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+# {	ULONG64 *rsp = (ULONG64 *)context->Rax;
-+#	if (context->Rip >= magic_point)
-+#	{   rsp = ((ULONG64 **)context->Rsp)[0];
-+#	    context->Rbp = rsp[-3];
-+#	    context->Rbx = rsp[-2];
-+#	    context->R15 = rsp[-1];
-+#	}
-+#	context->Rsp = (ULONG64)rsp;
-+#	context->Rdi = rsp[1];
-+#	context->Rsi = rsp[2];
-+#
-+#	memcpy (disp->ContextRecord,context,sizeof(CONTEXT));
-+#	RtlVirtualUnwind(UNW_FLAG_NHANDLER,disp->ImageBase,
-+#		dips->ControlPc,disp->FunctionEntry,disp->ContextRecord,
-+#		&disp->HandlerData,&disp->EstablisherFrame,NULL);
-+#	return ExceptionContinueSearch;
-+# }
-+#
-+# It's appropriate to implement this handler in assembler, directly in
-+# function's module. In order to do that one has to know members'
-+# offsets in CONTEXT and DISPATCHER_CONTEXT structures and some constant
-+# values. Here they are:
-+#
-+#	CONTEXT.Rax				120
-+#	CONTEXT.Rcx				128
-+#	CONTEXT.Rdx				136
-+#	CONTEXT.Rbx				144
-+#	CONTEXT.Rsp				152
-+#	CONTEXT.Rbp				160
-+#	CONTEXT.Rsi				168
-+#	CONTEXT.Rdi				176
-+#	CONTEXT.R8				184
-+#	CONTEXT.R9				192
-+#	CONTEXT.R10				200
-+#	CONTEXT.R11				208
-+#	CONTEXT.R12				216
-+#	CONTEXT.R13				224
-+#	CONTEXT.R14				232
-+#	CONTEXT.R15				240
-+#	CONTEXT.Rip				248
-+#	CONTEXT.Xmm6				512
-+#	sizeof(CONTEXT)				1232
-+#	DISPATCHER_CONTEXT.ControlPc		0
-+#	DISPATCHER_CONTEXT.ImageBase		8
-+#	DISPATCHER_CONTEXT.FunctionEntry	16
-+#	DISPATCHER_CONTEXT.EstablisherFrame	24
-+#	DISPATCHER_CONTEXT.TargetIp		32
-+#	DISPATCHER_CONTEXT.ContextRecord	40
-+#	DISPATCHER_CONTEXT.LanguageHandler	48
-+#	DISPATCHER_CONTEXT.HandlerData		56
-+#	UNW_FLAG_NHANDLER			0
-+#	ExceptionContinueSearch			1
-+#
-+# In order to tie the handler to the function one has to compose
-+# couple of structures: one for .xdata segment and one for .pdata.
-+#
-+# UNWIND_INFO structure for .xdata segment would be
-+#
-+# function_unwind_info:
-+#	.byte	9,0,0,0
-+#	.rva	handler
-+#
-+# This structure designates exception handler for a function with
-+# zero-length prologue, no stack frame or frame register.
-+#
-+# To facilitate composing of .pdata structures, auto-generated "gear"
-+# prologue copies rsp value to rax and denotes next instruction with
-+# .LSEH_begin_{function_name} label. This essentially defines the SEH
-+# styling rule mentioned in the beginning. Position of this label is
-+# chosen in such manner that possible exceptions raised in the "gear"
-+# prologue would be accounted to caller and unwound from latter's frame.
-+# End of function is marked with respective .LSEH_end_{function_name}
-+# label. To summarize, .pdata segment would contain
-+#
-+#	.rva	.LSEH_begin_function
-+#	.rva	.LSEH_end_function
-+#	.rva	function_unwind_info
-+#
-+# Reference to function_unwind_info from .xdata segment is the anchor.
-+# In case you wonder why references are 32-bit .rvas and not 64-bit
-+# .quads. References put into these two segments are required to be
-+# *relative* to the base address of the current binary module, a.k.a.
-+# image base. No Win64 module, be it .exe or .dll, can be larger than
-+# 2GB and thus such relative references can be and are accommodated in
-+# 32 bits.
-+#
-+# Having reviewed the example function code, one can argue that "movq
-+# %rsp,%rax" above is redundant. It is not! Keep in mind that on Unix
-+# rax would contain an undefined value. If this "offends" you, use
-+# another register and refrain from modifying rax till magic_point is
-+# reached, i.e. as if it was a non-volatile register. If more registers
-+# are required prior [variable] frame setup is completed, note that
-+# nobody says that you can have only one "magic point." You can
-+# "liberate" non-volatile registers by denoting last stack off-load
-+# instruction and reflecting it in finer grade unwind logic in handler.
-+# After all, isn't it why it's called *language-specific* handler...
-+#
-+# Attentive reader can notice that exceptions would be mishandled in
-+# auto-generated "gear" epilogue. Well, exception effectively can't
-+# occur there, because if memory area used by it was subject to
-+# segmentation violation, then it would be raised upon call to the
-+# function (and as already mentioned be accounted to caller, which is
-+# not a problem). If you're still not comfortable, then define tail
-+# "magic point" just prior ret instruction and have handler treat it...
-+#
-+# (*)	Note that we're talking about run-time, not debug-time. Lack of
-+#	unwind information makes debugging hard on both Windows and
-+#	Unix. "Unlike" referes to the fact that on Unix signal handler
-+#	will always be invoked, core dumped and appropriate exit code
-+#	returned to parent (for user notification).
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86asm.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86asm.pl
-new file mode 100644
-index 0000000..1ff46c9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86asm.pl
-@@ -0,0 +1,310 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# require 'x86asm.pl';
-+# &asm_init(,"des-586.pl"[,$i386only]);
-+# &function_begin("foo");
-+# ...
-+# &function_end("foo");
-+# &asm_finish
-+
-+$out=();
-+$i386=0;
-+
-+# AUTOLOAD is this context has quite unpleasant side effect, namely
-+# that typos in function calls effectively go to assembler output,
-+# but on the pros side we don't have to implement one subroutine per
-+# each opcode...
-+sub ::AUTOLOAD
-+{ my $opcode = $AUTOLOAD;
-+
-+    die "more than 4 arguments passed to $opcode" if ($#_>3);
-+
-+    $opcode =~ s/.*:://;
-+    if    ($opcode =~ /^push/) { $stack+=4; }
-+    elsif ($opcode =~ /^pop/)  { $stack-=4; }
-+
-+    &generic($opcode,@_) or die "undefined subroutine \&$AUTOLOAD";
-+}
-+
-+sub ::emit
-+{ my $opcode=shift;
-+
-+    if ($#_==-1)    { push(@out,"\t$opcode\n");				}
-+    else            { push(@out,"\t$opcode\t".join(',',@_)."\n");	}
-+}
-+
-+sub ::LB
-+{   $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'low byte'";
-+  $1."l";
-+}
-+sub ::HB
-+{   $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'high byte'";
-+  $1."h";
-+}
-+sub ::stack_push{ my $num=$_[0]*4; $stack+=$num; &sub("esp",$num);	}
-+sub ::stack_pop	{ my $num=$_[0]*4; $stack-=$num; &add("esp",$num);	}
-+sub ::blindpop	{ &pop($_[0]); $stack+=4;				}
-+sub ::wparam	{ &DWP($stack+4*$_[0],"esp");				}
-+sub ::swtmp	{ &DWP(4*$_[0],"esp");					}
-+
-+sub ::bswap
-+{   if ($i386)	# emulate bswap for i386
-+    {	&comment("bswap @_");
-+	&xchg(&HB(@_),&LB(@_));
-+	&ror (@_,16);
-+	&xchg(&HB(@_),&LB(@_));
-+    }
-+    else
-+    {	&generic("bswap",@_);	}
-+}
-+# These are made-up opcodes introduced over the years essentially
-+# by ignorance, just alias them to real ones...
-+sub ::movb	{ &mov(@_);	}
-+sub ::xorb	{ &xor(@_);	}
-+sub ::rotl	{ &rol(@_);	}
-+sub ::rotr	{ &ror(@_);	}
-+sub ::exch	{ &xchg(@_);	}
-+sub ::halt	{ &hlt;		}
-+sub ::movz	{ &movzx(@_);	}
-+sub ::pushf	{ &pushfd;	}
-+sub ::popf	{ &popfd;	}
-+
-+# 3 argument instructions
-+sub ::movq
-+{ my($p1,$p2,$optimize)=@_;
-+
-+    if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
-+    # movq between mmx registers can sink Intel CPUs
-+    {	&::pshufw($p1,$p2,0xe4);		}
-+    else
-+    {	&::generic("movq",@_);			}
-+}
-+
-+# SSE>2 instructions
-+my %regrm = (	"eax"=>0, "ecx"=>1, "edx"=>2, "ebx"=>3,
-+		"esp"=>4, "ebp"=>5, "esi"=>6, "edi"=>7	);
-+sub ::pextrd
-+{ my($dst,$src,$imm)=@_;
-+    if ("$dst:$src" =~ /(e[a-dsd][ixp]):xmm([0-7])/)
-+    {	&::data_byte(0x66,0x0f,0x3a,0x16,0xc0|($2<<3)|$regrm{$1},$imm);	}
-+    else
-+    {	&::generic("pextrd",@_);		}
-+}
-+
-+sub ::pinsrd
-+{ my($dst,$src,$imm)=@_;
-+    if ("$dst:$src" =~ /xmm([0-7]):(e[a-dsd][ixp])/)
-+    {	&::data_byte(0x66,0x0f,0x3a,0x22,0xc0|($1<<3)|$regrm{$2},$imm);	}
-+    else
-+    {	&::generic("pinsrd",@_);		}
-+}
-+
-+sub ::pshufb
-+{ my($dst,$src)=@_;
-+    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
-+    {	&data_byte(0x66,0x0f,0x38,0x00,0xc0|($1<<3)|$2);	}
-+    else
-+    {	&::generic("pshufb",@_);		}
-+}
-+
-+sub ::palignr
-+{ my($dst,$src,$imm)=@_;
-+    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
-+    {	&::data_byte(0x66,0x0f,0x3a,0x0f,0xc0|($1<<3)|$2,$imm);	}
-+    else
-+    {	&::generic("palignr",@_);		}
-+}
-+
-+sub ::pclmulqdq
-+{ my($dst,$src,$imm)=@_;
-+    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
-+    {	&::data_byte(0x66,0x0f,0x3a,0x44,0xc0|($1<<3)|$2,$imm);	}
-+    else
-+    {	&::generic("pclmulqdq",@_);		}
-+}
-+
-+sub ::rdrand
-+{ my ($dst)=@_;
-+    if ($dst =~ /(e[a-dsd][ixp])/)
-+    {	&::data_byte(0x0f,0xc7,0xf0|$regrm{$dst});	}
-+    else
-+    {	&::generic("rdrand",@_);	}
-+}
-+
-+sub ::rdseed
-+{ my ($dst)=@_;
-+    if ($dst =~ /(e[a-dsd][ixp])/)
-+    {	&::data_byte(0x0f,0xc7,0xf8|$regrm{$dst});	}
-+    else
-+    {	&::generic("rdrand",@_);	}
-+}
-+
-+sub rxb {
-+ local *opcode=shift;
-+ my ($dst,$src1,$src2,$rxb)=@_;
-+
-+   $rxb|=0x7<<5;
-+   $rxb&=~(0x04<<5) if($dst>=8);
-+   $rxb&=~(0x01<<5) if($src1>=8);
-+   $rxb&=~(0x02<<5) if($src2>=8);
-+   push @opcode,$rxb;
-+}
-+
-+sub ::vprotd
-+{ my $args=join(',',@_);
-+    if ($args =~ /xmm([0-7]),xmm([0-7]),([x0-9a-f]+)/)
-+    { my @opcode=(0x8f);
-+	rxb(\@opcode,$1,$2,-1,0x08);
-+	push @opcode,0x78,0xc2;
-+	push @opcode,0xc0|($2&7)|(($1&7)<<3);		# ModR/M
-+	my $c=$3;
-+	push @opcode,$c=~/^0/?oct($c):$c;
-+	&::data_byte(@opcode);
-+    }
-+    else
-+    {	&::generic("vprotd",@_);	}
-+}
-+
-+sub ::endbranch
-+{
-+    &::data_byte(0xf3,0x0f,0x1e,0xfb);
-+}
-+
-+# label management
-+$lbdecor="L";		# local label decoration, set by package
-+$label="000";
-+
-+sub ::islabel		# see is argument is a known label
-+{ my $i;
-+    foreach $i (values %label) { return $i if ($i eq $_[0]); }
-+  $label{$_[0]};	# can be undef
-+}
-+
-+sub ::label		# instantiate a function-scope label
-+{   if (!defined($label{$_[0]}))
-+    {	$label{$_[0]}="${lbdecor}${label}${_[0]}"; $label++;   }
-+  $label{$_[0]};
-+}
-+
-+sub ::LABEL		# instantiate a file-scope label
-+{   $label{$_[0]}=$_[1] if (!defined($label{$_[0]}));
-+  $label{$_[0]};
-+}
-+
-+sub ::static_label	{ &::LABEL($_[0],$lbdecor.$_[0]); }
-+
-+sub ::set_label_B	{ push(@out,"@_:\n"); }
-+sub ::set_label
-+{ my $label=&::label($_[0]);
-+    &::align($_[1]) if ($_[1]>1);
-+    &::set_label_B($label);
-+  $label;
-+}
-+
-+sub ::wipe_labels	# wipes function-scope labels
-+{   foreach $i (keys %label)
-+    {	delete $label{$i} if ($label{$i} =~ /^\Q${lbdecor}\E[0-9]{3}/);	}
-+}
-+
-+# subroutine management
-+sub ::function_begin
-+{   &function_begin_B(@_);
-+    $stack=4;
-+    &push("ebp");
-+    &push("ebx");
-+    &push("esi");
-+    &push("edi");
-+}
-+
-+sub ::function_end
-+{   &pop("edi");
-+    &pop("esi");
-+    &pop("ebx");
-+    &pop("ebp");
-+    &ret();
-+    &function_end_B(@_);
-+    $stack=0;
-+    &wipe_labels();
-+}
-+
-+sub ::function_end_A
-+{   &pop("edi");
-+    &pop("esi");
-+    &pop("ebx");
-+    &pop("ebp");
-+    &ret();
-+    $stack+=16;	# readjust esp as if we didn't pop anything
-+}
-+
-+sub ::asciz
-+{ my @str=unpack("C*",shift);
-+    push @str,0;
-+    while ($#str>15) {
-+	&data_byte(@str[0..15]);
-+	foreach (0..15) { shift @str; }
-+    }
-+    &data_byte(@str) if (@str);
-+}
-+
-+sub ::asm_finish
-+{   &file_end();
-+    print @out;
-+}
-+
-+sub ::asm_init
-+{ my ($type,$fn,$cpu)=@_;
-+
-+    $filename=$fn;
-+    $i386=$cpu;
-+
-+    $elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=$android=0;
-+    if    (($type eq "elf"))
-+    {	$elf=1;			require "x86gas.pl";	}
-+    elsif (($type eq "elf-1"))
-+    {	$elf=-1;		require "x86gas.pl";	}
-+    elsif (($type eq "a\.out"))
-+    {	$aout=1;		require "x86gas.pl";	}
-+    elsif (($type eq "coff" or $type eq "gaswin"))
-+    {	$coff=1;		require "x86gas.pl";	}
-+    elsif (($type eq "win32n"))
-+    {	$win32=1;		require "x86nasm.pl";	}
-+    elsif (($type eq "nw-nasm"))
-+    {	$netware=1;		require "x86nasm.pl";	}
-+    #elsif (($type eq "nw-mwasm"))
-+    #{	$netware=1; $mwerks=1;	require "x86nasm.pl";	}
-+    elsif (($type eq "win32"))
-+    {	$win32=1;		require "x86masm.pl";	}
-+    elsif (($type eq "macosx"))
-+    {	$aout=1; $macosx=1;	require "x86gas.pl";	}
-+    elsif (($type eq "android"))
-+    {	$elf=1; $android=1;	require "x86gas.pl";	}
-+    else
-+    {	print STDERR <<"EOF";
-+Pick one target type from
-+	elf	- Linux, FreeBSD, Solaris x86, etc.
-+	a.out	- DJGPP, elder OpenBSD, etc.
-+	coff	- GAS/COFF such as Win32 targets
-+	win32n	- Windows 95/Windows NT NASM format
-+	nw-nasm - NetWare NASM format
-+	macosx	- Mac OS X
-+EOF
-+	exit(1);
-+    }
-+
-+    $pic=0;
-+    for (@ARGV) { $pic=1 if (/\-[fK]PIC/i); }
-+
-+    $filename =~ s/\.pl$//;
-+    &file($filename);
-+}
-+
-+sub ::hidden {}
-+
-+1;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86gas.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86gas.pl
-new file mode 100644
-index 0000000..2c8fce0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86gas.pl
-@@ -0,0 +1,265 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+package x86gas;
-+
-+*out=\@::out;
-+
-+$::lbdecor=$::aout?"L":".L";		# local label decoration
-+$nmdecor=($::aout or $::coff)?"_":"";	# external name decoration
-+
-+$initseg="";
-+
-+$align=16;
-+$align=log($align)/log(2) if ($::aout);
-+$com_start="#" if ($::aout or $::coff);
-+
-+sub opsize()
-+{ my $reg=shift;
-+    if    ($reg =~ m/^%e/o)		{ "l"; }
-+    elsif ($reg =~ m/^%[a-d][hl]$/o)	{ "b"; }
-+    elsif ($reg =~ m/^%[yxm]/o)		{ undef; }
-+    else				{ "w"; }
-+}
-+
-+# swap arguments;
-+# expand opcode with size suffix;
-+# prefix numeric constants with $;
-+sub ::generic
-+{ my($opcode,@arg)=@_;
-+  my($suffix,$dst,$src);
-+
-+    @arg=reverse(@arg);
-+
-+    for (@arg)
-+    {	s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o;	# gp registers
-+	s/^([xy]?mm[0-7])$/%$1/o;		# xmm/mmx registers
-+	s/^(\-?[0-9]+)$/\$$1/o;			# constants
-+	s/^(\-?0x[0-9a-f]+)$/\$$1/o;		# constants
-+    }
-+
-+    $dst = $arg[$#arg]		if ($#arg>=0);
-+    $src = $arg[$#arg-1]	if ($#arg>=1);
-+    if    ($dst =~ m/^%/o)	{ $suffix=&opsize($dst); }
-+    elsif ($src =~ m/^%/o)	{ $suffix=&opsize($src); }
-+    else			{ $suffix="l";           }
-+    undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o);
-+
-+    if ($#_==0)				{ &::emit($opcode);		}
-+    elsif ($#_==1 && $opcode =~ m/^(call|clflush|j|loop|set)/o)
-+					{ &::emit($opcode,@arg);	}
-+    else				{ &::emit($opcode.$suffix,@arg);}
-+
-+  1;
-+}
-+#
-+# opcodes not covered by ::generic above, mostly inconsistent namings...
-+#
-+sub ::movzx	{ &::movzb(@_);			}
-+sub ::pushfd	{ &::pushfl;			}
-+sub ::popfd	{ &::popfl;			}
-+sub ::cpuid	{ &::emit(".byte\t0x0f,0xa2");	}
-+sub ::rdtsc	{ &::emit(".byte\t0x0f,0x31");	}
-+
-+sub ::call	{ &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); }
-+sub ::call_ptr	{ &::generic("call","*$_[0]");	}
-+sub ::jmp_ptr	{ &::generic("jmp","*$_[0]");	}
-+
-+*::bswap = sub	{ &::emit("bswap","%$_[0]");	} if (!$::i386);
-+
-+sub ::DWP
-+{ my($addr,$reg1,$reg2,$idx)=@_;
-+  my $ret="";
-+
-+    if (!defined($idx) && 1*$reg2) { $idx=$reg2; $reg2=$reg1; undef $reg1; }
-+
-+    $addr =~ s/^\s+//;
-+    # prepend global references with optional underscore
-+    $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige;
-+
-+    $reg1 = "%$reg1" if ($reg1);
-+    $reg2 = "%$reg2" if ($reg2);
-+
-+    $ret .= $addr if (($addr ne "") && ($addr ne 0));
-+
-+    if ($reg2)
-+    {	$idx!= 0 or $idx=1;
-+	$ret .= "($reg1,$reg2,$idx)";
-+    }
-+    elsif ($reg1)
-+    {	$ret .= "($reg1)";	}
-+
-+  $ret;
-+}
-+sub ::QWP	{ &::DWP(@_);	}
-+sub ::BP	{ &::DWP(@_);	}
-+sub ::WP	{ &::DWP(@_);	}
-+sub ::BC	{ @_;		}
-+sub ::DWC	{ @_;		}
-+
-+sub ::file
-+{   push(@out,".file\t\"$_[0].s\"\n.text\n");	}
-+
-+sub ::function_begin_B
-+{ my $func=shift;
-+  my $global=($func !~ /^_/);
-+  my $begin="${::lbdecor}_${func}_begin";
-+
-+    &::LABEL($func,$global?"$begin":"$nmdecor$func");
-+    $func=$nmdecor.$func;
-+
-+    push(@out,".globl\t$func\n")	if ($global);
-+    if ($::coff)
-+    {	push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); }
-+    elsif (($::aout and !$::pic) or $::macosx)
-+    { }
-+    else
-+    {	push(@out,".type	$func,\@function\n"); }
-+    push(@out,".align\t$align\n");
-+    push(@out,"$func:\n");
-+    push(@out,"$begin:\n")		if ($global);
-+    $::stack=4;
-+}
-+
-+sub ::function_end_B
-+{ my $func=shift;
-+    push(@out,".size\t$nmdecor$func,.-".&::LABEL($func)."\n") if ($::elf);
-+    $::stack=0;
-+    &::wipe_labels();
-+}
-+
-+sub ::comment
-+	{
-+	if (!defined($com_start) or $::elf)
-+		{	# Regarding $::elf above...
-+			# GNU and SVR4 as'es use different comment delimiters,
-+		push(@out,"\n");	# so we just skip ELF comments...
-+		return;
-+		}
-+	foreach (@_)
-+		{
-+		if (/^\s*$/)
-+			{ push(@out,"\n"); }
-+		else
-+			{ push(@out,"\t$com_start $_ $com_end\n"); }
-+		}
-+	}
-+
-+sub ::external_label
-+{   foreach(@_) { &::LABEL($_,$nmdecor.$_); }   }
-+
-+sub ::public_label
-+{   push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n");   }
-+
-+sub ::file_end
-+{   if ($::macosx)
-+    {	if (%non_lazy_ptr)
-+    	{   push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n");
-+	    foreach $i (keys %non_lazy_ptr)
-+	    {	push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n");   }
-+	}
-+    }
-+    if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) {
-+	my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,16";
-+	if ($::macosx)	{ push (@out,"$tmp,2\n"); }
-+	elsif ($::elf)	{ push (@out,"$tmp,4\n"); }
-+	else		{ push (@out,"$tmp\n"); }
-+    }
-+    push(@out,$initseg) if ($initseg);
-+}
-+
-+sub ::data_byte	{   push(@out,".byte\t".join(',',@_)."\n");   }
-+sub ::data_short{   push(@out,".value\t".join(',',@_)."\n");  }
-+sub ::data_word {   push(@out,".long\t".join(',',@_)."\n");   }
-+
-+sub ::align
-+{ my $val=$_[0];
-+    if ($::aout)
-+    {	$val=int(log($val)/log(2));
-+	$val.=",0x90";
-+    }
-+    push(@out,".align\t$val\n");
-+}
-+
-+sub ::picmeup
-+{ my($dst,$sym,$base,$reflabel)=@_;
-+
-+    if (($::pic && ($::elf || $::aout)) || $::macosx)
-+    {	if (!defined($base))
-+	{   &::call(&::label("PIC_me_up"));
-+	    &::set_label("PIC_me_up");
-+	    &::blindpop($dst);
-+	    $base=$dst;
-+	    $reflabel=&::label("PIC_me_up");
-+	}
-+	if ($::macosx)
-+	{   my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr");
-+	    &::mov($dst,&::DWP("$indirect-$reflabel",$base));
-+	    $non_lazy_ptr{"$nmdecor$sym"}=$indirect;
-+	}
-+	elsif ($sym eq "OPENSSL_ia32cap_P" && $::elf>0)
-+	{   &::lea($dst,&::DWP("$sym-$reflabel",$base));   }
-+	else
-+	{   &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]",
-+			    $base));
-+	    &::mov($dst,&::DWP("$sym\@GOT",$dst));
-+	}
-+    }
-+    else
-+    {	&::lea($dst,&::DWP($sym));	}
-+}
-+
-+sub ::initseg
-+{ my $f=$nmdecor.shift;
-+
-+    if ($::android)
-+    {	$initseg.=<<___;
-+.section	.init_array
-+.align	4
-+.long	$f
-+___
-+    }
-+    elsif ($::elf)
-+    {	$initseg.=<<___;
-+.section	.init
-+	call	$f
-+___
-+    }
-+    elsif ($::coff)
-+    {   $initseg.=<<___;	# applies to both Cygwin and Mingw
-+.section	.ctors
-+.long	$f
-+___
-+    }
-+    elsif ($::macosx)
-+    {	$initseg.=<<___;
-+.mod_init_func
-+.align 2
-+.long   $f
-+___
-+    }
-+    elsif ($::aout)
-+    {	my $ctor="${nmdecor}_GLOBAL_\$I\$$f";
-+	$initseg.=".text\n";
-+	$initseg.=".type	$ctor,\@function\n" if ($::pic);
-+	$initseg.=<<___;	# OpenBSD way...
-+.globl	$ctor
-+.align	2
-+$ctor:
-+	jmp	$f
-+___
-+    }
-+}
-+
-+sub ::dataseg
-+{   push(@out,".data\n");   }
-+
-+*::hidden = sub { push(@out,".hidden\t$nmdecor$_[0]\n"); } if ($::elf);
-+
-+1;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86masm.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86masm.pl
-new file mode 100644
-index 0000000..d352f47
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/perlasm/x86masm.pl
-@@ -0,0 +1,207 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+package x86masm;
-+
-+*out=\@::out;
-+
-+$::lbdecor="\$L";	# local label decoration
-+$nmdecor="_";		# external name decoration
-+
-+$initseg="";
-+$segment="";
-+
-+sub ::generic
-+{ my ($opcode,@arg)=@_;
-+
-+    # fix hexadecimal constants
-+    for (@arg) { s/(?= 0x02030000\n");
-+    push(@out,"safeseh	".&::LABEL($nm,$nmdecor.$nm)."\n");
-+    push(@out,"%endif\n");
-+}
-+
-+1;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/build.info
-new file mode 100644
-index 0000000..b87299e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/build.info
-@@ -0,0 +1,5 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        p12_add.c p12_asn.c p12_attr.c p12_crpt.c p12_crt.c p12_decr.c \
-+        p12_init.c p12_key.c p12_kiss.c p12_mutl.c p12_sbag.c \
-+        p12_utl.c p12_npas.c pk12err.c p12_p8d.c p12_p8e.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c
-new file mode 100644
-index 0000000..193ed80
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_add.c
-@@ -0,0 +1,164 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "p12_lcl.h"
-+
-+/* Pack an object into an OCTET STRING and turn into a safebag */
-+
-+PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it,
-+                                         int nid1, int nid2)
-+{
-+    PKCS12_BAGS *bag;
-+    PKCS12_SAFEBAG *safebag;
-+
-+    if ((bag = PKCS12_BAGS_new()) == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    bag->type = OBJ_nid2obj(nid1);
-+    if (!ASN1_item_pack(obj, it, &bag->value.octet)) {
-+        PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if ((safebag = PKCS12_SAFEBAG_new()) == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    safebag->value.bag = bag;
-+    safebag->type = OBJ_nid2obj(nid2);
-+    return safebag;
-+
-+ err:
-+    PKCS12_BAGS_free(bag);
-+    return NULL;
-+}
-+
-+/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
-+PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk)
-+{
-+    PKCS7 *p7;
-+
-+    if ((p7 = PKCS7_new()) == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    p7->type = OBJ_nid2obj(NID_pkcs7_data);
-+    if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) {
-+        PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE);
-+        goto err;
-+    }
-+    return p7;
-+
-+ err:
-+    PKCS7_free(p7);
-+    return NULL;
-+}
-+
-+/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */
-+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
-+{
-+    if (!PKCS7_type_is_data(p7)) {
-+        PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA,
-+                  PKCS12_R_CONTENT_TYPE_NOT_DATA);
-+        return NULL;
-+    }
-+    return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
-+}
-+
-+/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
-+
-+PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
-+                             unsigned char *salt, int saltlen, int iter,
-+                             STACK_OF(PKCS12_SAFEBAG) *bags)
-+{
-+    PKCS7 *p7;
-+    X509_ALGOR *pbe;
-+    const EVP_CIPHER *pbe_ciph;
-+
-+    if ((p7 = PKCS7_new()) == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) {
-+        PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA,
-+                  PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
-+        goto err;
-+    }
-+
-+    pbe_ciph = EVP_get_cipherbynid(pbe_nid);
-+
-+    if (pbe_ciph)
-+        pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen);
-+    else
-+        pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
-+
-+    if (!pbe) {
-+        PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm);
-+    p7->d.encrypted->enc_data->algorithm = pbe;
-+    ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data);
-+    if (!(p7->d.encrypted->enc_data->enc_data =
-+          PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass,
-+                                  passlen, bags, 1))) {
-+        PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR);
-+        goto err;
-+    }
-+
-+    return p7;
-+
-+ err:
-+    PKCS7_free(p7);
-+    return NULL;
-+}
-+
-+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
-+                                                  int passlen)
-+{
-+    if (!PKCS7_type_is_encrypted(p7))
-+        return NULL;
-+    return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
-+                                   ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
-+                                   pass, passlen,
-+                                   p7->d.encrypted->enc_data->enc_data, 1);
-+}
-+
-+PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag,
-+                                         const char *pass, int passlen)
-+{
-+    return PKCS8_decrypt(bag->value.shkeybag, pass, passlen);
-+}
-+
-+int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes)
-+{
-+    if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES),
-+                       &p12->authsafes->d.data))
-+        return 1;
-+    return 0;
-+}
-+
-+STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12)
-+{
-+    if (!PKCS7_type_is_data(p12->authsafes)) {
-+        PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES,
-+                  PKCS12_R_CONTENT_TYPE_NOT_DATA);
-+        return NULL;
-+    }
-+    return ASN1_item_unpack(p12->authsafes->d.data,
-+                            ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_asn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_asn.c
-new file mode 100644
-index 0000000..f2bfe32
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_asn.c
-@@ -0,0 +1,76 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "p12_lcl.h"
-+
-+/* PKCS#12 ASN1 module */
-+
-+ASN1_SEQUENCE(PKCS12) = {
-+        ASN1_SIMPLE(PKCS12, version, ASN1_INTEGER),
-+        ASN1_SIMPLE(PKCS12, authsafes, PKCS7),
-+        ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA)
-+} ASN1_SEQUENCE_END(PKCS12)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS12)
-+
-+ASN1_SEQUENCE(PKCS12_MAC_DATA) = {
-+        ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG),
-+        ASN1_SIMPLE(PKCS12_MAC_DATA, salt, ASN1_OCTET_STRING),
-+        ASN1_OPT(PKCS12_MAC_DATA, iter, ASN1_INTEGER)
-+} ASN1_SEQUENCE_END(PKCS12_MAC_DATA)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
-+
-+ASN1_ADB_TEMPLATE(bag_default) = ASN1_EXP(PKCS12_BAGS, value.other, ASN1_ANY, 0);
-+
-+ASN1_ADB(PKCS12_BAGS) = {
-+        ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509cert, ASN1_OCTET_STRING, 0)),
-+        ADB_ENTRY(NID_x509Crl, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)),
-+        ADB_ENTRY(NID_sdsiCertificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)),
-+} ASN1_ADB_END(PKCS12_BAGS, 0, type, 0, &bag_default_tt, NULL);
-+
-+ASN1_SEQUENCE(PKCS12_BAGS) = {
-+        ASN1_SIMPLE(PKCS12_BAGS, type, ASN1_OBJECT),
-+        ASN1_ADB_OBJECT(PKCS12_BAGS),
-+} ASN1_SEQUENCE_END(PKCS12_BAGS)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_BAGS)
-+
-+ASN1_ADB_TEMPLATE(safebag_default) = ASN1_EXP(PKCS12_SAFEBAG, value.other, ASN1_ANY, 0);
-+
-+ASN1_ADB(PKCS12_SAFEBAG) = {
-+        ADB_ENTRY(NID_keyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, PKCS8_PRIV_KEY_INFO, 0)),
-+        ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.shkeybag, X509_SIG, 0)),
-+        ADB_ENTRY(NID_safeContentsBag, ASN1_EXP_SET_OF(PKCS12_SAFEBAG, value.safes, PKCS12_SAFEBAG, 0)),
-+        ADB_ENTRY(NID_certBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)),
-+        ADB_ENTRY(NID_crlBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)),
-+        ADB_ENTRY(NID_secretBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0))
-+} ASN1_ADB_END(PKCS12_SAFEBAG, 0, type, 0, &safebag_default_tt, NULL);
-+
-+ASN1_SEQUENCE(PKCS12_SAFEBAG) = {
-+        ASN1_SIMPLE(PKCS12_SAFEBAG, type, ASN1_OBJECT),
-+        ASN1_ADB_OBJECT(PKCS12_SAFEBAG),
-+        ASN1_SET_OF_OPT(PKCS12_SAFEBAG, attrib, X509_ATTRIBUTE)
-+} ASN1_SEQUENCE_END(PKCS12_SAFEBAG)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
-+
-+/* SEQUENCE OF SafeBag */
-+ASN1_ITEM_TEMPLATE(PKCS12_SAFEBAGS) =
-+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_SAFEBAGS, PKCS12_SAFEBAG)
-+ASN1_ITEM_TEMPLATE_END(PKCS12_SAFEBAGS)
-+
-+/* Authsafes: SEQUENCE OF PKCS7 */
-+ASN1_ITEM_TEMPLATE(PKCS12_AUTHSAFES) =
-+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_AUTHSAFES, PKCS7)
-+ASN1_ITEM_TEMPLATE_END(PKCS12_AUTHSAFES)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_attr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_attr.c
-new file mode 100644
-index 0000000..c324f50
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_attr.c
-@@ -0,0 +1,103 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "p12_lcl.h"
-+
-+/* Add a local keyid to a safebag */
-+
-+int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
-+                          int namelen)
-+{
-+    if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID,
-+                                V_ASN1_OCTET_STRING, name, namelen))
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+/* Add key usage to PKCS#8 structure */
-+
-+int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage)
-+{
-+    unsigned char us_val = (unsigned char)usage;
-+    return PKCS8_pkey_add1_attr_by_NID(p8, NID_key_usage,
-+                                       V_ASN1_BIT_STRING, &us_val, 1);
-+}
-+
-+/* Add a friendlyname to a safebag */
-+
-+int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
-+                                int namelen)
-+{
-+    if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
-+                                MBSTRING_ASC, (unsigned char *)name, namelen))
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+int PKCS12_add_friendlyname_utf8(PKCS12_SAFEBAG *bag, const char *name,
-+                                int namelen)
-+{
-+    if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
-+                                MBSTRING_UTF8, (unsigned char *)name, namelen))
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
-+                                const unsigned char *name, int namelen)
-+{
-+    if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
-+                                MBSTRING_BMP, name, namelen))
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen)
-+{
-+    if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name,
-+                                MBSTRING_ASC, (unsigned char *)name, namelen))
-+        return 1;
-+    else
-+        return 0;
-+}
-+
-+ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs,
-+                               int attr_nid)
-+{
-+    X509_ATTRIBUTE *attrib;
-+    int i;
-+    i = X509at_get_attr_by_NID(attrs, attr_nid, -1);
-+    attrib = X509at_get_attr(attrs, i);
-+    return X509_ATTRIBUTE_get0_type(attrib, 0);
-+}
-+
-+char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag)
-+{
-+    const ASN1_TYPE *atype;
-+
-+    if ((atype = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName)) == NULL)
-+        return NULL;
-+    if (atype->type != V_ASN1_BMPSTRING)
-+        return NULL;
-+    return OPENSSL_uni2utf8(atype->value.bmpstring->data,
-+                            atype->value.bmpstring->length);
-+}
-+
-+const STACK_OF(X509_ATTRIBUTE) *
-+PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag)
-+{
-+    return bag->attrib;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_crpt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_crpt.c
-new file mode 100644
-index 0000000..feef9d1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_crpt.c
-@@ -0,0 +1,70 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+/* PKCS#12 PBE algorithms now in static table */
-+
-+void PKCS12_PBE_add(void)
-+{
-+}
-+
-+int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
-+                        ASN1_TYPE *param, const EVP_CIPHER *cipher,
-+                        const EVP_MD *md, int en_de)
-+{
-+    PBEPARAM *pbe;
-+    int saltlen, iter, ret;
-+    unsigned char *salt;
-+    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
-+    int (*pkcs12_key_gen)(const char *pass, int passlen,
-+                          unsigned char *salt, int slen,
-+                          int id, int iter, int n,
-+                          unsigned char *out,
-+                          const EVP_MD *md_type);
-+
-+    pkcs12_key_gen = PKCS12_key_gen_utf8;
-+
-+    if (cipher == NULL)
-+        return 0;
-+
-+    /* Extract useful info from parameter */
-+
-+    pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param);
-+    if (pbe == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR);
-+        return 0;
-+    }
-+
-+    if (!pbe->iter)
-+        iter = 1;
-+    else
-+        iter = ASN1_INTEGER_get(pbe->iter);
-+    salt = pbe->salt->data;
-+    saltlen = pbe->salt->length;
-+    if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_KEY_ID,
-+                           iter, EVP_CIPHER_key_length(cipher), key, md)) {
-+        PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR);
-+        PBEPARAM_free(pbe);
-+        return 0;
-+    }
-+    if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_IV_ID,
-+                           iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
-+        PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR);
-+        PBEPARAM_free(pbe);
-+        return 0;
-+    }
-+    PBEPARAM_free(pbe);
-+    ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de);
-+    OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
-+    OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_crt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_crt.c
-new file mode 100644
-index 0000000..10cf8dd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_crt.c
-@@ -0,0 +1,291 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "p12_lcl.h"
-+
-+static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
-+                          PKCS12_SAFEBAG *bag);
-+
-+static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
-+{
-+    int idx;
-+    X509_ATTRIBUTE *attr;
-+    idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
-+    if (idx < 0)
-+        return 1;
-+    attr = EVP_PKEY_get_attr(pkey, idx);
-+    if (!X509at_add1_attr(&bag->attrib, attr))
-+        return 0;
-+    return 1;
-+}
-+
-+PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert,
-+                      STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
-+                      int mac_iter, int keytype)
-+{
-+    PKCS12 *p12 = NULL;
-+    STACK_OF(PKCS7) *safes = NULL;
-+    STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
-+    PKCS12_SAFEBAG *bag = NULL;
-+    int i;
-+    unsigned char keyid[EVP_MAX_MD_SIZE];
-+    unsigned int keyidlen = 0;
-+
-+    /* Set defaults */
-+    if (!nid_cert)
-+#ifdef OPENSSL_NO_RC2
-+        nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
-+#else
-+        nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
-+#endif
-+    if (!nid_key)
-+        nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
-+    if (!iter)
-+        iter = PKCS12_DEFAULT_ITER;
-+    if (!mac_iter)
-+        mac_iter = 1;
-+
-+    if (!pkey && !cert && !ca) {
-+        PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT);
-+        return NULL;
-+    }
-+
-+    if (pkey && cert) {
-+        if (!X509_check_private_key(cert, pkey))
-+            return NULL;
-+        X509_digest(cert, EVP_sha1(), keyid, &keyidlen);
-+    }
-+
-+    if (cert) {
-+        bag = PKCS12_add_cert(&bags, cert);
-+        if (name && !PKCS12_add_friendlyname(bag, name, -1))
-+            goto err;
-+        if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
-+            goto err;
-+    }
-+
-+    /* Add all other certificates */
-+    for (i = 0; i < sk_X509_num(ca); i++) {
-+        if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
-+            goto err;
-+    }
-+
-+    if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
-+        goto err;
-+
-+    sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-+    bags = NULL;
-+
-+    if (pkey) {
-+        bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
-+
-+        if (!bag)
-+            goto err;
-+
-+        if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
-+            goto err;
-+        if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
-+            goto err;
-+
-+        if (name && !PKCS12_add_friendlyname(bag, name, -1))
-+            goto err;
-+        if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
-+            goto err;
-+    }
-+
-+    if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
-+        goto err;
-+
-+    sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-+    bags = NULL;
-+
-+    p12 = PKCS12_add_safes(safes, 0);
-+
-+    if (!p12)
-+        goto err;
-+
-+    sk_PKCS7_pop_free(safes, PKCS7_free);
-+
-+    safes = NULL;
-+
-+    if ((mac_iter != -1) &&
-+        !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
-+        goto err;
-+
-+    return p12;
-+
-+ err:
-+    PKCS12_free(p12);
-+    sk_PKCS7_pop_free(safes, PKCS7_free);
-+    sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-+    return NULL;
-+
-+}
-+
-+PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
-+{
-+    PKCS12_SAFEBAG *bag = NULL;
-+    char *name;
-+    int namelen = -1;
-+    unsigned char *keyid;
-+    int keyidlen = -1;
-+
-+    /* Add user certificate */
-+    if ((bag = PKCS12_SAFEBAG_create_cert(cert)) == NULL)
-+        goto err;
-+
-+    /*
-+     * Use friendlyName and localKeyID in certificate. (if present)
-+     */
-+
-+    name = (char *)X509_alias_get0(cert, &namelen);
-+
-+    if (name && !PKCS12_add_friendlyname(bag, name, namelen))
-+        goto err;
-+
-+    keyid = X509_keyid_get0(cert, &keyidlen);
-+
-+    if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
-+        goto err;
-+
-+    if (!pkcs12_add_bag(pbags, bag))
-+        goto err;
-+
-+    return bag;
-+
-+ err:
-+    PKCS12_SAFEBAG_free(bag);
-+    return NULL;
-+
-+}
-+
-+PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
-+                               EVP_PKEY *key, int key_usage, int iter,
-+                               int nid_key, const char *pass)
-+{
-+
-+    PKCS12_SAFEBAG *bag = NULL;
-+    PKCS8_PRIV_KEY_INFO *p8 = NULL;
-+
-+    /* Make a PKCS#8 structure */
-+    if ((p8 = EVP_PKEY2PKCS8(key)) == NULL)
-+        goto err;
-+    if (key_usage && !PKCS8_add_keyusage(p8, key_usage))
-+        goto err;
-+    if (nid_key != -1) {
-+        bag = PKCS12_SAFEBAG_create_pkcs8_encrypt(nid_key, pass, -1, NULL, 0,
-+                                                  iter, p8);
-+        PKCS8_PRIV_KEY_INFO_free(p8);
-+    } else
-+        bag = PKCS12_SAFEBAG_create0_p8inf(p8);
-+
-+    if (!bag)
-+        goto err;
-+
-+    if (!pkcs12_add_bag(pbags, bag))
-+        goto err;
-+
-+    return bag;
-+
-+ err:
-+    PKCS12_SAFEBAG_free(bag);
-+    return NULL;
-+
-+}
-+
-+int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
-+                    int nid_safe, int iter, const char *pass)
-+{
-+    PKCS7 *p7 = NULL;
-+    int free_safes = 0;
-+
-+    if (!*psafes) {
-+        *psafes = sk_PKCS7_new_null();
-+        if (!*psafes)
-+            return 0;
-+        free_safes = 1;
-+    } else
-+        free_safes = 0;
-+
-+    if (nid_safe == 0)
-+#ifdef OPENSSL_NO_RC2
-+        nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
-+#else
-+        nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
-+#endif
-+
-+    if (nid_safe == -1)
-+        p7 = PKCS12_pack_p7data(bags);
-+    else
-+        p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags);
-+    if (!p7)
-+        goto err;
-+
-+    if (!sk_PKCS7_push(*psafes, p7))
-+        goto err;
-+
-+    return 1;
-+
-+ err:
-+    if (free_safes) {
-+        sk_PKCS7_free(*psafes);
-+        *psafes = NULL;
-+    }
-+    PKCS7_free(p7);
-+    return 0;
-+
-+}
-+
-+static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
-+                          PKCS12_SAFEBAG *bag)
-+{
-+    int free_bags;
-+    if (!pbags)
-+        return 1;
-+    if (!*pbags) {
-+        *pbags = sk_PKCS12_SAFEBAG_new_null();
-+        if (!*pbags)
-+            return 0;
-+        free_bags = 1;
-+    } else
-+        free_bags = 0;
-+
-+    if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) {
-+        if (free_bags) {
-+            sk_PKCS12_SAFEBAG_free(*pbags);
-+            *pbags = NULL;
-+        }
-+        return 0;
-+    }
-+
-+    return 1;
-+
-+}
-+
-+PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
-+{
-+    PKCS12 *p12;
-+    if (nid_p7 <= 0)
-+        nid_p7 = NID_pkcs7_data;
-+    p12 = PKCS12_init(nid_p7);
-+
-+    if (!p12)
-+        return NULL;
-+
-+    if (!PKCS12_pack_authsafes(p12, safes)) {
-+        PKCS12_free(p12);
-+        return NULL;
-+    }
-+
-+    return p12;
-+
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_decr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_decr.c
-new file mode 100644
-index 0000000..3c86058
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_decr.c
-@@ -0,0 +1,155 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+/* Define this to dump decrypted output to files called DERnnn */
-+/*
-+ * #define OPENSSL_DEBUG_DECRYPT
-+ */
-+
-+/*
-+ * Encrypt/Decrypt a buffer based on password and algor, result in a
-+ * OPENSSL_malloc'ed buffer
-+ */
-+unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
-+                                const char *pass, int passlen,
-+                                const unsigned char *in, int inlen,
-+                                unsigned char **data, int *datalen, int en_de)
-+{
-+    unsigned char *out = NULL;
-+    int outlen, i;
-+    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
-+
-+    if (ctx == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    /* Decrypt data */
-+    if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen,
-+                            algor->parameter, ctx, en_de)) {
-+        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
-+                  PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR);
-+        goto err;
-+    }
-+
-+    if ((out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(ctx)))
-+            == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (!EVP_CipherUpdate(ctx, out, &i, in, inlen)) {
-+        OPENSSL_free(out);
-+        out = NULL;
-+        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_EVP_LIB);
-+        goto err;
-+    }
-+
-+    outlen = i;
-+    if (!EVP_CipherFinal_ex(ctx, out + i, &i)) {
-+        OPENSSL_free(out);
-+        out = NULL;
-+        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
-+                  PKCS12_R_PKCS12_CIPHERFINAL_ERROR);
-+        goto err;
-+    }
-+    outlen += i;
-+    if (datalen)
-+        *datalen = outlen;
-+    if (data)
-+        *data = out;
-+ err:
-+    EVP_CIPHER_CTX_free(ctx);
-+    return out;
-+
-+}
-+
-+/*
-+ * Decrypt an OCTET STRING and decode ASN1 structure if zbuf set zero buffer
-+ * after use.
-+ */
-+
-+void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it,
-+                              const char *pass, int passlen,
-+                              const ASN1_OCTET_STRING *oct, int zbuf)
-+{
-+    unsigned char *out;
-+    const unsigned char *p;
-+    void *ret;
-+    int outlen;
-+
-+    if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length,
-+                          &out, &outlen, 0)) {
-+        PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,
-+                  PKCS12_R_PKCS12_PBE_CRYPT_ERROR);
-+        return NULL;
-+    }
-+    p = out;
-+#ifdef OPENSSL_DEBUG_DECRYPT
-+    {
-+        FILE *op;
-+
-+        char fname[30];
-+        static int fnm = 1;
-+        sprintf(fname, "DER%d", fnm++);
-+        op = fopen(fname, "wb");
-+        fwrite(p, 1, outlen, op);
-+        fclose(op);
-+    }
-+#endif
-+    ret = ASN1_item_d2i(NULL, &p, outlen, it);
-+    if (zbuf)
-+        OPENSSL_cleanse(out, outlen);
-+    if (!ret)
-+        PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, PKCS12_R_DECODE_ERROR);
-+    OPENSSL_free(out);
-+    return ret;
-+}
-+
-+/*
-+ * Encode ASN1 structure and encrypt, return OCTET STRING if zbuf set zero
-+ * encoding.
-+ */
-+
-+ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
-+                                           const ASN1_ITEM *it,
-+                                           const char *pass, int passlen,
-+                                           void *obj, int zbuf)
-+{
-+    ASN1_OCTET_STRING *oct = NULL;
-+    unsigned char *in = NULL;
-+    int inlen;
-+
-+    if ((oct = ASN1_OCTET_STRING_new()) == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    inlen = ASN1_item_i2d(obj, &in, it);
-+    if (!in) {
-+        PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCODE_ERROR);
-+        goto err;
-+    }
-+    if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data,
-+                          &oct->length, 1)) {
-+        PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
-+        OPENSSL_free(in);
-+        goto err;
-+    }
-+    if (zbuf)
-+        OPENSSL_cleanse(in, inlen);
-+    OPENSSL_free(in);
-+    return oct;
-+ err:
-+    ASN1_OCTET_STRING_free(oct);
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_init.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_init.c
-new file mode 100644
-index 0000000..a78e183
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_init.c
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "p12_lcl.h"
-+
-+/* Initialise a PKCS12 structure to take data */
-+
-+PKCS12 *PKCS12_init(int mode)
-+{
-+    PKCS12 *pkcs12;
-+
-+    if ((pkcs12 = PKCS12_new()) == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    ASN1_INTEGER_set(pkcs12->version, 3);
-+    pkcs12->authsafes->type = OBJ_nid2obj(mode);
-+    switch (mode) {
-+    case NID_pkcs7_data:
-+        if ((pkcs12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL) {
-+            PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        break;
-+    default:
-+        PKCS12err(PKCS12_F_PKCS12_INIT, PKCS12_R_UNSUPPORTED_PKCS12_MODE);
-+        goto err;
-+    }
-+    return pkcs12;
-+
-+ err:
-+    PKCS12_free(pkcs12);
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_key.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_key.c
-new file mode 100644
-index 0000000..9c13a45
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_key.c
-@@ -0,0 +1,205 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+/* Uncomment out this line to get debugging info about key generation */
-+/*
-+ * #define OPENSSL_DEBUG_KEYGEN
-+ */
-+#ifdef OPENSSL_DEBUG_KEYGEN
-+# include 
-+extern BIO *bio_err;
-+void h__dump(unsigned char *p, int len);
-+#endif
-+
-+/* PKCS12 compatible key/IV generation */
-+#ifndef min
-+# define min(a,b) ((a) < (b) ? (a) : (b))
-+#endif
-+
-+int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
-+                       int saltlen, int id, int iter, int n,
-+                       unsigned char *out, const EVP_MD *md_type)
-+{
-+    int ret;
-+    unsigned char *unipass;
-+    int uniplen;
-+
-+    if (!pass) {
-+        unipass = NULL;
-+        uniplen = 0;
-+    } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
-+        PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
-+                             id, iter, n, out, md_type);
-+    if (ret <= 0)
-+        return 0;
-+    OPENSSL_clear_free(unipass, uniplen);
-+    return ret;
-+}
-+
-+int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
-+                        int saltlen, int id, int iter, int n,
-+                        unsigned char *out, const EVP_MD *md_type)
-+{
-+    int ret;
-+    unsigned char *unipass;
-+    int uniplen;
-+
-+    if (!pass) {
-+        unipass = NULL;
-+        uniplen = 0;
-+    } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) {
-+        PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UTF8, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
-+                             id, iter, n, out, md_type);
-+    if (ret <= 0)
-+        return 0;
-+    OPENSSL_clear_free(unipass, uniplen);
-+    return ret;
-+}
-+
-+int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
-+                       int saltlen, int id, int iter, int n,
-+                       unsigned char *out, const EVP_MD *md_type)
-+{
-+    unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL;
-+    int Slen, Plen, Ilen, Ijlen;
-+    int i, j, u, v;
-+    int ret = 0;
-+    BIGNUM *Ij = NULL, *Bpl1 = NULL; /* These hold Ij and B + 1 */
-+    EVP_MD_CTX *ctx = NULL;
-+#ifdef  OPENSSL_DEBUG_KEYGEN
-+    unsigned char *tmpout = out;
-+    int tmpn = n;
-+#endif
-+
-+    ctx = EVP_MD_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+
-+#ifdef  OPENSSL_DEBUG_KEYGEN
-+    fprintf(stderr, "KEYGEN DEBUG\n");
-+    fprintf(stderr, "ID %d, ITER %d\n", id, iter);
-+    fprintf(stderr, "Password (length %d):\n", passlen);
-+    h__dump(pass, passlen);
-+    fprintf(stderr, "Salt (length %d):\n", saltlen);
-+    h__dump(salt, saltlen);
-+#endif
-+    v = EVP_MD_block_size(md_type);
-+    u = EVP_MD_size(md_type);
-+    if (u < 0 || v <= 0)
-+        goto err;
-+    D = OPENSSL_malloc(v);
-+    Ai = OPENSSL_malloc(u);
-+    B = OPENSSL_malloc(v + 1);
-+    Slen = v * ((saltlen + v - 1) / v);
-+    if (passlen)
-+        Plen = v * ((passlen + v - 1) / v);
-+    else
-+        Plen = 0;
-+    Ilen = Slen + Plen;
-+    I = OPENSSL_malloc(Ilen);
-+    Ij = BN_new();
-+    Bpl1 = BN_new();
-+    if (D == NULL || Ai == NULL || B == NULL || I == NULL || Ij == NULL
-+            || Bpl1 == NULL)
-+        goto err;
-+    for (i = 0; i < v; i++)
-+        D[i] = id;
-+    p = I;
-+    for (i = 0; i < Slen; i++)
-+        *p++ = salt[i % saltlen];
-+    for (i = 0; i < Plen; i++)
-+        *p++ = pass[i % passlen];
-+    for (;;) {
-+        if (!EVP_DigestInit_ex(ctx, md_type, NULL)
-+            || !EVP_DigestUpdate(ctx, D, v)
-+            || !EVP_DigestUpdate(ctx, I, Ilen)
-+            || !EVP_DigestFinal_ex(ctx, Ai, NULL))
-+            goto err;
-+        for (j = 1; j < iter; j++) {
-+            if (!EVP_DigestInit_ex(ctx, md_type, NULL)
-+                || !EVP_DigestUpdate(ctx, Ai, u)
-+                || !EVP_DigestFinal_ex(ctx, Ai, NULL))
-+                goto err;
-+        }
-+        memcpy(out, Ai, min(n, u));
-+        if (u >= n) {
-+#ifdef OPENSSL_DEBUG_KEYGEN
-+            fprintf(stderr, "Output KEY (length %d)\n", tmpn);
-+            h__dump(tmpout, tmpn);
-+#endif
-+            ret = 1;
-+            goto end;
-+        }
-+        n -= u;
-+        out += u;
-+        for (j = 0; j < v; j++)
-+            B[j] = Ai[j % u];
-+        /* Work out B + 1 first then can use B as tmp space */
-+        if (!BN_bin2bn(B, v, Bpl1))
-+            goto err;
-+        if (!BN_add_word(Bpl1, 1))
-+            goto err;
-+        for (j = 0; j < Ilen; j += v) {
-+            if (!BN_bin2bn(I + j, v, Ij))
-+                goto err;
-+            if (!BN_add(Ij, Ij, Bpl1))
-+                goto err;
-+            if (!BN_bn2bin(Ij, B))
-+                goto err;
-+            Ijlen = BN_num_bytes(Ij);
-+            /* If more than 2^(v*8) - 1 cut off MSB */
-+            if (Ijlen > v) {
-+                if (!BN_bn2bin(Ij, B))
-+                    goto err;
-+                memcpy(I + j, B + 1, v);
-+#ifndef PKCS12_BROKEN_KEYGEN
-+                /* If less than v bytes pad with zeroes */
-+            } else if (Ijlen < v) {
-+                memset(I + j, 0, v - Ijlen);
-+                if (!BN_bn2bin(Ij, I + j + v - Ijlen))
-+                    goto err;
-+#endif
-+            } else if (!BN_bn2bin(Ij, I + j))
-+                goto err;
-+        }
-+    }
-+
-+ err:
-+    PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE);
-+
-+ end:
-+    OPENSSL_free(Ai);
-+    OPENSSL_free(B);
-+    OPENSSL_free(D);
-+    OPENSSL_free(I);
-+    BN_free(Ij);
-+    BN_free(Bpl1);
-+    EVP_MD_CTX_free(ctx);
-+    return ret;
-+}
-+
-+#ifdef OPENSSL_DEBUG_KEYGEN
-+void h__dump(unsigned char *p, int len)
-+{
-+    for (; len--; p++)
-+        fprintf(stderr, "%02X", *p);
-+    fprintf(stderr, "\n");
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_kiss.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_kiss.c
-new file mode 100644
-index 0000000..62f5d1e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_kiss.c
-@@ -0,0 +1,245 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+/* Simplified PKCS#12 routines */
-+
-+static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
-+                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
-+
-+static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
-+                      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
-+
-+static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
-+                     EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
-+
-+/*
-+ * Parse and decrypt a PKCS#12 structure returning user key, user cert and
-+ * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it
-+ * should point to a valid STACK structure. pkey and cert can be passed
-+ * uninitialised.
-+ */
-+
-+int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
-+                 STACK_OF(X509) **ca)
-+{
-+    STACK_OF(X509) *ocerts = NULL;
-+    X509 *x = NULL;
-+    /* Check for NULL PKCS12 structure */
-+
-+    if (!p12) {
-+        PKCS12err(PKCS12_F_PKCS12_PARSE,
-+                  PKCS12_R_INVALID_NULL_PKCS12_POINTER);
-+        return 0;
-+    }
-+
-+    if (pkey)
-+        *pkey = NULL;
-+    if (cert)
-+        *cert = NULL;
-+
-+    /* Check the mac */
-+
-+    /*
-+     * If password is zero length or NULL then try verifying both cases to
-+     * determine which password is correct. The reason for this is that under
-+     * PKCS#12 password based encryption no password and a zero length
-+     * password are two different things...
-+     */
-+
-+    if (!pass || !*pass) {
-+        if (PKCS12_verify_mac(p12, NULL, 0))
-+            pass = NULL;
-+        else if (PKCS12_verify_mac(p12, "", 0))
-+            pass = "";
-+        else {
-+            PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
-+            goto err;
-+        }
-+    } else if (!PKCS12_verify_mac(p12, pass, -1)) {
-+        PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
-+        goto err;
-+    }
-+
-+    /* Allocate stack for other certificates */
-+    ocerts = sk_X509_new_null();
-+
-+    if (!ocerts) {
-+        PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    if (!parse_pk12(p12, pass, -1, pkey, ocerts)) {
-+        PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR);
-+        goto err;
-+    }
-+
-+    while ((x = sk_X509_pop(ocerts))) {
-+        if (pkey && *pkey && cert && !*cert) {
-+            ERR_set_mark();
-+            if (X509_check_private_key(x, *pkey)) {
-+                *cert = x;
-+                x = NULL;
-+            }
-+            ERR_pop_to_mark();
-+        }
-+
-+        if (ca && x) {
-+            if (!*ca)
-+                *ca = sk_X509_new_null();
-+            if (!*ca)
-+                goto err;
-+            if (!sk_X509_push(*ca, x))
-+                goto err;
-+            x = NULL;
-+        }
-+        X509_free(x);
-+    }
-+
-+    sk_X509_pop_free(ocerts, X509_free);
-+
-+    return 1;
-+
-+ err:
-+
-+    if (pkey)
-+        EVP_PKEY_free(*pkey);
-+    if (cert)
-+        X509_free(*cert);
-+    X509_free(x);
-+    sk_X509_pop_free(ocerts, X509_free);
-+    return 0;
-+
-+}
-+
-+/* Parse the outer PKCS#12 structure */
-+
-+static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
-+                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
-+{
-+    STACK_OF(PKCS7) *asafes;
-+    STACK_OF(PKCS12_SAFEBAG) *bags;
-+    int i, bagnid;
-+    PKCS7 *p7;
-+
-+    if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
-+        return 0;
-+    for (i = 0; i < sk_PKCS7_num(asafes); i++) {
-+        p7 = sk_PKCS7_value(asafes, i);
-+        bagnid = OBJ_obj2nid(p7->type);
-+        if (bagnid == NID_pkcs7_data) {
-+            bags = PKCS12_unpack_p7data(p7);
-+        } else if (bagnid == NID_pkcs7_encrypted) {
-+            bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
-+        } else
-+            continue;
-+        if (!bags) {
-+            sk_PKCS7_pop_free(asafes, PKCS7_free);
-+            return 0;
-+        }
-+        if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
-+            sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-+            sk_PKCS7_pop_free(asafes, PKCS7_free);
-+            return 0;
-+        }
-+        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-+    }
-+    sk_PKCS7_pop_free(asafes, PKCS7_free);
-+    return 1;
-+}
-+
-+static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
-+                      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
-+{
-+    int i;
-+    for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
-+        if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i),
-+                       pass, passlen, pkey, ocerts))
-+            return 0;
-+    }
-+    return 1;
-+}
-+
-+static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
-+                     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
-+{
-+    PKCS8_PRIV_KEY_INFO *p8;
-+    X509 *x509;
-+    const ASN1_TYPE *attrib;
-+    ASN1_BMPSTRING *fname = NULL;
-+    ASN1_OCTET_STRING *lkid = NULL;
-+
-+    if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName)))
-+        fname = attrib->value.bmpstring;
-+
-+    if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID)))
-+        lkid = attrib->value.octet_string;
-+
-+    switch (PKCS12_SAFEBAG_get_nid(bag)) {
-+    case NID_keyBag:
-+        if (!pkey || *pkey)
-+            return 1;
-+        *pkey = EVP_PKCS82PKEY(PKCS12_SAFEBAG_get0_p8inf(bag));
-+        if (*pkey == NULL)
-+            return 0;
-+        break;
-+
-+    case NID_pkcs8ShroudedKeyBag:
-+        if (!pkey || *pkey)
-+            return 1;
-+        if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
-+            return 0;
-+        *pkey = EVP_PKCS82PKEY(p8);
-+        PKCS8_PRIV_KEY_INFO_free(p8);
-+        if (!(*pkey))
-+            return 0;
-+        break;
-+
-+    case NID_certBag:
-+        if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate)
-+            return 1;
-+        if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL)
-+            return 0;
-+        if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
-+            X509_free(x509);
-+            return 0;
-+        }
-+        if (fname) {
-+            int len, r;
-+            unsigned char *data;
-+            len = ASN1_STRING_to_UTF8(&data, fname);
-+            if (len >= 0) {
-+                r = X509_alias_set1(x509, data, len);
-+                OPENSSL_free(data);
-+                if (!r) {
-+                    X509_free(x509);
-+                    return 0;
-+                }
-+            }
-+        }
-+
-+        if (!sk_X509_push(ocerts, x509)) {
-+            X509_free(x509);
-+            return 0;
-+        }
-+
-+        break;
-+
-+    case NID_safeContentsBag:
-+        return parse_bags(PKCS12_SAFEBAG_get0_safes(bag), pass, passlen, pkey,
-+                          ocerts);
-+
-+    default:
-+        return 1;
-+    }
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_lcl.h
-new file mode 100644
-index 0000000..0b52f1e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_lcl.h
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+struct PKCS12_MAC_DATA_st {
-+    X509_SIG *dinfo;
-+    ASN1_OCTET_STRING *salt;
-+    ASN1_INTEGER *iter;         /* defaults to 1 */
-+};
-+
-+struct PKCS12_st {
-+    ASN1_INTEGER *version;
-+    PKCS12_MAC_DATA *mac;
-+    PKCS7 *authsafes;
-+};
-+
-+struct PKCS12_SAFEBAG_st {
-+    ASN1_OBJECT *type;
-+    union {
-+        struct pkcs12_bag_st *bag; /* secret, crl and certbag */
-+        struct pkcs8_priv_key_info_st *keybag; /* keybag */
-+        X509_SIG *shkeybag;     /* shrouded key bag */
-+        STACK_OF(PKCS12_SAFEBAG) *safes;
-+        ASN1_TYPE *other;
-+    } value;
-+    STACK_OF(X509_ATTRIBUTE) *attrib;
-+};
-+
-+struct pkcs12_bag_st {
-+    ASN1_OBJECT *type;
-+    union {
-+        ASN1_OCTET_STRING *x509cert;
-+        ASN1_OCTET_STRING *x509crl;
-+        ASN1_OCTET_STRING *octet;
-+        ASN1_IA5STRING *sdsicert;
-+        ASN1_TYPE *other;       /* Secret or other bag */
-+    } value;
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c
-new file mode 100644
-index 0000000..d6b8919
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_mutl.c
-@@ -0,0 +1,239 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+# include 
-+# include "internal/cryptlib.h"
-+# include 
-+# include 
-+# include 
-+# include 
-+# include "p12_lcl.h"
-+
-+int PKCS12_mac_present(const PKCS12 *p12)
-+{
-+    return p12->mac ? 1 : 0;
-+}
-+
-+void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac,
-+                     const X509_ALGOR **pmacalg,
-+                     const ASN1_OCTET_STRING **psalt,
-+                     const ASN1_INTEGER **piter,
-+                     const PKCS12 *p12)
-+{
-+    if (p12->mac) {
-+        X509_SIG_get0(p12->mac->dinfo, pmacalg, pmac);
-+        if (psalt)
-+            *psalt = p12->mac->salt;
-+        if (piter)
-+            *piter = p12->mac->iter;
-+    } else {
-+        if (pmac)
-+            *pmac = NULL;
-+        if (pmacalg)
-+            *pmacalg = NULL;
-+        if (psalt)
-+            *psalt = NULL;
-+        if (piter)
-+            *piter = NULL;
-+    }
-+}
-+
-+# define TK26_MAC_KEY_LEN 32
-+
-+static int pkcs12_gen_gost_mac_key(const char *pass, int passlen,
-+                                   const unsigned char *salt, int saltlen,
-+                                   int iter, int keylen, unsigned char *key,
-+                                   const EVP_MD *digest)
-+{
-+    unsigned char out[96];
-+
-+    if (keylen != TK26_MAC_KEY_LEN) {
-+        return 0;
-+    }
-+
-+    if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter,
-+                           digest, sizeof(out), out)) {
-+        return 0;
-+    }
-+    memcpy(key, out + sizeof(out) - TK26_MAC_KEY_LEN, TK26_MAC_KEY_LEN);
-+    OPENSSL_cleanse(out, sizeof(out));
-+    return 1;
-+}
-+
-+/* Generate a MAC */
-+static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
-+                          unsigned char *mac, unsigned int *maclen,
-+                          int (*pkcs12_key_gen)(const char *pass, int passlen,
-+                                                unsigned char *salt, int slen,
-+                                                int id, int iter, int n,
-+                                                unsigned char *out,
-+                                                const EVP_MD *md_type))
-+{
-+    const EVP_MD *md_type;
-+    HMAC_CTX *hmac = NULL;
-+    unsigned char key[EVP_MAX_MD_SIZE], *salt;
-+    int saltlen, iter;
-+    int md_size = 0;
-+    int md_type_nid;
-+    const X509_ALGOR *macalg;
-+    const ASN1_OBJECT *macoid;
-+
-+    if (pkcs12_key_gen == NULL)
-+        pkcs12_key_gen = PKCS12_key_gen_utf8;
-+
-+    if (!PKCS7_type_is_data(p12->authsafes)) {
-+        PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA);
-+        return 0;
-+    }
-+
-+    salt = p12->mac->salt->data;
-+    saltlen = p12->mac->salt->length;
-+    if (!p12->mac->iter)
-+        iter = 1;
-+    else
-+        iter = ASN1_INTEGER_get(p12->mac->iter);
-+    X509_SIG_get0(p12->mac->dinfo, &macalg, NULL);
-+    X509_ALGOR_get0(&macoid, NULL, NULL, macalg);
-+    if ((md_type = EVP_get_digestbyobj(macoid)) == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
-+        return 0;
-+    }
-+    md_size = EVP_MD_size(md_type);
-+    md_type_nid = EVP_MD_type(md_type);
-+    if (md_size < 0)
-+        return 0;
-+    if ((md_type_nid == NID_id_GostR3411_94
-+         || md_type_nid == NID_id_GostR3411_2012_256
-+         || md_type_nid == NID_id_GostR3411_2012_512)
-+        && !getenv("LEGACY_GOST_PKCS12")) {
-+        md_size = TK26_MAC_KEY_LEN;
-+        if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter,
-+                                     md_size, key, md_type)) {
-+            PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR);
-+            return 0;
-+        }
-+    } else
-+        if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID,
-+                               iter, md_size, key, md_type)) {
-+        PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR);
-+        return 0;
-+    }
-+    hmac = HMAC_CTX_new();
-+    if (!HMAC_Init_ex(hmac, key, md_size, md_type, NULL)
-+        || !HMAC_Update(hmac, p12->authsafes->d.data->data,
-+                        p12->authsafes->d.data->length)
-+        || !HMAC_Final(hmac, mac, maclen)) {
-+        HMAC_CTX_free(hmac);
-+        return 0;
-+    }
-+    HMAC_CTX_free(hmac);
-+    return 1;
-+}
-+
-+int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
-+                   unsigned char *mac, unsigned int *maclen)
-+{
-+    return pkcs12_gen_mac(p12, pass, passlen, mac, maclen, NULL);
-+}
-+
-+/* Verify the mac */
-+int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
-+{
-+    unsigned char mac[EVP_MAX_MD_SIZE];
-+    unsigned int maclen;
-+    const ASN1_OCTET_STRING *macoct;
-+
-+    if (p12->mac == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT);
-+        return 0;
-+    }
-+    if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen,
-+                        PKCS12_key_gen_utf8)) {
-+        PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR);
-+        return 0;
-+    }
-+    X509_SIG_get0(p12->mac->dinfo, NULL, &macoct);
-+    if ((maclen != (unsigned int)ASN1_STRING_length(macoct))
-+        || CRYPTO_memcmp(mac, ASN1_STRING_get0_data(macoct), maclen) != 0)
-+        return 0;
-+
-+    return 1;
-+}
-+
-+/* Set a mac */
-+
-+int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
-+                   unsigned char *salt, int saltlen, int iter,
-+                   const EVP_MD *md_type)
-+{
-+    unsigned char mac[EVP_MAX_MD_SIZE];
-+    unsigned int maclen;
-+    ASN1_OCTET_STRING *macoct;
-+
-+    if (!md_type)
-+        md_type = EVP_sha1();
-+    if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) {
-+        PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR);
-+        return 0;
-+    }
-+    /*
-+     * Note that output mac is forced to UTF-8...
-+     */
-+    if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen,
-+                        PKCS12_key_gen_utf8)) {
-+        PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR);
-+        return 0;
-+    }
-+    X509_SIG_getm(p12->mac->dinfo, NULL, &macoct);
-+    if (!ASN1_OCTET_STRING_set(macoct, mac, maclen)) {
-+        PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR);
-+        return 0;
-+    }
-+    return 1;
-+}
-+
-+/* Set up a mac structure */
-+int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
-+                     const EVP_MD *md_type)
-+{
-+    X509_ALGOR *macalg;
-+
-+    if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL)
-+        return PKCS12_ERROR;
-+    if (iter > 1) {
-+        if ((p12->mac->iter = ASN1_INTEGER_new()) == NULL) {
-+            PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
-+            PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+    }
-+    if (!saltlen)
-+        saltlen = PKCS12_SALT_LEN;
-+    if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    p12->mac->salt->length = saltlen;
-+    if (!salt) {
-+        if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0)
-+            return 0;
-+    } else
-+        memcpy(p12->mac->salt->data, salt, saltlen);
-+    X509_SIG_getm(p12->mac->dinfo, &macalg, NULL);
-+    if (!X509_ALGOR_set0(macalg, OBJ_nid2obj(EVP_MD_type(md_type)),
-+                         V_ASN1_NULL, NULL)) {
-+        PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c
-new file mode 100644
-index 0000000..0ce75ed
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_npas.c
-@@ -0,0 +1,184 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "p12_lcl.h"
-+
-+/* PKCS#12 password change routine */
-+
-+static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass);
-+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
-+                        const char *newpass);
-+static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass,
-+                        const char *newpass);
-+static int alg_get(const X509_ALGOR *alg, int *pnid, int *piter,
-+                   int *psaltlen);
-+
-+/*
-+ * Change the password on a PKCS#12 structure.
-+ */
-+
-+int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass)
-+{
-+    /* Check for NULL PKCS12 structure */
-+
-+    if (!p12) {
-+        PKCS12err(PKCS12_F_PKCS12_NEWPASS,
-+                  PKCS12_R_INVALID_NULL_PKCS12_POINTER);
-+        return 0;
-+    }
-+
-+    /* Check the mac */
-+
-+    if (!PKCS12_verify_mac(p12, oldpass, -1)) {
-+        PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE);
-+        return 0;
-+    }
-+
-+    if (!newpass_p12(p12, oldpass, newpass)) {
-+        PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+/* Parse the outer PKCS#12 structure */
-+
-+static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass)
-+{
-+    STACK_OF(PKCS7) *asafes = NULL, *newsafes = NULL;
-+    STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
-+    int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
-+    PKCS7 *p7, *p7new;
-+    ASN1_OCTET_STRING *p12_data_tmp = NULL, *macoct = NULL;
-+    unsigned char mac[EVP_MAX_MD_SIZE];
-+    unsigned int maclen;
-+    int rv = 0;
-+
-+    if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
-+        goto err;
-+    if ((newsafes = sk_PKCS7_new_null()) == NULL)
-+        goto err;
-+    for (i = 0; i < sk_PKCS7_num(asafes); i++) {
-+        p7 = sk_PKCS7_value(asafes, i);
-+        bagnid = OBJ_obj2nid(p7->type);
-+        if (bagnid == NID_pkcs7_data) {
-+            bags = PKCS12_unpack_p7data(p7);
-+        } else if (bagnid == NID_pkcs7_encrypted) {
-+            bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
-+            if (!alg_get(p7->d.encrypted->enc_data->algorithm,
-+                         &pbe_nid, &pbe_iter, &pbe_saltlen))
-+                goto err;
-+        } else {
-+            continue;
-+        }
-+        if (bags == NULL)
-+            goto err;
-+        if (!newpass_bags(bags, oldpass, newpass))
-+            goto err;
-+        /* Repack bag in same form with new password */
-+        if (bagnid == NID_pkcs7_data)
-+            p7new = PKCS12_pack_p7data(bags);
-+        else
-+            p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL,
-+                                          pbe_saltlen, pbe_iter, bags);
-+        if (!p7new || !sk_PKCS7_push(newsafes, p7new))
-+            goto err;
-+        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-+        bags = NULL;
-+    }
-+
-+    /* Repack safe: save old safe in case of error */
-+
-+    p12_data_tmp = p12->authsafes->d.data;
-+    if ((p12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL)
-+        goto err;
-+    if (!PKCS12_pack_authsafes(p12, newsafes))
-+        goto err;
-+
-+    if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen))
-+        goto err;
-+    X509_SIG_getm(p12->mac->dinfo, NULL, &macoct);
-+    if (!ASN1_OCTET_STRING_set(macoct, mac, maclen))
-+        goto err;
-+
-+    rv = 1;
-+
-+err:
-+    /* Restore old safe if necessary */
-+    if (rv == 1) {
-+        ASN1_OCTET_STRING_free(p12_data_tmp);
-+    } else if (p12_data_tmp != NULL) {
-+        ASN1_OCTET_STRING_free(p12->authsafes->d.data);
-+        p12->authsafes->d.data = p12_data_tmp;
-+    }
-+    sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-+    sk_PKCS7_pop_free(asafes, PKCS7_free);
-+    sk_PKCS7_pop_free(newsafes, PKCS7_free);
-+    return rv;
-+}
-+
-+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
-+                        const char *newpass)
-+{
-+    int i;
-+    for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
-+        if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), oldpass, newpass))
-+            return 0;
-+    }
-+    return 1;
-+}
-+
-+/* Change password of safebag: only needs handle shrouded keybags */
-+
-+static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass,
-+                       const char *newpass)
-+{
-+    PKCS8_PRIV_KEY_INFO *p8;
-+    X509_SIG *p8new;
-+    int p8_nid, p8_saltlen, p8_iter;
-+    const X509_ALGOR *shalg;
-+
-+    if (PKCS12_SAFEBAG_get_nid(bag) != NID_pkcs8ShroudedKeyBag)
-+        return 1;
-+
-+    if ((p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)) == NULL)
-+        return 0;
-+    X509_SIG_get0(bag->value.shkeybag, &shalg, NULL);
-+    if (!alg_get(shalg, &p8_nid, &p8_iter, &p8_saltlen))
-+        return 0;
-+    p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
-+                          p8_iter, p8);
-+    PKCS8_PRIV_KEY_INFO_free(p8);
-+    if (p8new == NULL)
-+        return 0;
-+    X509_SIG_free(bag->value.shkeybag);
-+    bag->value.shkeybag = p8new;
-+    return 1;
-+}
-+
-+static int alg_get(const X509_ALGOR *alg, int *pnid, int *piter,
-+                   int *psaltlen)
-+{
-+    PBEPARAM *pbe;
-+    pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), alg->parameter);
-+    if (!pbe)
-+        return 0;
-+    *pnid = OBJ_obj2nid(alg->algorithm);
-+    *piter = ASN1_INTEGER_get(pbe->iter);
-+    *psaltlen = pbe->salt->length;
-+    PBEPARAM_free(pbe);
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_p8d.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_p8d.c
-new file mode 100644
-index 0000000..d926a77
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_p8d.c
-@@ -0,0 +1,23 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass,
-+                                   int passlen)
-+{
-+    const X509_ALGOR *dalg;
-+    const ASN1_OCTET_STRING *doct;
-+    X509_SIG_get0(p8, &dalg, &doct);
-+    return PKCS12_item_decrypt_d2i(dalg,
-+                                   ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass,
-+                                   passlen, doct, 1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_p8e.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_p8e.c
-new file mode 100644
-index 0000000..86a07e1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_p8e.c
-@@ -0,0 +1,69 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "internal/x509_int.h"
-+
-+X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
-+                        const char *pass, int passlen,
-+                        unsigned char *salt, int saltlen, int iter,
-+                        PKCS8_PRIV_KEY_INFO *p8inf)
-+{
-+    X509_SIG *p8 = NULL;
-+    X509_ALGOR *pbe;
-+
-+    if (pbe_nid == -1)
-+        pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
-+    else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0))
-+        pbe = PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, pbe_nid);
-+    else {
-+        ERR_clear_error();
-+        pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
-+    }
-+    if (!pbe) {
-+        PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
-+        return NULL;
-+    }
-+    p8 = PKCS8_set0_pbe(pass, passlen, p8inf, pbe);
-+    if (p8 == NULL) {
-+        X509_ALGOR_free(pbe);
-+        return NULL;
-+    }
-+
-+    return p8;
-+}
-+
-+X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
-+                         PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe)
-+{
-+    X509_SIG *p8;
-+    ASN1_OCTET_STRING *enckey;
-+
-+    enckey =
-+        PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
-+                                pass, passlen, p8inf, 1);
-+    if (!enckey) {
-+        PKCS12err(PKCS12_F_PKCS8_SET0_PBE, PKCS12_R_ENCRYPT_ERROR);
-+        return NULL;
-+    }
-+
-+    p8 = OPENSSL_zalloc(sizeof(*p8));
-+
-+    if (p8 == NULL) {
-+        PKCS12err(PKCS12_F_PKCS8_SET0_PBE, ERR_R_MALLOC_FAILURE);
-+        ASN1_OCTET_STRING_free(enckey);
-+        return NULL;
-+    }
-+    p8->algor = pbe;
-+    p8->digest = enckey;
-+
-+    return p8;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_sbag.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_sbag.c
-new file mode 100644
-index 0000000..4a3d259
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_sbag.c
-@@ -0,0 +1,170 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "p12_lcl.h"
-+
-+#if OPENSSL_API_COMPAT < 0x10100000L
-+ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid)
-+{
-+    return PKCS12_get_attr_gen(bag->attrib, attr_nid);
-+}
-+#endif
-+
-+const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag,
-+                                          int attr_nid)
-+{
-+    return PKCS12_get_attr_gen(bag->attrib, attr_nid);
-+}
-+
-+ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid)
-+{
-+    return PKCS12_get_attr_gen(PKCS8_pkey_get0_attrs(p8), attr_nid);
-+}
-+
-+const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag)
-+{
-+    if (PKCS12_SAFEBAG_get_nid(bag) != NID_keyBag)
-+        return NULL;
-+    return bag->value.keybag;
-+}
-+
-+const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag)
-+{
-+    if (OBJ_obj2nid(bag->type) != NID_pkcs8ShroudedKeyBag)
-+        return NULL;
-+    return bag->value.shkeybag;
-+}
-+
-+const STACK_OF(PKCS12_SAFEBAG) *
-+PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag)
-+{
-+    if (OBJ_obj2nid(bag->type) != NID_safeContentsBag)
-+        return NULL;
-+    return bag->value.safes;
-+}
-+
-+const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag)
-+{
-+    return bag->type;
-+}
-+
-+int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag)
-+{
-+    return OBJ_obj2nid(bag->type);
-+}
-+
-+int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag)
-+{
-+    int btype = PKCS12_SAFEBAG_get_nid(bag);
-+
-+    if (btype != NID_certBag && btype != NID_crlBag && btype != NID_secretBag)
-+        return -1;
-+    return OBJ_obj2nid(bag->value.bag->type);
-+}
-+
-+X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag)
-+{
-+    if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag)
-+        return NULL;
-+    if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate)
-+        return NULL;
-+    return ASN1_item_unpack(bag->value.bag->value.octet,
-+                            ASN1_ITEM_rptr(X509));
-+}
-+
-+X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag)
-+{
-+    if (PKCS12_SAFEBAG_get_nid(bag) != NID_crlBag)
-+        return NULL;
-+    if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl)
-+        return NULL;
-+    return ASN1_item_unpack(bag->value.bag->value.octet,
-+                            ASN1_ITEM_rptr(X509_CRL));
-+}
-+
-+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509)
-+{
-+    return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
-+                                    NID_x509Certificate, NID_certBag);
-+}
-+
-+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl)
-+{
-+    return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
-+                                    NID_x509Crl, NID_crlBag);
-+}
-+
-+/* Turn PKCS8 object into a keybag */
-+
-+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8)
-+{
-+    PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
-+
-+    if (bag == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    bag->type = OBJ_nid2obj(NID_keyBag);
-+    bag->value.keybag = p8;
-+    return bag;
-+}
-+
-+/* Turn PKCS8 object into a shrouded keybag */
-+
-+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8)
-+{
-+    PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
-+
-+    /* Set up the safe bag */
-+    if (bag == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+    bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
-+    bag->value.shkeybag = p8;
-+    return bag;
-+}
-+
-+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
-+                                                    const char *pass,
-+                                                    int passlen,
-+                                                    unsigned char *salt,
-+                                                    int saltlen, int iter,
-+                                                    PKCS8_PRIV_KEY_INFO *p8inf)
-+{
-+    PKCS12_SAFEBAG *bag;
-+    const EVP_CIPHER *pbe_ciph;
-+    X509_SIG *p8;
-+
-+    pbe_ciph = EVP_get_cipherbynid(pbe_nid);
-+
-+    if (pbe_ciph)
-+        pbe_nid = -1;
-+
-+    p8 = PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
-+                       p8inf);
-+
-+    if (p8 == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    bag = PKCS12_SAFEBAG_create0_pkcs8(p8);
-+
-+    if (bag == NULL) {
-+        PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+        X509_SIG_free(p8);
-+        return NULL;
-+    }
-+
-+    return bag;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_utl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_utl.c
-new file mode 100644
-index 0000000..0701478
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/p12_utl.c
-@@ -0,0 +1,237 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+
-+/* Cheap and nasty Unicode stuff */
-+
-+unsigned char *OPENSSL_asc2uni(const char *asc, int asclen,
-+                               unsigned char **uni, int *unilen)
-+{
-+    int ulen, i;
-+    unsigned char *unitmp;
-+
-+    if (asclen == -1)
-+        asclen = strlen(asc);
-+    ulen = asclen * 2 + 2;
-+    if ((unitmp = OPENSSL_malloc(ulen)) == NULL)
-+        return NULL;
-+    for (i = 0; i < ulen - 2; i += 2) {
-+        unitmp[i] = 0;
-+        unitmp[i + 1] = asc[i >> 1];
-+    }
-+    /* Make result double null terminated */
-+    unitmp[ulen - 2] = 0;
-+    unitmp[ulen - 1] = 0;
-+    if (unilen)
-+        *unilen = ulen;
-+    if (uni)
-+        *uni = unitmp;
-+    return unitmp;
-+}
-+
-+char *OPENSSL_uni2asc(const unsigned char *uni, int unilen)
-+{
-+    int asclen, i;
-+    char *asctmp;
-+    /* string must contain an even number of bytes */
-+    if (unilen & 1)
-+        return NULL;
-+    asclen = unilen / 2;
-+    /* If no terminating zero allow for one */
-+    if (!unilen || uni[unilen - 1])
-+        asclen++;
-+    uni++;
-+    if ((asctmp = OPENSSL_malloc(asclen)) == NULL)
-+        return NULL;
-+    for (i = 0; i < unilen; i += 2)
-+        asctmp[i >> 1] = uni[i];
-+    asctmp[asclen - 1] = 0;
-+    return asctmp;
-+}
-+
-+/*
-+ * OPENSSL_{utf82uni|uni2utf8} perform conversion between UTF-8 and
-+ * PKCS#12 BMPString format, which is specified as big-endian UTF-16.
-+ * One should keep in mind that even though BMPString is passed as
-+ * unsigned char *, it's not the kind of string you can exercise e.g.
-+ * strlen on. Caller also has to keep in mind that its length is
-+ * expressed not in number of UTF-16 characters, but in number of
-+ * bytes the string occupies, and treat it, the length, accordingly.
-+ */
-+unsigned char *OPENSSL_utf82uni(const char *asc, int asclen,
-+                                unsigned char **uni, int *unilen)
-+{
-+    int ulen, i, j;
-+    unsigned char *unitmp, *ret;
-+    unsigned long utf32chr = 0;
-+
-+    if (asclen == -1)
-+        asclen = strlen(asc);
-+
-+    for (ulen = 0, i = 0; i < asclen; i += j) {
-+        j = UTF8_getc((const unsigned char *)asc+i, asclen-i, &utf32chr);
-+
-+        /*
-+         * Following condition is somewhat opportunistic is sense that
-+         * decoding failure is used as *indirect* indication that input
-+         * string might in fact be extended ASCII/ANSI/ISO-8859-X. The
-+         * fallback is taken in hope that it would allow to process
-+         * files created with previous OpenSSL version, which used the
-+         * naive OPENSSL_asc2uni all along. It might be worth noting
-+         * that probability of false positive depends on language. In
-+         * cases covered by ISO Latin 1 probability is very low, because
-+         * any printable non-ASCII alphabet letter followed by another
-+         * or any ASCII character will trigger failure and fallback.
-+         * In other cases situation can be intensified by the fact that
-+         * English letters are not part of alternative keyboard layout,
-+         * but even then there should be plenty of pairs that trigger
-+         * decoding failure...
-+         */
-+        if (j < 0)
-+	    return OPENSSL_asc2uni(asc, asclen, uni, unilen);
-+
-+        if (utf32chr > 0x10FFFF)        /* UTF-16 cap */
-+	    return NULL;
-+
-+        if (utf32chr >= 0x10000)        /* pair of UTF-16 characters */
-+            ulen += 2*2;
-+        else                            /* or just one */
-+            ulen += 2;
-+    }
-+
-+    ulen += 2;  /* for trailing UTF16 zero */
-+
-+    if ((ret = OPENSSL_malloc(ulen)) == NULL)
-+        return NULL;
-+
-+    /* re-run the loop writing down UTF-16 characters in big-endian order */
-+    for (unitmp = ret, i = 0; i < asclen; i += j) {
-+        j = UTF8_getc((const unsigned char *)asc+i, asclen-i, &utf32chr);
-+        if (utf32chr >= 0x10000) {      /* pair if UTF-16 characters */
-+            unsigned int hi, lo;
-+
-+            utf32chr -= 0x10000;
-+            hi = 0xD800 + (utf32chr>>10);
-+            lo = 0xDC00 + (utf32chr&0x3ff);
-+            *unitmp++ = (unsigned char)(hi>>8);
-+            *unitmp++ = (unsigned char)(hi);
-+            *unitmp++ = (unsigned char)(lo>>8);
-+            *unitmp++ = (unsigned char)(lo);
-+        } else {                        /* or just one */
-+            *unitmp++ = (unsigned char)(utf32chr>>8);
-+            *unitmp++ = (unsigned char)(utf32chr);
-+        }
-+    }
-+    /* Make result double null terminated */
-+    *unitmp++ = 0;
-+    *unitmp++ = 0;
-+    if (unilen)
-+        *unilen = ulen;
-+    if (uni)
-+        *uni = ret;
-+    return ret;
-+}
-+
-+static int bmp_to_utf8(char *str, const unsigned char *utf16, int len)
-+{
-+    unsigned long utf32chr;
-+
-+    if (len == 0) return 0;
-+
-+    if (len < 2) return -1;
-+
-+    /* pull UTF-16 character in big-endian order */
-+    utf32chr = (utf16[0]<<8) | utf16[1];
-+
-+    if (utf32chr >= 0xD800 && utf32chr < 0xE000) {   /* two chars */
-+        unsigned int lo;
-+
-+        if (len < 4) return -1;
-+
-+        utf32chr -= 0xD800;
-+        utf32chr <<= 10;
-+        lo = (utf16[2]<<8) | utf16[3];
-+        if (lo < 0xDC00 || lo >= 0xE000) return -1;
-+        utf32chr |= lo-0xDC00;
-+        utf32chr += 0x10000;
-+    }
-+
-+    return UTF8_putc((unsigned char *)str, len > 4 ? 4 : len, utf32chr);
-+}
-+
-+char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen)
-+{
-+    int asclen, i, j;
-+    char *asctmp;
-+
-+    /* string must contain an even number of bytes */
-+    if (unilen & 1)
-+        return NULL;
-+
-+    for (asclen = 0, i = 0; i < unilen; ) {
-+        j = bmp_to_utf8(NULL, uni+i, unilen-i);
-+        /*
-+         * falling back to OPENSSL_uni2asc makes lesser sense [than
-+         * falling back to OPENSSL_asc2uni in OPENSSL_utf82uni above],
-+         * it's done rather to maintain symmetry...
-+         */
-+        if (j < 0) return OPENSSL_uni2asc(uni, unilen);
-+        if (j == 4) i += 4;
-+        else        i += 2;
-+        asclen += j;
-+    }
-+
-+    /* If no terminating zero allow for one */
-+    if (!unilen || (uni[unilen-2]||uni[unilen - 1]))
-+        asclen++;
-+
-+    if ((asctmp = OPENSSL_malloc(asclen)) == NULL)
-+        return NULL;
-+
-+    /* re-run the loop emitting UTF-8 string */
-+    for (asclen = 0, i = 0; i < unilen; ) {
-+        j = bmp_to_utf8(asctmp+asclen, uni+i, unilen-i);
-+        if (j == 4) i += 4;
-+        else        i += 2;
-+        asclen += j;
-+    }
-+
-+    /* If no terminating zero write one */
-+    if (!unilen || (uni[unilen-2]||uni[unilen - 1]))
-+        asctmp[asclen] = '\0';
-+
-+    return asctmp;
-+}
-+
-+int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12)
-+{
-+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12)
-+{
-+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
-+}
-+#endif
-+
-+PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12)
-+{
-+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
-+}
-+
-+#ifndef OPENSSL_NO_STDIO
-+PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12)
-+{
-+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/pk12err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/pk12err.c
-new file mode 100644
-index 0000000..f705084
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs12/pk12err.c
-@@ -0,0 +1,95 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS12,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS12,0,reason)
-+
-+static ERR_STRING_DATA PKCS12_str_functs[] = {
-+    {ERR_FUNC(PKCS12_F_PKCS12_CREATE), "PKCS12_create"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_GEN_MAC), "PKCS12_gen_mac"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_INIT), "PKCS12_init"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I), "PKCS12_item_decrypt_d2i"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT), "PKCS12_item_i2d_encrypt"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG), "PKCS12_item_pack_safebag"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_ASC), "PKCS12_key_gen_asc"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UNI), "PKCS12_key_gen_uni"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UTF8), "PKCS12_key_gen_utf8"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_NEWPASS), "PKCS12_newpass"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7DATA), "PKCS12_pack_p7data"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7ENCDATA), "PKCS12_pack_p7encdata"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_PARSE), "PKCS12_parse"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_PBE_CRYPT), "PKCS12_pbe_crypt"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_PBE_KEYIVGEN), "PKCS12_PBE_keyivgen"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF),
-+     "PKCS12_SAFEBAG_create0_p8inf"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8),
-+     "PKCS12_SAFEBAG_create0_pkcs8"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT),
-+     "PKCS12_SAFEBAG_create_pkcs8_encrypt"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_SETUP_MAC), "PKCS12_setup_mac"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_SET_MAC), "PKCS12_set_mac"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_AUTHSAFES), "PKCS12_unpack_authsafes"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_P7DATA), "PKCS12_unpack_p7data"},
-+    {ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC), "PKCS12_verify_mac"},
-+    {ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"},
-+    {ERR_FUNC(PKCS12_F_PKCS8_SET0_PBE), "PKCS8_set0_pbe"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA PKCS12_str_reasons[] = {
-+    {ERR_REASON(PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"},
-+    {ERR_REASON(PKCS12_R_CONTENT_TYPE_NOT_DATA), "content type not data"},
-+    {ERR_REASON(PKCS12_R_DECODE_ERROR), "decode error"},
-+    {ERR_REASON(PKCS12_R_ENCODE_ERROR), "encode error"},
-+    {ERR_REASON(PKCS12_R_ENCRYPT_ERROR), "encrypt error"},
-+    {ERR_REASON(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE),
-+     "error setting encrypted data type"},
-+    {ERR_REASON(PKCS12_R_INVALID_NULL_ARGUMENT), "invalid null argument"},
-+    {ERR_REASON(PKCS12_R_INVALID_NULL_PKCS12_POINTER),
-+     "invalid null pkcs12 pointer"},
-+    {ERR_REASON(PKCS12_R_IV_GEN_ERROR), "iv gen error"},
-+    {ERR_REASON(PKCS12_R_KEY_GEN_ERROR), "key gen error"},
-+    {ERR_REASON(PKCS12_R_MAC_ABSENT), "mac absent"},
-+    {ERR_REASON(PKCS12_R_MAC_GENERATION_ERROR), "mac generation error"},
-+    {ERR_REASON(PKCS12_R_MAC_SETUP_ERROR), "mac setup error"},
-+    {ERR_REASON(PKCS12_R_MAC_STRING_SET_ERROR), "mac string set error"},
-+    {ERR_REASON(PKCS12_R_MAC_VERIFY_FAILURE), "mac verify failure"},
-+    {ERR_REASON(PKCS12_R_PARSE_ERROR), "parse error"},
-+    {ERR_REASON(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR),
-+     "pkcs12 algor cipherinit error"},
-+    {ERR_REASON(PKCS12_R_PKCS12_CIPHERFINAL_ERROR),
-+     "pkcs12 cipherfinal error"},
-+    {ERR_REASON(PKCS12_R_PKCS12_PBE_CRYPT_ERROR), "pkcs12 pbe crypt error"},
-+    {ERR_REASON(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM),
-+     "unknown digest algorithm"},
-+    {ERR_REASON(PKCS12_R_UNSUPPORTED_PKCS12_MODE), "unsupported pkcs12 mode"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_PKCS12_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, PKCS12_str_functs);
-+        ERR_load_strings(0, PKCS12_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/bio_pk7.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/bio_pk7.c
-new file mode 100644
-index 0000000..29feaa3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/bio_pk7.c
-@@ -0,0 +1,24 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+#if !defined(OPENSSL_SYS_VXWORKS)
-+# include 
-+#endif
-+#include 
-+
-+/* Streaming encode support for PKCS#7 */
-+
-+BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7)
-+{
-+    return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/build.info
-new file mode 100644
-index 0000000..2029d53
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/build.info
-@@ -0,0 +1,4 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        pk7_asn1.c pk7_lib.c pkcs7err.c pk7_doit.c pk7_smime.c pk7_attr.c \
-+        pk7_mime.c bio_pk7.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_asn1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_asn1.c
-new file mode 100644
-index 0000000..315e1b8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_asn1.c
-@@ -0,0 +1,201 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+/* PKCS#7 ASN1 module */
-+
-+/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */
-+
-+ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0);
-+
-+ASN1_ADB(PKCS7) = {
-+        ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING_NDEF, 0)),
-+        ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)),
-+        ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)),
-+        ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)),
-+        ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)),
-+        ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0))
-+} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL);
-+
-+/* PKCS#7 streaming support */
-+static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                  void *exarg)
-+{
-+    ASN1_STREAM_ARG *sarg = exarg;
-+    PKCS7 **pp7 = (PKCS7 **)pval;
-+
-+    switch (operation) {
-+
-+    case ASN1_OP_STREAM_PRE:
-+        if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
-+            return 0;
-+    case ASN1_OP_DETACHED_PRE:
-+        sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
-+        if (!sarg->ndef_bio)
-+            return 0;
-+        break;
-+
-+    case ASN1_OP_STREAM_POST:
-+    case ASN1_OP_DETACHED_POST:
-+        if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
-+            return 0;
-+        break;
-+
-+    }
-+    return 1;
-+}
-+
-+ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = {
-+        ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT),
-+        ASN1_ADB_OBJECT(PKCS7)
-+}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
-+
-+IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7)
-+
-+IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7)
-+
-+ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = {
-+        ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER),
-+        ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR),
-+        ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7),
-+        ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0),
-+        ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1),
-+        ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO)
-+} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGNED)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED)
-+
-+/* Minor tweak to operation: free up EVP_PKEY */
-+static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                 void *exarg)
-+{
-+    if (operation == ASN1_OP_FREE_POST) {
-+        PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
-+        EVP_PKEY_free(si->pkey);
-+    }
-+    return 1;
-+}
-+
-+ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = {
-+        ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER),
-+        ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
-+        ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR),
-+        /* NB this should be a SET OF but we use a SEQUENCE OF so the
-+         * original order * is retained when the structure is reencoded.
-+         * Since the attributes are implicitly tagged this will not affect
-+         * the encoding.
-+         */
-+        ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0),
-+        ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR),
-+        ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING),
-+        ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1)
-+} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
-+
-+ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = {
-+        ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME),
-+        ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER)
-+} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
-+
-+ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = {
-+        ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER),
-+        ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
-+        ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT)
-+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENVELOPE)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
-+
-+/* Minor tweak to operation: free up X509 */
-+static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                 void *exarg)
-+{
-+    if (operation == ASN1_OP_FREE_POST) {
-+        PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
-+        X509_free(ri->cert);
-+    }
-+    return 1;
-+}
-+
-+ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = {
-+        ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER),
-+        ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
-+        ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR),
-+        ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING)
-+} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
-+
-+ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = {
-+        ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT),
-+        ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR),
-+        ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0)
-+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
-+
-+ASN1_NDEF_SEQUENCE(PKCS7_SIGN_ENVELOPE) = {
-+        ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER),
-+        ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
-+        ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR),
-+        ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT),
-+        ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0),
-+        ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1),
-+        ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO)
-+} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGN_ENVELOPE)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
-+
-+ASN1_NDEF_SEQUENCE(PKCS7_ENCRYPT) = {
-+        ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER),
-+        ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT)
-+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENCRYPT)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
-+
-+ASN1_NDEF_SEQUENCE(PKCS7_DIGEST) = {
-+        ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER),
-+        ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR),
-+        ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7),
-+        ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING)
-+} ASN1_NDEF_SEQUENCE_END(PKCS7_DIGEST)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST)
-+
-+/* Specials for authenticated attributes */
-+
-+/*
-+ * When signing attributes we want to reorder them to match the sorted
-+ * encoding.
-+ */
-+
-+ASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) =
-+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
-+ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN)
-+
-+/*
-+ * When verifying attributes we need to use the received order. So we use
-+ * SEQUENCE OF and tag it to SET OF
-+ */
-+
-+ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) =
-+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
-+                                V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
-+ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY)
-+
-+IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_attr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_attr.c
-new file mode 100644
-index 0000000..e90bf03
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_attr.c
-@@ -0,0 +1,121 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
-+                              STACK_OF(X509_ALGOR) *cap)
-+{
-+    ASN1_STRING *seq;
-+
-+    if ((seq = ASN1_STRING_new()) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data,
-+                                ASN1_ITEM_rptr(X509_ALGORS));
-+    return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
-+                                      V_ASN1_SEQUENCE, seq);
-+}
-+
-+STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
-+{
-+    ASN1_TYPE *cap;
-+    const unsigned char *p;
-+
-+    cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
-+    if (cap == NULL || (cap->type != V_ASN1_SEQUENCE))
-+        return NULL;
-+    p = cap->value.sequence->data;
-+    return (STACK_OF(X509_ALGOR) *)
-+        ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
-+                      ASN1_ITEM_rptr(X509_ALGORS));
-+}
-+
-+/* Basic smime-capabilities OID and optional integer arg */
-+int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
-+{
-+    ASN1_INTEGER *nbit = NULL;
-+    X509_ALGOR *alg;
-+
-+    if ((alg = X509_ALGOR_new()) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ASN1_OBJECT_free(alg->algorithm);
-+    alg->algorithm = OBJ_nid2obj(nid);
-+    if (arg > 0) {
-+        if ((alg->parameter = ASN1_TYPE_new()) == NULL) {
-+            goto err;
-+        }
-+        if ((nbit = ASN1_INTEGER_new()) == NULL) {
-+            goto err;
-+        }
-+        if (!ASN1_INTEGER_set(nbit, arg)) {
-+            goto err;
-+        }
-+        alg->parameter->value.integer = nbit;
-+        alg->parameter->type = V_ASN1_INTEGER;
-+        nbit = NULL;
-+    }
-+    if (!sk_X509_ALGOR_push(sk, alg)) {
-+        goto err;
-+    }
-+    return 1;
-+err:
-+    PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE);
-+    ASN1_INTEGER_free(nbit);
-+    X509_ALGOR_free(alg);
-+    return 0;
-+}
-+
-+int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
-+{
-+    if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
-+        return 0;
-+    if (!coid)
-+        coid = OBJ_nid2obj(NID_pkcs7_data);
-+    return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
-+                                      V_ASN1_OBJECT, coid);
-+}
-+
-+int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
-+{
-+    if (t == NULL && (t = X509_gmtime_adj(NULL, 0)) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME,
-+                 ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
-+                                      V_ASN1_UTCTIME, t);
-+}
-+
-+int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
-+                             const unsigned char *md, int mdlen)
-+{
-+    ASN1_OCTET_STRING *os;
-+    os = ASN1_OCTET_STRING_new();
-+    if (os == NULL)
-+        return 0;
-+    if (!ASN1_STRING_set(os, md, mdlen)
-+        || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
-+                                       V_ASN1_OCTET_STRING, os)) {
-+        ASN1_OCTET_STRING_free(os);
-+        return 0;
-+    }
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_dgst.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_dgst.c
-new file mode 100644
-index 0000000..965fb37
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_dgst.c
-@@ -0,0 +1,15 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_doit.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_doit.c
-new file mode 100644
-index 0000000..bc6bd30
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_doit.c
-@@ -0,0 +1,1178 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
-+                         void *value);
-+static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
-+
-+static int PKCS7_type_is_other(PKCS7 *p7)
-+{
-+    int isOther = 1;
-+
-+    int nid = OBJ_obj2nid(p7->type);
-+
-+    switch (nid) {
-+    case NID_pkcs7_data:
-+    case NID_pkcs7_signed:
-+    case NID_pkcs7_enveloped:
-+    case NID_pkcs7_signedAndEnveloped:
-+    case NID_pkcs7_digest:
-+    case NID_pkcs7_encrypted:
-+        isOther = 0;
-+        break;
-+    default:
-+        isOther = 1;
-+    }
-+
-+    return isOther;
-+
-+}
-+
-+static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
-+{
-+    if (PKCS7_type_is_data(p7))
-+        return p7->d.data;
-+    if (PKCS7_type_is_other(p7) && p7->d.other
-+        && (p7->d.other->type == V_ASN1_OCTET_STRING))
-+        return p7->d.other->value.octet_string;
-+    return NULL;
-+}
-+
-+static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
-+{
-+    BIO *btmp;
-+    const EVP_MD *md;
-+    if ((btmp = BIO_new(BIO_f_md())) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
-+        goto err;
-+    }
-+
-+    md = EVP_get_digestbyobj(alg->algorithm);
-+    if (md == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE);
-+        goto err;
-+    }
-+
-+    BIO_set_md(btmp, md);
-+    if (*pbio == NULL)
-+        *pbio = btmp;
-+    else if (!BIO_push(*pbio, btmp)) {
-+        PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
-+        goto err;
-+    }
-+    btmp = NULL;
-+
-+    return 1;
-+
-+ err:
-+    BIO_free(btmp);
-+    return 0;
-+
-+}
-+
-+static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
-+                              unsigned char *key, int keylen)
-+{
-+    EVP_PKEY_CTX *pctx = NULL;
-+    EVP_PKEY *pkey = NULL;
-+    unsigned char *ek = NULL;
-+    int ret = 0;
-+    size_t eklen;
-+
-+    pkey = X509_get0_pubkey(ri->cert);
-+
-+    if (!pkey)
-+        return 0;
-+
-+    pctx = EVP_PKEY_CTX_new(pkey, NULL);
-+    if (!pctx)
-+        return 0;
-+
-+    if (EVP_PKEY_encrypt_init(pctx) <= 0)
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
-+                          EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) {
-+        PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
-+        goto err;
-+    }
-+
-+    if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
-+        goto err;
-+
-+    ek = OPENSSL_malloc(eklen);
-+
-+    if (ek == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
-+        goto err;
-+
-+    ASN1_STRING_set0(ri->enc_key, ek, eklen);
-+    ek = NULL;
-+
-+    ret = 1;
-+
-+ err:
-+    EVP_PKEY_CTX_free(pctx);
-+    OPENSSL_free(ek);
-+    return ret;
-+
-+}
-+
-+static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
-+                               PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
-+{
-+    EVP_PKEY_CTX *pctx = NULL;
-+    unsigned char *ek = NULL;
-+    size_t eklen;
-+
-+    int ret = -1;
-+
-+    pctx = EVP_PKEY_CTX_new(pkey, NULL);
-+    if (!pctx)
-+        return -1;
-+
-+    if (EVP_PKEY_decrypt_init(pctx) <= 0)
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
-+                          EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) {
-+        PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
-+        goto err;
-+    }
-+
-+    if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
-+                         ri->enc_key->data, ri->enc_key->length) <= 0)
-+        goto err;
-+
-+    ek = OPENSSL_malloc(eklen);
-+
-+    if (ek == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (EVP_PKEY_decrypt(pctx, ek, &eklen,
-+                         ri->enc_key->data, ri->enc_key->length) <= 0) {
-+        ret = 0;
-+        PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
-+        goto err;
-+    }
-+
-+    ret = 1;
-+
-+    OPENSSL_clear_free(*pek, *peklen);
-+    *pek = ek;
-+    *peklen = eklen;
-+
-+ err:
-+    EVP_PKEY_CTX_free(pctx);
-+    if (!ret)
-+        OPENSSL_free(ek);
-+
-+    return ret;
-+}
-+
-+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
-+{
-+    int i;
-+    BIO *out = NULL, *btmp = NULL;
-+    X509_ALGOR *xa = NULL;
-+    const EVP_CIPHER *evp_cipher = NULL;
-+    STACK_OF(X509_ALGOR) *md_sk = NULL;
-+    STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
-+    X509_ALGOR *xalg = NULL;
-+    PKCS7_RECIP_INFO *ri = NULL;
-+    ASN1_OCTET_STRING *os = NULL;
-+
-+    if (p7 == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
-+        return NULL;
-+    }
-+    /*
-+     * The content field in the PKCS7 ContentInfo is optional, but that really
-+     * only applies to inner content (precisely, detached signatures).
-+     *
-+     * When reading content, missing outer content is therefore treated as an
-+     * error.
-+     *
-+     * When creating content, PKCS7_content_new() must be called before
-+     * calling this method, so a NULL p7->d is always an error.
-+     */
-+    if (p7->d.ptr == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
-+        return NULL;
-+    }
-+
-+    i = OBJ_obj2nid(p7->type);
-+    p7->state = PKCS7_S_HEADER;
-+
-+    switch (i) {
-+    case NID_pkcs7_signed:
-+        md_sk = p7->d.sign->md_algs;
-+        os = PKCS7_get_octet_string(p7->d.sign->contents);
-+        break;
-+    case NID_pkcs7_signedAndEnveloped:
-+        rsk = p7->d.signed_and_enveloped->recipientinfo;
-+        md_sk = p7->d.signed_and_enveloped->md_algs;
-+        xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
-+        evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
-+        if (evp_cipher == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
-+            goto err;
-+        }
-+        break;
-+    case NID_pkcs7_enveloped:
-+        rsk = p7->d.enveloped->recipientinfo;
-+        xalg = p7->d.enveloped->enc_data->algorithm;
-+        evp_cipher = p7->d.enveloped->enc_data->cipher;
-+        if (evp_cipher == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
-+            goto err;
-+        }
-+        break;
-+    case NID_pkcs7_digest:
-+        xa = p7->d.digest->md;
-+        os = PKCS7_get_octet_string(p7->d.digest->contents);
-+        break;
-+    case NID_pkcs7_data:
-+        break;
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
-+        goto err;
-+    }
-+
-+    for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
-+        if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
-+            goto err;
-+
-+    if (xa && !PKCS7_bio_add_digest(&out, xa))
-+        goto err;
-+
-+    if (evp_cipher != NULL) {
-+        unsigned char key[EVP_MAX_KEY_LENGTH];
-+        unsigned char iv[EVP_MAX_IV_LENGTH];
-+        int keylen, ivlen;
-+        EVP_CIPHER_CTX *ctx;
-+
-+        if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
-+            goto err;
-+        }
-+        BIO_get_cipher_ctx(btmp, &ctx);
-+        keylen = EVP_CIPHER_key_length(evp_cipher);
-+        ivlen = EVP_CIPHER_iv_length(evp_cipher);
-+        xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
-+        if (ivlen > 0)
-+            if (RAND_bytes(iv, ivlen) <= 0)
-+                goto err;
-+        if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0)
-+            goto err;
-+        if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
-+            goto err;
-+        if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
-+            goto err;
-+
-+        if (ivlen > 0) {
-+            if (xalg->parameter == NULL) {
-+                xalg->parameter = ASN1_TYPE_new();
-+                if (xalg->parameter == NULL)
-+                    goto err;
-+            }
-+            if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
-+                goto err;
-+        }
-+
-+        /* Lets do the pub key stuff :-) */
-+        for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
-+            ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
-+            if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
-+                goto err;
-+        }
-+        OPENSSL_cleanse(key, keylen);
-+
-+        if (out == NULL)
-+            out = btmp;
-+        else
-+            BIO_push(out, btmp);
-+        btmp = NULL;
-+    }
-+
-+    if (bio == NULL) {
-+        if (PKCS7_is_detached(p7))
-+            bio = BIO_new(BIO_s_null());
-+        else if (os && os->length > 0)
-+            bio = BIO_new_mem_buf(os->data, os->length);
-+        if (bio == NULL) {
-+            bio = BIO_new(BIO_s_mem());
-+            if (bio == NULL)
-+                goto err;
-+            BIO_set_mem_eof_return(bio, 0);
-+        }
-+    }
-+    if (out)
-+        BIO_push(out, bio);
-+    else
-+        out = bio;
-+    return out;
-+
-+ err:
-+    BIO_free_all(out);
-+    BIO_free_all(btmp);
-+    return NULL;
-+}
-+
-+static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
-+{
-+    int ret;
-+    ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
-+                        X509_get_issuer_name(pcert));
-+    if (ret)
-+        return ret;
-+    return ASN1_INTEGER_cmp(X509_get_serialNumber(pcert),
-+                            ri->issuer_and_serial->serial);
-+}
-+
-+/* int */
-+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
-+{
-+    int i, j;
-+    BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
-+    X509_ALGOR *xa;
-+    ASN1_OCTET_STRING *data_body = NULL;
-+    const EVP_MD *evp_md;
-+    const EVP_CIPHER *evp_cipher = NULL;
-+    EVP_CIPHER_CTX *evp_ctx = NULL;
-+    X509_ALGOR *enc_alg = NULL;
-+    STACK_OF(X509_ALGOR) *md_sk = NULL;
-+    STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
-+    PKCS7_RECIP_INFO *ri = NULL;
-+    unsigned char *ek = NULL, *tkey = NULL;
-+    int eklen = 0, tkeylen = 0;
-+
-+    if (p7 == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER);
-+        return NULL;
-+    }
-+
-+    if (p7->d.ptr == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
-+        return NULL;
-+    }
-+
-+    i = OBJ_obj2nid(p7->type);
-+    p7->state = PKCS7_S_HEADER;
-+
-+    switch (i) {
-+    case NID_pkcs7_signed:
-+        /*
-+         * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
-+         * field and optional content.
-+         * data_body is NULL if that structure has no (=detached) content
-+         * or if the contentType is wrong (i.e., not "data").
-+         */
-+        data_body = PKCS7_get_octet_string(p7->d.sign->contents);
-+        if (!PKCS7_is_detached(p7) && data_body == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_DATADECODE,
-+                     PKCS7_R_INVALID_SIGNED_DATA_TYPE);
-+            goto err;
-+        }
-+        md_sk = p7->d.sign->md_algs;
-+        break;
-+    case NID_pkcs7_signedAndEnveloped:
-+        rsk = p7->d.signed_and_enveloped->recipientinfo;
-+        md_sk = p7->d.signed_and_enveloped->md_algs;
-+        /* data_body is NULL if the optional EncryptedContent is missing. */
-+        data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
-+        enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
-+        evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
-+        if (evp_cipher == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_DATADECODE,
-+                     PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
-+            goto err;
-+        }
-+        break;
-+    case NID_pkcs7_enveloped:
-+        rsk = p7->d.enveloped->recipientinfo;
-+        enc_alg = p7->d.enveloped->enc_data->algorithm;
-+        /* data_body is NULL if the optional EncryptedContent is missing. */
-+        data_body = p7->d.enveloped->enc_data->enc_data;
-+        evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
-+        if (evp_cipher == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_DATADECODE,
-+                     PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
-+            goto err;
-+        }
-+        break;
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
-+        goto err;
-+    }
-+
-+    /* Detached content must be supplied via in_bio instead. */
-+    if (data_body == NULL && in_bio == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
-+        goto err;
-+    }
-+
-+    /* We will be checking the signature */
-+    if (md_sk != NULL) {
-+        for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
-+            xa = sk_X509_ALGOR_value(md_sk, i);
-+            if ((btmp = BIO_new(BIO_f_md())) == NULL) {
-+                PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
-+                goto err;
-+            }
-+
-+            j = OBJ_obj2nid(xa->algorithm);
-+            evp_md = EVP_get_digestbynid(j);
-+            if (evp_md == NULL) {
-+                PKCS7err(PKCS7_F_PKCS7_DATADECODE,
-+                         PKCS7_R_UNKNOWN_DIGEST_TYPE);
-+                goto err;
-+            }
-+
-+            BIO_set_md(btmp, evp_md);
-+            if (out == NULL)
-+                out = btmp;
-+            else
-+                BIO_push(out, btmp);
-+            btmp = NULL;
-+        }
-+    }
-+
-+    if (evp_cipher != NULL) {
-+        if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
-+            goto err;
-+        }
-+
-+        /*
-+         * It was encrypted, we need to decrypt the secret key with the
-+         * private key
-+         */
-+
-+        /*
-+         * Find the recipientInfo which matches the passed certificate (if
-+         * any)
-+         */
-+
-+        if (pcert) {
-+            for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
-+                ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
-+                if (!pkcs7_cmp_ri(ri, pcert))
-+                    break;
-+                ri = NULL;
-+            }
-+            if (ri == NULL) {
-+                PKCS7err(PKCS7_F_PKCS7_DATADECODE,
-+                         PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
-+                goto err;
-+            }
-+        }
-+
-+        /* If we haven't got a certificate try each ri in turn */
-+        if (pcert == NULL) {
-+            /*
-+             * Always attempt to decrypt all rinfo even after success as a
-+             * defence against MMA timing attacks.
-+             */
-+            for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
-+                ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
-+
-+                if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
-+                    goto err;
-+                ERR_clear_error();
-+            }
-+        } else {
-+            /* Only exit on fatal errors, not decrypt failure */
-+            if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
-+                goto err;
-+            ERR_clear_error();
-+        }
-+
-+        evp_ctx = NULL;
-+        BIO_get_cipher_ctx(etmp, &evp_ctx);
-+        if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0)
-+            goto err;
-+        if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
-+            goto err;
-+        /* Generate random key as MMA defence */
-+        tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
-+        tkey = OPENSSL_malloc(tkeylen);
-+        if (tkey == NULL)
-+            goto err;
-+        if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
-+            goto err;
-+        if (ek == NULL) {
-+            ek = tkey;
-+            eklen = tkeylen;
-+            tkey = NULL;
-+        }
-+
-+        if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
-+            /*
-+             * Some S/MIME clients don't use the same key and effective key
-+             * length. The key length is determined by the size of the
-+             * decrypted RSA key.
-+             */
-+            if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) {
-+                /* Use random key as MMA defence */
-+                OPENSSL_clear_free(ek, eklen);
-+                ek = tkey;
-+                eklen = tkeylen;
-+                tkey = NULL;
-+            }
-+        }
-+        /* Clear errors so we don't leak information useful in MMA */
-+        ERR_clear_error();
-+        if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0)
-+            goto err;
-+
-+        OPENSSL_clear_free(ek, eklen);
-+        ek = NULL;
-+        OPENSSL_clear_free(tkey, tkeylen);
-+        tkey = NULL;
-+
-+        if (out == NULL)
-+            out = etmp;
-+        else
-+            BIO_push(out, etmp);
-+        etmp = NULL;
-+    }
-+    if (in_bio != NULL) {
-+        bio = in_bio;
-+    } else {
-+        if (data_body->length > 0)
-+            bio = BIO_new_mem_buf(data_body->data, data_body->length);
-+        else {
-+            bio = BIO_new(BIO_s_mem());
-+            if (bio == NULL)
-+                goto err;
-+            BIO_set_mem_eof_return(bio, 0);
-+        }
-+        if (bio == NULL)
-+            goto err;
-+    }
-+    BIO_push(out, bio);
-+    bio = NULL;
-+    return out;
-+
-+ err:
-+    OPENSSL_clear_free(ek, eklen);
-+    OPENSSL_clear_free(tkey, tkeylen);
-+    BIO_free_all(out);
-+    BIO_free_all(btmp);
-+    BIO_free_all(etmp);
-+    BIO_free_all(bio);
-+    return NULL;
-+}
-+
-+static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
-+{
-+    for (;;) {
-+        bio = BIO_find_type(bio, BIO_TYPE_MD);
-+        if (bio == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,
-+                     PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
-+            return NULL;
-+        }
-+        BIO_get_md_ctx(bio, pmd);
-+        if (*pmd == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR);
-+            return NULL;
-+        }
-+        if (EVP_MD_CTX_type(*pmd) == nid)
-+            return bio;
-+        bio = BIO_next(bio);
-+    }
-+    return NULL;
-+}
-+
-+static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
-+{
-+    unsigned char md_data[EVP_MAX_MD_SIZE];
-+    unsigned int md_len;
-+
-+    /* Add signing time if not already present */
-+    if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
-+        if (!PKCS7_add0_attrib_signing_time(si, NULL)) {
-+            PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+    }
-+
-+    /* Add digest */
-+    if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) {
-+        PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
-+        return 0;
-+    }
-+    if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) {
-+        PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    /* Now sign the attributes */
-+    if (!PKCS7_SIGNER_INFO_sign(si))
-+        return 0;
-+
-+    return 1;
-+}
-+
-+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
-+{
-+    int ret = 0;
-+    int i, j;
-+    BIO *btmp;
-+    PKCS7_SIGNER_INFO *si;
-+    EVP_MD_CTX *mdc, *ctx_tmp;
-+    STACK_OF(X509_ATTRIBUTE) *sk;
-+    STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
-+    ASN1_OCTET_STRING *os = NULL;
-+
-+    if (p7 == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
-+        return 0;
-+    }
-+
-+    if (p7->d.ptr == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
-+        return 0;
-+    }
-+
-+    ctx_tmp = EVP_MD_CTX_new();
-+    if (ctx_tmp == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    i = OBJ_obj2nid(p7->type);
-+    p7->state = PKCS7_S_HEADER;
-+
-+    switch (i) {
-+    case NID_pkcs7_data:
-+        os = p7->d.data;
-+        break;
-+    case NID_pkcs7_signedAndEnveloped:
-+        /* XXXXXXXXXXXXXXXX */
-+        si_sk = p7->d.signed_and_enveloped->signer_info;
-+        os = p7->d.signed_and_enveloped->enc_data->enc_data;
-+        if (os == NULL) {
-+            os = ASN1_OCTET_STRING_new();
-+            if (os == NULL) {
-+                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            p7->d.signed_and_enveloped->enc_data->enc_data = os;
-+        }
-+        break;
-+    case NID_pkcs7_enveloped:
-+        /* XXXXXXXXXXXXXXXX */
-+        os = p7->d.enveloped->enc_data->enc_data;
-+        if (os == NULL) {
-+            os = ASN1_OCTET_STRING_new();
-+            if (os == NULL) {
-+                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            p7->d.enveloped->enc_data->enc_data = os;
-+        }
-+        break;
-+    case NID_pkcs7_signed:
-+        si_sk = p7->d.sign->signer_info;
-+        os = PKCS7_get_octet_string(p7->d.sign->contents);
-+        /* If detached data then the content is excluded */
-+        if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
-+            ASN1_OCTET_STRING_free(os);
-+            os = NULL;
-+            p7->d.sign->contents->d.data = NULL;
-+        }
-+        break;
-+
-+    case NID_pkcs7_digest:
-+        os = PKCS7_get_octet_string(p7->d.digest->contents);
-+        /* If detached data then the content is excluded */
-+        if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
-+            ASN1_OCTET_STRING_free(os);
-+            os = NULL;
-+            p7->d.digest->contents->d.data = NULL;
-+        }
-+        break;
-+
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
-+        goto err;
-+    }
-+
-+    if (si_sk != NULL) {
-+        for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
-+            si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
-+            if (si->pkey == NULL)
-+                continue;
-+
-+            j = OBJ_obj2nid(si->digest_alg->algorithm);
-+
-+            btmp = bio;
-+
-+            btmp = PKCS7_find_digest(&mdc, btmp, j);
-+
-+            if (btmp == NULL)
-+                goto err;
-+
-+            /*
-+             * We now have the EVP_MD_CTX, lets do the signing.
-+             */
-+            if (!EVP_MD_CTX_copy_ex(ctx_tmp, mdc))
-+                goto err;
-+
-+            sk = si->auth_attr;
-+
-+            /*
-+             * If there are attributes, we add the digest attribute and only
-+             * sign the attributes
-+             */
-+            if (sk_X509_ATTRIBUTE_num(sk) > 0) {
-+                if (!do_pkcs7_signed_attrib(si, ctx_tmp))
-+                    goto err;
-+            } else {
-+                unsigned char *abuf = NULL;
-+                unsigned int abuflen;
-+                abuflen = EVP_PKEY_size(si->pkey);
-+                abuf = OPENSSL_malloc(abuflen);
-+                if (abuf == NULL)
-+                    goto err;
-+
-+                if (!EVP_SignFinal(ctx_tmp, abuf, &abuflen, si->pkey)) {
-+                    OPENSSL_free(abuf);
-+                    PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
-+                    goto err;
-+                }
-+                ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
-+            }
-+        }
-+    } else if (i == NID_pkcs7_digest) {
-+        unsigned char md_data[EVP_MAX_MD_SIZE];
-+        unsigned int md_len;
-+        if (!PKCS7_find_digest(&mdc, bio,
-+                               OBJ_obj2nid(p7->d.digest->md->algorithm)))
-+            goto err;
-+        if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
-+            goto err;
-+        if (!ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len))
-+            goto err;
-+    }
-+
-+    if (!PKCS7_is_detached(p7)) {
-+        /*
-+         * NOTE(emilia): I think we only reach os == NULL here because detached
-+         * digested data support is broken.
-+         */
-+        if (os == NULL)
-+            goto err;
-+        if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
-+            char *cont;
-+            long contlen;
-+            btmp = BIO_find_type(bio, BIO_TYPE_MEM);
-+            if (btmp == NULL) {
-+                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
-+                goto err;
-+            }
-+            contlen = BIO_get_mem_data(btmp, &cont);
-+            /*
-+             * Mark the BIO read only then we can use its copy of the data
-+             * instead of making an extra copy.
-+             */
-+            BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
-+            BIO_set_mem_eof_return(btmp, 0);
-+            ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
-+        }
-+    }
-+    ret = 1;
-+ err:
-+    EVP_MD_CTX_free(ctx_tmp);
-+    return (ret);
-+}
-+
-+int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
-+{
-+    EVP_MD_CTX *mctx;
-+    EVP_PKEY_CTX *pctx;
-+    unsigned char *abuf = NULL;
-+    int alen;
-+    size_t siglen;
-+    const EVP_MD *md = NULL;
-+
-+    md = EVP_get_digestbyobj(si->digest_alg->algorithm);
-+    if (md == NULL)
-+        return 0;
-+
-+    mctx = EVP_MD_CTX_new();
-+    if (mctx == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
-+                          EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) {
-+        PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
-+        goto err;
-+    }
-+
-+    alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf,
-+                         ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
-+    if (!abuf)
-+        goto err;
-+    if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
-+        goto err;
-+    OPENSSL_free(abuf);
-+    abuf = NULL;
-+    if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
-+        goto err;
-+    abuf = OPENSSL_malloc(siglen);
-+    if (abuf == NULL)
-+        goto err;
-+    if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
-+                          EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) {
-+        PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
-+        goto err;
-+    }
-+
-+    EVP_MD_CTX_free(mctx);
-+
-+    ASN1_STRING_set0(si->enc_digest, abuf, siglen);
-+
-+    return 1;
-+
-+ err:
-+    OPENSSL_free(abuf);
-+    EVP_MD_CTX_free(mctx);
-+    return 0;
-+
-+}
-+
-+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
-+                     PKCS7 *p7, PKCS7_SIGNER_INFO *si)
-+{
-+    PKCS7_ISSUER_AND_SERIAL *ias;
-+    int ret = 0, i;
-+    STACK_OF(X509) *cert;
-+    X509 *x509;
-+
-+    if (p7 == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER);
-+        return 0;
-+    }
-+
-+    if (p7->d.ptr == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
-+        return 0;
-+    }
-+
-+    if (PKCS7_type_is_signed(p7)) {
-+        cert = p7->d.sign->cert;
-+    } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
-+        cert = p7->d.signed_and_enveloped->cert;
-+    } else {
-+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
-+        goto err;
-+    }
-+    /* XXXXXXXXXXXXXXXXXXXXXXX */
-+    ias = si->issuer_and_serial;
-+
-+    x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial);
-+
-+    /* were we able to find the cert in passed to us */
-+    if (x509 == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
-+                 PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
-+        goto err;
-+    }
-+
-+    /* Lets verify */
-+    if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) {
-+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
-+        goto err;
-+    }
-+    X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
-+    i = X509_verify_cert(ctx);
-+    if (i <= 0) {
-+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
-+        X509_STORE_CTX_cleanup(ctx);
-+        goto err;
-+    }
-+    X509_STORE_CTX_cleanup(ctx);
-+
-+    return PKCS7_signatureVerify(bio, p7, si, x509);
-+ err:
-+    return ret;
-+}
-+
-+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
-+                          X509 *x509)
-+{
-+    ASN1_OCTET_STRING *os;
-+    EVP_MD_CTX *mdc_tmp, *mdc;
-+    int ret = 0, i;
-+    int md_type;
-+    STACK_OF(X509_ATTRIBUTE) *sk;
-+    BIO *btmp;
-+    EVP_PKEY *pkey;
-+
-+    mdc_tmp = EVP_MD_CTX_new();
-+    if (mdc_tmp == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) {
-+        PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
-+        goto err;
-+    }
-+
-+    md_type = OBJ_obj2nid(si->digest_alg->algorithm);
-+
-+    btmp = bio;
-+    for (;;) {
-+        if ((btmp == NULL) ||
-+            ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
-+            PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
-+                     PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
-+            goto err;
-+        }
-+        BIO_get_md_ctx(btmp, &mdc);
-+        if (mdc == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR);
-+            goto err;
-+        }
-+        if (EVP_MD_CTX_type(mdc) == md_type)
-+            break;
-+        /*
-+         * Workaround for some broken clients that put the signature OID
-+         * instead of the digest OID in digest_alg->algorithm
-+         */
-+        if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
-+            break;
-+        btmp = BIO_next(btmp);
-+    }
-+
-+    /*
-+     * mdc is the digest ctx that we want, unless there are attributes, in
-+     * which case the digest is the signed attributes
-+     */
-+    if (!EVP_MD_CTX_copy_ex(mdc_tmp, mdc))
-+        goto err;
-+
-+    sk = si->auth_attr;
-+    if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
-+        unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
-+        unsigned int md_len;
-+        int alen;
-+        ASN1_OCTET_STRING *message_digest;
-+
-+        if (!EVP_DigestFinal_ex(mdc_tmp, md_dat, &md_len))
-+            goto err;
-+        message_digest = PKCS7_digest_from_attributes(sk);
-+        if (!message_digest) {
-+            PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
-+                     PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
-+            goto err;
-+        }
-+        if ((message_digest->length != (int)md_len) ||
-+            (memcmp(message_digest->data, md_dat, md_len))) {
-+            PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE);
-+            ret = -1;
-+            goto err;
-+        }
-+
-+        if (!EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL))
-+            goto err;
-+
-+        alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
-+                             ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
-+        if (alen <= 0) {
-+            PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB);
-+            ret = -1;
-+            goto err;
-+        }
-+        if (!EVP_VerifyUpdate(mdc_tmp, abuf, alen))
-+            goto err;
-+
-+        OPENSSL_free(abuf);
-+    }
-+
-+    os = si->enc_digest;
-+    pkey = X509_get0_pubkey(x509);
-+    if (!pkey) {
-+        ret = -1;
-+        goto err;
-+    }
-+
-+    i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey);
-+    if (i <= 0) {
-+        PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
-+        ret = -1;
-+        goto err;
-+    }
-+    ret = 1;
-+ err:
-+    EVP_MD_CTX_free(mdc_tmp);
-+    return (ret);
-+}
-+
-+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
-+{
-+    STACK_OF(PKCS7_RECIP_INFO) *rsk;
-+    PKCS7_RECIP_INFO *ri;
-+    int i;
-+
-+    i = OBJ_obj2nid(p7->type);
-+    if (i != NID_pkcs7_signedAndEnveloped)
-+        return NULL;
-+    if (p7->d.signed_and_enveloped == NULL)
-+        return NULL;
-+    rsk = p7->d.signed_and_enveloped->recipientinfo;
-+    if (rsk == NULL)
-+        return NULL;
-+    if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
-+        return (NULL);
-+    ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
-+    return (ri->issuer_and_serial);
-+}
-+
-+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
-+{
-+    return (get_attribute(si->auth_attr, nid));
-+}
-+
-+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
-+{
-+    return (get_attribute(si->unauth_attr, nid));
-+}
-+
-+static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
-+{
-+    int idx;
-+    X509_ATTRIBUTE *xa;
-+    idx = X509at_get_attr_by_NID(sk, nid, -1);
-+    xa = X509at_get_attr(sk, idx);
-+    return X509_ATTRIBUTE_get0_type(xa, 0);
-+}
-+
-+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
-+{
-+    ASN1_TYPE *astype;
-+    if ((astype = get_attribute(sk, NID_pkcs9_messageDigest)) == NULL)
-+        return NULL;
-+    return astype->value.octet_string;
-+}
-+
-+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
-+                                STACK_OF(X509_ATTRIBUTE) *sk)
-+{
-+    int i;
-+
-+    sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free);
-+    p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk);
-+    if (p7si->auth_attr == NULL)
-+        return 0;
-+    for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
-+        if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i,
-+                                   X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
-+                                                      (sk, i))))
-+            == NULL)
-+            return (0);
-+    }
-+    return (1);
-+}
-+
-+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
-+                         STACK_OF(X509_ATTRIBUTE) *sk)
-+{
-+    int i;
-+
-+    sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free);
-+    p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk);
-+    if (p7si->unauth_attr == NULL)
-+        return 0;
-+    for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
-+        if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i,
-+                                   X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
-+                                                      (sk, i))))
-+            == NULL)
-+            return (0);
-+    }
-+    return (1);
-+}
-+
-+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
-+                               void *value)
-+{
-+    return (add_attribute(&(p7si->auth_attr), nid, atrtype, value));
-+}
-+
-+int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
-+                        void *value)
-+{
-+    return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value));
-+}
-+
-+static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
-+                         void *value)
-+{
-+    X509_ATTRIBUTE *attr = NULL;
-+
-+    if (*sk == NULL) {
-+        if ((*sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
-+            return 0;
-+ new_attrib:
-+        if ((attr = X509_ATTRIBUTE_create(nid, atrtype, value)) == NULL)
-+            return 0;
-+        if (!sk_X509_ATTRIBUTE_push(*sk, attr)) {
-+            X509_ATTRIBUTE_free(attr);
-+            return 0;
-+        }
-+    } else {
-+        int i;
-+
-+        for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) {
-+            attr = sk_X509_ATTRIBUTE_value(*sk, i);
-+            if (OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr)) == nid) {
-+                X509_ATTRIBUTE_free(attr);
-+                attr = X509_ATTRIBUTE_create(nid, atrtype, value);
-+                if (attr == NULL)
-+                    return 0;
-+                if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) {
-+                    X509_ATTRIBUTE_free(attr);
-+                    return 0;
-+                }
-+                goto end;
-+            }
-+        }
-+        goto new_attrib;
-+    }
-+ end:
-+    return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_enc.c
-new file mode 100644
-index 0000000..3c59f9c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_enc.c
-@@ -0,0 +1,25 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+PKCS7_in_bio(PKCS7 *p7, BIO *in);
-+PKCS7_out_bio(PKCS7 *p7, BIO *out);
-+
-+PKCS7_add_signer(PKCS7 *p7, X509 *cert, EVP_PKEY *key);
-+PKCS7_cipher(PKCS7 *p7, EVP_CIPHER *cipher);
-+
-+PKCS7_Init(PKCS7 *p7);
-+PKCS7_Update(PKCS7 *p7);
-+PKCS7_Finish(PKCS7 *p7);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_lib.c
-new file mode 100644
-index 0000000..69c68cf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_lib.c
-@@ -0,0 +1,589 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+
-+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
-+{
-+    int nid;
-+    long ret;
-+
-+    nid = OBJ_obj2nid(p7->type);
-+
-+    switch (cmd) {
-+    /* NOTE(emilia): does not support detached digested data. */
-+    case PKCS7_OP_SET_DETACHED_SIGNATURE:
-+        if (nid == NID_pkcs7_signed) {
-+            ret = p7->detached = (int)larg;
-+            if (ret && PKCS7_type_is_data(p7->d.sign->contents)) {
-+                ASN1_OCTET_STRING *os;
-+                os = p7->d.sign->contents->d.data;
-+                ASN1_OCTET_STRING_free(os);
-+                p7->d.sign->contents->d.data = NULL;
-+            }
-+        } else {
-+            PKCS7err(PKCS7_F_PKCS7_CTRL,
-+                     PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
-+            ret = 0;
-+        }
-+        break;
-+    case PKCS7_OP_GET_DETACHED_SIGNATURE:
-+        if (nid == NID_pkcs7_signed) {
-+            if (!p7->d.sign || !p7->d.sign->contents->d.ptr)
-+                ret = 1;
-+            else
-+                ret = 0;
-+
-+            p7->detached = ret;
-+        } else {
-+            PKCS7err(PKCS7_F_PKCS7_CTRL,
-+                     PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
-+            ret = 0;
-+        }
-+
-+        break;
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION);
-+        ret = 0;
-+    }
-+    return (ret);
-+}
-+
-+int PKCS7_content_new(PKCS7 *p7, int type)
-+{
-+    PKCS7 *ret = NULL;
-+
-+    if ((ret = PKCS7_new()) == NULL)
-+        goto err;
-+    if (!PKCS7_set_type(ret, type))
-+        goto err;
-+    if (!PKCS7_set_content(p7, ret))
-+        goto err;
-+
-+    return (1);
-+ err:
-+    PKCS7_free(ret);
-+    return (0);
-+}
-+
-+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
-+{
-+    int i;
-+
-+    i = OBJ_obj2nid(p7->type);
-+    switch (i) {
-+    case NID_pkcs7_signed:
-+        PKCS7_free(p7->d.sign->contents);
-+        p7->d.sign->contents = p7_data;
-+        break;
-+    case NID_pkcs7_digest:
-+        PKCS7_free(p7->d.digest->contents);
-+        p7->d.digest->contents = p7_data;
-+        break;
-+    case NID_pkcs7_data:
-+    case NID_pkcs7_enveloped:
-+    case NID_pkcs7_signedAndEnveloped:
-+    case NID_pkcs7_encrypted:
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
-+        goto err;
-+    }
-+    return (1);
-+ err:
-+    return (0);
-+}
-+
-+int PKCS7_set_type(PKCS7 *p7, int type)
-+{
-+    ASN1_OBJECT *obj;
-+
-+    /*
-+     * PKCS7_content_free(p7);
-+     */
-+    obj = OBJ_nid2obj(type);    /* will not fail */
-+
-+    switch (type) {
-+    case NID_pkcs7_signed:
-+        p7->type = obj;
-+        if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
-+            goto err;
-+        if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
-+            PKCS7_SIGNED_free(p7->d.sign);
-+            p7->d.sign = NULL;
-+            goto err;
-+        }
-+        break;
-+    case NID_pkcs7_data:
-+        p7->type = obj;
-+        if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL)
-+            goto err;
-+        break;
-+    case NID_pkcs7_signedAndEnveloped:
-+        p7->type = obj;
-+        if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new())
-+            == NULL)
-+            goto err;
-+        ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1);
-+        if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
-+            goto err;
-+        p7->d.signed_and_enveloped->enc_data->content_type
-+            = OBJ_nid2obj(NID_pkcs7_data);
-+        break;
-+    case NID_pkcs7_enveloped:
-+        p7->type = obj;
-+        if ((p7->d.enveloped = PKCS7_ENVELOPE_new())
-+            == NULL)
-+            goto err;
-+        if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
-+            goto err;
-+        p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
-+        break;
-+    case NID_pkcs7_encrypted:
-+        p7->type = obj;
-+        if ((p7->d.encrypted = PKCS7_ENCRYPT_new())
-+            == NULL)
-+            goto err;
-+        if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
-+            goto err;
-+        p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
-+        break;
-+
-+    case NID_pkcs7_digest:
-+        p7->type = obj;
-+        if ((p7->d.digest = PKCS7_DIGEST_new())
-+            == NULL)
-+            goto err;
-+        if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
-+            goto err;
-+        break;
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
-+        goto err;
-+    }
-+    return (1);
-+ err:
-+    return (0);
-+}
-+
-+int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
-+{
-+    p7->type = OBJ_nid2obj(type);
-+    p7->d.other = other;
-+    return 1;
-+}
-+
-+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
-+{
-+    int i, j, nid;
-+    X509_ALGOR *alg;
-+    STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
-+    STACK_OF(X509_ALGOR) *md_sk;
-+
-+    i = OBJ_obj2nid(p7->type);
-+    switch (i) {
-+    case NID_pkcs7_signed:
-+        signer_sk = p7->d.sign->signer_info;
-+        md_sk = p7->d.sign->md_algs;
-+        break;
-+    case NID_pkcs7_signedAndEnveloped:
-+        signer_sk = p7->d.signed_and_enveloped->signer_info;
-+        md_sk = p7->d.signed_and_enveloped->md_algs;
-+        break;
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE);
-+        return (0);
-+    }
-+
-+    nid = OBJ_obj2nid(psi->digest_alg->algorithm);
-+
-+    /* If the digest is not currently listed, add it */
-+    j = 0;
-+    for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
-+        alg = sk_X509_ALGOR_value(md_sk, i);
-+        if (OBJ_obj2nid(alg->algorithm) == nid) {
-+            j = 1;
-+            break;
-+        }
-+    }
-+    if (!j) {                   /* we need to add another algorithm */
-+        if ((alg = X509_ALGOR_new()) == NULL
-+            || (alg->parameter = ASN1_TYPE_new()) == NULL) {
-+            X509_ALGOR_free(alg);
-+            PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, ERR_R_MALLOC_FAILURE);
-+            return (0);
-+        }
-+        alg->algorithm = OBJ_nid2obj(nid);
-+        alg->parameter->type = V_ASN1_NULL;
-+        if (!sk_X509_ALGOR_push(md_sk, alg)) {
-+            X509_ALGOR_free(alg);
-+            return 0;
-+        }
-+    }
-+
-+    if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
-+        return 0;
-+    return (1);
-+}
-+
-+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
-+{
-+    int i;
-+    STACK_OF(X509) **sk;
-+
-+    i = OBJ_obj2nid(p7->type);
-+    switch (i) {
-+    case NID_pkcs7_signed:
-+        sk = &(p7->d.sign->cert);
-+        break;
-+    case NID_pkcs7_signedAndEnveloped:
-+        sk = &(p7->d.signed_and_enveloped->cert);
-+        break;
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE);
-+        return (0);
-+    }
-+
-+    if (*sk == NULL)
-+        *sk = sk_X509_new_null();
-+    if (*sk == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    X509_up_ref(x509);
-+    if (!sk_X509_push(*sk, x509)) {
-+        X509_free(x509);
-+        return 0;
-+    }
-+    return (1);
-+}
-+
-+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
-+{
-+    int i;
-+    STACK_OF(X509_CRL) **sk;
-+
-+    i = OBJ_obj2nid(p7->type);
-+    switch (i) {
-+    case NID_pkcs7_signed:
-+        sk = &(p7->d.sign->crl);
-+        break;
-+    case NID_pkcs7_signedAndEnveloped:
-+        sk = &(p7->d.signed_and_enveloped->crl);
-+        break;
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE);
-+        return (0);
-+    }
-+
-+    if (*sk == NULL)
-+        *sk = sk_X509_CRL_new_null();
-+    if (*sk == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    X509_CRL_up_ref(crl);
-+    if (!sk_X509_CRL_push(*sk, crl)) {
-+        X509_CRL_free(crl);
-+        return 0;
-+    }
-+    return (1);
-+}
-+
-+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
-+                          const EVP_MD *dgst)
-+{
-+    int ret;
-+
-+    /* We now need to add another PKCS7_SIGNER_INFO entry */
-+    if (!ASN1_INTEGER_set(p7i->version, 1))
-+        goto err;
-+    if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
-+                       X509_get_issuer_name(x509)))
-+        goto err;
-+
-+    /*
-+     * because ASN1_INTEGER_set is used to set a 'long' we will do things the
-+     * ugly way.
-+     */
-+    ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
-+    if (!(p7i->issuer_and_serial->serial =
-+          ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
-+        goto err;
-+
-+    /* lets keep the pkey around for a while */
-+    EVP_PKEY_up_ref(pkey);
-+    p7i->pkey = pkey;
-+
-+    /* Set the algorithms */
-+
-+    X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
-+                    V_ASN1_NULL, NULL);
-+
-+    if (pkey->ameth && pkey->ameth->pkey_ctrl) {
-+        ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i);
-+        if (ret > 0)
-+            return 1;
-+        if (ret != -2) {
-+            PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
-+                     PKCS7_R_SIGNING_CTRL_FAILURE);
-+            return 0;
-+        }
-+    }
-+    PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
-+             PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
-+ err:
-+    return 0;
-+}
-+
-+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
-+                                       const EVP_MD *dgst)
-+{
-+    PKCS7_SIGNER_INFO *si = NULL;
-+
-+    if (dgst == NULL) {
-+        int def_nid;
-+        if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
-+            goto err;
-+        dgst = EVP_get_digestbynid(def_nid);
-+        if (dgst == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, PKCS7_R_NO_DEFAULT_DIGEST);
-+            goto err;
-+        }
-+    }
-+
-+    if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
-+        goto err;
-+    if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst))
-+        goto err;
-+    if (!PKCS7_add_signer(p7, si))
-+        goto err;
-+    return (si);
-+ err:
-+    PKCS7_SIGNER_INFO_free(si);
-+    return (NULL);
-+}
-+
-+int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
-+{
-+    if (PKCS7_type_is_digest(p7)) {
-+        if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+        p7->d.digest->md->parameter->type = V_ASN1_NULL;
-+        p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
-+        return 1;
-+    }
-+
-+    PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE);
-+    return 1;
-+}
-+
-+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
-+{
-+    if (p7 == NULL || p7->d.ptr == NULL)
-+        return NULL;
-+    if (PKCS7_type_is_signed(p7)) {
-+        return (p7->d.sign->signer_info);
-+    } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
-+        return (p7->d.signed_and_enveloped->signer_info);
-+    } else
-+        return (NULL);
-+}
-+
-+void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
-+                                 X509_ALGOR **pdig, X509_ALGOR **psig)
-+{
-+    if (pk)
-+        *pk = si->pkey;
-+    if (pdig)
-+        *pdig = si->digest_alg;
-+    if (psig)
-+        *psig = si->digest_enc_alg;
-+}
-+
-+void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
-+{
-+    if (penc)
-+        *penc = ri->key_enc_algor;
-+}
-+
-+PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
-+{
-+    PKCS7_RECIP_INFO *ri;
-+
-+    if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
-+        goto err;
-+    if (!PKCS7_RECIP_INFO_set(ri, x509))
-+        goto err;
-+    if (!PKCS7_add_recipient_info(p7, ri))
-+        goto err;
-+    return ri;
-+ err:
-+    PKCS7_RECIP_INFO_free(ri);
-+    return NULL;
-+}
-+
-+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
-+{
-+    int i;
-+    STACK_OF(PKCS7_RECIP_INFO) *sk;
-+
-+    i = OBJ_obj2nid(p7->type);
-+    switch (i) {
-+    case NID_pkcs7_signedAndEnveloped:
-+        sk = p7->d.signed_and_enveloped->recipientinfo;
-+        break;
-+    case NID_pkcs7_enveloped:
-+        sk = p7->d.enveloped->recipientinfo;
-+        break;
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,
-+                 PKCS7_R_WRONG_CONTENT_TYPE);
-+        return (0);
-+    }
-+
-+    if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
-+        return 0;
-+    return (1);
-+}
-+
-+int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
-+{
-+    int ret;
-+    EVP_PKEY *pkey = NULL;
-+    if (!ASN1_INTEGER_set(p7i->version, 0))
-+        return 0;
-+    if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
-+                       X509_get_issuer_name(x509)))
-+        return 0;
-+
-+    ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
-+    if (!(p7i->issuer_and_serial->serial =
-+          ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
-+        return 0;
-+
-+    pkey = X509_get0_pubkey(x509);
-+
-+    if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) {
-+        PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
-+                 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
-+        goto err;
-+    }
-+
-+    ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i);
-+    if (ret == -2) {
-+        PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
-+                 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
-+        goto err;
-+    }
-+    if (ret <= 0) {
-+        PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
-+                 PKCS7_R_ENCRYPTION_CTRL_FAILURE);
-+        goto err;
-+    }
-+
-+    X509_up_ref(x509);
-+    p7i->cert = x509;
-+
-+    return 1;
-+
-+ err:
-+    return 0;
-+}
-+
-+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
-+{
-+    if (PKCS7_type_is_signed(p7))
-+        return (X509_find_by_issuer_and_serial(p7->d.sign->cert,
-+                                               si->issuer_and_serial->issuer,
-+                                               si->
-+                                               issuer_and_serial->serial));
-+    else
-+        return (NULL);
-+}
-+
-+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
-+{
-+    int i;
-+    PKCS7_ENC_CONTENT *ec;
-+
-+    i = OBJ_obj2nid(p7->type);
-+    switch (i) {
-+    case NID_pkcs7_signedAndEnveloped:
-+        ec = p7->d.signed_and_enveloped->enc_data;
-+        break;
-+    case NID_pkcs7_enveloped:
-+        ec = p7->d.enveloped->enc_data;
-+        break;
-+    default:
-+        PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE);
-+        return (0);
-+    }
-+
-+    /* Check cipher OID exists and has data in it */
-+    i = EVP_CIPHER_type(cipher);
-+    if (i == NID_undef) {
-+        PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,
-+                 PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
-+        return (0);
-+    }
-+
-+    ec->cipher = cipher;
-+    return 1;
-+}
-+
-+int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
-+{
-+    ASN1_OCTET_STRING *os = NULL;
-+
-+    switch (OBJ_obj2nid(p7->type)) {
-+    case NID_pkcs7_data:
-+        os = p7->d.data;
-+        break;
-+
-+    case NID_pkcs7_signedAndEnveloped:
-+        os = p7->d.signed_and_enveloped->enc_data->enc_data;
-+        if (os == NULL) {
-+            os = ASN1_OCTET_STRING_new();
-+            p7->d.signed_and_enveloped->enc_data->enc_data = os;
-+        }
-+        break;
-+
-+    case NID_pkcs7_enveloped:
-+        os = p7->d.enveloped->enc_data->enc_data;
-+        if (os == NULL) {
-+            os = ASN1_OCTET_STRING_new();
-+            p7->d.enveloped->enc_data->enc_data = os;
-+        }
-+        break;
-+
-+    case NID_pkcs7_signed:
-+        os = p7->d.sign->contents->d.data;
-+        break;
-+
-+    default:
-+        os = NULL;
-+        break;
-+    }
-+
-+    if (os == NULL)
-+        return 0;
-+
-+    os->flags |= ASN1_STRING_FLAG_NDEF;
-+    *boundary = &os->data;
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c
-new file mode 100644
-index 0000000..97474cf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_mime.c
-@@ -0,0 +1,49 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+/* PKCS#7 wrappers round generalised stream and MIME routines */
-+
-+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
-+{
-+    return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags,
-+                               ASN1_ITEM_rptr(PKCS7));
-+}
-+
-+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
-+{
-+    return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)p7, in, flags,
-+                                     "PKCS7", ASN1_ITEM_rptr(PKCS7));
-+}
-+
-+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
-+{
-+    STACK_OF(X509_ALGOR) *mdalgs;
-+    int ctype_nid = OBJ_obj2nid(p7->type);
-+    if (ctype_nid == NID_pkcs7_signed)
-+        mdalgs = p7->d.sign->md_algs;
-+    else
-+        mdalgs = NULL;
-+
-+    flags ^= SMIME_OLDMIME;
-+
-+    return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
-+                            ctype_nid, NID_undef, mdalgs,
-+                            ASN1_ITEM_rptr(PKCS7));
-+}
-+
-+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
-+{
-+    return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_smime.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_smime.c
-new file mode 100644
-index 0000000..4418723
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pk7_smime.c
-@@ -0,0 +1,549 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* Simple PKCS#7 processing functions */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+
-+#define BUFFERSIZE 4096
-+
-+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
-+
-+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
-+                  BIO *data, int flags)
-+{
-+    PKCS7 *p7;
-+    int i;
-+
-+    if ((p7 = PKCS7_new()) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    if (!PKCS7_set_type(p7, NID_pkcs7_signed))
-+        goto err;
-+
-+    if (!PKCS7_content_new(p7, NID_pkcs7_data))
-+        goto err;
-+
-+    if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) {
-+        PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
-+        goto err;
-+    }
-+
-+    if (!(flags & PKCS7_NOCERTS)) {
-+        for (i = 0; i < sk_X509_num(certs); i++) {
-+            if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
-+                goto err;
-+        }
-+    }
-+
-+    if (flags & PKCS7_DETACHED)
-+        PKCS7_set_detached(p7, 1);
-+
-+    if (flags & (PKCS7_STREAM | PKCS7_PARTIAL))
-+        return p7;
-+
-+    if (PKCS7_final(p7, data, flags))
-+        return p7;
-+
-+ err:
-+    PKCS7_free(p7);
-+    return NULL;
-+}
-+
-+int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
-+{
-+    BIO *p7bio;
-+    int ret = 0;
-+
-+    if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    SMIME_crlf_copy(data, p7bio, flags);
-+
-+    (void)BIO_flush(p7bio);
-+
-+    if (!PKCS7_dataFinal(p7, p7bio)) {
-+        PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN);
-+        goto err;
-+    }
-+
-+    ret = 1;
-+
-+ err:
-+    BIO_free_all(p7bio);
-+
-+    return ret;
-+
-+}
-+
-+/* Check to see if a cipher exists and if so add S/MIME capabilities */
-+
-+static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
-+{
-+    if (EVP_get_cipherbynid(nid))
-+        return PKCS7_simple_smimecap(sk, nid, arg);
-+    return 1;
-+}
-+
-+static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
-+{
-+    if (EVP_get_digestbynid(nid))
-+        return PKCS7_simple_smimecap(sk, nid, arg);
-+    return 1;
-+}
-+
-+PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
-+                                         EVP_PKEY *pkey, const EVP_MD *md,
-+                                         int flags)
-+{
-+    PKCS7_SIGNER_INFO *si = NULL;
-+    STACK_OF(X509_ALGOR) *smcap = NULL;
-+    if (!X509_check_private_key(signcert, pkey)) {
-+        PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
-+                 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
-+        return NULL;
-+    }
-+
-+    if ((si = PKCS7_add_signature(p7, signcert, pkey, md)) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
-+                 PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
-+        return NULL;
-+    }
-+
-+    if (!(flags & PKCS7_NOCERTS)) {
-+        if (!PKCS7_add_certificate(p7, signcert))
-+            goto err;
-+    }
-+
-+    if (!(flags & PKCS7_NOATTR)) {
-+        if (!PKCS7_add_attrib_content_type(si, NULL))
-+            goto err;
-+        /* Add SMIMECapabilities */
-+        if (!(flags & PKCS7_NOSMIMECAP)) {
-+            if ((smcap = sk_X509_ALGOR_new_null()) == NULL) {
-+                PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, ERR_R_MALLOC_FAILURE);
-+                goto err;
-+            }
-+            if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
-+                || !add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1)
-+                || !add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1)
-+                || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
-+                || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
-+                || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
-+                || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
-+                || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
-+                || !add_cipher_smcap(smcap, NID_rc2_cbc, 128)
-+                || !add_cipher_smcap(smcap, NID_rc2_cbc, 64)
-+                || !add_cipher_smcap(smcap, NID_des_cbc, -1)
-+                || !add_cipher_smcap(smcap, NID_rc2_cbc, 40)
-+                || !PKCS7_add_attrib_smimecap(si, smcap))
-+                goto err;
-+            sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
-+            smcap = NULL;
-+        }
-+        if (flags & PKCS7_REUSE_DIGEST) {
-+            if (!pkcs7_copy_existing_digest(p7, si))
-+                goto err;
-+            if (!(flags & PKCS7_PARTIAL) && !PKCS7_SIGNER_INFO_sign(si))
-+                goto err;
-+        }
-+    }
-+    return si;
-+ err:
-+    sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
-+    return NULL;
-+}
-+
-+/*
-+ * Search for a digest matching SignerInfo digest type and if found copy
-+ * across.
-+ */
-+
-+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
-+{
-+    int i;
-+    STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
-+    PKCS7_SIGNER_INFO *sitmp;
-+    ASN1_OCTET_STRING *osdig = NULL;
-+    sinfos = PKCS7_get_signer_info(p7);
-+    for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
-+        sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
-+        if (si == sitmp)
-+            break;
-+        if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
-+            continue;
-+        if (!OBJ_cmp(si->digest_alg->algorithm, sitmp->digest_alg->algorithm)) {
-+            osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
-+            break;
-+        }
-+
-+    }
-+
-+    if (osdig)
-+        return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
-+
-+    PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
-+             PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
-+    return 0;
-+}
-+
-+int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
-+                 BIO *indata, BIO *out, int flags)
-+{
-+    STACK_OF(X509) *signers;
-+    X509 *signer;
-+    STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
-+    PKCS7_SIGNER_INFO *si;
-+    X509_STORE_CTX *cert_ctx = NULL;
-+    char *buf = NULL;
-+    int i, j = 0, k, ret = 0;
-+    BIO *p7bio = NULL;
-+    BIO *tmpin = NULL, *tmpout = NULL;
-+
-+    if (!p7) {
-+        PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER);
-+        return 0;
-+    }
-+
-+    if (!PKCS7_type_is_signed(p7)) {
-+        PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE);
-+        return 0;
-+    }
-+
-+    /* Check for no data and no content: no data to verify signature */
-+    if (PKCS7_get_detached(p7) && !indata) {
-+        PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT);
-+        return 0;
-+    }
-+
-+    if (flags & PKCS7_NO_DUAL_CONTENT) {
-+        /*
-+         * This was originally "#if 0" because we thought that only old broken
-+         * Netscape did this.  It turns out that Authenticode uses this kind
-+         * of "extended" PKCS7 format, and things like UEFI secure boot and
-+         * tools like osslsigncode need it.  In Authenticode the verification
-+         * process is different, but the existing PKCs7 verification works.
-+         */
-+        if (!PKCS7_get_detached(p7) && indata) {
-+            PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT);
-+            return 0;
-+        }
-+    }
-+
-+    sinfos = PKCS7_get_signer_info(p7);
-+
-+    if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
-+        PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA);
-+        return 0;
-+    }
-+
-+    signers = PKCS7_get0_signers(p7, certs, flags);
-+    if (!signers)
-+        return 0;
-+
-+    /* Now verify the certificates */
-+
-+    cert_ctx = X509_STORE_CTX_new();
-+    if (cert_ctx == NULL)
-+        goto err;
-+    if (!(flags & PKCS7_NOVERIFY))
-+        for (k = 0; k < sk_X509_num(signers); k++) {
-+            signer = sk_X509_value(signers, k);
-+            if (!(flags & PKCS7_NOCHAIN)) {
-+                if (!X509_STORE_CTX_init(cert_ctx, store, signer,
-+                                         p7->d.sign->cert)) {
-+                    PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
-+                    goto err;
-+                }
-+                X509_STORE_CTX_set_default(cert_ctx, "smime_sign");
-+            } else if (!X509_STORE_CTX_init(cert_ctx, store, signer, NULL)) {
-+                PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
-+                goto err;
-+            }
-+            if (!(flags & PKCS7_NOCRL))
-+                X509_STORE_CTX_set0_crls(cert_ctx, p7->d.sign->crl);
-+            i = X509_verify_cert(cert_ctx);
-+            if (i <= 0)
-+                j = X509_STORE_CTX_get_error(cert_ctx);
-+            X509_STORE_CTX_cleanup(cert_ctx);
-+            if (i <= 0) {
-+                PKCS7err(PKCS7_F_PKCS7_VERIFY,
-+                         PKCS7_R_CERTIFICATE_VERIFY_ERROR);
-+                ERR_add_error_data(2, "Verify error:",
-+                                   X509_verify_cert_error_string(j));
-+                goto err;
-+            }
-+            /* Check for revocation status here */
-+        }
-+
-+    /*
-+     * Performance optimization: if the content is a memory BIO then store
-+     * its contents in a temporary read only memory BIO. This avoids
-+     * potentially large numbers of slow copies of data which will occur when
-+     * reading from a read write memory BIO when signatures are calculated.
-+     */
-+
-+    if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) {
-+        char *ptr;
-+        long len;
-+        len = BIO_get_mem_data(indata, &ptr);
-+        tmpin = BIO_new_mem_buf(ptr, len);
-+        if (tmpin == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    } else
-+        tmpin = indata;
-+
-+    if ((p7bio = PKCS7_dataInit(p7, tmpin)) == NULL)
-+        goto err;
-+
-+    if (flags & PKCS7_TEXT) {
-+        if ((tmpout = BIO_new(BIO_s_mem())) == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        BIO_set_mem_eof_return(tmpout, 0);
-+    } else
-+        tmpout = out;
-+
-+    /* We now have to 'read' from p7bio to calculate digests etc. */
-+    if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    for (;;) {
-+        i = BIO_read(p7bio, buf, BUFFERSIZE);
-+        if (i <= 0)
-+            break;
-+        if (tmpout)
-+            BIO_write(tmpout, buf, i);
-+    }
-+
-+    if (flags & PKCS7_TEXT) {
-+        if (!SMIME_text(tmpout, out)) {
-+            PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SMIME_TEXT_ERROR);
-+            BIO_free(tmpout);
-+            goto err;
-+        }
-+        BIO_free(tmpout);
-+    }
-+
-+    /* Now Verify All Signatures */
-+    if (!(flags & PKCS7_NOSIGS))
-+        for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
-+            si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
-+            signer = sk_X509_value(signers, i);
-+            j = PKCS7_signatureVerify(p7bio, p7, si, signer);
-+            if (j <= 0) {
-+                PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE);
-+                goto err;
-+            }
-+        }
-+
-+    ret = 1;
-+
-+ err:
-+    X509_STORE_CTX_free(cert_ctx);
-+    OPENSSL_free(buf);
-+    if (tmpin == indata) {
-+        if (indata)
-+            BIO_pop(p7bio);
-+    }
-+    BIO_free_all(p7bio);
-+    sk_X509_free(signers);
-+    return ret;
-+}
-+
-+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs,
-+                                   int flags)
-+{
-+    STACK_OF(X509) *signers;
-+    STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
-+    PKCS7_SIGNER_INFO *si;
-+    PKCS7_ISSUER_AND_SERIAL *ias;
-+    X509 *signer;
-+    int i;
-+
-+    if (!p7) {
-+        PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_INVALID_NULL_POINTER);
-+        return NULL;
-+    }
-+
-+    if (!PKCS7_type_is_signed(p7)) {
-+        PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_WRONG_CONTENT_TYPE);
-+        return NULL;
-+    }
-+
-+    /* Collect all the signers together */
-+
-+    sinfos = PKCS7_get_signer_info(p7);
-+
-+    if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
-+        PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS);
-+        return 0;
-+    }
-+
-+    if ((signers = sk_X509_new_null()) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
-+        si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
-+        ias = si->issuer_and_serial;
-+        signer = NULL;
-+        /* If any certificates passed they take priority */
-+        if (certs)
-+            signer = X509_find_by_issuer_and_serial(certs,
-+                                                    ias->issuer, ias->serial);
-+        if (!signer && !(flags & PKCS7_NOINTERN)
-+            && p7->d.sign->cert)
-+            signer =
-+                X509_find_by_issuer_and_serial(p7->d.sign->cert,
-+                                               ias->issuer, ias->serial);
-+        if (!signer) {
-+            PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,
-+                     PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
-+            sk_X509_free(signers);
-+            return 0;
-+        }
-+
-+        if (!sk_X509_push(signers, signer)) {
-+            sk_X509_free(signers);
-+            return NULL;
-+        }
-+    }
-+    return signers;
-+}
-+
-+/* Build a complete PKCS#7 enveloped data */
-+
-+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
-+                     int flags)
-+{
-+    PKCS7 *p7;
-+    BIO *p7bio = NULL;
-+    int i;
-+    X509 *x509;
-+    if ((p7 = PKCS7_new()) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
-+        goto err;
-+    if (!PKCS7_set_cipher(p7, cipher)) {
-+        PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER);
-+        goto err;
-+    }
-+
-+    for (i = 0; i < sk_X509_num(certs); i++) {
-+        x509 = sk_X509_value(certs, i);
-+        if (!PKCS7_add_recipient(p7, x509)) {
-+            PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_ADDING_RECIPIENT);
-+            goto err;
-+        }
-+    }
-+
-+    if (flags & PKCS7_STREAM)
-+        return p7;
-+
-+    if (PKCS7_final(p7, in, flags))
-+        return p7;
-+
-+ err:
-+
-+    BIO_free_all(p7bio);
-+    PKCS7_free(p7);
-+    return NULL;
-+
-+}
-+
-+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
-+{
-+    BIO *tmpmem;
-+    int ret = 0, i;
-+    char *buf = NULL;
-+
-+    if (!p7) {
-+        PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER);
-+        return 0;
-+    }
-+
-+    if (!PKCS7_type_is_enveloped(p7)) {
-+        PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE);
-+        return 0;
-+    }
-+
-+    if (cert && !X509_check_private_key(cert, pkey)) {
-+        PKCS7err(PKCS7_F_PKCS7_DECRYPT,
-+                 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
-+        return 0;
-+    }
-+
-+    if ((tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert)) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
-+        return 0;
-+    }
-+
-+    if (flags & PKCS7_TEXT) {
-+        BIO *tmpbuf, *bread;
-+        /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
-+        if ((tmpbuf = BIO_new(BIO_f_buffer())) == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
-+            BIO_free_all(tmpmem);
-+            return 0;
-+        }
-+        if ((bread = BIO_push(tmpbuf, tmpmem)) == NULL) {
-+            PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
-+            BIO_free_all(tmpbuf);
-+            BIO_free_all(tmpmem);
-+            return 0;
-+        }
-+        ret = SMIME_text(bread, data);
-+        if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
-+            if (!BIO_get_cipher_status(tmpmem))
-+                ret = 0;
-+        }
-+        BIO_free_all(bread);
-+        return ret;
-+    }
-+    if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) {
-+        PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    for (;;) {
-+        i = BIO_read(tmpmem, buf, BUFFERSIZE);
-+        if (i <= 0) {
-+            ret = 1;
-+            if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
-+                if (!BIO_get_cipher_status(tmpmem))
-+                    ret = 0;
-+            }
-+
-+            break;
-+        }
-+        if (BIO_write(data, buf, i) != i) {
-+            break;
-+        }
-+    }
-+err:
-+    OPENSSL_free(buf);
-+    BIO_free_all(tmpmem);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pkcs7err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pkcs7err.c
-new file mode 100644
-index 0000000..d5baa9b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/pkcs7/pkcs7err.c
-@@ -0,0 +1,131 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason)
-+
-+static ERR_STRING_DATA PKCS7_str_functs[] = {
-+    {ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB), "do_pkcs7_signed_attrib"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME),
-+     "PKCS7_add0_attrib_signing_time"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP),
-+     "PKCS7_add_attrib_smimecap"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE), "PKCS7_add_signature"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_bio_add_digest"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST),
-+     "pkcs7_copy_existing_digest"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_DATAINIT), "PKCS7_dataInit"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO), "pkcs7_decrypt_rinfo"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO), "pkcs7_encode_rinfo"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_FINAL), "PKCS7_final"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_find_digest"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET), "PKCS7_RECIP_INFO_set"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET), "PKCS7_SIGNER_INFO_set"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN), "PKCS7_SIGNER_INFO_sign"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER), "PKCS7_sign_add_signer"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"},
-+    {ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA PKCS7_str_reasons[] = {
-+    {ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR),
-+     "certificate verify error"},
-+    {ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),
-+     "cipher has no object identifier"},
-+    {ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED), "cipher not initialized"},
-+    {ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),
-+     "content and data present"},
-+    {ERR_REASON(PKCS7_R_CTRL_ERROR), "ctrl error"},
-+    {ERR_REASON(PKCS7_R_DECRYPT_ERROR), "decrypt error"},
-+    {ERR_REASON(PKCS7_R_DIGEST_FAILURE), "digest failure"},
-+    {ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE), "encryption ctrl failure"},
-+    {ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),
-+     "encryption not supported for this key type"},
-+    {ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT), "error adding recipient"},
-+    {ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER), "error setting cipher"},
-+    {ERR_REASON(PKCS7_R_INVALID_NULL_POINTER), "invalid null pointer"},
-+    {ERR_REASON(PKCS7_R_INVALID_SIGNED_DATA_TYPE),
-+     "invalid signed data type"},
-+    {ERR_REASON(PKCS7_R_NO_CONTENT), "no content"},
-+    {ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST), "no default digest"},
-+    {ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND),
-+     "no matching digest type found"},
-+    {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),
-+     "no recipient matches certificate"},
-+    {ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA), "no signatures on data"},
-+    {ERR_REASON(PKCS7_R_NO_SIGNERS), "no signers"},
-+    {ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),
-+     "operation not supported on this type"},
-+    {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),
-+     "pkcs7 add signature error"},
-+    {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR), "pkcs7 add signer error"},
-+    {ERR_REASON(PKCS7_R_PKCS7_DATASIGN), "pkcs7 datasign"},
-+    {ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
-+     "private key does not match certificate"},
-+    {ERR_REASON(PKCS7_R_SIGNATURE_FAILURE), "signature failure"},
-+    {ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),
-+     "signer certificate not found"},
-+    {ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE), "signing ctrl failure"},
-+    {ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),
-+     "signing not supported for this key type"},
-+    {ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR), "smime text error"},
-+    {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),
-+     "unable to find certificate"},
-+    {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO), "unable to find mem bio"},
-+    {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST),
-+     "unable to find message digest"},
-+    {ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE), "unknown digest type"},
-+    {ERR_REASON(PKCS7_R_UNKNOWN_OPERATION), "unknown operation"},
-+    {ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE), "unsupported cipher type"},
-+    {ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE),
-+     "unsupported content type"},
-+    {ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE), "wrong content type"},
-+    {ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE), "wrong pkcs7 type"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_PKCS7_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, PKCS7_str_functs);
-+        ERR_load_strings(0, PKCS7_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-armv4.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-armv4.pl
-new file mode 100755
-index 0000000..fc899ce
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-armv4.pl
-@@ -0,0 +1,1252 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+#			IALU(*)/gcc-4.4		NEON
-+#
-+# ARM11xx(ARMv6)	7.78/+100%		-
-+# Cortex-A5		6.35/+130%		3.00
-+# Cortex-A8		6.25/+115%		2.36
-+# Cortex-A9		5.10/+95%		2.55
-+# Cortex-A15		3.85/+85%		1.25(**)
-+# Snapdragon S4		5.70/+100%		1.48(**)
-+#
-+# (*)	this is for -march=armv6, i.e. with bunch of ldrb loading data;
-+# (**)	these are trade-off results, they can be improved by ~8% but at
-+#	the cost of 15/12% regression on Cortex-A5/A7, it's even possible
-+#	to improve Cortex-A9 result, but then A5/A7 loose more than 20%;
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+($ctx,$inp,$len,$padbit)=map("r$_",(0..3));
-+
-+$code.=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+#if defined(__thumb2__)
-+.syntax	unified
-+.thumb
-+#else
-+.code	32
-+#endif
-+
-+.globl	poly1305_emit
-+.globl	poly1305_blocks
-+.globl	poly1305_init
-+.type	poly1305_init,%function
-+.align	5
-+poly1305_init:
-+.Lpoly1305_init:
-+	stmdb	sp!,{r4-r11}
-+
-+	eor	r3,r3,r3
-+	cmp	$inp,#0
-+	str	r3,[$ctx,#0]		@ zero hash value
-+	str	r3,[$ctx,#4]
-+	str	r3,[$ctx,#8]
-+	str	r3,[$ctx,#12]
-+	str	r3,[$ctx,#16]
-+	str	r3,[$ctx,#36]		@ is_base2_26
-+	add	$ctx,$ctx,#20
-+
-+#ifdef	__thumb2__
-+	it	eq
-+#endif
-+	moveq	r0,#0
-+	beq	.Lno_key
-+
-+#if	__ARM_MAX_ARCH__>=7
-+	adr	r11,.Lpoly1305_init
-+	ldr	r12,.LOPENSSL_armcap
-+#endif
-+	ldrb	r4,[$inp,#0]
-+	mov	r10,#0x0fffffff
-+	ldrb	r5,[$inp,#1]
-+	and	r3,r10,#-4		@ 0x0ffffffc
-+	ldrb	r6,[$inp,#2]
-+	ldrb	r7,[$inp,#3]
-+	orr	r4,r4,r5,lsl#8
-+	ldrb	r5,[$inp,#4]
-+	orr	r4,r4,r6,lsl#16
-+	ldrb	r6,[$inp,#5]
-+	orr	r4,r4,r7,lsl#24
-+	ldrb	r7,[$inp,#6]
-+	and	r4,r4,r10
-+
-+#if	__ARM_MAX_ARCH__>=7
-+	ldr	r12,[r11,r12]		@ OPENSSL_armcap_P
-+# ifdef	__APPLE__
-+	ldr	r12,[r12]
-+# endif
-+#endif
-+	ldrb	r8,[$inp,#7]
-+	orr	r5,r5,r6,lsl#8
-+	ldrb	r6,[$inp,#8]
-+	orr	r5,r5,r7,lsl#16
-+	ldrb	r7,[$inp,#9]
-+	orr	r5,r5,r8,lsl#24
-+	ldrb	r8,[$inp,#10]
-+	and	r5,r5,r3
-+
-+#if	__ARM_MAX_ARCH__>=7
-+	tst	r12,#ARMV7_NEON		@ check for NEON
-+# ifdef	__APPLE__
-+	adr	r9,poly1305_blocks_neon
-+	adr	r11,poly1305_blocks
-+#  ifdef __thumb2__
-+	it	ne
-+#  endif
-+	movne	r11,r9
-+	adr	r12,poly1305_emit
-+	adr	r10,poly1305_emit_neon
-+#  ifdef __thumb2__
-+	it	ne
-+#  endif
-+	movne	r12,r10
-+# else
-+#  ifdef __thumb2__
-+	itete	eq
-+#  endif
-+	addeq	r12,r11,#(poly1305_emit-.Lpoly1305_init)
-+	addne	r12,r11,#(poly1305_emit_neon-.Lpoly1305_init)
-+	addeq	r11,r11,#(poly1305_blocks-.Lpoly1305_init)
-+	addne	r11,r11,#(poly1305_blocks_neon-.Lpoly1305_init)
-+# endif
-+# ifdef	__thumb2__
-+	orr	r12,r12,#1	@ thumb-ify address
-+	orr	r11,r11,#1
-+# endif
-+#endif
-+	ldrb	r9,[$inp,#11]
-+	orr	r6,r6,r7,lsl#8
-+	ldrb	r7,[$inp,#12]
-+	orr	r6,r6,r8,lsl#16
-+	ldrb	r8,[$inp,#13]
-+	orr	r6,r6,r9,lsl#24
-+	ldrb	r9,[$inp,#14]
-+	and	r6,r6,r3
-+
-+	ldrb	r10,[$inp,#15]
-+	orr	r7,r7,r8,lsl#8
-+	str	r4,[$ctx,#0]
-+	orr	r7,r7,r9,lsl#16
-+	str	r5,[$ctx,#4]
-+	orr	r7,r7,r10,lsl#24
-+	str	r6,[$ctx,#8]
-+	and	r7,r7,r3
-+	str	r7,[$ctx,#12]
-+#if	__ARM_MAX_ARCH__>=7
-+	stmia	r2,{r11,r12}		@ fill functions table
-+	mov	r0,#1
-+#else
-+	mov	r0,#0
-+#endif
-+.Lno_key:
-+	ldmia	sp!,{r4-r11}
-+#if	__ARM_ARCH__>=5
-+	ret				@ bx	lr
-+#else
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	poly1305_init,.-poly1305_init
-+___
-+{
-+my ($h0,$h1,$h2,$h3,$h4,$r0,$r1,$r2,$r3)=map("r$_",(4..12));
-+my ($s1,$s2,$s3)=($r1,$r2,$r3);
-+
-+$code.=<<___;
-+.type	poly1305_blocks,%function
-+.align	5
-+poly1305_blocks:
-+	stmdb	sp!,{r3-r11,lr}
-+
-+	ands	$len,$len,#-16
-+	beq	.Lno_data
-+
-+	cmp	$padbit,#0
-+	add	$len,$len,$inp		@ end pointer
-+	sub	sp,sp,#32
-+
-+	ldmia	$ctx,{$h0-$r3}		@ load context
-+
-+	str	$ctx,[sp,#12]		@ offload stuff
-+	mov	lr,$inp
-+	str	$len,[sp,#16]
-+	str	$r1,[sp,#20]
-+	str	$r2,[sp,#24]
-+	str	$r3,[sp,#28]
-+	b	.Loop
-+
-+.Loop:
-+#if __ARM_ARCH__<7
-+	ldrb	r0,[lr],#16		@ load input
-+# ifdef	__thumb2__
-+	it	hi
-+# endif
-+	addhi	$h4,$h4,#1		@ 1<<128
-+	ldrb	r1,[lr,#-15]
-+	ldrb	r2,[lr,#-14]
-+	ldrb	r3,[lr,#-13]
-+	orr	r1,r0,r1,lsl#8
-+	ldrb	r0,[lr,#-12]
-+	orr	r2,r1,r2,lsl#16
-+	ldrb	r1,[lr,#-11]
-+	orr	r3,r2,r3,lsl#24
-+	ldrb	r2,[lr,#-10]
-+	adds	$h0,$h0,r3		@ accumulate input
-+
-+	ldrb	r3,[lr,#-9]
-+	orr	r1,r0,r1,lsl#8
-+	ldrb	r0,[lr,#-8]
-+	orr	r2,r1,r2,lsl#16
-+	ldrb	r1,[lr,#-7]
-+	orr	r3,r2,r3,lsl#24
-+	ldrb	r2,[lr,#-6]
-+	adcs	$h1,$h1,r3
-+
-+	ldrb	r3,[lr,#-5]
-+	orr	r1,r0,r1,lsl#8
-+	ldrb	r0,[lr,#-4]
-+	orr	r2,r1,r2,lsl#16
-+	ldrb	r1,[lr,#-3]
-+	orr	r3,r2,r3,lsl#24
-+	ldrb	r2,[lr,#-2]
-+	adcs	$h2,$h2,r3
-+
-+	ldrb	r3,[lr,#-1]
-+	orr	r1,r0,r1,lsl#8
-+	str	lr,[sp,#8]		@ offload input pointer
-+	orr	r2,r1,r2,lsl#16
-+	add	$s1,$r1,$r1,lsr#2
-+	orr	r3,r2,r3,lsl#24
-+#else
-+	ldr	r0,[lr],#16		@ load input
-+# ifdef	__thumb2__
-+	it	hi
-+# endif
-+	addhi	$h4,$h4,#1		@ padbit
-+	ldr	r1,[lr,#-12]
-+	ldr	r2,[lr,#-8]
-+	ldr	r3,[lr,#-4]
-+# ifdef	__ARMEB__
-+	rev	r0,r0
-+	rev	r1,r1
-+	rev	r2,r2
-+	rev	r3,r3
-+# endif
-+	adds	$h0,$h0,r0		@ accumulate input
-+	str	lr,[sp,#8]		@ offload input pointer
-+	adcs	$h1,$h1,r1
-+	add	$s1,$r1,$r1,lsr#2
-+	adcs	$h2,$h2,r2
-+#endif
-+	add	$s2,$r2,$r2,lsr#2
-+	adcs	$h3,$h3,r3
-+	add	$s3,$r3,$r3,lsr#2
-+
-+	umull	r2,r3,$h1,$r0
-+	 adc	$h4,$h4,#0
-+	umull	r0,r1,$h0,$r0
-+	umlal	r2,r3,$h4,$s1
-+	umlal	r0,r1,$h3,$s1
-+	ldr	$r1,[sp,#20]		@ reload $r1
-+	umlal	r2,r3,$h2,$s3
-+	umlal	r0,r1,$h1,$s3
-+	umlal	r2,r3,$h3,$s2
-+	umlal	r0,r1,$h2,$s2
-+	umlal	r2,r3,$h0,$r1
-+	str	r0,[sp,#0]		@ future $h0
-+	 mul	r0,$s2,$h4
-+	ldr	$r2,[sp,#24]		@ reload $r2
-+	adds	r2,r2,r1		@ d1+=d0>>32
-+	 eor	r1,r1,r1
-+	adc	lr,r3,#0		@ future $h2
-+	str	r2,[sp,#4]		@ future $h1
-+
-+	mul	r2,$s3,$h4
-+	eor	r3,r3,r3
-+	umlal	r0,r1,$h3,$s3
-+	ldr	$r3,[sp,#28]		@ reload $r3
-+	umlal	r2,r3,$h3,$r0
-+	umlal	r0,r1,$h2,$r0
-+	umlal	r2,r3,$h2,$r1
-+	umlal	r0,r1,$h1,$r1
-+	umlal	r2,r3,$h1,$r2
-+	umlal	r0,r1,$h0,$r2
-+	umlal	r2,r3,$h0,$r3
-+	ldr	$h0,[sp,#0]
-+	mul	$h4,$r0,$h4
-+	ldr	$h1,[sp,#4]
-+
-+	adds	$h2,lr,r0		@ d2+=d1>>32
-+	ldr	lr,[sp,#8]		@ reload input pointer
-+	adc	r1,r1,#0
-+	adds	$h3,r2,r1		@ d3+=d2>>32
-+	ldr	r0,[sp,#16]		@ reload end pointer
-+	adc	r3,r3,#0
-+	add	$h4,$h4,r3		@ h4+=d3>>32
-+
-+	and	r1,$h4,#-4
-+	and	$h4,$h4,#3
-+	add	r1,r1,r1,lsr#2		@ *=5
-+	adds	$h0,$h0,r1
-+	adcs	$h1,$h1,#0
-+	adcs	$h2,$h2,#0
-+	adcs	$h3,$h3,#0
-+	adc	$h4,$h4,#0
-+
-+	cmp	r0,lr			@ done yet?
-+	bhi	.Loop
-+
-+	ldr	$ctx,[sp,#12]
-+	add	sp,sp,#32
-+	stmia	$ctx,{$h0-$h4}		@ store the result
-+
-+.Lno_data:
-+#if	__ARM_ARCH__>=5
-+	ldmia	sp!,{r3-r11,pc}
-+#else
-+	ldmia	sp!,{r3-r11,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	poly1305_blocks,.-poly1305_blocks
-+___
-+}
-+{
-+my ($ctx,$mac,$nonce)=map("r$_",(0..2));
-+my ($h0,$h1,$h2,$h3,$h4,$g0,$g1,$g2,$g3)=map("r$_",(3..11));
-+my $g4=$h4;
-+
-+$code.=<<___;
-+.type	poly1305_emit,%function
-+.align	5
-+poly1305_emit:
-+	stmdb	sp!,{r4-r11}
-+.Lpoly1305_emit_enter:
-+
-+	ldmia	$ctx,{$h0-$h4}
-+	adds	$g0,$h0,#5		@ compare to modulus
-+	adcs	$g1,$h1,#0
-+	adcs	$g2,$h2,#0
-+	adcs	$g3,$h3,#0
-+	adc	$g4,$h4,#0
-+	tst	$g4,#4			@ did it carry/borrow?
-+
-+#ifdef	__thumb2__
-+	it	ne
-+#endif
-+	movne	$h0,$g0
-+	ldr	$g0,[$nonce,#0]
-+#ifdef	__thumb2__
-+	it	ne
-+#endif
-+	movne	$h1,$g1
-+	ldr	$g1,[$nonce,#4]
-+#ifdef	__thumb2__
-+	it	ne
-+#endif
-+	movne	$h2,$g2
-+	ldr	$g2,[$nonce,#8]
-+#ifdef	__thumb2__
-+	it	ne
-+#endif
-+	movne	$h3,$g3
-+	ldr	$g3,[$nonce,#12]
-+
-+	adds	$h0,$h0,$g0
-+	adcs	$h1,$h1,$g1
-+	adcs	$h2,$h2,$g2
-+	adc	$h3,$h3,$g3
-+
-+#if __ARM_ARCH__>=7
-+# ifdef __ARMEB__
-+	rev	$h0,$h0
-+	rev	$h1,$h1
-+	rev	$h2,$h2
-+	rev	$h3,$h3
-+# endif
-+	str	$h0,[$mac,#0]
-+	str	$h1,[$mac,#4]
-+	str	$h2,[$mac,#8]
-+	str	$h3,[$mac,#12]
-+#else
-+	strb	$h0,[$mac,#0]
-+	mov	$h0,$h0,lsr#8
-+	strb	$h1,[$mac,#4]
-+	mov	$h1,$h1,lsr#8
-+	strb	$h2,[$mac,#8]
-+	mov	$h2,$h2,lsr#8
-+	strb	$h3,[$mac,#12]
-+	mov	$h3,$h3,lsr#8
-+
-+	strb	$h0,[$mac,#1]
-+	mov	$h0,$h0,lsr#8
-+	strb	$h1,[$mac,#5]
-+	mov	$h1,$h1,lsr#8
-+	strb	$h2,[$mac,#9]
-+	mov	$h2,$h2,lsr#8
-+	strb	$h3,[$mac,#13]
-+	mov	$h3,$h3,lsr#8
-+
-+	strb	$h0,[$mac,#2]
-+	mov	$h0,$h0,lsr#8
-+	strb	$h1,[$mac,#6]
-+	mov	$h1,$h1,lsr#8
-+	strb	$h2,[$mac,#10]
-+	mov	$h2,$h2,lsr#8
-+	strb	$h3,[$mac,#14]
-+	mov	$h3,$h3,lsr#8
-+
-+	strb	$h0,[$mac,#3]
-+	strb	$h1,[$mac,#7]
-+	strb	$h2,[$mac,#11]
-+	strb	$h3,[$mac,#15]
-+#endif
-+	ldmia	sp!,{r4-r11}
-+#if	__ARM_ARCH__>=5
-+	ret				@ bx	lr
-+#else
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	poly1305_emit,.-poly1305_emit
-+___
-+{
-+my ($R0,$R1,$S1,$R2,$S2,$R3,$S3,$R4,$S4) = map("d$_",(0..9));
-+my ($D0,$D1,$D2,$D3,$D4, $H0,$H1,$H2,$H3,$H4) = map("q$_",(5..14));
-+my ($T0,$T1,$MASK) = map("q$_",(15,4,0));
-+
-+my ($in2,$zeros,$tbl0,$tbl1) = map("r$_",(4..7));
-+
-+$code.=<<___;
-+#if	__ARM_MAX_ARCH__>=7
-+.fpu	neon
-+
-+.type	poly1305_init_neon,%function
-+.align	5
-+poly1305_init_neon:
-+	ldr	r4,[$ctx,#20]		@ load key base 2^32
-+	ldr	r5,[$ctx,#24]
-+	ldr	r6,[$ctx,#28]
-+	ldr	r7,[$ctx,#32]
-+
-+	and	r2,r4,#0x03ffffff	@ base 2^32 -> base 2^26
-+	mov	r3,r4,lsr#26
-+	mov	r4,r5,lsr#20
-+	orr	r3,r3,r5,lsl#6
-+	mov	r5,r6,lsr#14
-+	orr	r4,r4,r6,lsl#12
-+	mov	r6,r7,lsr#8
-+	orr	r5,r5,r7,lsl#18
-+	and	r3,r3,#0x03ffffff
-+	and	r4,r4,#0x03ffffff
-+	and	r5,r5,#0x03ffffff
-+
-+	vdup.32	$R0,r2			@ r^1 in both lanes
-+	add	r2,r3,r3,lsl#2		@ *5
-+	vdup.32	$R1,r3
-+	add	r3,r4,r4,lsl#2
-+	vdup.32	$S1,r2
-+	vdup.32	$R2,r4
-+	add	r4,r5,r5,lsl#2
-+	vdup.32	$S2,r3
-+	vdup.32	$R3,r5
-+	add	r5,r6,r6,lsl#2
-+	vdup.32	$S3,r4
-+	vdup.32	$R4,r6
-+	vdup.32	$S4,r5
-+
-+	mov	$zeros,#2		@ counter
-+
-+.Lsquare_neon:
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
-+	@ d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
-+	@ d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	@ d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
-+	@ d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
-+
-+	vmull.u32	$D0,$R0,${R0}[1]
-+	vmull.u32	$D1,$R1,${R0}[1]
-+	vmull.u32	$D2,$R2,${R0}[1]
-+	vmull.u32	$D3,$R3,${R0}[1]
-+	vmull.u32	$D4,$R4,${R0}[1]
-+
-+	vmlal.u32	$D0,$R4,${S1}[1]
-+	vmlal.u32	$D1,$R0,${R1}[1]
-+	vmlal.u32	$D2,$R1,${R1}[1]
-+	vmlal.u32	$D3,$R2,${R1}[1]
-+	vmlal.u32	$D4,$R3,${R1}[1]
-+
-+	vmlal.u32	$D0,$R3,${S2}[1]
-+	vmlal.u32	$D1,$R4,${S2}[1]
-+	vmlal.u32	$D3,$R1,${R2}[1]
-+	vmlal.u32	$D2,$R0,${R2}[1]
-+	vmlal.u32	$D4,$R2,${R2}[1]
-+
-+	vmlal.u32	$D0,$R2,${S3}[1]
-+	vmlal.u32	$D3,$R0,${R3}[1]
-+	vmlal.u32	$D1,$R3,${S3}[1]
-+	vmlal.u32	$D2,$R4,${S3}[1]
-+	vmlal.u32	$D4,$R1,${R3}[1]
-+
-+	vmlal.u32	$D3,$R4,${S4}[1]
-+	vmlal.u32	$D0,$R1,${S4}[1]
-+	vmlal.u32	$D1,$R2,${S4}[1]
-+	vmlal.u32	$D2,$R3,${S4}[1]
-+	vmlal.u32	$D4,$R0,${R4}[1]
-+
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
-+	@ and P. Schwabe
-+	@
-+	@ H0>>+H1>>+H2>>+H3>>+H4
-+	@ H3>>+H4>>*5+H0>>+H1
-+	@
-+	@ Trivia.
-+	@
-+	@ Result of multiplication of n-bit number by m-bit number is
-+	@ n+m bits wide. However! Even though 2^n is a n+1-bit number,
-+	@ m-bit number multiplied by 2^n is still n+m bits wide.
-+	@
-+	@ Sum of two n-bit numbers is n+1 bits wide, sum of three - n+2,
-+	@ and so is sum of four. Sum of 2^m n-m-bit numbers and n-bit
-+	@ one is n+1 bits wide.
-+	@
-+	@ >>+ denotes Hnext += Hn>>26, Hn &= 0x3ffffff. This means that
-+	@ H0, H2, H3 are guaranteed to be 26 bits wide, while H1 and H4
-+	@ can be 27. However! In cases when their width exceeds 26 bits
-+	@ they are limited by 2^26+2^6. This in turn means that *sum*
-+	@ of the products with these values can still be viewed as sum
-+	@ of 52-bit numbers as long as the amount of addends is not a
-+	@ power of 2. For example,
-+	@
-+	@ H4 = H4*R0 + H3*R1 + H2*R2 + H1*R3 + H0 * R4,
-+	@
-+	@ which can't be larger than 5 * (2^26 + 2^6) * (2^26 + 2^6), or
-+	@ 5 * (2^52 + 2*2^32 + 2^12), which in turn is smaller than
-+	@ 8 * (2^52) or 2^55. However, the value is then multiplied by
-+	@ by 5, so we should be looking at 5 * 5 * (2^52 + 2^33 + 2^12),
-+	@ which is less than 32 * (2^52) or 2^57. And when processing
-+	@ data we are looking at triple as many addends...
-+	@
-+	@ In key setup procedure pre-reduced H0 is limited by 5*4+1 and
-+	@ 5*H4 - by 5*5 52-bit addends, or 57 bits. But when hashing the
-+	@ input H0 is limited by (5*4+1)*3 addends, or 58 bits, while
-+	@ 5*H4 by 5*5*3, or 59[!] bits. How is this relevant? vmlal.u32
-+	@ instruction accepts 2x32-bit input and writes 2x64-bit result.
-+	@ This means that result of reduction have to be compressed upon
-+	@ loop wrap-around. This can be done in the process of reduction
-+	@ to minimize amount of instructions [as well as amount of
-+	@ 128-bit instructions, which benefits low-end processors], but
-+	@ one has to watch for H2 (which is narrower than H0) and 5*H4
-+	@ not being wider than 58 bits, so that result of right shift
-+	@ by 26 bits fits in 32 bits. This is also useful on x86,
-+	@ because it allows to use paddd in place for paddq, which
-+	@ benefits Atom, where paddq is ridiculously slow.
-+
-+	vshr.u64	$T0,$D3,#26
-+	vmovn.i64	$D3#lo,$D3
-+	 vshr.u64	$T1,$D0,#26
-+	 vmovn.i64	$D0#lo,$D0
-+	vadd.i64	$D4,$D4,$T0		@ h3 -> h4
-+	vbic.i32	$D3#lo,#0xfc000000	@ &=0x03ffffff
-+	 vadd.i64	$D1,$D1,$T1		@ h0 -> h1
-+	 vbic.i32	$D0#lo,#0xfc000000
-+
-+	vshrn.u64	$T0#lo,$D4,#26
-+	vmovn.i64	$D4#lo,$D4
-+	 vshr.u64	$T1,$D1,#26
-+	 vmovn.i64	$D1#lo,$D1
-+	 vadd.i64	$D2,$D2,$T1		@ h1 -> h2
-+	vbic.i32	$D4#lo,#0xfc000000
-+	 vbic.i32	$D1#lo,#0xfc000000
-+
-+	vadd.i32	$D0#lo,$D0#lo,$T0#lo
-+	vshl.u32	$T0#lo,$T0#lo,#2
-+	 vshrn.u64	$T1#lo,$D2,#26
-+	 vmovn.i64	$D2#lo,$D2
-+	vadd.i32	$D0#lo,$D0#lo,$T0#lo	@ h4 -> h0
-+	 vadd.i32	$D3#lo,$D3#lo,$T1#lo	@ h2 -> h3
-+	 vbic.i32	$D2#lo,#0xfc000000
-+
-+	vshr.u32	$T0#lo,$D0#lo,#26
-+	vbic.i32	$D0#lo,#0xfc000000
-+	 vshr.u32	$T1#lo,$D3#lo,#26
-+	 vbic.i32	$D3#lo,#0xfc000000
-+	vadd.i32	$D1#lo,$D1#lo,$T0#lo	@ h0 -> h1
-+	 vadd.i32	$D4#lo,$D4#lo,$T1#lo	@ h3 -> h4
-+
-+	subs		$zeros,$zeros,#1
-+	beq		.Lsquare_break_neon
-+
-+	add		$tbl0,$ctx,#(48+0*9*4)
-+	add		$tbl1,$ctx,#(48+1*9*4)
-+
-+	vtrn.32		$R0,$D0#lo		@ r^2:r^1
-+	vtrn.32		$R2,$D2#lo
-+	vtrn.32		$R3,$D3#lo
-+	vtrn.32		$R1,$D1#lo
-+	vtrn.32		$R4,$D4#lo
-+
-+	vshl.u32	$S2,$R2,#2		@ *5
-+	vshl.u32	$S3,$R3,#2
-+	vshl.u32	$S1,$R1,#2
-+	vshl.u32	$S4,$R4,#2
-+	vadd.i32	$S2,$S2,$R2
-+	vadd.i32	$S1,$S1,$R1
-+	vadd.i32	$S3,$S3,$R3
-+	vadd.i32	$S4,$S4,$R4
-+
-+	vst4.32		{${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!
-+	vst4.32		{${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!
-+	vst4.32		{${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
-+	vst4.32		{${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
-+	vst1.32		{${S4}[0]},[$tbl0,:32]
-+	vst1.32		{${S4}[1]},[$tbl1,:32]
-+
-+	b		.Lsquare_neon
-+
-+.align	4
-+.Lsquare_break_neon:
-+	add		$tbl0,$ctx,#(48+2*4*9)
-+	add		$tbl1,$ctx,#(48+3*4*9)
-+
-+	vmov		$R0,$D0#lo		@ r^4:r^3
-+	vshl.u32	$S1,$D1#lo,#2		@ *5
-+	vmov		$R1,$D1#lo
-+	vshl.u32	$S2,$D2#lo,#2
-+	vmov		$R2,$D2#lo
-+	vshl.u32	$S3,$D3#lo,#2
-+	vmov		$R3,$D3#lo
-+	vshl.u32	$S4,$D4#lo,#2
-+	vmov		$R4,$D4#lo
-+	vadd.i32	$S1,$S1,$D1#lo
-+	vadd.i32	$S2,$S2,$D2#lo
-+	vadd.i32	$S3,$S3,$D3#lo
-+	vadd.i32	$S4,$S4,$D4#lo
-+
-+	vst4.32		{${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!
-+	vst4.32		{${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!
-+	vst4.32		{${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
-+	vst4.32		{${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
-+	vst1.32		{${S4}[0]},[$tbl0]
-+	vst1.32		{${S4}[1]},[$tbl1]
-+
-+	ret				@ bx	lr
-+.size	poly1305_init_neon,.-poly1305_init_neon
-+
-+.type	poly1305_blocks_neon,%function
-+.align	5
-+poly1305_blocks_neon:
-+	ldr	ip,[$ctx,#36]		@ is_base2_26
-+	ands	$len,$len,#-16
-+	beq	.Lno_data_neon
-+
-+	cmp	$len,#64
-+	bhs	.Lenter_neon
-+	tst	ip,ip			@ is_base2_26?
-+	beq	poly1305_blocks
-+
-+.Lenter_neon:
-+	stmdb	sp!,{r4-r7}
-+	vstmdb	sp!,{d8-d15}		@ ABI specification says so
-+
-+	tst	ip,ip			@ is_base2_26?
-+	bne	.Lbase2_26_neon
-+
-+	stmdb	sp!,{r1-r3,lr}
-+	bl	poly1305_init_neon
-+
-+	ldr	r4,[$ctx,#0]		@ load hash value base 2^32
-+	ldr	r5,[$ctx,#4]
-+	ldr	r6,[$ctx,#8]
-+	ldr	r7,[$ctx,#12]
-+	ldr	ip,[$ctx,#16]
-+
-+	and	r2,r4,#0x03ffffff	@ base 2^32 -> base 2^26
-+	mov	r3,r4,lsr#26
-+	 veor	$D0#lo,$D0#lo,$D0#lo
-+	mov	r4,r5,lsr#20
-+	orr	r3,r3,r5,lsl#6
-+	 veor	$D1#lo,$D1#lo,$D1#lo
-+	mov	r5,r6,lsr#14
-+	orr	r4,r4,r6,lsl#12
-+	 veor	$D2#lo,$D2#lo,$D2#lo
-+	mov	r6,r7,lsr#8
-+	orr	r5,r5,r7,lsl#18
-+	 veor	$D3#lo,$D3#lo,$D3#lo
-+	and	r3,r3,#0x03ffffff
-+	orr	r6,r6,ip,lsl#24
-+	 veor	$D4#lo,$D4#lo,$D4#lo
-+	and	r4,r4,#0x03ffffff
-+	mov	r1,#1
-+	and	r5,r5,#0x03ffffff
-+	str	r1,[$ctx,#36]		@ is_base2_26
-+
-+	vmov.32	$D0#lo[0],r2
-+	vmov.32	$D1#lo[0],r3
-+	vmov.32	$D2#lo[0],r4
-+	vmov.32	$D3#lo[0],r5
-+	vmov.32	$D4#lo[0],r6
-+	adr	$zeros,.Lzeros
-+
-+	ldmia	sp!,{r1-r3,lr}
-+	b	.Lbase2_32_neon
-+
-+.align	4
-+.Lbase2_26_neon:
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ load hash value
-+
-+	veor		$D0#lo,$D0#lo,$D0#lo
-+	veor		$D1#lo,$D1#lo,$D1#lo
-+	veor		$D2#lo,$D2#lo,$D2#lo
-+	veor		$D3#lo,$D3#lo,$D3#lo
-+	veor		$D4#lo,$D4#lo,$D4#lo
-+	vld4.32		{$D0#lo[0],$D1#lo[0],$D2#lo[0],$D3#lo[0]},[$ctx]!
-+	adr		$zeros,.Lzeros
-+	vld1.32		{$D4#lo[0]},[$ctx]
-+	sub		$ctx,$ctx,#16		@ rewind
-+
-+.Lbase2_32_neon:
-+	add		$in2,$inp,#32
-+	mov		$padbit,$padbit,lsl#24
-+	tst		$len,#31
-+	beq		.Leven
-+
-+	vld4.32		{$H0#lo[0],$H1#lo[0],$H2#lo[0],$H3#lo[0]},[$inp]!
-+	vmov.32		$H4#lo[0],$padbit
-+	sub		$len,$len,#16
-+	add		$in2,$inp,#32
-+
-+# ifdef	__ARMEB__
-+	vrev32.8	$H0,$H0
-+	vrev32.8	$H3,$H3
-+	vrev32.8	$H1,$H1
-+	vrev32.8	$H2,$H2
-+# endif
-+	vsri.u32	$H4#lo,$H3#lo,#8	@ base 2^32 -> base 2^26
-+	vshl.u32	$H3#lo,$H3#lo,#18
-+
-+	vsri.u32	$H3#lo,$H2#lo,#14
-+	vshl.u32	$H2#lo,$H2#lo,#12
-+	vadd.i32	$H4#hi,$H4#lo,$D4#lo	@ add hash value and move to #hi
-+
-+	vbic.i32	$H3#lo,#0xfc000000
-+	vsri.u32	$H2#lo,$H1#lo,#20
-+	vshl.u32	$H1#lo,$H1#lo,#6
-+
-+	vbic.i32	$H2#lo,#0xfc000000
-+	vsri.u32	$H1#lo,$H0#lo,#26
-+	vadd.i32	$H3#hi,$H3#lo,$D3#lo
-+
-+	vbic.i32	$H0#lo,#0xfc000000
-+	vbic.i32	$H1#lo,#0xfc000000
-+	vadd.i32	$H2#hi,$H2#lo,$D2#lo
-+
-+	vadd.i32	$H0#hi,$H0#lo,$D0#lo
-+	vadd.i32	$H1#hi,$H1#lo,$D1#lo
-+
-+	mov		$tbl1,$zeros
-+	add		$tbl0,$ctx,#48
-+
-+	cmp		$len,$len
-+	b		.Long_tail
-+
-+.align	4
-+.Leven:
-+	subs		$len,$len,#64
-+	it		lo
-+	movlo		$in2,$zeros
-+
-+	vmov.i32	$H4,#1<<24		@ padbit, yes, always
-+	vld4.32		{$H0#lo,$H1#lo,$H2#lo,$H3#lo},[$inp]	@ inp[0:1]
-+	add		$inp,$inp,#64
-+	vld4.32		{$H0#hi,$H1#hi,$H2#hi,$H3#hi},[$in2]	@ inp[2:3] (or 0)
-+	add		$in2,$in2,#64
-+	itt		hi
-+	addhi		$tbl1,$ctx,#(48+1*9*4)
-+	addhi		$tbl0,$ctx,#(48+3*9*4)
-+
-+# ifdef	__ARMEB__
-+	vrev32.8	$H0,$H0
-+	vrev32.8	$H3,$H3
-+	vrev32.8	$H1,$H1
-+	vrev32.8	$H2,$H2
-+# endif
-+	vsri.u32	$H4,$H3,#8		@ base 2^32 -> base 2^26
-+	vshl.u32	$H3,$H3,#18
-+
-+	vsri.u32	$H3,$H2,#14
-+	vshl.u32	$H2,$H2,#12
-+
-+	vbic.i32	$H3,#0xfc000000
-+	vsri.u32	$H2,$H1,#20
-+	vshl.u32	$H1,$H1,#6
-+
-+	vbic.i32	$H2,#0xfc000000
-+	vsri.u32	$H1,$H0,#26
-+
-+	vbic.i32	$H0,#0xfc000000
-+	vbic.i32	$H1,#0xfc000000
-+
-+	bls		.Lskip_loop
-+
-+	vld4.32		{${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!	@ load r^2
-+	vld4.32		{${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!	@ load r^4
-+	vld4.32		{${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
-+	vld4.32		{${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
-+	b		.Loop_neon
-+
-+.align	5
-+.Loop_neon:
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
-+	@ ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
-+	@   \___________________/
-+	@ ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
-+	@ ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
-+	@   \___________________/ \____________________/
-+	@
-+	@ Note that we start with inp[2:3]*r^2. This is because it
-+	@ doesn't depend on reduction in previous iteration.
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
-+	@ d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
-+	@ d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	@ d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
-+	@ d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
-+
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ inp[2:3]*r^2
-+
-+	vadd.i32	$H2#lo,$H2#lo,$D2#lo	@ accumulate inp[0:1]
-+	vmull.u32	$D2,$H2#hi,${R0}[1]
-+	vadd.i32	$H0#lo,$H0#lo,$D0#lo
-+	vmull.u32	$D0,$H0#hi,${R0}[1]
-+	vadd.i32	$H3#lo,$H3#lo,$D3#lo
-+	vmull.u32	$D3,$H3#hi,${R0}[1]
-+	vmlal.u32	$D2,$H1#hi,${R1}[1]
-+	vadd.i32	$H1#lo,$H1#lo,$D1#lo
-+	vmull.u32	$D1,$H1#hi,${R0}[1]
-+
-+	vadd.i32	$H4#lo,$H4#lo,$D4#lo
-+	vmull.u32	$D4,$H4#hi,${R0}[1]
-+	subs		$len,$len,#64
-+	vmlal.u32	$D0,$H4#hi,${S1}[1]
-+	it		lo
-+	movlo		$in2,$zeros
-+	vmlal.u32	$D3,$H2#hi,${R1}[1]
-+	vld1.32		${S4}[1],[$tbl1,:32]
-+	vmlal.u32	$D1,$H0#hi,${R1}[1]
-+	vmlal.u32	$D4,$H3#hi,${R1}[1]
-+
-+	vmlal.u32	$D0,$H3#hi,${S2}[1]
-+	vmlal.u32	$D3,$H1#hi,${R2}[1]
-+	vmlal.u32	$D4,$H2#hi,${R2}[1]
-+	vmlal.u32	$D1,$H4#hi,${S2}[1]
-+	vmlal.u32	$D2,$H0#hi,${R2}[1]
-+
-+	vmlal.u32	$D3,$H0#hi,${R3}[1]
-+	vmlal.u32	$D0,$H2#hi,${S3}[1]
-+	vmlal.u32	$D4,$H1#hi,${R3}[1]
-+	vmlal.u32	$D1,$H3#hi,${S3}[1]
-+	vmlal.u32	$D2,$H4#hi,${S3}[1]
-+
-+	vmlal.u32	$D3,$H4#hi,${S4}[1]
-+	vmlal.u32	$D0,$H1#hi,${S4}[1]
-+	vmlal.u32	$D4,$H0#hi,${R4}[1]
-+	vmlal.u32	$D1,$H2#hi,${S4}[1]
-+	vmlal.u32	$D2,$H3#hi,${S4}[1]
-+
-+	vld4.32		{$H0#hi,$H1#hi,$H2#hi,$H3#hi},[$in2]	@ inp[2:3] (or 0)
-+	add		$in2,$in2,#64
-+
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ (hash+inp[0:1])*r^4 and accumulate
-+
-+	vmlal.u32	$D3,$H3#lo,${R0}[0]
-+	vmlal.u32	$D0,$H0#lo,${R0}[0]
-+	vmlal.u32	$D4,$H4#lo,${R0}[0]
-+	vmlal.u32	$D1,$H1#lo,${R0}[0]
-+	vmlal.u32	$D2,$H2#lo,${R0}[0]
-+	vld1.32		${S4}[0],[$tbl0,:32]
-+
-+	vmlal.u32	$D3,$H2#lo,${R1}[0]
-+	vmlal.u32	$D0,$H4#lo,${S1}[0]
-+	vmlal.u32	$D4,$H3#lo,${R1}[0]
-+	vmlal.u32	$D1,$H0#lo,${R1}[0]
-+	vmlal.u32	$D2,$H1#lo,${R1}[0]
-+
-+	vmlal.u32	$D3,$H1#lo,${R2}[0]
-+	vmlal.u32	$D0,$H3#lo,${S2}[0]
-+	vmlal.u32	$D4,$H2#lo,${R2}[0]
-+	vmlal.u32	$D1,$H4#lo,${S2}[0]
-+	vmlal.u32	$D2,$H0#lo,${R2}[0]
-+
-+	vmlal.u32	$D3,$H0#lo,${R3}[0]
-+	vmlal.u32	$D0,$H2#lo,${S3}[0]
-+	vmlal.u32	$D4,$H1#lo,${R3}[0]
-+	vmlal.u32	$D1,$H3#lo,${S3}[0]
-+	vmlal.u32	$D3,$H4#lo,${S4}[0]
-+
-+	vmlal.u32	$D2,$H4#lo,${S3}[0]
-+	vmlal.u32	$D0,$H1#lo,${S4}[0]
-+	vmlal.u32	$D4,$H0#lo,${R4}[0]
-+	vmov.i32	$H4,#1<<24		@ padbit, yes, always
-+	vmlal.u32	$D1,$H2#lo,${S4}[0]
-+	vmlal.u32	$D2,$H3#lo,${S4}[0]
-+
-+	vld4.32		{$H0#lo,$H1#lo,$H2#lo,$H3#lo},[$inp]	@ inp[0:1]
-+	add		$inp,$inp,#64
-+# ifdef	__ARMEB__
-+	vrev32.8	$H0,$H0
-+	vrev32.8	$H1,$H1
-+	vrev32.8	$H2,$H2
-+	vrev32.8	$H3,$H3
-+# endif
-+
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ lazy reduction interleaved with base 2^32 -> base 2^26 of
-+	@ inp[0:3] previously loaded to $H0-$H3 and smashed to $H0-$H4.
-+
-+	vshr.u64	$T0,$D3,#26
-+	vmovn.i64	$D3#lo,$D3
-+	 vshr.u64	$T1,$D0,#26
-+	 vmovn.i64	$D0#lo,$D0
-+	vadd.i64	$D4,$D4,$T0		@ h3 -> h4
-+	vbic.i32	$D3#lo,#0xfc000000
-+	  vsri.u32	$H4,$H3,#8		@ base 2^32 -> base 2^26
-+	 vadd.i64	$D1,$D1,$T1		@ h0 -> h1
-+	  vshl.u32	$H3,$H3,#18
-+	 vbic.i32	$D0#lo,#0xfc000000
-+
-+	vshrn.u64	$T0#lo,$D4,#26
-+	vmovn.i64	$D4#lo,$D4
-+	 vshr.u64	$T1,$D1,#26
-+	 vmovn.i64	$D1#lo,$D1
-+	 vadd.i64	$D2,$D2,$T1		@ h1 -> h2
-+	  vsri.u32	$H3,$H2,#14
-+	vbic.i32	$D4#lo,#0xfc000000
-+	  vshl.u32	$H2,$H2,#12
-+	 vbic.i32	$D1#lo,#0xfc000000
-+
-+	vadd.i32	$D0#lo,$D0#lo,$T0#lo
-+	vshl.u32	$T0#lo,$T0#lo,#2
-+	  vbic.i32	$H3,#0xfc000000
-+	 vshrn.u64	$T1#lo,$D2,#26
-+	 vmovn.i64	$D2#lo,$D2
-+	vaddl.u32	$D0,$D0#lo,$T0#lo	@ h4 -> h0 [widen for a sec]
-+	  vsri.u32	$H2,$H1,#20
-+	 vadd.i32	$D3#lo,$D3#lo,$T1#lo	@ h2 -> h3
-+	  vshl.u32	$H1,$H1,#6
-+	 vbic.i32	$D2#lo,#0xfc000000
-+	  vbic.i32	$H2,#0xfc000000
-+
-+	vshrn.u64	$T0#lo,$D0,#26		@ re-narrow
-+	vmovn.i64	$D0#lo,$D0
-+	  vsri.u32	$H1,$H0,#26
-+	  vbic.i32	$H0,#0xfc000000
-+	 vshr.u32	$T1#lo,$D3#lo,#26
-+	 vbic.i32	$D3#lo,#0xfc000000
-+	vbic.i32	$D0#lo,#0xfc000000
-+	vadd.i32	$D1#lo,$D1#lo,$T0#lo	@ h0 -> h1
-+	 vadd.i32	$D4#lo,$D4#lo,$T1#lo	@ h3 -> h4
-+	  vbic.i32	$H1,#0xfc000000
-+
-+	bhi		.Loop_neon
-+
-+.Lskip_loop:
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
-+
-+	add		$tbl1,$ctx,#(48+0*9*4)
-+	add		$tbl0,$ctx,#(48+1*9*4)
-+	adds		$len,$len,#32
-+	it		ne
-+	movne		$len,#0
-+	bne		.Long_tail
-+
-+	vadd.i32	$H2#hi,$H2#lo,$D2#lo	@ add hash value and move to #hi
-+	vadd.i32	$H0#hi,$H0#lo,$D0#lo
-+	vadd.i32	$H3#hi,$H3#lo,$D3#lo
-+	vadd.i32	$H1#hi,$H1#lo,$D1#lo
-+	vadd.i32	$H4#hi,$H4#lo,$D4#lo
-+
-+.Long_tail:
-+	vld4.32		{${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!	@ load r^1
-+	vld4.32		{${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!	@ load r^2
-+
-+	vadd.i32	$H2#lo,$H2#lo,$D2#lo	@ can be redundant
-+	vmull.u32	$D2,$H2#hi,$R0
-+	vadd.i32	$H0#lo,$H0#lo,$D0#lo
-+	vmull.u32	$D0,$H0#hi,$R0
-+	vadd.i32	$H3#lo,$H3#lo,$D3#lo
-+	vmull.u32	$D3,$H3#hi,$R0
-+	vadd.i32	$H1#lo,$H1#lo,$D1#lo
-+	vmull.u32	$D1,$H1#hi,$R0
-+	vadd.i32	$H4#lo,$H4#lo,$D4#lo
-+	vmull.u32	$D4,$H4#hi,$R0
-+
-+	vmlal.u32	$D0,$H4#hi,$S1
-+	vld4.32		{${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
-+	vmlal.u32	$D3,$H2#hi,$R1
-+	vld4.32		{${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
-+	vmlal.u32	$D1,$H0#hi,$R1
-+	vmlal.u32	$D4,$H3#hi,$R1
-+	vmlal.u32	$D2,$H1#hi,$R1
-+
-+	vmlal.u32	$D3,$H1#hi,$R2
-+	vld1.32		${S4}[1],[$tbl1,:32]
-+	vmlal.u32	$D0,$H3#hi,$S2
-+	vld1.32		${S4}[0],[$tbl0,:32]
-+	vmlal.u32	$D4,$H2#hi,$R2
-+	vmlal.u32	$D1,$H4#hi,$S2
-+	vmlal.u32	$D2,$H0#hi,$R2
-+
-+	vmlal.u32	$D3,$H0#hi,$R3
-+	 it		ne
-+	 addne		$tbl1,$ctx,#(48+2*9*4)
-+	vmlal.u32	$D0,$H2#hi,$S3
-+	 it		ne
-+	 addne		$tbl0,$ctx,#(48+3*9*4)
-+	vmlal.u32	$D4,$H1#hi,$R3
-+	vmlal.u32	$D1,$H3#hi,$S3
-+	vmlal.u32	$D2,$H4#hi,$S3
-+
-+	vmlal.u32	$D3,$H4#hi,$S4
-+	 vorn		$MASK,$MASK,$MASK	@ all-ones, can be redundant
-+	vmlal.u32	$D0,$H1#hi,$S4
-+	 vshr.u64	$MASK,$MASK,#38
-+	vmlal.u32	$D4,$H0#hi,$R4
-+	vmlal.u32	$D1,$H2#hi,$S4
-+	vmlal.u32	$D2,$H3#hi,$S4
-+
-+	beq		.Lshort_tail
-+
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ (hash+inp[0:1])*r^4:r^3 and accumulate
-+
-+	vld4.32		{${R0}[1],${R1}[1],${S1}[1],${R2}[1]},[$tbl1]!	@ load r^3
-+	vld4.32		{${R0}[0],${R1}[0],${S1}[0],${R2}[0]},[$tbl0]!	@ load r^4
-+
-+	vmlal.u32	$D2,$H2#lo,$R0
-+	vmlal.u32	$D0,$H0#lo,$R0
-+	vmlal.u32	$D3,$H3#lo,$R0
-+	vmlal.u32	$D1,$H1#lo,$R0
-+	vmlal.u32	$D4,$H4#lo,$R0
-+
-+	vmlal.u32	$D0,$H4#lo,$S1
-+	vld4.32		{${S2}[1],${R3}[1],${S3}[1],${R4}[1]},[$tbl1]!
-+	vmlal.u32	$D3,$H2#lo,$R1
-+	vld4.32		{${S2}[0],${R3}[0],${S3}[0],${R4}[0]},[$tbl0]!
-+	vmlal.u32	$D1,$H0#lo,$R1
-+	vmlal.u32	$D4,$H3#lo,$R1
-+	vmlal.u32	$D2,$H1#lo,$R1
-+
-+	vmlal.u32	$D3,$H1#lo,$R2
-+	vld1.32		${S4}[1],[$tbl1,:32]
-+	vmlal.u32	$D0,$H3#lo,$S2
-+	vld1.32		${S4}[0],[$tbl0,:32]
-+	vmlal.u32	$D4,$H2#lo,$R2
-+	vmlal.u32	$D1,$H4#lo,$S2
-+	vmlal.u32	$D2,$H0#lo,$R2
-+
-+	vmlal.u32	$D3,$H0#lo,$R3
-+	vmlal.u32	$D0,$H2#lo,$S3
-+	vmlal.u32	$D4,$H1#lo,$R3
-+	vmlal.u32	$D1,$H3#lo,$S3
-+	vmlal.u32	$D2,$H4#lo,$S3
-+
-+	vmlal.u32	$D3,$H4#lo,$S4
-+	 vorn		$MASK,$MASK,$MASK	@ all-ones
-+	vmlal.u32	$D0,$H1#lo,$S4
-+	 vshr.u64	$MASK,$MASK,#38
-+	vmlal.u32	$D4,$H0#lo,$R4
-+	vmlal.u32	$D1,$H2#lo,$S4
-+	vmlal.u32	$D2,$H3#lo,$S4
-+
-+.Lshort_tail:
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ horizontal addition
-+
-+	vadd.i64	$D3#lo,$D3#lo,$D3#hi
-+	vadd.i64	$D0#lo,$D0#lo,$D0#hi
-+	vadd.i64	$D4#lo,$D4#lo,$D4#hi
-+	vadd.i64	$D1#lo,$D1#lo,$D1#hi
-+	vadd.i64	$D2#lo,$D2#lo,$D2#hi
-+
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ lazy reduction, but without narrowing
-+
-+	vshr.u64	$T0,$D3,#26
-+	vand.i64	$D3,$D3,$MASK
-+	 vshr.u64	$T1,$D0,#26
-+	 vand.i64	$D0,$D0,$MASK
-+	vadd.i64	$D4,$D4,$T0		@ h3 -> h4
-+	 vadd.i64	$D1,$D1,$T1		@ h0 -> h1
-+
-+	vshr.u64	$T0,$D4,#26
-+	vand.i64	$D4,$D4,$MASK
-+	 vshr.u64	$T1,$D1,#26
-+	 vand.i64	$D1,$D1,$MASK
-+	 vadd.i64	$D2,$D2,$T1		@ h1 -> h2
-+
-+	vadd.i64	$D0,$D0,$T0
-+	vshl.u64	$T0,$T0,#2
-+	 vshr.u64	$T1,$D2,#26
-+	 vand.i64	$D2,$D2,$MASK
-+	vadd.i64	$D0,$D0,$T0		@ h4 -> h0
-+	 vadd.i64	$D3,$D3,$T1		@ h2 -> h3
-+
-+	vshr.u64	$T0,$D0,#26
-+	vand.i64	$D0,$D0,$MASK
-+	 vshr.u64	$T1,$D3,#26
-+	 vand.i64	$D3,$D3,$MASK
-+	vadd.i64	$D1,$D1,$T0		@ h0 -> h1
-+	 vadd.i64	$D4,$D4,$T1		@ h3 -> h4
-+
-+	cmp		$len,#0
-+	bne		.Leven
-+
-+	@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-+	@ store hash value
-+
-+	vst4.32		{$D0#lo[0],$D1#lo[0],$D2#lo[0],$D3#lo[0]},[$ctx]!
-+	vst1.32		{$D4#lo[0]},[$ctx]
-+
-+	vldmia	sp!,{d8-d15}			@ epilogue
-+	ldmia	sp!,{r4-r7}
-+.Lno_data_neon:
-+	ret					@ bx	lr
-+.size	poly1305_blocks_neon,.-poly1305_blocks_neon
-+
-+.type	poly1305_emit_neon,%function
-+.align	5
-+poly1305_emit_neon:
-+	ldr	ip,[$ctx,#36]		@ is_base2_26
-+
-+	stmdb	sp!,{r4-r11}
-+
-+	tst	ip,ip
-+	beq	.Lpoly1305_emit_enter
-+
-+	ldmia	$ctx,{$h0-$h4}
-+	eor	$g0,$g0,$g0
-+
-+	adds	$h0,$h0,$h1,lsl#26	@ base 2^26 -> base 2^32
-+	mov	$h1,$h1,lsr#6
-+	adcs	$h1,$h1,$h2,lsl#20
-+	mov	$h2,$h2,lsr#12
-+	adcs	$h2,$h2,$h3,lsl#14
-+	mov	$h3,$h3,lsr#18
-+	adcs	$h3,$h3,$h4,lsl#8
-+	adc	$h4,$g0,$h4,lsr#24	@ can be partially reduced ...
-+
-+	and	$g0,$h4,#-4		@ ... so reduce
-+	and	$h4,$h3,#3
-+	add	$g0,$g0,$g0,lsr#2	@ *= 5
-+	adds	$h0,$h0,$g0
-+	adcs	$h1,$h1,#0
-+	adcs	$h2,$h2,#0
-+	adcs	$h3,$h3,#0
-+	adc	$h4,$h4,#0
-+
-+	adds	$g0,$h0,#5		@ compare to modulus
-+	adcs	$g1,$h1,#0
-+	adcs	$g2,$h2,#0
-+	adcs	$g3,$h3,#0
-+	adc	$g4,$h4,#0
-+	tst	$g4,#4			@ did it carry/borrow?
-+
-+	it	ne
-+	movne	$h0,$g0
-+	ldr	$g0,[$nonce,#0]
-+	it	ne
-+	movne	$h1,$g1
-+	ldr	$g1,[$nonce,#4]
-+	it	ne
-+	movne	$h2,$g2
-+	ldr	$g2,[$nonce,#8]
-+	it	ne
-+	movne	$h3,$g3
-+	ldr	$g3,[$nonce,#12]
-+
-+	adds	$h0,$h0,$g0		@ accumulate nonce
-+	adcs	$h1,$h1,$g1
-+	adcs	$h2,$h2,$g2
-+	adc	$h3,$h3,$g3
-+
-+# ifdef __ARMEB__
-+	rev	$h0,$h0
-+	rev	$h1,$h1
-+	rev	$h2,$h2
-+	rev	$h3,$h3
-+# endif
-+	str	$h0,[$mac,#0]		@ store the result
-+	str	$h1,[$mac,#4]
-+	str	$h2,[$mac,#8]
-+	str	$h3,[$mac,#12]
-+
-+	ldmia	sp!,{r4-r11}
-+	ret				@ bx	lr
-+.size	poly1305_emit_neon,.-poly1305_emit_neon
-+
-+.align	5
-+.Lzeros:
-+.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-+.LOPENSSL_armcap:
-+.word	OPENSSL_armcap_P-.Lpoly1305_init
-+#endif
-+___
-+}	}
-+$code.=<<___;
-+.asciz	"Poly1305 for ARMv4/NEON, CRYPTOGAMS by "
-+.align	2
-+#if	__ARM_MAX_ARCH__>=7
-+.comm   OPENSSL_armcap_P,4,4
-+#endif
-+___
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo	or
-+	s/\bret\b/bx	lr/go						or
-+	s/\bbx\s+lr\b/.word\t0xe12fff1e/go;	# make it possible to compile with -march=armv4
-+
-+	print $_,"\n";
-+}
-+close STDOUT; # enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-armv8.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-armv8.pl
-new file mode 100755
-index 0000000..607696c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-armv8.pl
-@@ -0,0 +1,939 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements Poly1305 hash for ARMv8.
-+#
-+# June 2015
-+#
-+# Numbers are cycles per processed byte with poly1305_blocks alone.
-+#
-+#		IALU/gcc-4.9	NEON
-+#
-+# Apple A7	1.86/+5%	0.72
-+# Cortex-A53	2.69/+58%	1.47
-+# Cortex-A57	2.70/+7%	1.14
-+# Denver	1.64/+50%	1.18(*)
-+# X-Gene	2.13/+68%	2.27
-+# Mongoose	1.77/+75%	1.12
-+#
-+# (*)	estimate based on resources availability is less than 1.0,
-+#	i.e. measured result is worse than expected, presumably binary
-+#	translator is not almighty;
-+
-+$flavour=shift;
-+$output=shift;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+my ($ctx,$inp,$len,$padbit) = map("x$_",(0..3));
-+my ($mac,$nonce)=($inp,$len);
-+
-+my ($h0,$h1,$h2,$r0,$r1,$s1,$t0,$t1,$d0,$d1,$d2) = map("x$_",(4..14));
-+
-+$code.=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+
-+// forward "declarations" are required for Apple
-+.extern	OPENSSL_armcap_P
-+.globl	poly1305_blocks
-+.globl	poly1305_emit
-+
-+.globl	poly1305_init
-+.type	poly1305_init,%function
-+.align	5
-+poly1305_init:
-+	cmp	$inp,xzr
-+	stp	xzr,xzr,[$ctx]		// zero hash value
-+	stp	xzr,xzr,[$ctx,#16]	// [along with is_base2_26]
-+
-+	csel	x0,xzr,x0,eq
-+	b.eq	.Lno_key
-+
-+#ifdef	__ILP32__
-+	ldrsw	$t1,.LOPENSSL_armcap_P
-+#else
-+	ldr	$t1,.LOPENSSL_armcap_P
-+#endif
-+	adr	$t0,.LOPENSSL_armcap_P
-+
-+	ldp	$r0,$r1,[$inp]		// load key
-+	mov	$s1,#0xfffffffc0fffffff
-+	movk	$s1,#0x0fff,lsl#48
-+	ldr	w17,[$t0,$t1]
-+#ifdef	__ARMEB__
-+	rev	$r0,$r0			// flip bytes
-+	rev	$r1,$r1
-+#endif
-+	and	$r0,$r0,$s1		// &=0ffffffc0fffffff
-+	and	$s1,$s1,#-4
-+	and	$r1,$r1,$s1		// &=0ffffffc0ffffffc
-+	stp	$r0,$r1,[$ctx,#32]	// save key value
-+
-+	tst	w17,#ARMV7_NEON
-+
-+	adr	$d0,poly1305_blocks
-+	adr	$r0,poly1305_blocks_neon
-+	adr	$d1,poly1305_emit
-+	adr	$r1,poly1305_emit_neon
-+
-+	csel	$d0,$d0,$r0,eq
-+	csel	$d1,$d1,$r1,eq
-+
-+	stp	$d0,$d1,[$len]
-+
-+	mov	x0,#1
-+.Lno_key:
-+	ret
-+.size	poly1305_init,.-poly1305_init
-+
-+.type	poly1305_blocks,%function
-+.align	5
-+poly1305_blocks:
-+	ands	$len,$len,#-16
-+	b.eq	.Lno_data
-+
-+	ldp	$h0,$h1,[$ctx]		// load hash value
-+	ldp	$r0,$r1,[$ctx,#32]	// load key value
-+	ldr	$h2,[$ctx,#16]
-+	add	$s1,$r1,$r1,lsr#2	// s1 = r1 + (r1 >> 2)
-+	b	.Loop
-+
-+.align	5
-+.Loop:
-+	ldp	$t0,$t1,[$inp],#16	// load input
-+	sub	$len,$len,#16
-+#ifdef	__ARMEB__
-+	rev	$t0,$t0
-+	rev	$t1,$t1
-+#endif
-+	adds	$h0,$h0,$t0		// accumulate input
-+	adcs	$h1,$h1,$t1
-+
-+	mul	$d0,$h0,$r0		// h0*r0
-+	adc	$h2,$h2,$padbit
-+	umulh	$d1,$h0,$r0
-+
-+	mul	$t0,$h1,$s1		// h1*5*r1
-+	umulh	$t1,$h1,$s1
-+
-+	adds	$d0,$d0,$t0
-+	mul	$t0,$h0,$r1		// h0*r1
-+	adc	$d1,$d1,$t1
-+	umulh	$d2,$h0,$r1
-+
-+	adds	$d1,$d1,$t0
-+	mul	$t0,$h1,$r0		// h1*r0
-+	adc	$d2,$d2,xzr
-+	umulh	$t1,$h1,$r0
-+
-+	adds	$d1,$d1,$t0
-+	mul	$t0,$h2,$s1		// h2*5*r1
-+	adc	$d2,$d2,$t1
-+	mul	$t1,$h2,$r0		// h2*r0
-+
-+	adds	$d1,$d1,$t0
-+	adc	$d2,$d2,$t1
-+
-+	and	$t0,$d2,#-4		// final reduction
-+	and	$h2,$d2,#3
-+	add	$t0,$t0,$d2,lsr#2
-+	adds	$h0,$d0,$t0
-+	adcs	$h1,$d1,xzr
-+	adc	$h2,$h2,xzr
-+
-+	cbnz	$len,.Loop
-+
-+	stp	$h0,$h1,[$ctx]		// store hash value
-+	str	$h2,[$ctx,#16]
-+
-+.Lno_data:
-+	ret
-+.size	poly1305_blocks,.-poly1305_blocks
-+
-+.type	poly1305_emit,%function
-+.align	5
-+poly1305_emit:
-+	ldp	$h0,$h1,[$ctx]		// load hash base 2^64
-+	ldr	$h2,[$ctx,#16]
-+	ldp	$t0,$t1,[$nonce]	// load nonce
-+
-+	adds	$d0,$h0,#5		// compare to modulus
-+	adcs	$d1,$h1,xzr
-+	adc	$d2,$h2,xzr
-+
-+	tst	$d2,#-4			// see if it's carried/borrowed
-+
-+	csel	$h0,$h0,$d0,eq
-+	csel	$h1,$h1,$d1,eq
-+
-+#ifdef	__ARMEB__
-+	ror	$t0,$t0,#32		// flip nonce words
-+	ror	$t1,$t1,#32
-+#endif
-+	adds	$h0,$h0,$t0		// accumulate nonce
-+	adc	$h1,$h1,$t1
-+#ifdef	__ARMEB__
-+	rev	$h0,$h0			// flip output bytes
-+	rev	$h1,$h1
-+#endif
-+	stp	$h0,$h1,[$mac]		// write result
-+
-+	ret
-+.size	poly1305_emit,.-poly1305_emit
-+___
-+my ($R0,$R1,$S1,$R2,$S2,$R3,$S3,$R4,$S4) = map("v$_.4s",(0..8));
-+my ($IN01_0,$IN01_1,$IN01_2,$IN01_3,$IN01_4) = map("v$_.2s",(9..13));
-+my ($IN23_0,$IN23_1,$IN23_2,$IN23_3,$IN23_4) = map("v$_.2s",(14..18));
-+my ($ACC0,$ACC1,$ACC2,$ACC3,$ACC4) = map("v$_.2d",(19..23));
-+my ($H0,$H1,$H2,$H3,$H4) = map("v$_.2s",(24..28));
-+my ($T0,$T1,$MASK) = map("v$_",(29..31));
-+
-+my ($in2,$zeros)=("x16","x17");
-+my $is_base2_26 = $zeros;		# borrow
-+
-+$code.=<<___;
-+.type	poly1305_mult,%function
-+.align	5
-+poly1305_mult:
-+	mul	$d0,$h0,$r0		// h0*r0
-+	umulh	$d1,$h0,$r0
-+
-+	mul	$t0,$h1,$s1		// h1*5*r1
-+	umulh	$t1,$h1,$s1
-+
-+	adds	$d0,$d0,$t0
-+	mul	$t0,$h0,$r1		// h0*r1
-+	adc	$d1,$d1,$t1
-+	umulh	$d2,$h0,$r1
-+
-+	adds	$d1,$d1,$t0
-+	mul	$t0,$h1,$r0		// h1*r0
-+	adc	$d2,$d2,xzr
-+	umulh	$t1,$h1,$r0
-+
-+	adds	$d1,$d1,$t0
-+	mul	$t0,$h2,$s1		// h2*5*r1
-+	adc	$d2,$d2,$t1
-+	mul	$t1,$h2,$r0		// h2*r0
-+
-+	adds	$d1,$d1,$t0
-+	adc	$d2,$d2,$t1
-+
-+	and	$t0,$d2,#-4		// final reduction
-+	and	$h2,$d2,#3
-+	add	$t0,$t0,$d2,lsr#2
-+	adds	$h0,$d0,$t0
-+	adcs	$h1,$d1,xzr
-+	adc	$h2,$h2,xzr
-+
-+	ret
-+.size	poly1305_mult,.-poly1305_mult
-+
-+.type	poly1305_splat,%function
-+.align	5
-+poly1305_splat:
-+	and	x12,$h0,#0x03ffffff	// base 2^64 -> base 2^26
-+	ubfx	x13,$h0,#26,#26
-+	extr	x14,$h1,$h0,#52
-+	and	x14,x14,#0x03ffffff
-+	ubfx	x15,$h1,#14,#26
-+	extr	x16,$h2,$h1,#40
-+
-+	str	w12,[$ctx,#16*0]	// r0
-+	add	w12,w13,w13,lsl#2	// r1*5
-+	str	w13,[$ctx,#16*1]	// r1
-+	add	w13,w14,w14,lsl#2	// r2*5
-+	str	w12,[$ctx,#16*2]	// s1
-+	str	w14,[$ctx,#16*3]	// r2
-+	add	w14,w15,w15,lsl#2	// r3*5
-+	str	w13,[$ctx,#16*4]	// s2
-+	str	w15,[$ctx,#16*5]	// r3
-+	add	w15,w16,w16,lsl#2	// r4*5
-+	str	w14,[$ctx,#16*6]	// s3
-+	str	w16,[$ctx,#16*7]	// r4
-+	str	w15,[$ctx,#16*8]	// s4
-+
-+	ret
-+.size	poly1305_splat,.-poly1305_splat
-+
-+.type	poly1305_blocks_neon,%function
-+.align	5
-+poly1305_blocks_neon:
-+	ldr	$is_base2_26,[$ctx,#24]
-+	cmp	$len,#128
-+	b.hs	.Lblocks_neon
-+	cbz	$is_base2_26,poly1305_blocks
-+
-+.Lblocks_neon:
-+	stp	x29,x30,[sp,#-80]!
-+	add	x29,sp,#0
-+
-+	ands	$len,$len,#-16
-+	b.eq	.Lno_data_neon
-+
-+	cbz	$is_base2_26,.Lbase2_64_neon
-+
-+	ldp	w10,w11,[$ctx]		// load hash value base 2^26
-+	ldp	w12,w13,[$ctx,#8]
-+	ldr	w14,[$ctx,#16]
-+
-+	tst	$len,#31
-+	b.eq	.Leven_neon
-+
-+	ldp	$r0,$r1,[$ctx,#32]	// load key value
-+
-+	add	$h0,x10,x11,lsl#26	// base 2^26 -> base 2^64
-+	lsr	$h1,x12,#12
-+	adds	$h0,$h0,x12,lsl#52
-+	add	$h1,$h1,x13,lsl#14
-+	adc	$h1,$h1,xzr
-+	lsr	$h2,x14,#24
-+	adds	$h1,$h1,x14,lsl#40
-+	adc	$d2,$h2,xzr		// can be partially reduced...
-+
-+	ldp	$d0,$d1,[$inp],#16	// load input
-+	sub	$len,$len,#16
-+	add	$s1,$r1,$r1,lsr#2	// s1 = r1 + (r1 >> 2)
-+
-+	and	$t0,$d2,#-4		// ... so reduce
-+	and	$h2,$d2,#3
-+	add	$t0,$t0,$d2,lsr#2
-+	adds	$h0,$h0,$t0
-+	adcs	$h1,$h1,xzr
-+	adc	$h2,$h2,xzr
-+
-+#ifdef	__ARMEB__
-+	rev	$d0,$d0
-+	rev	$d1,$d1
-+#endif
-+	adds	$h0,$h0,$d0		// accumulate input
-+	adcs	$h1,$h1,$d1
-+	adc	$h2,$h2,$padbit
-+
-+	bl	poly1305_mult
-+	ldr	x30,[sp,#8]
-+
-+	cbz	$padbit,.Lstore_base2_64_neon
-+
-+	and	x10,$h0,#0x03ffffff	// base 2^64 -> base 2^26
-+	ubfx	x11,$h0,#26,#26
-+	extr	x12,$h1,$h0,#52
-+	and	x12,x12,#0x03ffffff
-+	ubfx	x13,$h1,#14,#26
-+	extr	x14,$h2,$h1,#40
-+
-+	cbnz	$len,.Leven_neon
-+
-+	stp	w10,w11,[$ctx]		// store hash value base 2^26
-+	stp	w12,w13,[$ctx,#8]
-+	str	w14,[$ctx,#16]
-+	b	.Lno_data_neon
-+
-+.align	4
-+.Lstore_base2_64_neon:
-+	stp	$h0,$h1,[$ctx]		// store hash value base 2^64
-+	stp	$h2,xzr,[$ctx,#16]	// note that is_base2_26 is zeroed
-+	b	.Lno_data_neon
-+
-+.align	4
-+.Lbase2_64_neon:
-+	ldp	$r0,$r1,[$ctx,#32]	// load key value
-+
-+	ldp	$h0,$h1,[$ctx]		// load hash value base 2^64
-+	ldr	$h2,[$ctx,#16]
-+
-+	tst	$len,#31
-+	b.eq	.Linit_neon
-+
-+	ldp	$d0,$d1,[$inp],#16	// load input
-+	sub	$len,$len,#16
-+	add	$s1,$r1,$r1,lsr#2	// s1 = r1 + (r1 >> 2)
-+#ifdef	__ARMEB__
-+	rev	$d0,$d0
-+	rev	$d1,$d1
-+#endif
-+	adds	$h0,$h0,$d0		// accumulate input
-+	adcs	$h1,$h1,$d1
-+	adc	$h2,$h2,$padbit
-+
-+	bl	poly1305_mult
-+
-+.Linit_neon:
-+	and	x10,$h0,#0x03ffffff	// base 2^64 -> base 2^26
-+	ubfx	x11,$h0,#26,#26
-+	extr	x12,$h1,$h0,#52
-+	and	x12,x12,#0x03ffffff
-+	ubfx	x13,$h1,#14,#26
-+	extr	x14,$h2,$h1,#40
-+
-+	stp	d8,d9,[sp,#16]		// meet ABI requirements
-+	stp	d10,d11,[sp,#32]
-+	stp	d12,d13,[sp,#48]
-+	stp	d14,d15,[sp,#64]
-+
-+	fmov	${H0},x10
-+	fmov	${H1},x11
-+	fmov	${H2},x12
-+	fmov	${H3},x13
-+	fmov	${H4},x14
-+
-+	////////////////////////////////// initialize r^n table
-+	mov	$h0,$r0			// r^1
-+	add	$s1,$r1,$r1,lsr#2	// s1 = r1 + (r1 >> 2)
-+	mov	$h1,$r1
-+	mov	$h2,xzr
-+	add	$ctx,$ctx,#48+12
-+	bl	poly1305_splat
-+
-+	bl	poly1305_mult		// r^2
-+	sub	$ctx,$ctx,#4
-+	bl	poly1305_splat
-+
-+	bl	poly1305_mult		// r^3
-+	sub	$ctx,$ctx,#4
-+	bl	poly1305_splat
-+
-+	bl	poly1305_mult		// r^4
-+	sub	$ctx,$ctx,#4
-+	bl	poly1305_splat
-+	ldr	x30,[sp,#8]
-+
-+	add	$in2,$inp,#32
-+	adr	$zeros,.Lzeros
-+	subs	$len,$len,#64
-+	csel	$in2,$zeros,$in2,lo
-+
-+	mov	x4,#1
-+	str	x4,[$ctx,#-24]		// set is_base2_26
-+	sub	$ctx,$ctx,#48		// restore original $ctx
-+	b	.Ldo_neon
-+
-+.align	4
-+.Leven_neon:
-+	add	$in2,$inp,#32
-+	adr	$zeros,.Lzeros
-+	subs	$len,$len,#64
-+	csel	$in2,$zeros,$in2,lo
-+
-+	stp	d8,d9,[sp,#16]		// meet ABI requirements
-+	stp	d10,d11,[sp,#32]
-+	stp	d12,d13,[sp,#48]
-+	stp	d14,d15,[sp,#64]
-+
-+	fmov	${H0},x10
-+	fmov	${H1},x11
-+	fmov	${H2},x12
-+	fmov	${H3},x13
-+	fmov	${H4},x14
-+
-+.Ldo_neon:
-+	ldp	x8,x12,[$in2],#16	// inp[2:3] (or zero)
-+	ldp	x9,x13,[$in2],#48
-+
-+	lsl	$padbit,$padbit,#24
-+	add	x15,$ctx,#48
-+
-+#ifdef	__ARMEB__
-+	rev	x8,x8
-+	rev	x12,x12
-+	rev	x9,x9
-+	rev	x13,x13
-+#endif
-+	and	x4,x8,#0x03ffffff	// base 2^64 -> base 2^26
-+	and	x5,x9,#0x03ffffff
-+	ubfx	x6,x8,#26,#26
-+	ubfx	x7,x9,#26,#26
-+	add	x4,x4,x5,lsl#32		// bfi	x4,x5,#32,#32
-+	extr	x8,x12,x8,#52
-+	extr	x9,x13,x9,#52
-+	add	x6,x6,x7,lsl#32		// bfi	x6,x7,#32,#32
-+	fmov	$IN23_0,x4
-+	and	x8,x8,#0x03ffffff
-+	and	x9,x9,#0x03ffffff
-+	ubfx	x10,x12,#14,#26
-+	ubfx	x11,x13,#14,#26
-+	add	x12,$padbit,x12,lsr#40
-+	add	x13,$padbit,x13,lsr#40
-+	add	x8,x8,x9,lsl#32		// bfi	x8,x9,#32,#32
-+	fmov	$IN23_1,x6
-+	add	x10,x10,x11,lsl#32	// bfi	x10,x11,#32,#32
-+	add	x12,x12,x13,lsl#32	// bfi	x12,x13,#32,#32
-+	fmov	$IN23_2,x8
-+	fmov	$IN23_3,x10
-+	fmov	$IN23_4,x12
-+
-+	ldp	x8,x12,[$inp],#16	// inp[0:1]
-+	ldp	x9,x13,[$inp],#48
-+
-+	ld1	{$R0,$R1,$S1,$R2},[x15],#64
-+	ld1	{$S2,$R3,$S3,$R4},[x15],#64
-+	ld1	{$S4},[x15]
-+
-+#ifdef	__ARMEB__
-+	rev	x8,x8
-+	rev	x12,x12
-+	rev	x9,x9
-+	rev	x13,x13
-+#endif
-+	and	x4,x8,#0x03ffffff	// base 2^64 -> base 2^26
-+	and	x5,x9,#0x03ffffff
-+	ubfx	x6,x8,#26,#26
-+	ubfx	x7,x9,#26,#26
-+	add	x4,x4,x5,lsl#32		// bfi	x4,x5,#32,#32
-+	extr	x8,x12,x8,#52
-+	extr	x9,x13,x9,#52
-+	add	x6,x6,x7,lsl#32		// bfi	x6,x7,#32,#32
-+	fmov	$IN01_0,x4
-+	and	x8,x8,#0x03ffffff
-+	and	x9,x9,#0x03ffffff
-+	ubfx	x10,x12,#14,#26
-+	ubfx	x11,x13,#14,#26
-+	add	x12,$padbit,x12,lsr#40
-+	add	x13,$padbit,x13,lsr#40
-+	add	x8,x8,x9,lsl#32		// bfi	x8,x9,#32,#32
-+	fmov	$IN01_1,x6
-+	add	x10,x10,x11,lsl#32	// bfi	x10,x11,#32,#32
-+	add	x12,x12,x13,lsl#32	// bfi	x12,x13,#32,#32
-+	movi	$MASK.2d,#-1
-+	fmov	$IN01_2,x8
-+	fmov	$IN01_3,x10
-+	fmov	$IN01_4,x12
-+	ushr	$MASK.2d,$MASK.2d,#38
-+
-+	b.ls	.Lskip_loop
-+
-+.align	4
-+.Loop_neon:
-+	////////////////////////////////////////////////////////////////
-+	// ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
-+	// ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
-+	//   \___________________/
-+	// ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
-+	// ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
-+	//   \___________________/ \____________________/
-+	//
-+	// Note that we start with inp[2:3]*r^2. This is because it
-+	// doesn't depend on reduction in previous iteration.
-+	////////////////////////////////////////////////////////////////
-+	// d4 = h0*r4 + h1*r3   + h2*r2   + h3*r1   + h4*r0
-+	// d3 = h0*r3 + h1*r2   + h2*r1   + h3*r0   + h4*5*r4
-+	// d2 = h0*r2 + h1*r1   + h2*r0   + h3*5*r4 + h4*5*r3
-+	// d1 = h0*r1 + h1*r0   + h2*5*r4 + h3*5*r3 + h4*5*r2
-+	// d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
-+
-+	subs	$len,$len,#64
-+	umull	$ACC4,$IN23_0,${R4}[2]
-+	csel	$in2,$zeros,$in2,lo
-+	umull	$ACC3,$IN23_0,${R3}[2]
-+	umull	$ACC2,$IN23_0,${R2}[2]
-+	 ldp	x8,x12,[$in2],#16	// inp[2:3] (or zero)
-+	umull	$ACC1,$IN23_0,${R1}[2]
-+	 ldp	x9,x13,[$in2],#48
-+	umull	$ACC0,$IN23_0,${R0}[2]
-+#ifdef	__ARMEB__
-+	 rev	x8,x8
-+	 rev	x12,x12
-+	 rev	x9,x9
-+	 rev	x13,x13
-+#endif
-+
-+	umlal	$ACC4,$IN23_1,${R3}[2]
-+	 and	x4,x8,#0x03ffffff	// base 2^64 -> base 2^26
-+	umlal	$ACC3,$IN23_1,${R2}[2]
-+	 and	x5,x9,#0x03ffffff
-+	umlal	$ACC2,$IN23_1,${R1}[2]
-+	 ubfx	x6,x8,#26,#26
-+	umlal	$ACC1,$IN23_1,${R0}[2]
-+	 ubfx	x7,x9,#26,#26
-+	umlal	$ACC0,$IN23_1,${S4}[2]
-+	 add	x4,x4,x5,lsl#32		// bfi	x4,x5,#32,#32
-+
-+	umlal	$ACC4,$IN23_2,${R2}[2]
-+	 extr	x8,x12,x8,#52
-+	umlal	$ACC3,$IN23_2,${R1}[2]
-+	 extr	x9,x13,x9,#52
-+	umlal	$ACC2,$IN23_2,${R0}[2]
-+	 add	x6,x6,x7,lsl#32		// bfi	x6,x7,#32,#32
-+	umlal	$ACC1,$IN23_2,${S4}[2]
-+	 fmov	$IN23_0,x4
-+	umlal	$ACC0,$IN23_2,${S3}[2]
-+	 and	x8,x8,#0x03ffffff
-+
-+	umlal	$ACC4,$IN23_3,${R1}[2]
-+	 and	x9,x9,#0x03ffffff
-+	umlal	$ACC3,$IN23_3,${R0}[2]
-+	 ubfx	x10,x12,#14,#26
-+	umlal	$ACC2,$IN23_3,${S4}[2]
-+	 ubfx	x11,x13,#14,#26
-+	umlal	$ACC1,$IN23_3,${S3}[2]
-+	 add	x8,x8,x9,lsl#32		// bfi	x8,x9,#32,#32
-+	umlal	$ACC0,$IN23_3,${S2}[2]
-+	 fmov	$IN23_1,x6
-+
-+	add	$IN01_2,$IN01_2,$H2
-+	 add	x12,$padbit,x12,lsr#40
-+	umlal	$ACC4,$IN23_4,${R0}[2]
-+	 add	x13,$padbit,x13,lsr#40
-+	umlal	$ACC3,$IN23_4,${S4}[2]
-+	 add	x10,x10,x11,lsl#32	// bfi	x10,x11,#32,#32
-+	umlal	$ACC2,$IN23_4,${S3}[2]
-+	 add	x12,x12,x13,lsl#32	// bfi	x12,x13,#32,#32
-+	umlal	$ACC1,$IN23_4,${S2}[2]
-+	 fmov	$IN23_2,x8
-+	umlal	$ACC0,$IN23_4,${S1}[2]
-+	 fmov	$IN23_3,x10
-+
-+	////////////////////////////////////////////////////////////////
-+	// (hash+inp[0:1])*r^4 and accumulate
-+
-+	add	$IN01_0,$IN01_0,$H0
-+	 fmov	$IN23_4,x12
-+	umlal	$ACC3,$IN01_2,${R1}[0]
-+	 ldp	x8,x12,[$inp],#16	// inp[0:1]
-+	umlal	$ACC0,$IN01_2,${S3}[0]
-+	 ldp	x9,x13,[$inp],#48
-+	umlal	$ACC4,$IN01_2,${R2}[0]
-+	umlal	$ACC1,$IN01_2,${S4}[0]
-+	umlal	$ACC2,$IN01_2,${R0}[0]
-+#ifdef	__ARMEB__
-+	 rev	x8,x8
-+	 rev	x12,x12
-+	 rev	x9,x9
-+	 rev	x13,x13
-+#endif
-+
-+	add	$IN01_1,$IN01_1,$H1
-+	umlal	$ACC3,$IN01_0,${R3}[0]
-+	umlal	$ACC4,$IN01_0,${R4}[0]
-+	 and	x4,x8,#0x03ffffff	// base 2^64 -> base 2^26
-+	umlal	$ACC2,$IN01_0,${R2}[0]
-+	 and	x5,x9,#0x03ffffff
-+	umlal	$ACC0,$IN01_0,${R0}[0]
-+	 ubfx	x6,x8,#26,#26
-+	umlal	$ACC1,$IN01_0,${R1}[0]
-+	 ubfx	x7,x9,#26,#26
-+
-+	add	$IN01_3,$IN01_3,$H3
-+	 add	x4,x4,x5,lsl#32		// bfi	x4,x5,#32,#32
-+	umlal	$ACC3,$IN01_1,${R2}[0]
-+	 extr	x8,x12,x8,#52
-+	umlal	$ACC4,$IN01_1,${R3}[0]
-+	 extr	x9,x13,x9,#52
-+	umlal	$ACC0,$IN01_1,${S4}[0]
-+	 add	x6,x6,x7,lsl#32		// bfi	x6,x7,#32,#32
-+	umlal	$ACC2,$IN01_1,${R1}[0]
-+	 fmov	$IN01_0,x4
-+	umlal	$ACC1,$IN01_1,${R0}[0]
-+	 and	x8,x8,#0x03ffffff
-+
-+	add	$IN01_4,$IN01_4,$H4
-+	 and	x9,x9,#0x03ffffff
-+	umlal	$ACC3,$IN01_3,${R0}[0]
-+	 ubfx	x10,x12,#14,#26
-+	umlal	$ACC0,$IN01_3,${S2}[0]
-+	 ubfx	x11,x13,#14,#26
-+	umlal	$ACC4,$IN01_3,${R1}[0]
-+	 add	x8,x8,x9,lsl#32		// bfi	x8,x9,#32,#32
-+	umlal	$ACC1,$IN01_3,${S3}[0]
-+	 fmov	$IN01_1,x6
-+	umlal	$ACC2,$IN01_3,${S4}[0]
-+	 add	x12,$padbit,x12,lsr#40
-+
-+	umlal	$ACC3,$IN01_4,${S4}[0]
-+	 add	x13,$padbit,x13,lsr#40
-+	umlal	$ACC0,$IN01_4,${S1}[0]
-+	 add	x10,x10,x11,lsl#32	// bfi	x10,x11,#32,#32
-+	umlal	$ACC4,$IN01_4,${R0}[0]
-+	 add	x12,x12,x13,lsl#32	// bfi	x12,x13,#32,#32
-+	umlal	$ACC1,$IN01_4,${S2}[0]
-+	 fmov	$IN01_2,x8
-+	umlal	$ACC2,$IN01_4,${S3}[0]
-+	 fmov	$IN01_3,x10
-+	 fmov	$IN01_4,x12
-+
-+	/////////////////////////////////////////////////////////////////
-+	// lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
-+	// and P. Schwabe
-+	//
-+	// [see discussion in poly1305-armv4 module]
-+
-+	ushr	$T0.2d,$ACC3,#26
-+	xtn	$H3,$ACC3
-+	 ushr	$T1.2d,$ACC0,#26
-+	 and	$ACC0,$ACC0,$MASK.2d
-+	add	$ACC4,$ACC4,$T0.2d	// h3 -> h4
-+	bic	$H3,#0xfc,lsl#24	// &=0x03ffffff
-+	 add	$ACC1,$ACC1,$T1.2d	// h0 -> h1
-+
-+	ushr	$T0.2d,$ACC4,#26
-+	xtn	$H4,$ACC4
-+	 ushr	$T1.2d,$ACC1,#26
-+	 xtn	$H1,$ACC1
-+	bic	$H4,#0xfc,lsl#24
-+	 add	$ACC2,$ACC2,$T1.2d	// h1 -> h2
-+
-+	add	$ACC0,$ACC0,$T0.2d
-+	shl	$T0.2d,$T0.2d,#2
-+	 shrn	$T1.2s,$ACC2,#26
-+	 xtn	$H2,$ACC2
-+	add	$ACC0,$ACC0,$T0.2d	// h4 -> h0
-+	 bic	$H1,#0xfc,lsl#24
-+	 add	$H3,$H3,$T1.2s		// h2 -> h3
-+	 bic	$H2,#0xfc,lsl#24
-+
-+	shrn	$T0.2s,$ACC0,#26
-+	xtn	$H0,$ACC0
-+	 ushr	$T1.2s,$H3,#26
-+	 bic	$H3,#0xfc,lsl#24
-+	 bic	$H0,#0xfc,lsl#24
-+	add	$H1,$H1,$T0.2s		// h0 -> h1
-+	 add	$H4,$H4,$T1.2s		// h3 -> h4
-+
-+	b.hi	.Loop_neon
-+
-+.Lskip_loop:
-+	dup	$IN23_2,${IN23_2}[0]
-+	add	$IN01_2,$IN01_2,$H2
-+
-+	////////////////////////////////////////////////////////////////
-+	// multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
-+
-+	adds	$len,$len,#32
-+	b.ne	.Long_tail
-+
-+	dup	$IN23_2,${IN01_2}[0]
-+	add	$IN23_0,$IN01_0,$H0
-+	add	$IN23_3,$IN01_3,$H3
-+	add	$IN23_1,$IN01_1,$H1
-+	add	$IN23_4,$IN01_4,$H4
-+
-+.Long_tail:
-+	dup	$IN23_0,${IN23_0}[0]
-+	umull2	$ACC0,$IN23_2,${S3}
-+	umull2	$ACC3,$IN23_2,${R1}
-+	umull2	$ACC4,$IN23_2,${R2}
-+	umull2	$ACC2,$IN23_2,${R0}
-+	umull2	$ACC1,$IN23_2,${S4}
-+
-+	dup	$IN23_1,${IN23_1}[0]
-+	umlal2	$ACC0,$IN23_0,${R0}
-+	umlal2	$ACC2,$IN23_0,${R2}
-+	umlal2	$ACC3,$IN23_0,${R3}
-+	umlal2	$ACC4,$IN23_0,${R4}
-+	umlal2	$ACC1,$IN23_0,${R1}
-+
-+	dup	$IN23_3,${IN23_3}[0]
-+	umlal2	$ACC0,$IN23_1,${S4}
-+	umlal2	$ACC3,$IN23_1,${R2}
-+	umlal2	$ACC2,$IN23_1,${R1}
-+	umlal2	$ACC4,$IN23_1,${R3}
-+	umlal2	$ACC1,$IN23_1,${R0}
-+
-+	dup	$IN23_4,${IN23_4}[0]
-+	umlal2	$ACC3,$IN23_3,${R0}
-+	umlal2	$ACC4,$IN23_3,${R1}
-+	umlal2	$ACC0,$IN23_3,${S2}
-+	umlal2	$ACC1,$IN23_3,${S3}
-+	umlal2	$ACC2,$IN23_3,${S4}
-+
-+	umlal2	$ACC3,$IN23_4,${S4}
-+	umlal2	$ACC0,$IN23_4,${S1}
-+	umlal2	$ACC4,$IN23_4,${R0}
-+	umlal2	$ACC1,$IN23_4,${S2}
-+	umlal2	$ACC2,$IN23_4,${S3}
-+
-+	b.eq	.Lshort_tail
-+
-+	////////////////////////////////////////////////////////////////
-+	// (hash+inp[0:1])*r^4:r^3 and accumulate
-+
-+	add	$IN01_0,$IN01_0,$H0
-+	umlal	$ACC3,$IN01_2,${R1}
-+	umlal	$ACC0,$IN01_2,${S3}
-+	umlal	$ACC4,$IN01_2,${R2}
-+	umlal	$ACC1,$IN01_2,${S4}
-+	umlal	$ACC2,$IN01_2,${R0}
-+
-+	add	$IN01_1,$IN01_1,$H1
-+	umlal	$ACC3,$IN01_0,${R3}
-+	umlal	$ACC0,$IN01_0,${R0}
-+	umlal	$ACC4,$IN01_0,${R4}
-+	umlal	$ACC1,$IN01_0,${R1}
-+	umlal	$ACC2,$IN01_0,${R2}
-+
-+	add	$IN01_3,$IN01_3,$H3
-+	umlal	$ACC3,$IN01_1,${R2}
-+	umlal	$ACC0,$IN01_1,${S4}
-+	umlal	$ACC4,$IN01_1,${R3}
-+	umlal	$ACC1,$IN01_1,${R0}
-+	umlal	$ACC2,$IN01_1,${R1}
-+
-+	add	$IN01_4,$IN01_4,$H4
-+	umlal	$ACC3,$IN01_3,${R0}
-+	umlal	$ACC0,$IN01_3,${S2}
-+	umlal	$ACC4,$IN01_3,${R1}
-+	umlal	$ACC1,$IN01_3,${S3}
-+	umlal	$ACC2,$IN01_3,${S4}
-+
-+	umlal	$ACC3,$IN01_4,${S4}
-+	umlal	$ACC0,$IN01_4,${S1}
-+	umlal	$ACC4,$IN01_4,${R0}
-+	umlal	$ACC1,$IN01_4,${S2}
-+	umlal	$ACC2,$IN01_4,${S3}
-+
-+.Lshort_tail:
-+	////////////////////////////////////////////////////////////////
-+	// horizontal add
-+
-+	addp	$ACC3,$ACC3,$ACC3
-+	 ldp	d8,d9,[sp,#16]		// meet ABI requirements
-+	addp	$ACC0,$ACC0,$ACC0
-+	 ldp	d10,d11,[sp,#32]
-+	addp	$ACC4,$ACC4,$ACC4
-+	 ldp	d12,d13,[sp,#48]
-+	addp	$ACC1,$ACC1,$ACC1
-+	 ldp	d14,d15,[sp,#64]
-+	addp	$ACC2,$ACC2,$ACC2
-+
-+	////////////////////////////////////////////////////////////////
-+	// lazy reduction, but without narrowing
-+
-+	ushr	$T0.2d,$ACC3,#26
-+	and	$ACC3,$ACC3,$MASK.2d
-+	 ushr	$T1.2d,$ACC0,#26
-+	 and	$ACC0,$ACC0,$MASK.2d
-+
-+	add	$ACC4,$ACC4,$T0.2d	// h3 -> h4
-+	 add	$ACC1,$ACC1,$T1.2d	// h0 -> h1
-+
-+	ushr	$T0.2d,$ACC4,#26
-+	and	$ACC4,$ACC4,$MASK.2d
-+	 ushr	$T1.2d,$ACC1,#26
-+	 and	$ACC1,$ACC1,$MASK.2d
-+	 add	$ACC2,$ACC2,$T1.2d	// h1 -> h2
-+
-+	add	$ACC0,$ACC0,$T0.2d
-+	shl	$T0.2d,$T0.2d,#2
-+	 ushr	$T1.2d,$ACC2,#26
-+	 and	$ACC2,$ACC2,$MASK.2d
-+	add	$ACC0,$ACC0,$T0.2d	// h4 -> h0
-+	 add	$ACC3,$ACC3,$T1.2d	// h2 -> h3
-+
-+	ushr	$T0.2d,$ACC0,#26
-+	and	$ACC0,$ACC0,$MASK.2d
-+	 ushr	$T1.2d,$ACC3,#26
-+	 and	$ACC3,$ACC3,$MASK.2d
-+	add	$ACC1,$ACC1,$T0.2d	// h0 -> h1
-+	 add	$ACC4,$ACC4,$T1.2d	// h3 -> h4
-+
-+	////////////////////////////////////////////////////////////////
-+	// write the result, can be partially reduced
-+
-+	st4	{$ACC0,$ACC1,$ACC2,$ACC3}[0],[$ctx],#16
-+	st1	{$ACC4}[0],[$ctx]
-+
-+.Lno_data_neon:
-+	ldr	x29,[sp],#80
-+	ret
-+.size	poly1305_blocks_neon,.-poly1305_blocks_neon
-+
-+.type	poly1305_emit_neon,%function
-+.align	5
-+poly1305_emit_neon:
-+	ldr	$is_base2_26,[$ctx,#24]
-+	cbz	$is_base2_26,poly1305_emit
-+
-+	ldp	w10,w11,[$ctx]		// load hash value base 2^26
-+	ldp	w12,w13,[$ctx,#8]
-+	ldr	w14,[$ctx,#16]
-+
-+	add	$h0,x10,x11,lsl#26	// base 2^26 -> base 2^64
-+	lsr	$h1,x12,#12
-+	adds	$h0,$h0,x12,lsl#52
-+	add	$h1,$h1,x13,lsl#14
-+	adc	$h1,$h1,xzr
-+	lsr	$h2,x14,#24
-+	adds	$h1,$h1,x14,lsl#40
-+	adc	$h2,$h2,xzr		// can be partially reduced...
-+
-+	ldp	$t0,$t1,[$nonce]	// load nonce
-+
-+	and	$d0,$h2,#-4		// ... so reduce
-+	add	$d0,$d0,$h2,lsr#2
-+	and	$h2,$h2,#3
-+	adds	$h0,$h0,$d0
-+	adcs	$h1,$h1,xzr
-+	adc	$h2,$h2,xzr
-+
-+	adds	$d0,$h0,#5		// compare to modulus
-+	adcs	$d1,$h1,xzr
-+	adc	$d2,$h2,xzr
-+
-+	tst	$d2,#-4			// see if it's carried/borrowed
-+
-+	csel	$h0,$h0,$d0,eq
-+	csel	$h1,$h1,$d1,eq
-+
-+#ifdef	__ARMEB__
-+	ror	$t0,$t0,#32		// flip nonce words
-+	ror	$t1,$t1,#32
-+#endif
-+	adds	$h0,$h0,$t0		// accumulate nonce
-+	adc	$h1,$h1,$t1
-+#ifdef	__ARMEB__
-+	rev	$h0,$h0			// flip output bytes
-+	rev	$h1,$h1
-+#endif
-+	stp	$h0,$h1,[$mac]		// write result
-+
-+	ret
-+.size	poly1305_emit_neon,.-poly1305_emit_neon
-+
-+.align	5
-+.Lzeros:
-+.long	0,0,0,0,0,0,0,0
-+.LOPENSSL_armcap_P:
-+#ifdef	__ILP32__
-+.long	OPENSSL_armcap_P-.
-+#else
-+.quad	OPENSSL_armcap_P-.
-+#endif
-+.asciz	"Poly1305 for ARMv8, CRYPTOGAMS by "
-+.align	2
-+___
-+
-+foreach (split("\n",$code)) {
-+	s/\b(shrn\s+v[0-9]+)\.[24]d/$1.2s/			or
-+	s/\b(fmov\s+)v([0-9]+)[^,]*,\s*x([0-9]+)/$1d$2,x$3/	or
-+	(m/\bdup\b/ and (s/\.[24]s/.2d/g or 1))			or
-+	(m/\b(eor|and)/ and (s/\.[248][sdh]/.16b/g or 1))	or
-+	(m/\bum(ul|la)l\b/ and (s/\.4s/.2s/g or 1))		or
-+	(m/\bum(ul|la)l2\b/ and (s/\.2s/.4s/g or 1))		or
-+	(m/\bst[1-4]\s+{[^}]+}\[/ and (s/\.[24]d/.s/g or 1));
-+
-+	s/\.[124]([sd])\[/.$1\[/;
-+
-+	print $_,"\n";
-+}
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-c64xplus.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-c64xplus.pl
-new file mode 100755
-index 0000000..93fef37
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-c64xplus.pl
-@@ -0,0 +1,331 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# Poly1305 hash for C64x+.
-+#
-+# October 2015
-+#
-+# Performance is [incredible for a 32-bit processor] 1.82 cycles per
-+# processed byte. Comparison to compiler-generated code is problematic,
-+# because results were observed to vary from 2.1 to 7.6 cpb depending
-+# on compiler's ability to inline small functions. Compiler also
-+# disables interrupts for some reason, thus making interrupt response
-+# time dependent on input length. This module on the other hand is free
-+# from such limitation.
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+($CTXA,$INPB,$LEN,$PADBIT)=("A4","B4","A6","B6");
-+($H0,$H1,$H2,$H3,$H4,$H4a)=("A8","B8","A10","B10","B2",$LEN);
-+($D0,$D1,$D2,$D3)=         ("A9","B9","A11","B11");
-+($R0,$R1,$R2,$R3,$S1,$S2,$S3,$S3b)=("A0","B0","A1","B1","A12","B12","A13","B13");
-+($THREE,$R0b,$S2a)=("B7","B5","A5");
-+
-+$code.=<<___;
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.asg	poly1305_init,_poly1305_init
-+	.asg	poly1305_blocks,_poly1305_blocks
-+	.asg	poly1305_emit,_poly1305_emit
-+	.endif
-+
-+	.asg	B3,RA
-+	.asg	A15,FP
-+	.asg	B15,SP
-+
-+	.if	.LITTLE_ENDIAN
-+	.asg	MV,SWAP2
-+	.asg	MV.L,SWAP4
-+	.endif
-+
-+	.global	_poly1305_init
-+_poly1305_init:
-+	.asmfunc
-+	LDNDW	*${INPB}[0],B17:B16	; load key material
-+	LDNDW	*${INPB}[1],A17:A16
-+
-+||	ZERO	B9:B8
-+||	MVK	-1,B0
-+	STDW	B9:B8,*${CTXA}[0]	; initialize h1:h0
-+||	SHRU	B0,4,B0			; 0x0fffffff
-+||	MVK	-4,B1
-+	STDW	B9:B8,*${CTXA}[1]	; initialize h3:h2
-+||	AND	B0,B1,B1		; 0x0ffffffc
-+	STW	B8,*${CTXA}[4]		; initialize h4
-+
-+	.if	.BIG_ENDIAN
-+	SWAP2	B16,B17
-+||	SWAP2	B17,B16
-+	SWAP2	A16,A17
-+||	SWAP2	A17,A16
-+	SWAP4	B16,B16
-+||	SWAP4	A16,A16
-+	SWAP4	B17,B17
-+||	SWAP4	A17,A17
-+	.endif
-+
-+	AND	B16,B0,B20		; r0 = key[0] & 0x0fffffff
-+||	AND	B17,B1,B22		; r1 = key[1] & 0x0ffffffc
-+||	EXTU	B17,4,6,B16		; r1>>2
-+	AND	A16,B1,B21		; r2 = key[2] & 0x0ffffffc
-+||	AND	A17,B1,A23		; r3 = key[3] & 0x0ffffffc
-+||	BNOP	RA
-+	SHRU	B21,2,B18
-+||	ADD	B22,B16,B16		; s1 = r1 + r1>>2
-+
-+	STDW	B21:B20,*${CTXA}[3]	; save r2:r0
-+||	ADD	B21,B18,B18		; s2 = r2 + r2>>2
-+||	SHRU	A23,2,B17
-+||	MV	A23,B23
-+	STDW	B23:B22,*${CTXA}[4]	; save r3:r1
-+||	ADD	B23,B17,B19		; s3 = r3 + r3>>2
-+||	ADD	B23,B17,B17		; s3 = r3 + r3>>2
-+	STDW	B17:B16,*${CTXA}[5]	; save s3:s1
-+	STDW	B19:B18,*${CTXA}[6]	; save s3:s2
-+||	ZERO	A4			; return 0
-+	.endasmfunc
-+
-+	.global	_poly1305_blocks
-+	.align	32
-+_poly1305_blocks:
-+	.asmfunc	stack_usage(40)
-+	SHRU	$LEN,4,A2		; A2 is loop counter, number of blocks
-+  [!A2]	BNOP	RA			; no data
-+|| [A2]	STW	FP,*SP--(40)		; save frame pointer and alloca(40)
-+|| [A2]	MV	SP,FP
-+   [A2]	STDW	B13:B12,*SP[4]		; ABI says so
-+|| [A2]	MV	$CTXA,$S3b		; borrow $S3b
-+   [A2]	STDW	B11:B10,*SP[3]
-+|| [A2]	STDW	A13:A12,*FP[-3]
-+   [A2]	STDW	A11:A10,*FP[-4]
-+
-+|| [A2]	LDDW	*${S3b}[0],B25:B24	; load h1:h0
-+   [A2]	LDNW	*${INPB}++[4],$D0	; load inp[0]
-+   [A2]	LDNW	*${INPB}[-3],$D1	; load inp[1]
-+
-+	LDDW	*${CTXA}[1],B29:B28	; load h3:h2, B28 is h2
-+	LDNW	*${INPB}[-2],$D2	; load inp[2]
-+	LDNW	*${INPB}[-1],$D3	; load inp[3]
-+
-+	LDDW	*${CTXA}[3],$R2:$R0	; load r2:r0
-+||	LDDW	*${S3b}[4],$R3:$R1	; load r3:r1
-+||	SWAP2	$D0,$D0
-+
-+	LDDW	*${CTXA}[5],$S3:$S1	; load s3:s1
-+||	LDDW	*${S3b}[6],$S3b:$S2	; load s3:s2
-+||	SWAP4	$D0,$D0
-+||	SWAP2	$D1,$D1
-+
-+	ADDU	$D0,B24,$D0:$H0		; h0+=inp[0]
-+||	ADD	$D0,B24,B27		; B-copy of h0+inp[0]
-+||	SWAP4	$D1,$D1
-+	ADDU	$D1,B25,$D1:$H1		; h1+=inp[1]
-+||	MVK	3,$THREE
-+||	SWAP2	$D2,$D2
-+	LDW	*${CTXA}[4],$H4		; load h4
-+||	SWAP4	$D2,$D2
-+||	MV	B29,B30			; B30 is h3
-+	MV	$R0,$R0b
-+
-+loop?:
-+	MPY32U	$H0,$R0,A17:A16
-+||	MPY32U	B27,$R1,B17:B16		; MPY32U	$H0,$R1,B17:B16
-+||	ADDU	$D0,$D1:$H1,B25:B24	; ADDU		$D0,$D1:$H1,$D1:$H1
-+||	ADDU	$D2,B28,$D2:$H2		; h2+=inp[2]
-+||	SWAP2	$D3,$D3
-+	MPY32U	$H0,$R2,A19:A18
-+||	MPY32U	B27,$R3,B19:B18		; MPY32U	$H0,$R3,B19:B18
-+||	ADD	$D0,$H1,A24		; A-copy of B24
-+||	SWAP4	$D3,$D3
-+|| [A2]	SUB	A2,1,A2			; decrement loop counter
-+
-+	MPY32U	A24,$S3,A21:A20		; MPY32U	$H1,$S3,A21:A20
-+||	MPY32U	B24,$R0b,B21:B20	; MPY32U	$H1,$R0,B21:B20
-+||	ADDU	B25,$D2:$H2,$D2:$H2	; ADDU		$D1,$D2:$H2,$D2:$H2
-+||	ADDU	$D3,B30,$D3:$H3		; h3+=inp[3]
-+||	ADD	B25,$H2,B25		; B-copy of $H2
-+	MPY32U	A24,$R1,A23:A22		; MPY32U	$H1,$R1,A23:A22
-+||	MPY32U	B24,$R2,B23:B22		; MPY32U	$H1,$R2,B23:B22
-+
-+	MPY32U	$H2,$S2,A25:A24
-+||	MPY32U	B25,$S3b,B25:B24	; MPY32U	$H2,$S3,B25:B24
-+||	ADDU	$D2,$D3:$H3,$D3:$H3
-+||	ADD	$PADBIT,$H4,$H4		; h4+=padbit
-+	MPY32U	$H2,$R0,A27:A26
-+||	MPY32U	$H2,$R1,B27:B26
-+||	ADD	$D3,$H4,$H4
-+||	MV	$S2,$S2a
-+
-+	MPY32U	$H3,$S1,A29:A28
-+||	MPY32U	$H3,$S2,B29:B28
-+||	ADD	A21,A17,A21		; start accumulating "d3:d0"
-+||	ADD	B21,B17,B21
-+||	ADDU	A20,A16,A17:A16
-+||	ADDU	B20,B16,B17:B16
-+|| [A2]	LDNW	*${INPB}++[4],$D0	; load inp[0]
-+	MPY32U	$H3,$S3,A31:A30
-+||	MPY32U	$H3,$R0b,B31:B30
-+||	ADD	A23,A19,A23
-+||	ADD	B23,B19,B23
-+||	ADDU	A22,A18,A19:A18
-+||	ADDU	B22,B18,B19:B18
-+|| [A2]	LDNW	*${INPB}[-3],$D1	; load inp[1]
-+
-+	MPY32	$H4,$S1,B20
-+||	MPY32	$H4,$S2a,A20
-+||	ADD	A25,A21,A21
-+||	ADD	B25,B21,B21
-+||	ADDU	A24,A17:A16,A17:A16
-+||	ADDU	B24,B17:B16,B17:B16
-+|| [A2]	LDNW	*${INPB}[-2],$D2	; load inp[2]
-+	MPY32	$H4,$S3b,B22
-+||	ADD	A27,A23,A23
-+||	ADD	B27,B23,B23
-+||	ADDU	A26,A19:A18,A19:A18
-+||	ADDU	B26,B19:B18,B19:B18
-+|| [A2]	LDNW	*${INPB}[-1],$D3	; load inp[3]
-+
-+	MPY32	$H4,$R0b,$H4
-+||	ADD	A29,A21,A21		; final hi("d0")
-+||	ADD	B29,B21,B21		; final hi("d1")
-+||	ADDU	A28,A17:A16,A17:A16	; final lo("d0")
-+||	ADDU	B28,B17:B16,B17:B16
-+	ADD	A31,A23,A23		; final hi("d2")
-+||	ADD	B31,B23,B23		; final hi("d3")
-+||	ADDU	A30,A19:A18,A19:A18
-+||	ADDU	B30,B19:B18,B19:B18
-+	ADDU	B20,B17:B16,B17:B16	; final lo("d1")
-+||	ADDU	A20,A19:A18,A19:A18	; final lo("d2")
-+	ADDU	B22,B19:B18,B19:B18	; final lo("d3")
-+
-+||	ADD	A17,A21,A21		; "flatten" "d3:d0"
-+	MV	A19,B29			; move to avoid cross-path stalls
-+	ADDU	A21,B17:B16,B27:B26	; B26 is h1
-+	ADD	B21,B27,B27
-+||	DMV	B29,A18,B29:B28		; move to avoid cross-path stalls
-+	ADDU	B27,B29:B28,B29:B28	; B28 is h2
-+|| [A2]	SWAP2	$D0,$D0
-+	ADD	A23,B29,B29
-+|| [A2]	SWAP4	$D0,$D0
-+	ADDU	B29,B19:B18,B31:B30	; B30 is h3
-+	ADD	B23,B31,B31
-+||	MV	A16,B24			; B24 is h0
-+|| [A2]	SWAP2	$D1,$D1
-+	ADD	B31,$H4,$H4
-+|| [A2]	SWAP4	$D1,$D1
-+
-+	SHRU	$H4,2,B16		; last reduction step
-+||	AND	$H4,$THREE,$H4
-+	ADDAW	B16,B16,B16		; 5*(h4>>2)
-+|| [A2]	BNOP	loop?
-+
-+	ADDU	B24,B16,B25:B24		; B24 is h0
-+|| [A2]	SWAP2	$D2,$D2
-+	ADDU	B26,B25,B27:B26		; B26 is h1
-+|| [A2]	SWAP4	$D2,$D2
-+	ADDU	B28,B27,B29:B28		; B28 is h2
-+|| [A2]	ADDU	$D0,B24,$D0:$H0		; h0+=inp[0]
-+|| [A2]	ADD	$D0,B24,B27		; B-copy of h0+inp[0]
-+	ADDU	B30,B29,B31:B30		; B30 is h3
-+	ADD	B31,$H4,$H4
-+|| [A2]	ADDU	$D1,B26,$D1:$H1		; h1+=inp[1]
-+;;===== branch to loop? is taken here
-+
-+	LDDW	*FP[-4],A11:A10		; ABI says so
-+	LDDW	*FP[-3],A13:A12
-+||	LDDW	*SP[3],B11:B10
-+	LDDW	*SP[4],B13:B12
-+||	MV	B26,B25
-+||	BNOP	RA
-+	LDW	*++SP(40),FP		; restore frame pointer
-+||	MV	B30,B29
-+	STDW	B25:B24,*${CTXA}[0]	; save h1:h0
-+	STDW	B29:B28,*${CTXA}[1]	; save h3:h2
-+	STW	$H4,*${CTXA}[4]		; save h4
-+	NOP	1
-+	.endasmfunc
-+___
-+{
-+my ($MAC,$NONCEA,$NONCEB)=($INPB,$LEN,$PADBIT);
-+
-+$code.=<<___;
-+	.global	_poly1305_emit
-+	.align	32
-+_poly1305_emit:
-+	.asmfunc
-+	LDDW	*${CTXA}[0],A17:A16	; load h1:h0
-+	LDDW	*${CTXA}[1],A19:A18	; load h3:h2
-+	LDW	*${CTXA}[4],A20		; load h4
-+	MV	$NONCEA,$NONCEB
-+
-+	MVK	5,A22			; compare to modulus
-+	ADDU	A16,A22,A23:A22
-+||	LDW	*${NONCEA}[0],A8
-+||	LDW	*${NONCEB}[1],B8
-+	ADDU	A17,A23,A25:A24
-+||	LDW	*${NONCEA}[2],A9
-+||	LDW	*${NONCEB}[3],B9
-+	ADDU	A19,A25,A27:A26
-+	ADDU	A19,A27,A29:A28
-+	ADD	A20,A29,A29
-+
-+	SHRU	A29,2,A2		; check for overflow in 130-th bit
-+
-+   [A2]	MV	A22,A16			; select
-+|| [A2]	MV	A24,A17
-+   [A2]	MV	A26,A18
-+|| [A2]	MV	A28,A19
-+
-+||	ADDU	A8,A16,A23:A22		; accumulate nonce
-+	ADDU	B8,A17,A25:A24
-+||	SWAP2	A22,A22
-+	ADDU	A23,A25:A24,A25:A24
-+	ADDU	A9,A18,A27:A26
-+||	SWAP2	A24,A24
-+	ADDU	A25,A27:A26,A27:A26
-+||	ADD	B9,A19,A28
-+	ADD	A27,A28,A28
-+||	SWAP2	A26,A26
-+
-+	.if	.BIG_ENDIAN
-+	SWAP2	A28,A28
-+||	SWAP4	A22,A22
-+||	SWAP4	A24,B24
-+	SWAP4	A26,A26
-+	SWAP4	A28,A28
-+||	MV	B24,A24
-+	.endif
-+
-+	BNOP	RA,1
-+	STNW	A22,*${MAC}[0]		; write the result
-+	STNW	A24,*${MAC}[1]
-+	STNW	A26,*${MAC}[2]
-+	STNW	A28,*${MAC}[3]
-+	.endasmfunc
-+___
-+}
-+$code.=<<___;
-+	.sect	.const
-+	.cstring "Poly1305 for C64x+, CRYPTOGAMS by "
-+	.align	4
-+___
-+
-+print $code;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-mips.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-mips.pl
-new file mode 100755
-index 0000000..d2b3e90
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-mips.pl
-@@ -0,0 +1,425 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# Poly1305 hash for MIPS64.
-+#
-+# May 2016
-+#
-+# Numbers are cycles per processed byte with poly1305_blocks alone.
-+#
-+#		IALU/gcc
-+# R1x000	5.64/+120%	(big-endian)
-+# Octeon II	3.80/+280%	(little-endian)
-+
-+######################################################################
-+# There is a number of MIPS ABI in use, O32 and N32/64 are most
-+# widely used. Then there is a new contender: NUBI. It appears that if
-+# one picks the latter, it's possible to arrange code in ABI neutral
-+# manner. Therefore let's stick to NUBI register layout:
-+#
-+($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
-+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
-+($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
-+#
-+# The return value is placed in $a0. Following coding rules facilitate
-+# interoperability:
-+#
-+# - never ever touch $tp, "thread pointer", former $gp [o32 can be
-+#   excluded from the rule, because it's specified volatile];
-+# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
-+#   old code];
-+# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
-+#
-+# For reference here is register layout for N32/64 MIPS ABIs:
-+#
-+# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
-+# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
-+# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
-+# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
-+#
-+# 
-+#
-+######################################################################
-+
-+$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64
-+
-+die "MIPS64 only" unless ($flavour =~ /64|n32/i);
-+
-+$v0 = ($flavour =~ /nubi/i) ? $a0 : $t0;
-+$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? "0x0003f000" : "0x00030000";
-+
-+($ctx,$inp,$len,$padbit) = ($a0,$a1,$a2,$a3);
-+($in0,$in1,$tmp0,$tmp1,$tmp2,$tmp3,$tmp4) = ($a4,$a5,$a6,$a7,$at,$t0,$t1);
-+
-+$code.=<<___;
-+#ifdef MIPSEB
-+# define MSB 0
-+# define LSB 7
-+#else
-+# define MSB 7
-+# define LSB 0
-+#endif
-+
-+.text
-+.set	noat
-+.set	noreorder
-+
-+.align	5
-+.globl	poly1305_init
-+.ent	poly1305_init
-+poly1305_init:
-+	.frame	$sp,0,$ra
-+	.set	reorder
-+
-+	sd	$zero,0($ctx)
-+	sd	$zero,8($ctx)
-+	sd	$zero,16($ctx)
-+
-+	beqz	$inp,.Lno_key
-+
-+	ldl	$in0,0+MSB($inp)
-+	ldl	$in1,8+MSB($inp)
-+	ldr	$in0,0+LSB($inp)
-+	ldr	$in1,8+LSB($inp)
-+#ifdef	MIPSEB
-+# if defined(_MIPS_ARCH_MIPS64R2)
-+	dsbh	$in0,$in0		# byte swap
-+	 dsbh	$in1,$in1
-+	dshd	$in0,$in0
-+	 dshd	$in1,$in1
-+# else
-+	ori	$tmp0,$zero,0xFF
-+	dsll	$tmp2,$tmp0,32
-+	or	$tmp0,$tmp2		# 0x000000FF000000FF
-+
-+	and	$tmp1,$in0,$tmp0	# byte swap
-+	 and	$tmp3,$in1,$tmp0
-+	dsrl	$tmp2,$in0,24
-+	 dsrl	$tmp4,$in1,24
-+	dsll	$tmp1,24
-+	 dsll	$tmp3,24
-+	and	$tmp2,$tmp0
-+	 and	$tmp4,$tmp0
-+	dsll	$tmp0,8			# 0x0000FF000000FF00
-+	or	$tmp1,$tmp2
-+	 or	$tmp3,$tmp4
-+	and	$tmp2,$in0,$tmp0
-+	 and	$tmp4,$in1,$tmp0
-+	dsrl	$in0,8
-+	 dsrl	$in1,8
-+	dsll	$tmp2,8
-+	 dsll	$tmp4,8
-+	and	$in0,$tmp0
-+	 and	$in1,$tmp0
-+	or	$tmp1,$tmp2
-+	 or	$tmp3,$tmp4
-+	or	$in0,$tmp1
-+	 or	$in1,$tmp3
-+	dsrl	$tmp1,$in0,32
-+	 dsrl	$tmp3,$in1,32
-+	dsll	$in0,32
-+	 dsll	$in1,32
-+	or	$in0,$tmp1
-+	 or	$in1,$tmp3
-+# endif
-+#endif
-+	li	$tmp0,1
-+	dsll	$tmp0,32
-+	daddiu	$tmp0,-63
-+	dsll	$tmp0,28
-+	daddiu	$tmp0,-1		# 0ffffffc0fffffff
-+
-+	and	$in0,$tmp0
-+	daddiu	$tmp0,-3		# 0ffffffc0ffffffc
-+	and	$in1,$tmp0
-+
-+	sd	$in0,24($ctx)
-+	dsrl	$tmp0,$in1,2
-+	sd	$in1,32($ctx)
-+	daddu	$tmp0,$in1		# s1 = r1 + (r1 >> 2)
-+	sd	$tmp0,40($ctx)
-+
-+.Lno_key:
-+	li	$v0,0			# return 0
-+	jr	$ra
-+.end	poly1305_init
-+___
-+{
-+my ($h0,$h1,$h2,$r0,$r1,$s1,$d0,$d1,$d2) =
-+   ($s0,$s1,$s2,$s3,$s4,$s5,$in0,$in1,$t2);
-+
-+$code.=<<___;
-+.align	5
-+.globl	poly1305_blocks
-+.ent	poly1305_blocks
-+poly1305_blocks:
-+	.set	noreorder
-+	dsrl	$len,4			# number of complete blocks
-+	bnez	$len,poly1305_blocks_internal
-+	nop
-+	jr	$ra
-+	nop
-+.end	poly1305_blocks
-+
-+.align	5
-+.ent	poly1305_blocks_internal
-+poly1305_blocks_internal:
-+	.frame	$sp,6*8,$ra
-+	.mask	$SAVED_REGS_MASK,-8
-+	.set	noreorder
-+	dsub	$sp,6*8
-+	sd	$s5,40($sp)
-+	sd	$s4,32($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
-+	sd	$s3,24($sp)
-+	sd	$s2,16($sp)
-+	sd	$s1,8($sp)
-+	sd	$s0,0($sp)
-+___
-+$code.=<<___;
-+	.set	reorder
-+
-+	ld	$h0,0($ctx)		# load hash value
-+	ld	$h1,8($ctx)
-+	ld	$h2,16($ctx)
-+
-+	ld	$r0,24($ctx)		# load key
-+	ld	$r1,32($ctx)
-+	ld	$s1,40($ctx)
-+
-+.Loop:
-+	ldl	$in0,0+MSB($inp)	# load input
-+	ldl	$in1,8+MSB($inp)
-+	ldr	$in0,0+LSB($inp)
-+	daddiu	$len,-1
-+	ldr	$in1,8+LSB($inp)
-+	daddiu	$inp,16
-+#ifdef	MIPSEB
-+# if defined(_MIPS_ARCH_MIPS64R2)
-+	dsbh	$in0,$in0		# byte swap
-+	 dsbh	$in1,$in1
-+	dshd	$in0,$in0
-+	 dshd	$in1,$in1
-+# else
-+	ori	$tmp0,$zero,0xFF
-+	dsll	$tmp2,$tmp0,32
-+	or	$tmp0,$tmp2		# 0x000000FF000000FF
-+
-+	and	$tmp1,$in0,$tmp0	# byte swap
-+	 and	$tmp3,$in1,$tmp0
-+	dsrl	$tmp2,$in0,24
-+	 dsrl	$tmp4,$in1,24
-+	dsll	$tmp1,24
-+	 dsll	$tmp3,24
-+	and	$tmp2,$tmp0
-+	 and	$tmp4,$tmp0
-+	dsll	$tmp0,8			# 0x0000FF000000FF00
-+	or	$tmp1,$tmp2
-+	 or	$tmp3,$tmp4
-+	and	$tmp2,$in0,$tmp0
-+	 and	$tmp4,$in1,$tmp0
-+	dsrl	$in0,8
-+	 dsrl	$in1,8
-+	dsll	$tmp2,8
-+	 dsll	$tmp4,8
-+	and	$in0,$tmp0
-+	 and	$in1,$tmp0
-+	or	$tmp1,$tmp2
-+	 or	$tmp3,$tmp4
-+	or	$in0,$tmp1
-+	 or	$in1,$tmp3
-+	dsrl	$tmp1,$in0,32
-+	 dsrl	$tmp3,$in1,32
-+	dsll	$in0,32
-+	 dsll	$in1,32
-+	or	$in0,$tmp1
-+	 or	$in1,$tmp3
-+# endif
-+#endif
-+	daddu	$h0,$in0		# accumulate input
-+	daddu	$h1,$in1
-+	sltu	$tmp0,$h0,$in0
-+	sltu	$tmp1,$h1,$in1
-+	daddu	$h1,$tmp0
-+
-+	dmultu	$r0,$h0			# h0*r0
-+	 daddu	$h2,$padbit
-+	 sltu	$tmp0,$h1,$tmp0
-+	mflo	$d0
-+	mfhi	$d1
-+
-+	dmultu	$s1,$h1			# h1*5*r1
-+	 daddu	$tmp0,$tmp1
-+	 daddu	$h2,$tmp0
-+	mflo	$tmp0
-+	mfhi	$tmp1
-+
-+	dmultu	$r1,$h0			# h0*r1
-+	 daddu	$d0,$tmp0
-+	 daddu	$d1,$tmp1
-+	mflo	$tmp2
-+	mfhi	$d2
-+	 sltu	$tmp0,$d0,$tmp0
-+	 daddu	$d1,$tmp0
-+
-+	dmultu	$r0,$h1			# h1*r0
-+	 daddu	$d1,$tmp2
-+	 sltu	$tmp2,$d1,$tmp2
-+	mflo	$tmp0
-+	mfhi	$tmp1
-+	 daddu	$d2,$tmp2
-+
-+	dmultu	$s1,$h2			# h2*5*r1
-+	 daddu	$d1,$tmp0
-+	 daddu	$d2,$tmp1
-+	mflo	$tmp2
-+
-+	dmultu	$r0,$h2			# h2*r0
-+	 sltu	$tmp0,$d1,$tmp0
-+	 daddu	$d2,$tmp0
-+	mflo	$tmp3
-+
-+	daddu	$d1,$tmp2
-+	daddu	$d2,$tmp3
-+	sltu	$tmp2,$d1,$tmp2
-+	daddu	$d2,$tmp2
-+
-+	li	$tmp0,-4		# final reduction
-+	and	$tmp0,$d2
-+	dsrl	$tmp1,$d2,2
-+	andi	$h2,$d2,3
-+	daddu	$tmp0,$tmp1
-+	daddu	$h0,$d0,$tmp0
-+	sltu	$tmp0,$h0,$tmp0
-+	daddu	$h1,$d1,$tmp0
-+	sltu	$tmp0,$h1,$tmp0
-+	daddu	$h2,$h2,$tmp0
-+
-+	bnez	$len,.Loop
-+
-+	sd	$h0,0($ctx)		# store hash value
-+	sd	$h1,8($ctx)
-+	sd	$h2,16($ctx)
-+
-+	.set	noreorder
-+	ld	$s5,40($sp)		# epilogue
-+	ld	$s4,32($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi epilogue
-+	ld	$s3,24($sp)
-+	ld	$s2,16($sp)
-+	ld	$s1,8($sp)
-+	ld	$s0,0($sp)
-+___
-+$code.=<<___;
-+	jr	$ra
-+	dadd	$sp,6*8
-+.end	poly1305_blocks_internal
-+___
-+}
-+{
-+my ($ctx,$mac,$nonce) = ($a0,$a1,$a2);
-+
-+$code.=<<___;
-+.align	5
-+.globl	poly1305_emit
-+.ent	poly1305_emit
-+poly1305_emit:
-+	.frame	$sp,0,$ra
-+	.set	reorder
-+
-+	ld	$tmp0,0($ctx)
-+	ld	$tmp1,8($ctx)
-+	ld	$tmp2,16($ctx)
-+
-+	daddiu	$in0,$tmp0,5		# compare to modulus
-+	sltiu	$tmp3,$in0,5
-+	daddu	$in1,$tmp1,$tmp3
-+	sltu	$tmp3,$in1,$tmp3
-+	daddu	$tmp2,$tmp2,$tmp3
-+
-+	dsrl	$tmp2,2			# see if it carried/borrowed
-+	dsubu	$tmp2,$zero,$tmp2
-+	nor	$tmp3,$zero,$tmp2
-+
-+	and	$in0,$tmp2
-+	and	$tmp0,$tmp3
-+	and	$in1,$tmp2
-+	and	$tmp1,$tmp3
-+	or	$in0,$tmp0
-+	or	$in1,$tmp1
-+
-+	lwu	$tmp0,0($nonce)		# load nonce
-+	lwu	$tmp1,4($nonce)
-+	lwu	$tmp2,8($nonce)
-+	lwu	$tmp3,12($nonce)
-+	dsll	$tmp1,32
-+	dsll	$tmp3,32
-+	or	$tmp0,$tmp1
-+	or	$tmp2,$tmp3
-+
-+	daddu	$in0,$tmp0		# accumulate nonce
-+	daddu	$in1,$tmp2
-+	sltu	$tmp0,$in0,$tmp0
-+	daddu	$in1,$tmp0
-+
-+	dsrl	$tmp0,$in0,8		# write mac value
-+	dsrl	$tmp1,$in0,16
-+	dsrl	$tmp2,$in0,24
-+	sb	$in0,0($mac)
-+	dsrl	$tmp3,$in0,32
-+	sb	$tmp0,1($mac)
-+	dsrl	$tmp0,$in0,40
-+	sb	$tmp1,2($mac)
-+	dsrl	$tmp1,$in0,48
-+	sb	$tmp2,3($mac)
-+	dsrl	$tmp2,$in0,56
-+	sb	$tmp3,4($mac)
-+	dsrl	$tmp3,$in1,8
-+	sb	$tmp0,5($mac)
-+	dsrl	$tmp0,$in1,16
-+	sb	$tmp1,6($mac)
-+	dsrl	$tmp1,$in1,24
-+	sb	$tmp2,7($mac)
-+
-+	sb	$in1,8($mac)
-+	dsrl	$tmp2,$in1,32
-+	sb	$tmp3,9($mac)
-+	dsrl	$tmp3,$in1,40
-+	sb	$tmp0,10($mac)
-+	dsrl	$tmp0,$in1,48
-+	sb	$tmp1,11($mac)
-+	dsrl	$tmp1,$in1,56
-+	sb	$tmp2,12($mac)
-+	sb	$tmp3,13($mac)
-+	sb	$tmp0,14($mac)
-+	sb	$tmp1,15($mac)
-+
-+	jr	$ra
-+.end	poly1305_emit
-+.rdata
-+.asciiz	"Poly1305 for MIPS64, CRYPTOGAMS by "
-+.align	2
-+___
-+}
-+
-+$output=pop and open STDOUT,">$output";
-+print $code;
-+close STDOUT;
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppc.pl
-new file mode 100755
-index 0000000..ab65910
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppc.pl
-@@ -0,0 +1,644 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements Poly1305 hash for PowerPC.
-+#
-+# June 2015
-+#
-+# Numbers are cycles per processed byte with poly1305_blocks alone,
-+# and improvement coefficients relative to gcc-generated code.
-+#
-+#			-m32		-m64
-+#
-+# Freescale e300	14.8/+80%	-
-+# PPC74x0		7.60/+60%	-
-+# PPC970		7.00/+114%	3.51/+205%
-+# POWER7		3.75/+260%	1.93/+100%
-+# POWER8		-		2.03/+200%
-+#
-+# Do we need floating-point implementation for PPC? Results presented
-+# in poly1305_ieee754.c are tricky to compare to, because they are for
-+# compiler-generated code. On the other hand it's known that floating-
-+# point performance can be dominated by FPU latency, which means that
-+# there is limit even for ideally optimized (and even vectorized) code.
-+# And this limit is estimated to be higher than above -m64 results. Or
-+# in other words floating-point implementation can be meaningful to
-+# consider only in 32-bit application context. We probably have to
-+# recognize that 32-bit builds are getting less popular on high-end
-+# systems and therefore tend to target embedded ones, which might not
-+# even have FPU...
-+#
-+# On side note, Power ISA 2.07 enables vector base 2^26 implementation,
-+# and POWER8 might have capacity to break 1.0 cycle per byte barrier...
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /64/) {
-+	$SIZE_T	=8;
-+	$LRSAVE	=2*$SIZE_T;
-+	$UCMP	="cmpld";
-+	$STU	="stdu";
-+	$POP	="ld";
-+	$PUSH	="std";
-+} elsif ($flavour =~ /32/) {
-+	$SIZE_T	=4;
-+	$LRSAVE	=$SIZE_T;
-+	$UCMP	="cmplw";
-+	$STU	="stwu";
-+	$POP	="lwz";
-+	$PUSH	="stw";
-+} else { die "nonsense $flavour"; }
-+
-+# Define endianness based on flavour
-+# i.e.: linux64le
-+$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-+
-+$FRAME=24*$SIZE_T;
-+
-+$sp="r1";
-+my ($ctx,$inp,$len,$padbit) = map("r$_",(3..6));
-+my ($mac,$nonce)=($inp,$len);
-+my $mask = "r0";
-+
-+$code=<<___;
-+.machine	"any"
-+.text
-+___
-+							if ($flavour =~ /64/) {
-+###############################################################################
-+# base 2^64 implementation
-+
-+my ($h0,$h1,$h2,$d0,$d1,$d2, $r0,$r1,$s1, $t0,$t1) = map("r$_",(7..12,27..31));
-+
-+$code.=<<___;
-+.globl	.poly1305_init_int
-+.align	4
-+.poly1305_init_int:
-+	xor	r0,r0,r0
-+	std	r0,0($ctx)		# zero hash value
-+	std	r0,8($ctx)
-+	std	r0,16($ctx)
-+
-+	$UCMP	$inp,r0
-+	beq-	Lno_key
-+___
-+$code.=<<___	if ($LITTLE_ENDIAN);
-+	ld	$d0,0($inp)		# load key material
-+	ld	$d1,8($inp)
-+___
-+$code.=<<___	if (!$LITTLE_ENDIAN);
-+	li	$h0,4
-+	lwbrx	$d0,0,$inp		# load key material
-+	li	$d1,8
-+	lwbrx	$h0,$h0,$inp
-+	li	$h1,12
-+	lwbrx	$d1,$d1,$inp
-+	lwbrx	$h1,$h1,$inp
-+	insrdi	$d0,$h0,32,0
-+	insrdi	$d1,$h1,32,0
-+___
-+$code.=<<___;
-+	lis	$h1,0xfff		# 0x0fff0000
-+	ori	$h1,$h1,0xfffc		# 0x0ffffffc
-+	insrdi	$h1,$h1,32,0		# 0x0ffffffc0ffffffc
-+	ori	$h0,$h1,3		# 0x0ffffffc0fffffff
-+
-+	and	$d0,$d0,$h0
-+	and	$d1,$d1,$h1
-+
-+	std	$d0,32($ctx)		# store key
-+	std	$d1,40($ctx)
-+
-+Lno_key:
-+	xor	r3,r3,r3
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,2,0
-+.size	.poly1305_init_int,.-.poly1305_init_int
-+
-+.globl	.poly1305_blocks
-+.align	4
-+.poly1305_blocks:
-+	srdi.	$len,$len,4
-+	beq-	Labort
-+
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
-+	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
-+
-+	ld	$r0,32($ctx)		# load key
-+	ld	$r1,40($ctx)
-+
-+	ld	$h0,0($ctx)		# load hash value
-+	ld	$h1,8($ctx)
-+	ld	$h2,16($ctx)
-+
-+	srdi	$s1,$r1,2
-+	mtctr	$len
-+	add	$s1,$s1,$r1		# s1 = r1 + r1>>2
-+	li	$mask,3
-+	b	Loop
-+
-+.align	4
-+Loop:
-+___
-+$code.=<<___	if ($LITTLE_ENDIAN);
-+	ld	$t0,0($inp)		# load input
-+	ld	$t1,8($inp)
-+___
-+$code.=<<___	if (!$LITTLE_ENDIAN);
-+	li	$d0,4
-+	lwbrx	$t0,0,$inp		# load input
-+	li	$t1,8
-+	lwbrx	$d0,$d0,$inp
-+	li	$d1,12
-+	lwbrx	$t1,$t1,$inp
-+	lwbrx	$d1,$d1,$inp
-+	insrdi	$t0,$d0,32,0
-+	insrdi	$t1,$d1,32,0
-+___
-+$code.=<<___;
-+	addi	$inp,$inp,16
-+
-+	addc	$h0,$h0,$t0		# accumulate input
-+	adde	$h1,$h1,$t1
-+
-+	mulld	$d0,$h0,$r0		# h0*r0
-+	mulhdu	$d1,$h0,$r0
-+	adde	$h2,$h2,$padbit
-+
-+	mulld	$t0,$h1,$s1		# h1*5*r1
-+	mulhdu	$t1,$h1,$s1
-+	addc	$d0,$d0,$t0
-+	adde	$d1,$d1,$t1
-+
-+	mulld	$t0,$h0,$r1		# h0*r1
-+	mulhdu	$d2,$h0,$r1
-+	addc	$d1,$d1,$t0
-+	addze	$d2,$d2
-+
-+	mulld	$t0,$h1,$r0		# h1*r0
-+	mulhdu	$t1,$h1,$r0
-+	addc	$d1,$d1,$t0
-+	adde	$d2,$d2,$t1
-+
-+	mulld	$t0,$h2,$s1		# h2*5*r1
-+	mulld	$t1,$h2,$r0		# h2*r0
-+	addc	$d1,$d1,$t0
-+	adde	$d2,$d2,$t1
-+
-+	andc	$t0,$d2,$mask		# final reduction step
-+	and	$h2,$d2,$mask
-+	srdi	$t1,$t0,2
-+	add	$t0,$t0,$t1
-+	addc	$h0,$d0,$t0
-+	addze	$h1,$d1
-+	addze	$h2,$h2
-+
-+	bdnz	Loop
-+
-+	std	$h0,0($ctx)		# store hash value
-+	std	$h1,8($ctx)
-+	std	$h2,16($ctx)
-+
-+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
-+	addi	$sp,$sp,$FRAME
-+Labort:
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,5,4,0
-+.size	.poly1305_blocks,.-.poly1305_blocks
-+
-+.globl	.poly1305_emit
-+.align	4
-+.poly1305_emit:
-+	ld	$h0,0($ctx)		# load hash
-+	ld	$h1,8($ctx)
-+	ld	$h2,16($ctx)
-+	ld	$padbit,0($nonce)	# load nonce
-+	ld	$nonce,8($nonce)
-+
-+	addic	$d0,$h0,5		# compare to modulus
-+	addze	$d1,$h1
-+	addze	$d2,$h2
-+
-+	srdi	$mask,$d2,2		# did it carry/borrow?
-+	neg	$mask,$mask
-+
-+	andc	$h0,$h0,$mask
-+	and	$d0,$d0,$mask
-+	andc	$h1,$h1,$mask
-+	and	$d1,$d1,$mask
-+	or	$h0,$h0,$d0
-+	or	$h1,$h1,$d1
-+___
-+$code.=<<___	if (!$LITTLE_ENDIAN);
-+	rotldi	$padbit,$padbit,32	# flip nonce words
-+	rotldi	$nonce,$nonce,32
-+___
-+$code.=<<___;
-+	addc	$h0,$h0,$padbit		# accumulate nonce
-+	adde	$h1,$h1,$nonce
-+___
-+$code.=<<___	if ($LITTLE_ENDIAN);
-+	std	$h0,0($mac)		# write result
-+	std	$h1,8($mac)
-+___
-+$code.=<<___	if (!$LITTLE_ENDIAN);
-+	extrdi	r0,$h0,32,0
-+	li	$d0,4
-+	stwbrx	$h0,0,$mac		# write result
-+	extrdi	$h0,$h1,32,0
-+	li	$d1,8
-+	stwbrx	r0,$d0,$mac
-+	li	$d2,12
-+	stwbrx	$h1,$d1,$mac
-+	stwbrx	$h0,$d2,$mac
-+___
-+$code.=<<___;
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,3,0
-+.size	.poly1305_emit,.-.poly1305_emit
-+___
-+							} else {
-+###############################################################################
-+# base 2^32 implementation
-+
-+my ($h0,$h1,$h2,$h3,$h4, $r0,$r1,$r2,$r3, $s1,$s2,$s3,
-+    $t0,$t1,$t2,$t3, $D0,$D1,$D2,$D3, $d0,$d1,$d2,$d3
-+   ) = map("r$_",(7..12,14..31));
-+
-+$code.=<<___;
-+.globl	.poly1305_init_int
-+.align	4
-+.poly1305_init_int:
-+	xor	r0,r0,r0
-+	stw	r0,0($ctx)		# zero hash value
-+	stw	r0,4($ctx)
-+	stw	r0,8($ctx)
-+	stw	r0,12($ctx)
-+	stw	r0,16($ctx)
-+
-+	$UCMP	$inp,r0
-+	beq-	Lno_key
-+___
-+$code.=<<___	if ($LITTLE_ENDIAN);
-+	lw	$h0,0($inp)		# load key material
-+	lw	$h1,4($inp)
-+	lw	$h2,8($inp)
-+	lw	$h3,12($inp)
-+___
-+$code.=<<___	if (!$LITTLE_ENDIAN);
-+	li	$h1,4
-+	lwbrx	$h0,0,$inp		# load key material
-+	li	$h2,8
-+	lwbrx	$h1,$h1,$inp
-+	li	$h3,12
-+	lwbrx	$h2,$h2,$inp
-+	lwbrx	$h3,$h3,$inp
-+___
-+$code.=<<___;
-+	lis	$mask,0xf000		# 0xf0000000
-+	li	$r0,-4
-+	andc	$r0,$r0,$mask		# 0x0ffffffc
-+
-+	andc	$h0,$h0,$mask
-+	and	$h1,$h1,$r0
-+	and	$h2,$h2,$r0
-+	and	$h3,$h3,$r0
-+
-+	stw	$h0,32($ctx)		# store key
-+	stw	$h1,36($ctx)
-+	stw	$h2,40($ctx)
-+	stw	$h3,44($ctx)
-+
-+Lno_key:
-+	xor	r3,r3,r3
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,2,0
-+.size	.poly1305_init_int,.-.poly1305_init_int
-+
-+.globl	.poly1305_blocks
-+.align	4
-+.poly1305_blocks:
-+	srwi.	$len,$len,4
-+	beq-	Labort
-+
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
-+	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
-+
-+	lwz	$r0,32($ctx)		# load key
-+	lwz	$r1,36($ctx)
-+	lwz	$r2,40($ctx)
-+	lwz	$r3,44($ctx)
-+
-+	lwz	$h0,0($ctx)		# load hash value
-+	lwz	$h1,4($ctx)
-+	lwz	$h2,8($ctx)
-+	lwz	$h3,12($ctx)
-+	lwz	$h4,16($ctx)
-+
-+	srwi	$s1,$r1,2
-+	srwi	$s2,$r2,2
-+	srwi	$s3,$r3,2
-+	add	$s1,$s1,$r1		# si = ri + ri>>2
-+	add	$s2,$s2,$r2
-+	add	$s3,$s3,$r3
-+	mtctr	$len
-+	li	$mask,3
-+	b	Loop
-+
-+.align	4
-+Loop:
-+___
-+$code.=<<___	if ($LITTLE_ENDIAN);
-+	lwz	$d0,0($inp)		# load input
-+	lwz	$d1,4($inp)
-+	lwz	$d2,8($inp)
-+	lwz	$d3,12($inp)
-+___
-+$code.=<<___	if (!$LITTLE_ENDIAN);
-+	li	$d1,4
-+	lwbrx	$d0,0,$inp		# load input
-+	li	$d2,8
-+	lwbrx	$d1,$d1,$inp
-+	li	$d3,12
-+	lwbrx	$d2,$d2,$inp
-+	lwbrx	$d3,$d3,$inp
-+___
-+$code.=<<___;
-+	addi	$inp,$inp,16
-+
-+	addc	$h0,$h0,$d0		# accumulate input
-+	adde	$h1,$h1,$d1
-+	adde	$h2,$h2,$d2
-+
-+	mullw	$d0,$h0,$r0		# h0*r0
-+	mulhwu	$D0,$h0,$r0
-+
-+	mullw	$d1,$h0,$r1		# h0*r1
-+	mulhwu	$D1,$h0,$r1
-+
-+	mullw	$d2,$h0,$r2		# h0*r2
-+	mulhwu	$D2,$h0,$r2
-+
-+	 adde	$h3,$h3,$d3
-+	 adde	$h4,$h4,$padbit
-+
-+	mullw	$d3,$h0,$r3		# h0*r3
-+	mulhwu	$D3,$h0,$r3
-+
-+	mullw	$t0,$h1,$s3		# h1*s3
-+	mulhwu	$t1,$h1,$s3
-+
-+	mullw	$t2,$h1,$r0		# h1*r0
-+	mulhwu	$t3,$h1,$r0
-+	 addc	$d0,$d0,$t0
-+	 adde	$D0,$D0,$t1
-+
-+	mullw	$t0,$h1,$r1		# h1*r1
-+	mulhwu	$t1,$h1,$r1
-+	 addc	$d1,$d1,$t2
-+	 adde	$D1,$D1,$t3
-+
-+	mullw	$t2,$h1,$r2		# h1*r2
-+	mulhwu	$t3,$h1,$r2
-+	 addc	$d2,$d2,$t0
-+	 adde	$D2,$D2,$t1
-+
-+	mullw	$t0,$h2,$s2		# h2*s2
-+	mulhwu	$t1,$h2,$s2
-+	 addc	$d3,$d3,$t2
-+	 adde	$D3,$D3,$t3
-+
-+	mullw	$t2,$h2,$s3		# h2*s3
-+	mulhwu	$t3,$h2,$s3
-+	 addc	$d0,$d0,$t0
-+	 adde	$D0,$D0,$t1
-+
-+	mullw	$t0,$h2,$r0		# h2*r0
-+	mulhwu	$t1,$h2,$r0
-+	 addc	$d1,$d1,$t2
-+	 adde	$D1,$D1,$t3
-+
-+	mullw	$t2,$h2,$r1		# h2*r1
-+	mulhwu	$t3,$h2,$r1
-+	 addc	$d2,$d2,$t0
-+	 adde	$D2,$D2,$t1
-+
-+	mullw	$t0,$h3,$s1		# h3*s1
-+	mulhwu	$t1,$h3,$s1
-+	 addc	$d3,$d3,$t2
-+	 adde	$D3,$D3,$t3
-+
-+	mullw	$t2,$h3,$s2		# h3*s2
-+	mulhwu	$t3,$h3,$s2
-+	 addc	$d0,$d0,$t0
-+	 adde	$D0,$D0,$t1
-+
-+	mullw	$t0,$h3,$s3		# h3*s3
-+	mulhwu	$t1,$h3,$s3
-+	 addc	$d1,$d1,$t2
-+	 adde	$D1,$D1,$t3
-+
-+	mullw	$t2,$h3,$r0		# h3*r0
-+	mulhwu	$t3,$h3,$r0
-+	 addc	$d2,$d2,$t0
-+	 adde	$D2,$D2,$t1
-+
-+	mullw	$t0,$h4,$s1		# h4*s1
-+	 addc	$d3,$d3,$t2
-+	 adde	$D3,$D3,$t3
-+	addc	$d1,$d1,$t0
-+
-+	mullw	$t1,$h4,$s2		# h4*s2
-+	 addze	$D1,$D1
-+	addc	$d2,$d2,$t1
-+	addze	$D2,$D2
-+
-+	mullw	$t2,$h4,$s3		# h4*s3
-+	addc	$d3,$d3,$t2
-+	addze	$D3,$D3
-+
-+	mullw	$h4,$h4,$r0		# h4*r0
-+
-+	addc	$h1,$d1,$D0
-+	adde	$h2,$d2,$D1
-+	adde	$h3,$d3,$D2
-+	adde	$h4,$h4,$D3
-+
-+	andc	$D0,$h4,$mask		# final reduction step
-+	and	$h4,$h4,$mask
-+	srwi	$D1,$D0,2
-+	add	$D0,$D0,$D1
-+	addc	$h0,$d0,$D0
-+	addze	$h1,$h1
-+	addze	$h2,$h2
-+	addze	$h3,$h3
-+	addze	$h4,$h4
-+
-+	bdnz	Loop
-+
-+	stw	$h0,0($ctx)		# store hash value
-+	stw	$h1,4($ctx)
-+	stw	$h2,8($ctx)
-+	stw	$h3,12($ctx)
-+	stw	$h4,16($ctx)
-+
-+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
-+	addi	$sp,$sp,$FRAME
-+Labort:
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,18,4,0
-+.size	.poly1305_blocks,.-.poly1305_blocks
-+
-+.globl	.poly1305_emit
-+.align	4
-+.poly1305_emit:
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
-+	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
-+
-+	lwz	$h0,0($ctx)		# load hash
-+	lwz	$h1,4($ctx)
-+	lwz	$h2,8($ctx)
-+	lwz	$h3,12($ctx)
-+	lwz	$h4,16($ctx)
-+
-+	addic	$d0,$h0,5		# compare to modulus
-+	addze	$d1,$h1
-+	addze	$d2,$h2
-+	addze	$d3,$h3
-+	addze	$mask,$h4
-+
-+	srwi	$mask,$mask,2		# did it carry/borrow?
-+	neg	$mask,$mask
-+
-+	andc	$h0,$h0,$mask
-+	and	$d0,$d0,$mask
-+	andc	$h1,$h1,$mask
-+	and	$d1,$d1,$mask
-+	or	$h0,$h0,$d0
-+	lwz	$d0,0($nonce)		# load nonce
-+	andc	$h2,$h2,$mask
-+	and	$d2,$d2,$mask
-+	or	$h1,$h1,$d1
-+	lwz	$d1,4($nonce)
-+	andc	$h3,$h3,$mask
-+	and	$d3,$d3,$mask
-+	or	$h2,$h2,$d2
-+	lwz	$d2,8($nonce)
-+	or	$h3,$h3,$d3
-+	lwz	$d3,12($nonce)
-+
-+	addc	$h0,$h0,$d0		# accumulate nonce
-+	adde	$h1,$h1,$d1
-+	adde	$h2,$h2,$d2
-+	adde	$h3,$h3,$d3
-+___
-+$code.=<<___	if ($LITTLE_ENDIAN);
-+	stw	$h0,0($mac)		# write result
-+	stw	$h1,4($mac)
-+	stw	$h2,8($mac)
-+	stw	$h3,12($mac)
-+___
-+$code.=<<___	if (!$LITTLE_ENDIAN);
-+	li	$d1,4
-+	stwbrx	$h0,0,$mac		# write result
-+	li	$d2,8
-+	stwbrx	$h1,$d1,$mac
-+	li	$d3,12
-+	stwbrx	$h2,$d2,$mac
-+	stwbrx	$h3,$d3,$mac
-+___
-+$code.=<<___;
-+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,4,3,0
-+.size	.poly1305_emit,.-.poly1305_emit
-+___
-+							}
-+$code.=<<___;
-+.asciz	"Poly1305 for PPC, CRYPTOGAMS by "
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppcfp.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppcfp.pl
-new file mode 100755
-index 0000000..49f70a8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-ppcfp.pl
-@@ -0,0 +1,739 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements Poly1305 hash for PowerPC FPU.
-+#
-+# June 2015
-+#
-+# Numbers are cycles per processed byte with poly1305_blocks alone,
-+# and improvement coefficients relative to gcc-generated code.
-+#
-+# Freescale e300	9.78/+30%
-+# PPC74x0		6.92/+50%
-+# PPC970		6.03/+80%
-+# POWER7		3.50/+30%
-+# POWER8		3.75/+10%
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /64/) {
-+	$SIZE_T	=8;
-+	$LRSAVE	=2*$SIZE_T;
-+	$UCMP	="cmpld";
-+	$STU	="stdu";
-+	$POP	="ld";
-+	$PUSH	="std";
-+} elsif ($flavour =~ /32/) {
-+	$SIZE_T	=4;
-+	$LRSAVE	=$SIZE_T;
-+	$UCMP	="cmplw";
-+	$STU	="stwu";
-+	$POP	="lwz";
-+	$PUSH	="stw";
-+} else { die "nonsense $flavour"; }
-+
-+$LITTLE_ENDIAN = ($flavour=~/le$/) ? 4 : 0;
-+
-+$LWXLE = $LITTLE_ENDIAN ? "lwzx" : "lwbrx";
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-+
-+$LOCALS=6*$SIZE_T;
-+$FRAME=$LOCALS+6*8+18*8;
-+
-+my $sp="r1";
-+
-+my ($ctx,$inp,$len,$padbit) = map("r$_",(3..6));
-+my ($in0,$in1,$in2,$in3,$i1,$i2,$i3) = map("r$_",(7..12,6));
-+
-+my ($h0lo,$h0hi,$h1lo,$h1hi,$h2lo,$h2hi,$h3lo,$h3hi,
-+    $two0,$two32,$two64,$two96,$two130,$five_two130,
-+    $r0lo,$r0hi,$r1lo,$r1hi,$r2lo,$r2hi,
-+    $s2lo,$s2hi,$s3lo,$s3hi,
-+    $c0lo,$c0hi,$c1lo,$c1hi,$c2lo,$c2hi,$c3lo,$c3hi) = map("f$_",(0..31));
-+# borrowings
-+my ($r3lo,$r3hi,$s1lo,$s1hi) = ($c0lo,$c0hi,$c1lo,$c1hi);
-+my ($x0,$x1,$x2,$x3) = ($c2lo,$c2hi,$c3lo,$c3hi);
-+my ($y0,$y1,$y2,$y3) = ($c3lo,$c3hi,$c1lo,$c1hi);
-+
-+$code.=<<___;
-+.machine	"any"
-+.text
-+
-+.globl	.poly1305_init_fpu
-+.align	6
-+.poly1305_init_fpu:
-+	$STU	$sp,-$LOCALS($sp)		# minimal frame
-+	mflr	$padbit
-+	$PUSH	$padbit,`$LOCALS+$LRSAVE`($sp)
-+
-+	bl	LPICmeup
-+
-+	xor	r0,r0,r0
-+	mtlr	$padbit				# restore lr
-+
-+	lfd	$two0,8*0($len)			# load constants
-+	lfd	$two32,8*1($len)
-+	lfd	$two64,8*2($len)
-+	lfd	$two96,8*3($len)
-+	lfd	$two130,8*4($len)
-+	lfd	$five_two130,8*5($len)
-+
-+	stfd	$two0,8*0($ctx)			# initial hash value, biased 0
-+	stfd	$two32,8*1($ctx)
-+	stfd	$two64,8*2($ctx)
-+	stfd	$two96,8*3($ctx)
-+
-+	$UCMP	$inp,r0
-+	beq-	Lno_key
-+
-+	lfd	$h3lo,8*13($len)		# new fpscr
-+	mffs	$h3hi				# old fpscr
-+
-+	stfd	$two0,8*4($ctx)			# key "template"
-+	stfd	$two32,8*5($ctx)
-+	stfd	$two64,8*6($ctx)
-+	stfd	$two96,8*7($ctx)
-+
-+	li	$in1,4
-+	li	$in2,8
-+	li	$in3,12
-+	$LWXLE	$in0,0,$inp			# load key
-+	$LWXLE	$in1,$in1,$inp
-+	$LWXLE	$in2,$in2,$inp
-+	$LWXLE	$in3,$in3,$inp
-+
-+	lis	$i1,0xf000			#   0xf0000000
-+	ori	$i2,$i1,3			#   0xf0000003
-+	andc	$in0,$in0,$i1			# &=0x0fffffff
-+	andc	$in1,$in1,$i2			# &=0x0ffffffc
-+	andc	$in2,$in2,$i2
-+	andc	$in3,$in3,$i2
-+
-+	stw	$in0,`8*4+(4^$LITTLE_ENDIAN)`($ctx)	# fill "template"
-+	stw	$in1,`8*5+(4^$LITTLE_ENDIAN)`($ctx)
-+	stw	$in2,`8*6+(4^$LITTLE_ENDIAN)`($ctx)
-+	stw	$in3,`8*7+(4^$LITTLE_ENDIAN)`($ctx)
-+
-+	mtfsf	255,$h3lo			# fpscr
-+	stfd	$two0,8*18($ctx)		# copy constants to context
-+	stfd	$two32,8*19($ctx)
-+	stfd	$two64,8*20($ctx)
-+	stfd	$two96,8*21($ctx)
-+	stfd	$two130,8*22($ctx)
-+	stfd	$five_two130,8*23($ctx)
-+
-+	lfd	$h0lo,8*4($ctx)			# load [biased] key
-+	lfd	$h1lo,8*5($ctx)
-+	lfd	$h2lo,8*6($ctx)
-+	lfd	$h3lo,8*7($ctx)
-+
-+	fsub	$h0lo,$h0lo,$two0		# r0
-+	fsub	$h1lo,$h1lo,$two32		# r1
-+	fsub	$h2lo,$h2lo,$two64		# r2
-+	fsub	$h3lo,$h3lo,$two96		# r3
-+
-+	lfd	$two0,8*6($len)			# more constants
-+	lfd	$two32,8*7($len)
-+	lfd	$two64,8*8($len)
-+	lfd	$two96,8*9($len)
-+
-+	fmul	$h1hi,$h1lo,$five_two130	# s1
-+	fmul	$h2hi,$h2lo,$five_two130	# s2
-+	 stfd	$h3hi,8*15($ctx)		# borrow slot for original fpscr
-+	fmul	$h3hi,$h3lo,$five_two130	# s3
-+
-+	fadd	$h0hi,$h0lo,$two0
-+	 stfd	$h1hi,8*12($ctx)		# put aside for now
-+	fadd	$h1hi,$h1lo,$two32
-+	 stfd	$h2hi,8*13($ctx)
-+	fadd	$h2hi,$h2lo,$two64
-+	 stfd	$h3hi,8*14($ctx)
-+	fadd	$h3hi,$h3lo,$two96
-+
-+	fsub	$h0hi,$h0hi,$two0
-+	fsub	$h1hi,$h1hi,$two32
-+	fsub	$h2hi,$h2hi,$two64
-+	fsub	$h3hi,$h3hi,$two96
-+
-+	lfd	$two0,8*10($len)		# more constants
-+	lfd	$two32,8*11($len)
-+	lfd	$two64,8*12($len)
-+
-+	fsub	$h0lo,$h0lo,$h0hi
-+	fsub	$h1lo,$h1lo,$h1hi
-+	fsub	$h2lo,$h2lo,$h2hi
-+	fsub	$h3lo,$h3lo,$h3hi
-+
-+	stfd	$h0hi,8*5($ctx)			# r0hi
-+	stfd	$h1hi,8*7($ctx)			# r1hi
-+	stfd	$h2hi,8*9($ctx)			# r2hi
-+	stfd	$h3hi,8*11($ctx)		# r3hi
-+
-+	stfd	$h0lo,8*4($ctx)			# r0lo
-+	stfd	$h1lo,8*6($ctx)			# r1lo
-+	stfd	$h2lo,8*8($ctx)			# r2lo
-+	stfd	$h3lo,8*10($ctx)		# r3lo
-+
-+	lfd	$h1lo,8*12($ctx)		# s1
-+	lfd	$h2lo,8*13($ctx)		# s2
-+	lfd	$h3lo,8*14($ctx)		# s3
-+	lfd	$h0lo,8*15($ctx)		# pull original fpscr
-+
-+	fadd	$h1hi,$h1lo,$two0
-+	fadd	$h2hi,$h2lo,$two32
-+	fadd	$h3hi,$h3lo,$two64
-+
-+	fsub	$h1hi,$h1hi,$two0
-+	fsub	$h2hi,$h2hi,$two32
-+	fsub	$h3hi,$h3hi,$two64
-+
-+	fsub	$h1lo,$h1lo,$h1hi
-+	fsub	$h2lo,$h2lo,$h2hi
-+	fsub	$h3lo,$h3lo,$h3hi
-+
-+	stfd	$h1hi,8*13($ctx)		# s1hi
-+	stfd	$h2hi,8*15($ctx)		# s2hi
-+	stfd	$h3hi,8*17($ctx)		# s3hi
-+
-+	stfd	$h1lo,8*12($ctx)		# s1lo
-+	stfd	$h2lo,8*14($ctx)		# s2lo
-+	stfd	$h3lo,8*16($ctx)		# s3lo
-+
-+	mtfsf	255,$h0lo			# restore fpscr
-+Lno_key:
-+	xor	r3,r3,r3
-+	addi	$sp,$sp,$LOCALS
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,0,2,0
-+.size	.poly1305_init_fpu,.-.poly1305_init_fpu
-+
-+.globl	.poly1305_blocks_fpu
-+.align	4
-+.poly1305_blocks_fpu:
-+	srwi.	$len,$len,4
-+	beq-	Labort
-+
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+	stfd	f14,`$FRAME-8*18`($sp)
-+	stfd	f15,`$FRAME-8*17`($sp)
-+	stfd	f16,`$FRAME-8*16`($sp)
-+	stfd	f17,`$FRAME-8*15`($sp)
-+	stfd	f18,`$FRAME-8*14`($sp)
-+	stfd	f19,`$FRAME-8*13`($sp)
-+	stfd	f20,`$FRAME-8*12`($sp)
-+	stfd	f21,`$FRAME-8*11`($sp)
-+	stfd	f22,`$FRAME-8*10`($sp)
-+	stfd	f23,`$FRAME-8*9`($sp)
-+	stfd	f24,`$FRAME-8*8`($sp)
-+	stfd	f25,`$FRAME-8*7`($sp)
-+	stfd	f26,`$FRAME-8*6`($sp)
-+	stfd	f27,`$FRAME-8*5`($sp)
-+	stfd	f28,`$FRAME-8*4`($sp)
-+	stfd	f29,`$FRAME-8*3`($sp)
-+	stfd	f30,`$FRAME-8*2`($sp)
-+	stfd	f31,`$FRAME-8*1`($sp)
-+	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
-+
-+	xor	r0,r0,r0
-+	li	$in3,1
-+	mtctr	$len
-+	neg	$len,$len
-+	stw	r0,`$LOCALS+8*4+(0^$LITTLE_ENDIAN)`($sp)
-+	stw	$in3,`$LOCALS+8*4+(4^$LITTLE_ENDIAN)`($sp)
-+
-+	lfd	$two0,8*18($ctx)		# load constants
-+	lfd	$two32,8*19($ctx)
-+	lfd	$two64,8*20($ctx)
-+	lfd	$two96,8*21($ctx)
-+	lfd	$two130,8*22($ctx)
-+	lfd	$five_two130,8*23($ctx)
-+
-+	lfd	$h0lo,8*0($ctx)			# load [biased] hash value
-+	lfd	$h1lo,8*1($ctx)
-+	lfd	$h2lo,8*2($ctx)
-+	lfd	$h3lo,8*3($ctx)
-+
-+	stfd	$two0,`$LOCALS+8*0`($sp)	# input "template"
-+	oris	$in3,$padbit,`(1023+52+96)<<4`
-+	stfd	$two32,`$LOCALS+8*1`($sp)
-+	stfd	$two64,`$LOCALS+8*2`($sp)
-+	stw	$in3,`$LOCALS+8*3+(0^$LITTLE_ENDIAN)`($sp)
-+
-+	li	$i1,4
-+	li	$i2,8
-+	li	$i3,12
-+	$LWXLE	$in0,0,$inp			# load input
-+	$LWXLE	$in1,$i1,$inp
-+	$LWXLE	$in2,$i2,$inp
-+	$LWXLE	$in3,$i3,$inp
-+	addi	$inp,$inp,16
-+
-+	stw	$in0,`$LOCALS+8*0+(4^$LITTLE_ENDIAN)`($sp)	# fill "template"
-+	stw	$in1,`$LOCALS+8*1+(4^$LITTLE_ENDIAN)`($sp)
-+	stw	$in2,`$LOCALS+8*2+(4^$LITTLE_ENDIAN)`($sp)
-+	stw	$in3,`$LOCALS+8*3+(4^$LITTLE_ENDIAN)`($sp)
-+
-+	mffs	$x0				# original fpscr
-+	lfd	$x1,`$LOCALS+8*4`($sp)		# new fpscr
-+	lfd	$r0lo,8*4($ctx)			# load key
-+	lfd	$r0hi,8*5($ctx)
-+	lfd	$r1lo,8*6($ctx)
-+	lfd	$r1hi,8*7($ctx)
-+	lfd	$r2lo,8*8($ctx)
-+	lfd	$r2hi,8*9($ctx)
-+	lfd	$r3lo,8*10($ctx)
-+	lfd	$r3hi,8*11($ctx)
-+	lfd	$s1lo,8*12($ctx)
-+	lfd	$s1hi,8*13($ctx)
-+	lfd	$s2lo,8*14($ctx)
-+	lfd	$s2hi,8*15($ctx)
-+	lfd	$s3lo,8*16($ctx)
-+	lfd	$s3hi,8*17($ctx)
-+
-+	stfd	$x0,`$LOCALS+8*4`($sp)		# save original fpscr
-+	mtfsf	255,$x1
-+
-+	addic	$len,$len,1
-+	addze	r0,r0
-+	slwi.	r0,r0,4
-+	sub	$inp,$inp,r0			# conditional rewind
-+
-+	lfd	$x0,`$LOCALS+8*0`($sp)
-+	lfd	$x1,`$LOCALS+8*1`($sp)
-+	lfd	$x2,`$LOCALS+8*2`($sp)
-+	lfd	$x3,`$LOCALS+8*3`($sp)
-+
-+	fsub	$h0lo,$h0lo,$two0		# de-bias hash value
-+	 $LWXLE	$in0,0,$inp			# modulo-scheduled input load
-+	fsub	$h1lo,$h1lo,$two32
-+	 $LWXLE	$in1,$i1,$inp
-+	fsub	$h2lo,$h2lo,$two64
-+	 $LWXLE	$in2,$i2,$inp
-+	fsub	$h3lo,$h3lo,$two96
-+	 $LWXLE	$in3,$i3,$inp
-+
-+	fsub	$x0,$x0,$two0			# de-bias input
-+	 addi	$inp,$inp,16
-+	fsub	$x1,$x1,$two32
-+	fsub	$x2,$x2,$two64
-+	fsub	$x3,$x3,$two96
-+
-+	fadd	$x0,$x0,$h0lo			# accumulate input
-+	 stw	$in0,`$LOCALS+8*0+(4^$LITTLE_ENDIAN)`($sp)
-+	fadd	$x1,$x1,$h1lo
-+	 stw	$in1,`$LOCALS+8*1+(4^$LITTLE_ENDIAN)`($sp)
-+	fadd	$x2,$x2,$h2lo
-+	 stw	$in2,`$LOCALS+8*2+(4^$LITTLE_ENDIAN)`($sp)
-+	fadd	$x3,$x3,$h3lo
-+	 stw	$in3,`$LOCALS+8*3+(4^$LITTLE_ENDIAN)`($sp)
-+
-+	b	Lentry
-+
-+.align	4
-+Loop:
-+	fsub	$y0,$y0,$two0			# de-bias input
-+	 addic	$len,$len,1
-+	fsub	$y1,$y1,$two32
-+	 addze	r0,r0
-+	fsub	$y2,$y2,$two64
-+	 slwi.	r0,r0,4
-+	fsub	$y3,$y3,$two96
-+	 sub	$inp,$inp,r0			# conditional rewind
-+
-+	fadd	$h0lo,$h0lo,$y0			# accumulate input
-+	fadd	$h0hi,$h0hi,$y1
-+	fadd	$h2lo,$h2lo,$y2
-+	fadd	$h2hi,$h2hi,$y3
-+
-+	######################################### base 2^48 -> base 2^32
-+	fadd	$c1lo,$h1lo,$two64
-+	 $LWXLE	$in0,0,$inp			# modulo-scheduled input load
-+	fadd	$c1hi,$h1hi,$two64
-+	 $LWXLE	$in1,$i1,$inp
-+	fadd	$c3lo,$h3lo,$two130
-+	 $LWXLE	$in2,$i2,$inp
-+	fadd	$c3hi,$h3hi,$two130
-+	 $LWXLE	$in3,$i3,$inp
-+	fadd	$c0lo,$h0lo,$two32
-+	 addi	$inp,$inp,16
-+	fadd	$c0hi,$h0hi,$two32
-+	fadd	$c2lo,$h2lo,$two96
-+	fadd	$c2hi,$h2hi,$two96
-+
-+	fsub	$c1lo,$c1lo,$two64
-+	 stw	$in0,`$LOCALS+8*0+(4^$LITTLE_ENDIAN)`($sp)	# fill "template"
-+	fsub	$c1hi,$c1hi,$two64
-+	 stw	$in1,`$LOCALS+8*1+(4^$LITTLE_ENDIAN)`($sp)
-+	fsub	$c3lo,$c3lo,$two130
-+	 stw	$in2,`$LOCALS+8*2+(4^$LITTLE_ENDIAN)`($sp)
-+	fsub	$c3hi,$c3hi,$two130
-+	 stw	$in3,`$LOCALS+8*3+(4^$LITTLE_ENDIAN)`($sp)
-+	fsub	$c0lo,$c0lo,$two32
-+	fsub	$c0hi,$c0hi,$two32
-+	fsub	$c2lo,$c2lo,$two96
-+	fsub	$c2hi,$c2hi,$two96
-+
-+	fsub	$h1lo,$h1lo,$c1lo
-+	fsub	$h1hi,$h1hi,$c1hi
-+	fsub	$h3lo,$h3lo,$c3lo
-+	fsub	$h3hi,$h3hi,$c3hi
-+	fsub	$h2lo,$h2lo,$c2lo
-+	fsub	$h2hi,$h2hi,$c2hi
-+	fsub	$h0lo,$h0lo,$c0lo
-+	fsub	$h0hi,$h0hi,$c0hi
-+
-+	fadd	$h1lo,$h1lo,$c0lo
-+	fadd	$h1hi,$h1hi,$c0hi
-+	fadd	$h3lo,$h3lo,$c2lo
-+	fadd	$h3hi,$h3hi,$c2hi
-+	fadd	$h2lo,$h2lo,$c1lo
-+	fadd	$h2hi,$h2hi,$c1hi
-+	fmadd	$h0lo,$c3lo,$five_two130,$h0lo
-+	fmadd	$h0hi,$c3hi,$five_two130,$h0hi
-+
-+	fadd	$x1,$h1lo,$h1hi
-+	 lfd	$s1lo,8*12($ctx)		# reload constants
-+	fadd	$x3,$h3lo,$h3hi
-+	 lfd	$s1hi,8*13($ctx)
-+	fadd	$x2,$h2lo,$h2hi
-+	 lfd	$r3lo,8*10($ctx)
-+	fadd	$x0,$h0lo,$h0hi
-+	 lfd	$r3hi,8*11($ctx)
-+Lentry:
-+	fmul	$h0lo,$s3lo,$x1
-+	fmul	$h0hi,$s3hi,$x1
-+	fmul	$h2lo,$r1lo,$x1
-+	fmul	$h2hi,$r1hi,$x1
-+	fmul	$h1lo,$r0lo,$x1
-+	fmul	$h1hi,$r0hi,$x1
-+	fmul	$h3lo,$r2lo,$x1
-+	fmul	$h3hi,$r2hi,$x1
-+
-+	fmadd	$h0lo,$s1lo,$x3,$h0lo
-+	fmadd	$h0hi,$s1hi,$x3,$h0hi
-+	fmadd	$h2lo,$s3lo,$x3,$h2lo
-+	fmadd	$h2hi,$s3hi,$x3,$h2hi
-+	fmadd	$h1lo,$s2lo,$x3,$h1lo
-+	fmadd	$h1hi,$s2hi,$x3,$h1hi
-+	fmadd	$h3lo,$r0lo,$x3,$h3lo
-+	fmadd	$h3hi,$r0hi,$x3,$h3hi
-+
-+	fmadd	$h0lo,$s2lo,$x2,$h0lo
-+	fmadd	$h0hi,$s2hi,$x2,$h0hi
-+	fmadd	$h2lo,$r0lo,$x2,$h2lo
-+	fmadd	$h2hi,$r0hi,$x2,$h2hi
-+	fmadd	$h1lo,$s3lo,$x2,$h1lo
-+	fmadd	$h1hi,$s3hi,$x2,$h1hi
-+	fmadd	$h3lo,$r1lo,$x2,$h3lo
-+	fmadd	$h3hi,$r1hi,$x2,$h3hi
-+
-+	fmadd	$h0lo,$r0lo,$x0,$h0lo
-+	 lfd	$y0,`$LOCALS+8*0`($sp)		# load [biased] input
-+	fmadd	$h0hi,$r0hi,$x0,$h0hi
-+	 lfd	$y1,`$LOCALS+8*1`($sp)
-+	fmadd	$h2lo,$r2lo,$x0,$h2lo
-+	 lfd	$y2,`$LOCALS+8*2`($sp)
-+	fmadd	$h2hi,$r2hi,$x0,$h2hi
-+	 lfd	$y3,`$LOCALS+8*3`($sp)
-+	fmadd	$h1lo,$r1lo,$x0,$h1lo
-+	fmadd	$h1hi,$r1hi,$x0,$h1hi
-+	fmadd	$h3lo,$r3lo,$x0,$h3lo
-+	fmadd	$h3hi,$r3hi,$x0,$h3hi
-+
-+	bdnz	Loop
-+
-+	######################################### base 2^48 -> base 2^32
-+	fadd	$c0lo,$h0lo,$two32
-+	fadd	$c0hi,$h0hi,$two32
-+	fadd	$c2lo,$h2lo,$two96
-+	fadd	$c2hi,$h2hi,$two96
-+	fadd	$c1lo,$h1lo,$two64
-+	fadd	$c1hi,$h1hi,$two64
-+	fadd	$c3lo,$h3lo,$two130
-+	fadd	$c3hi,$h3hi,$two130
-+
-+	fsub	$c0lo,$c0lo,$two32
-+	fsub	$c0hi,$c0hi,$two32
-+	fsub	$c2lo,$c2lo,$two96
-+	fsub	$c2hi,$c2hi,$two96
-+	fsub	$c1lo,$c1lo,$two64
-+	fsub	$c1hi,$c1hi,$two64
-+	fsub	$c3lo,$c3lo,$two130
-+	fsub	$c3hi,$c3hi,$two130
-+
-+	fsub	$h1lo,$h1lo,$c1lo
-+	fsub	$h1hi,$h1hi,$c1hi
-+	fsub	$h3lo,$h3lo,$c3lo
-+	fsub	$h3hi,$h3hi,$c3hi
-+	fsub	$h2lo,$h2lo,$c2lo
-+	fsub	$h2hi,$h2hi,$c2hi
-+	fsub	$h0lo,$h0lo,$c0lo
-+	fsub	$h0hi,$h0hi,$c0hi
-+
-+	fadd	$h1lo,$h1lo,$c0lo
-+	fadd	$h1hi,$h1hi,$c0hi
-+	fadd	$h3lo,$h3lo,$c2lo
-+	fadd	$h3hi,$h3hi,$c2hi
-+	fadd	$h2lo,$h2lo,$c1lo
-+	fadd	$h2hi,$h2hi,$c1hi
-+	fmadd	$h0lo,$c3lo,$five_two130,$h0lo
-+	fmadd	$h0hi,$c3hi,$five_two130,$h0hi
-+
-+	fadd	$x1,$h1lo,$h1hi
-+	fadd	$x3,$h3lo,$h3hi
-+	fadd	$x2,$h2lo,$h2hi
-+	fadd	$x0,$h0lo,$h0hi
-+
-+	lfd	$h0lo,`$LOCALS+8*4`($sp)	# pull saved fpscr
-+	fadd	$x1,$x1,$two32			# bias
-+	fadd	$x3,$x3,$two96
-+	fadd	$x2,$x2,$two64
-+	fadd	$x0,$x0,$two0
-+
-+	stfd	$x1,8*1($ctx)			# store [biased] hash value
-+	stfd	$x3,8*3($ctx)
-+	stfd	$x2,8*2($ctx)
-+	stfd	$x0,8*0($ctx)
-+
-+	mtfsf	255,$h0lo			# restore original fpscr
-+	lfd	f14,`$FRAME-8*18`($sp)
-+	lfd	f15,`$FRAME-8*17`($sp)
-+	lfd	f16,`$FRAME-8*16`($sp)
-+	lfd	f17,`$FRAME-8*15`($sp)
-+	lfd	f18,`$FRAME-8*14`($sp)
-+	lfd	f19,`$FRAME-8*13`($sp)
-+	lfd	f20,`$FRAME-8*12`($sp)
-+	lfd	f21,`$FRAME-8*11`($sp)
-+	lfd	f22,`$FRAME-8*10`($sp)
-+	lfd	f23,`$FRAME-8*9`($sp)
-+	lfd	f24,`$FRAME-8*8`($sp)
-+	lfd	f25,`$FRAME-8*7`($sp)
-+	lfd	f26,`$FRAME-8*6`($sp)
-+	lfd	f27,`$FRAME-8*5`($sp)
-+	lfd	f28,`$FRAME-8*4`($sp)
-+	lfd	f29,`$FRAME-8*3`($sp)
-+	lfd	f30,`$FRAME-8*2`($sp)
-+	lfd	f31,`$FRAME-8*1`($sp)
-+	addi	$sp,$sp,$FRAME
-+Labort:
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,0,4,0
-+.size	.poly1305_blocks_fpu,.-.poly1305_blocks_fpu
-+___
-+{
-+my ($mac,$nonce)=($inp,$len);
-+
-+my ($h0,$h1,$h2,$h3,$h4, $d0,$d1,$d2,$d3
-+   ) = map("r$_",(7..11,28..31));
-+my $mask = "r0";
-+my $FRAME = (6+4)*$SIZE_T;
-+
-+$code.=<<___;
-+.globl	.poly1305_emit_fpu
-+.align	4
-+.poly1305_emit_fpu:
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
-+	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
-+
-+	lwz	$d0,`8*0+(0^$LITTLE_ENDIAN)`($ctx)	# load hash
-+	lwz	$h0,`8*0+(4^$LITTLE_ENDIAN)`($ctx)
-+	lwz	$d1,`8*1+(0^$LITTLE_ENDIAN)`($ctx)
-+	lwz	$h1,`8*1+(4^$LITTLE_ENDIAN)`($ctx)
-+	lwz	$d2,`8*2+(0^$LITTLE_ENDIAN)`($ctx)
-+	lwz	$h2,`8*2+(4^$LITTLE_ENDIAN)`($ctx)
-+	lwz	$d3,`8*3+(0^$LITTLE_ENDIAN)`($ctx)
-+	lwz	$h3,`8*3+(4^$LITTLE_ENDIAN)`($ctx)
-+
-+	lis	$mask,0xfff0
-+	andc	$d0,$d0,$mask			# mask exponent
-+	andc	$d1,$d1,$mask
-+	andc	$d2,$d2,$mask
-+	andc	$d3,$d3,$mask			# can be partially reduced...
-+	li	$mask,3
-+
-+	srwi	$padbit,$d3,2			# ... so reduce
-+	and	$h4,$d3,$mask
-+	andc	$d3,$d3,$mask
-+	add	$d3,$d3,$padbit
-+___
-+						if ($SIZE_T==4) {
-+$code.=<<___;
-+	addc	$h0,$h0,$d3
-+	adde	$h1,$h1,$d0
-+	adde	$h2,$h2,$d1
-+	adde	$h3,$h3,$d2
-+	addze	$h4,$h4
-+
-+	addic	$d0,$h0,5			# compare to modulus
-+	addze	$d1,$h1
-+	addze	$d2,$h2
-+	addze	$d3,$h3
-+	addze	$mask,$h4
-+
-+	srwi	$mask,$mask,2			# did it carry/borrow?
-+	neg	$mask,$mask
-+	srawi	$mask,$mask,31			# mask
-+
-+	andc	$h0,$h0,$mask
-+	and	$d0,$d0,$mask
-+	andc	$h1,$h1,$mask
-+	and	$d1,$d1,$mask
-+	or	$h0,$h0,$d0
-+	lwz	$d0,0($nonce)			# load nonce
-+	andc	$h2,$h2,$mask
-+	and	$d2,$d2,$mask
-+	or	$h1,$h1,$d1
-+	lwz	$d1,4($nonce)
-+	andc	$h3,$h3,$mask
-+	and	$d3,$d3,$mask
-+	or	$h2,$h2,$d2
-+	lwz	$d2,8($nonce)
-+	or	$h3,$h3,$d3
-+	lwz	$d3,12($nonce)
-+
-+	addc	$h0,$h0,$d0			# accumulate nonce
-+	adde	$h1,$h1,$d1
-+	adde	$h2,$h2,$d2
-+	adde	$h3,$h3,$d3
-+___
-+						} else {
-+$code.=<<___;
-+	add	$h0,$h0,$d3
-+	add	$h1,$h1,$d0
-+	add	$h2,$h2,$d1
-+	add	$h3,$h3,$d2
-+
-+	srdi	$d0,$h0,32
-+	add	$h1,$h1,$d0
-+	srdi	$d1,$h1,32
-+	add	$h2,$h2,$d1
-+	srdi	$d2,$h2,32
-+	add	$h3,$h3,$d2
-+	srdi	$d3,$h3,32
-+	add	$h4,$h4,$d3
-+
-+	insrdi	$h0,$h1,32,0
-+	insrdi	$h2,$h3,32,0
-+
-+	addic	$d0,$h0,5			# compare to modulus
-+	addze	$d1,$h2
-+	addze	$d2,$h4
-+
-+	srdi	$mask,$d2,2			# did it carry/borrow?
-+	neg	$mask,$mask
-+	sradi	$mask,$mask,63			# mask
-+	ld	$d2,0($nonce)			# load nonce
-+	ld	$d3,8($nonce)
-+
-+	andc	$h0,$h0,$mask
-+	and	$d0,$d0,$mask
-+	andc	$h2,$h2,$mask
-+	and	$d1,$d1,$mask
-+	or	$h0,$h0,$d0
-+	or	$h2,$h2,$d1
-+___
-+$code.=<<___	if (!$LITTLE_ENDIAN);
-+	rotldi	$d2,$d2,32			# flip nonce words
-+	rotldi	$d3,$d3,32
-+___
-+$code.=<<___;
-+	addc	$h0,$h0,$d2			# accumulate nonce
-+	adde	$h2,$h2,$d3
-+
-+	srdi	$h1,$h0,32
-+	srdi	$h3,$h2,32
-+___
-+						}
-+$code.=<<___	if ($LITTLE_ENDIAN);
-+	stw	$h0,0($mac)			# write result
-+	stw	$h1,4($mac)
-+	stw	$h2,8($mac)
-+	stw	$h3,12($mac)
-+___
-+$code.=<<___	if (!$LITTLE_ENDIAN);
-+	li	$d1,4
-+	stwbrx	$h0,0,$mac			# write result
-+	li	$d2,8
-+	stwbrx	$h1,$d1,$mac
-+	li	$d3,12
-+	stwbrx	$h2,$d2,$mac
-+	stwbrx	$h3,$d3,$mac
-+___
-+$code.=<<___;
-+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,4,3,0
-+.size	.poly1305_emit_fpu,.-.poly1305_emit_fpu
-+___
-+}
-+# Ugly hack here, because PPC assembler syntax seem to vary too
-+# much from platforms to platform...
-+$code.=<<___;
-+.align	6
-+LPICmeup:
-+	mflr	r0
-+	bcl	20,31,\$+4
-+	mflr	$len	# vvvvvv "distance" between . and 1st data entry
-+	addi	$len,$len,`64-8`	# borrow $len
-+	mtlr	r0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+	.space	`64-9*4`
-+
-+.quad	0x4330000000000000		# 2^(52+0)
-+.quad	0x4530000000000000		# 2^(52+32)
-+.quad	0x4730000000000000		# 2^(52+64)
-+.quad	0x4930000000000000		# 2^(52+96)
-+.quad	0x4b50000000000000		# 2^(52+130)
-+
-+.quad	0x37f4000000000000		# 5/2^130
-+
-+.quad	0x4430000000000000		# 2^(52+16+0)
-+.quad	0x4630000000000000		# 2^(52+16+32)
-+.quad	0x4830000000000000		# 2^(52+16+64)
-+.quad	0x4a30000000000000		# 2^(52+16+96)
-+.quad	0x3e30000000000000		# 2^(52+16+0-96)
-+.quad	0x4030000000000000		# 2^(52+16+32-96)
-+.quad	0x4230000000000000		# 2^(52+16+64-96)
-+
-+.quad	0x0000000000000001		# fpscr: truncate, no exceptions
-+.asciz	"Poly1305 for PPC FPU, CRYPTOGAMS by "
-+.align	4
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-s390x.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-s390x.pl
-new file mode 100755
-index 0000000..82d757d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-s390x.pl
-@@ -0,0 +1,227 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements Poly1305 hash for s390x.
-+#
-+# June 2015
-+#
-+# ~6.6/2.3 cpb on z10/z196+, >2x improvement over compiler-generated
-+# code. For older compiler improvement coefficient is >3x, because
-+# then base 2^64 and base 2^32 implementations are compared.
-+#
-+# On side note, z13 enables vector base 2^26 implementation...
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /3[12]/) {
-+	$SIZE_T=4;
-+	$g="";
-+} else {
-+	$SIZE_T=8;
-+	$g="g";
-+}
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+$sp="%r15";
-+
-+my ($ctx,$inp,$len,$padbit) = map("%r$_",(2..5));
-+
-+$code.=<<___;
-+.text
-+
-+.globl	poly1305_init
-+.type	poly1305_init,\@function
-+.align	16
-+poly1305_init:
-+	lghi	%r0,0
-+	lghi	%r1,-1
-+	stg	%r0,0($ctx)		# zero hash value
-+	stg	%r0,8($ctx)
-+	stg	%r0,16($ctx)
-+
-+	cl${g}r	$inp,%r0
-+	je	.Lno_key
-+
-+	lrvg	%r4,0($inp)		# load little-endian key
-+	lrvg	%r5,8($inp)
-+
-+	nihl	%r1,0xffc0		# 0xffffffc0ffffffff
-+	srlg	%r0,%r1,4		# 0x0ffffffc0fffffff
-+	srlg	%r1,%r1,4
-+	nill	%r1,0xfffc		# 0x0ffffffc0ffffffc
-+
-+	ngr	%r4,%r0
-+	ngr	%r5,%r1
-+
-+	stg	%r4,32($ctx)
-+	stg	%r5,40($ctx)
-+
-+.Lno_key:
-+	lghi	%r2,0
-+	br	%r14
-+.size	poly1305_init,.-poly1305_init
-+___
-+{
-+my ($d0hi,$d0lo,$d1hi,$d1lo,$t0,$h0,$t1,$h1,$h2) = map("%r$_",(6..14));
-+my ($r0,$r1,$s1) = map("%r$_",(0..2));
-+
-+$code.=<<___;
-+.globl	poly1305_blocks
-+.type	poly1305_blocks,\@function
-+.align	16
-+poly1305_blocks:
-+	srl${g}	$len,4			# fixed-up in 64-bit build
-+	lghi	%r0,0
-+	cl${g}r	$len,%r0
-+	je	.Lno_data
-+
-+	stm${g}	%r6,%r14,`6*$SIZE_T`($sp)
-+
-+	llgfr   $padbit,$padbit		# clear upper half, much needed with
-+					# non-64-bit ABI
-+	lg	$r0,32($ctx)		# load key
-+	lg	$r1,40($ctx)
-+
-+	lg	$h0,0($ctx)		# load hash value
-+	lg	$h1,8($ctx)
-+	lg	$h2,16($ctx)
-+
-+	st$g	$ctx,`2*$SIZE_T`($sp)	# off-load $ctx
-+	srlg	$s1,$r1,2
-+	algr	$s1,$r1			# s1 = r1 + r1>>2
-+	j	.Loop
-+
-+.align	16
-+.Loop:
-+	lrvg	$d0lo,0($inp)		# load little-endian input
-+	lrvg	$d1lo,8($inp)
-+	la	$inp,16($inp)
-+
-+	algr	$d0lo,$h0		# accumulate input
-+	alcgr	$d1lo,$h1
-+
-+	lgr	$h0,$d0lo
-+	mlgr	$d0hi,$r0		# h0*r0	  -> $d0hi:$d0lo
-+	lgr	$h1,$d1lo
-+	mlgr	$d1hi,$s1		# h1*5*r1 -> $d1hi:$d1lo
-+
-+	mlgr	$t0,$r1			# h0*r1   -> $t0:$h0
-+	mlgr	$t1,$r0			# h1*r0   -> $t1:$h1
-+	alcgr	$h2,$padbit
-+
-+	algr	$d0lo,$d1lo
-+	lgr	$d1lo,$h2
-+	alcgr	$d0hi,$d1hi
-+	lghi	$d1hi,0
-+
-+	algr	$h1,$h0
-+	alcgr	$t1,$t0
-+
-+	msgr	$d1lo,$s1		# h2*s1
-+	msgr	$h2,$r0			# h2*r0
-+
-+	algr	$h1,$d1lo
-+	alcgr	$t1,$d1hi		# $d1hi is zero
-+
-+	algr	$h1,$d0hi
-+	alcgr	$h2,$t1
-+
-+	lghi	$h0,-4			# final reduction step
-+	ngr	$h0,$h2
-+	srlg	$t0,$h2,2
-+	algr	$h0,$t0
-+	lghi	$t1,3
-+	ngr	$h2,$t1
-+
-+	algr	$h0,$d0lo
-+	alcgr	$h1,$d1hi		# $d1hi is still zero
-+	alcgr	$h2,$d1hi		# $d1hi is still zero
-+
-+	brct$g	$len,.Loop
-+
-+	l$g	$ctx,`2*$SIZE_T`($sp)	# restore $ctx
-+
-+	stg	$h0,0($ctx)		# store hash value
-+	stg	$h1,8($ctx)
-+	stg	$h2,16($ctx)
-+
-+	lm${g}	%r6,%r14,`6*$SIZE_T`($sp)
-+.Lno_data:
-+	br	%r14
-+.size	poly1305_blocks,.-poly1305_blocks
-+___
-+}
-+{
-+my ($mac,$nonce)=($inp,$len);
-+my ($h0,$h1,$h2,$d0,$d1)=map("%r$_",(5..9));
-+
-+$code.=<<___;
-+.globl	poly1305_emit
-+.type	poly1305_emit,\@function
-+.align	16
-+poly1305_emit:
-+	stm${g}	%r6,%r9,`6*$SIZE_T`($sp)
-+
-+	lg	$h0,0($ctx)
-+	lg	$h1,8($ctx)
-+	lg	$h2,16($ctx)
-+
-+	lghi	%r0,5
-+	lghi	%r1,0
-+	lgr	$d0,$h0
-+	lgr	$d1,$h1
-+
-+	algr	$h0,%r0			# compare to modulus
-+	alcgr	$h1,%r1
-+	alcgr	$h2,%r1
-+
-+	srlg	$h2,$h2,2		# did it borrow/carry?
-+	slgr	%r1,$h2			# 0-$h2>>2
-+	lg	$h2,0($nonce)		# load nonce
-+	lghi	%r0,-1
-+	lg	$ctx,8($nonce)
-+	xgr	%r0,%r1			# ~%r1
-+
-+	ngr	$h0,%r1
-+	ngr	$d0,%r0
-+	ngr	$h1,%r1
-+	ngr	$d1,%r0
-+	ogr	$h0,$d0
-+	rllg	$d0,$h2,32		# flip nonce words
-+	ogr	$h1,$d1
-+	rllg	$d1,$ctx,32
-+
-+	algr	$h0,$d0			# accumulate nonce
-+	alcgr	$h1,$d1
-+
-+	strvg	$h0,0($mac)		# write little-endian result
-+	strvg	$h1,8($mac)
-+
-+	lm${g}	%r6,%r9,`6*$SIZE_T`($sp)
-+	br	%r14
-+.size	poly1305_emit,.-poly1305_emit
-+
-+.string	"Poly1305 for s390x, CRYPTOGAMS by "
-+___
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+$code =~ s/\b(srlg\s+)(%r[0-9]+\s*,)\s*([0-9]+)/$1$2$2$3/gm;
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-sparcv9.pl
-new file mode 100755
-index 0000000..0bdd048
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-sparcv9.pl
-@@ -0,0 +1,1120 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements Poly1305 hash for SPARCv9, vanilla, as well
-+# as VIS3 and FMA extensions.
-+#
-+# May, August 2015
-+#
-+# Numbers are cycles per processed byte with poly1305_blocks alone.
-+#
-+#			IALU(*)		FMA
-+#
-+# UltraSPARC III	12.3(**)
-+# SPARC T3		7.92
-+# SPARC T4		1.70(***)	6.55
-+# SPARC64 X		5.60		3.64
-+#
-+# (*)	Comparison to compiler-generated code is really problematic,
-+#	because latter's performance varies too much depending on too
-+#	many variables. For example, one can measure from 5x to 15x
-+#	improvement on T4 for gcc-4.6. Well, in T4 case it's a bit
-+#	unfair comparison, because compiler doesn't use VIS3, but
-+#	given same initial conditions coefficient varies from 3x to 9x.
-+# (**)	Pre-III performance should be even worse; floating-point
-+#	performance for UltraSPARC I-IV on the other hand is reported
-+#	to be 4.25 for hand-coded assembly, but they are just too old
-+#	to care about.
-+# (***)	Multi-process benchmark saturates at ~12.5x single-process
-+#	result on 8-core processor, or ~21GBps per 2.85GHz socket.
-+
-+my $output = pop;
-+open STDOUT,">$output";
-+
-+my ($ctx,$inp,$len,$padbit,$shl,$shr)	= map("%i$_",(0..5));
-+my ($r0,$r1,$r2,$r3,$s1,$s2,$s3,$h4)	= map("%l$_",(0..7));
-+my ($h0,$h1,$h2,$h3, $t0,$t1,$t2)	= map("%o$_",(0..5,7));
-+my ($d0,$d1,$d2,$d3)			= map("%g$_",(1..4));
-+
-+my $output = pop;
-+open STDOUT,">$stdout";
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#ifdef	__arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+# define	STPTR	stx
-+# define	SIZE_T	8
-+#else
-+# define	STPTR	st
-+# define	SIZE_T	4
-+#endif
-+#define	LOCALS	(STACK_BIAS+STACK_FRAME)
-+
-+.section	".text",#alloc,#execinstr
-+
-+#ifdef __PIC__
-+SPARC_PIC_THUNK(%g1)
-+#endif
-+
-+.globl	poly1305_init
-+.align	32
-+poly1305_init:
-+	save	%sp,-STACK_FRAME-16,%sp
-+	nop
-+
-+	SPARC_LOAD_ADDRESS(OPENSSL_sparcv9cap_P,%g1)
-+	ld	[%g1],%g1
-+
-+	and	%g1,SPARCV9_FMADD|SPARCV9_VIS3,%g1
-+	cmp	%g1,SPARCV9_FMADD
-+	be	.Lpoly1305_init_fma
-+	nop
-+
-+	stx	%g0,[$ctx+0]
-+	stx	%g0,[$ctx+8]		! zero hash value
-+	brz,pn	$inp,.Lno_key
-+	stx	%g0,[$ctx+16]
-+
-+	and	$inp,7,$shr		! alignment factor
-+	andn	$inp,7,$inp
-+	sll	$shr,3,$shr		! *8
-+	neg	$shr,$shl
-+
-+	sethi	%hi(0x0ffffffc),$t0
-+	set	8,$h1
-+	or	$t0,%lo(0x0ffffffc),$t0
-+	set	16,$h2
-+	sllx	$t0,32,$t1
-+	or	$t0,$t1,$t1		! 0x0ffffffc0ffffffc
-+	or	$t1,3,$t0		! 0x0ffffffc0fffffff
-+
-+	ldxa	[$inp+%g0]0x88,$h0	! load little-endian key
-+	brz,pt	$shr,.Lkey_aligned
-+	ldxa	[$inp+$h1]0x88,$h1
-+
-+	ldxa	[$inp+$h2]0x88,$h2
-+	srlx	$h0,$shr,$h0
-+	sllx	$h1,$shl,$t2
-+	srlx	$h1,$shr,$h1
-+	or	$t2,$h0,$h0
-+	sllx	$h2,$shl,$h2
-+	or	$h2,$h1,$h1
-+
-+.Lkey_aligned:
-+	and	$t0,$h0,$h0
-+	and	$t1,$h1,$h1
-+	stx	$h0,[$ctx+32+0]		! store key
-+	stx	$h1,[$ctx+32+8]
-+
-+	andcc	%g1,SPARCV9_VIS3,%g0
-+	be	.Lno_key
-+	nop
-+
-+1:	call	.+8
-+	add	%o7,poly1305_blocks_vis3-1b,%o7
-+
-+	add	%o7,poly1305_emit-poly1305_blocks_vis3,%o5
-+	STPTR	%o7,[%i2]
-+	STPTR	%o5,[%i2+SIZE_T]
-+
-+	ret
-+	restore	%g0,1,%o0		! return 1
-+
-+.Lno_key:
-+	ret
-+	restore	%g0,%g0,%o0		! return 0
-+.type	poly1305_init,#function
-+.size	poly1305_init,.-poly1305_init
-+
-+.globl	poly1305_blocks
-+.align	32
-+poly1305_blocks:
-+	save	%sp,-STACK_FRAME,%sp
-+	srln	$len,4,$len
-+
-+	brz,pn	$len,.Lno_data
-+	nop
-+
-+	ld	[$ctx+32+0],$r1		! load key
-+	ld	[$ctx+32+4],$r0
-+	ld	[$ctx+32+8],$r3
-+	ld	[$ctx+32+12],$r2
-+
-+	ld	[$ctx+0],$h1		! load hash value
-+	ld	[$ctx+4],$h0
-+	ld	[$ctx+8],$h3
-+	ld	[$ctx+12],$h2
-+	ld	[$ctx+16],$h4
-+
-+	and	$inp,7,$shr		! alignment factor
-+	andn	$inp,7,$inp
-+	set	8,$d1
-+	sll	$shr,3,$shr		! *8
-+	set	16,$d2
-+	neg	$shr,$shl
-+
-+	srl	$r1,2,$s1
-+	srl	$r2,2,$s2
-+	add	$r1,$s1,$s1
-+	srl	$r3,2,$s3
-+	add	$r2,$s2,$s2
-+	add	$r3,$s3,$s3
-+
-+.Loop:
-+	ldxa	[$inp+%g0]0x88,$d0	! load little-endian input
-+	brz,pt	$shr,.Linp_aligned
-+	ldxa	[$inp+$d1]0x88,$d1
-+
-+	ldxa	[$inp+$d2]0x88,$d2
-+	srlx	$d0,$shr,$d0
-+	sllx	$d1,$shl,$t1
-+	srlx	$d1,$shr,$d1
-+	or	$t1,$d0,$d0
-+	sllx	$d2,$shl,$d2
-+	or	$d2,$d1,$d1
-+
-+.Linp_aligned:
-+	srlx	$d0,32,$t0
-+	addcc	$d0,$h0,$h0		! accumulate input
-+	srlx	$d1,32,$t1
-+	addccc	$t0,$h1,$h1
-+	addccc	$d1,$h2,$h2
-+	addccc	$t1,$h3,$h3
-+	addc	$padbit,$h4,$h4
-+
-+	umul	$r0,$h0,$d0
-+	umul	$r1,$h0,$d1
-+	umul	$r2,$h0,$d2
-+	umul	$r3,$h0,$d3
-+	 sub	$len,1,$len
-+	 add	$inp,16,$inp
-+
-+	umul	$s3,$h1,$t0
-+	umul	$r0,$h1,$t1
-+	umul	$r1,$h1,$t2
-+	add	$t0,$d0,$d0
-+	add	$t1,$d1,$d1
-+	umul	$r2,$h1,$t0
-+	add	$t2,$d2,$d2
-+	add	$t0,$d3,$d3
-+
-+	umul	$s2,$h2,$t1
-+	umul	$s3,$h2,$t2
-+	umul	$r0,$h2,$t0
-+	add	$t1,$d0,$d0
-+	add	$t2,$d1,$d1
-+	umul	$r1,$h2,$t1
-+	add	$t0,$d2,$d2
-+	add	$t1,$d3,$d3
-+
-+	umul	$s1,$h3,$t2
-+	umul	$s2,$h3,$t0
-+	umul	$s3,$h3,$t1
-+	add	$t2,$d0,$d0
-+	add	$t0,$d1,$d1
-+	umul	$r0,$h3,$t2
-+	add	$t1,$d2,$d2
-+	add	$t2,$d3,$d3
-+
-+	umul	$s1,$h4,$t0
-+	umul	$s2,$h4,$t1
-+	umul	$s3,$h4,$t2
-+	umul	$r0,$h4,$h4
-+	add	$t0,$d1,$d1
-+	add	$t1,$d2,$d2
-+	srlx	$d0,32,$h1
-+	add	$t2,$d3,$d3
-+	srlx	$d1,32,$h2
-+
-+	addcc	$d1,$h1,$h1
-+	srlx	$d2,32,$h3
-+	 set	8,$d1
-+	addccc	$d2,$h2,$h2
-+	srlx	$d3,32,$t0
-+	 set	16,$d2
-+	addccc	$d3,$h3,$h3
-+	addc	$t0,$h4,$h4
-+
-+	srl	$h4,2,$t0		! final reduction step
-+	andn	$h4,3,$t1
-+	and	$h4,3,$h4
-+	add	$t1,$t0,$t0
-+
-+	addcc	$t0,$d0,$h0
-+	addccc	%g0,$h1,$h1
-+	addccc	%g0,$h2,$h2
-+	addccc	%g0,$h3,$h3
-+	brnz,pt	$len,.Loop
-+	addc	%g0,$h4,$h4
-+
-+	st	$h1,[$ctx+0]		! store hash value
-+	st	$h0,[$ctx+4]
-+	st	$h3,[$ctx+8]
-+	st	$h2,[$ctx+12]
-+	st	$h4,[$ctx+16]
-+
-+.Lno_data:
-+	ret
-+	restore
-+.type	poly1305_blocks,#function
-+.size	poly1305_blocks,.-poly1305_blocks
-+___
-+########################################################################
-+# VIS3 has umulxhi and addxc...
-+{
-+my ($H0,$H1,$H2,$R0,$R1,$S1,$T1) = map("%o$_",(0..5,7));
-+my ($D0,$D1,$D2,$T0) = map("%g$_",(1..4));
-+
-+$code.=<<___;
-+.align	32
-+poly1305_blocks_vis3:
-+	save	%sp,-STACK_FRAME,%sp
-+	srln	$len,4,$len
-+
-+	brz,pn	$len,.Lno_data
-+	nop
-+
-+	ldx	[$ctx+32+0],$R0		! load key
-+	ldx	[$ctx+32+8],$R1
-+
-+	ldx	[$ctx+0],$H0		! load hash value
-+	ldx	[$ctx+8],$H1
-+	ld	[$ctx+16],$H2
-+
-+	and	$inp,7,$shr		! alignment factor
-+	andn	$inp,7,$inp
-+	set	8,$r1
-+	sll	$shr,3,$shr		! *8
-+	set	16,$r2
-+	neg	$shr,$shl
-+
-+	srlx	$R1,2,$S1
-+	b	.Loop_vis3
-+	add	$R1,$S1,$S1
-+
-+.Loop_vis3:
-+	ldxa	[$inp+%g0]0x88,$D0	! load little-endian input
-+	brz,pt	$shr,.Linp_aligned_vis3
-+	ldxa	[$inp+$r1]0x88,$D1
-+
-+	ldxa	[$inp+$r2]0x88,$D2
-+	srlx	$D0,$shr,$D0
-+	sllx	$D1,$shl,$T1
-+	srlx	$D1,$shr,$D1
-+	or	$T1,$D0,$D0
-+	sllx	$D2,$shl,$D2
-+	or	$D2,$D1,$D1
-+
-+.Linp_aligned_vis3:
-+	addcc	$D0,$H0,$H0		! accumulate input
-+	 sub	$len,1,$len
-+	addxccc	$D1,$H1,$H1
-+	 add	$inp,16,$inp
-+
-+	mulx	$R0,$H0,$D0		! r0*h0
-+	addxc	$padbit,$H2,$H2
-+	umulxhi	$R0,$H0,$D1
-+	mulx	$S1,$H1,$T0		! s1*h1
-+	umulxhi	$S1,$H1,$T1
-+	addcc	$T0,$D0,$D0
-+	mulx	$R1,$H0,$T0		! r1*h0
-+	addxc	$T1,$D1,$D1
-+	umulxhi	$R1,$H0,$D2
-+	addcc	$T0,$D1,$D1
-+	mulx	$R0,$H1,$T0		! r0*h1
-+	addxc	%g0,$D2,$D2
-+	umulxhi	$R0,$H1,$T1
-+	addcc	$T0,$D1,$D1
-+	mulx	$S1,$H2,$T0		! s1*h2
-+	addxc	$T1,$D2,$D2
-+	mulx	$R0,$H2,$T1		! r0*h2
-+	addcc	$T0,$D1,$D1
-+	addxc	$T1,$D2,$D2
-+
-+	srlx	$D2,2,$T0		! final reduction step
-+	andn	$D2,3,$T1
-+	and	$D2,3,$H2
-+	add	$T1,$T0,$T0
-+
-+	addcc	$T0,$D0,$H0
-+	addxccc	%g0,$D1,$H1
-+	brnz,pt	$len,.Loop_vis3
-+	addxc	%g0,$H2,$H2
-+
-+	stx	$H0,[$ctx+0]		! store hash value
-+	stx	$H1,[$ctx+8]
-+	st	$H2,[$ctx+16]
-+
-+	ret
-+	restore
-+.type	poly1305_blocks_vis3,#function
-+.size	poly1305_blocks_vis3,.-poly1305_blocks_vis3
-+___
-+}
-+my ($mac,$nonce) = ($inp,$len);
-+
-+$code.=<<___;
-+.globl	poly1305_emit
-+.align	32
-+poly1305_emit:
-+	save	%sp,-STACK_FRAME,%sp
-+
-+	ld	[$ctx+0],$h1		! load hash value
-+	ld	[$ctx+4],$h0
-+	ld	[$ctx+8],$h3
-+	ld	[$ctx+12],$h2
-+	ld	[$ctx+16],$h4
-+
-+	addcc	$h0,5,$r0		! compare to modulus
-+	addccc	$h1,0,$r1
-+	addccc	$h2,0,$r2
-+	addccc	$h3,0,$r3
-+	addc	$h4,0,$h4
-+	andcc	$h4,4,%g0		! did it carry/borrow?
-+
-+	movnz	%icc,$r0,$h0
-+	ld	[$nonce+0],$r0		! load nonce
-+	movnz	%icc,$r1,$h1
-+	ld	[$nonce+4],$r1
-+	movnz	%icc,$r2,$h2
-+	ld	[$nonce+8],$r2
-+	movnz	%icc,$r3,$h3
-+	ld	[$nonce+12],$r3
-+
-+	addcc	$r0,$h0,$h0		! accumulate nonce
-+	addccc	$r1,$h1,$h1
-+	addccc	$r2,$h2,$h2
-+	addc	$r3,$h3,$h3
-+
-+	srl	$h0,8,$r0
-+	stb	$h0,[$mac+0]		! store little-endian result
-+	srl	$h0,16,$r1
-+	stb	$r0,[$mac+1]
-+	srl	$h0,24,$r2
-+	stb	$r1,[$mac+2]
-+	stb	$r2,[$mac+3]
-+
-+	srl	$h1,8,$r0
-+	stb	$h1,[$mac+4]
-+	srl	$h1,16,$r1
-+	stb	$r0,[$mac+5]
-+	srl	$h1,24,$r2
-+	stb	$r1,[$mac+6]
-+	stb	$r2,[$mac+7]
-+
-+	srl	$h2,8,$r0
-+	stb	$h2,[$mac+8]
-+	srl	$h2,16,$r1
-+	stb	$r0,[$mac+9]
-+	srl	$h2,24,$r2
-+	stb	$r1,[$mac+10]
-+	stb	$r2,[$mac+11]
-+
-+	srl	$h3,8,$r0
-+	stb	$h3,[$mac+12]
-+	srl	$h3,16,$r1
-+	stb	$r0,[$mac+13]
-+	srl	$h3,24,$r2
-+	stb	$r1,[$mac+14]
-+	stb	$r2,[$mac+15]
-+
-+	ret
-+	restore
-+.type	poly1305_emit,#function
-+.size	poly1305_emit,.-poly1305_emit
-+___
-+
-+{
-+my ($ctx,$inp,$len,$padbit) = map("%i$_",(0..3));
-+my ($in0,$in1,$in2,$in3,$in4) = map("%o$_",(0..4));
-+my ($i1,$step,$shr,$shl) = map("%l$_",(0..7));
-+my $i2=$step;
-+
-+my ($h0lo,$h0hi,$h1lo,$h1hi,$h2lo,$h2hi,$h3lo,$h3hi,
-+    $two0,$two32,$two64,$two96,$two130,$five_two130,
-+    $r0lo,$r0hi,$r1lo,$r1hi,$r2lo,$r2hi,
-+    $s2lo,$s2hi,$s3lo,$s3hi,
-+    $c0lo,$c0hi,$c1lo,$c1hi,$c2lo,$c2hi,$c3lo,$c3hi) = map("%f".2*$_,(0..31));
-+# borrowings
-+my ($r3lo,$r3hi,$s1lo,$s1hi) = ($c0lo,$c0hi,$c1lo,$c1hi);
-+my ($x0,$x1,$x2,$x3) = ($c2lo,$c2hi,$c3lo,$c3hi);
-+my ($y0,$y1,$y2,$y3) = ($c1lo,$c1hi,$c3hi,$c3lo);
-+
-+$code.=<<___;
-+.align	32
-+poly1305_init_fma:
-+	save	%sp,-STACK_FRAME-16,%sp
-+	nop
-+
-+.Lpoly1305_init_fma:
-+1:	call	.+8
-+	add	%o7,.Lconsts_fma-1b,%o7
-+
-+	ldd	[%o7+8*0],$two0			! load constants
-+	ldd	[%o7+8*1],$two32
-+	ldd	[%o7+8*2],$two64
-+	ldd	[%o7+8*3],$two96
-+	ldd	[%o7+8*5],$five_two130
-+
-+	std	$two0,[$ctx+8*0]		! initial hash value, biased 0
-+	std	$two32,[$ctx+8*1]
-+	std	$two64,[$ctx+8*2]
-+	std	$two96,[$ctx+8*3]
-+
-+	brz,pn	$inp,.Lno_key_fma
-+	nop
-+
-+	stx	%fsr,[%sp+LOCALS]		! save original %fsr
-+	ldx	[%o7+8*6],%fsr			! load new %fsr
-+
-+	std	$two0,[$ctx+8*4] 		! key "template"
-+	std	$two32,[$ctx+8*5]
-+	std	$two64,[$ctx+8*6]
-+	std	$two96,[$ctx+8*7]
-+
-+	and	$inp,7,$shr
-+	andn	$inp,7,$inp			! align pointer
-+	mov	8,$i1
-+	sll	$shr,3,$shr
-+	mov	16,$i2
-+	neg	$shr,$shl
-+
-+	ldxa	[$inp+%g0]0x88,$in0		! load little-endian key
-+	ldxa	[$inp+$i1]0x88,$in2
-+
-+	brz	$shr,.Lkey_aligned_fma
-+	sethi	%hi(0xf0000000),$i1		!   0xf0000000
-+
-+	ldxa	[$inp+$i2]0x88,$in4
-+
-+	srlx	$in0,$shr,$in0			! align data
-+	sllx	$in2,$shl,$in1
-+	srlx	$in2,$shr,$in2
-+	or	$in1,$in0,$in0
-+	sllx	$in4,$shl,$in3
-+	or	$in3,$in2,$in2
-+
-+.Lkey_aligned_fma:
-+	or	$i1,3,$i2			!   0xf0000003
-+	srlx	$in0,32,$in1
-+	andn	$in0,$i1,$in0			! &=0x0fffffff
-+	andn	$in1,$i2,$in1			! &=0x0ffffffc
-+	srlx	$in2,32,$in3
-+	andn	$in2,$i2,$in2
-+	andn	$in3,$i2,$in3
-+
-+	st	$in0,[$ctx+`8*4+4`]		! fill "template"
-+	st	$in1,[$ctx+`8*5+4`]
-+	st	$in2,[$ctx+`8*6+4`]
-+	st	$in3,[$ctx+`8*7+4`]
-+
-+	ldd	[$ctx+8*4],$h0lo 		! load [biased] key
-+	ldd	[$ctx+8*5],$h1lo
-+	ldd	[$ctx+8*6],$h2lo
-+	ldd	[$ctx+8*7],$h3lo
-+
-+	fsubd	$h0lo,$two0, $h0lo		! r0
-+	 ldd	[%o7+8*7],$two0 		! more constants
-+	fsubd	$h1lo,$two32,$h1lo		! r1
-+	 ldd	[%o7+8*8],$two32
-+	fsubd	$h2lo,$two64,$h2lo		! r2
-+	 ldd	[%o7+8*9],$two64
-+	fsubd	$h3lo,$two96,$h3lo		! r3
-+	 ldd	[%o7+8*10],$two96
-+
-+	fmuld	$five_two130,$h1lo,$s1lo	! s1
-+	fmuld	$five_two130,$h2lo,$s2lo	! s2
-+	fmuld	$five_two130,$h3lo,$s3lo	! s3
-+
-+	faddd	$h0lo,$two0, $h0hi
-+	faddd	$h1lo,$two32,$h1hi
-+	faddd	$h2lo,$two64,$h2hi
-+	faddd	$h3lo,$two96,$h3hi
-+
-+	fsubd	$h0hi,$two0, $h0hi
-+	 ldd	[%o7+8*11],$two0		! more constants
-+	fsubd	$h1hi,$two32,$h1hi
-+	 ldd	[%o7+8*12],$two32
-+	fsubd	$h2hi,$two64,$h2hi
-+	 ldd	[%o7+8*13],$two64
-+	fsubd	$h3hi,$two96,$h3hi
-+
-+	fsubd	$h0lo,$h0hi,$h0lo
-+	 std	$h0hi,[$ctx+8*5] 		! r0hi
-+	fsubd	$h1lo,$h1hi,$h1lo
-+	 std	$h1hi,[$ctx+8*7] 		! r1hi
-+	fsubd	$h2lo,$h2hi,$h2lo
-+	 std	$h2hi,[$ctx+8*9] 		! r2hi
-+	fsubd	$h3lo,$h3hi,$h3lo
-+	 std	$h3hi,[$ctx+8*11]		! r3hi
-+
-+	faddd	$s1lo,$two0, $s1hi
-+	faddd	$s2lo,$two32,$s2hi
-+	faddd	$s3lo,$two64,$s3hi
-+
-+	fsubd	$s1hi,$two0, $s1hi
-+	fsubd	$s2hi,$two32,$s2hi
-+	fsubd	$s3hi,$two64,$s3hi
-+
-+	fsubd	$s1lo,$s1hi,$s1lo
-+	fsubd	$s2lo,$s2hi,$s2lo
-+	fsubd	$s3lo,$s3hi,$s3lo
-+
-+	ldx	[%sp+LOCALS],%fsr		! restore %fsr
-+
-+	std	$h0lo,[$ctx+8*4] 		! r0lo
-+	std	$h1lo,[$ctx+8*6] 		! r1lo
-+	std	$h2lo,[$ctx+8*8] 		! r2lo
-+	std	$h3lo,[$ctx+8*10]		! r3lo
-+
-+	std	$s1hi,[$ctx+8*13]
-+	std	$s2hi,[$ctx+8*15]
-+	std	$s3hi,[$ctx+8*17]
-+
-+	std	$s1lo,[$ctx+8*12]
-+	std	$s2lo,[$ctx+8*14]
-+	std	$s3lo,[$ctx+8*16]
-+
-+	add	%o7,poly1305_blocks_fma-.Lconsts_fma,%o0
-+	add	%o7,poly1305_emit_fma-.Lconsts_fma,%o1
-+	STPTR	%o0,[%i2]
-+	STPTR	%o1,[%i2+SIZE_T]
-+
-+	ret
-+	restore	%g0,1,%o0			! return 1
-+
-+.Lno_key_fma:
-+	ret
-+	restore	%g0,%g0,%o0			! return 0
-+.type	poly1305_init_fma,#function
-+.size	poly1305_init_fma,.-poly1305_init_fma
-+
-+.align	32
-+poly1305_blocks_fma:
-+	save	%sp,-STACK_FRAME-48,%sp
-+	srln	$len,4,$len
-+
-+	brz,pn	$len,.Labort
-+	sub	$len,1,$len
-+
-+1:	call	.+8
-+	add	%o7,.Lconsts_fma-1b,%o7
-+
-+	ldd	[%o7+8*0],$two0			! load constants
-+	ldd	[%o7+8*1],$two32
-+	ldd	[%o7+8*2],$two64
-+	ldd	[%o7+8*3],$two96
-+	ldd	[%o7+8*4],$two130
-+	ldd	[%o7+8*5],$five_two130
-+
-+	ldd	[$ctx+8*0],$h0lo 		! load [biased] hash value
-+	ldd	[$ctx+8*1],$h1lo
-+	ldd	[$ctx+8*2],$h2lo
-+	ldd	[$ctx+8*3],$h3lo
-+
-+	std	$two0,[%sp+LOCALS+8*0]		! input "template"
-+	sethi	%hi((1023+52+96)<<20),$in3
-+	std	$two32,[%sp+LOCALS+8*1]
-+	or	$padbit,$in3,$in3
-+	std	$two64,[%sp+LOCALS+8*2]
-+	st	$in3,[%sp+LOCALS+8*3]
-+
-+	and	$inp,7,$shr
-+	andn	$inp,7,$inp			! align pointer
-+	mov	8,$i1
-+	sll	$shr,3,$shr
-+	mov	16,$step
-+	neg	$shr,$shl
-+
-+	ldxa	[$inp+%g0]0x88,$in0		! load little-endian input
-+	brz	$shr,.Linp_aligned_fma
-+	ldxa	[$inp+$i1]0x88,$in2
-+
-+	ldxa	[$inp+$step]0x88,$in4
-+	add	$inp,8,$inp
-+
-+	srlx	$in0,$shr,$in0			! align data
-+	sllx	$in2,$shl,$in1
-+	srlx	$in2,$shr,$in2
-+	or	$in1,$in0,$in0
-+	sllx	$in4,$shl,$in3
-+	srlx	$in4,$shr,$in4			! pre-shift
-+	or	$in3,$in2,$in2
-+
-+.Linp_aligned_fma:
-+	srlx	$in0,32,$in1
-+	movrz	$len,0,$step
-+	srlx	$in2,32,$in3
-+	add	$step,$inp,$inp			! conditional advance
-+
-+	st	$in0,[%sp+LOCALS+8*0+4]		! fill "template"
-+	st	$in1,[%sp+LOCALS+8*1+4]
-+	st	$in2,[%sp+LOCALS+8*2+4]
-+	st	$in3,[%sp+LOCALS+8*3+4]
-+
-+	ldd	[$ctx+8*4],$r0lo 		! load key
-+	ldd	[$ctx+8*5],$r0hi
-+	ldd	[$ctx+8*6],$r1lo
-+	ldd	[$ctx+8*7],$r1hi
-+	ldd	[$ctx+8*8],$r2lo
-+	ldd	[$ctx+8*9],$r2hi
-+	ldd	[$ctx+8*10],$r3lo
-+	ldd	[$ctx+8*11],$r3hi
-+	ldd	[$ctx+8*12],$s1lo
-+	ldd	[$ctx+8*13],$s1hi
-+	ldd	[$ctx+8*14],$s2lo
-+	ldd	[$ctx+8*15],$s2hi
-+	ldd	[$ctx+8*16],$s3lo
-+	ldd	[$ctx+8*17],$s3hi
-+
-+	stx	%fsr,[%sp+LOCALS+8*4]		! save original %fsr
-+	ldx	[%o7+8*6],%fsr			! load new %fsr
-+
-+	subcc	$len,1,$len
-+	movrz	$len,0,$step
-+
-+	ldd	[%sp+LOCALS+8*0],$x0		! load biased input
-+	ldd	[%sp+LOCALS+8*1],$x1
-+	ldd	[%sp+LOCALS+8*2],$x2
-+	ldd	[%sp+LOCALS+8*3],$x3
-+
-+	fsubd	$h0lo,$two0, $h0lo		! de-bias hash value
-+	fsubd	$h1lo,$two32,$h1lo
-+	 ldxa	[$inp+%g0]0x88,$in0		! modulo-scheduled input load
-+	fsubd	$h2lo,$two64,$h2lo
-+	fsubd	$h3lo,$two96,$h3lo
-+	 ldxa	[$inp+$i1]0x88,$in2
-+
-+	fsubd	$x0,$two0, $x0  		! de-bias input
-+	fsubd	$x1,$two32,$x1
-+	fsubd	$x2,$two64,$x2
-+	fsubd	$x3,$two96,$x3
-+
-+	brz	$shr,.Linp_aligned_fma2
-+	add	$step,$inp,$inp			! conditional advance
-+
-+	sllx	$in0,$shl,$in1			! align data
-+	srlx	$in0,$shr,$in3
-+	or	$in1,$in4,$in0
-+	sllx	$in2,$shl,$in1
-+	srlx	$in2,$shr,$in4			! pre-shift
-+	or	$in3,$in1,$in2
-+.Linp_aligned_fma2:
-+	srlx	$in0,32,$in1
-+	srlx	$in2,32,$in3
-+
-+	faddd	$h0lo,$x0,$x0			! accumulate input
-+	 stw	$in0,[%sp+LOCALS+8*0+4]
-+	faddd	$h1lo,$x1,$x1
-+	 stw	$in1,[%sp+LOCALS+8*1+4]
-+	faddd	$h2lo,$x2,$x2
-+	 stw	$in2,[%sp+LOCALS+8*2+4]
-+	faddd	$h3lo,$x3,$x3
-+	 stw	$in3,[%sp+LOCALS+8*3+4]
-+
-+	b	.Lentry_fma
-+	nop
-+
-+.align	16
-+.Loop_fma:
-+	ldxa	[$inp+%g0]0x88,$in0		! modulo-scheduled input load
-+	ldxa	[$inp+$i1]0x88,$in2
-+	movrz	$len,0,$step
-+
-+	faddd	$y0,$h0lo,$h0lo 		! accumulate input
-+	faddd	$y1,$h0hi,$h0hi
-+	faddd	$y2,$h2lo,$h2lo
-+	faddd	$y3,$h2hi,$h2hi
-+
-+	brz,pn	$shr,.Linp_aligned_fma3
-+	add	$step,$inp,$inp			! conditional advance
-+
-+	sllx	$in0,$shl,$in1			! align data
-+	srlx	$in0,$shr,$in3
-+	or	$in1,$in4,$in0
-+	sllx	$in2,$shl,$in1
-+	srlx	$in2,$shr,$in4			! pre-shift
-+	or	$in3,$in1,$in2
-+
-+.Linp_aligned_fma3:
-+	!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! base 2^48 -> base 2^32
-+	faddd	$two64,$h1lo,$c1lo
-+	 srlx	$in0,32,$in1
-+	faddd	$two64,$h1hi,$c1hi
-+	 srlx	$in2,32,$in3
-+	faddd	$two130,$h3lo,$c3lo
-+	 st	$in0,[%sp+LOCALS+8*0+4]		! fill "template"
-+	faddd	$two130,$h3hi,$c3hi
-+	 st	$in1,[%sp+LOCALS+8*1+4]
-+	faddd	$two32,$h0lo,$c0lo
-+	 st	$in2,[%sp+LOCALS+8*2+4]
-+	faddd	$two32,$h0hi,$c0hi
-+	 st	$in3,[%sp+LOCALS+8*3+4]
-+	faddd	$two96,$h2lo,$c2lo
-+	faddd	$two96,$h2hi,$c2hi
-+
-+	fsubd	$c1lo,$two64,$c1lo
-+	fsubd	$c1hi,$two64,$c1hi
-+	fsubd	$c3lo,$two130,$c3lo
-+	fsubd	$c3hi,$two130,$c3hi
-+	fsubd	$c0lo,$two32,$c0lo
-+	fsubd	$c0hi,$two32,$c0hi
-+	fsubd	$c2lo,$two96,$c2lo
-+	fsubd	$c2hi,$two96,$c2hi
-+
-+	fsubd	$h1lo,$c1lo,$h1lo
-+	fsubd	$h1hi,$c1hi,$h1hi
-+	fsubd	$h3lo,$c3lo,$h3lo
-+	fsubd	$h3hi,$c3hi,$h3hi
-+	fsubd	$h2lo,$c2lo,$h2lo
-+	fsubd	$h2hi,$c2hi,$h2hi
-+	fsubd	$h0lo,$c0lo,$h0lo
-+	fsubd	$h0hi,$c0hi,$h0hi
-+
-+	faddd	$h1lo,$c0lo,$h1lo
-+	faddd	$h1hi,$c0hi,$h1hi
-+	faddd	$h3lo,$c2lo,$h3lo
-+	faddd	$h3hi,$c2hi,$h3hi
-+	faddd	$h2lo,$c1lo,$h2lo
-+	faddd	$h2hi,$c1hi,$h2hi
-+	fmaddd	$five_two130,$c3lo,$h0lo,$h0lo
-+	fmaddd	$five_two130,$c3hi,$h0hi,$h0hi
-+
-+	faddd	$h1lo,$h1hi,$x1
-+	 ldd	[$ctx+8*12],$s1lo		! reload constants
-+	faddd	$h3lo,$h3hi,$x3
-+	 ldd	[$ctx+8*13],$s1hi
-+	faddd	$h2lo,$h2hi,$x2
-+	 ldd	[$ctx+8*10],$r3lo
-+	faddd	$h0lo,$h0hi,$x0
-+	 ldd	[$ctx+8*11],$r3hi
-+
-+.Lentry_fma:
-+	fmuld	$x1,$s3lo,$h0lo
-+	fmuld	$x1,$s3hi,$h0hi
-+	fmuld	$x1,$r1lo,$h2lo
-+	fmuld	$x1,$r1hi,$h2hi
-+	fmuld	$x1,$r0lo,$h1lo
-+	fmuld	$x1,$r0hi,$h1hi
-+	fmuld	$x1,$r2lo,$h3lo
-+	fmuld	$x1,$r2hi,$h3hi
-+
-+	fmaddd	$x3,$s1lo,$h0lo,$h0lo
-+	fmaddd	$x3,$s1hi,$h0hi,$h0hi
-+	fmaddd	$x3,$s3lo,$h2lo,$h2lo
-+	fmaddd	$x3,$s3hi,$h2hi,$h2hi
-+	fmaddd	$x3,$s2lo,$h1lo,$h1lo
-+	fmaddd	$x3,$s2hi,$h1hi,$h1hi
-+	fmaddd	$x3,$r0lo,$h3lo,$h3lo
-+	fmaddd	$x3,$r0hi,$h3hi,$h3hi
-+
-+	fmaddd	$x2,$s2lo,$h0lo,$h0lo
-+	fmaddd	$x2,$s2hi,$h0hi,$h0hi
-+	fmaddd	$x2,$r0lo,$h2lo,$h2lo
-+	fmaddd	$x2,$r0hi,$h2hi,$h2hi
-+	fmaddd	$x2,$s3lo,$h1lo,$h1lo
-+	 ldd	[%sp+LOCALS+8*0],$y0		! load [biased] input
-+	fmaddd	$x2,$s3hi,$h1hi,$h1hi
-+	 ldd	[%sp+LOCALS+8*1],$y1
-+	fmaddd	$x2,$r1lo,$h3lo,$h3lo
-+	 ldd	[%sp+LOCALS+8*2],$y2
-+	fmaddd	$x2,$r1hi,$h3hi,$h3hi
-+	 ldd	[%sp+LOCALS+8*3],$y3
-+
-+	fmaddd	$x0,$r0lo,$h0lo,$h0lo
-+	 fsubd	$y0,$two0, $y0  		! de-bias input
-+	fmaddd	$x0,$r0hi,$h0hi,$h0hi
-+	 fsubd	$y1,$two32,$y1
-+	fmaddd	$x0,$r2lo,$h2lo,$h2lo
-+	 fsubd	$y2,$two64,$y2
-+	fmaddd	$x0,$r2hi,$h2hi,$h2hi
-+	 fsubd	$y3,$two96,$y3
-+	fmaddd	$x0,$r1lo,$h1lo,$h1lo
-+	fmaddd	$x0,$r1hi,$h1hi,$h1hi
-+	fmaddd	$x0,$r3lo,$h3lo,$h3lo
-+	fmaddd	$x0,$r3hi,$h3hi,$h3hi
-+
-+	bcc	SIZE_T_CC,.Loop_fma
-+	subcc	$len,1,$len
-+
-+	!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! base 2^48 -> base 2^32
-+	faddd	$h0lo,$two32,$c0lo
-+	faddd	$h0hi,$two32,$c0hi
-+	faddd	$h2lo,$two96,$c2lo
-+	faddd	$h2hi,$two96,$c2hi
-+	faddd	$h1lo,$two64,$c1lo
-+	faddd	$h1hi,$two64,$c1hi
-+	faddd	$h3lo,$two130,$c3lo
-+	faddd	$h3hi,$two130,$c3hi
-+
-+	fsubd	$c0lo,$two32,$c0lo
-+	fsubd	$c0hi,$two32,$c0hi
-+	fsubd	$c2lo,$two96,$c2lo
-+	fsubd	$c2hi,$two96,$c2hi
-+	fsubd	$c1lo,$two64,$c1lo
-+	fsubd	$c1hi,$two64,$c1hi
-+	fsubd	$c3lo,$two130,$c3lo
-+	fsubd	$c3hi,$two130,$c3hi
-+
-+	fsubd	$h1lo,$c1lo,$h1lo
-+	fsubd	$h1hi,$c1hi,$h1hi
-+	fsubd	$h3lo,$c3lo,$h3lo
-+	fsubd	$h3hi,$c3hi,$h3hi
-+	fsubd	$h2lo,$c2lo,$h2lo
-+	fsubd	$h2hi,$c2hi,$h2hi
-+	fsubd	$h0lo,$c0lo,$h0lo
-+	fsubd	$h0hi,$c0hi,$h0hi
-+
-+	faddd	$h1lo,$c0lo,$h1lo
-+	faddd	$h1hi,$c0hi,$h1hi
-+	faddd	$h3lo,$c2lo,$h3lo
-+	faddd	$h3hi,$c2hi,$h3hi
-+	faddd	$h2lo,$c1lo,$h2lo
-+	faddd	$h2hi,$c1hi,$h2hi
-+	fmaddd	$five_two130,$c3lo,$h0lo,$h0lo
-+	fmaddd	$five_two130,$c3hi,$h0hi,$h0hi
-+
-+	faddd	$h1lo,$h1hi,$x1
-+	faddd	$h3lo,$h3hi,$x3
-+	faddd	$h2lo,$h2hi,$x2
-+	faddd	$h0lo,$h0hi,$x0
-+
-+	faddd	$x1,$two32,$x1  		! bias
-+	faddd	$x3,$two96,$x3
-+	faddd	$x2,$two64,$x2
-+	faddd	$x0,$two0, $x0
-+
-+	ldx	[%sp+LOCALS+8*4],%fsr		! restore saved %fsr
-+
-+	std	$x1,[$ctx+8*1]			! store [biased] hash value
-+	std	$x3,[$ctx+8*3]
-+	std	$x2,[$ctx+8*2]
-+	std	$x0,[$ctx+8*0]
-+
-+.Labort:
-+	ret
-+	restore
-+.type	poly1305_blocks_fma,#function
-+.size	poly1305_blocks_fma,.-poly1305_blocks_fma
-+___
-+{
-+my ($mac,$nonce)=($inp,$len);
-+
-+my ($h0,$h1,$h2,$h3,$h4, $d0,$d1,$d2,$d3, $mask
-+   ) = (map("%l$_",(0..5)),map("%o$_",(0..4)));
-+
-+$code.=<<___;
-+.align	32
-+poly1305_emit_fma:
-+	save	%sp,-STACK_FRAME,%sp
-+
-+	ld	[$ctx+8*0+0],$d0		! load hash
-+	ld	[$ctx+8*0+4],$h0
-+	ld	[$ctx+8*1+0],$d1
-+	ld	[$ctx+8*1+4],$h1
-+	ld	[$ctx+8*2+0],$d2
-+	ld	[$ctx+8*2+4],$h2
-+	ld	[$ctx+8*3+0],$d3
-+	ld	[$ctx+8*3+4],$h3
-+
-+	sethi	%hi(0xfff00000),$mask
-+	andn	$d0,$mask,$d0			! mask exponent
-+	andn	$d1,$mask,$d1
-+	andn	$d2,$mask,$d2
-+	andn	$d3,$mask,$d3			! can be partially reduced...
-+	mov	3,$mask
-+
-+	srl	$d3,2,$padbit			! ... so reduce
-+	and	$d3,$mask,$h4
-+	andn	$d3,$mask,$d3
-+	add	$padbit,$d3,$d3
-+
-+	addcc	$d3,$h0,$h0
-+	addccc	$d0,$h1,$h1
-+	addccc	$d1,$h2,$h2
-+	addccc	$d2,$h3,$h3
-+	addc	%g0,$h4,$h4
-+
-+	addcc	$h0,5,$d0			! compare to modulus
-+	addccc	$h1,0,$d1
-+	addccc	$h2,0,$d2
-+	addccc	$h3,0,$d3
-+	addc	$h4,0,$mask
-+
-+	srl	$mask,2,$mask			! did it carry/borrow?
-+	neg	$mask,$mask
-+	sra	$mask,31,$mask			! mask
-+
-+	andn	$h0,$mask,$h0
-+	and	$d0,$mask,$d0
-+	andn	$h1,$mask,$h1
-+	and	$d1,$mask,$d1
-+	or	$d0,$h0,$h0
-+	ld	[$nonce+0],$d0			! load nonce
-+	andn	$h2,$mask,$h2
-+	and	$d2,$mask,$d2
-+	or	$d1,$h1,$h1
-+	ld	[$nonce+4],$d1
-+	andn	$h3,$mask,$h3
-+	and	$d3,$mask,$d3
-+	or	$d2,$h2,$h2
-+	ld	[$nonce+8],$d2
-+	or	$d3,$h3,$h3
-+	ld	[$nonce+12],$d3
-+
-+	addcc	$d0,$h0,$h0			! accumulate nonce
-+	addccc	$d1,$h1,$h1
-+	addccc	$d2,$h2,$h2
-+	addc	$d3,$h3,$h3
-+
-+	stb	$h0,[$mac+0]			! write little-endian result
-+	srl	$h0,8,$h0
-+	stb	$h1,[$mac+4]
-+	srl	$h1,8,$h1
-+	stb	$h2,[$mac+8]
-+	srl	$h2,8,$h2
-+	stb	$h3,[$mac+12]
-+	srl	$h3,8,$h3
-+
-+	stb	$h0,[$mac+1]
-+	srl	$h0,8,$h0
-+	stb	$h1,[$mac+5]
-+	srl	$h1,8,$h1
-+	stb	$h2,[$mac+9]
-+	srl	$h2,8,$h2
-+	stb	$h3,[$mac+13]
-+	srl	$h3,8,$h3
-+
-+	stb	$h0,[$mac+2]
-+	srl	$h0,8,$h0
-+	stb	$h1,[$mac+6]
-+	srl	$h1,8,$h1
-+	stb	$h2,[$mac+10]
-+	srl	$h2,8,$h2
-+	stb	$h3,[$mac+14]
-+	srl	$h3,8,$h3
-+
-+	stb	$h0,[$mac+3]
-+	stb	$h1,[$mac+7]
-+	stb	$h2,[$mac+11]
-+	stb	$h3,[$mac+15]
-+
-+	ret
-+	restore
-+.type	poly1305_emit_fma,#function
-+.size	poly1305_emit_fma,.-poly1305_emit_fma
-+___
-+}
-+
-+$code.=<<___;
-+.align	64
-+.Lconsts_fma:
-+.word	0x43300000,0x00000000		! 2^(52+0)
-+.word	0x45300000,0x00000000		! 2^(52+32)
-+.word	0x47300000,0x00000000		! 2^(52+64)
-+.word	0x49300000,0x00000000		! 2^(52+96)
-+.word	0x4b500000,0x00000000		! 2^(52+130)
-+
-+.word	0x37f40000,0x00000000		! 5/2^130
-+.word	0,1<<30				! fsr: truncate, no exceptions
-+
-+.word	0x44300000,0x00000000		! 2^(52+16+0)
-+.word	0x46300000,0x00000000		! 2^(52+16+32)
-+.word	0x48300000,0x00000000		! 2^(52+16+64)
-+.word	0x4a300000,0x00000000		! 2^(52+16+96)
-+.word	0x3e300000,0x00000000		! 2^(52+16+0-96)
-+.word	0x40300000,0x00000000		! 2^(52+16+32-96)
-+.word	0x42300000,0x00000000		! 2^(52+16+64-96)
-+.asciz	"Poly1305 for SPARCv9/VIS3/FMA, CRYPTOGAMS by "
-+.align	4
-+___
-+}
-+
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis3 {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my ($ref,$opf);
-+my %visopf = (	"addxc"		=> 0x011,
-+		"addxccc"	=> 0x013,
-+		"umulxhi"	=> 0x016	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%([goli])([0-9])/);
-+	    $_=$bias{$1}+$2;
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+sub unfma {
-+my ($mnemonic,$rs1,$rs2,$rs3,$rd)=@_;
-+my ($ref,$opf);
-+my %fmaopf = (	"fmadds"	=> 0x1,
-+		"fmaddd"	=> 0x2,
-+		"fmsubs"	=> 0x5,
-+		"fmsubd"	=> 0x6		);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rs3,$rd";
-+
-+    if ($opf=$fmaopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rs3,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b80000|$rd<<25|$rs1<<14|$rs3<<9|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	s/\b(umulxhi|addxc[c]{0,2})\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+		&unvis3($1,$2,$3,$4)
-+	 /ge	or
-+	s/\b(fmadd[sd])\s+(%f[0-9]+),\s*(%f[0-9]+),\s*(%f[0-9]+),\s*(%f[0-9]+)/
-+		&unfma($1,$2,$3,$4,$5)
-+	 /ge;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-x86.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-x86.pl
-new file mode 100755
-index 0000000..ab24dfc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-x86.pl
-@@ -0,0 +1,1814 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements Poly1305 hash for x86.
-+#
-+# April 2015
-+#
-+# Numbers are cycles per processed byte with poly1305_blocks alone,
-+# measured with rdtsc at fixed clock frequency.
-+#
-+#		IALU/gcc-3.4(*)	SSE2(**)	AVX2
-+# Pentium	15.7/+80%	-
-+# PIII		6.21/+90%	-
-+# P4		19.8/+40%	3.24
-+# Core 2	4.85/+90%	1.80
-+# Westmere	4.58/+100%	1.43
-+# Sandy Bridge	3.90/+100%	1.36
-+# Haswell	3.88/+70%	1.18		0.72
-+# Silvermont	11.0/+40%	4.80
-+# Goldmont	4.10/+200%	2.10
-+# VIA Nano	6.71/+90%	2.47
-+# Sledgehammer	3.51/+180%	4.27
-+# Bulldozer	4.53/+140%	1.31
-+#
-+# (*)	gcc 4.8 for some reason generated worse code;
-+# (**)	besides SSE2 there are floating-point and AVX options; FP
-+#	is deemed unnecessary, because pre-SSE2 processor are too
-+#	old to care about, while it's not the fastest option on
-+#	SSE2-capable ones; AVX is omitted, because it doesn't give
-+#	a lot of improvement, 5-10% depending on processor;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"poly1305-x86.pl",$ARGV[$#ARGV] eq "386");
-+
-+$sse2=$avx=0;
-+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-+
-+if ($sse2) {
-+	&static_label("const_sse2");
-+	&static_label("enter_blocks");
-+	&static_label("enter_emit");
-+	&external_label("OPENSSL_ia32cap_P");
-+
-+	if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+			=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+		$avx = ($1>=2.19) + ($1>=2.22);
-+	}
-+
-+	if (!$avx && $ARGV[0] eq "win32n" &&
-+	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+	}
-+
-+	if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/) {
-+		$avx = ($2>=3.0) + ($2>3.0);
-+	}
-+}
-+
-+########################################################################
-+# Layout of opaque area is following.
-+#
-+#	unsigned __int32 h[5];		# current hash value base 2^32
-+#	unsigned __int32 pad;		# is_base2_26 in vector context
-+#	unsigned __int32 r[4];		# key value base 2^32
-+
-+&align(64);
-+&function_begin("poly1305_init");
-+	&mov	("edi",&wparam(0));		# context
-+	&mov	("esi",&wparam(1));		# key
-+	&mov	("ebp",&wparam(2));		# function table
-+
-+	&xor	("eax","eax");
-+	&mov	(&DWP(4*0,"edi"),"eax");	# zero hash value
-+	&mov	(&DWP(4*1,"edi"),"eax");
-+	&mov	(&DWP(4*2,"edi"),"eax");
-+	&mov	(&DWP(4*3,"edi"),"eax");
-+	&mov	(&DWP(4*4,"edi"),"eax");
-+	&mov	(&DWP(4*5,"edi"),"eax");	# is_base2_26
-+
-+	&cmp	("esi",0);
-+	&je	(&label("nokey"));
-+
-+    if ($sse2) {
-+	&call	(&label("pic_point"));
-+    &set_label("pic_point");
-+	&blindpop("ebx");
-+
-+	&lea	("eax",&DWP("poly1305_blocks-".&label("pic_point"),"ebx"));
-+	&lea	("edx",&DWP("poly1305_emit-".&label("pic_point"),"ebx"));
-+
-+	&picmeup("edi","OPENSSL_ia32cap_P","ebx",&label("pic_point"));
-+	&mov	("ecx",&DWP(0,"edi"));
-+	&and	("ecx",1<<26|1<<24);
-+	&cmp	("ecx",1<<26|1<<24);		# SSE2 and XMM?
-+	&jne	(&label("no_sse2"));
-+
-+	&lea	("eax",&DWP("_poly1305_blocks_sse2-".&label("pic_point"),"ebx"));
-+	&lea	("edx",&DWP("_poly1305_emit_sse2-".&label("pic_point"),"ebx"));
-+
-+      if ($avx>1) {
-+	&mov	("ecx",&DWP(8,"edi"));
-+	&test	("ecx",1<<5);			# AVX2?
-+	&jz	(&label("no_sse2"));
-+
-+	&lea	("eax",&DWP("_poly1305_blocks_avx2-".&label("pic_point"),"ebx"));
-+      }
-+    &set_label("no_sse2");
-+	&mov	("edi",&wparam(0));		# reload context
-+	&mov	(&DWP(0,"ebp"),"eax");		# fill function table
-+	&mov	(&DWP(4,"ebp"),"edx");
-+    }
-+
-+	&mov	("eax",&DWP(4*0,"esi"));	# load input key
-+	&mov	("ebx",&DWP(4*1,"esi"));
-+	&mov	("ecx",&DWP(4*2,"esi"));
-+	&mov	("edx",&DWP(4*3,"esi"));
-+	&and	("eax",0x0fffffff);
-+	&and	("ebx",0x0ffffffc);
-+	&and	("ecx",0x0ffffffc);
-+	&and	("edx",0x0ffffffc);
-+	&mov	(&DWP(4*6,"edi"),"eax");
-+	&mov	(&DWP(4*7,"edi"),"ebx");
-+	&mov	(&DWP(4*8,"edi"),"ecx");
-+	&mov	(&DWP(4*9,"edi"),"edx");
-+
-+	&mov	("eax",$sse2);
-+&set_label("nokey");
-+&function_end("poly1305_init");
-+
-+($h0,$h1,$h2,$h3,$h4,
-+ $d0,$d1,$d2,$d3,
-+ $r0,$r1,$r2,$r3,
-+     $s1,$s2,$s3)=map(4*$_,(0..15));
-+
-+&function_begin("poly1305_blocks");
-+	&mov	("edi",&wparam(0));		# ctx
-+	&mov	("esi",&wparam(1));		# inp
-+	&mov	("ecx",&wparam(2));		# len
-+&set_label("enter_blocks");
-+	&and	("ecx",-15);
-+	&jz	(&label("nodata"));
-+
-+	&stack_push(16);
-+	&mov	("eax",&DWP(4*6,"edi"));	# r0
-+	&mov	("ebx",&DWP(4*7,"edi"));	# r1
-+	 &lea	("ebp",&DWP(0,"esi","ecx"));	# end of input
-+	&mov	("ecx",&DWP(4*8,"edi"));	# r2
-+	&mov	("edx",&DWP(4*9,"edi"));	# r3
-+
-+	&mov	(&wparam(2),"ebp");
-+	&mov	("ebp","esi");
-+
-+	&mov	(&DWP($r0,"esp"),"eax");	# r0
-+	&mov	("eax","ebx");
-+	&shr	("eax",2);
-+	&mov	(&DWP($r1,"esp"),"ebx");	# r1
-+	&add	("eax","ebx");			# s1
-+	&mov	("ebx","ecx");
-+	&shr	("ebx",2);
-+	&mov	(&DWP($r2,"esp"),"ecx");	# r2
-+	&add	("ebx","ecx");			# s2
-+	&mov	("ecx","edx");
-+	&shr	("ecx",2);
-+	&mov	(&DWP($r3,"esp"),"edx");	# r3
-+	&add	("ecx","edx");			# s3
-+	&mov	(&DWP($s1,"esp"),"eax");	# s1
-+	&mov	(&DWP($s2,"esp"),"ebx");	# s2
-+	&mov	(&DWP($s3,"esp"),"ecx");	# s3
-+
-+	&mov	("eax",&DWP(4*0,"edi"));	# load hash value
-+	&mov	("ebx",&DWP(4*1,"edi"));
-+	&mov	("ecx",&DWP(4*2,"edi"));
-+	&mov	("esi",&DWP(4*3,"edi"));
-+	&mov	("edi",&DWP(4*4,"edi"));
-+	&jmp	(&label("loop"));
-+
-+&set_label("loop",32);
-+	&add	("eax",&DWP(4*0,"ebp"));	# accumulate input
-+	&adc	("ebx",&DWP(4*1,"ebp"));
-+	&adc	("ecx",&DWP(4*2,"ebp"));
-+	&adc	("esi",&DWP(4*3,"ebp"));
-+	&lea	("ebp",&DWP(4*4,"ebp"));
-+	&adc	("edi",&wparam(3));		# padbit
-+
-+	&mov	(&DWP($h0,"esp"),"eax");	# put aside hash[+inp]
-+	&mov	(&DWP($h3,"esp"),"esi");
-+
-+	&mul	(&DWP($r0,"esp"));		# h0*r0
-+	 &mov	(&DWP($h4,"esp"),"edi");
-+	&mov	("edi","eax");
-+	&mov	("eax","ebx");			# h1
-+	&mov	("esi","edx");
-+	&mul	(&DWP($s3,"esp"));		# h1*s3
-+	&add	("edi","eax");
-+	&mov	("eax","ecx");			# h2
-+	&adc	("esi","edx");
-+	&mul	(&DWP($s2,"esp"));		# h2*s2
-+	&add	("edi","eax");
-+	&mov	("eax",&DWP($h3,"esp"));
-+	&adc	("esi","edx");
-+	&mul	(&DWP($s1,"esp"));		# h3*s1
-+	&add	("edi","eax");
-+	 &mov	("eax",&DWP($h0,"esp"));
-+	&adc	("esi","edx");
-+
-+	&mul	(&DWP($r1,"esp"));		# h0*r1
-+	 &mov	(&DWP($d0,"esp"),"edi");
-+	&xor	("edi","edi");
-+	&add	("esi","eax");
-+	&mov	("eax","ebx");			# h1
-+	&adc	("edi","edx");
-+	&mul	(&DWP($r0,"esp"));		# h1*r0
-+	&add	("esi","eax");
-+	&mov	("eax","ecx");			# h2
-+	&adc	("edi","edx");
-+	&mul	(&DWP($s3,"esp"));		# h2*s3
-+	&add	("esi","eax");
-+	&mov	("eax",&DWP($h3,"esp"));
-+	&adc	("edi","edx");
-+	&mul	(&DWP($s2,"esp"));		# h3*s2
-+	&add	("esi","eax");
-+	&mov	("eax",&DWP($h4,"esp"));
-+	&adc	("edi","edx");
-+	&imul	("eax",&DWP($s1,"esp"));	# h4*s1
-+	&add	("esi","eax");
-+	 &mov	("eax",&DWP($h0,"esp"));
-+	&adc	("edi",0);
-+
-+	&mul	(&DWP($r2,"esp"));		# h0*r2
-+	 &mov	(&DWP($d1,"esp"),"esi");
-+	&xor	("esi","esi");
-+	&add	("edi","eax");
-+	&mov	("eax","ebx");			# h1
-+	&adc	("esi","edx");
-+	&mul	(&DWP($r1,"esp"));		# h1*r1
-+	&add	("edi","eax");
-+	&mov	("eax","ecx");			# h2
-+	&adc	("esi","edx");
-+	&mul	(&DWP($r0,"esp"));		# h2*r0
-+	&add	("edi","eax");
-+	&mov	("eax",&DWP($h3,"esp"));
-+	&adc	("esi","edx");
-+	&mul	(&DWP($s3,"esp"));		# h3*s3
-+	&add	("edi","eax");
-+	&mov	("eax",&DWP($h4,"esp"));
-+	&adc	("esi","edx");
-+	&imul	("eax",&DWP($s2,"esp"));	# h4*s2
-+	&add	("edi","eax");
-+	 &mov	("eax",&DWP($h0,"esp"));
-+	&adc	("esi",0);
-+
-+	&mul	(&DWP($r3,"esp"));		# h0*r3
-+	 &mov	(&DWP($d2,"esp"),"edi");
-+	&xor	("edi","edi");
-+	&add	("esi","eax");
-+	&mov	("eax","ebx");			# h1
-+	&adc	("edi","edx");
-+	&mul	(&DWP($r2,"esp"));		# h1*r2
-+	&add	("esi","eax");
-+	&mov	("eax","ecx");			# h2
-+	&adc	("edi","edx");
-+	&mul	(&DWP($r1,"esp"));		# h2*r1
-+	&add	("esi","eax");
-+	&mov	("eax",&DWP($h3,"esp"));
-+	&adc	("edi","edx");
-+	&mul	(&DWP($r0,"esp"));		# h3*r0
-+	&add	("esi","eax");
-+	 &mov	("ecx",&DWP($h4,"esp"));
-+	&adc	("edi","edx");
-+
-+	&mov	("edx","ecx");
-+	&imul	("ecx",&DWP($s3,"esp"));	# h4*s3
-+	&add	("esi","ecx");
-+	 &mov	("eax",&DWP($d0,"esp"));
-+	&adc	("edi",0);
-+
-+	&imul	("edx",&DWP($r0,"esp"));	# h4*r0
-+	&add	("edx","edi");
-+
-+	&mov	("ebx",&DWP($d1,"esp"));
-+	&mov	("ecx",&DWP($d2,"esp"));
-+
-+	&mov	("edi","edx");			# last reduction step
-+	&shr	("edx",2);
-+	&and	("edi",3);
-+	&lea	("edx",&DWP(0,"edx","edx",4));	# *5
-+	&add	("eax","edx");
-+	&adc	("ebx",0);
-+	&adc	("ecx",0);
-+	&adc	("esi",0);
-+	&adc	("edi",0);
-+
-+	&cmp	("ebp",&wparam(2));		# done yet?
-+	&jne	(&label("loop"));
-+
-+	&mov	("edx",&wparam(0));		# ctx
-+	&stack_pop(16);
-+	&mov	(&DWP(4*0,"edx"),"eax");	# store hash value
-+	&mov	(&DWP(4*1,"edx"),"ebx");
-+	&mov	(&DWP(4*2,"edx"),"ecx");
-+	&mov	(&DWP(4*3,"edx"),"esi");
-+	&mov	(&DWP(4*4,"edx"),"edi");
-+&set_label("nodata");
-+&function_end("poly1305_blocks");
-+
-+&function_begin("poly1305_emit");
-+	&mov	("ebp",&wparam(0));		# context
-+&set_label("enter_emit");
-+	&mov	("edi",&wparam(1));		# output
-+	&mov	("eax",&DWP(4*0,"ebp"));	# load hash value
-+	&mov	("ebx",&DWP(4*1,"ebp"));
-+	&mov	("ecx",&DWP(4*2,"ebp"));
-+	&mov	("edx",&DWP(4*3,"ebp"));
-+	&mov	("esi",&DWP(4*4,"ebp"));
-+
-+	&add	("eax",5);			# compare to modulus
-+	&adc	("ebx",0);
-+	&adc	("ecx",0);
-+	&adc	("edx",0);
-+	&adc	("esi",0);
-+	&shr	("esi",2);			# did it carry/borrow?
-+	&neg	("esi");			# do we choose hash-modulus?
-+
-+	&and	("eax","esi");
-+	&and	("ebx","esi");
-+	&and	("ecx","esi");
-+	&and	("edx","esi");
-+	&mov	(&DWP(4*0,"edi"),"eax");
-+	&mov	(&DWP(4*1,"edi"),"ebx");
-+	&mov	(&DWP(4*2,"edi"),"ecx");
-+	&mov	(&DWP(4*3,"edi"),"edx");
-+
-+	¬	("esi");			# or original hash value?
-+	&mov	("eax",&DWP(4*0,"ebp"));
-+	&mov	("ebx",&DWP(4*1,"ebp"));
-+	&mov	("ecx",&DWP(4*2,"ebp"));
-+	&mov	("edx",&DWP(4*3,"ebp"));
-+	&mov	("ebp",&wparam(2));
-+	&and	("eax","esi");
-+	&and	("ebx","esi");
-+	&and	("ecx","esi");
-+	&and	("edx","esi");
-+	&or	("eax",&DWP(4*0,"edi"));
-+	&or	("ebx",&DWP(4*1,"edi"));
-+	&or	("ecx",&DWP(4*2,"edi"));
-+	&or	("edx",&DWP(4*3,"edi"));
-+
-+	&add	("eax",&DWP(4*0,"ebp"));	# accumulate key
-+	&adc	("ebx",&DWP(4*1,"ebp"));
-+	&adc	("ecx",&DWP(4*2,"ebp"));
-+	&adc	("edx",&DWP(4*3,"ebp"));
-+
-+	&mov	(&DWP(4*0,"edi"),"eax");
-+	&mov	(&DWP(4*1,"edi"),"ebx");
-+	&mov	(&DWP(4*2,"edi"),"ecx");
-+	&mov	(&DWP(4*3,"edi"),"edx");
-+&function_end("poly1305_emit");
-+
-+if ($sse2) {
-+########################################################################
-+# Layout of opaque area is following.
-+#
-+#	unsigned __int32 h[5];		# current hash value base 2^26
-+#	unsigned __int32 is_base2_26;
-+#	unsigned __int32 r[4];		# key value base 2^32
-+#	unsigned __int32 pad[2];
-+#	struct { unsigned __int32 r^4, r^3, r^2, r^1; } r[9];
-+#
-+# where r^n are base 2^26 digits of degrees of multiplier key. There are
-+# 5 digits, but last four are interleaved with multiples of 5, totalling
-+# in 9 elements: r0, r1, 5*r1, r2, 5*r2, r3, 5*r3, r4, 5*r4.
-+
-+my ($D0,$D1,$D2,$D3,$D4,$T0,$T1,$T2)=map("xmm$_",(0..7));
-+my $MASK=$T2;	# borrow and keep in mind
-+
-+&align	(32);
-+&function_begin_B("_poly1305_init_sse2");
-+	&movdqu		($D4,&QWP(4*6,"edi"));		# key base 2^32
-+	&lea		("edi",&DWP(16*3,"edi"));	# size optimization
-+	&mov		("ebp","esp");
-+	&sub		("esp",16*(9+5));
-+	&and		("esp",-16);
-+
-+	#&pand		($D4,&QWP(96,"ebx"));		# magic mask
-+	&movq		($MASK,&QWP(64,"ebx"));
-+
-+	&movdqa		($D0,$D4);
-+	&movdqa		($D1,$D4);
-+	&movdqa		($D2,$D4);
-+
-+	&pand		($D0,$MASK);			# -> base 2^26
-+	&psrlq		($D1,26);
-+	&psrldq		($D2,6);
-+	&pand		($D1,$MASK);
-+	&movdqa		($D3,$D2);
-+	&psrlq		($D2,4)
-+	&psrlq		($D3,30);
-+	&pand		($D2,$MASK);
-+	&pand		($D3,$MASK);
-+	&psrldq		($D4,13);
-+
-+	&lea		("edx",&DWP(16*9,"esp"));	# size optimization
-+	&mov		("ecx",2);
-+&set_label("square");
-+	&movdqa		(&QWP(16*0,"esp"),$D0);
-+	&movdqa		(&QWP(16*1,"esp"),$D1);
-+	&movdqa		(&QWP(16*2,"esp"),$D2);
-+	&movdqa		(&QWP(16*3,"esp"),$D3);
-+	&movdqa		(&QWP(16*4,"esp"),$D4);
-+
-+	&movdqa		($T1,$D1);
-+	&movdqa		($T0,$D2);
-+	&pslld		($T1,2);
-+	&pslld		($T0,2);
-+	&paddd		($T1,$D1);			# *5
-+	&paddd		($T0,$D2);			# *5
-+	&movdqa		(&QWP(16*5,"esp"),$T1);
-+	&movdqa		(&QWP(16*6,"esp"),$T0);
-+	&movdqa		($T1,$D3);
-+	&movdqa		($T0,$D4);
-+	&pslld		($T1,2);
-+	&pslld		($T0,2);
-+	&paddd		($T1,$D3);			# *5
-+	&paddd		($T0,$D4);			# *5
-+	&movdqa		(&QWP(16*7,"esp"),$T1);
-+	&movdqa		(&QWP(16*8,"esp"),$T0);
-+
-+	&pshufd		($T1,$D0,0b01000100);
-+	&movdqa		($T0,$D1);
-+	&pshufd		($D1,$D1,0b01000100);
-+	&pshufd		($D2,$D2,0b01000100);
-+	&pshufd		($D3,$D3,0b01000100);
-+	&pshufd		($D4,$D4,0b01000100);
-+	&movdqa		(&QWP(16*0,"edx"),$T1);
-+	&movdqa		(&QWP(16*1,"edx"),$D1);
-+	&movdqa		(&QWP(16*2,"edx"),$D2);
-+	&movdqa		(&QWP(16*3,"edx"),$D3);
-+	&movdqa		(&QWP(16*4,"edx"),$D4);
-+
-+	################################################################
-+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
-+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
-+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
-+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
-+
-+	&pmuludq	($D4,$D0);			# h4*r0
-+	&pmuludq	($D3,$D0);			# h3*r0
-+	&pmuludq	($D2,$D0);			# h2*r0
-+	&pmuludq	($D1,$D0);			# h1*r0
-+	&pmuludq	($D0,$T1);			# h0*r0
-+
-+sub pmuladd {
-+my $load = shift;
-+my $base = shift; $base = "esp" if (!defined($base));
-+
-+	################################################################
-+	# As for choice to "rotate" $T0-$T2 in order to move paddq
-+	# past next multiplication. While it makes code harder to read
-+	# and doesn't have significant effect on most processors, it
-+	# makes a lot of difference on Atom, up to 30% improvement.
-+
-+	&movdqa		($T1,$T0);
-+	&pmuludq	($T0,&QWP(16*3,$base));		# r1*h3
-+	&movdqa		($T2,$T1);
-+	&pmuludq	($T1,&QWP(16*2,$base));		# r1*h2
-+	&paddq		($D4,$T0);
-+	&movdqa		($T0,$T2);
-+	&pmuludq	($T2,&QWP(16*1,$base));		# r1*h1
-+	&paddq		($D3,$T1);
-+	&$load		($T1,5);			# s1
-+	&pmuludq	($T0,&QWP(16*0,$base));		# r1*h0
-+	&paddq		($D2,$T2);
-+	&pmuludq	($T1,&QWP(16*4,$base));		# s1*h4
-+	 &$load		($T2,2);			# r2^n
-+	&paddq		($D1,$T0);
-+
-+	&movdqa		($T0,$T2);
-+	&pmuludq	($T2,&QWP(16*2,$base));		# r2*h2
-+	 &paddq		($D0,$T1);
-+	&movdqa		($T1,$T0);
-+	&pmuludq	($T0,&QWP(16*1,$base));		# r2*h1
-+	&paddq		($D4,$T2);
-+	&$load		($T2,6);			# s2^n
-+	&pmuludq	($T1,&QWP(16*0,$base));		# r2*h0
-+	&paddq		($D3,$T0);
-+	&movdqa		($T0,$T2);
-+	&pmuludq	($T2,&QWP(16*4,$base));		# s2*h4
-+	&paddq		($D2,$T1);
-+	&pmuludq	($T0,&QWP(16*3,$base));		# s2*h3
-+	 &$load		($T1,3);			# r3^n
-+	&paddq		($D1,$T2);
-+
-+	&movdqa		($T2,$T1);
-+	&pmuludq	($T1,&QWP(16*1,$base));		# r3*h1
-+	 &paddq		($D0,$T0);
-+	&$load		($T0,7);			# s3^n
-+	&pmuludq	($T2,&QWP(16*0,$base));		# r3*h0
-+	&paddq		($D4,$T1);
-+	&movdqa		($T1,$T0);
-+	&pmuludq	($T0,&QWP(16*4,$base));		# s3*h4
-+	&paddq		($D3,$T2);
-+	&movdqa		($T2,$T1);
-+	&pmuludq	($T1,&QWP(16*3,$base));		# s3*h3
-+	&paddq		($D2,$T0);
-+	&pmuludq	($T2,&QWP(16*2,$base));		# s3*h2
-+	 &$load		($T0,4);			# r4^n
-+	&paddq		($D1,$T1);
-+
-+	&$load		($T1,8);			# s4^n
-+	&pmuludq	($T0,&QWP(16*0,$base));		# r4*h0
-+	 &paddq		($D0,$T2);
-+	&movdqa		($T2,$T1);
-+	&pmuludq	($T1,&QWP(16*4,$base));		# s4*h4
-+	&paddq		($D4,$T0);
-+	&movdqa		($T0,$T2);
-+	&pmuludq	($T2,&QWP(16*1,$base));		# s4*h1
-+	&paddq		($D3,$T1);
-+	&movdqa		($T1,$T0);
-+	&pmuludq	($T0,&QWP(16*2,$base));		# s4*h2
-+	&paddq		($D0,$T2);
-+	&pmuludq	($T1,&QWP(16*3,$base));		# s4*h3
-+	 &movdqa	($MASK,&QWP(64,"ebx"));
-+	&paddq		($D1,$T0);
-+	&paddq		($D2,$T1);
-+}
-+	&pmuladd	(sub {	my ($reg,$i)=@_;
-+				&movdqa ($reg,&QWP(16*$i,"esp"));
-+			     },"edx");
-+
-+sub lazy_reduction {
-+my $extra = shift;
-+
-+	################################################################
-+	# lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
-+	# and P. Schwabe
-+	#
-+	# [(*) see discussion in poly1305-armv4 module]
-+
-+	 &movdqa	($T0,$D3);
-+	 &pand		($D3,$MASK);
-+	 &psrlq		($T0,26);
-+	 &$extra	()				if (defined($extra));
-+	 &paddq		($T0,$D4);			# h3 -> h4
-+	&movdqa		($T1,$D0);
-+	&pand		($D0,$MASK);
-+	&psrlq		($T1,26);
-+	 &movdqa	($D4,$T0);
-+	&paddq		($T1,$D1);			# h0 -> h1
-+	 &psrlq		($T0,26);
-+	 &pand		($D4,$MASK);
-+	&movdqa		($D1,$T1);
-+	&psrlq		($T1,26);
-+	 &paddd		($D0,$T0);			# favour paddd when
-+							# possible, because
-+							# paddq is "broken"
-+							# on Atom
-+	 &psllq		($T0,2);
-+	&paddq		($T1,$D2);			# h1 -> h2
-+	 &paddq		($T0,$D0);			# h4 -> h0 (*)
-+	&pand		($D1,$MASK);
-+	&movdqa		($D2,$T1);
-+	&psrlq		($T1,26);
-+	&pand		($D2,$MASK);
-+	&paddd		($T1,$D3);			# h2 -> h3
-+	 &movdqa	($D0,$T0);
-+	 &psrlq		($T0,26);
-+	&movdqa		($D3,$T1);
-+	&psrlq		($T1,26);
-+	 &pand		($D0,$MASK);
-+	 &paddd		($D1,$T0);			# h0 -> h1
-+	&pand		($D3,$MASK);
-+	&paddd		($D4,$T1);			# h3 -> h4
-+}
-+	&lazy_reduction	();
-+
-+	&dec		("ecx");
-+	&jz		(&label("square_break"));
-+
-+	&punpcklqdq	($D0,&QWP(16*0,"esp"));		# 0:r^1:0:r^2
-+	&punpcklqdq	($D1,&QWP(16*1,"esp"));
-+	&punpcklqdq	($D2,&QWP(16*2,"esp"));
-+	&punpcklqdq	($D3,&QWP(16*3,"esp"));
-+	&punpcklqdq	($D4,&QWP(16*4,"esp"));
-+	&jmp		(&label("square"));
-+
-+&set_label("square_break");
-+	&psllq		($D0,32);			# -> r^3:0:r^4:0
-+	&psllq		($D1,32);
-+	&psllq		($D2,32);
-+	&psllq		($D3,32);
-+	&psllq		($D4,32);
-+	&por		($D0,&QWP(16*0,"esp"));		# r^3:r^1:r^4:r^2
-+	&por		($D1,&QWP(16*1,"esp"));
-+	&por		($D2,&QWP(16*2,"esp"));
-+	&por		($D3,&QWP(16*3,"esp"));
-+	&por		($D4,&QWP(16*4,"esp"));
-+
-+	&pshufd		($D0,$D0,0b10001101);		# -> r^1:r^2:r^3:r^4
-+	&pshufd		($D1,$D1,0b10001101);
-+	&pshufd		($D2,$D2,0b10001101);
-+	&pshufd		($D3,$D3,0b10001101);
-+	&pshufd		($D4,$D4,0b10001101);
-+
-+	&movdqu		(&QWP(16*0,"edi"),$D0);		# save the table
-+	&movdqu		(&QWP(16*1,"edi"),$D1);
-+	&movdqu		(&QWP(16*2,"edi"),$D2);
-+	&movdqu		(&QWP(16*3,"edi"),$D3);
-+	&movdqu		(&QWP(16*4,"edi"),$D4);
-+
-+	&movdqa		($T1,$D1);
-+	&movdqa		($T0,$D2);
-+	&pslld		($T1,2);
-+	&pslld		($T0,2);
-+	&paddd		($T1,$D1);			# *5
-+	&paddd		($T0,$D2);			# *5
-+	&movdqu		(&QWP(16*5,"edi"),$T1);
-+	&movdqu		(&QWP(16*6,"edi"),$T0);
-+	&movdqa		($T1,$D3);
-+	&movdqa		($T0,$D4);
-+	&pslld		($T1,2);
-+	&pslld		($T0,2);
-+	&paddd		($T1,$D3);			# *5
-+	&paddd		($T0,$D4);			# *5
-+	&movdqu		(&QWP(16*7,"edi"),$T1);
-+	&movdqu		(&QWP(16*8,"edi"),$T0);
-+
-+	&mov		("esp","ebp");
-+	&lea		("edi",&DWP(-16*3,"edi"));	# size de-optimization
-+	&ret		();
-+&function_end_B("_poly1305_init_sse2");
-+
-+&align	(32);
-+&function_begin("_poly1305_blocks_sse2");
-+	&mov	("edi",&wparam(0));			# ctx
-+	&mov	("esi",&wparam(1));			# inp
-+	&mov	("ecx",&wparam(2));			# len
-+
-+	&mov	("eax",&DWP(4*5,"edi"));		# is_base2_26
-+	&and	("ecx",-16);
-+	&jz	(&label("nodata"));
-+	&cmp	("ecx",64);
-+	&jae	(&label("enter_sse2"));
-+	&test	("eax","eax");				# is_base2_26?
-+	&jz	(&label("enter_blocks"));
-+
-+&set_label("enter_sse2",16);
-+	&call	(&label("pic_point"));
-+&set_label("pic_point");
-+	&blindpop("ebx");
-+	&lea	("ebx",&DWP(&label("const_sse2")."-".&label("pic_point"),"ebx"));
-+
-+	&test	("eax","eax");				# is_base2_26?
-+	&jnz	(&label("base2_26"));
-+
-+	&call	("_poly1305_init_sse2");
-+
-+	################################################# base 2^32 -> base 2^26
-+	&mov	("eax",&DWP(0,"edi"));
-+	&mov	("ecx",&DWP(3,"edi"));
-+	&mov	("edx",&DWP(6,"edi"));
-+	&mov	("esi",&DWP(9,"edi"));
-+	&mov	("ebp",&DWP(13,"edi"));
-+	&mov	(&DWP(4*5,"edi"),1);			# is_base2_26
-+
-+	&shr	("ecx",2);
-+	&and	("eax",0x3ffffff);
-+	&shr	("edx",4);
-+	&and	("ecx",0x3ffffff);
-+	&shr	("esi",6);
-+	&and	("edx",0x3ffffff);
-+
-+	&movd	($D0,"eax");
-+	&movd	($D1,"ecx");
-+	&movd	($D2,"edx");
-+	&movd	($D3,"esi");
-+	&movd	($D4,"ebp");
-+
-+	&mov	("esi",&wparam(1));			# [reload] inp
-+	&mov	("ecx",&wparam(2));			# [reload] len
-+	&jmp	(&label("base2_32"));
-+
-+&set_label("base2_26",16);
-+	&movd	($D0,&DWP(4*0,"edi"));			# load hash value
-+	&movd	($D1,&DWP(4*1,"edi"));
-+	&movd	($D2,&DWP(4*2,"edi"));
-+	&movd	($D3,&DWP(4*3,"edi"));
-+	&movd	($D4,&DWP(4*4,"edi"));
-+	&movdqa	($MASK,&QWP(64,"ebx"));
-+
-+&set_label("base2_32");
-+	&mov	("eax",&wparam(3));			# padbit
-+	&mov	("ebp","esp");
-+
-+	&sub	("esp",16*(5+5+5+9+9));
-+	&and	("esp",-16);
-+
-+	&lea	("edi",&DWP(16*3,"edi"));		# size optimization
-+	&shl	("eax",24);				# padbit
-+
-+	&test	("ecx",31);
-+	&jz	(&label("even"));
-+
-+	################################################################
-+	# process single block, with SSE2, because it's still faster
-+	# even though half of result is discarded
-+
-+	&movdqu		($T1,&QWP(0,"esi"));		# input
-+	&lea		("esi",&DWP(16,"esi"));
-+
-+	&movdqa		($T0,$T1);			# -> base 2^26 ...
-+	&pand		($T1,$MASK);
-+	&paddd		($D0,$T1);			# ... and accumuate
-+
-+	&movdqa		($T1,$T0);
-+	&psrlq		($T0,26);
-+	&psrldq		($T1,6);
-+	&pand		($T0,$MASK);
-+	&paddd		($D1,$T0);
-+
-+	&movdqa		($T0,$T1);
-+	&psrlq		($T1,4);
-+	&pand		($T1,$MASK);
-+	&paddd		($D2,$T1);
-+
-+	&movdqa		($T1,$T0);
-+	&psrlq		($T0,30);
-+	&pand		($T0,$MASK);
-+	&psrldq		($T1,7);
-+	&paddd		($D3,$T0);
-+
-+	&movd		($T0,"eax");			# padbit
-+	&paddd		($D4,$T1);
-+	 &movd		($T1,&DWP(16*0+12,"edi"));	# r0
-+	&paddd		($D4,$T0);
-+
-+	&movdqa		(&QWP(16*0,"esp"),$D0);
-+	&movdqa		(&QWP(16*1,"esp"),$D1);
-+	&movdqa		(&QWP(16*2,"esp"),$D2);
-+	&movdqa		(&QWP(16*3,"esp"),$D3);
-+	&movdqa		(&QWP(16*4,"esp"),$D4);
-+
-+	################################################################
-+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
-+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
-+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
-+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
-+
-+	&pmuludq	($D0,$T1);			# h4*r0
-+	&pmuludq	($D1,$T1);			# h3*r0
-+	&pmuludq	($D2,$T1);			# h2*r0
-+	 &movd		($T0,&DWP(16*1+12,"edi"));	# r1
-+	&pmuludq	($D3,$T1);			# h1*r0
-+	&pmuludq	($D4,$T1);			# h0*r0
-+
-+	&pmuladd	(sub {	my ($reg,$i)=@_;
-+				&movd ($reg,&DWP(16*$i+12,"edi"));
-+			     });
-+
-+	&lazy_reduction	();
-+
-+	&sub		("ecx",16);
-+	&jz		(&label("done"));
-+
-+&set_label("even");
-+	&lea		("edx",&DWP(16*(5+5+5+9),"esp"));# size optimization
-+	&lea		("eax",&DWP(-16*2,"esi"));
-+	&sub		("ecx",64);
-+
-+	################################################################
-+	# expand and copy pre-calculated table to stack
-+
-+	&movdqu		($T0,&QWP(16*0,"edi"));		# r^1:r^2:r^3:r^4
-+	&pshufd		($T1,$T0,0b01000100);		# duplicate r^3:r^4
-+	&cmovb		("esi","eax");
-+	&pshufd		($T0,$T0,0b11101110);		# duplicate r^1:r^2
-+	&movdqa		(&QWP(16*0,"edx"),$T1);
-+	&lea		("eax",&DWP(16*10,"esp"));
-+	&movdqu		($T1,&QWP(16*1,"edi"));
-+	&movdqa		(&QWP(16*(0-9),"edx"),$T0);
-+	&pshufd		($T0,$T1,0b01000100);
-+	&pshufd		($T1,$T1,0b11101110);
-+	&movdqa		(&QWP(16*1,"edx"),$T0);
-+	&movdqu		($T0,&QWP(16*2,"edi"));
-+	&movdqa		(&QWP(16*(1-9),"edx"),$T1);
-+	&pshufd		($T1,$T0,0b01000100);
-+	&pshufd		($T0,$T0,0b11101110);
-+	&movdqa		(&QWP(16*2,"edx"),$T1);
-+	&movdqu		($T1,&QWP(16*3,"edi"));
-+	&movdqa		(&QWP(16*(2-9),"edx"),$T0);
-+	&pshufd		($T0,$T1,0b01000100);
-+	&pshufd		($T1,$T1,0b11101110);
-+	&movdqa		(&QWP(16*3,"edx"),$T0);
-+	&movdqu		($T0,&QWP(16*4,"edi"));
-+	&movdqa		(&QWP(16*(3-9),"edx"),$T1);
-+	&pshufd		($T1,$T0,0b01000100);
-+	&pshufd		($T0,$T0,0b11101110);
-+	&movdqa		(&QWP(16*4,"edx"),$T1);
-+	&movdqu		($T1,&QWP(16*5,"edi"));
-+	&movdqa		(&QWP(16*(4-9),"edx"),$T0);
-+	&pshufd		($T0,$T1,0b01000100);
-+	&pshufd		($T1,$T1,0b11101110);
-+	&movdqa		(&QWP(16*5,"edx"),$T0);
-+	&movdqu		($T0,&QWP(16*6,"edi"));
-+	&movdqa		(&QWP(16*(5-9),"edx"),$T1);
-+	&pshufd		($T1,$T0,0b01000100);
-+	&pshufd		($T0,$T0,0b11101110);
-+	&movdqa		(&QWP(16*6,"edx"),$T1);
-+	&movdqu		($T1,&QWP(16*7,"edi"));
-+	&movdqa		(&QWP(16*(6-9),"edx"),$T0);
-+	&pshufd		($T0,$T1,0b01000100);
-+	&pshufd		($T1,$T1,0b11101110);
-+	&movdqa		(&QWP(16*7,"edx"),$T0);
-+	&movdqu		($T0,&QWP(16*8,"edi"));
-+	&movdqa		(&QWP(16*(7-9),"edx"),$T1);
-+	&pshufd		($T1,$T0,0b01000100);
-+	&pshufd		($T0,$T0,0b11101110);
-+	&movdqa		(&QWP(16*8,"edx"),$T1);
-+	&movdqa		(&QWP(16*(8-9),"edx"),$T0);
-+
-+sub load_input {
-+my ($inpbase,$offbase)=@_;
-+
-+	&movdqu		($T0,&QWP($inpbase+0,"esi"));	# load input
-+	&movdqu		($T1,&QWP($inpbase+16,"esi"));
-+	&lea		("esi",&DWP(16*2,"esi"));
-+
-+	&movdqa		(&QWP($offbase+16*2,"esp"),$D2);
-+	&movdqa		(&QWP($offbase+16*3,"esp"),$D3);
-+	&movdqa		(&QWP($offbase+16*4,"esp"),$D4);
-+
-+	&movdqa		($D2,$T0);			# splat input
-+	&movdqa		($D3,$T1);
-+	&psrldq		($D2,6);
-+	&psrldq		($D3,6);
-+	&movdqa		($D4,$T0);
-+	&punpcklqdq	($D2,$D3);			# 2:3
-+	&punpckhqdq	($D4,$T1);			# 4
-+	&punpcklqdq	($T0,$T1);			# 0:1
-+
-+	&movdqa		($D3,$D2);
-+	&psrlq		($D2,4);
-+	&psrlq		($D3,30);
-+	&movdqa		($T1,$T0);
-+	&psrlq		($D4,40);			# 4
-+	&psrlq		($T1,26);
-+	&pand		($T0,$MASK);			# 0
-+	&pand		($T1,$MASK);			# 1
-+	&pand		($D2,$MASK);			# 2
-+	&pand		($D3,$MASK);			# 3
-+	&por		($D4,&QWP(0,"ebx"));		# padbit, yes, always
-+
-+	&movdqa		(&QWP($offbase+16*0,"esp"),$D0)	if ($offbase);
-+	&movdqa		(&QWP($offbase+16*1,"esp"),$D1)	if ($offbase);
-+}
-+	&load_input	(16*2,16*5);
-+
-+	&jbe		(&label("skip_loop"));
-+	&jmp		(&label("loop"));
-+
-+&set_label("loop",32);
-+	################################################################
-+	# ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
-+	# ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
-+	#   \___________________/
-+	# ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
-+	# ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
-+	#   \___________________/ \____________________/
-+	################################################################
-+
-+	&movdqa		($T2,&QWP(16*(0-9),"edx"));	# r0^2
-+	&movdqa		(&QWP(16*1,"eax"),$T1);
-+	&movdqa		(&QWP(16*2,"eax"),$D2);
-+	&movdqa		(&QWP(16*3,"eax"),$D3);
-+	&movdqa		(&QWP(16*4,"eax"),$D4);
-+
-+	################################################################
-+	# d4 = h4*r0 + h0*r4   + h1*r3   + h2*r2   + h3*r1
-+	# d3 = h3*r0 + h0*r3   + h1*r2   + h2*r1   + h4*5*r4
-+	# d2 = h2*r0 + h0*r2   + h1*r1   + h3*5*r4 + h4*5*r3
-+	# d1 = h1*r0 + h0*r1   + h2*5*r4 + h3*5*r3 + h4*5*r2
-+	# d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
-+
-+	&movdqa		($D1,$T0);
-+	&pmuludq	($T0,$T2);			# h0*r0
-+	&movdqa		($D0,$T1);
-+	&pmuludq	($T1,$T2);			# h1*r0
-+	&pmuludq	($D2,$T2);			# h2*r0
-+	&pmuludq	($D3,$T2);			# h3*r0
-+	&pmuludq	($D4,$T2);			# h4*r0
-+
-+sub pmuladd_alt {
-+my $addr = shift;
-+
-+	&pmuludq	($D0,&$addr(8));		# h1*s4
-+	&movdqa		($T2,$D1);
-+	&pmuludq	($D1,&$addr(1));		# h0*r1
-+	&paddq		($D0,$T0);
-+	&movdqa		($T0,$T2);
-+	&pmuludq	($T2,&$addr(2));		# h0*r2
-+	&paddq		($D1,$T1);
-+	&movdqa		($T1,$T0);
-+	&pmuludq	($T0,&$addr(3));		# h0*r3
-+	&paddq		($D2,$T2);
-+	 &movdqa	($T2,&QWP(16*1,"eax"));		# pull h1
-+	&pmuludq	($T1,&$addr(4));		# h0*r4
-+	&paddq		($D3,$T0);
-+
-+	&movdqa		($T0,$T2);
-+	&pmuludq	($T2,&$addr(1));		# h1*r1
-+	 &paddq		($D4,$T1);
-+	&movdqa		($T1,$T0);
-+	&pmuludq	($T0,&$addr(2));		# h1*r2
-+	&paddq		($D2,$T2);
-+	&movdqa		($T2,&QWP(16*2,"eax"));		# pull h2
-+	&pmuludq	($T1,&$addr(3));		# h1*r3
-+	&paddq		($D3,$T0);
-+	&movdqa		($T0,$T2);
-+	&pmuludq	($T2,&$addr(7));		# h2*s3
-+	&paddq		($D4,$T1);
-+	&movdqa		($T1,$T0);
-+	&pmuludq	($T0,&$addr(8));		# h2*s4
-+	&paddq		($D0,$T2);
-+
-+	&movdqa		($T2,$T1);
-+	&pmuludq	($T1,&$addr(1));		# h2*r1
-+	 &paddq		($D1,$T0);
-+	&movdqa		($T0,&QWP(16*3,"eax"));		# pull h3
-+	&pmuludq	($T2,&$addr(2));		# h2*r2
-+	&paddq		($D3,$T1);
-+	&movdqa		($T1,$T0);
-+	&pmuludq	($T0,&$addr(6));		# h3*s2
-+	&paddq		($D4,$T2);
-+	&movdqa		($T2,$T1);
-+	&pmuludq	($T1,&$addr(7));		# h3*s3
-+	&paddq		($D0,$T0);
-+	&movdqa		($T0,$T2);
-+	&pmuludq	($T2,&$addr(8));		# h3*s4
-+	&paddq		($D1,$T1);
-+
-+	&movdqa		($T1,&QWP(16*4,"eax"));		# pull h4
-+	&pmuludq	($T0,&$addr(1));		# h3*r1
-+	 &paddq		($D2,$T2);
-+	&movdqa		($T2,$T1);
-+	&pmuludq	($T1,&$addr(8));		# h4*s4
-+	&paddq		($D4,$T0);
-+	&movdqa		($T0,$T2);
-+	&pmuludq	($T2,&$addr(5));		# h4*s1
-+	&paddq		($D3,$T1);
-+	&movdqa		($T1,$T0);
-+	&pmuludq	($T0,&$addr(6));		# h4*s2
-+	&paddq		($D0,$T2);
-+	 &movdqa	($MASK,&QWP(64,"ebx"));
-+	&pmuludq	($T1,&$addr(7));		# h4*s3
-+	&paddq		($D1,$T0);
-+	&paddq		($D2,$T1);
-+}
-+	&pmuladd_alt	(sub {	my $i=shift; &QWP(16*($i-9),"edx");	});
-+
-+	&load_input	(-16*2,0);
-+	&lea		("eax",&DWP(-16*2,"esi"));
-+	&sub		("ecx",64);
-+
-+	&paddd		($T0,&QWP(16*(5+0),"esp"));	# add hash value
-+	&paddd		($T1,&QWP(16*(5+1),"esp"));
-+	&paddd		($D2,&QWP(16*(5+2),"esp"));
-+	&paddd		($D3,&QWP(16*(5+3),"esp"));
-+	&paddd		($D4,&QWP(16*(5+4),"esp"));
-+
-+	&cmovb		("esi","eax");
-+	&lea		("eax",&DWP(16*10,"esp"));
-+
-+	&movdqa		($T2,&QWP(16*0,"edx"));		# r0^4
-+	&movdqa		(&QWP(16*1,"esp"),$D1);
-+	&movdqa		(&QWP(16*1,"eax"),$T1);
-+	&movdqa		(&QWP(16*2,"eax"),$D2);
-+	&movdqa		(&QWP(16*3,"eax"),$D3);
-+	&movdqa		(&QWP(16*4,"eax"),$D4);
-+
-+	################################################################
-+	# d4 += h4*r0 + h0*r4   + h1*r3   + h2*r2   + h3*r1
-+	# d3 += h3*r0 + h0*r3   + h1*r2   + h2*r1   + h4*5*r4
-+	# d2 += h2*r0 + h0*r2   + h1*r1   + h3*5*r4 + h4*5*r3
-+	# d1 += h1*r0 + h0*r1   + h2*5*r4 + h3*5*r3 + h4*5*r2
-+	# d0 += h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
-+
-+	&movdqa		($D1,$T0);
-+	&pmuludq	($T0,$T2);			# h0*r0
-+	&paddq		($T0,$D0);
-+	&movdqa		($D0,$T1);
-+	&pmuludq	($T1,$T2);			# h1*r0
-+	&pmuludq	($D2,$T2);			# h2*r0
-+	&pmuludq	($D3,$T2);			# h3*r0
-+	&pmuludq	($D4,$T2);			# h4*r0
-+
-+	&paddq		($T1,&QWP(16*1,"esp"));
-+	&paddq		($D2,&QWP(16*2,"esp"));
-+	&paddq		($D3,&QWP(16*3,"esp"));
-+	&paddq		($D4,&QWP(16*4,"esp"));
-+
-+	&pmuladd_alt	(sub {	my $i=shift; &QWP(16*$i,"edx");	});
-+
-+	&lazy_reduction	();
-+
-+	&load_input	(16*2,16*5);
-+
-+	&ja		(&label("loop"));
-+
-+&set_label("skip_loop");
-+	################################################################
-+	# multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
-+
-+	 &pshufd	($T2,&QWP(16*(0-9),"edx"),0x10);# r0^n
-+	&add		("ecx",32);
-+	&jnz		(&label("long_tail"));
-+
-+	&paddd		($T0,$D0);			# add hash value
-+	&paddd		($T1,$D1);
-+	&paddd		($D2,&QWP(16*7,"esp"));
-+	&paddd		($D3,&QWP(16*8,"esp"));
-+	&paddd		($D4,&QWP(16*9,"esp"));
-+
-+&set_label("long_tail");
-+
-+	&movdqa		(&QWP(16*0,"eax"),$T0);
-+	&movdqa		(&QWP(16*1,"eax"),$T1);
-+	&movdqa		(&QWP(16*2,"eax"),$D2);
-+	&movdqa		(&QWP(16*3,"eax"),$D3);
-+	&movdqa		(&QWP(16*4,"eax"),$D4);
-+
-+	################################################################
-+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
-+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
-+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
-+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
-+
-+	&pmuludq	($T0,$T2);			# h0*r0
-+	&pmuludq	($T1,$T2);			# h1*r0
-+	&pmuludq	($D2,$T2);			# h2*r0
-+	&movdqa		($D0,$T0);
-+	 &pshufd	($T0,&QWP(16*(1-9),"edx"),0x10);# r1^n
-+	&pmuludq	($D3,$T2);			# h3*r0
-+	&movdqa		($D1,$T1);
-+	&pmuludq	($D4,$T2);			# h4*r0
-+
-+	&pmuladd	(sub {	my ($reg,$i)=@_;
-+				&pshufd ($reg,&QWP(16*($i-9),"edx"),0x10);
-+			     },"eax");
-+
-+	&jz		(&label("short_tail"));
-+
-+	&load_input	(-16*2,0);
-+
-+	 &pshufd	($T2,&QWP(16*0,"edx"),0x10);	# r0^n
-+	&paddd		($T0,&QWP(16*5,"esp"));		# add hash value
-+	&paddd		($T1,&QWP(16*6,"esp"));
-+	&paddd		($D2,&QWP(16*7,"esp"));
-+	&paddd		($D3,&QWP(16*8,"esp"));
-+	&paddd		($D4,&QWP(16*9,"esp"));
-+
-+	################################################################
-+	# multiply inp[0:1] by r^4:r^3 and accumulate
-+
-+	&movdqa		(&QWP(16*0,"esp"),$T0);
-+	&pmuludq	($T0,$T2);			# h0*r0
-+	&movdqa		(&QWP(16*1,"esp"),$T1);
-+	&pmuludq	($T1,$T2);			# h1*r0
-+	&paddq		($D0,$T0);
-+	&movdqa		($T0,$D2);
-+	&pmuludq	($D2,$T2);			# h2*r0
-+	&paddq		($D1,$T1);
-+	&movdqa		($T1,$D3);
-+	&pmuludq	($D3,$T2);			# h3*r0
-+	&paddq		($D2,&QWP(16*2,"esp"));
-+	&movdqa		(&QWP(16*2,"esp"),$T0);
-+	 &pshufd	($T0,&QWP(16*1,"edx"),0x10);	# r1^n
-+	&paddq		($D3,&QWP(16*3,"esp"));
-+	&movdqa		(&QWP(16*3,"esp"),$T1);
-+	&movdqa		($T1,$D4);
-+	&pmuludq	($D4,$T2);			# h4*r0
-+	&paddq		($D4,&QWP(16*4,"esp"));
-+	&movdqa		(&QWP(16*4,"esp"),$T1);
-+
-+	&pmuladd	(sub {	my ($reg,$i)=@_;
-+				&pshufd ($reg,&QWP(16*$i,"edx"),0x10);
-+			     });
-+
-+&set_label("short_tail");
-+
-+	################################################################
-+	# horizontal addition
-+
-+	&pshufd		($T1,$D4,0b01001110);
-+	&pshufd		($T0,$D3,0b01001110);
-+	&paddq		($D4,$T1);
-+	&paddq		($D3,$T0);
-+	&pshufd		($T1,$D0,0b01001110);
-+	&pshufd		($T0,$D1,0b01001110);
-+	&paddq		($D0,$T1);
-+	&paddq		($D1,$T0);
-+	&pshufd		($T1,$D2,0b01001110);
-+	#&paddq		($D2,$T1);
-+
-+	&lazy_reduction	(sub { &paddq ($D2,$T1) });
-+
-+&set_label("done");
-+	&movd		(&DWP(-16*3+4*0,"edi"),$D0);	# store hash value
-+	&movd		(&DWP(-16*3+4*1,"edi"),$D1);
-+	&movd		(&DWP(-16*3+4*2,"edi"),$D2);
-+	&movd		(&DWP(-16*3+4*3,"edi"),$D3);
-+	&movd		(&DWP(-16*3+4*4,"edi"),$D4);
-+	&mov	("esp","ebp");
-+&set_label("nodata");
-+&function_end("_poly1305_blocks_sse2");
-+
-+&align	(32);
-+&function_begin("_poly1305_emit_sse2");
-+	&mov	("ebp",&wparam(0));		# context
-+
-+	&cmp	(&DWP(4*5,"ebp"),0);		# is_base2_26?
-+	&je	(&label("enter_emit"));
-+
-+	&mov	("eax",&DWP(4*0,"ebp"));	# load hash value
-+	&mov	("edi",&DWP(4*1,"ebp"));
-+	&mov	("ecx",&DWP(4*2,"ebp"));
-+	&mov	("edx",&DWP(4*3,"ebp"));
-+	&mov	("esi",&DWP(4*4,"ebp"));
-+
-+	&mov	("ebx","edi");			# base 2^26 -> base 2^32
-+	&shl	("edi",26);
-+	&shr	("ebx",6);
-+	&add	("eax","edi");
-+	&mov	("edi","ecx");
-+	&adc	("ebx",0);
-+
-+	&shl	("edi",20);
-+	&shr	("ecx",12);
-+	&add	("ebx","edi");
-+	&mov	("edi","edx");
-+	&adc	("ecx",0);
-+
-+	&shl	("edi",14);
-+	&shr	("edx",18);
-+	&add	("ecx","edi");
-+	&mov	("edi","esi");
-+	&adc	("edx",0);
-+
-+	&shl	("edi",8);
-+	&shr	("esi",24);
-+	&add	("edx","edi");
-+	&adc	("esi",0);			# can be partially reduced
-+
-+	&mov	("edi","esi");			# final reduction
-+	&and	("esi",3);
-+	&shr	("edi",2);
-+	&lea	("ebp",&DWP(0,"edi","edi",4));	# *5
-+	 &mov	("edi",&wparam(1));		# output
-+	&add	("eax","ebp");
-+	 &mov	("ebp",&wparam(2));		# key
-+	&adc	("ebx",0);
-+	&adc	("ecx",0);
-+	&adc	("edx",0);
-+	&adc	("esi",0);
-+
-+	&movd	($D0,"eax");			# offload original hash value
-+	&add	("eax",5);			# compare to modulus
-+	&movd	($D1,"ebx");
-+	&adc	("ebx",0);
-+	&movd	($D2,"ecx");
-+	&adc	("ecx",0);
-+	&movd	($D3,"edx");
-+	&adc	("edx",0);
-+	&adc	("esi",0);
-+	&shr	("esi",2);			# did it carry/borrow?
-+
-+	&neg	("esi");			# do we choose (hash-modulus) ...
-+	&and	("eax","esi");
-+	&and	("ebx","esi");
-+	&and	("ecx","esi");
-+	&and	("edx","esi");
-+	&mov	(&DWP(4*0,"edi"),"eax");
-+	&movd	("eax",$D0);
-+	&mov	(&DWP(4*1,"edi"),"ebx");
-+	&movd	("ebx",$D1);
-+	&mov	(&DWP(4*2,"edi"),"ecx");
-+	&movd	("ecx",$D2);
-+	&mov	(&DWP(4*3,"edi"),"edx");
-+	&movd	("edx",$D3);
-+
-+	¬	("esi");			# ... or original hash value?
-+	&and	("eax","esi");
-+	&and	("ebx","esi");
-+	&or	("eax",&DWP(4*0,"edi"));
-+	&and	("ecx","esi");
-+	&or	("ebx",&DWP(4*1,"edi"));
-+	&and	("edx","esi");
-+	&or	("ecx",&DWP(4*2,"edi"));
-+	&or	("edx",&DWP(4*3,"edi"));
-+
-+	&add	("eax",&DWP(4*0,"ebp"));	# accumulate key
-+	&adc	("ebx",&DWP(4*1,"ebp"));
-+	&mov	(&DWP(4*0,"edi"),"eax");
-+	&adc	("ecx",&DWP(4*2,"ebp"));
-+	&mov	(&DWP(4*1,"edi"),"ebx");
-+	&adc	("edx",&DWP(4*3,"ebp"));
-+	&mov	(&DWP(4*2,"edi"),"ecx");
-+	&mov	(&DWP(4*3,"edi"),"edx");
-+&function_end("_poly1305_emit_sse2");
-+
-+if ($avx>1) {
-+########################################################################
-+# Note that poly1305_init_avx2 operates on %xmm, I could have used
-+# poly1305_init_sse2...
-+
-+&align	(32);
-+&function_begin_B("_poly1305_init_avx2");
-+	&vmovdqu	($D4,&QWP(4*6,"edi"));		# key base 2^32
-+	&lea		("edi",&DWP(16*3,"edi"));	# size optimization
-+	&mov		("ebp","esp");
-+	&sub		("esp",16*(9+5));
-+	&and		("esp",-16);
-+
-+	#&vpand		($D4,$D4,&QWP(96,"ebx"));	# magic mask
-+	&vmovdqa	($MASK,&QWP(64,"ebx"));
-+
-+	&vpand		($D0,$D4,$MASK);		# -> base 2^26
-+	&vpsrlq		($D1,$D4,26);
-+	&vpsrldq	($D3,$D4,6);
-+	&vpand		($D1,$D1,$MASK);
-+	&vpsrlq		($D2,$D3,4)
-+	&vpsrlq		($D3,$D3,30);
-+	&vpand		($D2,$D2,$MASK);
-+	&vpand		($D3,$D3,$MASK);
-+	&vpsrldq	($D4,$D4,13);
-+
-+	&lea		("edx",&DWP(16*9,"esp"));	# size optimization
-+	&mov		("ecx",2);
-+&set_label("square");
-+	&vmovdqa	(&QWP(16*0,"esp"),$D0);
-+	&vmovdqa	(&QWP(16*1,"esp"),$D1);
-+	&vmovdqa	(&QWP(16*2,"esp"),$D2);
-+	&vmovdqa	(&QWP(16*3,"esp"),$D3);
-+	&vmovdqa	(&QWP(16*4,"esp"),$D4);
-+
-+	&vpslld		($T1,$D1,2);
-+	&vpslld		($T0,$D2,2);
-+	&vpaddd		($T1,$T1,$D1);			# *5
-+	&vpaddd		($T0,$T0,$D2);			# *5
-+	&vmovdqa	(&QWP(16*5,"esp"),$T1);
-+	&vmovdqa	(&QWP(16*6,"esp"),$T0);
-+	&vpslld		($T1,$D3,2);
-+	&vpslld		($T0,$D4,2);
-+	&vpaddd		($T1,$T1,$D3);			# *5
-+	&vpaddd		($T0,$T0,$D4);			# *5
-+	&vmovdqa	(&QWP(16*7,"esp"),$T1);
-+	&vmovdqa	(&QWP(16*8,"esp"),$T0);
-+
-+	&vpshufd	($T0,$D0,0b01000100);
-+	&vmovdqa	($T1,$D1);
-+	&vpshufd	($D1,$D1,0b01000100);
-+	&vpshufd	($D2,$D2,0b01000100);
-+	&vpshufd	($D3,$D3,0b01000100);
-+	&vpshufd	($D4,$D4,0b01000100);
-+	&vmovdqa	(&QWP(16*0,"edx"),$T0);
-+	&vmovdqa	(&QWP(16*1,"edx"),$D1);
-+	&vmovdqa	(&QWP(16*2,"edx"),$D2);
-+	&vmovdqa	(&QWP(16*3,"edx"),$D3);
-+	&vmovdqa	(&QWP(16*4,"edx"),$D4);
-+
-+	################################################################
-+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
-+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
-+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
-+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
-+
-+	&vpmuludq	($D4,$D4,$D0);			# h4*r0
-+	&vpmuludq	($D3,$D3,$D0);			# h3*r0
-+	&vpmuludq	($D2,$D2,$D0);			# h2*r0
-+	&vpmuludq	($D1,$D1,$D0);			# h1*r0
-+	&vpmuludq	($D0,$T0,$D0);			# h0*r0
-+
-+	&vpmuludq	($T0,$T1,&QWP(16*3,"edx"));	# r1*h3
-+	&vpaddq		($D4,$D4,$T0);
-+	&vpmuludq	($T2,$T1,&QWP(16*2,"edx"));	# r1*h2
-+	&vpaddq		($D3,$D3,$T2);
-+	&vpmuludq	($T0,$T1,&QWP(16*1,"edx"));	# r1*h1
-+	&vpaddq		($D2,$D2,$T0);
-+	&vmovdqa	($T2,&QWP(16*5,"esp"));		# s1
-+	&vpmuludq	($T1,$T1,&QWP(16*0,"edx"));	# r1*h0
-+	&vpaddq		($D1,$D1,$T1);
-+	 &vmovdqa	($T0,&QWP(16*2,"esp"));		# r2
-+	&vpmuludq	($T2,$T2,&QWP(16*4,"edx"));	# s1*h4
-+	&vpaddq		($D0,$D0,$T2);
-+
-+	&vpmuludq	($T1,$T0,&QWP(16*2,"edx"));	# r2*h2
-+	&vpaddq		($D4,$D4,$T1);
-+	&vpmuludq	($T2,$T0,&QWP(16*1,"edx"));	# r2*h1
-+	&vpaddq		($D3,$D3,$T2);
-+	&vmovdqa	($T1,&QWP(16*6,"esp"));		# s2
-+	&vpmuludq	($T0,$T0,&QWP(16*0,"edx"));	# r2*h0
-+	&vpaddq		($D2,$D2,$T0);
-+	&vpmuludq	($T2,$T1,&QWP(16*4,"edx"));	# s2*h4
-+	&vpaddq		($D1,$D1,$T2);
-+	 &vmovdqa	($T0,&QWP(16*3,"esp"));		# r3
-+	&vpmuludq	($T1,$T1,&QWP(16*3,"edx"));	# s2*h3
-+	&vpaddq		($D0,$D0,$T1);
-+
-+	&vpmuludq	($T2,$T0,&QWP(16*1,"edx"));	# r3*h1
-+	&vpaddq		($D4,$D4,$T2);
-+	&vmovdqa	($T1,&QWP(16*7,"esp"));		# s3
-+	&vpmuludq	($T0,$T0,&QWP(16*0,"edx"));	# r3*h0
-+	&vpaddq		($D3,$D3,$T0);
-+	&vpmuludq	($T2,$T1,&QWP(16*4,"edx"));	# s3*h4
-+	&vpaddq		($D2,$D2,$T2);
-+	&vpmuludq	($T0,$T1,&QWP(16*3,"edx"));	# s3*h3
-+	&vpaddq		($D1,$D1,$T0);
-+	 &vmovdqa	($T2,&QWP(16*4,"esp"));		# r4
-+	&vpmuludq	($T1,$T1,&QWP(16*2,"edx"));	# s3*h2
-+	&vpaddq		($D0,$D0,$T1);
-+
-+	&vmovdqa	($T0,&QWP(16*8,"esp"));		# s4
-+	&vpmuludq	($T2,$T2,&QWP(16*0,"edx"));	# r4*h0
-+	&vpaddq		($D4,$D4,$T2);
-+	&vpmuludq	($T1,$T0,&QWP(16*4,"edx"));	# s4*h4
-+	&vpaddq		($D3,$D3,$T1);
-+	&vpmuludq	($T2,$T0,&QWP(16*1,"edx"));	# s4*h1
-+	&vpaddq		($D0,$D0,$T2);
-+	&vpmuludq	($T1,$T0,&QWP(16*2,"edx"));	# s4*h2
-+	&vpaddq		($D1,$D1,$T1);
-+	 &vmovdqa	($MASK,&QWP(64,"ebx"));
-+	&vpmuludq	($T0,$T0,&QWP(16*3,"edx"));	# s4*h3
-+	&vpaddq		($D2,$D2,$T0);
-+
-+	################################################################
-+	# lazy reduction
-+	 &vpsrlq	($T0,$D3,26);
-+	 &vpand		($D3,$D3,$MASK);
-+	&vpsrlq		($T1,$D0,26);
-+	&vpand		($D0,$D0,$MASK);
-+	 &vpaddq	($D4,$D4,$T0);			# h3 -> h4
-+	&vpaddq		($D1,$D1,$T1);			# h0 -> h1
-+	 &vpsrlq	($T0,$D4,26);
-+	 &vpand		($D4,$D4,$MASK);
-+	&vpsrlq		($T1,$D1,26);
-+	&vpand		($D1,$D1,$MASK);
-+	&vpaddq		($D2,$D2,$T1);			# h1 -> h2
-+	 &vpaddd	($D0,$D0,$T0);
-+	 &vpsllq	($T0,$T0,2);
-+	&vpsrlq		($T1,$D2,26);
-+	&vpand		($D2,$D2,$MASK);
-+	 &vpaddd	($D0,$D0,$T0);			# h4 -> h0
-+	&vpaddd		($D3,$D3,$T1);			# h2 -> h3
-+	&vpsrlq		($T1,$D3,26);
-+	 &vpsrlq	($T0,$D0,26);
-+	 &vpand		($D0,$D0,$MASK);
-+	&vpand		($D3,$D3,$MASK);
-+	 &vpaddd	($D1,$D1,$T0);			# h0 -> h1
-+	&vpaddd		($D4,$D4,$T1);			# h3 -> h4
-+
-+	&dec		("ecx");
-+	&jz		(&label("square_break"));
-+
-+	&vpunpcklqdq	($D0,$D0,&QWP(16*0,"esp"));	# 0:r^1:0:r^2
-+	&vpunpcklqdq	($D1,$D1,&QWP(16*1,"esp"));
-+	&vpunpcklqdq	($D2,$D2,&QWP(16*2,"esp"));
-+	&vpunpcklqdq	($D3,$D3,&QWP(16*3,"esp"));
-+	&vpunpcklqdq	($D4,$D4,&QWP(16*4,"esp"));
-+	&jmp		(&label("square"));
-+
-+&set_label("square_break");
-+	&vpsllq		($D0,$D0,32);			# -> r^3:0:r^4:0
-+	&vpsllq		($D1,$D1,32);
-+	&vpsllq		($D2,$D2,32);
-+	&vpsllq		($D3,$D3,32);
-+	&vpsllq		($D4,$D4,32);
-+	&vpor		($D0,$D0,&QWP(16*0,"esp"));	# r^3:r^1:r^4:r^2
-+	&vpor		($D1,$D1,&QWP(16*1,"esp"));
-+	&vpor		($D2,$D2,&QWP(16*2,"esp"));
-+	&vpor		($D3,$D3,&QWP(16*3,"esp"));
-+	&vpor		($D4,$D4,&QWP(16*4,"esp"));
-+
-+	&vpshufd	($D0,$D0,0b10001101);		# -> r^1:r^2:r^3:r^4
-+	&vpshufd	($D1,$D1,0b10001101);
-+	&vpshufd	($D2,$D2,0b10001101);
-+	&vpshufd	($D3,$D3,0b10001101);
-+	&vpshufd	($D4,$D4,0b10001101);
-+
-+	&vmovdqu	(&QWP(16*0,"edi"),$D0);		# save the table
-+	&vmovdqu	(&QWP(16*1,"edi"),$D1);
-+	&vmovdqu	(&QWP(16*2,"edi"),$D2);
-+	&vmovdqu	(&QWP(16*3,"edi"),$D3);
-+	&vmovdqu	(&QWP(16*4,"edi"),$D4);
-+
-+	&vpslld		($T1,$D1,2);
-+	&vpslld		($T0,$D2,2);
-+	&vpaddd		($T1,$T1,$D1);			# *5
-+	&vpaddd		($T0,$T0,$D2);			# *5
-+	&vmovdqu	(&QWP(16*5,"edi"),$T1);
-+	&vmovdqu	(&QWP(16*6,"edi"),$T0);
-+	&vpslld		($T1,$D3,2);
-+	&vpslld		($T0,$D4,2);
-+	&vpaddd		($T1,$T1,$D3);			# *5
-+	&vpaddd		($T0,$T0,$D4);			# *5
-+	&vmovdqu	(&QWP(16*7,"edi"),$T1);
-+	&vmovdqu	(&QWP(16*8,"edi"),$T0);
-+
-+	&mov		("esp","ebp");
-+	&lea		("edi",&DWP(-16*3,"edi"));	# size de-optimization
-+	&ret		();
-+&function_end_B("_poly1305_init_avx2");
-+
-+########################################################################
-+# now it's time to switch to %ymm
-+
-+my ($D0,$D1,$D2,$D3,$D4,$T0,$T1,$T2)=map("ymm$_",(0..7));
-+my $MASK=$T2;
-+
-+sub X { my $reg=shift; $reg=~s/^ymm/xmm/; $reg; }
-+
-+&align	(32);
-+&function_begin("_poly1305_blocks_avx2");
-+	&mov	("edi",&wparam(0));			# ctx
-+	&mov	("esi",&wparam(1));			# inp
-+	&mov	("ecx",&wparam(2));			# len
-+
-+	&mov	("eax",&DWP(4*5,"edi"));		# is_base2_26
-+	&and	("ecx",-16);
-+	&jz	(&label("nodata"));
-+	&cmp	("ecx",64);
-+	&jae	(&label("enter_avx2"));
-+	&test	("eax","eax");				# is_base2_26?
-+	&jz	(&label("enter_blocks"));
-+
-+&set_label("enter_avx2");
-+	&vzeroupper	();
-+
-+	&call	(&label("pic_point"));
-+&set_label("pic_point");
-+	&blindpop("ebx");
-+	&lea	("ebx",&DWP(&label("const_sse2")."-".&label("pic_point"),"ebx"));
-+
-+	&test	("eax","eax");				# is_base2_26?
-+	&jnz	(&label("base2_26"));
-+
-+	&call	("_poly1305_init_avx2");
-+
-+	################################################# base 2^32 -> base 2^26
-+	&mov	("eax",&DWP(0,"edi"));
-+	&mov	("ecx",&DWP(3,"edi"));
-+	&mov	("edx",&DWP(6,"edi"));
-+	&mov	("esi",&DWP(9,"edi"));
-+	&mov	("ebp",&DWP(13,"edi"));
-+
-+	&shr	("ecx",2);
-+	&and	("eax",0x3ffffff);
-+	&shr	("edx",4);
-+	&and	("ecx",0x3ffffff);
-+	&shr	("esi",6);
-+	&and	("edx",0x3ffffff);
-+
-+	&mov	(&DWP(4*0,"edi"),"eax");
-+	&mov	(&DWP(4*1,"edi"),"ecx");
-+	&mov	(&DWP(4*2,"edi"),"edx");
-+	&mov	(&DWP(4*3,"edi"),"esi");
-+	&mov	(&DWP(4*4,"edi"),"ebp");
-+	&mov	(&DWP(4*5,"edi"),1);			# is_base2_26
-+
-+	&mov	("esi",&wparam(1));			# [reload] inp
-+	&mov	("ecx",&wparam(2));			# [reload] len
-+
-+&set_label("base2_26");
-+	&mov	("eax",&wparam(3));			# padbit
-+	&mov	("ebp","esp");
-+
-+	&sub	("esp",32*(5+9));
-+	&and	("esp",-512);				# ensure that frame
-+							# doesn't cross page
-+							# boundary, which is
-+							# essential for
-+							# misaligned 32-byte
-+							# loads
-+
-+	################################################################
-+        # expand and copy pre-calculated table to stack
-+
-+	&vmovdqu	(&X($D0),&QWP(16*(3+0),"edi"));
-+	&lea		("edx",&DWP(32*5+128,"esp"));	# +128 size optimization
-+	&vmovdqu	(&X($D1),&QWP(16*(3+1),"edi"));
-+	&vmovdqu	(&X($D2),&QWP(16*(3+2),"edi"));
-+	&vmovdqu	(&X($D3),&QWP(16*(3+3),"edi"));
-+	&vmovdqu	(&X($D4),&QWP(16*(3+4),"edi"));
-+	&lea		("edi",&DWP(16*3,"edi"));	# size optimization
-+	&vpermq		($D0,$D0,0b01000000);		# 00001234 -> 12343434
-+	&vpermq		($D1,$D1,0b01000000);
-+	&vpermq		($D2,$D2,0b01000000);
-+	&vpermq		($D3,$D3,0b01000000);
-+	&vpermq		($D4,$D4,0b01000000);
-+	&vpshufd	($D0,$D0,0b11001000);		# 12343434 -> 14243444
-+	&vpshufd	($D1,$D1,0b11001000);
-+	&vpshufd	($D2,$D2,0b11001000);
-+	&vpshufd	($D3,$D3,0b11001000);
-+	&vpshufd	($D4,$D4,0b11001000);
-+	&vmovdqa	(&QWP(32*0-128,"edx"),$D0);
-+	&vmovdqu	(&X($D0),&QWP(16*5,"edi"));
-+	&vmovdqa	(&QWP(32*1-128,"edx"),$D1);
-+	&vmovdqu	(&X($D1),&QWP(16*6,"edi"));
-+	&vmovdqa	(&QWP(32*2-128,"edx"),$D2);
-+	&vmovdqu	(&X($D2),&QWP(16*7,"edi"));
-+	&vmovdqa	(&QWP(32*3-128,"edx"),$D3);
-+	&vmovdqu	(&X($D3),&QWP(16*8,"edi"));
-+	&vmovdqa	(&QWP(32*4-128,"edx"),$D4);
-+	&vpermq		($D0,$D0,0b01000000);
-+	&vpermq		($D1,$D1,0b01000000);
-+	&vpermq		($D2,$D2,0b01000000);
-+	&vpermq		($D3,$D3,0b01000000);
-+	&vpshufd	($D0,$D0,0b11001000);
-+	&vpshufd	($D1,$D1,0b11001000);
-+	&vpshufd	($D2,$D2,0b11001000);
-+	&vpshufd	($D3,$D3,0b11001000);
-+	&vmovdqa	(&QWP(32*5-128,"edx"),$D0);
-+	&vmovd		(&X($D0),&DWP(-16*3+4*0,"edi"));# load hash value
-+	&vmovdqa	(&QWP(32*6-128,"edx"),$D1);
-+	&vmovd		(&X($D1),&DWP(-16*3+4*1,"edi"));
-+	&vmovdqa	(&QWP(32*7-128,"edx"),$D2);
-+	&vmovd		(&X($D2),&DWP(-16*3+4*2,"edi"));
-+	&vmovdqa	(&QWP(32*8-128,"edx"),$D3);
-+	&vmovd		(&X($D3),&DWP(-16*3+4*3,"edi"));
-+	&vmovd		(&X($D4),&DWP(-16*3+4*4,"edi"));
-+	&vmovdqa	($MASK,&QWP(64,"ebx"));
-+	&neg		("eax");			# padbit
-+
-+	&test		("ecx",63);
-+	&jz		(&label("even"));
-+
-+	&mov		("edx","ecx");
-+	&and		("ecx",-64);
-+	&and		("edx",63);
-+
-+	&vmovdqu	(&X($T0),&QWP(16*0,"esi"));
-+	&cmp		("edx",32);
-+	&jb		(&label("one"));
-+
-+	&vmovdqu	(&X($T1),&QWP(16*1,"esi"));
-+	&je		(&label("two"));
-+
-+	&vinserti128	($T0,$T0,&QWP(16*2,"esi"),1);
-+	&lea		("esi",&DWP(16*3,"esi"));
-+	&lea		("ebx",&DWP(8,"ebx"));		# three padbits
-+	&lea		("edx",&DWP(32*5+128+8,"esp"));	# --:r^1:r^2:r^3 (*)
-+	&jmp		(&label("tail"));
-+
-+&set_label("two");
-+	&lea		("esi",&DWP(16*2,"esi"));
-+	&lea		("ebx",&DWP(16,"ebx"));		# two padbits
-+	&lea		("edx",&DWP(32*5+128+16,"esp"));# --:--:r^1:r^2 (*)
-+	&jmp		(&label("tail"));
-+
-+&set_label("one");
-+	&lea		("esi",&DWP(16*1,"esi"));
-+	&vpxor		($T1,$T1,$T1);
-+	&lea		("ebx",&DWP(32,"ebx","eax",8));	# one or no padbits
-+	&lea		("edx",&DWP(32*5+128+24,"esp"));# --:--:--:r^1 (*)
-+	&jmp		(&label("tail"));
-+
-+# (*)	spots marked with '--' are data from next table entry, but they
-+#	are multiplied by 0 and therefore rendered insignificant
-+
-+&set_label("even",32);
-+	&vmovdqu	(&X($T0),&QWP(16*0,"esi"));	# load input
-+	&vmovdqu	(&X($T1),&QWP(16*1,"esi"));
-+	&vinserti128	($T0,$T0,&QWP(16*2,"esi"),1);
-+	&vinserti128	($T1,$T1,&QWP(16*3,"esi"),1);
-+	&lea		("esi",&DWP(16*4,"esi"));
-+	&sub		("ecx",64);
-+	&jz		(&label("tail"));
-+
-+&set_label("loop");
-+	################################################################
-+	# ((inp[0]*r^4+r[4])*r^4+r[8])*r^4
-+	# ((inp[1]*r^4+r[5])*r^4+r[9])*r^3
-+	# ((inp[2]*r^4+r[6])*r^4+r[10])*r^2
-+	# ((inp[3]*r^4+r[7])*r^4+r[11])*r^1
-+	#   \________/ \_______/
-+	################################################################
-+
-+sub vsplat_input {
-+	&vmovdqa	(&QWP(32*2,"esp"),$D2);
-+	&vpsrldq	($D2,$T0,6);			# splat input
-+	&vmovdqa	(&QWP(32*0,"esp"),$D0);
-+	&vpsrldq	($D0,$T1,6);
-+	&vmovdqa	(&QWP(32*1,"esp"),$D1);
-+	&vpunpckhqdq	($D1,$T0,$T1);			# 4
-+	&vpunpcklqdq	($T0,$T0,$T1);			# 0:1
-+	&vpunpcklqdq	($D2,$D2,$D0);			# 2:3
-+
-+	&vpsrlq		($D0,$D2,30);
-+	&vpsrlq		($D2,$D2,4);
-+	&vpsrlq		($T1,$T0,26);
-+	&vpsrlq		($D1,$D1,40);			# 4
-+	&vpand		($D2,$D2,$MASK);		# 2
-+	&vpand		($T0,$T0,$MASK);		# 0
-+	&vpand		($T1,$T1,$MASK);		# 1
-+	&vpand		($D0,$D0,$MASK);		# 3 (*)
-+	&vpor		($D1,$D1,&QWP(0,"ebx"));	# padbit, yes, always
-+
-+	# (*)	note that output is counterintuitive, inp[3:4] is
-+	#	returned in $D1-2, while $D3-4 are preserved;
-+}
-+	&vsplat_input	();
-+
-+sub vpmuladd {
-+my $addr = shift;
-+
-+	&vpaddq		($D2,$D2,&QWP(32*2,"esp"));	# add hash value
-+	&vpaddq		($T0,$T0,&QWP(32*0,"esp"));
-+	&vpaddq		($T1,$T1,&QWP(32*1,"esp"));
-+	&vpaddq		($D0,$D0,$D3);
-+	&vpaddq		($D1,$D1,$D4);
-+
-+	################################################################
-+	# d3 = h2*r1   + h0*r3 + h1*r2   + h3*r0   + h4*5*r4
-+	# d4 = h2*r2   + h0*r4 + h1*r3   + h3*r1   + h4*r0
-+	# d0 = h2*5*r3 + h0*r0 + h1*5*r4 + h3*5*r2 + h4*5*r1
-+	# d1 = h2*5*r4 + h0*r1 + h1*r0   + h3*5*r3 + h4*5*r2
-+	# d2 = h2*r0   + h0*r2 + h1*r1   + h3*5*r4 + h4*5*r3
-+
-+	&vpmuludq	($D3,$D2,&$addr(1));		# d3 = h2*r1
-+	 &vmovdqa	(QWP(32*1,"esp"),$T1);
-+	&vpmuludq	($D4,$D2,&$addr(2));		# d4 = h2*r2
-+	 &vmovdqa	(QWP(32*3,"esp"),$D0);
-+	&vpmuludq	($D0,$D2,&$addr(7));		# d0 = h2*s3
-+	 &vmovdqa	(QWP(32*4,"esp"),$D1);
-+	&vpmuludq	($D1,$D2,&$addr(8));		# d1 = h2*s4
-+	&vpmuludq	($D2,$D2,&$addr(0));		# d2 = h2*r0
-+
-+	&vpmuludq	($T2,$T0,&$addr(3));		# h0*r3
-+	&vpaddq		($D3,$D3,$T2);			# d3 += h0*r3
-+	&vpmuludq	($T1,$T0,&$addr(4));		# h0*r4
-+	&vpaddq		($D4,$D4,$T1);			# d4 + h0*r4
-+	&vpmuludq	($T2,$T0,&$addr(0));		# h0*r0
-+	&vpaddq		($D0,$D0,$T2);			# d0 + h0*r0
-+	 &vmovdqa	($T2,&QWP(32*1,"esp"));		# h1
-+	&vpmuludq	($T1,$T0,&$addr(1));		# h0*r1
-+	&vpaddq		($D1,$D1,$T1);			# d1 += h0*r1
-+	&vpmuludq	($T0,$T0,&$addr(2));		# h0*r2
-+	&vpaddq		($D2,$D2,$T0);			# d2 += h0*r2
-+
-+	&vpmuludq	($T1,$T2,&$addr(2));		# h1*r2
-+	&vpaddq		($D3,$D3,$T1);			# d3 += h1*r2
-+	&vpmuludq	($T0,$T2,&$addr(3));		# h1*r3
-+	&vpaddq		($D4,$D4,$T0);			# d4 += h1*r3
-+	&vpmuludq	($T1,$T2,&$addr(8));		# h1*s4
-+	&vpaddq		($D0,$D0,$T1);			# d0 += h1*s4
-+	 &vmovdqa	($T1,&QWP(32*3,"esp"));		# h3
-+	&vpmuludq	($T0,$T2,&$addr(0));		# h1*r0
-+	&vpaddq		($D1,$D1,$T0);			# d1 += h1*r0
-+	&vpmuludq	($T2,$T2,&$addr(1));		# h1*r1
-+	&vpaddq		($D2,$D2,$T2);			# d2 += h1*r1
-+
-+	&vpmuludq	($T0,$T1,&$addr(0));		# h3*r0
-+	&vpaddq		($D3,$D3,$T0);			# d3 += h3*r0
-+	&vpmuludq	($T2,$T1,&$addr(1));		# h3*r1
-+	&vpaddq		($D4,$D4,$T2);			# d4 += h3*r1
-+	&vpmuludq	($T0,$T1,&$addr(6));		# h3*s2
-+	&vpaddq		($D0,$D0,$T0);			# d0 += h3*s2
-+	 &vmovdqa	($T0,&QWP(32*4,"esp"));		# h4
-+	&vpmuludq	($T2,$T1,&$addr(7));		# h3*s3
-+	&vpaddq		($D1,$D1,$T2);			# d1+= h3*s3
-+	&vpmuludq	($T1,$T1,&$addr(8));		# h3*s4
-+	&vpaddq		($D2,$D2,$T1);			# d2 += h3*s4
-+
-+	&vpmuludq	($T2,$T0,&$addr(8));		# h4*s4
-+	&vpaddq		($D3,$D3,$T2);			# d3 += h4*s4
-+	&vpmuludq	($T1,$T0,&$addr(5));		# h4*s1
-+	&vpaddq		($D0,$D0,$T1);			# d0 += h4*s1
-+	&vpmuludq	($T2,$T0,&$addr(0));		# h4*r0
-+	&vpaddq		($D4,$D4,$T2);			# d4 += h4*r0
-+	 &vmovdqa	($MASK,&QWP(64,"ebx"));
-+	&vpmuludq	($T1,$T0,&$addr(6));		# h4*s2
-+	&vpaddq		($D1,$D1,$T1);			# d1 += h4*s2
-+	&vpmuludq	($T0,$T0,&$addr(7));		# h4*s3
-+	&vpaddq		($D2,$D2,$T0);			# d2 += h4*s3
-+}
-+	&vpmuladd	(sub {	my $i=shift; &QWP(32*$i-128,"edx");	});
-+
-+sub vlazy_reduction {
-+	################################################################
-+	# lazy reduction
-+
-+	 &vpsrlq	($T0,$D3,26);
-+	 &vpand		($D3,$D3,$MASK);
-+	&vpsrlq		($T1,$D0,26);
-+	&vpand		($D0,$D0,$MASK);
-+	 &vpaddq	($D4,$D4,$T0);			# h3 -> h4
-+	&vpaddq		($D1,$D1,$T1);			# h0 -> h1
-+	 &vpsrlq	($T0,$D4,26);
-+	 &vpand		($D4,$D4,$MASK);
-+	&vpsrlq		($T1,$D1,26);
-+	&vpand		($D1,$D1,$MASK);
-+	&vpaddq		($D2,$D2,$T1);			# h1 -> h2
-+	 &vpaddq	($D0,$D0,$T0);
-+	 &vpsllq	($T0,$T0,2);
-+	&vpsrlq		($T1,$D2,26);
-+	&vpand		($D2,$D2,$MASK);
-+	 &vpaddq	($D0,$D0,$T0);			# h4 -> h0
-+	&vpaddq		($D3,$D3,$T1);			# h2 -> h3
-+	&vpsrlq		($T1,$D3,26);
-+	 &vpsrlq	($T0,$D0,26);
-+	 &vpand		($D0,$D0,$MASK);
-+	&vpand		($D3,$D3,$MASK);
-+	 &vpaddq	($D1,$D1,$T0);			# h0 -> h1
-+	&vpaddq		($D4,$D4,$T1);			# h3 -> h4
-+}
-+	&vlazy_reduction();
-+
-+	&vmovdqu	(&X($T0),&QWP(16*0,"esi"));	# load input
-+	&vmovdqu	(&X($T1),&QWP(16*1,"esi"));
-+	&vinserti128	($T0,$T0,&QWP(16*2,"esi"),1);
-+	&vinserti128	($T1,$T1,&QWP(16*3,"esi"),1);
-+	&lea		("esi",&DWP(16*4,"esi"));
-+	&sub		("ecx",64);
-+	&jnz		(&label("loop"));
-+
-+&set_label("tail");
-+	&vsplat_input	();
-+	&and		("ebx",-64);			# restore pointer
-+
-+	&vpmuladd	(sub {	my $i=shift; &QWP(4+32*$i-128,"edx");	});
-+
-+	################################################################
-+	# horizontal addition
-+
-+	&vpsrldq	($T0,$D4,8);
-+	&vpsrldq	($T1,$D3,8);
-+	&vpaddq		($D4,$D4,$T0);
-+	&vpsrldq	($T0,$D0,8);
-+	&vpaddq		($D3,$D3,$T1);
-+	&vpsrldq	($T1,$D1,8);
-+	&vpaddq		($D0,$D0,$T0);
-+	&vpsrldq	($T0,$D2,8);
-+	&vpaddq		($D1,$D1,$T1);
-+	&vpermq		($T1,$D4,2);			# keep folding
-+	&vpaddq		($D2,$D2,$T0);
-+	&vpermq		($T0,$D3,2);
-+	&vpaddq		($D4,$D4,$T1);
-+	&vpermq		($T1,$D0,2);
-+	&vpaddq		($D3,$D3,$T0);
-+	&vpermq		($T0,$D1,2);
-+	&vpaddq		($D0,$D0,$T1);
-+	&vpermq		($T1,$D2,2);
-+	&vpaddq		($D1,$D1,$T0);
-+	&vpaddq		($D2,$D2,$T1);
-+
-+	&vlazy_reduction();
-+
-+	&cmp		("ecx",0);
-+	&je		(&label("done"));
-+
-+	################################################################
-+	# clear all but single word
-+
-+	&vpshufd	(&X($D0),&X($D0),0b11111100);
-+	&lea		("edx",&DWP(32*5+128,"esp"));	# restore pointer
-+	&vpshufd	(&X($D1),&X($D1),0b11111100);
-+	&vpshufd	(&X($D2),&X($D2),0b11111100);
-+	&vpshufd	(&X($D3),&X($D3),0b11111100);
-+	&vpshufd	(&X($D4),&X($D4),0b11111100);
-+	&jmp		(&label("even"));
-+
-+&set_label("done",16);
-+	&vmovd		(&DWP(-16*3+4*0,"edi"),&X($D0));# store hash value
-+	&vmovd		(&DWP(-16*3+4*1,"edi"),&X($D1));
-+	&vmovd		(&DWP(-16*3+4*2,"edi"),&X($D2));
-+	&vmovd		(&DWP(-16*3+4*3,"edi"),&X($D3));
-+	&vmovd		(&DWP(-16*3+4*4,"edi"),&X($D4));
-+	&vzeroupper	();
-+	&mov	("esp","ebp");
-+&set_label("nodata");
-+&function_end("_poly1305_blocks_avx2");
-+}
-+&set_label("const_sse2",64);
-+	&data_word(1<<24,0,	1<<24,0,	1<<24,0,	1<<24,0);
-+	&data_word(0,0,		0,0,		0,0,		0,0);
-+	&data_word(0x03ffffff,0,0x03ffffff,0,	0x03ffffff,0,	0x03ffffff,0);
-+	&data_word(0x0fffffff,0x0ffffffc,0x0ffffffc,0x0ffffffc);
-+}
-+&asciz	("Poly1305 for x86, CRYPTOGAMS by ");
-+&align	(4);
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-x86_64.pl
-new file mode 100755
-index 0000000..4c22ded
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/asm/poly1305-x86_64.pl
-@@ -0,0 +1,2268 @@
-+#! /usr/bin/env perl
-+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# This module implements Poly1305 hash for x86_64.
-+#
-+# March 2015
-+#
-+# Numbers are cycles per processed byte with poly1305_blocks alone,
-+# measured with rdtsc at fixed clock frequency.
-+#
-+#		IALU/gcc-4.8(*)	AVX(**)		AVX2
-+# P4		4.46/+120%	-
-+# Core 2	2.41/+90%	-
-+# Westmere	1.88/+120%	-
-+# Sandy Bridge	1.39/+140%	1.10
-+# Haswell	1.14/+175%	1.11		0.65
-+# Skylake	1.13/+120%	0.96		0.51
-+# Silvermont	2.83/+95%	-
-+# Goldmont	1.70/+180%	-
-+# VIA Nano	1.82/+150%	-
-+# Sledgehammer	1.38/+160%	-
-+# Bulldozer	2.30/+130%	0.97
-+#
-+# (*)	improvement coefficients relative to clang are more modest and
-+#	are ~50% on most processors, in both cases we are comparing to
-+#	__int128 code;
-+# (**)	SSE2 implementation was attempted, but among non-AVX processors
-+#	it was faster than integer-only code only on older Intel P4 and
-+#	Core processors, 50-30%, less newer processor is, but slower on
-+#	contemporary ones, for example almost 2x slower on Atom, and as
-+#	former are naturally disappearing, SSE2 is deemed unnecessary;
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	   `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=12);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+my ($ctx,$inp,$len,$padbit)=("%rdi","%rsi","%rdx","%rcx");
-+my ($mac,$nonce)=($inp,$len);	# *_emit arguments
-+my ($d1,$d2,$d3, $r0,$r1,$s1)=map("%r$_",(8..13));
-+my ($h0,$h1,$h2)=("%r14","%rbx","%rbp");
-+
-+sub poly1305_iteration {
-+# input:	copy of $r1 in %rax, $h0-$h2, $r0-$r1
-+# output:	$h0-$h2 *= $r0-$r1
-+$code.=<<___;
-+	mulq	$h0			# h0*r1
-+	mov	%rax,$d2
-+	 mov	$r0,%rax
-+	mov	%rdx,$d3
-+
-+	mulq	$h0			# h0*r0
-+	mov	%rax,$h0		# future $h0
-+	 mov	$r0,%rax
-+	mov	%rdx,$d1
-+
-+	mulq	$h1			# h1*r0
-+	add	%rax,$d2
-+	 mov	$s1,%rax
-+	adc	%rdx,$d3
-+
-+	mulq	$h1			# h1*s1
-+	 mov	$h2,$h1			# borrow $h1
-+	add	%rax,$h0
-+	adc	%rdx,$d1
-+
-+	imulq	$s1,$h1			# h2*s1
-+	add	$h1,$d2
-+	 mov	$d1,$h1
-+	adc	\$0,$d3
-+
-+	imulq	$r0,$h2			# h2*r0
-+	add	$d2,$h1
-+	mov	\$-4,%rax		# mask value
-+	adc	$h2,$d3
-+
-+	and	$d3,%rax		# last reduction step
-+	mov	$d3,$h2
-+	shr	\$2,$d3
-+	and	\$3,$h2
-+	add	$d3,%rax
-+	add	%rax,$h0
-+	adc	\$0,$h1
-+	adc	\$0,$h2
-+___
-+}
-+
-+########################################################################
-+# Layout of opaque area is following.
-+#
-+#	unsigned __int64 h[3];		# current hash value base 2^64
-+#	unsigned __int64 r[2];		# key value base 2^64
-+
-+$code.=<<___;
-+.text
-+
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	poly1305_init
-+.hidden	poly1305_init
-+.globl	poly1305_blocks
-+.hidden	poly1305_blocks
-+.globl	poly1305_emit
-+.hidden	poly1305_emit
-+
-+.type	poly1305_init,\@function,3
-+.align	32
-+poly1305_init:
-+	xor	%rax,%rax
-+	mov	%rax,0($ctx)		# initialize hash value
-+	mov	%rax,8($ctx)
-+	mov	%rax,16($ctx)
-+
-+	cmp	\$0,$inp
-+	je	.Lno_key
-+
-+	lea	poly1305_blocks(%rip),%r10
-+	lea	poly1305_emit(%rip),%r11
-+___
-+$code.=<<___	if ($avx);
-+	mov	OPENSSL_ia32cap_P+4(%rip),%r9
-+	lea	poly1305_blocks_avx(%rip),%rax
-+	lea	poly1305_emit_avx(%rip),%rcx
-+	bt	\$`60-32`,%r9		# AVX?
-+	cmovc	%rax,%r10
-+	cmovc	%rcx,%r11
-+___
-+$code.=<<___	if ($avx>1);
-+	lea	poly1305_blocks_avx2(%rip),%rax
-+	bt	\$`5+32`,%r9		# AVX2?
-+	cmovc	%rax,%r10
-+___
-+$code.=<<___;
-+	mov	\$0x0ffffffc0fffffff,%rax
-+	mov	\$0x0ffffffc0ffffffc,%rcx
-+	and	0($inp),%rax
-+	and	8($inp),%rcx
-+	mov	%rax,24($ctx)
-+	mov	%rcx,32($ctx)
-+___
-+$code.=<<___	if ($flavour !~ /elf32/);
-+	mov	%r10,0(%rdx)
-+	mov	%r11,8(%rdx)
-+___
-+$code.=<<___	if ($flavour =~ /elf32/);
-+	mov	%r10d,0(%rdx)
-+	mov	%r11d,4(%rdx)
-+___
-+$code.=<<___;
-+	mov	\$1,%eax
-+.Lno_key:
-+	ret
-+.size	poly1305_init,.-poly1305_init
-+
-+.type	poly1305_blocks,\@function,4
-+.align	32
-+poly1305_blocks:
-+.Lblocks:
-+	shr	\$4,$len
-+	jz	.Lno_data		# too short
-+
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lblocks_body:
-+
-+	mov	$len,%r15		# reassign $len
-+
-+	mov	24($ctx),$r0		# load r
-+	mov	32($ctx),$s1
-+
-+	mov	0($ctx),$h0		# load hash value
-+	mov	8($ctx),$h1
-+	mov	16($ctx),$h2
-+
-+	mov	$s1,$r1
-+	shr	\$2,$s1
-+	mov	$r1,%rax
-+	add	$r1,$s1			# s1 = r1 + (r1 >> 2)
-+	jmp	.Loop
-+
-+.align	32
-+.Loop:
-+	add	0($inp),$h0		# accumulate input
-+	adc	8($inp),$h1
-+	lea	16($inp),$inp
-+	adc	$padbit,$h2
-+___
-+	&poly1305_iteration();
-+$code.=<<___;
-+	mov	$r1,%rax
-+	dec	%r15			# len-=16
-+	jnz	.Loop
-+
-+	mov	$h0,0($ctx)		# store hash value
-+	mov	$h1,8($ctx)
-+	mov	$h2,16($ctx)
-+
-+	mov	0(%rsp),%r15
-+	mov	8(%rsp),%r14
-+	mov	16(%rsp),%r13
-+	mov	24(%rsp),%r12
-+	mov	32(%rsp),%rbp
-+	mov	40(%rsp),%rbx
-+	lea	48(%rsp),%rsp
-+.Lno_data:
-+.Lblocks_epilogue:
-+	ret
-+.size	poly1305_blocks,.-poly1305_blocks
-+
-+.type	poly1305_emit,\@function,3
-+.align	32
-+poly1305_emit:
-+.Lemit:
-+	mov	0($ctx),%r8	# load hash value
-+	mov	8($ctx),%r9
-+	mov	16($ctx),%r10
-+
-+	mov	%r8,%rax
-+	add	\$5,%r8		# compare to modulus
-+	mov	%r9,%rcx
-+	adc	\$0,%r9
-+	adc	\$0,%r10
-+	shr	\$2,%r10	# did 130-bit value overfow?
-+	cmovnz	%r8,%rax
-+	cmovnz	%r9,%rcx
-+
-+	add	0($nonce),%rax	# accumulate nonce
-+	adc	8($nonce),%rcx
-+	mov	%rax,0($mac)	# write result
-+	mov	%rcx,8($mac)
-+
-+	ret
-+.size	poly1305_emit,.-poly1305_emit
-+___
-+if ($avx) {
-+
-+########################################################################
-+# Layout of opaque area is following.
-+#
-+#	unsigned __int32 h[5];		# current hash value base 2^26
-+#	unsigned __int32 is_base2_26;
-+#	unsigned __int64 r[2];		# key value base 2^64
-+#	unsigned __int64 pad;
-+#	struct { unsigned __int32 r^2, r^1, r^4, r^3; } r[9];
-+#
-+# where r^n are base 2^26 digits of degrees of multiplier key. There are
-+# 5 digits, but last four are interleaved with multiples of 5, totalling
-+# in 9 elements: r0, r1, 5*r1, r2, 5*r2, r3, 5*r3, r4, 5*r4.
-+
-+my ($H0,$H1,$H2,$H3,$H4, $T0,$T1,$T2,$T3,$T4, $D0,$D1,$D2,$D3,$D4, $MASK) =
-+    map("%xmm$_",(0..15));
-+
-+$code.=<<___;
-+.type	__poly1305_block,\@abi-omnipotent
-+.align	32
-+__poly1305_block:
-+___
-+	&poly1305_iteration();
-+$code.=<<___;
-+	ret
-+.size	__poly1305_block,.-__poly1305_block
-+
-+.type	__poly1305_init_avx,\@abi-omnipotent
-+.align	32
-+__poly1305_init_avx:
-+	mov	$r0,$h0
-+	mov	$r1,$h1
-+	xor	$h2,$h2
-+
-+	lea	48+64($ctx),$ctx	# size optimization
-+
-+	mov	$r1,%rax
-+	call	__poly1305_block	# r^2
-+
-+	mov	\$0x3ffffff,%eax	# save interleaved r^2 and r base 2^26
-+	mov	\$0x3ffffff,%edx
-+	mov	$h0,$d1
-+	and	$h0#d,%eax
-+	mov	$r0,$d2
-+	and	$r0#d,%edx
-+	mov	%eax,`16*0+0-64`($ctx)
-+	shr	\$26,$d1
-+	mov	%edx,`16*0+4-64`($ctx)
-+	shr	\$26,$d2
-+
-+	mov	\$0x3ffffff,%eax
-+	mov	\$0x3ffffff,%edx
-+	and	$d1#d,%eax
-+	and	$d2#d,%edx
-+	mov	%eax,`16*1+0-64`($ctx)
-+	lea	(%rax,%rax,4),%eax	# *5
-+	mov	%edx,`16*1+4-64`($ctx)
-+	lea	(%rdx,%rdx,4),%edx	# *5
-+	mov	%eax,`16*2+0-64`($ctx)
-+	shr	\$26,$d1
-+	mov	%edx,`16*2+4-64`($ctx)
-+	shr	\$26,$d2
-+
-+	mov	$h1,%rax
-+	mov	$r1,%rdx
-+	shl	\$12,%rax
-+	shl	\$12,%rdx
-+	or	$d1,%rax
-+	or	$d2,%rdx
-+	and	\$0x3ffffff,%eax
-+	and	\$0x3ffffff,%edx
-+	mov	%eax,`16*3+0-64`($ctx)
-+	lea	(%rax,%rax,4),%eax	# *5
-+	mov	%edx,`16*3+4-64`($ctx)
-+	lea	(%rdx,%rdx,4),%edx	# *5
-+	mov	%eax,`16*4+0-64`($ctx)
-+	mov	$h1,$d1
-+	mov	%edx,`16*4+4-64`($ctx)
-+	mov	$r1,$d2
-+
-+	mov	\$0x3ffffff,%eax
-+	mov	\$0x3ffffff,%edx
-+	shr	\$14,$d1
-+	shr	\$14,$d2
-+	and	$d1#d,%eax
-+	and	$d2#d,%edx
-+	mov	%eax,`16*5+0-64`($ctx)
-+	lea	(%rax,%rax,4),%eax	# *5
-+	mov	%edx,`16*5+4-64`($ctx)
-+	lea	(%rdx,%rdx,4),%edx	# *5
-+	mov	%eax,`16*6+0-64`($ctx)
-+	shr	\$26,$d1
-+	mov	%edx,`16*6+4-64`($ctx)
-+	shr	\$26,$d2
-+
-+	mov	$h2,%rax
-+	shl	\$24,%rax
-+	or	%rax,$d1
-+	mov	$d1#d,`16*7+0-64`($ctx)
-+	lea	($d1,$d1,4),$d1		# *5
-+	mov	$d2#d,`16*7+4-64`($ctx)
-+	lea	($d2,$d2,4),$d2		# *5
-+	mov	$d1#d,`16*8+0-64`($ctx)
-+	mov	$d2#d,`16*8+4-64`($ctx)
-+
-+	mov	$r1,%rax
-+	call	__poly1305_block	# r^3
-+
-+	mov	\$0x3ffffff,%eax	# save r^3 base 2^26
-+	mov	$h0,$d1
-+	and	$h0#d,%eax
-+	shr	\$26,$d1
-+	mov	%eax,`16*0+12-64`($ctx)
-+
-+	mov	\$0x3ffffff,%edx
-+	and	$d1#d,%edx
-+	mov	%edx,`16*1+12-64`($ctx)
-+	lea	(%rdx,%rdx,4),%edx	# *5
-+	shr	\$26,$d1
-+	mov	%edx,`16*2+12-64`($ctx)
-+
-+	mov	$h1,%rax
-+	shl	\$12,%rax
-+	or	$d1,%rax
-+	and	\$0x3ffffff,%eax
-+	mov	%eax,`16*3+12-64`($ctx)
-+	lea	(%rax,%rax,4),%eax	# *5
-+	mov	$h1,$d1
-+	mov	%eax,`16*4+12-64`($ctx)
-+
-+	mov	\$0x3ffffff,%edx
-+	shr	\$14,$d1
-+	and	$d1#d,%edx
-+	mov	%edx,`16*5+12-64`($ctx)
-+	lea	(%rdx,%rdx,4),%edx	# *5
-+	shr	\$26,$d1
-+	mov	%edx,`16*6+12-64`($ctx)
-+
-+	mov	$h2,%rax
-+	shl	\$24,%rax
-+	or	%rax,$d1
-+	mov	$d1#d,`16*7+12-64`($ctx)
-+	lea	($d1,$d1,4),$d1		# *5
-+	mov	$d1#d,`16*8+12-64`($ctx)
-+
-+	mov	$r1,%rax
-+	call	__poly1305_block	# r^4
-+
-+	mov	\$0x3ffffff,%eax	# save r^4 base 2^26
-+	mov	$h0,$d1
-+	and	$h0#d,%eax
-+	shr	\$26,$d1
-+	mov	%eax,`16*0+8-64`($ctx)
-+
-+	mov	\$0x3ffffff,%edx
-+	and	$d1#d,%edx
-+	mov	%edx,`16*1+8-64`($ctx)
-+	lea	(%rdx,%rdx,4),%edx	# *5
-+	shr	\$26,$d1
-+	mov	%edx,`16*2+8-64`($ctx)
-+
-+	mov	$h1,%rax
-+	shl	\$12,%rax
-+	or	$d1,%rax
-+	and	\$0x3ffffff,%eax
-+	mov	%eax,`16*3+8-64`($ctx)
-+	lea	(%rax,%rax,4),%eax	# *5
-+	mov	$h1,$d1
-+	mov	%eax,`16*4+8-64`($ctx)
-+
-+	mov	\$0x3ffffff,%edx
-+	shr	\$14,$d1
-+	and	$d1#d,%edx
-+	mov	%edx,`16*5+8-64`($ctx)
-+	lea	(%rdx,%rdx,4),%edx	# *5
-+	shr	\$26,$d1
-+	mov	%edx,`16*6+8-64`($ctx)
-+
-+	mov	$h2,%rax
-+	shl	\$24,%rax
-+	or	%rax,$d1
-+	mov	$d1#d,`16*7+8-64`($ctx)
-+	lea	($d1,$d1,4),$d1		# *5
-+	mov	$d1#d,`16*8+8-64`($ctx)
-+
-+	lea	-48-64($ctx),$ctx	# size [de-]optimization
-+	ret
-+.size	__poly1305_init_avx,.-__poly1305_init_avx
-+
-+.type	poly1305_blocks_avx,\@function,4
-+.align	32
-+poly1305_blocks_avx:
-+	mov	20($ctx),%r8d		# is_base2_26
-+	cmp	\$128,$len
-+	jae	.Lblocks_avx
-+	test	%r8d,%r8d
-+	jz	.Lblocks
-+
-+.Lblocks_avx:
-+	and	\$-16,$len
-+	jz	.Lno_data_avx
-+
-+	vzeroupper
-+
-+	test	%r8d,%r8d
-+	jz	.Lbase2_64_avx
-+
-+	test	\$31,$len
-+	jz	.Leven_avx
-+
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lblocks_avx_body:
-+
-+	mov	$len,%r15		# reassign $len
-+
-+	mov	0($ctx),$d1		# load hash value
-+	mov	8($ctx),$d2
-+	mov	16($ctx),$h2#d
-+
-+	mov	24($ctx),$r0		# load r
-+	mov	32($ctx),$s1
-+
-+	################################# base 2^26 -> base 2^64
-+	mov	$d1#d,$h0#d
-+	and	\$`-1*(1<<31)`,$d1
-+	mov	$d2,$r1			# borrow $r1
-+	mov	$d2#d,$h1#d
-+	and	\$`-1*(1<<31)`,$d2
-+
-+	shr	\$6,$d1
-+	shl	\$52,$r1
-+	add	$d1,$h0
-+	shr	\$12,$h1
-+	shr	\$18,$d2
-+	add	$r1,$h0
-+	adc	$d2,$h1
-+
-+	mov	$h2,$d1
-+	shl	\$40,$d1
-+	shr	\$24,$h2
-+	add	$d1,$h1
-+	adc	\$0,$h2			# can be partially reduced...
-+
-+	mov	\$-4,$d2		# ... so reduce
-+	mov	$h2,$d1
-+	and	$h2,$d2
-+	shr	\$2,$d1
-+	and	\$3,$h2
-+	add	$d2,$d1			# =*5
-+	add	$d1,$h0
-+	adc	\$0,$h1
-+	adc	\$0,$h2
-+
-+	mov	$s1,$r1
-+	mov	$s1,%rax
-+	shr	\$2,$s1
-+	add	$r1,$s1			# s1 = r1 + (r1 >> 2)
-+
-+	add	0($inp),$h0		# accumulate input
-+	adc	8($inp),$h1
-+	lea	16($inp),$inp
-+	adc	$padbit,$h2
-+
-+	call	__poly1305_block
-+
-+	test	$padbit,$padbit		# if $padbit is zero,
-+	jz	.Lstore_base2_64_avx	# store hash in base 2^64 format
-+
-+	################################# base 2^64 -> base 2^26
-+	mov	$h0,%rax
-+	mov	$h0,%rdx
-+	shr	\$52,$h0
-+	mov	$h1,$r0
-+	mov	$h1,$r1
-+	shr	\$26,%rdx
-+	and	\$0x3ffffff,%rax	# h[0]
-+	shl	\$12,$r0
-+	and	\$0x3ffffff,%rdx	# h[1]
-+	shr	\$14,$h1
-+	or	$r0,$h0
-+	shl	\$24,$h2
-+	and	\$0x3ffffff,$h0		# h[2]
-+	shr	\$40,$r1
-+	and	\$0x3ffffff,$h1		# h[3]
-+	or	$r1,$h2			# h[4]
-+
-+	sub	\$16,%r15
-+	jz	.Lstore_base2_26_avx
-+
-+	vmovd	%rax#d,$H0
-+	vmovd	%rdx#d,$H1
-+	vmovd	$h0#d,$H2
-+	vmovd	$h1#d,$H3
-+	vmovd	$h2#d,$H4
-+	jmp	.Lproceed_avx
-+
-+.align	32
-+.Lstore_base2_64_avx:
-+	mov	$h0,0($ctx)
-+	mov	$h1,8($ctx)
-+	mov	$h2,16($ctx)		# note that is_base2_26 is zeroed
-+	jmp	.Ldone_avx
-+
-+.align	16
-+.Lstore_base2_26_avx:
-+	mov	%rax#d,0($ctx)		# store hash value base 2^26
-+	mov	%rdx#d,4($ctx)
-+	mov	$h0#d,8($ctx)
-+	mov	$h1#d,12($ctx)
-+	mov	$h2#d,16($ctx)
-+.align	16
-+.Ldone_avx:
-+	mov	0(%rsp),%r15
-+	mov	8(%rsp),%r14
-+	mov	16(%rsp),%r13
-+	mov	24(%rsp),%r12
-+	mov	32(%rsp),%rbp
-+	mov	40(%rsp),%rbx
-+	lea	48(%rsp),%rsp
-+.Lno_data_avx:
-+.Lblocks_avx_epilogue:
-+	ret
-+
-+.align	32
-+.Lbase2_64_avx:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lbase2_64_avx_body:
-+
-+	mov	$len,%r15		# reassign $len
-+
-+	mov	24($ctx),$r0		# load r
-+	mov	32($ctx),$s1
-+
-+	mov	0($ctx),$h0		# load hash value
-+	mov	8($ctx),$h1
-+	mov	16($ctx),$h2#d
-+
-+	mov	$s1,$r1
-+	mov	$s1,%rax
-+	shr	\$2,$s1
-+	add	$r1,$s1			# s1 = r1 + (r1 >> 2)
-+
-+	test	\$31,$len
-+	jz	.Linit_avx
-+
-+	add	0($inp),$h0		# accumulate input
-+	adc	8($inp),$h1
-+	lea	16($inp),$inp
-+	adc	$padbit,$h2
-+	sub	\$16,%r15
-+
-+	call	__poly1305_block
-+
-+.Linit_avx:
-+	################################# base 2^64 -> base 2^26
-+	mov	$h0,%rax
-+	mov	$h0,%rdx
-+	shr	\$52,$h0
-+	mov	$h1,$d1
-+	mov	$h1,$d2
-+	shr	\$26,%rdx
-+	and	\$0x3ffffff,%rax	# h[0]
-+	shl	\$12,$d1
-+	and	\$0x3ffffff,%rdx	# h[1]
-+	shr	\$14,$h1
-+	or	$d1,$h0
-+	shl	\$24,$h2
-+	and	\$0x3ffffff,$h0		# h[2]
-+	shr	\$40,$d2
-+	and	\$0x3ffffff,$h1		# h[3]
-+	or	$d2,$h2			# h[4]
-+
-+	vmovd	%rax#d,$H0
-+	vmovd	%rdx#d,$H1
-+	vmovd	$h0#d,$H2
-+	vmovd	$h1#d,$H3
-+	vmovd	$h2#d,$H4
-+	movl	\$1,20($ctx)		# set is_base2_26
-+
-+	call	__poly1305_init_avx
-+
-+.Lproceed_avx:
-+	mov	%r15,$len
-+
-+	mov	0(%rsp),%r15
-+	mov	8(%rsp),%r14
-+	mov	16(%rsp),%r13
-+	mov	24(%rsp),%r12
-+	mov	32(%rsp),%rbp
-+	mov	40(%rsp),%rbx
-+	lea	48(%rsp),%rax
-+	lea	48(%rsp),%rsp
-+.Lbase2_64_avx_epilogue:
-+	jmp	.Ldo_avx
-+
-+.align	32
-+.Leven_avx:
-+	vmovd		4*0($ctx),$H0		# load hash value
-+	vmovd		4*1($ctx),$H1
-+	vmovd		4*2($ctx),$H2
-+	vmovd		4*3($ctx),$H3
-+	vmovd		4*4($ctx),$H4
-+
-+.Ldo_avx:
-+___
-+$code.=<<___	if (!$win64);
-+	lea		-0x58(%rsp),%r11
-+	sub		\$0x178,%rsp
-+___
-+$code.=<<___	if ($win64);
-+	lea		-0xf8(%rsp),%r11
-+	sub		\$0x218,%rsp
-+	vmovdqa		%xmm6,0x50(%r11)
-+	vmovdqa		%xmm7,0x60(%r11)
-+	vmovdqa		%xmm8,0x70(%r11)
-+	vmovdqa		%xmm9,0x80(%r11)
-+	vmovdqa		%xmm10,0x90(%r11)
-+	vmovdqa		%xmm11,0xa0(%r11)
-+	vmovdqa		%xmm12,0xb0(%r11)
-+	vmovdqa		%xmm13,0xc0(%r11)
-+	vmovdqa		%xmm14,0xd0(%r11)
-+	vmovdqa		%xmm15,0xe0(%r11)
-+.Ldo_avx_body:
-+___
-+$code.=<<___;
-+	sub		\$64,$len
-+	lea		-32($inp),%rax
-+	cmovc		%rax,$inp
-+
-+	vmovdqu		`16*3`($ctx),$D4	# preload r0^2
-+	lea		`16*3+64`($ctx),$ctx	# size optimization
-+	lea		.Lconst(%rip),%rcx
-+
-+	################################################################
-+	# load input
-+	vmovdqu		16*2($inp),$T0
-+	vmovdqu		16*3($inp),$T1
-+	vmovdqa		64(%rcx),$MASK		# .Lmask26
-+
-+	vpsrldq		\$6,$T0,$T2		# splat input
-+	vpsrldq		\$6,$T1,$T3
-+	vpunpckhqdq	$T1,$T0,$T4		# 4
-+	vpunpcklqdq	$T1,$T0,$T0		# 0:1
-+	vpunpcklqdq	$T3,$T2,$T3		# 2:3
-+
-+	vpsrlq		\$40,$T4,$T4		# 4
-+	vpsrlq		\$26,$T0,$T1
-+	vpand		$MASK,$T0,$T0		# 0
-+	vpsrlq		\$4,$T3,$T2
-+	vpand		$MASK,$T1,$T1		# 1
-+	vpsrlq		\$30,$T3,$T3
-+	vpand		$MASK,$T2,$T2		# 2
-+	vpand		$MASK,$T3,$T3		# 3
-+	vpor		32(%rcx),$T4,$T4	# padbit, yes, always
-+
-+	jbe		.Lskip_loop_avx
-+
-+	# expand and copy pre-calculated table to stack
-+	vmovdqu		`16*1-64`($ctx),$D1
-+	vmovdqu		`16*2-64`($ctx),$D2
-+	vpshufd		\$0xEE,$D4,$D3		# 34xx -> 3434
-+	vpshufd		\$0x44,$D4,$D0		# xx12 -> 1212
-+	vmovdqa		$D3,-0x90(%r11)
-+	vmovdqa		$D0,0x00(%rsp)
-+	vpshufd		\$0xEE,$D1,$D4
-+	vmovdqu		`16*3-64`($ctx),$D0
-+	vpshufd		\$0x44,$D1,$D1
-+	vmovdqa		$D4,-0x80(%r11)
-+	vmovdqa		$D1,0x10(%rsp)
-+	vpshufd		\$0xEE,$D2,$D3
-+	vmovdqu		`16*4-64`($ctx),$D1
-+	vpshufd		\$0x44,$D2,$D2
-+	vmovdqa		$D3,-0x70(%r11)
-+	vmovdqa		$D2,0x20(%rsp)
-+	vpshufd		\$0xEE,$D0,$D4
-+	vmovdqu		`16*5-64`($ctx),$D2
-+	vpshufd		\$0x44,$D0,$D0
-+	vmovdqa		$D4,-0x60(%r11)
-+	vmovdqa		$D0,0x30(%rsp)
-+	vpshufd		\$0xEE,$D1,$D3
-+	vmovdqu		`16*6-64`($ctx),$D0
-+	vpshufd		\$0x44,$D1,$D1
-+	vmovdqa		$D3,-0x50(%r11)
-+	vmovdqa		$D1,0x40(%rsp)
-+	vpshufd		\$0xEE,$D2,$D4
-+	vmovdqu		`16*7-64`($ctx),$D1
-+	vpshufd		\$0x44,$D2,$D2
-+	vmovdqa		$D4,-0x40(%r11)
-+	vmovdqa		$D2,0x50(%rsp)
-+	vpshufd		\$0xEE,$D0,$D3
-+	vmovdqu		`16*8-64`($ctx),$D2
-+	vpshufd		\$0x44,$D0,$D0
-+	vmovdqa		$D3,-0x30(%r11)
-+	vmovdqa		$D0,0x60(%rsp)
-+	vpshufd		\$0xEE,$D1,$D4
-+	vpshufd		\$0x44,$D1,$D1
-+	vmovdqa		$D4,-0x20(%r11)
-+	vmovdqa		$D1,0x70(%rsp)
-+	vpshufd		\$0xEE,$D2,$D3
-+	 vmovdqa	0x00(%rsp),$D4		# preload r0^2
-+	vpshufd		\$0x44,$D2,$D2
-+	vmovdqa		$D3,-0x10(%r11)
-+	vmovdqa		$D2,0x80(%rsp)
-+
-+	jmp		.Loop_avx
-+
-+.align	32
-+.Loop_avx:
-+	################################################################
-+	# ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
-+	# ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
-+	#   \___________________/
-+	# ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
-+	# ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
-+	#   \___________________/ \____________________/
-+	#
-+	# Note that we start with inp[2:3]*r^2. This is because it
-+	# doesn't depend on reduction in previous iteration.
-+	################################################################
-+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
-+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
-+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
-+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
-+	#
-+	# though note that $Tx and $Hx are "reversed" in this section,
-+	# and $D4 is preloaded with r0^2...
-+
-+	vpmuludq	$T0,$D4,$D0		# d0 = h0*r0
-+	vpmuludq	$T1,$D4,$D1		# d1 = h1*r0
-+	  vmovdqa	$H2,0x20(%r11)				# offload hash
-+	vpmuludq	$T2,$D4,$D2		# d3 = h2*r0
-+	 vmovdqa	0x10(%rsp),$H2		# r1^2
-+	vpmuludq	$T3,$D4,$D3		# d3 = h3*r0
-+	vpmuludq	$T4,$D4,$D4		# d4 = h4*r0
-+
-+	  vmovdqa	$H0,0x00(%r11)				#
-+	vpmuludq	0x20(%rsp),$T4,$H0	# h4*s1
-+	  vmovdqa	$H1,0x10(%r11)				#
-+	vpmuludq	$T3,$H2,$H1		# h3*r1
-+	vpaddq		$H0,$D0,$D0		# d0 += h4*s1
-+	vpaddq		$H1,$D4,$D4		# d4 += h3*r1
-+	  vmovdqa	$H3,0x30(%r11)				#
-+	vpmuludq	$T2,$H2,$H0		# h2*r1
-+	vpmuludq	$T1,$H2,$H1		# h1*r1
-+	vpaddq		$H0,$D3,$D3		# d3 += h2*r1
-+	 vmovdqa	0x30(%rsp),$H3		# r2^2
-+	vpaddq		$H1,$D2,$D2		# d2 += h1*r1
-+	  vmovdqa	$H4,0x40(%r11)				#
-+	vpmuludq	$T0,$H2,$H2		# h0*r1
-+	 vpmuludq	$T2,$H3,$H0		# h2*r2
-+	vpaddq		$H2,$D1,$D1		# d1 += h0*r1
-+
-+	 vmovdqa	0x40(%rsp),$H4		# s2^2
-+	vpaddq		$H0,$D4,$D4		# d4 += h2*r2
-+	vpmuludq	$T1,$H3,$H1		# h1*r2
-+	vpmuludq	$T0,$H3,$H3		# h0*r2
-+	vpaddq		$H1,$D3,$D3		# d3 += h1*r2
-+	 vmovdqa	0x50(%rsp),$H2		# r3^2
-+	vpaddq		$H3,$D2,$D2		# d2 += h0*r2
-+	vpmuludq	$T4,$H4,$H0		# h4*s2
-+	vpmuludq	$T3,$H4,$H4		# h3*s2
-+	vpaddq		$H0,$D1,$D1		# d1 += h4*s2
-+	 vmovdqa	0x60(%rsp),$H3		# s3^2
-+	vpaddq		$H4,$D0,$D0		# d0 += h3*s2
-+
-+	 vmovdqa	0x80(%rsp),$H4		# s4^2
-+	vpmuludq	$T1,$H2,$H1		# h1*r3
-+	vpmuludq	$T0,$H2,$H2		# h0*r3
-+	vpaddq		$H1,$D4,$D4		# d4 += h1*r3
-+	vpaddq		$H2,$D3,$D3		# d3 += h0*r3
-+	vpmuludq	$T4,$H3,$H0		# h4*s3
-+	vpmuludq	$T3,$H3,$H1		# h3*s3
-+	vpaddq		$H0,$D2,$D2		# d2 += h4*s3
-+	 vmovdqu	16*0($inp),$H0				# load input
-+	vpaddq		$H1,$D1,$D1		# d1 += h3*s3
-+	vpmuludq	$T2,$H3,$H3		# h2*s3
-+	 vpmuludq	$T2,$H4,$T2		# h2*s4
-+	vpaddq		$H3,$D0,$D0		# d0 += h2*s3
-+
-+	 vmovdqu	16*1($inp),$H1				#
-+	vpaddq		$T2,$D1,$D1		# d1 += h2*s4
-+	vpmuludq	$T3,$H4,$T3		# h3*s4
-+	vpmuludq	$T4,$H4,$T4		# h4*s4
-+	 vpsrldq	\$6,$H0,$H2				# splat input
-+	vpaddq		$T3,$D2,$D2		# d2 += h3*s4
-+	vpaddq		$T4,$D3,$D3		# d3 += h4*s4
-+	 vpsrldq	\$6,$H1,$H3				#
-+	vpmuludq	0x70(%rsp),$T0,$T4	# h0*r4
-+	vpmuludq	$T1,$H4,$T0		# h1*s4
-+	 vpunpckhqdq	$H1,$H0,$H4		# 4
-+	vpaddq		$T4,$D4,$D4		# d4 += h0*r4
-+	 vmovdqa	-0x90(%r11),$T4		# r0^4
-+	vpaddq		$T0,$D0,$D0		# d0 += h1*s4
-+
-+	vpunpcklqdq	$H1,$H0,$H0		# 0:1
-+	vpunpcklqdq	$H3,$H2,$H3		# 2:3
-+
-+	#vpsrlq		\$40,$H4,$H4		# 4
-+	vpsrldq		\$`40/8`,$H4,$H4	# 4
-+	vpsrlq		\$26,$H0,$H1
-+	vpand		$MASK,$H0,$H0		# 0
-+	vpsrlq		\$4,$H3,$H2
-+	vpand		$MASK,$H1,$H1		# 1
-+	vpand		0(%rcx),$H4,$H4		# .Lmask24
-+	vpsrlq		\$30,$H3,$H3
-+	vpand		$MASK,$H2,$H2		# 2
-+	vpand		$MASK,$H3,$H3		# 3
-+	vpor		32(%rcx),$H4,$H4	# padbit, yes, always
-+
-+	vpaddq		0x00(%r11),$H0,$H0	# add hash value
-+	vpaddq		0x10(%r11),$H1,$H1
-+	vpaddq		0x20(%r11),$H2,$H2
-+	vpaddq		0x30(%r11),$H3,$H3
-+	vpaddq		0x40(%r11),$H4,$H4
-+
-+	lea		16*2($inp),%rax
-+	lea		16*4($inp),$inp
-+	sub		\$64,$len
-+	cmovc		%rax,$inp
-+
-+	################################################################
-+	# Now we accumulate (inp[0:1]+hash)*r^4
-+	################################################################
-+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
-+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
-+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
-+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
-+
-+	vpmuludq	$H0,$T4,$T0		# h0*r0
-+	vpmuludq	$H1,$T4,$T1		# h1*r0
-+	vpaddq		$T0,$D0,$D0
-+	vpaddq		$T1,$D1,$D1
-+	 vmovdqa	-0x80(%r11),$T2		# r1^4
-+	vpmuludq	$H2,$T4,$T0		# h2*r0
-+	vpmuludq	$H3,$T4,$T1		# h3*r0
-+	vpaddq		$T0,$D2,$D2
-+	vpaddq		$T1,$D3,$D3
-+	vpmuludq	$H4,$T4,$T4		# h4*r0
-+	 vpmuludq	-0x70(%r11),$H4,$T0	# h4*s1
-+	vpaddq		$T4,$D4,$D4
-+
-+	vpaddq		$T0,$D0,$D0		# d0 += h4*s1
-+	vpmuludq	$H2,$T2,$T1		# h2*r1
-+	vpmuludq	$H3,$T2,$T0		# h3*r1
-+	vpaddq		$T1,$D3,$D3		# d3 += h2*r1
-+	 vmovdqa	-0x60(%r11),$T3		# r2^4
-+	vpaddq		$T0,$D4,$D4		# d4 += h3*r1
-+	vpmuludq	$H1,$T2,$T1		# h1*r1
-+	vpmuludq	$H0,$T2,$T2		# h0*r1
-+	vpaddq		$T1,$D2,$D2		# d2 += h1*r1
-+	vpaddq		$T2,$D1,$D1		# d1 += h0*r1
-+
-+	 vmovdqa	-0x50(%r11),$T4		# s2^4
-+	vpmuludq	$H2,$T3,$T0		# h2*r2
-+	vpmuludq	$H1,$T3,$T1		# h1*r2
-+	vpaddq		$T0,$D4,$D4		# d4 += h2*r2
-+	vpaddq		$T1,$D3,$D3		# d3 += h1*r2
-+	 vmovdqa	-0x40(%r11),$T2		# r3^4
-+	vpmuludq	$H0,$T3,$T3		# h0*r2
-+	vpmuludq	$H4,$T4,$T0		# h4*s2
-+	vpaddq		$T3,$D2,$D2		# d2 += h0*r2
-+	vpaddq		$T0,$D1,$D1		# d1 += h4*s2
-+	 vmovdqa	-0x30(%r11),$T3		# s3^4
-+	vpmuludq	$H3,$T4,$T4		# h3*s2
-+	 vpmuludq	$H1,$T2,$T1		# h1*r3
-+	vpaddq		$T4,$D0,$D0		# d0 += h3*s2
-+
-+	 vmovdqa	-0x10(%r11),$T4		# s4^4
-+	vpaddq		$T1,$D4,$D4		# d4 += h1*r3
-+	vpmuludq	$H0,$T2,$T2		# h0*r3
-+	vpmuludq	$H4,$T3,$T0		# h4*s3
-+	vpaddq		$T2,$D3,$D3		# d3 += h0*r3
-+	vpaddq		$T0,$D2,$D2		# d2 += h4*s3
-+	 vmovdqu	16*2($inp),$T0				# load input
-+	vpmuludq	$H3,$T3,$T2		# h3*s3
-+	vpmuludq	$H2,$T3,$T3		# h2*s3
-+	vpaddq		$T2,$D1,$D1		# d1 += h3*s3
-+	 vmovdqu	16*3($inp),$T1				#
-+	vpaddq		$T3,$D0,$D0		# d0 += h2*s3
-+
-+	vpmuludq	$H2,$T4,$H2		# h2*s4
-+	vpmuludq	$H3,$T4,$H3		# h3*s4
-+	 vpsrldq	\$6,$T0,$T2				# splat input
-+	vpaddq		$H2,$D1,$D1		# d1 += h2*s4
-+	vpmuludq	$H4,$T4,$H4		# h4*s4
-+	 vpsrldq	\$6,$T1,$T3				#
-+	vpaddq		$H3,$D2,$H2		# h2 = d2 + h3*s4
-+	vpaddq		$H4,$D3,$H3		# h3 = d3 + h4*s4
-+	vpmuludq	-0x20(%r11),$H0,$H4	# h0*r4
-+	vpmuludq	$H1,$T4,$H0
-+	 vpunpckhqdq	$T1,$T0,$T4		# 4
-+	vpaddq		$H4,$D4,$H4		# h4 = d4 + h0*r4
-+	vpaddq		$H0,$D0,$H0		# h0 = d0 + h1*s4
-+
-+	vpunpcklqdq	$T1,$T0,$T0		# 0:1
-+	vpunpcklqdq	$T3,$T2,$T3		# 2:3
-+
-+	#vpsrlq		\$40,$T4,$T4		# 4
-+	vpsrldq		\$`40/8`,$T4,$T4	# 4
-+	vpsrlq		\$26,$T0,$T1
-+	 vmovdqa	0x00(%rsp),$D4		# preload r0^2
-+	vpand		$MASK,$T0,$T0		# 0
-+	vpsrlq		\$4,$T3,$T2
-+	vpand		$MASK,$T1,$T1		# 1
-+	vpand		0(%rcx),$T4,$T4		# .Lmask24
-+	vpsrlq		\$30,$T3,$T3
-+	vpand		$MASK,$T2,$T2		# 2
-+	vpand		$MASK,$T3,$T3		# 3
-+	vpor		32(%rcx),$T4,$T4	# padbit, yes, always
-+
-+	################################################################
-+	# lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
-+	# and P. Schwabe
-+
-+	vpsrlq		\$26,$H3,$D3
-+	vpand		$MASK,$H3,$H3
-+	vpaddq		$D3,$H4,$H4		# h3 -> h4
-+
-+	vpsrlq		\$26,$H0,$D0
-+	vpand		$MASK,$H0,$H0
-+	vpaddq		$D0,$D1,$H1		# h0 -> h1
-+
-+	vpsrlq		\$26,$H4,$D0
-+	vpand		$MASK,$H4,$H4
-+
-+	vpsrlq		\$26,$H1,$D1
-+	vpand		$MASK,$H1,$H1
-+	vpaddq		$D1,$H2,$H2		# h1 -> h2
-+
-+	vpaddq		$D0,$H0,$H0
-+	vpsllq		\$2,$D0,$D0
-+	vpaddq		$D0,$H0,$H0		# h4 -> h0
-+
-+	vpsrlq		\$26,$H2,$D2
-+	vpand		$MASK,$H2,$H2
-+	vpaddq		$D2,$H3,$H3		# h2 -> h3
-+
-+	vpsrlq		\$26,$H0,$D0
-+	vpand		$MASK,$H0,$H0
-+	vpaddq		$D0,$H1,$H1		# h0 -> h1
-+
-+	vpsrlq		\$26,$H3,$D3
-+	vpand		$MASK,$H3,$H3
-+	vpaddq		$D3,$H4,$H4		# h3 -> h4
-+
-+	ja		.Loop_avx
-+
-+.Lskip_loop_avx:
-+	################################################################
-+	# multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
-+
-+	vpshufd		\$0x10,$D4,$D4		# r0^n, xx12 -> x1x2
-+	add		\$32,$len
-+	jnz		.Long_tail_avx
-+
-+	vpaddq		$H2,$T2,$T2
-+	vpaddq		$H0,$T0,$T0
-+	vpaddq		$H1,$T1,$T1
-+	vpaddq		$H3,$T3,$T3
-+	vpaddq		$H4,$T4,$T4
-+
-+.Long_tail_avx:
-+	vmovdqa		$H2,0x20(%r11)
-+	vmovdqa		$H0,0x00(%r11)
-+	vmovdqa		$H1,0x10(%r11)
-+	vmovdqa		$H3,0x30(%r11)
-+	vmovdqa		$H4,0x40(%r11)
-+
-+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
-+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
-+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
-+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
-+
-+	vpmuludq	$T2,$D4,$D2		# d2 = h2*r0
-+	vpmuludq	$T0,$D4,$D0		# d0 = h0*r0
-+	 vpshufd	\$0x10,`16*1-64`($ctx),$H2		# r1^n
-+	vpmuludq	$T1,$D4,$D1		# d1 = h1*r0
-+	vpmuludq	$T3,$D4,$D3		# d3 = h3*r0
-+	vpmuludq	$T4,$D4,$D4		# d4 = h4*r0
-+
-+	vpmuludq	$T3,$H2,$H0		# h3*r1
-+	vpaddq		$H0,$D4,$D4		# d4 += h3*r1
-+	 vpshufd	\$0x10,`16*2-64`($ctx),$H3		# s1^n
-+	vpmuludq	$T2,$H2,$H1		# h2*r1
-+	vpaddq		$H1,$D3,$D3		# d3 += h2*r1
-+	 vpshufd	\$0x10,`16*3-64`($ctx),$H4		# r2^n
-+	vpmuludq	$T1,$H2,$H0		# h1*r1
-+	vpaddq		$H0,$D2,$D2		# d2 += h1*r1
-+	vpmuludq	$T0,$H2,$H2		# h0*r1
-+	vpaddq		$H2,$D1,$D1		# d1 += h0*r1
-+	vpmuludq	$T4,$H3,$H3		# h4*s1
-+	vpaddq		$H3,$D0,$D0		# d0 += h4*s1
-+
-+	 vpshufd	\$0x10,`16*4-64`($ctx),$H2		# s2^n
-+	vpmuludq	$T2,$H4,$H1		# h2*r2
-+	vpaddq		$H1,$D4,$D4		# d4 += h2*r2
-+	vpmuludq	$T1,$H4,$H0		# h1*r2
-+	vpaddq		$H0,$D3,$D3		# d3 += h1*r2
-+	 vpshufd	\$0x10,`16*5-64`($ctx),$H3		# r3^n
-+	vpmuludq	$T0,$H4,$H4		# h0*r2
-+	vpaddq		$H4,$D2,$D2		# d2 += h0*r2
-+	vpmuludq	$T4,$H2,$H1		# h4*s2
-+	vpaddq		$H1,$D1,$D1		# d1 += h4*s2
-+	 vpshufd	\$0x10,`16*6-64`($ctx),$H4		# s3^n
-+	vpmuludq	$T3,$H2,$H2		# h3*s2
-+	vpaddq		$H2,$D0,$D0		# d0 += h3*s2
-+
-+	vpmuludq	$T1,$H3,$H0		# h1*r3
-+	vpaddq		$H0,$D4,$D4		# d4 += h1*r3
-+	vpmuludq	$T0,$H3,$H3		# h0*r3
-+	vpaddq		$H3,$D3,$D3		# d3 += h0*r3
-+	 vpshufd	\$0x10,`16*7-64`($ctx),$H2		# r4^n
-+	vpmuludq	$T4,$H4,$H1		# h4*s3
-+	vpaddq		$H1,$D2,$D2		# d2 += h4*s3
-+	 vpshufd	\$0x10,`16*8-64`($ctx),$H3		# s4^n
-+	vpmuludq	$T3,$H4,$H0		# h3*s3
-+	vpaddq		$H0,$D1,$D1		# d1 += h3*s3
-+	vpmuludq	$T2,$H4,$H4		# h2*s3
-+	vpaddq		$H4,$D0,$D0		# d0 += h2*s3
-+
-+	vpmuludq	$T0,$H2,$H2		# h0*r4
-+	vpaddq		$H2,$D4,$D4		# h4 = d4 + h0*r4
-+	vpmuludq	$T4,$H3,$H1		# h4*s4
-+	vpaddq		$H1,$D3,$D3		# h3 = d3 + h4*s4
-+	vpmuludq	$T3,$H3,$H0		# h3*s4
-+	vpaddq		$H0,$D2,$D2		# h2 = d2 + h3*s4
-+	vpmuludq	$T2,$H3,$H1		# h2*s4
-+	vpaddq		$H1,$D1,$D1		# h1 = d1 + h2*s4
-+	vpmuludq	$T1,$H3,$H3		# h1*s4
-+	vpaddq		$H3,$D0,$D0		# h0 = d0 + h1*s4
-+
-+	jz		.Lshort_tail_avx
-+
-+	vmovdqu		16*0($inp),$H0		# load input
-+	vmovdqu		16*1($inp),$H1
-+
-+	vpsrldq		\$6,$H0,$H2		# splat input
-+	vpsrldq		\$6,$H1,$H3
-+	vpunpckhqdq	$H1,$H0,$H4		# 4
-+	vpunpcklqdq	$H1,$H0,$H0		# 0:1
-+	vpunpcklqdq	$H3,$H2,$H3		# 2:3
-+
-+	vpsrlq		\$40,$H4,$H4		# 4
-+	vpsrlq		\$26,$H0,$H1
-+	vpand		$MASK,$H0,$H0		# 0
-+	vpsrlq		\$4,$H3,$H2
-+	vpand		$MASK,$H1,$H1		# 1
-+	vpsrlq		\$30,$H3,$H3
-+	vpand		$MASK,$H2,$H2		# 2
-+	vpand		$MASK,$H3,$H3		# 3
-+	vpor		32(%rcx),$H4,$H4	# padbit, yes, always
-+
-+	vpshufd		\$0x32,`16*0-64`($ctx),$T4	# r0^n, 34xx -> x3x4
-+	vpaddq		0x00(%r11),$H0,$H0
-+	vpaddq		0x10(%r11),$H1,$H1
-+	vpaddq		0x20(%r11),$H2,$H2
-+	vpaddq		0x30(%r11),$H3,$H3
-+	vpaddq		0x40(%r11),$H4,$H4
-+
-+	################################################################
-+	# multiply (inp[0:1]+hash) by r^4:r^3 and accumulate
-+
-+	vpmuludq	$H0,$T4,$T0		# h0*r0
-+	vpaddq		$T0,$D0,$D0		# d0 += h0*r0
-+	vpmuludq	$H1,$T4,$T1		# h1*r0
-+	vpaddq		$T1,$D1,$D1		# d1 += h1*r0
-+	vpmuludq	$H2,$T4,$T0		# h2*r0
-+	vpaddq		$T0,$D2,$D2		# d2 += h2*r0
-+	 vpshufd	\$0x32,`16*1-64`($ctx),$T2		# r1^n
-+	vpmuludq	$H3,$T4,$T1		# h3*r0
-+	vpaddq		$T1,$D3,$D3		# d3 += h3*r0
-+	vpmuludq	$H4,$T4,$T4		# h4*r0
-+	vpaddq		$T4,$D4,$D4		# d4 += h4*r0
-+
-+	vpmuludq	$H3,$T2,$T0		# h3*r1
-+	vpaddq		$T0,$D4,$D4		# d4 += h3*r1
-+	 vpshufd	\$0x32,`16*2-64`($ctx),$T3		# s1
-+	vpmuludq	$H2,$T2,$T1		# h2*r1
-+	vpaddq		$T1,$D3,$D3		# d3 += h2*r1
-+	 vpshufd	\$0x32,`16*3-64`($ctx),$T4		# r2
-+	vpmuludq	$H1,$T2,$T0		# h1*r1
-+	vpaddq		$T0,$D2,$D2		# d2 += h1*r1
-+	vpmuludq	$H0,$T2,$T2		# h0*r1
-+	vpaddq		$T2,$D1,$D1		# d1 += h0*r1
-+	vpmuludq	$H4,$T3,$T3		# h4*s1
-+	vpaddq		$T3,$D0,$D0		# d0 += h4*s1
-+
-+	 vpshufd	\$0x32,`16*4-64`($ctx),$T2		# s2
-+	vpmuludq	$H2,$T4,$T1		# h2*r2
-+	vpaddq		$T1,$D4,$D4		# d4 += h2*r2
-+	vpmuludq	$H1,$T4,$T0		# h1*r2
-+	vpaddq		$T0,$D3,$D3		# d3 += h1*r2
-+	 vpshufd	\$0x32,`16*5-64`($ctx),$T3		# r3
-+	vpmuludq	$H0,$T4,$T4		# h0*r2
-+	vpaddq		$T4,$D2,$D2		# d2 += h0*r2
-+	vpmuludq	$H4,$T2,$T1		# h4*s2
-+	vpaddq		$T1,$D1,$D1		# d1 += h4*s2
-+	 vpshufd	\$0x32,`16*6-64`($ctx),$T4		# s3
-+	vpmuludq	$H3,$T2,$T2		# h3*s2
-+	vpaddq		$T2,$D0,$D0		# d0 += h3*s2
-+
-+	vpmuludq	$H1,$T3,$T0		# h1*r3
-+	vpaddq		$T0,$D4,$D4		# d4 += h1*r3
-+	vpmuludq	$H0,$T3,$T3		# h0*r3
-+	vpaddq		$T3,$D3,$D3		# d3 += h0*r3
-+	 vpshufd	\$0x32,`16*7-64`($ctx),$T2		# r4
-+	vpmuludq	$H4,$T4,$T1		# h4*s3
-+	vpaddq		$T1,$D2,$D2		# d2 += h4*s3
-+	 vpshufd	\$0x32,`16*8-64`($ctx),$T3		# s4
-+	vpmuludq	$H3,$T4,$T0		# h3*s3
-+	vpaddq		$T0,$D1,$D1		# d1 += h3*s3
-+	vpmuludq	$H2,$T4,$T4		# h2*s3
-+	vpaddq		$T4,$D0,$D0		# d0 += h2*s3
-+
-+	vpmuludq	$H0,$T2,$T2		# h0*r4
-+	vpaddq		$T2,$D4,$D4		# d4 += h0*r4
-+	vpmuludq	$H4,$T3,$T1		# h4*s4
-+	vpaddq		$T1,$D3,$D3		# d3 += h4*s4
-+	vpmuludq	$H3,$T3,$T0		# h3*s4
-+	vpaddq		$T0,$D2,$D2		# d2 += h3*s4
-+	vpmuludq	$H2,$T3,$T1		# h2*s4
-+	vpaddq		$T1,$D1,$D1		# d1 += h2*s4
-+	vpmuludq	$H1,$T3,$T3		# h1*s4
-+	vpaddq		$T3,$D0,$D0		# d0 += h1*s4
-+
-+.Lshort_tail_avx:
-+	################################################################
-+	# horizontal addition
-+
-+	vpsrldq		\$8,$D4,$T4
-+	vpsrldq		\$8,$D3,$T3
-+	vpsrldq		\$8,$D1,$T1
-+	vpsrldq		\$8,$D0,$T0
-+	vpsrldq		\$8,$D2,$T2
-+	vpaddq		$T3,$D3,$D3
-+	vpaddq		$T4,$D4,$D4
-+	vpaddq		$T0,$D0,$D0
-+	vpaddq		$T1,$D1,$D1
-+	vpaddq		$T2,$D2,$D2
-+
-+	################################################################
-+	# lazy reduction
-+
-+	vpsrlq		\$26,$D3,$H3
-+	vpand		$MASK,$D3,$D3
-+	vpaddq		$H3,$D4,$D4		# h3 -> h4
-+
-+	vpsrlq		\$26,$D0,$H0
-+	vpand		$MASK,$D0,$D0
-+	vpaddq		$H0,$D1,$D1		# h0 -> h1
-+
-+	vpsrlq		\$26,$D4,$H4
-+	vpand		$MASK,$D4,$D4
-+
-+	vpsrlq		\$26,$D1,$H1
-+	vpand		$MASK,$D1,$D1
-+	vpaddq		$H1,$D2,$D2		# h1 -> h2
-+
-+	vpaddq		$H4,$D0,$D0
-+	vpsllq		\$2,$H4,$H4
-+	vpaddq		$H4,$D0,$D0		# h4 -> h0
-+
-+	vpsrlq		\$26,$D2,$H2
-+	vpand		$MASK,$D2,$D2
-+	vpaddq		$H2,$D3,$D3		# h2 -> h3
-+
-+	vpsrlq		\$26,$D0,$H0
-+	vpand		$MASK,$D0,$D0
-+	vpaddq		$H0,$D1,$D1		# h0 -> h1
-+
-+	vpsrlq		\$26,$D3,$H3
-+	vpand		$MASK,$D3,$D3
-+	vpaddq		$H3,$D4,$D4		# h3 -> h4
-+
-+	vmovd		$D0,`4*0-48-64`($ctx)	# save partially reduced
-+	vmovd		$D1,`4*1-48-64`($ctx)
-+	vmovd		$D2,`4*2-48-64`($ctx)
-+	vmovd		$D3,`4*3-48-64`($ctx)
-+	vmovd		$D4,`4*4-48-64`($ctx)
-+___
-+$code.=<<___	if ($win64);
-+	vmovdqa		0x50(%r11),%xmm6
-+	vmovdqa		0x60(%r11),%xmm7
-+	vmovdqa		0x70(%r11),%xmm8
-+	vmovdqa		0x80(%r11),%xmm9
-+	vmovdqa		0x90(%r11),%xmm10
-+	vmovdqa		0xa0(%r11),%xmm11
-+	vmovdqa		0xb0(%r11),%xmm12
-+	vmovdqa		0xc0(%r11),%xmm13
-+	vmovdqa		0xd0(%r11),%xmm14
-+	vmovdqa		0xe0(%r11),%xmm15
-+	lea		0xf8(%r11),%rsp
-+.Ldo_avx_epilogue:
-+___
-+$code.=<<___	if (!$win64);
-+	lea		0x58(%r11),%rsp
-+___
-+$code.=<<___;
-+	vzeroupper
-+	ret
-+.size	poly1305_blocks_avx,.-poly1305_blocks_avx
-+
-+.type	poly1305_emit_avx,\@function,3
-+.align	32
-+poly1305_emit_avx:
-+	cmpl	\$0,20($ctx)	# is_base2_26?
-+	je	.Lemit
-+
-+	mov	0($ctx),%eax	# load hash value base 2^26
-+	mov	4($ctx),%ecx
-+	mov	8($ctx),%r8d
-+	mov	12($ctx),%r11d
-+	mov	16($ctx),%r10d
-+
-+	shl	\$26,%rcx	# base 2^26 -> base 2^64
-+	mov	%r8,%r9
-+	shl	\$52,%r8
-+	add	%rcx,%rax
-+	shr	\$12,%r9
-+	add	%rax,%r8	# h0
-+	adc	\$0,%r9
-+
-+	shl	\$14,%r11
-+	mov	%r10,%rax
-+	shr	\$24,%r10
-+	add	%r11,%r9
-+	shl	\$40,%rax
-+	add	%rax,%r9	# h1
-+	adc	\$0,%r10	# h2
-+
-+	mov	%r10,%rax	# could be partially reduced, so reduce
-+	mov	%r10,%rcx
-+	and	\$3,%r10
-+	shr	\$2,%rax
-+	and	\$-4,%rcx
-+	add	%rcx,%rax
-+	add	%rax,%r8
-+	adc	\$0,%r9
-+	adc	\$0,%r10
-+
-+	mov	%r8,%rax
-+	add	\$5,%r8		# compare to modulus
-+	mov	%r9,%rcx
-+	adc	\$0,%r9
-+	adc	\$0,%r10
-+	shr	\$2,%r10	# did 130-bit value overfow?
-+	cmovnz	%r8,%rax
-+	cmovnz	%r9,%rcx
-+
-+	add	0($nonce),%rax	# accumulate nonce
-+	adc	8($nonce),%rcx
-+	mov	%rax,0($mac)	# write result
-+	mov	%rcx,8($mac)
-+
-+	ret
-+.size	poly1305_emit_avx,.-poly1305_emit_avx
-+___
-+
-+if ($avx>1) {
-+my ($H0,$H1,$H2,$H3,$H4, $MASK, $T4,$T0,$T1,$T2,$T3, $D0,$D1,$D2,$D3,$D4) =
-+    map("%ymm$_",(0..15));
-+my $S4=$MASK;
-+
-+$code.=<<___;
-+.type	poly1305_blocks_avx2,\@function,4
-+.align	32
-+poly1305_blocks_avx2:
-+	mov	20($ctx),%r8d		# is_base2_26
-+	cmp	\$128,$len
-+	jae	.Lblocks_avx2
-+	test	%r8d,%r8d
-+	jz	.Lblocks
-+
-+.Lblocks_avx2:
-+	and	\$-16,$len
-+	jz	.Lno_data_avx2
-+
-+	vzeroupper
-+
-+	test	%r8d,%r8d
-+	jz	.Lbase2_64_avx2
-+
-+	test	\$63,$len
-+	jz	.Leven_avx2
-+
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lblocks_avx2_body:
-+
-+	mov	$len,%r15		# reassign $len
-+
-+	mov	0($ctx),$d1		# load hash value
-+	mov	8($ctx),$d2
-+	mov	16($ctx),$h2#d
-+
-+	mov	24($ctx),$r0		# load r
-+	mov	32($ctx),$s1
-+
-+	################################# base 2^26 -> base 2^64
-+	mov	$d1#d,$h0#d
-+	and	\$`-1*(1<<31)`,$d1
-+	mov	$d2,$r1			# borrow $r1
-+	mov	$d2#d,$h1#d
-+	and	\$`-1*(1<<31)`,$d2
-+
-+	shr	\$6,$d1
-+	shl	\$52,$r1
-+	add	$d1,$h0
-+	shr	\$12,$h1
-+	shr	\$18,$d2
-+	add	$r1,$h0
-+	adc	$d2,$h1
-+
-+	mov	$h2,$d1
-+	shl	\$40,$d1
-+	shr	\$24,$h2
-+	add	$d1,$h1
-+	adc	\$0,$h2			# can be partially reduced...
-+
-+	mov	\$-4,$d2		# ... so reduce
-+	mov	$h2,$d1
-+	and	$h2,$d2
-+	shr	\$2,$d1
-+	and	\$3,$h2
-+	add	$d2,$d1			# =*5
-+	add	$d1,$h0
-+	adc	\$0,$h1
-+	adc	\$0,$h2
-+
-+	mov	$s1,$r1
-+	mov	$s1,%rax
-+	shr	\$2,$s1
-+	add	$r1,$s1			# s1 = r1 + (r1 >> 2)
-+
-+.Lbase2_26_pre_avx2:
-+	add	0($inp),$h0		# accumulate input
-+	adc	8($inp),$h1
-+	lea	16($inp),$inp
-+	adc	$padbit,$h2
-+	sub	\$16,%r15
-+
-+	call	__poly1305_block
-+	mov	$r1,%rax
-+
-+	test	\$63,%r15
-+	jnz	.Lbase2_26_pre_avx2
-+
-+	test	$padbit,$padbit		# if $padbit is zero,
-+	jz	.Lstore_base2_64_avx2	# store hash in base 2^64 format
-+
-+	################################# base 2^64 -> base 2^26
-+	mov	$h0,%rax
-+	mov	$h0,%rdx
-+	shr	\$52,$h0
-+	mov	$h1,$r0
-+	mov	$h1,$r1
-+	shr	\$26,%rdx
-+	and	\$0x3ffffff,%rax	# h[0]
-+	shl	\$12,$r0
-+	and	\$0x3ffffff,%rdx	# h[1]
-+	shr	\$14,$h1
-+	or	$r0,$h0
-+	shl	\$24,$h2
-+	and	\$0x3ffffff,$h0		# h[2]
-+	shr	\$40,$r1
-+	and	\$0x3ffffff,$h1		# h[3]
-+	or	$r1,$h2			# h[4]
-+
-+	test	%r15,%r15
-+	jz	.Lstore_base2_26_avx2
-+
-+	vmovd	%rax#d,%x#$H0
-+	vmovd	%rdx#d,%x#$H1
-+	vmovd	$h0#d,%x#$H2
-+	vmovd	$h1#d,%x#$H3
-+	vmovd	$h2#d,%x#$H4
-+	jmp	.Lproceed_avx2
-+
-+.align	32
-+.Lstore_base2_64_avx2:
-+	mov	$h0,0($ctx)
-+	mov	$h1,8($ctx)
-+	mov	$h2,16($ctx)		# note that is_base2_26 is zeroed
-+	jmp	.Ldone_avx2
-+
-+.align	16
-+.Lstore_base2_26_avx2:
-+	mov	%rax#d,0($ctx)		# store hash value base 2^26
-+	mov	%rdx#d,4($ctx)
-+	mov	$h0#d,8($ctx)
-+	mov	$h1#d,12($ctx)
-+	mov	$h2#d,16($ctx)
-+.align	16
-+.Ldone_avx2:
-+	mov	0(%rsp),%r15
-+	mov	8(%rsp),%r14
-+	mov	16(%rsp),%r13
-+	mov	24(%rsp),%r12
-+	mov	32(%rsp),%rbp
-+	mov	40(%rsp),%rbx
-+	lea	48(%rsp),%rsp
-+.Lno_data_avx2:
-+.Lblocks_avx2_epilogue:
-+	ret
-+
-+.align	32
-+.Lbase2_64_avx2:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+.Lbase2_64_avx2_body:
-+
-+	mov	$len,%r15		# reassign $len
-+
-+	mov	24($ctx),$r0		# load r
-+	mov	32($ctx),$s1
-+
-+	mov	0($ctx),$h0		# load hash value
-+	mov	8($ctx),$h1
-+	mov	16($ctx),$h2#d
-+
-+	mov	$s1,$r1
-+	mov	$s1,%rax
-+	shr	\$2,$s1
-+	add	$r1,$s1			# s1 = r1 + (r1 >> 2)
-+
-+	test	\$63,$len
-+	jz	.Linit_avx2
-+
-+.Lbase2_64_pre_avx2:
-+	add	0($inp),$h0		# accumulate input
-+	adc	8($inp),$h1
-+	lea	16($inp),$inp
-+	adc	$padbit,$h2
-+	sub	\$16,%r15
-+
-+	call	__poly1305_block
-+	mov	$r1,%rax
-+
-+	test	\$63,%r15
-+	jnz	.Lbase2_64_pre_avx2
-+
-+.Linit_avx2:
-+	################################# base 2^64 -> base 2^26
-+	mov	$h0,%rax
-+	mov	$h0,%rdx
-+	shr	\$52,$h0
-+	mov	$h1,$d1
-+	mov	$h1,$d2
-+	shr	\$26,%rdx
-+	and	\$0x3ffffff,%rax	# h[0]
-+	shl	\$12,$d1
-+	and	\$0x3ffffff,%rdx	# h[1]
-+	shr	\$14,$h1
-+	or	$d1,$h0
-+	shl	\$24,$h2
-+	and	\$0x3ffffff,$h0		# h[2]
-+	shr	\$40,$d2
-+	and	\$0x3ffffff,$h1		# h[3]
-+	or	$d2,$h2			# h[4]
-+
-+	vmovd	%rax#d,%x#$H0
-+	vmovd	%rdx#d,%x#$H1
-+	vmovd	$h0#d,%x#$H2
-+	vmovd	$h1#d,%x#$H3
-+	vmovd	$h2#d,%x#$H4
-+	movl	\$1,20($ctx)		# set is_base2_26
-+
-+	call	__poly1305_init_avx
-+
-+.Lproceed_avx2:
-+	mov	%r15,$len
-+
-+	mov	0(%rsp),%r15
-+	mov	8(%rsp),%r14
-+	mov	16(%rsp),%r13
-+	mov	24(%rsp),%r12
-+	mov	32(%rsp),%rbp
-+	mov	40(%rsp),%rbx
-+	lea	48(%rsp),%rax
-+	lea	48(%rsp),%rsp
-+.Lbase2_64_avx2_epilogue:
-+	jmp	.Ldo_avx2
-+
-+.align	32
-+.Leven_avx2:
-+	vmovd		4*0($ctx),%x#$H0	# load hash value base 2^26
-+	vmovd		4*1($ctx),%x#$H1
-+	vmovd		4*2($ctx),%x#$H2
-+	vmovd		4*3($ctx),%x#$H3
-+	vmovd		4*4($ctx),%x#$H4
-+
-+.Ldo_avx2:
-+___
-+$code.=<<___	if (!$win64);
-+	lea		-8(%rsp),%r11
-+	sub		\$0x128,%rsp
-+___
-+$code.=<<___	if ($win64);
-+	lea		-0xf8(%rsp),%r11
-+	sub		\$0x1c8,%rsp
-+	vmovdqa		%xmm6,0x50(%r11)
-+	vmovdqa		%xmm7,0x60(%r11)
-+	vmovdqa		%xmm8,0x70(%r11)
-+	vmovdqa		%xmm9,0x80(%r11)
-+	vmovdqa		%xmm10,0x90(%r11)
-+	vmovdqa		%xmm11,0xa0(%r11)
-+	vmovdqa		%xmm12,0xb0(%r11)
-+	vmovdqa		%xmm13,0xc0(%r11)
-+	vmovdqa		%xmm14,0xd0(%r11)
-+	vmovdqa		%xmm15,0xe0(%r11)
-+.Ldo_avx2_body:
-+___
-+$code.=<<___;
-+	lea		48+64($ctx),$ctx	# size optimization
-+	lea		.Lconst(%rip),%rcx
-+
-+	# expand and copy pre-calculated table to stack
-+	vmovdqu		`16*0-64`($ctx),%x#$T2
-+	and		\$-512,%rsp
-+	vmovdqu		`16*1-64`($ctx),%x#$T3
-+	vmovdqu		`16*2-64`($ctx),%x#$T4
-+	vmovdqu		`16*3-64`($ctx),%x#$D0
-+	vmovdqu		`16*4-64`($ctx),%x#$D1
-+	vmovdqu		`16*5-64`($ctx),%x#$D2
-+	vmovdqu		`16*6-64`($ctx),%x#$D3
-+	vpermq		\$0x15,$T2,$T2		# 00003412 -> 12343434
-+	vmovdqu		`16*7-64`($ctx),%x#$D4
-+	vpermq		\$0x15,$T3,$T3
-+	vpshufd		\$0xc8,$T2,$T2		# 12343434 -> 14243444
-+	vmovdqu		`16*8-64`($ctx),%x#$MASK
-+	vpermq		\$0x15,$T4,$T4
-+	vpshufd		\$0xc8,$T3,$T3
-+	vmovdqa		$T2,0x00(%rsp)
-+	vpermq		\$0x15,$D0,$D0
-+	vpshufd		\$0xc8,$T4,$T4
-+	vmovdqa		$T3,0x20(%rsp)
-+	vpermq		\$0x15,$D1,$D1
-+	vpshufd		\$0xc8,$D0,$D0
-+	vmovdqa		$T4,0x40(%rsp)
-+	vpermq		\$0x15,$D2,$D2
-+	vpshufd		\$0xc8,$D1,$D1
-+	vmovdqa		$D0,0x60(%rsp)
-+	vpermq		\$0x15,$D3,$D3
-+	vpshufd		\$0xc8,$D2,$D2
-+	vmovdqa		$D1,0x80(%rsp)
-+	vpermq		\$0x15,$D4,$D4
-+	vpshufd		\$0xc8,$D3,$D3
-+	vmovdqa		$D2,0xa0(%rsp)
-+	vpermq		\$0x15,$MASK,$MASK
-+	vpshufd		\$0xc8,$D4,$D4
-+	vmovdqa		$D3,0xc0(%rsp)
-+	vpshufd		\$0xc8,$MASK,$MASK
-+	vmovdqa		$D4,0xe0(%rsp)
-+	vmovdqa		$MASK,0x100(%rsp)
-+	vmovdqa		64(%rcx),$MASK		# .Lmask26
-+
-+	################################################################
-+	# load input
-+	vmovdqu		16*0($inp),%x#$T0
-+	vmovdqu		16*1($inp),%x#$T1
-+	vinserti128	\$1,16*2($inp),$T0,$T0
-+	vinserti128	\$1,16*3($inp),$T1,$T1
-+	lea		16*4($inp),$inp
-+
-+	vpsrldq		\$6,$T0,$T2		# splat input
-+	vpsrldq		\$6,$T1,$T3
-+	vpunpckhqdq	$T1,$T0,$T4		# 4
-+	vpunpcklqdq	$T3,$T2,$T2		# 2:3
-+	vpunpcklqdq	$T1,$T0,$T0		# 0:1
-+
-+	vpsrlq		\$30,$T2,$T3
-+	vpsrlq		\$4,$T2,$T2
-+	vpsrlq		\$26,$T0,$T1
-+	vpsrlq		\$40,$T4,$T4		# 4
-+	vpand		$MASK,$T2,$T2		# 2
-+	vpand		$MASK,$T0,$T0		# 0
-+	vpand		$MASK,$T1,$T1		# 1
-+	vpand		$MASK,$T3,$T3		# 3
-+	vpor		32(%rcx),$T4,$T4	# padbit, yes, always
-+
-+	lea		0x90(%rsp),%rax		# size optimization
-+	vpaddq		$H2,$T2,$H2		# accumulate input
-+	sub		\$64,$len
-+	jz		.Ltail_avx2
-+	jmp		.Loop_avx2
-+
-+.align	32
-+.Loop_avx2:
-+	################################################################
-+	# ((inp[0]*r^4+r[4])*r^4+r[8])*r^4
-+	# ((inp[1]*r^4+r[5])*r^4+r[9])*r^3
-+	# ((inp[2]*r^4+r[6])*r^4+r[10])*r^2
-+	# ((inp[3]*r^4+r[7])*r^4+r[11])*r^1
-+	#   \________/\________/
-+	################################################################
-+	#vpaddq		$H2,$T2,$H2		# accumulate input
-+	vpaddq		$H0,$T0,$H0
-+	vmovdqa		`32*0`(%rsp),$T0	# r0^4
-+	vpaddq		$H1,$T1,$H1
-+	vmovdqa		`32*1`(%rsp),$T1	# r1^4
-+	vpaddq		$H3,$T3,$H3
-+	vmovdqa		`32*3`(%rsp),$T2	# r2^4
-+	vpaddq		$H4,$T4,$H4
-+	vmovdqa		`32*6-0x90`(%rax),$T3	# s3^4
-+	vmovdqa		`32*8-0x90`(%rax),$S4	# s4^4
-+
-+	# d4 = h4*r0 + h3*r1   + h2*r2   + h1*r3   + h0*r4
-+	# d3 = h3*r0 + h2*r1   + h1*r2   + h0*r3   + h4*5*r4
-+	# d2 = h2*r0 + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	# d1 = h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3 + h2*5*r4
-+	# d0 = h0*r0 + h4*5*r1 + h3*5*r2 + h2*5*r3 + h1*5*r4
-+	#
-+	# however, as h2 is "chronologically" first one available pull
-+	# corresponding operations up, so it's
-+	#
-+	# d4 = h2*r2   + h4*r0 + h3*r1             + h1*r3   + h0*r4
-+	# d3 = h2*r1   + h3*r0           + h1*r2   + h0*r3   + h4*5*r4
-+	# d2 = h2*r0           + h1*r1   + h0*r2   + h4*5*r3 + h3*5*r4
-+	# d1 = h2*5*r4 + h1*r0 + h0*r1   + h4*5*r2 + h3*5*r3
-+	# d0 = h2*5*r3 + h0*r0 + h4*5*r1 + h3*5*r2           + h1*5*r4
-+
-+	vpmuludq	$H2,$T0,$D2		# d2 = h2*r0
-+	vpmuludq	$H2,$T1,$D3		# d3 = h2*r1
-+	vpmuludq	$H2,$T2,$D4		# d4 = h2*r2
-+	vpmuludq	$H2,$T3,$D0		# d0 = h2*s3
-+	vpmuludq	$H2,$S4,$D1		# d1 = h2*s4
-+
-+	vpmuludq	$H0,$T1,$T4		# h0*r1
-+	vpmuludq	$H1,$T1,$H2		# h1*r1, borrow $H2 as temp
-+	vpaddq		$T4,$D1,$D1		# d1 += h0*r1
-+	vpaddq		$H2,$D2,$D2		# d2 += h1*r1
-+	vpmuludq	$H3,$T1,$T4		# h3*r1
-+	vpmuludq	`32*2`(%rsp),$H4,$H2	# h4*s1
-+	vpaddq		$T4,$D4,$D4		# d4 += h3*r1
-+	vpaddq		$H2,$D0,$D0		# d0 += h4*s1
-+	 vmovdqa	`32*4-0x90`(%rax),$T1	# s2
-+
-+	vpmuludq	$H0,$T0,$T4		# h0*r0
-+	vpmuludq	$H1,$T0,$H2		# h1*r0
-+	vpaddq		$T4,$D0,$D0		# d0 += h0*r0
-+	vpaddq		$H2,$D1,$D1		# d1 += h1*r0
-+	vpmuludq	$H3,$T0,$T4		# h3*r0
-+	vpmuludq	$H4,$T0,$H2		# h4*r0
-+	 vmovdqu	16*0($inp),%x#$T0	# load input
-+	vpaddq		$T4,$D3,$D3		# d3 += h3*r0
-+	vpaddq		$H2,$D4,$D4		# d4 += h4*r0
-+	 vinserti128	\$1,16*2($inp),$T0,$T0
-+
-+	vpmuludq	$H3,$T1,$T4		# h3*s2
-+	vpmuludq	$H4,$T1,$H2		# h4*s2
-+	 vmovdqu	16*1($inp),%x#$T1
-+	vpaddq		$T4,$D0,$D0		# d0 += h3*s2
-+	vpaddq		$H2,$D1,$D1		# d1 += h4*s2
-+	 vmovdqa	`32*5-0x90`(%rax),$H2	# r3
-+	vpmuludq	$H1,$T2,$T4		# h1*r2
-+	vpmuludq	$H0,$T2,$T2		# h0*r2
-+	vpaddq		$T4,$D3,$D3		# d3 += h1*r2
-+	vpaddq		$T2,$D2,$D2		# d2 += h0*r2
-+	 vinserti128	\$1,16*3($inp),$T1,$T1
-+	 lea		16*4($inp),$inp
-+
-+	vpmuludq	$H1,$H2,$T4		# h1*r3
-+	vpmuludq	$H0,$H2,$H2		# h0*r3
-+	 vpsrldq	\$6,$T0,$T2		# splat input
-+	vpaddq		$T4,$D4,$D4		# d4 += h1*r3
-+	vpaddq		$H2,$D3,$D3		# d3 += h0*r3
-+	vpmuludq	$H3,$T3,$T4		# h3*s3
-+	vpmuludq	$H4,$T3,$H2		# h4*s3
-+	 vpsrldq	\$6,$T1,$T3
-+	vpaddq		$T4,$D1,$D1		# d1 += h3*s3
-+	vpaddq		$H2,$D2,$D2		# d2 += h4*s3
-+	 vpunpckhqdq	$T1,$T0,$T4		# 4
-+
-+	vpmuludq	$H3,$S4,$H3		# h3*s4
-+	vpmuludq	$H4,$S4,$H4		# h4*s4
-+	 vpunpcklqdq	$T1,$T0,$T0		# 0:1
-+	vpaddq		$H3,$D2,$H2		# h2 = d2 + h3*r4
-+	vpaddq		$H4,$D3,$H3		# h3 = d3 + h4*r4
-+	 vpunpcklqdq	$T3,$T2,$T3		# 2:3
-+	vpmuludq	`32*7-0x90`(%rax),$H0,$H4	# h0*r4
-+	vpmuludq	$H1,$S4,$H0		# h1*s4
-+	vmovdqa		64(%rcx),$MASK		# .Lmask26
-+	vpaddq		$H4,$D4,$H4		# h4 = d4 + h0*r4
-+	vpaddq		$H0,$D0,$H0		# h0 = d0 + h1*s4
-+
-+	################################################################
-+	# lazy reduction (interleaved with tail of input splat)
-+
-+	vpsrlq		\$26,$H3,$D3
-+	vpand		$MASK,$H3,$H3
-+	vpaddq		$D3,$H4,$H4		# h3 -> h4
-+
-+	vpsrlq		\$26,$H0,$D0
-+	vpand		$MASK,$H0,$H0
-+	vpaddq		$D0,$D1,$H1		# h0 -> h1
-+
-+	vpsrlq		\$26,$H4,$D4
-+	vpand		$MASK,$H4,$H4
-+
-+	 vpsrlq		\$4,$T3,$T2
-+
-+	vpsrlq		\$26,$H1,$D1
-+	vpand		$MASK,$H1,$H1
-+	vpaddq		$D1,$H2,$H2		# h1 -> h2
-+
-+	vpaddq		$D4,$H0,$H0
-+	vpsllq		\$2,$D4,$D4
-+	vpaddq		$D4,$H0,$H0		# h4 -> h0
-+
-+	 vpand		$MASK,$T2,$T2		# 2
-+	 vpsrlq		\$26,$T0,$T1
-+
-+	vpsrlq		\$26,$H2,$D2
-+	vpand		$MASK,$H2,$H2
-+	vpaddq		$D2,$H3,$H3		# h2 -> h3
-+
-+	 vpaddq		$T2,$H2,$H2		# modulo-scheduled
-+	 vpsrlq		\$30,$T3,$T3
-+
-+	vpsrlq		\$26,$H0,$D0
-+	vpand		$MASK,$H0,$H0
-+	vpaddq		$D0,$H1,$H1		# h0 -> h1
-+
-+	 vpsrlq		\$40,$T4,$T4		# 4
-+
-+	vpsrlq		\$26,$H3,$D3
-+	vpand		$MASK,$H3,$H3
-+	vpaddq		$D3,$H4,$H4		# h3 -> h4
-+
-+	 vpand		$MASK,$T0,$T0		# 0
-+	 vpand		$MASK,$T1,$T1		# 1
-+	 vpand		$MASK,$T3,$T3		# 3
-+	 vpor		32(%rcx),$T4,$T4	# padbit, yes, always
-+
-+	sub		\$64,$len
-+	jnz		.Loop_avx2
-+
-+	.byte		0x66,0x90
-+.Ltail_avx2:
-+	################################################################
-+	# while above multiplications were by r^4 in all lanes, in last
-+	# iteration we multiply least significant lane by r^4 and most
-+	# significant one by r, so copy of above except that references
-+	# to the precomputed table are displaced by 4...
-+
-+	#vpaddq		$H2,$T2,$H2		# accumulate input
-+	vpaddq		$H0,$T0,$H0
-+	vmovdqu		`32*0+4`(%rsp),$T0	# r0^4
-+	vpaddq		$H1,$T1,$H1
-+	vmovdqu		`32*1+4`(%rsp),$T1	# r1^4
-+	vpaddq		$H3,$T3,$H3
-+	vmovdqu		`32*3+4`(%rsp),$T2	# r2^4
-+	vpaddq		$H4,$T4,$H4
-+	vmovdqu		`32*6+4-0x90`(%rax),$T3	# s3^4
-+	vmovdqu		`32*8+4-0x90`(%rax),$S4	# s4^4
-+
-+	vpmuludq	$H2,$T0,$D2		# d2 = h2*r0
-+	vpmuludq	$H2,$T1,$D3		# d3 = h2*r1
-+	vpmuludq	$H2,$T2,$D4		# d4 = h2*r2
-+	vpmuludq	$H2,$T3,$D0		# d0 = h2*s3
-+	vpmuludq	$H2,$S4,$D1		# d1 = h2*s4
-+
-+	vpmuludq	$H0,$T1,$T4		# h0*r1
-+	vpmuludq	$H1,$T1,$H2		# h1*r1
-+	vpaddq		$T4,$D1,$D1		# d1 += h0*r1
-+	vpaddq		$H2,$D2,$D2		# d2 += h1*r1
-+	vpmuludq	$H3,$T1,$T4		# h3*r1
-+	vpmuludq	`32*2+4`(%rsp),$H4,$H2	# h4*s1
-+	vpaddq		$T4,$D4,$D4		# d4 += h3*r1
-+	vpaddq		$H2,$D0,$D0		# d0 += h4*s1
-+
-+	vpmuludq	$H0,$T0,$T4		# h0*r0
-+	vpmuludq	$H1,$T0,$H2		# h1*r0
-+	vpaddq		$T4,$D0,$D0		# d0 += h0*r0
-+	 vmovdqu	`32*4+4-0x90`(%rax),$T1	# s2
-+	vpaddq		$H2,$D1,$D1		# d1 += h1*r0
-+	vpmuludq	$H3,$T0,$T4		# h3*r0
-+	vpmuludq	$H4,$T0,$H2		# h4*r0
-+	vpaddq		$T4,$D3,$D3		# d3 += h3*r0
-+	vpaddq		$H2,$D4,$D4		# d4 += h4*r0
-+
-+	vpmuludq	$H3,$T1,$T4		# h3*s2
-+	vpmuludq	$H4,$T1,$H2		# h4*s2
-+	vpaddq		$T4,$D0,$D0		# d0 += h3*s2
-+	vpaddq		$H2,$D1,$D1		# d1 += h4*s2
-+	 vmovdqu	`32*5+4-0x90`(%rax),$H2	# r3
-+	vpmuludq	$H1,$T2,$T4		# h1*r2
-+	vpmuludq	$H0,$T2,$T2		# h0*r2
-+	vpaddq		$T4,$D3,$D3		# d3 += h1*r2
-+	vpaddq		$T2,$D2,$D2		# d2 += h0*r2
-+
-+	vpmuludq	$H1,$H2,$T4		# h1*r3
-+	vpmuludq	$H0,$H2,$H2		# h0*r3
-+	vpaddq		$T4,$D4,$D4		# d4 += h1*r3
-+	vpaddq		$H2,$D3,$D3		# d3 += h0*r3
-+	vpmuludq	$H3,$T3,$T4		# h3*s3
-+	vpmuludq	$H4,$T3,$H2		# h4*s3
-+	vpaddq		$T4,$D1,$D1		# d1 += h3*s3
-+	vpaddq		$H2,$D2,$D2		# d2 += h4*s3
-+
-+	vpmuludq	$H3,$S4,$H3		# h3*s4
-+	vpmuludq	$H4,$S4,$H4		# h4*s4
-+	vpaddq		$H3,$D2,$H2		# h2 = d2 + h3*r4
-+	vpaddq		$H4,$D3,$H3		# h3 = d3 + h4*r4
-+	vpmuludq	`32*7+4-0x90`(%rax),$H0,$H4		# h0*r4
-+	vpmuludq	$H1,$S4,$H0		# h1*s4
-+	vmovdqa		64(%rcx),$MASK		# .Lmask26
-+	vpaddq		$H4,$D4,$H4		# h4 = d4 + h0*r4
-+	vpaddq		$H0,$D0,$H0		# h0 = d0 + h1*s4
-+
-+	################################################################
-+	# horizontal addition
-+
-+	vpsrldq		\$8,$D1,$T1
-+	vpsrldq		\$8,$H2,$T2
-+	vpsrldq		\$8,$H3,$T3
-+	vpsrldq		\$8,$H4,$T4
-+	vpsrldq		\$8,$H0,$T0
-+	vpaddq		$T1,$D1,$D1
-+	vpaddq		$T2,$H2,$H2
-+	vpaddq		$T3,$H3,$H3
-+	vpaddq		$T4,$H4,$H4
-+	vpaddq		$T0,$H0,$H0
-+
-+	vpermq		\$0x2,$H3,$T3
-+	vpermq		\$0x2,$H4,$T4
-+	vpermq		\$0x2,$H0,$T0
-+	vpermq		\$0x2,$D1,$T1
-+	vpermq		\$0x2,$H2,$T2
-+	vpaddq		$T3,$H3,$H3
-+	vpaddq		$T4,$H4,$H4
-+	vpaddq		$T0,$H0,$H0
-+	vpaddq		$T1,$D1,$D1
-+	vpaddq		$T2,$H2,$H2
-+
-+	################################################################
-+	# lazy reduction
-+
-+	vpsrlq		\$26,$H3,$D3
-+	vpand		$MASK,$H3,$H3
-+	vpaddq		$D3,$H4,$H4		# h3 -> h4
-+
-+	vpsrlq		\$26,$H0,$D0
-+	vpand		$MASK,$H0,$H0
-+	vpaddq		$D0,$D1,$H1		# h0 -> h1
-+
-+	vpsrlq		\$26,$H4,$D4
-+	vpand		$MASK,$H4,$H4
-+
-+	vpsrlq		\$26,$H1,$D1
-+	vpand		$MASK,$H1,$H1
-+	vpaddq		$D1,$H2,$H2		# h1 -> h2
-+
-+	vpaddq		$D4,$H0,$H0
-+	vpsllq		\$2,$D4,$D4
-+	vpaddq		$D4,$H0,$H0		# h4 -> h0
-+
-+	vpsrlq		\$26,$H2,$D2
-+	vpand		$MASK,$H2,$H2
-+	vpaddq		$D2,$H3,$H3		# h2 -> h3
-+
-+	vpsrlq		\$26,$H0,$D0
-+	vpand		$MASK,$H0,$H0
-+	vpaddq		$D0,$H1,$H1		# h0 -> h1
-+
-+	vpsrlq		\$26,$H3,$D3
-+	vpand		$MASK,$H3,$H3
-+	vpaddq		$D3,$H4,$H4		# h3 -> h4
-+
-+	vmovd		%x#$H0,`4*0-48-64`($ctx)# save partially reduced
-+	vmovd		%x#$H1,`4*1-48-64`($ctx)
-+	vmovd		%x#$H2,`4*2-48-64`($ctx)
-+	vmovd		%x#$H3,`4*3-48-64`($ctx)
-+	vmovd		%x#$H4,`4*4-48-64`($ctx)
-+___
-+$code.=<<___	if ($win64);
-+	vmovdqa		0x50(%r11),%xmm6
-+	vmovdqa		0x60(%r11),%xmm7
-+	vmovdqa		0x70(%r11),%xmm8
-+	vmovdqa		0x80(%r11),%xmm9
-+	vmovdqa		0x90(%r11),%xmm10
-+	vmovdqa		0xa0(%r11),%xmm11
-+	vmovdqa		0xb0(%r11),%xmm12
-+	vmovdqa		0xc0(%r11),%xmm13
-+	vmovdqa		0xd0(%r11),%xmm14
-+	vmovdqa		0xe0(%r11),%xmm15
-+	lea		0xf8(%r11),%rsp
-+.Ldo_avx2_epilogue:
-+___
-+$code.=<<___	if (!$win64);
-+	lea		8(%r11),%rsp
-+___
-+$code.=<<___;
-+	vzeroupper
-+	ret
-+.size	poly1305_blocks_avx2,.-poly1305_blocks_avx2
-+___
-+}
-+$code.=<<___;
-+.align	64
-+.Lconst:
-+.Lmask24:
-+.long	0x0ffffff,0,0x0ffffff,0,0x0ffffff,0,0x0ffffff,0
-+.L129:
-+.long	`1<<24`,0,`1<<24`,0,`1<<24`,0,`1<<24`,0
-+.Lmask26:
-+.long	0x3ffffff,0,0x3ffffff,0,0x3ffffff,0,0x3ffffff,0
-+.Lfive:
-+.long	5,0,5,0,5,0,5,0
-+___
-+}
-+
-+$code.=<<___;
-+.asciz	"Poly1305 for x86_64, CRYPTOGAMS by "
-+.align	16
-+___
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->Rip<.Lprologue
-+	jb	.Lcommon_seh_tail
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
-+	jae	.Lcommon_seh_tail
-+
-+	lea	48(%rax),%rax
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R14
-+
-+	jmp	.Lcommon_seh_tail
-+.size	se_handler,.-se_handler
-+
-+.type	avx_handler,\@abi-omnipotent
-+.align	16
-+avx_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+
-+	mov	208($context),%rax	# pull context->R11
-+
-+	lea	0x50(%rax),%rsi
-+	lea	0xf8(%rax),%rax
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+.Lcommon_seh_tail:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	avx_handler,.-avx_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_poly1305_init
-+	.rva	.LSEH_end_poly1305_init
-+	.rva	.LSEH_info_poly1305_init
-+
-+	.rva	.LSEH_begin_poly1305_blocks
-+	.rva	.LSEH_end_poly1305_blocks
-+	.rva	.LSEH_info_poly1305_blocks
-+
-+	.rva	.LSEH_begin_poly1305_emit
-+	.rva	.LSEH_end_poly1305_emit
-+	.rva	.LSEH_info_poly1305_emit
-+___
-+$code.=<<___ if ($avx);
-+	.rva	.LSEH_begin_poly1305_blocks_avx
-+	.rva	.Lbase2_64_avx
-+	.rva	.LSEH_info_poly1305_blocks_avx_1
-+
-+	.rva	.Lbase2_64_avx
-+	.rva	.Leven_avx
-+	.rva	.LSEH_info_poly1305_blocks_avx_2
-+
-+	.rva	.Leven_avx
-+	.rva	.LSEH_end_poly1305_blocks_avx
-+	.rva	.LSEH_info_poly1305_blocks_avx_3
-+
-+	.rva	.LSEH_begin_poly1305_emit_avx
-+	.rva	.LSEH_end_poly1305_emit_avx
-+	.rva	.LSEH_info_poly1305_emit_avx
-+___
-+$code.=<<___ if ($avx>1);
-+	.rva	.LSEH_begin_poly1305_blocks_avx2
-+	.rva	.Lbase2_64_avx2
-+	.rva	.LSEH_info_poly1305_blocks_avx2_1
-+
-+	.rva	.Lbase2_64_avx2
-+	.rva	.Leven_avx2
-+	.rva	.LSEH_info_poly1305_blocks_avx2_2
-+
-+	.rva	.Leven_avx2
-+	.rva	.LSEH_end_poly1305_blocks_avx2
-+	.rva	.LSEH_info_poly1305_blocks_avx2_3
-+___
-+$code.=<<___;
-+.section	.xdata
-+.align	8
-+.LSEH_info_poly1305_init:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.LSEH_begin_poly1305_init,.LSEH_begin_poly1305_init
-+
-+.LSEH_info_poly1305_blocks:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lblocks_body,.Lblocks_epilogue
-+
-+.LSEH_info_poly1305_emit:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.LSEH_begin_poly1305_emit,.LSEH_begin_poly1305_emit
-+___
-+$code.=<<___ if ($avx);
-+.LSEH_info_poly1305_blocks_avx_1:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lblocks_avx_body,.Lblocks_avx_epilogue		# HandlerData[]
-+
-+.LSEH_info_poly1305_blocks_avx_2:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lbase2_64_avx_body,.Lbase2_64_avx_epilogue	# HandlerData[]
-+
-+.LSEH_info_poly1305_blocks_avx_3:
-+	.byte	9,0,0,0
-+	.rva	avx_handler
-+	.rva	.Ldo_avx_body,.Ldo_avx_epilogue			# HandlerData[]
-+
-+.LSEH_info_poly1305_emit_avx:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.LSEH_begin_poly1305_emit_avx,.LSEH_begin_poly1305_emit_avx
-+___
-+$code.=<<___ if ($avx>1);
-+.LSEH_info_poly1305_blocks_avx2_1:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lblocks_avx2_body,.Lblocks_avx2_epilogue	# HandlerData[]
-+
-+.LSEH_info_poly1305_blocks_avx2_2:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lbase2_64_avx2_body,.Lbase2_64_avx2_epilogue	# HandlerData[]
-+
-+.LSEH_info_poly1305_blocks_avx2_3:
-+	.byte	9,0,0,0
-+	.rva	avx_handler
-+	.rva	.Ldo_avx2_body,.Ldo_avx2_epilogue		# HandlerData[]
-+___
-+}
-+
-+foreach (split('\n',$code)) {
-+	s/\`([^\`]*)\`/eval($1)/ge;
-+	s/%r([a-z]+)#d/%e$1/g;
-+	s/%r([0-9]+)#d/%r$1d/g;
-+	s/%x#%y/%x/g;
-+
-+	print $_,"\n";
-+}
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/build.info
-new file mode 100644
-index 0000000..d575f5a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/build.info
-@@ -0,0 +1,20 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        poly1305.c {- $target{poly1305_asm_src} -}
-+
-+GENERATE[poly1305-sparcv9.S]=asm/poly1305-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[poly1305-sparcv9.o]=..
-+GENERATE[poly1305-x86.s]=asm/poly1305-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+GENERATE[poly1305-x86_64.s]=asm/poly1305-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[poly1305-ppc.s]=asm/poly1305-ppc.pl $(PERLASM_SCHEME)
-+GENERATE[poly1305-ppcfp.s]=asm/poly1305-ppcfp.pl $(PERLASM_SCHEME)
-+GENERATE[poly1305-armv4.S]=asm/poly1305-armv4.pl $(PERLASM_SCHEME)
-+INCLUDE[poly1305-armv4.o]=..
-+GENERATE[poly1305-armv8.S]=asm/poly1305-armv8.pl $(PERLASM_SCHEME)
-+INCLUDE[poly1305-armv8.o]=..
-+GENERATE[poly1305-mips.S]=asm/poly1305-mips.pl $(PERLASM_SCHEME)
-+
-+BEGINRAW[Makefile(unix)]
-+{- $builddir -}/poly1305-%.S:	{- $sourcedir -}/asm/poly1305-%.pl
-+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-+ENDRAW[Makefile(unix)]
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/poly1305.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/poly1305.c
-new file mode 100644
-index 0000000..eec4d67
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/poly1305.c
-@@ -0,0 +1,1037 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+#include "internal/poly1305.h"
-+
-+typedef void (*poly1305_blocks_f) (void *ctx, const unsigned char *inp,
-+                                   size_t len, unsigned int padbit);
-+typedef void (*poly1305_emit_f) (void *ctx, unsigned char mac[16],
-+                                 const unsigned int nonce[4]);
-+
-+struct poly1305_context {
-+    double opaque[24];  /* large enough to hold internal state, declared
-+                         * 'double' to ensure at least 64-bit invariant
-+                         * alignment across all platforms and
-+                         * configurations */
-+    unsigned int nonce[4];
-+    unsigned char data[POLY1305_BLOCK_SIZE];
-+    size_t num;
-+    struct {
-+        poly1305_blocks_f blocks;
-+        poly1305_emit_f emit;
-+    } func;
-+};
-+
-+size_t Poly1305_ctx_size ()
-+{
-+    return sizeof(struct poly1305_context);
-+}
-+
-+/* pick 32-bit unsigned integer in little endian order */
-+static unsigned int U8TOU32(const unsigned char *p)
-+{
-+    return (((unsigned int)(p[0] & 0xff)) |
-+            ((unsigned int)(p[1] & 0xff) << 8) |
-+            ((unsigned int)(p[2] & 0xff) << 16) |
-+            ((unsigned int)(p[3] & 0xff) << 24));
-+}
-+
-+/*
-+ * Implementations can be classified by amount of significant bits in
-+ * words making up the multi-precision value, or in other words radix
-+ * or base of numerical representation, e.g. base 2^64, base 2^32,
-+ * base 2^26. Complementary characteristic is how wide is the result of
-+ * multiplication of pair of digits, e.g. it would take 128 bits to
-+ * accommodate multiplication result in base 2^64 case. These are used
-+ * interchangeably. To describe implementation that is. But interface
-+ * is designed to isolate this so that low-level primitives implemented
-+ * in assembly can be self-contained/self-coherent.
-+ */
-+#ifndef POLY1305_ASM
-+/*
-+ * Even though there is __int128 reference implementation targeting
-+ * 64-bit platforms provided below, it's not obvious that it's optimal
-+ * choice for every one of them. Depending on instruction set overall
-+ * amount of instructions can be comparable to one in __int64
-+ * implementation. Amount of multiplication instructions would be lower,
-+ * but not necessarily overall. And in out-of-order execution context,
-+ * it is the latter that can be crucial...
-+ *
-+ * On related note. Poly1305 author, D. J. Bernstein, discusses and
-+ * provides floating-point implementations of the algorithm in question.
-+ * It made a lot of sense by the time of introduction, because most
-+ * then-modern processors didn't have pipelined integer multiplier.
-+ * [Not to mention that some had non-constant timing for integer
-+ * multiplications.] Floating-point instructions on the other hand could
-+ * be issued every cycle, which allowed to achieve better performance.
-+ * Nowadays, with SIMD and/or out-or-order execution, shared or
-+ * even emulated FPU, it's more complicated, and floating-point
-+ * implementation is not necessarily optimal choice in every situation,
-+ * rather contrary...
-+ *
-+ *                                              
-+ */
-+
-+typedef unsigned int u32;
-+
-+/*
-+ * poly1305_blocks processes a multiple of POLY1305_BLOCK_SIZE blocks
-+ * of |inp| no longer than |len|. Behaviour for |len| not divisible by
-+ * block size is unspecified in general case, even though in reference
-+ * implementation the trailing chunk is simply ignored. Per algorithm
-+ * specification, every input block, complete or last partial, is to be
-+ * padded with a bit past most significant byte. The latter kind is then
-+ * padded with zeros till block size. This last partial block padding
-+ * is caller(*)'s responsibility, and because of this the last partial
-+ * block is always processed with separate call with |len| set to
-+ * POLY1305_BLOCK_SIZE and |padbit| to 0. In all other cases |padbit|
-+ * should be set to 1 to perform implicit padding with 128th bit.
-+ * poly1305_blocks does not actually check for this constraint though,
-+ * it's caller(*)'s responsibility to comply.
-+ *
-+ * (*)  In the context "caller" is not application code, but higher
-+ *      level Poly1305_* from this very module, so that quirks are
-+ *      handled locally.
-+ */
-+static void
-+poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, u32 padbit);
-+
-+/*
-+ * Type-agnostic "rip-off" from constant_time_locl.h
-+ */
-+# define CONSTANT_TIME_CARRY(a,b) ( \
-+         (a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(a) * 8 - 1) \
-+         )
-+
-+# if !defined(PEDANTIC) && \
-+     (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16) && \
-+     (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__==8)
-+
-+typedef unsigned long u64;
-+typedef unsigned __int128 u128;
-+
-+typedef struct {
-+    u64 h[3];
-+    u64 r[2];
-+} poly1305_internal;
-+
-+/* pick 32-bit unsigned integer in little endian order */
-+static u64 U8TOU64(const unsigned char *p)
-+{
-+    return (((u64)(p[0] & 0xff)) |
-+            ((u64)(p[1] & 0xff) << 8) |
-+            ((u64)(p[2] & 0xff) << 16) |
-+            ((u64)(p[3] & 0xff) << 24) |
-+            ((u64)(p[4] & 0xff) << 32) |
-+            ((u64)(p[5] & 0xff) << 40) |
-+            ((u64)(p[6] & 0xff) << 48) |
-+            ((u64)(p[7] & 0xff) << 56));
-+}
-+
-+/* store a 32-bit unsigned integer in little endian */
-+static void U64TO8(unsigned char *p, u64 v)
-+{
-+    p[0] = (unsigned char)((v) & 0xff);
-+    p[1] = (unsigned char)((v >> 8) & 0xff);
-+    p[2] = (unsigned char)((v >> 16) & 0xff);
-+    p[3] = (unsigned char)((v >> 24) & 0xff);
-+    p[4] = (unsigned char)((v >> 32) & 0xff);
-+    p[5] = (unsigned char)((v >> 40) & 0xff);
-+    p[6] = (unsigned char)((v >> 48) & 0xff);
-+    p[7] = (unsigned char)((v >> 56) & 0xff);
-+}
-+
-+static void poly1305_init(void *ctx, const unsigned char key[16])
-+{
-+    poly1305_internal *st = (poly1305_internal *) ctx;
-+
-+    /* h = 0 */
-+    st->h[0] = 0;
-+    st->h[1] = 0;
-+    st->h[2] = 0;
-+
-+    /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
-+    st->r[0] = U8TOU64(&key[0]) & 0x0ffffffc0fffffff;
-+    st->r[1] = U8TOU64(&key[8]) & 0x0ffffffc0ffffffc;
-+}
-+
-+static void
-+poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, u32 padbit)
-+{
-+    poly1305_internal *st = (poly1305_internal *)ctx;
-+    u64 r0, r1;
-+    u64 s1;
-+    u64 h0, h1, h2, c;
-+    u128 d0, d1;
-+
-+    r0 = st->r[0];
-+    r1 = st->r[1];
-+
-+    s1 = r1 + (r1 >> 2);
-+
-+    h0 = st->h[0];
-+    h1 = st->h[1];
-+    h2 = st->h[2];
-+
-+    while (len >= POLY1305_BLOCK_SIZE) {
-+        /* h += m[i] */
-+        h0 = (u64)(d0 = (u128)h0 + U8TOU64(inp + 0));
-+        h1 = (u64)(d1 = (u128)h1 + (d0 >> 64) + U8TOU64(inp + 8));
-+        /*
-+         * padbit can be zero only when original len was
-+         * POLY1306_BLOCK_SIZE, but we don't check
-+         */
-+        h2 += (u64)(d1 >> 64) + padbit;
-+
-+        /* h *= r "%" p, where "%" stands for "partial remainder" */
-+        d0 = ((u128)h0 * r0) +
-+             ((u128)h1 * s1);
-+        d1 = ((u128)h0 * r1) +
-+             ((u128)h1 * r0) +
-+             (h2 * s1);
-+        h2 = (h2 * r0);
-+
-+        /* last reduction step: */
-+        /* a) h2:h0 = h2<<128 + d1<<64 + d0 */
-+        h0 = (u64)d0;
-+        h1 = (u64)(d1 += d0 >> 64);
-+        h2 += (u64)(d1 >> 64);
-+        /* b) (h2:h0 += (h2:h0>>130) * 5) %= 2^130 */
-+        c = (h2 >> 2) + (h2 & ~3UL);
-+        h2 &= 3;
-+        h0 += c;
-+        h1 += (c = CONSTANT_TIME_CARRY(h0,c));
-+        h2 += CONSTANT_TIME_CARRY(h1,c);
-+        /*
-+         * Occasional overflows to 3rd bit of h2 are taken care of
-+         * "naturally". If after this point we end up at the top of
-+         * this loop, then the overflow bit will be accounted for
-+         * in next iteration. If we end up in poly1305_emit, then
-+         * comparison to modulus below will still count as "carry
-+         * into 131st bit", so that properly reduced value will be
-+         * picked in conditional move.
-+         */
-+
-+        inp += POLY1305_BLOCK_SIZE;
-+        len -= POLY1305_BLOCK_SIZE;
-+    }
-+
-+    st->h[0] = h0;
-+    st->h[1] = h1;
-+    st->h[2] = h2;
-+}
-+
-+static void poly1305_emit(void *ctx, unsigned char mac[16],
-+                          const u32 nonce[4])
-+{
-+    poly1305_internal *st = (poly1305_internal *) ctx;
-+    u64 h0, h1, h2;
-+    u64 g0, g1, g2;
-+    u128 t;
-+    u64 mask;
-+
-+    h0 = st->h[0];
-+    h1 = st->h[1];
-+    h2 = st->h[2];
-+
-+    /* compare to modulus by computing h + -p */
-+    g0 = (u64)(t = (u128)h0 + 5);
-+    g1 = (u64)(t = (u128)h1 + (t >> 64));
-+    g2 = h2 + (u64)(t >> 64);
-+
-+    /* if there was carry into 131st bit, h1:h0 = g1:g0 */
-+    mask = 0 - (g2 >> 2);
-+    g0 &= mask;
-+    g1 &= mask;
-+    mask = ~mask;
-+    h0 = (h0 & mask) | g0;
-+    h1 = (h1 & mask) | g1;
-+
-+    /* mac = (h + nonce) % (2^128) */
-+    h0 = (u64)(t = (u128)h0 + nonce[0] + ((u64)nonce[1]<<32));
-+    h1 = (u64)(t = (u128)h1 + nonce[2] + ((u64)nonce[3]<<32) + (t >> 64));
-+
-+    U64TO8(mac + 0, h0);
-+    U64TO8(mac + 8, h1);
-+}
-+
-+# else
-+
-+#  if defined(_WIN32) && !defined(__MINGW32__)
-+typedef unsigned __int64 u64;
-+#  elif defined(__arch64__)
-+typedef unsigned long u64;
-+#  else
-+typedef unsigned long long u64;
-+#  endif
-+
-+typedef struct {
-+    u32 h[5];
-+    u32 r[4];
-+} poly1305_internal;
-+
-+/* store a 32-bit unsigned integer in little endian */
-+static void U32TO8(unsigned char *p, unsigned int v)
-+{
-+    p[0] = (unsigned char)((v) & 0xff);
-+    p[1] = (unsigned char)((v >> 8) & 0xff);
-+    p[2] = (unsigned char)((v >> 16) & 0xff);
-+    p[3] = (unsigned char)((v >> 24) & 0xff);
-+}
-+
-+static void poly1305_init(void *ctx, const unsigned char key[16])
-+{
-+    poly1305_internal *st = (poly1305_internal *) ctx;
-+
-+    /* h = 0 */
-+    st->h[0] = 0;
-+    st->h[1] = 0;
-+    st->h[2] = 0;
-+    st->h[3] = 0;
-+    st->h[4] = 0;
-+
-+    /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
-+    st->r[0] = U8TOU32(&key[0]) & 0x0fffffff;
-+    st->r[1] = U8TOU32(&key[4]) & 0x0ffffffc;
-+    st->r[2] = U8TOU32(&key[8]) & 0x0ffffffc;
-+    st->r[3] = U8TOU32(&key[12]) & 0x0ffffffc;
-+}
-+
-+static void
-+poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, u32 padbit)
-+{
-+    poly1305_internal *st = (poly1305_internal *)ctx;
-+    u32 r0, r1, r2, r3;
-+    u32 s1, s2, s3;
-+    u32 h0, h1, h2, h3, h4, c;
-+    u64 d0, d1, d2, d3;
-+
-+    r0 = st->r[0];
-+    r1 = st->r[1];
-+    r2 = st->r[2];
-+    r3 = st->r[3];
-+
-+    s1 = r1 + (r1 >> 2);
-+    s2 = r2 + (r2 >> 2);
-+    s3 = r3 + (r3 >> 2);
-+
-+    h0 = st->h[0];
-+    h1 = st->h[1];
-+    h2 = st->h[2];
-+    h3 = st->h[3];
-+    h4 = st->h[4];
-+
-+    while (len >= POLY1305_BLOCK_SIZE) {
-+        /* h += m[i] */
-+        h0 = (u32)(d0 = (u64)h0 + U8TOU32(inp + 0));
-+        h1 = (u32)(d1 = (u64)h1 + (d0 >> 32) + U8TOU32(inp + 4));
-+        h2 = (u32)(d2 = (u64)h2 + (d1 >> 32) + U8TOU32(inp + 8));
-+        h3 = (u32)(d3 = (u64)h3 + (d2 >> 32) + U8TOU32(inp + 12));
-+        h4 += (u32)(d3 >> 32) + padbit;
-+
-+        /* h *= r "%" p, where "%" stands for "partial remainder" */
-+        d0 = ((u64)h0 * r0) +
-+             ((u64)h1 * s3) +
-+             ((u64)h2 * s2) +
-+             ((u64)h3 * s1);
-+        d1 = ((u64)h0 * r1) +
-+             ((u64)h1 * r0) +
-+             ((u64)h2 * s3) +
-+             ((u64)h3 * s2) +
-+             (h4 * s1);
-+        d2 = ((u64)h0 * r2) +
-+             ((u64)h1 * r1) +
-+             ((u64)h2 * r0) +
-+             ((u64)h3 * s3) +
-+             (h4 * s2);
-+        d3 = ((u64)h0 * r3) +
-+             ((u64)h1 * r2) +
-+             ((u64)h2 * r1) +
-+             ((u64)h3 * r0) +
-+             (h4 * s3);
-+        h4 = (h4 * r0);
-+
-+        /* last reduction step: */
-+        /* a) h4:h0 = h4<<128 + d3<<96 + d2<<64 + d1<<32 + d0 */
-+        h0 = (u32)d0;
-+        h1 = (u32)(d1 += d0 >> 32);
-+        h2 = (u32)(d2 += d1 >> 32);
-+        h3 = (u32)(d3 += d2 >> 32);
-+        h4 += (u32)(d3 >> 32);
-+        /* b) (h4:h0 += (h4:h0>>130) * 5) %= 2^130 */
-+        c = (h4 >> 2) + (h4 & ~3U);
-+        h4 &= 3;
-+        h0 += c;
-+        h1 += (c = CONSTANT_TIME_CARRY(h0,c));
-+        h2 += (c = CONSTANT_TIME_CARRY(h1,c));
-+        h3 += (c = CONSTANT_TIME_CARRY(h2,c));
-+        h4 += CONSTANT_TIME_CARRY(h3,c);
-+        /*
-+         * Occasional overflows to 3rd bit of h4 are taken care of
-+         * "naturally". If after this point we end up at the top of
-+         * this loop, then the overflow bit will be accounted for
-+         * in next iteration. If we end up in poly1305_emit, then
-+         * comparison to modulus below will still count as "carry
-+         * into 131st bit", so that properly reduced value will be
-+         * picked in conditional move.
-+         */
-+
-+        inp += POLY1305_BLOCK_SIZE;
-+        len -= POLY1305_BLOCK_SIZE;
-+    }
-+
-+    st->h[0] = h0;
-+    st->h[1] = h1;
-+    st->h[2] = h2;
-+    st->h[3] = h3;
-+    st->h[4] = h4;
-+}
-+
-+static void poly1305_emit(void *ctx, unsigned char mac[16],
-+                          const u32 nonce[4])
-+{
-+    poly1305_internal *st = (poly1305_internal *) ctx;
-+    u32 h0, h1, h2, h3, h4;
-+    u32 g0, g1, g2, g3, g4;
-+    u64 t;
-+    u32 mask;
-+
-+    h0 = st->h[0];
-+    h1 = st->h[1];
-+    h2 = st->h[2];
-+    h3 = st->h[3];
-+    h4 = st->h[4];
-+
-+    /* compare to modulus by computing h + -p */
-+    g0 = (u32)(t = (u64)h0 + 5);
-+    g1 = (u32)(t = (u64)h1 + (t >> 32));
-+    g2 = (u32)(t = (u64)h2 + (t >> 32));
-+    g3 = (u32)(t = (u64)h3 + (t >> 32));
-+    g4 = h4 + (u32)(t >> 32);
-+
-+    /* if there was carry into 131st bit, h3:h0 = g3:g0 */
-+    mask = 0 - (g4 >> 2);
-+    g0 &= mask;
-+    g1 &= mask;
-+    g2 &= mask;
-+    g3 &= mask;
-+    mask = ~mask;
-+    h0 = (h0 & mask) | g0;
-+    h1 = (h1 & mask) | g1;
-+    h2 = (h2 & mask) | g2;
-+    h3 = (h3 & mask) | g3;
-+
-+    /* mac = (h + nonce) % (2^128) */
-+    h0 = (u32)(t = (u64)h0 + nonce[0]);
-+    h1 = (u32)(t = (u64)h1 + (t >> 32) + nonce[1]);
-+    h2 = (u32)(t = (u64)h2 + (t >> 32) + nonce[2]);
-+    h3 = (u32)(t = (u64)h3 + (t >> 32) + nonce[3]);
-+
-+    U32TO8(mac + 0, h0);
-+    U32TO8(mac + 4, h1);
-+    U32TO8(mac + 8, h2);
-+    U32TO8(mac + 12, h3);
-+}
-+# endif
-+#else
-+int poly1305_init(void *ctx, const unsigned char key[16], void *func);
-+void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len,
-+                     unsigned int padbit);
-+void poly1305_emit(void *ctx, unsigned char mac[16],
-+                   const unsigned int nonce[4]);
-+#endif
-+
-+void Poly1305_Init(POLY1305 *ctx, const unsigned char key[32])
-+{
-+    ctx->nonce[0] = U8TOU32(&key[16]);
-+    ctx->nonce[1] = U8TOU32(&key[20]);
-+    ctx->nonce[2] = U8TOU32(&key[24]);
-+    ctx->nonce[3] = U8TOU32(&key[28]);
-+
-+#ifndef POLY1305_ASM
-+    poly1305_init(ctx->opaque, key);
-+#else
-+    /*
-+     * Unlike reference poly1305_init assembly counterpart is expected
-+     * to return a value: non-zero if it initializes ctx->func, and zero
-+     * otherwise. Latter is to simplify assembly in cases when there no
-+     * multiple code paths to switch between.
-+     */
-+    if (!poly1305_init(ctx->opaque, key, &ctx->func)) {
-+        ctx->func.blocks = poly1305_blocks;
-+        ctx->func.emit = poly1305_emit;
-+    }
-+#endif
-+
-+    ctx->num = 0;
-+
-+}
-+
-+#ifdef POLY1305_ASM
-+/*
-+ * This "eclipses" poly1305_blocks and poly1305_emit, but it's
-+ * conscious choice imposed by -Wshadow compiler warnings.
-+ */
-+# define poly1305_blocks (*poly1305_blocks_p)
-+# define poly1305_emit   (*poly1305_emit_p)
-+#endif
-+
-+void Poly1305_Update(POLY1305 *ctx, const unsigned char *inp, size_t len)
-+{
-+#ifdef POLY1305_ASM
-+    /*
-+     * As documented, poly1305_blocks is never called with input
-+     * longer than single block and padbit argument set to 0. This
-+     * property is fluently used in assembly modules to optimize
-+     * padbit handling on loop boundary.
-+     */
-+    poly1305_blocks_f poly1305_blocks_p = ctx->func.blocks;
-+#endif
-+    size_t rem, num;
-+
-+    if ((num = ctx->num)) {
-+        rem = POLY1305_BLOCK_SIZE - num;
-+        if (len >= rem) {
-+            memcpy(ctx->data + num, inp, rem);
-+            poly1305_blocks(ctx->opaque, ctx->data, POLY1305_BLOCK_SIZE, 1);
-+            inp += rem;
-+            len -= rem;
-+        } else {
-+            /* Still not enough data to process a block. */
-+            memcpy(ctx->data + num, inp, len);
-+            ctx->num = num + len;
-+            return;
-+        }
-+    }
-+
-+    rem = len % POLY1305_BLOCK_SIZE;
-+    len -= rem;
-+
-+    if (len >= POLY1305_BLOCK_SIZE) {
-+        poly1305_blocks(ctx->opaque, inp, len, 1);
-+        inp += len;
-+    }
-+
-+    if (rem)
-+        memcpy(ctx->data, inp, rem);
-+
-+    ctx->num = rem;
-+}
-+
-+void Poly1305_Final(POLY1305 *ctx, unsigned char mac[16])
-+{
-+#ifdef POLY1305_ASM
-+    poly1305_blocks_f poly1305_blocks_p = ctx->func.blocks;
-+    poly1305_emit_f poly1305_emit_p = ctx->func.emit;
-+#endif
-+    size_t num;
-+
-+    if ((num = ctx->num)) {
-+        ctx->data[num++] = 1;   /* pad bit */
-+        while (num < POLY1305_BLOCK_SIZE)
-+            ctx->data[num++] = 0;
-+        poly1305_blocks(ctx->opaque, ctx->data, POLY1305_BLOCK_SIZE, 0);
-+    }
-+
-+    poly1305_emit(ctx->opaque, mac, ctx->nonce);
-+
-+    /* zero out the state */
-+    OPENSSL_cleanse(ctx, sizeof(*ctx));
-+}
-+
-+#ifdef SELFTEST
-+#include 
-+
-+struct poly1305_test {
-+    const char *inputhex;
-+    const char *keyhex;
-+    const char *outhex;
-+};
-+
-+static const struct poly1305_test poly1305_tests[] = {
-+    /*
-+     * RFC7539
-+     */
-+    {
-+     "43727970746f6772617068696320466f72756d2052657365617263682047726f"
-+     "7570",
-+     "85d6be7857556d337f4452fe42d506a8""0103808afb0db2fd4abff6af4149f51b",
-+     "a8061dc1305136c6c22b8baf0c0127a9"
-+    },
-+    /*
-+     * test vectors from "The Poly1305-AES message-authentication code"
-+     */
-+    {
-+     "f3f6",
-+     "851fc40c3467ac0be05cc20404f3f700""580b3b0f9447bb1e69d095b5928b6dbc",
-+     "f4c633c3044fc145f84f335cb81953de"
-+    },
-+    {
-+     "",
-+     "a0f3080000f46400d0c7e9076c834403""dd3fab2251f11ac759f0887129cc2ee7",
-+     "dd3fab2251f11ac759f0887129cc2ee7"
-+    },
-+    {
-+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136",
-+     "48443d0bb0d21109c89a100b5ce2c208""83149c69b561dd88298a1798b10716ef",
-+     "0ee1c16bb73f0f4fd19881753c01cdbe"
-+    },
-+    {
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9",
-+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
-+     "5154ad0d2cb26e01274fc51148491f1b"
-+    },
-+    /*
-+     * self-generated vectors exercise "significant" lengths, such that
-+     * are handled by different code paths
-+     */
-+    {
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af",
-+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
-+     "812059a5da198637cac7c4a631bee466"
-+    },
-+    {
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67",
-+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
-+     "5b88d7f6228b11e2e28579a5c0c1f761"
-+    },
-+    {
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
-+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136",
-+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
-+     "bbb613b2b6d753ba07395b916aaece15"
-+    },
-+    {
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
-+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
-+     "663cea190ffb83d89593f3f476b6bc24",
-+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
-+     "c794d7057d1778c4bbee0a39b3d97342"
-+    },
-+    {
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
-+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
-+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136",
-+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
-+     "ffbcb9b371423152d7fca5ad042fbaa9"
-+    },
-+    {
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
-+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
-+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136"
-+     "812059a5da198637cac7c4a631bee466",
-+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
-+     "069ed6b8ef0f207b3e243bb1019fe632"
-+    },
-+    {
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
-+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
-+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136"
-+     "812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761",
-+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
-+     "cca339d9a45fa2368c2c68b3a4179133"
-+    },
-+    {
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
-+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
-+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136"
-+     "812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761"
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
-+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
-+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136",
-+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
-+     "53f6e828a2f0fe0ee815bf0bd5841a34"
-+    },
-+    {
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
-+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
-+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136"
-+     "812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761"
-+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
-+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
-+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
-+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136"
-+     "812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761",
-+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
-+     "b846d44e9bbd53cedffbfbb6b7fa4933"
-+    },
-+    /*
-+     * 4th power of the key spills to 131th bit in SIMD key setup
-+     */
-+    {
-+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
-+     "ad628107e8351d0f2c231a05dc4a4106""00000000000000000000000000000000",
-+     "07145a4c02fe5fa32036de68fabe9066"
-+    },
-+    {
-+    /*
-+     * poly1305_ieee754.c failed this in final stage
-+     */
-+     "842364e156336c0998b933a6237726180d9e3fdcbde4cd5d17080fc3beb49614"
-+     "d7122c037463ff104d73f19c12704628d417c4c54a3fe30d3c3d7714382d43b0"
-+     "382a50a5dee54be844b076e8df88201a1cd43b90eb21643fa96f39b518aa8340"
-+     "c942ff3c31baf7c9bdbf0f31ae3fa096bf8c63030609829fe72e179824890bc8"
-+     "e08c315c1cce2a83144dbbff09f74e3efc770b54d0984a8f19b14719e6363564"
-+     "1d6b1eedf63efbf080e1783d32445412114c20de0b837a0dfa33d6b82825fff4"
-+     "4c9a70ea54ce47f07df698e6b03323b53079364a5fc3e9dd034392bdde86dccd"
-+     "da94321c5e44060489336cb65bf3989c36f7282c2f5d2b882c171e74",
-+     "95d5c005503e510d8cd0aa072c4a4d06""6eabc52d11653df47fbf63ab198bcc26",
-+     "f248312e578d9d58f8b7bb4d19105431"
-+    },
-+    /*
-+     * AVX2 in poly1305-x86.pl failed this with 176+32 split
-+     */
-+    {
-+    "248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd"
-+    "2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e8"
-+    "74cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c"
-+    "8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936a"
-+    "ff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a37"
-+    "09894e4eb0a4eedc4ae19468e66b81f2"
-+    "71351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb",
-+    "000102030405060708090a0b0c0d0e0f""00000000000000000000000000000000",
-+    "bc939bc5281480fa99c6d68c258ec42f"
-+    },
-+    /*
-+     * test vectors from Google
-+     */
-+    {
-+     "",
-+     "c8afaac331ee372cd6082de134943b17""4710130e9f6fea8d72293850a667d86c",
-+     "4710130e9f6fea8d72293850a667d86c",
-+    },
-+    {
-+     "48656c6c6f20776f726c6421",
-+     "746869732069732033322d6279746520""6b657920666f7220506f6c7931333035",
-+     "a6f745008f81c916a20dcc74eef2b2f0"
-+    },
-+    {
-+     "0000000000000000000000000000000000000000000000000000000000000000",
-+     "746869732069732033322d6279746520""6b657920666f7220506f6c7931333035",
-+     "49ec78090e481ec6c26b33b91ccc0307"
-+    },
-+    {
-+     "89dab80b7717c1db5db437860a3f70218e93e1b8f461fb677f16f35f6f87e2a9"
-+     "1c99bc3a47ace47640cc95c345be5ecca5a3523c35cc01893af0b64a62033427"
-+     "0372ec12482d1b1e363561698a578b359803495bb4e2ef1930b17a5190b580f1"
-+     "41300df30adbeca28f6427a8bc1a999fd51c554a017d095d8c3e3127daf9f595",
-+     "2d773be37adb1e4d683bf0075e79c4ee""037918535a7f99ccb7040fb5f5f43aea",
-+     "c85d15ed44c378d6b00e23064c7bcd51"
-+    },
-+    {
-+     "000000000000000b1703030200000000"
-+     "06db1f1f368d696a810a349c0c714c9a5e7850c2407d721acded95e018d7a852"
-+     "66a6e1289cdb4aeb18da5ac8a2b0026d24a59ad485227f3eaedbb2e7e35e1c66"
-+     "cd60f9abf716dcc9ac42682dd7dab287a7024c4eefc321cc0574e16793e37cec"
-+     "03c5bda42b54c114a80b57af26416c7be742005e20855c73e21dc8e2edc9d435"
-+     "cb6f6059280011c270b71570051c1c9b3052126620bc1e2730fa066c7a509d53"
-+     "c60e5ae1b40aa6e39e49669228c90eecb4a50db32a50bc49e90b4f4b359a1dfd"
-+     "11749cd3867fcf2fb7bb6cd4738f6a4ad6f7ca5058f7618845af9f020f6c3b96"
-+     "7b8f4cd4a91e2813b507ae66f2d35c18284f7292186062e10fd5510d18775351"
-+     "ef334e7634ab4743f5b68f49adcab384d3fd75f7390f4006ef2a295c8c7a076a"
-+     "d54546cd25d2107fbe1436c840924aaebe5b370893cd63d1325b8616fc481088"
-+     "6bc152c53221b6df373119393255ee72bcaa880174f1717f9184fa91646f17a2"
-+     "4ac55d16bfddca9581a92eda479201f0edbf633600d6066d1ab36d5d2415d713"
-+     "51bbcd608a25108d25641992c1f26c531cf9f90203bc4cc19f5927d834b0a471"
-+     "16d3884bbb164b8ec883d1ac832e56b3918a98601a08d171881541d594db399c"
-+     "6ae6151221745aec814c45b0b05b565436fd6f137aa10a0c0b643761dbd6f9a9"
-+     "dcb99b1a6e690854ce0769cde39761d82fcdec15f0d92d7d8e94ade8eb83fbe0",
-+     "99e5822dd4173c995e3dae0ddefb9774""3fde3b080134b39f76e9bf8d0e88d546",
-+     "2637408fe13086ea73f971e3425e2820"
-+    },
-+    /*
-+     * test vectors from Hanno Böck
-+     */
-+    {
-+     "cccccccccccccccccccccccccccccccccccccccccccccccccc80cccccccccccc"
-+     "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccecccccc"
-+     "ccccccccccccccccccccccccccccccc5cccccccccccccccccccccccccccccccc"
-+     "cccccccccce3cccccccccccccccccccccccccccccccccccccccccccccccccccc"
-+     "ccccccccaccccccccccccccccccccce6cccccccccc000000afcccccccccccccc"
-+     "ccccfffffff50000000000000000000000000000000000000000000000000000"
-+     "00ffffffe7000000000000000000000000000000000000000000000000000000"
-+     "0000000000000000000000000000000000000000000000000000719205a8521d"
-+     "fc",
-+     "7f1b0264000000000000000000000000""0000000000000000cccccccccccccccc",
-+     "8559b876eceed66eb37798c0457baff9"
-+    },
-+    {
-+     "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000"
-+     "00000000800264",
-+     "e0001600000000000000000000000000""0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-+     "00bd1258978e205444c9aaaa82006fed"
-+    },
-+    {
-+     "02fc",
-+     "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c""0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c",
-+     "06120c0c0c0c0c0c0c0c0c0c0c0c0c0c"
-+    },
-+    {
-+     "7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b"
-+     "7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b"
-+     "7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b"
-+     "7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b007b7b7b7b7b7b7b7b7b"
-+     "7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b"
-+     "7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b"
-+     "7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b"
-+     "7b6e7b001300000000b300000000000000000000000000000000000000000000"
-+     "f20000000000000000000000000000000000002000efff000900000000000000"
-+     "0000000000100000000009000000640000000000000000000000001300000000"
-+     "b300000000000000000000000000000000000000000000f20000000000000000"
-+     "000000000000000000002000efff00090000000000000000007a000010000000"
-+     "000900000064000000000000000000000000000000000000000000000000fc",
-+     "00ff0000000000000000000000000000""00000000001e00000000000000007b7b",
-+     "33205bbf9e9f8f7212ab9e2ab9b7e4a5"
-+    },
-+    {
-+     "7777777777777777777777777777777777777777777777777777777777777777"
-+     "7777777777777777777777777777777777777777777777777777777777777777"
-+     "777777777777777777777777ffffffe9e9acacacacacacacacacacac0000acac"
-+     "ec0100acacac2caca2acacacacacacacacacacac64f2",
-+     "0000007f0000007f0100002000000000""0000cf77777777777777777777777777",
-+     "02ee7c8c546ddeb1a467e4c3981158b9"
-+    },
-+    /*
-+     * test vectors from Andrew Moon
-+     */
-+    {   /* nacl */
-+     "8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186a"
-+     "c0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738"
-+     "b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da"
-+     "99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74"
-+     "e355a5",
-+     "eea6a7251c1e72916d11c2cb214d3c25""2539121d8e234e652d651fa4c8cff880",
-+     "f3ffc7703f9400e52a7dfb4b3d3305d9"
-+    },
-+    {   /* wrap 2^130-5 */
-+     "ffffffffffffffffffffffffffffffff",
-+     "02000000000000000000000000000000""00000000000000000000000000000000",
-+     "03000000000000000000000000000000"
-+    },
-+    {   /* wrap 2^128 */
-+     "02000000000000000000000000000000",
-+     "02000000000000000000000000000000""ffffffffffffffffffffffffffffffff",
-+     "03000000000000000000000000000000"
-+    },
-+    {   /* limb carry */
-+     "fffffffffffffffffffffffffffffffff0ffffffffffffffffffffffffffffff"
-+     "11000000000000000000000000000000",
-+     "01000000000000000000000000000000""00000000000000000000000000000000",
-+     "05000000000000000000000000000000"
-+    },
-+    {   /* 2^130-5 */
-+     "fffffffffffffffffffffffffffffffffbfefefefefefefefefefefefefefefe"
-+     "01010101010101010101010101010101",
-+     "01000000000000000000000000000000""00000000000000000000000000000000",
-+     "00000000000000000000000000000000"
-+    },
-+    {   /* 2^130-6 */
-+     "fdffffffffffffffffffffffffffffff",
-+     "02000000000000000000000000000000""00000000000000000000000000000000",
-+     "faffffffffffffffffffffffffffffff"
-+    },
-+    {   /* 5*H+L reduction intermediate */
-+     "e33594d7505e43b900000000000000003394d7505e4379cd0100000000000000"
-+     "0000000000000000000000000000000001000000000000000000000000000000",
-+     "01000000000000000400000000000000""00000000000000000000000000000000",
-+     "14000000000000005500000000000000"
-+    },
-+    {   /* 5*H+L reduction final */
-+     "e33594d7505e43b900000000000000003394d7505e4379cd0100000000000000"
-+     "00000000000000000000000000000000",
-+     "01000000000000000400000000000000""00000000000000000000000000000000",
-+     "13000000000000000000000000000000"
-+    }
-+};
-+
-+static unsigned char hex_digit(char h)
-+{
-+    int i = OPENSSL_hexchar2int(h);
-+
-+    if (i < 0)
-+        abort();
-+    return i;
-+}
-+
-+static void hex_decode(unsigned char *out, const char *hex)
-+{
-+    size_t j = 0;
-+
-+    while (*hex != 0) {
-+        unsigned char v = hex_digit(*hex++);
-+        v <<= 4;
-+        v |= hex_digit(*hex++);
-+        out[j++] = v;
-+    }
-+}
-+
-+static void hexdump(unsigned char *a, size_t len)
-+{
-+    size_t i;
-+
-+    for (i = 0; i < len; i++)
-+        printf("%02x", a[i]);
-+}
-+
-+int main()
-+{
-+    static const unsigned num_tests =
-+        sizeof(poly1305_tests) / sizeof(struct poly1305_test);
-+    unsigned i;
-+    unsigned char key[32], out[16], expected[16];
-+    POLY1305 poly1305;
-+
-+    for (i = 0; i < num_tests; i++) {
-+        const struct poly1305_test *test = &poly1305_tests[i];
-+        unsigned char *in;
-+        size_t inlen = strlen(test->inputhex);
-+
-+        if (strlen(test->keyhex) != sizeof(key) * 2 ||
-+            strlen(test->outhex) != sizeof(out) * 2 || (inlen & 1) == 1)
-+            return 1;
-+
-+        inlen /= 2;
-+
-+        hex_decode(key, test->keyhex);
-+        hex_decode(expected, test->outhex);
-+
-+        in = malloc(inlen);
-+
-+        hex_decode(in, test->inputhex);
-+
-+        Poly1305_Init(&poly1305, key);
-+        Poly1305_Update(&poly1305, in, inlen);
-+        Poly1305_Final(&poly1305, out);
-+
-+        if (memcmp(out, expected, sizeof(expected)) != 0) {
-+            printf("Poly1305 test #%d failed.\n", i);
-+            printf("got:      ");
-+            hexdump(out, sizeof(out));
-+            printf("\nexpected: ");
-+            hexdump(expected, sizeof(expected));
-+            printf("\n");
-+            return 1;
-+        }
-+
-+        if (inlen > 16) {
-+            Poly1305_Init(&poly1305, key);
-+            Poly1305_Update(&poly1305, in, 1);
-+            Poly1305_Update(&poly1305, in+1, inlen-1);
-+            Poly1305_Final(&poly1305, out);
-+
-+            if (memcmp(out, expected, sizeof(expected)) != 0) {
-+                printf("Poly1305 test #%d/1+(N-1) failed.\n", i);
-+                printf("got:      ");
-+                hexdump(out, sizeof(out));
-+                printf("\nexpected: ");
-+                hexdump(expected, sizeof(expected));
-+                printf("\n");
-+                return 1;
-+            }
-+        }
-+
-+        if (inlen > 32) {
-+            size_t half = inlen / 2;
-+
-+            Poly1305_Init(&poly1305, key);
-+            Poly1305_Update(&poly1305, in, half);
-+            Poly1305_Update(&poly1305, in+half, inlen-half);
-+            Poly1305_Final(&poly1305, out);
-+
-+            if (memcmp(out, expected, sizeof(expected)) != 0) {
-+                printf("Poly1305 test #%d/2 failed.\n", i);
-+                printf("got:      ");
-+                hexdump(out, sizeof(out));
-+                printf("\nexpected: ");
-+                hexdump(expected, sizeof(expected));
-+                printf("\n");
-+                return 1;
-+            }
-+
-+            for (half = 16; half < inlen; half += 16) {
-+                Poly1305_Init(&poly1305, key);
-+                Poly1305_Update(&poly1305, in, half);
-+                Poly1305_Update(&poly1305, in+half, inlen-half);
-+                Poly1305_Final(&poly1305, out);
-+
-+                if (memcmp(out, expected, sizeof(expected)) != 0) {
-+                    printf("Poly1305 test #%d/%d+%d failed.\n",
-+                                           i, half, inlen-half);
-+                    printf("got:      ");
-+                    hexdump(out, sizeof(out));
-+                    printf("\nexpected: ");
-+                    hexdump(expected, sizeof(expected));
-+                    printf("\n");
-+                    return 1;
-+                }
-+            }
-+        }
-+
-+        free(in);
-+    }
-+
-+    printf("PASS\n");
-+
-+# ifdef OPENSSL_CPUID_OBJ
-+    {
-+        unsigned char buf[8192];
-+        unsigned long long stopwatch;
-+        unsigned long long OPENSSL_rdtsc();
-+
-+        memset (buf,0x55,sizeof(buf));
-+        memset (key,0xAA,sizeof(key));
-+
-+        Poly1305_Init(&poly1305, key);
-+
-+        for (i=0;i<100000;i++)
-+            Poly1305_Update(&poly1305,buf,sizeof(buf));
-+
-+        stopwatch = OPENSSL_rdtsc();
-+        for (i=0;i<10000;i++)
-+            Poly1305_Update(&poly1305,buf,sizeof(buf));
-+        stopwatch = OPENSSL_rdtsc() - stopwatch;
-+
-+        printf("%g\n",stopwatch/(double)(i*sizeof(buf)));
-+
-+        stopwatch = OPENSSL_rdtsc();
-+        for (i=0;i<10000;i++) {
-+            Poly1305_Init(&poly1305, key);
-+            Poly1305_Update(&poly1305,buf,16);
-+            Poly1305_Final(&poly1305,buf);
-+        }
-+        stopwatch = OPENSSL_rdtsc() - stopwatch;
-+
-+        printf("%g\n",stopwatch/(double)(i));
-+    }
-+# endif
-+    return 0;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/poly1305_ieee754.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/poly1305_ieee754.c
-new file mode 100644
-index 0000000..08a5b58
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/poly1305/poly1305_ieee754.c
-@@ -0,0 +1,472 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * This module is meant to be used as template for non-x87 floating-
-+ * point assembly modules. The template itself is x86_64-specific
-+ * though, as it was debugged on x86_64. So that implementor would
-+ * have to recognize platform-specific parts, UxTOy and inline asm,
-+ * and act accordingly.
-+ *
-+ * Huh? x86_64-specific code as template for non-x87? Note seven, which
-+ * is not a typo, but reference to 80-bit precision. This module on the
-+ * other hand relies on 64-bit precision operations, which are default
-+ * for x86_64 code. And since we are at it, just for sense of it,
-+ * large-block performance in cycles per processed byte for *this* code
-+ * is:
-+ *			gcc-4.8		icc-15.0	clang-3.4(*)
-+ *
-+ * Westmere		4.96		5.09		4.37
-+ * Sandy Bridge		4.95		4.90		4.17
-+ * Haswell		4.92		4.87		3.78
-+ * Bulldozer		4.67		4.49		4.68
-+ * VIA Nano		7.07		7.05		5.98
-+ * Silvermont		10.6		9.61		12.6
-+ *
-+ * (*)	clang managed to discover parallelism and deployed SIMD;
-+ *
-+ * And for range of other platforms with unspecified gcc versions:
-+ *
-+ * Freescale e300	12.5
-+ * PPC74x0		10.8
-+ * POWER6		4.92
-+ * POWER7		4.50
-+ * POWER8		4.10
-+ *
-+ * z10			11.2
-+ * z196+		7.30
-+ *
-+ * UltraSPARC III	16.0
-+ * SPARC T4		16.1
-+ */
-+
-+#if !(defined(__GNUC__) && __GNUC__>=2)
-+# error "this is gcc-specific template"
-+#endif
-+
-+#include 
-+
-+typedef unsigned char u8;
-+typedef unsigned int u32;
-+typedef unsigned long long u64;
-+typedef union { double d; u64 u; } elem64;
-+
-+#define TWO(p)		((double)(1ULL<<(p)))
-+#define TWO0		TWO(0)
-+#define TWO32		TWO(32)
-+#define TWO64		(TWO32*TWO(32))
-+#define TWO96		(TWO64*TWO(32))
-+#define TWO130		(TWO96*TWO(34))
-+
-+#define EXP(p)		((1023ULL+(p))<<52)
-+
-+#if defined(__x86_64__) || (defined(__PPC__) && defined(__LITTLE_ENDIAN__))
-+# define U8TOU32(p)	(*(const u32 *)(p))
-+# define U32TO8(p,v)	(*(u32 *)(p) = (v))
-+#elif defined(__PPC__)
-+# define U8TOU32(p)	({u32 ret; asm ("lwbrx	%0,0,%1":"=r"(ret):"b"(p)); ret; })
-+# define U32TO8(p,v)	asm ("stwbrx %0,0,%1"::"r"(v),"b"(p):"memory")
-+#elif defined(__s390x__)
-+# define U8TOU32(p)	({u32 ret; asm ("lrv	%0,%1":"=d"(ret):"m"(*(u32 *)(p))); ret; })
-+# define U32TO8(p,v)	asm ("strv	%1,%0":"=m"(*(u32 *)(p)):"d"(v))
-+#endif
-+
-+#ifndef U8TOU32
-+# define U8TOU32(p)	((u32)(p)[0]     | (u32)(p)[1]<<8 | \
-+			 (u32)(p)[2]<<16 | (u32)(p)[3]<<24  )
-+#endif
-+#ifndef U32TO8
-+# define U32TO8(p,v)	((p)[0] = (u8)(v),       (p)[1] = (u8)((v)>>8), \
-+			 (p)[2] = (u8)((v)>>16), (p)[3] = (u8)((v)>>24) )
-+#endif
-+
-+typedef struct {
-+    elem64 h[4];
-+    double r[8];
-+    double s[6];
-+} poly1305_internal;
-+
-+/* "round toward zero (truncate), mask all exceptions" */
-+#if defined(__x86_64__)
-+static const u32 mxcsr = 0x7f80;
-+#elif defined(__PPC__)
-+static const u64 one = 1;
-+#elif defined(__s390x__)
-+static const u32 fpc = 1;
-+#elif defined(__sparc__)
-+static const u64 fsr = 1ULL<<30;
-+#else
-+#error "unrecognized platform"
-+#endif
-+
-+int poly1305_init(void *ctx, const unsigned char key[16])
-+{
-+    poly1305_internal *st = (poly1305_internal *) ctx;
-+    elem64 r0, r1, r2, r3;
-+
-+    /* h = 0, biased */
-+#if 0
-+    st->h[0].d = TWO(52)*TWO0;
-+    st->h[1].d = TWO(52)*TWO32;
-+    st->h[2].d = TWO(52)*TWO64;
-+    st->h[3].d = TWO(52)*TWO96;
-+#else
-+    st->h[0].u = EXP(52+0);
-+    st->h[1].u = EXP(52+32);
-+    st->h[2].u = EXP(52+64);
-+    st->h[3].u = EXP(52+96);
-+#endif
-+
-+    if (key) {
-+        /*
-+         * set "truncate" rounding mode
-+         */
-+#if defined(__x86_64__)
-+        u32 mxcsr_orig;
-+
-+        asm volatile ("stmxcsr	%0":"=m"(mxcsr_orig));
-+        asm volatile ("ldmxcsr	%0"::"m"(mxcsr));
-+#elif defined(__PPC__)
-+        double fpscr_orig, fpscr = *(double *)&one;
-+
-+        asm volatile ("mffs	%0":"=f"(fpscr_orig));
-+        asm volatile ("mtfsf	255,%0"::"f"(fpscr));
-+#elif defined(__s390x__)
-+        u32 fpc_orig;
-+
-+        asm volatile ("stfpc	%0":"=m"(fpc_orig));
-+        asm volatile ("lfpc	%0"::"m"(fpc));
-+#elif defined(__sparc__)
-+        u64 fsr_orig;
-+
-+        asm volatile ("stx	%%fsr,%0":"=m"(fsr_orig));
-+        asm volatile ("ldx	%0,%%fsr"::"m"(fsr));
-+#endif
-+
-+        /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
-+        r0.u = EXP(52+0)  | (U8TOU32(&key[0])  & 0x0fffffff);
-+        r1.u = EXP(52+32) | (U8TOU32(&key[4])  & 0x0ffffffc);
-+        r2.u = EXP(52+64) | (U8TOU32(&key[8])  & 0x0ffffffc);
-+        r3.u = EXP(52+96) | (U8TOU32(&key[12]) & 0x0ffffffc);
-+
-+        st->r[0] = r0.d - TWO(52)*TWO0;
-+        st->r[2] = r1.d - TWO(52)*TWO32;
-+        st->r[4] = r2.d - TWO(52)*TWO64;
-+        st->r[6] = r3.d - TWO(52)*TWO96;
-+
-+        st->s[0] = st->r[2] * (5.0/TWO130);
-+        st->s[2] = st->r[4] * (5.0/TWO130);
-+        st->s[4] = st->r[6] * (5.0/TWO130);
-+
-+        /*
-+         * base 2^32 -> base 2^16
-+         */
-+        st->r[1] = (st->r[0] + TWO(52)*TWO(16)*TWO0) -
-+                               TWO(52)*TWO(16)*TWO0;
-+        st->r[0] -= st->r[1];
-+
-+        st->r[3] = (st->r[2] + TWO(52)*TWO(16)*TWO32) -
-+                               TWO(52)*TWO(16)*TWO32;
-+        st->r[2] -= st->r[3];
-+
-+        st->r[5] = (st->r[4] + TWO(52)*TWO(16)*TWO64) -
-+                               TWO(52)*TWO(16)*TWO64;
-+        st->r[4] -= st->r[5];
-+
-+        st->r[7] = (st->r[6] + TWO(52)*TWO(16)*TWO96) -
-+                               TWO(52)*TWO(16)*TWO96;
-+        st->r[6] -= st->r[7];
-+
-+        st->s[1] = (st->s[0] + TWO(52)*TWO(16)*TWO0/TWO96) -
-+                               TWO(52)*TWO(16)*TWO0/TWO96;
-+        st->s[0] -= st->s[1];
-+
-+        st->s[3] = (st->s[2] + TWO(52)*TWO(16)*TWO32/TWO96) -
-+                               TWO(52)*TWO(16)*TWO32/TWO96;
-+        st->s[2] -= st->s[3];
-+
-+        st->s[5] = (st->s[4] + TWO(52)*TWO(16)*TWO64/TWO96) -
-+                               TWO(52)*TWO(16)*TWO64/TWO96;
-+        st->s[4] -= st->s[5];
-+
-+        /*
-+         * restore original FPU control register
-+         */
-+#if defined(__x86_64__)
-+        asm volatile ("ldmxcsr	%0"::"m"(mxcsr_orig));
-+#elif defined(__PPC__)
-+        asm volatile ("mtfsf	255,%0"::"f"(fpscr_orig));
-+#elif defined(__s390x__)
-+        asm volatile ("lfpc	%0"::"m"(fpc_orig));
-+#elif defined(__sparc__)
-+        asm volatile ("ldx	%0,%%fsr"::"m"(fsr_orig));
-+#endif
-+    }
-+
-+    return 0;
-+}
-+
-+void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len,
-+                     int padbit)
-+{
-+    poly1305_internal *st = (poly1305_internal *)ctx;
-+    elem64 in0, in1, in2, in3;
-+    u64 pad = (u64)padbit<<32;
-+
-+    double x0, x1, x2, x3;
-+    double h0lo, h0hi, h1lo, h1hi, h2lo, h2hi, h3lo, h3hi;
-+    double c0lo, c0hi, c1lo, c1hi, c2lo, c2hi, c3lo, c3hi;
-+
-+    const double r0lo = st->r[0];
-+    const double r0hi = st->r[1];
-+    const double r1lo = st->r[2];
-+    const double r1hi = st->r[3];
-+    const double r2lo = st->r[4];
-+    const double r2hi = st->r[5];
-+    const double r3lo = st->r[6];
-+    const double r3hi = st->r[7];
-+
-+    const double s1lo = st->s[0];
-+    const double s1hi = st->s[1];
-+    const double s2lo = st->s[2];
-+    const double s2hi = st->s[3];
-+    const double s3lo = st->s[4];
-+    const double s3hi = st->s[5];
-+
-+    /*
-+     * set "truncate" rounding mode
-+     */
-+#if defined(__x86_64__)
-+    u32 mxcsr_orig;
-+
-+    asm volatile ("stmxcsr	%0":"=m"(mxcsr_orig));
-+    asm volatile ("ldmxcsr	%0"::"m"(mxcsr));
-+#elif defined(__PPC__)
-+    double fpscr_orig, fpscr = *(double *)&one;
-+
-+    asm volatile ("mffs		%0":"=f"(fpscr_orig));
-+    asm volatile ("mtfsf	255,%0"::"f"(fpscr));
-+#elif defined(__s390x__)
-+    u32 fpc_orig;
-+
-+    asm volatile ("stfpc	%0":"=m"(fpc_orig));
-+    asm volatile ("lfpc		%0"::"m"(fpc));
-+#elif defined(__sparc__)
-+    u64 fsr_orig;
-+
-+    asm volatile ("stx		%%fsr,%0":"=m"(fsr_orig));
-+    asm volatile ("ldx		%0,%%fsr"::"m"(fsr));
-+#endif
-+
-+    /*
-+     * load base 2^32 and de-bias
-+     */
-+    h0lo = st->h[0].d - TWO(52)*TWO0;
-+    h1lo = st->h[1].d - TWO(52)*TWO32;
-+    h2lo = st->h[2].d - TWO(52)*TWO64;
-+    h3lo = st->h[3].d - TWO(52)*TWO96;
-+
-+#ifdef __clang__
-+    h0hi = 0;
-+    h1hi = 0;
-+    h2hi = 0;
-+    h3hi = 0;
-+#else
-+    in0.u = EXP(52+0)  | U8TOU32(&inp[0]);
-+    in1.u = EXP(52+32) | U8TOU32(&inp[4]);
-+    in2.u = EXP(52+64) | U8TOU32(&inp[8]);
-+    in3.u = EXP(52+96) | U8TOU32(&inp[12]) | pad;
-+
-+    x0 = in0.d - TWO(52)*TWO0;
-+    x1 = in1.d - TWO(52)*TWO32;
-+    x2 = in2.d - TWO(52)*TWO64;
-+    x3 = in3.d - TWO(52)*TWO96;
-+
-+    x0 += h0lo;
-+    x1 += h1lo;
-+    x2 += h2lo;
-+    x3 += h3lo;
-+
-+    goto fast_entry;
-+#endif
-+
-+    do {
-+        in0.u = EXP(52+0)  | U8TOU32(&inp[0]);
-+        in1.u = EXP(52+32) | U8TOU32(&inp[4]);
-+        in2.u = EXP(52+64) | U8TOU32(&inp[8]);
-+        in3.u = EXP(52+96) | U8TOU32(&inp[12]) | pad;
-+
-+        x0 = in0.d - TWO(52)*TWO0;
-+        x1 = in1.d - TWO(52)*TWO32;
-+        x2 = in2.d - TWO(52)*TWO64;
-+        x3 = in3.d - TWO(52)*TWO96;
-+
-+        /*
-+         * note that there are multiple ways to accumulate input, e.g.
-+         * one can as well accumulate to h0lo-h1lo-h1hi-h2hi...
-+         */
-+        h0lo += x0;
-+        h0hi += x1;
-+        h2lo += x2;
-+        h2hi += x3;
-+
-+        /*
-+         * carries that cross 32n-bit (and 130-bit) boundaries
-+         */
-+        c0lo = (h0lo + TWO(52)*TWO32)  - TWO(52)*TWO32;
-+        c1lo = (h1lo + TWO(52)*TWO64)  - TWO(52)*TWO64;
-+        c2lo = (h2lo + TWO(52)*TWO96)  - TWO(52)*TWO96;
-+        c3lo = (h3lo + TWO(52)*TWO130) - TWO(52)*TWO130;
-+
-+        c0hi = (h0hi + TWO(52)*TWO32)  - TWO(52)*TWO32;
-+        c1hi = (h1hi + TWO(52)*TWO64)  - TWO(52)*TWO64;
-+        c2hi = (h2hi + TWO(52)*TWO96)  - TWO(52)*TWO96;
-+        c3hi = (h3hi + TWO(52)*TWO130) - TWO(52)*TWO130;
-+
-+        /*
-+         * base 2^48 -> base 2^32 with last reduction step
-+         */
-+        x1 =  (h1lo - c1lo) + c0lo;
-+        x2 =  (h2lo - c2lo) + c1lo;
-+        x3 =  (h3lo - c3lo) + c2lo;
-+        x0 =  (h0lo - c0lo) + c3lo * (5.0/TWO130);
-+
-+        x1 += (h1hi - c1hi) + c0hi;
-+        x2 += (h2hi - c2hi) + c1hi;
-+        x3 += (h3hi - c3hi) + c2hi;
-+        x0 += (h0hi - c0hi) + c3hi * (5.0/TWO130);
-+
-+#ifndef __clang__
-+    fast_entry:
-+#endif
-+	/*
-+	 * base 2^32 * base 2^16 = base 2^48
-+	 */
-+        h0lo = s3lo * x1 + s2lo * x2 + s1lo * x3 + r0lo * x0;
-+        h1lo = r0lo * x1 + s3lo * x2 + s2lo * x3 + r1lo * x0;
-+        h2lo = r1lo * x1 + r0lo * x2 + s3lo * x3 + r2lo * x0;
-+        h3lo = r2lo * x1 + r1lo * x2 + r0lo * x3 + r3lo * x0;
-+
-+        h0hi = s3hi * x1 + s2hi * x2 + s1hi * x3 + r0hi * x0;
-+        h1hi = r0hi * x1 + s3hi * x2 + s2hi * x3 + r1hi * x0;
-+        h2hi = r1hi * x1 + r0hi * x2 + s3hi * x3 + r2hi * x0;
-+        h3hi = r2hi * x1 + r1hi * x2 + r0hi * x3 + r3hi * x0;
-+
-+        inp += 16;
-+        len -= 16;
-+
-+    } while (len >= 16);
-+
-+    /*
-+     * carries that cross 32n-bit (and 130-bit) boundaries
-+     */
-+    c0lo = (h0lo + TWO(52)*TWO32)  - TWO(52)*TWO32;
-+    c1lo = (h1lo + TWO(52)*TWO64)  - TWO(52)*TWO64;
-+    c2lo = (h2lo + TWO(52)*TWO96)  - TWO(52)*TWO96;
-+    c3lo = (h3lo + TWO(52)*TWO130) - TWO(52)*TWO130;
-+
-+    c0hi = (h0hi + TWO(52)*TWO32)  - TWO(52)*TWO32;
-+    c1hi = (h1hi + TWO(52)*TWO64)  - TWO(52)*TWO64;
-+    c2hi = (h2hi + TWO(52)*TWO96)  - TWO(52)*TWO96;
-+    c3hi = (h3hi + TWO(52)*TWO130) - TWO(52)*TWO130;
-+
-+    /*
-+     * base 2^48 -> base 2^32 with last reduction step
-+     */
-+    x1 =  (h1lo - c1lo) + c0lo;
-+    x2 =  (h2lo - c2lo) + c1lo;
-+    x3 =  (h3lo - c3lo) + c2lo;
-+    x0 =  (h0lo - c0lo) + c3lo * (5.0/TWO130);
-+
-+    x1 += (h1hi - c1hi) + c0hi;
-+    x2 += (h2hi - c2hi) + c1hi;
-+    x3 += (h3hi - c3hi) + c2hi;
-+    x0 += (h0hi - c0hi) + c3hi * (5.0/TWO130);
-+
-+    /*
-+     * store base 2^32, with bias
-+     */
-+    st->h[1].d = x1 + TWO(52)*TWO32;
-+    st->h[2].d = x2 + TWO(52)*TWO64;
-+    st->h[3].d = x3 + TWO(52)*TWO96;
-+    st->h[0].d = x0 + TWO(52)*TWO0;
-+
-+    /*
-+     * restore original FPU control register
-+     */
-+#if defined(__x86_64__)
-+    asm volatile ("ldmxcsr	%0"::"m"(mxcsr_orig));
-+#elif defined(__PPC__)
-+    asm volatile ("mtfsf	255,%0"::"f"(fpscr_orig));
-+#elif defined(__s390x__)
-+    asm volatile ("lfpc		%0"::"m"(fpc_orig));
-+#elif defined(__sparc__)
-+    asm volatile ("ldx		%0,%%fsr"::"m"(fsr_orig));
-+#endif
-+}
-+
-+void poly1305_emit(void *ctx, unsigned char mac[16], const u32 nonce[4])
-+{
-+    poly1305_internal *st = (poly1305_internal *) ctx;
-+    u64 h0, h1, h2, h3, h4;
-+    u32 g0, g1, g2, g3, g4;
-+    u64 t;
-+    u32 mask;
-+
-+    /*
-+     * thanks to bias masking exponent gives integer result
-+     */
-+    h0 = st->h[0].u & 0x000fffffffffffffULL;
-+    h1 = st->h[1].u & 0x000fffffffffffffULL;
-+    h2 = st->h[2].u & 0x000fffffffffffffULL;
-+    h3 = st->h[3].u & 0x000fffffffffffffULL;
-+
-+    /*
-+     * can be partially reduced, so reduce...
-+     */
-+    h4 = h3>>32; h3 &= 0xffffffffU;
-+    g4 = h4&-4;
-+    h4 &= 3;
-+    g4 += g4>>2;
-+
-+    h0 += g4;
-+    h1 += h0>>32; h0 &= 0xffffffffU;
-+    h2 += h1>>32; h1 &= 0xffffffffU;
-+    h3 += h2>>32; h2 &= 0xffffffffU;
-+
-+    /* compute h + -p */
-+    g0 = (u32)(t = h0 + 5);
-+    g1 = (u32)(t = h1 + (t >> 32));
-+    g2 = (u32)(t = h2 + (t >> 32));
-+    g3 = (u32)(t = h3 + (t >> 32));
-+    g4 = h4 + (u32)(t >> 32);
-+
-+    /* if there was carry, select g0-g3 */
-+    mask = 0 - (g4 >> 2);
-+    g0 &= mask;
-+    g1 &= mask;
-+    g2 &= mask;
-+    g3 &= mask;
-+    mask = ~mask;
-+    g0 |= (h0 & mask);
-+    g1 |= (h1 & mask);
-+    g2 |= (h2 & mask);
-+    g3 |= (h3 & mask);
-+
-+    /* mac = (h + nonce) % (2^128) */
-+    g0 = (u32)(t = (u64)g0 + nonce[0]);
-+    g1 = (u32)(t = (u64)g1 + (t >> 32) + nonce[1]);
-+    g2 = (u32)(t = (u64)g2 + (t >> 32) + nonce[2]);
-+    g3 = (u32)(t = (u64)g3 + (t >> 32) + nonce[3]);
-+
-+    U32TO8(mac + 0, g0);
-+    U32TO8(mac + 4, g1);
-+    U32TO8(mac + 8, g2);
-+    U32TO8(mac + 12, g3);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ppc_arch.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/ppc_arch.h
-new file mode 100644
-index 0000000..65cf96f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ppc_arch.h
-@@ -0,0 +1,26 @@
-+/*
-+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_PPC_ARCH_H
-+# define HEADER_PPC_ARCH_H
-+
-+extern unsigned int OPENSSL_ppccap_P;
-+
-+/*
-+ * Flags' usage can appear ambiguous, because they are set rather
-+ * to reflect OpenSSL performance preferences than actual processor
-+ * capabilities.
-+ */
-+# define PPC_FPU64       (1<<0)
-+# define PPC_ALTIVEC     (1<<1)
-+# define PPC_CRYPTO207   (1<<2)
-+# define PPC_FPU         (1<<3)
-+# define PPC_MADD300     (1<<4)
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ppccap.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ppccap.c
-new file mode 100644
-index 0000000..ef38b17
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ppccap.c
-@@ -0,0 +1,317 @@
-+/*
-+ * Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#if defined(__linux) || defined(_AIX)
-+# include 
-+#endif
-+#if defined(_AIX53)     /* defined even on post-5.3 */
-+# include 
-+# if !defined(__power_set)
-+#  define __power_set(a) (_system_configuration.implementation & (a))
-+# endif
-+#endif
-+#include 
-+#include 
-+
-+#include "ppc_arch.h"
-+
-+unsigned int OPENSSL_ppccap_P = 0;
-+
-+static sigset_t all_masked;
-+
-+#ifdef OPENSSL_BN_ASM_MONT
-+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                const BN_ULONG *np, const BN_ULONG *n0, int num)
-+{
-+    int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap,
-+                          const BN_ULONG *bp, const BN_ULONG *np,
-+                          const BN_ULONG *n0, int num);
-+    int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                        const BN_ULONG *np, const BN_ULONG *n0, int num);
-+
-+    if (sizeof(size_t) == 4) {
-+# if 1 || (defined(__APPLE__) && defined(__MACH__))
-+        if (num >= 8 && (num & 3) == 0 && (OPENSSL_ppccap_P & PPC_FPU64))
-+            return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num);
-+# else
-+        /*
-+         * boundary of 32 was experimentally determined on Linux 2.6.22,
-+         * might have to be adjusted on AIX...
-+         */
-+        if (num >= 32 && (num & 3) == 0 && (OPENSSL_ppccap_P & PPC_FPU64)) {
-+            sigset_t oset;
-+            int ret;
-+
-+            sigprocmask(SIG_SETMASK, &all_masked, &oset);
-+            ret = bn_mul_mont_fpu64(rp, ap, bp, np, n0, num);
-+            sigprocmask(SIG_SETMASK, &oset, NULL);
-+
-+            return ret;
-+        }
-+# endif
-+    } else if ((OPENSSL_ppccap_P & PPC_FPU64))
-+        /*
-+         * this is a "must" on POWER6, but run-time detection is not
-+         * implemented yet...
-+         */
-+        return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num);
-+
-+    return bn_mul_mont_int(rp, ap, bp, np, n0, num);
-+}
-+#endif
-+
-+void sha256_block_p8(void *ctx, const void *inp, size_t len);
-+void sha256_block_ppc(void *ctx, const void *inp, size_t len);
-+void sha256_block_data_order(void *ctx, const void *inp, size_t len)
-+{
-+    OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha256_block_p8(ctx, inp, len) :
-+        sha256_block_ppc(ctx, inp, len);
-+}
-+
-+void sha512_block_p8(void *ctx, const void *inp, size_t len);
-+void sha512_block_ppc(void *ctx, const void *inp, size_t len);
-+void sha512_block_data_order(void *ctx, const void *inp, size_t len)
-+{
-+    OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha512_block_p8(ctx, inp, len) :
-+        sha512_block_ppc(ctx, inp, len);
-+}
-+
-+#ifndef OPENSSL_NO_CHACHA
-+void ChaCha20_ctr32_int(unsigned char *out, const unsigned char *inp,
-+                        size_t len, const unsigned int key[8],
-+                        const unsigned int counter[4]);
-+void ChaCha20_ctr32_vmx(unsigned char *out, const unsigned char *inp,
-+                        size_t len, const unsigned int key[8],
-+                        const unsigned int counter[4]);
-+void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
-+                    size_t len, const unsigned int key[8],
-+                    const unsigned int counter[4])
-+{
-+    OPENSSL_ppccap_P & PPC_ALTIVEC
-+        ? ChaCha20_ctr32_vmx(out, inp, len, key, counter)
-+        : ChaCha20_ctr32_int(out, inp, len, key, counter);
-+}
-+#endif
-+
-+#ifndef OPENSSL_NO_POLY1305
-+void poly1305_init_int(void *ctx, const unsigned char key[16]);
-+void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len,
-+                         unsigned int padbit);
-+void poly1305_emit(void *ctx, unsigned char mac[16],
-+                       const unsigned int nonce[4]);
-+void poly1305_init_fpu(void *ctx, const unsigned char key[16]);
-+void poly1305_blocks_fpu(void *ctx, const unsigned char *inp, size_t len,
-+                         unsigned int padbit);
-+void poly1305_emit_fpu(void *ctx, unsigned char mac[16],
-+                       const unsigned int nonce[4]);
-+int poly1305_init(void *ctx, const unsigned char key[16], void *func[2])
-+{
-+    if (sizeof(size_t) == 4 && (OPENSSL_ppccap_P & PPC_FPU)) {
-+        poly1305_init_fpu(ctx, key);
-+        func[0] = poly1305_blocks_fpu;
-+        func[1] = poly1305_emit_fpu;
-+    } else {
-+        poly1305_init_int(ctx, key);
-+        func[0] = poly1305_blocks;
-+        func[1] = poly1305_emit;
-+    }
-+    return 1;
-+}
-+#endif
-+
-+static sigjmp_buf ill_jmp;
-+static void ill_handler(int sig)
-+{
-+    siglongjmp(ill_jmp, sig);
-+}
-+
-+void OPENSSL_fpu_probe(void);
-+void OPENSSL_ppc64_probe(void);
-+void OPENSSL_altivec_probe(void);
-+void OPENSSL_crypto207_probe(void);
-+void OPENSSL_madd300_probe(void);
-+
-+/*
-+ * Use a weak reference to getauxval() so we can use it if it is available
-+ * but don't break the build if it is not. Note that this is *link-time*
-+ * feature detection, not *run-time*. In other words if we link with
-+ * symbol present, it's expected to be present even at run-time.
-+ */
-+#if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__)
-+extern unsigned long getauxval(unsigned long type) __attribute__ ((weak));
-+#else
-+static unsigned long (*getauxval) (unsigned long) = NULL;
-+#endif
-+
-+/* I wish  was universally available */
-+#define HWCAP                   16      /* AT_HWCAP */
-+#define HWCAP_PPC64             (1U << 30)
-+#define HWCAP_ALTIVEC           (1U << 28)
-+#define HWCAP_FPU               (1U << 27)
-+#define HWCAP_POWER6_EXT        (1U << 9)
-+#define HWCAP_VSX               (1U << 7)
-+
-+#define HWCAP2                  26      /* AT_HWCAP2 */
-+#define HWCAP_VEC_CRYPTO        (1U << 25)
-+#define HWCAP_ARCH_3_00         (1U << 23)
-+
-+# if defined(__GNUC__) && __GNUC__>=2
-+__attribute__ ((constructor))
-+# endif
-+void OPENSSL_cpuid_setup(void)
-+{
-+    char *e;
-+    struct sigaction ill_oact, ill_act;
-+    sigset_t oset;
-+    static int trigger = 0;
-+
-+    if (trigger)
-+        return;
-+    trigger = 1;
-+
-+    if ((e = getenv("OPENSSL_ppccap"))) {
-+        OPENSSL_ppccap_P = strtoul(e, NULL, 0);
-+        return;
-+    }
-+
-+    OPENSSL_ppccap_P = 0;
-+
-+#if defined(_AIX)
-+    OPENSSL_ppccap_P |= PPC_FPU;
-+
-+    if (sizeof(size_t) == 4) {
-+        struct utsname uts;
-+# if defined(_SC_AIX_KERNEL_BITMODE)
-+        if (sysconf(_SC_AIX_KERNEL_BITMODE) != 64)
-+            return;
-+# endif
-+        if (uname(&uts) != 0 || atoi(uts.version) < 6)
-+            return;
-+    }
-+
-+# if defined(__power_set)
-+    /*
-+     * Value used in __power_set is a single-bit 1<
-+#include 
-+
-+#include "e_os.h"
-+
-+#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_DSPBIOS))
-+# include 
-+#endif
-+#if defined(OPENSSL_SYS_VXWORKS)
-+# include 
-+#endif
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "rand_lcl.h"
-+
-+#include 
-+
-+#include 
-+
-+#ifdef OPENSSL_FIPS
-+# include 
-+#endif
-+
-+#ifdef BN_DEBUG
-+# define PREDICT
-+#endif
-+
-+/* #define PREDICT      1 */
-+
-+#define STATE_SIZE      1023
-+static size_t state_num = 0, state_index = 0;
-+static unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH];
-+static unsigned char md[MD_DIGEST_LENGTH];
-+static long md_count[2] = { 0, 0 };
-+
-+static double entropy = 0;
-+static int initialized = 0;
-+
-+static CRYPTO_RWLOCK *rand_lock = NULL;
-+static CRYPTO_RWLOCK *rand_tmp_lock = NULL;
-+static CRYPTO_ONCE rand_lock_init = CRYPTO_ONCE_STATIC_INIT;
-+
-+/* May be set only when a thread holds rand_lock (to prevent double locking) */
-+static unsigned int crypto_lock_rand = 0;
-+/* access to locking_threadid is synchronized by rand_tmp_lock */
-+/* valid iff crypto_lock_rand is set */
-+static CRYPTO_THREAD_ID locking_threadid;
-+
-+#ifdef PREDICT
-+int rand_predictable = 0;
-+#endif
-+
-+static int rand_hw_seed(EVP_MD_CTX *ctx);
-+
-+static void rand_cleanup(void);
-+static int rand_seed(const void *buf, int num);
-+static int rand_add(const void *buf, int num, double add_entropy);
-+static int rand_bytes(unsigned char *buf, int num, int pseudo);
-+static int rand_nopseudo_bytes(unsigned char *buf, int num);
-+#if OPENSSL_API_COMPAT < 0x10100000L
-+static int rand_pseudo_bytes(unsigned char *buf, int num);
-+#endif
-+static int rand_status(void);
-+
-+static RAND_METHOD rand_meth = {
-+    rand_seed,
-+    rand_nopseudo_bytes,
-+    rand_cleanup,
-+    rand_add,
-+#if OPENSSL_API_COMPAT < 0x10100000L
-+    rand_pseudo_bytes,
-+#else
-+    NULL,
-+#endif
-+    rand_status
-+};
-+
-+DEFINE_RUN_ONCE_STATIC(do_rand_lock_init)
-+{
-+    OPENSSL_init_crypto(0, NULL);
-+    rand_lock = CRYPTO_THREAD_lock_new();
-+    rand_tmp_lock = CRYPTO_THREAD_lock_new();
-+    return rand_lock != NULL && rand_tmp_lock != NULL;
-+}
-+
-+RAND_METHOD *RAND_OpenSSL(void)
-+{
-+    return (&rand_meth);
-+}
-+
-+static void rand_cleanup(void)
-+{
-+    OPENSSL_cleanse(state, sizeof(state));
-+    state_num = 0;
-+    state_index = 0;
-+    OPENSSL_cleanse(md, MD_DIGEST_LENGTH);
-+    md_count[0] = 0;
-+    md_count[1] = 0;
-+    entropy = 0;
-+    initialized = 0;
-+    CRYPTO_THREAD_lock_free(rand_lock);
-+    CRYPTO_THREAD_lock_free(rand_tmp_lock);
-+}
-+
-+static int rand_add(const void *buf, int num, double add)
-+{
-+    int i, j, k, st_idx;
-+    long md_c[2];
-+    unsigned char local_md[MD_DIGEST_LENGTH];
-+    EVP_MD_CTX *m;
-+    int do_not_lock;
-+    int rv = 0;
-+
-+    if (!num)
-+        return 1;
-+
-+    /*
-+     * (Based on the rand(3) manpage)
-+     *
-+     * The input is chopped up into units of 20 bytes (or less for
-+     * the last block).  Each of these blocks is run through the hash
-+     * function as follows:  The data passed to the hash function
-+     * is the current 'md', the same number of bytes from the 'state'
-+     * (the location determined by in incremented looping index) as
-+     * the current 'block', the new key data 'block', and 'count'
-+     * (which is incremented after each use).
-+     * The result of this is kept in 'md' and also xored into the
-+     * 'state' at the same locations that were used as input into the
-+     * hash function.
-+     */
-+
-+    m = EVP_MD_CTX_new();
-+    if (m == NULL)
-+        goto err;
-+
-+    if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
-+        goto err;
-+
-+    /* check if we already have the lock */
-+    if (crypto_lock_rand) {
-+        CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id();
-+        CRYPTO_THREAD_read_lock(rand_tmp_lock);
-+        do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
-+        CRYPTO_THREAD_unlock(rand_tmp_lock);
-+    } else
-+        do_not_lock = 0;
-+
-+    if (!do_not_lock)
-+        CRYPTO_THREAD_write_lock(rand_lock);
-+    st_idx = state_index;
-+
-+    /*
-+     * use our own copies of the counters so that even if a concurrent thread
-+     * seeds with exactly the same data and uses the same subarray there's
-+     * _some_ difference
-+     */
-+    md_c[0] = md_count[0];
-+    md_c[1] = md_count[1];
-+
-+    memcpy(local_md, md, sizeof md);
-+
-+    /* state_index <= state_num <= STATE_SIZE */
-+    state_index += num;
-+    if (state_index >= STATE_SIZE) {
-+        state_index %= STATE_SIZE;
-+        state_num = STATE_SIZE;
-+    } else if (state_num < STATE_SIZE) {
-+        if (state_index > state_num)
-+            state_num = state_index;
-+    }
-+    /* state_index <= state_num <= STATE_SIZE */
-+
-+    /*
-+     * state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] are what we
-+     * will use now, but other threads may use them as well
-+     */
-+
-+    md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
-+
-+    if (!do_not_lock)
-+        CRYPTO_THREAD_unlock(rand_lock);
-+
-+    for (i = 0; i < num; i += MD_DIGEST_LENGTH) {
-+        j = (num - i);
-+        j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j;
-+
-+        if (!MD_Init(m))
-+            goto err;
-+        if (!MD_Update(m, local_md, MD_DIGEST_LENGTH))
-+            goto err;
-+        k = (st_idx + j) - STATE_SIZE;
-+        if (k > 0) {
-+            if (!MD_Update(m, &(state[st_idx]), j - k))
-+                goto err;
-+            if (!MD_Update(m, &(state[0]), k))
-+                goto err;
-+        } else if (!MD_Update(m, &(state[st_idx]), j))
-+            goto err;
-+
-+        /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
-+        if (!MD_Update(m, buf, j))
-+            goto err;
-+        /*
-+         * We know that line may cause programs such as purify and valgrind
-+         * to complain about use of uninitialized data.  The problem is not,
-+         * it's with the caller.  Removing that line will make sure you get
-+         * really bad randomness and thereby other problems such as very
-+         * insecure keys.
-+         */
-+
-+        if (!MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
-+            goto err;
-+        if (!MD_Final(m, local_md))
-+            goto err;
-+        md_c[1]++;
-+
-+        buf = (const char *)buf + j;
-+
-+        for (k = 0; k < j; k++) {
-+            /*
-+             * Parallel threads may interfere with this, but always each byte
-+             * of the new state is the XOR of some previous value of its and
-+             * local_md (intermediate values may be lost). Alway using locking
-+             * could hurt performance more than necessary given that
-+             * conflicts occur only when the total seeding is longer than the
-+             * random state.
-+             */
-+            state[st_idx++] ^= local_md[k];
-+            if (st_idx >= STATE_SIZE)
-+                st_idx = 0;
-+        }
-+    }
-+
-+    if (!do_not_lock)
-+        CRYPTO_THREAD_write_lock(rand_lock);
-+    /*
-+     * Don't just copy back local_md into md -- this could mean that other
-+     * thread's seeding remains without effect (except for the incremented
-+     * counter).  By XORing it we keep at least as much entropy as fits into
-+     * md.
-+     */
-+    for (k = 0; k < (int)sizeof(md); k++) {
-+        md[k] ^= local_md[k];
-+    }
-+    if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
-+        entropy += add;
-+    if (!do_not_lock)
-+        CRYPTO_THREAD_unlock(rand_lock);
-+
-+    rv = 1;
-+ err:
-+    EVP_MD_CTX_free(m);
-+    return rv;
-+}
-+
-+static int rand_seed(const void *buf, int num)
-+{
-+    return rand_add(buf, num, (double)num);
-+}
-+
-+static int rand_bytes(unsigned char *buf, int num, int pseudo)
-+{
-+    static volatile int stirred_pool = 0;
-+    int i, j, k;
-+    size_t num_ceil, st_idx, st_num;
-+    int ok;
-+    long md_c[2];
-+    unsigned char local_md[MD_DIGEST_LENGTH];
-+    EVP_MD_CTX *m;
-+#ifndef GETPID_IS_MEANINGLESS
-+    pid_t curr_pid = getpid();
-+#endif
-+    time_t curr_time = time(NULL);
-+    int do_stir_pool = 0;
-+/* time value for various platforms */
-+#ifdef OPENSSL_SYS_WIN32
-+    FILETIME tv;
-+# ifdef _WIN32_WCE
-+    SYSTEMTIME t;
-+    GetSystemTime(&t);
-+    SystemTimeToFileTime(&t, &tv);
-+# else
-+    GetSystemTimeAsFileTime(&tv);
-+# endif
-+#elif defined(OPENSSL_SYS_VXWORKS)
-+    struct timespec tv;
-+    clock_gettime(CLOCK_REALTIME, &ts);
-+#elif defined(OPENSSL_SYS_DSPBIOS)
-+    unsigned long long tv, OPENSSL_rdtsc();
-+    tv = OPENSSL_rdtsc();
-+#else
-+    struct timeval tv;
-+    gettimeofday(&tv, NULL);
-+#endif
-+
-+#ifdef PREDICT
-+    if (rand_predictable) {
-+        static unsigned char val = 0;
-+
-+        for (i = 0; i < num; i++)
-+            buf[i] = val++;
-+        return (1);
-+    }
-+#endif
-+
-+    if (num <= 0)
-+        return 1;
-+
-+    m = EVP_MD_CTX_new();
-+    if (m == NULL)
-+        goto err_mem;
-+
-+    /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
-+    num_ceil =
-+        (1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2);
-+
-+    /*
-+     * (Based on the rand(3) manpage:)
-+     *
-+     * For each group of 10 bytes (or less), we do the following:
-+     *
-+     * Input into the hash function the local 'md' (which is initialized from
-+     * the global 'md' before any bytes are generated), the bytes that are to
-+     * be overwritten by the random bytes, and bytes from the 'state'
-+     * (incrementing looping index). From this digest output (which is kept
-+     * in 'md'), the top (up to) 10 bytes are returned to the caller and the
-+     * bottom 10 bytes are xored into the 'state'.
-+     *
-+     * Finally, after we have finished 'num' random bytes for the
-+     * caller, 'count' (which is incremented) and the local and global 'md'
-+     * are fed into the hash function and the results are kept in the
-+     * global 'md'.
-+     */
-+
-+    if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
-+        goto err_mem;
-+
-+    CRYPTO_THREAD_write_lock(rand_lock);
-+    /*
-+     * We could end up in an async engine while holding this lock so ensure
-+     * we don't pause and cause a deadlock
-+     */
-+    ASYNC_block_pause();
-+
-+    /* prevent rand_bytes() from trying to obtain the lock again */
-+    CRYPTO_THREAD_write_lock(rand_tmp_lock);
-+    locking_threadid = CRYPTO_THREAD_get_current_id();
-+    CRYPTO_THREAD_unlock(rand_tmp_lock);
-+    crypto_lock_rand = 1;
-+
-+    if (!initialized) {
-+        RAND_poll();
-+        initialized = 1;
-+    }
-+
-+    if (!stirred_pool)
-+        do_stir_pool = 1;
-+
-+    ok = (entropy >= ENTROPY_NEEDED);
-+    if (!ok) {
-+        /*
-+         * If the PRNG state is not yet unpredictable, then seeing the PRNG
-+         * output may help attackers to determine the new state; thus we have
-+         * to decrease the entropy estimate. Once we've had enough initial
-+         * seeding we don't bother to adjust the entropy count, though,
-+         * because we're not ambitious to provide *information-theoretic*
-+         * randomness. NOTE: This approach fails if the program forks before
-+         * we have enough entropy. Entropy should be collected in a separate
-+         * input pool and be transferred to the output pool only when the
-+         * entropy limit has been reached.
-+         */
-+        entropy -= num;
-+        if (entropy < 0)
-+            entropy = 0;
-+    }
-+
-+    if (do_stir_pool) {
-+        /*
-+         * In the output function only half of 'md' remains secret, so we
-+         * better make sure that the required entropy gets 'evenly
-+         * distributed' through 'state', our randomness pool. The input
-+         * function (rand_add) chains all of 'md', which makes it more
-+         * suitable for this purpose.
-+         */
-+
-+        int n = STATE_SIZE;     /* so that the complete pool gets accessed */
-+        while (n > 0) {
-+#if MD_DIGEST_LENGTH > 20
-+# error "Please adjust DUMMY_SEED."
-+#endif
-+#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
-+            /*
-+             * Note that the seed does not matter, it's just that
-+             * rand_add expects to have something to hash.
-+             */
-+            rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
-+            n -= MD_DIGEST_LENGTH;
-+        }
-+        if (ok)
-+            stirred_pool = 1;
-+    }
-+
-+    st_idx = state_index;
-+    st_num = state_num;
-+    md_c[0] = md_count[0];
-+    md_c[1] = md_count[1];
-+    memcpy(local_md, md, sizeof md);
-+
-+    state_index += num_ceil;
-+    if (state_index > state_num)
-+        state_index %= state_num;
-+
-+    /*
-+     * state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] are now
-+     * ours (but other threads may use them too)
-+     */
-+
-+    md_count[0] += 1;
-+
-+    /* before unlocking, we must clear 'crypto_lock_rand' */
-+    crypto_lock_rand = 0;
-+    ASYNC_unblock_pause();
-+    CRYPTO_THREAD_unlock(rand_lock);
-+
-+    while (num > 0) {
-+        /* num_ceil -= MD_DIGEST_LENGTH/2 */
-+        j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num;
-+        num -= j;
-+        if (!MD_Init(m))
-+            goto err;
-+#ifndef GETPID_IS_MEANINGLESS
-+        if (curr_pid) {         /* just in the first iteration to save time */
-+            if (!MD_Update(m, (unsigned char *)&curr_pid, sizeof curr_pid))
-+                goto err;
-+            curr_pid = 0;
-+        }
-+#endif
-+        if (curr_time) {        /* just in the first iteration to save time */
-+            if (!MD_Update(m, (unsigned char *)&curr_time, sizeof curr_time))
-+                goto err;
-+            if (!MD_Update(m, (unsigned char *)&tv, sizeof tv))
-+                goto err;
-+            curr_time = 0;
-+            if (!rand_hw_seed(m))
-+                goto err;
-+        }
-+        if (!MD_Update(m, local_md, MD_DIGEST_LENGTH))
-+            goto err;
-+        if (!MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
-+            goto err;
-+
-+        k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num;
-+        if (k > 0) {
-+            if (!MD_Update(m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k))
-+                goto err;
-+            if (!MD_Update(m, &(state[0]), k))
-+                goto err;
-+        } else if (!MD_Update(m, &(state[st_idx]), MD_DIGEST_LENGTH / 2))
-+            goto err;
-+        if (!MD_Final(m, local_md))
-+            goto err;
-+
-+        for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) {
-+            /* may compete with other threads */
-+            state[st_idx++] ^= local_md[i];
-+            if (st_idx >= st_num)
-+                st_idx = 0;
-+            if (i < j)
-+                *(buf++) = local_md[i + MD_DIGEST_LENGTH / 2];
-+        }
-+    }
-+
-+    if (!MD_Init(m)
-+        || !MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c))
-+        || !MD_Update(m, local_md, MD_DIGEST_LENGTH))
-+        goto err;
-+    CRYPTO_THREAD_write_lock(rand_lock);
-+    /*
-+     * Prevent deadlocks if we end up in an async engine
-+     */
-+    ASYNC_block_pause();
-+    if (!MD_Update(m, md, MD_DIGEST_LENGTH) || !MD_Final(m, md)) {
-+        CRYPTO_THREAD_unlock(rand_lock);
-+        goto err;
-+    }
-+    ASYNC_unblock_pause();
-+    CRYPTO_THREAD_unlock(rand_lock);
-+
-+    EVP_MD_CTX_free(m);
-+    if (ok)
-+        return (1);
-+    else if (pseudo)
-+        return 0;
-+    else {
-+        RANDerr(RAND_F_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED);
-+        ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
-+                           "https://www.openssl.org/docs/faq.html");
-+        return (0);
-+    }
-+ err:
-+    RANDerr(RAND_F_RAND_BYTES, ERR_R_EVP_LIB);
-+    EVP_MD_CTX_free(m);
-+    return 0;
-+ err_mem:
-+    RANDerr(RAND_F_RAND_BYTES, ERR_R_MALLOC_FAILURE);
-+    EVP_MD_CTX_free(m);
-+    return 0;
-+
-+}
-+
-+static int rand_nopseudo_bytes(unsigned char *buf, int num)
-+{
-+    return rand_bytes(buf, num, 0);
-+}
-+
-+#if OPENSSL_API_COMPAT < 0x10100000L
-+/*
-+ * pseudo-random bytes that are guaranteed to be unique but not unpredictable
-+ */
-+static int rand_pseudo_bytes(unsigned char *buf, int num)
-+{
-+    return rand_bytes(buf, num, 1);
-+}
-+#endif
-+
-+static int rand_status(void)
-+{
-+    CRYPTO_THREAD_ID cur;
-+    int ret;
-+    int do_not_lock;
-+
-+    if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
-+        return 0;
-+
-+    cur = CRYPTO_THREAD_get_current_id();
-+    /*
-+     * check if we already have the lock (could happen if a RAND_poll()
-+     * implementation calls RAND_status())
-+     */
-+    if (crypto_lock_rand) {
-+        CRYPTO_THREAD_read_lock(rand_tmp_lock);
-+        do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
-+        CRYPTO_THREAD_unlock(rand_tmp_lock);
-+    } else
-+        do_not_lock = 0;
-+
-+    if (!do_not_lock) {
-+        CRYPTO_THREAD_write_lock(rand_lock);
-+        /*
-+         * Prevent deadlocks in case we end up in an async engine
-+         */
-+        ASYNC_block_pause();
-+
-+        /*
-+         * prevent rand_bytes() from trying to obtain the lock again
-+         */
-+        CRYPTO_THREAD_write_lock(rand_tmp_lock);
-+        locking_threadid = cur;
-+        CRYPTO_THREAD_unlock(rand_tmp_lock);
-+        crypto_lock_rand = 1;
-+    }
-+
-+    if (!initialized) {
-+        RAND_poll();
-+        initialized = 1;
-+    }
-+
-+    ret = entropy >= ENTROPY_NEEDED;
-+
-+    if (!do_not_lock) {
-+        /* before unlocking, we must clear 'crypto_lock_rand' */
-+        crypto_lock_rand = 0;
-+
-+        ASYNC_unblock_pause();
-+        CRYPTO_THREAD_unlock(rand_lock);
-+    }
-+
-+    return ret;
-+}
-+
-+/*
-+ * rand_hw_seed: get seed data from any available hardware RNG. only
-+ * currently supports rdrand.
-+ */
-+
-+/* Adapted from eng_rdrand.c */
-+
-+#if (defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
-+     defined(__x86_64) || defined(__x86_64__) || \
-+     defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ) \
-+     && !defined(OPENSSL_NO_RDRAND)
-+
-+# define RDRAND_CALLS    4
-+
-+size_t OPENSSL_ia32_rdrand(void);
-+extern unsigned int OPENSSL_ia32cap_P[];
-+
-+static int rand_hw_seed(EVP_MD_CTX *ctx)
-+{
-+    int i;
-+    if (!(OPENSSL_ia32cap_P[1] & (1 << (62 - 32))))
-+        return 1;
-+    for (i = 0; i < RDRAND_CALLS; i++) {
-+        size_t rnd;
-+        rnd = OPENSSL_ia32_rdrand();
-+        if (rnd == 0)
-+            return 1;
-+        if (!MD_Update(ctx, (unsigned char *)&rnd, sizeof(size_t)))
-+            return 0;
-+    }
-+    return 1;
-+}
-+
-+/* XOR an existing buffer with random data */
-+
-+void rand_hw_xor(unsigned char *buf, size_t num)
-+{
-+    size_t rnd;
-+    if (!(OPENSSL_ia32cap_P[1] & (1 << (62 - 32))))
-+        return;
-+    while (num >= sizeof(size_t)) {
-+        rnd = OPENSSL_ia32_rdrand();
-+        if (rnd == 0)
-+            return;
-+        *((size_t *)buf) ^= rnd;
-+        buf += sizeof(size_t);
-+        num -= sizeof(size_t);
-+    }
-+    if (num) {
-+        rnd = OPENSSL_ia32_rdrand();
-+        if (rnd == 0)
-+            return;
-+        while (num) {
-+            *buf ^= rnd & 0xff;
-+            rnd >>= 8;
-+            buf++;
-+            num--;
-+        }
-+    }
-+}
-+
-+#else
-+
-+static int rand_hw_seed(EVP_MD_CTX *ctx)
-+{
-+    return 1;
-+}
-+
-+void rand_hw_xor(unsigned char *buf, size_t num)
-+{
-+    return;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_egd.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_egd.c
-new file mode 100644
-index 0000000..dd58b21
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_egd.c
-@@ -0,0 +1,249 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#ifdef OPENSSL_NO_EGD
-+NON_EMPTY_TRANSLATION_UNIT
-+#else
-+
-+# include 
-+# include 
-+# include 
-+
-+/*-
-+ * Query the EGD .
-+ *
-+ * This module supplies three routines:
-+ *
-+ * RAND_query_egd_bytes(path, buf, bytes)
-+ *   will actually query "bytes" bytes of entropy form the egd-socket located
-+ *   at path and will write them to buf (if supplied) or will directly feed
-+ *   it to RAND_seed() if buf==NULL.
-+ *   The number of bytes is not limited by the maximum chunk size of EGD,
-+ *   which is 255 bytes. If more than 255 bytes are wanted, several chunks
-+ *   of entropy bytes are requested. The connection is left open until the
-+ *   query is competed.
-+ *   RAND_query_egd_bytes() returns with
-+ *     -1  if an error occurred during connection or communication.
-+ *     num the number of bytes read from the EGD socket. This number is either
-+ *         the number of bytes requested or smaller, if the EGD pool is
-+ *         drained and the daemon signals that the pool is empty.
-+ *   This routine does not touch any RAND_status(). This is necessary, since
-+ *   PRNG functions may call it during initialization.
-+ *
-+ * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them
-+ *   used to seed the PRNG.
-+ *   RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL.
-+ *   Unlike RAND_query_egd_bytes(), RAND_status() is used to test the
-+ *   seed status so that the return value can reflect the seed state:
-+ *     -1  if an error occurred during connection or communication _or_
-+ *         if the PRNG has still not received the required seeding.
-+ *     num the number of bytes read from the EGD socket. This number is either
-+ *         the number of bytes requested or smaller, if the EGD pool is
-+ *         drained and the daemon signals that the pool is empty.
-+ *
-+ * RAND_egd(path) will query 255 bytes and use the bytes retrieved to seed
-+ *   the PRNG.
-+ *   RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
-+ */
-+
-+# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_UEFI)
-+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
-+{
-+    return (-1);
-+}
-+
-+int RAND_egd(const char *path)
-+{
-+    return (-1);
-+}
-+
-+int RAND_egd_bytes(const char *path, int bytes)
-+{
-+    return (-1);
-+}
-+# else
-+#  include 
-+#  include OPENSSL_UNISTD
-+#  include 
-+#  include 
-+#  include 
-+#  ifndef NO_SYS_UN_H
-+#   ifdef OPENSSL_SYS_VXWORKS
-+#    include 
-+#   else
-+#    include 
-+#   endif
-+#  else
-+struct sockaddr_un {
-+    short sun_family;           /* AF_UNIX */
-+    char sun_path[108];         /* path name (gag) */
-+};
-+#  endif                         /* NO_SYS_UN_H */
-+#  include 
-+#  include 
-+
-+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
-+{
-+    int ret = 0;
-+    struct sockaddr_un addr;
-+    int len, num, numbytes;
-+    int fd = -1;
-+    int success;
-+    unsigned char egdbuf[2], tempbuf[255], *retrievebuf;
-+
-+    memset(&addr, 0, sizeof(addr));
-+    addr.sun_family = AF_UNIX;
-+    if (strlen(path) >= sizeof(addr.sun_path))
-+        return (-1);
-+    OPENSSL_strlcpy(addr.sun_path, path, sizeof addr.sun_path);
-+    len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
-+    fd = socket(AF_UNIX, SOCK_STREAM, 0);
-+    if (fd == -1)
-+        return (-1);
-+    success = 0;
-+    while (!success) {
-+        if (connect(fd, (struct sockaddr *)&addr, len) == 0)
-+            success = 1;
-+        else {
-+            switch (errno) {
-+#  ifdef EINTR
-+            case EINTR:
-+#  endif
-+#  ifdef EAGAIN
-+            case EAGAIN:
-+#  endif
-+#  ifdef EINPROGRESS
-+            case EINPROGRESS:
-+#  endif
-+#  ifdef EALREADY
-+            case EALREADY:
-+#  endif
-+                /* No error, try again */
-+                break;
-+#  ifdef EISCONN
-+            case EISCONN:
-+                success = 1;
-+                break;
-+#  endif
-+            default:
-+                ret = -1;
-+                goto err;       /* failure */
-+            }
-+        }
-+    }
-+
-+    while (bytes > 0) {
-+        egdbuf[0] = 1;
-+        egdbuf[1] = bytes < 255 ? bytes : 255;
-+        numbytes = 0;
-+        while (numbytes != 2) {
-+            num = write(fd, egdbuf + numbytes, 2 - numbytes);
-+            if (num >= 0)
-+                numbytes += num;
-+            else {
-+                switch (errno) {
-+#  ifdef EINTR
-+                case EINTR:
-+#  endif
-+#  ifdef EAGAIN
-+                case EAGAIN:
-+#  endif
-+                    /* No error, try again */
-+                    break;
-+                default:
-+                    ret = -1;
-+                    goto err;   /* failure */
-+                }
-+            }
-+        }
-+        numbytes = 0;
-+        while (numbytes != 1) {
-+            num = read(fd, egdbuf, 1);
-+            if (num == 0)
-+                goto err;       /* descriptor closed */
-+            else if (num > 0)
-+                numbytes += num;
-+            else {
-+                switch (errno) {
-+#  ifdef EINTR
-+                case EINTR:
-+#  endif
-+#  ifdef EAGAIN
-+                case EAGAIN:
-+#  endif
-+                    /* No error, try again */
-+                    break;
-+                default:
-+                    ret = -1;
-+                    goto err;   /* failure */
-+                }
-+            }
-+        }
-+        if (egdbuf[0] == 0)
-+            goto err;
-+        if (buf)
-+            retrievebuf = buf + ret;
-+        else
-+            retrievebuf = tempbuf;
-+        numbytes = 0;
-+        while (numbytes != egdbuf[0]) {
-+            num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes);
-+            if (num == 0)
-+                goto err;       /* descriptor closed */
-+            else if (num > 0)
-+                numbytes += num;
-+            else {
-+                switch (errno) {
-+#  ifdef EINTR
-+                case EINTR:
-+#  endif
-+#  ifdef EAGAIN
-+                case EAGAIN:
-+#  endif
-+                    /* No error, try again */
-+                    break;
-+                default:
-+                    ret = -1;
-+                    goto err;   /* failure */
-+                }
-+            }
-+        }
-+        ret += egdbuf[0];
-+        bytes -= egdbuf[0];
-+        if (!buf)
-+            RAND_seed(tempbuf, egdbuf[0]);
-+    }
-+ err:
-+    if (fd != -1)
-+        close(fd);
-+    return (ret);
-+}
-+
-+int RAND_egd_bytes(const char *path, int bytes)
-+{
-+    int num, ret = -1;
-+
-+    num = RAND_query_egd_bytes(path, NULL, bytes);
-+    if (num < 0)
-+        goto err;
-+    if (RAND_status() == 1)
-+        ret = num;
-+ err:
-+    return (ret);
-+}
-+
-+int RAND_egd(const char *path)
-+{
-+    return (RAND_egd_bytes(path, 255));
-+}
-+
-+# endif
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_err.c
-new file mode 100644
-index 0000000..5543126
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_err.c
-@@ -0,0 +1,43 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason)
-+
-+static ERR_STRING_DATA RAND_str_functs[] = {
-+    {ERR_FUNC(RAND_F_RAND_BYTES), "RAND_bytes"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA RAND_str_reasons[] = {
-+    {ERR_REASON(RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_RAND_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, RAND_str_functs);
-+        ERR_load_strings(0, RAND_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_lcl.h
-new file mode 100644
-index 0000000..d98c90e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_lcl.h
-@@ -0,0 +1,46 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_RAND_LCL_H
-+# define HEADER_RAND_LCL_H
-+
-+# define ENTROPY_NEEDED 32      /* require 256 bits = 32 bytes of randomness */
-+
-+# if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND)
-+#  define USE_SHA1_RAND
-+# endif
-+
-+# include 
-+# define MD_Update(a,b,c)        EVP_DigestUpdate(a,b,c)
-+# define MD_Final(a,b)           EVP_DigestFinal_ex(a,b,NULL)
-+# if defined(USE_MD5_RAND)
-+#  include 
-+#  define MD_DIGEST_LENGTH        MD5_DIGEST_LENGTH
-+#  define MD_Init(a)              EVP_DigestInit_ex(a,EVP_md5(), NULL)
-+#  define MD(a,b,c)               EVP_Digest(a,b,c,NULL,EVP_md5(), NULL)
-+# elif defined(USE_SHA1_RAND)
-+#  include 
-+#  define MD_DIGEST_LENGTH        SHA_DIGEST_LENGTH
-+#  define MD_Init(a)              EVP_DigestInit_ex(a,EVP_sha1(), NULL)
-+#  define MD(a,b,c)               EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL)
-+# elif defined(USE_MDC2_RAND)
-+#  include 
-+#  define MD_DIGEST_LENGTH        MDC2_DIGEST_LENGTH
-+#  define MD_Init(a)              EVP_DigestInit_ex(a,EVP_mdc2(), NULL)
-+#  define MD(a,b,c)               EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL)
-+# elif defined(USE_MD2_RAND)
-+#  include 
-+#  define MD_DIGEST_LENGTH        MD2_DIGEST_LENGTH
-+#  define MD_Init(a)              EVP_DigestInit_ex(a,EVP_md2(), NULL)
-+#  define MD(a,b,c)               EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
-+# endif
-+
-+void rand_hw_xor(unsigned char *buf, size_t num);
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_lib.c
-new file mode 100644
-index 0000000..2387126
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_lib.c
-@@ -0,0 +1,126 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "internal/rand.h"
-+
-+#include 
-+
-+#ifdef OPENSSL_FIPS
-+# include 
-+# include 
-+#endif
-+
-+#ifndef OPENSSL_NO_ENGINE
-+/* non-NULL if default_RAND_meth is ENGINE-provided */
-+static ENGINE *funct_ref = NULL;
-+#endif
-+static const RAND_METHOD *default_RAND_meth = NULL;
-+
-+int RAND_set_rand_method(const RAND_METHOD *meth)
-+{
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(funct_ref);
-+    funct_ref = NULL;
-+#endif
-+    default_RAND_meth = meth;
-+    return 1;
-+}
-+
-+const RAND_METHOD *RAND_get_rand_method(void)
-+{
-+    if (!default_RAND_meth) {
-+#ifndef OPENSSL_NO_ENGINE
-+        ENGINE *e = ENGINE_get_default_RAND();
-+        if (e) {
-+            default_RAND_meth = ENGINE_get_RAND(e);
-+            if (default_RAND_meth == NULL) {
-+                ENGINE_finish(e);
-+                e = NULL;
-+            }
-+        }
-+        if (e)
-+            funct_ref = e;
-+        else
-+#endif
-+            default_RAND_meth = RAND_OpenSSL();
-+    }
-+    return default_RAND_meth;
-+}
-+
-+#ifndef OPENSSL_NO_ENGINE
-+int RAND_set_rand_engine(ENGINE *engine)
-+{
-+    const RAND_METHOD *tmp_meth = NULL;
-+    if (engine) {
-+        if (!ENGINE_init(engine))
-+            return 0;
-+        tmp_meth = ENGINE_get_RAND(engine);
-+        if (tmp_meth == NULL) {
-+            ENGINE_finish(engine);
-+            return 0;
-+        }
-+    }
-+    /* This function releases any prior ENGINE so call it first */
-+    RAND_set_rand_method(tmp_meth);
-+    funct_ref = engine;
-+    return 1;
-+}
-+#endif
-+
-+void rand_cleanup_int(void)
-+{
-+    const RAND_METHOD *meth = RAND_get_rand_method();
-+    if (meth && meth->cleanup)
-+        meth->cleanup();
-+    RAND_set_rand_method(NULL);
-+}
-+
-+void RAND_seed(const void *buf, int num)
-+{
-+    const RAND_METHOD *meth = RAND_get_rand_method();
-+    if (meth && meth->seed)
-+        meth->seed(buf, num);
-+}
-+
-+void RAND_add(const void *buf, int num, double entropy)
-+{
-+    const RAND_METHOD *meth = RAND_get_rand_method();
-+    if (meth && meth->add)
-+        meth->add(buf, num, entropy);
-+}
-+
-+int RAND_bytes(unsigned char *buf, int num)
-+{
-+    const RAND_METHOD *meth = RAND_get_rand_method();
-+    if (meth && meth->bytes)
-+        return meth->bytes(buf, num);
-+    return (-1);
-+}
-+
-+#if OPENSSL_API_COMPAT < 0x10100000L
-+int RAND_pseudo_bytes(unsigned char *buf, int num)
-+{
-+    const RAND_METHOD *meth = RAND_get_rand_method();
-+    if (meth && meth->pseudorand)
-+        return meth->pseudorand(buf, num);
-+    return (-1);
-+}
-+#endif
-+
-+int RAND_status(void)
-+{
-+    const RAND_METHOD *meth = RAND_get_rand_method();
-+    if (meth && meth->status)
-+        return meth->status();
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_unix.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_unix.c
-new file mode 100644
-index 0000000..ecba2dc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_unix.c
-@@ -0,0 +1,324 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#define USE_SOCKETS
-+#include "e_os.h"
-+#include "internal/cryptlib.h"
-+#include 
-+#include "rand_lcl.h"
-+
-+#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI))
-+
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually
-+                                 * everywhere */
-+#  include 
-+# endif
-+# include 
-+# ifndef FD_SETSIZE
-+#  define FD_SETSIZE (8*sizeof(fd_set))
-+# endif
-+
-+# if defined(OPENSSL_SYS_VOS)
-+
-+/*
-+ * The following algorithm repeatedly samples the real-time clock (RTC) to
-+ * generate a sequence of unpredictable data.  The algorithm relies upon the
-+ * uneven execution speed of the code (due to factors such as cache misses,
-+ * interrupts, bus activity, and scheduling) and upon the rather large
-+ * relative difference between the speed of the clock and the rate at which
-+ * it can be read.
-+ *
-+ * If this code is ported to an environment where execution speed is more
-+ * constant or where the RTC ticks at a much slower rate, or the clock can be
-+ * read with fewer instructions, it is likely that the results would be far
-+ * more predictable.
-+ *
-+ * As a precaution, we generate 4 times the minimum required amount of seed
-+ * data.
-+ */
-+
-+int RAND_poll(void)
-+{
-+    short int code;
-+    gid_t curr_gid;
-+    pid_t curr_pid;
-+    uid_t curr_uid;
-+    int i, k;
-+    struct timespec ts;
-+    unsigned char v;
-+
-+#  ifdef OPENSSL_SYS_VOS_HPPA
-+    long duration;
-+    extern void s$sleep(long *_duration, short int *_code);
-+#  else
-+#   ifdef OPENSSL_SYS_VOS_IA32
-+    long long duration;
-+    extern void s$sleep2(long long *_duration, short int *_code);
-+#   else
-+#    error "Unsupported Platform."
-+#   endif                       /* OPENSSL_SYS_VOS_IA32 */
-+#  endif                        /* OPENSSL_SYS_VOS_HPPA */
-+
-+    /*
-+     * Seed with the gid, pid, and uid, to ensure *some* variation between
-+     * different processes.
-+     */
-+
-+    curr_gid = getgid();
-+    RAND_add(&curr_gid, sizeof curr_gid, 1);
-+    curr_gid = 0;
-+
-+    curr_pid = getpid();
-+    RAND_add(&curr_pid, sizeof curr_pid, 1);
-+    curr_pid = 0;
-+
-+    curr_uid = getuid();
-+    RAND_add(&curr_uid, sizeof curr_uid, 1);
-+    curr_uid = 0;
-+
-+    for (i = 0; i < (ENTROPY_NEEDED * 4); i++) {
-+        /*
-+         * burn some cpu; hope for interrupts, cache collisions, bus
-+         * interference, etc.
-+         */
-+        for (k = 0; k < 99; k++)
-+            ts.tv_nsec = random();
-+
-+#  ifdef OPENSSL_SYS_VOS_HPPA
-+        /* sleep for 1/1024 of a second (976 us).  */
-+        duration = 1;
-+        s$sleep(&duration, &code);
-+#  else
-+#   ifdef OPENSSL_SYS_VOS_IA32
-+        /* sleep for 1/65536 of a second (15 us).  */
-+        duration = 1;
-+        s$sleep2(&duration, &code);
-+#   endif                       /* OPENSSL_SYS_VOS_IA32 */
-+#  endif                        /* OPENSSL_SYS_VOS_HPPA */
-+
-+        /* get wall clock time.  */
-+        clock_gettime(CLOCK_REALTIME, &ts);
-+
-+        /* take 8 bits */
-+        v = (unsigned char)(ts.tv_nsec % 256);
-+        RAND_add(&v, sizeof v, 1);
-+        v = 0;
-+    }
-+    return 1;
-+}
-+# elif defined __OpenBSD__
-+int RAND_poll(void)
-+{
-+    u_int32_t rnd = 0, i;
-+    unsigned char buf[ENTROPY_NEEDED];
-+
-+    for (i = 0; i < sizeof(buf); i++) {
-+        if (i % 4 == 0)
-+            rnd = arc4random();
-+        buf[i] = rnd;
-+        rnd >>= 8;
-+    }
-+    RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
-+    OPENSSL_cleanse(buf, sizeof(buf));
-+
-+    return 1;
-+}
-+# else                          /* !defined(__OpenBSD__) */
-+int RAND_poll(void)
-+{
-+    unsigned long l;
-+    pid_t curr_pid = getpid();
-+#  if defined(DEVRANDOM) || (!defined(OPENSS_NO_EGD) && defined(DEVRANDOM_EGD))
-+    unsigned char tmpbuf[ENTROPY_NEEDED];
-+    int n = 0;
-+#  endif
-+#  ifdef DEVRANDOM
-+    static const char *randomfiles[] = { DEVRANDOM };
-+    struct stat randomstats[OSSL_NELEM(randomfiles)];
-+    int fd;
-+    unsigned int i;
-+#  endif
-+#  if !defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD)
-+    static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
-+    const char **egdsocket = NULL;
-+#  endif
-+
-+#  ifdef DEVRANDOM
-+    memset(randomstats, 0, sizeof(randomstats));
-+    /*
-+     * Use a random entropy pool device. Linux, FreeBSD and OpenBSD have
-+     * this. Use /dev/urandom if you can as /dev/random may block if it runs
-+     * out of random entries.
-+     */
-+
-+    for (i = 0; (i < OSSL_NELEM(randomfiles)) && (n < ENTROPY_NEEDED); i++) {
-+        if ((fd = open(randomfiles[i], O_RDONLY
-+#   ifdef O_NONBLOCK
-+                       | O_NONBLOCK
-+#   endif
-+#   ifdef O_BINARY
-+                       | O_BINARY
-+#   endif
-+#   ifdef O_NOCTTY              /* If it happens to be a TTY (god forbid), do
-+                                 * not make it our controlling tty */
-+                       | O_NOCTTY
-+#   endif
-+             )) >= 0) {
-+            int usec = 10 * 1000; /* spend 10ms on each file */
-+            int r;
-+            unsigned int j;
-+            struct stat *st = &randomstats[i];
-+
-+            /*
-+             * Avoid using same input... Used to be O_NOFOLLOW above, but
-+             * it's not universally appropriate...
-+             */
-+            if (fstat(fd, st) != 0) {
-+                close(fd);
-+                continue;
-+            }
-+            for (j = 0; j < i; j++) {
-+                if (randomstats[j].st_ino == st->st_ino &&
-+                    randomstats[j].st_dev == st->st_dev)
-+                    break;
-+            }
-+            if (j < i) {
-+                close(fd);
-+                continue;
-+            }
-+
-+            do {
-+                int try_read = 0;
-+
-+#   if defined(OPENSSL_SYS_LINUX)
-+                /* use poll() */
-+                struct pollfd pset;
-+
-+                pset.fd = fd;
-+                pset.events = POLLIN;
-+                pset.revents = 0;
-+
-+                if (poll(&pset, 1, usec / 1000) < 0)
-+                    usec = 0;
-+                else
-+                    try_read = (pset.revents & POLLIN) != 0;
-+
-+#   else
-+                /* use select() */
-+                fd_set fset;
-+                struct timeval t;
-+
-+                t.tv_sec = 0;
-+                t.tv_usec = usec;
-+
-+                if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) {
-+                    /*
-+                     * can't use select, so just try to read once anyway
-+                     */
-+                    try_read = 1;
-+                } else {
-+                    FD_ZERO(&fset);
-+                    FD_SET(fd, &fset);
-+
-+                    if (select(fd + 1, &fset, NULL, NULL, &t) >= 0) {
-+                        usec = t.tv_usec;
-+                        if (FD_ISSET(fd, &fset))
-+                            try_read = 1;
-+                    } else
-+                        usec = 0;
-+                }
-+#   endif
-+
-+                if (try_read) {
-+                    r = read(fd, (unsigned char *)tmpbuf + n,
-+                             ENTROPY_NEEDED - n);
-+                    if (r > 0)
-+                        n += r;
-+                } else
-+                    r = -1;
-+
-+                /*
-+                 * Some Unixen will update t in select(), some won't.  For
-+                 * those who won't, or if we didn't use select() in the first
-+                 * place, give up here, otherwise, we will do this once again
-+                 * for the remaining time.
-+                 */
-+                if (usec == 10 * 1000)
-+                    usec = 0;
-+            }
-+            while ((r > 0 ||
-+                    (errno == EINTR || errno == EAGAIN)) && usec != 0
-+                   && n < ENTROPY_NEEDED);
-+
-+            close(fd);
-+        }
-+    }
-+#  endif                        /* defined(DEVRANDOM) */
-+
-+#  if !defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD)
-+    /*
-+     * Use an EGD socket to read entropy from an EGD or PRNGD entropy
-+     * collecting daemon.
-+     */
-+
-+    for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED;
-+         egdsocket++) {
-+        int r;
-+
-+        r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf + n,
-+                                 ENTROPY_NEEDED - n);
-+        if (r > 0)
-+            n += r;
-+    }
-+#  endif                        /* defined(DEVRANDOM_EGD) */
-+
-+#  if defined(DEVRANDOM) || (!defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD))
-+    if (n > 0) {
-+        RAND_add(tmpbuf, sizeof tmpbuf, (double)n);
-+        OPENSSL_cleanse(tmpbuf, n);
-+    }
-+#  endif
-+
-+    /* put in some default random data, we need more than just this */
-+    l = curr_pid;
-+    RAND_add(&l, sizeof(l), 0.0);
-+    l = getuid();
-+    RAND_add(&l, sizeof(l), 0.0);
-+
-+    l = time(NULL);
-+    RAND_add(&l, sizeof(l), 0.0);
-+
-+#  if defined(DEVRANDOM) || (!defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD))
-+    return 1;
-+#  else
-+    return 0;
-+#  endif
-+}
-+
-+# endif                         /* defined(__OpenBSD__) */
-+#endif                          /* !(defined(OPENSSL_SYS_WINDOWS) ||
-+                                 * defined(OPENSSL_SYS_WIN32) ||
-+                                 * defined(OPENSSL_SYS_VMS) ||
-+                                 * defined(OPENSSL_SYS_VXWORKS) */
-+
-+#if defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)
-+int RAND_poll(void)
-+{
-+    return 0;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_vms.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_vms.c
-new file mode 100644
-index 0000000..9c462dd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_vms.c
-@@ -0,0 +1,133 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Modified by VMS Software, Inc (2016)
-+ *    Eliminate looping through all processes (performance)
-+ *    Add additional randomizations using rand() function
-+ */
-+
-+#include 
-+#include "rand_lcl.h"
-+
-+#if defined(OPENSSL_SYS_VMS)
-+# include 
-+# include 
-+# include 
-+# include 
-+# include 
-+# ifdef __DECC
-+#  pragma message disable DOLLARID
-+# endif
-+
-+/*
-+ * Use 32-bit pointers almost everywhere.  Define the type to which to cast a
-+ * pointer passed to an external function.
-+ */
-+# if __INITIAL_POINTER_SIZE == 64
-+#  define PTR_T __void_ptr64
-+#  pragma pointer_size save
-+#  pragma pointer_size 32
-+# else                          /* __INITIAL_POINTER_SIZE == 64 */
-+#  define PTR_T void *
-+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
-+
-+static struct items_data_st {
-+    short length, code;         /* length is number of bytes */
-+} items_data[] = {
-+    {4, JPI$_BUFIO},
-+    {4, JPI$_CPUTIM},
-+    {4, JPI$_DIRIO},
-+    {4, JPI$_IMAGECOUNT},
-+    {8, JPI$_LAST_LOGIN_I},
-+    {8, JPI$_LOGINTIM},
-+    {4, JPI$_PAGEFLTS},
-+    {4, JPI$_PID},
-+    {4, JPI$_PPGCNT},
-+    {4, JPI$_WSPEAK},
-+    {4, JPI$_FINALEXC},
-+    {0, 0}                      /* zero terminated */
-+};
-+
-+int RAND_poll(void)
-+{
-+
-+    /* determine the number of items in the JPI array */
-+
-+    struct items_data_st item_entry;
-+    int item_entry_count = sizeof(items_data)/sizeof(item_entry);
-+
-+    /* Create the JPI itemlist array to hold item_data content */
-+
-+    struct {
-+        short length, code;
-+        int *buffer;
-+        int *retlen;
-+    } item[item_entry_count], *pitem; /* number of entries in items_data */
-+
-+    struct items_data_st *pitems_data;
-+    int data_buffer[(item_entry_count*2)+4]; /* 8 bytes per entry max */
-+    int iosb[2];
-+    int sys_time[2];
-+    int *ptr;
-+    int i, j ;
-+    int tmp_length   = 0;
-+    int total_length = 0;
-+
-+    pitems_data = items_data;
-+    pitem = item;
-+
-+
-+    /* Setup itemlist for GETJPI */
-+    while (pitems_data->length) {
-+        pitem->length = pitems_data->length;
-+        pitem->code   = pitems_data->code;
-+        pitem->buffer = &data_buffer[total_length];
-+        pitem->retlen = 0;
-+        /* total_length is in longwords */
-+        total_length += pitems_data->length/4;
-+        pitems_data++;
-+        pitem ++;
-+    }
-+    pitem->length = pitem->code = 0;
-+
-+    /* Fill data_buffer with various info bits from this process */
-+    /* and twist that data to seed the SSL random number init    */
-+
-+    if (sys$getjpiw(EFN$C_ENF, NULL, NULL, item, &iosb, 0, 0) == SS$_NORMAL) {
-+        for (i = 0; i < total_length; i++) {
-+            sys$gettim((struct _generic_64 *)&sys_time[0]);
-+            srand(sys_time[0] * data_buffer[0] * data_buffer[1] + i);
-+
-+            if (i == (total_length - 1)) { /* for JPI$_FINALEXC */
-+                ptr = &data_buffer[i];
-+                for (j = 0; j < 4; j++) {
-+                    data_buffer[i + j] = ptr[j];
-+                    /* OK to use rand() just to scramble the seed */
-+                    data_buffer[i + j] ^= (sys_time[0] ^ rand());
-+                    tmp_length++;
-+                }
-+            } else {
-+                /* OK to use rand() just to scramble the seed */
-+                data_buffer[i] ^= (sys_time[0] ^ rand());
-+            }
-+        }
-+
-+        total_length += (tmp_length - 1);
-+
-+        /* size of seed is total_length*4 bytes (64bytes) */
-+        RAND_add((PTR_T) data_buffer, total_length*4, total_length * 2);
-+    } else {
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_win.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_win.c
-new file mode 100644
-index 0000000..1be0ed3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/rand_win.c
-@@ -0,0 +1,135 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include "rand_lcl.h"
-+
-+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
-+# include 
-+/* On Windows 7 or higher use BCrypt instead of the legacy CryptoAPI */
-+# if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0601
-+#  define RAND_WINDOWS_USE_BCRYPT
-+# endif
-+
-+# ifdef RAND_WINDOWS_USE_BCRYPT
-+#  include 
-+#  pragma comment(lib, "bcrypt.lib")
-+#  ifndef STATUS_SUCCESS
-+#   define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
-+#  endif
-+# else
-+#  include 
-+/*
-+ * Intel hardware RNG CSP -- available from
-+ * http://developer.intel.com/design/security/rng/redist_license.htm
-+ */
-+#  define PROV_INTEL_SEC 22
-+#  define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"
-+# endif
-+
-+static void readtimer(void);
-+
-+int RAND_poll(void)
-+{
-+    MEMORYSTATUS mst;
-+# ifndef RAND_WINDOWS_USE_BCRYPT
-+    HCRYPTPROV hProvider;
-+# endif
-+    DWORD w;
-+    BYTE buf[64];
-+
-+# ifdef RAND_WINDOWS_USE_BCRYPT
-+    if (BCryptGenRandom(NULL, buf, (ULONG)sizeof(buf), BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) {
-+        RAND_add(buf, sizeof(buf), sizeof(buf));
-+    }
-+# else
-+    /* poll the CryptoAPI PRNG */
-+    /* The CryptoAPI returns sizeof(buf) bytes of randomness */
-+    if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
-+        if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
-+            RAND_add(buf, sizeof(buf), sizeof(buf));
-+        }
-+        CryptReleaseContext(hProvider, 0);
-+    }
-+
-+    /* poll the Pentium PRG with CryptoAPI */
-+    if (CryptAcquireContextW(&hProvider, NULL, INTEL_DEF_PROV, PROV_INTEL_SEC, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
-+        if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
-+            RAND_add(buf, sizeof(buf), sizeof(buf));
-+        }
-+        CryptReleaseContext(hProvider, 0);
-+    }
-+# endif
-+
-+    /* timer data */
-+    readtimer();
-+
-+    /* memory usage statistics */
-+    GlobalMemoryStatus(&mst);
-+    RAND_add(&mst, sizeof(mst), 1);
-+
-+    /* process ID */
-+    w = GetCurrentProcessId();
-+    RAND_add(&w, sizeof(w), 1);
-+
-+    return (1);
-+}
-+
-+#if OPENSSL_API_COMPAT < 0x10100000L
-+int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
-+{
-+    RAND_poll();
-+    return RAND_status();
-+}
-+
-+void RAND_screen(void)
-+{
-+    RAND_poll();
-+}
-+#endif
-+
-+/* feed timing information to the PRNG */
-+static void readtimer(void)
-+{
-+    DWORD w;
-+    LARGE_INTEGER l;
-+    static int have_perfc = 1;
-+# if defined(_MSC_VER) && defined(_M_X86)
-+    static int have_tsc = 1;
-+    DWORD cyclecount;
-+
-+    if (have_tsc) {
-+        __try {
-+            __asm {
-+            _emit 0x0f _emit 0x31 mov cyclecount, eax}
-+            RAND_add(&cyclecount, sizeof(cyclecount), 1);
-+        }
-+        __except(EXCEPTION_EXECUTE_HANDLER) {
-+            have_tsc = 0;
-+        }
-+    }
-+# else
-+#  define have_tsc 0
-+# endif
-+
-+    if (have_perfc) {
-+        if (QueryPerformanceCounter(&l) == 0)
-+            have_perfc = 0;
-+        else
-+            RAND_add(&l, sizeof(l), 0);
-+    }
-+
-+    if (!have_tsc && !have_perfc) {
-+        w = GetTickCount();
-+        RAND_add(&w, sizeof(w), 0);
-+    }
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/randfile.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/randfile.c
-new file mode 100644
-index 0000000..15fa9dc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rand/randfile.c
-@@ -0,0 +1,366 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+
-+#ifdef OPENSSL_SYS_VMS
-+# include 
-+#endif
-+#ifndef NO_SYS_TYPES_H
-+# include 
-+#endif
-+#ifndef OPENSSL_NO_POSIX_IO
-+# include 
-+# include 
-+/*
-+ * Following should not be needed, and we could have been stricter
-+ * and demand S_IS*. But some systems just don't comply... Formally
-+ * below macros are "anatomically incorrect", because normally they
-+ * would look like ((m) & MASK == TYPE), but since MASK availability
-+ * is as questionable, we settle for this poor-man fallback...
-+ */
-+# if !defined(S_ISBLK)
-+#  if defined(_S_IFBLK)
-+#   define S_ISBLK(m) ((m) & _S_IFBLK)
-+#  elif defined(S_IFBLK)
-+#   define S_ISBLK(m) ((m) & S_IFBLK)
-+#  elif defined(_WIN32)
-+#   define S_ISBLK(m) 0 /* no concept of block devices on Windows */
-+#  endif
-+# endif
-+# if !defined(S_ISCHR)
-+#  if defined(_S_IFCHR)
-+#   define S_ISCHR(m) ((m) & _S_IFCHR)
-+#  elif defined(S_IFCHR)
-+#   define S_ISCHR(m) ((m) & S_IFCHR)
-+#  endif
-+# endif
-+#endif
-+
-+#ifdef _WIN32
-+# define stat    _stat
-+# define chmod   _chmod
-+# define open    _open
-+# define fdopen  _fdopen
-+# define fstat   _fstat
-+# define fileno  _fileno
-+#endif
-+
-+#undef BUFSIZE
-+#define BUFSIZE 1024
-+#define RAND_DATA 1024
-+
-+#ifdef OPENSSL_SYS_VMS
-+/*
-+ * Misc hacks needed for specific cases.
-+ *
-+ * __FILE_ptr32 is a type provided by DEC C headers (types.h specifically)
-+ * to make sure the FILE* is a 32-bit pointer no matter what.  We know that
-+ * stdio function return this type (a study of stdio.h proves it).
-+ * Additionally, we create a similar char pointer type for the sake of
-+ * vms_setbuf below.
-+ */
-+# if __INITIAL_POINTER_SIZE == 64
-+#  pragma pointer_size save
-+#  pragma pointer_size 32
-+typedef char *char_ptr32;
-+#  pragma pointer_size restore
-+/*
-+ * On VMS, setbuf() will only take 32-bit pointers, and a compilation
-+ * with /POINTER_SIZE=64 will give off a MAYLOSEDATA2 warning here.
-+ * Since we know that the FILE* really is a 32-bit pointer expanded to
-+ * 64 bits, we also know it's safe to convert it back to a 32-bit pointer.
-+ * As for the buffer parameter, we only use NULL here, so that passes as
-+ * well...
-+ */
-+#  define setbuf(fp,buf) (setbuf)((__FILE_ptr32)(fp), (char_ptr32)(buf))
-+# endif
-+
-+/*
-+ * This declaration is a nasty hack to get around vms' extension to fopen for
-+ * passing in sharing options being disabled by /STANDARD=ANSI89
-+ */
-+static __FILE_ptr32 (*const vms_fopen)(const char *, const char *, ...) =
-+      (__FILE_ptr32 (*)(const char *, const char *, ...))fopen;
-+# define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0"
-+
-+# define openssl_fopen(fname,mode) vms_fopen((fname), (mode), VMS_OPEN_ATTRS)
-+#endif
-+
-+#define RFILE ".rnd"
-+
-+/*
-+ * Note that these functions are intended for seed files only. Entropy
-+ * devices and EGD sockets are handled in rand_unix.c
-+ */
-+
-+int RAND_load_file(const char *file, long bytes)
-+{
-+    /*-
-+     * If bytes >= 0, read up to 'bytes' bytes.
-+     * if bytes == -1, read complete file.
-+     */
-+
-+    unsigned char buf[BUFSIZE];
-+#ifndef OPENSSL_NO_POSIX_IO
-+    struct stat sb;
-+#endif
-+    int i, ret = 0, n;
-+    FILE *in = NULL;
-+
-+    if (file == NULL)
-+        return 0;
-+
-+    if (bytes == 0)
-+        return ret;
-+
-+    in = openssl_fopen(file, "rb");
-+    if (in == NULL)
-+        goto err;
-+
-+#ifndef OPENSSL_NO_POSIX_IO
-+    /*
-+     * struct stat can have padding and unused fields that may not be
-+     * initialized in the call to stat(). We need to clear the entire
-+     * structure before calling RAND_add() to avoid complaints from
-+     * applications such as Valgrind.
-+     */
-+    memset(&sb, 0, sizeof(sb));
-+    if (fstat(fileno(in), &sb) < 0)
-+        goto err;
-+    RAND_add(&sb, sizeof(sb), 0.0);
-+
-+# if defined(S_ISBLK) && defined(S_ISCHR)
-+    if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
-+        /*
-+         * this file is a device. we don't want read an infinite number of
-+         * bytes from a random device, nor do we want to use buffered I/O
-+         * because we will waste system entropy.
-+         */
-+        bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
-+        setbuf(in, NULL); /* don't do buffered reads */
-+    }
-+# endif
-+#endif
-+    for (;;) {
-+        if (bytes > 0)
-+            n = (bytes < BUFSIZE) ? (int)bytes : BUFSIZE;
-+        else
-+            n = BUFSIZE;
-+        i = fread(buf, 1, n, in);
-+        if (i <= 0)
-+            break;
-+
-+        RAND_add(buf, i, (double)i);
-+        ret += i;
-+        if (bytes > 0) {
-+            bytes -= n;
-+            if (bytes <= 0)
-+                break;
-+        }
-+    }
-+    OPENSSL_cleanse(buf, BUFSIZE);
-+ err:
-+    if (in != NULL)
-+        fclose(in);
-+    return ret;
-+}
-+
-+int RAND_write_file(const char *file)
-+{
-+    unsigned char buf[BUFSIZE];
-+    int i, ret = 0, rand_err = 0;
-+    FILE *out = NULL;
-+    int n;
-+#ifndef OPENSSL_NO_POSIX_IO
-+    struct stat sb;
-+
-+# if defined(S_ISBLK) && defined(S_ISCHR)
-+# ifdef _WIN32
-+    /*
-+     * Check for |file| being a driver as "ASCII-safe" on Windows,
-+     * because driver paths are always ASCII.
-+     */
-+# endif
-+    i = stat(file, &sb);
-+    if (i != -1) {
-+        if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
-+            /*
-+             * this file is a device. we don't write back to it. we
-+             * "succeed" on the assumption this is some sort of random
-+             * device. Otherwise attempting to write to and chmod the device
-+             * causes problems.
-+             */
-+            return 1;
-+        }
-+    }
-+# endif
-+#endif
-+
-+#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && \
-+    !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WINDOWS)
-+    {
-+# ifndef O_BINARY
-+#  define O_BINARY 0
-+# endif
-+        /*
-+         * chmod(..., 0600) is too late to protect the file, permissions
-+         * should be restrictive from the start
-+         */
-+        int fd = open(file, O_WRONLY | O_CREAT | O_BINARY, 0600);
-+        if (fd != -1)
-+            out = fdopen(fd, "wb");
-+    }
-+#endif
-+
-+#ifdef OPENSSL_SYS_VMS
-+    /*
-+     * VMS NOTE: Prior versions of this routine created a _new_ version of
-+     * the rand file for each call into this routine, then deleted all
-+     * existing versions named ;-1, and finally renamed the current version
-+     * as ';1'. Under concurrent usage, this resulted in an RMS race
-+     * condition in rename() which could orphan files (see vms message help
-+     * for RMS$_REENT). With the fopen() calls below, openssl/VMS now shares
-+     * the top-level version of the rand file. Note that there may still be
-+     * conditions where the top-level rand file is locked. If so, this code
-+     * will then create a new version of the rand file. Without the delete
-+     * and rename code, this can result in ascending file versions that stop
-+     * at version 32767, and this routine will then return an error. The
-+     * remedy for this is to recode the calling application to avoid
-+     * concurrent use of the rand file, or synchronize usage at the
-+     * application level. Also consider whether or not you NEED a persistent
-+     * rand file in a concurrent use situation.
-+     */
-+
-+    out = openssl_fopen(file, "rb+");
-+#endif
-+    if (out == NULL)
-+        out = openssl_fopen(file, "wb");
-+    if (out == NULL)
-+        goto err;
-+
-+#if !defined(NO_CHMOD) && !defined(OPENSSL_NO_POSIX_IO)
-+    chmod(file, 0600);
-+#endif
-+    n = RAND_DATA;
-+    for (;;) {
-+        i = (n > BUFSIZE) ? BUFSIZE : n;
-+        n -= BUFSIZE;
-+        if (RAND_bytes(buf, i) <= 0)
-+            rand_err = 1;
-+        i = fwrite(buf, 1, i, out);
-+        if (i <= 0) {
-+            ret = 0;
-+            break;
-+        }
-+        ret += i;
-+        if (n <= 0)
-+            break;
-+    }
-+
-+    fclose(out);
-+    OPENSSL_cleanse(buf, BUFSIZE);
-+ err:
-+    return (rand_err ? -1 : ret);
-+}
-+
-+const char *RAND_file_name(char *buf, size_t size)
-+{
-+    char *s = NULL;
-+    int use_randfile = 1;
-+#ifdef __OpenBSD__
-+    struct stat sb;
-+#endif
-+
-+#if defined(_WIN32) && defined(CP_UTF8)
-+    DWORD len;
-+    WCHAR *var, *val;
-+
-+    if ((var = L"RANDFILE",
-+         len = GetEnvironmentVariableW(var, NULL, 0)) == 0
-+        && (var = L"HOME", use_randfile = 0,
-+            len = GetEnvironmentVariableW(var, NULL, 0)) == 0
-+        && (var = L"USERPROFILE",
-+            len = GetEnvironmentVariableW(var, NULL, 0)) == 0) {
-+        var = L"SYSTEMROOT",
-+        len = GetEnvironmentVariableW(var, NULL, 0);
-+    }
-+
-+    if (len != 0) {
-+        int sz;
-+
-+        val = _alloca(len * sizeof(WCHAR));
-+
-+        if (GetEnvironmentVariableW(var, val, len) < len
-+            && (sz = WideCharToMultiByte(CP_UTF8, 0, val, -1, NULL, 0,
-+                                         NULL, NULL)) != 0) {
-+            s = _alloca(sz);
-+            if (WideCharToMultiByte(CP_UTF8, 0, val, -1, s, sz,
-+                                    NULL, NULL) == 0)
-+                s = NULL;
-+        }
-+    }
-+#else
-+    if (OPENSSL_issetugid() != 0) {
-+        use_randfile = 0;
-+    } else {
-+        s = getenv("RANDFILE");
-+        if (s == NULL || *s == '\0') {
-+            use_randfile = 0;
-+            s = getenv("HOME");
-+        }
-+    }
-+#endif
-+#ifdef DEFAULT_HOME
-+    if (!use_randfile && s == NULL) {
-+        s = DEFAULT_HOME;
-+    }
-+#endif
-+    if (s != NULL && *s) {
-+        size_t len = strlen(s);
-+
-+        if (use_randfile && len + 1 < size) {
-+            if (OPENSSL_strlcpy(buf, s, size) >= size)
-+                return NULL;
-+        } else if (len + strlen(RFILE) + 2 < size) {
-+            OPENSSL_strlcpy(buf, s, size);
-+#ifndef OPENSSL_SYS_VMS
-+            OPENSSL_strlcat(buf, "/", size);
-+#endif
-+            OPENSSL_strlcat(buf, RFILE, size);
-+        }
-+    } else {
-+        buf[0] = '\0';      /* no file name */
-+    }
-+
-+#ifdef __OpenBSD__
-+    /*
-+     * given that all random loads just fail if the file can't be seen on a
-+     * stat, we stat the file we're returning, if it fails, use /dev/arandom
-+     * instead. this allows the user to use their own source for good random
-+     * data, but defaults to something hopefully decent if that isn't
-+     * available.
-+     */
-+
-+    if (!buf[0] || stat(buf, &sb) == -1)
-+        if (OPENSSL_strlcpy(buf, "/dev/arandom", size) >= size) {
-+            return NULL;
-+        }
-+#endif
-+    return buf[0] ? buf : NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/build.info
-new file mode 100644
-index 0000000..47a3fd0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        rc2_ecb.c rc2_skey.c rc2_cbc.c rc2cfb64.c rc2ofb64.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_cbc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_cbc.c
-new file mode 100644
-index 0000000..2b59353
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_cbc.c
-@@ -0,0 +1,179 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc2_locl.h"
-+
-+void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
-+                     RC2_KEY *ks, unsigned char *iv, int encrypt)
-+{
-+    register unsigned long tin0, tin1;
-+    register unsigned long tout0, tout1, xor0, xor1;
-+    register long l = length;
-+    unsigned long tin[2];
-+
-+    if (encrypt) {
-+        c2l(iv, tout0);
-+        c2l(iv, tout1);
-+        iv -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            c2l(in, tin0);
-+            c2l(in, tin1);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            RC2_encrypt(tin, ks);
-+            tout0 = tin[0];
-+            l2c(tout0, out);
-+            tout1 = tin[1];
-+            l2c(tout1, out);
-+        }
-+        if (l != -8) {
-+            c2ln(in, tin0, tin1, l + 8);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            RC2_encrypt(tin, ks);
-+            tout0 = tin[0];
-+            l2c(tout0, out);
-+            tout1 = tin[1];
-+            l2c(tout1, out);
-+        }
-+        l2c(tout0, iv);
-+        l2c(tout1, iv);
-+    } else {
-+        c2l(iv, xor0);
-+        c2l(iv, xor1);
-+        iv -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            c2l(in, tin0);
-+            tin[0] = tin0;
-+            c2l(in, tin1);
-+            tin[1] = tin1;
-+            RC2_decrypt(tin, ks);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2c(tout0, out);
-+            l2c(tout1, out);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        if (l != -8) {
-+            c2l(in, tin0);
-+            tin[0] = tin0;
-+            c2l(in, tin1);
-+            tin[1] = tin1;
-+            RC2_decrypt(tin, ks);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2cn(tout0, tout1, out, l + 8);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        l2c(xor0, iv);
-+        l2c(xor1, iv);
-+    }
-+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
-+    tin[0] = tin[1] = 0;
-+}
-+
-+void RC2_encrypt(unsigned long *d, RC2_KEY *key)
-+{
-+    int i, n;
-+    register RC2_INT *p0, *p1;
-+    register RC2_INT x0, x1, x2, x3, t;
-+    unsigned long l;
-+
-+    l = d[0];
-+    x0 = (RC2_INT) l & 0xffff;
-+    x1 = (RC2_INT) (l >> 16L);
-+    l = d[1];
-+    x2 = (RC2_INT) l & 0xffff;
-+    x3 = (RC2_INT) (l >> 16L);
-+
-+    n = 3;
-+    i = 5;
-+
-+    p0 = p1 = &(key->data[0]);
-+    for (;;) {
-+        t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff;
-+        x0 = (t << 1) | (t >> 15);
-+        t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff;
-+        x1 = (t << 2) | (t >> 14);
-+        t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff;
-+        x2 = (t << 3) | (t >> 13);
-+        t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff;
-+        x3 = (t << 5) | (t >> 11);
-+
-+        if (--i == 0) {
-+            if (--n == 0)
-+                break;
-+            i = (n == 2) ? 6 : 5;
-+
-+            x0 += p1[x3 & 0x3f];
-+            x1 += p1[x0 & 0x3f];
-+            x2 += p1[x1 & 0x3f];
-+            x3 += p1[x2 & 0x3f];
-+        }
-+    }
-+
-+    d[0] =
-+        (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L);
-+    d[1] =
-+        (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L);
-+}
-+
-+void RC2_decrypt(unsigned long *d, RC2_KEY *key)
-+{
-+    int i, n;
-+    register RC2_INT *p0, *p1;
-+    register RC2_INT x0, x1, x2, x3, t;
-+    unsigned long l;
-+
-+    l = d[0];
-+    x0 = (RC2_INT) l & 0xffff;
-+    x1 = (RC2_INT) (l >> 16L);
-+    l = d[1];
-+    x2 = (RC2_INT) l & 0xffff;
-+    x3 = (RC2_INT) (l >> 16L);
-+
-+    n = 3;
-+    i = 5;
-+
-+    p0 = &(key->data[63]);
-+    p1 = &(key->data[0]);
-+    for (;;) {
-+        t = ((x3 << 11) | (x3 >> 5)) & 0xffff;
-+        x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff;
-+        t = ((x2 << 13) | (x2 >> 3)) & 0xffff;
-+        x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff;
-+        t = ((x1 << 14) | (x1 >> 2)) & 0xffff;
-+        x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff;
-+        t = ((x0 << 15) | (x0 >> 1)) & 0xffff;
-+        x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff;
-+
-+        if (--i == 0) {
-+            if (--n == 0)
-+                break;
-+            i = (n == 2) ? 6 : 5;
-+
-+            x3 = (x3 - p1[x2 & 0x3f]) & 0xffff;
-+            x2 = (x2 - p1[x1 & 0x3f]) & 0xffff;
-+            x1 = (x1 - p1[x0 & 0x3f]) & 0xffff;
-+            x0 = (x0 - p1[x3 & 0x3f]) & 0xffff;
-+        }
-+    }
-+
-+    d[0] =
-+        (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L);
-+    d[1] =
-+        (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_ecb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_ecb.c
-new file mode 100644
-index 0000000..b87931f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_ecb.c
-@@ -0,0 +1,41 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc2_locl.h"
-+#include 
-+
-+/*-
-+ * RC2 as implemented frm a posting from
-+ * Newsgroups: sci.crypt
-+ * Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann)
-+ * Subject: Specification for Ron Rivests Cipher No.2
-+ * Message-ID: <4fk39f$f70@net.auckland.ac.nz>
-+ * Date: 11 Feb 1996 06:45:03 GMT
-+ */
-+
-+void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *ks,
-+                     int encrypt)
-+{
-+    unsigned long l, d[2];
-+
-+    c2l(in, l);
-+    d[0] = l;
-+    c2l(in, l);
-+    d[1] = l;
-+    if (encrypt)
-+        RC2_encrypt(d, ks);
-+    else
-+        RC2_decrypt(d, ks);
-+    l = d[0];
-+    l2c(l, out);
-+    l = d[1];
-+    l2c(l, out);
-+    l = d[0] = d[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_locl.h
-new file mode 100644
-index 0000000..a9a57d6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_locl.h
-@@ -0,0 +1,106 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#undef c2l
-+#define c2l(c,l)        (l =((unsigned long)(*((c)++)))    , \
-+                         l|=((unsigned long)(*((c)++)))<< 8L, \
-+                         l|=((unsigned long)(*((c)++)))<<16L, \
-+                         l|=((unsigned long)(*((c)++)))<<24L)
-+
-+/* NOTE - c is not incremented as per c2l */
-+#undef c2ln
-+#define c2ln(c,l1,l2,n) { \
-+                        c+=n; \
-+                        l1=l2=0; \
-+                        switch (n) { \
-+                        case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
-+                        case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
-+                        case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
-+                        case 5: l2|=((unsigned long)(*(--(c))));     \
-+                        case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
-+                        case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
-+                        case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
-+                        case 1: l1|=((unsigned long)(*(--(c))));     \
-+                                } \
-+                        }
-+
-+#undef l2c
-+#define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
-+
-+/* NOTE - c is not incremented as per l2c */
-+#undef l2cn
-+#define l2cn(l1,l2,c,n) { \
-+                        c+=n; \
-+                        switch (n) { \
-+                        case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
-+                        case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
-+                        case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
-+                        case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
-+                        case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
-+                        case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
-+                        case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
-+                        case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
-+                                } \
-+                        }
-+
-+/* NOTE - c is not incremented as per n2l */
-+#define n2ln(c,l1,l2,n) { \
-+                        c+=n; \
-+                        l1=l2=0; \
-+                        switch (n) { \
-+                        case 8: l2 =((unsigned long)(*(--(c))))    ; \
-+                        case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
-+                        case 6: l2|=((unsigned long)(*(--(c))))<<16; \
-+                        case 5: l2|=((unsigned long)(*(--(c))))<<24; \
-+                        case 4: l1 =((unsigned long)(*(--(c))))    ; \
-+                        case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
-+                        case 2: l1|=((unsigned long)(*(--(c))))<<16; \
-+                        case 1: l1|=((unsigned long)(*(--(c))))<<24; \
-+                                } \
-+                        }
-+
-+/* NOTE - c is not incremented as per l2n */
-+#define l2nn(l1,l2,c,n) { \
-+                        c+=n; \
-+                        switch (n) { \
-+                        case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
-+                        case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
-+                        case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
-+                        case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
-+                        case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
-+                        case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
-+                        case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
-+                        case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
-+                                } \
-+                        }
-+
-+#undef n2l
-+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
-+                         l|=((unsigned long)(*((c)++)))<<16L, \
-+                         l|=((unsigned long)(*((c)++)))<< 8L, \
-+                         l|=((unsigned long)(*((c)++))))
-+
-+#undef l2n
-+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)     )&0xff))
-+
-+#define C_RC2(n) \
-+        t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \
-+        x0=(t<<1)|(t>>15); \
-+        t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \
-+        x1=(t<<2)|(t>>14); \
-+        t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \
-+        x2=(t<<3)|(t>>13); \
-+        t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \
-+        x3=(t<<5)|(t>>11);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_skey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_skey.c
-new file mode 100644
-index 0000000..55d8ba3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2_skey.c
-@@ -0,0 +1,98 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc2_locl.h"
-+
-+static const unsigned char key_table[256] = {
-+    0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79,
-+    0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
-+    0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5,
-+    0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
-+    0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22,
-+    0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
-+    0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f,
-+    0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
-+    0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b,
-+    0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
-+    0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde,
-+    0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
-+    0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e,
-+    0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
-+    0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85,
-+    0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
-+    0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10,
-+    0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
-+    0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b,
-+    0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
-+    0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68,
-+    0xfe, 0x7f, 0xc1, 0xad,
-+};
-+
-+#if defined(_MSC_VER) && defined(_ARM_)
-+# pragma optimize("g",off)
-+#endif
-+
-+/*
-+ * It has come to my attention that there are 2 versions of the RC2 key
-+ * schedule.  One which is normal, and anther which has a hook to use a
-+ * reduced key length. BSAFE uses the 'retarded' version.  What I previously
-+ * shipped is the same as specifying 1024 for the 'bits' parameter.  Bsafe
-+ * uses a version where the bits parameter is the same as len*8
-+ */
-+void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
-+{
-+    int i, j;
-+    unsigned char *k;
-+    RC2_INT *ki;
-+    unsigned int c, d;
-+
-+    k = (unsigned char *)&(key->data[0]);
-+    *k = 0;                     /* for if there is a zero length key */
-+
-+    if (len > 128)
-+        len = 128;
-+    if (bits <= 0)
-+        bits = 1024;
-+    if (bits > 1024)
-+        bits = 1024;
-+
-+    for (i = 0; i < len; i++)
-+        k[i] = data[i];
-+
-+    /* expand table */
-+    d = k[len - 1];
-+    j = 0;
-+    for (i = len; i < 128; i++, j++) {
-+        d = key_table[(k[j] + d) & 0xff];
-+        k[i] = d;
-+    }
-+
-+    /* hmm.... key reduction to 'bits' bits */
-+
-+    j = (bits + 7) >> 3;
-+    i = 128 - j;
-+    c = (0xff >> (-bits & 0x07));
-+
-+    d = key_table[k[i] & c];
-+    k[i] = d;
-+    while (i--) {
-+        d = key_table[k[i + j] ^ d];
-+        k[i] = d;
-+    }
-+
-+    /* copy from bytes into RC2_INT's */
-+    ki = &(key->data[63]);
-+    for (i = 127; i >= 0; i -= 2)
-+        *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff;
-+}
-+
-+#if defined(_MSC_VER)
-+# pragma optimize("",on)
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2cfb64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2cfb64.c
-new file mode 100644
-index 0000000..e11093d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2cfb64.c
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc2_locl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit cfb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+
-+void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
-+                       long length, RC2_KEY *schedule, unsigned char *ivec,
-+                       int *num, int encrypt)
-+{
-+    register unsigned long v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    unsigned long ti[2];
-+    unsigned char *iv, c, cc;
-+
-+    iv = (unsigned char *)ivec;
-+    if (encrypt) {
-+        while (l--) {
-+            if (n == 0) {
-+                c2l(iv, v0);
-+                ti[0] = v0;
-+                c2l(iv, v1);
-+                ti[1] = v1;
-+                RC2_encrypt((unsigned long *)ti, schedule);
-+                iv = (unsigned char *)ivec;
-+                t = ti[0];
-+                l2c(t, iv);
-+                t = ti[1];
-+                l2c(t, iv);
-+                iv = (unsigned char *)ivec;
-+            }
-+            c = *(in++) ^ iv[n];
-+            *(out++) = c;
-+            iv[n] = c;
-+            n = (n + 1) & 0x07;
-+        }
-+    } else {
-+        while (l--) {
-+            if (n == 0) {
-+                c2l(iv, v0);
-+                ti[0] = v0;
-+                c2l(iv, v1);
-+                ti[1] = v1;
-+                RC2_encrypt((unsigned long *)ti, schedule);
-+                iv = (unsigned char *)ivec;
-+                t = ti[0];
-+                l2c(t, iv);
-+                t = ti[1];
-+                l2c(t, iv);
-+                iv = (unsigned char *)ivec;
-+            }
-+            cc = *(in++);
-+            c = iv[n];
-+            iv[n] = cc;
-+            *(out++) = c ^ cc;
-+            n = (n + 1) & 0x07;
-+        }
-+    }
-+    v0 = v1 = ti[0] = ti[1] = t = c = cc = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2ofb64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2ofb64.c
-new file mode 100644
-index 0000000..d610278
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/rc2ofb64.c
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc2_locl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit ofb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
-+                       long length, RC2_KEY *schedule, unsigned char *ivec,
-+                       int *num)
-+{
-+    register unsigned long v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    unsigned char d[8];
-+    register char *dp;
-+    unsigned long ti[2];
-+    unsigned char *iv;
-+    int save = 0;
-+
-+    iv = (unsigned char *)ivec;
-+    c2l(iv, v0);
-+    c2l(iv, v1);
-+    ti[0] = v0;
-+    ti[1] = v1;
-+    dp = (char *)d;
-+    l2c(v0, dp);
-+    l2c(v1, dp);
-+    while (l--) {
-+        if (n == 0) {
-+            RC2_encrypt((unsigned long *)ti, schedule);
-+            dp = (char *)d;
-+            t = ti[0];
-+            l2c(t, dp);
-+            t = ti[1];
-+            l2c(t, dp);
-+            save++;
-+        }
-+        *(out++) = *(in++) ^ d[n];
-+        n = (n + 1) & 0x07;
-+    }
-+    if (save) {
-+        v0 = ti[0];
-+        v1 = ti[1];
-+        iv = (unsigned char *)ivec;
-+        l2c(v0, iv);
-+        l2c(v1, iv);
-+    }
-+    t = v0 = v1 = ti[0] = ti[1] = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/tab.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/tab.c
-new file mode 100644
-index 0000000..bc95dc4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc2/tab.c
-@@ -0,0 +1,93 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+unsigned char ebits_to_num[256] = {
-+    0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a,
-+    0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0,
-+    0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b,
-+    0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a,
-+    0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda,
-+    0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36,
-+    0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8,
-+    0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c,
-+    0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17,
-+    0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60,
-+    0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72,
-+    0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa,
-+    0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd,
-+    0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e,
-+    0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b,
-+    0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf,
-+    0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77,
-+    0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6,
-+    0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3,
-+    0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3,
-+    0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e,
-+    0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c,
-+    0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d,
-+    0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2,
-+    0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46,
-+    0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5,
-+    0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97,
-+    0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5,
-+    0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef,
-+    0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f,
-+    0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf,
-+    0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab,
-+};
-+
-+unsigned char num_to_ebits[256] = {
-+    0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d,
-+    0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5,
-+    0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47,
-+    0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5,
-+    0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c,
-+    0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef,
-+    0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89,
-+    0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d,
-+    0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8,
-+    0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb,
-+    0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab,
-+    0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d,
-+    0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46,
-+    0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3,
-+    0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87,
-+    0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61,
-+    0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6,
-+    0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1,
-+    0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7,
-+    0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21,
-+    0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0,
-+    0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42,
-+    0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a,
-+    0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f,
-+    0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5,
-+    0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7,
-+    0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90,
-+    0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15,
-+    0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b,
-+    0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7,
-+    0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18,
-+    0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd,
-+};
-+
-+main()
-+{
-+    int i, j;
-+
-+    for (i = 0; i < 256; i++) {
-+        for (j = 0; j < 256; j++)
-+            if (ebits_to_num[j] == i) {
-+                printf("0x%02x,", j);
-+                break;
-+            }
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-586.pl
-new file mode 100644
-index 0000000..7d6f97c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-586.pl
-@@ -0,0 +1,428 @@
-+#! /usr/bin/env perl
-+# Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# [Re]written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# At some point it became apparent that the original SSLeay RC4
-+# assembler implementation performs suboptimally on latest IA-32
-+# microarchitectures. After re-tuning performance has changed as
-+# following:
-+#
-+# Pentium	-10%
-+# Pentium III	+12%
-+# AMD		+50%(*)
-+# P4		+250%(**)
-+#
-+# (*)	This number is actually a trade-off:-) It's possible to
-+#	achieve	+72%, but at the cost of -48% off PIII performance.
-+#	In other words code performing further 13% faster on AMD
-+#	would perform almost 2 times slower on Intel PIII...
-+#	For reference! This code delivers ~80% of rc4-amd64.pl
-+#	performance on the same Opteron machine.
-+# (**)	This number requires compressed key schedule set up by
-+#	RC4_set_key [see commentary below for further details].
-+#
-+#					
-+
-+# May 2011
-+#
-+# Optimize for Core2 and Westmere [and incidentally Opteron]. Current
-+# performance in cycles per processed byte (less is better) and
-+# improvement relative to previous version of this module is:
-+#
-+# Pentium	10.2			# original numbers
-+# Pentium III	7.8(*)
-+# Intel P4	7.5
-+#
-+# Opteron	6.1/+20%		# new MMX numbers
-+# Core2		5.3/+67%(**)
-+# Westmere	5.1/+94%(**)
-+# Sandy Bridge	5.0/+8%
-+# Atom		12.6/+6%
-+# VIA Nano	6.4/+9%
-+# Ivy Bridge	4.9/±0%
-+# Bulldozer	4.9/+15%
-+#
-+# (*)	PIII can actually deliver 6.6 cycles per byte with MMX code,
-+#	but this specific code performs poorly on Core2. And vice
-+#	versa, below MMX/SSE code delivering 5.8/7.1 on Core2 performs
-+#	poorly on PIII, at 8.0/14.5:-( As PIII is not a "hot" CPU
-+#	[anymore], I chose to discard PIII-specific code path and opt
-+#	for original IALU-only code, which is why MMX/SSE code path
-+#	is guarded by SSE2 bit (see below), not MMX/SSE.
-+# (**)	Performance vs. block size on Core2 and Westmere had a maximum
-+#	at ... 64 bytes block size. And it was quite a maximum, 40-60%
-+#	in comparison to largest 8KB block size. Above improvement
-+#	coefficients are for the largest block size.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"rc4-586.pl",$x86only = $ARGV[$#ARGV] eq "386");
-+
-+$xx="eax";
-+$yy="ebx";
-+$tx="ecx";
-+$ty="edx";
-+$inp="esi";
-+$out="ebp";
-+$dat="edi";
-+
-+sub RC4_loop {
-+  my $i=shift;
-+  my $func = ($i==0)?*mov:*or;
-+
-+	&add	(&LB($yy),&LB($tx));
-+	&mov	($ty,&DWP(0,$dat,$yy,4));
-+	&mov	(&DWP(0,$dat,$yy,4),$tx);
-+	&mov	(&DWP(0,$dat,$xx,4),$ty);
-+	&add	($ty,$tx);
-+	&inc	(&LB($xx));
-+	&and	($ty,0xff);
-+	&ror	($out,8)	if ($i!=0);
-+	if ($i<3) {
-+	  &mov	($tx,&DWP(0,$dat,$xx,4));
-+	} else {
-+	  &mov	($tx,&wparam(3));	# reload [re-biased] out
-+	}
-+	&$func	($out,&DWP(0,$dat,$ty,4));
-+}
-+
-+if ($alt=0) {
-+  # >20% faster on Atom and Sandy Bridge[!], 8% faster on Opteron,
-+  # but ~40% slower on Core2 and Westmere... Attempt to add movz
-+  # brings down Opteron by 25%, Atom and Sandy Bridge by 15%, yet
-+  # on Core2 with movz it's almost 20% slower than below alternative
-+  # code... Yes, it's a total mess...
-+  my @XX=($xx,$out);
-+  $RC4_loop_mmx = sub {		# SSE actually...
-+    my $i=shift;
-+    my $j=$i<=0?0:$i>>1;
-+    my $mm=$i<=0?"mm0":"mm".($i&1);
-+
-+	&add	(&LB($yy),&LB($tx));
-+	&lea	(@XX[1],&DWP(1,@XX[0]));
-+	&pxor	("mm2","mm0")				if ($i==0);
-+	&psllq	("mm1",8)				if ($i==0);
-+	&and	(@XX[1],0xff);
-+	&pxor	("mm0","mm0")				if ($i<=0);
-+	&mov	($ty,&DWP(0,$dat,$yy,4));
-+	&mov	(&DWP(0,$dat,$yy,4),$tx);
-+	&pxor	("mm1","mm2")				if ($i==0);
-+	&mov	(&DWP(0,$dat,$XX[0],4),$ty);
-+	&add	(&LB($ty),&LB($tx));
-+	&movd	(@XX[0],"mm7")				if ($i==0);
-+	&mov	($tx,&DWP(0,$dat,@XX[1],4));
-+	&pxor	("mm1","mm1")				if ($i==1);
-+	&movq	("mm2",&QWP(0,$inp))			if ($i==1);
-+	&movq	(&QWP(-8,(@XX[0],$inp)),"mm1")		if ($i==0);
-+	&pinsrw	($mm,&DWP(0,$dat,$ty,4),$j);
-+
-+	push	(@XX,shift(@XX))			if ($i>=0);
-+  }
-+} else {
-+  # Using pinsrw here improves performane on Intel CPUs by 2-3%, but
-+  # brings down AMD by 7%...
-+  $RC4_loop_mmx = sub {
-+    my $i=shift;
-+
-+	&add	(&LB($yy),&LB($tx));
-+	&psllq	("mm1",8*(($i-1)&7))			if (abs($i)!=1);
-+	&mov	($ty,&DWP(0,$dat,$yy,4));
-+	&mov	(&DWP(0,$dat,$yy,4),$tx);
-+	&mov	(&DWP(0,$dat,$xx,4),$ty);
-+	&inc	($xx);
-+	&add	($ty,$tx);
-+	&movz	($xx,&LB($xx));				# (*)
-+	&movz	($ty,&LB($ty));				# (*)
-+	&pxor	("mm2",$i==1?"mm0":"mm1")		if ($i>=0);
-+	&movq	("mm0",&QWP(0,$inp))			if ($i<=0);
-+	&movq	(&QWP(-8,($out,$inp)),"mm2")		if ($i==0);
-+	&mov	($tx,&DWP(0,$dat,$xx,4));
-+	&movd	($i>0?"mm1":"mm2",&DWP(0,$dat,$ty,4));
-+
-+	# (*)	This is the key to Core2 and Westmere performance.
-+	#	Without movz out-of-order execution logic confuses
-+	#	itself and fails to reorder loads and stores. Problem
-+	#	appears to be fixed in Sandy Bridge...
-+  }
-+}
-+
-+&external_label("OPENSSL_ia32cap_P");
-+
-+# void RC4(RC4_KEY *key,size_t len,const unsigned char *inp,unsigned char *out);
-+&function_begin("RC4");
-+	&mov	($dat,&wparam(0));	# load key schedule pointer
-+	&mov	($ty, &wparam(1));	# load len
-+	&mov	($inp,&wparam(2));	# load inp
-+	&mov	($out,&wparam(3));	# load out
-+
-+	&xor	($xx,$xx);		# avoid partial register stalls
-+	&xor	($yy,$yy);
-+
-+	&cmp	($ty,0);		# safety net
-+	&je	(&label("abort"));
-+
-+	&mov	(&LB($xx),&BP(0,$dat));	# load key->x
-+	&mov	(&LB($yy),&BP(4,$dat));	# load key->y
-+	&add	($dat,8);
-+
-+	&lea	($tx,&DWP(0,$inp,$ty));
-+	&sub	($out,$inp);		# re-bias out
-+	&mov	(&wparam(1),$tx);	# save input+len
-+
-+	&inc	(&LB($xx));
-+
-+	# detect compressed key schedule...
-+	&cmp	(&DWP(256,$dat),-1);
-+	&je	(&label("RC4_CHAR"));
-+
-+	&mov	($tx,&DWP(0,$dat,$xx,4));
-+
-+	&and	($ty,-4);		# how many 4-byte chunks?
-+	&jz	(&label("loop1"));
-+
-+	&mov	(&wparam(3),$out);	# $out as accumulator in these loops
-+					if ($x86only) {
-+	&jmp	(&label("go4loop4"));
-+					} else {
-+	&test	($ty,-8);
-+	&jz	(&label("go4loop4"));
-+
-+	&picmeup($out,"OPENSSL_ia32cap_P");
-+	&bt	(&DWP(0,$out),26);	# check SSE2 bit [could have been MMX]
-+	&jnc	(&label("go4loop4"));
-+
-+	&mov	($out,&wparam(3))	if (!$alt);
-+	&movd	("mm7",&wparam(3))	if ($alt);
-+	&and	($ty,-8);
-+	&lea	($ty,&DWP(-8,$inp,$ty));
-+	&mov	(&DWP(-4,$dat),$ty);	# save input+(len/8)*8-8
-+
-+	&$RC4_loop_mmx(-1);
-+	&jmp(&label("loop_mmx_enter"));
-+
-+	&set_label("loop_mmx",16);
-+		&$RC4_loop_mmx(0);
-+	&set_label("loop_mmx_enter");
-+		for 	($i=1;$i<8;$i++) { &$RC4_loop_mmx($i); }
-+		&mov	($ty,$yy);
-+		&xor	($yy,$yy);		# this is second key to Core2
-+		&mov	(&LB($yy),&LB($ty));	# and Westmere performance...
-+		&cmp	($inp,&DWP(-4,$dat));
-+		&lea	($inp,&DWP(8,$inp));
-+	&jb	(&label("loop_mmx"));
-+
-+    if ($alt) {
-+	&movd	($out,"mm7");
-+	&pxor	("mm2","mm0");
-+	&psllq	("mm1",8);
-+	&pxor	("mm1","mm2");
-+	&movq	(&QWP(-8,$out,$inp),"mm1");
-+    } else {
-+	&psllq	("mm1",56);
-+	&pxor	("mm2","mm1");
-+	&movq	(&QWP(-8,$out,$inp),"mm2");
-+    }
-+	&emms	();
-+
-+	&cmp	($inp,&wparam(1));	# compare to input+len
-+	&je	(&label("done"));
-+	&jmp	(&label("loop1"));
-+					}
-+
-+&set_label("go4loop4",16);
-+	&lea	($ty,&DWP(-4,$inp,$ty));
-+	&mov	(&wparam(2),$ty);	# save input+(len/4)*4-4
-+
-+	&set_label("loop4");
-+		for ($i=0;$i<4;$i++) { RC4_loop($i); }
-+		&ror	($out,8);
-+		&xor	($out,&DWP(0,$inp));
-+		&cmp	($inp,&wparam(2));	# compare to input+(len/4)*4-4
-+		&mov	(&DWP(0,$tx,$inp),$out);# $tx holds re-biased out here
-+		&lea	($inp,&DWP(4,$inp));
-+		&mov	($tx,&DWP(0,$dat,$xx,4));
-+	&jb	(&label("loop4"));
-+
-+	&cmp	($inp,&wparam(1));	# compare to input+len
-+	&je	(&label("done"));
-+	&mov	($out,&wparam(3));	# restore $out
-+
-+	&set_label("loop1",16);
-+		&add	(&LB($yy),&LB($tx));
-+		&mov	($ty,&DWP(0,$dat,$yy,4));
-+		&mov	(&DWP(0,$dat,$yy,4),$tx);
-+		&mov	(&DWP(0,$dat,$xx,4),$ty);
-+		&add	($ty,$tx);
-+		&inc	(&LB($xx));
-+		&and	($ty,0xff);
-+		&mov	($ty,&DWP(0,$dat,$ty,4));
-+		&xor	(&LB($ty),&BP(0,$inp));
-+		&lea	($inp,&DWP(1,$inp));
-+		&mov	($tx,&DWP(0,$dat,$xx,4));
-+		&cmp	($inp,&wparam(1));	# compare to input+len
-+		&mov	(&BP(-1,$out,$inp),&LB($ty));
-+	&jb	(&label("loop1"));
-+
-+	&jmp	(&label("done"));
-+
-+# this is essentially Intel P4 specific codepath...
-+&set_label("RC4_CHAR",16);
-+	&movz	($tx,&BP(0,$dat,$xx));
-+	# strangely enough unrolled loop performs over 20% slower...
-+	&set_label("cloop1");
-+		&add	(&LB($yy),&LB($tx));
-+		&movz	($ty,&BP(0,$dat,$yy));
-+		&mov	(&BP(0,$dat,$yy),&LB($tx));
-+		&mov	(&BP(0,$dat,$xx),&LB($ty));
-+		&add	(&LB($ty),&LB($tx));
-+		&movz	($ty,&BP(0,$dat,$ty));
-+		&add	(&LB($xx),1);
-+		&xor	(&LB($ty),&BP(0,$inp));
-+		&lea	($inp,&DWP(1,$inp));
-+		&movz	($tx,&BP(0,$dat,$xx));
-+		&cmp	($inp,&wparam(1));
-+		&mov	(&BP(-1,$out,$inp),&LB($ty));
-+	&jb	(&label("cloop1"));
-+
-+&set_label("done");
-+	&dec	(&LB($xx));
-+	&mov	(&DWP(-4,$dat),$yy);		# save key->y
-+	&mov	(&BP(-8,$dat),&LB($xx));	# save key->x
-+&set_label("abort");
-+&function_end("RC4");
-+
-+########################################################################
-+
-+$inp="esi";
-+$out="edi";
-+$idi="ebp";
-+$ido="ecx";
-+$idx="edx";
-+
-+# void RC4_set_key(RC4_KEY *key,int len,const unsigned char *data);
-+&function_begin("RC4_set_key");
-+	&mov	($out,&wparam(0));		# load key
-+	&mov	($idi,&wparam(1));		# load len
-+	&mov	($inp,&wparam(2));		# load data
-+	&picmeup($idx,"OPENSSL_ia32cap_P");
-+
-+	&lea	($out,&DWP(2*4,$out));		# &key->data
-+	&lea	($inp,&DWP(0,$inp,$idi));	# $inp to point at the end
-+	&neg	($idi);
-+	&xor	("eax","eax");
-+	&mov	(&DWP(-4,$out),$idi);		# borrow key->y
-+
-+	&bt	(&DWP(0,$idx),20);		# check for bit#20
-+	&jc	(&label("c1stloop"));
-+
-+&set_label("w1stloop",16);
-+	&mov	(&DWP(0,$out,"eax",4),"eax");	# key->data[i]=i;
-+	&add	(&LB("eax"),1);			# i++;
-+	&jnc	(&label("w1stloop"));
-+
-+	&xor	($ido,$ido);
-+	&xor	($idx,$idx);
-+
-+&set_label("w2ndloop",16);
-+	&mov	("eax",&DWP(0,$out,$ido,4));
-+	&add	(&LB($idx),&BP(0,$inp,$idi));
-+	&add	(&LB($idx),&LB("eax"));
-+	&add	($idi,1);
-+	&mov	("ebx",&DWP(0,$out,$idx,4));
-+	&jnz	(&label("wnowrap"));
-+	  &mov	($idi,&DWP(-4,$out));
-+	&set_label("wnowrap");
-+	&mov	(&DWP(0,$out,$idx,4),"eax");
-+	&mov	(&DWP(0,$out,$ido,4),"ebx");
-+	&add	(&LB($ido),1);
-+	&jnc	(&label("w2ndloop"));
-+&jmp	(&label("exit"));
-+
-+# Unlike all other x86 [and x86_64] implementations, Intel P4 core
-+# [including EM64T] was found to perform poorly with above "32-bit" key
-+# schedule, a.k.a. RC4_INT. Performance improvement for IA-32 hand-coded
-+# assembler turned out to be 3.5x if re-coded for compressed 8-bit one,
-+# a.k.a. RC4_CHAR! It's however inappropriate to just switch to 8-bit
-+# schedule for x86[_64], because non-P4 implementations suffer from
-+# significant performance losses then, e.g. PIII exhibits >2x
-+# deterioration, and so does Opteron. In order to assure optimal
-+# all-round performance, we detect P4 at run-time and set up compressed
-+# key schedule, which is recognized by RC4 procedure.
-+
-+&set_label("c1stloop",16);
-+	&mov	(&BP(0,$out,"eax"),&LB("eax"));	# key->data[i]=i;
-+	&add	(&LB("eax"),1);			# i++;
-+	&jnc	(&label("c1stloop"));
-+
-+	&xor	($ido,$ido);
-+	&xor	($idx,$idx);
-+	&xor	("ebx","ebx");
-+
-+&set_label("c2ndloop",16);
-+	&mov	(&LB("eax"),&BP(0,$out,$ido));
-+	&add	(&LB($idx),&BP(0,$inp,$idi));
-+	&add	(&LB($idx),&LB("eax"));
-+	&add	($idi,1);
-+	&mov	(&LB("ebx"),&BP(0,$out,$idx));
-+	&jnz	(&label("cnowrap"));
-+	  &mov	($idi,&DWP(-4,$out));
-+	&set_label("cnowrap");
-+	&mov	(&BP(0,$out,$idx),&LB("eax"));
-+	&mov	(&BP(0,$out,$ido),&LB("ebx"));
-+	&add	(&LB($ido),1);
-+	&jnc	(&label("c2ndloop"));
-+
-+	&mov	(&DWP(256,$out),-1);		# mark schedule as compressed
-+
-+&set_label("exit");
-+	&xor	("eax","eax");
-+	&mov	(&DWP(-8,$out),"eax");		# key->x=0;
-+	&mov	(&DWP(-4,$out),"eax");		# key->y=0;
-+&function_end("RC4_set_key");
-+
-+# const char *RC4_options(void);
-+&function_begin_B("RC4_options");
-+	&call	(&label("pic_point"));
-+&set_label("pic_point");
-+	&blindpop("eax");
-+	&lea	("eax",&DWP(&label("opts")."-".&label("pic_point"),"eax"));
-+	&picmeup("edx","OPENSSL_ia32cap_P");
-+	&mov	("edx",&DWP(0,"edx"));
-+	&bt	("edx",20);
-+	&jc	(&label("1xchar"));
-+	&bt	("edx",26);
-+	&jnc	(&label("ret"));
-+	&add	("eax",25);
-+	&ret	();
-+&set_label("1xchar");
-+	&add	("eax",12);
-+&set_label("ret");
-+	&ret	();
-+&set_label("opts",64);
-+&asciz	("rc4(4x,int)");
-+&asciz	("rc4(1x,char)");
-+&asciz	("rc4(8x,mmx)");
-+&asciz	("RC4 for x86, CRYPTOGAMS by ");
-+&align	(64);
-+&function_end_B("RC4_options");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-c64xplus.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-c64xplus.pl
-new file mode 100644
-index 0000000..daed75c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-c64xplus.pl
-@@ -0,0 +1,190 @@
-+#! /usr/bin/env perl
-+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# RC4 for C64x+.
-+#
-+# April 2014
-+#
-+# RC4 subroutine processes one byte in 7.0 cycles, which is 3x faster
-+# than TI CGT-generated code. Loop is scheduled in such way that
-+# there is only one reference to memory in each cycle. This is done
-+# to avoid L1D memory banking conflicts, see SPRU871 TI publication
-+# for further details. Otherwise it should be possible to schedule
-+# the loop for iteration interval of 6...
-+
-+($KEY,$LEN,$INP,$OUT)=("A4","B4","A6","B6");
-+
-+($KEYA,$XX,$TY,$xx,$ONE,$ret)=map("A$_",(5,7,8,9,1,2));
-+($KEYB,$YY,$TX,$tx,$SUM,$dat)=map("B$_",(5,7,8,9,1,2));
-+
-+$code.=<<___;
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.nocmp
-+	.asg	RC4,_RC4
-+	.asg	RC4_set_key,_RC4_set_key
-+	.asg	RC4_options,_RC4_options
-+	.endif
-+
-+	.global	_RC4
-+	.align	16
-+_RC4:
-+	.asmfunc
-+	MV	$LEN,B0
-+  [!B0]	BNOP	B3			; if (len==0) return;
-+||[B0]	ADD	$KEY,2,$KEYA
-+||[B0]	ADD	$KEY,2,$KEYB
-+  [B0]	MVK	1,$ONE
-+||[B0]	LDBU	*${KEYA}[-2],$XX	; key->x
-+  [B0]	LDBU	*${KEYB}[-1],$YY	; key->y
-+||	NOP	4
-+
-+	ADD4	$ONE,$XX,$XX
-+	LDBU	*${KEYA}[$XX],$TX
-+||	MVC	$LEN,ILC
-+	NOP	4
-+;;==================================================
-+	SPLOOP	7
-+||	ADD4	$TX,$YY,$YY
-+
-+	LDBU	*${KEYB}[$YY],$TY
-+||	MVD	$XX,$xx
-+||	ADD4	$ONE,$XX,$XX
-+	LDBU	*${KEYA}[$XX],$tx
-+	CMPEQ	$YY,$XX,B0
-+||	NOP	3
-+	STB	$TX,*${KEYB}[$YY]
-+||[B0]	ADD4	$TX,$YY,$YY
-+	STB	$TY,*${KEYA}[$xx]
-+||[!B0]	ADD4	$tx,$YY,$YY
-+||[!B0]	MVD	$tx,$TX
-+	ADD4	$TY,$TX,$SUM		; [0,0] $TX is not replaced by $tx yet!
-+||	NOP	2
-+	LDBU	*$INP++,$dat
-+||	NOP	2
-+	LDBU	*${KEYB}[$SUM],$ret
-+||	NOP	5
-+	XOR.L	$dat,$ret,$ret
-+	SPKERNEL
-+||	STB	$ret,*$OUT++
-+;;==================================================
-+	SUB4	$XX,$ONE,$XX
-+||	NOP	5
-+	STB	$XX,*${KEYA}[-2]	; key->x
-+||	SUB4	$YY,$TX,$YY
-+||	BNOP	B3	
-+	STB	$YY,*${KEYB}[-1]	; key->y
-+||	NOP	5
-+	.endasmfunc
-+
-+	.global	_RC4_set_key
-+	.align	16
-+_RC4_set_key:
-+	.asmfunc
-+	.if	.BIG_ENDIAN
-+	MVK	0x00000404,$ONE
-+||	MVK	0x00000203,B0
-+	MVKH	0x04040000,$ONE
-+||	MVKH	0x00010000,B0
-+	.else
-+	MVK	0x00000404,$ONE
-+||	MVK	0x00000100,B0
-+	MVKH	0x04040000,$ONE
-+||	MVKH	0x03020000,B0
-+	.endif
-+	ADD	$KEY,2,$KEYA
-+||	ADD	$KEY,2,$KEYB
-+||	ADD	$INP,$LEN,$ret		; end of input
-+	LDBU	*${INP}++,$dat
-+||	MVK	0,$TX
-+	STH	$TX,*${KEY}++		; key->x=key->y=0
-+||	MV	B0,A0
-+||	MVK	64-4,B0
-+
-+;;==================================================
-+	SPLOOPD	1
-+||	MVC	B0,ILC
-+
-+	STNW	A0,*${KEY}++
-+||	ADD4	$ONE,A0,A0
-+	SPKERNEL
-+;;==================================================
-+
-+	MVK	0,$YY
-+||	MVK	0,$XX
-+	MVK	1,$ONE
-+||	MVK	256-1,B0
-+
-+;;==================================================
-+	SPLOOPD	8
-+||	MVC	B0,ILC
-+
-+	ADD4	$dat,$YY,$YY
-+||	CMPEQ	$INP,$ret,A0		; end of input?
-+	LDBU	*${KEYB}[$YY],$TY
-+||	MVD	$XX,$xx
-+||	ADD4	$ONE,$XX,$XX
-+	LDBU	*${KEYA}[$XX],$tx
-+||[A0]	SUB	$INP,$LEN,$INP		; rewind
-+	LDBU	*${INP}++,$dat
-+||	CMPEQ	$YY,$XX,B0
-+||	NOP	3
-+	STB	$TX,*${KEYB}[$YY]
-+||[B0]	ADD4	$TX,$YY,$YY
-+	STB	$TY,*${KEYA}[$xx]
-+||[!B0]	ADD4	$tx,$YY,$YY
-+||[!B0]	MV	$tx,$TX
-+	SPKERNEL
-+;;==================================================
-+
-+	BNOP	B3,5
-+	.endasmfunc
-+
-+	.global	_RC4_options
-+	.align	16
-+_RC4_options:
-+_rc4_options:
-+	.asmfunc
-+	BNOP	B3,1
-+	ADDKPC	_rc4_options,B4
-+	.if	__TI_EABI__
-+	MVKL	\$PCR_OFFSET(rc4_options,_rc4_options),A4
-+	MVKH	\$PCR_OFFSET(rc4_options,_rc4_options),A4
-+	.else
-+	MVKL	(rc4_options-_rc4_options),A4
-+	MVKH	(rc4_options-_rc4_options),A4
-+	.endif
-+	ADD	B4,A4,A4
-+	.endasmfunc
-+
-+	.if	__TI_EABI__
-+	.sect	".text:rc4_options.const"
-+	.else
-+	.sect	".const:rc4_options"
-+	.endif
-+	.align	4
-+rc4_options:
-+	.cstring "rc4(sploop,char)"
-+	.cstring "RC4 for C64+, CRYPTOGAMS by "
-+	.align	4
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-ia64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-ia64.pl
-new file mode 100644
-index 0000000..5e8f5f5
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-ia64.pl
-@@ -0,0 +1,767 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by David Mosberger  based on the
-+# Itanium optimized Crypto code which was released by HP Labs at
-+# http://www.hpl.hp.com/research/linux/crypto/.
-+#
-+# Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
-+#
-+# Permission is hereby granted, free of charge, to any person obtaining
-+# a copy of this software and associated documentation files (the
-+# "Software"), to deal in the Software without restriction, including
-+# without limitation the rights to use, copy, modify, merge, publish,
-+# distribute, sublicense, and/or sell copies of the Software, and to
-+# permit persons to whom the Software is furnished to do so, subject to
-+# the following conditions:
-+#
-+# The above copyright notice and this permission notice shall be
-+# included in all copies or substantial portions of the Software.
-+
-+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
-+
-+
-+
-+# This is a little helper program which generates a software-pipelined
-+# for RC4 encryption.  The basic algorithm looks like this:
-+#
-+#   for (counter = 0; counter < len; ++counter)
-+#     {
-+#       in = inp[counter];
-+#       SI = S[I];
-+#       J = (SI + J) & 0xff;
-+#       SJ = S[J];
-+#       T = (SI + SJ) & 0xff;
-+#       S[I] = SJ, S[J] = SI;
-+#       ST = S[T];
-+#       outp[counter] = in ^ ST;
-+#       I = (I + 1) & 0xff;
-+#     }
-+#
-+# Pipelining this loop isn't easy, because the stores to the S[] array
-+# need to be observed in the right order.  The loop generated by the
-+# code below has the following pipeline diagram:
-+#
-+#      cycle
-+#     | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |17 |
-+# iter
-+#   1: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
-+#   2:             xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
-+#   3:                         xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx
-+#
-+#   where:
-+# 	LDI = load of S[I]
-+# 	LDJ = load of S[J]
-+# 	SWP = swap of S[I] and S[J]
-+# 	LDT = load of S[T]
-+#
-+# Note that in the above diagram, the major trouble-spot is that LDI
-+# of the 2nd iteration is performed BEFORE the SWP of the first
-+# iteration.  Fortunately, this is easy to detect (I of the 1st
-+# iteration will be equal to J of the 2nd iteration) and when this
-+# happens, we simply forward the proper value from the 1st iteration
-+# to the 2nd one.  The proper value in this case is simply the value
-+# of S[I] from the first iteration (thanks to the fact that SWP
-+# simply swaps the contents of S[I] and S[J]).
-+#
-+# Another potential trouble-spot is in cycle 7, where SWP of the 1st
-+# iteration issues at the same time as the LDI of the 3rd iteration.
-+# However, thanks to IA-64 execution semantics, this can be taken
-+# care of simply by placing LDI later in the instruction-group than
-+# SWP.  IA-64 CPUs will automatically forward the value if they
-+# detect that the SWP and LDI are accessing the same memory-location.
-+
-+# The core-loop that can be pipelined then looks like this (annotated
-+# with McKinley/Madison issue port & latency numbers, assuming L1
-+# cache hits for the most part):
-+
-+# operation:	    instruction:		    issue-ports:  latency
-+# ------------------  -----------------------------   ------------- -------
-+
-+# Data = *inp++       ld1 data = [inp], 1             M0-M1         1 cyc     c0
-+#                     shladd Iptr = I, KeyTable, 3    M0-M3, I0, I1 1 cyc
-+# I = (I + 1) & 0xff  padd1 nextI = I, one            M0-M3, I0, I1 3 cyc
-+#                     ;;
-+# SI = S[I]           ld8 SI = [Iptr]                 M0-M1         1 cyc     c1 * after SWAP!
-+#                     ;;
-+#                     cmp.eq.unc pBypass = I, J                                  * after J is valid!
-+# J = SI + J          add J = J, SI                   M0-M3, I0, I1 1 cyc     c2
-+#                     (pBypass) br.cond.spnt Bypass
-+#                     ;;
-+# ---------------------------------------------------------------------------------------
-+# J = J & 0xff        zxt1 J = J                      I0, I1, 1 cyc           c3
-+#                     ;;
-+#                     shladd Jptr = J, KeyTable, 3    M0-M3, I0, I1 1 cyc     c4
-+#                     ;;
-+# SJ = S[J]           ld8 SJ = [Jptr]                 M0-M1         1 cyc     c5
-+#                     ;;
-+# ---------------------------------------------------------------------------------------
-+# T = (SI + SJ)       add T = SI, SJ                  M0-M3, I0, I1 1 cyc     c6
-+#                     ;;
-+# T = T & 0xff        zxt1 T = T                      I0, I1        1 cyc
-+# S[I] = SJ           st8 [Iptr] = SJ                 M2-M3                   c7
-+# S[J] = SI           st8 [Jptr] = SI                 M2-M3
-+#                     ;;
-+#                     shladd Tptr = T, KeyTable, 3    M0-M3, I0, I1 1 cyc     c8
-+#                     ;;
-+# ---------------------------------------------------------------------------------------
-+# T = S[T]            ld8 T = [Tptr]                  M0-M1         1 cyc     c9
-+#                     ;;
-+# data ^= T           xor data = data, T              M0-M3, I0, I1 1 cyc     c10
-+#                     ;;
-+# *out++ = Data ^ T   dep word = word, data, 8, POS   I0, I1        1 cyc     c11
-+#                     ;;
-+# ---------------------------------------------------------------------------------------
-+
-+# There are several points worth making here:
-+
-+#   - Note that due to the bypass/forwarding-path, the first two
-+#     phases of the loop are strangly mingled together.  In
-+#     particular, note that the first stage of the pipeline is
-+#     using the value of "J", as calculated by the second stage.
-+#   - Each bundle-pair will have exactly 6 instructions.
-+#   - Pipelined, the loop can execute in 3 cycles/iteration and
-+#     4 stages.  However, McKinley/Madison can issue "st1" to
-+#     the same bank at a rate of at most one per 4 cycles.  Thus,
-+#     instead of storing each byte, we accumulate them in a word
-+#     and then write them back at once with a single "st8" (this
-+#     implies that the setup code needs to ensure that the output
-+#     buffer is properly aligned, if need be, by encoding the
-+#     first few bytes separately).
-+#   - There is no space for a "br.ctop" instruction.  For this
-+#     reason we can't use module-loop support in IA-64 and have
-+#     to do a traditional, purely software-pipelined loop.
-+#   - We can't replace any of the remaining "add/zxt1" pairs with
-+#     "padd1" because the latency for that instruction is too high
-+#     and would push the loop to the point where more bypasses
-+#     would be needed, which we don't have space for.
-+#   - The above loop runs at around 3.26 cycles/byte, or roughly
-+#     440 MByte/sec on a 1.5GHz Madison.  This is well below the
-+#     system bus bandwidth and hence with judicious use of
-+#     "lfetch" this loop can run at (almost) peak speed even when
-+#     the input and output data reside in memory.  The
-+#     max. latency that can be tolerated is (PREFETCH_DISTANCE *
-+#     L2_LINE_SIZE * 3 cyc), or about 384 cycles assuming (at
-+#     least) 1-ahead prefetching of 128 byte cache-lines.  Note
-+#     that we do NOT prefetch into L1, since that would only
-+#     interfere with the S[] table values stored there.  This is
-+#     acceptable because there is a 10 cycle latency between
-+#     load and first use of the input data.
-+#   - We use a branch to out-of-line bypass-code of cycle-pressure:
-+#     we calculate the next J, check for the need to activate the
-+#     bypass path, and activate the bypass path ALL IN THE SAME
-+#     CYCLE.  If we didn't have these constraints, we could do
-+#     the bypass with a simple conditional move instruction.
-+#     Fortunately, the bypass paths get activated relatively
-+#     infrequently, so the extra branches don't cost all that much
-+#     (about 0.04 cycles/byte, measured on a 16396 byte file with
-+#     random input data).
-+#
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+$phases = 4;		# number of stages/phases in the pipelined-loop
-+$unroll_count = 6;	# number of times we unrolled it
-+$pComI = (1 << 0);
-+$pComJ = (1 << 1);
-+$pComT = (1 << 2);
-+$pOut  = (1 << 3);
-+
-+$NData = 4;
-+$NIP = 3;
-+$NJP = 2;
-+$NI = 2;
-+$NSI = 3;
-+$NSJ = 2;
-+$NT = 2;
-+$NOutWord = 2;
-+
-+#
-+# $threshold is the minimum length before we attempt to use the
-+# big software-pipelined loop.  It MUST be greater-or-equal
-+# to:
-+#  		PHASES * (UNROLL_COUNT + 1) + 7
-+#
-+# The "+ 7" comes from the fact we may have to encode up to
-+#   7 bytes separately before the output pointer is aligned.
-+#
-+$threshold = (3 * ($phases * ($unroll_count + 1)) + 7);
-+
-+sub I {
-+    local *code = shift;
-+    local $format = shift;
-+    $code .= sprintf ("\t\t".$format."\n", @_);
-+}
-+
-+sub P {
-+    local *code = shift;
-+    local $format = shift;
-+    $code .= sprintf ($format."\n", @_);
-+}
-+
-+sub STOP {
-+    local *code = shift;
-+    $code .=<<___;
-+		;;
-+___
-+}
-+
-+sub emit_body {
-+    local *c = shift;
-+    local *bypass = shift;
-+    local ($iteration, $p) = @_;
-+
-+    local $i0 = $iteration;
-+    local $i1 = $iteration - 1;
-+    local $i2 = $iteration - 2;
-+    local $i3 = $iteration - 3;
-+    local $iw0 = ($iteration - 3) / 8;
-+    local $iw1 = ($iteration > 3) ? ($iteration - 4) / 8 : 1;
-+    local $byte_num = ($iteration - 3) % 8;
-+    local $label = $iteration + 1;
-+    local $pAny = ($p & 0xf) == 0xf;
-+    local $pByp = (($p & $pComI) && ($iteration > 0));
-+
-+    $c.=<<___;
-+//////////////////////////////////////////////////
-+___
-+
-+    if (($p & 0xf) == 0) {
-+	$c.="#ifdef HOST_IS_BIG_ENDIAN\n";
-+	&I(\$c,"shr.u	OutWord[%u] = OutWord[%u], 32;;",
-+				$iw1 % $NOutWord, $iw1 % $NOutWord);
-+	$c.="#endif\n";
-+	&I(\$c, "st4 [OutPtr] = OutWord[%u], 4", $iw1 % $NOutWord);
-+	return;
-+    }
-+
-+    # Cycle 0
-+    &I(\$c, "{ .mmi")					      if ($pAny);
-+    &I(\$c, "ld1    Data[%u] = [InPtr], 1", $i0 % $NData)     if ($p & $pComI);
-+    &I(\$c, "padd1  I[%u] = One, I[%u]", $i0 % $NI, $i1 % $NI)if ($p & $pComI);
-+    &I(\$c, "zxt1   J = J")				      if ($p & $pComJ);
-+    &I(\$c, "}")					      if ($pAny);
-+    &I(\$c, "{ .mmi")					      if ($pAny);
-+    &I(\$c, "LKEY   T[%u] = [T[%u]]", $i1 % $NT, $i1 % $NT)   if ($p & $pOut);
-+    &I(\$c, "add    T[%u] = SI[%u], SJ[%u]",
-+       $i0 % $NT, $i2 % $NSI, $i1 % $NSJ)		      if ($p & $pComT);
-+    &I(\$c, "KEYADDR(IPr[%u], I[%u])", $i0 % $NIP, $i1 % $NI) if ($p & $pComI);
-+    &I(\$c, "}")					      if ($pAny);
-+    &STOP(\$c);
-+
-+    # Cycle 1
-+    &I(\$c, "{ .mmi")					      if ($pAny);
-+    &I(\$c, "SKEY   [IPr[%u]] = SJ[%u]", $i2 % $NIP, $i1%$NSJ)if ($p & $pComT);
-+    &I(\$c, "SKEY   [JP[%u]] = SI[%u]", $i1 % $NJP, $i2%$NSI) if ($p & $pComT);
-+    &I(\$c, "zxt1   T[%u] = T[%u]", $i0 % $NT, $i0 % $NT)     if ($p & $pComT);
-+    &I(\$c, "}")					      if ($pAny);
-+    &I(\$c, "{ .mmi")					      if ($pAny);
-+    &I(\$c, "LKEY   SI[%u] = [IPr[%u]]", $i0 % $NSI, $i0%$NIP)if ($p & $pComI);
-+    &I(\$c, "KEYADDR(JP[%u], J)", $i0 % $NJP)		      if ($p & $pComJ);
-+    &I(\$c, "xor    Data[%u] = Data[%u], T[%u]",
-+       $i3 % $NData, $i3 % $NData, $i1 % $NT)		      if ($p & $pOut);
-+    &I(\$c, "}")					      if ($pAny);
-+    &STOP(\$c);
-+
-+    # Cycle 2
-+    &I(\$c, "{ .mmi")					      if ($pAny);
-+    &I(\$c, "LKEY   SJ[%u] = [JP[%u]]", $i0 % $NSJ, $i0%$NJP) if ($p & $pComJ);
-+    &I(\$c, "cmp.eq pBypass, p0 = I[%u], J", $i1 % $NI)	      if ($pByp);
-+    &I(\$c, "dep OutWord[%u] = Data[%u], OutWord[%u], BYTE_POS(%u), 8",
-+       $iw0%$NOutWord, $i3%$NData, $iw1%$NOutWord, $byte_num) if ($p & $pOut);
-+    &I(\$c, "}")					      if ($pAny);
-+    &I(\$c, "{ .mmb")					      if ($pAny);
-+    &I(\$c, "add    J = J, SI[%u]", $i0 % $NSI)		      if ($p & $pComI);
-+    &I(\$c, "KEYADDR(T[%u], T[%u])", $i0 % $NT, $i0 % $NT)    if ($p & $pComT);
-+    &P(\$c, "(pBypass)\tbr.cond.spnt.many .rc4Bypass%u",$label)if ($pByp);
-+    &I(\$c, "}") if ($pAny);
-+    &STOP(\$c);
-+
-+    &P(\$c, ".rc4Resume%u:", $label)			      if ($pByp);
-+    if ($byte_num == 0 && $iteration >= $phases) {
-+	&I(\$c, "st8 [OutPtr] = OutWord[%u], 8",
-+	   $iw1 % $NOutWord)				      if ($p & $pOut);
-+	if ($iteration == (1 + $unroll_count) * $phases - 1) {
-+	    if ($unroll_count == 6) {
-+		&I(\$c, "mov OutWord[%u] = OutWord[%u]",
-+		   $iw1 % $NOutWord, $iw0 % $NOutWord);
-+	    }
-+	    &I(\$c, "lfetch.nt1 [InPrefetch], %u",
-+	       $unroll_count * $phases);
-+	    &I(\$c, "lfetch.excl.nt1 [OutPrefetch], %u",
-+	       $unroll_count * $phases);
-+	    &I(\$c, "br.cloop.sptk.few .rc4Loop");
-+	}
-+    }
-+
-+    if ($pByp) {
-+	&P(\$bypass, ".rc4Bypass%u:", $label);
-+	&I(\$bypass, "sub J = J, SI[%u]", $i0 % $NSI);
-+	&I(\$bypass, "nop 0");
-+	&I(\$bypass, "nop 0");
-+	&I(\$bypass, ";;");
-+	&I(\$bypass, "add J = J, SI[%u]", $i1 % $NSI);
-+	&I(\$bypass, "mov SI[%u] = SI[%u]", $i0 % $NSI, $i1 % $NSI);
-+	&I(\$bypass, "br.sptk.many .rc4Resume%u\n", $label);
-+	&I(\$bypass, ";;");
-+    }
-+}
-+
-+$code=<<___;
-+.ident \"rc4-ia64.s, version 3.0\"
-+.ident \"Copyright (c) 2005 Hewlett-Packard Development Company, L.P.\"
-+
-+#define LCSave		r8
-+#define PRSave		r9
-+
-+/* Inputs become invalid once rotation begins!  */
-+
-+#define StateTable	in0
-+#define DataLen		in1
-+#define InputBuffer	in2
-+#define OutputBuffer	in3
-+
-+#define KTable		r14
-+#define J		r15
-+#define InPtr		r16
-+#define OutPtr		r17
-+#define InPrefetch	r18
-+#define OutPrefetch	r19
-+#define One		r20
-+#define LoopCount	r21
-+#define Remainder	r22
-+#define IFinal		r23
-+#define EndPtr		r24
-+
-+#define tmp0		r25
-+#define tmp1		r26
-+
-+#define pBypass		p6
-+#define pDone		p7
-+#define pSmall		p8
-+#define pAligned	p9
-+#define pUnaligned	p10
-+
-+#define pComputeI	pPhase[0]
-+#define pComputeJ	pPhase[1]
-+#define pComputeT	pPhase[2]
-+#define pOutput		pPhase[3]
-+
-+#define RetVal		r8
-+#define L_OK		p7
-+#define L_NOK		p8
-+
-+#define	_NINPUTS	4
-+#define	_NOUTPUT	0
-+
-+#define	_NROTATE	24
-+#define	_NLOCALS	(_NROTATE - _NINPUTS - _NOUTPUT)
-+
-+#ifndef SZ
-+# define SZ	4	// this must be set to sizeof(RC4_INT)
-+#endif
-+
-+#if SZ == 1
-+# define LKEY			ld1
-+# define SKEY			st1
-+# define KEYADDR(dst, i)	add dst = i, KTable
-+#elif SZ == 2
-+# define LKEY			ld2
-+# define SKEY			st2
-+# define KEYADDR(dst, i)	shladd dst = i, 1, KTable
-+#elif SZ == 4
-+# define LKEY			ld4
-+# define SKEY			st4
-+# define KEYADDR(dst, i)	shladd dst = i, 2, KTable
-+#else
-+# define LKEY			ld8
-+# define SKEY			st8
-+# define KEYADDR(dst, i)	shladd dst = i, 3, KTable
-+#endif
-+
-+#if defined(_HPUX_SOURCE) && !defined(_LP64)
-+# define ADDP	addp4
-+#else
-+# define ADDP	add
-+#endif
-+
-+/* Define a macro for the bit number of the n-th byte: */
-+
-+#if defined(_HPUX_SOURCE) || defined(B_ENDIAN)
-+# define HOST_IS_BIG_ENDIAN
-+# define BYTE_POS(n)	(56 - (8 * (n)))
-+#else
-+# define BYTE_POS(n)	(8 * (n))
-+#endif
-+
-+/*
-+   We must perform the first phase of the pipeline explicitly since
-+   we will always load from the stable the first time. The br.cexit
-+   will never be taken since regardless of the number of bytes because
-+   the epilogue count is 4.
-+*/
-+/* MODSCHED_RC4 macro was split to _PROLOGUE and _LOOP, because HP-UX
-+   assembler failed on original macro with syntax error.  */
-+#define MODSCHED_RC4_PROLOGUE						   \\
-+	{								   \\
-+				ld1		Data[0] = [InPtr], 1;	   \\
-+				add		IFinal = 1, I[1];	   \\
-+				KEYADDR(IPr[0], I[1]);			   \\
-+	} ;;								   \\
-+	{								   \\
-+				LKEY		SI[0] = [IPr[0]];	   \\
-+				mov		pr.rot = 0x10000;	   \\
-+				mov		ar.ec = 4;		   \\
-+	} ;;								   \\
-+	{								   \\
-+				add		J = J, SI[0];		   \\
-+				zxt1		I[0] = IFinal;		   \\
-+				br.cexit.spnt.few .+16; /* never taken */  \\
-+	} ;;
-+#define MODSCHED_RC4_LOOP(label)					   \\
-+label:									   \\
-+	{	.mmi;							   \\
-+		(pComputeI)	ld1		Data[0] = [InPtr], 1;	   \\
-+		(pComputeI)	add		IFinal = 1, I[1];	   \\
-+		(pComputeJ)	zxt1		J = J;			   \\
-+	}{	.mmi;							   \\
-+		(pOutput)	LKEY		T[1] = [T[1]];		   \\
-+		(pComputeT)	add		T[0] = SI[2], SJ[1];	   \\
-+		(pComputeI)	KEYADDR(IPr[0], I[1]);			   \\
-+	} ;;								   \\
-+	{	.mmi;							   \\
-+		(pComputeT)	SKEY		[IPr[2]] = SJ[1];	   \\
-+		(pComputeT)	SKEY		[JP[1]] = SI[2];	   \\
-+		(pComputeT)	zxt1		T[0] = T[0];		   \\
-+	}{	.mmi;							   \\
-+		(pComputeI)	LKEY		SI[0] = [IPr[0]];	   \\
-+		(pComputeJ)	KEYADDR(JP[0], J);			   \\
-+		(pComputeI)	cmp.eq.unc	pBypass, p0 = I[1], J;	   \\
-+	} ;;								   \\
-+	{	.mmi;							   \\
-+		(pComputeJ)	LKEY		SJ[0] = [JP[0]];	   \\
-+		(pOutput)	xor		Data[3] = Data[3], T[1];   \\
-+				nop		0x0;			   \\
-+	}{	.mmi;							   \\
-+		(pComputeT)	KEYADDR(T[0], T[0]);			   \\
-+		(pBypass)	mov		SI[0] = SI[1];		   \\
-+		(pComputeI)	zxt1		I[0] = IFinal;		   \\
-+	} ;;								   \\
-+	{	.mmb;							   \\
-+		(pOutput)	st1		[OutPtr] = Data[3], 1;	   \\
-+		(pComputeI)	add		J = J, SI[0];		   \\
-+				br.ctop.sptk.few label;			   \\
-+	} ;;
-+
-+	.text
-+
-+	.align	32
-+
-+	.type	RC4, \@function
-+	.global	RC4
-+
-+	.proc	RC4
-+	.prologue
-+
-+RC4:
-+	{
-+	  	.mmi
-+		alloc	r2 = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE
-+
-+		.rotr Data[4], I[2], IPr[3], SI[3], JP[2], SJ[2], T[2], \\
-+		      OutWord[2]
-+		.rotp pPhase[4]
-+
-+		ADDP		InPrefetch = 0, InputBuffer
-+		ADDP		KTable = 0, StateTable
-+	}
-+	{
-+		.mmi
-+		ADDP		InPtr = 0, InputBuffer
-+		ADDP		OutPtr = 0, OutputBuffer
-+		mov		RetVal = r0
-+	}
-+	;;
-+	{
-+		.mmi
-+		lfetch.nt1	[InPrefetch], 0x80
-+		ADDP		OutPrefetch = 0, OutputBuffer
-+	}
-+	{               // Return 0 if the input length is nonsensical
-+        	.mib
-+		ADDP		StateTable = 0, StateTable
-+        	cmp.ge.unc  	L_NOK, L_OK = r0, DataLen
-+	(L_NOK) br.ret.sptk.few rp
-+	}
-+	;;
-+	{
-+        	.mib
-+        	cmp.eq.or  	L_NOK, L_OK = r0, InPtr
-+        	cmp.eq.or  	L_NOK, L_OK = r0, OutPtr
-+		nop		0x0
-+	}
-+	{
-+		.mib
-+        	cmp.eq.or  	L_NOK, L_OK = r0, StateTable
-+		nop		0x0
-+	(L_NOK) br.ret.sptk.few rp
-+	}
-+	;;
-+		LKEY		I[1] = [KTable], SZ
-+/* Prefetch the state-table. It contains 256 elements of size SZ */
-+
-+#if SZ == 1
-+		ADDP		tmp0 = 1*128, StateTable
-+#elif SZ == 2
-+		ADDP		tmp0 = 3*128, StateTable
-+		ADDP		tmp1 = 2*128, StateTable
-+#elif SZ == 4
-+		ADDP		tmp0 = 7*128, StateTable
-+		ADDP		tmp1 = 6*128, StateTable
-+#elif SZ == 8
-+		ADDP		tmp0 = 15*128, StateTable
-+		ADDP		tmp1 = 14*128, StateTable
-+#endif
-+		;;
-+#if SZ >= 8
-+		lfetch.fault.nt1		[tmp0], -256	// 15
-+		lfetch.fault.nt1		[tmp1], -256;;
-+		lfetch.fault.nt1		[tmp0], -256	// 13
-+		lfetch.fault.nt1		[tmp1], -256;;
-+		lfetch.fault.nt1		[tmp0], -256	// 11
-+		lfetch.fault.nt1		[tmp1], -256;;
-+		lfetch.fault.nt1		[tmp0], -256	//  9
-+		lfetch.fault.nt1		[tmp1], -256;;
-+#endif
-+#if SZ >= 4
-+		lfetch.fault.nt1		[tmp0], -256	//  7
-+		lfetch.fault.nt1		[tmp1], -256;;
-+		lfetch.fault.nt1		[tmp0], -256	//  5
-+		lfetch.fault.nt1		[tmp1], -256;;
-+#endif
-+#if SZ >= 2
-+		lfetch.fault.nt1		[tmp0], -256	//  3
-+		lfetch.fault.nt1		[tmp1], -256;;
-+#endif
-+	{
-+		.mii
-+		lfetch.fault.nt1		[tmp0]		//  1
-+		add		I[1]=1,I[1];;
-+		zxt1		I[1]=I[1]
-+	}
-+	{
-+		.mmi
-+		lfetch.nt1	[InPrefetch], 0x80
-+		lfetch.excl.nt1	[OutPrefetch], 0x80
-+		.save		pr, PRSave
-+		mov		PRSave = pr
-+	} ;;
-+	{
-+		.mmi
-+		lfetch.excl.nt1	[OutPrefetch], 0x80
-+		LKEY		J = [KTable], SZ
-+		ADDP		EndPtr = DataLen, InPtr
-+	}  ;;
-+	{
-+		.mmi
-+		ADDP		EndPtr = -1, EndPtr	// Make it point to
-+							// last data byte.
-+		mov		One = 1
-+		.save		ar.lc, LCSave
-+		mov		LCSave = ar.lc
-+		.body
-+	} ;;
-+	{
-+		.mmb
-+		sub		Remainder = 0, OutPtr
-+		cmp.gtu		pSmall, p0 = $threshold, DataLen
-+(pSmall)	br.cond.dpnt	.rc4Remainder		// Data too small for
-+							// big loop.
-+	} ;;
-+	{
-+		.mmi
-+		and		Remainder = 0x7, Remainder
-+		;;
-+		cmp.eq		pAligned, pUnaligned = Remainder, r0
-+		nop		0x0
-+	} ;;
-+	{
-+		.mmb
-+.pred.rel	"mutex",pUnaligned,pAligned
-+(pUnaligned)	add		Remainder = -1, Remainder
-+(pAligned)	sub		Remainder = EndPtr, InPtr
-+(pAligned)	br.cond.dptk.many .rc4Aligned
-+	} ;;
-+	{
-+		.mmi
-+		nop		0x0
-+		nop		0x0
-+		mov.i		ar.lc = Remainder
-+	}
-+
-+/* Do the initial few bytes via the compact, modulo-scheduled loop
-+   until the output pointer is 8-byte-aligned.  */
-+
-+		MODSCHED_RC4_PROLOGUE
-+		MODSCHED_RC4_LOOP(.RC4AlignLoop)
-+
-+	{
-+		.mib
-+		sub		Remainder = EndPtr, InPtr
-+		zxt1		IFinal = IFinal
-+		clrrrb				// Clear CFM.rrb.pr so
-+		;;				// next "mov pr.rot = N"
-+						// does the right thing.
-+	}
-+	{
-+		.mmi
-+		mov		I[1] = IFinal
-+		nop		0x0
-+		nop		0x0
-+	} ;;
-+
-+
-+.rc4Aligned:
-+
-+/*
-+   Unrolled loop count = (Remainder - ($unroll_count+1)*$phases)/($unroll_count*$phases)
-+ */
-+
-+	{
-+		.mlx
-+		add	LoopCount = 1 - ($unroll_count + 1)*$phases, Remainder
-+		movl		Remainder = 0xaaaaaaaaaaaaaaab
-+	} ;;
-+	{
-+		.mmi
-+		setf.sig	f6 = LoopCount		// M2, M3	6 cyc
-+		setf.sig	f7 = Remainder		// M2, M3	6 cyc
-+		nop		0x0
-+	} ;;
-+	{
-+		.mfb
-+		nop		0x0
-+		xmpy.hu		f6 = f6, f7
-+		nop		0x0
-+	} ;;
-+	{
-+		.mmi
-+		getf.sig	LoopCount = f6;;	// M2		5 cyc
-+		nop		0x0
-+		shr.u		LoopCount = LoopCount, 4
-+	} ;;
-+	{
-+		.mmi
-+		nop		0x0
-+		nop		0x0
-+		mov.i		ar.lc = LoopCount
-+	} ;;
-+
-+/* Now comes the unrolled loop: */
-+
-+.rc4Prologue:
-+___
-+
-+$iteration = 0;
-+
-+# Generate the prologue:
-+$predicates = 1;
-+for ($i = 0; $i < $phases; ++$i) {
-+    &emit_body (\$code, \$bypass, $iteration++, $predicates);
-+    $predicates = ($predicates << 1) | 1;
-+}
-+
-+$code.=<<___;
-+.rc4Loop:
-+___
-+
-+# Generate the body:
-+for ($i = 0; $i < $unroll_count*$phases; ++$i) {
-+    &emit_body (\$code, \$bypass, $iteration++, $predicates);
-+}
-+
-+$code.=<<___;
-+.rc4Epilogue:
-+___
-+
-+# Generate the epilogue:
-+for ($i = 0; $i < $phases; ++$i) {
-+    $predicates <<= 1;
-+    &emit_body (\$code, \$bypass, $iteration++, $predicates);
-+}
-+
-+$code.=<<___;
-+	{
-+		.mmi
-+		lfetch.nt1	[EndPtr]	// fetch line with last byte
-+		mov		IFinal = I[1]
-+		nop		0x0
-+	}
-+
-+.rc4Remainder:
-+	{
-+		.mmi
-+		sub		Remainder = EndPtr, InPtr	// Calculate
-+								// # of bytes
-+								// left - 1
-+		nop		0x0
-+		nop		0x0
-+	} ;;
-+	{
-+		.mib
-+		cmp.eq		pDone, p0 = -1, Remainder // done already?
-+		mov.i		ar.lc = Remainder
-+(pDone)		br.cond.dptk.few .rc4Complete
-+	}
-+
-+/* Do the remaining bytes via the compact, modulo-scheduled loop */
-+
-+		MODSCHED_RC4_PROLOGUE
-+		MODSCHED_RC4_LOOP(.RC4RestLoop)
-+
-+.rc4Complete:
-+	{
-+		.mmi
-+		add		KTable = -SZ, KTable
-+		add		IFinal = -1, IFinal
-+		mov		ar.lc = LCSave
-+	} ;;
-+	{
-+		.mii
-+		SKEY		[KTable] = J,-SZ
-+		zxt1		IFinal = IFinal
-+		mov		pr = PRSave, 0x1FFFF
-+	} ;;
-+	{
-+		.mib
-+		SKEY		[KTable] = IFinal
-+		add		RetVal = 1, r0
-+		br.ret.sptk.few	rp
-+	} ;;
-+___
-+
-+# Last but not least, emit the code for the bypass-code of the unrolled loop:
-+
-+$code.=$bypass;
-+
-+$code.=<<___;
-+	.endp RC4
-+___
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
-new file mode 100644
-index 0000000..890161b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl
-@@ -0,0 +1,645 @@
-+#! /usr/bin/env perl
-+# Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# June 2011
-+#
-+# This is RC4+MD5 "stitch" implementation. The idea, as spelled in
-+# http://download.intel.com/design/intarch/papers/323686.pdf, is that
-+# since both algorithms exhibit instruction-level parallelism, ILP,
-+# below theoretical maximum, interleaving them would allow to utilize
-+# processor resources better and achieve better performance. RC4
-+# instruction sequence is virtually identical to rc4-x86_64.pl, which
-+# is heavily based on submission by Maxim Perminov, Maxim Locktyukhin
-+# and Jim Guilford of Intel. MD5 is fresh implementation aiming to
-+# minimize register usage, which was used as "main thread" with RC4
-+# weaved into it, one RC4 round per one MD5 round. In addition to the
-+# stiched subroutine the script can generate standalone replacement
-+# md5_block_asm_data_order and RC4. Below are performance numbers in
-+# cycles per processed byte, less is better, for these the standalone
-+# subroutines, sum of them, and stitched one:
-+#
-+#		RC4	MD5	RC4+MD5	stitch	gain
-+# Opteron	6.5(*)	5.4	11.9	7.0	+70%(*)
-+# Core2		6.5	5.8	12.3	7.7	+60%
-+# Westmere	4.3	5.2	9.5	7.0	+36%
-+# Sandy Bridge	4.2	5.5	9.7	6.8	+43%
-+# Ivy Bridge	4.1	5.2	9.3	6.0	+54%
-+# Haswell	4.0	5.0	9.0	5.7	+60%
-+# Skylake	6.3(**)	5.0	11.3	5.3	+110%
-+# Atom		9.3	6.5	15.8	11.1	+42%
-+# VIA Nano	6.3	5.4	11.7	8.6	+37%
-+# Bulldozer	4.5	5.4	9.9	7.7	+29%
-+#
-+# (*)	rc4-x86_64.pl delivers 5.3 on Opteron, so real improvement
-+#	is +53%...
-+# (**)	unidentified anomaly;
-+
-+my ($rc4,$md5)=(1,1);	# what to generate?
-+my $D="#" if (!$md5);	# if set to "#", MD5 is stitched into RC4(),
-+			# but its result is discarded. Idea here is
-+			# to be able to use 'openssl speed rc4' for
-+			# benchmarking the stitched subroutine... 
-+
-+my $flavour = shift;
-+my $output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs);
-+
-+if ($rc4 && !$md5) {
-+  ($dat,$len,$in0,$out) = ("%rdi","%rsi","%rdx","%rcx");
-+  $func="RC4";				$nargs=4;
-+} elsif ($md5 && !$rc4) {
-+  ($ctx,$inp,$len) = ("%rdi","%rsi","%rdx");
-+  $func="md5_block_asm_data_order";	$nargs=3;
-+} else {
-+  ($dat,$in0,$out,$ctx,$inp,$len) = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9");
-+  $func="rc4_md5_enc";			$nargs=6;
-+  # void rc4_md5_enc(
-+  #		RC4_KEY *key,		#
-+  #		const void *in0,	# RC4 input
-+  #		void *out,		# RC4 output
-+  #		MD5_CTX *ctx,		#
-+  #		const void *inp,	# MD5 input
-+  #		size_t len);		# number of 64-byte blocks
-+}
-+
-+my @K=(	0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
-+	0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
-+	0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
-+	0x6b901122,0xfd987193,0xa679438e,0x49b40821,
-+
-+	0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
-+	0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
-+	0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
-+	0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
-+
-+	0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
-+	0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
-+	0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
-+	0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
-+
-+	0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
-+	0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
-+	0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
-+	0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391	);
-+
-+my @V=("%r8d","%r9d","%r10d","%r11d");	# MD5 registers
-+my $tmp="%r12d";
-+
-+my @XX=("%rbp","%rsi");			# RC4 registers
-+my @TX=("%rax","%rbx");
-+my $YY="%rcx";
-+my $TY="%rdx";
-+
-+my $MOD=32;				# 16, 32 or 64
-+
-+$code.=<<___;
-+.text
-+.align 16
-+
-+.globl	$func
-+.type	$func,\@function,$nargs
-+$func:
-+	cmp	\$0,$len
-+	je	.Labort
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	sub	\$40,%rsp
-+.Lbody:
-+___
-+if ($rc4) {
-+$code.=<<___;
-+$D#md5#	mov	$ctx,%r11		# reassign arguments
-+	mov	$len,%r12
-+	mov	$in0,%r13
-+	mov	$out,%r14
-+$D#md5#	mov	$inp,%r15
-+___
-+    $ctx="%r11"	if ($md5);		# reassign arguments
-+    $len="%r12";
-+    $in0="%r13";
-+    $out="%r14";
-+    $inp="%r15"	if ($md5);
-+    $inp=$in0	if (!$md5);
-+$code.=<<___;
-+	xor	$XX[0],$XX[0]
-+	xor	$YY,$YY
-+
-+	lea	8($dat),$dat
-+	mov	-8($dat),$XX[0]#b
-+	mov	-4($dat),$YY#b
-+
-+	inc	$XX[0]#b
-+	sub	$in0,$out
-+	movl	($dat,$XX[0],4),$TX[0]#d
-+___
-+$code.=<<___ if (!$md5);
-+	xor	$TX[1],$TX[1]
-+	test	\$-128,$len
-+	jz	.Loop1
-+	sub	$XX[0],$TX[1]
-+	and	\$`$MOD-1`,$TX[1]
-+	jz	.Loop${MOD}_is_hot
-+	sub	$TX[1],$len
-+.Loop${MOD}_warmup:
-+	add	$TX[0]#b,$YY#b
-+	movl	($dat,$YY,4),$TY#d
-+	movl	$TX[0]#d,($dat,$YY,4)
-+	movl	$TY#d,($dat,$XX[0],4)
-+	add	$TY#b,$TX[0]#b
-+	inc	$XX[0]#b
-+	movl	($dat,$TX[0],4),$TY#d
-+	movl	($dat,$XX[0],4),$TX[0]#d
-+	xorb	($in0),$TY#b
-+	movb	$TY#b,($out,$in0)
-+	lea	1($in0),$in0
-+	dec	$TX[1]
-+	jnz	.Loop${MOD}_warmup
-+
-+	mov	$YY,$TX[1]
-+	xor	$YY,$YY
-+	mov	$TX[1]#b,$YY#b
-+
-+.Loop${MOD}_is_hot:
-+	mov	$len,32(%rsp)		# save original $len
-+	shr	\$6,$len		# number of 64-byte blocks
-+___
-+  if ($D && !$md5) {			# stitch in dummy MD5
-+    $md5=1;
-+    $ctx="%r11";
-+    $inp="%r15";
-+    $code.=<<___;
-+	mov	%rsp,$ctx
-+	mov	$in0,$inp
-+___
-+  }
-+}
-+$code.=<<___;
-+#rc4#	add	$TX[0]#b,$YY#b
-+#rc4#	lea	($dat,$XX[0],4),$XX[1]
-+	shl	\$6,$len
-+	add	$inp,$len		# pointer to the end of input
-+	mov	$len,16(%rsp)
-+
-+#md5#	mov	$ctx,24(%rsp)		# save pointer to MD5_CTX
-+#md5#	mov	0*4($ctx),$V[0]		# load current hash value from MD5_CTX
-+#md5#	mov	1*4($ctx),$V[1]
-+#md5#	mov	2*4($ctx),$V[2]
-+#md5#	mov	3*4($ctx),$V[3]
-+	jmp	.Loop
-+
-+.align	16
-+.Loop:
-+#md5#	mov	$V[0],0*4(%rsp)		# put aside current hash value
-+#md5#	mov	$V[1],1*4(%rsp)
-+#md5#	mov	$V[2],2*4(%rsp)
-+#md5#	mov	$V[3],$tmp		# forward reference
-+#md5#	mov	$V[3],3*4(%rsp)
-+___
-+
-+sub R0 {
-+  my ($i,$a,$b,$c,$d)=@_;
-+  my @rot0=(7,12,17,22);
-+  my $j=$i%16;
-+  my $k=$i%$MOD;
-+  my $xmm="%xmm".($j&1);
-+    $code.="	movdqu	($in0),%xmm2\n"		if ($rc4 && $j==15);
-+    $code.="	add	\$$MOD,$XX[0]#b\n"	if ($rc4 && $j==15 && $k==$MOD-1);
-+    $code.="	pxor	$xmm,$xmm\n"		if ($rc4 && $j<=1);
-+    $code.=<<___;
-+#rc4#	movl	($dat,$YY,4),$TY#d
-+#md5#	xor	$c,$tmp
-+#rc4#	movl	$TX[0]#d,($dat,$YY,4)
-+#md5#	and	$b,$tmp
-+#md5#	add	4*`$j`($inp),$a
-+#rc4#	add	$TY#b,$TX[0]#b
-+#rc4#	movl	`4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
-+#md5#	add	\$$K[$i],$a
-+#md5#	xor	$d,$tmp
-+#rc4#	movz	$TX[0]#b,$TX[0]#d
-+#rc4#	movl	$TY#d,4*$k($XX[1])
-+#md5#	add	$tmp,$a
-+#rc4#	add	$TX[1]#b,$YY#b
-+#md5#	rol	\$$rot0[$j%4],$a
-+#md5#	mov	`$j==15?"$b":"$c"`,$tmp		# forward reference
-+#rc4#	pinsrw	\$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
-+#md5#	add	$b,$a
-+___
-+    $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
-+	mov	$YY,$XX[1]
-+	xor	$YY,$YY				# keyword to partial register
-+	mov	$XX[1]#b,$YY#b
-+	lea	($dat,$XX[0],4),$XX[1]
-+___
-+    $code.=<<___ if ($rc4 && $j==15);
-+	psllq	\$8,%xmm1
-+	pxor	%xmm0,%xmm2
-+	pxor	%xmm1,%xmm2
-+___
-+}
-+sub R1 {
-+  my ($i,$a,$b,$c,$d)=@_;
-+  my @rot1=(5,9,14,20);
-+  my $j=$i%16;
-+  my $k=$i%$MOD;
-+  my $xmm="%xmm".($j&1);
-+    $code.="	movdqu	16($in0),%xmm3\n"	if ($rc4 && $j==15);
-+    $code.="	add	\$$MOD,$XX[0]#b\n"	if ($rc4 && $j==15 && $k==$MOD-1);
-+    $code.="	pxor	$xmm,$xmm\n"		if ($rc4 && $j<=1);
-+    $code.=<<___;
-+#rc4#	movl	($dat,$YY,4),$TY#d
-+#md5#	xor	$b,$tmp
-+#rc4#	movl	$TX[0]#d,($dat,$YY,4)
-+#md5#	and	$d,$tmp
-+#md5#	add	4*`((1+5*$j)%16)`($inp),$a
-+#rc4#	add	$TY#b,$TX[0]#b
-+#rc4#	movl	`4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
-+#md5#	add	\$$K[$i],$a
-+#md5#	xor	$c,$tmp
-+#rc4#	movz	$TX[0]#b,$TX[0]#d
-+#rc4#	movl	$TY#d,4*$k($XX[1])
-+#md5#	add	$tmp,$a
-+#rc4#	add	$TX[1]#b,$YY#b
-+#md5#	rol	\$$rot1[$j%4],$a
-+#md5#	mov	`$j==15?"$c":"$b"`,$tmp		# forward reference
-+#rc4#	pinsrw	\$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
-+#md5#	add	$b,$a
-+___
-+    $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
-+	mov	$YY,$XX[1]
-+	xor	$YY,$YY				# keyword to partial register
-+	mov	$XX[1]#b,$YY#b
-+	lea	($dat,$XX[0],4),$XX[1]
-+___
-+    $code.=<<___ if ($rc4 && $j==15);
-+	psllq	\$8,%xmm1
-+	pxor	%xmm0,%xmm3
-+	pxor	%xmm1,%xmm3
-+___
-+}
-+sub R2 {
-+  my ($i,$a,$b,$c,$d)=@_;
-+  my @rot2=(4,11,16,23);
-+  my $j=$i%16;
-+  my $k=$i%$MOD;
-+  my $xmm="%xmm".($j&1);
-+    $code.="	movdqu	32($in0),%xmm4\n"	if ($rc4 && $j==15);
-+    $code.="	add	\$$MOD,$XX[0]#b\n"	if ($rc4 && $j==15 && $k==$MOD-1);
-+    $code.="	pxor	$xmm,$xmm\n"		if ($rc4 && $j<=1);
-+    $code.=<<___;
-+#rc4#	movl	($dat,$YY,4),$TY#d
-+#md5#	xor	$c,$tmp
-+#rc4#	movl	$TX[0]#d,($dat,$YY,4)
-+#md5#	xor	$b,$tmp
-+#md5#	add	4*`((5+3*$j)%16)`($inp),$a
-+#rc4#	add	$TY#b,$TX[0]#b
-+#rc4#	movl	`4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
-+#md5#	add	\$$K[$i],$a
-+#rc4#	movz	$TX[0]#b,$TX[0]#d
-+#md5#	add	$tmp,$a
-+#rc4#	movl	$TY#d,4*$k($XX[1])
-+#rc4#	add	$TX[1]#b,$YY#b
-+#md5#	rol	\$$rot2[$j%4],$a
-+#md5#	mov	`$j==15?"\\\$-1":"$c"`,$tmp	# forward reference
-+#rc4#	pinsrw	\$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
-+#md5#	add	$b,$a
-+___
-+    $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
-+	mov	$YY,$XX[1]
-+	xor	$YY,$YY				# keyword to partial register
-+	mov	$XX[1]#b,$YY#b
-+	lea	($dat,$XX[0],4),$XX[1]
-+___
-+    $code.=<<___ if ($rc4 && $j==15);
-+	psllq	\$8,%xmm1
-+	pxor	%xmm0,%xmm4
-+	pxor	%xmm1,%xmm4
-+___
-+}
-+sub R3 {
-+  my ($i,$a,$b,$c,$d)=@_;
-+  my @rot3=(6,10,15,21);
-+  my $j=$i%16;
-+  my $k=$i%$MOD;
-+  my $xmm="%xmm".($j&1);
-+    $code.="	movdqu	48($in0),%xmm5\n"	if ($rc4 && $j==15);
-+    $code.="	add	\$$MOD,$XX[0]#b\n"	if ($rc4 && $j==15 && $k==$MOD-1);
-+    $code.="	pxor	$xmm,$xmm\n"		if ($rc4 && $j<=1);
-+    $code.=<<___;
-+#rc4#	movl	($dat,$YY,4),$TY#d
-+#md5#	xor	$d,$tmp
-+#rc4#	movl	$TX[0]#d,($dat,$YY,4)
-+#md5#	or	$b,$tmp
-+#md5#	add	4*`((7*$j)%16)`($inp),$a
-+#rc4#	add	$TY#b,$TX[0]#b
-+#rc4#	movl	`4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
-+#md5#	add	\$$K[$i],$a
-+#rc4#	movz	$TX[0]#b,$TX[0]#d
-+#md5#	xor	$c,$tmp
-+#rc4#	movl	$TY#d,4*$k($XX[1])
-+#md5#	add	$tmp,$a
-+#rc4#	add	$TX[1]#b,$YY#b
-+#md5#	rol	\$$rot3[$j%4],$a
-+#md5#	mov	\$-1,$tmp			# forward reference
-+#rc4#	pinsrw	\$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
-+#md5#	add	$b,$a
-+___
-+    $code.=<<___ if ($rc4 && $j==15);
-+	mov	$XX[0],$XX[1]
-+	xor	$XX[0],$XX[0]			# keyword to partial register
-+	mov	$XX[1]#b,$XX[0]#b
-+	mov	$YY,$XX[1]
-+	xor	$YY,$YY				# keyword to partial register
-+	mov	$XX[1]#b,$YY#b
-+	lea	($dat,$XX[0],4),$XX[1]
-+	psllq	\$8,%xmm1
-+	pxor	%xmm0,%xmm5
-+	pxor	%xmm1,%xmm5
-+___
-+}
-+
-+my $i=0;
-+for(;$i<16;$i++) { R0($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
-+for(;$i<32;$i++) { R1($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
-+for(;$i<48;$i++) { R2($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
-+for(;$i<64;$i++) { R3($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
-+
-+$code.=<<___;
-+#md5#	add	0*4(%rsp),$V[0]		# accumulate hash value
-+#md5#	add	1*4(%rsp),$V[1]
-+#md5#	add	2*4(%rsp),$V[2]
-+#md5#	add	3*4(%rsp),$V[3]
-+
-+#rc4#	movdqu	%xmm2,($out,$in0)	# write RC4 output
-+#rc4#	movdqu	%xmm3,16($out,$in0)
-+#rc4#	movdqu	%xmm4,32($out,$in0)
-+#rc4#	movdqu	%xmm5,48($out,$in0)
-+#md5#	lea	64($inp),$inp
-+#rc4#	lea	64($in0),$in0
-+	cmp	16(%rsp),$inp		# are we done?
-+	jb	.Loop
-+
-+#md5#	mov	24(%rsp),$len		# restore pointer to MD5_CTX
-+#rc4#	sub	$TX[0]#b,$YY#b		# correct $YY
-+#md5#	mov	$V[0],0*4($len)		# write MD5_CTX
-+#md5#	mov	$V[1],1*4($len)
-+#md5#	mov	$V[2],2*4($len)
-+#md5#	mov	$V[3],3*4($len)
-+___
-+$code.=<<___ if ($rc4 && (!$md5 || $D));
-+	mov	32(%rsp),$len		# restore original $len
-+	and	\$63,$len		# remaining bytes
-+	jnz	.Loop1
-+	jmp	.Ldone
-+	
-+.align	16
-+.Loop1:
-+	add	$TX[0]#b,$YY#b
-+	movl	($dat,$YY,4),$TY#d
-+	movl	$TX[0]#d,($dat,$YY,4)
-+	movl	$TY#d,($dat,$XX[0],4)
-+	add	$TY#b,$TX[0]#b
-+	inc	$XX[0]#b
-+	movl	($dat,$TX[0],4),$TY#d
-+	movl	($dat,$XX[0],4),$TX[0]#d
-+	xorb	($in0),$TY#b
-+	movb	$TY#b,($out,$in0)
-+	lea	1($in0),$in0
-+	dec	$len
-+	jnz	.Loop1
-+
-+.Ldone:
-+___
-+$code.=<<___;
-+#rc4#	sub	\$1,$XX[0]#b
-+#rc4#	movl	$XX[0]#d,-8($dat)
-+#rc4#	movl	$YY#d,-4($dat)
-+
-+	mov	40(%rsp),%r15
-+	mov	48(%rsp),%r14
-+	mov	56(%rsp),%r13
-+	mov	64(%rsp),%r12
-+	mov	72(%rsp),%rbp
-+	mov	80(%rsp),%rbx
-+	lea	88(%rsp),%rsp
-+.Lepilogue:
-+.Labort:
-+	ret
-+.size $func,.-$func
-+___
-+
-+if ($rc4 && $D) {	# sole purpose of this section is to provide
-+			# option to use the generated module as drop-in
-+			# replacement for rc4-x86_64.pl for debugging
-+			# and testing purposes...
-+my ($idx,$ido)=("%r8","%r9");
-+my ($dat,$len,$inp)=("%rdi","%rsi","%rdx");
-+
-+$code.=<<___;
-+.globl	RC4_set_key
-+.type	RC4_set_key,\@function,3
-+.align	16
-+RC4_set_key:
-+	lea	8($dat),$dat
-+	lea	($inp,$len),$inp
-+	neg	$len
-+	mov	$len,%rcx
-+	xor	%eax,%eax
-+	xor	$ido,$ido
-+	xor	%r10,%r10
-+	xor	%r11,%r11
-+	jmp	.Lw1stloop
-+
-+.align	16
-+.Lw1stloop:
-+	mov	%eax,($dat,%rax,4)
-+	add	\$1,%al
-+	jnc	.Lw1stloop
-+
-+	xor	$ido,$ido
-+	xor	$idx,$idx
-+.align	16
-+.Lw2ndloop:
-+	mov	($dat,$ido,4),%r10d
-+	add	($inp,$len,1),$idx#b
-+	add	%r10b,$idx#b
-+	add	\$1,$len
-+	mov	($dat,$idx,4),%r11d
-+	cmovz	%rcx,$len
-+	mov	%r10d,($dat,$idx,4)
-+	mov	%r11d,($dat,$ido,4)
-+	add	\$1,$ido#b
-+	jnc	.Lw2ndloop
-+
-+	xor	%eax,%eax
-+	mov	%eax,-8($dat)
-+	mov	%eax,-4($dat)
-+	ret
-+.size	RC4_set_key,.-RC4_set_key
-+
-+.globl	RC4_options
-+.type	RC4_options,\@abi-omnipotent
-+.align	16
-+RC4_options:
-+	lea	.Lopts(%rip),%rax
-+	ret
-+.align	64
-+.Lopts:
-+.asciz	"rc4(64x,int)"
-+.align	64
-+.size	RC4_options,.-RC4_options
-+___
-+}
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+my $rec="%rcx";
-+my $frame="%rdx";
-+my $context="%r8";
-+my $disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lbody(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lbody
-+	jb	.Lin_prologue
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	lea	.Lepilogue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
-+	jae	.Lin_prologue
-+
-+	mov	40(%rax),%r15
-+	mov	48(%rax),%r14
-+	mov	56(%rax),%r13
-+	mov	64(%rax),%r12
-+	mov	72(%rax),%rbp
-+	mov	80(%rax),%rbx
-+	lea	88(%rax),%rax
-+
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R12
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_$func
-+	.rva	.LSEH_end_$func
-+	.rva	.LSEH_info_$func
-+
-+.section	.xdata
-+.align	8
-+.LSEH_info_$func:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+___
-+}
-+
-+sub reg_part {
-+my ($reg,$conv)=@_;
-+    if ($reg =~ /%r[0-9]+/)     { $reg .= $conv; }
-+    elsif ($conv eq "b")        { $reg =~ s/%[er]([^x]+)x?/%$1l/;       }
-+    elsif ($conv eq "w")        { $reg =~ s/%[er](.+)/%$1/;             }
-+    elsif ($conv eq "d")        { $reg =~ s/%[er](.+)/%e$1/;            }
-+    return $reg;
-+}
-+
-+$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+$code =~ s/pinsrw\s+\$0,/movd	/gm;
-+
-+$code =~ s/#md5#//gm	if ($md5);
-+$code =~ s/#rc4#//gm	if ($rc4);
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-parisc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-parisc.pl
-new file mode 100644
-index 0000000..006b6b0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-parisc.pl
-@@ -0,0 +1,321 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# RC4 for PA-RISC.
-+
-+# June 2009.
-+#
-+# Performance is 33% better than gcc 3.2 generated code on PA-7100LC.
-+# For reference, [4x] unrolled loop is >40% faster than folded one.
-+# It's possible to unroll loop 8 times on PA-RISC 2.0, but improvement
-+# is believed to be not sufficient to justify the effort...
-+#
-+# Special thanks to polarhome.com for providing HP-UX account.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+
-+$flavour = shift;
-+$output = shift;
-+open STDOUT,">$output";
-+
-+if ($flavour =~ /64/) {
-+	$LEVEL		="2.0W";
-+	$SIZE_T		=8;
-+	$FRAME_MARKER	=80;
-+	$SAVED_RP	=16;
-+	$PUSH		="std";
-+	$PUSHMA		="std,ma";
-+	$POP		="ldd";
-+	$POPMB		="ldd,mb";
-+} else {
-+	$LEVEL		="1.0";
-+	$SIZE_T		=4;
-+	$FRAME_MARKER	=48;
-+	$SAVED_RP	=20;
-+	$PUSH		="stw";
-+	$PUSHMA		="stwm";
-+	$POP		="ldw";
-+	$POPMB		="ldwm";
-+}
-+
-+$FRAME=4*$SIZE_T+$FRAME_MARKER;	# 4 saved regs + frame marker
-+				#                [+ argument transfer]
-+$SZ=1;				# defaults to RC4_CHAR
-+if (open CONF,"<${dir}../../opensslconf.h") {
-+    while() {
-+	if (m/#\s*define\s+RC4_INT\s+(.*)/) {
-+	    $SZ = ($1=~/char$/) ? 1 : 4;
-+	    last;
-+	}
-+    }
-+    close CONF;
-+}
-+
-+if ($SZ==1) {	# RC4_CHAR
-+    $LD="ldb";
-+    $LDX="ldbx";
-+    $MKX="addl";
-+    $ST="stb";
-+} else {	# RC4_INT (~5% faster than RC4_CHAR on PA-7100LC)
-+    $LD="ldw";
-+    $LDX="ldwx,s";
-+    $MKX="sh2addl";
-+    $ST="stw";
-+}
-+
-+$key="%r26";
-+$len="%r25";
-+$inp="%r24";
-+$out="%r23";
-+
-+@XX=("%r19","%r20");
-+@TX=("%r21","%r22");
-+$YY="%r28";
-+$TY="%r29";
-+
-+$acc="%r1";
-+$ix="%r2";
-+$iy="%r3";
-+$dat0="%r4";
-+$dat1="%r5";
-+$rem="%r6";
-+$mask="%r31";
-+
-+sub unrolledloopbody {
-+for ($i=0;$i<4;$i++) {
-+$code.=<<___;
-+	ldo	1($XX[0]),$XX[1]
-+	`sprintf("$LDX	%$TY(%$key),%$dat1") if ($i>0)`	
-+	and	$mask,$XX[1],$XX[1]
-+	$LDX	$YY($key),$TY
-+	$MKX	$YY,$key,$ix
-+	$LDX	$XX[1]($key),$TX[1]
-+	$MKX	$XX[0],$key,$iy
-+	$ST	$TX[0],0($ix)
-+	comclr,<> $XX[1],$YY,%r0	; conditional
-+	copy	$TX[0],$TX[1]		; move
-+	`sprintf("%sdep	%$dat1,%d,8,%$acc",$i==1?"z":"",8*($i-1)+7) if ($i>0)`
-+	$ST	$TY,0($iy)
-+	addl	$TX[0],$TY,$TY
-+	addl	$TX[1],$YY,$YY
-+	and	$mask,$TY,$TY
-+	and	$mask,$YY,$YY
-+___
-+push(@TX,shift(@TX)); push(@XX,shift(@XX));	# "rotate" registers
-+} }
-+
-+sub foldedloop {
-+my ($label,$count)=@_;
-+$code.=<<___;
-+$label
-+	$MKX	$YY,$key,$iy
-+	$LDX	$YY($key),$TY
-+	$MKX	$XX[0],$key,$ix
-+	$ST	$TX[0],0($iy)
-+	ldo	1($XX[0]),$XX[0]
-+	$ST	$TY,0($ix)
-+	addl	$TX[0],$TY,$TY
-+	ldbx	$inp($out),$dat1
-+	and	$mask,$TY,$TY
-+	and	$mask,$XX[0],$XX[0]
-+	$LDX	$TY($key),$acc
-+	$LDX	$XX[0]($key),$TX[0]
-+	ldo	1($out),$out
-+	xor	$dat1,$acc,$acc
-+	addl	$TX[0],$YY,$YY
-+	stb	$acc,-1($out)
-+	addib,<> -1,$count,$label	; $count is always small
-+	and	$mask,$YY,$YY
-+___
-+}
-+
-+$code=<<___;
-+	.LEVEL	$LEVEL
-+	.SPACE	\$TEXT\$
-+	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
-+
-+	.EXPORT	RC4,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
-+RC4
-+	.PROC
-+	.CALLINFO	FRAME=`$FRAME-4*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=6
-+	.ENTRY
-+	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
-+	$PUSHMA	%r3,$FRAME(%sp)
-+	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
-+	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
-+	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
-+
-+	cmpib,*= 0,$len,L\$abort
-+	sub	$inp,$out,$inp		; distance between $inp and $out
-+
-+	$LD	`0*$SZ`($key),$XX[0]
-+	$LD	`1*$SZ`($key),$YY
-+	ldo	`2*$SZ`($key),$key
-+
-+	ldi	0xff,$mask
-+	ldi	3,$dat0		
-+
-+	ldo	1($XX[0]),$XX[0]	; warm up loop
-+	and	$mask,$XX[0],$XX[0]
-+	$LDX	$XX[0]($key),$TX[0]
-+	addl	$TX[0],$YY,$YY
-+	cmpib,*>>= 6,$len,L\$oop1	; is $len large enough to bother?
-+	and	$mask,$YY,$YY
-+
-+	and,<>	$out,$dat0,$rem		; is $out aligned?
-+	b	L\$alignedout
-+	subi	4,$rem,$rem
-+	sub	$len,$rem,$len
-+___
-+&foldedloop("L\$alignout",$rem);	# process till $out is aligned
-+
-+$code.=<<___;
-+L\$alignedout				; $len is at least 4 here
-+	and,<>	$inp,$dat0,$acc		; is $inp aligned?
-+	b	L\$oop4
-+	sub	$inp,$acc,$rem		; align $inp
-+
-+	sh3addl	$acc,%r0,$acc
-+	subi	32,$acc,$acc
-+	mtctl	$acc,%cr11		; load %sar with vshd align factor
-+	ldwx	$rem($out),$dat0
-+	ldo	4($rem),$rem
-+L\$oop4misalignedinp
-+___
-+&unrolledloopbody();
-+$code.=<<___;
-+	$LDX	$TY($key),$ix
-+	ldwx	$rem($out),$dat1
-+	ldo	-4($len),$len
-+	or	$ix,$acc,$acc		; last piece, no need to dep
-+	vshd	$dat0,$dat1,$iy		; align data
-+	copy	$dat1,$dat0
-+	xor	$iy,$acc,$acc
-+	stw	$acc,0($out)
-+	cmpib,*<< 3,$len,L\$oop4misalignedinp
-+	ldo	4($out),$out
-+	cmpib,*= 0,$len,L\$done
-+	nop
-+	b	L\$oop1
-+	nop
-+
-+	.ALIGN	8
-+L\$oop4
-+___
-+&unrolledloopbody();
-+$code.=<<___;
-+	$LDX	$TY($key),$ix
-+	ldwx	$inp($out),$dat0
-+	ldo	-4($len),$len
-+	or	$ix,$acc,$acc		; last piece, no need to dep
-+	xor	$dat0,$acc,$acc
-+	stw	$acc,0($out)
-+	cmpib,*<< 3,$len,L\$oop4
-+	ldo	4($out),$out
-+	cmpib,*= 0,$len,L\$done
-+	nop
-+___
-+&foldedloop("L\$oop1",$len);
-+$code.=<<___;
-+L\$done
-+	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2
-+	ldo	-1($XX[0]),$XX[0]	; chill out loop
-+	sub	$YY,$TX[0],$YY
-+	and	$mask,$XX[0],$XX[0]
-+	and	$mask,$YY,$YY
-+	$ST	$XX[0],`-2*$SZ`($key)
-+	$ST	$YY,`-1*$SZ`($key)
-+	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
-+	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
-+	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
-+L\$abort
-+	bv	(%r2)
-+	.EXIT
-+	$POPMB	-$FRAME(%sp),%r3
-+	.PROCEND
-+___
-+
-+$code.=<<___;
-+
-+	.EXPORT	RC4_set_key,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
-+	.ALIGN	8
-+RC4_set_key
-+	.PROC
-+	.CALLINFO	NO_CALLS
-+	.ENTRY
-+	$ST	%r0,`0*$SZ`($key)
-+	$ST	%r0,`1*$SZ`($key)
-+	ldo	`2*$SZ`($key),$key
-+	copy	%r0,@XX[0]
-+L\$1st
-+	$ST	@XX[0],0($key)
-+	ldo	1(@XX[0]),@XX[0]
-+	bb,>=	@XX[0],`31-8`,L\$1st	; @XX[0]<256
-+	ldo	$SZ($key),$key
-+
-+	ldo	`-256*$SZ`($key),$key	; rewind $key
-+	addl	$len,$inp,$inp		; $inp to point at the end
-+	sub	%r0,$len,%r23		; inverse index
-+	copy	%r0,@XX[0]
-+	copy	%r0,@XX[1]
-+	ldi	0xff,$mask
-+
-+L\$2nd
-+	$LDX	@XX[0]($key),@TX[0]
-+	ldbx	%r23($inp),@TX[1]
-+	addi,nuv 1,%r23,%r23		; increment and conditional
-+	sub	%r0,$len,%r23		; inverse index
-+	addl	@TX[0],@XX[1],@XX[1]
-+	addl	@TX[1],@XX[1],@XX[1]
-+	and	$mask,@XX[1],@XX[1]
-+	$MKX	@XX[0],$key,$TY
-+	$LDX	@XX[1]($key),@TX[1]
-+	$MKX	@XX[1],$key,$YY
-+	ldo	1(@XX[0]),@XX[0]
-+	$ST	@TX[0],0($YY)
-+	bb,>=	@XX[0],`31-8`,L\$2nd	; @XX[0]<256
-+	$ST	@TX[1],0($TY)
-+
-+	bv,n	(%r2)
-+	.EXIT
-+	nop
-+	.PROCEND
-+
-+	.EXPORT	RC4_options,ENTRY
-+	.ALIGN	8
-+RC4_options
-+	.PROC
-+	.CALLINFO	NO_CALLS
-+	.ENTRY
-+	blr	%r0,%r28
-+	ldi	3,%r1
-+L\$pic
-+	andcm	%r28,%r1,%r28
-+	bv	(%r2)
-+	.EXIT
-+	ldo	L\$opts-L\$pic(%r28),%r28
-+	.PROCEND
-+	.ALIGN	8
-+L\$opts
-+	.STRINGZ "rc4(4x,`$SZ==1?"char":"int"`)"
-+	.STRINGZ "RC4 for PA-RISC, CRYPTOGAMS by "
-+___
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+$code =~ s/cmpib,\*/comib,/gm	if ($SIZE_T==4);
-+$code =~ s/\bbv\b/bve/gm	if ($SIZE_T==8);
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-s390x.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-s390x.pl
-new file mode 100644
-index 0000000..5589503
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-s390x.pl
-@@ -0,0 +1,241 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# February 2009
-+#
-+# Performance is 2x of gcc 3.4.6 on z10. Coding "secret" is to
-+# "cluster" Address Generation Interlocks, so that one pipeline stall
-+# resolves several dependencies.
-+
-+# November 2010.
-+#
-+# Adapt for -m31 build. If kernel supports what's called "highgprs"
-+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
-+# instructions and achieve "64-bit" performance even in 31-bit legacy
-+# application context. The feature is not specific to any particular
-+# processor, as long as it's "z-CPU". Latter implies that the code
-+# remains z/Architecture specific. On z990 it was measured to perform
-+# 50% better than code generated by gcc 4.3.
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /3[12]/) {
-+	$SIZE_T=4;
-+	$g="";
-+} else {
-+	$SIZE_T=8;
-+	$g="g";
-+}
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+$rp="%r14";
-+$sp="%r15";
-+$code=<<___;
-+.text
-+
-+___
-+
-+# void RC4(RC4_KEY *key,size_t len,const void *inp,void *out)
-+{
-+$acc="%r0";
-+$cnt="%r1";
-+$key="%r2";
-+$len="%r3";
-+$inp="%r4";
-+$out="%r5";
-+
-+@XX=("%r6","%r7");
-+@TX=("%r8","%r9");
-+$YY="%r10";
-+$TY="%r11";
-+
-+$code.=<<___;
-+.globl	RC4
-+.type	RC4,\@function
-+.align	64
-+RC4:
-+	stm${g}	%r6,%r11,6*$SIZE_T($sp)
-+___
-+$code.=<<___ if ($flavour =~ /3[12]/);
-+	llgfr	$len,$len
-+___
-+$code.=<<___;
-+	llgc	$XX[0],0($key)
-+	llgc	$YY,1($key)
-+	la	$XX[0],1($XX[0])
-+	nill	$XX[0],0xff
-+	srlg	$cnt,$len,3
-+	ltgr	$cnt,$cnt
-+	llgc	$TX[0],2($XX[0],$key)
-+	jz	.Lshort
-+	j	.Loop8
-+
-+.align	64
-+.Loop8:
-+___
-+for ($i=0;$i<8;$i++) {
-+$code.=<<___;
-+	la	$YY,0($YY,$TX[0])	# $i
-+	nill	$YY,255
-+	la	$XX[1],1($XX[0])
-+	nill	$XX[1],255
-+___
-+$code.=<<___ if ($i==1);
-+	llgc	$acc,2($TY,$key)
-+___
-+$code.=<<___ if ($i>1);
-+	sllg	$acc,$acc,8
-+	ic	$acc,2($TY,$key)
-+___
-+$code.=<<___;
-+	llgc	$TY,2($YY,$key)
-+	stc	$TX[0],2($YY,$key)
-+	llgc	$TX[1],2($XX[1],$key)
-+	stc	$TY,2($XX[0],$key)
-+	cr	$XX[1],$YY
-+	jne	.Lcmov$i
-+	la	$TX[1],0($TX[0])
-+.Lcmov$i:
-+	la	$TY,0($TY,$TX[0])
-+	nill	$TY,255
-+___
-+push(@TX,shift(@TX)); push(@XX,shift(@XX));     # "rotate" registers
-+}
-+
-+$code.=<<___;
-+	lg	$TX[1],0($inp)
-+	sllg	$acc,$acc,8
-+	la	$inp,8($inp)
-+	ic	$acc,2($TY,$key)
-+	xgr	$acc,$TX[1]
-+	stg	$acc,0($out)
-+	la	$out,8($out)
-+	brctg	$cnt,.Loop8
-+
-+.Lshort:
-+	lghi	$acc,7
-+	ngr	$len,$acc
-+	jz	.Lexit
-+	j	.Loop1
-+
-+.align	16
-+.Loop1:
-+	la	$YY,0($YY,$TX[0])
-+	nill	$YY,255
-+	llgc	$TY,2($YY,$key)
-+	stc	$TX[0],2($YY,$key)
-+	stc	$TY,2($XX[0],$key)
-+	ar	$TY,$TX[0]
-+	ahi	$XX[0],1
-+	nill	$TY,255
-+	nill	$XX[0],255
-+	llgc	$acc,0($inp)
-+	la	$inp,1($inp)
-+	llgc	$TY,2($TY,$key)
-+	llgc	$TX[0],2($XX[0],$key)
-+	xr	$acc,$TY
-+	stc	$acc,0($out)
-+	la	$out,1($out)
-+	brct	$len,.Loop1
-+
-+.Lexit:
-+	ahi	$XX[0],-1
-+	stc	$XX[0],0($key)
-+	stc	$YY,1($key)
-+	lm${g}	%r6,%r11,6*$SIZE_T($sp)
-+	br	$rp
-+.size	RC4,.-RC4
-+.string	"RC4 for s390x, CRYPTOGAMS by "
-+
-+___
-+}
-+
-+# void RC4_set_key(RC4_KEY *key,unsigned int len,const void *inp)
-+{
-+$cnt="%r0";
-+$idx="%r1";
-+$key="%r2";
-+$len="%r3";
-+$inp="%r4";
-+$acc="%r5";
-+$dat="%r6";
-+$ikey="%r7";
-+$iinp="%r8";
-+
-+$code.=<<___;
-+.globl	RC4_set_key
-+.type	RC4_set_key,\@function
-+.align	64
-+RC4_set_key:
-+	stm${g}	%r6,%r8,6*$SIZE_T($sp)
-+	lhi	$cnt,256
-+	la	$idx,0(%r0)
-+	sth	$idx,0($key)
-+.align	4
-+.L1stloop:
-+	stc	$idx,2($idx,$key)
-+	la	$idx,1($idx)
-+	brct	$cnt,.L1stloop
-+
-+	lghi	$ikey,-256
-+	lr	$cnt,$len
-+	la	$iinp,0(%r0)
-+	la	$idx,0(%r0)
-+.align	16
-+.L2ndloop:
-+	llgc	$acc,2+256($ikey,$key)
-+	llgc	$dat,0($iinp,$inp)
-+	la	$idx,0($idx,$acc)
-+	la	$ikey,1($ikey)
-+	la	$idx,0($idx,$dat)
-+	nill	$idx,255
-+	la	$iinp,1($iinp)
-+	tml	$ikey,255
-+	llgc	$dat,2($idx,$key)
-+	stc	$dat,2+256-1($ikey,$key)
-+	stc	$acc,2($idx,$key)
-+	jz	.Ldone
-+	brct	$cnt,.L2ndloop
-+	lr	$cnt,$len
-+	la	$iinp,0(%r0)
-+	j	.L2ndloop
-+.Ldone:
-+	lm${g}	%r6,%r8,6*$SIZE_T($sp)
-+	br	$rp
-+.size	RC4_set_key,.-RC4_set_key
-+
-+___
-+}
-+
-+# const char *RC4_options()
-+$code.=<<___;
-+.globl	RC4_options
-+.type	RC4_options,\@function
-+.align	16
-+RC4_options:
-+	larl	%r2,.Loptions
-+	br	%r14
-+.size	RC4_options,.-RC4_options
-+.section	.rodata
-+.Loptions:
-+.align	8
-+.string	"rc4(8x,char)"
-+___
-+
-+print $code;
-+close STDOUT;	# force flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-x86_64.pl
-new file mode 100755
-index 0000000..aaed2b1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/asm/rc4-x86_64.pl
-@@ -0,0 +1,687 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# July 2004
-+#
-+# 2.22x RC4 tune-up:-) It should be noted though that my hand [as in
-+# "hand-coded assembler"] doesn't stand for the whole improvement
-+# coefficient. It turned out that eliminating RC4_CHAR from config
-+# line results in ~40% improvement (yes, even for C implementation).
-+# Presumably it has everything to do with AMD cache architecture and
-+# RAW or whatever penalties. Once again! The module *requires* config
-+# line *without* RC4_CHAR! As for coding "secret," I bet on partial
-+# register arithmetics. For example instead of 'inc %r8; and $255,%r8'
-+# I simply 'inc %r8b'. Even though optimization manual discourages
-+# to operate on partial registers, it turned out to be the best bet.
-+# At least for AMD... How IA32E would perform remains to be seen...
-+
-+# November 2004
-+#
-+# As was shown by Marc Bevand reordering of couple of load operations
-+# results in even higher performance gain of 3.3x:-) At least on
-+# Opteron... For reference, 1x in this case is RC4_CHAR C-code
-+# compiled with gcc 3.3.2, which performs at ~54MBps per 1GHz clock.
-+# Latter means that if you want to *estimate* what to expect from
-+# *your* Opteron, then multiply 54 by 3.3 and clock frequency in GHz.
-+
-+# November 2004
-+#
-+# Intel P4 EM64T core was found to run the AMD64 code really slow...
-+# The only way to achieve comparable performance on P4 was to keep
-+# RC4_CHAR. Kind of ironic, huh? As it's apparently impossible to
-+# compose blended code, which would perform even within 30% marginal
-+# on either AMD and Intel platforms, I implement both cases. See
-+# rc4_skey.c for further details...
-+
-+# April 2005
-+#
-+# P4 EM64T core appears to be "allergic" to 64-bit inc/dec. Replacing 
-+# those with add/sub results in 50% performance improvement of folded
-+# loop...
-+
-+# May 2005
-+#
-+# As was shown by Zou Nanhai loop unrolling can improve Intel EM64T
-+# performance by >30% [unlike P4 32-bit case that is]. But this is
-+# provided that loads are reordered even more aggressively! Both code
-+# paths, AMD64 and EM64T, reorder loads in essentially same manner
-+# as my IA-64 implementation. On Opteron this resulted in modest 5%
-+# improvement [I had to test it], while final Intel P4 performance
-+# achieves respectful 432MBps on 2.8GHz processor now. For reference.
-+# If executed on Xeon, current RC4_CHAR code-path is 2.7x faster than
-+# RC4_INT code-path. While if executed on Opteron, it's only 25%
-+# slower than the RC4_INT one [meaning that if CPU µ-arch detection
-+# is not implemented, then this final RC4_CHAR code-path should be
-+# preferred, as it provides better *all-round* performance].
-+
-+# March 2007
-+#
-+# Intel Core2 was observed to perform poorly on both code paths:-( It
-+# apparently suffers from some kind of partial register stall, which
-+# occurs in 64-bit mode only [as virtually identical 32-bit loop was
-+# observed to outperform 64-bit one by almost 50%]. Adding two movzb to
-+# cloop1 boosts its performance by 80%! This loop appears to be optimal
-+# fit for Core2 and therefore the code was modified to skip cloop8 on
-+# this CPU.
-+
-+# May 2010
-+#
-+# Intel Westmere was observed to perform suboptimally. Adding yet
-+# another movzb to cloop1 improved performance by almost 50%! Core2
-+# performance is improved too, but nominally...
-+
-+# May 2011
-+#
-+# The only code path that was not modified is P4-specific one. Non-P4
-+# Intel code path optimization is heavily based on submission by Maxim
-+# Perminov, Maxim Locktyukhin and Jim Guilford of Intel. I've used
-+# some of the ideas even in attempt to optmize the original RC4_INT
-+# code path... Current performance in cycles per processed byte (less
-+# is better) and improvement coefficients relative to previous
-+# version of this module are:
-+#
-+# Opteron	5.3/+0%(*)
-+# P4		6.5
-+# Core2		6.2/+15%(**)
-+# Westmere	4.2/+60%
-+# Sandy Bridge	4.2/+120%
-+# Atom		9.3/+80%
-+# VIA Nano	6.4/+4%
-+# Ivy Bridge	4.1/+30%
-+# Bulldozer	4.5/+30%(*)
-+#
-+# (*)	But corresponding loop has less instructions, which should have
-+#	positive effect on upcoming Bulldozer, which has one less ALU.
-+#	For reference, Intel code runs at 6.8 cpb rate on Opteron.
-+# (**)	Note that Core2 result is ~15% lower than corresponding result
-+#	for 32-bit code, meaning that it's possible to improve it,
-+#	but more than likely at the cost of the others (see rc4-586.pl
-+#	to get the idea)...
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+$dat="%rdi";	    # arg1
-+$len="%rsi";	    # arg2
-+$inp="%rdx";	    # arg3
-+$out="%rcx";	    # arg4
-+
-+{
-+$code=<<___;
-+.text
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	RC4
-+.type	RC4,\@function,4
-+.align	16
-+RC4:	or	$len,$len
-+	jne	.Lentry
-+	ret
-+.Lentry:
-+	push	%rbx
-+	push	%r12
-+	push	%r13
-+.Lprologue:
-+	mov	$len,%r11
-+	mov	$inp,%r12
-+	mov	$out,%r13
-+___
-+my $len="%r11";		# reassign input arguments
-+my $inp="%r12";
-+my $out="%r13";
-+
-+my @XX=("%r10","%rsi");
-+my @TX=("%rax","%rbx");
-+my $YY="%rcx";
-+my $TY="%rdx";
-+
-+$code.=<<___;
-+	xor	$XX[0],$XX[0]
-+	xor	$YY,$YY
-+
-+	lea	8($dat),$dat
-+	mov	-8($dat),$XX[0]#b
-+	mov	-4($dat),$YY#b
-+	cmpl	\$-1,256($dat)
-+	je	.LRC4_CHAR
-+	mov	OPENSSL_ia32cap_P(%rip),%r8d
-+	xor	$TX[1],$TX[1]
-+	inc	$XX[0]#b
-+	sub	$XX[0],$TX[1]
-+	sub	$inp,$out
-+	movl	($dat,$XX[0],4),$TX[0]#d
-+	test	\$-16,$len
-+	jz	.Lloop1
-+	bt	\$30,%r8d	# Intel CPU?
-+	jc	.Lintel
-+	and	\$7,$TX[1]
-+	lea	1($XX[0]),$XX[1]
-+	jz	.Loop8
-+	sub	$TX[1],$len
-+.Loop8_warmup:
-+	add	$TX[0]#b,$YY#b
-+	movl	($dat,$YY,4),$TY#d
-+	movl	$TX[0]#d,($dat,$YY,4)
-+	movl	$TY#d,($dat,$XX[0],4)
-+	add	$TY#b,$TX[0]#b
-+	inc	$XX[0]#b
-+	movl	($dat,$TX[0],4),$TY#d
-+	movl	($dat,$XX[0],4),$TX[0]#d
-+	xorb	($inp),$TY#b
-+	movb	$TY#b,($out,$inp)
-+	lea	1($inp),$inp
-+	dec	$TX[1]
-+	jnz	.Loop8_warmup
-+
-+	lea	1($XX[0]),$XX[1]
-+	jmp	.Loop8
-+.align	16
-+.Loop8:
-+___
-+for ($i=0;$i<8;$i++) {
-+$code.=<<___ if ($i==7);
-+	add	\$8,$XX[1]#b
-+___
-+$code.=<<___;
-+	add	$TX[0]#b,$YY#b
-+	movl	($dat,$YY,4),$TY#d
-+	movl	$TX[0]#d,($dat,$YY,4)
-+	movl	`4*($i==7?-1:$i)`($dat,$XX[1],4),$TX[1]#d
-+	ror	\$8,%r8				# ror is redundant when $i=0
-+	movl	$TY#d,4*$i($dat,$XX[0],4)
-+	add	$TX[0]#b,$TY#b
-+	movb	($dat,$TY,4),%r8b
-+___
-+push(@TX,shift(@TX)); #push(@XX,shift(@XX));	# "rotate" registers
-+}
-+$code.=<<___;
-+	add	\$8,$XX[0]#b
-+	ror	\$8,%r8
-+	sub	\$8,$len
-+
-+	xor	($inp),%r8
-+	mov	%r8,($out,$inp)
-+	lea	8($inp),$inp
-+
-+	test	\$-8,$len
-+	jnz	.Loop8
-+	cmp	\$0,$len
-+	jne	.Lloop1
-+	jmp	.Lexit
-+
-+.align	16
-+.Lintel:
-+	test	\$-32,$len
-+	jz	.Lloop1
-+	and	\$15,$TX[1]
-+	jz	.Loop16_is_hot
-+	sub	$TX[1],$len
-+.Loop16_warmup:
-+	add	$TX[0]#b,$YY#b
-+	movl	($dat,$YY,4),$TY#d
-+	movl	$TX[0]#d,($dat,$YY,4)
-+	movl	$TY#d,($dat,$XX[0],4)
-+	add	$TY#b,$TX[0]#b
-+	inc	$XX[0]#b
-+	movl	($dat,$TX[0],4),$TY#d
-+	movl	($dat,$XX[0],4),$TX[0]#d
-+	xorb	($inp),$TY#b
-+	movb	$TY#b,($out,$inp)
-+	lea	1($inp),$inp
-+	dec	$TX[1]
-+	jnz	.Loop16_warmup
-+
-+	mov	$YY,$TX[1]
-+	xor	$YY,$YY
-+	mov	$TX[1]#b,$YY#b
-+
-+.Loop16_is_hot:
-+	lea	($dat,$XX[0],4),$XX[1]
-+___
-+sub RC4_loop {
-+  my $i=shift;
-+  my $j=$i<0?0:$i;
-+  my $xmm="%xmm".($j&1);
-+
-+    $code.="	add	\$16,$XX[0]#b\n"		if ($i==15);
-+    $code.="	movdqu	($inp),%xmm2\n"			if ($i==15);
-+    $code.="	add	$TX[0]#b,$YY#b\n"		if ($i<=0);
-+    $code.="	movl	($dat,$YY,4),$TY#d\n";
-+    $code.="	pxor	%xmm0,%xmm2\n"			if ($i==0);
-+    $code.="	psllq	\$8,%xmm1\n"			if ($i==0);
-+    $code.="	pxor	$xmm,$xmm\n"			if ($i<=1);
-+    $code.="	movl	$TX[0]#d,($dat,$YY,4)\n";
-+    $code.="	add	$TY#b,$TX[0]#b\n";
-+    $code.="	movl	`4*($j+1)`($XX[1]),$TX[1]#d\n"	if ($i<15);
-+    $code.="	movz	$TX[0]#b,$TX[0]#d\n";
-+    $code.="	movl	$TY#d,4*$j($XX[1])\n";
-+    $code.="	pxor	%xmm1,%xmm2\n"			if ($i==0);
-+    $code.="	lea	($dat,$XX[0],4),$XX[1]\n"	if ($i==15);
-+    $code.="	add	$TX[1]#b,$YY#b\n"		if ($i<15);
-+    $code.="	pinsrw	\$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n";
-+    $code.="	movdqu	%xmm2,($out,$inp)\n"		if ($i==0);
-+    $code.="	lea	16($inp),$inp\n"		if ($i==0);
-+    $code.="	movl	($XX[1]),$TX[1]#d\n"		if ($i==15);
-+}
-+	RC4_loop(-1);
-+$code.=<<___;
-+	jmp	.Loop16_enter
-+.align	16
-+.Loop16:
-+___
-+
-+for ($i=0;$i<16;$i++) {
-+    $code.=".Loop16_enter:\n"		if ($i==1);
-+	RC4_loop($i);
-+	push(@TX,shift(@TX)); 		# "rotate" registers
-+}
-+$code.=<<___;
-+	mov	$YY,$TX[1]
-+	xor	$YY,$YY			# keyword to partial register
-+	sub	\$16,$len
-+	mov	$TX[1]#b,$YY#b
-+	test	\$-16,$len
-+	jnz	.Loop16
-+
-+	psllq	\$8,%xmm1
-+	pxor	%xmm0,%xmm2
-+	pxor	%xmm1,%xmm2
-+	movdqu	%xmm2,($out,$inp)
-+	lea	16($inp),$inp
-+
-+	cmp	\$0,$len
-+	jne	.Lloop1
-+	jmp	.Lexit
-+
-+.align	16
-+.Lloop1:
-+	add	$TX[0]#b,$YY#b
-+	movl	($dat,$YY,4),$TY#d
-+	movl	$TX[0]#d,($dat,$YY,4)
-+	movl	$TY#d,($dat,$XX[0],4)
-+	add	$TY#b,$TX[0]#b
-+	inc	$XX[0]#b
-+	movl	($dat,$TX[0],4),$TY#d
-+	movl	($dat,$XX[0],4),$TX[0]#d
-+	xorb	($inp),$TY#b
-+	movb	$TY#b,($out,$inp)
-+	lea	1($inp),$inp
-+	dec	$len
-+	jnz	.Lloop1
-+	jmp	.Lexit
-+
-+.align	16
-+.LRC4_CHAR:
-+	add	\$1,$XX[0]#b
-+	movzb	($dat,$XX[0]),$TX[0]#d
-+	test	\$-8,$len
-+	jz	.Lcloop1
-+	jmp	.Lcloop8
-+.align	16
-+.Lcloop8:
-+	mov	($inp),%r8d
-+	mov	4($inp),%r9d
-+___
-+# unroll 2x4-wise, because 64-bit rotates kill Intel P4...
-+for ($i=0;$i<4;$i++) {
-+$code.=<<___;
-+	add	$TX[0]#b,$YY#b
-+	lea	1($XX[0]),$XX[1]
-+	movzb	($dat,$YY),$TY#d
-+	movzb	$XX[1]#b,$XX[1]#d
-+	movzb	($dat,$XX[1]),$TX[1]#d
-+	movb	$TX[0]#b,($dat,$YY)
-+	cmp	$XX[1],$YY
-+	movb	$TY#b,($dat,$XX[0])
-+	jne	.Lcmov$i			# Intel cmov is sloooow...
-+	mov	$TX[0],$TX[1]
-+.Lcmov$i:
-+	add	$TX[0]#b,$TY#b
-+	xor	($dat,$TY),%r8b
-+	ror	\$8,%r8d
-+___
-+push(@TX,shift(@TX)); push(@XX,shift(@XX));	# "rotate" registers
-+}
-+for ($i=4;$i<8;$i++) {
-+$code.=<<___;
-+	add	$TX[0]#b,$YY#b
-+	lea	1($XX[0]),$XX[1]
-+	movzb	($dat,$YY),$TY#d
-+	movzb	$XX[1]#b,$XX[1]#d
-+	movzb	($dat,$XX[1]),$TX[1]#d
-+	movb	$TX[0]#b,($dat,$YY)
-+	cmp	$XX[1],$YY
-+	movb	$TY#b,($dat,$XX[0])
-+	jne	.Lcmov$i			# Intel cmov is sloooow...
-+	mov	$TX[0],$TX[1]
-+.Lcmov$i:
-+	add	$TX[0]#b,$TY#b
-+	xor	($dat,$TY),%r9b
-+	ror	\$8,%r9d
-+___
-+push(@TX,shift(@TX)); push(@XX,shift(@XX));	# "rotate" registers
-+}
-+$code.=<<___;
-+	lea	-8($len),$len
-+	mov	%r8d,($out)
-+	lea	8($inp),$inp
-+	mov	%r9d,4($out)
-+	lea	8($out),$out
-+
-+	test	\$-8,$len
-+	jnz	.Lcloop8
-+	cmp	\$0,$len
-+	jne	.Lcloop1
-+	jmp	.Lexit
-+___
-+$code.=<<___;
-+.align	16
-+.Lcloop1:
-+	add	$TX[0]#b,$YY#b
-+	movzb	$YY#b,$YY#d
-+	movzb	($dat,$YY),$TY#d
-+	movb	$TX[0]#b,($dat,$YY)
-+	movb	$TY#b,($dat,$XX[0])
-+	add	$TX[0]#b,$TY#b
-+	add	\$1,$XX[0]#b
-+	movzb	$TY#b,$TY#d
-+	movzb	$XX[0]#b,$XX[0]#d
-+	movzb	($dat,$TY),$TY#d
-+	movzb	($dat,$XX[0]),$TX[0]#d
-+	xorb	($inp),$TY#b
-+	lea	1($inp),$inp
-+	movb	$TY#b,($out)
-+	lea	1($out),$out
-+	sub	\$1,$len
-+	jnz	.Lcloop1
-+	jmp	.Lexit
-+
-+.align	16
-+.Lexit:
-+	sub	\$1,$XX[0]#b
-+	movl	$XX[0]#d,-8($dat)
-+	movl	$YY#d,-4($dat)
-+
-+	mov	(%rsp),%r13
-+	mov	8(%rsp),%r12
-+	mov	16(%rsp),%rbx
-+	add	\$24,%rsp
-+.Lepilogue:
-+	ret
-+.size	RC4,.-RC4
-+___
-+}
-+
-+$idx="%r8";
-+$ido="%r9";
-+
-+$code.=<<___;
-+.globl	RC4_set_key
-+.type	RC4_set_key,\@function,3
-+.align	16
-+RC4_set_key:
-+	lea	8($dat),$dat
-+	lea	($inp,$len),$inp
-+	neg	$len
-+	mov	$len,%rcx
-+	xor	%eax,%eax
-+	xor	$ido,$ido
-+	xor	%r10,%r10
-+	xor	%r11,%r11
-+
-+	mov	OPENSSL_ia32cap_P(%rip),$idx#d
-+	bt	\$20,$idx#d	# RC4_CHAR?
-+	jc	.Lc1stloop
-+	jmp	.Lw1stloop
-+
-+.align	16
-+.Lw1stloop:
-+	mov	%eax,($dat,%rax,4)
-+	add	\$1,%al
-+	jnc	.Lw1stloop
-+
-+	xor	$ido,$ido
-+	xor	$idx,$idx
-+.align	16
-+.Lw2ndloop:
-+	mov	($dat,$ido,4),%r10d
-+	add	($inp,$len,1),$idx#b
-+	add	%r10b,$idx#b
-+	add	\$1,$len
-+	mov	($dat,$idx,4),%r11d
-+	cmovz	%rcx,$len
-+	mov	%r10d,($dat,$idx,4)
-+	mov	%r11d,($dat,$ido,4)
-+	add	\$1,$ido#b
-+	jnc	.Lw2ndloop
-+	jmp	.Lexit_key
-+
-+.align	16
-+.Lc1stloop:
-+	mov	%al,($dat,%rax)
-+	add	\$1,%al
-+	jnc	.Lc1stloop
-+
-+	xor	$ido,$ido
-+	xor	$idx,$idx
-+.align	16
-+.Lc2ndloop:
-+	mov	($dat,$ido),%r10b
-+	add	($inp,$len),$idx#b
-+	add	%r10b,$idx#b
-+	add	\$1,$len
-+	mov	($dat,$idx),%r11b
-+	jnz	.Lcnowrap
-+	mov	%rcx,$len
-+.Lcnowrap:
-+	mov	%r10b,($dat,$idx)
-+	mov	%r11b,($dat,$ido)
-+	add	\$1,$ido#b
-+	jnc	.Lc2ndloop
-+	movl	\$-1,256($dat)
-+
-+.align	16
-+.Lexit_key:
-+	xor	%eax,%eax
-+	mov	%eax,-8($dat)
-+	mov	%eax,-4($dat)
-+	ret
-+.size	RC4_set_key,.-RC4_set_key
-+
-+.globl	RC4_options
-+.type	RC4_options,\@abi-omnipotent
-+.align	16
-+RC4_options:
-+	lea	.Lopts(%rip),%rax
-+	mov	OPENSSL_ia32cap_P(%rip),%edx
-+	bt	\$20,%edx
-+	jc	.L8xchar
-+	bt	\$30,%edx
-+	jnc	.Ldone
-+	add	\$25,%rax
-+	ret
-+.L8xchar:
-+	add	\$12,%rax
-+.Ldone:
-+	ret
-+.align	64
-+.Lopts:
-+.asciz	"rc4(8x,int)"
-+.asciz	"rc4(8x,char)"
-+.asciz	"rc4(16x,int)"
-+.asciz	"RC4 for x86_64, CRYPTOGAMS by "
-+.align	64
-+.size	RC4_options,.-RC4_options
-+___
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	stream_se_handler,\@abi-omnipotent
-+.align	16
-+stream_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lprologue(%rip),%r10
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	lea	.Lepilogue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_prologue
-+
-+	lea	24(%rax),%rax
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%r12
-+	mov	-24(%rax),%r13
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	jmp	.Lcommon_seh_exit
-+.size	stream_se_handler,.-stream_se_handler
-+
-+.type	key_se_handler,\@abi-omnipotent
-+.align	16
-+key_se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+.Lcommon_seh_exit:
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	key_se_handler,.-key_se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_RC4
-+	.rva	.LSEH_end_RC4
-+	.rva	.LSEH_info_RC4
-+
-+	.rva	.LSEH_begin_RC4_set_key
-+	.rva	.LSEH_end_RC4_set_key
-+	.rva	.LSEH_info_RC4_set_key
-+
-+.section	.xdata
-+.align	8
-+.LSEH_info_RC4:
-+	.byte	9,0,0,0
-+	.rva	stream_se_handler
-+.LSEH_info_RC4_set_key:
-+	.byte	9,0,0,0
-+	.rva	key_se_handler
-+___
-+}
-+
-+sub reg_part {
-+my ($reg,$conv)=@_;
-+    if ($reg =~ /%r[0-9]+/)	{ $reg .= $conv; }
-+    elsif ($conv eq "b")	{ $reg =~ s/%[er]([^x]+)x?/%$1l/;	}
-+    elsif ($conv eq "w")	{ $reg =~ s/%[er](.+)/%$1/;		}
-+    elsif ($conv eq "d")	{ $reg =~ s/%[er](.+)/%e$1/;		}
-+    return $reg;
-+}
-+
-+$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+
-+print $code;
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/build.info
-new file mode 100644
-index 0000000..6c48889
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/build.info
-@@ -0,0 +1,33 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        {- $target{rc4_asm_src} -}
-+
-+GENERATE[rc4-586.s]=asm/rc4-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[rc4-586.s]=../perlasm/x86asm.pl
-+
-+GENERATE[rc4-x86_64.s]=asm/rc4-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[rc4-md5-x86_64.s]=asm/rc4-md5-x86_64.pl $(PERLASM_SCHEME)
-+
-+GENERATE[rc4-parisc.s]=asm/rc4-parisc.pl $(PERLASM_SCHEME)
-+
-+BEGINRAW[makefile(windows)]
-+{- $builddir -}\rc4-ia64.asm: {- $sourcedir -}\asm\rc4-ia64.pl
-+	$(PERL) {- $sourcedir -}\asm\rc4-ia64.pl $@.S
-+	$(CC) -DSZ=4 -EP $@.S > $@.i && move /Y $@.i $@
-+	del /Q $@.S
-+ENDRAW[makefile(windows)]
-+
-+BEGINRAW[Makefile]
-+{- $builddir -}/rc4-ia64.s: {- $sourcedir -}/asm/rc4-ia64.pl
-+	@(trap "rm $@.*" INT 0; \
-+	  $(PERL) $< $(CFLAGS) $(LIB_CFLAGS) $@.S; \
-+	  case `awk '/^#define RC4_INT/{print$$NF}' $(BLDDIR)/include/openssl/opensslconf.h` in \
-+	  int)	set -x; $(CC) $(CFLAGS) $(LIB_CFLAGS) -DSZ=4 -E $@.S > $@.i && mv -f $@.i $@;; \
-+	  char)	set -x; $(CC) $(CFLAGS) $(LIB_CFLAGS) -DSZ=1 -E $@.S > $@.i && mv -f $@.i $@;; \
-+	  *)	exit 1 ;; \
-+	  esac )
-+
-+# GNU make "catch all"
-+{- $builddir -}/rc4-%.s:	{- $sourcedir -}/asm/rc4-%.pl
-+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-+ENDRAW[Makefile]
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_enc.c
-new file mode 100644
-index 0000000..be11bad
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_enc.c
-@@ -0,0 +1,86 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc4_locl.h"
-+
-+/*-
-+ * RC4 as implemented from a posting from
-+ * Newsgroups: sci.crypt
-+ * From: sterndark@netcom.com (David Sterndark)
-+ * Subject: RC4 Algorithm revealed.
-+ * Message-ID: 
-+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
-+ */
-+
-+void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
-+         unsigned char *outdata)
-+{
-+    register RC4_INT *d;
-+    register RC4_INT x, y, tx, ty;
-+    size_t i;
-+
-+    x = key->x;
-+    y = key->y;
-+    d = key->data;
-+
-+#define LOOP(in,out) \
-+                x=((x+1)&0xff); \
-+                tx=d[x]; \
-+                y=(tx+y)&0xff; \
-+                d[x]=ty=d[y]; \
-+                d[y]=tx; \
-+                (out) = d[(tx+ty)&0xff]^ (in);
-+
-+    i = len >> 3;
-+    if (i) {
-+        for (;;) {
-+            LOOP(indata[0], outdata[0]);
-+            LOOP(indata[1], outdata[1]);
-+            LOOP(indata[2], outdata[2]);
-+            LOOP(indata[3], outdata[3]);
-+            LOOP(indata[4], outdata[4]);
-+            LOOP(indata[5], outdata[5]);
-+            LOOP(indata[6], outdata[6]);
-+            LOOP(indata[7], outdata[7]);
-+            indata += 8;
-+            outdata += 8;
-+            if (--i == 0)
-+                break;
-+        }
-+    }
-+    i = len & 0x07;
-+    if (i) {
-+        for (;;) {
-+            LOOP(indata[0], outdata[0]);
-+            if (--i == 0)
-+                break;
-+            LOOP(indata[1], outdata[1]);
-+            if (--i == 0)
-+                break;
-+            LOOP(indata[2], outdata[2]);
-+            if (--i == 0)
-+                break;
-+            LOOP(indata[3], outdata[3]);
-+            if (--i == 0)
-+                break;
-+            LOOP(indata[4], outdata[4]);
-+            if (--i == 0)
-+                break;
-+            LOOP(indata[5], outdata[5]);
-+            if (--i == 0)
-+                break;
-+            LOOP(indata[6], outdata[6]);
-+            if (--i == 0)
-+                break;
-+        }
-+    }
-+    key->x = x;
-+    key->y = y;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_locl.h
-new file mode 100644
-index 0000000..4380add
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_locl.h
-@@ -0,0 +1,16 @@
-+/*
-+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_RC4_LOCL_H
-+# define HEADER_RC4_LOCL_H
-+
-+# include 
-+# include "internal/cryptlib.h"
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_skey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_skey.c
-new file mode 100644
-index 0000000..16f81a4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc4/rc4_skey.c
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc4_locl.h"
-+#include 
-+
-+const char *RC4_options(void)
-+{
-+    if (sizeof(RC4_INT) == 1)
-+        return ("rc4(char)");
-+    else
-+        return ("rc4(int)");
-+}
-+
-+/*-
-+ * RC4 as implemented from a posting from
-+ * Newsgroups: sci.crypt
-+ * From: sterndark@netcom.com (David Sterndark)
-+ * Subject: RC4 Algorithm revealed.
-+ * Message-ID: 
-+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
-+ */
-+
-+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
-+{
-+    register RC4_INT tmp;
-+    register int id1, id2;
-+    register RC4_INT *d;
-+    unsigned int i;
-+
-+    d = &(key->data[0]);
-+    key->x = 0;
-+    key->y = 0;
-+    id1 = id2 = 0;
-+
-+#define SK_LOOP(d,n) { \
-+                tmp=d[(n)]; \
-+                id2 = (data[id1] + tmp + id2) & 0xff; \
-+                if (++id1 == len) id1=0; \
-+                d[(n)]=d[id2]; \
-+                d[id2]=tmp; }
-+
-+    for (i = 0; i < 256; i++)
-+        d[i] = i;
-+    for (i = 0; i < 256; i += 4) {
-+        SK_LOOP(d, i + 0);
-+        SK_LOOP(d, i + 1);
-+        SK_LOOP(d, i + 2);
-+        SK_LOOP(d, i + 3);
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/asm/rc5-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/asm/rc5-586.pl
-new file mode 100644
-index 0000000..e3e1c64
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/asm/rc5-586.pl
-@@ -0,0 +1,122 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+require "cbc.pl";
-+
-+$output = pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"rc5-586.pl");
-+
-+$RC5_MAX_ROUNDS=16;
-+$RC5_32_OFF=($RC5_MAX_ROUNDS+2)*4;
-+$A="edi";
-+$B="esi";
-+$S="ebp";
-+$tmp1="eax";
-+$r="ebx";
-+$tmpc="ecx";
-+$tmp4="edx";
-+
-+&RC5_32_encrypt("RC5_32_encrypt",1);
-+&RC5_32_encrypt("RC5_32_decrypt",0);
-+&cbc("RC5_32_cbc_encrypt","RC5_32_encrypt","RC5_32_decrypt",0,4,5,3,-1,-1);
-+&asm_finish();
-+
-+close STDOUT;
-+
-+sub RC5_32_encrypt
-+	{
-+	local($name,$enc)=@_;
-+
-+	&function_begin_B($name,"");
-+
-+	&comment("");
-+
-+	&push("ebp");
-+	 &push("esi");
-+	&push("edi");
-+	 &mov($tmp4,&wparam(0));
-+	&mov($S,&wparam(1));
-+
-+	&comment("Load the 2 words");
-+	 &mov($A,&DWP(0,$tmp4,"",0));
-+	&mov($B,&DWP(4,$tmp4,"",0));
-+
-+	&push($r);
-+	 &mov($r,	&DWP(0,$S,"",0));
-+
-+	# encrypting part
-+
-+	if ($enc)
-+		{
-+		 &add($A,	&DWP(4+0,$S,"",0));
-+		&add($B,	&DWP(4+4,$S,"",0));
-+
-+		for ($i=0; $i<$RC5_MAX_ROUNDS; $i++)
-+			{
-+			 &xor($A,	$B);
-+			&mov($tmp1,	&DWP(12+$i*8,$S,"",0));
-+			 &mov($tmpc,	$B);
-+			&rotl($A,	&LB("ecx"));
-+			&add($A,	$tmp1);
-+
-+			 &xor($B,	$A);
-+			&mov($tmp1,	&DWP(16+$i*8,$S,"",0));
-+			 &mov($tmpc,	$A);
-+			&rotl($B,	&LB("ecx"));
-+			&add($B,	$tmp1);
-+			if (($i == 7) || ($i == 11))
-+				{
-+			 &cmp($r,	$i+1);
-+			&je(&label("rc5_exit"));
-+				}
-+			}
-+		}
-+	else
-+		{
-+		 &cmp($r,	12);
-+		&je(&label("rc5_dec_12"));
-+		 &cmp($r,	8);
-+		&je(&label("rc5_dec_8"));
-+		for ($i=$RC5_MAX_ROUNDS; $i > 0; $i--)
-+			{
-+			&set_label("rc5_dec_$i") if ($i == 12) || ($i == 8);
-+			 &mov($tmp1,	&DWP($i*8+8,$S,"",0));
-+			&sub($B,	$tmp1);
-+			 &mov($tmpc,	$A);
-+			&rotr($B,	&LB("ecx"));
-+			&xor($B,	$A);
-+
-+			 &mov($tmp1,	&DWP($i*8+4,$S,"",0));
-+			&sub($A,	$tmp1);
-+			 &mov($tmpc,	$B);
-+			&rotr($A,	&LB("ecx"));
-+			&xor($A,	$B);
-+			}
-+		 &sub($B,	&DWP(4+4,$S,"",0));
-+		&sub($A,	&DWP(4+0,$S,"",0));
-+		}
-+
-+	&set_label("rc5_exit");
-+	 &mov(&DWP(0,$tmp4,"",0),$A);
-+	&mov(&DWP(4,$tmp4,"",0),$B);
-+
-+	 &pop("ebx");
-+	&pop("edi");
-+	 &pop("esi");
-+	&pop("ebp");
-+	 &ret();
-+	&function_end_B($name);
-+	}
-+
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/build.info
-new file mode 100644
-index 0000000..baf8a0e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/build.info
-@@ -0,0 +1,6 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        rc5_skey.c rc5_ecb.c {- $target{rc5_asm_src} -} rc5cfb64.c rc5ofb64.c
-+
-+GENERATE[rc5-586.s]=asm/rc5-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS)
-+DEPEND[rc5-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_ecb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_ecb.c
-new file mode 100644
-index 0000000..c32f38e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_ecb.c
-@@ -0,0 +1,32 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc5_locl.h"
-+#include 
-+
-+void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out,
-+                        RC5_32_KEY *ks, int encrypt)
-+{
-+    unsigned long l, d[2];
-+
-+    c2l(in, l);
-+    d[0] = l;
-+    c2l(in, l);
-+    d[1] = l;
-+    if (encrypt)
-+        RC5_32_encrypt(d, ks);
-+    else
-+        RC5_32_decrypt(d, ks);
-+    l = d[0];
-+    l2c(l, out);
-+    l = d[1];
-+    l2c(l, out);
-+    l = d[0] = d[1] = 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_enc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_enc.c
-new file mode 100644
-index 0000000..58631de
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_enc.c
-@@ -0,0 +1,160 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "rc5_locl.h"
-+
-+void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                        long length, RC5_32_KEY *ks, unsigned char *iv,
-+                        int encrypt)
-+{
-+    register unsigned long tin0, tin1;
-+    register unsigned long tout0, tout1, xor0, xor1;
-+    register long l = length;
-+    unsigned long tin[2];
-+
-+    if (encrypt) {
-+        c2l(iv, tout0);
-+        c2l(iv, tout1);
-+        iv -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            c2l(in, tin0);
-+            c2l(in, tin1);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            RC5_32_encrypt(tin, ks);
-+            tout0 = tin[0];
-+            l2c(tout0, out);
-+            tout1 = tin[1];
-+            l2c(tout1, out);
-+        }
-+        if (l != -8) {
-+            c2ln(in, tin0, tin1, l + 8);
-+            tin0 ^= tout0;
-+            tin1 ^= tout1;
-+            tin[0] = tin0;
-+            tin[1] = tin1;
-+            RC5_32_encrypt(tin, ks);
-+            tout0 = tin[0];
-+            l2c(tout0, out);
-+            tout1 = tin[1];
-+            l2c(tout1, out);
-+        }
-+        l2c(tout0, iv);
-+        l2c(tout1, iv);
-+    } else {
-+        c2l(iv, xor0);
-+        c2l(iv, xor1);
-+        iv -= 8;
-+        for (l -= 8; l >= 0; l -= 8) {
-+            c2l(in, tin0);
-+            tin[0] = tin0;
-+            c2l(in, tin1);
-+            tin[1] = tin1;
-+            RC5_32_decrypt(tin, ks);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2c(tout0, out);
-+            l2c(tout1, out);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        if (l != -8) {
-+            c2l(in, tin0);
-+            tin[0] = tin0;
-+            c2l(in, tin1);
-+            tin[1] = tin1;
-+            RC5_32_decrypt(tin, ks);
-+            tout0 = tin[0] ^ xor0;
-+            tout1 = tin[1] ^ xor1;
-+            l2cn(tout0, tout1, out, l + 8);
-+            xor0 = tin0;
-+            xor1 = tin1;
-+        }
-+        l2c(xor0, iv);
-+        l2c(xor1, iv);
-+    }
-+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
-+    tin[0] = tin[1] = 0;
-+}
-+
-+void RC5_32_encrypt(unsigned long *d, RC5_32_KEY *key)
-+{
-+    RC5_32_INT a, b, *s;
-+
-+    s = key->data;
-+
-+    a = d[0] + s[0];
-+    b = d[1] + s[1];
-+    E_RC5_32(a, b, s, 2);
-+    E_RC5_32(a, b, s, 4);
-+    E_RC5_32(a, b, s, 6);
-+    E_RC5_32(a, b, s, 8);
-+    E_RC5_32(a, b, s, 10);
-+    E_RC5_32(a, b, s, 12);
-+    E_RC5_32(a, b, s, 14);
-+    E_RC5_32(a, b, s, 16);
-+    if (key->rounds == 12) {
-+        E_RC5_32(a, b, s, 18);
-+        E_RC5_32(a, b, s, 20);
-+        E_RC5_32(a, b, s, 22);
-+        E_RC5_32(a, b, s, 24);
-+    } else if (key->rounds == 16) {
-+        /* Do a full expansion to avoid a jump */
-+        E_RC5_32(a, b, s, 18);
-+        E_RC5_32(a, b, s, 20);
-+        E_RC5_32(a, b, s, 22);
-+        E_RC5_32(a, b, s, 24);
-+        E_RC5_32(a, b, s, 26);
-+        E_RC5_32(a, b, s, 28);
-+        E_RC5_32(a, b, s, 30);
-+        E_RC5_32(a, b, s, 32);
-+    }
-+    d[0] = a;
-+    d[1] = b;
-+}
-+
-+void RC5_32_decrypt(unsigned long *d, RC5_32_KEY *key)
-+{
-+    RC5_32_INT a, b, *s;
-+
-+    s = key->data;
-+
-+    a = d[0];
-+    b = d[1];
-+    if (key->rounds == 16) {
-+        D_RC5_32(a, b, s, 32);
-+        D_RC5_32(a, b, s, 30);
-+        D_RC5_32(a, b, s, 28);
-+        D_RC5_32(a, b, s, 26);
-+        /* Do a full expansion to avoid a jump */
-+        D_RC5_32(a, b, s, 24);
-+        D_RC5_32(a, b, s, 22);
-+        D_RC5_32(a, b, s, 20);
-+        D_RC5_32(a, b, s, 18);
-+    } else if (key->rounds == 12) {
-+        D_RC5_32(a, b, s, 24);
-+        D_RC5_32(a, b, s, 22);
-+        D_RC5_32(a, b, s, 20);
-+        D_RC5_32(a, b, s, 18);
-+    }
-+    D_RC5_32(a, b, s, 16);
-+    D_RC5_32(a, b, s, 14);
-+    D_RC5_32(a, b, s, 12);
-+    D_RC5_32(a, b, s, 10);
-+    D_RC5_32(a, b, s, 8);
-+    D_RC5_32(a, b, s, 6);
-+    D_RC5_32(a, b, s, 4);
-+    D_RC5_32(a, b, s, 2);
-+    d[0] = a - s[0];
-+    d[1] = b - s[1];
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_locl.h
-new file mode 100644
-index 0000000..33a709b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_locl.h
-@@ -0,0 +1,158 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#undef c2l
-+#define c2l(c,l)        (l =((unsigned long)(*((c)++)))    , \
-+                         l|=((unsigned long)(*((c)++)))<< 8L, \
-+                         l|=((unsigned long)(*((c)++)))<<16L, \
-+                         l|=((unsigned long)(*((c)++)))<<24L)
-+
-+/* NOTE - c is not incremented as per c2l */
-+#undef c2ln
-+#define c2ln(c,l1,l2,n) { \
-+                        c+=n; \
-+                        l1=l2=0; \
-+                        switch (n) { \
-+                        case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
-+                        case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
-+                        case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
-+                        case 5: l2|=((unsigned long)(*(--(c))));     \
-+                        case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
-+                        case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
-+                        case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
-+                        case 1: l1|=((unsigned long)(*(--(c))));     \
-+                                } \
-+                        }
-+
-+#undef l2c
-+#define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
-+
-+/* NOTE - c is not incremented as per l2c */
-+#undef l2cn
-+#define l2cn(l1,l2,c,n) { \
-+                        c+=n; \
-+                        switch (n) { \
-+                        case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
-+                        case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
-+                        case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
-+                        case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
-+                        case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
-+                        case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
-+                        case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
-+                        case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
-+                                } \
-+                        }
-+
-+/* NOTE - c is not incremented as per n2l */
-+#define n2ln(c,l1,l2,n) { \
-+                        c+=n; \
-+                        l1=l2=0; \
-+                        switch (n) { \
-+                        case 8: l2 =((unsigned long)(*(--(c))))    ; \
-+                        case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
-+                        case 6: l2|=((unsigned long)(*(--(c))))<<16; \
-+                        case 5: l2|=((unsigned long)(*(--(c))))<<24; \
-+                        case 4: l1 =((unsigned long)(*(--(c))))    ; \
-+                        case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
-+                        case 2: l1|=((unsigned long)(*(--(c))))<<16; \
-+                        case 1: l1|=((unsigned long)(*(--(c))))<<24; \
-+                                } \
-+                        }
-+
-+/* NOTE - c is not incremented as per l2n */
-+#define l2nn(l1,l2,c,n) { \
-+                        c+=n; \
-+                        switch (n) { \
-+                        case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
-+                        case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
-+                        case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
-+                        case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
-+                        case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
-+                        case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
-+                        case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
-+                        case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
-+                                } \
-+                        }
-+
-+#undef n2l
-+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
-+                         l|=((unsigned long)(*((c)++)))<<16L, \
-+                         l|=((unsigned long)(*((c)++)))<< 8L, \
-+                         l|=((unsigned long)(*((c)++))))
-+
-+#undef l2n
-+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+                         *((c)++)=(unsigned char)(((l)     )&0xff))
-+
-+#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER))
-+# define ROTATE_l32(a,n)     _lrotl(a,n)
-+# define ROTATE_r32(a,n)     _lrotr(a,n)
-+#elif defined(__ICC)
-+# define ROTATE_l32(a,n)     _rotl(a,n)
-+# define ROTATE_r32(a,n)     _rotr(a,n)
-+#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
-+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
-+#  define ROTATE_l32(a,n)       ({ register unsigned int ret;   \
-+                                        asm ("roll %%cl,%0"     \
-+                                                : "=r"(ret)     \
-+                                                : "c"(n),"0"((unsigned int)(a)) \
-+                                                : "cc");        \
-+                                        ret;                    \
-+                                })
-+#  define ROTATE_r32(a,n)       ({ register unsigned int ret;   \
-+                                        asm ("rorl %%cl,%0"     \
-+                                                : "=r"(ret)     \
-+                                                : "c"(n),"0"((unsigned int)(a)) \
-+                                                : "cc");        \
-+                                        ret;                    \
-+                                })
-+# endif
-+#endif
-+#ifndef ROTATE_l32
-+# define ROTATE_l32(a,n)     (((a)<<(n&0x1f))|(((a)&0xffffffff)>>((32-n)&0x1f)))
-+#endif
-+#ifndef ROTATE_r32
-+# define ROTATE_r32(a,n)     (((a)<<((32-n)&0x1f))|(((a)&0xffffffff)>>(n&0x1f)))
-+#endif
-+
-+#define RC5_32_MASK     0xffffffffL
-+
-+#define RC5_16_P        0xB7E1
-+#define RC5_16_Q        0x9E37
-+#define RC5_32_P        0xB7E15163L
-+#define RC5_32_Q        0x9E3779B9L
-+#define RC5_64_P        0xB7E151628AED2A6BLL
-+#define RC5_64_Q        0x9E3779B97F4A7C15LL
-+
-+#define E_RC5_32(a,b,s,n) \
-+        a^=b; \
-+        a=ROTATE_l32(a,b); \
-+        a+=s[n]; \
-+        a&=RC5_32_MASK; \
-+        b^=a; \
-+        b=ROTATE_l32(b,a); \
-+        b+=s[n+1]; \
-+        b&=RC5_32_MASK;
-+
-+#define D_RC5_32(a,b,s,n) \
-+        b-=s[n+1]; \
-+        b&=RC5_32_MASK; \
-+        b=ROTATE_r32(b,a); \
-+        b^=a; \
-+        a-=s[n]; \
-+        a&=RC5_32_MASK; \
-+        a=ROTATE_r32(a,b); \
-+        a^=b;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_skey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_skey.c
-new file mode 100644
-index 0000000..943a784
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5_skey.c
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc5_locl.h"
-+
-+void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,
-+                    int rounds)
-+{
-+    RC5_32_INT L[64], l, ll, A, B, *S, k;
-+    int i, j, m, c, t, ii, jj;
-+
-+    if ((rounds != RC5_16_ROUNDS) &&
-+        (rounds != RC5_12_ROUNDS) && (rounds != RC5_8_ROUNDS))
-+        rounds = RC5_16_ROUNDS;
-+
-+    key->rounds = rounds;
-+    S = &(key->data[0]);
-+    j = 0;
-+    for (i = 0; i <= (len - 8); i += 8) {
-+        c2l(data, l);
-+        L[j++] = l;
-+        c2l(data, l);
-+        L[j++] = l;
-+    }
-+    ii = len - i;
-+    if (ii) {
-+        k = len & 0x07;
-+        c2ln(data, l, ll, k);
-+        L[j + 0] = l;
-+        L[j + 1] = ll;
-+    }
-+
-+    c = (len + 3) / 4;
-+    t = (rounds + 1) * 2;
-+    S[0] = RC5_32_P;
-+    for (i = 1; i < t; i++)
-+        S[i] = (S[i - 1] + RC5_32_Q) & RC5_32_MASK;
-+
-+    j = (t > c) ? t : c;
-+    j *= 3;
-+    ii = jj = 0;
-+    A = B = 0;
-+    for (i = 0; i < j; i++) {
-+        k = (S[ii] + A + B) & RC5_32_MASK;
-+        A = S[ii] = ROTATE_l32(k, 3);
-+        m = (int)(A + B);
-+        k = (L[jj] + A + B) & RC5_32_MASK;
-+        B = L[jj] = ROTATE_l32(k, m);
-+        if (++ii >= t)
-+            ii = 0;
-+        if (++jj >= c)
-+            jj = 0;
-+    }
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5cfb64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5cfb64.c
-new file mode 100644
-index 0000000..9a8aa6b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5cfb64.c
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc5_locl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit cfb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+
-+void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out,
-+                          long length, RC5_32_KEY *schedule,
-+                          unsigned char *ivec, int *num, int encrypt)
-+{
-+    register unsigned long v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    unsigned long ti[2];
-+    unsigned char *iv, c, cc;
-+
-+    iv = (unsigned char *)ivec;
-+    if (encrypt) {
-+        while (l--) {
-+            if (n == 0) {
-+                c2l(iv, v0);
-+                ti[0] = v0;
-+                c2l(iv, v1);
-+                ti[1] = v1;
-+                RC5_32_encrypt((unsigned long *)ti, schedule);
-+                iv = (unsigned char *)ivec;
-+                t = ti[0];
-+                l2c(t, iv);
-+                t = ti[1];
-+                l2c(t, iv);
-+                iv = (unsigned char *)ivec;
-+            }
-+            c = *(in++) ^ iv[n];
-+            *(out++) = c;
-+            iv[n] = c;
-+            n = (n + 1) & 0x07;
-+        }
-+    } else {
-+        while (l--) {
-+            if (n == 0) {
-+                c2l(iv, v0);
-+                ti[0] = v0;
-+                c2l(iv, v1);
-+                ti[1] = v1;
-+                RC5_32_encrypt((unsigned long *)ti, schedule);
-+                iv = (unsigned char *)ivec;
-+                t = ti[0];
-+                l2c(t, iv);
-+                t = ti[1];
-+                l2c(t, iv);
-+                iv = (unsigned char *)ivec;
-+            }
-+            cc = *(in++);
-+            c = iv[n];
-+            iv[n] = cc;
-+            *(out++) = c ^ cc;
-+            n = (n + 1) & 0x07;
-+        }
-+    }
-+    v0 = v1 = ti[0] = ti[1] = t = c = cc = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5ofb64.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5ofb64.c
-new file mode 100644
-index 0000000..3a41d77
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rc5/rc5ofb64.c
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rc5_locl.h"
-+
-+/*
-+ * The input and output encrypted as though 64bit ofb mode is being used.
-+ * The extra state information to record how much of the 64bit block we have
-+ * used is contained in *num;
-+ */
-+void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out,
-+                          long length, RC5_32_KEY *schedule,
-+                          unsigned char *ivec, int *num)
-+{
-+    register unsigned long v0, v1, t;
-+    register int n = *num;
-+    register long l = length;
-+    unsigned char d[8];
-+    register char *dp;
-+    unsigned long ti[2];
-+    unsigned char *iv;
-+    int save = 0;
-+
-+    iv = (unsigned char *)ivec;
-+    c2l(iv, v0);
-+    c2l(iv, v1);
-+    ti[0] = v0;
-+    ti[1] = v1;
-+    dp = (char *)d;
-+    l2c(v0, dp);
-+    l2c(v1, dp);
-+    while (l--) {
-+        if (n == 0) {
-+            RC5_32_encrypt((unsigned long *)ti, schedule);
-+            dp = (char *)d;
-+            t = ti[0];
-+            l2c(t, dp);
-+            t = ti[1];
-+            l2c(t, dp);
-+            save++;
-+        }
-+        *(out++) = *(in++) ^ d[n];
-+        n = (n + 1) & 0x07;
-+    }
-+    if (save) {
-+        v0 = ti[0];
-+        v1 = ti[1];
-+        iv = (unsigned char *)ivec;
-+        l2c(v0, iv);
-+        l2c(v1, iv);
-+    }
-+    t = v0 = v1 = ti[0] = ti[1] = 0;
-+    *num = n;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/asm/rmd-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/asm/rmd-586.pl
-new file mode 100644
-index 0000000..544c496
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/asm/rmd-586.pl
-@@ -0,0 +1,603 @@
-+#! /usr/bin/env perl
-+# Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# Normal is the
-+# ripemd160_block_asm_data_order(RIPEMD160_CTX *c, ULONG *X,int blocks);
-+
-+$normal=0;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],$0);
-+
-+$A="ecx";
-+$B="esi";
-+$C="edi";
-+$D="ebx";
-+$E="ebp";
-+$tmp1="eax";
-+$tmp2="edx";
-+
-+$KL1=0x5A827999;
-+$KL2=0x6ED9EBA1;
-+$KL3=0x8F1BBCDC;
-+$KL4=0xA953FD4E;
-+$KR0=0x50A28BE6;
-+$KR1=0x5C4DD124; 
-+$KR2=0x6D703EF3;
-+$KR3=0x7A6D76E9;
-+
-+
-+@wl=(	 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
-+	 7, 4,13, 1,10, 6,15, 3,12, 0, 9, 5, 2,14,11, 8,
-+	 3,10,14, 4, 9,15, 8, 1, 2, 7, 0, 6,13,11, 5,12,
-+	 1, 9,11,10, 0, 8,12, 4,13, 3, 7,15,14, 5, 6, 2,
-+	 4, 0, 5, 9, 7,12, 2,10,14, 1, 3, 8,11, 6,15,13,
-+	 );
-+
-+@wr=(	 5,14, 7, 0, 9, 2,11, 4,13, 6,15, 8, 1,10, 3,12,
-+	 6,11, 3, 7, 0,13, 5,10,14,15, 8,12, 4, 9, 1, 2,
-+	15, 5, 1, 3, 7,14, 6, 9,11, 8,12, 2,10, 0, 4,13,
-+	 8, 6, 4, 1, 3,11,15, 0, 5,12, 2,13, 9, 7,10,14,
-+	12,15,10, 4, 1, 5, 8, 7, 6, 2,13,14, 0, 3, 9,11,
-+	);
-+
-+@sl=(	11,14,15,12, 5, 8, 7, 9,11,13,14,15, 6, 7, 9, 8,
-+	 7, 6, 8,13,11, 9, 7,15, 7,12,15, 9,11, 7,13,12,
-+	11,13, 6, 7,14, 9,13,15,14, 8,13, 6, 5,12, 7, 5,
-+	11,12,14,15,14,15, 9, 8, 9,14, 5, 6, 8, 6, 5,12,
-+	 9,15, 5,11, 6, 8,13,12, 5,12,13,14,11, 8, 5, 6,
-+	 );
-+
-+@sr=(	 8, 9, 9,11,13,15,15, 5, 7, 7, 8,11,14,14,12, 6,
-+	 9,13,15, 7,12, 8, 9,11, 7, 7,12, 7, 6,15,13,11,
-+	 9, 7,15,11, 8, 6, 6,14,12,13, 5,14,13,13, 7, 5,
-+	15, 5, 8,11,14,14, 6,14, 6, 9,12, 9,12, 5,15, 8,
-+	 8, 5,12, 9,12, 5,14, 6, 8,13, 6, 5,15,13,11,11,
-+ 	);
-+
-+&ripemd160_block("ripemd160_block_asm_data_order");
-+&asm_finish();
-+
-+close STDOUT;
-+
-+sub Xv
-+	{
-+	local($n)=@_;
-+	return(&swtmp($n));
-+	# tmp on stack
-+	}
-+
-+sub Np
-+	{
-+	local($p)=@_;
-+	local(%n)=($A,$E,$B,$A,$C,$B,$D,$C,$E,$D);
-+	return($n{$p});
-+	}
-+
-+sub RIP1
-+	{
-+	local($a,$b,$c,$d,$e,$pos,$s,$o,$pos2)=@_;
-+
-+	&comment($p++);
-+	if ($p & 1)
-+		{
-+	 #&mov($tmp1,	$c) if $o == -1;
-+	&xor($tmp1,	$d) if $o == -1;
-+	 &mov($tmp2,	&Xv($pos));
-+	&xor($tmp1,	$b);
-+	 &add($a,	$tmp2);
-+	&rotl($c,	10);
-+	&add($a,	$tmp1);
-+	 &mov($tmp1,	&Np($c));	# NEXT
-+	 # XXX
-+	&rotl($a,	$s);
-+	&add($a,	$e);
-+		}
-+	else
-+		{
-+	 &xor($tmp1,	$d);
-+	&mov($tmp2,	&Xv($pos));
-+	 &xor($tmp1,	$b);
-+	&add($a,	$tmp1);
-+	 &mov($tmp1,	&Np($c)) if $o <= 0;
-+	 &mov($tmp1,	-1) if $o == 1;
-+	 # XXX if $o == 2;
-+	&rotl($c,	10);
-+	&add($a,	$tmp2);
-+	 &xor($tmp1,	&Np($d)) if $o <= 0;
-+	 &mov($tmp2,	&Xv($pos2)) if $o == 1;
-+	 &mov($tmp2,	&wparam(0)) if $o == 2;
-+	&rotl($a,	$s);
-+	&add($a,	$e);
-+		}
-+	}
-+
-+sub RIP2
-+	{
-+	local($a,$b,$c,$d,$e,$pos,$pos2,$s,$K,$o)=@_;
-+
-+# XXXXXX
-+	&comment($p++);
-+	if ($p & 1)
-+		{
-+#	 &mov($tmp2,	&Xv($pos)) if $o < -1;
-+#	&mov($tmp1,	-1) if $o < -1;
-+
-+	 &add($a,	$tmp2);
-+	&mov($tmp2,	$c);
-+	 &sub($tmp1,	$b);
-+	&and($tmp2,	$b);
-+	 &and($tmp1,	$d);
-+	&or($tmp2,	$tmp1);
-+	 &mov($tmp1,	&Xv($pos2)) if $o <= 0; # XXXXXXXXXXXXXX
-+	 # XXX
-+	&rotl($c,	10);
-+	&lea($a,	&DWP($K,$a,$tmp2,1));
-+	 &mov($tmp2,	-1) if $o <= 0;
-+	 # XXX
-+	&rotl($a,	$s);
-+	&add($a,	$e);
-+		}
-+	else
-+		{
-+	 # XXX
-+	 &add($a,	$tmp1);
-+	&mov($tmp1,	$c);
-+	 &sub($tmp2,	$b);
-+	&and($tmp1,	$b);
-+	 &and($tmp2,	$d);
-+	if ($o != 2)
-+		{
-+	&or($tmp1,	$tmp2);
-+	 &mov($tmp2,	&Xv($pos2)) if $o <= 0;
-+	 &mov($tmp2,	-1) if $o == 1;
-+	&rotl($c,	10);
-+	&lea($a,	&DWP($K,$a,$tmp1,1));
-+	 &mov($tmp1,	-1) if $o <= 0;
-+	 &sub($tmp2,	&Np($c)) if $o == 1;
-+		} else {
-+	&or($tmp2,	$tmp1);
-+	 &mov($tmp1,	&Np($c));
-+	&rotl($c,	10);
-+	&lea($a,	&DWP($K,$a,$tmp2,1));
-+	 &xor($tmp1,	&Np($d));
-+		}
-+	&rotl($a,	$s);
-+	&add($a,	$e);
-+		}
-+	}
-+
-+sub RIP3
-+	{
-+	local($a,$b,$c,$d,$e,$pos,$s,$K,$o,$pos2)=@_;
-+
-+	&comment($p++);
-+	if ($p & 1)
-+		{
-+#	 &mov($tmp2,	-1) if $o < -1;
-+#	&sub($tmp2,	$c) if $o < -1;
-+	 &mov($tmp1,	&Xv($pos));
-+	&or($tmp2,	$b);
-+	 &add($a,	$tmp1);
-+	&xor($tmp2,	$d);
-+	 &mov($tmp1,	-1) if $o <= 0;		# NEXT
-+	 # XXX
-+	&rotl($c,	10);
-+	&lea($a,	&DWP($K,$a,$tmp2,1));
-+	 &sub($tmp1,	&Np($c)) if $o <= 0;	# NEXT
-+	 # XXX
-+	&rotl($a,	$s);
-+	&add($a,	$e);
-+		}
-+	else
-+		{
-+	 &mov($tmp2,	&Xv($pos));
-+	&or($tmp1,	$b);
-+	 &add($a,	$tmp2);
-+	&xor($tmp1,	$d);
-+	 &mov($tmp2,	-1) if $o <= 0;		# NEXT
-+	 &mov($tmp2,	-1) if $o == 1;
-+	 &mov($tmp2,	&Xv($pos2)) if $o == 2;
-+	&rotl($c,	10);
-+	&lea($a,	&DWP($K,$a,$tmp1,1));
-+	 &sub($tmp2,	&Np($c)) if $o <= 0;	# NEXT
-+	 &mov($tmp1,	&Np($d)) if $o == 1;
-+	 &mov($tmp1,	-1) if $o == 2;
-+	&rotl($a,	$s);
-+	&add($a,	$e);
-+		}
-+	}
-+
-+sub RIP4
-+	{
-+	local($a,$b,$c,$d,$e,$pos,$s,$K,$o)=@_;
-+
-+	&comment($p++);
-+	if ($p & 1)
-+		{
-+#	 &mov($tmp2,	-1) if $o == -2;
-+#	&mov($tmp1,	$d) if $o == -2;
-+	 &sub($tmp2,	$d);
-+	&and($tmp1,	$b);
-+	 &and($tmp2,	$c);
-+	&or($tmp2,	$tmp1);
-+	 &mov($tmp1,	&Xv($pos));
-+	&rotl($c,	10);
-+	&lea($a,	&DWP($K,$a,$tmp2));
-+	 &mov($tmp2,	-1) unless $o > 0;	# NEXT
-+	 # XXX
-+	&add($a,	$tmp1);
-+	 &mov($tmp1,	&Np($d)) unless $o > 0; # NEXT
-+	 # XXX
-+	&rotl($a,	$s);
-+	&add($a,	$e);
-+		}
-+	else
-+		{
-+	 &sub($tmp2,	$d);
-+	&and($tmp1,	$b);
-+	 &and($tmp2,	$c);
-+	&or($tmp2,	$tmp1);
-+	 &mov($tmp1,	&Xv($pos));
-+	&rotl($c,	10);
-+	&lea($a,	&DWP($K,$a,$tmp2));
-+	 &mov($tmp2,	-1) if $o == 0;	# NEXT
-+	 &mov($tmp2,	-1) if $o == 1;
-+	 &mov($tmp2,	-1) if $o == 2;
-+	 # XXX
-+	&add($a,	$tmp1);
-+	 &mov($tmp1,	&Np($d)) if $o == 0;	# NEXT
-+	 &sub($tmp2,	&Np($d)) if $o == 1;
-+	 &sub($tmp2,	&Np($c)) if $o == 2;
-+	 # XXX
-+	&rotl($a,	$s);
-+	&add($a,	$e);
-+		}
-+	}
-+
-+sub RIP5
-+	{
-+	local($a,$b,$c,$d,$e,$pos,$s,$K,$o)=@_;
-+
-+	&comment($p++);
-+	if ($p & 1)
-+		{
-+	 &mov($tmp2,	-1) if $o == -2;
-+	&sub($tmp2,	$d) if $o == -2;
-+	 &mov($tmp1,	&Xv($pos));
-+	&or($tmp2,	$c);
-+	 &add($a,	$tmp1);
-+	&xor($tmp2,	$b);
-+	 &mov($tmp1,	-1) if $o <= 0;
-+	 # XXX
-+	&rotl($c,	10);
-+	&lea($a,	&DWP($K,$a,$tmp2,1));
-+	 &sub($tmp1,	&Np($d)) if $o <= 0;
-+	 # XXX
-+	&rotl($a,	$s);
-+	&add($a,	$e);
-+		}
-+	else
-+		{
-+	 &mov($tmp2,	&Xv($pos));
-+	&or($tmp1,	$c);
-+	 &add($a,	$tmp2);
-+	&xor($tmp1,	$b);
-+	 &mov($tmp2,	-1) if $o <= 0;
-+	 &mov($tmp2,	&wparam(0)) if $o == 1;	# Middle code
-+	 &mov($tmp2,	-1) if $o == 2;
-+	&rotl($c,	10);
-+	&lea($a,	&DWP($K,$a,$tmp1,1));
-+	 &sub($tmp2,	&Np($d)) if $o <= 0;
-+	 &mov(&swtmp(16),	$A) if $o == 1;
-+	 &mov($tmp1,	&Np($d)) if $o == 2;
-+	&rotl($a,	$s);
-+	&add($a,	$e);
-+		}
-+	}
-+
-+sub ripemd160_block
-+	{
-+	local($name)=@_;
-+
-+	&function_begin_B($name,"",3);
-+
-+	# parameter 1 is the RIPEMD160_CTX structure.
-+	# A	0
-+	# B	4
-+	# C	8
-+	# D 	12
-+	# E 	16
-+
-+	&mov($tmp2,	&wparam(0));
-+	 &mov($tmp1,	&wparam(1));
-+	&push("esi");
-+	 &mov($A,	&DWP( 0,$tmp2,"",0));
-+	&push("edi");
-+	 &mov($B,	&DWP( 4,$tmp2,"",0));
-+	&push("ebp");
-+	 &mov($C,	&DWP( 8,$tmp2,"",0));
-+	&push("ebx");
-+	 &stack_push(16+5+6);
-+			  # Special comment about the figure of 6.
-+			  # Idea is to pad the current frame so
-+			  # that the top of the stack gets fairly
-+			  # aligned. Well, as you realize it would
-+			  # always depend on how the frame below is
-+			  # aligned. The good news are that gcc-2.95
-+			  # and later does keep first argument at
-+			  # least double-wise aligned.
-+			  #			
-+
-+	&set_label("start") unless $normal;
-+	&comment("");
-+
-+	# &mov($tmp1,	&wparam(1)); # Done at end of loop
-+	# &mov($tmp2,	&wparam(0)); # Done at end of loop
-+
-+	for ($z=0; $z<16; $z+=2)
-+		{
-+		&mov($D,		&DWP( $z*4,$tmp1,"",0));
-+		 &mov($E,		&DWP( ($z+1)*4,$tmp1,"",0));
-+		&mov(&swtmp($z),	$D);
-+		 &mov(&swtmp($z+1),	$E);
-+		}
-+	&mov($tmp1,	$C);
-+	 &mov($D,	&DWP(12,$tmp2,"",0));
-+	&mov($E,	&DWP(16,$tmp2,"",0));
-+
-+	&RIP1($A,$B,$C,$D,$E,$wl[ 0],$sl[ 0],-1);
-+	&RIP1($E,$A,$B,$C,$D,$wl[ 1],$sl[ 1],0);
-+	&RIP1($D,$E,$A,$B,$C,$wl[ 2],$sl[ 2],0);
-+	&RIP1($C,$D,$E,$A,$B,$wl[ 3],$sl[ 3],0);
-+	&RIP1($B,$C,$D,$E,$A,$wl[ 4],$sl[ 4],0);
-+	&RIP1($A,$B,$C,$D,$E,$wl[ 5],$sl[ 5],0);
-+	&RIP1($E,$A,$B,$C,$D,$wl[ 6],$sl[ 6],0);
-+	&RIP1($D,$E,$A,$B,$C,$wl[ 7],$sl[ 7],0);
-+	&RIP1($C,$D,$E,$A,$B,$wl[ 8],$sl[ 8],0);
-+	&RIP1($B,$C,$D,$E,$A,$wl[ 9],$sl[ 9],0);
-+	&RIP1($A,$B,$C,$D,$E,$wl[10],$sl[10],0);
-+	&RIP1($E,$A,$B,$C,$D,$wl[11],$sl[11],0);
-+	&RIP1($D,$E,$A,$B,$C,$wl[12],$sl[12],0);
-+	&RIP1($C,$D,$E,$A,$B,$wl[13],$sl[13],0);
-+	&RIP1($B,$C,$D,$E,$A,$wl[14],$sl[14],0);
-+	&RIP1($A,$B,$C,$D,$E,$wl[15],$sl[15],1,$wl[16]);
-+
-+	&RIP2($E,$A,$B,$C,$D,$wl[16],$wl[17],$sl[16],$KL1,-1);
-+	&RIP2($D,$E,$A,$B,$C,$wl[17],$wl[18],$sl[17],$KL1,0);
-+	&RIP2($C,$D,$E,$A,$B,$wl[18],$wl[19],$sl[18],$KL1,0);
-+	&RIP2($B,$C,$D,$E,$A,$wl[19],$wl[20],$sl[19],$KL1,0);
-+	&RIP2($A,$B,$C,$D,$E,$wl[20],$wl[21],$sl[20],$KL1,0);
-+	&RIP2($E,$A,$B,$C,$D,$wl[21],$wl[22],$sl[21],$KL1,0);
-+	&RIP2($D,$E,$A,$B,$C,$wl[22],$wl[23],$sl[22],$KL1,0);
-+	&RIP2($C,$D,$E,$A,$B,$wl[23],$wl[24],$sl[23],$KL1,0);
-+	&RIP2($B,$C,$D,$E,$A,$wl[24],$wl[25],$sl[24],$KL1,0);
-+	&RIP2($A,$B,$C,$D,$E,$wl[25],$wl[26],$sl[25],$KL1,0);
-+	&RIP2($E,$A,$B,$C,$D,$wl[26],$wl[27],$sl[26],$KL1,0);
-+	&RIP2($D,$E,$A,$B,$C,$wl[27],$wl[28],$sl[27],$KL1,0);
-+	&RIP2($C,$D,$E,$A,$B,$wl[28],$wl[29],$sl[28],$KL1,0);
-+	&RIP2($B,$C,$D,$E,$A,$wl[29],$wl[30],$sl[29],$KL1,0);
-+	&RIP2($A,$B,$C,$D,$E,$wl[30],$wl[31],$sl[30],$KL1,0);
-+	&RIP2($E,$A,$B,$C,$D,$wl[31],$wl[32],$sl[31],$KL1,1);
-+
-+	&RIP3($D,$E,$A,$B,$C,$wl[32],$sl[32],$KL2,-1);
-+	&RIP3($C,$D,$E,$A,$B,$wl[33],$sl[33],$KL2,0);
-+	&RIP3($B,$C,$D,$E,$A,$wl[34],$sl[34],$KL2,0);
-+	&RIP3($A,$B,$C,$D,$E,$wl[35],$sl[35],$KL2,0);
-+	&RIP3($E,$A,$B,$C,$D,$wl[36],$sl[36],$KL2,0);
-+	&RIP3($D,$E,$A,$B,$C,$wl[37],$sl[37],$KL2,0);
-+	&RIP3($C,$D,$E,$A,$B,$wl[38],$sl[38],$KL2,0);
-+	&RIP3($B,$C,$D,$E,$A,$wl[39],$sl[39],$KL2,0);
-+	&RIP3($A,$B,$C,$D,$E,$wl[40],$sl[40],$KL2,0);
-+	&RIP3($E,$A,$B,$C,$D,$wl[41],$sl[41],$KL2,0);
-+	&RIP3($D,$E,$A,$B,$C,$wl[42],$sl[42],$KL2,0);
-+	&RIP3($C,$D,$E,$A,$B,$wl[43],$sl[43],$KL2,0);
-+	&RIP3($B,$C,$D,$E,$A,$wl[44],$sl[44],$KL2,0);
-+	&RIP3($A,$B,$C,$D,$E,$wl[45],$sl[45],$KL2,0);
-+	&RIP3($E,$A,$B,$C,$D,$wl[46],$sl[46],$KL2,0);
-+	&RIP3($D,$E,$A,$B,$C,$wl[47],$sl[47],$KL2,1);
-+
-+	&RIP4($C,$D,$E,$A,$B,$wl[48],$sl[48],$KL3,-1);
-+	&RIP4($B,$C,$D,$E,$A,$wl[49],$sl[49],$KL3,0);
-+	&RIP4($A,$B,$C,$D,$E,$wl[50],$sl[50],$KL3,0);
-+	&RIP4($E,$A,$B,$C,$D,$wl[51],$sl[51],$KL3,0);
-+	&RIP4($D,$E,$A,$B,$C,$wl[52],$sl[52],$KL3,0);
-+	&RIP4($C,$D,$E,$A,$B,$wl[53],$sl[53],$KL3,0);
-+	&RIP4($B,$C,$D,$E,$A,$wl[54],$sl[54],$KL3,0);
-+	&RIP4($A,$B,$C,$D,$E,$wl[55],$sl[55],$KL3,0);
-+	&RIP4($E,$A,$B,$C,$D,$wl[56],$sl[56],$KL3,0);
-+	&RIP4($D,$E,$A,$B,$C,$wl[57],$sl[57],$KL3,0);
-+	&RIP4($C,$D,$E,$A,$B,$wl[58],$sl[58],$KL3,0);
-+	&RIP4($B,$C,$D,$E,$A,$wl[59],$sl[59],$KL3,0);
-+	&RIP4($A,$B,$C,$D,$E,$wl[60],$sl[60],$KL3,0);
-+	&RIP4($E,$A,$B,$C,$D,$wl[61],$sl[61],$KL3,0);
-+	&RIP4($D,$E,$A,$B,$C,$wl[62],$sl[62],$KL3,0);
-+	&RIP4($C,$D,$E,$A,$B,$wl[63],$sl[63],$KL3,1);
-+
-+	&RIP5($B,$C,$D,$E,$A,$wl[64],$sl[64],$KL4,-1);
-+	&RIP5($A,$B,$C,$D,$E,$wl[65],$sl[65],$KL4,0);
-+	&RIP5($E,$A,$B,$C,$D,$wl[66],$sl[66],$KL4,0);
-+	&RIP5($D,$E,$A,$B,$C,$wl[67],$sl[67],$KL4,0);
-+	&RIP5($C,$D,$E,$A,$B,$wl[68],$sl[68],$KL4,0);
-+	&RIP5($B,$C,$D,$E,$A,$wl[69],$sl[69],$KL4,0);
-+	&RIP5($A,$B,$C,$D,$E,$wl[70],$sl[70],$KL4,0);
-+	&RIP5($E,$A,$B,$C,$D,$wl[71],$sl[71],$KL4,0);
-+	&RIP5($D,$E,$A,$B,$C,$wl[72],$sl[72],$KL4,0);
-+	&RIP5($C,$D,$E,$A,$B,$wl[73],$sl[73],$KL4,0);
-+	&RIP5($B,$C,$D,$E,$A,$wl[74],$sl[74],$KL4,0);
-+	&RIP5($A,$B,$C,$D,$E,$wl[75],$sl[75],$KL4,0);
-+	&RIP5($E,$A,$B,$C,$D,$wl[76],$sl[76],$KL4,0);
-+	&RIP5($D,$E,$A,$B,$C,$wl[77],$sl[77],$KL4,0);
-+	&RIP5($C,$D,$E,$A,$B,$wl[78],$sl[78],$KL4,0);
-+	&RIP5($B,$C,$D,$E,$A,$wl[79],$sl[79],$KL4,1);
-+
-+	# &mov($tmp2,	&wparam(0)); # moved into last RIP5
-+	# &mov(&swtmp(16),	$A);
-+	 &mov($A,	&DWP( 0,$tmp2,"",0));
-+	&mov(&swtmp(16+1),	$B);
-+	 &mov(&swtmp(16+2),	$C);
-+	&mov($B,	&DWP( 4,$tmp2,"",0));
-+	 &mov(&swtmp(16+3),	$D);
-+	&mov($C,	&DWP( 8,$tmp2,"",0));
-+	 &mov(&swtmp(16+4),	$E);
-+	&mov($D,	&DWP(12,$tmp2,"",0));
-+	 &mov($E,	&DWP(16,$tmp2,"",0));
-+
-+	&RIP5($A,$B,$C,$D,$E,$wr[ 0],$sr[ 0],$KR0,-2);
-+	&RIP5($E,$A,$B,$C,$D,$wr[ 1],$sr[ 1],$KR0,0);
-+	&RIP5($D,$E,$A,$B,$C,$wr[ 2],$sr[ 2],$KR0,0);
-+	&RIP5($C,$D,$E,$A,$B,$wr[ 3],$sr[ 3],$KR0,0);
-+	&RIP5($B,$C,$D,$E,$A,$wr[ 4],$sr[ 4],$KR0,0);
-+	&RIP5($A,$B,$C,$D,$E,$wr[ 5],$sr[ 5],$KR0,0);
-+	&RIP5($E,$A,$B,$C,$D,$wr[ 6],$sr[ 6],$KR0,0);
-+	&RIP5($D,$E,$A,$B,$C,$wr[ 7],$sr[ 7],$KR0,0);
-+	&RIP5($C,$D,$E,$A,$B,$wr[ 8],$sr[ 8],$KR0,0);
-+	&RIP5($B,$C,$D,$E,$A,$wr[ 9],$sr[ 9],$KR0,0);
-+	&RIP5($A,$B,$C,$D,$E,$wr[10],$sr[10],$KR0,0);
-+	&RIP5($E,$A,$B,$C,$D,$wr[11],$sr[11],$KR0,0);
-+	&RIP5($D,$E,$A,$B,$C,$wr[12],$sr[12],$KR0,0);
-+	&RIP5($C,$D,$E,$A,$B,$wr[13],$sr[13],$KR0,0);
-+	&RIP5($B,$C,$D,$E,$A,$wr[14],$sr[14],$KR0,0);
-+	&RIP5($A,$B,$C,$D,$E,$wr[15],$sr[15],$KR0,2);
-+
-+	&RIP4($E,$A,$B,$C,$D,$wr[16],$sr[16],$KR1,-2);
-+	&RIP4($D,$E,$A,$B,$C,$wr[17],$sr[17],$KR1,0);
-+	&RIP4($C,$D,$E,$A,$B,$wr[18],$sr[18],$KR1,0);
-+	&RIP4($B,$C,$D,$E,$A,$wr[19],$sr[19],$KR1,0);
-+	&RIP4($A,$B,$C,$D,$E,$wr[20],$sr[20],$KR1,0);
-+	&RIP4($E,$A,$B,$C,$D,$wr[21],$sr[21],$KR1,0);
-+	&RIP4($D,$E,$A,$B,$C,$wr[22],$sr[22],$KR1,0);
-+	&RIP4($C,$D,$E,$A,$B,$wr[23],$sr[23],$KR1,0);
-+	&RIP4($B,$C,$D,$E,$A,$wr[24],$sr[24],$KR1,0);
-+	&RIP4($A,$B,$C,$D,$E,$wr[25],$sr[25],$KR1,0);
-+	&RIP4($E,$A,$B,$C,$D,$wr[26],$sr[26],$KR1,0);
-+	&RIP4($D,$E,$A,$B,$C,$wr[27],$sr[27],$KR1,0);
-+	&RIP4($C,$D,$E,$A,$B,$wr[28],$sr[28],$KR1,0);
-+	&RIP4($B,$C,$D,$E,$A,$wr[29],$sr[29],$KR1,0);
-+	&RIP4($A,$B,$C,$D,$E,$wr[30],$sr[30],$KR1,0);
-+	&RIP4($E,$A,$B,$C,$D,$wr[31],$sr[31],$KR1,2);
-+
-+	&RIP3($D,$E,$A,$B,$C,$wr[32],$sr[32],$KR2,-2);
-+	&RIP3($C,$D,$E,$A,$B,$wr[33],$sr[33],$KR2,0);
-+	&RIP3($B,$C,$D,$E,$A,$wr[34],$sr[34],$KR2,0);
-+	&RIP3($A,$B,$C,$D,$E,$wr[35],$sr[35],$KR2,0);
-+	&RIP3($E,$A,$B,$C,$D,$wr[36],$sr[36],$KR2,0);
-+	&RIP3($D,$E,$A,$B,$C,$wr[37],$sr[37],$KR2,0);
-+	&RIP3($C,$D,$E,$A,$B,$wr[38],$sr[38],$KR2,0);
-+	&RIP3($B,$C,$D,$E,$A,$wr[39],$sr[39],$KR2,0);
-+	&RIP3($A,$B,$C,$D,$E,$wr[40],$sr[40],$KR2,0);
-+	&RIP3($E,$A,$B,$C,$D,$wr[41],$sr[41],$KR2,0);
-+	&RIP3($D,$E,$A,$B,$C,$wr[42],$sr[42],$KR2,0);
-+	&RIP3($C,$D,$E,$A,$B,$wr[43],$sr[43],$KR2,0);
-+	&RIP3($B,$C,$D,$E,$A,$wr[44],$sr[44],$KR2,0);
-+	&RIP3($A,$B,$C,$D,$E,$wr[45],$sr[45],$KR2,0);
-+	&RIP3($E,$A,$B,$C,$D,$wr[46],$sr[46],$KR2,0);
-+	&RIP3($D,$E,$A,$B,$C,$wr[47],$sr[47],$KR2,2,$wr[48]);
-+
-+	&RIP2($C,$D,$E,$A,$B,$wr[48],$wr[49],$sr[48],$KR3,-2);
-+	&RIP2($B,$C,$D,$E,$A,$wr[49],$wr[50],$sr[49],$KR3,0);
-+	&RIP2($A,$B,$C,$D,$E,$wr[50],$wr[51],$sr[50],$KR3,0);
-+	&RIP2($E,$A,$B,$C,$D,$wr[51],$wr[52],$sr[51],$KR3,0);
-+	&RIP2($D,$E,$A,$B,$C,$wr[52],$wr[53],$sr[52],$KR3,0);
-+	&RIP2($C,$D,$E,$A,$B,$wr[53],$wr[54],$sr[53],$KR3,0);
-+	&RIP2($B,$C,$D,$E,$A,$wr[54],$wr[55],$sr[54],$KR3,0);
-+	&RIP2($A,$B,$C,$D,$E,$wr[55],$wr[56],$sr[55],$KR3,0);
-+	&RIP2($E,$A,$B,$C,$D,$wr[56],$wr[57],$sr[56],$KR3,0);
-+	&RIP2($D,$E,$A,$B,$C,$wr[57],$wr[58],$sr[57],$KR3,0);
-+	&RIP2($C,$D,$E,$A,$B,$wr[58],$wr[59],$sr[58],$KR3,0);
-+	&RIP2($B,$C,$D,$E,$A,$wr[59],$wr[60],$sr[59],$KR3,0);
-+	&RIP2($A,$B,$C,$D,$E,$wr[60],$wr[61],$sr[60],$KR3,0);
-+	&RIP2($E,$A,$B,$C,$D,$wr[61],$wr[62],$sr[61],$KR3,0);
-+	&RIP2($D,$E,$A,$B,$C,$wr[62],$wr[63],$sr[62],$KR3,0);
-+	&RIP2($C,$D,$E,$A,$B,$wr[63],$wr[64],$sr[63],$KR3,2);
-+
-+	&RIP1($B,$C,$D,$E,$A,$wr[64],$sr[64],-2);
-+	&RIP1($A,$B,$C,$D,$E,$wr[65],$sr[65],0);
-+	&RIP1($E,$A,$B,$C,$D,$wr[66],$sr[66],0);
-+	&RIP1($D,$E,$A,$B,$C,$wr[67],$sr[67],0);
-+	&RIP1($C,$D,$E,$A,$B,$wr[68],$sr[68],0);
-+	&RIP1($B,$C,$D,$E,$A,$wr[69],$sr[69],0);
-+	&RIP1($A,$B,$C,$D,$E,$wr[70],$sr[70],0);
-+	&RIP1($E,$A,$B,$C,$D,$wr[71],$sr[71],0);
-+	&RIP1($D,$E,$A,$B,$C,$wr[72],$sr[72],0);
-+	&RIP1($C,$D,$E,$A,$B,$wr[73],$sr[73],0);
-+	&RIP1($B,$C,$D,$E,$A,$wr[74],$sr[74],0);
-+	&RIP1($A,$B,$C,$D,$E,$wr[75],$sr[75],0);
-+	&RIP1($E,$A,$B,$C,$D,$wr[76],$sr[76],0);
-+	&RIP1($D,$E,$A,$B,$C,$wr[77],$sr[77],0);
-+	&RIP1($C,$D,$E,$A,$B,$wr[78],$sr[78],0);
-+	&RIP1($B,$C,$D,$E,$A,$wr[79],$sr[79],2);
-+
-+	# &mov($tmp2,	&wparam(0)); # Moved into last round
-+
-+	 &mov($tmp1,	&DWP( 4,$tmp2,"",0));	# ctx->B
-+ 	&add($D,	$tmp1);	
-+	 &mov($tmp1,	&swtmp(16+2));		# $c
-+	&add($D,	$tmp1);
-+
-+	 &mov($tmp1,	&DWP( 8,$tmp2,"",0));	# ctx->C
-+	&add($E,	$tmp1);	
-+	 &mov($tmp1,	&swtmp(16+3));		# $d
-+	&add($E,	$tmp1);
-+
-+	 &mov($tmp1,	&DWP(12,$tmp2,"",0));	# ctx->D
-+	&add($A,	$tmp1);	
-+	 &mov($tmp1,	&swtmp(16+4));		# $e
-+	&add($A,	$tmp1);
-+
-+
-+	 &mov($tmp1,	&DWP(16,$tmp2,"",0));	# ctx->E
-+	&add($B,	$tmp1);	
-+	 &mov($tmp1,	&swtmp(16+0));		# $a
-+	&add($B,	$tmp1);
-+
-+	 &mov($tmp1,	&DWP( 0,$tmp2,"",0));	# ctx->A
-+	&add($C,	$tmp1);	
-+	 &mov($tmp1,	&swtmp(16+1));		# $b
-+	&add($C,	$tmp1);
-+
-+	 &mov($tmp1,	&wparam(2));
-+
-+	&mov(&DWP( 0,$tmp2,"",0),	$D);
-+	 &mov(&DWP( 4,$tmp2,"",0),	$E);
-+	&mov(&DWP( 8,$tmp2,"",0),	$A);
-+	 &sub($tmp1,1);
-+	&mov(&DWP(12,$tmp2,"",0),	$B);
-+	 &mov(&DWP(16,$tmp2,"",0),	$C);
-+
-+	&jle(&label("get_out"));
-+
-+	&mov(&wparam(2),$tmp1);
-+	 &mov($C,	$A);
-+	&mov($tmp1,	&wparam(1));
-+	 &mov($A,	$D);
-+	&add($tmp1,	64);
-+	 &mov($B,	$E);
-+	&mov(&wparam(1),$tmp1);
-+
-+	&jmp(&label("start"));
-+
-+	&set_label("get_out");
-+
-+	&stack_pop(16+5+6);
-+
-+	&pop("ebx");
-+	&pop("ebp");
-+	&pop("edi");
-+	&pop("esi");
-+	&ret();
-+	&function_end_B($name);
-+	}
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/build.info
-new file mode 100644
-index 0000000..c45050c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/build.info
-@@ -0,0 +1,6 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        rmd_dgst.c rmd_one.c {- $target{rmd160_asm_src} -}
-+
-+GENERATE[rmd-586.s]=asm/rmd-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS)
-+DEPEND[rmd-586.s]=../perlasm/x86asm.pl
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_dgst.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_dgst.c
-new file mode 100644
-index 0000000..a1670c7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_dgst.c
-@@ -0,0 +1,282 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rmd_locl.h"
-+#include 
-+
-+#ifdef RMD160_ASM
-+void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p, size_t num);
-+# define ripemd160_block ripemd160_block_x86
-+#else
-+void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p, size_t num);
-+#endif
-+
-+int RIPEMD160_Init(RIPEMD160_CTX *c)
-+{
-+    memset(c, 0, sizeof(*c));
-+    c->A = RIPEMD160_A;
-+    c->B = RIPEMD160_B;
-+    c->C = RIPEMD160_C;
-+    c->D = RIPEMD160_D;
-+    c->E = RIPEMD160_E;
-+    return 1;
-+}
-+
-+#ifndef ripemd160_block_data_order
-+# ifdef X
-+#  undef X
-+# endif
-+void ripemd160_block_data_order(RIPEMD160_CTX *ctx, const void *p, size_t num)
-+{
-+    const unsigned char *data = p;
-+    register unsigned MD32_REG_T A, B, C, D, E;
-+    unsigned MD32_REG_T a, b, c, d, e, l;
-+# ifndef MD32_XARRAY
-+    /* See comment in crypto/sha/sha_locl.h for details. */
-+    unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
-+        XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
-+#  define X(i)   XX##i
-+# else
-+    RIPEMD160_LONG XX[16];
-+#  define X(i)   XX[i]
-+# endif
-+
-+    for (; num--;) {
-+
-+        A = ctx->A;
-+        B = ctx->B;
-+        C = ctx->C;
-+        D = ctx->D;
-+        E = ctx->E;
-+
-+        (void)HOST_c2l(data, l);
-+        X(0) = l;
-+        (void)HOST_c2l(data, l);
-+        X(1) = l;
-+        RIP1(A, B, C, D, E, WL00, SL00);
-+        (void)HOST_c2l(data, l);
-+        X(2) = l;
-+        RIP1(E, A, B, C, D, WL01, SL01);
-+        (void)HOST_c2l(data, l);
-+        X(3) = l;
-+        RIP1(D, E, A, B, C, WL02, SL02);
-+        (void)HOST_c2l(data, l);
-+        X(4) = l;
-+        RIP1(C, D, E, A, B, WL03, SL03);
-+        (void)HOST_c2l(data, l);
-+        X(5) = l;
-+        RIP1(B, C, D, E, A, WL04, SL04);
-+        (void)HOST_c2l(data, l);
-+        X(6) = l;
-+        RIP1(A, B, C, D, E, WL05, SL05);
-+        (void)HOST_c2l(data, l);
-+        X(7) = l;
-+        RIP1(E, A, B, C, D, WL06, SL06);
-+        (void)HOST_c2l(data, l);
-+        X(8) = l;
-+        RIP1(D, E, A, B, C, WL07, SL07);
-+        (void)HOST_c2l(data, l);
-+        X(9) = l;
-+        RIP1(C, D, E, A, B, WL08, SL08);
-+        (void)HOST_c2l(data, l);
-+        X(10) = l;
-+        RIP1(B, C, D, E, A, WL09, SL09);
-+        (void)HOST_c2l(data, l);
-+        X(11) = l;
-+        RIP1(A, B, C, D, E, WL10, SL10);
-+        (void)HOST_c2l(data, l);
-+        X(12) = l;
-+        RIP1(E, A, B, C, D, WL11, SL11);
-+        (void)HOST_c2l(data, l);
-+        X(13) = l;
-+        RIP1(D, E, A, B, C, WL12, SL12);
-+        (void)HOST_c2l(data, l);
-+        X(14) = l;
-+        RIP1(C, D, E, A, B, WL13, SL13);
-+        (void)HOST_c2l(data, l);
-+        X(15) = l;
-+        RIP1(B, C, D, E, A, WL14, SL14);
-+        RIP1(A, B, C, D, E, WL15, SL15);
-+
-+        RIP2(E, A, B, C, D, WL16, SL16, KL1);
-+        RIP2(D, E, A, B, C, WL17, SL17, KL1);
-+        RIP2(C, D, E, A, B, WL18, SL18, KL1);
-+        RIP2(B, C, D, E, A, WL19, SL19, KL1);
-+        RIP2(A, B, C, D, E, WL20, SL20, KL1);
-+        RIP2(E, A, B, C, D, WL21, SL21, KL1);
-+        RIP2(D, E, A, B, C, WL22, SL22, KL1);
-+        RIP2(C, D, E, A, B, WL23, SL23, KL1);
-+        RIP2(B, C, D, E, A, WL24, SL24, KL1);
-+        RIP2(A, B, C, D, E, WL25, SL25, KL1);
-+        RIP2(E, A, B, C, D, WL26, SL26, KL1);
-+        RIP2(D, E, A, B, C, WL27, SL27, KL1);
-+        RIP2(C, D, E, A, B, WL28, SL28, KL1);
-+        RIP2(B, C, D, E, A, WL29, SL29, KL1);
-+        RIP2(A, B, C, D, E, WL30, SL30, KL1);
-+        RIP2(E, A, B, C, D, WL31, SL31, KL1);
-+
-+        RIP3(D, E, A, B, C, WL32, SL32, KL2);
-+        RIP3(C, D, E, A, B, WL33, SL33, KL2);
-+        RIP3(B, C, D, E, A, WL34, SL34, KL2);
-+        RIP3(A, B, C, D, E, WL35, SL35, KL2);
-+        RIP3(E, A, B, C, D, WL36, SL36, KL2);
-+        RIP3(D, E, A, B, C, WL37, SL37, KL2);
-+        RIP3(C, D, E, A, B, WL38, SL38, KL2);
-+        RIP3(B, C, D, E, A, WL39, SL39, KL2);
-+        RIP3(A, B, C, D, E, WL40, SL40, KL2);
-+        RIP3(E, A, B, C, D, WL41, SL41, KL2);
-+        RIP3(D, E, A, B, C, WL42, SL42, KL2);
-+        RIP3(C, D, E, A, B, WL43, SL43, KL2);
-+        RIP3(B, C, D, E, A, WL44, SL44, KL2);
-+        RIP3(A, B, C, D, E, WL45, SL45, KL2);
-+        RIP3(E, A, B, C, D, WL46, SL46, KL2);
-+        RIP3(D, E, A, B, C, WL47, SL47, KL2);
-+
-+        RIP4(C, D, E, A, B, WL48, SL48, KL3);
-+        RIP4(B, C, D, E, A, WL49, SL49, KL3);
-+        RIP4(A, B, C, D, E, WL50, SL50, KL3);
-+        RIP4(E, A, B, C, D, WL51, SL51, KL3);
-+        RIP4(D, E, A, B, C, WL52, SL52, KL3);
-+        RIP4(C, D, E, A, B, WL53, SL53, KL3);
-+        RIP4(B, C, D, E, A, WL54, SL54, KL3);
-+        RIP4(A, B, C, D, E, WL55, SL55, KL3);
-+        RIP4(E, A, B, C, D, WL56, SL56, KL3);
-+        RIP4(D, E, A, B, C, WL57, SL57, KL3);
-+        RIP4(C, D, E, A, B, WL58, SL58, KL3);
-+        RIP4(B, C, D, E, A, WL59, SL59, KL3);
-+        RIP4(A, B, C, D, E, WL60, SL60, KL3);
-+        RIP4(E, A, B, C, D, WL61, SL61, KL3);
-+        RIP4(D, E, A, B, C, WL62, SL62, KL3);
-+        RIP4(C, D, E, A, B, WL63, SL63, KL3);
-+
-+        RIP5(B, C, D, E, A, WL64, SL64, KL4);
-+        RIP5(A, B, C, D, E, WL65, SL65, KL4);
-+        RIP5(E, A, B, C, D, WL66, SL66, KL4);
-+        RIP5(D, E, A, B, C, WL67, SL67, KL4);
-+        RIP5(C, D, E, A, B, WL68, SL68, KL4);
-+        RIP5(B, C, D, E, A, WL69, SL69, KL4);
-+        RIP5(A, B, C, D, E, WL70, SL70, KL4);
-+        RIP5(E, A, B, C, D, WL71, SL71, KL4);
-+        RIP5(D, E, A, B, C, WL72, SL72, KL4);
-+        RIP5(C, D, E, A, B, WL73, SL73, KL4);
-+        RIP5(B, C, D, E, A, WL74, SL74, KL4);
-+        RIP5(A, B, C, D, E, WL75, SL75, KL4);
-+        RIP5(E, A, B, C, D, WL76, SL76, KL4);
-+        RIP5(D, E, A, B, C, WL77, SL77, KL4);
-+        RIP5(C, D, E, A, B, WL78, SL78, KL4);
-+        RIP5(B, C, D, E, A, WL79, SL79, KL4);
-+
-+        a = A;
-+        b = B;
-+        c = C;
-+        d = D;
-+        e = E;
-+        /* Do other half */
-+        A = ctx->A;
-+        B = ctx->B;
-+        C = ctx->C;
-+        D = ctx->D;
-+        E = ctx->E;
-+
-+        RIP5(A, B, C, D, E, WR00, SR00, KR0);
-+        RIP5(E, A, B, C, D, WR01, SR01, KR0);
-+        RIP5(D, E, A, B, C, WR02, SR02, KR0);
-+        RIP5(C, D, E, A, B, WR03, SR03, KR0);
-+        RIP5(B, C, D, E, A, WR04, SR04, KR0);
-+        RIP5(A, B, C, D, E, WR05, SR05, KR0);
-+        RIP5(E, A, B, C, D, WR06, SR06, KR0);
-+        RIP5(D, E, A, B, C, WR07, SR07, KR0);
-+        RIP5(C, D, E, A, B, WR08, SR08, KR0);
-+        RIP5(B, C, D, E, A, WR09, SR09, KR0);
-+        RIP5(A, B, C, D, E, WR10, SR10, KR0);
-+        RIP5(E, A, B, C, D, WR11, SR11, KR0);
-+        RIP5(D, E, A, B, C, WR12, SR12, KR0);
-+        RIP5(C, D, E, A, B, WR13, SR13, KR0);
-+        RIP5(B, C, D, E, A, WR14, SR14, KR0);
-+        RIP5(A, B, C, D, E, WR15, SR15, KR0);
-+
-+        RIP4(E, A, B, C, D, WR16, SR16, KR1);
-+        RIP4(D, E, A, B, C, WR17, SR17, KR1);
-+        RIP4(C, D, E, A, B, WR18, SR18, KR1);
-+        RIP4(B, C, D, E, A, WR19, SR19, KR1);
-+        RIP4(A, B, C, D, E, WR20, SR20, KR1);
-+        RIP4(E, A, B, C, D, WR21, SR21, KR1);
-+        RIP4(D, E, A, B, C, WR22, SR22, KR1);
-+        RIP4(C, D, E, A, B, WR23, SR23, KR1);
-+        RIP4(B, C, D, E, A, WR24, SR24, KR1);
-+        RIP4(A, B, C, D, E, WR25, SR25, KR1);
-+        RIP4(E, A, B, C, D, WR26, SR26, KR1);
-+        RIP4(D, E, A, B, C, WR27, SR27, KR1);
-+        RIP4(C, D, E, A, B, WR28, SR28, KR1);
-+        RIP4(B, C, D, E, A, WR29, SR29, KR1);
-+        RIP4(A, B, C, D, E, WR30, SR30, KR1);
-+        RIP4(E, A, B, C, D, WR31, SR31, KR1);
-+
-+        RIP3(D, E, A, B, C, WR32, SR32, KR2);
-+        RIP3(C, D, E, A, B, WR33, SR33, KR2);
-+        RIP3(B, C, D, E, A, WR34, SR34, KR2);
-+        RIP3(A, B, C, D, E, WR35, SR35, KR2);
-+        RIP3(E, A, B, C, D, WR36, SR36, KR2);
-+        RIP3(D, E, A, B, C, WR37, SR37, KR2);
-+        RIP3(C, D, E, A, B, WR38, SR38, KR2);
-+        RIP3(B, C, D, E, A, WR39, SR39, KR2);
-+        RIP3(A, B, C, D, E, WR40, SR40, KR2);
-+        RIP3(E, A, B, C, D, WR41, SR41, KR2);
-+        RIP3(D, E, A, B, C, WR42, SR42, KR2);
-+        RIP3(C, D, E, A, B, WR43, SR43, KR2);
-+        RIP3(B, C, D, E, A, WR44, SR44, KR2);
-+        RIP3(A, B, C, D, E, WR45, SR45, KR2);
-+        RIP3(E, A, B, C, D, WR46, SR46, KR2);
-+        RIP3(D, E, A, B, C, WR47, SR47, KR2);
-+
-+        RIP2(C, D, E, A, B, WR48, SR48, KR3);
-+        RIP2(B, C, D, E, A, WR49, SR49, KR3);
-+        RIP2(A, B, C, D, E, WR50, SR50, KR3);
-+        RIP2(E, A, B, C, D, WR51, SR51, KR3);
-+        RIP2(D, E, A, B, C, WR52, SR52, KR3);
-+        RIP2(C, D, E, A, B, WR53, SR53, KR3);
-+        RIP2(B, C, D, E, A, WR54, SR54, KR3);
-+        RIP2(A, B, C, D, E, WR55, SR55, KR3);
-+        RIP2(E, A, B, C, D, WR56, SR56, KR3);
-+        RIP2(D, E, A, B, C, WR57, SR57, KR3);
-+        RIP2(C, D, E, A, B, WR58, SR58, KR3);
-+        RIP2(B, C, D, E, A, WR59, SR59, KR3);
-+        RIP2(A, B, C, D, E, WR60, SR60, KR3);
-+        RIP2(E, A, B, C, D, WR61, SR61, KR3);
-+        RIP2(D, E, A, B, C, WR62, SR62, KR3);
-+        RIP2(C, D, E, A, B, WR63, SR63, KR3);
-+
-+        RIP1(B, C, D, E, A, WR64, SR64);
-+        RIP1(A, B, C, D, E, WR65, SR65);
-+        RIP1(E, A, B, C, D, WR66, SR66);
-+        RIP1(D, E, A, B, C, WR67, SR67);
-+        RIP1(C, D, E, A, B, WR68, SR68);
-+        RIP1(B, C, D, E, A, WR69, SR69);
-+        RIP1(A, B, C, D, E, WR70, SR70);
-+        RIP1(E, A, B, C, D, WR71, SR71);
-+        RIP1(D, E, A, B, C, WR72, SR72);
-+        RIP1(C, D, E, A, B, WR73, SR73);
-+        RIP1(B, C, D, E, A, WR74, SR74);
-+        RIP1(A, B, C, D, E, WR75, SR75);
-+        RIP1(E, A, B, C, D, WR76, SR76);
-+        RIP1(D, E, A, B, C, WR77, SR77);
-+        RIP1(C, D, E, A, B, WR78, SR78);
-+        RIP1(B, C, D, E, A, WR79, SR79);
-+
-+        D = ctx->B + c + D;
-+        ctx->B = ctx->C + d + E;
-+        ctx->C = ctx->D + e + A;
-+        ctx->D = ctx->E + a + B;
-+        ctx->E = ctx->A + b + C;
-+        ctx->A = D;
-+
-+    }
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_locl.h
-new file mode 100644
-index 0000000..9c5ba15
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_locl.h
-@@ -0,0 +1,88 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+/*
-+ * DO EXAMINE COMMENTS IN crypto/md5/md5_locl.h & crypto/md5/md5_dgst.c
-+ * FOR EXPLANATIONS ON FOLLOWING "CODE."
-+ *                                      
-+ */
-+#ifdef RMD160_ASM
-+# if defined(__i386) || defined(__i386__) || defined(_M_IX86)
-+#  define ripemd160_block_data_order ripemd160_block_asm_data_order
-+# endif
-+#endif
-+
-+void ripemd160_block_data_order(RIPEMD160_CTX *c, const void *p, size_t num);
-+
-+#define DATA_ORDER_IS_LITTLE_ENDIAN
-+
-+#define HASH_LONG               RIPEMD160_LONG
-+#define HASH_CTX                RIPEMD160_CTX
-+#define HASH_CBLOCK             RIPEMD160_CBLOCK
-+#define HASH_UPDATE             RIPEMD160_Update
-+#define HASH_TRANSFORM          RIPEMD160_Transform
-+#define HASH_FINAL              RIPEMD160_Final
-+#define HASH_MAKE_STRING(c,s)   do {    \
-+        unsigned long ll;               \
-+        ll=(c)->A; (void)HOST_l2c(ll,(s));      \
-+        ll=(c)->B; (void)HOST_l2c(ll,(s));      \
-+        ll=(c)->C; (void)HOST_l2c(ll,(s));      \
-+        ll=(c)->D; (void)HOST_l2c(ll,(s));      \
-+        ll=(c)->E; (void)HOST_l2c(ll,(s));      \
-+        } while (0)
-+#define HASH_BLOCK_DATA_ORDER   ripemd160_block_data_order
-+
-+#include "internal/md32_common.h"
-+
-+/*
-+ * Transformed F2 and F4 are courtesy of Wei Dai 
-+ */
-+#define F1(x,y,z)       ((x) ^ (y) ^ (z))
-+#define F2(x,y,z)       ((((y) ^ (z)) & (x)) ^ (z))
-+#define F3(x,y,z)       (((~(y)) | (x)) ^ (z))
-+#define F4(x,y,z)       ((((x) ^ (y)) & (z)) ^ (y))
-+#define F5(x,y,z)       (((~(z)) | (y)) ^ (x))
-+
-+#define RIPEMD160_A     0x67452301L
-+#define RIPEMD160_B     0xEFCDAB89L
-+#define RIPEMD160_C     0x98BADCFEL
-+#define RIPEMD160_D     0x10325476L
-+#define RIPEMD160_E     0xC3D2E1F0L
-+
-+#include "rmdconst.h"
-+
-+#define RIP1(a,b,c,d,e,w,s) { \
-+        a+=F1(b,c,d)+X(w); \
-+        a=ROTATE(a,s)+e; \
-+        c=ROTATE(c,10); }
-+
-+#define RIP2(a,b,c,d,e,w,s,K) { \
-+        a+=F2(b,c,d)+X(w)+K; \
-+        a=ROTATE(a,s)+e; \
-+        c=ROTATE(c,10); }
-+
-+#define RIP3(a,b,c,d,e,w,s,K) { \
-+        a+=F3(b,c,d)+X(w)+K; \
-+        a=ROTATE(a,s)+e; \
-+        c=ROTATE(c,10); }
-+
-+#define RIP4(a,b,c,d,e,w,s,K) { \
-+        a+=F4(b,c,d)+X(w)+K; \
-+        a=ROTATE(a,s)+e; \
-+        c=ROTATE(c,10); }
-+
-+#define RIP5(a,b,c,d,e,w,s,K) { \
-+        a+=F5(b,c,d)+X(w)+K; \
-+        a=ROTATE(a,s)+e; \
-+        c=ROTATE(c,10); }
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_one.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_one.c
-new file mode 100644
-index 0000000..c3193bd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmd_one.c
-@@ -0,0 +1,28 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md)
-+{
-+    RIPEMD160_CTX c;
-+    static unsigned char m[RIPEMD160_DIGEST_LENGTH];
-+
-+    if (md == NULL)
-+        md = m;
-+    if (!RIPEMD160_Init(&c))
-+        return NULL;
-+    RIPEMD160_Update(&c, d, n);
-+    RIPEMD160_Final(md, &c);
-+    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
-+    return (md);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmdconst.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmdconst.h
-new file mode 100644
-index 0000000..b810132
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ripemd/rmdconst.h
-@@ -0,0 +1,350 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#define KL0 0x00000000L
-+#define KL1 0x5A827999L
-+#define KL2 0x6ED9EBA1L
-+#define KL3 0x8F1BBCDCL
-+#define KL4 0xA953FD4EL
-+
-+#define KR0 0x50A28BE6L
-+#define KR1 0x5C4DD124L
-+#define KR2 0x6D703EF3L
-+#define KR3 0x7A6D76E9L
-+#define KR4 0x00000000L
-+
-+#define WL00  0
-+#define SL00 11
-+#define WL01  1
-+#define SL01 14
-+#define WL02  2
-+#define SL02 15
-+#define WL03  3
-+#define SL03 12
-+#define WL04  4
-+#define SL04  5
-+#define WL05  5
-+#define SL05  8
-+#define WL06  6
-+#define SL06  7
-+#define WL07  7
-+#define SL07  9
-+#define WL08  8
-+#define SL08 11
-+#define WL09  9
-+#define SL09 13
-+#define WL10 10
-+#define SL10 14
-+#define WL11 11
-+#define SL11 15
-+#define WL12 12
-+#define SL12  6
-+#define WL13 13
-+#define SL13  7
-+#define WL14 14
-+#define SL14  9
-+#define WL15 15
-+#define SL15  8
-+
-+#define WL16  7
-+#define SL16  7
-+#define WL17  4
-+#define SL17  6
-+#define WL18 13
-+#define SL18  8
-+#define WL19  1
-+#define SL19 13
-+#define WL20 10
-+#define SL20 11
-+#define WL21  6
-+#define SL21  9
-+#define WL22 15
-+#define SL22  7
-+#define WL23  3
-+#define SL23 15
-+#define WL24 12
-+#define SL24  7
-+#define WL25  0
-+#define SL25 12
-+#define WL26  9
-+#define SL26 15
-+#define WL27  5
-+#define SL27  9
-+#define WL28  2
-+#define SL28 11
-+#define WL29 14
-+#define SL29  7
-+#define WL30 11
-+#define SL30 13
-+#define WL31  8
-+#define SL31 12
-+
-+#define WL32  3
-+#define SL32 11
-+#define WL33 10
-+#define SL33 13
-+#define WL34 14
-+#define SL34  6
-+#define WL35  4
-+#define SL35  7
-+#define WL36  9
-+#define SL36 14
-+#define WL37 15
-+#define SL37  9
-+#define WL38  8
-+#define SL38 13
-+#define WL39  1
-+#define SL39 15
-+#define WL40  2
-+#define SL40 14
-+#define WL41  7
-+#define SL41  8
-+#define WL42  0
-+#define SL42 13
-+#define WL43  6
-+#define SL43  6
-+#define WL44 13
-+#define SL44  5
-+#define WL45 11
-+#define SL45 12
-+#define WL46  5
-+#define SL46  7
-+#define WL47 12
-+#define SL47  5
-+
-+#define WL48  1
-+#define SL48 11
-+#define WL49  9
-+#define SL49 12
-+#define WL50 11
-+#define SL50 14
-+#define WL51 10
-+#define SL51 15
-+#define WL52  0
-+#define SL52 14
-+#define WL53  8
-+#define SL53 15
-+#define WL54 12
-+#define SL54  9
-+#define WL55  4
-+#define SL55  8
-+#define WL56 13
-+#define SL56  9
-+#define WL57  3
-+#define SL57 14
-+#define WL58  7
-+#define SL58  5
-+#define WL59 15
-+#define SL59  6
-+#define WL60 14
-+#define SL60  8
-+#define WL61  5
-+#define SL61  6
-+#define WL62  6
-+#define SL62  5
-+#define WL63  2
-+#define SL63 12
-+
-+#define WL64  4
-+#define SL64  9
-+#define WL65  0
-+#define SL65 15
-+#define WL66  5
-+#define SL66  5
-+#define WL67  9
-+#define SL67 11
-+#define WL68  7
-+#define SL68  6
-+#define WL69 12
-+#define SL69  8
-+#define WL70  2
-+#define SL70 13
-+#define WL71 10
-+#define SL71 12
-+#define WL72 14
-+#define SL72  5
-+#define WL73  1
-+#define SL73 12
-+#define WL74  3
-+#define SL74 13
-+#define WL75  8
-+#define SL75 14
-+#define WL76 11
-+#define SL76 11
-+#define WL77  6
-+#define SL77  8
-+#define WL78 15
-+#define SL78  5
-+#define WL79 13
-+#define SL79  6
-+
-+#define WR00  5
-+#define SR00  8
-+#define WR01 14
-+#define SR01  9
-+#define WR02  7
-+#define SR02  9
-+#define WR03  0
-+#define SR03 11
-+#define WR04  9
-+#define SR04 13
-+#define WR05  2
-+#define SR05 15
-+#define WR06 11
-+#define SR06 15
-+#define WR07  4
-+#define SR07  5
-+#define WR08 13
-+#define SR08  7
-+#define WR09  6
-+#define SR09  7
-+#define WR10 15
-+#define SR10  8
-+#define WR11  8
-+#define SR11 11
-+#define WR12  1
-+#define SR12 14
-+#define WR13 10
-+#define SR13 14
-+#define WR14  3
-+#define SR14 12
-+#define WR15 12
-+#define SR15  6
-+
-+#define WR16  6
-+#define SR16  9
-+#define WR17 11
-+#define SR17 13
-+#define WR18  3
-+#define SR18 15
-+#define WR19  7
-+#define SR19  7
-+#define WR20  0
-+#define SR20 12
-+#define WR21 13
-+#define SR21  8
-+#define WR22  5
-+#define SR22  9
-+#define WR23 10
-+#define SR23 11
-+#define WR24 14
-+#define SR24  7
-+#define WR25 15
-+#define SR25  7
-+#define WR26  8
-+#define SR26 12
-+#define WR27 12
-+#define SR27  7
-+#define WR28  4
-+#define SR28  6
-+#define WR29  9
-+#define SR29 15
-+#define WR30  1
-+#define SR30 13
-+#define WR31  2
-+#define SR31 11
-+
-+#define WR32 15
-+#define SR32  9
-+#define WR33  5
-+#define SR33  7
-+#define WR34  1
-+#define SR34 15
-+#define WR35  3
-+#define SR35 11
-+#define WR36  7
-+#define SR36  8
-+#define WR37 14
-+#define SR37  6
-+#define WR38  6
-+#define SR38  6
-+#define WR39  9
-+#define SR39 14
-+#define WR40 11
-+#define SR40 12
-+#define WR41  8
-+#define SR41 13
-+#define WR42 12
-+#define SR42  5
-+#define WR43  2
-+#define SR43 14
-+#define WR44 10
-+#define SR44 13
-+#define WR45  0
-+#define SR45 13
-+#define WR46  4
-+#define SR46  7
-+#define WR47 13
-+#define SR47  5
-+
-+#define WR48  8
-+#define SR48 15
-+#define WR49  6
-+#define SR49  5
-+#define WR50  4
-+#define SR50  8
-+#define WR51  1
-+#define SR51 11
-+#define WR52  3
-+#define SR52 14
-+#define WR53 11
-+#define SR53 14
-+#define WR54 15
-+#define SR54  6
-+#define WR55  0
-+#define SR55 14
-+#define WR56  5
-+#define SR56  6
-+#define WR57 12
-+#define SR57  9
-+#define WR58  2
-+#define SR58 12
-+#define WR59 13
-+#define SR59  9
-+#define WR60  9
-+#define SR60 12
-+#define WR61  7
-+#define SR61  5
-+#define WR62 10
-+#define SR62 15
-+#define WR63 14
-+#define SR63  8
-+
-+#define WR64 12
-+#define SR64  8
-+#define WR65 15
-+#define SR65  5
-+#define WR66 10
-+#define SR66 12
-+#define WR67  4
-+#define SR67  9
-+#define WR68  1
-+#define SR68 12
-+#define WR69  5
-+#define SR69  5
-+#define WR70  8
-+#define SR70 14
-+#define WR71  7
-+#define SR71  6
-+#define WR72  6
-+#define SR72  8
-+#define WR73  2
-+#define SR73 13
-+#define WR74 13
-+#define SR74  6
-+#define WR75 14
-+#define SR75  5
-+#define WR76  0
-+#define SR76 15
-+#define WR77  3
-+#define SR77 13
-+#define WR78  9
-+#define SR78 11
-+#define WR79 11
-+#define SR79 11
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/build.info
-new file mode 100644
-index 0000000..39b7464
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/build.info
-@@ -0,0 +1,6 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \
-+        rsa_pk1.c rsa_ssl.c rsa_none.c rsa_oaep.c rsa_chk.c rsa_null.c \
-+        rsa_pss.c rsa_x931.c rsa_asn1.c rsa_depr.c rsa_ameth.c rsa_prn.c \
-+        rsa_pmeth.c rsa_crpt.c rsa_x931g.c rsa_meth.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ameth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ameth.c
-new file mode 100644
-index 0000000..5694140
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ameth.c
-@@ -0,0 +1,866 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/asn1_int.h"
-+#include "internal/evp_int.h"
-+#include "rsa_locl.h"
-+
-+#ifndef OPENSSL_NO_CMS
-+static int rsa_cms_sign(CMS_SignerInfo *si);
-+static int rsa_cms_verify(CMS_SignerInfo *si);
-+static int rsa_cms_decrypt(CMS_RecipientInfo *ri);
-+static int rsa_cms_encrypt(CMS_RecipientInfo *ri);
-+#endif
-+
-+static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
-+{
-+    unsigned char *penc = NULL;
-+    int penclen;
-+    penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc);
-+    if (penclen <= 0)
-+        return 0;
-+    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA),
-+                               V_ASN1_NULL, NULL, penc, penclen))
-+        return 1;
-+
-+    OPENSSL_free(penc);
-+    return 0;
-+}
-+
-+static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
-+{
-+    const unsigned char *p;
-+    int pklen;
-+    RSA *rsa = NULL;
-+
-+    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey))
-+        return 0;
-+    if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) {
-+        RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
-+        return 0;
-+    }
-+    EVP_PKEY_assign_RSA(pkey, rsa);
-+    return 1;
-+}
-+
-+static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
-+{
-+    if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0
-+        || BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0)
-+        return 0;
-+    return 1;
-+}
-+
-+static int old_rsa_priv_decode(EVP_PKEY *pkey,
-+                               const unsigned char **pder, int derlen)
-+{
-+    RSA *rsa;
-+
-+    if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) {
-+        RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
-+        return 0;
-+    }
-+    EVP_PKEY_assign_RSA(pkey, rsa);
-+    return 1;
-+}
-+
-+static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
-+{
-+    return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
-+}
-+
-+static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
-+{
-+    unsigned char *rk = NULL;
-+    int rklen;
-+    rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
-+
-+    if (rklen <= 0) {
-+        RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0,
-+                         V_ASN1_NULL, NULL, rk, rklen)) {
-+        RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+static int rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
-+{
-+    const unsigned char *p;
-+    int pklen;
-+    if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
-+        return 0;
-+    return old_rsa_priv_decode(pkey, &p, pklen);
-+}
-+
-+static int int_rsa_size(const EVP_PKEY *pkey)
-+{
-+    return RSA_size(pkey->pkey.rsa);
-+}
-+
-+static int rsa_bits(const EVP_PKEY *pkey)
-+{
-+    return BN_num_bits(pkey->pkey.rsa->n);
-+}
-+
-+static int rsa_security_bits(const EVP_PKEY *pkey)
-+{
-+    return RSA_security_bits(pkey->pkey.rsa);
-+}
-+
-+static void int_rsa_free(EVP_PKEY *pkey)
-+{
-+    RSA_free(pkey->pkey.rsa);
-+}
-+
-+static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv)
-+{
-+    char *str;
-+    const char *s;
-+    int ret = 0, mod_len = 0;
-+
-+    if (x->n != NULL)
-+        mod_len = BN_num_bits(x->n);
-+
-+    if (!BIO_indent(bp, off, 128))
-+        goto err;
-+
-+    if (priv && x->d) {
-+        if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) <= 0)
-+            goto err;
-+        str = "modulus:";
-+        s = "publicExponent:";
-+    } else {
-+        if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0)
-+            goto err;
-+        str = "Modulus:";
-+        s = "Exponent:";
-+    }
-+    if (!ASN1_bn_print(bp, str, x->n, NULL, off))
-+        goto err;
-+    if (!ASN1_bn_print(bp, s, x->e, NULL, off))
-+        goto err;
-+    if (priv) {
-+        if (!ASN1_bn_print(bp, "privateExponent:", x->d, NULL, off))
-+            goto err;
-+        if (!ASN1_bn_print(bp, "prime1:", x->p, NULL, off))
-+            goto err;
-+        if (!ASN1_bn_print(bp, "prime2:", x->q, NULL, off))
-+            goto err;
-+        if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, NULL, off))
-+            goto err;
-+        if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, NULL, off))
-+            goto err;
-+        if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, NULL, off))
-+            goto err;
-+    }
-+    ret = 1;
-+ err:
-+    return (ret);
-+}
-+
-+static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                         ASN1_PCTX *ctx)
-+{
-+    return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
-+}
-+
-+static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
-+                          ASN1_PCTX *ctx)
-+{
-+    return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
-+}
-+
-+/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */
-+static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg)
-+{
-+    if (alg == NULL)
-+        return NULL;
-+    if (OBJ_obj2nid(alg->algorithm) != NID_mgf1)
-+        return NULL;
-+    return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
-+                                     alg->parameter);
-+}
-+
-+static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
-+                                      X509_ALGOR **pmaskHash)
-+{
-+    RSA_PSS_PARAMS *pss;
-+
-+    *pmaskHash = NULL;
-+
-+    pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS),
-+                                    alg->parameter);
-+
-+    if (!pss)
-+        return NULL;
-+
-+    *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
-+
-+    return pss;
-+}
-+
-+static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss,
-+                               X509_ALGOR *maskHash, int indent)
-+{
-+    int rv = 0;
-+    if (!pss) {
-+        if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0)
-+            return 0;
-+        return 1;
-+    }
-+    if (BIO_puts(bp, "\n") <= 0)
-+        goto err;
-+    if (!BIO_indent(bp, indent, 128))
-+        goto err;
-+    if (BIO_puts(bp, "Hash Algorithm: ") <= 0)
-+        goto err;
-+
-+    if (pss->hashAlgorithm) {
-+        if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0)
-+            goto err;
-+    } else if (BIO_puts(bp, "sha1 (default)") <= 0)
-+        goto err;
-+
-+    if (BIO_puts(bp, "\n") <= 0)
-+        goto err;
-+
-+    if (!BIO_indent(bp, indent, 128))
-+        goto err;
-+
-+    if (BIO_puts(bp, "Mask Algorithm: ") <= 0)
-+        goto err;
-+    if (pss->maskGenAlgorithm) {
-+        if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0)
-+            goto err;
-+        if (BIO_puts(bp, " with ") <= 0)
-+            goto err;
-+        if (maskHash) {
-+            if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0)
-+                goto err;
-+        } else if (BIO_puts(bp, "INVALID") <= 0)
-+            goto err;
-+    } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0)
-+        goto err;
-+    BIO_puts(bp, "\n");
-+
-+    if (!BIO_indent(bp, indent, 128))
-+        goto err;
-+    if (BIO_puts(bp, "Salt Length: 0x") <= 0)
-+        goto err;
-+    if (pss->saltLength) {
-+        if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
-+            goto err;
-+    } else if (BIO_puts(bp, "14 (default)") <= 0)
-+        goto err;
-+    BIO_puts(bp, "\n");
-+
-+    if (!BIO_indent(bp, indent, 128))
-+        goto err;
-+    if (BIO_puts(bp, "Trailer Field: 0x") <= 0)
-+        goto err;
-+    if (pss->trailerField) {
-+        if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0)
-+            goto err;
-+    } else if (BIO_puts(bp, "BC (default)") <= 0)
-+        goto err;
-+    BIO_puts(bp, "\n");
-+
-+    rv = 1;
-+
-+ err:
-+    return rv;
-+
-+}
-+
-+static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
-+                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
-+{
-+    if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) {
-+        int rv;
-+        RSA_PSS_PARAMS *pss;
-+        X509_ALGOR *maskHash;
-+        pss = rsa_pss_decode(sigalg, &maskHash);
-+        rv = rsa_pss_param_print(bp, pss, maskHash, indent);
-+        RSA_PSS_PARAMS_free(pss);
-+        X509_ALGOR_free(maskHash);
-+        if (!rv)
-+            return 0;
-+    } else if (!sig && BIO_puts(bp, "\n") <= 0)
-+        return 0;
-+    if (sig)
-+        return X509_signature_dump(bp, sig, indent);
-+    return 1;
-+}
-+
-+static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
-+{
-+    X509_ALGOR *alg = NULL;
-+    switch (op) {
-+
-+    case ASN1_PKEY_CTRL_PKCS7_SIGN:
-+        if (arg1 == 0)
-+            PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
-+        break;
-+
-+    case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
-+        if (arg1 == 0)
-+            PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
-+        break;
-+#ifndef OPENSSL_NO_CMS
-+    case ASN1_PKEY_CTRL_CMS_SIGN:
-+        if (arg1 == 0)
-+            return rsa_cms_sign(arg2);
-+        else if (arg1 == 1)
-+            return rsa_cms_verify(arg2);
-+        break;
-+
-+    case ASN1_PKEY_CTRL_CMS_ENVELOPE:
-+        if (arg1 == 0)
-+            return rsa_cms_encrypt(arg2);
-+        else if (arg1 == 1)
-+            return rsa_cms_decrypt(arg2);
-+        break;
-+
-+    case ASN1_PKEY_CTRL_CMS_RI_TYPE:
-+        *(int *)arg2 = CMS_RECIPINFO_TRANS;
-+        return 1;
-+#endif
-+
-+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
-+        *(int *)arg2 = NID_sha256;
-+        return 1;
-+
-+    default:
-+        return -2;
-+
-+    }
-+
-+    if (alg)
-+        X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
-+
-+    return 1;
-+
-+}
-+
-+/* allocate and set algorithm ID from EVP_MD, default SHA1 */
-+static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md)
-+{
-+    if (EVP_MD_type(md) == NID_sha1)
-+        return 1;
-+    *palg = X509_ALGOR_new();
-+    if (*palg == NULL)
-+        return 0;
-+    X509_ALGOR_set_md(*palg, md);
-+    return 1;
-+}
-+
-+/* Allocate and set MGF1 algorithm ID from EVP_MD */
-+static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md)
-+{
-+    X509_ALGOR *algtmp = NULL;
-+    ASN1_STRING *stmp = NULL;
-+    *palg = NULL;
-+    if (EVP_MD_type(mgf1md) == NID_sha1)
-+        return 1;
-+    /* need to embed algorithm ID inside another */
-+    if (!rsa_md_to_algor(&algtmp, mgf1md))
-+        goto err;
-+    if (!ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp))
-+         goto err;
-+    *palg = X509_ALGOR_new();
-+    if (*palg == NULL)
-+        goto err;
-+    X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
-+    stmp = NULL;
-+ err:
-+    ASN1_STRING_free(stmp);
-+    X509_ALGOR_free(algtmp);
-+    if (*palg)
-+        return 1;
-+    return 0;
-+}
-+
-+/* convert algorithm ID to EVP_MD, default SHA1 */
-+static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg)
-+{
-+    const EVP_MD *md;
-+    if (!alg)
-+        return EVP_sha1();
-+    md = EVP_get_digestbyobj(alg->algorithm);
-+    if (md == NULL)
-+        RSAerr(RSA_F_RSA_ALGOR_TO_MD, RSA_R_UNKNOWN_DIGEST);
-+    return md;
-+}
-+
-+/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */
-+static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash)
-+{
-+    const EVP_MD *md;
-+    if (!alg)
-+        return EVP_sha1();
-+    /* Check mask and lookup mask hash algorithm */
-+    if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) {
-+        RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_ALGORITHM);
-+        return NULL;
-+    }
-+    if (!maskHash) {
-+        RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_PARAMETER);
-+        return NULL;
-+    }
-+    md = EVP_get_digestbyobj(maskHash->algorithm);
-+    if (md == NULL) {
-+        RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNKNOWN_MASK_DIGEST);
-+        return NULL;
-+    }
-+    return md;
-+}
-+
-+/*
-+ * Convert EVP_PKEY_CTX is PSS mode into corresponding algorithm parameter,
-+ * suitable for setting an AlgorithmIdentifier.
-+ */
-+
-+static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
-+{
-+    const EVP_MD *sigmd, *mgf1md;
-+    RSA_PSS_PARAMS *pss = NULL;
-+    ASN1_STRING *os = NULL;
-+    EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
-+    int saltlen, rv = 0;
-+    if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0)
-+        goto err;
-+    if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
-+        goto err;
-+    if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen))
-+        goto err;
-+    if (saltlen == -1)
-+        saltlen = EVP_MD_size(sigmd);
-+    else if (saltlen == -2) {
-+        saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
-+        if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0)
-+            saltlen--;
-+    }
-+    pss = RSA_PSS_PARAMS_new();
-+    if (pss == NULL)
-+        goto err;
-+    if (saltlen != 20) {
-+        pss->saltLength = ASN1_INTEGER_new();
-+        if (pss->saltLength == NULL)
-+            goto err;
-+        if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
-+            goto err;
-+    }
-+    if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd))
-+        goto err;
-+    if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md))
-+        goto err;
-+    /* Finally create string with pss parameter encoding. */
-+    if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os))
-+         goto err;
-+    rv = 1;
-+ err:
-+    RSA_PSS_PARAMS_free(pss);
-+    if (rv)
-+        return os;
-+    ASN1_STRING_free(os);
-+    return NULL;
-+}
-+
-+/*
-+ * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL
-+ * then the EVP_MD_CTX is setup and initialised. If it is NULL parameters are
-+ * passed to pkctx instead.
-+ */
-+
-+static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
-+                          X509_ALGOR *sigalg, EVP_PKEY *pkey)
-+{
-+    int rv = -1;
-+    int saltlen;
-+    const EVP_MD *mgf1md = NULL, *md = NULL;
-+    RSA_PSS_PARAMS *pss;
-+    X509_ALGOR *maskHash;
-+    /* Sanity check: make sure it is PSS */
-+    if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
-+        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
-+        return -1;
-+    }
-+    /* Decode PSS parameters */
-+    pss = rsa_pss_decode(sigalg, &maskHash);
-+
-+    if (pss == NULL) {
-+        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS);
-+        goto err;
-+    }
-+    mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
-+    if (!mgf1md)
-+        goto err;
-+    md = rsa_algor_to_md(pss->hashAlgorithm);
-+    if (!md)
-+        goto err;
-+
-+    if (pss->saltLength) {
-+        saltlen = ASN1_INTEGER_get(pss->saltLength);
-+
-+        /*
-+         * Could perform more salt length sanity checks but the main RSA
-+         * routines will trap other invalid values anyway.
-+         */
-+        if (saltlen < 0) {
-+            RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_SALT_LENGTH);
-+            goto err;
-+        }
-+    } else
-+        saltlen = 20;
-+
-+    /*
-+     * low-level routines support only trailer field 0xbc (value 1) and
-+     * PKCS#1 says we should reject any other value anyway.
-+     */
-+    if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
-+        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_TRAILER);
-+        goto err;
-+    }
-+
-+    /* We have all parameters now set up context */
-+
-+    if (pkey) {
-+        if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
-+            goto err;
-+    } else {
-+        const EVP_MD *checkmd;
-+        if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0)
-+            goto err;
-+        if (EVP_MD_type(md) != EVP_MD_type(checkmd)) {
-+            RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH);
-+            goto err;
-+        }
-+    }
-+
-+    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0)
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
-+        goto err;
-+
-+    if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
-+        goto err;
-+    /* Carry on */
-+    rv = 1;
-+
-+ err:
-+    RSA_PSS_PARAMS_free(pss);
-+    X509_ALGOR_free(maskHash);
-+    return rv;
-+}
-+
-+#ifndef OPENSSL_NO_CMS
-+static int rsa_cms_verify(CMS_SignerInfo *si)
-+{
-+    int nid, nid2;
-+    X509_ALGOR *alg;
-+    EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
-+    CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
-+    nid = OBJ_obj2nid(alg->algorithm);
-+    if (nid == NID_rsaEncryption)
-+        return 1;
-+    if (nid == NID_rsassaPss)
-+        return rsa_pss_to_ctx(NULL, pkctx, alg, NULL);
-+    /* Workaround for some implementation that use a signature OID */
-+    if (OBJ_find_sigid_algs(nid, NULL, &nid2)) {
-+        if (nid2 == NID_rsaEncryption)
-+            return 1;
-+    }
-+    return 0;
-+}
-+#endif
-+
-+/*
-+ * Customised RSA item verification routine. This is called when a signature
-+ * is encountered requiring special handling. We currently only handle PSS.
-+ */
-+
-+static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
-+                           X509_ALGOR *sigalg, ASN1_BIT_STRING *sig,
-+                           EVP_PKEY *pkey)
-+{
-+    /* Sanity check: make sure it is PSS */
-+    if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
-+        RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
-+        return -1;
-+    }
-+    if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) {
-+        /* Carry on */
-+        return 2;
-+    }
-+    return -1;
-+}
-+
-+#ifndef OPENSSL_NO_CMS
-+static int rsa_cms_sign(CMS_SignerInfo *si)
-+{
-+    int pad_mode = RSA_PKCS1_PADDING;
-+    X509_ALGOR *alg;
-+    EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
-+    ASN1_STRING *os = NULL;
-+    CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
-+    if (pkctx) {
-+        if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
-+            return 0;
-+    }
-+    if (pad_mode == RSA_PKCS1_PADDING) {
-+        X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
-+        return 1;
-+    }
-+    /* We don't support it */
-+    if (pad_mode != RSA_PKCS1_PSS_PADDING)
-+        return 0;
-+    os = rsa_ctx_to_pss(pkctx);
-+    if (!os)
-+        return 0;
-+    X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os);
-+    return 1;
-+}
-+#endif
-+
-+static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
-+                         X509_ALGOR *alg1, X509_ALGOR *alg2,
-+                         ASN1_BIT_STRING *sig)
-+{
-+    int pad_mode;
-+    EVP_PKEY_CTX *pkctx = EVP_MD_CTX_pkey_ctx(ctx);
-+    if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
-+        return 0;
-+    if (pad_mode == RSA_PKCS1_PADDING)
-+        return 2;
-+    if (pad_mode == RSA_PKCS1_PSS_PADDING) {
-+        ASN1_STRING *os1 = NULL;
-+        os1 = rsa_ctx_to_pss(pkctx);
-+        if (!os1)
-+            return 0;
-+        /* Duplicate parameters if we have to */
-+        if (alg2) {
-+            ASN1_STRING *os2 = ASN1_STRING_dup(os1);
-+            if (!os2) {
-+                ASN1_STRING_free(os1);
-+                return 0;
-+            }
-+            X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss),
-+                            V_ASN1_SEQUENCE, os2);
-+        }
-+        X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss),
-+                        V_ASN1_SEQUENCE, os1);
-+        return 3;
-+    }
-+    return 2;
-+}
-+
-+#ifndef OPENSSL_NO_CMS
-+static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg,
-+                                        X509_ALGOR **pmaskHash)
-+{
-+    RSA_OAEP_PARAMS *pss;
-+
-+    *pmaskHash = NULL;
-+
-+    pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS),
-+                                    alg->parameter);
-+
-+    if (!pss)
-+        return NULL;
-+
-+    *pmaskHash = rsa_mgf1_decode(pss->maskGenFunc);
-+
-+    return pss;
-+}
-+
-+static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
-+{
-+    EVP_PKEY_CTX *pkctx;
-+    X509_ALGOR *cmsalg;
-+    int nid;
-+    int rv = -1;
-+    unsigned char *label = NULL;
-+    int labellen = 0;
-+    const EVP_MD *mgf1md = NULL, *md = NULL;
-+    RSA_OAEP_PARAMS *oaep;
-+    X509_ALGOR *maskHash;
-+    pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
-+    if (!pkctx)
-+        return 0;
-+    if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg))
-+        return -1;
-+    nid = OBJ_obj2nid(cmsalg->algorithm);
-+    if (nid == NID_rsaEncryption)
-+        return 1;
-+    if (nid != NID_rsaesOaep) {
-+        RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE);
-+        return -1;
-+    }
-+    /* Decode OAEP parameters */
-+    oaep = rsa_oaep_decode(cmsalg, &maskHash);
-+
-+    if (oaep == NULL) {
-+        RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS);
-+        goto err;
-+    }
-+
-+    mgf1md = rsa_mgf1_to_md(oaep->maskGenFunc, maskHash);
-+    if (!mgf1md)
-+        goto err;
-+    md = rsa_algor_to_md(oaep->hashFunc);
-+    if (!md)
-+        goto err;
-+
-+    if (oaep->pSourceFunc) {
-+        X509_ALGOR *plab = oaep->pSourceFunc;
-+        if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) {
-+            RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE);
-+            goto err;
-+        }
-+        if (plab->parameter->type != V_ASN1_OCTET_STRING) {
-+            RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL);
-+            goto err;
-+        }
-+
-+        label = plab->parameter->value.octet_string->data;
-+        /* Stop label being freed when OAEP parameters are freed */
-+        plab->parameter->value.octet_string->data = NULL;
-+        labellen = plab->parameter->value.octet_string->length;
-+    }
-+
-+    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0)
-+        goto err;
-+    if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0)
-+        goto err;
-+    if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
-+        goto err;
-+    if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0)
-+        goto err;
-+    /* Carry on */
-+    rv = 1;
-+
-+ err:
-+    RSA_OAEP_PARAMS_free(oaep);
-+    X509_ALGOR_free(maskHash);
-+    return rv;
-+}
-+
-+static int rsa_cms_encrypt(CMS_RecipientInfo *ri)
-+{
-+    const EVP_MD *md, *mgf1md;
-+    RSA_OAEP_PARAMS *oaep = NULL;
-+    ASN1_STRING *os = NULL;
-+    X509_ALGOR *alg;
-+    EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
-+    int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen;
-+    unsigned char *label;
-+    CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg);
-+    if (pkctx) {
-+        if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
-+            return 0;
-+    }
-+    if (pad_mode == RSA_PKCS1_PADDING) {
-+        X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
-+        return 1;
-+    }
-+    /* Not supported */
-+    if (pad_mode != RSA_PKCS1_OAEP_PADDING)
-+        return 0;
-+    if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0)
-+        goto err;
-+    if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
-+        goto err;
-+    labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label);
-+    if (labellen < 0)
-+        goto err;
-+    oaep = RSA_OAEP_PARAMS_new();
-+    if (oaep == NULL)
-+        goto err;
-+    if (!rsa_md_to_algor(&oaep->hashFunc, md))
-+        goto err;
-+    if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md))
-+        goto err;
-+    if (labellen > 0) {
-+        ASN1_OCTET_STRING *los;
-+        oaep->pSourceFunc = X509_ALGOR_new();
-+        if (oaep->pSourceFunc == NULL)
-+            goto err;
-+        los = ASN1_OCTET_STRING_new();
-+        if (los == NULL)
-+            goto err;
-+        if (!ASN1_OCTET_STRING_set(los, label, labellen)) {
-+            ASN1_OCTET_STRING_free(los);
-+            goto err;
-+        }
-+        X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified),
-+                        V_ASN1_OCTET_STRING, los);
-+    }
-+    /* create string with pss parameter encoding. */
-+    if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os))
-+         goto err;
-+    X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os);
-+    os = NULL;
-+    rv = 1;
-+ err:
-+    RSA_OAEP_PARAMS_free(oaep);
-+    ASN1_STRING_free(os);
-+    return rv;
-+}
-+#endif
-+
-+const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = {
-+    {
-+     EVP_PKEY_RSA,
-+     EVP_PKEY_RSA,
-+     ASN1_PKEY_SIGPARAM_NULL,
-+
-+     "RSA",
-+     "OpenSSL RSA method",
-+
-+     rsa_pub_decode,
-+     rsa_pub_encode,
-+     rsa_pub_cmp,
-+     rsa_pub_print,
-+
-+     rsa_priv_decode,
-+     rsa_priv_encode,
-+     rsa_priv_print,
-+
-+     int_rsa_size,
-+     rsa_bits,
-+     rsa_security_bits,
-+
-+     0, 0, 0, 0, 0, 0,
-+
-+     rsa_sig_print,
-+     int_rsa_free,
-+     rsa_pkey_ctrl,
-+     old_rsa_priv_decode,
-+     old_rsa_priv_encode,
-+     rsa_item_verify,
-+     rsa_item_sign},
-+
-+    {
-+     EVP_PKEY_RSA2,
-+     EVP_PKEY_RSA,
-+     ASN1_PKEY_ALIAS}
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_asn1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_asn1.c
-new file mode 100644
-index 0000000..20f8ebf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_asn1.c
-@@ -0,0 +1,81 @@
-+/*
-+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "rsa_locl.h"
-+
-+/* Override the default free and new methods */
-+static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                  void *exarg)
-+{
-+    if (operation == ASN1_OP_NEW_PRE) {
-+        *pval = (ASN1_VALUE *)RSA_new();
-+        if (*pval != NULL)
-+            return 2;
-+        return 0;
-+    } else if (operation == ASN1_OP_FREE_PRE) {
-+        RSA_free((RSA *)*pval);
-+        *pval = NULL;
-+        return 2;
-+    }
-+    return 1;
-+}
-+
-+ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = {
-+        ASN1_SIMPLE(RSA, version, LONG),
-+        ASN1_SIMPLE(RSA, n, BIGNUM),
-+        ASN1_SIMPLE(RSA, e, BIGNUM),
-+        ASN1_SIMPLE(RSA, d, CBIGNUM),
-+        ASN1_SIMPLE(RSA, p, CBIGNUM),
-+        ASN1_SIMPLE(RSA, q, CBIGNUM),
-+        ASN1_SIMPLE(RSA, dmp1, CBIGNUM),
-+        ASN1_SIMPLE(RSA, dmq1, CBIGNUM),
-+        ASN1_SIMPLE(RSA, iqmp, CBIGNUM)
-+} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey)
-+
-+
-+ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = {
-+        ASN1_SIMPLE(RSA, n, BIGNUM),
-+        ASN1_SIMPLE(RSA, e, BIGNUM),
-+} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey)
-+
-+ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
-+        ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
-+        ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
-+        ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
-+        ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3)
-+} ASN1_SEQUENCE_END(RSA_PSS_PARAMS)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
-+
-+ASN1_SEQUENCE(RSA_OAEP_PARAMS) = {
-+        ASN1_EXP_OPT(RSA_OAEP_PARAMS, hashFunc, X509_ALGOR, 0),
-+        ASN1_EXP_OPT(RSA_OAEP_PARAMS, maskGenFunc, X509_ALGOR, 1),
-+        ASN1_EXP_OPT(RSA_OAEP_PARAMS, pSourceFunc, X509_ALGOR, 2),
-+} ASN1_SEQUENCE_END(RSA_OAEP_PARAMS)
-+
-+IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS)
-+
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey)
-+
-+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey)
-+
-+RSA *RSAPublicKey_dup(RSA *rsa)
-+{
-+    return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa);
-+}
-+
-+RSA *RSAPrivateKey_dup(RSA *rsa)
-+{
-+    return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_chk.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_chk.c
-new file mode 100644
-index 0000000..00260fb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_chk.c
-@@ -0,0 +1,156 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "rsa_locl.h"
-+
-+int RSA_check_key(const RSA *key)
-+{
-+    return RSA_check_key_ex(key, NULL);
-+}
-+
-+int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)
-+{
-+    BIGNUM *i, *j, *k, *l, *m;
-+    BN_CTX *ctx;
-+    int ret = 1;
-+
-+    if (key->p == NULL || key->q == NULL || key->n == NULL
-+            || key->e == NULL || key->d == NULL) {
-+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_VALUE_MISSING);
-+        return 0;
-+    }
-+
-+    i = BN_new();
-+    j = BN_new();
-+    k = BN_new();
-+    l = BN_new();
-+    m = BN_new();
-+    ctx = BN_CTX_new();
-+    if (i == NULL || j == NULL || k == NULL || l == NULL
-+            || m == NULL || ctx == NULL) {
-+        ret = -1;
-+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (BN_is_one(key->e)) {
-+        ret = 0;
-+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE);
-+    }
-+    if (!BN_is_odd(key->e)) {
-+        ret = 0;
-+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE);
-+    }
-+
-+    /* p prime? */
-+    if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, cb) != 1) {
-+        ret = 0;
-+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_P_NOT_PRIME);
-+    }
-+
-+    /* q prime? */
-+    if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, cb) != 1) {
-+        ret = 0;
-+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_Q_NOT_PRIME);
-+    }
-+
-+    /* n = p*q? */
-+    if (!BN_mul(i, key->p, key->q, ctx)) {
-+        ret = -1;
-+        goto err;
-+    }
-+    if (BN_cmp(i, key->n) != 0) {
-+        ret = 0;
-+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_P_Q);
-+    }
-+
-+    /* d*e = 1  mod lcm(p-1,q-1)? */
-+    if (!BN_sub(i, key->p, BN_value_one())) {
-+        ret = -1;
-+        goto err;
-+    }
-+    if (!BN_sub(j, key->q, BN_value_one())) {
-+        ret = -1;
-+        goto err;
-+    }
-+
-+    /* now compute k = lcm(i,j) */
-+    if (!BN_mul(l, i, j, ctx)) {
-+        ret = -1;
-+        goto err;
-+    }
-+    if (!BN_gcd(m, i, j, ctx)) {
-+        ret = -1;
-+        goto err;
-+    }
-+    if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */
-+        ret = -1;
-+        goto err;
-+    }
-+    if (!BN_mod_mul(i, key->d, key->e, k, ctx)) {
-+        ret = -1;
-+        goto err;
-+    }
-+
-+    if (!BN_is_one(i)) {
-+        ret = 0;
-+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_D_E_NOT_CONGRUENT_TO_1);
-+    }
-+
-+    if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) {
-+        /* dmp1 = d mod (p-1)? */
-+        if (!BN_sub(i, key->p, BN_value_one())) {
-+            ret = -1;
-+            goto err;
-+        }
-+        if (!BN_mod(j, key->d, i, ctx)) {
-+            ret = -1;
-+            goto err;
-+        }
-+        if (BN_cmp(j, key->dmp1) != 0) {
-+            ret = 0;
-+            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMP1_NOT_CONGRUENT_TO_D);
-+        }
-+
-+        /* dmq1 = d mod (q-1)? */
-+        if (!BN_sub(i, key->q, BN_value_one())) {
-+            ret = -1;
-+            goto err;
-+        }
-+        if (!BN_mod(j, key->d, i, ctx)) {
-+            ret = -1;
-+            goto err;
-+        }
-+        if (BN_cmp(j, key->dmq1) != 0) {
-+            ret = 0;
-+            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
-+        }
-+
-+        /* iqmp = q^-1 mod p? */
-+        if (!BN_mod_inverse(i, key->q, key->p, ctx)) {
-+            ret = -1;
-+            goto err;
-+        }
-+        if (BN_cmp(i, key->iqmp) != 0) {
-+            ret = 0;
-+            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_IQMP_NOT_INVERSE_OF_Q);
-+        }
-+    }
-+
-+ err:
-+    BN_free(i);
-+    BN_free(j);
-+    BN_free(k);
-+    BN_free(l);
-+    BN_free(m);
-+    BN_CTX_free(ctx);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_crpt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_crpt.c
-new file mode 100644
-index 0000000..9cd733b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_crpt.c
-@@ -0,0 +1,178 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "internal/bn_int.h"
-+#include 
-+#include "rsa_locl.h"
-+
-+int RSA_bits(const RSA *r)
-+{
-+    return (BN_num_bits(r->n));
-+}
-+
-+int RSA_size(const RSA *r)
-+{
-+    return (BN_num_bytes(r->n));
-+}
-+
-+int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
-+                       RSA *rsa, int padding)
-+{
-+    return (rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
-+}
-+
-+int RSA_private_encrypt(int flen, const unsigned char *from,
-+                        unsigned char *to, RSA *rsa, int padding)
-+{
-+    return (rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
-+}
-+
-+int RSA_private_decrypt(int flen, const unsigned char *from,
-+                        unsigned char *to, RSA *rsa, int padding)
-+{
-+    return (rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
-+}
-+
-+int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
-+                       RSA *rsa, int padding)
-+{
-+    return (rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
-+}
-+
-+int RSA_flags(const RSA *r)
-+{
-+    return ((r == NULL) ? 0 : r->meth->flags);
-+}
-+
-+void RSA_blinding_off(RSA *rsa)
-+{
-+    BN_BLINDING_free(rsa->blinding);
-+    rsa->blinding = NULL;
-+    rsa->flags &= ~RSA_FLAG_BLINDING;
-+    rsa->flags |= RSA_FLAG_NO_BLINDING;
-+}
-+
-+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
-+{
-+    int ret = 0;
-+
-+    if (rsa->blinding != NULL)
-+        RSA_blinding_off(rsa);
-+
-+    rsa->blinding = RSA_setup_blinding(rsa, ctx);
-+    if (rsa->blinding == NULL)
-+        goto err;
-+
-+    rsa->flags |= RSA_FLAG_BLINDING;
-+    rsa->flags &= ~RSA_FLAG_NO_BLINDING;
-+    ret = 1;
-+ err:
-+    return (ret);
-+}
-+
-+static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
-+                                  const BIGNUM *q, BN_CTX *ctx)
-+{
-+    BIGNUM *ret = NULL, *r0, *r1, *r2;
-+
-+    if (d == NULL || p == NULL || q == NULL)
-+        return NULL;
-+
-+    BN_CTX_start(ctx);
-+    r0 = BN_CTX_get(ctx);
-+    r1 = BN_CTX_get(ctx);
-+    r2 = BN_CTX_get(ctx);
-+    if (r2 == NULL)
-+        goto err;
-+
-+    if (!BN_sub(r1, p, BN_value_one()))
-+        goto err;
-+    if (!BN_sub(r2, q, BN_value_one()))
-+        goto err;
-+    if (!BN_mul(r0, r1, r2, ctx))
-+        goto err;
-+
-+    ret = BN_mod_inverse(NULL, d, r0, ctx);
-+ err:
-+    BN_CTX_end(ctx);
-+    return ret;
-+}
-+
-+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
-+{
-+    BIGNUM *e;
-+    BN_CTX *ctx;
-+    BN_BLINDING *ret = NULL;
-+
-+    if (in_ctx == NULL) {
-+        if ((ctx = BN_CTX_new()) == NULL)
-+            return 0;
-+    } else
-+        ctx = in_ctx;
-+
-+    BN_CTX_start(ctx);
-+    e = BN_CTX_get(ctx);
-+    if (e == NULL) {
-+        RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    if (rsa->e == NULL) {
-+        e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
-+        if (e == NULL) {
-+            RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
-+            goto err;
-+        }
-+    } else
-+        e = rsa->e;
-+
-+    if ((RAND_status() == 0) && rsa->d != NULL
-+        && bn_get_words(rsa->d) != NULL) {
-+        /*
-+         * if PRNG is not properly seeded, resort to secret exponent as
-+         * unpredictable seed
-+         */
-+        RAND_add(bn_get_words(rsa->d), bn_get_dmax(rsa->d) * sizeof(BN_ULONG),
-+                 0.0);
-+    }
-+
-+    {
-+        BIGNUM *n = BN_new();
-+
-+        if (n == NULL) {
-+            RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
-+
-+        ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp,
-+                                       rsa->_method_mod_n);
-+        /* We MUST free n before any further use of rsa->n */
-+        BN_free(n);
-+    }
-+    if (ret == NULL) {
-+        RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
-+        goto err;
-+    }
-+
-+    BN_BLINDING_set_current_thread(ret);
-+
-+ err:
-+    BN_CTX_end(ctx);
-+    if (ctx != in_ctx)
-+        BN_CTX_free(ctx);
-+    if (e != rsa->e)
-+        BN_free(e);
-+
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_depr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_depr.c
-new file mode 100644
-index 0000000..21e0562
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_depr.c
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * NB: This file contains deprecated functions (compatibility wrappers to the
-+ * "new" versions).
-+ */
-+
-+#include 
-+#if OPENSSL_API_COMPAT >= 0x00908000L
-+NON_EMPTY_TRANSLATION_UNIT
-+
-+#else
-+
-+# include 
-+# include 
-+# include "internal/cryptlib.h"
-+# include 
-+# include 
-+
-+RSA *RSA_generate_key(int bits, unsigned long e_value,
-+                      void (*callback) (int, int, void *), void *cb_arg)
-+{
-+    int i;
-+    BN_GENCB *cb = BN_GENCB_new();
-+    RSA *rsa = RSA_new();
-+    BIGNUM *e = BN_new();
-+
-+    if (cb == NULL || rsa == NULL || e == NULL)
-+        goto err;
-+
-+    /*
-+     * The problem is when building with 8, 16, or 32 BN_ULONG, unsigned long
-+     * can be larger
-+     */
-+    for (i = 0; i < (int)sizeof(unsigned long) * 8; i++) {
-+        if (e_value & (1UL << i))
-+            if (BN_set_bit(e, i) == 0)
-+                goto err;
-+    }
-+
-+    BN_GENCB_set_old(cb, callback, cb_arg);
-+
-+    if (RSA_generate_key_ex(rsa, bits, e, cb)) {
-+        BN_free(e);
-+        BN_GENCB_free(cb);
-+        return rsa;
-+    }
-+ err:
-+    BN_free(e);
-+    RSA_free(rsa);
-+    BN_GENCB_free(cb);
-+    return 0;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_err.c
-new file mode 100644
-index 0000000..bf54095
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_err.c
-@@ -0,0 +1,185 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason)
-+
-+static ERR_STRING_DATA RSA_str_functs[] = {
-+    {ERR_FUNC(RSA_F_CHECK_PADDING_MD), "check_padding_md"},
-+    {ERR_FUNC(RSA_F_ENCODE_PKCS1), "encode_pkcs1"},
-+    {ERR_FUNC(RSA_F_INT_RSA_VERIFY), "int_rsa_verify"},
-+    {ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), "old_rsa_priv_decode"},
-+    {ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "pkey_rsa_ctrl"},
-+    {ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "pkey_rsa_ctrl_str"},
-+    {ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "pkey_rsa_sign"},
-+    {ERR_FUNC(RSA_F_PKEY_RSA_VERIFY), "pkey_rsa_verify"},
-+    {ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "pkey_rsa_verifyrecover"},
-+    {ERR_FUNC(RSA_F_RSA_ALGOR_TO_MD), "rsa_algor_to_md"},
-+    {ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "rsa_builtin_keygen"},
-+    {ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"},
-+    {ERR_FUNC(RSA_F_RSA_CHECK_KEY_EX), "RSA_check_key_ex"},
-+    {ERR_FUNC(RSA_F_RSA_CMS_DECRYPT), "rsa_cms_decrypt"},
-+    {ERR_FUNC(RSA_F_RSA_ITEM_VERIFY), "rsa_item_verify"},
-+    {ERR_FUNC(RSA_F_RSA_METH_DUP), "RSA_meth_dup"},
-+    {ERR_FUNC(RSA_F_RSA_METH_NEW), "RSA_meth_new"},
-+    {ERR_FUNC(RSA_F_RSA_METH_SET1_NAME), "RSA_meth_set1_name"},
-+    {ERR_FUNC(RSA_F_RSA_MGF1_TO_MD), "rsa_mgf1_to_md"},
-+    {ERR_FUNC(RSA_F_RSA_NEW_METHOD), "RSA_new_method"},
-+    {ERR_FUNC(RSA_F_RSA_NULL), "RSA_NULL"},
-+    {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT), "RSA_null_private_decrypt"},
-+    {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT), "RSA_null_private_encrypt"},
-+    {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT), "RSA_null_public_decrypt"},
-+    {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT), "RSA_null_public_encrypt"},
-+    {ERR_FUNC(RSA_F_RSA_OSSL_PRIVATE_DECRYPT), "rsa_ossl_private_decrypt"},
-+    {ERR_FUNC(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT), "rsa_ossl_private_encrypt"},
-+    {ERR_FUNC(RSA_F_RSA_OSSL_PUBLIC_DECRYPT), "rsa_ossl_public_decrypt"},
-+    {ERR_FUNC(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT), "rsa_ossl_public_encrypt"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP),
-+     "RSA_padding_add_PKCS1_OAEP"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1),
-+     "RSA_padding_add_PKCS1_OAEP_mgf1"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1),
-+     "RSA_padding_add_PKCS1_PSS_mgf1"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1),
-+     "RSA_padding_add_PKCS1_type_1"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2),
-+     "RSA_padding_add_PKCS1_type_2"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931), "RSA_padding_add_X931"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE), "RSA_padding_check_none"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP),
-+     "RSA_padding_check_PKCS1_OAEP"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1),
-+     "RSA_padding_check_PKCS1_OAEP_mgf1"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1),
-+     "RSA_padding_check_PKCS1_type_1"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2),
-+     "RSA_padding_check_PKCS1_type_2"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23), "RSA_padding_check_SSLv23"},
-+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"},
-+    {ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
-+    {ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
-+    {ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "rsa_priv_encode"},
-+    {ERR_FUNC(RSA_F_RSA_PSS_TO_CTX), "rsa_pss_to_ctx"},
-+    {ERR_FUNC(RSA_F_RSA_PUB_DECODE), "rsa_pub_decode"},
-+    {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"},
-+    {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
-+    {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING),
-+     "RSA_sign_ASN1_OCTET_STRING"},
-+    {ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"},
-+    {ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING),
-+     "RSA_verify_ASN1_OCTET_STRING"},
-+    {ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1), "RSA_verify_PKCS1_PSS_mgf1"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA RSA_str_reasons[] = {
-+    {ERR_REASON(RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch"},
-+    {ERR_REASON(RSA_R_BAD_E_VALUE), "bad e value"},
-+    {ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT), "bad fixed header decrypt"},
-+    {ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT), "bad pad byte count"},
-+    {ERR_REASON(RSA_R_BAD_SIGNATURE), "bad signature"},
-+    {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01), "block type is not 01"},
-+    {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02), "block type is not 02"},
-+    {ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN),
-+     "data greater than mod len"},
-+    {ERR_REASON(RSA_R_DATA_TOO_LARGE), "data too large"},
-+    {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),
-+     "data too large for key size"},
-+    {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS),
-+     "data too large for modulus"},
-+    {ERR_REASON(RSA_R_DATA_TOO_SMALL), "data too small"},
-+    {ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE),
-+     "data too small for key size"},
-+    {ERR_REASON(RSA_R_DIGEST_DOES_NOT_MATCH), "digest does not match"},
-+    {ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY),
-+     "digest too big for rsa key"},
-+    {ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D), "dmp1 not congruent to d"},
-+    {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D), "dmq1 not congruent to d"},
-+    {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1), "d e not congruent to 1"},
-+    {ERR_REASON(RSA_R_FIRST_OCTET_INVALID), "first octet invalid"},
-+    {ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),
-+     "illegal or unsupported padding mode"},
-+    {ERR_REASON(RSA_R_INVALID_DIGEST), "invalid digest"},
-+    {ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH), "invalid digest length"},
-+    {ERR_REASON(RSA_R_INVALID_HEADER), "invalid header"},
-+    {ERR_REASON(RSA_R_INVALID_LABEL), "invalid label"},
-+    {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH), "invalid message length"},
-+    {ERR_REASON(RSA_R_INVALID_MGF1_MD), "invalid mgf1 md"},
-+    {ERR_REASON(RSA_R_INVALID_OAEP_PARAMETERS), "invalid oaep parameters"},
-+    {ERR_REASON(RSA_R_INVALID_PADDING), "invalid padding"},
-+    {ERR_REASON(RSA_R_INVALID_PADDING_MODE), "invalid padding mode"},
-+    {ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS), "invalid pss parameters"},
-+    {ERR_REASON(RSA_R_INVALID_PSS_SALTLEN), "invalid pss saltlen"},
-+    {ERR_REASON(RSA_R_INVALID_SALT_LENGTH), "invalid salt length"},
-+    {ERR_REASON(RSA_R_INVALID_TRAILER), "invalid trailer"},
-+    {ERR_REASON(RSA_R_INVALID_X931_DIGEST), "invalid x931 digest"},
-+    {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q), "iqmp not inverse of q"},
-+    {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL), "key size too small"},
-+    {ERR_REASON(RSA_R_LAST_OCTET_INVALID), "last octet invalid"},
-+    {ERR_REASON(RSA_R_MODULUS_TOO_LARGE), "modulus too large"},
-+    {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT), "no public exponent"},
-+    {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),
-+     "null before block missing"},
-+    {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q), "n does not equal p q"},
-+    {ERR_REASON(RSA_R_OAEP_DECODING_ERROR), "oaep decoding error"},
-+    {ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
-+     "operation not supported for this keytype"},
-+    {ERR_REASON(RSA_R_PADDING_CHECK_FAILED), "padding check failed"},
-+    {ERR_REASON(RSA_R_PKCS_DECODING_ERROR), "pkcs decoding error"},
-+    {ERR_REASON(RSA_R_P_NOT_PRIME), "p not prime"},
-+    {ERR_REASON(RSA_R_Q_NOT_PRIME), "q not prime"},
-+    {ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),
-+     "rsa operations not supported"},
-+    {ERR_REASON(RSA_R_SLEN_CHECK_FAILED), "salt length check failed"},
-+    {ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED), "salt length recovery failed"},
-+    {ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK), "sslv3 rollback attack"},
-+    {ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),
-+     "the asn1 object identifier is not known for this md"},
-+    {ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE), "unknown algorithm type"},
-+    {ERR_REASON(RSA_R_UNKNOWN_DIGEST), "unknown digest"},
-+    {ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST), "unknown mask digest"},
-+    {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE), "unknown padding type"},
-+    {ERR_REASON(RSA_R_UNSUPPORTED_ENCRYPTION_TYPE),
-+     "unsupported encryption type"},
-+    {ERR_REASON(RSA_R_UNSUPPORTED_LABEL_SOURCE), "unsupported label source"},
-+    {ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM),
-+     "unsupported mask algorithm"},
-+    {ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER),
-+     "unsupported mask parameter"},
-+    {ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE),
-+     "unsupported signature type"},
-+    {ERR_REASON(RSA_R_VALUE_MISSING), "value missing"},
-+    {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_RSA_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, RSA_str_functs);
-+        ERR_load_strings(0, RSA_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_gen.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_gen.c
-new file mode 100644
-index 0000000..0d1d56b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_gen.c
-@@ -0,0 +1,199 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * NB: these functions have been "upgraded", the deprecated versions (which
-+ * are compatibility wrappers using these functions) are in rsa_depr.c. -
-+ * Geoff
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "rsa_locl.h"
-+
-+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
-+                              BN_GENCB *cb);
-+
-+/*
-+ * NB: this wrapper would normally be placed in rsa_lib.c and the static
-+ * implementation would probably be in rsa_eay.c. Nonetheless, is kept here
-+ * so that we don't introduce a new linker dependency. Eg. any application
-+ * that wasn't previously linking object code related to key-generation won't
-+ * have to now just because key-generation is part of RSA_METHOD.
-+ */
-+int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
-+{
-+    if (rsa->meth->rsa_keygen)
-+        return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
-+    return rsa_builtin_keygen(rsa, bits, e_value, cb);
-+}
-+
-+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
-+                              BN_GENCB *cb)
-+{
-+    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
-+    int bitsp, bitsq, ok = -1, n = 0;
-+    BN_CTX *ctx = NULL;
-+
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    r0 = BN_CTX_get(ctx);
-+    r1 = BN_CTX_get(ctx);
-+    r2 = BN_CTX_get(ctx);
-+    r3 = BN_CTX_get(ctx);
-+    if (r3 == NULL)
-+        goto err;
-+
-+    bitsp = (bits + 1) / 2;
-+    bitsq = bits - bitsp;
-+
-+    /* We need the RSA components non-NULL */
-+    if (!rsa->n && ((rsa->n = BN_new()) == NULL))
-+        goto err;
-+    if (!rsa->d && ((rsa->d = BN_secure_new()) == NULL))
-+        goto err;
-+    if (!rsa->e && ((rsa->e = BN_new()) == NULL))
-+        goto err;
-+    if (!rsa->p && ((rsa->p = BN_secure_new()) == NULL))
-+        goto err;
-+    if (!rsa->q && ((rsa->q = BN_secure_new()) == NULL))
-+        goto err;
-+    if (!rsa->dmp1 && ((rsa->dmp1 = BN_secure_new()) == NULL))
-+        goto err;
-+    if (!rsa->dmq1 && ((rsa->dmq1 = BN_secure_new()) == NULL))
-+        goto err;
-+    if (!rsa->iqmp && ((rsa->iqmp = BN_secure_new()) == NULL))
-+        goto err;
-+
-+    if (BN_copy(rsa->e, e_value) == NULL)
-+        goto err;
-+
-+    /* generate p and q */
-+    for (;;) {
-+        if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
-+            goto err;
-+        if (!BN_sub(r2, rsa->p, BN_value_one()))
-+            goto err;
-+        if (!BN_gcd(r1, r2, rsa->e, ctx))
-+            goto err;
-+        if (BN_is_one(r1))
-+            break;
-+        if (!BN_GENCB_call(cb, 2, n++))
-+            goto err;
-+    }
-+    if (!BN_GENCB_call(cb, 3, 0))
-+        goto err;
-+    for (;;) {
-+        /*
-+         * When generating ridiculously small keys, we can get stuck
-+         * continually regenerating the same prime values. Check for this and
-+         * bail if it happens 3 times.
-+         */
-+        unsigned int degenerate = 0;
-+        do {
-+            if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
-+                goto err;
-+        } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
-+        if (degenerate == 3) {
-+            ok = 0;             /* we set our own err */
-+            RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
-+            goto err;
-+        }
-+        if (!BN_sub(r2, rsa->q, BN_value_one()))
-+            goto err;
-+        if (!BN_gcd(r1, r2, rsa->e, ctx))
-+            goto err;
-+        if (BN_is_one(r1))
-+            break;
-+        if (!BN_GENCB_call(cb, 2, n++))
-+            goto err;
-+    }
-+    if (!BN_GENCB_call(cb, 3, 1))
-+        goto err;
-+    if (BN_cmp(rsa->p, rsa->q) < 0) {
-+        tmp = rsa->p;
-+        rsa->p = rsa->q;
-+        rsa->q = tmp;
-+    }
-+
-+    /* calculate n */
-+    if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx))
-+        goto err;
-+
-+    /* calculate d */
-+    if (!BN_sub(r1, rsa->p, BN_value_one()))
-+        goto err;               /* p-1 */
-+    if (!BN_sub(r2, rsa->q, BN_value_one()))
-+        goto err;               /* q-1 */
-+    if (!BN_mul(r0, r1, r2, ctx))
-+        goto err;               /* (p-1)(q-1) */
-+    {
-+        BIGNUM *pr0 = BN_new();
-+
-+        if (pr0 == NULL)
-+            goto err;
-+        BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
-+        if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) {
-+            BN_free(pr0);
-+            goto err;               /* d */
-+        }
-+        /* We MUST free pr0 before any further use of r0 */
-+        BN_free(pr0);
-+    }
-+
-+    {
-+        BIGNUM *d = BN_new();
-+
-+        if (d == NULL)
-+            goto err;
-+        BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
-+
-+        if (   /* calculate d mod (p-1) */
-+               !BN_mod(rsa->dmp1, d, r1, ctx)
-+               /* calculate d mod (q-1) */
-+            || !BN_mod(rsa->dmq1, d, r2, ctx)) {
-+            BN_free(d);
-+            goto err;
-+        }
-+        /* We MUST free d before any further use of rsa->d */
-+        BN_free(d);
-+    }
-+
-+    {
-+        BIGNUM *p = BN_new();
-+
-+        if (p == NULL)
-+            goto err;
-+        BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
-+
-+        /* calculate inverse of q mod p */
-+        if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) {
-+            BN_free(p);
-+            goto err;
-+        }
-+        /* We MUST free p before any further use of rsa->p */
-+        BN_free(p);
-+    }
-+
-+    ok = 1;
-+ err:
-+    if (ok == -1) {
-+        RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN);
-+        ok = 0;
-+    }
-+    if (ctx != NULL)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+
-+    return ok;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_lib.c
-new file mode 100644
-index 0000000..48e9100
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_lib.c
-@@ -0,0 +1,310 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "internal/bn_int.h"
-+#include 
-+#include "rsa_locl.h"
-+
-+static const RSA_METHOD *default_RSA_meth = NULL;
-+
-+RSA *RSA_new(void)
-+{
-+    RSA *r = RSA_new_method(NULL);
-+
-+    return r;
-+}
-+
-+void RSA_set_default_method(const RSA_METHOD *meth)
-+{
-+    default_RSA_meth = meth;
-+}
-+
-+const RSA_METHOD *RSA_get_default_method(void)
-+{
-+    if (default_RSA_meth == NULL) {
-+#ifdef RSA_NULL
-+        default_RSA_meth = RSA_null_method();
-+#else
-+        default_RSA_meth = RSA_PKCS1_OpenSSL();
-+#endif
-+    }
-+
-+    return default_RSA_meth;
-+}
-+
-+const RSA_METHOD *RSA_get_method(const RSA *rsa)
-+{
-+    return rsa->meth;
-+}
-+
-+int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
-+{
-+    /*
-+     * NB: The caller is specifically setting a method, so it's not up to us
-+     * to deal with which ENGINE it comes from.
-+     */
-+    const RSA_METHOD *mtmp;
-+    mtmp = rsa->meth;
-+    if (mtmp->finish)
-+        mtmp->finish(rsa);
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(rsa->engine);
-+    rsa->engine = NULL;
-+#endif
-+    rsa->meth = meth;
-+    if (meth->init)
-+        meth->init(rsa);
-+    return 1;
-+}
-+
-+RSA *RSA_new_method(ENGINE *engine)
-+{
-+    RSA *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->references = 1;
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+
-+    ret->meth = RSA_get_default_method();
-+#ifndef OPENSSL_NO_ENGINE
-+    ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
-+    if (engine) {
-+        if (!ENGINE_init(engine)) {
-+            RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
-+            goto err;
-+        }
-+        ret->engine = engine;
-+    } else
-+        ret->engine = ENGINE_get_default_RSA();
-+    if (ret->engine) {
-+        ret->meth = ENGINE_get_RSA(ret->engine);
-+        if (ret->meth == NULL) {
-+            RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
-+            goto err;
-+        }
-+    }
-+#endif
-+
-+    ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
-+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) {
-+        goto err;
-+    }
-+
-+    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
-+        RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_INIT_FAIL);
-+        goto err;
-+    }
-+
-+    return ret;
-+
-+err:
-+    RSA_free(ret);
-+    return NULL;
-+}
-+
-+void RSA_free(RSA *r)
-+{
-+    int i;
-+
-+    if (r == NULL)
-+        return;
-+
-+    CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
-+    REF_PRINT_COUNT("RSA", r);
-+    if (i > 0)
-+        return;
-+    REF_ASSERT_ISNT(i < 0);
-+
-+    if (r->meth->finish)
-+        r->meth->finish(r);
-+#ifndef OPENSSL_NO_ENGINE
-+    ENGINE_finish(r->engine);
-+#endif
-+
-+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);
-+
-+    CRYPTO_THREAD_lock_free(r->lock);
-+
-+    BN_clear_free(r->n);
-+    BN_clear_free(r->e);
-+    BN_clear_free(r->d);
-+    BN_clear_free(r->p);
-+    BN_clear_free(r->q);
-+    BN_clear_free(r->dmp1);
-+    BN_clear_free(r->dmq1);
-+    BN_clear_free(r->iqmp);
-+    BN_BLINDING_free(r->blinding);
-+    BN_BLINDING_free(r->mt_blinding);
-+    OPENSSL_free(r->bignum_data);
-+    OPENSSL_free(r);
-+}
-+
-+int RSA_up_ref(RSA *r)
-+{
-+    int i;
-+
-+    if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
-+        return 0;
-+
-+    REF_PRINT_COUNT("RSA", r);
-+    REF_ASSERT_ISNT(i < 2);
-+    return ((i > 1) ? 1 : 0);
-+}
-+
-+int RSA_set_ex_data(RSA *r, int idx, void *arg)
-+{
-+    return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
-+}
-+
-+void *RSA_get_ex_data(const RSA *r, int idx)
-+{
-+    return (CRYPTO_get_ex_data(&r->ex_data, idx));
-+}
-+
-+int RSA_security_bits(const RSA *rsa)
-+{
-+    return BN_security_bits(BN_num_bits(rsa->n), -1);
-+}
-+
-+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
-+{
-+    /* If the fields n and e in r are NULL, the corresponding input
-+     * parameters MUST be non-NULL for n and e.  d may be
-+     * left NULL (in case only the public key is used).
-+     */
-+    if ((r->n == NULL && n == NULL)
-+        || (r->e == NULL && e == NULL))
-+        return 0;
-+
-+    if (n != NULL) {
-+        BN_free(r->n);
-+        r->n = n;
-+    }
-+    if (e != NULL) {
-+        BN_free(r->e);
-+        r->e = e;
-+    }
-+    if (d != NULL) {
-+        BN_free(r->d);
-+        r->d = d;
-+    }
-+
-+    return 1;
-+}
-+
-+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
-+{
-+    /* If the fields p and q in r are NULL, the corresponding input
-+     * parameters MUST be non-NULL.
-+     */
-+    if ((r->p == NULL && p == NULL)
-+        || (r->q == NULL && q == NULL))
-+        return 0;
-+
-+    if (p != NULL) {
-+        BN_free(r->p);
-+        r->p = p;
-+    }
-+    if (q != NULL) {
-+        BN_free(r->q);
-+        r->q = q;
-+    }
-+
-+    return 1;
-+}
-+
-+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
-+{
-+    /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
-+     * parameters MUST be non-NULL.
-+     */
-+    if ((r->dmp1 == NULL && dmp1 == NULL)
-+        || (r->dmq1 == NULL && dmq1 == NULL)
-+        || (r->iqmp == NULL && iqmp == NULL))
-+        return 0;
-+
-+    if (dmp1 != NULL) {
-+        BN_free(r->dmp1);
-+        r->dmp1 = dmp1;
-+    }
-+    if (dmq1 != NULL) {
-+        BN_free(r->dmq1);
-+        r->dmq1 = dmq1;
-+    }
-+    if (iqmp != NULL) {
-+        BN_free(r->iqmp);
-+        r->iqmp = iqmp;
-+    }
-+
-+    return 1;
-+}
-+
-+void RSA_get0_key(const RSA *r,
-+                  const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
-+{
-+    if (n != NULL)
-+        *n = r->n;
-+    if (e != NULL)
-+        *e = r->e;
-+    if (d != NULL)
-+        *d = r->d;
-+}
-+
-+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
-+{
-+    if (p != NULL)
-+        *p = r->p;
-+    if (q != NULL)
-+        *q = r->q;
-+}
-+
-+void RSA_get0_crt_params(const RSA *r,
-+                         const BIGNUM **dmp1, const BIGNUM **dmq1,
-+                         const BIGNUM **iqmp)
-+{
-+    if (dmp1 != NULL)
-+        *dmp1 = r->dmp1;
-+    if (dmq1 != NULL)
-+        *dmq1 = r->dmq1;
-+    if (iqmp != NULL)
-+        *iqmp = r->iqmp;
-+}
-+
-+void RSA_clear_flags(RSA *r, int flags)
-+{
-+    r->flags &= ~flags;
-+}
-+
-+int RSA_test_flags(const RSA *r, int flags)
-+{
-+    return r->flags & flags;
-+}
-+
-+void RSA_set_flags(RSA *r, int flags)
-+{
-+    r->flags |= flags;
-+}
-+
-+ENGINE *RSA_get0_engine(const RSA *r)
-+{
-+    return r->engine;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_locl.h
-new file mode 100644
-index 0000000..5d16aa6
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_locl.h
-@@ -0,0 +1,96 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+struct rsa_st {
-+    /*
-+     * The first parameter is used to pickup errors where this is passed
-+     * instead of aEVP_PKEY, it is set to 0
-+     */
-+    int pad;
-+    long version;
-+    const RSA_METHOD *meth;
-+    /* functional reference if 'meth' is ENGINE-provided */
-+    ENGINE *engine;
-+    BIGNUM *n;
-+    BIGNUM *e;
-+    BIGNUM *d;
-+    BIGNUM *p;
-+    BIGNUM *q;
-+    BIGNUM *dmp1;
-+    BIGNUM *dmq1;
-+    BIGNUM *iqmp;
-+    /* be careful using this if the RSA structure is shared */
-+    CRYPTO_EX_DATA ex_data;
-+    int references;
-+    int flags;
-+    /* Used to cache montgomery values */
-+    BN_MONT_CTX *_method_mod_n;
-+    BN_MONT_CTX *_method_mod_p;
-+    BN_MONT_CTX *_method_mod_q;
-+    /*
-+     * all BIGNUM values are actually in the following data, if it is not
-+     * NULL
-+     */
-+    char *bignum_data;
-+    BN_BLINDING *blinding;
-+    BN_BLINDING *mt_blinding;
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+struct rsa_meth_st {
-+    char *name;
-+    int (*rsa_pub_enc) (int flen, const unsigned char *from,
-+                        unsigned char *to, RSA *rsa, int padding);
-+    int (*rsa_pub_dec) (int flen, const unsigned char *from,
-+                        unsigned char *to, RSA *rsa, int padding);
-+    int (*rsa_priv_enc) (int flen, const unsigned char *from,
-+                         unsigned char *to, RSA *rsa, int padding);
-+    int (*rsa_priv_dec) (int flen, const unsigned char *from,
-+                         unsigned char *to, RSA *rsa, int padding);
-+    /* Can be null */
-+    int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
-+    /* Can be null */
-+    int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-+                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
-+    /* called at new */
-+    int (*init) (RSA *rsa);
-+    /* called at free */
-+    int (*finish) (RSA *rsa);
-+    /* RSA_METHOD_FLAG_* things */
-+    int flags;
-+    /* may be needed! */
-+    char *app_data;
-+    /*
-+     * New sign and verify functions: some libraries don't allow arbitrary
-+     * data to be signed/verified: this allows them to be used. Note: for
-+     * this to work the RSA_public_decrypt() and RSA_private_encrypt() should
-+     * *NOT* be used RSA_sign(), RSA_verify() should be used instead.
-+     */
-+    int (*rsa_sign) (int type,
-+                     const unsigned char *m, unsigned int m_length,
-+                     unsigned char *sigret, unsigned int *siglen,
-+                     const RSA *rsa);
-+    int (*rsa_verify) (int dtype, const unsigned char *m,
-+                       unsigned int m_length, const unsigned char *sigbuf,
-+                       unsigned int siglen, const RSA *rsa);
-+    /*
-+     * If this callback is NULL, the builtin software RSA key-gen will be
-+     * used. This is for behavioural compatibility whilst the code gets
-+     * rewired, but one day it would be nice to assume there are no such
-+     * things as "builtin software" implementations.
-+     */
-+    int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
-+};
-+
-+extern int int_rsa_verify(int dtype, const unsigned char *m,
-+                          unsigned int m_len, unsigned char *rm,
-+                          size_t *prm_len, const unsigned char *sigbuf,
-+                          size_t siglen, RSA *rsa);
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_meth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_meth.c
-new file mode 100644
-index 0000000..9480abd
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_meth.c
-@@ -0,0 +1,273 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "rsa_locl.h"
-+#include 
-+
-+RSA_METHOD *RSA_meth_new(const char *name, int flags)
-+{
-+    RSA_METHOD *meth = OPENSSL_zalloc(sizeof(*meth));
-+
-+    if (meth != NULL) {
-+        meth->flags = flags;
-+
-+        meth->name = OPENSSL_strdup(name);
-+        if (meth->name != NULL)
-+            return meth;
-+
-+        OPENSSL_free(meth);
-+    }
-+
-+    RSAerr(RSA_F_RSA_METH_NEW, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+void RSA_meth_free(RSA_METHOD *meth)
-+{
-+    if (meth != NULL) {
-+        OPENSSL_free(meth->name);
-+        OPENSSL_free(meth);
-+    }
-+}
-+
-+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth)
-+{
-+    RSA_METHOD *ret = OPENSSL_malloc(sizeof(*ret));
-+
-+    if (ret != NULL) {
-+        memcpy(ret, meth, sizeof(*meth));
-+
-+        ret->name = OPENSSL_strdup(meth->name);
-+        if (ret->name != NULL)
-+            return ret;
-+
-+        OPENSSL_free(ret);
-+    }
-+
-+    RSAerr(RSA_F_RSA_METH_DUP, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+const char *RSA_meth_get0_name(const RSA_METHOD *meth)
-+{
-+    return meth->name;
-+}
-+
-+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name)
-+{
-+    char *tmpname = OPENSSL_strdup(name);
-+
-+    if (tmpname == NULL) {
-+        RSAerr(RSA_F_RSA_METH_SET1_NAME, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    OPENSSL_free(meth->name);
-+    meth->name = tmpname;
-+
-+    return 1;
-+}
-+
-+int RSA_meth_get_flags(RSA_METHOD *meth)
-+{
-+    return meth->flags;
-+}
-+
-+int RSA_meth_set_flags(RSA_METHOD *meth, int flags)
-+{
-+    meth->flags = flags;
-+    return 1;
-+}
-+
-+void *RSA_meth_get0_app_data(const RSA_METHOD *meth)
-+{
-+    return meth->app_data;
-+}
-+
-+int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data)
-+{
-+    meth->app_data = app_data;
-+    return 1;
-+}
-+
-+int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth))
-+    (int flen, const unsigned char *from,
-+     unsigned char *to, RSA *rsa, int padding)
-+{
-+    return meth->rsa_pub_enc;
-+}
-+
-+int RSA_meth_set_pub_enc(RSA_METHOD *meth,
-+                         int (*pub_enc) (int flen, const unsigned char *from,
-+                                         unsigned char *to, RSA *rsa,
-+                                         int padding))
-+{
-+    meth->rsa_pub_enc = pub_enc;
-+    return 1;
-+}
-+
-+int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth))
-+    (int flen, const unsigned char *from,
-+     unsigned char *to, RSA *rsa, int padding)
-+{
-+    return meth->rsa_pub_dec;
-+}
-+
-+int RSA_meth_set_pub_dec(RSA_METHOD *meth,
-+                         int (*pub_dec) (int flen, const unsigned char *from,
-+                                         unsigned char *to, RSA *rsa,
-+                                         int padding))
-+{
-+    meth->rsa_pub_dec = pub_dec;
-+    return 1;
-+}
-+
-+int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth))
-+    (int flen, const unsigned char *from,
-+     unsigned char *to, RSA *rsa, int padding)
-+{
-+    return meth->rsa_priv_enc;
-+}
-+
-+int RSA_meth_set_priv_enc(RSA_METHOD *meth,
-+                          int (*priv_enc) (int flen, const unsigned char *from,
-+                                           unsigned char *to, RSA *rsa,
-+                                           int padding))
-+{
-+    meth->rsa_priv_enc = priv_enc;
-+    return 1;
-+}
-+
-+int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth))
-+    (int flen, const unsigned char *from,
-+     unsigned char *to, RSA *rsa, int padding)
-+{
-+    return meth->rsa_priv_dec;
-+}
-+
-+int RSA_meth_set_priv_dec(RSA_METHOD *meth,
-+                          int (*priv_dec) (int flen, const unsigned char *from,
-+                                           unsigned char *to, RSA *rsa,
-+                                           int padding))
-+{
-+    meth->rsa_priv_dec = priv_dec;
-+    return 1;
-+}
-+
-+    /* Can be null */
-+int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth))
-+    (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
-+{
-+    return meth->rsa_mod_exp;
-+}
-+
-+int RSA_meth_set_mod_exp(RSA_METHOD *meth,
-+                         int (*mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa,
-+                                         BN_CTX *ctx))
-+{
-+    meth->rsa_mod_exp = mod_exp;
-+    return 1;
-+}
-+
-+    /* Can be null */
-+int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth))
-+    (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
-+     const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
-+{
-+    return meth->bn_mod_exp;
-+}
-+
-+int RSA_meth_set_bn_mod_exp(RSA_METHOD *meth,
-+                            int (*bn_mod_exp) (BIGNUM *r,
-+                                               const BIGNUM *a,
-+                                               const BIGNUM *p,
-+                                               const BIGNUM *m,
-+                                               BN_CTX *ctx,
-+                                               BN_MONT_CTX *m_ctx))
-+{
-+    meth->bn_mod_exp = bn_mod_exp;
-+    return 1;
-+}
-+
-+    /* called at new */
-+int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa)
-+{
-+    return meth->init;
-+}
-+
-+int RSA_meth_set_init(RSA_METHOD *meth, int (*init) (RSA *rsa))
-+{
-+    meth->init = init;
-+    return 1;
-+}
-+
-+    /* called at free */
-+int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa)
-+{
-+    return meth->finish;
-+}
-+
-+int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa))
-+{
-+    meth->finish = finish;
-+    return 1;
-+}
-+
-+int (*RSA_meth_get_sign(const RSA_METHOD *meth))
-+    (int type,
-+     const unsigned char *m, unsigned int m_length,
-+     unsigned char *sigret, unsigned int *siglen,
-+     const RSA *rsa)
-+{
-+    return meth->rsa_sign;
-+}
-+
-+int RSA_meth_set_sign(RSA_METHOD *meth,
-+                      int (*sign) (int type, const unsigned char *m,
-+                                   unsigned int m_length,
-+                                   unsigned char *sigret, unsigned int *siglen,
-+                                   const RSA *rsa))
-+{
-+    meth->rsa_sign = sign;
-+    return 1;
-+}
-+
-+int (*RSA_meth_get_verify(const RSA_METHOD *meth))
-+    (int dtype, const unsigned char *m,
-+     unsigned int m_length, const unsigned char *sigbuf,
-+     unsigned int siglen, const RSA *rsa)
-+{
-+    return meth->rsa_verify;
-+}
-+
-+int RSA_meth_set_verify(RSA_METHOD *meth,
-+                        int (*verify) (int dtype, const unsigned char *m,
-+                                       unsigned int m_length,
-+                                       const unsigned char *sigbuf,
-+                                       unsigned int siglen, const RSA *rsa))
-+{
-+    meth->rsa_verify = verify;
-+    return 1;
-+}
-+
-+int (*RSA_meth_get_keygen(const RSA_METHOD *meth))
-+    (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
-+{
-+    return meth->rsa_keygen;
-+}
-+
-+int RSA_meth_set_keygen(RSA_METHOD *meth,
-+                        int (*keygen) (RSA *rsa, int bits, BIGNUM *e,
-+                                       BN_GENCB *cb))
-+{
-+    meth->rsa_keygen = keygen;
-+    return 1;
-+}
-+
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_none.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_none.c
-new file mode 100644
-index 0000000..b78756d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_none.c
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+int RSA_padding_add_none(unsigned char *to, int tlen,
-+                         const unsigned char *from, int flen)
-+{
-+    if (flen > tlen) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-+        return (0);
-+    }
-+
-+    if (flen < tlen) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
-+        return (0);
-+    }
-+
-+    memcpy(to, from, (unsigned int)flen);
-+    return (1);
-+}
-+
-+int RSA_padding_check_none(unsigned char *to, int tlen,
-+                           const unsigned char *from, int flen, int num)
-+{
-+
-+    if (flen > tlen) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE);
-+        return (-1);
-+    }
-+
-+    memset(to, 0, tlen - flen);
-+    memcpy(to + tlen - flen, from, flen);
-+    return (tlen);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_null.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_null.c
-new file mode 100644
-index 0000000..d339494
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_null.c
-@@ -0,0 +1,93 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include "rsa_locl.h"
-+
-+/*
-+ * This is a dummy RSA implementation that just returns errors when called.
-+ * It is designed to allow some RSA functions to work while stopping those
-+ * covered by the RSA patent. That is RSA, encryption, decryption, signing
-+ * and verify is not allowed but RSA key generation, key checking and other
-+ * operations (like storing RSA keys) are permitted.
-+ */
-+
-+static int RSA_null_public_encrypt(int flen, const unsigned char *from,
-+                                   unsigned char *to, RSA *rsa, int padding);
-+static int RSA_null_private_encrypt(int flen, const unsigned char *from,
-+                                    unsigned char *to, RSA *rsa, int padding);
-+static int RSA_null_public_decrypt(int flen, const unsigned char *from,
-+                                   unsigned char *to, RSA *rsa, int padding);
-+static int RSA_null_private_decrypt(int flen, const unsigned char *from,
-+                                    unsigned char *to, RSA *rsa, int padding);
-+static int RSA_null_init(RSA *rsa);
-+static int RSA_null_finish(RSA *rsa);
-+static RSA_METHOD rsa_null_meth = {
-+    "Null RSA",
-+    RSA_null_public_encrypt,
-+    RSA_null_public_decrypt,
-+    RSA_null_private_encrypt,
-+    RSA_null_private_decrypt,
-+    NULL,
-+    NULL,
-+    RSA_null_init,
-+    RSA_null_finish,
-+    0,
-+    NULL,
-+    NULL,
-+    NULL,
-+    NULL
-+};
-+
-+const RSA_METHOD *RSA_null_method(void)
-+{
-+    return (&rsa_null_meth);
-+}
-+
-+static int RSA_null_public_encrypt(int flen, const unsigned char *from,
-+                                   unsigned char *to, RSA *rsa, int padding)
-+{
-+    RSAerr(RSA_F_RSA_NULL_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
-+    return -1;
-+}
-+
-+static int RSA_null_private_encrypt(int flen, const unsigned char *from,
-+                                    unsigned char *to, RSA *rsa, int padding)
-+{
-+    RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT,
-+           RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
-+    return -1;
-+}
-+
-+static int RSA_null_private_decrypt(int flen, const unsigned char *from,
-+                                    unsigned char *to, RSA *rsa, int padding)
-+{
-+    RSAerr(RSA_F_RSA_NULL_PRIVATE_DECRYPT,
-+           RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
-+    return -1;
-+}
-+
-+static int RSA_null_public_decrypt(int flen, const unsigned char *from,
-+                                   unsigned char *to, RSA *rsa, int padding)
-+{
-+    RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
-+    return -1;
-+}
-+
-+static int RSA_null_init(RSA *rsa)
-+{
-+    return (1);
-+}
-+
-+static int RSA_null_finish(RSA *rsa)
-+{
-+    return (1);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_oaep.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_oaep.c
-new file mode 100644
-index 0000000..868104f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_oaep.c
-@@ -0,0 +1,286 @@
-+/*
-+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
-+
-+/*
-+ * See Victor Shoup, "OAEP reconsidered," Nov. 2000,  for problems with the security
-+ * proof for the original OAEP scheme, which EME-OAEP is based on. A new
-+ * proof can be found in E. Fujisaki, T. Okamoto, D. Pointcheval, J. Stern,
-+ * "RSA-OEAP is Still Alive!", Dec. 2000, . The new proof has stronger requirements
-+ * for the underlying permutation: "partial-one-wayness" instead of
-+ * one-wayness.  For the RSA function, this is an equivalent notion.
-+ */
-+
-+#include "internal/constant_time_locl.h"
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "rsa_locl.h"
-+
-+int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
-+                               const unsigned char *from, int flen,
-+                               const unsigned char *param, int plen)
-+{
-+    return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen,
-+                                           param, plen, NULL, NULL);
-+}
-+
-+int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
-+                                    const unsigned char *from, int flen,
-+                                    const unsigned char *param, int plen,
-+                                    const EVP_MD *md, const EVP_MD *mgf1md)
-+{
-+    int i, emlen = tlen - 1;
-+    unsigned char *db, *seed;
-+    unsigned char *dbmask, seedmask[EVP_MAX_MD_SIZE];
-+    int mdlen;
-+
-+    if (md == NULL)
-+        md = EVP_sha1();
-+    if (mgf1md == NULL)
-+        mgf1md = md;
-+
-+    mdlen = EVP_MD_size(md);
-+
-+    if (flen > emlen - 2 * mdlen - 1) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
-+               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-+        return 0;
-+    }
-+
-+    if (emlen < 2 * mdlen + 1) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
-+               RSA_R_KEY_SIZE_TOO_SMALL);
-+        return 0;
-+    }
-+
-+    to[0] = 0;
-+    seed = to + 1;
-+    db = to + mdlen + 1;
-+
-+    if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL))
-+        return 0;
-+    memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);
-+    db[emlen - flen - mdlen - 1] = 0x01;
-+    memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen);
-+    if (RAND_bytes(seed, mdlen) <= 0)
-+        return 0;
-+#ifdef PKCS_TESTVECT
-+    memcpy(seed,
-+           "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
-+           20);
-+#endif
-+
-+    dbmask = OPENSSL_malloc(emlen - mdlen);
-+    if (dbmask == NULL) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0)
-+        goto err;
-+    for (i = 0; i < emlen - mdlen; i++)
-+        db[i] ^= dbmask[i];
-+
-+    if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0)
-+        goto err;
-+    for (i = 0; i < mdlen; i++)
-+        seed[i] ^= seedmask[i];
-+
-+    OPENSSL_free(dbmask);
-+    return 1;
-+
-+ err:
-+    OPENSSL_free(dbmask);
-+    return 0;
-+}
-+
-+int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
-+                                 const unsigned char *from, int flen, int num,
-+                                 const unsigned char *param, int plen)
-+{
-+    return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num,
-+                                             param, plen, NULL, NULL);
-+}
-+
-+int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
-+                                      const unsigned char *from, int flen,
-+                                      int num, const unsigned char *param,
-+                                      int plen, const EVP_MD *md,
-+                                      const EVP_MD *mgf1md)
-+{
-+    int i, dblen, mlen = -1, one_index = 0, msg_index;
-+    unsigned int good, found_one_byte;
-+    const unsigned char *maskedseed, *maskeddb;
-+    /*
-+     * |em| is the encoded message, zero-padded to exactly |num| bytes: em =
-+     * Y || maskedSeed || maskedDB
-+     */
-+    unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE],
-+        phash[EVP_MAX_MD_SIZE];
-+    int mdlen;
-+
-+    if (md == NULL)
-+        md = EVP_sha1();
-+    if (mgf1md == NULL)
-+        mgf1md = md;
-+
-+    mdlen = EVP_MD_size(md);
-+
-+    if (tlen <= 0 || flen <= 0)
-+        return -1;
-+    /*
-+     * |num| is the length of the modulus; |flen| is the length of the
-+     * encoded message. Therefore, for any |from| that was obtained by
-+     * decrypting a ciphertext, we must have |flen| <= |num|. Similarly,
-+     * num < 2 * mdlen + 2 must hold for the modulus irrespective of
-+     * the ciphertext, see PKCS #1 v2.2, section 7.1.2.
-+     * This does not leak any side-channel information.
-+     */
-+    if (num < flen || num < 2 * mdlen + 2)
-+        goto decoding_err;
-+
-+    dblen = num - mdlen - 1;
-+    db = OPENSSL_malloc(dblen);
-+    em = OPENSSL_malloc(num);
-+    if (db == NULL || em == NULL) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
-+        goto cleanup;
-+    }
-+
-+    /*
-+     * Always do this zero-padding copy (even when num == flen) to avoid
-+     * leaking that information. The copy still leaks some side-channel
-+     * information, but it's impossible to have a fixed  memory access
-+     * pattern since we can't read out of the bounds of |from|.
-+     *
-+     * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
-+     */
-+    memset(em, 0, num);
-+    memcpy(em + num - flen, from, flen);
-+
-+    /*
-+     * The first byte must be zero, however we must not leak if this is
-+     * true. See James H. Manger, "A Chosen Ciphertext  Attack on RSA
-+     * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001).
-+     */
-+    good = constant_time_is_zero(em[0]);
-+
-+    maskedseed = em + 1;
-+    maskeddb = em + 1 + mdlen;
-+
-+    if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md))
-+        goto cleanup;
-+    for (i = 0; i < mdlen; i++)
-+        seed[i] ^= maskedseed[i];
-+
-+    if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md))
-+        goto cleanup;
-+    for (i = 0; i < dblen; i++)
-+        db[i] ^= maskeddb[i];
-+
-+    if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL))
-+        goto cleanup;
-+
-+    good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));
-+
-+    found_one_byte = 0;
-+    for (i = mdlen; i < dblen; i++) {
-+        /*
-+         * Padding consists of a number of 0-bytes, followed by a 1.
-+         */
-+        unsigned int equals1 = constant_time_eq(db[i], 1);
-+        unsigned int equals0 = constant_time_is_zero(db[i]);
-+        one_index = constant_time_select_int(~found_one_byte & equals1,
-+                                             i, one_index);
-+        found_one_byte |= equals1;
-+        good &= (found_one_byte | equals0);
-+    }
-+
-+    good &= found_one_byte;
-+
-+    /*
-+     * At this point |good| is zero unless the plaintext was valid,
-+     * so plaintext-awareness ensures timing side-channels are no longer a
-+     * concern.
-+     */
-+    if (!good)
-+        goto decoding_err;
-+
-+    msg_index = one_index + 1;
-+    mlen = dblen - msg_index;
-+
-+    if (tlen < mlen) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE);
-+        mlen = -1;
-+    } else {
-+        memcpy(to, db + msg_index, mlen);
-+        goto cleanup;
-+    }
-+
-+ decoding_err:
-+    /*
-+     * To avoid chosen ciphertext attacks, the error message should not
-+     * reveal which kind of decoding error happened.
-+     */
-+    RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1,
-+           RSA_R_OAEP_DECODING_ERROR);
-+ cleanup:
-+    OPENSSL_free(db);
-+    OPENSSL_free(em);
-+    return mlen;
-+}
-+
-+int PKCS1_MGF1(unsigned char *mask, long len,
-+               const unsigned char *seed, long seedlen, const EVP_MD *dgst)
-+{
-+    long i, outlen = 0;
-+    unsigned char cnt[4];
-+    EVP_MD_CTX *c = EVP_MD_CTX_new();
-+    unsigned char md[EVP_MAX_MD_SIZE];
-+    int mdlen;
-+    int rv = -1;
-+
-+    if (c == NULL)
-+        goto err;
-+    mdlen = EVP_MD_size(dgst);
-+    if (mdlen < 0)
-+        goto err;
-+    for (i = 0; outlen < len; i++) {
-+        cnt[0] = (unsigned char)((i >> 24) & 255);
-+        cnt[1] = (unsigned char)((i >> 16) & 255);
-+        cnt[2] = (unsigned char)((i >> 8)) & 255;
-+        cnt[3] = (unsigned char)(i & 255);
-+        if (!EVP_DigestInit_ex(c, dgst, NULL)
-+            || !EVP_DigestUpdate(c, seed, seedlen)
-+            || !EVP_DigestUpdate(c, cnt, 4))
-+            goto err;
-+        if (outlen + mdlen <= len) {
-+            if (!EVP_DigestFinal_ex(c, mask + outlen, NULL))
-+                goto err;
-+            outlen += mdlen;
-+        } else {
-+            if (!EVP_DigestFinal_ex(c, md, NULL))
-+                goto err;
-+            memcpy(mask + outlen, md, len - outlen);
-+            outlen = len;
-+        }
-+    }
-+    rv = 0;
-+ err:
-+    EVP_MD_CTX_free(c);
-+    return rv;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ossl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ossl.c
-new file mode 100644
-index 0000000..7826066
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ossl.c
-@@ -0,0 +1,790 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include "internal/bn_int.h"
-+#include "rsa_locl.h"
-+
-+#ifndef RSA_NULL
-+
-+static int rsa_ossl_public_encrypt(int flen, const unsigned char *from,
-+                                  unsigned char *to, RSA *rsa, int padding);
-+static int rsa_ossl_private_encrypt(int flen, const unsigned char *from,
-+                                   unsigned char *to, RSA *rsa, int padding);
-+static int rsa_ossl_public_decrypt(int flen, const unsigned char *from,
-+                                  unsigned char *to, RSA *rsa, int padding);
-+static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
-+                                   unsigned char *to, RSA *rsa, int padding);
-+static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa,
-+                           BN_CTX *ctx);
-+static int rsa_ossl_init(RSA *rsa);
-+static int rsa_ossl_finish(RSA *rsa);
-+static RSA_METHOD rsa_pkcs1_ossl_meth = {
-+    "OpenSSL PKCS#1 RSA (from Eric Young)",
-+    rsa_ossl_public_encrypt,
-+    rsa_ossl_public_decrypt,     /* signature verification */
-+    rsa_ossl_private_encrypt,    /* signing */
-+    rsa_ossl_private_decrypt,
-+    rsa_ossl_mod_exp,
-+    BN_mod_exp_mont,            /* XXX probably we should not use Montgomery
-+                                 * if e == 3 */
-+    rsa_ossl_init,
-+    rsa_ossl_finish,
-+    RSA_FLAG_FIPS_METHOD,       /* flags */
-+    NULL,
-+    0,                          /* rsa_sign */
-+    0,                          /* rsa_verify */
-+    NULL                        /* rsa_keygen */
-+};
-+
-+const RSA_METHOD *RSA_PKCS1_OpenSSL(void)
-+{
-+    return &rsa_pkcs1_ossl_meth;
-+}
-+
-+static int rsa_ossl_public_encrypt(int flen, const unsigned char *from,
-+                                  unsigned char *to, RSA *rsa, int padding)
-+{
-+    BIGNUM *f, *ret;
-+    int i, j, k, num = 0, r = -1;
-+    unsigned char *buf = NULL;
-+    BN_CTX *ctx = NULL;
-+
-+    if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
-+        return -1;
-+    }
-+
-+    if (BN_ucmp(rsa->n, rsa->e) <= 0) {
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
-+        return -1;
-+    }
-+
-+    /* for large moduli, enforce exponent limit */
-+    if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) {
-+        if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
-+            RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
-+            return -1;
-+        }
-+    }
-+
-+    if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    f = BN_CTX_get(ctx);
-+    ret = BN_CTX_get(ctx);
-+    num = BN_num_bytes(rsa->n);
-+    buf = OPENSSL_malloc(num);
-+    if (f == NULL || ret == NULL || buf == NULL) {
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    switch (padding) {
-+    case RSA_PKCS1_PADDING:
-+        i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
-+        break;
-+    case RSA_PKCS1_OAEP_PADDING:
-+        i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
-+        break;
-+    case RSA_SSLV23_PADDING:
-+        i = RSA_padding_add_SSLv23(buf, num, from, flen);
-+        break;
-+    case RSA_NO_PADDING:
-+        i = RSA_padding_add_none(buf, num, from, flen);
-+        break;
-+    default:
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
-+        goto err;
-+    }
-+    if (i <= 0)
-+        goto err;
-+
-+    if (BN_bin2bn(buf, num, f) == NULL)
-+        goto err;
-+
-+    if (BN_ucmp(f, rsa->n) >= 0) {
-+        /* usually the padding functions would catch this */
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT,
-+               RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
-+        goto err;
-+    }
-+
-+    if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
-+        if (!BN_MONT_CTX_set_locked
-+            (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx))
-+            goto err;
-+
-+    if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx,
-+                               rsa->_method_mod_n))
-+        goto err;
-+
-+    /*
-+     * put in leading 0 bytes if the number is less than the length of the
-+     * modulus
-+     */
-+    j = BN_num_bytes(ret);
-+    i = BN_bn2bin(ret, &(to[num - j]));
-+    for (k = 0; k < (num - i); k++)
-+        to[k] = 0;
-+
-+    r = num;
-+ err:
-+    if (ctx != NULL)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    OPENSSL_clear_free(buf, num);
-+    return (r);
-+}
-+
-+static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
-+{
-+    BN_BLINDING *ret;
-+
-+    CRYPTO_THREAD_write_lock(rsa->lock);
-+
-+    if (rsa->blinding == NULL) {
-+        rsa->blinding = RSA_setup_blinding(rsa, ctx);
-+    }
-+
-+    ret = rsa->blinding;
-+    if (ret == NULL)
-+        goto err;
-+
-+    if (BN_BLINDING_is_current_thread(ret)) {
-+        /* rsa->blinding is ours! */
-+
-+        *local = 1;
-+    } else {
-+        /* resort to rsa->mt_blinding instead */
-+
-+        /*
-+         * instructs rsa_blinding_convert(), rsa_blinding_invert() that the
-+         * BN_BLINDING is shared, meaning that accesses require locks, and
-+         * that the blinding factor must be stored outside the BN_BLINDING
-+         */
-+        *local = 0;
-+
-+        if (rsa->mt_blinding == NULL) {
-+            rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
-+        }
-+        ret = rsa->mt_blinding;
-+    }
-+
-+ err:
-+    CRYPTO_THREAD_unlock(rsa->lock);
-+    return ret;
-+}
-+
-+static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
-+                                BN_CTX *ctx)
-+{
-+    if (unblind == NULL)
-+        /*
-+         * Local blinding: store the unblinding factor in BN_BLINDING.
-+         */
-+        return BN_BLINDING_convert_ex(f, NULL, b, ctx);
-+    else {
-+        /*
-+         * Shared blinding: store the unblinding factor outside BN_BLINDING.
-+         */
-+        int ret;
-+
-+        BN_BLINDING_lock(b);
-+        ret = BN_BLINDING_convert_ex(f, unblind, b, ctx);
-+        BN_BLINDING_unlock(b);
-+
-+        return ret;
-+    }
-+}
-+
-+static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
-+                               BN_CTX *ctx)
-+{
-+    /*
-+     * For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex
-+     * will use the unblinding factor stored in BN_BLINDING. If BN_BLINDING
-+     * is shared between threads, unblind must be non-null:
-+     * BN_BLINDING_invert_ex will then use the local unblinding factor, and
-+     * will only read the modulus from BN_BLINDING. In both cases it's safe
-+     * to access the blinding without a lock.
-+     */
-+    return BN_BLINDING_invert_ex(f, unblind, b, ctx);
-+}
-+
-+/* signing */
-+static int rsa_ossl_private_encrypt(int flen, const unsigned char *from,
-+                                   unsigned char *to, RSA *rsa, int padding)
-+{
-+    BIGNUM *f, *ret, *res;
-+    int i, j, k, num = 0, r = -1;
-+    unsigned char *buf = NULL;
-+    BN_CTX *ctx = NULL;
-+    int local_blinding = 0;
-+    /*
-+     * Used only if the blinding structure is shared. A non-NULL unblind
-+     * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
-+     * the unblinding factor outside the blinding structure.
-+     */
-+    BIGNUM *unblind = NULL;
-+    BN_BLINDING *blinding = NULL;
-+
-+    if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    f = BN_CTX_get(ctx);
-+    ret = BN_CTX_get(ctx);
-+    num = BN_num_bytes(rsa->n);
-+    buf = OPENSSL_malloc(num);
-+    if (f == NULL || ret == NULL || buf == NULL) {
-+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    switch (padding) {
-+    case RSA_PKCS1_PADDING:
-+        i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
-+        break;
-+    case RSA_X931_PADDING:
-+        i = RSA_padding_add_X931(buf, num, from, flen);
-+        break;
-+    case RSA_NO_PADDING:
-+        i = RSA_padding_add_none(buf, num, from, flen);
-+        break;
-+    case RSA_SSLV23_PADDING:
-+    default:
-+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
-+        goto err;
-+    }
-+    if (i <= 0)
-+        goto err;
-+
-+    if (BN_bin2bn(buf, num, f) == NULL)
-+        goto err;
-+
-+    if (BN_ucmp(f, rsa->n) >= 0) {
-+        /* usually the padding functions would catch this */
-+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT,
-+               RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
-+        goto err;
-+    }
-+
-+    if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
-+        blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
-+        if (blinding == NULL) {
-+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
-+            goto err;
-+        }
-+    }
-+
-+    if (blinding != NULL) {
-+        if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) {
-+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (!rsa_blinding_convert(blinding, f, unblind, ctx))
-+            goto err;
-+    }
-+
-+    if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
-+        ((rsa->p != NULL) &&
-+         (rsa->q != NULL) &&
-+         (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) {
-+        if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx))
-+            goto err;
-+    } else {
-+        BIGNUM *d = BN_new();
-+        if (d == NULL) {
-+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
-+
-+        if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
-+            if (!BN_MONT_CTX_set_locked
-+                (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) {
-+                BN_free(d);
-+                goto err;
-+            }
-+
-+        if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx,
-+                                   rsa->_method_mod_n)) {
-+            BN_free(d);
-+            goto err;
-+        }
-+        /* We MUST free d before any further use of rsa->d */
-+        BN_free(d);
-+    }
-+
-+    if (blinding)
-+        if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
-+            goto err;
-+
-+    if (padding == RSA_X931_PADDING) {
-+        BN_sub(f, rsa->n, ret);
-+        if (BN_cmp(ret, f) > 0)
-+            res = f;
-+        else
-+            res = ret;
-+    } else
-+        res = ret;
-+
-+    /*
-+     * put in leading 0 bytes if the number is less than the length of the
-+     * modulus
-+     */
-+    j = BN_num_bytes(res);
-+    i = BN_bn2bin(res, &(to[num - j]));
-+    for (k = 0; k < (num - i); k++)
-+        to[k] = 0;
-+
-+    r = num;
-+ err:
-+    if (ctx != NULL)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    OPENSSL_clear_free(buf, num);
-+    return (r);
-+}
-+
-+static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
-+                                   unsigned char *to, RSA *rsa, int padding)
-+{
-+    BIGNUM *f, *ret;
-+    int j, num = 0, r = -1;
-+    unsigned char *p;
-+    unsigned char *buf = NULL;
-+    BN_CTX *ctx = NULL;
-+    int local_blinding = 0;
-+    /*
-+     * Used only if the blinding structure is shared. A non-NULL unblind
-+     * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
-+     * the unblinding factor outside the blinding structure.
-+     */
-+    BIGNUM *unblind = NULL;
-+    BN_BLINDING *blinding = NULL;
-+
-+    if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    f = BN_CTX_get(ctx);
-+    ret = BN_CTX_get(ctx);
-+    num = BN_num_bytes(rsa->n);
-+    buf = OPENSSL_malloc(num);
-+    if (f == NULL || ret == NULL || buf == NULL) {
-+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    /*
-+     * This check was for equality but PGP does evil things and chops off the
-+     * top '0' bytes
-+     */
-+    if (flen > num) {
-+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT,
-+               RSA_R_DATA_GREATER_THAN_MOD_LEN);
-+        goto err;
-+    }
-+
-+    /* make data into a big number */
-+    if (BN_bin2bn(from, (int)flen, f) == NULL)
-+        goto err;
-+
-+    if (BN_ucmp(f, rsa->n) >= 0) {
-+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT,
-+               RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
-+        goto err;
-+    }
-+
-+    if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
-+        blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
-+        if (blinding == NULL) {
-+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
-+            goto err;
-+        }
-+    }
-+
-+    if (blinding != NULL) {
-+        if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) {
-+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (!rsa_blinding_convert(blinding, f, unblind, ctx))
-+            goto err;
-+    }
-+
-+    /* do the decrypt */
-+    if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
-+        ((rsa->p != NULL) &&
-+         (rsa->q != NULL) &&
-+         (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) {
-+        if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx))
-+            goto err;
-+    } else {
-+        BIGNUM *d = BN_new();
-+        if (d == NULL) {
-+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
-+
-+        if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
-+            if (!BN_MONT_CTX_set_locked
-+                (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) {
-+                BN_free(d);
-+                goto err;
-+            }
-+        if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx,
-+                                   rsa->_method_mod_n)) {
-+            BN_free(d);
-+            goto err;
-+        }
-+        /* We MUST free d before any further use of rsa->d */
-+        BN_free(d);
-+    }
-+
-+    if (blinding)
-+        if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
-+            goto err;
-+
-+    p = buf;
-+    j = BN_bn2bin(ret, p);      /* j is only used with no-padding mode */
-+
-+    switch (padding) {
-+    case RSA_PKCS1_PADDING:
-+        r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num);
-+        break;
-+    case RSA_PKCS1_OAEP_PADDING:
-+        r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0);
-+        break;
-+    case RSA_SSLV23_PADDING:
-+        r = RSA_padding_check_SSLv23(to, num, buf, j, num);
-+        break;
-+    case RSA_NO_PADDING:
-+        r = RSA_padding_check_none(to, num, buf, j, num);
-+        break;
-+    default:
-+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
-+        goto err;
-+    }
-+    if (r < 0)
-+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED);
-+
-+ err:
-+    if (ctx != NULL)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    OPENSSL_clear_free(buf, num);
-+    return (r);
-+}
-+
-+/* signature verification */
-+static int rsa_ossl_public_decrypt(int flen, const unsigned char *from,
-+                                  unsigned char *to, RSA *rsa, int padding)
-+{
-+    BIGNUM *f, *ret;
-+    int i, num = 0, r = -1;
-+    unsigned char *p;
-+    unsigned char *buf = NULL;
-+    BN_CTX *ctx = NULL;
-+
-+    if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
-+        return -1;
-+    }
-+
-+    if (BN_ucmp(rsa->n, rsa->e) <= 0) {
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
-+        return -1;
-+    }
-+
-+    /* for large moduli, enforce exponent limit */
-+    if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) {
-+        if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
-+            RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
-+            return -1;
-+        }
-+    }
-+
-+    if ((ctx = BN_CTX_new()) == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+    f = BN_CTX_get(ctx);
-+    ret = BN_CTX_get(ctx);
-+    num = BN_num_bytes(rsa->n);
-+    buf = OPENSSL_malloc(num);
-+    if (f == NULL || ret == NULL || buf == NULL) {
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    /*
-+     * This check was for equality but PGP does evil things and chops off the
-+     * top '0' bytes
-+     */
-+    if (flen > num) {
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN);
-+        goto err;
-+    }
-+
-+    if (BN_bin2bn(from, flen, f) == NULL)
-+        goto err;
-+
-+    if (BN_ucmp(f, rsa->n) >= 0) {
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT,
-+               RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
-+        goto err;
-+    }
-+
-+    if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
-+        if (!BN_MONT_CTX_set_locked
-+            (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx))
-+            goto err;
-+
-+    if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx,
-+                               rsa->_method_mod_n))
-+        goto err;
-+
-+    if ((padding == RSA_X931_PADDING) && ((bn_get_words(ret)[0] & 0xf) != 12))
-+        if (!BN_sub(ret, rsa->n, ret))
-+            goto err;
-+
-+    p = buf;
-+    i = BN_bn2bin(ret, p);
-+
-+    switch (padding) {
-+    case RSA_PKCS1_PADDING:
-+        r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num);
-+        break;
-+    case RSA_X931_PADDING:
-+        r = RSA_padding_check_X931(to, num, buf, i, num);
-+        break;
-+    case RSA_NO_PADDING:
-+        r = RSA_padding_check_none(to, num, buf, i, num);
-+        break;
-+    default:
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
-+        goto err;
-+    }
-+    if (r < 0)
-+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED);
-+
-+ err:
-+    if (ctx != NULL)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    OPENSSL_clear_free(buf, num);
-+    return (r);
-+}
-+
-+static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
-+{
-+    BIGNUM *r1, *m1, *vrfy;
-+    int ret = 0;
-+
-+    BN_CTX_start(ctx);
-+
-+    r1 = BN_CTX_get(ctx);
-+    m1 = BN_CTX_get(ctx);
-+    vrfy = BN_CTX_get(ctx);
-+
-+    {
-+        BIGNUM *p = BN_new(), *q = BN_new();
-+
-+        /*
-+         * Make sure BN_mod_inverse in Montgomery initialization uses the
-+         * BN_FLG_CONSTTIME flag
-+         */
-+        if (p == NULL || q == NULL) {
-+            BN_free(p);
-+            BN_free(q);
-+            goto err;
-+        }
-+        BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
-+        BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
-+
-+        if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) {
-+            if (!BN_MONT_CTX_set_locked
-+                (&rsa->_method_mod_p, rsa->lock, p, ctx)
-+                || !BN_MONT_CTX_set_locked(&rsa->_method_mod_q,
-+                                           rsa->lock, q, ctx)) {
-+                BN_free(p);
-+                BN_free(q);
-+                goto err;
-+            }
-+        }
-+        /*
-+         * We MUST free p and q before any further use of rsa->p and rsa->q
-+         */
-+        BN_free(p);
-+        BN_free(q);
-+    }
-+
-+    if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
-+        if (!BN_MONT_CTX_set_locked
-+            (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx))
-+            goto err;
-+
-+    /* compute I mod q */
-+    {
-+        BIGNUM *c = BN_new();
-+        if (c == NULL)
-+            goto err;
-+        BN_with_flags(c, I, BN_FLG_CONSTTIME);
-+
-+        if (!BN_mod(r1, c, rsa->q, ctx)) {
-+            BN_free(c);
-+            goto err;
-+        }
-+
-+        {
-+            BIGNUM *dmq1 = BN_new();
-+            if (dmq1 == NULL) {
-+                BN_free(c);
-+                goto err;
-+            }
-+            BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
-+
-+            /* compute r1^dmq1 mod q */
-+            if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx,
-+                rsa->_method_mod_q)) {
-+                BN_free(c);
-+                BN_free(dmq1);
-+                goto err;
-+            }
-+            /* We MUST free dmq1 before any further use of rsa->dmq1 */
-+            BN_free(dmq1);
-+        }
-+
-+        /* compute I mod p */
-+        if (!BN_mod(r1, c, rsa->p, ctx)) {
-+            BN_free(c);
-+            goto err;
-+        }
-+        /* We MUST free c before any further use of I */
-+        BN_free(c);
-+    }
-+
-+    {
-+        BIGNUM *dmp1 = BN_new();
-+        if (dmp1 == NULL)
-+            goto err;
-+        BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
-+
-+        /* compute r1^dmp1 mod p */
-+        if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx,
-+                                   rsa->_method_mod_p)) {
-+            BN_free(dmp1);
-+            goto err;
-+        }
-+        /* We MUST free dmp1 before any further use of rsa->dmp1 */
-+        BN_free(dmp1);
-+    }
-+
-+    if (!BN_sub(r0, r0, m1))
-+        goto err;
-+    /*
-+     * This will help stop the size of r0 increasing, which does affect the
-+     * multiply if it optimised for a power of 2 size
-+     */
-+    if (BN_is_negative(r0))
-+        if (!BN_add(r0, r0, rsa->p))
-+            goto err;
-+
-+    if (!BN_mul(r1, r0, rsa->iqmp, ctx))
-+        goto err;
-+
-+    {
-+        BIGNUM *pr1 = BN_new();
-+        if (pr1 == NULL)
-+            goto err;
-+        BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
-+
-+        if (!BN_mod(r0, pr1, rsa->p, ctx)) {
-+            BN_free(pr1);
-+            goto err;
-+        }
-+        /* We MUST free pr1 before any further use of r1 */
-+        BN_free(pr1);
-+    }
-+
-+    /*
-+     * If p < q it is occasionally possible for the correction of adding 'p'
-+     * if r0 is negative above to leave the result still negative. This can
-+     * break the private key operations: the following second correction
-+     * should *always* correct this rare occurrence. This will *never* happen
-+     * with OpenSSL generated keys because they ensure p > q [steve]
-+     */
-+    if (BN_is_negative(r0))
-+        if (!BN_add(r0, r0, rsa->p))
-+            goto err;
-+    if (!BN_mul(r1, r0, rsa->q, ctx))
-+        goto err;
-+    if (!BN_add(r0, r1, m1))
-+        goto err;
-+
-+    if (rsa->e && rsa->n) {
-+        if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx,
-+                                   rsa->_method_mod_n))
-+            goto err;
-+        /*
-+         * If 'I' was greater than (or equal to) rsa->n, the operation will
-+         * be equivalent to using 'I mod n'. However, the result of the
-+         * verify will *always* be less than 'n' so we don't check for
-+         * absolute equality, just congruency.
-+         */
-+        if (!BN_sub(vrfy, vrfy, I))
-+            goto err;
-+        if (!BN_mod(vrfy, vrfy, rsa->n, ctx))
-+            goto err;
-+        if (BN_is_negative(vrfy))
-+            if (!BN_add(vrfy, vrfy, rsa->n))
-+                goto err;
-+        if (!BN_is_zero(vrfy)) {
-+            /*
-+             * 'I' and 'vrfy' aren't congruent mod n. Don't leak
-+             * miscalculated CRT output, just do a raw (slower) mod_exp and
-+             * return that instead.
-+             */
-+
-+            BIGNUM *d = BN_new();
-+            if (d == NULL)
-+                goto err;
-+            BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
-+
-+            if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx,
-+                                       rsa->_method_mod_n)) {
-+                BN_free(d);
-+                goto err;
-+            }
-+            /* We MUST free d before any further use of rsa->d */
-+            BN_free(d);
-+        }
-+    }
-+    ret = 1;
-+ err:
-+    BN_CTX_end(ctx);
-+    return (ret);
-+}
-+
-+static int rsa_ossl_init(RSA *rsa)
-+{
-+    rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE;
-+    return (1);
-+}
-+
-+static int rsa_ossl_finish(RSA *rsa)
-+{
-+    BN_MONT_CTX_free(rsa->_method_mod_n);
-+    BN_MONT_CTX_free(rsa->_method_mod_p);
-+    BN_MONT_CTX_free(rsa->_method_mod_q);
-+    return (1);
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pk1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pk1.c
-new file mode 100644
-index 0000000..efb16a0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pk1.c
-@@ -0,0 +1,245 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/constant_time_locl.h"
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
-+                                 const unsigned char *from, int flen)
-+{
-+    int j;
-+    unsigned char *p;
-+
-+    if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,
-+               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-+        return (0);
-+    }
-+
-+    p = (unsigned char *)to;
-+
-+    *(p++) = 0;
-+    *(p++) = 1;                 /* Private Key BT (Block Type) */
-+
-+    /* pad out with 0xff data */
-+    j = tlen - 3 - flen;
-+    memset(p, 0xff, j);
-+    p += j;
-+    *(p++) = '\0';
-+    memcpy(p, from, (unsigned int)flen);
-+    return (1);
-+}
-+
-+int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
-+                                   const unsigned char *from, int flen,
-+                                   int num)
-+{
-+    int i, j;
-+    const unsigned char *p;
-+
-+    p = from;
-+
-+    /*
-+     * The format is
-+     * 00 || 01 || PS || 00 || D
-+     * PS - padding string, at least 8 bytes of FF
-+     * D  - data.
-+     */
-+
-+    if (num < 11)
-+        return -1;
-+
-+    /* Accept inputs with and without the leading 0-byte. */
-+    if (num == flen) {
-+        if ((*p++) != 0x00) {
-+            RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
-+                   RSA_R_INVALID_PADDING);
-+            return -1;
-+        }
-+        flen--;
-+    }
-+
-+    if ((num != (flen + 1)) || (*(p++) != 0x01)) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
-+               RSA_R_BLOCK_TYPE_IS_NOT_01);
-+        return (-1);
-+    }
-+
-+    /* scan over padding data */
-+    j = flen - 1;               /* one for type. */
-+    for (i = 0; i < j; i++) {
-+        if (*p != 0xff) {       /* should decrypt to 0xff */
-+            if (*p == 0) {
-+                p++;
-+                break;
-+            } else {
-+                RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
-+                       RSA_R_BAD_FIXED_HEADER_DECRYPT);
-+                return (-1);
-+            }
-+        }
-+        p++;
-+    }
-+
-+    if (i == j) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
-+               RSA_R_NULL_BEFORE_BLOCK_MISSING);
-+        return (-1);
-+    }
-+
-+    if (i < 8) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
-+               RSA_R_BAD_PAD_BYTE_COUNT);
-+        return (-1);
-+    }
-+    i++;                        /* Skip over the '\0' */
-+    j -= i;
-+    if (j > tlen) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, RSA_R_DATA_TOO_LARGE);
-+        return (-1);
-+    }
-+    memcpy(to, p, (unsigned int)j);
-+
-+    return (j);
-+}
-+
-+int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
-+                                 const unsigned char *from, int flen)
-+{
-+    int i, j;
-+    unsigned char *p;
-+
-+    if (flen > (tlen - 11)) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,
-+               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-+        return (0);
-+    }
-+
-+    p = (unsigned char *)to;
-+
-+    *(p++) = 0;
-+    *(p++) = 2;                 /* Public Key BT (Block Type) */
-+
-+    /* pad out with non-zero random data */
-+    j = tlen - 3 - flen;
-+
-+    if (RAND_bytes(p, j) <= 0)
-+        return (0);
-+    for (i = 0; i < j; i++) {
-+        if (*p == '\0')
-+            do {
-+                if (RAND_bytes(p, 1) <= 0)
-+                    return (0);
-+            } while (*p == '\0');
-+        p++;
-+    }
-+
-+    *(p++) = '\0';
-+
-+    memcpy(p, from, (unsigned int)flen);
-+    return (1);
-+}
-+
-+int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
-+                                   const unsigned char *from, int flen,
-+                                   int num)
-+{
-+    int i;
-+    /* |em| is the encoded message, zero-padded to exactly |num| bytes */
-+    unsigned char *em = NULL;
-+    unsigned int good, found_zero_byte;
-+    int zero_index = 0, msg_index, mlen = -1;
-+
-+    if (tlen < 0 || flen < 0)
-+        return -1;
-+
-+    /*
-+     * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard",
-+     * section 7.2.2.
-+     */
-+
-+    if (flen > num)
-+        goto err;
-+
-+    if (num < 11)
-+        goto err;
-+
-+    em = OPENSSL_zalloc(num);
-+    if (em == NULL) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
-+        return -1;
-+    }
-+    /*
-+     * Always do this zero-padding copy (even when num == flen) to avoid
-+     * leaking that information. The copy still leaks some side-channel
-+     * information, but it's impossible to have a fixed memory access
-+     * pattern since we can't read out of the bounds of |from|.
-+     *
-+     * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
-+     */
-+    memcpy(em + num - flen, from, flen);
-+
-+    good = constant_time_is_zero(em[0]);
-+    good &= constant_time_eq(em[1], 2);
-+
-+    found_zero_byte = 0;
-+    for (i = 2; i < num; i++) {
-+        unsigned int equals0 = constant_time_is_zero(em[i]);
-+        zero_index =
-+            constant_time_select_int(~found_zero_byte & equals0, i,
-+                                     zero_index);
-+        found_zero_byte |= equals0;
-+    }
-+
-+    /*
-+     * PS must be at least 8 bytes long, and it starts two bytes into |em|.
-+     * If we never found a 0-byte, then |zero_index| is 0 and the check
-+     * also fails.
-+     */
-+    good &= constant_time_ge((unsigned int)(zero_index), 2 + 8);
-+
-+    /*
-+     * Skip the zero byte. This is incorrect if we never found a zero-byte
-+     * but in this case we also do not copy the message out.
-+     */
-+    msg_index = zero_index + 1;
-+    mlen = num - msg_index;
-+
-+    /*
-+     * For good measure, do this check in constant time as well; it could
-+     * leak something if |tlen| was assuming valid padding.
-+     */
-+    good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen));
-+
-+    /*
-+     * We can't continue in constant-time because we need to copy the result
-+     * and we cannot fake its length. This unavoidably leaks timing
-+     * information at the API boundary.
-+     * TODO(emilia): this could be addressed at the call site,
-+     * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26.
-+     */
-+    if (!good) {
-+        mlen = -1;
-+        goto err;
-+    }
-+
-+    memcpy(to, em + msg_index, mlen);
-+
-+ err:
-+    OPENSSL_free(em);
-+    if (mlen == -1)
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,
-+               RSA_R_PKCS_DECODING_ERROR);
-+    return mlen;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pmeth.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pmeth.c
-new file mode 100644
-index 0000000..db4fb0f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pmeth.c
-@@ -0,0 +1,673 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/evp_int.h"
-+#include "rsa_locl.h"
-+
-+/* RSA pkey context structure */
-+
-+typedef struct {
-+    /* Key gen parameters */
-+    int nbits;
-+    BIGNUM *pub_exp;
-+    /* Keygen callback info */
-+    int gentmp[2];
-+    /* RSA padding mode */
-+    int pad_mode;
-+    /* message digest */
-+    const EVP_MD *md;
-+    /* message digest for MGF1 */
-+    const EVP_MD *mgf1md;
-+    /* PSS salt length */
-+    int saltlen;
-+    /* Temp buffer */
-+    unsigned char *tbuf;
-+    /* OAEP label */
-+    unsigned char *oaep_label;
-+    size_t oaep_labellen;
-+} RSA_PKEY_CTX;
-+
-+static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
-+{
-+    RSA_PKEY_CTX *rctx;
-+    rctx = OPENSSL_zalloc(sizeof(*rctx));
-+    if (rctx == NULL)
-+        return 0;
-+    rctx->nbits = 1024;
-+    rctx->pad_mode = RSA_PKCS1_PADDING;
-+    rctx->saltlen = -2;
-+    ctx->data = rctx;
-+    ctx->keygen_info = rctx->gentmp;
-+    ctx->keygen_info_count = 2;
-+
-+    return 1;
-+}
-+
-+static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
-+{
-+    RSA_PKEY_CTX *dctx, *sctx;
-+    if (!pkey_rsa_init(dst))
-+        return 0;
-+    sctx = src->data;
-+    dctx = dst->data;
-+    dctx->nbits = sctx->nbits;
-+    if (sctx->pub_exp) {
-+        dctx->pub_exp = BN_dup(sctx->pub_exp);
-+        if (!dctx->pub_exp)
-+            return 0;
-+    }
-+    dctx->pad_mode = sctx->pad_mode;
-+    dctx->md = sctx->md;
-+    dctx->mgf1md = sctx->mgf1md;
-+    if (sctx->oaep_label) {
-+        OPENSSL_free(dctx->oaep_label);
-+        dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen);
-+        if (!dctx->oaep_label)
-+            return 0;
-+        dctx->oaep_labellen = sctx->oaep_labellen;
-+    }
-+    return 1;
-+}
-+
-+static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
-+{
-+    if (ctx->tbuf)
-+        return 1;
-+    ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
-+    if (ctx->tbuf == NULL)
-+        return 0;
-+    return 1;
-+}
-+
-+static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
-+{
-+    RSA_PKEY_CTX *rctx = ctx->data;
-+    if (rctx) {
-+        BN_free(rctx->pub_exp);
-+        OPENSSL_free(rctx->tbuf);
-+        OPENSSL_free(rctx->oaep_label);
-+        OPENSSL_free(rctx);
-+    }
-+}
-+
-+static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
-+                         size_t *siglen, const unsigned char *tbs,
-+                         size_t tbslen)
-+{
-+    int ret;
-+    RSA_PKEY_CTX *rctx = ctx->data;
-+    RSA *rsa = ctx->pkey->pkey.rsa;
-+
-+    if (rctx->md) {
-+        if (tbslen != (size_t)EVP_MD_size(rctx->md)) {
-+            RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH);
-+            return -1;
-+        }
-+
-+        if (EVP_MD_type(rctx->md) == NID_mdc2) {
-+            unsigned int sltmp;
-+            if (rctx->pad_mode != RSA_PKCS1_PADDING)
-+                return -1;
-+            ret = RSA_sign_ASN1_OCTET_STRING(0,
-+                                             tbs, tbslen, sig, &sltmp, rsa);
-+
-+            if (ret <= 0)
-+                return ret;
-+            ret = sltmp;
-+        } else if (rctx->pad_mode == RSA_X931_PADDING) {
-+            if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) {
-+                RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL);
-+                return -1;
-+            }
-+            if (!setup_tbuf(rctx, ctx)) {
-+                RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE);
-+                return -1;
-+            }
-+            memcpy(rctx->tbuf, tbs, tbslen);
-+            rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md));
-+            ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
-+                                      sig, rsa, RSA_X931_PADDING);
-+        } else if (rctx->pad_mode == RSA_PKCS1_PADDING) {
-+            unsigned int sltmp;
-+            ret = RSA_sign(EVP_MD_type(rctx->md),
-+                           tbs, tbslen, sig, &sltmp, rsa);
-+            if (ret <= 0)
-+                return ret;
-+            ret = sltmp;
-+        } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) {
-+            if (!setup_tbuf(rctx, ctx))
-+                return -1;
-+            if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa,
-+                                                rctx->tbuf, tbs,
-+                                                rctx->md, rctx->mgf1md,
-+                                                rctx->saltlen))
-+                return -1;
-+            ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
-+                                      sig, rsa, RSA_NO_PADDING);
-+        } else
-+            return -1;
-+    } else
-+        ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
-+                                  rctx->pad_mode);
-+    if (ret < 0)
-+        return ret;
-+    *siglen = ret;
-+    return 1;
-+}
-+
-+static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
-+                                  unsigned char *rout, size_t *routlen,
-+                                  const unsigned char *sig, size_t siglen)
-+{
-+    int ret;
-+    RSA_PKEY_CTX *rctx = ctx->data;
-+
-+    if (rctx->md) {
-+        if (rctx->pad_mode == RSA_X931_PADDING) {
-+            if (!setup_tbuf(rctx, ctx))
-+                return -1;
-+            ret = RSA_public_decrypt(siglen, sig,
-+                                     rctx->tbuf, ctx->pkey->pkey.rsa,
-+                                     RSA_X931_PADDING);
-+            if (ret < 1)
-+                return 0;
-+            ret--;
-+            if (rctx->tbuf[ret] != RSA_X931_hash_id(EVP_MD_type(rctx->md))) {
-+                RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
-+                       RSA_R_ALGORITHM_MISMATCH);
-+                return 0;
-+            }
-+            if (ret != EVP_MD_size(rctx->md)) {
-+                RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
-+                       RSA_R_INVALID_DIGEST_LENGTH);
-+                return 0;
-+            }
-+            if (rout)
-+                memcpy(rout, rctx->tbuf, ret);
-+        } else if (rctx->pad_mode == RSA_PKCS1_PADDING) {
-+            size_t sltmp;
-+            ret = int_rsa_verify(EVP_MD_type(rctx->md),
-+                                 NULL, 0, rout, &sltmp,
-+                                 sig, siglen, ctx->pkey->pkey.rsa);
-+            if (ret <= 0)
-+                return 0;
-+            ret = sltmp;
-+        } else
-+            return -1;
-+    } else
-+        ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
-+                                 rctx->pad_mode);
-+    if (ret < 0)
-+        return ret;
-+    *routlen = ret;
-+    return 1;
-+}
-+
-+static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
-+                           const unsigned char *sig, size_t siglen,
-+                           const unsigned char *tbs, size_t tbslen)
-+{
-+    RSA_PKEY_CTX *rctx = ctx->data;
-+    RSA *rsa = ctx->pkey->pkey.rsa;
-+    size_t rslen;
-+    if (rctx->md) {
-+        if (rctx->pad_mode == RSA_PKCS1_PADDING)
-+            return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
-+                              sig, siglen, rsa);
-+        if (tbslen != (size_t)EVP_MD_size(rctx->md)) {
-+            RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
-+            return -1;
-+        }
-+        if (rctx->pad_mode == RSA_X931_PADDING) {
-+            if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0)
-+                return 0;
-+        } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) {
-+            int ret;
-+            if (!setup_tbuf(rctx, ctx))
-+                return -1;
-+            ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
-+                                     rsa, RSA_NO_PADDING);
-+            if (ret <= 0)
-+                return 0;
-+            ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs,
-+                                            rctx->md, rctx->mgf1md,
-+                                            rctx->tbuf, rctx->saltlen);
-+            if (ret <= 0)
-+                return 0;
-+            return 1;
-+        } else
-+            return -1;
-+    } else {
-+        if (!setup_tbuf(rctx, ctx))
-+            return -1;
-+        rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
-+                                   rsa, rctx->pad_mode);
-+        if (rslen == 0)
-+            return 0;
-+    }
-+
-+    if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
-+        return 0;
-+
-+    return 1;
-+
-+}
-+
-+static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
-+                            unsigned char *out, size_t *outlen,
-+                            const unsigned char *in, size_t inlen)
-+{
-+    int ret;
-+    RSA_PKEY_CTX *rctx = ctx->data;
-+    if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
-+        int klen = RSA_size(ctx->pkey->pkey.rsa);
-+        if (!setup_tbuf(rctx, ctx))
-+            return -1;
-+        if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen,
-+                                             in, inlen,
-+                                             rctx->oaep_label,
-+                                             rctx->oaep_labellen,
-+                                             rctx->md, rctx->mgf1md))
-+            return -1;
-+        ret = RSA_public_encrypt(klen, rctx->tbuf, out,
-+                                 ctx->pkey->pkey.rsa, RSA_NO_PADDING);
-+    } else
-+        ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
-+                                 rctx->pad_mode);
-+    if (ret < 0)
-+        return ret;
-+    *outlen = ret;
-+    return 1;
-+}
-+
-+static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
-+                            unsigned char *out, size_t *outlen,
-+                            const unsigned char *in, size_t inlen)
-+{
-+    int ret;
-+    RSA_PKEY_CTX *rctx = ctx->data;
-+    if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
-+        int i;
-+        if (!setup_tbuf(rctx, ctx))
-+            return -1;
-+        ret = RSA_private_decrypt(inlen, in, rctx->tbuf,
-+                                  ctx->pkey->pkey.rsa, RSA_NO_PADDING);
-+        if (ret <= 0)
-+            return ret;
-+        for (i = 0; i < ret; i++) {
-+            if (rctx->tbuf[i])
-+                break;
-+        }
-+        ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf + i,
-+                                                ret - i, ret,
-+                                                rctx->oaep_label,
-+                                                rctx->oaep_labellen,
-+                                                rctx->md, rctx->mgf1md);
-+    } else
-+        ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
-+                                  rctx->pad_mode);
-+    if (ret < 0)
-+        return ret;
-+    *outlen = ret;
-+    return 1;
-+}
-+
-+static int check_padding_md(const EVP_MD *md, int padding)
-+{
-+    int mdnid;
-+    if (!md)
-+        return 1;
-+
-+    mdnid = EVP_MD_type(md);
-+
-+    if (padding == RSA_NO_PADDING) {
-+        RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
-+        return 0;
-+    }
-+
-+    if (padding == RSA_X931_PADDING) {
-+        if (RSA_X931_hash_id(mdnid) == -1) {
-+            RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST);
-+            return 0;
-+        }
-+    } else {
-+        switch(mdnid) {
-+        /* List of all supported RSA digests */
-+        case NID_sha1:
-+        case NID_sha224:
-+        case NID_sha256:
-+        case NID_sha384:
-+        case NID_sha512:
-+        case NID_md5:
-+        case NID_md5_sha1:
-+        case NID_md2:
-+        case NID_md4:
-+        case NID_mdc2:
-+        case NID_ripemd160:
-+            return 1;
-+
-+        default:
-+            RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_DIGEST);
-+            return 0;
-+
-+        }
-+    }
-+
-+    return 1;
-+}
-+
-+static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-+{
-+    RSA_PKEY_CTX *rctx = ctx->data;
-+    switch (type) {
-+    case EVP_PKEY_CTRL_RSA_PADDING:
-+        if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) {
-+            if (!check_padding_md(rctx->md, p1))
-+                return 0;
-+            if (p1 == RSA_PKCS1_PSS_PADDING) {
-+                if (!(ctx->operation &
-+                      (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
-+                    goto bad_pad;
-+                if (!rctx->md)
-+                    rctx->md = EVP_sha1();
-+            }
-+            if (p1 == RSA_PKCS1_OAEP_PADDING) {
-+                if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
-+                    goto bad_pad;
-+                if (!rctx->md)
-+                    rctx->md = EVP_sha1();
-+            }
-+            rctx->pad_mode = p1;
-+            return 1;
-+        }
-+ bad_pad:
-+        RSAerr(RSA_F_PKEY_RSA_CTRL,
-+               RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
-+        return -2;
-+
-+    case EVP_PKEY_CTRL_GET_RSA_PADDING:
-+        *(int *)p2 = rctx->pad_mode;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
-+    case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
-+        if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
-+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
-+            return -2;
-+        }
-+        if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN)
-+            *(int *)p2 = rctx->saltlen;
-+        else {
-+            if (p1 < -2)
-+                return -2;
-+            rctx->saltlen = p1;
-+        }
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
-+        if (p1 < 512) {
-+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL);
-+            return -2;
-+        }
-+        rctx->nbits = p1;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
-+        if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) {
-+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_BAD_E_VALUE);
-+            return -2;
-+        }
-+        BN_free(rctx->pub_exp);
-+        rctx->pub_exp = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_RSA_OAEP_MD:
-+    case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
-+        if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
-+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE);
-+            return -2;
-+        }
-+        if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD)
-+            *(const EVP_MD **)p2 = rctx->md;
-+        else
-+            rctx->md = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_MD:
-+        if (!check_padding_md(p2, rctx->pad_mode))
-+            return 0;
-+        rctx->md = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_MD:
-+        *(const EVP_MD **)p2 = rctx->md;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_RSA_MGF1_MD:
-+    case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
-+        if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING
-+            && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
-+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD);
-+            return -2;
-+        }
-+        if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) {
-+            if (rctx->mgf1md)
-+                *(const EVP_MD **)p2 = rctx->mgf1md;
-+            else
-+                *(const EVP_MD **)p2 = rctx->md;
-+        } else
-+            rctx->mgf1md = p2;
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
-+        if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
-+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE);
-+            return -2;
-+        }
-+        OPENSSL_free(rctx->oaep_label);
-+        if (p2 && p1 > 0) {
-+            rctx->oaep_label = p2;
-+            rctx->oaep_labellen = p1;
-+        } else {
-+            rctx->oaep_label = NULL;
-+            rctx->oaep_labellen = 0;
-+        }
-+        return 1;
-+
-+    case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
-+        if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
-+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE);
-+            return -2;
-+        }
-+        *(unsigned char **)p2 = rctx->oaep_label;
-+        return rctx->oaep_labellen;
-+
-+    case EVP_PKEY_CTRL_DIGESTINIT:
-+    case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
-+    case EVP_PKEY_CTRL_PKCS7_DECRYPT:
-+    case EVP_PKEY_CTRL_PKCS7_SIGN:
-+        return 1;
-+#ifndef OPENSSL_NO_CMS
-+    case EVP_PKEY_CTRL_CMS_DECRYPT:
-+    case EVP_PKEY_CTRL_CMS_ENCRYPT:
-+    case EVP_PKEY_CTRL_CMS_SIGN:
-+        return 1;
-+#endif
-+    case EVP_PKEY_CTRL_PEER_KEY:
-+        RSAerr(RSA_F_PKEY_RSA_CTRL,
-+               RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
-+        return -2;
-+
-+    default:
-+        return -2;
-+
-+    }
-+}
-+
-+static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
-+                             const char *type, const char *value)
-+{
-+    if (!value) {
-+        RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
-+        return 0;
-+    }
-+    if (strcmp(type, "rsa_padding_mode") == 0) {
-+        int pm;
-+        if (strcmp(value, "pkcs1") == 0)
-+            pm = RSA_PKCS1_PADDING;
-+        else if (strcmp(value, "sslv23") == 0)
-+            pm = RSA_SSLV23_PADDING;
-+        else if (strcmp(value, "none") == 0)
-+            pm = RSA_NO_PADDING;
-+        else if (strcmp(value, "oeap") == 0)
-+            pm = RSA_PKCS1_OAEP_PADDING;
-+        else if (strcmp(value, "oaep") == 0)
-+            pm = RSA_PKCS1_OAEP_PADDING;
-+        else if (strcmp(value, "x931") == 0)
-+            pm = RSA_X931_PADDING;
-+        else if (strcmp(value, "pss") == 0)
-+            pm = RSA_PKCS1_PSS_PADDING;
-+        else {
-+            RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE);
-+            return -2;
-+        }
-+        return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
-+    }
-+
-+    if (strcmp(type, "rsa_pss_saltlen") == 0) {
-+        int saltlen;
-+        saltlen = atoi(value);
-+        return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
-+    }
-+
-+    if (strcmp(type, "rsa_keygen_bits") == 0) {
-+        int nbits;
-+        nbits = atoi(value);
-+        return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
-+    }
-+
-+    if (strcmp(type, "rsa_keygen_pubexp") == 0) {
-+        int ret;
-+        BIGNUM *pubexp = NULL;
-+        if (!BN_asc2bn(&pubexp, value))
-+            return 0;
-+        ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
-+        if (ret <= 0)
-+            BN_free(pubexp);
-+        return ret;
-+    }
-+
-+    if (strcmp(type, "rsa_mgf1_md") == 0) {
-+        const EVP_MD *md;
-+        if ((md = EVP_get_digestbyname(value)) == NULL) {
-+            RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST);
-+            return 0;
-+        }
-+        return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md);
-+    }
-+
-+    if (strcmp(type, "rsa_oaep_md") == 0) {
-+        const EVP_MD *md;
-+        if ((md = EVP_get_digestbyname(value)) == NULL) {
-+            RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST);
-+            return 0;
-+        }
-+        return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md);
-+    }
-+    if (strcmp(type, "rsa_oaep_label") == 0) {
-+        unsigned char *lab;
-+        long lablen;
-+        int ret;
-+        lab = OPENSSL_hexstr2buf(value, &lablen);
-+        if (!lab)
-+            return 0;
-+        ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen);
-+        if (ret <= 0)
-+            OPENSSL_free(lab);
-+        return ret;
-+    }
-+
-+    return -2;
-+}
-+
-+static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
-+{
-+    RSA *rsa = NULL;
-+    RSA_PKEY_CTX *rctx = ctx->data;
-+    BN_GENCB *pcb;
-+    int ret;
-+    if (rctx->pub_exp == NULL) {
-+        rctx->pub_exp = BN_new();
-+        if (rctx->pub_exp == NULL || !BN_set_word(rctx->pub_exp, RSA_F4))
-+            return 0;
-+    }
-+    rsa = RSA_new();
-+    if (rsa == NULL)
-+        return 0;
-+    if (ctx->pkey_gencb) {
-+        pcb = BN_GENCB_new();
-+        if (pcb == NULL) {
-+            RSA_free(rsa);
-+            return 0;
-+        }
-+        evp_pkey_set_cb_translate(pcb, ctx);
-+    } else
-+        pcb = NULL;
-+    ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
-+    BN_GENCB_free(pcb);
-+    if (ret > 0)
-+        EVP_PKEY_assign_RSA(pkey, rsa);
-+    else
-+        RSA_free(rsa);
-+    return ret;
-+}
-+
-+const EVP_PKEY_METHOD rsa_pkey_meth = {
-+    EVP_PKEY_RSA,
-+    EVP_PKEY_FLAG_AUTOARGLEN,
-+    pkey_rsa_init,
-+    pkey_rsa_copy,
-+    pkey_rsa_cleanup,
-+
-+    0, 0,
-+
-+    0,
-+    pkey_rsa_keygen,
-+
-+    0,
-+    pkey_rsa_sign,
-+
-+    0,
-+    pkey_rsa_verify,
-+
-+    0,
-+    pkey_rsa_verifyrecover,
-+
-+    0, 0, 0, 0,
-+
-+    0,
-+    pkey_rsa_encrypt,
-+
-+    0,
-+    pkey_rsa_decrypt,
-+
-+    0, 0,
-+
-+    pkey_rsa_ctrl,
-+    pkey_rsa_ctrl_str
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_prn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_prn.c
-new file mode 100644
-index 0000000..5e6c599
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_prn.c
-@@ -0,0 +1,42 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+#ifndef OPENSSL_NO_STDIO
-+int RSA_print_fp(FILE *fp, const RSA *x, int off)
-+{
-+    BIO *b;
-+    int ret;
-+
-+    if ((b = BIO_new(BIO_s_file())) == NULL) {
-+        RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB);
-+        return (0);
-+    }
-+    BIO_set_fp(b, fp, BIO_NOCLOSE);
-+    ret = RSA_print(b, x, off);
-+    BIO_free(b);
-+    return (ret);
-+}
-+#endif
-+
-+int RSA_print(BIO *bp, const RSA *x, int off)
-+{
-+    EVP_PKEY *pk;
-+    int ret;
-+    pk = EVP_PKEY_new();
-+    if (pk == NULL || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
-+        return 0;
-+    ret = EVP_PKEY_print_private(bp, pk, off, NULL);
-+    EVP_PKEY_free(pk);
-+    return ret;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pss.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pss.c
-new file mode 100644
-index 0000000..0ec63b2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_pss.c
-@@ -0,0 +1,244 @@
-+/*
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "rsa_locl.h"
-+
-+static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-+
-+#if defined(_MSC_VER) && defined(_ARM_)
-+# pragma optimize("g", off)
-+#endif
-+
-+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
-+                         const EVP_MD *Hash, const unsigned char *EM,
-+                         int sLen)
-+{
-+    return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen);
-+}
-+
-+int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
-+                              const EVP_MD *Hash, const EVP_MD *mgf1Hash,
-+                              const unsigned char *EM, int sLen)
-+{
-+    int i;
-+    int ret = 0;
-+    int hLen, maskedDBLen, MSBits, emLen;
-+    const unsigned char *H;
-+    unsigned char *DB = NULL;
-+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
-+    unsigned char H_[EVP_MAX_MD_SIZE];
-+
-+
-+    if (ctx == NULL)
-+        goto err;
-+
-+    if (mgf1Hash == NULL)
-+        mgf1Hash = Hash;
-+
-+    hLen = EVP_MD_size(Hash);
-+    if (hLen < 0)
-+        goto err;
-+    /*-
-+     * Negative sLen has special meanings:
-+     *      -1      sLen == hLen
-+     *      -2      salt length is autorecovered from signature
-+     *      -N      reserved
-+     */
-+    if (sLen == -1)
-+        sLen = hLen;
-+    else if (sLen == -2)
-+        sLen = -2;
-+    else if (sLen < -2) {
-+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
-+        goto err;
-+    }
-+
-+    MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
-+    emLen = RSA_size(rsa);
-+    if (EM[0] & (0xFF << MSBits)) {
-+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
-+        goto err;
-+    }
-+    if (MSBits == 0) {
-+        EM++;
-+        emLen--;
-+    }
-+    if (emLen < (hLen + sLen + 2)) { /* sLen can be small negative */
-+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
-+        goto err;
-+    }
-+    if (EM[emLen - 1] != 0xbc) {
-+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
-+        goto err;
-+    }
-+    maskedDBLen = emLen - hLen - 1;
-+    H = EM + maskedDBLen;
-+    DB = OPENSSL_malloc(maskedDBLen);
-+    if (DB == NULL) {
-+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
-+        goto err;
-+    for (i = 0; i < maskedDBLen; i++)
-+        DB[i] ^= EM[i];
-+    if (MSBits)
-+        DB[0] &= 0xFF >> (8 - MSBits);
-+    for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ;
-+    if (DB[i++] != 0x1) {
-+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
-+        goto err;
-+    }
-+    if (sLen >= 0 && (maskedDBLen - i) != sLen) {
-+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
-+        goto err;
-+    }
-+    if (!EVP_DigestInit_ex(ctx, Hash, NULL)
-+        || !EVP_DigestUpdate(ctx, zeroes, sizeof zeroes)
-+        || !EVP_DigestUpdate(ctx, mHash, hLen))
-+        goto err;
-+    if (maskedDBLen - i) {
-+        if (!EVP_DigestUpdate(ctx, DB + i, maskedDBLen - i))
-+            goto err;
-+    }
-+    if (!EVP_DigestFinal_ex(ctx, H_, NULL))
-+        goto err;
-+    if (memcmp(H_, H, hLen)) {
-+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
-+        ret = 0;
-+    } else
-+        ret = 1;
-+
-+ err:
-+    OPENSSL_free(DB);
-+    EVP_MD_CTX_free(ctx);
-+
-+    return ret;
-+
-+}
-+
-+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
-+                              const unsigned char *mHash,
-+                              const EVP_MD *Hash, int sLen)
-+{
-+    return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen);
-+}
-+
-+int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
-+                                   const unsigned char *mHash,
-+                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
-+                                   int sLen)
-+{
-+    int i;
-+    int ret = 0;
-+    int hLen, maskedDBLen, MSBits, emLen;
-+    unsigned char *H, *salt = NULL, *p;
-+    EVP_MD_CTX *ctx = NULL;
-+
-+    if (mgf1Hash == NULL)
-+        mgf1Hash = Hash;
-+
-+    hLen = EVP_MD_size(Hash);
-+    if (hLen < 0)
-+        goto err;
-+    /*-
-+     * Negative sLen has special meanings:
-+     *      -1      sLen == hLen
-+     *      -2      salt length is maximized
-+     *      -N      reserved
-+     */
-+    if (sLen == -1)
-+        sLen = hLen;
-+    else if (sLen == -2)
-+        sLen = -2;
-+    else if (sLen < -2) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
-+        goto err;
-+    }
-+
-+    MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
-+    emLen = RSA_size(rsa);
-+    if (MSBits == 0) {
-+        *EM++ = 0;
-+        emLen--;
-+    }
-+    if (sLen == -2) {
-+        sLen = emLen - hLen - 2;
-+    } else if (emLen < (hLen + sLen + 2)) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
-+               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-+        goto err;
-+    }
-+    if (sLen > 0) {
-+        salt = OPENSSL_malloc(sLen);
-+        if (salt == NULL) {
-+            RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
-+                   ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+        if (RAND_bytes(salt, sLen) <= 0)
-+            goto err;
-+    }
-+    maskedDBLen = emLen - hLen - 1;
-+    H = EM + maskedDBLen;
-+    ctx = EVP_MD_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+    if (!EVP_DigestInit_ex(ctx, Hash, NULL)
-+        || !EVP_DigestUpdate(ctx, zeroes, sizeof zeroes)
-+        || !EVP_DigestUpdate(ctx, mHash, hLen))
-+        goto err;
-+    if (sLen && !EVP_DigestUpdate(ctx, salt, sLen))
-+        goto err;
-+    if (!EVP_DigestFinal_ex(ctx, H, NULL))
-+        goto err;
-+
-+    /* Generate dbMask in place then perform XOR on it */
-+    if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash))
-+        goto err;
-+
-+    p = EM;
-+
-+    /*
-+     * Initial PS XORs with all zeroes which is a NOP so just update pointer.
-+     * Note from a test above this value is guaranteed to be non-negative.
-+     */
-+    p += emLen - sLen - hLen - 2;
-+    *p++ ^= 0x1;
-+    if (sLen > 0) {
-+        for (i = 0; i < sLen; i++)
-+            *p++ ^= salt[i];
-+    }
-+    if (MSBits)
-+        EM[0] &= 0xFF >> (8 - MSBits);
-+
-+    /* H is already in place so just set final 0xbc */
-+
-+    EM[emLen - 1] = 0xbc;
-+
-+    ret = 1;
-+
-+ err:
-+    EVP_MD_CTX_free(ctx);
-+    OPENSSL_free(salt);
-+
-+    return ret;
-+
-+}
-+
-+#if defined(_MSC_VER)
-+# pragma optimize("",on)
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_saos.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_saos.c
-new file mode 100644
-index 0000000..9e5fff4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_saos.c
-@@ -0,0 +1,94 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+int RSA_sign_ASN1_OCTET_STRING(int type,
-+                               const unsigned char *m, unsigned int m_len,
-+                               unsigned char *sigret, unsigned int *siglen,
-+                               RSA *rsa)
-+{
-+    ASN1_OCTET_STRING sig;
-+    int i, j, ret = 1;
-+    unsigned char *p, *s;
-+
-+    sig.type = V_ASN1_OCTET_STRING;
-+    sig.length = m_len;
-+    sig.data = (unsigned char *)m;
-+
-+    i = i2d_ASN1_OCTET_STRING(&sig, NULL);
-+    j = RSA_size(rsa);
-+    if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
-+        RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,
-+               RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
-+        return (0);
-+    }
-+    s = OPENSSL_malloc((unsigned int)j + 1);
-+    if (s == NULL) {
-+        RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
-+        return (0);
-+    }
-+    p = s;
-+    i2d_ASN1_OCTET_STRING(&sig, &p);
-+    i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
-+    if (i <= 0)
-+        ret = 0;
-+    else
-+        *siglen = i;
-+
-+    OPENSSL_clear_free(s, (unsigned int)j + 1);
-+    return (ret);
-+}
-+
-+int RSA_verify_ASN1_OCTET_STRING(int dtype,
-+                                 const unsigned char *m,
-+                                 unsigned int m_len, unsigned char *sigbuf,
-+                                 unsigned int siglen, RSA *rsa)
-+{
-+    int i, ret = 0;
-+    unsigned char *s;
-+    const unsigned char *p;
-+    ASN1_OCTET_STRING *sig = NULL;
-+
-+    if (siglen != (unsigned int)RSA_size(rsa)) {
-+        RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,
-+               RSA_R_WRONG_SIGNATURE_LENGTH);
-+        return (0);
-+    }
-+
-+    s = OPENSSL_malloc((unsigned int)siglen);
-+    if (s == NULL) {
-+        RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
-+
-+    if (i <= 0)
-+        goto err;
-+
-+    p = s;
-+    sig = d2i_ASN1_OCTET_STRING(NULL, &p, (long)i);
-+    if (sig == NULL)
-+        goto err;
-+
-+    if (((unsigned int)sig->length != m_len) ||
-+        (memcmp(m, sig->data, m_len) != 0)) {
-+        RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, RSA_R_BAD_SIGNATURE);
-+    } else
-+        ret = 1;
-+ err:
-+    ASN1_OCTET_STRING_free(sig);
-+    OPENSSL_clear_free(s, (unsigned int)siglen);
-+    return (ret);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sign.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sign.c
-new file mode 100644
-index 0000000..952d24f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_sign.c
-@@ -0,0 +1,248 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "internal/x509_int.h"
-+#include "rsa_locl.h"
-+
-+/* Size of an SSL signature: MD5+SHA1 */
-+#define SSL_SIG_LENGTH  36
-+
-+/*
-+ * encode_pkcs1 encodes a DigestInfo prefix of hash |type| and digest |m|, as
-+ * described in EMSA-PKCS1-v1_5-ENCODE, RFC 3447 section 9.2 step 2. This
-+ * encodes the DigestInfo (T and tLen) but does not add the padding.
-+ *
-+ * On success, it returns one and sets |*out| to a newly allocated buffer
-+ * containing the result and |*out_len| to its length. The caller must free
-+ * |*out| with |OPENSSL_free|. Otherwise, it returns zero.
-+ */
-+static int encode_pkcs1(unsigned char **out, int *out_len, int type,
-+                        const unsigned char *m, unsigned int m_len)
-+{
-+    X509_SIG sig;
-+    X509_ALGOR algor;
-+    ASN1_TYPE parameter;
-+    ASN1_OCTET_STRING digest;
-+    uint8_t *der = NULL;
-+    int len;
-+
-+    sig.algor = &algor;
-+    sig.algor->algorithm = OBJ_nid2obj(type);
-+    if (sig.algor->algorithm == NULL) {
-+        RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE);
-+        return 0;
-+    }
-+    if (OBJ_length(sig.algor->algorithm) == 0) {
-+        RSAerr(RSA_F_ENCODE_PKCS1,
-+               RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
-+        return 0;
-+    }
-+    parameter.type = V_ASN1_NULL;
-+    parameter.value.ptr = NULL;
-+    sig.algor->parameter = ¶meter;
-+
-+    sig.digest = &digest;
-+    sig.digest->data = (unsigned char *)m;
-+    sig.digest->length = m_len;
-+
-+    len = i2d_X509_SIG(&sig, &der);
-+    if (len < 0)
-+        return 0;
-+
-+    *out = der;
-+    *out_len = len;
-+    return 1;
-+}
-+
-+int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
-+             unsigned char *sigret, unsigned int *siglen, RSA *rsa)
-+{
-+    int encrypt_len, encoded_len = 0, ret = 0;
-+    unsigned char *tmps = NULL;
-+    const unsigned char *encoded = NULL;
-+
-+    if (rsa->meth->rsa_sign) {
-+        return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
-+    }
-+
-+    /* Compute the encoded digest. */
-+    if (type == NID_md5_sha1) {
-+        /*
-+         * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and
-+         * earlier. It has no DigestInfo wrapper but otherwise is
-+         * RSASSA-PKCS1-v1_5.
-+         */
-+        if (m_len != SSL_SIG_LENGTH) {
-+            RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);
-+            return 0;
-+        }
-+        encoded_len = SSL_SIG_LENGTH;
-+        encoded = m;
-+    } else {
-+        if (!encode_pkcs1(&tmps, &encoded_len, type, m, m_len))
-+            goto err;
-+        encoded = tmps;
-+    }
-+
-+    if (encoded_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) {
-+        RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
-+        goto err;
-+    }
-+    encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret, rsa,
-+                                      RSA_PKCS1_PADDING);
-+    if (encrypt_len <= 0)
-+        goto err;
-+
-+    *siglen = encrypt_len;
-+    ret = 1;
-+
-+err:
-+    OPENSSL_clear_free(tmps, (size_t)encoded_len);
-+    return ret;
-+}
-+
-+/*
-+ * int_rsa_verify verifies an RSA signature in |sigbuf| using |rsa|. It may be
-+ * called in two modes. If |rm| is NULL, it verifies the signature for digest
-+ * |m|. Otherwise, it recovers the digest from the signature, writing the digest
-+ * to |rm| and the length to |*prm_len|. |type| is the NID of the digest
-+ * algorithm to use. It returns one on successful verification and zero
-+ * otherwise.
-+ */
-+int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
-+                   unsigned char *rm, size_t *prm_len,
-+                   const unsigned char *sigbuf, size_t siglen, RSA *rsa)
-+{
-+    int decrypt_len, ret = 0, encoded_len = 0;
-+    unsigned char *decrypt_buf = NULL, *encoded = NULL;
-+
-+    if (siglen != (size_t)RSA_size(rsa)) {
-+        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
-+        return 0;
-+    }
-+
-+    /* Recover the encoded digest. */
-+    decrypt_buf = OPENSSL_malloc(siglen);
-+    if (decrypt_buf == NULL) {
-+        RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    decrypt_len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa,
-+                                     RSA_PKCS1_PADDING);
-+    if (decrypt_len <= 0)
-+        goto err;
-+
-+    if (type == NID_md5_sha1) {
-+        /*
-+         * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and
-+         * earlier. It has no DigestInfo wrapper but otherwise is
-+         * RSASSA-PKCS1-v1_5.
-+         */
-+        if (decrypt_len != SSL_SIG_LENGTH) {
-+            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
-+            goto err;
-+        }
-+
-+        if (rm != NULL) {
-+            memcpy(rm, decrypt_buf, SSL_SIG_LENGTH);
-+            *prm_len = SSL_SIG_LENGTH;
-+        } else {
-+            if (m_len != SSL_SIG_LENGTH) {
-+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
-+                goto err;
-+            }
-+
-+            if (memcmp(decrypt_buf, m, SSL_SIG_LENGTH) != 0) {
-+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
-+                goto err;
-+            }
-+        }
-+    } else if (type == NID_mdc2 && decrypt_len == 2 + 16
-+               && decrypt_buf[0] == 0x04 && decrypt_buf[1] == 0x10) {
-+        /*
-+         * Oddball MDC2 case: signature can be OCTET STRING. check for correct
-+         * tag and length octets.
-+         */
-+        if (rm != NULL) {
-+            memcpy(rm, decrypt_buf + 2, 16);
-+            *prm_len = 16;
-+        } else {
-+            if (m_len != 16) {
-+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
-+                goto err;
-+            }
-+
-+            if (memcmp(m, decrypt_buf + 2, 16) != 0) {
-+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
-+                goto err;
-+            }
-+        }
-+    } else {
-+        /*
-+         * If recovering the digest, extract a digest-sized output from the end
-+         * of |decrypt_buf| for |encode_pkcs1|, then compare the decryption
-+         * output as in a standard verification.
-+         */
-+        if (rm != NULL) {
-+            const EVP_MD *md = EVP_get_digestbynid(type);
-+            if (md == NULL) {
-+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE);
-+                goto err;
-+            }
-+
-+            m_len = EVP_MD_size(md);
-+            if (m_len > (size_t)decrypt_len) {
-+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
-+                goto err;
-+            }
-+            m = decrypt_buf + decrypt_len - m_len;
-+        }
-+
-+        /* Construct the encoded digest and ensure it matches. */
-+        if (!encode_pkcs1(&encoded, &encoded_len, type, m, m_len))
-+            goto err;
-+
-+        if (encoded_len != decrypt_len
-+            || memcmp(encoded, decrypt_buf, encoded_len) != 0) {
-+            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
-+            goto err;
-+        }
-+
-+        /* Output the recovered digest. */
-+        if (rm != NULL) {
-+            memcpy(rm, m, m_len);
-+            *prm_len = m_len;
-+        }
-+    }
-+
-+    ret = 1;
-+
-+err:
-+    OPENSSL_clear_free(encoded, (size_t)encoded_len);
-+    OPENSSL_clear_free(decrypt_buf, siglen);
-+    return ret;
-+}
-+
-+int RSA_verify(int type, const unsigned char *m, unsigned int m_len,
-+               const unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
-+{
-+
-+    if (rsa->meth->rsa_verify) {
-+        return rsa->meth->rsa_verify(type, m, m_len, sigbuf, siglen, rsa);
-+    }
-+
-+    return int_rsa_verify(type, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ssl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ssl.c
-new file mode 100644
-index 0000000..9ef6b80
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_ssl.c
-@@ -0,0 +1,100 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+int RSA_padding_add_SSLv23(unsigned char *to, int tlen,
-+                           const unsigned char *from, int flen)
-+{
-+    int i, j;
-+    unsigned char *p;
-+
-+    if (flen > (tlen - 11)) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23,
-+               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-+        return (0);
-+    }
-+
-+    p = (unsigned char *)to;
-+
-+    *(p++) = 0;
-+    *(p++) = 2;                 /* Public Key BT (Block Type) */
-+
-+    /* pad out with non-zero random data */
-+    j = tlen - 3 - 8 - flen;
-+
-+    if (RAND_bytes(p, j) <= 0)
-+        return (0);
-+    for (i = 0; i < j; i++) {
-+        if (*p == '\0')
-+            do {
-+                if (RAND_bytes(p, 1) <= 0)
-+                    return (0);
-+            } while (*p == '\0');
-+        p++;
-+    }
-+
-+    memset(p, 3, 8);
-+    p += 8;
-+    *(p++) = '\0';
-+
-+    memcpy(p, from, (unsigned int)flen);
-+    return (1);
-+}
-+
-+int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
-+                             const unsigned char *from, int flen, int num)
-+{
-+    int i, j, k;
-+    const unsigned char *p;
-+
-+    p = from;
-+    if (flen < 10) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL);
-+        return (-1);
-+    }
-+    if ((num != (flen + 1)) || (*(p++) != 02)) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02);
-+        return (-1);
-+    }
-+
-+    /* scan over padding data */
-+    j = flen - 1;               /* one for type */
-+    for (i = 0; i < j; i++)
-+        if (*(p++) == 0)
-+            break;
-+
-+    if ((i == j) || (i < 8)) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,
-+               RSA_R_NULL_BEFORE_BLOCK_MISSING);
-+        return (-1);
-+    }
-+    for (k = -9; k < -1; k++) {
-+        if (p[k] != 0x03)
-+            break;
-+    }
-+    if (k == -1) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_SSLV3_ROLLBACK_ATTACK);
-+        return (-1);
-+    }
-+
-+    i++;                        /* Skip over the '\0' */
-+    j -= i;
-+    if (j > tlen) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_LARGE);
-+        return (-1);
-+    }
-+    memcpy(to, p, (unsigned int)j);
-+
-+    return (j);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_x931.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_x931.c
-new file mode 100644
-index 0000000..b9301f3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_x931.c
-@@ -0,0 +1,116 @@
-+/*
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+int RSA_padding_add_X931(unsigned char *to, int tlen,
-+                         const unsigned char *from, int flen)
-+{
-+    int j;
-+    unsigned char *p;
-+
-+    /*
-+     * Absolute minimum amount of padding is 1 header nibble, 1 padding
-+     * nibble and 2 trailer bytes: but 1 hash if is already in 'from'.
-+     */
-+
-+    j = tlen - flen - 2;
-+
-+    if (j < 0) {
-+        RSAerr(RSA_F_RSA_PADDING_ADD_X931, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-+        return -1;
-+    }
-+
-+    p = (unsigned char *)to;
-+
-+    /* If no padding start and end nibbles are in one byte */
-+    if (j == 0)
-+        *p++ = 0x6A;
-+    else {
-+        *p++ = 0x6B;
-+        if (j > 1) {
-+            memset(p, 0xBB, j - 1);
-+            p += j - 1;
-+        }
-+        *p++ = 0xBA;
-+    }
-+    memcpy(p, from, (unsigned int)flen);
-+    p += flen;
-+    *p = 0xCC;
-+    return (1);
-+}
-+
-+int RSA_padding_check_X931(unsigned char *to, int tlen,
-+                           const unsigned char *from, int flen, int num)
-+{
-+    int i = 0, j;
-+    const unsigned char *p;
-+
-+    p = from;
-+    if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER);
-+        return -1;
-+    }
-+
-+    if (*p++ == 0x6B) {
-+        j = flen - 3;
-+        for (i = 0; i < j; i++) {
-+            unsigned char c = *p++;
-+            if (c == 0xBA)
-+                break;
-+            if (c != 0xBB) {
-+                RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
-+                return -1;
-+            }
-+        }
-+
-+        j -= i;
-+
-+        if (i == 0) {
-+            RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
-+            return -1;
-+        }
-+
-+    } else
-+        j = flen - 2;
-+
-+    if (p[j] != 0xCC) {
-+        RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER);
-+        return -1;
-+    }
-+
-+    memcpy(to, p, (unsigned int)j);
-+
-+    return (j);
-+}
-+
-+/* Translate between X931 hash ids and NIDs */
-+
-+int RSA_X931_hash_id(int nid)
-+{
-+    switch (nid) {
-+    case NID_sha1:
-+        return 0x33;
-+
-+    case NID_sha256:
-+        return 0x34;
-+
-+    case NID_sha384:
-+        return 0x36;
-+
-+    case NID_sha512:
-+        return 0x35;
-+
-+    }
-+    return -1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_x931g.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_x931g.c
-new file mode 100644
-index 0000000..9dd993f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/rsa/rsa_x931g.c
-@@ -0,0 +1,195 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "rsa_locl.h"
-+
-+/* X9.31 RSA key derivation and generation */
-+
-+int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1,
-+                       BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2,
-+                       const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2,
-+                       const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb)
-+{
-+    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL;
-+    BN_CTX *ctx = NULL, *ctx2 = NULL;
-+    int ret = 0;
-+
-+    if (!rsa)
-+        goto err;
-+
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto err;
-+    BN_CTX_start(ctx);
-+
-+    r0 = BN_CTX_get(ctx);
-+    r1 = BN_CTX_get(ctx);
-+    r2 = BN_CTX_get(ctx);
-+    r3 = BN_CTX_get(ctx);
-+
-+    if (r3 == NULL)
-+        goto err;
-+    if (!rsa->e) {
-+        rsa->e = BN_dup(e);
-+        if (!rsa->e)
-+            goto err;
-+    } else
-+        e = rsa->e;
-+
-+    /*
-+     * If not all parameters present only calculate what we can. This allows
-+     * test programs to output selective parameters.
-+     */
-+
-+    if (Xp && rsa->p == NULL) {
-+        rsa->p = BN_new();
-+        if (rsa->p == NULL)
-+            goto err;
-+
-+        if (!BN_X931_derive_prime_ex(rsa->p, p1, p2,
-+                                     Xp, Xp1, Xp2, e, ctx, cb))
-+            goto err;
-+    }
-+
-+    if (Xq && rsa->q == NULL) {
-+        rsa->q = BN_new();
-+        if (rsa->q == NULL)
-+            goto err;
-+        if (!BN_X931_derive_prime_ex(rsa->q, q1, q2,
-+                                     Xq, Xq1, Xq2, e, ctx, cb))
-+            goto err;
-+    }
-+
-+    if (rsa->p == NULL || rsa->q == NULL) {
-+        BN_CTX_end(ctx);
-+        BN_CTX_free(ctx);
-+        return 2;
-+    }
-+
-+    /*
-+     * Since both primes are set we can now calculate all remaining
-+     * components.
-+     */
-+
-+    /* calculate n */
-+    rsa->n = BN_new();
-+    if (rsa->n == NULL)
-+        goto err;
-+    if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx))
-+        goto err;
-+
-+    /* calculate d */
-+    if (!BN_sub(r1, rsa->p, BN_value_one()))
-+        goto err;               /* p-1 */
-+    if (!BN_sub(r2, rsa->q, BN_value_one()))
-+        goto err;               /* q-1 */
-+    if (!BN_mul(r0, r1, r2, ctx))
-+        goto err;               /* (p-1)(q-1) */
-+
-+    if (!BN_gcd(r3, r1, r2, ctx))
-+        goto err;
-+
-+    if (!BN_div(r0, NULL, r0, r3, ctx))
-+        goto err;               /* LCM((p-1)(q-1)) */
-+
-+    ctx2 = BN_CTX_new();
-+    if (ctx2 == NULL)
-+        goto err;
-+
-+    rsa->d = BN_mod_inverse(NULL, rsa->e, r0, ctx2); /* d */
-+    if (rsa->d == NULL)
-+        goto err;
-+
-+    /* calculate d mod (p-1) */
-+    rsa->dmp1 = BN_new();
-+    if (rsa->dmp1 == NULL)
-+        goto err;
-+    if (!BN_mod(rsa->dmp1, rsa->d, r1, ctx))
-+        goto err;
-+
-+    /* calculate d mod (q-1) */
-+    rsa->dmq1 = BN_new();
-+    if (rsa->dmq1 == NULL)
-+        goto err;
-+    if (!BN_mod(rsa->dmq1, rsa->d, r2, ctx))
-+        goto err;
-+
-+    /* calculate inverse of q mod p */
-+    rsa->iqmp = BN_mod_inverse(NULL, rsa->q, rsa->p, ctx2);
-+
-+    ret = 1;
-+ err:
-+    if (ctx)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+    BN_CTX_free(ctx2);
-+
-+    return ret;
-+
-+}
-+
-+int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e,
-+                             BN_GENCB *cb)
-+{
-+    int ok = 0;
-+    BIGNUM *Xp = NULL, *Xq = NULL;
-+    BN_CTX *ctx = NULL;
-+
-+    ctx = BN_CTX_new();
-+    if (ctx == NULL)
-+        goto error;
-+
-+    BN_CTX_start(ctx);
-+    Xp = BN_CTX_get(ctx);
-+    Xq = BN_CTX_get(ctx);
-+    if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx))
-+        goto error;
-+
-+    rsa->p = BN_new();
-+    rsa->q = BN_new();
-+    if (rsa->p == NULL || rsa->q == NULL)
-+        goto error;
-+
-+    /* Generate two primes from Xp, Xq */
-+
-+    if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp,
-+                                   e, ctx, cb))
-+        goto error;
-+
-+    if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq,
-+                                   e, ctx, cb))
-+        goto error;
-+
-+    /*
-+     * Since rsa->p and rsa->q are valid this call will just derive remaining
-+     * RSA components.
-+     */
-+
-+    if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL,
-+                            NULL, NULL, NULL, NULL, NULL, NULL, e, cb))
-+        goto error;
-+
-+    ok = 1;
-+
-+ error:
-+    if (ctx)
-+        BN_CTX_end(ctx);
-+    BN_CTX_free(ctx);
-+
-+    if (ok)
-+        return 1;
-+
-+    return 0;
-+
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/s390xcap.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/s390xcap.c
-new file mode 100644
-index 0000000..675f2ec
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/s390xcap.c
-@@ -0,0 +1,50 @@
-+/*
-+ * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+extern unsigned long OPENSSL_s390xcap_P[];
-+
-+static sigjmp_buf ill_jmp;
-+static void ill_handler(int sig)
-+{
-+    siglongjmp(ill_jmp, sig);
-+}
-+
-+unsigned long OPENSSL_s390x_facilities(void);
-+
-+void OPENSSL_cpuid_setup(void)
-+{
-+    sigset_t oset;
-+    struct sigaction ill_act, oact;
-+
-+    if (OPENSSL_s390xcap_P[0])
-+        return;
-+
-+    OPENSSL_s390xcap_P[0] = 1UL << (8 * sizeof(unsigned long) - 1);
-+
-+    memset(&ill_act, 0, sizeof(ill_act));
-+    ill_act.sa_handler = ill_handler;
-+    sigfillset(&ill_act.sa_mask);
-+    sigdelset(&ill_act.sa_mask, SIGILL);
-+    sigdelset(&ill_act.sa_mask, SIGTRAP);
-+    sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
-+    sigaction(SIGILL, &ill_act, &oact);
-+
-+    /* protection against missing store-facility-list-extended */
-+    if (sigsetjmp(ill_jmp, 1) == 0)
-+        OPENSSL_s390x_facilities();
-+
-+    sigaction(SIGILL, &oact, NULL);
-+    sigprocmask(SIG_SETMASK, &oset, NULL);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/s390xcpuid.S b/CryptoPkg/Library/OpensslLib/openssl/crypto/s390xcpuid.S
-new file mode 100644
-index 0000000..8859e9e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/s390xcpuid.S
-@@ -0,0 +1,180 @@
-+.text
-+// Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+//
-+// Licensed under the OpenSSL license (the "License").  You may not use
-+// this file except in compliance with the License.  You can obtain a copy
-+// in the file LICENSE in the source distribution or at
-+// https://www.openssl.org/source/license.html
-+
-+.globl	OPENSSL_s390x_facilities
-+.type	OPENSSL_s390x_facilities,@function
-+.align	16
-+OPENSSL_s390x_facilities:
-+	lghi	%r0,0
-+	larl	%r4,OPENSSL_s390xcap_P
-+	stg	%r0,8(%r4)	# wipe capability vectors
-+	stg	%r0,16(%r4)
-+	stg	%r0,24(%r4)
-+	stg	%r0,32(%r4)
-+	stg	%r0,40(%r4)
-+	stg	%r0,48(%r4)
-+	stg	%r0,56(%r4)
-+	stg	%r0,64(%r4)
-+	stg	%r0,72(%r4)
-+
-+	.long	0xb2b04000	# stfle	0(%r4)
-+	brc	8,.Ldone
-+	lghi	%r0,1
-+	.long	0xb2b04000	# stfle 0(%r4)
-+.Ldone:
-+	lmg	%r2,%r3,0(%r4)
-+	tmhl	%r2,0x4000	# check for message-security-assist
-+	jz	.Lret
-+
-+	lghi	%r0,0		# query kimd capabilities
-+	la	%r1,16(%r4)
-+	.long	0xb93e0002	# kimd %r0,%r2
-+
-+	lghi	%r0,0		# query km capability vector
-+	la	%r1,32(%r4)
-+	.long	0xb92e0042	# km %r4,%r2
-+
-+	lghi	%r0,0		# query kmc capability vector
-+	la	%r1,48(%r4)
-+	.long	0xb92f0042	# kmc %r4,%r2
-+
-+	tmhh	%r3,0x0004	# check for message-security-assist-4
-+	jz	.Lret
-+
-+	lghi	%r0,0		# query kmctr capability vector
-+	la	%r1,64(%r4)
-+	.long	0xb92d2042	# kmctr %r4,%r2,%r2
-+
-+.Lret:
-+	br	%r14
-+.size	OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
-+
-+.globl	OPENSSL_rdtsc
-+.type	OPENSSL_rdtsc,@function
-+.align	16
-+OPENSSL_rdtsc:
-+	stck	16(%r15)
-+	lg	%r2,16(%r15)
-+	br	%r14
-+.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
-+
-+.globl	OPENSSL_atomic_add
-+.type	OPENSSL_atomic_add,@function
-+.align	16
-+OPENSSL_atomic_add:
-+	l	%r1,0(%r2)
-+.Lspin:	lr	%r0,%r1
-+	ar	%r0,%r3
-+	cs	%r1,%r0,0(%r2)
-+	brc	4,.Lspin
-+	lgfr	%r2,%r0		# OpenSSL expects the new value
-+	br	%r14
-+.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
-+
-+.globl	OPENSSL_wipe_cpu
-+.type	OPENSSL_wipe_cpu,@function
-+.align	16
-+OPENSSL_wipe_cpu:
-+	xgr	%r0,%r0
-+	xgr	%r1,%r1
-+	lgr	%r2,%r15
-+	xgr	%r3,%r3
-+	xgr	%r4,%r4
-+	lzdr	%f0
-+	lzdr	%f1
-+	lzdr	%f2
-+	lzdr	%f3
-+	lzdr	%f4
-+	lzdr	%f5
-+	lzdr	%f6
-+	lzdr	%f7
-+	br	%r14
-+.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
-+
-+.globl	OPENSSL_cleanse
-+.type	OPENSSL_cleanse,@function
-+.align	16
-+OPENSSL_cleanse:
-+#if !defined(__s390x__) && !defined(__s390x)
-+	llgfr	%r3,%r3
-+#endif
-+	lghi	%r4,15
-+	lghi	%r0,0
-+	clgr	%r3,%r4
-+	jh	.Lot
-+	clgr	%r3,%r0
-+	bcr	8,%r14
-+.Little:
-+	stc	%r0,0(%r2)
-+	la	%r2,1(%r2)
-+	brctg	%r3,.Little
-+	br	%r14
-+.align	4
-+.Lot:	tmll	%r2,7
-+	jz	.Laligned
-+	stc	%r0,0(%r2)
-+	la	%r2,1(%r2)
-+	brctg	%r3,.Lot
-+.Laligned:
-+	srlg	%r4,%r3,3
-+.Loop:	stg	%r0,0(%r2)
-+	la	%r2,8(%r2)
-+	brctg	%r4,.Loop
-+	lghi	%r4,7
-+	ngr	%r3,%r4
-+	jnz	.Little
-+	br	%r14
-+.size	OPENSSL_cleanse,.-OPENSSL_cleanse
-+
-+.globl	CRYPTO_memcmp
-+.type	CRYPTO_memcmp,@function
-+.align	16
-+CRYPTO_memcmp:
-+#if !defined(__s390x__) && !defined(__s390x)
-+	llgfr	%r4,%r4
-+#endif
-+	lghi	%r5,0
-+	clgr	%r4,%r5
-+	je	.Lno_data
-+
-+.Loop_cmp:
-+	llgc	%r0,0(%r2)
-+	la	%r2,1(%r2)
-+	llgc	%r1,0(%r3)
-+	la	%r3,1(%r3)
-+	xr	%r1,%r0
-+	or	%r5,%r1
-+	brctg	%r4,.Loop_cmp
-+
-+	lnr	%r5,%r5
-+	srl	%r5,31
-+.Lno_data:
-+	lgr	%r2,%r5
-+	br	%r14
-+.size	CRYPTO_memcmp,.-CRYPTO_memcmp
-+
-+.globl	OPENSSL_instrument_bus
-+.type	OPENSSL_instrument_bus,@function
-+.align	16
-+OPENSSL_instrument_bus:
-+	lghi	%r2,0
-+	br	%r14
-+.size	OPENSSL_instrument_bus,.-OPENSSL_instrument_bus
-+
-+.globl	OPENSSL_instrument_bus2
-+.type	OPENSSL_instrument_bus2,@function
-+.align	16
-+OPENSSL_instrument_bus2:
-+	lghi	%r2,0
-+	br	%r14
-+.size	OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2
-+
-+.section	.init
-+	brasl	%r14,OPENSSL_cpuid_setup
-+
-+.comm	OPENSSL_s390xcap_P,80,8
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/build.info
-new file mode 100644
-index 0000000..abdcbca
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/build.info
-@@ -0,0 +1,2 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=seed.c seed_ecb.c seed_cbc.c seed_cfb.c seed_ofb.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed.c
-new file mode 100644
-index 0000000..c1e9285
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed.c
-@@ -0,0 +1,590 @@
-+/*
-+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Neither the name of author nor the names of its contributors may
-+ *    be used to endorse or promote products derived from this software
-+ *    without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ */
-+#ifndef OPENSSL_NO_SEED
-+
-+# include 
-+# include 
-+# include 
-+# ifdef WIN32
-+#  include 
-+# endif
-+
-+# include 
-+# include "seed_locl.h"
-+
-+# ifdef SS                      /* can get defined on Solaris by inclusion of
-+                                 *  */
-+#  undef SS
-+# endif
-+
-+# if !defined(OPENSSL_SMALL_FOOTPRINT)
-+
-+#  define G_FUNC(v)       \
-+        SS[0][(unsigned char)      (v) & 0xff] ^ \
-+        SS[1][(unsigned char) ((v)>>8) & 0xff] ^ \
-+        SS[2][(unsigned char)((v)>>16) & 0xff] ^ \
-+        SS[3][(unsigned char)((v)>>24) & 0xff]
-+
-+static const seed_word SS[4][256] = {
-+    { 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0,
-+      0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
-+      0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
-+      0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
-+      0x28082028, 0x04444044, 0x20002020, 0x1d8d919c,
-+      0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
-+      0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378,
-+      0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec,
-+      0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
-+      0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074,
-+      0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354,
-+      0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
-+      0x24042024, 0x1c0c101c, 0x33437370, 0x18889098,
-+      0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8,
-+      0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
-+      0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8,
-+      0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8,
-+      0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
-+      0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078,
-+      0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4,
-+      0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
-+      0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008,
-+      0x1f0f131c, 0x19899198, 0x00000000, 0x19091118,
-+      0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
-+      0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324,
-+      0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8,
-+      0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
-+      0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208,
-+      0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4,
-+      0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
-+      0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218,
-+      0x06060204, 0x21012120, 0x2b4b6368, 0x26466264,
-+      0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
-+      0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0,
-+      0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4,
-+      0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
-+      0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac,
-+      0x36063234, 0x15051114, 0x22022220, 0x38083038,
-+      0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
-+      0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394,
-+      0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c,
-+      0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
-+      0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8,
-+      0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4,
-+      0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
-+      0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8,
-+      0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320,
-+      0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
-+      0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0,
-+      0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040,
-+      0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
-+      0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154,
-+      0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c,
-+      0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
-+      0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244,
-+      0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8,
-+      0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
-+      0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0,
-+      0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c,
-+      0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
-+      0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4,
-+      0x22426260, 0x29092128, 0x07070304, 0x33033330,
-+      0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
-+      0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298
-+    },
-+    { 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2,
-+      0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0,
-+      0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
-+      0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53,
-+      0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1,
-+      0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
-+      0xd013c3d3, 0x90118191, 0x10110111, 0x04060602,
-+      0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43,
-+      0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
-+      0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0,
-+      0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2,
-+      0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
-+      0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32,
-+      0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3,
-+      0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
-+      0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272,
-+      0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0,
-+      0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
-+      0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13,
-+      0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430,
-+      0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
-+      0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0,
-+      0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1,
-+      0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
-+      0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131,
-+      0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1,
-+      0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
-+      0x20220222, 0x04040400, 0x68284860, 0x70314171,
-+      0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991,
-+      0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
-+      0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0,
-+      0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0,
-+      0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
-+      0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3,
-+      0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2,
-+      0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
-+      0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32,
-+      0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62,
-+      0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
-+      0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0,
-+      0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571,
-+      0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
-+      0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470,
-+      0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901,
-+      0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
-+      0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501,
-+      0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22,
-+      0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
-+      0x84058581, 0x14140410, 0x88098981, 0x981b8b93,
-+      0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971,
-+      0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
-+      0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53,
-+      0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11,
-+      0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
-+      0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3,
-+      0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1,
-+      0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
-+      0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70,
-+      0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622,
-+      0x30320232, 0x84048480, 0x68294961, 0x90138393,
-+      0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0,
-+      0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783,
-+      0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
-+      0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3
-+    },
-+    { 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3,
-+      0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505,
-+      0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
-+      0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343,
-+      0x20282808, 0x40440444, 0x20202000, 0x919c1d8d,
-+      0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
-+      0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b,
-+      0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece,
-+      0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
-+      0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444,
-+      0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747,
-+      0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
-+      0x20242404, 0x101c1c0c, 0x73703343, 0x90981888,
-+      0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9,
-+      0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
-+      0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9,
-+      0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb,
-+      0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
-+      0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848,
-+      0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5,
-+      0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
-+      0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808,
-+      0x131c1f0f, 0x91981989, 0x00000000, 0x11181909,
-+      0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
-+      0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707,
-+      0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b,
-+      0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
-+      0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a,
-+      0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5,
-+      0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
-+      0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a,
-+      0x02040606, 0x21202101, 0x63682b4b, 0x62642646,
-+      0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
-+      0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0,
-+      0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5,
-+      0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
-+      0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e,
-+      0x32343606, 0x11141505, 0x22202202, 0x30383808,
-+      0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
-+      0x81800181, 0xe1e829c9, 0x80840484, 0x93941787,
-+      0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c,
-+      0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
-+      0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8,
-+      0x90941484, 0x51581949, 0x82800282, 0xc0c404c4,
-+      0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
-+      0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888,
-+      0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303,
-+      0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
-+      0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2,
-+      0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040,
-+      0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
-+      0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545,
-+      0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f,
-+      0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
-+      0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646,
-+      0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca,
-+      0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
-+      0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282,
-+      0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f,
-+      0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
-+      0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4,
-+      0x62602242, 0x21282909, 0x03040707, 0x33303303,
-+      0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
-+      0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a
-+    },
-+    { 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426,
-+      0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838,
-+      0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
-+      0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b,
-+      0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435,
-+      0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
-+      0xc3d3d013, 0x81919011, 0x01111011, 0x06020406,
-+      0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b,
-+      0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
-+      0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434,
-+      0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416,
-+      0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
-+      0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e,
-+      0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f,
-+      0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
-+      0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032,
-+      0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000,
-+      0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
-+      0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f,
-+      0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434,
-+      0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
-+      0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838,
-+      0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405,
-+      0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
-+      0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031,
-+      0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031,
-+      0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
-+      0x02222022, 0x04000404, 0x48606828, 0x41717031,
-+      0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819,
-+      0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
-+      0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c,
-+      0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010,
-+      0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
-+      0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f,
-+      0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022,
-+      0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
-+      0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a,
-+      0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e,
-+      0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
-+      0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c,
-+      0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435,
-+      0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
-+      0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434,
-+      0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809,
-+      0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
-+      0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405,
-+      0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a,
-+      0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
-+      0x85818405, 0x04101414, 0x89818809, 0x8b93981b,
-+      0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839,
-+      0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
-+      0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f,
-+      0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d,
-+      0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
-+      0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b,
-+      0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d,
-+      0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
-+      0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c,
-+      0x0e020c0e, 0x40505010, 0x09313839, 0x06222426,
-+      0x02323032, 0x84808404, 0x49616829, 0x83939013,
-+      0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424,
-+      0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407,
-+      0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
-+      0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437
-+    }
-+};
-+
-+#else
-+
-+/* on x86_64 >5x size reduction at 40% performance penalty */
-+static const unsigned char SEED_Sbox[2][256] = {
-+{
-+      0xA9, 0x85, 0xD6, 0xD3, 0x54, 0x1D, 0xAC, 0x25,
-+      0x5D, 0x43, 0x18, 0x1E, 0x51, 0xFC, 0xCA, 0x63,
-+      0x28, 0x44, 0x20, 0x9D, 0xE0, 0xE2, 0xC8, 0x17,
-+      0xA5, 0x8F, 0x03, 0x7B, 0xBB, 0x13, 0xD2, 0xEE,
-+      0x70, 0x8C, 0x3F, 0xA8, 0x32, 0xDD, 0xF6, 0x74,
-+      0xEC, 0x95, 0x0B, 0x57, 0x5C, 0x5B, 0xBD, 0x01,
-+      0x24, 0x1C, 0x73, 0x98, 0x10, 0xCC, 0xF2, 0xD9,
-+      0x2C, 0xE7, 0x72, 0x83, 0x9B, 0xD1, 0x86, 0xC9,
-+      0x60, 0x50, 0xA3, 0xEB, 0x0D, 0xB6, 0x9E, 0x4F,
-+      0xB7, 0x5A, 0xC6, 0x78, 0xA6, 0x12, 0xAF, 0xD5,
-+      0x61, 0xC3, 0xB4, 0x41, 0x52, 0x7D, 0x8D, 0x08,
-+      0x1F, 0x99, 0x00, 0x19, 0x04, 0x53, 0xF7, 0xE1,
-+      0xFD, 0x76, 0x2F, 0x27, 0xB0, 0x8B, 0x0E, 0xAB,
-+      0xA2, 0x6E, 0x93, 0x4D, 0x69, 0x7C, 0x09, 0x0A,
-+      0xBF, 0xEF, 0xF3, 0xC5, 0x87, 0x14, 0xFE, 0x64,
-+      0xDE, 0x2E, 0x4B, 0x1A, 0x06, 0x21, 0x6B, 0x66,
-+      0x02, 0xF5, 0x92, 0x8A, 0x0C, 0xB3, 0x7E, 0xD0,
-+      0x7A, 0x47, 0x96, 0xE5, 0x26, 0x80, 0xAD, 0xDF,
-+      0xA1, 0x30, 0x37, 0xAE, 0x36, 0x15, 0x22, 0x38,
-+      0xF4, 0xA7, 0x45, 0x4C, 0x81, 0xE9, 0x84, 0x97,
-+      0x35, 0xCB, 0xCE, 0x3C, 0x71, 0x11, 0xC7, 0x89,
-+      0x75, 0xFB, 0xDA, 0xF8, 0x94, 0x59, 0x82, 0xC4,
-+      0xFF, 0x49, 0x39, 0x67, 0xC0, 0xCF, 0xD7, 0xB8,
-+      0x0F, 0x8E, 0x42, 0x23, 0x91, 0x6C, 0xDB, 0xA4,
-+      0x34, 0xF1, 0x48, 0xC2, 0x6F, 0x3D, 0x2D, 0x40,
-+      0xBE, 0x3E, 0xBC, 0xC1, 0xAA, 0xBA, 0x4E, 0x55,
-+      0x3B, 0xDC, 0x68, 0x7F, 0x9C, 0xD8, 0x4A, 0x56,
-+      0x77, 0xA0, 0xED, 0x46, 0xB5, 0x2B, 0x65, 0xFA,
-+      0xE3, 0xB9, 0xB1, 0x9F, 0x5E, 0xF9, 0xE6, 0xB2,
-+      0x31, 0xEA, 0x6D, 0x5F, 0xE4, 0xF0, 0xCD, 0x88,
-+      0x16, 0x3A, 0x58, 0xD4, 0x62, 0x29, 0x07, 0x33,
-+      0xE8, 0x1B, 0x05, 0x79, 0x90, 0x6A, 0x2A, 0x9A
-+    },
-+    {
-+      0x38, 0xE8, 0x2D, 0xA6, 0xCF, 0xDE, 0xB3, 0xB8,
-+      0xAF, 0x60, 0x55, 0xC7, 0x44, 0x6F, 0x6B, 0x5B,
-+      0xC3, 0x62, 0x33, 0xB5, 0x29, 0xA0, 0xE2, 0xA7,
-+      0xD3, 0x91, 0x11, 0x06, 0x1C, 0xBC, 0x36, 0x4B,
-+      0xEF, 0x88, 0x6C, 0xA8, 0x17, 0xC4, 0x16, 0xF4,
-+      0xC2, 0x45, 0xE1, 0xD6, 0x3F, 0x3D, 0x8E, 0x98,
-+      0x28, 0x4E, 0xF6, 0x3E, 0xA5, 0xF9, 0x0D, 0xDF,
-+      0xD8, 0x2B, 0x66, 0x7A, 0x27, 0x2F, 0xF1, 0x72,
-+      0x42, 0xD4, 0x41, 0xC0, 0x73, 0x67, 0xAC, 0x8B,
-+      0xF7, 0xAD, 0x80, 0x1F, 0xCA, 0x2C, 0xAA, 0x34,
-+      0xD2, 0x0B, 0xEE, 0xE9, 0x5D, 0x94, 0x18, 0xF8,
-+      0x57, 0xAE, 0x08, 0xC5, 0x13, 0xCD, 0x86, 0xB9,
-+      0xFF, 0x7D, 0xC1, 0x31, 0xF5, 0x8A, 0x6A, 0xB1,
-+      0xD1, 0x20, 0xD7, 0x02, 0x22, 0x04, 0x68, 0x71,
-+      0x07, 0xDB, 0x9D, 0x99, 0x61, 0xBE, 0xE6, 0x59,
-+      0xDD, 0x51, 0x90, 0xDC, 0x9A, 0xA3, 0xAB, 0xD0,
-+      0x81, 0x0F, 0x47, 0x1A, 0xE3, 0xEC, 0x8D, 0xBF,
-+      0x96, 0x7B, 0x5C, 0xA2, 0xA1, 0x63, 0x23, 0x4D,
-+      0xC8, 0x9E, 0x9C, 0x3A, 0x0C, 0x2E, 0xBA, 0x6E,
-+      0x9F, 0x5A, 0xF2, 0x92, 0xF3, 0x49, 0x78, 0xCC,
-+      0x15, 0xFB, 0x70, 0x75, 0x7F, 0x35, 0x10, 0x03,
-+      0x64, 0x6D, 0xC6, 0x74, 0xD5, 0xB4, 0xEA, 0x09,
-+      0x76, 0x19, 0xFE, 0x40, 0x12, 0xE0, 0xBD, 0x05,
-+      0xFA, 0x01, 0xF0, 0x2A, 0x5E, 0xA9, 0x56, 0x43,
-+      0x85, 0x14, 0x89, 0x9B, 0xB0, 0xE5, 0x48, 0x79,
-+      0x97, 0xFC, 0x1E, 0x82, 0x21, 0x8C, 0x1B, 0x5F,
-+      0x77, 0x54, 0xB2, 0x1D, 0x25, 0x4F, 0x00, 0x46,
-+      0xED, 0x58, 0x52, 0xEB, 0x7E, 0xDA, 0xC9, 0xFD,
-+      0x30, 0x95, 0x65, 0x3C, 0xB6, 0xE4, 0xBB, 0x7C,
-+      0x0E, 0x50, 0x39, 0x26, 0x32, 0x84, 0x69, 0x93,
-+      0x37, 0xE7, 0x24, 0xA4, 0xCB, 0x53, 0x0A, 0x87,
-+      0xD9, 0x4C, 0x83, 0x8F, 0xCE, 0x3B, 0x4A, 0xB7
-+    }
-+};
-+
-+static unsigned int G_FUNC(unsigned int v)
-+{
-+    unsigned int s0, s1, s2, s3, ret;
-+
-+    s0 = SEED_Sbox[0][(unsigned char)      (v) & 0xff];
-+    s1 = SEED_Sbox[1][(unsigned char)((v)>> 8) & 0xff];
-+    s2 = SEED_Sbox[0][(unsigned char)((v)>>16) & 0xff];
-+    s3 = SEED_Sbox[1][(unsigned char)((v)>>24) & 0xff];
-+
-+    ret  = ((s0 & 0xFC) ^ (s1 & 0xF3) ^ (s2 & 0xCF) ^ (s3 & 0x3F));
-+    ret |= ((s0 & 0xF3) ^ (s1 & 0xCF) ^ (s2 & 0x3F) ^ (s3 & 0xFC)) << 8;
-+    ret |= ((s0 & 0xCF) ^ (s1 & 0x3F) ^ (s2 & 0xFC) ^ (s3 & 0xF3)) << 16;
-+    ret |= ((s0 & 0x3F) ^ (s1 & 0xFC) ^ (s2 & 0xF3) ^ (s3 & 0xCF)) << 24;
-+
-+    return ret;
-+}
-+# endif
-+
-+/* key schedule constants - golden ratio */
-+# define KC0     0x9e3779b9
-+# define KC1     0x3c6ef373
-+# define KC2     0x78dde6e6
-+# define KC3     0xf1bbcdcc
-+# define KC4     0xe3779b99
-+# define KC5     0xc6ef3733
-+# define KC6     0x8dde6e67
-+# define KC7     0x1bbcdccf
-+# define KC8     0x3779b99e
-+# define KC9     0x6ef3733c
-+# define KC10    0xdde6e678
-+# define KC11    0xbbcdccf1
-+# define KC12    0x779b99e3
-+# define KC13    0xef3733c6
-+# define KC14    0xde6e678d
-+# define KC15    0xbcdccf1b
-+
-+# if defined(OPENSSL_SMALL_FOOTPRINT)
-+static const seed_word KC[] = {
-+    KC0, KC1, KC2, KC3, KC4, KC5, KC6, KC7,
-+    KC8, KC9, KC10, KC11, KC12, KC13, KC14, KC15
-+};
-+# endif
-+
-+void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
-+                  SEED_KEY_SCHEDULE *ks)
-+{
-+    seed_word x1, x2, x3, x4;
-+    seed_word t0, t1;
-+
-+    char2word(rawkey, x1);
-+    char2word(rawkey + 4, x2);
-+    char2word(rawkey + 8, x3);
-+    char2word(rawkey + 12, x4);
-+
-+    t0 = (x1 + x3 - KC0) & 0xffffffff;
-+    t1 = (x2 - x4 + KC0) & 0xffffffff;
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[0]);
-+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[2]);
-+
-+# if !defined(OPENSSL_SMALL_FOOTPRINT)
-+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[4]);
-+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[6]);
-+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[8]);
-+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[10]);
-+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[12]);
-+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[14]);
-+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[16]);
-+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[18]);
-+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[20]);
-+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[22]);
-+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[24]);
-+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[26]);
-+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[28]);
-+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15);
-+    KEYUPDATE_TEMP(t0, t1, &ks->data[30]);
-+# else
-+    {
-+        int i;
-+        for (i = 2; i < 16; i += 2) {
-+            KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC[i]);
-+            KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2]);
-+            KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC[i + 1]);
-+            KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2 + 2]);
-+        }
-+    }
-+# endif
-+}
-+
-+void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE],
-+                  unsigned char d[SEED_BLOCK_SIZE],
-+                  const SEED_KEY_SCHEDULE *ks)
-+{
-+    seed_word x1, x2, x3, x4;
-+    seed_word t0, t1;
-+
-+    char2word(s, x1);
-+    char2word(s + 4, x2);
-+    char2word(s + 8, x3);
-+    char2word(s + 12, x4);
-+
-+# if !defined(OPENSSL_SMALL_FOOTPRINT)
-+    E_SEED(t0, t1, x1, x2, x3, x4, 0);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 2);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 4);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 6);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 8);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 10);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 12);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 14);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 16);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 18);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 20);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 22);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 24);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 26);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 28);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 30);
-+# else
-+    {
-+        int i;
-+        for (i = 0; i < 30; i += 4) {
-+            E_SEED(t0, t1, x1, x2, x3, x4, i);
-+            E_SEED(t0, t1, x3, x4, x1, x2, i + 2);
-+        }
-+    }
-+# endif
-+
-+    word2char(x3, d);
-+    word2char(x4, d + 4);
-+    word2char(x1, d + 8);
-+    word2char(x2, d + 12);
-+}
-+
-+void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
-+                  unsigned char d[SEED_BLOCK_SIZE],
-+                  const SEED_KEY_SCHEDULE *ks)
-+{
-+    seed_word x1, x2, x3, x4;
-+    seed_word t0, t1;
-+
-+    char2word(s, x1);
-+    char2word(s + 4, x2);
-+    char2word(s + 8, x3);
-+    char2word(s + 12, x4);
-+
-+# if !defined(OPENSSL_SMALL_FOOTPRINT)
-+    E_SEED(t0, t1, x1, x2, x3, x4, 30);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 28);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 26);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 24);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 22);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 20);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 18);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 16);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 14);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 12);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 10);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 8);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 6);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 4);
-+    E_SEED(t0, t1, x1, x2, x3, x4, 2);
-+    E_SEED(t0, t1, x3, x4, x1, x2, 0);
-+# else
-+    {
-+        int i;
-+        for (i = 30; i > 0; i -= 4) {
-+            E_SEED(t0, t1, x1, x2, x3, x4, i);
-+            E_SEED(t0, t1, x3, x4, x1, x2, i - 2);
-+
-+        }
-+    }
-+# endif
-+
-+    word2char(x3, d);
-+    word2char(x4, d + 4);
-+    word2char(x1, d + 8);
-+    word2char(x2, d + 12);
-+}
-+
-+#endif                          /* OPENSSL_NO_SEED */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_cbc.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_cbc.c
-new file mode 100644
-index 0000000..c9a4fe2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_cbc.c
-@@ -0,0 +1,23 @@
-+/*
-+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
-+                      size_t len, const SEED_KEY_SCHEDULE *ks,
-+                      unsigned char ivec[SEED_BLOCK_SIZE], int enc)
-+{
-+    if (enc)
-+        CRYPTO_cbc128_encrypt(in, out, len, ks, ivec,
-+                              (block128_f) SEED_encrypt);
-+    else
-+        CRYPTO_cbc128_decrypt(in, out, len, ks, ivec,
-+                              (block128_f) SEED_decrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_cfb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_cfb.c
-new file mode 100644
-index 0000000..2aee1ff
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_cfb.c
-@@ -0,0 +1,20 @@
-+/*
-+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out,
-+                         size_t len, const SEED_KEY_SCHEDULE *ks,
-+                         unsigned char ivec[SEED_BLOCK_SIZE], int *num,
-+                         int enc)
-+{
-+    CRYPTO_cfb128_encrypt(in, out, len, ks, ivec, num, enc,
-+                          (block128_f) SEED_encrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_ecb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_ecb.c
-new file mode 100644
-index 0000000..b6e301c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_ecb.c
-@@ -0,0 +1,19 @@
-+/*
-+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out,
-+                      const SEED_KEY_SCHEDULE *ks, int enc)
-+{
-+    if (enc)
-+        SEED_encrypt(in, out, ks);
-+    else
-+        SEED_decrypt(in, out, ks);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_locl.h
-new file mode 100644
-index 0000000..d4a03fc
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_locl.h
-@@ -0,0 +1,120 @@
-+/*
-+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*
-+ * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Neither the name of author nor the names of its contributors may
-+ *    be used to endorse or promote products derived from this software
-+ *    without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ */
-+#ifndef HEADER_SEED_LOCL_H
-+# define HEADER_SEED_LOCL_H
-+
-+# include "openssl/e_os2.h"
-+# include 
-+
-+# ifdef SEED_LONG               /* need 32-bit type */
-+typedef unsigned long seed_word;
-+# else
-+typedef unsigned int seed_word;
-+# endif
-+
-+
-+#ifdef  __cplusplus
-+extern "C" {
-+#endif
-+
-+# define char2word(c, i)  \
-+        (i) = ((((seed_word)(c)[0]) << 24) | (((seed_word)(c)[1]) << 16) | (((seed_word)(c)[2]) << 8) | ((seed_word)(c)[3]))
-+
-+# define word2char(l, c)  \
-+        *((c)+0) = (unsigned char)((l)>>24) & 0xff; \
-+        *((c)+1) = (unsigned char)((l)>>16) & 0xff; \
-+        *((c)+2) = (unsigned char)((l)>> 8) & 0xff; \
-+        *((c)+3) = (unsigned char)((l))     & 0xff
-+
-+# define KEYSCHEDULE_UPDATE0(T0, T1, X1, X2, X3, X4, KC)  \
-+        (T0) = (X3);                                     \
-+        (X3) = (((X3)<<8) ^ ((X4)>>24)) & 0xffffffff;    \
-+        (X4) = (((X4)<<8) ^ ((T0)>>24)) & 0xffffffff;    \
-+        (T0) = ((X1) + (X3) - (KC))     & 0xffffffff;    \
-+        (T1) = ((X2) + (KC) - (X4))     & 0xffffffff
-+
-+# define KEYSCHEDULE_UPDATE1(T0, T1, X1, X2, X3, X4, KC)  \
-+        (T0) = (X1);                                     \
-+        (X1) = (((X1)>>8) ^ ((X2)<<24)) & 0xffffffff;    \
-+        (X2) = (((X2)>>8) ^ ((T0)<<24)) & 0xffffffff;    \
-+        (T0) = ((X1) + (X3) - (KC))     & 0xffffffff;     \
-+        (T1) = ((X2) + (KC) - (X4))     & 0xffffffff
-+
-+# define KEYUPDATE_TEMP(T0, T1, K)   \
-+        (K)[0] = G_FUNC((T0));      \
-+        (K)[1] = G_FUNC((T1))
-+
-+# define XOR_SEEDBLOCK(DST, SRC)      \
-+        ((DST))[0] ^= ((SRC))[0];    \
-+        ((DST))[1] ^= ((SRC))[1];    \
-+        ((DST))[2] ^= ((SRC))[2];    \
-+        ((DST))[3] ^= ((SRC))[3]
-+
-+# define MOV_SEEDBLOCK(DST, SRC)      \
-+        ((DST))[0] = ((SRC))[0];     \
-+        ((DST))[1] = ((SRC))[1];     \
-+        ((DST))[2] = ((SRC))[2];     \
-+        ((DST))[3] = ((SRC))[3]
-+
-+# define CHAR2WORD(C, I)              \
-+        char2word((C),    (I)[0]);    \
-+        char2word((C+4),  (I)[1]);    \
-+        char2word((C+8),  (I)[2]);    \
-+        char2word((C+12), (I)[3])
-+
-+# define WORD2CHAR(I, C)              \
-+        word2char((I)[0], (C));       \
-+        word2char((I)[1], (C+4));     \
-+        word2char((I)[2], (C+8));     \
-+        word2char((I)[3], (C+12))
-+
-+# define E_SEED(T0, T1, X1, X2, X3, X4, rbase)   \
-+        (T0) = (X3) ^ (ks->data)[(rbase)];       \
-+        (T1) = (X4) ^ (ks->data)[(rbase)+1];     \
-+        (T1) ^= (T0);                            \
-+        (T1) = G_FUNC((T1));                     \
-+        (T0) = ((T0) + (T1)) & 0xffffffff;       \
-+        (T0) = G_FUNC((T0));                     \
-+        (T1) = ((T1) + (T0)) & 0xffffffff;       \
-+        (T1) = G_FUNC((T1));                     \
-+        (T0) = ((T0) + (T1)) & 0xffffffff;       \
-+        (X1) ^= (T0);                            \
-+        (X2) ^= (T1)
-+
-+#ifdef  __cplusplus
-+}
-+#endif
-+
-+#endif                          /* HEADER_SEED_LOCL_H */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_ofb.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_ofb.c
-new file mode 100644
-index 0000000..b455540
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/seed/seed_ofb.c
-@@ -0,0 +1,19 @@
-+/*
-+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out,
-+                         size_t len, const SEED_KEY_SCHEDULE *ks,
-+                         unsigned char ivec[SEED_BLOCK_SIZE], int *num)
-+{
-+    CRYPTO_ofb128_encrypt(in, out, len, ks, ivec, num,
-+                          (block128_f) SEED_encrypt);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-586.pl
-new file mode 100644
-index 0000000..0efed70
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-586.pl
-@@ -0,0 +1,1488 @@
-+#! /usr/bin/env perl
-+# Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# [Re]written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# "[Re]written" was achieved in two major overhauls. In 2004 BODY_*
-+# functions were re-implemented to address P4 performance issue [see
-+# commentary below], and in 2006 the rest was rewritten in order to
-+# gain freedom to liberate licensing terms.
-+
-+# January, September 2004.
-+#
-+# It was noted that Intel IA-32 C compiler generates code which
-+# performs ~30% *faster* on P4 CPU than original *hand-coded*
-+# SHA1 assembler implementation. To address this problem (and
-+# prove that humans are still better than machines:-), the
-+# original code was overhauled, which resulted in following
-+# performance changes:
-+#
-+#		compared with original	compared with Intel cc
-+#		assembler impl.		generated code
-+# Pentium	-16%			+48%
-+# PIII/AMD	+8%			+16%
-+# P4		+85%(!)			+45%
-+#
-+# As you can see Pentium came out as looser:-( Yet I reckoned that
-+# improvement on P4 outweights the loss and incorporate this
-+# re-tuned code to 0.9.7 and later.
-+# ----------------------------------------------------------------
-+#					
-+
-+# August 2009.
-+#
-+# George Spelvin has tipped that F_40_59(b,c,d) can be rewritten as
-+# '(c&d) + (b&(c^d))', which allows to accumulate partial results
-+# and lighten "pressure" on scratch registers. This resulted in
-+# >12% performance improvement on contemporary AMD cores (with no
-+# degradation on other CPUs:-). Also, the code was revised to maximize
-+# "distance" between instructions producing input to 'lea' instruction
-+# and the 'lea' instruction itself, which is essential for Intel Atom
-+# core and resulted in ~15% improvement.
-+
-+# October 2010.
-+#
-+# Add SSSE3, Supplemental[!] SSE3, implementation. The idea behind it
-+# is to offload message schedule denoted by Wt in NIST specification,
-+# or Xupdate in OpenSSL source, to SIMD unit. The idea is not novel,
-+# and in SSE2 context was first explored by Dean Gaudet in 2004, see
-+# http://arctic.org/~dean/crypto/sha1.html. Since then several things
-+# have changed that made it interesting again:
-+#
-+# a) XMM units became faster and wider;
-+# b) instruction set became more versatile;
-+# c) an important observation was made by Max Locktykhin, which made
-+#    it possible to reduce amount of instructions required to perform
-+#    the operation in question, for further details see
-+#    http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1/.
-+
-+# April 2011.
-+#
-+# Add AVX code path, probably most controversial... The thing is that
-+# switch to AVX alone improves performance by as little as 4% in
-+# comparison to SSSE3 code path. But below result doesn't look like
-+# 4% improvement... Trouble is that Sandy Bridge decodes 'ro[rl]' as
-+# pair of µ-ops, and it's the additional µ-ops, two per round, that
-+# make it run slower than Core2 and Westmere. But 'sh[rl]d' is decoded
-+# as single µ-op by Sandy Bridge and it's replacing 'ro[rl]' with
-+# equivalent 'sh[rl]d' that is responsible for the impressive 5.1
-+# cycles per processed byte. But 'sh[rl]d' is not something that used
-+# to be fast, nor does it appear to be fast in upcoming Bulldozer
-+# [according to its optimization manual]. Which is why AVX code path
-+# is guarded by *both* AVX and synthetic bit denoting Intel CPUs.
-+# One can argue that it's unfair to AMD, but without 'sh[rl]d' it
-+# makes no sense to keep the AVX code path. If somebody feels that
-+# strongly, it's probably more appropriate to discuss possibility of
-+# using vector rotate XOP on AMD...
-+
-+# March 2014.
-+#
-+# Add support for Intel SHA Extensions.
-+
-+######################################################################
-+# Current performance is summarized in following table. Numbers are
-+# CPU clock cycles spent to process single byte (less is better).
-+#
-+#		x86		SSSE3		AVX
-+# Pentium	15.7		-
-+# PIII		11.5		-
-+# P4		10.6		-
-+# AMD K8	7.1		-
-+# Core2		7.3		6.0/+22%	-
-+# Westmere	7.3		5.5/+33%	-
-+# Sandy Bridge	8.8		6.2/+40%	5.1(**)/+73%
-+# Ivy Bridge	7.2		4.8/+51%	4.7(**)/+53%
-+# Haswell	6.5		4.3/+51%	4.1(**)/+58%
-+# Bulldozer	11.6		6.0/+92%
-+# VIA Nano	10.6		7.5/+41%
-+# Atom		12.5		9.3(*)/+35%
-+# Silvermont	14.5		9.9(*)/+46%
-+#
-+# (*)	Loop is 1056 instructions long and expected result is ~8.25.
-+#	The discrepancy is because of front-end limitations, so
-+#	called MS-ROM penalties, and on Silvermont even rotate's
-+#	limited parallelism.
-+#
-+# (**)	As per above comment, the result is for AVX *plus* sh[rl]d.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"sha1-586.pl",$ARGV[$#ARGV] eq "386");
-+
-+$xmm=$ymm=0;
-+for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
-+
-+$ymm=1 if ($xmm &&
-+		`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+			=~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
-+		$1>=2.19);	# first version supporting AVX
-+
-+$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32n" && 
-+		`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
-+		$1>=2.03);	# first version supporting AVX
-+
-+$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32" &&
-+		`ml 2>&1` =~ /Version ([0-9]+)\./ &&
-+		$1>=10);	# first version supporting AVX
-+
-+$ymm=1 if ($xmm && !$ymm && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/ &&
-+		$2>=3.0);	# first version supporting AVX
-+
-+$shaext=$xmm;	### set to zero if compiling for 1.0.1
-+
-+&external_label("OPENSSL_ia32cap_P") if ($xmm);
-+
-+
-+$A="eax";
-+$B="ebx";
-+$C="ecx";
-+$D="edx";
-+$E="edi";
-+$T="esi";
-+$tmp1="ebp";
-+
-+@V=($A,$B,$C,$D,$E,$T);
-+
-+$alt=0;	# 1 denotes alternative IALU implementation, which performs
-+	# 8% *worse* on P4, same on Westmere and Atom, 2% better on
-+	# Sandy Bridge...
-+
-+sub BODY_00_15
-+	{
-+	local($n,$a,$b,$c,$d,$e,$f)=@_;
-+
-+	&comment("00_15 $n");
-+
-+	&mov($f,$c);			# f to hold F_00_19(b,c,d)
-+	 if ($n==0)  { &mov($tmp1,$a); }
-+	 else        { &mov($a,$tmp1); }
-+	&rotl($tmp1,5);			# tmp1=ROTATE(a,5)
-+	 &xor($f,$d);
-+	&add($tmp1,$e);			# tmp1+=e;
-+	 &mov($e,&swtmp($n%16));	# e becomes volatile and is loaded
-+	 				# with xi, also note that e becomes
-+					# f in next round...
-+	&and($f,$b);
-+	&rotr($b,2);			# b=ROTATE(b,30)
-+	 &xor($f,$d);			# f holds F_00_19(b,c,d)
-+	&lea($tmp1,&DWP(0x5a827999,$tmp1,$e));	# tmp1+=K_00_19+xi
-+
-+	if ($n==15) { &mov($e,&swtmp(($n+1)%16));# pre-fetch f for next round
-+		      &add($f,$tmp1); }	# f+=tmp1
-+	else        { &add($tmp1,$f); }	# f becomes a in next round
-+	&mov($tmp1,$a)			if ($alt && $n==15);
-+	}
-+
-+sub BODY_16_19
-+	{
-+	local($n,$a,$b,$c,$d,$e,$f)=@_;
-+
-+	&comment("16_19 $n");
-+
-+if ($alt) {
-+	&xor($c,$d);
-+	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
-+	&and($tmp1,$c);			# tmp1 to hold F_00_19(b,c,d), b&=c^d
-+	 &xor($f,&swtmp(($n+8)%16));
-+	&xor($tmp1,$d);			# tmp1=F_00_19(b,c,d)
-+	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
-+	&rotl($f,1);			# f=ROTATE(f,1)
-+	 &add($e,$tmp1);		# e+=F_00_19(b,c,d)
-+	&xor($c,$d);			# restore $c
-+	 &mov($tmp1,$a);		# b in next round
-+	&rotr($b,$n==16?2:7);		# b=ROTATE(b,30)
-+	 &mov(&swtmp($n%16),$f);	# xi=f
-+	&rotl($a,5);			# ROTATE(a,5)
-+	 &lea($f,&DWP(0x5a827999,$f,$e));# f+=F_00_19(b,c,d)+e
-+	&mov($e,&swtmp(($n+1)%16));	# pre-fetch f for next round
-+	 &add($f,$a);			# f+=ROTATE(a,5)
-+} else {
-+	&mov($tmp1,$c);			# tmp1 to hold F_00_19(b,c,d)
-+	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
-+	&xor($tmp1,$d);
-+	 &xor($f,&swtmp(($n+8)%16));
-+	&and($tmp1,$b);
-+	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
-+	&rotl($f,1);			# f=ROTATE(f,1)
-+	 &xor($tmp1,$d);		# tmp1=F_00_19(b,c,d)
-+	&add($e,$tmp1);			# e+=F_00_19(b,c,d)
-+	 &mov($tmp1,$a);
-+	&rotr($b,2);			# b=ROTATE(b,30)
-+	 &mov(&swtmp($n%16),$f);	# xi=f
-+	&rotl($tmp1,5);			# ROTATE(a,5)
-+	 &lea($f,&DWP(0x5a827999,$f,$e));# f+=F_00_19(b,c,d)+e
-+	&mov($e,&swtmp(($n+1)%16));	# pre-fetch f for next round
-+	 &add($f,$tmp1);		# f+=ROTATE(a,5)
-+}
-+	}
-+
-+sub BODY_20_39
-+	{
-+	local($n,$a,$b,$c,$d,$e,$f)=@_;
-+	local $K=($n<40)?0x6ed9eba1:0xca62c1d6;
-+
-+	&comment("20_39 $n");
-+
-+if ($alt) {
-+	&xor($tmp1,$c);			# tmp1 to hold F_20_39(b,c,d), b^=c
-+	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
-+	&xor($tmp1,$d);			# tmp1 holds F_20_39(b,c,d)
-+	 &xor($f,&swtmp(($n+8)%16));
-+	&add($e,$tmp1);			# e+=F_20_39(b,c,d)
-+	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
-+	&rotl($f,1);			# f=ROTATE(f,1)
-+	 &mov($tmp1,$a);		# b in next round
-+	&rotr($b,7);			# b=ROTATE(b,30)
-+	 &mov(&swtmp($n%16),$f)		if($n<77);# xi=f
-+	&rotl($a,5);			# ROTATE(a,5)
-+	 &xor($b,$c)			if($n==39);# warm up for BODY_40_59
-+	&and($tmp1,$b)			if($n==39);
-+	 &lea($f,&DWP($K,$f,$e));	# f+=e+K_XX_YY
-+	&mov($e,&swtmp(($n+1)%16))	if($n<79);# pre-fetch f for next round
-+	 &add($f,$a);			# f+=ROTATE(a,5)
-+	&rotr($a,5)			if ($n==79);
-+} else {
-+	&mov($tmp1,$b);			# tmp1 to hold F_20_39(b,c,d)
-+	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
-+	&xor($tmp1,$c);
-+	 &xor($f,&swtmp(($n+8)%16));
-+	&xor($tmp1,$d);			# tmp1 holds F_20_39(b,c,d)
-+	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
-+	&rotl($f,1);			# f=ROTATE(f,1)
-+	 &add($e,$tmp1);		# e+=F_20_39(b,c,d)
-+	&rotr($b,2);			# b=ROTATE(b,30)
-+	 &mov($tmp1,$a);
-+	&rotl($tmp1,5);			# ROTATE(a,5)
-+	 &mov(&swtmp($n%16),$f) if($n<77);# xi=f
-+	&lea($f,&DWP($K,$f,$e));	# f+=e+K_XX_YY
-+	 &mov($e,&swtmp(($n+1)%16)) if($n<79);# pre-fetch f for next round
-+	&add($f,$tmp1);			# f+=ROTATE(a,5)
-+}
-+	}
-+
-+sub BODY_40_59
-+	{
-+	local($n,$a,$b,$c,$d,$e,$f)=@_;
-+
-+	&comment("40_59 $n");
-+
-+if ($alt) {
-+	&add($e,$tmp1);			# e+=b&(c^d)
-+	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
-+	&mov($tmp1,$d);
-+	 &xor($f,&swtmp(($n+8)%16));
-+	&xor($c,$d);			# restore $c
-+	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
-+	&rotl($f,1);			# f=ROTATE(f,1)
-+	 &and($tmp1,$c);
-+	&rotr($b,7);			# b=ROTATE(b,30)
-+	 &add($e,$tmp1);		# e+=c&d
-+	&mov($tmp1,$a);			# b in next round
-+	 &mov(&swtmp($n%16),$f);	# xi=f
-+	&rotl($a,5);			# ROTATE(a,5)
-+	 &xor($b,$c)			if ($n<59);
-+	&and($tmp1,$b)			if ($n<59);# tmp1 to hold F_40_59(b,c,d)
-+	 &lea($f,&DWP(0x8f1bbcdc,$f,$e));# f+=K_40_59+e+(b&(c^d))
-+	&mov($e,&swtmp(($n+1)%16));	# pre-fetch f for next round
-+	 &add($f,$a);			# f+=ROTATE(a,5)
-+} else {
-+	&mov($tmp1,$c);			# tmp1 to hold F_40_59(b,c,d)
-+	 &xor($f,&swtmp(($n+2)%16));	# f to hold Xupdate(xi,xa,xb,xc,xd)
-+	&xor($tmp1,$d);
-+	 &xor($f,&swtmp(($n+8)%16));
-+	&and($tmp1,$b);
-+	 &xor($f,&swtmp(($n+13)%16));	# f holds xa^xb^xc^xd
-+	&rotl($f,1);			# f=ROTATE(f,1)
-+	 &add($tmp1,$e);		# b&(c^d)+=e
-+	&rotr($b,2);			# b=ROTATE(b,30)
-+	 &mov($e,$a);			# e becomes volatile
-+	&rotl($e,5);			# ROTATE(a,5)
-+	 &mov(&swtmp($n%16),$f);	# xi=f
-+	&lea($f,&DWP(0x8f1bbcdc,$f,$tmp1));# f+=K_40_59+e+(b&(c^d))
-+	 &mov($tmp1,$c);
-+	&add($f,$e);			# f+=ROTATE(a,5)
-+	 &and($tmp1,$d);
-+	&mov($e,&swtmp(($n+1)%16));	# pre-fetch f for next round
-+	 &add($f,$tmp1);		# f+=c&d
-+}
-+	}
-+
-+&function_begin("sha1_block_data_order");
-+if ($xmm) {
-+  &static_label("shaext_shortcut")	if ($shaext);
-+  &static_label("ssse3_shortcut");
-+  &static_label("avx_shortcut")		if ($ymm);
-+  &static_label("K_XX_XX");
-+
-+	&call	(&label("pic_point"));	# make it PIC!
-+  &set_label("pic_point");
-+	&blindpop($tmp1);
-+	&picmeup($T,"OPENSSL_ia32cap_P",$tmp1,&label("pic_point"));
-+	&lea	($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1));
-+
-+	&mov	($A,&DWP(0,$T));
-+	&mov	($D,&DWP(4,$T));
-+	&test	($D,1<<9);		# check SSSE3 bit
-+	&jz	(&label("x86"));
-+	&mov	($C,&DWP(8,$T));
-+	&test	($A,1<<24);		# check FXSR bit
-+	&jz	(&label("x86"));
-+	if ($shaext) {
-+		&test	($C,1<<29);		# check SHA bit
-+		&jnz	(&label("shaext_shortcut"));
-+	}
-+	if ($ymm) {
-+		&and	($D,1<<28);		# mask AVX bit
-+		&and	($A,1<<30);		# mask "Intel CPU" bit
-+		&or	($A,$D);
-+		&cmp	($A,1<<28|1<<30);
-+		&je	(&label("avx_shortcut"));
-+	}
-+	&jmp	(&label("ssse3_shortcut"));
-+  &set_label("x86",16);
-+}
-+	&mov($tmp1,&wparam(0));	# SHA_CTX *c
-+	&mov($T,&wparam(1));	# const void *input
-+	&mov($A,&wparam(2));	# size_t num
-+	&stack_push(16+3);	# allocate X[16]
-+	&shl($A,6);
-+	&add($A,$T);
-+	&mov(&wparam(2),$A);	# pointer beyond the end of input
-+	&mov($E,&DWP(16,$tmp1));# pre-load E
-+	&jmp(&label("loop"));
-+
-+&set_label("loop",16);
-+
-+	# copy input chunk to X, but reversing byte order!
-+	for ($i=0; $i<16; $i+=4)
-+		{
-+		&mov($A,&DWP(4*($i+0),$T));
-+		&mov($B,&DWP(4*($i+1),$T));
-+		&mov($C,&DWP(4*($i+2),$T));
-+		&mov($D,&DWP(4*($i+3),$T));
-+		&bswap($A);
-+		&bswap($B);
-+		&bswap($C);
-+		&bswap($D);
-+		&mov(&swtmp($i+0),$A);
-+		&mov(&swtmp($i+1),$B);
-+		&mov(&swtmp($i+2),$C);
-+		&mov(&swtmp($i+3),$D);
-+		}
-+	&mov(&wparam(1),$T);	# redundant in 1st spin
-+
-+	&mov($A,&DWP(0,$tmp1));	# load SHA_CTX
-+	&mov($B,&DWP(4,$tmp1));
-+	&mov($C,&DWP(8,$tmp1));
-+	&mov($D,&DWP(12,$tmp1));
-+	# E is pre-loaded
-+
-+	for($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
-+	for(;$i<20;$i++)	{ &BODY_16_19($i,@V); unshift(@V,pop(@V)); }
-+	for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+	for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+	for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+
-+	(($V[5] eq $D) and ($V[0] eq $E)) or die;	# double-check
-+
-+	&mov($tmp1,&wparam(0));	# re-load SHA_CTX*
-+	&mov($D,&wparam(1));	# D is last "T" and is discarded
-+
-+	&add($E,&DWP(0,$tmp1));	# E is last "A"...
-+	&add($T,&DWP(4,$tmp1));
-+	&add($A,&DWP(8,$tmp1));
-+	&add($B,&DWP(12,$tmp1));
-+	&add($C,&DWP(16,$tmp1));
-+
-+	&mov(&DWP(0,$tmp1),$E);	# update SHA_CTX
-+	 &add($D,64);		# advance input pointer
-+	&mov(&DWP(4,$tmp1),$T);
-+	 &cmp($D,&wparam(2));	# have we reached the end yet?
-+	&mov(&DWP(8,$tmp1),$A);
-+	 &mov($E,$C);		# C is last "E" which needs to be "pre-loaded"
-+	&mov(&DWP(12,$tmp1),$B);
-+	 &mov($T,$D);		# input pointer
-+	&mov(&DWP(16,$tmp1),$C);
-+	&jb(&label("loop"));
-+
-+	&stack_pop(16+3);
-+&function_end("sha1_block_data_order");
-+
-+if ($xmm) {
-+if ($shaext) {
-+######################################################################
-+# Intel SHA Extensions implementation of SHA1 update function.
-+#
-+my ($ctx,$inp,$num)=("edi","esi","ecx");
-+my ($ABCD,$E,$E_,$BSWAP)=map("xmm$_",(0..3));
-+my @MSG=map("xmm$_",(4..7));
-+
-+sub sha1rnds4 {
-+ my ($dst,$src,$imm)=@_;
-+    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
-+    {	&data_byte(0x0f,0x3a,0xcc,0xc0|($1<<3)|$2,$imm);	}
-+}
-+sub sha1op38 {
-+ my ($opcodelet,$dst,$src)=@_;
-+    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
-+    {	&data_byte(0x0f,0x38,$opcodelet,0xc0|($1<<3)|$2);	}
-+}
-+sub sha1nexte	{ sha1op38(0xc8,@_); }
-+sub sha1msg1	{ sha1op38(0xc9,@_); }
-+sub sha1msg2	{ sha1op38(0xca,@_); }
-+
-+&function_begin("_sha1_block_data_order_shaext");
-+	&call	(&label("pic_point"));	# make it PIC!
-+	&set_label("pic_point");
-+	&blindpop($tmp1);
-+	&lea	($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1));
-+&set_label("shaext_shortcut");
-+	&mov	($ctx,&wparam(0));
-+	&mov	("ebx","esp");
-+	&mov	($inp,&wparam(1));
-+	&mov	($num,&wparam(2));
-+	&sub	("esp",32);
-+
-+	&movdqu	($ABCD,&QWP(0,$ctx));
-+	&movd	($E,&DWP(16,$ctx));
-+	&and	("esp",-32);
-+	&movdqa	($BSWAP,&QWP(0x50,$tmp1));	# byte-n-word swap
-+
-+	&movdqu	(@MSG[0],&QWP(0,$inp));
-+	&pshufd	($ABCD,$ABCD,0b00011011);	# flip word order
-+	&movdqu	(@MSG[1],&QWP(0x10,$inp));
-+	&pshufd	($E,$E,0b00011011);		# flip word order
-+	&movdqu	(@MSG[2],&QWP(0x20,$inp));
-+	&pshufb	(@MSG[0],$BSWAP);
-+	&movdqu	(@MSG[3],&QWP(0x30,$inp));
-+	&pshufb	(@MSG[1],$BSWAP);
-+	&pshufb	(@MSG[2],$BSWAP);
-+	&pshufb	(@MSG[3],$BSWAP);
-+	&jmp	(&label("loop_shaext"));
-+
-+&set_label("loop_shaext",16);
-+	&dec		($num);
-+	&lea		("eax",&DWP(0x40,$inp));
-+	&movdqa		(&QWP(0,"esp"),$E);	# offload $E
-+	&paddd		($E,@MSG[0]);
-+	&cmovne		($inp,"eax");
-+	&movdqa		(&QWP(16,"esp"),$ABCD);	# offload $ABCD
-+
-+for($i=0;$i<20-4;$i+=2) {
-+	&sha1msg1	(@MSG[0],@MSG[1]);
-+	&movdqa		($E_,$ABCD);
-+	&sha1rnds4	($ABCD,$E,int($i/5));	# 0-3...
-+	&sha1nexte	($E_,@MSG[1]);
-+	&pxor		(@MSG[0],@MSG[2]);
-+	&sha1msg1	(@MSG[1],@MSG[2]);
-+	&sha1msg2	(@MSG[0],@MSG[3]);
-+
-+	&movdqa		($E,$ABCD);
-+	&sha1rnds4	($ABCD,$E_,int(($i+1)/5));
-+	&sha1nexte	($E,@MSG[2]);
-+	&pxor		(@MSG[1],@MSG[3]);
-+	&sha1msg2	(@MSG[1],@MSG[0]);
-+
-+	push(@MSG,shift(@MSG));	push(@MSG,shift(@MSG));
-+}
-+	&movdqu		(@MSG[0],&QWP(0,$inp));
-+	&movdqa		($E_,$ABCD);
-+	&sha1rnds4	($ABCD,$E,3);		# 64-67
-+	&sha1nexte	($E_,@MSG[1]);
-+	&movdqu		(@MSG[1],&QWP(0x10,$inp));
-+	&pshufb		(@MSG[0],$BSWAP);
-+
-+	&movdqa		($E,$ABCD);
-+	&sha1rnds4	($ABCD,$E_,3);		# 68-71
-+	&sha1nexte	($E,@MSG[2]);
-+	&movdqu		(@MSG[2],&QWP(0x20,$inp));
-+	&pshufb		(@MSG[1],$BSWAP);
-+
-+	&movdqa		($E_,$ABCD);
-+	&sha1rnds4	($ABCD,$E,3);		# 72-75
-+	&sha1nexte	($E_,@MSG[3]);
-+	&movdqu		(@MSG[3],&QWP(0x30,$inp));
-+	&pshufb		(@MSG[2],$BSWAP);
-+
-+	&movdqa		($E,$ABCD);
-+	&sha1rnds4	($ABCD,$E_,3);		# 76-79
-+	&movdqa		($E_,&QWP(0,"esp"));
-+	&pshufb		(@MSG[3],$BSWAP);
-+	&sha1nexte	($E,$E_);
-+	&paddd		($ABCD,&QWP(16,"esp"));
-+
-+	&jnz		(&label("loop_shaext"));
-+
-+	&pshufd	($ABCD,$ABCD,0b00011011);
-+	&pshufd	($E,$E,0b00011011);
-+	&movdqu	(&QWP(0,$ctx),$ABCD)
-+	&movd	(&DWP(16,$ctx),$E);
-+	&mov	("esp","ebx");
-+&function_end("_sha1_block_data_order_shaext");
-+}
-+######################################################################
-+# The SSSE3 implementation.
-+#
-+# %xmm[0-7] are used as ring @X[] buffer containing quadruples of last
-+# 32 elements of the message schedule or Xupdate outputs. First 4
-+# quadruples are simply byte-swapped input, next 4 are calculated
-+# according to method originally suggested by Dean Gaudet (modulo
-+# being implemented in SSSE3). Once 8 quadruples or 32 elements are
-+# collected, it switches to routine proposed by Max Locktyukhin.
-+#
-+# Calculations inevitably require temporary reqisters, and there are
-+# no %xmm registers left to spare. For this reason part of the ring
-+# buffer, X[2..4] to be specific, is offloaded to 3 quadriples ring
-+# buffer on the stack. Keep in mind that X[2] is alias X[-6], X[3] -
-+# X[-5], and X[4] - X[-4]...
-+#
-+# Another notable optimization is aggressive stack frame compression
-+# aiming to minimize amount of 9-byte instructions...
-+#
-+# Yet another notable optimization is "jumping" $B variable. It means
-+# that there is no register permanently allocated for $B value. This
-+# allowed to eliminate one instruction from body_20_39...
-+#
-+my $Xi=4;			# 4xSIMD Xupdate round, start pre-seeded
-+my @X=map("xmm$_",(4..7,0..3));	# pre-seeded for $Xi=4
-+my @V=($A,$B,$C,$D,$E);
-+my $j=0;			# hash round
-+my $rx=0;
-+my @T=($T,$tmp1);
-+my $inp;
-+
-+my $_rol=sub { &rol(@_) };
-+my $_ror=sub { &ror(@_) };
-+
-+&function_begin("_sha1_block_data_order_ssse3");
-+	&call	(&label("pic_point"));	# make it PIC!
-+	&set_label("pic_point");
-+	&blindpop($tmp1);
-+	&lea	($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1));
-+&set_label("ssse3_shortcut");
-+
-+	&movdqa	(@X[3],&QWP(0,$tmp1));		# K_00_19
-+	&movdqa	(@X[4],&QWP(16,$tmp1));		# K_20_39
-+	&movdqa	(@X[5],&QWP(32,$tmp1));		# K_40_59
-+	&movdqa	(@X[6],&QWP(48,$tmp1));		# K_60_79
-+	&movdqa	(@X[2],&QWP(64,$tmp1));		# pbswap mask
-+
-+	&mov	($E,&wparam(0));		# load argument block
-+	&mov	($inp=@T[1],&wparam(1));
-+	&mov	($D,&wparam(2));
-+	&mov	(@T[0],"esp");
-+
-+	# stack frame layout
-+	#
-+	# +0	X[0]+K	X[1]+K	X[2]+K	X[3]+K	# XMM->IALU xfer area
-+	#	X[4]+K	X[5]+K	X[6]+K	X[7]+K
-+	#	X[8]+K	X[9]+K	X[10]+K	X[11]+K
-+	#	X[12]+K	X[13]+K	X[14]+K	X[15]+K
-+	#
-+	# +64	X[0]	X[1]	X[2]	X[3]	# XMM->XMM backtrace area
-+	#	X[4]	X[5]	X[6]	X[7]
-+	#	X[8]	X[9]	X[10]	X[11]	# even borrowed for K_00_19
-+	#
-+	# +112	K_20_39	K_20_39	K_20_39	K_20_39	# constants
-+	#	K_40_59	K_40_59	K_40_59	K_40_59
-+	#	K_60_79	K_60_79	K_60_79	K_60_79
-+	#	K_00_19	K_00_19	K_00_19	K_00_19
-+	#	pbswap mask
-+	#
-+	# +192	ctx				# argument block
-+	# +196	inp
-+	# +200	end
-+	# +204	esp
-+	&sub	("esp",208);
-+	&and	("esp",-64);
-+
-+	&movdqa	(&QWP(112+0,"esp"),@X[4]);	# copy constants
-+	&movdqa	(&QWP(112+16,"esp"),@X[5]);
-+	&movdqa	(&QWP(112+32,"esp"),@X[6]);
-+	&shl	($D,6);				# len*64
-+	&movdqa	(&QWP(112+48,"esp"),@X[3]);
-+	&add	($D,$inp);			# end of input
-+	&movdqa	(&QWP(112+64,"esp"),@X[2]);
-+	&add	($inp,64);
-+	&mov	(&DWP(192+0,"esp"),$E);		# save argument block
-+	&mov	(&DWP(192+4,"esp"),$inp);
-+	&mov	(&DWP(192+8,"esp"),$D);
-+	&mov	(&DWP(192+12,"esp"),@T[0]);	# save original %esp
-+
-+	&mov	($A,&DWP(0,$E));		# load context
-+	&mov	($B,&DWP(4,$E));
-+	&mov	($C,&DWP(8,$E));
-+	&mov	($D,&DWP(12,$E));
-+	&mov	($E,&DWP(16,$E));
-+	&mov	(@T[0],$B);			# magic seed
-+
-+	&movdqu	(@X[-4&7],&QWP(-64,$inp));	# load input to %xmm[0-3]
-+	&movdqu	(@X[-3&7],&QWP(-48,$inp));
-+	&movdqu	(@X[-2&7],&QWP(-32,$inp));
-+	&movdqu	(@X[-1&7],&QWP(-16,$inp));
-+	&pshufb	(@X[-4&7],@X[2]);		# byte swap
-+	&pshufb	(@X[-3&7],@X[2]);
-+	&pshufb	(@X[-2&7],@X[2]);
-+	&movdqa	(&QWP(112-16,"esp"),@X[3]);	# borrow last backtrace slot
-+	&pshufb	(@X[-1&7],@X[2]);
-+	&paddd	(@X[-4&7],@X[3]);		# add K_00_19
-+	&paddd	(@X[-3&7],@X[3]);
-+	&paddd	(@X[-2&7],@X[3]);
-+	&movdqa	(&QWP(0,"esp"),@X[-4&7]);	# X[]+K xfer to IALU
-+	&psubd	(@X[-4&7],@X[3]);		# restore X[]
-+	&movdqa	(&QWP(0+16,"esp"),@X[-3&7]);
-+	&psubd	(@X[-3&7],@X[3]);
-+	&movdqa	(&QWP(0+32,"esp"),@X[-2&7]);
-+	&mov	(@T[1],$C);
-+	&psubd	(@X[-2&7],@X[3]);
-+	&xor	(@T[1],$D);
-+	&pshufd	(@X[0],@X[-4&7],0xee);		# was &movdqa	(@X[0],@X[-3&7]);
-+	&and	(@T[0],@T[1]);
-+	&jmp	(&label("loop"));
-+
-+######################################################################
-+# SSE instruction sequence is first broken to groups of indepentent
-+# instructions, independent in respect to their inputs and shifter
-+# (not all architectures have more than one). Then IALU instructions
-+# are "knitted in" between the SSE groups. Distance is maintained for
-+# SSE latency of 2 in hope that it fits better upcoming AMD Bulldozer
-+# [which allegedly also implements SSSE3]...
-+#
-+# Temporary registers usage. X[2] is volatile at the entry and at the
-+# end is restored from backtrace ring buffer. X[3] is expected to
-+# contain current K_XX_XX constant and is used to caclulate X[-1]+K
-+# from previous round, it becomes volatile the moment the value is
-+# saved to stack for transfer to IALU. X[4] becomes volatile whenever
-+# X[-4] is accumulated and offloaded to backtrace ring buffer, at the
-+# end it is loaded with next K_XX_XX [which becomes X[3] in next
-+# round]...
-+#
-+sub Xupdate_ssse3_16_31()		# recall that $Xi starts wtih 4
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&punpcklqdq(@X[0],@X[-3&7]);	# compose "X[-14]" in "X[0]", was &palignr(@X[0],@X[-4&7],8);
-+	&movdqa	(@X[2],@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	  &paddd	(@X[3],@X[-1&7]);
-+	  &movdqa	(&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);# save X[] to backtrace buffer
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	&psrldq	(@X[2],4);		# "X[-3]", 3 dwords
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&pxor	(@X[0],@X[-4&7]);	# "X[0]"^="X[-16]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+
-+	&pxor	(@X[2],@X[-2&7]);	# "X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@X[2]);		# "X[0]"^="X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	  &movdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&movdqa	(@X[4],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	&movdqa (@X[2],@X[0]);
-+	 eval(shift(@insns));
-+
-+	&pslldq	(@X[4],12);		# "X[0]"<<96, extract one dword
-+	&paddd	(@X[0],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&psrld	(@X[2],31);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	&movdqa	(@X[3],@X[4]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&psrld	(@X[4],30);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	&por	(@X[0],@X[2]);		# "X[0]"<<<=1
-+	 eval(shift(@insns));
-+	  &movdqa	(@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if ($Xi>5);	# restore X[] from backtrace buffer
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pslld	(@X[3],2);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	&pxor   (@X[0],@X[4]);
-+	  &movdqa	(@X[4],&QWP(112-16+16*(($Xi)/5),"esp"));	# K_XX_XX
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@X[3]);		# "X[0]"^=("X[0]"<<96)<<<2
-+	  &pshufd	(@X[1],@X[-3&7],0xee)	if ($Xi<7);	# was &movdqa	(@X[1],@X[-2&7])
-+	  &pshufd	(@X[3],@X[-1&7],0xee)	if ($Xi==7);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	 foreach (@insns) { eval; }	# remaining instructions [if any]
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xupdate_ssse3_32_79()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 44 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));		# body_20_39
-+	&pxor	(@X[0],@X[-4&7]);	# "X[0]"="X[-32]"^"X[-16]"
-+	&punpcklqdq(@X[2],@X[-1&7]);	# compose "X[-6]", was &palignr(@X[2],@X[-2&7],8)
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+
-+	&pxor	(@X[0],@X[-7&7]);	# "X[0]"^="X[-28]"
-+	  &movdqa	(&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);	# save X[] to backtrace buffer
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns))		if (@insns[0] =~ /_rol/);
-+	 if ($Xi%5) {
-+	  &movdqa	(@X[4],@X[3]);	# "perpetuate" K_XX_XX...
-+	 } else {			# ... or load next one
-+	  &movdqa	(@X[4],&QWP(112-16+16*($Xi/5),"esp"));
-+	 }
-+	 eval(shift(@insns));		# ror
-+	  &paddd	(@X[3],@X[-1&7]);
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@X[2]);		# "X[0]"^="X[-6]"
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+
-+	&movdqa	(@X[2],@X[0]);
-+	  &movdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+	 eval(shift(@insns))		if (@insns[0] =~ /_rol/);
-+
-+	&pslld	(@X[0],2);
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	&psrld	(@X[2],30);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+	 eval(shift(@insns))		if (@insns[1] =~ /_rol/);
-+	 eval(shift(@insns))		if (@insns[0] =~ /_rol/);
-+
-+	&por	(@X[0],@X[2]);		# "X[0]"<<<=2
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	  &movdqa	(@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if($Xi<19);	# restore X[] from backtrace buffer
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	  &pshufd	(@X[3],@X[-1],0xee)	if ($Xi<19);	# was &movdqa	(@X[3],@X[0])
-+	 eval(shift(@insns));
-+
-+	 foreach (@insns) { eval; }	# remaining instructions
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xuplast_ssse3_80()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &paddd	(@X[3],@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	  &movdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer IALU
-+
-+	 foreach (@insns) { eval; }		# remaining instructions
-+
-+	&mov	($inp=@T[1],&DWP(192+4,"esp"));
-+	&cmp	($inp,&DWP(192+8,"esp"));
-+	&je	(&label("done"));
-+
-+	&movdqa	(@X[3],&QWP(112+48,"esp"));	# K_00_19
-+	&movdqa	(@X[2],&QWP(112+64,"esp"));	# pbswap mask
-+	&movdqu	(@X[-4&7],&QWP(0,$inp));	# load input
-+	&movdqu	(@X[-3&7],&QWP(16,$inp));
-+	&movdqu	(@X[-2&7],&QWP(32,$inp));
-+	&movdqu	(@X[-1&7],&QWP(48,$inp));
-+	&add	($inp,64);
-+	&pshufb	(@X[-4&7],@X[2]);		# byte swap
-+	&mov	(&DWP(192+4,"esp"),$inp);
-+	&movdqa	(&QWP(112-16,"esp"),@X[3]);	# borrow last backtrace slot
-+
-+  $Xi=0;
-+}
-+
-+sub Xloop_ssse3()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&pshufb	(@X[($Xi-3)&7],@X[2]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&paddd	(@X[($Xi-4)&7],@X[3]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&movdqa	(&QWP(0+16*$Xi,"esp"),@X[($Xi-4)&7]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&psubd	(@X[($Xi-4)&7],@X[3]);
-+
-+	foreach (@insns) { eval; }
-+  $Xi++;
-+}
-+
-+sub Xtail_ssse3()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	foreach (@insns) { eval; }
-+}
-+
-+sub body_00_19 () {	# ((c^d)&b)^d
-+	# on start @T[0]=(c^d)&b
-+	return &body_20_39()	if ($rx==19);	$rx++;
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.
-+	'&$_ror	($b,$j?7:2);',	# $b>>>2
-+	'&xor	(@T[0],$d);',
-+	'&mov	(@T[1],$a);',	# $b in next round
-+
-+	'&add	($e,&DWP(4*($j&15),"esp"));',	# X[]+K xfer
-+	'&xor	($b,$c);',	# $c^$d for next round
-+
-+	'&$_rol	($a,5);',
-+	'&add	($e,@T[0]);',
-+	'&and	(@T[1],$b);',	# ($b&($c^$d)) for next round
-+
-+	'&xor	($b,$c);',	# restore $b
-+	'&add	($e,$a);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+}
-+
-+sub body_20_39 () {	# b^d^c
-+	# on entry @T[0]=b^d
-+	return &body_40_59()	if ($rx==39);	$rx++;
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.
-+	'&add	($e,&DWP(4*($j&15),"esp"));',	# X[]+K xfer
-+	'&xor	(@T[0],$d)	if($j==19);'.
-+	'&xor	(@T[0],$c)	if($j> 19);',	# ($b^$d^$c)
-+	'&mov	(@T[1],$a);',	# $b in next round
-+
-+	'&$_rol	($a,5);',
-+	'&add	($e,@T[0]);',
-+	'&xor	(@T[1],$c)	if ($j< 79);',	# $b^$d for next round
-+
-+	'&$_ror	($b,7);',	# $b>>>2
-+	'&add	($e,$a);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+}
-+
-+sub body_40_59 () {	# ((b^c)&(c^d))^c
-+	# on entry @T[0]=(b^c), (c^=d)
-+	$rx++;
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.
-+	'&add	($e,&DWP(4*($j&15),"esp"));',	# X[]+K xfer
-+	'&and	(@T[0],$c)	if ($j>=40);',	# (b^c)&(c^d)
-+	'&xor	($c,$d)		if ($j>=40);',	# restore $c
-+
-+	'&$_ror	($b,7);',	# $b>>>2
-+	'&mov	(@T[1],$a);',	# $b for next round
-+	'&xor	(@T[0],$c);',
-+
-+	'&$_rol	($a,5);',
-+	'&add	($e,@T[0]);',
-+	'&xor	(@T[1],$c)	if ($j==59);'.
-+	'&xor	(@T[1],$b)	if ($j< 59);',	# b^c for next round
-+
-+	'&xor	($b,$c)		if ($j< 59);',	# c^d for next round
-+	'&add	($e,$a);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+}
-+######
-+sub bodyx_00_19 () {	# ((c^d)&b)^d
-+	# on start @T[0]=(b&c)^(~b&d), $e+=X[]+K
-+	return &bodyx_20_39()	if ($rx==19);	$rx++;
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.
-+
-+	'&rorx	($b,$b,2)			if ($j==0);'.	# $b>>>2
-+	'&rorx	($b,@T[1],7)			if ($j!=0);',	# $b>>>2
-+	'&lea	($e,&DWP(0,$e,@T[0]));',
-+	'&rorx	(@T[0],$a,5);',
-+
-+	'&andn	(@T[1],$a,$c);',
-+	'&and	($a,$b)',
-+	'&add	($d,&DWP(4*(($j+1)&15),"esp"));',	# X[]+K xfer
-+
-+	'&xor	(@T[1],$a)',
-+	'&add	($e,@T[0]);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+}
-+
-+sub bodyx_20_39 () {	# b^d^c
-+	# on start $b=b^c^d
-+	return &bodyx_40_59()	if ($rx==39);	$rx++;
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.
-+
-+	'&add	($e,($j==19?@T[0]:$b))',
-+	'&rorx	($b,@T[1],7);',	# $b>>>2
-+	'&rorx	(@T[0],$a,5);',
-+
-+	'&xor	($a,$b)				if ($j<79);',
-+	'&add	($d,&DWP(4*(($j+1)&15),"esp"))	if ($j<79);',	# X[]+K xfer
-+	'&xor	($a,$c)				if ($j<79);',
-+	'&add	($e,@T[0]);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+}
-+
-+sub bodyx_40_59 () {	# ((b^c)&(c^d))^c
-+	# on start $b=((b^c)&(c^d))^c
-+	return &bodyx_20_39()	if ($rx==59);	$rx++;
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.
-+
-+	'&rorx	(@T[0],$a,5)',
-+	'&lea	($e,&DWP(0,$e,$b))',
-+	'&rorx	($b,@T[1],7)',	# $b>>>2
-+	'&add	($d,&DWP(4*(($j+1)&15),"esp"))',	# X[]+K xfer
-+
-+	'&mov	(@T[1],$c)',
-+	'&xor	($a,$b)',	# b^c for next round
-+	'&xor	(@T[1],$b)',	# c^d for next round
-+
-+	'&and	($a,@T[1])',
-+	'&add	($e,@T[0])',
-+	'&xor	($a,$b)'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+}
-+
-+&set_label("loop",16);
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_32_79(\&body_00_19);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xuplast_ssse3_80(\&body_20_39);	# can jump to "done"
-+
-+				$saved_j=$j; @saved_V=@V;
-+
-+	&Xloop_ssse3(\&body_20_39);
-+	&Xloop_ssse3(\&body_20_39);
-+	&Xloop_ssse3(\&body_20_39);
-+
-+	&mov	(@T[1],&DWP(192,"esp"));	# update context
-+	&add	($A,&DWP(0,@T[1]));
-+	&add	(@T[0],&DWP(4,@T[1]));		# $b
-+	&add	($C,&DWP(8,@T[1]));
-+	&mov	(&DWP(0,@T[1]),$A);
-+	&add	($D,&DWP(12,@T[1]));
-+	&mov	(&DWP(4,@T[1]),@T[0]);
-+	&add	($E,&DWP(16,@T[1]));
-+	&mov	(&DWP(8,@T[1]),$C);
-+	&mov	($B,$C);
-+	&mov	(&DWP(12,@T[1]),$D);
-+	&xor	($B,$D);
-+	&mov	(&DWP(16,@T[1]),$E);
-+	&mov	(@T[1],@T[0]);
-+	&pshufd	(@X[0],@X[-4&7],0xee);		# was &movdqa	(@X[0],@X[-3&7]);
-+	&and	(@T[0],$B);
-+	&mov	($B,$T[1]);
-+
-+	&jmp	(&label("loop"));
-+
-+&set_label("done",16);		$j=$saved_j; @V=@saved_V;
-+
-+	&Xtail_ssse3(\&body_20_39);
-+	&Xtail_ssse3(\&body_20_39);
-+	&Xtail_ssse3(\&body_20_39);
-+
-+	&mov	(@T[1],&DWP(192,"esp"));	# update context
-+	&add	($A,&DWP(0,@T[1]));
-+	&mov	("esp",&DWP(192+12,"esp"));	# restore %esp
-+	&add	(@T[0],&DWP(4,@T[1]));		# $b
-+	&add	($C,&DWP(8,@T[1]));
-+	&mov	(&DWP(0,@T[1]),$A);
-+	&add	($D,&DWP(12,@T[1]));
-+	&mov	(&DWP(4,@T[1]),@T[0]);
-+	&add	($E,&DWP(16,@T[1]));
-+	&mov	(&DWP(8,@T[1]),$C);
-+	&mov	(&DWP(12,@T[1]),$D);
-+	&mov	(&DWP(16,@T[1]),$E);
-+
-+&function_end("_sha1_block_data_order_ssse3");
-+
-+$rx=0;	# reset
-+
-+if ($ymm) {
-+my $Xi=4;			# 4xSIMD Xupdate round, start pre-seeded
-+my @X=map("xmm$_",(4..7,0..3));	# pre-seeded for $Xi=4
-+my @V=($A,$B,$C,$D,$E);
-+my $j=0;			# hash round
-+my @T=($T,$tmp1);
-+my $inp;
-+
-+my $_rol=sub { &shld(@_[0],@_) };
-+my $_ror=sub { &shrd(@_[0],@_) };
-+
-+&function_begin("_sha1_block_data_order_avx");
-+	&call	(&label("pic_point"));	# make it PIC!
-+	&set_label("pic_point");
-+	&blindpop($tmp1);
-+	&lea	($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1));
-+&set_label("avx_shortcut");
-+	&vzeroall();
-+
-+	&vmovdqa(@X[3],&QWP(0,$tmp1));		# K_00_19
-+	&vmovdqa(@X[4],&QWP(16,$tmp1));		# K_20_39
-+	&vmovdqa(@X[5],&QWP(32,$tmp1));		# K_40_59
-+	&vmovdqa(@X[6],&QWP(48,$tmp1));		# K_60_79
-+	&vmovdqa(@X[2],&QWP(64,$tmp1));		# pbswap mask
-+
-+	&mov	($E,&wparam(0));		# load argument block
-+	&mov	($inp=@T[1],&wparam(1));
-+	&mov	($D,&wparam(2));
-+	&mov	(@T[0],"esp");
-+
-+	# stack frame layout
-+	#
-+	# +0	X[0]+K	X[1]+K	X[2]+K	X[3]+K	# XMM->IALU xfer area
-+	#	X[4]+K	X[5]+K	X[6]+K	X[7]+K
-+	#	X[8]+K	X[9]+K	X[10]+K	X[11]+K
-+	#	X[12]+K	X[13]+K	X[14]+K	X[15]+K
-+	#
-+	# +64	X[0]	X[1]	X[2]	X[3]	# XMM->XMM backtrace area
-+	#	X[4]	X[5]	X[6]	X[7]
-+	#	X[8]	X[9]	X[10]	X[11]	# even borrowed for K_00_19
-+	#
-+	# +112	K_20_39	K_20_39	K_20_39	K_20_39	# constants
-+	#	K_40_59	K_40_59	K_40_59	K_40_59
-+	#	K_60_79	K_60_79	K_60_79	K_60_79
-+	#	K_00_19	K_00_19	K_00_19	K_00_19
-+	#	pbswap mask
-+	#
-+	# +192	ctx				# argument block
-+	# +196	inp
-+	# +200	end
-+	# +204	esp
-+	&sub	("esp",208);
-+	&and	("esp",-64);
-+
-+	&vmovdqa(&QWP(112+0,"esp"),@X[4]);	# copy constants
-+	&vmovdqa(&QWP(112+16,"esp"),@X[5]);
-+	&vmovdqa(&QWP(112+32,"esp"),@X[6]);
-+	&shl	($D,6);				# len*64
-+	&vmovdqa(&QWP(112+48,"esp"),@X[3]);
-+	&add	($D,$inp);			# end of input
-+	&vmovdqa(&QWP(112+64,"esp"),@X[2]);
-+	&add	($inp,64);
-+	&mov	(&DWP(192+0,"esp"),$E);		# save argument block
-+	&mov	(&DWP(192+4,"esp"),$inp);
-+	&mov	(&DWP(192+8,"esp"),$D);
-+	&mov	(&DWP(192+12,"esp"),@T[0]);	# save original %esp
-+
-+	&mov	($A,&DWP(0,$E));		# load context
-+	&mov	($B,&DWP(4,$E));
-+	&mov	($C,&DWP(8,$E));
-+	&mov	($D,&DWP(12,$E));
-+	&mov	($E,&DWP(16,$E));
-+	&mov	(@T[0],$B);			# magic seed
-+
-+	&vmovdqu(@X[-4&7],&QWP(-64,$inp));	# load input to %xmm[0-3]
-+	&vmovdqu(@X[-3&7],&QWP(-48,$inp));
-+	&vmovdqu(@X[-2&7],&QWP(-32,$inp));
-+	&vmovdqu(@X[-1&7],&QWP(-16,$inp));
-+	&vpshufb(@X[-4&7],@X[-4&7],@X[2]);	# byte swap
-+	&vpshufb(@X[-3&7],@X[-3&7],@X[2]);
-+	&vpshufb(@X[-2&7],@X[-2&7],@X[2]);
-+	&vmovdqa(&QWP(112-16,"esp"),@X[3]);	# borrow last backtrace slot
-+	&vpshufb(@X[-1&7],@X[-1&7],@X[2]);
-+	&vpaddd	(@X[0],@X[-4&7],@X[3]);		# add K_00_19
-+	&vpaddd	(@X[1],@X[-3&7],@X[3]);
-+	&vpaddd	(@X[2],@X[-2&7],@X[3]);
-+	&vmovdqa(&QWP(0,"esp"),@X[0]);		# X[]+K xfer to IALU
-+	&mov	(@T[1],$C);
-+	&vmovdqa(&QWP(0+16,"esp"),@X[1]);
-+	&xor	(@T[1],$D);
-+	&vmovdqa(&QWP(0+32,"esp"),@X[2]);
-+	&and	(@T[0],@T[1]);
-+	&jmp	(&label("loop"));
-+
-+sub Xupdate_avx_16_31()		# recall that $Xi starts wtih 4
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpalignr(@X[0],@X[-3&7],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	  &vpaddd	(@X[3],@X[3],@X[-1&7]);
-+	  &vmovdqa	(&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);# save X[] to backtrace buffer
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpsrldq(@X[2],@X[-1&7],4);		# "X[-3]", 3 dwords
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"^="X[-16]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[2],@X[2],@X[-2&7]);		# "X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vmovdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@X[2]);		# "X[0]"^="X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpsrld	(@X[2],@X[0],31);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpslldq(@X[4],@X[0],12);		# "X[0]"<<96, extract one dword
-+	&vpaddd	(@X[0],@X[0],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpsrld	(@X[3],@X[4],30);
-+	&vpor	(@X[0],@X[0],@X[2]);		# "X[0]"<<<=1
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpslld	(@X[4],@X[4],2);
-+	  &vmovdqa	(@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if ($Xi>5);	# restore X[] from backtrace buffer
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpxor	(@X[0],@X[0],@X[3]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@X[4]);		# "X[0]"^=("X[0]"<<96)<<<2
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vmovdqa	(@X[4],&QWP(112-16+16*(($Xi)/5),"esp"));	# K_XX_XX
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	 foreach (@insns) { eval; }	# remaining instructions [if any]
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xupdate_avx_32_79()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 44 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	&vpalignr(@X[2],@X[-1&7],@X[-2&7],8);	# compose "X[-6]"
-+	&vpxor	(@X[0],@X[0],@X[-4&7]);	# "X[0]"="X[-32]"^"X[-16]"
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+
-+	&vpxor	(@X[0],@X[0],@X[-7&7]);	# "X[0]"^="X[-28]"
-+	  &vmovdqa	(&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);	# save X[] to backtrace buffer
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 if ($Xi%5) {
-+	  &vmovdqa	(@X[4],@X[3]);	# "perpetuate" K_XX_XX...
-+	 } else {			# ... or load next one
-+	  &vmovdqa	(@X[4],&QWP(112-16+16*($Xi/5),"esp"));
-+	 }
-+	  &vpaddd	(@X[3],@X[3],@X[-1&7]);
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@X[2]);		# "X[0]"^="X[-6]"
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+
-+	&vpsrld	(@X[2],@X[0],30);
-+	  &vmovdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+
-+	&vpslld	(@X[0],@X[0],2);
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+
-+	&vpor	(@X[0],@X[0],@X[2]);	# "X[0]"<<<=2
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	  &vmovdqa	(@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if($Xi<19);	# restore X[] from backtrace buffer
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+
-+	 foreach (@insns) { eval; }	# remaining instructions
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xuplast_avx_80()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	  &vpaddd	(@X[3],@X[3],@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	  &vmovdqa	(&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]);	# X[]+K xfer IALU
-+
-+	 foreach (@insns) { eval; }		# remaining instructions
-+
-+	&mov	($inp=@T[1],&DWP(192+4,"esp"));
-+	&cmp	($inp,&DWP(192+8,"esp"));
-+	&je	(&label("done"));
-+
-+	&vmovdqa(@X[3],&QWP(112+48,"esp"));	# K_00_19
-+	&vmovdqa(@X[2],&QWP(112+64,"esp"));	# pbswap mask
-+	&vmovdqu(@X[-4&7],&QWP(0,$inp));	# load input
-+	&vmovdqu(@X[-3&7],&QWP(16,$inp));
-+	&vmovdqu(@X[-2&7],&QWP(32,$inp));
-+	&vmovdqu(@X[-1&7],&QWP(48,$inp));
-+	&add	($inp,64);
-+	&vpshufb(@X[-4&7],@X[-4&7],@X[2]);		# byte swap
-+	&mov	(&DWP(192+4,"esp"),$inp);
-+	&vmovdqa(&QWP(112-16,"esp"),@X[3]);	# borrow last backtrace slot
-+
-+  $Xi=0;
-+}
-+
-+sub Xloop_avx()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpshufb	(@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpaddd	(@X[$Xi&7],@X[($Xi-4)&7],@X[3]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vmovdqa	(&QWP(0+16*$Xi,"esp"),@X[$Xi&7]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	foreach (@insns) { eval; }
-+  $Xi++;
-+}
-+
-+sub Xtail_avx()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	foreach (@insns) { eval; }
-+}
-+
-+&set_label("loop",16);
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_32_79(\&body_00_19);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xuplast_avx_80(\&body_20_39);	# can jump to "done"
-+
-+				$saved_j=$j; @saved_V=@V;
-+
-+	&Xloop_avx(\&body_20_39);
-+	&Xloop_avx(\&body_20_39);
-+	&Xloop_avx(\&body_20_39);
-+
-+	&mov	(@T[1],&DWP(192,"esp"));	# update context
-+	&add	($A,&DWP(0,@T[1]));
-+	&add	(@T[0],&DWP(4,@T[1]));		# $b
-+	&add	($C,&DWP(8,@T[1]));
-+	&mov	(&DWP(0,@T[1]),$A);
-+	&add	($D,&DWP(12,@T[1]));
-+	&mov	(&DWP(4,@T[1]),@T[0]);
-+	&add	($E,&DWP(16,@T[1]));
-+	&mov	($B,$C);
-+	&mov	(&DWP(8,@T[1]),$C);
-+	&xor	($B,$D);
-+	&mov	(&DWP(12,@T[1]),$D);
-+	&mov	(&DWP(16,@T[1]),$E);
-+	&mov	(@T[1],@T[0]);
-+	&and	(@T[0],$B);
-+	&mov	($B,@T[1]);
-+
-+	&jmp	(&label("loop"));
-+
-+&set_label("done",16);		$j=$saved_j; @V=@saved_V;
-+
-+	&Xtail_avx(\&body_20_39);
-+	&Xtail_avx(\&body_20_39);
-+	&Xtail_avx(\&body_20_39);
-+
-+	&vzeroall();
-+
-+	&mov	(@T[1],&DWP(192,"esp"));	# update context
-+	&add	($A,&DWP(0,@T[1]));
-+	&mov	("esp",&DWP(192+12,"esp"));	# restore %esp
-+	&add	(@T[0],&DWP(4,@T[1]));		# $b
-+	&add	($C,&DWP(8,@T[1]));
-+	&mov	(&DWP(0,@T[1]),$A);
-+	&add	($D,&DWP(12,@T[1]));
-+	&mov	(&DWP(4,@T[1]),@T[0]);
-+	&add	($E,&DWP(16,@T[1]));
-+	&mov	(&DWP(8,@T[1]),$C);
-+	&mov	(&DWP(12,@T[1]),$D);
-+	&mov	(&DWP(16,@T[1]),$E);
-+&function_end("_sha1_block_data_order_avx");
-+}
-+&set_label("K_XX_XX",64);
-+&data_word(0x5a827999,0x5a827999,0x5a827999,0x5a827999);	# K_00_19
-+&data_word(0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1);	# K_20_39
-+&data_word(0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc);	# K_40_59
-+&data_word(0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6);	# K_60_79
-+&data_word(0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f);	# pbswap mask
-+&data_byte(0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0);
-+}
-+&asciz("SHA1 block transform for x86, CRYPTOGAMS by ");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-alpha.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-alpha.pl
-new file mode 100644
-index 0000000..4124958
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-alpha.pl
-@@ -0,0 +1,329 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# SHA1 block procedure for Alpha.
-+
-+# On 21264 performance is 33% better than code generated by vendor
-+# compiler, and 75% better than GCC [3.4], and in absolute terms is
-+# 8.7 cycles per processed byte. Implementation features vectorized
-+# byte swap, but not Xupdate.
-+
-+@X=(	"\$0",	"\$1",	"\$2",	"\$3",	"\$4",	"\$5",	"\$6",	"\$7",
-+	"\$8",	"\$9",	"\$10",	"\$11",	"\$12",	"\$13",	"\$14",	"\$15");
-+$ctx="a0";	# $16
-+$inp="a1";
-+$num="a2";
-+$A="a3";
-+$B="a4";	# 20
-+$C="a5";
-+$D="t8";
-+$E="t9";	@V=($A,$B,$C,$D,$E);
-+$t0="t10";	# 24
-+$t1="t11";
-+$t2="ra";
-+$t3="t12";
-+$K="AT";	# 28
-+
-+sub BODY_00_19 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___ if ($i==0);
-+	ldq_u	@X[0],0+0($inp)
-+	ldq_u	@X[1],0+7($inp)
-+___
-+$code.=<<___ if (!($i&1) && $i<14);
-+	ldq_u	@X[$i+2],($i+2)*4+0($inp)
-+	ldq_u	@X[$i+3],($i+2)*4+7($inp)
-+___
-+$code.=<<___ if (!($i&1) && $i<15);
-+	extql	@X[$i],$inp,@X[$i]
-+	extqh	@X[$i+1],$inp,@X[$i+1]
-+
-+	or	@X[$i+1],@X[$i],@X[$i]	# pair of 32-bit values are fetched
-+
-+	srl	@X[$i],24,$t0		# vectorized byte swap
-+	srl	@X[$i],8,$t2
-+
-+	sll	@X[$i],8,$t3
-+	sll	@X[$i],24,@X[$i]
-+	zapnot	$t0,0x11,$t0
-+	zapnot	$t2,0x22,$t2
-+
-+	zapnot	@X[$i],0x88,@X[$i]
-+	or	$t0,$t2,$t0
-+	zapnot	$t3,0x44,$t3
-+	sll	$a,5,$t1
-+
-+	or	@X[$i],$t0,@X[$i]
-+	addl	$K,$e,$e
-+	and	$b,$c,$t2
-+	zapnot	$a,0xf,$a
-+
-+	or	@X[$i],$t3,@X[$i]
-+	srl	$a,27,$t0
-+	bic	$d,$b,$t3
-+	sll	$b,30,$b
-+
-+	extll	@X[$i],4,@X[$i+1]	# extract upper half
-+	or	$t2,$t3,$t2
-+	addl	@X[$i],$e,$e
-+
-+	addl	$t1,$e,$e
-+	srl	$b,32,$t3
-+	zapnot	@X[$i],0xf,@X[$i]
-+
-+	addl	$t0,$e,$e
-+	addl	$t2,$e,$e
-+	or	$t3,$b,$b
-+___
-+$code.=<<___ if (($i&1) && $i<15);
-+	sll	$a,5,$t1
-+	addl	$K,$e,$e
-+	and	$b,$c,$t2
-+	zapnot	$a,0xf,$a
-+
-+	srl	$a,27,$t0
-+	addl	@X[$i%16],$e,$e
-+	bic	$d,$b,$t3
-+	sll	$b,30,$b
-+
-+	or	$t2,$t3,$t2
-+	addl	$t1,$e,$e
-+	srl	$b,32,$t3
-+	zapnot	@X[$i],0xf,@X[$i]
-+
-+	addl	$t0,$e,$e
-+	addl	$t2,$e,$e
-+	or	$t3,$b,$b
-+___
-+$code.=<<___ if ($i>=15);	# with forward Xupdate
-+	sll	$a,5,$t1
-+	addl	$K,$e,$e
-+	and	$b,$c,$t2
-+	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]
-+
-+	zapnot	$a,0xf,$a
-+	addl	@X[$i%16],$e,$e
-+	bic	$d,$b,$t3
-+	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
-+
-+	srl	$a,27,$t0
-+	addl	$t1,$e,$e
-+	or	$t2,$t3,$t2
-+	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
-+
-+	sll	$b,30,$b
-+	addl	$t0,$e,$e
-+	srl	@X[$j%16],31,$t1
-+
-+	addl	$t2,$e,$e
-+	srl	$b,32,$t3
-+	addl	@X[$j%16],@X[$j%16],@X[$j%16]
-+
-+	or	$t3,$b,$b
-+	zapnot	@X[$i%16],0xf,@X[$i%16]
-+	or	$t1,@X[$j%16],@X[$j%16]
-+___
-+}
-+
-+sub BODY_20_39 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___ if ($i<79);	# with forward Xupdate
-+	sll	$a,5,$t1
-+	addl	$K,$e,$e
-+	zapnot	$a,0xf,$a
-+	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]
-+
-+	sll	$b,30,$t3
-+	addl	$t1,$e,$e
-+	xor	$b,$c,$t2
-+	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
-+
-+	srl	$b,2,$b
-+	addl	@X[$i%16],$e,$e
-+	xor	$d,$t2,$t2
-+	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
-+
-+	srl	@X[$j%16],31,$t1
-+	addl	$t2,$e,$e
-+	srl	$a,27,$t0
-+	addl	@X[$j%16],@X[$j%16],@X[$j%16]
-+
-+	or	$t3,$b,$b
-+	addl	$t0,$e,$e
-+	or	$t1,@X[$j%16],@X[$j%16]
-+___
-+$code.=<<___ if ($i<77);
-+	zapnot	@X[$i%16],0xf,@X[$i%16]
-+___
-+$code.=<<___ if ($i==79);	# with context fetch
-+	sll	$a,5,$t1
-+	addl	$K,$e,$e
-+	zapnot	$a,0xf,$a
-+	ldl	@X[0],0($ctx)
-+
-+	sll	$b,30,$t3
-+	addl	$t1,$e,$e
-+	xor	$b,$c,$t2
-+	ldl	@X[1],4($ctx)
-+
-+	srl	$b,2,$b
-+	addl	@X[$i%16],$e,$e
-+	xor	$d,$t2,$t2
-+	ldl	@X[2],8($ctx)
-+
-+	srl	$a,27,$t0
-+	addl	$t2,$e,$e
-+	ldl	@X[3],12($ctx)
-+
-+	or	$t3,$b,$b
-+	addl	$t0,$e,$e
-+	ldl	@X[4],16($ctx)
-+___
-+}
-+
-+sub BODY_40_59 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___;	# with forward Xupdate
-+	sll	$a,5,$t1
-+	addl	$K,$e,$e
-+	zapnot	$a,0xf,$a
-+	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]
-+
-+	srl	$a,27,$t0
-+	and	$b,$c,$t2
-+	and	$b,$d,$t3
-+	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
-+
-+	sll	$b,30,$b
-+	addl	$t1,$e,$e
-+	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
-+
-+	srl	@X[$j%16],31,$t1
-+	addl	$t0,$e,$e
-+	or	$t2,$t3,$t2
-+	and	$c,$d,$t3
-+
-+	or	$t2,$t3,$t2
-+	srl	$b,32,$t3
-+	addl	@X[$i%16],$e,$e
-+	addl	@X[$j%16],@X[$j%16],@X[$j%16]
-+
-+	or	$t3,$b,$b
-+	addl	$t2,$e,$e
-+	or	$t1,@X[$j%16],@X[$j%16]
-+	zapnot	@X[$i%16],0xf,@X[$i%16]
-+___
-+}
-+
-+$code=<<___;
-+#ifdef __linux__
-+#include 
-+#else
-+#include 
-+#include 
-+#endif
-+
-+.text
-+
-+.set	noat
-+.set	noreorder
-+.globl	sha1_block_data_order
-+.align	5
-+.ent	sha1_block_data_order
-+sha1_block_data_order:
-+	lda	sp,-64(sp)
-+	stq	ra,0(sp)
-+	stq	s0,8(sp)
-+	stq	s1,16(sp)
-+	stq	s2,24(sp)
-+	stq	s3,32(sp)
-+	stq	s4,40(sp)
-+	stq	s5,48(sp)
-+	stq	fp,56(sp)
-+	.mask	0x0400fe00,-64
-+	.frame	sp,64,ra
-+	.prologue 0
-+
-+	ldl	$A,0($ctx)
-+	ldl	$B,4($ctx)
-+	sll	$num,6,$num
-+	ldl	$C,8($ctx)
-+	ldl	$D,12($ctx)
-+	ldl	$E,16($ctx)
-+	addq	$inp,$num,$num
-+
-+.Lloop:
-+	.set	noreorder
-+	ldah	$K,23170(zero)
-+	zapnot	$B,0xf,$B
-+	lda	$K,31129($K)	# K_00_19
-+___
-+for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
-+
-+$code.=<<___;
-+	ldah	$K,28378(zero)
-+	lda	$K,-5215($K)	# K_20_39
-+___
-+for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+
-+$code.=<<___;
-+	ldah	$K,-28900(zero)
-+	lda	$K,-17188($K)	# K_40_59
-+___
-+for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+
-+$code.=<<___;
-+	ldah	$K,-13725(zero)
-+	lda	$K,-15914($K)	# K_60_79
-+___
-+for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+
-+$code.=<<___;
-+	addl	@X[0],$A,$A
-+	addl	@X[1],$B,$B
-+	addl	@X[2],$C,$C
-+	addl	@X[3],$D,$D
-+	addl	@X[4],$E,$E
-+	stl	$A,0($ctx)
-+	stl	$B,4($ctx)
-+	addq	$inp,64,$inp
-+	stl	$C,8($ctx)
-+	stl	$D,12($ctx)
-+	stl	$E,16($ctx)
-+	cmpult	$inp,$num,$t1
-+	bne	$t1,.Lloop
-+
-+	.set	noreorder
-+	ldq	ra,0(sp)
-+	ldq	s0,8(sp)
-+	ldq	s1,16(sp)
-+	ldq	s2,24(sp)
-+	ldq	s3,32(sp)
-+	ldq	s4,40(sp)
-+	ldq	s5,48(sp)
-+	ldq	fp,56(sp)
-+	lda	sp,64(sp)
-+	ret	(ra)
-+.end	sha1_block_data_order
-+.ascii	"SHA1 block transform for Alpha, CRYPTOGAMS by "
-+.align	2
-+___
-+$output=pop and open STDOUT,">$output";
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-armv4-large.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-armv4-large.pl
-new file mode 100644
-index 0000000..7ff5bfb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-armv4-large.pl
-@@ -0,0 +1,742 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# sha1_block procedure for ARMv4.
-+#
-+# January 2007.
-+
-+# Size/performance trade-off
-+# ====================================================================
-+# impl		size in bytes	comp cycles[*]	measured performance
-+# ====================================================================
-+# thumb		304		3212		4420
-+# armv4-small	392/+29%	1958/+64%	2250/+96%
-+# armv4-compact	740/+89%	1552/+26%	1840/+22%
-+# armv4-large	1420/+92%	1307/+19%	1370/+34%[***]
-+# full unroll	~5100/+260%	~1260/+4%	~1300/+5%
-+# ====================================================================
-+# thumb		= same as 'small' but in Thumb instructions[**] and
-+#		  with recurring code in two private functions;
-+# small		= detached Xload/update, loops are folded;
-+# compact	= detached Xload/update, 5x unroll;
-+# large		= interleaved Xload/update, 5x unroll;
-+# full unroll	= interleaved Xload/update, full unroll, estimated[!];
-+#
-+# [*]	Manually counted instructions in "grand" loop body. Measured
-+#	performance is affected by prologue and epilogue overhead,
-+#	i-cache availability, branch penalties, etc.
-+# [**]	While each Thumb instruction is twice smaller, they are not as
-+#	diverse as ARM ones: e.g., there are only two arithmetic
-+#	instructions with 3 arguments, no [fixed] rotate, addressing
-+#	modes are limited. As result it takes more instructions to do
-+#	the same job in Thumb, therefore the code is never twice as
-+#	small and always slower.
-+# [***]	which is also ~35% better than compiler generated code. Dual-
-+#	issue Cortex A8 core was measured to process input block in
-+#	~990 cycles.
-+
-+# August 2010.
-+#
-+# Rescheduling for dual-issue pipeline resulted in 13% improvement on
-+# Cortex A8 core and in absolute terms ~870 cycles per input block
-+# [or 13.6 cycles per byte].
-+
-+# February 2011.
-+#
-+# Profiler-assisted and platform-specific optimization resulted in 10%
-+# improvement on Cortex A8 core and 12.2 cycles per byte.
-+
-+# September 2013.
-+#
-+# Add NEON implementation (see sha1-586.pl for background info). On
-+# Cortex A8 it was measured to process one byte in 6.7 cycles or >80%
-+# faster than integer-only code. Because [fully unrolled] NEON code
-+# is ~2.5x larger and there are some redundant instructions executed
-+# when processing last block, improvement is not as big for smallest
-+# blocks, only ~30%. Snapdragon S4 is a tad faster, 6.4 cycles per
-+# byte, which is also >80% faster than integer-only code. Cortex-A15
-+# is even faster spending 5.6 cycles per byte outperforming integer-
-+# only code by factor of 2.
-+
-+# May 2014.
-+#
-+# Add ARMv8 code path performing at 2.35 cpb on Apple A7.
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+$ctx="r0";
-+$inp="r1";
-+$len="r2";
-+$a="r3";
-+$b="r4";
-+$c="r5";
-+$d="r6";
-+$e="r7";
-+$K="r8";
-+$t0="r9";
-+$t1="r10";
-+$t2="r11";
-+$t3="r12";
-+$Xi="r14";
-+@V=($a,$b,$c,$d,$e);
-+
-+sub Xupdate {
-+my ($a,$b,$c,$d,$e,$opt1,$opt2)=@_;
-+$code.=<<___;
-+	ldr	$t0,[$Xi,#15*4]
-+	ldr	$t1,[$Xi,#13*4]
-+	ldr	$t2,[$Xi,#7*4]
-+	add	$e,$K,$e,ror#2			@ E+=K_xx_xx
-+	ldr	$t3,[$Xi,#2*4]
-+	eor	$t0,$t0,$t1
-+	eor	$t2,$t2,$t3			@ 1 cycle stall
-+	eor	$t1,$c,$d			@ F_xx_xx
-+	mov	$t0,$t0,ror#31
-+	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
-+	eor	$t0,$t0,$t2,ror#31
-+	str	$t0,[$Xi,#-4]!
-+	$opt1					@ F_xx_xx
-+	$opt2					@ F_xx_xx
-+	add	$e,$e,$t0			@ E+=X[i]
-+___
-+}
-+
-+sub BODY_00_15 {
-+my ($a,$b,$c,$d,$e)=@_;
-+$code.=<<___;
-+#if __ARM_ARCH__<7
-+	ldrb	$t1,[$inp,#2]
-+	ldrb	$t0,[$inp,#3]
-+	ldrb	$t2,[$inp,#1]
-+	add	$e,$K,$e,ror#2			@ E+=K_00_19
-+	ldrb	$t3,[$inp],#4
-+	orr	$t0,$t0,$t1,lsl#8
-+	eor	$t1,$c,$d			@ F_xx_xx
-+	orr	$t0,$t0,$t2,lsl#16
-+	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
-+	orr	$t0,$t0,$t3,lsl#24
-+#else
-+	ldr	$t0,[$inp],#4			@ handles unaligned
-+	add	$e,$K,$e,ror#2			@ E+=K_00_19
-+	eor	$t1,$c,$d			@ F_xx_xx
-+	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
-+#ifdef __ARMEL__
-+	rev	$t0,$t0				@ byte swap
-+#endif
-+#endif
-+	and	$t1,$b,$t1,ror#2
-+	add	$e,$e,$t0			@ E+=X[i]
-+	eor	$t1,$t1,$d,ror#2		@ F_00_19(B,C,D)
-+	str	$t0,[$Xi,#-4]!
-+	add	$e,$e,$t1			@ E+=F_00_19(B,C,D)
-+___
-+}
-+
-+sub BODY_16_19 {
-+my ($a,$b,$c,$d,$e)=@_;
-+	&Xupdate(@_,"and $t1,$b,$t1,ror#2");
-+$code.=<<___;
-+	eor	$t1,$t1,$d,ror#2		@ F_00_19(B,C,D)
-+	add	$e,$e,$t1			@ E+=F_00_19(B,C,D)
-+___
-+}
-+
-+sub BODY_20_39 {
-+my ($a,$b,$c,$d,$e)=@_;
-+	&Xupdate(@_,"eor $t1,$b,$t1,ror#2");
-+$code.=<<___;
-+	add	$e,$e,$t1			@ E+=F_20_39(B,C,D)
-+___
-+}
-+
-+sub BODY_40_59 {
-+my ($a,$b,$c,$d,$e)=@_;
-+	&Xupdate(@_,"and $t1,$b,$t1,ror#2","and $t2,$c,$d");
-+$code.=<<___;
-+	add	$e,$e,$t1			@ E+=F_40_59(B,C,D)
-+	add	$e,$e,$t2,ror#2
-+___
-+}
-+
-+$code=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+#if defined(__thumb2__)
-+.syntax	unified
-+.thumb
-+#else
-+.code	32
-+#endif
-+
-+.global	sha1_block_data_order
-+.type	sha1_block_data_order,%function
-+
-+.align	5
-+sha1_block_data_order:
-+#if __ARM_MAX_ARCH__>=7
-+.Lsha1_block:
-+	adr	r3,.Lsha1_block
-+	ldr	r12,.LOPENSSL_armcap
-+	ldr	r12,[r3,r12]		@ OPENSSL_armcap_P
-+#ifdef	__APPLE__
-+	ldr	r12,[r12]
-+#endif
-+	tst	r12,#ARMV8_SHA1
-+	bne	.LARMv8
-+	tst	r12,#ARMV7_NEON
-+	bne	.LNEON
-+#endif
-+	stmdb	sp!,{r4-r12,lr}
-+	add	$len,$inp,$len,lsl#6	@ $len to point at the end of $inp
-+	ldmia	$ctx,{$a,$b,$c,$d,$e}
-+.Lloop:
-+	ldr	$K,.LK_00_19
-+	mov	$Xi,sp
-+	sub	sp,sp,#15*4
-+	mov	$c,$c,ror#30
-+	mov	$d,$d,ror#30
-+	mov	$e,$e,ror#30		@ [6]
-+.L_00_15:
-+___
-+for($i=0;$i<5;$i++) {
-+	&BODY_00_15(@V);	unshift(@V,pop(@V));
-+}
-+$code.=<<___;
-+#if defined(__thumb2__)
-+	mov	$t3,sp
-+	teq	$Xi,$t3
-+#else
-+	teq	$Xi,sp
-+#endif
-+	bne	.L_00_15		@ [((11+4)*5+2)*3]
-+	sub	sp,sp,#25*4
-+___
-+	&BODY_00_15(@V);	unshift(@V,pop(@V));
-+	&BODY_16_19(@V);	unshift(@V,pop(@V));
-+	&BODY_16_19(@V);	unshift(@V,pop(@V));
-+	&BODY_16_19(@V);	unshift(@V,pop(@V));
-+	&BODY_16_19(@V);	unshift(@V,pop(@V));
-+$code.=<<___;
-+
-+	ldr	$K,.LK_20_39		@ [+15+16*4]
-+	cmn	sp,#0			@ [+3], clear carry to denote 20_39
-+.L_20_39_or_60_79:
-+___
-+for($i=0;$i<5;$i++) {
-+	&BODY_20_39(@V);	unshift(@V,pop(@V));
-+}
-+$code.=<<___;
-+#if defined(__thumb2__)
-+	mov	$t3,sp
-+	teq	$Xi,$t3
-+#else
-+	teq	$Xi,sp			@ preserve carry
-+#endif
-+	bne	.L_20_39_or_60_79	@ [+((12+3)*5+2)*4]
-+	bcs	.L_done			@ [+((12+3)*5+2)*4], spare 300 bytes
-+
-+	ldr	$K,.LK_40_59
-+	sub	sp,sp,#20*4		@ [+2]
-+.L_40_59:
-+___
-+for($i=0;$i<5;$i++) {
-+	&BODY_40_59(@V);	unshift(@V,pop(@V));
-+}
-+$code.=<<___;
-+#if defined(__thumb2__)
-+	mov	$t3,sp
-+	teq	$Xi,$t3
-+#else
-+	teq	$Xi,sp
-+#endif
-+	bne	.L_40_59		@ [+((12+5)*5+2)*4]
-+
-+	ldr	$K,.LK_60_79
-+	sub	sp,sp,#20*4
-+	cmp	sp,#0			@ set carry to denote 60_79
-+	b	.L_20_39_or_60_79	@ [+4], spare 300 bytes
-+.L_done:
-+	add	sp,sp,#80*4		@ "deallocate" stack frame
-+	ldmia	$ctx,{$K,$t0,$t1,$t2,$t3}
-+	add	$a,$K,$a
-+	add	$b,$t0,$b
-+	add	$c,$t1,$c,ror#2
-+	add	$d,$t2,$d,ror#2
-+	add	$e,$t3,$e,ror#2
-+	stmia	$ctx,{$a,$b,$c,$d,$e}
-+	teq	$inp,$len
-+	bne	.Lloop			@ [+18], total 1307
-+
-+#if __ARM_ARCH__>=5
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	sha1_block_data_order,.-sha1_block_data_order
-+
-+.align	5
-+.LK_00_19:	.word	0x5a827999
-+.LK_20_39:	.word	0x6ed9eba1
-+.LK_40_59:	.word	0x8f1bbcdc
-+.LK_60_79:	.word	0xca62c1d6
-+#if __ARM_MAX_ARCH__>=7
-+.LOPENSSL_armcap:
-+.word	OPENSSL_armcap_P-.Lsha1_block
-+#endif
-+.asciz	"SHA1 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by "
-+.align	5
-+___
-+#####################################################################
-+# NEON stuff
-+#
-+{{{
-+my @V=($a,$b,$c,$d,$e);
-+my ($K_XX_XX,$Ki,$t0,$t1,$Xfer,$saved_sp)=map("r$_",(8..12,14));
-+my $Xi=4;
-+my @X=map("q$_",(8..11,0..3));
-+my @Tx=("q12","q13");
-+my ($K,$zero)=("q14","q15");
-+my $j=0;
-+
-+sub AUTOLOAD()          # thunk [simplified] x86-style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
-+  my $arg = pop;
-+    $arg = "#$arg" if ($arg*1 eq $arg);
-+    $code .= "\t$opcode\t".join(',',@_,$arg)."\n";
-+}
-+
-+sub body_00_19 () {
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.		# '$code.="@ $j\n";'.
-+	'&bic	($t0,$d,$b)',
-+	'&add	($e,$e,$Ki)',		# e+=X[i]+K
-+	'&and	($t1,$c,$b)',
-+	'&ldr	($Ki,sprintf "[sp,#%d]",4*(($j+1)&15))',
-+	'&add	($e,$e,$a,"ror#27")',	# e+=ROR(A,27)
-+	'&eor	($t1,$t1,$t0)',		# F_00_19
-+	'&mov	($b,$b,"ror#2")',	# b=ROR(b,2)
-+	'&add	($e,$e,$t1);'.		# e+=F_00_19
-+	'$j++;	unshift(@V,pop(@V));'
-+	)
-+}
-+sub body_20_39 () {
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.		# '$code.="@ $j\n";'.
-+	'&eor	($t0,$b,$d)',
-+	'&add	($e,$e,$Ki)',		# e+=X[i]+K
-+	'&ldr	($Ki,sprintf "[sp,#%d]",4*(($j+1)&15)) if ($j<79)',
-+	'&eor	($t1,$t0,$c)',		# F_20_39
-+	'&add	($e,$e,$a,"ror#27")',	# e+=ROR(A,27)
-+	'&mov	($b,$b,"ror#2")',	# b=ROR(b,2)
-+	'&add	($e,$e,$t1);'.		# e+=F_20_39
-+	'$j++;	unshift(@V,pop(@V));'
-+	)
-+}
-+sub body_40_59 () {
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.		# '$code.="@ $j\n";'.
-+	'&add	($e,$e,$Ki)',		# e+=X[i]+K
-+	'&and	($t0,$c,$d)',
-+	'&ldr	($Ki,sprintf "[sp,#%d]",4*(($j+1)&15))',
-+	'&add	($e,$e,$a,"ror#27")',	# e+=ROR(A,27)
-+	'&eor	($t1,$c,$d)',
-+	'&add	($e,$e,$t0)',
-+	'&and	($t1,$t1,$b)',
-+	'&mov	($b,$b,"ror#2")',	# b=ROR(b,2)
-+	'&add	($e,$e,$t1);'.		# e+=F_40_59
-+	'$j++;	unshift(@V,pop(@V));'
-+	)
-+}
-+
-+sub Xupdate_16_31 ()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);
-+  my ($a,$b,$c,$d,$e);
-+
-+	&vext_8		(@X[0],@X[-4&7],@X[-3&7],8);	# compose "X[-14]" in "X[0]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vadd_i32	(@Tx[1],@X[-1&7],$K);
-+	 eval(shift(@insns));
-+	  &vld1_32	("{$K\[]}","[$K_XX_XX,:32]!")	if ($Xi%5==0);
-+	 eval(shift(@insns));
-+	&vext_8		(@Tx[0],@X[-1&7],$zero,4);	# "X[-3]", 3 words
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&veor		(@X[0],@X[0],@X[-4&7]);		# "X[0]"^="X[-16]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&veor		(@Tx[0],@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&veor		(@Tx[0],@Tx[0],@X[0]);		# "X[0]"^="X[-3]"^"X[-8]
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vst1_32	("{@Tx[1]}","[$Xfer,:128]!");	# X[]+K xfer
-+	  &sub		($Xfer,$Xfer,64)		if ($Xi%4==0);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vext_8		(@Tx[1],$zero,@Tx[0],4);	# "X[0]"<<96, extract one dword
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vadd_i32	(@X[0],@Tx[0],@Tx[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vsri_32	(@X[0],@Tx[0],31);		# "X[0]"<<<=1
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vshr_u32	(@Tx[0],@Tx[1],30);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vshl_u32	(@Tx[1],@Tx[1],2);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&veor		(@X[0],@X[0],@Tx[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&veor		(@X[0],@X[0],@Tx[1]);		# "X[0]"^=("X[0]">>96)<<<2
-+
-+	foreach (@insns) { eval; }	# remaining instructions [if any]
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xupdate_32_79 ()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);
-+  my ($a,$b,$c,$d,$e);
-+
-+	&vext_8		(@Tx[0],@X[-2&7],@X[-1&7],8);	# compose "X[-6]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&veor		(@X[0],@X[0],@X[-4&7]);		# "X[0]"="X[-32]"^"X[-16]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&veor		(@X[0],@X[0],@X[-7&7]);		# "X[0]"^="X[-28]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vadd_i32	(@Tx[1],@X[-1&7],$K);
-+	 eval(shift(@insns));
-+	  &vld1_32	("{$K\[]}","[$K_XX_XX,:32]!")	if ($Xi%5==0);
-+	 eval(shift(@insns));
-+	&veor		(@Tx[0],@Tx[0],@X[0]);		# "X[-6]"^="X[0]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vshr_u32	(@X[0],@Tx[0],30);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vst1_32	("{@Tx[1]}","[$Xfer,:128]!");	# X[]+K xfer
-+	  &sub		($Xfer,$Xfer,64)		if ($Xi%4==0);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vsli_32	(@X[0],@Tx[0],2);		# "X[0]"="X[-6]"<<<2
-+
-+	foreach (@insns) { eval; }	# remaining instructions [if any]
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xuplast_80 ()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);
-+  my ($a,$b,$c,$d,$e);
-+
-+	&vadd_i32	(@Tx[1],@X[-1&7],$K);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vst1_32	("{@Tx[1]}","[$Xfer,:128]!");
-+	&sub		($Xfer,$Xfer,64);
-+
-+	&teq		($inp,$len);
-+	&sub		($K_XX_XX,$K_XX_XX,16);	# rewind $K_XX_XX
-+	&it		("eq");
-+	&subeq		($inp,$inp,64);		# reload last block to avoid SEGV
-+	&vld1_8		("{@X[-4&7]-@X[-3&7]}","[$inp]!");
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vld1_8		("{@X[-2&7]-@X[-1&7]}","[$inp]!");
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vld1_32	("{$K\[]}","[$K_XX_XX,:32]!");	# load K_00_19
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vrev32_8	(@X[-4&7],@X[-4&7]);
-+
-+	foreach (@insns) { eval; }		# remaining instructions
-+
-+   $Xi=0;
-+}
-+
-+sub Xloop()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);
-+  my ($a,$b,$c,$d,$e);
-+
-+	&vrev32_8	(@X[($Xi-3)&7],@X[($Xi-3)&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vadd_i32	(@X[$Xi&7],@X[($Xi-4)&7],$K);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vst1_32	("{@X[$Xi&7]}","[$Xfer,:128]!");# X[]+K xfer to IALU
-+
-+	foreach (@insns) { eval; }
-+
-+  $Xi++;
-+}
-+
-+$code.=<<___;
-+#if __ARM_MAX_ARCH__>=7
-+.arch	armv7-a
-+.fpu	neon
-+
-+.type	sha1_block_data_order_neon,%function
-+.align	4
-+sha1_block_data_order_neon:
-+.LNEON:
-+	stmdb	sp!,{r4-r12,lr}
-+	add	$len,$inp,$len,lsl#6	@ $len to point at the end of $inp
-+	@ dmb				@ errata #451034 on early Cortex A8
-+	@ vstmdb	sp!,{d8-d15}	@ ABI specification says so
-+	mov	$saved_sp,sp
-+	sub	$Xfer,sp,#64
-+	adr	$K_XX_XX,.LK_00_19
-+	bic	$Xfer,$Xfer,#15		@ align for 128-bit stores
-+
-+	ldmia	$ctx,{$a,$b,$c,$d,$e}	@ load context
-+	mov	sp,$Xfer		@ alloca
-+
-+	vld1.8		{@X[-4&7]-@X[-3&7]},[$inp]!	@ handles unaligned
-+	veor		$zero,$zero,$zero
-+	vld1.8		{@X[-2&7]-@X[-1&7]},[$inp]!
-+	vld1.32		{${K}\[]},[$K_XX_XX,:32]!	@ load K_00_19
-+	vrev32.8	@X[-4&7],@X[-4&7]		@ yes, even on
-+	vrev32.8	@X[-3&7],@X[-3&7]		@ big-endian...
-+	vrev32.8	@X[-2&7],@X[-2&7]
-+	vadd.i32	@X[0],@X[-4&7],$K
-+	vrev32.8	@X[-1&7],@X[-1&7]
-+	vadd.i32	@X[1],@X[-3&7],$K
-+	vst1.32		{@X[0]},[$Xfer,:128]!
-+	vadd.i32	@X[2],@X[-2&7],$K
-+	vst1.32		{@X[1]},[$Xfer,:128]!
-+	vst1.32		{@X[2]},[$Xfer,:128]!
-+	ldr		$Ki,[sp]			@ big RAW stall
-+
-+.Loop_neon:
-+___
-+	&Xupdate_16_31(\&body_00_19);
-+	&Xupdate_16_31(\&body_00_19);
-+	&Xupdate_16_31(\&body_00_19);
-+	&Xupdate_16_31(\&body_00_19);
-+	&Xupdate_32_79(\&body_00_19);
-+	&Xupdate_32_79(\&body_20_39);
-+	&Xupdate_32_79(\&body_20_39);
-+	&Xupdate_32_79(\&body_20_39);
-+	&Xupdate_32_79(\&body_20_39);
-+	&Xupdate_32_79(\&body_20_39);
-+	&Xupdate_32_79(\&body_40_59);
-+	&Xupdate_32_79(\&body_40_59);
-+	&Xupdate_32_79(\&body_40_59);
-+	&Xupdate_32_79(\&body_40_59);
-+	&Xupdate_32_79(\&body_40_59);
-+	&Xupdate_32_79(\&body_20_39);
-+	&Xuplast_80(\&body_20_39);
-+	&Xloop(\&body_20_39);
-+	&Xloop(\&body_20_39);
-+	&Xloop(\&body_20_39);
-+$code.=<<___;
-+	ldmia	$ctx,{$Ki,$t0,$t1,$Xfer}	@ accumulate context
-+	add	$a,$a,$Ki
-+	ldr	$Ki,[$ctx,#16]
-+	add	$b,$b,$t0
-+	add	$c,$c,$t1
-+	add	$d,$d,$Xfer
-+	it	eq
-+	moveq	sp,$saved_sp
-+	add	$e,$e,$Ki
-+	it	ne
-+	ldrne	$Ki,[sp]
-+	stmia	$ctx,{$a,$b,$c,$d,$e}
-+	itt	ne
-+	addne	$Xfer,sp,#3*16
-+	bne	.Loop_neon
-+
-+	@ vldmia	sp!,{d8-d15}
-+	ldmia	sp!,{r4-r12,pc}
-+.size	sha1_block_data_order_neon,.-sha1_block_data_order_neon
-+#endif
-+___
-+}}}
-+#####################################################################
-+# ARMv8 stuff
-+#
-+{{{
-+my ($ABCD,$E,$E0,$E1)=map("q$_",(0..3));
-+my @MSG=map("q$_",(4..7));
-+my @Kxx=map("q$_",(8..11));
-+my ($W0,$W1,$ABCD_SAVE)=map("q$_",(12..14));
-+
-+$code.=<<___;
-+#if __ARM_MAX_ARCH__>=7
-+
-+# if defined(__thumb2__)
-+#  define INST(a,b,c,d)	.byte	c,d|0xf,a,b
-+# else
-+#  define INST(a,b,c,d)	.byte	a,b,c,d|0x10
-+# endif
-+
-+.type	sha1_block_data_order_armv8,%function
-+.align	5
-+sha1_block_data_order_armv8:
-+.LARMv8:
-+	vstmdb	sp!,{d8-d15}		@ ABI specification says so
-+
-+	veor	$E,$E,$E
-+	adr	r3,.LK_00_19
-+	vld1.32	{$ABCD},[$ctx]!
-+	vld1.32	{$E\[0]},[$ctx]
-+	sub	$ctx,$ctx,#16
-+	vld1.32	{@Kxx[0]\[]},[r3,:32]!
-+	vld1.32	{@Kxx[1]\[]},[r3,:32]!
-+	vld1.32	{@Kxx[2]\[]},[r3,:32]!
-+	vld1.32	{@Kxx[3]\[]},[r3,:32]
-+
-+.Loop_v8:
-+	vld1.8		{@MSG[0]-@MSG[1]},[$inp]!
-+	vld1.8		{@MSG[2]-@MSG[3]},[$inp]!
-+	vrev32.8	@MSG[0],@MSG[0]
-+	vrev32.8	@MSG[1],@MSG[1]
-+
-+	vadd.i32	$W0,@Kxx[0],@MSG[0]
-+	vrev32.8	@MSG[2],@MSG[2]
-+	vmov		$ABCD_SAVE,$ABCD	@ offload
-+	subs		$len,$len,#1
-+
-+	vadd.i32	$W1,@Kxx[0],@MSG[1]
-+	vrev32.8	@MSG[3],@MSG[3]
-+	sha1h		$E1,$ABCD		@ 0
-+	sha1c		$ABCD,$E,$W0
-+	vadd.i32	$W0,@Kxx[$j],@MSG[2]
-+	sha1su0		@MSG[0],@MSG[1],@MSG[2]
-+___
-+for ($j=0,$i=1;$i<20-3;$i++) {
-+my $f=("c","p","m","p")[$i/5];
-+$code.=<<___;
-+	sha1h		$E0,$ABCD		@ $i
-+	sha1$f		$ABCD,$E1,$W1
-+	vadd.i32	$W1,@Kxx[$j],@MSG[3]
-+	sha1su1		@MSG[0],@MSG[3]
-+___
-+$code.=<<___ if ($i<20-4);
-+	sha1su0		@MSG[1],@MSG[2],@MSG[3]
-+___
-+	($E0,$E1)=($E1,$E0);	($W0,$W1)=($W1,$W0);
-+	push(@MSG,shift(@MSG));	$j++ if ((($i+3)%5)==0);
-+}
-+$code.=<<___;
-+	sha1h		$E0,$ABCD		@ $i
-+	sha1p		$ABCD,$E1,$W1
-+	vadd.i32	$W1,@Kxx[$j],@MSG[3]
-+
-+	sha1h		$E1,$ABCD		@ 18
-+	sha1p		$ABCD,$E0,$W0
-+
-+	sha1h		$E0,$ABCD		@ 19
-+	sha1p		$ABCD,$E1,$W1
-+
-+	vadd.i32	$E,$E,$E0
-+	vadd.i32	$ABCD,$ABCD,$ABCD_SAVE
-+	bne		.Loop_v8
-+
-+	vst1.32		{$ABCD},[$ctx]!
-+	vst1.32		{$E\[0]},[$ctx]
-+
-+	vldmia	sp!,{d8-d15}
-+	ret					@ bx lr
-+.size	sha1_block_data_order_armv8,.-sha1_block_data_order_armv8
-+#endif
-+___
-+}}}
-+$code.=<<___;
-+#if __ARM_MAX_ARCH__>=7
-+.comm	OPENSSL_armcap_P,4,4
-+#endif
-+___
-+
-+{   my  %opcode = (
-+	"sha1c"		=> 0xf2000c40,	"sha1p"		=> 0xf2100c40,
-+	"sha1m"		=> 0xf2200c40,	"sha1su0"	=> 0xf2300c40,
-+	"sha1h"		=> 0xf3b902c0,	"sha1su1"	=> 0xf3ba0380	);
-+
-+    sub unsha1 {
-+	my ($mnemonic,$arg)=@_;
-+
-+	if ($arg =~ m/q([0-9]+)(?:,\s*q([0-9]+))?,\s*q([0-9]+)/o) {
-+	    my $word = $opcode{$mnemonic}|(($1&7)<<13)|(($1&8)<<19)
-+					 |(($2&7)<<17)|(($2&8)<<4)
-+					 |(($3&7)<<1) |(($3&8)<<2);
-+	    # since ARMv7 instructions are always encoded little-endian.
-+	    # correct solution is to use .inst directive, but older
-+	    # assemblers don't implement it:-(
-+
-+	    # this fix-up provides Thumb encoding in conjunction with INST
-+	    $word &= ~0x10000000 if (($word & 0x0f000000) == 0x02000000);
-+	    sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s",
-+			$word&0xff,($word>>8)&0xff,
-+			($word>>16)&0xff,($word>>24)&0xff,
-+			$mnemonic,$arg;
-+	}
-+    }
-+}
-+
-+foreach (split($/,$code)) {
-+	s/{q([0-9]+)\[\]}/sprintf "{d%d[],d%d[]}",2*$1,2*$1+1/eo	or
-+	s/{q([0-9]+)\[0\]}/sprintf "{d%d[0]}",2*$1/eo;
-+
-+	s/\b(sha1\w+)\s+(q.*)/unsha1($1,$2)/geo;
-+
-+	s/\bret\b/bx	lr/o		or
-+	s/\bbx\s+lr\b/.word\t0xe12fff1e/o;	# make it possible to compile with -march=armv4
-+
-+	print $_,$/;
-+}
-+
-+close STDOUT; # enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-armv8.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-armv8.pl
-new file mode 100644
-index 0000000..84a00bf
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-armv8.pl
-@@ -0,0 +1,363 @@
-+#! /usr/bin/env perl
-+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# SHA1 for ARMv8.
-+#
-+# Performance in cycles per processed byte and improvement coefficient
-+# over code generated with "default" compiler:
-+#
-+#		hardware-assisted	software(*)
-+# Apple A7	2.31			4.13 (+14%)
-+# Cortex-A53	2.24			8.03 (+97%)
-+# Cortex-A57	2.35			7.88 (+74%)
-+# Denver	2.13			3.97 (+0%)(**)
-+# X-Gene				8.80 (+200%)
-+# Mongoose	2.05			6.50 (+160%)
-+#
-+# (*)	Software results are presented mostly for reference purposes.
-+# (**)	Keep in mind that Denver relies on binary translation, which
-+#	optimizes compiler output at run-time.
-+
-+$flavour = shift;
-+$output  = shift;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+($ctx,$inp,$num)=("x0","x1","x2");
-+@Xw=map("w$_",(3..17,19));
-+@Xx=map("x$_",(3..17,19));
-+@V=($A,$B,$C,$D,$E)=map("w$_",(20..24));
-+($t0,$t1,$t2,$K)=map("w$_",(25..28));
-+
-+
-+sub BODY_00_19 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=($i+2)&15;
-+
-+$code.=<<___ if ($i<15 && !($i&1));
-+	lsr	@Xx[$i+1],@Xx[$i],#32
-+___
-+$code.=<<___ if ($i<14 && !($i&1));
-+	ldr	@Xx[$i+2],[$inp,#`($i+2)*4-64`]
-+___
-+$code.=<<___ if ($i<14 && ($i&1));
-+#ifdef	__ARMEB__
-+	ror	@Xx[$i+1],@Xx[$i+1],#32
-+#else
-+	rev32	@Xx[$i+1],@Xx[$i+1]
-+#endif
-+___
-+$code.=<<___ if ($i<14);
-+	bic	$t0,$d,$b
-+	and	$t1,$c,$b
-+	ror	$t2,$a,#27
-+	add	$d,$d,$K		// future e+=K
-+	orr	$t0,$t0,$t1
-+	add	$e,$e,$t2		// e+=rot(a,5)
-+	ror	$b,$b,#2
-+	add	$d,$d,@Xw[($i+1)&15]	// future e+=X[i]
-+	add	$e,$e,$t0		// e+=F(b,c,d)
-+___
-+$code.=<<___ if ($i==19);
-+	movz	$K,#0xeba1
-+	movk	$K,#0x6ed9,lsl#16
-+___
-+$code.=<<___ if ($i>=14);
-+	 eor	@Xw[$j],@Xw[$j],@Xw[($j+2)&15]
-+	bic	$t0,$d,$b
-+	and	$t1,$c,$b
-+	ror	$t2,$a,#27
-+	 eor	@Xw[$j],@Xw[$j],@Xw[($j+8)&15]
-+	add	$d,$d,$K		// future e+=K
-+	orr	$t0,$t0,$t1
-+	add	$e,$e,$t2		// e+=rot(a,5)
-+	 eor	@Xw[$j],@Xw[$j],@Xw[($j+13)&15]
-+	ror	$b,$b,#2
-+	add	$d,$d,@Xw[($i+1)&15]	// future e+=X[i]
-+	add	$e,$e,$t0		// e+=F(b,c,d)
-+	 ror	@Xw[$j],@Xw[$j],#31
-+___
-+}
-+
-+sub BODY_40_59 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=($i+2)&15;
-+
-+$code.=<<___ if ($i==59);
-+	movz	$K,#0xc1d6
-+	movk	$K,#0xca62,lsl#16
-+___
-+$code.=<<___;
-+	orr	$t0,$b,$c
-+	and	$t1,$b,$c
-+	 eor	@Xw[$j],@Xw[$j],@Xw[($j+2)&15]
-+	ror	$t2,$a,#27
-+	and	$t0,$t0,$d
-+	add	$d,$d,$K		// future e+=K
-+	 eor	@Xw[$j],@Xw[$j],@Xw[($j+8)&15]
-+	add	$e,$e,$t2		// e+=rot(a,5)
-+	orr	$t0,$t0,$t1
-+	ror	$b,$b,#2
-+	 eor	@Xw[$j],@Xw[$j],@Xw[($j+13)&15]
-+	add	$d,$d,@Xw[($i+1)&15]	// future e+=X[i]
-+	add	$e,$e,$t0		// e+=F(b,c,d)
-+	 ror	@Xw[$j],@Xw[$j],#31
-+___
-+}
-+
-+sub BODY_20_39 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=($i+2)&15;
-+
-+$code.=<<___ if ($i==39);
-+	movz	$K,#0xbcdc
-+	movk	$K,#0x8f1b,lsl#16
-+___
-+$code.=<<___ if ($i<78);
-+	 eor	@Xw[$j],@Xw[$j],@Xw[($j+2)&15]
-+	eor	$t0,$d,$b
-+	ror	$t2,$a,#27
-+	add	$d,$d,$K		// future e+=K
-+	 eor	@Xw[$j],@Xw[$j],@Xw[($j+8)&15]
-+	eor	$t0,$t0,$c
-+	add	$e,$e,$t2		// e+=rot(a,5)
-+	ror	$b,$b,#2
-+	 eor	@Xw[$j],@Xw[$j],@Xw[($j+13)&15]
-+	add	$d,$d,@Xw[($i+1)&15]	// future e+=X[i]
-+	add	$e,$e,$t0		// e+=F(b,c,d)
-+	 ror	@Xw[$j],@Xw[$j],#31
-+___
-+$code.=<<___ if ($i==78);
-+	ldp	@Xw[1],@Xw[2],[$ctx]
-+	eor	$t0,$d,$b
-+	ror	$t2,$a,#27
-+	add	$d,$d,$K		// future e+=K
-+	eor	$t0,$t0,$c
-+	add	$e,$e,$t2		// e+=rot(a,5)
-+	ror	$b,$b,#2
-+	add	$d,$d,@Xw[($i+1)&15]	// future e+=X[i]
-+	add	$e,$e,$t0		// e+=F(b,c,d)
-+___
-+$code.=<<___ if ($i==79);
-+	ldp	@Xw[3],@Xw[4],[$ctx,#8]
-+	eor	$t0,$d,$b
-+	ror	$t2,$a,#27
-+	eor	$t0,$t0,$c
-+	add	$e,$e,$t2		// e+=rot(a,5)
-+	ror	$b,$b,#2
-+	ldr	@Xw[5],[$ctx,#16]
-+	add	$e,$e,$t0		// e+=F(b,c,d)
-+___
-+}
-+
-+$code.=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+
-+.extern	OPENSSL_armcap_P
-+.globl	sha1_block_data_order
-+.type	sha1_block_data_order,%function
-+.align	6
-+sha1_block_data_order:
-+#ifdef	__ILP32__
-+	ldrsw	x16,.LOPENSSL_armcap_P
-+#else
-+	ldr	x16,.LOPENSSL_armcap_P
-+#endif
-+	adr	x17,.LOPENSSL_armcap_P
-+	add	x16,x16,x17
-+	ldr	w16,[x16]
-+	tst	w16,#ARMV8_SHA1
-+	b.ne	.Lv8_entry
-+
-+	stp	x29,x30,[sp,#-96]!
-+	add	x29,sp,#0
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	stp	x23,x24,[sp,#48]
-+	stp	x25,x26,[sp,#64]
-+	stp	x27,x28,[sp,#80]
-+
-+	ldp	$A,$B,[$ctx]
-+	ldp	$C,$D,[$ctx,#8]
-+	ldr	$E,[$ctx,#16]
-+
-+.Loop:
-+	ldr	@Xx[0],[$inp],#64
-+	movz	$K,#0x7999
-+	sub	$num,$num,#1
-+	movk	$K,#0x5a82,lsl#16
-+#ifdef	__ARMEB__
-+	ror	$Xx[0],@Xx[0],#32
-+#else
-+	rev32	@Xx[0],@Xx[0]
-+#endif
-+	add	$E,$E,$K		// warm it up
-+	add	$E,$E,@Xw[0]
-+___
-+for($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
-+for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	add	$B,$B,@Xw[2]
-+	add	$C,$C,@Xw[3]
-+	add	$A,$A,@Xw[1]
-+	add	$D,$D,@Xw[4]
-+	add	$E,$E,@Xw[5]
-+	stp	$A,$B,[$ctx]
-+	stp	$C,$D,[$ctx,#8]
-+	str	$E,[$ctx,#16]
-+	cbnz	$num,.Loop
-+
-+	ldp	x19,x20,[sp,#16]
-+	ldp	x21,x22,[sp,#32]
-+	ldp	x23,x24,[sp,#48]
-+	ldp	x25,x26,[sp,#64]
-+	ldp	x27,x28,[sp,#80]
-+	ldr	x29,[sp],#96
-+	ret
-+.size	sha1_block_data_order,.-sha1_block_data_order
-+___
-+{{{
-+my ($ABCD,$E,$E0,$E1)=map("v$_.16b",(0..3));
-+my @MSG=map("v$_.16b",(4..7));
-+my @Kxx=map("v$_.4s",(16..19));
-+my ($W0,$W1)=("v20.4s","v21.4s");
-+my $ABCD_SAVE="v22.16b";
-+
-+$code.=<<___;
-+.type	sha1_block_armv8,%function
-+.align	6
-+sha1_block_armv8:
-+.Lv8_entry:
-+	stp	x29,x30,[sp,#-16]!
-+	add	x29,sp,#0
-+
-+	adr	x4,.Lconst
-+	eor	$E,$E,$E
-+	ld1.32	{$ABCD},[$ctx],#16
-+	ld1.32	{$E}[0],[$ctx]
-+	sub	$ctx,$ctx,#16
-+	ld1.32	{@Kxx[0]-@Kxx[3]},[x4]
-+
-+.Loop_hw:
-+	ld1	{@MSG[0]-@MSG[3]},[$inp],#64
-+	sub	$num,$num,#1
-+	rev32	@MSG[0],@MSG[0]
-+	rev32	@MSG[1],@MSG[1]
-+
-+	add.i32	$W0,@Kxx[0],@MSG[0]
-+	rev32	@MSG[2],@MSG[2]
-+	orr	$ABCD_SAVE,$ABCD,$ABCD	// offload
-+
-+	add.i32	$W1,@Kxx[0],@MSG[1]
-+	rev32	@MSG[3],@MSG[3]
-+	sha1h	$E1,$ABCD
-+	sha1c	$ABCD,$E,$W0		// 0
-+	add.i32	$W0,@Kxx[$j],@MSG[2]
-+	sha1su0	@MSG[0],@MSG[1],@MSG[2]
-+___
-+for ($j=0,$i=1;$i<20-3;$i++) {
-+my $f=("c","p","m","p")[$i/5];
-+$code.=<<___;
-+	sha1h	$E0,$ABCD		// $i
-+	sha1$f	$ABCD,$E1,$W1
-+	add.i32	$W1,@Kxx[$j],@MSG[3]
-+	sha1su1	@MSG[0],@MSG[3]
-+___
-+$code.=<<___ if ($i<20-4);
-+	sha1su0	@MSG[1],@MSG[2],@MSG[3]
-+___
-+	($E0,$E1)=($E1,$E0);		($W0,$W1)=($W1,$W0);
-+	push(@MSG,shift(@MSG));		$j++ if ((($i+3)%5)==0);
-+}
-+$code.=<<___;
-+	sha1h	$E0,$ABCD		// $i
-+	sha1p	$ABCD,$E1,$W1
-+	add.i32	$W1,@Kxx[$j],@MSG[3]
-+
-+	sha1h	$E1,$ABCD		// 18
-+	sha1p	$ABCD,$E0,$W0
-+
-+	sha1h	$E0,$ABCD		// 19
-+	sha1p	$ABCD,$E1,$W1
-+
-+	add.i32	$E,$E,$E0
-+	add.i32	$ABCD,$ABCD,$ABCD_SAVE
-+
-+	cbnz	$num,.Loop_hw
-+
-+	st1.32	{$ABCD},[$ctx],#16
-+	st1.32	{$E}[0],[$ctx]
-+
-+	ldr	x29,[sp],#16
-+	ret
-+.size	sha1_block_armv8,.-sha1_block_armv8
-+.align	6
-+.Lconst:
-+.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	//K_00_19
-+.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	//K_20_39
-+.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	//K_40_59
-+.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	//K_60_79
-+.LOPENSSL_armcap_P:
-+#ifdef	__ILP32__
-+.long	OPENSSL_armcap_P-.
-+#else
-+.quad	OPENSSL_armcap_P-.
-+#endif
-+.asciz	"SHA1 block transform for ARMv8, CRYPTOGAMS by "
-+.align	2
-+.comm	OPENSSL_armcap_P,4,4
-+___
-+}}}
-+
-+{   my	%opcode = (
-+	"sha1c"		=> 0x5e000000,	"sha1p"		=> 0x5e001000,
-+	"sha1m"		=> 0x5e002000,	"sha1su0"	=> 0x5e003000,
-+	"sha1h"		=> 0x5e280800,	"sha1su1"	=> 0x5e281800	);
-+
-+    sub unsha1 {
-+	my ($mnemonic,$arg)=@_;
-+
-+	$arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv]([0-9]+))?/o
-+	&&
-+	sprintf ".inst\t0x%08x\t//%s %s",
-+			$opcode{$mnemonic}|$1|($2<<5)|($3<<16),
-+			$mnemonic,$arg;
-+    }
-+}
-+
-+foreach(split("\n",$code)) {
-+
-+	s/\`([^\`]*)\`/eval($1)/geo;
-+
-+	s/\b(sha1\w+)\s+([qv].*)/unsha1($1,$2)/geo;
-+
-+	s/\.\w?32\b//o		and s/\.16b/\.4s/go;
-+	m/(ld|st)1[^\[]+\[0\]/o	and s/\.4s/\.s/go;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-c64xplus.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-c64xplus.pl
-new file mode 100644
-index 0000000..4db2bcb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-c64xplus.pl
-@@ -0,0 +1,337 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# SHA1 for C64x+.
-+#
-+# November 2011
-+#
-+# If compared to compiler-generated code with similar characteristics,
-+# i.e. compiled with OPENSSL_SMALL_FOOTPRINT and utilizing SPLOOPs,
-+# this implementation is 25% smaller and >2x faster. In absolute terms
-+# performance is (quite impressive) ~6.5 cycles per processed byte.
-+# Fully unrolled assembler would be ~5x larger and is likely to be
-+# ~15% faster. It would be free from references to intermediate ring
-+# buffer, but put more pressure on L1P [both because the code would be
-+# larger and won't be using SPLOOP buffer]. There are no plans to
-+# realize fully unrolled variant though...
-+#
-+# !!! Note that this module uses AMR, which means that all interrupt
-+# service routines are expected to preserve it and for own well-being
-+# zero it upon entry.
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+($CTX,$INP,$NUM) = ("A4","B4","A6");		# arguments
-+
-+($A,$B,$C,$D,$E, $Arot,$F,$F0,$T,$K) = map("A$_",(16..20, 21..25));
-+($X0,$X2,$X8,$X13) = ("A26","B26","A27","B27");
-+($TX0,$TX1,$TX2,$TX3) = map("B$_",(28..31));
-+($XPA,$XPB) = ("A5","B5");			# X circular buffer
-+($Actx,$Bctx,$Cctx,$Dctx,$Ectx) = map("A$_",(3,6..9));	# zaps $NUM
-+
-+$code=<<___;
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.asg	sha1_block_data_order,_sha1_block_data_order
-+	.endif
-+
-+	.asg	B3,RA
-+	.asg	A15,FP
-+	.asg	B15,SP
-+
-+	.if	.BIG_ENDIAN
-+	.asg	MV,SWAP2
-+	.asg	MV,SWAP4
-+	.endif
-+
-+	.global	_sha1_block_data_order
-+_sha1_block_data_order:
-+	.asmfunc stack_usage(64)
-+	MV	$NUM,A0			; reassign $NUM
-+||	MVK	-64,B0
-+  [!A0]	BNOP	RA			; if ($NUM==0) return;
-+|| [A0]	STW	FP,*SP--[16]		; save frame pointer and alloca(64)
-+|| [A0]	MV	SP,FP
-+   [A0]	LDW	*${CTX}[0],$A		; load A-E...
-+|| [A0]	AND	B0,SP,SP		; align stack at 64 bytes
-+   [A0]	LDW	*${CTX}[1],$B
-+|| [A0]	SUBAW	SP,2,SP			; reserve two words above buffer
-+   [A0]	LDW	*${CTX}[2],$C
-+|| [A0]	MVK	0x00404,B0
-+   [A0]	LDW	*${CTX}[3],$D
-+|| [A0]	MVKH	0x50000,B0		; 0x050404, 64 bytes for $XP[AB]
-+   [A0]	LDW	*${CTX}[4],$E
-+|| [A0]	MVC	B0,AMR			; setup circular addressing
-+	LDNW	*${INP}++,$TX1		; pre-fetch input
-+	NOP	1
-+
-+loop?:
-+	MVK	0x00007999,$K
-+||	ADDAW	SP,2,$XPA
-+||	SUB	A0,1,A0
-+||	MVK	13,B0
-+	MVKH	0x5a820000,$K		; K_00_19
-+||	ADDAW	SP,2,$XPB
-+||	MV	$A,$Actx
-+||	MV	$B,$Bctx
-+;;==================================================
-+	SPLOOPD	5			; BODY_00_13
-+||	MV	$C,$Cctx
-+||	MV	$D,$Dctx
-+||	MV	$E,$Ectx
-+||	MVC	B0,ILC
-+
-+	ROTL	$A,5,$Arot
-+||	AND	$C,$B,$F
-+||	ANDN	$D,$B,$F0
-+||	ADD	$K,$E,$T		; T=E+K
-+
-+	XOR	$F0,$F,$F		; F_00_19(B,C,D)
-+||	MV	$D,$E			; E=D
-+||	MV	$C,$D			; D=C
-+||	SWAP2	$TX1,$TX2
-+||	LDNW	*${INP}++,$TX1
-+
-+	ADD	$F,$T,$T		; T+=F_00_19(B,C,D)
-+||	ROTL	$B,30,$C		; C=ROL(B,30)
-+||	SWAP4	$TX2,$TX3		; byte swap
-+
-+	ADD	$Arot,$T,$T		; T+=ROL(A,5)
-+||	MV	$A,$B			; B=A
-+
-+	ADD	$TX3,$T,$A		; A=T+Xi
-+||	STW	$TX3,*${XPB}++
-+	SPKERNEL
-+;;==================================================
-+	ROTL	$A,5,$Arot		; BODY_14
-+||	AND	$C,$B,$F
-+||	ANDN	$D,$B,$F0
-+||	ADD	$K,$E,$T		; T=E+K
-+
-+	XOR	$F0,$F,$F		; F_00_19(B,C,D)
-+||	MV	$D,$E			; E=D
-+||	MV	$C,$D			; D=C
-+||	SWAP2	$TX1,$TX2
-+||	LDNW	*${INP}++,$TX1
-+
-+	ADD	$F,$T,$T		; T+=F_00_19(B,C,D)
-+||	ROTL	$B,30,$C		; C=ROL(B,30)
-+||	SWAP4	$TX2,$TX2		; byte swap
-+||	LDW	*${XPA}++,$X0		; fetches from X ring buffer are
-+||	LDW	*${XPB}[4],$X2		; 2 iterations ahead
-+
-+	ADD	$Arot,$T,$T		; T+=ROL(A,5)
-+||	MV	$A,$B			; B=A
-+||	LDW	*${XPA}[7],$X8
-+||	MV	$TX3,$X13		; ||	LDW	*${XPB}[15],$X13
-+||	MV	$TX2,$TX3
-+
-+	ADD	$TX2,$T,$A		; A=T+Xi
-+||	STW	$TX2,*${XPB}++
-+;;==================================================
-+	ROTL	$A,5,$Arot		; BODY_15
-+||	AND	$C,$B,$F
-+||	ANDN	$D,$B,$F0
-+||	ADD	$K,$E,$T		; T=E+K
-+
-+	XOR	$F0,$F,$F		; F_00_19(B,C,D)
-+||	MV	$D,$E			; E=D
-+||	MV	$C,$D			; D=C
-+||	SWAP2	$TX1,$TX2
-+
-+	ADD	$F,$T,$T		; T+=F_00_19(B,C,D)
-+||	ROTL	$B,30,$C		; C=ROL(B,30)
-+||	SWAP4	$TX2,$TX2		; byte swap
-+||	XOR	$X0,$X2,$TX0		; Xupdate XORs are 1 iteration ahead
-+||	LDW	*${XPA}++,$X0
-+||	LDW	*${XPB}[4],$X2
-+
-+	ADD	$Arot,$T,$T		; T+=ROL(A,5)
-+||	MV	$A,$B			; B=A
-+||	XOR	$X8,$X13,$TX1
-+||	LDW	*${XPA}[7],$X8
-+||	MV	$TX3,$X13		; ||	LDW	*${XPB}[15],$X13
-+||	MV	$TX2,$TX3
-+
-+	ADD	$TX2,$T,$A		; A=T+Xi
-+||	STW	$TX2,*${XPB}++
-+||	XOR	$TX0,$TX1,$TX1
-+||	MVK	3,B0
-+;;==================================================
-+	SPLOOPD	5			; BODY_16_19
-+||	MVC	B0,ILC
-+
-+	ROTL	$A,5,$Arot
-+||	AND	$C,$B,$F
-+||	ANDN	$D,$B,$F0
-+||	ADD	$K,$E,$T		; T=E+K
-+||	ROTL	$TX1,1,$TX2		; Xupdate output
-+
-+	XOR	$F0,$F,$F		; F_00_19(B,C,D)
-+||	MV	$D,$E			; E=D
-+||	MV	$C,$D			; D=C
-+
-+	ADD	$F,$T,$T		; T+=F_00_19(B,C,D)
-+||	ROTL	$B,30,$C		; C=ROL(B,30)
-+||	XOR	$X0,$X2,$TX0
-+||	LDW	*${XPA}++,$X0
-+||	LDW	*${XPB}[4],$X2
-+
-+	ADD	$Arot,$T,$T		; T+=ROL(A,5)
-+||	MV	$A,$B			; B=A
-+||	XOR	$X8,$X13,$TX1
-+||	LDW	*${XPA}[7],$X8
-+||	MV	$TX3,$X13		; ||	LDW	*${XPB}[15],$X13
-+||	MV	$TX2,$TX3
-+
-+	ADD	$TX2,$T,$A		; A=T+Xi
-+||	STW	$TX2,*${XPB}++
-+||	XOR	$TX0,$TX1,$TX1
-+	SPKERNEL
-+
-+	MVK	0xffffeba1,$K
-+||	MVK	19,B0
-+	MVKH	0x6ed90000,$K		; K_20_39
-+___
-+sub BODY_20_39 {
-+$code.=<<___;
-+;;==================================================
-+	SPLOOPD	5			; BODY_20_39
-+||	MVC	B0,ILC
-+
-+	ROTL	$A,5,$Arot
-+||	XOR	$B,$C,$F
-+||	ADD	$K,$E,$T		; T=E+K
-+||	ROTL	$TX1,1,$TX2		; Xupdate output
-+
-+	XOR	$D,$F,$F		; F_20_39(B,C,D)
-+||	MV	$D,$E			; E=D
-+||	MV	$C,$D			; D=C
-+
-+	ADD	$F,$T,$T		; T+=F_20_39(B,C,D)
-+||	ROTL	$B,30,$C		; C=ROL(B,30)
-+||	XOR	$X0,$X2,$TX0
-+||	LDW	*${XPA}++,$X0
-+||	LDW	*${XPB}[4],$X2
-+
-+	ADD	$Arot,$T,$T		; T+=ROL(A,5)
-+||	MV	$A,$B			; B=A
-+||	XOR	$X8,$X13,$TX1
-+||	LDW	*${XPA}[7],$X8
-+||	MV	$TX3,$X13		; ||	LDW	*${XPB}[15],$X13
-+||	MV	$TX2,$TX3
-+
-+	ADD	$TX2,$T,$A		; A=T+Xi
-+||	STW	$TX2,*${XPB}++		; last one is redundant
-+||	XOR	$TX0,$TX1,$TX1
-+	SPKERNEL
-+___
-+$code.=<<___ if (!shift);
-+	MVK	0xffffbcdc,$K
-+	MVKH	0x8f1b0000,$K		; K_40_59
-+___
-+}	&BODY_20_39();
-+$code.=<<___;
-+;;==================================================
-+	SPLOOPD	5			; BODY_40_59
-+||	MVC	B0,ILC
-+||	AND	$B,$C,$F
-+||	AND	$B,$D,$F0
-+
-+	ROTL	$A,5,$Arot
-+||	XOR	$F0,$F,$F
-+||	AND	$C,$D,$F0
-+||	ADD	$K,$E,$T		; T=E+K
-+||	ROTL	$TX1,1,$TX2		; Xupdate output
-+
-+	XOR	$F0,$F,$F		; F_40_59(B,C,D)
-+||	MV	$D,$E			; E=D
-+||	MV	$C,$D			; D=C
-+
-+	ADD	$F,$T,$T		; T+=F_40_59(B,C,D)
-+||	ROTL	$B,30,$C		; C=ROL(B,30)
-+||	XOR	$X0,$X2,$TX0
-+||	LDW	*${XPA}++,$X0
-+||	LDW	*${XPB}[4],$X2
-+
-+	ADD	$Arot,$T,$T		; T+=ROL(A,5)
-+||	MV	$A,$B			; B=A
-+||	XOR	$X8,$X13,$TX1
-+||	LDW	*${XPA}[7],$X8
-+||	MV	$TX3,$X13		; ||	LDW	*${XPB}[15],$X13
-+||	MV	$TX2,$TX3
-+
-+	ADD	$TX2,$T,$A		; A=T+Xi
-+||	STW	$TX2,*${XPB}++
-+||	XOR	$TX0,$TX1,$TX1
-+||	AND	$B,$C,$F
-+||	AND	$B,$D,$F0
-+	SPKERNEL
-+
-+	MVK	0xffffc1d6,$K
-+||	MVK	18,B0
-+	MVKH	0xca620000,$K		; K_60_79
-+___
-+	&BODY_20_39(-1);		# BODY_60_78
-+$code.=<<___;
-+;;==================================================
-+   [A0]	B	loop?
-+||	ROTL	$A,5,$Arot		; BODY_79
-+||	XOR	$B,$C,$F
-+||	ROTL	$TX1,1,$TX2		; Xupdate output
-+
-+   [A0]	LDNW	*${INP}++,$TX1		; pre-fetch input
-+||	ADD	$K,$E,$T		; T=E+K
-+||	XOR	$D,$F,$F		; F_20_39(B,C,D)
-+
-+	ADD	$F,$T,$T		; T+=F_20_39(B,C,D)
-+||	ADD	$Ectx,$D,$E		; E=D,E+=Ectx
-+||	ADD	$Dctx,$C,$D		; D=C,D+=Dctx
-+||	ROTL	$B,30,$C		; C=ROL(B,30)
-+
-+	ADD	$Arot,$T,$T		; T+=ROL(A,5)
-+||	ADD	$Bctx,$A,$B		; B=A,B+=Bctx
-+
-+	ADD	$TX2,$T,$A		; A=T+Xi
-+
-+	ADD	$Actx,$A,$A		; A+=Actx
-+||	ADD	$Cctx,$C,$C		; C+=Cctx
-+;; end of loop?
-+
-+	BNOP	RA			; return
-+||	MV	FP,SP			; restore stack pointer
-+||	LDW	*FP[0],FP		; restore frame pointer
-+	STW	$A,*${CTX}[0]		; emit A-E...
-+||	MVK	0,B0
-+	STW	$B,*${CTX}[1]
-+||	MVC	B0,AMR			; clear AMR
-+	STW	$C,*${CTX}[2]
-+	STW	$D,*${CTX}[3]
-+	STW	$E,*${CTX}[4]
-+	.endasmfunc
-+
-+	.sect	.const
-+	.cstring "SHA1 block transform for C64x+, CRYPTOGAMS by "
-+	.align	4
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-ia64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-ia64.pl
-new file mode 100644
-index 0000000..dec21f9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-ia64.pl
-@@ -0,0 +1,314 @@
-+#! /usr/bin/env perl
-+# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# Eternal question is what's wrong with compiler generated code? The
-+# trick is that it's possible to reduce the number of shifts required
-+# to perform rotations by maintaining copy of 32-bit value in upper
-+# bits of 64-bit register. Just follow mux2 and shrp instructions...
-+# Performance under big-endian OS such as HP-UX is 179MBps*1GHz, which
-+# is >50% better than HP C and >2x better than gcc.
-+
-+$output = pop;
-+
-+$code=<<___;
-+.ident  \"sha1-ia64.s, version 1.3\"
-+.ident  \"IA-64 ISA artwork by Andy Polyakov \"
-+.explicit
-+
-+___
-+
-+
-+if ($^O eq "hpux") {
-+    $ADDP="addp4";
-+    for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
-+} else { $ADDP="add"; }
-+
-+#$human=1;
-+if ($human) {	# useful for visual code auditing...
-+	($A,$B,$C,$D,$E)   = ("A","B","C","D","E");
-+	($h0,$h1,$h2,$h3,$h4) = ("h0","h1","h2","h3","h4");
-+	($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
-+	    (	"K_00_19","K_20_39","K_40_59","K_60_79"	);
-+	@X= (	"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7",
-+		"X8", "X9","X10","X11","X12","X13","X14","X15"	);
-+}
-+else {
-+	($A,$B,$C,$D,$E)   =    ("loc0","loc1","loc2","loc3","loc4");
-+	($h0,$h1,$h2,$h3,$h4) = ("loc5","loc6","loc7","loc8","loc9");
-+	($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
-+	    (	"r14", "r15", "loc10", "loc11"	);
-+	@X= (	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
-+		"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"	);
-+}
-+
-+sub BODY_00_15 {
-+local	*code=shift;
-+my	($i,$a,$b,$c,$d,$e)=@_;
-+my	$j=$i+1;
-+my	$Xn=@X[$j%16];
-+
-+$code.=<<___ if ($i==0);
-+{ .mmi;	ld1	$X[$i]=[inp],2		    // MSB
-+	ld1	tmp2=[tmp3],2		};;
-+{ .mmi;	ld1	tmp0=[inp],2
-+	ld1	tmp4=[tmp3],2		    // LSB
-+	dep	$X[$i]=$X[$i],tmp2,8,8	};;
-+___
-+if ($i<15) {
-+	$code.=<<___;
-+{ .mmi;	ld1	$Xn=[inp],2		    // forward Xload
-+	nop.m	0x0
-+	dep	tmp1=tmp0,tmp4,8,8	};;
-+{ .mmi;	ld1	tmp2=[tmp3],2		    // forward Xload
-+	and	tmp4=$c,$b
-+	dep	$X[$i]=$X[$i],tmp1,16,16} //;;
-+{ .mmi;	add	$e=$e,$K_00_19		    // e+=K_00_19
-+	andcm	tmp1=$d,$b
-+	dep.z	tmp5=$a,5,27		};; // a<<5
-+{ .mmi;	add	$e=$e,$X[$i]		    // e+=Xload
-+	or	tmp4=tmp4,tmp1		    // F_00_19(b,c,d)=(b&c)|(~b&d)
-+	extr.u	tmp1=$a,27,5		};; // a>>27
-+{ .mmi;	ld1	tmp0=[inp],2		    // forward Xload
-+	add	$e=$e,tmp4		    // e+=F_00_19(b,c,d)
-+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
-+{ .mmi;	ld1	tmp4=[tmp3],2		    // forward Xload
-+	or	tmp5=tmp1,tmp5		    // ROTATE(a,5)
-+	mux2	tmp6=$a,0x44		};; // see b in next iteration
-+{ .mii;	add	$e=$e,tmp5		    // e+=ROTATE(a,5)
-+	dep	$Xn=$Xn,tmp2,8,8	    // forward Xload
-+	mux2	$X[$i]=$X[$i],0x44	} //;;
-+
-+___
-+	}
-+else	{
-+	$code.=<<___;
-+{ .mii;	and	tmp3=$c,$b
-+	dep	tmp1=tmp0,tmp4,8,8;;
-+	dep	$X[$i]=$X[$i],tmp1,16,16} //;;
-+{ .mmi;	add	$e=$e,$K_00_19		    // e+=K_00_19
-+	andcm	tmp1=$d,$b
-+	dep.z	tmp5=$a,5,27		};; // a<<5
-+{ .mmi;	add	$e=$e,$X[$i]		    // e+=Xupdate
-+	or	tmp4=tmp3,tmp1		    // F_00_19(b,c,d)=(b&c)|(~b&d)
-+	extr.u	tmp1=$a,27,5		}   // a>>27
-+{ .mmi;	xor	$Xn=$Xn,$X[($j+2)%16]	    // forward Xupdate
-+	xor	tmp3=$X[($j+8)%16],$X[($j+13)%16] // forward Xupdate
-+	nop.i	0			};;
-+{ .mmi;	add	$e=$e,tmp4		    // e+=F_00_19(b,c,d)
-+	xor	$Xn=$Xn,tmp3		    // forward Xupdate
-+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
-+{ .mmi; or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
-+	mux2	tmp6=$a,0x44		};; // see b in next iteration
-+{ .mii;	add	$e=$e,tmp1		    // e+=ROTATE(a,5)
-+	shrp	$Xn=$Xn,$Xn,31		    // ROTATE(x[0]^x[2]^x[8]^x[13],1)
-+	mux2	$X[$i]=$X[$i],0x44	};;
-+
-+___
-+	}
-+}
-+
-+sub BODY_16_19 {
-+local	*code=shift;
-+my	($i,$a,$b,$c,$d,$e)=@_;
-+my	$j=$i+1;
-+my	$Xn=@X[$j%16];
-+
-+$code.=<<___;
-+{ .mib;	add	$e=$e,$K_00_19		    // e+=K_00_19
-+	dep.z	tmp5=$a,5,27		}   // a<<5
-+{ .mib;	andcm	tmp1=$d,$b
-+	and	tmp0=$c,$b		};;
-+{ .mmi;	add	$e=$e,$X[$i%16]		    // e+=Xupdate
-+	or	tmp0=tmp0,tmp1		    // F_00_19(b,c,d)=(b&c)|(~b&d)
-+	extr.u	tmp1=$a,27,5		}   // a>>27
-+{ .mmi;	xor	$Xn=$Xn,$X[($j+2)%16]	    // forward Xupdate
-+	xor	tmp3=$X[($j+8)%16],$X[($j+13)%16]	// forward Xupdate
-+	nop.i	0			};;
-+{ .mmi;	add	$e=$e,tmp0		    // f+=F_00_19(b,c,d)
-+	xor	$Xn=$Xn,tmp3		    // forward Xupdate
-+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
-+{ .mmi;	or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
-+	mux2	tmp6=$a,0x44		};; // see b in next iteration
-+{ .mii;	add	$e=$e,tmp1		    // e+=ROTATE(a,5)
-+	shrp	$Xn=$Xn,$Xn,31		    // ROTATE(x[0]^x[2]^x[8]^x[13],1)
-+	nop.i	0			};;
-+
-+___
-+}
-+
-+sub BODY_20_39 {
-+local	*code=shift;
-+my	($i,$a,$b,$c,$d,$e,$Konst)=@_;
-+	$Konst = $K_20_39 if (!defined($Konst));
-+my	$j=$i+1;
-+my	$Xn=@X[$j%16];
-+
-+if ($i<79) {
-+$code.=<<___;
-+{ .mib;	add	$e=$e,$Konst		    // e+=K_XX_XX
-+	dep.z	tmp5=$a,5,27		}   // a<<5
-+{ .mib;	xor	tmp0=$c,$b
-+	xor	$Xn=$Xn,$X[($j+2)%16]	};; // forward Xupdate
-+{ .mib;	add	$e=$e,$X[$i%16]		    // e+=Xupdate
-+	extr.u	tmp1=$a,27,5		}   // a>>27
-+{ .mib;	xor	tmp0=tmp0,$d		    // F_20_39(b,c,d)=b^c^d
-+	xor	$Xn=$Xn,$X[($j+8)%16]	};; // forward Xupdate
-+{ .mmi;	add	$e=$e,tmp0		    // e+=F_20_39(b,c,d)
-+	xor	$Xn=$Xn,$X[($j+13)%16]	    // forward Xupdate
-+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
-+{ .mmi;	or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
-+	mux2	tmp6=$a,0x44		};; // see b in next iteration
-+{ .mii;	add	$e=$e,tmp1		    // e+=ROTATE(a,5)
-+	shrp	$Xn=$Xn,$Xn,31		    // ROTATE(x[0]^x[2]^x[8]^x[13],1)
-+	nop.i	0			};;
-+
-+___
-+}
-+else {
-+$code.=<<___;
-+{ .mib;	add	$e=$e,$Konst		    // e+=K_60_79
-+	dep.z	tmp5=$a,5,27		}   // a<<5
-+{ .mib;	xor	tmp0=$c,$b
-+	add	$h1=$h1,$a		};; // wrap up
-+{ .mib;	add	$e=$e,$X[$i%16]		    // e+=Xupdate
-+	extr.u	tmp1=$a,27,5		}   // a>>27
-+{ .mib;	xor	tmp0=tmp0,$d		    // F_20_39(b,c,d)=b^c^d
-+	add	$h3=$h3,$c		};; // wrap up
-+{ .mmi;	add	$e=$e,tmp0		    // e+=F_20_39(b,c,d)
-+	or	tmp1=tmp1,tmp5		    // ROTATE(a,5)
-+	shrp	$b=tmp6,tmp6,2		};; // b=ROTATE(b,30) ;;?
-+{ .mmi;	add	$e=$e,tmp1		    // e+=ROTATE(a,5)
-+	add	tmp3=1,inp		    // used in unaligned codepath
-+	add	$h4=$h4,$d		};; // wrap up
-+
-+___
-+}
-+}
-+
-+sub BODY_40_59 {
-+local	*code=shift;
-+my	($i,$a,$b,$c,$d,$e)=@_;
-+my	$j=$i+1;
-+my	$Xn=@X[$j%16];
-+
-+$code.=<<___;
-+{ .mib;	add	$e=$e,$K_40_59		    // e+=K_40_59
-+	dep.z	tmp5=$a,5,27		}   // a<<5
-+{ .mib;	and	tmp1=$c,$d
-+	xor	tmp0=$c,$d		};;
-+{ .mmi;	add	$e=$e,$X[$i%16]		    // e+=Xupdate
-+	add	tmp5=tmp5,tmp1		    // a<<5+(c&d)
-+	extr.u	tmp1=$a,27,5		}   // a>>27
-+{ .mmi;	and	tmp0=tmp0,$b
-+	xor	$Xn=$Xn,$X[($j+2)%16]	    // forward Xupdate
-+	xor	tmp3=$X[($j+8)%16],$X[($j+13)%16] };;	// forward Xupdate
-+{ .mmi;	add	$e=$e,tmp0		    // e+=b&(c^d)
-+	add	tmp5=tmp5,tmp1		    // ROTATE(a,5)+(c&d)
-+	shrp	$b=tmp6,tmp6,2		}   // b=ROTATE(b,30)
-+{ .mmi;	xor	$Xn=$Xn,tmp3
-+	mux2	tmp6=$a,0x44		};; // see b in next iteration
-+{ .mii;	add	$e=$e,tmp5		    // e+=ROTATE(a,5)+(c&d)
-+	shrp	$Xn=$Xn,$Xn,31		    // ROTATE(x[0]^x[2]^x[8]^x[13],1)
-+	nop.i	0x0			};;
-+
-+___
-+}
-+sub BODY_60_79	{ &BODY_20_39(@_,$K_60_79); }
-+
-+$code.=<<___;
-+.text
-+
-+tmp0=r8;
-+tmp1=r9;
-+tmp2=r10;
-+tmp3=r11;
-+ctx=r32;	// in0
-+inp=r33;	// in1
-+
-+// void sha1_block_data_order(SHA_CTX *c,const void *p,size_t num);
-+.global	sha1_block_data_order#
-+.proc	sha1_block_data_order#
-+.align	32
-+sha1_block_data_order:
-+	.prologue
-+{ .mmi;	alloc	tmp1=ar.pfs,3,14,0,0
-+	$ADDP	tmp0=4,ctx
-+	.save	ar.lc,r3
-+	mov	r3=ar.lc		}
-+{ .mmi;	$ADDP	ctx=0,ctx
-+	$ADDP	inp=0,inp
-+	mov	r2=pr			};;
-+tmp4=in2;
-+tmp5=loc12;
-+tmp6=loc13;
-+	.body
-+{ .mlx;	ld4	$h0=[ctx],8
-+	movl	$K_00_19=0x5a827999	}
-+{ .mlx;	ld4	$h1=[tmp0],8
-+	movl	$K_20_39=0x6ed9eba1	};;
-+{ .mlx;	ld4	$h2=[ctx],8
-+	movl	$K_40_59=0x8f1bbcdc	}
-+{ .mlx;	ld4	$h3=[tmp0]
-+	movl	$K_60_79=0xca62c1d6	};;
-+{ .mmi;	ld4	$h4=[ctx],-16
-+	add	in2=-1,in2		    // adjust num for ar.lc
-+	mov	ar.ec=1			};;
-+{ .mmi;	nop.m	0
-+	add	tmp3=1,inp
-+	mov	ar.lc=in2		};; // brp.loop.imp: too far
-+
-+.Ldtop:
-+{ .mmi;	mov	$A=$h0
-+	mov	$B=$h1
-+	mux2	tmp6=$h1,0x44		}
-+{ .mmi;	mov	$C=$h2
-+	mov	$D=$h3
-+	mov	$E=$h4			};;
-+
-+___
-+
-+{ my $i;
-+  my @V=($A,$B,$C,$D,$E);
-+
-+	for($i=0;$i<16;$i++)	{ &BODY_00_15(\$code,$i,@V); unshift(@V,pop(@V)); }
-+	for(;$i<20;$i++)	{ &BODY_16_19(\$code,$i,@V); unshift(@V,pop(@V)); }
-+	for(;$i<40;$i++)	{ &BODY_20_39(\$code,$i,@V); unshift(@V,pop(@V)); }
-+	for(;$i<60;$i++)	{ &BODY_40_59(\$code,$i,@V); unshift(@V,pop(@V)); }
-+	for(;$i<80;$i++)	{ &BODY_60_79(\$code,$i,@V); unshift(@V,pop(@V)); }
-+
-+	(($V[0] eq $A) and ($V[4] eq $E)) or die;	# double-check
-+}
-+
-+$code.=<<___;
-+{ .mmb;	add	$h0=$h0,$A
-+	add	$h2=$h2,$C
-+	br.ctop.dptk.many	.Ldtop	};;
-+.Ldend:
-+{ .mmi;	add	tmp0=4,ctx
-+	mov	ar.lc=r3		};;
-+{ .mmi;	st4	[ctx]=$h0,8
-+	st4	[tmp0]=$h1,8		};;
-+{ .mmi;	st4	[ctx]=$h2,8
-+	st4	[tmp0]=$h3		};;
-+{ .mib;	st4	[ctx]=$h4,-16
-+	mov	pr=r2,0x1ffff
-+	br.ret.sptk.many	b0	};;
-+.endp	sha1_block_data_order#
-+stringz	"SHA1 block transform for IA64, CRYPTOGAMS by "
-+___
-+
-+open STDOUT,">$output" if $output;
-+print $code;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-mb-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-mb-x86_64.pl
-new file mode 100644
-index 0000000..51c73c0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-mb-x86_64.pl
-@@ -0,0 +1,1582 @@
-+#! /usr/bin/env perl
-+# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# Multi-buffer SHA1 procedure processes n buffers in parallel by
-+# placing buffer data to designated lane of SIMD register. n is
-+# naturally limited to 4 on pre-AVX2 processors and to 8 on
-+# AVX2-capable processors such as Haswell.
-+#
-+#		this	+aesni(i)	sha1	aesni-sha1	gain(iv)
-+# -------------------------------------------------------------------
-+# Westmere(ii)	10.7/n	+1.28=3.96(n=4)	5.30	6.66		+68%
-+# Atom(ii)	18.1/n	+3.93=8.46(n=4)	9.37	12.8		+51%
-+# Sandy Bridge	(8.16	+5.15=13.3)/n	4.99	5.98		+80%
-+# Ivy Bridge	(8.08	+5.14=13.2)/n	4.60	5.54		+68%
-+# Haswell(iii)	(8.96	+5.00=14.0)/n	3.57	4.55		+160%
-+# Skylake	(8.70	+5.00=13.7)/n	3.64	4.20		+145%
-+# Bulldozer	(9.76	+5.76=15.5)/n	5.95	6.37		+64%
-+#
-+# (i)	multi-block CBC encrypt with 128-bit key;
-+# (ii)	(HASH+AES)/n does not apply to Westmere for n>3 and Atom,
-+#	because of lower AES-NI instruction throughput;
-+# (iii)	"this" is for n=8, when we gather twice as much data, result
-+#	for n=4 is 8.00+4.44=12.4;
-+# (iv)	presented improvement coefficients are asymptotic limits and
-+#	in real-life application are somewhat lower, e.g. for 2KB
-+#	fragments they range from 30% to 100% (on Haswell);
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+$avx=0;
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	   `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+# void sha1_multi_block (
-+#     struct {	unsigned int A[8];
-+#		unsigned int B[8];
-+#		unsigned int C[8];
-+#		unsigned int D[8];
-+#		unsigned int E[8];	} *ctx,
-+#     struct {	void *ptr; int blocks;	} inp[8],
-+#     int num);		/* 1 or 2 */
-+#
-+$ctx="%rdi";	# 1st arg
-+$inp="%rsi";	# 2nd arg
-+$num="%edx";
-+@ptr=map("%r$_",(8..11));
-+$Tbl="%rbp";
-+
-+@V=($A,$B,$C,$D,$E)=map("%xmm$_",(0..4));
-+($t0,$t1,$t2,$t3,$tx)=map("%xmm$_",(5..9));
-+@Xi=map("%xmm$_",(10..14));
-+$K="%xmm15";
-+
-+if (1) {
-+    # Atom-specific optimization aiming to eliminate pshufb with high
-+    # registers [and thus get rid of 48 cycles accumulated penalty] 
-+    @Xi=map("%xmm$_",(0..4));
-+    ($tx,$t0,$t1,$t2,$t3)=map("%xmm$_",(5..9));
-+    @V=($A,$B,$C,$D,$E)=map("%xmm$_",(10..14));
-+}
-+
-+$REG_SZ=16;
-+
-+sub Xi_off {
-+my $off = shift;
-+
-+    $off %= 16; $off *= $REG_SZ;
-+    $off<256 ? "$off-128(%rax)" : "$off-256-128(%rbx)";
-+}
-+
-+sub BODY_00_19 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+my $k=$i+2;
-+
-+# Loads are performed 2+3/4 iterations in advance. 3/4 means that out
-+# of 4 words you would expect to be loaded per given iteration one is
-+# spilled to next iteration. In other words indices in four input
-+# streams are distributed as following:
-+#
-+# $i==0:	0,0,0,0,1,1,1,1,2,2,2,
-+# $i==1:	2,3,3,3,
-+# $i==2:	3,4,4,4,
-+# ...
-+# $i==13:	14,15,15,15,
-+# $i==14:	15
-+# 
-+# Then at $i==15 Xupdate is applied one iteration in advance...
-+$code.=<<___ if ($i==0);
-+	movd		(@ptr[0]),@Xi[0]
-+	 lea		`16*4`(@ptr[0]),@ptr[0]
-+	movd		(@ptr[1]),@Xi[2]	# borrow @Xi[2]
-+	 lea		`16*4`(@ptr[1]),@ptr[1]
-+	movd		(@ptr[2]),@Xi[3]	# borrow @Xi[3]
-+	 lea		`16*4`(@ptr[2]),@ptr[2]
-+	movd		(@ptr[3]),@Xi[4]	# borrow @Xi[4]
-+	 lea		`16*4`(@ptr[3]),@ptr[3]
-+	punpckldq	@Xi[3],@Xi[0]
-+	 movd		`4*$j-16*4`(@ptr[0]),@Xi[1]
-+	punpckldq	@Xi[4],@Xi[2]
-+	 movd		`4*$j-16*4`(@ptr[1]),$t3
-+	punpckldq	@Xi[2],@Xi[0]
-+	 movd		`4*$j-16*4`(@ptr[2]),$t2
-+	pshufb		$tx,@Xi[0]
-+___
-+$code.=<<___ if ($i<14);			# just load input
-+	 movd		`4*$j-16*4`(@ptr[3]),$t1
-+	 punpckldq	$t2,@Xi[1]
-+	movdqa	$a,$t2
-+	paddd	$K,$e				# e+=K_00_19
-+	 punpckldq	$t1,$t3
-+	movdqa	$b,$t1
-+	movdqa	$b,$t0
-+	pslld	\$5,$t2
-+	pandn	$d,$t1
-+	pand	$c,$t0
-+	 punpckldq	$t3,@Xi[1]
-+	movdqa	$a,$t3
-+
-+	movdqa	@Xi[0],`&Xi_off($i)`
-+	paddd	@Xi[0],$e			# e+=X[i]
-+	 movd		`4*$k-16*4`(@ptr[0]),@Xi[2]
-+	psrld	\$27,$t3
-+	pxor	$t1,$t0				# Ch(b,c,d)
-+	movdqa	$b,$t1
-+
-+	por	$t3,$t2				# rol(a,5)
-+	 movd		`4*$k-16*4`(@ptr[1]),$t3
-+	pslld	\$30,$t1
-+	paddd	$t0,$e				# e+=Ch(b,c,d)
-+
-+	psrld	\$2,$b
-+	paddd	$t2,$e				# e+=rol(a,5)
-+	 pshufb	$tx,@Xi[1]
-+	 movd		`4*$k-16*4`(@ptr[2]),$t2
-+	por	$t1,$b				# b=rol(b,30)
-+___
-+$code.=<<___ if ($i==14);			# just load input
-+	 movd		`4*$j-16*4`(@ptr[3]),$t1
-+	 punpckldq	$t2,@Xi[1]
-+	movdqa	$a,$t2
-+	paddd	$K,$e				# e+=K_00_19
-+	 punpckldq	$t1,$t3
-+	movdqa	$b,$t1
-+	movdqa	$b,$t0
-+	pslld	\$5,$t2
-+	 prefetcht0	63(@ptr[0])
-+	pandn	$d,$t1
-+	pand	$c,$t0
-+	 punpckldq	$t3,@Xi[1]
-+	movdqa	$a,$t3
-+
-+	movdqa	@Xi[0],`&Xi_off($i)`
-+	paddd	@Xi[0],$e			# e+=X[i]
-+	psrld	\$27,$t3
-+	pxor	$t1,$t0				# Ch(b,c,d)
-+	movdqa	$b,$t1
-+	 prefetcht0	63(@ptr[1])
-+
-+	por	$t3,$t2				# rol(a,5)
-+	pslld	\$30,$t1
-+	paddd	$t0,$e				# e+=Ch(b,c,d)
-+	 prefetcht0	63(@ptr[2])
-+
-+	psrld	\$2,$b
-+	paddd	$t2,$e				# e+=rol(a,5)
-+	 pshufb	$tx,@Xi[1]
-+	 prefetcht0	63(@ptr[3])
-+	por	$t1,$b				# b=rol(b,30)
-+___
-+$code.=<<___ if ($i>=13 && $i<15);
-+	movdqa	`&Xi_off($j+2)`,@Xi[3]		# preload "X[2]"
-+___
-+$code.=<<___ if ($i>=15);			# apply Xupdate
-+	pxor	@Xi[-2],@Xi[1]			# "X[13]"
-+	movdqa	`&Xi_off($j+2)`,@Xi[3]		# "X[2]"
-+
-+	movdqa	$a,$t2
-+	 pxor	`&Xi_off($j+8)`,@Xi[1]
-+	paddd	$K,$e				# e+=K_00_19
-+	movdqa	$b,$t1
-+	pslld	\$5,$t2
-+	 pxor	@Xi[3],@Xi[1]
-+	movdqa	$b,$t0
-+	pandn	$d,$t1
-+	 movdqa	@Xi[1],$tx
-+	pand	$c,$t0
-+	movdqa	$a,$t3
-+	 psrld	\$31,$tx
-+	 paddd	@Xi[1],@Xi[1]
-+
-+	movdqa	@Xi[0],`&Xi_off($i)`
-+	paddd	@Xi[0],$e			# e+=X[i]
-+	psrld	\$27,$t3
-+	pxor	$t1,$t0				# Ch(b,c,d)
-+
-+	movdqa	$b,$t1
-+	por	$t3,$t2				# rol(a,5)
-+	pslld	\$30,$t1
-+	paddd	$t0,$e				# e+=Ch(b,c,d)
-+
-+	psrld	\$2,$b
-+	paddd	$t2,$e				# e+=rol(a,5)
-+	 por	$tx,@Xi[1]			# rol	\$1,@Xi[1]
-+	por	$t1,$b				# b=rol(b,30)
-+___
-+push(@Xi,shift(@Xi));
-+}
-+
-+sub BODY_20_39 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+
-+$code.=<<___ if ($i<79);
-+	pxor	@Xi[-2],@Xi[1]			# "X[13]"
-+	movdqa	`&Xi_off($j+2)`,@Xi[3]		# "X[2]"
-+
-+	movdqa	$a,$t2
-+	movdqa	$d,$t0
-+	 pxor	`&Xi_off($j+8)`,@Xi[1]
-+	paddd	$K,$e				# e+=K_20_39
-+	pslld	\$5,$t2
-+	pxor	$b,$t0
-+
-+	movdqa	$a,$t3
-+___
-+$code.=<<___ if ($i<72);
-+	movdqa	@Xi[0],`&Xi_off($i)`
-+___
-+$code.=<<___ if ($i<79);
-+	paddd	@Xi[0],$e			# e+=X[i]
-+	 pxor	@Xi[3],@Xi[1]
-+	psrld	\$27,$t3
-+	pxor	$c,$t0				# Parity(b,c,d)
-+	movdqa	$b,$t1
-+
-+	pslld	\$30,$t1
-+	 movdqa	@Xi[1],$tx
-+	por	$t3,$t2				# rol(a,5)
-+	 psrld	\$31,$tx
-+	paddd	$t0,$e				# e+=Parity(b,c,d)
-+	 paddd	@Xi[1],@Xi[1]
-+
-+	psrld	\$2,$b
-+	paddd	$t2,$e				# e+=rol(a,5)
-+	 por	$tx,@Xi[1]			# rol(@Xi[1],1)
-+	por	$t1,$b				# b=rol(b,30)
-+___
-+$code.=<<___ if ($i==79);
-+	movdqa	$a,$t2
-+	paddd	$K,$e				# e+=K_20_39
-+	movdqa	$d,$t0
-+	pslld	\$5,$t2
-+	pxor	$b,$t0
-+
-+	movdqa	$a,$t3
-+	paddd	@Xi[0],$e			# e+=X[i]
-+	psrld	\$27,$t3
-+	movdqa	$b,$t1
-+	pxor	$c,$t0				# Parity(b,c,d)
-+
-+	pslld	\$30,$t1
-+	por	$t3,$t2				# rol(a,5)
-+	paddd	$t0,$e				# e+=Parity(b,c,d)
-+
-+	psrld	\$2,$b
-+	paddd	$t2,$e				# e+=rol(a,5)
-+	por	$t1,$b				# b=rol(b,30)
-+___
-+push(@Xi,shift(@Xi));
-+}
-+
-+sub BODY_40_59 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+
-+$code.=<<___;
-+	pxor	@Xi[-2],@Xi[1]			# "X[13]"
-+	movdqa	`&Xi_off($j+2)`,@Xi[3]		# "X[2]"
-+
-+	movdqa	$a,$t2
-+	movdqa	$d,$t1
-+	 pxor	`&Xi_off($j+8)`,@Xi[1]
-+	pxor	@Xi[3],@Xi[1]
-+	paddd	$K,$e				# e+=K_40_59
-+	pslld	\$5,$t2
-+	movdqa	$a,$t3
-+	pand	$c,$t1
-+
-+	movdqa	$d,$t0
-+	 movdqa	@Xi[1],$tx
-+	psrld	\$27,$t3
-+	paddd	$t1,$e
-+	pxor	$c,$t0
-+
-+	movdqa	@Xi[0],`&Xi_off($i)`
-+	paddd	@Xi[0],$e			# e+=X[i]
-+	por	$t3,$t2				# rol(a,5)
-+	 psrld	\$31,$tx
-+	pand	$b,$t0
-+	movdqa	$b,$t1
-+
-+	pslld	\$30,$t1
-+	 paddd	@Xi[1],@Xi[1]
-+	paddd	$t0,$e				# e+=Maj(b,d,c)
-+
-+	psrld	\$2,$b
-+	paddd	$t2,$e				# e+=rol(a,5)
-+	 por	$tx,@Xi[1]			# rol(@X[1],1)
-+	por	$t1,$b				# b=rol(b,30)
-+___
-+push(@Xi,shift(@Xi));
-+}
-+
-+$code.=<<___;
-+.text
-+
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	sha1_multi_block
-+.type	sha1_multi_block,\@function,3
-+.align	32
-+sha1_multi_block:
-+	mov	OPENSSL_ia32cap_P+4(%rip),%rcx
-+	bt	\$61,%rcx			# check SHA bit
-+	jc	_shaext_shortcut
-+___
-+$code.=<<___ if ($avx);
-+	test	\$`1<<28`,%ecx
-+	jnz	_avx_shortcut
-+___
-+$code.=<<___;
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,-0x78(%rax)
-+	movaps	%xmm11,-0x68(%rax)
-+	movaps	%xmm12,-0x58(%rax)
-+	movaps	%xmm13,-0x48(%rax)
-+	movaps	%xmm14,-0x38(%rax)
-+	movaps	%xmm15,-0x28(%rax)
-+___
-+$code.=<<___;
-+	sub	\$`$REG_SZ*18`,%rsp
-+	and	\$-256,%rsp
-+	mov	%rax,`$REG_SZ*17`(%rsp)		# original %rsp
-+.Lbody:
-+	lea	K_XX_XX(%rip),$Tbl
-+	lea	`$REG_SZ*16`(%rsp),%rbx
-+
-+.Loop_grande:
-+	mov	$num,`$REG_SZ*17+8`(%rsp)	# original $num
-+	xor	$num,$num
-+___
-+for($i=0;$i<4;$i++) {
-+    $code.=<<___;
-+	mov	`16*$i+0`($inp),@ptr[$i]	# input pointer
-+	mov	`16*$i+8`($inp),%ecx		# number of blocks
-+	cmp	$num,%ecx
-+	cmovg	%ecx,$num			# find maximum
-+	test	%ecx,%ecx
-+	mov	%ecx,`4*$i`(%rbx)		# initialize counters
-+	cmovle	$Tbl,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	test	$num,$num
-+	jz	.Ldone
-+
-+	movdqu	0x00($ctx),$A			# load context
-+	 lea	128(%rsp),%rax
-+	movdqu	0x20($ctx),$B
-+	movdqu	0x40($ctx),$C
-+	movdqu	0x60($ctx),$D
-+	movdqu	0x80($ctx),$E
-+	movdqa	0x60($Tbl),$tx			# pbswap_mask
-+	movdqa	-0x20($Tbl),$K			# K_00_19
-+	jmp	.Loop
-+
-+.align	32
-+.Loop:
-+___
-+for($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
-+$code.="	movdqa	0x00($Tbl),$K\n";	# K_20_39
-+for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.="	movdqa	0x20($Tbl),$K\n";	# K_40_59
-+for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+$code.="	movdqa	0x40($Tbl),$K\n";	# K_60_79
-+for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	movdqa	(%rbx),@Xi[0]			# pull counters
-+	mov	\$1,%ecx
-+	cmp	4*0(%rbx),%ecx			# examinte counters
-+	pxor	$t2,$t2
-+	cmovge	$Tbl,@ptr[0]			# cancel input
-+	cmp	4*1(%rbx),%ecx
-+	movdqa	@Xi[0],@Xi[1]
-+	cmovge	$Tbl,@ptr[1]
-+	cmp	4*2(%rbx),%ecx
-+	pcmpgtd	$t2,@Xi[1]			# mask value
-+	cmovge	$Tbl,@ptr[2]
-+	cmp	4*3(%rbx),%ecx
-+	paddd	@Xi[1],@Xi[0]			# counters--
-+	cmovge	$Tbl,@ptr[3]
-+
-+	movdqu	0x00($ctx),$t0
-+	pand	@Xi[1],$A
-+	movdqu	0x20($ctx),$t1
-+	pand	@Xi[1],$B
-+	paddd	$t0,$A
-+	movdqu	0x40($ctx),$t2
-+	pand	@Xi[1],$C
-+	paddd	$t1,$B
-+	movdqu	0x60($ctx),$t3
-+	pand	@Xi[1],$D
-+	paddd	$t2,$C
-+	movdqu	0x80($ctx),$tx
-+	pand	@Xi[1],$E
-+	movdqu	$A,0x00($ctx)
-+	paddd	$t3,$D
-+	movdqu	$B,0x20($ctx)
-+	paddd	$tx,$E
-+	movdqu	$C,0x40($ctx)
-+	movdqu	$D,0x60($ctx)
-+	movdqu	$E,0x80($ctx)
-+
-+	movdqa	@Xi[0],(%rbx)			# save counters
-+	movdqa	0x60($Tbl),$tx			# pbswap_mask
-+	movdqa	-0x20($Tbl),$K			# K_00_19
-+	dec	$num
-+	jnz	.Loop
-+
-+	mov	`$REG_SZ*17+8`(%rsp),$num
-+	lea	$REG_SZ($ctx),$ctx
-+	lea	`16*$REG_SZ/4`($inp),$inp
-+	dec	$num
-+	jnz	.Loop_grande
-+
-+.Ldone:
-+	mov	`$REG_SZ*17`(%rsp),%rax		# original %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xb8(%rax),%xmm6
-+	movaps	-0xa8(%rax),%xmm7
-+	movaps	-0x98(%rax),%xmm8
-+	movaps	-0x88(%rax),%xmm9
-+	movaps	-0x78(%rax),%xmm10
-+	movaps	-0x68(%rax),%xmm11
-+	movaps	-0x58(%rax),%xmm12
-+	movaps	-0x48(%rax),%xmm13
-+	movaps	-0x38(%rax),%xmm14
-+	movaps	-0x28(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Lepilogue:
-+	ret
-+.size	sha1_multi_block,.-sha1_multi_block
-+___
-+						{{{
-+my ($ABCD0,$E0,$E0_,$BSWAP,$ABCD1,$E1,$E1_)=map("%xmm$_",(0..3,8..10));
-+my @MSG0=map("%xmm$_",(4..7));
-+my @MSG1=map("%xmm$_",(11..14));
-+
-+$code.=<<___;
-+.type	sha1_multi_block_shaext,\@function,3
-+.align	32
-+sha1_multi_block_shaext:
-+_shaext_shortcut:
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,-0x78(%rax)
-+	movaps	%xmm11,-0x68(%rax)
-+	movaps	%xmm12,-0x58(%rax)
-+	movaps	%xmm13,-0x48(%rax)
-+	movaps	%xmm14,-0x38(%rax)
-+	movaps	%xmm15,-0x28(%rax)
-+___
-+$code.=<<___;
-+	sub	\$`$REG_SZ*18`,%rsp
-+	shl	\$1,$num			# we process pair at a time
-+	and	\$-256,%rsp
-+	lea	0x40($ctx),$ctx			# size optimization
-+	mov	%rax,`$REG_SZ*17`(%rsp)		# original %rsp
-+.Lbody_shaext:
-+	lea	`$REG_SZ*16`(%rsp),%rbx
-+	movdqa	K_XX_XX+0x80(%rip),$BSWAP	# byte-n-word swap
-+
-+.Loop_grande_shaext:
-+	mov	$num,`$REG_SZ*17+8`(%rsp)	# original $num
-+	xor	$num,$num
-+___
-+for($i=0;$i<2;$i++) {
-+    $code.=<<___;
-+	mov	`16*$i+0`($inp),@ptr[$i]	# input pointer
-+	mov	`16*$i+8`($inp),%ecx		# number of blocks
-+	cmp	$num,%ecx
-+	cmovg	%ecx,$num			# find maximum
-+	test	%ecx,%ecx
-+	mov	%ecx,`4*$i`(%rbx)		# initialize counters
-+	cmovle	%rsp,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	test	$num,$num
-+	jz	.Ldone_shaext
-+
-+	movq		0x00-0x40($ctx),$ABCD0	# a1.a0
-+	movq		0x20-0x40($ctx),@MSG0[0]# b1.b0
-+	movq		0x40-0x40($ctx),@MSG0[1]# c1.c0
-+	movq		0x60-0x40($ctx),@MSG0[2]# d1.d0
-+	movq		0x80-0x40($ctx),@MSG0[3]# e1.e0
-+
-+	punpckldq	@MSG0[0],$ABCD0		# b1.a1.b0.a0
-+	punpckldq	@MSG0[2],@MSG0[1]	# d1.c1.d0.c0
-+
-+	movdqa		$ABCD0,$ABCD1
-+	punpcklqdq	@MSG0[1],$ABCD0		# d0.c0.b0.a0
-+	punpckhqdq	@MSG0[1],$ABCD1		# d1.c1.b1.a1
-+
-+	pshufd		\$0b00111111,@MSG0[3],$E0
-+	pshufd		\$0b01111111,@MSG0[3],$E1
-+	pshufd		\$0b00011011,$ABCD0,$ABCD0
-+	pshufd		\$0b00011011,$ABCD1,$ABCD1
-+	jmp		.Loop_shaext
-+
-+.align	32
-+.Loop_shaext:
-+	movdqu		0x00(@ptr[0]),@MSG0[0]
-+	 movdqu		0x00(@ptr[1]),@MSG1[0]
-+	movdqu		0x10(@ptr[0]),@MSG0[1]
-+	 movdqu		0x10(@ptr[1]),@MSG1[1]
-+	movdqu		0x20(@ptr[0]),@MSG0[2]
-+	pshufb		$BSWAP,@MSG0[0]
-+	 movdqu		0x20(@ptr[1]),@MSG1[2]
-+	 pshufb		$BSWAP,@MSG1[0]
-+	movdqu		0x30(@ptr[0]),@MSG0[3]
-+	lea		0x40(@ptr[0]),@ptr[0]
-+	pshufb		$BSWAP,@MSG0[1]
-+	 movdqu		0x30(@ptr[1]),@MSG1[3]
-+	 lea		0x40(@ptr[1]),@ptr[1]
-+	 pshufb		$BSWAP,@MSG1[1]
-+
-+	movdqa		$E0,0x50(%rsp)		# offload
-+	paddd		@MSG0[0],$E0
-+	 movdqa		$E1,0x70(%rsp)
-+	 paddd		@MSG1[0],$E1
-+	movdqa		$ABCD0,0x40(%rsp)	# offload
-+	movdqa		$ABCD0,$E0_
-+	 movdqa		$ABCD1,0x60(%rsp)
-+	 movdqa		$ABCD1,$E1_
-+	sha1rnds4	\$0,$E0,$ABCD0		# 0-3
-+	sha1nexte	@MSG0[1],$E0_
-+	 sha1rnds4	\$0,$E1,$ABCD1		# 0-3
-+	 sha1nexte	@MSG1[1],$E1_
-+	pshufb		$BSWAP,@MSG0[2]
-+	prefetcht0	127(@ptr[0])
-+	sha1msg1	@MSG0[1],@MSG0[0]
-+	 pshufb		$BSWAP,@MSG1[2]
-+	 prefetcht0	127(@ptr[1])
-+	 sha1msg1	@MSG1[1],@MSG1[0]
-+
-+	pshufb		$BSWAP,@MSG0[3]
-+	movdqa		$ABCD0,$E0
-+	 pshufb		$BSWAP,@MSG1[3]
-+	 movdqa		$ABCD1,$E1
-+	sha1rnds4	\$0,$E0_,$ABCD0		# 4-7
-+	sha1nexte	@MSG0[2],$E0
-+	 sha1rnds4	\$0,$E1_,$ABCD1		# 4-7
-+	 sha1nexte	@MSG1[2],$E1
-+	pxor		@MSG0[2],@MSG0[0]
-+	sha1msg1	@MSG0[2],@MSG0[1]
-+	 pxor		@MSG1[2],@MSG1[0]
-+	 sha1msg1	@MSG1[2],@MSG1[1]
-+___
-+for($i=2;$i<20-4;$i++) {
-+$code.=<<___;
-+	movdqa		$ABCD0,$E0_
-+	 movdqa		$ABCD1,$E1_
-+	sha1rnds4	\$`int($i/5)`,$E0,$ABCD0	# 8-11
-+	sha1nexte	@MSG0[3],$E0_
-+	 sha1rnds4	\$`int($i/5)`,$E1,$ABCD1	# 8-11
-+	 sha1nexte	@MSG1[3],$E1_
-+	sha1msg2	@MSG0[3],@MSG0[0]
-+	 sha1msg2	@MSG1[3],@MSG1[0]
-+	pxor		@MSG0[3],@MSG0[1]
-+	sha1msg1	@MSG0[3],@MSG0[2]
-+	 pxor		@MSG1[3],@MSG1[1]
-+	 sha1msg1	@MSG1[3],@MSG1[2]
-+___
-+	($E0,$E0_)=($E0_,$E0);		($E1,$E1_)=($E1_,$E1);
-+	push(@MSG0,shift(@MSG0));	push(@MSG1,shift(@MSG1));
-+}
-+$code.=<<___;
-+	movdqa		$ABCD0,$E0_
-+	 movdqa		$ABCD1,$E1_
-+	sha1rnds4	\$3,$E0,$ABCD0		# 64-67
-+	sha1nexte	@MSG0[3],$E0_
-+	 sha1rnds4	\$3,$E1,$ABCD1		# 64-67
-+	 sha1nexte	@MSG1[3],$E1_
-+	sha1msg2	@MSG0[3],@MSG0[0]
-+	 sha1msg2	@MSG1[3],@MSG1[0]
-+	pxor		@MSG0[3],@MSG0[1]
-+	 pxor		@MSG1[3],@MSG1[1]
-+
-+	mov		\$1,%ecx
-+	pxor		@MSG0[2],@MSG0[2]	# zero
-+	cmp		4*0(%rbx),%ecx		# examine counters
-+	cmovge		%rsp,@ptr[0]		# cancel input
-+
-+	movdqa		$ABCD0,$E0
-+	 movdqa		$ABCD1,$E1
-+	sha1rnds4	\$3,$E0_,$ABCD0		# 68-71
-+	sha1nexte	@MSG0[0],$E0
-+	 sha1rnds4	\$3,$E1_,$ABCD1		# 68-71
-+	 sha1nexte	@MSG1[0],$E1
-+	sha1msg2	@MSG0[0],@MSG0[1]
-+	 sha1msg2	@MSG1[0],@MSG1[1]
-+
-+	cmp		4*1(%rbx),%ecx
-+	cmovge		%rsp,@ptr[1]
-+	movq		(%rbx),@MSG0[0]		# pull counters
-+
-+	movdqa		$ABCD0,$E0_
-+	 movdqa		$ABCD1,$E1_
-+	sha1rnds4	\$3,$E0,$ABCD0		# 72-75
-+	sha1nexte	@MSG0[1],$E0_
-+	 sha1rnds4	\$3,$E1,$ABCD1		# 72-75
-+	 sha1nexte	@MSG1[1],$E1_
-+
-+	pshufd		\$0x00,@MSG0[0],@MSG1[2]
-+	pshufd		\$0x55,@MSG0[0],@MSG1[3]
-+	movdqa		@MSG0[0],@MSG0[1]
-+	pcmpgtd		@MSG0[2],@MSG1[2]
-+	pcmpgtd		@MSG0[2],@MSG1[3]
-+
-+	movdqa		$ABCD0,$E0
-+	 movdqa		$ABCD1,$E1
-+	sha1rnds4	\$3,$E0_,$ABCD0		# 76-79
-+	sha1nexte	$MSG0[2],$E0
-+	 sha1rnds4	\$3,$E1_,$ABCD1		# 76-79
-+	 sha1nexte	$MSG0[2],$E1
-+
-+	pcmpgtd		@MSG0[2],@MSG0[1]	# counter mask
-+	pand		@MSG1[2],$ABCD0
-+	pand		@MSG1[2],$E0
-+	 pand		@MSG1[3],$ABCD1
-+	 pand		@MSG1[3],$E1
-+	paddd		@MSG0[1],@MSG0[0]	# counters--
-+
-+	paddd		0x40(%rsp),$ABCD0
-+	paddd		0x50(%rsp),$E0
-+	 paddd		0x60(%rsp),$ABCD1
-+	 paddd		0x70(%rsp),$E1
-+
-+	movq		@MSG0[0],(%rbx)		# save counters
-+	dec		$num
-+	jnz		.Loop_shaext
-+
-+	mov		`$REG_SZ*17+8`(%rsp),$num
-+
-+	pshufd		\$0b00011011,$ABCD0,$ABCD0
-+	pshufd		\$0b00011011,$ABCD1,$ABCD1
-+
-+	movdqa		$ABCD0,@MSG0[0]
-+	punpckldq	$ABCD1,$ABCD0		# b1.b0.a1.a0
-+	punpckhdq	$ABCD1,@MSG0[0]		# d1.d0.c1.c0
-+	punpckhdq	$E1,$E0			# e1.e0.xx.xx
-+	movq		$ABCD0,0x00-0x40($ctx)	# a1.a0
-+	psrldq		\$8,$ABCD0
-+	movq		@MSG0[0],0x40-0x40($ctx)# c1.c0
-+	psrldq		\$8,@MSG0[0]
-+	movq		$ABCD0,0x20-0x40($ctx)	# b1.b0
-+	psrldq		\$8,$E0
-+	movq		@MSG0[0],0x60-0x40($ctx)# d1.d0
-+	movq		$E0,0x80-0x40($ctx)	# e1.e0
-+
-+	lea	`$REG_SZ/2`($ctx),$ctx
-+	lea	`16*2`($inp),$inp
-+	dec	$num
-+	jnz	.Loop_grande_shaext
-+
-+.Ldone_shaext:
-+	#mov	`$REG_SZ*17`(%rsp),%rax		# original %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xb8(%rax),%xmm6
-+	movaps	-0xa8(%rax),%xmm7
-+	movaps	-0x98(%rax),%xmm8
-+	movaps	-0x88(%rax),%xmm9
-+	movaps	-0x78(%rax),%xmm10
-+	movaps	-0x68(%rax),%xmm11
-+	movaps	-0x58(%rax),%xmm12
-+	movaps	-0x48(%rax),%xmm13
-+	movaps	-0x38(%rax),%xmm14
-+	movaps	-0x28(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Lepilogue_shaext:
-+	ret
-+.size	sha1_multi_block_shaext,.-sha1_multi_block_shaext
-+___
-+						}}}
-+
-+						if ($avx) {{{
-+sub BODY_00_19_avx {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+my $k=$i+2;
-+my $vpack = $REG_SZ==16 ? "vpunpckldq" : "vinserti128";
-+my $ptr_n = $REG_SZ==16 ? @ptr[1] : @ptr[4];
-+
-+$code.=<<___ if ($i==0 && $REG_SZ==16);
-+	vmovd		(@ptr[0]),@Xi[0]
-+	 lea		`16*4`(@ptr[0]),@ptr[0]
-+	vmovd		(@ptr[1]),@Xi[2]	# borrow Xi[2]
-+	 lea		`16*4`(@ptr[1]),@ptr[1]
-+	vpinsrd		\$1,(@ptr[2]),@Xi[0],@Xi[0]
-+	 lea		`16*4`(@ptr[2]),@ptr[2]
-+	vpinsrd		\$1,(@ptr[3]),@Xi[2],@Xi[2]
-+	 lea		`16*4`(@ptr[3]),@ptr[3]
-+	 vmovd		`4*$j-16*4`(@ptr[0]),@Xi[1]
-+	vpunpckldq	@Xi[2],@Xi[0],@Xi[0]
-+	 vmovd		`4*$j-16*4`($ptr_n),$t3
-+	vpshufb		$tx,@Xi[0],@Xi[0]
-+___
-+$code.=<<___ if ($i<15 && $REG_SZ==16);		# just load input
-+	 vpinsrd	\$1,`4*$j-16*4`(@ptr[2]),@Xi[1],@Xi[1]
-+	 vpinsrd	\$1,`4*$j-16*4`(@ptr[3]),$t3,$t3
-+___
-+$code.=<<___ if ($i==0 && $REG_SZ==32);
-+	vmovd		(@ptr[0]),@Xi[0]
-+	 lea		`16*4`(@ptr[0]),@ptr[0]
-+	vmovd		(@ptr[4]),@Xi[2]	# borrow Xi[2]
-+	 lea		`16*4`(@ptr[4]),@ptr[4]
-+	vmovd		(@ptr[1]),$t2
-+	 lea		`16*4`(@ptr[1]),@ptr[1]
-+	vmovd		(@ptr[5]),$t1
-+	 lea		`16*4`(@ptr[5]),@ptr[5]
-+	vpinsrd		\$1,(@ptr[2]),@Xi[0],@Xi[0]
-+	 lea		`16*4`(@ptr[2]),@ptr[2]
-+	vpinsrd		\$1,(@ptr[6]),@Xi[2],@Xi[2]
-+	 lea		`16*4`(@ptr[6]),@ptr[6]
-+	vpinsrd		\$1,(@ptr[3]),$t2,$t2
-+	 lea		`16*4`(@ptr[3]),@ptr[3]
-+	vpunpckldq	$t2,@Xi[0],@Xi[0]
-+	vpinsrd		\$1,(@ptr[7]),$t1,$t1
-+	 lea		`16*4`(@ptr[7]),@ptr[7]
-+	vpunpckldq	$t1,@Xi[2],@Xi[2]
-+	 vmovd		`4*$j-16*4`(@ptr[0]),@Xi[1]
-+	vinserti128	@Xi[2],@Xi[0],@Xi[0]
-+	 vmovd		`4*$j-16*4`($ptr_n),$t3
-+	vpshufb		$tx,@Xi[0],@Xi[0]
-+___
-+$code.=<<___ if ($i<15 && $REG_SZ==32);		# just load input
-+	 vmovd		`4*$j-16*4`(@ptr[1]),$t2
-+	 vmovd		`4*$j-16*4`(@ptr[5]),$t1
-+	 vpinsrd	\$1,`4*$j-16*4`(@ptr[2]),@Xi[1],@Xi[1]
-+	 vpinsrd	\$1,`4*$j-16*4`(@ptr[6]),$t3,$t3
-+	 vpinsrd	\$1,`4*$j-16*4`(@ptr[3]),$t2,$t2
-+	 vpunpckldq	$t2,@Xi[1],@Xi[1]
-+	 vpinsrd	\$1,`4*$j-16*4`(@ptr[7]),$t1,$t1
-+	 vpunpckldq	$t1,$t3,$t3
-+___
-+$code.=<<___ if ($i<14);
-+	vpaddd	$K,$e,$e			# e+=K_00_19
-+	vpslld	\$5,$a,$t2
-+	vpandn	$d,$b,$t1
-+	vpand	$c,$b,$t0
-+
-+	vmovdqa	@Xi[0],`&Xi_off($i)`
-+	vpaddd	@Xi[0],$e,$e			# e+=X[i]
-+	 $vpack		$t3,@Xi[1],@Xi[1]
-+	vpsrld	\$27,$a,$t3
-+	vpxor	$t1,$t0,$t0			# Ch(b,c,d)
-+	 vmovd		`4*$k-16*4`(@ptr[0]),@Xi[2]
-+
-+	vpslld	\$30,$b,$t1
-+	vpor	$t3,$t2,$t2			# rol(a,5)
-+	 vmovd		`4*$k-16*4`($ptr_n),$t3
-+	vpaddd	$t0,$e,$e			# e+=Ch(b,c,d)
-+
-+	vpsrld	\$2,$b,$b
-+	vpaddd	$t2,$e,$e			# e+=rol(a,5)
-+	 vpshufb	$tx,@Xi[1],@Xi[1]
-+	vpor	$t1,$b,$b			# b=rol(b,30)
-+___
-+$code.=<<___ if ($i==14);
-+	vpaddd	$K,$e,$e			# e+=K_00_19
-+	 prefetcht0	63(@ptr[0])
-+	vpslld	\$5,$a,$t2
-+	vpandn	$d,$b,$t1
-+	vpand	$c,$b,$t0
-+
-+	vmovdqa	@Xi[0],`&Xi_off($i)`
-+	vpaddd	@Xi[0],$e,$e			# e+=X[i]
-+	 $vpack		$t3,@Xi[1],@Xi[1]
-+	vpsrld	\$27,$a,$t3
-+	 prefetcht0	63(@ptr[1])
-+	vpxor	$t1,$t0,$t0			# Ch(b,c,d)
-+
-+	vpslld	\$30,$b,$t1
-+	vpor	$t3,$t2,$t2			# rol(a,5)
-+	 prefetcht0	63(@ptr[2])
-+	vpaddd	$t0,$e,$e			# e+=Ch(b,c,d)
-+
-+	vpsrld	\$2,$b,$b
-+	vpaddd	$t2,$e,$e			# e+=rol(a,5)
-+	 prefetcht0	63(@ptr[3])
-+	 vpshufb	$tx,@Xi[1],@Xi[1]
-+	vpor	$t1,$b,$b			# b=rol(b,30)
-+___
-+$code.=<<___ if ($i>=13 && $i<15);
-+	vmovdqa	`&Xi_off($j+2)`,@Xi[3]		# preload "X[2]"
-+___
-+$code.=<<___ if ($i>=15);			# apply Xupdate
-+	vpxor	@Xi[-2],@Xi[1],@Xi[1]		# "X[13]"
-+	vmovdqa	`&Xi_off($j+2)`,@Xi[3]		# "X[2]"
-+
-+	vpaddd	$K,$e,$e			# e+=K_00_19
-+	vpslld	\$5,$a,$t2
-+	vpandn	$d,$b,$t1
-+	 `"prefetcht0	63(@ptr[4])"		if ($i==15 && $REG_SZ==32)`
-+	vpand	$c,$b,$t0
-+
-+	vmovdqa	@Xi[0],`&Xi_off($i)`
-+	vpaddd	@Xi[0],$e,$e			# e+=X[i]
-+	 vpxor	`&Xi_off($j+8)`,@Xi[1],@Xi[1]
-+	vpsrld	\$27,$a,$t3
-+	vpxor	$t1,$t0,$t0			# Ch(b,c,d)
-+	 vpxor	@Xi[3],@Xi[1],@Xi[1]
-+	 `"prefetcht0	63(@ptr[5])"		if ($i==15 && $REG_SZ==32)`
-+
-+	vpslld	\$30,$b,$t1
-+	vpor	$t3,$t2,$t2			# rol(a,5)
-+	vpaddd	$t0,$e,$e			# e+=Ch(b,c,d)
-+	 `"prefetcht0	63(@ptr[6])"		if ($i==15 && $REG_SZ==32)`
-+	 vpsrld	\$31,@Xi[1],$tx
-+	 vpaddd	@Xi[1],@Xi[1],@Xi[1]
-+
-+	vpsrld	\$2,$b,$b
-+	 `"prefetcht0	63(@ptr[7])"		if ($i==15 && $REG_SZ==32)`
-+	vpaddd	$t2,$e,$e			# e+=rol(a,5)
-+	 vpor	$tx,@Xi[1],@Xi[1]		# rol	\$1,@Xi[1]
-+	vpor	$t1,$b,$b			# b=rol(b,30)
-+___
-+push(@Xi,shift(@Xi));
-+}
-+
-+sub BODY_20_39_avx {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+
-+$code.=<<___ if ($i<79);
-+	vpxor	@Xi[-2],@Xi[1],@Xi[1]		# "X[13]"
-+	vmovdqa	`&Xi_off($j+2)`,@Xi[3]		# "X[2]"
-+
-+	vpslld	\$5,$a,$t2
-+	vpaddd	$K,$e,$e			# e+=K_20_39
-+	vpxor	$b,$d,$t0
-+___
-+$code.=<<___ if ($i<72);
-+	vmovdqa	@Xi[0],`&Xi_off($i)`
-+___
-+$code.=<<___ if ($i<79);
-+	vpaddd	@Xi[0],$e,$e			# e+=X[i]
-+	 vpxor	`&Xi_off($j+8)`,@Xi[1],@Xi[1]
-+	vpsrld	\$27,$a,$t3
-+	vpxor	$c,$t0,$t0			# Parity(b,c,d)
-+	 vpxor	@Xi[3],@Xi[1],@Xi[1]
-+
-+	vpslld	\$30,$b,$t1
-+	vpor	$t3,$t2,$t2			# rol(a,5)
-+	vpaddd	$t0,$e,$e			# e+=Parity(b,c,d)
-+	 vpsrld	\$31,@Xi[1],$tx
-+	 vpaddd	@Xi[1],@Xi[1],@Xi[1]
-+
-+	vpsrld	\$2,$b,$b
-+	vpaddd	$t2,$e,$e			# e+=rol(a,5)
-+	 vpor	$tx,@Xi[1],@Xi[1]		# rol(@Xi[1],1)
-+	vpor	$t1,$b,$b			# b=rol(b,30)
-+___
-+$code.=<<___ if ($i==79);
-+	vpslld	\$5,$a,$t2
-+	vpaddd	$K,$e,$e			# e+=K_20_39
-+	vpxor	$b,$d,$t0
-+
-+	vpsrld	\$27,$a,$t3
-+	vpaddd	@Xi[0],$e,$e			# e+=X[i]
-+	vpxor	$c,$t0,$t0			# Parity(b,c,d)
-+
-+	vpslld	\$30,$b,$t1
-+	vpor	$t3,$t2,$t2			# rol(a,5)
-+	vpaddd	$t0,$e,$e			# e+=Parity(b,c,d)
-+
-+	vpsrld	\$2,$b,$b
-+	vpaddd	$t2,$e,$e			# e+=rol(a,5)
-+	vpor	$t1,$b,$b			# b=rol(b,30)
-+___
-+push(@Xi,shift(@Xi));
-+}
-+
-+sub BODY_40_59_avx {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+
-+$code.=<<___;
-+	vpxor	@Xi[-2],@Xi[1],@Xi[1]		# "X[13]"
-+	vmovdqa	`&Xi_off($j+2)`,@Xi[3]		# "X[2]"
-+
-+	vpaddd	$K,$e,$e			# e+=K_40_59
-+	vpslld	\$5,$a,$t2
-+	vpand	$c,$d,$t1
-+	 vpxor	`&Xi_off($j+8)`,@Xi[1],@Xi[1]
-+
-+	vpaddd	$t1,$e,$e
-+	vpsrld	\$27,$a,$t3
-+	vpxor	$c,$d,$t0
-+	 vpxor	@Xi[3],@Xi[1],@Xi[1]
-+
-+	vmovdqu	@Xi[0],`&Xi_off($i)`
-+	vpaddd	@Xi[0],$e,$e			# e+=X[i]
-+	vpor	$t3,$t2,$t2			# rol(a,5)
-+	 vpsrld	\$31,@Xi[1],$tx
-+	vpand	$b,$t0,$t0
-+	 vpaddd	@Xi[1],@Xi[1],@Xi[1]
-+
-+	vpslld	\$30,$b,$t1
-+	vpaddd	$t0,$e,$e			# e+=Maj(b,d,c)
-+
-+	vpsrld	\$2,$b,$b
-+	vpaddd	$t2,$e,$e			# e+=rol(a,5)
-+	 vpor	$tx,@Xi[1],@Xi[1]		# rol(@X[1],1)
-+	vpor	$t1,$b,$b			# b=rol(b,30)
-+___
-+push(@Xi,shift(@Xi));
-+}
-+
-+$code.=<<___;
-+.type	sha1_multi_block_avx,\@function,3
-+.align	32
-+sha1_multi_block_avx:
-+_avx_shortcut:
-+___
-+$code.=<<___ if ($avx>1);
-+	shr	\$32,%rcx
-+	cmp	\$2,$num
-+	jb	.Lavx
-+	test	\$`1<<5`,%ecx
-+	jnz	_avx2_shortcut
-+	jmp	.Lavx
-+.align	32
-+.Lavx:
-+___
-+$code.=<<___;
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,-0x78(%rax)
-+	movaps	%xmm11,-0x68(%rax)
-+	movaps	%xmm12,-0x58(%rax)
-+	movaps	%xmm13,-0x48(%rax)
-+	movaps	%xmm14,-0x38(%rax)
-+	movaps	%xmm15,-0x28(%rax)
-+___
-+$code.=<<___;
-+	sub	\$`$REG_SZ*18`, %rsp
-+	and	\$-256,%rsp
-+	mov	%rax,`$REG_SZ*17`(%rsp)		# original %rsp
-+.Lbody_avx:
-+	lea	K_XX_XX(%rip),$Tbl
-+	lea	`$REG_SZ*16`(%rsp),%rbx
-+
-+	vzeroupper
-+.Loop_grande_avx:
-+	mov	$num,`$REG_SZ*17+8`(%rsp)	# original $num
-+	xor	$num,$num
-+___
-+for($i=0;$i<4;$i++) {
-+    $code.=<<___;
-+	mov	`16*$i+0`($inp),@ptr[$i]	# input pointer
-+	mov	`16*$i+8`($inp),%ecx		# number of blocks
-+	cmp	$num,%ecx
-+	cmovg	%ecx,$num			# find maximum
-+	test	%ecx,%ecx
-+	mov	%ecx,`4*$i`(%rbx)		# initialize counters
-+	cmovle	$Tbl,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	test	$num,$num
-+	jz	.Ldone_avx
-+
-+	vmovdqu	0x00($ctx),$A			# load context
-+	 lea	128(%rsp),%rax
-+	vmovdqu	0x20($ctx),$B
-+	vmovdqu	0x40($ctx),$C
-+	vmovdqu	0x60($ctx),$D
-+	vmovdqu	0x80($ctx),$E
-+	vmovdqu	0x60($Tbl),$tx			# pbswap_mask
-+	jmp	.Loop_avx
-+
-+.align	32
-+.Loop_avx:
-+___
-+$code.="	vmovdqa	-0x20($Tbl),$K\n";	# K_00_19
-+for($i=0;$i<20;$i++)	{ &BODY_00_19_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.="	vmovdqa	0x00($Tbl),$K\n";	# K_20_39
-+for(;$i<40;$i++)	{ &BODY_20_39_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.="	vmovdqa	0x20($Tbl),$K\n";	# K_40_59
-+for(;$i<60;$i++)	{ &BODY_40_59_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.="	vmovdqa	0x40($Tbl),$K\n";	# K_60_79
-+for(;$i<80;$i++)	{ &BODY_20_39_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	mov	\$1,%ecx
-+___
-+for($i=0;$i<4;$i++) {
-+    $code.=<<___;
-+	cmp	`4*$i`(%rbx),%ecx		# examine counters
-+	cmovge	$Tbl,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	vmovdqu	(%rbx),$t0			# pull counters
-+	vpxor	$t2,$t2,$t2
-+	vmovdqa	$t0,$t1
-+	vpcmpgtd $t2,$t1,$t1			# mask value
-+	vpaddd	$t1,$t0,$t0			# counters--
-+
-+	vpand	$t1,$A,$A
-+	vpand	$t1,$B,$B
-+	vpaddd	0x00($ctx),$A,$A
-+	vpand	$t1,$C,$C
-+	vpaddd	0x20($ctx),$B,$B
-+	vpand	$t1,$D,$D
-+	vpaddd	0x40($ctx),$C,$C
-+	vpand	$t1,$E,$E
-+	vpaddd	0x60($ctx),$D,$D
-+	vpaddd	0x80($ctx),$E,$E
-+	vmovdqu	$A,0x00($ctx)
-+	vmovdqu	$B,0x20($ctx)
-+	vmovdqu	$C,0x40($ctx)
-+	vmovdqu	$D,0x60($ctx)
-+	vmovdqu	$E,0x80($ctx)
-+
-+	vmovdqu	$t0,(%rbx)			# save counters
-+	vmovdqu	0x60($Tbl),$tx			# pbswap_mask
-+	dec	$num
-+	jnz	.Loop_avx
-+
-+	mov	`$REG_SZ*17+8`(%rsp),$num
-+	lea	$REG_SZ($ctx),$ctx
-+	lea	`16*$REG_SZ/4`($inp),$inp
-+	dec	$num
-+	jnz	.Loop_grande_avx
-+
-+.Ldone_avx:
-+	mov	`$REG_SZ*17`(%rsp),%rax		# original %rsp
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xb8(%rax),%xmm6
-+	movaps	-0xa8(%rax),%xmm7
-+	movaps	-0x98(%rax),%xmm8
-+	movaps	-0x88(%rax),%xmm9
-+	movaps	-0x78(%rax),%xmm10
-+	movaps	-0x68(%rax),%xmm11
-+	movaps	-0x58(%rax),%xmm12
-+	movaps	-0x48(%rax),%xmm13
-+	movaps	-0x38(%rax),%xmm14
-+	movaps	-0x28(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Lepilogue_avx:
-+	ret
-+.size	sha1_multi_block_avx,.-sha1_multi_block_avx
-+___
-+
-+						if ($avx>1) {
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+
-+$REG_SZ=32;
-+
-+@ptr=map("%r$_",(12..15,8..11));
-+
-+@V=($A,$B,$C,$D,$E)=map("%ymm$_",(0..4));
-+($t0,$t1,$t2,$t3,$tx)=map("%ymm$_",(5..9));
-+@Xi=map("%ymm$_",(10..14));
-+$K="%ymm15";
-+
-+$code.=<<___;
-+.type	sha1_multi_block_avx2,\@function,3
-+.align	32
-+sha1_multi_block_avx2:
-+_avx2_shortcut:
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,0x40(%rsp)
-+	movaps	%xmm11,0x50(%rsp)
-+	movaps	%xmm12,-0x78(%rax)
-+	movaps	%xmm13,-0x68(%rax)
-+	movaps	%xmm14,-0x58(%rax)
-+	movaps	%xmm15,-0x48(%rax)
-+___
-+$code.=<<___;
-+	sub	\$`$REG_SZ*18`, %rsp
-+	and	\$-256,%rsp
-+	mov	%rax,`$REG_SZ*17`(%rsp)		# original %rsp
-+.Lbody_avx2:
-+	lea	K_XX_XX(%rip),$Tbl
-+	shr	\$1,$num
-+
-+	vzeroupper
-+.Loop_grande_avx2:
-+	mov	$num,`$REG_SZ*17+8`(%rsp)	# original $num
-+	xor	$num,$num
-+	lea	`$REG_SZ*16`(%rsp),%rbx
-+___
-+for($i=0;$i<8;$i++) {
-+    $code.=<<___;
-+	mov	`16*$i+0`($inp),@ptr[$i]	# input pointer
-+	mov	`16*$i+8`($inp),%ecx		# number of blocks
-+	cmp	$num,%ecx
-+	cmovg	%ecx,$num			# find maximum
-+	test	%ecx,%ecx
-+	mov	%ecx,`4*$i`(%rbx)		# initialize counters
-+	cmovle	$Tbl,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	vmovdqu	0x00($ctx),$A			# load context
-+	 lea	128(%rsp),%rax
-+	vmovdqu	0x20($ctx),$B
-+	 lea	256+128(%rsp),%rbx
-+	vmovdqu	0x40($ctx),$C
-+	vmovdqu	0x60($ctx),$D
-+	vmovdqu	0x80($ctx),$E
-+	vmovdqu	0x60($Tbl),$tx			# pbswap_mask
-+	jmp	.Loop_avx2
-+
-+.align	32
-+.Loop_avx2:
-+___
-+$code.="	vmovdqa	-0x20($Tbl),$K\n";	# K_00_19
-+for($i=0;$i<20;$i++)	{ &BODY_00_19_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.="	vmovdqa	0x00($Tbl),$K\n";	# K_20_39
-+for(;$i<40;$i++)	{ &BODY_20_39_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.="	vmovdqa	0x20($Tbl),$K\n";	# K_40_59
-+for(;$i<60;$i++)	{ &BODY_40_59_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.="	vmovdqa	0x40($Tbl),$K\n";	# K_60_79
-+for(;$i<80;$i++)	{ &BODY_20_39_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	mov	\$1,%ecx
-+	lea	`$REG_SZ*16`(%rsp),%rbx
-+___
-+for($i=0;$i<8;$i++) {
-+    $code.=<<___;
-+	cmp	`4*$i`(%rbx),%ecx		# examine counters
-+	cmovge	$Tbl,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	vmovdqu	(%rbx),$t0		# pull counters
-+	vpxor	$t2,$t2,$t2
-+	vmovdqa	$t0,$t1
-+	vpcmpgtd $t2,$t1,$t1			# mask value
-+	vpaddd	$t1,$t0,$t0			# counters--
-+
-+	vpand	$t1,$A,$A
-+	vpand	$t1,$B,$B
-+	vpaddd	0x00($ctx),$A,$A
-+	vpand	$t1,$C,$C
-+	vpaddd	0x20($ctx),$B,$B
-+	vpand	$t1,$D,$D
-+	vpaddd	0x40($ctx),$C,$C
-+	vpand	$t1,$E,$E
-+	vpaddd	0x60($ctx),$D,$D
-+	vpaddd	0x80($ctx),$E,$E
-+	vmovdqu	$A,0x00($ctx)
-+	vmovdqu	$B,0x20($ctx)
-+	vmovdqu	$C,0x40($ctx)
-+	vmovdqu	$D,0x60($ctx)
-+	vmovdqu	$E,0x80($ctx)
-+
-+	vmovdqu	$t0,(%rbx)			# save counters
-+	lea	256+128(%rsp),%rbx
-+	vmovdqu	0x60($Tbl),$tx			# pbswap_mask
-+	dec	$num
-+	jnz	.Loop_avx2
-+
-+	#mov	`$REG_SZ*17+8`(%rsp),$num
-+	#lea	$REG_SZ($ctx),$ctx
-+	#lea	`16*$REG_SZ/4`($inp),$inp
-+	#dec	$num
-+	#jnz	.Loop_grande_avx2
-+
-+.Ldone_avx2:
-+	mov	`$REG_SZ*17`(%rsp),%rax		# original %rsp
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xd8(%rax),%xmm6
-+	movaps	-0xc8(%rax),%xmm7
-+	movaps	-0xb8(%rax),%xmm8
-+	movaps	-0xa8(%rax),%xmm9
-+	movaps	-0x98(%rax),%xmm10
-+	movaps	-0x88(%rax),%xmm11
-+	movaps	-0x78(%rax),%xmm12
-+	movaps	-0x68(%rax),%xmm13
-+	movaps	-0x58(%rax),%xmm14
-+	movaps	-0x48(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Lepilogue_avx2:
-+	ret
-+.size	sha1_multi_block_avx2,.-sha1_multi_block_avx2
-+___
-+						}	}}}
-+$code.=<<___;
-+
-+.align	256
-+	.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	# K_00_19
-+	.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	# K_00_19
-+K_XX_XX:
-+	.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	# K_20_39
-+	.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	# K_20_39
-+	.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	# K_40_59
-+	.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	# K_40_59
-+	.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	# K_60_79
-+	.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	# K_60_79
-+	.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	# pbswap
-+	.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	# pbswap
-+	.byte	0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0
-+	.asciz	"SHA1 multi-block transform for x86_64, CRYPTOGAMS by "
-+___
-+
-+if ($win64) {
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# end of prologue label
-+	cmp	%r10,%rbx		# context->Rip<.Lbody
-+	jb	.Lin_prologue
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
-+	jae	.Lin_prologue
-+
-+	mov	`16*17`(%rax),%rax	# pull saved stack pointer
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+
-+	lea	-24-10*16(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+___
-+$code.=<<___ if ($avx>1);
-+.type	avx2_handler,\@abi-omnipotent
-+.align	16
-+avx2_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# end of prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_prologue
-+
-+	mov	`32*17`($context),%rax	# pull saved stack pointer
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore cotnext->R12
-+	mov	%r13,224($context)	# restore cotnext->R13
-+	mov	%r14,232($context)	# restore cotnext->R14
-+	mov	%r15,240($context)	# restore cotnext->R15
-+
-+	lea	-56-10*16(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	jmp	.Lin_prologue
-+.size	avx2_handler,.-avx2_handler
-+___
-+$code.=<<___;
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_sha1_multi_block
-+	.rva	.LSEH_end_sha1_multi_block
-+	.rva	.LSEH_info_sha1_multi_block
-+	.rva	.LSEH_begin_sha1_multi_block_shaext
-+	.rva	.LSEH_end_sha1_multi_block_shaext
-+	.rva	.LSEH_info_sha1_multi_block_shaext
-+___
-+$code.=<<___ if ($avx);
-+	.rva	.LSEH_begin_sha1_multi_block_avx
-+	.rva	.LSEH_end_sha1_multi_block_avx
-+	.rva	.LSEH_info_sha1_multi_block_avx
-+___
-+$code.=<<___ if ($avx>1);
-+	.rva	.LSEH_begin_sha1_multi_block_avx2
-+	.rva	.LSEH_end_sha1_multi_block_avx2
-+	.rva	.LSEH_info_sha1_multi_block_avx2
-+___
-+$code.=<<___;
-+.section	.xdata
-+.align	8
-+.LSEH_info_sha1_multi_block:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lbody,.Lepilogue			# HandlerData[]
-+.LSEH_info_sha1_multi_block_shaext:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lbody_shaext,.Lepilogue_shaext	# HandlerData[]
-+___
-+$code.=<<___ if ($avx);
-+.LSEH_info_sha1_multi_block_avx:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lbody_avx,.Lepilogue_avx		# HandlerData[]
-+___
-+$code.=<<___ if ($avx>1);
-+.LSEH_info_sha1_multi_block_avx2:
-+	.byte	9,0,0,0
-+	.rva	avx2_handler
-+	.rva	.Lbody_avx2,.Lepilogue_avx2		# HandlerData[]
-+___
-+}
-+####################################################################
-+
-+sub rex {
-+  local *opcode=shift;
-+  my ($dst,$src)=@_;
-+  my $rex=0;
-+
-+    $rex|=0x04			if ($dst>=8);
-+    $rex|=0x01			if ($src>=8);
-+    unshift @opcode,$rex|0x40	if ($rex);
-+}
-+
-+sub sha1rnds4 {
-+    if (@_[0] =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x0f,0x3a,0xcc);
-+	rex(\@opcode,$3,$2);
-+	push @opcode,0xc0|($2&7)|(($3&7)<<3);		# ModR/M
-+	my $c=$1;
-+	push @opcode,$c=~/^0/?oct($c):$c;
-+	return ".byte\t".join(',',@opcode);
-+    } else {
-+	return "sha1rnds4\t".@_[0];
-+    }
-+}
-+
-+sub sha1op38 {
-+    my $instr = shift;
-+    my %opcodelet = (
-+		"sha1nexte" => 0xc8,
-+  		"sha1msg1"  => 0xc9,
-+		"sha1msg2"  => 0xca	);
-+
-+    if (defined($opcodelet{$instr}) && @_[0] =~ /%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x0f,0x38);
-+	rex(\@opcode,$2,$1);
-+	push @opcode,$opcodelet{$instr};
-+	push @opcode,0xc0|($1&7)|(($2&7)<<3);		# ModR/M
-+	return ".byte\t".join(',',@opcode);
-+    } else {
-+	return $instr."\t".@_[0];
-+    }
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval($1)/ge;
-+
-+	s/\b(sha1rnds4)\s+(.*)/sha1rnds4($2)/geo		or
-+	s/\b(sha1[^\s]*)\s+(.*)/sha1op38($1,$2)/geo		or
-+
-+	s/\b(vmov[dq])\b(.+)%ymm([0-9]+)/$1$2%xmm$3/go		or
-+	s/\b(vmovdqu)\b(.+)%x%ymm([0-9]+)/$1$2%xmm$3/go		or
-+	s/\b(vpinsr[qd])\b(.+)%ymm([0-9]+),%ymm([0-9]+)/$1$2%xmm$3,%xmm$4/go	or
-+	s/\b(vpextr[qd])\b(.+)%ymm([0-9]+)/$1$2%xmm$3/go	or
-+	s/\b(vinserti128)\b(\s+)%ymm/$1$2\$1,%xmm/go		or
-+	s/\b(vpbroadcast[qd]\s+)%ymm([0-9]+)/$1%xmm$2/go;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-mips.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-mips.pl
-new file mode 100644
-index 0000000..882f973
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-mips.pl
-@@ -0,0 +1,457 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# SHA1 block procedure for MIPS.
-+
-+# Performance improvement is 30% on unaligned input. The "secret" is
-+# to deploy lwl/lwr pair to load unaligned input. One could have
-+# vectorized Xupdate on MIPSIII/IV, but the goal was to code MIPS32-
-+# compatible subroutine. There is room for minor optimization on
-+# little-endian platforms...
-+
-+# September 2012.
-+#
-+# Add MIPS32r2 code (>25% less instructions).
-+
-+######################################################################
-+# There is a number of MIPS ABI in use, O32 and N32/64 are most
-+# widely used. Then there is a new contender: NUBI. It appears that if
-+# one picks the latter, it's possible to arrange code in ABI neutral
-+# manner. Therefore let's stick to NUBI register layout:
-+#
-+($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
-+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
-+($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
-+#
-+# The return value is placed in $a0. Following coding rules facilitate
-+# interoperability:
-+#
-+# - never ever touch $tp, "thread pointer", former $gp;
-+# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
-+#   old code];
-+# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
-+#
-+# For reference here is register layout for N32/64 MIPS ABIs:
-+#
-+# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
-+# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
-+# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
-+# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
-+#
-+$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64
-+
-+if ($flavour =~ /64|n32/i) {
-+	$PTR_ADD="dadd";	# incidentally works even on n32
-+	$PTR_SUB="dsub";	# incidentally works even on n32
-+	$REG_S="sd";
-+	$REG_L="ld";
-+	$PTR_SLL="dsll";	# incidentally works even on n32
-+	$SZREG=8;
-+} else {
-+	$PTR_ADD="add";
-+	$PTR_SUB="sub";
-+	$REG_S="sw";
-+	$REG_L="lw";
-+	$PTR_SLL="sll";
-+	$SZREG=4;
-+}
-+#
-+# 
-+#
-+######################################################################
-+
-+$big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC});
-+
-+for (@ARGV) {	$output=$_ if (/\w[\w\-]*\.\w+$/);   }
-+open STDOUT,">$output";
-+
-+if (!defined($big_endian))
-+            {   $big_endian=(unpack('L',pack('N',1))==1);   }
-+
-+# offsets of the Most and Least Significant Bytes
-+$MSB=$big_endian?0:3;
-+$LSB=3&~$MSB;
-+
-+@X=map("\$$_",(8..23));	# a4-a7,s0-s11
-+
-+$ctx=$a0;
-+$inp=$a1;
-+$num=$a2;
-+$A="\$1";
-+$B="\$2";
-+$C="\$3";
-+$D="\$7";
-+$E="\$24";	@V=($A,$B,$C,$D,$E);
-+$t0="\$25";
-+$t1=$num;	# $num is offloaded to stack
-+$t2="\$30";	# fp
-+$K="\$31";	# ra
-+
-+sub BODY_00_14 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___	if (!$big_endian);
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	wsbh	@X[$i],@X[$i]	# byte swap($i)
-+	rotr	@X[$i],@X[$i],16
-+#else
-+	srl	$t0,@X[$i],24	# byte swap($i)
-+	srl	$t1,@X[$i],8
-+	andi	$t2,@X[$i],0xFF00
-+	sll	@X[$i],@X[$i],24
-+	andi	$t1,0xFF00
-+	sll	$t2,$t2,8
-+	or	@X[$i],$t0
-+	or	$t1,$t2
-+	or	@X[$i],$t1
-+#endif
-+___
-+$code.=<<___;
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	addu	$e,$K		# $i
-+	xor	$t0,$c,$d
-+	rotr	$t1,$a,27
-+	 lwl	@X[$j],$j*4+$MSB($inp)
-+	and	$t0,$b
-+	addu	$e,$t1
-+	 lwr	@X[$j],$j*4+$LSB($inp)
-+	xor	$t0,$d
-+	addu	$e,@X[$i]
-+	rotr	$b,$b,2
-+	addu	$e,$t0
-+#else
-+	 lwl	@X[$j],$j*4+$MSB($inp)
-+	sll	$t0,$a,5	# $i
-+	addu	$e,$K
-+	 lwr	@X[$j],$j*4+$LSB($inp)
-+	srl	$t1,$a,27
-+	addu	$e,$t0
-+	xor	$t0,$c,$d
-+	addu	$e,$t1
-+	sll	$t2,$b,30
-+	and	$t0,$b
-+	srl	$b,$b,2
-+	xor	$t0,$d
-+	addu	$e,@X[$i]
-+	or	$b,$t2
-+	addu	$e,$t0
-+#endif
-+___
-+}
-+
-+sub BODY_15_19 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+
-+$code.=<<___	if (!$big_endian && $i==15);
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	wsbh	@X[$i],@X[$i]	# byte swap($i)
-+	rotr	@X[$i],@X[$i],16
-+#else
-+	srl	$t0,@X[$i],24	# byte swap($i)
-+	srl	$t1,@X[$i],8
-+	andi	$t2,@X[$i],0xFF00
-+	sll	@X[$i],@X[$i],24
-+	andi	$t1,0xFF00
-+	sll	$t2,$t2,8
-+	or	@X[$i],$t0
-+	or	@X[$i],$t1
-+	or	@X[$i],$t2
-+#endif
-+___
-+$code.=<<___;
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	addu	$e,$K		# $i
-+	 xor	@X[$j%16],@X[($j+2)%16]
-+	xor	$t0,$c,$d
-+	rotr	$t1,$a,27
-+	 xor	@X[$j%16],@X[($j+8)%16]
-+	and	$t0,$b
-+	addu	$e,$t1
-+	 xor	@X[$j%16],@X[($j+13)%16]
-+	xor	$t0,$d
-+	addu	$e,@X[$i%16]
-+	 rotr	@X[$j%16],@X[$j%16],31
-+	rotr	$b,$b,2
-+	addu	$e,$t0
-+#else
-+	 xor	@X[$j%16],@X[($j+2)%16]
-+	sll	$t0,$a,5	# $i
-+	addu	$e,$K
-+	srl	$t1,$a,27
-+	addu	$e,$t0
-+	 xor	@X[$j%16],@X[($j+8)%16]
-+	xor	$t0,$c,$d
-+	addu	$e,$t1
-+	 xor	@X[$j%16],@X[($j+13)%16]
-+	sll	$t2,$b,30
-+	and	$t0,$b
-+	 srl	$t1,@X[$j%16],31
-+	 addu	@X[$j%16],@X[$j%16]
-+	srl	$b,$b,2
-+	xor	$t0,$d
-+	 or	@X[$j%16],$t1
-+	addu	$e,@X[$i%16]
-+	or	$b,$t2
-+	addu	$e,$t0
-+#endif
-+___
-+}
-+
-+sub BODY_20_39 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___ if ($i<79);
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	 xor	@X[$j%16],@X[($j+2)%16]
-+	addu	$e,$K		# $i
-+	rotr	$t1,$a,27
-+	 xor	@X[$j%16],@X[($j+8)%16]
-+	xor	$t0,$c,$d
-+	addu	$e,$t1
-+	 xor	@X[$j%16],@X[($j+13)%16]
-+	xor	$t0,$b
-+	addu	$e,@X[$i%16]
-+	 rotr	@X[$j%16],@X[$j%16],31
-+	rotr	$b,$b,2
-+	addu	$e,$t0
-+#else
-+	 xor	@X[$j%16],@X[($j+2)%16]
-+	sll	$t0,$a,5	# $i
-+	addu	$e,$K
-+	srl	$t1,$a,27
-+	addu	$e,$t0
-+	 xor	@X[$j%16],@X[($j+8)%16]
-+	xor	$t0,$c,$d
-+	addu	$e,$t1
-+	 xor	@X[$j%16],@X[($j+13)%16]
-+	sll	$t2,$b,30
-+	xor	$t0,$b
-+	 srl	$t1,@X[$j%16],31
-+	 addu	@X[$j%16],@X[$j%16]
-+	srl	$b,$b,2
-+	addu	$e,@X[$i%16]
-+	 or	@X[$j%16],$t1
-+	or	$b,$t2
-+	addu	$e,$t0
-+#endif
-+___
-+$code.=<<___ if ($i==79);
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	 lw	@X[0],0($ctx)
-+	addu	$e,$K		# $i
-+	 lw	@X[1],4($ctx)
-+	rotr	$t1,$a,27
-+	 lw	@X[2],8($ctx)
-+	xor	$t0,$c,$d
-+	addu	$e,$t1
-+	 lw	@X[3],12($ctx)
-+	xor	$t0,$b
-+	addu	$e,@X[$i%16]
-+	 lw	@X[4],16($ctx)
-+	rotr	$b,$b,2
-+	addu	$e,$t0
-+#else
-+	 lw	@X[0],0($ctx)
-+	sll	$t0,$a,5	# $i
-+	addu	$e,$K
-+	 lw	@X[1],4($ctx)
-+	srl	$t1,$a,27
-+	addu	$e,$t0
-+	 lw	@X[2],8($ctx)
-+	xor	$t0,$c,$d
-+	addu	$e,$t1
-+	 lw	@X[3],12($ctx)
-+	sll	$t2,$b,30
-+	xor	$t0,$b
-+	 lw	@X[4],16($ctx)
-+	srl	$b,$b,2
-+	addu	$e,@X[$i%16]
-+	or	$b,$t2
-+	addu	$e,$t0
-+#endif
-+___
-+}
-+
-+sub BODY_40_59 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___ if ($i<79);
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	addu	$e,$K		# $i
-+	and	$t0,$c,$d
-+	 xor	@X[$j%16],@X[($j+2)%16]
-+	rotr	$t1,$a,27
-+	addu	$e,$t0
-+	 xor	@X[$j%16],@X[($j+8)%16]
-+	xor	$t0,$c,$d
-+	addu	$e,$t1
-+	 xor	@X[$j%16],@X[($j+13)%16]
-+	and	$t0,$b
-+	addu	$e,@X[$i%16]
-+	 rotr	@X[$j%16],@X[$j%16],31
-+	rotr	$b,$b,2
-+	addu	$e,$t0
-+#else
-+	 xor	@X[$j%16],@X[($j+2)%16]
-+	sll	$t0,$a,5	# $i
-+	addu	$e,$K
-+	srl	$t1,$a,27
-+	addu	$e,$t0
-+	 xor	@X[$j%16],@X[($j+8)%16]
-+	and	$t0,$c,$d
-+	addu	$e,$t1
-+	 xor	@X[$j%16],@X[($j+13)%16]
-+	sll	$t2,$b,30
-+	addu	$e,$t0
-+	 srl	$t1,@X[$j%16],31
-+	xor	$t0,$c,$d
-+	 addu	@X[$j%16],@X[$j%16]
-+	and	$t0,$b
-+	srl	$b,$b,2
-+	 or	@X[$j%16],$t1
-+	addu	$e,@X[$i%16]
-+	or	$b,$t2
-+	addu	$e,$t0
-+#endif
-+___
-+}
-+
-+$FRAMESIZE=16;	# large enough to accommodate NUBI saved registers
-+$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? "0xc0fff008" : "0xc0ff0000";
-+
-+$code=<<___;
-+#ifdef OPENSSL_FIPSCANISTER
-+# include 
-+#endif
-+
-+#if defined(__mips_smartmips) && !defined(_MIPS_ARCH_MIPS32R2)
-+#define _MIPS_ARCH_MIPS32R2
-+#endif
-+
-+.text
-+
-+.set	noat
-+.set	noreorder
-+.align	5
-+.globl	sha1_block_data_order
-+.ent	sha1_block_data_order
-+sha1_block_data_order:
-+	.frame	$sp,$FRAMESIZE*$SZREG,$ra
-+	.mask	$SAVED_REGS_MASK,-$SZREG
-+	.set	noreorder
-+	$PTR_SUB $sp,$FRAMESIZE*$SZREG
-+	$REG_S	$ra,($FRAMESIZE-1)*$SZREG($sp)
-+	$REG_S	$fp,($FRAMESIZE-2)*$SZREG($sp)
-+	$REG_S	$s11,($FRAMESIZE-3)*$SZREG($sp)
-+	$REG_S	$s10,($FRAMESIZE-4)*$SZREG($sp)
-+	$REG_S	$s9,($FRAMESIZE-5)*$SZREG($sp)
-+	$REG_S	$s8,($FRAMESIZE-6)*$SZREG($sp)
-+	$REG_S	$s7,($FRAMESIZE-7)*$SZREG($sp)
-+	$REG_S	$s6,($FRAMESIZE-8)*$SZREG($sp)
-+	$REG_S	$s5,($FRAMESIZE-9)*$SZREG($sp)
-+	$REG_S	$s4,($FRAMESIZE-10)*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
-+	$REG_S	$s3,($FRAMESIZE-11)*$SZREG($sp)
-+	$REG_S	$s2,($FRAMESIZE-12)*$SZREG($sp)
-+	$REG_S	$s1,($FRAMESIZE-13)*$SZREG($sp)
-+	$REG_S	$s0,($FRAMESIZE-14)*$SZREG($sp)
-+	$REG_S	$gp,($FRAMESIZE-15)*$SZREG($sp)
-+___
-+$code.=<<___;
-+	$PTR_SLL $num,6
-+	$PTR_ADD $num,$inp
-+	$REG_S	$num,0($sp)
-+	lw	$A,0($ctx)
-+	lw	$B,4($ctx)
-+	lw	$C,8($ctx)
-+	lw	$D,12($ctx)
-+	b	.Loop
-+	lw	$E,16($ctx)
-+.align	4
-+.Loop:
-+	.set	reorder
-+	lwl	@X[0],$MSB($inp)
-+	lui	$K,0x5a82
-+	lwr	@X[0],$LSB($inp)
-+	ori	$K,0x7999	# K_00_19
-+___
-+for ($i=0;$i<15;$i++)	{ &BODY_00_14($i,@V); unshift(@V,pop(@V)); }
-+for (;$i<20;$i++)	{ &BODY_15_19($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	lui	$K,0x6ed9
-+	ori	$K,0xeba1	# K_20_39
-+___
-+for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	lui	$K,0x8f1b
-+	ori	$K,0xbcdc	# K_40_59
-+___
-+for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	lui	$K,0xca62
-+	ori	$K,0xc1d6	# K_60_79
-+___
-+for (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	$PTR_ADD $inp,64
-+	$REG_L	$num,0($sp)
-+
-+	addu	$A,$X[0]
-+	addu	$B,$X[1]
-+	sw	$A,0($ctx)
-+	addu	$C,$X[2]
-+	addu	$D,$X[3]
-+	sw	$B,4($ctx)
-+	addu	$E,$X[4]
-+	sw	$C,8($ctx)
-+	sw	$D,12($ctx)
-+	sw	$E,16($ctx)
-+	.set	noreorder
-+	bne	$inp,$num,.Loop
-+	nop
-+
-+	.set	noreorder
-+	$REG_L	$ra,($FRAMESIZE-1)*$SZREG($sp)
-+	$REG_L	$fp,($FRAMESIZE-2)*$SZREG($sp)
-+	$REG_L	$s11,($FRAMESIZE-3)*$SZREG($sp)
-+	$REG_L	$s10,($FRAMESIZE-4)*$SZREG($sp)
-+	$REG_L	$s9,($FRAMESIZE-5)*$SZREG($sp)
-+	$REG_L	$s8,($FRAMESIZE-6)*$SZREG($sp)
-+	$REG_L	$s7,($FRAMESIZE-7)*$SZREG($sp)
-+	$REG_L	$s6,($FRAMESIZE-8)*$SZREG($sp)
-+	$REG_L	$s5,($FRAMESIZE-9)*$SZREG($sp)
-+	$REG_L	$s4,($FRAMESIZE-10)*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$s3,($FRAMESIZE-11)*$SZREG($sp)
-+	$REG_L	$s2,($FRAMESIZE-12)*$SZREG($sp)
-+	$REG_L	$s1,($FRAMESIZE-13)*$SZREG($sp)
-+	$REG_L	$s0,($FRAMESIZE-14)*$SZREG($sp)
-+	$REG_L	$gp,($FRAMESIZE-15)*$SZREG($sp)
-+___
-+$code.=<<___;
-+	jr	$ra
-+	$PTR_ADD $sp,$FRAMESIZE*$SZREG
-+.end	sha1_block_data_order
-+.rdata
-+.asciiz	"SHA1 for MIPS, CRYPTOGAMS by "
-+___
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-parisc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-parisc.pl
-new file mode 100644
-index 0000000..a85d126
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-parisc.pl
-@@ -0,0 +1,267 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# SHA1 block procedure for PA-RISC.
-+
-+# June 2009.
-+#
-+# On PA-7100LC performance is >30% better than gcc 3.2 generated code
-+# for aligned input and >50% better for unaligned. Compared to vendor
-+# compiler on PA-8600 it's almost 60% faster in 64-bit build and just
-+# few percent faster in 32-bit one (this for aligned input, data for
-+# unaligned input is not available).
-+#
-+# Special thanks to polarhome.com for providing HP-UX account.
-+
-+$flavour = shift;
-+$output = shift;
-+open STDOUT,">$output";
-+
-+if ($flavour =~ /64/) {
-+	$LEVEL		="2.0W";
-+	$SIZE_T		=8;
-+	$FRAME_MARKER	=80;
-+	$SAVED_RP	=16;
-+	$PUSH		="std";
-+	$PUSHMA		="std,ma";
-+	$POP		="ldd";
-+	$POPMB		="ldd,mb";
-+} else {
-+	$LEVEL		="1.0";
-+	$SIZE_T		=4;
-+	$FRAME_MARKER	=48;
-+	$SAVED_RP	=20;
-+	$PUSH		="stw";
-+	$PUSHMA		="stwm";
-+	$POP		="ldw";
-+	$POPMB		="ldwm";
-+}
-+
-+$FRAME=14*$SIZE_T+$FRAME_MARKER;# 14 saved regs + frame marker
-+				#                 [+ argument transfer]
-+$ctx="%r26";		# arg0
-+$inp="%r25";		# arg1
-+$num="%r24";		# arg2
-+
-+$t0="%r28";
-+$t1="%r29";
-+$K="%r31";
-+
-+@X=("%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8",
-+    "%r9", "%r10","%r11","%r12","%r13","%r14","%r15","%r16",$t0);
-+
-+@V=($A,$B,$C,$D,$E)=("%r19","%r20","%r21","%r22","%r23");
-+
-+sub BODY_00_19 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___ if ($i<15);
-+	addl	$K,$e,$e	; $i
-+	shd	$a,$a,27,$t1
-+	addl	@X[$i],$e,$e
-+	and	$c,$b,$t0
-+	addl	$t1,$e,$e
-+	andcm	$d,$b,$t1
-+	shd	$b,$b,2,$b
-+	or	$t1,$t0,$t0
-+	addl	$t0,$e,$e
-+___
-+$code.=<<___ if ($i>=15);	# with forward Xupdate
-+	addl	$K,$e,$e	; $i
-+	shd	$a,$a,27,$t1
-+	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]
-+	addl	@X[$i%16],$e,$e
-+	and	$c,$b,$t0
-+	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
-+	addl	$t1,$e,$e
-+	andcm	$d,$b,$t1
-+	shd	$b,$b,2,$b
-+	or	$t1,$t0,$t0
-+	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
-+	add	$t0,$e,$e
-+	shd	@X[$j%16],@X[$j%16],31,@X[$j%16]
-+___
-+}
-+
-+sub BODY_20_39 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___ if ($i<79);
-+	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]	; $i
-+	addl	$K,$e,$e
-+	shd	$a,$a,27,$t1
-+	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
-+	addl	@X[$i%16],$e,$e
-+	xor	$b,$c,$t0
-+	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
-+	addl	$t1,$e,$e
-+	shd	$b,$b,2,$b
-+	xor	$d,$t0,$t0
-+	shd	@X[$j%16],@X[$j%16],31,@X[$j%16]
-+	addl	$t0,$e,$e
-+___
-+$code.=<<___ if ($i==79);	# with context load
-+	ldw	0($ctx),@X[0]	; $i
-+	addl	$K,$e,$e
-+	shd	$a,$a,27,$t1
-+	ldw	4($ctx),@X[1]
-+	addl	@X[$i%16],$e,$e
-+	xor	$b,$c,$t0
-+	ldw	8($ctx),@X[2]
-+	addl	$t1,$e,$e
-+	shd	$b,$b,2,$b
-+	xor	$d,$t0,$t0
-+	ldw	12($ctx),@X[3]
-+	addl	$t0,$e,$e
-+	ldw	16($ctx),@X[4]
-+___
-+}
-+
-+sub BODY_40_59 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___;
-+	shd	$a,$a,27,$t1	; $i
-+	addl	$K,$e,$e
-+	xor	@X[($j+2)%16],@X[$j%16],@X[$j%16]
-+	xor	$d,$c,$t0
-+	addl	@X[$i%16],$e,$e
-+	xor	@X[($j+8)%16],@X[$j%16],@X[$j%16]
-+	and	$b,$t0,$t0
-+	addl	$t1,$e,$e
-+	shd	$b,$b,2,$b
-+	xor	@X[($j+13)%16],@X[$j%16],@X[$j%16]
-+	addl	$t0,$e,$e
-+	and	$d,$c,$t1
-+	shd	@X[$j%16],@X[$j%16],31,@X[$j%16]
-+	addl	$t1,$e,$e
-+___
-+}
-+
-+$code=<<___;
-+	.LEVEL	$LEVEL
-+	.SPACE	\$TEXT\$
-+	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
-+
-+	.EXPORT	sha1_block_data_order,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
-+sha1_block_data_order
-+	.PROC
-+	.CALLINFO	FRAME=`$FRAME-14*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=16
-+	.ENTRY
-+	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
-+	$PUSHMA	%r3,$FRAME(%sp)
-+	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
-+	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
-+	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
-+	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
-+	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
-+	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
-+	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
-+	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
-+	$PUSH	%r12,`-$FRAME+9*$SIZE_T`(%sp)
-+	$PUSH	%r13,`-$FRAME+10*$SIZE_T`(%sp)
-+	$PUSH	%r14,`-$FRAME+11*$SIZE_T`(%sp)
-+	$PUSH	%r15,`-$FRAME+12*$SIZE_T`(%sp)
-+	$PUSH	%r16,`-$FRAME+13*$SIZE_T`(%sp)
-+
-+	ldw	0($ctx),$A
-+	ldw	4($ctx),$B
-+	ldw	8($ctx),$C
-+	ldw	12($ctx),$D
-+	ldw	16($ctx),$E
-+
-+	extru	$inp,31,2,$t0		; t0=inp&3;
-+	sh3addl	$t0,%r0,$t0		; t0*=8;
-+	subi	32,$t0,$t0		; t0=32-t0;
-+	mtctl	$t0,%cr11		; %sar=t0;
-+
-+L\$oop
-+	ldi	3,$t0
-+	andcm	$inp,$t0,$t0		; 64-bit neutral
-+___
-+	for ($i=0;$i<15;$i++) {		# load input block
-+	$code.="\tldw	`4*$i`($t0),@X[$i]\n";		}
-+$code.=<<___;
-+	cmpb,*=	$inp,$t0,L\$aligned
-+	ldw	60($t0),@X[15]
-+	ldw	64($t0),@X[16]
-+___
-+	for ($i=0;$i<16;$i++) {		# align input
-+	$code.="\tvshd	@X[$i],@X[$i+1],@X[$i]\n";	}
-+$code.=<<___;
-+L\$aligned
-+	ldil	L'0x5a827000,$K		; K_00_19
-+	ldo	0x999($K),$K
-+___
-+for ($i=0;$i<20;$i++)   { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	ldil	L'0x6ed9e000,$K		; K_20_39
-+	ldo	0xba1($K),$K
-+___
-+
-+for (;$i<40;$i++)       { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	ldil	L'0x8f1bb000,$K		; K_40_59
-+	ldo	0xcdc($K),$K
-+___
-+
-+for (;$i<60;$i++)       { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	ldil	L'0xca62c000,$K		; K_60_79
-+	ldo	0x1d6($K),$K
-+___
-+for (;$i<80;$i++)       { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+
-+$code.=<<___;
-+	addl	@X[0],$A,$A
-+	addl	@X[1],$B,$B
-+	addl	@X[2],$C,$C
-+	addl	@X[3],$D,$D
-+	addl	@X[4],$E,$E
-+	stw	$A,0($ctx)
-+	stw	$B,4($ctx)
-+	stw	$C,8($ctx)
-+	stw	$D,12($ctx)
-+	stw	$E,16($ctx)
-+	addib,*<> -1,$num,L\$oop
-+	ldo	64($inp),$inp
-+
-+	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2	; standard epilogue
-+	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
-+	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
-+	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
-+	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
-+	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
-+	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
-+	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
-+	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
-+	$POP	`-$FRAME+9*$SIZE_T`(%sp),%r12
-+	$POP	`-$FRAME+10*$SIZE_T`(%sp),%r13
-+	$POP	`-$FRAME+11*$SIZE_T`(%sp),%r14
-+	$POP	`-$FRAME+12*$SIZE_T`(%sp),%r15
-+	$POP	`-$FRAME+13*$SIZE_T`(%sp),%r16
-+	bv	(%r2)
-+	.EXIT
-+	$POPMB	-$FRAME(%sp),%r3
-+	.PROCEND
-+	.STRINGZ "SHA1 block transform for PA-RISC, CRYPTOGAMS by "
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+$code =~ s/,\*/,/gm		if ($SIZE_T==4);
-+$code =~ s/\bbv\b/bve/gm	if ($SIZE_T==8);
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-ppc.pl
-new file mode 100755
-index 0000000..add5a9e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-ppc.pl
-@@ -0,0 +1,351 @@
-+#! /usr/bin/env perl
-+# Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# I let hardware handle unaligned input(*), except on page boundaries
-+# (see below for details). Otherwise straightforward implementation
-+# with X vector in register bank.
-+#
-+# (*) this means that this module is inappropriate for PPC403? Does
-+#     anybody know if pre-POWER3 can sustain unaligned load?
-+
-+# 			-m64	-m32
-+# ----------------------------------
-+# PPC970,gcc-4.0.0	+76%	+59%
-+# Power6,xlc-7		+68%	+33%
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /64/) {
-+	$SIZE_T	=8;
-+	$LRSAVE	=2*$SIZE_T;
-+	$UCMP	="cmpld";
-+	$STU	="stdu";
-+	$POP	="ld";
-+	$PUSH	="std";
-+} elsif ($flavour =~ /32/) {
-+	$SIZE_T	=4;
-+	$LRSAVE	=$SIZE_T;
-+	$UCMP	="cmplw";
-+	$STU	="stwu";
-+	$POP	="lwz";
-+	$PUSH	="stw";
-+} else { die "nonsense $flavour"; }
-+
-+# Define endianness based on flavour
-+# i.e.: linux64le
-+$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
-+
-+$FRAME=24*$SIZE_T+64;
-+$LOCALS=6*$SIZE_T;
-+
-+$K  ="r0";
-+$sp ="r1";
-+$toc="r2";
-+$ctx="r3";
-+$inp="r4";
-+$num="r5";
-+$t0 ="r15";
-+$t1 ="r6";
-+
-+$A  ="r7";
-+$B  ="r8";
-+$C  ="r9";
-+$D  ="r10";
-+$E  ="r11";
-+$T  ="r12";
-+
-+@V=($A,$B,$C,$D,$E,$T);
-+@X=("r16","r17","r18","r19","r20","r21","r22","r23",
-+    "r24","r25","r26","r27","r28","r29","r30","r31");
-+
-+sub loadbe {
-+my ($dst, $src, $temp_reg) = @_;
-+$code.=<<___ if (!$LITTLE_ENDIAN);
-+	lwz	$dst,$src
-+___
-+$code.=<<___ if ($LITTLE_ENDIAN);
-+	lwz	$temp_reg,$src
-+	rotlwi	$dst,$temp_reg,8
-+	rlwimi	$dst,$temp_reg,24,0,7
-+	rlwimi	$dst,$temp_reg,24,16,23
-+___
-+}
-+
-+sub BODY_00_19 {
-+my ($i,$a,$b,$c,$d,$e,$f)=@_;
-+my $j=$i+1;
-+
-+	# Since the last value of $f is discarded, we can use
-+	# it as a temp reg to swap byte-order when needed.
-+	loadbe("@X[$i]","`$i*4`($inp)",$f) if ($i==0);
-+	loadbe("@X[$j]","`$j*4`($inp)",$f) if ($i<15);
-+$code.=<<___ if ($i<15);
-+	add	$f,$K,$e
-+	rotlwi	$e,$a,5
-+	add	$f,$f,@X[$i]
-+	and	$t0,$c,$b
-+	add	$f,$f,$e
-+	andc	$t1,$d,$b
-+	rotlwi	$b,$b,30
-+	or	$t0,$t0,$t1
-+	add	$f,$f,$t0
-+___
-+$code.=<<___ if ($i>=15);
-+	add	$f,$K,$e
-+	rotlwi	$e,$a,5
-+	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
-+	add	$f,$f,@X[$i%16]
-+	and	$t0,$c,$b
-+	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
-+	add	$f,$f,$e
-+	andc	$t1,$d,$b
-+	rotlwi	$b,$b,30
-+	or	$t0,$t0,$t1
-+	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
-+	add	$f,$f,$t0
-+	rotlwi	@X[$j%16],@X[$j%16],1
-+___
-+}
-+
-+sub BODY_20_39 {
-+my ($i,$a,$b,$c,$d,$e,$f)=@_;
-+my $j=$i+1;
-+$code.=<<___ if ($i<79);
-+	add	$f,$K,$e
-+	xor	$t0,$b,$d
-+	rotlwi	$e,$a,5
-+	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
-+	add	$f,$f,@X[$i%16]
-+	xor	$t0,$t0,$c
-+	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
-+	add	$f,$f,$t0
-+	rotlwi	$b,$b,30
-+	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
-+	add	$f,$f,$e
-+	rotlwi	@X[$j%16],@X[$j%16],1
-+___
-+$code.=<<___ if ($i==79);
-+	add	$f,$K,$e
-+	xor	$t0,$b,$d
-+	rotlwi	$e,$a,5
-+	lwz	r16,0($ctx)
-+	add	$f,$f,@X[$i%16]
-+	xor	$t0,$t0,$c
-+	lwz	r17,4($ctx)
-+	add	$f,$f,$t0
-+	rotlwi	$b,$b,30
-+	lwz	r18,8($ctx)
-+	lwz	r19,12($ctx)
-+	add	$f,$f,$e
-+	lwz	r20,16($ctx)
-+___
-+}
-+
-+sub BODY_40_59 {
-+my ($i,$a,$b,$c,$d,$e,$f)=@_;
-+my $j=$i+1;
-+$code.=<<___;
-+	add	$f,$K,$e
-+	rotlwi	$e,$a,5
-+	xor	@X[$j%16],@X[$j%16],@X[($j+2)%16]
-+	add	$f,$f,@X[$i%16]
-+	and	$t0,$b,$c
-+	xor	@X[$j%16],@X[$j%16],@X[($j+8)%16]
-+	add	$f,$f,$e
-+	or	$t1,$b,$c
-+	rotlwi	$b,$b,30
-+	xor	@X[$j%16],@X[$j%16],@X[($j+13)%16]
-+	and	$t1,$t1,$d
-+	or	$t0,$t0,$t1
-+	rotlwi	@X[$j%16],@X[$j%16],1
-+	add	$f,$f,$t0
-+___
-+}
-+
-+$code=<<___;
-+.machine	"any"
-+.text
-+
-+.globl	.sha1_block_data_order
-+.align	4
-+.sha1_block_data_order:
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
-+	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
-+	lwz	$A,0($ctx)
-+	lwz	$B,4($ctx)
-+	lwz	$C,8($ctx)
-+	lwz	$D,12($ctx)
-+	lwz	$E,16($ctx)
-+	andi.	r0,$inp,3
-+	bne	Lunaligned
-+Laligned:
-+	mtctr	$num
-+	bl	Lsha1_block_private
-+	b	Ldone
-+
-+; PowerPC specification allows an implementation to be ill-behaved
-+; upon unaligned access which crosses page boundary. "Better safe
-+; than sorry" principle makes me treat it specially. But I don't
-+; look for particular offending word, but rather for 64-byte input
-+; block which crosses the boundary. Once found that block is aligned
-+; and hashed separately...
-+.align	4
-+Lunaligned:
-+	subfic	$t1,$inp,4096
-+	andi.	$t1,$t1,4095	; distance to closest page boundary
-+	srwi.	$t1,$t1,6	; t1/=64
-+	beq	Lcross_page
-+	$UCMP	$num,$t1
-+	ble	Laligned	; didn't cross the page boundary
-+	mtctr	$t1
-+	subfc	$num,$t1,$num
-+	bl	Lsha1_block_private
-+Lcross_page:
-+	li	$t1,16
-+	mtctr	$t1
-+	addi	r20,$sp,$LOCALS	; spot within the frame
-+Lmemcpy:
-+	lbz	r16,0($inp)
-+	lbz	r17,1($inp)
-+	lbz	r18,2($inp)
-+	lbz	r19,3($inp)
-+	addi	$inp,$inp,4
-+	stb	r16,0(r20)
-+	stb	r17,1(r20)
-+	stb	r18,2(r20)
-+	stb	r19,3(r20)
-+	addi	r20,r20,4
-+	bdnz	Lmemcpy
-+
-+	$PUSH	$inp,`$FRAME-$SIZE_T*18`($sp)
-+	li	$t1,1
-+	addi	$inp,$sp,$LOCALS
-+	mtctr	$t1
-+	bl	Lsha1_block_private
-+	$POP	$inp,`$FRAME-$SIZE_T*18`($sp)
-+	addic.	$num,$num,-1
-+	bne	Lunaligned
-+
-+Ldone:
-+	$POP	r0,`$FRAME+$LRSAVE`($sp)
-+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
-+	mtlr	r0
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,18,3,0
-+	.long	0
-+___
-+
-+# This is private block function, which uses tailored calling
-+# interface, namely upon entry SHA_CTX is pre-loaded to given
-+# registers and counter register contains amount of chunks to
-+# digest...
-+$code.=<<___;
-+.align	4
-+Lsha1_block_private:
-+___
-+$code.=<<___;	# load K_00_19
-+	lis	$K,0x5a82
-+	ori	$K,$K,0x7999
-+___
-+for($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;	# load K_20_39
-+	lis	$K,0x6ed9
-+	ori	$K,$K,0xeba1
-+___
-+for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;	# load K_40_59
-+	lis	$K,0x8f1b
-+	ori	$K,$K,0xbcdc
-+___
-+for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;	# load K_60_79
-+	lis	$K,0xca62
-+	ori	$K,$K,0xc1d6
-+___
-+for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	add	r16,r16,$E
-+	add	r17,r17,$T
-+	add	r18,r18,$A
-+	add	r19,r19,$B
-+	add	r20,r20,$C
-+	stw	r16,0($ctx)
-+	mr	$A,r16
-+	stw	r17,4($ctx)
-+	mr	$B,r17
-+	stw	r18,8($ctx)
-+	mr	$C,r18
-+	stw	r19,12($ctx)
-+	mr	$D,r19
-+	stw	r20,16($ctx)
-+	mr	$E,r20
-+	addi	$inp,$inp,`16*4`
-+	bdnz	Lsha1_block_private
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+.size	.sha1_block_data_order,.-.sha1_block_data_order
-+___
-+$code.=<<___;
-+.asciz	"SHA1 block transform for PPC, CRYPTOGAMS by "
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-s390x.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-s390x.pl
-new file mode 100644
-index 0000000..b19606c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-s390x.pl
-@@ -0,0 +1,251 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# SHA1 block procedure for s390x.
-+
-+# April 2007.
-+#
-+# Performance is >30% better than gcc 3.3 generated code. But the real
-+# twist is that SHA1 hardware support is detected and utilized. In
-+# which case performance can reach further >4.5x for larger chunks.
-+
-+# January 2009.
-+#
-+# Optimize Xupdate for amount of memory references and reschedule
-+# instructions to favour dual-issue z10 pipeline. On z10 hardware is
-+# "only" ~2.3x faster than software.
-+
-+# November 2010.
-+#
-+# Adapt for -m31 build. If kernel supports what's called "highgprs"
-+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
-+# instructions and achieve "64-bit" performance even in 31-bit legacy
-+# application context. The feature is not specific to any particular
-+# processor, as long as it's "z-CPU". Latter implies that the code
-+# remains z/Architecture specific. On z990 it was measured to perform
-+# 23% better than code generated by gcc 4.3.
-+
-+$kimdfunc=1;	# magic function code for kimd instruction
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /3[12]/) {
-+	$SIZE_T=4;
-+	$g="";
-+} else {
-+	$SIZE_T=8;
-+	$g="g";
-+}
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+$K_00_39="%r0"; $K=$K_00_39;
-+$K_40_79="%r1";
-+$ctx="%r2";	$prefetch="%r2";
-+$inp="%r3";
-+$len="%r4";
-+
-+$A="%r5";
-+$B="%r6";
-+$C="%r7";
-+$D="%r8";
-+$E="%r9";	@V=($A,$B,$C,$D,$E);
-+$t0="%r10";
-+$t1="%r11";
-+@X=("%r12","%r13","%r14");
-+$sp="%r15";
-+
-+$stdframe=16*$SIZE_T+4*8;
-+$frame=$stdframe+16*4;
-+
-+sub Xupdate {
-+my $i=shift;
-+
-+$code.=<<___ if ($i==15);
-+	lg	$prefetch,$stdframe($sp)	### Xupdate(16) warm-up
-+	lr	$X[0],$X[2]
-+___
-+return if ($i&1);	# Xupdate is vectorized and executed every 2nd cycle
-+$code.=<<___ if ($i<16);
-+	lg	$X[0],`$i*4`($inp)	### Xload($i)
-+	rllg	$X[1],$X[0],32
-+___
-+$code.=<<___ if ($i>=16);
-+	xgr	$X[0],$prefetch		### Xupdate($i)
-+	lg	$prefetch,`$stdframe+4*(($i+2)%16)`($sp)
-+	xg	$X[0],`$stdframe+4*(($i+8)%16)`($sp)
-+	xgr	$X[0],$prefetch
-+	rll	$X[0],$X[0],1
-+	rllg	$X[1],$X[0],32
-+	rll	$X[1],$X[1],1
-+	rllg	$X[0],$X[1],32
-+	lr	$X[2],$X[1]		# feedback
-+___
-+$code.=<<___ if ($i<=70);
-+	stg	$X[0],`$stdframe+4*($i%16)`($sp)
-+___
-+unshift(@X,pop(@X));
-+}
-+
-+sub BODY_00_19 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $xi=$X[1];
-+
-+	&Xupdate($i);
-+$code.=<<___;
-+	alr	$e,$K		### $i
-+	rll	$t1,$a,5
-+	lr	$t0,$d
-+	xr	$t0,$c
-+	alr	$e,$t1
-+	nr	$t0,$b
-+	alr	$e,$xi
-+	xr	$t0,$d
-+	rll	$b,$b,30
-+	alr	$e,$t0
-+___
-+}
-+
-+sub BODY_20_39 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $xi=$X[1];
-+
-+	&Xupdate($i);
-+$code.=<<___;
-+	alr	$e,$K		### $i
-+	rll	$t1,$a,5
-+	lr	$t0,$b
-+	alr	$e,$t1
-+	xr	$t0,$c
-+	alr	$e,$xi
-+	xr	$t0,$d
-+	rll	$b,$b,30
-+	alr	$e,$t0
-+___
-+}
-+
-+sub BODY_40_59 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $xi=$X[1];
-+
-+	&Xupdate($i);
-+$code.=<<___;
-+	alr	$e,$K		### $i
-+	rll	$t1,$a,5
-+	lr	$t0,$b
-+	alr	$e,$t1
-+	or	$t0,$c
-+	lr	$t1,$b
-+	nr	$t0,$d
-+	nr	$t1,$c
-+	alr	$e,$xi
-+	or	$t0,$t1
-+	rll	$b,$b,30
-+	alr	$e,$t0
-+___
-+}
-+
-+$code.=<<___;
-+.text
-+.align	64
-+.type	Ktable,\@object
-+Ktable: .long	0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6
-+	.skip	48	#.long	0,0,0,0,0,0,0,0,0,0,0,0
-+.size	Ktable,.-Ktable
-+.globl	sha1_block_data_order
-+.type	sha1_block_data_order,\@function
-+sha1_block_data_order:
-+___
-+$code.=<<___ if ($kimdfunc);
-+	larl	%r1,OPENSSL_s390xcap_P
-+	lg	%r0,0(%r1)
-+	tmhl	%r0,0x4000	# check for message-security assist
-+	jz	.Lsoftware
-+	lg	%r0,16(%r1)	# check kimd capabilities
-+	tmhh	%r0,`0x8000>>$kimdfunc`
-+	jz	.Lsoftware
-+	lghi	%r0,$kimdfunc
-+	lgr	%r1,$ctx
-+	lgr	%r2,$inp
-+	sllg	%r3,$len,6
-+	.long	0xb93e0002	# kimd %r0,%r2
-+	brc	1,.-4		# pay attention to "partial completion"
-+	br	%r14
-+.align	16
-+.Lsoftware:
-+___
-+$code.=<<___;
-+	lghi	%r1,-$frame
-+	st${g}	$ctx,`2*$SIZE_T`($sp)
-+	stm${g}	%r6,%r15,`6*$SIZE_T`($sp)
-+	lgr	%r0,$sp
-+	la	$sp,0(%r1,$sp)
-+	st${g}	%r0,0($sp)
-+
-+	larl	$t0,Ktable
-+	llgf	$A,0($ctx)
-+	llgf	$B,4($ctx)
-+	llgf	$C,8($ctx)
-+	llgf	$D,12($ctx)
-+	llgf	$E,16($ctx)
-+
-+	lg	$K_00_39,0($t0)
-+	lg	$K_40_79,8($t0)
-+
-+.Lloop:
-+	rllg	$K_00_39,$K_00_39,32
-+___
-+for ($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	rllg	$K_00_39,$K_00_39,32
-+___
-+for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;	$K=$K_40_79;
-+	rllg	$K_40_79,$K_40_79,32
-+___
-+for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	rllg	$K_40_79,$K_40_79,32
-+___
-+for (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+
-+	l${g}	$ctx,`$frame+2*$SIZE_T`($sp)
-+	la	$inp,64($inp)
-+	al	$A,0($ctx)
-+	al	$B,4($ctx)
-+	al	$C,8($ctx)
-+	al	$D,12($ctx)
-+	al	$E,16($ctx)
-+	st	$A,0($ctx)
-+	st	$B,4($ctx)
-+	st	$C,8($ctx)
-+	st	$D,12($ctx)
-+	st	$E,16($ctx)
-+	brct${g} $len,.Lloop
-+
-+	lm${g}	%r6,%r15,`$frame+6*$SIZE_T`($sp)
-+	br	%r14
-+.size	sha1_block_data_order,.-sha1_block_data_order
-+.string	"SHA1 block transform for s390x, CRYPTOGAMS by "
-+.comm	OPENSSL_s390xcap_P,80,8
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-sparcv9.pl
-new file mode 100644
-index 0000000..7437ff4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-sparcv9.pl
-@@ -0,0 +1,434 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+#
-+# Hardware SPARC T4 support by David S. Miller .
-+# ====================================================================
-+
-+# Performance improvement is not really impressive on pre-T1 CPU: +8%
-+# over Sun C and +25% over gcc [3.3]. While on T1, a.k.a. Niagara, it
-+# turned to be 40% faster than 64-bit code generated by Sun C 5.8 and
-+# >2x than 64-bit code generated by gcc 3.4. And there is a gimmick.
-+# X[16] vector is packed to 8 64-bit registers and as result nothing
-+# is spilled on stack. In addition input data is loaded in compact
-+# instruction sequence, thus minimizing the window when the code is
-+# subject to [inter-thread] cache-thrashing hazard. The goal is to
-+# ensure scalability on UltraSPARC T1, or rather to avoid decay when
-+# amount of active threads exceeds the number of physical cores.
-+
-+# SPARC T4 SHA1 hardware achieves 3.72 cycles per byte, which is 3.1x
-+# faster than software. Multi-process benchmark saturates at 11x
-+# single-process result on 8-core processor, or ~9GBps per 2.85GHz
-+# socket.
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
-+$rot1m="%g2";
-+$tmp64="%g3";
-+$Xi="%g4";
-+$A="%l0";
-+$B="%l1";
-+$C="%l2";
-+$D="%l3";
-+$E="%l4";
-+@V=($A,$B,$C,$D,$E);
-+$K_00_19="%l5";
-+$K_20_39="%l6";
-+$K_40_59="%l7";
-+$K_60_79="%g5";
-+@K=($K_00_19,$K_20_39,$K_40_59,$K_60_79);
-+
-+$ctx="%i0";
-+$inp="%i1";
-+$len="%i2";
-+$tmp0="%i3";
-+$tmp1="%i4";
-+$tmp2="%i5";
-+
-+sub BODY_00_15 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $xi=($i&1)?@X[($i/2)%8]:$Xi;
-+
-+$code.=<<___;
-+	sll	$a,5,$tmp0		!! $i
-+	add	@K[$i/20],$e,$e
-+	srl	$a,27,$tmp1
-+	add	$tmp0,$e,$e
-+	and	$c,$b,$tmp0
-+	add	$tmp1,$e,$e
-+	sll	$b,30,$tmp2
-+	andn	$d,$b,$tmp1
-+	srl	$b,2,$b
-+	or	$tmp1,$tmp0,$tmp1
-+	or	$tmp2,$b,$b
-+	add	$xi,$e,$e
-+___
-+if ($i&1 && $i<15) {
-+	$code.=
-+	"	srlx	@X[(($i+1)/2)%8],32,$Xi\n";
-+}
-+$code.=<<___;
-+	add	$tmp1,$e,$e
-+___
-+}
-+
-+sub Xupdate {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i/2;
-+
-+if ($i&1) {
-+$code.=<<___;
-+	sll	$a,5,$tmp0		!! $i
-+	add	@K[$i/20],$e,$e
-+	srl	$a,27,$tmp1
-+___
-+} else {
-+$code.=<<___;
-+	sllx	@X[($j+6)%8],32,$Xi	! Xupdate($i)
-+	xor	@X[($j+1)%8],@X[$j%8],@X[$j%8]
-+	srlx	@X[($j+7)%8],32,$tmp1
-+	xor	@X[($j+4)%8],@X[$j%8],@X[$j%8]
-+	sll	$a,5,$tmp0		!! $i
-+	or	$tmp1,$Xi,$Xi
-+	add	@K[$i/20],$e,$e		!!
-+	xor	$Xi,@X[$j%8],@X[$j%8]
-+	srlx	@X[$j%8],31,$Xi
-+	add	@X[$j%8],@X[$j%8],@X[$j%8]
-+	and	$Xi,$rot1m,$Xi
-+	andn	@X[$j%8],$rot1m,@X[$j%8]
-+	srl	$a,27,$tmp1		!!
-+	or	$Xi,@X[$j%8],@X[$j%8]
-+___
-+}
-+}
-+
-+sub BODY_16_19 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+
-+	&Xupdate(@_);
-+    if ($i&1) {
-+	$xi=@X[($i/2)%8];
-+    } else {
-+	$xi=$Xi;
-+	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
-+    }
-+$code.=<<___;
-+	add	$tmp0,$e,$e		!!
-+	and	$c,$b,$tmp0
-+	add	$tmp1,$e,$e
-+	sll	$b,30,$tmp2
-+	add	$xi,$e,$e
-+	andn	$d,$b,$tmp1
-+	srl	$b,2,$b
-+	or	$tmp1,$tmp0,$tmp1
-+	or	$tmp2,$b,$b
-+	add	$tmp1,$e,$e
-+___
-+}
-+
-+sub BODY_20_39 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $xi;
-+	&Xupdate(@_);
-+    if ($i&1) {
-+	$xi=@X[($i/2)%8];
-+    } else {
-+	$xi=$Xi;
-+	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
-+    }
-+$code.=<<___;
-+	add	$tmp0,$e,$e		!!
-+	xor	$c,$b,$tmp0
-+	add	$tmp1,$e,$e
-+	sll	$b,30,$tmp2
-+	xor	$d,$tmp0,$tmp1
-+	srl	$b,2,$b
-+	add	$tmp1,$e,$e
-+	or	$tmp2,$b,$b
-+	add	$xi,$e,$e
-+___
-+}
-+
-+sub BODY_40_59 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $xi;
-+	&Xupdate(@_);
-+    if ($i&1) {
-+	$xi=@X[($i/2)%8];
-+    } else {
-+	$xi=$Xi;
-+	$code.="\tsrlx	@X[($i/2)%8],32,$xi\n";
-+    }
-+$code.=<<___;
-+	add	$tmp0,$e,$e		!!
-+	and	$c,$b,$tmp0
-+	add	$tmp1,$e,$e
-+	sll	$b,30,$tmp2
-+	or	$c,$b,$tmp1
-+	srl	$b,2,$b
-+	and	$d,$tmp1,$tmp1
-+	add	$xi,$e,$e
-+	or	$tmp1,$tmp0,$tmp1
-+	or	$tmp2,$b,$b
-+	add	$tmp1,$e,$e
-+___
-+}
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#ifdef __arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+#endif
-+
-+.section	".text",#alloc,#execinstr
-+
-+#ifdef __PIC__
-+SPARC_PIC_THUNK(%g1)
-+#endif
-+
-+.align	32
-+.globl	sha1_block_data_order
-+sha1_block_data_order:
-+	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+	ld	[%g1+4],%g1		! OPENSSL_sparcv9cap_P[1]
-+
-+	andcc	%g1, CFR_SHA1, %g0
-+	be	.Lsoftware
-+	nop
-+
-+	ld	[%o0 + 0x00], %f0	! load context
-+	ld	[%o0 + 0x04], %f1
-+	ld	[%o0 + 0x08], %f2
-+	andcc	%o1, 0x7, %g0
-+	ld	[%o0 + 0x0c], %f3
-+	bne,pn	%icc, .Lhwunaligned
-+	 ld	[%o0 + 0x10], %f4
-+
-+.Lhw_loop:
-+	ldd	[%o1 + 0x00], %f8
-+	ldd	[%o1 + 0x08], %f10
-+	ldd	[%o1 + 0x10], %f12
-+	ldd	[%o1 + 0x18], %f14
-+	ldd	[%o1 + 0x20], %f16
-+	ldd	[%o1 + 0x28], %f18
-+	ldd	[%o1 + 0x30], %f20
-+	subcc	%o2, 1, %o2		! done yet? 
-+	ldd	[%o1 + 0x38], %f22
-+	add	%o1, 0x40, %o1
-+	prefetch [%o1 + 63], 20
-+
-+	.word	0x81b02820		! SHA1
-+
-+	bne,pt	SIZE_T_CC, .Lhw_loop
-+	nop
-+
-+.Lhwfinish:
-+	st	%f0, [%o0 + 0x00]	! store context
-+	st	%f1, [%o0 + 0x04]
-+	st	%f2, [%o0 + 0x08]
-+	st	%f3, [%o0 + 0x0c]
-+	retl
-+	st	%f4, [%o0 + 0x10]
-+
-+.align	8
-+.Lhwunaligned:
-+	alignaddr %o1, %g0, %o1
-+
-+	ldd	[%o1 + 0x00], %f10
-+.Lhwunaligned_loop:
-+	ldd	[%o1 + 0x08], %f12
-+	ldd	[%o1 + 0x10], %f14
-+	ldd	[%o1 + 0x18], %f16
-+	ldd	[%o1 + 0x20], %f18
-+	ldd	[%o1 + 0x28], %f20
-+	ldd	[%o1 + 0x30], %f22
-+	ldd	[%o1 + 0x38], %f24
-+	subcc	%o2, 1, %o2		! done yet?
-+	ldd	[%o1 + 0x40], %f26
-+	add	%o1, 0x40, %o1
-+	prefetch [%o1 + 63], 20
-+
-+	faligndata %f10, %f12, %f8
-+	faligndata %f12, %f14, %f10
-+	faligndata %f14, %f16, %f12
-+	faligndata %f16, %f18, %f14
-+	faligndata %f18, %f20, %f16
-+	faligndata %f20, %f22, %f18
-+	faligndata %f22, %f24, %f20
-+	faligndata %f24, %f26, %f22
-+
-+	.word	0x81b02820		! SHA1
-+
-+	bne,pt	SIZE_T_CC, .Lhwunaligned_loop
-+	for	%f26, %f26, %f10	! %f10=%f26
-+
-+	ba	.Lhwfinish
-+	nop
-+
-+.align	16
-+.Lsoftware:
-+	save	%sp,-STACK_FRAME,%sp
-+	sllx	$len,6,$len
-+	add	$inp,$len,$len
-+
-+	or	%g0,1,$rot1m
-+	sllx	$rot1m,32,$rot1m
-+	or	$rot1m,1,$rot1m
-+
-+	ld	[$ctx+0],$A
-+	ld	[$ctx+4],$B
-+	ld	[$ctx+8],$C
-+	ld	[$ctx+12],$D
-+	ld	[$ctx+16],$E
-+	andn	$inp,7,$tmp0
-+
-+	sethi	%hi(0x5a827999),$K_00_19
-+	or	$K_00_19,%lo(0x5a827999),$K_00_19
-+	sethi	%hi(0x6ed9eba1),$K_20_39
-+	or	$K_20_39,%lo(0x6ed9eba1),$K_20_39
-+	sethi	%hi(0x8f1bbcdc),$K_40_59
-+	or	$K_40_59,%lo(0x8f1bbcdc),$K_40_59
-+	sethi	%hi(0xca62c1d6),$K_60_79
-+	or	$K_60_79,%lo(0xca62c1d6),$K_60_79
-+
-+.Lloop:
-+	ldx	[$tmp0+0],@X[0]
-+	ldx	[$tmp0+16],@X[2]
-+	ldx	[$tmp0+32],@X[4]
-+	ldx	[$tmp0+48],@X[6]
-+	and	$inp,7,$tmp1
-+	ldx	[$tmp0+8],@X[1]
-+	sll	$tmp1,3,$tmp1
-+	ldx	[$tmp0+24],@X[3]
-+	subcc	%g0,$tmp1,$tmp2	! should be 64-$tmp1, but -$tmp1 works too
-+	ldx	[$tmp0+40],@X[5]
-+	bz,pt	%icc,.Laligned
-+	ldx	[$tmp0+56],@X[7]
-+
-+	sllx	@X[0],$tmp1,@X[0]
-+	ldx	[$tmp0+64],$tmp64
-+___
-+for($i=0;$i<7;$i++)
-+{   $code.=<<___;
-+	srlx	@X[$i+1],$tmp2,$Xi
-+	sllx	@X[$i+1],$tmp1,@X[$i+1]
-+	or	$Xi,@X[$i],@X[$i]
-+___
-+}
-+$code.=<<___;
-+	srlx	$tmp64,$tmp2,$tmp64
-+	or	$tmp64,@X[7],@X[7]
-+.Laligned:
-+	srlx	@X[0],32,$Xi
-+___
-+for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
-+for (;$i<20;$i++)	{ &BODY_16_19($i,@V); unshift(@V,pop(@V)); }
-+for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+for (;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+
-+	ld	[$ctx+0],@X[0]
-+	ld	[$ctx+4],@X[1]
-+	ld	[$ctx+8],@X[2]
-+	ld	[$ctx+12],@X[3]
-+	add	$inp,64,$inp
-+	ld	[$ctx+16],@X[4]
-+	cmp	$inp,$len
-+
-+	add	$A,@X[0],$A
-+	st	$A,[$ctx+0]
-+	add	$B,@X[1],$B
-+	st	$B,[$ctx+4]
-+	add	$C,@X[2],$C
-+	st	$C,[$ctx+8]
-+	add	$D,@X[3],$D
-+	st	$D,[$ctx+12]
-+	add	$E,@X[4],$E
-+	st	$E,[$ctx+16]
-+
-+	bne	SIZE_T_CC,.Lloop
-+	andn	$inp,7,$tmp0
-+
-+	ret
-+	restore
-+.type	sha1_block_data_order,#function
-+.size	sha1_block_data_order,(.-sha1_block_data_order)
-+.asciz	"SHA1 block transform for SPARCv9, CRYPTOGAMS by "
-+.align	4
-+___
-+
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my $ref,$opf;
-+my %visopf = (	"faligndata"	=> 0x048,
-+		"for"		=> 0x07c	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+sub unalignaddr {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my $ref="$mnemonic\t$rs1,$rs2,$rd";
-+
-+    foreach ($rs1,$rs2,$rd) {
-+	if (/%([goli])([0-7])/)	{ $_=$bias{$1}+$2; }
-+	else			{ return $ref; }
-+    }
-+    return  sprintf ".word\t0x%08x !%s",
-+		    0x81b00300|$rd<<25|$rs1<<14|$rs2,
-+		    $ref;
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-+		&unvis($1,$2,$3,$4)
-+	 /ge;
-+	s/\b(alignaddr)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+		&unalignaddr($1,$2,$3,$4)
-+	 /ge;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-sparcv9a.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-sparcv9a.pl
-new file mode 100644
-index 0000000..f9ed563
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-sparcv9a.pl
-@@ -0,0 +1,608 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# January 2009
-+#
-+# Provided that UltraSPARC VIS instructions are pipe-lined(*) and
-+# pairable(*) with IALU ones, offloading of Xupdate to the UltraSPARC
-+# Graphic Unit would make it possible to achieve higher instruction-
-+# level parallelism, ILP, and thus higher performance. It should be
-+# explicitly noted that ILP is the keyword, and it means that this
-+# code would be unsuitable for cores like UltraSPARC-Tx. The idea is
-+# not really novel, Sun had VIS-powered implementation for a while.
-+# Unlike Sun's implementation this one can process multiple unaligned
-+# input blocks, and as such works as drop-in replacement for OpenSSL
-+# sha1_block_data_order. Performance improvement was measured to be
-+# 40% over pure IALU sha1-sparcv9.pl on UltraSPARC-IIi, but 12% on
-+# UltraSPARC-III. See below for discussion...
-+#
-+# The module does not present direct interest for OpenSSL, because
-+# it doesn't provide better performance on contemporary SPARCv9 CPUs,
-+# UltraSPARC-Tx and SPARC64-V[II] to be specific. Those who feel they
-+# absolutely must score on UltraSPARC-I-IV can simply replace
-+# crypto/sha/asm/sha1-sparcv9.pl with this module.
-+#
-+# (*)	"Pipe-lined" means that even if it takes several cycles to
-+#	complete, next instruction using same functional unit [but not
-+#	depending on the result of the current instruction] can start
-+#	execution without having to wait for the unit. "Pairable"
-+#	means that two [or more] independent instructions can be
-+#	issued at the very same time.
-+
-+$bits=32;
-+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
-+if ($bits==64)	{ $bias=2047; $frame=192; }
-+else		{ $bias=0;    $frame=112; }
-+
-+$output=shift;
-+open STDOUT,">$output";
-+
-+$ctx="%i0";
-+$inp="%i1";
-+$len="%i2";
-+$tmp0="%i3";
-+$tmp1="%i4";
-+$tmp2="%i5";
-+$tmp3="%g5";
-+
-+$base="%g1";
-+$align="%g4";
-+$Xfer="%o5";
-+$nXfer=$tmp3;
-+$Xi="%o7";
-+
-+$A="%l0";
-+$B="%l1";
-+$C="%l2";
-+$D="%l3";
-+$E="%l4";
-+@V=($A,$B,$C,$D,$E);
-+
-+$Actx="%o0";
-+$Bctx="%o1";
-+$Cctx="%o2";
-+$Dctx="%o3";
-+$Ectx="%o4";
-+
-+$fmul="%f32";
-+$VK_00_19="%f34";
-+$VK_20_39="%f36";
-+$VK_40_59="%f38";
-+$VK_60_79="%f40";
-+@VK=($VK_00_19,$VK_20_39,$VK_40_59,$VK_60_79);
-+@X=("%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
-+    "%f8", "%f9","%f10","%f11","%f12","%f13","%f14","%f15","%f16");
-+
-+# This is reference 2x-parallelized VIS-powered Xupdate procedure. It
-+# covers even K_NN_MM addition...
-+sub Xupdate {
-+my ($i)=@_;
-+my $K=@VK[($i+16)/20];
-+my $j=($i+16)%16;
-+
-+#	[ provided that GSR.alignaddr_offset is 5, $mul contains
-+#	  0x100ULL<<32|0x100 value and K_NN_MM are pre-loaded to
-+#	  chosen registers... ]
-+$code.=<<___;
-+	fxors		@X[($j+13)%16],@X[$j],@X[$j]	!-1/-1/-1:X[0]^=X[13]
-+	fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
-+	fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
-+	fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
-+	faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
-+	fpadd32		@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
-+	fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
-+	![fxors		%f15,%f2,%f2]
-+	for		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
-+	![fxors		%f0,%f3,%f3]			!10/17/12:X[0] dependency
-+	fpadd32		$K,@X[$j],%f20
-+	std		%f20,[$Xfer+`4*$j`]
-+___
-+# The numbers delimited with slash are the earliest possible dispatch
-+# cycles for given instruction assuming 1 cycle latency for simple VIS
-+# instructions, such as on UltraSPARC-I&II, 3 cycles latency, such as
-+# on UltraSPARC-III&IV, and 2 cycles latency(*), respectively. Being
-+# 2x-parallelized the procedure is "worth" 5, 8.5 or 6 ticks per SHA1
-+# round. As [long as] FPU/VIS instructions are perfectly pairable with
-+# IALU ones, the round timing is defined by the maximum between VIS
-+# and IALU timings. The latter varies from round to round and averages
-+# out at 6.25 ticks. This means that USI&II should operate at IALU
-+# rate, while USIII&IV - at VIS rate. This explains why performance
-+# improvement varies among processors. Well, given that pure IALU
-+# sha1-sparcv9.pl module exhibits virtually uniform performance of
-+# ~9.3 cycles per SHA1 round. Timings mentioned above are theoretical
-+# lower limits. Real-life performance was measured to be 6.6 cycles
-+# per SHA1 round on USIIi and 8.3 on USIII. The latter is lower than
-+# half-round VIS timing, because there are 16 Xupdate-free rounds,
-+# which "push down" average theoretical timing to 8 cycles...
-+
-+# (*)	SPARC64-V[II] was originally believed to have 2 cycles VIS
-+#	latency. Well, it might have, but it doesn't have dedicated
-+#	VIS-unit. Instead, VIS instructions are executed by other
-+#	functional units, ones used here - by IALU. This doesn't
-+#	improve effective ILP...
-+}
-+
-+# The reference Xupdate procedure is then "strained" over *pairs* of
-+# BODY_NN_MM and kind of modulo-scheduled in respect to X[n]^=X[n+13]
-+# and K_NN_MM addition. It's "running" 15 rounds ahead, which leaves
-+# plenty of room to amortize for read-after-write hazard, as well as
-+# to fetch and align input for the next spin. The VIS instructions are
-+# scheduled for latency of 2 cycles, because there are not enough IALU
-+# instructions to schedule for latency of 3, while scheduling for 1
-+# would give no gain on USI&II anyway.
-+
-+sub BODY_00_19 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i&~1;
-+my $k=($j+16+2)%16;	# ahead reference
-+my $l=($j+16-2)%16;	# behind reference
-+my $K=@VK[($j+16-2)/20];
-+
-+$j=($j+16)%16;
-+
-+$code.=<<___ if (!($i&1));
-+	sll		$a,5,$tmp0			!! $i
-+	and		$c,$b,$tmp3
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
-+	sll		$b,30,$tmp2
-+	add		$tmp1,$e,$e
-+	andn		$d,$b,$tmp1
-+	add		$Xi,$e,$e
-+	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
-+	srl		$b,2,$b
-+	or		$tmp1,$tmp3,$tmp1
-+	or		$tmp2,$b,$b
-+	add		$tmp1,$e,$e
-+	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
-+___
-+$code.=<<___ if ($i&1);
-+	sll		$a,5,$tmp0			!! $i
-+	and		$c,$b,$tmp3
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
-+	sll		$b,30,$tmp2
-+	add		$tmp1,$e,$e
-+	 fpadd32	$K,@X[$l],%f20			!
-+	andn		$d,$b,$tmp1
-+	add		$Xi,$e,$e
-+	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
-+	srl		$b,2,$b
-+	or		$tmp1,$tmp3,$tmp1
-+	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
-+	or		$tmp2,$b,$b
-+	add		$tmp1,$e,$e
-+___
-+$code.=<<___ if ($i&1 && $i>=2);
-+	 std		%f20,[$Xfer+`4*$l`]		!
-+___
-+}
-+
-+sub BODY_20_39 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i&~1;
-+my $k=($j+16+2)%16;	# ahead reference
-+my $l=($j+16-2)%16;	# behind reference
-+my $K=@VK[($j+16-2)/20];
-+
-+$j=($j+16)%16;
-+
-+$code.=<<___ if (!($i&1) && $i<64);
-+	sll		$a,5,$tmp0			!! $i
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
-+	xor		$c,$b,$tmp0
-+	add		$tmp1,$e,$e
-+	sll		$b,30,$tmp2
-+	xor		$d,$tmp0,$tmp1
-+	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
-+	srl		$b,2,$b
-+	add		$tmp1,$e,$e
-+	or		$tmp2,$b,$b
-+	add		$Xi,$e,$e
-+	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
-+___
-+$code.=<<___ if ($i&1 && $i<64);
-+	sll		$a,5,$tmp0			!! $i
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
-+	xor		$c,$b,$tmp0
-+	add		$tmp1,$e,$e
-+	 fpadd32	$K,@X[$l],%f20			!
-+	sll		$b,30,$tmp2
-+	xor		$d,$tmp0,$tmp1
-+	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
-+	srl		$b,2,$b
-+	add		$tmp1,$e,$e
-+	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
-+	or		$tmp2,$b,$b
-+	add		$Xi,$e,$e
-+	 std		%f20,[$Xfer+`4*$l`]		!
-+___
-+$code.=<<___ if ($i==64);
-+	sll		$a,5,$tmp0			!! $i
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	 fpadd32	$K,@X[$l],%f20
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	xor		$c,$b,$tmp0
-+	add		$tmp1,$e,$e
-+	sll		$b,30,$tmp2
-+	xor		$d,$tmp0,$tmp1
-+	 std		%f20,[$Xfer+`4*$l`]
-+	srl		$b,2,$b
-+	add		$tmp1,$e,$e
-+	or		$tmp2,$b,$b
-+	add		$Xi,$e,$e
-+___
-+$code.=<<___ if ($i>64);
-+	sll		$a,5,$tmp0			!! $i
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	xor		$c,$b,$tmp0
-+	add		$tmp1,$e,$e
-+	sll		$b,30,$tmp2
-+	xor		$d,$tmp0,$tmp1
-+	srl		$b,2,$b
-+	add		$tmp1,$e,$e
-+	or		$tmp2,$b,$b
-+	add		$Xi,$e,$e
-+___
-+}
-+
-+sub BODY_40_59 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i&~1;
-+my $k=($j+16+2)%16;	# ahead reference
-+my $l=($j+16-2)%16;	# behind reference
-+my $K=@VK[($j+16-2)/20];
-+
-+$j=($j+16)%16;
-+
-+$code.=<<___ if (!($i&1));
-+	sll		$a,5,$tmp0			!! $i
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	 fxors		@X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14]
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	 fxor		@X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9]
-+	and		$c,$b,$tmp0
-+	add		$tmp1,$e,$e
-+	sll		$b,30,$tmp2
-+	or		$c,$b,$tmp1
-+	 fxor		%f18,@X[$j],@X[$j]		! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9]
-+	srl		$b,2,$b
-+	and		$d,$tmp1,$tmp1
-+	add		$Xi,$e,$e
-+	or		$tmp1,$tmp0,$tmp1
-+	 faligndata	@X[$j],@X[$j],%f18		! 3/ 7/ 5:Tmp=X[0,1]>>>24
-+	or		$tmp2,$b,$b
-+	add		$tmp1,$e,$e
-+	 fpadd32	@X[$j],@X[$j],@X[$j]		! 4/ 8/ 6:X[0,1]<<=1
-+___
-+$code.=<<___ if ($i&1);
-+	sll		$a,5,$tmp0			!! $i
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	 fmul8ulx16	%f18,$fmul,%f18			! 5/10/ 7:Tmp>>=7, Tmp&=1
-+	and		$c,$b,$tmp0
-+	add		$tmp1,$e,$e
-+	 fpadd32	$K,@X[$l],%f20			!
-+	sll		$b,30,$tmp2
-+	or		$c,$b,$tmp1
-+	 fxors		@X[($k+13)%16],@X[$k],@X[$k]	!-1/-1/-1:X[0]^=X[13]
-+	srl		$b,2,$b
-+	and		$d,$tmp1,$tmp1
-+	 fxor		%f18,@X[$j],@X[$j]		! 8/14/10:X[0,1]|=Tmp
-+	add		$Xi,$e,$e
-+	or		$tmp1,$tmp0,$tmp1
-+	or		$tmp2,$b,$b
-+	add		$tmp1,$e,$e
-+	 std		%f20,[$Xfer+`4*$l`]		!
-+___
-+}
-+
-+# If there is more data to process, then we pre-fetch the data for
-+# next iteration in last ten rounds...
-+sub BODY_70_79 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i&~1;
-+my $m=($i%8)*2;
-+
-+$j=($j+16)%16;
-+
-+$code.=<<___ if ($i==70);
-+	sll		$a,5,$tmp0			!! $i
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	 ldd		[$inp+64],@X[0]
-+	xor		$c,$b,$tmp0
-+	add		$tmp1,$e,$e
-+	sll		$b,30,$tmp2
-+	xor		$d,$tmp0,$tmp1
-+	srl		$b,2,$b
-+	add		$tmp1,$e,$e
-+	or		$tmp2,$b,$b
-+	add		$Xi,$e,$e
-+
-+	and		$inp,-64,$nXfer
-+	inc		64,$inp
-+	and		$nXfer,255,$nXfer
-+	alignaddr	%g0,$align,%g0
-+	add		$base,$nXfer,$nXfer
-+___
-+$code.=<<___ if ($i==71);
-+	sll		$a,5,$tmp0			!! $i
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	xor		$c,$b,$tmp0
-+	add		$tmp1,$e,$e
-+	sll		$b,30,$tmp2
-+	xor		$d,$tmp0,$tmp1
-+	srl		$b,2,$b
-+	add		$tmp1,$e,$e
-+	or		$tmp2,$b,$b
-+	add		$Xi,$e,$e
-+___
-+$code.=<<___ if ($i>=72);
-+	 faligndata	@X[$m],@X[$m+2],@X[$m]
-+	sll		$a,5,$tmp0			!! $i
-+	ld		[$Xfer+`4*($i%16)`],$Xi
-+	srl		$a,27,$tmp1
-+	add		$tmp0,$e,$e
-+	xor		$c,$b,$tmp0
-+	add		$tmp1,$e,$e
-+	 fpadd32	$VK_00_19,@X[$m],%f20
-+	sll		$b,30,$tmp2
-+	xor		$d,$tmp0,$tmp1
-+	srl		$b,2,$b
-+	add		$tmp1,$e,$e
-+	or		$tmp2,$b,$b
-+	add		$Xi,$e,$e
-+___
-+$code.=<<___ if ($i<77);
-+	 ldd		[$inp+`8*($i+1-70)`],@X[2*($i+1-70)]
-+___
-+$code.=<<___ if ($i==77);	# redundant if $inp was aligned
-+	 add		$align,63,$tmp0
-+	 and		$tmp0,-8,$tmp0
-+	 ldd		[$inp+$tmp0],@X[16]
-+___
-+$code.=<<___ if ($i>=72);
-+	 std		%f20,[$nXfer+`4*$m`]
-+___
-+}
-+
-+$code.=<<___;
-+.section	".text",#alloc,#execinstr
-+
-+.align	64
-+vis_const:
-+.long	0x5a827999,0x5a827999	! K_00_19
-+.long	0x6ed9eba1,0x6ed9eba1	! K_20_39
-+.long	0x8f1bbcdc,0x8f1bbcdc	! K_40_59
-+.long	0xca62c1d6,0xca62c1d6	! K_60_79
-+.long	0x00000100,0x00000100
-+.align	64
-+.type	vis_const,#object
-+.size	vis_const,(.-vis_const)
-+
-+.globl	sha1_block_data_order
-+sha1_block_data_order:
-+	save	%sp,-$frame,%sp
-+	add	%fp,$bias-256,$base
-+
-+1:	call	.+8
-+	add	%o7,vis_const-1b,$tmp0
-+
-+	ldd	[$tmp0+0],$VK_00_19
-+	ldd	[$tmp0+8],$VK_20_39
-+	ldd	[$tmp0+16],$VK_40_59
-+	ldd	[$tmp0+24],$VK_60_79
-+	ldd	[$tmp0+32],$fmul
-+
-+	ld	[$ctx+0],$Actx
-+	and	$base,-256,$base
-+	ld	[$ctx+4],$Bctx
-+	sub	$base,$bias+$frame,%sp
-+	ld	[$ctx+8],$Cctx
-+	and	$inp,7,$align
-+	ld	[$ctx+12],$Dctx
-+	and	$inp,-8,$inp
-+	ld	[$ctx+16],$Ectx
-+
-+	! X[16] is maintained in FP register bank
-+	alignaddr	%g0,$align,%g0
-+	ldd		[$inp+0],@X[0]
-+	sub		$inp,-64,$Xfer
-+	ldd		[$inp+8],@X[2]
-+	and		$Xfer,-64,$Xfer
-+	ldd		[$inp+16],@X[4]
-+	and		$Xfer,255,$Xfer
-+	ldd		[$inp+24],@X[6]
-+	add		$base,$Xfer,$Xfer
-+	ldd		[$inp+32],@X[8]
-+	ldd		[$inp+40],@X[10]
-+	ldd		[$inp+48],@X[12]
-+	brz,pt		$align,.Laligned
-+	ldd		[$inp+56],@X[14]
-+
-+	ldd		[$inp+64],@X[16]
-+	faligndata	@X[0],@X[2],@X[0]
-+	faligndata	@X[2],@X[4],@X[2]
-+	faligndata	@X[4],@X[6],@X[4]
-+	faligndata	@X[6],@X[8],@X[6]
-+	faligndata	@X[8],@X[10],@X[8]
-+	faligndata	@X[10],@X[12],@X[10]
-+	faligndata	@X[12],@X[14],@X[12]
-+	faligndata	@X[14],@X[16],@X[14]
-+
-+.Laligned:
-+	mov		5,$tmp0
-+	dec		1,$len
-+	alignaddr	%g0,$tmp0,%g0
-+	fpadd32		$VK_00_19,@X[0],%f16
-+	fpadd32		$VK_00_19,@X[2],%f18
-+	fpadd32		$VK_00_19,@X[4],%f20
-+	fpadd32		$VK_00_19,@X[6],%f22
-+	fpadd32		$VK_00_19,@X[8],%f24
-+	fpadd32		$VK_00_19,@X[10],%f26
-+	fpadd32		$VK_00_19,@X[12],%f28
-+	fpadd32		$VK_00_19,@X[14],%f30
-+	std		%f16,[$Xfer+0]
-+	mov		$Actx,$A
-+	std		%f18,[$Xfer+8]
-+	mov		$Bctx,$B
-+	std		%f20,[$Xfer+16]
-+	mov		$Cctx,$C
-+	std		%f22,[$Xfer+24]
-+	mov		$Dctx,$D
-+	std		%f24,[$Xfer+32]
-+	mov		$Ectx,$E
-+	std		%f26,[$Xfer+40]
-+	fxors		@X[13],@X[0],@X[0]
-+	std		%f28,[$Xfer+48]
-+	ba		.Loop
-+	std		%f30,[$Xfer+56]
-+.align	32
-+.Loop:
-+___
-+for ($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
-+for (;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+for (;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+for (;$i<70;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	tst		$len
-+	bz,pn		`$bits==32?"%icc":"%xcc"`,.Ltail
-+	nop
-+___
-+for (;$i<80;$i++)	{ &BODY_70_79($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	add		$A,$Actx,$Actx
-+	add		$B,$Bctx,$Bctx
-+	add		$C,$Cctx,$Cctx
-+	add		$D,$Dctx,$Dctx
-+	add		$E,$Ectx,$Ectx
-+	mov		5,$tmp0
-+	fxors		@X[13],@X[0],@X[0]
-+	mov		$Actx,$A
-+	mov		$Bctx,$B
-+	mov		$Cctx,$C
-+	mov		$Dctx,$D
-+	mov		$Ectx,$E
-+	alignaddr	%g0,$tmp0,%g0	
-+	dec		1,$len
-+	ba		.Loop
-+	mov		$nXfer,$Xfer
-+
-+.align	32
-+.Ltail:
-+___
-+for($i=70;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	add	$A,$Actx,$Actx
-+	add	$B,$Bctx,$Bctx
-+	add	$C,$Cctx,$Cctx
-+	add	$D,$Dctx,$Dctx
-+	add	$E,$Ectx,$Ectx
-+
-+	st	$Actx,[$ctx+0]
-+	st	$Bctx,[$ctx+4]
-+	st	$Cctx,[$ctx+8]
-+	st	$Dctx,[$ctx+12]
-+	st	$Ectx,[$ctx+16]
-+
-+	ret
-+	restore
-+.type	sha1_block_data_order,#function
-+.size	sha1_block_data_order,(.-sha1_block_data_order)
-+.asciz	"SHA1 block transform for SPARCv9a, CRYPTOGAMS by "
-+.align	4
-+___
-+
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my ($ref,$opf);
-+my %visopf = (	"fmul8ulx16"	=> 0x037,
-+		"faligndata"	=> 0x048,
-+		"fpadd32"	=> 0x052,
-+		"fxor"		=> 0x06c,
-+		"fxors"		=> 0x06d	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+sub unalignaddr {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my $ref="$mnemonic\t$rs1,$rs2,$rd";
-+
-+    foreach ($rs1,$rs2,$rd) {
-+	if (/%([goli])([0-7])/)	{ $_=$bias{$1}+$2; }
-+	else			{ return $ref; }
-+    }
-+    return  sprintf ".word\t0x%08x !%s",
-+		    0x81b00300|$rd<<25|$rs1<<14|$rs2,
-+		    $ref;
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+$code =~ s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),(%f[0-9]{1,2}),(%f[0-9]{1,2})/
-+		&unvis($1,$2,$3,$4)
-+	  /gem;
-+$code =~ s/\b(alignaddr)\s+(%[goli][0-7]),(%[goli][0-7]),(%[goli][0-7])/
-+		&unalignaddr($1,$2,$3,$4)
-+	  /gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-thumb.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-thumb.pl
-new file mode 100644
-index 0000000..661fd9f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-thumb.pl
-@@ -0,0 +1,266 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# sha1_block for Thumb.
-+#
-+# January 2007.
-+#
-+# The code does not present direct interest to OpenSSL, because of low
-+# performance. Its purpose is to establish _size_ benchmark. Pretty
-+# useless one I must say, because 30% or 88 bytes larger ARMv4 code
-+# [avialable on demand] is almost _twice_ as fast. It should also be
-+# noted that in-lining of .Lcommon and .Lrotate improves performance
-+# by over 40%, while code increases by only 10% or 32 bytes. But once
-+# again, the goal was to establish _size_ benchmark, not performance.
-+
-+$output=shift;
-+open STDOUT,">$output";
-+
-+$inline=0;
-+#$cheat_on_binutils=1;
-+
-+$t0="r0";
-+$t1="r1";
-+$t2="r2";
-+$a="r3";
-+$b="r4";
-+$c="r5";
-+$d="r6";
-+$e="r7";
-+$K="r8";	# "upper" registers can be used in add/sub and mov insns
-+$ctx="r9";
-+$inp="r10";
-+$len="r11";
-+$Xi="r12";
-+
-+sub common {
-+<<___;
-+	sub	$t0,#4
-+	ldr	$t1,[$t0]
-+	add	$e,$K			@ E+=K_xx_xx
-+	lsl	$t2,$a,#5
-+	add	$t2,$e
-+	lsr	$e,$a,#27
-+	add	$t2,$e			@ E+=ROR(A,27)
-+	add	$t2,$t1			@ E+=X[i]
-+___
-+}
-+sub rotate {
-+<<___;
-+	mov	$e,$d			@ E=D
-+	mov	$d,$c			@ D=C
-+	lsl	$c,$b,#30
-+	lsr	$b,$b,#2
-+	orr	$c,$b			@ C=ROR(B,2)
-+	mov	$b,$a			@ B=A
-+	add	$a,$t2,$t1		@ A=E+F_xx_xx(B,C,D)
-+___
-+}
-+
-+sub BODY_00_19 {
-+$code.=$inline?&common():"\tbl	.Lcommon\n";
-+$code.=<<___;
-+	mov	$t1,$c
-+	eor	$t1,$d
-+	and	$t1,$b
-+	eor	$t1,$d			@ F_00_19(B,C,D)
-+___
-+$code.=$inline?&rotate():"\tbl	.Lrotate\n";
-+}
-+
-+sub BODY_20_39 {
-+$code.=$inline?&common():"\tbl	.Lcommon\n";
-+$code.=<<___;
-+	mov	$t1,$b
-+	eor	$t1,$c
-+	eor	$t1,$d			@ F_20_39(B,C,D)
-+___
-+$code.=$inline?&rotate():"\tbl	.Lrotate\n";
-+}
-+
-+sub BODY_40_59 {
-+$code.=$inline?&common():"\tbl	.Lcommon\n";
-+$code.=<<___;
-+	mov	$t1,$b
-+	and	$t1,$c
-+	mov	$e,$b
-+	orr	$e,$c
-+	and	$e,$d
-+	orr	$t1,$e			@ F_40_59(B,C,D)
-+___
-+$code.=$inline?&rotate():"\tbl	.Lrotate\n";
-+}
-+
-+$code=<<___;
-+.text
-+.code	16
-+
-+.global	sha1_block_data_order
-+.type	sha1_block_data_order,%function
-+
-+.align	2
-+sha1_block_data_order:
-+___
-+if ($cheat_on_binutils) {
-+$code.=<<___;
-+.code	32
-+	add	r3,pc,#1
-+	bx	r3			@ switch to Thumb ISA
-+.code	16
-+___
-+}
-+$code.=<<___;
-+	push	{r4-r7}
-+	mov	r3,r8
-+	mov	r4,r9
-+	mov	r5,r10
-+	mov	r6,r11
-+	mov	r7,r12
-+	push	{r3-r7,lr}
-+	lsl	r2,#6
-+	mov	$ctx,r0			@ save context
-+	mov	$inp,r1			@ save inp
-+	mov	$len,r2			@ save len
-+	add	$len,$inp		@ $len to point at inp end
-+
-+.Lloop:
-+	mov	$Xi,sp
-+	mov	$t2,sp
-+	sub	$t2,#16*4		@ [3]
-+.LXload:
-+	ldrb	$a,[$t1,#0]		@ $t1 is r1 and holds inp
-+	ldrb	$b,[$t1,#1]
-+	ldrb	$c,[$t1,#2]
-+	ldrb	$d,[$t1,#3]
-+	lsl	$a,#24
-+	lsl	$b,#16
-+	lsl	$c,#8
-+	orr	$a,$b
-+	orr	$a,$c
-+	orr	$a,$d
-+	add	$t1,#4
-+	push	{$a}
-+	cmp	sp,$t2
-+	bne	.LXload			@ [+14*16]
-+
-+	mov	$inp,$t1		@ update $inp
-+	sub	$t2,#32*4
-+	sub	$t2,#32*4
-+	mov	$e,#31			@ [+4]
-+.LXupdate:
-+	ldr	$a,[sp,#15*4]
-+	ldr	$b,[sp,#13*4]
-+	ldr	$c,[sp,#7*4]
-+	ldr	$d,[sp,#2*4]
-+	eor	$a,$b
-+	eor	$a,$c
-+	eor	$a,$d
-+	ror	$a,$e
-+	push	{$a}
-+	cmp	sp,$t2
-+	bne	.LXupdate		@ [+(11+1)*64]
-+
-+	ldmia	$t0!,{$a,$b,$c,$d,$e}	@ $t0 is r0 and holds ctx
-+	mov	$t0,$Xi
-+
-+	ldr	$t2,.LK_00_19
-+	mov	$t1,$t0
-+	sub	$t1,#20*4
-+	mov	$Xi,$t1
-+	mov	$K,$t2			@ [+7+4]
-+.L_00_19:
-+___
-+	&BODY_00_19();
-+$code.=<<___;
-+	cmp	$Xi,$t0
-+	bne	.L_00_19		@ [+(2+9+4+2+8+2)*20]
-+
-+	ldr	$t2,.LK_20_39
-+	mov	$t1,$t0
-+	sub	$t1,#20*4
-+	mov	$Xi,$t1
-+	mov	$K,$t2			@ [+5]
-+.L_20_39_or_60_79:
-+___
-+	&BODY_20_39();
-+$code.=<<___;
-+	cmp	$Xi,$t0
-+	bne	.L_20_39_or_60_79	@ [+(2+9+3+2+8+2)*20*2]
-+	cmp	sp,$t0
-+	beq	.Ldone			@ [+2]
-+
-+	ldr	$t2,.LK_40_59
-+	mov	$t1,$t0
-+	sub	$t1,#20*4
-+	mov	$Xi,$t1
-+	mov	$K,$t2			@ [+5]
-+.L_40_59:
-+___
-+	&BODY_40_59();
-+$code.=<<___;
-+	cmp	$Xi,$t0
-+	bne	.L_40_59		@ [+(2+9+6+2+8+2)*20]
-+
-+	ldr	$t2,.LK_60_79
-+	mov	$Xi,sp
-+	mov	$K,$t2
-+	b	.L_20_39_or_60_79	@ [+4]
-+.Ldone:
-+	mov	$t0,$ctx
-+	ldr	$t1,[$t0,#0]
-+	ldr	$t2,[$t0,#4]
-+	add	$a,$t1
-+	ldr	$t1,[$t0,#8]
-+	add	$b,$t2
-+	ldr	$t2,[$t0,#12]
-+	add	$c,$t1
-+	ldr	$t1,[$t0,#16]
-+	add	$d,$t2
-+	add	$e,$t1
-+	stmia	$t0!,{$a,$b,$c,$d,$e}	@ [+20]
-+
-+	add	sp,#80*4		@ deallocate stack frame
-+	mov	$t0,$ctx		@ restore ctx
-+	mov	$t1,$inp		@ restore inp
-+	cmp	$t1,$len
-+	beq	.Lexit
-+	b	.Lloop			@ [+6] total 3212 cycles
-+.Lexit:
-+	pop	{r2-r7}
-+	mov	r8,r2
-+	mov	r9,r3
-+	mov	r10,r4
-+	mov	r11,r5
-+	mov	r12,r6
-+	mov	lr,r7
-+	pop	{r4-r7}
-+	bx	lr
-+.align	2
-+___
-+$code.=".Lcommon:\n".&common()."\tmov	pc,lr\n" if (!$inline);
-+$code.=".Lrotate:\n".&rotate()."\tmov	pc,lr\n" if (!$inline);
-+$code.=<<___;
-+.align	2
-+.LK_00_19:	.word	0x5a827999
-+.LK_20_39:	.word	0x6ed9eba1
-+.LK_40_59:	.word	0x8f1bbcdc
-+.LK_60_79:	.word	0xca62c1d6
-+.size	sha1_block_data_order,.-sha1_block_data_order
-+.asciz	"SHA1 block transform for Thumb, CRYPTOGAMS by "
-+___
-+
-+print $code;
-+close STDOUT; # enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-x86_64.pl
-new file mode 100755
-index 0000000..e11c6e4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha1-x86_64.pl
-@@ -0,0 +1,2077 @@
-+#! /usr/bin/env perl
-+# Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# sha1_block procedure for x86_64.
-+#
-+# It was brought to my attention that on EM64T compiler-generated code
-+# was far behind 32-bit assembler implementation. This is unlike on
-+# Opteron where compiler-generated code was only 15% behind 32-bit
-+# assembler, which originally made it hard to motivate the effort.
-+# There was suggestion to mechanically translate 32-bit code, but I
-+# dismissed it, reasoning that x86_64 offers enough register bank
-+# capacity to fully utilize SHA-1 parallelism. Therefore this fresh
-+# implementation:-) However! While 64-bit code does perform better
-+# on Opteron, I failed to beat 32-bit assembler on EM64T core. Well,
-+# x86_64 does offer larger *addressable* bank, but out-of-order core
-+# reaches for even more registers through dynamic aliasing, and EM64T
-+# core must have managed to run-time optimize even 32-bit code just as
-+# good as 64-bit one. Performance improvement is summarized in the
-+# following table:
-+#
-+#		gcc 3.4		32-bit asm	cycles/byte
-+# Opteron	+45%		+20%		6.8
-+# Xeon P4	+65%		+0%		9.9
-+# Core2		+60%		+10%		7.0
-+
-+# August 2009.
-+#
-+# The code was revised to minimize code size and to maximize
-+# "distance" between instructions producing input to 'lea'
-+# instruction and the 'lea' instruction itself, which is essential
-+# for Intel Atom core.
-+
-+# October 2010.
-+#
-+# Add SSSE3, Supplemental[!] SSE3, implementation. The idea behind it
-+# is to offload message schedule denoted by Wt in NIST specification,
-+# or Xupdate in OpenSSL source, to SIMD unit. See sha1-586.pl module
-+# for background and implementation details. The only difference from
-+# 32-bit code is that 64-bit code doesn't have to spill @X[] elements
-+# to free temporary registers.
-+
-+# April 2011.
-+#
-+# Add AVX code path. See sha1-586.pl for further information.
-+
-+# May 2013.
-+#
-+# Add AVX2+BMI code path. Initial attempt (utilizing BMI instructions
-+# and loading pair of consecutive blocks to 256-bit %ymm registers)
-+# did not provide impressive performance improvement till a crucial
-+# hint regarding the number of Xupdate iterations to pre-compute in
-+# advance was provided by Ilya Albrekht of Intel Corp.
-+
-+# March 2014.
-+#
-+# Add support for Intel SHA Extensions.
-+
-+######################################################################
-+# Current performance is summarized in following table. Numbers are
-+# CPU clock cycles spent to process single byte (less is better).
-+#
-+#		x86_64		SSSE3		AVX[2]
-+# P4		9.05		-
-+# Opteron	6.26		-
-+# Core2		6.55		6.05/+8%	-
-+# Westmere	6.73		5.30/+27%	-
-+# Sandy Bridge	7.70		6.10/+26%	4.99/+54%
-+# Ivy Bridge	6.06		4.67/+30%	4.60/+32%
-+# Haswell	5.45		4.15/+31%	3.57/+53%
-+# Skylake	5.18		4.06/+28%	3.54/+46%
-+# Bulldozer	9.11		5.95/+53%
-+# VIA Nano	9.32		7.15/+30%
-+# Atom		10.3		9.17/+12%
-+# Silvermont	13.1(*)		9.37/+40%
-+# Goldmont	8.13		6.42/+27%	1.70/+380%(**)
-+#
-+# (*)	obviously suboptimal result, nothing was done about it,
-+#	because SSSE3 code is compiled unconditionally;
-+# (**)	SHAEXT result
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	   `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([2-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+$shaext=1;	### set to zero if compiling for 1.0.1
-+$avx=1		if (!$shaext && $avx);
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+$ctx="%rdi";	# 1st arg
-+$inp="%rsi";	# 2nd arg
-+$num="%rdx";	# 3rd arg
-+
-+# reassign arguments in order to produce more compact code
-+$ctx="%r8";
-+$inp="%r9";
-+$num="%r10";
-+
-+$t0="%eax";
-+$t1="%ebx";
-+$t2="%ecx";
-+@xi=("%edx","%ebp","%r14d");
-+$A="%esi";
-+$B="%edi";
-+$C="%r11d";
-+$D="%r12d";
-+$E="%r13d";
-+
-+@V=($A,$B,$C,$D,$E);
-+
-+sub BODY_00_19 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___ if ($i==0);
-+	mov	`4*$i`($inp),$xi[0]
-+	bswap	$xi[0]
-+___
-+$code.=<<___ if ($i<15);
-+	mov	`4*$j`($inp),$xi[1]
-+	mov	$d,$t0
-+	mov	$xi[0],`4*$i`(%rsp)
-+	mov	$a,$t2
-+	bswap	$xi[1]
-+	xor	$c,$t0
-+	rol	\$5,$t2
-+	and	$b,$t0
-+	lea	0x5a827999($xi[0],$e),$e
-+	add	$t2,$e
-+	xor	$d,$t0
-+	rol	\$30,$b
-+	add	$t0,$e
-+___
-+$code.=<<___ if ($i>=15);
-+	xor	`4*($j%16)`(%rsp),$xi[1]
-+	mov	$d,$t0
-+	mov	$xi[0],`4*($i%16)`(%rsp)
-+	mov	$a,$t2
-+	xor	`4*(($j+2)%16)`(%rsp),$xi[1]
-+	xor	$c,$t0
-+	rol	\$5,$t2
-+	xor	`4*(($j+8)%16)`(%rsp),$xi[1]
-+	and	$b,$t0
-+	lea	0x5a827999($xi[0],$e),$e
-+	rol	\$30,$b
-+	xor	$d,$t0
-+	add	$t2,$e
-+	rol	\$1,$xi[1]
-+	add	$t0,$e
-+___
-+push(@xi,shift(@xi));
-+}
-+
-+sub BODY_20_39 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+my $K=($i<40)?0x6ed9eba1:0xca62c1d6;
-+$code.=<<___ if ($i<79);
-+	xor	`4*($j%16)`(%rsp),$xi[1]
-+	mov	$b,$t0
-+	`"mov	$xi[0],".4*($i%16)."(%rsp)"	if ($i<72)`
-+	mov	$a,$t2
-+	xor	`4*(($j+2)%16)`(%rsp),$xi[1]
-+	xor	$d,$t0
-+	rol	\$5,$t2
-+	xor	`4*(($j+8)%16)`(%rsp),$xi[1]
-+	lea	$K($xi[0],$e),$e
-+	xor	$c,$t0
-+	add	$t2,$e
-+	rol	\$30,$b
-+	add	$t0,$e
-+	rol	\$1,$xi[1]
-+___
-+$code.=<<___ if ($i==79);
-+	mov	$b,$t0
-+	mov	$a,$t2
-+	xor	$d,$t0
-+	lea	$K($xi[0],$e),$e
-+	rol	\$5,$t2
-+	xor	$c,$t0
-+	add	$t2,$e
-+	rol	\$30,$b
-+	add	$t0,$e
-+___
-+push(@xi,shift(@xi));
-+}
-+
-+sub BODY_40_59 {
-+my ($i,$a,$b,$c,$d,$e)=@_;
-+my $j=$i+1;
-+$code.=<<___;
-+	xor	`4*($j%16)`(%rsp),$xi[1]
-+	mov	$d,$t0
-+	mov	$xi[0],`4*($i%16)`(%rsp)
-+	mov	$d,$t1
-+	xor	`4*(($j+2)%16)`(%rsp),$xi[1]
-+	and	$c,$t0
-+	mov	$a,$t2
-+	xor	`4*(($j+8)%16)`(%rsp),$xi[1]
-+	lea	0x8f1bbcdc($xi[0],$e),$e
-+	xor	$c,$t1
-+	rol	\$5,$t2
-+	add	$t0,$e
-+	rol	\$1,$xi[1]
-+	and	$b,$t1
-+	add	$t2,$e
-+	rol	\$30,$b
-+	add	$t1,$e
-+___
-+push(@xi,shift(@xi));
-+}
-+
-+$code.=<<___;
-+.text
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	sha1_block_data_order
-+.type	sha1_block_data_order,\@function,3
-+.align	16
-+sha1_block_data_order:
-+	mov	OPENSSL_ia32cap_P+0(%rip),%r9d
-+	mov	OPENSSL_ia32cap_P+4(%rip),%r8d
-+	mov	OPENSSL_ia32cap_P+8(%rip),%r10d
-+	test	\$`1<<9`,%r8d		# check SSSE3 bit
-+	jz	.Lialu
-+___
-+$code.=<<___ if ($shaext);
-+	test	\$`1<<29`,%r10d		# check SHA bit	
-+	jnz	_shaext_shortcut
-+___
-+$code.=<<___ if ($avx>1);
-+	and	\$`1<<3|1<<5|1<<8`,%r10d	# check AVX2+BMI1+BMI2
-+	cmp	\$`1<<3|1<<5|1<<8`,%r10d
-+	je	_avx2_shortcut
-+___
-+$code.=<<___ if ($avx);
-+	and	\$`1<<28`,%r8d		# mask AVX bit
-+	and	\$`1<<30`,%r9d		# mask "Intel CPU" bit
-+	or	%r9d,%r8d
-+	cmp	\$`1<<28|1<<30`,%r8d
-+	je	_avx_shortcut
-+___
-+$code.=<<___;
-+	jmp	_ssse3_shortcut
-+
-+.align	16
-+.Lialu:
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	mov	%rdi,$ctx	# reassigned argument
-+	sub	\$`8+16*4`,%rsp
-+	mov	%rsi,$inp	# reassigned argument
-+	and	\$-64,%rsp
-+	mov	%rdx,$num	# reassigned argument
-+	mov	%rax,`16*4`(%rsp)
-+.Lprologue:
-+
-+	mov	0($ctx),$A
-+	mov	4($ctx),$B
-+	mov	8($ctx),$C
-+	mov	12($ctx),$D
-+	mov	16($ctx),$E
-+	jmp	.Lloop
-+
-+.align	16
-+.Lloop:
-+___
-+for($i=0;$i<20;$i++)	{ &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
-+for(;$i<40;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+for(;$i<60;$i++)	{ &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
-+for(;$i<80;$i++)	{ &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	add	0($ctx),$A
-+	add	4($ctx),$B
-+	add	8($ctx),$C
-+	add	12($ctx),$D
-+	add	16($ctx),$E
-+	mov	$A,0($ctx)
-+	mov	$B,4($ctx)
-+	mov	$C,8($ctx)
-+	mov	$D,12($ctx)
-+	mov	$E,16($ctx)
-+
-+	sub	\$1,$num
-+	lea	`16*4`($inp),$inp
-+	jnz	.Lloop
-+
-+	mov	`16*4`(%rsp),%rsi
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lepilogue:
-+	ret
-+.size	sha1_block_data_order,.-sha1_block_data_order
-+___
-+if ($shaext) {{{
-+######################################################################
-+# Intel SHA Extensions implementation of SHA1 update function.
-+#
-+my ($ctx,$inp,$num)=("%rdi","%rsi","%rdx");
-+my ($ABCD,$E,$E_,$BSWAP,$ABCD_SAVE,$E_SAVE)=map("%xmm$_",(0..3,8,9));
-+my @MSG=map("%xmm$_",(4..7));
-+
-+$code.=<<___;
-+.type	sha1_block_data_order_shaext,\@function,3
-+.align	32
-+sha1_block_data_order_shaext:
-+_shaext_shortcut:
-+___
-+$code.=<<___ if ($win64);
-+	lea	`-8-4*16`(%rsp),%rsp
-+	movaps	%xmm6,-8-4*16(%rax)
-+	movaps	%xmm7,-8-3*16(%rax)
-+	movaps	%xmm8,-8-2*16(%rax)
-+	movaps	%xmm9,-8-1*16(%rax)
-+.Lprologue_shaext:
-+___
-+$code.=<<___;
-+	movdqu	($ctx),$ABCD
-+	movd	16($ctx),$E
-+	movdqa	K_XX_XX+0xa0(%rip),$BSWAP	# byte-n-word swap
-+
-+	movdqu	($inp),@MSG[0]
-+	pshufd	\$0b00011011,$ABCD,$ABCD	# flip word order
-+	movdqu	0x10($inp),@MSG[1]
-+	pshufd	\$0b00011011,$E,$E		# flip word order
-+	movdqu	0x20($inp),@MSG[2]
-+	pshufb	$BSWAP,@MSG[0]
-+	movdqu	0x30($inp),@MSG[3]
-+	pshufb	$BSWAP,@MSG[1]
-+	pshufb	$BSWAP,@MSG[2]
-+	movdqa	$E,$E_SAVE			# offload $E
-+	pshufb	$BSWAP,@MSG[3]
-+	jmp	.Loop_shaext
-+
-+.align	16
-+.Loop_shaext:
-+	dec		$num
-+	lea		0x40($inp),%r8		# next input block
-+	paddd		@MSG[0],$E
-+	cmovne		%r8,$inp
-+	movdqa		$ABCD,$ABCD_SAVE	# offload $ABCD
-+___
-+for($i=0;$i<20-4;$i+=2) {
-+$code.=<<___;
-+	sha1msg1	@MSG[1],@MSG[0]
-+	movdqa		$ABCD,$E_
-+	sha1rnds4	\$`int($i/5)`,$E,$ABCD	# 0-3...
-+	sha1nexte	@MSG[1],$E_
-+	pxor		@MSG[2],@MSG[0]
-+	sha1msg1	@MSG[2],@MSG[1]
-+	sha1msg2	@MSG[3],@MSG[0]
-+
-+	movdqa		$ABCD,$E
-+	sha1rnds4	\$`int(($i+1)/5)`,$E_,$ABCD
-+	sha1nexte	@MSG[2],$E
-+	pxor		@MSG[3],@MSG[1]
-+	sha1msg2	@MSG[0],@MSG[1]
-+___
-+	push(@MSG,shift(@MSG));	push(@MSG,shift(@MSG));
-+}
-+$code.=<<___;
-+	movdqu		($inp),@MSG[0]
-+	movdqa		$ABCD,$E_
-+	sha1rnds4	\$3,$E,$ABCD		# 64-67
-+	sha1nexte	@MSG[1],$E_
-+	movdqu		0x10($inp),@MSG[1]
-+	pshufb		$BSWAP,@MSG[0]
-+
-+	movdqa		$ABCD,$E
-+	sha1rnds4	\$3,$E_,$ABCD		# 68-71
-+	sha1nexte	@MSG[2],$E
-+	movdqu		0x20($inp),@MSG[2]
-+	pshufb		$BSWAP,@MSG[1]
-+
-+	movdqa		$ABCD,$E_
-+	sha1rnds4	\$3,$E,$ABCD		# 72-75
-+	sha1nexte	@MSG[3],$E_
-+	movdqu		0x30($inp),@MSG[3]
-+	pshufb		$BSWAP,@MSG[2]
-+
-+	movdqa		$ABCD,$E
-+	sha1rnds4	\$3,$E_,$ABCD		# 76-79
-+	sha1nexte	$E_SAVE,$E
-+	pshufb		$BSWAP,@MSG[3]
-+
-+	paddd		$ABCD_SAVE,$ABCD
-+	movdqa		$E,$E_SAVE		# offload $E
-+
-+	jnz		.Loop_shaext
-+
-+	pshufd	\$0b00011011,$ABCD,$ABCD
-+	pshufd	\$0b00011011,$E,$E
-+	movdqu	$ABCD,($ctx)
-+	movd	$E,16($ctx)
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-8-4*16(%rax),%xmm6
-+	movaps	-8-3*16(%rax),%xmm7
-+	movaps	-8-2*16(%rax),%xmm8
-+	movaps	-8-1*16(%rax),%xmm9
-+	mov	%rax,%rsp
-+.Lepilogue_shaext:
-+___
-+$code.=<<___;
-+	ret
-+.size	sha1_block_data_order_shaext,.-sha1_block_data_order_shaext
-+___
-+}}}
-+{{{
-+my $Xi=4;
-+my @X=map("%xmm$_",(4..7,0..3));
-+my @Tx=map("%xmm$_",(8..10));
-+my $Kx="%xmm11";
-+my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp");	# size optimization
-+my @T=("%esi","%edi");
-+my $j=0;
-+my $rx=0;
-+my $K_XX_XX="%r11";
-+
-+my $_rol=sub { &rol(@_) };
-+my $_ror=sub { &ror(@_) };
-+
-+{ my $sn;
-+sub align32() {
-+  ++$sn;
-+$code.=<<___;
-+	jmp	.Lalign32_$sn	# see "Decoded ICache" in manual
-+.align	32
-+.Lalign32_$sn:
-+___
-+}
-+}
-+
-+$code.=<<___;
-+.type	sha1_block_data_order_ssse3,\@function,3
-+.align	16
-+sha1_block_data_order_ssse3:
-+_ssse3_shortcut:
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13		# redundant, done to share Win64 SE handler
-+	push	%r14
-+	lea	`-64-($win64?6*16:0)`(%rsp),%rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,-40-6*16(%rax)
-+	movaps	%xmm7,-40-5*16(%rax)
-+	movaps	%xmm8,-40-4*16(%rax)
-+	movaps	%xmm9,-40-3*16(%rax)
-+	movaps	%xmm10,-40-2*16(%rax)
-+	movaps	%xmm11,-40-1*16(%rax)
-+.Lprologue_ssse3:
-+___
-+$code.=<<___;
-+	mov	%rax,%r14	# original %rsp
-+	and	\$-64,%rsp
-+	mov	%rdi,$ctx	# reassigned argument
-+	mov	%rsi,$inp	# reassigned argument
-+	mov	%rdx,$num	# reassigned argument
-+
-+	shl	\$6,$num
-+	add	$inp,$num
-+	lea	K_XX_XX+64(%rip),$K_XX_XX
-+
-+	mov	0($ctx),$A		# load context
-+	mov	4($ctx),$B
-+	mov	8($ctx),$C
-+	mov	12($ctx),$D
-+	mov	$B,@T[0]		# magic seed
-+	mov	16($ctx),$E
-+	mov	$C,@T[1]
-+	xor	$D,@T[1]
-+	and	@T[1],@T[0]
-+
-+	movdqa	64($K_XX_XX),@X[2]	# pbswap mask
-+	movdqa	-64($K_XX_XX),@Tx[1]	# K_00_19
-+	movdqu	0($inp),@X[-4&7]	# load input to %xmm[0-3]
-+	movdqu	16($inp),@X[-3&7]
-+	movdqu	32($inp),@X[-2&7]
-+	movdqu	48($inp),@X[-1&7]
-+	pshufb	@X[2],@X[-4&7]		# byte swap
-+	pshufb	@X[2],@X[-3&7]
-+	pshufb	@X[2],@X[-2&7]
-+	add	\$64,$inp
-+	paddd	@Tx[1],@X[-4&7]		# add K_00_19
-+	pshufb	@X[2],@X[-1&7]
-+	paddd	@Tx[1],@X[-3&7]
-+	paddd	@Tx[1],@X[-2&7]
-+	movdqa	@X[-4&7],0(%rsp)	# X[]+K xfer to IALU
-+	psubd	@Tx[1],@X[-4&7]		# restore X[]
-+	movdqa	@X[-3&7],16(%rsp)
-+	psubd	@Tx[1],@X[-3&7]
-+	movdqa	@X[-2&7],32(%rsp)
-+	psubd	@Tx[1],@X[-2&7]
-+	jmp	.Loop_ssse3
-+___
-+
-+sub AUTOLOAD()		# thunk [simplified] 32-bit style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
-+  my $arg = pop;
-+    $arg = "\$$arg" if ($arg*1 eq $arg);
-+    $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
-+}
-+
-+sub Xupdate_ssse3_16_31()		# recall that $Xi starts wtih 4
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));		# ror
-+	&pshufd	(@X[0],@X[-4&7],0xee);	# was &movdqa	(@X[0],@X[-3&7]);
-+	 eval(shift(@insns));
-+	&movdqa	(@Tx[0],@X[-1&7]);
-+	  &paddd	(@Tx[1],@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&punpcklqdq(@X[0],@X[-3&7]);	# compose "X[-14]" in "X[0]", was &palignr(@X[0],@X[-4&7],8);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	&psrldq	(@Tx[0],4);		# "X[-3]", 3 dwords
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@X[-4&7]);	# "X[0]"^="X[-16]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	&pxor	(@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@Tx[0]);		# "X[0]"^="X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&movdqa	(@Tx[2],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	&movdqa	(@Tx[0],@X[0]);
-+	 eval(shift(@insns));
-+
-+	&pslldq	(@Tx[2],12);		# "X[0]"<<96, extract one dword
-+	&paddd	(@X[0],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&psrld	(@Tx[0],31);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	&movdqa	(@Tx[1],@Tx[2]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&psrld	(@Tx[2],30);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	&por	(@X[0],@Tx[0]);		# "X[0]"<<<=1
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pslld	(@Tx[1],2);
-+	&pxor	(@X[0],@Tx[2]);
-+	 eval(shift(@insns));
-+	  &movdqa	(@Tx[2],eval(2*16*(($Xi)/5)-64)."($K_XX_XX)");	# K_XX_XX
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@Tx[1]);		# "X[0]"^=("X[0]">>96)<<<2
-+	&pshufd (@Tx[1],@X[-1&7],0xee)	if ($Xi==7);	# was &movdqa	(@Tx[0],@X[-1&7]) in Xupdate_ssse3_32_79
-+
-+	 foreach (@insns) { eval; }	# remaining instructions [if any]
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+		push(@Tx,shift(@Tx));
-+}
-+
-+sub Xupdate_ssse3_32_79()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 44 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns))		if ($Xi==8);
-+	&pxor	(@X[0],@X[-4&7]);	# "X[0]"="X[-32]"^"X[-16]"
-+	 eval(shift(@insns))		if ($Xi==8);
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns))		if (@insns[1] =~ /_ror/);
-+	 eval(shift(@insns))		if (@insns[0] =~ /_ror/);
-+	&punpcklqdq(@Tx[0],@X[-1&7]);	# compose "X[-6]", was &palignr(@Tx[0],@X[-2&7],8);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+
-+	&pxor	(@X[0],@X[-7&7]);	# "X[0]"^="X[-28]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	if ($Xi%5) {
-+	  &movdqa	(@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX...
-+	} else {			# ... or load next one
-+	  &movdqa	(@Tx[2],eval(2*16*($Xi/5)-64)."($K_XX_XX)");
-+	}
-+	 eval(shift(@insns));		# ror
-+	  &paddd	(@Tx[1],@X[-1&7]);
-+	 eval(shift(@insns));
-+
-+	&pxor	(@X[0],@Tx[0]);		# "X[0]"^="X[-6]"
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns))		if (@insns[0] =~ /_ror/);
-+
-+	&movdqa	(@Tx[0],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# body_20_39
-+
-+	&pslld	(@X[0],2);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&psrld	(@Tx[0],30);
-+	 eval(shift(@insns))		if (@insns[0] =~ /_rol/);# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+
-+	&por	(@X[0],@Tx[0]);		# "X[0]"<<<=2
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns))		if (@insns[1] =~ /_rol/);
-+	 eval(shift(@insns))		if (@insns[0] =~ /_rol/);
-+	  &pshufd(@Tx[1],@X[-1&7],0xee)	if ($Xi<19);	# was &movdqa	(@Tx[1],@X[0])
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+
-+	 foreach (@insns) { eval; }	# remaining instructions
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+		push(@Tx,shift(@Tx));
-+}
-+
-+sub Xuplast_ssse3_80()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &paddd	(@Tx[1],@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	  &movdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer IALU
-+
-+	 foreach (@insns) { eval; }		# remaining instructions
-+
-+	&cmp	($inp,$num);
-+	&je	(".Ldone_ssse3");
-+
-+	unshift(@Tx,pop(@Tx));
-+
-+	&movdqa	(@X[2],"64($K_XX_XX)");		# pbswap mask
-+	&movdqa	(@Tx[1],"-64($K_XX_XX)");	# K_00_19
-+	&movdqu	(@X[-4&7],"0($inp)");		# load input
-+	&movdqu	(@X[-3&7],"16($inp)");
-+	&movdqu	(@X[-2&7],"32($inp)");
-+	&movdqu	(@X[-1&7],"48($inp)");
-+	&pshufb	(@X[-4&7],@X[2]);		# byte swap
-+	&add	($inp,64);
-+
-+  $Xi=0;
-+}
-+
-+sub Xloop_ssse3()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&pshufb	(@X[($Xi-3)&7],@X[2]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&paddd	(@X[($Xi-4)&7],@Tx[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&movdqa	(eval(16*$Xi)."(%rsp)",@X[($Xi-4)&7]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&psubd	(@X[($Xi-4)&7],@Tx[1]);
-+
-+	foreach (@insns) { eval; }
-+  $Xi++;
-+}
-+
-+sub Xtail_ssse3()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	foreach (@insns) { eval; }
-+}
-+
-+sub body_00_19 () {	# ((c^d)&b)^d
-+	# on start @T[0]=(c^d)&b
-+	return &body_20_39() if ($rx==19); $rx++;
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.
-+	'&$_ror	($b,$j?7:2)',	# $b>>>2
-+	'&xor	(@T[0],$d)',
-+	'&mov	(@T[1],$a)',	# $b for next round
-+
-+	'&add	($e,eval(4*($j&15))."(%rsp)")',	# X[]+K xfer
-+	'&xor	($b,$c)',	# $c^$d for next round
-+
-+	'&$_rol	($a,5)',
-+	'&add	($e,@T[0])',
-+	'&and	(@T[1],$b)',	# ($b&($c^$d)) for next round
-+
-+	'&xor	($b,$c)',	# restore $b
-+	'&add	($e,$a);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+}
-+
-+sub body_20_39 () {	# b^d^c
-+	# on entry @T[0]=b^d
-+	return &body_40_59() if ($rx==39); $rx++;
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.
-+	'&add	($e,eval(4*($j&15))."(%rsp)")',	# X[]+K xfer
-+	'&xor	(@T[0],$d)	if($j==19);'.
-+	'&xor	(@T[0],$c)	if($j> 19)',	# ($b^$d^$c)
-+	'&mov	(@T[1],$a)',	# $b for next round
-+
-+	'&$_rol	($a,5)',
-+	'&add	($e,@T[0])',
-+	'&xor	(@T[1],$c)	if ($j< 79)',	# $b^$d for next round
-+
-+	'&$_ror	($b,7)',	# $b>>>2
-+	'&add	($e,$a);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+}
-+
-+sub body_40_59 () {	# ((b^c)&(c^d))^c
-+	# on entry @T[0]=(b^c), (c^=d)
-+	$rx++;
-+	(
-+	'($a,$b,$c,$d,$e)=@V;'.
-+	'&add	($e,eval(4*($j&15))."(%rsp)")',	# X[]+K xfer
-+	'&and	(@T[0],$c)	if ($j>=40)',	# (b^c)&(c^d)
-+	'&xor	($c,$d)		if ($j>=40)',	# restore $c
-+
-+	'&$_ror	($b,7)',	# $b>>>2
-+	'&mov	(@T[1],$a)',	# $b for next round
-+	'&xor	(@T[0],$c)',
-+
-+	'&$_rol	($a,5)',
-+	'&add	($e,@T[0])',
-+	'&xor	(@T[1],$c)	if ($j==59);'.
-+	'&xor	(@T[1],$b)	if ($j< 59)',	# b^c for next round
-+
-+	'&xor	($b,$c)		if ($j< 59)',	# c^d for next round
-+	'&add	($e,$a);'	.'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
-+	);
-+}
-+$code.=<<___;
-+.align	16
-+.Loop_ssse3:
-+___
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_16_31(\&body_00_19);
-+	&Xupdate_ssse3_32_79(\&body_00_19);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_40_59);
-+	&Xupdate_ssse3_32_79(\&body_20_39);
-+	&Xuplast_ssse3_80(\&body_20_39);	# can jump to "done"
-+
-+				$saved_j=$j; @saved_V=@V;
-+
-+	&Xloop_ssse3(\&body_20_39);
-+	&Xloop_ssse3(\&body_20_39);
-+	&Xloop_ssse3(\&body_20_39);
-+
-+$code.=<<___;
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	add	12($ctx),$D
-+	mov	$A,0($ctx)
-+	add	16($ctx),$E
-+	mov	@T[0],4($ctx)
-+	mov	@T[0],$B			# magic seed
-+	mov	$C,8($ctx)
-+	mov	$C,@T[1]
-+	mov	$D,12($ctx)
-+	xor	$D,@T[1]
-+	mov	$E,16($ctx)
-+	and	@T[1],@T[0]
-+	jmp	.Loop_ssse3
-+
-+.align	16
-+.Ldone_ssse3:
-+___
-+				$j=$saved_j; @V=@saved_V;
-+
-+	&Xtail_ssse3(\&body_20_39);
-+	&Xtail_ssse3(\&body_20_39);
-+	&Xtail_ssse3(\&body_20_39);
-+
-+$code.=<<___;
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	mov	$A,0($ctx)
-+	add	12($ctx),$D
-+	mov	@T[0],4($ctx)
-+	add	16($ctx),$E
-+	mov	$C,8($ctx)
-+	mov	$D,12($ctx)
-+	mov	$E,16($ctx)
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-40-6*16(%r14),%xmm6
-+	movaps	-40-5*16(%r14),%xmm7
-+	movaps	-40-4*16(%r14),%xmm8
-+	movaps	-40-3*16(%r14),%xmm9
-+	movaps	-40-2*16(%r14),%xmm10
-+	movaps	-40-1*16(%r14),%xmm11
-+___
-+$code.=<<___;
-+	lea	(%r14),%rsi
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lepilogue_ssse3:
-+	ret
-+.size	sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3
-+___
-+
-+if ($avx) {
-+$Xi=4;				# reset variables
-+@X=map("%xmm$_",(4..7,0..3));
-+@Tx=map("%xmm$_",(8..10));
-+$j=0;
-+$rx=0;
-+
-+my $done_avx_label=".Ldone_avx";
-+
-+my $_rol=sub { &shld(@_[0],@_) };
-+my $_ror=sub { &shrd(@_[0],@_) };
-+
-+$code.=<<___;
-+.type	sha1_block_data_order_avx,\@function,3
-+.align	16
-+sha1_block_data_order_avx:
-+_avx_shortcut:
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13		# redundant, done to share Win64 SE handler
-+	push	%r14
-+	lea	`-64-($win64?6*16:0)`(%rsp),%rsp
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	vmovaps	%xmm6,-40-6*16(%rax)
-+	vmovaps	%xmm7,-40-5*16(%rax)
-+	vmovaps	%xmm8,-40-4*16(%rax)
-+	vmovaps	%xmm9,-40-3*16(%rax)
-+	vmovaps	%xmm10,-40-2*16(%rax)
-+	vmovaps	%xmm11,-40-1*16(%rax)
-+.Lprologue_avx:
-+___
-+$code.=<<___;
-+	mov	%rax,%r14	# original %rsp
-+	and	\$-64,%rsp
-+	mov	%rdi,$ctx	# reassigned argument
-+	mov	%rsi,$inp	# reassigned argument
-+	mov	%rdx,$num	# reassigned argument
-+
-+	shl	\$6,$num
-+	add	$inp,$num
-+	lea	K_XX_XX+64(%rip),$K_XX_XX
-+
-+	mov	0($ctx),$A		# load context
-+	mov	4($ctx),$B
-+	mov	8($ctx),$C
-+	mov	12($ctx),$D
-+	mov	$B,@T[0]		# magic seed
-+	mov	16($ctx),$E
-+	mov	$C,@T[1]
-+	xor	$D,@T[1]
-+	and	@T[1],@T[0]
-+
-+	vmovdqa	64($K_XX_XX),@X[2]	# pbswap mask
-+	vmovdqa	-64($K_XX_XX),$Kx	# K_00_19
-+	vmovdqu	0($inp),@X[-4&7]	# load input to %xmm[0-3]
-+	vmovdqu	16($inp),@X[-3&7]
-+	vmovdqu	32($inp),@X[-2&7]
-+	vmovdqu	48($inp),@X[-1&7]
-+	vpshufb	@X[2],@X[-4&7],@X[-4&7]	# byte swap
-+	add	\$64,$inp
-+	vpshufb	@X[2],@X[-3&7],@X[-3&7]
-+	vpshufb	@X[2],@X[-2&7],@X[-2&7]
-+	vpshufb	@X[2],@X[-1&7],@X[-1&7]
-+	vpaddd	$Kx,@X[-4&7],@X[0]	# add K_00_19
-+	vpaddd	$Kx,@X[-3&7],@X[1]
-+	vpaddd	$Kx,@X[-2&7],@X[2]
-+	vmovdqa	@X[0],0(%rsp)		# X[]+K xfer to IALU
-+	vmovdqa	@X[1],16(%rsp)
-+	vmovdqa	@X[2],32(%rsp)
-+	jmp	.Loop_avx
-+___
-+
-+sub Xupdate_avx_16_31()		# recall that $Xi starts wtih 4
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 40 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpalignr(@X[0],@X[-3&7],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	  &vpaddd	(@Tx[1],$Kx,@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpsrldq(@Tx[0],@X[-1&7],4);		# "X[-3]", 3 dwords
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"^="X[-16]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@Tx[0],@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vmovdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpsrld	(@Tx[0],@X[0],31);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpslldq(@Tx[2],@X[0],12);		# "X[0]"<<96, extract one dword
-+	&vpaddd	(@X[0],@X[0],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpsrld	(@Tx[1],@Tx[2],30);
-+	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=1
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpslld	(@Tx[2],@Tx[2],2);
-+	&vpxor	(@X[0],@X[0],@Tx[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@Tx[2]);		# "X[0]"^=("X[0]">>96)<<<2
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vmovdqa	($Kx,eval(2*16*(($Xi)/5)-64)."($K_XX_XX)")	if ($Xi%5==0);	# K_XX_XX
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+
-+	 foreach (@insns) { eval; }	# remaining instructions [if any]
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xupdate_avx_32_79()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 to 44 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	&vpalignr(@Tx[0],@X[-1&7],@X[-2&7],8);	# compose "X[-6]"
-+	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"="X[-32]"^"X[-16]"
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+
-+	&vpxor	(@X[0],@X[0],@X[-7&7]);		# "X[0]"^="X[-28]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns))	if (@insns[0] !~ /&ro[rl]/);
-+	  &vpaddd	(@Tx[1],$Kx,@X[-1&7]);
-+	  &vmovdqa	($Kx,eval(2*16*($Xi/5)-64)."($K_XX_XX)")	if ($Xi%5==0);
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-6]"
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+
-+	&vpsrld	(@Tx[0],@X[0],30);
-+	  &vmovdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+
-+	&vpslld	(@X[0],@X[0],2);
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# ror
-+	 eval(shift(@insns));
-+
-+	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=2
-+	 eval(shift(@insns));		# body_20_39
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));		# rol
-+	 eval(shift(@insns));
-+
-+	 foreach (@insns) { eval; }	# remaining instructions
-+
-+  $Xi++;	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xuplast_avx_80()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	  &vpaddd	(@Tx[1],$Kx,@X[-1&7]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	  &vmovdqa	(eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]);	# X[]+K xfer IALU
-+
-+	 foreach (@insns) { eval; }		# remaining instructions
-+
-+	&cmp	($inp,$num);
-+	&je	($done_avx_label);
-+
-+	&vmovdqa(@X[2],"64($K_XX_XX)");		# pbswap mask
-+	&vmovdqa($Kx,"-64($K_XX_XX)");		# K_00_19
-+	&vmovdqu(@X[-4&7],"0($inp)");		# load input
-+	&vmovdqu(@X[-3&7],"16($inp)");
-+	&vmovdqu(@X[-2&7],"32($inp)");
-+	&vmovdqu(@X[-1&7],"48($inp)");
-+	&vpshufb(@X[-4&7],@X[-4&7],@X[2]);	# byte swap
-+	&add	($inp,64);
-+
-+  $Xi=0;
-+}
-+
-+sub Xloop_avx()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpshufb(@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vpaddd	(@X[$Xi&7],@X[($Xi-4)&7],$Kx);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vmovdqa(eval(16*$Xi)."(%rsp)",@X[$Xi&7]);	# X[]+K xfer to IALU
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	foreach (@insns) { eval; }
-+  $Xi++;
-+}
-+
-+sub Xtail_avx()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	foreach (@insns) { eval; }
-+}
-+
-+$code.=<<___;
-+.align	16
-+.Loop_avx:
-+___
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_16_31(\&body_00_19);
-+	&Xupdate_avx_32_79(\&body_00_19);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_40_59);
-+	&Xupdate_avx_32_79(\&body_20_39);
-+	&Xuplast_avx_80(\&body_20_39);	# can jump to "done"
-+
-+				$saved_j=$j; @saved_V=@V;
-+
-+	&Xloop_avx(\&body_20_39);
-+	&Xloop_avx(\&body_20_39);
-+	&Xloop_avx(\&body_20_39);
-+
-+$code.=<<___;
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	add	12($ctx),$D
-+	mov	$A,0($ctx)
-+	add	16($ctx),$E
-+	mov	@T[0],4($ctx)
-+	mov	@T[0],$B			# magic seed
-+	mov	$C,8($ctx)
-+	mov	$C,@T[1]
-+	mov	$D,12($ctx)
-+	xor	$D,@T[1]
-+	mov	$E,16($ctx)
-+	and	@T[1],@T[0]
-+	jmp	.Loop_avx
-+
-+.align	16
-+$done_avx_label:
-+___
-+				$j=$saved_j; @V=@saved_V;
-+
-+	&Xtail_avx(\&body_20_39);
-+	&Xtail_avx(\&body_20_39);
-+	&Xtail_avx(\&body_20_39);
-+
-+$code.=<<___;
-+	vzeroupper
-+
-+	add	0($ctx),$A			# update context
-+	add	4($ctx),@T[0]
-+	add	8($ctx),$C
-+	mov	$A,0($ctx)
-+	add	12($ctx),$D
-+	mov	@T[0],4($ctx)
-+	add	16($ctx),$E
-+	mov	$C,8($ctx)
-+	mov	$D,12($ctx)
-+	mov	$E,16($ctx)
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-40-6*16(%r14),%xmm6
-+	movaps	-40-5*16(%r14),%xmm7
-+	movaps	-40-4*16(%r14),%xmm8
-+	movaps	-40-3*16(%r14),%xmm9
-+	movaps	-40-2*16(%r14),%xmm10
-+	movaps	-40-1*16(%r14),%xmm11
-+___
-+$code.=<<___;
-+	lea	(%r14),%rsi
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lepilogue_avx:
-+	ret
-+.size	sha1_block_data_order_avx,.-sha1_block_data_order_avx
-+___
-+
-+if ($avx>1) {
-+use integer;
-+$Xi=4;					# reset variables
-+@X=map("%ymm$_",(4..7,0..3));
-+@Tx=map("%ymm$_",(8..10));
-+$Kx="%ymm11";
-+$j=0;
-+
-+my @ROTX=("%eax","%ebp","%ebx","%ecx","%edx","%esi");
-+my ($a5,$t0)=("%r12d","%edi");
-+
-+my ($A,$F,$B,$C,$D,$E)=@ROTX;
-+my $rx=0;
-+my $frame="%r13";
-+
-+$code.=<<___;
-+.type	sha1_block_data_order_avx2,\@function,3
-+.align	16
-+sha1_block_data_order_avx2:
-+_avx2_shortcut:
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	lea	-6*16(%rsp),%rsp
-+	vmovaps	%xmm6,-40-6*16(%rax)
-+	vmovaps	%xmm7,-40-5*16(%rax)
-+	vmovaps	%xmm8,-40-4*16(%rax)
-+	vmovaps	%xmm9,-40-3*16(%rax)
-+	vmovaps	%xmm10,-40-2*16(%rax)
-+	vmovaps	%xmm11,-40-1*16(%rax)
-+.Lprologue_avx2:
-+___
-+$code.=<<___;
-+	mov	%rax,%r14		# original %rsp
-+	mov	%rdi,$ctx		# reassigned argument
-+	mov	%rsi,$inp		# reassigned argument
-+	mov	%rdx,$num		# reassigned argument
-+
-+	lea	-640(%rsp),%rsp
-+	shl	\$6,$num
-+	 lea	64($inp),$frame
-+	and	\$-128,%rsp
-+	add	$inp,$num
-+	lea	K_XX_XX+64(%rip),$K_XX_XX
-+
-+	mov	0($ctx),$A		# load context
-+	 cmp	$num,$frame
-+	 cmovae	$inp,$frame		# next or same block
-+	mov	4($ctx),$F
-+	mov	8($ctx),$C
-+	mov	12($ctx),$D
-+	mov	16($ctx),$E
-+	vmovdqu	64($K_XX_XX),@X[2]	# pbswap mask
-+
-+	vmovdqu		($inp),%xmm0
-+	vmovdqu		16($inp),%xmm1
-+	vmovdqu		32($inp),%xmm2
-+	vmovdqu		48($inp),%xmm3
-+	lea		64($inp),$inp
-+	vinserti128	\$1,($frame),@X[-4&7],@X[-4&7]
-+	vinserti128	\$1,16($frame),@X[-3&7],@X[-3&7]
-+	vpshufb		@X[2],@X[-4&7],@X[-4&7]
-+	vinserti128	\$1,32($frame),@X[-2&7],@X[-2&7]
-+	vpshufb		@X[2],@X[-3&7],@X[-3&7]
-+	vinserti128	\$1,48($frame),@X[-1&7],@X[-1&7]
-+	vpshufb		@X[2],@X[-2&7],@X[-2&7]
-+	vmovdqu		-64($K_XX_XX),$Kx	# K_00_19
-+	vpshufb		@X[2],@X[-1&7],@X[-1&7]
-+
-+	vpaddd	$Kx,@X[-4&7],@X[0]	# add K_00_19
-+	vpaddd	$Kx,@X[-3&7],@X[1]
-+	vmovdqu	@X[0],0(%rsp)		# X[]+K xfer to IALU
-+	vpaddd	$Kx,@X[-2&7],@X[2]
-+	vmovdqu	@X[1],32(%rsp)
-+	vpaddd	$Kx,@X[-1&7],@X[3]
-+	vmovdqu	@X[2],64(%rsp)
-+	vmovdqu	@X[3],96(%rsp)
-+___
-+for (;$Xi<8;$Xi++) {	# Xupdate_avx2_16_31
-+    use integer;
-+
-+	&vpalignr(@X[0],@X[-3&7],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
-+	&vpsrldq(@Tx[0],@X[-1&7],4);		# "X[-3]", 3 dwords
-+	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"^="X[-16]"
-+	&vpxor	(@Tx[0],@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
-+	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-3]"^"X[-8]"
-+	&vpsrld	(@Tx[0],@X[0],31);
-+	&vmovdqu($Kx,eval(2*16*(($Xi)/5)-64)."($K_XX_XX)")	if ($Xi%5==0);	# K_XX_XX
-+	&vpslldq(@Tx[2],@X[0],12);		# "X[0]"<<96, extract one dword
-+	&vpaddd	(@X[0],@X[0],@X[0]);
-+	&vpsrld	(@Tx[1],@Tx[2],30);
-+	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=1
-+	&vpslld	(@Tx[2],@Tx[2],2);
-+	&vpxor	(@X[0],@X[0],@Tx[1]);
-+	&vpxor	(@X[0],@X[0],@Tx[2]);		# "X[0]"^=("X[0]">>96)<<<2
-+	&vpaddd	(@Tx[1],@X[0],$Kx);
-+	&vmovdqu("32*$Xi(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+
-+	push(@X,shift(@X));	# "rotate" X[]
-+}
-+$code.=<<___;
-+	lea	128(%rsp),$frame
-+	jmp	.Loop_avx2
-+.align	32
-+.Loop_avx2:
-+	rorx	\$2,$F,$B
-+	andn	$D,$F,$t0
-+	and	$C,$F
-+	xor	$t0,$F
-+___
-+sub bodyx_00_19 () {	# 8 instructions, 3 cycles critical path
-+	# at start $f=(b&c)^(~b&d), $b>>>=2
-+	return &bodyx_20_39() if ($rx==19); $rx++;
-+	(
-+	'($a,$f,$b,$c,$d,$e)=@ROTX;'.
-+
-+	'&add	($e,((32*($j/4)+4*($j%4))%256-128)."($frame)");'.	# e+=X[i]+K
-+	 '&lea	($frame,"256($frame)")	if ($j%32==31);',
-+	'&andn	($t0,$a,$c)',			# ~b&d for next round
-+
-+	'&add	($e,$f)',			# e+=(b&c)^(~b&d)
-+	'&rorx	($a5,$a,27)',			# a<<<5
-+	'&rorx	($f,$a,2)',			# b>>>2 for next round
-+	'&and	($a,$b)',			# b&c for next round
-+
-+	'&add	($e,$a5)',			# e+=a<<<5
-+	'&xor	($a,$t0);'.			# f=(b&c)^(~b&d) for next round
-+
-+	'unshift(@ROTX,pop(@ROTX)); $j++;'
-+	)
-+}
-+
-+sub bodyx_20_39 () {	# 7 instructions, 2 cycles critical path
-+	# on entry $f=b^c^d, $b>>>=2
-+	return &bodyx_40_59() if ($rx==39); $rx++;
-+	(
-+	'($a,$f,$b,$c,$d,$e)=@ROTX;'.
-+
-+	'&add	($e,((32*($j/4)+4*($j%4))%256-128)."($frame)");'.	# e+=X[i]+K
-+	 '&lea	($frame,"256($frame)")	if ($j%32==31);',
-+
-+	'&lea	($e,"($e,$f)")',		# e+=b^c^d
-+	'&rorx	($a5,$a,27)',			# a<<<5
-+	'&rorx	($f,$a,2)	if ($j<79)',	# b>>>2 in next round
-+	'&xor	($a,$b)		if ($j<79)',	# b^c for next round
-+
-+	'&add	($e,$a5)',			# e+=a<<<5
-+	'&xor	($a,$c)		if ($j<79);'.	# f=b^c^d for next round
-+
-+	'unshift(@ROTX,pop(@ROTX)); $j++;'
-+	)
-+}
-+
-+sub bodyx_40_59 () {	# 10 instructions, 3 cycles critical path
-+	# on entry $f=((b^c)&(c^d)), $b>>>=2
-+	$rx++;
-+	(
-+	'($a,$f,$b,$c,$d,$e)=@ROTX;'.
-+
-+	'&add	($e,((32*($j/4)+4*($j%4))%256-128)."($frame)");'.	# e+=X[i]+K
-+	 '&lea	($frame,"256($frame)")	if ($j%32==31);',
-+	'&xor	($f,$c)		if ($j>39)',	# (b^c)&(c^d)^c
-+	'&mov	($t0,$b)	if ($j<59)',	# count on zero latency
-+	'&xor	($t0,$c)	if ($j<59)',	# c^d for next round
-+
-+	'&lea	($e,"($e,$f)")',		# e+=(b^c)&(c^d)^c
-+	'&rorx	($a5,$a,27)',			# a<<<5
-+	'&rorx	($f,$a,2)',			# b>>>2 in next round
-+	'&xor	($a,$b)',			# b^c for next round
-+
-+	'&add	($e,$a5)',			# e+=a<<<5
-+	'&and	($a,$t0)	if ($j< 59);'.	# f=(b^c)&(c^d) for next round
-+	'&xor	($a,$c)		if ($j==59);'.	# f=b^c^d for next round
-+
-+	'unshift(@ROTX,pop(@ROTX)); $j++;'
-+	)
-+}
-+
-+sub Xupdate_avx2_16_31()		# recall that $Xi starts wtih 4
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body,&$body);	# 35 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	&vpalignr(@X[0],@X[-3&7],@X[-4&7],8);	# compose "X[-14]" in "X[0]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpsrldq(@Tx[0],@X[-1&7],4);		# "X[-3]", 3 dwords
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"^="X[-16]"
-+	&vpxor	(@Tx[0],@Tx[0],@X[-2&7]);	# "X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-3]"^"X[-8]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpsrld	(@Tx[0],@X[0],31);
-+	&vmovdqu($Kx,eval(2*16*(($Xi)/5)-64)."($K_XX_XX)")	if ($Xi%5==0);	# K_XX_XX
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpslldq(@Tx[2],@X[0],12);		# "X[0]"<<96, extract one dword
-+	&vpaddd	(@X[0],@X[0],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpsrld	(@Tx[1],@Tx[2],30);
-+	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=1
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpslld	(@Tx[2],@Tx[2],2);
-+	&vpxor	(@X[0],@X[0],@Tx[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@Tx[2]);		# "X[0]"^=("X[0]">>96)<<<2
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpaddd	(@Tx[1],@X[0],$Kx);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vmovdqu(eval(32*($Xi))."(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+
-+	 foreach (@insns) { eval; }	# remaining instructions [if any]
-+
-+	$Xi++;
-+	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xupdate_avx2_32_79()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body,&$body);	# 35 to 50 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	&vpalignr(@Tx[0],@X[-1&7],@X[-2&7],8);	# compose "X[-6]"
-+	&vpxor	(@X[0],@X[0],@X[-4&7]);		# "X[0]"="X[-32]"^"X[-16]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@X[-7&7]);		# "X[0]"^="X[-28]"
-+	&vmovdqu($Kx,eval(2*16*($Xi/5)-64)."($K_XX_XX)")	if ($Xi%5==0);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpxor	(@X[0],@X[0],@Tx[0]);		# "X[0]"^="X[-6]"
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpsrld	(@Tx[0],@X[0],30);
-+	&vpslld	(@X[0],@X[0],2);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	#&vpslld	(@X[0],@X[0],2);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpor	(@X[0],@X[0],@Tx[0]);		# "X[0]"<<<=2
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vpaddd	(@Tx[1],@X[0],$Kx);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	&vmovdqu("32*$Xi(%rsp)",@Tx[1]);	# X[]+K xfer to IALU
-+
-+	 foreach (@insns) { eval; }	# remaining instructions
-+
-+	$Xi++;
-+	push(@X,shift(@X));	# "rotate" X[]
-+}
-+
-+sub Xloop_avx2()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body,&$body);	# 32 instructions
-+  my ($a,$b,$c,$d,$e);
-+
-+	 foreach (@insns) { eval; }
-+}
-+
-+	&align32();
-+	&Xupdate_avx2_32_79(\&bodyx_00_19);
-+	&Xupdate_avx2_32_79(\&bodyx_00_19);
-+	&Xupdate_avx2_32_79(\&bodyx_00_19);
-+	&Xupdate_avx2_32_79(\&bodyx_00_19);
-+
-+	&Xupdate_avx2_32_79(\&bodyx_20_39);
-+	&Xupdate_avx2_32_79(\&bodyx_20_39);
-+	&Xupdate_avx2_32_79(\&bodyx_20_39);
-+	&Xupdate_avx2_32_79(\&bodyx_20_39);
-+
-+	&align32();
-+	&Xupdate_avx2_32_79(\&bodyx_40_59);
-+	&Xupdate_avx2_32_79(\&bodyx_40_59);
-+	&Xupdate_avx2_32_79(\&bodyx_40_59);
-+	&Xupdate_avx2_32_79(\&bodyx_40_59);
-+
-+	&Xloop_avx2(\&bodyx_20_39);
-+	&Xloop_avx2(\&bodyx_20_39);
-+	&Xloop_avx2(\&bodyx_20_39);
-+	&Xloop_avx2(\&bodyx_20_39);
-+
-+$code.=<<___;
-+	lea	128($inp),$frame
-+	lea	128($inp),%rdi			# borrow $t0
-+	cmp	$num,$frame
-+	cmovae	$inp,$frame			# next or previous block
-+
-+	# output is d-e-[a]-f-b-c => A=d,F=e,C=f,D=b,E=c
-+	add	0($ctx),@ROTX[0]		# update context
-+	add	4($ctx),@ROTX[1]
-+	add	8($ctx),@ROTX[3]
-+	mov	@ROTX[0],0($ctx)
-+	add	12($ctx),@ROTX[4]
-+	mov	@ROTX[1],4($ctx)
-+	 mov	@ROTX[0],$A			# A=d
-+	add	16($ctx),@ROTX[5]
-+	 mov	@ROTX[3],$a5
-+	mov	@ROTX[3],8($ctx)
-+	 mov	@ROTX[4],$D			# D=b
-+	 #xchg	@ROTX[5],$F			# F=c, C=f
-+	mov	@ROTX[4],12($ctx)
-+	 mov	@ROTX[1],$F			# F=e
-+	mov	@ROTX[5],16($ctx)
-+	#mov	$F,16($ctx)
-+	 mov	@ROTX[5],$E			# E=c
-+	 mov	$a5,$C				# C=f
-+	 #xchg	$F,$E				# E=c, F=e
-+
-+	cmp	$num,$inp
-+	je	.Ldone_avx2
-+___
-+
-+$Xi=4;				# reset variables
-+@X=map("%ymm$_",(4..7,0..3));
-+
-+$code.=<<___;
-+	vmovdqu	64($K_XX_XX),@X[2]		# pbswap mask
-+	cmp	$num,%rdi			# borrowed $t0
-+	ja	.Last_avx2
-+
-+	vmovdqu		-64(%rdi),%xmm0		# low part of @X[-4&7]
-+	vmovdqu		-48(%rdi),%xmm1
-+	vmovdqu		-32(%rdi),%xmm2
-+	vmovdqu		-16(%rdi),%xmm3
-+	vinserti128	\$1,0($frame),@X[-4&7],@X[-4&7]
-+	vinserti128	\$1,16($frame),@X[-3&7],@X[-3&7]
-+	vinserti128	\$1,32($frame),@X[-2&7],@X[-2&7]
-+	vinserti128	\$1,48($frame),@X[-1&7],@X[-1&7]
-+	jmp	.Last_avx2
-+
-+.align	32
-+.Last_avx2:
-+	lea	128+16(%rsp),$frame
-+	rorx	\$2,$F,$B
-+	andn	$D,$F,$t0
-+	and	$C,$F
-+	xor	$t0,$F
-+	sub	\$-128,$inp
-+___
-+	$rx=$j=0;	@ROTX=($A,$F,$B,$C,$D,$E);
-+
-+	&Xloop_avx2	(\&bodyx_00_19);
-+	&Xloop_avx2	(\&bodyx_00_19);
-+	&Xloop_avx2	(\&bodyx_00_19);
-+	&Xloop_avx2	(\&bodyx_00_19);
-+
-+	&Xloop_avx2	(\&bodyx_20_39);
-+	  &vmovdqu	($Kx,"-64($K_XX_XX)");		# K_00_19
-+	  &vpshufb	(@X[-4&7],@X[-4&7],@X[2]);	# byte swap
-+	&Xloop_avx2	(\&bodyx_20_39);
-+	  &vpshufb	(@X[-3&7],@X[-3&7],@X[2]);
-+	  &vpaddd	(@Tx[0],@X[-4&7],$Kx);		# add K_00_19
-+	&Xloop_avx2	(\&bodyx_20_39);
-+	  &vmovdqu	("0(%rsp)",@Tx[0]);
-+	  &vpshufb	(@X[-2&7],@X[-2&7],@X[2]);
-+	  &vpaddd	(@Tx[1],@X[-3&7],$Kx);
-+	&Xloop_avx2	(\&bodyx_20_39);
-+	  &vmovdqu	("32(%rsp)",@Tx[1]);
-+	  &vpshufb	(@X[-1&7],@X[-1&7],@X[2]);
-+	  &vpaddd	(@X[2],@X[-2&7],$Kx);
-+
-+	&Xloop_avx2	(\&bodyx_40_59);
-+	&align32	();
-+	  &vmovdqu	("64(%rsp)",@X[2]);
-+	  &vpaddd	(@X[3],@X[-1&7],$Kx);
-+	&Xloop_avx2	(\&bodyx_40_59);
-+	  &vmovdqu	("96(%rsp)",@X[3]);
-+	&Xloop_avx2	(\&bodyx_40_59);
-+	&Xupdate_avx2_16_31(\&bodyx_40_59);
-+
-+	&Xupdate_avx2_16_31(\&bodyx_20_39);
-+	&Xupdate_avx2_16_31(\&bodyx_20_39);
-+	&Xupdate_avx2_16_31(\&bodyx_20_39);
-+	&Xloop_avx2	(\&bodyx_20_39);
-+
-+$code.=<<___;
-+	lea	128(%rsp),$frame
-+
-+	# output is d-e-[a]-f-b-c => A=d,F=e,C=f,D=b,E=c
-+	add	0($ctx),@ROTX[0]		# update context
-+	add	4($ctx),@ROTX[1]
-+	add	8($ctx),@ROTX[3]
-+	mov	@ROTX[0],0($ctx)
-+	add	12($ctx),@ROTX[4]
-+	mov	@ROTX[1],4($ctx)
-+	 mov	@ROTX[0],$A			# A=d
-+	add	16($ctx),@ROTX[5]
-+	 mov	@ROTX[3],$a5
-+	mov	@ROTX[3],8($ctx)
-+	 mov	@ROTX[4],$D			# D=b
-+	 #xchg	@ROTX[5],$F			# F=c, C=f
-+	mov	@ROTX[4],12($ctx)
-+	 mov	@ROTX[1],$F			# F=e
-+	mov	@ROTX[5],16($ctx)
-+	#mov	$F,16($ctx)
-+	 mov	@ROTX[5],$E			# E=c
-+	 mov	$a5,$C				# C=f
-+	 #xchg	$F,$E				# E=c, F=e
-+
-+	cmp	$num,$inp
-+	jbe	.Loop_avx2
-+
-+.Ldone_avx2:
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-40-6*16(%r14),%xmm6
-+	movaps	-40-5*16(%r14),%xmm7
-+	movaps	-40-4*16(%r14),%xmm8
-+	movaps	-40-3*16(%r14),%xmm9
-+	movaps	-40-2*16(%r14),%xmm10
-+	movaps	-40-1*16(%r14),%xmm11
-+___
-+$code.=<<___;
-+	lea	(%r14),%rsi
-+	mov	-40(%rsi),%r14
-+	mov	-32(%rsi),%r13
-+	mov	-24(%rsi),%r12
-+	mov	-16(%rsi),%rbp
-+	mov	-8(%rsi),%rbx
-+	lea	(%rsi),%rsp
-+.Lepilogue_avx2:
-+	ret
-+.size	sha1_block_data_order_avx2,.-sha1_block_data_order_avx2
-+___
-+}
-+}
-+$code.=<<___;
-+.align	64
-+K_XX_XX:
-+.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	# K_00_19
-+.long	0x5a827999,0x5a827999,0x5a827999,0x5a827999	# K_00_19
-+.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	# K_20_39
-+.long	0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1	# K_20_39
-+.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	# K_40_59
-+.long	0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc	# K_40_59
-+.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	# K_60_79
-+.long	0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6	# K_60_79
-+.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	# pbswap mask
-+.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	# pbswap mask
-+.byte	0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0
-+___
-+}}}
-+$code.=<<___;
-+.asciz	"SHA1 block transform for x86_64, CRYPTOGAMS by "
-+.align	64
-+___
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lprologue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lprologue
-+	jb	.Lcommon_seh_tail
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	lea	.Lepilogue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
-+	jae	.Lcommon_seh_tail
-+
-+	mov	`16*4`(%rax),%rax	# pull saved stack pointer
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+
-+	jmp	.Lcommon_seh_tail
-+.size	se_handler,.-se_handler
-+___
-+
-+$code.=<<___ if ($shaext);
-+.type	shaext_handler,\@abi-omnipotent
-+.align	16
-+shaext_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lprologue_shaext(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lprologue
-+	jb	.Lcommon_seh_tail
-+
-+	lea	.Lepilogue_shaext(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
-+	jae	.Lcommon_seh_tail
-+
-+	lea	-8-4*16(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$8,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	jmp	.Lcommon_seh_tail
-+.size	shaext_handler,.-shaext_handler
-+___
-+
-+$code.=<<___;
-+.type	ssse3_handler,\@abi-omnipotent
-+.align	16
-+ssse3_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lcommon_seh_tail
-+
-+	mov	232($context),%rax	# pull context->R14
-+
-+	lea	-40-6*16(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$12,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore cotnext->R12
-+	mov	%r13,224($context)	# restore cotnext->R13
-+	mov	%r14,232($context)	# restore cotnext->R14
-+
-+.Lcommon_seh_tail:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	ssse3_handler,.-ssse3_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_sha1_block_data_order
-+	.rva	.LSEH_end_sha1_block_data_order
-+	.rva	.LSEH_info_sha1_block_data_order
-+___
-+$code.=<<___ if ($shaext);
-+	.rva	.LSEH_begin_sha1_block_data_order_shaext
-+	.rva	.LSEH_end_sha1_block_data_order_shaext
-+	.rva	.LSEH_info_sha1_block_data_order_shaext
-+___
-+$code.=<<___;
-+	.rva	.LSEH_begin_sha1_block_data_order_ssse3
-+	.rva	.LSEH_end_sha1_block_data_order_ssse3
-+	.rva	.LSEH_info_sha1_block_data_order_ssse3
-+___
-+$code.=<<___ if ($avx);
-+	.rva	.LSEH_begin_sha1_block_data_order_avx
-+	.rva	.LSEH_end_sha1_block_data_order_avx
-+	.rva	.LSEH_info_sha1_block_data_order_avx
-+___
-+$code.=<<___ if ($avx>1);
-+	.rva	.LSEH_begin_sha1_block_data_order_avx2
-+	.rva	.LSEH_end_sha1_block_data_order_avx2
-+	.rva	.LSEH_info_sha1_block_data_order_avx2
-+___
-+$code.=<<___;
-+.section	.xdata
-+.align	8
-+.LSEH_info_sha1_block_data_order:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+___
-+$code.=<<___ if ($shaext);
-+.LSEH_info_sha1_block_data_order_shaext:
-+	.byte	9,0,0,0
-+	.rva	shaext_handler
-+___
-+$code.=<<___;
-+.LSEH_info_sha1_block_data_order_ssse3:
-+	.byte	9,0,0,0
-+	.rva	ssse3_handler
-+	.rva	.Lprologue_ssse3,.Lepilogue_ssse3	# HandlerData[]
-+___
-+$code.=<<___ if ($avx);
-+.LSEH_info_sha1_block_data_order_avx:
-+	.byte	9,0,0,0
-+	.rva	ssse3_handler
-+	.rva	.Lprologue_avx,.Lepilogue_avx		# HandlerData[]
-+___
-+$code.=<<___ if ($avx>1);
-+.LSEH_info_sha1_block_data_order_avx2:
-+	.byte	9,0,0,0
-+	.rva	ssse3_handler
-+	.rva	.Lprologue_avx2,.Lepilogue_avx2		# HandlerData[]
-+___
-+}
-+
-+####################################################################
-+
-+sub sha1rnds4 {
-+    if (@_[0] =~ /\$([x0-9a-f]+),\s*%xmm([0-7]),\s*%xmm([0-7])/) {
-+      my @opcode=(0x0f,0x3a,0xcc);
-+	push @opcode,0xc0|($2&7)|(($3&7)<<3);		# ModR/M
-+	my $c=$1;
-+	push @opcode,$c=~/^0/?oct($c):$c;
-+	return ".byte\t".join(',',@opcode);
-+    } else {
-+	return "sha1rnds4\t".@_[0];
-+    }
-+}
-+
-+sub sha1op38 {
-+    my $instr = shift;
-+    my %opcodelet = (
-+		"sha1nexte" => 0xc8,
-+  		"sha1msg1"  => 0xc9,
-+		"sha1msg2"  => 0xca	);
-+
-+    if (defined($opcodelet{$instr}) && @_[0] =~ /%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x0f,0x38);
-+      my $rex=0;
-+	$rex|=0x04			if ($2>=8);
-+	$rex|=0x01			if ($1>=8);
-+	unshift @opcode,0x40|$rex	if ($rex);
-+	push @opcode,$opcodelet{$instr};
-+	push @opcode,0xc0|($1&7)|(($2&7)<<3);		# ModR/M
-+	return ".byte\t".join(',',@opcode);
-+    } else {
-+	return $instr."\t".@_[0];
-+    }
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	s/\b(sha1rnds4)\s+(.*)/sha1rnds4($2)/geo	or
-+	s/\b(sha1[^\s]*)\s+(.*)/sha1op38($1,$2)/geo;
-+
-+	print $_,"\n";
-+}
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-586.pl
-new file mode 100644
-index 0000000..6af1d84
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-586.pl
-@@ -0,0 +1,1293 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# SHA256 block transform for x86. September 2007.
-+#
-+# Performance improvement over compiler generated code varies from
-+# 10% to 40% [see below]. Not very impressive on some µ-archs, but
-+# it's 5 times smaller and optimizies amount of writes.
-+#
-+# May 2012.
-+#
-+# Optimization including two of Pavel Semjanov's ideas, alternative
-+# Maj and full unroll, resulted in ~20-25% improvement on most CPUs,
-+# ~7% on Pentium, ~40% on Atom. As fully unrolled loop body is almost
-+# 15x larger, 8KB vs. 560B, it's fired only for longer inputs. But not
-+# on P4, where it kills performance, nor Sandy Bridge, where folded
-+# loop is approximately as fast...
-+#
-+# June 2012.
-+#
-+# Add AMD XOP-specific code path, >30% improvement on Bulldozer over
-+# May version, >60% over original. Add AVX+shrd code path, >25%
-+# improvement on Sandy Bridge over May version, 60% over original.
-+#
-+# May 2013.
-+#
-+# Replace AMD XOP code path with SSSE3 to cover more processors.
-+# (Biggest improvement coefficient is on upcoming Atom Silvermont,
-+# not shown.) Add AVX+BMI code path.
-+#
-+# March 2014.
-+#
-+# Add support for Intel SHA Extensions.
-+#
-+# Performance in clock cycles per processed byte (less is better):
-+#
-+#		gcc	icc	x86 asm(*)	SIMD	x86_64 asm(**)	
-+# Pentium	46	57	40/38		-	-
-+# PIII		36	33	27/24		-	-
-+# P4		41	38	28		-	17.3
-+# AMD K8	27	25	19/15.5		-	14.9
-+# Core2		26	23	18/15.6		14.3	13.8
-+# Westmere	27	-	19/15.7		13.4	12.3
-+# Sandy Bridge	25	-	15.9		12.4	11.6
-+# Ivy Bridge	24	-	15.0		11.4	10.3
-+# Haswell	22	-	13.9		9.46	7.80
-+# Bulldozer	36	-	27/22		17.0	13.6
-+# VIA Nano	36	-	25/22		16.8	16.5
-+# Atom		50	-	30/25		21.9	18.9
-+# Silvermont	40	-	34/31		22.9	20.6
-+#
-+# (*)	numbers after slash are for unrolled loop, where applicable;
-+# (**)	x86_64 assembly performance is presented for reference
-+#	purposes, results are best-available;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
-+
-+$xmm=$avx=0;
-+for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
-+
-+if ($xmm &&	`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+			=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+}
-+
-+if ($xmm && !$avx && $ARGV[0] eq "win32n" &&
-+		`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.03) + ($1>=2.10);
-+}
-+
-+if ($xmm && !$avx && $ARGV[0] eq "win32" &&
-+		`ml 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+}
-+
-+if ($xmm && !$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+$shaext=$xmm;	### set to zero if compiling for 1.0.1
-+
-+$unroll_after = 64*4;	# If pre-evicted from L1P cache first spin of
-+			# fully unrolled loop was measured to run about
-+			# 3-4x slower. If slowdown coefficient is N and
-+			# unrolled loop is m times faster, then you break
-+			# even at (N-1)/(m-1) blocks. Then it needs to be
-+			# adjusted for probability of code being evicted,
-+			# code size/cache size=1/4. Typical m is 1.15...
-+
-+$A="eax";
-+$E="edx";
-+$T="ebx";
-+$Aoff=&DWP(4,"esp");
-+$Boff=&DWP(8,"esp");
-+$Coff=&DWP(12,"esp");
-+$Doff=&DWP(16,"esp");
-+$Eoff=&DWP(20,"esp");
-+$Foff=&DWP(24,"esp");
-+$Goff=&DWP(28,"esp");
-+$Hoff=&DWP(32,"esp");
-+$Xoff=&DWP(36,"esp");
-+$K256="ebp";
-+
-+sub BODY_16_63() {
-+	&mov	($T,"ecx");			# "ecx" is preloaded
-+	 &mov	("esi",&DWP(4*(9+15+16-14),"esp"));
-+	&ror	("ecx",18-7);
-+	 &mov	("edi","esi");
-+	&ror	("esi",19-17);
-+	 &xor	("ecx",$T);
-+	 &shr	($T,3);
-+	&ror	("ecx",7);
-+	 &xor	("esi","edi");
-+	 &xor	($T,"ecx");			# T = sigma0(X[-15])
-+	&ror	("esi",17);
-+	 &add	($T,&DWP(4*(9+15+16),"esp"));	# T += X[-16]
-+	&shr	("edi",10);
-+	 &add	($T,&DWP(4*(9+15+16-9),"esp"));	# T += X[-7]
-+	#&xor	("edi","esi")			# sigma1(X[-2])
-+	# &add	($T,"edi");			# T += sigma1(X[-2])
-+	# &mov	(&DWP(4*(9+15),"esp"),$T);	# save X[0]
-+
-+	&BODY_00_15(1);
-+}
-+sub BODY_00_15() {
-+    my $in_16_63=shift;
-+
-+	&mov	("ecx",$E);
-+	 &xor	("edi","esi")			if ($in_16_63);	# sigma1(X[-2])
-+	 &mov	("esi",$Foff);
-+	&ror	("ecx",25-11);
-+	 &add	($T,"edi")			if ($in_16_63);	# T += sigma1(X[-2])
-+	 &mov	("edi",$Goff);
-+	&xor	("ecx",$E);
-+	 &xor	("esi","edi");
-+	 &mov	($T,&DWP(4*(9+15),"esp"))	if (!$in_16_63);
-+	 &mov	(&DWP(4*(9+15),"esp"),$T)	if ($in_16_63);	# save X[0]
-+	&ror	("ecx",11-6);
-+	 &and	("esi",$E);
-+	 &mov	($Eoff,$E);		# modulo-scheduled
-+	&xor	($E,"ecx");
-+	 &add	($T,$Hoff);		# T += h
-+	 &xor	("esi","edi");		# Ch(e,f,g)
-+	&ror	($E,6);			# Sigma1(e)
-+	 &mov	("ecx",$A);
-+	 &add	($T,"esi");		# T += Ch(e,f,g)
-+
-+	&ror	("ecx",22-13);
-+	 &add	($T,$E);		# T += Sigma1(e)
-+	 &mov	("edi",$Boff);
-+	&xor	("ecx",$A);
-+	 &mov	($Aoff,$A);		# modulo-scheduled
-+	 &lea	("esp",&DWP(-4,"esp"));
-+	&ror	("ecx",13-2);
-+	 &mov	("esi",&DWP(0,$K256));
-+	&xor	("ecx",$A);
-+	 &mov	($E,$Eoff);		# e in next iteration, d in this one
-+	 &xor	($A,"edi");		# a ^= b
-+	&ror	("ecx",2);		# Sigma0(a)
-+
-+	 &add	($T,"esi");		# T+= K[i]
-+	 &mov	(&DWP(0,"esp"),$A);	# (b^c) in next round
-+	&add	($E,$T);		# d += T
-+	 &and	($A,&DWP(4,"esp"));	# a &= (b^c)
-+	&add	($T,"ecx");		# T += Sigma0(a)
-+	 &xor	($A,"edi");		# h = Maj(a,b,c) = Ch(a^b,c,b)
-+	 &mov	("ecx",&DWP(4*(9+15+16-1),"esp"))	if ($in_16_63);	# preload T
-+	&add	($K256,4);
-+	 &add	($A,$T);		# h += T
-+}
-+
-+&external_label("OPENSSL_ia32cap_P")		if (!$i386);
-+
-+&function_begin("sha256_block_data_order");
-+	&mov	("esi",wparam(0));	# ctx
-+	&mov	("edi",wparam(1));	# inp
-+	&mov	("eax",wparam(2));	# num
-+	&mov	("ebx","esp");		# saved sp
-+
-+	&call	(&label("pic_point"));	# make it PIC!
-+&set_label("pic_point");
-+	&blindpop($K256);
-+	&lea	($K256,&DWP(&label("K256")."-".&label("pic_point"),$K256));
-+
-+	&sub	("esp",16);
-+	&and	("esp",-64);
-+
-+	&shl	("eax",6);
-+	&add	("eax","edi");
-+	&mov	(&DWP(0,"esp"),"esi");	# ctx
-+	&mov	(&DWP(4,"esp"),"edi");	# inp
-+	&mov	(&DWP(8,"esp"),"eax");	# inp+num*128
-+	&mov	(&DWP(12,"esp"),"ebx");	# saved sp
-+						if (!$i386 && $xmm) {
-+	&picmeup("edx","OPENSSL_ia32cap_P",$K256,&label("K256"));
-+	&mov	("ecx",&DWP(0,"edx"));
-+	&mov	("ebx",&DWP(4,"edx"));
-+	&test	("ecx",1<<20);		# check for P4
-+	&jnz	(&label("loop"));
-+	&mov	("edx",&DWP(8,"edx"))	if ($xmm);
-+	&test	("ecx",1<<24);		# check for FXSR
-+	&jz	($unroll_after?&label("no_xmm"):&label("loop"));
-+	&and	("ecx",1<<30);		# mask "Intel CPU" bit
-+	&and	("ebx",1<<28|1<<9);	# mask AVX and SSSE3 bits
-+	&test	("edx",1<<29)		if ($shaext);	# check for SHA
-+	&jnz	(&label("shaext"))	if ($shaext);
-+	&or	("ecx","ebx");
-+	&and	("ecx",1<<28|1<<30);
-+	&cmp	("ecx",1<<28|1<<30);
-+					if ($xmm) {
-+	&je	(&label("AVX"))		if ($avx);
-+	&test	("ebx",1<<9);		# check for SSSE3
-+	&jnz	(&label("SSSE3"));
-+					} else {
-+	&je	(&label("loop_shrd"));
-+					}
-+						if ($unroll_after) {
-+&set_label("no_xmm");
-+	&sub	("eax","edi");
-+	&cmp	("eax",$unroll_after);
-+	&jae	(&label("unrolled"));
-+						} }
-+	&jmp	(&label("loop"));
-+
-+sub COMPACT_LOOP() {
-+my $suffix=shift;
-+
-+&set_label("loop$suffix",$suffix?32:16);
-+    # copy input block to stack reversing byte and dword order
-+    for($i=0;$i<4;$i++) {
-+	&mov	("eax",&DWP($i*16+0,"edi"));
-+	&mov	("ebx",&DWP($i*16+4,"edi"));
-+	&mov	("ecx",&DWP($i*16+8,"edi"));
-+	&bswap	("eax");
-+	&mov	("edx",&DWP($i*16+12,"edi"));
-+	&bswap	("ebx");
-+	&push	("eax");
-+	&bswap	("ecx");
-+	&push	("ebx");
-+	&bswap	("edx");
-+	&push	("ecx");
-+	&push	("edx");
-+    }
-+	&add	("edi",64);
-+	&lea	("esp",&DWP(-4*9,"esp"));# place for A,B,C,D,E,F,G,H
-+	&mov	(&DWP(4*(9+16)+4,"esp"),"edi");
-+
-+	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
-+	&mov	($A,&DWP(0,"esi"));
-+	&mov	("ebx",&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&mov	("edi",&DWP(12,"esi"));
-+	# &mov	($Aoff,$A);
-+	&mov	($Boff,"ebx");
-+	&xor	("ebx","ecx");
-+	&mov	($Coff,"ecx");
-+	&mov	($Doff,"edi");
-+	&mov	(&DWP(0,"esp"),"ebx");	# magic
-+	&mov	($E,&DWP(16,"esi"));	
-+	&mov	("ebx",&DWP(20,"esi"));
-+	&mov	("ecx",&DWP(24,"esi"));
-+	&mov	("edi",&DWP(28,"esi"));
-+	# &mov	($Eoff,$E);
-+	&mov	($Foff,"ebx");
-+	&mov	($Goff,"ecx");
-+	&mov	($Hoff,"edi");
-+
-+&set_label("00_15$suffix",16);
-+
-+	&BODY_00_15();
-+
-+	&cmp	("esi",0xc19bf174);
-+	&jne	(&label("00_15$suffix"));
-+
-+	&mov	("ecx",&DWP(4*(9+15+16-1),"esp"));	# preloaded in BODY_00_15(1)
-+	&jmp	(&label("16_63$suffix"));
-+
-+&set_label("16_63$suffix",16);
-+
-+	&BODY_16_63();
-+
-+	&cmp	("esi",0xc67178f2);
-+	&jne	(&label("16_63$suffix"));
-+
-+	&mov	("esi",&DWP(4*(9+16+64)+0,"esp"));#ctx
-+	# &mov	($A,$Aoff);
-+	&mov	("ebx",$Boff);
-+	# &mov	("edi",$Coff);
-+	&mov	("ecx",$Doff);
-+	&add	($A,&DWP(0,"esi"));
-+	&add	("ebx",&DWP(4,"esi"));
-+	&add	("edi",&DWP(8,"esi"));
-+	&add	("ecx",&DWP(12,"esi"));
-+	&mov	(&DWP(0,"esi"),$A);
-+	&mov	(&DWP(4,"esi"),"ebx");
-+	&mov	(&DWP(8,"esi"),"edi");
-+	&mov	(&DWP(12,"esi"),"ecx");
-+	# &mov	($E,$Eoff);
-+	&mov	("eax",$Foff);
-+	&mov	("ebx",$Goff);
-+	&mov	("ecx",$Hoff);
-+	&mov	("edi",&DWP(4*(9+16+64)+4,"esp"));#inp
-+	&add	($E,&DWP(16,"esi"));
-+	&add	("eax",&DWP(20,"esi"));
-+	&add	("ebx",&DWP(24,"esi"));
-+	&add	("ecx",&DWP(28,"esi"));
-+	&mov	(&DWP(16,"esi"),$E);
-+	&mov	(&DWP(20,"esi"),"eax");
-+	&mov	(&DWP(24,"esi"),"ebx");
-+	&mov	(&DWP(28,"esi"),"ecx");
-+
-+	&lea	("esp",&DWP(4*(9+16+64),"esp"));# destroy frame
-+	&sub	($K256,4*64);			# rewind K
-+
-+	&cmp	("edi",&DWP(8,"esp"));		# are we done yet?
-+	&jb	(&label("loop$suffix"));
-+}
-+	&COMPACT_LOOP();
-+	&mov	("esp",&DWP(12,"esp"));		# restore sp
-+&function_end_A();
-+						if (!$i386 && !$xmm) {
-+	# ~20% improvement on Sandy Bridge
-+	local *ror = sub { &shrd(@_[0],@_) };
-+	&COMPACT_LOOP("_shrd");
-+	&mov	("esp",&DWP(12,"esp"));		# restore sp
-+&function_end_A();
-+						}
-+
-+&set_label("K256",64);	# Yes! I keep it in the code segment!
-+@K256=(	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,
-+	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
-+	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,
-+	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
-+	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,
-+	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
-+	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,
-+	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
-+	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,
-+	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
-+	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,
-+	0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
-+	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,
-+	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
-+	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,
-+	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2	);
-+&data_word(@K256);
-+&data_word(0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f);	# byte swap mask
-+&asciz("SHA256 block transform for x86, CRYPTOGAMS by ");
-+
-+($a,$b,$c,$d,$e,$f,$g,$h)=(0..7);	# offsets
-+sub off { &DWP(4*(((shift)-$i)&7),"esp"); }
-+
-+if (!$i386 && $unroll_after) {
-+my @AH=($A,$K256);
-+
-+&set_label("unrolled",16);
-+	&lea	("esp",&DWP(-96,"esp"));
-+	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
-+	&mov	($AH[0],&DWP(0,"esi"));
-+	&mov	($AH[1],&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&mov	("ebx",&DWP(12,"esi"));
-+	#&mov	(&DWP(0,"esp"),$AH[0]);
-+	&mov	(&DWP(4,"esp"),$AH[1]);
-+	&xor	($AH[1],"ecx");		# magic
-+	&mov	(&DWP(8,"esp"),"ecx");
-+	&mov	(&DWP(12,"esp"),"ebx");
-+	&mov	($E,&DWP(16,"esi"));	
-+	&mov	("ebx",&DWP(20,"esi"));
-+	&mov	("ecx",&DWP(24,"esi"));
-+	&mov	("esi",&DWP(28,"esi"));
-+	#&mov	(&DWP(16,"esp"),$E);
-+	&mov	(&DWP(20,"esp"),"ebx");
-+	&mov	(&DWP(24,"esp"),"ecx");
-+	&mov	(&DWP(28,"esp"),"esi");
-+	&jmp	(&label("grand_loop"));
-+
-+&set_label("grand_loop",16);
-+    # copy input block to stack reversing byte order
-+    for($i=0;$i<5;$i++) {
-+	&mov	("ebx",&DWP(12*$i+0,"edi"));
-+	&mov	("ecx",&DWP(12*$i+4,"edi"));
-+	&bswap	("ebx");
-+	&mov	("esi",&DWP(12*$i+8,"edi"));
-+	&bswap	("ecx");
-+	&mov	(&DWP(32+12*$i+0,"esp"),"ebx");
-+	&bswap	("esi");
-+	&mov	(&DWP(32+12*$i+4,"esp"),"ecx");
-+	&mov	(&DWP(32+12*$i+8,"esp"),"esi");
-+    }
-+	&mov	("ebx",&DWP($i*12,"edi"));
-+	&add	("edi",64);
-+	&bswap	("ebx");
-+	&mov	(&DWP(96+4,"esp"),"edi");
-+	&mov	(&DWP(32+12*$i,"esp"),"ebx");
-+
-+    my ($t1,$t2) = ("ecx","esi");
-+
-+    for ($i=0;$i<64;$i++) {
-+
-+      if ($i>=16) {
-+	&mov	($T,$t1);			# $t1 is preloaded
-+	# &mov	($t2,&DWP(32+4*(($i+14)&15),"esp"));
-+	&ror	($t1,18-7);
-+	 &mov	("edi",$t2);
-+	&ror	($t2,19-17);
-+	 &xor	($t1,$T);
-+	 &shr	($T,3);
-+	&ror	($t1,7);
-+	 &xor	($t2,"edi");
-+	 &xor	($T,$t1);			# T = sigma0(X[-15])
-+	&ror	($t2,17);
-+	 &add	($T,&DWP(32+4*($i&15),"esp"));	# T += X[-16]
-+	&shr	("edi",10);
-+	 &add	($T,&DWP(32+4*(($i+9)&15),"esp"));	# T += X[-7]
-+	#&xor	("edi",$t2)			# sigma1(X[-2])
-+	# &add	($T,"edi");			# T += sigma1(X[-2])
-+	# &mov	(&DWP(4*(9+15),"esp"),$T);	# save X[0]
-+      }
-+	&mov	($t1,$E);
-+	 &xor	("edi",$t2)			if ($i>=16);	# sigma1(X[-2])
-+	 &mov	($t2,&off($f));
-+	&ror	($E,25-11);
-+	 &add	($T,"edi")			if ($i>=16);	# T += sigma1(X[-2])
-+	 &mov	("edi",&off($g));
-+	&xor	($E,$t1);
-+	 &mov	($T,&DWP(32+4*($i&15),"esp"))	if ($i<16);	# X[i]
-+	 &mov	(&DWP(32+4*($i&15),"esp"),$T)	if ($i>=16 && $i<62);	# save X[0]
-+	 &xor	($t2,"edi");
-+	&ror	($E,11-6);
-+	 &and	($t2,$t1);
-+	 &mov	(&off($e),$t1);		# save $E, modulo-scheduled
-+	&xor	($E,$t1);
-+	 &add	($T,&off($h));		# T += h
-+	 &xor	("edi",$t2);		# Ch(e,f,g)
-+	&ror	($E,6);			# Sigma1(e)
-+	 &mov	($t1,$AH[0]);
-+	 &add	($T,"edi");		# T += Ch(e,f,g)
-+
-+	&ror	($t1,22-13);
-+	 &mov	($t2,$AH[0]);
-+	 &mov	("edi",&off($b));
-+	&xor	($t1,$AH[0]);
-+	 &mov	(&off($a),$AH[0]);	# save $A, modulo-scheduled
-+	 &xor	($AH[0],"edi");		# a ^= b, (b^c) in next round
-+	&ror	($t1,13-2);
-+	 &and	($AH[1],$AH[0]);	# (b^c) &= (a^b)
-+	 &lea	($E,&DWP(@K256[$i],$T,$E));	# T += Sigma1(1)+K[i]
-+	&xor	($t1,$t2);
-+	 &xor	($AH[1],"edi");		# h = Maj(a,b,c) = Ch(a^b,c,b)
-+	 &mov	($t2,&DWP(32+4*(($i+2)&15),"esp"))	if ($i>=15 && $i<63);
-+	&ror	($t1,2);		# Sigma0(a)
-+
-+	 &add	($AH[1],$E);		# h += T
-+	 &add	($E,&off($d));		# d += T
-+	&add	($AH[1],$t1);		# h += Sigma0(a)
-+	 &mov	($t1,&DWP(32+4*(($i+15)&15),"esp"))	if ($i>=15 && $i<63);
-+
-+	@AH = reverse(@AH);		# rotate(a,h)
-+	($t1,$t2) = ($t2,$t1);		# rotate(t1,t2)
-+    }
-+	&mov	("esi",&DWP(96,"esp"));	#ctx
-+					#&mov	($AH[0],&DWP(0,"esp"));
-+	&xor	($AH[1],"edi");		#&mov	($AH[1],&DWP(4,"esp"));
-+					#&mov	("edi", &DWP(8,"esp"));
-+	&mov	("ecx",&DWP(12,"esp"));
-+	&add	($AH[0],&DWP(0,"esi"));
-+	&add	($AH[1],&DWP(4,"esi"));
-+	&add	("edi",&DWP(8,"esi"));
-+	&add	("ecx",&DWP(12,"esi"));
-+	&mov	(&DWP(0,"esi"),$AH[0]);
-+	&mov	(&DWP(4,"esi"),$AH[1]);
-+	&mov	(&DWP(8,"esi"),"edi");
-+	&mov	(&DWP(12,"esi"),"ecx");
-+	 #&mov	(&DWP(0,"esp"),$AH[0]);
-+	 &mov	(&DWP(4,"esp"),$AH[1]);
-+	 &xor	($AH[1],"edi");		# magic
-+	 &mov	(&DWP(8,"esp"),"edi");
-+	 &mov	(&DWP(12,"esp"),"ecx");
-+	#&mov	($E,&DWP(16,"esp"));
-+	&mov	("edi",&DWP(20,"esp"));
-+	&mov	("ebx",&DWP(24,"esp"));
-+	&mov	("ecx",&DWP(28,"esp"));
-+	&add	($E,&DWP(16,"esi"));
-+	&add	("edi",&DWP(20,"esi"));
-+	&add	("ebx",&DWP(24,"esi"));
-+	&add	("ecx",&DWP(28,"esi"));
-+	&mov	(&DWP(16,"esi"),$E);
-+	&mov	(&DWP(20,"esi"),"edi");
-+	&mov	(&DWP(24,"esi"),"ebx");
-+	&mov	(&DWP(28,"esi"),"ecx");
-+	 #&mov	(&DWP(16,"esp"),$E);
-+	 &mov	(&DWP(20,"esp"),"edi");
-+	&mov	("edi",&DWP(96+4,"esp"));	# inp
-+	 &mov	(&DWP(24,"esp"),"ebx");
-+	 &mov	(&DWP(28,"esp"),"ecx");
-+
-+	&cmp	("edi",&DWP(96+8,"esp"));	# are we done yet?
-+	&jb	(&label("grand_loop"));
-+
-+	&mov	("esp",&DWP(96+12,"esp"));	# restore sp
-+&function_end_A();
-+}
-+						if (!$i386 && $xmm) {{{
-+if ($shaext) {
-+######################################################################
-+# Intel SHA Extensions implementation of SHA256 update function.
-+#
-+my ($ctx,$inp,$end)=("esi","edi","eax");
-+my ($Wi,$ABEF,$CDGH,$TMP)=map("xmm$_",(0..2,7));
-+my @MSG=map("xmm$_",(3..6));
-+
-+sub sha256op38 {
-+ my ($opcodelet,$dst,$src)=@_;
-+    if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
-+    {	&data_byte(0x0f,0x38,$opcodelet,0xc0|($1<<3)|$2);	}
-+}
-+sub sha256rnds2	{ sha256op38(0xcb,@_); }
-+sub sha256msg1	{ sha256op38(0xcc,@_); }
-+sub sha256msg2	{ sha256op38(0xcd,@_); }
-+
-+&set_label("shaext",32);
-+	&sub		("esp",32);
-+
-+	&movdqu		($ABEF,&QWP(0,$ctx));		# DCBA
-+	&lea		($K256,&DWP(0x80,$K256));
-+	&movdqu		($CDGH,&QWP(16,$ctx));		# HGFE
-+	&movdqa		($TMP,&QWP(0x100-0x80,$K256));	# byte swap mask
-+
-+	&pshufd		($Wi,$ABEF,0x1b);		# ABCD
-+	&pshufd		($ABEF,$ABEF,0xb1);		# CDAB
-+	&pshufd		($CDGH,$CDGH,0x1b);		# EFGH
-+	&palignr	($ABEF,$CDGH,8);		# ABEF
-+	&punpcklqdq	($CDGH,$Wi);			# CDGH
-+	&jmp		(&label("loop_shaext"));
-+
-+&set_label("loop_shaext",16);
-+	&movdqu		(@MSG[0],&QWP(0,$inp));
-+	&movdqu		(@MSG[1],&QWP(0x10,$inp));
-+	&movdqu		(@MSG[2],&QWP(0x20,$inp));
-+	&pshufb		(@MSG[0],$TMP);
-+	&movdqu		(@MSG[3],&QWP(0x30,$inp));
-+	&movdqa		(&QWP(16,"esp"),$CDGH);		# offload
-+
-+	&movdqa		($Wi,&QWP(0*16-0x80,$K256));
-+	&paddd		($Wi,@MSG[0]);
-+	&pshufb		(@MSG[1],$TMP);
-+	&sha256rnds2	($CDGH,$ABEF);			# 0-3
-+	&pshufd		($Wi,$Wi,0x0e);
-+	&nop		();
-+	&movdqa		(&QWP(0,"esp"),$ABEF);		# offload
-+	&sha256rnds2	($ABEF,$CDGH);
-+
-+	&movdqa		($Wi,&QWP(1*16-0x80,$K256));
-+	&paddd		($Wi,@MSG[1]);
-+	&pshufb		(@MSG[2],$TMP);
-+	&sha256rnds2	($CDGH,$ABEF);			# 4-7
-+	&pshufd		($Wi,$Wi,0x0e);
-+	&lea		($inp,&DWP(0x40,$inp));
-+	&sha256msg1	(@MSG[0],@MSG[1]);
-+	&sha256rnds2	($ABEF,$CDGH);
-+
-+	&movdqa		($Wi,&QWP(2*16-0x80,$K256));
-+	&paddd		($Wi,@MSG[2]);
-+	&pshufb		(@MSG[3],$TMP);
-+	&sha256rnds2	($CDGH,$ABEF);			# 8-11
-+	&pshufd		($Wi,$Wi,0x0e);
-+	&movdqa		($TMP,@MSG[3]);
-+	&palignr	($TMP,@MSG[2],4);
-+	&nop		();
-+	&paddd		(@MSG[0],$TMP);
-+	&sha256msg1	(@MSG[1],@MSG[2]);
-+	&sha256rnds2	($ABEF,$CDGH);
-+
-+	&movdqa		($Wi,&QWP(3*16-0x80,$K256));
-+	&paddd		($Wi,@MSG[3]);
-+	&sha256msg2	(@MSG[0],@MSG[3]);
-+	&sha256rnds2	($CDGH,$ABEF);			# 12-15
-+	&pshufd		($Wi,$Wi,0x0e);
-+	&movdqa		($TMP,@MSG[0]);
-+	&palignr	($TMP,@MSG[3],4);
-+	&nop		();
-+	&paddd		(@MSG[1],$TMP);
-+	&sha256msg1	(@MSG[2],@MSG[3]);
-+	&sha256rnds2	($ABEF,$CDGH);
-+
-+for($i=4;$i<16-3;$i++) {
-+	&movdqa		($Wi,&QWP($i*16-0x80,$K256));
-+	&paddd		($Wi,@MSG[0]);
-+	&sha256msg2	(@MSG[1],@MSG[0]);
-+	&sha256rnds2	($CDGH,$ABEF);			# 16-19...
-+	&pshufd		($Wi,$Wi,0x0e);
-+	&movdqa		($TMP,@MSG[1]);
-+	&palignr	($TMP,@MSG[0],4);
-+	&nop		();
-+	&paddd		(@MSG[2],$TMP);
-+	&sha256msg1	(@MSG[3],@MSG[0]);
-+	&sha256rnds2	($ABEF,$CDGH);
-+
-+	push(@MSG,shift(@MSG));
-+}
-+	&movdqa		($Wi,&QWP(13*16-0x80,$K256));
-+	&paddd		($Wi,@MSG[0]);
-+	&sha256msg2	(@MSG[1],@MSG[0]);
-+	&sha256rnds2	($CDGH,$ABEF);			# 52-55
-+	&pshufd		($Wi,$Wi,0x0e);
-+	&movdqa		($TMP,@MSG[1])
-+	&palignr	($TMP,@MSG[0],4);
-+	&sha256rnds2	($ABEF,$CDGH);
-+	&paddd		(@MSG[2],$TMP);
-+
-+	&movdqa		($Wi,&QWP(14*16-0x80,$K256));
-+	&paddd		($Wi,@MSG[1]);
-+	&sha256rnds2	($CDGH,$ABEF);			# 56-59
-+	&pshufd		($Wi,$Wi,0x0e);
-+	&sha256msg2	(@MSG[2],@MSG[1]);
-+	&movdqa		($TMP,&QWP(0x100-0x80,$K256));	# byte swap mask
-+	&sha256rnds2	($ABEF,$CDGH);
-+
-+	&movdqa		($Wi,&QWP(15*16-0x80,$K256));
-+	&paddd		($Wi,@MSG[2]);
-+	&nop		();
-+	&sha256rnds2	($CDGH,$ABEF);			# 60-63
-+	&pshufd		($Wi,$Wi,0x0e);
-+	&cmp		($end,$inp);
-+	&nop		();
-+	&sha256rnds2	($ABEF,$CDGH);
-+
-+	&paddd		($CDGH,&QWP(16,"esp"));
-+	&paddd		($ABEF,&QWP(0,"esp"));
-+	&jnz		(&label("loop_shaext"));
-+
-+	&pshufd		($CDGH,$CDGH,0xb1);		# DCHG
-+	&pshufd		($TMP,$ABEF,0x1b);		# FEBA
-+	&pshufd		($ABEF,$ABEF,0xb1);		# BAFE
-+	&punpckhqdq	($ABEF,$CDGH);			# DCBA
-+	&palignr	($CDGH,$TMP,8);			# HGFE
-+
-+	&mov		("esp",&DWP(32+12,"esp"));
-+	&movdqu		(&QWP(0,$ctx),$ABEF);
-+	&movdqu		(&QWP(16,$ctx),$CDGH);
-+&function_end_A();
-+}
-+
-+my @X = map("xmm$_",(0..3));
-+my ($t0,$t1,$t2,$t3) = map("xmm$_",(4..7));
-+my @AH = ($A,$T);
-+
-+&set_label("SSSE3",32);
-+	&lea	("esp",&DWP(-96,"esp"));
-+	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
-+	&mov	($AH[0],&DWP(0,"esi"));
-+	&mov	($AH[1],&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&mov	("edi",&DWP(12,"esi"));
-+	#&mov	(&DWP(0,"esp"),$AH[0]);
-+	&mov	(&DWP(4,"esp"),$AH[1]);
-+	&xor	($AH[1],"ecx");			# magic
-+	&mov	(&DWP(8,"esp"),"ecx");
-+	&mov	(&DWP(12,"esp"),"edi");
-+	&mov	($E,&DWP(16,"esi"));
-+	&mov	("edi",&DWP(20,"esi"));
-+	&mov	("ecx",&DWP(24,"esi"));
-+	&mov	("esi",&DWP(28,"esi"));
-+	#&mov	(&DWP(16,"esp"),$E);
-+	&mov	(&DWP(20,"esp"),"edi");
-+	&mov	("edi",&DWP(96+4,"esp"));	# inp
-+	&mov	(&DWP(24,"esp"),"ecx");
-+	&mov	(&DWP(28,"esp"),"esi");
-+	&movdqa	($t3,&QWP(256,$K256));
-+	&jmp	(&label("grand_ssse3"));
-+
-+&set_label("grand_ssse3",16);
-+	# load input, reverse byte order, add K256[0..15], save to stack
-+	&movdqu	(@X[0],&QWP(0,"edi"));
-+	&movdqu	(@X[1],&QWP(16,"edi"));
-+	&movdqu	(@X[2],&QWP(32,"edi"));
-+	&movdqu	(@X[3],&QWP(48,"edi"));
-+	&add	("edi",64);
-+	&pshufb	(@X[0],$t3);
-+	&mov	(&DWP(96+4,"esp"),"edi");
-+	&pshufb	(@X[1],$t3);
-+	&movdqa	($t0,&QWP(0,$K256));
-+	&pshufb	(@X[2],$t3);
-+	&movdqa	($t1,&QWP(16,$K256));
-+	&paddd	($t0,@X[0]);
-+	&pshufb	(@X[3],$t3);
-+	&movdqa	($t2,&QWP(32,$K256));
-+	&paddd	($t1,@X[1]);
-+	&movdqa	($t3,&QWP(48,$K256));
-+	&movdqa	(&QWP(32+0,"esp"),$t0);
-+	&paddd	($t2,@X[2]);
-+	&movdqa	(&QWP(32+16,"esp"),$t1);
-+	&paddd	($t3,@X[3]);
-+	&movdqa	(&QWP(32+32,"esp"),$t2);
-+	&movdqa	(&QWP(32+48,"esp"),$t3);
-+	&jmp	(&label("ssse3_00_47"));
-+
-+&set_label("ssse3_00_47",16);
-+	&add		($K256,64);
-+
-+sub SSSE3_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body,&$body,&$body);	# 120 instructions
-+
-+	  eval(shift(@insns));
-+	&movdqa		($t0,@X[1]);
-+	  eval(shift(@insns));			# @
-+	  eval(shift(@insns));
-+	&movdqa		($t3,@X[3]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&palignr	($t0,@X[0],4);		# X[1..4]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	  eval(shift(@insns));
-+	 &palignr	($t3,@X[2],4);		# X[9..12]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&movdqa		($t1,$t0);
-+	  eval(shift(@insns));			# @
-+	  eval(shift(@insns));
-+	&movdqa		($t2,$t0);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&psrld		($t0,3);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	 &paddd		(@X[0],$t3);		# X[0..3] += X[9..12]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&psrld		($t2,7);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	  eval(shift(@insns));
-+	 &pshufd	($t3,@X[3],0b11111010);	# X[14..15]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&pslld		($t1,32-18);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	&pxor		($t0,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&psrld		($t2,18-7);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	&pxor		($t0,$t1);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&pslld		($t1,18-7);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	&pxor		($t0,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &movdqa	($t2,$t3);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	&pxor		($t0,$t1);		# sigma0(X[1..4])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &psrld		($t3,10);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	&paddd		(@X[0],$t0);		# X[0..3] += sigma0(X[1..4])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &psrlq		($t2,17);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	 &pxor		($t3,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &psrlq		($t2,19-17);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	 &pxor		($t3,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &pshufd	($t3,$t3,0b10000000);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	  eval(shift(@insns));
-+	 &psrldq	($t3,8);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&paddd		(@X[0],$t3);		# X[0..1] += sigma1(X[14..15])
-+	  eval(shift(@insns));			# @
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	  eval(shift(@insns));
-+	 &pshufd	($t3,@X[0],0b01010000);	# X[16..17]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &movdqa	($t2,$t3);
-+	  eval(shift(@insns));			# @
-+	 &psrld		($t3,10);
-+	  eval(shift(@insns));
-+	 &psrlq		($t2,17);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	 &pxor		($t3,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &psrlq		($t2,19-17);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	 &pxor		($t3,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &pshufd	($t3,$t3,0b00001000);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	&movdqa		($t2,&QWP(16*$j,$K256));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &pslldq	($t3,8);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));			# @
-+	&paddd		(@X[0],$t3);		# X[2..3] += sigma1(X[16..17])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&paddd		($t2,@X[0]);
-+	  eval(shift(@insns));			# @
-+
-+	foreach (@insns) { eval; }		# remaining instructions
-+
-+	&movdqa		(&QWP(32+16*$j,"esp"),$t2);
-+}
-+
-+sub body_00_15 () {
-+	(
-+	'&mov	("ecx",$E);',
-+	'&ror	($E,25-11);',
-+	 '&mov	("esi",&off($f));',
-+	'&xor	($E,"ecx");',
-+	 '&mov	("edi",&off($g));',
-+	 '&xor	("esi","edi");',
-+	'&ror	($E,11-6);',
-+	 '&and	("esi","ecx");',
-+	 '&mov	(&off($e),"ecx");',	# save $E, modulo-scheduled
-+	'&xor	($E,"ecx");',
-+	 '&xor	("edi","esi");',	# Ch(e,f,g)
-+	'&ror	($E,6);',		# T = Sigma1(e)
-+	 '&mov	("ecx",$AH[0]);',
-+	 '&add	($E,"edi");',		# T += Ch(e,f,g)
-+	 '&mov	("edi",&off($b));',
-+	'&mov	("esi",$AH[0]);',
-+
-+	'&ror	("ecx",22-13);',
-+	 '&mov	(&off($a),$AH[0]);',	# save $A, modulo-scheduled
-+	'&xor	("ecx",$AH[0]);',
-+	 '&xor	($AH[0],"edi");',	# a ^= b, (b^c) in next round
-+	 '&add	($E,&off($h));',	# T += h
-+	'&ror	("ecx",13-2);',
-+	 '&and	($AH[1],$AH[0]);',	# (b^c) &= (a^b)
-+	'&xor	("ecx","esi");',
-+	 '&add	($E,&DWP(32+4*($i&15),"esp"));',	# T += K[i]+X[i]
-+	 '&xor	($AH[1],"edi");',	# h = Maj(a,b,c) = Ch(a^b,c,b)
-+	'&ror	("ecx",2);',		# Sigma0(a)
-+
-+	 '&add	($AH[1],$E);',		# h += T
-+	 '&add	($E,&off($d));',	# d += T
-+	'&add	($AH[1],"ecx");'.	# h += Sigma0(a)
-+
-+	'@AH = reverse(@AH); $i++;'	# rotate(a,h)
-+	);
-+}
-+
-+    for ($i=0,$j=0; $j<4; $j++) {
-+	&SSSE3_00_47($j,\&body_00_15,@X);
-+	push(@X,shift(@X));		# rotate(@X)
-+    }
-+	&cmp	(&DWP(16*$j,$K256),0x00010203);
-+	&jne	(&label("ssse3_00_47"));
-+
-+    for ($i=0; $i<16; ) {
-+	foreach(body_00_15()) { eval; }
-+    }
-+
-+	&mov	("esi",&DWP(96,"esp"));	#ctx
-+					#&mov	($AH[0],&DWP(0,"esp"));
-+	&xor	($AH[1],"edi");		#&mov	($AH[1],&DWP(4,"esp"));
-+					#&mov	("edi", &DWP(8,"esp"));
-+	&mov	("ecx",&DWP(12,"esp"));
-+	&add	($AH[0],&DWP(0,"esi"));
-+	&add	($AH[1],&DWP(4,"esi"));
-+	&add	("edi",&DWP(8,"esi"));
-+	&add	("ecx",&DWP(12,"esi"));
-+	&mov	(&DWP(0,"esi"),$AH[0]);
-+	&mov	(&DWP(4,"esi"),$AH[1]);
-+	&mov	(&DWP(8,"esi"),"edi");
-+	&mov	(&DWP(12,"esi"),"ecx");
-+	 #&mov	(&DWP(0,"esp"),$AH[0]);
-+	 &mov	(&DWP(4,"esp"),$AH[1]);
-+	 &xor	($AH[1],"edi");			# magic
-+	 &mov	(&DWP(8,"esp"),"edi");
-+	 &mov	(&DWP(12,"esp"),"ecx");
-+	#&mov	($E,&DWP(16,"esp"));
-+	&mov	("edi",&DWP(20,"esp"));
-+	&mov	("ecx",&DWP(24,"esp"));
-+	&add	($E,&DWP(16,"esi"));
-+	&add	("edi",&DWP(20,"esi"));
-+	&add	("ecx",&DWP(24,"esi"));
-+	&mov	(&DWP(16,"esi"),$E);
-+	&mov	(&DWP(20,"esi"),"edi");
-+	 &mov	(&DWP(20,"esp"),"edi");
-+	&mov	("edi",&DWP(28,"esp"));
-+	&mov	(&DWP(24,"esi"),"ecx");
-+	 #&mov	(&DWP(16,"esp"),$E);
-+	&add	("edi",&DWP(28,"esi"));
-+	 &mov	(&DWP(24,"esp"),"ecx");
-+	&mov	(&DWP(28,"esi"),"edi");
-+	 &mov	(&DWP(28,"esp"),"edi");
-+	&mov	("edi",&DWP(96+4,"esp"));	# inp
-+
-+	&movdqa	($t3,&QWP(64,$K256));
-+	&sub	($K256,3*64);			# rewind K
-+	&cmp	("edi",&DWP(96+8,"esp"));	# are we done yet?
-+	&jb	(&label("grand_ssse3"));
-+
-+	&mov	("esp",&DWP(96+12,"esp"));	# restore sp
-+&function_end_A();
-+						if ($avx) {
-+&set_label("AVX",32);
-+						if ($avx>1) {
-+	&and	("edx",1<<8|1<<3);		# check for BMI2+BMI1
-+	&cmp	("edx",1<<8|1<<3);
-+	&je	(&label("AVX_BMI"));
-+						}
-+	&lea	("esp",&DWP(-96,"esp"));
-+	&vzeroall	();
-+	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
-+	&mov	($AH[0],&DWP(0,"esi"));
-+	&mov	($AH[1],&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&mov	("edi",&DWP(12,"esi"));
-+	#&mov	(&DWP(0,"esp"),$AH[0]);
-+	&mov	(&DWP(4,"esp"),$AH[1]);
-+	&xor	($AH[1],"ecx");			# magic
-+	&mov	(&DWP(8,"esp"),"ecx");
-+	&mov	(&DWP(12,"esp"),"edi");
-+	&mov	($E,&DWP(16,"esi"));
-+	&mov	("edi",&DWP(20,"esi"));
-+	&mov	("ecx",&DWP(24,"esi"));
-+	&mov	("esi",&DWP(28,"esi"));
-+	#&mov	(&DWP(16,"esp"),$E);
-+	&mov	(&DWP(20,"esp"),"edi");
-+	&mov	("edi",&DWP(96+4,"esp"));	# inp
-+	&mov	(&DWP(24,"esp"),"ecx");
-+	&mov	(&DWP(28,"esp"),"esi");
-+	&vmovdqa	($t3,&QWP(256,$K256));
-+	&jmp	(&label("grand_avx"));
-+
-+&set_label("grand_avx",32);
-+	# load input, reverse byte order, add K256[0..15], save to stack
-+	&vmovdqu	(@X[0],&QWP(0,"edi"));
-+	&vmovdqu	(@X[1],&QWP(16,"edi"));
-+	&vmovdqu	(@X[2],&QWP(32,"edi"));
-+	&vmovdqu	(@X[3],&QWP(48,"edi"));
-+	&add		("edi",64);
-+	&vpshufb	(@X[0],@X[0],$t3);
-+	&mov		(&DWP(96+4,"esp"),"edi");
-+	&vpshufb	(@X[1],@X[1],$t3);
-+	&vpshufb	(@X[2],@X[2],$t3);
-+	&vpaddd		($t0,@X[0],&QWP(0,$K256));
-+	&vpshufb	(@X[3],@X[3],$t3);
-+	&vpaddd		($t1,@X[1],&QWP(16,$K256));
-+	&vpaddd		($t2,@X[2],&QWP(32,$K256));
-+	&vpaddd		($t3,@X[3],&QWP(48,$K256));
-+	&vmovdqa	(&QWP(32+0,"esp"),$t0);
-+	&vmovdqa	(&QWP(32+16,"esp"),$t1);
-+	&vmovdqa	(&QWP(32+32,"esp"),$t2);
-+	&vmovdqa	(&QWP(32+48,"esp"),$t3);
-+	&jmp		(&label("avx_00_47"));
-+
-+&set_label("avx_00_47",16);
-+	&add		($K256,64);
-+
-+sub Xupdate_AVX () {
-+	(
-+	'&vpalignr	($t0,@X[1],@X[0],4);',	# X[1..4]
-+	 '&vpalignr	($t3,@X[3],@X[2],4);',	# X[9..12]
-+	'&vpsrld	($t2,$t0,7);',
-+	 '&vpaddd	(@X[0],@X[0],$t3);',	# X[0..3] += X[9..16]
-+	'&vpsrld	($t3,$t0,3);',
-+	'&vpslld	($t1,$t0,14);',
-+	'&vpxor		($t0,$t3,$t2);',
-+	 '&vpshufd	($t3,@X[3],0b11111010)',# X[14..15]
-+	'&vpsrld	($t2,$t2,18-7);',
-+	'&vpxor		($t0,$t0,$t1);',
-+	'&vpslld	($t1,$t1,25-14);',
-+	'&vpxor		($t0,$t0,$t2);',
-+	 '&vpsrld	($t2,$t3,10);',
-+	'&vpxor		($t0,$t0,$t1);',	# sigma0(X[1..4])
-+	 '&vpsrlq	($t1,$t3,17);',
-+	'&vpaddd	(@X[0],@X[0],$t0);',	# X[0..3] += sigma0(X[1..4])
-+	 '&vpxor	($t2,$t2,$t1);',
-+	 '&vpsrlq	($t3,$t3,19);',
-+	 '&vpxor	($t2,$t2,$t3);',	# sigma1(X[14..15]
-+	 '&vpshufd	($t3,$t2,0b10000100);',
-+	'&vpsrldq	($t3,$t3,8);',
-+	'&vpaddd	(@X[0],@X[0],$t3);',	# X[0..1] += sigma1(X[14..15])
-+	 '&vpshufd	($t3,@X[0],0b01010000)',# X[16..17]
-+	 '&vpsrld	($t2,$t3,10);',
-+	 '&vpsrlq	($t1,$t3,17);',
-+	 '&vpxor	($t2,$t2,$t1);',
-+	 '&vpsrlq	($t3,$t3,19);',
-+	 '&vpxor	($t2,$t2,$t3);',	# sigma1(X[16..17]
-+	 '&vpshufd	($t3,$t2,0b11101000);',
-+	'&vpslldq	($t3,$t3,8);',
-+	'&vpaddd	(@X[0],@X[0],$t3);'	# X[2..3] += sigma1(X[16..17])
-+	);
-+}
-+
-+local *ror = sub { &shrd(@_[0],@_) };
-+sub AVX_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body,&$body,&$body);	# 120 instructions
-+my $insn;
-+
-+	foreach (Xupdate_AVX()) {		# 31 instructions
-+	    eval;
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	    eval($insn = shift(@insns));
-+	    eval(shift(@insns)) if ($insn =~ /rorx/ && @insns[0] =~ /rorx/);
-+	}
-+	&vpaddd		($t2,@X[0],&QWP(16*$j,$K256));
-+	foreach (@insns) { eval; }		# remaining instructions
-+	&vmovdqa	(&QWP(32+16*$j,"esp"),$t2);
-+}
-+
-+    for ($i=0,$j=0; $j<4; $j++) {
-+	&AVX_00_47($j,\&body_00_15,@X);
-+	push(@X,shift(@X));		# rotate(@X)
-+    }
-+	&cmp	(&DWP(16*$j,$K256),0x00010203);
-+	&jne	(&label("avx_00_47"));
-+
-+    for ($i=0; $i<16; ) {
-+	foreach(body_00_15()) { eval; }
-+    }
-+
-+	&mov	("esi",&DWP(96,"esp"));	#ctx
-+					#&mov	($AH[0],&DWP(0,"esp"));
-+	&xor	($AH[1],"edi");		#&mov	($AH[1],&DWP(4,"esp"));
-+					#&mov	("edi", &DWP(8,"esp"));
-+	&mov	("ecx",&DWP(12,"esp"));
-+	&add	($AH[0],&DWP(0,"esi"));
-+	&add	($AH[1],&DWP(4,"esi"));
-+	&add	("edi",&DWP(8,"esi"));
-+	&add	("ecx",&DWP(12,"esi"));
-+	&mov	(&DWP(0,"esi"),$AH[0]);
-+	&mov	(&DWP(4,"esi"),$AH[1]);
-+	&mov	(&DWP(8,"esi"),"edi");
-+	&mov	(&DWP(12,"esi"),"ecx");
-+	 #&mov	(&DWP(0,"esp"),$AH[0]);
-+	 &mov	(&DWP(4,"esp"),$AH[1]);
-+	 &xor	($AH[1],"edi");			# magic
-+	 &mov	(&DWP(8,"esp"),"edi");
-+	 &mov	(&DWP(12,"esp"),"ecx");
-+	#&mov	($E,&DWP(16,"esp"));
-+	&mov	("edi",&DWP(20,"esp"));
-+	&mov	("ecx",&DWP(24,"esp"));
-+	&add	($E,&DWP(16,"esi"));
-+	&add	("edi",&DWP(20,"esi"));
-+	&add	("ecx",&DWP(24,"esi"));
-+	&mov	(&DWP(16,"esi"),$E);
-+	&mov	(&DWP(20,"esi"),"edi");
-+	 &mov	(&DWP(20,"esp"),"edi");
-+	&mov	("edi",&DWP(28,"esp"));
-+	&mov	(&DWP(24,"esi"),"ecx");
-+	 #&mov	(&DWP(16,"esp"),$E);
-+	&add	("edi",&DWP(28,"esi"));
-+	 &mov	(&DWP(24,"esp"),"ecx");
-+	&mov	(&DWP(28,"esi"),"edi");
-+	 &mov	(&DWP(28,"esp"),"edi");
-+	&mov	("edi",&DWP(96+4,"esp"));	# inp
-+
-+	&vmovdqa	($t3,&QWP(64,$K256));
-+	&sub	($K256,3*64);			# rewind K
-+	&cmp	("edi",&DWP(96+8,"esp"));	# are we done yet?
-+	&jb	(&label("grand_avx"));
-+
-+	&mov	("esp",&DWP(96+12,"esp"));	# restore sp
-+	&vzeroall	();
-+&function_end_A();
-+						if ($avx>1) {
-+sub bodyx_00_15 () {			# +10%
-+	(
-+	'&rorx	("ecx",$E,6)',
-+	'&rorx	("esi",$E,11)',
-+	 '&mov	(&off($e),$E)',		# save $E, modulo-scheduled
-+	'&rorx	("edi",$E,25)',
-+	'&xor	("ecx","esi")',
-+	 '&andn	("esi",$E,&off($g))',
-+	'&xor	("ecx","edi")',		# Sigma1(e)
-+	 '&and	($E,&off($f))',
-+	 '&mov	(&off($a),$AH[0]);',	# save $A, modulo-scheduled
-+	 '&or	($E,"esi")',		# T = Ch(e,f,g)
-+
-+	'&rorx	("edi",$AH[0],2)',
-+	'&rorx	("esi",$AH[0],13)',
-+	 '&lea	($E,&DWP(0,$E,"ecx"))',	# T += Sigma1(e)
-+	'&rorx	("ecx",$AH[0],22)',
-+	'&xor	("esi","edi")',
-+	 '&mov	("edi",&off($b))',
-+	'&xor	("ecx","esi")',		# Sigma0(a)
-+
-+	 '&xor	($AH[0],"edi")',	# a ^= b, (b^c) in next round
-+	 '&add	($E,&off($h))',		# T += h
-+	 '&and	($AH[1],$AH[0])',	# (b^c) &= (a^b)
-+	 '&add	($E,&DWP(32+4*($i&15),"esp"))',	# T += K[i]+X[i]
-+	 '&xor	($AH[1],"edi")',	# h = Maj(a,b,c) = Ch(a^b,c,b)
-+
-+	 '&add	("ecx",$E)',		# h += T
-+	 '&add	($E,&off($d))',		# d += T
-+	'&lea	($AH[1],&DWP(0,$AH[1],"ecx"));'.	# h += Sigma0(a)
-+
-+	'@AH = reverse(@AH); $i++;'	# rotate(a,h)
-+	);
-+}
-+
-+&set_label("AVX_BMI",32);
-+	&lea	("esp",&DWP(-96,"esp"));
-+	&vzeroall	();
-+	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
-+	&mov	($AH[0],&DWP(0,"esi"));
-+	&mov	($AH[1],&DWP(4,"esi"));
-+	&mov	("ecx",&DWP(8,"esi"));
-+	&mov	("edi",&DWP(12,"esi"));
-+	#&mov	(&DWP(0,"esp"),$AH[0]);
-+	&mov	(&DWP(4,"esp"),$AH[1]);
-+	&xor	($AH[1],"ecx");			# magic
-+	&mov	(&DWP(8,"esp"),"ecx");
-+	&mov	(&DWP(12,"esp"),"edi");
-+	&mov	($E,&DWP(16,"esi"));
-+	&mov	("edi",&DWP(20,"esi"));
-+	&mov	("ecx",&DWP(24,"esi"));
-+	&mov	("esi",&DWP(28,"esi"));
-+	#&mov	(&DWP(16,"esp"),$E);
-+	&mov	(&DWP(20,"esp"),"edi");
-+	&mov	("edi",&DWP(96+4,"esp"));	# inp
-+	&mov	(&DWP(24,"esp"),"ecx");
-+	&mov	(&DWP(28,"esp"),"esi");
-+	&vmovdqa	($t3,&QWP(256,$K256));
-+	&jmp	(&label("grand_avx_bmi"));
-+
-+&set_label("grand_avx_bmi",32);
-+	# load input, reverse byte order, add K256[0..15], save to stack
-+	&vmovdqu	(@X[0],&QWP(0,"edi"));
-+	&vmovdqu	(@X[1],&QWP(16,"edi"));
-+	&vmovdqu	(@X[2],&QWP(32,"edi"));
-+	&vmovdqu	(@X[3],&QWP(48,"edi"));
-+	&add		("edi",64);
-+	&vpshufb	(@X[0],@X[0],$t3);
-+	&mov		(&DWP(96+4,"esp"),"edi");
-+	&vpshufb	(@X[1],@X[1],$t3);
-+	&vpshufb	(@X[2],@X[2],$t3);
-+	&vpaddd		($t0,@X[0],&QWP(0,$K256));
-+	&vpshufb	(@X[3],@X[3],$t3);
-+	&vpaddd		($t1,@X[1],&QWP(16,$K256));
-+	&vpaddd		($t2,@X[2],&QWP(32,$K256));
-+	&vpaddd		($t3,@X[3],&QWP(48,$K256));
-+	&vmovdqa	(&QWP(32+0,"esp"),$t0);
-+	&vmovdqa	(&QWP(32+16,"esp"),$t1);
-+	&vmovdqa	(&QWP(32+32,"esp"),$t2);
-+	&vmovdqa	(&QWP(32+48,"esp"),$t3);
-+	&jmp		(&label("avx_bmi_00_47"));
-+
-+&set_label("avx_bmi_00_47",16);
-+	&add		($K256,64);
-+
-+    for ($i=0,$j=0; $j<4; $j++) {
-+	&AVX_00_47($j,\&bodyx_00_15,@X);
-+	push(@X,shift(@X));		# rotate(@X)
-+    }
-+	&cmp	(&DWP(16*$j,$K256),0x00010203);
-+	&jne	(&label("avx_bmi_00_47"));
-+
-+    for ($i=0; $i<16; ) {
-+	foreach(bodyx_00_15()) { eval; }
-+    }
-+
-+	&mov	("esi",&DWP(96,"esp"));	#ctx
-+					#&mov	($AH[0],&DWP(0,"esp"));
-+	&xor	($AH[1],"edi");		#&mov	($AH[1],&DWP(4,"esp"));
-+					#&mov	("edi", &DWP(8,"esp"));
-+	&mov	("ecx",&DWP(12,"esp"));
-+	&add	($AH[0],&DWP(0,"esi"));
-+	&add	($AH[1],&DWP(4,"esi"));
-+	&add	("edi",&DWP(8,"esi"));
-+	&add	("ecx",&DWP(12,"esi"));
-+	&mov	(&DWP(0,"esi"),$AH[0]);
-+	&mov	(&DWP(4,"esi"),$AH[1]);
-+	&mov	(&DWP(8,"esi"),"edi");
-+	&mov	(&DWP(12,"esi"),"ecx");
-+	 #&mov	(&DWP(0,"esp"),$AH[0]);
-+	 &mov	(&DWP(4,"esp"),$AH[1]);
-+	 &xor	($AH[1],"edi");			# magic
-+	 &mov	(&DWP(8,"esp"),"edi");
-+	 &mov	(&DWP(12,"esp"),"ecx");
-+	#&mov	($E,&DWP(16,"esp"));
-+	&mov	("edi",&DWP(20,"esp"));
-+	&mov	("ecx",&DWP(24,"esp"));
-+	&add	($E,&DWP(16,"esi"));
-+	&add	("edi",&DWP(20,"esi"));
-+	&add	("ecx",&DWP(24,"esi"));
-+	&mov	(&DWP(16,"esi"),$E);
-+	&mov	(&DWP(20,"esi"),"edi");
-+	 &mov	(&DWP(20,"esp"),"edi");
-+	&mov	("edi",&DWP(28,"esp"));
-+	&mov	(&DWP(24,"esi"),"ecx");
-+	 #&mov	(&DWP(16,"esp"),$E);
-+	&add	("edi",&DWP(28,"esi"));
-+	 &mov	(&DWP(24,"esp"),"ecx");
-+	&mov	(&DWP(28,"esi"),"edi");
-+	 &mov	(&DWP(28,"esp"),"edi");
-+	&mov	("edi",&DWP(96+4,"esp"));	# inp
-+
-+	&vmovdqa	($t3,&QWP(64,$K256));
-+	&sub	($K256,3*64);			# rewind K
-+	&cmp	("edi",&DWP(96+8,"esp"));	# are we done yet?
-+	&jb	(&label("grand_avx_bmi"));
-+
-+	&mov	("esp",&DWP(96+12,"esp"));	# restore sp
-+	&vzeroall	();
-+&function_end_A();
-+						}
-+						}
-+						}}}
-+&function_end_B("sha256_block_data_order");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-armv4.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-armv4.pl
-new file mode 100644
-index 0000000..55d30cb
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-armv4.pl
-@@ -0,0 +1,732 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+#
-+# Permission to use under GPL terms is granted.
-+# ====================================================================
-+
-+# SHA256 block procedure for ARMv4. May 2007.
-+
-+# Performance is ~2x better than gcc 3.4 generated code and in "abso-
-+# lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per
-+# byte [on single-issue Xscale PXA250 core].
-+
-+# July 2010.
-+#
-+# Rescheduling for dual-issue pipeline resulted in 22% improvement on
-+# Cortex A8 core and ~20 cycles per processed byte.
-+
-+# February 2011.
-+#
-+# Profiler-assisted and platform-specific optimization resulted in 16%
-+# improvement on Cortex A8 core and ~15.4 cycles per processed byte.
-+
-+# September 2013.
-+#
-+# Add NEON implementation. On Cortex A8 it was measured to process one
-+# byte in 12.5 cycles or 23% faster than integer-only code. Snapdragon
-+# S4 does it in 12.5 cycles too, but it's 50% faster than integer-only
-+# code (meaning that latter performs sub-optimally, nothing was done
-+# about it).
-+
-+# May 2014.
-+#
-+# Add ARMv8 code path performing at 2.0 cpb on Apple A7.
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+$ctx="r0";	$t0="r0";
-+$inp="r1";	$t4="r1";
-+$len="r2";	$t1="r2";
-+$T1="r3";	$t3="r3";
-+$A="r4";
-+$B="r5";
-+$C="r6";
-+$D="r7";
-+$E="r8";
-+$F="r9";
-+$G="r10";
-+$H="r11";
-+@V=($A,$B,$C,$D,$E,$F,$G,$H);
-+$t2="r12";
-+$Ktbl="r14";
-+
-+@Sigma0=( 2,13,22);
-+@Sigma1=( 6,11,25);
-+@sigma0=( 7,18, 3);
-+@sigma1=(17,19,10);
-+
-+sub BODY_00_15 {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
-+
-+$code.=<<___ if ($i<16);
-+#if __ARM_ARCH__>=7
-+	@ ldr	$t1,[$inp],#4			@ $i
-+# if $i==15
-+	str	$inp,[sp,#17*4]			@ make room for $t4
-+# endif
-+	eor	$t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`
-+	add	$a,$a,$t2			@ h+=Maj(a,b,c) from the past
-+	eor	$t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]`	@ Sigma1(e)
-+# ifndef __ARMEB__
-+	rev	$t1,$t1
-+# endif
-+#else
-+	@ ldrb	$t1,[$inp,#3]			@ $i
-+	add	$a,$a,$t2			@ h+=Maj(a,b,c) from the past
-+	ldrb	$t2,[$inp,#2]
-+	ldrb	$t0,[$inp,#1]
-+	orr	$t1,$t1,$t2,lsl#8
-+	ldrb	$t2,[$inp],#4
-+	orr	$t1,$t1,$t0,lsl#16
-+# if $i==15
-+	str	$inp,[sp,#17*4]			@ make room for $t4
-+# endif
-+	eor	$t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`
-+	orr	$t1,$t1,$t2,lsl#24
-+	eor	$t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]`	@ Sigma1(e)
-+#endif
-+___
-+$code.=<<___;
-+	ldr	$t2,[$Ktbl],#4			@ *K256++
-+	add	$h,$h,$t1			@ h+=X[i]
-+	str	$t1,[sp,#`$i%16`*4]
-+	eor	$t1,$f,$g
-+	add	$h,$h,$t0,ror#$Sigma1[0]	@ h+=Sigma1(e)
-+	and	$t1,$t1,$e
-+	add	$h,$h,$t2			@ h+=K256[i]
-+	eor	$t1,$t1,$g			@ Ch(e,f,g)
-+	eor	$t0,$a,$a,ror#`$Sigma0[1]-$Sigma0[0]`
-+	add	$h,$h,$t1			@ h+=Ch(e,f,g)
-+#if $i==31
-+	and	$t2,$t2,#0xff
-+	cmp	$t2,#0xf2			@ done?
-+#endif
-+#if $i<15
-+# if __ARM_ARCH__>=7
-+	ldr	$t1,[$inp],#4			@ prefetch
-+# else
-+	ldrb	$t1,[$inp,#3]
-+# endif
-+	eor	$t2,$a,$b			@ a^b, b^c in next round
-+#else
-+	ldr	$t1,[sp,#`($i+2)%16`*4]		@ from future BODY_16_xx
-+	eor	$t2,$a,$b			@ a^b, b^c in next round
-+	ldr	$t4,[sp,#`($i+15)%16`*4]	@ from future BODY_16_xx
-+#endif
-+	eor	$t0,$t0,$a,ror#`$Sigma0[2]-$Sigma0[0]`	@ Sigma0(a)
-+	and	$t3,$t3,$t2			@ (b^c)&=(a^b)
-+	add	$d,$d,$h			@ d+=h
-+	eor	$t3,$t3,$b			@ Maj(a,b,c)
-+	add	$h,$h,$t0,ror#$Sigma0[0]	@ h+=Sigma0(a)
-+	@ add	$h,$h,$t3			@ h+=Maj(a,b,c)
-+___
-+	($t2,$t3)=($t3,$t2);
-+}
-+
-+sub BODY_16_XX {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
-+
-+$code.=<<___;
-+	@ ldr	$t1,[sp,#`($i+1)%16`*4]		@ $i
-+	@ ldr	$t4,[sp,#`($i+14)%16`*4]
-+	mov	$t0,$t1,ror#$sigma0[0]
-+	add	$a,$a,$t2			@ h+=Maj(a,b,c) from the past
-+	mov	$t2,$t4,ror#$sigma1[0]
-+	eor	$t0,$t0,$t1,ror#$sigma0[1]
-+	eor	$t2,$t2,$t4,ror#$sigma1[1]
-+	eor	$t0,$t0,$t1,lsr#$sigma0[2]	@ sigma0(X[i+1])
-+	ldr	$t1,[sp,#`($i+0)%16`*4]
-+	eor	$t2,$t2,$t4,lsr#$sigma1[2]	@ sigma1(X[i+14])
-+	ldr	$t4,[sp,#`($i+9)%16`*4]
-+
-+	add	$t2,$t2,$t0
-+	eor	$t0,$e,$e,ror#`$Sigma1[1]-$Sigma1[0]`	@ from BODY_00_15
-+	add	$t1,$t1,$t2
-+	eor	$t0,$t0,$e,ror#`$Sigma1[2]-$Sigma1[0]`	@ Sigma1(e)
-+	add	$t1,$t1,$t4			@ X[i]
-+___
-+	&BODY_00_15(@_);
-+}
-+
-+$code=<<___;
-+#ifndef __KERNEL__
-+# include "arm_arch.h"
-+#else
-+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
-+# define __ARM_MAX_ARCH__ 7
-+#endif
-+
-+.text
-+#if defined(__thumb2__)
-+.syntax unified
-+.thumb
-+#else
-+.code   32
-+#endif
-+
-+.type	K256,%object
-+.align	5
-+K256:
-+.word	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+.word	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+.word	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+.word	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+.word	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+.word	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+.word	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+.word	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+.word	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+.word	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+.word	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+.word	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+.word	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+.word	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+.word	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+.word	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+.size	K256,.-K256
-+.word	0				@ terminator
-+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
-+.LOPENSSL_armcap:
-+.word	OPENSSL_armcap_P-.Lsha256_block_data_order
-+#endif
-+.align	5
-+
-+.global	sha256_block_data_order
-+.type	sha256_block_data_order,%function
-+sha256_block_data_order:
-+.Lsha256_block_data_order:
-+#if __ARM_ARCH__<7 && !defined(__thumb2__)
-+	sub	r3,pc,#8		@ sha256_block_data_order
-+#else
-+	adr	r3,.Lsha256_block_data_order
-+#endif
-+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
-+	ldr	r12,.LOPENSSL_armcap
-+	ldr	r12,[r3,r12]		@ OPENSSL_armcap_P
-+#ifdef	__APPLE__
-+	ldr	r12,[r12]
-+#endif
-+	tst	r12,#ARMV8_SHA256
-+	bne	.LARMv8
-+	tst	r12,#ARMV7_NEON
-+	bne	.LNEON
-+#endif
-+	add	$len,$inp,$len,lsl#6	@ len to point at the end of inp
-+	stmdb	sp!,{$ctx,$inp,$len,r4-r11,lr}
-+	ldmia	$ctx,{$A,$B,$C,$D,$E,$F,$G,$H}
-+	sub	$Ktbl,r3,#256+32	@ K256
-+	sub	sp,sp,#16*4		@ alloca(X[16])
-+.Loop:
-+# if __ARM_ARCH__>=7
-+	ldr	$t1,[$inp],#4
-+# else
-+	ldrb	$t1,[$inp,#3]
-+# endif
-+	eor	$t3,$B,$C		@ magic
-+	eor	$t2,$t2,$t2
-+___
-+for($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
-+$code.=".Lrounds_16_xx:\n";
-+for (;$i<32;$i++)	{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+#if __ARM_ARCH__>=7
-+	ite	eq			@ Thumb2 thing, sanity check in ARM
-+#endif
-+	ldreq	$t3,[sp,#16*4]		@ pull ctx
-+	bne	.Lrounds_16_xx
-+
-+	add	$A,$A,$t2		@ h+=Maj(a,b,c) from the past
-+	ldr	$t0,[$t3,#0]
-+	ldr	$t1,[$t3,#4]
-+	ldr	$t2,[$t3,#8]
-+	add	$A,$A,$t0
-+	ldr	$t0,[$t3,#12]
-+	add	$B,$B,$t1
-+	ldr	$t1,[$t3,#16]
-+	add	$C,$C,$t2
-+	ldr	$t2,[$t3,#20]
-+	add	$D,$D,$t0
-+	ldr	$t0,[$t3,#24]
-+	add	$E,$E,$t1
-+	ldr	$t1,[$t3,#28]
-+	add	$F,$F,$t2
-+	ldr	$inp,[sp,#17*4]		@ pull inp
-+	ldr	$t2,[sp,#18*4]		@ pull inp+len
-+	add	$G,$G,$t0
-+	add	$H,$H,$t1
-+	stmia	$t3,{$A,$B,$C,$D,$E,$F,$G,$H}
-+	cmp	$inp,$t2
-+	sub	$Ktbl,$Ktbl,#256	@ rewind Ktbl
-+	bne	.Loop
-+
-+	add	sp,sp,#`16+3`*4	@ destroy frame
-+#if __ARM_ARCH__>=5
-+	ldmia	sp!,{r4-r11,pc}
-+#else
-+	ldmia	sp!,{r4-r11,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	sha256_block_data_order,.-sha256_block_data_order
-+___
-+######################################################################
-+# NEON stuff
-+#
-+{{{
-+my @X=map("q$_",(0..3));
-+my ($T0,$T1,$T2,$T3,$T4,$T5)=("q8","q9","q10","q11","d24","d25");
-+my $Xfer=$t4;
-+my $j=0;
-+
-+sub Dlo()   { shift=~m|q([1]?[0-9])|?"d".($1*2):"";     }
-+sub Dhi()   { shift=~m|q([1]?[0-9])|?"d".($1*2+1):"";   }
-+
-+sub AUTOLOAD()          # thunk [simplified] x86-style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
-+  my $arg = pop;
-+    $arg = "#$arg" if ($arg*1 eq $arg);
-+    $code .= "\t$opcode\t".join(',',@_,$arg)."\n";
-+}
-+
-+sub Xupdate()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);
-+  my ($a,$b,$c,$d,$e,$f,$g,$h);
-+
-+	&vext_8		($T0,@X[0],@X[1],4);	# X[1..4]
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vext_8		($T1,@X[2],@X[3],4);	# X[9..12]
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vshr_u32	($T2,$T0,$sigma0[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vadd_i32	(@X[0],@X[0],$T1);	# X[0..3] += X[9..12]
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vshr_u32	($T1,$T0,$sigma0[2]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vsli_32	($T2,$T0,32-$sigma0[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vshr_u32	($T3,$T0,$sigma0[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&veor		($T1,$T1,$T2);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vsli_32	($T3,$T0,32-$sigma0[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vshr_u32	($T4,&Dhi(@X[3]),$sigma1[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&veor		($T1,$T1,$T3);		# sigma0(X[1..4])
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vsli_32	($T4,&Dhi(@X[3]),32-$sigma1[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vshr_u32	($T5,&Dhi(@X[3]),$sigma1[2]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vadd_i32	(@X[0],@X[0],$T1);	# X[0..3] += sigma0(X[1..4])
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &veor		($T5,$T5,$T4);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vshr_u32	($T4,&Dhi(@X[3]),$sigma1[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vsli_32	($T4,&Dhi(@X[3]),32-$sigma1[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &veor		($T5,$T5,$T4);		# sigma1(X[14..15])
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vadd_i32	(&Dlo(@X[0]),&Dlo(@X[0]),$T5);# X[0..1] += sigma1(X[14..15])
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vshr_u32	($T4,&Dlo(@X[0]),$sigma1[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vsli_32	($T4,&Dlo(@X[0]),32-$sigma1[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vshr_u32	($T5,&Dlo(@X[0]),$sigma1[2]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &veor		($T5,$T5,$T4);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vshr_u32	($T4,&Dlo(@X[0]),$sigma1[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vld1_32	("{$T0}","[$Ktbl,:128]!");
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &vsli_32	($T4,&Dlo(@X[0]),32-$sigma1[1]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	  &veor		($T5,$T5,$T4);		# sigma1(X[16..17])
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vadd_i32	(&Dhi(@X[0]),&Dhi(@X[0]),$T5);# X[2..3] += sigma1(X[16..17])
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vadd_i32	($T0,$T0,@X[0]);
-+	 while($#insns>=2) { eval(shift(@insns)); }
-+	&vst1_32	("{$T0}","[$Xfer,:128]!");
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+
-+	push(@X,shift(@X));		# "rotate" X[]
-+}
-+
-+sub Xpreload()
-+{ use integer;
-+  my $body = shift;
-+  my @insns = (&$body,&$body,&$body,&$body);
-+  my ($a,$b,$c,$d,$e,$f,$g,$h);
-+
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vld1_32	("{$T0}","[$Ktbl,:128]!");
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vrev32_8	(@X[0],@X[0]);
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&vadd_i32	($T0,$T0,@X[0]);
-+	 foreach (@insns) { eval; }	# remaining instructions
-+	&vst1_32	("{$T0}","[$Xfer,:128]!");
-+
-+	push(@X,shift(@X));		# "rotate" X[]
-+}
-+
-+sub body_00_15 () {
-+	(
-+	'($a,$b,$c,$d,$e,$f,$g,$h)=@V;'.
-+	'&add	($h,$h,$t1)',			# h+=X[i]+K[i]
-+	'&eor	($t1,$f,$g)',
-+	'&eor	($t0,$e,$e,"ror#".($Sigma1[1]-$Sigma1[0]))',
-+	'&add	($a,$a,$t2)',			# h+=Maj(a,b,c) from the past
-+	'&and	($t1,$t1,$e)',
-+	'&eor	($t2,$t0,$e,"ror#".($Sigma1[2]-$Sigma1[0]))',	# Sigma1(e)
-+	'&eor	($t0,$a,$a,"ror#".($Sigma0[1]-$Sigma0[0]))',
-+	'&eor	($t1,$t1,$g)',			# Ch(e,f,g)
-+	'&add	($h,$h,$t2,"ror#$Sigma1[0]")',	# h+=Sigma1(e)
-+	'&eor	($t2,$a,$b)',			# a^b, b^c in next round
-+	'&eor	($t0,$t0,$a,"ror#".($Sigma0[2]-$Sigma0[0]))',	# Sigma0(a)
-+	'&add	($h,$h,$t1)',			# h+=Ch(e,f,g)
-+	'&ldr	($t1,sprintf "[sp,#%d]",4*(($j+1)&15))	if (($j&15)!=15);'.
-+	'&ldr	($t1,"[$Ktbl]")				if ($j==15);'.
-+	'&ldr	($t1,"[sp,#64]")			if ($j==31)',
-+	'&and	($t3,$t3,$t2)',			# (b^c)&=(a^b)
-+	'&add	($d,$d,$h)',			# d+=h
-+	'&add	($h,$h,$t0,"ror#$Sigma0[0]");'.	# h+=Sigma0(a)
-+	'&eor	($t3,$t3,$b)',			# Maj(a,b,c)
-+	'$j++;	unshift(@V,pop(@V)); ($t2,$t3)=($t3,$t2);'
-+	)
-+}
-+
-+$code.=<<___;
-+#if __ARM_MAX_ARCH__>=7
-+.arch	armv7-a
-+.fpu	neon
-+
-+.global	sha256_block_data_order_neon
-+.type	sha256_block_data_order_neon,%function
-+.align	5
-+.skip	16
-+sha256_block_data_order_neon:
-+.LNEON:
-+	stmdb	sp!,{r4-r12,lr}
-+
-+	sub	$H,sp,#16*4+16
-+	adr	$Ktbl,K256
-+	bic	$H,$H,#15		@ align for 128-bit stores
-+	mov	$t2,sp
-+	mov	sp,$H			@ alloca
-+	add	$len,$inp,$len,lsl#6	@ len to point at the end of inp
-+
-+	vld1.8		{@X[0]},[$inp]!
-+	vld1.8		{@X[1]},[$inp]!
-+	vld1.8		{@X[2]},[$inp]!
-+	vld1.8		{@X[3]},[$inp]!
-+	vld1.32		{$T0},[$Ktbl,:128]!
-+	vld1.32		{$T1},[$Ktbl,:128]!
-+	vld1.32		{$T2},[$Ktbl,:128]!
-+	vld1.32		{$T3},[$Ktbl,:128]!
-+	vrev32.8	@X[0],@X[0]		@ yes, even on
-+	str		$ctx,[sp,#64]
-+	vrev32.8	@X[1],@X[1]		@ big-endian
-+	str		$inp,[sp,#68]
-+	mov		$Xfer,sp
-+	vrev32.8	@X[2],@X[2]
-+	str		$len,[sp,#72]
-+	vrev32.8	@X[3],@X[3]
-+	str		$t2,[sp,#76]		@ save original sp
-+	vadd.i32	$T0,$T0,@X[0]
-+	vadd.i32	$T1,$T1,@X[1]
-+	vst1.32		{$T0},[$Xfer,:128]!
-+	vadd.i32	$T2,$T2,@X[2]
-+	vst1.32		{$T1},[$Xfer,:128]!
-+	vadd.i32	$T3,$T3,@X[3]
-+	vst1.32		{$T2},[$Xfer,:128]!
-+	vst1.32		{$T3},[$Xfer,:128]!
-+
-+	ldmia		$ctx,{$A-$H}
-+	sub		$Xfer,$Xfer,#64
-+	ldr		$t1,[sp,#0]
-+	eor		$t2,$t2,$t2
-+	eor		$t3,$B,$C
-+	b		.L_00_48
-+
-+.align	4
-+.L_00_48:
-+___
-+	&Xupdate(\&body_00_15);
-+	&Xupdate(\&body_00_15);
-+	&Xupdate(\&body_00_15);
-+	&Xupdate(\&body_00_15);
-+$code.=<<___;
-+	teq	$t1,#0				@ check for K256 terminator
-+	ldr	$t1,[sp,#0]
-+	sub	$Xfer,$Xfer,#64
-+	bne	.L_00_48
-+
-+	ldr		$inp,[sp,#68]
-+	ldr		$t0,[sp,#72]
-+	sub		$Ktbl,$Ktbl,#256	@ rewind $Ktbl
-+	teq		$inp,$t0
-+	it		eq
-+	subeq		$inp,$inp,#64		@ avoid SEGV
-+	vld1.8		{@X[0]},[$inp]!		@ load next input block
-+	vld1.8		{@X[1]},[$inp]!
-+	vld1.8		{@X[2]},[$inp]!
-+	vld1.8		{@X[3]},[$inp]!
-+	it		ne
-+	strne		$inp,[sp,#68]
-+	mov		$Xfer,sp
-+___
-+	&Xpreload(\&body_00_15);
-+	&Xpreload(\&body_00_15);
-+	&Xpreload(\&body_00_15);
-+	&Xpreload(\&body_00_15);
-+$code.=<<___;
-+	ldr	$t0,[$t1,#0]
-+	add	$A,$A,$t2			@ h+=Maj(a,b,c) from the past
-+	ldr	$t2,[$t1,#4]
-+	ldr	$t3,[$t1,#8]
-+	ldr	$t4,[$t1,#12]
-+	add	$A,$A,$t0			@ accumulate
-+	ldr	$t0,[$t1,#16]
-+	add	$B,$B,$t2
-+	ldr	$t2,[$t1,#20]
-+	add	$C,$C,$t3
-+	ldr	$t3,[$t1,#24]
-+	add	$D,$D,$t4
-+	ldr	$t4,[$t1,#28]
-+	add	$E,$E,$t0
-+	str	$A,[$t1],#4
-+	add	$F,$F,$t2
-+	str	$B,[$t1],#4
-+	add	$G,$G,$t3
-+	str	$C,[$t1],#4
-+	add	$H,$H,$t4
-+	str	$D,[$t1],#4
-+	stmia	$t1,{$E-$H}
-+
-+	ittte	ne
-+	movne	$Xfer,sp
-+	ldrne	$t1,[sp,#0]
-+	eorne	$t2,$t2,$t2
-+	ldreq	sp,[sp,#76]			@ restore original sp
-+	itt	ne
-+	eorne	$t3,$B,$C
-+	bne	.L_00_48
-+
-+	ldmia	sp!,{r4-r12,pc}
-+.size	sha256_block_data_order_neon,.-sha256_block_data_order_neon
-+#endif
-+___
-+}}}
-+######################################################################
-+# ARMv8 stuff
-+#
-+{{{
-+my ($ABCD,$EFGH,$abcd)=map("q$_",(0..2));
-+my @MSG=map("q$_",(8..11));
-+my ($W0,$W1,$ABCD_SAVE,$EFGH_SAVE)=map("q$_",(12..15));
-+my $Ktbl="r3";
-+
-+$code.=<<___;
-+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
-+
-+# if defined(__thumb2__)
-+#  define INST(a,b,c,d)	.byte	c,d|0xc,a,b
-+# else
-+#  define INST(a,b,c,d)	.byte	a,b,c,d
-+# endif
-+
-+.type	sha256_block_data_order_armv8,%function
-+.align	5
-+sha256_block_data_order_armv8:
-+.LARMv8:
-+	vld1.32	{$ABCD,$EFGH},[$ctx]
-+	sub	$Ktbl,$Ktbl,#256+32
-+	add	$len,$inp,$len,lsl#6	@ len to point at the end of inp
-+	b	.Loop_v8
-+
-+.align	4
-+.Loop_v8:
-+	vld1.8		{@MSG[0]-@MSG[1]},[$inp]!
-+	vld1.8		{@MSG[2]-@MSG[3]},[$inp]!
-+	vld1.32		{$W0},[$Ktbl]!
-+	vrev32.8	@MSG[0],@MSG[0]
-+	vrev32.8	@MSG[1],@MSG[1]
-+	vrev32.8	@MSG[2],@MSG[2]
-+	vrev32.8	@MSG[3],@MSG[3]
-+	vmov		$ABCD_SAVE,$ABCD	@ offload
-+	vmov		$EFGH_SAVE,$EFGH
-+	teq		$inp,$len
-+___
-+for($i=0;$i<12;$i++) {
-+$code.=<<___;
-+	vld1.32		{$W1},[$Ktbl]!
-+	vadd.i32	$W0,$W0,@MSG[0]
-+	sha256su0	@MSG[0],@MSG[1]
-+	vmov		$abcd,$ABCD
-+	sha256h		$ABCD,$EFGH,$W0
-+	sha256h2	$EFGH,$abcd,$W0
-+	sha256su1	@MSG[0],@MSG[2],@MSG[3]
-+___
-+	($W0,$W1)=($W1,$W0);	push(@MSG,shift(@MSG));
-+}
-+$code.=<<___;
-+	vld1.32		{$W1},[$Ktbl]!
-+	vadd.i32	$W0,$W0,@MSG[0]
-+	vmov		$abcd,$ABCD
-+	sha256h		$ABCD,$EFGH,$W0
-+	sha256h2	$EFGH,$abcd,$W0
-+
-+	vld1.32		{$W0},[$Ktbl]!
-+	vadd.i32	$W1,$W1,@MSG[1]
-+	vmov		$abcd,$ABCD
-+	sha256h		$ABCD,$EFGH,$W1
-+	sha256h2	$EFGH,$abcd,$W1
-+
-+	vld1.32		{$W1},[$Ktbl]
-+	vadd.i32	$W0,$W0,@MSG[2]
-+	sub		$Ktbl,$Ktbl,#256-16	@ rewind
-+	vmov		$abcd,$ABCD
-+	sha256h		$ABCD,$EFGH,$W0
-+	sha256h2	$EFGH,$abcd,$W0
-+
-+	vadd.i32	$W1,$W1,@MSG[3]
-+	vmov		$abcd,$ABCD
-+	sha256h		$ABCD,$EFGH,$W1
-+	sha256h2	$EFGH,$abcd,$W1
-+
-+	vadd.i32	$ABCD,$ABCD,$ABCD_SAVE
-+	vadd.i32	$EFGH,$EFGH,$EFGH_SAVE
-+	it		ne
-+	bne		.Loop_v8
-+
-+	vst1.32		{$ABCD,$EFGH},[$ctx]
-+
-+	ret		@ bx lr
-+.size	sha256_block_data_order_armv8,.-sha256_block_data_order_armv8
-+#endif
-+___
-+}}}
-+$code.=<<___;
-+.asciz  "SHA256 block transform for ARMv4/NEON/ARMv8, CRYPTOGAMS by "
-+.align	2
-+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
-+.comm   OPENSSL_armcap_P,4,4
-+#endif
-+___
-+
-+open SELF,$0;
-+while() {
-+	next if (/^#!/);
-+	last if (!s/^#/@/ and !/^$/);
-+	print;
-+}
-+close SELF;
-+
-+{   my  %opcode = (
-+	"sha256h"	=> 0xf3000c40,	"sha256h2"	=> 0xf3100c40,
-+	"sha256su0"	=> 0xf3ba03c0,	"sha256su1"	=> 0xf3200c40	);
-+
-+    sub unsha256 {
-+	my ($mnemonic,$arg)=@_;
-+
-+	if ($arg =~ m/q([0-9]+)(?:,\s*q([0-9]+))?,\s*q([0-9]+)/o) {
-+	    my $word = $opcode{$mnemonic}|(($1&7)<<13)|(($1&8)<<19)
-+					 |(($2&7)<<17)|(($2&8)<<4)
-+					 |(($3&7)<<1) |(($3&8)<<2);
-+	    # since ARMv7 instructions are always encoded little-endian.
-+	    # correct solution is to use .inst directive, but older
-+	    # assemblers don't implement it:-(
-+	    sprintf "INST(0x%02x,0x%02x,0x%02x,0x%02x)\t@ %s %s",
-+			$word&0xff,($word>>8)&0xff,
-+			($word>>16)&0xff,($word>>24)&0xff,
-+			$mnemonic,$arg;
-+	}
-+    }
-+}
-+
-+foreach (split($/,$code)) {
-+
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	s/\b(sha256\w+)\s+(q.*)/unsha256($1,$2)/geo;
-+
-+	s/\bret\b/bx	lr/go		or
-+	s/\bbx\s+lr\b/.word\t0xe12fff1e/go;	# make it possible to compile with -march=armv4
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT; # enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-c64xplus.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-c64xplus.pl
-new file mode 100644
-index 0000000..3ab7d9b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-c64xplus.pl
-@@ -0,0 +1,320 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# SHA256 for C64x+.
-+#
-+# January 2012
-+#
-+# Performance is just below 10 cycles per processed byte, which is
-+# almost 40% faster than compiler-generated code. Unroll is unlikely
-+# to give more than ~8% improvement...
-+#
-+# !!! Note that this module uses AMR, which means that all interrupt
-+# service routines are expected to preserve it and for own well-being
-+# zero it upon entry.
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+($CTXA,$INP,$NUM) = ("A4","B4","A6");            # arguments
-+ $K256="A3";
-+
-+($A,$Actx,$B,$Bctx,$C,$Cctx,$D,$Dctx,$T2,$S0,$s1,$t0a,$t1a,$t2a,$X9,$X14)
-+	=map("A$_",(16..31));
-+($E,$Ectx,$F,$Fctx,$G,$Gctx,$H,$Hctx,$T1,$S1,$s0,$t0e,$t1e,$t2e,$X1,$X15)
-+	=map("B$_",(16..31));
-+
-+($Xia,$Xib)=("A5","B5");			# circular/ring buffer
-+ $CTXB=$t2e;
-+
-+($Xn,$X0,$K)=("B7","B8","B9");
-+($Maj,$Ch)=($T2,"B6");
-+
-+$code.=<<___;
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.nocmp
-+	.asg	sha256_block_data_order,_sha256_block_data_order
-+	.endif
-+
-+	.asg	B3,RA
-+	.asg	A15,FP
-+	.asg	B15,SP
-+
-+	.if	.BIG_ENDIAN
-+	.asg	SWAP2,MV
-+	.asg	SWAP4,MV
-+	.endif
-+
-+	.global	_sha256_block_data_order
-+_sha256_block_data_order:
-+__sha256_block:
-+	.asmfunc stack_usage(64)
-+	MV	$NUM,A0				; reassign $NUM
-+||	MVK	-64,B0
-+  [!A0]	BNOP	RA				; if ($NUM==0) return;
-+|| [A0]	STW	FP,*SP--[16]			; save frame pointer and alloca(64)
-+|| [A0]	MV	SP,FP
-+   [A0]	ADDKPC	__sha256_block,B2
-+|| [A0]	AND	B0,SP,SP			; align stack at 64 bytes
-+	.if	__TI_EABI__
-+   [A0]	MVK	0x00404,B1
-+|| [A0]	MVKL	\$PCR_OFFSET(K256,__sha256_block),$K256
-+   [A0]	MVKH	0x50000,B1
-+|| [A0]	MVKH	\$PCR_OFFSET(K256,__sha256_block),$K256
-+	.else
-+   [A0]	MVK	0x00404,B1
-+|| [A0]	MVKL	(K256-__sha256_block),$K256
-+   [A0]	MVKH	0x50000,B1
-+|| [A0]	MVKH	(K256-__sha256_block),$K256
-+	.endif
-+   [A0]	MVC	B1,AMR				; setup circular addressing
-+|| [A0]	MV	SP,$Xia
-+   [A0]	MV	SP,$Xib
-+|| [A0]	ADD	B2,$K256,$K256
-+|| [A0]	MV	$CTXA,$CTXB
-+|| [A0]	SUBAW	SP,2,SP				; reserve two words above buffer
-+	LDW	*${CTXA}[0],$A			; load ctx
-+||	LDW	*${CTXB}[4],$E
-+	LDW	*${CTXA}[1],$B
-+||	LDW	*${CTXB}[5],$F
-+	LDW	*${CTXA}[2],$C
-+||	LDW	*${CTXB}[6],$G
-+	LDW	*${CTXA}[3],$D
-+||	LDW	*${CTXB}[7],$H
-+
-+	LDNW	*$INP++,$Xn			; pre-fetch input
-+	LDW	*$K256++,$K			; pre-fetch K256[0]
-+	MVK	14,B0				; loop counters
-+	MVK	47,B1
-+||	ADDAW	$Xia,9,$Xia
-+outerloop?:
-+	SUB	A0,1,A0
-+||	MV	$A,$Actx
-+||	MV	$E,$Ectx
-+||	MVD	$B,$Bctx
-+||	MVD	$F,$Fctx
-+	MV	$C,$Cctx
-+||	MV	$G,$Gctx
-+||	MVD	$D,$Dctx
-+||	MVD	$H,$Hctx
-+||	SWAP4	$Xn,$X0
-+
-+	SPLOOPD	8				; BODY_00_14
-+||	MVC	B0,ILC
-+||	SWAP2	$X0,$X0
-+
-+	LDNW	*$INP++,$Xn
-+||	ROTL	$A,30,$S0
-+||	OR	$A,$B,$Maj
-+||	AND	$A,$B,$t2a
-+||	ROTL	$E,26,$S1
-+||	AND	$F,$E,$Ch
-+||	ANDN	$G,$E,$t2e
-+	ROTL	$A,19,$t0a
-+||	AND	$C,$Maj,$Maj
-+||	ROTL	$E,21,$t0e
-+||	XOR	$t2e,$Ch,$Ch			; Ch(e,f,g) = (e&f)^(~e&g)
-+	ROTL	$A,10,$t1a
-+||	OR	$t2a,$Maj,$Maj			; Maj(a,b,c) = ((a|b)&c)|(a&b)
-+||	ROTL	$E,7,$t1e
-+||	ADD	$K,$H,$T1			; T1 = h + K256[i]
-+	ADD	$X0,$T1,$T1			; T1 += X[i];
-+||	STW	$X0,*$Xib++
-+||	XOR	$t0a,$S0,$S0
-+||	XOR	$t0e,$S1,$S1
-+	XOR	$t1a,$S0,$S0			; Sigma0(a)
-+||	XOR	$t1e,$S1,$S1			; Sigma1(e)
-+||	LDW	*$K256++,$K			; pre-fetch K256[i+1]
-+||	ADD	$Ch,$T1,$T1			; T1 += Ch(e,f,g)
-+	ADD	$S1,$T1,$T1			; T1 += Sigma1(e)
-+||	ADD	$S0,$Maj,$T2			; T2 = Sigma0(a) + Maj(a,b,c)
-+||	ROTL	$G,0,$H				; h = g
-+||	MV	$F,$G				; g = f
-+||	MV	$X0,$X14
-+||	SWAP4	$Xn,$X0
-+	SWAP2	$X0,$X0
-+||	MV	$E,$F				; f = e
-+||	ADD	$D,$T1,$E			; e = d + T1
-+||	MV	$C,$D				; d = c
-+	MV	$B,$C				; c = b
-+||	MV	$A,$B				; b = a
-+||	ADD	$T1,$T2,$A			; a = T1 + T2
-+	SPKERNEL
-+
-+	ROTL	$A,30,$S0			; BODY_15
-+||	OR	$A,$B,$Maj
-+||	AND	$A,$B,$t2a
-+||	ROTL	$E,26,$S1
-+||	AND	$F,$E,$Ch
-+||	ANDN	$G,$E,$t2e
-+||	LDW	*${Xib}[1],$Xn			; modulo-scheduled
-+	ROTL	$A,19,$t0a
-+||	AND	$C,$Maj,$Maj
-+||	ROTL	$E,21,$t0e
-+||	XOR	$t2e,$Ch,$Ch			; Ch(e,f,g) = (e&f)^(~e&g)
-+||	LDW	*${Xib}[2],$X1			; modulo-scheduled
-+	ROTL	$A,10,$t1a
-+||	OR	$t2a,$Maj,$Maj			; Maj(a,b,c) = ((a|b)&c)|(a&b)
-+||	ROTL	$E,7,$t1e
-+||	ADD	$K,$H,$T1			; T1 = h + K256[i]
-+	ADD	$X0,$T1,$T1			; T1 += X[i];
-+||	STW	$X0,*$Xib++
-+||	XOR	$t0a,$S0,$S0
-+||	XOR	$t0e,$S1,$S1
-+	XOR	$t1a,$S0,$S0			; Sigma0(a)
-+||	XOR	$t1e,$S1,$S1			; Sigma1(e)
-+||	LDW	*$K256++,$K			; pre-fetch K256[i+1]
-+||	ADD	$Ch,$T1,$T1			; T1 += Ch(e,f,g)
-+	ADD	$S1,$T1,$T1			; T1 += Sigma1(e)
-+||	ADD	$S0,$Maj,$T2			; T2 = Sigma0(a) + Maj(a,b,c)
-+||	ROTL	$G,0,$H				; h = g
-+||	MV	$F,$G				; g = f
-+||	MV	$X0,$X15
-+	MV	$E,$F				; f = e
-+||	ADD	$D,$T1,$E			; e = d + T1
-+||	MV	$C,$D				; d = c
-+||	MV	$Xn,$X0				; modulo-scheduled
-+||	LDW	*$Xia,$X9			; modulo-scheduled
-+||	ROTL	$X1,25,$t0e			; modulo-scheduled
-+||	ROTL	$X14,15,$t0a			; modulo-scheduled
-+	SHRU	$X1,3,$s0			; modulo-scheduled
-+||	SHRU	$X14,10,$s1			; modulo-scheduled
-+||	ROTL	$B,0,$C				; c = b
-+||	MV	$A,$B				; b = a
-+||	ADD	$T1,$T2,$A			; a = T1 + T2
-+
-+	SPLOOPD	10				; BODY_16_63
-+||	MVC	B1,ILC
-+||	ROTL	$X1,14,$t1e			; modulo-scheduled
-+||	ROTL	$X14,13,$t1a			; modulo-scheduled
-+
-+	XOR	$t0e,$s0,$s0
-+||	XOR	$t0a,$s1,$s1
-+||	MV	$X15,$X14
-+||	MV	$X1,$Xn
-+	XOR	$t1e,$s0,$s0			; sigma0(X[i+1])
-+||	XOR	$t1a,$s1,$s1			; sigma1(X[i+14])
-+||	LDW	*${Xib}[2],$X1			; module-scheduled
-+	ROTL	$A,30,$S0
-+||	OR	$A,$B,$Maj
-+||	AND	$A,$B,$t2a
-+||	ROTL	$E,26,$S1
-+||	AND	$F,$E,$Ch
-+||	ANDN	$G,$E,$t2e
-+||	ADD	$X9,$X0,$X0			; X[i] += X[i+9]
-+	ROTL	$A,19,$t0a
-+||	AND	$C,$Maj,$Maj
-+||	ROTL	$E,21,$t0e
-+||	XOR	$t2e,$Ch,$Ch			; Ch(e,f,g) = (e&f)^(~e&g)
-+||	ADD	$s0,$X0,$X0			; X[i] += sigma1(X[i+1])
-+	ROTL	$A,10,$t1a
-+||	OR	$t2a,$Maj,$Maj			; Maj(a,b,c) = ((a|b)&c)|(a&b)
-+||	ROTL	$E,7,$t1e
-+||	ADD	$H,$K,$T1			; T1 = h + K256[i]
-+||	ADD	$s1,$X0,$X0			; X[i] += sigma1(X[i+14])
-+	XOR	$t0a,$S0,$S0
-+||	XOR	$t0e,$S1,$S1
-+||	ADD	$X0,$T1,$T1			; T1 += X[i]
-+||	STW	$X0,*$Xib++
-+	XOR	$t1a,$S0,$S0			; Sigma0(a)
-+||	XOR	$t1e,$S1,$S1			; Sigma1(e)
-+||	ADD	$Ch,$T1,$T1			; T1 += Ch(e,f,g)
-+||	MV	$X0,$X15
-+||	ROTL	$G,0,$H				; h = g
-+||	LDW	*$K256++,$K			; pre-fetch K256[i+1]
-+	ADD	$S1,$T1,$T1			; T1 += Sigma1(e)
-+||	ADD	$S0,$Maj,$T2			; T2 = Sigma0(a) + Maj(a,b,c)
-+||	MV	$F,$G				; g = f
-+||	MV	$Xn,$X0				; modulo-scheduled
-+||	LDW	*++$Xia,$X9			; modulo-scheduled
-+||	ROTL	$X1,25,$t0e			; module-scheduled
-+||	ROTL	$X14,15,$t0a			; modulo-scheduled
-+	ROTL	$X1,14,$t1e			; modulo-scheduled
-+||	ROTL	$X14,13,$t1a			; modulo-scheduled
-+||	MV	$E,$F				; f = e
-+||	ADD	$D,$T1,$E			; e = d + T1
-+||	MV	$C,$D				; d = c
-+||	MV	$B,$C				; c = b
-+	MV	$A,$B				; b = a
-+||	ADD	$T1,$T2,$A			; a = T1 + T2
-+||	SHRU	$X1,3,$s0			; modulo-scheduled
-+||	SHRU	$X14,10,$s1			; modulo-scheduled
-+	SPKERNEL
-+
-+   [A0]	B	outerloop?
-+|| [A0]	LDNW	*$INP++,$Xn			; pre-fetch input
-+|| [A0]	ADDK	-260,$K256			; rewind K256
-+||	ADD	$Actx,$A,$A			; accumulate ctx
-+||	ADD	$Ectx,$E,$E
-+||	ADD	$Bctx,$B,$B
-+	ADD	$Fctx,$F,$F
-+||	ADD	$Cctx,$C,$C
-+||	ADD	$Gctx,$G,$G
-+||	ADD	$Dctx,$D,$D
-+||	ADD	$Hctx,$H,$H
-+|| [A0]	LDW	*$K256++,$K			; pre-fetch K256[0]
-+
-+  [!A0]	BNOP	RA
-+||[!A0]	MV	$CTXA,$CTXB
-+  [!A0]	MV	FP,SP				; restore stack pointer
-+||[!A0]	LDW	*FP[0],FP			; restore frame pointer
-+  [!A0]	STW	$A,*${CTXA}[0]  		; save ctx
-+||[!A0]	STW	$E,*${CTXB}[4]
-+||[!A0]	MVK	0,B0
-+  [!A0]	STW	$B,*${CTXA}[1]
-+||[!A0]	STW	$F,*${CTXB}[5]
-+||[!A0]	MVC	B0,AMR				; clear AMR
-+	STW	$C,*${CTXA}[2]
-+||	STW	$G,*${CTXB}[6]
-+	STW	$D,*${CTXA}[3]
-+||	STW	$H,*${CTXB}[7]
-+	.endasmfunc
-+
-+	.if	__TI_EABI__
-+	.sect	".text:sha_asm.const"
-+	.else
-+	.sect	".const:sha_asm"
-+	.endif
-+	.align	128
-+K256:
-+	.uword	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
-+	.uword	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
-+	.uword	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
-+	.uword	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
-+	.uword	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
-+	.uword	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
-+	.uword	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
-+	.uword	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
-+	.uword	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
-+	.uword	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
-+	.uword	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
-+	.uword	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
-+	.uword	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
-+	.uword	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
-+	.uword	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
-+	.uword	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-+	.cstring "SHA256 block transform for C64x+, CRYPTOGAMS by "
-+	.align	4
-+
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-mb-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-mb-x86_64.pl
-new file mode 100644
-index 0000000..fbcd29f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha256-mb-x86_64.pl
-@@ -0,0 +1,1568 @@
-+#! /usr/bin/env perl
-+# Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# Multi-buffer SHA256 procedure processes n buffers in parallel by
-+# placing buffer data to designated lane of SIMD register. n is
-+# naturally limited to 4 on pre-AVX2 processors and to 8 on
-+# AVX2-capable processors such as Haswell.
-+#
-+#		this	+aesni(i)	sha256	aesni-sha256	gain(iv)
-+# -------------------------------------------------------------------
-+# Westmere(ii)	23.3/n	+1.28=7.11(n=4)	12.3	+3.75=16.1	+126%
-+# Atom(ii)	38.7/n	+3.93=13.6(n=4)	20.8	+5.69=26.5	+95%
-+# Sandy Bridge	(20.5	+5.15=25.7)/n	11.6	13.0		+103%
-+# Ivy Bridge	(20.4	+5.14=25.5)/n	10.3	11.6		+82%
-+# Haswell(iii)	(21.0	+5.00=26.0)/n	7.80	8.79		+170%
-+# Skylake	(18.9	+5.00=23.9)/n	7.70	8.17		+170%
-+# Bulldozer	(21.6	+5.76=27.4)/n	13.6	13.7		+100%
-+#
-+# (i)	multi-block CBC encrypt with 128-bit key;
-+# (ii)	(HASH+AES)/n does not apply to Westmere for n>3 and Atom,
-+#	because of lower AES-NI instruction throughput, nor is there
-+#	AES-NI-SHA256 stitch for these processors;
-+# (iii)	"this" is for n=8, when we gather twice as much data, result
-+#	for n=4 is 20.3+4.44=24.7;
-+# (iv)	presented improvement coefficients are asymptotic limits and
-+#	in real-life application are somewhat lower, e.g. for 2KB 
-+#	fragments they range from 75% to 130% (on Haswell);
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+$avx=0;
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	   `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+# void sha256_multi_block (
-+#     struct {	unsigned int A[8];
-+#		unsigned int B[8];
-+#		unsigned int C[8];
-+#		unsigned int D[8];
-+#		unsigned int E[8];
-+#		unsigned int F[8];
-+#		unsigned int G[8];
-+#		unsigned int H[8];	} *ctx,
-+#     struct {	void *ptr; int blocks;	} inp[8],
-+#     int num);		/* 1 or 2 */
-+#
-+$ctx="%rdi";	# 1st arg
-+$inp="%rsi";	# 2nd arg
-+$num="%edx";	# 3rd arg
-+@ptr=map("%r$_",(8..11));
-+$Tbl="%rbp";
-+
-+@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("%xmm$_",(8..15));
-+($t1,$t2,$t3,$axb,$bxc,$Xi,$Xn,$sigma)=map("%xmm$_",(0..7));
-+
-+$REG_SZ=16;
-+
-+sub Xi_off {
-+my $off = shift;
-+
-+    $off %= 16; $off *= $REG_SZ;
-+    $off<256 ? "$off-128(%rax)" : "$off-256-128(%rbx)";
-+}
-+
-+sub ROUND_00_15 {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+
-+$code.=<<___ if ($i<15);
-+	movd		`4*$i`(@ptr[0]),$Xi
-+	movd		`4*$i`(@ptr[1]),$t1
-+	movd		`4*$i`(@ptr[2]),$t2
-+	movd		`4*$i`(@ptr[3]),$t3
-+	punpckldq	$t2,$Xi
-+	punpckldq	$t3,$t1
-+	punpckldq	$t1,$Xi
-+___
-+$code.=<<___ if ($i==15);
-+	movd		`4*$i`(@ptr[0]),$Xi
-+	 lea		`16*4`(@ptr[0]),@ptr[0]
-+	movd		`4*$i`(@ptr[1]),$t1
-+	 lea		`16*4`(@ptr[1]),@ptr[1]
-+	movd		`4*$i`(@ptr[2]),$t2
-+	 lea		`16*4`(@ptr[2]),@ptr[2]
-+	movd		`4*$i`(@ptr[3]),$t3
-+	 lea		`16*4`(@ptr[3]),@ptr[3]
-+	punpckldq	$t2,$Xi
-+	punpckldq	$t3,$t1
-+	punpckldq	$t1,$Xi
-+___
-+$code.=<<___;
-+	movdqa	$e,$sigma
-+	`"pshufb	$Xn,$Xi"		if ($i<=15 && ($i&1)==0)`
-+	movdqa	$e,$t3
-+	`"pshufb	$Xn,$Xi"		if ($i<=15 && ($i&1)==1)`
-+	psrld	\$6,$sigma
-+	movdqa	$e,$t2
-+	pslld	\$7,$t3
-+	movdqa	$Xi,`&Xi_off($i)`
-+	 paddd	$h,$Xi				# Xi+=h
-+
-+	psrld	\$11,$t2
-+	pxor	$t3,$sigma
-+	pslld	\$21-7,$t3
-+	 paddd	`32*($i%8)-128`($Tbl),$Xi	# Xi+=K[round]
-+	pxor	$t2,$sigma
-+
-+	psrld	\$25-11,$t2
-+	 movdqa	$e,$t1
-+	 `"prefetcht0	63(@ptr[0])"		if ($i==15)`
-+	pxor	$t3,$sigma
-+	 movdqa	$e,$axb				# borrow $axb
-+	pslld	\$26-21,$t3
-+	 pandn	$g,$t1
-+	 pand	$f,$axb
-+	pxor	$t2,$sigma
-+
-+	 `"prefetcht0	63(@ptr[1])"		if ($i==15)`
-+	movdqa	$a,$t2
-+	pxor	$t3,$sigma			# Sigma1(e)
-+	movdqa	$a,$t3
-+	psrld	\$2,$t2
-+	paddd	$sigma,$Xi			# Xi+=Sigma1(e)
-+	 pxor	$axb,$t1			# Ch(e,f,g)
-+	 movdqa	$b,$axb
-+	movdqa	$a,$sigma
-+	pslld	\$10,$t3
-+	 pxor	$a,$axb				# a^b, b^c in next round
-+
-+	 `"prefetcht0	63(@ptr[2])"		if ($i==15)`
-+	psrld	\$13,$sigma
-+	pxor	$t3,$t2
-+	 paddd	$t1,$Xi				# Xi+=Ch(e,f,g)
-+	pslld	\$19-10,$t3
-+	 pand	$axb,$bxc
-+	pxor	$sigma,$t2
-+
-+	 `"prefetcht0	63(@ptr[3])"		if ($i==15)`
-+	psrld	\$22-13,$sigma
-+	pxor	$t3,$t2
-+	 movdqa	$b,$h
-+	pslld	\$30-19,$t3
-+	pxor	$t2,$sigma
-+	 pxor	$bxc,$h				# h=Maj(a,b,c)=Ch(a^b,c,b)
-+	 paddd	$Xi,$d				# d+=Xi
-+	pxor	$t3,$sigma			# Sigma0(a)
-+
-+	paddd	$Xi,$h				# h+=Xi
-+	paddd	$sigma,$h			# h+=Sigma0(a)
-+___
-+$code.=<<___ if (($i%8)==7);
-+	lea	`32*8`($Tbl),$Tbl
-+___
-+	($axb,$bxc)=($bxc,$axb);
-+}
-+
-+sub ROUND_16_XX {
-+my $i=shift;
-+
-+$code.=<<___;
-+	movdqa	`&Xi_off($i+1)`,$Xn
-+	paddd	`&Xi_off($i+9)`,$Xi		# Xi+=X[i+9]
-+
-+	movdqa	$Xn,$sigma
-+	movdqa	$Xn,$t2
-+	psrld	\$3,$sigma
-+	movdqa	$Xn,$t3
-+
-+	psrld	\$7,$t2
-+	movdqa	`&Xi_off($i+14)`,$t1
-+	pslld	\$14,$t3
-+	pxor	$t2,$sigma
-+	psrld	\$18-7,$t2
-+	movdqa	$t1,$axb			# borrow $axb
-+	pxor	$t3,$sigma
-+	pslld	\$25-14,$t3
-+	pxor	$t2,$sigma
-+	psrld	\$10,$t1
-+	movdqa	$axb,$t2
-+
-+	psrld	\$17,$axb
-+	pxor	$t3,$sigma			# sigma0(X[i+1])
-+	pslld	\$13,$t2
-+	 paddd	$sigma,$Xi			# Xi+=sigma0(e)
-+	pxor	$axb,$t1
-+	psrld	\$19-17,$axb
-+	pxor	$t2,$t1
-+	pslld	\$15-13,$t2
-+	pxor	$axb,$t1
-+	pxor	$t2,$t1				# sigma0(X[i+14])
-+	paddd	$t1,$Xi				# Xi+=sigma1(X[i+14])
-+___
-+	&ROUND_00_15($i,@_);
-+	($Xi,$Xn)=($Xn,$Xi);
-+}
-+
-+$code.=<<___;
-+.text
-+
-+.extern	OPENSSL_ia32cap_P
-+
-+.globl	sha256_multi_block
-+.type	sha256_multi_block,\@function,3
-+.align	32
-+sha256_multi_block:
-+	mov	OPENSSL_ia32cap_P+4(%rip),%rcx
-+	bt	\$61,%rcx			# check SHA bit
-+	jc	_shaext_shortcut
-+___
-+$code.=<<___ if ($avx);
-+	test	\$`1<<28`,%ecx
-+	jnz	_avx_shortcut
-+___
-+$code.=<<___;
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,-0x78(%rax)
-+	movaps	%xmm11,-0x68(%rax)
-+	movaps	%xmm12,-0x58(%rax)
-+	movaps	%xmm13,-0x48(%rax)
-+	movaps	%xmm14,-0x38(%rax)
-+	movaps	%xmm15,-0x28(%rax)
-+___
-+$code.=<<___;
-+	sub	\$`$REG_SZ*18`, %rsp
-+	and	\$-256,%rsp
-+	mov	%rax,`$REG_SZ*17`(%rsp)		# original %rsp
-+.Lbody:
-+	lea	K256+128(%rip),$Tbl
-+	lea	`$REG_SZ*16`(%rsp),%rbx
-+	lea	0x80($ctx),$ctx			# size optimization
-+
-+.Loop_grande:
-+	mov	$num,`$REG_SZ*17+8`(%rsp)	# original $num
-+	xor	$num,$num
-+___
-+for($i=0;$i<4;$i++) {
-+    $code.=<<___;
-+	mov	`16*$i+0`($inp),@ptr[$i]	# input pointer
-+	mov	`16*$i+8`($inp),%ecx		# number of blocks
-+	cmp	$num,%ecx
-+	cmovg	%ecx,$num			# find maximum
-+	test	%ecx,%ecx
-+	mov	%ecx,`4*$i`(%rbx)		# initialize counters
-+	cmovle	$Tbl,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	test	$num,$num
-+	jz	.Ldone
-+
-+	movdqu	0x00-0x80($ctx),$A		# load context
-+	 lea	128(%rsp),%rax
-+	movdqu	0x20-0x80($ctx),$B
-+	movdqu	0x40-0x80($ctx),$C
-+	movdqu	0x60-0x80($ctx),$D
-+	movdqu	0x80-0x80($ctx),$E
-+	movdqu	0xa0-0x80($ctx),$F
-+	movdqu	0xc0-0x80($ctx),$G
-+	movdqu	0xe0-0x80($ctx),$H
-+	movdqu	.Lpbswap(%rip),$Xn
-+	jmp	.Loop
-+
-+.align	32
-+.Loop:
-+	movdqa	$C,$bxc
-+	pxor	$B,$bxc				# magic seed
-+___
-+for($i=0;$i<16;$i++)	{ &ROUND_00_15($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	movdqu	`&Xi_off($i)`,$Xi
-+	mov	\$3,%ecx
-+	jmp	.Loop_16_xx
-+.align	32
-+.Loop_16_xx:
-+___
-+for(;$i<32;$i++)	{ &ROUND_16_XX($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	dec	%ecx
-+	jnz	.Loop_16_xx
-+
-+	mov	\$1,%ecx
-+	lea	K256+128(%rip),$Tbl
-+
-+	movdqa	(%rbx),$sigma			# pull counters
-+	cmp	4*0(%rbx),%ecx			# examine counters
-+	pxor	$t1,$t1
-+	cmovge	$Tbl,@ptr[0]			# cancel input
-+	cmp	4*1(%rbx),%ecx
-+	movdqa	$sigma,$Xn
-+	cmovge	$Tbl,@ptr[1]
-+	cmp	4*2(%rbx),%ecx
-+	pcmpgtd	$t1,$Xn				# mask value
-+	cmovge	$Tbl,@ptr[2]
-+	cmp	4*3(%rbx),%ecx
-+	paddd	$Xn,$sigma			# counters--
-+	cmovge	$Tbl,@ptr[3]
-+
-+	movdqu	0x00-0x80($ctx),$t1
-+	pand	$Xn,$A
-+	movdqu	0x20-0x80($ctx),$t2
-+	pand	$Xn,$B
-+	movdqu	0x40-0x80($ctx),$t3
-+	pand	$Xn,$C
-+	movdqu	0x60-0x80($ctx),$Xi
-+	pand	$Xn,$D
-+	paddd	$t1,$A
-+	movdqu	0x80-0x80($ctx),$t1
-+	pand	$Xn,$E
-+	paddd	$t2,$B
-+	movdqu	0xa0-0x80($ctx),$t2
-+	pand	$Xn,$F
-+	paddd	$t3,$C
-+	movdqu	0xc0-0x80($ctx),$t3
-+	pand	$Xn,$G
-+	paddd	$Xi,$D
-+	movdqu	0xe0-0x80($ctx),$Xi
-+	pand	$Xn,$H
-+	paddd	$t1,$E
-+	paddd	$t2,$F
-+	movdqu	$A,0x00-0x80($ctx)
-+	paddd	$t3,$G
-+	movdqu	$B,0x20-0x80($ctx)
-+	paddd	$Xi,$H
-+	movdqu	$C,0x40-0x80($ctx)
-+	movdqu	$D,0x60-0x80($ctx)
-+	movdqu	$E,0x80-0x80($ctx)
-+	movdqu	$F,0xa0-0x80($ctx)
-+	movdqu	$G,0xc0-0x80($ctx)
-+	movdqu	$H,0xe0-0x80($ctx)
-+
-+	movdqa	$sigma,(%rbx)			# save counters
-+	movdqa	.Lpbswap(%rip),$Xn
-+	dec	$num
-+	jnz	.Loop
-+
-+	mov	`$REG_SZ*17+8`(%rsp),$num
-+	lea	$REG_SZ($ctx),$ctx
-+	lea	`16*$REG_SZ/4`($inp),$inp
-+	dec	$num
-+	jnz	.Loop_grande
-+
-+.Ldone:
-+	mov	`$REG_SZ*17`(%rsp),%rax		# original %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xb8(%rax),%xmm6
-+	movaps	-0xa8(%rax),%xmm7
-+	movaps	-0x98(%rax),%xmm8
-+	movaps	-0x88(%rax),%xmm9
-+	movaps	-0x78(%rax),%xmm10
-+	movaps	-0x68(%rax),%xmm11
-+	movaps	-0x58(%rax),%xmm12
-+	movaps	-0x48(%rax),%xmm13
-+	movaps	-0x38(%rax),%xmm14
-+	movaps	-0x28(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Lepilogue:
-+	ret
-+.size	sha256_multi_block,.-sha256_multi_block
-+___
-+						{{{
-+my ($Wi,$TMP0,$TMP1,$TMPx,$ABEF0,$CDGH0,$ABEF1,$CDGH1)=map("%xmm$_",(0..3,12..15));
-+my @MSG0=map("%xmm$_",(4..7));
-+my @MSG1=map("%xmm$_",(8..11));
-+
-+$code.=<<___;
-+.type	sha256_multi_block_shaext,\@function,3
-+.align	32
-+sha256_multi_block_shaext:
-+_shaext_shortcut:
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,-0x78(%rax)
-+	movaps	%xmm11,-0x68(%rax)
-+	movaps	%xmm12,-0x58(%rax)
-+	movaps	%xmm13,-0x48(%rax)
-+	movaps	%xmm14,-0x38(%rax)
-+	movaps	%xmm15,-0x28(%rax)
-+___
-+$code.=<<___;
-+	sub	\$`$REG_SZ*18`,%rsp
-+	shl	\$1,$num			# we process pair at a time
-+	and	\$-256,%rsp
-+	lea	0x80($ctx),$ctx			# size optimization
-+	mov	%rax,`$REG_SZ*17`(%rsp)		# original %rsp
-+.Lbody_shaext:
-+	lea	`$REG_SZ*16`(%rsp),%rbx
-+	lea	K256_shaext+0x80(%rip),$Tbl
-+
-+.Loop_grande_shaext:
-+	mov	$num,`$REG_SZ*17+8`(%rsp)	# original $num
-+	xor	$num,$num
-+___
-+for($i=0;$i<2;$i++) {
-+    $code.=<<___;
-+	mov	`16*$i+0`($inp),@ptr[$i]	# input pointer
-+	mov	`16*$i+8`($inp),%ecx		# number of blocks
-+	cmp	$num,%ecx
-+	cmovg	%ecx,$num			# find maximum
-+	test	%ecx,%ecx
-+	mov	%ecx,`4*$i`(%rbx)		# initialize counters
-+	cmovle	%rsp,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	test	$num,$num
-+	jz	.Ldone_shaext
-+
-+	movq		0x00-0x80($ctx),$ABEF0		# A1.A0
-+	movq		0x20-0x80($ctx),@MSG0[0]	# B1.B0
-+	movq		0x40-0x80($ctx),$CDGH0		# C1.C0
-+	movq		0x60-0x80($ctx),@MSG0[1]	# D1.D0
-+	movq		0x80-0x80($ctx),@MSG1[0]	# E1.E0
-+	movq		0xa0-0x80($ctx),@MSG1[1]	# F1.F0
-+	movq		0xc0-0x80($ctx),@MSG1[2]	# G1.G0
-+	movq		0xe0-0x80($ctx),@MSG1[3]	# H1.H0
-+
-+	punpckldq	@MSG0[0],$ABEF0			# B1.A1.B0.A0
-+	punpckldq	@MSG0[1],$CDGH0			# D1.C1.D0.C0
-+	punpckldq	@MSG1[1],@MSG1[0]		# F1.E1.F0.E0
-+	punpckldq	@MSG1[3],@MSG1[2]		# H1.G1.H0.G0
-+	movdqa		K256_shaext-0x10(%rip),$TMPx	# byte swap
-+
-+	movdqa		$ABEF0,$ABEF1
-+	movdqa		$CDGH0,$CDGH1
-+	punpcklqdq	@MSG1[0],$ABEF0			# F0.E0.B0.A0
-+	punpcklqdq	@MSG1[2],$CDGH0			# H0.G0.D0.C0
-+	punpckhqdq	@MSG1[0],$ABEF1			# F1.E1.B1.A1
-+	punpckhqdq	@MSG1[2],$CDGH1			# H1.G1.D1.C1
-+
-+	pshufd		\$0b00011011,$ABEF0,$ABEF0
-+	pshufd		\$0b00011011,$CDGH0,$CDGH0
-+	pshufd		\$0b00011011,$ABEF1,$ABEF1
-+	pshufd		\$0b00011011,$CDGH1,$CDGH1
-+	jmp		.Loop_shaext
-+
-+.align	32
-+.Loop_shaext:
-+	movdqu		0x00(@ptr[0]),@MSG0[0]
-+	 movdqu		0x00(@ptr[1]),@MSG1[0]
-+	movdqu		0x10(@ptr[0]),@MSG0[1]
-+	 movdqu		0x10(@ptr[1]),@MSG1[1]
-+	movdqu		0x20(@ptr[0]),@MSG0[2]
-+	pshufb		$TMPx,@MSG0[0]
-+	 movdqu		0x20(@ptr[1]),@MSG1[2]
-+	 pshufb		$TMPx,@MSG1[0]
-+	movdqu		0x30(@ptr[0]),@MSG0[3]
-+	lea		0x40(@ptr[0]),@ptr[0]
-+	 movdqu		0x30(@ptr[1]),@MSG1[3]
-+	 lea		0x40(@ptr[1]),@ptr[1]
-+
-+	movdqa		0*16-0x80($Tbl),$Wi
-+	pshufb		$TMPx,@MSG0[1]
-+	paddd		@MSG0[0],$Wi
-+	pxor		$ABEF0,@MSG0[0]		# black magic
-+	movdqa		$Wi,$TMP0
-+	 movdqa		0*16-0x80($Tbl),$TMP1
-+	 pshufb		$TMPx,@MSG1[1]
-+	 paddd		@MSG1[0],$TMP1
-+	movdqa		$CDGH0,0x50(%rsp)	# offload
-+	sha256rnds2	$ABEF0,$CDGH0		# 0-3
-+	 pxor		$ABEF1,@MSG1[0]		# black magic
-+	 movdqa		$TMP1,$Wi
-+	 movdqa		$CDGH1,0x70(%rsp)
-+	 sha256rnds2	$ABEF1,$CDGH1		# 0-3
-+	pshufd		\$0x0e,$TMP0,$Wi
-+	pxor		$ABEF0,@MSG0[0]		# black magic
-+	movdqa		$ABEF0,0x40(%rsp)	# offload
-+	sha256rnds2	$CDGH0,$ABEF0
-+	 pshufd		\$0x0e,$TMP1,$Wi
-+	 pxor		$ABEF1,@MSG1[0]		# black magic
-+	 movdqa		$ABEF1,0x60(%rsp)
-+	movdqa		1*16-0x80($Tbl),$TMP0
-+	paddd		@MSG0[1],$TMP0
-+	pshufb		$TMPx,@MSG0[2]
-+	 sha256rnds2	$CDGH1,$ABEF1
-+
-+	movdqa		$TMP0,$Wi
-+	 movdqa		1*16-0x80($Tbl),$TMP1
-+	 paddd		@MSG1[1],$TMP1
-+	sha256rnds2	$ABEF0,$CDGH0		# 4-7
-+	 movdqa		$TMP1,$Wi
-+	prefetcht0	127(@ptr[0])
-+	pshufb		$TMPx,@MSG0[3]
-+	 pshufb		$TMPx,@MSG1[2]
-+	 prefetcht0	127(@ptr[1])
-+	 sha256rnds2	$ABEF1,$CDGH1		# 4-7
-+	pshufd		\$0x0e,$TMP0,$Wi
-+	 pshufb		$TMPx,@MSG1[3]
-+	sha256msg1	@MSG0[1],@MSG0[0]
-+	sha256rnds2	$CDGH0,$ABEF0
-+	 pshufd		\$0x0e,$TMP1,$Wi
-+	movdqa		2*16-0x80($Tbl),$TMP0
-+	paddd		@MSG0[2],$TMP0
-+	 sha256rnds2	$CDGH1,$ABEF1
-+
-+	movdqa		$TMP0,$Wi
-+	 movdqa		2*16-0x80($Tbl),$TMP1
-+	 paddd		@MSG1[2],$TMP1
-+	sha256rnds2	$ABEF0,$CDGH0		# 8-11
-+	 sha256msg1	@MSG1[1],@MSG1[0]
-+	 movdqa		$TMP1,$Wi
-+	movdqa		@MSG0[3],$TMPx
-+	 sha256rnds2	$ABEF1,$CDGH1		# 8-11
-+	pshufd		\$0x0e,$TMP0,$Wi
-+	palignr		\$4,@MSG0[2],$TMPx
-+	paddd		$TMPx,@MSG0[0]
-+	 movdqa		@MSG1[3],$TMPx
-+	 palignr	\$4,@MSG1[2],$TMPx
-+	sha256msg1	@MSG0[2],@MSG0[1]
-+	sha256rnds2	$CDGH0,$ABEF0
-+	 pshufd		\$0x0e,$TMP1,$Wi
-+	movdqa		3*16-0x80($Tbl),$TMP0
-+	paddd		@MSG0[3],$TMP0
-+	 sha256rnds2	$CDGH1,$ABEF1
-+	 sha256msg1	@MSG1[2],@MSG1[1]
-+
-+	movdqa		$TMP0,$Wi
-+	 movdqa		3*16-0x80($Tbl),$TMP1
-+	 paddd		$TMPx,@MSG1[0]
-+	 paddd		@MSG1[3],$TMP1
-+	sha256msg2	@MSG0[3],@MSG0[0]
-+	sha256rnds2	$ABEF0,$CDGH0		# 12-15
-+	 movdqa		$TMP1,$Wi
-+	movdqa		@MSG0[0],$TMPx
-+	palignr		\$4,@MSG0[3],$TMPx
-+	 sha256rnds2	$ABEF1,$CDGH1		# 12-15
-+	 sha256msg2	@MSG1[3],@MSG1[0]
-+	pshufd		\$0x0e,$TMP0,$Wi
-+	paddd		$TMPx,@MSG0[1]
-+	 movdqa		@MSG1[0],$TMPx
-+	 palignr	\$4,@MSG1[3],$TMPx
-+	sha256msg1	@MSG0[3],@MSG0[2]
-+	sha256rnds2	$CDGH0,$ABEF0
-+	 pshufd		\$0x0e,$TMP1,$Wi
-+	movdqa		4*16-0x80($Tbl),$TMP0
-+	paddd		@MSG0[0],$TMP0
-+	 sha256rnds2	$CDGH1,$ABEF1
-+	 sha256msg1	@MSG1[3],@MSG1[2]
-+___
-+for($i=4;$i<16-3;$i++) {
-+$code.=<<___;
-+	movdqa		$TMP0,$Wi
-+	 movdqa		$i*16-0x80($Tbl),$TMP1
-+	 paddd		$TMPx,@MSG1[1]
-+	 paddd		@MSG1[0],$TMP1
-+	sha256msg2	@MSG0[0],@MSG0[1]
-+	sha256rnds2	$ABEF0,$CDGH0		# 16-19...
-+	 movdqa		$TMP1,$Wi
-+	movdqa		@MSG0[1],$TMPx
-+	palignr		\$4,@MSG0[0],$TMPx
-+	 sha256rnds2	$ABEF1,$CDGH1		# 16-19...
-+	 sha256msg2	@MSG1[0],@MSG1[1]
-+	pshufd		\$0x0e,$TMP0,$Wi
-+	paddd		$TMPx,@MSG0[2]
-+	 movdqa		@MSG1[1],$TMPx
-+	 palignr	\$4,@MSG1[0],$TMPx
-+	sha256msg1	@MSG0[0],@MSG0[3]
-+	sha256rnds2	$CDGH0,$ABEF0
-+	 pshufd		\$0x0e,$TMP1,$Wi
-+	movdqa		`($i+1)*16`-0x80($Tbl),$TMP0
-+	paddd		@MSG0[1],$TMP0
-+	 sha256rnds2	$CDGH1,$ABEF1
-+	 sha256msg1	@MSG1[0],@MSG1[3]
-+___
-+	push(@MSG0,shift(@MSG0));	push(@MSG1,shift(@MSG1));
-+}
-+$code.=<<___;
-+	movdqa		$TMP0,$Wi
-+	 movdqa		13*16-0x80($Tbl),$TMP1
-+	 paddd		$TMPx,@MSG1[1]
-+	 paddd		@MSG1[0],$TMP1
-+	sha256msg2	@MSG0[0],@MSG0[1]
-+	sha256rnds2	$ABEF0,$CDGH0		# 52-55
-+	 movdqa		$TMP1,$Wi
-+	movdqa		@MSG0[1],$TMPx
-+	palignr		\$4,@MSG0[0],$TMPx
-+	 sha256rnds2	$ABEF1,$CDGH1		# 52-55
-+	 sha256msg2	@MSG1[0],@MSG1[1]
-+	pshufd		\$0x0e,$TMP0,$Wi
-+	paddd		$TMPx,@MSG0[2]
-+	 movdqa		@MSG1[1],$TMPx
-+	 palignr	\$4,@MSG1[0],$TMPx
-+	nop
-+	sha256rnds2	$CDGH0,$ABEF0
-+	 pshufd		\$0x0e,$TMP1,$Wi
-+	movdqa		14*16-0x80($Tbl),$TMP0
-+	paddd		@MSG0[1],$TMP0
-+	 sha256rnds2	$CDGH1,$ABEF1
-+
-+	movdqa		$TMP0,$Wi
-+	 movdqa		14*16-0x80($Tbl),$TMP1
-+	 paddd		$TMPx,@MSG1[2]
-+	 paddd		@MSG1[1],$TMP1
-+	sha256msg2	@MSG0[1],@MSG0[2]
-+	nop
-+	sha256rnds2	$ABEF0,$CDGH0		# 56-59
-+	 movdqa		$TMP1,$Wi
-+	  mov		\$1,%ecx
-+	  pxor		@MSG0[1],@MSG0[1]	# zero
-+	 sha256rnds2	$ABEF1,$CDGH1		# 56-59
-+	 sha256msg2	@MSG1[1],@MSG1[2]
-+	pshufd		\$0x0e,$TMP0,$Wi
-+	movdqa		15*16-0x80($Tbl),$TMP0
-+	paddd		@MSG0[2],$TMP0
-+	  movq		(%rbx),@MSG0[2]		# pull counters
-+	  nop
-+	sha256rnds2	$CDGH0,$ABEF0
-+	 pshufd		\$0x0e,$TMP1,$Wi
-+	 movdqa		15*16-0x80($Tbl),$TMP1
-+	 paddd		@MSG1[2],$TMP1
-+	 sha256rnds2	$CDGH1,$ABEF1
-+
-+	movdqa		$TMP0,$Wi
-+	  cmp		4*0(%rbx),%ecx		# examine counters
-+	  cmovge	%rsp,@ptr[0]		# cancel input
-+	  cmp		4*1(%rbx),%ecx
-+	  cmovge	%rsp,@ptr[1]
-+	  pshufd	\$0x00,@MSG0[2],@MSG1[0]
-+	sha256rnds2	$ABEF0,$CDGH0		# 60-63
-+	 movdqa		$TMP1,$Wi
-+	  pshufd	\$0x55,@MSG0[2],@MSG1[1]
-+	  movdqa	@MSG0[2],@MSG1[2]
-+	 sha256rnds2	$ABEF1,$CDGH1		# 60-63
-+	pshufd		\$0x0e,$TMP0,$Wi
-+	  pcmpgtd	@MSG0[1],@MSG1[0]
-+	  pcmpgtd	@MSG0[1],@MSG1[1]
-+	sha256rnds2	$CDGH0,$ABEF0
-+	 pshufd		\$0x0e,$TMP1,$Wi
-+	  pcmpgtd	@MSG0[1],@MSG1[2]	# counter mask
-+	  movdqa	K256_shaext-0x10(%rip),$TMPx
-+	 sha256rnds2	$CDGH1,$ABEF1
-+
-+	pand		@MSG1[0],$CDGH0
-+	 pand		@MSG1[1],$CDGH1
-+	pand		@MSG1[0],$ABEF0
-+	 pand		@MSG1[1],$ABEF1
-+	paddd		@MSG0[2],@MSG1[2]	# counters--
-+
-+	paddd		0x50(%rsp),$CDGH0
-+	 paddd		0x70(%rsp),$CDGH1
-+	paddd		0x40(%rsp),$ABEF0
-+	 paddd		0x60(%rsp),$ABEF1
-+
-+	movq		@MSG1[2],(%rbx)		# save counters
-+	dec		$num
-+	jnz		.Loop_shaext
-+
-+	mov		`$REG_SZ*17+8`(%rsp),$num
-+
-+	pshufd		\$0b00011011,$ABEF0,$ABEF0
-+	pshufd		\$0b00011011,$CDGH0,$CDGH0
-+	pshufd		\$0b00011011,$ABEF1,$ABEF1
-+	pshufd		\$0b00011011,$CDGH1,$CDGH1
-+
-+	movdqa		$ABEF0,@MSG0[0]
-+	movdqa		$CDGH0,@MSG0[1]
-+	punpckldq	$ABEF1,$ABEF0			# B1.B0.A1.A0
-+	punpckhdq	$ABEF1,@MSG0[0]			# F1.F0.E1.E0
-+	punpckldq	$CDGH1,$CDGH0			# D1.D0.C1.C0
-+	punpckhdq	$CDGH1,@MSG0[1]			# H1.H0.G1.G0
-+
-+	movq		$ABEF0,0x00-0x80($ctx)		# A1.A0
-+	psrldq		\$8,$ABEF0
-+	movq		@MSG0[0],0x80-0x80($ctx)	# E1.E0
-+	psrldq		\$8,@MSG0[0]
-+	movq		$ABEF0,0x20-0x80($ctx)		# B1.B0
-+	movq		@MSG0[0],0xa0-0x80($ctx)	# F1.F0
-+
-+	movq		$CDGH0,0x40-0x80($ctx)		# C1.C0
-+	psrldq		\$8,$CDGH0
-+	movq		@MSG0[1],0xc0-0x80($ctx)	# G1.G0
-+	psrldq		\$8,@MSG0[1]
-+	movq		$CDGH0,0x60-0x80($ctx)		# D1.D0
-+	movq		@MSG0[1],0xe0-0x80($ctx)	# H1.H0
-+
-+	lea	`$REG_SZ/2`($ctx),$ctx
-+	lea	`16*2`($inp),$inp
-+	dec	$num
-+	jnz	.Loop_grande_shaext
-+
-+.Ldone_shaext:
-+	#mov	`$REG_SZ*17`(%rsp),%rax		# original %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xb8(%rax),%xmm6
-+	movaps	-0xa8(%rax),%xmm7
-+	movaps	-0x98(%rax),%xmm8
-+	movaps	-0x88(%rax),%xmm9
-+	movaps	-0x78(%rax),%xmm10
-+	movaps	-0x68(%rax),%xmm11
-+	movaps	-0x58(%rax),%xmm12
-+	movaps	-0x48(%rax),%xmm13
-+	movaps	-0x38(%rax),%xmm14
-+	movaps	-0x28(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Lepilogue_shaext:
-+	ret
-+.size	sha256_multi_block_shaext,.-sha256_multi_block_shaext
-+___
-+						}}}
-+						if ($avx) {{{
-+sub ROUND_00_15_avx {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+
-+$code.=<<___ if ($i<15 && $REG_SZ==16);
-+	vmovd		`4*$i`(@ptr[0]),$Xi
-+	vmovd		`4*$i`(@ptr[1]),$t1
-+	vpinsrd		\$1,`4*$i`(@ptr[2]),$Xi,$Xi
-+	vpinsrd		\$1,`4*$i`(@ptr[3]),$t1,$t1
-+	vpunpckldq	$t1,$Xi,$Xi
-+	vpshufb		$Xn,$Xi,$Xi
-+___
-+$code.=<<___ if ($i==15 && $REG_SZ==16);
-+	vmovd		`4*$i`(@ptr[0]),$Xi
-+	 lea		`16*4`(@ptr[0]),@ptr[0]
-+	vmovd		`4*$i`(@ptr[1]),$t1
-+	 lea		`16*4`(@ptr[1]),@ptr[1]
-+	vpinsrd		\$1,`4*$i`(@ptr[2]),$Xi,$Xi
-+	 lea		`16*4`(@ptr[2]),@ptr[2]
-+	vpinsrd		\$1,`4*$i`(@ptr[3]),$t1,$t1
-+	 lea		`16*4`(@ptr[3]),@ptr[3]
-+	vpunpckldq	$t1,$Xi,$Xi
-+	vpshufb		$Xn,$Xi,$Xi
-+___
-+$code.=<<___ if ($i<15 && $REG_SZ==32);
-+	vmovd		`4*$i`(@ptr[0]),$Xi
-+	vmovd		`4*$i`(@ptr[4]),$t1
-+	vmovd		`4*$i`(@ptr[1]),$t2
-+	vmovd		`4*$i`(@ptr[5]),$t3
-+	vpinsrd		\$1,`4*$i`(@ptr[2]),$Xi,$Xi
-+	vpinsrd		\$1,`4*$i`(@ptr[6]),$t1,$t1
-+	vpinsrd		\$1,`4*$i`(@ptr[3]),$t2,$t2
-+	vpunpckldq	$t2,$Xi,$Xi
-+	vpinsrd		\$1,`4*$i`(@ptr[7]),$t3,$t3
-+	vpunpckldq	$t3,$t1,$t1
-+	vinserti128	$t1,$Xi,$Xi
-+	vpshufb		$Xn,$Xi,$Xi
-+___
-+$code.=<<___ if ($i==15 && $REG_SZ==32);
-+	vmovd		`4*$i`(@ptr[0]),$Xi
-+	 lea		`16*4`(@ptr[0]),@ptr[0]
-+	vmovd		`4*$i`(@ptr[4]),$t1
-+	 lea		`16*4`(@ptr[4]),@ptr[4]
-+	vmovd		`4*$i`(@ptr[1]),$t2
-+	 lea		`16*4`(@ptr[1]),@ptr[1]
-+	vmovd		`4*$i`(@ptr[5]),$t3
-+	 lea		`16*4`(@ptr[5]),@ptr[5]
-+	vpinsrd		\$1,`4*$i`(@ptr[2]),$Xi,$Xi
-+	 lea		`16*4`(@ptr[2]),@ptr[2]
-+	vpinsrd		\$1,`4*$i`(@ptr[6]),$t1,$t1
-+	 lea		`16*4`(@ptr[6]),@ptr[6]
-+	vpinsrd		\$1,`4*$i`(@ptr[3]),$t2,$t2
-+	 lea		`16*4`(@ptr[3]),@ptr[3]
-+	vpunpckldq	$t2,$Xi,$Xi
-+	vpinsrd		\$1,`4*$i`(@ptr[7]),$t3,$t3
-+	 lea		`16*4`(@ptr[7]),@ptr[7]
-+	vpunpckldq	$t3,$t1,$t1
-+	vinserti128	$t1,$Xi,$Xi
-+	vpshufb		$Xn,$Xi,$Xi
-+___
-+$code.=<<___;
-+	vpsrld	\$6,$e,$sigma
-+	vpslld	\$26,$e,$t3
-+	vmovdqu	$Xi,`&Xi_off($i)`
-+	 vpaddd	$h,$Xi,$Xi			# Xi+=h
-+
-+	vpsrld	\$11,$e,$t2
-+	vpxor	$t3,$sigma,$sigma
-+	vpslld	\$21,$e,$t3
-+	 vpaddd	`32*($i%8)-128`($Tbl),$Xi,$Xi	# Xi+=K[round]
-+	vpxor	$t2,$sigma,$sigma
-+
-+	vpsrld	\$25,$e,$t2
-+	vpxor	$t3,$sigma,$sigma
-+	 `"prefetcht0	63(@ptr[0])"		if ($i==15)`
-+	vpslld	\$7,$e,$t3
-+	 vpandn	$g,$e,$t1
-+	 vpand	$f,$e,$axb			# borrow $axb
-+	 `"prefetcht0	63(@ptr[1])"		if ($i==15)`
-+	vpxor	$t2,$sigma,$sigma
-+
-+	vpsrld	\$2,$a,$h			# borrow $h
-+	vpxor	$t3,$sigma,$sigma		# Sigma1(e)
-+	 `"prefetcht0	63(@ptr[2])"		if ($i==15)`
-+	vpslld	\$30,$a,$t2
-+	 vpxor	$axb,$t1,$t1			# Ch(e,f,g)
-+	 vpxor	$a,$b,$axb			# a^b, b^c in next round
-+	 `"prefetcht0	63(@ptr[3])"		if ($i==15)`
-+	vpxor	$t2,$h,$h
-+	vpaddd	$sigma,$Xi,$Xi			# Xi+=Sigma1(e)
-+
-+	vpsrld	\$13,$a,$t2
-+	 `"prefetcht0	63(@ptr[4])"		if ($i==15 && $REG_SZ==32)`
-+	vpslld	\$19,$a,$t3
-+	 vpaddd	$t1,$Xi,$Xi			# Xi+=Ch(e,f,g)
-+	 vpand	$axb,$bxc,$bxc
-+	 `"prefetcht0	63(@ptr[5])"		if ($i==15 && $REG_SZ==32)`
-+	vpxor	$t2,$h,$sigma
-+
-+	vpsrld	\$22,$a,$t2
-+	vpxor	$t3,$sigma,$sigma
-+	 `"prefetcht0	63(@ptr[6])"		if ($i==15 && $REG_SZ==32)`
-+	vpslld	\$10,$a,$t3
-+	 vpxor	$bxc,$b,$h			# h=Maj(a,b,c)=Ch(a^b,c,b)
-+	 vpaddd	$Xi,$d,$d			# d+=Xi
-+	 `"prefetcht0	63(@ptr[7])"		if ($i==15 && $REG_SZ==32)`
-+	vpxor	$t2,$sigma,$sigma
-+	vpxor	$t3,$sigma,$sigma		# Sigma0(a)
-+
-+	vpaddd	$Xi,$h,$h			# h+=Xi
-+	vpaddd	$sigma,$h,$h			# h+=Sigma0(a)
-+___
-+$code.=<<___ if (($i%8)==7);
-+	add	\$`32*8`,$Tbl
-+___
-+	($axb,$bxc)=($bxc,$axb);
-+}
-+
-+sub ROUND_16_XX_avx {
-+my $i=shift;
-+
-+$code.=<<___;
-+	vmovdqu	`&Xi_off($i+1)`,$Xn
-+	vpaddd	`&Xi_off($i+9)`,$Xi,$Xi		# Xi+=X[i+9]
-+
-+	vpsrld	\$3,$Xn,$sigma
-+	vpsrld	\$7,$Xn,$t2
-+	vpslld	\$25,$Xn,$t3
-+	vpxor	$t2,$sigma,$sigma
-+	vpsrld	\$18,$Xn,$t2
-+	vpxor	$t3,$sigma,$sigma
-+	vpslld	\$14,$Xn,$t3
-+	vmovdqu	`&Xi_off($i+14)`,$t1
-+	vpsrld	\$10,$t1,$axb			# borrow $axb
-+
-+	vpxor	$t2,$sigma,$sigma
-+	vpsrld	\$17,$t1,$t2
-+	vpxor	$t3,$sigma,$sigma		# sigma0(X[i+1])
-+	vpslld	\$15,$t1,$t3
-+	 vpaddd	$sigma,$Xi,$Xi			# Xi+=sigma0(e)
-+	vpxor	$t2,$axb,$sigma
-+	vpsrld	\$19,$t1,$t2
-+	vpxor	$t3,$sigma,$sigma
-+	vpslld	\$13,$t1,$t3
-+	vpxor	$t2,$sigma,$sigma
-+	vpxor	$t3,$sigma,$sigma		# sigma0(X[i+14])
-+	vpaddd	$sigma,$Xi,$Xi			# Xi+=sigma1(X[i+14])
-+___
-+	&ROUND_00_15_avx($i,@_);
-+	($Xi,$Xn)=($Xn,$Xi);
-+}
-+
-+$code.=<<___;
-+.type	sha256_multi_block_avx,\@function,3
-+.align	32
-+sha256_multi_block_avx:
-+_avx_shortcut:
-+___
-+$code.=<<___ if ($avx>1);
-+	shr	\$32,%rcx
-+	cmp	\$2,$num
-+	jb	.Lavx
-+	test	\$`1<<5`,%ecx
-+	jnz	_avx2_shortcut
-+	jmp	.Lavx
-+.align	32
-+.Lavx:
-+___
-+$code.=<<___;
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,-0x78(%rax)
-+	movaps	%xmm11,-0x68(%rax)
-+	movaps	%xmm12,-0x58(%rax)
-+	movaps	%xmm13,-0x48(%rax)
-+	movaps	%xmm14,-0x38(%rax)
-+	movaps	%xmm15,-0x28(%rax)
-+___
-+$code.=<<___;
-+	sub	\$`$REG_SZ*18`, %rsp
-+	and	\$-256,%rsp
-+	mov	%rax,`$REG_SZ*17`(%rsp)		# original %rsp
-+.Lbody_avx:
-+	lea	K256+128(%rip),$Tbl
-+	lea	`$REG_SZ*16`(%rsp),%rbx
-+	lea	0x80($ctx),$ctx			# size optimization
-+
-+.Loop_grande_avx:
-+	mov	$num,`$REG_SZ*17+8`(%rsp)	# original $num
-+	xor	$num,$num
-+___
-+for($i=0;$i<4;$i++) {
-+    $code.=<<___;
-+	mov	`16*$i+0`($inp),@ptr[$i]	# input pointer
-+	mov	`16*$i+8`($inp),%ecx		# number of blocks
-+	cmp	$num,%ecx
-+	cmovg	%ecx,$num			# find maximum
-+	test	%ecx,%ecx
-+	mov	%ecx,`4*$i`(%rbx)		# initialize counters
-+	cmovle	$Tbl,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	test	$num,$num
-+	jz	.Ldone_avx
-+
-+	vmovdqu	0x00-0x80($ctx),$A		# load context
-+	 lea	128(%rsp),%rax
-+	vmovdqu	0x20-0x80($ctx),$B
-+	vmovdqu	0x40-0x80($ctx),$C
-+	vmovdqu	0x60-0x80($ctx),$D
-+	vmovdqu	0x80-0x80($ctx),$E
-+	vmovdqu	0xa0-0x80($ctx),$F
-+	vmovdqu	0xc0-0x80($ctx),$G
-+	vmovdqu	0xe0-0x80($ctx),$H
-+	vmovdqu	.Lpbswap(%rip),$Xn
-+	jmp	.Loop_avx
-+
-+.align	32
-+.Loop_avx:
-+	vpxor	$B,$C,$bxc			# magic seed
-+___
-+for($i=0;$i<16;$i++)	{ &ROUND_00_15_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	vmovdqu	`&Xi_off($i)`,$Xi
-+	mov	\$3,%ecx
-+	jmp	.Loop_16_xx_avx
-+.align	32
-+.Loop_16_xx_avx:
-+___
-+for(;$i<32;$i++)	{ &ROUND_16_XX_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	dec	%ecx
-+	jnz	.Loop_16_xx_avx
-+
-+	mov	\$1,%ecx
-+	lea	K256+128(%rip),$Tbl
-+___
-+for($i=0;$i<4;$i++) {
-+    $code.=<<___;
-+	cmp	`4*$i`(%rbx),%ecx		# examine counters
-+	cmovge	$Tbl,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	vmovdqa	(%rbx),$sigma			# pull counters
-+	vpxor	$t1,$t1,$t1
-+	vmovdqa	$sigma,$Xn
-+	vpcmpgtd $t1,$Xn,$Xn			# mask value
-+	vpaddd	$Xn,$sigma,$sigma		# counters--
-+
-+	vmovdqu	0x00-0x80($ctx),$t1
-+	vpand	$Xn,$A,$A
-+	vmovdqu	0x20-0x80($ctx),$t2
-+	vpand	$Xn,$B,$B
-+	vmovdqu	0x40-0x80($ctx),$t3
-+	vpand	$Xn,$C,$C
-+	vmovdqu	0x60-0x80($ctx),$Xi
-+	vpand	$Xn,$D,$D
-+	vpaddd	$t1,$A,$A
-+	vmovdqu	0x80-0x80($ctx),$t1
-+	vpand	$Xn,$E,$E
-+	vpaddd	$t2,$B,$B
-+	vmovdqu	0xa0-0x80($ctx),$t2
-+	vpand	$Xn,$F,$F
-+	vpaddd	$t3,$C,$C
-+	vmovdqu	0xc0-0x80($ctx),$t3
-+	vpand	$Xn,$G,$G
-+	vpaddd	$Xi,$D,$D
-+	vmovdqu	0xe0-0x80($ctx),$Xi
-+	vpand	$Xn,$H,$H
-+	vpaddd	$t1,$E,$E
-+	vpaddd	$t2,$F,$F
-+	vmovdqu	$A,0x00-0x80($ctx)
-+	vpaddd	$t3,$G,$G
-+	vmovdqu	$B,0x20-0x80($ctx)
-+	vpaddd	$Xi,$H,$H
-+	vmovdqu	$C,0x40-0x80($ctx)
-+	vmovdqu	$D,0x60-0x80($ctx)
-+	vmovdqu	$E,0x80-0x80($ctx)
-+	vmovdqu	$F,0xa0-0x80($ctx)
-+	vmovdqu	$G,0xc0-0x80($ctx)
-+	vmovdqu	$H,0xe0-0x80($ctx)
-+
-+	vmovdqu	$sigma,(%rbx)			# save counters
-+	vmovdqu	.Lpbswap(%rip),$Xn
-+	dec	$num
-+	jnz	.Loop_avx
-+
-+	mov	`$REG_SZ*17+8`(%rsp),$num
-+	lea	$REG_SZ($ctx),$ctx
-+	lea	`16*$REG_SZ/4`($inp),$inp
-+	dec	$num
-+	jnz	.Loop_grande_avx
-+
-+.Ldone_avx:
-+	mov	`$REG_SZ*17`(%rsp),%rax		# original %rsp
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xb8(%rax),%xmm6
-+	movaps	-0xa8(%rax),%xmm7
-+	movaps	-0x98(%rax),%xmm8
-+	movaps	-0x88(%rax),%xmm9
-+	movaps	-0x78(%rax),%xmm10
-+	movaps	-0x68(%rax),%xmm11
-+	movaps	-0x58(%rax),%xmm12
-+	movaps	-0x48(%rax),%xmm13
-+	movaps	-0x38(%rax),%xmm14
-+	movaps	-0x28(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Lepilogue_avx:
-+	ret
-+.size	sha256_multi_block_avx,.-sha256_multi_block_avx
-+___
-+						if ($avx>1) {
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+
-+$REG_SZ=32;
-+@ptr=map("%r$_",(12..15,8..11));
-+
-+@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("%ymm$_",(8..15));
-+($t1,$t2,$t3,$axb,$bxc,$Xi,$Xn,$sigma)=map("%ymm$_",(0..7));
-+
-+$code.=<<___;
-+.type	sha256_multi_block_avx2,\@function,3
-+.align	32
-+sha256_multi_block_avx2:
-+_avx2_shortcut:
-+	mov	%rsp,%rax
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+___
-+$code.=<<___ if ($win64);
-+	lea	-0xa8(%rsp),%rsp
-+	movaps	%xmm6,(%rsp)
-+	movaps	%xmm7,0x10(%rsp)
-+	movaps	%xmm8,0x20(%rsp)
-+	movaps	%xmm9,0x30(%rsp)
-+	movaps	%xmm10,0x40(%rsp)
-+	movaps	%xmm11,0x50(%rsp)
-+	movaps	%xmm12,-0x78(%rax)
-+	movaps	%xmm13,-0x68(%rax)
-+	movaps	%xmm14,-0x58(%rax)
-+	movaps	%xmm15,-0x48(%rax)
-+___
-+$code.=<<___;
-+	sub	\$`$REG_SZ*18`, %rsp
-+	and	\$-256,%rsp
-+	mov	%rax,`$REG_SZ*17`(%rsp)		# original %rsp
-+.Lbody_avx2:
-+	lea	K256+128(%rip),$Tbl
-+	lea	0x80($ctx),$ctx			# size optimization
-+
-+.Loop_grande_avx2:
-+	mov	$num,`$REG_SZ*17+8`(%rsp)	# original $num
-+	xor	$num,$num
-+	lea	`$REG_SZ*16`(%rsp),%rbx
-+___
-+for($i=0;$i<8;$i++) {
-+    $code.=<<___;
-+	mov	`16*$i+0`($inp),@ptr[$i]	# input pointer
-+	mov	`16*$i+8`($inp),%ecx		# number of blocks
-+	cmp	$num,%ecx
-+	cmovg	%ecx,$num			# find maximum
-+	test	%ecx,%ecx
-+	mov	%ecx,`4*$i`(%rbx)		# initialize counters
-+	cmovle	$Tbl,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	vmovdqu	0x00-0x80($ctx),$A		# load context
-+	 lea	128(%rsp),%rax
-+	vmovdqu	0x20-0x80($ctx),$B
-+	 lea	256+128(%rsp),%rbx
-+	vmovdqu	0x40-0x80($ctx),$C
-+	vmovdqu	0x60-0x80($ctx),$D
-+	vmovdqu	0x80-0x80($ctx),$E
-+	vmovdqu	0xa0-0x80($ctx),$F
-+	vmovdqu	0xc0-0x80($ctx),$G
-+	vmovdqu	0xe0-0x80($ctx),$H
-+	vmovdqu	.Lpbswap(%rip),$Xn
-+	jmp	.Loop_avx2
-+
-+.align	32
-+.Loop_avx2:
-+	vpxor	$B,$C,$bxc			# magic seed
-+___
-+for($i=0;$i<16;$i++)	{ &ROUND_00_15_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	vmovdqu	`&Xi_off($i)`,$Xi
-+	mov	\$3,%ecx
-+	jmp	.Loop_16_xx_avx2
-+.align	32
-+.Loop_16_xx_avx2:
-+___
-+for(;$i<32;$i++)	{ &ROUND_16_XX_avx($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	dec	%ecx
-+	jnz	.Loop_16_xx_avx2
-+
-+	mov	\$1,%ecx
-+	lea	`$REG_SZ*16`(%rsp),%rbx
-+	lea	K256+128(%rip),$Tbl
-+___
-+for($i=0;$i<8;$i++) {
-+    $code.=<<___;
-+	cmp	`4*$i`(%rbx),%ecx		# examine counters
-+	cmovge	$Tbl,@ptr[$i]			# cancel input
-+___
-+}
-+$code.=<<___;
-+	vmovdqa	(%rbx),$sigma			# pull counters
-+	vpxor	$t1,$t1,$t1
-+	vmovdqa	$sigma,$Xn
-+	vpcmpgtd $t1,$Xn,$Xn			# mask value
-+	vpaddd	$Xn,$sigma,$sigma		# counters--
-+
-+	vmovdqu	0x00-0x80($ctx),$t1
-+	vpand	$Xn,$A,$A
-+	vmovdqu	0x20-0x80($ctx),$t2
-+	vpand	$Xn,$B,$B
-+	vmovdqu	0x40-0x80($ctx),$t3
-+	vpand	$Xn,$C,$C
-+	vmovdqu	0x60-0x80($ctx),$Xi
-+	vpand	$Xn,$D,$D
-+	vpaddd	$t1,$A,$A
-+	vmovdqu	0x80-0x80($ctx),$t1
-+	vpand	$Xn,$E,$E
-+	vpaddd	$t2,$B,$B
-+	vmovdqu	0xa0-0x80($ctx),$t2
-+	vpand	$Xn,$F,$F
-+	vpaddd	$t3,$C,$C
-+	vmovdqu	0xc0-0x80($ctx),$t3
-+	vpand	$Xn,$G,$G
-+	vpaddd	$Xi,$D,$D
-+	vmovdqu	0xe0-0x80($ctx),$Xi
-+	vpand	$Xn,$H,$H
-+	vpaddd	$t1,$E,$E
-+	vpaddd	$t2,$F,$F
-+	vmovdqu	$A,0x00-0x80($ctx)
-+	vpaddd	$t3,$G,$G
-+	vmovdqu	$B,0x20-0x80($ctx)
-+	vpaddd	$Xi,$H,$H
-+	vmovdqu	$C,0x40-0x80($ctx)
-+	vmovdqu	$D,0x60-0x80($ctx)
-+	vmovdqu	$E,0x80-0x80($ctx)
-+	vmovdqu	$F,0xa0-0x80($ctx)
-+	vmovdqu	$G,0xc0-0x80($ctx)
-+	vmovdqu	$H,0xe0-0x80($ctx)
-+
-+	vmovdqu	$sigma,(%rbx)			# save counters
-+	lea	256+128(%rsp),%rbx
-+	vmovdqu	.Lpbswap(%rip),$Xn
-+	dec	$num
-+	jnz	.Loop_avx2
-+
-+	#mov	`$REG_SZ*17+8`(%rsp),$num
-+	#lea	$REG_SZ($ctx),$ctx
-+	#lea	`16*$REG_SZ/4`($inp),$inp
-+	#dec	$num
-+	#jnz	.Loop_grande_avx2
-+
-+.Ldone_avx2:
-+	mov	`$REG_SZ*17`(%rsp),%rax		# original %rsp
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-0xd8(%rax),%xmm6
-+	movaps	-0xc8(%rax),%xmm7
-+	movaps	-0xb8(%rax),%xmm8
-+	movaps	-0xa8(%rax),%xmm9
-+	movaps	-0x98(%rax),%xmm10
-+	movaps	-0x88(%rax),%xmm11
-+	movaps	-0x78(%rax),%xmm12
-+	movaps	-0x68(%rax),%xmm13
-+	movaps	-0x58(%rax),%xmm14
-+	movaps	-0x48(%rax),%xmm15
-+___
-+$code.=<<___;
-+	mov	-48(%rax),%r15
-+	mov	-40(%rax),%r14
-+	mov	-32(%rax),%r13
-+	mov	-24(%rax),%r12
-+	mov	-16(%rax),%rbp
-+	mov	-8(%rax),%rbx
-+	lea	(%rax),%rsp
-+.Lepilogue_avx2:
-+	ret
-+.size	sha256_multi_block_avx2,.-sha256_multi_block_avx2
-+___
-+					}	}}}
-+$code.=<<___;
-+.align	256
-+K256:
-+___
-+sub TABLE {
-+    foreach (@_) {
-+	$code.=<<___;
-+	.long	$_,$_,$_,$_
-+	.long	$_,$_,$_,$_
-+___
-+    }
-+}
-+&TABLE(	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,
-+	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
-+	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,
-+	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
-+	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,
-+	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
-+	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,
-+	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
-+	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,
-+	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
-+	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,
-+	0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
-+	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,
-+	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
-+	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,
-+	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 );
-+$code.=<<___;
-+.Lpbswap:
-+	.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	# pbswap
-+	.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f	# pbswap
-+K256_shaext:
-+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+	.asciz	"SHA256 multi-block transform for x86_64, CRYPTOGAMS by "
-+___
-+
-+if ($win64) {
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# end of prologue label
-+	cmp	%r10,%rbx		# context->Rip<.Lbody
-+	jb	.Lin_prologue
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
-+	jae	.Lin_prologue
-+
-+	mov	`16*17`(%rax),%rax	# pull saved stack pointer
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+
-+	lea	-24-10*16(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+___
-+$code.=<<___ if ($avx>1);
-+.type	avx2_handler,\@abi-omnipotent
-+.align	16
-+avx2_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HandlerData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# end of prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_prologue
-+
-+	mov	`32*17`($context),%rax	# pull saved stack pointer
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore cotnext->R12
-+	mov	%r13,224($context)	# restore cotnext->R13
-+	mov	%r14,232($context)	# restore cotnext->R14
-+	mov	%r15,240($context)	# restore cotnext->R15
-+
-+	lea	-56-10*16(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$20,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	jmp	.Lin_prologue
-+.size	avx2_handler,.-avx2_handler
-+___
-+$code.=<<___;
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_sha256_multi_block
-+	.rva	.LSEH_end_sha256_multi_block
-+	.rva	.LSEH_info_sha256_multi_block
-+	.rva	.LSEH_begin_sha256_multi_block_shaext
-+	.rva	.LSEH_end_sha256_multi_block_shaext
-+	.rva	.LSEH_info_sha256_multi_block_shaext
-+___
-+$code.=<<___ if ($avx);
-+	.rva	.LSEH_begin_sha256_multi_block_avx
-+	.rva	.LSEH_end_sha256_multi_block_avx
-+	.rva	.LSEH_info_sha256_multi_block_avx
-+___
-+$code.=<<___ if ($avx>1);
-+	.rva	.LSEH_begin_sha256_multi_block_avx2
-+	.rva	.LSEH_end_sha256_multi_block_avx2
-+	.rva	.LSEH_info_sha256_multi_block_avx2
-+___
-+$code.=<<___;
-+.section	.xdata
-+.align	8
-+.LSEH_info_sha256_multi_block:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lbody,.Lepilogue			# HandlerData[]
-+.LSEH_info_sha256_multi_block_shaext:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lbody_shaext,.Lepilogue_shaext		# HandlerData[]
-+___
-+$code.=<<___ if ($avx);
-+.LSEH_info_sha256_multi_block_avx:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lbody_avx,.Lepilogue_avx		# HandlerData[]
-+___
-+$code.=<<___ if ($avx>1);
-+.LSEH_info_sha256_multi_block_avx2:
-+	.byte	9,0,0,0
-+	.rva	avx2_handler
-+	.rva	.Lbody_avx2,.Lepilogue_avx2		# HandlerData[]
-+___
-+}
-+####################################################################
-+
-+sub rex {
-+  local *opcode=shift;
-+  my ($dst,$src)=@_;
-+  my $rex=0;
-+
-+    $rex|=0x04			if ($dst>=8);
-+    $rex|=0x01			if ($src>=8);
-+    unshift @opcode,$rex|0x40	if ($rex);
-+}
-+
-+sub sha256op38 {
-+    my $instr = shift;
-+    my %opcodelet = (
-+		"sha256rnds2" => 0xcb,
-+  		"sha256msg1"  => 0xcc,
-+		"sha256msg2"  => 0xcd	);
-+
-+    if (defined($opcodelet{$instr}) && @_[0] =~ /%xmm([0-9]+),\s*%xmm([0-9]+)/) {
-+      my @opcode=(0x0f,0x38);
-+	rex(\@opcode,$2,$1);
-+	push @opcode,$opcodelet{$instr};
-+	push @opcode,0xc0|($1&7)|(($2&7)<<3);		# ModR/M
-+	return ".byte\t".join(',',@opcode);
-+    } else {
-+	return $instr."\t".@_[0];
-+    }
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval($1)/ge;
-+
-+	s/\b(sha256[^\s]*)\s+(.*)/sha256op38($1,$2)/geo		or
-+
-+	s/\b(vmov[dq])\b(.+)%ymm([0-9]+)/$1$2%xmm$3/go		or
-+	s/\b(vmovdqu)\b(.+)%x%ymm([0-9]+)/$1$2%xmm$3/go		or
-+	s/\b(vpinsr[qd])\b(.+)%ymm([0-9]+),%ymm([0-9]+)/$1$2%xmm$3,%xmm$4/go	or
-+	s/\b(vpextr[qd])\b(.+)%ymm([0-9]+)/$1$2%xmm$3/go	or
-+	s/\b(vinserti128)\b(\s+)%ymm/$1$2\$1,%xmm/go		or
-+	s/\b(vpbroadcast[qd]\s+)%ymm([0-9]+)/$1%xmm$2/go;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-586.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-586.pl
-new file mode 100644
-index 0000000..3873934
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-586.pl
-@@ -0,0 +1,924 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# SHA512 block transform for x86. September 2007.
-+#
-+# May 2013.
-+#
-+# Add SSSE3 code path, 20-25% improvement [over original SSE2 code].
-+#
-+# Performance in clock cycles per processed byte (less is better):
-+#
-+#		gcc	icc	x86 asm	SIMD(*)	x86_64(**)
-+# Pentium	100	97	61	-	-
-+# PIII		75	77	56	-	-
-+# P4		116	95	82	34.6	30.8
-+# AMD K8	54	55	36	20.7	9.57
-+# Core2		66	57	40	15.9	9.97
-+# Westmere	70	-	38	12.2	9.58
-+# Sandy Bridge	58	-	35	11.9	11.2
-+# Ivy Bridge	50	-	33	11.5	8.17
-+# Haswell	46	-	29	11.3	7.66
-+# Bulldozer	121	-	50	14.0	13.5
-+# VIA Nano	91	-	52	33	14.7
-+# Atom		126	-	68	48(***)	14.7
-+# Silvermont	97	-	58	42(***)	17.5
-+# Goldmont	80	-	48	19.5	12.0
-+#
-+# (*)	whichever best applicable.
-+# (**)	x86_64 assembler performance is presented for reference
-+#	purposes, the results are for integer-only code.
-+# (***)	paddq is increadibly slow on Atom.
-+#
-+# IALU code-path is optimized for elder Pentiums. On vanilla Pentium
-+# performance improvement over compiler generated code reaches ~60%,
-+# while on PIII - ~35%. On newer µ-archs improvement varies from 15%
-+# to 50%, but it's less important as they are expected to execute SSE2
-+# code-path, which is commonly ~2-3x faster [than compiler generated
-+# code]. SSE2 code-path is as fast as original sha512-sse2.pl, even
-+# though it does not use 128-bit operations. The latter means that
-+# SSE2-aware kernel is no longer required to execute the code. Another
-+# difference is that new code optimizes amount of writes, but at the
-+# cost of increased data cache "footprint" by 1/2KB.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386");
-+
-+$sse2=0;
-+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-+
-+&external_label("OPENSSL_ia32cap_P") if ($sse2);
-+
-+$Tlo=&DWP(0,"esp");	$Thi=&DWP(4,"esp");
-+$Alo=&DWP(8,"esp");	$Ahi=&DWP(8+4,"esp");
-+$Blo=&DWP(16,"esp");	$Bhi=&DWP(16+4,"esp");
-+$Clo=&DWP(24,"esp");	$Chi=&DWP(24+4,"esp");
-+$Dlo=&DWP(32,"esp");	$Dhi=&DWP(32+4,"esp");
-+$Elo=&DWP(40,"esp");	$Ehi=&DWP(40+4,"esp");
-+$Flo=&DWP(48,"esp");	$Fhi=&DWP(48+4,"esp");
-+$Glo=&DWP(56,"esp");	$Ghi=&DWP(56+4,"esp");
-+$Hlo=&DWP(64,"esp");	$Hhi=&DWP(64+4,"esp");
-+$K512="ebp";
-+
-+$Asse2=&QWP(0,"esp");
-+$Bsse2=&QWP(8,"esp");
-+$Csse2=&QWP(16,"esp");
-+$Dsse2=&QWP(24,"esp");
-+$Esse2=&QWP(32,"esp");
-+$Fsse2=&QWP(40,"esp");
-+$Gsse2=&QWP(48,"esp");
-+$Hsse2=&QWP(56,"esp");
-+
-+$A="mm0";	# B-D and
-+$E="mm4";	# F-H are commonly loaded to respectively mm1-mm3 and
-+		# mm5-mm7, but it's done on on-demand basis...
-+$BxC="mm2";	# ... except for B^C
-+
-+sub BODY_00_15_sse2 {
-+    my $phase=shift;
-+
-+	#&movq	("mm5",$Fsse2);			# load f
-+	#&movq	("mm6",$Gsse2);			# load g
-+
-+	&movq	("mm1",$E);			# %mm1 is sliding right
-+	 &pxor	("mm5","mm6");			# f^=g
-+	&psrlq	("mm1",14);
-+	 &movq	($Esse2,$E);			# modulo-scheduled save e
-+	 &pand	("mm5",$E);			# f&=e
-+	&psllq	($E,23);			# $E is sliding left
-+	 &movq	($A,"mm3")			if ($phase<2);
-+	 &movq	(&QWP(8*9,"esp"),"mm7")		# save X[i]
-+	&movq	("mm3","mm1");			# %mm3 is T1
-+	 &psrlq	("mm1",4);
-+	 &pxor	("mm5","mm6");			# Ch(e,f,g)
-+	&pxor	("mm3",$E);
-+	 &psllq	($E,23);
-+	&pxor	("mm3","mm1");
-+	 &movq	($Asse2,$A);			# modulo-scheduled save a
-+	 &paddq	("mm7","mm5");			# X[i]+=Ch(e,f,g)
-+	&pxor	("mm3",$E);
-+	 &psrlq	("mm1",23);
-+	 &paddq	("mm7",$Hsse2);			# X[i]+=h
-+	&pxor	("mm3","mm1");
-+	 &psllq	($E,4);
-+	 &paddq	("mm7",QWP(0,$K512));		# X[i]+=K512[i]
-+	&pxor	("mm3",$E);			# T1=Sigma1_512(e)
-+
-+	 &movq	($E,$Dsse2);			# e = load d, e in next round
-+	&paddq	("mm3","mm7");			# T1+=X[i]
-+	 &movq	("mm5",$A);			# %mm5 is sliding right
-+	 &psrlq	("mm5",28);
-+	&paddq	($E,"mm3");			# d += T1
-+	 &movq	("mm6",$A);			# %mm6 is sliding left
-+	 &movq	("mm7","mm5");
-+	 &psllq	("mm6",25);
-+	&movq	("mm1",$Bsse2);			# load b
-+	 &psrlq	("mm5",6);
-+	 &pxor	("mm7","mm6");
-+	&sub	("esp",8);
-+	 &psllq	("mm6",5);
-+	 &pxor	("mm7","mm5");
-+	&pxor	($A,"mm1");			# a^b, b^c in next round
-+	 &psrlq	("mm5",5);
-+	 &pxor	("mm7","mm6");
-+	&pand	($BxC,$A);			# (b^c)&(a^b)
-+	 &psllq	("mm6",6);
-+	 &pxor	("mm7","mm5");
-+	&pxor	($BxC,"mm1");			# [h=]Maj(a,b,c)
-+	 &pxor	("mm6","mm7");			# Sigma0_512(a)
-+	 &movq	("mm7",&QWP(8*(9+16-1),"esp"))	if ($phase!=0);	# pre-fetch
-+	 &movq	("mm5",$Fsse2)			if ($phase==0);	# load f
-+
-+    if ($phase>1) {
-+	&paddq	($BxC,"mm6");			# h+=Sigma0(a)
-+	 &add	($K512,8);
-+	#&paddq	($BxC,"mm3");			# h+=T1
-+
-+	($A,$BxC) = ($BxC,$A);			# rotate registers
-+    } else {
-+	&paddq	("mm3",$BxC);			# T1+=Maj(a,b,c)
-+	 &movq	($BxC,$A);
-+	 &add	($K512,8);
-+	&paddq	("mm3","mm6");			# T1+=Sigma0(a)
-+	 &movq	("mm6",$Gsse2)			if ($phase==0);	# load g
-+	#&movq	($A,"mm3");			# h=T1
-+    }
-+}
-+
-+sub BODY_00_15_x86 {
-+	#define Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18)  ^ ROTR((x),41))
-+	#	LO		lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
-+	#	HI		hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
-+	&mov	("ecx",$Elo);
-+	&mov	("edx",$Ehi);
-+	&mov	("esi","ecx");
-+
-+	&shr	("ecx",9);	# lo>>9
-+	&mov	("edi","edx");
-+	&shr	("edx",9);	# hi>>9
-+	&mov	("ebx","ecx");
-+	&shl	("esi",14);	# lo<<14
-+	&mov	("eax","edx");
-+	&shl	("edi",14);	# hi<<14
-+	&xor	("ebx","esi");
-+
-+	&shr	("ecx",14-9);	# lo>>14
-+	&xor	("eax","edi");
-+	&shr	("edx",14-9);	# hi>>14
-+	&xor	("eax","ecx");
-+	&shl	("esi",18-14);	# lo<<18
-+	&xor	("ebx","edx");
-+	&shl	("edi",18-14);	# hi<<18
-+	&xor	("ebx","esi");
-+
-+	&shr	("ecx",18-14);	# lo>>18
-+	&xor	("eax","edi");
-+	&shr	("edx",18-14);	# hi>>18
-+	&xor	("eax","ecx");
-+	&shl	("esi",23-18);	# lo<<23
-+	&xor	("ebx","edx");
-+	&shl	("edi",23-18);	# hi<<23
-+	&xor	("eax","esi");
-+	&xor	("ebx","edi");			# T1 = Sigma1(e)
-+
-+	&mov	("ecx",$Flo);
-+	&mov	("edx",$Fhi);
-+	&mov	("esi",$Glo);
-+	&mov	("edi",$Ghi);
-+	 &add	("eax",$Hlo);
-+	 &adc	("ebx",$Hhi);			# T1 += h
-+	&xor	("ecx","esi");
-+	&xor	("edx","edi");
-+	&and	("ecx",$Elo);
-+	&and	("edx",$Ehi);
-+	 &add	("eax",&DWP(8*(9+15)+0,"esp"));
-+	 &adc	("ebx",&DWP(8*(9+15)+4,"esp"));	# T1 += X[0]
-+	&xor	("ecx","esi");
-+	&xor	("edx","edi");			# Ch(e,f,g) = (f^g)&e)^g
-+
-+	&mov	("esi",&DWP(0,$K512));
-+	&mov	("edi",&DWP(4,$K512));		# K[i]
-+	&add	("eax","ecx");
-+	&adc	("ebx","edx");			# T1 += Ch(e,f,g)
-+	&mov	("ecx",$Dlo);
-+	&mov	("edx",$Dhi);
-+	&add	("eax","esi");
-+	&adc	("ebx","edi");			# T1 += K[i]
-+	&mov	($Tlo,"eax");
-+	&mov	($Thi,"ebx");			# put T1 away
-+	&add	("eax","ecx");
-+	&adc	("ebx","edx");			# d += T1
-+
-+	#define Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
-+	#	LO		lo>>28^hi<<4  ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
-+	#	HI		hi>>28^lo<<4  ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
-+	&mov	("ecx",$Alo);
-+	&mov	("edx",$Ahi);
-+	&mov	($Dlo,"eax");
-+	&mov	($Dhi,"ebx");
-+	&mov	("esi","ecx");
-+
-+	&shr	("ecx",2);	# lo>>2
-+	&mov	("edi","edx");
-+	&shr	("edx",2);	# hi>>2
-+	&mov	("ebx","ecx");
-+	&shl	("esi",4);	# lo<<4
-+	&mov	("eax","edx");
-+	&shl	("edi",4);	# hi<<4
-+	&xor	("ebx","esi");
-+
-+	&shr	("ecx",7-2);	# lo>>7
-+	&xor	("eax","edi");
-+	&shr	("edx",7-2);	# hi>>7
-+	&xor	("ebx","ecx");
-+	&shl	("esi",25-4);	# lo<<25
-+	&xor	("eax","edx");
-+	&shl	("edi",25-4);	# hi<<25
-+	&xor	("eax","esi");
-+
-+	&shr	("ecx",28-7);	# lo>>28
-+	&xor	("ebx","edi");
-+	&shr	("edx",28-7);	# hi>>28
-+	&xor	("eax","ecx");
-+	&shl	("esi",30-25);	# lo<<30
-+	&xor	("ebx","edx");
-+	&shl	("edi",30-25);	# hi<<30
-+	&xor	("eax","esi");
-+	&xor	("ebx","edi");			# Sigma0(a)
-+
-+	&mov	("ecx",$Alo);
-+	&mov	("edx",$Ahi);
-+	&mov	("esi",$Blo);
-+	&mov	("edi",$Bhi);
-+	&add	("eax",$Tlo);
-+	&adc	("ebx",$Thi);			# T1 = Sigma0(a)+T1
-+	&or	("ecx","esi");
-+	&or	("edx","edi");
-+	&and	("ecx",$Clo);
-+	&and	("edx",$Chi);
-+	&and	("esi",$Alo);
-+	&and	("edi",$Ahi);
-+	&or	("ecx","esi");
-+	&or	("edx","edi");			# Maj(a,b,c) = ((a|b)&c)|(a&b)
-+
-+	&add	("eax","ecx");
-+	&adc	("ebx","edx");			# T1 += Maj(a,b,c)
-+	&mov	($Tlo,"eax");
-+	&mov	($Thi,"ebx");
-+
-+	&mov	(&LB("edx"),&BP(0,$K512));	# pre-fetch LSB of *K
-+	&sub	("esp",8);
-+	&lea	($K512,&DWP(8,$K512));		# K++
-+}
-+
-+
-+&function_begin("sha512_block_data_order");
-+	&mov	("esi",wparam(0));	# ctx
-+	&mov	("edi",wparam(1));	# inp
-+	&mov	("eax",wparam(2));	# num
-+	&mov	("ebx","esp");		# saved sp
-+
-+	&call	(&label("pic_point"));	# make it PIC!
-+&set_label("pic_point");
-+	&blindpop($K512);
-+	&lea	($K512,&DWP(&label("K512")."-".&label("pic_point"),$K512));
-+
-+	&sub	("esp",16);
-+	&and	("esp",-64);
-+
-+	&shl	("eax",7);
-+	&add	("eax","edi");
-+	&mov	(&DWP(0,"esp"),"esi");	# ctx
-+	&mov	(&DWP(4,"esp"),"edi");	# inp
-+	&mov	(&DWP(8,"esp"),"eax");	# inp+num*128
-+	&mov	(&DWP(12,"esp"),"ebx");	# saved sp
-+
-+if ($sse2) {
-+	&picmeup("edx","OPENSSL_ia32cap_P",$K512,&label("K512"));
-+	&mov	("ecx",&DWP(0,"edx"));
-+	&test	("ecx",1<<26);
-+	&jz	(&label("loop_x86"));
-+
-+	&mov	("edx",&DWP(4,"edx"));
-+
-+	# load ctx->h[0-7]
-+	&movq	($A,&QWP(0,"esi"));
-+	 &and	("ecx",1<<24);		# XMM registers availability
-+	&movq	("mm1",&QWP(8,"esi"));
-+	 &and	("edx",1<<9);		# SSSE3 bit
-+	&movq	($BxC,&QWP(16,"esi"));
-+	 &or	("ecx","edx");
-+	&movq	("mm3",&QWP(24,"esi"));
-+	&movq	($E,&QWP(32,"esi"));
-+	&movq	("mm5",&QWP(40,"esi"));
-+	&movq	("mm6",&QWP(48,"esi"));
-+	&movq	("mm7",&QWP(56,"esi"));
-+	&cmp	("ecx",1<<24|1<<9);
-+	&je	(&label("SSSE3"));
-+	&sub	("esp",8*10);
-+	&jmp	(&label("loop_sse2"));
-+
-+&set_label("loop_sse2",16);
-+	#&movq	($Asse2,$A);
-+	&movq	($Bsse2,"mm1");
-+	&movq	($Csse2,$BxC);
-+	&movq	($Dsse2,"mm3");
-+	#&movq	($Esse2,$E);
-+	&movq	($Fsse2,"mm5");
-+	&movq	($Gsse2,"mm6");
-+	&pxor	($BxC,"mm1");			# magic
-+	&movq	($Hsse2,"mm7");
-+	&movq	("mm3",$A);			# magic
-+
-+	&mov	("eax",&DWP(0,"edi"));
-+	&mov	("ebx",&DWP(4,"edi"));
-+	&add	("edi",8);
-+	&mov	("edx",15);			# counter
-+	&bswap	("eax");
-+	&bswap	("ebx");
-+	&jmp	(&label("00_14_sse2"));
-+
-+&set_label("00_14_sse2",16);
-+	&movd	("mm1","eax");
-+	&mov	("eax",&DWP(0,"edi"));
-+	&movd	("mm7","ebx");
-+	&mov	("ebx",&DWP(4,"edi"));
-+	&add	("edi",8);
-+	&bswap	("eax");
-+	&bswap	("ebx");
-+	&punpckldq("mm7","mm1");
-+
-+	&BODY_00_15_sse2();
-+
-+	&dec	("edx");
-+	&jnz	(&label("00_14_sse2"));
-+
-+	&movd	("mm1","eax");
-+	&movd	("mm7","ebx");
-+	&punpckldq("mm7","mm1");
-+
-+	&BODY_00_15_sse2(1);
-+
-+	&pxor	($A,$A);			# A is in %mm3
-+	&mov	("edx",32);			# counter
-+	&jmp	(&label("16_79_sse2"));
-+
-+&set_label("16_79_sse2",16);
-+    for ($j=0;$j<2;$j++) {			# 2x unroll
-+	#&movq	("mm7",&QWP(8*(9+16-1),"esp"));	# prefetched in BODY_00_15 
-+	&movq	("mm5",&QWP(8*(9+16-14),"esp"));
-+	&movq	("mm1","mm7");
-+	&psrlq	("mm7",1);
-+	 &movq	("mm6","mm5");
-+	 &psrlq	("mm5",6);
-+	&psllq	("mm1",56);
-+	 &paddq	($A,"mm3");			# from BODY_00_15
-+	 &movq	("mm3","mm7");
-+	&psrlq	("mm7",7-1);
-+	 &pxor	("mm3","mm1");
-+	 &psllq	("mm1",63-56);
-+	&pxor	("mm3","mm7");
-+	 &psrlq	("mm7",8-7);
-+	&pxor	("mm3","mm1");
-+	 &movq	("mm1","mm5");
-+	 &psrlq	("mm5",19-6);
-+	&pxor	("mm7","mm3");			# sigma0
-+
-+	 &psllq	("mm6",3);
-+	 &pxor	("mm1","mm5");
-+	&paddq	("mm7",&QWP(8*(9+16),"esp"));
-+	 &pxor	("mm1","mm6");
-+	 &psrlq	("mm5",61-19);
-+	&paddq	("mm7",&QWP(8*(9+16-9),"esp"));
-+	 &pxor	("mm1","mm5");
-+	 &psllq	("mm6",45-3);
-+	&movq	("mm5",$Fsse2);			# load f
-+	 &pxor	("mm1","mm6");			# sigma1
-+	&movq	("mm6",$Gsse2);			# load g
-+
-+	&paddq	("mm7","mm1");			# X[i]
-+	#&movq	(&QWP(8*9,"esp"),"mm7");	# moved to BODY_00_15
-+
-+	&BODY_00_15_sse2(2);
-+    }
-+	&dec	("edx");
-+	&jnz	(&label("16_79_sse2"));
-+
-+	#&movq	($A,$Asse2);
-+	&paddq	($A,"mm3");			# from BODY_00_15
-+	&movq	("mm1",$Bsse2);
-+	#&movq	($BxC,$Csse2);
-+	&movq	("mm3",$Dsse2);
-+	#&movq	($E,$Esse2);
-+	&movq	("mm5",$Fsse2);
-+	&movq	("mm6",$Gsse2);
-+	&movq	("mm7",$Hsse2);
-+
-+	&pxor	($BxC,"mm1");			# de-magic
-+	&paddq	($A,&QWP(0,"esi"));
-+	&paddq	("mm1",&QWP(8,"esi"));
-+	&paddq	($BxC,&QWP(16,"esi"));
-+	&paddq	("mm3",&QWP(24,"esi"));
-+	&paddq	($E,&QWP(32,"esi"));
-+	&paddq	("mm5",&QWP(40,"esi"));
-+	&paddq	("mm6",&QWP(48,"esi"));
-+	&paddq	("mm7",&QWP(56,"esi"));
-+
-+	&mov	("eax",8*80);
-+	&movq	(&QWP(0,"esi"),$A);
-+	&movq	(&QWP(8,"esi"),"mm1");
-+	&movq	(&QWP(16,"esi"),$BxC);
-+	&movq	(&QWP(24,"esi"),"mm3");
-+	&movq	(&QWP(32,"esi"),$E);
-+	&movq	(&QWP(40,"esi"),"mm5");
-+	&movq	(&QWP(48,"esi"),"mm6");
-+	&movq	(&QWP(56,"esi"),"mm7");
-+
-+	&lea	("esp",&DWP(0,"esp","eax"));	# destroy frame
-+	&sub	($K512,"eax");			# rewind K
-+
-+	&cmp	("edi",&DWP(8*10+8,"esp"));	# are we done yet?
-+	&jb	(&label("loop_sse2"));
-+
-+	&mov	("esp",&DWP(8*10+12,"esp"));	# restore sp
-+	&emms	();
-+&function_end_A();
-+
-+&set_label("SSSE3",32);
-+{ my ($cnt,$frame)=("ecx","edx");
-+  my @X=map("xmm$_",(0..7));
-+  my $j;
-+  my $i=0;
-+
-+	&lea	($frame,&DWP(-64,"esp"));
-+	&sub	("esp",256);
-+
-+	# fixed stack frame layout
-+	#
-+	# +0	A B C D E F G H		# backing store
-+	# +64	X[0]+K[i] .. X[15]+K[i]	# XMM->MM xfer area
-+	# +192				# XMM off-load ring buffer
-+	# +256				# saved parameters
-+
-+	&movdqa		(@X[1],&QWP(80*8,$K512));		# byte swap mask
-+	&movdqu		(@X[0],&QWP(0,"edi"));
-+	&pshufb		(@X[0],@X[1]);
-+    for ($j=0;$j<8;$j++) {
-+	&movdqa		(&QWP(16*(($j-1)%4),$frame),@X[3])	if ($j>4); # off-load
-+	&movdqa		(@X[3],&QWP(16*($j%8),$K512));
-+	&movdqa		(@X[2],@X[1])				if ($j<7); # perpetuate byte swap mask
-+	&movdqu		(@X[1],&QWP(16*($j+1),"edi"))		if ($j<7); # next input
-+	&movdqa		(@X[1],&QWP(16*(($j+1)%4),$frame))	if ($j==7);# restore @X[0]
-+	&paddq		(@X[3],@X[0]);
-+	&pshufb		(@X[1],@X[2])				if ($j<7);
-+	&movdqa		(&QWP(16*($j%8)-128,$frame),@X[3]);	# xfer X[i]+K[i]
-+
-+	push(@X,shift(@X));					# rotate(@X)
-+    }
-+	#&jmp		(&label("loop_ssse3"));
-+	&nop		();
-+
-+&set_label("loop_ssse3",32);
-+	&movdqa		(@X[2],&QWP(16*(($j+1)%4),$frame));	# pre-restore @X[1]
-+	&movdqa		(&QWP(16*(($j-1)%4),$frame),@X[3]);	# off-load @X[3]
-+	&lea		($K512,&DWP(16*8,$K512));
-+
-+	#&movq	($Asse2,$A);			# off-load A-H
-+	&movq	($Bsse2,"mm1");
-+	 &mov	("ebx","edi");
-+	&movq	($Csse2,$BxC);
-+	 &lea	("edi",&DWP(128,"edi"));	# advance input
-+	&movq	($Dsse2,"mm3");
-+	 &cmp	("edi","eax");
-+	#&movq	($Esse2,$E);
-+	&movq	($Fsse2,"mm5");
-+	 &cmovb	("ebx","edi");
-+	&movq	($Gsse2,"mm6");
-+	 &mov	("ecx",4);			# loop counter
-+	&pxor	($BxC,"mm1");			# magic
-+	&movq	($Hsse2,"mm7");
-+	&pxor	("mm3","mm3");			# magic
-+
-+	&jmp		(&label("00_47_ssse3"));
-+
-+sub BODY_00_15_ssse3 {		# "phase-less" copy of BODY_00_15_sse2
-+	(
-+	'&movq	("mm1",$E)',				# %mm1 is sliding right
-+	'&movq	("mm7",&QWP(((-8*$i)%128)-128,$frame))',# X[i]+K[i]
-+	 '&pxor	("mm5","mm6")',				# f^=g
-+	'&psrlq	("mm1",14)',
-+	 '&movq	(&QWP(8*($i+4)%64,"esp"),$E)',		# modulo-scheduled save e
-+	 '&pand	("mm5",$E)',				# f&=e
-+	'&psllq	($E,23)',				# $E is sliding left
-+	'&paddq	($A,"mm3")',				# [h+=Maj(a,b,c)]
-+	'&movq	("mm3","mm1")',				# %mm3 is T1
-+	 '&psrlq("mm1",4)',
-+	 '&pxor	("mm5","mm6")',				# Ch(e,f,g)
-+	'&pxor	("mm3",$E)',
-+	 '&psllq($E,23)',
-+	'&pxor	("mm3","mm1")',
-+	 '&movq	(&QWP(8*$i%64,"esp"),$A)',		# modulo-scheduled save a
-+	 '&paddq("mm7","mm5")',				# X[i]+=Ch(e,f,g)
-+	'&pxor	("mm3",$E)',
-+	 '&psrlq("mm1",23)',
-+	 '&paddq("mm7",&QWP(8*($i+7)%64,"esp"))',	# X[i]+=h
-+	'&pxor	("mm3","mm1")',
-+	 '&psllq($E,4)',
-+	'&pxor	("mm3",$E)',				# T1=Sigma1_512(e)
-+
-+	 '&movq	($E,&QWP(8*($i+3)%64,"esp"))',		# e = load d, e in next round
-+	'&paddq	("mm3","mm7")',				# T1+=X[i]
-+	 '&movq	("mm5",$A)',				# %mm5 is sliding right
-+	 '&psrlq("mm5",28)',
-+	'&paddq	($E,"mm3")',				# d += T1
-+	 '&movq	("mm6",$A)',				# %mm6 is sliding left
-+	 '&movq	("mm7","mm5")',
-+	 '&psllq("mm6",25)',
-+	'&movq	("mm1",&QWP(8*($i+1)%64,"esp"))',	# load b
-+	 '&psrlq("mm5",6)',
-+	 '&pxor	("mm7","mm6")',
-+	 '&psllq("mm6",5)',
-+	 '&pxor	("mm7","mm5")',
-+	'&pxor	($A,"mm1")',				# a^b, b^c in next round
-+	 '&psrlq("mm5",5)',
-+	 '&pxor	("mm7","mm6")',
-+	'&pand	($BxC,$A)',				# (b^c)&(a^b)
-+	 '&psllq("mm6",6)',
-+	 '&pxor	("mm7","mm5")',
-+	'&pxor	($BxC,"mm1")',				# [h=]Maj(a,b,c)
-+	 '&pxor	("mm6","mm7")',				# Sigma0_512(a)
-+	 '&movq	("mm5",&QWP(8*($i+5-1)%64,"esp"))',	# pre-load f
-+	'&paddq	($BxC,"mm6")',				# h+=Sigma0(a)
-+	 '&movq	("mm6",&QWP(8*($i+6-1)%64,"esp"))',	# pre-load g
-+
-+	'($A,$BxC) = ($BxC,$A); $i--;'
-+	);
-+}
-+
-+&set_label("00_47_ssse3",32);
-+
-+    for(;$j<16;$j++) {
-+	my ($t0,$t2,$t1)=@X[2..4];
-+	my @insns = (&BODY_00_15_ssse3(),&BODY_00_15_ssse3());
-+
-+	&movdqa		($t2,@X[5]);
-+	&movdqa		(@X[1],$t0);			# restore @X[1]
-+	&palignr	($t0,@X[0],8);			# X[1..2]
-+	&movdqa		(&QWP(16*($j%4),$frame),@X[4]);	# off-load @X[4]
-+	 &palignr	($t2,@X[4],8);			# X[9..10]
-+
-+	&movdqa		($t1,$t0);
-+	&psrlq		($t0,7);
-+	 &paddq		(@X[0],$t2);			# X[0..1] += X[9..10]
-+	&movdqa		($t2,$t1);
-+	&psrlq		($t1,1);
-+	&psllq		($t2,64-8);
-+	&pxor		($t0,$t1);
-+	&psrlq		($t1,8-1);
-+	&pxor		($t0,$t2);
-+	&psllq		($t2,8-1);
-+	&pxor		($t0,$t1);
-+	 &movdqa	($t1,@X[7]);
-+	&pxor		($t0,$t2);			# sigma0(X[1..2])
-+	 &movdqa	($t2,@X[7]);
-+	 &psrlq		($t1,6);
-+	&paddq		(@X[0],$t0);			# X[0..1] += sigma0(X[1..2])
-+
-+	&movdqa		($t0,@X[7]);
-+	&psrlq		($t2,19);
-+	&psllq		($t0,64-61);
-+	&pxor		($t1,$t2);
-+	&psrlq		($t2,61-19);
-+	&pxor		($t1,$t0);
-+	&psllq		($t0,61-19);
-+	&pxor		($t1,$t2);
-+	&movdqa		($t2,&QWP(16*(($j+2)%4),$frame));# pre-restore @X[1]
-+	&pxor		($t1,$t0);			# sigma0(X[1..2])
-+	&movdqa		($t0,&QWP(16*($j%8),$K512));
-+	 eval(shift(@insns));
-+	&paddq		(@X[0],$t1);			# X[0..1] += sigma0(X[14..15])
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	 eval(shift(@insns));
-+	&paddq		($t0,@X[0]);
-+	 foreach(@insns) { eval; }
-+	&movdqa		(&QWP(16*($j%8)-128,$frame),$t0);# xfer X[i]+K[i]
-+
-+	push(@X,shift(@X));				# rotate(@X)
-+    }
-+	&lea		($K512,&DWP(16*8,$K512));
-+	&dec		("ecx");
-+	&jnz		(&label("00_47_ssse3"));
-+
-+	&movdqa		(@X[1],&QWP(0,$K512));		# byte swap mask
-+	&lea		($K512,&DWP(-80*8,$K512));	# rewind
-+	&movdqu		(@X[0],&QWP(0,"ebx"));
-+	&pshufb		(@X[0],@X[1]);
-+
-+    for ($j=0;$j<8;$j++) {	# load next or same block
-+	my @insns = (&BODY_00_15_ssse3(),&BODY_00_15_ssse3());
-+
-+	&movdqa		(&QWP(16*(($j-1)%4),$frame),@X[3])	if ($j>4); # off-load
-+	&movdqa		(@X[3],&QWP(16*($j%8),$K512));
-+	&movdqa		(@X[2],@X[1])				if ($j<7); # perpetuate byte swap mask
-+	&movdqu		(@X[1],&QWP(16*($j+1),"ebx"))		if ($j<7); # next input
-+	&movdqa		(@X[1],&QWP(16*(($j+1)%4),$frame))	if ($j==7);# restore @X[0]
-+	&paddq		(@X[3],@X[0]);
-+	&pshufb		(@X[1],@X[2])				if ($j<7);
-+	 foreach(@insns) { eval; }
-+	&movdqa		(&QWP(16*($j%8)-128,$frame),@X[3]);# xfer X[i]+K[i]
-+
-+	push(@X,shift(@X));				# rotate(@X)
-+    }
-+
-+	#&movq	($A,$Asse2);			# load A-H
-+	&movq	("mm1",$Bsse2);
-+	&paddq	($A,"mm3");			# from BODY_00_15
-+	#&movq	($BxC,$Csse2);
-+	&movq	("mm3",$Dsse2);
-+	#&movq	($E,$Esse2);
-+	#&movq	("mm5",$Fsse2);
-+	#&movq	("mm6",$Gsse2);
-+	&movq	("mm7",$Hsse2);
-+
-+	&pxor	($BxC,"mm1");			# de-magic
-+	&paddq	($A,&QWP(0,"esi"));
-+	&paddq	("mm1",&QWP(8,"esi"));
-+	&paddq	($BxC,&QWP(16,"esi"));
-+	&paddq	("mm3",&QWP(24,"esi"));
-+	&paddq	($E,&QWP(32,"esi"));
-+	&paddq	("mm5",&QWP(40,"esi"));
-+	&paddq	("mm6",&QWP(48,"esi"));
-+	&paddq	("mm7",&QWP(56,"esi"));
-+
-+	&movq	(&QWP(0,"esi"),$A);
-+	&movq	(&QWP(8,"esi"),"mm1");
-+	&movq	(&QWP(16,"esi"),$BxC);
-+	&movq	(&QWP(24,"esi"),"mm3");
-+	&movq	(&QWP(32,"esi"),$E);
-+	&movq	(&QWP(40,"esi"),"mm5");
-+	&movq	(&QWP(48,"esi"),"mm6");
-+	&movq	(&QWP(56,"esi"),"mm7");
-+
-+    	&cmp	("edi","eax")			# are we done yet?
-+	&jb	(&label("loop_ssse3"));
-+
-+	&mov	("esp",&DWP(64+12,$frame));	# restore sp
-+	&emms	();
-+}
-+&function_end_A();
-+}
-+&set_label("loop_x86",16);
-+    # copy input block to stack reversing byte and qword order
-+    for ($i=0;$i<8;$i++) {
-+	&mov	("eax",&DWP($i*16+0,"edi"));
-+	&mov	("ebx",&DWP($i*16+4,"edi"));
-+	&mov	("ecx",&DWP($i*16+8,"edi"));
-+	&mov	("edx",&DWP($i*16+12,"edi"));
-+	&bswap	("eax");
-+	&bswap	("ebx");
-+	&bswap	("ecx");
-+	&bswap	("edx");
-+	&push	("eax");
-+	&push	("ebx");
-+	&push	("ecx");
-+	&push	("edx");
-+    }
-+	&add	("edi",128);
-+	&sub	("esp",9*8);		# place for T,A,B,C,D,E,F,G,H
-+	&mov	(&DWP(8*(9+16)+4,"esp"),"edi");
-+
-+	# copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack
-+	&lea	("edi",&DWP(8,"esp"));
-+	&mov	("ecx",16);
-+	&data_word(0xA5F3F689);		# rep movsd
-+
-+&set_label("00_15_x86",16);
-+	&BODY_00_15_x86();
-+
-+	&cmp	(&LB("edx"),0x94);
-+	&jne	(&label("00_15_x86"));
-+
-+&set_label("16_79_x86",16);
-+	#define sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
-+	#	LO		lo>>1^hi<<31  ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
-+	#	HI		hi>>1^lo<<31  ^ hi>>8^lo<<24 ^ hi>>7
-+	&mov	("ecx",&DWP(8*(9+15+16-1)+0,"esp"));
-+	&mov	("edx",&DWP(8*(9+15+16-1)+4,"esp"));
-+	&mov	("esi","ecx");
-+
-+	&shr	("ecx",1);	# lo>>1
-+	&mov	("edi","edx");
-+	&shr	("edx",1);	# hi>>1
-+	&mov	("eax","ecx");
-+	&shl	("esi",24);	# lo<<24
-+	&mov	("ebx","edx");
-+	&shl	("edi",24);	# hi<<24
-+	&xor	("ebx","esi");
-+
-+	&shr	("ecx",7-1);	# lo>>7
-+	&xor	("eax","edi");
-+	&shr	("edx",7-1);	# hi>>7
-+	&xor	("eax","ecx");
-+	&shl	("esi",31-24);	# lo<<31
-+	&xor	("ebx","edx");
-+	&shl	("edi",25-24);	# hi<<25
-+	&xor	("ebx","esi");
-+
-+	&shr	("ecx",8-7);	# lo>>8
-+	&xor	("eax","edi");
-+	&shr	("edx",8-7);	# hi>>8
-+	&xor	("eax","ecx");
-+	&shl	("edi",31-25);	# hi<<31
-+	&xor	("ebx","edx");
-+	&xor	("eax","edi");			# T1 = sigma0(X[-15])
-+
-+	&mov	(&DWP(0,"esp"),"eax");
-+	&mov	(&DWP(4,"esp"),"ebx");		# put T1 away
-+
-+	#define sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
-+	#	LO		lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26
-+	#	HI		hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6
-+	&mov	("ecx",&DWP(8*(9+15+16-14)+0,"esp"));
-+	&mov	("edx",&DWP(8*(9+15+16-14)+4,"esp"));
-+	&mov	("esi","ecx");
-+
-+	&shr	("ecx",6);	# lo>>6
-+	&mov	("edi","edx");
-+	&shr	("edx",6);	# hi>>6
-+	&mov	("eax","ecx");
-+	&shl	("esi",3);	# lo<<3
-+	&mov	("ebx","edx");
-+	&shl	("edi",3);	# hi<<3
-+	&xor	("eax","esi");
-+
-+	&shr	("ecx",19-6);	# lo>>19
-+	&xor	("ebx","edi");
-+	&shr	("edx",19-6);	# hi>>19
-+	&xor	("eax","ecx");
-+	&shl	("esi",13-3);	# lo<<13
-+	&xor	("ebx","edx");
-+	&shl	("edi",13-3);	# hi<<13
-+	&xor	("ebx","esi");
-+
-+	&shr	("ecx",29-19);	# lo>>29
-+	&xor	("eax","edi");
-+	&shr	("edx",29-19);	# hi>>29
-+	&xor	("ebx","ecx");
-+	&shl	("edi",26-13);	# hi<<26
-+	&xor	("eax","edx");
-+	&xor	("eax","edi");			# sigma1(X[-2])
-+
-+	&mov	("ecx",&DWP(8*(9+15+16)+0,"esp"));
-+	&mov	("edx",&DWP(8*(9+15+16)+4,"esp"));
-+	&add	("eax",&DWP(0,"esp"));
-+	&adc	("ebx",&DWP(4,"esp"));		# T1 = sigma1(X[-2])+T1
-+	&mov	("esi",&DWP(8*(9+15+16-9)+0,"esp"));
-+	&mov	("edi",&DWP(8*(9+15+16-9)+4,"esp"));
-+	&add	("eax","ecx");
-+	&adc	("ebx","edx");			# T1 += X[-16]
-+	&add	("eax","esi");
-+	&adc	("ebx","edi");			# T1 += X[-7]
-+	&mov	(&DWP(8*(9+15)+0,"esp"),"eax");
-+	&mov	(&DWP(8*(9+15)+4,"esp"),"ebx");	# save X[0]
-+
-+	&BODY_00_15_x86();
-+
-+	&cmp	(&LB("edx"),0x17);
-+	&jne	(&label("16_79_x86"));
-+
-+	&mov	("esi",&DWP(8*(9+16+80)+0,"esp"));# ctx
-+	&mov	("edi",&DWP(8*(9+16+80)+4,"esp"));# inp
-+    for($i=0;$i<4;$i++) {
-+	&mov	("eax",&DWP($i*16+0,"esi"));
-+	&mov	("ebx",&DWP($i*16+4,"esi"));
-+	&mov	("ecx",&DWP($i*16+8,"esi"));
-+	&mov	("edx",&DWP($i*16+12,"esi"));
-+	&add	("eax",&DWP(8+($i*16)+0,"esp"));
-+	&adc	("ebx",&DWP(8+($i*16)+4,"esp"));
-+	&mov	(&DWP($i*16+0,"esi"),"eax");
-+	&mov	(&DWP($i*16+4,"esi"),"ebx");
-+	&add	("ecx",&DWP(8+($i*16)+8,"esp"));
-+	&adc	("edx",&DWP(8+($i*16)+12,"esp"));
-+	&mov	(&DWP($i*16+8,"esi"),"ecx");
-+	&mov	(&DWP($i*16+12,"esi"),"edx");
-+    }
-+	&add	("esp",8*(9+16+80));		# destroy frame
-+	&sub	($K512,8*80);			# rewind K
-+
-+	&cmp	("edi",&DWP(8,"esp"));		# are we done yet?
-+	&jb	(&label("loop_x86"));
-+
-+	&mov	("esp",&DWP(12,"esp"));		# restore sp
-+&function_end_A();
-+
-+&set_label("K512",64);	# Yes! I keep it in the code segment!
-+	&data_word(0xd728ae22,0x428a2f98);	# u64
-+	&data_word(0x23ef65cd,0x71374491);	# u64
-+	&data_word(0xec4d3b2f,0xb5c0fbcf);	# u64
-+	&data_word(0x8189dbbc,0xe9b5dba5);	# u64
-+	&data_word(0xf348b538,0x3956c25b);	# u64
-+	&data_word(0xb605d019,0x59f111f1);	# u64
-+	&data_word(0xaf194f9b,0x923f82a4);	# u64
-+	&data_word(0xda6d8118,0xab1c5ed5);	# u64
-+	&data_word(0xa3030242,0xd807aa98);	# u64
-+	&data_word(0x45706fbe,0x12835b01);	# u64
-+	&data_word(0x4ee4b28c,0x243185be);	# u64
-+	&data_word(0xd5ffb4e2,0x550c7dc3);	# u64
-+	&data_word(0xf27b896f,0x72be5d74);	# u64
-+	&data_word(0x3b1696b1,0x80deb1fe);	# u64
-+	&data_word(0x25c71235,0x9bdc06a7);	# u64
-+	&data_word(0xcf692694,0xc19bf174);	# u64
-+	&data_word(0x9ef14ad2,0xe49b69c1);	# u64
-+	&data_word(0x384f25e3,0xefbe4786);	# u64
-+	&data_word(0x8b8cd5b5,0x0fc19dc6);	# u64
-+	&data_word(0x77ac9c65,0x240ca1cc);	# u64
-+	&data_word(0x592b0275,0x2de92c6f);	# u64
-+	&data_word(0x6ea6e483,0x4a7484aa);	# u64
-+	&data_word(0xbd41fbd4,0x5cb0a9dc);	# u64
-+	&data_word(0x831153b5,0x76f988da);	# u64
-+	&data_word(0xee66dfab,0x983e5152);	# u64
-+	&data_word(0x2db43210,0xa831c66d);	# u64
-+	&data_word(0x98fb213f,0xb00327c8);	# u64
-+	&data_word(0xbeef0ee4,0xbf597fc7);	# u64
-+	&data_word(0x3da88fc2,0xc6e00bf3);	# u64
-+	&data_word(0x930aa725,0xd5a79147);	# u64
-+	&data_word(0xe003826f,0x06ca6351);	# u64
-+	&data_word(0x0a0e6e70,0x14292967);	# u64
-+	&data_word(0x46d22ffc,0x27b70a85);	# u64
-+	&data_word(0x5c26c926,0x2e1b2138);	# u64
-+	&data_word(0x5ac42aed,0x4d2c6dfc);	# u64
-+	&data_word(0x9d95b3df,0x53380d13);	# u64
-+	&data_word(0x8baf63de,0x650a7354);	# u64
-+	&data_word(0x3c77b2a8,0x766a0abb);	# u64
-+	&data_word(0x47edaee6,0x81c2c92e);	# u64
-+	&data_word(0x1482353b,0x92722c85);	# u64
-+	&data_word(0x4cf10364,0xa2bfe8a1);	# u64
-+	&data_word(0xbc423001,0xa81a664b);	# u64
-+	&data_word(0xd0f89791,0xc24b8b70);	# u64
-+	&data_word(0x0654be30,0xc76c51a3);	# u64
-+	&data_word(0xd6ef5218,0xd192e819);	# u64
-+	&data_word(0x5565a910,0xd6990624);	# u64
-+	&data_word(0x5771202a,0xf40e3585);	# u64
-+	&data_word(0x32bbd1b8,0x106aa070);	# u64
-+	&data_word(0xb8d2d0c8,0x19a4c116);	# u64
-+	&data_word(0x5141ab53,0x1e376c08);	# u64
-+	&data_word(0xdf8eeb99,0x2748774c);	# u64
-+	&data_word(0xe19b48a8,0x34b0bcb5);	# u64
-+	&data_word(0xc5c95a63,0x391c0cb3);	# u64
-+	&data_word(0xe3418acb,0x4ed8aa4a);	# u64
-+	&data_word(0x7763e373,0x5b9cca4f);	# u64
-+	&data_word(0xd6b2b8a3,0x682e6ff3);	# u64
-+	&data_word(0x5defb2fc,0x748f82ee);	# u64
-+	&data_word(0x43172f60,0x78a5636f);	# u64
-+	&data_word(0xa1f0ab72,0x84c87814);	# u64
-+	&data_word(0x1a6439ec,0x8cc70208);	# u64
-+	&data_word(0x23631e28,0x90befffa);	# u64
-+	&data_word(0xde82bde9,0xa4506ceb);	# u64
-+	&data_word(0xb2c67915,0xbef9a3f7);	# u64
-+	&data_word(0xe372532b,0xc67178f2);	# u64
-+	&data_word(0xea26619c,0xca273ece);	# u64
-+	&data_word(0x21c0c207,0xd186b8c7);	# u64
-+	&data_word(0xcde0eb1e,0xeada7dd6);	# u64
-+	&data_word(0xee6ed178,0xf57d4f7f);	# u64
-+	&data_word(0x72176fba,0x06f067aa);	# u64
-+	&data_word(0xa2c898a6,0x0a637dc5);	# u64
-+	&data_word(0xbef90dae,0x113f9804);	# u64
-+	&data_word(0x131c471b,0x1b710b35);	# u64
-+	&data_word(0x23047d84,0x28db77f5);	# u64
-+	&data_word(0x40c72493,0x32caab7b);	# u64
-+	&data_word(0x15c9bebc,0x3c9ebe0a);	# u64
-+	&data_word(0x9c100d4c,0x431d67c4);	# u64
-+	&data_word(0xcb3e42b6,0x4cc5d4be);	# u64
-+	&data_word(0xfc657e2a,0x597f299c);	# u64
-+	&data_word(0x3ad6faec,0x5fcb6fab);	# u64
-+	&data_word(0x4a475817,0x6c44198c);	# u64
-+
-+	&data_word(0x04050607,0x00010203);	# byte swap
-+	&data_word(0x0c0d0e0f,0x08090a0b);	# mask
-+&function_end_B("sha512_block_data_order");
-+&asciz("SHA512 block transform for x86, CRYPTOGAMS by ");
-+
-+&asm_finish();
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-armv4.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-armv4.pl
-new file mode 100644
-index 0000000..22b5a9d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-armv4.pl
-@@ -0,0 +1,668 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+#
-+# Permission to use under GPL terms is granted.
-+# ====================================================================
-+
-+# SHA512 block procedure for ARMv4. September 2007.
-+
-+# This code is ~4.5 (four and a half) times faster than code generated
-+# by gcc 3.4 and it spends ~72 clock cycles per byte [on single-issue
-+# Xscale PXA250 core].
-+#
-+# July 2010.
-+#
-+# Rescheduling for dual-issue pipeline resulted in 6% improvement on
-+# Cortex A8 core and ~40 cycles per processed byte.
-+
-+# February 2011.
-+#
-+# Profiler-assisted and platform-specific optimization resulted in 7%
-+# improvement on Coxtex A8 core and ~38 cycles per byte.
-+
-+# March 2011.
-+#
-+# Add NEON implementation. On Cortex A8 it was measured to process
-+# one byte in 23.3 cycles or ~60% faster than integer-only code.
-+
-+# August 2012.
-+#
-+# Improve NEON performance by 12% on Snapdragon S4. In absolute
-+# terms it's 22.6 cycles per byte, which is disappointing result.
-+# Technical writers asserted that 3-way S4 pipeline can sustain
-+# multiple NEON instructions per cycle, but dual NEON issue could
-+# not be observed, see http://www.openssl.org/~appro/Snapdragon-S4.html
-+# for further details. On side note Cortex-A15 processes one byte in
-+# 16 cycles.
-+
-+# Byte order [in]dependence. =========================================
-+#
-+# Originally caller was expected to maintain specific *dword* order in
-+# h[0-7], namely with most significant dword at *lower* address, which
-+# was reflected in below two parameters as 0 and 4. Now caller is
-+# expected to maintain native byte order for whole 64-bit values.
-+$hi="HI";
-+$lo="LO";
-+# ====================================================================
-+
-+$flavour = shift;
-+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
-+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
-+
-+if ($flavour && $flavour ne "void") {
-+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+    die "can't locate arm-xlate.pl";
-+
-+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-+} else {
-+    open STDOUT,">$output";
-+}
-+
-+$ctx="r0";	# parameter block
-+$inp="r1";
-+$len="r2";
-+
-+$Tlo="r3";
-+$Thi="r4";
-+$Alo="r5";
-+$Ahi="r6";
-+$Elo="r7";
-+$Ehi="r8";
-+$t0="r9";
-+$t1="r10";
-+$t2="r11";
-+$t3="r12";
-+############	r13 is stack pointer
-+$Ktbl="r14";
-+############	r15 is program counter
-+
-+$Aoff=8*0;
-+$Boff=8*1;
-+$Coff=8*2;
-+$Doff=8*3;
-+$Eoff=8*4;
-+$Foff=8*5;
-+$Goff=8*6;
-+$Hoff=8*7;
-+$Xoff=8*8;
-+
-+sub BODY_00_15() {
-+my $magic = shift;
-+$code.=<<___;
-+	@ Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18)  ^ ROTR((x),41))
-+	@ LO		lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
-+	@ HI		hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
-+	mov	$t0,$Elo,lsr#14
-+	str	$Tlo,[sp,#$Xoff+0]
-+	mov	$t1,$Ehi,lsr#14
-+	str	$Thi,[sp,#$Xoff+4]
-+	eor	$t0,$t0,$Ehi,lsl#18
-+	ldr	$t2,[sp,#$Hoff+0]	@ h.lo
-+	eor	$t1,$t1,$Elo,lsl#18
-+	ldr	$t3,[sp,#$Hoff+4]	@ h.hi
-+	eor	$t0,$t0,$Elo,lsr#18
-+	eor	$t1,$t1,$Ehi,lsr#18
-+	eor	$t0,$t0,$Ehi,lsl#14
-+	eor	$t1,$t1,$Elo,lsl#14
-+	eor	$t0,$t0,$Ehi,lsr#9
-+	eor	$t1,$t1,$Elo,lsr#9
-+	eor	$t0,$t0,$Elo,lsl#23
-+	eor	$t1,$t1,$Ehi,lsl#23	@ Sigma1(e)
-+	adds	$Tlo,$Tlo,$t0
-+	ldr	$t0,[sp,#$Foff+0]	@ f.lo
-+	adc	$Thi,$Thi,$t1		@ T += Sigma1(e)
-+	ldr	$t1,[sp,#$Foff+4]	@ f.hi
-+	adds	$Tlo,$Tlo,$t2
-+	ldr	$t2,[sp,#$Goff+0]	@ g.lo
-+	adc	$Thi,$Thi,$t3		@ T += h
-+	ldr	$t3,[sp,#$Goff+4]	@ g.hi
-+
-+	eor	$t0,$t0,$t2
-+	str	$Elo,[sp,#$Eoff+0]
-+	eor	$t1,$t1,$t3
-+	str	$Ehi,[sp,#$Eoff+4]
-+	and	$t0,$t0,$Elo
-+	str	$Alo,[sp,#$Aoff+0]
-+	and	$t1,$t1,$Ehi
-+	str	$Ahi,[sp,#$Aoff+4]
-+	eor	$t0,$t0,$t2
-+	ldr	$t2,[$Ktbl,#$lo]	@ K[i].lo
-+	eor	$t1,$t1,$t3		@ Ch(e,f,g)
-+	ldr	$t3,[$Ktbl,#$hi]	@ K[i].hi
-+
-+	adds	$Tlo,$Tlo,$t0
-+	ldr	$Elo,[sp,#$Doff+0]	@ d.lo
-+	adc	$Thi,$Thi,$t1		@ T += Ch(e,f,g)
-+	ldr	$Ehi,[sp,#$Doff+4]	@ d.hi
-+	adds	$Tlo,$Tlo,$t2
-+	and	$t0,$t2,#0xff
-+	adc	$Thi,$Thi,$t3		@ T += K[i]
-+	adds	$Elo,$Elo,$Tlo
-+	ldr	$t2,[sp,#$Boff+0]	@ b.lo
-+	adc	$Ehi,$Ehi,$Thi		@ d += T
-+	teq	$t0,#$magic
-+
-+	ldr	$t3,[sp,#$Coff+0]	@ c.lo
-+#if __ARM_ARCH__>=7
-+	it	eq			@ Thumb2 thing, sanity check in ARM
-+#endif
-+	orreq	$Ktbl,$Ktbl,#1
-+	@ Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
-+	@ LO		lo>>28^hi<<4  ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
-+	@ HI		hi>>28^lo<<4  ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
-+	mov	$t0,$Alo,lsr#28
-+	mov	$t1,$Ahi,lsr#28
-+	eor	$t0,$t0,$Ahi,lsl#4
-+	eor	$t1,$t1,$Alo,lsl#4
-+	eor	$t0,$t0,$Ahi,lsr#2
-+	eor	$t1,$t1,$Alo,lsr#2
-+	eor	$t0,$t0,$Alo,lsl#30
-+	eor	$t1,$t1,$Ahi,lsl#30
-+	eor	$t0,$t0,$Ahi,lsr#7
-+	eor	$t1,$t1,$Alo,lsr#7
-+	eor	$t0,$t0,$Alo,lsl#25
-+	eor	$t1,$t1,$Ahi,lsl#25	@ Sigma0(a)
-+	adds	$Tlo,$Tlo,$t0
-+	and	$t0,$Alo,$t2
-+	adc	$Thi,$Thi,$t1		@ T += Sigma0(a)
-+
-+	ldr	$t1,[sp,#$Boff+4]	@ b.hi
-+	orr	$Alo,$Alo,$t2
-+	ldr	$t2,[sp,#$Coff+4]	@ c.hi
-+	and	$Alo,$Alo,$t3
-+	and	$t3,$Ahi,$t1
-+	orr	$Ahi,$Ahi,$t1
-+	orr	$Alo,$Alo,$t0		@ Maj(a,b,c).lo
-+	and	$Ahi,$Ahi,$t2
-+	adds	$Alo,$Alo,$Tlo
-+	orr	$Ahi,$Ahi,$t3		@ Maj(a,b,c).hi
-+	sub	sp,sp,#8
-+	adc	$Ahi,$Ahi,$Thi		@ h += T
-+	tst	$Ktbl,#1
-+	add	$Ktbl,$Ktbl,#8
-+___
-+}
-+$code=<<___;
-+#ifndef __KERNEL__
-+# include "arm_arch.h"
-+# define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
-+# define VFP_ABI_POP	vldmia	sp!,{d8-d15}
-+#else
-+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
-+# define __ARM_MAX_ARCH__ 7
-+# define VFP_ABI_PUSH
-+# define VFP_ABI_POP
-+#endif
-+
-+#ifdef __ARMEL__
-+# define LO 0
-+# define HI 4
-+# define WORD64(hi0,lo0,hi1,lo1)	.word	lo0,hi0, lo1,hi1
-+#else
-+# define HI 0
-+# define LO 4
-+# define WORD64(hi0,lo0,hi1,lo1)	.word	hi0,lo0, hi1,lo1
-+#endif
-+
-+.text
-+#if defined(__thumb2__)
-+.syntax unified
-+.thumb
-+# define adrl adr
-+#else
-+.code	32
-+#endif
-+
-+.type	K512,%object
-+.align	5
-+K512:
-+WORD64(0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd)
-+WORD64(0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc)
-+WORD64(0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019)
-+WORD64(0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118)
-+WORD64(0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe)
-+WORD64(0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2)
-+WORD64(0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1)
-+WORD64(0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694)
-+WORD64(0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3)
-+WORD64(0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65)
-+WORD64(0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483)
-+WORD64(0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5)
-+WORD64(0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210)
-+WORD64(0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4)
-+WORD64(0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725)
-+WORD64(0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70)
-+WORD64(0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926)
-+WORD64(0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df)
-+WORD64(0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8)
-+WORD64(0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b)
-+WORD64(0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001)
-+WORD64(0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30)
-+WORD64(0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910)
-+WORD64(0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8)
-+WORD64(0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53)
-+WORD64(0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8)
-+WORD64(0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb)
-+WORD64(0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3)
-+WORD64(0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60)
-+WORD64(0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec)
-+WORD64(0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9)
-+WORD64(0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b)
-+WORD64(0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207)
-+WORD64(0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178)
-+WORD64(0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6)
-+WORD64(0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b)
-+WORD64(0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493)
-+WORD64(0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c)
-+WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a)
-+WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817)
-+.size	K512,.-K512
-+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
-+.LOPENSSL_armcap:
-+.word	OPENSSL_armcap_P-.Lsha512_block_data_order
-+.skip	32-4
-+#else
-+.skip	32
-+#endif
-+
-+.global	sha512_block_data_order
-+.type	sha512_block_data_order,%function
-+sha512_block_data_order:
-+.Lsha512_block_data_order:
-+#if __ARM_ARCH__<7 && !defined(__thumb2__)
-+	sub	r3,pc,#8		@ sha512_block_data_order
-+#else
-+	adr	r3,.Lsha512_block_data_order
-+#endif
-+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
-+	ldr	r12,.LOPENSSL_armcap
-+	ldr	r12,[r3,r12]		@ OPENSSL_armcap_P
-+#ifdef	__APPLE__
-+	ldr	r12,[r12]
-+#endif
-+	tst	r12,#ARMV7_NEON
-+	bne	.LNEON
-+#endif
-+	add	$len,$inp,$len,lsl#7	@ len to point at the end of inp
-+	stmdb	sp!,{r4-r12,lr}
-+	sub	$Ktbl,r3,#672		@ K512
-+	sub	sp,sp,#9*8
-+
-+	ldr	$Elo,[$ctx,#$Eoff+$lo]
-+	ldr	$Ehi,[$ctx,#$Eoff+$hi]
-+	ldr	$t0, [$ctx,#$Goff+$lo]
-+	ldr	$t1, [$ctx,#$Goff+$hi]
-+	ldr	$t2, [$ctx,#$Hoff+$lo]
-+	ldr	$t3, [$ctx,#$Hoff+$hi]
-+.Loop:
-+	str	$t0, [sp,#$Goff+0]
-+	str	$t1, [sp,#$Goff+4]
-+	str	$t2, [sp,#$Hoff+0]
-+	str	$t3, [sp,#$Hoff+4]
-+	ldr	$Alo,[$ctx,#$Aoff+$lo]
-+	ldr	$Ahi,[$ctx,#$Aoff+$hi]
-+	ldr	$Tlo,[$ctx,#$Boff+$lo]
-+	ldr	$Thi,[$ctx,#$Boff+$hi]
-+	ldr	$t0, [$ctx,#$Coff+$lo]
-+	ldr	$t1, [$ctx,#$Coff+$hi]
-+	ldr	$t2, [$ctx,#$Doff+$lo]
-+	ldr	$t3, [$ctx,#$Doff+$hi]
-+	str	$Tlo,[sp,#$Boff+0]
-+	str	$Thi,[sp,#$Boff+4]
-+	str	$t0, [sp,#$Coff+0]
-+	str	$t1, [sp,#$Coff+4]
-+	str	$t2, [sp,#$Doff+0]
-+	str	$t3, [sp,#$Doff+4]
-+	ldr	$Tlo,[$ctx,#$Foff+$lo]
-+	ldr	$Thi,[$ctx,#$Foff+$hi]
-+	str	$Tlo,[sp,#$Foff+0]
-+	str	$Thi,[sp,#$Foff+4]
-+
-+.L00_15:
-+#if __ARM_ARCH__<7
-+	ldrb	$Tlo,[$inp,#7]
-+	ldrb	$t0, [$inp,#6]
-+	ldrb	$t1, [$inp,#5]
-+	ldrb	$t2, [$inp,#4]
-+	ldrb	$Thi,[$inp,#3]
-+	ldrb	$t3, [$inp,#2]
-+	orr	$Tlo,$Tlo,$t0,lsl#8
-+	ldrb	$t0, [$inp,#1]
-+	orr	$Tlo,$Tlo,$t1,lsl#16
-+	ldrb	$t1, [$inp],#8
-+	orr	$Tlo,$Tlo,$t2,lsl#24
-+	orr	$Thi,$Thi,$t3,lsl#8
-+	orr	$Thi,$Thi,$t0,lsl#16
-+	orr	$Thi,$Thi,$t1,lsl#24
-+#else
-+	ldr	$Tlo,[$inp,#4]
-+	ldr	$Thi,[$inp],#8
-+#ifdef __ARMEL__
-+	rev	$Tlo,$Tlo
-+	rev	$Thi,$Thi
-+#endif
-+#endif
-+___
-+	&BODY_00_15(0x94);
-+$code.=<<___;
-+	tst	$Ktbl,#1
-+	beq	.L00_15
-+	ldr	$t0,[sp,#`$Xoff+8*(16-1)`+0]
-+	ldr	$t1,[sp,#`$Xoff+8*(16-1)`+4]
-+	bic	$Ktbl,$Ktbl,#1
-+.L16_79:
-+	@ sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
-+	@ LO		lo>>1^hi<<31  ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
-+	@ HI		hi>>1^lo<<31  ^ hi>>8^lo<<24 ^ hi>>7
-+	mov	$Tlo,$t0,lsr#1
-+	ldr	$t2,[sp,#`$Xoff+8*(16-14)`+0]
-+	mov	$Thi,$t1,lsr#1
-+	ldr	$t3,[sp,#`$Xoff+8*(16-14)`+4]
-+	eor	$Tlo,$Tlo,$t1,lsl#31
-+	eor	$Thi,$Thi,$t0,lsl#31
-+	eor	$Tlo,$Tlo,$t0,lsr#8
-+	eor	$Thi,$Thi,$t1,lsr#8
-+	eor	$Tlo,$Tlo,$t1,lsl#24
-+	eor	$Thi,$Thi,$t0,lsl#24
-+	eor	$Tlo,$Tlo,$t0,lsr#7
-+	eor	$Thi,$Thi,$t1,lsr#7
-+	eor	$Tlo,$Tlo,$t1,lsl#25
-+
-+	@ sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
-+	@ LO		lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26
-+	@ HI		hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6
-+	mov	$t0,$t2,lsr#19
-+	mov	$t1,$t3,lsr#19
-+	eor	$t0,$t0,$t3,lsl#13
-+	eor	$t1,$t1,$t2,lsl#13
-+	eor	$t0,$t0,$t3,lsr#29
-+	eor	$t1,$t1,$t2,lsr#29
-+	eor	$t0,$t0,$t2,lsl#3
-+	eor	$t1,$t1,$t3,lsl#3
-+	eor	$t0,$t0,$t2,lsr#6
-+	eor	$t1,$t1,$t3,lsr#6
-+	ldr	$t2,[sp,#`$Xoff+8*(16-9)`+0]
-+	eor	$t0,$t0,$t3,lsl#26
-+
-+	ldr	$t3,[sp,#`$Xoff+8*(16-9)`+4]
-+	adds	$Tlo,$Tlo,$t0
-+	ldr	$t0,[sp,#`$Xoff+8*16`+0]
-+	adc	$Thi,$Thi,$t1
-+
-+	ldr	$t1,[sp,#`$Xoff+8*16`+4]
-+	adds	$Tlo,$Tlo,$t2
-+	adc	$Thi,$Thi,$t3
-+	adds	$Tlo,$Tlo,$t0
-+	adc	$Thi,$Thi,$t1
-+___
-+	&BODY_00_15(0x17);
-+$code.=<<___;
-+#if __ARM_ARCH__>=7
-+	ittt	eq			@ Thumb2 thing, sanity check in ARM
-+#endif
-+	ldreq	$t0,[sp,#`$Xoff+8*(16-1)`+0]
-+	ldreq	$t1,[sp,#`$Xoff+8*(16-1)`+4]
-+	beq	.L16_79
-+	bic	$Ktbl,$Ktbl,#1
-+
-+	ldr	$Tlo,[sp,#$Boff+0]
-+	ldr	$Thi,[sp,#$Boff+4]
-+	ldr	$t0, [$ctx,#$Aoff+$lo]
-+	ldr	$t1, [$ctx,#$Aoff+$hi]
-+	ldr	$t2, [$ctx,#$Boff+$lo]
-+	ldr	$t3, [$ctx,#$Boff+$hi]
-+	adds	$t0,$Alo,$t0
-+	str	$t0, [$ctx,#$Aoff+$lo]
-+	adc	$t1,$Ahi,$t1
-+	str	$t1, [$ctx,#$Aoff+$hi]
-+	adds	$t2,$Tlo,$t2
-+	str	$t2, [$ctx,#$Boff+$lo]
-+	adc	$t3,$Thi,$t3
-+	str	$t3, [$ctx,#$Boff+$hi]
-+
-+	ldr	$Alo,[sp,#$Coff+0]
-+	ldr	$Ahi,[sp,#$Coff+4]
-+	ldr	$Tlo,[sp,#$Doff+0]
-+	ldr	$Thi,[sp,#$Doff+4]
-+	ldr	$t0, [$ctx,#$Coff+$lo]
-+	ldr	$t1, [$ctx,#$Coff+$hi]
-+	ldr	$t2, [$ctx,#$Doff+$lo]
-+	ldr	$t3, [$ctx,#$Doff+$hi]
-+	adds	$t0,$Alo,$t0
-+	str	$t0, [$ctx,#$Coff+$lo]
-+	adc	$t1,$Ahi,$t1
-+	str	$t1, [$ctx,#$Coff+$hi]
-+	adds	$t2,$Tlo,$t2
-+	str	$t2, [$ctx,#$Doff+$lo]
-+	adc	$t3,$Thi,$t3
-+	str	$t3, [$ctx,#$Doff+$hi]
-+
-+	ldr	$Tlo,[sp,#$Foff+0]
-+	ldr	$Thi,[sp,#$Foff+4]
-+	ldr	$t0, [$ctx,#$Eoff+$lo]
-+	ldr	$t1, [$ctx,#$Eoff+$hi]
-+	ldr	$t2, [$ctx,#$Foff+$lo]
-+	ldr	$t3, [$ctx,#$Foff+$hi]
-+	adds	$Elo,$Elo,$t0
-+	str	$Elo,[$ctx,#$Eoff+$lo]
-+	adc	$Ehi,$Ehi,$t1
-+	str	$Ehi,[$ctx,#$Eoff+$hi]
-+	adds	$t2,$Tlo,$t2
-+	str	$t2, [$ctx,#$Foff+$lo]
-+	adc	$t3,$Thi,$t3
-+	str	$t3, [$ctx,#$Foff+$hi]
-+
-+	ldr	$Alo,[sp,#$Goff+0]
-+	ldr	$Ahi,[sp,#$Goff+4]
-+	ldr	$Tlo,[sp,#$Hoff+0]
-+	ldr	$Thi,[sp,#$Hoff+4]
-+	ldr	$t0, [$ctx,#$Goff+$lo]
-+	ldr	$t1, [$ctx,#$Goff+$hi]
-+	ldr	$t2, [$ctx,#$Hoff+$lo]
-+	ldr	$t3, [$ctx,#$Hoff+$hi]
-+	adds	$t0,$Alo,$t0
-+	str	$t0, [$ctx,#$Goff+$lo]
-+	adc	$t1,$Ahi,$t1
-+	str	$t1, [$ctx,#$Goff+$hi]
-+	adds	$t2,$Tlo,$t2
-+	str	$t2, [$ctx,#$Hoff+$lo]
-+	adc	$t3,$Thi,$t3
-+	str	$t3, [$ctx,#$Hoff+$hi]
-+
-+	add	sp,sp,#640
-+	sub	$Ktbl,$Ktbl,#640
-+
-+	teq	$inp,$len
-+	bne	.Loop
-+
-+	add	sp,sp,#8*9		@ destroy frame
-+#if __ARM_ARCH__>=5
-+	ldmia	sp!,{r4-r12,pc}
-+#else
-+	ldmia	sp!,{r4-r12,lr}
-+	tst	lr,#1
-+	moveq	pc,lr			@ be binary compatible with V4, yet
-+	bx	lr			@ interoperable with Thumb ISA:-)
-+#endif
-+.size	sha512_block_data_order,.-sha512_block_data_order
-+___
-+
-+{
-+my @Sigma0=(28,34,39);
-+my @Sigma1=(14,18,41);
-+my @sigma0=(1, 8, 7);
-+my @sigma1=(19,61,6);
-+
-+my $Ktbl="r3";
-+my $cnt="r12";	# volatile register known as ip, intra-procedure-call scratch
-+
-+my @X=map("d$_",(0..15));
-+my @V=($A,$B,$C,$D,$E,$F,$G,$H)=map("d$_",(16..23));
-+
-+sub NEON_00_15() {
-+my $i=shift;
-+my ($a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+my ($t0,$t1,$t2,$T1,$K,$Ch,$Maj)=map("d$_",(24..31));	# temps
-+
-+$code.=<<___ if ($i<16 || $i&1);
-+	vshr.u64	$t0,$e,#@Sigma1[0]	@ $i
-+#if $i<16
-+	vld1.64		{@X[$i%16]},[$inp]!	@ handles unaligned
-+#endif
-+	vshr.u64	$t1,$e,#@Sigma1[1]
-+#if $i>0
-+	 vadd.i64	$a,$Maj			@ h+=Maj from the past
-+#endif
-+	vshr.u64	$t2,$e,#@Sigma1[2]
-+___
-+$code.=<<___;
-+	vld1.64		{$K},[$Ktbl,:64]!	@ K[i++]
-+	vsli.64		$t0,$e,#`64-@Sigma1[0]`
-+	vsli.64		$t1,$e,#`64-@Sigma1[1]`
-+	vmov		$Ch,$e
-+	vsli.64		$t2,$e,#`64-@Sigma1[2]`
-+#if $i<16 && defined(__ARMEL__)
-+	vrev64.8	@X[$i],@X[$i]
-+#endif
-+	veor		$t1,$t0
-+	vbsl		$Ch,$f,$g		@ Ch(e,f,g)
-+	vshr.u64	$t0,$a,#@Sigma0[0]
-+	veor		$t2,$t1			@ Sigma1(e)
-+	vadd.i64	$T1,$Ch,$h
-+	vshr.u64	$t1,$a,#@Sigma0[1]
-+	vsli.64		$t0,$a,#`64-@Sigma0[0]`
-+	vadd.i64	$T1,$t2
-+	vshr.u64	$t2,$a,#@Sigma0[2]
-+	vadd.i64	$K,@X[$i%16]
-+	vsli.64		$t1,$a,#`64-@Sigma0[1]`
-+	veor		$Maj,$a,$b
-+	vsli.64		$t2,$a,#`64-@Sigma0[2]`
-+	veor		$h,$t0,$t1
-+	vadd.i64	$T1,$K
-+	vbsl		$Maj,$c,$b		@ Maj(a,b,c)
-+	veor		$h,$t2			@ Sigma0(a)
-+	vadd.i64	$d,$T1
-+	vadd.i64	$Maj,$T1
-+	@ vadd.i64	$h,$Maj
-+___
-+}
-+
-+sub NEON_16_79() {
-+my $i=shift;
-+
-+if ($i&1)	{ &NEON_00_15($i,@_); return; }
-+
-+# 2x-vectorized, therefore runs every 2nd round
-+my @X=map("q$_",(0..7));			# view @X as 128-bit vector
-+my ($t0,$t1,$s0,$s1) = map("q$_",(12..15));	# temps
-+my ($d0,$d1,$d2) = map("d$_",(24..26));		# temps from NEON_00_15
-+my $e=@_[4];					# $e from NEON_00_15
-+$i /= 2;
-+$code.=<<___;
-+	vshr.u64	$t0,@X[($i+7)%8],#@sigma1[0]
-+	vshr.u64	$t1,@X[($i+7)%8],#@sigma1[1]
-+	 vadd.i64	@_[0],d30			@ h+=Maj from the past
-+	vshr.u64	$s1,@X[($i+7)%8],#@sigma1[2]
-+	vsli.64		$t0,@X[($i+7)%8],#`64-@sigma1[0]`
-+	vext.8		$s0,@X[$i%8],@X[($i+1)%8],#8	@ X[i+1]
-+	vsli.64		$t1,@X[($i+7)%8],#`64-@sigma1[1]`
-+	veor		$s1,$t0
-+	vshr.u64	$t0,$s0,#@sigma0[0]
-+	veor		$s1,$t1				@ sigma1(X[i+14])
-+	vshr.u64	$t1,$s0,#@sigma0[1]
-+	vadd.i64	@X[$i%8],$s1
-+	vshr.u64	$s1,$s0,#@sigma0[2]
-+	vsli.64		$t0,$s0,#`64-@sigma0[0]`
-+	vsli.64		$t1,$s0,#`64-@sigma0[1]`
-+	vext.8		$s0,@X[($i+4)%8],@X[($i+5)%8],#8	@ X[i+9]
-+	veor		$s1,$t0
-+	vshr.u64	$d0,$e,#@Sigma1[0]		@ from NEON_00_15
-+	vadd.i64	@X[$i%8],$s0
-+	vshr.u64	$d1,$e,#@Sigma1[1]		@ from NEON_00_15
-+	veor		$s1,$t1				@ sigma0(X[i+1])
-+	vshr.u64	$d2,$e,#@Sigma1[2]		@ from NEON_00_15
-+	vadd.i64	@X[$i%8],$s1
-+___
-+	&NEON_00_15(2*$i,@_);
-+}
-+
-+$code.=<<___;
-+#if __ARM_MAX_ARCH__>=7
-+.arch	armv7-a
-+.fpu	neon
-+
-+.global	sha512_block_data_order_neon
-+.type	sha512_block_data_order_neon,%function
-+.align	4
-+sha512_block_data_order_neon:
-+.LNEON:
-+	dmb				@ errata #451034 on early Cortex A8
-+	add	$len,$inp,$len,lsl#7	@ len to point at the end of inp
-+	adr	$Ktbl,K512
-+	VFP_ABI_PUSH
-+	vldmia	$ctx,{$A-$H}		@ load context
-+.Loop_neon:
-+___
-+for($i=0;$i<16;$i++)	{ &NEON_00_15($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	mov		$cnt,#4
-+.L16_79_neon:
-+	subs		$cnt,#1
-+___
-+for(;$i<32;$i++)	{ &NEON_16_79($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	bne		.L16_79_neon
-+
-+	 vadd.i64	$A,d30		@ h+=Maj from the past
-+	vldmia		$ctx,{d24-d31}	@ load context to temp
-+	vadd.i64	q8,q12		@ vectorized accumulate
-+	vadd.i64	q9,q13
-+	vadd.i64	q10,q14
-+	vadd.i64	q11,q15
-+	vstmia		$ctx,{$A-$H}	@ save context
-+	teq		$inp,$len
-+	sub		$Ktbl,#640	@ rewind K512
-+	bne		.Loop_neon
-+
-+	VFP_ABI_POP
-+	ret				@ bx lr
-+.size	sha512_block_data_order_neon,.-sha512_block_data_order_neon
-+#endif
-+___
-+}
-+$code.=<<___;
-+.asciz	"SHA512 block transform for ARMv4/NEON, CRYPTOGAMS by "
-+.align	2
-+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
-+.comm	OPENSSL_armcap_P,4,4
-+#endif
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
-+$code =~ s/\bret\b/bx	lr/gm;
-+
-+open SELF,$0;
-+while() {
-+	next if (/^#!/);
-+	last if (!s/^#/@/ and !/^$/);
-+	print;
-+}
-+close SELF;
-+
-+print $code;
-+close STDOUT; # enforce flush
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-armv8.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-armv8.pl
-new file mode 100644
-index 0000000..c1aaf77
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-armv8.pl
-@@ -0,0 +1,446 @@
-+#! /usr/bin/env perl
-+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# SHA256/512 for ARMv8.
-+#
-+# Performance in cycles per processed byte and improvement coefficient
-+# over code generated with "default" compiler:
-+#
-+#		SHA256-hw	SHA256(*)	SHA512
-+# Apple A7	1.97		10.5 (+33%)	6.73 (-1%(**))
-+# Cortex-A53	2.38		15.5 (+115%)	10.0 (+150%(***))
-+# Cortex-A57	2.31		11.6 (+86%)	7.51 (+260%(***))
-+# Denver	2.01		10.5 (+26%)	6.70 (+8%)
-+# X-Gene			20.0 (+100%)	12.8 (+300%(***))
-+# Mongoose	2.36		13.0 (+50%)	8.36 (+33%)
-+# 
-+# (*)	Software SHA256 results are of lesser relevance, presented
-+#	mostly for informational purposes.
-+# (**)	The result is a trade-off: it's possible to improve it by
-+#	10% (or by 1 cycle per round), but at the cost of 20% loss
-+#	on Cortex-A53 (or by 4 cycles per round).
-+# (***)	Super-impressive coefficients over gcc-generated code are
-+#	indication of some compiler "pathology", most notably code
-+#	generated with -mgeneral-regs-only is significanty faster
-+#	and the gap is only 40-90%.
-+
-+$flavour=shift;
-+$output=shift;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-+die "can't locate arm-xlate.pl";
-+
-+open OUT,"| \"$^X\" $xlate $flavour $output";
-+*STDOUT=*OUT;
-+
-+if ($output =~ /512/) {
-+	$BITS=512;
-+	$SZ=8;
-+	@Sigma0=(28,34,39);
-+	@Sigma1=(14,18,41);
-+	@sigma0=(1,  8, 7);
-+	@sigma1=(19,61, 6);
-+	$rounds=80;
-+	$reg_t="x";
-+} else {
-+	$BITS=256;
-+	$SZ=4;
-+	@Sigma0=( 2,13,22);
-+	@Sigma1=( 6,11,25);
-+	@sigma0=( 7,18, 3);
-+	@sigma1=(17,19,10);
-+	$rounds=64;
-+	$reg_t="w";
-+}
-+
-+$func="sha${BITS}_block_data_order";
-+
-+($ctx,$inp,$num,$Ktbl)=map("x$_",(0..2,30));
-+
-+@X=map("$reg_t$_",(3..15,0..2));
-+@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("$reg_t$_",(20..27));
-+($t0,$t1,$t2,$t3)=map("$reg_t$_",(16,17,19,28));
-+
-+sub BODY_00_xx {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+my $j=($i+1)&15;
-+my ($T0,$T1,$T2)=(@X[($i-8)&15],@X[($i-9)&15],@X[($i-10)&15]);
-+   $T0=@X[$i+3] if ($i<11);
-+
-+$code.=<<___	if ($i<16);
-+#ifndef	__ARMEB__
-+	rev	@X[$i],@X[$i]			// $i
-+#endif
-+___
-+$code.=<<___	if ($i<13 && ($i&1));
-+	ldp	@X[$i+1],@X[$i+2],[$inp],#2*$SZ
-+___
-+$code.=<<___	if ($i==13);
-+	ldp	@X[14],@X[15],[$inp]
-+___
-+$code.=<<___	if ($i>=14);
-+	ldr	@X[($i-11)&15],[sp,#`$SZ*(($i-11)%4)`]
-+___
-+$code.=<<___	if ($i>0 && $i<16);
-+	add	$a,$a,$t1			// h+=Sigma0(a)
-+___
-+$code.=<<___	if ($i>=11);
-+	str	@X[($i-8)&15],[sp,#`$SZ*(($i-8)%4)`]
-+___
-+# While ARMv8 specifies merged rotate-n-logical operation such as
-+# 'eor x,y,z,ror#n', it was found to negatively affect performance
-+# on Apple A7. The reason seems to be that it requires even 'y' to
-+# be available earlier. This means that such merged instruction is
-+# not necessarily best choice on critical path... On the other hand
-+# Cortex-A5x handles merged instructions much better than disjoint
-+# rotate and logical... See (**) footnote above.
-+$code.=<<___	if ($i<15);
-+	ror	$t0,$e,#$Sigma1[0]
-+	add	$h,$h,$t2			// h+=K[i]
-+	eor	$T0,$e,$e,ror#`$Sigma1[2]-$Sigma1[1]`
-+	and	$t1,$f,$e
-+	bic	$t2,$g,$e
-+	add	$h,$h,@X[$i&15]			// h+=X[i]
-+	orr	$t1,$t1,$t2			// Ch(e,f,g)
-+	eor	$t2,$a,$b			// a^b, b^c in next round
-+	eor	$t0,$t0,$T0,ror#$Sigma1[1]	// Sigma1(e)
-+	ror	$T0,$a,#$Sigma0[0]
-+	add	$h,$h,$t1			// h+=Ch(e,f,g)
-+	eor	$t1,$a,$a,ror#`$Sigma0[2]-$Sigma0[1]`
-+	add	$h,$h,$t0			// h+=Sigma1(e)
-+	and	$t3,$t3,$t2			// (b^c)&=(a^b)
-+	add	$d,$d,$h			// d+=h
-+	eor	$t3,$t3,$b			// Maj(a,b,c)
-+	eor	$t1,$T0,$t1,ror#$Sigma0[1]	// Sigma0(a)
-+	add	$h,$h,$t3			// h+=Maj(a,b,c)
-+	ldr	$t3,[$Ktbl],#$SZ		// *K++, $t2 in next round
-+	//add	$h,$h,$t1			// h+=Sigma0(a)
-+___
-+$code.=<<___	if ($i>=15);
-+	ror	$t0,$e,#$Sigma1[0]
-+	add	$h,$h,$t2			// h+=K[i]
-+	ror	$T1,@X[($j+1)&15],#$sigma0[0]
-+	and	$t1,$f,$e
-+	ror	$T2,@X[($j+14)&15],#$sigma1[0]
-+	bic	$t2,$g,$e
-+	ror	$T0,$a,#$Sigma0[0]
-+	add	$h,$h,@X[$i&15]			// h+=X[i]
-+	eor	$t0,$t0,$e,ror#$Sigma1[1]
-+	eor	$T1,$T1,@X[($j+1)&15],ror#$sigma0[1]
-+	orr	$t1,$t1,$t2			// Ch(e,f,g)
-+	eor	$t2,$a,$b			// a^b, b^c in next round
-+	eor	$t0,$t0,$e,ror#$Sigma1[2]	// Sigma1(e)
-+	eor	$T0,$T0,$a,ror#$Sigma0[1]
-+	add	$h,$h,$t1			// h+=Ch(e,f,g)
-+	and	$t3,$t3,$t2			// (b^c)&=(a^b)
-+	eor	$T2,$T2,@X[($j+14)&15],ror#$sigma1[1]
-+	eor	$T1,$T1,@X[($j+1)&15],lsr#$sigma0[2]	// sigma0(X[i+1])
-+	add	$h,$h,$t0			// h+=Sigma1(e)
-+	eor	$t3,$t3,$b			// Maj(a,b,c)
-+	eor	$t1,$T0,$a,ror#$Sigma0[2]	// Sigma0(a)
-+	eor	$T2,$T2,@X[($j+14)&15],lsr#$sigma1[2]	// sigma1(X[i+14])
-+	add	@X[$j],@X[$j],@X[($j+9)&15]
-+	add	$d,$d,$h			// d+=h
-+	add	$h,$h,$t3			// h+=Maj(a,b,c)
-+	ldr	$t3,[$Ktbl],#$SZ		// *K++, $t2 in next round
-+	add	@X[$j],@X[$j],$T1
-+	add	$h,$h,$t1			// h+=Sigma0(a)
-+	add	@X[$j],@X[$j],$T2
-+___
-+	($t2,$t3)=($t3,$t2);
-+}
-+
-+$code.=<<___;
-+#include "arm_arch.h"
-+
-+.text
-+
-+.extern	OPENSSL_armcap_P
-+.globl	$func
-+.type	$func,%function
-+.align	6
-+$func:
-+___
-+$code.=<<___	if ($SZ==4);
-+#ifdef	__ILP32__
-+	ldrsw	x16,.LOPENSSL_armcap_P
-+#else
-+	ldr	x16,.LOPENSSL_armcap_P
-+#endif
-+	adr	x17,.LOPENSSL_armcap_P
-+	add	x16,x16,x17
-+	ldr	w16,[x16]
-+	tst	w16,#ARMV8_SHA256
-+	b.ne	.Lv8_entry
-+___
-+$code.=<<___;
-+	stp	x29,x30,[sp,#-128]!
-+	add	x29,sp,#0
-+
-+	stp	x19,x20,[sp,#16]
-+	stp	x21,x22,[sp,#32]
-+	stp	x23,x24,[sp,#48]
-+	stp	x25,x26,[sp,#64]
-+	stp	x27,x28,[sp,#80]
-+	sub	sp,sp,#4*$SZ
-+
-+	ldp	$A,$B,[$ctx]				// load context
-+	ldp	$C,$D,[$ctx,#2*$SZ]
-+	ldp	$E,$F,[$ctx,#4*$SZ]
-+	add	$num,$inp,$num,lsl#`log(16*$SZ)/log(2)`	// end of input
-+	ldp	$G,$H,[$ctx,#6*$SZ]
-+	adr	$Ktbl,.LK$BITS
-+	stp	$ctx,$num,[x29,#96]
-+
-+.Loop:
-+	ldp	@X[0],@X[1],[$inp],#2*$SZ
-+	ldr	$t2,[$Ktbl],#$SZ			// *K++
-+	eor	$t3,$B,$C				// magic seed
-+	str	$inp,[x29,#112]
-+___
-+for ($i=0;$i<16;$i++)	{ &BODY_00_xx($i,@V); unshift(@V,pop(@V)); }
-+$code.=".Loop_16_xx:\n";
-+for (;$i<32;$i++)	{ &BODY_00_xx($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	cbnz	$t2,.Loop_16_xx
-+
-+	ldp	$ctx,$num,[x29,#96]
-+	ldr	$inp,[x29,#112]
-+	sub	$Ktbl,$Ktbl,#`$SZ*($rounds+1)`		// rewind
-+
-+	ldp	@X[0],@X[1],[$ctx]
-+	ldp	@X[2],@X[3],[$ctx,#2*$SZ]
-+	add	$inp,$inp,#14*$SZ			// advance input pointer
-+	ldp	@X[4],@X[5],[$ctx,#4*$SZ]
-+	add	$A,$A,@X[0]
-+	ldp	@X[6],@X[7],[$ctx,#6*$SZ]
-+	add	$B,$B,@X[1]
-+	add	$C,$C,@X[2]
-+	add	$D,$D,@X[3]
-+	stp	$A,$B,[$ctx]
-+	add	$E,$E,@X[4]
-+	add	$F,$F,@X[5]
-+	stp	$C,$D,[$ctx,#2*$SZ]
-+	add	$G,$G,@X[6]
-+	add	$H,$H,@X[7]
-+	cmp	$inp,$num
-+	stp	$E,$F,[$ctx,#4*$SZ]
-+	stp	$G,$H,[$ctx,#6*$SZ]
-+	b.ne	.Loop
-+
-+	ldp	x19,x20,[x29,#16]
-+	add	sp,sp,#4*$SZ
-+	ldp	x21,x22,[x29,#32]
-+	ldp	x23,x24,[x29,#48]
-+	ldp	x25,x26,[x29,#64]
-+	ldp	x27,x28,[x29,#80]
-+	ldp	x29,x30,[sp],#128
-+	ret
-+.size	$func,.-$func
-+
-+.align	6
-+.type	.LK$BITS,%object
-+.LK$BITS:
-+___
-+$code.=<<___ if ($SZ==8);
-+	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
-+	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
-+	.quad	0x3956c25bf348b538,0x59f111f1b605d019
-+	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
-+	.quad	0xd807aa98a3030242,0x12835b0145706fbe
-+	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
-+	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
-+	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
-+	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
-+	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
-+	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
-+	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
-+	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
-+	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
-+	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
-+	.quad	0x06ca6351e003826f,0x142929670a0e6e70
-+	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
-+	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
-+	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
-+	.quad	0x81c2c92e47edaee6,0x92722c851482353b
-+	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
-+	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
-+	.quad	0xd192e819d6ef5218,0xd69906245565a910
-+	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
-+	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
-+	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
-+	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
-+	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
-+	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
-+	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
-+	.quad	0x90befffa23631e28,0xa4506cebde82bde9
-+	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
-+	.quad	0xca273eceea26619c,0xd186b8c721c0c207
-+	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
-+	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
-+	.quad	0x113f9804bef90dae,0x1b710b35131c471b
-+	.quad	0x28db77f523047d84,0x32caab7b40c72493
-+	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
-+	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
-+	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
-+	.quad	0	// terminator
-+___
-+$code.=<<___ if ($SZ==4);
-+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+	.long	0	//terminator
-+___
-+$code.=<<___;
-+.size	.LK$BITS,.-.LK$BITS
-+.align	3
-+.LOPENSSL_armcap_P:
-+#ifdef	__ILP32__
-+	.long	OPENSSL_armcap_P-.
-+#else
-+	.quad	OPENSSL_armcap_P-.
-+#endif
-+.asciz	"SHA$BITS block transform for ARMv8, CRYPTOGAMS by "
-+.align	2
-+___
-+
-+if ($SZ==4) {
-+my $Ktbl="x3";
-+
-+my ($ABCD,$EFGH,$abcd)=map("v$_.16b",(0..2));
-+my @MSG=map("v$_.16b",(4..7));
-+my ($W0,$W1)=("v16.4s","v17.4s");
-+my ($ABCD_SAVE,$EFGH_SAVE)=("v18.16b","v19.16b");
-+
-+$code.=<<___;
-+.type	sha256_block_armv8,%function
-+.align	6
-+sha256_block_armv8:
-+.Lv8_entry:
-+	stp		x29,x30,[sp,#-16]!
-+	add		x29,sp,#0
-+
-+	ld1.32		{$ABCD,$EFGH},[$ctx]
-+	adr		$Ktbl,.LK256
-+
-+.Loop_hw:
-+	ld1		{@MSG[0]-@MSG[3]},[$inp],#64
-+	sub		$num,$num,#1
-+	ld1.32		{$W0},[$Ktbl],#16
-+	rev32		@MSG[0],@MSG[0]
-+	rev32		@MSG[1],@MSG[1]
-+	rev32		@MSG[2],@MSG[2]
-+	rev32		@MSG[3],@MSG[3]
-+	orr		$ABCD_SAVE,$ABCD,$ABCD		// offload
-+	orr		$EFGH_SAVE,$EFGH,$EFGH
-+___
-+for($i=0;$i<12;$i++) {
-+$code.=<<___;
-+	ld1.32		{$W1},[$Ktbl],#16
-+	add.i32		$W0,$W0,@MSG[0]
-+	sha256su0	@MSG[0],@MSG[1]
-+	orr		$abcd,$ABCD,$ABCD
-+	sha256h		$ABCD,$EFGH,$W0
-+	sha256h2	$EFGH,$abcd,$W0
-+	sha256su1	@MSG[0],@MSG[2],@MSG[3]
-+___
-+	($W0,$W1)=($W1,$W0);	push(@MSG,shift(@MSG));
-+}
-+$code.=<<___;
-+	ld1.32		{$W1},[$Ktbl],#16
-+	add.i32		$W0,$W0,@MSG[0]
-+	orr		$abcd,$ABCD,$ABCD
-+	sha256h		$ABCD,$EFGH,$W0
-+	sha256h2	$EFGH,$abcd,$W0
-+
-+	ld1.32		{$W0},[$Ktbl],#16
-+	add.i32		$W1,$W1,@MSG[1]
-+	orr		$abcd,$ABCD,$ABCD
-+	sha256h		$ABCD,$EFGH,$W1
-+	sha256h2	$EFGH,$abcd,$W1
-+
-+	ld1.32		{$W1},[$Ktbl]
-+	add.i32		$W0,$W0,@MSG[2]
-+	sub		$Ktbl,$Ktbl,#$rounds*$SZ-16	// rewind
-+	orr		$abcd,$ABCD,$ABCD
-+	sha256h		$ABCD,$EFGH,$W0
-+	sha256h2	$EFGH,$abcd,$W0
-+
-+	add.i32		$W1,$W1,@MSG[3]
-+	orr		$abcd,$ABCD,$ABCD
-+	sha256h		$ABCD,$EFGH,$W1
-+	sha256h2	$EFGH,$abcd,$W1
-+
-+	add.i32		$ABCD,$ABCD,$ABCD_SAVE
-+	add.i32		$EFGH,$EFGH,$EFGH_SAVE
-+
-+	cbnz		$num,.Loop_hw
-+
-+	st1.32		{$ABCD,$EFGH},[$ctx]
-+
-+	ldr		x29,[sp],#16
-+	ret
-+.size	sha256_block_armv8,.-sha256_block_armv8
-+___
-+}
-+
-+$code.=<<___;
-+.comm	OPENSSL_armcap_P,4,4
-+___
-+
-+{   my  %opcode = (
-+	"sha256h"	=> 0x5e004000,	"sha256h2"	=> 0x5e005000,
-+	"sha256su0"	=> 0x5e282800,	"sha256su1"	=> 0x5e006000	);
-+
-+    sub unsha256 {
-+	my ($mnemonic,$arg)=@_;
-+
-+	$arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv]([0-9]+))?/o
-+	&&
-+	sprintf ".inst\t0x%08x\t//%s %s",
-+			$opcode{$mnemonic}|$1|($2<<5)|($3<<16),
-+			$mnemonic,$arg;
-+    }
-+}
-+
-+foreach(split("\n",$code)) {
-+
-+	s/\`([^\`]*)\`/eval($1)/geo;
-+
-+	s/\b(sha256\w+)\s+([qv].*)/unsha256($1,$2)/geo;
-+
-+	s/\.\w?32\b//o		and s/\.16b/\.4s/go;
-+	m/(ld|st)1[^\[]+\[0\]/o	and s/\.4s/\.s/go;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-c64xplus.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-c64xplus.pl
-new file mode 100644
-index 0000000..9ebfc92
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-c64xplus.pl
-@@ -0,0 +1,438 @@
-+#! /usr/bin/env perl
-+# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# SHA512 for C64x+.
-+#
-+# January 2012
-+#
-+# Performance is 19 cycles per processed byte. Compared to block
-+# transform function from sha512.c compiled with cl6x with -mv6400+
-+# -o2 -DOPENSSL_SMALL_FOOTPRINT it's almost 7x faster and 2x smaller.
-+# Loop unroll won't make it, this implementation, any faster, because
-+# it's effectively dominated by SHRU||SHL pairs and you can't schedule
-+# more of them.
-+#
-+# !!! Note that this module uses AMR, which means that all interrupt
-+# service routines are expected to preserve it and for own well-being
-+# zero it upon entry.
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+($CTXA,$INP,$NUM) = ("A4","B4","A6");            # arguments
-+ $K512="A3";
-+
-+($Ahi,$Actxhi,$Bhi,$Bctxhi,$Chi,$Cctxhi,$Dhi,$Dctxhi,
-+ $Ehi,$Ectxhi,$Fhi,$Fctxhi,$Ghi,$Gctxhi,$Hhi,$Hctxhi)=map("A$_",(16..31));
-+($Alo,$Actxlo,$Blo,$Bctxlo,$Clo,$Cctxlo,$Dlo,$Dctxlo,
-+ $Elo,$Ectxlo,$Flo,$Fctxlo,$Glo,$Gctxlo,$Hlo,$Hctxlo)=map("B$_",(16..31));
-+
-+($S1hi,$CHhi,$S0hi,$t0hi)=map("A$_",(10..13));
-+($S1lo,$CHlo,$S0lo,$t0lo)=map("B$_",(10..13));
-+($T1hi,         $T2hi)=         ("A6","A7");
-+($T1lo,$T1carry,$T2lo,$T2carry)=("B6","B7","B8","B9");
-+($Khi,$Klo)=("A9","A8");
-+($MAJhi,$MAJlo)=($T2hi,$T2lo);
-+($t1hi,$t1lo)=($Khi,"B2");
-+ $CTXB=$t1lo;
-+
-+($Xihi,$Xilo)=("A5","B5");			# circular/ring buffer
-+
-+$code.=<<___;
-+	.text
-+
-+	.if	.ASSEMBLER_VERSION<7000000
-+	.asg	0,__TI_EABI__
-+	.endif
-+	.if	__TI_EABI__
-+	.nocmp
-+	.asg	sha512_block_data_order,_sha512_block_data_order
-+	.endif
-+
-+	.asg	B3,RA
-+	.asg	A15,FP
-+	.asg	B15,SP
-+
-+	.if	.BIG_ENDIAN
-+	.asg	$Khi,KHI
-+	.asg	$Klo,KLO
-+	.else
-+	.asg	$Khi,KLO
-+	.asg	$Klo,KHI
-+	.endif
-+
-+	.global	_sha512_block_data_order
-+_sha512_block_data_order:
-+__sha512_block:
-+	.asmfunc stack_usage(40+128)
-+	MV	$NUM,A0				; reassign $NUM
-+||	MVK	-128,B0
-+  [!A0]	BNOP	RA				; if ($NUM==0) return;
-+|| [A0]	STW	FP,*SP--(40)			; save frame pointer
-+|| [A0]	MV	SP,FP
-+   [A0]	STDW	B13:B12,*SP[4]
-+|| [A0]	MVK	0x00404,B1
-+   [A0]	STDW	B11:B10,*SP[3]
-+|| [A0]	STDW	A13:A12,*FP[-3]
-+|| [A0]	MVKH	0x60000,B1
-+   [A0]	STDW	A11:A10,*SP[1]
-+|| [A0]	MVC	B1,AMR				; setup circular addressing
-+|| [A0]	ADD	B0,SP,SP			; alloca(128)
-+	.if	__TI_EABI__
-+   [A0]	AND	B0,SP,SP			; align stack at 128 bytes
-+|| [A0]	ADDKPC	__sha512_block,B1
-+|| [A0]	MVKL	\$PCR_OFFSET(K512,__sha512_block),$K512
-+   [A0]	MVKH	\$PCR_OFFSET(K512,__sha512_block),$K512
-+|| [A0]	SUBAW	SP,2,SP				; reserve two words above buffer
-+	.else
-+   [A0]	AND	B0,SP,SP			; align stack at 128 bytes
-+|| [A0]	ADDKPC	__sha512_block,B1
-+|| [A0]	MVKL	(K512-__sha512_block),$K512
-+   [A0]	MVKH	(K512-__sha512_block),$K512
-+|| [A0]	SUBAW	SP,2,SP				; reserve two words above buffer
-+	.endif
-+	ADDAW	SP,3,$Xilo
-+	ADDAW	SP,2,$Xihi
-+
-+||	MV	$CTXA,$CTXB
-+	LDW	*${CTXA}[0^.LITTLE_ENDIAN],$Ahi	; load ctx
-+||	LDW	*${CTXB}[1^.LITTLE_ENDIAN],$Alo
-+||	ADD	B1,$K512,$K512
-+	LDW	*${CTXA}[2^.LITTLE_ENDIAN],$Bhi
-+||	LDW	*${CTXB}[3^.LITTLE_ENDIAN],$Blo
-+	LDW	*${CTXA}[4^.LITTLE_ENDIAN],$Chi
-+||	LDW	*${CTXB}[5^.LITTLE_ENDIAN],$Clo
-+	LDW	*${CTXA}[6^.LITTLE_ENDIAN],$Dhi
-+||	LDW	*${CTXB}[7^.LITTLE_ENDIAN],$Dlo
-+	LDW	*${CTXA}[8^.LITTLE_ENDIAN],$Ehi
-+||	LDW	*${CTXB}[9^.LITTLE_ENDIAN],$Elo
-+	LDW	*${CTXA}[10^.LITTLE_ENDIAN],$Fhi
-+||	LDW	*${CTXB}[11^.LITTLE_ENDIAN],$Flo
-+	LDW	*${CTXA}[12^.LITTLE_ENDIAN],$Ghi
-+||	LDW	*${CTXB}[13^.LITTLE_ENDIAN],$Glo
-+	LDW	*${CTXA}[14^.LITTLE_ENDIAN],$Hhi
-+||	LDW	*${CTXB}[15^.LITTLE_ENDIAN],$Hlo
-+
-+	LDNDW	*$INP++,B11:B10			; pre-fetch input
-+	LDDW	*$K512++,$Khi:$Klo		; pre-fetch K512[0]
-+outerloop?:
-+	MVK	15,B0				; loop counters
-+||	MVK	64,B1
-+||	SUB	A0,1,A0
-+	MV	$Ahi,$Actxhi
-+||	MV	$Alo,$Actxlo
-+||	MV	$Bhi,$Bctxhi
-+||	MV	$Blo,$Bctxlo
-+||	MV	$Chi,$Cctxhi
-+||	MV	$Clo,$Cctxlo
-+||	MVD	$Dhi,$Dctxhi
-+||	MVD	$Dlo,$Dctxlo
-+	MV	$Ehi,$Ectxhi
-+||	MV	$Elo,$Ectxlo
-+||	MV	$Fhi,$Fctxhi
-+||	MV	$Flo,$Fctxlo
-+||	MV	$Ghi,$Gctxhi
-+||	MV	$Glo,$Gctxlo
-+||	MVD	$Hhi,$Hctxhi
-+||	MVD	$Hlo,$Hctxlo
-+loop0_15?:
-+	.if	.BIG_ENDIAN
-+	MV	B11,$T1hi
-+||	MV	B10,$T1lo
-+	.else
-+	SWAP4	B10,$T1hi
-+||	SWAP4	B11,$T1lo
-+	SWAP2	$T1hi,$T1hi
-+||	SWAP2	$T1lo,$T1lo
-+	.endif
-+loop16_79?:
-+	STW	$T1hi,*$Xihi++[2]
-+||	STW	$T1lo,*$Xilo++[2]			; X[i] = T1
-+||	ADD	$Hhi,$T1hi,$T1hi
-+||	ADDU	$Hlo,$T1lo,$T1carry:$T1lo		; T1 += h
-+||	SHRU	$Ehi,14,$S1hi
-+||	SHL	$Ehi,32-14,$S1lo
-+	XOR	$Fhi,$Ghi,$CHhi
-+||	XOR	$Flo,$Glo,$CHlo
-+||	ADD	KHI,$T1hi,$T1hi
-+||	ADDU	KLO,$T1carry:$T1lo,$T1carry:$T1lo	; T1 += K512[i]
-+||	SHRU	$Elo,14,$t0lo
-+||	SHL	$Elo,32-14,$t0hi
-+	XOR	$t0hi,$S1hi,$S1hi
-+||	XOR	$t0lo,$S1lo,$S1lo
-+||	AND	$Ehi,$CHhi,$CHhi
-+||	AND	$Elo,$CHlo,$CHlo
-+||	ROTL	$Ghi,0,$Hhi
-+||	ROTL	$Glo,0,$Hlo				; h = g
-+||	SHRU	$Ehi,18,$t0hi
-+||	SHL	$Ehi,32-18,$t0lo
-+	XOR	$t0hi,$S1hi,$S1hi
-+||	XOR	$t0lo,$S1lo,$S1lo
-+||	XOR	$Ghi,$CHhi,$CHhi
-+||	XOR	$Glo,$CHlo,$CHlo			; Ch(e,f,g) = ((f^g)&e)^g
-+||	ROTL	$Fhi,0,$Ghi
-+||	ROTL	$Flo,0,$Glo				; g = f
-+||	SHRU	$Elo,18,$t0lo
-+||	SHL	$Elo,32-18,$t0hi
-+	XOR	$t0hi,$S1hi,$S1hi
-+||	XOR	$t0lo,$S1lo,$S1lo
-+||	OR	$Ahi,$Bhi,$MAJhi
-+||	OR	$Alo,$Blo,$MAJlo
-+||	ROTL	$Ehi,0,$Fhi
-+||	ROTL	$Elo,0,$Flo				; f = e
-+||	SHRU	$Ehi,41-32,$t0lo
-+||	SHL	$Ehi,64-41,$t0hi
-+	XOR	$t0hi,$S1hi,$S1hi
-+||	XOR	$t0lo,$S1lo,$S1lo
-+||	AND	$Chi,$MAJhi,$MAJhi
-+||	AND	$Clo,$MAJlo,$MAJlo
-+||	ROTL	$Dhi,0,$Ehi
-+||	ROTL	$Dlo,0,$Elo				; e = d
-+||	SHRU	$Elo,41-32,$t0hi
-+||	SHL	$Elo,64-41,$t0lo
-+	XOR	$t0hi,$S1hi,$S1hi
-+||	XOR	$t0lo,$S1lo,$S1lo			; Sigma1(e)
-+||	AND	$Ahi,$Bhi,$t1hi
-+||	AND	$Alo,$Blo,$t1lo
-+||	ROTL	$Chi,0,$Dhi
-+||	ROTL	$Clo,0,$Dlo				; d = c
-+||	SHRU	$Ahi,28,$S0hi
-+||	SHL	$Ahi,32-28,$S0lo
-+	OR	$t1hi,$MAJhi,$MAJhi
-+||	OR	$t1lo,$MAJlo,$MAJlo			; Maj(a,b,c) = ((a|b)&c)|(a&b)
-+||	ADD	$CHhi,$T1hi,$T1hi
-+||	ADDU	$CHlo,$T1carry:$T1lo,$T1carry:$T1lo	; T1 += Ch(e,f,g)
-+||	ROTL	$Bhi,0,$Chi
-+||	ROTL	$Blo,0,$Clo				; c = b
-+||	SHRU	$Alo,28,$t0lo
-+||	SHL	$Alo,32-28,$t0hi
-+	XOR	$t0hi,$S0hi,$S0hi
-+||	XOR	$t0lo,$S0lo,$S0lo
-+||	ADD	$S1hi,$T1hi,$T1hi
-+||	ADDU	$S1lo,$T1carry:$T1lo,$T1carry:$T1lo	; T1 += Sigma1(e)
-+||	ROTL	$Ahi,0,$Bhi
-+||	ROTL	$Alo,0,$Blo				; b = a
-+||	SHRU	$Ahi,34-32,$t0lo
-+||	SHL	$Ahi,64-34,$t0hi
-+	XOR	$t0hi,$S0hi,$S0hi
-+||	XOR	$t0lo,$S0lo,$S0lo
-+||	ADD	$MAJhi,$T1hi,$T2hi
-+||	ADDU	$MAJlo,$T1carry:$T1lo,$T2carry:$T2lo	; T2 = T1+Maj(a,b,c)
-+||	SHRU	$Alo,34-32,$t0hi
-+||	SHL	$Alo,64-34,$t0lo
-+	XOR	$t0hi,$S0hi,$S0hi
-+||	XOR	$t0lo,$S0lo,$S0lo
-+||	ADD	$Ehi,$T1hi,$T1hi
-+||	ADDU	$Elo,$T1carry:$T1lo,$T1carry:$T1lo	; T1 += e
-+|| [B0]	BNOP	loop0_15?
-+||	SHRU	$Ahi,39-32,$t0lo
-+||	SHL	$Ahi,64-39,$t0hi
-+	XOR	$t0hi,$S0hi,$S0hi
-+||	XOR	$t0lo,$S0lo,$S0lo
-+|| [B0]	LDNDW	*$INP++,B11:B10				; pre-fetch input
-+||[!B1]	BNOP	break?
-+||	SHRU	$Alo,39-32,$t0hi
-+||	SHL	$Alo,64-39,$t0lo
-+	XOR	$t0hi,$S0hi,$S0hi
-+||	XOR	$t0lo,$S0lo,$S0lo			; Sigma0(a)
-+||	ADD	$T1carry,$T1hi,$Ehi
-+||	MV	$T1lo,$Elo				; e = T1
-+||[!B0]	LDW	*${Xihi}[28],$T1hi
-+||[!B0]	LDW	*${Xilo}[28],$T1lo			; X[i+14]
-+	ADD	$S0hi,$T2hi,$T2hi
-+||	ADDU	$S0lo,$T2carry:$T2lo,$T2carry:$T2lo	; T2 += Sigma0(a)
-+|| [B1]	LDDW	*$K512++,$Khi:$Klo			; pre-fetch K512[i]
-+	NOP						; avoid cross-path stall
-+	ADD	$T2carry,$T2hi,$Ahi
-+||	MV	$T2lo,$Alo				; a = T2
-+|| [B0]	SUB	B0,1,B0
-+;;===== branch to loop00_15? is taken here
-+	NOP
-+;;===== branch to break? is taken here
-+	LDW	*${Xihi}[2],$T2hi
-+||	LDW	*${Xilo}[2],$T2lo			; X[i+1]
-+||	SHRU	$T1hi,19,$S1hi
-+||	SHL	$T1hi,32-19,$S1lo
-+	SHRU	$T1lo,19,$t0lo
-+||	SHL	$T1lo,32-19,$t0hi
-+	XOR	$t0hi,$S1hi,$S1hi
-+||	XOR	$t0lo,$S1lo,$S1lo
-+||	SHRU	$T1hi,61-32,$t0lo
-+||	SHL	$T1hi,64-61,$t0hi
-+	XOR	$t0hi,$S1hi,$S1hi
-+||	XOR	$t0lo,$S1lo,$S1lo
-+||	SHRU	$T1lo,61-32,$t0hi
-+||	SHL	$T1lo,64-61,$t0lo
-+	XOR	$t0hi,$S1hi,$S1hi
-+||	XOR	$t0lo,$S1lo,$S1lo
-+||	SHRU	$T1hi,6,$t0hi
-+||	SHL	$T1hi,32-6,$t0lo
-+	XOR	$t0hi,$S1hi,$S1hi
-+||	XOR	$t0lo,$S1lo,$S1lo
-+||	SHRU	$T1lo,6,$t0lo
-+||	LDW	*${Xihi}[18],$T1hi
-+||	LDW	*${Xilo}[18],$T1lo			; X[i+9]
-+	XOR	$t0lo,$S1lo,$S1lo			; sigma1(Xi[i+14])
-+
-+||	LDW	*${Xihi}[0],$CHhi
-+||	LDW	*${Xilo}[0],$CHlo			; X[i]
-+||	SHRU	$T2hi,1,$S0hi
-+||	SHL	$T2hi,32-1,$S0lo
-+	SHRU	$T2lo,1,$t0lo
-+||	SHL	$T2lo,32-1,$t0hi
-+	XOR	$t0hi,$S0hi,$S0hi
-+||	XOR	$t0lo,$S0lo,$S0lo
-+||	SHRU	$T2hi,8,$t0hi
-+||	SHL	$T2hi,32-8,$t0lo
-+	XOR	$t0hi,$S0hi,$S0hi
-+||	XOR	$t0lo,$S0lo,$S0lo
-+||	SHRU	$T2lo,8,$t0lo
-+||	SHL	$T2lo,32-8,$t0hi
-+	XOR	$t0hi,$S0hi,$S0hi
-+||	XOR	$t0lo,$S0lo,$S0lo
-+||	ADD	$S1hi,$T1hi,$T1hi
-+||	ADDU	$S1lo,$T1lo,$T1carry:$T1lo		; T1 = X[i+9]+sigma1()
-+|| [B1]	BNOP	loop16_79?
-+||	SHRU	$T2hi,7,$t0hi
-+||	SHL	$T2hi,32-7,$t0lo
-+	XOR	$t0hi,$S0hi,$S0hi
-+||	XOR	$t0lo,$S0lo,$S0lo
-+||	ADD	$CHhi,$T1hi,$T1hi
-+||	ADDU	$CHlo,$T1carry:$T1lo,$T1carry:$T1lo	; T1 += X[i]
-+||	SHRU	$T2lo,7,$t0lo
-+	XOR	$t0lo,$S0lo,$S0lo			; sigma0(Xi[i+1]
-+
-+	ADD	$S0hi,$T1hi,$T1hi
-+||	ADDU	$S0lo,$T1carry:$T1lo,$T1carry:$T1lo	; T1 += sigma0()
-+|| [B1]	SUB	B1,1,B1
-+	NOP						; avoid cross-path stall
-+	ADD	$T1carry,$T1hi,$T1hi
-+;;===== branch to loop16_79? is taken here
-+
-+break?:
-+	ADD	$Ahi,$Actxhi,$Ahi		; accumulate ctx
-+||	ADDU	$Alo,$Actxlo,$Actxlo:$Alo
-+|| [A0]	LDNDW	*$INP++,B11:B10			; pre-fetch input
-+|| [A0]	ADDK	-640,$K512			; rewind pointer to K512
-+	ADD	$Bhi,$Bctxhi,$Bhi
-+||	ADDU	$Blo,$Bctxlo,$Bctxlo:$Blo
-+|| [A0]	LDDW	*$K512++,$Khi:$Klo		; pre-fetch K512[0]
-+	ADD	$Chi,$Cctxhi,$Chi
-+||	ADDU	$Clo,$Cctxlo,$Cctxlo:$Clo
-+||	ADD	$Actxlo,$Ahi,$Ahi
-+||[!A0]	MV	$CTXA,$CTXB
-+	ADD	$Dhi,$Dctxhi,$Dhi
-+||	ADDU	$Dlo,$Dctxlo,$Dctxlo:$Dlo
-+||	ADD	$Bctxlo,$Bhi,$Bhi
-+||[!A0]	STW	$Ahi,*${CTXA}[0^.LITTLE_ENDIAN]	; save ctx
-+||[!A0]	STW	$Alo,*${CTXB}[1^.LITTLE_ENDIAN]
-+	ADD	$Ehi,$Ectxhi,$Ehi
-+||	ADDU	$Elo,$Ectxlo,$Ectxlo:$Elo
-+||	ADD	$Cctxlo,$Chi,$Chi
-+|| [A0]	BNOP	outerloop?
-+||[!A0]	STW	$Bhi,*${CTXA}[2^.LITTLE_ENDIAN]
-+||[!A0]	STW	$Blo,*${CTXB}[3^.LITTLE_ENDIAN]
-+	ADD	$Fhi,$Fctxhi,$Fhi
-+||	ADDU	$Flo,$Fctxlo,$Fctxlo:$Flo
-+||	ADD	$Dctxlo,$Dhi,$Dhi
-+||[!A0]	STW	$Chi,*${CTXA}[4^.LITTLE_ENDIAN]
-+||[!A0]	STW	$Clo,*${CTXB}[5^.LITTLE_ENDIAN]
-+	ADD	$Ghi,$Gctxhi,$Ghi
-+||	ADDU	$Glo,$Gctxlo,$Gctxlo:$Glo
-+||	ADD	$Ectxlo,$Ehi,$Ehi
-+||[!A0]	STW	$Dhi,*${CTXA}[6^.LITTLE_ENDIAN]
-+||[!A0]	STW	$Dlo,*${CTXB}[7^.LITTLE_ENDIAN]
-+	ADD	$Hhi,$Hctxhi,$Hhi
-+||	ADDU	$Hlo,$Hctxlo,$Hctxlo:$Hlo
-+||	ADD	$Fctxlo,$Fhi,$Fhi
-+||[!A0]	STW	$Ehi,*${CTXA}[8^.LITTLE_ENDIAN]
-+||[!A0]	STW	$Elo,*${CTXB}[9^.LITTLE_ENDIAN]
-+	ADD	$Gctxlo,$Ghi,$Ghi
-+||[!A0]	STW	$Fhi,*${CTXA}[10^.LITTLE_ENDIAN]
-+||[!A0]	STW	$Flo,*${CTXB}[11^.LITTLE_ENDIAN]
-+	ADD	$Hctxlo,$Hhi,$Hhi
-+||[!A0]	STW	$Ghi,*${CTXA}[12^.LITTLE_ENDIAN]
-+||[!A0]	STW	$Glo,*${CTXB}[13^.LITTLE_ENDIAN]
-+;;===== branch to outerloop? is taken here
-+
-+	STW	$Hhi,*${CTXA}[14^.LITTLE_ENDIAN]
-+||	STW	$Hlo,*${CTXB}[15^.LITTLE_ENDIAN]
-+||	MVK	-40,B0
-+	ADD	FP,B0,SP			; destroy circular buffer
-+||	LDDW	*FP[-4],A11:A10
-+	LDDW	*SP[2],A13:A12
-+||	LDDW	*FP[-2],B11:B10
-+	LDDW	*SP[4],B13:B12
-+||	BNOP	RA
-+	LDW	*++SP(40),FP			; restore frame pointer
-+	MVK	0,B0
-+	MVC	B0,AMR				; clear AMR
-+	NOP	2				; wait till FP is committed
-+	.endasmfunc
-+
-+	.if	__TI_EABI__
-+	.sect	".text:sha_asm.const"
-+	.else
-+	.sect	".const:sha_asm"
-+	.endif
-+	.align	128
-+K512:
-+	.uword	0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
-+	.uword	0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
-+	.uword	0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
-+	.uword	0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
-+	.uword	0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
-+	.uword	0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
-+	.uword	0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
-+	.uword	0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
-+	.uword	0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
-+	.uword	0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
-+	.uword	0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
-+	.uword	0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
-+	.uword	0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
-+	.uword	0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
-+	.uword	0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
-+	.uword	0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
-+	.uword	0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
-+	.uword	0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
-+	.uword	0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
-+	.uword	0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
-+	.uword	0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
-+	.uword	0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
-+	.uword	0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
-+	.uword	0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
-+	.uword	0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
-+	.uword	0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
-+	.uword	0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
-+	.uword	0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
-+	.uword	0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
-+	.uword	0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
-+	.uword	0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
-+	.uword	0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
-+	.uword	0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
-+	.uword	0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
-+	.uword	0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
-+	.uword	0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
-+	.uword	0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
-+	.uword	0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
-+	.uword	0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
-+	.uword	0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
-+	.cstring "SHA512 block transform for C64x+, CRYPTOGAMS by "
-+	.align	4
-+___
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-ia64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-ia64.pl
-new file mode 100755
-index 0000000..356a46a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-ia64.pl
-@@ -0,0 +1,692 @@
-+#! /usr/bin/env perl
-+# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+#
-+# SHA256/512_Transform for Itanium.
-+#
-+# sha512_block runs in 1003 cycles on Itanium 2, which is almost 50%
-+# faster than gcc and >60%(!) faster than code generated by HP-UX
-+# compiler (yes, HP-UX is generating slower code, because unlike gcc,
-+# it failed to deploy "shift right pair," 'shrp' instruction, which
-+# substitutes for 64-bit rotate).
-+#
-+# 924 cycles long sha256_block outperforms gcc by over factor of 2(!)
-+# and HP-UX compiler - by >40% (yes, gcc won sha512_block, but lost
-+# this one big time). Note that "formally" 924 is about 100 cycles
-+# too much. I mean it's 64 32-bit rounds vs. 80 virtually identical
-+# 64-bit ones and 1003*64/80 gives 802. Extra cycles, 2 per round,
-+# are spent on extra work to provide for 32-bit rotations. 32-bit
-+# rotations are still handled by 'shrp' instruction and for this
-+# reason lower 32 bits are deposited to upper half of 64-bit register
-+# prior 'shrp' issue. And in order to minimize the amount of such
-+# operations, X[16] values are *maintained* with copies of lower
-+# halves in upper halves, which is why you'll spot such instructions
-+# as custom 'mux2', "parallel 32-bit add," 'padd4' and "parallel
-+# 32-bit unsigned right shift," 'pshr4.u' instructions here.
-+#
-+# Rules of engagement.
-+#
-+# There is only one integer shifter meaning that if I have two rotate,
-+# deposit or extract instructions in adjacent bundles, they shall
-+# split [at run-time if they have to]. But note that variable and
-+# parallel shifts are performed by multi-media ALU and *are* pairable
-+# with rotates [and alike]. On the backside MMALU is rather slow: it
-+# takes 2 extra cycles before the result of integer operation is
-+# available *to* MMALU and 2(*) extra cycles before the result of MM
-+# operation is available "back" *to* integer ALU, not to mention that
-+# MMALU itself has 2 cycles latency. However! I explicitly scheduled
-+# these MM instructions to avoid MM stalls, so that all these extra
-+# latencies get "hidden" in instruction-level parallelism.
-+#
-+# (*) 2 cycles on Itanium 1 and 1 cycle on Itanium 2. But I schedule
-+#     for 2 in order to provide for best *overall* performance,
-+#     because on Itanium 1 stall on MM result is accompanied by
-+#     pipeline flush, which takes 6 cycles:-(
-+#
-+# June 2012
-+#
-+# Improve performance by 15-20%. Note about "rules of engagement"
-+# above. Contemporary cores are equipped with additional shifter,
-+# so that they should perform even better than below, presumably
-+# by ~10%.
-+#
-+######################################################################
-+# Current performance in cycles per processed byte for Itanium 2
-+# pre-9000 series [little-endian] system:
-+#
-+# SHA1(*)	5.7
-+# SHA256	12.6
-+# SHA512	6.7
-+#
-+# (*) SHA1 result is presented purely for reference purposes.
-+#
-+# To generate code, pass the file name with either 256 or 512 in its
-+# name and compiler flags.
-+
-+$output=pop;
-+
-+if ($output =~ /512.*\.[s|asm]/) {
-+	$SZ=8;
-+	$BITS=8*$SZ;
-+	$LDW="ld8";
-+	$STW="st8";
-+	$ADD="add";
-+	$SHRU="shr.u";
-+	$TABLE="K512";
-+	$func="sha512_block_data_order";
-+	@Sigma0=(28,34,39);
-+	@Sigma1=(14,18,41);
-+	@sigma0=(1,  8, 7);
-+	@sigma1=(19,61, 6);
-+	$rounds=80;
-+} elsif ($output =~ /256.*\.[s|asm]/) {
-+	$SZ=4;
-+	$BITS=8*$SZ;
-+	$LDW="ld4";
-+	$STW="st4";
-+	$ADD="padd4";
-+	$SHRU="pshr4.u";
-+	$TABLE="K256";
-+	$func="sha256_block_data_order";
-+	@Sigma0=( 2,13,22);
-+	@Sigma1=( 6,11,25);
-+	@sigma0=( 7,18, 3);
-+	@sigma1=(17,19,10);
-+	$rounds=64;
-+} else { die "nonsense $output"; }
-+
-+open STDOUT,">$output" || die "can't open $output: $!";
-+
-+if ($^O eq "hpux") {
-+    $ADDP="addp4";
-+    for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
-+} else { $ADDP="add"; }
-+for (@ARGV)  {	$big_endian=1 if (/\-DB_ENDIAN/);
-+		$big_endian=0 if (/\-DL_ENDIAN/);  }
-+if (!defined($big_endian))
-+             {	$big_endian=(unpack('L',pack('N',1))==1);  }
-+
-+$code=<<___;
-+.ident  \"$output, version 2.0\"
-+.ident  \"IA-64 ISA artwork by Andy Polyakov \"
-+.explicit
-+.text
-+
-+pfssave=r2;
-+lcsave=r3;
-+prsave=r14;
-+K=r15;
-+A_=r16; B_=r17; C_=r18; D_=r19;
-+E_=r20; F_=r21; G_=r22; H_=r23;
-+T1=r24;	T2=r25;
-+s0=r26;	s1=r27;	t0=r28;	t1=r29;
-+Ktbl=r30;
-+ctx=r31;	// 1st arg
-+input=r56;	// 2nd arg
-+num=r57;	// 3rd arg
-+sgm0=r58;	sgm1=r59;	// small constants
-+
-+// void $func (SHA_CTX *ctx, const void *in,size_t num[,int host])
-+.global	$func#
-+.proc	$func#
-+.align	32
-+.skip	16
-+$func:
-+	.prologue
-+	.save	ar.pfs,pfssave
-+{ .mmi;	alloc	pfssave=ar.pfs,3,25,0,24
-+	$ADDP	ctx=0,r32		// 1st arg
-+	.save	ar.lc,lcsave
-+	mov	lcsave=ar.lc	}
-+{ .mmi;	$ADDP	input=0,r33		// 2nd arg
-+	mov	num=r34			// 3rd arg
-+	.save	pr,prsave
-+	mov	prsave=pr	};;
-+
-+	.body
-+{ .mib;	add	r8=0*$SZ,ctx
-+	add	r9=1*$SZ,ctx	}
-+{ .mib;	add	r10=2*$SZ,ctx
-+	add	r11=3*$SZ,ctx	};;
-+
-+// load A-H
-+.Lpic_point:
-+{ .mmi;	$LDW	A_=[r8],4*$SZ
-+	$LDW	B_=[r9],4*$SZ
-+	mov	Ktbl=ip		}
-+{ .mmi;	$LDW	C_=[r10],4*$SZ
-+	$LDW	D_=[r11],4*$SZ
-+	mov	sgm0=$sigma0[2]	};;
-+{ .mmi;	$LDW	E_=[r8]
-+	$LDW	F_=[r9]
-+	add	Ktbl=($TABLE#-.Lpic_point),Ktbl		}
-+{ .mmi;	$LDW	G_=[r10]
-+	$LDW	H_=[r11]
-+	cmp.ne	p0,p16=0,r0	};;
-+___
-+$code.=<<___ if ($BITS==64);
-+{ .mii;	and	r8=7,input
-+	and	input=~7,input;;
-+	cmp.eq	p9,p0=1,r8	}
-+{ .mmi;	cmp.eq	p10,p0=2,r8
-+	cmp.eq	p11,p0=3,r8
-+	cmp.eq	p12,p0=4,r8	}
-+{ .mmi;	cmp.eq	p13,p0=5,r8
-+	cmp.eq	p14,p0=6,r8
-+	cmp.eq	p15,p0=7,r8	};;
-+___
-+$code.=<<___;
-+.L_outer:
-+.rotr	R[8],X[16]
-+A=R[0]; B=R[1]; C=R[2]; D=R[3]; E=R[4]; F=R[5]; G=R[6]; H=R[7]
-+{ .mmi;	ld1	X[15]=[input],$SZ		// eliminated in sha512
-+	mov	A=A_
-+	mov	ar.lc=14	}
-+{ .mmi;	mov	B=B_
-+	mov	C=C_
-+	mov	D=D_		}
-+{ .mmi;	mov	E=E_
-+	mov	F=F_
-+	mov	ar.ec=2		};;
-+{ .mmi;	mov	G=G_
-+	mov	H=H_
-+	mov	sgm1=$sigma1[2]	}
-+{ .mib;	mov	r8=0
-+	add	r9=1-$SZ,input
-+	brp.loop.imp	.L_first16,.L_first16_end-16	};;
-+___
-+$t0="A", $t1="E", $code.=<<___ if ($BITS==64);
-+// in sha512 case I load whole X[16] at once and take care of alignment...
-+{ .mmi;	add	r8=1*$SZ,input
-+	add	r9=2*$SZ,input
-+	add	r10=3*$SZ,input		};;
-+{ .mmb;	$LDW	X[15]=[input],4*$SZ
-+	$LDW	X[14]=[r8],4*$SZ
-+(p9)	br.cond.dpnt.many	.L1byte	};;
-+{ .mmb;	$LDW	X[13]=[r9],4*$SZ
-+	$LDW	X[12]=[r10],4*$SZ
-+(p10)	br.cond.dpnt.many	.L2byte	};;
-+{ .mmb;	$LDW	X[11]=[input],4*$SZ
-+	$LDW	X[10]=[r8],4*$SZ
-+(p11)	br.cond.dpnt.many	.L3byte	};;
-+{ .mmb;	$LDW	X[ 9]=[r9],4*$SZ
-+	$LDW	X[ 8]=[r10],4*$SZ
-+(p12)	br.cond.dpnt.many	.L4byte	};;
-+{ .mmb;	$LDW	X[ 7]=[input],4*$SZ
-+	$LDW	X[ 6]=[r8],4*$SZ
-+(p13)	br.cond.dpnt.many	.L5byte	};;
-+{ .mmb;	$LDW	X[ 5]=[r9],4*$SZ
-+	$LDW	X[ 4]=[r10],4*$SZ
-+(p14)	br.cond.dpnt.many	.L6byte	};;
-+{ .mmb;	$LDW	X[ 3]=[input],4*$SZ
-+	$LDW	X[ 2]=[r8],4*$SZ
-+(p15)	br.cond.dpnt.many	.L7byte	};;
-+{ .mmb;	$LDW	X[ 1]=[r9],4*$SZ
-+	$LDW	X[ 0]=[r10],4*$SZ	}
-+{ .mib;	mov	r8=0
-+	mux1	X[15]=X[15],\@rev		// eliminated on big-endian
-+	br.many	.L_first16		};;
-+.L1byte:
-+{ .mmi;	$LDW	X[13]=[r9],4*$SZ
-+	$LDW	X[12]=[r10],4*$SZ
-+	shrp	X[15]=X[15],X[14],56	};;
-+{ .mmi;	$LDW	X[11]=[input],4*$SZ
-+	$LDW	X[10]=[r8],4*$SZ
-+	shrp	X[14]=X[14],X[13],56	}
-+{ .mmi;	$LDW	X[ 9]=[r9],4*$SZ
-+	$LDW	X[ 8]=[r10],4*$SZ
-+	shrp	X[13]=X[13],X[12],56	};;
-+{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
-+	$LDW	X[ 6]=[r8],4*$SZ
-+	shrp	X[12]=X[12],X[11],56	}
-+{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
-+	$LDW	X[ 4]=[r10],4*$SZ
-+	shrp	X[11]=X[11],X[10],56	};;
-+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
-+	$LDW	X[ 2]=[r8],4*$SZ
-+	shrp	X[10]=X[10],X[ 9],56	}
-+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
-+	$LDW	X[ 0]=[r10],4*$SZ
-+	shrp	X[ 9]=X[ 9],X[ 8],56	};;
-+{ .mii;	$LDW	T1=[input]
-+	shrp	X[ 8]=X[ 8],X[ 7],56
-+	shrp	X[ 7]=X[ 7],X[ 6],56	}
-+{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],56
-+	shrp	X[ 5]=X[ 5],X[ 4],56	};;
-+{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],56
-+	shrp	X[ 3]=X[ 3],X[ 2],56	}
-+{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],56
-+	shrp	X[ 1]=X[ 1],X[ 0],56	}
-+{ .mib;	shrp	X[ 0]=X[ 0],T1,56	}
-+{ .mib;	mov	r8=0
-+	mux1	X[15]=X[15],\@rev		// eliminated on big-endian
-+	br.many	.L_first16		};;
-+.L2byte:
-+{ .mmi;	$LDW	X[11]=[input],4*$SZ
-+	$LDW	X[10]=[r8],4*$SZ
-+	shrp	X[15]=X[15],X[14],48	}
-+{ .mmi;	$LDW	X[ 9]=[r9],4*$SZ
-+	$LDW	X[ 8]=[r10],4*$SZ
-+	shrp	X[14]=X[14],X[13],48	};;
-+{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
-+	$LDW	X[ 6]=[r8],4*$SZ
-+	shrp	X[13]=X[13],X[12],48	}
-+{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
-+	$LDW	X[ 4]=[r10],4*$SZ
-+	shrp	X[12]=X[12],X[11],48	};;
-+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
-+	$LDW	X[ 2]=[r8],4*$SZ
-+	shrp	X[11]=X[11],X[10],48	}
-+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
-+	$LDW	X[ 0]=[r10],4*$SZ
-+	shrp	X[10]=X[10],X[ 9],48	};;
-+{ .mii;	$LDW	T1=[input]
-+	shrp	X[ 9]=X[ 9],X[ 8],48
-+	shrp	X[ 8]=X[ 8],X[ 7],48	}
-+{ .mii;	shrp	X[ 7]=X[ 7],X[ 6],48
-+	shrp	X[ 6]=X[ 6],X[ 5],48	};;
-+{ .mii;	shrp	X[ 5]=X[ 5],X[ 4],48
-+	shrp	X[ 4]=X[ 4],X[ 3],48	}
-+{ .mii;	shrp	X[ 3]=X[ 3],X[ 2],48
-+	shrp	X[ 2]=X[ 2],X[ 1],48	}
-+{ .mii;	shrp	X[ 1]=X[ 1],X[ 0],48
-+	shrp	X[ 0]=X[ 0],T1,48	}
-+{ .mib;	mov	r8=0
-+	mux1	X[15]=X[15],\@rev		// eliminated on big-endian
-+	br.many	.L_first16		};;
-+.L3byte:
-+{ .mmi;	$LDW	X[ 9]=[r9],4*$SZ
-+	$LDW	X[ 8]=[r10],4*$SZ
-+	shrp	X[15]=X[15],X[14],40	};;
-+{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
-+	$LDW	X[ 6]=[r8],4*$SZ
-+	shrp	X[14]=X[14],X[13],40	}
-+{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
-+	$LDW	X[ 4]=[r10],4*$SZ
-+	shrp	X[13]=X[13],X[12],40	};;
-+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
-+	$LDW	X[ 2]=[r8],4*$SZ
-+	shrp	X[12]=X[12],X[11],40	}
-+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
-+	$LDW	X[ 0]=[r10],4*$SZ
-+	shrp	X[11]=X[11],X[10],40	};;
-+{ .mii;	$LDW	T1=[input]
-+	shrp	X[10]=X[10],X[ 9],40
-+	shrp	X[ 9]=X[ 9],X[ 8],40	}
-+{ .mii;	shrp	X[ 8]=X[ 8],X[ 7],40
-+	shrp	X[ 7]=X[ 7],X[ 6],40	};;
-+{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],40
-+	shrp	X[ 5]=X[ 5],X[ 4],40	}
-+{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],40
-+	shrp	X[ 3]=X[ 3],X[ 2],40	}
-+{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],40
-+	shrp	X[ 1]=X[ 1],X[ 0],40	}
-+{ .mib;	shrp	X[ 0]=X[ 0],T1,40	}
-+{ .mib;	mov	r8=0
-+	mux1	X[15]=X[15],\@rev		// eliminated on big-endian
-+	br.many	.L_first16		};;
-+.L4byte:
-+{ .mmi;	$LDW	X[ 7]=[input],4*$SZ
-+	$LDW	X[ 6]=[r8],4*$SZ
-+	shrp	X[15]=X[15],X[14],32	}
-+{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
-+	$LDW	X[ 4]=[r10],4*$SZ
-+	shrp	X[14]=X[14],X[13],32	};;
-+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
-+	$LDW	X[ 2]=[r8],4*$SZ
-+	shrp	X[13]=X[13],X[12],32	}
-+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
-+	$LDW	X[ 0]=[r10],4*$SZ
-+	shrp	X[12]=X[12],X[11],32	};;
-+{ .mii;	$LDW	T1=[input]
-+	shrp	X[11]=X[11],X[10],32
-+	shrp	X[10]=X[10],X[ 9],32	}
-+{ .mii;	shrp	X[ 9]=X[ 9],X[ 8],32
-+	shrp	X[ 8]=X[ 8],X[ 7],32	};;
-+{ .mii;	shrp	X[ 7]=X[ 7],X[ 6],32
-+	shrp	X[ 6]=X[ 6],X[ 5],32	}
-+{ .mii;	shrp	X[ 5]=X[ 5],X[ 4],32
-+	shrp	X[ 4]=X[ 4],X[ 3],32	}
-+{ .mii;	shrp	X[ 3]=X[ 3],X[ 2],32
-+	shrp	X[ 2]=X[ 2],X[ 1],32	}
-+{ .mii;	shrp	X[ 1]=X[ 1],X[ 0],32
-+	shrp	X[ 0]=X[ 0],T1,32	}
-+{ .mib;	mov	r8=0
-+	mux1	X[15]=X[15],\@rev		// eliminated on big-endian
-+	br.many	.L_first16		};;
-+.L5byte:
-+{ .mmi;	$LDW	X[ 5]=[r9],4*$SZ
-+	$LDW	X[ 4]=[r10],4*$SZ
-+	shrp	X[15]=X[15],X[14],24	};;
-+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
-+	$LDW	X[ 2]=[r8],4*$SZ
-+	shrp	X[14]=X[14],X[13],24	}
-+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
-+	$LDW	X[ 0]=[r10],4*$SZ
-+	shrp	X[13]=X[13],X[12],24	};;
-+{ .mii;	$LDW	T1=[input]
-+	shrp	X[12]=X[12],X[11],24
-+	shrp	X[11]=X[11],X[10],24	}
-+{ .mii;	shrp	X[10]=X[10],X[ 9],24
-+	shrp	X[ 9]=X[ 9],X[ 8],24	};;
-+{ .mii;	shrp	X[ 8]=X[ 8],X[ 7],24
-+	shrp	X[ 7]=X[ 7],X[ 6],24	}
-+{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],24
-+	shrp	X[ 5]=X[ 5],X[ 4],24	}
-+{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],24
-+	shrp	X[ 3]=X[ 3],X[ 2],24	}
-+{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],24
-+	shrp	X[ 1]=X[ 1],X[ 0],24	}
-+{ .mib;	shrp	X[ 0]=X[ 0],T1,24	}
-+{ .mib;	mov	r8=0
-+	mux1	X[15]=X[15],\@rev		// eliminated on big-endian
-+	br.many	.L_first16		};;
-+.L6byte:
-+{ .mmi;	$LDW	X[ 3]=[input],4*$SZ
-+	$LDW	X[ 2]=[r8],4*$SZ
-+	shrp	X[15]=X[15],X[14],16	}
-+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
-+	$LDW	X[ 0]=[r10],4*$SZ
-+	shrp	X[14]=X[14],X[13],16	};;
-+{ .mii;	$LDW	T1=[input]
-+	shrp	X[13]=X[13],X[12],16
-+	shrp	X[12]=X[12],X[11],16	}
-+{ .mii;	shrp	X[11]=X[11],X[10],16
-+	shrp	X[10]=X[10],X[ 9],16	};;
-+{ .mii;	shrp	X[ 9]=X[ 9],X[ 8],16
-+	shrp	X[ 8]=X[ 8],X[ 7],16	}
-+{ .mii;	shrp	X[ 7]=X[ 7],X[ 6],16
-+	shrp	X[ 6]=X[ 6],X[ 5],16	}
-+{ .mii;	shrp	X[ 5]=X[ 5],X[ 4],16
-+	shrp	X[ 4]=X[ 4],X[ 3],16	}
-+{ .mii;	shrp	X[ 3]=X[ 3],X[ 2],16
-+	shrp	X[ 2]=X[ 2],X[ 1],16	}
-+{ .mii;	shrp	X[ 1]=X[ 1],X[ 0],16
-+	shrp	X[ 0]=X[ 0],T1,16	}
-+{ .mib;	mov	r8=0
-+	mux1	X[15]=X[15],\@rev		// eliminated on big-endian
-+	br.many	.L_first16		};;
-+.L7byte:
-+{ .mmi;	$LDW	X[ 1]=[r9],4*$SZ
-+	$LDW	X[ 0]=[r10],4*$SZ
-+	shrp	X[15]=X[15],X[14],8	};;
-+{ .mii;	$LDW	T1=[input]
-+	shrp	X[14]=X[14],X[13],8
-+	shrp	X[13]=X[13],X[12],8	}
-+{ .mii;	shrp	X[12]=X[12],X[11],8
-+	shrp	X[11]=X[11],X[10],8	};;
-+{ .mii;	shrp	X[10]=X[10],X[ 9],8
-+	shrp	X[ 9]=X[ 9],X[ 8],8	}
-+{ .mii;	shrp	X[ 8]=X[ 8],X[ 7],8
-+	shrp	X[ 7]=X[ 7],X[ 6],8	}
-+{ .mii;	shrp	X[ 6]=X[ 6],X[ 5],8
-+	shrp	X[ 5]=X[ 5],X[ 4],8	}
-+{ .mii;	shrp	X[ 4]=X[ 4],X[ 3],8
-+	shrp	X[ 3]=X[ 3],X[ 2],8	}
-+{ .mii;	shrp	X[ 2]=X[ 2],X[ 1],8
-+	shrp	X[ 1]=X[ 1],X[ 0],8	}
-+{ .mib;	shrp	X[ 0]=X[ 0],T1,8	}
-+{ .mib;	mov	r8=0
-+	mux1	X[15]=X[15],\@rev	};;	// eliminated on big-endian
-+
-+.align	32
-+.L_first16:
-+{ .mmi;		$LDW	K=[Ktbl],$SZ
-+		add	A=A,r8			// H+=Sigma(0) from the past
-+		_rotr	r10=$t1,$Sigma1[0]  }	// ROTR(e,14)
-+{ .mmi;		and	T1=F,E
-+		andcm	r8=G,E
-+	(p16)	mux1	X[14]=X[14],\@rev   };;	// eliminated on big-endian
-+{ .mmi;		and	T2=A,B
-+		and	r9=A,C
-+		_rotr	r11=$t1,$Sigma1[1]  }	// ROTR(e,41)
-+{ .mmi;		xor	T1=T1,r8		// T1=((e & f) ^ (~e & g))
-+		and	r8=B,C		    };;
-+___
-+$t0="t0", $t1="t1", $code.=<<___ if ($BITS==32);
-+.align	32
-+.L_first16:
-+{ .mmi;		add	A=A,r8			// H+=Sigma(0) from the past
-+		add	r10=2-$SZ,input
-+		add	r11=3-$SZ,input	};;
-+{ .mmi;		ld1	r9=[r9]
-+		ld1	r10=[r10]
-+		dep.z	$t1=E,32,32	}
-+{ .mmi;		ld1	r11=[r11]
-+		$LDW	K=[Ktbl],$SZ
-+		zxt4	E=E		};;
-+{ .mii;		or	$t1=$t1,E
-+		dep	X[15]=X[15],r9,8,8
-+		mux2	$t0=A,0x44	};;	// copy lower half to upper
-+{ .mmi;		and	T1=F,E
-+		andcm	r8=G,E
-+		dep	r11=r10,r11,8,8	};;
-+{ .mmi;		and	T2=A,B
-+		and	r9=A,C
-+		dep	X[15]=X[15],r11,16,16	};;
-+{ .mmi;	(p16)	ld1	X[15-1]=[input],$SZ	// prefetch
-+		xor	T1=T1,r8		// T1=((e & f) ^ (~e & g))
-+		_rotr	r10=$t1,$Sigma1[0] }	// ROTR(e,14)
-+{ .mmi;		and	r8=B,C
-+		_rotr	r11=$t1,$Sigma1[1] };;	// ROTR(e,18)
-+___
-+$code.=<<___;
-+{ .mmi;		add	T1=T1,H			// T1=Ch(e,f,g)+h
-+		xor	r10=r10,r11
-+		_rotr	r11=$t1,$Sigma1[2]  }	// ROTR(e,41)
-+{ .mmi;		xor	T2=T2,r9
-+		add	K=K,X[15]	    };;
-+{ .mmi;		add	T1=T1,K			// T1+=K[i]+X[i]
-+		xor	T2=T2,r8		// T2=((a & b) ^ (a & c) ^ (b & c))
-+		_rotr	r8=$t0,$Sigma0[0]   }	// ROTR(a,28)
-+{ .mmi;		xor	r11=r11,r10		// Sigma1(e)
-+		_rotr	r9=$t0,$Sigma0[1]   };;	// ROTR(a,34)
-+{ .mmi;		add	T1=T1,r11		// T+=Sigma1(e)
-+		xor	r8=r8,r9
-+		_rotr	r9=$t0,$Sigma0[2]   };;	// ROTR(a,39)
-+{ .mmi;		xor	r8=r8,r9		// Sigma0(a)
-+		add	D=D,T1
-+		mux2	H=X[15],0x44	    }	// mov H=X[15] in sha512
-+{ .mib;	(p16)	add	r9=1-$SZ,input		// not used in sha512
-+		add	X[15]=T1,T2		// H=T1+Maj(a,b,c)
-+	br.ctop.sptk	.L_first16	    };;
-+.L_first16_end:
-+
-+{ .mib;	mov	ar.lc=$rounds-17
-+	brp.loop.imp	.L_rest,.L_rest_end-16		}
-+{ .mib;	mov	ar.ec=1
-+	br.many	.L_rest			};;
-+
-+.align	32
-+.L_rest:
-+{ .mmi;		$LDW	K=[Ktbl],$SZ
-+		add	A=A,r8			// H+=Sigma0(a) from the past
-+		_rotr	r8=X[15-1],$sigma0[0] }	// ROTR(s0,1)
-+{ .mmi; 	add	X[15]=X[15],X[15-9]	// X[i&0xF]+=X[(i+9)&0xF]
-+		$SHRU	s0=X[15-1],sgm0	    };;	// s0=X[(i+1)&0xF]>>7
-+{ .mib;		and	T1=F,E
-+		_rotr	r9=X[15-1],$sigma0[1] }	// ROTR(s0,8)
-+{ .mib;		andcm	r10=G,E
-+		$SHRU	s1=X[15-14],sgm1    };;	// s1=X[(i+14)&0xF]>>6
-+// Pair of mmi; splits on Itanium 1 and prevents pipeline flush
-+// upon $SHRU output usage
-+{ .mmi;		xor	T1=T1,r10		// T1=((e & f) ^ (~e & g))
-+		xor	r9=r8,r9
-+		_rotr	r10=X[15-14],$sigma1[0] }// ROTR(s1,19)
-+{ .mmi;		and	T2=A,B
-+		and	r8=A,C
-+		_rotr	r11=X[15-14],$sigma1[1] };;// ROTR(s1,61)
-+___
-+$t0="t0", $t1="t1", $code.=<<___ if ($BITS==32);
-+{ .mib;		xor	s0=s0,r9		// s0=sigma0(X[(i+1)&0xF])
-+		dep.z	$t1=E,32,32	    }
-+{ .mib;		xor	r10=r11,r10
-+		zxt4	E=E		    };;
-+{ .mii;		xor	s1=s1,r10		// s1=sigma1(X[(i+14)&0xF])
-+		shrp	r9=E,$t1,32+$Sigma1[0]	// ROTR(e,14)
-+		mux2	$t0=A,0x44	    };;	// copy lower half to upper
-+// Pair of mmi; splits on Itanium 1 and prevents pipeline flush
-+// upon mux2 output usage
-+{ .mmi;		xor	T2=T2,r8
-+		shrp	r8=E,$t1,32+$Sigma1[1]}	// ROTR(e,18)
-+{ .mmi;		and	r10=B,C
-+		add	T1=T1,H			// T1=Ch(e,f,g)+h
-+		or	$t1=$t1,E   	    };;
-+___
-+$t0="A", $t1="E", $code.=<<___ if ($BITS==64);
-+{ .mib;		xor	s0=s0,r9		// s0=sigma0(X[(i+1)&0xF])
-+		_rotr	r9=$t1,$Sigma1[0]   }	// ROTR(e,14)
-+{ .mib;		xor	r10=r11,r10
-+		xor	T2=T2,r8	    };;
-+{ .mib;		xor	s1=s1,r10		// s1=sigma1(X[(i+14)&0xF])
-+		_rotr	r8=$t1,$Sigma1[1]   }	// ROTR(e,18)
-+{ .mib;		and	r10=B,C
-+		add	T1=T1,H		    };;	// T1+=H
-+___
-+$code.=<<___;
-+{ .mib;		xor	r9=r9,r8
-+		_rotr	r8=$t1,$Sigma1[2]   }	// ROTR(e,41)
-+{ .mib;		xor	T2=T2,r10		// T2=((a & b) ^ (a & c) ^ (b & c))
-+		add	X[15]=X[15],s0	    };;	// X[i]+=sigma0(X[i+1])
-+{ .mmi;		xor	r9=r9,r8		// Sigma1(e)
-+		add	X[15]=X[15],s1		// X[i]+=sigma0(X[i+14])
-+		_rotr	r8=$t0,$Sigma0[0]   };;	// ROTR(a,28)
-+{ .mmi;		add	K=K,X[15]
-+		add	T1=T1,r9		// T1+=Sigma1(e)
-+		_rotr	r9=$t0,$Sigma0[1]   };;	// ROTR(a,34)
-+{ .mmi;		add	T1=T1,K			// T1+=K[i]+X[i]
-+		xor	r8=r8,r9
-+		_rotr	r9=$t0,$Sigma0[2]   };;	// ROTR(a,39)
-+{ .mib;		add	D=D,T1
-+		mux2	H=X[15],0x44	    }	// mov H=X[15] in sha512
-+{ .mib;		xor	r8=r8,r9		// Sigma0(a)
-+		add	X[15]=T1,T2		// H=T1+Maj(a,b,c)
-+	br.ctop.sptk	.L_rest		    };;
-+.L_rest_end:
-+
-+{ .mmi;	add	A=A,r8			};;	// H+=Sigma0(a) from the past
-+{ .mmi;	add	A_=A_,A
-+	add	B_=B_,B
-+	add	C_=C_,C			}
-+{ .mmi;	add	D_=D_,D
-+	add	E_=E_,E
-+	cmp.ltu	p16,p0=1,num		};;
-+{ .mmi;	add	F_=F_,F
-+	add	G_=G_,G
-+	add	H_=H_,H			}
-+{ .mmb;	add	Ktbl=-$SZ*$rounds,Ktbl
-+(p16)	add	num=-1,num
-+(p16)	br.dptk.many	.L_outer	};;
-+
-+{ .mib;	add	r8=0*$SZ,ctx
-+	add	r9=1*$SZ,ctx		}
-+{ .mib;	add	r10=2*$SZ,ctx
-+	add	r11=3*$SZ,ctx		};;
-+{ .mmi;	$STW	[r8]=A_,4*$SZ
-+	$STW	[r9]=B_,4*$SZ
-+	mov	ar.lc=lcsave		}
-+{ .mmi;	$STW	[r10]=C_,4*$SZ
-+	$STW	[r11]=D_,4*$SZ
-+	mov	pr=prsave,0x1ffff	};;
-+{ .mmb;	$STW	[r8]=E_
-+	$STW	[r9]=F_			}
-+{ .mmb;	$STW	[r10]=G_
-+	$STW	[r11]=H_
-+	br.ret.sptk.many	b0	};;
-+.endp	$func#
-+___
-+
-+foreach(split($/,$code)) {
-+    s/\`([^\`]*)\`/eval $1/gem;
-+    s/_rotr(\s+)([^=]+)=([^,]+),([0-9]+)/shrp$1$2=$3,$3,$4/gm;
-+    if ($BITS==64) {
-+	s/mux2(\s+)([^=]+)=([^,]+),\S+/mov$1 $2=$3/gm;
-+	s/mux1(\s+)\S+/nop.i$1 0x0/gm	if ($big_endian);
-+	s/(shrp\s+X\[[^=]+)=([^,]+),([^,]+),([1-9]+)/$1=$3,$2,64-$4/gm
-+    						if (!$big_endian);
-+	s/ld1(\s+)X\[\S+/nop.m$1 0x0/gm;
-+    }
-+
-+    print $_,"\n";
-+}
-+
-+print<<___ if ($BITS==32);
-+.align	64
-+.type	K256#,\@object
-+K256:	data4	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+	data4	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+	data4	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+	data4	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+	data4	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+	data4	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+	data4	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+	data4	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+	data4	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+	data4	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+	data4	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+	data4	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+	data4	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+	data4	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+	data4	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+	data4	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+.size	K256#,$SZ*$rounds
-+stringz	"SHA256 block transform for IA64, CRYPTOGAMS by "
-+___
-+print<<___ if ($BITS==64);
-+.align	64
-+.type	K512#,\@object
-+K512:	data8	0x428a2f98d728ae22,0x7137449123ef65cd
-+	data8	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
-+	data8	0x3956c25bf348b538,0x59f111f1b605d019
-+	data8	0x923f82a4af194f9b,0xab1c5ed5da6d8118
-+	data8	0xd807aa98a3030242,0x12835b0145706fbe
-+	data8	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
-+	data8	0x72be5d74f27b896f,0x80deb1fe3b1696b1
-+	data8	0x9bdc06a725c71235,0xc19bf174cf692694
-+	data8	0xe49b69c19ef14ad2,0xefbe4786384f25e3
-+	data8	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
-+	data8	0x2de92c6f592b0275,0x4a7484aa6ea6e483
-+	data8	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
-+	data8	0x983e5152ee66dfab,0xa831c66d2db43210
-+	data8	0xb00327c898fb213f,0xbf597fc7beef0ee4
-+	data8	0xc6e00bf33da88fc2,0xd5a79147930aa725
-+	data8	0x06ca6351e003826f,0x142929670a0e6e70
-+	data8	0x27b70a8546d22ffc,0x2e1b21385c26c926
-+	data8	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
-+	data8	0x650a73548baf63de,0x766a0abb3c77b2a8
-+	data8	0x81c2c92e47edaee6,0x92722c851482353b
-+	data8	0xa2bfe8a14cf10364,0xa81a664bbc423001
-+	data8	0xc24b8b70d0f89791,0xc76c51a30654be30
-+	data8	0xd192e819d6ef5218,0xd69906245565a910
-+	data8	0xf40e35855771202a,0x106aa07032bbd1b8
-+	data8	0x19a4c116b8d2d0c8,0x1e376c085141ab53
-+	data8	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
-+	data8	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
-+	data8	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
-+	data8	0x748f82ee5defb2fc,0x78a5636f43172f60
-+	data8	0x84c87814a1f0ab72,0x8cc702081a6439ec
-+	data8	0x90befffa23631e28,0xa4506cebde82bde9
-+	data8	0xbef9a3f7b2c67915,0xc67178f2e372532b
-+	data8	0xca273eceea26619c,0xd186b8c721c0c207
-+	data8	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
-+	data8	0x06f067aa72176fba,0x0a637dc5a2c898a6
-+	data8	0x113f9804bef90dae,0x1b710b35131c471b
-+	data8	0x28db77f523047d84,0x32caab7b40c72493
-+	data8	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
-+	data8	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
-+	data8	0x5fcb6fab3ad6faec,0x6c44198c4a475817
-+.size	K512#,$SZ*$rounds
-+stringz	"SHA512 block transform for IA64, CRYPTOGAMS by "
-+___
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-mips.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-mips.pl
-new file mode 100644
-index 0000000..5c2d23f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-mips.pl
-@@ -0,0 +1,519 @@
-+#! /usr/bin/env perl
-+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# SHA2 block procedures for MIPS.
-+
-+# October 2010.
-+#
-+# SHA256 performance improvement on MIPS R5000 CPU is ~27% over gcc-
-+# generated code in o32 build and ~55% in n32/64 build. SHA512 [which
-+# for now can only be compiled for MIPS64 ISA] improvement is modest
-+# ~17%, but it comes for free, because it's same instruction sequence.
-+# Improvement coefficients are for aligned input.
-+
-+# September 2012.
-+#
-+# Add MIPS[32|64]R2 code (>25% less instructions).
-+
-+######################################################################
-+# There is a number of MIPS ABI in use, O32 and N32/64 are most
-+# widely used. Then there is a new contender: NUBI. It appears that if
-+# one picks the latter, it's possible to arrange code in ABI neutral
-+# manner. Therefore let's stick to NUBI register layout:
-+#
-+($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25));
-+($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23));
-+($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31));
-+#
-+# The return value is placed in $a0. Following coding rules facilitate
-+# interoperability:
-+#
-+# - never ever touch $tp, "thread pointer", former $gp [o32 can be
-+#   excluded from the rule, because it's specified volatile];
-+# - copy return value to $t0, former $v0 [or to $a0 if you're adapting
-+#   old code];
-+# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary;
-+#
-+# For reference here is register layout for N32/64 MIPS ABIs:
-+#
-+# ($zero,$at,$v0,$v1)=map("\$$_",(0..3));
-+# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11));
-+# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25));
-+# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
-+# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
-+#
-+$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64
-+
-+if ($flavour =~ /64|n32/i) {
-+	$PTR_LA="dla";
-+	$PTR_ADD="dadd";	# incidentally works even on n32
-+	$PTR_SUB="dsub";	# incidentally works even on n32
-+	$REG_S="sd";
-+	$REG_L="ld";
-+	$PTR_SLL="dsll";	# incidentally works even on n32
-+	$SZREG=8;
-+} else {
-+	$PTR_LA="la";
-+	$PTR_ADD="add";
-+	$PTR_SUB="sub";
-+	$REG_S="sw";
-+	$REG_L="lw";
-+	$PTR_SLL="sll";
-+	$SZREG=4;
-+}
-+$pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
-+#
-+# 
-+#
-+######################################################################
-+
-+$big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC});
-+
-+for (@ARGV) {	$output=$_ if (/\w[\w\-]*\.\w+$/);	}
-+open STDOUT,">$output";
-+
-+if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); }
-+
-+if ($output =~ /512/) {
-+	$label="512";
-+	$SZ=8;
-+	$LD="ld";		# load from memory
-+	$ST="sd";		# store to memory
-+	$SLL="dsll";		# shift left logical
-+	$SRL="dsrl";		# shift right logical
-+	$ADDU="daddu";
-+	$ROTR="drotr";
-+	@Sigma0=(28,34,39);
-+	@Sigma1=(14,18,41);
-+	@sigma0=( 7, 1, 8);	# right shift first
-+	@sigma1=( 6,19,61);	# right shift first
-+	$lastK=0x817;
-+	$rounds=80;
-+} else {
-+	$label="256";
-+	$SZ=4;
-+	$LD="lw";		# load from memory
-+	$ST="sw";		# store to memory
-+	$SLL="sll";		# shift left logical
-+	$SRL="srl";		# shift right logical
-+	$ADDU="addu";
-+	$ROTR="rotr";
-+	@Sigma0=( 2,13,22);
-+	@Sigma1=( 6,11,25);
-+	@sigma0=( 3, 7,18);	# right shift first
-+	@sigma1=(10,17,19);	# right shift first
-+	$lastK=0x8f2;
-+	$rounds=64;
-+}
-+
-+$MSB = $big_endian ? 0 : ($SZ-1);
-+$LSB = ($SZ-1)&~$MSB;
-+
-+@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("\$$_",(1,2,3,7,24,25,30,31));
-+@X=map("\$$_",(8..23));
-+
-+$ctx=$a0;
-+$inp=$a1;
-+$len=$a2;	$Ktbl=$len;
-+
-+sub BODY_00_15 {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+my ($T1,$tmp0,$tmp1,$tmp2)=(@X[4],@X[5],@X[6],@X[7]);
-+
-+$code.=<<___ if ($i<15);
-+	${LD}l	@X[1],`($i+1)*$SZ+$MSB`($inp)
-+	${LD}r	@X[1],`($i+1)*$SZ+$LSB`($inp)
-+___
-+$code.=<<___	if (!$big_endian && $i<16 && $SZ==4);
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	wsbh	@X[0],@X[0]		# byte swap($i)
-+	rotr	@X[0],@X[0],16
-+#else
-+	srl	$tmp0,@X[0],24		# byte swap($i)
-+	srl	$tmp1,@X[0],8
-+	andi	$tmp2,@X[0],0xFF00
-+	sll	@X[0],@X[0],24
-+	andi	$tmp1,0xFF00
-+	sll	$tmp2,$tmp2,8
-+	or	@X[0],$tmp0
-+	or	$tmp1,$tmp2
-+	or	@X[0],$tmp1
-+#endif
-+___
-+$code.=<<___	if (!$big_endian && $i<16 && $SZ==8);
-+#if defined(_MIPS_ARCH_MIPS64R2)
-+	dsbh	@X[0],@X[0]		# byte swap($i)
-+	dshd	@X[0],@X[0]
-+#else
-+	ori	$tmp0,$zero,0xFF
-+	dsll	$tmp2,$tmp0,32
-+	or	$tmp0,$tmp2		# 0x000000FF000000FF
-+	and	$tmp1,@X[0],$tmp0	# byte swap($i)
-+	dsrl	$tmp2,@X[0],24
-+	dsll	$tmp1,24
-+	and	$tmp2,$tmp0
-+	dsll	$tmp0,8			# 0x0000FF000000FF00
-+	or	$tmp1,$tmp2
-+	and	$tmp2,@X[0],$tmp0
-+	dsrl	@X[0],8
-+	dsll	$tmp2,8
-+	and	@X[0],$tmp0
-+	or	$tmp1,$tmp2
-+	or	@X[0],$tmp1
-+	dsrl	$tmp1,@X[0],32
-+	dsll	@X[0],32
-+	or	@X[0],$tmp1
-+#endif
-+___
-+$code.=<<___;
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	xor	$tmp2,$f,$g			# $i
-+	$ROTR	$tmp0,$e,@Sigma1[0]
-+	$ADDU	$T1,$X[0],$h
-+	$ROTR	$tmp1,$e,@Sigma1[1]
-+	and	$tmp2,$e
-+	$ROTR	$h,$e,@Sigma1[2]
-+	xor	$tmp0,$tmp1
-+	$ROTR	$tmp1,$a,@Sigma0[0]
-+	xor	$tmp2,$g			# Ch(e,f,g)
-+	xor	$tmp0,$h			# Sigma1(e)
-+
-+	$ROTR	$h,$a,@Sigma0[1]
-+	$ADDU	$T1,$tmp2
-+	$LD	$tmp2,`$i*$SZ`($Ktbl)		# K[$i]
-+	xor	$h,$tmp1
-+	$ROTR	$tmp1,$a,@Sigma0[2]
-+	$ADDU	$T1,$tmp0
-+	and	$tmp0,$b,$c
-+	xor	$h,$tmp1			# Sigma0(a)
-+	xor	$tmp1,$b,$c
-+#else
-+	$ADDU	$T1,$X[0],$h			# $i
-+	$SRL	$h,$e,@Sigma1[0]
-+	xor	$tmp2,$f,$g
-+	$SLL	$tmp1,$e,`$SZ*8-@Sigma1[2]`
-+	and	$tmp2,$e
-+	$SRL	$tmp0,$e,@Sigma1[1]
-+	xor	$h,$tmp1
-+	$SLL	$tmp1,$e,`$SZ*8-@Sigma1[1]`
-+	xor	$h,$tmp0
-+	$SRL	$tmp0,$e,@Sigma1[2]
-+	xor	$h,$tmp1
-+	$SLL	$tmp1,$e,`$SZ*8-@Sigma1[0]`
-+	xor	$h,$tmp0
-+	xor	$tmp2,$g			# Ch(e,f,g)
-+	xor	$tmp0,$tmp1,$h			# Sigma1(e)
-+
-+	$SRL	$h,$a,@Sigma0[0]
-+	$ADDU	$T1,$tmp2
-+	$LD	$tmp2,`$i*$SZ`($Ktbl)		# K[$i]
-+	$SLL	$tmp1,$a,`$SZ*8-@Sigma0[2]`
-+	$ADDU	$T1,$tmp0
-+	$SRL	$tmp0,$a,@Sigma0[1]
-+	xor	$h,$tmp1
-+	$SLL	$tmp1,$a,`$SZ*8-@Sigma0[1]`
-+	xor	$h,$tmp0
-+	$SRL	$tmp0,$a,@Sigma0[2]
-+	xor	$h,$tmp1
-+	$SLL	$tmp1,$a,`$SZ*8-@Sigma0[0]`
-+	xor	$h,$tmp0
-+	and	$tmp0,$b,$c
-+	xor	$h,$tmp1			# Sigma0(a)
-+	xor	$tmp1,$b,$c
-+#endif
-+	$ST	@X[0],`($i%16)*$SZ`($sp)	# offload to ring buffer
-+	$ADDU	$h,$tmp0
-+	and	$tmp1,$a
-+	$ADDU	$T1,$tmp2			# +=K[$i]
-+	$ADDU	$h,$tmp1			# +=Maj(a,b,c)
-+	$ADDU	$d,$T1
-+	$ADDU	$h,$T1
-+___
-+$code.=<<___ if ($i>=13);
-+	$LD	@X[3],`(($i+3)%16)*$SZ`($sp)	# prefetch from ring buffer
-+___
-+}
-+
-+sub BODY_16_XX {
-+my $i=@_[0];
-+my ($tmp0,$tmp1,$tmp2,$tmp3)=(@X[4],@X[5],@X[6],@X[7]);
-+
-+$code.=<<___;
-+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
-+	$SRL	$tmp2,@X[1],@sigma0[0]		# Xupdate($i)
-+	$ROTR	$tmp0,@X[1],@sigma0[1]
-+	$ADDU	@X[0],@X[9]			# +=X[i+9]
-+	xor	$tmp2,$tmp0
-+	$ROTR	$tmp0,@X[1],@sigma0[2]
-+
-+	$SRL	$tmp3,@X[14],@sigma1[0]
-+	$ROTR	$tmp1,@X[14],@sigma1[1]
-+	xor	$tmp2,$tmp0			# sigma0(X[i+1])
-+	$ROTR	$tmp0,@X[14],@sigma1[2]
-+	xor	$tmp3,$tmp1
-+	$ADDU	@X[0],$tmp2
-+#else
-+	$SRL	$tmp2,@X[1],@sigma0[0]		# Xupdate($i)
-+	$ADDU	@X[0],@X[9]			# +=X[i+9]
-+	$SLL	$tmp1,@X[1],`$SZ*8-@sigma0[2]`
-+	$SRL	$tmp0,@X[1],@sigma0[1]
-+	xor	$tmp2,$tmp1
-+	$SLL	$tmp1,`@sigma0[2]-@sigma0[1]`
-+	xor	$tmp2,$tmp0
-+	$SRL	$tmp0,@X[1],@sigma0[2]
-+	xor	$tmp2,$tmp1
-+
-+	$SRL	$tmp3,@X[14],@sigma1[0]
-+	xor	$tmp2,$tmp0			# sigma0(X[i+1])
-+	$SLL	$tmp1,@X[14],`$SZ*8-@sigma1[2]`
-+	$ADDU	@X[0],$tmp2
-+	$SRL	$tmp0,@X[14],@sigma1[1]
-+	xor	$tmp3,$tmp1
-+	$SLL	$tmp1,`@sigma1[2]-@sigma1[1]`
-+	xor	$tmp3,$tmp0
-+	$SRL	$tmp0,@X[14],@sigma1[2]
-+	xor	$tmp3,$tmp1
-+#endif
-+	xor	$tmp3,$tmp0			# sigma1(X[i+14])
-+	$ADDU	@X[0],$tmp3
-+___
-+	&BODY_00_15(@_);
-+}
-+
-+$FRAMESIZE=16*$SZ+16*$SZREG;
-+$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? "0xc0fff008" : "0xc0ff0000";
-+
-+$code.=<<___;
-+#ifdef OPENSSL_FIPSCANISTER
-+# include 
-+#endif
-+
-+#if defined(__mips_smartmips) && !defined(_MIPS_ARCH_MIPS32R2)
-+#define _MIPS_ARCH_MIPS32R2
-+#endif
-+
-+.text
-+.set	noat
-+#if !defined(__mips_eabi) && (!defined(__vxworks) || defined(__pic__))
-+.option	pic2
-+#endif
-+
-+.align	5
-+.globl	sha${label}_block_data_order
-+.ent	sha${label}_block_data_order
-+sha${label}_block_data_order:
-+	.frame	$sp,$FRAMESIZE,$ra
-+	.mask	$SAVED_REGS_MASK,-$SZREG
-+	.set	noreorder
-+___
-+$code.=<<___ if ($flavour =~ /o32/i);	# o32 PIC-ification
-+	.cpload	$pf
-+___
-+$code.=<<___;
-+	$PTR_SUB $sp,$FRAMESIZE
-+	$REG_S	$ra,$FRAMESIZE-1*$SZREG($sp)
-+	$REG_S	$fp,$FRAMESIZE-2*$SZREG($sp)
-+	$REG_S	$s11,$FRAMESIZE-3*$SZREG($sp)
-+	$REG_S	$s10,$FRAMESIZE-4*$SZREG($sp)
-+	$REG_S	$s9,$FRAMESIZE-5*$SZREG($sp)
-+	$REG_S	$s8,$FRAMESIZE-6*$SZREG($sp)
-+	$REG_S	$s7,$FRAMESIZE-7*$SZREG($sp)
-+	$REG_S	$s6,$FRAMESIZE-8*$SZREG($sp)
-+	$REG_S	$s5,$FRAMESIZE-9*$SZREG($sp)
-+	$REG_S	$s4,$FRAMESIZE-10*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
-+	$REG_S	$s3,$FRAMESIZE-11*$SZREG($sp)
-+	$REG_S	$s2,$FRAMESIZE-12*$SZREG($sp)
-+	$REG_S	$s1,$FRAMESIZE-13*$SZREG($sp)
-+	$REG_S	$s0,$FRAMESIZE-14*$SZREG($sp)
-+	$REG_S	$gp,$FRAMESIZE-15*$SZREG($sp)
-+___
-+$code.=<<___;
-+	$PTR_SLL @X[15],$len,`log(16*$SZ)/log(2)`
-+___
-+$code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
-+	.cplocal	$Ktbl
-+	.cpsetup	$pf,$zero,sha${label}_block_data_order
-+___
-+$code.=<<___;
-+	.set	reorder
-+	$PTR_LA	$Ktbl,K${label}		# PIC-ified 'load address'
-+
-+	$LD	$A,0*$SZ($ctx)		# load context
-+	$LD	$B,1*$SZ($ctx)
-+	$LD	$C,2*$SZ($ctx)
-+	$LD	$D,3*$SZ($ctx)
-+	$LD	$E,4*$SZ($ctx)
-+	$LD	$F,5*$SZ($ctx)
-+	$LD	$G,6*$SZ($ctx)
-+	$LD	$H,7*$SZ($ctx)
-+
-+	$PTR_ADD @X[15],$inp		# pointer to the end of input
-+	$REG_S	@X[15],16*$SZ($sp)
-+	b	.Loop
-+
-+.align	5
-+.Loop:
-+	${LD}l	@X[0],$MSB($inp)
-+	${LD}r	@X[0],$LSB($inp)
-+___
-+for ($i=0;$i<16;$i++)
-+{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); push(@X,shift(@X)); }
-+$code.=<<___;
-+	b	.L16_xx
-+.align	4
-+.L16_xx:
-+___
-+for (;$i<32;$i++)
-+{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); push(@X,shift(@X)); }
-+$code.=<<___;
-+	and	@X[6],0xfff
-+	li	@X[7],$lastK
-+	.set	noreorder
-+	bne	@X[6],@X[7],.L16_xx
-+	$PTR_ADD $Ktbl,16*$SZ		# Ktbl+=16
-+
-+	$REG_L	@X[15],16*$SZ($sp)	# restore pointer to the end of input
-+	$LD	@X[0],0*$SZ($ctx)
-+	$LD	@X[1],1*$SZ($ctx)
-+	$LD	@X[2],2*$SZ($ctx)
-+	$PTR_ADD $inp,16*$SZ
-+	$LD	@X[3],3*$SZ($ctx)
-+	$ADDU	$A,@X[0]
-+	$LD	@X[4],4*$SZ($ctx)
-+	$ADDU	$B,@X[1]
-+	$LD	@X[5],5*$SZ($ctx)
-+	$ADDU	$C,@X[2]
-+	$LD	@X[6],6*$SZ($ctx)
-+	$ADDU	$D,@X[3]
-+	$LD	@X[7],7*$SZ($ctx)
-+	$ADDU	$E,@X[4]
-+	$ST	$A,0*$SZ($ctx)
-+	$ADDU	$F,@X[5]
-+	$ST	$B,1*$SZ($ctx)
-+	$ADDU	$G,@X[6]
-+	$ST	$C,2*$SZ($ctx)
-+	$ADDU	$H,@X[7]
-+	$ST	$D,3*$SZ($ctx)
-+	$ST	$E,4*$SZ($ctx)
-+	$ST	$F,5*$SZ($ctx)
-+	$ST	$G,6*$SZ($ctx)
-+	$ST	$H,7*$SZ($ctx)
-+
-+	bne	$inp,@X[15],.Loop
-+	$PTR_SUB $Ktbl,`($rounds-16)*$SZ`	# rewind $Ktbl
-+
-+	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
-+	$REG_L	$fp,$FRAMESIZE-2*$SZREG($sp)
-+	$REG_L	$s11,$FRAMESIZE-3*$SZREG($sp)
-+	$REG_L	$s10,$FRAMESIZE-4*$SZREG($sp)
-+	$REG_L	$s9,$FRAMESIZE-5*$SZREG($sp)
-+	$REG_L	$s8,$FRAMESIZE-6*$SZREG($sp)
-+	$REG_L	$s7,$FRAMESIZE-7*$SZREG($sp)
-+	$REG_L	$s6,$FRAMESIZE-8*$SZREG($sp)
-+	$REG_L	$s5,$FRAMESIZE-9*$SZREG($sp)
-+	$REG_L	$s4,$FRAMESIZE-10*$SZREG($sp)
-+___
-+$code.=<<___ if ($flavour =~ /nubi/i);
-+	$REG_L	$s3,$FRAMESIZE-11*$SZREG($sp)
-+	$REG_L	$s2,$FRAMESIZE-12*$SZREG($sp)
-+	$REG_L	$s1,$FRAMESIZE-13*$SZREG($sp)
-+	$REG_L	$s0,$FRAMESIZE-14*$SZREG($sp)
-+	$REG_L	$gp,$FRAMESIZE-15*$SZREG($sp)
-+___
-+$code.=<<___;
-+	jr	$ra
-+	$PTR_ADD $sp,$FRAMESIZE
-+.end	sha${label}_block_data_order
-+
-+.rdata
-+.align	5
-+K${label}:
-+___
-+if ($SZ==4) {
-+$code.=<<___;
-+	.word	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
-+	.word	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
-+	.word	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
-+	.word	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
-+	.word	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
-+	.word	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
-+	.word	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
-+	.word	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
-+	.word	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
-+	.word	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
-+	.word	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
-+	.word	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
-+	.word	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
-+	.word	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
-+	.word	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
-+	.word	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-+___
-+} else {
-+$code.=<<___;
-+	.dword	0x428a2f98d728ae22, 0x7137449123ef65cd
-+	.dword	0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc
-+	.dword	0x3956c25bf348b538, 0x59f111f1b605d019
-+	.dword	0x923f82a4af194f9b, 0xab1c5ed5da6d8118
-+	.dword	0xd807aa98a3030242, 0x12835b0145706fbe
-+	.dword	0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2
-+	.dword	0x72be5d74f27b896f, 0x80deb1fe3b1696b1
-+	.dword	0x9bdc06a725c71235, 0xc19bf174cf692694
-+	.dword	0xe49b69c19ef14ad2, 0xefbe4786384f25e3
-+	.dword	0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65
-+	.dword	0x2de92c6f592b0275, 0x4a7484aa6ea6e483
-+	.dword	0x5cb0a9dcbd41fbd4, 0x76f988da831153b5
-+	.dword	0x983e5152ee66dfab, 0xa831c66d2db43210
-+	.dword	0xb00327c898fb213f, 0xbf597fc7beef0ee4
-+	.dword	0xc6e00bf33da88fc2, 0xd5a79147930aa725
-+	.dword	0x06ca6351e003826f, 0x142929670a0e6e70
-+	.dword	0x27b70a8546d22ffc, 0x2e1b21385c26c926
-+	.dword	0x4d2c6dfc5ac42aed, 0x53380d139d95b3df
-+	.dword	0x650a73548baf63de, 0x766a0abb3c77b2a8
-+	.dword	0x81c2c92e47edaee6, 0x92722c851482353b
-+	.dword	0xa2bfe8a14cf10364, 0xa81a664bbc423001
-+	.dword	0xc24b8b70d0f89791, 0xc76c51a30654be30
-+	.dword	0xd192e819d6ef5218, 0xd69906245565a910
-+	.dword	0xf40e35855771202a, 0x106aa07032bbd1b8
-+	.dword	0x19a4c116b8d2d0c8, 0x1e376c085141ab53
-+	.dword	0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8
-+	.dword	0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb
-+	.dword	0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3
-+	.dword	0x748f82ee5defb2fc, 0x78a5636f43172f60
-+	.dword	0x84c87814a1f0ab72, 0x8cc702081a6439ec
-+	.dword	0x90befffa23631e28, 0xa4506cebde82bde9
-+	.dword	0xbef9a3f7b2c67915, 0xc67178f2e372532b
-+	.dword	0xca273eceea26619c, 0xd186b8c721c0c207
-+	.dword	0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178
-+	.dword	0x06f067aa72176fba, 0x0a637dc5a2c898a6
-+	.dword	0x113f9804bef90dae, 0x1b710b35131c471b
-+	.dword	0x28db77f523047d84, 0x32caab7b40c72493
-+	.dword	0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c
-+	.dword	0x4cc5d4becb3e42b6, 0x597f299cfc657e2a
-+	.dword	0x5fcb6fab3ad6faec, 0x6c44198c4a475817
-+___
-+}
-+$code.=<<___;
-+.asciiz	"SHA${label} for MIPS, CRYPTOGAMS by "
-+.align	5
-+
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-parisc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-parisc.pl
-new file mode 100755
-index 0000000..fcb6157
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-parisc.pl
-@@ -0,0 +1,800 @@
-+#! /usr/bin/env perl
-+# Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# SHA256/512 block procedure for PA-RISC.
-+
-+# June 2009.
-+#
-+# SHA256 performance is >75% better than gcc 3.2 generated code on
-+# PA-7100LC. Compared to code generated by vendor compiler this
-+# implementation is almost 70% faster in 64-bit build, but delivers
-+# virtually same performance in 32-bit build on PA-8600.
-+#
-+# SHA512 performance is >2.9x better than gcc 3.2 generated code on
-+# PA-7100LC, PA-RISC 1.1 processor. Then implementation detects if the
-+# code is executed on PA-RISC 2.0 processor and switches to 64-bit
-+# code path delivering adequate performance even in "blended" 32-bit
-+# build. Though 64-bit code is not any faster than code generated by
-+# vendor compiler on PA-8600...
-+#
-+# Special thanks to polarhome.com for providing HP-UX account.
-+
-+$flavour = shift;
-+$output = shift;
-+open STDOUT,">$output";
-+
-+if ($flavour =~ /64/) {
-+	$LEVEL		="2.0W";
-+	$SIZE_T		=8;
-+	$FRAME_MARKER	=80;
-+	$SAVED_RP	=16;
-+	$PUSH		="std";
-+	$PUSHMA		="std,ma";
-+	$POP		="ldd";
-+	$POPMB		="ldd,mb";
-+} else {
-+	$LEVEL		="1.0";
-+	$SIZE_T		=4;
-+	$FRAME_MARKER	=48;
-+	$SAVED_RP	=20;
-+	$PUSH		="stw";
-+	$PUSHMA		="stwm";
-+	$POP		="ldw";
-+	$POPMB		="ldwm";
-+}
-+
-+if ($output =~ /512/) {
-+	$func="sha512_block_data_order";
-+	$SZ=8;
-+	@Sigma0=(28,34,39);
-+	@Sigma1=(14,18,41);
-+	@sigma0=(1,  8, 7);
-+	@sigma1=(19,61, 6);
-+	$rounds=80;
-+	$LAST10BITS=0x017;
-+	$LD="ldd";
-+	$LDM="ldd,ma";
-+	$ST="std";
-+} else {
-+	$func="sha256_block_data_order";
-+	$SZ=4;
-+	@Sigma0=( 2,13,22);
-+	@Sigma1=( 6,11,25);
-+	@sigma0=( 7,18, 3);
-+	@sigma1=(17,19,10);
-+	$rounds=64;
-+	$LAST10BITS=0x0f2;
-+	$LD="ldw";
-+	$LDM="ldwm";
-+	$ST="stw";
-+}
-+
-+$FRAME=16*$SIZE_T+$FRAME_MARKER;# 16 saved regs + frame marker
-+				#                 [+ argument transfer]
-+$XOFF=16*$SZ+32;		# local variables
-+$FRAME+=$XOFF;
-+$XOFF+=$FRAME_MARKER;		# distance between %sp and local variables
-+
-+$ctx="%r26";	# zapped by $a0
-+$inp="%r25";	# zapped by $a1
-+$num="%r24";	# zapped by $t0
-+
-+$a0 ="%r26";
-+$a1 ="%r25";
-+$t0 ="%r24";
-+$t1 ="%r29";
-+$Tbl="%r31";
-+
-+@V=($A,$B,$C,$D,$E,$F,$G,$H)=("%r17","%r18","%r19","%r20","%r21","%r22","%r23","%r28");
-+
-+@X=("%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8",
-+    "%r9", "%r10","%r11","%r12","%r13","%r14","%r15","%r16",$inp);
-+
-+sub ROUND_00_15 {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+$code.=<<___;
-+	_ror	$e,$Sigma1[0],$a0
-+	and	$f,$e,$t0
-+	_ror	$e,$Sigma1[1],$a1
-+	addl	$t1,$h,$h
-+	andcm	$g,$e,$t1
-+	xor	$a1,$a0,$a0
-+	_ror	$a1,`$Sigma1[2]-$Sigma1[1]`,$a1
-+	or	$t0,$t1,$t1		; Ch(e,f,g)
-+	addl	@X[$i%16],$h,$h
-+	xor	$a0,$a1,$a1		; Sigma1(e)
-+	addl	$t1,$h,$h
-+	_ror	$a,$Sigma0[0],$a0
-+	addl	$a1,$h,$h
-+
-+	_ror	$a,$Sigma0[1],$a1
-+	and	$a,$b,$t0
-+	and	$a,$c,$t1
-+	xor	$a1,$a0,$a0
-+	_ror	$a1,`$Sigma0[2]-$Sigma0[1]`,$a1
-+	xor	$t1,$t0,$t0
-+	and	$b,$c,$t1
-+	xor	$a0,$a1,$a1		; Sigma0(a)
-+	addl	$h,$d,$d
-+	xor	$t1,$t0,$t0		; Maj(a,b,c)
-+	`"$LDM	$SZ($Tbl),$t1" if ($i<15)`
-+	addl	$a1,$h,$h
-+	addl	$t0,$h,$h
-+
-+___
-+}
-+
-+sub ROUND_16_xx {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+$i-=16;
-+$code.=<<___;
-+	_ror	@X[($i+1)%16],$sigma0[0],$a0
-+	_ror	@X[($i+1)%16],$sigma0[1],$a1
-+	addl	@X[($i+9)%16],@X[$i],@X[$i]
-+	_ror	@X[($i+14)%16],$sigma1[0],$t0
-+	_ror	@X[($i+14)%16],$sigma1[1],$t1
-+	xor	$a1,$a0,$a0
-+	_shr	@X[($i+1)%16],$sigma0[2],$a1
-+	xor	$t1,$t0,$t0
-+	_shr	@X[($i+14)%16],$sigma1[2],$t1
-+	xor	$a1,$a0,$a0		; sigma0(X[(i+1)&0x0f])
-+	xor	$t1,$t0,$t0		; sigma1(X[(i+14)&0x0f])
-+	$LDM	$SZ($Tbl),$t1
-+	addl	$a0,@X[$i],@X[$i]
-+	addl	$t0,@X[$i],@X[$i]
-+___
-+$code.=<<___ if ($i==15);
-+	extru	$t1,31,10,$a1
-+	comiclr,<> $LAST10BITS,$a1,%r0
-+	ldo	1($Tbl),$Tbl		; signal end of $Tbl
-+___
-+&ROUND_00_15($i+16,$a,$b,$c,$d,$e,$f,$g,$h);
-+}
-+
-+$code=<<___;
-+	.LEVEL	$LEVEL
-+	.SPACE	\$TEXT\$
-+	.SUBSPA	\$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY
-+
-+	.ALIGN	64
-+L\$table
-+___
-+$code.=<<___ if ($SZ==8);
-+	.WORD	0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd
-+	.WORD	0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc
-+	.WORD	0x3956c25b,0xf348b538,0x59f111f1,0xb605d019
-+	.WORD	0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118
-+	.WORD	0xd807aa98,0xa3030242,0x12835b01,0x45706fbe
-+	.WORD	0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2
-+	.WORD	0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1
-+	.WORD	0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694
-+	.WORD	0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3
-+	.WORD	0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65
-+	.WORD	0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483
-+	.WORD	0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5
-+	.WORD	0x983e5152,0xee66dfab,0xa831c66d,0x2db43210
-+	.WORD	0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4
-+	.WORD	0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725
-+	.WORD	0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70
-+	.WORD	0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926
-+	.WORD	0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df
-+	.WORD	0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8
-+	.WORD	0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b
-+	.WORD	0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001
-+	.WORD	0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30
-+	.WORD	0xd192e819,0xd6ef5218,0xd6990624,0x5565a910
-+	.WORD	0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8
-+	.WORD	0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53
-+	.WORD	0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8
-+	.WORD	0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb
-+	.WORD	0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3
-+	.WORD	0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60
-+	.WORD	0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec
-+	.WORD	0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9
-+	.WORD	0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b
-+	.WORD	0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207
-+	.WORD	0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178
-+	.WORD	0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6
-+	.WORD	0x113f9804,0xbef90dae,0x1b710b35,0x131c471b
-+	.WORD	0x28db77f5,0x23047d84,0x32caab7b,0x40c72493
-+	.WORD	0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c
-+	.WORD	0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a
-+	.WORD	0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817
-+___
-+$code.=<<___ if ($SZ==4);
-+	.WORD	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+	.WORD	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+	.WORD	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+	.WORD	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+	.WORD	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+	.WORD	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+	.WORD	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+	.WORD	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+	.WORD	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+	.WORD	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+	.WORD	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+	.WORD	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+	.WORD	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+	.WORD	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+	.WORD	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+	.WORD	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+___
-+$code.=<<___;
-+
-+	.EXPORT	$func,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR
-+	.ALIGN	64
-+$func
-+	.PROC
-+	.CALLINFO	FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18
-+	.ENTRY
-+	$PUSH	%r2,-$SAVED_RP(%sp)	; standard prologue
-+	$PUSHMA	%r3,$FRAME(%sp)
-+	$PUSH	%r4,`-$FRAME+1*$SIZE_T`(%sp)
-+	$PUSH	%r5,`-$FRAME+2*$SIZE_T`(%sp)
-+	$PUSH	%r6,`-$FRAME+3*$SIZE_T`(%sp)
-+	$PUSH	%r7,`-$FRAME+4*$SIZE_T`(%sp)
-+	$PUSH	%r8,`-$FRAME+5*$SIZE_T`(%sp)
-+	$PUSH	%r9,`-$FRAME+6*$SIZE_T`(%sp)
-+	$PUSH	%r10,`-$FRAME+7*$SIZE_T`(%sp)
-+	$PUSH	%r11,`-$FRAME+8*$SIZE_T`(%sp)
-+	$PUSH	%r12,`-$FRAME+9*$SIZE_T`(%sp)
-+	$PUSH	%r13,`-$FRAME+10*$SIZE_T`(%sp)
-+	$PUSH	%r14,`-$FRAME+11*$SIZE_T`(%sp)
-+	$PUSH	%r15,`-$FRAME+12*$SIZE_T`(%sp)
-+	$PUSH	%r16,`-$FRAME+13*$SIZE_T`(%sp)
-+	$PUSH	%r17,`-$FRAME+14*$SIZE_T`(%sp)
-+	$PUSH	%r18,`-$FRAME+15*$SIZE_T`(%sp)
-+
-+	_shl	$num,`log(16*$SZ)/log(2)`,$num
-+	addl	$inp,$num,$num		; $num to point at the end of $inp
-+
-+	$PUSH	$num,`-$FRAME_MARKER-4*$SIZE_T`(%sp)	; save arguments
-+	$PUSH	$inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp)
-+	$PUSH	$ctx,`-$FRAME_MARKER-2*$SIZE_T`(%sp)
-+
-+	blr	%r0,$Tbl
-+	ldi	3,$t1
-+L\$pic
-+	andcm	$Tbl,$t1,$Tbl		; wipe privilege level
-+	ldo	L\$table-L\$pic($Tbl),$Tbl
-+___
-+$code.=<<___ if ($SZ==8 && $SIZE_T==4);
-+	ldi	31,$t1
-+	mtctl	$t1,%cr11
-+	extrd,u,*= $t1,%sar,1,$t1	; executes on PA-RISC 1.0
-+	b	L\$parisc1
-+	nop
-+___
-+$code.=<<___;
-+	$LD	`0*$SZ`($ctx),$A	; load context
-+	$LD	`1*$SZ`($ctx),$B
-+	$LD	`2*$SZ`($ctx),$C
-+	$LD	`3*$SZ`($ctx),$D
-+	$LD	`4*$SZ`($ctx),$E
-+	$LD	`5*$SZ`($ctx),$F
-+	$LD	`6*$SZ`($ctx),$G
-+	$LD	`7*$SZ`($ctx),$H
-+
-+	extru	$inp,31,`log($SZ)/log(2)`,$t0
-+	sh3addl	$t0,%r0,$t0
-+	subi	`8*$SZ`,$t0,$t0
-+	mtctl	$t0,%cr11		; load %sar with align factor
-+
-+L\$oop
-+	ldi	`$SZ-1`,$t0
-+	$LDM	$SZ($Tbl),$t1
-+	andcm	$inp,$t0,$t0		; align $inp
-+___
-+	for ($i=0;$i<15;$i++) {		# load input block
-+	$code.="\t$LD	`$SZ*$i`($t0),@X[$i]\n";		}
-+$code.=<<___;
-+	cmpb,*=	$inp,$t0,L\$aligned
-+	$LD	`$SZ*15`($t0),@X[15]
-+	$LD	`$SZ*16`($t0),@X[16]
-+___
-+	for ($i=0;$i<16;$i++) {		# align data
-+	$code.="\t_align	@X[$i],@X[$i+1],@X[$i]\n";	}
-+$code.=<<___;
-+L\$aligned
-+	nop	; otherwise /usr/ccs/bin/as is confused by below .WORD
-+___
-+
-+for($i=0;$i<16;$i++)	{ &ROUND_00_15($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+L\$rounds
-+	nop	; otherwise /usr/ccs/bin/as is confused by below .WORD
-+___
-+for(;$i<32;$i++)	{ &ROUND_16_xx($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	bb,>=	$Tbl,31,L\$rounds	; end of $Tbl signalled?
-+	nop
-+
-+	$POP	`-$FRAME_MARKER-2*$SIZE_T`(%sp),$ctx	; restore arguments
-+	$POP	`-$FRAME_MARKER-3*$SIZE_T`(%sp),$inp
-+	$POP	`-$FRAME_MARKER-4*$SIZE_T`(%sp),$num
-+	ldo	`-$rounds*$SZ-1`($Tbl),$Tbl		; rewind $Tbl
-+
-+	$LD	`0*$SZ`($ctx),@X[0]	; load context
-+	$LD	`1*$SZ`($ctx),@X[1]
-+	$LD	`2*$SZ`($ctx),@X[2]
-+	$LD	`3*$SZ`($ctx),@X[3]
-+	$LD	`4*$SZ`($ctx),@X[4]
-+	$LD	`5*$SZ`($ctx),@X[5]
-+	addl	@X[0],$A,$A
-+	$LD	`6*$SZ`($ctx),@X[6]
-+	addl	@X[1],$B,$B
-+	$LD	`7*$SZ`($ctx),@X[7]
-+	ldo	`16*$SZ`($inp),$inp	; advance $inp
-+
-+	$ST	$A,`0*$SZ`($ctx)	; save context
-+	addl	@X[2],$C,$C
-+	$ST	$B,`1*$SZ`($ctx)
-+	addl	@X[3],$D,$D
-+	$ST	$C,`2*$SZ`($ctx)
-+	addl	@X[4],$E,$E
-+	$ST	$D,`3*$SZ`($ctx)
-+	addl	@X[5],$F,$F
-+	$ST	$E,`4*$SZ`($ctx)
-+	addl	@X[6],$G,$G
-+	$ST	$F,`5*$SZ`($ctx)
-+	addl	@X[7],$H,$H
-+	$ST	$G,`6*$SZ`($ctx)
-+	$ST	$H,`7*$SZ`($ctx)
-+
-+	cmpb,*<>,n $inp,$num,L\$oop
-+	$PUSH	$inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp)	; save $inp
-+___
-+if ($SZ==8 && $SIZE_T==4)	# SHA512 for 32-bit PA-RISC 1.0
-+{{
-+$code.=<<___;
-+	b	L\$done
-+	nop
-+
-+	.ALIGN	64
-+L\$parisc1
-+___
-+
-+@V=(  $Ahi,  $Alo,  $Bhi,  $Blo,  $Chi,  $Clo,  $Dhi,  $Dlo,
-+      $Ehi,  $Elo,  $Fhi,  $Flo,  $Ghi,  $Glo,  $Hhi,  $Hlo) = 
-+   ( "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8",
-+     "%r9","%r10","%r11","%r12","%r13","%r14","%r15","%r16");
-+$a0 ="%r17";
-+$a1 ="%r18";
-+$a2 ="%r19";
-+$a3 ="%r20";
-+$t0 ="%r21";
-+$t1 ="%r22";
-+$t2 ="%r28";
-+$t3 ="%r29";
-+$Tbl="%r31";
-+
-+@X=("%r23","%r24","%r25","%r26");	# zaps $num,$inp,$ctx
-+
-+sub ROUND_00_15_pa1 {
-+my ($i,$ahi,$alo,$bhi,$blo,$chi,$clo,$dhi,$dlo,
-+       $ehi,$elo,$fhi,$flo,$ghi,$glo,$hhi,$hlo,$flag)=@_;
-+my ($Xhi,$Xlo,$Xnhi,$Xnlo) = @X;
-+
-+$code.=<<___ if (!$flag);
-+	ldw	`-$XOFF+8*(($i+1)%16)`(%sp),$Xnhi
-+	ldw	`-$XOFF+8*(($i+1)%16)+4`(%sp),$Xnlo	; load X[i+1]
-+___
-+$code.=<<___;
-+	shd	$ehi,$elo,$Sigma1[0],$t0
-+	 add	$Xlo,$hlo,$hlo
-+	shd	$elo,$ehi,$Sigma1[0],$t1
-+	 addc	$Xhi,$hhi,$hhi		; h += X[i]
-+	shd	$ehi,$elo,$Sigma1[1],$t2
-+	 ldwm	8($Tbl),$Xhi
-+	shd	$elo,$ehi,$Sigma1[1],$t3
-+	 ldw	-4($Tbl),$Xlo		; load K[i]
-+	xor	$t2,$t0,$t0
-+	xor	$t3,$t1,$t1
-+	 and	$flo,$elo,$a0
-+	 and	$fhi,$ehi,$a1
-+	shd	$ehi,$elo,$Sigma1[2],$t2
-+	 andcm	$glo,$elo,$a2
-+	shd	$elo,$ehi,$Sigma1[2],$t3
-+	 andcm	$ghi,$ehi,$a3
-+	xor	$t2,$t0,$t0
-+	xor	$t3,$t1,$t1		; Sigma1(e)
-+	add	$Xlo,$hlo,$hlo
-+	 xor	$a2,$a0,$a0
-+	addc	$Xhi,$hhi,$hhi		; h += K[i]
-+	 xor	$a3,$a1,$a1		; Ch(e,f,g)
-+
-+	 add	$t0,$hlo,$hlo
-+	shd	$ahi,$alo,$Sigma0[0],$t0
-+	 addc	$t1,$hhi,$hhi		; h += Sigma1(e)
-+	shd	$alo,$ahi,$Sigma0[0],$t1	
-+	 add	$a0,$hlo,$hlo
-+	shd	$ahi,$alo,$Sigma0[1],$t2
-+	 addc	$a1,$hhi,$hhi		; h += Ch(e,f,g)
-+	shd	$alo,$ahi,$Sigma0[1],$t3
-+
-+	xor	$t2,$t0,$t0
-+	xor	$t3,$t1,$t1
-+	shd	$ahi,$alo,$Sigma0[2],$t2
-+	and	$alo,$blo,$a0
-+	shd	$alo,$ahi,$Sigma0[2],$t3
-+	and	$ahi,$bhi,$a1
-+	xor	$t2,$t0,$t0
-+	xor	$t3,$t1,$t1		; Sigma0(a)
-+
-+	and	$alo,$clo,$a2
-+	and	$ahi,$chi,$a3
-+	xor	$a2,$a0,$a0
-+	 add	$hlo,$dlo,$dlo
-+	xor	$a3,$a1,$a1
-+	 addc	$hhi,$dhi,$dhi		; d += h
-+	and	$blo,$clo,$a2
-+	 add	$t0,$hlo,$hlo
-+	and	$bhi,$chi,$a3
-+	 addc	$t1,$hhi,$hhi		; h += Sigma0(a)
-+	xor	$a2,$a0,$a0
-+	 add	$a0,$hlo,$hlo
-+	xor	$a3,$a1,$a1		; Maj(a,b,c)
-+	 addc	$a1,$hhi,$hhi		; h += Maj(a,b,c)
-+
-+___
-+$code.=<<___ if ($i==15 && $flag);
-+	extru	$Xlo,31,10,$Xlo
-+	comiclr,= $LAST10BITS,$Xlo,%r0
-+	b	L\$rounds_pa1
-+	nop
-+___
-+push(@X,shift(@X)); push(@X,shift(@X));
-+}
-+
-+sub ROUND_16_xx_pa1 {
-+my ($Xhi,$Xlo,$Xnhi,$Xnlo) = @X;
-+my ($i)=shift;
-+$i-=16;
-+$code.=<<___;
-+	ldw	`-$XOFF+8*(($i+1)%16)`(%sp),$Xnhi
-+	ldw	`-$XOFF+8*(($i+1)%16)+4`(%sp),$Xnlo	; load X[i+1]
-+	ldw	`-$XOFF+8*(($i+9)%16)`(%sp),$a1
-+	ldw	`-$XOFF+8*(($i+9)%16)+4`(%sp),$a0	; load X[i+9]
-+	ldw	`-$XOFF+8*(($i+14)%16)`(%sp),$a3
-+	ldw	`-$XOFF+8*(($i+14)%16)+4`(%sp),$a2	; load X[i+14]
-+	shd	$Xnhi,$Xnlo,$sigma0[0],$t0
-+	shd	$Xnlo,$Xnhi,$sigma0[0],$t1
-+	 add	$a0,$Xlo,$Xlo
-+	shd	$Xnhi,$Xnlo,$sigma0[1],$t2
-+	 addc	$a1,$Xhi,$Xhi
-+	shd	$Xnlo,$Xnhi,$sigma0[1],$t3
-+	xor	$t2,$t0,$t0
-+	shd	$Xnhi,$Xnlo,$sigma0[2],$t2
-+	xor	$t3,$t1,$t1
-+	extru	$Xnhi,`31-$sigma0[2]`,`32-$sigma0[2]`,$t3
-+	xor	$t2,$t0,$t0
-+	 shd	$a3,$a2,$sigma1[0],$a0
-+	xor	$t3,$t1,$t1		; sigma0(X[i+1)&0x0f])
-+	 shd	$a2,$a3,$sigma1[0],$a1
-+	add	$t0,$Xlo,$Xlo
-+	 shd	$a3,$a2,$sigma1[1],$t2
-+	addc	$t1,$Xhi,$Xhi
-+	 shd	$a2,$a3,$sigma1[1],$t3
-+	xor	$t2,$a0,$a0
-+	shd	$a3,$a2,$sigma1[2],$t2
-+	xor	$t3,$a1,$a1
-+	extru	$a3,`31-$sigma1[2]`,`32-$sigma1[2]`,$t3
-+	xor	$t2,$a0,$a0
-+	xor	$t3,$a1,$a1		; sigma0(X[i+14)&0x0f])
-+	add	$a0,$Xlo,$Xlo
-+	addc	$a1,$Xhi,$Xhi
-+
-+	stw	$Xhi,`-$XOFF+8*($i%16)`(%sp)
-+	stw	$Xlo,`-$XOFF+8*($i%16)+4`(%sp)
-+___
-+&ROUND_00_15_pa1($i,@_,1);
-+}
-+$code.=<<___;
-+	ldw	`0*4`($ctx),$Ahi		; load context
-+	ldw	`1*4`($ctx),$Alo
-+	ldw	`2*4`($ctx),$Bhi
-+	ldw	`3*4`($ctx),$Blo
-+	ldw	`4*4`($ctx),$Chi
-+	ldw	`5*4`($ctx),$Clo
-+	ldw	`6*4`($ctx),$Dhi
-+	ldw	`7*4`($ctx),$Dlo
-+	ldw	`8*4`($ctx),$Ehi
-+	ldw	`9*4`($ctx),$Elo
-+	ldw	`10*4`($ctx),$Fhi
-+	ldw	`11*4`($ctx),$Flo
-+	ldw	`12*4`($ctx),$Ghi
-+	ldw	`13*4`($ctx),$Glo
-+	ldw	`14*4`($ctx),$Hhi
-+	ldw	`15*4`($ctx),$Hlo
-+
-+	extru	$inp,31,2,$t0
-+	sh3addl	$t0,%r0,$t0
-+	subi	32,$t0,$t0
-+	mtctl	$t0,%cr11		; load %sar with align factor
-+
-+L\$oop_pa1
-+	extru	$inp,31,2,$a3
-+	comib,=	0,$a3,L\$aligned_pa1
-+	sub	$inp,$a3,$inp
-+
-+	ldw	`0*4`($inp),$X[0]
-+	ldw	`1*4`($inp),$X[1]
-+	ldw	`2*4`($inp),$t2
-+	ldw	`3*4`($inp),$t3
-+	ldw	`4*4`($inp),$a0
-+	ldw	`5*4`($inp),$a1
-+	ldw	`6*4`($inp),$a2
-+	ldw	`7*4`($inp),$a3
-+	vshd	$X[0],$X[1],$X[0]
-+	vshd	$X[1],$t2,$X[1]
-+	stw	$X[0],`-$XOFF+0*4`(%sp)
-+	ldw	`8*4`($inp),$t0
-+	vshd	$t2,$t3,$t2
-+	stw	$X[1],`-$XOFF+1*4`(%sp)
-+	ldw	`9*4`($inp),$t1
-+	vshd	$t3,$a0,$t3
-+___
-+{
-+my @t=($t2,$t3,$a0,$a1,$a2,$a3,$t0,$t1);
-+for ($i=2;$i<=(128/4-8);$i++) {
-+$code.=<<___;
-+	stw	$t[0],`-$XOFF+$i*4`(%sp)
-+	ldw	`(8+$i)*4`($inp),$t[0]
-+	vshd	$t[1],$t[2],$t[1]
-+___
-+push(@t,shift(@t));
-+}
-+for (;$i<(128/4-1);$i++) {
-+$code.=<<___;
-+	stw	$t[0],`-$XOFF+$i*4`(%sp)
-+	vshd	$t[1],$t[2],$t[1]
-+___
-+push(@t,shift(@t));
-+}
-+$code.=<<___;
-+	b	L\$collected_pa1
-+	stw	$t[0],`-$XOFF+$i*4`(%sp)
-+
-+___
-+}
-+$code.=<<___;
-+L\$aligned_pa1
-+	ldw	`0*4`($inp),$X[0]
-+	ldw	`1*4`($inp),$X[1]
-+	ldw	`2*4`($inp),$t2
-+	ldw	`3*4`($inp),$t3
-+	ldw	`4*4`($inp),$a0
-+	ldw	`5*4`($inp),$a1
-+	ldw	`6*4`($inp),$a2
-+	ldw	`7*4`($inp),$a3
-+	stw	$X[0],`-$XOFF+0*4`(%sp)
-+	ldw	`8*4`($inp),$t0
-+	stw	$X[1],`-$XOFF+1*4`(%sp)
-+	ldw	`9*4`($inp),$t1
-+___
-+{
-+my @t=($t2,$t3,$a0,$a1,$a2,$a3,$t0,$t1);
-+for ($i=2;$i<(128/4-8);$i++) {
-+$code.=<<___;
-+	stw	$t[0],`-$XOFF+$i*4`(%sp)
-+	ldw	`(8+$i)*4`($inp),$t[0]
-+___
-+push(@t,shift(@t));
-+}
-+for (;$i<128/4;$i++) {
-+$code.=<<___;
-+	stw	$t[0],`-$XOFF+$i*4`(%sp)
-+___
-+push(@t,shift(@t));
-+}
-+$code.="L\$collected_pa1\n";
-+}
-+
-+for($i=0;$i<16;$i++)	{ &ROUND_00_15_pa1($i,@V); unshift(@V,pop(@V)); unshift(@V,pop(@V)); }
-+$code.="L\$rounds_pa1\n";
-+for(;$i<32;$i++)	{ &ROUND_16_xx_pa1($i,@V); unshift(@V,pop(@V)); unshift(@V,pop(@V)); }
-+
-+$code.=<<___;
-+	$POP	`-$FRAME_MARKER-2*$SIZE_T`(%sp),$ctx	; restore arguments
-+	$POP	`-$FRAME_MARKER-3*$SIZE_T`(%sp),$inp
-+	$POP	`-$FRAME_MARKER-4*$SIZE_T`(%sp),$num
-+	ldo	`-$rounds*$SZ`($Tbl),$Tbl		; rewind $Tbl
-+
-+	ldw	`0*4`($ctx),$t1		; update context
-+	ldw	`1*4`($ctx),$t0
-+	ldw	`2*4`($ctx),$t3
-+	ldw	`3*4`($ctx),$t2
-+	ldw	`4*4`($ctx),$a1
-+	ldw	`5*4`($ctx),$a0
-+	ldw	`6*4`($ctx),$a3
-+	add	$t0,$Alo,$Alo
-+	ldw	`7*4`($ctx),$a2
-+	addc	$t1,$Ahi,$Ahi
-+	ldw	`8*4`($ctx),$t1
-+	add	$t2,$Blo,$Blo
-+	ldw	`9*4`($ctx),$t0
-+	addc	$t3,$Bhi,$Bhi
-+	ldw	`10*4`($ctx),$t3
-+	add	$a0,$Clo,$Clo
-+	ldw	`11*4`($ctx),$t2
-+	addc	$a1,$Chi,$Chi
-+	ldw	`12*4`($ctx),$a1
-+	add	$a2,$Dlo,$Dlo
-+	ldw	`13*4`($ctx),$a0
-+	addc	$a3,$Dhi,$Dhi
-+	ldw	`14*4`($ctx),$a3
-+	add	$t0,$Elo,$Elo
-+	ldw	`15*4`($ctx),$a2
-+	addc	$t1,$Ehi,$Ehi
-+	stw	$Ahi,`0*4`($ctx)
-+	add	$t2,$Flo,$Flo
-+	stw	$Alo,`1*4`($ctx)
-+	addc	$t3,$Fhi,$Fhi
-+	stw	$Bhi,`2*4`($ctx)
-+	add	$a0,$Glo,$Glo
-+	stw	$Blo,`3*4`($ctx)
-+	addc	$a1,$Ghi,$Ghi
-+	stw	$Chi,`4*4`($ctx)
-+	add	$a2,$Hlo,$Hlo
-+	stw	$Clo,`5*4`($ctx)
-+	addc	$a3,$Hhi,$Hhi
-+	stw	$Dhi,`6*4`($ctx)
-+	ldo	`16*$SZ`($inp),$inp	; advance $inp
-+	stw	$Dlo,`7*4`($ctx)
-+	stw	$Ehi,`8*4`($ctx)
-+	stw	$Elo,`9*4`($ctx)
-+	stw	$Fhi,`10*4`($ctx)
-+	stw	$Flo,`11*4`($ctx)
-+	stw	$Ghi,`12*4`($ctx)
-+	stw	$Glo,`13*4`($ctx)
-+	stw	$Hhi,`14*4`($ctx)
-+	comb,=	$inp,$num,L\$done
-+	stw	$Hlo,`15*4`($ctx)
-+	b	L\$oop_pa1
-+	$PUSH	$inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp)	; save $inp
-+L\$done
-+___
-+}}
-+$code.=<<___;
-+	$POP	`-$FRAME-$SAVED_RP`(%sp),%r2		; standard epilogue
-+	$POP	`-$FRAME+1*$SIZE_T`(%sp),%r4
-+	$POP	`-$FRAME+2*$SIZE_T`(%sp),%r5
-+	$POP	`-$FRAME+3*$SIZE_T`(%sp),%r6
-+	$POP	`-$FRAME+4*$SIZE_T`(%sp),%r7
-+	$POP	`-$FRAME+5*$SIZE_T`(%sp),%r8
-+	$POP	`-$FRAME+6*$SIZE_T`(%sp),%r9
-+	$POP	`-$FRAME+7*$SIZE_T`(%sp),%r10
-+	$POP	`-$FRAME+8*$SIZE_T`(%sp),%r11
-+	$POP	`-$FRAME+9*$SIZE_T`(%sp),%r12
-+	$POP	`-$FRAME+10*$SIZE_T`(%sp),%r13
-+	$POP	`-$FRAME+11*$SIZE_T`(%sp),%r14
-+	$POP	`-$FRAME+12*$SIZE_T`(%sp),%r15
-+	$POP	`-$FRAME+13*$SIZE_T`(%sp),%r16
-+	$POP	`-$FRAME+14*$SIZE_T`(%sp),%r17
-+	$POP	`-$FRAME+15*$SIZE_T`(%sp),%r18
-+	bv	(%r2)
-+	.EXIT
-+	$POPMB	-$FRAME(%sp),%r3
-+	.PROCEND
-+	.STRINGZ "SHA`64*$SZ` block transform for PA-RISC, CRYPTOGAMS by "
-+___
-+
-+# Explicitly encode PA-RISC 2.0 instructions used in this module, so
-+# that it can be compiled with .LEVEL 1.0. It should be noted that I
-+# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0
-+# directive...
-+
-+my $ldd = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "ldd$mod\t$args";
-+
-+    if ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 3 suffices
-+    {	my $opcode=(0x14<<26)|($2<<21)|($3<<16)|(($1&0x1FF8)<<1)|(($1>>13)&1);
-+	$opcode|=(1<<3) if ($mod =~ /^,m/);
-+	$opcode|=(1<<2) if ($mod =~ /^,mb/);
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $std = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "std$mod\t$args";
-+
-+    if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/) # format 3 suffices
-+    {	my $opcode=(0x1c<<26)|($3<<21)|($1<<16)|(($2&0x1FF8)<<1)|(($2>>13)&1);
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $extrd = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "extrd$mod\t$args";
-+
-+    # I only have ",u" completer, it's implicitly encoded...
-+    if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/)	# format 15
-+    {	my $opcode=(0x36<<26)|($1<<21)|($4<<16);
-+	my $len=32-$3;
-+	$opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5);		# encode pos
-+	$opcode |= (($len&0x20)<<7)|($len&0x1f);		# encode len
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/)	# format 12
-+    {	my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9);
-+	my $len=32-$2;
-+	$opcode |= (($len&0x20)<<3)|($len&0x1f);		# encode len
-+	$opcode |= (1<<13) if ($mod =~ /,\**=/);
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+my $shrpd = sub {
-+  my ($mod,$args) = @_;
-+  my $orig = "shrpd$mod\t$args";
-+
-+    if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/)	# format 14
-+    {	my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4;
-+	my $cpos=63-$3;
-+	$opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5);		# encode sa
-+	sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig;
-+    }
-+    elsif ($args =~ /%r([0-9]+),%r([0-9]+),%sar,%r([0-9]+)/)	# format 11
-+    {	sprintf "\t.WORD\t0x%08x\t; %s",
-+		(0x34<<26)|($2<<21)|($1<<16)|(1<<9)|$3,$orig;
-+    }
-+    else { "\t".$orig; }
-+};
-+
-+sub assemble {
-+  my ($mnemonic,$mod,$args)=@_;
-+  my $opcode = eval("\$$mnemonic");
-+
-+    ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args";
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	s/shd\s+(%r[0-9]+),(%r[0-9]+),([0-9]+)/
-+		$3>31 ? sprintf("shd\t%$2,%$1,%d",$3-32)	# rotation for >=32
-+		:       sprintf("shd\t%$1,%$2,%d",$3)/e			or
-+	# translate made up instructons: _ror, _shr, _align, _shl
-+	s/_ror(\s+)(%r[0-9]+),/
-+		($SZ==4 ? "shd" : "shrpd")."$1$2,$2,"/e			or
-+
-+	s/_shr(\s+%r[0-9]+),([0-9]+),/
-+		$SZ==4 ? sprintf("extru%s,%d,%d,",$1,31-$2,32-$2)
-+		:        sprintf("extrd,u%s,%d,%d,",$1,63-$2,64-$2)/e	or
-+
-+	s/_align(\s+%r[0-9]+,%r[0-9]+),/
-+		($SZ==4 ? "vshd$1," : "shrpd$1,%sar,")/e		or
-+
-+	s/_shl(\s+%r[0-9]+),([0-9]+),/
-+		$SIZE_T==4 ? sprintf("zdep%s,%d,%d,",$1,31-$2,32-$2)
-+		:            sprintf("depd,z%s,%d,%d,",$1,63-$2,64-$2)/e;
-+
-+	s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e if ($SIZE_T==4);
-+
-+	s/cmpb,\*/comb,/ if ($SIZE_T==4);
-+
-+	s/\bbv\b/bve/    if ($SIZE_T==8);
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-ppc.pl
-new file mode 100755
-index 0000000..fe95b01
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-ppc.pl
-@@ -0,0 +1,799 @@
-+#! /usr/bin/env perl
-+# Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# I let hardware handle unaligned input, except on page boundaries
-+# (see below for details). Otherwise straightforward implementation
-+# with X vector in register bank.
-+
-+#			sha256		|	sha512
-+# 			-m64	-m32	|	-m64	-m32
-+# --------------------------------------+-----------------------
-+# PPC970,gcc-4.0.0	+50%	+38%	|	+40%	+410%(*)
-+# Power6,xlc-7		+150%	+90%	|	+100%	+430%(*)
-+#
-+# (*)	64-bit code in 32-bit application context, which actually is
-+#	on TODO list. It should be noted that for safe deployment in
-+#	32-bit *mutli-threaded* context asyncronous signals should be
-+#	blocked upon entry to SHA512 block routine. This is because
-+#	32-bit signaling procedure invalidates upper halves of GPRs.
-+#	Context switch procedure preserves them, but not signaling:-(
-+
-+# Second version is true multi-thread safe. Trouble with the original
-+# version was that it was using thread local storage pointer register.
-+# Well, it scrupulously preserved it, but the problem would arise the
-+# moment asynchronous signal was delivered and signal handler would
-+# dereference the TLS pointer. While it's never the case in openssl
-+# application or test suite, we have to respect this scenario and not
-+# use TLS pointer register. Alternative would be to require caller to
-+# block signals prior calling this routine. For the record, in 32-bit
-+# context R2 serves as TLS pointer, while in 64-bit context - R13.
-+
-+$flavour=shift;
-+$output =shift;
-+
-+if ($flavour =~ /64/) {
-+	$SIZE_T=8;
-+	$LRSAVE=2*$SIZE_T;
-+	$STU="stdu";
-+	$UCMP="cmpld";
-+	$SHL="sldi";
-+	$POP="ld";
-+	$PUSH="std";
-+} elsif ($flavour =~ /32/) {
-+	$SIZE_T=4;
-+	$LRSAVE=$SIZE_T;
-+	$STU="stwu";
-+	$UCMP="cmplw";
-+	$SHL="slwi";
-+	$POP="lwz";
-+	$PUSH="stw";
-+} else { die "nonsense $flavour"; }
-+
-+$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0;
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!";
-+
-+if ($output =~ /512/) {
-+	$func="sha512_block_ppc";
-+	$SZ=8;
-+	@Sigma0=(28,34,39);
-+	@Sigma1=(14,18,41);
-+	@sigma0=(1,  8, 7);
-+	@sigma1=(19,61, 6);
-+	$rounds=80;
-+	$LD="ld";
-+	$ST="std";
-+	$ROR="rotrdi";
-+	$SHR="srdi";
-+} else {
-+	$func="sha256_block_ppc";
-+	$SZ=4;
-+	@Sigma0=( 2,13,22);
-+	@Sigma1=( 6,11,25);
-+	@sigma0=( 7,18, 3);
-+	@sigma1=(17,19,10);
-+	$rounds=64;
-+	$LD="lwz";
-+	$ST="stw";
-+	$ROR="rotrwi";
-+	$SHR="srwi";
-+}
-+
-+$FRAME=32*$SIZE_T+16*$SZ;
-+$LOCALS=6*$SIZE_T;
-+
-+$sp ="r1";
-+$toc="r2";
-+$ctx="r3";	# zapped by $a0
-+$inp="r4";	# zapped by $a1
-+$num="r5";	# zapped by $t0
-+
-+$T  ="r0";
-+$a0 ="r3";
-+$a1 ="r4";
-+$t0 ="r5";
-+$t1 ="r6";
-+$Tbl="r7";
-+
-+$A  ="r8";
-+$B  ="r9";
-+$C  ="r10";
-+$D  ="r11";
-+$E  ="r12";
-+$F  =$t1;	$t1 = "r0";	# stay away from "r13";
-+$G  ="r14";
-+$H  ="r15";
-+
-+@V=($A,$B,$C,$D,$E,$F,$G,$H);
-+@X=("r16","r17","r18","r19","r20","r21","r22","r23",
-+    "r24","r25","r26","r27","r28","r29","r30","r31");
-+
-+$inp="r31" if($SZ==4 || $SIZE_T==8);	# reassigned $inp! aliases with @X[15]
-+
-+sub ROUND_00_15 {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+$code.=<<___;
-+	$ROR	$a0,$e,$Sigma1[0]
-+	$ROR	$a1,$e,$Sigma1[1]
-+	and	$t0,$f,$e
-+	xor	$a0,$a0,$a1
-+	add	$h,$h,$t1
-+	andc	$t1,$g,$e
-+	$ROR	$a1,$a1,`$Sigma1[2]-$Sigma1[1]`
-+	or	$t0,$t0,$t1		; Ch(e,f,g)
-+	add	$h,$h,@X[$i%16]
-+	xor	$a0,$a0,$a1		; Sigma1(e)
-+	add	$h,$h,$t0
-+	add	$h,$h,$a0
-+
-+	$ROR	$a0,$a,$Sigma0[0]
-+	$ROR	$a1,$a,$Sigma0[1]
-+	and	$t0,$a,$b
-+	and	$t1,$a,$c
-+	xor	$a0,$a0,$a1
-+	$ROR	$a1,$a1,`$Sigma0[2]-$Sigma0[1]`
-+	xor	$t0,$t0,$t1
-+	and	$t1,$b,$c
-+	xor	$a0,$a0,$a1		; Sigma0(a)
-+	add	$d,$d,$h
-+	xor	$t0,$t0,$t1		; Maj(a,b,c)
-+___
-+$code.=<<___ if ($i<15);
-+	$LD	$t1,`($i+1)*$SZ`($Tbl)
-+___
-+$code.=<<___;
-+	add	$h,$h,$a0
-+	add	$h,$h,$t0
-+
-+___
-+}
-+
-+sub ROUND_16_xx {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+$i-=16;
-+$code.=<<___;
-+	$ROR	$a0,@X[($i+1)%16],$sigma0[0]
-+	$ROR	$a1,@X[($i+1)%16],$sigma0[1]
-+	$ROR	$t0,@X[($i+14)%16],$sigma1[0]
-+	$ROR	$t1,@X[($i+14)%16],$sigma1[1]
-+	xor	$a0,$a0,$a1
-+	$SHR	$a1,@X[($i+1)%16],$sigma0[2]
-+	xor	$t0,$t0,$t1
-+	$SHR	$t1,@X[($i+14)%16],$sigma1[2]
-+	add	@X[$i],@X[$i],@X[($i+9)%16]
-+	xor	$a0,$a0,$a1		; sigma0(X[(i+1)&0x0f])
-+	xor	$t0,$t0,$t1		; sigma1(X[(i+14)&0x0f])
-+	$LD	$t1,`$i*$SZ`($Tbl)
-+	add	@X[$i],@X[$i],$a0
-+	add	@X[$i],@X[$i],$t0
-+___
-+&ROUND_00_15($i+16,$a,$b,$c,$d,$e,$f,$g,$h);
-+}
-+
-+$code=<<___;
-+.machine	"any"
-+.text
-+
-+.globl	$func
-+.align	6
-+$func:
-+	$STU	$sp,-$FRAME($sp)
-+	mflr	r0
-+	$SHL	$num,$num,`log(16*$SZ)/log(2)`
-+
-+	$PUSH	$ctx,`$FRAME-$SIZE_T*22`($sp)
-+
-+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
-+	$PUSH	r0,`$FRAME+$LRSAVE`($sp)
-+___
-+
-+if ($SZ==4 || $SIZE_T==8) {
-+$code.=<<___;
-+	$LD	$A,`0*$SZ`($ctx)
-+	mr	$inp,r4				; incarnate $inp
-+	$LD	$B,`1*$SZ`($ctx)
-+	$LD	$C,`2*$SZ`($ctx)
-+	$LD	$D,`3*$SZ`($ctx)
-+	$LD	$E,`4*$SZ`($ctx)
-+	$LD	$F,`5*$SZ`($ctx)
-+	$LD	$G,`6*$SZ`($ctx)
-+	$LD	$H,`7*$SZ`($ctx)
-+___
-+} else {
-+  for ($i=16;$i<32;$i++) {
-+    $code.=<<___;
-+	lwz	r$i,`$LITTLE_ENDIAN^(4*($i-16))`($ctx)
-+___
-+  }
-+}
-+
-+$code.=<<___;
-+	bl	LPICmeup
-+LPICedup:
-+	andi.	r0,$inp,3
-+	bne	Lunaligned
-+Laligned:
-+	add	$num,$inp,$num
-+	$PUSH	$num,`$FRAME-$SIZE_T*24`($sp)	; end pointer
-+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
-+	bl	Lsha2_block_private
-+	b	Ldone
-+
-+; PowerPC specification allows an implementation to be ill-behaved
-+; upon unaligned access which crosses page boundary. "Better safe
-+; than sorry" principle makes me treat it specially. But I don't
-+; look for particular offending word, but rather for the input
-+; block which crosses the boundary. Once found that block is aligned
-+; and hashed separately...
-+.align	4
-+Lunaligned:
-+	subfic	$t1,$inp,4096
-+	andi.	$t1,$t1,`4096-16*$SZ`	; distance to closest page boundary
-+	beq	Lcross_page
-+	$UCMP	$num,$t1
-+	ble	Laligned		; didn't cross the page boundary
-+	subfc	$num,$t1,$num
-+	add	$t1,$inp,$t1
-+	$PUSH	$num,`$FRAME-$SIZE_T*25`($sp)	; save real remaining num
-+	$PUSH	$t1,`$FRAME-$SIZE_T*24`($sp)	; intermediate end pointer
-+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
-+	bl	Lsha2_block_private
-+	; $inp equals to the intermediate end pointer here
-+	$POP	$num,`$FRAME-$SIZE_T*25`($sp)	; restore real remaining num
-+Lcross_page:
-+	li	$t1,`16*$SZ/4`
-+	mtctr	$t1
-+___
-+if ($SZ==4 || $SIZE_T==8) {
-+$code.=<<___;
-+	addi	r20,$sp,$LOCALS			; aligned spot below the frame
-+Lmemcpy:
-+	lbz	r16,0($inp)
-+	lbz	r17,1($inp)
-+	lbz	r18,2($inp)
-+	lbz	r19,3($inp)
-+	addi	$inp,$inp,4
-+	stb	r16,0(r20)
-+	stb	r17,1(r20)
-+	stb	r18,2(r20)
-+	stb	r19,3(r20)
-+	addi	r20,r20,4
-+	bdnz	Lmemcpy
-+___
-+} else {
-+$code.=<<___;
-+	addi	r12,$sp,$LOCALS			; aligned spot below the frame
-+Lmemcpy:
-+	lbz	r8,0($inp)
-+	lbz	r9,1($inp)
-+	lbz	r10,2($inp)
-+	lbz	r11,3($inp)
-+	addi	$inp,$inp,4
-+	stb	r8,0(r12)
-+	stb	r9,1(r12)
-+	stb	r10,2(r12)
-+	stb	r11,3(r12)
-+	addi	r12,r12,4
-+	bdnz	Lmemcpy
-+___
-+}
-+
-+$code.=<<___;
-+	$PUSH	$inp,`$FRAME-$SIZE_T*26`($sp)	; save real inp
-+	addi	$t1,$sp,`$LOCALS+16*$SZ`	; fictitious end pointer
-+	addi	$inp,$sp,$LOCALS		; fictitious inp pointer
-+	$PUSH	$num,`$FRAME-$SIZE_T*25`($sp)	; save real num
-+	$PUSH	$t1,`$FRAME-$SIZE_T*24`($sp)	; end pointer
-+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
-+	bl	Lsha2_block_private
-+	$POP	$inp,`$FRAME-$SIZE_T*26`($sp)	; restore real inp
-+	$POP	$num,`$FRAME-$SIZE_T*25`($sp)	; restore real num
-+	addic.	$num,$num,`-16*$SZ`		; num--
-+	bne	Lunaligned
-+
-+Ldone:
-+	$POP	r0,`$FRAME+$LRSAVE`($sp)
-+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
-+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
-+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
-+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
-+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
-+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
-+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
-+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
-+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
-+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
-+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
-+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
-+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
-+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
-+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
-+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
-+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
-+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
-+	mtlr	r0
-+	addi	$sp,$sp,$FRAME
-+	blr
-+	.long	0
-+	.byte	0,12,4,1,0x80,18,3,0
-+	.long	0
-+___
-+
-+if ($SZ==4 || $SIZE_T==8) {
-+$code.=<<___;
-+.align	4
-+Lsha2_block_private:
-+	$LD	$t1,0($Tbl)
-+___
-+for($i=0;$i<16;$i++) {
-+$code.=<<___ if ($SZ==4 && !$LITTLE_ENDIAN);
-+	lwz	@X[$i],`$i*$SZ`($inp)
-+___
-+$code.=<<___ if ($SZ==4 && $LITTLE_ENDIAN);
-+	lwz	$a0,`$i*$SZ`($inp)
-+	rotlwi	@X[$i],$a0,8
-+	rlwimi	@X[$i],$a0,24,0,7
-+	rlwimi	@X[$i],$a0,24,16,23
-+___
-+# 64-bit loads are split to 2x32-bit ones, as CPU can't handle
-+# unaligned 64-bit loads, only 32-bit ones...
-+$code.=<<___ if ($SZ==8 && !$LITTLE_ENDIAN);
-+	lwz	$t0,`$i*$SZ`($inp)
-+	lwz	@X[$i],`$i*$SZ+4`($inp)
-+	insrdi	@X[$i],$t0,32,0
-+___
-+$code.=<<___ if ($SZ==8 && $LITTLE_ENDIAN);
-+	lwz	$a0,`$i*$SZ`($inp)
-+	 lwz	$a1,`$i*$SZ+4`($inp)
-+	rotlwi	$t0,$a0,8
-+	 rotlwi	@X[$i],$a1,8
-+	rlwimi	$t0,$a0,24,0,7
-+	 rlwimi	@X[$i],$a1,24,0,7
-+	rlwimi	$t0,$a0,24,16,23
-+	 rlwimi	@X[$i],$a1,24,16,23
-+	insrdi	@X[$i],$t0,32,0
-+___
-+	&ROUND_00_15($i,@V);
-+	unshift(@V,pop(@V));
-+}
-+$code.=<<___;
-+	li	$t0,`$rounds/16-1`
-+	mtctr	$t0
-+.align	4
-+Lrounds:
-+	addi	$Tbl,$Tbl,`16*$SZ`
-+___
-+for(;$i<32;$i++) {
-+	&ROUND_16_xx($i,@V);
-+	unshift(@V,pop(@V));
-+}
-+$code.=<<___;
-+	bdnz	Lrounds
-+
-+	$POP	$ctx,`$FRAME-$SIZE_T*22`($sp)
-+	$POP	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
-+	$POP	$num,`$FRAME-$SIZE_T*24`($sp)	; end pointer
-+	subi	$Tbl,$Tbl,`($rounds-16)*$SZ`	; rewind Tbl
-+
-+	$LD	r16,`0*$SZ`($ctx)
-+	$LD	r17,`1*$SZ`($ctx)
-+	$LD	r18,`2*$SZ`($ctx)
-+	$LD	r19,`3*$SZ`($ctx)
-+	$LD	r20,`4*$SZ`($ctx)
-+	$LD	r21,`5*$SZ`($ctx)
-+	$LD	r22,`6*$SZ`($ctx)
-+	addi	$inp,$inp,`16*$SZ`		; advance inp
-+	$LD	r23,`7*$SZ`($ctx)
-+	add	$A,$A,r16
-+	add	$B,$B,r17
-+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)
-+	add	$C,$C,r18
-+	$ST	$A,`0*$SZ`($ctx)
-+	add	$D,$D,r19
-+	$ST	$B,`1*$SZ`($ctx)
-+	add	$E,$E,r20
-+	$ST	$C,`2*$SZ`($ctx)
-+	add	$F,$F,r21
-+	$ST	$D,`3*$SZ`($ctx)
-+	add	$G,$G,r22
-+	$ST	$E,`4*$SZ`($ctx)
-+	add	$H,$H,r23
-+	$ST	$F,`5*$SZ`($ctx)
-+	$ST	$G,`6*$SZ`($ctx)
-+	$UCMP	$inp,$num
-+	$ST	$H,`7*$SZ`($ctx)
-+	bne	Lsha2_block_private
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+.size	$func,.-$func
-+___
-+} else {
-+########################################################################
-+# SHA512 for PPC32, X vector is off-loaded to stack...
-+#
-+#			|	sha512
-+#			|	-m32
-+# ----------------------+-----------------------
-+# PPC74x0,gcc-4.0.1	|	+48%
-+# POWER6,gcc-4.4.6	|	+124%(*)
-+# POWER7,gcc-4.4.6	|	+79%(*)
-+# e300,gcc-4.1.0	|	+167%
-+#
-+# (*)	~1/3 of -m64 result [and ~20% better than -m32 code generated
-+#	by xlc-12.1]
-+
-+my $XOFF=$LOCALS;
-+
-+my @V=map("r$_",(16..31));	# A..H
-+
-+my ($s0,$s1,$t0,$t1,$t2,$t3,$a0,$a1,$a2,$a3)=map("r$_",(0,5,6,8..12,14,15));
-+my ($x0,$x1)=("r3","r4");	# zaps $ctx and $inp
-+
-+sub ROUND_00_15_ppc32 {
-+my ($i,	$ahi,$alo,$bhi,$blo,$chi,$clo,$dhi,$dlo,
-+	$ehi,$elo,$fhi,$flo,$ghi,$glo,$hhi,$hlo)=@_;
-+
-+$code.=<<___;
-+	lwz	$t2,`$SZ*($i%16)+($LITTLE_ENDIAN^4)`($Tbl)
-+	 xor	$a0,$flo,$glo
-+	lwz	$t3,`$SZ*($i%16)+($LITTLE_ENDIAN^0)`($Tbl)
-+	 xor	$a1,$fhi,$ghi
-+	addc	$hlo,$hlo,$t0			; h+=x[i]
-+	stw	$t0,`$XOFF+0+$SZ*($i%16)`($sp)	; save x[i]
-+
-+	srwi	$s0,$elo,$Sigma1[0]
-+	srwi	$s1,$ehi,$Sigma1[0]
-+	 and	$a0,$a0,$elo
-+	adde	$hhi,$hhi,$t1
-+	 and	$a1,$a1,$ehi
-+	stw	$t1,`$XOFF+4+$SZ*($i%16)`($sp)
-+	srwi	$t0,$elo,$Sigma1[1]
-+	srwi	$t1,$ehi,$Sigma1[1]
-+	 addc	$hlo,$hlo,$t2			; h+=K512[i]
-+	insrwi	$s0,$ehi,$Sigma1[0],0
-+	insrwi	$s1,$elo,$Sigma1[0],0
-+	 xor	$a0,$a0,$glo			; Ch(e,f,g)
-+	 adde	$hhi,$hhi,$t3
-+	 xor	$a1,$a1,$ghi
-+	insrwi	$t0,$ehi,$Sigma1[1],0
-+	insrwi	$t1,$elo,$Sigma1[1],0
-+	 addc	$hlo,$hlo,$a0			; h+=Ch(e,f,g)
-+	srwi	$t2,$ehi,$Sigma1[2]-32
-+	srwi	$t3,$elo,$Sigma1[2]-32
-+	xor	$s0,$s0,$t0
-+	xor	$s1,$s1,$t1
-+	insrwi	$t2,$elo,$Sigma1[2]-32,0
-+	insrwi	$t3,$ehi,$Sigma1[2]-32,0
-+	 xor	$a0,$alo,$blo			; a^b, b^c in next round
-+	 adde	$hhi,$hhi,$a1
-+	 xor	$a1,$ahi,$bhi
-+	xor	$s0,$s0,$t2			; Sigma1(e)
-+	xor	$s1,$s1,$t3
-+
-+	srwi	$t0,$alo,$Sigma0[0]
-+	 and	$a2,$a2,$a0
-+	 addc	$hlo,$hlo,$s0			; h+=Sigma1(e)
-+	 and	$a3,$a3,$a1
-+	srwi	$t1,$ahi,$Sigma0[0]
-+	srwi	$s0,$ahi,$Sigma0[1]-32
-+	 adde	$hhi,$hhi,$s1
-+	srwi	$s1,$alo,$Sigma0[1]-32
-+	insrwi	$t0,$ahi,$Sigma0[0],0
-+	insrwi	$t1,$alo,$Sigma0[0],0
-+	 xor	$a2,$a2,$blo			; Maj(a,b,c)
-+	 addc	$dlo,$dlo,$hlo			; d+=h
-+	 xor	$a3,$a3,$bhi
-+	insrwi	$s0,$alo,$Sigma0[1]-32,0
-+	insrwi	$s1,$ahi,$Sigma0[1]-32,0
-+	 adde	$dhi,$dhi,$hhi
-+	srwi	$t2,$ahi,$Sigma0[2]-32
-+	srwi	$t3,$alo,$Sigma0[2]-32
-+	xor	$s0,$s0,$t0
-+	 addc	$hlo,$hlo,$a2			; h+=Maj(a,b,c)
-+	xor	$s1,$s1,$t1
-+	insrwi	$t2,$alo,$Sigma0[2]-32,0
-+	insrwi	$t3,$ahi,$Sigma0[2]-32,0
-+	 adde	$hhi,$hhi,$a3
-+___
-+$code.=<<___ if ($i>=15);
-+	lwz	$t0,`$XOFF+0+$SZ*(($i+2)%16)`($sp)
-+	lwz	$t1,`$XOFF+4+$SZ*(($i+2)%16)`($sp)
-+___
-+$code.=<<___ if ($i<15 && !$LITTLE_ENDIAN);
-+	lwz	$t1,`$SZ*($i+1)+0`($inp)
-+	lwz	$t0,`$SZ*($i+1)+4`($inp)
-+___
-+$code.=<<___ if ($i<15 && $LITTLE_ENDIAN);
-+	lwz	$a2,`$SZ*($i+1)+0`($inp)
-+	 lwz	$a3,`$SZ*($i+1)+4`($inp)
-+	rotlwi	$t1,$a2,8
-+	 rotlwi	$t0,$a3,8
-+	rlwimi	$t1,$a2,24,0,7
-+	 rlwimi	$t0,$a3,24,0,7
-+	rlwimi	$t1,$a2,24,16,23
-+	 rlwimi	$t0,$a3,24,16,23
-+___
-+$code.=<<___;
-+	xor	$s0,$s0,$t2			; Sigma0(a)
-+	xor	$s1,$s1,$t3
-+	addc	$hlo,$hlo,$s0			; h+=Sigma0(a)
-+	adde	$hhi,$hhi,$s1
-+___
-+$code.=<<___ if ($i==15);
-+	lwz	$x0,`$XOFF+0+$SZ*(($i+1)%16)`($sp)
-+	lwz	$x1,`$XOFF+4+$SZ*(($i+1)%16)`($sp)
-+___
-+}
-+sub ROUND_16_xx_ppc32 {
-+my ($i,	$ahi,$alo,$bhi,$blo,$chi,$clo,$dhi,$dlo,
-+	$ehi,$elo,$fhi,$flo,$ghi,$glo,$hhi,$hlo)=@_;
-+
-+$code.=<<___;
-+	srwi	$s0,$t0,$sigma0[0]
-+	srwi	$s1,$t1,$sigma0[0]
-+	srwi	$t2,$t0,$sigma0[1]
-+	srwi	$t3,$t1,$sigma0[1]
-+	insrwi	$s0,$t1,$sigma0[0],0
-+	insrwi	$s1,$t0,$sigma0[0],0
-+	srwi	$a0,$t0,$sigma0[2]
-+	insrwi	$t2,$t1,$sigma0[1],0
-+	insrwi	$t3,$t0,$sigma0[1],0
-+	insrwi	$a0,$t1,$sigma0[2],0
-+	xor	$s0,$s0,$t2
-+	 lwz	$t2,`$XOFF+0+$SZ*(($i+14)%16)`($sp)
-+	srwi	$a1,$t1,$sigma0[2]
-+	xor	$s1,$s1,$t3
-+	 lwz	$t3,`$XOFF+4+$SZ*(($i+14)%16)`($sp)
-+	xor	$a0,$a0,$s0
-+	 srwi	$s0,$t2,$sigma1[0]
-+	xor	$a1,$a1,$s1
-+	 srwi	$s1,$t3,$sigma1[0]
-+	addc	$x0,$x0,$a0			; x[i]+=sigma0(x[i+1])
-+	 srwi	$a0,$t3,$sigma1[1]-32
-+	insrwi	$s0,$t3,$sigma1[0],0
-+	insrwi	$s1,$t2,$sigma1[0],0
-+	adde	$x1,$x1,$a1
-+	 srwi	$a1,$t2,$sigma1[1]-32
-+
-+	insrwi	$a0,$t2,$sigma1[1]-32,0
-+	srwi	$t2,$t2,$sigma1[2]
-+	insrwi	$a1,$t3,$sigma1[1]-32,0
-+	insrwi	$t2,$t3,$sigma1[2],0
-+	xor	$s0,$s0,$a0
-+	 lwz	$a0,`$XOFF+0+$SZ*(($i+9)%16)`($sp)
-+	srwi	$t3,$t3,$sigma1[2]
-+	xor	$s1,$s1,$a1
-+	 lwz	$a1,`$XOFF+4+$SZ*(($i+9)%16)`($sp)
-+	xor	$s0,$s0,$t2
-+	 addc	$x0,$x0,$a0			; x[i]+=x[i+9]
-+	xor	$s1,$s1,$t3
-+	 adde	$x1,$x1,$a1
-+	addc	$x0,$x0,$s0			; x[i]+=sigma1(x[i+14])
-+	adde	$x1,$x1,$s1
-+___
-+	($t0,$t1,$x0,$x1) = ($x0,$x1,$t0,$t1);
-+	&ROUND_00_15_ppc32(@_);
-+}
-+
-+$code.=<<___;
-+.align	4
-+Lsha2_block_private:
-+___
-+$code.=<<___ if (!$LITTLE_ENDIAN);
-+	lwz	$t1,0($inp)
-+	xor	$a2,@V[3],@V[5]		; B^C, magic seed
-+	lwz	$t0,4($inp)
-+	xor	$a3,@V[2],@V[4]
-+___
-+$code.=<<___ if ($LITTLE_ENDIAN);
-+	lwz	$a1,0($inp)
-+	xor	$a2,@V[3],@V[5]		; B^C, magic seed
-+	lwz	$a0,4($inp)
-+	xor	$a3,@V[2],@V[4]
-+	rotlwi	$t1,$a1,8
-+	 rotlwi	$t0,$a0,8
-+	rlwimi	$t1,$a1,24,0,7
-+	 rlwimi	$t0,$a0,24,0,7
-+	rlwimi	$t1,$a1,24,16,23
-+	 rlwimi	$t0,$a0,24,16,23
-+___
-+for($i=0;$i<16;$i++) {
-+	&ROUND_00_15_ppc32($i,@V);
-+	unshift(@V,pop(@V));	unshift(@V,pop(@V));
-+	($a0,$a1,$a2,$a3) = ($a2,$a3,$a0,$a1);
-+}
-+$code.=<<___;
-+	li	$a0,`$rounds/16-1`
-+	mtctr	$a0
-+.align	4
-+Lrounds:
-+	addi	$Tbl,$Tbl,`16*$SZ`
-+___
-+for(;$i<32;$i++) {
-+	&ROUND_16_xx_ppc32($i,@V);
-+	unshift(@V,pop(@V));	unshift(@V,pop(@V));
-+	($a0,$a1,$a2,$a3) = ($a2,$a3,$a0,$a1);
-+}
-+$code.=<<___;
-+	bdnz	Lrounds
-+
-+	$POP	$ctx,`$FRAME-$SIZE_T*22`($sp)
-+	$POP	$inp,`$FRAME-$SIZE_T*23`($sp)	; inp pointer
-+	$POP	$num,`$FRAME-$SIZE_T*24`($sp)	; end pointer
-+	subi	$Tbl,$Tbl,`($rounds-16)*$SZ`	; rewind Tbl
-+
-+	lwz	$t0,`$LITTLE_ENDIAN^0`($ctx)
-+	lwz	$t1,`$LITTLE_ENDIAN^4`($ctx)
-+	lwz	$t2,`$LITTLE_ENDIAN^8`($ctx)
-+	lwz	$t3,`$LITTLE_ENDIAN^12`($ctx)
-+	lwz	$a0,`$LITTLE_ENDIAN^16`($ctx)
-+	lwz	$a1,`$LITTLE_ENDIAN^20`($ctx)
-+	lwz	$a2,`$LITTLE_ENDIAN^24`($ctx)
-+	addc	@V[1],@V[1],$t1
-+	lwz	$a3,`$LITTLE_ENDIAN^28`($ctx)
-+	adde	@V[0],@V[0],$t0
-+	lwz	$t0,`$LITTLE_ENDIAN^32`($ctx)
-+	addc	@V[3],@V[3],$t3
-+	lwz	$t1,`$LITTLE_ENDIAN^36`($ctx)
-+	adde	@V[2],@V[2],$t2
-+	lwz	$t2,`$LITTLE_ENDIAN^40`($ctx)
-+	addc	@V[5],@V[5],$a1
-+	lwz	$t3,`$LITTLE_ENDIAN^44`($ctx)
-+	adde	@V[4],@V[4],$a0
-+	lwz	$a0,`$LITTLE_ENDIAN^48`($ctx)
-+	addc	@V[7],@V[7],$a3
-+	lwz	$a1,`$LITTLE_ENDIAN^52`($ctx)
-+	adde	@V[6],@V[6],$a2
-+	lwz	$a2,`$LITTLE_ENDIAN^56`($ctx)
-+	addc	@V[9],@V[9],$t1
-+	lwz	$a3,`$LITTLE_ENDIAN^60`($ctx)
-+	adde	@V[8],@V[8],$t0
-+	stw	@V[0],`$LITTLE_ENDIAN^0`($ctx)
-+	stw	@V[1],`$LITTLE_ENDIAN^4`($ctx)
-+	addc	@V[11],@V[11],$t3
-+	stw	@V[2],`$LITTLE_ENDIAN^8`($ctx)
-+	stw	@V[3],`$LITTLE_ENDIAN^12`($ctx)
-+	adde	@V[10],@V[10],$t2
-+	stw	@V[4],`$LITTLE_ENDIAN^16`($ctx)
-+	stw	@V[5],`$LITTLE_ENDIAN^20`($ctx)
-+	addc	@V[13],@V[13],$a1
-+	stw	@V[6],`$LITTLE_ENDIAN^24`($ctx)
-+	stw	@V[7],`$LITTLE_ENDIAN^28`($ctx)
-+	adde	@V[12],@V[12],$a0
-+	stw	@V[8],`$LITTLE_ENDIAN^32`($ctx)
-+	stw	@V[9],`$LITTLE_ENDIAN^36`($ctx)
-+	addc	@V[15],@V[15],$a3
-+	stw	@V[10],`$LITTLE_ENDIAN^40`($ctx)
-+	stw	@V[11],`$LITTLE_ENDIAN^44`($ctx)
-+	adde	@V[14],@V[14],$a2
-+	stw	@V[12],`$LITTLE_ENDIAN^48`($ctx)
-+	stw	@V[13],`$LITTLE_ENDIAN^52`($ctx)
-+	stw	@V[14],`$LITTLE_ENDIAN^56`($ctx)
-+	stw	@V[15],`$LITTLE_ENDIAN^60`($ctx)
-+
-+	addi	$inp,$inp,`16*$SZ`		; advance inp
-+	$PUSH	$inp,`$FRAME-$SIZE_T*23`($sp)
-+	$UCMP	$inp,$num
-+	bne	Lsha2_block_private
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+.size	$func,.-$func
-+___
-+}
-+
-+# Ugly hack here, because PPC assembler syntax seem to vary too
-+# much from platforms to platform...
-+$code.=<<___;
-+.align	6
-+LPICmeup:
-+	mflr	r0
-+	bcl	20,31,\$+4
-+	mflr	$Tbl	; vvvvvv "distance" between . and 1st data entry
-+	addi	$Tbl,$Tbl,`64-8`
-+	mtlr	r0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+	.space	`64-9*4`
-+___
-+$code.=<<___ if ($SZ==8);
-+	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
-+	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
-+	.quad	0x3956c25bf348b538,0x59f111f1b605d019
-+	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
-+	.quad	0xd807aa98a3030242,0x12835b0145706fbe
-+	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
-+	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
-+	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
-+	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
-+	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
-+	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
-+	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
-+	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
-+	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
-+	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
-+	.quad	0x06ca6351e003826f,0x142929670a0e6e70
-+	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
-+	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
-+	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
-+	.quad	0x81c2c92e47edaee6,0x92722c851482353b
-+	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
-+	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
-+	.quad	0xd192e819d6ef5218,0xd69906245565a910
-+	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
-+	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
-+	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
-+	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
-+	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
-+	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
-+	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
-+	.quad	0x90befffa23631e28,0xa4506cebde82bde9
-+	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
-+	.quad	0xca273eceea26619c,0xd186b8c721c0c207
-+	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
-+	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
-+	.quad	0x113f9804bef90dae,0x1b710b35131c471b
-+	.quad	0x28db77f523047d84,0x32caab7b40c72493
-+	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
-+	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
-+	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
-+___
-+$code.=<<___ if ($SZ==4);
-+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-s390x.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-s390x.pl
-new file mode 100644
-index 0000000..582d393
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-s390x.pl
-@@ -0,0 +1,326 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# SHA256/512 block procedures for s390x.
-+
-+# April 2007.
-+#
-+# sha256_block_data_order is reportedly >3 times faster than gcc 3.3
-+# generated code (must be a bug in compiler, as improvement is
-+# "pathologically" high, in particular in comparison to other SHA
-+# modules). But the real twist is that it detects if hardware support
-+# for SHA256 is available and in such case utilizes it. Then the
-+# performance can reach >6.5x of assembler one for larger chunks.
-+#
-+# sha512_block_data_order is ~70% faster than gcc 3.3 generated code.
-+
-+# January 2009.
-+#
-+# Add support for hardware SHA512 and reschedule instructions to
-+# favour dual-issue z10 pipeline. Hardware SHA256/512 is ~4.7x faster
-+# than software.
-+
-+# November 2010.
-+#
-+# Adapt for -m31 build. If kernel supports what's called "highgprs"
-+# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
-+# instructions and achieve "64-bit" performance even in 31-bit legacy
-+# application context. The feature is not specific to any particular
-+# processor, as long as it's "z-CPU". Latter implies that the code
-+# remains z/Architecture specific. On z990 SHA256 was measured to
-+# perform 2.4x and SHA512 - 13x better than code generated by gcc 4.3.
-+
-+$flavour = shift;
-+
-+if ($flavour =~ /3[12]/) {
-+	$SIZE_T=4;
-+	$g="";
-+} else {
-+	$SIZE_T=8;
-+	$g="g";
-+}
-+
-+$t0="%r0";
-+$t1="%r1";
-+$ctx="%r2";	$t2="%r2";
-+$inp="%r3";
-+$len="%r4";	# used as index in inner loop
-+
-+$A="%r5";
-+$B="%r6";
-+$C="%r7";
-+$D="%r8";
-+$E="%r9";
-+$F="%r10";
-+$G="%r11";
-+$H="%r12";	@V=($A,$B,$C,$D,$E,$F,$G,$H);
-+$tbl="%r13";
-+$T1="%r14";
-+$sp="%r15";
-+
-+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
-+open STDOUT,">$output";
-+
-+if ($output =~ /512/) {
-+	$label="512";
-+	$SZ=8;
-+	$LD="lg";	# load from memory
-+	$ST="stg";	# store to memory
-+	$ADD="alg";	# add with memory operand
-+	$ROT="rllg";	# rotate left
-+	$SHR="srlg";	# logical right shift [see even at the end]
-+	@Sigma0=(25,30,36);
-+	@Sigma1=(23,46,50);
-+	@sigma0=(56,63, 7);
-+	@sigma1=( 3,45, 6);
-+	$rounds=80;
-+	$kimdfunc=3;	# 0 means unknown/unsupported/unimplemented/disabled
-+} else {
-+	$label="256";
-+	$SZ=4;
-+	$LD="llgf";	# load from memory
-+	$ST="st";	# store to memory
-+	$ADD="al";	# add with memory operand
-+	$ROT="rll";	# rotate left
-+	$SHR="srl";	# logical right shift
-+	@Sigma0=(10,19,30);
-+	@Sigma1=( 7,21,26);
-+	@sigma0=(14,25, 3);
-+	@sigma1=(13,15,10);
-+	$rounds=64;
-+	$kimdfunc=2;	# magic function code for kimd instruction
-+}
-+$Func="sha${label}_block_data_order";
-+$Table="K${label}";
-+$stdframe=16*$SIZE_T+4*8;
-+$frame=$stdframe+16*$SZ;
-+
-+sub BODY_00_15 {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
-+
-+$code.=<<___ if ($i<16);
-+	$LD	$T1,`$i*$SZ`($inp)	### $i
-+___
-+$code.=<<___;
-+	$ROT	$t0,$e,$Sigma1[0]
-+	$ROT	$t1,$e,$Sigma1[1]
-+	 lgr	$t2,$f
-+	xgr	$t0,$t1
-+	$ROT	$t1,$t1,`$Sigma1[2]-$Sigma1[1]`
-+	 xgr	$t2,$g
-+	$ST	$T1,`$stdframe+$SZ*($i%16)`($sp)
-+	xgr	$t0,$t1			# Sigma1(e)
-+	algr	$T1,$h			# T1+=h
-+	 ngr	$t2,$e
-+	 lgr	$t1,$a
-+	algr	$T1,$t0			# T1+=Sigma1(e)
-+	$ROT	$h,$a,$Sigma0[0]
-+	 xgr	$t2,$g			# Ch(e,f,g)
-+	$ADD	$T1,`$i*$SZ`($len,$tbl)	# T1+=K[i]
-+	$ROT	$t0,$a,$Sigma0[1]
-+	algr	$T1,$t2			# T1+=Ch(e,f,g)
-+	 ogr	$t1,$b
-+	xgr	$h,$t0
-+	 lgr	$t2,$a
-+	 ngr	$t1,$c
-+	$ROT	$t0,$t0,`$Sigma0[2]-$Sigma0[1]`
-+	xgr	$h,$t0			# h=Sigma0(a)
-+	 ngr	$t2,$b
-+	algr	$h,$T1			# h+=T1
-+	 ogr	$t2,$t1			# Maj(a,b,c)
-+	algr	$d,$T1			# d+=T1
-+	algr	$h,$t2			# h+=Maj(a,b,c)
-+___
-+}
-+
-+sub BODY_16_XX {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
-+
-+$code.=<<___;
-+	$LD	$T1,`$stdframe+$SZ*(($i+1)%16)`($sp)	### $i
-+	$LD	$t1,`$stdframe+$SZ*(($i+14)%16)`($sp)
-+	$ROT	$t0,$T1,$sigma0[0]
-+	$SHR	$T1,$sigma0[2]
-+	$ROT	$t2,$t0,`$sigma0[1]-$sigma0[0]`
-+	xgr	$T1,$t0
-+	$ROT	$t0,$t1,$sigma1[0]
-+	xgr	$T1,$t2					# sigma0(X[i+1])
-+	$SHR	$t1,$sigma1[2]
-+	$ADD	$T1,`$stdframe+$SZ*($i%16)`($sp)	# +=X[i]
-+	xgr	$t1,$t0
-+	$ROT	$t0,$t0,`$sigma1[1]-$sigma1[0]`
-+	$ADD	$T1,`$stdframe+$SZ*(($i+9)%16)`($sp)	# +=X[i+9]
-+	xgr	$t1,$t0				# sigma1(X[i+14])
-+	algr	$T1,$t1				# +=sigma1(X[i+14])
-+___
-+	&BODY_00_15(@_);
-+}
-+
-+$code.=<<___;
-+.text
-+.align	64
-+.type	$Table,\@object
-+$Table:
-+___
-+$code.=<<___ if ($SZ==4);
-+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+___
-+$code.=<<___ if ($SZ==8);
-+	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
-+	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
-+	.quad	0x3956c25bf348b538,0x59f111f1b605d019
-+	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
-+	.quad	0xd807aa98a3030242,0x12835b0145706fbe
-+	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
-+	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
-+	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
-+	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
-+	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
-+	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
-+	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
-+	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
-+	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
-+	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
-+	.quad	0x06ca6351e003826f,0x142929670a0e6e70
-+	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
-+	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
-+	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
-+	.quad	0x81c2c92e47edaee6,0x92722c851482353b
-+	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
-+	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
-+	.quad	0xd192e819d6ef5218,0xd69906245565a910
-+	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
-+	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
-+	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
-+	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
-+	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
-+	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
-+	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
-+	.quad	0x90befffa23631e28,0xa4506cebde82bde9
-+	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
-+	.quad	0xca273eceea26619c,0xd186b8c721c0c207
-+	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
-+	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
-+	.quad	0x113f9804bef90dae,0x1b710b35131c471b
-+	.quad	0x28db77f523047d84,0x32caab7b40c72493
-+	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
-+	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
-+	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
-+___
-+$code.=<<___;
-+.size	$Table,.-$Table
-+.globl	$Func
-+.type	$Func,\@function
-+$Func:
-+	sllg	$len,$len,`log(16*$SZ)/log(2)`
-+___
-+$code.=<<___ if ($kimdfunc);
-+	larl	%r1,OPENSSL_s390xcap_P
-+	lg	%r0,0(%r1)
-+	tmhl	%r0,0x4000	# check for message-security assist
-+	jz	.Lsoftware
-+	lg	%r0,16(%r1)	# check kimd capabilities
-+	tmhh	%r0,`0x8000>>$kimdfunc`
-+	jz	.Lsoftware
-+	lghi	%r0,$kimdfunc
-+	lgr	%r1,$ctx
-+	lgr	%r2,$inp
-+	lgr	%r3,$len
-+	.long	0xb93e0002	# kimd %r0,%r2
-+	brc	1,.-4		# pay attention to "partial completion"
-+	br	%r14
-+.align	16
-+.Lsoftware:
-+___
-+$code.=<<___;
-+	lghi	%r1,-$frame
-+	la	$len,0($len,$inp)
-+	stm${g}	$ctx,%r15,`2*$SIZE_T`($sp)
-+	lgr	%r0,$sp
-+	la	$sp,0(%r1,$sp)
-+	st${g}	%r0,0($sp)
-+
-+	larl	$tbl,$Table
-+	$LD	$A,`0*$SZ`($ctx)
-+	$LD	$B,`1*$SZ`($ctx)
-+	$LD	$C,`2*$SZ`($ctx)
-+	$LD	$D,`3*$SZ`($ctx)
-+	$LD	$E,`4*$SZ`($ctx)
-+	$LD	$F,`5*$SZ`($ctx)
-+	$LD	$G,`6*$SZ`($ctx)
-+	$LD	$H,`7*$SZ`($ctx)
-+
-+.Lloop:
-+	lghi	$len,0
-+___
-+for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
-+$code.=".Lrounds_16_xx:\n";
-+for (;$i<32;$i++)	{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	aghi	$len,`16*$SZ`
-+	lghi	$t0,`($rounds-16)*$SZ`
-+	clgr	$len,$t0
-+	jne	.Lrounds_16_xx
-+
-+	l${g}	$ctx,`$frame+2*$SIZE_T`($sp)
-+	la	$inp,`16*$SZ`($inp)
-+	$ADD	$A,`0*$SZ`($ctx)
-+	$ADD	$B,`1*$SZ`($ctx)
-+	$ADD	$C,`2*$SZ`($ctx)
-+	$ADD	$D,`3*$SZ`($ctx)
-+	$ADD	$E,`4*$SZ`($ctx)
-+	$ADD	$F,`5*$SZ`($ctx)
-+	$ADD	$G,`6*$SZ`($ctx)
-+	$ADD	$H,`7*$SZ`($ctx)
-+	$ST	$A,`0*$SZ`($ctx)
-+	$ST	$B,`1*$SZ`($ctx)
-+	$ST	$C,`2*$SZ`($ctx)
-+	$ST	$D,`3*$SZ`($ctx)
-+	$ST	$E,`4*$SZ`($ctx)
-+	$ST	$F,`5*$SZ`($ctx)
-+	$ST	$G,`6*$SZ`($ctx)
-+	$ST	$H,`7*$SZ`($ctx)
-+	cl${g}	$inp,`$frame+4*$SIZE_T`($sp)
-+	jne	.Lloop
-+
-+	lm${g}	%r6,%r15,`$frame+6*$SIZE_T`($sp)	
-+	br	%r14
-+.size	$Func,.-$Func
-+.string	"SHA${label} block transform for s390x, CRYPTOGAMS by "
-+.comm	OPENSSL_s390xcap_P,80,8
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+# unlike 32-bit shift 64-bit one takes three arguments
-+$code =~ s/(srlg\s+)(%r[0-9]+),/$1$2,$2,/gm;
-+
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-sparcv9.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-sparcv9.pl
-new file mode 100644
-index 0000000..4a1ce5f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-sparcv9.pl
-@@ -0,0 +1,857 @@
-+#! /usr/bin/env perl
-+# Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+#
-+# Hardware SPARC T4 support by David S. Miller .
-+# ====================================================================
-+
-+# SHA256 performance improvement over compiler generated code varies
-+# from 40% for Sun C [32-bit build] to 70% for gcc [3.3, 64-bit
-+# build]. Just like in SHA1 module I aim to ensure scalability on
-+# UltraSPARC T1 by packing X[16] to 8 64-bit registers.
-+
-+# SHA512 on pre-T1 UltraSPARC.
-+#
-+# Performance is >75% better than 64-bit code generated by Sun C and
-+# over 2x than 32-bit code. X[16] resides on stack, but access to it
-+# is scheduled for L2 latency and staged through 32 least significant
-+# bits of %l0-%l7. The latter is done to achieve 32-/64-bit ABI
-+# duality. Nevetheless it's ~40% faster than SHA256, which is pretty
-+# good [optimal coefficient is 50%].
-+#
-+# SHA512 on UltraSPARC T1.
-+#
-+# It's not any faster than 64-bit code generated by Sun C 5.8. This is
-+# because 64-bit code generator has the advantage of using 64-bit
-+# loads(*) to access X[16], which I consciously traded for 32-/64-bit
-+# ABI duality [as per above]. But it surpasses 32-bit Sun C generated
-+# code by 60%, not to mention that it doesn't suffer from severe decay
-+# when running 4 times physical cores threads and that it leaves gcc
-+# [3.4] behind by over 4x factor! If compared to SHA256, single thread
-+# performance is only 10% better, but overall throughput for maximum
-+# amount of threads for given CPU exceeds corresponding one of SHA256
-+# by 30% [again, optimal coefficient is 50%].
-+#
-+# (*)	Unlike pre-T1 UltraSPARC loads on T1 are executed strictly
-+#	in-order, i.e. load instruction has to complete prior next
-+#	instruction in given thread is executed, even if the latter is
-+#	not dependent on load result! This means that on T1 two 32-bit
-+#	loads are always slower than one 64-bit load. Once again this
-+#	is unlike pre-T1 UltraSPARC, where, if scheduled appropriately,
-+#	2x32-bit loads can be as fast as 1x64-bit ones.
-+#
-+# SPARC T4 SHA256/512 hardware achieves 3.17/2.01 cycles per byte,
-+# which is 9.3x/11.1x faster than software. Multi-process benchmark
-+# saturates at 11.5x single-process result on 8-core processor, or
-+# ~11/16GBps per 2.85GHz socket.
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+if ($output =~ /512/) {
-+	$label="512";
-+	$SZ=8;
-+	$LD="ldx";		# load from memory
-+	$ST="stx";		# store to memory
-+	$SLL="sllx";		# shift left logical
-+	$SRL="srlx";		# shift right logical
-+	@Sigma0=(28,34,39);
-+	@Sigma1=(14,18,41);
-+	@sigma0=( 7, 1, 8);	# right shift first
-+	@sigma1=( 6,19,61);	# right shift first
-+	$lastK=0x817;
-+	$rounds=80;
-+	$align=4;
-+
-+	$locals=16*$SZ;		# X[16]
-+
-+	$A="%o0";
-+	$B="%o1";
-+	$C="%o2";
-+	$D="%o3";
-+	$E="%o4";
-+	$F="%o5";
-+	$G="%g1";
-+	$H="%o7";
-+	@V=($A,$B,$C,$D,$E,$F,$G,$H);
-+} else {
-+	$label="256";
-+	$SZ=4;
-+	$LD="ld";		# load from memory
-+	$ST="st";		# store to memory
-+	$SLL="sll";		# shift left logical
-+	$SRL="srl";		# shift right logical
-+	@Sigma0=( 2,13,22);
-+	@Sigma1=( 6,11,25);
-+	@sigma0=( 3, 7,18);	# right shift first
-+	@sigma1=(10,17,19);	# right shift first
-+	$lastK=0x8f2;
-+	$rounds=64;
-+	$align=8;
-+
-+	$locals=0;		# X[16] is register resident
-+	@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7");
-+	
-+	$A="%l0";
-+	$B="%l1";
-+	$C="%l2";
-+	$D="%l3";
-+	$E="%l4";
-+	$F="%l5";
-+	$G="%l6";
-+	$H="%l7";
-+	@V=($A,$B,$C,$D,$E,$F,$G,$H);
-+}
-+$T1="%g2";
-+$tmp0="%g3";
-+$tmp1="%g4";
-+$tmp2="%g5";
-+
-+$ctx="%i0";
-+$inp="%i1";
-+$len="%i2";
-+$Ktbl="%i3";
-+$tmp31="%i4";
-+$tmp32="%i5";
-+
-+########### SHA256
-+$Xload = sub {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+
-+    if ($i==0) {
-+$code.=<<___;
-+	ldx	[$inp+0],@X[0]
-+	ldx	[$inp+16],@X[2]
-+	ldx	[$inp+32],@X[4]
-+	ldx	[$inp+48],@X[6]
-+	ldx	[$inp+8],@X[1]
-+	ldx	[$inp+24],@X[3]
-+	subcc	%g0,$tmp31,$tmp32 ! should be 64-$tmp31, but -$tmp31 works too
-+	ldx	[$inp+40],@X[5]
-+	bz,pt	%icc,.Laligned
-+	ldx	[$inp+56],@X[7]
-+
-+	sllx	@X[0],$tmp31,@X[0]
-+	ldx	[$inp+64],$T1
-+___
-+for($j=0;$j<7;$j++)
-+{   $code.=<<___;
-+	srlx	@X[$j+1],$tmp32,$tmp1
-+	sllx	@X[$j+1],$tmp31,@X[$j+1]
-+	or	$tmp1,@X[$j],@X[$j]
-+___
-+}
-+$code.=<<___;
-+	srlx	$T1,$tmp32,$T1
-+	or	$T1,@X[7],@X[7]
-+.Laligned:
-+___
-+    }
-+
-+    if ($i&1) {
-+	$code.="\tadd	@X[$i/2],$h,$T1\n";
-+    } else {
-+	$code.="\tsrlx	@X[$i/2],32,$T1\n\tadd	$h,$T1,$T1\n";
-+    }
-+} if ($SZ==4);
-+
-+########### SHA512
-+$Xload = sub {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1),"%l".eval((($i+1)*2)%8));
-+
-+$code.=<<___ if ($i==0);
-+	ld	[$inp+0],%l0
-+	ld	[$inp+4],%l1
-+	ld	[$inp+8],%l2
-+	ld	[$inp+12],%l3
-+	ld	[$inp+16],%l4
-+	ld	[$inp+20],%l5
-+	ld	[$inp+24],%l6
-+	cmp	$tmp31,0
-+	ld	[$inp+28],%l7
-+___
-+$code.=<<___ if ($i<15);
-+	sllx	@pair[1],$tmp31,$tmp2	! Xload($i)
-+	add	$tmp31,32,$tmp0
-+	sllx	@pair[0],$tmp0,$tmp1
-+	`"ld	[$inp+".eval(32+0+$i*8)."],@pair[0]"	if ($i<12)`
-+	srlx	@pair[2],$tmp32,@pair[1]
-+	or	$tmp1,$tmp2,$tmp2
-+	or	@pair[1],$tmp2,$tmp2
-+	`"ld	[$inp+".eval(32+4+$i*8)."],@pair[1]"	if ($i<12)`
-+	add	$h,$tmp2,$T1
-+	$ST	$tmp2,[%sp+STACK_BIAS+STACK_FRAME+`$i*$SZ`]
-+___
-+$code.=<<___ if ($i==12);
-+	bnz,a,pn	%icc,.+8
-+	ld	[$inp+128],%l0
-+___
-+$code.=<<___ if ($i==15);
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+1)%16)*$SZ+0`],%l2
-+	sllx	@pair[1],$tmp31,$tmp2	! Xload($i)
-+	add	$tmp31,32,$tmp0
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+1)%16)*$SZ+4`],%l3
-+	sllx	@pair[0],$tmp0,$tmp1
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+9)%16)*$SZ+0`],%l4
-+	srlx	@pair[2],$tmp32,@pair[1]
-+	or	$tmp1,$tmp2,$tmp2
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+9)%16)*$SZ+4`],%l5
-+	or	@pair[1],$tmp2,$tmp2
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+14)%16)*$SZ+0`],%l6
-+	add	$h,$tmp2,$T1
-+	$ST	$tmp2,[%sp+STACK_BIAS+STACK_FRAME+`$i*$SZ`]
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+14)%16)*$SZ+4`],%l7
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+0)%16)*$SZ+0`],%l0
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+0)%16)*$SZ+4`],%l1
-+___
-+} if ($SZ==8);
-+
-+########### common
-+sub BODY_00_15 {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+
-+    if ($i<16) {
-+	&$Xload(@_);
-+    } else {
-+	$code.="\tadd	$h,$T1,$T1\n";
-+    }
-+
-+$code.=<<___;
-+	$SRL	$e,@Sigma1[0],$h	!! $i
-+	xor	$f,$g,$tmp2
-+	$SLL	$e,`$SZ*8-@Sigma1[2]`,$tmp1
-+	and	$e,$tmp2,$tmp2
-+	$SRL	$e,@Sigma1[1],$tmp0
-+	xor	$tmp1,$h,$h
-+	$SLL	$e,`$SZ*8-@Sigma1[1]`,$tmp1
-+	xor	$tmp0,$h,$h
-+	$SRL	$e,@Sigma1[2],$tmp0
-+	xor	$tmp1,$h,$h
-+	$SLL	$e,`$SZ*8-@Sigma1[0]`,$tmp1
-+	xor	$tmp0,$h,$h
-+	xor	$g,$tmp2,$tmp2		! Ch(e,f,g)
-+	xor	$tmp1,$h,$tmp0		! Sigma1(e)
-+
-+	$SRL	$a,@Sigma0[0],$h
-+	add	$tmp2,$T1,$T1
-+	$LD	[$Ktbl+`$i*$SZ`],$tmp2	! K[$i]
-+	$SLL	$a,`$SZ*8-@Sigma0[2]`,$tmp1
-+	add	$tmp0,$T1,$T1
-+	$SRL	$a,@Sigma0[1],$tmp0
-+	xor	$tmp1,$h,$h
-+	$SLL	$a,`$SZ*8-@Sigma0[1]`,$tmp1
-+	xor	$tmp0,$h,$h
-+	$SRL	$a,@Sigma0[2],$tmp0
-+	xor	$tmp1,$h,$h	
-+	$SLL	$a,`$SZ*8-@Sigma0[0]`,$tmp1
-+	xor	$tmp0,$h,$h
-+	xor	$tmp1,$h,$h		! Sigma0(a)
-+
-+	or	$a,$b,$tmp0
-+	and	$a,$b,$tmp1
-+	and	$c,$tmp0,$tmp0
-+	or	$tmp0,$tmp1,$tmp1	! Maj(a,b,c)
-+	add	$tmp2,$T1,$T1		! +=K[$i]
-+	add	$tmp1,$h,$h
-+
-+	add	$T1,$d,$d
-+	add	$T1,$h,$h
-+___
-+}
-+
-+########### SHA256
-+$BODY_16_XX = sub {
-+my $i=@_[0];
-+my $xi;
-+
-+    if ($i&1) {
-+	$xi=$tmp32;
-+	$code.="\tsrlx	@X[(($i+1)/2)%8],32,$xi\n";
-+    } else {
-+	$xi=@X[(($i+1)/2)%8];
-+    }
-+$code.=<<___;
-+	srl	$xi,@sigma0[0],$T1		!! Xupdate($i)
-+	sll	$xi,`32-@sigma0[2]`,$tmp1
-+	srl	$xi,@sigma0[1],$tmp0
-+	xor	$tmp1,$T1,$T1
-+	sll	$tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
-+	xor	$tmp0,$T1,$T1
-+	srl	$xi,@sigma0[2],$tmp0
-+	xor	$tmp1,$T1,$T1
-+___
-+    if ($i&1) {
-+	$xi=@X[(($i+14)/2)%8];
-+    } else {
-+	$xi=$tmp32;
-+	$code.="\tsrlx	@X[(($i+14)/2)%8],32,$xi\n";
-+    }
-+$code.=<<___;
-+	srl	$xi,@sigma1[0],$tmp2
-+	xor	$tmp0,$T1,$T1			! T1=sigma0(X[i+1])
-+	sll	$xi,`32-@sigma1[2]`,$tmp1
-+	srl	$xi,@sigma1[1],$tmp0
-+	xor	$tmp1,$tmp2,$tmp2
-+	sll	$tmp1,`@sigma1[2]-@sigma1[1]`,$tmp1
-+	xor	$tmp0,$tmp2,$tmp2
-+	srl	$xi,@sigma1[2],$tmp0
-+	xor	$tmp1,$tmp2,$tmp2
-+___
-+    if ($i&1) {
-+	$xi=@X[($i/2)%8];
-+$code.=<<___;
-+	srlx	@X[(($i+9)/2)%8],32,$tmp1	! X[i+9]
-+	xor	$tmp0,$tmp2,$tmp2		! sigma1(X[i+14])
-+	srl	@X[($i/2)%8],0,$tmp0
-+	add	$tmp2,$tmp1,$tmp1
-+	add	$xi,$T1,$T1			! +=X[i]
-+	xor	$tmp0,@X[($i/2)%8],@X[($i/2)%8]
-+	add	$tmp1,$T1,$T1
-+
-+	srl	$T1,0,$T1
-+	or	$T1,@X[($i/2)%8],@X[($i/2)%8]
-+___
-+    } else {
-+	$xi=@X[(($i+9)/2)%8];
-+$code.=<<___;
-+	srlx	@X[($i/2)%8],32,$tmp1		! X[i]
-+	xor	$tmp0,$tmp2,$tmp2		! sigma1(X[i+14])
-+	add	$xi,$T1,$T1			! +=X[i+9]
-+	add	$tmp2,$tmp1,$tmp1
-+	srl	@X[($i/2)%8],0,@X[($i/2)%8]
-+	add	$tmp1,$T1,$T1
-+
-+	sllx	$T1,32,$tmp0
-+	or	$tmp0,@X[($i/2)%8],@X[($i/2)%8]
-+___
-+    }
-+    &BODY_00_15(@_);
-+} if ($SZ==4);
-+
-+########### SHA512
-+$BODY_16_XX = sub {
-+my $i=@_[0];
-+my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1));
-+
-+$code.=<<___;
-+	sllx	%l2,32,$tmp0		!! Xupdate($i)
-+	or	%l3,$tmp0,$tmp0
-+
-+	srlx	$tmp0,@sigma0[0],$T1
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+1)%16)*$SZ+0`],%l2
-+	sllx	$tmp0,`64-@sigma0[2]`,$tmp1
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+1)%16)*$SZ+4`],%l3
-+	srlx	$tmp0,@sigma0[1],$tmp0
-+	xor	$tmp1,$T1,$T1
-+	sllx	$tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1
-+	xor	$tmp0,$T1,$T1
-+	srlx	$tmp0,`@sigma0[2]-@sigma0[1]`,$tmp0
-+	xor	$tmp1,$T1,$T1
-+	sllx	%l6,32,$tmp2
-+	xor	$tmp0,$T1,$T1		! sigma0(X[$i+1])
-+	or	%l7,$tmp2,$tmp2
-+
-+	srlx	$tmp2,@sigma1[0],$tmp1
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+14)%16)*$SZ+0`],%l6
-+	sllx	$tmp2,`64-@sigma1[2]`,$tmp0
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+14)%16)*$SZ+4`],%l7
-+	srlx	$tmp2,@sigma1[1],$tmp2
-+	xor	$tmp0,$tmp1,$tmp1
-+	sllx	$tmp0,`@sigma1[2]-@sigma1[1]`,$tmp0
-+	xor	$tmp2,$tmp1,$tmp1
-+	srlx	$tmp2,`@sigma1[2]-@sigma1[1]`,$tmp2
-+	xor	$tmp0,$tmp1,$tmp1
-+	sllx	%l4,32,$tmp0
-+	xor	$tmp2,$tmp1,$tmp1	! sigma1(X[$i+14])
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+9)%16)*$SZ+0`],%l4
-+	or	%l5,$tmp0,$tmp0
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+9)%16)*$SZ+4`],%l5
-+
-+	sllx	%l0,32,$tmp2
-+	add	$tmp1,$T1,$T1
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+0)%16)*$SZ+0`],%l0
-+	or	%l1,$tmp2,$tmp2
-+	add	$tmp0,$T1,$T1		! +=X[$i+9]
-+	ld	[%sp+STACK_BIAS+STACK_FRAME+`(($i+1+0)%16)*$SZ+4`],%l1
-+	add	$tmp2,$T1,$T1		! +=X[$i]
-+	$ST	$T1,[%sp+STACK_BIAS+STACK_FRAME+`($i%16)*$SZ`]
-+___
-+    &BODY_00_15(@_);
-+} if ($SZ==8);
-+
-+$code.=<<___;
-+#include "sparc_arch.h"
-+
-+#ifdef __arch64__
-+.register	%g2,#scratch
-+.register	%g3,#scratch
-+#endif
-+
-+.section	".text",#alloc,#execinstr
-+
-+.align	64
-+K${label}:
-+.type	K${label},#object
-+___
-+if ($SZ==4) {
-+$code.=<<___;
-+	.long	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
-+	.long	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
-+	.long	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
-+	.long	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
-+	.long	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
-+	.long	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
-+	.long	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
-+	.long	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
-+	.long	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
-+	.long	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
-+	.long	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
-+	.long	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
-+	.long	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
-+	.long	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
-+	.long	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
-+	.long	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-+___
-+} else {
-+$code.=<<___;
-+	.long	0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
-+	.long	0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
-+	.long	0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
-+	.long	0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
-+	.long	0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
-+	.long	0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
-+	.long	0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
-+	.long	0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
-+	.long	0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
-+	.long	0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
-+	.long	0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
-+	.long	0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
-+	.long	0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
-+	.long	0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
-+	.long	0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
-+	.long	0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
-+	.long	0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
-+	.long	0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
-+	.long	0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
-+	.long	0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
-+	.long	0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
-+	.long	0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
-+	.long	0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
-+	.long	0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
-+	.long	0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
-+	.long	0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
-+	.long	0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
-+	.long	0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
-+	.long	0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
-+	.long	0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
-+	.long	0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
-+	.long	0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
-+	.long	0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
-+	.long	0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
-+	.long	0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
-+	.long	0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
-+	.long	0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
-+	.long	0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
-+	.long	0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
-+	.long	0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
-+___
-+}
-+$code.=<<___;
-+.size	K${label},.-K${label}
-+
-+#ifdef __PIC__
-+SPARC_PIC_THUNK(%g1)
-+#endif
-+
-+.globl	sha${label}_block_data_order
-+.align	32
-+sha${label}_block_data_order:
-+	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+	ld	[%g1+4],%g1		! OPENSSL_sparcv9cap_P[1]
-+
-+	andcc	%g1, CFR_SHA${label}, %g0
-+	be	.Lsoftware
-+	nop
-+___
-+$code.=<<___ if ($SZ==8); 		# SHA512
-+	ldd	[%o0 + 0x00], %f0	! load context
-+	ldd	[%o0 + 0x08], %f2
-+	ldd	[%o0 + 0x10], %f4
-+	ldd	[%o0 + 0x18], %f6
-+	ldd	[%o0 + 0x20], %f8
-+	ldd	[%o0 + 0x28], %f10
-+	andcc	%o1, 0x7, %g0
-+	ldd	[%o0 + 0x30], %f12
-+	bne,pn	%icc, .Lhwunaligned
-+	 ldd	[%o0 + 0x38], %f14
-+
-+.Lhwaligned_loop:
-+	ldd	[%o1 + 0x00], %f16
-+	ldd	[%o1 + 0x08], %f18
-+	ldd	[%o1 + 0x10], %f20
-+	ldd	[%o1 + 0x18], %f22
-+	ldd	[%o1 + 0x20], %f24
-+	ldd	[%o1 + 0x28], %f26
-+	ldd	[%o1 + 0x30], %f28
-+	ldd	[%o1 + 0x38], %f30
-+	ldd	[%o1 + 0x40], %f32
-+	ldd	[%o1 + 0x48], %f34
-+	ldd	[%o1 + 0x50], %f36
-+	ldd	[%o1 + 0x58], %f38
-+	ldd	[%o1 + 0x60], %f40
-+	ldd	[%o1 + 0x68], %f42
-+	ldd	[%o1 + 0x70], %f44
-+	subcc	%o2, 1, %o2		! done yet?
-+	ldd	[%o1 + 0x78], %f46
-+	add	%o1, 0x80, %o1
-+	prefetch [%o1 + 63], 20
-+	prefetch [%o1 + 64+63], 20
-+
-+	.word	0x81b02860		! SHA512
-+
-+	bne,pt	SIZE_T_CC, .Lhwaligned_loop
-+	nop
-+
-+.Lhwfinish:
-+	std	%f0, [%o0 + 0x00]	! store context
-+	std	%f2, [%o0 + 0x08]
-+	std	%f4, [%o0 + 0x10]
-+	std	%f6, [%o0 + 0x18]
-+	std	%f8, [%o0 + 0x20]
-+	std	%f10, [%o0 + 0x28]
-+	std	%f12, [%o0 + 0x30]
-+	retl
-+	 std	%f14, [%o0 + 0x38]
-+
-+.align	16
-+.Lhwunaligned:
-+	alignaddr %o1, %g0, %o1
-+
-+	ldd	[%o1 + 0x00], %f18
-+.Lhwunaligned_loop:
-+	ldd	[%o1 + 0x08], %f20
-+	ldd	[%o1 + 0x10], %f22
-+	ldd	[%o1 + 0x18], %f24
-+	ldd	[%o1 + 0x20], %f26
-+	ldd	[%o1 + 0x28], %f28
-+	ldd	[%o1 + 0x30], %f30
-+	ldd	[%o1 + 0x38], %f32
-+	ldd	[%o1 + 0x40], %f34
-+	ldd	[%o1 + 0x48], %f36
-+	ldd	[%o1 + 0x50], %f38
-+	ldd	[%o1 + 0x58], %f40
-+	ldd	[%o1 + 0x60], %f42
-+	ldd	[%o1 + 0x68], %f44
-+	ldd	[%o1 + 0x70], %f46
-+	ldd	[%o1 + 0x78], %f48
-+	subcc	%o2, 1, %o2		! done yet?
-+	ldd	[%o1 + 0x80], %f50
-+	add	%o1, 0x80, %o1
-+	prefetch [%o1 + 63], 20
-+	prefetch [%o1 + 64+63], 20
-+
-+	faligndata %f18, %f20, %f16
-+	faligndata %f20, %f22, %f18
-+	faligndata %f22, %f24, %f20
-+	faligndata %f24, %f26, %f22
-+	faligndata %f26, %f28, %f24
-+	faligndata %f28, %f30, %f26
-+	faligndata %f30, %f32, %f28
-+	faligndata %f32, %f34, %f30
-+	faligndata %f34, %f36, %f32
-+	faligndata %f36, %f38, %f34
-+	faligndata %f38, %f40, %f36
-+	faligndata %f40, %f42, %f38
-+	faligndata %f42, %f44, %f40
-+	faligndata %f44, %f46, %f42
-+	faligndata %f46, %f48, %f44
-+	faligndata %f48, %f50, %f46
-+
-+	.word	0x81b02860		! SHA512
-+
-+	bne,pt	SIZE_T_CC, .Lhwunaligned_loop
-+	for	%f50, %f50, %f18	! %f18=%f50
-+
-+	ba	.Lhwfinish
-+	nop
-+___
-+$code.=<<___ if ($SZ==4); 		# SHA256
-+	ld	[%o0 + 0x00], %f0
-+	ld	[%o0 + 0x04], %f1
-+	ld	[%o0 + 0x08], %f2
-+	ld	[%o0 + 0x0c], %f3
-+	ld	[%o0 + 0x10], %f4
-+	ld	[%o0 + 0x14], %f5
-+	andcc	%o1, 0x7, %g0
-+	ld	[%o0 + 0x18], %f6
-+	bne,pn	%icc, .Lhwunaligned
-+	 ld	[%o0 + 0x1c], %f7
-+
-+.Lhwloop:
-+	ldd	[%o1 + 0x00], %f8
-+	ldd	[%o1 + 0x08], %f10
-+	ldd	[%o1 + 0x10], %f12
-+	ldd	[%o1 + 0x18], %f14
-+	ldd	[%o1 + 0x20], %f16
-+	ldd	[%o1 + 0x28], %f18
-+	ldd	[%o1 + 0x30], %f20
-+	subcc	%o2, 1, %o2		! done yet?
-+	ldd	[%o1 + 0x38], %f22
-+	add	%o1, 0x40, %o1
-+	prefetch [%o1 + 63], 20
-+
-+	.word	0x81b02840		! SHA256
-+
-+	bne,pt	SIZE_T_CC, .Lhwloop
-+	nop
-+
-+.Lhwfinish:
-+	st	%f0, [%o0 + 0x00]	! store context
-+	st	%f1, [%o0 + 0x04]
-+	st	%f2, [%o0 + 0x08]
-+	st	%f3, [%o0 + 0x0c]
-+	st	%f4, [%o0 + 0x10]
-+	st	%f5, [%o0 + 0x14]
-+	st	%f6, [%o0 + 0x18]
-+	retl
-+	 st	%f7, [%o0 + 0x1c]
-+
-+.align	8
-+.Lhwunaligned:
-+	alignaddr %o1, %g0, %o1
-+
-+	ldd	[%o1 + 0x00], %f10
-+.Lhwunaligned_loop:
-+	ldd	[%o1 + 0x08], %f12
-+	ldd	[%o1 + 0x10], %f14
-+	ldd	[%o1 + 0x18], %f16
-+	ldd	[%o1 + 0x20], %f18
-+	ldd	[%o1 + 0x28], %f20
-+	ldd	[%o1 + 0x30], %f22
-+	ldd	[%o1 + 0x38], %f24
-+	subcc	%o2, 1, %o2		! done yet?
-+	ldd	[%o1 + 0x40], %f26
-+	add	%o1, 0x40, %o1
-+	prefetch [%o1 + 63], 20
-+
-+	faligndata %f10, %f12, %f8
-+	faligndata %f12, %f14, %f10
-+	faligndata %f14, %f16, %f12
-+	faligndata %f16, %f18, %f14
-+	faligndata %f18, %f20, %f16
-+	faligndata %f20, %f22, %f18
-+	faligndata %f22, %f24, %f20
-+	faligndata %f24, %f26, %f22
-+
-+	.word	0x81b02840		! SHA256
-+
-+	bne,pt	SIZE_T_CC, .Lhwunaligned_loop
-+	for	%f26, %f26, %f10	! %f10=%f26
-+
-+	ba	.Lhwfinish
-+	nop
-+___
-+$code.=<<___;
-+.align	16
-+.Lsoftware:
-+	save	%sp,-STACK_FRAME-$locals,%sp
-+	and	$inp,`$align-1`,$tmp31
-+	sllx	$len,`log(16*$SZ)/log(2)`,$len
-+	andn	$inp,`$align-1`,$inp
-+	sll	$tmp31,3,$tmp31
-+	add	$inp,$len,$len
-+___
-+$code.=<<___ if ($SZ==8); # SHA512
-+	mov	32,$tmp32
-+	sub	$tmp32,$tmp31,$tmp32
-+___
-+$code.=<<___;
-+.Lpic:	call	.+8
-+	add	%o7,K${label}-.Lpic,$Ktbl
-+
-+	$LD	[$ctx+`0*$SZ`],$A
-+	$LD	[$ctx+`1*$SZ`],$B
-+	$LD	[$ctx+`2*$SZ`],$C
-+	$LD	[$ctx+`3*$SZ`],$D
-+	$LD	[$ctx+`4*$SZ`],$E
-+	$LD	[$ctx+`5*$SZ`],$F
-+	$LD	[$ctx+`6*$SZ`],$G
-+	$LD	[$ctx+`7*$SZ`],$H
-+
-+.Lloop:
-+___
-+for ($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
-+$code.=".L16_xx:\n";
-+for (;$i<32;$i++)	{ &$BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	and	$tmp2,0xfff,$tmp2
-+	cmp	$tmp2,$lastK
-+	bne	.L16_xx
-+	add	$Ktbl,`16*$SZ`,$Ktbl	! Ktbl+=16
-+
-+___
-+$code.=<<___ if ($SZ==4); # SHA256
-+	$LD	[$ctx+`0*$SZ`],@X[0]
-+	$LD	[$ctx+`1*$SZ`],@X[1]
-+	$LD	[$ctx+`2*$SZ`],@X[2]
-+	$LD	[$ctx+`3*$SZ`],@X[3]
-+	$LD	[$ctx+`4*$SZ`],@X[4]
-+	$LD	[$ctx+`5*$SZ`],@X[5]
-+	$LD	[$ctx+`6*$SZ`],@X[6]
-+	$LD	[$ctx+`7*$SZ`],@X[7]
-+
-+	add	$A,@X[0],$A
-+	$ST	$A,[$ctx+`0*$SZ`]
-+	add	$B,@X[1],$B
-+	$ST	$B,[$ctx+`1*$SZ`]
-+	add	$C,@X[2],$C
-+	$ST	$C,[$ctx+`2*$SZ`]
-+	add	$D,@X[3],$D
-+	$ST	$D,[$ctx+`3*$SZ`]
-+	add	$E,@X[4],$E
-+	$ST	$E,[$ctx+`4*$SZ`]
-+	add	$F,@X[5],$F
-+	$ST	$F,[$ctx+`5*$SZ`]
-+	add	$G,@X[6],$G
-+	$ST	$G,[$ctx+`6*$SZ`]
-+	add	$H,@X[7],$H
-+	$ST	$H,[$ctx+`7*$SZ`]
-+___
-+$code.=<<___ if ($SZ==8); # SHA512
-+	ld	[$ctx+`0*$SZ+0`],%l0
-+	ld	[$ctx+`0*$SZ+4`],%l1
-+	ld	[$ctx+`1*$SZ+0`],%l2
-+	ld	[$ctx+`1*$SZ+4`],%l3
-+	ld	[$ctx+`2*$SZ+0`],%l4
-+	ld	[$ctx+`2*$SZ+4`],%l5
-+	ld	[$ctx+`3*$SZ+0`],%l6
-+
-+	sllx	%l0,32,$tmp0
-+	ld	[$ctx+`3*$SZ+4`],%l7
-+	sllx	%l2,32,$tmp1
-+	or	%l1,$tmp0,$tmp0
-+	or	%l3,$tmp1,$tmp1
-+	add	$tmp0,$A,$A
-+	add	$tmp1,$B,$B
-+	$ST	$A,[$ctx+`0*$SZ`]
-+	sllx	%l4,32,$tmp2
-+	$ST	$B,[$ctx+`1*$SZ`]
-+	sllx	%l6,32,$T1
-+	or	%l5,$tmp2,$tmp2
-+	or	%l7,$T1,$T1
-+	add	$tmp2,$C,$C
-+	$ST	$C,[$ctx+`2*$SZ`]
-+	add	$T1,$D,$D
-+	$ST	$D,[$ctx+`3*$SZ`]
-+
-+	ld	[$ctx+`4*$SZ+0`],%l0
-+	ld	[$ctx+`4*$SZ+4`],%l1
-+	ld	[$ctx+`5*$SZ+0`],%l2
-+	ld	[$ctx+`5*$SZ+4`],%l3
-+	ld	[$ctx+`6*$SZ+0`],%l4
-+	ld	[$ctx+`6*$SZ+4`],%l5
-+	ld	[$ctx+`7*$SZ+0`],%l6
-+
-+	sllx	%l0,32,$tmp0
-+	ld	[$ctx+`7*$SZ+4`],%l7
-+	sllx	%l2,32,$tmp1
-+	or	%l1,$tmp0,$tmp0
-+	or	%l3,$tmp1,$tmp1
-+	add	$tmp0,$E,$E
-+	add	$tmp1,$F,$F
-+	$ST	$E,[$ctx+`4*$SZ`]
-+	sllx	%l4,32,$tmp2
-+	$ST	$F,[$ctx+`5*$SZ`]
-+	sllx	%l6,32,$T1
-+	or	%l5,$tmp2,$tmp2
-+	or	%l7,$T1,$T1
-+	add	$tmp2,$G,$G
-+	$ST	$G,[$ctx+`6*$SZ`]
-+	add	$T1,$H,$H
-+	$ST	$H,[$ctx+`7*$SZ`]
-+___
-+$code.=<<___;
-+	add	$inp,`16*$SZ`,$inp		! advance inp
-+	cmp	$inp,$len
-+	bne	SIZE_T_CC,.Lloop
-+	sub	$Ktbl,`($rounds-16)*$SZ`,$Ktbl	! rewind Ktbl
-+
-+	ret
-+	restore
-+.type	sha${label}_block_data_order,#function
-+.size	sha${label}_block_data_order,(.-sha${label}_block_data_order)
-+.asciz	"SHA${label} block transform for SPARCv9, CRYPTOGAMS by "
-+.align	4
-+___
-+
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my $ref,$opf;
-+my %visopf = (	"faligndata"	=> 0x048,
-+		"for"		=> 0x07c	);
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+	foreach ($rs1,$rs2,$rd) {
-+	    return $ref if (!/%f([0-9]{1,2})/);
-+	    $_=$1;
-+	    if ($1>=32) {
-+		return $ref if ($1&1);
-+		# re-encode for upper double register addressing
-+		$_=($1|$1>>5)&31;
-+	    }
-+	}
-+
-+	return	sprintf ".word\t0x%08x !%s",
-+			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+			$ref;
-+    } else {
-+	return $ref;
-+    }
-+}
-+sub unalignaddr {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my $ref="$mnemonic\t$rs1,$rs2,$rd";
-+
-+    foreach ($rs1,$rs2,$rd) {
-+	if (/%([goli])([0-7])/)	{ $_=$bias{$1}+$2; }
-+	else			{ return $ref; }
-+    }
-+    return  sprintf ".word\t0x%08x !%s",
-+		    0x81b00300|$rd<<25|$rs1<<14|$rs2,
-+		    $ref;
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/ge;
-+
-+	s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-+		&unvis($1,$2,$3,$4)
-+	 /ge;
-+	s/\b(alignaddr)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+		&unalignaddr($1,$2,$3,$4)
-+	 /ge;
-+
-+	print $_,"\n";
-+}
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-x86_64.pl
-new file mode 100755
-index 0000000..c9b7b28
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512-x86_64.pl
-@@ -0,0 +1,2407 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. Rights for redistribution and usage in source and binary
-+# forms are granted according to the OpenSSL license.
-+# ====================================================================
-+#
-+# sha256/512_block procedure for x86_64.
-+#
-+# 40% improvement over compiler-generated code on Opteron. On EM64T
-+# sha256 was observed to run >80% faster and sha512 - >40%. No magical
-+# tricks, just straight implementation... I really wonder why gcc
-+# [being armed with inline assembler] fails to generate as fast code.
-+# The only thing which is cool about this module is that it's very
-+# same instruction sequence used for both SHA-256 and SHA-512. In
-+# former case the instructions operate on 32-bit operands, while in
-+# latter - on 64-bit ones. All I had to do is to get one flavor right,
-+# the other one passed the test right away:-)
-+#
-+# sha256_block runs in ~1005 cycles on Opteron, which gives you
-+# asymptotic performance of 64*1000/1005=63.7MBps times CPU clock
-+# frequency in GHz. sha512_block runs in ~1275 cycles, which results
-+# in 128*1000/1275=100MBps per GHz. Is there room for improvement?
-+# Well, if you compare it to IA-64 implementation, which maintains
-+# X[16] in register bank[!], tends to 4 instructions per CPU clock
-+# cycle and runs in 1003 cycles, 1275 is very good result for 3-way
-+# issue Opteron pipeline and X[16] maintained in memory. So that *if*
-+# there is a way to improve it, *then* the only way would be to try to
-+# offload X[16] updates to SSE unit, but that would require "deeper"
-+# loop unroll, which in turn would naturally cause size blow-up, not
-+# to mention increased complexity! And once again, only *if* it's
-+# actually possible to noticeably improve overall ILP, instruction
-+# level parallelism, on a given CPU implementation in this case.
-+#
-+# Special note on Intel EM64T. While Opteron CPU exhibits perfect
-+# performance ratio of 1.5 between 64- and 32-bit flavors [see above],
-+# [currently available] EM64T CPUs apparently are far from it. On the
-+# contrary, 64-bit version, sha512_block, is ~30% *slower* than 32-bit
-+# sha256_block:-( This is presumably because 64-bit shifts/rotates
-+# apparently are not atomic instructions, but implemented in microcode.
-+#
-+# May 2012.
-+#
-+# Optimization including one of Pavel Semjanov's ideas, alternative
-+# Maj, resulted in >=5% improvement on most CPUs, +20% SHA256 and
-+# unfortunately -2% SHA512 on P4 [which nobody should care about
-+# that much].
-+#
-+# June 2012.
-+#
-+# Add SIMD code paths, see below for improvement coefficients. SSSE3
-+# code path was not attempted for SHA512, because improvement is not
-+# estimated to be high enough, noticeably less than 9%, to justify
-+# the effort, not on pre-AVX processors. [Obviously with exclusion
-+# for VIA Nano, but it has SHA512 instruction that is faster and
-+# should be used instead.] For reference, corresponding estimated
-+# upper limit for improvement for SSSE3 SHA256 is 28%. The fact that
-+# higher coefficients are observed on VIA Nano and Bulldozer has more
-+# to do with specifics of their architecture [which is topic for
-+# separate discussion].
-+#
-+# November 2012.
-+#
-+# Add AVX2 code path. Two consecutive input blocks are loaded to
-+# 256-bit %ymm registers, with data from first block to least
-+# significant 128-bit halves and data from second to most significant.
-+# The data is then processed with same SIMD instruction sequence as
-+# for AVX, but with %ymm as operands. Side effect is increased stack
-+# frame, 448 additional bytes in SHA256 and 1152 in SHA512, and 1.2KB
-+# code size increase.
-+#
-+# March 2014.
-+#
-+# Add support for Intel SHA Extensions.
-+
-+######################################################################
-+# Current performance in cycles per processed byte (less is better):
-+#
-+#		SHA256	SSSE3       AVX/XOP(*)	    SHA512  AVX/XOP(*)
-+#
-+# AMD K8	14.9	-	    -		    9.57    -
-+# P4		17.3	-	    -		    30.8    -
-+# Core 2	15.6	13.8(+13%)  -		    9.97    -
-+# Westmere	14.8	12.3(+19%)  -		    9.58    -
-+# Sandy Bridge	17.4	14.2(+23%)  11.6(+50%(**))  11.2    8.10(+38%(**))
-+# Ivy Bridge	12.6	10.5(+20%)  10.3(+22%)	    8.17    7.22(+13%)
-+# Haswell	12.2	9.28(+31%)  7.80(+56%)	    7.66    5.40(+42%)
-+# Skylake	11.4	9.03(+26%)  7.70(+48%)      7.25    5.20(+40%)
-+# Bulldozer	21.1	13.6(+54%)  13.6(+54%(***)) 13.5    8.58(+57%)
-+# VIA Nano	23.0	16.5(+39%)  -		    14.7    -
-+# Atom		23.0	18.9(+22%)  -		    14.7    -
-+# Silvermont	27.4	20.6(+33%)  -               17.5    -
-+# Goldmont	18.9	14.3(+32%)  4.16(+350%)     12.0    -
-+#
-+# (*)	whichever best applicable, including SHAEXT;
-+# (**)	switch from ror to shrd stands for fair share of improvement;
-+# (***)	execution time is fully determined by remaining integer-only
-+#	part, body_00_15; reducing the amount of SIMD instructions
-+#	below certain limit makes no difference/sense; to conserve
-+#	space SHA256 XOP code path is therefore omitted;
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
-+		=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.19) + ($1>=2.22);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
-+	   `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
-+	$avx = ($1>=2.09) + ($1>=2.10);
-+}
-+
-+if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
-+	   `ml64 2>&1` =~ /Version ([0-9]+)\./) {
-+	$avx = ($1>=10) + ($1>=11);
-+}
-+
-+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) {
-+	$avx = ($2>=3.0) + ($2>3.0);
-+}
-+
-+$shaext=1;	### set to zero if compiling for 1.0.1
-+$avx=1		if (!$shaext && $avx);
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+if ($output =~ /512/) {
-+	$func="sha512_block_data_order";
-+	$TABLE="K512";
-+	$SZ=8;
-+	@ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%rax","%rbx","%rcx","%rdx",
-+					"%r8", "%r9", "%r10","%r11");
-+	($T1,$a0,$a1,$a2,$a3)=("%r12","%r13","%r14","%r15","%rdi");
-+	@Sigma0=(28,34,39);
-+	@Sigma1=(14,18,41);
-+	@sigma0=(1,  8, 7);
-+	@sigma1=(19,61, 6);
-+	$rounds=80;
-+} else {
-+	$func="sha256_block_data_order";
-+	$TABLE="K256";
-+	$SZ=4;
-+	@ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%eax","%ebx","%ecx","%edx",
-+					"%r8d","%r9d","%r10d","%r11d");
-+	($T1,$a0,$a1,$a2,$a3)=("%r12d","%r13d","%r14d","%r15d","%edi");
-+	@Sigma0=( 2,13,22);
-+	@Sigma1=( 6,11,25);
-+	@sigma0=( 7,18, 3);
-+	@sigma1=(17,19,10);
-+	$rounds=64;
-+}
-+
-+$ctx="%rdi";	# 1st arg, zapped by $a3
-+$inp="%rsi";	# 2nd arg
-+$Tbl="%rbp";
-+
-+$_ctx="16*$SZ+0*8(%rsp)";
-+$_inp="16*$SZ+1*8(%rsp)";
-+$_end="16*$SZ+2*8(%rsp)";
-+$_rsp="16*$SZ+3*8(%rsp)";
-+$framesz="16*$SZ+4*8";
-+
-+
-+sub ROUND_00_15()
-+{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
-+  my $STRIDE=$SZ;
-+     $STRIDE += 16 if ($i%(16/$SZ)==(16/$SZ-1));
-+
-+$code.=<<___;
-+	ror	\$`$Sigma1[2]-$Sigma1[1]`,$a0
-+	mov	$f,$a2
-+
-+	xor	$e,$a0
-+	ror	\$`$Sigma0[2]-$Sigma0[1]`,$a1
-+	xor	$g,$a2			# f^g
-+
-+	mov	$T1,`$SZ*($i&0xf)`(%rsp)
-+	xor	$a,$a1
-+	and	$e,$a2			# (f^g)&e
-+
-+	ror	\$`$Sigma1[1]-$Sigma1[0]`,$a0
-+	add	$h,$T1			# T1+=h
-+	xor	$g,$a2			# Ch(e,f,g)=((f^g)&e)^g
-+
-+	ror	\$`$Sigma0[1]-$Sigma0[0]`,$a1
-+	xor	$e,$a0
-+	add	$a2,$T1			# T1+=Ch(e,f,g)
-+
-+	mov	$a,$a2
-+	add	($Tbl),$T1		# T1+=K[round]
-+	xor	$a,$a1
-+
-+	xor	$b,$a2			# a^b, b^c in next round
-+	ror	\$$Sigma1[0],$a0	# Sigma1(e)
-+	mov	$b,$h
-+
-+	and	$a2,$a3
-+	ror	\$$Sigma0[0],$a1	# Sigma0(a)
-+	add	$a0,$T1			# T1+=Sigma1(e)
-+
-+	xor	$a3,$h			# h=Maj(a,b,c)=Ch(a^b,c,b)
-+	add	$T1,$d			# d+=T1
-+	add	$T1,$h			# h+=T1
-+
-+	lea	$STRIDE($Tbl),$Tbl	# round++
-+___
-+$code.=<<___ if ($i<15);
-+	add	$a1,$h			# h+=Sigma0(a)
-+___
-+	($a2,$a3) = ($a3,$a2);
-+}
-+
-+sub ROUND_16_XX()
-+{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
-+
-+$code.=<<___;
-+	mov	`$SZ*(($i+1)&0xf)`(%rsp),$a0
-+	mov	`$SZ*(($i+14)&0xf)`(%rsp),$a2
-+
-+	mov	$a0,$T1
-+	ror	\$`$sigma0[1]-$sigma0[0]`,$a0
-+	add	$a1,$a			# modulo-scheduled h+=Sigma0(a)
-+	mov	$a2,$a1
-+	ror	\$`$sigma1[1]-$sigma1[0]`,$a2
-+
-+	xor	$T1,$a0
-+	shr	\$$sigma0[2],$T1
-+	ror	\$$sigma0[0],$a0
-+	xor	$a1,$a2
-+	shr	\$$sigma1[2],$a1
-+
-+	ror	\$$sigma1[0],$a2
-+	xor	$a0,$T1			# sigma0(X[(i+1)&0xf])
-+	xor	$a1,$a2			# sigma1(X[(i+14)&0xf])
-+	add	`$SZ*(($i+9)&0xf)`(%rsp),$T1
-+
-+	add	`$SZ*($i&0xf)`(%rsp),$T1
-+	mov	$e,$a0
-+	add	$a2,$T1
-+	mov	$a,$a1
-+___
-+	&ROUND_00_15(@_);
-+}
-+
-+$code=<<___;
-+.text
-+
-+.extern	OPENSSL_ia32cap_P
-+.globl	$func
-+.type	$func,\@function,3
-+.align	16
-+$func:
-+___
-+$code.=<<___ if ($SZ==4 || $avx);
-+	lea	OPENSSL_ia32cap_P(%rip),%r11
-+	mov	0(%r11),%r9d
-+	mov	4(%r11),%r10d
-+	mov	8(%r11),%r11d
-+___
-+$code.=<<___ if ($SZ==4 && $shaext);
-+	test	\$`1<<29`,%r11d		# check for SHA
-+	jnz	_shaext_shortcut
-+___
-+$code.=<<___ if ($avx && $SZ==8);
-+	test	\$`1<<11`,%r10d		# check for XOP
-+	jnz	.Lxop_shortcut
-+___
-+$code.=<<___ if ($avx>1);
-+	and	\$`1<<8|1<<5|1<<3`,%r11d	# check for BMI2+AVX2+BMI1
-+	cmp	\$`1<<8|1<<5|1<<3`,%r11d
-+	je	.Lavx2_shortcut
-+___
-+$code.=<<___ if ($avx);
-+	and	\$`1<<30`,%r9d		# mask "Intel CPU" bit
-+	and	\$`1<<28|1<<9`,%r10d	# mask AVX and SSSE3 bits
-+	or	%r9d,%r10d
-+	cmp	\$`1<<28|1<<9|1<<30`,%r10d
-+	je	.Lavx_shortcut
-+___
-+$code.=<<___ if ($SZ==4);
-+	test	\$`1<<9`,%r10d
-+	jnz	.Lssse3_shortcut
-+___
-+$code.=<<___;
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	mov	%rsp,%r11		# copy %rsp
-+	shl	\$4,%rdx		# num*16
-+	sub	\$$framesz,%rsp
-+	lea	($inp,%rdx,$SZ),%rdx	# inp+num*16*$SZ
-+	and	\$-64,%rsp		# align stack frame
-+	mov	$ctx,$_ctx		# save ctx, 1st arg
-+	mov	$inp,$_inp		# save inp, 2nd arh
-+	mov	%rdx,$_end		# save end pointer, "3rd" arg
-+	mov	%r11,$_rsp		# save copy of %rsp
-+.Lprologue:
-+
-+	mov	$SZ*0($ctx),$A
-+	mov	$SZ*1($ctx),$B
-+	mov	$SZ*2($ctx),$C
-+	mov	$SZ*3($ctx),$D
-+	mov	$SZ*4($ctx),$E
-+	mov	$SZ*5($ctx),$F
-+	mov	$SZ*6($ctx),$G
-+	mov	$SZ*7($ctx),$H
-+	jmp	.Lloop
-+
-+.align	16
-+.Lloop:
-+	mov	$B,$a3
-+	lea	$TABLE(%rip),$Tbl
-+	xor	$C,$a3			# magic
-+___
-+	for($i=0;$i<16;$i++) {
-+		$code.="	mov	$SZ*$i($inp),$T1\n";
-+		$code.="	mov	@ROT[4],$a0\n";
-+		$code.="	mov	@ROT[0],$a1\n";
-+		$code.="	bswap	$T1\n";
-+		&ROUND_00_15($i,@ROT);
-+		unshift(@ROT,pop(@ROT));
-+	}
-+$code.=<<___;
-+	jmp	.Lrounds_16_xx
-+.align	16
-+.Lrounds_16_xx:
-+___
-+	for(;$i<32;$i++) {
-+		&ROUND_16_XX($i,@ROT);
-+		unshift(@ROT,pop(@ROT));
-+	}
-+
-+$code.=<<___;
-+	cmpb	\$0,`$SZ-1`($Tbl)
-+	jnz	.Lrounds_16_xx
-+
-+	mov	$_ctx,$ctx
-+	add	$a1,$A			# modulo-scheduled h+=Sigma0(a)
-+	lea	16*$SZ($inp),$inp
-+
-+	add	$SZ*0($ctx),$A
-+	add	$SZ*1($ctx),$B
-+	add	$SZ*2($ctx),$C
-+	add	$SZ*3($ctx),$D
-+	add	$SZ*4($ctx),$E
-+	add	$SZ*5($ctx),$F
-+	add	$SZ*6($ctx),$G
-+	add	$SZ*7($ctx),$H
-+
-+	cmp	$_end,$inp
-+
-+	mov	$A,$SZ*0($ctx)
-+	mov	$B,$SZ*1($ctx)
-+	mov	$C,$SZ*2($ctx)
-+	mov	$D,$SZ*3($ctx)
-+	mov	$E,$SZ*4($ctx)
-+	mov	$F,$SZ*5($ctx)
-+	mov	$G,$SZ*6($ctx)
-+	mov	$H,$SZ*7($ctx)
-+	jb	.Lloop
-+
-+	mov	$_rsp,%rsi
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue:
-+	ret
-+.size	$func,.-$func
-+___
-+
-+if ($SZ==4) {
-+$code.=<<___;
-+.align	64
-+.type	$TABLE,\@object
-+$TABLE:
-+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
-+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
-+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
-+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
-+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
-+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
-+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
-+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
-+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
-+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
-+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
-+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
-+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
-+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
-+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
-+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
-+
-+	.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
-+	.long	0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f
-+	.long	0x03020100,0x0b0a0908,0xffffffff,0xffffffff
-+	.long	0x03020100,0x0b0a0908,0xffffffff,0xffffffff
-+	.long	0xffffffff,0xffffffff,0x03020100,0x0b0a0908
-+	.long	0xffffffff,0xffffffff,0x03020100,0x0b0a0908
-+	.asciz	"SHA256 block transform for x86_64, CRYPTOGAMS by "
-+___
-+} else {
-+$code.=<<___;
-+.align	64
-+.type	$TABLE,\@object
-+$TABLE:
-+	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
-+	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
-+	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
-+	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
-+	.quad	0x3956c25bf348b538,0x59f111f1b605d019
-+	.quad	0x3956c25bf348b538,0x59f111f1b605d019
-+	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
-+	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
-+	.quad	0xd807aa98a3030242,0x12835b0145706fbe
-+	.quad	0xd807aa98a3030242,0x12835b0145706fbe
-+	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
-+	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
-+	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
-+	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
-+	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
-+	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
-+	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
-+	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
-+	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
-+	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
-+	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
-+	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
-+	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
-+	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
-+	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
-+	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
-+	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
-+	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
-+	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
-+	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
-+	.quad	0x06ca6351e003826f,0x142929670a0e6e70
-+	.quad	0x06ca6351e003826f,0x142929670a0e6e70
-+	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
-+	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
-+	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
-+	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
-+	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
-+	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
-+	.quad	0x81c2c92e47edaee6,0x92722c851482353b
-+	.quad	0x81c2c92e47edaee6,0x92722c851482353b
-+	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
-+	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
-+	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
-+	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
-+	.quad	0xd192e819d6ef5218,0xd69906245565a910
-+	.quad	0xd192e819d6ef5218,0xd69906245565a910
-+	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
-+	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
-+	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
-+	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
-+	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
-+	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
-+	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
-+	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
-+	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
-+	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
-+	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
-+	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
-+	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
-+	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
-+	.quad	0x90befffa23631e28,0xa4506cebde82bde9
-+	.quad	0x90befffa23631e28,0xa4506cebde82bde9
-+	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
-+	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
-+	.quad	0xca273eceea26619c,0xd186b8c721c0c207
-+	.quad	0xca273eceea26619c,0xd186b8c721c0c207
-+	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
-+	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
-+	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
-+	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
-+	.quad	0x113f9804bef90dae,0x1b710b35131c471b
-+	.quad	0x113f9804bef90dae,0x1b710b35131c471b
-+	.quad	0x28db77f523047d84,0x32caab7b40c72493
-+	.quad	0x28db77f523047d84,0x32caab7b40c72493
-+	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
-+	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
-+	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
-+	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
-+	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
-+	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
-+
-+	.quad	0x0001020304050607,0x08090a0b0c0d0e0f
-+	.quad	0x0001020304050607,0x08090a0b0c0d0e0f
-+	.asciz	"SHA512 block transform for x86_64, CRYPTOGAMS by "
-+___
-+}
-+
-+######################################################################
-+# SIMD code paths
-+#
-+if ($SZ==4 && $shaext) {{{
-+######################################################################
-+# Intel SHA Extensions implementation of SHA256 update function.
-+#
-+my ($ctx,$inp,$num,$Tbl)=("%rdi","%rsi","%rdx","%rcx");
-+
-+my ($Wi,$ABEF,$CDGH,$TMP,$BSWAP,$ABEF_SAVE,$CDGH_SAVE)=map("%xmm$_",(0..2,7..10));
-+my @MSG=map("%xmm$_",(3..6));
-+
-+$code.=<<___;
-+.type	sha256_block_data_order_shaext,\@function,3
-+.align	64
-+sha256_block_data_order_shaext:
-+_shaext_shortcut:
-+___
-+$code.=<<___ if ($win64);
-+	lea	`-8-5*16`(%rsp),%rsp
-+	movaps	%xmm6,-8-5*16(%rax)
-+	movaps	%xmm7,-8-4*16(%rax)
-+	movaps	%xmm8,-8-3*16(%rax)
-+	movaps	%xmm9,-8-2*16(%rax)
-+	movaps	%xmm10,-8-1*16(%rax)
-+.Lprologue_shaext:
-+___
-+$code.=<<___;
-+	lea		K256+0x80(%rip),$Tbl
-+	movdqu		($ctx),$ABEF		# DCBA
-+	movdqu		16($ctx),$CDGH		# HGFE
-+	movdqa		0x200-0x80($Tbl),$TMP	# byte swap mask
-+
-+	pshufd		\$0x1b,$ABEF,$Wi	# ABCD
-+	pshufd		\$0xb1,$ABEF,$ABEF	# CDAB
-+	pshufd		\$0x1b,$CDGH,$CDGH	# EFGH
-+	movdqa		$TMP,$BSWAP		# offload
-+	palignr		\$8,$CDGH,$ABEF		# ABEF
-+	punpcklqdq	$Wi,$CDGH		# CDGH
-+	jmp		.Loop_shaext
-+
-+.align	16
-+.Loop_shaext:
-+	movdqu		($inp),@MSG[0]
-+	movdqu		0x10($inp),@MSG[1]
-+	movdqu		0x20($inp),@MSG[2]
-+	pshufb		$TMP,@MSG[0]
-+	movdqu		0x30($inp),@MSG[3]
-+
-+	movdqa		0*32-0x80($Tbl),$Wi
-+	paddd		@MSG[0],$Wi
-+	pshufb		$TMP,@MSG[1]
-+	movdqa		$CDGH,$CDGH_SAVE	# offload
-+	sha256rnds2	$ABEF,$CDGH		# 0-3
-+	pshufd		\$0x0e,$Wi,$Wi
-+	nop
-+	movdqa		$ABEF,$ABEF_SAVE	# offload
-+	sha256rnds2	$CDGH,$ABEF
-+
-+	movdqa		1*32-0x80($Tbl),$Wi
-+	paddd		@MSG[1],$Wi
-+	pshufb		$TMP,@MSG[2]
-+	sha256rnds2	$ABEF,$CDGH		# 4-7
-+	pshufd		\$0x0e,$Wi,$Wi
-+	lea		0x40($inp),$inp
-+	sha256msg1	@MSG[1],@MSG[0]
-+	sha256rnds2	$CDGH,$ABEF
-+
-+	movdqa		2*32-0x80($Tbl),$Wi
-+	paddd		@MSG[2],$Wi
-+	pshufb		$TMP,@MSG[3]
-+	sha256rnds2	$ABEF,$CDGH		# 8-11
-+	pshufd		\$0x0e,$Wi,$Wi
-+	movdqa		@MSG[3],$TMP
-+	palignr		\$4,@MSG[2],$TMP
-+	nop
-+	paddd		$TMP,@MSG[0]
-+	sha256msg1	@MSG[2],@MSG[1]
-+	sha256rnds2	$CDGH,$ABEF
-+
-+	movdqa		3*32-0x80($Tbl),$Wi
-+	paddd		@MSG[3],$Wi
-+	sha256msg2	@MSG[3],@MSG[0]
-+	sha256rnds2	$ABEF,$CDGH		# 12-15
-+	pshufd		\$0x0e,$Wi,$Wi
-+	movdqa		@MSG[0],$TMP
-+	palignr		\$4,@MSG[3],$TMP
-+	nop
-+	paddd		$TMP,@MSG[1]
-+	sha256msg1	@MSG[3],@MSG[2]
-+	sha256rnds2	$CDGH,$ABEF
-+___
-+for($i=4;$i<16-3;$i++) {
-+$code.=<<___;
-+	movdqa		$i*32-0x80($Tbl),$Wi
-+	paddd		@MSG[0],$Wi
-+	sha256msg2	@MSG[0],@MSG[1]
-+	sha256rnds2	$ABEF,$CDGH		# 16-19...
-+	pshufd		\$0x0e,$Wi,$Wi
-+	movdqa		@MSG[1],$TMP
-+	palignr		\$4,@MSG[0],$TMP
-+	nop
-+	paddd		$TMP,@MSG[2]
-+	sha256msg1	@MSG[0],@MSG[3]
-+	sha256rnds2	$CDGH,$ABEF
-+___
-+	push(@MSG,shift(@MSG));
-+}
-+$code.=<<___;
-+	movdqa		13*32-0x80($Tbl),$Wi
-+	paddd		@MSG[0],$Wi
-+	sha256msg2	@MSG[0],@MSG[1]
-+	sha256rnds2	$ABEF,$CDGH		# 52-55
-+	pshufd		\$0x0e,$Wi,$Wi
-+	movdqa		@MSG[1],$TMP
-+	palignr		\$4,@MSG[0],$TMP
-+	sha256rnds2	$CDGH,$ABEF
-+	paddd		$TMP,@MSG[2]
-+
-+	movdqa		14*32-0x80($Tbl),$Wi
-+	paddd		@MSG[1],$Wi
-+	sha256rnds2	$ABEF,$CDGH		# 56-59
-+	pshufd		\$0x0e,$Wi,$Wi
-+	sha256msg2	@MSG[1],@MSG[2]
-+	movdqa		$BSWAP,$TMP
-+	sha256rnds2	$CDGH,$ABEF
-+
-+	movdqa		15*32-0x80($Tbl),$Wi
-+	paddd		@MSG[2],$Wi
-+	nop
-+	sha256rnds2	$ABEF,$CDGH		# 60-63
-+	pshufd		\$0x0e,$Wi,$Wi
-+	dec		$num
-+	nop
-+	sha256rnds2	$CDGH,$ABEF
-+
-+	paddd		$CDGH_SAVE,$CDGH
-+	paddd		$ABEF_SAVE,$ABEF
-+	jnz		.Loop_shaext
-+
-+	pshufd		\$0xb1,$CDGH,$CDGH	# DCHG
-+	pshufd		\$0x1b,$ABEF,$TMP	# FEBA
-+	pshufd		\$0xb1,$ABEF,$ABEF	# BAFE
-+	punpckhqdq	$CDGH,$ABEF		# DCBA
-+	palignr		\$8,$TMP,$CDGH		# HGFE
-+
-+	movdqu	$ABEF,($ctx)
-+	movdqu	$CDGH,16($ctx)
-+___
-+$code.=<<___ if ($win64);
-+	movaps	-8-5*16(%rax),%xmm6
-+	movaps	-8-4*16(%rax),%xmm7
-+	movaps	-8-3*16(%rax),%xmm8
-+	movaps	-8-2*16(%rax),%xmm9
-+	movaps	-8-1*16(%rax),%xmm10
-+	mov	%rax,%rsp
-+.Lepilogue_shaext:
-+___
-+$code.=<<___;
-+	ret
-+.size	sha256_block_data_order_shaext,.-sha256_block_data_order_shaext
-+___
-+}}}
-+{{{
-+
-+my $a4=$T1;
-+my ($a,$b,$c,$d,$e,$f,$g,$h);
-+
-+sub AUTOLOAD()		# thunk [simplified] 32-bit style perlasm
-+{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://;
-+  my $arg = pop;
-+    $arg = "\$$arg" if ($arg*1 eq $arg);
-+    $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n";
-+}
-+
-+sub body_00_15 () {
-+	(
-+	'($a,$b,$c,$d,$e,$f,$g,$h)=@ROT;'.
-+
-+	'&ror	($a0,$Sigma1[2]-$Sigma1[1])',
-+	'&mov	($a,$a1)',
-+	'&mov	($a4,$f)',
-+
-+	'&ror	($a1,$Sigma0[2]-$Sigma0[1])',
-+	'&xor	($a0,$e)',
-+	'&xor	($a4,$g)',			# f^g
-+
-+	'&ror	($a0,$Sigma1[1]-$Sigma1[0])',
-+	'&xor	($a1,$a)',
-+	'&and	($a4,$e)',			# (f^g)&e
-+
-+	'&xor	($a0,$e)',
-+	'&add	($h,$SZ*($i&15)."(%rsp)")',	# h+=X[i]+K[i]
-+	'&mov	($a2,$a)',
-+
-+	'&xor	($a4,$g)',			# Ch(e,f,g)=((f^g)&e)^g
-+	'&ror	($a1,$Sigma0[1]-$Sigma0[0])',
-+	'&xor	($a2,$b)',			# a^b, b^c in next round
-+
-+	'&add	($h,$a4)',			# h+=Ch(e,f,g)
-+	'&ror	($a0,$Sigma1[0])',		# Sigma1(e)
-+	'&and	($a3,$a2)',			# (b^c)&(a^b)
-+
-+	'&xor	($a1,$a)',
-+	'&add	($h,$a0)',			# h+=Sigma1(e)
-+	'&xor	($a3,$b)',			# Maj(a,b,c)=Ch(a^b,c,b)
-+
-+	'&ror	($a1,$Sigma0[0])',		# Sigma0(a)
-+	'&add	($d,$h)',			# d+=h
-+	'&add	($h,$a3)',			# h+=Maj(a,b,c)
-+
-+	'&mov	($a0,$d)',
-+	'&add	($a1,$h);'.			# h+=Sigma0(a)
-+	'($a2,$a3) = ($a3,$a2); unshift(@ROT,pop(@ROT)); $i++;'
-+	);
-+}
-+
-+######################################################################
-+# SSSE3 code path
-+#
-+if ($SZ==4) {	# SHA256 only
-+my @X = map("%xmm$_",(0..3));
-+my ($t0,$t1,$t2,$t3, $t4,$t5) = map("%xmm$_",(4..9));
-+
-+$code.=<<___;
-+.type	${func}_ssse3,\@function,3
-+.align	64
-+${func}_ssse3:
-+.Lssse3_shortcut:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	mov	%rsp,%r11		# copy %rsp
-+	shl	\$4,%rdx		# num*16
-+	sub	\$`$framesz+$win64*16*4`,%rsp
-+	lea	($inp,%rdx,$SZ),%rdx	# inp+num*16*$SZ
-+	and	\$-64,%rsp		# align stack frame
-+	mov	$ctx,$_ctx		# save ctx, 1st arg
-+	mov	$inp,$_inp		# save inp, 2nd arh
-+	mov	%rdx,$_end		# save end pointer, "3rd" arg
-+	mov	%r11,$_rsp		# save copy of %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,16*$SZ+32(%rsp)
-+	movaps	%xmm7,16*$SZ+48(%rsp)
-+	movaps	%xmm8,16*$SZ+64(%rsp)
-+	movaps	%xmm9,16*$SZ+80(%rsp)
-+___
-+$code.=<<___;
-+.Lprologue_ssse3:
-+
-+	mov	$SZ*0($ctx),$A
-+	mov	$SZ*1($ctx),$B
-+	mov	$SZ*2($ctx),$C
-+	mov	$SZ*3($ctx),$D
-+	mov	$SZ*4($ctx),$E
-+	mov	$SZ*5($ctx),$F
-+	mov	$SZ*6($ctx),$G
-+	mov	$SZ*7($ctx),$H
-+___
-+
-+$code.=<<___;
-+	#movdqa	$TABLE+`$SZ*2*$rounds`+32(%rip),$t4
-+	#movdqa	$TABLE+`$SZ*2*$rounds`+64(%rip),$t5
-+	jmp	.Lloop_ssse3
-+.align	16
-+.Lloop_ssse3:
-+	movdqa	$TABLE+`$SZ*2*$rounds`(%rip),$t3
-+	movdqu	0x00($inp),@X[0]
-+	movdqu	0x10($inp),@X[1]
-+	movdqu	0x20($inp),@X[2]
-+	pshufb	$t3,@X[0]
-+	movdqu	0x30($inp),@X[3]
-+	lea	$TABLE(%rip),$Tbl
-+	pshufb	$t3,@X[1]
-+	movdqa	0x00($Tbl),$t0
-+	movdqa	0x20($Tbl),$t1
-+	pshufb	$t3,@X[2]
-+	paddd	@X[0],$t0
-+	movdqa	0x40($Tbl),$t2
-+	pshufb	$t3,@X[3]
-+	movdqa	0x60($Tbl),$t3
-+	paddd	@X[1],$t1
-+	paddd	@X[2],$t2
-+	paddd	@X[3],$t3
-+	movdqa	$t0,0x00(%rsp)
-+	mov	$A,$a1
-+	movdqa	$t1,0x10(%rsp)
-+	mov	$B,$a3
-+	movdqa	$t2,0x20(%rsp)
-+	xor	$C,$a3			# magic
-+	movdqa	$t3,0x30(%rsp)
-+	mov	$E,$a0
-+	jmp	.Lssse3_00_47
-+
-+.align	16
-+.Lssse3_00_47:
-+	sub	\$`-16*2*$SZ`,$Tbl	# size optimization
-+___
-+sub Xupdate_256_SSSE3 () {
-+	(
-+	'&movdqa	($t0,@X[1]);',
-+	'&movdqa	($t3,@X[3])',
-+	'&palignr	($t0,@X[0],$SZ)',	# X[1..4]
-+	 '&palignr	($t3,@X[2],$SZ);',	# X[9..12]
-+	'&movdqa	($t1,$t0)',
-+	'&movdqa	($t2,$t0);',
-+	'&psrld		($t0,$sigma0[2])',
-+	 '&paddd	(@X[0],$t3);',		# X[0..3] += X[9..12]
-+	'&psrld		($t2,$sigma0[0])',
-+	 '&pshufd	($t3,@X[3],0b11111010)',# X[14..15]
-+	'&pslld		($t1,8*$SZ-$sigma0[1]);'.
-+	'&pxor		($t0,$t2)',
-+	'&psrld		($t2,$sigma0[1]-$sigma0[0]);'.
-+	'&pxor		($t0,$t1)',
-+	'&pslld		($t1,$sigma0[1]-$sigma0[0]);'.
-+	'&pxor		($t0,$t2);',
-+	 '&movdqa	($t2,$t3)',
-+	'&pxor		($t0,$t1);',		# sigma0(X[1..4])
-+	 '&psrld	($t3,$sigma1[2])',
-+	'&paddd		(@X[0],$t0);',		# X[0..3] += sigma0(X[1..4])
-+	 '&psrlq	($t2,$sigma1[0])',
-+	 '&pxor		($t3,$t2);',
-+	 '&psrlq	($t2,$sigma1[1]-$sigma1[0])',
-+	 '&pxor		($t3,$t2)',
-+	 '&pshufb	($t3,$t4)',		# sigma1(X[14..15])
-+	'&paddd		(@X[0],$t3)',		# X[0..1] += sigma1(X[14..15])
-+	 '&pshufd	($t3,@X[0],0b01010000)',# X[16..17]
-+	 '&movdqa	($t2,$t3);',
-+	 '&psrld	($t3,$sigma1[2])',
-+	 '&psrlq	($t2,$sigma1[0])',
-+	 '&pxor		($t3,$t2);',
-+	 '&psrlq	($t2,$sigma1[1]-$sigma1[0])',
-+	 '&pxor		($t3,$t2);',
-+	'&movdqa	($t2,16*2*$j."($Tbl)")',
-+	 '&pshufb	($t3,$t5)',
-+	'&paddd		(@X[0],$t3)'		# X[2..3] += sigma1(X[16..17])
-+	);
-+}
-+
-+sub SSSE3_256_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body,&$body,&$body);	# 104 instructions
-+
-+    if (0) {
-+	foreach (Xupdate_256_SSSE3()) {		# 36 instructions
-+	    eval;
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	}
-+    } else {			# squeeze extra 4% on Westmere and 19% on Atom
-+	  eval(shift(@insns));	#@
-+	&movdqa		($t0,@X[1]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&movdqa		($t3,@X[3]);
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	&palignr	($t0,@X[0],$SZ);	# X[1..4]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &palignr	($t3,@X[2],$SZ);	# X[9..12]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	&movdqa		($t1,$t0);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&movdqa		($t2,$t0);
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	&psrld		($t0,$sigma0[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &paddd		(@X[0],$t3);		# X[0..3] += X[9..12]
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	&psrld		($t2,$sigma0[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &pshufd	($t3,@X[3],0b11111010);	# X[4..15]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	&pslld		($t1,8*$SZ-$sigma0[1]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&pxor		($t0,$t2);
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	&psrld		($t2,$sigma0[1]-$sigma0[0]);
-+	  eval(shift(@insns));
-+	&pxor		($t0,$t1);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&pslld		($t1,$sigma0[1]-$sigma0[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&pxor		($t0,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	 &movdqa	($t2,$t3);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&pxor		($t0,$t1);		# sigma0(X[1..4])
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &psrld		($t3,$sigma1[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&paddd		(@X[0],$t0);		# X[0..3] += sigma0(X[1..4])
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	 &psrlq		($t2,$sigma1[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &pxor		($t3,$t2);
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	 &psrlq		($t2,$sigma1[1]-$sigma1[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &pxor		($t3,$t2);
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 #&pshufb	($t3,$t4);		# sigma1(X[14..15])
-+	 &pshufd	($t3,$t3,0b10000000);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &psrldq	($t3,8);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	&paddd		(@X[0],$t3);		# X[0..1] += sigma1(X[14..15])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &pshufd	($t3,@X[0],0b01010000);	# X[16..17]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	 &movdqa	($t2,$t3);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &psrld		($t3,$sigma1[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	 &psrlq		($t2,$sigma1[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &pxor		($t3,$t2);
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	 &psrlq		($t2,$sigma1[1]-$sigma1[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &pxor		($t3,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));	#@
-+	 #&pshufb	($t3,$t5);
-+	 &pshufd	($t3,$t3,0b00001000);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&movdqa		($t2,16*2*$j."($Tbl)");
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	 &pslldq	($t3,8);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&paddd		(@X[0],$t3);		# X[2..3] += sigma1(X[16..17])
-+	  eval(shift(@insns));	#@
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+    }
-+	&paddd		($t2,@X[0]);
-+	  foreach (@insns) { eval; }		# remaining instructions
-+	&movdqa		(16*$j."(%rsp)",$t2);
-+}
-+
-+    for ($i=0,$j=0; $j<4; $j++) {
-+	&SSSE3_256_00_47($j,\&body_00_15,@X);
-+	push(@X,shift(@X));			# rotate(@X)
-+    }
-+	&cmpb	($SZ-1+16*2*$SZ."($Tbl)",0);
-+	&jne	(".Lssse3_00_47");
-+
-+    for ($i=0; $i<16; ) {
-+	foreach(body_00_15()) { eval; }
-+    }
-+$code.=<<___;
-+	mov	$_ctx,$ctx
-+	mov	$a1,$A
-+
-+	add	$SZ*0($ctx),$A
-+	lea	16*$SZ($inp),$inp
-+	add	$SZ*1($ctx),$B
-+	add	$SZ*2($ctx),$C
-+	add	$SZ*3($ctx),$D
-+	add	$SZ*4($ctx),$E
-+	add	$SZ*5($ctx),$F
-+	add	$SZ*6($ctx),$G
-+	add	$SZ*7($ctx),$H
-+
-+	cmp	$_end,$inp
-+
-+	mov	$A,$SZ*0($ctx)
-+	mov	$B,$SZ*1($ctx)
-+	mov	$C,$SZ*2($ctx)
-+	mov	$D,$SZ*3($ctx)
-+	mov	$E,$SZ*4($ctx)
-+	mov	$F,$SZ*5($ctx)
-+	mov	$G,$SZ*6($ctx)
-+	mov	$H,$SZ*7($ctx)
-+	jb	.Lloop_ssse3
-+
-+	mov	$_rsp,%rsi
-+___
-+$code.=<<___ if ($win64);
-+	movaps	16*$SZ+32(%rsp),%xmm6
-+	movaps	16*$SZ+48(%rsp),%xmm7
-+	movaps	16*$SZ+64(%rsp),%xmm8
-+	movaps	16*$SZ+80(%rsp),%xmm9
-+___
-+$code.=<<___;
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_ssse3:
-+	ret
-+.size	${func}_ssse3,.-${func}_ssse3
-+___
-+}
-+
-+if ($avx) {{
-+######################################################################
-+# XOP code path
-+#
-+if ($SZ==8) {	# SHA512 only
-+$code.=<<___;
-+.type	${func}_xop,\@function,3
-+.align	64
-+${func}_xop:
-+.Lxop_shortcut:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	mov	%rsp,%r11		# copy %rsp
-+	shl	\$4,%rdx		# num*16
-+	sub	\$`$framesz+$win64*16*($SZ==4?4:6)`,%rsp
-+	lea	($inp,%rdx,$SZ),%rdx	# inp+num*16*$SZ
-+	and	\$-64,%rsp		# align stack frame
-+	mov	$ctx,$_ctx		# save ctx, 1st arg
-+	mov	$inp,$_inp		# save inp, 2nd arh
-+	mov	%rdx,$_end		# save end pointer, "3rd" arg
-+	mov	%r11,$_rsp		# save copy of %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,16*$SZ+32(%rsp)
-+	movaps	%xmm7,16*$SZ+48(%rsp)
-+	movaps	%xmm8,16*$SZ+64(%rsp)
-+	movaps	%xmm9,16*$SZ+80(%rsp)
-+___
-+$code.=<<___ if ($win64 && $SZ>4);
-+	movaps	%xmm10,16*$SZ+96(%rsp)
-+	movaps	%xmm11,16*$SZ+112(%rsp)
-+___
-+$code.=<<___;
-+.Lprologue_xop:
-+
-+	vzeroupper
-+	mov	$SZ*0($ctx),$A
-+	mov	$SZ*1($ctx),$B
-+	mov	$SZ*2($ctx),$C
-+	mov	$SZ*3($ctx),$D
-+	mov	$SZ*4($ctx),$E
-+	mov	$SZ*5($ctx),$F
-+	mov	$SZ*6($ctx),$G
-+	mov	$SZ*7($ctx),$H
-+	jmp	.Lloop_xop
-+___
-+					if ($SZ==4) {	# SHA256
-+    my @X = map("%xmm$_",(0..3));
-+    my ($t0,$t1,$t2,$t3) = map("%xmm$_",(4..7));
-+
-+$code.=<<___;
-+.align	16
-+.Lloop_xop:
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`(%rip),$t3
-+	vmovdqu	0x00($inp),@X[0]
-+	vmovdqu	0x10($inp),@X[1]
-+	vmovdqu	0x20($inp),@X[2]
-+	vmovdqu	0x30($inp),@X[3]
-+	vpshufb	$t3,@X[0],@X[0]
-+	lea	$TABLE(%rip),$Tbl
-+	vpshufb	$t3,@X[1],@X[1]
-+	vpshufb	$t3,@X[2],@X[2]
-+	vpaddd	0x00($Tbl),@X[0],$t0
-+	vpshufb	$t3,@X[3],@X[3]
-+	vpaddd	0x20($Tbl),@X[1],$t1
-+	vpaddd	0x40($Tbl),@X[2],$t2
-+	vpaddd	0x60($Tbl),@X[3],$t3
-+	vmovdqa	$t0,0x00(%rsp)
-+	mov	$A,$a1
-+	vmovdqa	$t1,0x10(%rsp)
-+	mov	$B,$a3
-+	vmovdqa	$t2,0x20(%rsp)
-+	xor	$C,$a3			# magic
-+	vmovdqa	$t3,0x30(%rsp)
-+	mov	$E,$a0
-+	jmp	.Lxop_00_47
-+
-+.align	16
-+.Lxop_00_47:
-+	sub	\$`-16*2*$SZ`,$Tbl	# size optimization
-+___
-+sub XOP_256_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body,&$body,&$body);	# 104 instructions
-+
-+	&vpalignr	($t0,@X[1],@X[0],$SZ);	# X[1..4]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpalignr	($t3,@X[3],@X[2],$SZ);	# X[9..12]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vprotd		($t1,$t0,8*$SZ-$sigma0[1]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpsrld		($t0,$t0,$sigma0[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpaddd	(@X[0],@X[0],$t3);	# X[0..3] += X[9..12]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vprotd		($t2,$t1,$sigma0[1]-$sigma0[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpxor		($t0,$t0,$t1);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vprotd	($t3,@X[3],8*$SZ-$sigma1[1]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpxor		($t0,$t0,$t2);		# sigma0(X[1..4])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpsrld	($t2,@X[3],$sigma1[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddd		(@X[0],@X[0],$t0);	# X[0..3] += sigma0(X[1..4])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vprotd	($t1,$t3,$sigma1[1]-$sigma1[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpxor		($t3,$t3,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpxor		($t3,$t3,$t1);		# sigma1(X[14..15])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpsrldq	($t3,$t3,8);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddd		(@X[0],@X[0],$t3);	# X[0..1] += sigma1(X[14..15])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vprotd	($t3,@X[0],8*$SZ-$sigma1[1]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpsrld	($t2,@X[0],$sigma1[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vprotd	($t1,$t3,$sigma1[1]-$sigma1[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpxor		($t3,$t3,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpxor		($t3,$t3,$t1);		# sigma1(X[16..17])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpslldq	($t3,$t3,8);		# 22 instructions
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddd		(@X[0],@X[0],$t3);	# X[2..3] += sigma1(X[16..17])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddd		($t2,@X[0],16*2*$j."($Tbl)");
-+	  foreach (@insns) { eval; }		# remaining instructions
-+	&vmovdqa	(16*$j."(%rsp)",$t2);
-+}
-+
-+    for ($i=0,$j=0; $j<4; $j++) {
-+	&XOP_256_00_47($j,\&body_00_15,@X);
-+	push(@X,shift(@X));			# rotate(@X)
-+    }
-+	&cmpb	($SZ-1+16*2*$SZ."($Tbl)",0);
-+	&jne	(".Lxop_00_47");
-+
-+    for ($i=0; $i<16; ) {
-+	foreach(body_00_15()) { eval; }
-+    }
-+
-+					} else {	# SHA512
-+    my @X = map("%xmm$_",(0..7));
-+    my ($t0,$t1,$t2,$t3) = map("%xmm$_",(8..11));
-+
-+$code.=<<___;
-+.align	16
-+.Lloop_xop:
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`(%rip),$t3
-+	vmovdqu	0x00($inp),@X[0]
-+	lea	$TABLE+0x80(%rip),$Tbl	# size optimization
-+	vmovdqu	0x10($inp),@X[1]
-+	vmovdqu	0x20($inp),@X[2]
-+	vpshufb	$t3,@X[0],@X[0]
-+	vmovdqu	0x30($inp),@X[3]
-+	vpshufb	$t3,@X[1],@X[1]
-+	vmovdqu	0x40($inp),@X[4]
-+	vpshufb	$t3,@X[2],@X[2]
-+	vmovdqu	0x50($inp),@X[5]
-+	vpshufb	$t3,@X[3],@X[3]
-+	vmovdqu	0x60($inp),@X[6]
-+	vpshufb	$t3,@X[4],@X[4]
-+	vmovdqu	0x70($inp),@X[7]
-+	vpshufb	$t3,@X[5],@X[5]
-+	vpaddq	-0x80($Tbl),@X[0],$t0
-+	vpshufb	$t3,@X[6],@X[6]
-+	vpaddq	-0x60($Tbl),@X[1],$t1
-+	vpshufb	$t3,@X[7],@X[7]
-+	vpaddq	-0x40($Tbl),@X[2],$t2
-+	vpaddq	-0x20($Tbl),@X[3],$t3
-+	vmovdqa	$t0,0x00(%rsp)
-+	vpaddq	0x00($Tbl),@X[4],$t0
-+	vmovdqa	$t1,0x10(%rsp)
-+	vpaddq	0x20($Tbl),@X[5],$t1
-+	vmovdqa	$t2,0x20(%rsp)
-+	vpaddq	0x40($Tbl),@X[6],$t2
-+	vmovdqa	$t3,0x30(%rsp)
-+	vpaddq	0x60($Tbl),@X[7],$t3
-+	vmovdqa	$t0,0x40(%rsp)
-+	mov	$A,$a1
-+	vmovdqa	$t1,0x50(%rsp)
-+	mov	$B,$a3
-+	vmovdqa	$t2,0x60(%rsp)
-+	xor	$C,$a3			# magic
-+	vmovdqa	$t3,0x70(%rsp)
-+	mov	$E,$a0
-+	jmp	.Lxop_00_47
-+
-+.align	16
-+.Lxop_00_47:
-+	add	\$`16*2*$SZ`,$Tbl
-+___
-+sub XOP_512_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body);			# 52 instructions
-+
-+	&vpalignr	($t0,@X[1],@X[0],$SZ);	# X[1..2]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpalignr	($t3,@X[5],@X[4],$SZ);	# X[9..10]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vprotq		($t1,$t0,8*$SZ-$sigma0[1]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpsrlq		($t0,$t0,$sigma0[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpaddq	(@X[0],@X[0],$t3);	# X[0..1] += X[9..10]
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vprotq		($t2,$t1,$sigma0[1]-$sigma0[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpxor		($t0,$t0,$t1);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vprotq	($t3,@X[7],8*$SZ-$sigma1[1]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpxor		($t0,$t0,$t2);		# sigma0(X[1..2])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpsrlq	($t2,@X[7],$sigma1[2]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddq		(@X[0],@X[0],$t0);	# X[0..1] += sigma0(X[1..2])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vprotq	($t1,$t3,$sigma1[1]-$sigma1[0]);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpxor		($t3,$t3,$t2);
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	 &vpxor		($t3,$t3,$t1);		# sigma1(X[14..15])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddq		(@X[0],@X[0],$t3);	# X[0..1] += sigma1(X[14..15])
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	  eval(shift(@insns));
-+	&vpaddq		($t2,@X[0],16*2*$j-0x80."($Tbl)");
-+	  foreach (@insns) { eval; }		# remaining instructions
-+	&vmovdqa	(16*$j."(%rsp)",$t2);
-+}
-+
-+    for ($i=0,$j=0; $j<8; $j++) {
-+	&XOP_512_00_47($j,\&body_00_15,@X);
-+	push(@X,shift(@X));			# rotate(@X)
-+    }
-+	&cmpb	($SZ-1+16*2*$SZ-0x80."($Tbl)",0);
-+	&jne	(".Lxop_00_47");
-+
-+    for ($i=0; $i<16; ) {
-+	foreach(body_00_15()) { eval; }
-+    }
-+}
-+$code.=<<___;
-+	mov	$_ctx,$ctx
-+	mov	$a1,$A
-+
-+	add	$SZ*0($ctx),$A
-+	lea	16*$SZ($inp),$inp
-+	add	$SZ*1($ctx),$B
-+	add	$SZ*2($ctx),$C
-+	add	$SZ*3($ctx),$D
-+	add	$SZ*4($ctx),$E
-+	add	$SZ*5($ctx),$F
-+	add	$SZ*6($ctx),$G
-+	add	$SZ*7($ctx),$H
-+
-+	cmp	$_end,$inp
-+
-+	mov	$A,$SZ*0($ctx)
-+	mov	$B,$SZ*1($ctx)
-+	mov	$C,$SZ*2($ctx)
-+	mov	$D,$SZ*3($ctx)
-+	mov	$E,$SZ*4($ctx)
-+	mov	$F,$SZ*5($ctx)
-+	mov	$G,$SZ*6($ctx)
-+	mov	$H,$SZ*7($ctx)
-+	jb	.Lloop_xop
-+
-+	mov	$_rsp,%rsi
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	16*$SZ+32(%rsp),%xmm6
-+	movaps	16*$SZ+48(%rsp),%xmm7
-+	movaps	16*$SZ+64(%rsp),%xmm8
-+	movaps	16*$SZ+80(%rsp),%xmm9
-+___
-+$code.=<<___ if ($win64 && $SZ>4);
-+	movaps	16*$SZ+96(%rsp),%xmm10
-+	movaps	16*$SZ+112(%rsp),%xmm11
-+___
-+$code.=<<___;
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_xop:
-+	ret
-+.size	${func}_xop,.-${func}_xop
-+___
-+}
-+######################################################################
-+# AVX+shrd code path
-+#
-+local *ror = sub { &shrd(@_[0],@_) };
-+
-+$code.=<<___;
-+.type	${func}_avx,\@function,3
-+.align	64
-+${func}_avx:
-+.Lavx_shortcut:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	mov	%rsp,%r11		# copy %rsp
-+	shl	\$4,%rdx		# num*16
-+	sub	\$`$framesz+$win64*16*($SZ==4?4:6)`,%rsp
-+	lea	($inp,%rdx,$SZ),%rdx	# inp+num*16*$SZ
-+	and	\$-64,%rsp		# align stack frame
-+	mov	$ctx,$_ctx		# save ctx, 1st arg
-+	mov	$inp,$_inp		# save inp, 2nd arh
-+	mov	%rdx,$_end		# save end pointer, "3rd" arg
-+	mov	%r11,$_rsp		# save copy of %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,16*$SZ+32(%rsp)
-+	movaps	%xmm7,16*$SZ+48(%rsp)
-+	movaps	%xmm8,16*$SZ+64(%rsp)
-+	movaps	%xmm9,16*$SZ+80(%rsp)
-+___
-+$code.=<<___ if ($win64 && $SZ>4);
-+	movaps	%xmm10,16*$SZ+96(%rsp)
-+	movaps	%xmm11,16*$SZ+112(%rsp)
-+___
-+$code.=<<___;
-+.Lprologue_avx:
-+
-+	vzeroupper
-+	mov	$SZ*0($ctx),$A
-+	mov	$SZ*1($ctx),$B
-+	mov	$SZ*2($ctx),$C
-+	mov	$SZ*3($ctx),$D
-+	mov	$SZ*4($ctx),$E
-+	mov	$SZ*5($ctx),$F
-+	mov	$SZ*6($ctx),$G
-+	mov	$SZ*7($ctx),$H
-+___
-+					if ($SZ==4) {	# SHA256
-+    my @X = map("%xmm$_",(0..3));
-+    my ($t0,$t1,$t2,$t3, $t4,$t5) = map("%xmm$_",(4..9));
-+
-+$code.=<<___;
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`+32(%rip),$t4
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`+64(%rip),$t5
-+	jmp	.Lloop_avx
-+.align	16
-+.Lloop_avx:
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`(%rip),$t3
-+	vmovdqu	0x00($inp),@X[0]
-+	vmovdqu	0x10($inp),@X[1]
-+	vmovdqu	0x20($inp),@X[2]
-+	vmovdqu	0x30($inp),@X[3]
-+	vpshufb	$t3,@X[0],@X[0]
-+	lea	$TABLE(%rip),$Tbl
-+	vpshufb	$t3,@X[1],@X[1]
-+	vpshufb	$t3,@X[2],@X[2]
-+	vpaddd	0x00($Tbl),@X[0],$t0
-+	vpshufb	$t3,@X[3],@X[3]
-+	vpaddd	0x20($Tbl),@X[1],$t1
-+	vpaddd	0x40($Tbl),@X[2],$t2
-+	vpaddd	0x60($Tbl),@X[3],$t3
-+	vmovdqa	$t0,0x00(%rsp)
-+	mov	$A,$a1
-+	vmovdqa	$t1,0x10(%rsp)
-+	mov	$B,$a3
-+	vmovdqa	$t2,0x20(%rsp)
-+	xor	$C,$a3			# magic
-+	vmovdqa	$t3,0x30(%rsp)
-+	mov	$E,$a0
-+	jmp	.Lavx_00_47
-+
-+.align	16
-+.Lavx_00_47:
-+	sub	\$`-16*2*$SZ`,$Tbl	# size optimization
-+___
-+sub Xupdate_256_AVX () {
-+	(
-+	'&vpalignr	($t0,@X[1],@X[0],$SZ)',	# X[1..4]
-+	 '&vpalignr	($t3,@X[3],@X[2],$SZ)',	# X[9..12]
-+	'&vpsrld	($t2,$t0,$sigma0[0]);',
-+	 '&vpaddd	(@X[0],@X[0],$t3)',	# X[0..3] += X[9..12]
-+	'&vpsrld	($t3,$t0,$sigma0[2])',
-+	'&vpslld	($t1,$t0,8*$SZ-$sigma0[1]);',
-+	'&vpxor		($t0,$t3,$t2)',
-+	 '&vpshufd	($t3,@X[3],0b11111010)',# X[14..15]
-+	'&vpsrld	($t2,$t2,$sigma0[1]-$sigma0[0]);',
-+	'&vpxor		($t0,$t0,$t1)',
-+	'&vpslld	($t1,$t1,$sigma0[1]-$sigma0[0]);',
-+	'&vpxor		($t0,$t0,$t2)',
-+	 '&vpsrld	($t2,$t3,$sigma1[2]);',
-+	'&vpxor		($t0,$t0,$t1)',		# sigma0(X[1..4])
-+	 '&vpsrlq	($t3,$t3,$sigma1[0]);',
-+	'&vpaddd	(@X[0],@X[0],$t0)',	# X[0..3] += sigma0(X[1..4])
-+	 '&vpxor	($t2,$t2,$t3);',
-+	 '&vpsrlq	($t3,$t3,$sigma1[1]-$sigma1[0])',
-+	 '&vpxor	($t2,$t2,$t3)',
-+	 '&vpshufb	($t2,$t2,$t4)',		# sigma1(X[14..15])
-+	'&vpaddd	(@X[0],@X[0],$t2)',	# X[0..1] += sigma1(X[14..15])
-+	 '&vpshufd	($t3,@X[0],0b01010000)',# X[16..17]
-+	 '&vpsrld	($t2,$t3,$sigma1[2])',
-+	 '&vpsrlq	($t3,$t3,$sigma1[0])',
-+	 '&vpxor	($t2,$t2,$t3);',
-+	 '&vpsrlq	($t3,$t3,$sigma1[1]-$sigma1[0])',
-+	 '&vpxor	($t2,$t2,$t3)',
-+	 '&vpshufb	($t2,$t2,$t5)',
-+	'&vpaddd	(@X[0],@X[0],$t2)'	# X[2..3] += sigma1(X[16..17])
-+	);
-+}
-+
-+sub AVX_256_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body,&$body,&$body);	# 104 instructions
-+
-+	foreach (Xupdate_256_AVX()) {		# 29 instructions
-+	    eval;
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	}
-+	&vpaddd		($t2,@X[0],16*2*$j."($Tbl)");
-+	  foreach (@insns) { eval; }		# remaining instructions
-+	&vmovdqa	(16*$j."(%rsp)",$t2);
-+}
-+
-+    for ($i=0,$j=0; $j<4; $j++) {
-+	&AVX_256_00_47($j,\&body_00_15,@X);
-+	push(@X,shift(@X));			# rotate(@X)
-+    }
-+	&cmpb	($SZ-1+16*2*$SZ."($Tbl)",0);
-+	&jne	(".Lavx_00_47");
-+
-+    for ($i=0; $i<16; ) {
-+	foreach(body_00_15()) { eval; }
-+    }
-+
-+					} else {	# SHA512
-+    my @X = map("%xmm$_",(0..7));
-+    my ($t0,$t1,$t2,$t3) = map("%xmm$_",(8..11));
-+
-+$code.=<<___;
-+	jmp	.Lloop_avx
-+.align	16
-+.Lloop_avx:
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`(%rip),$t3
-+	vmovdqu	0x00($inp),@X[0]
-+	lea	$TABLE+0x80(%rip),$Tbl	# size optimization
-+	vmovdqu	0x10($inp),@X[1]
-+	vmovdqu	0x20($inp),@X[2]
-+	vpshufb	$t3,@X[0],@X[0]
-+	vmovdqu	0x30($inp),@X[3]
-+	vpshufb	$t3,@X[1],@X[1]
-+	vmovdqu	0x40($inp),@X[4]
-+	vpshufb	$t3,@X[2],@X[2]
-+	vmovdqu	0x50($inp),@X[5]
-+	vpshufb	$t3,@X[3],@X[3]
-+	vmovdqu	0x60($inp),@X[6]
-+	vpshufb	$t3,@X[4],@X[4]
-+	vmovdqu	0x70($inp),@X[7]
-+	vpshufb	$t3,@X[5],@X[5]
-+	vpaddq	-0x80($Tbl),@X[0],$t0
-+	vpshufb	$t3,@X[6],@X[6]
-+	vpaddq	-0x60($Tbl),@X[1],$t1
-+	vpshufb	$t3,@X[7],@X[7]
-+	vpaddq	-0x40($Tbl),@X[2],$t2
-+	vpaddq	-0x20($Tbl),@X[3],$t3
-+	vmovdqa	$t0,0x00(%rsp)
-+	vpaddq	0x00($Tbl),@X[4],$t0
-+	vmovdqa	$t1,0x10(%rsp)
-+	vpaddq	0x20($Tbl),@X[5],$t1
-+	vmovdqa	$t2,0x20(%rsp)
-+	vpaddq	0x40($Tbl),@X[6],$t2
-+	vmovdqa	$t3,0x30(%rsp)
-+	vpaddq	0x60($Tbl),@X[7],$t3
-+	vmovdqa	$t0,0x40(%rsp)
-+	mov	$A,$a1
-+	vmovdqa	$t1,0x50(%rsp)
-+	mov	$B,$a3
-+	vmovdqa	$t2,0x60(%rsp)
-+	xor	$C,$a3			# magic
-+	vmovdqa	$t3,0x70(%rsp)
-+	mov	$E,$a0
-+	jmp	.Lavx_00_47
-+
-+.align	16
-+.Lavx_00_47:
-+	add	\$`16*2*$SZ`,$Tbl
-+___
-+sub Xupdate_512_AVX () {
-+	(
-+	'&vpalignr	($t0,@X[1],@X[0],$SZ)',	# X[1..2]
-+	 '&vpalignr	($t3,@X[5],@X[4],$SZ)',	# X[9..10]
-+	'&vpsrlq	($t2,$t0,$sigma0[0])',
-+	 '&vpaddq	(@X[0],@X[0],$t3);',	# X[0..1] += X[9..10]
-+	'&vpsrlq	($t3,$t0,$sigma0[2])',
-+	'&vpsllq	($t1,$t0,8*$SZ-$sigma0[1]);',
-+	 '&vpxor	($t0,$t3,$t2)',
-+	'&vpsrlq	($t2,$t2,$sigma0[1]-$sigma0[0]);',
-+	 '&vpxor	($t0,$t0,$t1)',
-+	'&vpsllq	($t1,$t1,$sigma0[1]-$sigma0[0]);',
-+	 '&vpxor	($t0,$t0,$t2)',
-+	 '&vpsrlq	($t3,@X[7],$sigma1[2]);',
-+	'&vpxor		($t0,$t0,$t1)',		# sigma0(X[1..2])
-+	 '&vpsllq	($t2,@X[7],8*$SZ-$sigma1[1]);',
-+	'&vpaddq	(@X[0],@X[0],$t0)',	# X[0..1] += sigma0(X[1..2])
-+	 '&vpsrlq	($t1,@X[7],$sigma1[0]);',
-+	 '&vpxor	($t3,$t3,$t2)',
-+	 '&vpsllq	($t2,$t2,$sigma1[1]-$sigma1[0]);',
-+	 '&vpxor	($t3,$t3,$t1)',
-+	 '&vpsrlq	($t1,$t1,$sigma1[1]-$sigma1[0]);',
-+	 '&vpxor	($t3,$t3,$t2)',
-+	 '&vpxor	($t3,$t3,$t1)',		# sigma1(X[14..15])
-+	'&vpaddq	(@X[0],@X[0],$t3)',	# X[0..1] += sigma1(X[14..15])
-+	);
-+}
-+
-+sub AVX_512_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body);			# 52 instructions
-+
-+	foreach (Xupdate_512_AVX()) {		# 23 instructions
-+	    eval;
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	}
-+	&vpaddq		($t2,@X[0],16*2*$j-0x80."($Tbl)");
-+	  foreach (@insns) { eval; }		# remaining instructions
-+	&vmovdqa	(16*$j."(%rsp)",$t2);
-+}
-+
-+    for ($i=0,$j=0; $j<8; $j++) {
-+	&AVX_512_00_47($j,\&body_00_15,@X);
-+	push(@X,shift(@X));			# rotate(@X)
-+    }
-+	&cmpb	($SZ-1+16*2*$SZ-0x80."($Tbl)",0);
-+	&jne	(".Lavx_00_47");
-+
-+    for ($i=0; $i<16; ) {
-+	foreach(body_00_15()) { eval; }
-+    }
-+}
-+$code.=<<___;
-+	mov	$_ctx,$ctx
-+	mov	$a1,$A
-+
-+	add	$SZ*0($ctx),$A
-+	lea	16*$SZ($inp),$inp
-+	add	$SZ*1($ctx),$B
-+	add	$SZ*2($ctx),$C
-+	add	$SZ*3($ctx),$D
-+	add	$SZ*4($ctx),$E
-+	add	$SZ*5($ctx),$F
-+	add	$SZ*6($ctx),$G
-+	add	$SZ*7($ctx),$H
-+
-+	cmp	$_end,$inp
-+
-+	mov	$A,$SZ*0($ctx)
-+	mov	$B,$SZ*1($ctx)
-+	mov	$C,$SZ*2($ctx)
-+	mov	$D,$SZ*3($ctx)
-+	mov	$E,$SZ*4($ctx)
-+	mov	$F,$SZ*5($ctx)
-+	mov	$G,$SZ*6($ctx)
-+	mov	$H,$SZ*7($ctx)
-+	jb	.Lloop_avx
-+
-+	mov	$_rsp,%rsi
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	16*$SZ+32(%rsp),%xmm6
-+	movaps	16*$SZ+48(%rsp),%xmm7
-+	movaps	16*$SZ+64(%rsp),%xmm8
-+	movaps	16*$SZ+80(%rsp),%xmm9
-+___
-+$code.=<<___ if ($win64 && $SZ>4);
-+	movaps	16*$SZ+96(%rsp),%xmm10
-+	movaps	16*$SZ+112(%rsp),%xmm11
-+___
-+$code.=<<___;
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_avx:
-+	ret
-+.size	${func}_avx,.-${func}_avx
-+___
-+
-+if ($avx>1) {{
-+######################################################################
-+# AVX2+BMI code path
-+#
-+my $a5=$SZ==4?"%esi":"%rsi";	# zap $inp 
-+my $PUSH8=8*2*$SZ;
-+use integer;
-+
-+sub bodyx_00_15 () {
-+	# at start $a1 should be zero, $a3 - $b^$c and $a4 copy of $f
-+	(
-+	'($a,$b,$c,$d,$e,$f,$g,$h)=@ROT;'.
-+
-+	'&add	($h,(32*($i/(16/$SZ))+$SZ*($i%(16/$SZ)))%$PUSH8.$base)',    # h+=X[i]+K[i]
-+	'&and	($a4,$e)',		# f&e
-+	'&rorx	($a0,$e,$Sigma1[2])',
-+	'&rorx	($a2,$e,$Sigma1[1])',
-+
-+	'&lea	($a,"($a,$a1)")',	# h+=Sigma0(a) from the past
-+	'&lea	($h,"($h,$a4)")',
-+	'&andn	($a4,$e,$g)',		# ~e&g
-+	'&xor	($a0,$a2)',
-+
-+	'&rorx	($a1,$e,$Sigma1[0])',
-+	'&lea	($h,"($h,$a4)")',	# h+=Ch(e,f,g)=(e&f)+(~e&g)
-+	'&xor	($a0,$a1)',		# Sigma1(e)
-+	'&mov	($a2,$a)',
-+
-+	'&rorx	($a4,$a,$Sigma0[2])',
-+	'&lea	($h,"($h,$a0)")',	# h+=Sigma1(e)
-+	'&xor	($a2,$b)',		# a^b, b^c in next round
-+	'&rorx	($a1,$a,$Sigma0[1])',
-+
-+	'&rorx	($a0,$a,$Sigma0[0])',
-+	'&lea	($d,"($d,$h)")',	# d+=h
-+	'&and	($a3,$a2)',		# (b^c)&(a^b)
-+	'&xor	($a1,$a4)',
-+
-+	'&xor	($a3,$b)',		# Maj(a,b,c)=Ch(a^b,c,b)
-+	'&xor	($a1,$a0)',		# Sigma0(a)
-+	'&lea	($h,"($h,$a3)");'.	# h+=Maj(a,b,c)
-+	'&mov	($a4,$e)',		# copy of f in future
-+
-+	'($a2,$a3) = ($a3,$a2); unshift(@ROT,pop(@ROT)); $i++;'
-+	);
-+	# and at the finish one has to $a+=$a1
-+}
-+
-+$code.=<<___;
-+.type	${func}_avx2,\@function,3
-+.align	64
-+${func}_avx2:
-+.Lavx2_shortcut:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	mov	%rsp,%r11		# copy %rsp
-+	sub	\$`2*$SZ*$rounds+4*8+$win64*16*($SZ==4?4:6)`,%rsp
-+	shl	\$4,%rdx		# num*16
-+	and	\$-256*$SZ,%rsp		# align stack frame
-+	lea	($inp,%rdx,$SZ),%rdx	# inp+num*16*$SZ
-+	add	\$`2*$SZ*($rounds-8)`,%rsp
-+	mov	$ctx,$_ctx		# save ctx, 1st arg
-+	mov	$inp,$_inp		# save inp, 2nd arh
-+	mov	%rdx,$_end		# save end pointer, "3rd" arg
-+	mov	%r11,$_rsp		# save copy of %rsp
-+___
-+$code.=<<___ if ($win64);
-+	movaps	%xmm6,16*$SZ+32(%rsp)
-+	movaps	%xmm7,16*$SZ+48(%rsp)
-+	movaps	%xmm8,16*$SZ+64(%rsp)
-+	movaps	%xmm9,16*$SZ+80(%rsp)
-+___
-+$code.=<<___ if ($win64 && $SZ>4);
-+	movaps	%xmm10,16*$SZ+96(%rsp)
-+	movaps	%xmm11,16*$SZ+112(%rsp)
-+___
-+$code.=<<___;
-+.Lprologue_avx2:
-+
-+	vzeroupper
-+	sub	\$-16*$SZ,$inp		# inp++, size optimization
-+	mov	$SZ*0($ctx),$A
-+	mov	$inp,%r12		# borrow $T1
-+	mov	$SZ*1($ctx),$B
-+	cmp	%rdx,$inp		# $_end
-+	mov	$SZ*2($ctx),$C
-+	cmove	%rsp,%r12		# next block or random data
-+	mov	$SZ*3($ctx),$D
-+	mov	$SZ*4($ctx),$E
-+	mov	$SZ*5($ctx),$F
-+	mov	$SZ*6($ctx),$G
-+	mov	$SZ*7($ctx),$H
-+___
-+					if ($SZ==4) {	# SHA256
-+    my @X = map("%ymm$_",(0..3));
-+    my ($t0,$t1,$t2,$t3, $t4,$t5) = map("%ymm$_",(4..9));
-+
-+$code.=<<___;
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`+32(%rip),$t4
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`+64(%rip),$t5
-+	jmp	.Loop_avx2
-+.align	16
-+.Loop_avx2:
-+	vmovdqa	$TABLE+`$SZ*2*$rounds`(%rip),$t3
-+	vmovdqu	-16*$SZ+0($inp),%xmm0
-+	vmovdqu	-16*$SZ+16($inp),%xmm1
-+	vmovdqu	-16*$SZ+32($inp),%xmm2
-+	vmovdqu	-16*$SZ+48($inp),%xmm3
-+	#mov		$inp,$_inp	# offload $inp
-+	vinserti128	\$1,(%r12),@X[0],@X[0]
-+	vinserti128	\$1,16(%r12),@X[1],@X[1]
-+	vpshufb		$t3,@X[0],@X[0]
-+	vinserti128	\$1,32(%r12),@X[2],@X[2]
-+	vpshufb		$t3,@X[1],@X[1]
-+	vinserti128	\$1,48(%r12),@X[3],@X[3]
-+
-+	lea	$TABLE(%rip),$Tbl
-+	vpshufb	$t3,@X[2],@X[2]
-+	vpaddd	0x00($Tbl),@X[0],$t0
-+	vpshufb	$t3,@X[3],@X[3]
-+	vpaddd	0x20($Tbl),@X[1],$t1
-+	vpaddd	0x40($Tbl),@X[2],$t2
-+	vpaddd	0x60($Tbl),@X[3],$t3
-+	vmovdqa	$t0,0x00(%rsp)
-+	xor	$a1,$a1
-+	vmovdqa	$t1,0x20(%rsp)
-+	lea	-$PUSH8(%rsp),%rsp
-+	mov	$B,$a3
-+	vmovdqa	$t2,0x00(%rsp)
-+	xor	$C,$a3			# magic
-+	vmovdqa	$t3,0x20(%rsp)
-+	mov	$F,$a4
-+	sub	\$-16*2*$SZ,$Tbl	# size optimization
-+	jmp	.Lavx2_00_47
-+
-+.align	16
-+.Lavx2_00_47:
-+___
-+
-+sub AVX2_256_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body,&$body,&$body);	# 96 instructions
-+my $base = "+2*$PUSH8(%rsp)";
-+
-+	&lea	("%rsp","-$PUSH8(%rsp)")	if (($j%2)==0);
-+	foreach (Xupdate_256_AVX()) {		# 29 instructions
-+	    eval;
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	    eval(shift(@insns));
-+	}
-+	&vpaddd		($t2,@X[0],16*2*$j."($Tbl)");
-+	  foreach (@insns) { eval; }		# remaining instructions
-+	&vmovdqa	((32*$j)%$PUSH8."(%rsp)",$t2);
-+}
-+
-+    for ($i=0,$j=0; $j<4; $j++) {
-+	&AVX2_256_00_47($j,\&bodyx_00_15,@X);
-+	push(@X,shift(@X));			# rotate(@X)
-+    }
-+	&lea	($Tbl,16*2*$SZ."($Tbl)");
-+	&cmpb	(($SZ-1)."($Tbl)",0);
-+	&jne	(".Lavx2_00_47");
-+
-+    for ($i=0; $i<16; ) {
-+	my $base=$i<8?"+$PUSH8(%rsp)":"(%rsp)";
-+	foreach(bodyx_00_15()) { eval; }
-+    }
-+					} else {	# SHA512
-+    my @X = map("%ymm$_",(0..7));
-+    my ($t0,$t1,$t2,$t3) = map("%ymm$_",(8..11));
-+
-+$code.=<<___;
-+	jmp	.Loop_avx2
-+.align	16
-+.Loop_avx2:
-+	vmovdqu	-16*$SZ($inp),%xmm0
-+	vmovdqu	-16*$SZ+16($inp),%xmm1
-+	vmovdqu	-16*$SZ+32($inp),%xmm2
-+	lea	$TABLE+0x80(%rip),$Tbl	# size optimization
-+	vmovdqu	-16*$SZ+48($inp),%xmm3
-+	vmovdqu	-16*$SZ+64($inp),%xmm4
-+	vmovdqu	-16*$SZ+80($inp),%xmm5
-+	vmovdqu	-16*$SZ+96($inp),%xmm6
-+	vmovdqu	-16*$SZ+112($inp),%xmm7
-+	#mov	$inp,$_inp	# offload $inp
-+	vmovdqa	`$SZ*2*$rounds-0x80`($Tbl),$t2
-+	vinserti128	\$1,(%r12),@X[0],@X[0]
-+	vinserti128	\$1,16(%r12),@X[1],@X[1]
-+	 vpshufb	$t2,@X[0],@X[0]
-+	vinserti128	\$1,32(%r12),@X[2],@X[2]
-+	 vpshufb	$t2,@X[1],@X[1]
-+	vinserti128	\$1,48(%r12),@X[3],@X[3]
-+	 vpshufb	$t2,@X[2],@X[2]
-+	vinserti128	\$1,64(%r12),@X[4],@X[4]
-+	 vpshufb	$t2,@X[3],@X[3]
-+	vinserti128	\$1,80(%r12),@X[5],@X[5]
-+	 vpshufb	$t2,@X[4],@X[4]
-+	vinserti128	\$1,96(%r12),@X[6],@X[6]
-+	 vpshufb	$t2,@X[5],@X[5]
-+	vinserti128	\$1,112(%r12),@X[7],@X[7]
-+
-+	vpaddq	-0x80($Tbl),@X[0],$t0
-+	vpshufb	$t2,@X[6],@X[6]
-+	vpaddq	-0x60($Tbl),@X[1],$t1
-+	vpshufb	$t2,@X[7],@X[7]
-+	vpaddq	-0x40($Tbl),@X[2],$t2
-+	vpaddq	-0x20($Tbl),@X[3],$t3
-+	vmovdqa	$t0,0x00(%rsp)
-+	vpaddq	0x00($Tbl),@X[4],$t0
-+	vmovdqa	$t1,0x20(%rsp)
-+	vpaddq	0x20($Tbl),@X[5],$t1
-+	vmovdqa	$t2,0x40(%rsp)
-+	vpaddq	0x40($Tbl),@X[6],$t2
-+	vmovdqa	$t3,0x60(%rsp)
-+	lea	-$PUSH8(%rsp),%rsp
-+	vpaddq	0x60($Tbl),@X[7],$t3
-+	vmovdqa	$t0,0x00(%rsp)
-+	xor	$a1,$a1
-+	vmovdqa	$t1,0x20(%rsp)
-+	mov	$B,$a3
-+	vmovdqa	$t2,0x40(%rsp)
-+	xor	$C,$a3			# magic
-+	vmovdqa	$t3,0x60(%rsp)
-+	mov	$F,$a4
-+	add	\$16*2*$SZ,$Tbl
-+	jmp	.Lavx2_00_47
-+
-+.align	16
-+.Lavx2_00_47:
-+___
-+
-+sub AVX2_512_00_47 () {
-+my $j = shift;
-+my $body = shift;
-+my @X = @_;
-+my @insns = (&$body,&$body);			# 48 instructions
-+my $base = "+2*$PUSH8(%rsp)";
-+
-+	&lea	("%rsp","-$PUSH8(%rsp)")	if (($j%4)==0);
-+	foreach (Xupdate_512_AVX()) {		# 23 instructions
-+	    eval;
-+	    if ($_ !~ /\;$/) {
-+		eval(shift(@insns));
-+		eval(shift(@insns));
-+		eval(shift(@insns));
-+	    }
-+	}
-+	&vpaddq		($t2,@X[0],16*2*$j-0x80."($Tbl)");
-+	  foreach (@insns) { eval; }		# remaining instructions
-+	&vmovdqa	((32*$j)%$PUSH8."(%rsp)",$t2);
-+}
-+
-+    for ($i=0,$j=0; $j<8; $j++) {
-+	&AVX2_512_00_47($j,\&bodyx_00_15,@X);
-+	push(@X,shift(@X));			# rotate(@X)
-+    }
-+	&lea	($Tbl,16*2*$SZ."($Tbl)");
-+	&cmpb	(($SZ-1-0x80)."($Tbl)",0);
-+	&jne	(".Lavx2_00_47");
-+
-+    for ($i=0; $i<16; ) {
-+	my $base=$i<8?"+$PUSH8(%rsp)":"(%rsp)";
-+	foreach(bodyx_00_15()) { eval; }
-+    }
-+}
-+$code.=<<___;
-+	mov	`2*$SZ*$rounds`(%rsp),$ctx	# $_ctx
-+	add	$a1,$A
-+	#mov	`2*$SZ*$rounds+8`(%rsp),$inp	# $_inp
-+	lea	`2*$SZ*($rounds-8)`(%rsp),$Tbl
-+
-+	add	$SZ*0($ctx),$A
-+	add	$SZ*1($ctx),$B
-+	add	$SZ*2($ctx),$C
-+	add	$SZ*3($ctx),$D
-+	add	$SZ*4($ctx),$E
-+	add	$SZ*5($ctx),$F
-+	add	$SZ*6($ctx),$G
-+	add	$SZ*7($ctx),$H
-+
-+	mov	$A,$SZ*0($ctx)
-+	mov	$B,$SZ*1($ctx)
-+	mov	$C,$SZ*2($ctx)
-+	mov	$D,$SZ*3($ctx)
-+	mov	$E,$SZ*4($ctx)
-+	mov	$F,$SZ*5($ctx)
-+	mov	$G,$SZ*6($ctx)
-+	mov	$H,$SZ*7($ctx)
-+
-+	cmp	`$PUSH8+2*8`($Tbl),$inp	# $_end
-+	je	.Ldone_avx2
-+
-+	xor	$a1,$a1
-+	mov	$B,$a3
-+	xor	$C,$a3			# magic
-+	mov	$F,$a4
-+	jmp	.Lower_avx2
-+.align	16
-+.Lower_avx2:
-+___
-+    for ($i=0; $i<8; ) {
-+	my $base="+16($Tbl)";
-+	foreach(bodyx_00_15()) { eval; }
-+    }
-+$code.=<<___;
-+	lea	-$PUSH8($Tbl),$Tbl
-+	cmp	%rsp,$Tbl
-+	jae	.Lower_avx2
-+
-+	mov	`2*$SZ*$rounds`(%rsp),$ctx	# $_ctx
-+	add	$a1,$A
-+	#mov	`2*$SZ*$rounds+8`(%rsp),$inp	# $_inp
-+	lea	`2*$SZ*($rounds-8)`(%rsp),%rsp
-+
-+	add	$SZ*0($ctx),$A
-+	add	$SZ*1($ctx),$B
-+	add	$SZ*2($ctx),$C
-+	add	$SZ*3($ctx),$D
-+	add	$SZ*4($ctx),$E
-+	add	$SZ*5($ctx),$F
-+	lea	`2*16*$SZ`($inp),$inp	# inp+=2
-+	add	$SZ*6($ctx),$G
-+	mov	$inp,%r12
-+	add	$SZ*7($ctx),$H
-+	cmp	$_end,$inp
-+
-+	mov	$A,$SZ*0($ctx)
-+	cmove	%rsp,%r12		# next block or stale data
-+	mov	$B,$SZ*1($ctx)
-+	mov	$C,$SZ*2($ctx)
-+	mov	$D,$SZ*3($ctx)
-+	mov	$E,$SZ*4($ctx)
-+	mov	$F,$SZ*5($ctx)
-+	mov	$G,$SZ*6($ctx)
-+	mov	$H,$SZ*7($ctx)
-+
-+	jbe	.Loop_avx2
-+	lea	(%rsp),$Tbl
-+
-+.Ldone_avx2:
-+	lea	($Tbl),%rsp
-+	mov	$_rsp,%rsi
-+	vzeroupper
-+___
-+$code.=<<___ if ($win64);
-+	movaps	16*$SZ+32(%rsp),%xmm6
-+	movaps	16*$SZ+48(%rsp),%xmm7
-+	movaps	16*$SZ+64(%rsp),%xmm8
-+	movaps	16*$SZ+80(%rsp),%xmm9
-+___
-+$code.=<<___ if ($win64 && $SZ>4);
-+	movaps	16*$SZ+96(%rsp),%xmm10
-+	movaps	16*$SZ+112(%rsp),%xmm11
-+___
-+$code.=<<___;
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue_avx2:
-+	ret
-+.size	${func}_avx2,.-${func}_avx2
-+___
-+}}
-+}}}}}
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	mov	8($disp),%rsi		# disp->ImageBase
-+	mov	56($disp),%r11		# disp->HanderlData
-+
-+	mov	0(%r11),%r10d		# HandlerData[0]
-+	lea	(%rsi,%r10),%r10	# prologue label
-+	cmp	%r10,%rbx		# context->RipRsp
-+
-+	mov	4(%r11),%r10d		# HandlerData[1]
-+	lea	(%rsi,%r10),%r10	# epilogue label
-+	cmp	%r10,%rbx		# context->Rip>=epilogue label
-+	jae	.Lin_prologue
-+___
-+$code.=<<___ if ($avx>1);
-+	lea	.Lavx2_shortcut(%rip),%r10
-+	cmp	%r10,%rbx		# context->RipRbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+	lea	.Lepilogue(%rip),%r10
-+	cmp	%r10,%rbx
-+	jb	.Lin_prologue		# non-AVX code
-+
-+	lea	16*$SZ+4*8(%rsi),%rsi	# Xmm6- save area
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$`$SZ==4?8:12`,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+___
-+
-+$code.=<<___ if ($SZ==4 && $shaext);
-+.type	shaext_handler,\@abi-omnipotent
-+.align	16
-+shaext_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lprologue_shaext(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lprologue
-+	jb	.Lin_prologue
-+
-+	lea	.Lepilogue_shaext(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
-+	jae	.Lin_prologue
-+
-+	lea	-8-5*16(%rax),%rsi
-+	lea	512($context),%rdi	# &context.Xmm6
-+	mov	\$10,%ecx
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	jmp	.Lin_prologue
-+.size	shaext_handler,.-shaext_handler
-+___
-+
-+$code.=<<___;
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_$func
-+	.rva	.LSEH_end_$func
-+	.rva	.LSEH_info_$func
-+___
-+$code.=<<___ if ($SZ==4 && $shaext);
-+	.rva	.LSEH_begin_${func}_shaext
-+	.rva	.LSEH_end_${func}_shaext
-+	.rva	.LSEH_info_${func}_shaext
-+___
-+$code.=<<___ if ($SZ==4);
-+	.rva	.LSEH_begin_${func}_ssse3
-+	.rva	.LSEH_end_${func}_ssse3
-+	.rva	.LSEH_info_${func}_ssse3
-+___
-+$code.=<<___ if ($avx && $SZ==8);
-+	.rva	.LSEH_begin_${func}_xop
-+	.rva	.LSEH_end_${func}_xop
-+	.rva	.LSEH_info_${func}_xop
-+___
-+$code.=<<___ if ($avx);
-+	.rva	.LSEH_begin_${func}_avx
-+	.rva	.LSEH_end_${func}_avx
-+	.rva	.LSEH_info_${func}_avx
-+___
-+$code.=<<___ if ($avx>1);
-+	.rva	.LSEH_begin_${func}_avx2
-+	.rva	.LSEH_end_${func}_avx2
-+	.rva	.LSEH_info_${func}_avx2
-+___
-+$code.=<<___;
-+.section	.xdata
-+.align	8
-+.LSEH_info_$func:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lprologue,.Lepilogue			# HandlerData[]
-+___
-+$code.=<<___ if ($SZ==4 && $shaext);
-+.LSEH_info_${func}_shaext:
-+	.byte	9,0,0,0
-+	.rva	shaext_handler
-+___
-+$code.=<<___ if ($SZ==4);
-+.LSEH_info_${func}_ssse3:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lprologue_ssse3,.Lepilogue_ssse3	# HandlerData[]
-+___
-+$code.=<<___ if ($avx && $SZ==8);
-+.LSEH_info_${func}_xop:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lprologue_xop,.Lepilogue_xop		# HandlerData[]
-+___
-+$code.=<<___ if ($avx);
-+.LSEH_info_${func}_avx:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lprologue_avx,.Lepilogue_avx		# HandlerData[]
-+___
-+$code.=<<___ if ($avx>1);
-+.LSEH_info_${func}_avx2:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+	.rva	.Lprologue_avx2,.Lepilogue_avx2		# HandlerData[]
-+___
-+}
-+
-+sub sha256op38 {
-+    my $instr = shift;
-+    my %opcodelet = (
-+		"sha256rnds2" => 0xcb,
-+  		"sha256msg1"  => 0xcc,
-+		"sha256msg2"  => 0xcd	);
-+
-+    if (defined($opcodelet{$instr}) && @_[0] =~ /%xmm([0-7]),\s*%xmm([0-7])/) {
-+      my @opcode=(0x0f,0x38);
-+	push @opcode,$opcodelet{$instr};
-+	push @opcode,0xc0|($1&7)|(($2&7)<<3);		# ModR/M
-+	return ".byte\t".join(',',@opcode);
-+    } else {
-+	return $instr."\t".@_[0];
-+    }
-+}
-+
-+foreach (split("\n",$code)) {
-+	s/\`([^\`]*)\`/eval $1/geo;
-+
-+	s/\b(sha256[^\s]*)\s+(.*)/sha256op38($1,$2)/geo;
-+
-+	print $_,"\n";
-+}
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512p8-ppc.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512p8-ppc.pl
-new file mode 100755
-index 0000000..4d3d3b2
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/asm/sha512p8-ppc.pl
-@@ -0,0 +1,431 @@
-+#! /usr/bin/env perl
-+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. The module is, however, dual licensed under OpenSSL and
-+# CRYPTOGAMS licenses depending on where you obtain it. For further
-+# details see http://www.openssl.org/~appro/cryptogams/.
-+# ====================================================================
-+
-+# SHA256/512 for PowerISA v2.07.
-+#
-+# Accurate performance measurements are problematic, because it's
-+# always virtualized setup with possibly throttled processor.
-+# Relative comparison is therefore more informative. This module is
-+# ~60% faster than integer-only sha512-ppc.pl. To anchor to something
-+# else, SHA256 is 24% slower than sha1-ppc.pl and 2.5x slower than
-+# hardware-assisted aes-128-cbc encrypt. SHA512 is 20% faster than
-+# sha1-ppc.pl and 1.6x slower than aes-128-cbc. Another interesting
-+# result is degree of computational resources' utilization. POWER8 is
-+# "massively multi-threaded chip" and difference between single- and
-+# maximum multi-process benchmark results tells that utlization is
-+# whooping 94%. For sha512-ppc.pl we get [not unimpressive] 84% and
-+# for sha1-ppc.pl - 73%. 100% means that multi-process result equals
-+# to single-process one, given that all threads end up on the same
-+# physical core.
-+
-+$flavour=shift;
-+$output =shift;
-+
-+if ($flavour =~ /64/) {
-+	$SIZE_T=8;
-+	$LRSAVE=2*$SIZE_T;
-+	$STU="stdu";
-+	$POP="ld";
-+	$PUSH="std";
-+} elsif ($flavour =~ /32/) {
-+	$SIZE_T=4;
-+	$LRSAVE=$SIZE_T;
-+	$STU="stwu";
-+	$POP="lwz";
-+	$PUSH="stw";
-+} else { die "nonsense $flavour"; }
-+
-+$LENDIAN=($flavour=~/le/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
-+die "can't locate ppc-xlate.pl";
-+
-+open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!";
-+
-+if ($output =~ /512/) {
-+	$bits=512;
-+	$SZ=8;
-+	$sz="d";
-+	$rounds=80;
-+} else {
-+	$bits=256;
-+	$SZ=4;
-+	$sz="w";
-+	$rounds=64;
-+}
-+
-+$func="sha${bits}_block_p8";
-+$FRAME=8*$SIZE_T;
-+
-+$sp ="r1";
-+$toc="r2";
-+$ctx="r3";
-+$inp="r4";
-+$num="r5";
-+$Tbl="r6";
-+$idx="r7";
-+$lrsave="r8";
-+$offload="r11";
-+$vrsave="r12";
-+($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,10,26..31));
-+ $x00=0 if ($flavour =~ /osx/);
-+
-+@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("v$_",(0..7));
-+@X=map("v$_",(8..23));
-+($Ki,$Func,$S0,$S1,$s0,$s1,$lemask)=map("v$_",(24..31));
-+
-+sub ROUND {
-+my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
-+my $j=($i+1)%16;
-+
-+$code.=<<___		if ($i<15 && ($i%(16/$SZ))==(16/$SZ-1));
-+	lvx_u		@X[$i+1],0,$inp		; load X[i] in advance
-+	addi		$inp,$inp,16
-+___
-+$code.=<<___		if ($i<16 && ($i%(16/$SZ)));
-+	vsldoi		@X[$i],@X[$i-1],@X[$i-1],$SZ
-+___
-+$code.=<<___		if ($LENDIAN && $i<16 && ($i%(16/$SZ))==0);
-+	vperm		@X[$i],@X[$i],@X[$i],$lemask
-+___
-+$code.=<<___;
-+	`"vshasigma${sz}	$s0,@X[($j+1)%16],0,0"		if ($i>=15)`
-+	vsel		$Func,$g,$f,$e		; Ch(e,f,g)
-+	vshasigma${sz}	$S1,$e,1,15		; Sigma1(e)
-+	vaddu${sz}m	$h,$h,@X[$i%16]		; h+=X[i]
-+	vshasigma${sz}	$S0,$a,1,0		; Sigma0(a)
-+	`"vshasigma${sz}	$s1,@X[($j+14)%16],0,15"	if ($i>=15)`
-+	vaddu${sz}m	$h,$h,$Func		; h+=Ch(e,f,g)
-+	vxor		$Func,$a,$b
-+	`"vaddu${sz}m		@X[$j],@X[$j],@X[($j+9)%16]"	if ($i>=15)`
-+	vaddu${sz}m	$h,$h,$S1		; h+=Sigma1(e)
-+	vsel		$Func,$b,$c,$Func	; Maj(a,b,c)
-+	vaddu${sz}m	$g,$g,$Ki		; future h+=K[i]
-+	vaddu${sz}m	$d,$d,$h		; d+=h
-+	vaddu${sz}m	$S0,$S0,$Func		; Sigma0(a)+Maj(a,b,c)
-+	`"vaddu${sz}m		@X[$j],@X[$j],$s0"		if ($i>=15)`
-+	lvx		$Ki,$idx,$Tbl		; load next K[i]
-+	addi		$idx,$idx,16
-+	vaddu${sz}m	$h,$h,$S0		; h+=Sigma0(a)+Maj(a,b,c)
-+	`"vaddu${sz}m		@X[$j],@X[$j],$s1"		if ($i>=15)`
-+___
-+}
-+
-+$code=<<___;
-+.machine	"any"
-+.text
-+
-+.globl	$func
-+.align	6
-+$func:
-+	$STU		$sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
-+	mflr		$lrsave
-+	li		r10,`$FRAME+8*16+15`
-+	li		r11,`$FRAME+8*16+31`
-+	stvx		v20,r10,$sp		# ABI says so
-+	addi		r10,r10,32
-+	mfspr		$vrsave,256
-+	stvx		v21,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v22,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v23,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v24,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v25,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v26,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v27,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v28,r10,$sp
-+	addi		r10,r10,32
-+	stvx		v29,r11,$sp
-+	addi		r11,r11,32
-+	stvx		v30,r10,$sp
-+	stvx		v31,r11,$sp
-+	li		r11,-1
-+	stw		$vrsave,`$FRAME+21*16-4`($sp)	# save vrsave
-+	li		$x10,0x10
-+	$PUSH		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
-+	li		$x20,0x20
-+	$PUSH		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
-+	li		$x30,0x30
-+	$PUSH		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
-+	li		$x40,0x40
-+	$PUSH		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
-+	li		$x50,0x50
-+	$PUSH		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
-+	li		$x60,0x60
-+	$PUSH		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
-+	li		$x70,0x70
-+	$PUSH		$lrsave,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp)
-+	mtspr		256,r11
-+
-+	bl		LPICmeup
-+	addi		$offload,$sp,$FRAME+15
-+___
-+$code.=<<___		if ($LENDIAN);
-+	li		$idx,8
-+	lvsl		$lemask,0,$idx
-+	vspltisb	$Ki,0x0f
-+	vxor		$lemask,$lemask,$Ki
-+___
-+$code.=<<___		if ($SZ==4);
-+	lvx_4w		$A,$x00,$ctx
-+	lvx_4w		$E,$x10,$ctx
-+	vsldoi		$B,$A,$A,4		# unpack
-+	vsldoi		$C,$A,$A,8
-+	vsldoi		$D,$A,$A,12
-+	vsldoi		$F,$E,$E,4
-+	vsldoi		$G,$E,$E,8
-+	vsldoi		$H,$E,$E,12
-+___
-+$code.=<<___		if ($SZ==8);
-+	lvx_u		$A,$x00,$ctx
-+	lvx_u		$C,$x10,$ctx
-+	lvx_u		$E,$x20,$ctx
-+	vsldoi		$B,$A,$A,8		# unpack
-+	lvx_u		$G,$x30,$ctx
-+	vsldoi		$D,$C,$C,8
-+	vsldoi		$F,$E,$E,8
-+	vsldoi		$H,$G,$G,8
-+___
-+$code.=<<___;
-+	li		r0,`($rounds-16)/16`	# inner loop counter
-+	b		Loop
-+.align	5
-+Loop:
-+	lvx		$Ki,$x00,$Tbl
-+	li		$idx,16
-+	lvx_u		@X[0],0,$inp
-+	addi		$inp,$inp,16
-+	stvx		$A,$x00,$offload	# offload $A-$H
-+	stvx		$B,$x10,$offload
-+	stvx		$C,$x20,$offload
-+	stvx		$D,$x30,$offload
-+	stvx		$E,$x40,$offload
-+	stvx		$F,$x50,$offload
-+	stvx		$G,$x60,$offload
-+	stvx		$H,$x70,$offload
-+	vaddu${sz}m	$H,$H,$Ki		# h+K[i]
-+	lvx		$Ki,$idx,$Tbl
-+	addi		$idx,$idx,16
-+___
-+for ($i=0;$i<16;$i++)	{ &ROUND($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	mtctr		r0
-+	b		L16_xx
-+.align	5
-+L16_xx:
-+___
-+for (;$i<32;$i++)	{ &ROUND($i,@V); unshift(@V,pop(@V)); }
-+$code.=<<___;
-+	bdnz		L16_xx
-+
-+	lvx		@X[2],$x00,$offload
-+	subic.		$num,$num,1
-+	lvx		@X[3],$x10,$offload
-+	vaddu${sz}m	$A,$A,@X[2]
-+	lvx		@X[4],$x20,$offload
-+	vaddu${sz}m	$B,$B,@X[3]
-+	lvx		@X[5],$x30,$offload
-+	vaddu${sz}m	$C,$C,@X[4]
-+	lvx		@X[6],$x40,$offload
-+	vaddu${sz}m	$D,$D,@X[5]
-+	lvx		@X[7],$x50,$offload
-+	vaddu${sz}m	$E,$E,@X[6]
-+	lvx		@X[8],$x60,$offload
-+	vaddu${sz}m	$F,$F,@X[7]
-+	lvx		@X[9],$x70,$offload
-+	vaddu${sz}m	$G,$G,@X[8]
-+	vaddu${sz}m	$H,$H,@X[9]
-+	bne		Loop
-+___
-+$code.=<<___		if ($SZ==4);
-+	lvx		@X[0],$idx,$Tbl
-+	addi		$idx,$idx,16
-+	vperm		$A,$A,$B,$Ki		# pack the answer
-+	lvx		@X[1],$idx,$Tbl
-+	vperm		$E,$E,$F,$Ki
-+	vperm		$A,$A,$C,@X[0]
-+	vperm		$E,$E,$G,@X[0]
-+	vperm		$A,$A,$D,@X[1]
-+	vperm		$E,$E,$H,@X[1]
-+	stvx_4w		$A,$x00,$ctx
-+	stvx_4w		$E,$x10,$ctx
-+___
-+$code.=<<___		if ($SZ==8);
-+	vperm		$A,$A,$B,$Ki		# pack the answer
-+	vperm		$C,$C,$D,$Ki
-+	vperm		$E,$E,$F,$Ki
-+	vperm		$G,$G,$H,$Ki
-+	stvx_u		$A,$x00,$ctx
-+	stvx_u		$C,$x10,$ctx
-+	stvx_u		$E,$x20,$ctx
-+	stvx_u		$G,$x30,$ctx
-+___
-+$code.=<<___;
-+	li		r10,`$FRAME+8*16+15`
-+	mtlr		$lrsave
-+	li		r11,`$FRAME+8*16+31`
-+	mtspr		256,$vrsave
-+	lvx		v20,r10,$sp		# ABI says so
-+	addi		r10,r10,32
-+	lvx		v21,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v22,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v23,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v24,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v25,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v26,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v27,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v28,r10,$sp
-+	addi		r10,r10,32
-+	lvx		v29,r11,$sp
-+	addi		r11,r11,32
-+	lvx		v30,r10,$sp
-+	lvx		v31,r11,$sp
-+	$POP		r26,`$FRAME+21*16+0*$SIZE_T`($sp)
-+	$POP		r27,`$FRAME+21*16+1*$SIZE_T`($sp)
-+	$POP		r28,`$FRAME+21*16+2*$SIZE_T`($sp)
-+	$POP		r29,`$FRAME+21*16+3*$SIZE_T`($sp)
-+	$POP		r30,`$FRAME+21*16+4*$SIZE_T`($sp)
-+	$POP		r31,`$FRAME+21*16+5*$SIZE_T`($sp)
-+	addi		$sp,$sp,`$FRAME+21*16+6*$SIZE_T`
-+	blr
-+	.long		0
-+	.byte		0,12,4,1,0x80,6,3,0
-+	.long		0
-+.size	$func,.-$func
-+___
-+
-+# Ugly hack here, because PPC assembler syntax seem to vary too
-+# much from platforms to platform...
-+$code.=<<___;
-+.align	6
-+LPICmeup:
-+	mflr	r0
-+	bcl	20,31,\$+4
-+	mflr	$Tbl	; vvvvvv "distance" between . and 1st data entry
-+	addi	$Tbl,$Tbl,`64-8`
-+	mtlr	r0
-+	blr
-+	.long	0
-+	.byte	0,12,0x14,0,0,0,0,0
-+	.space	`64-9*4`
-+___
-+
-+if ($SZ==8) {
-+    local *table = sub {
-+	foreach(@_) { $code.=".quad	$_,$_\n"; }
-+    };
-+    table(
-+	"0x428a2f98d728ae22","0x7137449123ef65cd",
-+	"0xb5c0fbcfec4d3b2f","0xe9b5dba58189dbbc",
-+	"0x3956c25bf348b538","0x59f111f1b605d019",
-+	"0x923f82a4af194f9b","0xab1c5ed5da6d8118",
-+	"0xd807aa98a3030242","0x12835b0145706fbe",
-+	"0x243185be4ee4b28c","0x550c7dc3d5ffb4e2",
-+	"0x72be5d74f27b896f","0x80deb1fe3b1696b1",
-+	"0x9bdc06a725c71235","0xc19bf174cf692694",
-+	"0xe49b69c19ef14ad2","0xefbe4786384f25e3",
-+	"0x0fc19dc68b8cd5b5","0x240ca1cc77ac9c65",
-+	"0x2de92c6f592b0275","0x4a7484aa6ea6e483",
-+	"0x5cb0a9dcbd41fbd4","0x76f988da831153b5",
-+	"0x983e5152ee66dfab","0xa831c66d2db43210",
-+	"0xb00327c898fb213f","0xbf597fc7beef0ee4",
-+	"0xc6e00bf33da88fc2","0xd5a79147930aa725",
-+	"0x06ca6351e003826f","0x142929670a0e6e70",
-+	"0x27b70a8546d22ffc","0x2e1b21385c26c926",
-+	"0x4d2c6dfc5ac42aed","0x53380d139d95b3df",
-+	"0x650a73548baf63de","0x766a0abb3c77b2a8",
-+	"0x81c2c92e47edaee6","0x92722c851482353b",
-+	"0xa2bfe8a14cf10364","0xa81a664bbc423001",
-+	"0xc24b8b70d0f89791","0xc76c51a30654be30",
-+	"0xd192e819d6ef5218","0xd69906245565a910",
-+	"0xf40e35855771202a","0x106aa07032bbd1b8",
-+	"0x19a4c116b8d2d0c8","0x1e376c085141ab53",
-+	"0x2748774cdf8eeb99","0x34b0bcb5e19b48a8",
-+	"0x391c0cb3c5c95a63","0x4ed8aa4ae3418acb",
-+	"0x5b9cca4f7763e373","0x682e6ff3d6b2b8a3",
-+	"0x748f82ee5defb2fc","0x78a5636f43172f60",
-+	"0x84c87814a1f0ab72","0x8cc702081a6439ec",
-+	"0x90befffa23631e28","0xa4506cebde82bde9",
-+	"0xbef9a3f7b2c67915","0xc67178f2e372532b",
-+	"0xca273eceea26619c","0xd186b8c721c0c207",
-+	"0xeada7dd6cde0eb1e","0xf57d4f7fee6ed178",
-+	"0x06f067aa72176fba","0x0a637dc5a2c898a6",
-+	"0x113f9804bef90dae","0x1b710b35131c471b",
-+	"0x28db77f523047d84","0x32caab7b40c72493",
-+	"0x3c9ebe0a15c9bebc","0x431d67c49c100d4c",
-+	"0x4cc5d4becb3e42b6","0x597f299cfc657e2a",
-+	"0x5fcb6fab3ad6faec","0x6c44198c4a475817","0");
-+$code.=<<___	if (!$LENDIAN);
-+.quad	0x0001020304050607,0x1011121314151617
-+___
-+$code.=<<___	if ($LENDIAN);	# quad-swapped
-+.quad	0x1011121314151617,0x0001020304050607
-+___
-+} else {
-+    local *table = sub {
-+	foreach(@_) { $code.=".long	$_,$_,$_,$_\n"; }
-+    };
-+    table(
-+	"0x428a2f98","0x71374491","0xb5c0fbcf","0xe9b5dba5",
-+	"0x3956c25b","0x59f111f1","0x923f82a4","0xab1c5ed5",
-+	"0xd807aa98","0x12835b01","0x243185be","0x550c7dc3",
-+	"0x72be5d74","0x80deb1fe","0x9bdc06a7","0xc19bf174",
-+	"0xe49b69c1","0xefbe4786","0x0fc19dc6","0x240ca1cc",
-+	"0x2de92c6f","0x4a7484aa","0x5cb0a9dc","0x76f988da",
-+	"0x983e5152","0xa831c66d","0xb00327c8","0xbf597fc7",
-+	"0xc6e00bf3","0xd5a79147","0x06ca6351","0x14292967",
-+	"0x27b70a85","0x2e1b2138","0x4d2c6dfc","0x53380d13",
-+	"0x650a7354","0x766a0abb","0x81c2c92e","0x92722c85",
-+	"0xa2bfe8a1","0xa81a664b","0xc24b8b70","0xc76c51a3",
-+	"0xd192e819","0xd6990624","0xf40e3585","0x106aa070",
-+	"0x19a4c116","0x1e376c08","0x2748774c","0x34b0bcb5",
-+	"0x391c0cb3","0x4ed8aa4a","0x5b9cca4f","0x682e6ff3",
-+	"0x748f82ee","0x78a5636f","0x84c87814","0x8cc70208",
-+	"0x90befffa","0xa4506ceb","0xbef9a3f7","0xc67178f2","0");
-+$code.=<<___	if (!$LENDIAN);
-+.long	0x00010203,0x10111213,0x10111213,0x10111213
-+.long	0x00010203,0x04050607,0x10111213,0x10111213
-+.long	0x00010203,0x04050607,0x08090a0b,0x10111213
-+___
-+$code.=<<___	if ($LENDIAN);	# word-swapped
-+.long	0x10111213,0x10111213,0x10111213,0x00010203
-+.long	0x10111213,0x10111213,0x04050607,0x00010203
-+.long	0x10111213,0x08090a0b,0x04050607,0x00010203
-+___
-+}
-+$code.=<<___;
-+.asciz	"SHA${bits} for PowerISA 2.07, CRYPTOGAMS by "
-+.align	2
-+___
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/build.info
-new file mode 100644
-index 0000000..5843e50
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/build.info
-@@ -0,0 +1,69 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        sha1dgst.c sha1_one.c sha256.c sha512.c {- $target{sha1_asm_src} -}
-+
-+GENERATE[sha1-586.s]=asm/sha1-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[sha1-586.s]=../perlasm/x86asm.pl
-+GENERATE[sha256-586.s]=asm/sha256-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[sha256-586.s]=../perlasm/x86asm.pl
-+GENERATE[sha512-586.s]=asm/sha512-586.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[sha512-586.s]=../perlasm/x86asm.pl
-+
-+GENERATE[sha1-ia64.s]=asm/sha1-ia64.pl $(CFLAGS) $(LIB_CFLAGS)
-+GENERATE[sha256-ia64.s]=asm/sha512-ia64.pl $(CFLAGS) $(LIB_CFLAGS)
-+GENERATE[sha512-ia64.s]=asm/sha512-ia64.pl $(CFLAGS) $(LIB_CFLAGS)
-+
-+GENERATE[sha1-alpha.S]=asm/sha1-alpha.pl $(PERLASM_SCHEME)
-+
-+GENERATE[sha1-x86_64.s]=asm/sha1-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[sha1-mb-x86_64.s]=asm/sha1-mb-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[sha256-x86_64.s]=asm/sha512-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[sha256-mb-x86_64.s]=asm/sha256-mb-x86_64.pl $(PERLASM_SCHEME)
-+GENERATE[sha512-x86_64.s]=asm/sha512-x86_64.pl $(PERLASM_SCHEME)
-+
-+GENERATE[sha1-sparcv9.S]=asm/sha1-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[sha1-sparcv9.o]=..
-+GENERATE[sha256-sparcv9.S]=asm/sha512-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[sha256-sparcv9.o]=..
-+GENERATE[sha512-sparcv9.S]=asm/sha512-sparcv9.pl $(PERLASM_SCHEME)
-+INCLUDE[sha512-sparcv9.o]=..
-+
-+GENERATE[sha1-ppc.s]=asm/sha1-ppc.pl $(PERLASM_SCHEME)
-+GENERATE[sha256-ppc.s]=asm/sha512-ppc.pl $(PERLASM_SCHEME)
-+GENERATE[sha512-ppc.s]=asm/sha512-ppc.pl $(PERLASM_SCHEME)
-+GENERATE[sha256p8-ppc.s]=asm/sha512p8-ppc.pl $(PERLASM_SCHEME)
-+GENERATE[sha512p8-ppc.s]=asm/sha512p8-ppc.pl $(PERLASM_SCHEME)
-+
-+GENERATE[sha1-parisc.s]=asm/sha1-parisc.pl $(PERLASM_SCHEME)
-+GENERATE[sha256-parisc.s]=asm/sha512-parisc.pl $(PERLASM_SCHEME)
-+GENERATE[sha512-parisc.s]=asm/sha512-parisc.pl $(PERLASM_SCHEME)
-+
-+GENERATE[sha1-mips.S]=asm/sha1-mips.pl $(PERLASM_SCHEME)
-+GENERATE[sha256-mips.S]=asm/sha512-mips.pl $(PERLASM_SCHEME)
-+GENERATE[sha512-mips.S]=asm/sha512-mips.pl $(PERLASM_SCHEME)
-+
-+GENERATE[sha1-armv4-large.S]=asm/sha1-armv4-large.pl $(PERLASM_SCHEME)
-+INCLUDE[sha1-armv4-large.o]=..
-+GENERATE[sha256-armv4.S]=asm/sha256-armv4.pl $(PERLASM_SCHEME)
-+INCLUDE[sha256-armv4.o]=..
-+GENERATE[sha512-armv4.S]=asm/sha512-armv4.pl $(PERLASM_SCHEME)
-+INCLUDE[sha512-armv4.o]=..
-+
-+GENERATE[sha1-armv8.S]=asm/sha1-armv8.pl $(PERLASM_SCHEME)
-+INCLUDE[sha1-armv8.o]=..
-+GENERATE[sha256-armv8.S]=asm/sha512-armv8.pl $(PERLASM_SCHEME)
-+INCLUDE[sha256-armv8.o]=..
-+GENERATE[sha512-armv8.S]=asm/sha512-armv8.pl $(PERLASM_SCHEME)
-+INCLUDE[sha512-armv8.o]=..
-+
-+BEGINRAW[Makefile(unix)]
-+##### SHA assembler implementations
-+
-+# GNU make "catch all"
-+{- $builddir -}/sha1-%.S:	{- $sourcedir -}/asm/sha1-%.pl
-+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-+{- $builddir -}/sha256-%.S:	{- $sourcedir -}/asm/sha512-%.pl
-+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-+{- $builddir -}/sha512-%.S:	{- $sourcedir -}/asm/sha512-%.pl
-+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
-+ENDRAW[Makefile(unix)]
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha1_one.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha1_one.c
-new file mode 100644
-index 0000000..273ab08
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha1_one.c
-@@ -0,0 +1,28 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
-+{
-+    SHA_CTX c;
-+    static unsigned char m[SHA_DIGEST_LENGTH];
-+
-+    if (md == NULL)
-+        md = m;
-+    if (!SHA1_Init(&c))
-+        return NULL;
-+    SHA1_Update(&c, d, n);
-+    SHA1_Final(md, &c);
-+    OPENSSL_cleanse(&c, sizeof(c));
-+    return (md);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha1dgst.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha1dgst.c
-new file mode 100644
-index 0000000..819370e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha1dgst.c
-@@ -0,0 +1,17 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+# include 
-+
-+/* The implementation is in ../md32_common.h */
-+
-+# include "sha_locl.h"
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha256.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha256.c
-new file mode 100644
-index 0000000..5e7ba43
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha256.c
-@@ -0,0 +1,386 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+
-+int SHA224_Init(SHA256_CTX *c)
-+{
-+    memset(c, 0, sizeof(*c));
-+    c->h[0] = 0xc1059ed8UL;
-+    c->h[1] = 0x367cd507UL;
-+    c->h[2] = 0x3070dd17UL;
-+    c->h[3] = 0xf70e5939UL;
-+    c->h[4] = 0xffc00b31UL;
-+    c->h[5] = 0x68581511UL;
-+    c->h[6] = 0x64f98fa7UL;
-+    c->h[7] = 0xbefa4fa4UL;
-+    c->md_len = SHA224_DIGEST_LENGTH;
-+    return 1;
-+}
-+
-+int SHA256_Init(SHA256_CTX *c)
-+{
-+    memset(c, 0, sizeof(*c));
-+    c->h[0] = 0x6a09e667UL;
-+    c->h[1] = 0xbb67ae85UL;
-+    c->h[2] = 0x3c6ef372UL;
-+    c->h[3] = 0xa54ff53aUL;
-+    c->h[4] = 0x510e527fUL;
-+    c->h[5] = 0x9b05688cUL;
-+    c->h[6] = 0x1f83d9abUL;
-+    c->h[7] = 0x5be0cd19UL;
-+    c->md_len = SHA256_DIGEST_LENGTH;
-+    return 1;
-+}
-+
-+unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md)
-+{
-+    SHA256_CTX c;
-+    static unsigned char m[SHA224_DIGEST_LENGTH];
-+
-+    if (md == NULL)
-+        md = m;
-+    SHA224_Init(&c);
-+    SHA256_Update(&c, d, n);
-+    SHA256_Final(md, &c);
-+    OPENSSL_cleanse(&c, sizeof(c));
-+    return (md);
-+}
-+
-+unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
-+{
-+    SHA256_CTX c;
-+    static unsigned char m[SHA256_DIGEST_LENGTH];
-+
-+    if (md == NULL)
-+        md = m;
-+    SHA256_Init(&c);
-+    SHA256_Update(&c, d, n);
-+    SHA256_Final(md, &c);
-+    OPENSSL_cleanse(&c, sizeof(c));
-+    return (md);
-+}
-+
-+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len)
-+{
-+    return SHA256_Update(c, data, len);
-+}
-+
-+int SHA224_Final(unsigned char *md, SHA256_CTX *c)
-+{
-+    return SHA256_Final(md, c);
-+}
-+
-+#define DATA_ORDER_IS_BIG_ENDIAN
-+
-+#define HASH_LONG               SHA_LONG
-+#define HASH_CTX                SHA256_CTX
-+#define HASH_CBLOCK             SHA_CBLOCK
-+
-+/*
-+ * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
-+ * default: case below covers for it. It's not clear however if it's
-+ * permitted to truncate to amount of bytes not divisible by 4. I bet not,
-+ * but if it is, then default: case shall be extended. For reference.
-+ * Idea behind separate cases for pre-defined lengths is to let the
-+ * compiler decide if it's appropriate to unroll small loops.
-+ */
-+#define HASH_MAKE_STRING(c,s)   do {    \
-+        unsigned long ll;               \
-+        unsigned int  nn;               \
-+        switch ((c)->md_len)            \
-+        {   case SHA224_DIGEST_LENGTH:  \
-+                for (nn=0;nnh[nn]; (void)HOST_l2c(ll,(s));   }  \
-+                break;                  \
-+            case SHA256_DIGEST_LENGTH:  \
-+                for (nn=0;nnh[nn]; (void)HOST_l2c(ll,(s));   }  \
-+                break;                  \
-+            default:                    \
-+                if ((c)->md_len > SHA256_DIGEST_LENGTH) \
-+                    return 0;                           \
-+                for (nn=0;nn<(c)->md_len/4;nn++)                \
-+                {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \
-+                break;                  \
-+        }                               \
-+        } while (0)
-+
-+#define HASH_UPDATE             SHA256_Update
-+#define HASH_TRANSFORM          SHA256_Transform
-+#define HASH_FINAL              SHA256_Final
-+#define HASH_BLOCK_DATA_ORDER   sha256_block_data_order
-+#ifndef SHA256_ASM
-+static
-+#endif
-+void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
-+
-+#include "internal/md32_common.h"
-+
-+#ifndef SHA256_ASM
-+static const SHA_LONG K256[64] = {
-+    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
-+    0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
-+    0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
-+    0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
-+    0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
-+    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
-+    0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
-+    0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
-+    0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
-+    0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
-+    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
-+    0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
-+    0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
-+    0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
-+    0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
-+    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
-+};
-+
-+/*
-+ * FIPS specification refers to right rotations, while our ROTATE macro
-+ * is left one. This is why you might notice that rotation coefficients
-+ * differ from those observed in FIPS document by 32-N...
-+ */
-+# define Sigma0(x)       (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10))
-+# define Sigma1(x)       (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7))
-+# define sigma0(x)       (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3))
-+# define sigma1(x)       (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10))
-+
-+# define Ch(x,y,z)       (((x) & (y)) ^ ((~(x)) & (z)))
-+# define Maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-+
-+# ifdef OPENSSL_SMALL_FOOTPRINT
-+
-+static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
-+                                    size_t num)
-+{
-+    unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2;
-+    SHA_LONG X[16], l;
-+    int i;
-+    const unsigned char *data = in;
-+
-+    while (num--) {
-+
-+        a = ctx->h[0];
-+        b = ctx->h[1];
-+        c = ctx->h[2];
-+        d = ctx->h[3];
-+        e = ctx->h[4];
-+        f = ctx->h[5];
-+        g = ctx->h[6];
-+        h = ctx->h[7];
-+
-+        for (i = 0; i < 16; i++) {
-+            (void)HOST_c2l(data, l);
-+            T1 = X[i] = l;
-+            T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
-+            T2 = Sigma0(a) + Maj(a, b, c);
-+            h = g;
-+            g = f;
-+            f = e;
-+            e = d + T1;
-+            d = c;
-+            c = b;
-+            b = a;
-+            a = T1 + T2;
-+        }
-+
-+        for (; i < 64; i++) {
-+            s0 = X[(i + 1) & 0x0f];
-+            s0 = sigma0(s0);
-+            s1 = X[(i + 14) & 0x0f];
-+            s1 = sigma1(s1);
-+
-+            T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];
-+            T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
-+            T2 = Sigma0(a) + Maj(a, b, c);
-+            h = g;
-+            g = f;
-+            f = e;
-+            e = d + T1;
-+            d = c;
-+            c = b;
-+            b = a;
-+            a = T1 + T2;
-+        }
-+
-+        ctx->h[0] += a;
-+        ctx->h[1] += b;
-+        ctx->h[2] += c;
-+        ctx->h[3] += d;
-+        ctx->h[4] += e;
-+        ctx->h[5] += f;
-+        ctx->h[6] += g;
-+        ctx->h[7] += h;
-+
-+    }
-+}
-+
-+# else
-+
-+#  define ROUND_00_15(i,a,b,c,d,e,f,g,h)          do {    \
-+        T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];      \
-+        h = Sigma0(a) + Maj(a,b,c);                     \
-+        d += T1;        h += T1;                } while (0)
-+
-+#  define ROUND_16_63(i,a,b,c,d,e,f,g,h,X)        do {    \
-+        s0 = X[(i+1)&0x0f];     s0 = sigma0(s0);        \
-+        s1 = X[(i+14)&0x0f];    s1 = sigma1(s1);        \
-+        T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f];    \
-+        ROUND_00_15(i,a,b,c,d,e,f,g,h);         } while (0)
-+
-+static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
-+                                    size_t num)
-+{
-+    unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1;
-+    SHA_LONG X[16];
-+    int i;
-+    const unsigned char *data = in;
-+    const union {
-+        long one;
-+        char little;
-+    } is_endian = {
-+        1
-+    };
-+
-+    while (num--) {
-+
-+        a = ctx->h[0];
-+        b = ctx->h[1];
-+        c = ctx->h[2];
-+        d = ctx->h[3];
-+        e = ctx->h[4];
-+        f = ctx->h[5];
-+        g = ctx->h[6];
-+        h = ctx->h[7];
-+
-+        if (!is_endian.little && sizeof(SHA_LONG) == 4
-+            && ((size_t)in % 4) == 0) {
-+            const SHA_LONG *W = (const SHA_LONG *)data;
-+
-+            T1 = X[0] = W[0];
-+            ROUND_00_15(0, a, b, c, d, e, f, g, h);
-+            T1 = X[1] = W[1];
-+            ROUND_00_15(1, h, a, b, c, d, e, f, g);
-+            T1 = X[2] = W[2];
-+            ROUND_00_15(2, g, h, a, b, c, d, e, f);
-+            T1 = X[3] = W[3];
-+            ROUND_00_15(3, f, g, h, a, b, c, d, e);
-+            T1 = X[4] = W[4];
-+            ROUND_00_15(4, e, f, g, h, a, b, c, d);
-+            T1 = X[5] = W[5];
-+            ROUND_00_15(5, d, e, f, g, h, a, b, c);
-+            T1 = X[6] = W[6];
-+            ROUND_00_15(6, c, d, e, f, g, h, a, b);
-+            T1 = X[7] = W[7];
-+            ROUND_00_15(7, b, c, d, e, f, g, h, a);
-+            T1 = X[8] = W[8];
-+            ROUND_00_15(8, a, b, c, d, e, f, g, h);
-+            T1 = X[9] = W[9];
-+            ROUND_00_15(9, h, a, b, c, d, e, f, g);
-+            T1 = X[10] = W[10];
-+            ROUND_00_15(10, g, h, a, b, c, d, e, f);
-+            T1 = X[11] = W[11];
-+            ROUND_00_15(11, f, g, h, a, b, c, d, e);
-+            T1 = X[12] = W[12];
-+            ROUND_00_15(12, e, f, g, h, a, b, c, d);
-+            T1 = X[13] = W[13];
-+            ROUND_00_15(13, d, e, f, g, h, a, b, c);
-+            T1 = X[14] = W[14];
-+            ROUND_00_15(14, c, d, e, f, g, h, a, b);
-+            T1 = X[15] = W[15];
-+            ROUND_00_15(15, b, c, d, e, f, g, h, a);
-+
-+            data += SHA256_CBLOCK;
-+        } else {
-+            SHA_LONG l;
-+
-+            (void)HOST_c2l(data, l);
-+            T1 = X[0] = l;
-+            ROUND_00_15(0, a, b, c, d, e, f, g, h);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[1] = l;
-+            ROUND_00_15(1, h, a, b, c, d, e, f, g);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[2] = l;
-+            ROUND_00_15(2, g, h, a, b, c, d, e, f);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[3] = l;
-+            ROUND_00_15(3, f, g, h, a, b, c, d, e);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[4] = l;
-+            ROUND_00_15(4, e, f, g, h, a, b, c, d);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[5] = l;
-+            ROUND_00_15(5, d, e, f, g, h, a, b, c);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[6] = l;
-+            ROUND_00_15(6, c, d, e, f, g, h, a, b);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[7] = l;
-+            ROUND_00_15(7, b, c, d, e, f, g, h, a);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[8] = l;
-+            ROUND_00_15(8, a, b, c, d, e, f, g, h);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[9] = l;
-+            ROUND_00_15(9, h, a, b, c, d, e, f, g);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[10] = l;
-+            ROUND_00_15(10, g, h, a, b, c, d, e, f);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[11] = l;
-+            ROUND_00_15(11, f, g, h, a, b, c, d, e);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[12] = l;
-+            ROUND_00_15(12, e, f, g, h, a, b, c, d);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[13] = l;
-+            ROUND_00_15(13, d, e, f, g, h, a, b, c);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[14] = l;
-+            ROUND_00_15(14, c, d, e, f, g, h, a, b);
-+            (void)HOST_c2l(data, l);
-+            T1 = X[15] = l;
-+            ROUND_00_15(15, b, c, d, e, f, g, h, a);
-+        }
-+
-+        for (i = 16; i < 64; i += 8) {
-+            ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X);
-+            ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X);
-+            ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X);
-+            ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X);
-+            ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X);
-+            ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X);
-+            ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X);
-+            ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X);
-+        }
-+
-+        ctx->h[0] += a;
-+        ctx->h[1] += b;
-+        ctx->h[2] += c;
-+        ctx->h[3] += d;
-+        ctx->h[4] += e;
-+        ctx->h[5] += f;
-+        ctx->h[6] += g;
-+        ctx->h[7] += h;
-+
-+    }
-+}
-+
-+# endif
-+#endif                         /* SHA256_ASM */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha512.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha512.c
-new file mode 100644
-index 0000000..d24d103
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha512.c
-@@ -0,0 +1,678 @@
-+/*
-+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+/*-
-+ * IMPLEMENTATION NOTES.
-+ *
-+ * As you might have noticed 32-bit hash algorithms:
-+ *
-+ * - permit SHA_LONG to be wider than 32-bit
-+ * - optimized versions implement two transform functions: one operating
-+ *   on [aligned] data in host byte order and one - on data in input
-+ *   stream byte order;
-+ * - share common byte-order neutral collector and padding function
-+ *   implementations, ../md32_common.h;
-+ *
-+ * Neither of the above applies to this SHA-512 implementations. Reasons
-+ * [in reverse order] are:
-+ *
-+ * - it's the only 64-bit hash algorithm for the moment of this writing,
-+ *   there is no need for common collector/padding implementation [yet];
-+ * - by supporting only one transform function [which operates on
-+ *   *aligned* data in input stream byte order, big-endian in this case]
-+ *   we minimize burden of maintenance in two ways: a) collector/padding
-+ *   function is simpler; b) only one transform function to stare at;
-+ * - SHA_LONG64 is required to be exactly 64-bit in order to be able to
-+ *   apply a number of optimizations to mitigate potential performance
-+ *   penalties caused by previous design decision;
-+ *
-+ * Caveat lector.
-+ *
-+ * Implementation relies on the fact that "long long" is 64-bit on
-+ * both 32- and 64-bit platforms. If some compiler vendor comes up
-+ * with 128-bit long long, adjustment to sha.h would be required.
-+ * As this implementation relies on 64-bit integer type, it's totally
-+ * inappropriate for platforms which don't support it, most notably
-+ * 16-bit platforms.
-+ *                                      
-+ */
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+#include 
-+
-+#include "internal/cryptlib.h"
-+
-+#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
-+    defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \
-+    defined(__s390__) || defined(__s390x__) || \
-+    defined(__aarch64__) || \
-+    defined(SHA512_ASM)
-+# define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
-+#endif
-+
-+int SHA384_Init(SHA512_CTX *c)
-+{
-+    c->h[0] = U64(0xcbbb9d5dc1059ed8);
-+    c->h[1] = U64(0x629a292a367cd507);
-+    c->h[2] = U64(0x9159015a3070dd17);
-+    c->h[3] = U64(0x152fecd8f70e5939);
-+    c->h[4] = U64(0x67332667ffc00b31);
-+    c->h[5] = U64(0x8eb44a8768581511);
-+    c->h[6] = U64(0xdb0c2e0d64f98fa7);
-+    c->h[7] = U64(0x47b5481dbefa4fa4);
-+
-+    c->Nl = 0;
-+    c->Nh = 0;
-+    c->num = 0;
-+    c->md_len = SHA384_DIGEST_LENGTH;
-+    return 1;
-+}
-+
-+int SHA512_Init(SHA512_CTX *c)
-+{
-+    c->h[0] = U64(0x6a09e667f3bcc908);
-+    c->h[1] = U64(0xbb67ae8584caa73b);
-+    c->h[2] = U64(0x3c6ef372fe94f82b);
-+    c->h[3] = U64(0xa54ff53a5f1d36f1);
-+    c->h[4] = U64(0x510e527fade682d1);
-+    c->h[5] = U64(0x9b05688c2b3e6c1f);
-+    c->h[6] = U64(0x1f83d9abfb41bd6b);
-+    c->h[7] = U64(0x5be0cd19137e2179);
-+
-+    c->Nl = 0;
-+    c->Nh = 0;
-+    c->num = 0;
-+    c->md_len = SHA512_DIGEST_LENGTH;
-+    return 1;
-+}
-+
-+#ifndef SHA512_ASM
-+static
-+#endif
-+void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
-+
-+int SHA512_Final(unsigned char *md, SHA512_CTX *c)
-+{
-+    unsigned char *p = (unsigned char *)c->u.p;
-+    size_t n = c->num;
-+
-+    p[n] = 0x80;                /* There always is a room for one */
-+    n++;
-+    if (n > (sizeof(c->u) - 16)) {
-+        memset(p + n, 0, sizeof(c->u) - n);
-+        n = 0;
-+        sha512_block_data_order(c, p, 1);
-+    }
-+
-+    memset(p + n, 0, sizeof(c->u) - 16 - n);
-+#ifdef  B_ENDIAN
-+    c->u.d[SHA_LBLOCK - 2] = c->Nh;
-+    c->u.d[SHA_LBLOCK - 1] = c->Nl;
-+#else
-+    p[sizeof(c->u) - 1] = (unsigned char)(c->Nl);
-+    p[sizeof(c->u) - 2] = (unsigned char)(c->Nl >> 8);
-+    p[sizeof(c->u) - 3] = (unsigned char)(c->Nl >> 16);
-+    p[sizeof(c->u) - 4] = (unsigned char)(c->Nl >> 24);
-+    p[sizeof(c->u) - 5] = (unsigned char)(c->Nl >> 32);
-+    p[sizeof(c->u) - 6] = (unsigned char)(c->Nl >> 40);
-+    p[sizeof(c->u) - 7] = (unsigned char)(c->Nl >> 48);
-+    p[sizeof(c->u) - 8] = (unsigned char)(c->Nl >> 56);
-+    p[sizeof(c->u) - 9] = (unsigned char)(c->Nh);
-+    p[sizeof(c->u) - 10] = (unsigned char)(c->Nh >> 8);
-+    p[sizeof(c->u) - 11] = (unsigned char)(c->Nh >> 16);
-+    p[sizeof(c->u) - 12] = (unsigned char)(c->Nh >> 24);
-+    p[sizeof(c->u) - 13] = (unsigned char)(c->Nh >> 32);
-+    p[sizeof(c->u) - 14] = (unsigned char)(c->Nh >> 40);
-+    p[sizeof(c->u) - 15] = (unsigned char)(c->Nh >> 48);
-+    p[sizeof(c->u) - 16] = (unsigned char)(c->Nh >> 56);
-+#endif
-+
-+    sha512_block_data_order(c, p, 1);
-+
-+    if (md == 0)
-+        return 0;
-+
-+    switch (c->md_len) {
-+        /* Let compiler decide if it's appropriate to unroll... */
-+    case SHA384_DIGEST_LENGTH:
-+        for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) {
-+            SHA_LONG64 t = c->h[n];
-+
-+            *(md++) = (unsigned char)(t >> 56);
-+            *(md++) = (unsigned char)(t >> 48);
-+            *(md++) = (unsigned char)(t >> 40);
-+            *(md++) = (unsigned char)(t >> 32);
-+            *(md++) = (unsigned char)(t >> 24);
-+            *(md++) = (unsigned char)(t >> 16);
-+            *(md++) = (unsigned char)(t >> 8);
-+            *(md++) = (unsigned char)(t);
-+        }
-+        break;
-+    case SHA512_DIGEST_LENGTH:
-+        for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
-+            SHA_LONG64 t = c->h[n];
-+
-+            *(md++) = (unsigned char)(t >> 56);
-+            *(md++) = (unsigned char)(t >> 48);
-+            *(md++) = (unsigned char)(t >> 40);
-+            *(md++) = (unsigned char)(t >> 32);
-+            *(md++) = (unsigned char)(t >> 24);
-+            *(md++) = (unsigned char)(t >> 16);
-+            *(md++) = (unsigned char)(t >> 8);
-+            *(md++) = (unsigned char)(t);
-+        }
-+        break;
-+        /* ... as well as make sure md_len is not abused. */
-+    default:
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+int SHA384_Final(unsigned char *md, SHA512_CTX *c)
-+{
-+    return SHA512_Final(md, c);
-+}
-+
-+int SHA512_Update(SHA512_CTX *c, const void *_data, size_t len)
-+{
-+    SHA_LONG64 l;
-+    unsigned char *p = c->u.p;
-+    const unsigned char *data = (const unsigned char *)_data;
-+
-+    if (len == 0)
-+        return 1;
-+
-+    l = (c->Nl + (((SHA_LONG64) len) << 3)) & U64(0xffffffffffffffff);
-+    if (l < c->Nl)
-+        c->Nh++;
-+    if (sizeof(len) >= 8)
-+        c->Nh += (((SHA_LONG64) len) >> 61);
-+    c->Nl = l;
-+
-+    if (c->num != 0) {
-+        size_t n = sizeof(c->u) - c->num;
-+
-+        if (len < n) {
-+            memcpy(p + c->num, data, len), c->num += (unsigned int)len;
-+            return 1;
-+        } else {
-+            memcpy(p + c->num, data, n), c->num = 0;
-+            len -= n, data += n;
-+            sha512_block_data_order(c, p, 1);
-+        }
-+    }
-+
-+    if (len >= sizeof(c->u)) {
-+#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
-+        if ((size_t)data % sizeof(c->u.d[0]) != 0)
-+            while (len >= sizeof(c->u))
-+                memcpy(p, data, sizeof(c->u)),
-+                    sha512_block_data_order(c, p, 1),
-+                    len -= sizeof(c->u), data += sizeof(c->u);
-+        else
-+#endif
-+            sha512_block_data_order(c, data, len / sizeof(c->u)),
-+                data += len, len %= sizeof(c->u), data -= len;
-+    }
-+
-+    if (len != 0)
-+        memcpy(p, data, len), c->num = (int)len;
-+
-+    return 1;
-+}
-+
-+int SHA384_Update(SHA512_CTX *c, const void *data, size_t len)
-+{
-+    return SHA512_Update(c, data, len);
-+}
-+
-+void SHA512_Transform(SHA512_CTX *c, const unsigned char *data)
-+{
-+#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
-+    if ((size_t)data % sizeof(c->u.d[0]) != 0)
-+        memcpy(c->u.p, data, sizeof(c->u.p)), data = c->u.p;
-+#endif
-+    sha512_block_data_order(c, data, 1);
-+}
-+
-+unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md)
-+{
-+    SHA512_CTX c;
-+    static unsigned char m[SHA384_DIGEST_LENGTH];
-+
-+    if (md == NULL)
-+        md = m;
-+    SHA384_Init(&c);
-+    SHA512_Update(&c, d, n);
-+    SHA512_Final(md, &c);
-+    OPENSSL_cleanse(&c, sizeof(c));
-+    return (md);
-+}
-+
-+unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md)
-+{
-+    SHA512_CTX c;
-+    static unsigned char m[SHA512_DIGEST_LENGTH];
-+
-+    if (md == NULL)
-+        md = m;
-+    SHA512_Init(&c);
-+    SHA512_Update(&c, d, n);
-+    SHA512_Final(md, &c);
-+    OPENSSL_cleanse(&c, sizeof(c));
-+    return (md);
-+}
-+
-+#ifndef SHA512_ASM
-+static const SHA_LONG64 K512[80] = {
-+    U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
-+    U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
-+    U64(0x3956c25bf348b538), U64(0x59f111f1b605d019),
-+    U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118),
-+    U64(0xd807aa98a3030242), U64(0x12835b0145706fbe),
-+    U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2),
-+    U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1),
-+    U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694),
-+    U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3),
-+    U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65),
-+    U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483),
-+    U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5),
-+    U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210),
-+    U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4),
-+    U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725),
-+    U64(0x06ca6351e003826f), U64(0x142929670a0e6e70),
-+    U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926),
-+    U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df),
-+    U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8),
-+    U64(0x81c2c92e47edaee6), U64(0x92722c851482353b),
-+    U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001),
-+    U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30),
-+    U64(0xd192e819d6ef5218), U64(0xd69906245565a910),
-+    U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8),
-+    U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53),
-+    U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8),
-+    U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb),
-+    U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3),
-+    U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60),
-+    U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec),
-+    U64(0x90befffa23631e28), U64(0xa4506cebde82bde9),
-+    U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b),
-+    U64(0xca273eceea26619c), U64(0xd186b8c721c0c207),
-+    U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178),
-+    U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6),
-+    U64(0x113f9804bef90dae), U64(0x1b710b35131c471b),
-+    U64(0x28db77f523047d84), U64(0x32caab7b40c72493),
-+    U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c),
-+    U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a),
-+    U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817)
-+};
-+
-+# ifndef PEDANTIC
-+#  if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
-+#   if defined(__x86_64) || defined(__x86_64__)
-+#    define ROTR(a,n)    ({ SHA_LONG64 ret;              \
-+                                asm ("rorq %1,%0"       \
-+                                : "=r"(ret)             \
-+                                : "J"(n),"0"(a)         \
-+                                : "cc"); ret;           })
-+#    if !defined(B_ENDIAN)
-+#     define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x)));  \
-+                                asm ("bswapq    %0"             \
-+                                : "=r"(ret)                     \
-+                                : "0"(ret)); ret;               })
-+#    endif
-+#   elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN)
-+#    if defined(I386_ONLY)
-+#     define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
-+                         unsigned int hi=p[0],lo=p[1];          \
-+                                asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\
-+                                    "roll $16,%%eax; roll $16,%%edx; "\
-+                                    "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \
-+                                : "=a"(lo),"=d"(hi)             \
-+                                : "0"(lo),"1"(hi) : "cc");      \
-+                                ((SHA_LONG64)hi)<<32|lo;        })
-+#    else
-+#     define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
-+                         unsigned int hi=p[0],lo=p[1];          \
-+                                asm ("bswapl %0; bswapl %1;"    \
-+                                : "=r"(lo),"=r"(hi)             \
-+                                : "0"(lo),"1"(hi));             \
-+                                ((SHA_LONG64)hi)<<32|lo;        })
-+#    endif
-+#   elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
-+#    define ROTR(a,n)    ({ SHA_LONG64 ret;              \
-+                                asm ("rotrdi %0,%1,%2"  \
-+                                : "=r"(ret)             \
-+                                : "r"(a),"K"(n)); ret;  })
-+#   elif defined(__aarch64__)
-+#    define ROTR(a,n)    ({ SHA_LONG64 ret;              \
-+                                asm ("ror %0,%1,%2"     \
-+                                : "=r"(ret)             \
-+                                : "r"(a),"I"(n)); ret;  })
-+#    if  defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
-+        __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
-+#     define PULL64(x)   ({ SHA_LONG64 ret;                      \
-+                                asm ("rev       %0,%1"          \
-+                                : "=r"(ret)                     \
-+                                : "r"(*((const SHA_LONG64 *)(&(x))))); ret;             })
-+#    endif
-+#   endif
-+#  elif defined(_MSC_VER)
-+#   if defined(_WIN64)         /* applies to both IA-64 and AMD64 */
-+#    pragma intrinsic(_rotr64)
-+#    define ROTR(a,n)    _rotr64((a),n)
-+#   endif
-+#   if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
-+#    if defined(I386_ONLY)
-+static SHA_LONG64 __fastcall __pull64be(const void *x)
-+{
-+    _asm mov edx,[ecx + 0]
-+    _asm mov eax,[ecx + 4]
-+_asm xchg dh, dl
-+        _asm xchg ah, al
-+        _asm rol edx, 16 _asm rol eax, 16 _asm xchg dh, dl _asm xchg ah, al}
-+#    else
-+static SHA_LONG64 __fastcall __pull64be(const void *x)
-+{
-+    _asm mov edx,[ecx + 0]
-+    _asm mov eax,[ecx + 4]
-+_asm bswap edx _asm bswap eax}
-+#    endif
-+#    define PULL64(x) __pull64be(&(x))
-+#    if _MSC_VER<=1200
-+#     pragma inline_depth(0)
-+#    endif
-+#   endif
-+#  endif
-+# endif
-+# ifndef PULL64
-+#  define B(x,j)    (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8))
-+#  define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7))
-+# endif
-+# ifndef ROTR
-+#  define ROTR(x,s)       (((x)>>s) | (x)<<(64-s))
-+# endif
-+# define Sigma0(x)       (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
-+# define Sigma1(x)       (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
-+# define sigma0(x)       (ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
-+# define sigma1(x)       (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
-+# define Ch(x,y,z)       (((x) & (y)) ^ ((~(x)) & (z)))
-+# define Maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-+# if defined(__i386) || defined(__i386__) || defined(_M_IX86)
-+/*
-+ * This code should give better results on 32-bit CPU with less than
-+ * ~24 registers, both size and performance wise...
-+ */ static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
-+                                        size_t num)
-+{
-+    const SHA_LONG64 *W = in;
-+    SHA_LONG64 A, E, T;
-+    SHA_LONG64 X[9 + 80], *F;
-+    int i;
-+
-+    while (num--) {
-+
-+        F = X + 80;
-+        A = ctx->h[0];
-+        F[1] = ctx->h[1];
-+        F[2] = ctx->h[2];
-+        F[3] = ctx->h[3];
-+        E = ctx->h[4];
-+        F[5] = ctx->h[5];
-+        F[6] = ctx->h[6];
-+        F[7] = ctx->h[7];
-+
-+        for (i = 0; i < 16; i++, F--) {
-+#  ifdef B_ENDIAN
-+            T = W[i];
-+#  else
-+            T = PULL64(W[i]);
-+#  endif
-+            F[0] = A;
-+            F[4] = E;
-+            F[8] = T;
-+            T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i];
-+            E = F[3] + T;
-+            A = T + Sigma0(A) + Maj(A, F[1], F[2]);
-+        }
-+
-+        for (; i < 80; i++, F--) {
-+            T = sigma0(F[8 + 16 - 1]);
-+            T += sigma1(F[8 + 16 - 14]);
-+            T += F[8 + 16] + F[8 + 16 - 9];
-+
-+            F[0] = A;
-+            F[4] = E;
-+            F[8] = T;
-+            T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i];
-+            E = F[3] + T;
-+            A = T + Sigma0(A) + Maj(A, F[1], F[2]);
-+        }
-+
-+        ctx->h[0] += A;
-+        ctx->h[1] += F[1];
-+        ctx->h[2] += F[2];
-+        ctx->h[3] += F[3];
-+        ctx->h[4] += E;
-+        ctx->h[5] += F[5];
-+        ctx->h[6] += F[6];
-+        ctx->h[7] += F[7];
-+
-+        W += SHA_LBLOCK;
-+    }
-+}
-+
-+# elif defined(OPENSSL_SMALL_FOOTPRINT)
-+static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
-+                                    size_t num)
-+{
-+    const SHA_LONG64 *W = in;
-+    SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1, T2;
-+    SHA_LONG64 X[16];
-+    int i;
-+
-+    while (num--) {
-+
-+        a = ctx->h[0];
-+        b = ctx->h[1];
-+        c = ctx->h[2];
-+        d = ctx->h[3];
-+        e = ctx->h[4];
-+        f = ctx->h[5];
-+        g = ctx->h[6];
-+        h = ctx->h[7];
-+
-+        for (i = 0; i < 16; i++) {
-+#  ifdef B_ENDIAN
-+            T1 = X[i] = W[i];
-+#  else
-+            T1 = X[i] = PULL64(W[i]);
-+#  endif
-+            T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
-+            T2 = Sigma0(a) + Maj(a, b, c);
-+            h = g;
-+            g = f;
-+            f = e;
-+            e = d + T1;
-+            d = c;
-+            c = b;
-+            b = a;
-+            a = T1 + T2;
-+        }
-+
-+        for (; i < 80; i++) {
-+            s0 = X[(i + 1) & 0x0f];
-+            s0 = sigma0(s0);
-+            s1 = X[(i + 14) & 0x0f];
-+            s1 = sigma1(s1);
-+
-+            T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];
-+            T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
-+            T2 = Sigma0(a) + Maj(a, b, c);
-+            h = g;
-+            g = f;
-+            f = e;
-+            e = d + T1;
-+            d = c;
-+            c = b;
-+            b = a;
-+            a = T1 + T2;
-+        }
-+
-+        ctx->h[0] += a;
-+        ctx->h[1] += b;
-+        ctx->h[2] += c;
-+        ctx->h[3] += d;
-+        ctx->h[4] += e;
-+        ctx->h[5] += f;
-+        ctx->h[6] += g;
-+        ctx->h[7] += h;
-+
-+        W += SHA_LBLOCK;
-+    }
-+}
-+
-+# else
-+#  define ROUND_00_15(i,a,b,c,d,e,f,g,h)          do {    \
-+        T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];      \
-+        h = Sigma0(a) + Maj(a,b,c);                     \
-+        d += T1;        h += T1;                } while (0)
-+#  define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X)      do {    \
-+        s0 = X[(j+1)&0x0f];     s0 = sigma0(s0);        \
-+        s1 = X[(j+14)&0x0f];    s1 = sigma1(s1);        \
-+        T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f];    \
-+        ROUND_00_15(i+j,a,b,c,d,e,f,g,h);               } while (0)
-+static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
-+                                    size_t num)
-+{
-+    const SHA_LONG64 *W = in;
-+    SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1;
-+    SHA_LONG64 X[16];
-+    int i;
-+
-+    while (num--) {
-+
-+        a = ctx->h[0];
-+        b = ctx->h[1];
-+        c = ctx->h[2];
-+        d = ctx->h[3];
-+        e = ctx->h[4];
-+        f = ctx->h[5];
-+        g = ctx->h[6];
-+        h = ctx->h[7];
-+
-+#  ifdef B_ENDIAN
-+        T1 = X[0] = W[0];
-+        ROUND_00_15(0, a, b, c, d, e, f, g, h);
-+        T1 = X[1] = W[1];
-+        ROUND_00_15(1, h, a, b, c, d, e, f, g);
-+        T1 = X[2] = W[2];
-+        ROUND_00_15(2, g, h, a, b, c, d, e, f);
-+        T1 = X[3] = W[3];
-+        ROUND_00_15(3, f, g, h, a, b, c, d, e);
-+        T1 = X[4] = W[4];
-+        ROUND_00_15(4, e, f, g, h, a, b, c, d);
-+        T1 = X[5] = W[5];
-+        ROUND_00_15(5, d, e, f, g, h, a, b, c);
-+        T1 = X[6] = W[6];
-+        ROUND_00_15(6, c, d, e, f, g, h, a, b);
-+        T1 = X[7] = W[7];
-+        ROUND_00_15(7, b, c, d, e, f, g, h, a);
-+        T1 = X[8] = W[8];
-+        ROUND_00_15(8, a, b, c, d, e, f, g, h);
-+        T1 = X[9] = W[9];
-+        ROUND_00_15(9, h, a, b, c, d, e, f, g);
-+        T1 = X[10] = W[10];
-+        ROUND_00_15(10, g, h, a, b, c, d, e, f);
-+        T1 = X[11] = W[11];
-+        ROUND_00_15(11, f, g, h, a, b, c, d, e);
-+        T1 = X[12] = W[12];
-+        ROUND_00_15(12, e, f, g, h, a, b, c, d);
-+        T1 = X[13] = W[13];
-+        ROUND_00_15(13, d, e, f, g, h, a, b, c);
-+        T1 = X[14] = W[14];
-+        ROUND_00_15(14, c, d, e, f, g, h, a, b);
-+        T1 = X[15] = W[15];
-+        ROUND_00_15(15, b, c, d, e, f, g, h, a);
-+#  else
-+        T1 = X[0] = PULL64(W[0]);
-+        ROUND_00_15(0, a, b, c, d, e, f, g, h);
-+        T1 = X[1] = PULL64(W[1]);
-+        ROUND_00_15(1, h, a, b, c, d, e, f, g);
-+        T1 = X[2] = PULL64(W[2]);
-+        ROUND_00_15(2, g, h, a, b, c, d, e, f);
-+        T1 = X[3] = PULL64(W[3]);
-+        ROUND_00_15(3, f, g, h, a, b, c, d, e);
-+        T1 = X[4] = PULL64(W[4]);
-+        ROUND_00_15(4, e, f, g, h, a, b, c, d);
-+        T1 = X[5] = PULL64(W[5]);
-+        ROUND_00_15(5, d, e, f, g, h, a, b, c);
-+        T1 = X[6] = PULL64(W[6]);
-+        ROUND_00_15(6, c, d, e, f, g, h, a, b);
-+        T1 = X[7] = PULL64(W[7]);
-+        ROUND_00_15(7, b, c, d, e, f, g, h, a);
-+        T1 = X[8] = PULL64(W[8]);
-+        ROUND_00_15(8, a, b, c, d, e, f, g, h);
-+        T1 = X[9] = PULL64(W[9]);
-+        ROUND_00_15(9, h, a, b, c, d, e, f, g);
-+        T1 = X[10] = PULL64(W[10]);
-+        ROUND_00_15(10, g, h, a, b, c, d, e, f);
-+        T1 = X[11] = PULL64(W[11]);
-+        ROUND_00_15(11, f, g, h, a, b, c, d, e);
-+        T1 = X[12] = PULL64(W[12]);
-+        ROUND_00_15(12, e, f, g, h, a, b, c, d);
-+        T1 = X[13] = PULL64(W[13]);
-+        ROUND_00_15(13, d, e, f, g, h, a, b, c);
-+        T1 = X[14] = PULL64(W[14]);
-+        ROUND_00_15(14, c, d, e, f, g, h, a, b);
-+        T1 = X[15] = PULL64(W[15]);
-+        ROUND_00_15(15, b, c, d, e, f, g, h, a);
-+#  endif
-+
-+        for (i = 16; i < 80; i += 16) {
-+            ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X);
-+            ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X);
-+            ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X);
-+            ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X);
-+            ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X);
-+            ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X);
-+            ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X);
-+            ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X);
-+            ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X);
-+            ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X);
-+            ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X);
-+            ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X);
-+            ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X);
-+            ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X);
-+            ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X);
-+            ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X);
-+        }
-+
-+        ctx->h[0] += a;
-+        ctx->h[1] += b;
-+        ctx->h[2] += c;
-+        ctx->h[3] += d;
-+        ctx->h[4] += e;
-+        ctx->h[5] += f;
-+        ctx->h[6] += g;
-+        ctx->h[7] += h;
-+
-+        W += SHA_LBLOCK;
-+    }
-+}
-+
-+# endif
-+
-+#endif                         /* SHA512_ASM */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha_locl.h
-new file mode 100644
-index 0000000..918278a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sha/sha_locl.h
-@@ -0,0 +1,424 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+#include 
-+#include 
-+
-+#define DATA_ORDER_IS_BIG_ENDIAN
-+
-+#define HASH_LONG               SHA_LONG
-+#define HASH_CTX                SHA_CTX
-+#define HASH_CBLOCK             SHA_CBLOCK
-+#define HASH_MAKE_STRING(c,s)   do {    \
-+        unsigned long ll;               \
-+        ll=(c)->h0; (void)HOST_l2c(ll,(s));     \
-+        ll=(c)->h1; (void)HOST_l2c(ll,(s));     \
-+        ll=(c)->h2; (void)HOST_l2c(ll,(s));     \
-+        ll=(c)->h3; (void)HOST_l2c(ll,(s));     \
-+        ll=(c)->h4; (void)HOST_l2c(ll,(s));     \
-+        } while (0)
-+
-+#define HASH_UPDATE                     SHA1_Update
-+#define HASH_TRANSFORM                  SHA1_Transform
-+#define HASH_FINAL                      SHA1_Final
-+#define HASH_INIT                       SHA1_Init
-+#define HASH_BLOCK_DATA_ORDER           sha1_block_data_order
-+#define Xupdate(a,ix,ia,ib,ic,id)       ( (a)=(ia^ib^ic^id),    \
-+                                          ix=(a)=ROTATE((a),1)  \
-+                                        )
-+
-+#ifndef SHA1_ASM
-+static void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
-+#else
-+void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
-+#endif
-+
-+#include "internal/md32_common.h"
-+
-+#define INIT_DATA_h0 0x67452301UL
-+#define INIT_DATA_h1 0xefcdab89UL
-+#define INIT_DATA_h2 0x98badcfeUL
-+#define INIT_DATA_h3 0x10325476UL
-+#define INIT_DATA_h4 0xc3d2e1f0UL
-+
-+int HASH_INIT(SHA_CTX *c)
-+{
-+    memset(c, 0, sizeof(*c));
-+    c->h0 = INIT_DATA_h0;
-+    c->h1 = INIT_DATA_h1;
-+    c->h2 = INIT_DATA_h2;
-+    c->h3 = INIT_DATA_h3;
-+    c->h4 = INIT_DATA_h4;
-+    return 1;
-+}
-+
-+#define K_00_19 0x5a827999UL
-+#define K_20_39 0x6ed9eba1UL
-+#define K_40_59 0x8f1bbcdcUL
-+#define K_60_79 0xca62c1d6UL
-+
-+/*
-+ * As pointed out by Wei Dai , F() below can be simplified
-+ * to the code in F_00_19.  Wei attributes these optimisations to Peter
-+ * Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define
-+ * F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another
-+ * tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a
-+ */
-+#define F_00_19(b,c,d)  ((((c) ^ (d)) & (b)) ^ (d))
-+#define F_20_39(b,c,d)  ((b) ^ (c) ^ (d))
-+#define F_40_59(b,c,d)  (((b) & (c)) | (((b)|(c)) & (d)))
-+#define F_60_79(b,c,d)  F_20_39(b,c,d)
-+
-+#ifndef OPENSSL_SMALL_FOOTPRINT
-+
-+# define BODY_00_15(i,a,b,c,d,e,f,xi) \
-+        (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
-+        (b)=ROTATE((b),30);
-+
-+# define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
-+        Xupdate(f,xi,xa,xb,xc,xd); \
-+        (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
-+        (b)=ROTATE((b),30);
-+
-+# define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
-+        Xupdate(f,xi,xa,xb,xc,xd); \
-+        (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
-+        (b)=ROTATE((b),30);
-+
-+# define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
-+        Xupdate(f,xa,xa,xb,xc,xd); \
-+        (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
-+        (b)=ROTATE((b),30);
-+
-+# define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
-+        Xupdate(f,xa,xa,xb,xc,xd); \
-+        (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
-+        (b)=ROTATE((b),30);
-+
-+# define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
-+        Xupdate(f,xa,xa,xb,xc,xd); \
-+        (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
-+        (b)=ROTATE((b),30);
-+
-+# ifdef X
-+#  undef X
-+# endif
-+# ifndef MD32_XARRAY
-+  /*
-+   * Originally X was an array. As it's automatic it's natural
-+   * to expect RISC compiler to accommodate at least part of it in
-+   * the register bank, isn't it? Unfortunately not all compilers
-+   * "find" this expectation reasonable:-( On order to make such
-+   * compilers generate better code I replace X[] with a bunch of
-+   * X0, X1, etc. See the function body below...
-+   *                                    
-+   */
-+#  define X(i)   XX##i
-+# else
-+  /*
-+   * However! Some compilers (most notably HP C) get overwhelmed by
-+   * that many local variables so that we have to have the way to
-+   * fall down to the original behavior.
-+   */
-+#  define X(i)   XX[i]
-+# endif
-+
-+# if !defined(SHA1_ASM)
-+static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num)
-+{
-+    const unsigned char *data = p;
-+    register unsigned MD32_REG_T A, B, C, D, E, T, l;
-+#  ifndef MD32_XARRAY
-+    unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
-+        XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
-+#  else
-+    SHA_LONG XX[16];
-+#  endif
-+
-+    A = c->h0;
-+    B = c->h1;
-+    C = c->h2;
-+    D = c->h3;
-+    E = c->h4;
-+
-+    for (;;) {
-+        const union {
-+            long one;
-+            char little;
-+        } is_endian = {
-+            1
-+        };
-+
-+        if (!is_endian.little && sizeof(SHA_LONG) == 4
-+            && ((size_t)p % 4) == 0) {
-+            const SHA_LONG *W = (const SHA_LONG *)data;
-+
-+            X(0) = W[0];
-+            X(1) = W[1];
-+            BODY_00_15(0, A, B, C, D, E, T, X(0));
-+            X(2) = W[2];
-+            BODY_00_15(1, T, A, B, C, D, E, X(1));
-+            X(3) = W[3];
-+            BODY_00_15(2, E, T, A, B, C, D, X(2));
-+            X(4) = W[4];
-+            BODY_00_15(3, D, E, T, A, B, C, X(3));
-+            X(5) = W[5];
-+            BODY_00_15(4, C, D, E, T, A, B, X(4));
-+            X(6) = W[6];
-+            BODY_00_15(5, B, C, D, E, T, A, X(5));
-+            X(7) = W[7];
-+            BODY_00_15(6, A, B, C, D, E, T, X(6));
-+            X(8) = W[8];
-+            BODY_00_15(7, T, A, B, C, D, E, X(7));
-+            X(9) = W[9];
-+            BODY_00_15(8, E, T, A, B, C, D, X(8));
-+            X(10) = W[10];
-+            BODY_00_15(9, D, E, T, A, B, C, X(9));
-+            X(11) = W[11];
-+            BODY_00_15(10, C, D, E, T, A, B, X(10));
-+            X(12) = W[12];
-+            BODY_00_15(11, B, C, D, E, T, A, X(11));
-+            X(13) = W[13];
-+            BODY_00_15(12, A, B, C, D, E, T, X(12));
-+            X(14) = W[14];
-+            BODY_00_15(13, T, A, B, C, D, E, X(13));
-+            X(15) = W[15];
-+            BODY_00_15(14, E, T, A, B, C, D, X(14));
-+            BODY_00_15(15, D, E, T, A, B, C, X(15));
-+
-+            data += SHA_CBLOCK;
-+        } else {
-+            (void)HOST_c2l(data, l);
-+            X(0) = l;
-+            (void)HOST_c2l(data, l);
-+            X(1) = l;
-+            BODY_00_15(0, A, B, C, D, E, T, X(0));
-+            (void)HOST_c2l(data, l);
-+            X(2) = l;
-+            BODY_00_15(1, T, A, B, C, D, E, X(1));
-+            (void)HOST_c2l(data, l);
-+            X(3) = l;
-+            BODY_00_15(2, E, T, A, B, C, D, X(2));
-+            (void)HOST_c2l(data, l);
-+            X(4) = l;
-+            BODY_00_15(3, D, E, T, A, B, C, X(3));
-+            (void)HOST_c2l(data, l);
-+            X(5) = l;
-+            BODY_00_15(4, C, D, E, T, A, B, X(4));
-+            (void)HOST_c2l(data, l);
-+            X(6) = l;
-+            BODY_00_15(5, B, C, D, E, T, A, X(5));
-+            (void)HOST_c2l(data, l);
-+            X(7) = l;
-+            BODY_00_15(6, A, B, C, D, E, T, X(6));
-+            (void)HOST_c2l(data, l);
-+            X(8) = l;
-+            BODY_00_15(7, T, A, B, C, D, E, X(7));
-+            (void)HOST_c2l(data, l);
-+            X(9) = l;
-+            BODY_00_15(8, E, T, A, B, C, D, X(8));
-+            (void)HOST_c2l(data, l);
-+            X(10) = l;
-+            BODY_00_15(9, D, E, T, A, B, C, X(9));
-+            (void)HOST_c2l(data, l);
-+            X(11) = l;
-+            BODY_00_15(10, C, D, E, T, A, B, X(10));
-+            (void)HOST_c2l(data, l);
-+            X(12) = l;
-+            BODY_00_15(11, B, C, D, E, T, A, X(11));
-+            (void)HOST_c2l(data, l);
-+            X(13) = l;
-+            BODY_00_15(12, A, B, C, D, E, T, X(12));
-+            (void)HOST_c2l(data, l);
-+            X(14) = l;
-+            BODY_00_15(13, T, A, B, C, D, E, X(13));
-+            (void)HOST_c2l(data, l);
-+            X(15) = l;
-+            BODY_00_15(14, E, T, A, B, C, D, X(14));
-+            BODY_00_15(15, D, E, T, A, B, C, X(15));
-+        }
-+
-+        BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13));
-+        BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14));
-+        BODY_16_19(18, A, B, C, D, E, T, X(2), X(2), X(4), X(10), X(15));
-+        BODY_16_19(19, T, A, B, C, D, E, X(3), X(3), X(5), X(11), X(0));
-+
-+        BODY_20_31(20, E, T, A, B, C, D, X(4), X(4), X(6), X(12), X(1));
-+        BODY_20_31(21, D, E, T, A, B, C, X(5), X(5), X(7), X(13), X(2));
-+        BODY_20_31(22, C, D, E, T, A, B, X(6), X(6), X(8), X(14), X(3));
-+        BODY_20_31(23, B, C, D, E, T, A, X(7), X(7), X(9), X(15), X(4));
-+        BODY_20_31(24, A, B, C, D, E, T, X(8), X(8), X(10), X(0), X(5));
-+        BODY_20_31(25, T, A, B, C, D, E, X(9), X(9), X(11), X(1), X(6));
-+        BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X(2), X(7));
-+        BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X(3), X(8));
-+        BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X(4), X(9));
-+        BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X(5), X(10));
-+        BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X(0), X(6), X(11));
-+        BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X(1), X(7), X(12));
-+
-+        BODY_32_39(32, E, T, A, B, C, D, X(0), X(2), X(8), X(13));
-+        BODY_32_39(33, D, E, T, A, B, C, X(1), X(3), X(9), X(14));
-+        BODY_32_39(34, C, D, E, T, A, B, X(2), X(4), X(10), X(15));
-+        BODY_32_39(35, B, C, D, E, T, A, X(3), X(5), X(11), X(0));
-+        BODY_32_39(36, A, B, C, D, E, T, X(4), X(6), X(12), X(1));
-+        BODY_32_39(37, T, A, B, C, D, E, X(5), X(7), X(13), X(2));
-+        BODY_32_39(38, E, T, A, B, C, D, X(6), X(8), X(14), X(3));
-+        BODY_32_39(39, D, E, T, A, B, C, X(7), X(9), X(15), X(4));
-+
-+        BODY_40_59(40, C, D, E, T, A, B, X(8), X(10), X(0), X(5));
-+        BODY_40_59(41, B, C, D, E, T, A, X(9), X(11), X(1), X(6));
-+        BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X(2), X(7));
-+        BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X(3), X(8));
-+        BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X(4), X(9));
-+        BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X(5), X(10));
-+        BODY_40_59(46, C, D, E, T, A, B, X(14), X(0), X(6), X(11));
-+        BODY_40_59(47, B, C, D, E, T, A, X(15), X(1), X(7), X(12));
-+        BODY_40_59(48, A, B, C, D, E, T, X(0), X(2), X(8), X(13));
-+        BODY_40_59(49, T, A, B, C, D, E, X(1), X(3), X(9), X(14));
-+        BODY_40_59(50, E, T, A, B, C, D, X(2), X(4), X(10), X(15));
-+        BODY_40_59(51, D, E, T, A, B, C, X(3), X(5), X(11), X(0));
-+        BODY_40_59(52, C, D, E, T, A, B, X(4), X(6), X(12), X(1));
-+        BODY_40_59(53, B, C, D, E, T, A, X(5), X(7), X(13), X(2));
-+        BODY_40_59(54, A, B, C, D, E, T, X(6), X(8), X(14), X(3));
-+        BODY_40_59(55, T, A, B, C, D, E, X(7), X(9), X(15), X(4));
-+        BODY_40_59(56, E, T, A, B, C, D, X(8), X(10), X(0), X(5));
-+        BODY_40_59(57, D, E, T, A, B, C, X(9), X(11), X(1), X(6));
-+        BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X(2), X(7));
-+        BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X(3), X(8));
-+
-+        BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X(4), X(9));
-+        BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X(5), X(10));
-+        BODY_60_79(62, E, T, A, B, C, D, X(14), X(0), X(6), X(11));
-+        BODY_60_79(63, D, E, T, A, B, C, X(15), X(1), X(7), X(12));
-+        BODY_60_79(64, C, D, E, T, A, B, X(0), X(2), X(8), X(13));
-+        BODY_60_79(65, B, C, D, E, T, A, X(1), X(3), X(9), X(14));
-+        BODY_60_79(66, A, B, C, D, E, T, X(2), X(4), X(10), X(15));
-+        BODY_60_79(67, T, A, B, C, D, E, X(3), X(5), X(11), X(0));
-+        BODY_60_79(68, E, T, A, B, C, D, X(4), X(6), X(12), X(1));
-+        BODY_60_79(69, D, E, T, A, B, C, X(5), X(7), X(13), X(2));
-+        BODY_60_79(70, C, D, E, T, A, B, X(6), X(8), X(14), X(3));
-+        BODY_60_79(71, B, C, D, E, T, A, X(7), X(9), X(15), X(4));
-+        BODY_60_79(72, A, B, C, D, E, T, X(8), X(10), X(0), X(5));
-+        BODY_60_79(73, T, A, B, C, D, E, X(9), X(11), X(1), X(6));
-+        BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X(2), X(7));
-+        BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X(3), X(8));
-+        BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X(4), X(9));
-+        BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X(5), X(10));
-+        BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11));
-+        BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12));
-+
-+        c->h0 = (c->h0 + E) & 0xffffffffL;
-+        c->h1 = (c->h1 + T) & 0xffffffffL;
-+        c->h2 = (c->h2 + A) & 0xffffffffL;
-+        c->h3 = (c->h3 + B) & 0xffffffffL;
-+        c->h4 = (c->h4 + C) & 0xffffffffL;
-+
-+        if (--num == 0)
-+            break;
-+
-+        A = c->h0;
-+        B = c->h1;
-+        C = c->h2;
-+        D = c->h3;
-+        E = c->h4;
-+
-+    }
-+}
-+# endif
-+
-+#else                           /* OPENSSL_SMALL_FOOTPRINT */
-+
-+# define BODY_00_15(xi)           do {   \
-+        T=E+K_00_19+F_00_19(B,C,D);     \
-+        E=D, D=C, C=ROTATE(B,30), B=A;  \
-+        A=ROTATE(A,5)+T+xi;         } while(0)
-+
-+# define BODY_16_19(xa,xb,xc,xd)  do {   \
-+        Xupdate(T,xa,xa,xb,xc,xd);      \
-+        T+=E+K_00_19+F_00_19(B,C,D);    \
-+        E=D, D=C, C=ROTATE(B,30), B=A;  \
-+        A=ROTATE(A,5)+T;            } while(0)
-+
-+# define BODY_20_39(xa,xb,xc,xd)  do {   \
-+        Xupdate(T,xa,xa,xb,xc,xd);      \
-+        T+=E+K_20_39+F_20_39(B,C,D);    \
-+        E=D, D=C, C=ROTATE(B,30), B=A;  \
-+        A=ROTATE(A,5)+T;            } while(0)
-+
-+# define BODY_40_59(xa,xb,xc,xd)  do {   \
-+        Xupdate(T,xa,xa,xb,xc,xd);      \
-+        T+=E+K_40_59+F_40_59(B,C,D);    \
-+        E=D, D=C, C=ROTATE(B,30), B=A;  \
-+        A=ROTATE(A,5)+T;            } while(0)
-+
-+# define BODY_60_79(xa,xb,xc,xd)  do {   \
-+        Xupdate(T,xa,xa,xb,xc,xd);      \
-+        T=E+K_60_79+F_60_79(B,C,D);     \
-+        E=D, D=C, C=ROTATE(B,30), B=A;  \
-+        A=ROTATE(A,5)+T+xa;         } while(0)
-+
-+# if !defined(SHA1_ASM)
-+static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num)
-+{
-+    const unsigned char *data = p;
-+    register unsigned MD32_REG_T A, B, C, D, E, T, l;
-+    int i;
-+    SHA_LONG X[16];
-+
-+    A = c->h0;
-+    B = c->h1;
-+    C = c->h2;
-+    D = c->h3;
-+    E = c->h4;
-+
-+    for (;;) {
-+        for (i = 0; i < 16; i++) {
-+            (void)HOST_c2l(data, l);
-+            X[i] = l;
-+            BODY_00_15(X[i]);
-+        }
-+        for (i = 0; i < 4; i++) {
-+            BODY_16_19(X[i], X[i + 2], X[i + 8], X[(i + 13) & 15]);
-+        }
-+        for (; i < 24; i++) {
-+            BODY_20_39(X[i & 15], X[(i + 2) & 15], X[(i + 8) & 15],
-+                       X[(i + 13) & 15]);
-+        }
-+        for (i = 0; i < 20; i++) {
-+            BODY_40_59(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15],
-+                       X[(i + 5) & 15]);
-+        }
-+        for (i = 4; i < 24; i++) {
-+            BODY_60_79(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15],
-+                       X[(i + 5) & 15]);
-+        }
-+
-+        c->h0 = (c->h0 + A) & 0xffffffffL;
-+        c->h1 = (c->h1 + B) & 0xffffffffL;
-+        c->h2 = (c->h2 + C) & 0xffffffffL;
-+        c->h3 = (c->h3 + D) & 0xffffffffL;
-+        c->h4 = (c->h4 + E) & 0xffffffffL;
-+
-+        if (--num == 0)
-+            break;
-+
-+        A = c->h0;
-+        B = c->h1;
-+        C = c->h2;
-+        D = c->h3;
-+        E = c->h4;
-+
-+    }
-+}
-+# endif
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sparc_arch.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/sparc_arch.h
-new file mode 100644
-index 0000000..99eafb3
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sparc_arch.h
-@@ -0,0 +1,118 @@
-+/*
-+ * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef __SPARC_ARCH_H__
-+# define __SPARC_ARCH_H__
-+
-+# define SPARCV9_TICK_PRIVILEGED (1<<0)
-+# define SPARCV9_PREFER_FPU      (1<<1)
-+# define SPARCV9_VIS1            (1<<2)
-+# define SPARCV9_VIS2            (1<<3)/* reserved */
-+# define SPARCV9_FMADD           (1<<4)
-+# define SPARCV9_BLK             (1<<5)/* VIS1 block copy */
-+# define SPARCV9_VIS3            (1<<6)
-+# define SPARCV9_RANDOM          (1<<7)
-+# define SPARCV9_64BIT_STACK     (1<<8)
-+# define SPARCV9_FJAESX          (1<<9)/* Fujitsu SPARC64 X AES */
-+# define SPARCV9_FJDESX          (1<<10)/* Fujitsu SPARC64 X DES, reserved */
-+# define SPARCV9_FJHPCACE        (1<<11)/* Fujitsu HPC-ACE, reserved */
-+# define SPARCV9_IMA             (1<<13)/* reserved */
-+# define SPARCV9_VIS4            (1<<14)/* reserved */
-+
-+/*
-+ * OPENSSL_sparcv9cap_P[1] is copy of Compatibility Feature Register,
-+ * %asr26, SPARC-T4 and later. There is no SPARCV9_CFR bit in
-+ * OPENSSL_sparcv9cap_P[0], as %cfr copy is sufficient...
-+ */
-+# define CFR_AES         0x00000001/* Supports AES opcodes */
-+# define CFR_DES         0x00000002/* Supports DES opcodes */
-+# define CFR_KASUMI      0x00000004/* Supports KASUMI opcodes */
-+# define CFR_CAMELLIA    0x00000008/* Supports CAMELLIA opcodes */
-+# define CFR_MD5         0x00000010/* Supports MD5 opcodes */
-+# define CFR_SHA1        0x00000020/* Supports SHA1 opcodes */
-+# define CFR_SHA256      0x00000040/* Supports SHA256 opcodes */
-+# define CFR_SHA512      0x00000080/* Supports SHA512 opcodes */
-+# define CFR_MPMUL       0x00000100/* Supports MPMUL opcodes */
-+# define CFR_MONTMUL     0x00000200/* Supports MONTMUL opcodes */
-+# define CFR_MONTSQR     0x00000400/* Supports MONTSQR opcodes */
-+# define CFR_CRC32C      0x00000800/* Supports CRC32C opcodes */
-+# define CFR_XMPMUL      0x00001000/* Supports XMPMUL opcodes */
-+# define CFR_XMONTMUL    0x00002000/* Supports XMONTMUL opcodes */
-+# define CFR_XMONTSQR    0x00004000/* Supports XMONTSQR opcodes */
-+
-+# if defined(OPENSSL_PIC) && !defined(__PIC__)
-+#  define __PIC__
-+# endif
-+
-+# if defined(__SUNPRO_C) && defined(__sparcv9) && !defined(__arch64__)
-+#  define __arch64__
-+# endif
-+
-+# define SPARC_PIC_THUNK(reg)    \
-+        .align  32;             \
-+.Lpic_thunk:                    \
-+        jmp     %o7 + 8;        \
-+         add    %o7, reg, reg;
-+
-+# define SPARC_PIC_THUNK_CALL(reg)                       \
-+        sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), reg;      \
-+        call    .Lpic_thunk;                            \
-+         or     reg, %lo(_GLOBAL_OFFSET_TABLE_+4), reg;
-+
-+# if 1
-+#  define SPARC_SETUP_GOT_REG(reg)       SPARC_PIC_THUNK_CALL(reg)
-+# else
-+#  define SPARC_SETUP_GOT_REG(reg)       \
-+        sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), reg;      \
-+        call    .+8;                                    \
-+        or      reg,%lo(_GLOBAL_OFFSET_TABLE_+4), reg;  \
-+        add     %o7, reg, reg
-+# endif
-+
-+# if defined(__arch64__)
-+
-+#  define SPARC_LOAD_ADDRESS(SYM, reg)   \
-+        setx    SYM, %o7, reg;
-+#  define LDPTR          ldx
-+#  define SIZE_T_CC      %xcc
-+#  define STACK_FRAME    192
-+#  define STACK_BIAS     2047
-+#  define STACK_7thARG   (STACK_BIAS+176)
-+
-+# else
-+
-+#  define SPARC_LOAD_ADDRESS(SYM, reg)   \
-+        set     SYM, reg;
-+#  define LDPTR          ld
-+#  define SIZE_T_CC      %icc
-+#  define STACK_FRAME    112
-+#  define STACK_BIAS     0
-+#  define STACK_7thARG   92
-+#  define SPARC_LOAD_ADDRESS_LEAF(SYM,reg,tmp) SPARC_LOAD_ADDRESS(SYM,reg)
-+
-+# endif
-+
-+# ifdef __PIC__
-+#  undef SPARC_LOAD_ADDRESS
-+#  undef SPARC_LOAD_ADDRESS_LEAF
-+#  define SPARC_LOAD_ADDRESS(SYM, reg)   \
-+        SPARC_SETUP_GOT_REG(reg);       \
-+        sethi   %hi(SYM), %o7;          \
-+        or      %o7, %lo(SYM), %o7;     \
-+        LDPTR   [reg + %o7], reg;
-+# endif
-+
-+# ifndef SPARC_LOAD_ADDRESS_LEAF
-+#  define SPARC_LOAD_ADDRESS_LEAF(SYM, reg, tmp) \
-+        mov     %o7, tmp;                       \
-+        SPARC_LOAD_ADDRESS(SYM, reg)            \
-+        mov     tmp, %o7;
-+# endif
-+
-+#endif                          /* __SPARC_ARCH_H__ */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sparccpuid.S b/CryptoPkg/Library/OpensslLib/openssl/crypto/sparccpuid.S
-new file mode 100644
-index 0000000..c6ca224
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sparccpuid.S
-@@ -0,0 +1,582 @@
-+! Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+!
-+! Licensed under the OpenSSL license (the "License").  You may not use
-+! this file except in compliance with the License.  You can obtain a copy
-+! in the file LICENSE in the source distribution or at
-+! https://www.openssl.org/source/license.html
-+
-+#ifdef OPENSSL_FIPSCANISTER
-+#include 
-+#endif
-+
-+#if defined(__SUNPRO_C) && defined(__sparcv9)
-+# define ABI64  /* They've said -xarch=v9 at command line */
-+#elif defined(__GNUC__) && defined(__arch64__)
-+# define ABI64  /* They've said -m64 at command line */
-+#endif
-+
-+#ifdef ABI64
-+  .register	%g2,#scratch
-+  .register	%g3,#scratch
-+# define	FRAME	-192
-+# define	BIAS	2047
-+#else
-+# define	FRAME	-96
-+# define	BIAS	0
-+#endif
-+
-+.text
-+.align	32
-+.global	OPENSSL_wipe_cpu
-+.type	OPENSSL_wipe_cpu,#function
-+! Keep in mind that this does not excuse us from wiping the stack!
-+! This routine wipes registers, but not the backing store [which
-+! resides on the stack, toward lower addresses]. To facilitate for
-+! stack wiping I return pointer to the top of stack of the *caller*.
-+OPENSSL_wipe_cpu:
-+	save	%sp,FRAME,%sp
-+	nop
-+#ifdef __sun
-+#include 
-+	ta	ST_CLEAN_WINDOWS
-+#else
-+	call	.walk.reg.wins
-+#endif
-+	nop
-+	call	.PIC.zero.up
-+	mov	.zero-(.-4),%o0
-+	ld	[%o0],%f0
-+	ld	[%o0],%f1
-+
-+	subcc	%g0,1,%o0
-+	! Following is V9 "rd %ccr,%o0" instruction. However! V8
-+	! specification says that it ("rd %asr2,%o0" in V8 terms) does
-+	! not cause illegal_instruction trap. It therefore can be used
-+	! to determine if the CPU the code is executing on is V8- or
-+	! V9-compliant, as V9 returns a distinct value of 0x99,
-+	! "negative" and "borrow" bits set in both %icc and %xcc.
-+	.word	0x91408000	!rd	%ccr,%o0
-+	cmp	%o0,0x99
-+	bne	.v8
-+	nop
-+			! Even though we do not use %fp register bank,
-+			! we wipe it as memcpy might have used it...
-+			.word	0xbfa00040	!fmovd	%f0,%f62
-+			.word	0xbba00040	!...
-+			.word	0xb7a00040
-+			.word	0xb3a00040
-+			.word	0xafa00040
-+			.word	0xaba00040
-+			.word	0xa7a00040
-+			.word	0xa3a00040
-+			.word	0x9fa00040
-+			.word	0x9ba00040
-+			.word	0x97a00040
-+			.word	0x93a00040
-+			.word	0x8fa00040
-+			.word	0x8ba00040
-+			.word	0x87a00040
-+			.word	0x83a00040	!fmovd	%f0,%f32
-+.v8:			fmovs	%f1,%f31
-+	clr	%o0
-+			fmovs	%f0,%f30
-+	clr	%o1
-+			fmovs	%f1,%f29
-+	clr	%o2
-+			fmovs	%f0,%f28
-+	clr	%o3
-+			fmovs	%f1,%f27
-+	clr	%o4
-+			fmovs	%f0,%f26
-+	clr	%o5
-+			fmovs	%f1,%f25
-+	clr	%o7
-+			fmovs	%f0,%f24
-+	clr	%l0
-+			fmovs	%f1,%f23
-+	clr	%l1
-+			fmovs	%f0,%f22
-+	clr	%l2
-+			fmovs	%f1,%f21
-+	clr	%l3
-+			fmovs	%f0,%f20
-+	clr	%l4
-+			fmovs	%f1,%f19
-+	clr	%l5
-+			fmovs	%f0,%f18
-+	clr	%l6
-+			fmovs	%f1,%f17
-+	clr	%l7
-+			fmovs	%f0,%f16
-+	clr	%i0
-+			fmovs	%f1,%f15
-+	clr	%i1
-+			fmovs	%f0,%f14
-+	clr	%i2
-+			fmovs	%f1,%f13
-+	clr	%i3
-+			fmovs	%f0,%f12
-+	clr	%i4
-+			fmovs	%f1,%f11
-+	clr	%i5
-+			fmovs	%f0,%f10
-+	clr	%g1
-+			fmovs	%f1,%f9
-+	clr	%g2
-+			fmovs	%f0,%f8
-+	clr	%g3
-+			fmovs	%f1,%f7
-+	clr	%g4
-+			fmovs	%f0,%f6
-+	clr	%g5
-+			fmovs	%f1,%f5
-+			fmovs	%f0,%f4
-+			fmovs	%f1,%f3
-+			fmovs	%f0,%f2
-+
-+	add	%fp,BIAS,%i0	! return pointer to caller´s top of stack
-+
-+	ret
-+	restore
-+
-+.zero:	.long	0x0,0x0
-+.PIC.zero.up:
-+	retl
-+	add	%o0,%o7,%o0
-+#ifdef DEBUG
-+.global	walk_reg_wins
-+.type	walk_reg_wins,#function
-+walk_reg_wins:
-+#endif
-+.walk.reg.wins:
-+	save	%sp,FRAME,%sp
-+	cmp	%i7,%o7
-+	be	2f
-+	clr	%o0
-+	cmp	%o7,0	! compiler never cleans %o7...
-+	be	1f	! could have been a leaf function...
-+	clr	%o1
-+	call	.walk.reg.wins
-+	nop
-+1:	clr	%o2
-+	clr	%o3
-+	clr	%o4
-+	clr	%o5
-+	clr	%o7
-+	clr	%l0
-+	clr	%l1
-+	clr	%l2
-+	clr	%l3
-+	clr	%l4
-+	clr	%l5
-+	clr	%l6
-+	clr	%l7
-+	add	%o0,1,%i0	! used for debugging
-+2:	ret
-+	restore
-+.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
-+
-+.global	OPENSSL_atomic_add
-+.type	OPENSSL_atomic_add,#function
-+.align	32
-+OPENSSL_atomic_add:
-+#ifndef ABI64
-+	subcc	%g0,1,%o2
-+	.word	0x95408000	!rd	%ccr,%o2, see comment above
-+	cmp	%o2,0x99
-+	be	.v9
-+	nop
-+	save	%sp,FRAME,%sp
-+	ba	.enter
-+	nop
-+#ifdef __sun
-+! Note that you do not have to link with libthread to call thr_yield,
-+! as libc provides a stub, which is overloaded the moment you link
-+! with *either* libpthread or libthread...
-+#define	YIELD_CPU	thr_yield
-+#else
-+! applies at least to Linux and FreeBSD... Feedback expected...
-+#define	YIELD_CPU	sched_yield
-+#endif
-+.spin:	call	YIELD_CPU
-+	nop
-+.enter:	ld	[%i0],%i2
-+	cmp	%i2,-4096
-+	be	.spin
-+	mov	-1,%i2
-+	swap	[%i0],%i2
-+	cmp	%i2,-1
-+	be	.spin
-+	add	%i2,%i1,%i2
-+	stbar
-+	st	%i2,[%i0]
-+	sra	%i2,%g0,%i0
-+	ret
-+	restore
-+.v9:
-+#endif
-+	ld	[%o0],%o2
-+1:	add	%o1,%o2,%o3
-+	.word	0xd7e2100a	!cas [%o0],%o2,%o3, compare [%o0] with %o2 and swap %o3
-+	cmp	%o2,%o3
-+	bne	1b
-+	mov	%o3,%o2		! cas is always fetching to dest. register
-+	add	%o1,%o2,%o0	! OpenSSL expects the new value
-+	retl
-+	sra	%o0,%g0,%o0	! we return signed int, remember?
-+.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
-+
-+.global	_sparcv9_rdtick
-+.align	32
-+_sparcv9_rdtick:
-+	subcc	%g0,1,%o0
-+	.word	0x91408000	!rd	%ccr,%o0
-+	cmp	%o0,0x99
-+	bne	.notick
-+	xor	%o0,%o0,%o0
-+	.word	0x91410000	!rd	%tick,%o0
-+	retl
-+	.word	0x93323020	!srlx	%o0,32,%o1
-+.notick:
-+	retl
-+	xor	%o1,%o1,%o1
-+.type	_sparcv9_rdtick,#function
-+.size	_sparcv9_rdtick,.-_sparcv9_rdtick
-+
-+.global	_sparcv9_vis1_probe
-+.align	8
-+_sparcv9_vis1_probe:
-+	add	%sp,BIAS+2,%o1
-+	.word	0xc19a5a40	!ldda	[%o1]ASI_FP16_P,%f0
-+	retl
-+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
-+.type	_sparcv9_vis1_probe,#function
-+.size	_sparcv9_vis1_probe,.-_sparcv9_vis1_probe
-+
-+! Probe and instrument VIS1 instruction. Output is number of cycles it
-+! takes to execute rdtick and pair of VIS1 instructions. US-Tx VIS unit
-+! is slow (documented to be 6 cycles on T2) and the core is in-order
-+! single-issue, it should be possible to distinguish Tx reliably...
-+! Observed return values are:
-+!
-+!	UltraSPARC IIe		7
-+!	UltraSPARC III		7
-+!	UltraSPARC T1		24
-+!	SPARC T4		65(*)
-+!
-+! (*)	result has lesser to do with VIS instruction latencies, rdtick
-+!	appears that slow, but it does the trick in sense that FP and
-+!	VIS code paths are still slower than integer-only ones.
-+!
-+! Numbers for T2 and SPARC64 V-VII are more than welcomed.
-+!
-+! It would be possible to detect specifically US-T1 by instrumenting
-+! fmul8ulx16, which is emulated on T1 and as such accounts for quite
-+! a lot of %tick-s, couple of thousand on Linux...
-+.global	_sparcv9_vis1_instrument
-+.align	8
-+_sparcv9_vis1_instrument:
-+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
-+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
-+	.word	0x91410000	!rd	%tick,%o0
-+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
-+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
-+	.word	0x93410000	!rd	%tick,%o1
-+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
-+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
-+	.word	0x95410000	!rd	%tick,%o2
-+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
-+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
-+	.word	0x97410000	!rd	%tick,%o3
-+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
-+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
-+	.word	0x99410000	!rd	%tick,%o4
-+
-+	! calculate intervals
-+	sub	%o1,%o0,%o0
-+	sub	%o2,%o1,%o1
-+	sub	%o3,%o2,%o2
-+	sub	%o4,%o3,%o3
-+
-+	! find minimum value
-+	cmp	%o0,%o1
-+	.word	0x38680002	!bgu,a	%xcc,.+8
-+	mov	%o1,%o0
-+	cmp	%o0,%o2
-+	.word	0x38680002	!bgu,a	%xcc,.+8
-+	mov	%o2,%o0
-+	cmp	%o0,%o3
-+	.word	0x38680002	!bgu,a	%xcc,.+8
-+	mov	%o3,%o0
-+
-+	retl
-+	nop
-+.type	_sparcv9_vis1_instrument,#function
-+.size	_sparcv9_vis1_instrument,.-_sparcv9_vis1_instrument
-+
-+.global	_sparcv9_vis2_probe
-+.align	8
-+_sparcv9_vis2_probe:
-+	retl
-+	.word	0x81b00980	!bshuffle	%f0,%f0,%f0
-+.type	_sparcv9_vis2_probe,#function
-+.size	_sparcv9_vis2_probe,.-_sparcv9_vis2_probe
-+
-+.global	_sparcv9_fmadd_probe
-+.align	8
-+_sparcv9_fmadd_probe:
-+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
-+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
-+	retl
-+	.word	0x81b80440	!fmaddd	%f0,%f0,%f2,%f0
-+.type	_sparcv9_fmadd_probe,#function
-+.size	_sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe
-+
-+.global	_sparcv9_rdcfr
-+.align	8
-+_sparcv9_rdcfr:
-+	retl
-+	.word	0x91468000	!rd	%asr26,%o0
-+.type	_sparcv9_rdcfr,#function
-+.size	_sparcv9_rdcfr,.-_sparcv9_rdcfr
-+
-+.global	_sparcv9_vis3_probe
-+.align	8
-+_sparcv9_vis3_probe:
-+	retl
-+	.word	0x81b022a0	!xmulx	%g0,%g0,%g0
-+.type	_sparcv9_vis3_probe,#function
-+.size	_sparcv9_vis3_probe,.-_sparcv9_vis3_probe
-+
-+.global	_sparcv9_random
-+.align	8
-+_sparcv9_random:
-+	retl
-+	.word	0x91b002a0	!random	%o0
-+.type	_sparcv9_random,#function
-+.size	_sparcv9_random,.-_sparcv9_vis3_probe
-+
-+.global	_sparcv9_fjaesx_probe
-+.align	8
-+_sparcv9_fjaesx_probe:
-+	.word	0x81b09206	!faesencx %f2,%f6,%f0
-+	retl
-+	nop
-+.size	_sparcv9_fjaesx_probe,.-_sparcv9_fjaesx_probe
-+
-+.global	OPENSSL_cleanse
-+.align	32
-+OPENSSL_cleanse:
-+	cmp	%o1,14
-+	nop
-+#ifdef ABI64
-+	bgu	%xcc,.Lot
-+#else
-+	bgu	.Lot
-+#endif
-+	cmp	%o1,0
-+	bne	.Little
-+	nop
-+	retl
-+	nop
-+
-+.Little:
-+	stb	%g0,[%o0]
-+	subcc	%o1,1,%o1
-+	bnz	.Little
-+	add	%o0,1,%o0
-+	retl
-+	nop
-+.align	32
-+.Lot:
-+#ifndef ABI64
-+	subcc	%g0,1,%g1
-+	! see above for explanation
-+	.word	0x83408000	!rd	%ccr,%g1
-+	cmp	%g1,0x99
-+	bne	.v8lot
-+	nop
-+#endif
-+
-+.v9lot:	andcc	%o0,7,%g0
-+	bz	.v9aligned
-+	nop
-+	stb	%g0,[%o0]
-+	sub	%o1,1,%o1
-+	ba	.v9lot
-+	add	%o0,1,%o0
-+.align	16,0x01000000
-+.v9aligned:
-+	.word	0xc0720000	!stx	%g0,[%o0]
-+	sub	%o1,8,%o1
-+	andcc	%o1,-8,%g0
-+#ifdef ABI64
-+	.word	0x126ffffd	!bnz	%xcc,.v9aligned
-+#else
-+	.word	0x124ffffd	!bnz	%icc,.v9aligned
-+#endif
-+	add	%o0,8,%o0
-+
-+	cmp	%o1,0
-+	bne	.Little
-+	nop
-+	retl
-+	nop
-+#ifndef ABI64
-+.v8lot:	andcc	%o0,3,%g0
-+	bz	.v8aligned
-+	nop
-+	stb	%g0,[%o0]
-+	sub	%o1,1,%o1
-+	ba	.v8lot
-+	add	%o0,1,%o0
-+	nop
-+.v8aligned:
-+	st	%g0,[%o0]
-+	sub	%o1,4,%o1
-+	andcc	%o1,-4,%g0
-+	bnz	.v8aligned
-+	add	%o0,4,%o0
-+
-+	cmp	%o1,0
-+	bne	.Little
-+	nop
-+	retl
-+	nop
-+#endif
-+.type	OPENSSL_cleanse,#function
-+.size	OPENSSL_cleanse,.-OPENSSL_cleanse
-+
-+.global	CRYPTO_memcmp
-+.align	16
-+CRYPTO_memcmp:
-+	cmp	%o2,0
-+#ifdef ABI64
-+	beq,pn	%xcc,.Lno_data
-+#else
-+	beq	.Lno_data
-+#endif
-+	xor	%g1,%g1,%g1
-+	nop
-+
-+.Loop_cmp:
-+	ldub	[%o0],%o3
-+	add	%o0,1,%o0
-+	ldub	[%o1],%o4
-+	add	%o1,1,%o1
-+	subcc	%o2,1,%o2
-+	xor	%o3,%o4,%o4
-+#ifdef ABI64
-+	bnz	%xcc,.Loop_cmp
-+#else
-+	bnz	.Loop_cmp
-+#endif
-+	or	%o4,%g1,%g1
-+
-+	sub	%g0,%g1,%g1
-+	srl	%g1,31,%g1
-+.Lno_data:
-+	retl
-+	mov	%g1,%o0
-+.type	CRYPTO_memcmp,#function
-+.size	CRYPTO_memcmp,.-CRYPTO_memcmp
-+
-+.global	_sparcv9_vis1_instrument_bus
-+.align	8
-+_sparcv9_vis1_instrument_bus:
-+	mov	%o1,%o3					! save cnt
-+	.word	0x99410000	!rd	%tick,%o4	! tick
-+	mov	%o4,%o5					! lasttick = tick
-+	set	0,%g4					! diff
-+
-+	andn	%o0,63,%g1
-+	.word	0xc1985e00	!ldda	[%g1]0xf0,%f0	! block load
-+	.word	0x8143e040	!membar	#Sync
-+	.word	0xc1b85c00	!stda	%f0,[%g1]0xe0	! block store and commit
-+	.word	0x8143e040	!membar	#Sync
-+	ld	[%o0],%o4
-+	add	%o4,%g4,%g4
-+	.word	0xc9e2100c	!cas	[%o0],%o4,%g4
-+
-+.Loop:	.word	0x99410000	!rd	%tick,%o4
-+	sub	%o4,%o5,%g4				! diff=tick-lasttick
-+	mov	%o4,%o5					! lasttick=tick
-+
-+	andn	%o0,63,%g1
-+	.word	0xc1985e00	!ldda	[%g1]0xf0,%f0	! block load
-+	.word	0x8143e040	!membar	#Sync
-+	.word	0xc1b85c00	!stda	%f0,[%g1]0xe0	! block store and commit
-+	.word	0x8143e040	!membar	#Sync
-+	ld	[%o0],%o4
-+	add	%o4,%g4,%g4
-+	.word	0xc9e2100c	!cas	[%o0],%o4,%g4
-+	subcc	%o1,1,%o1				! --$cnt
-+	bnz	.Loop
-+	add	%o0,4,%o0				! ++$out
-+
-+	retl
-+	mov	%o3,%o0
-+.type	_sparcv9_vis1_instrument_bus,#function
-+.size	_sparcv9_vis1_instrument_bus,.-_sparcv9_vis1_instrument_bus
-+
-+.global	_sparcv9_vis1_instrument_bus2
-+.align	8
-+_sparcv9_vis1_instrument_bus2:
-+	mov	%o1,%o3					! save cnt
-+	sll	%o1,2,%o1				! cnt*=4
-+
-+	.word	0x99410000	!rd	%tick,%o4	! tick
-+	mov	%o4,%o5					! lasttick = tick
-+	set	0,%g4					! diff
-+
-+	andn	%o0,63,%g1
-+	.word	0xc1985e00	!ldda	[%g1]0xf0,%f0	! block load
-+	.word	0x8143e040	!membar	#Sync
-+	.word	0xc1b85c00	!stda	%f0,[%g1]0xe0	! block store and commit
-+	.word	0x8143e040	!membar	#Sync
-+	ld	[%o0],%o4
-+	add	%o4,%g4,%g4
-+	.word	0xc9e2100c	!cas	[%o0],%o4,%g4
-+
-+	.word	0x99410000	!rd	%tick,%o4	! tick
-+	sub	%o4,%o5,%g4				! diff=tick-lasttick
-+	mov	%o4,%o5					! lasttick=tick
-+	mov	%g4,%g5					! lastdiff=diff
-+.Loop2:
-+	andn	%o0,63,%g1
-+	.word	0xc1985e00	!ldda	[%g1]0xf0,%f0	! block load
-+	.word	0x8143e040	!membar	#Sync
-+	.word	0xc1b85c00	!stda	%f0,[%g1]0xe0	! block store and commit
-+	.word	0x8143e040	!membar	#Sync
-+	ld	[%o0],%o4
-+	add	%o4,%g4,%g4
-+	.word	0xc9e2100c	!cas	[%o0],%o4,%g4
-+
-+	subcc	%o2,1,%o2				! --max
-+	bz	.Ldone2
-+	nop
-+
-+	.word	0x99410000	!rd	%tick,%o4	! tick
-+	sub	%o4,%o5,%g4				! diff=tick-lasttick
-+	mov	%o4,%o5					! lasttick=tick
-+	cmp	%g4,%g5
-+	mov	%g4,%g5					! lastdiff=diff
-+
-+	.word	0x83408000	!rd	%ccr,%g1
-+	and	%g1,4,%g1				! isolate zero flag
-+	xor	%g1,4,%g1				! flip zero flag
-+
-+	subcc	%o1,%g1,%o1				! conditional --$cnt
-+	bnz	.Loop2
-+	add	%o0,%g1,%o0				! conditional ++$out
-+
-+.Ldone2:
-+	srl	%o1,2,%o1
-+	retl
-+	sub	%o3,%o1,%o0
-+.type	_sparcv9_vis1_instrument_bus2,#function
-+.size	_sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2
-+
-+.section	".init",#alloc,#execinstr
-+	call	OPENSSL_cpuid_setup
-+	nop
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/sparcv9cap.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/sparcv9cap.c
-new file mode 100644
-index 0000000..61d0334
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/sparcv9cap.c
-@@ -0,0 +1,294 @@
-+/*
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#include "sparc_arch.h"
-+
-+#if defined(__GNUC__) && defined(__linux)
-+__attribute__ ((visibility("hidden")))
-+#endif
-+unsigned int OPENSSL_sparcv9cap_P[2] = { SPARCV9_TICK_PRIVILEGED, 0 };
-+
-+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                const BN_ULONG *np, const BN_ULONG *n0, int num)
-+{
-+    int bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                         const BN_ULONG *np, const BN_ULONG *n0, int num);
-+    int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                        const BN_ULONG *np, const BN_ULONG *n0, int num);
-+    int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                        const BN_ULONG *np, const BN_ULONG *n0, int num);
-+
-+    if (!(num & 1) && num >= 6) {
-+        if ((num & 15) == 0 && num <= 64 &&
-+            (OPENSSL_sparcv9cap_P[1] & (CFR_MONTMUL | CFR_MONTSQR)) ==
-+            (CFR_MONTMUL | CFR_MONTSQR)) {
-+            typedef int (*bn_mul_mont_f) (BN_ULONG *rp, const BN_ULONG *ap,
-+                                          const BN_ULONG *bp,
-+                                          const BN_ULONG *np,
-+                                          const BN_ULONG *n0);
-+            int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap,
-+                                 const BN_ULONG *bp, const BN_ULONG *np,
-+                                 const BN_ULONG *n0);
-+            int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap,
-+                                  const BN_ULONG *bp, const BN_ULONG *np,
-+                                  const BN_ULONG *n0);
-+            int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap,
-+                                  const BN_ULONG *bp, const BN_ULONG *np,
-+                                  const BN_ULONG *n0);
-+            int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap,
-+                                  const BN_ULONG *bp, const BN_ULONG *np,
-+                                  const BN_ULONG *n0);
-+            static const bn_mul_mont_f funcs[4] = {
-+                bn_mul_mont_t4_8, bn_mul_mont_t4_16,
-+                bn_mul_mont_t4_24, bn_mul_mont_t4_32
-+            };
-+            bn_mul_mont_f worker = funcs[num / 16 - 1];
-+
-+            if ((*worker) (rp, ap, bp, np, n0))
-+                return 1;
-+            /* retry once and fall back */
-+            if ((*worker) (rp, ap, bp, np, n0))
-+                return 1;
-+            return bn_mul_mont_vis3(rp, ap, bp, np, n0, num);
-+        }
-+        if ((OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3))
-+            return bn_mul_mont_vis3(rp, ap, bp, np, n0, num);
-+        else if (num >= 8 &&
-+                 /*
-+                  * bn_mul_mont_fpu doesn't use FMADD, we just use the
-+                  * flag to detect when FPU path is preferable in cases
-+                  * when current heuristics is unreliable. [it works
-+                  * out because FMADD-capable processors where FPU
-+                  * code path is undesirable are also VIS3-capable and
-+                  * VIS3 code path takes precedence.]
-+                  */
-+                 ( (OPENSSL_sparcv9cap_P[0] & SPARCV9_FMADD) ||
-+                   (OPENSSL_sparcv9cap_P[0] &
-+                    (SPARCV9_PREFER_FPU | SPARCV9_VIS1)) ==
-+                   (SPARCV9_PREFER_FPU | SPARCV9_VIS1) ))
-+            return bn_mul_mont_fpu(rp, ap, bp, np, n0, num);
-+    }
-+    return bn_mul_mont_int(rp, ap, bp, np, n0, num);
-+}
-+
-+unsigned long _sparcv9_rdtick(void);
-+void _sparcv9_vis1_probe(void);
-+unsigned long _sparcv9_vis1_instrument(void);
-+void _sparcv9_vis2_probe(void);
-+void _sparcv9_fmadd_probe(void);
-+unsigned long _sparcv9_rdcfr(void);
-+void _sparcv9_vis3_probe(void);
-+void _sparcv9_fjaesx_probe(void);
-+unsigned long _sparcv9_random(void);
-+size_t _sparcv9_vis1_instrument_bus(unsigned int *, size_t);
-+size_t _sparcv9_vis1_instrument_bus2(unsigned int *, size_t, size_t);
-+
-+unsigned long OPENSSL_rdtsc(void)
-+{
-+    if (OPENSSL_sparcv9cap_P[0] & SPARCV9_TICK_PRIVILEGED)
-+#if defined(__sun) && defined(__SVR4)
-+        return gethrtime();
-+#else
-+        return 0;
-+#endif
-+    else
-+        return _sparcv9_rdtick();
-+}
-+
-+size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt)
-+{
-+    if ((OPENSSL_sparcv9cap_P[0] & (SPARCV9_TICK_PRIVILEGED | SPARCV9_BLK)) ==
-+        SPARCV9_BLK)
-+        return _sparcv9_vis1_instrument_bus(out, cnt);
-+    else
-+        return 0;
-+}
-+
-+size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max)
-+{
-+    if ((OPENSSL_sparcv9cap_P[0] & (SPARCV9_TICK_PRIVILEGED | SPARCV9_BLK)) ==
-+        SPARCV9_BLK)
-+        return _sparcv9_vis1_instrument_bus2(out, cnt, max);
-+    else
-+        return 0;
-+}
-+
-+static sigjmp_buf common_jmp;
-+static void common_handler(int sig)
-+{
-+    siglongjmp(common_jmp, sig);
-+}
-+
-+#if defined(__sun) && defined(__SVR4)
-+# if defined(__GNUC__) && __GNUC__>=2
-+extern unsigned int getisax(unsigned int vec[], unsigned int sz) __attribute__ ((weak));
-+# elif defined(__SUNPRO_C)
-+#pragma weak getisax
-+extern unsigned int getisax(unsigned int vec[], unsigned int sz);
-+# else
-+static unsigned int (*getisax) (unsigned int vec[], unsigned int sz) = NULL;
-+# endif
-+#endif
-+
-+void OPENSSL_cpuid_setup(void)
-+{
-+    char *e;
-+    struct sigaction common_act, ill_oact, bus_oact;
-+    sigset_t all_masked, oset;
-+    static int trigger = 0;
-+
-+    if (trigger)
-+        return;
-+    trigger = 1;
-+
-+    if ((e = getenv("OPENSSL_sparcv9cap"))) {
-+        OPENSSL_sparcv9cap_P[0] = strtoul(e, NULL, 0);
-+        if ((e = strchr(e, ':')))
-+            OPENSSL_sparcv9cap_P[1] = strtoul(e + 1, NULL, 0);
-+        return;
-+    }
-+
-+#if defined(__sun) && defined(__SVR4)
-+    if (getisax != NULL) {
-+        unsigned int vec[2] = { 0, 0 };
-+
-+        if (getisax (vec,2)) {
-+            if (vec[0]&0x00020) OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS1;
-+            if (vec[0]&0x00040) OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2;
-+            if (vec[0]&0x00080) OPENSSL_sparcv9cap_P[0] |= SPARCV9_BLK;
-+            if (vec[0]&0x00100) OPENSSL_sparcv9cap_P[0] |= SPARCV9_FMADD;
-+            if (vec[0]&0x00400) OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS3;
-+            if (vec[0]&0x01000) OPENSSL_sparcv9cap_P[0] |= SPARCV9_FJHPCACE;
-+            if (vec[0]&0x02000) OPENSSL_sparcv9cap_P[0] |= SPARCV9_FJDESX;
-+            if (vec[0]&0x08000) OPENSSL_sparcv9cap_P[0] |= SPARCV9_IMA;
-+            if (vec[0]&0x10000) OPENSSL_sparcv9cap_P[0] |= SPARCV9_FJAESX;
-+            if (vec[1]&0x00008) OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS4;
-+
-+            /* reconstruct %cfr copy */
-+            OPENSSL_sparcv9cap_P[1] = (vec[0]>>17)&0x3ff;
-+            OPENSSL_sparcv9cap_P[1] |= (OPENSSL_sparcv9cap_P[1]&CFR_MONTMUL)<<1;
-+            if (vec[0]&0x20000000) OPENSSL_sparcv9cap_P[1] |= CFR_CRC32C;
-+            if (vec[1]&0x00000020) OPENSSL_sparcv9cap_P[1] |= CFR_XMPMUL;
-+            if (vec[1]&0x00000040)
-+                OPENSSL_sparcv9cap_P[1] |= CFR_XMONTMUL|CFR_XMONTSQR;
-+
-+            /* Some heuristics */
-+            /* all known VIS2-capable CPUs have unprivileged tick counter */
-+            if (OPENSSL_sparcv9cap_P[0]&SPARCV9_VIS2)
-+                OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
-+
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_PREFER_FPU;
-+
-+            /* detect UltraSPARC-Tx, see sparccpud.S for details... */
-+            if ((OPENSSL_sparcv9cap_P[0]&SPARCV9_VIS1) &&
-+                _sparcv9_vis1_instrument() >= 12)
-+                OPENSSL_sparcv9cap_P[0] &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU);
-+        }
-+
-+        if (sizeof(size_t) == 8)
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_64BIT_STACK;
-+
-+        return;
-+    }
-+#endif
-+
-+    /* Initial value, fits UltraSPARC-I&II... */
-+    OPENSSL_sparcv9cap_P[0] = SPARCV9_PREFER_FPU | SPARCV9_TICK_PRIVILEGED;
-+
-+    sigfillset(&all_masked);
-+    sigdelset(&all_masked, SIGILL);
-+    sigdelset(&all_masked, SIGTRAP);
-+# ifdef SIGEMT
-+    sigdelset(&all_masked, SIGEMT);
-+# endif
-+    sigdelset(&all_masked, SIGFPE);
-+    sigdelset(&all_masked, SIGBUS);
-+    sigdelset(&all_masked, SIGSEGV);
-+    sigprocmask(SIG_SETMASK, &all_masked, &oset);
-+
-+    memset(&common_act, 0, sizeof(common_act));
-+    common_act.sa_handler = common_handler;
-+    common_act.sa_mask = all_masked;
-+
-+    sigaction(SIGILL, &common_act, &ill_oact);
-+    sigaction(SIGBUS, &common_act, &bus_oact); /* T1 fails 16-bit ldda [on
-+                                                * Linux] */
-+
-+    if (sigsetjmp(common_jmp, 1) == 0) {
-+        _sparcv9_rdtick();
-+        OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
-+    }
-+
-+    if (sigsetjmp(common_jmp, 1) == 0) {
-+        _sparcv9_vis1_probe();
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS1 | SPARCV9_BLK;
-+        /* detect UltraSPARC-Tx, see sparccpud.S for details... */
-+        if (_sparcv9_vis1_instrument() >= 12)
-+            OPENSSL_sparcv9cap_P[0] &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU);
-+        else {
-+            _sparcv9_vis2_probe();
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2;
-+        }
-+    }
-+
-+    if (sigsetjmp(common_jmp, 1) == 0) {
-+        _sparcv9_fmadd_probe();
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_FMADD;
-+    }
-+
-+    /*
-+     * VIS3 flag is tested independently from VIS1, unlike VIS2 that is,
-+     * because VIS3 defines even integer instructions.
-+     */
-+    if (sigsetjmp(common_jmp, 1) == 0) {
-+        _sparcv9_vis3_probe();
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS3;
-+    }
-+
-+    if (sigsetjmp(common_jmp, 1) == 0) {
-+        _sparcv9_fjaesx_probe();
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_FJAESX;
-+    }
-+
-+    /*
-+     * In wait for better solution _sparcv9_rdcfr is masked by
-+     * VIS3 flag, because it goes to uninterruptable endless
-+     * loop on UltraSPARC II running Solaris. Things might be
-+     * different on Linux...
-+     */
-+    if ((OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3) &&
-+        sigsetjmp(common_jmp, 1) == 0) {
-+        OPENSSL_sparcv9cap_P[1] = (unsigned int)_sparcv9_rdcfr();
-+    }
-+
-+    sigaction(SIGBUS, &bus_oact, NULL);
-+    sigaction(SIGILL, &ill_oact, NULL);
-+
-+    sigprocmask(SIG_SETMASK, &oset, NULL);
-+
-+    if (sizeof(size_t) == 8)
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_64BIT_STACK;
-+# ifdef __linux
-+    else {
-+        int ret = syscall(340);
-+
-+        if (ret >= 0 && ret & 1)
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_64BIT_STACK;
-+    }
-+# endif
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/srp/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/srp/build.info
-new file mode 100644
-index 0000000..b6c7fe7
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/srp/build.info
-@@ -0,0 +1,2 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=srp_lib.c srp_vfy.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/srp/srp_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/srp/srp_lib.c
-new file mode 100644
-index 0000000..e69de29
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/srp/srp_vfy.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/srp/srp_vfy.c
-new file mode 100644
-index 0000000..e69de29
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/stack/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/stack/build.info
-new file mode 100644
-index 0000000..e587021
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/stack/build.info
-@@ -0,0 +1,2 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=stack.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/stack/stack.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/stack/stack.c
-new file mode 100644
-index 0000000..43ddf30
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/stack/stack.c
-@@ -0,0 +1,312 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include "internal/numbers.h"
-+#include 
-+#include 
-+
-+struct stack_st {
-+    int num;
-+    const char **data;
-+    int sorted;
-+    size_t num_alloc;
-+    OPENSSL_sk_compfunc comp;
-+};
-+
-+#undef MIN_NODES
-+#define MIN_NODES       4
-+
-+#include 
-+
-+OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_compfunc c)
-+{
-+    OPENSSL_sk_compfunc old = sk->comp;
-+
-+    if (sk->comp != c)
-+        sk->sorted = 0;
-+    sk->comp = c;
-+
-+    return old;
-+}
-+
-+OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk)
-+{
-+    OPENSSL_STACK *ret;
-+
-+    if (sk->num < 0)
-+        return NULL;
-+
-+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
-+        return NULL;
-+
-+    /* direct structure assignment */
-+    *ret = *sk;
-+
-+    if ((ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc)) == NULL)
-+        goto err;
-+    memcpy(ret->data, sk->data, sizeof(char *) * sk->num);
-+    return ret;
-+ err:
-+    OPENSSL_sk_free(ret);
-+    return NULL;
-+}
-+
-+OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
-+                             OPENSSL_sk_copyfunc copy_func,
-+                             OPENSSL_sk_freefunc free_func)
-+{
-+    OPENSSL_STACK *ret;
-+    int i;
-+
-+    if (sk->num < 0)
-+        return NULL;
-+
-+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
-+        return NULL;
-+
-+    /* direct structure assignment */
-+    *ret = *sk;
-+
-+    ret->num_alloc = sk->num > MIN_NODES ? (size_t)sk->num : MIN_NODES;
-+    ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc);
-+    if (ret->data == NULL) {
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+
-+    for (i = 0; i < ret->num; ++i) {
-+        if (sk->data[i] == NULL)
-+            continue;
-+        if ((ret->data[i] = copy_func(sk->data[i])) == NULL) {
-+            while (--i >= 0)
-+                if (ret->data[i] != NULL)
-+                    free_func((void *)ret->data[i]);
-+            OPENSSL_sk_free(ret);
-+            return NULL;
-+        }
-+    }
-+    return ret;
-+}
-+
-+OPENSSL_STACK *OPENSSL_sk_new_null(void)
-+{
-+    return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL);
-+}
-+
-+OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc c)
-+{
-+    OPENSSL_STACK *ret;
-+
-+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
-+        goto err;
-+    if ((ret->data = OPENSSL_zalloc(sizeof(*ret->data) * MIN_NODES)) == NULL)
-+        goto err;
-+    ret->comp = c;
-+    ret->num_alloc = MIN_NODES;
-+    return (ret);
-+
-+ err:
-+    OPENSSL_free(ret);
-+    return (NULL);
-+}
-+
-+int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc)
-+{
-+    if (st == NULL || st->num < 0 || st->num == INT_MAX) {
-+        return 0;
-+    }
-+
-+    if (st->num_alloc <= (size_t)(st->num + 1)) {
-+        size_t doub_num_alloc = st->num_alloc * 2;
-+        const char **tmpdata;
-+
-+        /* Overflow checks */
-+        if (doub_num_alloc < st->num_alloc)
-+            return 0;
-+
-+        /* Avoid overflow due to multiplication by sizeof(char *) */
-+        if (doub_num_alloc > SIZE_MAX / sizeof(char *))
-+            return 0;
-+
-+        tmpdata = OPENSSL_realloc((char *)st->data,
-+                                  sizeof(char *) * doub_num_alloc);
-+        if (tmpdata == NULL)
-+            return 0;
-+
-+        st->data = tmpdata;
-+        st->num_alloc = doub_num_alloc;
-+    }
-+    if ((loc >= st->num) || (loc < 0)) {
-+        st->data[st->num] = data;
-+    } else {
-+        memmove(&st->data[loc + 1], &st->data[loc],
-+                sizeof(st->data[0]) * (st->num - loc));
-+        st->data[loc] = data;
-+    }
-+    st->num++;
-+    st->sorted = 0;
-+    return st->num;
-+}
-+
-+void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p)
-+{
-+    int i;
-+
-+    for (i = 0; i < st->num; i++)
-+        if (st->data[i] == p)
-+            return OPENSSL_sk_delete(st, i);
-+    return NULL;
-+}
-+
-+void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc)
-+{
-+    const char *ret;
-+
-+    if (st == NULL || loc < 0 || loc >= st->num)
-+        return NULL;
-+
-+    ret = st->data[loc];
-+    if (loc != st->num - 1)
-+         memmove(&st->data[loc], &st->data[loc + 1],
-+                 sizeof(st->data[0]) * (st->num - loc - 1));
-+    st->num--;
-+    return (void *)ret;
-+}
-+
-+static int internal_find(OPENSSL_STACK *st, const void *data,
-+                         int ret_val_options)
-+{
-+    const void *r;
-+    int i;
-+
-+    if (st == NULL)
-+        return -1;
-+
-+    if (st->comp == NULL) {
-+        for (i = 0; i < st->num; i++)
-+            if (st->data[i] == data)
-+                return (i);
-+        return (-1);
-+    }
-+    OPENSSL_sk_sort(st);
-+    if (data == NULL)
-+        return (-1);
-+    r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
-+                        ret_val_options);
-+    if (r == NULL)
-+        return (-1);
-+    return (int)((const char **)r - st->data);
-+}
-+
-+int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)
-+{
-+    return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
-+}
-+
-+int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data)
-+{
-+    return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
-+}
-+
-+int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)
-+{
-+    return (OPENSSL_sk_insert(st, data, st->num));
-+}
-+
-+int OPENSSL_sk_unshift(OPENSSL_STACK *st, const void *data)
-+{
-+    return (OPENSSL_sk_insert(st, data, 0));
-+}
-+
-+void *OPENSSL_sk_shift(OPENSSL_STACK *st)
-+{
-+    if (st == NULL)
-+        return (NULL);
-+    if (st->num <= 0)
-+        return (NULL);
-+    return (OPENSSL_sk_delete(st, 0));
-+}
-+
-+void *OPENSSL_sk_pop(OPENSSL_STACK *st)
-+{
-+    if (st == NULL)
-+        return (NULL);
-+    if (st->num <= 0)
-+        return (NULL);
-+    return (OPENSSL_sk_delete(st, st->num - 1));
-+}
-+
-+void OPENSSL_sk_zero(OPENSSL_STACK *st)
-+{
-+    if (st == NULL)
-+        return;
-+    if (st->num <= 0)
-+        return;
-+    memset(st->data, 0, sizeof(*st->data) * st->num);
-+    st->num = 0;
-+}
-+
-+void OPENSSL_sk_pop_free(OPENSSL_STACK *st, OPENSSL_sk_freefunc func)
-+{
-+    int i;
-+
-+    if (st == NULL)
-+        return;
-+    for (i = 0; i < st->num; i++)
-+        if (st->data[i] != NULL)
-+            func((char *)st->data[i]);
-+    OPENSSL_sk_free(st);
-+}
-+
-+void OPENSSL_sk_free(OPENSSL_STACK *st)
-+{
-+    if (st == NULL)
-+        return;
-+    OPENSSL_free(st->data);
-+    OPENSSL_free(st);
-+}
-+
-+int OPENSSL_sk_num(const OPENSSL_STACK *st)
-+{
-+    if (st == NULL)
-+        return -1;
-+    return st->num;
-+}
-+
-+void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i)
-+{
-+    if (st == NULL || i < 0 || i >= st->num)
-+        return NULL;
-+    return (void *)st->data[i];
-+}
-+
-+void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data)
-+{
-+    if (st == NULL || i < 0 || i >= st->num)
-+        return NULL;
-+    st->data[i] = data;
-+    return (void *)st->data[i];
-+}
-+
-+void OPENSSL_sk_sort(OPENSSL_STACK *st)
-+{
-+    if (st && !st->sorted && st->comp != NULL) {
-+        qsort(st->data, st->num, sizeof(char *), st->comp);
-+        st->sorted = 1;
-+    }
-+}
-+
-+int OPENSSL_sk_is_sorted(const OPENSSL_STACK *st)
-+{
-+    if (st == NULL)
-+        return 1;
-+    return st->sorted;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/threads_none.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/threads_none.c
-new file mode 100644
-index 0000000..72bf25b
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/threads_none.c
-@@ -0,0 +1,124 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)
-+
-+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
-+{
-+    CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(unsigned int));
-+    if (lock == NULL)
-+        return NULL;
-+
-+    *(unsigned int *)lock = 1;
-+
-+    return lock;
-+}
-+
-+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
-+{
-+    OPENSSL_assert(*(unsigned int *)lock == 1);
-+    return 1;
-+}
-+
-+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
-+{
-+    OPENSSL_assert(*(unsigned int *)lock == 1);
-+    return 1;
-+}
-+
-+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
-+{
-+    OPENSSL_assert(*(unsigned int *)lock == 1);
-+    return 1;
-+}
-+
-+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock) {
-+    if (lock == NULL)
-+        return;
-+
-+    *(unsigned int *)lock = 0;
-+    OPENSSL_free(lock);
-+
-+    return;
-+}
-+
-+int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
-+{
-+    if (*once != 0)
-+        return 1;
-+
-+    init();
-+    *once = 1;
-+
-+    return 1;
-+}
-+
-+#define OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX 256
-+
-+static void *thread_local_storage[OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX];
-+
-+int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
-+{
-+    static unsigned int thread_local_key = 0;
-+
-+    if (thread_local_key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
-+        return 0;
-+
-+    *key = thread_local_key++;
-+
-+    thread_local_storage[*key] = NULL;
-+
-+    return 1;
-+}
-+
-+void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
-+{
-+    if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
-+        return NULL;
-+
-+    return thread_local_storage[*key];
-+}
-+
-+int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
-+{
-+    if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
-+        return 0;
-+
-+    thread_local_storage[*key] = val;
-+
-+    return 1;
-+}
-+
-+int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
-+{
-+    *key = OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX + 1;
-+    return 1;
-+}
-+
-+CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
-+{
-+    return 0;
-+}
-+
-+int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
-+{
-+    return (a == b);
-+}
-+
-+int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
-+{
-+    *val += amount;
-+    *ret  = *val;
-+
-+    return 1;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/threads_pthread.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/threads_pthread.c
-new file mode 100644
-index 0000000..151013e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/threads_pthread.c
-@@ -0,0 +1,171 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS)
-+
-+# ifdef PTHREAD_RWLOCK_INITIALIZER
-+#  define USE_RWLOCK
-+# endif
-+
-+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
-+{
-+# ifdef USE_RWLOCK
-+    CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(pthread_rwlock_t));
-+    if (lock == NULL)
-+        return NULL;
-+
-+    if (pthread_rwlock_init(lock, NULL) != 0) {
-+        OPENSSL_free(lock);
-+        return NULL;
-+    }
-+# else
-+    pthread_mutexattr_t attr;
-+    CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(pthread_mutex_t));
-+    if (lock == NULL)
-+        return NULL;
-+
-+    pthread_mutexattr_init(&attr);
-+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-+
-+    if (pthread_mutex_init(lock, &attr) != 0) {
-+        pthread_mutexattr_destroy(&attr);
-+        OPENSSL_free(lock);
-+        return NULL;
-+    }
-+
-+    pthread_mutexattr_destroy(&attr);
-+# endif
-+
-+    return lock;
-+}
-+
-+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
-+{
-+# ifdef USE_RWLOCK
-+    if (pthread_rwlock_rdlock(lock) != 0)
-+        return 0;
-+# else
-+    if (pthread_mutex_lock(lock) != 0)
-+        return 0;
-+# endif
-+
-+    return 1;
-+}
-+
-+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
-+{
-+# ifdef USE_RWLOCK
-+    if (pthread_rwlock_wrlock(lock) != 0)
-+        return 0;
-+# else
-+    if (pthread_mutex_lock(lock) != 0)
-+        return 0;
-+# endif
-+
-+    return 1;
-+}
-+
-+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
-+{
-+# ifdef USE_RWLOCK
-+    if (pthread_rwlock_unlock(lock) != 0)
-+        return 0;
-+# else
-+    if (pthread_mutex_unlock(lock) != 0)
-+        return 0;
-+# endif
-+
-+    return 1;
-+}
-+
-+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
-+{
-+    if (lock == NULL)
-+        return;
-+
-+# ifdef USE_RWLOCK
-+    pthread_rwlock_destroy(lock);
-+# else
-+    pthread_mutex_destroy(lock);
-+# endif
-+    OPENSSL_free(lock);
-+
-+    return;
-+}
-+
-+int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
-+{
-+    if (pthread_once(once, init) != 0)
-+        return 0;
-+
-+    return 1;
-+}
-+
-+int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
-+{
-+    if (pthread_key_create(key, cleanup) != 0)
-+        return 0;
-+
-+    return 1;
-+}
-+
-+void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
-+{
-+    return pthread_getspecific(*key);
-+}
-+
-+int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
-+{
-+    if (pthread_setspecific(*key, val) != 0)
-+        return 0;
-+
-+    return 1;
-+}
-+
-+int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
-+{
-+    if (pthread_key_delete(*key) != 0)
-+        return 0;
-+
-+    return 1;
-+}
-+
-+CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
-+{
-+    return pthread_self();
-+}
-+
-+int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
-+{
-+    return pthread_equal(a, b);
-+}
-+
-+int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
-+{
-+# if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL)
-+    if (__atomic_is_lock_free(sizeof(*val), val)) {
-+        *ret = __atomic_add_fetch(val, amount, __ATOMIC_ACQ_REL);
-+        return 1;
-+    }
-+# endif
-+    if (!CRYPTO_THREAD_write_lock(lock))
-+        return 0;
-+
-+    *val += amount;
-+    *ret  = *val;
-+
-+    if (!CRYPTO_THREAD_unlock(lock))
-+        return 0;
-+
-+    return 1;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/threads_win.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/threads_win.c
-new file mode 100644
-index 0000000..4e0de90
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/threads_win.c
-@@ -0,0 +1,136 @@
-+/*
-+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#if defined(_WIN32)
-+# include 
-+#endif
-+
-+#include 
-+
-+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && defined(OPENSSL_SYS_WINDOWS)
-+
-+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
-+{
-+    CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(CRITICAL_SECTION));
-+    if (lock == NULL)
-+        return NULL;
-+
-+    /* 0x400 is the spin count value suggested in the documentation */
-+    if (!InitializeCriticalSectionAndSpinCount(lock, 0x400)) {
-+        OPENSSL_free(lock);
-+        return NULL;
-+    }
-+
-+    return lock;
-+}
-+
-+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
-+{
-+    EnterCriticalSection(lock);
-+    return 1;
-+}
-+
-+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
-+{
-+    EnterCriticalSection(lock);
-+    return 1;
-+}
-+
-+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
-+{
-+    LeaveCriticalSection(lock);
-+    return 1;
-+}
-+
-+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
-+{
-+    if (lock == NULL)
-+        return;
-+
-+    DeleteCriticalSection(lock);
-+    OPENSSL_free(lock);
-+
-+    return;
-+}
-+
-+#  define ONCE_UNINITED     0
-+#  define ONCE_ININIT       1
-+#  define ONCE_DONE         2
-+
-+/*
-+ * We don't use InitOnceExecuteOnce because that isn't available in WinXP which
-+ * we still have to support.
-+ */
-+int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
-+{
-+    LONG volatile *lock = (LONG *)once;
-+    LONG result;
-+
-+    if (*lock == ONCE_DONE)
-+        return 1;
-+
-+    do {
-+        result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED);
-+        if (result == ONCE_UNINITED) {
-+            init();
-+            *lock = ONCE_DONE;
-+            return 1;
-+        }
-+    } while (result == ONCE_ININIT);
-+
-+    return (*lock == ONCE_DONE);
-+}
-+
-+int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
-+{
-+    *key = TlsAlloc();
-+    if (*key == TLS_OUT_OF_INDEXES)
-+        return 0;
-+
-+    return 1;
-+}
-+
-+void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
-+{
-+    return TlsGetValue(*key);
-+}
-+
-+int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
-+{
-+    if (TlsSetValue(*key, val) == 0)
-+        return 0;
-+
-+    return 1;
-+}
-+
-+int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
-+{
-+    if (TlsFree(*key) == 0)
-+        return 0;
-+
-+    return 1;
-+}
-+
-+CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
-+{
-+    return GetCurrentThreadId();
-+}
-+
-+int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
-+{
-+    return (a == b);
-+}
-+
-+int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
-+{
-+    *ret = InterlockedExchangeAdd(val, amount) + amount;
-+    return 1;
-+}
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/build.info
-new file mode 100644
-index 0000000..98e633d
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/build.info
-@@ -0,0 +1,5 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        ts_err.c ts_req_utils.c ts_req_print.c ts_rsp_utils.c ts_rsp_print.c \
-+        ts_rsp_sign.c ts_rsp_verify.c ts_verify_ctx.c ts_lib.c ts_conf.c \
-+        ts_asn1.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_asn1.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_asn1.c
-new file mode 100644
-index 0000000..e60675a
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_asn1.c
-@@ -0,0 +1,259 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "ts_lcl.h"
-+
-+ASN1_SEQUENCE(TS_MSG_IMPRINT) = {
-+        ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR),
-+        ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING)
-+} static_ASN1_SEQUENCE_END(TS_MSG_IMPRINT)
-+
-+IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT)
-+IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT)
-+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a)
-+{
-+    return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new,
-+                           d2i_TS_MSG_IMPRINT, bp, a);
-+}
-+
-+int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a)
-+{
-+    return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a);
-+}
-+#ifndef OPENSSL_NO_STDIO
-+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a)
-+{
-+    return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new,
-+                          d2i_TS_MSG_IMPRINT, fp, a);
-+}
-+
-+int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a)
-+{
-+    return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a);
-+}
-+#endif
-+
-+ASN1_SEQUENCE(TS_REQ) = {
-+        ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER),
-+        ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT),
-+        ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT),
-+        ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER),
-+        ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN),
-+        ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0)
-+} static_ASN1_SEQUENCE_END(TS_REQ)
-+
-+IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ)
-+IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ)
-+TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a)
-+{
-+    return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a);
-+}
-+
-+int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a)
-+{
-+    return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a);
-+}
-+#ifndef OPENSSL_NO_STDIO
-+TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a)
-+{
-+    return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a);
-+}
-+
-+int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a)
-+{
-+    return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a);
-+}
-+#endif
-+
-+ASN1_SEQUENCE(TS_ACCURACY) = {
-+        ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER),
-+        ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0),
-+        ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1)
-+} static_ASN1_SEQUENCE_END(TS_ACCURACY)
-+
-+IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY)
-+IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY)
-+
-+ASN1_SEQUENCE(TS_TST_INFO) = {
-+        ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER),
-+        ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT),
-+        ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT),
-+        ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER),
-+        ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME),
-+        ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY),
-+        ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN),
-+        ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER),
-+        ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0),
-+        ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1)
-+} static_ASN1_SEQUENCE_END(TS_TST_INFO)
-+
-+IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO)
-+IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO)
-+TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a)
-+{
-+    return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp,
-+                           a);
-+}
-+
-+int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a)
-+{
-+    return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a);
-+}
-+#ifndef OPENSSL_NO_STDIO
-+TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a)
-+{
-+    return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp,
-+                          a);
-+}
-+
-+int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a)
-+{
-+    return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a);
-+}
-+#endif
-+
-+ASN1_SEQUENCE(TS_STATUS_INFO) = {
-+        ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER),
-+        ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING),
-+        ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING)
-+} static_ASN1_SEQUENCE_END(TS_STATUS_INFO)
-+
-+IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO)
-+IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO)
-+
-+static int ts_resp_set_tst_info(TS_RESP *a)
-+{
-+    long status;
-+
-+    status = ASN1_INTEGER_get(a->status_info->status);
-+
-+    if (a->token) {
-+        if (status != 0 && status != 1) {
-+            TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT);
-+            return 0;
-+        }
-+        TS_TST_INFO_free(a->tst_info);
-+        a->tst_info = PKCS7_to_TS_TST_INFO(a->token);
-+        if (!a->tst_info) {
-+            TSerr(TS_F_TS_RESP_SET_TST_INFO,
-+                  TS_R_PKCS7_TO_TS_TST_INFO_FAILED);
-+            return 0;
-+        }
-+    } else if (status == 0 || status == 1) {
-+        TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it,
-+                      void *exarg)
-+{
-+    TS_RESP *ts_resp = (TS_RESP *)*pval;
-+    if (op == ASN1_OP_NEW_POST) {
-+        ts_resp->tst_info = NULL;
-+    } else if (op == ASN1_OP_FREE_POST) {
-+        TS_TST_INFO_free(ts_resp->tst_info);
-+    } else if (op == ASN1_OP_D2I_POST) {
-+        if (ts_resp_set_tst_info(ts_resp) == 0)
-+            return 0;
-+    }
-+    return 1;
-+}
-+
-+ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = {
-+        ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO),
-+        ASN1_OPT(TS_RESP, token, PKCS7),
-+} static_ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP)
-+
-+IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP)
-+
-+IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP)
-+
-+TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a)
-+{
-+    return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a);
-+}
-+
-+int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a)
-+{
-+    return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a);
-+}
-+#ifndef OPENSSL_NO_STDIO
-+TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a)
-+{
-+    return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a);
-+}
-+
-+int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a)
-+{
-+    return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a);
-+}
-+#endif
-+
-+ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = {
-+        ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME),
-+        ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER)
-+} static_ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL)
-+
-+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL)
-+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL)
-+
-+ASN1_SEQUENCE(ESS_CERT_ID) = {
-+        ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING),
-+        ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL)
-+} static_ASN1_SEQUENCE_END(ESS_CERT_ID)
-+
-+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID)
-+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID)
-+
-+ASN1_SEQUENCE(ESS_SIGNING_CERT) = {
-+        ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID),
-+        ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO)
-+} static_ASN1_SEQUENCE_END(ESS_SIGNING_CERT)
-+
-+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT)
-+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT)
-+
-+/* Getting encapsulated TS_TST_INFO object from PKCS7. */
-+TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token)
-+{
-+    PKCS7_SIGNED *pkcs7_signed;
-+    PKCS7 *enveloped;
-+    ASN1_TYPE *tst_info_wrapper;
-+    ASN1_OCTET_STRING *tst_info_der;
-+    const unsigned char *p;
-+
-+    if (!PKCS7_type_is_signed(token)) {
-+        TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
-+        return NULL;
-+    }
-+    if (PKCS7_get_detached(token)) {
-+        TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT);
-+        return NULL;
-+    }
-+    pkcs7_signed = token->d.sign;
-+    enveloped = pkcs7_signed->contents;
-+    if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo) {
-+        TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
-+        return NULL;
-+    }
-+    tst_info_wrapper = enveloped->d.other;
-+    if (tst_info_wrapper->type != V_ASN1_OCTET_STRING) {
-+        TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE);
-+        return NULL;
-+    }
-+    tst_info_der = tst_info_wrapper->value.octet_string;
-+    p = tst_info_der->data;
-+    return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_conf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_conf.c
-new file mode 100644
-index 0000000..f5f3934
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_conf.c
-@@ -0,0 +1,468 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+
-+/* Macro definitions for the configuration file. */
-+#define BASE_SECTION                    "tsa"
-+#define ENV_DEFAULT_TSA                 "default_tsa"
-+#define ENV_SERIAL                      "serial"
-+#define ENV_CRYPTO_DEVICE               "crypto_device"
-+#define ENV_SIGNER_CERT                 "signer_cert"
-+#define ENV_CERTS                       "certs"
-+#define ENV_SIGNER_KEY                  "signer_key"
-+#define ENV_SIGNER_DIGEST               "signer_digest"
-+#define ENV_DEFAULT_POLICY              "default_policy"
-+#define ENV_OTHER_POLICIES              "other_policies"
-+#define ENV_DIGESTS                     "digests"
-+#define ENV_ACCURACY                    "accuracy"
-+#define ENV_ORDERING                    "ordering"
-+#define ENV_TSA_NAME                    "tsa_name"
-+#define ENV_ESS_CERT_ID_CHAIN           "ess_cert_id_chain"
-+#define ENV_VALUE_SECS                  "secs"
-+#define ENV_VALUE_MILLISECS             "millisecs"
-+#define ENV_VALUE_MICROSECS             "microsecs"
-+#define ENV_CLOCK_PRECISION_DIGITS      "clock_precision_digits"
-+#define ENV_VALUE_YES                   "yes"
-+#define ENV_VALUE_NO                    "no"
-+
-+/* Function definitions for certificate and key loading. */
-+
-+X509 *TS_CONF_load_cert(const char *file)
-+{
-+    BIO *cert = NULL;
-+    X509 *x = NULL;
-+
-+    if ((cert = BIO_new_file(file, "r")) == NULL)
-+        goto end;
-+    x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
-+ end:
-+    if (x == NULL)
-+        TSerr(TS_F_TS_CONF_LOAD_CERT, TS_R_CANNOT_LOAD_CERT);
-+    BIO_free(cert);
-+    return x;
-+}
-+
-+STACK_OF(X509) *TS_CONF_load_certs(const char *file)
-+{
-+    BIO *certs = NULL;
-+    STACK_OF(X509) *othercerts = NULL;
-+    STACK_OF(X509_INFO) *allcerts = NULL;
-+    int i;
-+
-+    if ((certs = BIO_new_file(file, "r")) == NULL)
-+        goto end;
-+    if ((othercerts = sk_X509_new_null()) == NULL)
-+        goto end;
-+
-+    allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
-+    for (i = 0; i < sk_X509_INFO_num(allcerts); i++) {
-+        X509_INFO *xi = sk_X509_INFO_value(allcerts, i);
-+        if (xi->x509) {
-+            sk_X509_push(othercerts, xi->x509);
-+            xi->x509 = NULL;
-+        }
-+    }
-+ end:
-+    if (othercerts == NULL)
-+        TSerr(TS_F_TS_CONF_LOAD_CERTS, TS_R_CANNOT_LOAD_CERT);
-+    sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
-+    BIO_free(certs);
-+    return othercerts;
-+}
-+
-+EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass)
-+{
-+    BIO *key = NULL;
-+    EVP_PKEY *pkey = NULL;
-+
-+    if ((key = BIO_new_file(file, "r")) == NULL)
-+        goto end;
-+    pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *)pass);
-+ end:
-+    if (pkey == NULL)
-+        TSerr(TS_F_TS_CONF_LOAD_KEY, TS_R_CANNOT_LOAD_KEY);
-+    BIO_free(key);
-+    return pkey;
-+}
-+
-+/* Function definitions for handling configuration options. */
-+
-+static void ts_CONF_lookup_fail(const char *name, const char *tag)
-+{
-+    TSerr(TS_F_TS_CONF_LOOKUP_FAIL, TS_R_VAR_LOOKUP_FAILURE);
-+    ERR_add_error_data(3, name, "::", tag);
-+}
-+
-+static void ts_CONF_invalid(const char *name, const char *tag)
-+{
-+    TSerr(TS_F_TS_CONF_INVALID, TS_R_VAR_BAD_VALUE);
-+    ERR_add_error_data(3, name, "::", tag);
-+}
-+
-+const char *TS_CONF_get_tsa_section(CONF *conf, const char *section)
-+{
-+    if (!section) {
-+        section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA);
-+        if (!section)
-+            ts_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA);
-+    }
-+    return section;
-+}
-+
-+int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
-+                       TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    char *serial = NCONF_get_string(conf, section, ENV_SERIAL);
-+    if (!serial) {
-+        ts_CONF_lookup_fail(section, ENV_SERIAL);
-+        goto err;
-+    }
-+    TS_RESP_CTX_set_serial_cb(ctx, cb, serial);
-+
-+    ret = 1;
-+ err:
-+    return ret;
-+}
-+
-+#ifndef OPENSSL_NO_ENGINE
-+
-+int TS_CONF_set_crypto_device(CONF *conf, const char *section,
-+                              const char *device)
-+{
-+    int ret = 0;
-+
-+    if (device == NULL)
-+        device = NCONF_get_string(conf, section, ENV_CRYPTO_DEVICE);
-+
-+    if (device && !TS_CONF_set_default_engine(device)) {
-+        ts_CONF_invalid(section, ENV_CRYPTO_DEVICE);
-+        goto err;
-+    }
-+    ret = 1;
-+ err:
-+    return ret;
-+}
-+
-+int TS_CONF_set_default_engine(const char *name)
-+{
-+    ENGINE *e = NULL;
-+    int ret = 0;
-+
-+    if (strcmp(name, "builtin") == 0)
-+        return 1;
-+
-+    if ((e = ENGINE_by_id(name)) == NULL)
-+        goto err;
-+    if (strcmp(name, "chil") == 0)
-+        ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
-+    if (!ENGINE_set_default(e, ENGINE_METHOD_ALL))
-+        goto err;
-+    ret = 1;
-+
-+ err:
-+    if (!ret) {
-+        TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, TS_R_COULD_NOT_SET_ENGINE);
-+        ERR_add_error_data(2, "engine:", name);
-+    }
-+    ENGINE_free(e);
-+    return ret;
-+}
-+
-+#endif
-+
-+int TS_CONF_set_signer_cert(CONF *conf, const char *section,
-+                            const char *cert, TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    X509 *cert_obj = NULL;
-+
-+    if (cert == NULL) {
-+        cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT);
-+        if (cert == NULL) {
-+            ts_CONF_lookup_fail(section, ENV_SIGNER_CERT);
-+            goto err;
-+        }
-+    }
-+    if ((cert_obj = TS_CONF_load_cert(cert)) == NULL)
-+        goto err;
-+    if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    X509_free(cert_obj);
-+    return ret;
-+}
-+
-+int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
-+                      TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    STACK_OF(X509) *certs_obj = NULL;
-+
-+    if (certs == NULL) {
-+        /* Certificate chain is optional. */
-+        if ((certs = NCONF_get_string(conf, section, ENV_CERTS)) == NULL)
-+            goto end;
-+    }
-+    if ((certs_obj = TS_CONF_load_certs(certs)) == NULL)
-+        goto err;
-+    if (!TS_RESP_CTX_set_certs(ctx, certs_obj))
-+        goto err;
-+ end:
-+    ret = 1;
-+ err:
-+    sk_X509_pop_free(certs_obj, X509_free);
-+    return ret;
-+}
-+
-+int TS_CONF_set_signer_key(CONF *conf, const char *section,
-+                           const char *key, const char *pass,
-+                           TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    EVP_PKEY *key_obj = NULL;
-+    if (!key)
-+        key = NCONF_get_string(conf, section, ENV_SIGNER_KEY);
-+    if (!key) {
-+        ts_CONF_lookup_fail(section, ENV_SIGNER_KEY);
-+        goto err;
-+    }
-+    if ((key_obj = TS_CONF_load_key(key, pass)) == NULL)
-+        goto err;
-+    if (!TS_RESP_CTX_set_signer_key(ctx, key_obj))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    EVP_PKEY_free(key_obj);
-+    return ret;
-+}
-+
-+int TS_CONF_set_signer_digest(CONF *conf, const char *section,
-+                              const char *md, TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    const EVP_MD *sign_md = NULL;
-+    if (md == NULL)
-+        md = NCONF_get_string(conf, section, ENV_SIGNER_DIGEST);
-+    if (md == NULL) {
-+        ts_CONF_lookup_fail(section, ENV_SIGNER_DIGEST);
-+        goto err;
-+    }
-+    sign_md = EVP_get_digestbyname(md);
-+    if (sign_md == NULL) {
-+        ts_CONF_invalid(section, ENV_SIGNER_DIGEST);
-+        goto err;
-+    }
-+    if (!TS_RESP_CTX_set_signer_digest(ctx, sign_md))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    return ret;
-+}
-+
-+int TS_CONF_set_def_policy(CONF *conf, const char *section,
-+                           const char *policy, TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    ASN1_OBJECT *policy_obj = NULL;
-+    if (!policy)
-+        policy = NCONF_get_string(conf, section, ENV_DEFAULT_POLICY);
-+    if (!policy) {
-+        ts_CONF_lookup_fail(section, ENV_DEFAULT_POLICY);
-+        goto err;
-+    }
-+    if ((policy_obj = OBJ_txt2obj(policy, 0)) == NULL) {
-+        ts_CONF_invalid(section, ENV_DEFAULT_POLICY);
-+        goto err;
-+    }
-+    if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    ASN1_OBJECT_free(policy_obj);
-+    return ret;
-+}
-+
-+int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    int i;
-+    STACK_OF(CONF_VALUE) *list = NULL;
-+    char *policies = NCONF_get_string(conf, section, ENV_OTHER_POLICIES);
-+
-+    /* If no other policy is specified, that's fine. */
-+    if (policies && (list = X509V3_parse_list(policies)) == NULL) {
-+        ts_CONF_invalid(section, ENV_OTHER_POLICIES);
-+        goto err;
-+    }
-+    for (i = 0; i < sk_CONF_VALUE_num(list); ++i) {
-+        CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
-+        const char *extval = val->value ? val->value : val->name;
-+        ASN1_OBJECT *objtmp;
-+
-+        if ((objtmp = OBJ_txt2obj(extval, 0)) == NULL) {
-+            ts_CONF_invalid(section, ENV_OTHER_POLICIES);
-+            goto err;
-+        }
-+        if (!TS_RESP_CTX_add_policy(ctx, objtmp))
-+            goto err;
-+        ASN1_OBJECT_free(objtmp);
-+    }
-+
-+    ret = 1;
-+ err:
-+    sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
-+    return ret;
-+}
-+
-+int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    int i;
-+    STACK_OF(CONF_VALUE) *list = NULL;
-+    char *digests = NCONF_get_string(conf, section, ENV_DIGESTS);
-+
-+    if (digests == NULL) {
-+        ts_CONF_lookup_fail(section, ENV_DIGESTS);
-+        goto err;
-+    }
-+    if ((list = X509V3_parse_list(digests)) == NULL) {
-+        ts_CONF_invalid(section, ENV_DIGESTS);
-+        goto err;
-+    }
-+    if (sk_CONF_VALUE_num(list) == 0) {
-+        ts_CONF_invalid(section, ENV_DIGESTS);
-+        goto err;
-+    }
-+    for (i = 0; i < sk_CONF_VALUE_num(list); ++i) {
-+        CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
-+        const char *extval = val->value ? val->value : val->name;
-+        const EVP_MD *md;
-+
-+        if ((md = EVP_get_digestbyname(extval)) == NULL) {
-+            ts_CONF_invalid(section, ENV_DIGESTS);
-+            goto err;
-+        }
-+        if (!TS_RESP_CTX_add_md(ctx, md))
-+            goto err;
-+    }
-+
-+    ret = 1;
-+ err:
-+    sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
-+    return ret;
-+}
-+
-+int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    int i;
-+    int secs = 0, millis = 0, micros = 0;
-+    STACK_OF(CONF_VALUE) *list = NULL;
-+    char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY);
-+
-+    if (accuracy && (list = X509V3_parse_list(accuracy)) == NULL) {
-+        ts_CONF_invalid(section, ENV_ACCURACY);
-+        goto err;
-+    }
-+    for (i = 0; i < sk_CONF_VALUE_num(list); ++i) {
-+        CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
-+        if (strcmp(val->name, ENV_VALUE_SECS) == 0) {
-+            if (val->value)
-+                secs = atoi(val->value);
-+        } else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) {
-+            if (val->value)
-+                millis = atoi(val->value);
-+        } else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) {
-+            if (val->value)
-+                micros = atoi(val->value);
-+        } else {
-+            ts_CONF_invalid(section, ENV_ACCURACY);
-+            goto err;
-+        }
-+    }
-+    if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros))
-+        goto err;
-+
-+    ret = 1;
-+ err:
-+    sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
-+    return ret;
-+}
-+
-+int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
-+                                       TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    long digits = 0;
-+
-+    /*
-+     * If not specified, set the default value to 0, i.e. sec precision
-+     */
-+    if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS,
-+                            &digits))
-+        digits = 0;
-+    if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS) {
-+        ts_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS);
-+        goto err;
-+    }
-+
-+    if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits))
-+        goto err;
-+
-+    return 1;
-+ err:
-+    return ret;
-+}
-+
-+static int ts_CONF_add_flag(CONF *conf, const char *section,
-+                            const char *field, int flag, TS_RESP_CTX *ctx)
-+{
-+    const char *value = NCONF_get_string(conf, section, field);
-+
-+    if (value) {
-+        if (strcmp(value, ENV_VALUE_YES) == 0)
-+            TS_RESP_CTX_add_flags(ctx, flag);
-+        else if (strcmp(value, ENV_VALUE_NO) != 0) {
-+            ts_CONF_invalid(section, field);
-+            return 0;
-+        }
-+    }
-+
-+    return 1;
-+}
-+
-+int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx)
-+{
-+    return ts_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx);
-+}
-+
-+int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx)
-+{
-+    return ts_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx);
-+}
-+
-+int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
-+                                  TS_RESP_CTX *ctx)
-+{
-+    return ts_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN,
-+                            TS_ESS_CERT_ID_CHAIN, ctx);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_err.c
-new file mode 100644
-index 0000000..a6d73a1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_err.c
-@@ -0,0 +1,144 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason)
-+
-+static ERR_STRING_DATA TS_str_functs[] = {
-+    {ERR_FUNC(TS_F_DEF_SERIAL_CB), "def_serial_cb"},
-+    {ERR_FUNC(TS_F_DEF_TIME_CB), "def_time_cb"},
-+    {ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT), "ESS_add_signing_cert"},
-+    {ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT), "ess_CERT_ID_new_init"},
-+    {ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT), "ess_SIGNING_CERT_new_init"},
-+    {ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN), "int_ts_RESP_verify_token"},
-+    {ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO), "PKCS7_to_TS_TST_INFO"},
-+    {ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS), "TS_ACCURACY_set_micros"},
-+    {ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS), "TS_ACCURACY_set_millis"},
-+    {ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS), "TS_ACCURACY_set_seconds"},
-+    {ERR_FUNC(TS_F_TS_CHECK_IMPRINTS), "ts_check_imprints"},
-+    {ERR_FUNC(TS_F_TS_CHECK_NONCES), "ts_check_nonces"},
-+    {ERR_FUNC(TS_F_TS_CHECK_POLICY), "ts_check_policy"},
-+    {ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS), "ts_check_signing_certs"},
-+    {ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO), "ts_check_status_info"},
-+    {ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT), "ts_compute_imprint"},
-+    {ERR_FUNC(TS_F_TS_CONF_INVALID), "ts_CONF_invalid"},
-+    {ERR_FUNC(TS_F_TS_CONF_LOAD_CERT), "TS_CONF_load_cert"},
-+    {ERR_FUNC(TS_F_TS_CONF_LOAD_CERTS), "TS_CONF_load_certs"},
-+    {ERR_FUNC(TS_F_TS_CONF_LOAD_KEY), "TS_CONF_load_key"},
-+    {ERR_FUNC(TS_F_TS_CONF_LOOKUP_FAIL), "ts_CONF_lookup_fail"},
-+    {ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE), "TS_CONF_set_default_engine"},
-+    {ERR_FUNC(TS_F_TS_GET_STATUS_TEXT), "ts_get_status_text"},
-+    {ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO), "TS_MSG_IMPRINT_set_algo"},
-+    {ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT), "TS_REQ_set_msg_imprint"},
-+    {ERR_FUNC(TS_F_TS_REQ_SET_NONCE), "TS_REQ_set_nonce"},
-+    {ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID), "TS_REQ_set_policy_id"},
-+    {ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE), "TS_RESP_create_response"},
-+    {ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO), "ts_RESP_create_tst_info"},
-+    {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO),
-+     "TS_RESP_CTX_add_failure_info"},
-+    {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD), "TS_RESP_CTX_add_md"},
-+    {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY), "TS_RESP_CTX_add_policy"},
-+    {ERR_FUNC(TS_F_TS_RESP_CTX_NEW), "TS_RESP_CTX_new"},
-+    {ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY), "TS_RESP_CTX_set_accuracy"},
-+    {ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS), "TS_RESP_CTX_set_certs"},
-+    {ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY), "TS_RESP_CTX_set_def_policy"},
-+    {ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT),
-+     "TS_RESP_CTX_set_signer_cert"},
-+    {ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO),
-+     "TS_RESP_CTX_set_status_info"},
-+    {ERR_FUNC(TS_F_TS_RESP_GET_POLICY), "ts_RESP_get_policy"},
-+    {ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION),
-+     "TS_RESP_set_genTime_with_precision"},
-+    {ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO), "TS_RESP_set_status_info"},
-+    {ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO), "TS_RESP_set_tst_info"},
-+    {ERR_FUNC(TS_F_TS_RESP_SIGN), "ts_RESP_sign"},
-+    {ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE), "TS_RESP_verify_signature"},
-+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY), "TS_TST_INFO_set_accuracy"},
-+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT),
-+     "TS_TST_INFO_set_msg_imprint"},
-+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE), "TS_TST_INFO_set_nonce"},
-+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID), "TS_TST_INFO_set_policy_id"},
-+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL), "TS_TST_INFO_set_serial"},
-+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME), "TS_TST_INFO_set_time"},
-+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA), "TS_TST_INFO_set_tsa"},
-+    {ERR_FUNC(TS_F_TS_VERIFY), "TS_VERIFY"},
-+    {ERR_FUNC(TS_F_TS_VERIFY_CERT), "ts_verify_cert"},
-+    {ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW), "TS_VERIFY_CTX_new"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA TS_str_reasons[] = {
-+    {ERR_REASON(TS_R_BAD_PKCS7_TYPE), "bad pkcs7 type"},
-+    {ERR_REASON(TS_R_BAD_TYPE), "bad type"},
-+    {ERR_REASON(TS_R_CANNOT_LOAD_CERT), "cannot load certificate"},
-+    {ERR_REASON(TS_R_CANNOT_LOAD_KEY), "cannot load private key"},
-+    {ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
-+    {ERR_REASON(TS_R_COULD_NOT_SET_ENGINE), "could not set engine"},
-+    {ERR_REASON(TS_R_COULD_NOT_SET_TIME), "could not set time"},
-+    {ERR_REASON(TS_R_DETACHED_CONTENT), "detached content"},
-+    {ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),
-+     "ess add signing cert error"},
-+    {ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),
-+     "ess signing certificate error"},
-+    {ERR_REASON(TS_R_INVALID_NULL_POINTER), "invalid null pointer"},
-+    {ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE),
-+     "invalid signer certificate purpose"},
-+    {ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH), "message imprint mismatch"},
-+    {ERR_REASON(TS_R_NONCE_MISMATCH), "nonce mismatch"},
-+    {ERR_REASON(TS_R_NONCE_NOT_RETURNED), "nonce not returned"},
-+    {ERR_REASON(TS_R_NO_CONTENT), "no content"},
-+    {ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN), "no time stamp token"},
-+    {ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR), "pkcs7 add signature error"},
-+    {ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR),
-+     "pkcs7 add signed attr error"},
-+    {ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED),
-+     "pkcs7 to ts tst info failed"},
-+    {ERR_REASON(TS_R_POLICY_MISMATCH), "policy mismatch"},
-+    {ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
-+     "private key does not match certificate"},
-+    {ERR_REASON(TS_R_RESPONSE_SETUP_ERROR), "response setup error"},
-+    {ERR_REASON(TS_R_SIGNATURE_FAILURE), "signature failure"},
-+    {ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER), "there must be one signer"},
-+    {ERR_REASON(TS_R_TIME_SYSCALL_ERROR), "time syscall error"},
-+    {ERR_REASON(TS_R_TOKEN_NOT_PRESENT), "token not present"},
-+    {ERR_REASON(TS_R_TOKEN_PRESENT), "token present"},
-+    {ERR_REASON(TS_R_TSA_NAME_MISMATCH), "tsa name mismatch"},
-+    {ERR_REASON(TS_R_TSA_UNTRUSTED), "tsa untrusted"},
-+    {ERR_REASON(TS_R_TST_INFO_SETUP_ERROR), "tst info setup error"},
-+    {ERR_REASON(TS_R_TS_DATASIGN), "ts datasign"},
-+    {ERR_REASON(TS_R_UNACCEPTABLE_POLICY), "unacceptable policy"},
-+    {ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM), "unsupported md algorithm"},
-+    {ERR_REASON(TS_R_UNSUPPORTED_VERSION), "unsupported version"},
-+    {ERR_REASON(TS_R_VAR_BAD_VALUE), "var bad value"},
-+    {ERR_REASON(TS_R_VAR_LOOKUP_FAILURE), "cannot find config variable"},
-+    {ERR_REASON(TS_R_WRONG_CONTENT_TYPE), "wrong content type"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_TS_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(TS_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, TS_str_functs);
-+        ERR_load_strings(0, TS_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_lcl.h
-new file mode 100644
-index 0000000..d0c3cf8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_lcl.h
-@@ -0,0 +1,183 @@
-+/*
-+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/*-
-+ * MessageImprint ::= SEQUENCE  {
-+ *      hashAlgorithm                AlgorithmIdentifier,
-+ *      hashedMessage                OCTET STRING  }
-+ */
-+struct TS_msg_imprint_st {
-+    X509_ALGOR *hash_algo;
-+    ASN1_OCTET_STRING *hashed_msg;
-+};
-+
-+/*-
-+ * TimeStampResp ::= SEQUENCE  {
-+ *     status                  PKIStatusInfo,
-+ *     timeStampToken          TimeStampToken     OPTIONAL }
-+ */
-+struct TS_resp_st {
-+    TS_STATUS_INFO *status_info;
-+    PKCS7 *token;
-+    TS_TST_INFO *tst_info;
-+};
-+
-+/*-
-+ * TimeStampReq ::= SEQUENCE  {
-+ *    version                  INTEGER  { v1(1) },
-+ *    messageImprint           MessageImprint,
-+ *      --a hash algorithm OID and the hash value of the data to be
-+ *      --time-stamped
-+ *    reqPolicy                TSAPolicyId                OPTIONAL,
-+ *    nonce                    INTEGER                    OPTIONAL,
-+ *    certReq                  BOOLEAN                    DEFAULT FALSE,
-+ *    extensions               [0] IMPLICIT Extensions    OPTIONAL  }
-+ */
-+struct TS_req_st {
-+    ASN1_INTEGER *version;
-+    TS_MSG_IMPRINT *msg_imprint;
-+    ASN1_OBJECT *policy_id;
-+    ASN1_INTEGER *nonce;
-+    ASN1_BOOLEAN cert_req;
-+    STACK_OF(X509_EXTENSION) *extensions;
-+};
-+
-+/*-
-+ * Accuracy ::= SEQUENCE {
-+ *                 seconds        INTEGER           OPTIONAL,
-+ *                 millis     [0] INTEGER  (1..999) OPTIONAL,
-+ *                 micros     [1] INTEGER  (1..999) OPTIONAL  }
-+ */
-+struct TS_accuracy_st {
-+    ASN1_INTEGER *seconds;
-+    ASN1_INTEGER *millis;
-+    ASN1_INTEGER *micros;
-+};
-+
-+/*-
-+ * TSTInfo ::= SEQUENCE  {
-+ *     version                      INTEGER  { v1(1) },
-+ *     policy                       TSAPolicyId,
-+ *     messageImprint               MessageImprint,
-+ *       -- MUST have the same value as the similar field in
-+ *       -- TimeStampReq
-+ *     serialNumber                 INTEGER,
-+ *      -- Time-Stamping users MUST be ready to accommodate integers
-+ *      -- up to 160 bits.
-+ *     genTime                      GeneralizedTime,
-+ *     accuracy                     Accuracy                 OPTIONAL,
-+ *     ordering                     BOOLEAN             DEFAULT FALSE,
-+ *     nonce                        INTEGER                  OPTIONAL,
-+ *       -- MUST be present if the similar field was present
-+ *       -- in TimeStampReq.  In that case it MUST have the same value.
-+ *     tsa                          [0] GeneralName          OPTIONAL,
-+ *     extensions                   [1] IMPLICIT Extensions  OPTIONAL   }
-+ */
-+struct TS_tst_info_st {
-+    ASN1_INTEGER *version;
-+    ASN1_OBJECT *policy_id;
-+    TS_MSG_IMPRINT *msg_imprint;
-+    ASN1_INTEGER *serial;
-+    ASN1_GENERALIZEDTIME *time;
-+    TS_ACCURACY *accuracy;
-+    ASN1_BOOLEAN ordering;
-+    ASN1_INTEGER *nonce;
-+    GENERAL_NAME *tsa;
-+    STACK_OF(X509_EXTENSION) *extensions;
-+};
-+
-+struct TS_status_info_st {
-+    ASN1_INTEGER *status;
-+    STACK_OF(ASN1_UTF8STRING) *text;
-+    ASN1_BIT_STRING *failure_info;
-+};
-+
-+/*-
-+ * IssuerSerial ::= SEQUENCE {
-+ *         issuer                   GeneralNames,
-+ *         serialNumber             CertificateSerialNumber
-+ *         }
-+ */
-+struct ESS_issuer_serial {
-+    STACK_OF(GENERAL_NAME) *issuer;
-+    ASN1_INTEGER *serial;
-+};
-+
-+/*-
-+ * ESSCertID ::=  SEQUENCE {
-+ *         certHash                 Hash,
-+ *         issuerSerial             IssuerSerial OPTIONAL
-+ * }
-+ */
-+struct ESS_cert_id {
-+    ASN1_OCTET_STRING *hash;    /* Always SHA-1 digest. */
-+    ESS_ISSUER_SERIAL *issuer_serial;
-+};
-+
-+/*-
-+ * SigningCertificate ::=  SEQUENCE {
-+ *        certs        SEQUENCE OF ESSCertID,
-+ *        policies     SEQUENCE OF PolicyInformation OPTIONAL
-+ * }
-+ */
-+struct ESS_signing_cert {
-+    STACK_OF(ESS_CERT_ID) *cert_ids;
-+    STACK_OF(POLICYINFO) *policy_info;
-+};
-+
-+
-+struct TS_resp_ctx {
-+    X509 *signer_cert;
-+    EVP_PKEY *signer_key;
-+    const EVP_MD *signer_md;
-+    STACK_OF(X509) *certs;      /* Certs to include in signed data. */
-+    STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */
-+    ASN1_OBJECT *default_policy; /* It may appear in policies, too. */
-+    STACK_OF(EVP_MD) *mds;      /* Acceptable message digests. */
-+    ASN1_INTEGER *seconds;      /* accuracy, 0 means not specified. */
-+    ASN1_INTEGER *millis;       /* accuracy, 0 means not specified. */
-+    ASN1_INTEGER *micros;       /* accuracy, 0 means not specified. */
-+    unsigned clock_precision_digits; /* fraction of seconds in time stamp
-+                                      * token. */
-+    unsigned flags;             /* Optional info, see values above. */
-+    /* Callback functions. */
-+    TS_serial_cb serial_cb;
-+    void *serial_cb_data;       /* User data for serial_cb. */
-+    TS_time_cb time_cb;
-+    void *time_cb_data;         /* User data for time_cb. */
-+    TS_extension_cb extension_cb;
-+    void *extension_cb_data;    /* User data for extension_cb. */
-+    /* These members are used only while creating the response. */
-+    TS_REQ *request;
-+    TS_RESP *response;
-+    TS_TST_INFO *tst_info;
-+};
-+
-+struct TS_verify_ctx {
-+    /* Set this to the union of TS_VFY_... flags you want to carry out. */
-+    unsigned flags;
-+    /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */
-+    X509_STORE *store;
-+    STACK_OF(X509) *certs;
-+    /* Must be set only with TS_VFY_POLICY. */
-+    ASN1_OBJECT *policy;
-+    /*
-+     * Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, the
-+     * algorithm from the response is used.
-+     */
-+    X509_ALGOR *md_alg;
-+    unsigned char *imprint;
-+    unsigned imprint_len;
-+    /* Must be set only with TS_VFY_DATA. */
-+    BIO *data;
-+    /* Must be set only with TS_VFY_TSA_NAME. */
-+    ASN1_INTEGER *nonce;
-+    /* Must be set only with TS_VFY_TSA_NAME. */
-+    GENERAL_NAME *tsa_name;
-+};
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_lib.c
-new file mode 100644
-index 0000000..de36e0e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_lib.c
-@@ -0,0 +1,93 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "ts_lcl.h"
-+
-+int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num)
-+{
-+    BIGNUM *num_bn;
-+    int result = 0;
-+    char *hex;
-+
-+    num_bn = BN_new();
-+    if (num_bn == NULL)
-+        return -1;
-+    ASN1_INTEGER_to_BN(num, num_bn);
-+    if ((hex = BN_bn2hex(num_bn))) {
-+        result = BIO_write(bio, "0x", 2) > 0;
-+        result = result && BIO_write(bio, hex, strlen(hex)) > 0;
-+        OPENSSL_free(hex);
-+    }
-+    BN_free(num_bn);
-+
-+    return result;
-+}
-+
-+int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj)
-+{
-+    char obj_txt[128];
-+
-+    OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
-+    BIO_printf(bio, "%s\n", obj_txt);
-+
-+    return 1;
-+}
-+
-+int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions)
-+{
-+    int i, critical, n;
-+    X509_EXTENSION *ex;
-+    ASN1_OBJECT *obj;
-+
-+    BIO_printf(bio, "Extensions:\n");
-+    n = X509v3_get_ext_count(extensions);
-+    for (i = 0; i < n; i++) {
-+        ex = X509v3_get_ext(extensions, i);
-+        obj = X509_EXTENSION_get_object(ex);
-+        if (i2a_ASN1_OBJECT(bio, obj) < 0)
-+            return 0;
-+        critical = X509_EXTENSION_get_critical(ex);
-+        BIO_printf(bio, ":%s\n", critical ? " critical" : "");
-+        if (!X509V3_EXT_print(bio, ex, 0, 4)) {
-+            BIO_printf(bio, "%4s", "");
-+            ASN1_STRING_print(bio, X509_EXTENSION_get_data(ex));
-+        }
-+        BIO_write(bio, "\n", 1);
-+    }
-+
-+    return 1;
-+}
-+
-+int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg)
-+{
-+    int i = OBJ_obj2nid(alg->algorithm);
-+    return BIO_printf(bio, "Hash Algorithm: %s\n",
-+                      (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
-+}
-+
-+int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a)
-+{
-+    ASN1_OCTET_STRING *msg;
-+
-+    TS_X509_ALGOR_print_bio(bio, a->hash_algo);
-+
-+    BIO_printf(bio, "Message data:\n");
-+    msg = a->hashed_msg;
-+    BIO_dump_indent(bio, (const char *)ASN1_STRING_get0_data(msg),
-+                    ASN1_STRING_length(msg), 4);
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_req_print.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_req_print.c
-new file mode 100644
-index 0000000..0dedf47
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_req_print.c
-@@ -0,0 +1,51 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "ts_lcl.h"
-+
-+int TS_REQ_print_bio(BIO *bio, TS_REQ *a)
-+{
-+    int v;
-+    ASN1_OBJECT *policy_id;
-+
-+    if (a == NULL)
-+        return 0;
-+
-+    v = TS_REQ_get_version(a);
-+    BIO_printf(bio, "Version: %d\n", v);
-+
-+    TS_MSG_IMPRINT_print_bio(bio, a->msg_imprint);
-+
-+    BIO_printf(bio, "Policy OID: ");
-+    policy_id = TS_REQ_get_policy_id(a);
-+    if (policy_id == NULL)
-+        BIO_printf(bio, "unspecified\n");
-+    else
-+        TS_OBJ_print_bio(bio, policy_id);
-+
-+    BIO_printf(bio, "Nonce: ");
-+    if (a->nonce == NULL)
-+        BIO_printf(bio, "unspecified");
-+    else
-+        TS_ASN1_INTEGER_print_bio(bio, a->nonce);
-+    BIO_write(bio, "\n", 1);
-+
-+    BIO_printf(bio, "Certificate required: %s\n",
-+               a->cert_req ? "yes" : "no");
-+
-+    TS_ext_print_bio(bio, a->extensions);
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_req_utils.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_req_utils.c
-new file mode 100644
-index 0000000..2073d33
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_req_utils.c
-@@ -0,0 +1,183 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "ts_lcl.h"
-+
-+int TS_REQ_set_version(TS_REQ *a, long version)
-+{
-+    return ASN1_INTEGER_set(a->version, version);
-+}
-+
-+long TS_REQ_get_version(const TS_REQ *a)
-+{
-+    return ASN1_INTEGER_get(a->version);
-+}
-+
-+int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint)
-+{
-+    TS_MSG_IMPRINT *new_msg_imprint;
-+
-+    if (a->msg_imprint == msg_imprint)
-+        return 1;
-+    new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
-+    if (new_msg_imprint == NULL) {
-+        TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    TS_MSG_IMPRINT_free(a->msg_imprint);
-+    a->msg_imprint = new_msg_imprint;
-+    return 1;
-+}
-+
-+TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a)
-+{
-+    return a->msg_imprint;
-+}
-+
-+int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg)
-+{
-+    X509_ALGOR *new_alg;
-+
-+    if (a->hash_algo == alg)
-+        return 1;
-+    new_alg = X509_ALGOR_dup(alg);
-+    if (new_alg == NULL) {
-+        TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    X509_ALGOR_free(a->hash_algo);
-+    a->hash_algo = new_alg;
-+    return 1;
-+}
-+
-+X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a)
-+{
-+    return a->hash_algo;
-+}
-+
-+int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len)
-+{
-+    return ASN1_OCTET_STRING_set(a->hashed_msg, d, len);
-+}
-+
-+ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a)
-+{
-+    return a->hashed_msg;
-+}
-+
-+int TS_REQ_set_policy_id(TS_REQ *a, const ASN1_OBJECT *policy)
-+{
-+    ASN1_OBJECT *new_policy;
-+
-+    if (a->policy_id == policy)
-+        return 1;
-+    new_policy = OBJ_dup(policy);
-+    if (new_policy == NULL) {
-+        TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ASN1_OBJECT_free(a->policy_id);
-+    a->policy_id = new_policy;
-+    return 1;
-+}
-+
-+ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a)
-+{
-+    return a->policy_id;
-+}
-+
-+int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce)
-+{
-+    ASN1_INTEGER *new_nonce;
-+
-+    if (a->nonce == nonce)
-+        return 1;
-+    new_nonce = ASN1_INTEGER_dup(nonce);
-+    if (new_nonce == NULL) {
-+        TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ASN1_INTEGER_free(a->nonce);
-+    a->nonce = new_nonce;
-+    return 1;
-+}
-+
-+const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a)
-+{
-+    return a->nonce;
-+}
-+
-+int TS_REQ_set_cert_req(TS_REQ *a, int cert_req)
-+{
-+    a->cert_req = cert_req ? 0xFF : 0x00;
-+    return 1;
-+}
-+
-+int TS_REQ_get_cert_req(const TS_REQ *a)
-+{
-+    return a->cert_req ? 1 : 0;
-+}
-+
-+STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a)
-+{
-+    return a->extensions;
-+}
-+
-+void TS_REQ_ext_free(TS_REQ *a)
-+{
-+    if (!a)
-+        return;
-+    sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
-+    a->extensions = NULL;
-+}
-+
-+int TS_REQ_get_ext_count(TS_REQ *a)
-+{
-+    return X509v3_get_ext_count(a->extensions);
-+}
-+
-+int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos)
-+{
-+    return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
-+}
-+
-+int TS_REQ_get_ext_by_OBJ(TS_REQ *a, const ASN1_OBJECT *obj, int lastpos)
-+{
-+    return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
-+}
-+
-+int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos)
-+{
-+    return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
-+}
-+
-+X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc)
-+{
-+    return X509v3_get_ext(a->extensions, loc);
-+}
-+
-+X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc)
-+{
-+    return X509v3_delete_ext(a->extensions, loc);
-+}
-+
-+int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc)
-+{
-+    return X509v3_add_ext(&a->extensions, ex, loc) != NULL;
-+}
-+
-+void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx)
-+{
-+    return X509V3_get_d2i(a->extensions, nid, crit, idx);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_print.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_print.c
-new file mode 100644
-index 0000000..6eb0ec8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_print.c
-@@ -0,0 +1,195 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "ts_lcl.h"
-+
-+struct status_map_st {
-+    int bit;
-+    const char *text;
-+};
-+
-+static int ts_status_map_print(BIO *bio, const struct status_map_st *a,
-+                               const ASN1_BIT_STRING *v);
-+static int ts_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy);
-+
-+
-+int TS_RESP_print_bio(BIO *bio, TS_RESP *a)
-+{
-+    BIO_printf(bio, "Status info:\n");
-+    TS_STATUS_INFO_print_bio(bio, a->status_info);
-+
-+    BIO_printf(bio, "\nTST info:\n");
-+    if (a->tst_info != NULL)
-+        TS_TST_INFO_print_bio(bio, a->tst_info);
-+    else
-+        BIO_printf(bio, "Not included.\n");
-+
-+    return 1;
-+}
-+
-+int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a)
-+{
-+    static const char *status_map[] = {
-+        "Granted.",
-+        "Granted with modifications.",
-+        "Rejected.",
-+        "Waiting.",
-+        "Revocation warning.",
-+        "Revoked."
-+    };
-+    static const struct status_map_st failure_map[] = {
-+        {TS_INFO_BAD_ALG,
-+         "unrecognized or unsupported algorithm identifier"},
-+        {TS_INFO_BAD_REQUEST,
-+         "transaction not permitted or supported"},
-+        {TS_INFO_BAD_DATA_FORMAT,
-+         "the data submitted has the wrong format"},
-+        {TS_INFO_TIME_NOT_AVAILABLE,
-+         "the TSA's time source is not available"},
-+        {TS_INFO_UNACCEPTED_POLICY,
-+         "the requested TSA policy is not supported by the TSA"},
-+        {TS_INFO_UNACCEPTED_EXTENSION,
-+         "the requested extension is not supported by the TSA"},
-+        {TS_INFO_ADD_INFO_NOT_AVAILABLE,
-+         "the additional information requested could not be understood "
-+         "or is not available"},
-+        {TS_INFO_SYSTEM_FAILURE,
-+         "the request cannot be handled due to system failure"},
-+        {-1, NULL}
-+    };
-+    long status;
-+    int i, lines = 0;
-+
-+    BIO_printf(bio, "Status: ");
-+    status = ASN1_INTEGER_get(a->status);
-+    if (0 <= status && status < (long)OSSL_NELEM(status_map))
-+        BIO_printf(bio, "%s\n", status_map[status]);
-+    else
-+        BIO_printf(bio, "out of bounds\n");
-+
-+    BIO_printf(bio, "Status description: ");
-+    for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i) {
-+        if (i > 0)
-+            BIO_puts(bio, "\t");
-+        ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i), 0);
-+        BIO_puts(bio, "\n");
-+    }
-+    if (i == 0)
-+        BIO_printf(bio, "unspecified\n");
-+
-+    BIO_printf(bio, "Failure info: ");
-+    if (a->failure_info != NULL)
-+        lines = ts_status_map_print(bio, failure_map, a->failure_info);
-+    if (lines == 0)
-+        BIO_printf(bio, "unspecified");
-+    BIO_printf(bio, "\n");
-+
-+    return 1;
-+}
-+
-+static int ts_status_map_print(BIO *bio, const struct status_map_st *a,
-+                               const ASN1_BIT_STRING *v)
-+{
-+    int lines = 0;
-+
-+    for (; a->bit >= 0; ++a) {
-+        if (ASN1_BIT_STRING_get_bit(v, a->bit)) {
-+            if (++lines > 1)
-+                BIO_printf(bio, ", ");
-+            BIO_printf(bio, "%s", a->text);
-+        }
-+    }
-+
-+    return lines;
-+}
-+
-+int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a)
-+{
-+    int v;
-+
-+    if (a == NULL)
-+        return 0;
-+
-+    v = ASN1_INTEGER_get(a->version);
-+    BIO_printf(bio, "Version: %d\n", v);
-+
-+    BIO_printf(bio, "Policy OID: ");
-+    TS_OBJ_print_bio(bio, a->policy_id);
-+
-+    TS_MSG_IMPRINT_print_bio(bio, a->msg_imprint);
-+
-+    BIO_printf(bio, "Serial number: ");
-+    if (a->serial == NULL)
-+        BIO_printf(bio, "unspecified");
-+    else
-+        TS_ASN1_INTEGER_print_bio(bio, a->serial);
-+    BIO_write(bio, "\n", 1);
-+
-+    BIO_printf(bio, "Time stamp: ");
-+    ASN1_GENERALIZEDTIME_print(bio, a->time);
-+    BIO_write(bio, "\n", 1);
-+
-+    BIO_printf(bio, "Accuracy: ");
-+    if (a->accuracy == NULL)
-+        BIO_printf(bio, "unspecified");
-+    else
-+        ts_ACCURACY_print_bio(bio, a->accuracy);
-+    BIO_write(bio, "\n", 1);
-+
-+    BIO_printf(bio, "Ordering: %s\n", a->ordering ? "yes" : "no");
-+
-+    BIO_printf(bio, "Nonce: ");
-+    if (a->nonce == NULL)
-+        BIO_printf(bio, "unspecified");
-+    else
-+        TS_ASN1_INTEGER_print_bio(bio, a->nonce);
-+    BIO_write(bio, "\n", 1);
-+
-+    BIO_printf(bio, "TSA: ");
-+    if (a->tsa == NULL)
-+        BIO_printf(bio, "unspecified");
-+    else {
-+        STACK_OF(CONF_VALUE) *nval;
-+        if ((nval = i2v_GENERAL_NAME(NULL, a->tsa, NULL)))
-+            X509V3_EXT_val_prn(bio, nval, 0, 0);
-+        sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
-+    }
-+    BIO_write(bio, "\n", 1);
-+
-+    TS_ext_print_bio(bio, a->extensions);
-+
-+    return 1;
-+}
-+
-+static int ts_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *a)
-+{
-+    if (a->seconds != NULL)
-+        TS_ASN1_INTEGER_print_bio(bio, a->seconds);
-+    else
-+        BIO_printf(bio, "unspecified");
-+    BIO_printf(bio, " seconds, ");
-+    if (a->millis != NULL)
-+        TS_ASN1_INTEGER_print_bio(bio, a->millis);
-+    else
-+        BIO_printf(bio, "unspecified");
-+    BIO_printf(bio, " millis, ");
-+    if (a->micros != NULL)
-+        TS_ASN1_INTEGER_print_bio(bio, a->micros);
-+    else
-+        BIO_printf(bio, "unspecified");
-+    BIO_printf(bio, " micros");
-+
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_sign.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_sign.c
-new file mode 100644
-index 0000000..aea7b92
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_sign.c
-@@ -0,0 +1,904 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+
-+#if defined(OPENSSL_SYS_UNIX)
-+# include 
-+#endif
-+
-+#include 
-+#include 
-+#include 
-+#include "ts_lcl.h"
-+
-+static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
-+static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
-+static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
-+
-+static void ts_RESP_CTX_init(TS_RESP_CTX *ctx);
-+static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
-+static int ts_RESP_check_request(TS_RESP_CTX *ctx);
-+static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx);
-+static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
-+                                            ASN1_OBJECT *policy);
-+static int ts_RESP_process_extensions(TS_RESP_CTX *ctx);
-+static int ts_RESP_sign(TS_RESP_CTX *ctx);
-+
-+static ESS_SIGNING_CERT *ess_SIGNING_CERT_new_init(X509 *signcert,
-+                                                   STACK_OF(X509) *certs);
-+static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed);
-+static int ts_TST_INFO_content_new(PKCS7 *p7);
-+static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);
-+
-+static ASN1_GENERALIZEDTIME
-+*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long,
-+                                    unsigned);
-+
-+/* Default callback for response generation. */
-+static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
-+{
-+    ASN1_INTEGER *serial = ASN1_INTEGER_new();
-+
-+    if (serial == NULL)
-+        goto err;
-+    if (!ASN1_INTEGER_set(serial, 1))
-+        goto err;
-+    return serial;
-+
-+ err:
-+    TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
-+    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                "Error during serial number generation.");
-+    return NULL;
-+}
-+
-+#if defined(OPENSSL_SYS_UNIX)
-+
-+static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
-+                       long *sec, long *usec)
-+{
-+    struct timeval tv;
-+    if (gettimeofday(&tv, NULL) != 0) {
-+        TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
-+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                    "Time is not available.");
-+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
-+        return 0;
-+    }
-+    *sec = tv.tv_sec;
-+    *usec = tv.tv_usec;
-+
-+    return 1;
-+}
-+
-+#else
-+
-+static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
-+                       long *sec, long *usec)
-+{
-+    time_t t;
-+    if (time(&t) == (time_t)-1) {
-+        TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
-+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                    "Time is not available.");
-+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
-+        return 0;
-+    }
-+    *sec = (long)t;
-+    *usec = 0;
-+
-+    return 1;
-+}
-+
-+#endif
-+
-+static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
-+                            void *data)
-+{
-+    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                "Unsupported extension.");
-+    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
-+    return 0;
-+}
-+
-+/* TS_RESP_CTX management functions. */
-+
-+TS_RESP_CTX *TS_RESP_CTX_new()
-+{
-+    TS_RESP_CTX *ctx;
-+
-+    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
-+        TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ctx->signer_md = EVP_sha256();
-+
-+    ctx->serial_cb = def_serial_cb;
-+    ctx->time_cb = def_time_cb;
-+    ctx->extension_cb = def_extension_cb;
-+
-+    return ctx;
-+}
-+
-+void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
-+{
-+    if (!ctx)
-+        return;
-+
-+    X509_free(ctx->signer_cert);
-+    EVP_PKEY_free(ctx->signer_key);
-+    sk_X509_pop_free(ctx->certs, X509_free);
-+    sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
-+    ASN1_OBJECT_free(ctx->default_policy);
-+    sk_EVP_MD_free(ctx->mds);   /* No EVP_MD_free method exists. */
-+    ASN1_INTEGER_free(ctx->seconds);
-+    ASN1_INTEGER_free(ctx->millis);
-+    ASN1_INTEGER_free(ctx->micros);
-+    OPENSSL_free(ctx);
-+}
-+
-+int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
-+{
-+    if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) {
-+        TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT,
-+              TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
-+        return 0;
-+    }
-+    X509_free(ctx->signer_cert);
-+    ctx->signer_cert = signer;
-+    X509_up_ref(ctx->signer_cert);
-+    return 1;
-+}
-+
-+int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
-+{
-+    EVP_PKEY_free(ctx->signer_key);
-+    ctx->signer_key = key;
-+    EVP_PKEY_up_ref(ctx->signer_key);
-+
-+    return 1;
-+}
-+
-+int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, const EVP_MD *md)
-+{
-+    ctx->signer_md = md;
-+    return 1;
-+}
-+
-+int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy)
-+{
-+    ASN1_OBJECT_free(ctx->default_policy);
-+    if ((ctx->default_policy = OBJ_dup(def_policy)) == NULL)
-+        goto err;
-+    return 1;
-+ err:
-+    TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
-+    return 0;
-+}
-+
-+int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
-+{
-+
-+    sk_X509_pop_free(ctx->certs, X509_free);
-+    ctx->certs = NULL;
-+    if (!certs)
-+        return 1;
-+    if ((ctx->certs = X509_chain_up_ref(certs)) == NULL) {
-+        TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy)
-+{
-+    ASN1_OBJECT *copy = NULL;
-+
-+    if (ctx->policies == NULL
-+        && (ctx->policies = sk_ASN1_OBJECT_new_null()) == NULL)
-+        goto err;
-+    if ((copy = OBJ_dup(policy)) == NULL)
-+        goto err;
-+    if (!sk_ASN1_OBJECT_push(ctx->policies, copy))
-+        goto err;
-+
-+    return 1;
-+ err:
-+    TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
-+    ASN1_OBJECT_free(copy);
-+    return 0;
-+}
-+
-+int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
-+{
-+    if (ctx->mds == NULL
-+        && (ctx->mds = sk_EVP_MD_new_null()) == NULL)
-+        goto err;
-+    if (!sk_EVP_MD_push(ctx->mds, md))
-+        goto err;
-+
-+    return 1;
-+ err:
-+    TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
-+    return 0;
-+}
-+
-+#define TS_RESP_CTX_accuracy_free(ctx)          \
-+        ASN1_INTEGER_free(ctx->seconds);        \
-+        ctx->seconds = NULL;                    \
-+        ASN1_INTEGER_free(ctx->millis);         \
-+        ctx->millis = NULL;                     \
-+        ASN1_INTEGER_free(ctx->micros);         \
-+        ctx->micros = NULL;
-+
-+int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
-+                             int secs, int millis, int micros)
-+{
-+
-+    TS_RESP_CTX_accuracy_free(ctx);
-+    if (secs
-+        && ((ctx->seconds = ASN1_INTEGER_new()) == NULL
-+            || !ASN1_INTEGER_set(ctx->seconds, secs)))
-+        goto err;
-+    if (millis
-+        && ((ctx->millis = ASN1_INTEGER_new()) == NULL
-+            || !ASN1_INTEGER_set(ctx->millis, millis)))
-+        goto err;
-+    if (micros
-+        && ((ctx->micros = ASN1_INTEGER_new()) == NULL
-+            || !ASN1_INTEGER_set(ctx->micros, micros)))
-+        goto err;
-+
-+    return 1;
-+ err:
-+    TS_RESP_CTX_accuracy_free(ctx);
-+    TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
-+    return 0;
-+}
-+
-+void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
-+{
-+    ctx->flags |= flags;
-+}
-+
-+void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
-+{
-+    ctx->serial_cb = cb;
-+    ctx->serial_cb_data = data;
-+}
-+
-+void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data)
-+{
-+    ctx->time_cb = cb;
-+    ctx->time_cb_data = data;
-+}
-+
-+void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
-+                                  TS_extension_cb cb, void *data)
-+{
-+    ctx->extension_cb = cb;
-+    ctx->extension_cb_data = data;
-+}
-+
-+int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
-+                                int status, const char *text)
-+{
-+    TS_STATUS_INFO *si = NULL;
-+    ASN1_UTF8STRING *utf8_text = NULL;
-+    int ret = 0;
-+
-+    if ((si = TS_STATUS_INFO_new()) == NULL)
-+        goto err;
-+    if (!ASN1_INTEGER_set(si->status, status))
-+        goto err;
-+    if (text) {
-+        if ((utf8_text = ASN1_UTF8STRING_new()) == NULL
-+            || !ASN1_STRING_set(utf8_text, text, strlen(text)))
-+            goto err;
-+        if (si->text == NULL
-+            && (si->text = sk_ASN1_UTF8STRING_new_null()) == NULL)
-+            goto err;
-+        if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text))
-+            goto err;
-+        utf8_text = NULL;       /* Ownership is lost. */
-+    }
-+    if (!TS_RESP_set_status_info(ctx->response, si))
-+        goto err;
-+    ret = 1;
-+ err:
-+    if (!ret)
-+        TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
-+    TS_STATUS_INFO_free(si);
-+    ASN1_UTF8STRING_free(utf8_text);
-+    return ret;
-+}
-+
-+int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
-+                                     int status, const char *text)
-+{
-+    int ret = 1;
-+    TS_STATUS_INFO *si = ctx->response->status_info;
-+
-+    if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) {
-+        ret = TS_RESP_CTX_set_status_info(ctx, status, text);
-+    }
-+    return ret;
-+}
-+
-+int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
-+{
-+    TS_STATUS_INFO *si = ctx->response->status_info;
-+    if (si->failure_info == NULL
-+        && (si->failure_info = ASN1_BIT_STRING_new()) == NULL)
-+        goto err;
-+    if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
-+        goto err;
-+    return 1;
-+ err:
-+    TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
-+    return 0;
-+}
-+
-+TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
-+{
-+    return ctx->request;
-+}
-+
-+TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
-+{
-+    return ctx->tst_info;
-+}
-+
-+int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
-+                                           unsigned precision)
-+{
-+    if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
-+        return 0;
-+    ctx->clock_precision_digits = precision;
-+    return 1;
-+}
-+
-+/* Main entry method of the response generation. */
-+TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
-+{
-+    ASN1_OBJECT *policy;
-+    TS_RESP *response;
-+    int result = 0;
-+
-+    ts_RESP_CTX_init(ctx);
-+
-+    if ((ctx->response = TS_RESP_new()) == NULL) {
-+        TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
-+        goto end;
-+    }
-+    if ((ctx->request = d2i_TS_REQ_bio(req_bio, NULL)) == NULL) {
-+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                    "Bad request format or system error.");
-+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
-+        goto end;
-+    }
-+    if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
-+        goto end;
-+    if (!ts_RESP_check_request(ctx))
-+        goto end;
-+    if ((policy = ts_RESP_get_policy(ctx)) == NULL)
-+        goto end;
-+    if ((ctx->tst_info = ts_RESP_create_tst_info(ctx, policy)) == NULL)
-+        goto end;
-+    if (!ts_RESP_process_extensions(ctx))
-+        goto end;
-+    if (!ts_RESP_sign(ctx))
-+        goto end;
-+    result = 1;
-+
-+ end:
-+    if (!result) {
-+        TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
-+        if (ctx->response != NULL) {
-+            if (TS_RESP_CTX_set_status_info_cond(ctx,
-+                                                 TS_STATUS_REJECTION,
-+                                                 "Error during response "
-+                                                 "generation.") == 0) {
-+                TS_RESP_free(ctx->response);
-+                ctx->response = NULL;
-+            }
-+        }
-+    }
-+    response = ctx->response;
-+    ctx->response = NULL;       /* Ownership will be returned to caller. */
-+    ts_RESP_CTX_cleanup(ctx);
-+    return response;
-+}
-+
-+/* Initializes the variable part of the context. */
-+static void ts_RESP_CTX_init(TS_RESP_CTX *ctx)
-+{
-+    ctx->request = NULL;
-+    ctx->response = NULL;
-+    ctx->tst_info = NULL;
-+}
-+
-+/* Cleans up the variable part of the context. */
-+static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
-+{
-+    TS_REQ_free(ctx->request);
-+    ctx->request = NULL;
-+    TS_RESP_free(ctx->response);
-+    ctx->response = NULL;
-+    TS_TST_INFO_free(ctx->tst_info);
-+    ctx->tst_info = NULL;
-+}
-+
-+/* Checks the format and content of the request. */
-+static int ts_RESP_check_request(TS_RESP_CTX *ctx)
-+{
-+    TS_REQ *request = ctx->request;
-+    TS_MSG_IMPRINT *msg_imprint;
-+    X509_ALGOR *md_alg;
-+    int md_alg_id;
-+    const ASN1_OCTET_STRING *digest;
-+    const EVP_MD *md = NULL;
-+    int i;
-+
-+    if (TS_REQ_get_version(request) != 1) {
-+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                    "Bad request version.");
-+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
-+        return 0;
-+    }
-+
-+    msg_imprint = request->msg_imprint;
-+    md_alg = msg_imprint->hash_algo;
-+    md_alg_id = OBJ_obj2nid(md_alg->algorithm);
-+    for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) {
-+        const EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
-+        if (md_alg_id == EVP_MD_type(current_md))
-+            md = current_md;
-+    }
-+    if (!md) {
-+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                    "Message digest algorithm is "
-+                                    "not supported.");
-+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
-+        return 0;
-+    }
-+
-+    if (md_alg->parameter && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) {
-+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                    "Superfluous message digest "
-+                                    "parameter.");
-+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
-+        return 0;
-+    }
-+    digest = msg_imprint->hashed_msg;
-+    if (digest->length != EVP_MD_size(md)) {
-+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                    "Bad message digest.");
-+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+/* Returns the TSA policy based on the requested and acceptable policies. */
-+static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx)
-+{
-+    ASN1_OBJECT *requested = ctx->request->policy_id;
-+    ASN1_OBJECT *policy = NULL;
-+    int i;
-+
-+    if (ctx->default_policy == NULL) {
-+        TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
-+        return NULL;
-+    }
-+    if (!requested || !OBJ_cmp(requested, ctx->default_policy))
-+        policy = ctx->default_policy;
-+
-+    /* Check if the policy is acceptable. */
-+    for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) {
-+        ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
-+        if (!OBJ_cmp(requested, current))
-+            policy = current;
-+    }
-+    if (!policy) {
-+        TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
-+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
-+                                    "Requested policy is not " "supported.");
-+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
-+    }
-+    return policy;
-+}
-+
-+/* Creates the TS_TST_INFO object based on the settings of the context. */
-+static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
-+                                            ASN1_OBJECT *policy)
-+{
-+    int result = 0;
-+    TS_TST_INFO *tst_info = NULL;
-+    ASN1_INTEGER *serial = NULL;
-+    ASN1_GENERALIZEDTIME *asn1_time = NULL;
-+    long sec, usec;
-+    TS_ACCURACY *accuracy = NULL;
-+    const ASN1_INTEGER *nonce;
-+    GENERAL_NAME *tsa_name = NULL;
-+
-+    if ((tst_info = TS_TST_INFO_new()) == NULL)
-+        goto end;
-+    if (!TS_TST_INFO_set_version(tst_info, 1))
-+        goto end;
-+    if (!TS_TST_INFO_set_policy_id(tst_info, policy))
-+        goto end;
-+    if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
-+        goto end;
-+    if ((serial = ctx->serial_cb(ctx, ctx->serial_cb_data)) == NULL
-+        || !TS_TST_INFO_set_serial(tst_info, serial))
-+        goto end;
-+    if (!ctx->time_cb(ctx, ctx->time_cb_data, &sec, &usec)
-+        || (asn1_time =
-+            TS_RESP_set_genTime_with_precision(NULL, sec, usec,
-+                                        ctx->clock_precision_digits)) == NULL
-+        || !TS_TST_INFO_set_time(tst_info, asn1_time))
-+        goto end;
-+
-+    if ((ctx->seconds || ctx->millis || ctx->micros)
-+        && (accuracy = TS_ACCURACY_new()) == NULL)
-+        goto end;
-+    if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
-+        goto end;
-+    if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
-+        goto end;
-+    if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
-+        goto end;
-+    if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy))
-+        goto end;
-+
-+    if ((ctx->flags & TS_ORDERING)
-+        && !TS_TST_INFO_set_ordering(tst_info, 1))
-+        goto end;
-+
-+    if ((nonce = ctx->request->nonce) != NULL
-+        && !TS_TST_INFO_set_nonce(tst_info, nonce))
-+        goto end;
-+
-+    if (ctx->flags & TS_TSA_NAME) {
-+        if ((tsa_name = GENERAL_NAME_new()) == NULL)
-+            goto end;
-+        tsa_name->type = GEN_DIRNAME;
-+        tsa_name->d.dirn =
-+            X509_NAME_dup(X509_get_subject_name(ctx->signer_cert));
-+        if (!tsa_name->d.dirn)
-+            goto end;
-+        if (!TS_TST_INFO_set_tsa(tst_info, tsa_name))
-+            goto end;
-+    }
-+
-+    result = 1;
-+ end:
-+    if (!result) {
-+        TS_TST_INFO_free(tst_info);
-+        tst_info = NULL;
-+        TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR);
-+        TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
-+                                         "Error during TSTInfo "
-+                                         "generation.");
-+    }
-+    GENERAL_NAME_free(tsa_name);
-+    TS_ACCURACY_free(accuracy);
-+    ASN1_GENERALIZEDTIME_free(asn1_time);
-+    ASN1_INTEGER_free(serial);
-+
-+    return tst_info;
-+}
-+
-+/* Processing the extensions of the request. */
-+static int ts_RESP_process_extensions(TS_RESP_CTX *ctx)
-+{
-+    STACK_OF(X509_EXTENSION) *exts = ctx->request->extensions;
-+    int i;
-+    int ok = 1;
-+
-+    for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) {
-+        X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
-+        /*
-+         * The last argument was previously (void *)ctx->extension_cb,
-+         * but ISO C doesn't permit converting a function pointer to void *.
-+         * For lack of better information, I'm placing a NULL there instead.
-+         * The callback can pick its own address out from the ctx anyway...
-+         */
-+        ok = (*ctx->extension_cb) (ctx, ext, NULL);
-+    }
-+
-+    return ok;
-+}
-+
-+/* Functions for signing the TS_TST_INFO structure of the context. */
-+static int ts_RESP_sign(TS_RESP_CTX *ctx)
-+{
-+    int ret = 0;
-+    PKCS7 *p7 = NULL;
-+    PKCS7_SIGNER_INFO *si;
-+    STACK_OF(X509) *certs;      /* Certificates to include in sc. */
-+    ESS_SIGNING_CERT *sc = NULL;
-+    ASN1_OBJECT *oid;
-+    BIO *p7bio = NULL;
-+    int i;
-+
-+    if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
-+        TSerr(TS_F_TS_RESP_SIGN, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
-+        goto err;
-+    }
-+
-+    if ((p7 = PKCS7_new()) == NULL) {
-+        TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if (!PKCS7_set_type(p7, NID_pkcs7_signed))
-+        goto err;
-+    if (!ASN1_INTEGER_set(p7->d.sign->version, 3))
-+        goto err;
-+
-+    if (ctx->request->cert_req) {
-+        PKCS7_add_certificate(p7, ctx->signer_cert);
-+        if (ctx->certs) {
-+            for (i = 0; i < sk_X509_num(ctx->certs); ++i) {
-+                X509 *cert = sk_X509_value(ctx->certs, i);
-+                PKCS7_add_certificate(p7, cert);
-+            }
-+        }
-+    }
-+
-+    if ((si = PKCS7_add_signature(p7, ctx->signer_cert,
-+                                  ctx->signer_key, ctx->signer_md)) == NULL) {
-+        TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
-+        goto err;
-+    }
-+
-+    oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
-+    if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
-+                                    V_ASN1_OBJECT, oid)) {
-+        TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
-+        goto err;
-+    }
-+
-+    certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
-+    if ((sc = ess_SIGNING_CERT_new_init(ctx->signer_cert, certs)) == NULL)
-+        goto err;
-+    if (!ESS_add_signing_cert(si, sc)) {
-+        TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
-+        goto err;
-+    }
-+
-+    if (!ts_TST_INFO_content_new(p7))
-+        goto err;
-+    if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
-+        TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) {
-+        TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
-+        goto err;
-+    }
-+    if (!PKCS7_dataFinal(p7, p7bio)) {
-+        TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
-+        goto err;
-+    }
-+    TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
-+    p7 = NULL;                  /* Ownership is lost. */
-+    ctx->tst_info = NULL;       /* Ownership is lost. */
-+
-+    ret = 1;
-+ err:
-+    if (!ret)
-+        TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
-+                                         "Error during signature "
-+                                         "generation.");
-+    BIO_free_all(p7bio);
-+    ESS_SIGNING_CERT_free(sc);
-+    PKCS7_free(p7);
-+    return ret;
-+}
-+
-+static ESS_SIGNING_CERT *ess_SIGNING_CERT_new_init(X509 *signcert,
-+                                                   STACK_OF(X509) *certs)
-+{
-+    ESS_CERT_ID *cid;
-+    ESS_SIGNING_CERT *sc = NULL;
-+    int i;
-+
-+    if ((sc = ESS_SIGNING_CERT_new()) == NULL)
-+        goto err;
-+    if (sc->cert_ids == NULL
-+        && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL)
-+        goto err;
-+
-+    if ((cid = ess_CERT_ID_new_init(signcert, 0)) == NULL
-+        || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
-+        goto err;
-+    for (i = 0; i < sk_X509_num(certs); ++i) {
-+        X509 *cert = sk_X509_value(certs, i);
-+        if ((cid = ess_CERT_ID_new_init(cert, 1)) == NULL
-+            || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
-+            goto err;
-+    }
-+
-+    return sc;
-+ err:
-+    ESS_SIGNING_CERT_free(sc);
-+    TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed)
-+{
-+    ESS_CERT_ID *cid = NULL;
-+    GENERAL_NAME *name = NULL;
-+    unsigned char cert_sha1[SHA_DIGEST_LENGTH];
-+
-+    /* Call for side-effect of computing hash and caching extensions */
-+    X509_check_purpose(cert, -1, 0);
-+    if ((cid = ESS_CERT_ID_new()) == NULL)
-+        goto err;
-+    X509_digest(cert, EVP_sha1(), cert_sha1, NULL);
-+    if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH))
-+        goto err;
-+
-+    /* Setting the issuer/serial if requested. */
-+    if (issuer_needed) {
-+        if (cid->issuer_serial == NULL
-+            && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL)
-+            goto err;
-+        if ((name = GENERAL_NAME_new()) == NULL)
-+            goto err;
-+        name->type = GEN_DIRNAME;
-+        if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL)
-+            goto err;
-+        if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
-+            goto err;
-+        name = NULL;            /* Ownership is lost. */
-+        ASN1_INTEGER_free(cid->issuer_serial->serial);
-+        if (!(cid->issuer_serial->serial =
-+              ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
-+            goto err;
-+    }
-+
-+    return cid;
-+ err:
-+    GENERAL_NAME_free(name);
-+    ESS_CERT_ID_free(cid);
-+    TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE);
-+    return NULL;
-+}
-+
-+static int ts_TST_INFO_content_new(PKCS7 *p7)
-+{
-+    PKCS7 *ret = NULL;
-+    ASN1_OCTET_STRING *octet_string = NULL;
-+
-+    /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
-+    if ((ret = PKCS7_new()) == NULL)
-+        goto err;
-+    if ((ret->d.other = ASN1_TYPE_new()) == NULL)
-+        goto err;
-+    ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
-+    if ((octet_string = ASN1_OCTET_STRING_new()) == NULL)
-+        goto err;
-+    ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
-+    octet_string = NULL;
-+
-+    /* Add encapsulated content to signed PKCS7 structure. */
-+    if (!PKCS7_set_content(p7, ret))
-+        goto err;
-+
-+    return 1;
-+ err:
-+    ASN1_OCTET_STRING_free(octet_string);
-+    PKCS7_free(ret);
-+    return 0;
-+}
-+
-+static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
-+{
-+    ASN1_STRING *seq = NULL;
-+    unsigned char *p, *pp = NULL;
-+    int len;
-+
-+    len = i2d_ESS_SIGNING_CERT(sc, NULL);
-+    if ((pp = OPENSSL_malloc(len)) == NULL) {
-+        TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    p = pp;
-+    i2d_ESS_SIGNING_CERT(sc, &p);
-+    if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
-+        TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    OPENSSL_free(pp);
-+    pp = NULL;
-+    return PKCS7_add_signed_attribute(si,
-+                                      NID_id_smime_aa_signingCertificate,
-+                                      V_ASN1_SEQUENCE, seq);
-+ err:
-+    ASN1_STRING_free(seq);
-+    OPENSSL_free(pp);
-+
-+    return 0;
-+}
-+
-+static ASN1_GENERALIZEDTIME
-+*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time,
-+                                    long sec, long usec, unsigned precision)
-+{
-+    time_t time_sec = (time_t)sec;
-+    struct tm *tm = NULL;
-+    char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
-+    char *p = genTime_str;
-+    char *p_end = genTime_str + sizeof(genTime_str);
-+
-+    if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
-+        goto err;
-+
-+    if ((tm = gmtime(&time_sec)) == NULL)
-+        goto err;
-+
-+    /*
-+     * Put "genTime_str" in GeneralizedTime format.  We work around the
-+     * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST
-+     * NOT include fractional seconds") and OpenSSL related functions to
-+     * meet the rfc3161 requirement: "GeneralizedTime syntax can include
-+     * fraction-of-second details".
-+     */
-+    p += BIO_snprintf(p, p_end - p,
-+                      "%04d%02d%02d%02d%02d%02d",
-+                      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-+                      tm->tm_hour, tm->tm_min, tm->tm_sec);
-+    if (precision > 0) {
-+        BIO_snprintf(p, 2 + precision, ".%06ld", usec);
-+        p += strlen(p);
-+
-+        /*
-+         * To make things a bit harder, X.690 | ISO/IEC 8825-1 provides the
-+         * following restrictions for a DER-encoding, which OpenSSL
-+         * (specifically ASN1_GENERALIZEDTIME_check() function) doesn't
-+         * support: "The encoding MUST terminate with a "Z" (which means
-+         * "Zulu" time). The decimal point element, if present, MUST be the
-+         * point option ".". The fractional-seconds elements, if present,
-+         * MUST omit all trailing 0's; if the elements correspond to 0, they
-+         * MUST be wholly omitted, and the decimal point element also MUST be
-+         * omitted."
-+         */
-+        /*
-+         * Remove trailing zeros. The dot guarantees the exit condition of
-+         * this loop even if all the digits are zero.
-+         */
-+        while (*--p == '0')
-+             continue;
-+        if (*p != '.')
-+            ++p;
-+    }
-+    *p++ = 'Z';
-+    *p++ = '\0';
-+
-+    if (asn1_time == NULL
-+        && (asn1_time = ASN1_GENERALIZEDTIME_new()) == NULL)
-+        goto err;
-+    if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) {
-+        ASN1_GENERALIZEDTIME_free(asn1_time);
-+        goto err;
-+    }
-+    return asn1_time;
-+
-+ err:
-+    TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_utils.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_utils.c
-new file mode 100644
-index 0000000..3ecee39
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_utils.c
-@@ -0,0 +1,365 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "ts_lcl.h"
-+
-+int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info)
-+{
-+    TS_STATUS_INFO *new_status_info;
-+
-+    if (a->status_info == status_info)
-+        return 1;
-+    new_status_info = TS_STATUS_INFO_dup(status_info);
-+    if (new_status_info == NULL) {
-+        TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    TS_STATUS_INFO_free(a->status_info);
-+    a->status_info = new_status_info;
-+
-+    return 1;
-+}
-+
-+TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a)
-+{
-+    return a->status_info;
-+}
-+
-+/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
-+void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info)
-+{
-+    PKCS7_free(a->token);
-+    a->token = p7;
-+    TS_TST_INFO_free(a->tst_info);
-+    a->tst_info = tst_info;
-+}
-+
-+PKCS7 *TS_RESP_get_token(TS_RESP *a)
-+{
-+    return a->token;
-+}
-+
-+TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a)
-+{
-+    return a->tst_info;
-+}
-+
-+int TS_TST_INFO_set_version(TS_TST_INFO *a, long version)
-+{
-+    return ASN1_INTEGER_set(a->version, version);
-+}
-+
-+long TS_TST_INFO_get_version(const TS_TST_INFO *a)
-+{
-+    return ASN1_INTEGER_get(a->version);
-+}
-+
-+int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy)
-+{
-+    ASN1_OBJECT *new_policy;
-+
-+    if (a->policy_id == policy)
-+        return 1;
-+    new_policy = OBJ_dup(policy);
-+    if (new_policy == NULL) {
-+        TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ASN1_OBJECT_free(a->policy_id);
-+    a->policy_id = new_policy;
-+    return 1;
-+}
-+
-+ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a)
-+{
-+    return a->policy_id;
-+}
-+
-+int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint)
-+{
-+    TS_MSG_IMPRINT *new_msg_imprint;
-+
-+    if (a->msg_imprint == msg_imprint)
-+        return 1;
-+    new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
-+    if (new_msg_imprint == NULL) {
-+        TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    TS_MSG_IMPRINT_free(a->msg_imprint);
-+    a->msg_imprint = new_msg_imprint;
-+    return 1;
-+}
-+
-+TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a)
-+{
-+    return a->msg_imprint;
-+}
-+
-+int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial)
-+{
-+    ASN1_INTEGER *new_serial;
-+
-+    if (a->serial == serial)
-+        return 1;
-+    new_serial = ASN1_INTEGER_dup(serial);
-+    if (new_serial == NULL) {
-+        TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ASN1_INTEGER_free(a->serial);
-+    a->serial = new_serial;
-+    return 1;
-+}
-+
-+const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a)
-+{
-+    return a->serial;
-+}
-+
-+int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime)
-+{
-+    ASN1_GENERALIZEDTIME *new_time;
-+
-+    if (a->time == gtime)
-+        return 1;
-+    new_time = ASN1_STRING_dup(gtime);
-+    if (new_time == NULL) {
-+        TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ASN1_GENERALIZEDTIME_free(a->time);
-+    a->time = new_time;
-+    return 1;
-+}
-+
-+const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a)
-+{
-+    return a->time;
-+}
-+
-+int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy)
-+{
-+    TS_ACCURACY *new_accuracy;
-+
-+    if (a->accuracy == accuracy)
-+        return 1;
-+    new_accuracy = TS_ACCURACY_dup(accuracy);
-+    if (new_accuracy == NULL) {
-+        TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    TS_ACCURACY_free(a->accuracy);
-+    a->accuracy = new_accuracy;
-+    return 1;
-+}
-+
-+TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a)
-+{
-+    return a->accuracy;
-+}
-+
-+int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds)
-+{
-+    ASN1_INTEGER *new_seconds;
-+
-+    if (a->seconds == seconds)
-+        return 1;
-+    new_seconds = ASN1_INTEGER_dup(seconds);
-+    if (new_seconds == NULL) {
-+        TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ASN1_INTEGER_free(a->seconds);
-+    a->seconds = new_seconds;
-+    return 1;
-+}
-+
-+const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a)
-+{
-+    return a->seconds;
-+}
-+
-+int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis)
-+{
-+    ASN1_INTEGER *new_millis = NULL;
-+
-+    if (a->millis == millis)
-+        return 1;
-+    if (millis != NULL) {
-+        new_millis = ASN1_INTEGER_dup(millis);
-+        if (new_millis == NULL) {
-+            TSerr(TS_F_TS_ACCURACY_SET_MILLIS, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+    }
-+    ASN1_INTEGER_free(a->millis);
-+    a->millis = new_millis;
-+    return 1;
-+}
-+
-+const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a)
-+{
-+    return a->millis;
-+}
-+
-+int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros)
-+{
-+    ASN1_INTEGER *new_micros = NULL;
-+
-+    if (a->micros == micros)
-+        return 1;
-+    if (micros != NULL) {
-+        new_micros = ASN1_INTEGER_dup(micros);
-+        if (new_micros == NULL) {
-+            TSerr(TS_F_TS_ACCURACY_SET_MICROS, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+    }
-+    ASN1_INTEGER_free(a->micros);
-+    a->micros = new_micros;
-+    return 1;
-+}
-+
-+const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a)
-+{
-+    return a->micros;
-+}
-+
-+int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering)
-+{
-+    a->ordering = ordering ? 0xFF : 0x00;
-+    return 1;
-+}
-+
-+int TS_TST_INFO_get_ordering(const TS_TST_INFO *a)
-+{
-+    return a->ordering ? 1 : 0;
-+}
-+
-+int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce)
-+{
-+    ASN1_INTEGER *new_nonce;
-+
-+    if (a->nonce == nonce)
-+        return 1;
-+    new_nonce = ASN1_INTEGER_dup(nonce);
-+    if (new_nonce == NULL) {
-+        TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    ASN1_INTEGER_free(a->nonce);
-+    a->nonce = new_nonce;
-+    return 1;
-+}
-+
-+const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a)
-+{
-+    return a->nonce;
-+}
-+
-+int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa)
-+{
-+    GENERAL_NAME *new_tsa;
-+
-+    if (a->tsa == tsa)
-+        return 1;
-+    new_tsa = GENERAL_NAME_dup(tsa);
-+    if (new_tsa == NULL) {
-+        TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE);
-+        return 0;
-+    }
-+    GENERAL_NAME_free(a->tsa);
-+    a->tsa = new_tsa;
-+    return 1;
-+}
-+
-+GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a)
-+{
-+    return a->tsa;
-+}
-+
-+STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a)
-+{
-+    return a->extensions;
-+}
-+
-+void TS_TST_INFO_ext_free(TS_TST_INFO *a)
-+{
-+    if (!a)
-+        return;
-+    sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
-+    a->extensions = NULL;
-+}
-+
-+int TS_TST_INFO_get_ext_count(TS_TST_INFO *a)
-+{
-+    return X509v3_get_ext_count(a->extensions);
-+}
-+
-+int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos)
-+{
-+    return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
-+}
-+
-+int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, const ASN1_OBJECT *obj, int lastpos)
-+{
-+    return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
-+}
-+
-+int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos)
-+{
-+    return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
-+}
-+
-+X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc)
-+{
-+    return X509v3_get_ext(a->extensions, loc);
-+}
-+
-+X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc)
-+{
-+    return X509v3_delete_ext(a->extensions, loc);
-+}
-+
-+int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc)
-+{
-+    return X509v3_add_ext(&a->extensions, ex, loc) != NULL;
-+}
-+
-+void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx)
-+{
-+    return X509V3_get_d2i(a->extensions, nid, crit, idx);
-+}
-+
-+int TS_STATUS_INFO_set_status(TS_STATUS_INFO *a, int i)
-+{
-+    return ASN1_INTEGER_set(a->status, i);
-+}
-+
-+const ASN1_INTEGER *TS_STATUS_INFO_get0_status(const TS_STATUS_INFO *a)
-+{
-+    return a->status;
-+}
-+
-+const STACK_OF(ASN1_UTF8STRING) *
-+TS_STATUS_INFO_get0_text(const TS_STATUS_INFO *a)
-+{
-+    return a->text;
-+}
-+
-+const ASN1_BIT_STRING *TS_STATUS_INFO_get0_failure_info(const TS_STATUS_INFO *a)
-+{
-+    return a->failure_info;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_verify.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_verify.c
-new file mode 100644
-index 0000000..2755dd0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_rsp_verify.c
-@@ -0,0 +1,635 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include "ts_lcl.h"
-+
-+static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
-+                          X509 *signer, STACK_OF(X509) **chain);
-+static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
-+                                  STACK_OF(X509) *chain);
-+static ESS_SIGNING_CERT *ess_get_signing_cert(PKCS7_SIGNER_INFO *si);
-+static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
-+static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert);
-+static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx,
-+                                    PKCS7 *token, TS_TST_INFO *tst_info);
-+static int ts_check_status_info(TS_RESP *response);
-+static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
-+static int ts_check_policy(const ASN1_OBJECT *req_oid,
-+                           const TS_TST_INFO *tst_info);
-+static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
-+                              X509_ALGOR **md_alg,
-+                              unsigned char **imprint, unsigned *imprint_len);
-+static int ts_check_imprints(X509_ALGOR *algor_a,
-+                             const unsigned char *imprint_a, unsigned len_a,
-+                             TS_TST_INFO *tst_info);
-+static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
-+static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
-+static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names,
-+                        GENERAL_NAME *name);
-+
-+/*
-+ * This must be large enough to hold all values in ts_status_text (with
-+ * comma separator) or all text fields in ts_failure_info (also with comma).
-+ */
-+#define TS_STATUS_BUF_SIZE      256
-+
-+/*
-+ * Local mapping between response codes and descriptions.
-+ */
-+static const char *ts_status_text[] = {
-+    "granted",
-+    "grantedWithMods",
-+    "rejection",
-+    "waiting",
-+    "revocationWarning",
-+    "revocationNotification"
-+};
-+
-+#define TS_STATUS_TEXT_SIZE     OSSL_NELEM(ts_status_text)
-+
-+static struct {
-+    int code;
-+    const char *text;
-+} ts_failure_info[] = {
-+    {TS_INFO_BAD_ALG, "badAlg"},
-+    {TS_INFO_BAD_REQUEST, "badRequest"},
-+    {TS_INFO_BAD_DATA_FORMAT, "badDataFormat"},
-+    {TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable"},
-+    {TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy"},
-+    {TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension"},
-+    {TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable"},
-+    {TS_INFO_SYSTEM_FAILURE, "systemFailure"}
-+};
-+
-+
-+/*-
-+ * This function carries out the following tasks:
-+ *      - Checks if there is one and only one signer.
-+ *      - Search for the signing certificate in 'certs' and in the response.
-+ *      - Check the extended key usage and key usage fields of the signer
-+ *      certificate (done by the path validation).
-+ *      - Build and validate the certificate path.
-+ *      - Check if the certificate path meets the requirements of the
-+ *      SigningCertificate ESS signed attribute.
-+ *      - Verify the signature value.
-+ *      - Returns the signer certificate in 'signer', if 'signer' is not NULL.
-+ */
-+int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
-+                             X509_STORE *store, X509 **signer_out)
-+{
-+    STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
-+    PKCS7_SIGNER_INFO *si;
-+    STACK_OF(X509) *signers = NULL;
-+    X509 *signer;
-+    STACK_OF(X509) *chain = NULL;
-+    char buf[4096];
-+    int i, j = 0, ret = 0;
-+    BIO *p7bio = NULL;
-+
-+    /* Some sanity checks first. */
-+    if (!token) {
-+        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER);
-+        goto err;
-+    }
-+    if (!PKCS7_type_is_signed(token)) {
-+        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE);
-+        goto err;
-+    }
-+    sinfos = PKCS7_get_signer_info(token);
-+    if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) {
-+        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_THERE_MUST_BE_ONE_SIGNER);
-+        goto err;
-+    }
-+    si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0);
-+    if (PKCS7_get_detached(token)) {
-+        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT);
-+        goto err;
-+    }
-+
-+    /*
-+     * Get hold of the signer certificate, search only internal certificates
-+     * if it was requested.
-+     */
-+    signers = PKCS7_get0_signers(token, certs, 0);
-+    if (!signers || sk_X509_num(signers) != 1)
-+        goto err;
-+    signer = sk_X509_value(signers, 0);
-+
-+    if (!ts_verify_cert(store, certs, signer, &chain))
-+        goto err;
-+    if (!ts_check_signing_certs(si, chain))
-+        goto err;
-+    p7bio = PKCS7_dataInit(token, NULL);
-+
-+    /* We now have to 'read' from p7bio to calculate digests etc. */
-+    while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0)
-+        continue;
-+
-+    j = PKCS7_signatureVerify(p7bio, token, si, signer);
-+    if (j <= 0) {
-+        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE);
-+        goto err;
-+    }
-+
-+    if (signer_out) {
-+        *signer_out = signer;
-+        X509_up_ref(signer);
-+    }
-+    ret = 1;
-+
-+ err:
-+    BIO_free_all(p7bio);
-+    sk_X509_pop_free(chain, X509_free);
-+    sk_X509_free(signers);
-+
-+    return ret;
-+}
-+
-+/*
-+ * The certificate chain is returned in chain. Caller is responsible for
-+ * freeing the vector.
-+ */
-+static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
-+                          X509 *signer, STACK_OF(X509) **chain)
-+{
-+    X509_STORE_CTX *cert_ctx = NULL;
-+    int i;
-+    int ret = 0;
-+
-+    *chain = NULL;
-+    cert_ctx = X509_STORE_CTX_new();
-+    if (cert_ctx == NULL) {
-+        TSerr(TS_F_TS_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if (!X509_STORE_CTX_init(cert_ctx, store, signer, untrusted))
-+        goto end;
-+    X509_STORE_CTX_set_purpose(cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN);
-+    i = X509_verify_cert(cert_ctx);
-+    if (i <= 0) {
-+        int j = X509_STORE_CTX_get_error(cert_ctx);
-+        TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR);
-+        ERR_add_error_data(2, "Verify error:",
-+                           X509_verify_cert_error_string(j));
-+        goto err;
-+    }
-+    *chain = X509_STORE_CTX_get1_chain(cert_ctx);
-+    ret = 1;
-+    goto end;
-+
-+err:
-+    ret = 0;
-+
-+end:
-+    X509_STORE_CTX_free(cert_ctx);
-+    return ret;
-+}
-+
-+static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
-+                                  STACK_OF(X509) *chain)
-+{
-+    ESS_SIGNING_CERT *ss = ess_get_signing_cert(si);
-+    STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
-+    X509 *cert;
-+    int i = 0;
-+    int ret = 0;
-+
-+    if (!ss)
-+        goto err;
-+    cert_ids = ss->cert_ids;
-+    cert = sk_X509_value(chain, 0);
-+    if (ts_find_cert(cert_ids, cert) != 0)
-+        goto err;
-+
-+    /*
-+     * Check the other certificates of the chain if there are more than one
-+     * certificate ids in cert_ids.
-+     */
-+    if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
-+        for (i = 1; i < sk_X509_num(chain); ++i) {
-+            cert = sk_X509_value(chain, i);
-+            if (ts_find_cert(cert_ids, cert) < 0)
-+                goto err;
-+        }
-+    }
-+    ret = 1;
-+ err:
-+    if (!ret)
-+        TSerr(TS_F_TS_CHECK_SIGNING_CERTS,
-+              TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
-+    ESS_SIGNING_CERT_free(ss);
-+    return ret;
-+}
-+
-+static ESS_SIGNING_CERT *ess_get_signing_cert(PKCS7_SIGNER_INFO *si)
-+{
-+    ASN1_TYPE *attr;
-+    const unsigned char *p;
-+    attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate);
-+    if (!attr)
-+        return NULL;
-+    p = attr->value.sequence->data;
-+    return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
-+}
-+
-+/* Returns < 0 if certificate is not found, certificate index otherwise. */
-+static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
-+{
-+    int i;
-+    unsigned char cert_sha1[SHA_DIGEST_LENGTH];
-+
-+    if (!cert_ids || !cert)
-+        return -1;
-+
-+    X509_digest(cert, EVP_sha1(), cert_sha1, NULL);
-+
-+    /* Recompute SHA1 hash of certificate if necessary (side effect). */
-+    X509_check_purpose(cert, -1, 0);
-+
-+    /* Look for cert in the cert_ids vector. */
-+    for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) {
-+        ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
-+
-+        if (cid->hash->length == SHA_DIGEST_LENGTH
-+            && memcmp(cid->hash->data, cert_sha1, SHA_DIGEST_LENGTH) == 0) {
-+            ESS_ISSUER_SERIAL *is = cid->issuer_serial;
-+            if (!is || !ts_issuer_serial_cmp(is, cert))
-+                return i;
-+        }
-+    }
-+
-+    return -1;
-+}
-+
-+static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert)
-+{
-+    GENERAL_NAME *issuer;
-+
-+    if (!is || !cert || sk_GENERAL_NAME_num(is->issuer) != 1)
-+        return -1;
-+
-+    issuer = sk_GENERAL_NAME_value(is->issuer, 0);
-+    if (issuer->type != GEN_DIRNAME
-+        || X509_NAME_cmp(issuer->d.dirn, X509_get_issuer_name(cert)))
-+        return -1;
-+
-+    if (ASN1_INTEGER_cmp(is->serial, X509_get_serialNumber(cert)))
-+        return -1;
-+
-+    return 0;
-+}
-+
-+/*-
-+ * Verifies whether 'response' contains a valid response with regards
-+ * to the settings of the context:
-+ *      - Gives an error message if the TS_TST_INFO is not present.
-+ *      - Calls _TS_RESP_verify_token to verify the token content.
-+ */
-+int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
-+{
-+    PKCS7 *token = response->token;
-+    TS_TST_INFO *tst_info = response->tst_info;
-+    int ret = 0;
-+
-+    if (!ts_check_status_info(response))
-+        goto err;
-+    if (!int_ts_RESP_verify_token(ctx, token, tst_info))
-+        goto err;
-+    ret = 1;
-+
-+ err:
-+    return ret;
-+}
-+
-+/*
-+ * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
-+ * calls the internal int_TS_RESP_verify_token function for verifying it.
-+ */
-+int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
-+{
-+    TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
-+    int ret = 0;
-+    if (tst_info) {
-+        ret = int_ts_RESP_verify_token(ctx, token, tst_info);
-+        TS_TST_INFO_free(tst_info);
-+    }
-+    return ret;
-+}
-+
-+/*-
-+ * Verifies whether the 'token' contains a valid time stamp token
-+ * with regards to the settings of the context. Only those checks are
-+ * carried out that are specified in the context:
-+ *      - Verifies the signature of the TS_TST_INFO.
-+ *      - Checks the version number of the response.
-+ *      - Check if the requested and returned policies math.
-+ *      - Check if the message imprints are the same.
-+ *      - Check if the nonces are the same.
-+ *      - Check if the TSA name matches the signer.
-+ *      - Check if the TSA name is the expected TSA.
-+ */
-+static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx,
-+                                    PKCS7 *token, TS_TST_INFO *tst_info)
-+{
-+    X509 *signer = NULL;
-+    GENERAL_NAME *tsa_name = tst_info->tsa;
-+    X509_ALGOR *md_alg = NULL;
-+    unsigned char *imprint = NULL;
-+    unsigned imprint_len = 0;
-+    int ret = 0;
-+    int flags = ctx->flags;
-+
-+    /* Some options require us to also check the signature */
-+    if (((flags & TS_VFY_SIGNER) && tsa_name != NULL)
-+            || (flags & TS_VFY_TSA_NAME)) {
-+        flags |= TS_VFY_SIGNATURE;
-+    }
-+
-+    if ((flags & TS_VFY_SIGNATURE)
-+        && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer))
-+        goto err;
-+    if ((flags & TS_VFY_VERSION)
-+        && TS_TST_INFO_get_version(tst_info) != 1) {
-+        TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
-+        goto err;
-+    }
-+    if ((flags & TS_VFY_POLICY)
-+        && !ts_check_policy(ctx->policy, tst_info))
-+        goto err;
-+    if ((flags & TS_VFY_IMPRINT)
-+        && !ts_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
-+                              tst_info))
-+        goto err;
-+    if ((flags & TS_VFY_DATA)
-+        && (!ts_compute_imprint(ctx->data, tst_info,
-+                                &md_alg, &imprint, &imprint_len)
-+            || !ts_check_imprints(md_alg, imprint, imprint_len, tst_info)))
-+        goto err;
-+    if ((flags & TS_VFY_NONCE)
-+        && !ts_check_nonces(ctx->nonce, tst_info))
-+        goto err;
-+    if ((flags & TS_VFY_SIGNER)
-+        && tsa_name && !ts_check_signer_name(tsa_name, signer)) {
-+        TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
-+        goto err;
-+    }
-+    if ((flags & TS_VFY_TSA_NAME)
-+        && !ts_check_signer_name(ctx->tsa_name, signer)) {
-+        TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
-+        goto err;
-+    }
-+    ret = 1;
-+
-+ err:
-+    X509_free(signer);
-+    X509_ALGOR_free(md_alg);
-+    OPENSSL_free(imprint);
-+    return ret;
-+}
-+
-+static int ts_check_status_info(TS_RESP *response)
-+{
-+    TS_STATUS_INFO *info = response->status_info;
-+    long status = ASN1_INTEGER_get(info->status);
-+    const char *status_text = NULL;
-+    char *embedded_status_text = NULL;
-+    char failure_text[TS_STATUS_BUF_SIZE] = "";
-+
-+    if (status == 0 || status == 1)
-+        return 1;
-+
-+    /* There was an error, get the description in status_text. */
-+    if (0 <= status && status < (long) OSSL_NELEM(ts_status_text))
-+        status_text = ts_status_text[status];
-+    else
-+        status_text = "unknown code";
-+
-+    if (sk_ASN1_UTF8STRING_num(info->text) > 0
-+        && (embedded_status_text = ts_get_status_text(info->text)) == NULL)
-+        return 0;
-+
-+    /* Fill in failure_text with the failure information. */
-+    if (info->failure_info) {
-+        int i;
-+        int first = 1;
-+        for (i = 0; i < (int)OSSL_NELEM(ts_failure_info); ++i) {
-+            if (ASN1_BIT_STRING_get_bit(info->failure_info,
-+                                        ts_failure_info[i].code)) {
-+                if (!first)
-+                    strcat(failure_text, ",");
-+                else
-+                    first = 0;
-+                strcat(failure_text, ts_failure_info[i].text);
-+            }
-+        }
-+    }
-+    if (failure_text[0] == '\0')
-+        strcpy(failure_text, "unspecified");
-+
-+    TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN);
-+    ERR_add_error_data(6,
-+                       "status code: ", status_text,
-+                       ", status text: ", embedded_status_text ?
-+                       embedded_status_text : "unspecified",
-+                       ", failure codes: ", failure_text);
-+    OPENSSL_free(embedded_status_text);
-+
-+    return 0;
-+}
-+
-+static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
-+{
-+    int i;
-+    int length = 0;
-+    char *result = NULL;
-+    char *p;
-+
-+    for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
-+        ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
-+        if (ASN1_STRING_length(current) > TS_MAX_STATUS_LENGTH - length - 1)
-+            return NULL;
-+        length += ASN1_STRING_length(current);
-+        length += 1;            /* separator character */
-+    }
-+    if ((result = OPENSSL_malloc(length)) == NULL) {
-+        TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) {
-+        ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
-+        length = ASN1_STRING_length(current);
-+        if (i > 0)
-+            *p++ = '/';
-+        strncpy(p, (const char *)ASN1_STRING_get0_data(current), length);
-+        p += length;
-+    }
-+    *p = '\0';
-+
-+    return result;
-+}
-+
-+static int ts_check_policy(const ASN1_OBJECT *req_oid, 
-+                           const TS_TST_INFO *tst_info)
-+{
-+    const ASN1_OBJECT *resp_oid = tst_info->policy_id;
-+
-+    if (OBJ_cmp(req_oid, resp_oid) != 0) {
-+        TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
-+                              X509_ALGOR **md_alg,
-+                              unsigned char **imprint, unsigned *imprint_len)
-+{
-+    TS_MSG_IMPRINT *msg_imprint = tst_info->msg_imprint;
-+    X509_ALGOR *md_alg_resp = msg_imprint->hash_algo;
-+    const EVP_MD *md;
-+    EVP_MD_CTX *md_ctx = NULL;
-+    unsigned char buffer[4096];
-+    int length;
-+
-+    *md_alg = NULL;
-+    *imprint = NULL;
-+
-+    if ((*md_alg = X509_ALGOR_dup(md_alg_resp)) == NULL)
-+        goto err;
-+    if ((md = EVP_get_digestbyobj((*md_alg)->algorithm)) == NULL) {
-+        TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
-+        goto err;
-+    }
-+    length = EVP_MD_size(md);
-+    if (length < 0)
-+        goto err;
-+    *imprint_len = length;
-+    if ((*imprint = OPENSSL_malloc(*imprint_len)) == NULL) {
-+        TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+
-+    md_ctx = EVP_MD_CTX_new();
-+    if (md_ctx == NULL) {
-+        TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
-+        goto err;
-+    }
-+    if (!EVP_DigestInit(md_ctx, md))
-+        goto err;
-+    while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) {
-+        if (!EVP_DigestUpdate(md_ctx, buffer, length))
-+            goto err;
-+    }
-+    if (!EVP_DigestFinal(md_ctx, *imprint, NULL))
-+        goto err;
-+    EVP_MD_CTX_free(md_ctx);
-+
-+    return 1;
-+ err:
-+    EVP_MD_CTX_free(md_ctx);
-+    X509_ALGOR_free(*md_alg);
-+    OPENSSL_free(*imprint);
-+    *imprint_len = 0;
-+    *imprint = 0;
-+    return 0;
-+}
-+
-+static int ts_check_imprints(X509_ALGOR *algor_a,
-+                             const unsigned char *imprint_a, unsigned len_a,
-+                             TS_TST_INFO *tst_info)
-+{
-+    TS_MSG_IMPRINT *b = tst_info->msg_imprint;
-+    X509_ALGOR *algor_b = b->hash_algo;
-+    int ret = 0;
-+
-+    if (algor_a) {
-+        if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm))
-+            goto err;
-+
-+        /* The parameter must be NULL in both. */
-+        if ((algor_a->parameter
-+             && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL)
-+            || (algor_b->parameter
-+                && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))
-+            goto err;
-+    }
-+
-+    ret = len_a == (unsigned)ASN1_STRING_length(b->hashed_msg) &&
-+        memcmp(imprint_a, ASN1_STRING_get0_data(b->hashed_msg), len_a) == 0;
-+ err:
-+    if (!ret)
-+        TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
-+    return ret;
-+}
-+
-+static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
-+{
-+    const ASN1_INTEGER *b = tst_info->nonce;
-+
-+    if (!b) {
-+        TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED);
-+        return 0;
-+    }
-+
-+    /* No error if a nonce is returned without being requested. */
-+    if (ASN1_INTEGER_cmp(a, b) != 0) {
-+        TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+/*
-+ * Check if the specified TSA name matches either the subject or one of the
-+ * subject alternative names of the TSA certificate.
-+ */
-+static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
-+{
-+    STACK_OF(GENERAL_NAME) *gen_names = NULL;
-+    int idx = -1;
-+    int found = 0;
-+
-+    if (tsa_name->type == GEN_DIRNAME
-+        && X509_name_cmp(tsa_name->d.dirn, X509_get_subject_name(signer)) == 0)
-+        return 1;
-+    gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, NULL, &idx);
-+    while (gen_names != NULL) {
-+        found = ts_find_name(gen_names, tsa_name) >= 0;
-+        if (found)
-+            break;
-+        /*
-+         * Get the next subject alternative name, although there should be no
-+         * more than one.
-+         */
-+        GENERAL_NAMES_free(gen_names);
-+        gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, NULL, &idx);
-+    }
-+    GENERAL_NAMES_free(gen_names);
-+
-+    return found;
-+}
-+
-+/* Returns 1 if name is in gen_names, 0 otherwise. */
-+static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name)
-+{
-+    int i, found;
-+    for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); ++i) {
-+        GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i);
-+        found = GENERAL_NAME_cmp(current, name) == 0;
-+    }
-+    return found ? i - 1 : -1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_verify_ctx.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_verify_ctx.c
-new file mode 100644
-index 0000000..d4792ee
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ts/ts_verify_ctx.c
-@@ -0,0 +1,146 @@
-+/*
-+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include "ts_lcl.h"
-+
-+TS_VERIFY_CTX *TS_VERIFY_CTX_new(void)
-+{
-+    TS_VERIFY_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
-+
-+    if (ctx == NULL)
-+        TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE);
-+    return ctx;
-+}
-+
-+void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx)
-+{
-+    OPENSSL_assert(ctx != NULL);
-+    memset(ctx, 0, sizeof(*ctx));
-+}
-+
-+void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx)
-+{
-+    if (!ctx)
-+        return;
-+
-+    TS_VERIFY_CTX_cleanup(ctx);
-+    OPENSSL_free(ctx);
-+}
-+
-+int TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int f)
-+{
-+    ctx->flags |= f;
-+    return ctx->flags;
-+}
-+
-+int TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int f)
-+{
-+    ctx->flags = f;
-+    return ctx->flags;
-+}
-+
-+BIO *TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *b)
-+{
-+    ctx->data = b;
-+    return ctx->data;
-+}
-+
-+X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *s)
-+{
-+    ctx->store = s;
-+    return ctx->store;
-+}
-+
-+STACK_OF(X509) *TS_VERIFY_CTS_set_certs(TS_VERIFY_CTX *ctx,
-+                                        STACK_OF(X509) *certs)
-+{
-+    ctx->certs = certs;
-+    return ctx->certs;
-+}
-+
-+unsigned char *TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx,
-+                                         unsigned char *hexstr, long len)
-+{
-+    ctx->imprint = hexstr;
-+    ctx->imprint_len = len;
-+    return ctx->imprint;
-+}
-+
-+void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx)
-+{
-+    if (!ctx)
-+        return;
-+
-+    X509_STORE_free(ctx->store);
-+    sk_X509_pop_free(ctx->certs, X509_free);
-+
-+    ASN1_OBJECT_free(ctx->policy);
-+
-+    X509_ALGOR_free(ctx->md_alg);
-+    OPENSSL_free(ctx->imprint);
-+
-+    BIO_free_all(ctx->data);
-+
-+    ASN1_INTEGER_free(ctx->nonce);
-+
-+    GENERAL_NAME_free(ctx->tsa_name);
-+
-+    TS_VERIFY_CTX_init(ctx);
-+}
-+
-+TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx)
-+{
-+    TS_VERIFY_CTX *ret = ctx;
-+    ASN1_OBJECT *policy;
-+    TS_MSG_IMPRINT *imprint;
-+    X509_ALGOR *md_alg;
-+    ASN1_OCTET_STRING *msg;
-+    const ASN1_INTEGER *nonce;
-+
-+    OPENSSL_assert(req != NULL);
-+    if (ret)
-+        TS_VERIFY_CTX_cleanup(ret);
-+    else if ((ret = TS_VERIFY_CTX_new()) == NULL)
-+        return NULL;
-+
-+    ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE);
-+
-+    if ((policy = req->policy_id) != NULL) {
-+        if ((ret->policy = OBJ_dup(policy)) == NULL)
-+            goto err;
-+    } else
-+        ret->flags &= ~TS_VFY_POLICY;
-+
-+    imprint = req->msg_imprint;
-+    md_alg = imprint->hash_algo;
-+    if ((ret->md_alg = X509_ALGOR_dup(md_alg)) == NULL)
-+        goto err;
-+    msg = imprint->hashed_msg;
-+    ret->imprint_len = ASN1_STRING_length(msg);
-+    if ((ret->imprint = OPENSSL_malloc(ret->imprint_len)) == NULL)
-+        goto err;
-+    memcpy(ret->imprint, ASN1_STRING_get0_data(msg), ret->imprint_len);
-+
-+    if ((nonce = req->nonce) != NULL) {
-+        if ((ret->nonce = ASN1_INTEGER_dup(nonce)) == NULL)
-+            goto err;
-+    } else
-+        ret->flags &= ~TS_VFY_NONCE;
-+
-+    return ret;
-+ err:
-+    if (ctx)
-+        TS_VERIFY_CTX_cleanup(ctx);
-+    else
-+        TS_VERIFY_CTX_free(ret);
-+    return NULL;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/txt_db/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/txt_db/build.info
-new file mode 100644
-index 0000000..4379d5f
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/txt_db/build.info
-@@ -0,0 +1,2 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=txt_db.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/txt_db/txt_db.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/txt_db/txt_db.c
-new file mode 100644
-index 0000000..1432230
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/txt_db/txt_db.c
-@@ -0,0 +1,301 @@
-+/*
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+
-+#undef BUFSIZE
-+#define BUFSIZE 512
-+
-+TXT_DB *TXT_DB_read(BIO *in, int num)
-+{
-+    TXT_DB *ret = NULL;
-+    int esc = 0;
-+    long ln = 0;
-+    int i, add, n;
-+    int size = BUFSIZE;
-+    int offset = 0;
-+    char *p, *f;
-+    OPENSSL_STRING *pp;
-+    BUF_MEM *buf = NULL;
-+
-+    if ((buf = BUF_MEM_new()) == NULL)
-+        goto err;
-+    if (!BUF_MEM_grow(buf, size))
-+        goto err;
-+
-+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
-+        goto err;
-+    ret->num_fields = num;
-+    ret->index = NULL;
-+    ret->qual = NULL;
-+    if ((ret->data = sk_OPENSSL_PSTRING_new_null()) == NULL)
-+        goto err;
-+    if ((ret->index = OPENSSL_malloc(sizeof(*ret->index) * num)) == NULL)
-+        goto err;
-+    if ((ret->qual = OPENSSL_malloc(sizeof(*(ret->qual)) * num)) == NULL)
-+        goto err;
-+    for (i = 0; i < num; i++) {
-+        ret->index[i] = NULL;
-+        ret->qual[i] = NULL;
-+    }
-+
-+    add = (num + 1) * sizeof(char *);
-+    buf->data[size - 1] = '\0';
-+    offset = 0;
-+    for (;;) {
-+        if (offset != 0) {
-+            size += BUFSIZE;
-+            if (!BUF_MEM_grow_clean(buf, size))
-+                goto err;
-+        }
-+        buf->data[offset] = '\0';
-+        BIO_gets(in, &(buf->data[offset]), size - offset);
-+        ln++;
-+        if (buf->data[offset] == '\0')
-+            break;
-+        if ((offset == 0) && (buf->data[0] == '#'))
-+            continue;
-+        i = strlen(&(buf->data[offset]));
-+        offset += i;
-+        if (buf->data[offset - 1] != '\n')
-+            continue;
-+        else {
-+            buf->data[offset - 1] = '\0'; /* blat the '\n' */
-+            if ((p = OPENSSL_malloc(add + offset)) == NULL)
-+                goto err;
-+            offset = 0;
-+        }
-+        pp = (char **)p;
-+        p += add;
-+        n = 0;
-+        pp[n++] = p;
-+        i = 0;
-+        f = buf->data;
-+
-+        esc = 0;
-+        for (;;) {
-+            if (*f == '\0')
-+                break;
-+            if (*f == '\t') {
-+                if (esc)
-+                    p--;
-+                else {
-+                    *(p++) = '\0';
-+                    f++;
-+                    if (n >= num)
-+                        break;
-+                    pp[n++] = p;
-+                    continue;
-+                }
-+            }
-+            esc = (*f == '\\');
-+            *(p++) = *(f++);
-+        }
-+        *(p++) = '\0';
-+        if ((n != num) || (*f != '\0')) {
-+            ret->error = DB_ERROR_WRONG_NUM_FIELDS;
-+            goto err;
-+        }
-+        pp[n] = p;
-+        if (!sk_OPENSSL_PSTRING_push(ret->data, pp))
-+            goto err;
-+    }
-+    BUF_MEM_free(buf);
-+    return ret;
-+ err:
-+    BUF_MEM_free(buf);
-+    if (ret != NULL) {
-+        sk_OPENSSL_PSTRING_free(ret->data);
-+        OPENSSL_free(ret->index);
-+        OPENSSL_free(ret->qual);
-+        OPENSSL_free(ret);
-+    }
-+    return (NULL);
-+}
-+
-+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx,
-+                                    OPENSSL_STRING *value)
-+{
-+    OPENSSL_STRING *ret;
-+    LHASH_OF(OPENSSL_STRING) *lh;
-+
-+    if (idx >= db->num_fields) {
-+        db->error = DB_ERROR_INDEX_OUT_OF_RANGE;
-+        return (NULL);
-+    }
-+    lh = db->index[idx];
-+    if (lh == NULL) {
-+        db->error = DB_ERROR_NO_INDEX;
-+        return (NULL);
-+    }
-+    ret = lh_OPENSSL_STRING_retrieve(lh, value);
-+    db->error = DB_ERROR_OK;
-+    return (ret);
-+}
-+
-+int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
-+                        OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC cmp)
-+{
-+    LHASH_OF(OPENSSL_STRING) *idx;
-+    OPENSSL_STRING *r;
-+    int i, n;
-+
-+    if (field >= db->num_fields) {
-+        db->error = DB_ERROR_INDEX_OUT_OF_RANGE;
-+        return (0);
-+    }
-+    /* FIXME: we lose type checking at this point */
-+    if ((idx = (LHASH_OF(OPENSSL_STRING) *)OPENSSL_LH_new(hash, cmp)) == NULL) {
-+        db->error = DB_ERROR_MALLOC;
-+        return (0);
-+    }
-+    n = sk_OPENSSL_PSTRING_num(db->data);
-+    for (i = 0; i < n; i++) {
-+        r = sk_OPENSSL_PSTRING_value(db->data, i);
-+        if ((qual != NULL) && (qual(r) == 0))
-+            continue;
-+        if ((r = lh_OPENSSL_STRING_insert(idx, r)) != NULL) {
-+            db->error = DB_ERROR_INDEX_CLASH;
-+            db->arg1 = sk_OPENSSL_PSTRING_find(db->data, r);
-+            db->arg2 = i;
-+            lh_OPENSSL_STRING_free(idx);
-+            return (0);
-+        }
-+    }
-+    lh_OPENSSL_STRING_free(db->index[field]);
-+    db->index[field] = idx;
-+    db->qual[field] = qual;
-+    return (1);
-+}
-+
-+long TXT_DB_write(BIO *out, TXT_DB *db)
-+{
-+    long i, j, n, nn, l, tot = 0;
-+    char *p, **pp, *f;
-+    BUF_MEM *buf = NULL;
-+    long ret = -1;
-+
-+    if ((buf = BUF_MEM_new()) == NULL)
-+        goto err;
-+    n = sk_OPENSSL_PSTRING_num(db->data);
-+    nn = db->num_fields;
-+    for (i = 0; i < n; i++) {
-+        pp = sk_OPENSSL_PSTRING_value(db->data, i);
-+
-+        l = 0;
-+        for (j = 0; j < nn; j++) {
-+            if (pp[j] != NULL)
-+                l += strlen(pp[j]);
-+        }
-+        if (!BUF_MEM_grow_clean(buf, (int)(l * 2 + nn)))
-+            goto err;
-+
-+        p = buf->data;
-+        for (j = 0; j < nn; j++) {
-+            f = pp[j];
-+            if (f != NULL)
-+                for (;;) {
-+                    if (*f == '\0')
-+                        break;
-+                    if (*f == '\t')
-+                        *(p++) = '\\';
-+                    *(p++) = *(f++);
-+                }
-+            *(p++) = '\t';
-+        }
-+        p[-1] = '\n';
-+        j = p - buf->data;
-+        if (BIO_write(out, buf->data, (int)j) != j)
-+            goto err;
-+        tot += j;
-+    }
-+    ret = tot;
-+ err:
-+    BUF_MEM_free(buf);
-+    return (ret);
-+}
-+
-+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
-+{
-+    int i;
-+    OPENSSL_STRING *r;
-+
-+    for (i = 0; i < db->num_fields; i++) {
-+        if (db->index[i] != NULL) {
-+            if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
-+                continue;
-+            r = lh_OPENSSL_STRING_retrieve(db->index[i], row);
-+            if (r != NULL) {
-+                db->error = DB_ERROR_INDEX_CLASH;
-+                db->arg1 = i;
-+                db->arg_row = r;
-+                goto err;
-+            }
-+        }
-+    }
-+    /* We have passed the index checks, now just append and insert */
-+    if (!sk_OPENSSL_PSTRING_push(db->data, row)) {
-+        db->error = DB_ERROR_MALLOC;
-+        goto err;
-+    }
-+
-+    for (i = 0; i < db->num_fields; i++) {
-+        if (db->index[i] != NULL) {
-+            if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
-+                continue;
-+            (void)lh_OPENSSL_STRING_insert(db->index[i], row);
-+        }
-+    }
-+    return (1);
-+ err:
-+    return (0);
-+}
-+
-+void TXT_DB_free(TXT_DB *db)
-+{
-+    int i, n;
-+    char **p, *max;
-+
-+    if (db == NULL)
-+        return;
-+
-+    if (db->index != NULL) {
-+        for (i = db->num_fields - 1; i >= 0; i--)
-+            lh_OPENSSL_STRING_free(db->index[i]);
-+        OPENSSL_free(db->index);
-+    }
-+    OPENSSL_free(db->qual);
-+    if (db->data != NULL) {
-+        for (i = sk_OPENSSL_PSTRING_num(db->data) - 1; i >= 0; i--) {
-+            /*
-+             * check if any 'fields' have been allocated from outside of the
-+             * initial block
-+             */
-+            p = sk_OPENSSL_PSTRING_value(db->data, i);
-+            max = p[db->num_fields]; /* last address */
-+            if (max == NULL) {  /* new row */
-+                for (n = 0; n < db->num_fields; n++)
-+                    OPENSSL_free(p[n]);
-+            } else {
-+                for (n = 0; n < db->num_fields; n++) {
-+                    if (((p[n] < (char *)p) || (p[n] > max)))
-+                        OPENSSL_free(p[n]);
-+                }
-+            }
-+            OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data, i));
-+        }
-+        sk_OPENSSL_PSTRING_free(db->data);
-+    }
-+    OPENSSL_free(db);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/build.info
-new file mode 100644
-index 0000000..fcb45af
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/build.info
-@@ -0,0 +1,3 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=\
-+        ui_err.c ui_lib.c ui_openssl.c ui_util.c
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_err.c
-new file mode 100644
-index 0000000..c8640fe
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_err.c
-@@ -0,0 +1,72 @@
-+/*
-+ * Generated by util/mkerr.pl DO NOT EDIT
-+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+#include 
-+
-+/* BEGIN ERROR CODES */
-+#ifndef OPENSSL_NO_ERR
-+
-+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_UI,func,0)
-+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_UI,0,reason)
-+
-+static ERR_STRING_DATA UI_str_functs[] = {
-+    {ERR_FUNC(UI_F_CLOSE_CONSOLE), "close_console"},
-+    {ERR_FUNC(UI_F_ECHO_CONSOLE), "echo_console"},
-+    {ERR_FUNC(UI_F_GENERAL_ALLOCATE_BOOLEAN), "general_allocate_boolean"},
-+    {ERR_FUNC(UI_F_GENERAL_ALLOCATE_PROMPT), "general_allocate_prompt"},
-+    {ERR_FUNC(UI_F_NOECHO_CONSOLE), "noecho_console"},
-+    {ERR_FUNC(UI_F_OPEN_CONSOLE), "open_console"},
-+    {ERR_FUNC(UI_F_UI_CREATE_METHOD), "UI_create_method"},
-+    {ERR_FUNC(UI_F_UI_CTRL), "UI_ctrl"},
-+    {ERR_FUNC(UI_F_UI_DUP_ERROR_STRING), "UI_dup_error_string"},
-+    {ERR_FUNC(UI_F_UI_DUP_INFO_STRING), "UI_dup_info_string"},
-+    {ERR_FUNC(UI_F_UI_DUP_INPUT_BOOLEAN), "UI_dup_input_boolean"},
-+    {ERR_FUNC(UI_F_UI_DUP_INPUT_STRING), "UI_dup_input_string"},
-+    {ERR_FUNC(UI_F_UI_DUP_VERIFY_STRING), "UI_dup_verify_string"},
-+    {ERR_FUNC(UI_F_UI_GET0_RESULT), "UI_get0_result"},
-+    {ERR_FUNC(UI_F_UI_NEW_METHOD), "UI_new_method"},
-+    {ERR_FUNC(UI_F_UI_PROCESS), "UI_process"},
-+    {ERR_FUNC(UI_F_UI_SET_RESULT), "UI_set_result"},
-+    {0, NULL}
-+};
-+
-+static ERR_STRING_DATA UI_str_reasons[] = {
-+    {ERR_REASON(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS),
-+     "common ok and cancel characters"},
-+    {ERR_REASON(UI_R_INDEX_TOO_LARGE), "index too large"},
-+    {ERR_REASON(UI_R_INDEX_TOO_SMALL), "index too small"},
-+    {ERR_REASON(UI_R_NO_RESULT_BUFFER), "no result buffer"},
-+    {ERR_REASON(UI_R_PROCESSING_ERROR), "processing error"},
-+    {ERR_REASON(UI_R_RESULT_TOO_LARGE), "result too large"},
-+    {ERR_REASON(UI_R_RESULT_TOO_SMALL), "result too small"},
-+    {ERR_REASON(UI_R_SYSASSIGN_ERROR), "sys$assign error"},
-+    {ERR_REASON(UI_R_SYSDASSGN_ERROR), "sys$dassgn error"},
-+    {ERR_REASON(UI_R_SYSQIOW_ERROR), "sys$qiow error"},
-+    {ERR_REASON(UI_R_UNKNOWN_CONTROL_COMMAND), "unknown control command"},
-+    {ERR_REASON(UI_R_UNKNOWN_TTYGET_ERRNO_VALUE),
-+     "unknown ttyget errno value"},
-+    {0, NULL}
-+};
-+
-+#endif
-+
-+int ERR_load_UI_strings(void)
-+{
-+#ifndef OPENSSL_NO_ERR
-+
-+    if (ERR_func_error_string(UI_str_functs[0].error) == NULL) {
-+        ERR_load_strings(0, UI_str_functs);
-+        ERR_load_strings(0, UI_str_reasons);
-+    }
-+#endif
-+    return 1;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_lib.c
-new file mode 100644
-index 0000000..12d62d8
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_lib.c
-@@ -0,0 +1,826 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "internal/cryptlib.h"
-+#include 
-+#include 
-+#include 
-+#include 
-+#include "ui_locl.h"
-+
-+static const UI_METHOD *default_UI_meth = NULL;
-+
-+UI *UI_new(void)
-+{
-+    return (UI_new_method(NULL));
-+}
-+
-+UI *UI_new_method(const UI_METHOD *method)
-+{
-+    UI *ret = OPENSSL_zalloc(sizeof(*ret));
-+
-+    if (ret == NULL) {
-+        UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        return NULL;
-+    }
-+
-+    ret->lock = CRYPTO_THREAD_lock_new();
-+    if (ret->lock == NULL) {
-+        UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+
-+    if (method == NULL)
-+        ret->meth = UI_get_default_method();
-+    else
-+        ret->meth = method;
-+
-+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data)) {
-+        OPENSSL_free(ret);
-+        return NULL;
-+    }
-+    return ret;
-+}
-+
-+static void free_string(UI_STRING *uis)
-+{
-+    if (uis->flags & OUT_STRING_FREEABLE) {
-+        OPENSSL_free((char *)uis->out_string);
-+        switch (uis->type) {
-+        case UIT_BOOLEAN:
-+            OPENSSL_free((char *)uis->_.boolean_data.action_desc);
-+            OPENSSL_free((char *)uis->_.boolean_data.ok_chars);
-+            OPENSSL_free((char *)uis->_.boolean_data.cancel_chars);
-+            break;
-+        default:
-+            break;
-+        }
-+    }
-+    OPENSSL_free(uis);
-+}
-+
-+void UI_free(UI *ui)
-+{
-+    if (ui == NULL)
-+        return;
-+    sk_UI_STRING_pop_free(ui->strings, free_string);
-+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data);
-+    CRYPTO_THREAD_lock_free(ui->lock);
-+    OPENSSL_free(ui);
-+}
-+
-+static int allocate_string_stack(UI *ui)
-+{
-+    if (ui->strings == NULL) {
-+        ui->strings = sk_UI_STRING_new_null();
-+        if (ui->strings == NULL) {
-+            return -1;
-+        }
-+    }
-+    return 0;
-+}
-+
-+static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt,
-+                                          int prompt_freeable,
-+                                          enum UI_string_types type,
-+                                          int input_flags, char *result_buf)
-+{
-+    UI_STRING *ret = NULL;
-+
-+    if (prompt == NULL) {
-+        UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, ERR_R_PASSED_NULL_PARAMETER);
-+    } else if ((type == UIT_PROMPT || type == UIT_VERIFY
-+                || type == UIT_BOOLEAN) && result_buf == NULL) {
-+        UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, UI_R_NO_RESULT_BUFFER);
-+    } else if ((ret = OPENSSL_malloc(sizeof(*ret))) != NULL) {
-+        ret->out_string = prompt;
-+        ret->flags = prompt_freeable ? OUT_STRING_FREEABLE : 0;
-+        ret->input_flags = input_flags;
-+        ret->type = type;
-+        ret->result_buf = result_buf;
-+    }
-+    return ret;
-+}
-+
-+static int general_allocate_string(UI *ui, const char *prompt,
-+                                   int prompt_freeable,
-+                                   enum UI_string_types type, int input_flags,
-+                                   char *result_buf, int minsize, int maxsize,
-+                                   const char *test_buf)
-+{
-+    int ret = -1;
-+    UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
-+                                           type, input_flags, result_buf);
-+
-+    if (s != NULL) {
-+        if (allocate_string_stack(ui) >= 0) {
-+            s->_.string_data.result_minsize = minsize;
-+            s->_.string_data.result_maxsize = maxsize;
-+            s->_.string_data.test_buf = test_buf;
-+            ret = sk_UI_STRING_push(ui->strings, s);
-+            /* sk_push() returns 0 on error.  Let's adapt that */
-+            if (ret <= 0) {
-+                ret--;
-+                free_string(s);
-+            }
-+        } else
-+            free_string(s);
-+    }
-+    return ret;
-+}
-+
-+static int general_allocate_boolean(UI *ui,
-+                                    const char *prompt,
-+                                    const char *action_desc,
-+                                    const char *ok_chars,
-+                                    const char *cancel_chars,
-+                                    int prompt_freeable,
-+                                    enum UI_string_types type,
-+                                    int input_flags, char *result_buf)
-+{
-+    int ret = -1;
-+    UI_STRING *s;
-+    const char *p;
-+
-+    if (ok_chars == NULL) {
-+        UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER);
-+    } else if (cancel_chars == NULL) {
-+        UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER);
-+    } else {
-+        for (p = ok_chars; *p != '\0'; p++) {
-+            if (strchr(cancel_chars, *p) != NULL) {
-+                UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
-+                      UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
-+            }
-+        }
-+
-+        s = general_allocate_prompt(ui, prompt, prompt_freeable,
-+                                    type, input_flags, result_buf);
-+
-+        if (s != NULL) {
-+            if (allocate_string_stack(ui) >= 0) {
-+                s->_.boolean_data.action_desc = action_desc;
-+                s->_.boolean_data.ok_chars = ok_chars;
-+                s->_.boolean_data.cancel_chars = cancel_chars;
-+                ret = sk_UI_STRING_push(ui->strings, s);
-+                /*
-+                 * sk_push() returns 0 on error. Let's adapt that
-+                 */
-+                if (ret <= 0) {
-+                    ret--;
-+                    free_string(s);
-+                }
-+            } else
-+                free_string(s);
-+        }
-+    }
-+    return ret;
-+}
-+
-+/*
-+ * Returns the index to the place in the stack or -1 for error.  Uses a
-+ * direct reference to the prompt.
-+ */
-+int UI_add_input_string(UI *ui, const char *prompt, int flags,
-+                        char *result_buf, int minsize, int maxsize)
-+{
-+    return general_allocate_string(ui, prompt, 0,
-+                                   UIT_PROMPT, flags, result_buf, minsize,
-+                                   maxsize, NULL);
-+}
-+
-+/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */
-+int UI_dup_input_string(UI *ui, const char *prompt, int flags,
-+                        char *result_buf, int minsize, int maxsize)
-+{
-+    char *prompt_copy = NULL;
-+
-+    if (prompt != NULL) {
-+        prompt_copy = OPENSSL_strdup(prompt);
-+        if (prompt_copy == NULL) {
-+            UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE);
-+            return 0;
-+        }
-+    }
-+
-+    return general_allocate_string(ui, prompt_copy, 1,
-+                                   UIT_PROMPT, flags, result_buf, minsize,
-+                                   maxsize, NULL);
-+}
-+
-+int UI_add_verify_string(UI *ui, const char *prompt, int flags,
-+                         char *result_buf, int minsize, int maxsize,
-+                         const char *test_buf)
-+{
-+    return general_allocate_string(ui, prompt, 0,
-+                                   UIT_VERIFY, flags, result_buf, minsize,
-+                                   maxsize, test_buf);
-+}
-+
-+int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
-+                         char *result_buf, int minsize, int maxsize,
-+                         const char *test_buf)
-+{
-+    char *prompt_copy = NULL;
-+
-+    if (prompt != NULL) {
-+        prompt_copy = OPENSSL_strdup(prompt);
-+        if (prompt_copy == NULL) {
-+            UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE);
-+            return -1;
-+        }
-+    }
-+
-+    return general_allocate_string(ui, prompt_copy, 1,
-+                                   UIT_VERIFY, flags, result_buf, minsize,
-+                                   maxsize, test_buf);
-+}
-+
-+int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
-+                         const char *ok_chars, const char *cancel_chars,
-+                         int flags, char *result_buf)
-+{
-+    return general_allocate_boolean(ui, prompt, action_desc,
-+                                    ok_chars, cancel_chars, 0, UIT_BOOLEAN,
-+                                    flags, result_buf);
-+}
-+
-+int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
-+                         const char *ok_chars, const char *cancel_chars,
-+                         int flags, char *result_buf)
-+{
-+    char *prompt_copy = NULL;
-+    char *action_desc_copy = NULL;
-+    char *ok_chars_copy = NULL;
-+    char *cancel_chars_copy = NULL;
-+
-+    if (prompt != NULL) {
-+        prompt_copy = OPENSSL_strdup(prompt);
-+        if (prompt_copy == NULL) {
-+            UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    }
-+
-+    if (action_desc != NULL) {
-+        action_desc_copy = OPENSSL_strdup(action_desc);
-+        if (action_desc_copy == NULL) {
-+            UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    }
-+
-+    if (ok_chars != NULL) {
-+        ok_chars_copy = OPENSSL_strdup(ok_chars);
-+        if (ok_chars_copy == NULL) {
-+            UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    }
-+
-+    if (cancel_chars != NULL) {
-+        cancel_chars_copy = OPENSSL_strdup(cancel_chars);
-+        if (cancel_chars_copy == NULL) {
-+            UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
-+            goto err;
-+        }
-+    }
-+
-+    return general_allocate_boolean(ui, prompt_copy, action_desc_copy,
-+                                    ok_chars_copy, cancel_chars_copy, 1,
-+                                    UIT_BOOLEAN, flags, result_buf);
-+ err:
-+    OPENSSL_free(prompt_copy);
-+    OPENSSL_free(action_desc_copy);
-+    OPENSSL_free(ok_chars_copy);
-+    OPENSSL_free(cancel_chars_copy);
-+    return -1;
-+}
-+
-+int UI_add_info_string(UI *ui, const char *text)
-+{
-+    return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0,
-+                                   NULL);
-+}
-+
-+int UI_dup_info_string(UI *ui, const char *text)
-+{
-+    char *text_copy = NULL;
-+
-+    if (text != NULL) {
-+        text_copy = OPENSSL_strdup(text);
-+        if (text_copy == NULL) {
-+            UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE);
-+            return -1;
-+        }
-+    }
-+
-+    return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL,
-+                                   0, 0, NULL);
-+}
-+
-+int UI_add_error_string(UI *ui, const char *text)
-+{
-+    return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0,
-+                                   NULL);
-+}
-+
-+int UI_dup_error_string(UI *ui, const char *text)
-+{
-+    char *text_copy = NULL;
-+
-+    if (text != NULL) {
-+        text_copy = OPENSSL_strdup(text);
-+        if (text_copy == NULL) {
-+            UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE);
-+            return -1;
-+        }
-+    }
-+    return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL,
-+                                   0, 0, NULL);
-+}
-+
-+char *UI_construct_prompt(UI *ui, const char *object_desc,
-+                          const char *object_name)
-+{
-+    char *prompt = NULL;
-+
-+    if (ui->meth->ui_construct_prompt != NULL)
-+        prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name);
-+    else {
-+        char prompt1[] = "Enter ";
-+        char prompt2[] = " for ";
-+        char prompt3[] = ":";
-+        int len = 0;
-+
-+        if (object_desc == NULL)
-+            return NULL;
-+        len = sizeof(prompt1) - 1 + strlen(object_desc);
-+        if (object_name != NULL)
-+            len += sizeof(prompt2) - 1 + strlen(object_name);
-+        len += sizeof(prompt3) - 1;
-+
-+        prompt = OPENSSL_malloc(len + 1);
-+        if (prompt == NULL)
-+            return NULL;
-+        OPENSSL_strlcpy(prompt, prompt1, len + 1);
-+        OPENSSL_strlcat(prompt, object_desc, len + 1);
-+        if (object_name != NULL) {
-+            OPENSSL_strlcat(prompt, prompt2, len + 1);
-+            OPENSSL_strlcat(prompt, object_name, len + 1);
-+        }
-+        OPENSSL_strlcat(prompt, prompt3, len + 1);
-+    }
-+    return prompt;
-+}
-+
-+void *UI_add_user_data(UI *ui, void *user_data)
-+{
-+    void *old_data = ui->user_data;
-+    ui->user_data = user_data;
-+    return old_data;
-+}
-+
-+void *UI_get0_user_data(UI *ui)
-+{
-+    return ui->user_data;
-+}
-+
-+const char *UI_get0_result(UI *ui, int i)
-+{
-+    if (i < 0) {
-+        UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_SMALL);
-+        return NULL;
-+    }
-+    if (i >= sk_UI_STRING_num(ui->strings)) {
-+        UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_LARGE);
-+        return NULL;
-+    }
-+    return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i));
-+}
-+
-+static int print_error(const char *str, size_t len, UI *ui)
-+{
-+    UI_STRING uis;
-+
-+    memset(&uis, 0, sizeof(uis));
-+    uis.type = UIT_ERROR;
-+    uis.out_string = str;
-+
-+    if (ui->meth->ui_write_string != NULL
-+        && ui->meth->ui_write_string(ui, &uis) <= 0)
-+        return -1;
-+    return 0;
-+}
-+
-+int UI_process(UI *ui)
-+{
-+    int i, ok = 0;
-+    const char *state = "processing";
-+
-+    if (ui->meth->ui_open_session != NULL
-+        && ui->meth->ui_open_session(ui) <= 0) {
-+        state = "opening session";
-+        ok = -1;
-+        goto err;
-+    }
-+
-+    if (ui->flags & UI_FLAG_PRINT_ERRORS)
-+        ERR_print_errors_cb((int (*)(const char *, size_t, void *))
-+                            print_error, (void *)ui);
-+
-+    for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
-+        if (ui->meth->ui_write_string != NULL
-+            && (ui->meth->ui_write_string(ui,
-+                                          sk_UI_STRING_value(ui->strings, i))
-+                <= 0))
-+        {
-+            state = "writing strings";
-+            ok = -1;
-+            goto err;
-+        }
-+    }
-+
-+    if (ui->meth->ui_flush != NULL)
-+        switch (ui->meth->ui_flush(ui)) {
-+        case -1:               /* Interrupt/Cancel/something... */
-+            ok = -2;
-+            goto err;
-+        case 0:                /* Errors */
-+            state = "flushing";
-+            ok = -1;
-+            goto err;
-+        default:               /* Success */
-+            ok = 0;
-+            break;
-+        }
-+
-+    for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
-+        if (ui->meth->ui_read_string != NULL) {
-+            switch (ui->meth->ui_read_string(ui,
-+                                             sk_UI_STRING_value(ui->strings,
-+                                                                i))) {
-+            case -1:           /* Interrupt/Cancel/something... */
-+                ok = -2;
-+                goto err;
-+            case 0:            /* Errors */
-+                state = "reading strings";
-+                ok = -1;
-+                goto err;
-+            default:           /* Success */
-+                ok = 0;
-+                break;
-+            }
-+        }
-+    }
-+ err:
-+    if (ui->meth->ui_close_session != NULL
-+        && ui->meth->ui_close_session(ui) <= 0) {
-+        if (state == NULL)
-+            state = "closing session";
-+        ok = -1;
-+    }
-+
-+    if (ok == -1) {
-+        UIerr(UI_F_UI_PROCESS, UI_R_PROCESSING_ERROR);
-+        ERR_add_error_data(2, "while ", state);
-+    }
-+    return ok;
-+}
-+
-+int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void))
-+{
-+    if (ui == NULL) {
-+        UIerr(UI_F_UI_CTRL, ERR_R_PASSED_NULL_PARAMETER);
-+        return -1;
-+    }
-+    switch (cmd) {
-+    case UI_CTRL_PRINT_ERRORS:
-+        {
-+            int save_flag = ! !(ui->flags & UI_FLAG_PRINT_ERRORS);
-+            if (i)
-+                ui->flags |= UI_FLAG_PRINT_ERRORS;
-+            else
-+                ui->flags &= ~UI_FLAG_PRINT_ERRORS;
-+            return save_flag;
-+        }
-+    case UI_CTRL_IS_REDOABLE:
-+        return ! !(ui->flags & UI_FLAG_REDOABLE);
-+    default:
-+        break;
-+    }
-+    UIerr(UI_F_UI_CTRL, UI_R_UNKNOWN_CONTROL_COMMAND);
-+    return -1;
-+}
-+
-+int UI_set_ex_data(UI *r, int idx, void *arg)
-+{
-+    return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
-+}
-+
-+void *UI_get_ex_data(UI *r, int idx)
-+{
-+    return (CRYPTO_get_ex_data(&r->ex_data, idx));
-+}
-+
-+void UI_set_default_method(const UI_METHOD *meth)
-+{
-+    default_UI_meth = meth;
-+}
-+
-+const UI_METHOD *UI_get_default_method(void)
-+{
-+    if (default_UI_meth == NULL) {
-+        default_UI_meth = UI_OpenSSL();
-+    }
-+    return default_UI_meth;
-+}
-+
-+const UI_METHOD *UI_get_method(UI *ui)
-+{
-+    return ui->meth;
-+}
-+
-+const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth)
-+{
-+    ui->meth = meth;
-+    return ui->meth;
-+}
-+
-+UI_METHOD *UI_create_method(const char *name)
-+{
-+    UI_METHOD *ui_method = OPENSSL_zalloc(sizeof(*ui_method));
-+
-+    if (ui_method != NULL) {
-+        ui_method->name = OPENSSL_strdup(name);
-+        if (ui_method->name == NULL) {
-+            OPENSSL_free(ui_method);
-+            UIerr(UI_F_UI_CREATE_METHOD, ERR_R_MALLOC_FAILURE);
-+            return NULL;
-+        }
-+    }
-+    return ui_method;
-+}
-+
-+/*
-+ * BIG FSCKING WARNING!!!! If you use this on a statically allocated method
-+ * (that is, it hasn't been allocated using UI_create_method(), you deserve
-+ * anything Murphy can throw at you and more! You have been warned.
-+ */
-+void UI_destroy_method(UI_METHOD *ui_method)
-+{
-+    OPENSSL_free(ui_method->name);
-+    ui_method->name = NULL;
-+    OPENSSL_free(ui_method);
-+}
-+
-+int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui))
-+{
-+    if (method != NULL) {
-+        method->ui_open_session = opener;
-+        return 0;
-+    }
-+    return -1;
-+}
-+
-+int UI_method_set_writer(UI_METHOD *method,
-+                         int (*writer) (UI *ui, UI_STRING *uis))
-+{
-+    if (method != NULL) {
-+        method->ui_write_string = writer;
-+        return 0;
-+    }
-+    return -1;
-+}
-+
-+int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui))
-+{
-+    if (method != NULL) {
-+        method->ui_flush = flusher;
-+        return 0;
-+    }
-+    return -1;
-+}
-+
-+int UI_method_set_reader(UI_METHOD *method,
-+                         int (*reader) (UI *ui, UI_STRING *uis))
-+{
-+    if (method != NULL) {
-+        method->ui_read_string = reader;
-+        return 0;
-+    }
-+    return -1;
-+}
-+
-+int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui))
-+{
-+    if (method != NULL) {
-+        method->ui_close_session = closer;
-+        return 0;
-+    }
-+    return -1;
-+}
-+
-+int UI_method_set_prompt_constructor(UI_METHOD *method,
-+                                     char *(*prompt_constructor) (UI *ui,
-+                                                                  const char
-+                                                                  *object_desc,
-+                                                                  const char
-+                                                                  *object_name))
-+{
-+    if (method != NULL) {
-+        method->ui_construct_prompt = prompt_constructor;
-+        return 0;
-+    }
-+    return -1;
-+}
-+
-+int (*UI_method_get_opener(UI_METHOD *method)) (UI *)
-+{
-+    if (method != NULL)
-+        return method->ui_open_session;
-+    return NULL;
-+}
-+
-+int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *)
-+{
-+    if (method != NULL)
-+        return method->ui_write_string;
-+    return NULL;
-+}
-+
-+int (*UI_method_get_flusher(UI_METHOD *method)) (UI *)
-+{
-+    if (method != NULL)
-+        return method->ui_flush;
-+    return NULL;
-+}
-+
-+int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *)
-+{
-+    if (method != NULL)
-+        return method->ui_read_string;
-+    return NULL;
-+}
-+
-+int (*UI_method_get_closer(UI_METHOD *method)) (UI *)
-+{
-+    if (method != NULL)
-+        return method->ui_close_session;
-+    return NULL;
-+}
-+
-+char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
-+                                                              const char *,
-+                                                              const char *)
-+{
-+    if (method != NULL)
-+        return method->ui_construct_prompt;
-+    return NULL;
-+}
-+
-+enum UI_string_types UI_get_string_type(UI_STRING *uis)
-+{
-+    return uis->type;
-+}
-+
-+int UI_get_input_flags(UI_STRING *uis)
-+{
-+    return uis->input_flags;
-+}
-+
-+const char *UI_get0_output_string(UI_STRING *uis)
-+{
-+    return uis->out_string;
-+}
-+
-+const char *UI_get0_action_string(UI_STRING *uis)
-+{
-+    switch (uis->type) {
-+    case UIT_PROMPT:
-+    case UIT_BOOLEAN:
-+        return uis->_.boolean_data.action_desc;
-+    default:
-+        return NULL;
-+    }
-+}
-+
-+const char *UI_get0_result_string(UI_STRING *uis)
-+{
-+    switch (uis->type) {
-+    case UIT_PROMPT:
-+    case UIT_VERIFY:
-+        return uis->result_buf;
-+    default:
-+        return NULL;
-+    }
-+}
-+
-+const char *UI_get0_test_string(UI_STRING *uis)
-+{
-+    switch (uis->type) {
-+    case UIT_VERIFY:
-+        return uis->_.string_data.test_buf;
-+    default:
-+        return NULL;
-+    }
-+}
-+
-+int UI_get_result_minsize(UI_STRING *uis)
-+{
-+    switch (uis->type) {
-+    case UIT_PROMPT:
-+    case UIT_VERIFY:
-+        return uis->_.string_data.result_minsize;
-+    default:
-+        return -1;
-+    }
-+}
-+
-+int UI_get_result_maxsize(UI_STRING *uis)
-+{
-+    switch (uis->type) {
-+    case UIT_PROMPT:
-+    case UIT_VERIFY:
-+        return uis->_.string_data.result_maxsize;
-+    default:
-+        return -1;
-+    }
-+}
-+
-+int UI_set_result(UI *ui, UI_STRING *uis, const char *result)
-+{
-+    int l = strlen(result);
-+
-+    ui->flags &= ~UI_FLAG_REDOABLE;
-+
-+    switch (uis->type) {
-+    case UIT_PROMPT:
-+    case UIT_VERIFY:
-+        {
-+            char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize) + 1];
-+            char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize) + 1];
-+
-+            BIO_snprintf(number1, sizeof(number1), "%d",
-+                         uis->_.string_data.result_minsize);
-+            BIO_snprintf(number2, sizeof(number2), "%d",
-+                         uis->_.string_data.result_maxsize);
-+
-+            if (l < uis->_.string_data.result_minsize) {
-+                ui->flags |= UI_FLAG_REDOABLE;
-+                UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_SMALL);
-+                ERR_add_error_data(5, "You must type in ",
-+                                   number1, " to ", number2, " characters");
-+                return -1;
-+            }
-+            if (l > uis->_.string_data.result_maxsize) {
-+                ui->flags |= UI_FLAG_REDOABLE;
-+                UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_LARGE);
-+                ERR_add_error_data(5, "You must type in ",
-+                                   number1, " to ", number2, " characters");
-+                return -1;
-+            }
-+        }
-+
-+        if (uis->result_buf == NULL) {
-+            UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
-+            return -1;
-+        }
-+
-+        OPENSSL_strlcpy(uis->result_buf, result,
-+                    uis->_.string_data.result_maxsize + 1);
-+        break;
-+    case UIT_BOOLEAN:
-+        {
-+            const char *p;
-+
-+            if (uis->result_buf == NULL) {
-+                UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER);
-+                return -1;
-+            }
-+
-+            uis->result_buf[0] = '\0';
-+            for (p = result; *p; p++) {
-+                if (strchr(uis->_.boolean_data.ok_chars, *p)) {
-+                    uis->result_buf[0] = uis->_.boolean_data.ok_chars[0];
-+                    break;
-+                }
-+                if (strchr(uis->_.boolean_data.cancel_chars, *p)) {
-+                    uis->result_buf[0] = uis->_.boolean_data.cancel_chars[0];
-+                    break;
-+                }
-+            }
-+        }
-+    default:
-+        break;
-+    }
-+    return 0;
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_locl.h
-new file mode 100644
-index 0000000..2953739
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_locl.h
-@@ -0,0 +1,97 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifndef HEADER_UI_LOCL_H
-+# define HEADER_UI_LOCL_H
-+
-+# include 
-+# include 
-+
-+# ifdef _
-+#  undef _
-+# endif
-+
-+struct ui_method_st {
-+    char *name;
-+    /*
-+     * All the functions return 1 or non-NULL for success and 0 or NULL for
-+     * failure
-+     */
-+    /*
-+     * Open whatever channel for this, be it the console, an X window or
-+     * whatever. This function should use the ex_data structure to save
-+     * intermediate data.
-+     */
-+    int (*ui_open_session) (UI *ui);
-+    int (*ui_write_string) (UI *ui, UI_STRING *uis);
-+    /*
-+     * Flush the output.  If a GUI dialog box is used, this function can be
-+     * used to actually display it.
-+     */
-+    int (*ui_flush) (UI *ui);
-+    int (*ui_read_string) (UI *ui, UI_STRING *uis);
-+    int (*ui_close_session) (UI *ui);
-+    /*
-+     * Construct a prompt in a user-defined manner.  object_desc is a textual
-+     * short description of the object, for example "pass phrase", and
-+     * object_name is the name of the object (might be a card name or a file
-+     * name. The returned string shall always be allocated on the heap with
-+     * OPENSSL_malloc(), and need to be free'd with OPENSSL_free().
-+     */
-+    char *(*ui_construct_prompt) (UI *ui, const char *object_desc,
-+                                  const char *object_name);
-+};
-+
-+struct ui_string_st {
-+    enum UI_string_types type;  /* Input */
-+    const char *out_string;     /* Input */
-+    int input_flags;            /* Flags from the user */
-+    /*
-+     * The following parameters are completely irrelevant for UIT_INFO, and
-+     * can therefore be set to 0 or NULL
-+     */
-+    char *result_buf;           /* Input and Output: If not NULL,
-+                                 * user-defined with size in result_maxsize.
-+                                 * Otherwise, it may be allocated by the UI
-+                                 * routine, meaning result_minsize is going
-+                                 * to be overwritten. */
-+    union {
-+        struct {
-+            int result_minsize; /* Input: minimum required size of the
-+                                 * result. */
-+            int result_maxsize; /* Input: maximum permitted size of the
-+                                 * result */
-+            const char *test_buf; /* Input: test string to verify against */
-+        } string_data;
-+        struct {
-+            const char *action_desc; /* Input */
-+            const char *ok_chars; /* Input */
-+            const char *cancel_chars; /* Input */
-+        } boolean_data;
-+    } _;
-+
-+# define OUT_STRING_FREEABLE 0x01
-+    int flags;                  /* flags for internal use */
-+};
-+
-+struct ui_st {
-+    const UI_METHOD *meth;
-+    STACK_OF(UI_STRING) *strings; /* We might want to prompt for more than
-+                                   * one thing at a time, and with different
-+                                   * echoing status.  */
-+    void *user_data;
-+    CRYPTO_EX_DATA ex_data;
-+# define UI_FLAG_REDOABLE        0x0001
-+# define UI_FLAG_PRINT_ERRORS    0x0100
-+    int flags;
-+
-+    CRYPTO_RWLOCK *lock;
-+};
-+
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_openssl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_openssl.c
-new file mode 100644
-index 0000000..ed0bfa0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_openssl.c
-@@ -0,0 +1,700 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+/*
-+ * need for #define _POSIX_C_SOURCE arises whenever you pass -ansi to gcc
-+ * [maybe others?], because it masks interfaces not discussed in standard,
-+ * sigaction and fileno included. -pedantic would be more appropriate for the
-+ * intended purposes, but we can't prevent users from adding -ansi.
-+ */
-+#if defined(OPENSSL_SYS_VXWORKS)
-+# include 
-+#endif
-+
-+#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
-+# ifndef _POSIX_C_SOURCE
-+#  define _POSIX_C_SOURCE 2
-+# endif
-+#endif
-+#include 
-+#include 
-+#include 
-+#include 
-+
-+#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS)
-+# ifdef OPENSSL_UNISTD
-+#  include OPENSSL_UNISTD
-+# else
-+#  include 
-+# endif
-+/*
-+ * If unistd.h defines _POSIX_VERSION, we conclude that we are on a POSIX
-+ * system and have sigaction and termios.
-+ */
-+# if defined(_POSIX_VERSION)
-+
-+#  define SIGACTION
-+#  if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
-+#   define TERMIOS
-+#  endif
-+
-+# endif
-+#endif
-+
-+/* 06-Apr-92 Luke Brennan    Support for VMS */
-+#include "ui_locl.h"
-+#include "internal/cryptlib.h"
-+
-+#ifdef OPENSSL_SYS_VMS          /* prototypes for sys$whatever */
-+# include 
-+# ifdef __DECC
-+#  pragma message disable DOLLARID
-+# endif
-+#endif
-+
-+#ifdef WIN_CONSOLE_BUG
-+# include 
-+# ifndef OPENSSL_SYS_WINCE
-+#  include 
-+# endif
-+#endif
-+
-+/*
-+ * There are 6 types of terminal interface supported, TERMIO, TERMIOS, VMS,
-+ * MSDOS, WIN32 Console and SGTTY.
-+ *
-+ * If someone defines one of the macros TERMIO, TERMIOS or SGTTY, it will
-+ * remain respected.  Otherwise, we default to TERMIOS except for a few
-+ * systems that require something different.
-+ *
-+ * Note: we do not use SGTTY unless it's defined by the configuration.  We
-+ * may eventually opt to remove it's use entirely.
-+ */
-+
-+#if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY)
-+
-+# if defined(_LIBC)
-+#  undef  TERMIOS
-+#  define TERMIO
-+#  undef  SGTTY
-+/*
-+ * We know that VMS, MSDOS, VXWORKS, use entirely other mechanisms.
-+ */
-+# elif !defined(OPENSSL_SYS_VMS) \
-+	&& !defined(OPENSSL_SYS_MSDOS) \
-+	&& !defined(OPENSSL_SYS_VXWORKS)
-+#  define TERMIOS
-+#  undef  TERMIO
-+#  undef  SGTTY
-+# endif
-+
-+#endif
-+
-+#ifdef TERMIOS
-+# include 
-+# define TTY_STRUCT             struct termios
-+# define TTY_FLAGS              c_lflag
-+# define TTY_get(tty,data)      tcgetattr(tty,data)
-+# define TTY_set(tty,data)      tcsetattr(tty,TCSANOW,data)
-+#endif
-+
-+#ifdef TERMIO
-+# include 
-+# define TTY_STRUCT             struct termio
-+# define TTY_FLAGS              c_lflag
-+# define TTY_get(tty,data)      ioctl(tty,TCGETA,data)
-+# define TTY_set(tty,data)      ioctl(tty,TCSETA,data)
-+#endif
-+
-+#ifdef SGTTY
-+# include 
-+# define TTY_STRUCT             struct sgttyb
-+# define TTY_FLAGS              sg_flags
-+# define TTY_get(tty,data)      ioctl(tty,TIOCGETP,data)
-+# define TTY_set(tty,data)      ioctl(tty,TIOCSETP,data)
-+#endif
-+
-+#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS)
-+# include 
-+#endif
-+
-+#ifdef OPENSSL_SYS_MSDOS
-+# include 
-+#endif
-+
-+#ifdef OPENSSL_SYS_VMS
-+# include 
-+# include 
-+# include 
-+# include 
-+struct IOSB {
-+    short iosb$w_value;
-+    short iosb$w_count;
-+    long iosb$l_info;
-+};
-+#endif
-+
-+#ifndef NX509_SIG
-+# define NX509_SIG 32
-+#endif
-+
-+/* Define globals.  They are protected by a lock */
-+#ifdef SIGACTION
-+static struct sigaction savsig[NX509_SIG];
-+#else
-+static void (*savsig[NX509_SIG]) (int);
-+#endif
-+
-+#ifdef OPENSSL_SYS_VMS
-+static struct IOSB iosb;
-+static $DESCRIPTOR(terminal, "TT");
-+static long tty_orig[3], tty_new[3]; /* XXX Is there any guarantee that this
-+                                      * will always suffice for the actual
-+                                      * structures? */
-+static long status;
-+static unsigned short channel = 0;
-+#elif defined(_WIN32) && !defined(_WIN32_WCE)
-+static DWORD tty_orig, tty_new;
-+#else
-+# if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__)
-+static TTY_STRUCT tty_orig, tty_new;
-+# endif
-+#endif
-+static FILE *tty_in, *tty_out;
-+static int is_a_tty;
-+
-+/* Declare static functions */
-+#if !defined(OPENSSL_SYS_WINCE)
-+static int read_till_nl(FILE *);
-+static void recsig(int);
-+static void pushsig(void);
-+static void popsig(void);
-+#endif
-+#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
-+static int noecho_fgets(char *buf, int size, FILE *tty);
-+#endif
-+static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl);
-+
-+static int read_string(UI *ui, UI_STRING *uis);
-+static int write_string(UI *ui, UI_STRING *uis);
-+
-+static int open_console(UI *ui);
-+static int echo_console(UI *ui);
-+static int noecho_console(UI *ui);
-+static int close_console(UI *ui);
-+
-+static UI_METHOD ui_openssl = {
-+    "OpenSSL default user interface",
-+    open_console,
-+    write_string,
-+    NULL,                       /* No flusher is needed for command lines */
-+    read_string,
-+    close_console,
-+    NULL
-+};
-+
-+/* The method with all the built-in thingies */
-+UI_METHOD *UI_OpenSSL(void)
-+{
-+    return &ui_openssl;
-+}
-+
-+/*
-+ * The following function makes sure that info and error strings are printed
-+ * before any prompt.
-+ */
-+static int write_string(UI *ui, UI_STRING *uis)
-+{
-+    switch (UI_get_string_type(uis)) {
-+    case UIT_ERROR:
-+    case UIT_INFO:
-+        fputs(UI_get0_output_string(uis), tty_out);
-+        fflush(tty_out);
-+        break;
-+    default:
-+        break;
-+    }
-+    return 1;
-+}
-+
-+static int read_string(UI *ui, UI_STRING *uis)
-+{
-+    int ok = 0;
-+
-+    switch (UI_get_string_type(uis)) {
-+    case UIT_BOOLEAN:
-+        fputs(UI_get0_output_string(uis), tty_out);
-+        fputs(UI_get0_action_string(uis), tty_out);
-+        fflush(tty_out);
-+        return read_string_inner(ui, uis,
-+                                 UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO,
-+                                 0);
-+    case UIT_PROMPT:
-+        fputs(UI_get0_output_string(uis), tty_out);
-+        fflush(tty_out);
-+        return read_string_inner(ui, uis,
-+                                 UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO,
-+                                 1);
-+    case UIT_VERIFY:
-+        fprintf(tty_out, "Verifying - %s", UI_get0_output_string(uis));
-+        fflush(tty_out);
-+        if ((ok = read_string_inner(ui, uis,
-+                                    UI_get_input_flags(uis) &
-+                                    UI_INPUT_FLAG_ECHO, 1)) <= 0)
-+            return ok;
-+        if (strcmp(UI_get0_result_string(uis), UI_get0_test_string(uis)) != 0) {
-+            fprintf(tty_out, "Verify failure\n");
-+            fflush(tty_out);
-+            return 0;
-+        }
-+        break;
-+    default:
-+        break;
-+    }
-+    return 1;
-+}
-+
-+#if !defined(OPENSSL_SYS_WINCE)
-+/* Internal functions to read a string without echoing */
-+static int read_till_nl(FILE *in)
-+{
-+# define SIZE 4
-+    char buf[SIZE + 1];
-+
-+    do {
-+        if (!fgets(buf, SIZE, in))
-+            return 0;
-+    } while (strchr(buf, '\n') == NULL);
-+    return 1;
-+}
-+
-+static volatile sig_atomic_t intr_signal;
-+#endif
-+
-+static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
-+{
-+    static int ps;
-+    int ok;
-+    char result[BUFSIZ];
-+    int maxsize = BUFSIZ - 1;
-+#if !defined(OPENSSL_SYS_WINCE)
-+    char *p = NULL;
-+    int echo_eol = !echo;
-+
-+    intr_signal = 0;
-+    ok = 0;
-+    ps = 0;
-+
-+    pushsig();
-+    ps = 1;
-+
-+    if (!echo && !noecho_console(ui))
-+        goto error;
-+    ps = 2;
-+
-+    result[0] = '\0';
-+# if defined(_WIN32)
-+    if (is_a_tty) {
-+        DWORD numread;
-+#  if defined(CP_UTF8)
-+        if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) != 0) {
-+            WCHAR wresult[BUFSIZ];
-+
-+            if (ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE),
-+                         wresult, maxsize, &numread, NULL)) {
-+                if (numread >= 2 &&
-+                    wresult[numread-2] == L'\r' &&
-+                    wresult[numread-1] == L'\n') {
-+                    wresult[numread-2] = L'\n';
-+                    numread--;
-+                }
-+                wresult[numread] = '\0';
-+                if (WideCharToMultiByte(CP_UTF8, 0, wresult, -1,
-+                                        result, sizeof(result), NULL, 0) > 0)
-+                    p = result;
-+
-+                OPENSSL_cleanse(wresult, sizeof(wresult));
-+            }
-+        } else
-+#  endif
-+        if (ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE),
-+                         result, maxsize, &numread, NULL)) {
-+            if (numread >= 2 &&
-+                result[numread-2] == '\r' && result[numread-1] == '\n') {
-+                result[numread-2] = '\n';
-+                numread--;
-+            }
-+            result[numread] = '\0';
-+            p = result;
-+        }
-+    } else
-+# elif defined(OPENSSL_SYS_MSDOS)
-+    if (!echo) {
-+        noecho_fgets(result, maxsize, tty_in);
-+        p = result;             /* FIXME: noecho_fgets doesn't return errors */
-+    } else
-+# endif
-+    p = fgets(result, maxsize, tty_in);
-+    if (p == NULL)
-+        goto error;
-+    if (feof(tty_in))
-+        goto error;
-+    if (ferror(tty_in))
-+        goto error;
-+    if ((p = (char *)strchr(result, '\n')) != NULL) {
-+        if (strip_nl)
-+            *p = '\0';
-+    } else if (!read_till_nl(tty_in))
-+        goto error;
-+    if (UI_set_result(ui, uis, result) >= 0)
-+        ok = 1;
-+
-+ error:
-+    if (intr_signal == SIGINT)
-+        ok = -1;
-+    if (echo_eol)
-+        fprintf(tty_out, "\n");
-+    if (ps >= 2 && !echo && !echo_console(ui))
-+        ok = 0;
-+
-+    if (ps >= 1)
-+        popsig();
-+#else
-+    ok = 1;
-+#endif
-+
-+    OPENSSL_cleanse(result, BUFSIZ);
-+    return ok;
-+}
-+
-+/* Internal functions to open, handle and close a channel to the console.  */
-+static int open_console(UI *ui)
-+{
-+    CRYPTO_THREAD_write_lock(ui->lock);
-+    is_a_tty = 1;
-+
-+#if defined(OPENSSL_SYS_VXWORKS)
-+    tty_in = stdin;
-+    tty_out = stderr;
-+#elif defined(_WIN32) && !defined(_WIN32_WCE)
-+    if ((tty_out = fopen("conout$", "w")) == NULL)
-+        tty_out = stderr;
-+
-+    if (GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &tty_orig)) {
-+        tty_in = stdin;
-+    } else {
-+        is_a_tty = 0;
-+        if ((tty_in = fopen("conin$", "r")) == NULL)
-+            tty_in = stdin;
-+    }
-+#else
-+# ifdef OPENSSL_SYS_MSDOS
-+#  define DEV_TTY "con"
-+# else
-+#  define DEV_TTY "/dev/tty"
-+# endif
-+    if ((tty_in = fopen(DEV_TTY, "r")) == NULL)
-+        tty_in = stdin;
-+    if ((tty_out = fopen(DEV_TTY, "w")) == NULL)
-+        tty_out = stderr;
-+#endif
-+
-+#if defined(TTY_get) && !defined(OPENSSL_SYS_VMS)
-+    if (TTY_get(fileno(tty_in), &tty_orig) == -1) {
-+# ifdef ENOTTY
-+        if (errno == ENOTTY)
-+            is_a_tty = 0;
-+        else
-+# endif
-+# ifdef EINVAL
-+            /*
-+             * Ariel Glenn ariel@columbia.edu reports that solaris can return
-+             * EINVAL instead.  This should be ok
-+             */
-+        if (errno == EINVAL)
-+            is_a_tty = 0;
-+        else
-+# endif
-+# ifdef ENODEV
-+            /*
-+             * MacOS X returns ENODEV (Operation not supported by device),
-+             * which seems appropriate.
-+             */
-+        if (errno == ENODEV)
-+            is_a_tty = 0;
-+        else
-+# endif
-+            {
-+                char tmp_num[10];
-+                BIO_snprintf(tmp_num, sizeof(tmp_num) - 1, "%d", errno);
-+                UIerr(UI_F_OPEN_CONSOLE, UI_R_UNKNOWN_TTYGET_ERRNO_VALUE);
-+                ERR_add_error_data(2, "errno=", tmp_num);
-+
-+                return 0;
-+            }
-+    }
-+#endif
-+#ifdef OPENSSL_SYS_VMS
-+    status = sys$assign(&terminal, &channel, 0, 0);
-+
-+    /* if there isn't a TT device, something is very wrong */
-+    if (status != SS$_NORMAL) {
-+        char tmp_num[12];
-+
-+        BIO_snprintf(tmp_num, sizeof(tmp_num) - 1, "%%X%08X", status);
-+        UIerr(UI_F_OPEN_CONSOLE, UI_R_SYSASSIGN_ERROR);
-+        ERR_add_error_data(2, "status=", tmp_num);
-+        return 0;
-+    }
-+
-+    status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12,
-+                      0, 0, 0, 0);
-+
-+    /* If IO$_SENSEMODE doesn't work, this is not a terminal device */
-+    if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
-+        is_a_tty = 0;
-+#endif
-+    return 1;
-+}
-+
-+static int noecho_console(UI *ui)
-+{
-+#ifdef TTY_FLAGS
-+    memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig));
-+    tty_new.TTY_FLAGS &= ~ECHO;
-+#endif
-+
-+#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
-+    if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1))
-+        return 0;
-+#endif
-+#ifdef OPENSSL_SYS_VMS
-+    if (is_a_tty) {
-+        tty_new[0] = tty_orig[0];
-+        tty_new[1] = tty_orig[1] | TT$M_NOECHO;
-+        tty_new[2] = tty_orig[2];
-+        status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12,
-+                          0, 0, 0, 0);
-+        if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) {
-+            char tmp_num[2][12];
-+
-+            BIO_snprintf(tmp_num[0], sizeof(tmp_num[0]) - 1, "%%X%08X",
-+                         status);
-+            BIO_snprintf(tmp_num[1], sizeof(tmp_num[1]) - 1, "%%X%08X",
-+                         iosb.iosb$w_value);
-+            UIerr(UI_F_NOECHO_CONSOLE, UI_R_SYSQIOW_ERROR);
-+            ERR_add_error_data(5, "status=", tmp_num[0],
-+                               ",", "iosb.iosb$w_value=", tmp_num[1]);
-+            return 0;
-+        }
-+    }
-+#endif
-+#if defined(_WIN32) && !defined(_WIN32_WCE)
-+    if (is_a_tty) {
-+        tty_new = tty_orig;
-+        tty_new &= ~ENABLE_ECHO_INPUT;
-+        SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), tty_new);
-+    }
-+#endif
-+    return 1;
-+}
-+
-+static int echo_console(UI *ui)
-+{
-+#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
-+    memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig));
-+    tty_new.TTY_FLAGS |= ECHO;
-+#endif
-+
-+#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS)
-+    if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1))
-+        return 0;
-+#endif
-+#ifdef OPENSSL_SYS_VMS
-+    if (is_a_tty) {
-+        tty_new[0] = tty_orig[0];
-+        tty_new[1] = tty_orig[1] & ~TT$M_NOECHO;
-+        tty_new[2] = tty_orig[2];
-+        status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12,
-+                          0, 0, 0, 0);
-+        if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) {
-+            char tmp_num[2][12];
-+
-+            BIO_snprintf(tmp_num[0], sizeof(tmp_num[0]) - 1, "%%X%08X",
-+                         status);
-+            BIO_snprintf(tmp_num[1], sizeof(tmp_num[1]) - 1, "%%X%08X",
-+                         iosb.iosb$w_value);
-+            UIerr(UI_F_ECHO_CONSOLE, UI_R_SYSQIOW_ERROR);
-+            ERR_add_error_data(5, "status=", tmp_num[0],
-+                               ",", "iosb.iosb$w_value=", tmp_num[1]);
-+            return 0;
-+        }
-+    }
-+#endif
-+#if defined(_WIN32) && !defined(_WIN32_WCE)
-+    if (is_a_tty) {
-+        tty_new = tty_orig;
-+        tty_new |= ENABLE_ECHO_INPUT;
-+        SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), tty_new);
-+    }
-+#endif
-+    return 1;
-+}
-+
-+static int close_console(UI *ui)
-+{
-+    if (tty_in != stdin)
-+        fclose(tty_in);
-+    if (tty_out != stderr)
-+        fclose(tty_out);
-+#ifdef OPENSSL_SYS_VMS
-+    status = sys$dassgn(channel);
-+    if (status != SS$_NORMAL) {
-+        char tmp_num[12];
-+
-+        BIO_snprintf(tmp_num, sizeof(tmp_num) - 1, "%%X%08X", status);
-+        UIerr(UI_F_CLOSE_CONSOLE, UI_R_SYSDASSGN_ERROR);
-+        ERR_add_error_data(2, "status=", tmp_num);
-+        return 0;
-+    }
-+#endif
-+    CRYPTO_THREAD_unlock(ui->lock);
-+
-+    return 1;
-+}
-+
-+#if !defined(OPENSSL_SYS_WINCE)
-+/* Internal functions to handle signals and act on them */
-+static void pushsig(void)
-+{
-+# ifndef OPENSSL_SYS_WIN32
-+    int i;
-+# endif
-+# ifdef SIGACTION
-+    struct sigaction sa;
-+
-+    memset(&sa, 0, sizeof(sa));
-+    sa.sa_handler = recsig;
-+# endif
-+
-+# ifdef OPENSSL_SYS_WIN32
-+    savsig[SIGABRT] = signal(SIGABRT, recsig);
-+    savsig[SIGFPE] = signal(SIGFPE, recsig);
-+    savsig[SIGILL] = signal(SIGILL, recsig);
-+    savsig[SIGINT] = signal(SIGINT, recsig);
-+    savsig[SIGSEGV] = signal(SIGSEGV, recsig);
-+    savsig[SIGTERM] = signal(SIGTERM, recsig);
-+# else
-+    for (i = 1; i < NX509_SIG; i++) {
-+#  ifdef SIGUSR1
-+        if (i == SIGUSR1)
-+            continue;
-+#  endif
-+#  ifdef SIGUSR2
-+        if (i == SIGUSR2)
-+            continue;
-+#  endif
-+#  ifdef SIGKILL
-+        if (i == SIGKILL)       /* We can't make any action on that. */
-+            continue;
-+#  endif
-+#  ifdef SIGACTION
-+        sigaction(i, &sa, &savsig[i]);
-+#  else
-+        savsig[i] = signal(i, recsig);
-+#  endif
-+    }
-+# endif
-+
-+# ifdef SIGWINCH
-+    signal(SIGWINCH, SIG_DFL);
-+# endif
-+}
-+
-+static void popsig(void)
-+{
-+# ifdef OPENSSL_SYS_WIN32
-+    signal(SIGABRT, savsig[SIGABRT]);
-+    signal(SIGFPE, savsig[SIGFPE]);
-+    signal(SIGILL, savsig[SIGILL]);
-+    signal(SIGINT, savsig[SIGINT]);
-+    signal(SIGSEGV, savsig[SIGSEGV]);
-+    signal(SIGTERM, savsig[SIGTERM]);
-+# else
-+    int i;
-+    for (i = 1; i < NX509_SIG; i++) {
-+#  ifdef SIGUSR1
-+        if (i == SIGUSR1)
-+            continue;
-+#  endif
-+#  ifdef SIGUSR2
-+        if (i == SIGUSR2)
-+            continue;
-+#  endif
-+#  ifdef SIGACTION
-+        sigaction(i, &savsig[i], NULL);
-+#  else
-+        signal(i, savsig[i]);
-+#  endif
-+    }
-+# endif
-+}
-+
-+static void recsig(int i)
-+{
-+    intr_signal = i;
-+}
-+#endif
-+
-+/* Internal functions specific for Windows */
-+#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
-+static int noecho_fgets(char *buf, int size, FILE *tty)
-+{
-+    int i;
-+    char *p;
-+
-+    p = buf;
-+    for (;;) {
-+        if (size == 0) {
-+            *p = '\0';
-+            break;
-+        }
-+        size--;
-+# if defined(_WIN32)
-+        i = _getch();
-+# else
-+        i = getch();
-+# endif
-+        if (i == '\r')
-+            i = '\n';
-+        *(p++) = i;
-+        if (i == '\n') {
-+            *p = '\0';
-+            break;
-+        }
-+    }
-+# ifdef WIN_CONSOLE_BUG
-+    /*
-+     * Win95 has several evil console bugs: one of these is that the last
-+     * character read using getch() is passed to the next read: this is
-+     * usually a CR so this can be trouble. No STDIO fix seems to work but
-+     * flushing the console appears to do the trick.
-+     */
-+    {
-+        HANDLE inh;
-+        inh = GetStdHandle(STD_INPUT_HANDLE);
-+        FlushConsoleInputBuffer(inh);
-+    }
-+# endif
-+    return (strlen(buf));
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_util.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_util.c
-new file mode 100644
-index 0000000..3b51db9
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/ui/ui_util.c
-@@ -0,0 +1,51 @@
-+/*
-+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include "ui_locl.h"
-+
-+#ifndef BUFSIZ
-+#define BUFSIZ 256
-+#endif
-+
-+int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt,
-+                           int verify)
-+{
-+    char buff[BUFSIZ];
-+    int ret;
-+
-+    ret =
-+        UI_UTIL_read_pw(buf, buff, (length > BUFSIZ) ? BUFSIZ : length,
-+                        prompt, verify);
-+    OPENSSL_cleanse(buff, BUFSIZ);
-+    return (ret);
-+}
-+
-+int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
-+                    int verify)
-+{
-+    int ok = 0;
-+    UI *ui;
-+
-+    if (size < 1)
-+        return -1;
-+
-+    ui = UI_new();
-+    if (ui != NULL) {
-+        ok = UI_add_input_string(ui, prompt, 0, buf, 0, size - 1);
-+        if (ok >= 0 && verify)
-+            ok = UI_add_verify_string(ui, prompt, 0, buff, 0, size - 1, buf);
-+        if (ok >= 0)
-+            ok = UI_process(ui);
-+        UI_free(ui);
-+    }
-+    if (ok > 0)
-+        ok = 0;
-+    return (ok);
-+}
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/uid.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/uid.c
-new file mode 100644
-index 0000000..12df8a4
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/uid.c
-@@ -0,0 +1,42 @@
-+/*
-+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include 
-+#include 
-+
-+#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2)
-+
-+# include OPENSSL_UNISTD
-+
-+int OPENSSL_issetugid(void)
-+{
-+    return issetugid();
-+}
-+
-+#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS)
-+
-+int OPENSSL_issetugid(void)
-+{
-+    return 0;
-+}
-+
-+#else
-+
-+# include OPENSSL_UNISTD
-+# include 
-+
-+int OPENSSL_issetugid(void)
-+{
-+    if (getuid() != geteuid())
-+        return 1;
-+    if (getgid() != getegid())
-+        return 1;
-+    return 0;
-+}
-+#endif
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/vms_rms.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/vms_rms.h
-new file mode 100644
-index 0000000..3b994a0
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/vms_rms.h
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#ifdef NAML$C_MAXRSS
-+
-+# define CC_RMS_NAMX cc$rms_naml
-+# define FAB_NAMX fab$l_naml
-+# define FAB_OR_NAML( fab, naml) naml
-+# define FAB_OR_NAML_DNA naml$l_long_defname
-+# define FAB_OR_NAML_DNS naml$l_long_defname_size
-+# define FAB_OR_NAML_FNA naml$l_long_filename
-+# define FAB_OR_NAML_FNS naml$l_long_filename_size
-+# define NAMX_ESA naml$l_long_expand
-+# define NAMX_ESL naml$l_long_expand_size
-+# define NAMX_ESS naml$l_long_expand_alloc
-+# define NAMX_NOP naml$b_nop
-+# define SET_NAMX_NO_SHORT_UPCASE( nam) nam.naml$v_no_short_upcase = 1
-+
-+# if __INITIAL_POINTER_SIZE == 64
-+#  define NAMX_DNA_FNA_SET(fab) fab.fab$l_dna = (__char_ptr32) -1; \
-+   fab.fab$l_fna = (__char_ptr32) -1;
-+# else                          /* __INITIAL_POINTER_SIZE == 64 */
-+#  define NAMX_DNA_FNA_SET(fab) fab.fab$l_dna = (char *) -1; \
-+   fab.fab$l_fna = (char *) -1;
-+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
-+
-+# define NAMX_MAXRSS NAML$C_MAXRSS
-+# define NAMX_STRUCT NAML
-+
-+#else                           /* def NAML$C_MAXRSS */
-+
-+# define CC_RMS_NAMX cc$rms_nam
-+# define FAB_NAMX fab$l_nam
-+# define FAB_OR_NAML( fab, naml) fab
-+# define FAB_OR_NAML_DNA fab$l_dna
-+# define FAB_OR_NAML_DNS fab$b_dns
-+# define FAB_OR_NAML_FNA fab$l_fna
-+# define FAB_OR_NAML_FNS fab$b_fns
-+# define NAMX_ESA nam$l_esa
-+# define NAMX_ESL nam$b_esl
-+# define NAMX_ESS nam$b_ess
-+# define NAMX_NOP nam$b_nop
-+# define NAMX_DNA_FNA_SET(fab)
-+# define NAMX_MAXRSS NAM$C_MAXRSS
-+# define NAMX_STRUCT NAM
-+# ifdef NAM$M_NO_SHORT_UPCASE
-+#  define SET_NAMX_NO_SHORT_UPCASE( nam) naml.naml$v_no_short_upcase = 1
-+# else                          /* def NAM$M_NO_SHORT_UPCASE */
-+#  define SET_NAMX_NO_SHORT_UPCASE( nam)
-+# endif                         /* def NAM$M_NO_SHORT_UPCASE [else] */
-+
-+#endif                          /* def NAML$C_MAXRSS [else] */
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/asm/wp-mmx.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/asm/wp-mmx.pl
-new file mode 100644
-index 0000000..f63945c
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/asm/wp-mmx.pl
-@@ -0,0 +1,507 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. Rights for redistribution and usage in source and binary
-+# forms are granted according to the OpenSSL license.
-+# ====================================================================
-+#
-+# whirlpool_block_mmx implementation.
-+#
-+*SCALE=\(2); # 2 or 8, that is the question:-) Value of 8 results
-+# in 16KB large table, which is tough on L1 cache, but eliminates
-+# unaligned references to it. Value of 2 results in 4KB table, but
-+# 7/8 of references to it are unaligned. AMD cores seem to be
-+# allergic to the latter, while Intel ones - to former [see the
-+# table]. I stick to value of 2 for two reasons: 1. smaller table
-+# minimizes cache trashing and thus mitigates the hazard of side-
-+# channel leakage similar to AES cache-timing one; 2. performance
-+# gap among different µ-archs is smaller.
-+#
-+# Performance table lists rounded amounts of CPU cycles spent by
-+# whirlpool_block_mmx routine on single 64 byte input block, i.e.
-+# smaller is better and asymptotic throughput can be estimated by
-+# multiplying 64 by CPU clock frequency and dividing by relevant
-+# value from the given table:
-+#
-+#		$SCALE=2/8	icc8	gcc3	
-+# Intel P4	3200/4600	4600(*)	6400
-+# Intel PIII	2900/3000	4900	5400
-+# AMD K[78]	2500/1800	9900	8200(**)
-+#
-+# (*)	I've sketched even non-MMX assembler, but for the record
-+#	I've failed to beat the Intel compiler on P4, without using
-+#	MMX that is...
-+# (**)	... on AMD on the other hand non-MMX assembler was observed
-+#	to perform significantly better, but I figured this MMX
-+#	implementation is even faster anyway, so why bother? As for
-+#	pre-MMX AMD core[s], the improvement coefficient is more
-+#	than likely to vary anyway and I don't know how. But the
-+#	least I know is that gcc-generated code compiled with
-+#	-DL_ENDIAN and -DOPENSSL_SMALL_FOOTPRINT [see C module for
-+#	details] and optimized for Pentium was observed to perform
-+#	*better* on Pentium 100 than unrolled non-MMX assembler
-+#	loop... So we just say that I don't know if maintaining
-+#	non-MMX implementation would actually pay off, but till
-+#	opposite is proved "unlikely" is assumed.
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-+push(@INC,"${dir}","${dir}../../perlasm");
-+require "x86asm.pl";
-+
-+$output=pop;
-+open STDOUT,">$output";
-+
-+&asm_init($ARGV[0],"wp-mmx.pl");
-+
-+sub L()  { &data_byte(@_); }
-+sub LL()
-+{	if	($SCALE==2)	{ &data_byte(@_); &data_byte(@_); }
-+	elsif	($SCALE==8)	{ for ($i=0;$i<8;$i++) {
-+					&data_byte(@_);
-+					unshift(@_,pop(@_));
-+				  }
-+				}
-+	else			{ die "unvalid SCALE value"; }
-+}
-+
-+sub scale()
-+{	if	($SCALE==2)	{ &lea(@_[0],&DWP(0,@_[1],@_[1])); }
-+	elsif	($SCALE==8)	{ &lea(@_[0],&DWP(0,"",@_[1],8));  }
-+	else			{ die "unvalid SCALE value";       }
-+}
-+
-+sub row()
-+{	if	($SCALE==2)	{ ((8-shift)&7); }
-+	elsif	($SCALE==8)	{ (8*shift);     }
-+	else			{ die "unvalid SCALE value"; }
-+}
-+
-+$tbl="ebp";
-+@mm=("mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7");
-+
-+&function_begin_B("whirlpool_block_mmx");
-+	&push	("ebp");
-+	&push	("ebx");
-+	&push	("esi");
-+	&push	("edi");
-+
-+	&mov	("esi",&wparam(0));		# hash value
-+	&mov	("edi",&wparam(1));		# input data stream
-+	&mov	("ebp",&wparam(2));		# number of chunks in input
-+
-+	&mov	("eax","esp");			# copy stack pointer
-+	&sub	("esp",128+20);			# allocate frame
-+	&and	("esp",-64);			# align for cache-line
-+
-+	&lea	("ebx",&DWP(128,"esp"));
-+	&mov	(&DWP(0,"ebx"),"esi");		# save parameter block
-+	&mov	(&DWP(4,"ebx"),"edi");
-+	&mov	(&DWP(8,"ebx"),"ebp");
-+	&mov	(&DWP(16,"ebx"),"eax");		# saved stack pointer
-+
-+	&call	(&label("pic_point"));
-+&set_label("pic_point");
-+	&blindpop($tbl);
-+	&lea	($tbl,&DWP(&label("table")."-".&label("pic_point"),$tbl));
-+
-+	&xor	("ecx","ecx");
-+	&xor	("edx","edx");
-+
-+	for($i=0;$i<8;$i++) { &movq(@mm[$i],&QWP($i*8,"esi")); }    # L=H
-+&set_label("outerloop");
-+	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); }    # K=L
-+	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); }    # L^=inp
-+	for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L
-+
-+	&xor	("esi","esi");
-+	&mov	(&DWP(12,"ebx"),"esi");		# zero round counter
-+
-+&set_label("round",16);
-+	&movq	(@mm[0],&QWP(2048*$SCALE,$tbl,"esi",8));	# rc[r]
-+	&mov	("eax",&DWP(0,"esp"));
-+	&mov	("ebx",&DWP(4,"esp"));
-+	&movz	("ecx",&LB("eax"));
-+	&movz	("edx",&HB("eax"));
-+for($i=0;$i<8;$i++) {
-+    my $func = ($i==0)? \&movq : \&pxor;
-+	&shr	("eax",16);
-+	&scale	("esi","ecx");
-+	&movz	("ecx",&LB("eax"));
-+	&scale	("edi","edx");
-+	&movz	("edx",&HB("eax"));
-+	&pxor	(@mm[0],&QWP(&row(0),$tbl,"esi",8));
-+	&$func	(@mm[1],&QWP(&row(1),$tbl,"edi",8));
-+	&mov	("eax",&DWP(($i+1)*8,"esp"));
-+	&scale	("esi","ecx");
-+	&movz	("ecx",&LB("ebx"));
-+	&scale	("edi","edx");
-+	&movz	("edx",&HB("ebx"));
-+	&$func	(@mm[2],&QWP(&row(2),$tbl,"esi",8));
-+	&$func	(@mm[3],&QWP(&row(3),$tbl,"edi",8));
-+	&shr	("ebx",16);
-+	&scale	("esi","ecx");
-+	&movz	("ecx",&LB("ebx"));
-+	&scale	("edi","edx");
-+	&movz	("edx",&HB("ebx"));
-+	&$func	(@mm[4],&QWP(&row(4),$tbl,"esi",8));
-+	&$func	(@mm[5],&QWP(&row(5),$tbl,"edi",8));
-+	&mov	("ebx",&DWP(($i+1)*8+4,"esp"));
-+	&scale	("esi","ecx");
-+	&movz	("ecx",&LB("eax"));
-+	&scale	("edi","edx");
-+	&movz	("edx",&HB("eax"));
-+	&$func	(@mm[6],&QWP(&row(6),$tbl,"esi",8));
-+	&$func	(@mm[7],&QWP(&row(7),$tbl,"edi",8));
-+    push(@mm,shift(@mm));
-+}
-+
-+	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); }    # K=L
-+
-+for($i=0;$i<8;$i++) {
-+	&shr	("eax",16);
-+	&scale	("esi","ecx");
-+	&movz	("ecx",&LB("eax"));
-+	&scale	("edi","edx");
-+	&movz	("edx",&HB("eax"));
-+	&pxor	(@mm[0],&QWP(&row(0),$tbl,"esi",8));
-+	&pxor	(@mm[1],&QWP(&row(1),$tbl,"edi",8));
-+	&mov	("eax",&DWP(64+($i+1)*8,"esp"))		if ($i<7);
-+	&scale	("esi","ecx");
-+	&movz	("ecx",&LB("ebx"));
-+	&scale	("edi","edx");
-+	&movz	("edx",&HB("ebx"));
-+	&pxor	(@mm[2],&QWP(&row(2),$tbl,"esi",8));
-+	&pxor	(@mm[3],&QWP(&row(3),$tbl,"edi",8));
-+	&shr	("ebx",16);
-+	&scale	("esi","ecx");
-+	&movz	("ecx",&LB("ebx"));
-+	&scale	("edi","edx");
-+	&movz	("edx",&HB("ebx"));
-+	&pxor	(@mm[4],&QWP(&row(4),$tbl,"esi",8));
-+	&pxor	(@mm[5],&QWP(&row(5),$tbl,"edi",8));
-+	&mov	("ebx",&DWP(64+($i+1)*8+4,"esp"))	if ($i<7);
-+	&scale	("esi","ecx");
-+	&movz	("ecx",&LB("eax"));
-+	&scale	("edi","edx");
-+	&movz	("edx",&HB("eax"));
-+	&pxor	(@mm[6],&QWP(&row(6),$tbl,"esi",8));
-+	&pxor	(@mm[7],&QWP(&row(7),$tbl,"edi",8));
-+    push(@mm,shift(@mm));
-+}
-+	&lea	("ebx",&DWP(128,"esp"));
-+	&mov	("esi",&DWP(12,"ebx"));		# pull round counter
-+	&add	("esi",1);
-+	&cmp	("esi",10);
-+	&je	(&label("roundsdone"));
-+
-+	&mov	(&DWP(12,"ebx"),"esi");		# update round counter
-+	for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L
-+	&jmp	(&label("round"));
-+
-+&set_label("roundsdone",16);
-+	&mov	("esi",&DWP(0,"ebx"));		# reload argument block
-+	&mov	("edi",&DWP(4,"ebx"));
-+	&mov	("eax",&DWP(8,"ebx"));
-+
-+	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); }    # L^=inp
-+	for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"esi")); }    # L^=H
-+	for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esi"),@mm[$i]); }    # H=L
-+
-+	&lea	("edi",&DWP(64,"edi"));		# inp+=64
-+	&sub	("eax",1);			# num--
-+	&jz	(&label("alldone"));
-+	&mov	(&DWP(4,"ebx"),"edi");		# update argument block
-+	&mov	(&DWP(8,"ebx"),"eax");
-+	&jmp	(&label("outerloop"));
-+
-+&set_label("alldone");
-+	&emms	();
-+	&mov	("esp",&DWP(16,"ebx"));		# restore saved stack pointer
-+	&pop	("edi");
-+	&pop	("esi");
-+	&pop	("ebx");
-+	&pop	("ebp");
-+	&ret	();
-+
-+&align(64);
-+&set_label("table");
-+	&LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8);
-+	&LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26);
-+	&LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8);
-+	&LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb);
-+	&LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb);
-+	&LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11);
-+	&LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09);
-+	&LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d);
-+	&LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b);
-+	&LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff);
-+	&LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c);
-+	&LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e);
-+	&LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96);
-+	&LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30);
-+	&LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d);
-+	&LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8);
-+	&LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47);
-+	&LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35);
-+	&LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37);
-+	&LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a);
-+	&LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2);
-+	&LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c);
-+	&LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84);
-+	&LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80);
-+	&LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5);
-+	&LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3);
-+	&LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21);
-+	&LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c);
-+	&LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43);
-+	&LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29);
-+	&LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d);
-+	&LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5);
-+	&LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd);
-+	&LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8);
-+	&LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92);
-+	&LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e);
-+	&LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13);
-+	&LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23);
-+	&LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20);
-+	&LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44);
-+	&LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2);
-+	&LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf);
-+	&LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c);
-+	&LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a);
-+	&LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50);
-+	&LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9);
-+	&LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14);
-+	&LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9);
-+	&LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c);
-+	&LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f);
-+	&LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90);
-+	&LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07);
-+	&LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd);
-+	&LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3);
-+	&LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d);
-+	&LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78);
-+	&LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97);
-+	&LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02);
-+	&LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73);
-+	&LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7);
-+	&LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6);
-+	&LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2);
-+	&LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49);
-+	&LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56);
-+	&LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70);
-+	&LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd);
-+	&LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb);
-+	&LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71);
-+	&LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b);
-+	&LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf);
-+	&LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45);
-+	&LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a);
-+	&LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4);
-+	&LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58);
-+	&LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e);
-+	&LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f);
-+	&LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac);
-+	&LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0);
-+	&LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef);
-+	&LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6);
-+	&LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c);
-+	&LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12);
-+	&LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93);
-+	&LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde);
-+	&LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6);
-+	&LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1);
-+	&LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b);
-+	&LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f);
-+	&LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31);
-+	&LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8);
-+	&LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9);
-+	&LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc);
-+	&LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e);
-+	&LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b);
-+	&LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf);
-+	&LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59);
-+	&LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2);
-+	&LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77);
-+	&LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33);
-+	&LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4);
-+	&LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27);
-+	&LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb);
-+	&LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89);
-+	&LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32);
-+	&LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54);
-+	&LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d);
-+	&LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64);
-+	&LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d);
-+	&LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d);
-+	&LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f);
-+	&LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca);
-+	&LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7);
-+	&LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d);
-+	&LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce);
-+	&LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f);
-+	&LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f);
-+	&LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63);
-+	&LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a);
-+	&LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc);
-+	&LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82);
-+	&LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a);
-+	&LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48);
-+	&LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95);
-+	&LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf);
-+	&LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d);
-+	&LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0);
-+	&LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91);
-+	&LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8);
-+	&LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b);
-+	&LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
-+	&LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9);
-+	&LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e);
-+	&LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1);
-+	&LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6);
-+	&LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28);
-+	&LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3);
-+	&LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74);
-+	&LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe);
-+	&LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d);
-+	&LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea);
-+	&LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57);
-+	&LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38);
-+	&LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad);
-+	&LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4);
-+	&LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda);
-+	&LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7);
-+	&LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb);
-+	&LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9);
-+	&LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a);
-+	&LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03);
-+	&LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a);
-+	&LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e);
-+	&LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60);
-+	&LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc);
-+	&LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46);
-+	&LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f);
-+	&LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76);
-+	&LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa);
-+	&LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36);
-+	&LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae);
-+	&LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b);
-+	&LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85);
-+	&LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e);
-+	&LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7);
-+	&LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55);
-+	&LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a);
-+	&LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81);
-+	&LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52);
-+	&LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62);
-+	&LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3);
-+	&LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10);
-+	&LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab);
-+	&LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0);
-+	&LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5);
-+	&LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec);
-+	&LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16);
-+	&LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94);
-+	&LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f);
-+	&LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5);
-+	&LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98);
-+	&LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17);
-+	&LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4);
-+	&LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1);
-+	&LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e);
-+	&LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42);
-+	&LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34);
-+	&LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08);
-+	&LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee);
-+	&LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61);
-+	&LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1);
-+	&LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f);
-+	&LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24);
-+	&LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3);
-+	&LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25);
-+	&LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22);
-+	&LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65);
-+	&LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79);
-+	&LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69);
-+	&LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9);
-+	&LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19);
-+	&LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe);
-+	&LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a);
-+	&LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0);
-+	&LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99);
-+	&LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83);
-+	&LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04);
-+	&LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66);
-+	&LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0);
-+	&LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1);
-+	&LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd);
-+	&LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40);
-+	&LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c);
-+	&LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18);
-+	&LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b);
-+	&LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51);
-+	&LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05);
-+	&LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c);
-+	&LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39);
-+	&LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa);
-+	&LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b);
-+	&LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc);
-+	&LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e);
-+	&LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0);
-+	&LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88);
-+	&LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67);
-+	&LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a);
-+	&LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87);
-+	&LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1);
-+	&LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72);
-+	&LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53);
-+	&LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01);
-+	&LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b);
-+	&LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4);
-+	&LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3);
-+	&LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15);
-+	&LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c);
-+	&LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5);
-+	&LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5);
-+	&LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4);
-+	&LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba);
-+	&LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6);
-+	&LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7);
-+	&LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06);
-+	&LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41);
-+	&LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7);
-+	&LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f);
-+	&LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e);
-+	&LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6);
-+	&LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2);
-+	&LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68);
-+	&LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c);
-+	&LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed);
-+	&LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75);
-+	&LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86);
-+	&LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b);
-+	&LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2);
-+
-+	&L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f);	# rc[ROUNDS]
-+	&L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52);
-+	&L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35);
-+	&L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57);
-+	&L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda);
-+	&L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85);
-+	&L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67);
-+	&L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8);
-+	&L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e);
-+	&L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33);
-+
-+&function_end_B("whirlpool_block_mmx");
-+&asm_finish(); 
-+
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/asm/wp-x86_64.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/asm/wp-x86_64.pl
-new file mode 100644
-index 0000000..c0b21d1
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/asm/wp-x86_64.pl
-@@ -0,0 +1,600 @@
-+#! /usr/bin/env perl
-+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+#
-+# Licensed under the OpenSSL license (the "License").  You may not use
-+# this file except in compliance with the License.  You can obtain a copy
-+# in the file LICENSE in the source distribution or at
-+# https://www.openssl.org/source/license.html
-+
-+#
-+# ====================================================================
-+# Written by Andy Polyakov  for the OpenSSL
-+# project. Rights for redistribution and usage in source and binary
-+# forms are granted according to the OpenSSL license.
-+# ====================================================================
-+#
-+# whirlpool_block for x86_64.
-+#
-+# 2500 cycles per 64-byte input block on AMD64, which is *identical*
-+# to 32-bit MMX version executed on same CPU. So why did I bother?
-+# Well, it's faster than gcc 3.3.2 generated code by over 50%, and
-+# over 80% faster than PathScale 1.4, an "ambitious" commercial
-+# compiler. Furthermore it surpasses gcc 3.4.3 by 170% and Sun Studio
-+# 10 - by 360%[!]... What is it with x86_64 compilers? It's not the
-+# first example when they fail to generate more optimal code, when
-+# I believe they had *all* chances to...
-+#
-+# Note that register and stack frame layout are virtually identical
-+# to 32-bit MMX version, except that %r8-15 are used instead of
-+# %mm0-8. You can even notice that K[i] and S[i] are loaded to
-+# %eax:%ebx as pair of 32-bit values and not as single 64-bit one.
-+# This is done in order to avoid 64-bit shift penalties on Intel
-+# EM64T core. Speaking of which! I bet it's possible to improve
-+# Opteron performance by compressing the table to 2KB and replacing
-+# unaligned references with complementary rotations [which would
-+# incidentally replace lea instructions], but it would definitely
-+# just "kill" EM64T, because it has only 1 shifter/rotator [against
-+# 3 on Opteron] and which is *unacceptably* slow with 64-bit
-+# operand.
-+
-+$flavour = shift;
-+$output  = shift;
-+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-+
-+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-+
-+$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
-+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-+( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
-+die "can't locate x86_64-xlate.pl";
-+
-+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-+*STDOUT=*OUT;
-+
-+sub L() { $code.=".byte	".join(',',@_)."\n"; }
-+sub LL(){ $code.=".byte	".join(',',@_).",".join(',',@_)."\n"; }
-+
-+@mm=("%r8","%r9","%r10","%r11","%r12","%r13","%r14","%r15");
-+
-+$func="whirlpool_block";
-+$table=".Ltable";
-+
-+$code=<<___;
-+.text
-+
-+.globl	$func
-+.type	$func,\@function,3
-+.align	16
-+$func:
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+
-+	mov	%rsp,%r11
-+	sub	\$128+40,%rsp
-+	and	\$-64,%rsp
-+
-+	lea	128(%rsp),%r10
-+	mov	%rdi,0(%r10)		# save parameter block
-+	mov	%rsi,8(%r10)
-+	mov	%rdx,16(%r10)
-+	mov	%r11,32(%r10)		# saved stack pointer
-+.Lprologue:
-+
-+	mov	%r10,%rbx
-+	lea	$table(%rip),%rbp
-+
-+	xor	%rcx,%rcx
-+	xor	%rdx,%rdx
-+___
-+for($i=0;$i<8;$i++) { $code.="mov $i*8(%rdi),@mm[$i]\n"; }	# L=H
-+$code.=".Louterloop:\n";
-+for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; }	# K=L
-+for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; }	# L^=inp
-+for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; }	# S=L
-+$code.=<<___;
-+	xor	%rsi,%rsi
-+	mov	%rsi,24(%rbx)		# zero round counter
-+	jmp	.Lround
-+.align	16
-+.Lround:
-+	mov	4096(%rbp,%rsi,8),@mm[0]	# rc[r]
-+	mov	0(%rsp),%eax
-+	mov	4(%rsp),%ebx
-+	movz	%al,%ecx
-+	movz	%ah,%edx
-+___
-+for($i=0;$i<8;$i++) {
-+    my $func = ($i==0)? "mov" : "xor";
-+    $code.=<<___;
-+	shr	\$16,%eax
-+	lea	(%rcx,%rcx),%rsi
-+	movz	%al,%ecx
-+	lea	(%rdx,%rdx),%rdi
-+	movz	%ah,%edx
-+	xor	0(%rbp,%rsi,8),@mm[0]
-+	$func	7(%rbp,%rdi,8),@mm[1]
-+	mov	$i*8+8(%rsp),%eax		# ($i+1)*8
-+	lea	(%rcx,%rcx),%rsi
-+	movz	%bl,%ecx
-+	lea	(%rdx,%rdx),%rdi
-+	movz	%bh,%edx
-+	$func	6(%rbp,%rsi,8),@mm[2]
-+	$func	5(%rbp,%rdi,8),@mm[3]
-+	shr	\$16,%ebx
-+	lea	(%rcx,%rcx),%rsi
-+	movz	%bl,%ecx
-+	lea	(%rdx,%rdx),%rdi
-+	movz	%bh,%edx
-+	$func	4(%rbp,%rsi,8),@mm[4]
-+	$func	3(%rbp,%rdi,8),@mm[5]
-+	mov	$i*8+8+4(%rsp),%ebx		# ($i+1)*8+4
-+	lea	(%rcx,%rcx),%rsi
-+	movz	%al,%ecx
-+	lea	(%rdx,%rdx),%rdi
-+	movz	%ah,%edx
-+	$func	2(%rbp,%rsi,8),@mm[6]
-+	$func	1(%rbp,%rdi,8),@mm[7]
-+___
-+    push(@mm,shift(@mm));
-+}
-+for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; }	# K=L
-+for($i=0;$i<8;$i++) {
-+    $code.=<<___;
-+	shr	\$16,%eax
-+	lea	(%rcx,%rcx),%rsi
-+	movz	%al,%ecx
-+	lea	(%rdx,%rdx),%rdi
-+	movz	%ah,%edx
-+	xor	0(%rbp,%rsi,8),@mm[0]
-+	xor	7(%rbp,%rdi,8),@mm[1]
-+	`"mov	64+$i*8+8(%rsp),%eax"	if($i<7);`	# 64+($i+1)*8
-+	lea	(%rcx,%rcx),%rsi
-+	movz	%bl,%ecx
-+	lea	(%rdx,%rdx),%rdi
-+	movz	%bh,%edx
-+	xor	6(%rbp,%rsi,8),@mm[2]
-+	xor	5(%rbp,%rdi,8),@mm[3]
-+	shr	\$16,%ebx
-+	lea	(%rcx,%rcx),%rsi
-+	movz	%bl,%ecx
-+	lea	(%rdx,%rdx),%rdi
-+	movz	%bh,%edx
-+	xor	4(%rbp,%rsi,8),@mm[4]
-+	xor	3(%rbp,%rdi,8),@mm[5]
-+	`"mov	64+$i*8+8+4(%rsp),%ebx"	if($i<7);`	# 64+($i+1)*8+4
-+	lea	(%rcx,%rcx),%rsi
-+	movz	%al,%ecx
-+	lea	(%rdx,%rdx),%rdi
-+	movz	%ah,%edx
-+	xor	2(%rbp,%rsi,8),@mm[6]
-+	xor	1(%rbp,%rdi,8),@mm[7]
-+___
-+    push(@mm,shift(@mm));
-+}
-+$code.=<<___;
-+	lea	128(%rsp),%rbx
-+	mov	24(%rbx),%rsi		# pull round counter
-+	add	\$1,%rsi
-+	cmp	\$10,%rsi
-+	je	.Lroundsdone
-+
-+	mov	%rsi,24(%rbx)		# update round counter
-+___
-+for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; }	# S=L
-+$code.=<<___;
-+	jmp	.Lround
-+.align	16
-+.Lroundsdone:
-+	mov	0(%rbx),%rdi		# reload argument block
-+	mov	8(%rbx),%rsi
-+	mov	16(%rbx),%rax
-+___
-+for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; }	# L^=inp
-+for($i=0;$i<8;$i++) { $code.="xor $i*8(%rdi),@mm[$i]\n"; }	# L^=H
-+for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rdi)\n"; }	# H=L
-+$code.=<<___;
-+	lea	64(%rsi),%rsi		# inp+=64
-+	sub	\$1,%rax		# num--
-+	jz	.Lalldone
-+	mov	%rsi,8(%rbx)		# update parameter block
-+	mov	%rax,16(%rbx)
-+	jmp	.Louterloop
-+.Lalldone:
-+	mov	32(%rbx),%rsi		# restore saved pointer
-+	mov	(%rsi),%r15
-+	mov	8(%rsi),%r14
-+	mov	16(%rsi),%r13
-+	mov	24(%rsi),%r12
-+	mov	32(%rsi),%rbp
-+	mov	40(%rsi),%rbx
-+	lea	48(%rsi),%rsp
-+.Lepilogue:
-+	ret
-+.size	$func,.-$func
-+
-+.align	64
-+.type	$table,\@object
-+$table:
-+___
-+	&LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8);
-+	&LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26);
-+	&LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8);
-+	&LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb);
-+	&LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb);
-+	&LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11);
-+	&LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09);
-+	&LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d);
-+	&LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b);
-+	&LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff);
-+	&LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c);
-+	&LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e);
-+	&LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96);
-+	&LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30);
-+	&LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d);
-+	&LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8);
-+	&LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47);
-+	&LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35);
-+	&LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37);
-+	&LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a);
-+	&LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2);
-+	&LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c);
-+	&LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84);
-+	&LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80);
-+	&LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5);
-+	&LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3);
-+	&LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21);
-+	&LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c);
-+	&LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43);
-+	&LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29);
-+	&LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d);
-+	&LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5);
-+	&LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd);
-+	&LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8);
-+	&LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92);
-+	&LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e);
-+	&LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13);
-+	&LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23);
-+	&LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20);
-+	&LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44);
-+	&LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2);
-+	&LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf);
-+	&LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c);
-+	&LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a);
-+	&LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50);
-+	&LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9);
-+	&LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14);
-+	&LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9);
-+	&LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c);
-+	&LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f);
-+	&LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90);
-+	&LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07);
-+	&LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd);
-+	&LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3);
-+	&LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d);
-+	&LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78);
-+	&LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97);
-+	&LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02);
-+	&LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73);
-+	&LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7);
-+	&LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6);
-+	&LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2);
-+	&LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49);
-+	&LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56);
-+	&LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70);
-+	&LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd);
-+	&LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb);
-+	&LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71);
-+	&LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b);
-+	&LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf);
-+	&LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45);
-+	&LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a);
-+	&LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4);
-+	&LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58);
-+	&LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e);
-+	&LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f);
-+	&LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac);
-+	&LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0);
-+	&LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef);
-+	&LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6);
-+	&LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c);
-+	&LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12);
-+	&LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93);
-+	&LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde);
-+	&LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6);
-+	&LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1);
-+	&LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b);
-+	&LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f);
-+	&LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31);
-+	&LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8);
-+	&LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9);
-+	&LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc);
-+	&LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e);
-+	&LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b);
-+	&LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf);
-+	&LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59);
-+	&LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2);
-+	&LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77);
-+	&LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33);
-+	&LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4);
-+	&LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27);
-+	&LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb);
-+	&LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89);
-+	&LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32);
-+	&LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54);
-+	&LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d);
-+	&LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64);
-+	&LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d);
-+	&LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d);
-+	&LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f);
-+	&LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca);
-+	&LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7);
-+	&LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d);
-+	&LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce);
-+	&LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f);
-+	&LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f);
-+	&LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63);
-+	&LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a);
-+	&LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc);
-+	&LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82);
-+	&LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a);
-+	&LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48);
-+	&LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95);
-+	&LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf);
-+	&LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d);
-+	&LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0);
-+	&LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91);
-+	&LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8);
-+	&LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b);
-+	&LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
-+	&LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9);
-+	&LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e);
-+	&LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1);
-+	&LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6);
-+	&LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28);
-+	&LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3);
-+	&LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74);
-+	&LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe);
-+	&LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d);
-+	&LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea);
-+	&LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57);
-+	&LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38);
-+	&LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad);
-+	&LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4);
-+	&LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda);
-+	&LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7);
-+	&LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb);
-+	&LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9);
-+	&LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a);
-+	&LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03);
-+	&LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a);
-+	&LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e);
-+	&LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60);
-+	&LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc);
-+	&LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46);
-+	&LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f);
-+	&LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76);
-+	&LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa);
-+	&LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36);
-+	&LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae);
-+	&LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b);
-+	&LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85);
-+	&LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e);
-+	&LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7);
-+	&LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55);
-+	&LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a);
-+	&LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81);
-+	&LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52);
-+	&LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62);
-+	&LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3);
-+	&LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10);
-+	&LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab);
-+	&LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0);
-+	&LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5);
-+	&LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec);
-+	&LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16);
-+	&LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94);
-+	&LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f);
-+	&LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5);
-+	&LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98);
-+	&LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17);
-+	&LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4);
-+	&LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1);
-+	&LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e);
-+	&LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42);
-+	&LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34);
-+	&LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08);
-+	&LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee);
-+	&LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61);
-+	&LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1);
-+	&LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f);
-+	&LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24);
-+	&LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3);
-+	&LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25);
-+	&LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22);
-+	&LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65);
-+	&LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79);
-+	&LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69);
-+	&LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9);
-+	&LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19);
-+	&LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe);
-+	&LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a);
-+	&LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0);
-+	&LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99);
-+	&LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83);
-+	&LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04);
-+	&LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66);
-+	&LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0);
-+	&LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1);
-+	&LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd);
-+	&LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40);
-+	&LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c);
-+	&LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18);
-+	&LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b);
-+	&LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51);
-+	&LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05);
-+	&LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c);
-+	&LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39);
-+	&LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa);
-+	&LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b);
-+	&LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc);
-+	&LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e);
-+	&LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0);
-+	&LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88);
-+	&LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67);
-+	&LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a);
-+	&LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87);
-+	&LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1);
-+	&LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72);
-+	&LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53);
-+	&LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01);
-+	&LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b);
-+	&LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4);
-+	&LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3);
-+	&LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15);
-+	&LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c);
-+	&LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5);
-+	&LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5);
-+	&LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4);
-+	&LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba);
-+	&LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6);
-+	&LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7);
-+	&LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06);
-+	&LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41);
-+	&LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7);
-+	&LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f);
-+	&LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e);
-+	&LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6);
-+	&LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2);
-+	&LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68);
-+	&LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c);
-+	&LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed);
-+	&LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75);
-+	&LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86);
-+	&LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b);
-+	&LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2);
-+
-+	&L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f);	# rc[ROUNDS]
-+	&L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52);
-+	&L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35);
-+	&L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57);
-+	&L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda);
-+	&L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85);
-+	&L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67);
-+	&L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8);
-+	&L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e);
-+	&L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33);
-+
-+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
-+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
-+if ($win64) {
-+$rec="%rcx";
-+$frame="%rdx";
-+$context="%r8";
-+$disp="%r9";
-+
-+$code.=<<___;
-+.extern	__imp_RtlVirtualUnwind
-+.type	se_handler,\@abi-omnipotent
-+.align	16
-+se_handler:
-+	push	%rsi
-+	push	%rdi
-+	push	%rbx
-+	push	%rbp
-+	push	%r12
-+	push	%r13
-+	push	%r14
-+	push	%r15
-+	pushfq
-+	sub	\$64,%rsp
-+
-+	mov	120($context),%rax	# pull context->Rax
-+	mov	248($context),%rbx	# pull context->Rip
-+
-+	lea	.Lprologue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip<.Lprologue
-+	jb	.Lin_prologue
-+
-+	mov	152($context),%rax	# pull context->Rsp
-+
-+	lea	.Lepilogue(%rip),%r10
-+	cmp	%r10,%rbx		# context->Rip>=.Lepilogue
-+	jae	.Lin_prologue
-+
-+	mov	128+32(%rax),%rax	# pull saved stack pointer
-+	lea	48(%rax),%rax
-+
-+	mov	-8(%rax),%rbx
-+	mov	-16(%rax),%rbp
-+	mov	-24(%rax),%r12
-+	mov	-32(%rax),%r13
-+	mov	-40(%rax),%r14
-+	mov	-48(%rax),%r15
-+	mov	%rbx,144($context)	# restore context->Rbx
-+	mov	%rbp,160($context)	# restore context->Rbp
-+	mov	%r12,216($context)	# restore context->R12
-+	mov	%r13,224($context)	# restore context->R13
-+	mov	%r14,232($context)	# restore context->R14
-+	mov	%r15,240($context)	# restore context->R15
-+
-+.Lin_prologue:
-+	mov	8(%rax),%rdi
-+	mov	16(%rax),%rsi
-+	mov	%rax,152($context)	# restore context->Rsp
-+	mov	%rsi,168($context)	# restore context->Rsi
-+	mov	%rdi,176($context)	# restore context->Rdi
-+
-+	mov	40($disp),%rdi		# disp->ContextRecord
-+	mov	$context,%rsi		# context
-+	mov	\$154,%ecx		# sizeof(CONTEXT)
-+	.long	0xa548f3fc		# cld; rep movsq
-+
-+	mov	$disp,%rsi
-+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
-+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
-+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
-+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
-+	mov	40(%rsi),%r10		# disp->ContextRecord
-+	lea	56(%rsi),%r11		# &disp->HandlerData
-+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
-+	mov	%r10,32(%rsp)		# arg5
-+	mov	%r11,40(%rsp)		# arg6
-+	mov	%r12,48(%rsp)		# arg7
-+	mov	%rcx,56(%rsp)		# arg8, (NULL)
-+	call	*__imp_RtlVirtualUnwind(%rip)
-+
-+	mov	\$1,%eax		# ExceptionContinueSearch
-+	add	\$64,%rsp
-+	popfq
-+	pop	%r15
-+	pop	%r14
-+	pop	%r13
-+	pop	%r12
-+	pop	%rbp
-+	pop	%rbx
-+	pop	%rdi
-+	pop	%rsi
-+	ret
-+.size	se_handler,.-se_handler
-+
-+.section	.pdata
-+.align	4
-+	.rva	.LSEH_begin_$func
-+	.rva	.LSEH_end_$func
-+	.rva	.LSEH_info_$func
-+
-+.section	.xdata
-+.align	8
-+.LSEH_info_$func:
-+	.byte	9,0,0,0
-+	.rva	se_handler
-+___
-+}
-+
-+$code =~ s/\`([^\`]*)\`/eval $1/gem;
-+print $code;
-+close STDOUT;
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/build.info
-new file mode 100644
-index 0000000..7f3a19e
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/build.info
-@@ -0,0 +1,7 @@
-+LIBS=../../libcrypto
-+SOURCE[../../libcrypto]=wp_dgst.c {- $target{wp_asm_src} -}
-+
-+GENERATE[wp-mmx.s]=asm/wp-mmx.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
-+DEPEND[wp-mmx.s]=../perlasm/x86asm.pl
-+
-+GENERATE[wp-x86_64.s]=asm/wp-x86_64.pl $(PERLASM_SCHEME)
-diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_block.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_block.c
-new file mode 100644
-index 0000000..b29f037
---- /dev/null
-+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_block.c
-@@ -0,0 +1,792 @@
-+/*
-+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License").  You may not use
-+ * this file except in compliance with the License.  You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+/**
-+ * The Whirlpool hashing function.
-+ *
-+ * 

-+ * References -+ * -+ *

-+ * The Whirlpool algorithm was developed by -+ * Paulo S. L. M. Barreto and -+ * Vincent Rijmen. -+ * -+ * See -+ * P.S.L.M. Barreto, V. Rijmen, -+ * ``The Whirlpool hashing function,'' -+ * NESSIE submission, 2000 (tweaked version, 2001), -+ * -+ * -+ * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and -+ * Vincent Rijmen. Lookup "reference implementations" on -+ * -+ * -+ * ============================================================================= -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS -+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ */ -+ -+#include "wp_locl.h" -+#include -+ -+typedef unsigned char u8; -+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32) -+typedef unsigned __int64 u64; -+#elif defined(__arch64__) -+typedef unsigned long u64; -+#else -+typedef unsigned long long u64; -+#endif -+ -+#define ROUNDS 10 -+ -+#define STRICT_ALIGNMENT -+#if !defined(PEDANTIC) && (defined(__i386) || defined(__i386__) || \ -+ defined(__x86_64) || defined(__x86_64__) || \ -+ defined(_M_IX86) || defined(_M_AMD64) || \ -+ defined(_M_X64)) -+/* -+ * Well, formally there're couple of other architectures, which permit -+ * unaligned loads, specifically those not crossing cache lines, IA-64 and -+ * PowerPC... -+ */ -+# undef STRICT_ALIGNMENT -+#endif -+ -+#undef SMALL_REGISTER_BANK -+#if defined(__i386) || defined(__i386__) || defined(_M_IX86) -+# define SMALL_REGISTER_BANK -+# if defined(WHIRLPOOL_ASM) -+# ifndef OPENSSL_SMALL_FOOTPRINT -+/* -+ * it appears that for elder non-MMX -+ * CPUs this is actually faster! -+ */ -+# define OPENSSL_SMALL_FOOTPRINT -+# endif -+# define GO_FOR_MMX(ctx,inp,num) do { \ -+ extern unsigned long OPENSSL_ia32cap_P[]; \ -+ void whirlpool_block_mmx(void *,const void *,size_t); \ -+ if (!(OPENSSL_ia32cap_P[0] & (1<<23))) break; \ -+ whirlpool_block_mmx(ctx->H.c,inp,num); return; \ -+ } while (0) -+# endif -+#endif -+ -+#undef ROTATE -+#ifndef PEDANTIC -+# if defined(_MSC_VER) -+# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ -+# pragma intrinsic(_rotl64) -+# define ROTATE(a,n) _rotl64((a),n) -+# endif -+# elif defined(__GNUC__) && __GNUC__>=2 -+# if defined(__x86_64) || defined(__x86_64__) -+# if defined(L_ENDIAN) -+# define ROTATE(a,n) ({ u64 ret; asm ("rolq %1,%0" \ -+ : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) -+# elif defined(B_ENDIAN) -+ /* -+ * Most will argue that x86_64 is always little-endian. Well, yes, but -+ * then we have stratus.com who has modified gcc to "emulate" -+ * big-endian on x86. Is there evidence that they [or somebody else] -+ * won't do same for x86_64? Naturally no. And this line is waiting -+ * ready for that brave soul:-) -+ */ -+# define ROTATE(a,n) ({ u64 ret; asm ("rorq %1,%0" \ -+ : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) -+# endif -+# elif defined(__ia64) || defined(__ia64__) -+# if defined(L_ENDIAN) -+# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ -+ : "=r"(ret) : "r"(a),"M"(64-(n))); ret; }) -+# elif defined(B_ENDIAN) -+# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ -+ : "=r"(ret) : "r"(a),"M"(n)); ret; }) -+# endif -+# endif -+# endif -+#endif -+ -+#if defined(OPENSSL_SMALL_FOOTPRINT) -+# if !defined(ROTATE) -+# if defined(L_ENDIAN) /* little-endians have to rotate left */ -+# define ROTATE(i,n) ((i)<<(n) ^ (i)>>(64-n)) -+# elif defined(B_ENDIAN) /* big-endians have to rotate right */ -+# define ROTATE(i,n) ((i)>>(n) ^ (i)<<(64-n)) -+# endif -+# endif -+# if defined(ROTATE) && !defined(STRICT_ALIGNMENT) -+# define STRICT_ALIGNMENT /* ensure smallest table size */ -+# endif -+#endif -+ -+/* -+ * Table size depends on STRICT_ALIGNMENT and whether or not endian- -+ * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not -+ * defined, which is normally the case on x86[_64] CPUs, the table is -+ * 4KB large unconditionally. Otherwise if ROTATE is defined, the -+ * table is 2KB large, and otherwise - 16KB. 2KB table requires a -+ * whole bunch of additional rotations, but I'm willing to "trade," -+ * because 16KB table certainly trashes L1 cache. I wish all CPUs -+ * could handle unaligned load as 4KB table doesn't trash the cache, -+ * nor does it require additional rotations. -+ */ -+/* -+ * Note that every Cn macro expands as two loads: one byte load and -+ * one quadword load. One can argue that that many single-byte loads -+ * is too excessive, as one could load a quadword and "milk" it for -+ * eight 8-bit values instead. Well, yes, but in order to do so *and* -+ * avoid excessive loads you have to accommodate a handful of 64-bit -+ * values in the register bank and issue a bunch of shifts and mask. -+ * It's a tradeoff: loads vs. shift and mask in big register bank[!]. -+ * On most CPUs eight single-byte loads are faster and I let other -+ * ones to depend on smart compiler to fold byte loads if beneficial. -+ * Hand-coded assembler would be another alternative:-) -+ */ -+#ifdef STRICT_ALIGNMENT -+# if defined(ROTATE) -+# define N 1 -+# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7 -+# define C0(K,i) (Cx.q[K.c[(i)*8+0]]) -+# define C1(K,i) ROTATE(Cx.q[K.c[(i)*8+1]],8) -+# define C2(K,i) ROTATE(Cx.q[K.c[(i)*8+2]],16) -+# define C3(K,i) ROTATE(Cx.q[K.c[(i)*8+3]],24) -+# define C4(K,i) ROTATE(Cx.q[K.c[(i)*8+4]],32) -+# define C5(K,i) ROTATE(Cx.q[K.c[(i)*8+5]],40) -+# define C6(K,i) ROTATE(Cx.q[K.c[(i)*8+6]],48) -+# define C7(K,i) ROTATE(Cx.q[K.c[(i)*8+7]],56) -+# else -+# define N 8 -+# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ -+ c7,c0,c1,c2,c3,c4,c5,c6, \ -+ c6,c7,c0,c1,c2,c3,c4,c5, \ -+ c5,c6,c7,c0,c1,c2,c3,c4, \ -+ c4,c5,c6,c7,c0,c1,c2,c3, \ -+ c3,c4,c5,c6,c7,c0,c1,c2, \ -+ c2,c3,c4,c5,c6,c7,c0,c1, \ -+ c1,c2,c3,c4,c5,c6,c7,c0 -+# define C0(K,i) (Cx.q[0+8*K.c[(i)*8+0]]) -+# define C1(K,i) (Cx.q[1+8*K.c[(i)*8+1]]) -+# define C2(K,i) (Cx.q[2+8*K.c[(i)*8+2]]) -+# define C3(K,i) (Cx.q[3+8*K.c[(i)*8+3]]) -+# define C4(K,i) (Cx.q[4+8*K.c[(i)*8+4]]) -+# define C5(K,i) (Cx.q[5+8*K.c[(i)*8+5]]) -+# define C6(K,i) (Cx.q[6+8*K.c[(i)*8+6]]) -+# define C7(K,i) (Cx.q[7+8*K.c[(i)*8+7]]) -+# endif -+#else -+# define N 2 -+# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ -+ c0,c1,c2,c3,c4,c5,c6,c7 -+# define C0(K,i) (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]]) -+# define C1(K,i) (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]]) -+# define C2(K,i) (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]]) -+# define C3(K,i) (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]]) -+# define C4(K,i) (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]]) -+# define C5(K,i) (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]]) -+# define C6(K,i) (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]]) -+# define C7(K,i) (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]]) -+#endif -+ -+static const -+ union { -+ u8 c[(256 * N + ROUNDS) * sizeof(u64)]; -+ u64 q[(256 * N + ROUNDS)]; -+} Cx = { -+ { -+ /* Note endian-neutral representation:-) */ -+ LL(0x18, 0x18, 0x60, 0x18, 0xc0, 0x78, 0x30, 0xd8), -+ LL(0x23, 0x23, 0x8c, 0x23, 0x05, 0xaf, 0x46, 0x26), -+ LL(0xc6, 0xc6, 0x3f, 0xc6, 0x7e, 0xf9, 0x91, 0xb8), -+ LL(0xe8, 0xe8, 0x87, 0xe8, 0x13, 0x6f, 0xcd, 0xfb), -+ LL(0x87, 0x87, 0x26, 0x87, 0x4c, 0xa1, 0x13, 0xcb), -+ LL(0xb8, 0xb8, 0xda, 0xb8, 0xa9, 0x62, 0x6d, 0x11), -+ LL(0x01, 0x01, 0x04, 0x01, 0x08, 0x05, 0x02, 0x09), -+ LL(0x4f, 0x4f, 0x21, 0x4f, 0x42, 0x6e, 0x9e, 0x0d), -+ LL(0x36, 0x36, 0xd8, 0x36, 0xad, 0xee, 0x6c, 0x9b), -+ LL(0xa6, 0xa6, 0xa2, 0xa6, 0x59, 0x04, 0x51, 0xff), -+ LL(0xd2, 0xd2, 0x6f, 0xd2, 0xde, 0xbd, 0xb9, 0x0c), -+ LL(0xf5, 0xf5, 0xf3, 0xf5, 0xfb, 0x06, 0xf7, 0x0e), -+ LL(0x79, 0x79, 0xf9, 0x79, 0xef, 0x80, 0xf2, 0x96), -+ LL(0x6f, 0x6f, 0xa1, 0x6f, 0x5f, 0xce, 0xde, 0x30), -+ LL(0x91, 0x91, 0x7e, 0x91, 0xfc, 0xef, 0x3f, 0x6d), -+ LL(0x52, 0x52, 0x55, 0x52, 0xaa, 0x07, 0xa4, 0xf8), -+ LL(0x60, 0x60, 0x9d, 0x60, 0x27, 0xfd, 0xc0, 0x47), -+ LL(0xbc, 0xbc, 0xca, 0xbc, 0x89, 0x76, 0x65, 0x35), -+ LL(0x9b, 0x9b, 0x56, 0x9b, 0xac, 0xcd, 0x2b, 0x37), -+ LL(0x8e, 0x8e, 0x02, 0x8e, 0x04, 0x8c, 0x01, 0x8a), -+ LL(0xa3, 0xa3, 0xb6, 0xa3, 0x71, 0x15, 0x5b, 0xd2), -+ LL(0x0c, 0x0c, 0x30, 0x0c, 0x60, 0x3c, 0x18, 0x6c), -+ LL(0x7b, 0x7b, 0xf1, 0x7b, 0xff, 0x8a, 0xf6, 0x84), -+ LL(0x35, 0x35, 0xd4, 0x35, 0xb5, 0xe1, 0x6a, 0x80), -+ LL(0x1d, 0x1d, 0x74, 0x1d, 0xe8, 0x69, 0x3a, 0xf5), -+ LL(0xe0, 0xe0, 0xa7, 0xe0, 0x53, 0x47, 0xdd, 0xb3), -+ LL(0xd7, 0xd7, 0x7b, 0xd7, 0xf6, 0xac, 0xb3, 0x21), -+ LL(0xc2, 0xc2, 0x2f, 0xc2, 0x5e, 0xed, 0x99, 0x9c), -+ LL(0x2e, 0x2e, 0xb8, 0x2e, 0x6d, 0x96, 0x5c, 0x43), -+ LL(0x4b, 0x4b, 0x31, 0x4b, 0x62, 0x7a, 0x96, 0x29), -+ LL(0xfe, 0xfe, 0xdf, 0xfe, 0xa3, 0x21, 0xe1, 0x5d), -+ LL(0x57, 0x57, 0x41, 0x57, 0x82, 0x16, 0xae, 0xd5), -+ LL(0x15, 0x15, 0x54, 0x15, 0xa8, 0x41, 0x2a, 0xbd), -+ LL(0x77, 0x77, 0xc1, 0x77, 0x9f, 0xb6, 0xee, 0xe8), -+ LL(0x37, 0x37, 0xdc, 0x37, 0xa5, 0xeb, 0x6e, 0x92), -+ LL(0xe5, 0xe5, 0xb3, 0xe5, 0x7b, 0x56, 0xd7, 0x9e), -+ LL(0x9f, 0x9f, 0x46, 0x9f, 0x8c, 0xd9, 0x23, 0x13), -+ LL(0xf0, 0xf0, 0xe7, 0xf0, 0xd3, 0x17, 0xfd, 0x23), -+ LL(0x4a, 0x4a, 0x35, 0x4a, 0x6a, 0x7f, 0x94, 0x20), -+ LL(0xda, 0xda, 0x4f, 0xda, 0x9e, 0x95, 0xa9, 0x44), -+ LL(0x58, 0x58, 0x7d, 0x58, 0xfa, 0x25, 0xb0, 0xa2), -+ LL(0xc9, 0xc9, 0x03, 0xc9, 0x06, 0xca, 0x8f, 0xcf), -+ LL(0x29, 0x29, 0xa4, 0x29, 0x55, 0x8d, 0x52, 0x7c), -+ LL(0x0a, 0x0a, 0x28, 0x0a, 0x50, 0x22, 0x14, 0x5a), -+ LL(0xb1, 0xb1, 0xfe, 0xb1, 0xe1, 0x4f, 0x7f, 0x50), -+ LL(0xa0, 0xa0, 0xba, 0xa0, 0x69, 0x1a, 0x5d, 0xc9), -+ LL(0x6b, 0x6b, 0xb1, 0x6b, 0x7f, 0xda, 0xd6, 0x14), -+ LL(0x85, 0x85, 0x2e, 0x85, 0x5c, 0xab, 0x17, 0xd9), -+ LL(0xbd, 0xbd, 0xce, 0xbd, 0x81, 0x73, 0x67, 0x3c), -+ LL(0x5d, 0x5d, 0x69, 0x5d, 0xd2, 0x34, 0xba, 0x8f), -+ LL(0x10, 0x10, 0x40, 0x10, 0x80, 0x50, 0x20, 0x90), -+ LL(0xf4, 0xf4, 0xf7, 0xf4, 0xf3, 0x03, 0xf5, 0x07), -+ LL(0xcb, 0xcb, 0x0b, 0xcb, 0x16, 0xc0, 0x8b, 0xdd), -+ LL(0x3e, 0x3e, 0xf8, 0x3e, 0xed, 0xc6, 0x7c, 0xd3), -+ LL(0x05, 0x05, 0x14, 0x05, 0x28, 0x11, 0x0a, 0x2d), -+ LL(0x67, 0x67, 0x81, 0x67, 0x1f, 0xe6, 0xce, 0x78), -+ LL(0xe4, 0xe4, 0xb7, 0xe4, 0x73, 0x53, 0xd5, 0x97), -+ LL(0x27, 0x27, 0x9c, 0x27, 0x25, 0xbb, 0x4e, 0x02), -+ LL(0x41, 0x41, 0x19, 0x41, 0x32, 0x58, 0x82, 0x73), -+ LL(0x8b, 0x8b, 0x16, 0x8b, 0x2c, 0x9d, 0x0b, 0xa7), -+ LL(0xa7, 0xa7, 0xa6, 0xa7, 0x51, 0x01, 0x53, 0xf6), -+ LL(0x7d, 0x7d, 0xe9, 0x7d, 0xcf, 0x94, 0xfa, 0xb2), -+ LL(0x95, 0x95, 0x6e, 0x95, 0xdc, 0xfb, 0x37, 0x49), -+ LL(0xd8, 0xd8, 0x47, 0xd8, 0x8e, 0x9f, 0xad, 0x56), -+ LL(0xfb, 0xfb, 0xcb, 0xfb, 0x8b, 0x30, 0xeb, 0x70), -+ LL(0xee, 0xee, 0x9f, 0xee, 0x23, 0x71, 0xc1, 0xcd), -+ LL(0x7c, 0x7c, 0xed, 0x7c, 0xc7, 0x91, 0xf8, 0xbb), -+ LL(0x66, 0x66, 0x85, 0x66, 0x17, 0xe3, 0xcc, 0x71), -+ LL(0xdd, 0xdd, 0x53, 0xdd, 0xa6, 0x8e, 0xa7, 0x7b), -+ LL(0x17, 0x17, 0x5c, 0x17, 0xb8, 0x4b, 0x2e, 0xaf), -+ LL(0x47, 0x47, 0x01, 0x47, 0x02, 0x46, 0x8e, 0x45), -+ LL(0x9e, 0x9e, 0x42, 0x9e, 0x84, 0xdc, 0x21, 0x1a), -+ LL(0xca, 0xca, 0x0f, 0xca, 0x1e, 0xc5, 0x89, 0xd4), -+ LL(0x2d, 0x2d, 0xb4, 0x2d, 0x75, 0x99, 0x5a, 0x58), -+ LL(0xbf, 0xbf, 0xc6, 0xbf, 0x91, 0x79, 0x63, 0x2e), -+ LL(0x07, 0x07, 0x1c, 0x07, 0x38, 0x1b, 0x0e, 0x3f), -+ LL(0xad, 0xad, 0x8e, 0xad, 0x01, 0x23, 0x47, 0xac), -+ LL(0x5a, 0x5a, 0x75, 0x5a, 0xea, 0x2f, 0xb4, 0xb0), -+ LL(0x83, 0x83, 0x36, 0x83, 0x6c, 0xb5, 0x1b, 0xef), -+ LL(0x33, 0x33, 0xcc, 0x33, 0x85, 0xff, 0x66, 0xb6), -+ LL(0x63, 0x63, 0x91, 0x63, 0x3f, 0xf2, 0xc6, 0x5c), -+ LL(0x02, 0x02, 0x08, 0x02, 0x10, 0x0a, 0x04, 0x12), -+ LL(0xaa, 0xaa, 0x92, 0xaa, 0x39, 0x38, 0x49, 0x93), -+ LL(0x71, 0x71, 0xd9, 0x71, 0xaf, 0xa8, 0xe2, 0xde), -+ LL(0xc8, 0xc8, 0x07, 0xc8, 0x0e, 0xcf, 0x8d, 0xc6), -+ LL(0x19, 0x19, 0x64, 0x19, 0xc8, 0x7d, 0x32, 0xd1), -+ LL(0x49, 0x49, 0x39, 0x49, 0x72, 0x70, 0x92, 0x3b), -+ LL(0xd9, 0xd9, 0x43, 0xd9, 0x86, 0x9a, 0xaf, 0x5f), -+ LL(0xf2, 0xf2, 0xef, 0xf2, 0xc3, 0x1d, 0xf9, 0x31), -+ LL(0xe3, 0xe3, 0xab, 0xe3, 0x4b, 0x48, 0xdb, 0xa8), -+ LL(0x5b, 0x5b, 0x71, 0x5b, 0xe2, 0x2a, 0xb6, 0xb9), -+ LL(0x88, 0x88, 0x1a, 0x88, 0x34, 0x92, 0x0d, 0xbc), -+ LL(0x9a, 0x9a, 0x52, 0x9a, 0xa4, 0xc8, 0x29, 0x3e), -+ LL(0x26, 0x26, 0x98, 0x26, 0x2d, 0xbe, 0x4c, 0x0b), -+ LL(0x32, 0x32, 0xc8, 0x32, 0x8d, 0xfa, 0x64, 0xbf), -+ LL(0xb0, 0xb0, 0xfa, 0xb0, 0xe9, 0x4a, 0x7d, 0x59), -+ LL(0xe9, 0xe9, 0x83, 0xe9, 0x1b, 0x6a, 0xcf, 0xf2), -+ LL(0x0f, 0x0f, 0x3c, 0x0f, 0x78, 0x33, 0x1e, 0x77), -+ LL(0xd5, 0xd5, 0x73, 0xd5, 0xe6, 0xa6, 0xb7, 0x33), -+ LL(0x80, 0x80, 0x3a, 0x80, 0x74, 0xba, 0x1d, 0xf4), -+ LL(0xbe, 0xbe, 0xc2, 0xbe, 0x99, 0x7c, 0x61, 0x27), -+ LL(0xcd, 0xcd, 0x13, 0xcd, 0x26, 0xde, 0x87, 0xeb), -+ LL(0x34, 0x34, 0xd0, 0x34, 0xbd, 0xe4, 0x68, 0x89), -+ LL(0x48, 0x48, 0x3d, 0x48, 0x7a, 0x75, 0x90, 0x32), -+ LL(0xff, 0xff, 0xdb, 0xff, 0xab, 0x24, 0xe3, 0x54), -+ LL(0x7a, 0x7a, 0xf5, 0x7a, 0xf7, 0x8f, 0xf4, 0x8d), -+ LL(0x90, 0x90, 0x7a, 0x90, 0xf4, 0xea, 0x3d, 0x64), -+ LL(0x5f, 0x5f, 0x61, 0x5f, 0xc2, 0x3e, 0xbe, 0x9d), -+ LL(0x20, 0x20, 0x80, 0x20, 0x1d, 0xa0, 0x40, 0x3d), -+ LL(0x68, 0x68, 0xbd, 0x68, 0x67, 0xd5, 0xd0, 0x0f), -+ LL(0x1a, 0x1a, 0x68, 0x1a, 0xd0, 0x72, 0x34, 0xca), -+ LL(0xae, 0xae, 0x82, 0xae, 0x19, 0x2c, 0x41, 0xb7), -+ LL(0xb4, 0xb4, 0xea, 0xb4, 0xc9, 0x5e, 0x75, 0x7d), -+ LL(0x54, 0x54, 0x4d, 0x54, 0x9a, 0x19, 0xa8, 0xce), -+ LL(0x93, 0x93, 0x76, 0x93, 0xec, 0xe5, 0x3b, 0x7f), -+ LL(0x22, 0x22, 0x88, 0x22, 0x0d, 0xaa, 0x44, 0x2f), -+ LL(0x64, 0x64, 0x8d, 0x64, 0x07, 0xe9, 0xc8, 0x63), -+ LL(0xf1, 0xf1, 0xe3, 0xf1, 0xdb, 0x12, 0xff, 0x2a), -+ LL(0x73, 0x73, 0xd1, 0x73, 0xbf, 0xa2, 0xe6, 0xcc), -+ LL(0x12, 0x12, 0x48, 0x12, 0x90, 0x5a, 0x24, 0x82), -+ LL(0x40, 0x40, 0x1d, 0x40, 0x3a, 0x5d, 0x80, 0x7a), -+ LL(0x08, 0x08, 0x20, 0x08, 0x40, 0x28, 0x10, 0x48), -+ LL(0xc3, 0xc3, 0x2b, 0xc3, 0x56, 0xe8, 0x9b, 0x95), -+ LL(0xec, 0xec, 0x97, 0xec, 0x33, 0x7b, 0xc5, 0xdf), -+ LL(0xdb, 0xdb, 0x4b, 0xdb, 0x96, 0x90, 0xab, 0x4d), -+ LL(0xa1, 0xa1, 0xbe, 0xa1, 0x61, 0x1f, 0x5f, 0xc0), -+ LL(0x8d, 0x8d, 0x0e, 0x8d, 0x1c, 0x83, 0x07, 0x91), -+ LL(0x3d, 0x3d, 0xf4, 0x3d, 0xf5, 0xc9, 0x7a, 0xc8), -+ LL(0x97, 0x97, 0x66, 0x97, 0xcc, 0xf1, 0x33, 0x5b), -+ LL(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), -+ LL(0xcf, 0xcf, 0x1b, 0xcf, 0x36, 0xd4, 0x83, 0xf9), -+ LL(0x2b, 0x2b, 0xac, 0x2b, 0x45, 0x87, 0x56, 0x6e), -+ LL(0x76, 0x76, 0xc5, 0x76, 0x97, 0xb3, 0xec, 0xe1), -+ LL(0x82, 0x82, 0x32, 0x82, 0x64, 0xb0, 0x19, 0xe6), -+ LL(0xd6, 0xd6, 0x7f, 0xd6, 0xfe, 0xa9, 0xb1, 0x28), -+ LL(0x1b, 0x1b, 0x6c, 0x1b, 0xd8, 0x77, 0x36, 0xc3), -+ LL(0xb5, 0xb5, 0xee, 0xb5, 0xc1, 0x5b, 0x77, 0x74), -+ LL(0xaf, 0xaf, 0x86, 0xaf, 0x11, 0x29, 0x43, 0xbe), -+ LL(0x6a, 0x6a, 0xb5, 0x6a, 0x77, 0xdf, 0xd4, 0x1d), -+ LL(0x50, 0x50, 0x5d, 0x50, 0xba, 0x0d, 0xa0, 0xea), -+ LL(0x45, 0x45, 0x09, 0x45, 0x12, 0x4c, 0x8a, 0x57), -+ LL(0xf3, 0xf3, 0xeb, 0xf3, 0xcb, 0x18, 0xfb, 0x38), -+ LL(0x30, 0x30, 0xc0, 0x30, 0x9d, 0xf0, 0x60, 0xad), -+ LL(0xef, 0xef, 0x9b, 0xef, 0x2b, 0x74, 0xc3, 0xc4), -+ LL(0x3f, 0x3f, 0xfc, 0x3f, 0xe5, 0xc3, 0x7e, 0xda), -+ LL(0x55, 0x55, 0x49, 0x55, 0x92, 0x1c, 0xaa, 0xc7), -+ LL(0xa2, 0xa2, 0xb2, 0xa2, 0x79, 0x10, 0x59, 0xdb), -+ LL(0xea, 0xea, 0x8f, 0xea, 0x03, 0x65, 0xc9, 0xe9), -+ LL(0x65, 0x65, 0x89, 0x65, 0x0f, 0xec, 0xca, 0x6a), -+ LL(0xba, 0xba, 0xd2, 0xba, 0xb9, 0x68, 0x69, 0x03), -+ LL(0x2f, 0x2f, 0xbc, 0x2f, 0x65, 0x93, 0x5e, 0x4a), -+ LL(0xc0, 0xc0, 0x27, 0xc0, 0x4e, 0xe7, 0x9d, 0x8e), -+ LL(0xde, 0xde, 0x5f, 0xde, 0xbe, 0x81, 0xa1, 0x60), -+ LL(0x1c, 0x1c, 0x70, 0x1c, 0xe0, 0x6c, 0x38, 0xfc), -+ LL(0xfd, 0xfd, 0xd3, 0xfd, 0xbb, 0x2e, 0xe7, 0x46), -+ LL(0x4d, 0x4d, 0x29, 0x4d, 0x52, 0x64, 0x9a, 0x1f), -+ LL(0x92, 0x92, 0x72, 0x92, 0xe4, 0xe0, 0x39, 0x76), -+ LL(0x75, 0x75, 0xc9, 0x75, 0x8f, 0xbc, 0xea, 0xfa), -+ LL(0x06, 0x06, 0x18, 0x06, 0x30, 0x1e, 0x0c, 0x36), -+ LL(0x8a, 0x8a, 0x12, 0x8a, 0x24, 0x98, 0x09, 0xae), -+ LL(0xb2, 0xb2, 0xf2, 0xb2, 0xf9, 0x40, 0x79, 0x4b), -+ LL(0xe6, 0xe6, 0xbf, 0xe6, 0x63, 0x59, 0xd1, 0x85), -+ LL(0x0e, 0x0e, 0x38, 0x0e, 0x70, 0x36, 0x1c, 0x7e), -+ LL(0x1f, 0x1f, 0x7c, 0x1f, 0xf8, 0x63, 0x3e, 0xe7), -+ LL(0x62, 0x62, 0x95, 0x62, 0x37, 0xf7, 0xc4, 0x55), -+ LL(0xd4, 0xd4, 0x77, 0xd4, 0xee, 0xa3, 0xb5, 0x3a), -+ LL(0xa8, 0xa8, 0x9a, 0xa8, 0x29, 0x32, 0x4d, 0x81), -+ LL(0x96, 0x96, 0x62, 0x96, 0xc4, 0xf4, 0x31, 0x52), -+ LL(0xf9, 0xf9, 0xc3, 0xf9, 0x9b, 0x3a, 0xef, 0x62), -+ LL(0xc5, 0xc5, 0x33, 0xc5, 0x66, 0xf6, 0x97, 0xa3), -+ LL(0x25, 0x25, 0x94, 0x25, 0x35, 0xb1, 0x4a, 0x10), -+ LL(0x59, 0x59, 0x79, 0x59, 0xf2, 0x20, 0xb2, 0xab), -+ LL(0x84, 0x84, 0x2a, 0x84, 0x54, 0xae, 0x15, 0xd0), -+ LL(0x72, 0x72, 0xd5, 0x72, 0xb7, 0xa7, 0xe4, 0xc5), -+ LL(0x39, 0x39, 0xe4, 0x39, 0xd5, 0xdd, 0x72, 0xec), -+ LL(0x4c, 0x4c, 0x2d, 0x4c, 0x5a, 0x61, 0x98, 0x16), -+ LL(0x5e, 0x5e, 0x65, 0x5e, 0xca, 0x3b, 0xbc, 0x94), -+ LL(0x78, 0x78, 0xfd, 0x78, 0xe7, 0x85, 0xf0, 0x9f), -+ LL(0x38, 0x38, 0xe0, 0x38, 0xdd, 0xd8, 0x70, 0xe5), -+ LL(0x8c, 0x8c, 0x0a, 0x8c, 0x14, 0x86, 0x05, 0x98), -+ LL(0xd1, 0xd1, 0x63, 0xd1, 0xc6, 0xb2, 0xbf, 0x17), -+ LL(0xa5, 0xa5, 0xae, 0xa5, 0x41, 0x0b, 0x57, 0xe4), -+ LL(0xe2, 0xe2, 0xaf, 0xe2, 0x43, 0x4d, 0xd9, 0xa1), -+ LL(0x61, 0x61, 0x99, 0x61, 0x2f, 0xf8, 0xc2, 0x4e), -+ LL(0xb3, 0xb3, 0xf6, 0xb3, 0xf1, 0x45, 0x7b, 0x42), -+ LL(0x21, 0x21, 0x84, 0x21, 0x15, 0xa5, 0x42, 0x34), -+ LL(0x9c, 0x9c, 0x4a, 0x9c, 0x94, 0xd6, 0x25, 0x08), -+ LL(0x1e, 0x1e, 0x78, 0x1e, 0xf0, 0x66, 0x3c, 0xee), -+ LL(0x43, 0x43, 0x11, 0x43, 0x22, 0x52, 0x86, 0x61), -+ LL(0xc7, 0xc7, 0x3b, 0xc7, 0x76, 0xfc, 0x93, 0xb1), -+ LL(0xfc, 0xfc, 0xd7, 0xfc, 0xb3, 0x2b, 0xe5, 0x4f), -+ LL(0x04, 0x04, 0x10, 0x04, 0x20, 0x14, 0x08, 0x24), -+ LL(0x51, 0x51, 0x59, 0x51, 0xb2, 0x08, 0xa2, 0xe3), -+ LL(0x99, 0x99, 0x5e, 0x99, 0xbc, 0xc7, 0x2f, 0x25), -+ LL(0x6d, 0x6d, 0xa9, 0x6d, 0x4f, 0xc4, 0xda, 0x22), -+ LL(0x0d, 0x0d, 0x34, 0x0d, 0x68, 0x39, 0x1a, 0x65), -+ LL(0xfa, 0xfa, 0xcf, 0xfa, 0x83, 0x35, 0xe9, 0x79), -+ LL(0xdf, 0xdf, 0x5b, 0xdf, 0xb6, 0x84, 0xa3, 0x69), -+ LL(0x7e, 0x7e, 0xe5, 0x7e, 0xd7, 0x9b, 0xfc, 0xa9), -+ LL(0x24, 0x24, 0x90, 0x24, 0x3d, 0xb4, 0x48, 0x19), -+ LL(0x3b, 0x3b, 0xec, 0x3b, 0xc5, 0xd7, 0x76, 0xfe), -+ LL(0xab, 0xab, 0x96, 0xab, 0x31, 0x3d, 0x4b, 0x9a), -+ LL(0xce, 0xce, 0x1f, 0xce, 0x3e, 0xd1, 0x81, 0xf0), -+ LL(0x11, 0x11, 0x44, 0x11, 0x88, 0x55, 0x22, 0x99), -+ LL(0x8f, 0x8f, 0x06, 0x8f, 0x0c, 0x89, 0x03, 0x83), -+ LL(0x4e, 0x4e, 0x25, 0x4e, 0x4a, 0x6b, 0x9c, 0x04), -+ LL(0xb7, 0xb7, 0xe6, 0xb7, 0xd1, 0x51, 0x73, 0x66), -+ LL(0xeb, 0xeb, 0x8b, 0xeb, 0x0b, 0x60, 0xcb, 0xe0), -+ LL(0x3c, 0x3c, 0xf0, 0x3c, 0xfd, 0xcc, 0x78, 0xc1), -+ LL(0x81, 0x81, 0x3e, 0x81, 0x7c, 0xbf, 0x1f, 0xfd), -+ LL(0x94, 0x94, 0x6a, 0x94, 0xd4, 0xfe, 0x35, 0x40), -+ LL(0xf7, 0xf7, 0xfb, 0xf7, 0xeb, 0x0c, 0xf3, 0x1c), -+ LL(0xb9, 0xb9, 0xde, 0xb9, 0xa1, 0x67, 0x6f, 0x18), -+ LL(0x13, 0x13, 0x4c, 0x13, 0x98, 0x5f, 0x26, 0x8b), -+ LL(0x2c, 0x2c, 0xb0, 0x2c, 0x7d, 0x9c, 0x58, 0x51), -+ LL(0xd3, 0xd3, 0x6b, 0xd3, 0xd6, 0xb8, 0xbb, 0x05), -+ LL(0xe7, 0xe7, 0xbb, 0xe7, 0x6b, 0x5c, 0xd3, 0x8c), -+ LL(0x6e, 0x6e, 0xa5, 0x6e, 0x57, 0xcb, 0xdc, 0x39), -+ LL(0xc4, 0xc4, 0x37, 0xc4, 0x6e, 0xf3, 0x95, 0xaa), -+ LL(0x03, 0x03, 0x0c, 0x03, 0x18, 0x0f, 0x06, 0x1b), -+ LL(0x56, 0x56, 0x45, 0x56, 0x8a, 0x13, 0xac, 0xdc), -+ LL(0x44, 0x44, 0x0d, 0x44, 0x1a, 0x49, 0x88, 0x5e), -+ LL(0x7f, 0x7f, 0xe1, 0x7f, 0xdf, 0x9e, 0xfe, 0xa0), -+ LL(0xa9, 0xa9, 0x9e, 0xa9, 0x21, 0x37, 0x4f, 0x88), -+ LL(0x2a, 0x2a, 0xa8, 0x2a, 0x4d, 0x82, 0x54, 0x67), -+ LL(0xbb, 0xbb, 0xd6, 0xbb, 0xb1, 0x6d, 0x6b, 0x0a), -+ LL(0xc1, 0xc1, 0x23, 0xc1, 0x46, 0xe2, 0x9f, 0x87), -+ LL(0x53, 0x53, 0x51, 0x53, 0xa2, 0x02, 0xa6, 0xf1), -+ LL(0xdc, 0xdc, 0x57, 0xdc, 0xae, 0x8b, 0xa5, 0x72), -+ LL(0x0b, 0x0b, 0x2c, 0x0b, 0x58, 0x27, 0x16, 0x53), -+ LL(0x9d, 0x9d, 0x4e, 0x9d, 0x9c, 0xd3, 0x27, 0x01), -+ LL(0x6c, 0x6c, 0xad, 0x6c, 0x47, 0xc1, 0xd8, 0x2b), -+ LL(0x31, 0x31, 0xc4, 0x31, 0x95, 0xf5, 0x62, 0xa4), -+ LL(0x74, 0x74, 0xcd, 0x74, 0x87, 0xb9, 0xe8, 0xf3), -+ LL(0xf6, 0xf6, 0xff, 0xf6, 0xe3, 0x09, 0xf1, 0x15), -+ LL(0x46, 0x46, 0x05, 0x46, 0x0a, 0x43, 0x8c, 0x4c), -+ LL(0xac, 0xac, 0x8a, 0xac, 0x09, 0x26, 0x45, 0xa5), -+ LL(0x89, 0x89, 0x1e, 0x89, 0x3c, 0x97, 0x0f, 0xb5), -+ LL(0x14, 0x14, 0x50, 0x14, 0xa0, 0x44, 0x28, 0xb4), -+ LL(0xe1, 0xe1, 0xa3, 0xe1, 0x5b, 0x42, 0xdf, 0xba), -+ LL(0x16, 0x16, 0x58, 0x16, 0xb0, 0x4e, 0x2c, 0xa6), -+ LL(0x3a, 0x3a, 0xe8, 0x3a, 0xcd, 0xd2, 0x74, 0xf7), -+ LL(0x69, 0x69, 0xb9, 0x69, 0x6f, 0xd0, 0xd2, 0x06), -+ LL(0x09, 0x09, 0x24, 0x09, 0x48, 0x2d, 0x12, 0x41), -+ LL(0x70, 0x70, 0xdd, 0x70, 0xa7, 0xad, 0xe0, 0xd7), -+ LL(0xb6, 0xb6, 0xe2, 0xb6, 0xd9, 0x54, 0x71, 0x6f), -+ LL(0xd0, 0xd0, 0x67, 0xd0, 0xce, 0xb7, 0xbd, 0x1e), -+ LL(0xed, 0xed, 0x93, 0xed, 0x3b, 0x7e, 0xc7, 0xd6), -+ LL(0xcc, 0xcc, 0x17, 0xcc, 0x2e, 0xdb, 0x85, 0xe2), -+ LL(0x42, 0x42, 0x15, 0x42, 0x2a, 0x57, 0x84, 0x68), -+ LL(0x98, 0x98, 0x5a, 0x98, 0xb4, 0xc2, 0x2d, 0x2c), -+ LL(0xa4, 0xa4, 0xaa, 0xa4, 0x49, 0x0e, 0x55, 0xed), -+ LL(0x28, 0x28, 0xa0, 0x28, 0x5d, 0x88, 0x50, 0x75), -+ LL(0x5c, 0x5c, 0x6d, 0x5c, 0xda, 0x31, 0xb8, 0x86), -+ LL(0xf8, 0xf8, 0xc7, 0xf8, 0x93, 0x3f, 0xed, 0x6b), -+ LL(0x86, 0x86, 0x22, 0x86, 0x44, 0xa4, 0x11, 0xc2), -+#define RC (&(Cx.q[256*N])) -+ 0x18, 0x23, 0xc6, 0xe8, 0x87, 0xb8, 0x01, 0x4f, -+ /* rc[ROUNDS] */ -+ 0x36, 0xa6, 0xd2, 0xf5, 0x79, 0x6f, 0x91, 0x52, 0x60, 0xbc, 0x9b, -+ 0x8e, 0xa3, 0x0c, 0x7b, 0x35, 0x1d, 0xe0, 0xd7, 0xc2, 0x2e, 0x4b, -+ 0xfe, 0x57, 0x15, 0x77, 0x37, 0xe5, 0x9f, 0xf0, 0x4a, 0xda, 0x58, -+ 0xc9, 0x29, 0x0a, 0xb1, 0xa0, 0x6b, 0x85, 0xbd, 0x5d, 0x10, 0xf4, -+ 0xcb, 0x3e, 0x05, 0x67, 0xe4, 0x27, 0x41, 0x8b, 0xa7, 0x7d, 0x95, -+ 0xd8, 0xfb, 0xee, 0x7c, 0x66, 0xdd, 0x17, 0x47, 0x9e, 0xca, 0x2d, -+ 0xbf, 0x07, 0xad, 0x5a, 0x83, 0x33 -+ } -+ }; -+ -+void whirlpool_block(WHIRLPOOL_CTX *ctx, const void *inp, size_t n) -+{ -+ int r; -+ const u8 *p = inp; -+ union { -+ u64 q[8]; -+ u8 c[64]; -+ } S, K, *H = (void *)ctx->H.q; -+ -+#ifdef GO_FOR_MMX -+ GO_FOR_MMX(ctx, inp, n); -+#endif -+ do { -+#ifdef OPENSSL_SMALL_FOOTPRINT -+ u64 L[8]; -+ int i; -+ -+ for (i = 0; i < 64; i++) -+ S.c[i] = (K.c[i] = H->c[i]) ^ p[i]; -+ for (r = 0; r < ROUNDS; r++) { -+ for (i = 0; i < 8; i++) { -+ L[i] = i ? 0 : RC[r]; -+ L[i] ^= C0(K, i) ^ C1(K, (i - 1) & 7) ^ -+ C2(K, (i - 2) & 7) ^ C3(K, (i - 3) & 7) ^ -+ C4(K, (i - 4) & 7) ^ C5(K, (i - 5) & 7) ^ -+ C6(K, (i - 6) & 7) ^ C7(K, (i - 7) & 7); -+ } -+ memcpy(K.q, L, 64); -+ for (i = 0; i < 8; i++) { -+ L[i] ^= C0(S, i) ^ C1(S, (i - 1) & 7) ^ -+ C2(S, (i - 2) & 7) ^ C3(S, (i - 3) & 7) ^ -+ C4(S, (i - 4) & 7) ^ C5(S, (i - 5) & 7) ^ -+ C6(S, (i - 6) & 7) ^ C7(S, (i - 7) & 7); -+ } -+ memcpy(S.q, L, 64); -+ } -+ for (i = 0; i < 64; i++) -+ H->c[i] ^= S.c[i] ^ p[i]; -+#else -+ u64 L0, L1, L2, L3, L4, L5, L6, L7; -+ -+# ifdef STRICT_ALIGNMENT -+ if ((size_t)p & 7) { -+ memcpy(S.c, p, 64); -+ S.q[0] ^= (K.q[0] = H->q[0]); -+ S.q[1] ^= (K.q[1] = H->q[1]); -+ S.q[2] ^= (K.q[2] = H->q[2]); -+ S.q[3] ^= (K.q[3] = H->q[3]); -+ S.q[4] ^= (K.q[4] = H->q[4]); -+ S.q[5] ^= (K.q[5] = H->q[5]); -+ S.q[6] ^= (K.q[6] = H->q[6]); -+ S.q[7] ^= (K.q[7] = H->q[7]); -+ } else -+# endif -+ { -+ const u64 *pa = (const u64 *)p; -+ S.q[0] = (K.q[0] = H->q[0]) ^ pa[0]; -+ S.q[1] = (K.q[1] = H->q[1]) ^ pa[1]; -+ S.q[2] = (K.q[2] = H->q[2]) ^ pa[2]; -+ S.q[3] = (K.q[3] = H->q[3]) ^ pa[3]; -+ S.q[4] = (K.q[4] = H->q[4]) ^ pa[4]; -+ S.q[5] = (K.q[5] = H->q[5]) ^ pa[5]; -+ S.q[6] = (K.q[6] = H->q[6]) ^ pa[6]; -+ S.q[7] = (K.q[7] = H->q[7]) ^ pa[7]; -+ } -+ -+ for (r = 0; r < ROUNDS; r++) { -+# ifdef SMALL_REGISTER_BANK -+ L0 = C0(K, 0) ^ C1(K, 7) ^ C2(K, 6) ^ C3(K, 5) ^ -+ C4(K, 4) ^ C5(K, 3) ^ C6(K, 2) ^ C7(K, 1) ^ RC[r]; -+ L1 = C0(K, 1) ^ C1(K, 0) ^ C2(K, 7) ^ C3(K, 6) ^ -+ C4(K, 5) ^ C5(K, 4) ^ C6(K, 3) ^ C7(K, 2); -+ L2 = C0(K, 2) ^ C1(K, 1) ^ C2(K, 0) ^ C3(K, 7) ^ -+ C4(K, 6) ^ C5(K, 5) ^ C6(K, 4) ^ C7(K, 3); -+ L3 = C0(K, 3) ^ C1(K, 2) ^ C2(K, 1) ^ C3(K, 0) ^ -+ C4(K, 7) ^ C5(K, 6) ^ C6(K, 5) ^ C7(K, 4); -+ L4 = C0(K, 4) ^ C1(K, 3) ^ C2(K, 2) ^ C3(K, 1) ^ -+ C4(K, 0) ^ C5(K, 7) ^ C6(K, 6) ^ C7(K, 5); -+ L5 = C0(K, 5) ^ C1(K, 4) ^ C2(K, 3) ^ C3(K, 2) ^ -+ C4(K, 1) ^ C5(K, 0) ^ C6(K, 7) ^ C7(K, 6); -+ L6 = C0(K, 6) ^ C1(K, 5) ^ C2(K, 4) ^ C3(K, 3) ^ -+ C4(K, 2) ^ C5(K, 1) ^ C6(K, 0) ^ C7(K, 7); -+ L7 = C0(K, 7) ^ C1(K, 6) ^ C2(K, 5) ^ C3(K, 4) ^ -+ C4(K, 3) ^ C5(K, 2) ^ C6(K, 1) ^ C7(K, 0); -+ -+ K.q[0] = L0; -+ K.q[1] = L1; -+ K.q[2] = L2; -+ K.q[3] = L3; -+ K.q[4] = L4; -+ K.q[5] = L5; -+ K.q[6] = L6; -+ K.q[7] = L7; -+ -+ L0 ^= C0(S, 0) ^ C1(S, 7) ^ C2(S, 6) ^ C3(S, 5) ^ -+ C4(S, 4) ^ C5(S, 3) ^ C6(S, 2) ^ C7(S, 1); -+ L1 ^= C0(S, 1) ^ C1(S, 0) ^ C2(S, 7) ^ C3(S, 6) ^ -+ C4(S, 5) ^ C5(S, 4) ^ C6(S, 3) ^ C7(S, 2); -+ L2 ^= C0(S, 2) ^ C1(S, 1) ^ C2(S, 0) ^ C3(S, 7) ^ -+ C4(S, 6) ^ C5(S, 5) ^ C6(S, 4) ^ C7(S, 3); -+ L3 ^= C0(S, 3) ^ C1(S, 2) ^ C2(S, 1) ^ C3(S, 0) ^ -+ C4(S, 7) ^ C5(S, 6) ^ C6(S, 5) ^ C7(S, 4); -+ L4 ^= C0(S, 4) ^ C1(S, 3) ^ C2(S, 2) ^ C3(S, 1) ^ -+ C4(S, 0) ^ C5(S, 7) ^ C6(S, 6) ^ C7(S, 5); -+ L5 ^= C0(S, 5) ^ C1(S, 4) ^ C2(S, 3) ^ C3(S, 2) ^ -+ C4(S, 1) ^ C5(S, 0) ^ C6(S, 7) ^ C7(S, 6); -+ L6 ^= C0(S, 6) ^ C1(S, 5) ^ C2(S, 4) ^ C3(S, 3) ^ -+ C4(S, 2) ^ C5(S, 1) ^ C6(S, 0) ^ C7(S, 7); -+ L7 ^= C0(S, 7) ^ C1(S, 6) ^ C2(S, 5) ^ C3(S, 4) ^ -+ C4(S, 3) ^ C5(S, 2) ^ C6(S, 1) ^ C7(S, 0); -+ -+ S.q[0] = L0; -+ S.q[1] = L1; -+ S.q[2] = L2; -+ S.q[3] = L3; -+ S.q[4] = L4; -+ S.q[5] = L5; -+ S.q[6] = L6; -+ S.q[7] = L7; -+# else -+ L0 = C0(K, 0); -+ L1 = C1(K, 0); -+ L2 = C2(K, 0); -+ L3 = C3(K, 0); -+ L4 = C4(K, 0); -+ L5 = C5(K, 0); -+ L6 = C6(K, 0); -+ L7 = C7(K, 0); -+ L0 ^= RC[r]; -+ -+ L1 ^= C0(K, 1); -+ L2 ^= C1(K, 1); -+ L3 ^= C2(K, 1); -+ L4 ^= C3(K, 1); -+ L5 ^= C4(K, 1); -+ L6 ^= C5(K, 1); -+ L7 ^= C6(K, 1); -+ L0 ^= C7(K, 1); -+ -+ L2 ^= C0(K, 2); -+ L3 ^= C1(K, 2); -+ L4 ^= C2(K, 2); -+ L5 ^= C3(K, 2); -+ L6 ^= C4(K, 2); -+ L7 ^= C5(K, 2); -+ L0 ^= C6(K, 2); -+ L1 ^= C7(K, 2); -+ -+ L3 ^= C0(K, 3); -+ L4 ^= C1(K, 3); -+ L5 ^= C2(K, 3); -+ L6 ^= C3(K, 3); -+ L7 ^= C4(K, 3); -+ L0 ^= C5(K, 3); -+ L1 ^= C6(K, 3); -+ L2 ^= C7(K, 3); -+ -+ L4 ^= C0(K, 4); -+ L5 ^= C1(K, 4); -+ L6 ^= C2(K, 4); -+ L7 ^= C3(K, 4); -+ L0 ^= C4(K, 4); -+ L1 ^= C5(K, 4); -+ L2 ^= C6(K, 4); -+ L3 ^= C7(K, 4); -+ -+ L5 ^= C0(K, 5); -+ L6 ^= C1(K, 5); -+ L7 ^= C2(K, 5); -+ L0 ^= C3(K, 5); -+ L1 ^= C4(K, 5); -+ L2 ^= C5(K, 5); -+ L3 ^= C6(K, 5); -+ L4 ^= C7(K, 5); -+ -+ L6 ^= C0(K, 6); -+ L7 ^= C1(K, 6); -+ L0 ^= C2(K, 6); -+ L1 ^= C3(K, 6); -+ L2 ^= C4(K, 6); -+ L3 ^= C5(K, 6); -+ L4 ^= C6(K, 6); -+ L5 ^= C7(K, 6); -+ -+ L7 ^= C0(K, 7); -+ L0 ^= C1(K, 7); -+ L1 ^= C2(K, 7); -+ L2 ^= C3(K, 7); -+ L3 ^= C4(K, 7); -+ L4 ^= C5(K, 7); -+ L5 ^= C6(K, 7); -+ L6 ^= C7(K, 7); -+ -+ K.q[0] = L0; -+ K.q[1] = L1; -+ K.q[2] = L2; -+ K.q[3] = L3; -+ K.q[4] = L4; -+ K.q[5] = L5; -+ K.q[6] = L6; -+ K.q[7] = L7; -+ -+ L0 ^= C0(S, 0); -+ L1 ^= C1(S, 0); -+ L2 ^= C2(S, 0); -+ L3 ^= C3(S, 0); -+ L4 ^= C4(S, 0); -+ L5 ^= C5(S, 0); -+ L6 ^= C6(S, 0); -+ L7 ^= C7(S, 0); -+ -+ L1 ^= C0(S, 1); -+ L2 ^= C1(S, 1); -+ L3 ^= C2(S, 1); -+ L4 ^= C3(S, 1); -+ L5 ^= C4(S, 1); -+ L6 ^= C5(S, 1); -+ L7 ^= C6(S, 1); -+ L0 ^= C7(S, 1); -+ -+ L2 ^= C0(S, 2); -+ L3 ^= C1(S, 2); -+ L4 ^= C2(S, 2); -+ L5 ^= C3(S, 2); -+ L6 ^= C4(S, 2); -+ L7 ^= C5(S, 2); -+ L0 ^= C6(S, 2); -+ L1 ^= C7(S, 2); -+ -+ L3 ^= C0(S, 3); -+ L4 ^= C1(S, 3); -+ L5 ^= C2(S, 3); -+ L6 ^= C3(S, 3); -+ L7 ^= C4(S, 3); -+ L0 ^= C5(S, 3); -+ L1 ^= C6(S, 3); -+ L2 ^= C7(S, 3); -+ -+ L4 ^= C0(S, 4); -+ L5 ^= C1(S, 4); -+ L6 ^= C2(S, 4); -+ L7 ^= C3(S, 4); -+ L0 ^= C4(S, 4); -+ L1 ^= C5(S, 4); -+ L2 ^= C6(S, 4); -+ L3 ^= C7(S, 4); -+ -+ L5 ^= C0(S, 5); -+ L6 ^= C1(S, 5); -+ L7 ^= C2(S, 5); -+ L0 ^= C3(S, 5); -+ L1 ^= C4(S, 5); -+ L2 ^= C5(S, 5); -+ L3 ^= C6(S, 5); -+ L4 ^= C7(S, 5); -+ -+ L6 ^= C0(S, 6); -+ L7 ^= C1(S, 6); -+ L0 ^= C2(S, 6); -+ L1 ^= C3(S, 6); -+ L2 ^= C4(S, 6); -+ L3 ^= C5(S, 6); -+ L4 ^= C6(S, 6); -+ L5 ^= C7(S, 6); -+ -+ L7 ^= C0(S, 7); -+ L0 ^= C1(S, 7); -+ L1 ^= C2(S, 7); -+ L2 ^= C3(S, 7); -+ L3 ^= C4(S, 7); -+ L4 ^= C5(S, 7); -+ L5 ^= C6(S, 7); -+ L6 ^= C7(S, 7); -+ -+ S.q[0] = L0; -+ S.q[1] = L1; -+ S.q[2] = L2; -+ S.q[3] = L3; -+ S.q[4] = L4; -+ S.q[5] = L5; -+ S.q[6] = L6; -+ S.q[7] = L7; -+# endif -+ } -+ -+# ifdef STRICT_ALIGNMENT -+ if ((size_t)p & 7) { -+ int i; -+ for (i = 0; i < 64; i++) -+ H->c[i] ^= S.c[i] ^ p[i]; -+ } else -+# endif -+ { -+ const u64 *pa = (const u64 *)p; -+ H->q[0] ^= S.q[0] ^ pa[0]; -+ H->q[1] ^= S.q[1] ^ pa[1]; -+ H->q[2] ^= S.q[2] ^ pa[2]; -+ H->q[3] ^= S.q[3] ^ pa[3]; -+ H->q[4] ^= S.q[4] ^ pa[4]; -+ H->q[5] ^= S.q[5] ^ pa[5]; -+ H->q[6] ^= S.q[6] ^ pa[6]; -+ H->q[7] ^= S.q[7] ^ pa[7]; -+ } -+#endif -+ p += 64; -+ } while (--n); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_dgst.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_dgst.c -new file mode 100644 -index 0000000..ed06424 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_dgst.c -@@ -0,0 +1,266 @@ -+/* -+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/** -+ * The Whirlpool hashing function. -+ * -+ *

-+ * References -+ * -+ *

-+ * The Whirlpool algorithm was developed by -+ * Paulo S. L. M. Barreto and -+ * Vincent Rijmen. -+ * -+ * See -+ * P.S.L.M. Barreto, V. Rijmen, -+ * ``The Whirlpool hashing function,'' -+ * NESSIE submission, 2000 (tweaked version, 2001), -+ * -+ * -+ * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and -+ * Vincent Rijmen. Lookup "reference implementations" on -+ * -+ * -+ * ============================================================================= -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS -+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ */ -+ -+/* -+ * OpenSSL-specific implementation notes. -+ * -+ * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect -+ * number of *bytes* as input length argument. Bit-oriented routine -+ * as specified by authors is called WHIRLPOOL_BitUpdate[!] and -+ * does not have one-stroke counterpart. -+ * -+ * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially -+ * to serve WHIRLPOOL_Update. This is done for performance. -+ * -+ * Unlike authors' reference implementation, block processing -+ * routine whirlpool_block is designed to operate on multi-block -+ * input. This is done for performance. -+ */ -+ -+#include -+#include "wp_locl.h" -+#include -+ -+int WHIRLPOOL_Init(WHIRLPOOL_CTX *c) -+{ -+ memset(c, 0, sizeof(*c)); -+ return (1); -+} -+ -+int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *_inp, size_t bytes) -+{ -+ /* -+ * Well, largest suitable chunk size actually is -+ * (1<<(sizeof(size_t)*8-3))-64, but below number is large enough for not -+ * to care about excessive calls to WHIRLPOOL_BitUpdate... -+ */ -+ size_t chunk = ((size_t)1) << (sizeof(size_t) * 8 - 4); -+ const unsigned char *inp = _inp; -+ -+ while (bytes >= chunk) { -+ WHIRLPOOL_BitUpdate(c, inp, chunk * 8); -+ bytes -= chunk; -+ inp += chunk; -+ } -+ if (bytes) -+ WHIRLPOOL_BitUpdate(c, inp, bytes * 8); -+ -+ return (1); -+} -+ -+void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) -+{ -+ size_t n; -+ unsigned int bitoff = c->bitoff, -+ bitrem = bitoff % 8, inpgap = (8 - (unsigned int)bits % 8) & 7; -+ const unsigned char *inp = _inp; -+ -+ /* -+ * This 256-bit increment procedure relies on the size_t being natural -+ * size of CPU register, so that we don't have to mask the value in order -+ * to detect overflows. -+ */ -+ c->bitlen[0] += bits; -+ if (c->bitlen[0] < bits) { /* overflow */ -+ n = 1; -+ do { -+ c->bitlen[n]++; -+ } while (c->bitlen[n] == 0 -+ && ++n < (WHIRLPOOL_COUNTER / sizeof(size_t))); -+ } -+#ifndef OPENSSL_SMALL_FOOTPRINT -+ reconsider: -+ if (inpgap == 0 && bitrem == 0) { /* byte-oriented loop */ -+ while (bits) { -+ if (bitoff == 0 && (n = bits / WHIRLPOOL_BBLOCK)) { -+ whirlpool_block(c, inp, n); -+ inp += n * WHIRLPOOL_BBLOCK / 8; -+ bits %= WHIRLPOOL_BBLOCK; -+ } else { -+ unsigned int byteoff = bitoff / 8; -+ -+ bitrem = WHIRLPOOL_BBLOCK - bitoff; /* re-use bitrem */ -+ if (bits >= bitrem) { -+ bits -= bitrem; -+ bitrem /= 8; -+ memcpy(c->data + byteoff, inp, bitrem); -+ inp += bitrem; -+ whirlpool_block(c, c->data, 1); -+ bitoff = 0; -+ } else { -+ memcpy(c->data + byteoff, inp, bits / 8); -+ bitoff += (unsigned int)bits; -+ bits = 0; -+ } -+ c->bitoff = bitoff; -+ } -+ } -+ } else /* bit-oriented loop */ -+#endif -+ { -+ /*- -+ inp -+ | -+ +-------+-------+------- -+ ||||||||||||||||||||| -+ +-------+-------+------- -+ +-------+-------+-------+-------+------- -+ |||||||||||||| c->data -+ +-------+-------+-------+-------+------- -+ | -+ c->bitoff/8 -+ */ -+ while (bits) { -+ unsigned int byteoff = bitoff / 8; -+ unsigned char b; -+ -+#ifndef OPENSSL_SMALL_FOOTPRINT -+ if (bitrem == inpgap) { -+ c->data[byteoff++] |= inp[0] & (0xff >> inpgap); -+ inpgap = 8 - inpgap; -+ bitoff += inpgap; -+ bitrem = 0; /* bitoff%8 */ -+ bits -= inpgap; -+ inpgap = 0; /* bits%8 */ -+ inp++; -+ if (bitoff == WHIRLPOOL_BBLOCK) { -+ whirlpool_block(c, c->data, 1); -+ bitoff = 0; -+ } -+ c->bitoff = bitoff; -+ goto reconsider; -+ } else -+#endif -+ if (bits >= 8) { -+ b = ((inp[0] << inpgap) | (inp[1] >> (8 - inpgap))); -+ b &= 0xff; -+ if (bitrem) -+ c->data[byteoff++] |= b >> bitrem; -+ else -+ c->data[byteoff++] = b; -+ bitoff += 8; -+ bits -= 8; -+ inp++; -+ if (bitoff >= WHIRLPOOL_BBLOCK) { -+ whirlpool_block(c, c->data, 1); -+ byteoff = 0; -+ bitoff %= WHIRLPOOL_BBLOCK; -+ } -+ if (bitrem) -+ c->data[byteoff] = b << (8 - bitrem); -+ } else { /* remaining less than 8 bits */ -+ -+ b = (inp[0] << inpgap) & 0xff; -+ if (bitrem) -+ c->data[byteoff++] |= b >> bitrem; -+ else -+ c->data[byteoff++] = b; -+ bitoff += (unsigned int)bits; -+ if (bitoff == WHIRLPOOL_BBLOCK) { -+ whirlpool_block(c, c->data, 1); -+ byteoff = 0; -+ bitoff %= WHIRLPOOL_BBLOCK; -+ } -+ if (bitrem) -+ c->data[byteoff] = b << (8 - bitrem); -+ bits = 0; -+ } -+ c->bitoff = bitoff; -+ } -+ } -+} -+ -+int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c) -+{ -+ unsigned int bitoff = c->bitoff, byteoff = bitoff / 8; -+ size_t i, j, v; -+ unsigned char *p; -+ -+ bitoff %= 8; -+ if (bitoff) -+ c->data[byteoff] |= 0x80 >> bitoff; -+ else -+ c->data[byteoff] = 0x80; -+ byteoff++; -+ -+ /* pad with zeros */ -+ if (byteoff > (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) { -+ if (byteoff < WHIRLPOOL_BBLOCK / 8) -+ memset(&c->data[byteoff], 0, WHIRLPOOL_BBLOCK / 8 - byteoff); -+ whirlpool_block(c, c->data, 1); -+ byteoff = 0; -+ } -+ if (byteoff < (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) -+ memset(&c->data[byteoff], 0, -+ (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER) - byteoff); -+ /* smash 256-bit c->bitlen in big-endian order */ -+ p = &c->data[WHIRLPOOL_BBLOCK / 8 - 1]; /* last byte in c->data */ -+ for (i = 0; i < WHIRLPOOL_COUNTER / sizeof(size_t); i++) -+ for (v = c->bitlen[i], j = 0; j < sizeof(size_t); j++, v >>= 8) -+ *p-- = (unsigned char)(v & 0xff); -+ -+ whirlpool_block(c, c->data, 1); -+ -+ if (md) { -+ memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH); -+ OPENSSL_cleanse(c, sizeof(*c)); -+ return (1); -+ } -+ return (0); -+} -+ -+unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md) -+{ -+ WHIRLPOOL_CTX ctx; -+ static unsigned char m[WHIRLPOOL_DIGEST_LENGTH]; -+ -+ if (md == NULL) -+ md = m; -+ WHIRLPOOL_Init(&ctx); -+ WHIRLPOOL_Update(&ctx, inp, bytes); -+ WHIRLPOOL_Final(md, &ctx); -+ return (md); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_locl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_locl.h -new file mode 100644 -index 0000000..3a81cfd ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/whrlpool/wp_locl.h -@@ -0,0 +1,12 @@ -+/* -+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+ -+void whirlpool_block(WHIRLPOOL_CTX *, const void *, size_t); -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/build.info -new file mode 100644 -index 0000000..7fc4b45 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/build.info -@@ -0,0 +1,10 @@ -+LIBS=../../libcrypto -+SOURCE[../../libcrypto]=\ -+ x509_def.c x509_d2.c x509_r2x.c x509_cmp.c \ -+ x509_obj.c x509_req.c x509spki.c x509_vfy.c \ -+ x509_set.c x509cset.c x509rset.c x509_err.c \ -+ x509name.c x509_v3.c x509_ext.c x509_att.c \ -+ x509type.c x509_lu.c x_all.c x509_txt.c \ -+ x509_trs.c by_file.c by_dir.c x509_vpm.c \ -+ x_crl.c t_crl.c x_req.c t_req.c x_x509.c t_x509.c \ -+ x_pubkey.c x_x509a.c x_attrib.c x_exten.c x_name.c -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/by_dir.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/by_dir.c -new file mode 100644 -index 0000000..f3a1f05 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/by_dir.c -@@ -0,0 +1,388 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+ -+#include "internal/cryptlib.h" -+ -+#ifndef NO_SYS_TYPES_H -+# include -+#endif -+#ifndef OPENSSL_NO_POSIX_IO -+# include -+#endif -+ -+ -+#include -+#include -+#include "internal/x509_int.h" -+#include "x509_lcl.h" -+ -+struct lookup_dir_hashes_st { -+ unsigned long hash; -+ int suffix; -+}; -+ -+struct lookup_dir_entry_st { -+ char *dir; -+ int dir_type; -+ STACK_OF(BY_DIR_HASH) *hashes; -+}; -+ -+typedef struct lookup_dir_st { -+ BUF_MEM *buffer; -+ STACK_OF(BY_DIR_ENTRY) *dirs; -+ CRYPTO_RWLOCK *lock; -+} BY_DIR; -+ -+static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, -+ char **ret); -+static int new_dir(X509_LOOKUP *lu); -+static void free_dir(X509_LOOKUP *lu); -+static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); -+static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, -+ X509_NAME *name, X509_OBJECT *ret); -+static X509_LOOKUP_METHOD x509_dir_lookup = { -+ "Load certs from files in a directory", -+ new_dir, /* new */ -+ free_dir, /* free */ -+ NULL, /* init */ -+ NULL, /* shutdown */ -+ dir_ctrl, /* ctrl */ -+ get_cert_by_subject, /* get_by_subject */ -+ NULL, /* get_by_issuer_serial */ -+ NULL, /* get_by_fingerprint */ -+ NULL, /* get_by_alias */ -+}; -+ -+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) -+{ -+ return (&x509_dir_lookup); -+} -+ -+static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, -+ char **retp) -+{ -+ int ret = 0; -+ BY_DIR *ld; -+ char *dir = NULL; -+ -+ ld = (BY_DIR *)ctx->method_data; -+ -+ switch (cmd) { -+ case X509_L_ADD_DIR: -+ if (argl == X509_FILETYPE_DEFAULT) { -+ dir = (char *)getenv(X509_get_default_cert_dir_env()); -+ if (dir) -+ ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); -+ else -+ ret = add_cert_dir(ld, X509_get_default_cert_dir(), -+ X509_FILETYPE_PEM); -+ if (!ret) { -+ X509err(X509_F_DIR_CTRL, X509_R_LOADING_CERT_DIR); -+ } -+ } else -+ ret = add_cert_dir(ld, argp, (int)argl); -+ break; -+ } -+ return (ret); -+} -+ -+static int new_dir(X509_LOOKUP *lu) -+{ -+ BY_DIR *a; -+ -+ if ((a = OPENSSL_malloc(sizeof(*a))) == NULL) -+ return 0; -+ if ((a->buffer = BUF_MEM_new()) == NULL) { -+ OPENSSL_free(a); -+ return 0; -+ } -+ a->dirs = NULL; -+ a->lock = CRYPTO_THREAD_lock_new(); -+ if (a->lock == NULL) { -+ BUF_MEM_free(a->buffer); -+ OPENSSL_free(a); -+ return 0; -+ } -+ lu->method_data = (char *)a; -+ return 1; -+} -+ -+static void by_dir_hash_free(BY_DIR_HASH *hash) -+{ -+ OPENSSL_free(hash); -+} -+ -+static int by_dir_hash_cmp(const BY_DIR_HASH *const *a, -+ const BY_DIR_HASH *const *b) -+{ -+ if ((*a)->hash > (*b)->hash) -+ return 1; -+ if ((*a)->hash < (*b)->hash) -+ return -1; -+ return 0; -+} -+ -+static void by_dir_entry_free(BY_DIR_ENTRY *ent) -+{ -+ OPENSSL_free(ent->dir); -+ sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); -+ OPENSSL_free(ent); -+} -+ -+static void free_dir(X509_LOOKUP *lu) -+{ -+ BY_DIR *a; -+ -+ a = (BY_DIR *)lu->method_data; -+ sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); -+ BUF_MEM_free(a->buffer); -+ CRYPTO_THREAD_lock_free(a->lock); -+ OPENSSL_free(a); -+} -+ -+static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) -+{ -+ const char *s, *p; -+ -+ if (dir == NULL || !*dir) { -+ X509err(X509_F_ADD_CERT_DIR, X509_R_INVALID_DIRECTORY); -+ return 0; -+ } -+ -+ s = dir; -+ p = s; -+ do { -+ if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) { -+ BY_DIR_ENTRY *ent; -+ int j; -+ size_t len; -+ const char *ss = s; -+ s = p + 1; -+ len = p - ss; -+ if (len == 0) -+ continue; -+ for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) { -+ ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); -+ if (strlen(ent->dir) == len && -+ strncmp(ent->dir, ss, len) == 0) -+ break; -+ } -+ if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) -+ continue; -+ if (ctx->dirs == NULL) { -+ ctx->dirs = sk_BY_DIR_ENTRY_new_null(); -+ if (!ctx->dirs) { -+ X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ } -+ ent = OPENSSL_malloc(sizeof(*ent)); -+ if (ent == NULL) -+ return 0; -+ ent->dir_type = type; -+ ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); -+ ent->dir = OPENSSL_strndup(ss, len); -+ if (ent->dir == NULL || ent->hashes == NULL) { -+ by_dir_entry_free(ent); -+ return 0; -+ } -+ if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { -+ by_dir_entry_free(ent); -+ return 0; -+ } -+ } -+ } while (*p++ != '\0'); -+ return 1; -+} -+ -+static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, -+ X509_NAME *name, X509_OBJECT *ret) -+{ -+ BY_DIR *ctx; -+ union { -+ X509 st_x509; -+ X509_CRL crl; -+ } data; -+ int ok = 0; -+ int i, j, k; -+ unsigned long h; -+ BUF_MEM *b = NULL; -+ X509_OBJECT stmp, *tmp; -+ const char *postfix = ""; -+ -+ if (name == NULL) -+ return (0); -+ -+ stmp.type = type; -+ if (type == X509_LU_X509) { -+ data.st_x509.cert_info.subject = name; -+ stmp.data.x509 = &data.st_x509; -+ postfix = ""; -+ } else if (type == X509_LU_CRL) { -+ data.crl.crl.issuer = name; -+ stmp.data.crl = &data.crl; -+ postfix = "r"; -+ } else { -+ X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE); -+ goto finish; -+ } -+ -+ if ((b = BUF_MEM_new()) == NULL) { -+ X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_BUF_LIB); -+ goto finish; -+ } -+ -+ ctx = (BY_DIR *)xl->method_data; -+ -+ h = X509_NAME_hash(name); -+ for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { -+ BY_DIR_ENTRY *ent; -+ int idx; -+ BY_DIR_HASH htmp, *hent; -+ ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); -+ j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; -+ if (!BUF_MEM_grow(b, j)) { -+ X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); -+ goto finish; -+ } -+ if (type == X509_LU_CRL && ent->hashes) { -+ htmp.hash = h; -+ CRYPTO_THREAD_read_lock(ctx->lock); -+ idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); -+ if (idx >= 0) { -+ hent = sk_BY_DIR_HASH_value(ent->hashes, idx); -+ k = hent->suffix; -+ } else { -+ hent = NULL; -+ k = 0; -+ } -+ CRYPTO_THREAD_unlock(ctx->lock); -+ } else { -+ k = 0; -+ hent = NULL; -+ } -+ for (;;) { -+ char c = '/'; -+#ifdef OPENSSL_SYS_VMS -+ c = ent->dir[strlen(ent->dir) - 1]; -+ if (c != ':' && c != '>' && c != ']') { -+ /* -+ * If no separator is present, we assume the directory -+ * specifier is a logical name, and add a colon. We really -+ * should use better VMS routines for merging things like -+ * this, but this will do for now... -- Richard Levitte -+ */ -+ c = ':'; -+ } else { -+ c = '\0'; -+ } -+#endif -+ if (c == '\0') { -+ /* -+ * This is special. When c == '\0', no directory separator -+ * should be added. -+ */ -+ BIO_snprintf(b->data, b->max, -+ "%s%08lx.%s%d", ent->dir, h, postfix, k); -+ } else { -+ BIO_snprintf(b->data, b->max, -+ "%s%c%08lx.%s%d", ent->dir, c, h, postfix, k); -+ } -+#ifndef OPENSSL_NO_POSIX_IO -+# ifdef _WIN32 -+# define stat _stat -+# endif -+ { -+ struct stat st; -+ if (stat(b->data, &st) < 0) -+ break; -+ } -+#endif -+ /* found one. */ -+ if (type == X509_LU_X509) { -+ if ((X509_load_cert_file(xl, b->data, ent->dir_type)) == 0) -+ break; -+ } else if (type == X509_LU_CRL) { -+ if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) -+ break; -+ } -+ /* else case will caught higher up */ -+ k++; -+ } -+ -+ /* -+ * we have added it to the cache so now pull it out again -+ */ -+ CRYPTO_THREAD_write_lock(ctx->lock); -+ j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp); -+ if (j != -1) -+ tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j); -+ else -+ tmp = NULL; -+ CRYPTO_THREAD_unlock(ctx->lock); -+ -+ /* If a CRL, update the last file suffix added for this */ -+ -+ if (type == X509_LU_CRL) { -+ CRYPTO_THREAD_write_lock(ctx->lock); -+ /* -+ * Look for entry again in case another thread added an entry -+ * first. -+ */ -+ if (!hent) { -+ htmp.hash = h; -+ idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); -+ if (idx >= 0) -+ hent = sk_BY_DIR_HASH_value(ent->hashes, idx); -+ } -+ if (!hent) { -+ hent = OPENSSL_malloc(sizeof(*hent)); -+ if (hent == NULL) { -+ CRYPTO_THREAD_unlock(ctx->lock); -+ X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); -+ ok = 0; -+ goto finish; -+ } -+ hent->hash = h; -+ hent->suffix = k; -+ if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { -+ CRYPTO_THREAD_unlock(ctx->lock); -+ OPENSSL_free(hent); -+ ok = 0; -+ goto finish; -+ } -+ } else if (hent->suffix < k) { -+ hent->suffix = k; -+ } -+ -+ CRYPTO_THREAD_unlock(ctx->lock); -+ -+ } -+ -+ if (tmp != NULL) { -+ ok = 1; -+ ret->type = tmp->type; -+ memcpy(&ret->data, &tmp->data, sizeof(ret->data)); -+ /* -+ * If we were going to up the reference count, we would need to -+ * do it on a perl 'type' basis -+ */ -+ /*- CRYPTO_add(&tmp->data.x509->references,1, -+ CRYPTO_LOCK_X509);*/ -+ goto finish; -+ } -+ } -+ finish: -+ BUF_MEM_free(b); -+ return (ok); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/by_file.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/by_file.c -new file mode 100644 -index 0000000..4376bed ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/by_file.c -@@ -0,0 +1,221 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+ -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "x509_lcl.h" -+ -+static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, -+ long argl, char **ret); -+static X509_LOOKUP_METHOD x509_file_lookup = { -+ "Load file into cache", -+ NULL, /* new */ -+ NULL, /* free */ -+ NULL, /* init */ -+ NULL, /* shutdown */ -+ by_file_ctrl, /* ctrl */ -+ NULL, /* get_by_subject */ -+ NULL, /* get_by_issuer_serial */ -+ NULL, /* get_by_fingerprint */ -+ NULL, /* get_by_alias */ -+}; -+ -+X509_LOOKUP_METHOD *X509_LOOKUP_file(void) -+{ -+ return (&x509_file_lookup); -+} -+ -+static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, -+ long argl, char **ret) -+{ -+ int ok = 0; -+ char *file; -+ -+ switch (cmd) { -+ case X509_L_FILE_LOAD: -+ if (argl == X509_FILETYPE_DEFAULT) { -+ file = (char *)getenv(X509_get_default_cert_file_env()); -+ if (file) -+ ok = (X509_load_cert_crl_file(ctx, file, -+ X509_FILETYPE_PEM) != 0); -+ -+ else -+ ok = (X509_load_cert_crl_file -+ (ctx, X509_get_default_cert_file(), -+ X509_FILETYPE_PEM) != 0); -+ -+ if (!ok) { -+ X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS); -+ } -+ } else { -+ if (argl == X509_FILETYPE_PEM) -+ ok = (X509_load_cert_crl_file(ctx, argp, -+ X509_FILETYPE_PEM) != 0); -+ else -+ ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); -+ } -+ break; -+ } -+ return (ok); -+} -+ -+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) -+{ -+ int ret = 0; -+ BIO *in = NULL; -+ int i, count = 0; -+ X509 *x = NULL; -+ -+ if (file == NULL) -+ return (1); -+ in = BIO_new(BIO_s_file()); -+ -+ if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { -+ X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); -+ goto err; -+ } -+ -+ if (type == X509_FILETYPE_PEM) { -+ for (;;) { -+ x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); -+ if (x == NULL) { -+ if ((ERR_GET_REASON(ERR_peek_last_error()) == -+ PEM_R_NO_START_LINE) && (count > 0)) { -+ ERR_clear_error(); -+ break; -+ } else { -+ X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB); -+ goto err; -+ } -+ } -+ i = X509_STORE_add_cert(ctx->store_ctx, x); -+ if (!i) -+ goto err; -+ count++; -+ X509_free(x); -+ x = NULL; -+ } -+ ret = count; -+ } else if (type == X509_FILETYPE_ASN1) { -+ x = d2i_X509_bio(in, NULL); -+ if (x == NULL) { -+ X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ i = X509_STORE_add_cert(ctx->store_ctx, x); -+ if (!i) -+ goto err; -+ ret = i; -+ } else { -+ X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); -+ goto err; -+ } -+ err: -+ X509_free(x); -+ BIO_free(in); -+ return (ret); -+} -+ -+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) -+{ -+ int ret = 0; -+ BIO *in = NULL; -+ int i, count = 0; -+ X509_CRL *x = NULL; -+ -+ if (file == NULL) -+ return (1); -+ in = BIO_new(BIO_s_file()); -+ -+ if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { -+ X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB); -+ goto err; -+ } -+ -+ if (type == X509_FILETYPE_PEM) { -+ for (;;) { -+ x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); -+ if (x == NULL) { -+ if ((ERR_GET_REASON(ERR_peek_last_error()) == -+ PEM_R_NO_START_LINE) && (count > 0)) { -+ ERR_clear_error(); -+ break; -+ } else { -+ X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_PEM_LIB); -+ goto err; -+ } -+ } -+ i = X509_STORE_add_crl(ctx->store_ctx, x); -+ if (!i) -+ goto err; -+ count++; -+ X509_CRL_free(x); -+ x = NULL; -+ } -+ ret = count; -+ } else if (type == X509_FILETYPE_ASN1) { -+ x = d2i_X509_CRL_bio(in, NULL); -+ if (x == NULL) { -+ X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB); -+ goto err; -+ } -+ i = X509_STORE_add_crl(ctx->store_ctx, x); -+ if (!i) -+ goto err; -+ ret = i; -+ } else { -+ X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE); -+ goto err; -+ } -+ err: -+ X509_CRL_free(x); -+ BIO_free(in); -+ return (ret); -+} -+ -+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) -+{ -+ STACK_OF(X509_INFO) *inf; -+ X509_INFO *itmp; -+ BIO *in; -+ int i, count = 0; -+ if (type != X509_FILETYPE_PEM) -+ return X509_load_cert_file(ctx, file, type); -+ in = BIO_new_file(file, "r"); -+ if (!in) { -+ X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); -+ return 0; -+ } -+ inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); -+ BIO_free(in); -+ if (!inf) { -+ X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); -+ return 0; -+ } -+ for (i = 0; i < sk_X509_INFO_num(inf); i++) { -+ itmp = sk_X509_INFO_value(inf, i); -+ if (itmp->x509) { -+ X509_STORE_add_cert(ctx->store_ctx, itmp->x509); -+ count++; -+ } -+ if (itmp->crl) { -+ X509_STORE_add_crl(ctx->store_ctx, itmp->crl); -+ count++; -+ } -+ } -+ sk_X509_INFO_pop_free(inf, X509_INFO_free); -+ return count; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_crl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_crl.c -new file mode 100644 -index 0000000..f3ca6db ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_crl.c -@@ -0,0 +1,89 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef OPENSSL_NO_STDIO -+int X509_CRL_print_fp(FILE *fp, X509_CRL *x) -+{ -+ BIO *b; -+ int ret; -+ -+ if ((b = BIO_new(BIO_s_file())) == NULL) { -+ X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB); -+ return (0); -+ } -+ BIO_set_fp(b, fp, BIO_NOCLOSE); -+ ret = X509_CRL_print(b, x); -+ BIO_free(b); -+ return (ret); -+} -+#endif -+ -+int X509_CRL_print(BIO *out, X509_CRL *x) -+{ -+ STACK_OF(X509_REVOKED) *rev; -+ X509_REVOKED *r; -+ const X509_ALGOR *sig_alg; -+ const ASN1_BIT_STRING *sig; -+ long l; -+ int i; -+ char *p; -+ -+ BIO_printf(out, "Certificate Revocation List (CRL):\n"); -+ l = X509_CRL_get_version(x); -+ if (l >= 0 && l <= 1) -+ BIO_printf(out, "%8sVersion %ld (0x%lx)\n", "", l + 1, (unsigned long)l); -+ else -+ BIO_printf(out, "%8sVersion unknown (%ld)\n", "", l); -+ X509_CRL_get0_signature(x, &sig, &sig_alg); -+ X509_signature_print(out, sig_alg, NULL); -+ p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0); -+ BIO_printf(out, "%8sIssuer: %s\n", "", p); -+ OPENSSL_free(p); -+ BIO_printf(out, "%8sLast Update: ", ""); -+ ASN1_TIME_print(out, X509_CRL_get0_lastUpdate(x)); -+ BIO_printf(out, "\n%8sNext Update: ", ""); -+ if (X509_CRL_get0_nextUpdate(x)) -+ ASN1_TIME_print(out, X509_CRL_get0_nextUpdate(x)); -+ else -+ BIO_printf(out, "NONE"); -+ BIO_printf(out, "\n"); -+ -+ X509V3_extensions_print(out, "CRL extensions", -+ X509_CRL_get0_extensions(x), 0, 8); -+ -+ rev = X509_CRL_get_REVOKED(x); -+ -+ if (sk_X509_REVOKED_num(rev) > 0) -+ BIO_printf(out, "Revoked Certificates:\n"); -+ else -+ BIO_printf(out, "No Revoked Certificates.\n"); -+ -+ for (i = 0; i < sk_X509_REVOKED_num(rev); i++) { -+ r = sk_X509_REVOKED_value(rev, i); -+ BIO_printf(out, " Serial Number: "); -+ i2a_ASN1_INTEGER(out, X509_REVOKED_get0_serialNumber(r)); -+ BIO_printf(out, "\n Revocation Date: "); -+ ASN1_TIME_print(out, X509_REVOKED_get0_revocationDate(r)); -+ BIO_printf(out, "\n"); -+ X509V3_extensions_print(out, "CRL entry extensions", -+ X509_REVOKED_get0_extensions(r), 0, 8); -+ } -+ X509_signature_print(out, sig_alg, sig); -+ -+ return 1; -+ -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_req.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_req.c -new file mode 100644 -index 0000000..77ce810 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_req.c -@@ -0,0 +1,198 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef OPENSSL_NO_STDIO -+int X509_REQ_print_fp(FILE *fp, X509_REQ *x) -+{ -+ BIO *b; -+ int ret; -+ -+ if ((b = BIO_new(BIO_s_file())) == NULL) { -+ X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB); -+ return (0); -+ } -+ BIO_set_fp(b, fp, BIO_NOCLOSE); -+ ret = X509_REQ_print(b, x); -+ BIO_free(b); -+ return (ret); -+} -+#endif -+ -+int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, -+ unsigned long cflag) -+{ -+ long l; -+ int i; -+ EVP_PKEY *pkey; -+ STACK_OF(X509_EXTENSION) *exts; -+ char mlch = ' '; -+ int nmindent = 0; -+ -+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { -+ mlch = '\n'; -+ nmindent = 12; -+ } -+ -+ if (nmflags == X509_FLAG_COMPAT) -+ nmindent = 16; -+ -+ if (!(cflag & X509_FLAG_NO_HEADER)) { -+ if (BIO_write(bp, "Certificate Request:\n", 21) <= 0) -+ goto err; -+ if (BIO_write(bp, " Data:\n", 10) <= 0) -+ goto err; -+ } -+ if (!(cflag & X509_FLAG_NO_VERSION)) { -+ l = X509_REQ_get_version(x); -+ if (l >= 0 && l <= 2) { -+ if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0) -+ goto err; -+ } else { -+ if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 0) -+ goto err; -+ } -+ } -+ if (!(cflag & X509_FLAG_NO_SUBJECT)) { -+ if (BIO_printf(bp, " Subject:%c", mlch) <= 0) -+ goto err; -+ if (X509_NAME_print_ex(bp, X509_REQ_get_subject_name(x), -+ nmindent, nmflags) < 0) -+ goto err; -+ if (BIO_write(bp, "\n", 1) <= 0) -+ goto err; -+ } -+ if (!(cflag & X509_FLAG_NO_PUBKEY)) { -+ X509_PUBKEY *xpkey; -+ ASN1_OBJECT *koid; -+ if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) -+ goto err; -+ if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) -+ goto err; -+ xpkey = X509_REQ_get_X509_PUBKEY(x); -+ X509_PUBKEY_get0_param(&koid, NULL, NULL, NULL, xpkey); -+ if (i2a_ASN1_OBJECT(bp, koid) <= 0) -+ goto err; -+ if (BIO_puts(bp, "\n") <= 0) -+ goto err; -+ -+ pkey = X509_REQ_get0_pubkey(x); -+ if (pkey == NULL) { -+ BIO_printf(bp, "%12sUnable to load Public Key\n", ""); -+ ERR_print_errors(bp); -+ } else { -+ EVP_PKEY_print_public(bp, pkey, 16, NULL); -+ } -+ } -+ -+ if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) { -+ /* may not be */ -+ if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0) -+ goto err; -+ -+ if (X509_REQ_get_attr_count(x) == 0) { -+ if (BIO_printf(bp, "%12sa0:00\n", "") <= 0) -+ goto err; -+ } else { -+ for (i = 0; i < X509_REQ_get_attr_count(x); i++) { -+ ASN1_TYPE *at; -+ X509_ATTRIBUTE *a; -+ ASN1_BIT_STRING *bs = NULL; -+ ASN1_OBJECT *aobj; -+ int j, type = 0, count = 1, ii = 0; -+ -+ a = X509_REQ_get_attr(x, i); -+ aobj = X509_ATTRIBUTE_get0_object(a); -+ if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) -+ continue; -+ if (BIO_printf(bp, "%12s", "") <= 0) -+ goto err; -+ if ((j = i2a_ASN1_OBJECT(bp, aobj)) > 0) { -+ ii = 0; -+ count = X509_ATTRIBUTE_count(a); -+ get_next: -+ at = X509_ATTRIBUTE_get0_type(a, ii); -+ type = at->type; -+ bs = at->value.asn1_string; -+ } -+ for (j = 25 - j; j > 0; j--) -+ if (BIO_write(bp, " ", 1) != 1) -+ goto err; -+ if (BIO_puts(bp, ":") <= 0) -+ goto err; -+ if ((type == V_ASN1_PRINTABLESTRING) || -+ (type == V_ASN1_T61STRING) || -+ (type == V_ASN1_UTF8STRING) || -+ (type == V_ASN1_IA5STRING)) { -+ if (BIO_write(bp, (char *)bs->data, bs->length) -+ != bs->length) -+ goto err; -+ BIO_puts(bp, "\n"); -+ } else { -+ BIO_puts(bp, "unable to print attribute\n"); -+ } -+ if (++ii < count) -+ goto get_next; -+ } -+ } -+ } -+ if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { -+ exts = X509_REQ_get_extensions(x); -+ if (exts) { -+ BIO_printf(bp, "%8sRequested Extensions:\n", ""); -+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { -+ ASN1_OBJECT *obj; -+ X509_EXTENSION *ex; -+ int critical; -+ ex = sk_X509_EXTENSION_value(exts, i); -+ if (BIO_printf(bp, "%12s", "") <= 0) -+ goto err; -+ obj = X509_EXTENSION_get_object(ex); -+ i2a_ASN1_OBJECT(bp, obj); -+ critical = X509_EXTENSION_get_critical(ex); -+ if (BIO_printf(bp, ": %s\n", critical ? "critical" : "") <= 0) -+ goto err; -+ if (!X509V3_EXT_print(bp, ex, cflag, 16)) { -+ BIO_printf(bp, "%16s", ""); -+ ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex)); -+ } -+ if (BIO_write(bp, "\n", 1) <= 0) -+ goto err; -+ } -+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); -+ } -+ } -+ -+ if (!(cflag & X509_FLAG_NO_SIGDUMP)) { -+ const X509_ALGOR *sig_alg; -+ const ASN1_BIT_STRING *sig; -+ X509_REQ_get0_signature(x, &sig, &sig_alg); -+ if (!X509_signature_print(bp, sig_alg, sig)) -+ goto err; -+ } -+ -+ return (1); -+ err: -+ X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB); -+ return (0); -+} -+ -+int X509_REQ_print(BIO *bp, X509_REQ *x) -+{ -+ return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_x509.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_x509.c -new file mode 100644 -index 0000000..eb65d88 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/t_x509.c -@@ -0,0 +1,376 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+#include "internal/asn1_int.h" -+ -+#ifndef OPENSSL_NO_STDIO -+int X509_print_fp(FILE *fp, X509 *x) -+{ -+ return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); -+} -+ -+int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, -+ unsigned long cflag) -+{ -+ BIO *b; -+ int ret; -+ -+ if ((b = BIO_new(BIO_s_file())) == NULL) { -+ X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB); -+ return (0); -+ } -+ BIO_set_fp(b, fp, BIO_NOCLOSE); -+ ret = X509_print_ex(b, x, nmflag, cflag); -+ BIO_free(b); -+ return (ret); -+} -+#endif -+ -+int X509_print(BIO *bp, X509 *x) -+{ -+ return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); -+} -+ -+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, -+ unsigned long cflag) -+{ -+ long l; -+ int ret = 0, i; -+ char *m = NULL, mlch = ' '; -+ int nmindent = 0; -+ ASN1_INTEGER *bs; -+ EVP_PKEY *pkey = NULL; -+ const char *neg; -+ -+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { -+ mlch = '\n'; -+ nmindent = 12; -+ } -+ -+ if (nmflags == X509_FLAG_COMPAT) -+ nmindent = 16; -+ -+ if (!(cflag & X509_FLAG_NO_HEADER)) { -+ if (BIO_write(bp, "Certificate:\n", 13) <= 0) -+ goto err; -+ if (BIO_write(bp, " Data:\n", 10) <= 0) -+ goto err; -+ } -+ if (!(cflag & X509_FLAG_NO_VERSION)) { -+ l = X509_get_version(x); -+ if (l >= 0 && l <= 2) { -+ if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0) -+ goto err; -+ } else { -+ if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 0) -+ goto err; -+ } -+ } -+ if (!(cflag & X509_FLAG_NO_SERIAL)) { -+ -+ if (BIO_write(bp, " Serial Number:", 22) <= 0) -+ goto err; -+ -+ bs = X509_get_serialNumber(x); -+ if (bs->length <= (int)sizeof(long)) { -+ ERR_set_mark(); -+ l = ASN1_INTEGER_get(bs); -+ ERR_pop_to_mark(); -+ } else { -+ l = -1; -+ } -+ if (l != -1) { -+ unsigned long ul; -+ if (bs->type == V_ASN1_NEG_INTEGER) { -+ ul = 0 - (unsigned long)l; -+ neg = "-"; -+ } else { -+ ul = l; -+ neg = ""; -+ } -+ if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, ul, neg, ul) <= 0) -+ goto err; -+ } else { -+ neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : ""; -+ if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0) -+ goto err; -+ -+ for (i = 0; i < bs->length; i++) { -+ if (BIO_printf(bp, "%02x%c", bs->data[i], -+ ((i + 1 == bs->length) ? '\n' : ':')) <= 0) -+ goto err; -+ } -+ } -+ -+ } -+ -+ if (!(cflag & X509_FLAG_NO_SIGNAME)) { -+ const X509_ALGOR *tsig_alg = X509_get0_tbs_sigalg(x); -+ if (X509_signature_print(bp, tsig_alg, NULL) <= 0) -+ goto err; -+ } -+ -+ if (!(cflag & X509_FLAG_NO_ISSUER)) { -+ if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) -+ goto err; -+ if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags) -+ < 0) -+ goto err; -+ if (BIO_write(bp, "\n", 1) <= 0) -+ goto err; -+ } -+ if (!(cflag & X509_FLAG_NO_VALIDITY)) { -+ if (BIO_write(bp, " Validity\n", 17) <= 0) -+ goto err; -+ if (BIO_write(bp, " Not Before: ", 24) <= 0) -+ goto err; -+ if (!ASN1_TIME_print(bp, X509_get0_notBefore(x))) -+ goto err; -+ if (BIO_write(bp, "\n Not After : ", 25) <= 0) -+ goto err; -+ if (!ASN1_TIME_print(bp, X509_get0_notAfter(x))) -+ goto err; -+ if (BIO_write(bp, "\n", 1) <= 0) -+ goto err; -+ } -+ if (!(cflag & X509_FLAG_NO_SUBJECT)) { -+ if (BIO_printf(bp, " Subject:%c", mlch) <= 0) -+ goto err; -+ if (X509_NAME_print_ex -+ (bp, X509_get_subject_name(x), nmindent, nmflags) < 0) -+ goto err; -+ if (BIO_write(bp, "\n", 1) <= 0) -+ goto err; -+ } -+ if (!(cflag & X509_FLAG_NO_PUBKEY)) { -+ X509_PUBKEY *xpkey = X509_get_X509_PUBKEY(x); -+ ASN1_OBJECT *xpoid; -+ X509_PUBKEY_get0_param(&xpoid, NULL, NULL, NULL, xpkey); -+ if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) -+ goto err; -+ if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) -+ goto err; -+ if (i2a_ASN1_OBJECT(bp, xpoid) <= 0) -+ goto err; -+ if (BIO_puts(bp, "\n") <= 0) -+ goto err; -+ -+ pkey = X509_get0_pubkey(x); -+ if (pkey == NULL) { -+ BIO_printf(bp, "%12sUnable to load Public Key\n", ""); -+ ERR_print_errors(bp); -+ } else { -+ EVP_PKEY_print_public(bp, pkey, 16, NULL); -+ } -+ } -+ -+ if (!(cflag & X509_FLAG_NO_IDS)) { -+ const ASN1_BIT_STRING *iuid, *suid; -+ X509_get0_uids(x, &iuid, &suid); -+ if (iuid != NULL) { -+ if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0) -+ goto err; -+ if (!X509_signature_dump(bp, iuid, 12)) -+ goto err; -+ } -+ if (suid != NULL) { -+ if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0) -+ goto err; -+ if (!X509_signature_dump(bp, suid, 12)) -+ goto err; -+ } -+ } -+ -+ if (!(cflag & X509_FLAG_NO_EXTENSIONS)) -+ X509V3_extensions_print(bp, "X509v3 extensions", -+ X509_get0_extensions(x), cflag, 8); -+ -+ if (!(cflag & X509_FLAG_NO_SIGDUMP)) { -+ const X509_ALGOR *sig_alg; -+ const ASN1_BIT_STRING *sig; -+ X509_get0_signature(&sig, &sig_alg, x); -+ if (X509_signature_print(bp, sig_alg, sig) <= 0) -+ goto err; -+ } -+ if (!(cflag & X509_FLAG_NO_AUX)) { -+ if (!X509_aux_print(bp, x, 0)) -+ goto err; -+ } -+ ret = 1; -+ err: -+ OPENSSL_free(m); -+ return (ret); -+} -+ -+int X509_ocspid_print(BIO *bp, X509 *x) -+{ -+ unsigned char *der = NULL; -+ unsigned char *dertmp; -+ int derlen; -+ int i; -+ unsigned char SHA1md[SHA_DIGEST_LENGTH]; -+ ASN1_BIT_STRING *keybstr; -+ X509_NAME *subj; -+ -+ /* -+ * display the hash of the subject as it would appear in OCSP requests -+ */ -+ if (BIO_printf(bp, " Subject OCSP hash: ") <= 0) -+ goto err; -+ subj = X509_get_subject_name(x); -+ derlen = i2d_X509_NAME(subj, NULL); -+ if ((der = dertmp = OPENSSL_malloc(derlen)) == NULL) -+ goto err; -+ i2d_X509_NAME(subj, &dertmp); -+ -+ if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL)) -+ goto err; -+ for (i = 0; i < SHA_DIGEST_LENGTH; i++) { -+ if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) -+ goto err; -+ } -+ OPENSSL_free(der); -+ der = NULL; -+ -+ /* -+ * display the hash of the public key as it would appear in OCSP requests -+ */ -+ if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0) -+ goto err; -+ -+ keybstr = X509_get0_pubkey_bitstr(x); -+ -+ if (keybstr == NULL) -+ goto err; -+ -+ if (!EVP_Digest(ASN1_STRING_get0_data(keybstr), -+ ASN1_STRING_length(keybstr), SHA1md, NULL, EVP_sha1(), -+ NULL)) -+ goto err; -+ for (i = 0; i < SHA_DIGEST_LENGTH; i++) { -+ if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) -+ goto err; -+ } -+ BIO_printf(bp, "\n"); -+ -+ return (1); -+ err: -+ OPENSSL_free(der); -+ return (0); -+} -+ -+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) -+{ -+ const unsigned char *s; -+ int i, n; -+ -+ n = sig->length; -+ s = sig->data; -+ for (i = 0; i < n; i++) { -+ if ((i % 18) == 0) { -+ if (BIO_write(bp, "\n", 1) <= 0) -+ return 0; -+ if (BIO_indent(bp, indent, indent) <= 0) -+ return 0; -+ } -+ if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0) -+ return 0; -+ } -+ if (BIO_write(bp, "\n", 1) != 1) -+ return 0; -+ -+ return 1; -+} -+ -+int X509_signature_print(BIO *bp, const X509_ALGOR *sigalg, -+ const ASN1_STRING *sig) -+{ -+ int sig_nid; -+ if (BIO_puts(bp, " Signature Algorithm: ") <= 0) -+ return 0; -+ if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) -+ return 0; -+ -+ sig_nid = OBJ_obj2nid(sigalg->algorithm); -+ if (sig_nid != NID_undef) { -+ int pkey_nid, dig_nid; -+ const EVP_PKEY_ASN1_METHOD *ameth; -+ if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) { -+ ameth = EVP_PKEY_asn1_find(NULL, pkey_nid); -+ if (ameth && ameth->sig_print) -+ return ameth->sig_print(bp, sigalg, sig, 9, 0); -+ } -+ } -+ if (sig) -+ return X509_signature_dump(bp, sig, 9); -+ else if (BIO_puts(bp, "\n") <= 0) -+ return 0; -+ return 1; -+} -+ -+int X509_aux_print(BIO *out, X509 *x, int indent) -+{ -+ char oidstr[80], first; -+ STACK_OF(ASN1_OBJECT) *trust, *reject; -+ const unsigned char *alias, *keyid; -+ int keyidlen; -+ int i; -+ if (X509_trusted(x) == 0) -+ return 1; -+ trust = X509_get0_trust_objects(x); -+ reject = X509_get0_reject_objects(x); -+ if (trust) { -+ first = 1; -+ BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, ""); -+ for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) { -+ if (!first) -+ BIO_puts(out, ", "); -+ else -+ first = 0; -+ OBJ_obj2txt(oidstr, sizeof oidstr, -+ sk_ASN1_OBJECT_value(trust, i), 0); -+ BIO_puts(out, oidstr); -+ } -+ BIO_puts(out, "\n"); -+ } else -+ BIO_printf(out, "%*sNo Trusted Uses.\n", indent, ""); -+ if (reject) { -+ first = 1; -+ BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, ""); -+ for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) { -+ if (!first) -+ BIO_puts(out, ", "); -+ else -+ first = 0; -+ OBJ_obj2txt(oidstr, sizeof oidstr, -+ sk_ASN1_OBJECT_value(reject, i), 0); -+ BIO_puts(out, oidstr); -+ } -+ BIO_puts(out, "\n"); -+ } else -+ BIO_printf(out, "%*sNo Rejected Uses.\n", indent, ""); -+ alias = X509_alias_get0(x, NULL); -+ if (alias) -+ BIO_printf(out, "%*sAlias: %s\n", indent, "", alias); -+ keyid = X509_keyid_get0(x, &keyidlen); -+ if (keyid) { -+ BIO_printf(out, "%*sKey Id: ", indent, ""); -+ for (i = 0; i < keyidlen; i++) -+ BIO_printf(out, "%s%02X", i ? ":" : "", keyid[i]); -+ BIO_write(out, "\n", 1); -+ } -+ return 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_att.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_att.c -new file mode 100644 -index 0000000..15f0e4f ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_att.c -@@ -0,0 +1,329 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+#include "x509_lcl.h" -+ -+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) -+{ -+ return sk_X509_ATTRIBUTE_num(x); -+} -+ -+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, -+ int lastpos) -+{ -+ const ASN1_OBJECT *obj = OBJ_nid2obj(nid); -+ -+ if (obj == NULL) -+ return (-2); -+ return (X509at_get_attr_by_OBJ(x, obj, lastpos)); -+} -+ -+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, -+ const ASN1_OBJECT *obj, int lastpos) -+{ -+ int n; -+ X509_ATTRIBUTE *ex; -+ -+ if (sk == NULL) -+ return (-1); -+ lastpos++; -+ if (lastpos < 0) -+ lastpos = 0; -+ n = sk_X509_ATTRIBUTE_num(sk); -+ for (; lastpos < n; lastpos++) { -+ ex = sk_X509_ATTRIBUTE_value(sk, lastpos); -+ if (OBJ_cmp(ex->object, obj) == 0) -+ return (lastpos); -+ } -+ return (-1); -+} -+ -+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) -+{ -+ if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) -+ return NULL; -+ else -+ return sk_X509_ATTRIBUTE_value(x, loc); -+} -+ -+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) -+{ -+ X509_ATTRIBUTE *ret; -+ -+ if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) -+ return (NULL); -+ ret = sk_X509_ATTRIBUTE_delete(x, loc); -+ return (ret); -+} -+ -+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, -+ X509_ATTRIBUTE *attr) -+{ -+ X509_ATTRIBUTE *new_attr = NULL; -+ STACK_OF(X509_ATTRIBUTE) *sk = NULL; -+ -+ if (x == NULL) { -+ X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER); -+ goto err2; -+ } -+ -+ if (*x == NULL) { -+ if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) -+ goto err; -+ } else -+ sk = *x; -+ -+ if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) -+ goto err2; -+ if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) -+ goto err; -+ if (*x == NULL) -+ *x = sk; -+ return (sk); -+ err: -+ X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_MALLOC_FAILURE); -+ err2: -+ X509_ATTRIBUTE_free(new_attr); -+ sk_X509_ATTRIBUTE_free(sk); -+ return (NULL); -+} -+ -+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) -+ **x, const ASN1_OBJECT *obj, -+ int type, -+ const unsigned char *bytes, -+ int len) -+{ -+ X509_ATTRIBUTE *attr; -+ STACK_OF(X509_ATTRIBUTE) *ret; -+ attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); -+ if (!attr) -+ return 0; -+ ret = X509at_add1_attr(x, attr); -+ X509_ATTRIBUTE_free(attr); -+ return ret; -+} -+ -+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) -+ **x, int nid, int type, -+ const unsigned char *bytes, -+ int len) -+{ -+ X509_ATTRIBUTE *attr; -+ STACK_OF(X509_ATTRIBUTE) *ret; -+ attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); -+ if (!attr) -+ return 0; -+ ret = X509at_add1_attr(x, attr); -+ X509_ATTRIBUTE_free(attr); -+ return ret; -+} -+ -+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) -+ **x, const char *attrname, -+ int type, -+ const unsigned char *bytes, -+ int len) -+{ -+ X509_ATTRIBUTE *attr; -+ STACK_OF(X509_ATTRIBUTE) *ret; -+ attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); -+ if (!attr) -+ return 0; -+ ret = X509at_add1_attr(x, attr); -+ X509_ATTRIBUTE_free(attr); -+ return ret; -+} -+ -+void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, -+ const ASN1_OBJECT *obj, int lastpos, int type) -+{ -+ int i; -+ X509_ATTRIBUTE *at; -+ i = X509at_get_attr_by_OBJ(x, obj, lastpos); -+ if (i == -1) -+ return NULL; -+ if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1)) -+ return NULL; -+ at = X509at_get_attr(x, i); -+ if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1)) -+ return NULL; -+ return X509_ATTRIBUTE_get0_data(at, 0, type, NULL); -+} -+ -+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, -+ int atrtype, const void *data, -+ int len) -+{ -+ ASN1_OBJECT *obj; -+ X509_ATTRIBUTE *ret; -+ -+ obj = OBJ_nid2obj(nid); -+ if (obj == NULL) { -+ X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID, X509_R_UNKNOWN_NID); -+ return (NULL); -+ } -+ ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len); -+ if (ret == NULL) -+ ASN1_OBJECT_free(obj); -+ return (ret); -+} -+ -+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, -+ const ASN1_OBJECT *obj, -+ int atrtype, const void *data, -+ int len) -+{ -+ X509_ATTRIBUTE *ret; -+ -+ if ((attr == NULL) || (*attr == NULL)) { -+ if ((ret = X509_ATTRIBUTE_new()) == NULL) { -+ X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ, -+ ERR_R_MALLOC_FAILURE); -+ return (NULL); -+ } -+ } else -+ ret = *attr; -+ -+ if (!X509_ATTRIBUTE_set1_object(ret, obj)) -+ goto err; -+ if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len)) -+ goto err; -+ -+ if ((attr != NULL) && (*attr == NULL)) -+ *attr = ret; -+ return (ret); -+ err: -+ if ((attr == NULL) || (ret != *attr)) -+ X509_ATTRIBUTE_free(ret); -+ return (NULL); -+} -+ -+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, -+ const char *atrname, int type, -+ const unsigned char *bytes, -+ int len) -+{ -+ ASN1_OBJECT *obj; -+ X509_ATTRIBUTE *nattr; -+ -+ obj = OBJ_txt2obj(atrname, 0); -+ if (obj == NULL) { -+ X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, -+ X509_R_INVALID_FIELD_NAME); -+ ERR_add_error_data(2, "name=", atrname); -+ return (NULL); -+ } -+ nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); -+ ASN1_OBJECT_free(obj); -+ return nattr; -+} -+ -+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) -+{ -+ if ((attr == NULL) || (obj == NULL)) -+ return (0); -+ ASN1_OBJECT_free(attr->object); -+ attr->object = OBJ_dup(obj); -+ return attr->object != NULL; -+} -+ -+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, -+ const void *data, int len) -+{ -+ ASN1_TYPE *ttmp = NULL; -+ ASN1_STRING *stmp = NULL; -+ int atype = 0; -+ if (!attr) -+ return 0; -+ if (attrtype & MBSTRING_FLAG) { -+ stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, -+ OBJ_obj2nid(attr->object)); -+ if (!stmp) { -+ X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB); -+ return 0; -+ } -+ atype = stmp->type; -+ } else if (len != -1) { -+ if ((stmp = ASN1_STRING_type_new(attrtype)) == NULL) -+ goto err; -+ if (!ASN1_STRING_set(stmp, data, len)) -+ goto err; -+ atype = attrtype; -+ } -+ /* -+ * This is a bit naughty because the attribute should really have at -+ * least one value but some types use and zero length SET and require -+ * this. -+ */ -+ if (attrtype == 0) { -+ ASN1_STRING_free(stmp); -+ return 1; -+ } -+ if ((ttmp = ASN1_TYPE_new()) == NULL) -+ goto err; -+ if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { -+ if (!ASN1_TYPE_set1(ttmp, attrtype, data)) -+ goto err; -+ } else { -+ ASN1_TYPE_set(ttmp, atype, stmp); -+ stmp = NULL; -+ } -+ if (!sk_ASN1_TYPE_push(attr->set, ttmp)) -+ goto err; -+ return 1; -+ err: -+ X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE); -+ ASN1_TYPE_free(ttmp); -+ ASN1_STRING_free(stmp); -+ return 0; -+} -+ -+int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr) -+{ -+ if (attr == NULL) -+ return 0; -+ return sk_ASN1_TYPE_num(attr->set); -+} -+ -+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) -+{ -+ if (attr == NULL) -+ return (NULL); -+ return (attr->object); -+} -+ -+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, -+ int atrtype, void *data) -+{ -+ ASN1_TYPE *ttmp; -+ ttmp = X509_ATTRIBUTE_get0_type(attr, idx); -+ if (!ttmp) -+ return NULL; -+ if (atrtype != ASN1_TYPE_get(ttmp)) { -+ X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE); -+ return NULL; -+ } -+ return ttmp->value.ptr; -+} -+ -+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) -+{ -+ if (attr == NULL) -+ return NULL; -+ return sk_ASN1_TYPE_value(attr->set, idx); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_cmp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_cmp.c -new file mode 100644 -index 0000000..0105635 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_cmp.c -@@ -0,0 +1,459 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+ -+int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) -+{ -+ int i; -+ const X509_CINF *ai, *bi; -+ -+ ai = &a->cert_info; -+ bi = &b->cert_info; -+ i = ASN1_INTEGER_cmp(&ai->serialNumber, &bi->serialNumber); -+ if (i) -+ return (i); -+ return (X509_NAME_cmp(ai->issuer, bi->issuer)); -+} -+ -+#ifndef OPENSSL_NO_MD5 -+unsigned long X509_issuer_and_serial_hash(X509 *a) -+{ -+ unsigned long ret = 0; -+ EVP_MD_CTX *ctx = EVP_MD_CTX_new(); -+ unsigned char md[16]; -+ char *f; -+ -+ if (ctx == NULL) -+ goto err; -+ f = X509_NAME_oneline(a->cert_info.issuer, NULL, 0); -+ if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL)) -+ goto err; -+ if (!EVP_DigestUpdate(ctx, (unsigned char *)f, strlen(f))) -+ goto err; -+ OPENSSL_free(f); -+ if (!EVP_DigestUpdate -+ (ctx, (unsigned char *)a->cert_info.serialNumber.data, -+ (unsigned long)a->cert_info.serialNumber.length)) -+ goto err; -+ if (!EVP_DigestFinal_ex(ctx, &(md[0]), NULL)) -+ goto err; -+ ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | -+ ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) -+ ) & 0xffffffffL; -+ err: -+ EVP_MD_CTX_free(ctx); -+ return (ret); -+} -+#endif -+ -+int X509_issuer_name_cmp(const X509 *a, const X509 *b) -+{ -+ return (X509_NAME_cmp(a->cert_info.issuer, b->cert_info.issuer)); -+} -+ -+int X509_subject_name_cmp(const X509 *a, const X509 *b) -+{ -+ return (X509_NAME_cmp(a->cert_info.subject, b->cert_info.subject)); -+} -+ -+int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) -+{ -+ return (X509_NAME_cmp(a->crl.issuer, b->crl.issuer)); -+} -+ -+int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) -+{ -+ return memcmp(a->sha1_hash, b->sha1_hash, 20); -+} -+ -+X509_NAME *X509_get_issuer_name(const X509 *a) -+{ -+ return (a->cert_info.issuer); -+} -+ -+unsigned long X509_issuer_name_hash(X509 *x) -+{ -+ return (X509_NAME_hash(x->cert_info.issuer)); -+} -+ -+#ifndef OPENSSL_NO_MD5 -+unsigned long X509_issuer_name_hash_old(X509 *x) -+{ -+ return (X509_NAME_hash_old(x->cert_info.issuer)); -+} -+#endif -+ -+X509_NAME *X509_get_subject_name(const X509 *a) -+{ -+ return (a->cert_info.subject); -+} -+ -+ASN1_INTEGER *X509_get_serialNumber(X509 *a) -+{ -+ return &a->cert_info.serialNumber; -+} -+ -+const ASN1_INTEGER *X509_get0_serialNumber(const X509 *a) -+{ -+ return &a->cert_info.serialNumber; -+} -+ -+unsigned long X509_subject_name_hash(X509 *x) -+{ -+ return (X509_NAME_hash(x->cert_info.subject)); -+} -+ -+#ifndef OPENSSL_NO_MD5 -+unsigned long X509_subject_name_hash_old(X509 *x) -+{ -+ return (X509_NAME_hash_old(x->cert_info.subject)); -+} -+#endif -+ -+/* -+ * Compare two certificates: they must be identical for this to work. NB: -+ * Although "cmp" operations are generally prototyped to take "const" -+ * arguments (eg. for use in STACKs), the way X509 handling is - these -+ * operations may involve ensuring the hashes are up-to-date and ensuring -+ * certain cert information is cached. So this is the point where the -+ * "depth-first" constification tree has to halt with an evil cast. -+ */ -+int X509_cmp(const X509 *a, const X509 *b) -+{ -+ int rv; -+ /* ensure hash is valid */ -+ X509_check_purpose((X509 *)a, -1, 0); -+ X509_check_purpose((X509 *)b, -1, 0); -+ -+ rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); -+ if (rv) -+ return rv; -+ /* Check for match against stored encoding too */ -+ if (!a->cert_info.enc.modified && !b->cert_info.enc.modified) { -+ if (a->cert_info.enc.len < b->cert_info.enc.len) -+ return -1; -+ if (a->cert_info.enc.len > b->cert_info.enc.len) -+ return 1; -+ return memcmp(a->cert_info.enc.enc, b->cert_info.enc.enc, -+ a->cert_info.enc.len); -+ } -+ return rv; -+} -+ -+int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) -+{ -+ int ret; -+ -+ /* Ensure canonical encoding is present and up to date */ -+ -+ if (!a->canon_enc || a->modified) { -+ ret = i2d_X509_NAME((X509_NAME *)a, NULL); -+ if (ret < 0) -+ return -2; -+ } -+ -+ if (!b->canon_enc || b->modified) { -+ ret = i2d_X509_NAME((X509_NAME *)b, NULL); -+ if (ret < 0) -+ return -2; -+ } -+ -+ ret = a->canon_enclen - b->canon_enclen; -+ -+ if (ret) -+ return ret; -+ -+ return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); -+ -+} -+ -+unsigned long X509_NAME_hash(X509_NAME *x) -+{ -+ unsigned long ret = 0; -+ unsigned char md[SHA_DIGEST_LENGTH]; -+ -+ /* Make sure X509_NAME structure contains valid cached encoding */ -+ i2d_X509_NAME(x, NULL); -+ if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), -+ NULL)) -+ return 0; -+ -+ ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | -+ ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) -+ ) & 0xffffffffL; -+ return (ret); -+} -+ -+#ifndef OPENSSL_NO_MD5 -+/* -+ * I now DER encode the name and hash it. Since I cache the DER encoding, -+ * this is reasonably efficient. -+ */ -+ -+unsigned long X509_NAME_hash_old(X509_NAME *x) -+{ -+ EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); -+ unsigned long ret = 0; -+ unsigned char md[16]; -+ -+ if (md_ctx == NULL) -+ return ret; -+ -+ /* Make sure X509_NAME structure contains valid cached encoding */ -+ i2d_X509_NAME(x, NULL); -+ EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); -+ if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL) -+ && EVP_DigestUpdate(md_ctx, x->bytes->data, x->bytes->length) -+ && EVP_DigestFinal_ex(md_ctx, md, NULL)) -+ ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | -+ ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) -+ ) & 0xffffffffL; -+ EVP_MD_CTX_free(md_ctx); -+ -+ return (ret); -+} -+#endif -+ -+/* Search a stack of X509 for a match */ -+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, -+ ASN1_INTEGER *serial) -+{ -+ int i; -+ X509 x, *x509 = NULL; -+ -+ if (!sk) -+ return NULL; -+ -+ x.cert_info.serialNumber = *serial; -+ x.cert_info.issuer = name; -+ -+ for (i = 0; i < sk_X509_num(sk); i++) { -+ x509 = sk_X509_value(sk, i); -+ if (X509_issuer_and_serial_cmp(x509, &x) == 0) -+ return (x509); -+ } -+ return (NULL); -+} -+ -+X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) -+{ -+ X509 *x509; -+ int i; -+ -+ for (i = 0; i < sk_X509_num(sk); i++) { -+ x509 = sk_X509_value(sk, i); -+ if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) -+ return (x509); -+ } -+ return (NULL); -+} -+ -+EVP_PKEY *X509_get0_pubkey(const X509 *x) -+{ -+ if (x == NULL) -+ return NULL; -+ return X509_PUBKEY_get0(x->cert_info.key); -+} -+ -+EVP_PKEY *X509_get_pubkey(X509 *x) -+{ -+ if (x == NULL) -+ return NULL; -+ return X509_PUBKEY_get(x->cert_info.key); -+} -+ -+int X509_check_private_key(const X509 *x, const EVP_PKEY *k) -+{ -+ const EVP_PKEY *xk; -+ int ret; -+ -+ xk = X509_get0_pubkey(x); -+ -+ if (xk) -+ ret = EVP_PKEY_cmp(xk, k); -+ else -+ ret = -2; -+ -+ switch (ret) { -+ case 1: -+ break; -+ case 0: -+ X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH); -+ break; -+ case -1: -+ X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); -+ break; -+ case -2: -+ X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); -+ } -+ if (ret > 0) -+ return 1; -+ return 0; -+} -+ -+/* -+ * Check a suite B algorithm is permitted: pass in a public key and the NID -+ * of its signature (or 0 if no signature). The pflags is a pointer to a -+ * flags field which must contain the suite B verification flags. -+ */ -+ -+#ifndef OPENSSL_NO_EC -+ -+static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) -+{ -+ const EC_GROUP *grp = NULL; -+ int curve_nid; -+ if (pkey && EVP_PKEY_id(pkey) == EVP_PKEY_EC) -+ grp = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey)); -+ if (!grp) -+ return X509_V_ERR_SUITE_B_INVALID_ALGORITHM; -+ curve_nid = EC_GROUP_get_curve_name(grp); -+ /* Check curve is consistent with LOS */ -+ if (curve_nid == NID_secp384r1) { /* P-384 */ -+ /* -+ * Check signature algorithm is consistent with curve. -+ */ -+ if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384) -+ return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; -+ if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS)) -+ return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; -+ /* If we encounter P-384 we cannot use P-256 later */ -+ *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY; -+ } else if (curve_nid == NID_X9_62_prime256v1) { /* P-256 */ -+ if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256) -+ return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; -+ if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY)) -+ return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; -+ } else -+ return X509_V_ERR_SUITE_B_INVALID_CURVE; -+ -+ return X509_V_OK; -+} -+ -+int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, -+ unsigned long flags) -+{ -+ int rv, i, sign_nid; -+ EVP_PKEY *pk; -+ unsigned long tflags = flags; -+ -+ if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) -+ return X509_V_OK; -+ -+ /* If no EE certificate passed in must be first in chain */ -+ if (x == NULL) { -+ x = sk_X509_value(chain, 0); -+ i = 1; -+ } else -+ i = 0; -+ -+ pk = X509_get0_pubkey(x); -+ -+ /* -+ * With DANE-EE(3) success, or DANE-EE(3)/PKIX-EE(1) failure we don't build -+ * a chain all, just report trust success or failure, but must also report -+ * Suite-B errors if applicable. This is indicated via a NULL chain -+ * pointer. All we need to do is check the leaf key algorithm. -+ */ -+ if (chain == NULL) -+ return check_suite_b(pk, -1, &tflags); -+ -+ if (X509_get_version(x) != 2) { -+ rv = X509_V_ERR_SUITE_B_INVALID_VERSION; -+ /* Correct error depth */ -+ i = 0; -+ goto end; -+ } -+ -+ /* Check EE key only */ -+ rv = check_suite_b(pk, -1, &tflags); -+ if (rv != X509_V_OK) { -+ /* Correct error depth */ -+ i = 0; -+ goto end; -+ } -+ for (; i < sk_X509_num(chain); i++) { -+ sign_nid = X509_get_signature_nid(x); -+ x = sk_X509_value(chain, i); -+ if (X509_get_version(x) != 2) { -+ rv = X509_V_ERR_SUITE_B_INVALID_VERSION; -+ goto end; -+ } -+ pk = X509_get0_pubkey(x); -+ rv = check_suite_b(pk, sign_nid, &tflags); -+ if (rv != X509_V_OK) -+ goto end; -+ } -+ -+ /* Final check: root CA signature */ -+ rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags); -+ end: -+ if (rv != X509_V_OK) { -+ /* Invalid signature or LOS errors are for previous cert */ -+ if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM -+ || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i) -+ i--; -+ /* -+ * If we have LOS error and flags changed then we are signing P-384 -+ * with P-256. Use more meaningful error. -+ */ -+ if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags) -+ rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256; -+ if (perror_depth) -+ *perror_depth = i; -+ } -+ return rv; -+} -+ -+int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) -+{ -+ int sign_nid; -+ if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) -+ return X509_V_OK; -+ sign_nid = OBJ_obj2nid(crl->crl.sig_alg.algorithm); -+ return check_suite_b(pk, sign_nid, &flags); -+} -+ -+#else -+int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, -+ unsigned long flags) -+{ -+ return 0; -+} -+ -+int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) -+{ -+ return 0; -+} -+ -+#endif -+/* -+ * Not strictly speaking an "up_ref" as a STACK doesn't have a reference -+ * count but it has the same effect by duping the STACK and upping the ref of -+ * each X509 structure. -+ */ -+STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) -+{ -+ STACK_OF(X509) *ret; -+ int i; -+ ret = sk_X509_dup(chain); -+ for (i = 0; i < sk_X509_num(ret); i++) { -+ X509 *x = sk_X509_value(ret, i); -+ X509_up_ref(x); -+ } -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_d2.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_d2.c -new file mode 100644 -index 0000000..cb03dbf ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_d2.c -@@ -0,0 +1,57 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+ -+int X509_STORE_set_default_paths(X509_STORE *ctx) -+{ -+ X509_LOOKUP *lookup; -+ -+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); -+ if (lookup == NULL) -+ return (0); -+ X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); -+ -+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); -+ if (lookup == NULL) -+ return (0); -+ X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); -+ -+ /* clear any errors */ -+ ERR_clear_error(); -+ -+ return (1); -+} -+ -+int X509_STORE_load_locations(X509_STORE *ctx, const char *file, -+ const char *path) -+{ -+ X509_LOOKUP *lookup; -+ -+ if (file != NULL) { -+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); -+ if (lookup == NULL) -+ return (0); -+ if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) -+ return (0); -+ } -+ if (path != NULL) { -+ lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); -+ if (lookup == NULL) -+ return (0); -+ if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) -+ return (0); -+ } -+ if ((path == NULL) && (file == NULL)) -+ return (0); -+ return (1); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_def.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_def.c -new file mode 100644 -index 0000000..d11358e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_def.c -@@ -0,0 +1,43 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+ -+const char *X509_get_default_private_dir(void) -+{ -+ return (X509_PRIVATE_DIR); -+} -+ -+const char *X509_get_default_cert_area(void) -+{ -+ return (X509_CERT_AREA); -+} -+ -+const char *X509_get_default_cert_dir(void) -+{ -+ return (X509_CERT_DIR); -+} -+ -+const char *X509_get_default_cert_file(void) -+{ -+ return (X509_CERT_FILE); -+} -+ -+const char *X509_get_default_cert_dir_env(void) -+{ -+ return (X509_CERT_DIR_EVP); -+} -+ -+const char *X509_get_default_cert_file_env(void) -+{ -+ return (X509_CERT_FILE_EVP); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_err.c -new file mode 100644 -index 0000000..3f4b8ef ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_err.c -@@ -0,0 +1,142 @@ -+/* -+ * Generated by util/mkerr.pl DO NOT EDIT -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+ -+/* BEGIN ERROR CODES */ -+#ifndef OPENSSL_NO_ERR -+ -+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0) -+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason) -+ -+static ERR_STRING_DATA X509_str_functs[] = { -+ {ERR_FUNC(X509_F_ADD_CERT_DIR), "add_cert_dir"}, -+ {ERR_FUNC(X509_F_BUILD_CHAIN), "build_chain"}, -+ {ERR_FUNC(X509_F_BY_FILE_CTRL), "by_file_ctrl"}, -+ {ERR_FUNC(X509_F_CHECK_NAME_CONSTRAINTS), "check_name_constraints"}, -+ {ERR_FUNC(X509_F_CHECK_POLICY), "check_policy"}, -+ {ERR_FUNC(X509_F_DANE_I2D), "dane_i2d"}, -+ {ERR_FUNC(X509_F_DIR_CTRL), "dir_ctrl"}, -+ {ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "get_cert_by_subject"}, -+ {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE), "NETSCAPE_SPKI_b64_decode"}, -+ {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE), "NETSCAPE_SPKI_b64_encode"}, -+ {ERR_FUNC(X509_F_X509AT_ADD1_ATTR), "X509at_add1_attr"}, -+ {ERR_FUNC(X509_F_X509V3_ADD_EXT), "X509v3_add_ext"}, -+ {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID), -+ "X509_ATTRIBUTE_create_by_NID"}, -+ {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ), -+ "X509_ATTRIBUTE_create_by_OBJ"}, -+ {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT), -+ "X509_ATTRIBUTE_create_by_txt"}, -+ {ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"}, -+ {ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"}, -+ {ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"}, -+ {ERR_FUNC(X509_F_X509_CRL_DIFF), "X509_CRL_diff"}, -+ {ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"}, -+ {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID), -+ "X509_EXTENSION_create_by_NID"}, -+ {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ), -+ "X509_EXTENSION_create_by_OBJ"}, -+ {ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS), -+ "X509_get_pubkey_parameters"}, -+ {ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE), "X509_load_cert_crl_file"}, -+ {ERR_FUNC(X509_F_X509_LOAD_CERT_FILE), "X509_load_cert_file"}, -+ {ERR_FUNC(X509_F_X509_LOAD_CRL_FILE), "X509_load_crl_file"}, -+ {ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY), "X509_NAME_add_entry"}, -+ {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID), -+ "X509_NAME_ENTRY_create_by_NID"}, -+ {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT), -+ "X509_NAME_ENTRY_create_by_txt"}, -+ {ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT), -+ "X509_NAME_ENTRY_set_object"}, -+ {ERR_FUNC(X509_F_X509_NAME_ONELINE), "X509_NAME_oneline"}, -+ {ERR_FUNC(X509_F_X509_NAME_PRINT), "X509_NAME_print"}, -+ {ERR_FUNC(X509_F_X509_OBJECT_NEW), "X509_OBJECT_new"}, -+ {ERR_FUNC(X509_F_X509_PRINT_EX_FP), "X509_print_ex_fp"}, -+ {ERR_FUNC(X509_F_X509_PUBKEY_DECODE), "x509_pubkey_decode"}, -+ {ERR_FUNC(X509_F_X509_PUBKEY_GET0), "X509_PUBKEY_get0"}, -+ {ERR_FUNC(X509_F_X509_PUBKEY_SET), "X509_PUBKEY_set"}, -+ {ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY), -+ "X509_REQ_check_private_key"}, -+ {ERR_FUNC(X509_F_X509_REQ_PRINT_EX), "X509_REQ_print_ex"}, -+ {ERR_FUNC(X509_F_X509_REQ_PRINT_FP), "X509_REQ_print_fp"}, -+ {ERR_FUNC(X509_F_X509_REQ_TO_X509), "X509_REQ_to_X509"}, -+ {ERR_FUNC(X509_F_X509_STORE_ADD_CERT), "X509_STORE_add_cert"}, -+ {ERR_FUNC(X509_F_X509_STORE_ADD_CRL), "X509_STORE_add_crl"}, -+ {ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER), -+ "X509_STORE_CTX_get1_issuer"}, -+ {ERR_FUNC(X509_F_X509_STORE_CTX_INIT), "X509_STORE_CTX_init"}, -+ {ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"}, -+ {ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT), -+ "X509_STORE_CTX_purpose_inherit"}, -+ {ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"}, -+ {ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"}, -+ {ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"}, -+ {ERR_FUNC(X509_F_X509_VERIFY_CERT), "X509_verify_cert"}, -+ {0, NULL} -+}; -+ -+static ERR_STRING_DATA X509_str_reasons[] = { -+ {ERR_REASON(X509_R_AKID_MISMATCH), "akid mismatch"}, -+ {ERR_REASON(X509_R_BAD_SELECTOR), "bad selector"}, -+ {ERR_REASON(X509_R_BAD_X509_FILETYPE), "bad x509 filetype"}, -+ {ERR_REASON(X509_R_BASE64_DECODE_ERROR), "base64 decode error"}, -+ {ERR_REASON(X509_R_CANT_CHECK_DH_KEY), "cant check dh key"}, -+ {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE), -+ "cert already in hash table"}, -+ {ERR_REASON(X509_R_CRL_ALREADY_DELTA), "crl already delta"}, -+ {ERR_REASON(X509_R_CRL_VERIFY_FAILURE), "crl verify failure"}, -+ {ERR_REASON(X509_R_IDP_MISMATCH), "idp mismatch"}, -+ {ERR_REASON(X509_R_INVALID_DIRECTORY), "invalid directory"}, -+ {ERR_REASON(X509_R_INVALID_FIELD_NAME), "invalid field name"}, -+ {ERR_REASON(X509_R_INVALID_TRUST), "invalid trust"}, -+ {ERR_REASON(X509_R_ISSUER_MISMATCH), "issuer mismatch"}, -+ {ERR_REASON(X509_R_KEY_TYPE_MISMATCH), "key type mismatch"}, -+ {ERR_REASON(X509_R_KEY_VALUES_MISMATCH), "key values mismatch"}, -+ {ERR_REASON(X509_R_LOADING_CERT_DIR), "loading cert dir"}, -+ {ERR_REASON(X509_R_LOADING_DEFAULTS), "loading defaults"}, -+ {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED), "method not supported"}, -+ {ERR_REASON(X509_R_NAME_TOO_LONG), "name too long"}, -+ {ERR_REASON(X509_R_NEWER_CRL_NOT_NEWER), "newer crl not newer"}, -+ {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY), -+ "no cert set for us to verify"}, -+ {ERR_REASON(X509_R_NO_CRL_NUMBER), "no crl number"}, -+ {ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"}, -+ {ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"}, -+ {ERR_REASON(X509_R_SHOULD_RETRY), "should retry"}, -+ {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN), -+ "unable to find parameters in chain"}, -+ {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY), -+ "unable to get certs public key"}, -+ {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE), "unknown key type"}, -+ {ERR_REASON(X509_R_UNKNOWN_NID), "unknown nid"}, -+ {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"}, -+ {ERR_REASON(X509_R_UNKNOWN_TRUST_ID), "unknown trust id"}, -+ {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, -+ {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type"}, -+ {ERR_REASON(X509_R_WRONG_TYPE), "wrong type"}, -+ {0, NULL} -+}; -+ -+#endif -+ -+int ERR_load_X509_strings(void) -+{ -+#ifndef OPENSSL_NO_ERR -+ -+ if (ERR_func_error_string(X509_str_functs[0].error) == NULL) { -+ ERR_load_strings(0, X509_str_functs); -+ ERR_load_strings(0, X509_str_reasons); -+ } -+#endif -+ return 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_ext.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_ext.c -new file mode 100644 -index 0000000..3bbb0a6 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_ext.c -@@ -0,0 +1,160 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+#include -+ -+int X509_CRL_get_ext_count(const X509_CRL *x) -+{ -+ return (X509v3_get_ext_count(x->crl.extensions)); -+} -+ -+int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos) -+{ -+ return (X509v3_get_ext_by_NID(x->crl.extensions, nid, lastpos)); -+} -+ -+int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, -+ int lastpos) -+{ -+ return (X509v3_get_ext_by_OBJ(x->crl.extensions, obj, lastpos)); -+} -+ -+int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos) -+{ -+ return (X509v3_get_ext_by_critical(x->crl.extensions, crit, lastpos)); -+} -+ -+X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc) -+{ -+ return (X509v3_get_ext(x->crl.extensions, loc)); -+} -+ -+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc) -+{ -+ return (X509v3_delete_ext(x->crl.extensions, loc)); -+} -+ -+void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx) -+{ -+ return X509V3_get_d2i(x->crl.extensions, nid, crit, idx); -+} -+ -+int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, -+ unsigned long flags) -+{ -+ return X509V3_add1_i2d(&x->crl.extensions, nid, value, crit, flags); -+} -+ -+int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc) -+{ -+ return (X509v3_add_ext(&(x->crl.extensions), ex, loc) != NULL); -+} -+ -+int X509_get_ext_count(const X509 *x) -+{ -+ return (X509v3_get_ext_count(x->cert_info.extensions)); -+} -+ -+int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos) -+{ -+ return (X509v3_get_ext_by_NID(x->cert_info.extensions, nid, lastpos)); -+} -+ -+int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos) -+{ -+ return (X509v3_get_ext_by_OBJ(x->cert_info.extensions, obj, lastpos)); -+} -+ -+int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos) -+{ -+ return (X509v3_get_ext_by_critical -+ (x->cert_info.extensions, crit, lastpos)); -+} -+ -+X509_EXTENSION *X509_get_ext(const X509 *x, int loc) -+{ -+ return (X509v3_get_ext(x->cert_info.extensions, loc)); -+} -+ -+X509_EXTENSION *X509_delete_ext(X509 *x, int loc) -+{ -+ return (X509v3_delete_ext(x->cert_info.extensions, loc)); -+} -+ -+int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) -+{ -+ return (X509v3_add_ext(&(x->cert_info.extensions), ex, loc) != NULL); -+} -+ -+void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx) -+{ -+ return X509V3_get_d2i(x->cert_info.extensions, nid, crit, idx); -+} -+ -+int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, -+ unsigned long flags) -+{ -+ return X509V3_add1_i2d(&x->cert_info.extensions, nid, value, crit, -+ flags); -+} -+ -+int X509_REVOKED_get_ext_count(const X509_REVOKED *x) -+{ -+ return (X509v3_get_ext_count(x->extensions)); -+} -+ -+int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos) -+{ -+ return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); -+} -+ -+int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, -+ int lastpos) -+{ -+ return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); -+} -+ -+int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, int lastpos) -+{ -+ return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); -+} -+ -+X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc) -+{ -+ return (X509v3_get_ext(x->extensions, loc)); -+} -+ -+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) -+{ -+ return (X509v3_delete_ext(x->extensions, loc)); -+} -+ -+int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) -+{ -+ return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); -+} -+ -+void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, int *idx) -+{ -+ return X509V3_get_d2i(x->extensions, nid, crit, idx); -+} -+ -+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, -+ unsigned long flags) -+{ -+ return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_lcl.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_lcl.h -new file mode 100644 -index 0000000..40bd102 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_lcl.h -@@ -0,0 +1,142 @@ -+/* -+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * This structure holds all parameters associated with a verify operation by -+ * including an X509_VERIFY_PARAM structure in related structures the -+ * parameters used can be customized -+ */ -+ -+struct X509_VERIFY_PARAM_st { -+ char *name; -+ time_t check_time; /* Time to use */ -+ uint32_t inh_flags; /* Inheritance flags */ -+ unsigned long flags; /* Various verify flags */ -+ int purpose; /* purpose to check untrusted certificates */ -+ int trust; /* trust setting to check */ -+ int depth; /* Verify depth */ -+ int auth_level; /* Security level for chain verification */ -+ STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ -+ /* Peer identity details */ -+ STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */ -+ unsigned int hostflags; /* Flags to control matching features */ -+ char *peername; /* Matching hostname in peer certificate */ -+ char *email; /* If not NULL email address to match */ -+ size_t emaillen; -+ unsigned char *ip; /* If not NULL IP address to match */ -+ size_t iplen; /* Length of IP address */ -+}; -+ -+/* No error callback if depth < 0 */ -+int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth); -+ -+/* a sequence of these are used */ -+struct x509_attributes_st { -+ ASN1_OBJECT *object; -+ STACK_OF(ASN1_TYPE) *set; -+}; -+ -+struct X509_extension_st { -+ ASN1_OBJECT *object; -+ ASN1_BOOLEAN critical; -+ ASN1_OCTET_STRING value; -+}; -+ -+/* -+ * Method to handle CRL access. In general a CRL could be very large (several -+ * Mb) and can consume large amounts of resources if stored in memory by -+ * multiple processes. This method allows general CRL operations to be -+ * redirected to more efficient callbacks: for example a CRL entry database. -+ */ -+ -+#define X509_CRL_METHOD_DYNAMIC 1 -+ -+struct x509_crl_method_st { -+ int flags; -+ int (*crl_init) (X509_CRL *crl); -+ int (*crl_free) (X509_CRL *crl); -+ int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret, -+ ASN1_INTEGER *ser, X509_NAME *issuer); -+ int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk); -+}; -+ -+struct x509_lookup_method_st { -+ const char *name; -+ int (*new_item) (X509_LOOKUP *ctx); -+ void (*free) (X509_LOOKUP *ctx); -+ int (*init) (X509_LOOKUP *ctx); -+ int (*shutdown) (X509_LOOKUP *ctx); -+ int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, -+ char **ret); -+ int (*get_by_subject) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -+ X509_NAME *name, X509_OBJECT *ret); -+ int (*get_by_issuer_serial) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -+ X509_NAME *name, ASN1_INTEGER *serial, -+ X509_OBJECT *ret); -+ int (*get_by_fingerprint) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -+ const unsigned char *bytes, int len, -+ X509_OBJECT *ret); -+ int (*get_by_alias) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -+ const char *str, int len, X509_OBJECT *ret); -+}; -+ -+/* This is the functions plus an instance of the local variables. */ -+struct x509_lookup_st { -+ int init; /* have we been started */ -+ int skip; /* don't use us. */ -+ X509_LOOKUP_METHOD *method; /* the functions */ -+ char *method_data; /* method data */ -+ X509_STORE *store_ctx; /* who owns us */ -+}; -+ -+/* -+ * This is used to hold everything. It is used for all certificate -+ * validation. Once we have a certificate chain, the 'verify' function is -+ * then called to actually check the cert chain. -+ */ -+struct x509_store_st { -+ /* The following is a cache of trusted certs */ -+ int cache; /* if true, stash any hits */ -+ STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ -+ /* These are external lookup methods */ -+ STACK_OF(X509_LOOKUP) *get_cert_methods; -+ X509_VERIFY_PARAM *param; -+ /* Callbacks for various operations */ -+ /* called to verify a certificate */ -+ int (*verify) (X509_STORE_CTX *ctx); -+ /* error callback */ -+ int (*verify_cb) (int ok, X509_STORE_CTX *ctx); -+ /* get issuers cert from ctx */ -+ int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); -+ /* check issued */ -+ int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); -+ /* Check revocation status of chain */ -+ int (*check_revocation) (X509_STORE_CTX *ctx); -+ /* retrieve CRL */ -+ int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); -+ /* Check CRL validity */ -+ int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); -+ /* Check certificate against CRL */ -+ int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); -+ /* Check policy status of the chain */ -+ int (*check_policy) (X509_STORE_CTX *ctx); -+ STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); -+ STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); -+ int (*cleanup) (X509_STORE_CTX *ctx); -+ CRYPTO_EX_DATA ex_data; -+ int references; -+ CRYPTO_RWLOCK *lock; -+}; -+ -+typedef struct lookup_dir_hashes_st BY_DIR_HASH; -+typedef struct lookup_dir_entry_st BY_DIR_ENTRY; -+DEFINE_STACK_OF(BY_DIR_HASH) -+DEFINE_STACK_OF(BY_DIR_ENTRY) -+typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; -+DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY) -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_lu.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_lu.c -new file mode 100644 -index 0000000..952cbfb ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_lu.c -@@ -0,0 +1,861 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include "internal/x509_int.h" -+#include -+#include "x509_lcl.h" -+ -+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) -+{ -+ X509_LOOKUP *ret; -+ -+ ret = OPENSSL_zalloc(sizeof(*ret)); -+ if (ret == NULL) -+ return NULL; -+ -+ ret->method = method; -+ if ((method->new_item != NULL) && !method->new_item(ret)) { -+ OPENSSL_free(ret); -+ return NULL; -+ } -+ return ret; -+} -+ -+void X509_LOOKUP_free(X509_LOOKUP *ctx) -+{ -+ if (ctx == NULL) -+ return; -+ if ((ctx->method != NULL) && (ctx->method->free != NULL)) -+ (*ctx->method->free) (ctx); -+ OPENSSL_free(ctx); -+} -+ -+int X509_STORE_lock(X509_STORE *s) -+{ -+ return CRYPTO_THREAD_write_lock(s->lock); -+} -+ -+int X509_STORE_unlock(X509_STORE *s) -+{ -+ return CRYPTO_THREAD_unlock(s->lock); -+} -+ -+int X509_LOOKUP_init(X509_LOOKUP *ctx) -+{ -+ if (ctx->method == NULL) -+ return 0; -+ if (ctx->method->init != NULL) -+ return ctx->method->init(ctx); -+ else -+ return 1; -+} -+ -+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) -+{ -+ if (ctx->method == NULL) -+ return 0; -+ if (ctx->method->shutdown != NULL) -+ return ctx->method->shutdown(ctx); -+ else -+ return 1; -+} -+ -+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, -+ char **ret) -+{ -+ if (ctx->method == NULL) -+ return -1; -+ if (ctx->method->ctrl != NULL) -+ return ctx->method->ctrl(ctx, cmd, argc, argl, ret); -+ else -+ return 1; -+} -+ -+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -+ X509_NAME *name, X509_OBJECT *ret) -+{ -+ if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) -+ return 0; -+ if (ctx->skip) -+ return 0; -+ return ctx->method->get_by_subject(ctx, type, name, ret); -+} -+ -+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -+ X509_NAME *name, ASN1_INTEGER *serial, -+ X509_OBJECT *ret) -+{ -+ if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) -+ return 0; -+ return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret); -+} -+ -+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -+ const unsigned char *bytes, int len, -+ X509_OBJECT *ret) -+{ -+ if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) -+ return 0; -+ return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret); -+} -+ -+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -+ const char *str, int len, X509_OBJECT *ret) -+{ -+ if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) -+ return 0; -+ return ctx->method->get_by_alias(ctx, type, str, len, ret); -+} -+ -+static int x509_object_cmp(const X509_OBJECT *const *a, -+ const X509_OBJECT *const *b) -+{ -+ int ret; -+ -+ ret = ((*a)->type - (*b)->type); -+ if (ret) -+ return ret; -+ switch ((*a)->type) { -+ case X509_LU_X509: -+ ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); -+ break; -+ case X509_LU_CRL: -+ ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); -+ break; -+ default: -+ /* abort(); */ -+ return 0; -+ } -+ return ret; -+} -+ -+X509_STORE *X509_STORE_new(void) -+{ -+ X509_STORE *ret; -+ -+ if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) -+ return NULL; -+ if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) -+ goto err; -+ ret->cache = 1; -+ if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) -+ goto err; -+ -+ if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) -+ goto err; -+ -+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) -+ goto err; -+ -+ ret->lock = CRYPTO_THREAD_lock_new(); -+ if (ret->lock == NULL) -+ goto err; -+ -+ ret->references = 1; -+ return ret; -+ -+err: -+ X509_VERIFY_PARAM_free(ret->param); -+ sk_X509_OBJECT_free(ret->objs); -+ sk_X509_LOOKUP_free(ret->get_cert_methods); -+ OPENSSL_free(ret); -+ return NULL; -+} -+ -+static void cleanup(X509_OBJECT *a) -+{ -+ if (!a) -+ return; -+ if (a->type == X509_LU_X509) { -+ X509_free(a->data.x509); -+ } else if (a->type == X509_LU_CRL) { -+ X509_CRL_free(a->data.crl); -+ } else { -+ /* abort(); */ -+ } -+ -+ OPENSSL_free(a); -+} -+ -+void X509_STORE_free(X509_STORE *vfy) -+{ -+ int i; -+ STACK_OF(X509_LOOKUP) *sk; -+ X509_LOOKUP *lu; -+ -+ if (vfy == NULL) -+ return; -+ -+ CRYPTO_atomic_add(&vfy->references, -1, &i, vfy->lock); -+ REF_PRINT_COUNT("X509_STORE", vfy); -+ if (i > 0) -+ return; -+ REF_ASSERT_ISNT(i < 0); -+ -+ sk = vfy->get_cert_methods; -+ for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { -+ lu = sk_X509_LOOKUP_value(sk, i); -+ X509_LOOKUP_shutdown(lu); -+ X509_LOOKUP_free(lu); -+ } -+ sk_X509_LOOKUP_free(sk); -+ sk_X509_OBJECT_pop_free(vfy->objs, cleanup); -+ -+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data); -+ X509_VERIFY_PARAM_free(vfy->param); -+ CRYPTO_THREAD_lock_free(vfy->lock); -+ OPENSSL_free(vfy); -+} -+ -+int X509_STORE_up_ref(X509_STORE *vfy) -+{ -+ int i; -+ -+ if (CRYPTO_atomic_add(&vfy->references, 1, &i, vfy->lock) <= 0) -+ return 0; -+ -+ REF_PRINT_COUNT("X509_STORE", a); -+ REF_ASSERT_ISNT(i < 2); -+ return ((i > 1) ? 1 : 0); -+} -+ -+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) -+{ -+ int i; -+ STACK_OF(X509_LOOKUP) *sk; -+ X509_LOOKUP *lu; -+ -+ sk = v->get_cert_methods; -+ for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { -+ lu = sk_X509_LOOKUP_value(sk, i); -+ if (m == lu->method) { -+ return lu; -+ } -+ } -+ /* a new one */ -+ lu = X509_LOOKUP_new(m); -+ if (lu == NULL) -+ return NULL; -+ else { -+ lu->store_ctx = v; -+ if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) -+ return lu; -+ else { -+ X509_LOOKUP_free(lu); -+ return NULL; -+ } -+ } -+} -+ -+X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, -+ X509_LOOKUP_TYPE type, -+ X509_NAME *name) -+{ -+ X509_OBJECT *ret = X509_OBJECT_new(); -+ -+ if (ret == NULL) -+ return NULL; -+ if (!X509_STORE_CTX_get_by_subject(vs, type, name, ret)) { -+ X509_OBJECT_free(ret); -+ return NULL; -+ } -+ return ret; -+} -+ -+int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, -+ X509_NAME *name, X509_OBJECT *ret) -+{ -+ X509_STORE *ctx = vs->ctx; -+ X509_LOOKUP *lu; -+ X509_OBJECT stmp, *tmp; -+ int i, j; -+ -+ CRYPTO_THREAD_write_lock(ctx->lock); -+ tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); -+ CRYPTO_THREAD_unlock(ctx->lock); -+ -+ if (tmp == NULL || type == X509_LU_CRL) { -+ for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { -+ lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); -+ j = X509_LOOKUP_by_subject(lu, type, name, &stmp); -+ if (j) { -+ tmp = &stmp; -+ break; -+ } -+ } -+ if (tmp == NULL) -+ return 0; -+ } -+ -+ ret->type = tmp->type; -+ ret->data.ptr = tmp->data.ptr; -+ -+ X509_OBJECT_up_ref_count(ret); -+ -+ return 1; -+} -+ -+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) -+{ -+ X509_OBJECT *obj; -+ int ret = 1, added = 1; -+ -+ if (x == NULL) -+ return 0; -+ obj = X509_OBJECT_new(); -+ if (obj == NULL) -+ return 0; -+ obj->type = X509_LU_X509; -+ obj->data.x509 = x; -+ X509_OBJECT_up_ref_count(obj); -+ -+ CRYPTO_THREAD_write_lock(ctx->lock); -+ -+ if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { -+ X509err(X509_F_X509_STORE_ADD_CERT, -+ X509_R_CERT_ALREADY_IN_HASH_TABLE); -+ ret = 0; -+ } else { -+ added = sk_X509_OBJECT_push(ctx->objs, obj); -+ ret = added != 0; -+ } -+ -+ CRYPTO_THREAD_unlock(ctx->lock); -+ -+ if (!ret) /* obj not pushed */ -+ X509_OBJECT_free(obj); -+ if (!added) /* on push failure */ -+ X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE); -+ -+ return ret; -+} -+ -+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) -+{ -+ X509_OBJECT *obj; -+ int ret = 1, added = 1; -+ -+ if (x == NULL) -+ return 0; -+ obj = X509_OBJECT_new(); -+ if (obj == NULL) -+ return 0; -+ obj->type = X509_LU_CRL; -+ obj->data.crl = x; -+ X509_OBJECT_up_ref_count(obj); -+ -+ CRYPTO_THREAD_write_lock(ctx->lock); -+ -+ if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { -+ X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE); -+ ret = 0; -+ } else { -+ added = sk_X509_OBJECT_push(ctx->objs, obj); -+ ret = added != 0; -+ } -+ -+ CRYPTO_THREAD_unlock(ctx->lock); -+ -+ if (!ret) /* obj not pushed */ -+ X509_OBJECT_free(obj); -+ if (!added) /* on push failure */ -+ X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE); -+ -+ return ret; -+} -+ -+int X509_OBJECT_up_ref_count(X509_OBJECT *a) -+{ -+ switch (a->type) { -+ default: -+ break; -+ case X509_LU_X509: -+ return X509_up_ref(a->data.x509); -+ case X509_LU_CRL: -+ return X509_CRL_up_ref(a->data.crl); -+ } -+ return 1; -+} -+ -+X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a) -+{ -+ if (a == NULL || a->type != X509_LU_X509) -+ return NULL; -+ return a->data.x509; -+} -+ -+X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *a) -+{ -+ if (a == NULL || a->type != X509_LU_CRL) -+ return NULL; -+ return a->data.crl; -+} -+ -+X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a) -+{ -+ return a->type; -+} -+ -+X509_OBJECT *X509_OBJECT_new() -+{ -+ X509_OBJECT *ret = OPENSSL_zalloc(sizeof(*ret)); -+ -+ if (ret == NULL) { -+ X509err(X509_F_X509_OBJECT_NEW, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ ret->type = X509_LU_NONE; -+ return ret; -+} -+ -+ -+void X509_OBJECT_free(X509_OBJECT *a) -+{ -+ if (a == NULL) -+ return; -+ switch (a->type) { -+ default: -+ break; -+ case X509_LU_X509: -+ X509_free(a->data.x509); -+ break; -+ case X509_LU_CRL: -+ X509_CRL_free(a->data.crl); -+ break; -+ } -+ OPENSSL_free(a); -+} -+ -+static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, -+ X509_NAME *name, int *pnmatch) -+{ -+ X509_OBJECT stmp; -+ X509 x509_s; -+ X509_CRL crl_s; -+ int idx; -+ -+ stmp.type = type; -+ switch (type) { -+ case X509_LU_X509: -+ stmp.data.x509 = &x509_s; -+ x509_s.cert_info.subject = name; -+ break; -+ case X509_LU_CRL: -+ stmp.data.crl = &crl_s; -+ crl_s.crl.issuer = name; -+ break; -+ default: -+ /* abort(); */ -+ return -1; -+ } -+ -+ idx = sk_X509_OBJECT_find(h, &stmp); -+ if (idx >= 0 && pnmatch) { -+ int tidx; -+ const X509_OBJECT *tobj, *pstmp; -+ *pnmatch = 1; -+ pstmp = &stmp; -+ for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) { -+ tobj = sk_X509_OBJECT_value(h, tidx); -+ if (x509_object_cmp(&tobj, &pstmp)) -+ break; -+ (*pnmatch)++; -+ } -+ } -+ return idx; -+} -+ -+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, -+ X509_NAME *name) -+{ -+ return x509_object_idx_cnt(h, type, name, NULL); -+} -+ -+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, -+ X509_LOOKUP_TYPE type, -+ X509_NAME *name) -+{ -+ int idx; -+ idx = X509_OBJECT_idx_by_subject(h, type, name); -+ if (idx == -1) -+ return NULL; -+ return sk_X509_OBJECT_value(h, idx); -+} -+ -+STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v) -+{ -+ return v->objs; -+} -+ -+STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) -+{ -+ int i, idx, cnt; -+ STACK_OF(X509) *sk = NULL; -+ X509 *x; -+ X509_OBJECT *obj; -+ -+ CRYPTO_THREAD_write_lock(ctx->ctx->lock); -+ idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); -+ if (idx < 0) { -+ /* -+ * Nothing found in cache: do lookup to possibly add new objects to -+ * cache -+ */ -+ X509_OBJECT *xobj = X509_OBJECT_new(); -+ -+ CRYPTO_THREAD_unlock(ctx->ctx->lock); -+ if (xobj == NULL) -+ return NULL; -+ if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) { -+ X509_OBJECT_free(xobj); -+ return NULL; -+ } -+ X509_OBJECT_free(xobj); -+ CRYPTO_THREAD_write_lock(ctx->ctx->lock); -+ idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); -+ if (idx < 0) { -+ CRYPTO_THREAD_unlock(ctx->ctx->lock); -+ return NULL; -+ } -+ } -+ -+ sk = sk_X509_new_null(); -+ for (i = 0; i < cnt; i++, idx++) { -+ obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); -+ x = obj->data.x509; -+ X509_up_ref(x); -+ if (!sk_X509_push(sk, x)) { -+ CRYPTO_THREAD_unlock(ctx->ctx->lock); -+ X509_free(x); -+ sk_X509_pop_free(sk, X509_free); -+ return NULL; -+ } -+ } -+ CRYPTO_THREAD_unlock(ctx->ctx->lock); -+ return sk; -+} -+ -+STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) -+{ -+ int i, idx, cnt; -+ STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null(); -+ X509_CRL *x; -+ X509_OBJECT *obj, *xobj = X509_OBJECT_new(); -+ -+ /* Always do lookup to possibly add new CRLs to cache */ -+ if (sk == NULL || xobj == NULL || -+ !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) { -+ X509_OBJECT_free(xobj); -+ sk_X509_CRL_free(sk); -+ return NULL; -+ } -+ X509_OBJECT_free(xobj); -+ CRYPTO_THREAD_write_lock(ctx->ctx->lock); -+ idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); -+ if (idx < 0) { -+ CRYPTO_THREAD_unlock(ctx->ctx->lock); -+ sk_X509_CRL_free(sk); -+ return NULL; -+ } -+ -+ for (i = 0; i < cnt; i++, idx++) { -+ obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); -+ x = obj->data.crl; -+ X509_CRL_up_ref(x); -+ if (!sk_X509_CRL_push(sk, x)) { -+ CRYPTO_THREAD_unlock(ctx->ctx->lock); -+ X509_CRL_free(x); -+ sk_X509_CRL_pop_free(sk, X509_CRL_free); -+ return NULL; -+ } -+ } -+ CRYPTO_THREAD_unlock(ctx->ctx->lock); -+ return sk; -+} -+ -+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, -+ X509_OBJECT *x) -+{ -+ int idx, i; -+ X509_OBJECT *obj; -+ idx = sk_X509_OBJECT_find(h, x); -+ if (idx == -1) -+ return NULL; -+ if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) -+ return sk_X509_OBJECT_value(h, idx); -+ for (i = idx; i < sk_X509_OBJECT_num(h); i++) { -+ obj = sk_X509_OBJECT_value(h, i); -+ if (x509_object_cmp -+ ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) -+ return NULL; -+ if (x->type == X509_LU_X509) { -+ if (!X509_cmp(obj->data.x509, x->data.x509)) -+ return obj; -+ } else if (x->type == X509_LU_CRL) { -+ if (!X509_CRL_match(obj->data.crl, x->data.crl)) -+ return obj; -+ } else -+ return obj; -+ } -+ return NULL; -+} -+ -+/*- -+ * Try to get issuer certificate from store. Due to limitations -+ * of the API this can only retrieve a single certificate matching -+ * a given subject name. However it will fill the cache with all -+ * matching certificates, so we can examine the cache for all -+ * matches. -+ * -+ * Return values are: -+ * 1 lookup successful. -+ * 0 certificate not found. -+ * -1 some other error. -+ */ -+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) -+{ -+ X509_NAME *xn; -+ X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL; -+ int i, ok, idx, ret; -+ -+ if (obj == NULL) -+ return -1; -+ *issuer = NULL; -+ xn = X509_get_issuer_name(x); -+ ok = X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, xn, obj); -+ if (ok != 1) { -+ X509_OBJECT_free(obj); -+ return 0; -+ } -+ /* If certificate matches all OK */ -+ if (ctx->check_issued(ctx, x, obj->data.x509)) { -+ if (x509_check_cert_time(ctx, obj->data.x509, -1)) { -+ *issuer = obj->data.x509; -+ X509_up_ref(*issuer); -+ X509_OBJECT_free(obj); -+ return 1; -+ } -+ } -+ X509_OBJECT_free(obj); -+ -+ /* Else find index of first cert accepted by 'check_issued' */ -+ ret = 0; -+ CRYPTO_THREAD_write_lock(ctx->ctx->lock); -+ idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); -+ if (idx != -1) { /* should be true as we've had at least one -+ * match */ -+ /* Look through all matching certs for suitable issuer */ -+ for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { -+ pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); -+ /* See if we've run past the matches */ -+ if (pobj->type != X509_LU_X509) -+ break; -+ if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) -+ break; -+ if (ctx->check_issued(ctx, x, pobj->data.x509)) { -+ *issuer = pobj->data.x509; -+ ret = 1; -+ /* -+ * If times check, exit with match, -+ * otherwise keep looking. Leave last -+ * match in issuer so we return nearest -+ * match if no certificate time is OK. -+ */ -+ -+ if (x509_check_cert_time(ctx, *issuer, -1)) -+ break; -+ } -+ } -+ } -+ CRYPTO_THREAD_unlock(ctx->ctx->lock); -+ if (*issuer) -+ X509_up_ref(*issuer); -+ return ret; -+} -+ -+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) -+{ -+ return X509_VERIFY_PARAM_set_flags(ctx->param, flags); -+} -+ -+int X509_STORE_set_depth(X509_STORE *ctx, int depth) -+{ -+ X509_VERIFY_PARAM_set_depth(ctx->param, depth); -+ return 1; -+} -+ -+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) -+{ -+ return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); -+} -+ -+int X509_STORE_set_trust(X509_STORE *ctx, int trust) -+{ -+ return X509_VERIFY_PARAM_set_trust(ctx->param, trust); -+} -+ -+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) -+{ -+ return X509_VERIFY_PARAM_set1(ctx->param, param); -+} -+ -+X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) -+{ -+ return ctx->param; -+} -+ -+void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify) -+{ -+ ctx->verify = verify; -+} -+ -+X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx) -+{ -+ return ctx->verify; -+} -+ -+void X509_STORE_set_verify_cb(X509_STORE *ctx, -+ X509_STORE_CTX_verify_cb verify_cb) -+{ -+ ctx->verify_cb = verify_cb; -+} -+ -+X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx) -+{ -+ return ctx->verify_cb; -+} -+ -+void X509_STORE_set_get_issuer(X509_STORE *ctx, -+ X509_STORE_CTX_get_issuer_fn get_issuer) -+{ -+ ctx->get_issuer = get_issuer; -+} -+ -+X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx) -+{ -+ return ctx->get_issuer; -+} -+ -+void X509_STORE_set_check_issued(X509_STORE *ctx, -+ X509_STORE_CTX_check_issued_fn check_issued) -+{ -+ ctx->check_issued = check_issued; -+} -+ -+X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx) -+{ -+ return ctx->check_issued; -+} -+ -+void X509_STORE_set_check_revocation(X509_STORE *ctx, -+ X509_STORE_CTX_check_revocation_fn check_revocation) -+{ -+ ctx->check_revocation = check_revocation; -+} -+ -+X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx) -+{ -+ return ctx->check_revocation; -+} -+ -+void X509_STORE_set_get_crl(X509_STORE *ctx, -+ X509_STORE_CTX_get_crl_fn get_crl) -+{ -+ ctx->get_crl = get_crl; -+} -+ -+X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx) -+{ -+ return ctx->get_crl; -+} -+ -+void X509_STORE_set_check_crl(X509_STORE *ctx, -+ X509_STORE_CTX_check_crl_fn check_crl) -+{ -+ ctx->check_crl = check_crl; -+} -+ -+X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx) -+{ -+ return ctx->check_crl; -+} -+ -+void X509_STORE_set_cert_crl(X509_STORE *ctx, -+ X509_STORE_CTX_cert_crl_fn cert_crl) -+{ -+ ctx->cert_crl = cert_crl; -+} -+ -+X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx) -+{ -+ return ctx->cert_crl; -+} -+ -+void X509_STORE_set_check_policy(X509_STORE *ctx, -+ X509_STORE_CTX_check_policy_fn check_policy) -+{ -+ ctx->check_policy = check_policy; -+} -+ -+X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(X509_STORE *ctx) -+{ -+ return ctx->check_policy; -+} -+ -+void X509_STORE_set_lookup_certs(X509_STORE *ctx, -+ X509_STORE_CTX_lookup_certs_fn lookup_certs) -+{ -+ ctx->lookup_certs = lookup_certs; -+} -+ -+X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx) -+{ -+ return ctx->lookup_certs; -+} -+ -+void X509_STORE_set_lookup_crls(X509_STORE *ctx, -+ X509_STORE_CTX_lookup_crls_fn lookup_crls) -+{ -+ ctx->lookup_crls = lookup_crls; -+} -+ -+X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx) -+{ -+ return ctx->lookup_crls; -+} -+ -+void X509_STORE_set_cleanup(X509_STORE *ctx, -+ X509_STORE_CTX_cleanup_fn ctx_cleanup) -+{ -+ ctx->cleanup = ctx_cleanup; -+} -+ -+X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx) -+{ -+ return ctx->cleanup; -+} -+ -+int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data) -+{ -+ return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); -+} -+ -+void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx) -+{ -+ return CRYPTO_get_ex_data(&ctx->ex_data, idx); -+} -+ -+X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) -+{ -+ return ctx->ctx; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_obj.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_obj.c -new file mode 100644 -index 0000000..55dc778 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_obj.c -@@ -0,0 +1,182 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+ -+/* -+ * Limit to ensure we don't overflow: much greater than -+ * anything encountered in practice. -+ */ -+ -+#define NAME_ONELINE_MAX (1024 * 1024) -+ -+char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) -+{ -+ const X509_NAME_ENTRY *ne; -+ int i; -+ int n, lold, l, l1, l2, num, j, type; -+ const char *s; -+ char *p; -+ unsigned char *q; -+ BUF_MEM *b = NULL; -+ static const char hex[17] = "0123456789ABCDEF"; -+ int gs_doit[4]; -+ char tmp_buf[80]; -+#ifdef CHARSET_EBCDIC -+ unsigned char ebcdic_buf[1024]; -+#endif -+ -+ if (buf == NULL) { -+ if ((b = BUF_MEM_new()) == NULL) -+ goto err; -+ if (!BUF_MEM_grow(b, 200)) -+ goto err; -+ b->data[0] = '\0'; -+ len = 200; -+ } else if (len == 0) { -+ return NULL; -+ } -+ if (a == NULL) { -+ if (b) { -+ buf = b->data; -+ OPENSSL_free(b); -+ } -+ strncpy(buf, "NO X509_NAME", len); -+ buf[len - 1] = '\0'; -+ return buf; -+ } -+ -+ len--; /* space for '\0' */ -+ l = 0; -+ for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { -+ ne = sk_X509_NAME_ENTRY_value(a->entries, i); -+ n = OBJ_obj2nid(ne->object); -+ if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { -+ i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); -+ s = tmp_buf; -+ } -+ l1 = strlen(s); -+ -+ type = ne->value->type; -+ num = ne->value->length; -+ if (num > NAME_ONELINE_MAX) { -+ X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); -+ goto end; -+ } -+ q = ne->value->data; -+#ifdef CHARSET_EBCDIC -+ if (type == V_ASN1_GENERALSTRING || -+ type == V_ASN1_VISIBLESTRING || -+ type == V_ASN1_PRINTABLESTRING || -+ type == V_ASN1_TELETEXSTRING || -+ type == V_ASN1_IA5STRING) { -+ if (num > (int)sizeof(ebcdic_buf)) -+ num = sizeof(ebcdic_buf); -+ ascii2ebcdic(ebcdic_buf, q, num); -+ q = ebcdic_buf; -+ } -+#endif -+ -+ if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { -+ gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; -+ for (j = 0; j < num; j++) -+ if (q[j] != 0) -+ gs_doit[j & 3] = 1; -+ -+ if (gs_doit[0] | gs_doit[1] | gs_doit[2]) -+ gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; -+ else { -+ gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; -+ gs_doit[3] = 1; -+ } -+ } else -+ gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; -+ -+ for (l2 = j = 0; j < num; j++) { -+ if (!gs_doit[j & 3]) -+ continue; -+ l2++; -+#ifndef CHARSET_EBCDIC -+ if ((q[j] < ' ') || (q[j] > '~')) -+ l2 += 3; -+#else -+ if ((os_toascii[q[j]] < os_toascii[' ']) || -+ (os_toascii[q[j]] > os_toascii['~'])) -+ l2 += 3; -+#endif -+ } -+ -+ lold = l; -+ l += 1 + l1 + 1 + l2; -+ if (l > NAME_ONELINE_MAX) { -+ X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); -+ goto end; -+ } -+ if (b != NULL) { -+ if (!BUF_MEM_grow(b, l + 1)) -+ goto err; -+ p = &(b->data[lold]); -+ } else if (l > len) { -+ break; -+ } else -+ p = &(buf[lold]); -+ *(p++) = '/'; -+ memcpy(p, s, (unsigned int)l1); -+ p += l1; -+ *(p++) = '='; -+ -+#ifndef CHARSET_EBCDIC /* q was assigned above already. */ -+ q = ne->value->data; -+#endif -+ -+ for (j = 0; j < num; j++) { -+ if (!gs_doit[j & 3]) -+ continue; -+#ifndef CHARSET_EBCDIC -+ n = q[j]; -+ if ((n < ' ') || (n > '~')) { -+ *(p++) = '\\'; -+ *(p++) = 'x'; -+ *(p++) = hex[(n >> 4) & 0x0f]; -+ *(p++) = hex[n & 0x0f]; -+ } else -+ *(p++) = n; -+#else -+ n = os_toascii[q[j]]; -+ if ((n < os_toascii[' ']) || (n > os_toascii['~'])) { -+ *(p++) = '\\'; -+ *(p++) = 'x'; -+ *(p++) = hex[(n >> 4) & 0x0f]; -+ *(p++) = hex[n & 0x0f]; -+ } else -+ *(p++) = q[j]; -+#endif -+ } -+ *p = '\0'; -+ } -+ if (b != NULL) { -+ p = b->data; -+ OPENSSL_free(b); -+ } else -+ p = buf; -+ if (i == 0) -+ *p = '\0'; -+ return (p); -+ err: -+ X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE); -+ end: -+ BUF_MEM_free(b); -+ return (NULL); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_r2x.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_r2x.c -new file mode 100644 -index 0000000..3d72787 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_r2x.c -@@ -0,0 +1,67 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+#include -+#include -+ -+X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) -+{ -+ X509 *ret = NULL; -+ X509_CINF *xi = NULL; -+ X509_NAME *xn; -+ EVP_PKEY *pubkey = NULL; -+ -+ if ((ret = X509_new()) == NULL) { -+ X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ /* duplicate the request */ -+ xi = &ret->cert_info; -+ -+ if (sk_X509_ATTRIBUTE_num(r->req_info.attributes) != 0) { -+ if ((xi->version = ASN1_INTEGER_new()) == NULL) -+ goto err; -+ if (!ASN1_INTEGER_set(xi->version, 2)) -+ goto err; -+/*- xi->extensions=ri->attributes; <- bad, should not ever be done -+ ri->attributes=NULL; */ -+ } -+ -+ xn = X509_REQ_get_subject_name(r); -+ if (X509_set_subject_name(ret, xn) == 0) -+ goto err; -+ if (X509_set_issuer_name(ret, xn) == 0) -+ goto err; -+ -+ if (X509_gmtime_adj(xi->validity.notBefore, 0) == NULL) -+ goto err; -+ if (X509_gmtime_adj(xi->validity.notAfter, (long)60 * 60 * 24 * days) == -+ NULL) -+ goto err; -+ -+ pubkey = X509_REQ_get0_pubkey(r); -+ if (pubkey == NULL || !X509_set_pubkey(ret, pubkey)) -+ goto err; -+ -+ if (!X509_sign(ret, pkey, EVP_md5())) -+ goto err; -+ return ret; -+ -+ err: -+ X509_free(ret); -+ return NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_req.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_req.c -new file mode 100644 -index 0000000..7b88dbc ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_req.c -@@ -0,0 +1,298 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+#include -+#include -+#include -+ -+X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) -+{ -+ X509_REQ *ret; -+ X509_REQ_INFO *ri; -+ int i; -+ EVP_PKEY *pktmp; -+ -+ ret = X509_REQ_new(); -+ if (ret == NULL) { -+ X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ ri = &ret->req_info; -+ -+ ri->version->length = 1; -+ ri->version->data = OPENSSL_malloc(1); -+ if (ri->version->data == NULL) -+ goto err; -+ ri->version->data[0] = 0; /* version == 0 */ -+ -+ if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x))) -+ goto err; -+ -+ pktmp = X509_get0_pubkey(x); -+ if (pktmp == NULL) -+ goto err; -+ i = X509_REQ_set_pubkey(ret, pktmp); -+ if (!i) -+ goto err; -+ -+ if (pkey != NULL) { -+ if (!X509_REQ_sign(ret, pkey, md)) -+ goto err; -+ } -+ return (ret); -+ err: -+ X509_REQ_free(ret); -+ return (NULL); -+} -+ -+EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) -+{ -+ if (req == NULL) -+ return (NULL); -+ return (X509_PUBKEY_get(req->req_info.pubkey)); -+} -+ -+EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req) -+{ -+ if (req == NULL) -+ return NULL; -+ return (X509_PUBKEY_get0(req->req_info.pubkey)); -+} -+ -+X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req) -+{ -+ return req->req_info.pubkey; -+} -+ -+int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) -+{ -+ EVP_PKEY *xk = NULL; -+ int ok = 0; -+ -+ xk = X509_REQ_get_pubkey(x); -+ switch (EVP_PKEY_cmp(xk, k)) { -+ case 1: -+ ok = 1; -+ break; -+ case 0: -+ X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, -+ X509_R_KEY_VALUES_MISMATCH); -+ break; -+ case -1: -+ X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); -+ break; -+ case -2: -+#ifndef OPENSSL_NO_EC -+ if (EVP_PKEY_id(k) == EVP_PKEY_EC) { -+ X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); -+ break; -+ } -+#endif -+#ifndef OPENSSL_NO_DH -+ if (EVP_PKEY_id(k) == EVP_PKEY_DH) { -+ /* No idea */ -+ X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, -+ X509_R_CANT_CHECK_DH_KEY); -+ break; -+ } -+#endif -+ X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); -+ } -+ -+ EVP_PKEY_free(xk); -+ return (ok); -+} -+ -+/* -+ * It seems several organisations had the same idea of including a list of -+ * extensions in a certificate request. There are at least two OIDs that are -+ * used and there may be more: so the list is configurable. -+ */ -+ -+static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef }; -+ -+static int *ext_nids = ext_nid_list; -+ -+int X509_REQ_extension_nid(int req_nid) -+{ -+ int i, nid; -+ for (i = 0;; i++) { -+ nid = ext_nids[i]; -+ if (nid == NID_undef) -+ return 0; -+ else if (req_nid == nid) -+ return 1; -+ } -+} -+ -+int *X509_REQ_get_extension_nids(void) -+{ -+ return ext_nids; -+} -+ -+void X509_REQ_set_extension_nids(int *nids) -+{ -+ ext_nids = nids; -+} -+ -+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) -+{ -+ X509_ATTRIBUTE *attr; -+ ASN1_TYPE *ext = NULL; -+ int idx, *pnid; -+ const unsigned char *p; -+ -+ if ((req == NULL) || !ext_nids) -+ return (NULL); -+ for (pnid = ext_nids; *pnid != NID_undef; pnid++) { -+ idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); -+ if (idx == -1) -+ continue; -+ attr = X509_REQ_get_attr(req, idx); -+ ext = X509_ATTRIBUTE_get0_type(attr, 0); -+ break; -+ } -+ if (!ext || (ext->type != V_ASN1_SEQUENCE)) -+ return NULL; -+ p = ext->value.sequence->data; -+ return (STACK_OF(X509_EXTENSION) *) -+ ASN1_item_d2i(NULL, &p, ext->value.sequence->length, -+ ASN1_ITEM_rptr(X509_EXTENSIONS)); -+} -+ -+/* -+ * Add a STACK_OF extensions to a certificate request: allow alternative OIDs -+ * in case we want to create a non standard one. -+ */ -+ -+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, -+ int nid) -+{ -+ int extlen; -+ int rv = 0; -+ unsigned char *ext = NULL; -+ /* Generate encoding of extensions */ -+ extlen = ASN1_item_i2d((ASN1_VALUE *)exts, &ext, -+ ASN1_ITEM_rptr(X509_EXTENSIONS)); -+ if (extlen <= 0) -+ return 0; -+ rv = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen); -+ OPENSSL_free(ext); -+ return rv; -+} -+ -+/* This is the normal usage: use the "official" OID */ -+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) -+{ -+ return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); -+} -+ -+/* Request attribute functions */ -+ -+int X509_REQ_get_attr_count(const X509_REQ *req) -+{ -+ return X509at_get_attr_count(req->req_info.attributes); -+} -+ -+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) -+{ -+ return X509at_get_attr_by_NID(req->req_info.attributes, nid, lastpos); -+} -+ -+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, -+ int lastpos) -+{ -+ return X509at_get_attr_by_OBJ(req->req_info.attributes, obj, lastpos); -+} -+ -+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) -+{ -+ return X509at_get_attr(req->req_info.attributes, loc); -+} -+ -+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) -+{ -+ return X509at_delete_attr(req->req_info.attributes, loc); -+} -+ -+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) -+{ -+ if (X509at_add1_attr(&req->req_info.attributes, attr)) -+ return 1; -+ return 0; -+} -+ -+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, -+ const ASN1_OBJECT *obj, int type, -+ const unsigned char *bytes, int len) -+{ -+ if (X509at_add1_attr_by_OBJ(&req->req_info.attributes, obj, -+ type, bytes, len)) -+ return 1; -+ return 0; -+} -+ -+int X509_REQ_add1_attr_by_NID(X509_REQ *req, -+ int nid, int type, -+ const unsigned char *bytes, int len) -+{ -+ if (X509at_add1_attr_by_NID(&req->req_info.attributes, nid, -+ type, bytes, len)) -+ return 1; -+ return 0; -+} -+ -+int X509_REQ_add1_attr_by_txt(X509_REQ *req, -+ const char *attrname, int type, -+ const unsigned char *bytes, int len) -+{ -+ if (X509at_add1_attr_by_txt(&req->req_info.attributes, attrname, -+ type, bytes, len)) -+ return 1; -+ return 0; -+} -+ -+long X509_REQ_get_version(const X509_REQ *req) -+{ -+ return ASN1_INTEGER_get(req->req_info.version); -+} -+ -+X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req) -+{ -+ return req->req_info.subject; -+} -+ -+void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, -+ const X509_ALGOR **palg) -+{ -+ if (psig != NULL) -+ *psig = req->signature; -+ if (palg != NULL) -+ *palg = &req->sig_alg; -+} -+ -+int X509_REQ_get_signature_nid(const X509_REQ *req) -+{ -+ return OBJ_obj2nid(req->sig_alg.algorithm); -+} -+ -+int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) -+{ -+ req->req_info.enc.modified = 1; -+ return i2d_X509_REQ_INFO(&req->req_info, pp); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_set.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_set.c -new file mode 100644 -index 0000000..c0ea418 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_set.c -@@ -0,0 +1,159 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+ -+int X509_set_version(X509 *x, long version) -+{ -+ if (x == NULL) -+ return (0); -+ if (version == 0) { -+ ASN1_INTEGER_free(x->cert_info.version); -+ x->cert_info.version = NULL; -+ return (1); -+ } -+ if (x->cert_info.version == NULL) { -+ if ((x->cert_info.version = ASN1_INTEGER_new()) == NULL) -+ return (0); -+ } -+ return (ASN1_INTEGER_set(x->cert_info.version, version)); -+} -+ -+int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) -+{ -+ ASN1_INTEGER *in; -+ -+ if (x == NULL) -+ return 0; -+ in = &x->cert_info.serialNumber; -+ if (in != serial) -+ return ASN1_STRING_copy(in, serial); -+ return 1; -+} -+ -+int X509_set_issuer_name(X509 *x, X509_NAME *name) -+{ -+ if (x == NULL) -+ return (0); -+ return (X509_NAME_set(&x->cert_info.issuer, name)); -+} -+ -+int X509_set_subject_name(X509 *x, X509_NAME *name) -+{ -+ if (x == NULL) -+ return (0); -+ return (X509_NAME_set(&x->cert_info.subject, name)); -+} -+ -+int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm) -+{ -+ ASN1_TIME *in; -+ in = *ptm; -+ if (in != tm) { -+ in = ASN1_STRING_dup(tm); -+ if (in != NULL) { -+ ASN1_TIME_free(*ptm); -+ *ptm = in; -+ } -+ } -+ return (in != NULL); -+} -+ -+int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) -+{ -+ if (x == NULL) -+ return 0; -+ return x509_set1_time(&x->cert_info.validity.notBefore, tm); -+} -+ -+int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) -+{ -+ if (x == NULL) -+ return 0; -+ return x509_set1_time(&x->cert_info.validity.notAfter, tm); -+} -+ -+int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) -+{ -+ if (x == NULL) -+ return (0); -+ return (X509_PUBKEY_set(&(x->cert_info.key), pkey)); -+} -+ -+int X509_up_ref(X509 *x) -+{ -+ int i; -+ -+ if (CRYPTO_atomic_add(&x->references, 1, &i, x->lock) <= 0) -+ return 0; -+ -+ REF_PRINT_COUNT("X509", x); -+ REF_ASSERT_ISNT(i < 2); -+ return ((i > 1) ? 1 : 0); -+} -+ -+long X509_get_version(const X509 *x) -+{ -+ return ASN1_INTEGER_get(x->cert_info.version); -+} -+ -+const ASN1_TIME *X509_get0_notBefore(const X509 *x) -+{ -+ return x->cert_info.validity.notBefore; -+} -+ -+const ASN1_TIME *X509_get0_notAfter(const X509 *x) -+{ -+ return x->cert_info.validity.notAfter; -+} -+ -+ASN1_TIME *X509_getm_notBefore(const X509 *x) -+{ -+ return x->cert_info.validity.notBefore; -+} -+ -+ASN1_TIME *X509_getm_notAfter(const X509 *x) -+{ -+ return x->cert_info.validity.notAfter; -+} -+ -+int X509_get_signature_type(const X509 *x) -+{ -+ return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg.algorithm)); -+} -+ -+X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x) -+{ -+ return x->cert_info.key; -+} -+ -+const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x) -+{ -+ return x->cert_info.extensions; -+} -+ -+void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid, -+ const ASN1_BIT_STRING **psuid) -+{ -+ if (piuid != NULL) -+ *piuid = x->cert_info.issuerUID; -+ if (psuid != NULL) -+ *psuid = x->cert_info.subjectUID; -+} -+ -+const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) -+{ -+ return &x->cert_info.signature; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_trs.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_trs.c -new file mode 100644 -index 0000000..a9bb88d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_trs.c -@@ -0,0 +1,298 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include "internal/x509_int.h" -+ -+static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b); -+static void trtable_free(X509_TRUST *p); -+ -+static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); -+static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); -+static int trust_compat(X509_TRUST *trust, X509 *x, int flags); -+ -+static int obj_trust(int id, X509 *x, int flags); -+static int (*default_trust) (int id, X509 *x, int flags) = obj_trust; -+ -+/* -+ * WARNING: the following table should be kept in order of trust and without -+ * any gaps so we can just subtract the minimum trust value to get an index -+ * into the table -+ */ -+ -+static X509_TRUST trstandard[] = { -+ {X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL}, -+ {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, -+ NULL}, -+ {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, -+ NULL}, -+ {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, -+ NULL}, -+ {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, -+ NULL}, -+ {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, -+ NULL}, -+ {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, -+ NULL}, -+ {X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL} -+}; -+ -+#define X509_TRUST_COUNT OSSL_NELEM(trstandard) -+ -+static STACK_OF(X509_TRUST) *trtable = NULL; -+ -+static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b) -+{ -+ return (*a)->trust - (*b)->trust; -+} -+ -+int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, -+ int) { -+ int (*oldtrust) (int, X509 *, int); -+ oldtrust = default_trust; -+ default_trust = trust; -+ return oldtrust; -+} -+ -+int X509_check_trust(X509 *x, int id, int flags) -+{ -+ X509_TRUST *pt; -+ int idx; -+ -+ /* We get this as a default value */ -+ if (id == X509_TRUST_DEFAULT) -+ return obj_trust(NID_anyExtendedKeyUsage, x, -+ flags | X509_TRUST_DO_SS_COMPAT); -+ idx = X509_TRUST_get_by_id(id); -+ if (idx == -1) -+ return default_trust(id, x, flags); -+ pt = X509_TRUST_get0(idx); -+ return pt->check_trust(pt, x, flags); -+} -+ -+int X509_TRUST_get_count(void) -+{ -+ if (!trtable) -+ return X509_TRUST_COUNT; -+ return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; -+} -+ -+X509_TRUST *X509_TRUST_get0(int idx) -+{ -+ if (idx < 0) -+ return NULL; -+ if (idx < (int)X509_TRUST_COUNT) -+ return trstandard + idx; -+ return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); -+} -+ -+int X509_TRUST_get_by_id(int id) -+{ -+ X509_TRUST tmp; -+ int idx; -+ if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) -+ return id - X509_TRUST_MIN; -+ tmp.trust = id; -+ if (!trtable) -+ return -1; -+ idx = sk_X509_TRUST_find(trtable, &tmp); -+ if (idx == -1) -+ return -1; -+ return idx + X509_TRUST_COUNT; -+} -+ -+int X509_TRUST_set(int *t, int trust) -+{ -+ if (X509_TRUST_get_by_id(trust) == -1) { -+ X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST); -+ return 0; -+ } -+ *t = trust; -+ return 1; -+} -+ -+int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), -+ const char *name, int arg1, void *arg2) -+{ -+ int idx; -+ X509_TRUST *trtmp; -+ /* -+ * This is set according to what we change: application can't set it -+ */ -+ flags &= ~X509_TRUST_DYNAMIC; -+ /* This will always be set for application modified trust entries */ -+ flags |= X509_TRUST_DYNAMIC_NAME; -+ /* Get existing entry if any */ -+ idx = X509_TRUST_get_by_id(id); -+ /* Need a new entry */ -+ if (idx == -1) { -+ if ((trtmp = OPENSSL_malloc(sizeof(*trtmp))) == NULL) { -+ X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ trtmp->flags = X509_TRUST_DYNAMIC; -+ } else -+ trtmp = X509_TRUST_get0(idx); -+ -+ /* OPENSSL_free existing name if dynamic */ -+ if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) -+ OPENSSL_free(trtmp->name); -+ /* dup supplied name */ -+ if ((trtmp->name = OPENSSL_strdup(name)) == NULL) { -+ X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ /* Keep the dynamic flag of existing entry */ -+ trtmp->flags &= X509_TRUST_DYNAMIC; -+ /* Set all other flags */ -+ trtmp->flags |= flags; -+ -+ trtmp->trust = id; -+ trtmp->check_trust = ck; -+ trtmp->arg1 = arg1; -+ trtmp->arg2 = arg2; -+ -+ /* If its a new entry manage the dynamic table */ -+ if (idx == -1) { -+ if (trtable == NULL -+ && (trtable = sk_X509_TRUST_new(tr_cmp)) == NULL) { -+ X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); -+ goto err;; -+ } -+ if (!sk_X509_TRUST_push(trtable, trtmp)) { -+ X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } -+ return 1; -+ err: -+ if (idx == -1) { -+ OPENSSL_free(trtmp->name); -+ OPENSSL_free(trtmp); -+ } -+ return 0; -+} -+ -+static void trtable_free(X509_TRUST *p) -+{ -+ if (!p) -+ return; -+ if (p->flags & X509_TRUST_DYNAMIC) { -+ if (p->flags & X509_TRUST_DYNAMIC_NAME) -+ OPENSSL_free(p->name); -+ OPENSSL_free(p); -+ } -+} -+ -+void X509_TRUST_cleanup(void) -+{ -+ sk_X509_TRUST_pop_free(trtable, trtable_free); -+ trtable = NULL; -+} -+ -+int X509_TRUST_get_flags(const X509_TRUST *xp) -+{ -+ return xp->flags; -+} -+ -+char *X509_TRUST_get0_name(const X509_TRUST *xp) -+{ -+ return xp->name; -+} -+ -+int X509_TRUST_get_trust(const X509_TRUST *xp) -+{ -+ return xp->trust; -+} -+ -+static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) -+{ -+ /* -+ * Declare the chain verified if the desired trust OID is not rejected in -+ * any auxiliary trust info for this certificate, and the OID is either -+ * expressly trusted, or else either "anyEKU" is trusted, or the -+ * certificate is self-signed. -+ */ -+ flags |= X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU; -+ return obj_trust(trust->arg1, x, flags); -+} -+ -+static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) -+{ -+ /* -+ * Declare the chain verified only if the desired trust OID is not -+ * rejected and is expressly trusted. Neither "anyEKU" nor "compat" -+ * trust in self-signed certificates apply. -+ */ -+ flags &= ~(X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU); -+ return obj_trust(trust->arg1, x, flags); -+} -+ -+static int trust_compat(X509_TRUST *trust, X509 *x, int flags) -+{ -+ /* Call for side-effect of computing hash and caching extensions */ -+ X509_check_purpose(x, -1, 0); -+ if ((flags & X509_TRUST_NO_SS_COMPAT) == 0 && x->ex_flags & EXFLAG_SS) -+ return X509_TRUST_TRUSTED; -+ else -+ return X509_TRUST_UNTRUSTED; -+} -+ -+static int obj_trust(int id, X509 *x, int flags) -+{ -+ X509_CERT_AUX *ax = x->aux; -+ int i; -+ -+ if (ax && ax->reject) { -+ for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { -+ ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->reject, i); -+ int nid = OBJ_obj2nid(obj); -+ -+ if (nid == id || (nid == NID_anyExtendedKeyUsage && -+ (flags & X509_TRUST_OK_ANY_EKU))) -+ return X509_TRUST_REJECTED; -+ } -+ } -+ -+ if (ax && ax->trust) { -+ for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { -+ ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->trust, i); -+ int nid = OBJ_obj2nid(obj); -+ -+ if (nid == id || (nid == NID_anyExtendedKeyUsage && -+ (flags & X509_TRUST_OK_ANY_EKU))) -+ return X509_TRUST_TRUSTED; -+ } -+ /* -+ * Reject when explicit trust EKU are set and none match. -+ * -+ * Returning untrusted is enough for for full chains that end in -+ * self-signed roots, because when explicit trust is specified it -+ * suppresses the default blanket trust of self-signed objects. -+ * -+ * But for partial chains, this is not enough, because absent a similar -+ * trust-self-signed policy, non matching EKUs are indistinguishable -+ * from lack of EKU constraints. -+ * -+ * Therefore, failure to match any trusted purpose must trigger an -+ * explicit reject. -+ */ -+ return X509_TRUST_REJECTED; -+ } -+ -+ if ((flags & X509_TRUST_DO_SS_COMPAT) == 0) -+ return X509_TRUST_UNTRUSTED; -+ -+ /* -+ * Not rejected, and there is no list of accepted uses, try compat. -+ */ -+ return trust_compat(NULL, x, flags); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_txt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_txt.c -new file mode 100644 -index 0000000..66e5fcd ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_txt.c -@@ -0,0 +1,177 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+ -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+#include -+ -+const char *X509_verify_cert_error_string(long n) -+{ -+ switch ((int)n) { -+ case X509_V_OK: -+ return ("ok"); -+ case X509_V_ERR_UNSPECIFIED: -+ return ("unspecified certificate verification error"); -+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: -+ return ("unable to get issuer certificate"); -+ case X509_V_ERR_UNABLE_TO_GET_CRL: -+ return ("unable to get certificate CRL"); -+ case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: -+ return ("unable to decrypt certificate's signature"); -+ case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: -+ return ("unable to decrypt CRL's signature"); -+ case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: -+ return ("unable to decode issuer public key"); -+ case X509_V_ERR_CERT_SIGNATURE_FAILURE: -+ return ("certificate signature failure"); -+ case X509_V_ERR_CRL_SIGNATURE_FAILURE: -+ return ("CRL signature failure"); -+ case X509_V_ERR_CERT_NOT_YET_VALID: -+ return ("certificate is not yet valid"); -+ case X509_V_ERR_CERT_HAS_EXPIRED: -+ return ("certificate has expired"); -+ case X509_V_ERR_CRL_NOT_YET_VALID: -+ return ("CRL is not yet valid"); -+ case X509_V_ERR_CRL_HAS_EXPIRED: -+ return ("CRL has expired"); -+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: -+ return ("format error in certificate's notBefore field"); -+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: -+ return ("format error in certificate's notAfter field"); -+ case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: -+ return ("format error in CRL's lastUpdate field"); -+ case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: -+ return ("format error in CRL's nextUpdate field"); -+ case X509_V_ERR_OUT_OF_MEM: -+ return ("out of memory"); -+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: -+ return ("self signed certificate"); -+ case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: -+ return ("self signed certificate in certificate chain"); -+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: -+ return ("unable to get local issuer certificate"); -+ case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: -+ return ("unable to verify the first certificate"); -+ case X509_V_ERR_CERT_CHAIN_TOO_LONG: -+ return ("certificate chain too long"); -+ case X509_V_ERR_CERT_REVOKED: -+ return ("certificate revoked"); -+ case X509_V_ERR_INVALID_CA: -+ return ("invalid CA certificate"); -+ case X509_V_ERR_PATH_LENGTH_EXCEEDED: -+ return ("path length constraint exceeded"); -+ case X509_V_ERR_INVALID_PURPOSE: -+ return ("unsupported certificate purpose"); -+ case X509_V_ERR_CERT_UNTRUSTED: -+ return ("certificate not trusted"); -+ case X509_V_ERR_CERT_REJECTED: -+ return ("certificate rejected"); -+ case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: -+ return ("subject issuer mismatch"); -+ case X509_V_ERR_AKID_SKID_MISMATCH: -+ return ("authority and subject key identifier mismatch"); -+ case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: -+ return ("authority and issuer serial number mismatch"); -+ case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: -+ return ("key usage does not include certificate signing"); -+ case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: -+ return ("unable to get CRL issuer certificate"); -+ case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: -+ return ("unhandled critical extension"); -+ case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: -+ return ("key usage does not include CRL signing"); -+ case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: -+ return ("unhandled critical CRL extension"); -+ case X509_V_ERR_INVALID_NON_CA: -+ return ("invalid non-CA certificate (has CA markings)"); -+ case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: -+ return ("proxy path length constraint exceeded"); -+ case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: -+ return ("key usage does not include digital signature"); -+ case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: -+ return -+ ("proxy certificates not allowed, please set the appropriate flag"); -+ case X509_V_ERR_INVALID_EXTENSION: -+ return ("invalid or inconsistent certificate extension"); -+ case X509_V_ERR_INVALID_POLICY_EXTENSION: -+ return ("invalid or inconsistent certificate policy extension"); -+ case X509_V_ERR_NO_EXPLICIT_POLICY: -+ return ("no explicit policy"); -+ case X509_V_ERR_DIFFERENT_CRL_SCOPE: -+ return ("Different CRL scope"); -+ case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: -+ return ("Unsupported extension feature"); -+ case X509_V_ERR_UNNESTED_RESOURCE: -+ return ("RFC 3779 resource not subset of parent's resources"); -+ case X509_V_ERR_PERMITTED_VIOLATION: -+ return ("permitted subtree violation"); -+ case X509_V_ERR_EXCLUDED_VIOLATION: -+ return ("excluded subtree violation"); -+ case X509_V_ERR_SUBTREE_MINMAX: -+ return ("name constraints minimum and maximum not supported"); -+ case X509_V_ERR_APPLICATION_VERIFICATION: -+ return ("application verification failure"); -+ case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: -+ return ("unsupported name constraint type"); -+ case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: -+ return ("unsupported or invalid name constraint syntax"); -+ case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: -+ return ("unsupported or invalid name syntax"); -+ case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: -+ return ("CRL path validation error"); -+ case X509_V_ERR_PATH_LOOP: -+ return ("Path Loop"); -+ case X509_V_ERR_SUITE_B_INVALID_VERSION: -+ return ("Suite B: certificate version invalid"); -+ case X509_V_ERR_SUITE_B_INVALID_ALGORITHM: -+ return ("Suite B: invalid public key algorithm"); -+ case X509_V_ERR_SUITE_B_INVALID_CURVE: -+ return ("Suite B: invalid ECC curve"); -+ case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: -+ return ("Suite B: invalid signature algorithm"); -+ case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: -+ return ("Suite B: curve not allowed for this LOS"); -+ case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: -+ return ("Suite B: cannot sign P-384 with P-256"); -+ case X509_V_ERR_HOSTNAME_MISMATCH: -+ return ("Hostname mismatch"); -+ case X509_V_ERR_EMAIL_MISMATCH: -+ return ("Email address mismatch"); -+ case X509_V_ERR_IP_ADDRESS_MISMATCH: -+ return ("IP address mismatch"); -+ case X509_V_ERR_DANE_NO_MATCH: -+ return ("No matching DANE TLSA records"); -+ case X509_V_ERR_EE_KEY_TOO_SMALL: -+ return ("EE certificate key too weak"); -+ case X509_V_ERR_CA_KEY_TOO_SMALL: -+ return ("CA certificate key too weak"); -+ case X509_V_ERR_CA_MD_TOO_WEAK: -+ return ("CA signature digest algorithm too weak"); -+ case X509_V_ERR_INVALID_CALL: -+ return ("Invalid certificate verification context"); -+ case X509_V_ERR_STORE_LOOKUP: -+ return ("Issuer certificate lookup error"); -+ case X509_V_ERR_NO_VALID_SCTS: -+ return ("Certificate Transparency required, but no valid SCTs found"); -+ case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION: -+ return ("proxy subject name violation"); -+ -+ default: -+ /* Printing an error number into a static buffer is not thread-safe */ -+ return ("unknown certificate verification error"); -+ } -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_v3.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_v3.c -new file mode 100644 -index 0000000..ad126ef ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_v3.c -@@ -0,0 +1,234 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+#include "x509_lcl.h" -+ -+int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) -+{ -+ if (x == NULL) -+ return (0); -+ return (sk_X509_EXTENSION_num(x)); -+} -+ -+int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, -+ int lastpos) -+{ -+ ASN1_OBJECT *obj; -+ -+ obj = OBJ_nid2obj(nid); -+ if (obj == NULL) -+ return (-2); -+ return (X509v3_get_ext_by_OBJ(x, obj, lastpos)); -+} -+ -+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, -+ const ASN1_OBJECT *obj, int lastpos) -+{ -+ int n; -+ X509_EXTENSION *ex; -+ -+ if (sk == NULL) -+ return (-1); -+ lastpos++; -+ if (lastpos < 0) -+ lastpos = 0; -+ n = sk_X509_EXTENSION_num(sk); -+ for (; lastpos < n; lastpos++) { -+ ex = sk_X509_EXTENSION_value(sk, lastpos); -+ if (OBJ_cmp(ex->object, obj) == 0) -+ return (lastpos); -+ } -+ return (-1); -+} -+ -+int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, -+ int lastpos) -+{ -+ int n; -+ X509_EXTENSION *ex; -+ -+ if (sk == NULL) -+ return (-1); -+ lastpos++; -+ if (lastpos < 0) -+ lastpos = 0; -+ n = sk_X509_EXTENSION_num(sk); -+ for (; lastpos < n; lastpos++) { -+ ex = sk_X509_EXTENSION_value(sk, lastpos); -+ if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit)) -+ return (lastpos); -+ } -+ return (-1); -+} -+ -+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) -+{ -+ if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) -+ return NULL; -+ else -+ return sk_X509_EXTENSION_value(x, loc); -+} -+ -+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) -+{ -+ X509_EXTENSION *ret; -+ -+ if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) -+ return (NULL); -+ ret = sk_X509_EXTENSION_delete(x, loc); -+ return (ret); -+} -+ -+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, -+ X509_EXTENSION *ex, int loc) -+{ -+ X509_EXTENSION *new_ex = NULL; -+ int n; -+ STACK_OF(X509_EXTENSION) *sk = NULL; -+ -+ if (x == NULL) { -+ X509err(X509_F_X509V3_ADD_EXT, ERR_R_PASSED_NULL_PARAMETER); -+ goto err2; -+ } -+ -+ if (*x == NULL) { -+ if ((sk = sk_X509_EXTENSION_new_null()) == NULL) -+ goto err; -+ } else -+ sk = *x; -+ -+ n = sk_X509_EXTENSION_num(sk); -+ if (loc > n) -+ loc = n; -+ else if (loc < 0) -+ loc = n; -+ -+ if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) -+ goto err2; -+ if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) -+ goto err; -+ if (*x == NULL) -+ *x = sk; -+ return (sk); -+ err: -+ X509err(X509_F_X509V3_ADD_EXT, ERR_R_MALLOC_FAILURE); -+ err2: -+ X509_EXTENSION_free(new_ex); -+ sk_X509_EXTENSION_free(sk); -+ return (NULL); -+} -+ -+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, -+ int crit, -+ ASN1_OCTET_STRING *data) -+{ -+ ASN1_OBJECT *obj; -+ X509_EXTENSION *ret; -+ -+ obj = OBJ_nid2obj(nid); -+ if (obj == NULL) { -+ X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, X509_R_UNKNOWN_NID); -+ return (NULL); -+ } -+ ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); -+ if (ret == NULL) -+ ASN1_OBJECT_free(obj); -+ return (ret); -+} -+ -+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, -+ const ASN1_OBJECT *obj, int crit, -+ ASN1_OCTET_STRING *data) -+{ -+ X509_EXTENSION *ret; -+ -+ if ((ex == NULL) || (*ex == NULL)) { -+ if ((ret = X509_EXTENSION_new()) == NULL) { -+ X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ, -+ ERR_R_MALLOC_FAILURE); -+ return (NULL); -+ } -+ } else -+ ret = *ex; -+ -+ if (!X509_EXTENSION_set_object(ret, obj)) -+ goto err; -+ if (!X509_EXTENSION_set_critical(ret, crit)) -+ goto err; -+ if (!X509_EXTENSION_set_data(ret, data)) -+ goto err; -+ -+ if ((ex != NULL) && (*ex == NULL)) -+ *ex = ret; -+ return (ret); -+ err: -+ if ((ex == NULL) || (ret != *ex)) -+ X509_EXTENSION_free(ret); -+ return (NULL); -+} -+ -+int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj) -+{ -+ if ((ex == NULL) || (obj == NULL)) -+ return (0); -+ ASN1_OBJECT_free(ex->object); -+ ex->object = OBJ_dup(obj); -+ return ex->object != NULL; -+} -+ -+int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) -+{ -+ if (ex == NULL) -+ return (0); -+ ex->critical = (crit) ? 0xFF : -1; -+ return (1); -+} -+ -+int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) -+{ -+ int i; -+ -+ if (ex == NULL) -+ return (0); -+ i = ASN1_OCTET_STRING_set(&ex->value, data->data, data->length); -+ if (!i) -+ return (0); -+ return (1); -+} -+ -+ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex) -+{ -+ if (ex == NULL) -+ return (NULL); -+ return (ex->object); -+} -+ -+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex) -+{ -+ if (ex == NULL) -+ return (NULL); -+ return &ex->value; -+} -+ -+int X509_EXTENSION_get_critical(const X509_EXTENSION *ex) -+{ -+ if (ex == NULL) -+ return (0); -+ if (ex->critical > 0) -+ return 1; -+ return 0; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vfy.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vfy.c -new file mode 100644 -index 0000000..ebc4424 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vfy.c -@@ -0,0 +1,3275 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "x509_lcl.h" -+ -+/* CRL score values */ -+ -+/* No unhandled critical extensions */ -+ -+#define CRL_SCORE_NOCRITICAL 0x100 -+ -+/* certificate is within CRL scope */ -+ -+#define CRL_SCORE_SCOPE 0x080 -+ -+/* CRL times valid */ -+ -+#define CRL_SCORE_TIME 0x040 -+ -+/* Issuer name matches certificate */ -+ -+#define CRL_SCORE_ISSUER_NAME 0x020 -+ -+/* If this score or above CRL is probably valid */ -+ -+#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) -+ -+/* CRL issuer is certificate issuer */ -+ -+#define CRL_SCORE_ISSUER_CERT 0x018 -+ -+/* CRL issuer is on certificate path */ -+ -+#define CRL_SCORE_SAME_PATH 0x008 -+ -+/* CRL issuer matches CRL AKID */ -+ -+#define CRL_SCORE_AKID 0x004 -+ -+/* Have a delta CRL with valid times */ -+ -+#define CRL_SCORE_TIME_DELTA 0x002 -+ -+static int build_chain(X509_STORE_CTX *ctx); -+static int verify_chain(X509_STORE_CTX *ctx); -+static int dane_verify(X509_STORE_CTX *ctx); -+static int null_callback(int ok, X509_STORE_CTX *e); -+static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); -+static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); -+static int check_chain_extensions(X509_STORE_CTX *ctx); -+static int check_name_constraints(X509_STORE_CTX *ctx); -+static int check_id(X509_STORE_CTX *ctx); -+static int check_trust(X509_STORE_CTX *ctx, int num_untrusted); -+static int check_revocation(X509_STORE_CTX *ctx); -+static int check_cert(X509_STORE_CTX *ctx); -+static int check_policy(X509_STORE_CTX *ctx); -+static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); -+static int check_dane_issuer(X509_STORE_CTX *ctx, int depth); -+static int check_key_level(X509_STORE_CTX *ctx, X509 *cert); -+static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert); -+ -+static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, -+ unsigned int *preasons, X509_CRL *crl, X509 *x); -+static int get_crl_delta(X509_STORE_CTX *ctx, -+ X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); -+static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, -+ int *pcrl_score, X509_CRL *base, -+ STACK_OF(X509_CRL) *crls); -+static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, -+ int *pcrl_score); -+static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, -+ unsigned int *preasons); -+static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); -+static int check_crl_chain(X509_STORE_CTX *ctx, -+ STACK_OF(X509) *cert_path, -+ STACK_OF(X509) *crl_path); -+ -+static int internal_verify(X509_STORE_CTX *ctx); -+ -+static int null_callback(int ok, X509_STORE_CTX *e) -+{ -+ return ok; -+} -+ -+/* Return 1 is a certificate is self signed */ -+static int cert_self_signed(X509 *x) -+{ -+ /* -+ * FIXME: x509v3_cache_extensions() needs to detect more failures and not -+ * set EXFLAG_SET when that happens. Especially, if the failures are -+ * parse errors, rather than memory pressure! -+ */ -+ X509_check_purpose(x, -1, 0); -+ if (x->ex_flags & EXFLAG_SS) -+ return 1; -+ else -+ return 0; -+} -+ -+/* Given a certificate try and find an exact match in the store */ -+ -+static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) -+{ -+ STACK_OF(X509) *certs; -+ X509 *xtmp = NULL; -+ int i; -+ /* Lookup all certs with matching subject name */ -+ certs = ctx->lookup_certs(ctx, X509_get_subject_name(x)); -+ if (certs == NULL) -+ return NULL; -+ /* Look for exact match */ -+ for (i = 0; i < sk_X509_num(certs); i++) { -+ xtmp = sk_X509_value(certs, i); -+ if (!X509_cmp(xtmp, x)) -+ break; -+ } -+ if (i < sk_X509_num(certs)) -+ X509_up_ref(xtmp); -+ else -+ xtmp = NULL; -+ sk_X509_pop_free(certs, X509_free); -+ return xtmp; -+} -+ -+/*- -+ * Inform the verify callback of an error. -+ * If B is not NULL it is the error cert, otherwise use the chain cert at -+ * B. -+ * If B is not X509_V_OK, that's the error value, otherwise leave -+ * unchanged (presumably set by the caller). -+ * -+ * Returns 0 to abort verification with an error, non-zero to continue. -+ */ -+static int verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err) -+{ -+ ctx->error_depth = depth; -+ ctx->current_cert = (x != NULL) ? x : sk_X509_value(ctx->chain, depth); -+ if (err != X509_V_OK) -+ ctx->error = err; -+ return ctx->verify_cb(0, ctx); -+} -+ -+/*- -+ * Inform the verify callback of an error, CRL-specific variant. Here, the -+ * error depth and certificate are already set, we just specify the error -+ * number. -+ * -+ * Returns 0 to abort verification with an error, non-zero to continue. -+ */ -+static int verify_cb_crl(X509_STORE_CTX *ctx, int err) -+{ -+ ctx->error = err; -+ return ctx->verify_cb(0, ctx); -+} -+ -+static int check_auth_level(X509_STORE_CTX *ctx) -+{ -+ int i; -+ int num = sk_X509_num(ctx->chain); -+ -+ if (ctx->param->auth_level <= 0) -+ return 1; -+ -+ for (i = 0; i < num; ++i) { -+ X509 *cert = sk_X509_value(ctx->chain, i); -+ -+ /* -+ * We've already checked the security of the leaf key, so here we only -+ * check the security of issuer keys. -+ */ -+ if (i > 0 && !check_key_level(ctx, cert) && -+ verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_KEY_TOO_SMALL) == 0) -+ return 0; -+ /* -+ * We also check the signature algorithm security of all certificates -+ * except those of the trust anchor at index num-1. -+ */ -+ if (i < num - 1 && !check_sig_level(ctx, cert) && -+ verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_MD_TOO_WEAK) == 0) -+ return 0; -+ } -+ return 1; -+} -+ -+static int verify_chain(X509_STORE_CTX *ctx) -+{ -+ int err; -+ int ok; -+ -+ /* -+ * Before either returning with an error, or continuing with CRL checks, -+ * instantiate chain public key parameters. -+ */ -+ if ((ok = build_chain(ctx)) == 0 || -+ (ok = check_chain_extensions(ctx)) == 0 || -+ (ok = check_auth_level(ctx)) == 0 || -+ (ok = check_name_constraints(ctx)) == 0 || -+ (ok = check_id(ctx)) == 0 || 1) -+ X509_get_pubkey_parameters(NULL, ctx->chain); -+ if (ok == 0 || (ok = ctx->check_revocation(ctx)) == 0) -+ return ok; -+ -+ err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain, -+ ctx->param->flags); -+ if (err != X509_V_OK) { -+ if ((ok = verify_cb_cert(ctx, NULL, ctx->error_depth, err)) == 0) -+ return ok; -+ } -+ -+ /* Verify chain signatures and expiration times */ -+ ok = (ctx->verify != NULL) ? ctx->verify(ctx) : internal_verify(ctx); -+ if (!ok) -+ return ok; -+ -+#ifndef OPENSSL_NO_RFC3779 -+ /* RFC 3779 path validation, now that CRL check has been done */ -+ if ((ok = X509v3_asid_validate_path(ctx)) == 0) -+ return ok; -+ if ((ok = X509v3_addr_validate_path(ctx)) == 0) -+ return ok; -+#endif -+ -+ /* If we get this far evaluate policies */ -+ if (ctx->param->flags & X509_V_FLAG_POLICY_CHECK) -+ ok = ctx->check_policy(ctx); -+ return ok; -+} -+ -+int X509_verify_cert(X509_STORE_CTX *ctx) -+{ -+ SSL_DANE *dane = ctx->dane; -+ int ret; -+ -+ if (ctx->cert == NULL) { -+ X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); -+ ctx->error = X509_V_ERR_INVALID_CALL; -+ return -1; -+ } -+ -+ if (ctx->chain != NULL) { -+ /* -+ * This X509_STORE_CTX has already been used to verify a cert. We -+ * cannot do another one. -+ */ -+ X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); -+ ctx->error = X509_V_ERR_INVALID_CALL; -+ return -1; -+ } -+ -+ /* -+ * first we make sure the chain we are going to build is present and that -+ * the first entry is in place -+ */ -+ if (((ctx->chain = sk_X509_new_null()) == NULL) || -+ (!sk_X509_push(ctx->chain, ctx->cert))) { -+ X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ return -1; -+ } -+ X509_up_ref(ctx->cert); -+ ctx->num_untrusted = 1; -+ -+ /* If the peer's public key is too weak, we can stop early. */ -+ if (!check_key_level(ctx, ctx->cert) && -+ !verify_cb_cert(ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL)) -+ return 0; -+ -+ if (DANETLS_ENABLED(dane)) -+ ret = dane_verify(ctx); -+ else -+ ret = verify_chain(ctx); -+ -+ /* -+ * Safety-net. If we are returning an error, we must also set ctx->error, -+ * so that the chain is not considered verified should the error be ignored -+ * (e.g. TLS with SSL_VERIFY_NONE). -+ */ -+ if (ret <= 0 && ctx->error == X509_V_OK) -+ ctx->error = X509_V_ERR_UNSPECIFIED; -+ return ret; -+} -+ -+/* -+ * Given a STACK_OF(X509) find the issuer of cert (if any) -+ */ -+static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) -+{ -+ int i; -+ X509 *issuer, *rv = NULL; -+ -+ for (i = 0; i < sk_X509_num(sk); i++) { -+ issuer = sk_X509_value(sk, i); -+ if (ctx->check_issued(ctx, x, issuer)) { -+ rv = issuer; -+ if (x509_check_cert_time(ctx, rv, -1)) -+ break; -+ } -+ } -+ return rv; -+} -+ -+/* Given a possible certificate and issuer check them */ -+ -+static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) -+{ -+ int ret; -+ if (x == issuer) -+ return cert_self_signed(x); -+ ret = X509_check_issued(issuer, x); -+ if (ret == X509_V_OK) { -+ int i; -+ X509 *ch; -+ /* Special case: single self signed certificate */ -+ if (cert_self_signed(x) && sk_X509_num(ctx->chain) == 1) -+ return 1; -+ for (i = 0; i < sk_X509_num(ctx->chain); i++) { -+ ch = sk_X509_value(ctx->chain, i); -+ if (ch == issuer || !X509_cmp(ch, issuer)) { -+ ret = X509_V_ERR_PATH_LOOP; -+ break; -+ } -+ } -+ } -+ -+ return (ret == X509_V_OK); -+} -+ -+/* Alternative lookup method: look from a STACK stored in other_ctx */ -+ -+static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) -+{ -+ *issuer = find_issuer(ctx, ctx->other_ctx, x); -+ if (*issuer) { -+ X509_up_ref(*issuer); -+ return 1; -+ } else -+ return 0; -+} -+ -+static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, X509_NAME *nm) -+{ -+ STACK_OF(X509) *sk = NULL; -+ X509 *x; -+ int i; -+ for (i = 0; i < sk_X509_num(ctx->other_ctx); i++) { -+ x = sk_X509_value(ctx->other_ctx, i); -+ if (X509_NAME_cmp(nm, X509_get_subject_name(x)) == 0) { -+ if (sk == NULL) -+ sk = sk_X509_new_null(); -+ if (sk == NULL || sk_X509_push(sk, x) == 0) { -+ sk_X509_pop_free(sk, X509_free); -+ return NULL; -+ } -+ X509_up_ref(x); -+ } -+ } -+ return sk; -+} -+ -+/* -+ * Check EE or CA certificate purpose. For trusted certificates explicit local -+ * auxiliary trust can be used to override EKU-restrictions. -+ */ -+static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth, -+ int must_be_ca) -+{ -+ int tr_ok = X509_TRUST_UNTRUSTED; -+ -+ /* -+ * For trusted certificates we want to see whether any auxiliary trust -+ * settings trump the purpose constraints. -+ * -+ * This is complicated by the fact that the trust ordinals in -+ * ctx->param->trust are entirely independent of the purpose ordinals in -+ * ctx->param->purpose! -+ * -+ * What connects them is their mutual initialization via calls from -+ * X509_STORE_CTX_set_default() into X509_VERIFY_PARAM_lookup() which sets -+ * related values of both param->trust and param->purpose. It is however -+ * typically possible to infer associated trust values from a purpose value -+ * via the X509_PURPOSE API. -+ * -+ * Therefore, we can only check for trust overrides when the purpose we're -+ * checking is the same as ctx->param->purpose and ctx->param->trust is -+ * also set. -+ */ -+ if (depth >= ctx->num_untrusted && purpose == ctx->param->purpose) -+ tr_ok = X509_check_trust(x, ctx->param->trust, X509_TRUST_NO_SS_COMPAT); -+ -+ switch (tr_ok) { -+ case X509_TRUST_TRUSTED: -+ return 1; -+ case X509_TRUST_REJECTED: -+ break; -+ default: -+ switch (X509_check_purpose(x, purpose, must_be_ca > 0)) { -+ case 1: -+ return 1; -+ case 0: -+ break; -+ default: -+ if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) == 0) -+ return 1; -+ } -+ break; -+ } -+ -+ return verify_cb_cert(ctx, x, depth, X509_V_ERR_INVALID_PURPOSE); -+} -+ -+/* -+ * Check a certificate chains extensions for consistency with the supplied -+ * purpose -+ */ -+ -+static int check_chain_extensions(X509_STORE_CTX *ctx) -+{ -+ int i, must_be_ca, plen = 0; -+ X509 *x; -+ int proxy_path_length = 0; -+ int purpose; -+ int allow_proxy_certs; -+ int num = sk_X509_num(ctx->chain); -+ -+ /*- -+ * must_be_ca can have 1 of 3 values: -+ * -1: we accept both CA and non-CA certificates, to allow direct -+ * use of self-signed certificates (which are marked as CA). -+ * 0: we only accept non-CA certificates. This is currently not -+ * used, but the possibility is present for future extensions. -+ * 1: we only accept CA certificates. This is currently used for -+ * all certificates in the chain except the leaf certificate. -+ */ -+ must_be_ca = -1; -+ -+ /* CRL path validation */ -+ if (ctx->parent) { -+ allow_proxy_certs = 0; -+ purpose = X509_PURPOSE_CRL_SIGN; -+ } else { -+ allow_proxy_certs = -+ ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); -+ purpose = ctx->param->purpose; -+ } -+ -+ for (i = 0; i < num; i++) { -+ int ret; -+ x = sk_X509_value(ctx->chain, i); -+ if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) -+ && (x->ex_flags & EXFLAG_CRITICAL)) { -+ if (!verify_cb_cert(ctx, x, i, -+ X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION)) -+ return 0; -+ } -+ if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) { -+ if (!verify_cb_cert(ctx, x, i, -+ X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED)) -+ return 0; -+ } -+ ret = X509_check_ca(x); -+ switch (must_be_ca) { -+ case -1: -+ if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) -+ && (ret != 1) && (ret != 0)) { -+ ret = 0; -+ ctx->error = X509_V_ERR_INVALID_CA; -+ } else -+ ret = 1; -+ break; -+ case 0: -+ if (ret != 0) { -+ ret = 0; -+ ctx->error = X509_V_ERR_INVALID_NON_CA; -+ } else -+ ret = 1; -+ break; -+ default: -+ /* X509_V_FLAG_X509_STRICT is implicit for intermediate CAs */ -+ if ((ret == 0) -+ || ((i + 1 < num || ctx->param->flags & X509_V_FLAG_X509_STRICT) -+ && (ret != 1))) { -+ ret = 0; -+ ctx->error = X509_V_ERR_INVALID_CA; -+ } else -+ ret = 1; -+ break; -+ } -+ if (ret == 0 && !verify_cb_cert(ctx, x, i, X509_V_OK)) -+ return 0; -+ /* check_purpose() makes the callback as needed */ -+ if (purpose > 0 && !check_purpose(ctx, x, purpose, i, must_be_ca)) -+ return 0; -+ /* Check pathlen if not self issued */ -+ if ((i > 1) && !(x->ex_flags & EXFLAG_SI) -+ && (x->ex_pathlen != -1) -+ && (plen > (x->ex_pathlen + proxy_path_length + 1))) { -+ if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED)) -+ return 0; -+ } -+ /* Increment path length if not self issued */ -+ if (!(x->ex_flags & EXFLAG_SI)) -+ plen++; -+ /* -+ * If this certificate is a proxy certificate, the next certificate -+ * must be another proxy certificate or a EE certificate. If not, -+ * the next certificate must be a CA certificate. -+ */ -+ if (x->ex_flags & EXFLAG_PROXY) { -+ /* -+ * RFC3820, 4.1.3 (b)(1) stipulates that if pCPathLengthConstraint -+ * is less than max_path_length, the former should be copied to -+ * the latter, and 4.1.4 (a) stipulates that max_path_length -+ * should be verified to be larger than zero and decrement it. -+ * -+ * Because we're checking the certs in the reverse order, we start -+ * with verifying that proxy_path_length isn't larger than pcPLC, -+ * and copy the latter to the former if it is, and finally, -+ * increment proxy_path_length. -+ */ -+ if (x->ex_pcpathlen != -1) { -+ if (proxy_path_length > x->ex_pcpathlen) { -+ if (!verify_cb_cert(ctx, x, i, -+ X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED)) -+ return 0; -+ } -+ proxy_path_length = x->ex_pcpathlen; -+ } -+ proxy_path_length++; -+ must_be_ca = 0; -+ } else -+ must_be_ca = 1; -+ } -+ return 1; -+} -+ -+static int check_name_constraints(X509_STORE_CTX *ctx) -+{ -+ int i; -+ -+ /* Check name constraints for all certificates */ -+ for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) { -+ X509 *x = sk_X509_value(ctx->chain, i); -+ int j; -+ -+ /* Ignore self issued certs unless last in chain */ -+ if (i && (x->ex_flags & EXFLAG_SI)) -+ continue; -+ -+ /* -+ * Proxy certificates policy has an extra constraint, where the -+ * certificate subject MUST be the issuer with a single CN entry -+ * added. -+ * (RFC 3820: 3.4, 4.1.3 (a)(4)) -+ */ -+ if (x->ex_flags & EXFLAG_PROXY) { -+ X509_NAME *tmpsubject = X509_get_subject_name(x); -+ X509_NAME *tmpissuer = X509_get_issuer_name(x); -+ X509_NAME_ENTRY *tmpentry = NULL; -+ int last_object_nid = 0; -+ int err = X509_V_OK; -+ int last_object_loc = X509_NAME_entry_count(tmpsubject) - 1; -+ -+ /* Check that there are at least two RDNs */ -+ if (last_object_loc < 1) { -+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; -+ goto proxy_name_done; -+ } -+ -+ /* -+ * Check that there is exactly one more RDN in subject as -+ * there is in issuer. -+ */ -+ if (X509_NAME_entry_count(tmpsubject) -+ != X509_NAME_entry_count(tmpissuer) + 1) { -+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; -+ goto proxy_name_done; -+ } -+ -+ /* -+ * Check that the last subject component isn't part of a -+ * multivalued RDN -+ */ -+ if (X509_NAME_ENTRY_set(X509_NAME_get_entry(tmpsubject, -+ last_object_loc)) -+ == X509_NAME_ENTRY_set(X509_NAME_get_entry(tmpsubject, -+ last_object_loc - 1))) { -+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; -+ goto proxy_name_done; -+ } -+ -+ /* -+ * Check that the last subject RDN is a commonName, and that -+ * all the previous RDNs match the issuer exactly -+ */ -+ tmpsubject = X509_NAME_dup(tmpsubject); -+ if (tmpsubject == NULL) { -+ X509err(X509_F_CHECK_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ return 0; -+ } -+ -+ tmpentry = -+ X509_NAME_delete_entry(tmpsubject, last_object_loc); -+ last_object_nid = -+ OBJ_obj2nid(X509_NAME_ENTRY_get_object(tmpentry)); -+ -+ if (last_object_nid != NID_commonName -+ || X509_NAME_cmp(tmpsubject, tmpissuer) != 0) { -+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; -+ } -+ -+ X509_NAME_ENTRY_free(tmpentry); -+ X509_NAME_free(tmpsubject); -+ -+ proxy_name_done: -+ if (err != X509_V_OK -+ && !verify_cb_cert(ctx, x, i, err)) -+ return 0; -+ } -+ -+ /* -+ * Check against constraints for all certificates higher in chain -+ * including trust anchor. Trust anchor not strictly speaking needed -+ * but if it includes constraints it is to be assumed it expects them -+ * to be obeyed. -+ */ -+ for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) { -+ NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; -+ -+ if (nc) { -+ int rv = NAME_CONSTRAINTS_check(x, nc); -+ -+ /* If EE certificate check commonName too */ -+ if (rv == X509_V_OK && i == 0) -+ rv = NAME_CONSTRAINTS_check_CN(x, nc); -+ -+ switch (rv) { -+ case X509_V_OK: -+ break; -+ case X509_V_ERR_OUT_OF_MEM: -+ return 0; -+ default: -+ if (!verify_cb_cert(ctx, x, i, rv)) -+ return 0; -+ break; -+ } -+ } -+ } -+ } -+ return 1; -+} -+ -+static int check_id_error(X509_STORE_CTX *ctx, int errcode) -+{ -+ return verify_cb_cert(ctx, ctx->cert, 0, errcode); -+} -+ -+static int check_hosts(X509 *x, X509_VERIFY_PARAM *vpm) -+{ -+ int i; -+ int n = sk_OPENSSL_STRING_num(vpm->hosts); -+ char *name; -+ -+ if (vpm->peername != NULL) { -+ OPENSSL_free(vpm->peername); -+ vpm->peername = NULL; -+ } -+ for (i = 0; i < n; ++i) { -+ name = sk_OPENSSL_STRING_value(vpm->hosts, i); -+ if (X509_check_host(x, name, 0, vpm->hostflags, &vpm->peername) > 0) -+ return 1; -+ } -+ return n == 0; -+} -+ -+static int check_id(X509_STORE_CTX *ctx) -+{ -+ X509_VERIFY_PARAM *vpm = ctx->param; -+ X509 *x = ctx->cert; -+ if (vpm->hosts && check_hosts(x, vpm) <= 0) { -+ if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) -+ return 0; -+ } -+ if (vpm->email && X509_check_email(x, vpm->email, vpm->emaillen, 0) <= 0) { -+ if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) -+ return 0; -+ } -+ if (vpm->ip && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) { -+ if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) -+ return 0; -+ } -+ return 1; -+} -+ -+static int check_trust(X509_STORE_CTX *ctx, int num_untrusted) -+{ -+ int i; -+ X509 *x = NULL; -+ X509 *mx; -+ SSL_DANE *dane = ctx->dane; -+ int num = sk_X509_num(ctx->chain); -+ int trust; -+ -+ /* -+ * Check for a DANE issuer at depth 1 or greater, if it is a DANE-TA(2) -+ * match, we're done, otherwise we'll merely record the match depth. -+ */ -+ if (DANETLS_HAS_TA(dane) && num_untrusted > 0 && num_untrusted < num) { -+ switch (trust = check_dane_issuer(ctx, num_untrusted)) { -+ case X509_TRUST_TRUSTED: -+ case X509_TRUST_REJECTED: -+ return trust; -+ } -+ } -+ -+ /* -+ * Check trusted certificates in chain at depth num_untrusted and up. -+ * Note, that depths 0..num_untrusted-1 may also contain trusted -+ * certificates, but the caller is expected to have already checked those, -+ * and wants to incrementally check just any added since. -+ */ -+ for (i = num_untrusted; i < num; i++) { -+ x = sk_X509_value(ctx->chain, i); -+ trust = X509_check_trust(x, ctx->param->trust, 0); -+ /* If explicitly trusted return trusted */ -+ if (trust == X509_TRUST_TRUSTED) -+ goto trusted; -+ if (trust == X509_TRUST_REJECTED) -+ goto rejected; -+ } -+ -+ /* -+ * If we are looking at a trusted certificate, and accept partial chains, -+ * the chain is PKIX trusted. -+ */ -+ if (num_untrusted < num) { -+ if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) -+ goto trusted; -+ return X509_TRUST_UNTRUSTED; -+ } -+ -+ if (num_untrusted == num && ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { -+ /* -+ * Last-resort call with no new trusted certificates, check the leaf -+ * for a direct trust store match. -+ */ -+ i = 0; -+ x = sk_X509_value(ctx->chain, i); -+ mx = lookup_cert_match(ctx, x); -+ if (!mx) -+ return X509_TRUST_UNTRUSTED; -+ -+ /* -+ * Check explicit auxiliary trust/reject settings. If none are set, -+ * we'll accept X509_TRUST_UNTRUSTED when not self-signed. -+ */ -+ trust = X509_check_trust(mx, ctx->param->trust, 0); -+ if (trust == X509_TRUST_REJECTED) { -+ X509_free(mx); -+ goto rejected; -+ } -+ -+ /* Replace leaf with trusted match */ -+ (void) sk_X509_set(ctx->chain, 0, mx); -+ X509_free(x); -+ ctx->num_untrusted = 0; -+ goto trusted; -+ } -+ -+ /* -+ * If no trusted certs in chain at all return untrusted and allow -+ * standard (no issuer cert) etc errors to be indicated. -+ */ -+ return X509_TRUST_UNTRUSTED; -+ -+ rejected: -+ if (!verify_cb_cert(ctx, x, i, X509_V_ERR_CERT_REJECTED)) -+ return X509_TRUST_REJECTED; -+ return X509_TRUST_UNTRUSTED; -+ -+ trusted: -+ if (!DANETLS_ENABLED(dane)) -+ return X509_TRUST_TRUSTED; -+ if (dane->pdpth < 0) -+ dane->pdpth = num_untrusted; -+ /* With DANE, PKIX alone is not trusted until we have both */ -+ if (dane->mdpth >= 0) -+ return X509_TRUST_TRUSTED; -+ return X509_TRUST_UNTRUSTED; -+} -+ -+static int check_revocation(X509_STORE_CTX *ctx) -+{ -+ int i = 0, last = 0, ok = 0; -+ if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) -+ return 1; -+ if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) -+ last = sk_X509_num(ctx->chain) - 1; -+ else { -+ /* If checking CRL paths this isn't the EE certificate */ -+ if (ctx->parent) -+ return 1; -+ last = 0; -+ } -+ for (i = 0; i <= last; i++) { -+ ctx->error_depth = i; -+ ok = check_cert(ctx); -+ if (!ok) -+ return ok; -+ } -+ return 1; -+} -+ -+static int check_cert(X509_STORE_CTX *ctx) -+{ -+ X509_CRL *crl = NULL, *dcrl = NULL; -+ int ok = 0; -+ int cnum = ctx->error_depth; -+ X509 *x = sk_X509_value(ctx->chain, cnum); -+ -+ ctx->current_cert = x; -+ ctx->current_issuer = NULL; -+ ctx->current_crl_score = 0; -+ ctx->current_reasons = 0; -+ -+ if (x->ex_flags & EXFLAG_PROXY) -+ return 1; -+ -+ while (ctx->current_reasons != CRLDP_ALL_REASONS) { -+ unsigned int last_reasons = ctx->current_reasons; -+ -+ /* Try to retrieve relevant CRL */ -+ if (ctx->get_crl) -+ ok = ctx->get_crl(ctx, &crl, x); -+ else -+ ok = get_crl_delta(ctx, &crl, &dcrl, x); -+ /* -+ * If error looking up CRL, nothing we can do except notify callback -+ */ -+ if (!ok) { -+ ok = verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL); -+ goto done; -+ } -+ ctx->current_crl = crl; -+ ok = ctx->check_crl(ctx, crl); -+ if (!ok) -+ goto done; -+ -+ if (dcrl) { -+ ok = ctx->check_crl(ctx, dcrl); -+ if (!ok) -+ goto done; -+ ok = ctx->cert_crl(ctx, dcrl, x); -+ if (!ok) -+ goto done; -+ } else -+ ok = 1; -+ -+ /* Don't look in full CRL if delta reason is removefromCRL */ -+ if (ok != 2) { -+ ok = ctx->cert_crl(ctx, crl, x); -+ if (!ok) -+ goto done; -+ } -+ -+ X509_CRL_free(crl); -+ X509_CRL_free(dcrl); -+ crl = NULL; -+ dcrl = NULL; -+ /* -+ * If reasons not updated we won't get anywhere by another iteration, -+ * so exit loop. -+ */ -+ if (last_reasons == ctx->current_reasons) { -+ ok = verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL); -+ goto done; -+ } -+ } -+ done: -+ X509_CRL_free(crl); -+ X509_CRL_free(dcrl); -+ -+ ctx->current_crl = NULL; -+ return ok; -+} -+ -+/* Check CRL times against values in X509_STORE_CTX */ -+ -+static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) -+{ -+ time_t *ptime; -+ int i; -+ -+ if (notify) -+ ctx->current_crl = crl; -+ if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) -+ ptime = &ctx->param->check_time; -+ else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) -+ return 1; -+ else -+ ptime = NULL; -+ -+ i = X509_cmp_time(X509_CRL_get0_lastUpdate(crl), ptime); -+ if (i == 0) { -+ if (!notify) -+ return 0; -+ if (!verify_cb_crl(ctx, X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD)) -+ return 0; -+ } -+ -+ if (i > 0) { -+ if (!notify) -+ return 0; -+ if (!verify_cb_crl(ctx, X509_V_ERR_CRL_NOT_YET_VALID)) -+ return 0; -+ } -+ -+ if (X509_CRL_get0_nextUpdate(crl)) { -+ i = X509_cmp_time(X509_CRL_get0_nextUpdate(crl), ptime); -+ -+ if (i == 0) { -+ if (!notify) -+ return 0; -+ if (!verify_cb_crl(ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD)) -+ return 0; -+ } -+ /* Ignore expiry of base CRL is delta is valid */ -+ if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { -+ if (!notify) -+ return 0; -+ if (!verify_cb_crl(ctx, X509_V_ERR_CRL_HAS_EXPIRED)) -+ return 0; -+ } -+ } -+ -+ if (notify) -+ ctx->current_crl = NULL; -+ -+ return 1; -+} -+ -+static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, -+ X509 **pissuer, int *pscore, unsigned int *preasons, -+ STACK_OF(X509_CRL) *crls) -+{ -+ int i, crl_score, best_score = *pscore; -+ unsigned int reasons, best_reasons = 0; -+ X509 *x = ctx->current_cert; -+ X509_CRL *crl, *best_crl = NULL; -+ X509 *crl_issuer = NULL, *best_crl_issuer = NULL; -+ -+ for (i = 0; i < sk_X509_CRL_num(crls); i++) { -+ crl = sk_X509_CRL_value(crls, i); -+ reasons = *preasons; -+ crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); -+ if (crl_score < best_score || crl_score == 0) -+ continue; -+ /* If current CRL is equivalent use it if it is newer */ -+ if (crl_score == best_score && best_crl != NULL) { -+ int day, sec; -+ if (ASN1_TIME_diff(&day, &sec, X509_CRL_get0_lastUpdate(best_crl), -+ X509_CRL_get0_lastUpdate(crl)) == 0) -+ continue; -+ /* -+ * ASN1_TIME_diff never returns inconsistent signs for |day| -+ * and |sec|. -+ */ -+ if (day <= 0 && sec <= 0) -+ continue; -+ } -+ best_crl = crl; -+ best_crl_issuer = crl_issuer; -+ best_score = crl_score; -+ best_reasons = reasons; -+ } -+ -+ if (best_crl) { -+ X509_CRL_free(*pcrl); -+ *pcrl = best_crl; -+ *pissuer = best_crl_issuer; -+ *pscore = best_score; -+ *preasons = best_reasons; -+ X509_CRL_up_ref(best_crl); -+ X509_CRL_free(*pdcrl); -+ *pdcrl = NULL; -+ get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); -+ } -+ -+ if (best_score >= CRL_SCORE_VALID) -+ return 1; -+ -+ return 0; -+} -+ -+/* -+ * Compare two CRL extensions for delta checking purposes. They should be -+ * both present or both absent. If both present all fields must be identical. -+ */ -+ -+static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) -+{ -+ ASN1_OCTET_STRING *exta, *extb; -+ int i; -+ i = X509_CRL_get_ext_by_NID(a, nid, -1); -+ if (i >= 0) { -+ /* Can't have multiple occurrences */ -+ if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) -+ return 0; -+ exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); -+ } else -+ exta = NULL; -+ -+ i = X509_CRL_get_ext_by_NID(b, nid, -1); -+ -+ if (i >= 0) { -+ -+ if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) -+ return 0; -+ extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); -+ } else -+ extb = NULL; -+ -+ if (!exta && !extb) -+ return 1; -+ -+ if (!exta || !extb) -+ return 0; -+ -+ if (ASN1_OCTET_STRING_cmp(exta, extb)) -+ return 0; -+ -+ return 1; -+} -+ -+/* See if a base and delta are compatible */ -+ -+static int check_delta_base(X509_CRL *delta, X509_CRL *base) -+{ -+ /* Delta CRL must be a delta */ -+ if (!delta->base_crl_number) -+ return 0; -+ /* Base must have a CRL number */ -+ if (!base->crl_number) -+ return 0; -+ /* Issuer names must match */ -+ if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) -+ return 0; -+ /* AKID and IDP must match */ -+ if (!crl_extension_match(delta, base, NID_authority_key_identifier)) -+ return 0; -+ if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) -+ return 0; -+ /* Delta CRL base number must not exceed Full CRL number. */ -+ if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) -+ return 0; -+ /* Delta CRL number must exceed full CRL number */ -+ if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) -+ return 1; -+ return 0; -+} -+ -+/* -+ * For a given base CRL find a delta... maybe extend to delta scoring or -+ * retrieve a chain of deltas... -+ */ -+ -+static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, -+ X509_CRL *base, STACK_OF(X509_CRL) *crls) -+{ -+ X509_CRL *delta; -+ int i; -+ if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) -+ return; -+ if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) -+ return; -+ for (i = 0; i < sk_X509_CRL_num(crls); i++) { -+ delta = sk_X509_CRL_value(crls, i); -+ if (check_delta_base(delta, base)) { -+ if (check_crl_time(ctx, delta, 0)) -+ *pscore |= CRL_SCORE_TIME_DELTA; -+ X509_CRL_up_ref(delta); -+ *dcrl = delta; -+ return; -+ } -+ } -+ *dcrl = NULL; -+} -+ -+/* -+ * For a given CRL return how suitable it is for the supplied certificate -+ * 'x'. The return value is a mask of several criteria. If the issuer is not -+ * the certificate issuer this is returned in *pissuer. The reasons mask is -+ * also used to determine if the CRL is suitable: if no new reasons the CRL -+ * is rejected, otherwise reasons is updated. -+ */ -+ -+static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, -+ unsigned int *preasons, X509_CRL *crl, X509 *x) -+{ -+ -+ int crl_score = 0; -+ unsigned int tmp_reasons = *preasons, crl_reasons; -+ -+ /* First see if we can reject CRL straight away */ -+ -+ /* Invalid IDP cannot be processed */ -+ if (crl->idp_flags & IDP_INVALID) -+ return 0; -+ /* Reason codes or indirect CRLs need extended CRL support */ -+ if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { -+ if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) -+ return 0; -+ } else if (crl->idp_flags & IDP_REASONS) { -+ /* If no new reasons reject */ -+ if (!(crl->idp_reasons & ~tmp_reasons)) -+ return 0; -+ } -+ /* Don't process deltas at this stage */ -+ else if (crl->base_crl_number) -+ return 0; -+ /* If issuer name doesn't match certificate need indirect CRL */ -+ if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { -+ if (!(crl->idp_flags & IDP_INDIRECT)) -+ return 0; -+ } else -+ crl_score |= CRL_SCORE_ISSUER_NAME; -+ -+ if (!(crl->flags & EXFLAG_CRITICAL)) -+ crl_score |= CRL_SCORE_NOCRITICAL; -+ -+ /* Check expiry */ -+ if (check_crl_time(ctx, crl, 0)) -+ crl_score |= CRL_SCORE_TIME; -+ -+ /* Check authority key ID and locate certificate issuer */ -+ crl_akid_check(ctx, crl, pissuer, &crl_score); -+ -+ /* If we can't locate certificate issuer at this point forget it */ -+ -+ if (!(crl_score & CRL_SCORE_AKID)) -+ return 0; -+ -+ /* Check cert for matching CRL distribution points */ -+ -+ if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { -+ /* If no new reasons reject */ -+ if (!(crl_reasons & ~tmp_reasons)) -+ return 0; -+ tmp_reasons |= crl_reasons; -+ crl_score |= CRL_SCORE_SCOPE; -+ } -+ -+ *preasons = tmp_reasons; -+ -+ return crl_score; -+ -+} -+ -+static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, -+ X509 **pissuer, int *pcrl_score) -+{ -+ X509 *crl_issuer = NULL; -+ X509_NAME *cnm = X509_CRL_get_issuer(crl); -+ int cidx = ctx->error_depth; -+ int i; -+ -+ if (cidx != sk_X509_num(ctx->chain) - 1) -+ cidx++; -+ -+ crl_issuer = sk_X509_value(ctx->chain, cidx); -+ -+ if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { -+ if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { -+ *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT; -+ *pissuer = crl_issuer; -+ return; -+ } -+ } -+ -+ for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) { -+ crl_issuer = sk_X509_value(ctx->chain, cidx); -+ if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) -+ continue; -+ if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { -+ *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH; -+ *pissuer = crl_issuer; -+ return; -+ } -+ } -+ -+ /* Anything else needs extended CRL support */ -+ -+ if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) -+ return; -+ -+ /* -+ * Otherwise the CRL issuer is not on the path. Look for it in the set of -+ * untrusted certificates. -+ */ -+ for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { -+ crl_issuer = sk_X509_value(ctx->untrusted, i); -+ if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) -+ continue; -+ if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { -+ *pissuer = crl_issuer; -+ *pcrl_score |= CRL_SCORE_AKID; -+ return; -+ } -+ } -+} -+ -+/* -+ * Check the path of a CRL issuer certificate. This creates a new -+ * X509_STORE_CTX and populates it with most of the parameters from the -+ * parent. This could be optimised somewhat since a lot of path checking will -+ * be duplicated by the parent, but this will rarely be used in practice. -+ */ -+ -+static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) -+{ -+ X509_STORE_CTX crl_ctx; -+ int ret; -+ -+ /* Don't allow recursive CRL path validation */ -+ if (ctx->parent) -+ return 0; -+ if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) -+ return -1; -+ -+ crl_ctx.crls = ctx->crls; -+ /* Copy verify params across */ -+ X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); -+ -+ crl_ctx.parent = ctx; -+ crl_ctx.verify_cb = ctx->verify_cb; -+ -+ /* Verify CRL issuer */ -+ ret = X509_verify_cert(&crl_ctx); -+ if (ret <= 0) -+ goto err; -+ -+ /* Check chain is acceptable */ -+ ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); -+ err: -+ X509_STORE_CTX_cleanup(&crl_ctx); -+ return ret; -+} -+ -+/* -+ * RFC3280 says nothing about the relationship between CRL path and -+ * certificate path, which could lead to situations where a certificate could -+ * be revoked or validated by a CA not authorised to do so. RFC5280 is more -+ * strict and states that the two paths must end in the same trust anchor, -+ * though some discussions remain... until this is resolved we use the -+ * RFC5280 version -+ */ -+ -+static int check_crl_chain(X509_STORE_CTX *ctx, -+ STACK_OF(X509) *cert_path, -+ STACK_OF(X509) *crl_path) -+{ -+ X509 *cert_ta, *crl_ta; -+ cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); -+ crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); -+ if (!X509_cmp(cert_ta, crl_ta)) -+ return 1; -+ return 0; -+} -+ -+/*- -+ * Check for match between two dist point names: three separate cases. -+ * 1. Both are relative names and compare X509_NAME types. -+ * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. -+ * 3. Both are full names and compare two GENERAL_NAMES. -+ * 4. One is NULL: automatic match. -+ */ -+ -+static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) -+{ -+ X509_NAME *nm = NULL; -+ GENERAL_NAMES *gens = NULL; -+ GENERAL_NAME *gena, *genb; -+ int i, j; -+ if (!a || !b) -+ return 1; -+ if (a->type == 1) { -+ if (!a->dpname) -+ return 0; -+ /* Case 1: two X509_NAME */ -+ if (b->type == 1) { -+ if (!b->dpname) -+ return 0; -+ if (!X509_NAME_cmp(a->dpname, b->dpname)) -+ return 1; -+ else -+ return 0; -+ } -+ /* Case 2: set name and GENERAL_NAMES appropriately */ -+ nm = a->dpname; -+ gens = b->name.fullname; -+ } else if (b->type == 1) { -+ if (!b->dpname) -+ return 0; -+ /* Case 2: set name and GENERAL_NAMES appropriately */ -+ gens = a->name.fullname; -+ nm = b->dpname; -+ } -+ -+ /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ -+ if (nm) { -+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { -+ gena = sk_GENERAL_NAME_value(gens, i); -+ if (gena->type != GEN_DIRNAME) -+ continue; -+ if (!X509_NAME_cmp(nm, gena->d.directoryName)) -+ return 1; -+ } -+ return 0; -+ } -+ -+ /* Else case 3: two GENERAL_NAMES */ -+ -+ for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) { -+ gena = sk_GENERAL_NAME_value(a->name.fullname, i); -+ for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { -+ genb = sk_GENERAL_NAME_value(b->name.fullname, j); -+ if (!GENERAL_NAME_cmp(gena, genb)) -+ return 1; -+ } -+ } -+ -+ return 0; -+ -+} -+ -+static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) -+{ -+ int i; -+ X509_NAME *nm = X509_CRL_get_issuer(crl); -+ /* If no CRLissuer return is successful iff don't need a match */ -+ if (!dp->CRLissuer) -+ return ! !(crl_score & CRL_SCORE_ISSUER_NAME); -+ for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { -+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); -+ if (gen->type != GEN_DIRNAME) -+ continue; -+ if (!X509_NAME_cmp(gen->d.directoryName, nm)) -+ return 1; -+ } -+ return 0; -+} -+ -+/* Check CRLDP and IDP */ -+ -+static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, -+ unsigned int *preasons) -+{ -+ int i; -+ if (crl->idp_flags & IDP_ONLYATTR) -+ return 0; -+ if (x->ex_flags & EXFLAG_CA) { -+ if (crl->idp_flags & IDP_ONLYUSER) -+ return 0; -+ } else { -+ if (crl->idp_flags & IDP_ONLYCA) -+ return 0; -+ } -+ *preasons = crl->idp_reasons; -+ for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { -+ DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); -+ if (crldp_check_crlissuer(dp, crl, crl_score)) { -+ if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) { -+ *preasons &= dp->dp_reasons; -+ return 1; -+ } -+ } -+ } -+ if ((!crl->idp || !crl->idp->distpoint) -+ && (crl_score & CRL_SCORE_ISSUER_NAME)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * Retrieve CRL corresponding to current certificate. If deltas enabled try -+ * to find a delta CRL too -+ */ -+ -+static int get_crl_delta(X509_STORE_CTX *ctx, -+ X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) -+{ -+ int ok; -+ X509 *issuer = NULL; -+ int crl_score = 0; -+ unsigned int reasons; -+ X509_CRL *crl = NULL, *dcrl = NULL; -+ STACK_OF(X509_CRL) *skcrl; -+ X509_NAME *nm = X509_get_issuer_name(x); -+ -+ reasons = ctx->current_reasons; -+ ok = get_crl_sk(ctx, &crl, &dcrl, -+ &issuer, &crl_score, &reasons, ctx->crls); -+ if (ok) -+ goto done; -+ -+ /* Lookup CRLs from store */ -+ -+ skcrl = ctx->lookup_crls(ctx, nm); -+ -+ /* If no CRLs found and a near match from get_crl_sk use that */ -+ if (!skcrl && crl) -+ goto done; -+ -+ get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); -+ -+ sk_X509_CRL_pop_free(skcrl, X509_CRL_free); -+ -+ done: -+ /* If we got any kind of CRL use it and return success */ -+ if (crl) { -+ ctx->current_issuer = issuer; -+ ctx->current_crl_score = crl_score; -+ ctx->current_reasons = reasons; -+ *pcrl = crl; -+ *pdcrl = dcrl; -+ return 1; -+ } -+ return 0; -+} -+ -+/* Check CRL validity */ -+static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) -+{ -+ X509 *issuer = NULL; -+ EVP_PKEY *ikey = NULL; -+ int cnum = ctx->error_depth; -+ int chnum = sk_X509_num(ctx->chain) - 1; -+ -+ /* if we have an alternative CRL issuer cert use that */ -+ if (ctx->current_issuer) -+ issuer = ctx->current_issuer; -+ /* -+ * Else find CRL issuer: if not last certificate then issuer is next -+ * certificate in chain. -+ */ -+ else if (cnum < chnum) -+ issuer = sk_X509_value(ctx->chain, cnum + 1); -+ else { -+ issuer = sk_X509_value(ctx->chain, chnum); -+ /* If not self signed, can't check signature */ -+ if (!ctx->check_issued(ctx, issuer, issuer) && -+ !verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER)) -+ return 0; -+ } -+ -+ if (issuer == NULL) -+ return 1; -+ -+ /* -+ * Skip most tests for deltas because they have already been done -+ */ -+ if (!crl->base_crl_number) { -+ /* Check for cRLSign bit if keyUsage present */ -+ if ((issuer->ex_flags & EXFLAG_KUSAGE) && -+ !(issuer->ex_kusage & KU_CRL_SIGN) && -+ !verify_cb_crl(ctx, X509_V_ERR_KEYUSAGE_NO_CRL_SIGN)) -+ return 0; -+ -+ if (!(ctx->current_crl_score & CRL_SCORE_SCOPE) && -+ !verify_cb_crl(ctx, X509_V_ERR_DIFFERENT_CRL_SCOPE)) -+ return 0; -+ -+ if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH) && -+ check_crl_path(ctx, ctx->current_issuer) <= 0 && -+ !verify_cb_crl(ctx, X509_V_ERR_CRL_PATH_VALIDATION_ERROR)) -+ return 0; -+ -+ if ((crl->idp_flags & IDP_INVALID) && -+ !verify_cb_crl(ctx, X509_V_ERR_INVALID_EXTENSION)) -+ return 0; -+ } -+ -+ if (!(ctx->current_crl_score & CRL_SCORE_TIME) && -+ !check_crl_time(ctx, crl, 1)) -+ return 0; -+ -+ /* Attempt to get issuer certificate public key */ -+ ikey = X509_get0_pubkey(issuer); -+ -+ if (!ikey && -+ !verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)) -+ return 0; -+ -+ if (ikey) { -+ int rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags); -+ -+ if (rv != X509_V_OK && !verify_cb_crl(ctx, rv)) -+ return 0; -+ /* Verify CRL signature */ -+ if (X509_CRL_verify(crl, ikey) <= 0 && -+ !verify_cb_crl(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE)) -+ return 0; -+ } -+ return 1; -+} -+ -+/* Check certificate against CRL */ -+static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) -+{ -+ X509_REVOKED *rev; -+ -+ /* -+ * The rules changed for this... previously if a CRL contained unhandled -+ * critical extensions it could still be used to indicate a certificate -+ * was revoked. This has since been changed since critical extensions can -+ * change the meaning of CRL entries. -+ */ -+ if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) -+ && (crl->flags & EXFLAG_CRITICAL) && -+ !verify_cb_crl(ctx, X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION)) -+ return 0; -+ /* -+ * Look for serial number of certificate in CRL. If found, make sure -+ * reason is not removeFromCRL. -+ */ -+ if (X509_CRL_get0_by_cert(crl, &rev, x)) { -+ if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) -+ return 2; -+ if (!verify_cb_crl(ctx, X509_V_ERR_CERT_REVOKED)) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int check_policy(X509_STORE_CTX *ctx) -+{ -+ int ret; -+ -+ if (ctx->parent) -+ return 1; -+ /* -+ * With DANE, the trust anchor might be a bare public key, not a -+ * certificate! In that case our chain does not have the trust anchor -+ * certificate as a top-most element. This comports well with RFC5280 -+ * chain verification, since there too, the trust anchor is not part of the -+ * chain to be verified. In particular, X509_policy_check() does not look -+ * at the TA cert, but assumes that it is present as the top-most chain -+ * element. We therefore temporarily push a NULL cert onto the chain if it -+ * was verified via a bare public key, and pop it off right after the -+ * X509_policy_check() call. -+ */ -+ if (ctx->bare_ta_signed && !sk_X509_push(ctx->chain, NULL)) { -+ X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE); -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ return 0; -+ } -+ ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, -+ ctx->param->policies, ctx->param->flags); -+ if (ctx->bare_ta_signed) -+ sk_X509_pop(ctx->chain); -+ -+ if (ret == X509_PCY_TREE_INTERNAL) { -+ X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE); -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ return 0; -+ } -+ /* Invalid or inconsistent extensions */ -+ if (ret == X509_PCY_TREE_INVALID) { -+ int i; -+ -+ /* Locate certificates with bad extensions and notify callback. */ -+ for (i = 1; i < sk_X509_num(ctx->chain); i++) { -+ X509 *x = sk_X509_value(ctx->chain, i); -+ -+ if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) -+ continue; -+ if (!verify_cb_cert(ctx, x, i, -+ X509_V_ERR_INVALID_POLICY_EXTENSION)) -+ return 0; -+ } -+ return 1; -+ } -+ if (ret == X509_PCY_TREE_FAILURE) { -+ ctx->current_cert = NULL; -+ ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY; -+ return ctx->verify_cb(0, ctx); -+ } -+ if (ret != X509_PCY_TREE_VALID) { -+ X509err(X509_F_CHECK_POLICY, ERR_R_INTERNAL_ERROR); -+ return 0; -+ } -+ -+ if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { -+ ctx->current_cert = NULL; -+ /* -+ * Verification errors need to be "sticky", a callback may have allowed -+ * an SSL handshake to continue despite an error, and we must then -+ * remain in an error state. Therefore, we MUST NOT clear earlier -+ * verification errors by setting the error to X509_V_OK. -+ */ -+ if (!ctx->verify_cb(2, ctx)) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+/*- -+ * Check certificate validity times. -+ * If depth >= 0, invoke verification callbacks on error, otherwise just return -+ * the validation status. -+ * -+ * Return 1 on success, 0 otherwise. -+ */ -+int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) -+{ -+ time_t *ptime; -+ int i; -+ -+ if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) -+ ptime = &ctx->param->check_time; -+ else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) -+ return 1; -+ else -+ ptime = NULL; -+ -+ i = X509_cmp_time(X509_get0_notBefore(x), ptime); -+ if (i >= 0 && depth < 0) -+ return 0; -+ if (i == 0 && !verify_cb_cert(ctx, x, depth, -+ X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD)) -+ return 0; -+ if (i > 0 && !verify_cb_cert(ctx, x, depth, X509_V_ERR_CERT_NOT_YET_VALID)) -+ return 0; -+ -+ i = X509_cmp_time(X509_get0_notAfter(x), ptime); -+ if (i <= 0 && depth < 0) -+ return 0; -+ if (i == 0 && !verify_cb_cert(ctx, x, depth, -+ X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD)) -+ return 0; -+ if (i < 0 && !verify_cb_cert(ctx, x, depth, X509_V_ERR_CERT_HAS_EXPIRED)) -+ return 0; -+ return 1; -+} -+ -+static int internal_verify(X509_STORE_CTX *ctx) -+{ -+ int n = sk_X509_num(ctx->chain) - 1; -+ X509 *xi = sk_X509_value(ctx->chain, n); -+ X509 *xs; -+ -+ /* -+ * With DANE-verified bare public key TA signatures, it remains only to -+ * check the timestamps of the top certificate. We report the issuer as -+ * NULL, since all we have is a bare key. -+ */ -+ if (ctx->bare_ta_signed) { -+ xs = xi; -+ xi = NULL; -+ goto check_cert; -+ } -+ -+ if (ctx->check_issued(ctx, xi, xi)) -+ xs = xi; -+ else { -+ if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { -+ xs = xi; -+ goto check_cert; -+ } -+ if (n <= 0) -+ return verify_cb_cert(ctx, xi, 0, -+ X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE); -+ n--; -+ ctx->error_depth = n; -+ xs = sk_X509_value(ctx->chain, n); -+ } -+ -+ /* -+ * Do not clear ctx->error=0, it must be "sticky", only the user's callback -+ * is allowed to reset errors (at its own peril). -+ */ -+ while (n >= 0) { -+ EVP_PKEY *pkey; -+ -+ /* -+ * Skip signature check for self signed certificates unless explicitly -+ * asked for. It doesn't add any security and just wastes time. If -+ * the issuer's public key is unusable, report the issuer certificate -+ * and its depth (rather than the depth of the subject). -+ */ -+ if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) { -+ if ((pkey = X509_get0_pubkey(xi)) == NULL) { -+ if (!verify_cb_cert(ctx, xi, xi != xs ? n+1 : n, -+ X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)) -+ return 0; -+ } else if (X509_verify(xs, pkey) <= 0) { -+ if (!verify_cb_cert(ctx, xs, n, -+ X509_V_ERR_CERT_SIGNATURE_FAILURE)) -+ return 0; -+ } -+ } -+ -+ check_cert: -+ /* Calls verify callback as needed */ -+ if (!x509_check_cert_time(ctx, xs, n)) -+ return 0; -+ -+ /* -+ * Signal success at this depth. However, the previous error (if any) -+ * is retained. -+ */ -+ ctx->current_issuer = xi; -+ ctx->current_cert = xs; -+ ctx->error_depth = n; -+ if (!ctx->verify_cb(1, ctx)) -+ return 0; -+ -+ if (--n >= 0) { -+ xi = xs; -+ xs = sk_X509_value(ctx->chain, n); -+ } -+ } -+ return 1; -+} -+ -+int X509_cmp_current_time(const ASN1_TIME *ctm) -+{ -+ return X509_cmp_time(ctm, NULL); -+} -+ -+int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) -+{ -+ char *str; -+ ASN1_TIME atm; -+ long offset; -+ char buff1[24], buff2[24], *p; -+ int i, j, remaining; -+ -+ p = buff1; -+ remaining = ctm->length; -+ str = (char *)ctm->data; -+ /* -+ * Note that the following (historical) code allows much more slack in the -+ * time format than RFC5280. In RFC5280, the representation is fixed: -+ * UTCTime: YYMMDDHHMMSSZ -+ * GeneralizedTime: YYYYMMDDHHMMSSZ -+ */ -+ if (ctm->type == V_ASN1_UTCTIME) { -+ /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */ -+ int min_length = sizeof("YYMMDDHHMMZ") - 1; -+ int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1; -+ if (remaining < min_length || remaining > max_length) -+ return 0; -+ memcpy(p, str, 10); -+ p += 10; -+ str += 10; -+ remaining -= 10; -+ } else { -+ /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */ -+ int min_length = sizeof("YYYYMMDDHHMMZ") - 1; -+ int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1; -+ if (remaining < min_length || remaining > max_length) -+ return 0; -+ memcpy(p, str, 12); -+ p += 12; -+ str += 12; -+ remaining -= 12; -+ } -+ -+ if ((*str == 'Z') || (*str == '-') || (*str == '+')) { -+ *(p++) = '0'; -+ *(p++) = '0'; -+ } else { -+ /* SS (seconds) */ -+ if (remaining < 2) -+ return 0; -+ *(p++) = *(str++); -+ *(p++) = *(str++); -+ remaining -= 2; -+ /* -+ * Skip any (up to three) fractional seconds... -+ * TODO(emilia): in RFC5280, fractional seconds are forbidden. -+ * Can we just kill them altogether? -+ */ -+ if (remaining && *str == '.') { -+ str++; -+ remaining--; -+ for (i = 0; i < 3 && remaining; i++, str++, remaining--) { -+ if (*str < '0' || *str > '9') -+ break; -+ } -+ } -+ -+ } -+ *(p++) = 'Z'; -+ *(p++) = '\0'; -+ -+ /* We now need either a terminating 'Z' or an offset. */ -+ if (!remaining) -+ return 0; -+ if (*str == 'Z') { -+ if (remaining != 1) -+ return 0; -+ offset = 0; -+ } else { -+ /* (+-)HHMM */ -+ if ((*str != '+') && (*str != '-')) -+ return 0; -+ /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */ -+ if (remaining != 5) -+ return 0; -+ if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' || -+ str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9') -+ return 0; -+ offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60; -+ offset += (str[3] - '0') * 10 + (str[4] - '0'); -+ if (*str == '-') -+ offset = -offset; -+ } -+ atm.type = ctm->type; -+ atm.flags = 0; -+ atm.length = sizeof(buff2); -+ atm.data = (unsigned char *)buff2; -+ -+ if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL) -+ return 0; -+ -+ if (ctm->type == V_ASN1_UTCTIME) { -+ i = (buff1[0] - '0') * 10 + (buff1[1] - '0'); -+ if (i < 50) -+ i += 100; /* cf. RFC 2459 */ -+ j = (buff2[0] - '0') * 10 + (buff2[1] - '0'); -+ if (j < 50) -+ j += 100; -+ -+ if (i < j) -+ return -1; -+ if (i > j) -+ return 1; -+ } -+ i = strcmp(buff1, buff2); -+ if (i == 0) /* wait a second then return younger :-) */ -+ return -1; -+ else -+ return i; -+} -+ -+ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) -+{ -+ return X509_time_adj(s, adj, NULL); -+} -+ -+ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) -+{ -+ return X509_time_adj_ex(s, 0, offset_sec, in_tm); -+} -+ -+ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, -+ int offset_day, long offset_sec, time_t *in_tm) -+{ -+ time_t t; -+ -+ if (in_tm) -+ t = *in_tm; -+ else -+ time(&t); -+ -+ if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) { -+ if (s->type == V_ASN1_UTCTIME) -+ return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); -+ if (s->type == V_ASN1_GENERALIZEDTIME) -+ return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); -+ } -+ return ASN1_TIME_adj(s, t, offset_day, offset_sec); -+} -+ -+int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) -+{ -+ EVP_PKEY *ktmp = NULL, *ktmp2; -+ int i, j; -+ -+ if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) -+ return 1; -+ -+ for (i = 0; i < sk_X509_num(chain); i++) { -+ ktmp = X509_get0_pubkey(sk_X509_value(chain, i)); -+ if (ktmp == NULL) { -+ X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, -+ X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); -+ return 0; -+ } -+ if (!EVP_PKEY_missing_parameters(ktmp)) -+ break; -+ } -+ if (ktmp == NULL) { -+ X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, -+ X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); -+ return 0; -+ } -+ -+ /* first, populate the other certs */ -+ for (j = i - 1; j >= 0; j--) { -+ ktmp2 = X509_get0_pubkey(sk_X509_value(chain, j)); -+ EVP_PKEY_copy_parameters(ktmp2, ktmp); -+ } -+ -+ if (pkey != NULL) -+ EVP_PKEY_copy_parameters(pkey, ktmp); -+ return 1; -+} -+ -+/* Make a delta CRL as the diff between two full CRLs */ -+ -+X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, -+ EVP_PKEY *skey, const EVP_MD *md, unsigned int flags) -+{ -+ X509_CRL *crl = NULL; -+ int i; -+ STACK_OF(X509_REVOKED) *revs = NULL; -+ /* CRLs can't be delta already */ -+ if (base->base_crl_number || newer->base_crl_number) { -+ X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_ALREADY_DELTA); -+ return NULL; -+ } -+ /* Base and new CRL must have a CRL number */ -+ if (!base->crl_number || !newer->crl_number) { -+ X509err(X509_F_X509_CRL_DIFF, X509_R_NO_CRL_NUMBER); -+ return NULL; -+ } -+ /* Issuer names must match */ -+ if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) { -+ X509err(X509_F_X509_CRL_DIFF, X509_R_ISSUER_MISMATCH); -+ return NULL; -+ } -+ /* AKID and IDP must match */ -+ if (!crl_extension_match(base, newer, NID_authority_key_identifier)) { -+ X509err(X509_F_X509_CRL_DIFF, X509_R_AKID_MISMATCH); -+ return NULL; -+ } -+ if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) { -+ X509err(X509_F_X509_CRL_DIFF, X509_R_IDP_MISMATCH); -+ return NULL; -+ } -+ /* Newer CRL number must exceed full CRL number */ -+ if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) { -+ X509err(X509_F_X509_CRL_DIFF, X509_R_NEWER_CRL_NOT_NEWER); -+ return NULL; -+ } -+ /* CRLs must verify */ -+ if (skey && (X509_CRL_verify(base, skey) <= 0 || -+ X509_CRL_verify(newer, skey) <= 0)) { -+ X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_VERIFY_FAILURE); -+ return NULL; -+ } -+ /* Create new CRL */ -+ crl = X509_CRL_new(); -+ if (crl == NULL || !X509_CRL_set_version(crl, 1)) -+ goto memerr; -+ /* Set issuer name */ -+ if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer))) -+ goto memerr; -+ -+ if (!X509_CRL_set1_lastUpdate(crl, X509_CRL_get0_lastUpdate(newer))) -+ goto memerr; -+ if (!X509_CRL_set1_nextUpdate(crl, X509_CRL_get0_nextUpdate(newer))) -+ goto memerr; -+ -+ /* Set base CRL number: must be critical */ -+ -+ if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0)) -+ goto memerr; -+ -+ /* -+ * Copy extensions across from newest CRL to delta: this will set CRL -+ * number to correct value too. -+ */ -+ -+ for (i = 0; i < X509_CRL_get_ext_count(newer); i++) { -+ X509_EXTENSION *ext; -+ ext = X509_CRL_get_ext(newer, i); -+ if (!X509_CRL_add_ext(crl, ext, -1)) -+ goto memerr; -+ } -+ -+ /* Go through revoked entries, copying as needed */ -+ -+ revs = X509_CRL_get_REVOKED(newer); -+ -+ for (i = 0; i < sk_X509_REVOKED_num(revs); i++) { -+ X509_REVOKED *rvn, *rvtmp; -+ rvn = sk_X509_REVOKED_value(revs, i); -+ /* -+ * Add only if not also in base. TODO: need something cleverer here -+ * for some more complex CRLs covering multiple CAs. -+ */ -+ if (!X509_CRL_get0_by_serial(base, &rvtmp, &rvn->serialNumber)) { -+ rvtmp = X509_REVOKED_dup(rvn); -+ if (!rvtmp) -+ goto memerr; -+ if (!X509_CRL_add0_revoked(crl, rvtmp)) { -+ X509_REVOKED_free(rvtmp); -+ goto memerr; -+ } -+ } -+ } -+ /* TODO: optionally prune deleted entries */ -+ -+ if (skey && md && !X509_CRL_sign(crl, skey, md)) -+ goto memerr; -+ -+ return crl; -+ -+ memerr: -+ X509err(X509_F_X509_CRL_DIFF, ERR_R_MALLOC_FAILURE); -+ X509_CRL_free(crl); -+ return NULL; -+} -+ -+int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) -+{ -+ return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); -+} -+ -+void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) -+{ -+ return CRYPTO_get_ex_data(&ctx->ex_data, idx); -+} -+ -+int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) -+{ -+ return ctx->error; -+} -+ -+void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) -+{ -+ ctx->error = err; -+} -+ -+int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) -+{ -+ return ctx->error_depth; -+} -+ -+void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth) -+{ -+ ctx->error_depth = depth; -+} -+ -+X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) -+{ -+ return ctx->current_cert; -+} -+ -+void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x) -+{ -+ ctx->current_cert = x; -+} -+ -+STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx) -+{ -+ return ctx->chain; -+} -+ -+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) -+{ -+ if (!ctx->chain) -+ return NULL; -+ return X509_chain_up_ref(ctx->chain); -+} -+ -+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) -+{ -+ return ctx->current_issuer; -+} -+ -+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) -+{ -+ return ctx->current_crl; -+} -+ -+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) -+{ -+ return ctx->parent; -+} -+ -+void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) -+{ -+ ctx->cert = x; -+} -+ -+void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) -+{ -+ ctx->crls = sk; -+} -+ -+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) -+{ -+ /* -+ * XXX: Why isn't this function always used to set the associated trust? -+ * Should there even be a VPM->trust field at all? Or should the trust -+ * always be inferred from the purpose by X509_STORE_CTX_init(). -+ */ -+ return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); -+} -+ -+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) -+{ -+ /* -+ * XXX: See above, this function would only be needed when the default -+ * trust for the purpose needs an override in a corner case. -+ */ -+ return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); -+} -+ -+/* -+ * This function is used to set the X509_STORE_CTX purpose and trust values. -+ * This is intended to be used when another structure has its own trust and -+ * purpose values which (if set) will be inherited by the ctx. If they aren't -+ * set then we will usually have a default purpose in mind which should then -+ * be used to set the trust value. An example of this is SSL use: an SSL -+ * structure will have its own purpose and trust settings which the -+ * application can set: if they aren't set then we use the default of SSL -+ * client/server. -+ */ -+ -+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, -+ int purpose, int trust) -+{ -+ int idx; -+ /* If purpose not set use default */ -+ if (!purpose) -+ purpose = def_purpose; -+ /* If we have a purpose then check it is valid */ -+ if (purpose) { -+ X509_PURPOSE *ptmp; -+ idx = X509_PURPOSE_get_by_id(purpose); -+ if (idx == -1) { -+ X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, -+ X509_R_UNKNOWN_PURPOSE_ID); -+ return 0; -+ } -+ ptmp = X509_PURPOSE_get0(idx); -+ if (ptmp->trust == X509_TRUST_DEFAULT) { -+ idx = X509_PURPOSE_get_by_id(def_purpose); -+ /* -+ * XXX: In the two callers above def_purpose is always 0, which is -+ * not a known value, so idx will always be -1. How is the -+ * X509_TRUST_DEFAULT case actually supposed to be handled? -+ */ -+ if (idx == -1) { -+ X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, -+ X509_R_UNKNOWN_PURPOSE_ID); -+ return 0; -+ } -+ ptmp = X509_PURPOSE_get0(idx); -+ } -+ /* If trust not set then get from purpose default */ -+ if (!trust) -+ trust = ptmp->trust; -+ } -+ if (trust) { -+ idx = X509_TRUST_get_by_id(trust); -+ if (idx == -1) { -+ X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, -+ X509_R_UNKNOWN_TRUST_ID); -+ return 0; -+ } -+ } -+ -+ if (purpose && !ctx->param->purpose) -+ ctx->param->purpose = purpose; -+ if (trust && !ctx->param->trust) -+ ctx->param->trust = trust; -+ return 1; -+} -+ -+X509_STORE_CTX *X509_STORE_CTX_new(void) -+{ -+ X509_STORE_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); -+ -+ if (ctx == NULL) { -+ X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ return ctx; -+} -+ -+void X509_STORE_CTX_free(X509_STORE_CTX *ctx) -+{ -+ if (ctx == NULL) -+ return; -+ -+ X509_STORE_CTX_cleanup(ctx); -+ OPENSSL_free(ctx); -+} -+ -+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, -+ STACK_OF(X509) *chain) -+{ -+ int ret = 1; -+ -+ ctx->ctx = store; -+ ctx->cert = x509; -+ ctx->untrusted = chain; -+ ctx->crls = NULL; -+ ctx->num_untrusted = 0; -+ ctx->other_ctx = NULL; -+ ctx->valid = 0; -+ ctx->chain = NULL; -+ ctx->error = 0; -+ ctx->explicit_policy = 0; -+ ctx->error_depth = 0; -+ ctx->current_cert = NULL; -+ ctx->current_issuer = NULL; -+ ctx->current_crl = NULL; -+ ctx->current_crl_score = 0; -+ ctx->current_reasons = 0; -+ ctx->tree = NULL; -+ ctx->parent = NULL; -+ ctx->dane = NULL; -+ ctx->bare_ta_signed = 0; -+ /* Zero ex_data to make sure we're cleanup-safe */ -+ memset(&ctx->ex_data, 0, sizeof(ctx->ex_data)); -+ -+ /* store->cleanup is always 0 in OpenSSL, if set must be idempotent */ -+ if (store) -+ ctx->cleanup = store->cleanup; -+ else -+ ctx->cleanup = 0; -+ -+ if (store && store->check_issued) -+ ctx->check_issued = store->check_issued; -+ else -+ ctx->check_issued = check_issued; -+ -+ if (store && store->get_issuer) -+ ctx->get_issuer = store->get_issuer; -+ else -+ ctx->get_issuer = X509_STORE_CTX_get1_issuer; -+ -+ if (store && store->verify_cb) -+ ctx->verify_cb = store->verify_cb; -+ else -+ ctx->verify_cb = null_callback; -+ -+ if (store && store->verify) -+ ctx->verify = store->verify; -+ else -+ ctx->verify = internal_verify; -+ -+ if (store && store->check_revocation) -+ ctx->check_revocation = store->check_revocation; -+ else -+ ctx->check_revocation = check_revocation; -+ -+ if (store && store->get_crl) -+ ctx->get_crl = store->get_crl; -+ else -+ ctx->get_crl = NULL; -+ -+ if (store && store->check_crl) -+ ctx->check_crl = store->check_crl; -+ else -+ ctx->check_crl = check_crl; -+ -+ if (store && store->cert_crl) -+ ctx->cert_crl = store->cert_crl; -+ else -+ ctx->cert_crl = cert_crl; -+ -+ if (store && store->check_policy) -+ ctx->check_policy = store->check_policy; -+ else -+ ctx->check_policy = check_policy; -+ -+ if (store && store->lookup_certs) -+ ctx->lookup_certs = store->lookup_certs; -+ else -+ ctx->lookup_certs = X509_STORE_CTX_get1_certs; -+ -+ if (store && store->lookup_crls) -+ ctx->lookup_crls = store->lookup_crls; -+ else -+ ctx->lookup_crls = X509_STORE_CTX_get1_crls; -+ -+ ctx->param = X509_VERIFY_PARAM_new(); -+ if (ctx->param == NULL) { -+ X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* -+ * Inherit callbacks and flags from X509_STORE if not set use defaults. -+ */ -+ if (store) -+ ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); -+ else -+ ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE; -+ -+ if (ret) -+ ret = X509_VERIFY_PARAM_inherit(ctx->param, -+ X509_VERIFY_PARAM_lookup("default")); -+ -+ if (ret == 0) { -+ X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* -+ * XXX: For now, continue to inherit trust from VPM, but infer from the -+ * purpose if this still yields the default value. -+ */ -+ if (ctx->param->trust == X509_TRUST_DEFAULT) { -+ int idx = X509_PURPOSE_get_by_id(ctx->param->purpose); -+ X509_PURPOSE *xp = X509_PURPOSE_get0(idx); -+ -+ if (xp != NULL) -+ ctx->param->trust = X509_PURPOSE_get_trust(xp); -+ } -+ -+ if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, -+ &ctx->ex_data)) -+ return 1; -+ X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); -+ -+ err: -+ /* -+ * On error clean up allocated storage, if the store context was not -+ * allocated with X509_STORE_CTX_new() this is our last chance to do so. -+ */ -+ X509_STORE_CTX_cleanup(ctx); -+ return 0; -+} -+ -+/* -+ * Set alternative lookup method: just a STACK of trusted certificates. This -+ * avoids X509_STORE nastiness where it isn't needed. -+ */ -+void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) -+{ -+ ctx->other_ctx = sk; -+ ctx->get_issuer = get_issuer_sk; -+ ctx->lookup_certs = lookup_certs_sk; -+} -+ -+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) -+{ -+ /* -+ * We need to be idempotent because, unfortunately, free() also calls -+ * cleanup(), so the natural call sequence new(), init(), cleanup(), free() -+ * calls cleanup() for the same object twice! Thus we must zero the -+ * pointers below after they're freed! -+ */ -+ /* Seems to always be 0 in OpenSSL, do this at most once. */ -+ if (ctx->cleanup != NULL) { -+ ctx->cleanup(ctx); -+ ctx->cleanup = NULL; -+ } -+ if (ctx->param != NULL) { -+ if (ctx->parent == NULL) -+ X509_VERIFY_PARAM_free(ctx->param); -+ ctx->param = NULL; -+ } -+ X509_policy_tree_free(ctx->tree); -+ ctx->tree = NULL; -+ sk_X509_pop_free(ctx->chain, X509_free); -+ ctx->chain = NULL; -+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data)); -+ memset(&ctx->ex_data, 0, sizeof(ctx->ex_data)); -+} -+ -+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) -+{ -+ X509_VERIFY_PARAM_set_depth(ctx->param, depth); -+} -+ -+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) -+{ -+ X509_VERIFY_PARAM_set_flags(ctx->param, flags); -+} -+ -+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, -+ time_t t) -+{ -+ X509_VERIFY_PARAM_set_time(ctx->param, t); -+} -+ -+X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) -+{ -+ return ctx->cert; -+} -+ -+STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) -+{ -+ return ctx->untrusted; -+} -+ -+void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) -+{ -+ ctx->untrusted = sk; -+} -+ -+void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) -+{ -+ sk_X509_pop_free(ctx->chain, X509_free); -+ ctx->chain = sk; -+} -+ -+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, -+ X509_STORE_CTX_verify_cb verify_cb) -+{ -+ ctx->verify_cb = verify_cb; -+} -+ -+X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx) -+{ -+ return ctx->verify_cb; -+} -+ -+void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, -+ X509_STORE_CTX_verify_fn verify) -+{ -+ ctx->verify = verify; -+} -+ -+X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx) -+{ -+ return ctx->verify; -+} -+ -+X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(X509_STORE_CTX *ctx) -+{ -+ return ctx->get_issuer; -+} -+ -+X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx) -+{ -+ return ctx->check_issued; -+} -+ -+X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(X509_STORE_CTX *ctx) -+{ -+ return ctx->check_revocation; -+} -+ -+X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(X509_STORE_CTX *ctx) -+{ -+ return ctx->get_crl; -+} -+ -+X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(X509_STORE_CTX *ctx) -+{ -+ return ctx->check_crl; -+} -+ -+X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(X509_STORE_CTX *ctx) -+{ -+ return ctx->cert_crl; -+} -+ -+X509_STORE_CTX_check_policy_fn X509_STORE_CTX_get_check_policy(X509_STORE_CTX *ctx) -+{ -+ return ctx->check_policy; -+} -+ -+X509_STORE_CTX_lookup_certs_fn X509_STORE_CTX_get_lookup_certs(X509_STORE_CTX *ctx) -+{ -+ return ctx->lookup_certs; -+} -+ -+X509_STORE_CTX_lookup_crls_fn X509_STORE_CTX_get_lookup_crls(X509_STORE_CTX *ctx) -+{ -+ return ctx->lookup_crls; -+} -+ -+X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(X509_STORE_CTX *ctx) -+{ -+ return ctx->cleanup; -+} -+ -+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) -+{ -+ return ctx->tree; -+} -+ -+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) -+{ -+ return ctx->explicit_policy; -+} -+ -+int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx) -+{ -+ return ctx->num_untrusted; -+} -+ -+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) -+{ -+ const X509_VERIFY_PARAM *param; -+ param = X509_VERIFY_PARAM_lookup(name); -+ if (!param) -+ return 0; -+ return X509_VERIFY_PARAM_inherit(ctx->param, param); -+} -+ -+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) -+{ -+ return ctx->param; -+} -+ -+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) -+{ -+ X509_VERIFY_PARAM_free(ctx->param); -+ ctx->param = param; -+} -+ -+void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, SSL_DANE *dane) -+{ -+ ctx->dane = dane; -+} -+ -+static unsigned char *dane_i2d( -+ X509 *cert, -+ uint8_t selector, -+ unsigned int *i2dlen) -+{ -+ unsigned char *buf = NULL; -+ int len; -+ -+ /* -+ * Extract ASN.1 DER form of certificate or public key. -+ */ -+ switch (selector) { -+ case DANETLS_SELECTOR_CERT: -+ len = i2d_X509(cert, &buf); -+ break; -+ case DANETLS_SELECTOR_SPKI: -+ len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &buf); -+ break; -+ default: -+ X509err(X509_F_DANE_I2D, X509_R_BAD_SELECTOR); -+ return NULL; -+ } -+ -+ if (len < 0 || buf == NULL) { -+ X509err(X509_F_DANE_I2D, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ *i2dlen = (unsigned int)len; -+ return buf; -+} -+ -+#define DANETLS_NONE 256 /* impossible uint8_t */ -+ -+static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth) -+{ -+ SSL_DANE *dane = ctx->dane; -+ unsigned usage = DANETLS_NONE; -+ unsigned selector = DANETLS_NONE; -+ unsigned ordinal = DANETLS_NONE; -+ unsigned mtype = DANETLS_NONE; -+ unsigned char *i2dbuf = NULL; -+ unsigned int i2dlen = 0; -+ unsigned char mdbuf[EVP_MAX_MD_SIZE]; -+ unsigned char *cmpbuf = NULL; -+ unsigned int cmplen = 0; -+ int i; -+ int recnum; -+ int matched = 0; -+ danetls_record *t = NULL; -+ uint32_t mask; -+ -+ mask = (depth == 0) ? DANETLS_EE_MASK : DANETLS_TA_MASK; -+ -+ /* -+ * The trust store is not applicable with DANE-TA(2) -+ */ -+ if (depth >= ctx->num_untrusted) -+ mask &= DANETLS_PKIX_MASK; -+ -+ /* -+ * If we've previously matched a PKIX-?? record, no need to test any -+ * further PKIX-?? records, it remains to just build the PKIX chain. -+ * Had the match been a DANE-?? record, we'd be done already. -+ */ -+ if (dane->mdpth >= 0) -+ mask &= ~DANETLS_PKIX_MASK; -+ -+ /*- -+ * https://tools.ietf.org/html/rfc7671#section-5.1 -+ * https://tools.ietf.org/html/rfc7671#section-5.2 -+ * https://tools.ietf.org/html/rfc7671#section-5.3 -+ * https://tools.ietf.org/html/rfc7671#section-5.4 -+ * -+ * We handle DANE-EE(3) records first as they require no chain building -+ * and no expiration or hostname checks. We also process digests with -+ * higher ordinals first and ignore lower priorities except Full(0) which -+ * is always processed (last). If none match, we then process PKIX-EE(1). -+ * -+ * NOTE: This relies on DANE usages sorting before the corresponding PKIX -+ * usages in SSL_dane_tlsa_add(), and also on descending sorting of digest -+ * priorities. See twin comment in ssl/ssl_lib.c. -+ * -+ * We expect that most TLSA RRsets will have just a single usage, so we -+ * don't go out of our way to cache multiple selector-specific i2d buffers -+ * across usages, but if the selector happens to remain the same as switch -+ * usages, that's OK. Thus, a set of "3 1 1", "3 0 1", "1 1 1", "1 0 1", -+ * records would result in us generating each of the certificate and public -+ * key DER forms twice, but more typically we'd just see multiple "3 1 1" -+ * or multiple "3 0 1" records. -+ * -+ * As soon as we find a match at any given depth, we stop, because either -+ * we've matched a DANE-?? record and the peer is authenticated, or, after -+ * exhausting all DANE-?? records, we've matched a PKIX-?? record, which is -+ * sufficient for DANE, and what remains to do is ordinary PKIX validation. -+ */ -+ recnum = (dane->umask & mask) ? sk_danetls_record_num(dane->trecs) : 0; -+ for (i = 0; matched == 0 && i < recnum; ++i) { -+ t = sk_danetls_record_value(dane->trecs, i); -+ if ((DANETLS_USAGE_BIT(t->usage) & mask) == 0) -+ continue; -+ if (t->usage != usage) { -+ usage = t->usage; -+ -+ /* Reset digest agility for each usage/selector pair */ -+ mtype = DANETLS_NONE; -+ ordinal = dane->dctx->mdord[t->mtype]; -+ } -+ if (t->selector != selector) { -+ selector = t->selector; -+ -+ /* Update per-selector state */ -+ OPENSSL_free(i2dbuf); -+ i2dbuf = dane_i2d(cert, selector, &i2dlen); -+ if (i2dbuf == NULL) -+ return -1; -+ -+ /* Reset digest agility for each usage/selector pair */ -+ mtype = DANETLS_NONE; -+ ordinal = dane->dctx->mdord[t->mtype]; -+ } else if (t->mtype != DANETLS_MATCHING_FULL) { -+ /*- -+ * Digest agility: -+ * -+ * -+ * -+ * For a fixed selector, after processing all records with the -+ * highest mtype ordinal, ignore all mtypes with lower ordinals -+ * other than "Full". -+ */ -+ if (dane->dctx->mdord[t->mtype] < ordinal) -+ continue; -+ } -+ -+ /* -+ * Each time we hit a (new selector or) mtype, re-compute the relevant -+ * digest, more complex caching is not worth the code space. -+ */ -+ if (t->mtype != mtype) { -+ const EVP_MD *md = dane->dctx->mdevp[mtype = t->mtype]; -+ cmpbuf = i2dbuf; -+ cmplen = i2dlen; -+ -+ if (md != NULL) { -+ cmpbuf = mdbuf; -+ if (!EVP_Digest(i2dbuf, i2dlen, cmpbuf, &cmplen, md, 0)) { -+ matched = -1; -+ break; -+ } -+ } -+ } -+ -+ /* -+ * Squirrel away the certificate and depth if we have a match. Any -+ * DANE match is dispositive, but with PKIX we still need to build a -+ * full chain. -+ */ -+ if (cmplen == t->dlen && -+ memcmp(cmpbuf, t->data, cmplen) == 0) { -+ if (DANETLS_USAGE_BIT(usage) & DANETLS_DANE_MASK) -+ matched = 1; -+ if (matched || dane->mdpth < 0) { -+ dane->mdpth = depth; -+ dane->mtlsa = t; -+ OPENSSL_free(dane->mcert); -+ dane->mcert = cert; -+ X509_up_ref(cert); -+ } -+ break; -+ } -+ } -+ -+ /* Clear the one-element DER cache */ -+ OPENSSL_free(i2dbuf); -+ return matched; -+} -+ -+static int check_dane_issuer(X509_STORE_CTX *ctx, int depth) -+{ -+ SSL_DANE *dane = ctx->dane; -+ int matched = 0; -+ X509 *cert; -+ -+ if (!DANETLS_HAS_TA(dane) || depth == 0) -+ return X509_TRUST_UNTRUSTED; -+ -+ /* -+ * Record any DANE trust-anchor matches, for the first depth to test, if -+ * there's one at that depth. (This'll be false for length 1 chains looking -+ * for an exact match for the leaf certificate). -+ */ -+ cert = sk_X509_value(ctx->chain, depth); -+ if (cert != NULL && (matched = dane_match(ctx, cert, depth)) < 0) -+ return X509_TRUST_REJECTED; -+ if (matched > 0) { -+ ctx->num_untrusted = depth - 1; -+ return X509_TRUST_TRUSTED; -+ } -+ -+ return X509_TRUST_UNTRUSTED; -+} -+ -+static int check_dane_pkeys(X509_STORE_CTX *ctx) -+{ -+ SSL_DANE *dane = ctx->dane; -+ danetls_record *t; -+ int num = ctx->num_untrusted; -+ X509 *cert = sk_X509_value(ctx->chain, num - 1); -+ int recnum = sk_danetls_record_num(dane->trecs); -+ int i; -+ -+ for (i = 0; i < recnum; ++i) { -+ t = sk_danetls_record_value(dane->trecs, i); -+ if (t->usage != DANETLS_USAGE_DANE_TA || -+ t->selector != DANETLS_SELECTOR_SPKI || -+ t->mtype != DANETLS_MATCHING_FULL || -+ X509_verify(cert, t->spki) <= 0) -+ continue; -+ -+ /* Clear any PKIX-?? matches that failed to extend to a full chain */ -+ X509_free(dane->mcert); -+ dane->mcert = NULL; -+ -+ /* Record match via a bare TA public key */ -+ ctx->bare_ta_signed = 1; -+ dane->mdpth = num - 1; -+ dane->mtlsa = t; -+ -+ /* Prune any excess chain certificates */ -+ num = sk_X509_num(ctx->chain); -+ for (; num > ctx->num_untrusted; --num) -+ X509_free(sk_X509_pop(ctx->chain)); -+ -+ return X509_TRUST_TRUSTED; -+ } -+ -+ return X509_TRUST_UNTRUSTED; -+} -+ -+static void dane_reset(SSL_DANE *dane) -+{ -+ /* -+ * Reset state to verify another chain, or clear after failure. -+ */ -+ X509_free(dane->mcert); -+ dane->mcert = NULL; -+ dane->mtlsa = NULL; -+ dane->mdpth = -1; -+ dane->pdpth = -1; -+} -+ -+static int check_leaf_suiteb(X509_STORE_CTX *ctx, X509 *cert) -+{ -+ int err = X509_chain_check_suiteb(NULL, cert, NULL, ctx->param->flags); -+ -+ if (err == X509_V_OK) -+ return 1; -+ return verify_cb_cert(ctx, cert, 0, err); -+} -+ -+static int dane_verify(X509_STORE_CTX *ctx) -+{ -+ X509 *cert = ctx->cert; -+ SSL_DANE *dane = ctx->dane; -+ int matched; -+ int done; -+ -+ dane_reset(dane); -+ -+ /*- -+ * When testing the leaf certificate, if we match a DANE-EE(3) record, -+ * dane_match() returns 1 and we're done. If however we match a PKIX-EE(1) -+ * record, the match depth and matching TLSA record are recorded, but the -+ * return value is 0, because we still need to find a PKIX trust-anchor. -+ * Therefore, when DANE authentication is enabled (required), we're done -+ * if: -+ * + matched < 0, internal error. -+ * + matched == 1, we matched a DANE-EE(3) record -+ * + matched == 0, mdepth < 0 (no PKIX-EE match) and there are no -+ * DANE-TA(2) or PKIX-TA(0) to test. -+ */ -+ matched = dane_match(ctx, ctx->cert, 0); -+ done = matched != 0 || (!DANETLS_HAS_TA(dane) && dane->mdpth < 0); -+ -+ if (done) -+ X509_get_pubkey_parameters(NULL, ctx->chain); -+ -+ if (matched > 0) { -+ /* Callback invoked as needed */ -+ if (!check_leaf_suiteb(ctx, cert)) -+ return 0; -+ /* Callback invoked as needed */ -+ if ((dane->flags & DANE_FLAG_NO_DANE_EE_NAMECHECKS) == 0 && -+ !check_id(ctx)) -+ return 0; -+ /* Bypass internal_verify(), issue depth 0 success callback */ -+ ctx->error_depth = 0; -+ ctx->current_cert = cert; -+ return ctx->verify_cb(1, ctx); -+ } -+ -+ if (matched < 0) { -+ ctx->error_depth = 0; -+ ctx->current_cert = cert; -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ return -1; -+ } -+ -+ if (done) { -+ /* Fail early, TA-based success is not possible */ -+ if (!check_leaf_suiteb(ctx, cert)) -+ return 0; -+ return verify_cb_cert(ctx, cert, 0, X509_V_ERR_DANE_NO_MATCH); -+ } -+ -+ /* -+ * Chain verification for usages 0/1/2. TLSA record matching of depth > 0 -+ * certificates happens in-line with building the rest of the chain. -+ */ -+ return verify_chain(ctx); -+} -+ -+/* Get issuer, without duplicate suppression */ -+static int get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *cert) -+{ -+ STACK_OF(X509) *saved_chain = ctx->chain; -+ int ok; -+ -+ ctx->chain = NULL; -+ ok = ctx->get_issuer(issuer, ctx, cert); -+ ctx->chain = saved_chain; -+ -+ return ok; -+} -+ -+static int build_chain(X509_STORE_CTX *ctx) -+{ -+ SSL_DANE *dane = ctx->dane; -+ int num = sk_X509_num(ctx->chain); -+ X509 *cert = sk_X509_value(ctx->chain, num - 1); -+ int ss = cert_self_signed(cert); -+ STACK_OF(X509) *sktmp = NULL; -+ unsigned int search; -+ int may_trusted = 0; -+ int may_alternate = 0; -+ int trust = X509_TRUST_UNTRUSTED; -+ int alt_untrusted = 0; -+ int depth; -+ int ok = 0; -+ int i; -+ -+ /* Our chain starts with a single untrusted element. */ -+ OPENSSL_assert(num == 1 && ctx->num_untrusted == num); -+ -+#define S_DOUNTRUSTED (1 << 0) /* Search untrusted chain */ -+#define S_DOTRUSTED (1 << 1) /* Search trusted store */ -+#define S_DOALTERNATE (1 << 2) /* Retry with pruned alternate chain */ -+ /* -+ * Set up search policy, untrusted if possible, trusted-first if enabled. -+ * If we're doing DANE and not doing PKIX-TA/PKIX-EE, we never look in the -+ * trust_store, otherwise we might look there first. If not trusted-first, -+ * and alternate chains are not disabled, try building an alternate chain -+ * if no luck with untrusted first. -+ */ -+ search = (ctx->untrusted != NULL) ? S_DOUNTRUSTED : 0; -+ if (DANETLS_HAS_PKIX(dane) || !DANETLS_HAS_DANE(dane)) { -+ if (search == 0 || ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) -+ search |= S_DOTRUSTED; -+ else if (!(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) -+ may_alternate = 1; -+ may_trusted = 1; -+ } -+ -+ /* -+ * Shallow-copy the stack of untrusted certificates (with TLS, this is -+ * typically the content of the peer's certificate message) so can make -+ * multiple passes over it, while free to remove elements as we go. -+ */ -+ if (ctx->untrusted && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { -+ X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ return 0; -+ } -+ -+ /* -+ * If we got any "DANE-TA(2) Cert(0) Full(0)" trust-anchors from DNS, add -+ * them to our working copy of the untrusted certificate stack. Since the -+ * caller of X509_STORE_CTX_init() may have provided only a leaf cert with -+ * no corresponding stack of untrusted certificates, we may need to create -+ * an empty stack first. [ At present only the ssl library provides DANE -+ * support, and ssl_verify_cert_chain() always provides a non-null stack -+ * containing at least the leaf certificate, but we must be prepared for -+ * this to change. ] -+ */ -+ if (DANETLS_ENABLED(dane) && dane->certs != NULL) { -+ if (sktmp == NULL && (sktmp = sk_X509_new_null()) == NULL) { -+ X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ return 0; -+ } -+ for (i = 0; i < sk_X509_num(dane->certs); ++i) { -+ if (!sk_X509_push(sktmp, sk_X509_value(dane->certs, i))) { -+ sk_X509_free(sktmp); -+ X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ return 0; -+ } -+ } -+ } -+ -+ /* -+ * Still absurdly large, but arithmetically safe, a lower hard upper bound -+ * might be reasonable. -+ */ -+ if (ctx->param->depth > INT_MAX/2) -+ ctx->param->depth = INT_MAX/2; -+ -+ /* -+ * Try to Extend the chain until we reach an ultimately trusted issuer. -+ * Build chains up to one longer the limit, later fail if we hit the limit, -+ * with an X509_V_ERR_CERT_CHAIN_TOO_LONG error code. -+ */ -+ depth = ctx->param->depth + 1; -+ -+ while (search != 0) { -+ X509 *x; -+ X509 *xtmp = NULL; -+ -+ /* -+ * Look in the trust store if enabled for first lookup, or we've run -+ * out of untrusted issuers and search here is not disabled. When we -+ * reach the depth limit, we stop extending the chain, if by that point -+ * we've not found a trust-anchor, any trusted chain would be too long. -+ * -+ * The error reported to the application verify callback is at the -+ * maximal valid depth with the current certificate equal to the last -+ * not ultimately-trusted issuer. For example, with verify_depth = 0, -+ * the callback will report errors at depth=1 when the immediate issuer -+ * of the leaf certificate is not a trust anchor. No attempt will be -+ * made to locate an issuer for that certificate, since such a chain -+ * would be a-priori too long. -+ */ -+ if ((search & S_DOTRUSTED) != 0) { -+ i = num = sk_X509_num(ctx->chain); -+ if ((search & S_DOALTERNATE) != 0) { -+ /* -+ * As high up the chain as we can, look for an alternative -+ * trusted issuer of an untrusted certificate that currently -+ * has an untrusted issuer. We use the alt_untrusted variable -+ * to track how far up the chain we find the first match. It -+ * is only if and when we find a match, that we prune the chain -+ * and reset ctx->num_untrusted to the reduced count of -+ * untrusted certificates. While we're searching for such a -+ * match (which may never be found), it is neither safe nor -+ * wise to preemptively modify either the chain or -+ * ctx->num_untrusted. -+ * -+ * Note, like ctx->num_untrusted, alt_untrusted is a count of -+ * untrusted certificates, not a "depth". -+ */ -+ i = alt_untrusted; -+ } -+ x = sk_X509_value(ctx->chain, i-1); -+ -+ ok = (depth < num) ? 0 : get_issuer(&xtmp, ctx, x); -+ -+ if (ok < 0) { -+ trust = X509_TRUST_REJECTED; -+ ctx->error = X509_V_ERR_STORE_LOOKUP; -+ search = 0; -+ continue; -+ } -+ -+ if (ok > 0) { -+ /* -+ * Alternative trusted issuer for a mid-chain untrusted cert? -+ * Pop the untrusted cert's successors and retry. We might now -+ * be able to complete a valid chain via the trust store. Note -+ * that despite the current trust-store match we might still -+ * fail complete the chain to a suitable trust-anchor, in which -+ * case we may prune some more untrusted certificates and try -+ * again. Thus the S_DOALTERNATE bit may yet be turned on -+ * again with an even shorter untrusted chain! -+ * -+ * If in the process we threw away our matching PKIX-TA trust -+ * anchor, reset DANE trust. We might find a suitable trusted -+ * certificate among the ones from the trust store. -+ */ -+ if ((search & S_DOALTERNATE) != 0) { -+ OPENSSL_assert(num > i && i > 0 && ss == 0); -+ search &= ~S_DOALTERNATE; -+ for (; num > i; --num) -+ X509_free(sk_X509_pop(ctx->chain)); -+ ctx->num_untrusted = num; -+ -+ if (DANETLS_ENABLED(dane) && -+ dane->mdpth >= ctx->num_untrusted) { -+ dane->mdpth = -1; -+ X509_free(dane->mcert); -+ dane->mcert = NULL; -+ } -+ if (DANETLS_ENABLED(dane) && -+ dane->pdpth >= ctx->num_untrusted) -+ dane->pdpth = -1; -+ } -+ -+ /* -+ * Self-signed untrusted certificates get replaced by their -+ * trusted matching issuer. Otherwise, grow the chain. -+ */ -+ if (ss == 0) { -+ if (!sk_X509_push(ctx->chain, x = xtmp)) { -+ X509_free(xtmp); -+ X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); -+ trust = X509_TRUST_REJECTED; -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ search = 0; -+ continue; -+ } -+ ss = cert_self_signed(x); -+ } else if (num == ctx->num_untrusted) { -+ /* -+ * We have a self-signed certificate that has the same -+ * subject name (and perhaps keyid and/or serial number) as -+ * a trust-anchor. We must have an exact match to avoid -+ * possible impersonation via key substitution etc. -+ */ -+ if (X509_cmp(x, xtmp) != 0) { -+ /* Self-signed untrusted mimic. */ -+ X509_free(xtmp); -+ ok = 0; -+ } else { -+ X509_free(x); -+ ctx->num_untrusted = --num; -+ (void) sk_X509_set(ctx->chain, num, x = xtmp); -+ } -+ } -+ -+ /* -+ * We've added a new trusted certificate to the chain, recheck -+ * trust. If not done, and not self-signed look deeper. -+ * Whether or not we're doing "trusted first", we no longer -+ * look for untrusted certificates from the peer's chain. -+ * -+ * At this point ctx->num_trusted and num must reflect the -+ * correct number of untrusted certificates, since the DANE -+ * logic in check_trust() depends on distinguishing CAs from -+ * "the wire" from CAs from the trust store. In particular, the -+ * certificate at depth "num" should be the new trusted -+ * certificate with ctx->num_untrusted <= num. -+ */ -+ if (ok) { -+ OPENSSL_assert(ctx->num_untrusted <= num); -+ search &= ~S_DOUNTRUSTED; -+ switch (trust = check_trust(ctx, num)) { -+ case X509_TRUST_TRUSTED: -+ case X509_TRUST_REJECTED: -+ search = 0; -+ continue; -+ } -+ if (ss == 0) -+ continue; -+ } -+ } -+ -+ /* -+ * No dispositive decision, and either self-signed or no match, if -+ * we were doing untrusted-first, and alt-chains are not disabled, -+ * do that, by repeatedly losing one untrusted element at a time, -+ * and trying to extend the shorted chain. -+ */ -+ if ((search & S_DOUNTRUSTED) == 0) { -+ /* Continue search for a trusted issuer of a shorter chain? */ -+ if ((search & S_DOALTERNATE) != 0 && --alt_untrusted > 0) -+ continue; -+ /* Still no luck and no fallbacks left? */ -+ if (!may_alternate || (search & S_DOALTERNATE) != 0 || -+ ctx->num_untrusted < 2) -+ break; -+ /* Search for a trusted issuer of a shorter chain */ -+ search |= S_DOALTERNATE; -+ alt_untrusted = ctx->num_untrusted - 1; -+ ss = 0; -+ } -+ } -+ -+ /* -+ * Extend chain with peer-provided certificates -+ */ -+ if ((search & S_DOUNTRUSTED) != 0) { -+ num = sk_X509_num(ctx->chain); -+ OPENSSL_assert(num == ctx->num_untrusted); -+ x = sk_X509_value(ctx->chain, num-1); -+ -+ /* -+ * Once we run out of untrusted issuers, we stop looking for more -+ * and start looking only in the trust store if enabled. -+ */ -+ xtmp = (ss || depth < num) ? NULL : find_issuer(ctx, sktmp, x); -+ if (xtmp == NULL) { -+ search &= ~S_DOUNTRUSTED; -+ if (may_trusted) -+ search |= S_DOTRUSTED; -+ continue; -+ } -+ -+ /* Drop this issuer from future consideration */ -+ (void) sk_X509_delete_ptr(sktmp, xtmp); -+ -+ if (!sk_X509_push(ctx->chain, xtmp)) { -+ X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); -+ trust = X509_TRUST_REJECTED; -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ search = 0; -+ continue; -+ } -+ -+ X509_up_ref(x = xtmp); -+ ++ctx->num_untrusted; -+ ss = cert_self_signed(xtmp); -+ -+ /* -+ * Check for DANE-TA trust of the topmost untrusted certificate. -+ */ -+ switch (trust = check_dane_issuer(ctx, ctx->num_untrusted - 1)) { -+ case X509_TRUST_TRUSTED: -+ case X509_TRUST_REJECTED: -+ search = 0; -+ continue; -+ } -+ } -+ } -+ sk_X509_free(sktmp); -+ -+ /* -+ * Last chance to make a trusted chain, either bare DANE-TA public-key -+ * signers, or else direct leaf PKIX trust. -+ */ -+ num = sk_X509_num(ctx->chain); -+ if (num <= depth) { -+ if (trust == X509_TRUST_UNTRUSTED && DANETLS_HAS_DANE_TA(dane)) -+ trust = check_dane_pkeys(ctx); -+ if (trust == X509_TRUST_UNTRUSTED && num == ctx->num_untrusted) -+ trust = check_trust(ctx, num); -+ } -+ -+ switch (trust) { -+ case X509_TRUST_TRUSTED: -+ return 1; -+ case X509_TRUST_REJECTED: -+ /* Callback already issued */ -+ return 0; -+ case X509_TRUST_UNTRUSTED: -+ default: -+ num = sk_X509_num(ctx->chain); -+ if (num > depth) -+ return verify_cb_cert(ctx, NULL, num-1, -+ X509_V_ERR_CERT_CHAIN_TOO_LONG); -+ if (DANETLS_ENABLED(dane) && -+ (!DANETLS_HAS_PKIX(dane) || dane->pdpth >= 0)) -+ return verify_cb_cert(ctx, NULL, num-1, X509_V_ERR_DANE_NO_MATCH); -+ if (ss && sk_X509_num(ctx->chain) == 1) -+ return verify_cb_cert(ctx, NULL, num-1, -+ X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT); -+ if (ss) -+ return verify_cb_cert(ctx, NULL, num-1, -+ X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN); -+ if (ctx->num_untrusted < num) -+ return verify_cb_cert(ctx, NULL, num-1, -+ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT); -+ return verify_cb_cert(ctx, NULL, num-1, -+ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY); -+ } -+} -+ -+static const int minbits_table[] = { 80, 112, 128, 192, 256 }; -+static const int NUM_AUTH_LEVELS = OSSL_NELEM(minbits_table); -+ -+/* -+ * Check whether the public key of ``cert`` meets the security level of -+ * ``ctx``. -+ * -+ * Returns 1 on success, 0 otherwise. -+ */ -+static int check_key_level(X509_STORE_CTX *ctx, X509 *cert) -+{ -+ EVP_PKEY *pkey = X509_get0_pubkey(cert); -+ int level = ctx->param->auth_level; -+ -+ /* Unsupported or malformed keys are not secure */ -+ if (pkey == NULL) -+ return 0; -+ -+ if (level <= 0) -+ return 1; -+ if (level > NUM_AUTH_LEVELS) -+ level = NUM_AUTH_LEVELS; -+ -+ return EVP_PKEY_security_bits(pkey) >= minbits_table[level - 1]; -+} -+ -+/* -+ * Check whether the signature digest algorithm of ``cert`` meets the security -+ * level of ``ctx``. Should not be checked for trust anchors (whether -+ * self-signed or otherwise). -+ * -+ * Returns 1 on success, 0 otherwise. -+ */ -+static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert) -+{ -+ int nid = X509_get_signature_nid(cert); -+ int mdnid = NID_undef; -+ int secbits = -1; -+ int level = ctx->param->auth_level; -+ -+ if (level <= 0) -+ return 1; -+ if (level > NUM_AUTH_LEVELS) -+ level = NUM_AUTH_LEVELS; -+ -+ /* Lookup signature algorithm digest */ -+ if (nid && OBJ_find_sigid_algs(nid, &mdnid, NULL)) { -+ const EVP_MD *md; -+ -+ /* Assume 4 bits of collision resistance for each hash octet */ -+ if (mdnid != NID_undef && (md = EVP_get_digestbynid(mdnid)) != NULL) -+ secbits = EVP_MD_size(md) * 4; -+ } -+ -+ return secbits >= minbits_table[level - 1]; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vpm.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vpm.c -new file mode 100644 -index 0000000..b506722 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509_vpm.c -@@ -0,0 +1,617 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+ -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+ -+#include "x509_lcl.h" -+ -+/* X509_VERIFY_PARAM functions */ -+ -+#define SET_HOST 0 -+#define ADD_HOST 1 -+ -+static char *str_copy(const char *s) -+{ -+ return OPENSSL_strdup(s); -+} -+ -+static void str_free(char *s) -+{ -+ OPENSSL_free(s); -+} -+ -+static int int_x509_param_set_hosts(X509_VERIFY_PARAM *vpm, int mode, -+ const char *name, size_t namelen) -+{ -+ char *copy; -+ -+ /* -+ * Refuse names with embedded NUL bytes, except perhaps as final byte. -+ * XXX: Do we need to push an error onto the error stack? -+ */ -+ if (namelen == 0 || name == NULL) -+ namelen = name ? strlen(name) : 0; -+ else if (name && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen)) -+ return 0; -+ if (namelen > 0 && name[namelen - 1] == '\0') -+ --namelen; -+ -+ if (mode == SET_HOST) { -+ sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free); -+ vpm->hosts = NULL; -+ } -+ if (name == NULL || namelen == 0) -+ return 1; -+ -+ copy = OPENSSL_strndup(name, namelen); -+ if (copy == NULL) -+ return 0; -+ -+ if (vpm->hosts == NULL && -+ (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { -+ OPENSSL_free(copy); -+ return 0; -+ } -+ -+ if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) { -+ OPENSSL_free(copy); -+ if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) { -+ sk_OPENSSL_STRING_free(vpm->hosts); -+ vpm->hosts = NULL; -+ } -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static void x509_verify_param_zero(X509_VERIFY_PARAM *param) -+{ -+ if (!param) -+ return; -+ param->name = NULL; -+ param->purpose = 0; -+ param->trust = X509_TRUST_DEFAULT; -+ /* -+ * param->inh_flags = X509_VP_FLAG_DEFAULT; -+ */ -+ param->inh_flags = 0; -+ param->flags = 0; -+ param->depth = -1; -+ param->auth_level = -1; /* -1 means unset, 0 is explicit */ -+ sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); -+ param->policies = NULL; -+ sk_OPENSSL_STRING_pop_free(param->hosts, str_free); -+ param->hosts = NULL; -+ OPENSSL_free(param->peername); -+ param->peername = NULL; -+ OPENSSL_free(param->email); -+ param->email = NULL; -+ param->emaillen = 0; -+ OPENSSL_free(param->ip); -+ param->ip = NULL; -+ param->iplen = 0; -+} -+ -+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) -+{ -+ X509_VERIFY_PARAM *param; -+ -+ param = OPENSSL_zalloc(sizeof(*param)); -+ if (param == NULL) -+ return NULL; -+ x509_verify_param_zero(param); -+ return param; -+} -+ -+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) -+{ -+ if (!param) -+ return; -+ x509_verify_param_zero(param); -+ OPENSSL_free(param); -+} -+ -+/*- -+ * This function determines how parameters are "inherited" from one structure -+ * to another. There are several different ways this can happen. -+ * -+ * 1. If a child structure needs to have its values initialized from a parent -+ * they are simply copied across. For example SSL_CTX copied to SSL. -+ * 2. If the structure should take on values only if they are currently unset. -+ * For example the values in an SSL structure will take appropriate value -+ * for SSL servers or clients but only if the application has not set new -+ * ones. -+ * -+ * The "inh_flags" field determines how this function behaves. -+ * -+ * Normally any values which are set in the default are not copied from the -+ * destination and verify flags are ORed together. -+ * -+ * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied -+ * to the destination. Effectively the values in "to" become default values -+ * which will be used only if nothing new is set in "from". -+ * -+ * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether -+ * they are set or not. Flags is still Ored though. -+ * -+ * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead -+ * of ORed. -+ * -+ * If X509_VP_FLAG_LOCKED is set then no values are copied. -+ * -+ * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed -+ * after the next call. -+ */ -+ -+/* Macro to test if a field should be copied from src to dest */ -+ -+#define test_x509_verify_param_copy(field, def) \ -+ (to_overwrite || \ -+ ((src->field != def) && (to_default || (dest->field == def)))) -+ -+/* Macro to test and copy a field if necessary */ -+ -+#define x509_verify_param_copy(field, def) \ -+ if (test_x509_verify_param_copy(field, def)) \ -+ dest->field = src->field -+ -+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, -+ const X509_VERIFY_PARAM *src) -+{ -+ unsigned long inh_flags; -+ int to_default, to_overwrite; -+ if (!src) -+ return 1; -+ inh_flags = dest->inh_flags | src->inh_flags; -+ -+ if (inh_flags & X509_VP_FLAG_ONCE) -+ dest->inh_flags = 0; -+ -+ if (inh_flags & X509_VP_FLAG_LOCKED) -+ return 1; -+ -+ if (inh_flags & X509_VP_FLAG_DEFAULT) -+ to_default = 1; -+ else -+ to_default = 0; -+ -+ if (inh_flags & X509_VP_FLAG_OVERWRITE) -+ to_overwrite = 1; -+ else -+ to_overwrite = 0; -+ -+ x509_verify_param_copy(purpose, 0); -+ x509_verify_param_copy(trust, X509_TRUST_DEFAULT); -+ x509_verify_param_copy(depth, -1); -+ x509_verify_param_copy(auth_level, -1); -+ -+ /* If overwrite or check time not set, copy across */ -+ -+ if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { -+ dest->check_time = src->check_time; -+ dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; -+ /* Don't need to copy flag: that is done below */ -+ } -+ -+ if (inh_flags & X509_VP_FLAG_RESET_FLAGS) -+ dest->flags = 0; -+ -+ dest->flags |= src->flags; -+ -+ if (test_x509_verify_param_copy(policies, NULL)) { -+ if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) -+ return 0; -+ } -+ -+ /* Copy the host flags if and only if we're copying the host list */ -+ if (test_x509_verify_param_copy(hosts, NULL)) { -+ sk_OPENSSL_STRING_pop_free(dest->hosts, str_free); -+ dest->hosts = NULL; -+ if (src->hosts) { -+ dest->hosts = -+ sk_OPENSSL_STRING_deep_copy(src->hosts, str_copy, str_free); -+ if (dest->hosts == NULL) -+ return 0; -+ dest->hostflags = src->hostflags; -+ } -+ } -+ -+ if (test_x509_verify_param_copy(email, NULL)) { -+ if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen)) -+ return 0; -+ } -+ -+ if (test_x509_verify_param_copy(ip, NULL)) { -+ if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen)) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, -+ const X509_VERIFY_PARAM *from) -+{ -+ unsigned long save_flags = to->inh_flags; -+ int ret; -+ to->inh_flags |= X509_VP_FLAG_DEFAULT; -+ ret = X509_VERIFY_PARAM_inherit(to, from); -+ to->inh_flags = save_flags; -+ return ret; -+} -+ -+static int int_x509_param_set1(char **pdest, size_t *pdestlen, -+ const char *src, size_t srclen) -+{ -+ void *tmp; -+ if (src) { -+ if (srclen == 0) -+ srclen = strlen(src); -+ -+ tmp = OPENSSL_memdup(src, srclen); -+ if (tmp == NULL) -+ return 0; -+ } else { -+ tmp = NULL; -+ srclen = 0; -+ } -+ OPENSSL_free(*pdest); -+ *pdest = tmp; -+ if (pdestlen != NULL) -+ *pdestlen = srclen; -+ return 1; -+} -+ -+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) -+{ -+ OPENSSL_free(param->name); -+ param->name = OPENSSL_strdup(name); -+ if (param->name) -+ return 1; -+ return 0; -+} -+ -+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) -+{ -+ param->flags |= flags; -+ if (flags & X509_V_FLAG_POLICY_MASK) -+ param->flags |= X509_V_FLAG_POLICY_CHECK; -+ return 1; -+} -+ -+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, -+ unsigned long flags) -+{ -+ param->flags &= ~flags; -+ return 1; -+} -+ -+unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) -+{ -+ return param->flags; -+} -+ -+uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param) -+{ -+ return param->inh_flags; -+} -+ -+int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param, uint32_t flags) -+{ -+ param->inh_flags = flags; -+ return 1; -+} -+ -+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) -+{ -+ return X509_PURPOSE_set(¶m->purpose, purpose); -+} -+ -+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) -+{ -+ return X509_TRUST_set(¶m->trust, trust); -+} -+ -+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) -+{ -+ param->depth = depth; -+} -+ -+void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level) -+{ -+ param->auth_level = auth_level; -+} -+ -+time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param) -+{ -+ return param->check_time; -+} -+ -+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) -+{ -+ param->check_time = t; -+ param->flags |= X509_V_FLAG_USE_CHECK_TIME; -+} -+ -+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, -+ ASN1_OBJECT *policy) -+{ -+ if (!param->policies) { -+ param->policies = sk_ASN1_OBJECT_new_null(); -+ if (!param->policies) -+ return 0; -+ } -+ if (!sk_ASN1_OBJECT_push(param->policies, policy)) -+ return 0; -+ return 1; -+} -+ -+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, -+ STACK_OF(ASN1_OBJECT) *policies) -+{ -+ int i; -+ ASN1_OBJECT *oid, *doid; -+ -+ if (!param) -+ return 0; -+ sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); -+ -+ if (!policies) { -+ param->policies = NULL; -+ return 1; -+ } -+ -+ param->policies = sk_ASN1_OBJECT_new_null(); -+ if (!param->policies) -+ return 0; -+ -+ for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { -+ oid = sk_ASN1_OBJECT_value(policies, i); -+ doid = OBJ_dup(oid); -+ if (!doid) -+ return 0; -+ if (!sk_ASN1_OBJECT_push(param->policies, doid)) { -+ ASN1_OBJECT_free(doid); -+ return 0; -+ } -+ } -+ param->flags |= X509_V_FLAG_POLICY_CHECK; -+ return 1; -+} -+ -+int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, -+ const char *name, size_t namelen) -+{ -+ return int_x509_param_set_hosts(param, SET_HOST, name, namelen); -+} -+ -+int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, -+ const char *name, size_t namelen) -+{ -+ return int_x509_param_set_hosts(param, ADD_HOST, name, namelen); -+} -+ -+void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, -+ unsigned int flags) -+{ -+ param->hostflags = flags; -+} -+ -+char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) -+{ -+ return param->peername; -+} -+ -+/* -+ * Move peername from one param structure to another, freeing any name present -+ * at the target. If the source is a NULL parameter structure, free and zero -+ * the target peername. -+ */ -+void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *to, -+ X509_VERIFY_PARAM *from) -+{ -+ char *peername = (from != NULL) ? from->peername : NULL; -+ -+ if (to->peername != peername) { -+ OPENSSL_free(to->peername); -+ to->peername = peername; -+ } -+ if (from) -+ from->peername = NULL; -+} -+ -+int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, -+ const char *email, size_t emaillen) -+{ -+ return int_x509_param_set1(¶m->email, ¶m->emaillen, -+ email, emaillen); -+} -+ -+int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, -+ const unsigned char *ip, size_t iplen) -+{ -+ if (iplen != 0 && iplen != 4 && iplen != 16) -+ return 0; -+ return int_x509_param_set1((char **)¶m->ip, ¶m->iplen, -+ (char *)ip, iplen); -+} -+ -+int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) -+{ -+ unsigned char ipout[16]; -+ size_t iplen; -+ -+ iplen = (size_t)a2i_ipadd(ipout, ipasc); -+ if (iplen == 0) -+ return 0; -+ return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); -+} -+ -+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) -+{ -+ return param->depth; -+} -+ -+int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param) -+{ -+ return param->auth_level; -+} -+ -+const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) -+{ -+ return param->name; -+} -+ -+#define vpm_empty_id NULL, 0U, NULL, NULL, 0, NULL, 0 -+ -+/* -+ * Default verify parameters: these are used for various applications and can -+ * be overridden by the user specified table. NB: the 'name' field *must* be -+ * in alphabetical order because it will be searched using OBJ_search. -+ */ -+ -+static const X509_VERIFY_PARAM default_table[] = { -+ { -+ "default", /* X509 default parameters */ -+ 0, /* Check time */ -+ 0, /* internal flags */ -+ X509_V_FLAG_TRUSTED_FIRST, /* flags */ -+ 0, /* purpose */ -+ 0, /* trust */ -+ 100, /* depth */ -+ -1, /* auth_level */ -+ NULL, /* policies */ -+ vpm_empty_id}, -+ { -+ "pkcs7", /* S/MIME sign parameters */ -+ 0, /* Check time */ -+ 0, /* internal flags */ -+ 0, /* flags */ -+ X509_PURPOSE_SMIME_SIGN, /* purpose */ -+ X509_TRUST_EMAIL, /* trust */ -+ -1, /* depth */ -+ -1, /* auth_level */ -+ NULL, /* policies */ -+ vpm_empty_id}, -+ { -+ "smime_sign", /* S/MIME sign parameters */ -+ 0, /* Check time */ -+ 0, /* internal flags */ -+ 0, /* flags */ -+ X509_PURPOSE_SMIME_SIGN, /* purpose */ -+ X509_TRUST_EMAIL, /* trust */ -+ -1, /* depth */ -+ -1, /* auth_level */ -+ NULL, /* policies */ -+ vpm_empty_id}, -+ { -+ "ssl_client", /* SSL/TLS client parameters */ -+ 0, /* Check time */ -+ 0, /* internal flags */ -+ 0, /* flags */ -+ X509_PURPOSE_SSL_CLIENT, /* purpose */ -+ X509_TRUST_SSL_CLIENT, /* trust */ -+ -1, /* depth */ -+ -1, /* auth_level */ -+ NULL, /* policies */ -+ vpm_empty_id}, -+ { -+ "ssl_server", /* SSL/TLS server parameters */ -+ 0, /* Check time */ -+ 0, /* internal flags */ -+ 0, /* flags */ -+ X509_PURPOSE_SSL_SERVER, /* purpose */ -+ X509_TRUST_SSL_SERVER, /* trust */ -+ -1, /* depth */ -+ -1, /* auth_level */ -+ NULL, /* policies */ -+ vpm_empty_id} -+}; -+ -+static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; -+ -+static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b) -+{ -+ return strcmp(a->name, b->name); -+} -+ -+DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); -+IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); -+ -+static int param_cmp(const X509_VERIFY_PARAM *const *a, -+ const X509_VERIFY_PARAM *const *b) -+{ -+ return strcmp((*a)->name, (*b)->name); -+} -+ -+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) -+{ -+ int idx; -+ X509_VERIFY_PARAM *ptmp; -+ if (param_table == NULL) { -+ param_table = sk_X509_VERIFY_PARAM_new(param_cmp); -+ if (param_table == NULL) -+ return 0; -+ } else { -+ idx = sk_X509_VERIFY_PARAM_find(param_table, param); -+ if (idx != -1) { -+ ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); -+ X509_VERIFY_PARAM_free(ptmp); -+ (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); -+ } -+ } -+ if (!sk_X509_VERIFY_PARAM_push(param_table, param)) -+ return 0; -+ return 1; -+} -+ -+int X509_VERIFY_PARAM_get_count(void) -+{ -+ int num = OSSL_NELEM(default_table); -+ if (param_table) -+ num += sk_X509_VERIFY_PARAM_num(param_table); -+ return num; -+} -+ -+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id) -+{ -+ int num = OSSL_NELEM(default_table); -+ if (id < num) -+ return default_table + id; -+ return sk_X509_VERIFY_PARAM_value(param_table, id - num); -+} -+ -+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) -+{ -+ int idx; -+ X509_VERIFY_PARAM pm; -+ -+ pm.name = (char *)name; -+ if (param_table) { -+ idx = sk_X509_VERIFY_PARAM_find(param_table, &pm); -+ if (idx != -1) -+ return sk_X509_VERIFY_PARAM_value(param_table, idx); -+ } -+ return OBJ_bsearch_table(&pm, default_table, OSSL_NELEM(default_table)); -+} -+ -+void X509_VERIFY_PARAM_table_cleanup(void) -+{ -+ sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free); -+ param_table = NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509cset.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509cset.c -new file mode 100644 -index 0000000..2057859 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509cset.c -@@ -0,0 +1,182 @@ -+/* -+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+ -+int X509_CRL_set_version(X509_CRL *x, long version) -+{ -+ if (x == NULL) -+ return (0); -+ if (x->crl.version == NULL) { -+ if ((x->crl.version = ASN1_INTEGER_new()) == NULL) -+ return (0); -+ } -+ return (ASN1_INTEGER_set(x->crl.version, version)); -+} -+ -+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) -+{ -+ if (x == NULL) -+ return (0); -+ return (X509_NAME_set(&x->crl.issuer, name)); -+} -+ -+int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) -+{ -+ if (x == NULL) -+ return 0; -+ return x509_set1_time(&x->crl.lastUpdate, tm); -+} -+ -+int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) -+{ -+ if (x == NULL) -+ return 0; -+ return x509_set1_time(&x->crl.nextUpdate, tm); -+} -+ -+int X509_CRL_sort(X509_CRL *c) -+{ -+ int i; -+ X509_REVOKED *r; -+ /* -+ * sort the data so it will be written in serial number order -+ */ -+ sk_X509_REVOKED_sort(c->crl.revoked); -+ for (i = 0; i < sk_X509_REVOKED_num(c->crl.revoked); i++) { -+ r = sk_X509_REVOKED_value(c->crl.revoked, i); -+ r->sequence = i; -+ } -+ c->crl.enc.modified = 1; -+ return 1; -+} -+ -+int X509_CRL_up_ref(X509_CRL *crl) -+{ -+ int i; -+ -+ if (CRYPTO_atomic_add(&crl->references, 1, &i, crl->lock) <= 0) -+ return 0; -+ -+ REF_PRINT_COUNT("X509_CRL", crl); -+ REF_ASSERT_ISNT(i < 2); -+ return ((i > 1) ? 1 : 0); -+} -+ -+long X509_CRL_get_version(const X509_CRL *crl) -+{ -+ return ASN1_INTEGER_get(crl->crl.version); -+} -+ -+const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl) -+{ -+ return crl->crl.lastUpdate; -+} -+ -+const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl) -+{ -+ return crl->crl.nextUpdate; -+} -+ -+#if OPENSSL_API_COMPAT < 0x10100000L -+ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl) -+{ -+ return crl->crl.lastUpdate; -+} -+ -+ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl) -+{ -+ return crl->crl.nextUpdate; -+} -+#endif -+ -+X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl) -+{ -+ return crl->crl.issuer; -+} -+ -+const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl) -+{ -+ return crl->crl.extensions; -+} -+ -+STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl) -+{ -+ return crl->crl.revoked; -+} -+ -+void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, -+ const X509_ALGOR **palg) -+{ -+ if (psig != NULL) -+ *psig = &crl->signature; -+ if (palg != NULL) -+ *palg = &crl->sig_alg; -+} -+ -+int X509_CRL_get_signature_nid(const X509_CRL *crl) -+{ -+ return OBJ_obj2nid(crl->sig_alg.algorithm); -+} -+ -+const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x) -+{ -+ return x->revocationDate; -+} -+ -+int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) -+{ -+ ASN1_TIME *in; -+ -+ if (x == NULL) -+ return (0); -+ in = x->revocationDate; -+ if (in != tm) { -+ in = ASN1_STRING_dup(tm); -+ if (in != NULL) { -+ ASN1_TIME_free(x->revocationDate); -+ x->revocationDate = in; -+ } -+ } -+ return (in != NULL); -+} -+ -+const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x) -+{ -+ return &x->serialNumber; -+} -+ -+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) -+{ -+ ASN1_INTEGER *in; -+ -+ if (x == NULL) -+ return (0); -+ in = &x->serialNumber; -+ if (in != serial) -+ return ASN1_STRING_copy(in, serial); -+ return 1; -+} -+ -+const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions(const X509_REVOKED *r) -+{ -+ return r->extensions; -+} -+ -+int i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **pp) -+{ -+ crl->crl.enc.modified = 1; -+ return i2d_X509_CRL_INFO(&crl->crl, pp); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509name.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509name.c -new file mode 100644 -index 0000000..919d8c1 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509name.c -@@ -0,0 +1,358 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+ -+int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) -+{ -+ ASN1_OBJECT *obj; -+ -+ obj = OBJ_nid2obj(nid); -+ if (obj == NULL) -+ return (-1); -+ return (X509_NAME_get_text_by_OBJ(name, obj, buf, len)); -+} -+ -+int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf, -+ int len) -+{ -+ int i; -+ const ASN1_STRING *data; -+ -+ i = X509_NAME_get_index_by_OBJ(name, obj, -1); -+ if (i < 0) -+ return (-1); -+ data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); -+ i = (data->length > (len - 1)) ? (len - 1) : data->length; -+ if (buf == NULL) -+ return (data->length); -+ memcpy(buf, data->data, i); -+ buf[i] = '\0'; -+ return (i); -+} -+ -+int X509_NAME_entry_count(const X509_NAME *name) -+{ -+ if (name == NULL) -+ return (0); -+ return (sk_X509_NAME_ENTRY_num(name->entries)); -+} -+ -+int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos) -+{ -+ ASN1_OBJECT *obj; -+ -+ obj = OBJ_nid2obj(nid); -+ if (obj == NULL) -+ return (-2); -+ return (X509_NAME_get_index_by_OBJ(name, obj, lastpos)); -+} -+ -+/* NOTE: you should be passing -1, not 0 as lastpos */ -+int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int lastpos) -+{ -+ int n; -+ X509_NAME_ENTRY *ne; -+ STACK_OF(X509_NAME_ENTRY) *sk; -+ -+ if (name == NULL) -+ return (-1); -+ if (lastpos < 0) -+ lastpos = -1; -+ sk = name->entries; -+ n = sk_X509_NAME_ENTRY_num(sk); -+ for (lastpos++; lastpos < n; lastpos++) { -+ ne = sk_X509_NAME_ENTRY_value(sk, lastpos); -+ if (OBJ_cmp(ne->object, obj) == 0) -+ return (lastpos); -+ } -+ return (-1); -+} -+ -+X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc) -+{ -+ if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc -+ || loc < 0) -+ return (NULL); -+ else -+ return (sk_X509_NAME_ENTRY_value(name->entries, loc)); -+} -+ -+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) -+{ -+ X509_NAME_ENTRY *ret; -+ int i, n, set_prev, set_next; -+ STACK_OF(X509_NAME_ENTRY) *sk; -+ -+ if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc -+ || loc < 0) -+ return (NULL); -+ sk = name->entries; -+ ret = sk_X509_NAME_ENTRY_delete(sk, loc); -+ n = sk_X509_NAME_ENTRY_num(sk); -+ name->modified = 1; -+ if (loc == n) -+ return (ret); -+ -+ /* else we need to fixup the set field */ -+ if (loc != 0) -+ set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; -+ else -+ set_prev = ret->set - 1; -+ set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; -+ -+ /*- -+ * set_prev is the previous set -+ * set is the current set -+ * set_next is the following -+ * prev 1 1 1 1 1 1 1 1 -+ * set 1 1 2 2 -+ * next 1 1 2 2 2 2 3 2 -+ * so basically only if prev and next differ by 2, then -+ * re-number down by 1 -+ */ -+ if (set_prev + 1 < set_next) -+ for (i = loc; i < n; i++) -+ sk_X509_NAME_ENTRY_value(sk, i)->set--; -+ return (ret); -+} -+ -+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, -+ const unsigned char *bytes, int len, int loc, -+ int set) -+{ -+ X509_NAME_ENTRY *ne; -+ int ret; -+ ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); -+ if (!ne) -+ return 0; -+ ret = X509_NAME_add_entry(name, ne, loc, set); -+ X509_NAME_ENTRY_free(ne); -+ return ret; -+} -+ -+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, -+ const unsigned char *bytes, int len, int loc, -+ int set) -+{ -+ X509_NAME_ENTRY *ne; -+ int ret; -+ ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); -+ if (!ne) -+ return 0; -+ ret = X509_NAME_add_entry(name, ne, loc, set); -+ X509_NAME_ENTRY_free(ne); -+ return ret; -+} -+ -+int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, -+ const unsigned char *bytes, int len, int loc, -+ int set) -+{ -+ X509_NAME_ENTRY *ne; -+ int ret; -+ ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); -+ if (!ne) -+ return 0; -+ ret = X509_NAME_add_entry(name, ne, loc, set); -+ X509_NAME_ENTRY_free(ne); -+ return ret; -+} -+ -+/* -+ * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the -+ * guy we are about to stomp on. -+ */ -+int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc, -+ int set) -+{ -+ X509_NAME_ENTRY *new_name = NULL; -+ int n, i, inc; -+ STACK_OF(X509_NAME_ENTRY) *sk; -+ -+ if (name == NULL) -+ return (0); -+ sk = name->entries; -+ n = sk_X509_NAME_ENTRY_num(sk); -+ if (loc > n) -+ loc = n; -+ else if (loc < 0) -+ loc = n; -+ -+ name->modified = 1; -+ -+ if (set == -1) { -+ if (loc == 0) { -+ set = 0; -+ inc = 1; -+ } else { -+ set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; -+ inc = 0; -+ } -+ } else { /* if (set >= 0) */ -+ -+ if (loc >= n) { -+ if (loc != 0) -+ set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; -+ else -+ set = 0; -+ } else -+ set = sk_X509_NAME_ENTRY_value(sk, loc)->set; -+ inc = (set == 0) ? 1 : 0; -+ } -+ -+ /* -+ * X509_NAME_ENTRY_dup is ASN1 generated code, that can't be easily -+ * const'ified; harmless cast as dup() don't modify its input. -+ */ -+ if ((new_name = X509_NAME_ENTRY_dup((X509_NAME_ENTRY *)ne)) == NULL) -+ goto err; -+ new_name->set = set; -+ if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { -+ X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ if (inc) { -+ n = sk_X509_NAME_ENTRY_num(sk); -+ for (i = loc + 1; i < n; i++) -+ sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1; -+ } -+ return (1); -+ err: -+ X509_NAME_ENTRY_free(new_name); -+ return (0); -+} -+ -+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, -+ const char *field, int type, -+ const unsigned char *bytes, -+ int len) -+{ -+ ASN1_OBJECT *obj; -+ X509_NAME_ENTRY *nentry; -+ -+ obj = OBJ_txt2obj(field, 0); -+ if (obj == NULL) { -+ X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, -+ X509_R_INVALID_FIELD_NAME); -+ ERR_add_error_data(2, "name=", field); -+ return (NULL); -+ } -+ nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); -+ ASN1_OBJECT_free(obj); -+ return nentry; -+} -+ -+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, -+ int type, -+ const unsigned char *bytes, -+ int len) -+{ -+ ASN1_OBJECT *obj; -+ X509_NAME_ENTRY *nentry; -+ -+ obj = OBJ_nid2obj(nid); -+ if (obj == NULL) { -+ X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, X509_R_UNKNOWN_NID); -+ return (NULL); -+ } -+ nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); -+ ASN1_OBJECT_free(obj); -+ return nentry; -+} -+ -+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, -+ const ASN1_OBJECT *obj, int type, -+ const unsigned char *bytes, -+ int len) -+{ -+ X509_NAME_ENTRY *ret; -+ -+ if ((ne == NULL) || (*ne == NULL)) { -+ if ((ret = X509_NAME_ENTRY_new()) == NULL) -+ return (NULL); -+ } else -+ ret = *ne; -+ -+ if (!X509_NAME_ENTRY_set_object(ret, obj)) -+ goto err; -+ if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) -+ goto err; -+ -+ if ((ne != NULL) && (*ne == NULL)) -+ *ne = ret; -+ return (ret); -+ err: -+ if ((ne == NULL) || (ret != *ne)) -+ X509_NAME_ENTRY_free(ret); -+ return (NULL); -+} -+ -+int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj) -+{ -+ if ((ne == NULL) || (obj == NULL)) { -+ X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT, -+ ERR_R_PASSED_NULL_PARAMETER); -+ return (0); -+ } -+ ASN1_OBJECT_free(ne->object); -+ ne->object = OBJ_dup(obj); -+ return ((ne->object == NULL) ? 0 : 1); -+} -+ -+int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, -+ const unsigned char *bytes, int len) -+{ -+ int i; -+ -+ if ((ne == NULL) || ((bytes == NULL) && (len != 0))) -+ return (0); -+ if ((type > 0) && (type & MBSTRING_FLAG)) -+ return ASN1_STRING_set_by_NID(&ne->value, bytes, -+ len, type, -+ OBJ_obj2nid(ne->object)) ? 1 : 0; -+ if (len < 0) -+ len = strlen((const char *)bytes); -+ i = ASN1_STRING_set(ne->value, bytes, len); -+ if (!i) -+ return (0); -+ if (type != V_ASN1_UNDEF) { -+ if (type == V_ASN1_APP_CHOOSE) -+ ne->value->type = ASN1_PRINTABLE_type(bytes, len); -+ else -+ ne->value->type = type; -+ } -+ return (1); -+} -+ -+ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) -+{ -+ if (ne == NULL) -+ return (NULL); -+ return (ne->object); -+} -+ -+ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) -+{ -+ if (ne == NULL) -+ return (NULL); -+ return (ne->value); -+} -+ -+int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) -+{ -+ return ne->set; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509rset.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509rset.c -new file mode 100644 -index 0000000..6dee297 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509rset.c -@@ -0,0 +1,40 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+ -+int X509_REQ_set_version(X509_REQ *x, long version) -+{ -+ if (x == NULL) -+ return (0); -+ x->req_info.enc.modified = 1; -+ return (ASN1_INTEGER_set(x->req_info.version, version)); -+} -+ -+int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) -+{ -+ if (x == NULL) -+ return (0); -+ x->req_info.enc.modified = 1; -+ return (X509_NAME_set(&x->req_info.subject, name)); -+} -+ -+int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) -+{ -+ if (x == NULL) -+ return (0); -+ x->req_info.enc.modified = 1; -+ return (X509_PUBKEY_set(&x->req_info.pubkey, pkey)); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509spki.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509spki.c -new file mode 100644 -index 0000000..b142485 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509spki.c -@@ -0,0 +1,75 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+ -+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) -+{ -+ if ((x == NULL) || (x->spkac == NULL)) -+ return (0); -+ return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey)); -+} -+ -+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) -+{ -+ if ((x == NULL) || (x->spkac == NULL)) -+ return (NULL); -+ return (X509_PUBKEY_get(x->spkac->pubkey)); -+} -+ -+/* Load a Netscape SPKI from a base64 encoded string */ -+ -+NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len) -+{ -+ unsigned char *spki_der; -+ const unsigned char *p; -+ int spki_len; -+ NETSCAPE_SPKI *spki; -+ if (len <= 0) -+ len = strlen(str); -+ if ((spki_der = OPENSSL_malloc(len + 1)) == NULL) { -+ X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); -+ if (spki_len < 0) { -+ X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, X509_R_BASE64_DECODE_ERROR); -+ OPENSSL_free(spki_der); -+ return NULL; -+ } -+ p = spki_der; -+ spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); -+ OPENSSL_free(spki_der); -+ return spki; -+} -+ -+/* Generate a base64 encoded string from an SPKI */ -+ -+char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) -+{ -+ unsigned char *der_spki, *p; -+ char *b64_str; -+ int der_len; -+ der_len = i2d_NETSCAPE_SPKI(spki, NULL); -+ der_spki = OPENSSL_malloc(der_len); -+ b64_str = OPENSSL_malloc(der_len * 2); -+ if (der_spki == NULL || b64_str == NULL) { -+ X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE); -+ OPENSSL_free(der_spki); -+ OPENSSL_free(b64_str); -+ return NULL; -+ } -+ p = der_spki; -+ i2d_NETSCAPE_SPKI(spki, &p); -+ EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); -+ OPENSSL_free(der_spki); -+ return b64_str; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509type.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509type.c -new file mode 100644 -index 0000000..aca8355 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x509type.c -@@ -0,0 +1,77 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+ -+int X509_certificate_type(const X509 *x, const EVP_PKEY *pkey) -+{ -+ const EVP_PKEY *pk; -+ int ret = 0, i; -+ -+ if (x == NULL) -+ return (0); -+ -+ if (pkey == NULL) -+ pk = X509_get0_pubkey(x); -+ else -+ pk = pkey; -+ -+ if (pk == NULL) -+ return (0); -+ -+ switch (EVP_PKEY_id(pk)) { -+ case EVP_PKEY_RSA: -+ ret = EVP_PK_RSA | EVP_PKT_SIGN; -+/* if (!sign only extension) */ -+ ret |= EVP_PKT_ENC; -+ break; -+ case EVP_PKEY_DSA: -+ ret = EVP_PK_DSA | EVP_PKT_SIGN; -+ break; -+ case EVP_PKEY_EC: -+ ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH; -+ break; -+ case EVP_PKEY_DH: -+ ret = EVP_PK_DH | EVP_PKT_EXCH; -+ break; -+ case NID_id_GostR3410_2001: -+ case NID_id_GostR3410_2012_256: -+ case NID_id_GostR3410_2012_512: -+ ret = EVP_PKT_EXCH | EVP_PKT_SIGN; -+ break; -+ default: -+ break; -+ } -+ -+ i = X509_get_signature_nid(x); -+ if (i && OBJ_find_sigid_algs(i, NULL, &i)) { -+ -+ switch (i) { -+ case NID_rsaEncryption: -+ case NID_rsa: -+ ret |= EVP_PKS_RSA; -+ break; -+ case NID_dsa: -+ case NID_dsa_2: -+ ret |= EVP_PKS_DSA; -+ break; -+ case NID_X9_62_id_ecPublicKey: -+ ret |= EVP_PKS_EC; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ return (ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_all.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_all.c -new file mode 100644 -index 0000000..124dd2d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_all.c -@@ -0,0 +1,526 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+#include -+#include -+#include -+#include -+ -+int X509_verify(X509 *a, EVP_PKEY *r) -+{ -+ if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature)) -+ return 0; -+ return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg, -+ &a->signature, &a->cert_info, r)); -+} -+ -+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) -+{ -+ return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), -+ &a->sig_alg, a->signature, &a->req_info, r)); -+} -+ -+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) -+{ -+ return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), -+ &a->sig_algor, a->signature, a->spkac, r)); -+} -+ -+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) -+{ -+ x->cert_info.enc.modified = 1; -+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), &x->cert_info.signature, -+ &x->sig_alg, &x->signature, &x->cert_info, pkey, -+ md)); -+} -+ -+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) -+{ -+ x->cert_info.enc.modified = 1; -+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), -+ &x->cert_info.signature, -+ &x->sig_alg, &x->signature, &x->cert_info, ctx); -+} -+ -+#ifndef OPENSSL_NO_OCSP -+int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert) -+{ -+ return OCSP_REQ_CTX_nbio_d2i(rctx, -+ (ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509)); -+} -+#endif -+ -+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) -+{ -+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), &x->sig_alg, NULL, -+ x->signature, &x->req_info, pkey, md)); -+} -+ -+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) -+{ -+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), -+ &x->sig_alg, NULL, x->signature, &x->req_info, -+ ctx); -+} -+ -+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) -+{ -+ x->crl.enc.modified = 1; -+ return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), &x->crl.sig_alg, -+ &x->sig_alg, &x->signature, &x->crl, pkey, md)); -+} -+ -+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) -+{ -+ x->crl.enc.modified = 1; -+ return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), -+ &x->crl.sig_alg, &x->sig_alg, &x->signature, -+ &x->crl, ctx); -+} -+ -+#ifndef OPENSSL_NO_OCSP -+int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl) -+{ -+ return OCSP_REQ_CTX_nbio_d2i(rctx, -+ (ASN1_VALUE **)pcrl, -+ ASN1_ITEM_rptr(X509_CRL)); -+} -+#endif -+ -+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) -+{ -+ return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), &x->sig_algor, NULL, -+ x->signature, x->spkac, pkey, md)); -+} -+ -+#ifndef OPENSSL_NO_STDIO -+X509 *d2i_X509_fp(FILE *fp, X509 **x509) -+{ -+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509); -+} -+ -+int i2d_X509_fp(FILE *fp, X509 *x509) -+{ -+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509); -+} -+#endif -+ -+X509 *d2i_X509_bio(BIO *bp, X509 **x509) -+{ -+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509); -+} -+ -+int i2d_X509_bio(BIO *bp, X509 *x509) -+{ -+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); -+} -+ -+#ifndef OPENSSL_NO_STDIO -+X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) -+{ -+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); -+} -+ -+int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) -+{ -+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); -+} -+#endif -+ -+X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) -+{ -+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); -+} -+ -+int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) -+{ -+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); -+} -+ -+#ifndef OPENSSL_NO_STDIO -+PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) -+{ -+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); -+} -+ -+int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7) -+{ -+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); -+} -+#endif -+ -+PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) -+{ -+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); -+} -+ -+int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7) -+{ -+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); -+} -+ -+#ifndef OPENSSL_NO_STDIO -+X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) -+{ -+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); -+} -+ -+int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) -+{ -+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); -+} -+#endif -+ -+X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) -+{ -+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); -+} -+ -+int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) -+{ -+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); -+} -+ -+#ifndef OPENSSL_NO_RSA -+ -+# ifndef OPENSSL_NO_STDIO -+RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) -+{ -+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); -+} -+ -+int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) -+{ -+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); -+} -+ -+RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) -+{ -+ return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); -+} -+ -+RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa) -+{ -+ return ASN1_d2i_fp((void *(*)(void)) -+ RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp, -+ (void **)rsa); -+} -+ -+int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa) -+{ -+ return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); -+} -+ -+int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa) -+{ -+ return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa); -+} -+# endif -+ -+RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) -+{ -+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); -+} -+ -+int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) -+{ -+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); -+} -+ -+RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) -+{ -+ return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); -+} -+ -+RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa) -+{ -+ return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa); -+} -+ -+int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa) -+{ -+ return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); -+} -+ -+int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa) -+{ -+ return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa); -+} -+#endif -+ -+#ifndef OPENSSL_NO_DSA -+# ifndef OPENSSL_NO_STDIO -+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa) -+{ -+ return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa); -+} -+ -+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa) -+{ -+ return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa); -+} -+ -+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa) -+{ -+ return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa); -+} -+ -+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa) -+{ -+ return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa); -+} -+# endif -+ -+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa) -+{ -+ return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa); -+} -+ -+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa) -+{ -+ return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa); -+} -+ -+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa) -+{ -+ return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa); -+} -+ -+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa) -+{ -+ return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa); -+} -+ -+#endif -+ -+#ifndef OPENSSL_NO_EC -+# ifndef OPENSSL_NO_STDIO -+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey) -+{ -+ return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey); -+} -+ -+int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey) -+{ -+ return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey); -+} -+ -+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey) -+{ -+ return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey); -+} -+ -+int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey) -+{ -+ return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey); -+} -+# endif -+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey) -+{ -+ return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey); -+} -+ -+int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa) -+{ -+ return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa); -+} -+ -+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey) -+{ -+ return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey); -+} -+ -+int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey) -+{ -+ return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey); -+} -+#endif -+ -+int X509_pubkey_digest(const X509 *data, const EVP_MD *type, -+ unsigned char *md, unsigned int *len) -+{ -+ ASN1_BIT_STRING *key; -+ key = X509_get0_pubkey_bitstr(data); -+ if (!key) -+ return 0; -+ return EVP_Digest(key->data, key->length, md, len, type, NULL); -+} -+ -+int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, -+ unsigned int *len) -+{ -+ if (type == EVP_sha1() && (data->ex_flags & EXFLAG_SET) != 0) { -+ /* Asking for SHA1 and we already computed it. */ -+ if (len != NULL) -+ *len = sizeof(data->sha1_hash); -+ memcpy(md, data->sha1_hash, sizeof(data->sha1_hash)); -+ return 1; -+ } -+ return (ASN1_item_digest -+ (ASN1_ITEM_rptr(X509), type, (char *)data, md, len)); -+} -+ -+int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, -+ unsigned char *md, unsigned int *len) -+{ -+ if (type == EVP_sha1() && (data->flags & EXFLAG_SET) != 0) { -+ /* Asking for SHA1; always computed in CRL d2i. */ -+ if (len != NULL) -+ *len = sizeof(data->sha1_hash); -+ memcpy(md, data->sha1_hash, sizeof(data->sha1_hash)); -+ return 1; -+ } -+ return (ASN1_item_digest -+ (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len)); -+} -+ -+int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, -+ unsigned char *md, unsigned int *len) -+{ -+ return (ASN1_item_digest -+ (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len)); -+} -+ -+int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, -+ unsigned char *md, unsigned int *len) -+{ -+ return (ASN1_item_digest -+ (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len)); -+} -+ -+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, -+ const EVP_MD *type, unsigned char *md, -+ unsigned int *len) -+{ -+ return (ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL), type, -+ (char *)data, md, len)); -+} -+ -+#ifndef OPENSSL_NO_STDIO -+X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) -+{ -+ return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8); -+} -+ -+int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8) -+{ -+ return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8); -+} -+#endif -+ -+X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8) -+{ -+ return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8); -+} -+ -+int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8) -+{ -+ return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8); -+} -+ -+#ifndef OPENSSL_NO_STDIO -+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, -+ PKCS8_PRIV_KEY_INFO **p8inf) -+{ -+ return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new, -+ d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf); -+} -+ -+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf) -+{ -+ return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp, -+ p8inf); -+} -+ -+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) -+{ -+ PKCS8_PRIV_KEY_INFO *p8inf; -+ int ret; -+ p8inf = EVP_PKEY2PKCS8(key); -+ if (!p8inf) -+ return 0; -+ ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); -+ PKCS8_PRIV_KEY_INFO_free(p8inf); -+ return ret; -+} -+ -+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey) -+{ -+ return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey); -+} -+ -+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) -+{ -+ return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a); -+} -+ -+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey) -+{ -+ return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey); -+} -+ -+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a) -+{ -+ return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a); -+} -+ -+#endif -+ -+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, -+ PKCS8_PRIV_KEY_INFO **p8inf) -+{ -+ return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new, -+ d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf); -+} -+ -+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf) -+{ -+ return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp, -+ p8inf); -+} -+ -+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) -+{ -+ PKCS8_PRIV_KEY_INFO *p8inf; -+ int ret; -+ p8inf = EVP_PKEY2PKCS8(key); -+ if (!p8inf) -+ return 0; -+ ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); -+ PKCS8_PRIV_KEY_INFO_free(p8inf); -+ return ret; -+} -+ -+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) -+{ -+ return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey); -+} -+ -+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) -+{ -+ return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a); -+} -+ -+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey) -+{ -+ return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey); -+} -+ -+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a) -+{ -+ return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_attrib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_attrib.c -new file mode 100644 -index 0000000..35f4aee ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_attrib.c -@@ -0,0 +1,55 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include "x509_lcl.h" -+ -+/*- -+ * X509_ATTRIBUTE: this has the following form: -+ * -+ * typedef struct x509_attributes_st -+ * { -+ * ASN1_OBJECT *object; -+ * STACK_OF(ASN1_TYPE) *set; -+ * } X509_ATTRIBUTE; -+ * -+ */ -+ -+ASN1_SEQUENCE(X509_ATTRIBUTE) = { -+ ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT), -+ ASN1_SET_OF(X509_ATTRIBUTE, set, ASN1_ANY) -+} ASN1_SEQUENCE_END(X509_ATTRIBUTE) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE) -+IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE) -+ -+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value) -+{ -+ X509_ATTRIBUTE *ret = NULL; -+ ASN1_TYPE *val = NULL; -+ -+ if ((ret = X509_ATTRIBUTE_new()) == NULL) -+ return (NULL); -+ ret->object = OBJ_nid2obj(nid); -+ if ((val = ASN1_TYPE_new()) == NULL) -+ goto err; -+ if (!sk_ASN1_TYPE_push(ret->set, val)) -+ goto err; -+ -+ ASN1_TYPE_set(val, atrtype, value); -+ return (ret); -+ err: -+ X509_ATTRIBUTE_free(ret); -+ ASN1_TYPE_free(val); -+ return (NULL); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_crl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_crl.c -new file mode 100644 -index 0000000..dbed850 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_crl.c -@@ -0,0 +1,459 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include "internal/x509_int.h" -+#include -+#include "x509_lcl.h" -+ -+static int X509_REVOKED_cmp(const X509_REVOKED *const *a, -+ const X509_REVOKED *const *b); -+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); -+ -+ASN1_SEQUENCE(X509_REVOKED) = { -+ ASN1_EMBED(X509_REVOKED,serialNumber, ASN1_INTEGER), -+ ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME), -+ ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION) -+} ASN1_SEQUENCE_END(X509_REVOKED) -+ -+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); -+static int def_crl_lookup(X509_CRL *crl, -+ X509_REVOKED **ret, ASN1_INTEGER *serial, -+ X509_NAME *issuer); -+ -+static X509_CRL_METHOD int_crl_meth = { -+ 0, -+ 0, 0, -+ def_crl_lookup, -+ def_crl_verify -+}; -+ -+static const X509_CRL_METHOD *default_crl_method = &int_crl_meth; -+ -+/* -+ * The X509_CRL_INFO structure needs a bit of customisation. Since we cache -+ * the original encoding the signature won't be affected by reordering of the -+ * revoked field. -+ */ -+static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, -+ void *exarg) -+{ -+ X509_CRL_INFO *a = (X509_CRL_INFO *)*pval; -+ -+ if (!a || !a->revoked) -+ return 1; -+ switch (operation) { -+ /* -+ * Just set cmp function here. We don't sort because that would -+ * affect the output of X509_CRL_print(). -+ */ -+ case ASN1_OP_D2I_POST: -+ (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp); -+ break; -+ } -+ return 1; -+} -+ -+ -+ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { -+ ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER), -+ ASN1_EMBED(X509_CRL_INFO, sig_alg, X509_ALGOR), -+ ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME), -+ ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME), -+ ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME), -+ ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED), -+ ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) -+} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) -+ -+/* -+ * Set CRL entry issuer according to CRL certificate issuer extension. Check -+ * for unhandled critical CRL entry extensions. -+ */ -+ -+static int crl_set_issuers(X509_CRL *crl) -+{ -+ -+ int i, j; -+ GENERAL_NAMES *gens, *gtmp; -+ STACK_OF(X509_REVOKED) *revoked; -+ -+ revoked = X509_CRL_get_REVOKED(crl); -+ -+ gens = NULL; -+ for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { -+ X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); -+ STACK_OF(X509_EXTENSION) *exts; -+ ASN1_ENUMERATED *reason; -+ X509_EXTENSION *ext; -+ gtmp = X509_REVOKED_get_ext_d2i(rev, -+ NID_certificate_issuer, &j, NULL); -+ if (!gtmp && (j != -1)) { -+ crl->flags |= EXFLAG_INVALID; -+ return 1; -+ } -+ -+ if (gtmp) { -+ gens = gtmp; -+ if (!crl->issuers) { -+ crl->issuers = sk_GENERAL_NAMES_new_null(); -+ if (!crl->issuers) -+ return 0; -+ } -+ if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) -+ return 0; -+ } -+ rev->issuer = gens; -+ -+ reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); -+ if (!reason && (j != -1)) { -+ crl->flags |= EXFLAG_INVALID; -+ return 1; -+ } -+ -+ if (reason) { -+ rev->reason = ASN1_ENUMERATED_get(reason); -+ ASN1_ENUMERATED_free(reason); -+ } else -+ rev->reason = CRL_REASON_NONE; -+ -+ /* Check for critical CRL entry extensions */ -+ -+ exts = rev->extensions; -+ -+ for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) { -+ ext = sk_X509_EXTENSION_value(exts, j); -+ if (X509_EXTENSION_get_critical(ext)) { -+ if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_certificate_issuer) -+ continue; -+ crl->flags |= EXFLAG_CRITICAL; -+ break; -+ } -+ } -+ -+ } -+ -+ return 1; -+ -+} -+ -+/* -+ * The X509_CRL structure needs a bit of customisation. Cache some extensions -+ * and hash of the whole CRL. -+ */ -+static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, -+ void *exarg) -+{ -+ X509_CRL *crl = (X509_CRL *)*pval; -+ STACK_OF(X509_EXTENSION) *exts; -+ X509_EXTENSION *ext; -+ int idx; -+ -+ switch (operation) { -+ case ASN1_OP_NEW_POST: -+ crl->idp = NULL; -+ crl->akid = NULL; -+ crl->flags = 0; -+ crl->idp_flags = 0; -+ crl->idp_reasons = CRLDP_ALL_REASONS; -+ crl->meth = default_crl_method; -+ crl->meth_data = NULL; -+ crl->issuers = NULL; -+ crl->crl_number = NULL; -+ crl->base_crl_number = NULL; -+ break; -+ -+ case ASN1_OP_D2I_POST: -+ X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL); -+ crl->idp = X509_CRL_get_ext_d2i(crl, -+ NID_issuing_distribution_point, NULL, -+ NULL); -+ if (crl->idp) -+ setup_idp(crl, crl->idp); -+ -+ crl->akid = X509_CRL_get_ext_d2i(crl, -+ NID_authority_key_identifier, NULL, -+ NULL); -+ -+ crl->crl_number = X509_CRL_get_ext_d2i(crl, -+ NID_crl_number, NULL, NULL); -+ -+ crl->base_crl_number = X509_CRL_get_ext_d2i(crl, -+ NID_delta_crl, NULL, -+ NULL); -+ /* Delta CRLs must have CRL number */ -+ if (crl->base_crl_number && !crl->crl_number) -+ crl->flags |= EXFLAG_INVALID; -+ -+ /* -+ * See if we have any unhandled critical CRL extensions and indicate -+ * this in a flag. We only currently handle IDP so anything else -+ * critical sets the flag. This code accesses the X509_CRL structure -+ * directly: applications shouldn't do this. -+ */ -+ -+ exts = crl->crl.extensions; -+ -+ for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { -+ int nid; -+ ext = sk_X509_EXTENSION_value(exts, idx); -+ nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext)); -+ if (nid == NID_freshest_crl) -+ crl->flags |= EXFLAG_FRESHEST; -+ if (X509_EXTENSION_get_critical(ext)) { -+ /* We handle IDP and deltas */ -+ if ((nid == NID_issuing_distribution_point) -+ || (nid == NID_authority_key_identifier) -+ || (nid == NID_delta_crl)) -+ continue; -+ crl->flags |= EXFLAG_CRITICAL; -+ break; -+ } -+ } -+ -+ if (!crl_set_issuers(crl)) -+ return 0; -+ -+ if (crl->meth->crl_init) { -+ if (crl->meth->crl_init(crl) == 0) -+ return 0; -+ } -+ -+ crl->flags |= EXFLAG_SET; -+ break; -+ -+ case ASN1_OP_FREE_POST: -+ if (crl->meth->crl_free) { -+ if (!crl->meth->crl_free(crl)) -+ return 0; -+ } -+ AUTHORITY_KEYID_free(crl->akid); -+ ISSUING_DIST_POINT_free(crl->idp); -+ ASN1_INTEGER_free(crl->crl_number); -+ ASN1_INTEGER_free(crl->base_crl_number); -+ sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); -+ break; -+ } -+ return 1; -+} -+ -+/* Convert IDP into a more convenient form */ -+ -+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) -+{ -+ int idp_only = 0; -+ /* Set various flags according to IDP */ -+ crl->idp_flags |= IDP_PRESENT; -+ if (idp->onlyuser > 0) { -+ idp_only++; -+ crl->idp_flags |= IDP_ONLYUSER; -+ } -+ if (idp->onlyCA > 0) { -+ idp_only++; -+ crl->idp_flags |= IDP_ONLYCA; -+ } -+ if (idp->onlyattr > 0) { -+ idp_only++; -+ crl->idp_flags |= IDP_ONLYATTR; -+ } -+ -+ if (idp_only > 1) -+ crl->idp_flags |= IDP_INVALID; -+ -+ if (idp->indirectCRL > 0) -+ crl->idp_flags |= IDP_INDIRECT; -+ -+ if (idp->onlysomereasons) { -+ crl->idp_flags |= IDP_REASONS; -+ if (idp->onlysomereasons->length > 0) -+ crl->idp_reasons = idp->onlysomereasons->data[0]; -+ if (idp->onlysomereasons->length > 1) -+ crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8); -+ crl->idp_reasons &= CRLDP_ALL_REASONS; -+ } -+ -+ DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl)); -+} -+ -+ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = { -+ ASN1_EMBED(X509_CRL, crl, X509_CRL_INFO), -+ ASN1_EMBED(X509_CRL, sig_alg, X509_ALGOR), -+ ASN1_EMBED(X509_CRL, signature, ASN1_BIT_STRING) -+} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED) -+ -+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL) -+ -+IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL) -+ -+static int X509_REVOKED_cmp(const X509_REVOKED *const *a, -+ const X509_REVOKED *const *b) -+{ -+ return (ASN1_STRING_cmp((ASN1_STRING *)&(*a)->serialNumber, -+ (ASN1_STRING *)&(*b)->serialNumber)); -+} -+ -+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) -+{ -+ X509_CRL_INFO *inf; -+ inf = &crl->crl; -+ if (inf->revoked == NULL) -+ inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp); -+ if (inf->revoked == NULL || !sk_X509_REVOKED_push(inf->revoked, rev)) { -+ ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ inf->enc.modified = 1; -+ return 1; -+} -+ -+int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r) -+{ -+ if (crl->meth->crl_verify) -+ return crl->meth->crl_verify(crl, r); -+ return 0; -+} -+ -+int X509_CRL_get0_by_serial(X509_CRL *crl, -+ X509_REVOKED **ret, ASN1_INTEGER *serial) -+{ -+ if (crl->meth->crl_lookup) -+ return crl->meth->crl_lookup(crl, ret, serial, NULL); -+ return 0; -+} -+ -+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) -+{ -+ if (crl->meth->crl_lookup) -+ return crl->meth->crl_lookup(crl, ret, -+ X509_get_serialNumber(x), -+ X509_get_issuer_name(x)); -+ return 0; -+} -+ -+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) -+{ -+ return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), -+ &crl->sig_alg, &crl->signature, &crl->crl, r)); -+} -+ -+static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, -+ X509_REVOKED *rev) -+{ -+ int i; -+ -+ if (!rev->issuer) { -+ if (!nm) -+ return 1; -+ if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) -+ return 1; -+ return 0; -+ } -+ -+ if (!nm) -+ nm = X509_CRL_get_issuer(crl); -+ -+ for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { -+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); -+ if (gen->type != GEN_DIRNAME) -+ continue; -+ if (!X509_NAME_cmp(nm, gen->d.directoryName)) -+ return 1; -+ } -+ return 0; -+ -+} -+ -+static int def_crl_lookup(X509_CRL *crl, -+ X509_REVOKED **ret, ASN1_INTEGER *serial, -+ X509_NAME *issuer) -+{ -+ X509_REVOKED rtmp, *rev; -+ int idx; -+ rtmp.serialNumber = *serial; -+ /* -+ * Sort revoked into serial number order if not already sorted. Do this -+ * under a lock to avoid race condition. -+ */ -+ if (!sk_X509_REVOKED_is_sorted(crl->crl.revoked)) { -+ CRYPTO_THREAD_write_lock(crl->lock); -+ sk_X509_REVOKED_sort(crl->crl.revoked); -+ CRYPTO_THREAD_unlock(crl->lock); -+ } -+ idx = sk_X509_REVOKED_find(crl->crl.revoked, &rtmp); -+ if (idx < 0) -+ return 0; -+ /* Need to look for matching name */ -+ for (; idx < sk_X509_REVOKED_num(crl->crl.revoked); idx++) { -+ rev = sk_X509_REVOKED_value(crl->crl.revoked, idx); -+ if (ASN1_INTEGER_cmp(&rev->serialNumber, serial)) -+ return 0; -+ if (crl_revoked_issuer_match(crl, issuer, rev)) { -+ if (ret) -+ *ret = rev; -+ if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) -+ return 2; -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth) -+{ -+ if (meth == NULL) -+ default_crl_method = &int_crl_meth; -+ else -+ default_crl_method = meth; -+} -+ -+X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), -+ int (*crl_free) (X509_CRL *crl), -+ int (*crl_lookup) (X509_CRL *crl, -+ X509_REVOKED **ret, -+ ASN1_INTEGER *ser, -+ X509_NAME *issuer), -+ int (*crl_verify) (X509_CRL *crl, -+ EVP_PKEY *pk)) -+{ -+ X509_CRL_METHOD *m; -+ m = OPENSSL_malloc(sizeof(*m)); -+ if (m == NULL) -+ return NULL; -+ m->crl_init = crl_init; -+ m->crl_free = crl_free; -+ m->crl_lookup = crl_lookup; -+ m->crl_verify = crl_verify; -+ m->flags = X509_CRL_METHOD_DYNAMIC; -+ return m; -+} -+ -+void X509_CRL_METHOD_free(X509_CRL_METHOD *m) -+{ -+ if (m == NULL || !(m->flags & X509_CRL_METHOD_DYNAMIC)) -+ return; -+ OPENSSL_free(m); -+} -+ -+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat) -+{ -+ crl->meth_data = dat; -+} -+ -+void *X509_CRL_get_meth_data(X509_CRL *crl) -+{ -+ return crl->meth_data; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_exten.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_exten.c -new file mode 100644 -index 0000000..f10f4a4 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_exten.c -@@ -0,0 +1,28 @@ -+/* -+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include "x509_lcl.h" -+ -+ASN1_SEQUENCE(X509_EXTENSION) = { -+ ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT), -+ ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN), -+ ASN1_EMBED(X509_EXTENSION, value, ASN1_OCTET_STRING) -+} ASN1_SEQUENCE_END(X509_EXTENSION) -+ -+ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION) -+ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION) -+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) -+IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION) -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_name.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_name.c -new file mode 100644 -index 0000000..97d735f ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_name.c -@@ -0,0 +1,557 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include "internal/x509_int.h" -+#include "internal/asn1_int.h" -+#include "x509_lcl.h" -+ -+/* -+ * Maximum length of X509_NAME: much larger than anything we should -+ * ever see in practice. -+ */ -+ -+#define X509_NAME_MAX (1024 * 1024) -+ -+static int x509_name_ex_d2i(ASN1_VALUE **val, -+ const unsigned char **in, long len, -+ const ASN1_ITEM *it, -+ int tag, int aclass, char opt, ASN1_TLC *ctx); -+ -+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, -+ const ASN1_ITEM *it, int tag, int aclass); -+static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); -+static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); -+ -+static int x509_name_encode(X509_NAME *a); -+static int x509_name_canon(X509_NAME *a); -+static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in); -+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname, -+ unsigned char **in); -+ -+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, -+ int indent, -+ const char *fname, const ASN1_PCTX *pctx); -+ -+ASN1_SEQUENCE(X509_NAME_ENTRY) = { -+ ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), -+ ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) -+} ASN1_SEQUENCE_END(X509_NAME_ENTRY) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) -+IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) -+ -+/* -+ * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so -+ * declare two template wrappers for this -+ */ -+ -+ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) -+static_ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES) -+ -+ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) -+static_ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) -+ -+/* -+ * Normally that's where it would end: we'd have two nested STACK structures -+ * representing the ASN1. Unfortunately X509_NAME uses a completely different -+ * form and caches encodings so we have to process the internal form and -+ * convert to the external form. -+ */ -+ -+static const ASN1_EXTERN_FUNCS x509_name_ff = { -+ NULL, -+ x509_name_ex_new, -+ x509_name_ex_free, -+ 0, /* Default clear behaviour is OK */ -+ x509_name_ex_d2i, -+ x509_name_ex_i2d, -+ x509_name_ex_print -+}; -+ -+IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) -+ -+IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) -+ -+static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) -+{ -+ X509_NAME *ret = OPENSSL_zalloc(sizeof(*ret)); -+ -+ if (ret == NULL) -+ goto memerr; -+ if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) -+ goto memerr; -+ if ((ret->bytes = BUF_MEM_new()) == NULL) -+ goto memerr; -+ ret->modified = 1; -+ *val = (ASN1_VALUE *)ret; -+ return 1; -+ -+ memerr: -+ ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); -+ if (ret) { -+ sk_X509_NAME_ENTRY_free(ret->entries); -+ OPENSSL_free(ret); -+ } -+ return 0; -+} -+ -+static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -+{ -+ X509_NAME *a; -+ -+ if (!pval || !*pval) -+ return; -+ a = (X509_NAME *)*pval; -+ -+ BUF_MEM_free(a->bytes); -+ sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); -+ OPENSSL_free(a->canon_enc); -+ OPENSSL_free(a); -+ *pval = NULL; -+} -+ -+static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) -+{ -+ sk_X509_NAME_ENTRY_free(ne); -+} -+ -+static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) -+{ -+ sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); -+} -+ -+static int x509_name_ex_d2i(ASN1_VALUE **val, -+ const unsigned char **in, long len, -+ const ASN1_ITEM *it, int tag, int aclass, -+ char opt, ASN1_TLC *ctx) -+{ -+ const unsigned char *p = *in, *q; -+ union { -+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; -+ ASN1_VALUE *a; -+ } intname = { -+ NULL -+ }; -+ union { -+ X509_NAME *x; -+ ASN1_VALUE *a; -+ } nm = { -+ NULL -+ }; -+ int i, j, ret; -+ STACK_OF(X509_NAME_ENTRY) *entries; -+ X509_NAME_ENTRY *entry; -+ if (len > X509_NAME_MAX) -+ len = X509_NAME_MAX; -+ q = p; -+ -+ /* Get internal representation of Name */ -+ ret = ASN1_item_ex_d2i(&intname.a, -+ &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -+ tag, aclass, opt, ctx); -+ -+ if (ret <= 0) -+ return ret; -+ -+ if (*val) -+ x509_name_ex_free(val, NULL); -+ if (!x509_name_ex_new(&nm.a, NULL)) -+ goto err; -+ /* We've decoded it: now cache encoding */ -+ if (!BUF_MEM_grow(nm.x->bytes, p - q)) -+ goto err; -+ memcpy(nm.x->bytes->data, q, p - q); -+ -+ /* Convert internal representation to X509_NAME structure */ -+ for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { -+ entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); -+ for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { -+ entry = sk_X509_NAME_ENTRY_value(entries, j); -+ entry->set = i; -+ if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) -+ goto err; -+ sk_X509_NAME_ENTRY_set(entries, j, NULL); -+ } -+ } -+ ret = x509_name_canon(nm.x); -+ if (!ret) -+ goto err; -+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, -+ local_sk_X509_NAME_ENTRY_free); -+ nm.x->modified = 0; -+ *val = nm.a; -+ *in = p; -+ return ret; -+ -+ err: -+ if (nm.x != NULL) -+ X509_NAME_free(nm.x); -+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, -+ local_sk_X509_NAME_ENTRY_pop_free); -+ ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); -+ return 0; -+} -+ -+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, -+ const ASN1_ITEM *it, int tag, int aclass) -+{ -+ int ret; -+ X509_NAME *a = (X509_NAME *)*val; -+ if (a->modified) { -+ ret = x509_name_encode(a); -+ if (ret < 0) -+ return ret; -+ ret = x509_name_canon(a); -+ if (ret < 0) -+ return ret; -+ } -+ ret = a->bytes->length; -+ if (out != NULL) { -+ memcpy(*out, a->bytes->data, ret); -+ *out += ret; -+ } -+ return ret; -+} -+ -+static int x509_name_encode(X509_NAME *a) -+{ -+ union { -+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; -+ ASN1_VALUE *a; -+ } intname = { -+ NULL -+ }; -+ int len; -+ unsigned char *p; -+ STACK_OF(X509_NAME_ENTRY) *entries = NULL; -+ X509_NAME_ENTRY *entry; -+ int i, set = -1; -+ intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); -+ if (!intname.s) -+ goto memerr; -+ for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { -+ entry = sk_X509_NAME_ENTRY_value(a->entries, i); -+ if (entry->set != set) { -+ entries = sk_X509_NAME_ENTRY_new_null(); -+ if (!entries) -+ goto memerr; -+ if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) { -+ sk_X509_NAME_ENTRY_free(entries); -+ goto memerr; -+ } -+ set = entry->set; -+ } -+ if (!sk_X509_NAME_ENTRY_push(entries, entry)) -+ goto memerr; -+ } -+ len = ASN1_item_ex_i2d(&intname.a, NULL, -+ ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); -+ if (!BUF_MEM_grow(a->bytes, len)) -+ goto memerr; -+ p = (unsigned char *)a->bytes->data; -+ ASN1_item_ex_i2d(&intname.a, -+ &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); -+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, -+ local_sk_X509_NAME_ENTRY_free); -+ a->modified = 0; -+ return len; -+ memerr: -+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, -+ local_sk_X509_NAME_ENTRY_free); -+ ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); -+ return -1; -+} -+ -+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, -+ int indent, -+ const char *fname, const ASN1_PCTX *pctx) -+{ -+ if (X509_NAME_print_ex(out, (const X509_NAME *)*pval, -+ indent, pctx->nm_flags) <= 0) -+ return 0; -+ return 2; -+} -+ -+/* -+ * This function generates the canonical encoding of the Name structure. In -+ * it all strings are converted to UTF8, leading, trailing and multiple -+ * spaces collapsed, converted to lower case and the leading SEQUENCE header -+ * removed. In future we could also normalize the UTF8 too. By doing this -+ * comparison of Name structures can be rapidly performed by just using -+ * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name -+ * constraints of type dirName can also be checked with a simple memcmp(). -+ */ -+ -+static int x509_name_canon(X509_NAME *a) -+{ -+ unsigned char *p; -+ STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; -+ STACK_OF(X509_NAME_ENTRY) *entries = NULL; -+ X509_NAME_ENTRY *entry, *tmpentry = NULL; -+ int i, set = -1, ret = 0, len; -+ -+ OPENSSL_free(a->canon_enc); -+ a->canon_enc = NULL; -+ /* Special case: empty X509_NAME => null encoding */ -+ if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { -+ a->canon_enclen = 0; -+ return 1; -+ } -+ intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); -+ if (!intname) -+ goto err; -+ for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { -+ entry = sk_X509_NAME_ENTRY_value(a->entries, i); -+ if (entry->set != set) { -+ entries = sk_X509_NAME_ENTRY_new_null(); -+ if (!entries) -+ goto err; -+ if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { -+ sk_X509_NAME_ENTRY_free(entries); -+ goto err; -+ } -+ set = entry->set; -+ } -+ tmpentry = X509_NAME_ENTRY_new(); -+ if (tmpentry == NULL) -+ goto err; -+ tmpentry->object = OBJ_dup(entry->object); -+ if (tmpentry->object == NULL) -+ goto err; -+ if (!asn1_string_canon(tmpentry->value, entry->value)) -+ goto err; -+ if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) -+ goto err; -+ tmpentry = NULL; -+ } -+ -+ /* Finally generate encoding */ -+ -+ len = i2d_name_canon(intname, NULL); -+ if (len < 0) -+ goto err; -+ a->canon_enclen = len; -+ -+ p = OPENSSL_malloc(a->canon_enclen); -+ -+ if (p == NULL) -+ goto err; -+ -+ a->canon_enc = p; -+ -+ i2d_name_canon(intname, &p); -+ -+ ret = 1; -+ -+ err: -+ -+ X509_NAME_ENTRY_free(tmpentry); -+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, -+ local_sk_X509_NAME_ENTRY_pop_free); -+ return ret; -+} -+ -+/* Bitmap of all the types of string that will be canonicalized. */ -+ -+#define ASN1_MASK_CANON \ -+ (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ -+ | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ -+ | B_ASN1_VISIBLESTRING) -+ -+static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in) -+{ -+ unsigned char *to, *from; -+ int len, i; -+ -+ /* If type not in bitmask just copy string across */ -+ if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) { -+ if (!ASN1_STRING_copy(out, in)) -+ return 0; -+ return 1; -+ } -+ -+ out->type = V_ASN1_UTF8STRING; -+ out->length = ASN1_STRING_to_UTF8(&out->data, in); -+ if (out->length == -1) -+ return 0; -+ -+ to = out->data; -+ from = to; -+ -+ len = out->length; -+ -+ /* -+ * Convert string in place to canonical form. Ultimately we may need to -+ * handle a wider range of characters but for now ignore anything with -+ * MSB set and rely on the isspace() and tolower() functions. -+ */ -+ -+ /* Ignore leading spaces */ -+ while ((len > 0) && !(*from & 0x80) && isspace(*from)) { -+ from++; -+ len--; -+ } -+ -+ to = from + len; -+ -+ /* Ignore trailing spaces */ -+ while ((len > 0) && !(to[-1] & 0x80) && isspace(to[-1])) { -+ to--; -+ len--; -+ } -+ -+ to = out->data; -+ -+ i = 0; -+ while (i < len) { -+ /* If MSB set just copy across */ -+ if (*from & 0x80) { -+ *to++ = *from++; -+ i++; -+ } -+ /* Collapse multiple spaces */ -+ else if (isspace(*from)) { -+ /* Copy one space across */ -+ *to++ = ' '; -+ /* -+ * Ignore subsequent spaces. Note: don't need to check len here -+ * because we know the last character is a non-space so we can't -+ * overflow. -+ */ -+ do { -+ from++; -+ i++; -+ } -+ while (!(*from & 0x80) && isspace(*from)); -+ } else { -+ *to++ = tolower(*from); -+ from++; -+ i++; -+ } -+ } -+ -+ out->length = to - out->data; -+ -+ return 1; -+ -+} -+ -+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, -+ unsigned char **in) -+{ -+ int i, len, ltmp; -+ ASN1_VALUE *v; -+ STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; -+ -+ len = 0; -+ for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) { -+ v = sk_ASN1_VALUE_value(intname, i); -+ ltmp = ASN1_item_ex_i2d(&v, in, -+ ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1); -+ if (ltmp < 0) -+ return ltmp; -+ len += ltmp; -+ } -+ return len; -+} -+ -+int X509_NAME_set(X509_NAME **xn, X509_NAME *name) -+{ -+ X509_NAME *in; -+ -+ if (!xn || !name) -+ return (0); -+ -+ if (*xn != name) { -+ in = X509_NAME_dup(name); -+ if (in != NULL) { -+ X509_NAME_free(*xn); -+ *xn = in; -+ } -+ } -+ return (*xn != NULL); -+} -+ -+int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase) -+{ -+ char *s, *c, *b; -+ int l, i; -+ -+ l = 80 - 2 - obase; -+ -+ b = X509_NAME_oneline(name, NULL, 0); -+ if (!b) -+ return 0; -+ if (!*b) { -+ OPENSSL_free(b); -+ return 1; -+ } -+ s = b + 1; /* skip the first slash */ -+ -+ c = s; -+ for (;;) { -+#ifndef CHARSET_EBCDIC -+ if (((*s == '/') && -+ ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') || -+ ((s[2] >= 'A') -+ && (s[2] <= 'Z') -+ && (s[3] == '=')) -+ ))) || (*s == '\0')) -+#else -+ if (((*s == '/') && -+ (isupper(s[1]) && ((s[2] == '=') || -+ (isupper(s[2]) && (s[3] == '=')) -+ ))) || (*s == '\0')) -+#endif -+ { -+ i = s - c; -+ if (BIO_write(bp, c, i) != i) -+ goto err; -+ c = s + 1; /* skip following slash */ -+ if (*s != '\0') { -+ if (BIO_write(bp, ", ", 2) != 2) -+ goto err; -+ } -+ l--; -+ } -+ if (*s == '\0') -+ break; -+ s++; -+ l--; -+ } -+ -+ OPENSSL_free(b); -+ return 1; -+ err: -+ X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB); -+ OPENSSL_free(b); -+ return 0; -+} -+ -+int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, -+ size_t *pderlen) -+{ -+ /* Make sure encoding is valid */ -+ if (i2d_X509_NAME(nm, NULL) <= 0) -+ return 0; -+ if (pder != NULL) -+ *pder = (unsigned char *)nm->bytes->data; -+ if (pderlen != NULL) -+ *pderlen = nm->bytes->length; -+ return 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_pubkey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_pubkey.c -new file mode 100644 -index 0000000..cc69283 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_pubkey.c -@@ -0,0 +1,374 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include "internal/asn1_int.h" -+#include "internal/evp_int.h" -+#include "internal/x509_int.h" -+#include -+#include -+ -+struct X509_pubkey_st { -+ X509_ALGOR *algor; -+ ASN1_BIT_STRING *public_key; -+ EVP_PKEY *pkey; -+}; -+ -+static int x509_pubkey_decode(EVP_PKEY **pk, X509_PUBKEY *key); -+ -+/* Minor tweak to operation: free up EVP_PKEY */ -+static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, -+ void *exarg) -+{ -+ if (operation == ASN1_OP_FREE_POST) { -+ X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; -+ EVP_PKEY_free(pubkey->pkey); -+ } else if (operation == ASN1_OP_D2I_POST) { -+ /* Attempt to decode public key and cache in pubkey structure. */ -+ X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; -+ EVP_PKEY_free(pubkey->pkey); -+ /* -+ * Opportunistically decode the key but remove any non fatal errors -+ * from the queue. Subsequent explicit attempts to decode/use the key -+ * will return an appropriate error. -+ */ -+ ERR_set_mark(); -+ if (x509_pubkey_decode(&pubkey->pkey, pubkey) == -1) -+ return 0; -+ ERR_pop_to_mark(); -+ } -+ return 1; -+} -+ -+ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { -+ ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), -+ ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) -+} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) -+ -+int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) -+{ -+ X509_PUBKEY *pk = NULL; -+ -+ if (x == NULL) -+ return (0); -+ -+ if ((pk = X509_PUBKEY_new()) == NULL) -+ goto error; -+ -+ if (pkey->ameth) { -+ if (pkey->ameth->pub_encode) { -+ if (!pkey->ameth->pub_encode(pk, pkey)) { -+ X509err(X509_F_X509_PUBKEY_SET, -+ X509_R_PUBLIC_KEY_ENCODE_ERROR); -+ goto error; -+ } -+ } else { -+ X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED); -+ goto error; -+ } -+ } else { -+ X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM); -+ goto error; -+ } -+ -+ X509_PUBKEY_free(*x); -+ *x = pk; -+ pk->pkey = pkey; -+ EVP_PKEY_up_ref(pkey); -+ return 1; -+ -+ error: -+ X509_PUBKEY_free(pk); -+ return 0; -+} -+ -+/* -+ * Attempt to decode a public key. -+ * Returns 1 on success, 0 for a decode failure and -1 for a fatal -+ * error e.g. malloc failure. -+ */ -+ -+ -+static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key) -+ { -+ EVP_PKEY *pkey = EVP_PKEY_new(); -+ -+ if (pkey == NULL) { -+ X509err(X509_F_X509_PUBKEY_DECODE, ERR_R_MALLOC_FAILURE); -+ return -1; -+ } -+ -+ if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(key->algor->algorithm))) { -+ X509err(X509_F_X509_PUBKEY_DECODE, X509_R_UNSUPPORTED_ALGORITHM); -+ goto error; -+ } -+ -+ if (pkey->ameth->pub_decode) { -+ /* -+ * Treat any failure of pub_decode as a decode error. In -+ * future we could have different return codes for decode -+ * errors and fatal errors such as malloc failure. -+ */ -+ if (!pkey->ameth->pub_decode(pkey, key)) { -+ X509err(X509_F_X509_PUBKEY_DECODE, X509_R_PUBLIC_KEY_DECODE_ERROR); -+ goto error; -+ } -+ } else { -+ X509err(X509_F_X509_PUBKEY_DECODE, X509_R_METHOD_NOT_SUPPORTED); -+ goto error; -+ } -+ -+ *ppkey = pkey; -+ return 1; -+ -+ error: -+ EVP_PKEY_free(pkey); -+ return 0; -+} -+ -+EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key) -+{ -+ EVP_PKEY *ret = NULL; -+ -+ if (key == NULL || key->public_key == NULL) -+ return NULL; -+ -+ if (key->pkey != NULL) -+ return key->pkey; -+ -+ /* -+ * When the key ASN.1 is initially parsed an attempt is made to -+ * decode the public key and cache the EVP_PKEY structure. If this -+ * operation fails the cached value will be NULL. Parsing continues -+ * to allow parsing of unknown key types or unsupported forms. -+ * We repeat the decode operation so the appropriate errors are left -+ * in the queue. -+ */ -+ x509_pubkey_decode(&ret, key); -+ /* If decode doesn't fail something bad happened */ -+ if (ret != NULL) { -+ X509err(X509_F_X509_PUBKEY_GET0, ERR_R_INTERNAL_ERROR); -+ EVP_PKEY_free(ret); -+ } -+ -+ return NULL; -+} -+ -+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) -+{ -+ EVP_PKEY *ret = X509_PUBKEY_get0(key); -+ if (ret != NULL) -+ EVP_PKEY_up_ref(ret); -+ return ret; -+} -+ -+/* -+ * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or -+ * decode as X509_PUBKEY -+ */ -+ -+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) -+{ -+ X509_PUBKEY *xpk; -+ EVP_PKEY *pktmp; -+ const unsigned char *q; -+ q = *pp; -+ xpk = d2i_X509_PUBKEY(NULL, &q, length); -+ if (!xpk) -+ return NULL; -+ pktmp = X509_PUBKEY_get(xpk); -+ X509_PUBKEY_free(xpk); -+ if (!pktmp) -+ return NULL; -+ *pp = q; -+ if (a) { -+ EVP_PKEY_free(*a); -+ *a = pktmp; -+ } -+ return pktmp; -+} -+ -+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp) -+{ -+ X509_PUBKEY *xpk = NULL; -+ int ret; -+ if (!a) -+ return 0; -+ if (!X509_PUBKEY_set(&xpk, a)) -+ return 0; -+ ret = i2d_X509_PUBKEY(xpk, pp); -+ X509_PUBKEY_free(xpk); -+ return ret; -+} -+ -+/* -+ * The following are equivalents but which return RSA and DSA keys -+ */ -+#ifndef OPENSSL_NO_RSA -+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) -+{ -+ EVP_PKEY *pkey; -+ RSA *key; -+ const unsigned char *q; -+ q = *pp; -+ pkey = d2i_PUBKEY(NULL, &q, length); -+ if (!pkey) -+ return NULL; -+ key = EVP_PKEY_get1_RSA(pkey); -+ EVP_PKEY_free(pkey); -+ if (!key) -+ return NULL; -+ *pp = q; -+ if (a) { -+ RSA_free(*a); -+ *a = key; -+ } -+ return key; -+} -+ -+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp) -+{ -+ EVP_PKEY *pktmp; -+ int ret; -+ if (!a) -+ return 0; -+ pktmp = EVP_PKEY_new(); -+ if (pktmp == NULL) { -+ ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ EVP_PKEY_set1_RSA(pktmp, a); -+ ret = i2d_PUBKEY(pktmp, pp); -+ EVP_PKEY_free(pktmp); -+ return ret; -+} -+#endif -+ -+#ifndef OPENSSL_NO_DSA -+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) -+{ -+ EVP_PKEY *pkey; -+ DSA *key; -+ const unsigned char *q; -+ q = *pp; -+ pkey = d2i_PUBKEY(NULL, &q, length); -+ if (!pkey) -+ return NULL; -+ key = EVP_PKEY_get1_DSA(pkey); -+ EVP_PKEY_free(pkey); -+ if (!key) -+ return NULL; -+ *pp = q; -+ if (a) { -+ DSA_free(*a); -+ *a = key; -+ } -+ return key; -+} -+ -+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp) -+{ -+ EVP_PKEY *pktmp; -+ int ret; -+ if (!a) -+ return 0; -+ pktmp = EVP_PKEY_new(); -+ if (pktmp == NULL) { -+ ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ EVP_PKEY_set1_DSA(pktmp, a); -+ ret = i2d_PUBKEY(pktmp, pp); -+ EVP_PKEY_free(pktmp); -+ return ret; -+} -+#endif -+ -+#ifndef OPENSSL_NO_EC -+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) -+{ -+ EVP_PKEY *pkey; -+ EC_KEY *key; -+ const unsigned char *q; -+ q = *pp; -+ pkey = d2i_PUBKEY(NULL, &q, length); -+ if (!pkey) -+ return (NULL); -+ key = EVP_PKEY_get1_EC_KEY(pkey); -+ EVP_PKEY_free(pkey); -+ if (!key) -+ return (NULL); -+ *pp = q; -+ if (a) { -+ EC_KEY_free(*a); -+ *a = key; -+ } -+ return (key); -+} -+ -+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp) -+{ -+ EVP_PKEY *pktmp; -+ int ret; -+ if (!a) -+ return (0); -+ if ((pktmp = EVP_PKEY_new()) == NULL) { -+ ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE); -+ return (0); -+ } -+ EVP_PKEY_set1_EC_KEY(pktmp, a); -+ ret = i2d_PUBKEY(pktmp, pp); -+ EVP_PKEY_free(pktmp); -+ return (ret); -+} -+#endif -+ -+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, -+ int ptype, void *pval, -+ unsigned char *penc, int penclen) -+{ -+ if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval)) -+ return 0; -+ if (penc) { -+ OPENSSL_free(pub->public_key->data); -+ pub->public_key->data = penc; -+ pub->public_key->length = penclen; -+ /* Set number of unused bits to zero */ -+ pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); -+ pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; -+ } -+ return 1; -+} -+ -+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, -+ const unsigned char **pk, int *ppklen, -+ X509_ALGOR **pa, X509_PUBKEY *pub) -+{ -+ if (ppkalg) -+ *ppkalg = pub->algor->algorithm; -+ if (pk) { -+ *pk = pub->public_key->data; -+ *ppklen = pub->public_key->length; -+ } -+ if (pa) -+ *pa = pub->algor; -+ return 1; -+} -+ -+ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) -+{ -+ if (x == NULL) -+ return NULL; -+ return x->cert_info.key->public_key; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_req.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_req.c -new file mode 100644 -index 0000000..c2da95a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_req.c -@@ -0,0 +1,68 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include "internal/x509_int.h" -+ -+/*- -+ * X509_REQ_INFO is handled in an unusual way to get round -+ * invalid encodings. Some broken certificate requests don't -+ * encode the attributes field if it is empty. This is in -+ * violation of PKCS#10 but we need to tolerate it. We do -+ * this by making the attributes field OPTIONAL then using -+ * the callback to initialise it to an empty STACK. -+ * -+ * This means that the field will be correctly encoded unless -+ * we NULL out the field. -+ * -+ * As a result we no longer need the req_kludge field because -+ * the information is now contained in the attributes field: -+ * 1. If it is NULL then it's the invalid omission. -+ * 2. If it is empty it is the correct encoding. -+ * 3. If it is not empty then some attributes are present. -+ * -+ */ -+ -+static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, -+ void *exarg) -+{ -+ X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval; -+ -+ if (operation == ASN1_OP_NEW_POST) { -+ rinf->attributes = sk_X509_ATTRIBUTE_new_null(); -+ if (!rinf->attributes) -+ return 0; -+ } -+ return 1; -+} -+ -+ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { -+ ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), -+ ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), -+ ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY), -+ /* This isn't really OPTIONAL but it gets round invalid -+ * encodings -+ */ -+ ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0) -+} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO) -+ -+ASN1_SEQUENCE_ref(X509_REQ, 0) = { -+ ASN1_EMBED(X509_REQ, req_info, X509_REQ_INFO), -+ ASN1_EMBED(X509_REQ, sig_alg, X509_ALGOR), -+ ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING) -+} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ) -+ -+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ) -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_x509.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_x509.c -new file mode 100644 -index 0000000..6783fd8 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_x509.c -@@ -0,0 +1,224 @@ -+/* -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+ -+ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { -+ ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), -+ ASN1_EMBED(X509_CINF, serialNumber, ASN1_INTEGER), -+ ASN1_EMBED(X509_CINF, signature, X509_ALGOR), -+ ASN1_SIMPLE(X509_CINF, issuer, X509_NAME), -+ ASN1_EMBED(X509_CINF, validity, X509_VAL), -+ ASN1_SIMPLE(X509_CINF, subject, X509_NAME), -+ ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY), -+ ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1), -+ ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2), -+ ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3) -+} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) -+/* X509 top level structure needs a bit of customisation */ -+ -+extern void policy_cache_free(X509_POLICY_CACHE *cache); -+ -+static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, -+ void *exarg) -+{ -+ X509 *ret = (X509 *)*pval; -+ -+ switch (operation) { -+ -+ case ASN1_OP_NEW_POST: -+ ret->ex_flags = 0; -+ ret->ex_pathlen = -1; -+ ret->ex_pcpathlen = -1; -+ ret->skid = NULL; -+ ret->akid = NULL; -+#ifndef OPENSSL_NO_RFC3779 -+ ret->rfc3779_addr = NULL; -+ ret->rfc3779_asid = NULL; -+#endif -+ ret->aux = NULL; -+ ret->crldp = NULL; -+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data)) -+ return 0; -+ break; -+ -+ case ASN1_OP_FREE_POST: -+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); -+ X509_CERT_AUX_free(ret->aux); -+ ASN1_OCTET_STRING_free(ret->skid); -+ AUTHORITY_KEYID_free(ret->akid); -+ CRL_DIST_POINTS_free(ret->crldp); -+ policy_cache_free(ret->policy_cache); -+ GENERAL_NAMES_free(ret->altname); -+ NAME_CONSTRAINTS_free(ret->nc); -+#ifndef OPENSSL_NO_RFC3779 -+ sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); -+ ASIdentifiers_free(ret->rfc3779_asid); -+#endif -+ break; -+ -+ } -+ -+ return 1; -+ -+} -+ -+ASN1_SEQUENCE_ref(X509, x509_cb) = { -+ ASN1_EMBED(X509, cert_info, X509_CINF), -+ ASN1_EMBED(X509, sig_alg, X509_ALGOR), -+ ASN1_EMBED(X509, signature, ASN1_BIT_STRING) -+} ASN1_SEQUENCE_END_ref(X509, X509) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509) -+ -+IMPLEMENT_ASN1_DUP_FUNCTION(X509) -+ -+int X509_set_ex_data(X509 *r, int idx, void *arg) -+{ -+ return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); -+} -+ -+void *X509_get_ex_data(X509 *r, int idx) -+{ -+ return (CRYPTO_get_ex_data(&r->ex_data, idx)); -+} -+ -+/* -+ * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with -+ * extra info tagged on the end. Since these functions set how a certificate -+ * is trusted they should only be used when the certificate comes from a -+ * reliable source such as local storage. -+ */ -+ -+X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) -+{ -+ const unsigned char *q; -+ X509 *ret; -+ int freeret = 0; -+ -+ /* Save start position */ -+ q = *pp; -+ -+ if (a == NULL || *a == NULL) -+ freeret = 1; -+ ret = d2i_X509(a, &q, length); -+ /* If certificate unreadable then forget it */ -+ if (ret == NULL) -+ return NULL; -+ /* update length */ -+ length -= q - *pp; -+ if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length)) -+ goto err; -+ *pp = q; -+ return ret; -+ err: -+ if (freeret) { -+ X509_free(ret); -+ if (a) -+ *a = NULL; -+ } -+ return NULL; -+} -+ -+/* -+ * Serialize trusted certificate to *pp or just return the required buffer -+ * length if pp == NULL. We ultimately want to avoid modifying *pp in the -+ * error path, but that depends on similar hygiene in lower-level functions. -+ * Here we avoid compounding the problem. -+ */ -+static int i2d_x509_aux_internal(X509 *a, unsigned char **pp) -+{ -+ int length, tmplen; -+ unsigned char *start = pp != NULL ? *pp : NULL; -+ -+ OPENSSL_assert(pp == NULL || *pp != NULL); -+ -+ /* -+ * This might perturb *pp on error, but fixing that belongs in i2d_X509() -+ * not here. It should be that if a == NULL length is zero, but we check -+ * both just in case. -+ */ -+ length = i2d_X509(a, pp); -+ if (length <= 0 || a == NULL) -+ return length; -+ -+ tmplen = i2d_X509_CERT_AUX(a->aux, pp); -+ if (tmplen < 0) { -+ if (start != NULL) -+ *pp = start; -+ return tmplen; -+ } -+ length += tmplen; -+ -+ return length; -+} -+ -+/* -+ * Serialize trusted certificate to *pp, or just return the required buffer -+ * length if pp == NULL. -+ * -+ * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since -+ * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do -+ * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the -+ * allocated buffer. -+ */ -+int i2d_X509_AUX(X509 *a, unsigned char **pp) -+{ -+ int length; -+ unsigned char *tmp; -+ -+ /* Buffer provided by caller */ -+ if (pp == NULL || *pp != NULL) -+ return i2d_x509_aux_internal(a, pp); -+ -+ /* Obtain the combined length */ -+ if ((length = i2d_x509_aux_internal(a, NULL)) <= 0) -+ return length; -+ -+ /* Allocate requisite combined storage */ -+ *pp = tmp = OPENSSL_malloc(length); -+ if (tmp == NULL) -+ return -1; /* Push error onto error stack? */ -+ -+ /* Encode, but keep *pp at the originally malloced pointer */ -+ length = i2d_x509_aux_internal(a, &tmp); -+ if (length <= 0) { -+ OPENSSL_free(*pp); -+ *pp = NULL; -+ } -+ return length; -+} -+ -+int i2d_re_X509_tbs(X509 *x, unsigned char **pp) -+{ -+ x->cert_info.enc.modified = 1; -+ return i2d_X509_CINF(&x->cert_info, pp); -+} -+ -+void X509_get0_signature(const ASN1_BIT_STRING **psig, -+ const X509_ALGOR **palg, const X509 *x) -+{ -+ if (psig) -+ *psig = &x->signature; -+ if (palg) -+ *palg = &x->sig_alg; -+} -+ -+int X509_get_signature_nid(const X509 *x) -+{ -+ return OBJ_obj2nid(x->sig_alg.algorithm); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_x509a.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_x509a.c -new file mode 100644 -index 0000000..8c9ad71 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509/x_x509a.c -@@ -0,0 +1,169 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include "internal/x509_int.h" -+ -+/* -+ * X509_CERT_AUX routines. These are used to encode additional user -+ * modifiable data about a certificate. This data is appended to the X509 -+ * encoding when the *_X509_AUX routines are used. This means that the -+ * "traditional" X509 routines will simply ignore the extra data. -+ */ -+ -+static X509_CERT_AUX *aux_get(X509 *x); -+ -+ASN1_SEQUENCE(X509_CERT_AUX) = { -+ ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT), -+ ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0), -+ ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING), -+ ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING), -+ ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1) -+} ASN1_SEQUENCE_END(X509_CERT_AUX) -+ -+IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX) -+ -+int X509_trusted(const X509 *x) -+{ -+ return x->aux ? 1 : 0; -+} -+ -+static X509_CERT_AUX *aux_get(X509 *x) -+{ -+ if (x == NULL) -+ return NULL; -+ if (x->aux == NULL && (x->aux = X509_CERT_AUX_new()) == NULL) -+ return NULL; -+ return x->aux; -+} -+ -+int X509_alias_set1(X509 *x, const unsigned char *name, int len) -+{ -+ X509_CERT_AUX *aux; -+ if (!name) { -+ if (!x || !x->aux || !x->aux->alias) -+ return 1; -+ ASN1_UTF8STRING_free(x->aux->alias); -+ x->aux->alias = NULL; -+ return 1; -+ } -+ if ((aux = aux_get(x)) == NULL) -+ return 0; -+ if (aux->alias == NULL && (aux->alias = ASN1_UTF8STRING_new()) == NULL) -+ return 0; -+ return ASN1_STRING_set(aux->alias, name, len); -+} -+ -+int X509_keyid_set1(X509 *x, const unsigned char *id, int len) -+{ -+ X509_CERT_AUX *aux; -+ if (!id) { -+ if (!x || !x->aux || !x->aux->keyid) -+ return 1; -+ ASN1_OCTET_STRING_free(x->aux->keyid); -+ x->aux->keyid = NULL; -+ return 1; -+ } -+ if ((aux = aux_get(x)) == NULL) -+ return 0; -+ if (aux->keyid == NULL -+ && (aux->keyid = ASN1_OCTET_STRING_new()) == NULL) -+ return 0; -+ return ASN1_STRING_set(aux->keyid, id, len); -+} -+ -+unsigned char *X509_alias_get0(X509 *x, int *len) -+{ -+ if (!x->aux || !x->aux->alias) -+ return NULL; -+ if (len) -+ *len = x->aux->alias->length; -+ return x->aux->alias->data; -+} -+ -+unsigned char *X509_keyid_get0(X509 *x, int *len) -+{ -+ if (!x->aux || !x->aux->keyid) -+ return NULL; -+ if (len) -+ *len = x->aux->keyid->length; -+ return x->aux->keyid->data; -+} -+ -+int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj) -+{ -+ X509_CERT_AUX *aux; -+ ASN1_OBJECT *objtmp = NULL; -+ if (obj) { -+ objtmp = OBJ_dup(obj); -+ if (!objtmp) -+ return 0; -+ } -+ if ((aux = aux_get(x)) == NULL) -+ goto err; -+ if (aux->trust == NULL -+ && (aux->trust = sk_ASN1_OBJECT_new_null()) == NULL) -+ goto err; -+ if (!objtmp || sk_ASN1_OBJECT_push(aux->trust, objtmp)) -+ return 1; -+ err: -+ ASN1_OBJECT_free(objtmp); -+ return 0; -+} -+ -+int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj) -+{ -+ X509_CERT_AUX *aux; -+ ASN1_OBJECT *objtmp; -+ if ((objtmp = OBJ_dup(obj)) == NULL) -+ return 0; -+ if ((aux = aux_get(x)) == NULL) -+ goto err; -+ if (aux->reject == NULL -+ && (aux->reject = sk_ASN1_OBJECT_new_null()) == NULL) -+ goto err; -+ return sk_ASN1_OBJECT_push(aux->reject, objtmp); -+ err: -+ ASN1_OBJECT_free(objtmp); -+ return 0; -+} -+ -+void X509_trust_clear(X509 *x) -+{ -+ if (x->aux) { -+ sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free); -+ x->aux->trust = NULL; -+ } -+} -+ -+void X509_reject_clear(X509 *x) -+{ -+ if (x->aux) { -+ sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free); -+ x->aux->reject = NULL; -+ } -+} -+ -+STACK_OF(ASN1_OBJECT) *X509_get0_trust_objects(X509 *x) -+{ -+ if (x->aux != NULL) -+ return x->aux->trust; -+ return NULL; -+} -+ -+STACK_OF(ASN1_OBJECT) *X509_get0_reject_objects(X509 *x) -+{ -+ if (x->aux != NULL) -+ return x->aux->reject; -+ return NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/build.info b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/build.info -new file mode 100644 -index 0000000..452a8b0 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/build.info -@@ -0,0 +1,8 @@ -+LIBS=../../libcrypto -+SOURCE[../../libcrypto]=\ -+ v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_lib.c \ -+ v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.c v3_pku.c \ -+ v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c v3_info.c \ -+ v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c v3_pcia.c v3_pci.c \ -+ pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \ -+ v3_asid.c v3_addr.c v3_tlsf.c -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/ext_dat.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/ext_dat.h -new file mode 100644 -index 0000000..c9ede96 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/ext_dat.h -@@ -0,0 +1,24 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+int name_cmp(const char *name, const char *cmp); -+ -+extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; -+extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; -+extern const X509V3_EXT_METHOD v3_ns_ia5_list[8], v3_alt[3], v3_skey_id, v3_akey_id; -+extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; -+extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; -+extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; -+extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; -+extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci; -+extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; -+extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; -+extern const X509V3_EXT_METHOD v3_addr, v3_asid; -+extern const X509V3_EXT_METHOD v3_ct_scts[3]; -+extern const X509V3_EXT_METHOD v3_tls_feature; -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_cache.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_cache.c -new file mode 100644 -index 0000000..a9ee30a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_cache.c -@@ -0,0 +1,216 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "internal/cryptlib.h" -+#include -+#include -+#include "internal/x509_int.h" -+ -+#include "pcy_int.h" -+ -+static int policy_data_cmp(const X509_POLICY_DATA *const *a, -+ const X509_POLICY_DATA *const *b); -+static int policy_cache_set_int(long *out, ASN1_INTEGER *value); -+ -+/* -+ * Set cache entry according to CertificatePolicies extension. Note: this -+ * destroys the passed CERTIFICATEPOLICIES structure. -+ */ -+ -+static int policy_cache_create(X509 *x, -+ CERTIFICATEPOLICIES *policies, int crit) -+{ -+ int i; -+ int ret = 0; -+ X509_POLICY_CACHE *cache = x->policy_cache; -+ X509_POLICY_DATA *data = NULL; -+ POLICYINFO *policy; -+ if (sk_POLICYINFO_num(policies) == 0) -+ goto bad_policy; -+ cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp); -+ if (cache->data == NULL) -+ goto bad_policy; -+ for (i = 0; i < sk_POLICYINFO_num(policies); i++) { -+ policy = sk_POLICYINFO_value(policies, i); -+ data = policy_data_new(policy, NULL, crit); -+ if (data == NULL) -+ goto bad_policy; -+ /* -+ * Duplicate policy OIDs are illegal: reject if matches found. -+ */ -+ if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { -+ if (cache->anyPolicy) { -+ ret = -1; -+ goto bad_policy; -+ } -+ cache->anyPolicy = data; -+ } else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) { -+ ret = -1; -+ goto bad_policy; -+ } else if (!sk_X509_POLICY_DATA_push(cache->data, data)) -+ goto bad_policy; -+ data = NULL; -+ } -+ ret = 1; -+ bad_policy: -+ if (ret == -1) -+ x->ex_flags |= EXFLAG_INVALID_POLICY; -+ policy_data_free(data); -+ sk_POLICYINFO_pop_free(policies, POLICYINFO_free); -+ if (ret <= 0) { -+ sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); -+ cache->data = NULL; -+ } -+ return ret; -+} -+ -+static int policy_cache_new(X509 *x) -+{ -+ X509_POLICY_CACHE *cache; -+ ASN1_INTEGER *ext_any = NULL; -+ POLICY_CONSTRAINTS *ext_pcons = NULL; -+ CERTIFICATEPOLICIES *ext_cpols = NULL; -+ POLICY_MAPPINGS *ext_pmaps = NULL; -+ int i; -+ -+ if (x->policy_cache != NULL) -+ return 1; -+ cache = OPENSSL_malloc(sizeof(*cache)); -+ if (cache == NULL) -+ return 0; -+ cache->anyPolicy = NULL; -+ cache->data = NULL; -+ cache->any_skip = -1; -+ cache->explicit_skip = -1; -+ cache->map_skip = -1; -+ -+ x->policy_cache = cache; -+ -+ /* -+ * Handle requireExplicitPolicy *first*. Need to process this even if we -+ * don't have any policies. -+ */ -+ ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL); -+ -+ if (!ext_pcons) { -+ if (i != -1) -+ goto bad_cache; -+ } else { -+ if (!ext_pcons->requireExplicitPolicy -+ && !ext_pcons->inhibitPolicyMapping) -+ goto bad_cache; -+ if (!policy_cache_set_int(&cache->explicit_skip, -+ ext_pcons->requireExplicitPolicy)) -+ goto bad_cache; -+ if (!policy_cache_set_int(&cache->map_skip, -+ ext_pcons->inhibitPolicyMapping)) -+ goto bad_cache; -+ } -+ -+ /* Process CertificatePolicies */ -+ -+ ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL); -+ /* -+ * If no CertificatePolicies extension or problem decoding then there is -+ * no point continuing because the valid policies will be NULL. -+ */ -+ if (!ext_cpols) { -+ /* If not absent some problem with extension */ -+ if (i != -1) -+ goto bad_cache; -+ return 1; -+ } -+ -+ i = policy_cache_create(x, ext_cpols, i); -+ -+ /* NB: ext_cpols freed by policy_cache_set_policies */ -+ -+ if (i <= 0) -+ return i; -+ -+ ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL); -+ -+ if (!ext_pmaps) { -+ /* If not absent some problem with extension */ -+ if (i != -1) -+ goto bad_cache; -+ } else { -+ i = policy_cache_set_mapping(x, ext_pmaps); -+ if (i <= 0) -+ goto bad_cache; -+ } -+ -+ ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL); -+ -+ if (!ext_any) { -+ if (i != -1) -+ goto bad_cache; -+ } else if (!policy_cache_set_int(&cache->any_skip, ext_any)) -+ goto bad_cache; -+ goto just_cleanup; -+ -+ bad_cache: -+ x->ex_flags |= EXFLAG_INVALID_POLICY; -+ -+ just_cleanup: -+ POLICY_CONSTRAINTS_free(ext_pcons); -+ ASN1_INTEGER_free(ext_any); -+ return 1; -+ -+} -+ -+void policy_cache_free(X509_POLICY_CACHE *cache) -+{ -+ if (!cache) -+ return; -+ policy_data_free(cache->anyPolicy); -+ sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); -+ OPENSSL_free(cache); -+} -+ -+const X509_POLICY_CACHE *policy_cache_set(X509 *x) -+{ -+ -+ if (x->policy_cache == NULL) { -+ CRYPTO_THREAD_write_lock(x->lock); -+ policy_cache_new(x); -+ CRYPTO_THREAD_unlock(x->lock); -+ } -+ -+ return x->policy_cache; -+ -+} -+ -+X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, -+ const ASN1_OBJECT *id) -+{ -+ int idx; -+ X509_POLICY_DATA tmp; -+ tmp.valid_policy = (ASN1_OBJECT *)id; -+ idx = sk_X509_POLICY_DATA_find(cache->data, &tmp); -+ if (idx == -1) -+ return NULL; -+ return sk_X509_POLICY_DATA_value(cache->data, idx); -+} -+ -+static int policy_data_cmp(const X509_POLICY_DATA *const *a, -+ const X509_POLICY_DATA *const *b) -+{ -+ return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy); -+} -+ -+static int policy_cache_set_int(long *out, ASN1_INTEGER *value) -+{ -+ if (value == NULL) -+ return 1; -+ if (value->type == V_ASN1_NEG_INTEGER) -+ return 0; -+ *out = ASN1_INTEGER_get(value); -+ return 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_data.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_data.c -new file mode 100644 -index 0000000..cf1d635 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_data.c -@@ -0,0 +1,77 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "internal/cryptlib.h" -+#include -+#include -+ -+#include "pcy_int.h" -+ -+/* Policy Node routines */ -+ -+void policy_data_free(X509_POLICY_DATA *data) -+{ -+ if (!data) -+ return; -+ ASN1_OBJECT_free(data->valid_policy); -+ /* Don't free qualifiers if shared */ -+ if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS)) -+ sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free); -+ sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free); -+ OPENSSL_free(data); -+} -+ -+/* -+ * Create a data based on an existing policy. If 'id' is NULL use the OID in -+ * the policy, otherwise use 'id'. This behaviour covers the two types of -+ * data in RFC3280: data with from a CertificatePolicies extension and -+ * additional data with just the qualifiers of anyPolicy and ID from another -+ * source. -+ */ -+ -+X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, -+ const ASN1_OBJECT *cid, int crit) -+{ -+ X509_POLICY_DATA *ret; -+ ASN1_OBJECT *id; -+ if (!policy && !cid) -+ return NULL; -+ if (cid) { -+ id = OBJ_dup(cid); -+ if (!id) -+ return NULL; -+ } else -+ id = NULL; -+ ret = OPENSSL_zalloc(sizeof(*ret)); -+ if (ret == NULL) -+ return NULL; -+ ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); -+ if (ret->expected_policy_set == NULL) { -+ OPENSSL_free(ret); -+ ASN1_OBJECT_free(id); -+ return NULL; -+ } -+ -+ if (crit) -+ ret->flags = POLICY_DATA_FLAG_CRITICAL; -+ -+ if (id) -+ ret->valid_policy = id; -+ else { -+ ret->valid_policy = policy->policyid; -+ policy->policyid = NULL; -+ } -+ -+ if (policy) { -+ ret->qualifier_set = policy->qualifiers; -+ policy->qualifiers = NULL; -+ } -+ -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_int.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_int.h -new file mode 100644 -index 0000000..5daf78d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_int.h -@@ -0,0 +1,167 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; -+ -+DEFINE_STACK_OF(X509_POLICY_DATA) -+ -+/* Internal structures */ -+ -+/* -+ * This structure and the field names correspond to the Policy 'node' of -+ * RFC3280. NB this structure contains no pointers to parent or child data: -+ * X509_POLICY_NODE contains that. This means that the main policy data can -+ * be kept static and cached with the certificate. -+ */ -+ -+struct X509_POLICY_DATA_st { -+ unsigned int flags; -+ /* Policy OID and qualifiers for this data */ -+ ASN1_OBJECT *valid_policy; -+ STACK_OF(POLICYQUALINFO) *qualifier_set; -+ STACK_OF(ASN1_OBJECT) *expected_policy_set; -+}; -+ -+/* X509_POLICY_DATA flags values */ -+ -+/* -+ * This flag indicates the structure has been mapped using a policy mapping -+ * extension. If policy mapping is not active its references get deleted. -+ */ -+ -+#define POLICY_DATA_FLAG_MAPPED 0x1 -+ -+/* -+ * This flag indicates the data doesn't correspond to a policy in Certificate -+ * Policies: it has been mapped to any policy. -+ */ -+ -+#define POLICY_DATA_FLAG_MAPPED_ANY 0x2 -+ -+/* AND with flags to see if any mapping has occurred */ -+ -+#define POLICY_DATA_FLAG_MAP_MASK 0x3 -+ -+/* qualifiers are shared and shouldn't be freed */ -+ -+#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4 -+ -+/* Parent node is an extra node and should be freed */ -+ -+#define POLICY_DATA_FLAG_EXTRA_NODE 0x8 -+ -+/* Corresponding CertificatePolicies is critical */ -+ -+#define POLICY_DATA_FLAG_CRITICAL 0x10 -+ -+/* This structure is cached with a certificate */ -+ -+struct X509_POLICY_CACHE_st { -+ /* anyPolicy data or NULL if no anyPolicy */ -+ X509_POLICY_DATA *anyPolicy; -+ /* other policy data */ -+ STACK_OF(X509_POLICY_DATA) *data; -+ /* If InhibitAnyPolicy present this is its value or -1 if absent. */ -+ long any_skip; -+ /* -+ * If policyConstraints and requireExplicitPolicy present this is its -+ * value or -1 if absent. -+ */ -+ long explicit_skip; -+ /* -+ * If policyConstraints and policyMapping present this is its value or -1 -+ * if absent. -+ */ -+ long map_skip; -+}; -+ -+/* -+ * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL -+ */ -+ -+/* This structure represents the relationship between nodes */ -+ -+struct X509_POLICY_NODE_st { -+ /* node data this refers to */ -+ const X509_POLICY_DATA *data; -+ /* Parent node */ -+ X509_POLICY_NODE *parent; -+ /* Number of child nodes */ -+ int nchild; -+}; -+ -+struct X509_POLICY_LEVEL_st { -+ /* Cert for this level */ -+ X509 *cert; -+ /* nodes at this level */ -+ STACK_OF(X509_POLICY_NODE) *nodes; -+ /* anyPolicy node */ -+ X509_POLICY_NODE *anyPolicy; -+ /* Extra data */ -+ /* -+ * STACK_OF(X509_POLICY_DATA) *extra_data; -+ */ -+ unsigned int flags; -+}; -+ -+struct X509_POLICY_TREE_st { -+ /* This is the tree 'level' data */ -+ X509_POLICY_LEVEL *levels; -+ int nlevel; -+ /* -+ * Extra policy data when additional nodes (not from the certificate) are -+ * required. -+ */ -+ STACK_OF(X509_POLICY_DATA) *extra_data; -+ /* This is the authority constrained policy set */ -+ STACK_OF(X509_POLICY_NODE) *auth_policies; -+ STACK_OF(X509_POLICY_NODE) *user_policies; -+ unsigned int flags; -+}; -+ -+/* Set if anyPolicy present in user policies */ -+#define POLICY_FLAG_ANY_POLICY 0x2 -+ -+/* Useful macros */ -+ -+#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL) -+#define node_critical(node) node_data_critical(node->data) -+ -+/* Internal functions */ -+ -+X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, -+ int crit); -+void policy_data_free(X509_POLICY_DATA *data); -+ -+X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, -+ const ASN1_OBJECT *id); -+int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps); -+ -+STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void); -+ -+void policy_cache_init(void); -+ -+void policy_cache_free(X509_POLICY_CACHE *cache); -+ -+X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, -+ const X509_POLICY_NODE *parent, -+ const ASN1_OBJECT *id); -+ -+X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, -+ const ASN1_OBJECT *id); -+ -+X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, -+ X509_POLICY_DATA *data, -+ X509_POLICY_NODE *parent, -+ X509_POLICY_TREE *tree); -+void policy_node_free(X509_POLICY_NODE *node); -+int policy_node_match(const X509_POLICY_LEVEL *lvl, -+ const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); -+ -+const X509_POLICY_CACHE *policy_cache_set(X509 *x); -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_lib.c -new file mode 100644 -index 0000000..67f7eaf ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_lib.c -@@ -0,0 +1,108 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "internal/cryptlib.h" -+#include -+#include -+ -+#include "pcy_int.h" -+ -+/* accessor functions */ -+ -+/* X509_POLICY_TREE stuff */ -+ -+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree) -+{ -+ if (!tree) -+ return 0; -+ return tree->nlevel; -+} -+ -+X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, -+ int i) -+{ -+ if (!tree || (i < 0) || (i >= tree->nlevel)) -+ return NULL; -+ return tree->levels + i; -+} -+ -+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const -+ X509_POLICY_TREE -+ *tree) -+{ -+ if (!tree) -+ return NULL; -+ return tree->auth_policies; -+} -+ -+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const -+ X509_POLICY_TREE -+ *tree) -+{ -+ if (!tree) -+ return NULL; -+ if (tree->flags & POLICY_FLAG_ANY_POLICY) -+ return tree->auth_policies; -+ else -+ return tree->user_policies; -+} -+ -+/* X509_POLICY_LEVEL stuff */ -+ -+int X509_policy_level_node_count(X509_POLICY_LEVEL *level) -+{ -+ int n; -+ if (!level) -+ return 0; -+ if (level->anyPolicy) -+ n = 1; -+ else -+ n = 0; -+ if (level->nodes) -+ n += sk_X509_POLICY_NODE_num(level->nodes); -+ return n; -+} -+ -+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i) -+{ -+ if (!level) -+ return NULL; -+ if (level->anyPolicy) { -+ if (i == 0) -+ return level->anyPolicy; -+ i--; -+ } -+ return sk_X509_POLICY_NODE_value(level->nodes, i); -+} -+ -+/* X509_POLICY_NODE stuff */ -+ -+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node) -+{ -+ if (!node) -+ return NULL; -+ return node->data->valid_policy; -+} -+ -+STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const -+ X509_POLICY_NODE -+ *node) -+{ -+ if (!node) -+ return NULL; -+ return node->data->qualifier_set; -+} -+ -+const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE -+ *node) -+{ -+ if (!node) -+ return NULL; -+ return node->parent; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_map.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_map.c -new file mode 100644 -index 0000000..ab9dd21 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_map.c -@@ -0,0 +1,81 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "internal/cryptlib.h" -+#include -+#include -+#include "internal/x509_int.h" -+ -+#include "pcy_int.h" -+ -+/* -+ * Set policy mapping entries in cache. Note: this modifies the passed -+ * POLICY_MAPPINGS structure -+ */ -+ -+int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) -+{ -+ POLICY_MAPPING *map; -+ X509_POLICY_DATA *data; -+ X509_POLICY_CACHE *cache = x->policy_cache; -+ int i; -+ int ret = 0; -+ if (sk_POLICY_MAPPING_num(maps) == 0) { -+ ret = -1; -+ goto bad_mapping; -+ } -+ for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) { -+ map = sk_POLICY_MAPPING_value(maps, i); -+ /* Reject if map to or from anyPolicy */ -+ if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) -+ || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) { -+ ret = -1; -+ goto bad_mapping; -+ } -+ -+ /* Attempt to find matching policy data */ -+ data = policy_cache_find_data(cache, map->issuerDomainPolicy); -+ /* If we don't have anyPolicy can't map */ -+ if (data == NULL && !cache->anyPolicy) -+ continue; -+ -+ /* Create a NODE from anyPolicy */ -+ if (data == NULL) { -+ data = policy_data_new(NULL, map->issuerDomainPolicy, -+ cache->anyPolicy->flags -+ & POLICY_DATA_FLAG_CRITICAL); -+ if (data == NULL) -+ goto bad_mapping; -+ data->qualifier_set = cache->anyPolicy->qualifier_set; -+ /* -+ * map->issuerDomainPolicy = NULL; -+ */ -+ data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; -+ data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; -+ if (!sk_X509_POLICY_DATA_push(cache->data, data)) { -+ policy_data_free(data); -+ goto bad_mapping; -+ } -+ } else -+ data->flags |= POLICY_DATA_FLAG_MAPPED; -+ if (!sk_ASN1_OBJECT_push(data->expected_policy_set, -+ map->subjectDomainPolicy)) -+ goto bad_mapping; -+ map->subjectDomainPolicy = NULL; -+ -+ } -+ -+ ret = 1; -+ bad_mapping: -+ if (ret == -1) -+ x->ex_flags |= EXFLAG_INVALID_POLICY; -+ sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); -+ return ret; -+ -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c -new file mode 100644 -index 0000000..80443bf ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c -@@ -0,0 +1,139 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+ -+#include "pcy_int.h" -+ -+static int node_cmp(const X509_POLICY_NODE *const *a, -+ const X509_POLICY_NODE *const *b) -+{ -+ return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy); -+} -+ -+STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) -+{ -+ return sk_X509_POLICY_NODE_new(node_cmp); -+} -+ -+X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, -+ const ASN1_OBJECT *id) -+{ -+ X509_POLICY_DATA n; -+ X509_POLICY_NODE l; -+ int idx; -+ -+ n.valid_policy = (ASN1_OBJECT *)id; -+ l.data = &n; -+ -+ idx = sk_X509_POLICY_NODE_find(nodes, &l); -+ if (idx == -1) -+ return NULL; -+ -+ return sk_X509_POLICY_NODE_value(nodes, idx); -+ -+} -+ -+X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, -+ const X509_POLICY_NODE *parent, -+ const ASN1_OBJECT *id) -+{ -+ X509_POLICY_NODE *node; -+ int i; -+ for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { -+ node = sk_X509_POLICY_NODE_value(level->nodes, i); -+ if (node->parent == parent) { -+ if (!OBJ_cmp(node->data->valid_policy, id)) -+ return node; -+ } -+ } -+ return NULL; -+} -+ -+X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, -+ X509_POLICY_DATA *data, -+ X509_POLICY_NODE *parent, -+ X509_POLICY_TREE *tree) -+{ -+ X509_POLICY_NODE *node; -+ -+ node = OPENSSL_zalloc(sizeof(*node)); -+ if (node == NULL) -+ return NULL; -+ node->data = data; -+ node->parent = parent; -+ if (level) { -+ if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { -+ if (level->anyPolicy) -+ goto node_error; -+ level->anyPolicy = node; -+ } else { -+ -+ if (level->nodes == NULL) -+ level->nodes = policy_node_cmp_new(); -+ if (level->nodes == NULL) -+ goto node_error; -+ if (!sk_X509_POLICY_NODE_push(level->nodes, node)) -+ goto node_error; -+ } -+ } -+ -+ if (tree) { -+ if (tree->extra_data == NULL) -+ tree->extra_data = sk_X509_POLICY_DATA_new_null(); -+ if (tree->extra_data == NULL) -+ goto node_error; -+ if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) -+ goto node_error; -+ } -+ -+ if (parent) -+ parent->nchild++; -+ -+ return node; -+ -+ node_error: -+ policy_node_free(node); -+ return NULL; -+} -+ -+void policy_node_free(X509_POLICY_NODE *node) -+{ -+ OPENSSL_free(node); -+} -+ -+/* -+ * See if a policy node matches a policy OID. If mapping enabled look through -+ * expected policy set otherwise just valid policy. -+ */ -+ -+int policy_node_match(const X509_POLICY_LEVEL *lvl, -+ const X509_POLICY_NODE *node, const ASN1_OBJECT *oid) -+{ -+ int i; -+ ASN1_OBJECT *policy_oid; -+ const X509_POLICY_DATA *x = node->data; -+ -+ if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP) -+ || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) { -+ if (!OBJ_cmp(x->valid_policy, oid)) -+ return 1; -+ return 0; -+ } -+ -+ for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) { -+ policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i); -+ if (!OBJ_cmp(policy_oid, oid)) -+ return 1; -+ } -+ return 0; -+ -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c -new file mode 100644 -index 0000000..9f9246b ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c -@@ -0,0 +1,696 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "internal/cryptlib.h" -+#include -+#include -+ -+#include "pcy_int.h" -+ -+/* -+ * Enable this to print out the complete policy tree at various point during -+ * evaluation. -+ */ -+ -+/* -+ * #define OPENSSL_POLICY_DEBUG -+ */ -+ -+#ifdef OPENSSL_POLICY_DEBUG -+ -+static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, -+ X509_POLICY_NODE *node, int indent) -+{ -+ if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) -+ || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) -+ BIO_puts(err, " Not Mapped\n"); -+ else { -+ int i; -+ STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; -+ ASN1_OBJECT *oid; -+ BIO_puts(err, " Expected: "); -+ for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) { -+ oid = sk_ASN1_OBJECT_value(pset, i); -+ if (i) -+ BIO_puts(err, ", "); -+ i2a_ASN1_OBJECT(err, oid); -+ } -+ BIO_puts(err, "\n"); -+ } -+} -+ -+static void tree_print(char *str, X509_POLICY_TREE *tree, -+ X509_POLICY_LEVEL *curr) -+{ -+ BIO *err = BIO_new_fp(stderr, BIO_NOCLOSE); -+ X509_POLICY_LEVEL *plev; -+ -+ if (err == NULL) -+ return; -+ if (!curr) -+ curr = tree->levels + tree->nlevel; -+ else -+ curr++; -+ -+ BIO_printf(err, "Level print after %s\n", str); -+ BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); -+ for (plev = tree->levels; plev != curr; plev++) { -+ int i; -+ -+ BIO_printf(err, "Level %ld, flags = %x\n", -+ (long)(plev - tree->levels), plev->flags); -+ for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) { -+ X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(plev->nodes, i); -+ -+ X509_POLICY_NODE_print(err, node, 2); -+ expected_print(err, plev, node, 2); -+ BIO_printf(err, " Flags: %x\n", node->data->flags); -+ } -+ if (plev->anyPolicy) -+ X509_POLICY_NODE_print(err, plev->anyPolicy, 2); -+ } -+ BIO_free(err); -+} -+#endif -+ -+/*- -+ * Return value: <= 0 on error, or positive bit mask: -+ * -+ * X509_PCY_TREE_VALID: valid tree -+ * X509_PCY_TREE_EMPTY: empty tree (including bare TA case) -+ * X509_PCY_TREE_EXPLICIT: explicit policy required -+ */ -+static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, -+ unsigned int flags) -+{ -+ X509_POLICY_TREE *tree; -+ X509_POLICY_LEVEL *level; -+ const X509_POLICY_CACHE *cache; -+ X509_POLICY_DATA *data = NULL; -+ int ret = X509_PCY_TREE_VALID; -+ int n = sk_X509_num(certs) - 1; /* RFC5280 paths omit the TA */ -+ int explicit_policy = (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : n+1; -+ int any_skip = (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : n+1; -+ int map_skip = (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : n+1; -+ int i; -+ -+ *ptree = NULL; -+ -+ /* Can't do anything with just a trust anchor */ -+ if (n == 0) -+ return X509_PCY_TREE_EMPTY; -+ -+ /* -+ * First setup the policy cache in all n non-TA certificates, this will be -+ * used in X509_verify_cert() which will invoke the verify callback for all -+ * certificates with invalid policy extensions. -+ */ -+ for (i = n - 1; i >= 0; i--) { -+ X509 *x = sk_X509_value(certs, i); -+ -+ /* Call for side-effect of computing hash and caching extensions */ -+ X509_check_purpose(x, -1, 0); -+ -+ /* If cache is NULL, likely ENOMEM: return immediately */ -+ if (policy_cache_set(x) == NULL) -+ return X509_PCY_TREE_INTERNAL; -+ } -+ -+ /* -+ * At this point check for invalid policies and required explicit policy. -+ * Note that the explicit_policy counter is a count-down to zero, with the -+ * requirement kicking in if and once it does that. The counter is -+ * decremented for every non-self-issued certificate in the path, but may -+ * be further reduced by policy constraints in a non-leaf certificate. -+ * -+ * The ultimate policy set is the intersection of all the policies along -+ * the path, if we hit a certificate with an empty policy set, and explicit -+ * policy is required we're done. -+ */ -+ for (i = n - 1; -+ i >= 0 && (explicit_policy > 0 || (ret & X509_PCY_TREE_EMPTY) == 0); -+ i--) { -+ X509 *x = sk_X509_value(certs, i); -+ uint32_t ex_flags = X509_get_extension_flags(x); -+ -+ /* All the policies are already cached, we can return early */ -+ if (ex_flags & EXFLAG_INVALID_POLICY) -+ return X509_PCY_TREE_INVALID; -+ -+ /* Access the cache which we now know exists */ -+ cache = policy_cache_set(x); -+ -+ if ((ret & X509_PCY_TREE_VALID) && cache->data == NULL) -+ ret = X509_PCY_TREE_EMPTY; -+ if (explicit_policy > 0) { -+ if (!(ex_flags & EXFLAG_SI)) -+ explicit_policy--; -+ if ((cache->explicit_skip >= 0) -+ && (cache->explicit_skip < explicit_policy)) -+ explicit_policy = cache->explicit_skip; -+ } -+ } -+ -+ if (explicit_policy == 0) -+ ret |= X509_PCY_TREE_EXPLICIT; -+ if ((ret & X509_PCY_TREE_VALID) == 0) -+ return ret; -+ -+ /* If we get this far initialize the tree */ -+ if ((tree = OPENSSL_zalloc(sizeof(*tree))) == NULL) -+ return X509_PCY_TREE_INTERNAL; -+ -+ /* -+ * http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3. -+ * -+ * The top level is implicitly for the trust anchor with valid expected -+ * policies of anyPolicy. (RFC 5280 has the TA at depth 0 and the leaf at -+ * depth n, we have the leaf at depth 0 and the TA at depth n). -+ */ -+ if ((tree->levels = OPENSSL_zalloc(sizeof(*tree->levels)*(n+1))) == NULL) { -+ OPENSSL_free(tree); -+ return X509_PCY_TREE_INTERNAL; -+ } -+ tree->nlevel = n+1; -+ level = tree->levels; -+ if ((data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0)) == NULL) -+ goto bad_tree; -+ if (level_add_node(level, data, NULL, tree) == NULL) { -+ policy_data_free(data); -+ goto bad_tree; -+ } -+ -+ /* -+ * In this pass initialize all the tree levels and whether anyPolicy and -+ * policy mapping are inhibited at each level. -+ */ -+ for (i = n - 1; i >= 0; i--) { -+ X509 *x = sk_X509_value(certs, i); -+ uint32_t ex_flags = X509_get_extension_flags(x); -+ -+ /* Access the cache which we now know exists */ -+ cache = policy_cache_set(x); -+ -+ X509_up_ref(x); -+ (++level)->cert = x; -+ -+ if (!cache->anyPolicy) -+ level->flags |= X509_V_FLAG_INHIBIT_ANY; -+ -+ /* Determine inhibit any and inhibit map flags */ -+ if (any_skip == 0) { -+ /* -+ * Any matching allowed only if certificate is self issued and not -+ * the last in the chain. -+ */ -+ if (!(ex_flags & EXFLAG_SI) || (i == 0)) -+ level->flags |= X509_V_FLAG_INHIBIT_ANY; -+ } else { -+ if (!(ex_flags & EXFLAG_SI)) -+ any_skip--; -+ if ((cache->any_skip >= 0) && (cache->any_skip < any_skip)) -+ any_skip = cache->any_skip; -+ } -+ -+ if (map_skip == 0) -+ level->flags |= X509_V_FLAG_INHIBIT_MAP; -+ else { -+ if (!(ex_flags & EXFLAG_SI)) -+ map_skip--; -+ if ((cache->map_skip >= 0) && (cache->map_skip < map_skip)) -+ map_skip = cache->map_skip; -+ } -+ } -+ -+ *ptree = tree; -+ return ret; -+ -+ bad_tree: -+ X509_policy_tree_free(tree); -+ return X509_PCY_TREE_INTERNAL; -+} -+ -+/* -+ * Return value: 1 on success, 0 otherwise -+ */ -+static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, -+ X509_POLICY_DATA *data) -+{ -+ X509_POLICY_LEVEL *last = curr - 1; -+ int i, matched = 0; -+ -+ /* Iterate through all in nodes linking matches */ -+ for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { -+ X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i); -+ -+ if (policy_node_match(last, node, data->valid_policy)) { -+ if (level_add_node(curr, data, node, NULL) == NULL) -+ return 0; -+ matched = 1; -+ } -+ } -+ if (!matched && last->anyPolicy) { -+ if (level_add_node(curr, data, last->anyPolicy, NULL) == NULL) -+ return 0; -+ } -+ return 1; -+} -+ -+/* -+ * This corresponds to RFC3280 6.1.3(d)(1): link any data from -+ * CertificatePolicies onto matching parent or anyPolicy if no match. -+ * -+ * Return value: 1 on success, 0 otherwise. -+ */ -+static int tree_link_nodes(X509_POLICY_LEVEL *curr, -+ const X509_POLICY_CACHE *cache) -+{ -+ int i; -+ -+ for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) { -+ X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i); -+ -+ /* Look for matching nodes in previous level */ -+ if (!tree_link_matching_nodes(curr, data)) -+ return 0; -+ } -+ return 1; -+} -+ -+/* -+ * This corresponds to RFC3280 6.1.3(d)(2): Create new data for any unmatched -+ * policies in the parent and link to anyPolicy. -+ * -+ * Return value: 1 on success, 0 otherwise. -+ */ -+static int tree_add_unmatched(X509_POLICY_LEVEL *curr, -+ const X509_POLICY_CACHE *cache, -+ const ASN1_OBJECT *id, -+ X509_POLICY_NODE *node, X509_POLICY_TREE *tree) -+{ -+ X509_POLICY_DATA *data; -+ -+ if (id == NULL) -+ id = node->data->valid_policy; -+ /* -+ * Create a new node with qualifiers from anyPolicy and id from unmatched -+ * node. -+ */ -+ if ((data = policy_data_new(NULL, id, node_critical(node))) == NULL) -+ return 0; -+ -+ /* Curr may not have anyPolicy */ -+ data->qualifier_set = cache->anyPolicy->qualifier_set; -+ data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; -+ if (level_add_node(curr, data, node, tree) == NULL) { -+ policy_data_free(data); -+ return 0; -+ } -+ return 1; -+} -+ -+/* -+ * Return value: 1 on success, 0 otherwise. -+ */ -+static int tree_link_unmatched(X509_POLICY_LEVEL *curr, -+ const X509_POLICY_CACHE *cache, -+ X509_POLICY_NODE *node, X509_POLICY_TREE *tree) -+{ -+ const X509_POLICY_LEVEL *last = curr - 1; -+ int i; -+ -+ if ((last->flags & X509_V_FLAG_INHIBIT_MAP) -+ || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) { -+ /* If no policy mapping: matched if one child present */ -+ if (node->nchild) -+ return 1; -+ if (!tree_add_unmatched(curr, cache, NULL, node, tree)) -+ return 0; -+ /* Add it */ -+ } else { -+ /* If mapping: matched if one child per expected policy set */ -+ STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; -+ if (node->nchild == sk_ASN1_OBJECT_num(expset)) -+ return 1; -+ /* Locate unmatched nodes */ -+ for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) { -+ ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); -+ if (level_find_node(curr, node, oid)) -+ continue; -+ if (!tree_add_unmatched(curr, cache, oid, node, tree)) -+ return 0; -+ } -+ -+ } -+ return 1; -+} -+ -+/* -+ * Return value: 1 on success, 0 otherwise -+ */ -+static int tree_link_any(X509_POLICY_LEVEL *curr, -+ const X509_POLICY_CACHE *cache, -+ X509_POLICY_TREE *tree) -+{ -+ int i; -+ X509_POLICY_NODE *node; -+ X509_POLICY_LEVEL *last = curr - 1; -+ -+ for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { -+ node = sk_X509_POLICY_NODE_value(last->nodes, i); -+ -+ if (!tree_link_unmatched(curr, cache, node, tree)) -+ return 0; -+ } -+ /* Finally add link to anyPolicy */ -+ if (last->anyPolicy && -+ level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL) == NULL) -+ return 0; -+ return 1; -+} -+ -+/*- -+ * Prune the tree: delete any child mapped child data on the current level then -+ * proceed up the tree deleting any data with no children. If we ever have no -+ * data on a level we can halt because the tree will be empty. -+ * -+ * Return value: <= 0 error, otherwise one of: -+ * -+ * X509_PCY_TREE_VALID: valid tree -+ * X509_PCY_TREE_EMPTY: empty tree -+ */ -+static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) -+{ -+ STACK_OF(X509_POLICY_NODE) *nodes; -+ X509_POLICY_NODE *node; -+ int i; -+ nodes = curr->nodes; -+ if (curr->flags & X509_V_FLAG_INHIBIT_MAP) { -+ for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { -+ node = sk_X509_POLICY_NODE_value(nodes, i); -+ /* Delete any mapped data: see RFC3280 XXXX */ -+ if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) { -+ node->parent->nchild--; -+ OPENSSL_free(node); -+ (void)sk_X509_POLICY_NODE_delete(nodes, i); -+ } -+ } -+ } -+ -+ for (;;) { -+ --curr; -+ nodes = curr->nodes; -+ for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { -+ node = sk_X509_POLICY_NODE_value(nodes, i); -+ if (node->nchild == 0) { -+ node->parent->nchild--; -+ OPENSSL_free(node); -+ (void)sk_X509_POLICY_NODE_delete(nodes, i); -+ } -+ } -+ if (curr->anyPolicy && !curr->anyPolicy->nchild) { -+ if (curr->anyPolicy->parent) -+ curr->anyPolicy->parent->nchild--; -+ OPENSSL_free(curr->anyPolicy); -+ curr->anyPolicy = NULL; -+ } -+ if (curr == tree->levels) { -+ /* If we zapped anyPolicy at top then tree is empty */ -+ if (!curr->anyPolicy) -+ return X509_PCY_TREE_EMPTY; -+ break; -+ } -+ } -+ return X509_PCY_TREE_VALID; -+} -+ -+/* -+ * Return value: 1 on success, 0 otherwise. -+ */ -+static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, -+ X509_POLICY_NODE *pcy) -+{ -+ if (*pnodes == NULL && -+ (*pnodes = policy_node_cmp_new()) == NULL) -+ return 0; -+ if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1) -+ return 1; -+ return sk_X509_POLICY_NODE_push(*pnodes, pcy) != 0; -+} -+ -+#define TREE_CALC_FAILURE 0 -+#define TREE_CALC_OK_NOFREE 1 -+#define TREE_CALC_OK_DOFREE 2 -+ -+/*- -+ * Calculate the authority set based on policy tree. The 'pnodes' parameter is -+ * used as a store for the set of policy nodes used to calculate the user set. -+ * If the authority set is not anyPolicy then pnodes will just point to the -+ * authority set. If however the authority set is anyPolicy then the set of -+ * valid policies (other than anyPolicy) is store in pnodes. -+ * -+ * Return value: -+ * TREE_CALC_FAILURE on failure, -+ * TREE_CALC_OK_NOFREE on success and pnodes need not be freed, -+ * TREE_CALC_OK_DOFREE on success and pnodes needs to be freed -+ */ -+static int tree_calculate_authority_set(X509_POLICY_TREE *tree, -+ STACK_OF(X509_POLICY_NODE) **pnodes) -+{ -+ X509_POLICY_LEVEL *curr; -+ X509_POLICY_NODE *node, *anyptr; -+ STACK_OF(X509_POLICY_NODE) **addnodes; -+ int i, j; -+ curr = tree->levels + tree->nlevel - 1; -+ -+ /* If last level contains anyPolicy set is anyPolicy */ -+ if (curr->anyPolicy) { -+ if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) -+ return TREE_CALC_FAILURE; -+ addnodes = pnodes; -+ } else -+ /* Add policies to authority set */ -+ addnodes = &tree->auth_policies; -+ -+ curr = tree->levels; -+ for (i = 1; i < tree->nlevel; i++) { -+ /* -+ * If no anyPolicy node on this this level it can't appear on lower -+ * levels so end search. -+ */ -+ if ((anyptr = curr->anyPolicy) == NULL) -+ break; -+ curr++; -+ for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) { -+ node = sk_X509_POLICY_NODE_value(curr->nodes, j); -+ if ((node->parent == anyptr) -+ && !tree_add_auth_node(addnodes, node)) { -+ if (addnodes == pnodes) { -+ sk_X509_POLICY_NODE_free(*pnodes); -+ *pnodes = NULL; -+ } -+ return TREE_CALC_FAILURE; -+ } -+ } -+ } -+ if (addnodes == pnodes) -+ return TREE_CALC_OK_DOFREE; -+ -+ *pnodes = tree->auth_policies; -+ return TREE_CALC_OK_NOFREE; -+} -+ -+/* -+ * Return value: 1 on success, 0 otherwise. -+ */ -+static int tree_calculate_user_set(X509_POLICY_TREE *tree, -+ STACK_OF(ASN1_OBJECT) *policy_oids, -+ STACK_OF(X509_POLICY_NODE) *auth_nodes) -+{ -+ int i; -+ X509_POLICY_NODE *node; -+ ASN1_OBJECT *oid; -+ X509_POLICY_NODE *anyPolicy; -+ X509_POLICY_DATA *extra; -+ -+ /* -+ * Check if anyPolicy present in authority constrained policy set: this -+ * will happen if it is a leaf node. -+ */ -+ if (sk_ASN1_OBJECT_num(policy_oids) <= 0) -+ return 1; -+ -+ anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; -+ -+ for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { -+ oid = sk_ASN1_OBJECT_value(policy_oids, i); -+ if (OBJ_obj2nid(oid) == NID_any_policy) { -+ tree->flags |= POLICY_FLAG_ANY_POLICY; -+ return 1; -+ } -+ } -+ -+ for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { -+ oid = sk_ASN1_OBJECT_value(policy_oids, i); -+ node = tree_find_sk(auth_nodes, oid); -+ if (!node) { -+ if (!anyPolicy) -+ continue; -+ /* -+ * Create a new node with policy ID from user set and qualifiers -+ * from anyPolicy. -+ */ -+ extra = policy_data_new(NULL, oid, node_critical(anyPolicy)); -+ if (extra == NULL) -+ return 0; -+ extra->qualifier_set = anyPolicy->data->qualifier_set; -+ extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS -+ | POLICY_DATA_FLAG_EXTRA_NODE; -+ node = level_add_node(NULL, extra, anyPolicy->parent, tree); -+ } -+ if (!tree->user_policies) { -+ tree->user_policies = sk_X509_POLICY_NODE_new_null(); -+ if (!tree->user_policies) -+ return 1; -+ } -+ if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) -+ return 0; -+ } -+ return 1; -+} -+ -+/*- -+ * Return value: <= 0 error, otherwise one of: -+ * X509_PCY_TREE_VALID: valid tree -+ * X509_PCY_TREE_EMPTY: empty tree -+ * (see tree_prune()). -+ */ -+static int tree_evaluate(X509_POLICY_TREE *tree) -+{ -+ int ret, i; -+ X509_POLICY_LEVEL *curr = tree->levels + 1; -+ const X509_POLICY_CACHE *cache; -+ -+ for (i = 1; i < tree->nlevel; i++, curr++) { -+ cache = policy_cache_set(curr->cert); -+ if (!tree_link_nodes(curr, cache)) -+ return X509_PCY_TREE_INTERNAL; -+ -+ if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) -+ && !tree_link_any(curr, cache, tree)) -+ return X509_PCY_TREE_INTERNAL; -+#ifdef OPENSSL_POLICY_DEBUG -+ tree_print("before tree_prune()", tree, curr); -+#endif -+ ret = tree_prune(tree, curr); -+ if (ret != X509_PCY_TREE_VALID) -+ return ret; -+ } -+ return X509_PCY_TREE_VALID; -+} -+ -+static void exnode_free(X509_POLICY_NODE *node) -+{ -+ if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) -+ OPENSSL_free(node); -+} -+ -+void X509_policy_tree_free(X509_POLICY_TREE *tree) -+{ -+ X509_POLICY_LEVEL *curr; -+ int i; -+ -+ if (!tree) -+ return; -+ -+ sk_X509_POLICY_NODE_free(tree->auth_policies); -+ sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); -+ -+ for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) { -+ X509_free(curr->cert); -+ sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free); -+ policy_node_free(curr->anyPolicy); -+ } -+ -+ sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free); -+ OPENSSL_free(tree->levels); -+ OPENSSL_free(tree); -+ -+} -+ -+/*- -+ * Application policy checking function. -+ * Return codes: -+ * X509_PCY_TREE_FAILURE: Failure to satisfy explicit policy -+ * X509_PCY_TREE_INVALID: Inconsistent or invalid extensions -+ * X509_PCY_TREE_INTERNAL: Internal error, most likely malloc -+ * X509_PCY_TREE_VALID: Success (null tree if empty or bare TA) -+ */ -+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, -+ STACK_OF(X509) *certs, -+ STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags) -+{ -+ int init_ret; -+ int ret; -+ X509_POLICY_TREE *tree = NULL; -+ STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; -+ -+ *ptree = NULL; -+ *pexplicit_policy = 0; -+ init_ret = tree_init(&tree, certs, flags); -+ -+ if (init_ret <= 0) -+ return init_ret; -+ -+ if ((init_ret & X509_PCY_TREE_EXPLICIT) == 0) { -+ if (init_ret & X509_PCY_TREE_EMPTY) { -+ X509_policy_tree_free(tree); -+ return X509_PCY_TREE_VALID; -+ } -+ } else { -+ *pexplicit_policy = 1; -+ /* Tree empty and requireExplicit True: Error */ -+ if (init_ret & X509_PCY_TREE_EMPTY) -+ return X509_PCY_TREE_FAILURE; -+ } -+ -+ ret = tree_evaluate(tree); -+#ifdef OPENSSL_POLICY_DEBUG -+ tree_print("tree_evaluate()", tree, NULL); -+#endif -+ if (ret <= 0) -+ goto error; -+ -+ if (ret == X509_PCY_TREE_EMPTY) { -+ X509_policy_tree_free(tree); -+ if (init_ret & X509_PCY_TREE_EXPLICIT) -+ return X509_PCY_TREE_FAILURE; -+ return X509_PCY_TREE_VALID; -+ } -+ -+ /* Tree is not empty: continue */ -+ if ((ret = tree_calculate_authority_set(tree, &auth_nodes)) == 0 || -+ !tree_calculate_user_set(tree, policy_oids, auth_nodes)) -+ goto error; -+ if (ret == TREE_CALC_OK_DOFREE) -+ sk_X509_POLICY_NODE_free(auth_nodes); -+ -+ *ptree = tree; -+ -+ if (init_ret & X509_PCY_TREE_EXPLICIT) { -+ nodes = X509_policy_tree_get0_user_policies(tree); -+ if (sk_X509_POLICY_NODE_num(nodes) <= 0) -+ return X509_PCY_TREE_FAILURE; -+ } -+ return X509_PCY_TREE_VALID; -+ -+ error: -+ X509_policy_tree_free(tree); -+ return X509_PCY_TREE_INTERNAL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/tabtest.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/tabtest.c -new file mode 100644 -index 0000000..a33a63a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/tabtest.c -@@ -0,0 +1,42 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * Simple program to check the ext_dat.h is correct and print out problems if -+ * it is not. -+ */ -+ -+#include -+ -+#include -+ -+#include "ext_dat.h" -+ -+main() -+{ -+ int i, prev = -1, bad = 0; -+ X509V3_EXT_METHOD **tmp; -+ i = OSSL_NELEM(standard_exts); -+ if (i != STANDARD_EXTENSION_COUNT) -+ fprintf(stderr, "Extension number invalid expecting %d\n", i); -+ tmp = standard_exts; -+ for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) { -+ if ((*tmp)->ext_nid < prev) -+ bad = 1; -+ prev = (*tmp)->ext_nid; -+ -+ } -+ if (bad) { -+ tmp = standard_exts; -+ fprintf(stderr, "Extensions out of order!\n"); -+ for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) -+ printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid)); -+ } else -+ fprintf(stderr, "Order OK\n"); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_addr.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_addr.c -new file mode 100644 -index 0000000..ef1d775 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_addr.c -@@ -0,0 +1,1305 @@ -+/* -+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * Implementation of RFC 3779 section 2.2. -+ */ -+ -+#include -+#include -+ -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+#include "ext_dat.h" -+ -+#ifndef OPENSSL_NO_RFC3779 -+ -+/* -+ * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. -+ */ -+ -+ASN1_SEQUENCE(IPAddressRange) = { -+ ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING), -+ ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING) -+} ASN1_SEQUENCE_END(IPAddressRange) -+ -+ASN1_CHOICE(IPAddressOrRange) = { -+ ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING), -+ ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange) -+} ASN1_CHOICE_END(IPAddressOrRange) -+ -+ASN1_CHOICE(IPAddressChoice) = { -+ ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL), -+ ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange) -+} ASN1_CHOICE_END(IPAddressChoice) -+ -+ASN1_SEQUENCE(IPAddressFamily) = { -+ ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING), -+ ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice) -+} ASN1_SEQUENCE_END(IPAddressFamily) -+ -+ASN1_ITEM_TEMPLATE(IPAddrBlocks) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, -+ IPAddrBlocks, IPAddressFamily) -+static_ASN1_ITEM_TEMPLATE_END(IPAddrBlocks) -+ -+IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) -+IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange) -+IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice) -+IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily) -+ -+/* -+ * How much buffer space do we need for a raw address? -+ */ -+#define ADDR_RAW_BUF_LEN 16 -+ -+/* -+ * What's the address length associated with this AFI? -+ */ -+static int length_from_afi(const unsigned afi) -+{ -+ switch (afi) { -+ case IANA_AFI_IPV4: -+ return 4; -+ case IANA_AFI_IPV6: -+ return 16; -+ default: -+ return 0; -+ } -+} -+ -+/* -+ * Extract the AFI from an IPAddressFamily. -+ */ -+unsigned int X509v3_addr_get_afi(const IPAddressFamily *f) -+{ -+ return ((f != NULL && -+ f->addressFamily != NULL && f->addressFamily->data != NULL) -+ ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1])) -+ : 0); -+} -+ -+/* -+ * Expand the bitstring form of an address into a raw byte array. -+ * At the moment this is coded for simplicity, not speed. -+ */ -+static int addr_expand(unsigned char *addr, -+ const ASN1_BIT_STRING *bs, -+ const int length, const unsigned char fill) -+{ -+ if (bs->length < 0 || bs->length > length) -+ return 0; -+ if (bs->length > 0) { -+ memcpy(addr, bs->data, bs->length); -+ if ((bs->flags & 7) != 0) { -+ unsigned char mask = 0xFF >> (8 - (bs->flags & 7)); -+ if (fill == 0) -+ addr[bs->length - 1] &= ~mask; -+ else -+ addr[bs->length - 1] |= mask; -+ } -+ } -+ memset(addr + bs->length, fill, length - bs->length); -+ return 1; -+} -+ -+/* -+ * Extract the prefix length from a bitstring. -+ */ -+#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) -+ -+/* -+ * i2r handler for one address bitstring. -+ */ -+static int i2r_address(BIO *out, -+ const unsigned afi, -+ const unsigned char fill, const ASN1_BIT_STRING *bs) -+{ -+ unsigned char addr[ADDR_RAW_BUF_LEN]; -+ int i, n; -+ -+ if (bs->length < 0) -+ return 0; -+ switch (afi) { -+ case IANA_AFI_IPV4: -+ if (!addr_expand(addr, bs, 4, fill)) -+ return 0; -+ BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); -+ break; -+ case IANA_AFI_IPV6: -+ if (!addr_expand(addr, bs, 16, fill)) -+ return 0; -+ for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; -+ n -= 2) ; -+ for (i = 0; i < n; i += 2) -+ BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1], -+ (i < 14 ? ":" : "")); -+ if (i < 16) -+ BIO_puts(out, ":"); -+ if (i == 0) -+ BIO_puts(out, ":"); -+ break; -+ default: -+ for (i = 0; i < bs->length; i++) -+ BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]); -+ BIO_printf(out, "[%d]", (int)(bs->flags & 7)); -+ break; -+ } -+ return 1; -+} -+ -+/* -+ * i2r handler for a sequence of addresses and ranges. -+ */ -+static int i2r_IPAddressOrRanges(BIO *out, -+ const int indent, -+ const IPAddressOrRanges *aors, -+ const unsigned afi) -+{ -+ int i; -+ for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { -+ const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i); -+ BIO_printf(out, "%*s", indent, ""); -+ switch (aor->type) { -+ case IPAddressOrRange_addressPrefix: -+ if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix)) -+ return 0; -+ BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix)); -+ continue; -+ case IPAddressOrRange_addressRange: -+ if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min)) -+ return 0; -+ BIO_puts(out, "-"); -+ if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max)) -+ return 0; -+ BIO_puts(out, "\n"); -+ continue; -+ } -+ } -+ return 1; -+} -+ -+/* -+ * i2r handler for an IPAddrBlocks extension. -+ */ -+static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, -+ void *ext, BIO *out, int indent) -+{ -+ const IPAddrBlocks *addr = ext; -+ int i; -+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { -+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); -+ const unsigned int afi = X509v3_addr_get_afi(f); -+ switch (afi) { -+ case IANA_AFI_IPV4: -+ BIO_printf(out, "%*sIPv4", indent, ""); -+ break; -+ case IANA_AFI_IPV6: -+ BIO_printf(out, "%*sIPv6", indent, ""); -+ break; -+ default: -+ BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); -+ break; -+ } -+ if (f->addressFamily->length > 2) { -+ switch (f->addressFamily->data[2]) { -+ case 1: -+ BIO_puts(out, " (Unicast)"); -+ break; -+ case 2: -+ BIO_puts(out, " (Multicast)"); -+ break; -+ case 3: -+ BIO_puts(out, " (Unicast/Multicast)"); -+ break; -+ case 4: -+ BIO_puts(out, " (MPLS)"); -+ break; -+ case 64: -+ BIO_puts(out, " (Tunnel)"); -+ break; -+ case 65: -+ BIO_puts(out, " (VPLS)"); -+ break; -+ case 66: -+ BIO_puts(out, " (BGP MDT)"); -+ break; -+ case 128: -+ BIO_puts(out, " (MPLS-labeled VPN)"); -+ break; -+ default: -+ BIO_printf(out, " (Unknown SAFI %u)", -+ (unsigned)f->addressFamily->data[2]); -+ break; -+ } -+ } -+ switch (f->ipAddressChoice->type) { -+ case IPAddressChoice_inherit: -+ BIO_puts(out, ": inherit\n"); -+ break; -+ case IPAddressChoice_addressesOrRanges: -+ BIO_puts(out, ":\n"); -+ if (!i2r_IPAddressOrRanges(out, -+ indent + 2, -+ f->ipAddressChoice-> -+ u.addressesOrRanges, afi)) -+ return 0; -+ break; -+ } -+ } -+ return 1; -+} -+ -+/* -+ * Sort comparison function for a sequence of IPAddressOrRange -+ * elements. -+ * -+ * There's no sane answer we can give if addr_expand() fails, and an -+ * assertion failure on externally supplied data is seriously uncool, -+ * so we just arbitrarily declare that if given invalid inputs this -+ * function returns -1. If this messes up your preferred sort order -+ * for garbage input, tough noogies. -+ */ -+static int IPAddressOrRange_cmp(const IPAddressOrRange *a, -+ const IPAddressOrRange *b, const int length) -+{ -+ unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; -+ int prefixlen_a = 0, prefixlen_b = 0; -+ int r; -+ -+ switch (a->type) { -+ case IPAddressOrRange_addressPrefix: -+ if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) -+ return -1; -+ prefixlen_a = addr_prefixlen(a->u.addressPrefix); -+ break; -+ case IPAddressOrRange_addressRange: -+ if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) -+ return -1; -+ prefixlen_a = length * 8; -+ break; -+ } -+ -+ switch (b->type) { -+ case IPAddressOrRange_addressPrefix: -+ if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) -+ return -1; -+ prefixlen_b = addr_prefixlen(b->u.addressPrefix); -+ break; -+ case IPAddressOrRange_addressRange: -+ if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) -+ return -1; -+ prefixlen_b = length * 8; -+ break; -+ } -+ -+ if ((r = memcmp(addr_a, addr_b, length)) != 0) -+ return r; -+ else -+ return prefixlen_a - prefixlen_b; -+} -+ -+/* -+ * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() -+ * comparison routines are only allowed two arguments. -+ */ -+static int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a, -+ const IPAddressOrRange *const *b) -+{ -+ return IPAddressOrRange_cmp(*a, *b, 4); -+} -+ -+/* -+ * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() -+ * comparison routines are only allowed two arguments. -+ */ -+static int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a, -+ const IPAddressOrRange *const *b) -+{ -+ return IPAddressOrRange_cmp(*a, *b, 16); -+} -+ -+/* -+ * Calculate whether a range collapses to a prefix. -+ * See last paragraph of RFC 3779 2.2.3.7. -+ */ -+static int range_should_be_prefix(const unsigned char *min, -+ const unsigned char *max, const int length) -+{ -+ unsigned char mask; -+ int i, j; -+ -+ OPENSSL_assert(memcmp(min, max, length) <= 0); -+ for (i = 0; i < length && min[i] == max[i]; i++) ; -+ for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ; -+ if (i < j) -+ return -1; -+ if (i > j) -+ return i * 8; -+ mask = min[i] ^ max[i]; -+ switch (mask) { -+ case 0x01: -+ j = 7; -+ break; -+ case 0x03: -+ j = 6; -+ break; -+ case 0x07: -+ j = 5; -+ break; -+ case 0x0F: -+ j = 4; -+ break; -+ case 0x1F: -+ j = 3; -+ break; -+ case 0x3F: -+ j = 2; -+ break; -+ case 0x7F: -+ j = 1; -+ break; -+ default: -+ return -1; -+ } -+ if ((min[i] & mask) != 0 || (max[i] & mask) != mask) -+ return -1; -+ else -+ return i * 8 + j; -+} -+ -+/* -+ * Construct a prefix. -+ */ -+static int make_addressPrefix(IPAddressOrRange **result, -+ unsigned char *addr, const int prefixlen) -+{ -+ int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; -+ IPAddressOrRange *aor = IPAddressOrRange_new(); -+ -+ if (aor == NULL) -+ return 0; -+ aor->type = IPAddressOrRange_addressPrefix; -+ if (aor->u.addressPrefix == NULL && -+ (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) -+ goto err; -+ if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) -+ goto err; -+ aor->u.addressPrefix->flags &= ~7; -+ aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; -+ if (bitlen > 0) { -+ aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); -+ aor->u.addressPrefix->flags |= 8 - bitlen; -+ } -+ -+ *result = aor; -+ return 1; -+ -+ err: -+ IPAddressOrRange_free(aor); -+ return 0; -+} -+ -+/* -+ * Construct a range. If it can be expressed as a prefix, -+ * return a prefix instead. Doing this here simplifies -+ * the rest of the code considerably. -+ */ -+static int make_addressRange(IPAddressOrRange **result, -+ unsigned char *min, -+ unsigned char *max, const int length) -+{ -+ IPAddressOrRange *aor; -+ int i, prefixlen; -+ -+ if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) -+ return make_addressPrefix(result, min, prefixlen); -+ -+ if ((aor = IPAddressOrRange_new()) == NULL) -+ return 0; -+ aor->type = IPAddressOrRange_addressRange; -+ OPENSSL_assert(aor->u.addressRange == NULL); -+ if ((aor->u.addressRange = IPAddressRange_new()) == NULL) -+ goto err; -+ if (aor->u.addressRange->min == NULL && -+ (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL) -+ goto err; -+ if (aor->u.addressRange->max == NULL && -+ (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL) -+ goto err; -+ -+ for (i = length; i > 0 && min[i - 1] == 0x00; --i) ; -+ if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) -+ goto err; -+ aor->u.addressRange->min->flags &= ~7; -+ aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; -+ if (i > 0) { -+ unsigned char b = min[i - 1]; -+ int j = 1; -+ while ((b & (0xFFU >> j)) != 0) -+ ++j; -+ aor->u.addressRange->min->flags |= 8 - j; -+ } -+ -+ for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ; -+ if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) -+ goto err; -+ aor->u.addressRange->max->flags &= ~7; -+ aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; -+ if (i > 0) { -+ unsigned char b = max[i - 1]; -+ int j = 1; -+ while ((b & (0xFFU >> j)) != (0xFFU >> j)) -+ ++j; -+ aor->u.addressRange->max->flags |= 8 - j; -+ } -+ -+ *result = aor; -+ return 1; -+ -+ err: -+ IPAddressOrRange_free(aor); -+ return 0; -+} -+ -+/* -+ * Construct a new address family or find an existing one. -+ */ -+static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr, -+ const unsigned afi, -+ const unsigned *safi) -+{ -+ IPAddressFamily *f; -+ unsigned char key[3]; -+ int keylen; -+ int i; -+ -+ key[0] = (afi >> 8) & 0xFF; -+ key[1] = afi & 0xFF; -+ if (safi != NULL) { -+ key[2] = *safi & 0xFF; -+ keylen = 3; -+ } else { -+ keylen = 2; -+ } -+ -+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { -+ f = sk_IPAddressFamily_value(addr, i); -+ OPENSSL_assert(f->addressFamily->data != NULL); -+ if (f->addressFamily->length == keylen && -+ !memcmp(f->addressFamily->data, key, keylen)) -+ return f; -+ } -+ -+ if ((f = IPAddressFamily_new()) == NULL) -+ goto err; -+ if (f->ipAddressChoice == NULL && -+ (f->ipAddressChoice = IPAddressChoice_new()) == NULL) -+ goto err; -+ if (f->addressFamily == NULL && -+ (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL) -+ goto err; -+ if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen)) -+ goto err; -+ if (!sk_IPAddressFamily_push(addr, f)) -+ goto err; -+ -+ return f; -+ -+ err: -+ IPAddressFamily_free(f); -+ return NULL; -+} -+ -+/* -+ * Add an inheritance element. -+ */ -+int X509v3_addr_add_inherit(IPAddrBlocks *addr, -+ const unsigned afi, const unsigned *safi) -+{ -+ IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); -+ if (f == NULL || -+ f->ipAddressChoice == NULL || -+ (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && -+ f->ipAddressChoice->u.addressesOrRanges != NULL)) -+ return 0; -+ if (f->ipAddressChoice->type == IPAddressChoice_inherit && -+ f->ipAddressChoice->u.inherit != NULL) -+ return 1; -+ if (f->ipAddressChoice->u.inherit == NULL && -+ (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) -+ return 0; -+ f->ipAddressChoice->type = IPAddressChoice_inherit; -+ return 1; -+} -+ -+/* -+ * Construct an IPAddressOrRange sequence, or return an existing one. -+ */ -+static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr, -+ const unsigned afi, -+ const unsigned *safi) -+{ -+ IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); -+ IPAddressOrRanges *aors = NULL; -+ -+ if (f == NULL || -+ f->ipAddressChoice == NULL || -+ (f->ipAddressChoice->type == IPAddressChoice_inherit && -+ f->ipAddressChoice->u.inherit != NULL)) -+ return NULL; -+ if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) -+ aors = f->ipAddressChoice->u.addressesOrRanges; -+ if (aors != NULL) -+ return aors; -+ if ((aors = sk_IPAddressOrRange_new_null()) == NULL) -+ return NULL; -+ switch (afi) { -+ case IANA_AFI_IPV4: -+ (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); -+ break; -+ case IANA_AFI_IPV6: -+ (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); -+ break; -+ } -+ f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; -+ f->ipAddressChoice->u.addressesOrRanges = aors; -+ return aors; -+} -+ -+/* -+ * Add a prefix. -+ */ -+int X509v3_addr_add_prefix(IPAddrBlocks *addr, -+ const unsigned afi, -+ const unsigned *safi, -+ unsigned char *a, const int prefixlen) -+{ -+ IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); -+ IPAddressOrRange *aor; -+ if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) -+ return 0; -+ if (sk_IPAddressOrRange_push(aors, aor)) -+ return 1; -+ IPAddressOrRange_free(aor); -+ return 0; -+} -+ -+/* -+ * Add a range. -+ */ -+int X509v3_addr_add_range(IPAddrBlocks *addr, -+ const unsigned afi, -+ const unsigned *safi, -+ unsigned char *min, unsigned char *max) -+{ -+ IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); -+ IPAddressOrRange *aor; -+ int length = length_from_afi(afi); -+ if (aors == NULL) -+ return 0; -+ if (!make_addressRange(&aor, min, max, length)) -+ return 0; -+ if (sk_IPAddressOrRange_push(aors, aor)) -+ return 1; -+ IPAddressOrRange_free(aor); -+ return 0; -+} -+ -+/* -+ * Extract min and max values from an IPAddressOrRange. -+ */ -+static int extract_min_max(IPAddressOrRange *aor, -+ unsigned char *min, unsigned char *max, int length) -+{ -+ if (aor == NULL || min == NULL || max == NULL) -+ return 0; -+ switch (aor->type) { -+ case IPAddressOrRange_addressPrefix: -+ return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && -+ addr_expand(max, aor->u.addressPrefix, length, 0xFF)); -+ case IPAddressOrRange_addressRange: -+ return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && -+ addr_expand(max, aor->u.addressRange->max, length, 0xFF)); -+ } -+ return 0; -+} -+ -+/* -+ * Public wrapper for extract_min_max(). -+ */ -+int X509v3_addr_get_range(IPAddressOrRange *aor, -+ const unsigned afi, -+ unsigned char *min, -+ unsigned char *max, const int length) -+{ -+ int afi_length = length_from_afi(afi); -+ if (aor == NULL || min == NULL || max == NULL || -+ afi_length == 0 || length < afi_length || -+ (aor->type != IPAddressOrRange_addressPrefix && -+ aor->type != IPAddressOrRange_addressRange) || -+ !extract_min_max(aor, min, max, afi_length)) -+ return 0; -+ -+ return afi_length; -+} -+ -+/* -+ * Sort comparison function for a sequence of IPAddressFamily. -+ * -+ * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about -+ * the ordering: I can read it as meaning that IPv6 without a SAFI -+ * comes before IPv4 with a SAFI, which seems pretty weird. The -+ * examples in appendix B suggest that the author intended the -+ * null-SAFI rule to apply only within a single AFI, which is what I -+ * would have expected and is what the following code implements. -+ */ -+static int IPAddressFamily_cmp(const IPAddressFamily *const *a_, -+ const IPAddressFamily *const *b_) -+{ -+ const ASN1_OCTET_STRING *a = (*a_)->addressFamily; -+ const ASN1_OCTET_STRING *b = (*b_)->addressFamily; -+ int len = ((a->length <= b->length) ? a->length : b->length); -+ int cmp = memcmp(a->data, b->data, len); -+ return cmp ? cmp : a->length - b->length; -+} -+ -+/* -+ * Check whether an IPAddrBLocks is in canonical form. -+ */ -+int X509v3_addr_is_canonical(IPAddrBlocks *addr) -+{ -+ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; -+ unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; -+ IPAddressOrRanges *aors; -+ int i, j, k; -+ -+ /* -+ * Empty extension is canonical. -+ */ -+ if (addr == NULL) -+ return 1; -+ -+ /* -+ * Check whether the top-level list is in order. -+ */ -+ for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { -+ const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); -+ const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); -+ if (IPAddressFamily_cmp(&a, &b) >= 0) -+ return 0; -+ } -+ -+ /* -+ * Top level's ok, now check each address family. -+ */ -+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { -+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); -+ int length = length_from_afi(X509v3_addr_get_afi(f)); -+ -+ /* -+ * Inheritance is canonical. Anything other than inheritance or -+ * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something. -+ */ -+ if (f == NULL || f->ipAddressChoice == NULL) -+ return 0; -+ switch (f->ipAddressChoice->type) { -+ case IPAddressChoice_inherit: -+ continue; -+ case IPAddressChoice_addressesOrRanges: -+ break; -+ default: -+ return 0; -+ } -+ -+ /* -+ * It's an IPAddressOrRanges sequence, check it. -+ */ -+ aors = f->ipAddressChoice->u.addressesOrRanges; -+ if (sk_IPAddressOrRange_num(aors) == 0) -+ return 0; -+ for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { -+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); -+ IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); -+ -+ if (!extract_min_max(a, a_min, a_max, length) || -+ !extract_min_max(b, b_min, b_max, length)) -+ return 0; -+ -+ /* -+ * Punt misordered list, overlapping start, or inverted range. -+ */ -+ if (memcmp(a_min, b_min, length) >= 0 || -+ memcmp(a_min, a_max, length) > 0 || -+ memcmp(b_min, b_max, length) > 0) -+ return 0; -+ -+ /* -+ * Punt if adjacent or overlapping. Check for adjacency by -+ * subtracting one from b_min first. -+ */ -+ for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ; -+ if (memcmp(a_max, b_min, length) >= 0) -+ return 0; -+ -+ /* -+ * Check for range that should be expressed as a prefix. -+ */ -+ if (a->type == IPAddressOrRange_addressRange && -+ range_should_be_prefix(a_min, a_max, length) >= 0) -+ return 0; -+ } -+ -+ /* -+ * Check range to see if it's inverted or should be a -+ * prefix. -+ */ -+ j = sk_IPAddressOrRange_num(aors) - 1; -+ { -+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); -+ if (a != NULL && a->type == IPAddressOrRange_addressRange) { -+ if (!extract_min_max(a, a_min, a_max, length)) -+ return 0; -+ if (memcmp(a_min, a_max, length) > 0 || -+ range_should_be_prefix(a_min, a_max, length) >= 0) -+ return 0; -+ } -+ } -+ } -+ -+ /* -+ * If we made it through all that, we're happy. -+ */ -+ return 1; -+} -+ -+/* -+ * Whack an IPAddressOrRanges into canonical form. -+ */ -+static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, -+ const unsigned afi) -+{ -+ int i, j, length = length_from_afi(afi); -+ -+ /* -+ * Sort the IPAddressOrRanges sequence. -+ */ -+ sk_IPAddressOrRange_sort(aors); -+ -+ /* -+ * Clean up representation issues, punt on duplicates or overlaps. -+ */ -+ for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { -+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i); -+ IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1); -+ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; -+ unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; -+ -+ if (!extract_min_max(a, a_min, a_max, length) || -+ !extract_min_max(b, b_min, b_max, length)) -+ return 0; -+ -+ /* -+ * Punt inverted ranges. -+ */ -+ if (memcmp(a_min, a_max, length) > 0 || -+ memcmp(b_min, b_max, length) > 0) -+ return 0; -+ -+ /* -+ * Punt overlaps. -+ */ -+ if (memcmp(a_max, b_min, length) >= 0) -+ return 0; -+ -+ /* -+ * Merge if a and b are adjacent. We check for -+ * adjacency by subtracting one from b_min first. -+ */ -+ for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ; -+ if (memcmp(a_max, b_min, length) == 0) { -+ IPAddressOrRange *merged; -+ if (!make_addressRange(&merged, a_min, b_max, length)) -+ return 0; -+ (void)sk_IPAddressOrRange_set(aors, i, merged); -+ (void)sk_IPAddressOrRange_delete(aors, i + 1); -+ IPAddressOrRange_free(a); -+ IPAddressOrRange_free(b); -+ --i; -+ continue; -+ } -+ } -+ -+ /* -+ * Check for inverted final range. -+ */ -+ j = sk_IPAddressOrRange_num(aors) - 1; -+ { -+ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); -+ if (a != NULL && a->type == IPAddressOrRange_addressRange) { -+ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; -+ if (!extract_min_max(a, a_min, a_max, length)) -+ return 0; -+ if (memcmp(a_min, a_max, length) > 0) -+ return 0; -+ } -+ } -+ -+ return 1; -+} -+ -+/* -+ * Whack an IPAddrBlocks extension into canonical form. -+ */ -+int X509v3_addr_canonize(IPAddrBlocks *addr) -+{ -+ int i; -+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { -+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); -+ if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && -+ !IPAddressOrRanges_canonize(f->ipAddressChoice-> -+ u.addressesOrRanges, -+ X509v3_addr_get_afi(f))) -+ return 0; -+ } -+ (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); -+ sk_IPAddressFamily_sort(addr); -+ OPENSSL_assert(X509v3_addr_is_canonical(addr)); -+ return 1; -+} -+ -+/* -+ * v2i handler for the IPAddrBlocks extension. -+ */ -+static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, -+ struct v3_ext_ctx *ctx, -+ STACK_OF(CONF_VALUE) *values) -+{ -+ static const char v4addr_chars[] = "0123456789."; -+ static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; -+ IPAddrBlocks *addr = NULL; -+ char *s = NULL, *t; -+ int i; -+ -+ if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) { -+ CONF_VALUE *val = sk_CONF_VALUE_value(values, i); -+ unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; -+ unsigned afi, *safi = NULL, safi_; -+ const char *addr_chars = NULL; -+ int prefixlen, i1, i2, delim, length; -+ -+ if (!name_cmp(val->name, "IPv4")) { -+ afi = IANA_AFI_IPV4; -+ } else if (!name_cmp(val->name, "IPv6")) { -+ afi = IANA_AFI_IPV6; -+ } else if (!name_cmp(val->name, "IPv4-SAFI")) { -+ afi = IANA_AFI_IPV4; -+ safi = &safi_; -+ } else if (!name_cmp(val->name, "IPv6-SAFI")) { -+ afi = IANA_AFI_IPV6; -+ safi = &safi_; -+ } else { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, -+ X509V3_R_EXTENSION_NAME_ERROR); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ -+ switch (afi) { -+ case IANA_AFI_IPV4: -+ addr_chars = v4addr_chars; -+ break; -+ case IANA_AFI_IPV6: -+ addr_chars = v6addr_chars; -+ break; -+ } -+ -+ length = length_from_afi(afi); -+ -+ /* -+ * Handle SAFI, if any, and OPENSSL_strdup() so we can null-terminate -+ * the other input values. -+ */ -+ if (safi != NULL) { -+ *safi = strtoul(val->value, &t, 0); -+ t += strspn(t, " \t"); -+ if (*safi > 0xFF || *t++ != ':') { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ t += strspn(t, " \t"); -+ s = OPENSSL_strdup(t); -+ } else { -+ s = OPENSSL_strdup(val->value); -+ } -+ if (s == NULL) { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ /* -+ * Check for inheritance. Not worth additional complexity to -+ * optimize this (seldom-used) case. -+ */ -+ if (strcmp(s, "inherit") == 0) { -+ if (!X509v3_addr_add_inherit(addr, afi, safi)) { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, -+ X509V3_R_INVALID_INHERITANCE); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ OPENSSL_free(s); -+ s = NULL; -+ continue; -+ } -+ -+ i1 = strspn(s, addr_chars); -+ i2 = i1 + strspn(s + i1, " \t"); -+ delim = s[i2++]; -+ s[i1] = '\0'; -+ -+ if (a2i_ipadd(min, s) != length) { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ -+ switch (delim) { -+ case '/': -+ prefixlen = (int)strtoul(s + i2, &t, 10); -+ if (t == s + i2 || *t != '\0') { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, -+ X509V3_R_EXTENSION_VALUE_ERROR); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ if (!X509v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ break; -+ case '-': -+ i1 = i2 + strspn(s + i2, " \t"); -+ i2 = i1 + strspn(s + i1, addr_chars); -+ if (i1 == i2 || s[i2] != '\0') { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, -+ X509V3_R_EXTENSION_VALUE_ERROR); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ if (a2i_ipadd(max, s + i1) != length) { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, -+ X509V3_R_INVALID_IPADDRESS); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ if (memcmp(min, max, length_from_afi(afi)) > 0) { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, -+ X509V3_R_EXTENSION_VALUE_ERROR); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ if (!X509v3_addr_add_range(addr, afi, safi, min, max)) { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ break; -+ case '\0': -+ if (!X509v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ break; -+ default: -+ X509V3err(X509V3_F_V2I_IPADDRBLOCKS, -+ X509V3_R_EXTENSION_VALUE_ERROR); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ -+ OPENSSL_free(s); -+ s = NULL; -+ } -+ -+ /* -+ * Canonize the result, then we're done. -+ */ -+ if (!X509v3_addr_canonize(addr)) -+ goto err; -+ return addr; -+ -+ err: -+ OPENSSL_free(s); -+ sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); -+ return NULL; -+} -+ -+/* -+ * OpenSSL dispatch -+ */ -+const X509V3_EXT_METHOD v3_addr = { -+ NID_sbgp_ipAddrBlock, /* nid */ -+ 0, /* flags */ -+ ASN1_ITEM_ref(IPAddrBlocks), /* template */ -+ 0, 0, 0, 0, /* old functions, ignored */ -+ 0, /* i2s */ -+ 0, /* s2i */ -+ 0, /* i2v */ -+ v2i_IPAddrBlocks, /* v2i */ -+ i2r_IPAddrBlocks, /* i2r */ -+ 0, /* r2i */ -+ NULL /* extension-specific data */ -+}; -+ -+/* -+ * Figure out whether extension sues inheritance. -+ */ -+int X509v3_addr_inherits(IPAddrBlocks *addr) -+{ -+ int i; -+ if (addr == NULL) -+ return 0; -+ for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { -+ IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); -+ if (f->ipAddressChoice->type == IPAddressChoice_inherit) -+ return 1; -+ } -+ return 0; -+} -+ -+/* -+ * Figure out whether parent contains child. -+ */ -+static int addr_contains(IPAddressOrRanges *parent, -+ IPAddressOrRanges *child, int length) -+{ -+ unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN]; -+ unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN]; -+ int p, c; -+ -+ if (child == NULL || parent == child) -+ return 1; -+ if (parent == NULL) -+ return 0; -+ -+ p = 0; -+ for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { -+ if (!extract_min_max(sk_IPAddressOrRange_value(child, c), -+ c_min, c_max, length)) -+ return -1; -+ for (;; p++) { -+ if (p >= sk_IPAddressOrRange_num(parent)) -+ return 0; -+ if (!extract_min_max(sk_IPAddressOrRange_value(parent, p), -+ p_min, p_max, length)) -+ return 0; -+ if (memcmp(p_max, c_max, length) < 0) -+ continue; -+ if (memcmp(p_min, c_min, length) > 0) -+ return 0; -+ break; -+ } -+ } -+ -+ return 1; -+} -+ -+/* -+ * Test whether a is a subset of b. -+ */ -+int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) -+{ -+ int i; -+ if (a == NULL || a == b) -+ return 1; -+ if (b == NULL || X509v3_addr_inherits(a) || X509v3_addr_inherits(b)) -+ return 0; -+ (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); -+ for (i = 0; i < sk_IPAddressFamily_num(a); i++) { -+ IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); -+ int j = sk_IPAddressFamily_find(b, fa); -+ IPAddressFamily *fb; -+ fb = sk_IPAddressFamily_value(b, j); -+ if (fb == NULL) -+ return 0; -+ if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, -+ fa->ipAddressChoice->u.addressesOrRanges, -+ length_from_afi(X509v3_addr_get_afi(fb)))) -+ return 0; -+ } -+ return 1; -+} -+ -+/* -+ * Validation error handling via callback. -+ */ -+#define validation_err(_err_) \ -+ do { \ -+ if (ctx != NULL) { \ -+ ctx->error = _err_; \ -+ ctx->error_depth = i; \ -+ ctx->current_cert = x; \ -+ ret = ctx->verify_cb(0, ctx); \ -+ } else { \ -+ ret = 0; \ -+ } \ -+ if (!ret) \ -+ goto done; \ -+ } while (0) -+ -+/* -+ * Core code for RFC 3779 2.3 path validation. -+ * -+ * Returns 1 for success, 0 on error. -+ * -+ * When returning 0, ctx->error MUST be set to an appropriate value other than -+ * X509_V_OK. -+ */ -+static int addr_validate_path_internal(X509_STORE_CTX *ctx, -+ STACK_OF(X509) *chain, -+ IPAddrBlocks *ext) -+{ -+ IPAddrBlocks *child = NULL; -+ int i, j, ret = 1; -+ X509 *x; -+ -+ OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); -+ OPENSSL_assert(ctx != NULL || ext != NULL); -+ OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); -+ -+ /* -+ * Figure out where to start. If we don't have an extension to -+ * check, we're done. Otherwise, check canonical form and -+ * set up for walking up the chain. -+ */ -+ if (ext != NULL) { -+ i = -1; -+ x = NULL; -+ } else { -+ i = 0; -+ x = sk_X509_value(chain, i); -+ OPENSSL_assert(x != NULL); -+ if ((ext = x->rfc3779_addr) == NULL) -+ goto done; -+ } -+ if (!X509v3_addr_is_canonical(ext)) -+ validation_err(X509_V_ERR_INVALID_EXTENSION); -+ (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); -+ if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { -+ X509V3err(X509V3_F_ADDR_VALIDATE_PATH_INTERNAL, -+ ERR_R_MALLOC_FAILURE); -+ ctx->error = X509_V_ERR_OUT_OF_MEM; -+ ret = 0; -+ goto done; -+ } -+ -+ /* -+ * Now walk up the chain. No cert may list resources that its -+ * parent doesn't list. -+ */ -+ for (i++; i < sk_X509_num(chain); i++) { -+ x = sk_X509_value(chain, i); -+ OPENSSL_assert(x != NULL); -+ if (!X509v3_addr_is_canonical(x->rfc3779_addr)) -+ validation_err(X509_V_ERR_INVALID_EXTENSION); -+ if (x->rfc3779_addr == NULL) { -+ for (j = 0; j < sk_IPAddressFamily_num(child); j++) { -+ IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); -+ if (fc->ipAddressChoice->type != IPAddressChoice_inherit) { -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ break; -+ } -+ } -+ continue; -+ } -+ (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, -+ IPAddressFamily_cmp); -+ for (j = 0; j < sk_IPAddressFamily_num(child); j++) { -+ IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); -+ int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); -+ IPAddressFamily *fp = -+ sk_IPAddressFamily_value(x->rfc3779_addr, k); -+ if (fp == NULL) { -+ if (fc->ipAddressChoice->type == -+ IPAddressChoice_addressesOrRanges) { -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ break; -+ } -+ continue; -+ } -+ if (fp->ipAddressChoice->type == -+ IPAddressChoice_addressesOrRanges) { -+ if (fc->ipAddressChoice->type == IPAddressChoice_inherit -+ || addr_contains(fp->ipAddressChoice->u.addressesOrRanges, -+ fc->ipAddressChoice->u.addressesOrRanges, -+ length_from_afi(X509v3_addr_get_afi(fc)))) -+ sk_IPAddressFamily_set(child, j, fp); -+ else -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ } -+ } -+ } -+ -+ /* -+ * Trust anchor can't inherit. -+ */ -+ OPENSSL_assert(x != NULL); -+ if (x->rfc3779_addr != NULL) { -+ for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { -+ IPAddressFamily *fp = -+ sk_IPAddressFamily_value(x->rfc3779_addr, j); -+ if (fp->ipAddressChoice->type == IPAddressChoice_inherit -+ && sk_IPAddressFamily_find(child, fp) >= 0) -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ } -+ } -+ -+ done: -+ sk_IPAddressFamily_free(child); -+ return ret; -+} -+ -+#undef validation_err -+ -+/* -+ * RFC 3779 2.3 path validation -- called from X509_verify_cert(). -+ */ -+int X509v3_addr_validate_path(X509_STORE_CTX *ctx) -+{ -+ return addr_validate_path_internal(ctx, ctx->chain, NULL); -+} -+ -+/* -+ * RFC 3779 2.3 path validation of an extension. -+ * Test whether chain covers extension. -+ */ -+int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, -+ IPAddrBlocks *ext, int allow_inheritance) -+{ -+ if (ext == NULL) -+ return 1; -+ if (chain == NULL || sk_X509_num(chain) == 0) -+ return 0; -+ if (!allow_inheritance && X509v3_addr_inherits(ext)) -+ return 0; -+ return addr_validate_path_internal(NULL, chain, ext); -+} -+ -+#endif /* OPENSSL_NO_RFC3779 */ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_akey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_akey.c -new file mode 100644 -index 0000000..d9f7704 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_akey.c -@@ -0,0 +1,160 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "ext_dat.h" -+ -+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, -+ AUTHORITY_KEYID *akeyid, -+ STACK_OF(CONF_VALUE) -+ *extlist); -+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *values); -+ -+const X509V3_EXT_METHOD v3_akey_id = { -+ NID_authority_key_identifier, -+ X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID), -+ 0, 0, 0, 0, -+ 0, 0, -+ (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID, -+ (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, -+ 0, 0, -+ NULL -+}; -+ -+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, -+ AUTHORITY_KEYID *akeyid, -+ STACK_OF(CONF_VALUE) -+ *extlist) -+{ -+ char *tmp; -+ if (akeyid->keyid) { -+ tmp = OPENSSL_buf2hexstr(akeyid->keyid->data, akeyid->keyid->length); -+ X509V3_add_value("keyid", tmp, &extlist); -+ OPENSSL_free(tmp); -+ } -+ if (akeyid->issuer) -+ extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); -+ if (akeyid->serial) { -+ tmp = OPENSSL_buf2hexstr(akeyid->serial->data, akeyid->serial->length); -+ X509V3_add_value("serial", tmp, &extlist); -+ OPENSSL_free(tmp); -+ } -+ return extlist; -+} -+ -+/*- -+ * Currently two options: -+ * keyid: use the issuers subject keyid, the value 'always' means its is -+ * an error if the issuer certificate doesn't have a key id. -+ * issuer: use the issuers cert issuer and serial number. The default is -+ * to only use this if keyid is not present. With the option 'always' -+ * this is always included. -+ */ -+ -+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *values) -+{ -+ char keyid = 0, issuer = 0; -+ int i; -+ CONF_VALUE *cnf; -+ ASN1_OCTET_STRING *ikeyid = NULL; -+ X509_NAME *isname = NULL; -+ GENERAL_NAMES *gens = NULL; -+ GENERAL_NAME *gen = NULL; -+ ASN1_INTEGER *serial = NULL; -+ X509_EXTENSION *ext; -+ X509 *cert; -+ AUTHORITY_KEYID *akeyid; -+ -+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) { -+ cnf = sk_CONF_VALUE_value(values, i); -+ if (strcmp(cnf->name, "keyid") == 0) { -+ keyid = 1; -+ if (cnf->value && strcmp(cnf->value, "always") == 0) -+ keyid = 2; -+ } else if (strcmp(cnf->name, "issuer") == 0) { -+ issuer = 1; -+ if (cnf->value && strcmp(cnf->value, "always") == 0) -+ issuer = 2; -+ } else { -+ X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, X509V3_R_UNKNOWN_OPTION); -+ ERR_add_error_data(2, "name=", cnf->name); -+ return NULL; -+ } -+ } -+ -+ if (!ctx || !ctx->issuer_cert) { -+ if (ctx && (ctx->flags == CTX_TEST)) -+ return AUTHORITY_KEYID_new(); -+ X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, -+ X509V3_R_NO_ISSUER_CERTIFICATE); -+ return NULL; -+ } -+ -+ cert = ctx->issuer_cert; -+ -+ if (keyid) { -+ i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); -+ if ((i >= 0) && (ext = X509_get_ext(cert, i))) -+ ikeyid = X509V3_EXT_d2i(ext); -+ if (keyid == 2 && !ikeyid) { -+ X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, -+ X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); -+ return NULL; -+ } -+ } -+ -+ if ((issuer && !ikeyid) || (issuer == 2)) { -+ isname = X509_NAME_dup(X509_get_issuer_name(cert)); -+ serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); -+ if (!isname || !serial) { -+ X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, -+ X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); -+ goto err; -+ } -+ } -+ -+ if ((akeyid = AUTHORITY_KEYID_new()) == NULL) -+ goto err; -+ -+ if (isname) { -+ if ((gens = sk_GENERAL_NAME_new_null()) == NULL -+ || (gen = GENERAL_NAME_new()) == NULL -+ || !sk_GENERAL_NAME_push(gens, gen)) { -+ X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ gen->type = GEN_DIRNAME; -+ gen->d.dirn = isname; -+ } -+ -+ akeyid->issuer = gens; -+ gen = NULL; -+ gens = NULL; -+ akeyid->serial = serial; -+ akeyid->keyid = ikeyid; -+ -+ return akeyid; -+ -+ err: -+ sk_GENERAL_NAME_free(gens); -+ GENERAL_NAME_free(gen); -+ X509_NAME_free(isname); -+ ASN1_INTEGER_free(serial); -+ ASN1_OCTET_STRING_free(ikeyid); -+ return NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_akeya.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_akeya.c -new file mode 100644 -index 0000000..d6dd6bc ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_akeya.c -@@ -0,0 +1,23 @@ -+/* -+ * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+ -+ASN1_SEQUENCE(AUTHORITY_KEYID) = { -+ ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), -+ ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1), -+ ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2) -+} ASN1_SEQUENCE_END(AUTHORITY_KEYID) -+ -+IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID) -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_alt.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_alt.c -new file mode 100644 -index 0000000..0364e33 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_alt.c -@@ -0,0 +1,566 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include "ext_dat.h" -+ -+static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval); -+static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval); -+static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); -+static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); -+static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); -+static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); -+ -+const X509V3_EXT_METHOD v3_alt[3] = { -+ {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), -+ 0, 0, 0, 0, -+ 0, 0, -+ (X509V3_EXT_I2V) i2v_GENERAL_NAMES, -+ (X509V3_EXT_V2I)v2i_subject_alt, -+ NULL, NULL, NULL}, -+ -+ {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), -+ 0, 0, 0, 0, -+ 0, 0, -+ (X509V3_EXT_I2V) i2v_GENERAL_NAMES, -+ (X509V3_EXT_V2I)v2i_issuer_alt, -+ NULL, NULL, NULL}, -+ -+ {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), -+ 0, 0, 0, 0, -+ 0, 0, -+ (X509V3_EXT_I2V) i2v_GENERAL_NAMES, -+ NULL, NULL, NULL, NULL}, -+}; -+ -+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, -+ GENERAL_NAMES *gens, -+ STACK_OF(CONF_VALUE) *ret) -+{ -+ int i; -+ GENERAL_NAME *gen; -+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { -+ gen = sk_GENERAL_NAME_value(gens, i); -+ ret = i2v_GENERAL_NAME(method, gen, ret); -+ } -+ if (!ret) -+ return sk_CONF_VALUE_new_null(); -+ return ret; -+} -+ -+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, -+ GENERAL_NAME *gen, -+ STACK_OF(CONF_VALUE) *ret) -+{ -+ unsigned char *p; -+ char oline[256], htmp[5]; -+ int i; -+ switch (gen->type) { -+ case GEN_OTHERNAME: -+ X509V3_add_value("othername", "", &ret); -+ break; -+ -+ case GEN_X400: -+ X509V3_add_value("X400Name", "", &ret); -+ break; -+ -+ case GEN_EDIPARTY: -+ X509V3_add_value("EdiPartyName", "", &ret); -+ break; -+ -+ case GEN_EMAIL: -+ X509V3_add_value_uchar("email", gen->d.ia5->data, &ret); -+ break; -+ -+ case GEN_DNS: -+ X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret); -+ break; -+ -+ case GEN_URI: -+ X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret); -+ break; -+ -+ case GEN_DIRNAME: -+ X509_NAME_oneline(gen->d.dirn, oline, 256); -+ X509V3_add_value("DirName", oline, &ret); -+ break; -+ -+ case GEN_IPADD: -+ p = gen->d.ip->data; -+ if (gen->d.ip->length == 4) -+ BIO_snprintf(oline, sizeof oline, -+ "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); -+ else if (gen->d.ip->length == 16) { -+ oline[0] = 0; -+ for (i = 0; i < 8; i++) { -+ BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]); -+ p += 2; -+ strcat(oline, htmp); -+ if (i != 7) -+ strcat(oline, ":"); -+ } -+ } else { -+ X509V3_add_value("IP Address", "", &ret); -+ break; -+ } -+ X509V3_add_value("IP Address", oline, &ret); -+ break; -+ -+ case GEN_RID: -+ i2t_ASN1_OBJECT(oline, 256, gen->d.rid); -+ X509V3_add_value("Registered ID", oline, &ret); -+ break; -+ } -+ return ret; -+} -+ -+int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) -+{ -+ unsigned char *p; -+ int i; -+ switch (gen->type) { -+ case GEN_OTHERNAME: -+ BIO_printf(out, "othername:"); -+ break; -+ -+ case GEN_X400: -+ BIO_printf(out, "X400Name:"); -+ break; -+ -+ case GEN_EDIPARTY: -+ /* Maybe fix this: it is supported now */ -+ BIO_printf(out, "EdiPartyName:"); -+ break; -+ -+ case GEN_EMAIL: -+ BIO_printf(out, "email:%s", gen->d.ia5->data); -+ break; -+ -+ case GEN_DNS: -+ BIO_printf(out, "DNS:%s", gen->d.ia5->data); -+ break; -+ -+ case GEN_URI: -+ BIO_printf(out, "URI:%s", gen->d.ia5->data); -+ break; -+ -+ case GEN_DIRNAME: -+ BIO_printf(out, "DirName:"); -+ X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); -+ break; -+ -+ case GEN_IPADD: -+ p = gen->d.ip->data; -+ if (gen->d.ip->length == 4) -+ BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); -+ else if (gen->d.ip->length == 16) { -+ BIO_printf(out, "IP Address"); -+ for (i = 0; i < 8; i++) { -+ BIO_printf(out, ":%X", p[0] << 8 | p[1]); -+ p += 2; -+ } -+ BIO_puts(out, "\n"); -+ } else { -+ BIO_printf(out, "IP Address:"); -+ break; -+ } -+ break; -+ -+ case GEN_RID: -+ BIO_printf(out, "Registered ID:"); -+ i2a_ASN1_OBJECT(out, gen->d.rid); -+ break; -+ } -+ return 1; -+} -+ -+static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval) -+{ -+ GENERAL_NAMES *gens = NULL; -+ CONF_VALUE *cnf; -+ int i; -+ -+ if ((gens = sk_GENERAL_NAME_new_null()) == NULL) { -+ X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ cnf = sk_CONF_VALUE_value(nval, i); -+ if (!name_cmp(cnf->name, "issuer") -+ && cnf->value && strcmp(cnf->value, "copy") == 0) { -+ if (!copy_issuer(ctx, gens)) -+ goto err; -+ } else { -+ GENERAL_NAME *gen; -+ if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) -+ goto err; -+ sk_GENERAL_NAME_push(gens, gen); -+ } -+ } -+ return gens; -+ err: -+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); -+ return NULL; -+} -+ -+/* Append subject altname of issuer to issuer alt name of subject */ -+ -+static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) -+{ -+ GENERAL_NAMES *ialt; -+ GENERAL_NAME *gen; -+ X509_EXTENSION *ext; -+ int i; -+ -+ if (ctx && (ctx->flags == CTX_TEST)) -+ return 1; -+ if (!ctx || !ctx->issuer_cert) { -+ X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); -+ goto err; -+ } -+ i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); -+ if (i < 0) -+ return 1; -+ if ((ext = X509_get_ext(ctx->issuer_cert, i)) == NULL -+ || (ialt = X509V3_EXT_d2i(ext)) == NULL) { -+ X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); -+ goto err; -+ } -+ -+ for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { -+ gen = sk_GENERAL_NAME_value(ialt, i); -+ if (!sk_GENERAL_NAME_push(gens, gen)) { -+ X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } -+ sk_GENERAL_NAME_free(ialt); -+ -+ return 1; -+ -+ err: -+ return 0; -+ -+} -+ -+static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval) -+{ -+ GENERAL_NAMES *gens = NULL; -+ CONF_VALUE *cnf; -+ int i; -+ -+ if ((gens = sk_GENERAL_NAME_new_null()) == NULL) { -+ X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ cnf = sk_CONF_VALUE_value(nval, i); -+ if (!name_cmp(cnf->name, "email") -+ && cnf->value && strcmp(cnf->value, "copy") == 0) { -+ if (!copy_email(ctx, gens, 0)) -+ goto err; -+ } else if (!name_cmp(cnf->name, "email") -+ && cnf->value && strcmp(cnf->value, "move") == 0) { -+ if (!copy_email(ctx, gens, 1)) -+ goto err; -+ } else { -+ GENERAL_NAME *gen; -+ if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) -+ goto err; -+ sk_GENERAL_NAME_push(gens, gen); -+ } -+ } -+ return gens; -+ err: -+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); -+ return NULL; -+} -+ -+/* -+ * Copy any email addresses in a certificate or request to GENERAL_NAMES -+ */ -+ -+static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) -+{ -+ X509_NAME *nm; -+ ASN1_IA5STRING *email = NULL; -+ X509_NAME_ENTRY *ne; -+ GENERAL_NAME *gen = NULL; -+ int i; -+ if (ctx != NULL && ctx->flags == CTX_TEST) -+ return 1; -+ if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { -+ X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); -+ goto err; -+ } -+ /* Find the subject name */ -+ if (ctx->subject_cert) -+ nm = X509_get_subject_name(ctx->subject_cert); -+ else -+ nm = X509_REQ_get_subject_name(ctx->subject_req); -+ -+ /* Now add any email address(es) to STACK */ -+ i = -1; -+ while ((i = X509_NAME_get_index_by_NID(nm, -+ NID_pkcs9_emailAddress, i)) >= 0) { -+ ne = X509_NAME_get_entry(nm, i); -+ email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne)); -+ if (move_p) { -+ X509_NAME_delete_entry(nm, i); -+ X509_NAME_ENTRY_free(ne); -+ i--; -+ } -+ if (email == NULL || (gen = GENERAL_NAME_new()) == NULL) { -+ X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ gen->d.ia5 = email; -+ email = NULL; -+ gen->type = GEN_EMAIL; -+ if (!sk_GENERAL_NAME_push(gens, gen)) { -+ X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ gen = NULL; -+ } -+ -+ return 1; -+ -+ err: -+ GENERAL_NAME_free(gen); -+ ASN1_IA5STRING_free(email); -+ return 0; -+ -+} -+ -+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -+{ -+ GENERAL_NAME *gen; -+ GENERAL_NAMES *gens = NULL; -+ CONF_VALUE *cnf; -+ int i; -+ -+ if ((gens = sk_GENERAL_NAME_new_null()) == NULL) { -+ X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ cnf = sk_CONF_VALUE_value(nval, i); -+ if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) -+ goto err; -+ sk_GENERAL_NAME_push(gens, gen); -+ } -+ return gens; -+ err: -+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); -+ return NULL; -+} -+ -+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, CONF_VALUE *cnf) -+{ -+ return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); -+} -+ -+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, -+ const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, int gen_type, const char *value, -+ int is_nc) -+{ -+ char is_string = 0; -+ GENERAL_NAME *gen = NULL; -+ -+ if (!value) { -+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE); -+ return NULL; -+ } -+ -+ if (out) -+ gen = out; -+ else { -+ gen = GENERAL_NAME_new(); -+ if (gen == NULL) { -+ X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ } -+ -+ switch (gen_type) { -+ case GEN_URI: -+ case GEN_EMAIL: -+ case GEN_DNS: -+ is_string = 1; -+ break; -+ -+ case GEN_RID: -+ { -+ ASN1_OBJECT *obj; -+ if ((obj = OBJ_txt2obj(value, 0)) == NULL) { -+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT); -+ ERR_add_error_data(2, "value=", value); -+ goto err; -+ } -+ gen->d.rid = obj; -+ } -+ break; -+ -+ case GEN_IPADD: -+ if (is_nc) -+ gen->d.ip = a2i_IPADDRESS_NC(value); -+ else -+ gen->d.ip = a2i_IPADDRESS(value); -+ if (gen->d.ip == NULL) { -+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS); -+ ERR_add_error_data(2, "value=", value); -+ goto err; -+ } -+ break; -+ -+ case GEN_DIRNAME: -+ if (!do_dirname(gen, value, ctx)) { -+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR); -+ goto err; -+ } -+ break; -+ -+ case GEN_OTHERNAME: -+ if (!do_othername(gen, value, ctx)) { -+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR); -+ goto err; -+ } -+ break; -+ default: -+ X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE); -+ goto err; -+ } -+ -+ if (is_string) { -+ if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL || -+ !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, -+ strlen(value))) { -+ X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } -+ -+ gen->type = gen_type; -+ -+ return gen; -+ -+ err: -+ if (!out) -+ GENERAL_NAME_free(gen); -+ return NULL; -+} -+ -+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, -+ const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) -+{ -+ int type; -+ -+ char *name, *value; -+ -+ name = cnf->name; -+ value = cnf->value; -+ -+ if (!value) { -+ X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); -+ return NULL; -+ } -+ -+ if (!name_cmp(name, "email")) -+ type = GEN_EMAIL; -+ else if (!name_cmp(name, "URI")) -+ type = GEN_URI; -+ else if (!name_cmp(name, "DNS")) -+ type = GEN_DNS; -+ else if (!name_cmp(name, "RID")) -+ type = GEN_RID; -+ else if (!name_cmp(name, "IP")) -+ type = GEN_IPADD; -+ else if (!name_cmp(name, "dirName")) -+ type = GEN_DIRNAME; -+ else if (!name_cmp(name, "otherName")) -+ type = GEN_OTHERNAME; -+ else { -+ X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION); -+ ERR_add_error_data(2, "name=", name); -+ return NULL; -+ } -+ -+ return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); -+ -+} -+ -+static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) -+{ -+ char *objtmp = NULL, *p; -+ int objlen; -+ -+ if ((p = strchr(value, ';')) == NULL) -+ return 0; -+ if ((gen->d.otherName = OTHERNAME_new()) == NULL) -+ return 0; -+ /* -+ * Free this up because we will overwrite it. no need to free type_id -+ * because it is static -+ */ -+ ASN1_TYPE_free(gen->d.otherName->value); -+ if ((gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)) == NULL) -+ return 0; -+ objlen = p - value; -+ objtmp = OPENSSL_strndup(value, objlen); -+ if (objtmp == NULL) -+ return 0; -+ gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); -+ OPENSSL_free(objtmp); -+ if (!gen->d.otherName->type_id) -+ return 0; -+ return 1; -+} -+ -+static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) -+{ -+ int ret = 0; -+ STACK_OF(CONF_VALUE) *sk = NULL; -+ X509_NAME *nm; -+ -+ if ((nm = X509_NAME_new()) == NULL) -+ goto err; -+ sk = X509V3_get_section(ctx, value); -+ if (!sk) { -+ X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); -+ ERR_add_error_data(2, "section=", value); -+ goto err; -+ } -+ /* FIXME: should allow other character types... */ -+ ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); -+ if (!ret) -+ goto err; -+ gen->d.dirn = nm; -+ -+err: -+ if (ret == 0) -+ X509_NAME_free(nm); -+ X509V3_section_free(ctx, sk); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_asid.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_asid.c -new file mode 100644 -index 0000000..af4fcf4 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_asid.c -@@ -0,0 +1,852 @@ -+/* -+ * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * Implementation of RFC 3779 section 3.2. -+ */ -+ -+#include -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include -+#include "internal/x509_int.h" -+#include -+#include "ext_dat.h" -+ -+#ifndef OPENSSL_NO_RFC3779 -+ -+/* -+ * OpenSSL ASN.1 template translation of RFC 3779 3.2.3. -+ */ -+ -+ASN1_SEQUENCE(ASRange) = { -+ ASN1_SIMPLE(ASRange, min, ASN1_INTEGER), -+ ASN1_SIMPLE(ASRange, max, ASN1_INTEGER) -+} ASN1_SEQUENCE_END(ASRange) -+ -+ASN1_CHOICE(ASIdOrRange) = { -+ ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER), -+ ASN1_SIMPLE(ASIdOrRange, u.range, ASRange) -+} ASN1_CHOICE_END(ASIdOrRange) -+ -+ASN1_CHOICE(ASIdentifierChoice) = { -+ ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL), -+ ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange) -+} ASN1_CHOICE_END(ASIdentifierChoice) -+ -+ASN1_SEQUENCE(ASIdentifiers) = { -+ ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0), -+ ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1) -+} ASN1_SEQUENCE_END(ASIdentifiers) -+ -+IMPLEMENT_ASN1_FUNCTIONS(ASRange) -+IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange) -+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice) -+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers) -+ -+/* -+ * i2r method for an ASIdentifierChoice. -+ */ -+static int i2r_ASIdentifierChoice(BIO *out, -+ ASIdentifierChoice *choice, -+ int indent, const char *msg) -+{ -+ int i; -+ char *s; -+ if (choice == NULL) -+ return 1; -+ BIO_printf(out, "%*s%s:\n", indent, "", msg); -+ switch (choice->type) { -+ case ASIdentifierChoice_inherit: -+ BIO_printf(out, "%*sinherit\n", indent + 2, ""); -+ break; -+ case ASIdentifierChoice_asIdsOrRanges: -+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) { -+ ASIdOrRange *aor = -+ sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); -+ switch (aor->type) { -+ case ASIdOrRange_id: -+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL) -+ return 0; -+ BIO_printf(out, "%*s%s\n", indent + 2, "", s); -+ OPENSSL_free(s); -+ break; -+ case ASIdOrRange_range: -+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL) -+ return 0; -+ BIO_printf(out, "%*s%s-", indent + 2, "", s); -+ OPENSSL_free(s); -+ if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL) -+ return 0; -+ BIO_printf(out, "%s\n", s); -+ OPENSSL_free(s); -+ break; -+ default: -+ return 0; -+ } -+ } -+ break; -+ default: -+ return 0; -+ } -+ return 1; -+} -+ -+/* -+ * i2r method for an ASIdentifier extension. -+ */ -+static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, -+ void *ext, BIO *out, int indent) -+{ -+ ASIdentifiers *asid = ext; -+ return (i2r_ASIdentifierChoice(out, asid->asnum, indent, -+ "Autonomous System Numbers") && -+ i2r_ASIdentifierChoice(out, asid->rdi, indent, -+ "Routing Domain Identifiers")); -+} -+ -+/* -+ * Sort comparison function for a sequence of ASIdOrRange elements. -+ */ -+static int ASIdOrRange_cmp(const ASIdOrRange *const *a_, -+ const ASIdOrRange *const *b_) -+{ -+ const ASIdOrRange *a = *a_, *b = *b_; -+ -+ OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || -+ (a->type == ASIdOrRange_range && a->u.range != NULL && -+ a->u.range->min != NULL && a->u.range->max != NULL)); -+ -+ OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || -+ (b->type == ASIdOrRange_range && b->u.range != NULL && -+ b->u.range->min != NULL && b->u.range->max != NULL)); -+ -+ if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) -+ return ASN1_INTEGER_cmp(a->u.id, b->u.id); -+ -+ if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { -+ int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); -+ return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, -+ b->u.range->max); -+ } -+ -+ if (a->type == ASIdOrRange_id) -+ return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); -+ else -+ return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); -+} -+ -+/* -+ * Add an inherit element. -+ */ -+int X509v3_asid_add_inherit(ASIdentifiers *asid, int which) -+{ -+ ASIdentifierChoice **choice; -+ if (asid == NULL) -+ return 0; -+ switch (which) { -+ case V3_ASID_ASNUM: -+ choice = &asid->asnum; -+ break; -+ case V3_ASID_RDI: -+ choice = &asid->rdi; -+ break; -+ default: -+ return 0; -+ } -+ if (*choice == NULL) { -+ if ((*choice = ASIdentifierChoice_new()) == NULL) -+ return 0; -+ OPENSSL_assert((*choice)->u.inherit == NULL); -+ if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) -+ return 0; -+ (*choice)->type = ASIdentifierChoice_inherit; -+ } -+ return (*choice)->type == ASIdentifierChoice_inherit; -+} -+ -+/* -+ * Add an ID or range to an ASIdentifierChoice. -+ */ -+int X509v3_asid_add_id_or_range(ASIdentifiers *asid, -+ int which, ASN1_INTEGER *min, ASN1_INTEGER *max) -+{ -+ ASIdentifierChoice **choice; -+ ASIdOrRange *aor; -+ if (asid == NULL) -+ return 0; -+ switch (which) { -+ case V3_ASID_ASNUM: -+ choice = &asid->asnum; -+ break; -+ case V3_ASID_RDI: -+ choice = &asid->rdi; -+ break; -+ default: -+ return 0; -+ } -+ if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) -+ return 0; -+ if (*choice == NULL) { -+ if ((*choice = ASIdentifierChoice_new()) == NULL) -+ return 0; -+ OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL); -+ (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); -+ if ((*choice)->u.asIdsOrRanges == NULL) -+ return 0; -+ (*choice)->type = ASIdentifierChoice_asIdsOrRanges; -+ } -+ if ((aor = ASIdOrRange_new()) == NULL) -+ return 0; -+ if (max == NULL) { -+ aor->type = ASIdOrRange_id; -+ aor->u.id = min; -+ } else { -+ aor->type = ASIdOrRange_range; -+ if ((aor->u.range = ASRange_new()) == NULL) -+ goto err; -+ ASN1_INTEGER_free(aor->u.range->min); -+ aor->u.range->min = min; -+ ASN1_INTEGER_free(aor->u.range->max); -+ aor->u.range->max = max; -+ } -+ if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) -+ goto err; -+ return 1; -+ -+ err: -+ ASIdOrRange_free(aor); -+ return 0; -+} -+ -+/* -+ * Extract min and max values from an ASIdOrRange. -+ */ -+static void extract_min_max(ASIdOrRange *aor, -+ ASN1_INTEGER **min, ASN1_INTEGER **max) -+{ -+ OPENSSL_assert(aor != NULL && min != NULL && max != NULL); -+ switch (aor->type) { -+ case ASIdOrRange_id: -+ *min = aor->u.id; -+ *max = aor->u.id; -+ return; -+ case ASIdOrRange_range: -+ *min = aor->u.range->min; -+ *max = aor->u.range->max; -+ return; -+ } -+} -+ -+/* -+ * Check whether an ASIdentifierChoice is in canonical form. -+ */ -+static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) -+{ -+ ASN1_INTEGER *a_max_plus_one = NULL; -+ BIGNUM *bn = NULL; -+ int i, ret = 0; -+ -+ /* -+ * Empty element or inheritance is canonical. -+ */ -+ if (choice == NULL || choice->type == ASIdentifierChoice_inherit) -+ return 1; -+ -+ /* -+ * If not a list, or if empty list, it's broken. -+ */ -+ if (choice->type != ASIdentifierChoice_asIdsOrRanges || -+ sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) -+ return 0; -+ -+ /* -+ * It's a list, check it. -+ */ -+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { -+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); -+ ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); -+ ASN1_INTEGER *a_min = NULL, *a_max = NULL, *b_min = NULL, *b_max = -+ NULL; -+ -+ extract_min_max(a, &a_min, &a_max); -+ extract_min_max(b, &b_min, &b_max); -+ -+ /* -+ * Punt misordered list, overlapping start, or inverted range. -+ */ -+ if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || -+ ASN1_INTEGER_cmp(a_min, a_max) > 0 || -+ ASN1_INTEGER_cmp(b_min, b_max) > 0) -+ goto done; -+ -+ /* -+ * Calculate a_max + 1 to check for adjacency. -+ */ -+ if ((bn == NULL && (bn = BN_new()) == NULL) || -+ ASN1_INTEGER_to_BN(a_max, bn) == NULL || -+ !BN_add_word(bn, 1) || -+ (a_max_plus_one = -+ BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { -+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, -+ ERR_R_MALLOC_FAILURE); -+ goto done; -+ } -+ -+ /* -+ * Punt if adjacent or overlapping. -+ */ -+ if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) -+ goto done; -+ } -+ -+ /* -+ * Check for inverted range. -+ */ -+ i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; -+ { -+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); -+ ASN1_INTEGER *a_min, *a_max; -+ if (a != NULL && a->type == ASIdOrRange_range) { -+ extract_min_max(a, &a_min, &a_max); -+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0) -+ goto done; -+ } -+ } -+ -+ ret = 1; -+ -+ done: -+ ASN1_INTEGER_free(a_max_plus_one); -+ BN_free(bn); -+ return ret; -+} -+ -+/* -+ * Check whether an ASIdentifier extension is in canonical form. -+ */ -+int X509v3_asid_is_canonical(ASIdentifiers *asid) -+{ -+ return (asid == NULL || -+ (ASIdentifierChoice_is_canonical(asid->asnum) && -+ ASIdentifierChoice_is_canonical(asid->rdi))); -+} -+ -+/* -+ * Whack an ASIdentifierChoice into canonical form. -+ */ -+static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) -+{ -+ ASN1_INTEGER *a_max_plus_one = NULL; -+ BIGNUM *bn = NULL; -+ int i, ret = 0; -+ -+ /* -+ * Nothing to do for empty element or inheritance. -+ */ -+ if (choice == NULL || choice->type == ASIdentifierChoice_inherit) -+ return 1; -+ -+ /* -+ * If not a list, or if empty list, it's broken. -+ */ -+ if (choice->type != ASIdentifierChoice_asIdsOrRanges || -+ sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { -+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, -+ X509V3_R_EXTENSION_VALUE_ERROR); -+ return 0; -+ } -+ -+ /* -+ * We have a non-empty list. Sort it. -+ */ -+ sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); -+ -+ /* -+ * Now check for errors and suboptimal encoding, rejecting the -+ * former and fixing the latter. -+ */ -+ for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { -+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); -+ ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); -+ ASN1_INTEGER *a_min = NULL, *a_max = NULL, *b_min = NULL, *b_max = -+ NULL; -+ -+ extract_min_max(a, &a_min, &a_max); -+ extract_min_max(b, &b_min, &b_max); -+ -+ /* -+ * Make sure we're properly sorted (paranoia). -+ */ -+ OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); -+ -+ /* -+ * Punt inverted ranges. -+ */ -+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || -+ ASN1_INTEGER_cmp(b_min, b_max) > 0) -+ goto done; -+ -+ /* -+ * Check for overlaps. -+ */ -+ if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { -+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, -+ X509V3_R_EXTENSION_VALUE_ERROR); -+ goto done; -+ } -+ -+ /* -+ * Calculate a_max + 1 to check for adjacency. -+ */ -+ if ((bn == NULL && (bn = BN_new()) == NULL) || -+ ASN1_INTEGER_to_BN(a_max, bn) == NULL || -+ !BN_add_word(bn, 1) || -+ (a_max_plus_one = -+ BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { -+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, -+ ERR_R_MALLOC_FAILURE); -+ goto done; -+ } -+ -+ /* -+ * If a and b are adjacent, merge them. -+ */ -+ if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { -+ ASRange *r; -+ switch (a->type) { -+ case ASIdOrRange_id: -+ if ((r = OPENSSL_malloc(sizeof(*r))) == NULL) { -+ X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, -+ ERR_R_MALLOC_FAILURE); -+ goto done; -+ } -+ r->min = a_min; -+ r->max = b_max; -+ a->type = ASIdOrRange_range; -+ a->u.range = r; -+ break; -+ case ASIdOrRange_range: -+ ASN1_INTEGER_free(a->u.range->max); -+ a->u.range->max = b_max; -+ break; -+ } -+ switch (b->type) { -+ case ASIdOrRange_id: -+ b->u.id = NULL; -+ break; -+ case ASIdOrRange_range: -+ b->u.range->max = NULL; -+ break; -+ } -+ ASIdOrRange_free(b); -+ (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); -+ i--; -+ continue; -+ } -+ } -+ -+ /* -+ * Check for final inverted range. -+ */ -+ i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; -+ { -+ ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); -+ ASN1_INTEGER *a_min, *a_max; -+ if (a != NULL && a->type == ASIdOrRange_range) { -+ extract_min_max(a, &a_min, &a_max); -+ if (ASN1_INTEGER_cmp(a_min, a_max) > 0) -+ goto done; -+ } -+ } -+ -+ OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ -+ -+ ret = 1; -+ -+ done: -+ ASN1_INTEGER_free(a_max_plus_one); -+ BN_free(bn); -+ return ret; -+} -+ -+/* -+ * Whack an ASIdentifier extension into canonical form. -+ */ -+int X509v3_asid_canonize(ASIdentifiers *asid) -+{ -+ return (asid == NULL || -+ (ASIdentifierChoice_canonize(asid->asnum) && -+ ASIdentifierChoice_canonize(asid->rdi))); -+} -+ -+/* -+ * v2i method for an ASIdentifier extension. -+ */ -+static void *v2i_ASIdentifiers(const struct v3_ext_method *method, -+ struct v3_ext_ctx *ctx, -+ STACK_OF(CONF_VALUE) *values) -+{ -+ ASN1_INTEGER *min = NULL, *max = NULL; -+ ASIdentifiers *asid = NULL; -+ int i; -+ -+ if ((asid = ASIdentifiers_new()) == NULL) { -+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) { -+ CONF_VALUE *val = sk_CONF_VALUE_value(values, i); -+ int i1 = 0, i2 = 0, i3 = 0, is_range = 0, which = 0; -+ -+ /* -+ * Figure out whether this is an AS or an RDI. -+ */ -+ if (!name_cmp(val->name, "AS")) { -+ which = V3_ASID_ASNUM; -+ } else if (!name_cmp(val->name, "RDI")) { -+ which = V3_ASID_RDI; -+ } else { -+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, -+ X509V3_R_EXTENSION_NAME_ERROR); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ -+ /* -+ * Handle inheritance. -+ */ -+ if (strcmp(val->value, "inherit") == 0) { -+ if (X509v3_asid_add_inherit(asid, which)) -+ continue; -+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, -+ X509V3_R_INVALID_INHERITANCE); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ -+ /* -+ * Number, range, or mistake, pick it apart and figure out which. -+ */ -+ i1 = strspn(val->value, "0123456789"); -+ if (val->value[i1] == '\0') { -+ is_range = 0; -+ } else { -+ is_range = 1; -+ i2 = i1 + strspn(val->value + i1, " \t"); -+ if (val->value[i2] != '-') { -+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, -+ X509V3_R_INVALID_ASNUMBER); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ i2++; -+ i2 = i2 + strspn(val->value + i2, " \t"); -+ i3 = i2 + strspn(val->value + i2, "0123456789"); -+ if (val->value[i3] != '\0') { -+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, -+ X509V3_R_INVALID_ASRANGE); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ } -+ -+ /* -+ * Syntax is ok, read and add it. -+ */ -+ if (!is_range) { -+ if (!X509V3_get_value_int(val, &min)) { -+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } else { -+ char *s = OPENSSL_strdup(val->value); -+ if (s == NULL) { -+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ s[i1] = '\0'; -+ min = s2i_ASN1_INTEGER(NULL, s); -+ max = s2i_ASN1_INTEGER(NULL, s + i2); -+ OPENSSL_free(s); -+ if (min == NULL || max == NULL) { -+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ if (ASN1_INTEGER_cmp(min, max) > 0) { -+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, -+ X509V3_R_EXTENSION_VALUE_ERROR); -+ goto err; -+ } -+ } -+ if (!X509v3_asid_add_id_or_range(asid, which, min, max)) { -+ X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ min = max = NULL; -+ } -+ -+ /* -+ * Canonize the result, then we're done. -+ */ -+ if (!X509v3_asid_canonize(asid)) -+ goto err; -+ return asid; -+ -+ err: -+ ASIdentifiers_free(asid); -+ ASN1_INTEGER_free(min); -+ ASN1_INTEGER_free(max); -+ return NULL; -+} -+ -+/* -+ * OpenSSL dispatch. -+ */ -+const X509V3_EXT_METHOD v3_asid = { -+ NID_sbgp_autonomousSysNum, /* nid */ -+ 0, /* flags */ -+ ASN1_ITEM_ref(ASIdentifiers), /* template */ -+ 0, 0, 0, 0, /* old functions, ignored */ -+ 0, /* i2s */ -+ 0, /* s2i */ -+ 0, /* i2v */ -+ v2i_ASIdentifiers, /* v2i */ -+ i2r_ASIdentifiers, /* i2r */ -+ 0, /* r2i */ -+ NULL /* extension-specific data */ -+}; -+ -+/* -+ * Figure out whether extension uses inheritance. -+ */ -+int X509v3_asid_inherits(ASIdentifiers *asid) -+{ -+ return (asid != NULL && -+ ((asid->asnum != NULL && -+ asid->asnum->type == ASIdentifierChoice_inherit) || -+ (asid->rdi != NULL && -+ asid->rdi->type == ASIdentifierChoice_inherit))); -+} -+ -+/* -+ * Figure out whether parent contains child. -+ */ -+static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) -+{ -+ ASN1_INTEGER *p_min = NULL, *p_max = NULL, *c_min = NULL, *c_max = NULL; -+ int p, c; -+ -+ if (child == NULL || parent == child) -+ return 1; -+ if (parent == NULL) -+ return 0; -+ -+ p = 0; -+ for (c = 0; c < sk_ASIdOrRange_num(child); c++) { -+ extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max); -+ for (;; p++) { -+ if (p >= sk_ASIdOrRange_num(parent)) -+ return 0; -+ extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max); -+ if (ASN1_INTEGER_cmp(p_max, c_max) < 0) -+ continue; -+ if (ASN1_INTEGER_cmp(p_min, c_min) > 0) -+ return 0; -+ break; -+ } -+ } -+ -+ return 1; -+} -+ -+/* -+ * Test whether a is a subset of b. -+ */ -+int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b) -+{ -+ return (a == NULL || -+ a == b || -+ (b != NULL && -+ !X509v3_asid_inherits(a) && -+ !X509v3_asid_inherits(b) && -+ asid_contains(b->asnum->u.asIdsOrRanges, -+ a->asnum->u.asIdsOrRanges) && -+ asid_contains(b->rdi->u.asIdsOrRanges, -+ a->rdi->u.asIdsOrRanges))); -+} -+ -+/* -+ * Validation error handling via callback. -+ */ -+#define validation_err(_err_) \ -+ do { \ -+ if (ctx != NULL) { \ -+ ctx->error = _err_; \ -+ ctx->error_depth = i; \ -+ ctx->current_cert = x; \ -+ ret = ctx->verify_cb(0, ctx); \ -+ } else { \ -+ ret = 0; \ -+ } \ -+ if (!ret) \ -+ goto done; \ -+ } while (0) -+ -+/* -+ * Core code for RFC 3779 3.3 path validation. -+ */ -+static int asid_validate_path_internal(X509_STORE_CTX *ctx, -+ STACK_OF(X509) *chain, -+ ASIdentifiers *ext) -+{ -+ ASIdOrRanges *child_as = NULL, *child_rdi = NULL; -+ int i, ret = 1, inherit_as = 0, inherit_rdi = 0; -+ X509 *x; -+ -+ OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); -+ OPENSSL_assert(ctx != NULL || ext != NULL); -+ OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); -+ -+ /* -+ * Figure out where to start. If we don't have an extension to -+ * check, we're done. Otherwise, check canonical form and -+ * set up for walking up the chain. -+ */ -+ if (ext != NULL) { -+ i = -1; -+ x = NULL; -+ } else { -+ i = 0; -+ x = sk_X509_value(chain, i); -+ OPENSSL_assert(x != NULL); -+ if ((ext = x->rfc3779_asid) == NULL) -+ goto done; -+ } -+ if (!X509v3_asid_is_canonical(ext)) -+ validation_err(X509_V_ERR_INVALID_EXTENSION); -+ if (ext->asnum != NULL) { -+ switch (ext->asnum->type) { -+ case ASIdentifierChoice_inherit: -+ inherit_as = 1; -+ break; -+ case ASIdentifierChoice_asIdsOrRanges: -+ child_as = ext->asnum->u.asIdsOrRanges; -+ break; -+ } -+ } -+ if (ext->rdi != NULL) { -+ switch (ext->rdi->type) { -+ case ASIdentifierChoice_inherit: -+ inherit_rdi = 1; -+ break; -+ case ASIdentifierChoice_asIdsOrRanges: -+ child_rdi = ext->rdi->u.asIdsOrRanges; -+ break; -+ } -+ } -+ -+ /* -+ * Now walk up the chain. Extensions must be in canonical form, no -+ * cert may list resources that its parent doesn't list. -+ */ -+ for (i++; i < sk_X509_num(chain); i++) { -+ x = sk_X509_value(chain, i); -+ OPENSSL_assert(x != NULL); -+ if (x->rfc3779_asid == NULL) { -+ if (child_as != NULL || child_rdi != NULL) -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ continue; -+ } -+ if (!X509v3_asid_is_canonical(x->rfc3779_asid)) -+ validation_err(X509_V_ERR_INVALID_EXTENSION); -+ if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ child_as = NULL; -+ inherit_as = 0; -+ } -+ if (x->rfc3779_asid->asnum != NULL && -+ x->rfc3779_asid->asnum->type == -+ ASIdentifierChoice_asIdsOrRanges) { -+ if (inherit_as -+ || asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, -+ child_as)) { -+ child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; -+ inherit_as = 0; -+ } else { -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ } -+ } -+ if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ child_rdi = NULL; -+ inherit_rdi = 0; -+ } -+ if (x->rfc3779_asid->rdi != NULL && -+ x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { -+ if (inherit_rdi || -+ asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, -+ child_rdi)) { -+ child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; -+ inherit_rdi = 0; -+ } else { -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ } -+ } -+ } -+ -+ /* -+ * Trust anchor can't inherit. -+ */ -+ OPENSSL_assert(x != NULL); -+ if (x->rfc3779_asid != NULL) { -+ if (x->rfc3779_asid->asnum != NULL && -+ x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ if (x->rfc3779_asid->rdi != NULL && -+ x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) -+ validation_err(X509_V_ERR_UNNESTED_RESOURCE); -+ } -+ -+ done: -+ return ret; -+} -+ -+#undef validation_err -+ -+/* -+ * RFC 3779 3.3 path validation -- called from X509_verify_cert(). -+ */ -+int X509v3_asid_validate_path(X509_STORE_CTX *ctx) -+{ -+ return asid_validate_path_internal(ctx, ctx->chain, NULL); -+} -+ -+/* -+ * RFC 3779 3.3 path validation of an extension. -+ * Test whether chain covers extension. -+ */ -+int X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, -+ ASIdentifiers *ext, int allow_inheritance) -+{ -+ if (ext == NULL) -+ return 1; -+ if (chain == NULL || sk_X509_num(chain) == 0) -+ return 0; -+ if (!allow_inheritance && X509v3_asid_inherits(ext)) -+ return 0; -+ return asid_validate_path_internal(NULL, chain, ext); -+} -+ -+#endif /* OPENSSL_NO_RFC3779 */ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_bcons.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_bcons.c -new file mode 100644 -index 0000000..3bbf155 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_bcons.c -@@ -0,0 +1,84 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "ext_dat.h" -+ -+static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, -+ BASIC_CONSTRAINTS *bcons, -+ STACK_OF(CONF_VALUE) -+ *extlist); -+static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *values); -+ -+const X509V3_EXT_METHOD v3_bcons = { -+ NID_basic_constraints, 0, -+ ASN1_ITEM_ref(BASIC_CONSTRAINTS), -+ 0, 0, 0, 0, -+ 0, 0, -+ (X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS, -+ (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS, -+ NULL, NULL, -+ NULL -+}; -+ -+ASN1_SEQUENCE(BASIC_CONSTRAINTS) = { -+ ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN), -+ ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER) -+} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS) -+ -+IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) -+ -+static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, -+ BASIC_CONSTRAINTS *bcons, -+ STACK_OF(CONF_VALUE) -+ *extlist) -+{ -+ X509V3_add_value_bool("CA", bcons->ca, &extlist); -+ X509V3_add_value_int("pathlen", bcons->pathlen, &extlist); -+ return extlist; -+} -+ -+static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *values) -+{ -+ BASIC_CONSTRAINTS *bcons = NULL; -+ CONF_VALUE *val; -+ int i; -+ -+ if ((bcons = BASIC_CONSTRAINTS_new()) == NULL) { -+ X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) { -+ val = sk_CONF_VALUE_value(values, i); -+ if (strcmp(val->name, "CA") == 0) { -+ if (!X509V3_get_value_bool(val, &bcons->ca)) -+ goto err; -+ } else if (strcmp(val->name, "pathlen") == 0) { -+ if (!X509V3_get_value_int(val, &bcons->pathlen)) -+ goto err; -+ } else { -+ X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ } -+ return bcons; -+ err: -+ BASIC_CONSTRAINTS_free(bcons); -+ return NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_bitst.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_bitst.c -new file mode 100644 -index 0000000..4802116 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_bitst.c -@@ -0,0 +1,93 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include "ext_dat.h" -+ -+static BIT_STRING_BITNAME ns_cert_type_table[] = { -+ {0, "SSL Client", "client"}, -+ {1, "SSL Server", "server"}, -+ {2, "S/MIME", "email"}, -+ {3, "Object Signing", "objsign"}, -+ {4, "Unused", "reserved"}, -+ {5, "SSL CA", "sslCA"}, -+ {6, "S/MIME CA", "emailCA"}, -+ {7, "Object Signing CA", "objCA"}, -+ {-1, NULL, NULL} -+}; -+ -+static BIT_STRING_BITNAME key_usage_type_table[] = { -+ {0, "Digital Signature", "digitalSignature"}, -+ {1, "Non Repudiation", "nonRepudiation"}, -+ {2, "Key Encipherment", "keyEncipherment"}, -+ {3, "Data Encipherment", "dataEncipherment"}, -+ {4, "Key Agreement", "keyAgreement"}, -+ {5, "Certificate Sign", "keyCertSign"}, -+ {6, "CRL Sign", "cRLSign"}, -+ {7, "Encipher Only", "encipherOnly"}, -+ {8, "Decipher Only", "decipherOnly"}, -+ {-1, NULL, NULL} -+}; -+ -+const X509V3_EXT_METHOD v3_nscert = -+EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table); -+const X509V3_EXT_METHOD v3_key_usage = -+EXT_BITSTRING(NID_key_usage, key_usage_type_table); -+ -+STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, -+ ASN1_BIT_STRING *bits, -+ STACK_OF(CONF_VALUE) *ret) -+{ -+ BIT_STRING_BITNAME *bnam; -+ for (bnam = method->usr_data; bnam->lname; bnam++) { -+ if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) -+ X509V3_add_value(bnam->lname, NULL, &ret); -+ } -+ return ret; -+} -+ -+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval) -+{ -+ CONF_VALUE *val; -+ ASN1_BIT_STRING *bs; -+ int i; -+ BIT_STRING_BITNAME *bnam; -+ if ((bs = ASN1_BIT_STRING_new()) == NULL) { -+ X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ val = sk_CONF_VALUE_value(nval, i); -+ for (bnam = method->usr_data; bnam->lname; bnam++) { -+ if (strcmp(bnam->sname, val->name) == 0 -+ || strcmp(bnam->lname, val->name) == 0) { -+ if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) { -+ X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, -+ ERR_R_MALLOC_FAILURE); -+ ASN1_BIT_STRING_free(bs); -+ return NULL; -+ } -+ break; -+ } -+ } -+ if (!bnam->lname) { -+ X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, -+ X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); -+ X509V3_conf_err(val); -+ ASN1_BIT_STRING_free(bs); -+ return NULL; -+ } -+ } -+ return bs; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_conf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_conf.c -new file mode 100644 -index 0000000..f625ff5 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_conf.c -@@ -0,0 +1,507 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* extension creation utilities */ -+ -+#include -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include "internal/x509_int.h" -+#include -+ -+static int v3_check_critical(const char **value); -+static int v3_check_generic(const char **value); -+static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, -+ int crit, const char *value); -+static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, -+ int crit, int type, -+ X509V3_CTX *ctx); -+static char *conf_lhash_get_string(void *db, const char *section, const char *value); -+static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, const char *section); -+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, -+ int ext_nid, int crit, void *ext_struc); -+static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, -+ long *ext_len); -+/* CONF *conf: Config file */ -+/* char *name: Name */ -+/* char *value: Value */ -+X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, -+ const char *value) -+{ -+ int crit; -+ int ext_type; -+ X509_EXTENSION *ret; -+ crit = v3_check_critical(&value); -+ if ((ext_type = v3_check_generic(&value))) -+ return v3_generic_extension(name, value, crit, ext_type, ctx); -+ ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); -+ if (!ret) { -+ X509V3err(X509V3_F_X509V3_EXT_NCONF, X509V3_R_ERROR_IN_EXTENSION); -+ ERR_add_error_data(4, "name=", name, ", value=", value); -+ } -+ return ret; -+} -+ -+/* CONF *conf: Config file */ -+/* char *value: Value */ -+X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, -+ const char *value) -+{ -+ int crit; -+ int ext_type; -+ crit = v3_check_critical(&value); -+ if ((ext_type = v3_check_generic(&value))) -+ return v3_generic_extension(OBJ_nid2sn(ext_nid), -+ value, crit, ext_type, ctx); -+ return do_ext_nconf(conf, ctx, ext_nid, crit, value); -+} -+ -+/* CONF *conf: Config file */ -+/* char *value: Value */ -+static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, -+ int crit, const char *value) -+{ -+ const X509V3_EXT_METHOD *method; -+ X509_EXTENSION *ext; -+ STACK_OF(CONF_VALUE) *nval; -+ void *ext_struc; -+ -+ if (ext_nid == NID_undef) { -+ X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION_NAME); -+ return NULL; -+ } -+ if ((method = X509V3_EXT_get_nid(ext_nid)) == NULL) { -+ X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION); -+ return NULL; -+ } -+ /* Now get internal extension representation based on type */ -+ if (method->v2i) { -+ if (*value == '@') -+ nval = NCONF_get_section(conf, value + 1); -+ else -+ nval = X509V3_parse_list(value); -+ if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) { -+ X509V3err(X509V3_F_DO_EXT_NCONF, -+ X509V3_R_INVALID_EXTENSION_STRING); -+ ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", -+ value); -+ if (*value != '@') -+ sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); -+ return NULL; -+ } -+ ext_struc = method->v2i(method, ctx, nval); -+ if (*value != '@') -+ sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); -+ if (!ext_struc) -+ return NULL; -+ } else if (method->s2i) { -+ if ((ext_struc = method->s2i(method, ctx, value)) == NULL) -+ return NULL; -+ } else if (method->r2i) { -+ if (!ctx->db || !ctx->db_meth) { -+ X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_NO_CONFIG_DATABASE); -+ return NULL; -+ } -+ if ((ext_struc = method->r2i(method, ctx, value)) == NULL) -+ return NULL; -+ } else { -+ X509V3err(X509V3_F_DO_EXT_NCONF, -+ X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); -+ ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid)); -+ return NULL; -+ } -+ -+ ext = do_ext_i2d(method, ext_nid, crit, ext_struc); -+ if (method->it) -+ ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); -+ else -+ method->ext_free(ext_struc); -+ return ext; -+ -+} -+ -+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, -+ int ext_nid, int crit, void *ext_struc) -+{ -+ unsigned char *ext_der = NULL; -+ int ext_len; -+ ASN1_OCTET_STRING *ext_oct = NULL; -+ X509_EXTENSION *ext; -+ /* Convert internal representation to DER */ -+ if (method->it) { -+ ext_der = NULL; -+ ext_len = -+ ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); -+ if (ext_len < 0) -+ goto merr; -+ } else { -+ unsigned char *p; -+ -+ ext_len = method->i2d(ext_struc, NULL); -+ if ((ext_der = OPENSSL_malloc(ext_len)) == NULL) -+ goto merr; -+ p = ext_der; -+ method->i2d(ext_struc, &p); -+ } -+ if ((ext_oct = ASN1_OCTET_STRING_new()) == NULL) -+ goto merr; -+ ext_oct->data = ext_der; -+ ext_der = NULL; -+ ext_oct->length = ext_len; -+ -+ ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); -+ if (!ext) -+ goto merr; -+ ASN1_OCTET_STRING_free(ext_oct); -+ -+ return ext; -+ -+ merr: -+ X509V3err(X509V3_F_DO_EXT_I2D, ERR_R_MALLOC_FAILURE); -+ OPENSSL_free(ext_der); -+ ASN1_OCTET_STRING_free(ext_oct); -+ return NULL; -+ -+} -+ -+/* Given an internal structure, nid and critical flag create an extension */ -+ -+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) -+{ -+ const X509V3_EXT_METHOD *method; -+ -+ if ((method = X509V3_EXT_get_nid(ext_nid)) == NULL) { -+ X509V3err(X509V3_F_X509V3_EXT_I2D, X509V3_R_UNKNOWN_EXTENSION); -+ return NULL; -+ } -+ return do_ext_i2d(method, ext_nid, crit, ext_struc); -+} -+ -+/* Check the extension string for critical flag */ -+static int v3_check_critical(const char **value) -+{ -+ const char *p = *value; -+ if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) -+ return 0; -+ p += 9; -+ while (isspace((unsigned char)*p)) -+ p++; -+ *value = p; -+ return 1; -+} -+ -+/* Check extension string for generic extension and return the type */ -+static int v3_check_generic(const char **value) -+{ -+ int gen_type = 0; -+ const char *p = *value; -+ if ((strlen(p) >= 4) && strncmp(p, "DER:", 4) == 0) { -+ p += 4; -+ gen_type = 1; -+ } else if ((strlen(p) >= 5) && strncmp(p, "ASN1:", 5) == 0) { -+ p += 5; -+ gen_type = 2; -+ } else -+ return 0; -+ -+ while (isspace((unsigned char)*p)) -+ p++; -+ *value = p; -+ return gen_type; -+} -+ -+/* Create a generic extension: for now just handle DER type */ -+static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, -+ int crit, int gen_type, -+ X509V3_CTX *ctx) -+{ -+ unsigned char *ext_der = NULL; -+ long ext_len = 0; -+ ASN1_OBJECT *obj = NULL; -+ ASN1_OCTET_STRING *oct = NULL; -+ X509_EXTENSION *extension = NULL; -+ -+ if ((obj = OBJ_txt2obj(ext, 0)) == NULL) { -+ X509V3err(X509V3_F_V3_GENERIC_EXTENSION, -+ X509V3_R_EXTENSION_NAME_ERROR); -+ ERR_add_error_data(2, "name=", ext); -+ goto err; -+ } -+ -+ if (gen_type == 1) -+ ext_der = OPENSSL_hexstr2buf(value, &ext_len); -+ else if (gen_type == 2) -+ ext_der = generic_asn1(value, ctx, &ext_len); -+ -+ if (ext_der == NULL) { -+ X509V3err(X509V3_F_V3_GENERIC_EXTENSION, -+ X509V3_R_EXTENSION_VALUE_ERROR); -+ ERR_add_error_data(2, "value=", value); -+ goto err; -+ } -+ -+ if ((oct = ASN1_OCTET_STRING_new()) == NULL) { -+ X509V3err(X509V3_F_V3_GENERIC_EXTENSION, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ oct->data = ext_der; -+ oct->length = ext_len; -+ ext_der = NULL; -+ -+ extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); -+ -+ err: -+ ASN1_OBJECT_free(obj); -+ ASN1_OCTET_STRING_free(oct); -+ OPENSSL_free(ext_der); -+ return extension; -+ -+} -+ -+static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, -+ long *ext_len) -+{ -+ ASN1_TYPE *typ; -+ unsigned char *ext_der = NULL; -+ typ = ASN1_generate_v3(value, ctx); -+ if (typ == NULL) -+ return NULL; -+ *ext_len = i2d_ASN1_TYPE(typ, &ext_der); -+ ASN1_TYPE_free(typ); -+ return ext_der; -+} -+ -+static void delete_ext(STACK_OF(X509_EXTENSION) *sk, X509_EXTENSION *dext) -+{ -+ int idx; -+ ASN1_OBJECT *obj; -+ obj = X509_EXTENSION_get_object(dext); -+ while ((idx = X509v3_get_ext_by_OBJ(sk, obj, -1)) >= 0) { -+ X509_EXTENSION *tmpext = X509v3_get_ext(sk, idx); -+ X509v3_delete_ext(sk, idx); -+ X509_EXTENSION_free(tmpext); -+ } -+} -+ -+/* -+ * This is the main function: add a bunch of extensions based on a config -+ * file section to an extension STACK. -+ */ -+ -+int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, -+ STACK_OF(X509_EXTENSION) **sk) -+{ -+ X509_EXTENSION *ext; -+ STACK_OF(CONF_VALUE) *nval; -+ CONF_VALUE *val; -+ int i; -+ -+ if ((nval = NCONF_get_section(conf, section)) == NULL) -+ return 0; -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ val = sk_CONF_VALUE_value(nval, i); -+ if ((ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)) == NULL) -+ return 0; -+ if (ctx->flags == X509V3_CTX_REPLACE) -+ delete_ext(*sk, ext); -+ if (sk) -+ X509v3_add_ext(sk, ext, -1); -+ X509_EXTENSION_free(ext); -+ } -+ return 1; -+} -+ -+/* -+ * Convenience functions to add extensions to a certificate, CRL and request -+ */ -+ -+int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, -+ X509 *cert) -+{ -+ STACK_OF(X509_EXTENSION) **sk = NULL; -+ if (cert) -+ sk = &cert->cert_info.extensions; -+ return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); -+} -+ -+/* Same as above but for a CRL */ -+ -+int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, -+ X509_CRL *crl) -+{ -+ STACK_OF(X509_EXTENSION) **sk = NULL; -+ if (crl) -+ sk = &crl->crl.extensions; -+ return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); -+} -+ -+/* Add extensions to certificate request */ -+ -+int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, -+ X509_REQ *req) -+{ -+ STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; -+ int i; -+ if (req) -+ sk = &extlist; -+ i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); -+ if (!i || !sk) -+ return i; -+ i = X509_REQ_add_extensions(req, extlist); -+ sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); -+ return i; -+} -+ -+/* Config database functions */ -+ -+char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section) -+{ -+ if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) { -+ X509V3err(X509V3_F_X509V3_GET_STRING, X509V3_R_OPERATION_NOT_DEFINED); -+ return NULL; -+ } -+ if (ctx->db_meth->get_string) -+ return ctx->db_meth->get_string(ctx->db, name, section); -+ return NULL; -+} -+ -+STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section) -+{ -+ if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { -+ X509V3err(X509V3_F_X509V3_GET_SECTION, -+ X509V3_R_OPERATION_NOT_DEFINED); -+ return NULL; -+ } -+ if (ctx->db_meth->get_section) -+ return ctx->db_meth->get_section(ctx->db, section); -+ return NULL; -+} -+ -+void X509V3_string_free(X509V3_CTX *ctx, char *str) -+{ -+ if (!str) -+ return; -+ if (ctx->db_meth->free_string) -+ ctx->db_meth->free_string(ctx->db, str); -+} -+ -+void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) -+{ -+ if (!section) -+ return; -+ if (ctx->db_meth->free_section) -+ ctx->db_meth->free_section(ctx->db, section); -+} -+ -+static char *nconf_get_string(void *db, const char *section, const char *value) -+{ -+ return NCONF_get_string(db, section, value); -+} -+ -+static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, const char *section) -+{ -+ return NCONF_get_section(db, section); -+} -+ -+static X509V3_CONF_METHOD nconf_method = { -+ nconf_get_string, -+ nconf_get_section, -+ NULL, -+ NULL -+}; -+ -+void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) -+{ -+ ctx->db_meth = &nconf_method; -+ ctx->db = conf; -+} -+ -+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, -+ X509_CRL *crl, int flags) -+{ -+ ctx->issuer_cert = issuer; -+ ctx->subject_cert = subj; -+ ctx->crl = crl; -+ ctx->subject_req = req; -+ ctx->flags = flags; -+} -+ -+/* Old conf compatibility functions */ -+ -+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, -+ const char *name, const char *value) -+{ -+ CONF ctmp; -+ CONF_set_nconf(&ctmp, conf); -+ return X509V3_EXT_nconf(&ctmp, ctx, name, value); -+} -+ -+/* LHASH *conf: Config file */ -+/* char *value: Value */ -+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, -+ X509V3_CTX *ctx, int ext_nid, const char *value) -+{ -+ CONF ctmp; -+ CONF_set_nconf(&ctmp, conf); -+ return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value); -+} -+ -+static char *conf_lhash_get_string(void *db, const char *section, const char *value) -+{ -+ return CONF_get_string(db, section, value); -+} -+ -+static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, const char *section) -+{ -+ return CONF_get_section(db, section); -+} -+ -+static X509V3_CONF_METHOD conf_lhash_method = { -+ conf_lhash_get_string, -+ conf_lhash_get_section, -+ NULL, -+ NULL -+}; -+ -+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) -+{ -+ ctx->db_meth = &conf_lhash_method; -+ ctx->db = lhash; -+} -+ -+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, -+ const char *section, X509 *cert) -+{ -+ CONF ctmp; -+ CONF_set_nconf(&ctmp, conf); -+ return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert); -+} -+ -+/* Same as above but for a CRL */ -+ -+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, -+ const char *section, X509_CRL *crl) -+{ -+ CONF ctmp; -+ CONF_set_nconf(&ctmp, conf); -+ return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl); -+} -+ -+/* Add extensions to certificate request */ -+ -+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, -+ const char *section, X509_REQ *req) -+{ -+ CONF ctmp; -+ CONF_set_nconf(&ctmp, conf); -+ return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_cpols.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_cpols.c -new file mode 100644 -index 0000000..f717e13 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_cpols.c -@@ -0,0 +1,441 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+ -+#include "pcy_int.h" -+#include "ext_dat.h" -+ -+/* Certificate policies extension support: this one is a bit complex... */ -+ -+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, -+ BIO *out, int indent); -+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, const char *value); -+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, -+ int indent); -+static void print_notice(BIO *out, USERNOTICE *notice, int indent); -+static POLICYINFO *policy_section(X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *polstrs, int ia5org); -+static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *unot, int ia5org); -+static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); -+ -+const X509V3_EXT_METHOD v3_cpols = { -+ NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES), -+ 0, 0, 0, 0, -+ 0, 0, -+ 0, 0, -+ (X509V3_EXT_I2R)i2r_certpol, -+ (X509V3_EXT_R2I)r2i_certpol, -+ NULL -+}; -+ -+ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO) -+ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES) -+ -+IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) -+ -+ASN1_SEQUENCE(POLICYINFO) = { -+ ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT), -+ ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO) -+} ASN1_SEQUENCE_END(POLICYINFO) -+ -+IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO) -+ -+ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY); -+ -+ASN1_ADB(POLICYQUALINFO) = { -+ ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)), -+ ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE)) -+} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL); -+ -+ASN1_SEQUENCE(POLICYQUALINFO) = { -+ ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT), -+ ASN1_ADB_OBJECT(POLICYQUALINFO) -+} ASN1_SEQUENCE_END(POLICYQUALINFO) -+ -+IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO) -+ -+ASN1_SEQUENCE(USERNOTICE) = { -+ ASN1_OPT(USERNOTICE, noticeref, NOTICEREF), -+ ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT) -+} ASN1_SEQUENCE_END(USERNOTICE) -+ -+IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE) -+ -+ASN1_SEQUENCE(NOTICEREF) = { -+ ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT), -+ ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER) -+} ASN1_SEQUENCE_END(NOTICEREF) -+ -+IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF) -+ -+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, const char *value) -+{ -+ STACK_OF(POLICYINFO) *pols = NULL; -+ char *pstr; -+ POLICYINFO *pol; -+ ASN1_OBJECT *pobj; -+ STACK_OF(CONF_VALUE) *vals; -+ CONF_VALUE *cnf; -+ int i, ia5org; -+ pols = sk_POLICYINFO_new_null(); -+ if (pols == NULL) { -+ X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ vals = X509V3_parse_list(value); -+ if (vals == NULL) { -+ X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB); -+ goto err; -+ } -+ ia5org = 0; -+ for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { -+ cnf = sk_CONF_VALUE_value(vals, i); -+ if (cnf->value || !cnf->name) { -+ X509V3err(X509V3_F_R2I_CERTPOL, -+ X509V3_R_INVALID_POLICY_IDENTIFIER); -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ pstr = cnf->name; -+ if (strcmp(pstr, "ia5org") == 0) { -+ ia5org = 1; -+ continue; -+ } else if (*pstr == '@') { -+ STACK_OF(CONF_VALUE) *polsect; -+ polsect = X509V3_get_section(ctx, pstr + 1); -+ if (!polsect) { -+ X509V3err(X509V3_F_R2I_CERTPOL, X509V3_R_INVALID_SECTION); -+ -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ pol = policy_section(ctx, polsect, ia5org); -+ X509V3_section_free(ctx, polsect); -+ if (pol == NULL) -+ goto err; -+ } else { -+ if ((pobj = OBJ_txt2obj(cnf->name, 0)) == NULL) { -+ X509V3err(X509V3_F_R2I_CERTPOL, -+ X509V3_R_INVALID_OBJECT_IDENTIFIER); -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ pol = POLICYINFO_new(); -+ if (pol == NULL) { -+ X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); -+ ASN1_OBJECT_free(pobj); -+ goto err; -+ } -+ pol->policyid = pobj; -+ } -+ if (!sk_POLICYINFO_push(pols, pol)) { -+ POLICYINFO_free(pol); -+ X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } -+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); -+ return pols; -+ err: -+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); -+ sk_POLICYINFO_pop_free(pols, POLICYINFO_free); -+ return NULL; -+} -+ -+static POLICYINFO *policy_section(X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *polstrs, int ia5org) -+{ -+ int i; -+ CONF_VALUE *cnf; -+ POLICYINFO *pol; -+ POLICYQUALINFO *qual; -+ -+ if ((pol = POLICYINFO_new()) == NULL) -+ goto merr; -+ for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { -+ cnf = sk_CONF_VALUE_value(polstrs, i); -+ if (strcmp(cnf->name, "policyIdentifier") == 0) { -+ ASN1_OBJECT *pobj; -+ if ((pobj = OBJ_txt2obj(cnf->value, 0)) == NULL) { -+ X509V3err(X509V3_F_POLICY_SECTION, -+ X509V3_R_INVALID_OBJECT_IDENTIFIER); -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ pol->policyid = pobj; -+ -+ } else if (!name_cmp(cnf->name, "CPS")) { -+ if (pol->qualifiers == NULL) -+ pol->qualifiers = sk_POLICYQUALINFO_new_null(); -+ if ((qual = POLICYQUALINFO_new()) == NULL) -+ goto merr; -+ if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) -+ goto merr; -+ if ((qual->pqualid = OBJ_nid2obj(NID_id_qt_cps)) == NULL) { -+ X509V3err(X509V3_F_POLICY_SECTION, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ if ((qual->d.cpsuri = ASN1_IA5STRING_new()) == NULL) -+ goto merr; -+ if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, -+ strlen(cnf->value))) -+ goto merr; -+ } else if (!name_cmp(cnf->name, "userNotice")) { -+ STACK_OF(CONF_VALUE) *unot; -+ if (*cnf->value != '@') { -+ X509V3err(X509V3_F_POLICY_SECTION, -+ X509V3_R_EXPECTED_A_SECTION_NAME); -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ unot = X509V3_get_section(ctx, cnf->value + 1); -+ if (!unot) { -+ X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_SECTION); -+ -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ qual = notice_section(ctx, unot, ia5org); -+ X509V3_section_free(ctx, unot); -+ if (!qual) -+ goto err; -+ if (!pol->qualifiers) -+ pol->qualifiers = sk_POLICYQUALINFO_new_null(); -+ if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) -+ goto merr; -+ } else { -+ X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_OPTION); -+ -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ } -+ if (!pol->policyid) { -+ X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_NO_POLICY_IDENTIFIER); -+ goto err; -+ } -+ -+ return pol; -+ -+ merr: -+ X509V3err(X509V3_F_POLICY_SECTION, ERR_R_MALLOC_FAILURE); -+ -+ err: -+ POLICYINFO_free(pol); -+ return NULL; -+ -+} -+ -+static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *unot, int ia5org) -+{ -+ int i, ret; -+ CONF_VALUE *cnf; -+ USERNOTICE *not; -+ POLICYQUALINFO *qual; -+ -+ if ((qual = POLICYQUALINFO_new()) == NULL) -+ goto merr; -+ if ((qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice)) == NULL) { -+ X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_INTERNAL_ERROR); -+ goto err; -+ } -+ if ((not = USERNOTICE_new()) == NULL) -+ goto merr; -+ qual->d.usernotice = not; -+ for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { -+ cnf = sk_CONF_VALUE_value(unot, i); -+ if (strcmp(cnf->name, "explicitText") == 0) { -+ if ((not->exptext = ASN1_VISIBLESTRING_new()) == NULL) -+ goto merr; -+ if (!ASN1_STRING_set(not->exptext, cnf->value, -+ strlen(cnf->value))) -+ goto merr; -+ } else if (strcmp(cnf->name, "organization") == 0) { -+ NOTICEREF *nref; -+ if (!not->noticeref) { -+ if ((nref = NOTICEREF_new()) == NULL) -+ goto merr; -+ not->noticeref = nref; -+ } else -+ nref = not->noticeref; -+ if (ia5org) -+ nref->organization->type = V_ASN1_IA5STRING; -+ else -+ nref->organization->type = V_ASN1_VISIBLESTRING; -+ if (!ASN1_STRING_set(nref->organization, cnf->value, -+ strlen(cnf->value))) -+ goto merr; -+ } else if (strcmp(cnf->name, "noticeNumbers") == 0) { -+ NOTICEREF *nref; -+ STACK_OF(CONF_VALUE) *nos; -+ if (!not->noticeref) { -+ if ((nref = NOTICEREF_new()) == NULL) -+ goto merr; -+ not->noticeref = nref; -+ } else -+ nref = not->noticeref; -+ nos = X509V3_parse_list(cnf->value); -+ if (!nos || !sk_CONF_VALUE_num(nos)) { -+ X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_NUMBERS); -+ X509V3_conf_err(cnf); -+ sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); -+ goto err; -+ } -+ ret = nref_nos(nref->noticenos, nos); -+ sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); -+ if (!ret) -+ goto err; -+ } else { -+ X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_OPTION); -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ } -+ -+ if (not->noticeref && -+ (!not->noticeref->noticenos || !not->noticeref->organization)) { -+ X509V3err(X509V3_F_NOTICE_SECTION, -+ X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); -+ goto err; -+ } -+ -+ return qual; -+ -+ merr: -+ X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_MALLOC_FAILURE); -+ -+ err: -+ POLICYQUALINFO_free(qual); -+ return NULL; -+} -+ -+static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) -+{ -+ CONF_VALUE *cnf; -+ ASN1_INTEGER *aint; -+ -+ int i; -+ -+ for (i = 0; i < sk_CONF_VALUE_num(nos); i++) { -+ cnf = sk_CONF_VALUE_value(nos, i); -+ if ((aint = s2i_ASN1_INTEGER(NULL, cnf->name)) == NULL) { -+ X509V3err(X509V3_F_NREF_NOS, X509V3_R_INVALID_NUMBER); -+ goto err; -+ } -+ if (!sk_ASN1_INTEGER_push(nnums, aint)) -+ goto merr; -+ } -+ return 1; -+ -+ merr: -+ ASN1_INTEGER_free(aint); -+ X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE); -+ -+ err: -+ return 0; -+} -+ -+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, -+ BIO *out, int indent) -+{ -+ int i; -+ POLICYINFO *pinfo; -+ /* First print out the policy OIDs */ -+ for (i = 0; i < sk_POLICYINFO_num(pol); i++) { -+ pinfo = sk_POLICYINFO_value(pol, i); -+ BIO_printf(out, "%*sPolicy: ", indent, ""); -+ i2a_ASN1_OBJECT(out, pinfo->policyid); -+ BIO_puts(out, "\n"); -+ if (pinfo->qualifiers) -+ print_qualifiers(out, pinfo->qualifiers, indent + 2); -+ } -+ return 1; -+} -+ -+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, -+ int indent) -+{ -+ POLICYQUALINFO *qualinfo; -+ int i; -+ for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { -+ qualinfo = sk_POLICYQUALINFO_value(quals, i); -+ switch (OBJ_obj2nid(qualinfo->pqualid)) { -+ case NID_id_qt_cps: -+ BIO_printf(out, "%*sCPS: %s\n", indent, "", -+ qualinfo->d.cpsuri->data); -+ break; -+ -+ case NID_id_qt_unotice: -+ BIO_printf(out, "%*sUser Notice:\n", indent, ""); -+ print_notice(out, qualinfo->d.usernotice, indent + 2); -+ break; -+ -+ default: -+ BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, ""); -+ -+ i2a_ASN1_OBJECT(out, qualinfo->pqualid); -+ BIO_puts(out, "\n"); -+ break; -+ } -+ } -+} -+ -+static void print_notice(BIO *out, USERNOTICE *notice, int indent) -+{ -+ int i; -+ if (notice->noticeref) { -+ NOTICEREF *ref; -+ ref = notice->noticeref; -+ BIO_printf(out, "%*sOrganization: %s\n", indent, "", -+ ref->organization->data); -+ BIO_printf(out, "%*sNumber%s: ", indent, "", -+ sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); -+ for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { -+ ASN1_INTEGER *num; -+ char *tmp; -+ num = sk_ASN1_INTEGER_value(ref->noticenos, i); -+ if (i) -+ BIO_puts(out, ", "); -+ tmp = i2s_ASN1_INTEGER(NULL, num); -+ BIO_puts(out, tmp); -+ OPENSSL_free(tmp); -+ } -+ BIO_puts(out, "\n"); -+ } -+ if (notice->exptext) -+ BIO_printf(out, "%*sExplicit Text: %s\n", indent, "", -+ notice->exptext->data); -+} -+ -+void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) -+{ -+ const X509_POLICY_DATA *dat = node->data; -+ -+ BIO_printf(out, "%*sPolicy: ", indent, ""); -+ -+ i2a_ASN1_OBJECT(out, dat->valid_policy); -+ BIO_puts(out, "\n"); -+ BIO_printf(out, "%*s%s\n", indent + 2, "", -+ node_data_critical(dat) ? "Critical" : "Non Critical"); -+ if (dat->qualifier_set) -+ print_qualifiers(out, dat->qualifier_set, indent + 2); -+ else -+ BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_crld.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_crld.c -new file mode 100644 -index 0000000..c4c77f1 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_crld.c -@@ -0,0 +1,509 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+ -+#include "internal/x509_int.h" -+#include "ext_dat.h" -+ -+static void *v2i_crld(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -+static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, -+ int indent); -+ -+const X509V3_EXT_METHOD v3_crld = { -+ NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), -+ 0, 0, 0, 0, -+ 0, 0, -+ 0, -+ v2i_crld, -+ i2r_crldp, 0, -+ NULL -+}; -+ -+const X509V3_EXT_METHOD v3_freshest_crl = { -+ NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), -+ 0, 0, 0, 0, -+ 0, 0, -+ 0, -+ v2i_crld, -+ i2r_crldp, 0, -+ NULL -+}; -+ -+static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, -+ char *sect) -+{ -+ STACK_OF(CONF_VALUE) *gnsect; -+ STACK_OF(GENERAL_NAME) *gens; -+ if (*sect == '@') -+ gnsect = X509V3_get_section(ctx, sect + 1); -+ else -+ gnsect = X509V3_parse_list(sect); -+ if (!gnsect) { -+ X509V3err(X509V3_F_GNAMES_FROM_SECTNAME, X509V3_R_SECTION_NOT_FOUND); -+ return NULL; -+ } -+ gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); -+ if (*sect == '@') -+ X509V3_section_free(ctx, gnsect); -+ else -+ sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); -+ return gens; -+} -+ -+static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, -+ CONF_VALUE *cnf) -+{ -+ STACK_OF(GENERAL_NAME) *fnm = NULL; -+ STACK_OF(X509_NAME_ENTRY) *rnm = NULL; -+ -+ if (strncmp(cnf->name, "fullname", 9) == 0) { -+ fnm = gnames_from_sectname(ctx, cnf->value); -+ if (!fnm) -+ goto err; -+ } else if (strcmp(cnf->name, "relativename") == 0) { -+ int ret; -+ STACK_OF(CONF_VALUE) *dnsect; -+ X509_NAME *nm; -+ nm = X509_NAME_new(); -+ if (nm == NULL) -+ return -1; -+ dnsect = X509V3_get_section(ctx, cnf->value); -+ if (!dnsect) { -+ X509V3err(X509V3_F_SET_DIST_POINT_NAME, -+ X509V3_R_SECTION_NOT_FOUND); -+ return -1; -+ } -+ ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); -+ X509V3_section_free(ctx, dnsect); -+ rnm = nm->entries; -+ nm->entries = NULL; -+ X509_NAME_free(nm); -+ if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) -+ goto err; -+ /* -+ * Since its a name fragment can't have more than one RDNSequence -+ */ -+ if (sk_X509_NAME_ENTRY_value(rnm, -+ sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { -+ X509V3err(X509V3_F_SET_DIST_POINT_NAME, -+ X509V3_R_INVALID_MULTIPLE_RDNS); -+ goto err; -+ } -+ } else -+ return 0; -+ -+ if (*pdp) { -+ X509V3err(X509V3_F_SET_DIST_POINT_NAME, -+ X509V3_R_DISTPOINT_ALREADY_SET); -+ goto err; -+ } -+ -+ *pdp = DIST_POINT_NAME_new(); -+ if (*pdp == NULL) -+ goto err; -+ if (fnm) { -+ (*pdp)->type = 0; -+ (*pdp)->name.fullname = fnm; -+ } else { -+ (*pdp)->type = 1; -+ (*pdp)->name.relativename = rnm; -+ } -+ -+ return 1; -+ -+ err: -+ sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); -+ sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); -+ return -1; -+} -+ -+static const BIT_STRING_BITNAME reason_flags[] = { -+ {0, "Unused", "unused"}, -+ {1, "Key Compromise", "keyCompromise"}, -+ {2, "CA Compromise", "CACompromise"}, -+ {3, "Affiliation Changed", "affiliationChanged"}, -+ {4, "Superseded", "superseded"}, -+ {5, "Cessation Of Operation", "cessationOfOperation"}, -+ {6, "Certificate Hold", "certificateHold"}, -+ {7, "Privilege Withdrawn", "privilegeWithdrawn"}, -+ {8, "AA Compromise", "AACompromise"}, -+ {-1, NULL, NULL} -+}; -+ -+static int set_reasons(ASN1_BIT_STRING **preas, char *value) -+{ -+ STACK_OF(CONF_VALUE) *rsk = NULL; -+ const BIT_STRING_BITNAME *pbn; -+ const char *bnam; -+ int i, ret = 0; -+ rsk = X509V3_parse_list(value); -+ if (rsk == NULL) -+ return 0; -+ if (*preas != NULL) -+ goto err; -+ for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { -+ bnam = sk_CONF_VALUE_value(rsk, i)->name; -+ if (*preas == NULL) { -+ *preas = ASN1_BIT_STRING_new(); -+ if (*preas == NULL) -+ goto err; -+ } -+ for (pbn = reason_flags; pbn->lname; pbn++) { -+ if (strcmp(pbn->sname, bnam) == 0) { -+ if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) -+ goto err; -+ break; -+ } -+ } -+ if (!pbn->lname) -+ goto err; -+ } -+ ret = 1; -+ -+ err: -+ sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); -+ return ret; -+} -+ -+static int print_reasons(BIO *out, const char *rname, -+ ASN1_BIT_STRING *rflags, int indent) -+{ -+ int first = 1; -+ const BIT_STRING_BITNAME *pbn; -+ BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); -+ for (pbn = reason_flags; pbn->lname; pbn++) { -+ if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { -+ if (first) -+ first = 0; -+ else -+ BIO_puts(out, ", "); -+ BIO_puts(out, pbn->lname); -+ } -+ } -+ if (first) -+ BIO_puts(out, "\n"); -+ else -+ BIO_puts(out, "\n"); -+ return 1; -+} -+ -+static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval) -+{ -+ int i; -+ CONF_VALUE *cnf; -+ DIST_POINT *point = NULL; -+ point = DIST_POINT_new(); -+ if (point == NULL) -+ goto err; -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ int ret; -+ cnf = sk_CONF_VALUE_value(nval, i); -+ ret = set_dist_point_name(&point->distpoint, ctx, cnf); -+ if (ret > 0) -+ continue; -+ if (ret < 0) -+ goto err; -+ if (strcmp(cnf->name, "reasons") == 0) { -+ if (!set_reasons(&point->reasons, cnf->value)) -+ goto err; -+ } else if (strcmp(cnf->name, "CRLissuer") == 0) { -+ point->CRLissuer = gnames_from_sectname(ctx, cnf->value); -+ if (!point->CRLissuer) -+ goto err; -+ } -+ } -+ -+ return point; -+ -+ err: -+ DIST_POINT_free(point); -+ return NULL; -+} -+ -+static void *v2i_crld(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -+{ -+ STACK_OF(DIST_POINT) *crld = NULL; -+ GENERAL_NAMES *gens = NULL; -+ GENERAL_NAME *gen = NULL; -+ CONF_VALUE *cnf; -+ int i; -+ -+ if ((crld = sk_DIST_POINT_new_null()) == NULL) -+ goto merr; -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ DIST_POINT *point; -+ cnf = sk_CONF_VALUE_value(nval, i); -+ if (!cnf->value) { -+ STACK_OF(CONF_VALUE) *dpsect; -+ dpsect = X509V3_get_section(ctx, cnf->name); -+ if (!dpsect) -+ goto err; -+ point = crldp_from_section(ctx, dpsect); -+ X509V3_section_free(ctx, dpsect); -+ if (!point) -+ goto err; -+ if (!sk_DIST_POINT_push(crld, point)) { -+ DIST_POINT_free(point); -+ goto merr; -+ } -+ } else { -+ if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) -+ goto err; -+ if ((gens = GENERAL_NAMES_new()) == NULL) -+ goto merr; -+ if (!sk_GENERAL_NAME_push(gens, gen)) -+ goto merr; -+ gen = NULL; -+ if ((point = DIST_POINT_new()) == NULL) -+ goto merr; -+ if (!sk_DIST_POINT_push(crld, point)) { -+ DIST_POINT_free(point); -+ goto merr; -+ } -+ if ((point->distpoint = DIST_POINT_NAME_new()) == NULL) -+ goto merr; -+ point->distpoint->name.fullname = gens; -+ point->distpoint->type = 0; -+ gens = NULL; -+ } -+ } -+ return crld; -+ -+ merr: -+ X509V3err(X509V3_F_V2I_CRLD, ERR_R_MALLOC_FAILURE); -+ err: -+ GENERAL_NAME_free(gen); -+ GENERAL_NAMES_free(gens); -+ sk_DIST_POINT_pop_free(crld, DIST_POINT_free); -+ return NULL; -+} -+ -+static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, -+ void *exarg) -+{ -+ DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; -+ -+ switch (operation) { -+ case ASN1_OP_NEW_POST: -+ dpn->dpname = NULL; -+ break; -+ -+ case ASN1_OP_FREE_POST: -+ X509_NAME_free(dpn->dpname); -+ break; -+ } -+ return 1; -+} -+ -+ -+ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = { -+ ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), -+ ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1) -+} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type) -+ -+ -+IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) -+ -+ASN1_SEQUENCE(DIST_POINT) = { -+ ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), -+ ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1), -+ ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2) -+} ASN1_SEQUENCE_END(DIST_POINT) -+ -+IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT) -+ -+ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT) -+ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) -+ -+IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) -+ -+ASN1_SEQUENCE(ISSUING_DIST_POINT) = { -+ ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0), -+ ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1), -+ ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2), -+ ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3), -+ ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4), -+ ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5) -+} ASN1_SEQUENCE_END(ISSUING_DIST_POINT) -+ -+IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT) -+ -+static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, -+ int indent); -+static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval); -+ -+const X509V3_EXT_METHOD v3_idp = { -+ NID_issuing_distribution_point, X509V3_EXT_MULTILINE, -+ ASN1_ITEM_ref(ISSUING_DIST_POINT), -+ 0, 0, 0, 0, -+ 0, 0, -+ 0, -+ v2i_idp, -+ i2r_idp, 0, -+ NULL -+}; -+ -+static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval) -+{ -+ ISSUING_DIST_POINT *idp = NULL; -+ CONF_VALUE *cnf; -+ char *name, *val; -+ int i, ret; -+ idp = ISSUING_DIST_POINT_new(); -+ if (idp == NULL) -+ goto merr; -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ cnf = sk_CONF_VALUE_value(nval, i); -+ name = cnf->name; -+ val = cnf->value; -+ ret = set_dist_point_name(&idp->distpoint, ctx, cnf); -+ if (ret > 0) -+ continue; -+ if (ret < 0) -+ goto err; -+ if (strcmp(name, "onlyuser") == 0) { -+ if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) -+ goto err; -+ } else if (strcmp(name, "onlyCA") == 0) { -+ if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) -+ goto err; -+ } else if (strcmp(name, "onlyAA") == 0) { -+ if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) -+ goto err; -+ } else if (strcmp(name, "indirectCRL") == 0) { -+ if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) -+ goto err; -+ } else if (strcmp(name, "onlysomereasons") == 0) { -+ if (!set_reasons(&idp->onlysomereasons, val)) -+ goto err; -+ } else { -+ X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME); -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ } -+ return idp; -+ -+ merr: -+ X509V3err(X509V3_F_V2I_IDP, ERR_R_MALLOC_FAILURE); -+ err: -+ ISSUING_DIST_POINT_free(idp); -+ return NULL; -+} -+ -+static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) -+{ -+ int i; -+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { -+ BIO_printf(out, "%*s", indent + 2, ""); -+ GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); -+ BIO_puts(out, "\n"); -+ } -+ return 1; -+} -+ -+static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) -+{ -+ if (dpn->type == 0) { -+ BIO_printf(out, "%*sFull Name:\n", indent, ""); -+ print_gens(out, dpn->name.fullname, indent); -+ } else { -+ X509_NAME ntmp; -+ ntmp.entries = dpn->name.relativename; -+ BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, ""); -+ X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); -+ BIO_puts(out, "\n"); -+ } -+ return 1; -+} -+ -+static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, -+ int indent) -+{ -+ ISSUING_DIST_POINT *idp = pidp; -+ if (idp->distpoint) -+ print_distpoint(out, idp->distpoint, indent); -+ if (idp->onlyuser > 0) -+ BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); -+ if (idp->onlyCA > 0) -+ BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); -+ if (idp->indirectCRL > 0) -+ BIO_printf(out, "%*sIndirect CRL\n", indent, ""); -+ if (idp->onlysomereasons) -+ print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent); -+ if (idp->onlyattr > 0) -+ BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); -+ if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) -+ && (idp->indirectCRL <= 0) && !idp->onlysomereasons -+ && (idp->onlyattr <= 0)) -+ BIO_printf(out, "%*s\n", indent, ""); -+ -+ return 1; -+} -+ -+static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, -+ int indent) -+{ -+ STACK_OF(DIST_POINT) *crld = pcrldp; -+ DIST_POINT *point; -+ int i; -+ for (i = 0; i < sk_DIST_POINT_num(crld); i++) { -+ BIO_puts(out, "\n"); -+ point = sk_DIST_POINT_value(crld, i); -+ if (point->distpoint) -+ print_distpoint(out, point->distpoint, indent); -+ if (point->reasons) -+ print_reasons(out, "Reasons", point->reasons, indent); -+ if (point->CRLissuer) { -+ BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); -+ print_gens(out, point->CRLissuer, indent); -+ } -+ } -+ return 1; -+} -+ -+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) -+{ -+ int i; -+ STACK_OF(X509_NAME_ENTRY) *frag; -+ X509_NAME_ENTRY *ne; -+ if (!dpn || (dpn->type != 1)) -+ return 1; -+ frag = dpn->name.relativename; -+ dpn->dpname = X509_NAME_dup(iname); -+ if (!dpn->dpname) -+ return 0; -+ for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { -+ ne = sk_X509_NAME_ENTRY_value(frag, i); -+ if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { -+ X509_NAME_free(dpn->dpname); -+ dpn->dpname = NULL; -+ return 0; -+ } -+ } -+ /* generate cached encoding of name */ -+ if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { -+ X509_NAME_free(dpn->dpname); -+ dpn->dpname = NULL; -+ return 0; -+ } -+ return 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_enum.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_enum.c -new file mode 100644 -index 0000000..f39cb5a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_enum.c -@@ -0,0 +1,53 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include "ext_dat.h" -+ -+static ENUMERATED_NAMES crl_reasons[] = { -+ {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"}, -+ {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"}, -+ {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"}, -+ {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", -+ "affiliationChanged"}, -+ {CRL_REASON_SUPERSEDED, "Superseded", "superseded"}, -+ {CRL_REASON_CESSATION_OF_OPERATION, -+ "Cessation Of Operation", "cessationOfOperation"}, -+ {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"}, -+ {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"}, -+ {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", -+ "privilegeWithdrawn"}, -+ {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"}, -+ {-1, NULL, NULL} -+}; -+ -+const X509V3_EXT_METHOD v3_crl_reason = { -+ NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED), -+ 0, 0, 0, 0, -+ (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, -+ 0, -+ 0, 0, 0, 0, -+ crl_reasons -+}; -+ -+char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, -+ const ASN1_ENUMERATED *e) -+{ -+ ENUMERATED_NAMES *enam; -+ long strval; -+ -+ strval = ASN1_ENUMERATED_get(e); -+ for (enam = method->usr_data; enam->lname; enam++) { -+ if (strval == enam->bitnum) -+ return OPENSSL_strdup(enam->lname); -+ } -+ return i2s_ASN1_ENUMERATED(method, e); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_extku.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_extku.c -new file mode 100644 -index 0000000..bae755e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_extku.c -@@ -0,0 +1,100 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include "ext_dat.h" -+ -+static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval); -+static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD -+ *method, void *eku, STACK_OF(CONF_VALUE) -+ *extlist); -+ -+const X509V3_EXT_METHOD v3_ext_ku = { -+ NID_ext_key_usage, 0, -+ ASN1_ITEM_ref(EXTENDED_KEY_USAGE), -+ 0, 0, 0, 0, -+ 0, 0, -+ i2v_EXTENDED_KEY_USAGE, -+ v2i_EXTENDED_KEY_USAGE, -+ 0, 0, -+ NULL -+}; -+ -+/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */ -+const X509V3_EXT_METHOD v3_ocsp_accresp = { -+ NID_id_pkix_OCSP_acceptableResponses, 0, -+ ASN1_ITEM_ref(EXTENDED_KEY_USAGE), -+ 0, 0, 0, 0, -+ 0, 0, -+ i2v_EXTENDED_KEY_USAGE, -+ v2i_EXTENDED_KEY_USAGE, -+ 0, 0, -+ NULL -+}; -+ -+ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT) -+ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE) -+ -+IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) -+ -+static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD -+ *method, void *a, STACK_OF(CONF_VALUE) -+ *ext_list) -+{ -+ EXTENDED_KEY_USAGE *eku = a; -+ int i; -+ ASN1_OBJECT *obj; -+ char obj_tmp[80]; -+ for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { -+ obj = sk_ASN1_OBJECT_value(eku, i); -+ i2t_ASN1_OBJECT(obj_tmp, 80, obj); -+ X509V3_add_value(NULL, obj_tmp, &ext_list); -+ } -+ return ext_list; -+} -+ -+static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval) -+{ -+ EXTENDED_KEY_USAGE *extku; -+ char *extval; -+ ASN1_OBJECT *objtmp; -+ CONF_VALUE *val; -+ int i; -+ -+ if ((extku = sk_ASN1_OBJECT_new_null()) == NULL) { -+ X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ val = sk_CONF_VALUE_value(nval, i); -+ if (val->value) -+ extval = val->value; -+ else -+ extval = val->name; -+ if ((objtmp = OBJ_txt2obj(extval, 0)) == NULL) { -+ sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); -+ X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, -+ X509V3_R_INVALID_OBJECT_IDENTIFIER); -+ X509V3_conf_err(val); -+ return NULL; -+ } -+ sk_ASN1_OBJECT_push(extku, objtmp); -+ } -+ return extku; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c -new file mode 100644 -index 0000000..8d11997 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_genn.c -@@ -0,0 +1,200 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+ -+ASN1_SEQUENCE(OTHERNAME) = { -+ ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT), -+ /* Maybe have a true ANY DEFINED BY later */ -+ ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0) -+} ASN1_SEQUENCE_END(OTHERNAME) -+ -+IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME) -+ -+ASN1_SEQUENCE(EDIPARTYNAME) = { -+ ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), -+ ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1) -+} ASN1_SEQUENCE_END(EDIPARTYNAME) -+ -+IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME) -+ -+ASN1_CHOICE(GENERAL_NAME) = { -+ ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME), -+ ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL), -+ ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS), -+ /* Don't decode this */ -+ ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400), -+ /* X509_NAME is a CHOICE type so use EXPLICIT */ -+ ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME), -+ ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY), -+ ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI), -+ ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD), -+ ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID) -+} ASN1_CHOICE_END(GENERAL_NAME) -+ -+IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME) -+ -+ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME) -+ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) -+ -+IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) -+ -+GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a) -+{ -+ return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME, -+ (d2i_of_void *)d2i_GENERAL_NAME, -+ (char *)a); -+} -+ -+/* Returns 0 if they are equal, != 0 otherwise. */ -+int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) -+{ -+ int result = -1; -+ -+ if (!a || !b || a->type != b->type) -+ return -1; -+ switch (a->type) { -+ case GEN_X400: -+ case GEN_EDIPARTY: -+ result = ASN1_TYPE_cmp(a->d.other, b->d.other); -+ break; -+ -+ case GEN_OTHERNAME: -+ result = OTHERNAME_cmp(a->d.otherName, b->d.otherName); -+ break; -+ -+ case GEN_EMAIL: -+ case GEN_DNS: -+ case GEN_URI: -+ result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5); -+ break; -+ -+ case GEN_DIRNAME: -+ result = X509_NAME_cmp(a->d.dirn, b->d.dirn); -+ break; -+ -+ case GEN_IPADD: -+ result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); -+ break; -+ -+ case GEN_RID: -+ result = OBJ_cmp(a->d.rid, b->d.rid); -+ break; -+ } -+ return result; -+} -+ -+/* Returns 0 if they are equal, != 0 otherwise. */ -+int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b) -+{ -+ int result = -1; -+ -+ if (!a || !b) -+ return -1; -+ /* Check their type first. */ -+ if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) -+ return result; -+ /* Check the value. */ -+ result = ASN1_TYPE_cmp(a->value, b->value); -+ return result; -+} -+ -+void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) -+{ -+ switch (type) { -+ case GEN_X400: -+ case GEN_EDIPARTY: -+ a->d.other = value; -+ break; -+ -+ case GEN_OTHERNAME: -+ a->d.otherName = value; -+ break; -+ -+ case GEN_EMAIL: -+ case GEN_DNS: -+ case GEN_URI: -+ a->d.ia5 = value; -+ break; -+ -+ case GEN_DIRNAME: -+ a->d.dirn = value; -+ break; -+ -+ case GEN_IPADD: -+ a->d.ip = value; -+ break; -+ -+ case GEN_RID: -+ a->d.rid = value; -+ break; -+ } -+ a->type = type; -+} -+ -+void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype) -+{ -+ if (ptype) -+ *ptype = a->type; -+ switch (a->type) { -+ case GEN_X400: -+ case GEN_EDIPARTY: -+ return a->d.other; -+ -+ case GEN_OTHERNAME: -+ return a->d.otherName; -+ -+ case GEN_EMAIL: -+ case GEN_DNS: -+ case GEN_URI: -+ return a->d.ia5; -+ -+ case GEN_DIRNAME: -+ return a->d.dirn; -+ -+ case GEN_IPADD: -+ return a->d.ip; -+ -+ case GEN_RID: -+ return a->d.rid; -+ -+ default: -+ return NULL; -+ } -+} -+ -+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, -+ ASN1_OBJECT *oid, ASN1_TYPE *value) -+{ -+ OTHERNAME *oth; -+ oth = OTHERNAME_new(); -+ if (oth == NULL) -+ return 0; -+ oth->type_id = oid; -+ oth->value = value; -+ GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); -+ return 1; -+} -+ -+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, -+ ASN1_OBJECT **poid, ASN1_TYPE **pvalue) -+{ -+ if (gen->type != GEN_OTHERNAME) -+ return 0; -+ if (poid) -+ *poid = gen->d.otherName->type_id; -+ if (pvalue) -+ *pvalue = gen->d.otherName->value; -+ return 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ia5.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ia5.c -new file mode 100644 -index 0000000..c1170d4 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ia5.c -@@ -0,0 +1,65 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include "ext_dat.h" -+ -+const X509V3_EXT_METHOD v3_ns_ia5_list[8] = { -+ EXT_IA5STRING(NID_netscape_base_url), -+ EXT_IA5STRING(NID_netscape_revocation_url), -+ EXT_IA5STRING(NID_netscape_ca_revocation_url), -+ EXT_IA5STRING(NID_netscape_renewal_url), -+ EXT_IA5STRING(NID_netscape_ca_policy_url), -+ EXT_IA5STRING(NID_netscape_ssl_server_name), -+ EXT_IA5STRING(NID_netscape_comment), -+ EXT_END -+}; -+ -+char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5) -+{ -+ char *tmp; -+ -+ if (!ia5 || !ia5->length) -+ return NULL; -+ if ((tmp = OPENSSL_malloc(ia5->length + 1)) == NULL) { -+ X509V3err(X509V3_F_I2S_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ memcpy(tmp, ia5->data, ia5->length); -+ tmp[ia5->length] = 0; -+ return tmp; -+} -+ -+ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, const char *str) -+{ -+ ASN1_IA5STRING *ia5; -+ if (!str) { -+ X509V3err(X509V3_F_S2I_ASN1_IA5STRING, -+ X509V3_R_INVALID_NULL_ARGUMENT); -+ return NULL; -+ } -+ if ((ia5 = ASN1_IA5STRING_new()) == NULL) -+ goto err; -+ if (!ASN1_STRING_set((ASN1_STRING *)ia5, str, strlen(str))) { -+ ASN1_IA5STRING_free(ia5); -+ return NULL; -+ } -+#ifdef CHARSET_EBCDIC -+ ebcdic2ascii(ia5->data, ia5->data, ia5->length); -+#endif /* CHARSET_EBCDIC */ -+ return ia5; -+ err: -+ X509V3err(X509V3_F_S2I_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); -+ return NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_info.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_info.c -new file mode 100644 -index 0000000..61ef213 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_info.c -@@ -0,0 +1,157 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "ext_dat.h" -+ -+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD -+ *method, AUTHORITY_INFO_ACCESS -+ *ainfo, STACK_OF(CONF_VALUE) -+ *ret); -+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD -+ *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) -+ *nval); -+ -+const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE, -+ ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), -+ 0, 0, 0, 0, -+ 0, 0, -+ (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, -+ (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, -+ 0, 0, -+ NULL -+}; -+ -+const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE, -+ ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), -+ 0, 0, 0, 0, -+ 0, 0, -+ (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, -+ (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, -+ 0, 0, -+ NULL -+}; -+ -+ASN1_SEQUENCE(ACCESS_DESCRIPTION) = { -+ ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT), -+ ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME) -+} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION) -+ -+IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) -+ -+ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION) -+ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS) -+ -+IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) -+ -+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD -+ *method, AUTHORITY_INFO_ACCESS -+ *ainfo, STACK_OF(CONF_VALUE) -+ *ret) -+{ -+ ACCESS_DESCRIPTION *desc; -+ int i, nlen; -+ char objtmp[80], *ntmp; -+ CONF_VALUE *vtmp; -+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { -+ desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); -+ ret = i2v_GENERAL_NAME(method, desc->location, ret); -+ if (!ret) -+ break; -+ vtmp = sk_CONF_VALUE_value(ret, i); -+ i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method); -+ nlen = strlen(objtmp) + strlen(vtmp->name) + 5; -+ ntmp = OPENSSL_malloc(nlen); -+ if (ntmp == NULL) { -+ X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, -+ ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ OPENSSL_strlcpy(ntmp, objtmp, nlen); -+ OPENSSL_strlcat(ntmp, " - ", nlen); -+ OPENSSL_strlcat(ntmp, vtmp->name, nlen); -+ OPENSSL_free(vtmp->name); -+ vtmp->name = ntmp; -+ -+ } -+ if (!ret) -+ return sk_CONF_VALUE_new_null(); -+ return ret; -+} -+ -+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD -+ *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) -+ *nval) -+{ -+ AUTHORITY_INFO_ACCESS *ainfo = NULL; -+ CONF_VALUE *cnf, ctmp; -+ ACCESS_DESCRIPTION *acc; -+ int i, objlen; -+ char *objtmp, *ptmp; -+ -+ if ((ainfo = sk_ACCESS_DESCRIPTION_new_null()) == NULL) { -+ X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ cnf = sk_CONF_VALUE_value(nval, i); -+ if ((acc = ACCESS_DESCRIPTION_new()) == NULL -+ || !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) { -+ X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, -+ ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ ptmp = strchr(cnf->name, ';'); -+ if (!ptmp) { -+ X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, -+ X509V3_R_INVALID_SYNTAX); -+ goto err; -+ } -+ objlen = ptmp - cnf->name; -+ ctmp.name = ptmp + 1; -+ ctmp.value = cnf->value; -+ if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) -+ goto err; -+ if ((objtmp = OPENSSL_strndup(cnf->name, objlen)) == NULL) { -+ X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, -+ ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ acc->method = OBJ_txt2obj(objtmp, 0); -+ if (!acc->method) { -+ X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, -+ X509V3_R_BAD_OBJECT); -+ ERR_add_error_data(2, "value=", objtmp); -+ OPENSSL_free(objtmp); -+ goto err; -+ } -+ OPENSSL_free(objtmp); -+ -+ } -+ return ainfo; -+ err: -+ sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); -+ return NULL; -+} -+ -+int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a) -+{ -+ i2a_ASN1_OBJECT(bp, a->method); -+ return 2; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_int.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_int.c -new file mode 100644 -index 0000000..690c90e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_int.c -@@ -0,0 +1,43 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include "ext_dat.h" -+ -+const X509V3_EXT_METHOD v3_crl_num = { -+ NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER), -+ 0, 0, 0, 0, -+ (X509V3_EXT_I2S)i2s_ASN1_INTEGER, -+ 0, -+ 0, 0, 0, 0, NULL -+}; -+ -+const X509V3_EXT_METHOD v3_delta_crl = { -+ NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER), -+ 0, 0, 0, 0, -+ (X509V3_EXT_I2S)i2s_ASN1_INTEGER, -+ 0, -+ 0, 0, 0, 0, NULL -+}; -+ -+static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, -+ const char *value) -+{ -+ return s2i_ASN1_INTEGER(meth, value); -+} -+ -+const X509V3_EXT_METHOD v3_inhibit_anyp = { -+ NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER), -+ 0, 0, 0, 0, -+ (X509V3_EXT_I2S)i2s_ASN1_INTEGER, -+ (X509V3_EXT_S2I)s2i_asn1_int, -+ 0, 0, 0, 0, NULL -+}; -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_lib.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_lib.c -new file mode 100644 -index 0000000..a3ca720 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_lib.c -@@ -0,0 +1,360 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* X509 v3 extension utilities */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+ -+#include "ext_dat.h" -+ -+static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; -+ -+static int ext_cmp(const X509V3_EXT_METHOD *const *a, -+ const X509V3_EXT_METHOD *const *b); -+static void ext_list_free(X509V3_EXT_METHOD *ext); -+ -+int X509V3_EXT_add(X509V3_EXT_METHOD *ext) -+{ -+ if (ext_list == NULL -+ && (ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp)) == NULL) { -+ X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { -+ X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ return 1; -+} -+ -+static int ext_cmp(const X509V3_EXT_METHOD *const *a, -+ const X509V3_EXT_METHOD *const *b) -+{ -+ return ((*a)->ext_nid - (*b)->ext_nid); -+} -+ -+DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, -+ const X509V3_EXT_METHOD *, ext); -+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, -+ const X509V3_EXT_METHOD *, ext); -+ -+/* -+ * This table will be searched using OBJ_bsearch so it *must* kept in order -+ * of the ext_nid values. -+ */ -+ -+static const X509V3_EXT_METHOD *standard_exts[] = { -+ &v3_nscert, -+ &v3_ns_ia5_list[0], -+ &v3_ns_ia5_list[1], -+ &v3_ns_ia5_list[2], -+ &v3_ns_ia5_list[3], -+ &v3_ns_ia5_list[4], -+ &v3_ns_ia5_list[5], -+ &v3_ns_ia5_list[6], -+ &v3_skey_id, -+ &v3_key_usage, -+ &v3_pkey_usage_period, -+ &v3_alt[0], -+ &v3_alt[1], -+ &v3_bcons, -+ &v3_crl_num, -+ &v3_cpols, -+ &v3_akey_id, -+ &v3_crld, -+ &v3_ext_ku, -+ &v3_delta_crl, -+ &v3_crl_reason, -+#ifndef OPENSSL_NO_OCSP -+ &v3_crl_invdate, -+#endif -+ &v3_sxnet, -+ &v3_info, -+#ifndef OPENSSL_NO_RFC3779 -+ &v3_addr, -+ &v3_asid, -+#endif -+#ifndef OPENSSL_NO_OCSP -+ &v3_ocsp_nonce, -+ &v3_ocsp_crlid, -+ &v3_ocsp_accresp, -+ &v3_ocsp_nocheck, -+ &v3_ocsp_acutoff, -+ &v3_ocsp_serviceloc, -+#endif -+ &v3_sinfo, -+ &v3_policy_constraints, -+#ifndef OPENSSL_NO_OCSP -+ &v3_crl_hold, -+#endif -+ &v3_pci, -+ &v3_name_constraints, -+ &v3_policy_mappings, -+ &v3_inhibit_anyp, -+ &v3_idp, -+ &v3_alt[2], -+ &v3_freshest_crl, -+#ifndef OPENSSL_NO_CT -+ &v3_ct_scts[0], -+ &v3_ct_scts[1], -+ &v3_ct_scts[2], -+#endif -+ &v3_tls_feature, -+}; -+ -+/* Number of standard extensions */ -+ -+#define STANDARD_EXTENSION_COUNT OSSL_NELEM(standard_exts) -+ -+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) -+{ -+ X509V3_EXT_METHOD tmp; -+ const X509V3_EXT_METHOD *t = &tmp, *const *ret; -+ int idx; -+ if (nid < 0) -+ return NULL; -+ tmp.ext_nid = nid; -+ ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT); -+ if (ret) -+ return *ret; -+ if (!ext_list) -+ return NULL; -+ idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp); -+ if (idx == -1) -+ return NULL; -+ return sk_X509V3_EXT_METHOD_value(ext_list, idx); -+} -+ -+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext) -+{ -+ int nid; -+ if ((nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext))) == NID_undef) -+ return NULL; -+ return X509V3_EXT_get_nid(nid); -+} -+ -+int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist) -+{ -+ for (; extlist->ext_nid != -1; extlist++) -+ if (!X509V3_EXT_add(extlist)) -+ return 0; -+ return 1; -+} -+ -+int X509V3_EXT_add_alias(int nid_to, int nid_from) -+{ -+ const X509V3_EXT_METHOD *ext; -+ X509V3_EXT_METHOD *tmpext; -+ -+ if ((ext = X509V3_EXT_get_nid(nid_from)) == NULL) { -+ X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, X509V3_R_EXTENSION_NOT_FOUND); -+ return 0; -+ } -+ if ((tmpext = OPENSSL_malloc(sizeof(*tmpext))) == NULL) { -+ X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ *tmpext = *ext; -+ tmpext->ext_nid = nid_to; -+ tmpext->ext_flags |= X509V3_EXT_DYNAMIC; -+ return X509V3_EXT_add(tmpext); -+} -+ -+void X509V3_EXT_cleanup(void) -+{ -+ sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free); -+ ext_list = NULL; -+} -+ -+static void ext_list_free(X509V3_EXT_METHOD *ext) -+{ -+ if (ext->ext_flags & X509V3_EXT_DYNAMIC) -+ OPENSSL_free(ext); -+} -+ -+/* -+ * Legacy function: we don't need to add standard extensions any more because -+ * they are now kept in ext_dat.h. -+ */ -+ -+int X509V3_add_standard_extensions(void) -+{ -+ return 1; -+} -+ -+/* Return an extension internal structure */ -+ -+void *X509V3_EXT_d2i(X509_EXTENSION *ext) -+{ -+ const X509V3_EXT_METHOD *method; -+ const unsigned char *p; -+ ASN1_STRING *extvalue; -+ int extlen; -+ -+ if ((method = X509V3_EXT_get(ext)) == NULL) -+ return NULL; -+ extvalue = X509_EXTENSION_get_data(ext); -+ p = ASN1_STRING_get0_data(extvalue); -+ extlen = ASN1_STRING_length(extvalue); -+ if (method->it) -+ return ASN1_item_d2i(NULL, &p, extlen, ASN1_ITEM_ptr(method->it)); -+ return method->d2i(NULL, &p, extlen); -+} -+ -+/*- -+ * Get critical flag and decoded version of extension from a NID. -+ * The "idx" variable returns the last found extension and can -+ * be used to retrieve multiple extensions of the same NID. -+ * However multiple extensions with the same NID is usually -+ * due to a badly encoded certificate so if idx is NULL we -+ * choke if multiple extensions exist. -+ * The "crit" variable is set to the critical value. -+ * The return value is the decoded extension or NULL on -+ * error. The actual error can have several different causes, -+ * the value of *crit reflects the cause: -+ * >= 0, extension found but not decoded (reflects critical value). -+ * -1 extension not found. -+ * -2 extension occurs more than once. -+ */ -+ -+void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, -+ int *idx) -+{ -+ int lastpos, i; -+ X509_EXTENSION *ex, *found_ex = NULL; -+ if (!x) { -+ if (idx) -+ *idx = -1; -+ if (crit) -+ *crit = -1; -+ return NULL; -+ } -+ if (idx) -+ lastpos = *idx + 1; -+ else -+ lastpos = 0; -+ if (lastpos < 0) -+ lastpos = 0; -+ for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) { -+ ex = sk_X509_EXTENSION_value(x, i); -+ if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == nid) { -+ if (idx) { -+ *idx = i; -+ found_ex = ex; -+ break; -+ } else if (found_ex) { -+ /* Found more than one */ -+ if (crit) -+ *crit = -2; -+ return NULL; -+ } -+ found_ex = ex; -+ } -+ } -+ if (found_ex) { -+ /* Found it */ -+ if (crit) -+ *crit = X509_EXTENSION_get_critical(found_ex); -+ return X509V3_EXT_d2i(found_ex); -+ } -+ -+ /* Extension not found */ -+ if (idx) -+ *idx = -1; -+ if (crit) -+ *crit = -1; -+ return NULL; -+} -+ -+/* -+ * This function is a general extension append, replace and delete utility. -+ * The precise operation is governed by the 'flags' value. The 'crit' and -+ * 'value' arguments (if relevant) are the extensions internal structure. -+ */ -+ -+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, -+ int crit, unsigned long flags) -+{ -+ int extidx = -1; -+ int errcode; -+ X509_EXTENSION *ext, *extmp; -+ unsigned long ext_op = flags & X509V3_ADD_OP_MASK; -+ -+ /* -+ * If appending we don't care if it exists, otherwise look for existing -+ * extension. -+ */ -+ if (ext_op != X509V3_ADD_APPEND) -+ extidx = X509v3_get_ext_by_NID(*x, nid, -1); -+ -+ /* See if extension exists */ -+ if (extidx >= 0) { -+ /* If keep existing, nothing to do */ -+ if (ext_op == X509V3_ADD_KEEP_EXISTING) -+ return 1; -+ /* If default then its an error */ -+ if (ext_op == X509V3_ADD_DEFAULT) { -+ errcode = X509V3_R_EXTENSION_EXISTS; -+ goto err; -+ } -+ /* If delete, just delete it */ -+ if (ext_op == X509V3_ADD_DELETE) { -+ if (!sk_X509_EXTENSION_delete(*x, extidx)) -+ return -1; -+ return 1; -+ } -+ } else { -+ /* -+ * If replace existing or delete, error since extension must exist -+ */ -+ if ((ext_op == X509V3_ADD_REPLACE_EXISTING) || -+ (ext_op == X509V3_ADD_DELETE)) { -+ errcode = X509V3_R_EXTENSION_NOT_FOUND; -+ goto err; -+ } -+ } -+ -+ /* -+ * If we get this far then we have to create an extension: could have -+ * some flags for alternative encoding schemes... -+ */ -+ -+ ext = X509V3_EXT_i2d(nid, crit, value); -+ -+ if (!ext) { -+ X509V3err(X509V3_F_X509V3_ADD1_I2D, -+ X509V3_R_ERROR_CREATING_EXTENSION); -+ return 0; -+ } -+ -+ /* If extension exists replace it.. */ -+ if (extidx >= 0) { -+ extmp = sk_X509_EXTENSION_value(*x, extidx); -+ X509_EXTENSION_free(extmp); -+ if (!sk_X509_EXTENSION_set(*x, extidx, ext)) -+ return -1; -+ return 1; -+ } -+ -+ if (*x == NULL -+ && (*x = sk_X509_EXTENSION_new_null()) == NULL) -+ return -1; -+ if (!sk_X509_EXTENSION_push(*x, ext)) -+ return -1; -+ -+ return 1; -+ -+ err: -+ if (!(flags & X509V3_ADD_SILENT)) -+ X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode); -+ return 0; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ncons.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ncons.c -new file mode 100644 -index 0000000..9b3bb12 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_ncons.c -@@ -0,0 +1,513 @@ -+/* -+ * Copyright 2003-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include "internal/asn1_int.h" -+#include -+#include -+#include -+ -+#include "internal/x509_int.h" -+#include "ext_dat.h" -+ -+static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval); -+static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, -+ BIO *bp, int ind); -+static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, -+ STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, -+ int ind, const char *name); -+static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); -+ -+static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); -+static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); -+static int nc_dn(X509_NAME *sub, X509_NAME *nm); -+static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); -+static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); -+static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); -+static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base); -+ -+const X509V3_EXT_METHOD v3_name_constraints = { -+ NID_name_constraints, 0, -+ ASN1_ITEM_ref(NAME_CONSTRAINTS), -+ 0, 0, 0, 0, -+ 0, 0, -+ 0, v2i_NAME_CONSTRAINTS, -+ i2r_NAME_CONSTRAINTS, 0, -+ NULL -+}; -+ -+ASN1_SEQUENCE(GENERAL_SUBTREE) = { -+ ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME), -+ ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0), -+ ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1) -+} ASN1_SEQUENCE_END(GENERAL_SUBTREE) -+ -+ASN1_SEQUENCE(NAME_CONSTRAINTS) = { -+ ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees, -+ GENERAL_SUBTREE, 0), -+ ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees, -+ GENERAL_SUBTREE, 1), -+} ASN1_SEQUENCE_END(NAME_CONSTRAINTS) -+ -+ -+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) -+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) -+ -+static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -+{ -+ int i; -+ CONF_VALUE tval, *val; -+ STACK_OF(GENERAL_SUBTREE) **ptree = NULL; -+ NAME_CONSTRAINTS *ncons = NULL; -+ GENERAL_SUBTREE *sub = NULL; -+ -+ ncons = NAME_CONSTRAINTS_new(); -+ if (ncons == NULL) -+ goto memerr; -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ val = sk_CONF_VALUE_value(nval, i); -+ if (strncmp(val->name, "permitted", 9) == 0 && val->name[9]) { -+ ptree = &ncons->permittedSubtrees; -+ tval.name = val->name + 10; -+ } else if (strncmp(val->name, "excluded", 8) == 0 && val->name[8]) { -+ ptree = &ncons->excludedSubtrees; -+ tval.name = val->name + 9; -+ } else { -+ X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX); -+ goto err; -+ } -+ tval.value = val->value; -+ sub = GENERAL_SUBTREE_new(); -+ if (sub == NULL) -+ goto memerr; -+ if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) -+ goto err; -+ if (*ptree == NULL) -+ *ptree = sk_GENERAL_SUBTREE_new_null(); -+ if (*ptree == NULL || !sk_GENERAL_SUBTREE_push(*ptree, sub)) -+ goto memerr; -+ sub = NULL; -+ } -+ -+ return ncons; -+ -+ memerr: -+ X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); -+ err: -+ NAME_CONSTRAINTS_free(ncons); -+ GENERAL_SUBTREE_free(sub); -+ -+ return NULL; -+} -+ -+static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, -+ BIO *bp, int ind) -+{ -+ NAME_CONSTRAINTS *ncons = a; -+ do_i2r_name_constraints(method, ncons->permittedSubtrees, -+ bp, ind, "Permitted"); -+ do_i2r_name_constraints(method, ncons->excludedSubtrees, -+ bp, ind, "Excluded"); -+ return 1; -+} -+ -+static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, -+ STACK_OF(GENERAL_SUBTREE) *trees, -+ BIO *bp, int ind, const char *name) -+{ -+ GENERAL_SUBTREE *tree; -+ int i; -+ if (sk_GENERAL_SUBTREE_num(trees) > 0) -+ BIO_printf(bp, "%*s%s:\n", ind, "", name); -+ for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { -+ tree = sk_GENERAL_SUBTREE_value(trees, i); -+ BIO_printf(bp, "%*s", ind + 2, ""); -+ if (tree->base->type == GEN_IPADD) -+ print_nc_ipadd(bp, tree->base->d.ip); -+ else -+ GENERAL_NAME_print(bp, tree->base); -+ BIO_puts(bp, "\n"); -+ } -+ return 1; -+} -+ -+static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) -+{ -+ int i, len; -+ unsigned char *p; -+ p = ip->data; -+ len = ip->length; -+ BIO_puts(bp, "IP:"); -+ if (len == 8) { -+ BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", -+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); -+ } else if (len == 32) { -+ for (i = 0; i < 16; i++) { -+ BIO_printf(bp, "%X", p[0] << 8 | p[1]); -+ p += 2; -+ if (i == 7) -+ BIO_puts(bp, "/"); -+ else if (i != 15) -+ BIO_puts(bp, ":"); -+ } -+ } else -+ BIO_printf(bp, "IP Address:"); -+ return 1; -+} -+ -+/*- -+ * Check a certificate conforms to a specified set of constraints. -+ * Return values: -+ * X509_V_OK: All constraints obeyed. -+ * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. -+ * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. -+ * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. -+ * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. -+ * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax. -+ * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name -+ */ -+ -+int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) -+{ -+ int r, i; -+ X509_NAME *nm; -+ -+ nm = X509_get_subject_name(x); -+ -+ if (X509_NAME_entry_count(nm) > 0) { -+ GENERAL_NAME gntmp; -+ gntmp.type = GEN_DIRNAME; -+ gntmp.d.directoryName = nm; -+ -+ r = nc_match(&gntmp, nc); -+ -+ if (r != X509_V_OK) -+ return r; -+ -+ gntmp.type = GEN_EMAIL; -+ -+ /* Process any email address attributes in subject name */ -+ -+ for (i = -1;;) { -+ const X509_NAME_ENTRY *ne; -+ -+ i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i); -+ if (i == -1) -+ break; -+ ne = X509_NAME_get_entry(nm, i); -+ gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); -+ if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) -+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; -+ -+ r = nc_match(&gntmp, nc); -+ -+ if (r != X509_V_OK) -+ return r; -+ } -+ -+ } -+ -+ for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) { -+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); -+ r = nc_match(gen, nc); -+ if (r != X509_V_OK) -+ return r; -+ } -+ -+ return X509_V_OK; -+ -+} -+ -+int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc) -+{ -+ int r, i; -+ X509_NAME *nm; -+ -+ ASN1_STRING stmp; -+ GENERAL_NAME gntmp; -+ stmp.flags = 0; -+ stmp.type = V_ASN1_IA5STRING; -+ gntmp.type = GEN_DNS; -+ gntmp.d.dNSName = &stmp; -+ -+ nm = X509_get_subject_name(x); -+ -+ /* Process any commonName attributes in subject name */ -+ -+ for (i = -1;;) { -+ X509_NAME_ENTRY *ne; -+ ASN1_STRING *hn; -+ i = X509_NAME_get_index_by_NID(nm, NID_commonName, i); -+ if (i == -1) -+ break; -+ ne = X509_NAME_get_entry(nm, i); -+ hn = X509_NAME_ENTRY_get_data(ne); -+ /* Only process attributes that look like host names */ -+ if (asn1_valid_host(hn)) { -+ unsigned char *h; -+ int hlen = ASN1_STRING_to_UTF8(&h, hn); -+ if (hlen <= 0) -+ return X509_V_ERR_OUT_OF_MEM; -+ -+ stmp.length = hlen; -+ stmp.data = h; -+ -+ r = nc_match(&gntmp, nc); -+ -+ OPENSSL_free(h); -+ -+ if (r != X509_V_OK) -+ return r; -+ } -+ } -+ return X509_V_OK; -+} -+ -+static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) -+{ -+ GENERAL_SUBTREE *sub; -+ int i, r, match = 0; -+ -+ /* -+ * Permitted subtrees: if any subtrees exist of matching the type at -+ * least one subtree must match. -+ */ -+ -+ for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { -+ sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); -+ if (gen->type != sub->base->type) -+ continue; -+ if (sub->minimum || sub->maximum) -+ return X509_V_ERR_SUBTREE_MINMAX; -+ /* If we already have a match don't bother trying any more */ -+ if (match == 2) -+ continue; -+ if (match == 0) -+ match = 1; -+ r = nc_match_single(gen, sub->base); -+ if (r == X509_V_OK) -+ match = 2; -+ else if (r != X509_V_ERR_PERMITTED_VIOLATION) -+ return r; -+ } -+ -+ if (match == 1) -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ -+ /* Excluded subtrees: must not match any of these */ -+ -+ for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { -+ sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); -+ if (gen->type != sub->base->type) -+ continue; -+ if (sub->minimum || sub->maximum) -+ return X509_V_ERR_SUBTREE_MINMAX; -+ -+ r = nc_match_single(gen, sub->base); -+ if (r == X509_V_OK) -+ return X509_V_ERR_EXCLUDED_VIOLATION; -+ else if (r != X509_V_ERR_PERMITTED_VIOLATION) -+ return r; -+ -+ } -+ -+ return X509_V_OK; -+ -+} -+ -+static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) -+{ -+ switch (base->type) { -+ case GEN_DIRNAME: -+ return nc_dn(gen->d.directoryName, base->d.directoryName); -+ -+ case GEN_DNS: -+ return nc_dns(gen->d.dNSName, base->d.dNSName); -+ -+ case GEN_EMAIL: -+ return nc_email(gen->d.rfc822Name, base->d.rfc822Name); -+ -+ case GEN_URI: -+ return nc_uri(gen->d.uniformResourceIdentifier, -+ base->d.uniformResourceIdentifier); -+ -+ case GEN_IPADD: -+ return nc_ip(gen->d.iPAddress, base->d.iPAddress); -+ -+ default: -+ return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; -+ } -+ -+} -+ -+/* -+ * directoryName name constraint matching. The canonical encoding of -+ * X509_NAME makes this comparison easy. It is matched if the subtree is a -+ * subset of the name. -+ */ -+ -+static int nc_dn(X509_NAME *nm, X509_NAME *base) -+{ -+ /* Ensure canonical encodings are up to date. */ -+ if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) -+ return X509_V_ERR_OUT_OF_MEM; -+ if (base->modified && i2d_X509_NAME(base, NULL) < 0) -+ return X509_V_ERR_OUT_OF_MEM; -+ if (base->canon_enclen > nm->canon_enclen) -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ return X509_V_OK; -+} -+ -+static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) -+{ -+ char *baseptr = (char *)base->data; -+ char *dnsptr = (char *)dns->data; -+ /* Empty matches everything */ -+ if (!*baseptr) -+ return X509_V_OK; -+ /* -+ * Otherwise can add zero or more components on the left so compare RHS -+ * and if dns is longer and expect '.' as preceding character. -+ */ -+ if (dns->length > base->length) { -+ dnsptr += dns->length - base->length; -+ if (*baseptr != '.' && dnsptr[-1] != '.') -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ } -+ -+ if (strcasecmp(baseptr, dnsptr)) -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ -+ return X509_V_OK; -+ -+} -+ -+static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) -+{ -+ const char *baseptr = (char *)base->data; -+ const char *emlptr = (char *)eml->data; -+ -+ const char *baseat = strchr(baseptr, '@'); -+ const char *emlat = strchr(emlptr, '@'); -+ if (!emlat) -+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; -+ /* Special case: initial '.' is RHS match */ -+ if (!baseat && (*baseptr == '.')) { -+ if (eml->length > base->length) { -+ emlptr += eml->length - base->length; -+ if (strcasecmp(baseptr, emlptr) == 0) -+ return X509_V_OK; -+ } -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ } -+ -+ /* If we have anything before '@' match local part */ -+ -+ if (baseat) { -+ if (baseat != baseptr) { -+ if ((baseat - baseptr) != (emlat - emlptr)) -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ /* Case sensitive match of local part */ -+ if (strncmp(baseptr, emlptr, emlat - emlptr)) -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ } -+ /* Position base after '@' */ -+ baseptr = baseat + 1; -+ } -+ emlptr = emlat + 1; -+ /* Just have hostname left to match: case insensitive */ -+ if (strcasecmp(baseptr, emlptr)) -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ -+ return X509_V_OK; -+ -+} -+ -+static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) -+{ -+ const char *baseptr = (char *)base->data; -+ const char *hostptr = (char *)uri->data; -+ const char *p = strchr(hostptr, ':'); -+ int hostlen; -+ /* Check for foo:// and skip past it */ -+ if (!p || (p[1] != '/') || (p[2] != '/')) -+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; -+ hostptr = p + 3; -+ -+ /* Determine length of hostname part of URI */ -+ -+ /* Look for a port indicator as end of hostname first */ -+ -+ p = strchr(hostptr, ':'); -+ /* Otherwise look for trailing slash */ -+ if (!p) -+ p = strchr(hostptr, '/'); -+ -+ if (!p) -+ hostlen = strlen(hostptr); -+ else -+ hostlen = p - hostptr; -+ -+ if (hostlen == 0) -+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; -+ -+ /* Special case: initial '.' is RHS match */ -+ if (*baseptr == '.') { -+ if (hostlen > base->length) { -+ p = hostptr + hostlen - base->length; -+ if (strncasecmp(p, baseptr, base->length) == 0) -+ return X509_V_OK; -+ } -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ } -+ -+ if ((base->length != (int)hostlen) -+ || strncasecmp(hostptr, baseptr, hostlen)) -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ -+ return X509_V_OK; -+ -+} -+ -+static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base) -+{ -+ int hostlen, baselen, i; -+ unsigned char *hostptr, *baseptr, *maskptr; -+ hostptr = ip->data; -+ hostlen = ip->length; -+ baseptr = base->data; -+ baselen = base->length; -+ -+ /* Invalid if not IPv4 or IPv6 */ -+ if (!((hostlen == 4) || (hostlen == 16))) -+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; -+ if (!((baselen == 8) || (baselen == 32))) -+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; -+ -+ /* Do not match IPv4 with IPv6 */ -+ if (hostlen * 2 != baselen) -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ -+ maskptr = base->data + hostlen; -+ -+ /* Considering possible not aligned base ipAddress */ -+ /* Not checking for wrong mask definition: i.e.: 255.0.255.0 */ -+ for (i = 0; i < hostlen; i++) -+ if ((hostptr[i] & maskptr[i]) != (baseptr[i] & maskptr[i])) -+ return X509_V_ERR_PERMITTED_VIOLATION; -+ -+ return X509_V_OK; -+ -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pci.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pci.c -new file mode 100644 -index 0000000..2c05edb ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pci.c -@@ -0,0 +1,321 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Copyright (c) 2004 Kungliga Tekniska Högskolan -+ * (Royal Institute of Technology, Stockholm, Sweden). -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * 3. Neither the name of the Institute nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include "ext_dat.h" -+ -+static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, -+ BIO *out, int indent); -+static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, char *str); -+ -+const X509V3_EXT_METHOD v3_pci = -+ { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), -+ 0, 0, 0, 0, -+ 0, 0, -+ NULL, NULL, -+ (X509V3_EXT_I2R)i2r_pci, -+ (X509V3_EXT_R2I)r2i_pci, -+ NULL, -+}; -+ -+static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, -+ BIO *out, int indent) -+{ -+ BIO_printf(out, "%*sPath Length Constraint: ", indent, ""); -+ if (pci->pcPathLengthConstraint) -+ i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint); -+ else -+ BIO_printf(out, "infinite"); -+ BIO_puts(out, "\n"); -+ BIO_printf(out, "%*sPolicy Language: ", indent, ""); -+ i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); -+ BIO_puts(out, "\n"); -+ if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) -+ BIO_printf(out, "%*sPolicy Text: %s\n", indent, "", -+ pci->proxyPolicy->policy->data); -+ return 1; -+} -+ -+static int process_pci_value(CONF_VALUE *val, -+ ASN1_OBJECT **language, ASN1_INTEGER **pathlen, -+ ASN1_OCTET_STRING **policy) -+{ -+ int free_policy = 0; -+ -+ if (strcmp(val->name, "language") == 0) { -+ if (*language) { -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, -+ X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); -+ X509V3_conf_err(val); -+ return 0; -+ } -+ if ((*language = OBJ_txt2obj(val->value, 0)) == NULL) { -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, -+ X509V3_R_INVALID_OBJECT_IDENTIFIER); -+ X509V3_conf_err(val); -+ return 0; -+ } -+ } else if (strcmp(val->name, "pathlen") == 0) { -+ if (*pathlen) { -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, -+ X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); -+ X509V3_conf_err(val); -+ return 0; -+ } -+ if (!X509V3_get_value_int(val, pathlen)) { -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, -+ X509V3_R_POLICY_PATH_LENGTH); -+ X509V3_conf_err(val); -+ return 0; -+ } -+ } else if (strcmp(val->name, "policy") == 0) { -+ unsigned char *tmp_data = NULL; -+ long val_len; -+ if (!*policy) { -+ *policy = ASN1_OCTET_STRING_new(); -+ if (*policy == NULL) { -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); -+ X509V3_conf_err(val); -+ return 0; -+ } -+ free_policy = 1; -+ } -+ if (strncmp(val->value, "hex:", 4) == 0) { -+ unsigned char *tmp_data2 = -+ OPENSSL_hexstr2buf(val->value + 4, &val_len); -+ -+ if (!tmp_data2) { -+ X509V3_conf_err(val); -+ goto err; -+ } -+ -+ tmp_data = OPENSSL_realloc((*policy)->data, -+ (*policy)->length + val_len + 1); -+ if (tmp_data) { -+ (*policy)->data = tmp_data; -+ memcpy(&(*policy)->data[(*policy)->length], -+ tmp_data2, val_len); -+ (*policy)->length += val_len; -+ (*policy)->data[(*policy)->length] = '\0'; -+ } else { -+ OPENSSL_free(tmp_data2); -+ /* -+ * realloc failure implies the original data space is b0rked -+ * too! -+ */ -+ OPENSSL_free((*policy)->data); -+ (*policy)->data = NULL; -+ (*policy)->length = 0; -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ OPENSSL_free(tmp_data2); -+ } else if (strncmp(val->value, "file:", 5) == 0) { -+ unsigned char buf[2048]; -+ int n; -+ BIO *b = BIO_new_file(val->value + 5, "r"); -+ if (!b) { -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ while ((n = BIO_read(b, buf, sizeof(buf))) > 0 -+ || (n == 0 && BIO_should_retry(b))) { -+ if (!n) -+ continue; -+ -+ tmp_data = OPENSSL_realloc((*policy)->data, -+ (*policy)->length + n + 1); -+ -+ if (!tmp_data) { -+ OPENSSL_free((*policy)->data); -+ (*policy)->data = NULL; -+ (*policy)->length = 0; -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, -+ ERR_R_MALLOC_FAILURE); -+ X509V3_conf_err(val); -+ BIO_free_all(b); -+ goto err; -+ } -+ -+ (*policy)->data = tmp_data; -+ memcpy(&(*policy)->data[(*policy)->length], buf, n); -+ (*policy)->length += n; -+ (*policy)->data[(*policy)->length] = '\0'; -+ } -+ BIO_free_all(b); -+ -+ if (n < 0) { -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ } else if (strncmp(val->value, "text:", 5) == 0) { -+ val_len = strlen(val->value + 5); -+ tmp_data = OPENSSL_realloc((*policy)->data, -+ (*policy)->length + val_len + 1); -+ if (tmp_data) { -+ (*policy)->data = tmp_data; -+ memcpy(&(*policy)->data[(*policy)->length], -+ val->value + 5, val_len); -+ (*policy)->length += val_len; -+ (*policy)->data[(*policy)->length] = '\0'; -+ } else { -+ /* -+ * realloc failure implies the original data space is b0rked -+ * too! -+ */ -+ OPENSSL_free((*policy)->data); -+ (*policy)->data = NULL; -+ (*policy)->length = 0; -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ } else { -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, -+ X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ if (!tmp_data) { -+ X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ } -+ return 1; -+ err: -+ if (free_policy) { -+ ASN1_OCTET_STRING_free(*policy); -+ *policy = NULL; -+ } -+ return 0; -+} -+ -+static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, char *value) -+{ -+ PROXY_CERT_INFO_EXTENSION *pci = NULL; -+ STACK_OF(CONF_VALUE) *vals; -+ ASN1_OBJECT *language = NULL; -+ ASN1_INTEGER *pathlen = NULL; -+ ASN1_OCTET_STRING *policy = NULL; -+ int i, j; -+ -+ vals = X509V3_parse_list(value); -+ for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { -+ CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); -+ if (!cnf->name || (*cnf->name != '@' && !cnf->value)) { -+ X509V3err(X509V3_F_R2I_PCI, -+ X509V3_R_INVALID_PROXY_POLICY_SETTING); -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ if (*cnf->name == '@') { -+ STACK_OF(CONF_VALUE) *sect; -+ int success_p = 1; -+ -+ sect = X509V3_get_section(ctx, cnf->name + 1); -+ if (!sect) { -+ X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_SECTION); -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) { -+ success_p = -+ process_pci_value(sk_CONF_VALUE_value(sect, j), -+ &language, &pathlen, &policy); -+ } -+ X509V3_section_free(ctx, sect); -+ if (!success_p) -+ goto err; -+ } else { -+ if (!process_pci_value(cnf, &language, &pathlen, &policy)) { -+ X509V3_conf_err(cnf); -+ goto err; -+ } -+ } -+ } -+ -+ /* Language is mandatory */ -+ if (!language) { -+ X509V3err(X509V3_F_R2I_PCI, -+ X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); -+ goto err; -+ } -+ i = OBJ_obj2nid(language); -+ if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) { -+ X509V3err(X509V3_F_R2I_PCI, -+ X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); -+ goto err; -+ } -+ -+ pci = PROXY_CERT_INFO_EXTENSION_new(); -+ if (pci == NULL) { -+ X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ pci->proxyPolicy->policyLanguage = language; -+ language = NULL; -+ pci->proxyPolicy->policy = policy; -+ policy = NULL; -+ pci->pcPathLengthConstraint = pathlen; -+ pathlen = NULL; -+ goto end; -+ err: -+ ASN1_OBJECT_free(language); -+ ASN1_INTEGER_free(pathlen); -+ pathlen = NULL; -+ ASN1_OCTET_STRING_free(policy); -+ policy = NULL; -+ PROXY_CERT_INFO_EXTENSION_free(pci); -+ pci = NULL; -+ end: -+ sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); -+ return pci; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pcia.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pcia.c -new file mode 100644 -index 0000000..e6f7a91 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pcia.c -@@ -0,0 +1,60 @@ -+/* -+ * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Copyright (c) 2004 Kungliga Tekniska Högskolan -+ * (Royal Institute of Technology, Stockholm, Sweden). -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * 3. Neither the name of the Institute nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include -+ -+ASN1_SEQUENCE(PROXY_POLICY) = -+ { -+ ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT), -+ ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING) -+} ASN1_SEQUENCE_END(PROXY_POLICY) -+ -+IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY) -+ -+ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) = -+ { -+ ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER), -+ ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY) -+} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION) -+ -+IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pcons.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pcons.c -new file mode 100644 -index 0000000..24f7ff4 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pcons.c -@@ -0,0 +1,91 @@ -+/* -+ * Copyright 2003-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "ext_dat.h" -+ -+static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD -+ *method, void *bcons, STACK_OF(CONF_VALUE) -+ *extlist); -+static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *values); -+ -+const X509V3_EXT_METHOD v3_policy_constraints = { -+ NID_policy_constraints, 0, -+ ASN1_ITEM_ref(POLICY_CONSTRAINTS), -+ 0, 0, 0, 0, -+ 0, 0, -+ i2v_POLICY_CONSTRAINTS, -+ v2i_POLICY_CONSTRAINTS, -+ NULL, NULL, -+ NULL -+}; -+ -+ASN1_SEQUENCE(POLICY_CONSTRAINTS) = { -+ ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0), -+ ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1) -+} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS) -+ -+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) -+ -+static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD -+ *method, void *a, STACK_OF(CONF_VALUE) -+ *extlist) -+{ -+ POLICY_CONSTRAINTS *pcons = a; -+ X509V3_add_value_int("Require Explicit Policy", -+ pcons->requireExplicitPolicy, &extlist); -+ X509V3_add_value_int("Inhibit Policy Mapping", -+ pcons->inhibitPolicyMapping, &extlist); -+ return extlist; -+} -+ -+static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *values) -+{ -+ POLICY_CONSTRAINTS *pcons = NULL; -+ CONF_VALUE *val; -+ int i; -+ -+ if ((pcons = POLICY_CONSTRAINTS_new()) == NULL) { -+ X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ for (i = 0; i < sk_CONF_VALUE_num(values); i++) { -+ val = sk_CONF_VALUE_value(values, i); -+ if (strcmp(val->name, "requireExplicitPolicy") == 0) { -+ if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy)) -+ goto err; -+ } else if (strcmp(val->name, "inhibitPolicyMapping") == 0) { -+ if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping)) -+ goto err; -+ } else { -+ X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ } -+ if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { -+ X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, -+ X509V3_R_ILLEGAL_EMPTY_EXTENSION); -+ goto err; -+ } -+ -+ return pcons; -+ err: -+ POLICY_CONSTRAINTS_free(pcons); -+ return NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pku.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pku.c -new file mode 100644 -index 0000000..ed82bca ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pku.c -@@ -0,0 +1,65 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include "ext_dat.h" -+ -+static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, -+ PKEY_USAGE_PERIOD *usage, BIO *out, -+ int indent); -+/* -+ * static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, -+ * X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); -+ */ -+const X509V3_EXT_METHOD v3_pkey_usage_period = { -+ NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD), -+ 0, 0, 0, 0, -+ 0, 0, 0, 0, -+ (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL, -+ NULL -+}; -+ -+ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = { -+ ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0), -+ ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1) -+} ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD) -+ -+IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) -+ -+static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, -+ PKEY_USAGE_PERIOD *usage, BIO *out, -+ int indent) -+{ -+ BIO_printf(out, "%*s", indent, ""); -+ if (usage->notBefore) { -+ BIO_write(out, "Not Before: ", 12); -+ ASN1_GENERALIZEDTIME_print(out, usage->notBefore); -+ if (usage->notAfter) -+ BIO_write(out, ", ", 2); -+ } -+ if (usage->notAfter) { -+ BIO_write(out, "Not After: ", 11); -+ ASN1_GENERALIZEDTIME_print(out, usage->notAfter); -+ } -+ return 1; -+} -+ -+/*- -+static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values) -+X509V3_EXT_METHOD *method; -+X509V3_CTX *ctx; -+STACK_OF(CONF_VALUE) *values; -+{ -+return NULL; -+} -+*/ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pmaps.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pmaps.c -new file mode 100644 -index 0000000..73f4ec2 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_pmaps.c -@@ -0,0 +1,110 @@ -+/* -+ * Copyright 2003-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include "ext_dat.h" -+ -+static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -+static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD -+ *method, void *pmps, STACK_OF(CONF_VALUE) -+ *extlist); -+ -+const X509V3_EXT_METHOD v3_policy_mappings = { -+ NID_policy_mappings, 0, -+ ASN1_ITEM_ref(POLICY_MAPPINGS), -+ 0, 0, 0, 0, -+ 0, 0, -+ i2v_POLICY_MAPPINGS, -+ v2i_POLICY_MAPPINGS, -+ 0, 0, -+ NULL -+}; -+ -+ASN1_SEQUENCE(POLICY_MAPPING) = { -+ ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT), -+ ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT) -+} ASN1_SEQUENCE_END(POLICY_MAPPING) -+ -+ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS, -+ POLICY_MAPPING) -+ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS) -+ -+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) -+ -+static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD -+ *method, void *a, STACK_OF(CONF_VALUE) -+ *ext_list) -+{ -+ POLICY_MAPPINGS *pmaps = a; -+ POLICY_MAPPING *pmap; -+ int i; -+ char obj_tmp1[80]; -+ char obj_tmp2[80]; -+ for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { -+ pmap = sk_POLICY_MAPPING_value(pmaps, i); -+ i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy); -+ i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy); -+ X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list); -+ } -+ return ext_list; -+} -+ -+static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -+{ -+ POLICY_MAPPINGS *pmaps = NULL; -+ POLICY_MAPPING *pmap = NULL; -+ ASN1_OBJECT *obj1 = NULL, *obj2 = NULL; -+ CONF_VALUE *val; -+ int i; -+ -+ if ((pmaps = sk_POLICY_MAPPING_new_null()) == NULL) { -+ X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ val = sk_CONF_VALUE_value(nval, i); -+ if (!val->value || !val->name) { -+ X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, -+ X509V3_R_INVALID_OBJECT_IDENTIFIER); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ obj1 = OBJ_txt2obj(val->name, 0); -+ obj2 = OBJ_txt2obj(val->value, 0); -+ if (!obj1 || !obj2) { -+ X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, -+ X509V3_R_INVALID_OBJECT_IDENTIFIER); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ pmap = POLICY_MAPPING_new(); -+ if (pmap == NULL) { -+ X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ pmap->issuerDomainPolicy = obj1; -+ pmap->subjectDomainPolicy = obj2; -+ obj1 = obj2 = NULL; -+ sk_POLICY_MAPPING_push(pmaps, pmap); -+ } -+ return pmaps; -+ err: -+ ASN1_OBJECT_free(obj1); -+ ASN1_OBJECT_free(obj2); -+ sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); -+ return NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_prn.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_prn.c -new file mode 100644 -index 0000000..f384c34 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_prn.c -@@ -0,0 +1,210 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* X509 v3 extension utilities */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+ -+/* Extension printing routines */ -+ -+static int unknown_ext_print(BIO *out, const unsigned char *ext, int extlen, -+ unsigned long flag, int indent, int supported); -+ -+/* Print out a name+value stack */ -+ -+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, -+ int ml) -+{ -+ int i; -+ CONF_VALUE *nval; -+ if (!val) -+ return; -+ if (!ml || !sk_CONF_VALUE_num(val)) { -+ BIO_printf(out, "%*s", indent, ""); -+ if (!sk_CONF_VALUE_num(val)) -+ BIO_puts(out, "\n"); -+ } -+ for (i = 0; i < sk_CONF_VALUE_num(val); i++) { -+ if (ml) -+ BIO_printf(out, "%*s", indent, ""); -+ else if (i > 0) -+ BIO_printf(out, ", "); -+ nval = sk_CONF_VALUE_value(val, i); -+ if (!nval->name) -+ BIO_puts(out, nval->value); -+ else if (!nval->value) -+ BIO_puts(out, nval->name); -+#ifndef CHARSET_EBCDIC -+ else -+ BIO_printf(out, "%s:%s", nval->name, nval->value); -+#else -+ else { -+ int len; -+ char *tmp; -+ len = strlen(nval->value) + 1; -+ tmp = OPENSSL_malloc(len); -+ if (tmp != NULL) { -+ ascii2ebcdic(tmp, nval->value, len); -+ BIO_printf(out, "%s:%s", nval->name, tmp); -+ OPENSSL_free(tmp); -+ } -+ } -+#endif -+ if (ml) -+ BIO_puts(out, "\n"); -+ } -+} -+ -+/* Main routine: print out a general extension */ -+ -+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, -+ int indent) -+{ -+ void *ext_str = NULL; -+ char *value = NULL; -+ ASN1_OCTET_STRING *extoct; -+ const unsigned char *p; -+ int extlen; -+ const X509V3_EXT_METHOD *method; -+ STACK_OF(CONF_VALUE) *nval = NULL; -+ int ok = 1; -+ -+ extoct = X509_EXTENSION_get_data(ext); -+ p = ASN1_STRING_get0_data(extoct); -+ extlen = ASN1_STRING_length(extoct); -+ -+ if ((method = X509V3_EXT_get(ext)) == NULL) -+ return unknown_ext_print(out, p, extlen, flag, indent, 0); -+ if (method->it) -+ ext_str = ASN1_item_d2i(NULL, &p, extlen, ASN1_ITEM_ptr(method->it)); -+ else -+ ext_str = method->d2i(NULL, &p, extlen); -+ -+ if (!ext_str) -+ return unknown_ext_print(out, p, extlen, flag, indent, 1); -+ -+ if (method->i2s) { -+ if ((value = method->i2s(method, ext_str)) == NULL) { -+ ok = 0; -+ goto err; -+ } -+#ifndef CHARSET_EBCDIC -+ BIO_printf(out, "%*s%s", indent, "", value); -+#else -+ { -+ int len; -+ char *tmp; -+ len = strlen(value) + 1; -+ tmp = OPENSSL_malloc(len); -+ if (tmp != NULL) { -+ ascii2ebcdic(tmp, value, len); -+ BIO_printf(out, "%*s%s", indent, "", tmp); -+ OPENSSL_free(tmp); -+ } -+ } -+#endif -+ } else if (method->i2v) { -+ if ((nval = method->i2v(method, ext_str, NULL)) == NULL) { -+ ok = 0; -+ goto err; -+ } -+ X509V3_EXT_val_prn(out, nval, indent, -+ method->ext_flags & X509V3_EXT_MULTILINE); -+ } else if (method->i2r) { -+ if (!method->i2r(method, ext_str, out, indent)) -+ ok = 0; -+ } else -+ ok = 0; -+ -+ err: -+ sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); -+ OPENSSL_free(value); -+ if (method->it) -+ ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it)); -+ else -+ method->ext_free(ext_str); -+ return ok; -+} -+ -+int X509V3_extensions_print(BIO *bp, const char *title, -+ const STACK_OF(X509_EXTENSION) *exts, -+ unsigned long flag, int indent) -+{ -+ int i, j; -+ -+ if (sk_X509_EXTENSION_num(exts) <= 0) -+ return 1; -+ -+ if (title) { -+ BIO_printf(bp, "%*s%s:\n", indent, "", title); -+ indent += 4; -+ } -+ -+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { -+ ASN1_OBJECT *obj; -+ X509_EXTENSION *ex; -+ ex = sk_X509_EXTENSION_value(exts, i); -+ if (indent && BIO_printf(bp, "%*s", indent, "") <= 0) -+ return 0; -+ obj = X509_EXTENSION_get_object(ex); -+ i2a_ASN1_OBJECT(bp, obj); -+ j = X509_EXTENSION_get_critical(ex); -+ if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) -+ return 0; -+ if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) { -+ BIO_printf(bp, "%*s", indent + 4, ""); -+ ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex)); -+ } -+ if (BIO_write(bp, "\n", 1) <= 0) -+ return 0; -+ } -+ return 1; -+} -+ -+static int unknown_ext_print(BIO *out, const unsigned char *ext, int extlen, -+ unsigned long flag, int indent, int supported) -+{ -+ switch (flag & X509V3_EXT_UNKNOWN_MASK) { -+ -+ case X509V3_EXT_DEFAULT: -+ return 0; -+ -+ case X509V3_EXT_ERROR_UNKNOWN: -+ if (supported) -+ BIO_printf(out, "%*s", indent, ""); -+ else -+ BIO_printf(out, "%*s", indent, ""); -+ return 1; -+ -+ case X509V3_EXT_PARSE_UNKNOWN: -+ return ASN1_parse_dump(out, ext, extlen, indent, -1); -+ case X509V3_EXT_DUMP_UNKNOWN: -+ return BIO_dump_indent(out, (const char *)ext, extlen, indent); -+ -+ default: -+ return 1; -+ } -+} -+ -+#ifndef OPENSSL_NO_STDIO -+int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent) -+{ -+ BIO *bio_tmp; -+ int ret; -+ -+ if ((bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) -+ return 0; -+ ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); -+ BIO_free(bio_tmp); -+ return ret; -+} -+#endif -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_purp.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_purp.c -new file mode 100644 -index 0000000..451e7f8 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_purp.c -@@ -0,0 +1,865 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include "internal/numbers.h" -+#include -+#include -+#include "internal/x509_int.h" -+ -+static void x509v3_cache_extensions(X509 *x); -+ -+static int check_ssl_ca(const X509 *x); -+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, -+ int ca); -+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, -+ int ca); -+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, -+ int ca); -+static int purpose_smime(const X509 *x, int ca); -+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, -+ int ca); -+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, -+ int ca); -+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, -+ int ca); -+static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, -+ int ca); -+static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); -+static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); -+ -+static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b); -+static void xptable_free(X509_PURPOSE *p); -+ -+static X509_PURPOSE xstandard[] = { -+ {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, -+ check_purpose_ssl_client, "SSL client", "sslclient", NULL}, -+ {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, -+ check_purpose_ssl_server, "SSL server", "sslserver", NULL}, -+ {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, -+ check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL}, -+ {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, -+ "S/MIME signing", "smimesign", NULL}, -+ {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, -+ check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL}, -+ {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, -+ "CRL signing", "crlsign", NULL}, -+ {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", -+ NULL}, -+ {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, -+ "OCSP helper", "ocsphelper", NULL}, -+ {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, -+ check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", -+ NULL}, -+}; -+ -+#define X509_PURPOSE_COUNT OSSL_NELEM(xstandard) -+ -+static STACK_OF(X509_PURPOSE) *xptable = NULL; -+ -+static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b) -+{ -+ return (*a)->purpose - (*b)->purpose; -+} -+ -+/* -+ * As much as I'd like to make X509_check_purpose use a "const" X509* I -+ * really can't because it does recalculate hashes and do other non-const -+ * things. -+ */ -+int X509_check_purpose(X509 *x, int id, int ca) -+{ -+ int idx; -+ const X509_PURPOSE *pt; -+ if (!(x->ex_flags & EXFLAG_SET)) { -+ CRYPTO_THREAD_write_lock(x->lock); -+ x509v3_cache_extensions(x); -+ CRYPTO_THREAD_unlock(x->lock); -+ } -+ /* Return if side-effect only call */ -+ if (id == -1) -+ return 1; -+ idx = X509_PURPOSE_get_by_id(id); -+ if (idx == -1) -+ return -1; -+ pt = X509_PURPOSE_get0(idx); -+ return pt->check_purpose(pt, x, ca); -+} -+ -+int X509_PURPOSE_set(int *p, int purpose) -+{ -+ if (X509_PURPOSE_get_by_id(purpose) == -1) { -+ X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE); -+ return 0; -+ } -+ *p = purpose; -+ return 1; -+} -+ -+int X509_PURPOSE_get_count(void) -+{ -+ if (!xptable) -+ return X509_PURPOSE_COUNT; -+ return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT; -+} -+ -+X509_PURPOSE *X509_PURPOSE_get0(int idx) -+{ -+ if (idx < 0) -+ return NULL; -+ if (idx < (int)X509_PURPOSE_COUNT) -+ return xstandard + idx; -+ return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT); -+} -+ -+int X509_PURPOSE_get_by_sname(const char *sname) -+{ -+ int i; -+ X509_PURPOSE *xptmp; -+ for (i = 0; i < X509_PURPOSE_get_count(); i++) { -+ xptmp = X509_PURPOSE_get0(i); -+ if (strcmp(xptmp->sname, sname) == 0) -+ return i; -+ } -+ return -1; -+} -+ -+int X509_PURPOSE_get_by_id(int purpose) -+{ -+ X509_PURPOSE tmp; -+ int idx; -+ if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) -+ return purpose - X509_PURPOSE_MIN; -+ tmp.purpose = purpose; -+ if (!xptable) -+ return -1; -+ idx = sk_X509_PURPOSE_find(xptable, &tmp); -+ if (idx == -1) -+ return -1; -+ return idx + X509_PURPOSE_COUNT; -+} -+ -+int X509_PURPOSE_add(int id, int trust, int flags, -+ int (*ck) (const X509_PURPOSE *, const X509 *, int), -+ const char *name, const char *sname, void *arg) -+{ -+ int idx; -+ X509_PURPOSE *ptmp; -+ /* -+ * This is set according to what we change: application can't set it -+ */ -+ flags &= ~X509_PURPOSE_DYNAMIC; -+ /* This will always be set for application modified trust entries */ -+ flags |= X509_PURPOSE_DYNAMIC_NAME; -+ /* Get existing entry if any */ -+ idx = X509_PURPOSE_get_by_id(id); -+ /* Need a new entry */ -+ if (idx == -1) { -+ if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) { -+ X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ ptmp->flags = X509_PURPOSE_DYNAMIC; -+ } else -+ ptmp = X509_PURPOSE_get0(idx); -+ -+ /* OPENSSL_free existing name if dynamic */ -+ if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { -+ OPENSSL_free(ptmp->name); -+ OPENSSL_free(ptmp->sname); -+ } -+ /* dup supplied name */ -+ ptmp->name = OPENSSL_strdup(name); -+ ptmp->sname = OPENSSL_strdup(sname); -+ if (!ptmp->name || !ptmp->sname) { -+ X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ /* Keep the dynamic flag of existing entry */ -+ ptmp->flags &= X509_PURPOSE_DYNAMIC; -+ /* Set all other flags */ -+ ptmp->flags |= flags; -+ -+ ptmp->purpose = id; -+ ptmp->trust = trust; -+ ptmp->check_purpose = ck; -+ ptmp->usr_data = arg; -+ -+ /* If its a new entry manage the dynamic table */ -+ if (idx == -1) { -+ if (xptable == NULL -+ && (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) { -+ X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ if (!sk_X509_PURPOSE_push(xptable, ptmp)) { -+ X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ } -+ return 1; -+ err: -+ if (idx == -1) { -+ OPENSSL_free(ptmp->name); -+ OPENSSL_free(ptmp->sname); -+ OPENSSL_free(ptmp); -+ } -+ return 0; -+} -+ -+static void xptable_free(X509_PURPOSE *p) -+{ -+ if (!p) -+ return; -+ if (p->flags & X509_PURPOSE_DYNAMIC) { -+ if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { -+ OPENSSL_free(p->name); -+ OPENSSL_free(p->sname); -+ } -+ OPENSSL_free(p); -+ } -+} -+ -+void X509_PURPOSE_cleanup(void) -+{ -+ sk_X509_PURPOSE_pop_free(xptable, xptable_free); -+ xptable = NULL; -+} -+ -+int X509_PURPOSE_get_id(const X509_PURPOSE *xp) -+{ -+ return xp->purpose; -+} -+ -+char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp) -+{ -+ return xp->name; -+} -+ -+char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp) -+{ -+ return xp->sname; -+} -+ -+int X509_PURPOSE_get_trust(const X509_PURPOSE *xp) -+{ -+ return xp->trust; -+} -+ -+static int nid_cmp(const int *a, const int *b) -+{ -+ return *a - *b; -+} -+ -+DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid); -+IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid); -+ -+int X509_supported_extension(X509_EXTENSION *ex) -+{ -+ /* -+ * This table is a list of the NIDs of supported extensions: that is -+ * those which are used by the verify process. If an extension is -+ * critical and doesn't appear in this list then the verify process will -+ * normally reject the certificate. The list must be kept in numerical -+ * order because it will be searched using bsearch. -+ */ -+ -+ static const int supported_nids[] = { -+ NID_netscape_cert_type, /* 71 */ -+ NID_key_usage, /* 83 */ -+ NID_subject_alt_name, /* 85 */ -+ NID_basic_constraints, /* 87 */ -+ NID_certificate_policies, /* 89 */ -+ NID_ext_key_usage, /* 126 */ -+#ifndef OPENSSL_NO_RFC3779 -+ NID_sbgp_ipAddrBlock, /* 290 */ -+ NID_sbgp_autonomousSysNum, /* 291 */ -+#endif -+ NID_policy_constraints, /* 401 */ -+ NID_proxyCertInfo, /* 663 */ -+ NID_name_constraints, /* 666 */ -+ NID_policy_mappings, /* 747 */ -+ NID_inhibit_any_policy /* 748 */ -+ }; -+ -+ int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); -+ -+ if (ex_nid == NID_undef) -+ return 0; -+ -+ if (OBJ_bsearch_nid(&ex_nid, supported_nids, OSSL_NELEM(supported_nids))) -+ return 1; -+ return 0; -+} -+ -+static void setup_dp(X509 *x, DIST_POINT *dp) -+{ -+ X509_NAME *iname = NULL; -+ int i; -+ if (dp->reasons) { -+ if (dp->reasons->length > 0) -+ dp->dp_reasons = dp->reasons->data[0]; -+ if (dp->reasons->length > 1) -+ dp->dp_reasons |= (dp->reasons->data[1] << 8); -+ dp->dp_reasons &= CRLDP_ALL_REASONS; -+ } else -+ dp->dp_reasons = CRLDP_ALL_REASONS; -+ if (!dp->distpoint || (dp->distpoint->type != 1)) -+ return; -+ for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { -+ GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); -+ if (gen->type == GEN_DIRNAME) { -+ iname = gen->d.directoryName; -+ break; -+ } -+ } -+ if (!iname) -+ iname = X509_get_issuer_name(x); -+ -+ DIST_POINT_set_dpname(dp->distpoint, iname); -+ -+} -+ -+static void setup_crldp(X509 *x) -+{ -+ int i; -+ x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); -+ for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) -+ setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); -+} -+ -+#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) -+#define ku_reject(x, usage) \ -+ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) -+#define xku_reject(x, usage) \ -+ (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) -+#define ns_reject(x, usage) \ -+ (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) -+ -+static void x509v3_cache_extensions(X509 *x) -+{ -+ BASIC_CONSTRAINTS *bs; -+ PROXY_CERT_INFO_EXTENSION *pci; -+ ASN1_BIT_STRING *usage; -+ ASN1_BIT_STRING *ns; -+ EXTENDED_KEY_USAGE *extusage; -+ X509_EXTENSION *ex; -+ -+ int i; -+ if (x->ex_flags & EXFLAG_SET) -+ return; -+ X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); -+ /* V1 should mean no extensions ... */ -+ if (!X509_get_version(x)) -+ x->ex_flags |= EXFLAG_V1; -+ /* Handle basic constraints */ -+ if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) { -+ if (bs->ca) -+ x->ex_flags |= EXFLAG_CA; -+ if (bs->pathlen) { -+ if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) -+ || !bs->ca) { -+ x->ex_flags |= EXFLAG_INVALID; -+ x->ex_pathlen = 0; -+ } else -+ x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); -+ } else -+ x->ex_pathlen = -1; -+ BASIC_CONSTRAINTS_free(bs); -+ x->ex_flags |= EXFLAG_BCONS; -+ } -+ /* Handle proxy certificates */ -+ if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) { -+ if (x->ex_flags & EXFLAG_CA -+ || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 -+ || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) { -+ x->ex_flags |= EXFLAG_INVALID; -+ } -+ if (pci->pcPathLengthConstraint) { -+ x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); -+ } else -+ x->ex_pcpathlen = -1; -+ PROXY_CERT_INFO_EXTENSION_free(pci); -+ x->ex_flags |= EXFLAG_PROXY; -+ } -+ /* Handle key usage */ -+ if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { -+ if (usage->length > 0) { -+ x->ex_kusage = usage->data[0]; -+ if (usage->length > 1) -+ x->ex_kusage |= usage->data[1] << 8; -+ } else -+ x->ex_kusage = 0; -+ x->ex_flags |= EXFLAG_KUSAGE; -+ ASN1_BIT_STRING_free(usage); -+ } -+ x->ex_xkusage = 0; -+ if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) { -+ x->ex_flags |= EXFLAG_XKUSAGE; -+ for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { -+ switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { -+ case NID_server_auth: -+ x->ex_xkusage |= XKU_SSL_SERVER; -+ break; -+ -+ case NID_client_auth: -+ x->ex_xkusage |= XKU_SSL_CLIENT; -+ break; -+ -+ case NID_email_protect: -+ x->ex_xkusage |= XKU_SMIME; -+ break; -+ -+ case NID_code_sign: -+ x->ex_xkusage |= XKU_CODE_SIGN; -+ break; -+ -+ case NID_ms_sgc: -+ case NID_ns_sgc: -+ x->ex_xkusage |= XKU_SGC; -+ break; -+ -+ case NID_OCSP_sign: -+ x->ex_xkusage |= XKU_OCSP_SIGN; -+ break; -+ -+ case NID_time_stamp: -+ x->ex_xkusage |= XKU_TIMESTAMP; -+ break; -+ -+ case NID_dvcs: -+ x->ex_xkusage |= XKU_DVCS; -+ break; -+ -+ case NID_anyExtendedKeyUsage: -+ x->ex_xkusage |= XKU_ANYEKU; -+ break; -+ } -+ } -+ sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); -+ } -+ -+ if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) { -+ if (ns->length > 0) -+ x->ex_nscert = ns->data[0]; -+ else -+ x->ex_nscert = 0; -+ x->ex_flags |= EXFLAG_NSCERT; -+ ASN1_BIT_STRING_free(ns); -+ } -+ x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); -+ x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); -+ /* Does subject name match issuer ? */ -+ if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) { -+ x->ex_flags |= EXFLAG_SI; -+ /* If SKID matches AKID also indicate self signed */ -+ if (X509_check_akid(x, x->akid) == X509_V_OK && -+ !ku_reject(x, KU_KEY_CERT_SIGN)) -+ x->ex_flags |= EXFLAG_SS; -+ } -+ x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); -+ x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL); -+ if (!x->nc && (i != -1)) -+ x->ex_flags |= EXFLAG_INVALID; -+ setup_crldp(x); -+ -+#ifndef OPENSSL_NO_RFC3779 -+ x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); -+ x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, -+ NULL, NULL); -+#endif -+ for (i = 0; i < X509_get_ext_count(x); i++) { -+ ex = X509_get_ext(x, i); -+ if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) -+ == NID_freshest_crl) -+ x->ex_flags |= EXFLAG_FRESHEST; -+ if (!X509_EXTENSION_get_critical(ex)) -+ continue; -+ if (!X509_supported_extension(ex)) { -+ x->ex_flags |= EXFLAG_CRITICAL; -+ break; -+ } -+ } -+ x->ex_flags |= EXFLAG_SET; -+} -+ -+/*- -+ * CA checks common to all purposes -+ * return codes: -+ * 0 not a CA -+ * 1 is a CA -+ * 2 basicConstraints absent so "maybe" a CA -+ * 3 basicConstraints absent but self signed V1. -+ * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. -+ */ -+ -+static int check_ca(const X509 *x) -+{ -+ /* keyUsage if present should allow cert signing */ -+ if (ku_reject(x, KU_KEY_CERT_SIGN)) -+ return 0; -+ if (x->ex_flags & EXFLAG_BCONS) { -+ if (x->ex_flags & EXFLAG_CA) -+ return 1; -+ /* If basicConstraints says not a CA then say so */ -+ else -+ return 0; -+ } else { -+ /* we support V1 roots for... uh, I don't really know why. */ -+ if ((x->ex_flags & V1_ROOT) == V1_ROOT) -+ return 3; -+ /* -+ * If key usage present it must have certSign so tolerate it -+ */ -+ else if (x->ex_flags & EXFLAG_KUSAGE) -+ return 4; -+ /* Older certificates could have Netscape-specific CA types */ -+ else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA) -+ return 5; -+ /* can this still be regarded a CA certificate? I doubt it */ -+ return 0; -+ } -+} -+ -+void X509_set_proxy_flag(X509 *x) -+{ -+ x->ex_flags |= EXFLAG_PROXY; -+} -+ -+void X509_set_proxy_pathlen(X509 *x, long l) -+{ -+ x->ex_pcpathlen = l; -+} -+ -+int X509_check_ca(X509 *x) -+{ -+ if (!(x->ex_flags & EXFLAG_SET)) { -+ CRYPTO_THREAD_write_lock(x->lock); -+ x509v3_cache_extensions(x); -+ CRYPTO_THREAD_unlock(x->lock); -+ } -+ -+ return check_ca(x); -+} -+ -+/* Check SSL CA: common checks for SSL client and server */ -+static int check_ssl_ca(const X509 *x) -+{ -+ int ca_ret; -+ ca_ret = check_ca(x); -+ if (!ca_ret) -+ return 0; -+ /* check nsCertType if present */ -+ if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA) -+ return ca_ret; -+ else -+ return 0; -+} -+ -+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, -+ int ca) -+{ -+ if (xku_reject(x, XKU_SSL_CLIENT)) -+ return 0; -+ if (ca) -+ return check_ssl_ca(x); -+ /* We need to do digital signatures or key agreement */ -+ if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)) -+ return 0; -+ /* nsCertType if present should allow SSL client use */ -+ if (ns_reject(x, NS_SSL_CLIENT)) -+ return 0; -+ return 1; -+} -+ -+/* -+ * Key usage needed for TLS/SSL server: digital signature, encipherment or -+ * key agreement. The ssl code can check this more thoroughly for individual -+ * key types. -+ */ -+#define KU_TLS \ -+ KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT -+ -+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, -+ int ca) -+{ -+ if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC)) -+ return 0; -+ if (ca) -+ return check_ssl_ca(x); -+ -+ if (ns_reject(x, NS_SSL_SERVER)) -+ return 0; -+ if (ku_reject(x, KU_TLS)) -+ return 0; -+ -+ return 1; -+ -+} -+ -+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, -+ int ca) -+{ -+ int ret; -+ ret = check_purpose_ssl_server(xp, x, ca); -+ if (!ret || ca) -+ return ret; -+ /* We need to encipher or Netscape complains */ -+ if (ku_reject(x, KU_KEY_ENCIPHERMENT)) -+ return 0; -+ return ret; -+} -+ -+/* common S/MIME checks */ -+static int purpose_smime(const X509 *x, int ca) -+{ -+ if (xku_reject(x, XKU_SMIME)) -+ return 0; -+ if (ca) { -+ int ca_ret; -+ ca_ret = check_ca(x); -+ if (!ca_ret) -+ return 0; -+ /* check nsCertType if present */ -+ if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) -+ return ca_ret; -+ else -+ return 0; -+ } -+ if (x->ex_flags & EXFLAG_NSCERT) { -+ if (x->ex_nscert & NS_SMIME) -+ return 1; -+ /* Workaround for some buggy certificates */ -+ if (x->ex_nscert & NS_SSL_CLIENT) -+ return 2; -+ return 0; -+ } -+ return 1; -+} -+ -+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, -+ int ca) -+{ -+ int ret; -+ ret = purpose_smime(x, ca); -+ if (!ret || ca) -+ return ret; -+ if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)) -+ return 0; -+ return ret; -+} -+ -+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, -+ int ca) -+{ -+ int ret; -+ ret = purpose_smime(x, ca); -+ if (!ret || ca) -+ return ret; -+ if (ku_reject(x, KU_KEY_ENCIPHERMENT)) -+ return 0; -+ return ret; -+} -+ -+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, -+ int ca) -+{ -+ if (ca) { -+ int ca_ret; -+ if ((ca_ret = check_ca(x)) != 2) -+ return ca_ret; -+ else -+ return 0; -+ } -+ if (ku_reject(x, KU_CRL_SIGN)) -+ return 0; -+ return 1; -+} -+ -+/* -+ * OCSP helper: this is *not* a full OCSP check. It just checks that each CA -+ * is valid. Additional checks must be made on the chain. -+ */ -+ -+static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) -+{ -+ /* -+ * Must be a valid CA. Should we really support the "I don't know" value -+ * (2)? -+ */ -+ if (ca) -+ return check_ca(x); -+ /* leaf certificate is checked in OCSP_verify() */ -+ return 1; -+} -+ -+static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, -+ int ca) -+{ -+ int i_ext; -+ -+ /* If ca is true we must return if this is a valid CA certificate. */ -+ if (ca) -+ return check_ca(x); -+ -+ /* -+ * Check the optional key usage field: -+ * if Key Usage is present, it must be one of digitalSignature -+ * and/or nonRepudiation (other values are not consistent and shall -+ * be rejected). -+ */ -+ if ((x->ex_flags & EXFLAG_KUSAGE) -+ && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || -+ !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) -+ return 0; -+ -+ /* Only time stamp key usage is permitted and it's required. */ -+ if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) -+ return 0; -+ -+ /* Extended Key Usage MUST be critical */ -+ i_ext = X509_get_ext_by_NID(x, NID_ext_key_usage, -1); -+ if (i_ext >= 0) { -+ X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext); -+ if (!X509_EXTENSION_get_critical(ext)) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) -+{ -+ return 1; -+} -+ -+/*- -+ * Various checks to see if one certificate issued the second. -+ * This can be used to prune a set of possible issuer certificates -+ * which have been looked up using some simple method such as by -+ * subject name. -+ * These are: -+ * 1. Check issuer_name(subject) == subject_name(issuer) -+ * 2. If akid(subject) exists check it matches issuer -+ * 3. If key_usage(issuer) exists check it supports certificate signing -+ * returns 0 for OK, positive for reason for mismatch, reasons match -+ * codes for X509_verify_cert() -+ */ -+ -+int X509_check_issued(X509 *issuer, X509 *subject) -+{ -+ if (X509_NAME_cmp(X509_get_subject_name(issuer), -+ X509_get_issuer_name(subject))) -+ return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; -+ x509v3_cache_extensions(issuer); -+ x509v3_cache_extensions(subject); -+ -+ if (subject->akid) { -+ int ret = X509_check_akid(issuer, subject->akid); -+ if (ret != X509_V_OK) -+ return ret; -+ } -+ -+ if (subject->ex_flags & EXFLAG_PROXY) { -+ if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) -+ return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; -+ } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) -+ return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; -+ return X509_V_OK; -+} -+ -+int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) -+{ -+ -+ if (!akid) -+ return X509_V_OK; -+ -+ /* Check key ids (if present) */ -+ if (akid->keyid && issuer->skid && -+ ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid)) -+ return X509_V_ERR_AKID_SKID_MISMATCH; -+ /* Check serial number */ -+ if (akid->serial && -+ ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) -+ return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; -+ /* Check issuer name */ -+ if (akid->issuer) { -+ /* -+ * Ugh, for some peculiar reason AKID includes SEQUENCE OF -+ * GeneralName. So look for a DirName. There may be more than one but -+ * we only take any notice of the first. -+ */ -+ GENERAL_NAMES *gens; -+ GENERAL_NAME *gen; -+ X509_NAME *nm = NULL; -+ int i; -+ gens = akid->issuer; -+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { -+ gen = sk_GENERAL_NAME_value(gens, i); -+ if (gen->type == GEN_DIRNAME) { -+ nm = gen->d.dirn; -+ break; -+ } -+ } -+ if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) -+ return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; -+ } -+ return X509_V_OK; -+} -+ -+uint32_t X509_get_extension_flags(X509 *x) -+{ -+ /* Call for side-effect of computing hash and caching extensions */ -+ X509_check_purpose(x, -1, -1); -+ return x->ex_flags; -+} -+ -+uint32_t X509_get_key_usage(X509 *x) -+{ -+ /* Call for side-effect of computing hash and caching extensions */ -+ X509_check_purpose(x, -1, -1); -+ if (x->ex_flags & EXFLAG_KUSAGE) -+ return x->ex_kusage; -+ return UINT32_MAX; -+} -+ -+uint32_t X509_get_extended_key_usage(X509 *x) -+{ -+ /* Call for side-effect of computing hash and caching extensions */ -+ X509_check_purpose(x, -1, -1); -+ if (x->ex_flags & EXFLAG_XKUSAGE) -+ return x->ex_xkusage; -+ return UINT32_MAX; -+} -+ -+const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x) -+{ -+ /* Call for side-effect of computing hash and caching extensions */ -+ X509_check_purpose(x, -1, -1); -+ return x->skid; -+} -+ -+long X509_get_pathlen(X509 *x) -+{ -+ /* Called for side effect of caching extensions */ -+ if (X509_check_purpose(x, -1, -1) != 1 -+ || (x->ex_flags & EXFLAG_BCONS) == 0) -+ return -1; -+ return x->ex_pathlen; -+} -+ -+long X509_get_proxy_pathlen(X509 *x) -+{ -+ /* Called for side effect of caching extensions */ -+ if (X509_check_purpose(x, -1, -1) != 1 -+ || (x->ex_flags & EXFLAG_PROXY) == 0) -+ return -1; -+ return x->ex_pcpathlen; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_skey.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_skey.c -new file mode 100644 -index 0000000..39597dc ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_skey.c -@@ -0,0 +1,106 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include "internal/x509_int.h" -+#include "ext_dat.h" -+ -+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, char *str); -+const X509V3_EXT_METHOD v3_skey_id = { -+ NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING), -+ 0, 0, 0, 0, -+ (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, -+ (X509V3_EXT_S2I)s2i_skey_id, -+ 0, 0, 0, 0, -+ NULL -+}; -+ -+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, -+ const ASN1_OCTET_STRING *oct) -+{ -+ return OPENSSL_buf2hexstr(oct->data, oct->length); -+} -+ -+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, const char *str) -+{ -+ ASN1_OCTET_STRING *oct; -+ long length; -+ -+ if ((oct = ASN1_OCTET_STRING_new()) == NULL) { -+ X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ if ((oct->data = OPENSSL_hexstr2buf(str, &length)) == NULL) { -+ ASN1_OCTET_STRING_free(oct); -+ return NULL; -+ } -+ -+ oct->length = length; -+ -+ return oct; -+ -+} -+ -+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, char *str) -+{ -+ ASN1_OCTET_STRING *oct; -+ X509_PUBKEY *pubkey; -+ const unsigned char *pk; -+ int pklen; -+ unsigned char pkey_dig[EVP_MAX_MD_SIZE]; -+ unsigned int diglen; -+ -+ if (strcmp(str, "hash")) -+ return s2i_ASN1_OCTET_STRING(method, ctx, str); -+ -+ if ((oct = ASN1_OCTET_STRING_new()) == NULL) { -+ X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ if (ctx && (ctx->flags == CTX_TEST)) -+ return oct; -+ -+ if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { -+ X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); -+ goto err; -+ } -+ -+ if (ctx->subject_req) -+ pubkey = ctx->subject_req->req_info.pubkey; -+ else -+ pubkey = ctx->subject_cert->cert_info.key; -+ -+ if (pubkey == NULL) { -+ X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); -+ goto err; -+ } -+ -+ X509_PUBKEY_get0_param(NULL, &pk, &pklen, NULL, pubkey); -+ -+ if (!EVP_Digest(pk, pklen, pkey_dig, &diglen, EVP_sha1(), NULL)) -+ goto err; -+ -+ if (!ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { -+ X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ -+ return oct; -+ -+ err: -+ ASN1_OCTET_STRING_free(oct); -+ return NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_sxnet.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_sxnet.c -new file mode 100644 -index 0000000..89cda01 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_sxnet.c -@@ -0,0 +1,226 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+#include "ext_dat.h" -+ -+/* Support for Thawte strong extranet extension */ -+ -+#define SXNET_TEST -+ -+static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, -+ int indent); -+#ifdef SXNET_TEST -+static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval); -+#endif -+const X509V3_EXT_METHOD v3_sxnet = { -+ NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET), -+ 0, 0, 0, 0, -+ 0, 0, -+ 0, -+#ifdef SXNET_TEST -+ (X509V3_EXT_V2I)sxnet_v2i, -+#else -+ 0, -+#endif -+ (X509V3_EXT_I2R)sxnet_i2r, -+ 0, -+ NULL -+}; -+ -+ASN1_SEQUENCE(SXNETID) = { -+ ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER), -+ ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING) -+} ASN1_SEQUENCE_END(SXNETID) -+ -+IMPLEMENT_ASN1_FUNCTIONS(SXNETID) -+ -+ASN1_SEQUENCE(SXNET) = { -+ ASN1_SIMPLE(SXNET, version, ASN1_INTEGER), -+ ASN1_SEQUENCE_OF(SXNET, ids, SXNETID) -+} ASN1_SEQUENCE_END(SXNET) -+ -+IMPLEMENT_ASN1_FUNCTIONS(SXNET) -+ -+static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, -+ int indent) -+{ -+ long v; -+ char *tmp; -+ SXNETID *id; -+ int i; -+ v = ASN1_INTEGER_get(sx->version); -+ BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v); -+ for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { -+ id = sk_SXNETID_value(sx->ids, i); -+ tmp = i2s_ASN1_INTEGER(NULL, id->zone); -+ BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp); -+ OPENSSL_free(tmp); -+ ASN1_STRING_print(out, id->user); -+ } -+ return 1; -+} -+ -+#ifdef SXNET_TEST -+ -+/* -+ * NBB: this is used for testing only. It should *not* be used for anything -+ * else because it will just take static IDs from the configuration file and -+ * they should really be separate values for each user. -+ */ -+ -+static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval) -+{ -+ CONF_VALUE *cnf; -+ SXNET *sx = NULL; -+ int i; -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ cnf = sk_CONF_VALUE_value(nval, i); -+ if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1)) -+ return NULL; -+ } -+ return sx; -+} -+ -+#endif -+ -+/* Strong Extranet utility functions */ -+ -+/* Add an id given the zone as an ASCII number */ -+ -+int SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userlen) -+{ -+ ASN1_INTEGER *izone; -+ -+ if ((izone = s2i_ASN1_INTEGER(NULL, zone)) == NULL) { -+ X509V3err(X509V3_F_SXNET_ADD_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE); -+ return 0; -+ } -+ return SXNET_add_id_INTEGER(psx, izone, user, userlen); -+} -+ -+/* Add an id given the zone as an unsigned long */ -+ -+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user, -+ int userlen) -+{ -+ ASN1_INTEGER *izone; -+ -+ if ((izone = ASN1_INTEGER_new()) == NULL -+ || !ASN1_INTEGER_set(izone, lzone)) { -+ X509V3err(X509V3_F_SXNET_ADD_ID_ULONG, ERR_R_MALLOC_FAILURE); -+ ASN1_INTEGER_free(izone); -+ return 0; -+ } -+ return SXNET_add_id_INTEGER(psx, izone, user, userlen); -+ -+} -+ -+/* -+ * Add an id given the zone as an ASN1_INTEGER. Note this version uses the -+ * passed integer and doesn't make a copy so don't free it up afterwards. -+ */ -+ -+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user, -+ int userlen) -+{ -+ SXNET *sx = NULL; -+ SXNETID *id = NULL; -+ if (!psx || !zone || !user) { -+ X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, -+ X509V3_R_INVALID_NULL_ARGUMENT); -+ return 0; -+ } -+ if (userlen == -1) -+ userlen = strlen(user); -+ if (userlen > 64) { -+ X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_USER_TOO_LONG); -+ return 0; -+ } -+ if (*psx == NULL) { -+ if ((sx = SXNET_new()) == NULL) -+ goto err; -+ if (!ASN1_INTEGER_set(sx->version, 0)) -+ goto err; -+ *psx = sx; -+ } else -+ sx = *psx; -+ if (SXNET_get_id_INTEGER(sx, zone)) { -+ X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_DUPLICATE_ZONE_ID); -+ return 0; -+ } -+ -+ if ((id = SXNETID_new()) == NULL) -+ goto err; -+ if (userlen == -1) -+ userlen = strlen(user); -+ -+ if (!ASN1_OCTET_STRING_set(id->user, (const unsigned char *)user, userlen)) -+ goto err; -+ if (!sk_SXNETID_push(sx->ids, id)) -+ goto err; -+ id->zone = zone; -+ return 1; -+ -+ err: -+ X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, ERR_R_MALLOC_FAILURE); -+ SXNETID_free(id); -+ SXNET_free(sx); -+ *psx = NULL; -+ return 0; -+} -+ -+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, const char *zone) -+{ -+ ASN1_INTEGER *izone; -+ ASN1_OCTET_STRING *oct; -+ -+ if ((izone = s2i_ASN1_INTEGER(NULL, zone)) == NULL) { -+ X509V3err(X509V3_F_SXNET_GET_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE); -+ return NULL; -+ } -+ oct = SXNET_get_id_INTEGER(sx, izone); -+ ASN1_INTEGER_free(izone); -+ return oct; -+} -+ -+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) -+{ -+ ASN1_INTEGER *izone; -+ ASN1_OCTET_STRING *oct; -+ -+ if ((izone = ASN1_INTEGER_new()) == NULL -+ || !ASN1_INTEGER_set(izone, lzone)) { -+ X509V3err(X509V3_F_SXNET_GET_ID_ULONG, ERR_R_MALLOC_FAILURE); -+ ASN1_INTEGER_free(izone); -+ return NULL; -+ } -+ oct = SXNET_get_id_INTEGER(sx, izone); -+ ASN1_INTEGER_free(izone); -+ return oct; -+} -+ -+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone) -+{ -+ SXNETID *id; -+ int i; -+ for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { -+ id = sk_SXNETID_value(sx->ids, i); -+ if (!ASN1_INTEGER_cmp(id->zone, zone)) -+ return id->user; -+ } -+ return NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_tlsf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_tlsf.c -new file mode 100644 -index 0000000..fec6724 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_tlsf.c -@@ -0,0 +1,137 @@ -+/* -+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include "internal/o_str.h" -+#include -+#include -+#include -+#include "ext_dat.h" -+ -+static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method, -+ TLS_FEATURE *tls_feature, -+ STACK_OF(CONF_VALUE) *ext_list); -+static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, -+ STACK_OF(CONF_VALUE) *nval); -+ -+ASN1_ITEM_TEMPLATE(TLS_FEATURE) = -+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, TLS_FEATURE, ASN1_INTEGER) -+static_ASN1_ITEM_TEMPLATE_END(TLS_FEATURE) -+ -+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE) -+ -+const X509V3_EXT_METHOD v3_tls_feature = { -+ NID_tlsfeature, 0, -+ ASN1_ITEM_ref(TLS_FEATURE), -+ 0, 0, 0, 0, -+ 0, 0, -+ (X509V3_EXT_I2V)i2v_TLS_FEATURE, -+ (X509V3_EXT_V2I)v2i_TLS_FEATURE, -+ 0, 0, -+ NULL -+}; -+ -+ -+typedef struct { -+ long num; -+ const char *name; -+} TLS_FEATURE_NAME; -+ -+static TLS_FEATURE_NAME tls_feature_tbl[] = { -+ { 5, "status_request" }, -+ { 17, "status_request_v2" } -+}; -+ -+/* -+ * i2v_TLS_FEATURE converts the TLS_FEATURE structure tls_feature into the -+ * STACK_OF(CONF_VALUE) structure ext_list. STACK_OF(CONF_VALUE) is the format -+ * used by the CONF library to represent a multi-valued extension. ext_list is -+ * returned. -+ */ -+static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method, -+ TLS_FEATURE *tls_feature, -+ STACK_OF(CONF_VALUE) *ext_list) -+{ -+ int i; -+ size_t j; -+ ASN1_INTEGER *ai; -+ long tlsextid; -+ for (i = 0; i < sk_ASN1_INTEGER_num(tls_feature); i++) { -+ ai = sk_ASN1_INTEGER_value(tls_feature, i); -+ tlsextid = ASN1_INTEGER_get(ai); -+ for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++) -+ if (tlsextid == tls_feature_tbl[j].num) -+ break; -+ if (j < OSSL_NELEM(tls_feature_tbl)) -+ X509V3_add_value(NULL, tls_feature_tbl[j].name, &ext_list); -+ else -+ X509V3_add_value_int(NULL, ai, &ext_list); -+ } -+ return ext_list; -+} -+ -+/* -+ * v2i_TLS_FEATURE converts the multi-valued extension nval into a TLS_FEATURE -+ * structure, which is returned if the conversion is successful. In case of -+ * error, NULL is returned. -+ */ -+static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, -+ X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -+{ -+ TLS_FEATURE *tlsf; -+ char *extval, *endptr; -+ ASN1_INTEGER *ai; -+ CONF_VALUE *val; -+ int i; -+ size_t j; -+ long tlsextid; -+ -+ if ((tlsf = sk_ASN1_INTEGER_new_null()) == NULL) { -+ X509V3err(X509V3_F_V2I_TLS_FEATURE, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ -+ for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { -+ val = sk_CONF_VALUE_value(nval, i); -+ if (val->value) -+ extval = val->value; -+ else -+ extval = val->name; -+ -+ for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++) -+ if (strcasecmp(extval, tls_feature_tbl[j].name) == 0) -+ break; -+ if (j < OSSL_NELEM(tls_feature_tbl)) -+ tlsextid = tls_feature_tbl[j].num; -+ else { -+ tlsextid = strtol(extval, &endptr, 10); -+ if (((*endptr) != '\0') || (extval == endptr) || (tlsextid < 0) || -+ (tlsextid > 65535)) { -+ X509V3err(X509V3_F_V2I_TLS_FEATURE, X509V3_R_INVALID_SYNTAX); -+ X509V3_conf_err(val); -+ goto err; -+ } -+ } -+ -+ ai = ASN1_INTEGER_new(); -+ if (ai == NULL) { -+ X509V3err(X509V3_F_V2I_TLS_FEATURE, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ ASN1_INTEGER_set(ai, tlsextid); -+ sk_ASN1_INTEGER_push(tlsf, ai); -+ } -+ return tlsf; -+ -+ err: -+ sk_ASN1_INTEGER_pop_free(tlsf, ASN1_INTEGER_free); -+ return NULL; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c -new file mode 100644 -index 0000000..7dc9a45 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3_utl.c -@@ -0,0 +1,1195 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* X509 v3 extension utilities */ -+ -+#include -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include "internal/x509_int.h" -+#include -+#include "ext_dat.h" -+ -+static char *strip_spaces(char *name); -+static int sk_strcmp(const char *const *a, const char *const *b); -+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, -+ GENERAL_NAMES *gens); -+static void str_free(OPENSSL_STRING str); -+static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email); -+ -+static int ipv4_from_asc(unsigned char *v4, const char *in); -+static int ipv6_from_asc(unsigned char *v6, const char *in); -+static int ipv6_cb(const char *elem, int len, void *usr); -+static int ipv6_hex(unsigned char *out, const char *in, int inlen); -+ -+/* Add a CONF_VALUE name value pair to stack */ -+ -+int X509V3_add_value(const char *name, const char *value, -+ STACK_OF(CONF_VALUE) **extlist) -+{ -+ CONF_VALUE *vtmp = NULL; -+ char *tname = NULL, *tvalue = NULL; -+ -+ if (name && (tname = OPENSSL_strdup(name)) == NULL) -+ goto err; -+ if (value && (tvalue = OPENSSL_strdup(value)) == NULL) -+ goto err; -+ if ((vtmp = OPENSSL_malloc(sizeof(*vtmp))) == NULL) -+ goto err; -+ if (*extlist == NULL && (*extlist = sk_CONF_VALUE_new_null()) == NULL) -+ goto err; -+ vtmp->section = NULL; -+ vtmp->name = tname; -+ vtmp->value = tvalue; -+ if (!sk_CONF_VALUE_push(*extlist, vtmp)) -+ goto err; -+ return 1; -+ err: -+ X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE); -+ OPENSSL_free(vtmp); -+ OPENSSL_free(tname); -+ OPENSSL_free(tvalue); -+ return 0; -+} -+ -+int X509V3_add_value_uchar(const char *name, const unsigned char *value, -+ STACK_OF(CONF_VALUE) **extlist) -+{ -+ return X509V3_add_value(name, (const char *)value, extlist); -+} -+ -+/* Free function for STACK_OF(CONF_VALUE) */ -+ -+void X509V3_conf_free(CONF_VALUE *conf) -+{ -+ if (!conf) -+ return; -+ OPENSSL_free(conf->name); -+ OPENSSL_free(conf->value); -+ OPENSSL_free(conf->section); -+ OPENSSL_free(conf); -+} -+ -+int X509V3_add_value_bool(const char *name, int asn1_bool, -+ STACK_OF(CONF_VALUE) **extlist) -+{ -+ if (asn1_bool) -+ return X509V3_add_value(name, "TRUE", extlist); -+ return X509V3_add_value(name, "FALSE", extlist); -+} -+ -+int X509V3_add_value_bool_nf(const char *name, int asn1_bool, -+ STACK_OF(CONF_VALUE) **extlist) -+{ -+ if (asn1_bool) -+ return X509V3_add_value(name, "TRUE", extlist); -+ return 1; -+} -+ -+char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a) -+{ -+ BIGNUM *bntmp = NULL; -+ char *strtmp = NULL; -+ -+ if (!a) -+ return NULL; -+ if ((bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) == NULL -+ || (strtmp = BN_bn2dec(bntmp)) == NULL) -+ X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); -+ BN_free(bntmp); -+ return strtmp; -+} -+ -+char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a) -+{ -+ BIGNUM *bntmp = NULL; -+ char *strtmp = NULL; -+ -+ if (!a) -+ return NULL; -+ if ((bntmp = ASN1_INTEGER_to_BN(a, NULL)) == NULL -+ || (strtmp = BN_bn2dec(bntmp)) == NULL) -+ X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); -+ BN_free(bntmp); -+ return strtmp; -+} -+ -+ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value) -+{ -+ BIGNUM *bn = NULL; -+ ASN1_INTEGER *aint; -+ int isneg, ishex; -+ int ret; -+ if (value == NULL) { -+ X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE); -+ return NULL; -+ } -+ bn = BN_new(); -+ if (bn == NULL) { -+ X509V3err(X509V3_F_S2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); -+ return NULL; -+ } -+ if (value[0] == '-') { -+ value++; -+ isneg = 1; -+ } else -+ isneg = 0; -+ -+ if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) { -+ value += 2; -+ ishex = 1; -+ } else -+ ishex = 0; -+ -+ if (ishex) -+ ret = BN_hex2bn(&bn, value); -+ else -+ ret = BN_dec2bn(&bn, value); -+ -+ if (!ret || value[ret]) { -+ BN_free(bn); -+ X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR); -+ return NULL; -+ } -+ -+ if (isneg && BN_is_zero(bn)) -+ isneg = 0; -+ -+ aint = BN_to_ASN1_INTEGER(bn, NULL); -+ BN_free(bn); -+ if (!aint) { -+ X509V3err(X509V3_F_S2I_ASN1_INTEGER, -+ X509V3_R_BN_TO_ASN1_INTEGER_ERROR); -+ return NULL; -+ } -+ if (isneg) -+ aint->type |= V_ASN1_NEG; -+ return aint; -+} -+ -+int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, -+ STACK_OF(CONF_VALUE) **extlist) -+{ -+ char *strtmp; -+ int ret; -+ -+ if (!aint) -+ return 1; -+ if ((strtmp = i2s_ASN1_INTEGER(NULL, aint)) == NULL) -+ return 0; -+ ret = X509V3_add_value(name, strtmp, extlist); -+ OPENSSL_free(strtmp); -+ return ret; -+} -+ -+int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool) -+{ -+ const char *btmp; -+ -+ if ((btmp = value->value) == NULL) -+ goto err; -+ if (strcmp(btmp, "TRUE") == 0 -+ || strcmp(btmp, "true") == 0 -+ || strcmp(btmp, "Y") == 0 -+ || strcmp(btmp, "y") == 0 -+ || strcmp(btmp, "YES") == 0 -+ || strcmp(btmp, "yes") == 0) { -+ *asn1_bool = 0xff; -+ return 1; -+ } -+ if (strcmp(btmp, "FALSE") == 0 -+ || strcmp(btmp, "false") == 0 -+ || strcmp(btmp, "N") == 0 -+ || strcmp(btmp, "n") == 0 -+ || strcmp(btmp, "NO") == 0 -+ || strcmp(btmp, "no") == 0) { -+ *asn1_bool = 0; -+ return 1; -+ } -+ err: -+ X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL, -+ X509V3_R_INVALID_BOOLEAN_STRING); -+ X509V3_conf_err(value); -+ return 0; -+} -+ -+int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint) -+{ -+ ASN1_INTEGER *itmp; -+ -+ if ((itmp = s2i_ASN1_INTEGER(NULL, value->value)) == NULL) { -+ X509V3_conf_err(value); -+ return 0; -+ } -+ *aint = itmp; -+ return 1; -+} -+ -+#define HDR_NAME 1 -+#define HDR_VALUE 2 -+ -+/* -+ * #define DEBUG -+ */ -+ -+STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) -+{ -+ char *p, *q, c; -+ char *ntmp, *vtmp; -+ STACK_OF(CONF_VALUE) *values = NULL; -+ char *linebuf; -+ int state; -+ /* We are going to modify the line so copy it first */ -+ linebuf = OPENSSL_strdup(line); -+ if (linebuf == NULL) { -+ X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE); -+ goto err; -+ } -+ state = HDR_NAME; -+ ntmp = NULL; -+ /* Go through all characters */ -+ for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n'); -+ p++) { -+ -+ switch (state) { -+ case HDR_NAME: -+ if (c == ':') { -+ state = HDR_VALUE; -+ *p = 0; -+ ntmp = strip_spaces(q); -+ if (!ntmp) { -+ X509V3err(X509V3_F_X509V3_PARSE_LIST, -+ X509V3_R_INVALID_NULL_NAME); -+ goto err; -+ } -+ q = p + 1; -+ } else if (c == ',') { -+ *p = 0; -+ ntmp = strip_spaces(q); -+ q = p + 1; -+ if (!ntmp) { -+ X509V3err(X509V3_F_X509V3_PARSE_LIST, -+ X509V3_R_INVALID_NULL_NAME); -+ goto err; -+ } -+ X509V3_add_value(ntmp, NULL, &values); -+ } -+ break; -+ -+ case HDR_VALUE: -+ if (c == ',') { -+ state = HDR_NAME; -+ *p = 0; -+ vtmp = strip_spaces(q); -+ if (!vtmp) { -+ X509V3err(X509V3_F_X509V3_PARSE_LIST, -+ X509V3_R_INVALID_NULL_VALUE); -+ goto err; -+ } -+ X509V3_add_value(ntmp, vtmp, &values); -+ ntmp = NULL; -+ q = p + 1; -+ } -+ -+ } -+ } -+ -+ if (state == HDR_VALUE) { -+ vtmp = strip_spaces(q); -+ if (!vtmp) { -+ X509V3err(X509V3_F_X509V3_PARSE_LIST, -+ X509V3_R_INVALID_NULL_VALUE); -+ goto err; -+ } -+ X509V3_add_value(ntmp, vtmp, &values); -+ } else { -+ ntmp = strip_spaces(q); -+ if (!ntmp) { -+ X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME); -+ goto err; -+ } -+ X509V3_add_value(ntmp, NULL, &values); -+ } -+ OPENSSL_free(linebuf); -+ return values; -+ -+ err: -+ OPENSSL_free(linebuf); -+ sk_CONF_VALUE_pop_free(values, X509V3_conf_free); -+ return NULL; -+ -+} -+ -+/* Delete leading and trailing spaces from a string */ -+static char *strip_spaces(char *name) -+{ -+ char *p, *q; -+ /* Skip over leading spaces */ -+ p = name; -+ while (*p && isspace((unsigned char)*p)) -+ p++; -+ if (!*p) -+ return NULL; -+ q = p + strlen(p) - 1; -+ while ((q != p) && isspace((unsigned char)*q)) -+ q--; -+ if (p != q) -+ q[1] = 0; -+ if (!*p) -+ return NULL; -+ return p; -+} -+ -+ -+/* -+ * V2I name comparison function: returns zero if 'name' matches cmp or cmp.* -+ */ -+ -+int name_cmp(const char *name, const char *cmp) -+{ -+ int len, ret; -+ char c; -+ len = strlen(cmp); -+ if ((ret = strncmp(name, cmp, len))) -+ return ret; -+ c = name[len]; -+ if (!c || (c == '.')) -+ return 0; -+ return 1; -+} -+ -+static int sk_strcmp(const char *const *a, const char *const *b) -+{ -+ return strcmp(*a, *b); -+} -+ -+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) -+{ -+ GENERAL_NAMES *gens; -+ STACK_OF(OPENSSL_STRING) *ret; -+ -+ gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); -+ ret = get_email(X509_get_subject_name(x), gens); -+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); -+ return ret; -+} -+ -+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x) -+{ -+ AUTHORITY_INFO_ACCESS *info; -+ STACK_OF(OPENSSL_STRING) *ret = NULL; -+ int i; -+ -+ info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); -+ if (!info) -+ return NULL; -+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { -+ ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); -+ if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) { -+ if (ad->location->type == GEN_URI) { -+ if (!append_ia5 -+ (&ret, ad->location->d.uniformResourceIdentifier)) -+ break; -+ } -+ } -+ } -+ AUTHORITY_INFO_ACCESS_free(info); -+ return ret; -+} -+ -+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) -+{ -+ GENERAL_NAMES *gens; -+ STACK_OF(X509_EXTENSION) *exts; -+ STACK_OF(OPENSSL_STRING) *ret; -+ -+ exts = X509_REQ_get_extensions(x); -+ gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); -+ ret = get_email(X509_REQ_get_subject_name(x), gens); -+ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); -+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); -+ return ret; -+} -+ -+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, -+ GENERAL_NAMES *gens) -+{ -+ STACK_OF(OPENSSL_STRING) *ret = NULL; -+ X509_NAME_ENTRY *ne; -+ ASN1_IA5STRING *email; -+ GENERAL_NAME *gen; -+ int i; -+ /* Now add any email address(es) to STACK */ -+ i = -1; -+ /* First supplied X509_NAME */ -+ while ((i = X509_NAME_get_index_by_NID(name, -+ NID_pkcs9_emailAddress, i)) >= 0) { -+ ne = X509_NAME_get_entry(name, i); -+ email = X509_NAME_ENTRY_get_data(ne); -+ if (!append_ia5(&ret, email)) -+ return NULL; -+ } -+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { -+ gen = sk_GENERAL_NAME_value(gens, i); -+ if (gen->type != GEN_EMAIL) -+ continue; -+ if (!append_ia5(&ret, gen->d.ia5)) -+ return NULL; -+ } -+ return ret; -+} -+ -+static void str_free(OPENSSL_STRING str) -+{ -+ OPENSSL_free(str); -+} -+ -+static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email) -+{ -+ char *emtmp; -+ /* First some sanity checks */ -+ if (email->type != V_ASN1_IA5STRING) -+ return 1; -+ if (!email->data || !email->length) -+ return 1; -+ if (*sk == NULL) -+ *sk = sk_OPENSSL_STRING_new(sk_strcmp); -+ if (*sk == NULL) -+ return 0; -+ /* Don't add duplicates */ -+ if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) -+ return 1; -+ emtmp = OPENSSL_strdup((char *)email->data); -+ if (emtmp == NULL || !sk_OPENSSL_STRING_push(*sk, emtmp)) { -+ OPENSSL_free(emtmp); /* free on push failure */ -+ X509_email_free(*sk); -+ *sk = NULL; -+ return 0; -+ } -+ return 1; -+} -+ -+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk) -+{ -+ sk_OPENSSL_STRING_pop_free(sk, str_free); -+} -+ -+typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len, -+ const unsigned char *subject, size_t subject_len, -+ unsigned int flags); -+ -+/* Skip pattern prefix to match "wildcard" subject */ -+static void skip_prefix(const unsigned char **p, size_t *plen, -+ size_t subject_len, -+ unsigned int flags) -+{ -+ const unsigned char *pattern = *p; -+ size_t pattern_len = *plen; -+ -+ /* -+ * If subject starts with a leading '.' followed by more octets, and -+ * pattern is longer, compare just an equal-length suffix with the -+ * full subject (starting at the '.'), provided the prefix contains -+ * no NULs. -+ */ -+ if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0) -+ return; -+ -+ while (pattern_len > subject_len && *pattern) { -+ if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) && -+ *pattern == '.') -+ break; -+ ++pattern; -+ --pattern_len; -+ } -+ -+ /* Skip if entire prefix acceptable */ -+ if (pattern_len == subject_len) { -+ *p = pattern; -+ *plen = pattern_len; -+ } -+} -+ -+/* Compare while ASCII ignoring case. */ -+static int equal_nocase(const unsigned char *pattern, size_t pattern_len, -+ const unsigned char *subject, size_t subject_len, -+ unsigned int flags) -+{ -+ skip_prefix(&pattern, &pattern_len, subject_len, flags); -+ if (pattern_len != subject_len) -+ return 0; -+ while (pattern_len) { -+ unsigned char l = *pattern; -+ unsigned char r = *subject; -+ /* The pattern must not contain NUL characters. */ -+ if (l == 0) -+ return 0; -+ if (l != r) { -+ if ('A' <= l && l <= 'Z') -+ l = (l - 'A') + 'a'; -+ if ('A' <= r && r <= 'Z') -+ r = (r - 'A') + 'a'; -+ if (l != r) -+ return 0; -+ } -+ ++pattern; -+ ++subject; -+ --pattern_len; -+ } -+ return 1; -+} -+ -+/* Compare using memcmp. */ -+static int equal_case(const unsigned char *pattern, size_t pattern_len, -+ const unsigned char *subject, size_t subject_len, -+ unsigned int flags) -+{ -+ skip_prefix(&pattern, &pattern_len, subject_len, flags); -+ if (pattern_len != subject_len) -+ return 0; -+ return !memcmp(pattern, subject, pattern_len); -+} -+ -+/* -+ * RFC 5280, section 7.5, requires that only the domain is compared in a -+ * case-insensitive manner. -+ */ -+static int equal_email(const unsigned char *a, size_t a_len, -+ const unsigned char *b, size_t b_len, -+ unsigned int unused_flags) -+{ -+ size_t i = a_len; -+ if (a_len != b_len) -+ return 0; -+ /* -+ * We search backwards for the '@' character, so that we do not have to -+ * deal with quoted local-parts. The domain part is compared in a -+ * case-insensitive manner. -+ */ -+ while (i > 0) { -+ --i; -+ if (a[i] == '@' || b[i] == '@') { -+ if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0)) -+ return 0; -+ break; -+ } -+ } -+ if (i == 0) -+ i = a_len; -+ return equal_case(a, i, b, i, 0); -+} -+ -+/* -+ * Compare the prefix and suffix with the subject, and check that the -+ * characters in-between are valid. -+ */ -+static int wildcard_match(const unsigned char *prefix, size_t prefix_len, -+ const unsigned char *suffix, size_t suffix_len, -+ const unsigned char *subject, size_t subject_len, -+ unsigned int flags) -+{ -+ const unsigned char *wildcard_start; -+ const unsigned char *wildcard_end; -+ const unsigned char *p; -+ int allow_multi = 0; -+ int allow_idna = 0; -+ -+ if (subject_len < prefix_len + suffix_len) -+ return 0; -+ if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags)) -+ return 0; -+ wildcard_start = subject + prefix_len; -+ wildcard_end = subject + (subject_len - suffix_len); -+ if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags)) -+ return 0; -+ /* -+ * If the wildcard makes up the entire first label, it must match at -+ * least one character. -+ */ -+ if (prefix_len == 0 && *suffix == '.') { -+ if (wildcard_start == wildcard_end) -+ return 0; -+ allow_idna = 1; -+ if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS) -+ allow_multi = 1; -+ } -+ /* IDNA labels cannot match partial wildcards */ -+ if (!allow_idna && -+ subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0) -+ return 0; -+ /* The wildcard may match a literal '*' */ -+ if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*') -+ return 1; -+ /* -+ * Check that the part matched by the wildcard contains only -+ * permitted characters and only matches a single label unless -+ * allow_multi is set. -+ */ -+ for (p = wildcard_start; p != wildcard_end; ++p) -+ if (!(('0' <= *p && *p <= '9') || -+ ('A' <= *p && *p <= 'Z') || -+ ('a' <= *p && *p <= 'z') || -+ *p == '-' || (allow_multi && *p == '.'))) -+ return 0; -+ return 1; -+} -+ -+#define LABEL_START (1 << 0) -+#define LABEL_END (1 << 1) -+#define LABEL_HYPHEN (1 << 2) -+#define LABEL_IDNA (1 << 3) -+ -+static const unsigned char *valid_star(const unsigned char *p, size_t len, -+ unsigned int flags) -+{ -+ const unsigned char *star = 0; -+ size_t i; -+ int state = LABEL_START; -+ int dots = 0; -+ for (i = 0; i < len; ++i) { -+ /* -+ * Locate first and only legal wildcard, either at the start -+ * or end of a non-IDNA first and not final label. -+ */ -+ if (p[i] == '*') { -+ int atstart = (state & LABEL_START); -+ int atend = (i == len - 1 || p[i + 1] == '.'); -+ /*- -+ * At most one wildcard per pattern. -+ * No wildcards in IDNA labels. -+ * No wildcards after the first label. -+ */ -+ if (star != NULL || (state & LABEL_IDNA) != 0 || dots) -+ return NULL; -+ /* Only full-label '*.example.com' wildcards? */ -+ if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS) -+ && (!atstart || !atend)) -+ return NULL; -+ /* No 'foo*bar' wildcards */ -+ if (!atstart && !atend) -+ return NULL; -+ star = &p[i]; -+ state &= ~LABEL_START; -+ } else if (('a' <= p[i] && p[i] <= 'z') -+ || ('A' <= p[i] && p[i] <= 'Z') -+ || ('0' <= p[i] && p[i] <= '9')) { -+ if ((state & LABEL_START) != 0 -+ && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0) -+ state |= LABEL_IDNA; -+ state &= ~(LABEL_HYPHEN | LABEL_START); -+ } else if (p[i] == '.') { -+ if ((state & (LABEL_HYPHEN | LABEL_START)) != 0) -+ return NULL; -+ state = LABEL_START; -+ ++dots; -+ } else if (p[i] == '-') { -+ /* no domain/subdomain starts with '-' */ -+ if ((state & LABEL_START) != 0) -+ return NULL; -+ state |= LABEL_HYPHEN; -+ } else -+ return NULL; -+ } -+ -+ /* -+ * The final label must not end in a hyphen or ".", and -+ * there must be at least two dots after the star. -+ */ -+ if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2) -+ return NULL; -+ return star; -+} -+ -+/* Compare using wildcards. */ -+static int equal_wildcard(const unsigned char *pattern, size_t pattern_len, -+ const unsigned char *subject, size_t subject_len, -+ unsigned int flags) -+{ -+ const unsigned char *star = NULL; -+ -+ /* -+ * Subject names starting with '.' can only match a wildcard pattern -+ * via a subject sub-domain pattern suffix match. -+ */ -+ if (!(subject_len > 1 && subject[0] == '.')) -+ star = valid_star(pattern, pattern_len, flags); -+ if (star == NULL) -+ return equal_nocase(pattern, pattern_len, -+ subject, subject_len, flags); -+ return wildcard_match(pattern, star - pattern, -+ star + 1, (pattern + pattern_len) - star - 1, -+ subject, subject_len, flags); -+} -+ -+/* -+ * Compare an ASN1_STRING to a supplied string. If they match return 1. If -+ * cmp_type > 0 only compare if string matches the type, otherwise convert it -+ * to UTF8. -+ */ -+ -+static int do_check_string(const ASN1_STRING *a, int cmp_type, equal_fn equal, -+ unsigned int flags, const char *b, size_t blen, -+ char **peername) -+{ -+ int rv = 0; -+ -+ if (!a->data || !a->length) -+ return 0; -+ if (cmp_type > 0) { -+ if (cmp_type != a->type) -+ return 0; -+ if (cmp_type == V_ASN1_IA5STRING) -+ rv = equal(a->data, a->length, (unsigned char *)b, blen, flags); -+ else if (a->length == (int)blen && !memcmp(a->data, b, blen)) -+ rv = 1; -+ if (rv > 0 && peername) -+ *peername = OPENSSL_strndup((char *)a->data, a->length); -+ } else { -+ int astrlen; -+ unsigned char *astr; -+ astrlen = ASN1_STRING_to_UTF8(&astr, a); -+ if (astrlen < 0) { -+ /* -+ * -1 could be an internal malloc failure or a decoding error from -+ * malformed input; we can't distinguish. -+ */ -+ return -1; -+ } -+ rv = equal(astr, astrlen, (unsigned char *)b, blen, flags); -+ if (rv > 0 && peername) -+ *peername = OPENSSL_strndup((char *)astr, astrlen); -+ OPENSSL_free(astr); -+ } -+ return rv; -+} -+ -+static int do_x509_check(X509 *x, const char *chk, size_t chklen, -+ unsigned int flags, int check_type, char **peername) -+{ -+ GENERAL_NAMES *gens = NULL; -+ X509_NAME *name = NULL; -+ int i; -+ int cnid = NID_undef; -+ int alt_type; -+ int san_present = 0; -+ int rv = 0; -+ equal_fn equal; -+ -+ /* See below, this flag is internal-only */ -+ flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS; -+ if (check_type == GEN_EMAIL) { -+ cnid = NID_pkcs9_emailAddress; -+ alt_type = V_ASN1_IA5STRING; -+ equal = equal_email; -+ } else if (check_type == GEN_DNS) { -+ cnid = NID_commonName; -+ /* Implicit client-side DNS sub-domain pattern */ -+ if (chklen > 1 && chk[0] == '.') -+ flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS; -+ alt_type = V_ASN1_IA5STRING; -+ if (flags & X509_CHECK_FLAG_NO_WILDCARDS) -+ equal = equal_nocase; -+ else -+ equal = equal_wildcard; -+ } else { -+ alt_type = V_ASN1_OCTET_STRING; -+ equal = equal_case; -+ } -+ -+ if (chklen == 0) -+ chklen = strlen(chk); -+ -+ gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); -+ if (gens) { -+ for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { -+ GENERAL_NAME *gen; -+ ASN1_STRING *cstr; -+ gen = sk_GENERAL_NAME_value(gens, i); -+ if (gen->type != check_type) -+ continue; -+ san_present = 1; -+ if (check_type == GEN_EMAIL) -+ cstr = gen->d.rfc822Name; -+ else if (check_type == GEN_DNS) -+ cstr = gen->d.dNSName; -+ else -+ cstr = gen->d.iPAddress; -+ /* Positive on success, negative on error! */ -+ if ((rv = do_check_string(cstr, alt_type, equal, flags, -+ chk, chklen, peername)) != 0) -+ break; -+ } -+ GENERAL_NAMES_free(gens); -+ if (rv != 0) -+ return rv; -+ if (san_present && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT)) -+ return 0; -+ } -+ -+ /* We're done if CN-ID is not pertinent */ -+ if (cnid == NID_undef || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT)) -+ return 0; -+ -+ i = -1; -+ name = X509_get_subject_name(x); -+ while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) { -+ const X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i); -+ const ASN1_STRING *str = X509_NAME_ENTRY_get_data(ne); -+ -+ /* Positive on success, negative on error! */ -+ if ((rv = do_check_string(str, -1, equal, flags, -+ chk, chklen, peername)) != 0) -+ return rv; -+ } -+ return 0; -+} -+ -+int X509_check_host(X509 *x, const char *chk, size_t chklen, -+ unsigned int flags, char **peername) -+{ -+ if (chk == NULL) -+ return -2; -+ /* -+ * Embedded NULs are disallowed, except as the last character of a -+ * string of length 2 or more (tolerate caller including terminating -+ * NUL in string length). -+ */ -+ if (chklen == 0) -+ chklen = strlen(chk); -+ else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen)) -+ return -2; -+ if (chklen > 1 && chk[chklen - 1] == '\0') -+ --chklen; -+ return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername); -+} -+ -+int X509_check_email(X509 *x, const char *chk, size_t chklen, -+ unsigned int flags) -+{ -+ if (chk == NULL) -+ return -2; -+ /* -+ * Embedded NULs are disallowed, except as the last character of a -+ * string of length 2 or more (tolerate caller including terminating -+ * NUL in string length). -+ */ -+ if (chklen == 0) -+ chklen = strlen((char *)chk); -+ else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen)) -+ return -2; -+ if (chklen > 1 && chk[chklen - 1] == '\0') -+ --chklen; -+ return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL); -+} -+ -+int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, -+ unsigned int flags) -+{ -+ if (chk == NULL) -+ return -2; -+ return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL); -+} -+ -+int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags) -+{ -+ unsigned char ipout[16]; -+ size_t iplen; -+ -+ if (ipasc == NULL) -+ return -2; -+ iplen = (size_t)a2i_ipadd(ipout, ipasc); -+ if (iplen == 0) -+ return -2; -+ return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL); -+} -+ -+/* -+ * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible -+ * with RFC3280. -+ */ -+ -+ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc) -+{ -+ unsigned char ipout[16]; -+ ASN1_OCTET_STRING *ret; -+ int iplen; -+ -+ /* If string contains a ':' assume IPv6 */ -+ -+ iplen = a2i_ipadd(ipout, ipasc); -+ -+ if (!iplen) -+ return NULL; -+ -+ ret = ASN1_OCTET_STRING_new(); -+ if (ret == NULL) -+ return NULL; -+ if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { -+ ASN1_OCTET_STRING_free(ret); -+ return NULL; -+ } -+ return ret; -+} -+ -+ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) -+{ -+ ASN1_OCTET_STRING *ret = NULL; -+ unsigned char ipout[32]; -+ char *iptmp = NULL, *p; -+ int iplen1, iplen2; -+ p = strchr(ipasc, '/'); -+ if (!p) -+ return NULL; -+ iptmp = OPENSSL_strdup(ipasc); -+ if (!iptmp) -+ return NULL; -+ p = iptmp + (p - ipasc); -+ *p++ = 0; -+ -+ iplen1 = a2i_ipadd(ipout, iptmp); -+ -+ if (!iplen1) -+ goto err; -+ -+ iplen2 = a2i_ipadd(ipout + iplen1, p); -+ -+ OPENSSL_free(iptmp); -+ iptmp = NULL; -+ -+ if (!iplen2 || (iplen1 != iplen2)) -+ goto err; -+ -+ ret = ASN1_OCTET_STRING_new(); -+ if (ret == NULL) -+ goto err; -+ if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) -+ goto err; -+ -+ return ret; -+ -+ err: -+ OPENSSL_free(iptmp); -+ ASN1_OCTET_STRING_free(ret); -+ return NULL; -+} -+ -+int a2i_ipadd(unsigned char *ipout, const char *ipasc) -+{ -+ /* If string contains a ':' assume IPv6 */ -+ -+ if (strchr(ipasc, ':')) { -+ if (!ipv6_from_asc(ipout, ipasc)) -+ return 0; -+ return 16; -+ } else { -+ if (!ipv4_from_asc(ipout, ipasc)) -+ return 0; -+ return 4; -+ } -+} -+ -+static int ipv4_from_asc(unsigned char *v4, const char *in) -+{ -+ int a0, a1, a2, a3; -+ if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) -+ return 0; -+ if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) -+ || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) -+ return 0; -+ v4[0] = a0; -+ v4[1] = a1; -+ v4[2] = a2; -+ v4[3] = a3; -+ return 1; -+} -+ -+typedef struct { -+ /* Temporary store for IPV6 output */ -+ unsigned char tmp[16]; -+ /* Total number of bytes in tmp */ -+ int total; -+ /* The position of a zero (corresponding to '::') */ -+ int zero_pos; -+ /* Number of zeroes */ -+ int zero_cnt; -+} IPV6_STAT; -+ -+static int ipv6_from_asc(unsigned char *v6, const char *in) -+{ -+ IPV6_STAT v6stat; -+ v6stat.total = 0; -+ v6stat.zero_pos = -1; -+ v6stat.zero_cnt = 0; -+ /* -+ * Treat the IPv6 representation as a list of values separated by ':'. -+ * The presence of a '::' will parse as one, two or three zero length -+ * elements. -+ */ -+ if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) -+ return 0; -+ -+ /* Now for some sanity checks */ -+ -+ if (v6stat.zero_pos == -1) { -+ /* If no '::' must have exactly 16 bytes */ -+ if (v6stat.total != 16) -+ return 0; -+ } else { -+ /* If '::' must have less than 16 bytes */ -+ if (v6stat.total == 16) -+ return 0; -+ /* More than three zeroes is an error */ -+ if (v6stat.zero_cnt > 3) -+ return 0; -+ /* Can only have three zeroes if nothing else present */ -+ else if (v6stat.zero_cnt == 3) { -+ if (v6stat.total > 0) -+ return 0; -+ } -+ /* Can only have two zeroes if at start or end */ -+ else if (v6stat.zero_cnt == 2) { -+ if ((v6stat.zero_pos != 0) -+ && (v6stat.zero_pos != v6stat.total)) -+ return 0; -+ } else -+ /* Can only have one zero if *not* start or end */ -+ { -+ if ((v6stat.zero_pos == 0) -+ || (v6stat.zero_pos == v6stat.total)) -+ return 0; -+ } -+ } -+ -+ /* Format result */ -+ -+ if (v6stat.zero_pos >= 0) { -+ /* Copy initial part */ -+ memcpy(v6, v6stat.tmp, v6stat.zero_pos); -+ /* Zero middle */ -+ memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); -+ /* Copy final part */ -+ if (v6stat.total != v6stat.zero_pos) -+ memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, -+ v6stat.tmp + v6stat.zero_pos, -+ v6stat.total - v6stat.zero_pos); -+ } else -+ memcpy(v6, v6stat.tmp, 16); -+ -+ return 1; -+} -+ -+static int ipv6_cb(const char *elem, int len, void *usr) -+{ -+ IPV6_STAT *s = usr; -+ /* Error if 16 bytes written */ -+ if (s->total == 16) -+ return 0; -+ if (len == 0) { -+ /* Zero length element, corresponds to '::' */ -+ if (s->zero_pos == -1) -+ s->zero_pos = s->total; -+ /* If we've already got a :: its an error */ -+ else if (s->zero_pos != s->total) -+ return 0; -+ s->zero_cnt++; -+ } else { -+ /* If more than 4 characters could be final a.b.c.d form */ -+ if (len > 4) { -+ /* Need at least 4 bytes left */ -+ if (s->total > 12) -+ return 0; -+ /* Must be end of string */ -+ if (elem[len]) -+ return 0; -+ if (!ipv4_from_asc(s->tmp + s->total, elem)) -+ return 0; -+ s->total += 4; -+ } else { -+ if (!ipv6_hex(s->tmp + s->total, elem, len)) -+ return 0; -+ s->total += 2; -+ } -+ } -+ return 1; -+} -+ -+/* -+ * Convert a string of up to 4 hex digits into the corresponding IPv6 form. -+ */ -+ -+static int ipv6_hex(unsigned char *out, const char *in, int inlen) -+{ -+ unsigned char c; -+ unsigned int num = 0; -+ int x; -+ -+ if (inlen > 4) -+ return 0; -+ while (inlen--) { -+ c = *in++; -+ num <<= 4; -+ x = OPENSSL_hexchar2int(c); -+ if (x < 0) -+ return 0; -+ num |= (char)x; -+ } -+ out[0] = num >> 8; -+ out[1] = num & 0xff; -+ return 1; -+} -+ -+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, -+ unsigned long chtype) -+{ -+ CONF_VALUE *v; -+ int i, mval, spec_char, plus_char; -+ char *p, *type; -+ if (!nm) -+ return 0; -+ -+ for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { -+ v = sk_CONF_VALUE_value(dn_sk, i); -+ type = v->name; -+ /* -+ * Skip past any leading X. X: X, etc to allow for multiple instances -+ */ -+ for (p = type; *p; p++) { -+#ifndef CHARSET_EBCDIC -+ spec_char = ((*p == ':') || (*p == ',') || (*p == '.')); -+#else -+ spec_char = ((*p == os_toascii[':']) || (*p == os_toascii[',']) -+ || (*p == os_toascii['.'])); -+#endif -+ if (spec_char) { -+ p++; -+ if (*p) -+ type = p; -+ break; -+ } -+ } -+#ifndef CHARSET_EBCDIC -+ plus_char = (*type == '+'); -+#else -+ plus_char = (*type == os_toascii['+']); -+#endif -+ if (plus_char) { -+ mval = -1; -+ type++; -+ } else -+ mval = 0; -+ if (!X509_NAME_add_entry_by_txt(nm, type, chtype, -+ (unsigned char *)v->value, -1, -1, -+ mval)) -+ return 0; -+ -+ } -+ return 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3conf.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3conf.c -new file mode 100644 -index 0000000..966ab90 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3conf.c -@@ -0,0 +1,79 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include "internal/cryptlib.h" -+#include -+#include -+#include -+#include -+ -+/* Test application to add extensions from a config file */ -+ -+int main(int argc, char **argv) -+{ -+ LHASH *conf; -+ X509 *cert; -+ FILE *inf; -+ char *conf_file; -+ int i; -+ int count; -+ X509_EXTENSION *ext; -+ X509V3_add_standard_extensions(); -+ ERR_load_crypto_strings(); -+ if (!argv[1]) { -+ fprintf(stderr, "Usage: v3conf cert.pem [file.cnf]\n"); -+ exit(1); -+ } -+ conf_file = argv[2]; -+ if (!conf_file) -+ conf_file = "test.cnf"; -+ conf = CONF_load(NULL, "test.cnf", NULL); -+ if (!conf) { -+ fprintf(stderr, "Error opening Config file %s\n", conf_file); -+ ERR_print_errors_fp(stderr); -+ exit(1); -+ } -+ -+ inf = fopen(argv[1], "r"); -+ if (!inf) { -+ fprintf(stderr, "Can't open certificate file %s\n", argv[1]); -+ exit(1); -+ } -+ cert = PEM_read_X509(inf, NULL, NULL); -+ if (!cert) { -+ fprintf(stderr, "Error reading certificate file %s\n", argv[1]); -+ exit(1); -+ } -+ fclose(inf); -+ -+ sk_pop_free(cert->cert_info->extensions, X509_EXTENSION_free); -+ cert->cert_info->extensions = NULL; -+ -+ if (!X509V3_EXT_add_conf(conf, NULL, "test_section", cert)) { -+ fprintf(stderr, "Error adding extensions\n"); -+ ERR_print_errors_fp(stderr); -+ exit(1); -+ } -+ -+ count = X509_get_ext_count(cert); -+ printf("%d extensions\n", count); -+ for (i = 0; i < count; i++) { -+ ext = X509_get_ext(cert, i); -+ printf("%s", OBJ_nid2ln(OBJ_obj2nid(ext->object))); -+ if (ext->critical) -+ printf(",critical:\n"); -+ else -+ printf(":\n"); -+ X509V3_EXT_print_fp(stdout, ext, 0, 0); -+ printf("\n"); -+ -+ } -+ return 0; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3err.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3err.c -new file mode 100644 -index 0000000..5d79c8c ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3err.c -@@ -0,0 +1,187 @@ -+/* -+ * Generated by util/mkerr.pl DO NOT EDIT -+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+ -+/* BEGIN ERROR CODES */ -+#ifndef OPENSSL_NO_ERR -+ -+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0) -+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason) -+ -+static ERR_STRING_DATA X509V3_str_functs[] = { -+ {ERR_FUNC(X509V3_F_A2I_GENERAL_NAME), "a2i_GENERAL_NAME"}, -+ {ERR_FUNC(X509V3_F_ADDR_VALIDATE_PATH_INTERNAL), -+ "addr_validate_path_internal"}, -+ {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE), -+ "ASIdentifierChoice_canonize"}, -+ {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL), -+ "ASIdentifierChoice_is_canonical"}, -+ {ERR_FUNC(X509V3_F_COPY_EMAIL), "copy_email"}, -+ {ERR_FUNC(X509V3_F_COPY_ISSUER), "copy_issuer"}, -+ {ERR_FUNC(X509V3_F_DO_DIRNAME), "do_dirname"}, -+ {ERR_FUNC(X509V3_F_DO_EXT_I2D), "do_ext_i2d"}, -+ {ERR_FUNC(X509V3_F_DO_EXT_NCONF), "do_ext_nconf"}, -+ {ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "gnames_from_sectname"}, -+ {ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"}, -+ {ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "i2s_ASN1_IA5STRING"}, -+ {ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER), "i2s_ASN1_INTEGER"}, -+ {ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS), -+ "i2v_AUTHORITY_INFO_ACCESS"}, -+ {ERR_FUNC(X509V3_F_NOTICE_SECTION), "notice_section"}, -+ {ERR_FUNC(X509V3_F_NREF_NOS), "nref_nos"}, -+ {ERR_FUNC(X509V3_F_POLICY_SECTION), "policy_section"}, -+ {ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE), "process_pci_value"}, -+ {ERR_FUNC(X509V3_F_R2I_CERTPOL), "r2i_certpol"}, -+ {ERR_FUNC(X509V3_F_R2I_PCI), "r2i_pci"}, -+ {ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING), "s2i_ASN1_IA5STRING"}, -+ {ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER), "s2i_ASN1_INTEGER"}, -+ {ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"}, -+ {ERR_FUNC(X509V3_F_S2I_SKEY_ID), "s2i_skey_id"}, -+ {ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "set_dist_point_name"}, -+ {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"}, -+ {ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"}, -+ {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG), "SXNET_add_id_ulong"}, -+ {ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC), "SXNET_get_id_asc"}, -+ {ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG), "SXNET_get_id_ulong"}, -+ {ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS), "v2i_ASIdentifiers"}, -+ {ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING), "v2i_ASN1_BIT_STRING"}, -+ {ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS), -+ "v2i_AUTHORITY_INFO_ACCESS"}, -+ {ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID), "v2i_AUTHORITY_KEYID"}, -+ {ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS), "v2i_BASIC_CONSTRAINTS"}, -+ {ERR_FUNC(X509V3_F_V2I_CRLD), "v2i_crld"}, -+ {ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "v2i_EXTENDED_KEY_USAGE"}, -+ {ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"}, -+ {ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"}, -+ {ERR_FUNC(X509V3_F_V2I_IDP), "v2i_idp"}, -+ {ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "v2i_IPAddrBlocks"}, -+ {ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "v2i_issuer_alt"}, -+ {ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "v2i_NAME_CONSTRAINTS"}, -+ {ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "v2i_POLICY_CONSTRAINTS"}, -+ {ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "v2i_POLICY_MAPPINGS"}, -+ {ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "v2i_subject_alt"}, -+ {ERR_FUNC(X509V3_F_V2I_TLS_FEATURE), "v2i_TLS_FEATURE"}, -+ {ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "v3_generic_extension"}, -+ {ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"}, -+ {ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"}, -+ {ERR_FUNC(X509V3_F_X509V3_EXT_ADD), "X509V3_EXT_add"}, -+ {ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS), "X509V3_EXT_add_alias"}, -+ {ERR_FUNC(X509V3_F_X509V3_EXT_I2D), "X509V3_EXT_i2d"}, -+ {ERR_FUNC(X509V3_F_X509V3_EXT_NCONF), "X509V3_EXT_nconf"}, -+ {ERR_FUNC(X509V3_F_X509V3_GET_SECTION), "X509V3_get_section"}, -+ {ERR_FUNC(X509V3_F_X509V3_GET_STRING), "X509V3_get_string"}, -+ {ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL), "X509V3_get_value_bool"}, -+ {ERR_FUNC(X509V3_F_X509V3_PARSE_LIST), "X509V3_parse_list"}, -+ {ERR_FUNC(X509V3_F_X509_PURPOSE_ADD), "X509_PURPOSE_add"}, -+ {ERR_FUNC(X509V3_F_X509_PURPOSE_SET), "X509_PURPOSE_set"}, -+ {0, NULL} -+}; -+ -+static ERR_STRING_DATA X509V3_str_reasons[] = { -+ {ERR_REASON(X509V3_R_BAD_IP_ADDRESS), "bad ip address"}, -+ {ERR_REASON(X509V3_R_BAD_OBJECT), "bad object"}, -+ {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR), "bn dec2bn error"}, -+ {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR), -+ "bn to asn1 integer error"}, -+ {ERR_REASON(X509V3_R_DIRNAME_ERROR), "dirname error"}, -+ {ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET), "distpoint already set"}, -+ {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID), "duplicate zone id"}, -+ {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"}, -+ {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION), -+ "error creating extension"}, -+ {ERR_REASON(X509V3_R_ERROR_IN_EXTENSION), "error in extension"}, -+ {ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"}, -+ {ERR_REASON(X509V3_R_EXTENSION_EXISTS), "extension exists"}, -+ {ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"}, -+ {ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"}, -+ {ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED), -+ "extension setting not supported"}, -+ {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"}, -+ {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"}, -+ {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG), -+ "incorrect policy syntax tag"}, -+ {ERR_REASON(X509V3_R_INVALID_ASNUMBER), "invalid asnumber"}, -+ {ERR_REASON(X509V3_R_INVALID_ASRANGE), "invalid asrange"}, -+ {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"}, -+ {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING), -+ "invalid extension string"}, -+ {ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"}, -+ {ERR_REASON(X509V3_R_INVALID_IPADDRESS), "invalid ipaddress"}, -+ {ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"}, -+ {ERR_REASON(X509V3_R_INVALID_NAME), "invalid name"}, -+ {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, -+ {ERR_REASON(X509V3_R_INVALID_NULL_NAME), "invalid null name"}, -+ {ERR_REASON(X509V3_R_INVALID_NULL_VALUE), "invalid null value"}, -+ {ERR_REASON(X509V3_R_INVALID_NUMBER), "invalid number"}, -+ {ERR_REASON(X509V3_R_INVALID_NUMBERS), "invalid numbers"}, -+ {ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER), -+ "invalid object identifier"}, -+ {ERR_REASON(X509V3_R_INVALID_OPTION), "invalid option"}, -+ {ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER), -+ "invalid policy identifier"}, -+ {ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING), -+ "invalid proxy policy setting"}, -+ {ERR_REASON(X509V3_R_INVALID_PURPOSE), "invalid purpose"}, -+ {ERR_REASON(X509V3_R_INVALID_SAFI), "invalid safi"}, -+ {ERR_REASON(X509V3_R_INVALID_SECTION), "invalid section"}, -+ {ERR_REASON(X509V3_R_INVALID_SYNTAX), "invalid syntax"}, -+ {ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"}, -+ {ERR_REASON(X509V3_R_MISSING_VALUE), "missing value"}, -+ {ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), -+ "need organization and numbers"}, -+ {ERR_REASON(X509V3_R_NO_CONFIG_DATABASE), "no config database"}, -+ {ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"}, -+ {ERR_REASON(X509V3_R_NO_ISSUER_DETAILS), "no issuer details"}, -+ {ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"}, -+ {ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED), -+ "no proxy cert policy language defined"}, -+ {ERR_REASON(X509V3_R_NO_PUBLIC_KEY), "no public key"}, -+ {ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS), "no subject details"}, -+ {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED), "operation not defined"}, -+ {ERR_REASON(X509V3_R_OTHERNAME_ERROR), "othername error"}, -+ {ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED), -+ "policy language already defined"}, -+ {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH), "policy path length"}, -+ {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED), -+ "policy path length already defined"}, -+ {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY), -+ "policy when proxy language requires no policy"}, -+ {ERR_REASON(X509V3_R_SECTION_NOT_FOUND), "section not found"}, -+ {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS), -+ "unable to get issuer details"}, -+ {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID), -+ "unable to get issuer keyid"}, -+ {ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT), -+ "unknown bit string argument"}, -+ {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION), "unknown extension"}, -+ {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"}, -+ {ERR_REASON(X509V3_R_UNKNOWN_OPTION), "unknown option"}, -+ {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION), "unsupported option"}, -+ {ERR_REASON(X509V3_R_UNSUPPORTED_TYPE), "unsupported type"}, -+ {ERR_REASON(X509V3_R_USER_TOO_LONG), "user too long"}, -+ {0, NULL} -+}; -+ -+#endif -+ -+int ERR_load_X509V3_strings(void) -+{ -+#ifndef OPENSSL_NO_ERR -+ -+ if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) { -+ ERR_load_strings(0, X509V3_str_functs); -+ ERR_load_strings(0, X509V3_str_reasons); -+ } -+#endif -+ return 1; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3prin.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3prin.c -new file mode 100644 -index 0000000..7431a4e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/v3prin.c -@@ -0,0 +1,50 @@ -+/* -+ * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ X509 *cert; -+ FILE *inf; -+ int i, count; -+ X509_EXTENSION *ext; -+ -+ X509V3_add_standard_extensions(); -+ ERR_load_crypto_strings(); -+ if (!argv[1]) { -+ fprintf(stderr, "Usage v3prin cert.pem\n"); -+ exit(1); -+ } -+ if ((inf = fopen(argv[1], "r")) == NULL) { -+ fprintf(stderr, "Can't open %s\n", argv[1]); -+ exit(1); -+ } -+ if ((cert = PEM_read_X509(inf, NULL, NULL)) == NULL) { -+ fprintf(stderr, "Can't read certificate %s\n", argv[1]); -+ ERR_print_errors_fp(stderr); -+ exit(1); -+ } -+ fclose(inf); -+ count = X509_get_ext_count(cert); -+ printf("%d extensions\n", count); -+ for (i = 0; i < count; i++) { -+ ext = X509_get_ext(cert, i); -+ printf("%s\n", OBJ_nid2ln(OBJ_obj2nid(ext->object))); -+ if (!X509V3_EXT_print_fp(stdout, ext, 0, 0)) -+ ERR_print_errors_fp(stderr); -+ printf("\n"); -+ -+ } -+ return 0; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x86_64cpuid.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/x86_64cpuid.pl -new file mode 100644 -index 0000000..6cb1521 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x86_64cpuid.pl -@@ -0,0 +1,459 @@ -+#! /usr/bin/env perl -+# Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. -+# -+# Licensed under the OpenSSL license (the "License"). You may not use -+# this file except in compliance with the License. You can obtain a copy -+# in the file LICENSE in the source distribution or at -+# https://www.openssl.org/source/license.html -+ -+ -+$flavour = shift; -+$output = shift; -+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } -+ -+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); -+ -+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or -+( $xlate="${dir}perlasm/x86_64-xlate.pl" and -f $xlate) or -+die "can't locate x86_64-xlate.pl"; -+ -+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""; -+*STDOUT=*OUT; -+ -+($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order -+ ("%rdi","%rsi","%rdx","%rcx"); # Unix order -+ -+print<<___; -+.extern OPENSSL_cpuid_setup -+.hidden OPENSSL_cpuid_setup -+.section .init -+ call OPENSSL_cpuid_setup -+ -+.hidden OPENSSL_ia32cap_P -+.comm OPENSSL_ia32cap_P,16,4 -+ -+.text -+ -+.globl OPENSSL_atomic_add -+.type OPENSSL_atomic_add,\@abi-omnipotent -+.align 16 -+OPENSSL_atomic_add: -+ movl ($arg1),%eax -+.Lspin: leaq ($arg2,%rax),%r8 -+ .byte 0xf0 # lock -+ cmpxchgl %r8d,($arg1) -+ jne .Lspin -+ movl %r8d,%eax -+ .byte 0x48,0x98 # cltq/cdqe -+ ret -+.size OPENSSL_atomic_add,.-OPENSSL_atomic_add -+ -+.globl OPENSSL_rdtsc -+.type OPENSSL_rdtsc,\@abi-omnipotent -+.align 16 -+OPENSSL_rdtsc: -+ rdtsc -+ shl \$32,%rdx -+ or %rdx,%rax -+ ret -+.size OPENSSL_rdtsc,.-OPENSSL_rdtsc -+ -+.globl OPENSSL_ia32_cpuid -+.type OPENSSL_ia32_cpuid,\@function,1 -+.align 16 -+OPENSSL_ia32_cpuid: -+ mov %rbx,%r8 # save %rbx -+ -+ xor %eax,%eax -+ mov %eax,8(%rdi) # clear 3rd word -+ cpuid -+ mov %eax,%r11d # max value for standard query level -+ -+ xor %eax,%eax -+ cmp \$0x756e6547,%ebx # "Genu" -+ setne %al -+ mov %eax,%r9d -+ cmp \$0x49656e69,%edx # "ineI" -+ setne %al -+ or %eax,%r9d -+ cmp \$0x6c65746e,%ecx # "ntel" -+ setne %al -+ or %eax,%r9d # 0 indicates Intel CPU -+ jz .Lintel -+ -+ cmp \$0x68747541,%ebx # "Auth" -+ setne %al -+ mov %eax,%r10d -+ cmp \$0x69746E65,%edx # "enti" -+ setne %al -+ or %eax,%r10d -+ cmp \$0x444D4163,%ecx # "cAMD" -+ setne %al -+ or %eax,%r10d # 0 indicates AMD CPU -+ jnz .Lintel -+ -+ # AMD specific -+ mov \$0x80000000,%eax -+ cpuid -+ cmp \$0x80000001,%eax -+ jb .Lintel -+ mov %eax,%r10d -+ mov \$0x80000001,%eax -+ cpuid -+ or %ecx,%r9d -+ and \$0x00000801,%r9d # isolate AMD XOP bit, 1<<11 -+ -+ cmp \$0x80000008,%r10d -+ jb .Lintel -+ -+ mov \$0x80000008,%eax -+ cpuid -+ movzb %cl,%r10 # number of cores - 1 -+ inc %r10 # number of cores -+ -+ mov \$1,%eax -+ cpuid -+ bt \$28,%edx # test hyper-threading bit -+ jnc .Lgeneric -+ shr \$16,%ebx # number of logical processors -+ cmp %r10b,%bl -+ ja .Lgeneric -+ and \$0xefffffff,%edx # ~(1<<28) -+ jmp .Lgeneric -+ -+.Lintel: -+ cmp \$4,%r11d -+ mov \$-1,%r10d -+ jb .Lnocacheinfo -+ -+ mov \$4,%eax -+ mov \$0,%ecx # query L1D -+ cpuid -+ mov %eax,%r10d -+ shr \$14,%r10d -+ and \$0xfff,%r10d # number of cores -1 per L1D -+ -+ cmp \$7,%r11d -+ jb .Lnocacheinfo -+ -+ mov \$7,%eax -+ xor %ecx,%ecx -+ cpuid -+ mov %ebx,8(%rdi) -+ -+.Lnocacheinfo: -+ mov \$1,%eax -+ cpuid -+ and \$0xbfefffff,%edx # force reserved bits to 0 -+ cmp \$0,%r9d -+ jne .Lnotintel -+ or \$0x40000000,%edx # set reserved bit#30 on Intel CPUs -+ and \$15,%ah -+ cmp \$15,%ah # examine Family ID -+ jne .Lnotintel -+ or \$0x00100000,%edx # set reserved bit#20 to engage RC4_CHAR -+.Lnotintel: -+ bt \$28,%edx # test hyper-threading bit -+ jnc .Lgeneric -+ and \$0xefffffff,%edx # ~(1<<28) -+ cmp \$0,%r10d -+ je .Lgeneric -+ -+ or \$0x10000000,%edx # 1<<28 -+ shr \$16,%ebx -+ cmp \$1,%bl # see if cache is shared -+ ja .Lgeneric -+ and \$0xefffffff,%edx # ~(1<<28) -+.Lgeneric: -+ and \$0x00000800,%r9d # isolate AMD XOP flag -+ and \$0xfffff7ff,%ecx -+ or %ecx,%r9d # merge AMD XOP flag -+ -+ mov %edx,%r10d # %r9d:%r10d is copy of %ecx:%edx -+ bt \$27,%r9d # check OSXSAVE bit -+ jnc .Lclear_avx -+ xor %ecx,%ecx # XCR0 -+ .byte 0x0f,0x01,0xd0 # xgetbv -+ and \$6,%eax # isolate XMM and YMM state support -+ cmp \$6,%eax -+ je .Ldone -+.Lclear_avx: -+ mov \$0xefffe7ff,%eax # ~(1<<28|1<<12|1<<11) -+ and %eax,%r9d # clear AVX, FMA and AMD XOP bits -+ andl \$0xffffffdf,8(%rdi) # cleax AVX2, ~(1<<5) -+.Ldone: -+ shl \$32,%r9 -+ mov %r10d,%eax -+ mov %r8,%rbx # restore %rbx -+ or %r9,%rax -+ ret -+.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid -+ -+.globl OPENSSL_cleanse -+.type OPENSSL_cleanse,\@abi-omnipotent -+.align 16 -+OPENSSL_cleanse: -+ xor %rax,%rax -+ cmp \$15,$arg2 -+ jae .Lot -+ cmp \$0,$arg2 -+ je .Lret -+.Little: -+ mov %al,($arg1) -+ sub \$1,$arg2 -+ lea 1($arg1),$arg1 -+ jnz .Little -+.Lret: -+ ret -+.align 16 -+.Lot: -+ test \$7,$arg1 -+ jz .Laligned -+ mov %al,($arg1) -+ lea -1($arg2),$arg2 -+ lea 1($arg1),$arg1 -+ jmp .Lot -+.Laligned: -+ mov %rax,($arg1) -+ lea -8($arg2),$arg2 -+ test \$-8,$arg2 -+ lea 8($arg1),$arg1 -+ jnz .Laligned -+ cmp \$0,$arg2 -+ jne .Little -+ ret -+.size OPENSSL_cleanse,.-OPENSSL_cleanse -+ -+.globl CRYPTO_memcmp -+.type CRYPTO_memcmp,\@abi-omnipotent -+.align 16 -+CRYPTO_memcmp: -+ xor %rax,%rax -+ xor %r10,%r10 -+ cmp \$0,$arg3 -+ je .Lno_data -+.Loop_cmp: -+ mov ($arg1),%r10b -+ lea 1($arg1),$arg1 -+ xor ($arg2),%r10b -+ lea 1($arg2),$arg2 -+ or %r10b,%al -+ dec $arg3 -+ jnz .Loop_cmp -+ neg %rax -+ shr \$63,%rax -+.Lno_data: -+ ret -+.size CRYPTO_memcmp,.-CRYPTO_memcmp -+___ -+ -+print<<___ if (!$win64); -+.globl OPENSSL_wipe_cpu -+.type OPENSSL_wipe_cpu,\@abi-omnipotent -+.align 16 -+OPENSSL_wipe_cpu: -+ pxor %xmm0,%xmm0 -+ pxor %xmm1,%xmm1 -+ pxor %xmm2,%xmm2 -+ pxor %xmm3,%xmm3 -+ pxor %xmm4,%xmm4 -+ pxor %xmm5,%xmm5 -+ pxor %xmm6,%xmm6 -+ pxor %xmm7,%xmm7 -+ pxor %xmm8,%xmm8 -+ pxor %xmm9,%xmm9 -+ pxor %xmm10,%xmm10 -+ pxor %xmm11,%xmm11 -+ pxor %xmm12,%xmm12 -+ pxor %xmm13,%xmm13 -+ pxor %xmm14,%xmm14 -+ pxor %xmm15,%xmm15 -+ xorq %rcx,%rcx -+ xorq %rdx,%rdx -+ xorq %rsi,%rsi -+ xorq %rdi,%rdi -+ xorq %r8,%r8 -+ xorq %r9,%r9 -+ xorq %r10,%r10 -+ xorq %r11,%r11 -+ leaq 8(%rsp),%rax -+ ret -+.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu -+___ -+print<<___ if ($win64); -+.globl OPENSSL_wipe_cpu -+.type OPENSSL_wipe_cpu,\@abi-omnipotent -+.align 16 -+OPENSSL_wipe_cpu: -+ pxor %xmm0,%xmm0 -+ pxor %xmm1,%xmm1 -+ pxor %xmm2,%xmm2 -+ pxor %xmm3,%xmm3 -+ pxor %xmm4,%xmm4 -+ pxor %xmm5,%xmm5 -+ xorq %rcx,%rcx -+ xorq %rdx,%rdx -+ xorq %r8,%r8 -+ xorq %r9,%r9 -+ xorq %r10,%r10 -+ xorq %r11,%r11 -+ leaq 8(%rsp),%rax -+ ret -+.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu -+___ -+{ -+my $out="%r10"; -+my $cnt="%rcx"; -+my $max="%r11"; -+my $lasttick="%r8d"; -+my $lastdiff="%r9d"; -+my $redzone=win64?8:-8; -+ -+print<<___; -+.globl OPENSSL_instrument_bus -+.type OPENSSL_instrument_bus,\@abi-omnipotent -+.align 16 -+OPENSSL_instrument_bus: -+ mov $arg1,$out # tribute to Win64 -+ mov $arg2,$cnt -+ mov $arg2,$max -+ -+ rdtsc # collect 1st tick -+ mov %eax,$lasttick # lasttick = tick -+ mov \$0,$lastdiff # lastdiff = 0 -+ clflush ($out) -+ .byte 0xf0 # lock -+ add $lastdiff,($out) -+ jmp .Loop -+.align 16 -+.Loop: rdtsc -+ mov %eax,%edx -+ sub $lasttick,%eax -+ mov %edx,$lasttick -+ mov %eax,$lastdiff -+ clflush ($out) -+ .byte 0xf0 # lock -+ add %eax,($out) -+ lea 4($out),$out -+ sub \$1,$cnt -+ jnz .Loop -+ -+ mov $max,%rax -+ ret -+.size OPENSSL_instrument_bus,.-OPENSSL_instrument_bus -+ -+.globl OPENSSL_instrument_bus2 -+.type OPENSSL_instrument_bus2,\@abi-omnipotent -+.align 16 -+OPENSSL_instrument_bus2: -+ mov $arg1,$out # tribute to Win64 -+ mov $arg2,$cnt -+ mov $arg3,$max -+ mov $cnt,$redzone(%rsp) -+ -+ rdtsc # collect 1st tick -+ mov %eax,$lasttick # lasttick = tick -+ mov \$0,$lastdiff # lastdiff = 0 -+ -+ clflush ($out) -+ .byte 0xf0 # lock -+ add $lastdiff,($out) -+ -+ rdtsc # collect 1st diff -+ mov %eax,%edx -+ sub $lasttick,%eax # diff -+ mov %edx,$lasttick # lasttick = tick -+ mov %eax,$lastdiff # lastdiff = diff -+.Loop2: -+ clflush ($out) -+ .byte 0xf0 # lock -+ add %eax,($out) # accumulate diff -+ -+ sub \$1,$max -+ jz .Ldone2 -+ -+ rdtsc -+ mov %eax,%edx -+ sub $lasttick,%eax # diff -+ mov %edx,$lasttick # lasttick = tick -+ cmp $lastdiff,%eax -+ mov %eax,$lastdiff # lastdiff = diff -+ mov \$0,%edx -+ setne %dl -+ sub %rdx,$cnt # conditional --$cnt -+ lea ($out,%rdx,4),$out # conditional ++$out -+ jnz .Loop2 -+ -+.Ldone2: -+ mov $redzone(%rsp),%rax -+ sub $cnt,%rax -+ ret -+.size OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2 -+___ -+} -+ -+sub gen_random { -+my $rdop = shift; -+print<<___; -+.globl OPENSSL_ia32_${rdop} -+.type OPENSSL_ia32_${rdop},\@abi-omnipotent -+.align 16 -+OPENSSL_ia32_${rdop}: -+ mov \$8,%ecx -+.Loop_${rdop}: -+ ${rdop} %rax -+ jc .Lbreak_${rdop} -+ loop .Loop_${rdop} -+.Lbreak_${rdop}: -+ cmp \$0,%rax -+ cmove %rcx,%rax -+ ret -+.size OPENSSL_ia32_${rdop},.-OPENSSL_ia32_${rdop} -+ -+.globl OPENSSL_ia32_${rdop}_bytes -+.type OPENSSL_ia32_${rdop}_bytes,\@abi-omnipotent -+.align 16 -+OPENSSL_ia32_${rdop}_bytes: -+ xor %rax, %rax # return value -+ cmp \$0,$arg2 -+ je .Ldone_${rdop}_bytes -+ -+ mov \$8,%r11 -+.Loop_${rdop}_bytes: -+ ${rdop} %r10 -+ jc .Lbreak_${rdop}_bytes -+ dec %r11 -+ jnz .Loop_${rdop}_bytes -+ jmp .Ldone_${rdop}_bytes -+ -+.align 16 -+.Lbreak_${rdop}_bytes: -+ cmp \$8,$arg2 -+ jb .Ltail_${rdop}_bytes -+ mov %r10,($arg1) -+ lea 8($arg1),$arg1 -+ add \$8,%rax -+ sub \$8,$arg2 -+ jz .Ldone_${rdop}_bytes -+ mov \$8,%r11 -+ jmp .Loop_${rdop}_bytes -+ -+.align 16 -+.Ltail_${rdop}_bytes: -+ mov %r10b,($arg1) -+ lea 1($arg1),$arg1 -+ inc %rax -+ shr \$8,%r8 -+ dec $arg2 -+ jnz .Ltail_${rdop}_bytes -+ -+.Ldone_${rdop}_bytes: -+ ret -+.size OPENSSL_ia32_${rdop}_bytes,.-OPENSSL_ia32_${rdop}_bytes -+___ -+} -+gen_random("rdrand"); -+gen_random("rdseed"); -+ -+close STDOUT; # flush -diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x86cpuid.pl b/CryptoPkg/Library/OpensslLib/openssl/crypto/x86cpuid.pl -new file mode 100644 -index 0000000..c45b183 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x86cpuid.pl -@@ -0,0 +1,561 @@ -+#! /usr/bin/env perl -+# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. -+# -+# Licensed under the OpenSSL license (the "License"). You may not use -+# this file except in compliance with the License. You can obtain a copy -+# in the file LICENSE in the source distribution or at -+# https://www.openssl.org/source/license.html -+ -+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -+push(@INC, "${dir}perlasm", "perlasm"); -+require "x86asm.pl"; -+ -+$output = pop; -+open OUT,">$output"; -+*STDOUT=*OUT; -+ -+&asm_init($ARGV[0],"x86cpuid"); -+ -+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } -+ -+&function_begin("OPENSSL_ia32_cpuid"); -+ &xor ("edx","edx"); -+ &pushf (); -+ &pop ("eax"); -+ &mov ("ecx","eax"); -+ &xor ("eax",1<<21); -+ &push ("eax"); -+ &popf (); -+ &pushf (); -+ &pop ("eax"); -+ &xor ("ecx","eax"); -+ &xor ("eax","eax"); -+ &bt ("ecx",21); -+ &jnc (&label("nocpuid")); -+ &mov ("esi",&wparam(0)); -+ &mov (&DWP(8,"esi"),"eax"); # clear 3rd word -+ &cpuid (); -+ &mov ("edi","eax"); # max value for standard query level -+ -+ &xor ("eax","eax"); -+ &cmp ("ebx",0x756e6547); # "Genu" -+ &setne (&LB("eax")); -+ &mov ("ebp","eax"); -+ &cmp ("edx",0x49656e69); # "ineI" -+ &setne (&LB("eax")); -+ &or ("ebp","eax"); -+ &cmp ("ecx",0x6c65746e); # "ntel" -+ &setne (&LB("eax")); -+ &or ("ebp","eax"); # 0 indicates Intel CPU -+ &jz (&label("intel")); -+ -+ &cmp ("ebx",0x68747541); # "Auth" -+ &setne (&LB("eax")); -+ &mov ("esi","eax"); -+ &cmp ("edx",0x69746E65); # "enti" -+ &setne (&LB("eax")); -+ &or ("esi","eax"); -+ &cmp ("ecx",0x444D4163); # "cAMD" -+ &setne (&LB("eax")); -+ &or ("esi","eax"); # 0 indicates AMD CPU -+ &jnz (&label("intel")); -+ -+ # AMD specific -+ &mov ("eax",0x80000000); -+ &cpuid (); -+ &cmp ("eax",0x80000001); -+ &jb (&label("intel")); -+ &mov ("esi","eax"); -+ &mov ("eax",0x80000001); -+ &cpuid (); -+ &or ("ebp","ecx"); -+ &and ("ebp",1<<11|1); # isolate XOP bit -+ &cmp ("esi",0x80000008); -+ &jb (&label("intel")); -+ -+ &mov ("eax",0x80000008); -+ &cpuid (); -+ &movz ("esi",&LB("ecx")); # number of cores - 1 -+ &inc ("esi"); # number of cores -+ -+ &mov ("eax",1); -+ &xor ("ecx","ecx"); -+ &cpuid (); -+ &bt ("edx",28); -+ &jnc (&label("generic")); -+ &shr ("ebx",16); -+ &and ("ebx",0xff); -+ &cmp ("ebx","esi"); -+ &ja (&label("generic")); -+ &and ("edx",0xefffffff); # clear hyper-threading bit -+ &jmp (&label("generic")); -+ -+&set_label("intel"); -+ &cmp ("edi",7); -+ &jb (&label("cacheinfo")); -+ -+ &mov ("esi",&wparam(0)); -+ &mov ("eax",7); -+ &xor ("ecx","ecx"); -+ &cpuid (); -+ &mov (&DWP(8,"esi"),"ebx"); -+ -+&set_label("cacheinfo"); -+ &cmp ("edi",4); -+ &mov ("edi",-1); -+ &jb (&label("nocacheinfo")); -+ -+ &mov ("eax",4); -+ &mov ("ecx",0); # query L1D -+ &cpuid (); -+ &mov ("edi","eax"); -+ &shr ("edi",14); -+ &and ("edi",0xfff); # number of cores -1 per L1D -+ -+&set_label("nocacheinfo"); -+ &mov ("eax",1); -+ &xor ("ecx","ecx"); -+ &cpuid (); -+ &and ("edx",0xbfefffff); # force reserved bits #20, #30 to 0 -+ &cmp ("ebp",0); -+ &jne (&label("notintel")); -+ &or ("edx",1<<30); # set reserved bit#30 on Intel CPUs -+ &and (&HB("eax"),15); # familiy ID -+ &cmp (&HB("eax"),15); # P4? -+ &jne (&label("notintel")); -+ &or ("edx",1<<20); # set reserved bit#20 to engage RC4_CHAR -+&set_label("notintel"); -+ &bt ("edx",28); # test hyper-threading bit -+ &jnc (&label("generic")); -+ &and ("edx",0xefffffff); -+ &cmp ("edi",0); -+ &je (&label("generic")); -+ -+ &or ("edx",0x10000000); -+ &shr ("ebx",16); -+ &cmp (&LB("ebx"),1); -+ &ja (&label("generic")); -+ &and ("edx",0xefffffff); # clear hyper-threading bit if not -+ -+&set_label("generic"); -+ &and ("ebp",1<<11); # isolate AMD XOP flag -+ &and ("ecx",0xfffff7ff); # force 11th bit to 0 -+ &mov ("esi","edx"); -+ &or ("ebp","ecx"); # merge AMD XOP flag -+ -+ &bt ("ecx",27); # check OSXSAVE bit -+ &jnc (&label("clear_avx")); -+ &xor ("ecx","ecx"); -+ &data_byte(0x0f,0x01,0xd0); # xgetbv -+ &and ("eax",6); -+ &cmp ("eax",6); -+ &je (&label("done")); -+ &cmp ("eax",2); -+ &je (&label("clear_avx")); -+&set_label("clear_xmm"); -+ &and ("ebp",0xfdfffffd); # clear AESNI and PCLMULQDQ bits -+ &and ("esi",0xfeffffff); # clear FXSR -+&set_label("clear_avx"); -+ &and ("ebp",0xefffe7ff); # clear AVX, FMA and AMD XOP bits -+ &mov ("edi",&wparam(0)); -+ &and (&DWP(8,"edi"),0xffffffdf); # clear AVX2 -+&set_label("done"); -+ &mov ("eax","esi"); -+ &mov ("edx","ebp"); -+&set_label("nocpuid"); -+&function_end("OPENSSL_ia32_cpuid"); -+ -+&external_label("OPENSSL_ia32cap_P"); -+ -+&function_begin_B("OPENSSL_rdtsc","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); -+ &xor ("eax","eax"); -+ &xor ("edx","edx"); -+ &picmeup("ecx","OPENSSL_ia32cap_P"); -+ &bt (&DWP(0,"ecx"),4); -+ &jnc (&label("notsc")); -+ &rdtsc (); -+&set_label("notsc"); -+ &ret (); -+&function_end_B("OPENSSL_rdtsc"); -+ -+# This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host], -+# but it's safe to call it on any [supported] 32-bit platform... -+# Just check for [non-]zero return value... -+&function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); -+ &picmeup("ecx","OPENSSL_ia32cap_P"); -+ &bt (&DWP(0,"ecx"),4); -+ &jnc (&label("nohalt")); # no TSC -+ -+ &data_word(0x9058900e); # push %cs; pop %eax -+ &and ("eax",3); -+ &jnz (&label("nohalt")); # not enough privileges -+ -+ &pushf (); -+ &pop ("eax"); -+ &bt ("eax",9); -+ &jnc (&label("nohalt")); # interrupts are disabled -+ -+ &rdtsc (); -+ &push ("edx"); -+ &push ("eax"); -+ &halt (); -+ &rdtsc (); -+ -+ &sub ("eax",&DWP(0,"esp")); -+ &sbb ("edx",&DWP(4,"esp")); -+ &add ("esp",8); -+ &ret (); -+ -+&set_label("nohalt"); -+ &xor ("eax","eax"); -+ &xor ("edx","edx"); -+ &ret (); -+&function_end_B("OPENSSL_instrument_halt"); -+ -+# Essentially there is only one use for this function. Under DJGPP: -+# -+# #include -+# ... -+# i=OPENSSL_far_spin(_dos_ds,0x46c); -+# ... -+# to obtain the number of spins till closest timer interrupt. -+ -+&function_begin_B("OPENSSL_far_spin"); -+ &pushf (); -+ &pop ("eax"); -+ &bt ("eax",9); -+ &jnc (&label("nospin")); # interrupts are disabled -+ -+ &mov ("eax",&DWP(4,"esp")); -+ &mov ("ecx",&DWP(8,"esp")); -+ &data_word (0x90d88e1e); # push %ds, mov %eax,%ds -+ &xor ("eax","eax"); -+ &mov ("edx",&DWP(0,"ecx")); -+ &jmp (&label("spin")); -+ -+ &align (16); -+&set_label("spin"); -+ &inc ("eax"); -+ &cmp ("edx",&DWP(0,"ecx")); -+ &je (&label("spin")); -+ -+ &data_word (0x1f909090); # pop %ds -+ &ret (); -+ -+&set_label("nospin"); -+ &xor ("eax","eax"); -+ &xor ("edx","edx"); -+ &ret (); -+&function_end_B("OPENSSL_far_spin"); -+ -+&function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); -+ &xor ("eax","eax"); -+ &xor ("edx","edx"); -+ &picmeup("ecx","OPENSSL_ia32cap_P"); -+ &mov ("ecx",&DWP(0,"ecx")); -+ &bt (&DWP(0,"ecx"),1); -+ &jnc (&label("no_x87")); -+ if ($sse2) { -+ &and ("ecx",1<<26|1<<24); # check SSE2 and FXSR bits -+ &cmp ("ecx",1<<26|1<<24); -+ &jne (&label("no_sse2")); -+ &pxor ("xmm0","xmm0"); -+ &pxor ("xmm1","xmm1"); -+ &pxor ("xmm2","xmm2"); -+ &pxor ("xmm3","xmm3"); -+ &pxor ("xmm4","xmm4"); -+ &pxor ("xmm5","xmm5"); -+ &pxor ("xmm6","xmm6"); -+ &pxor ("xmm7","xmm7"); -+ &set_label("no_sse2"); -+ } -+ # just a bunch of fldz to zap the fp/mm bank followed by finit... -+ &data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9,0x90e3db9b); -+&set_label("no_x87"); -+ &lea ("eax",&DWP(4,"esp")); -+ &ret (); -+&function_end_B("OPENSSL_wipe_cpu"); -+ -+&function_begin_B("OPENSSL_atomic_add"); -+ &mov ("edx",&DWP(4,"esp")); # fetch the pointer, 1st arg -+ &mov ("ecx",&DWP(8,"esp")); # fetch the increment, 2nd arg -+ &push ("ebx"); -+ &nop (); -+ &mov ("eax",&DWP(0,"edx")); -+&set_label("spin"); -+ &lea ("ebx",&DWP(0,"eax","ecx")); -+ &nop (); -+ &data_word(0x1ab10ff0); # lock; cmpxchg %ebx,(%edx) # %eax is envolved and is always reloaded -+ &jne (&label("spin")); -+ &mov ("eax","ebx"); # OpenSSL expects the new value -+ &pop ("ebx"); -+ &ret (); -+&function_end_B("OPENSSL_atomic_add"); -+ -+# This function can become handy under Win32 in situations when -+# we don't know which calling convention, __stdcall or __cdecl(*), -+# indirect callee is using. In C it can be deployed as -+# -+#ifdef OPENSSL_CPUID_OBJ -+# type OPENSSL_indirect_call(void *f,...); -+# ... -+# OPENSSL_indirect_call(func,[up to $max arguments]); -+#endif -+# -+# (*) it's designed to work even for __fastcall if number of -+# arguments is 1 or 2! -+&function_begin_B("OPENSSL_indirect_call"); -+ { -+ my ($max,$i)=(7,); # $max has to be chosen as 4*n-1 -+ # in order to preserve eventual -+ # stack alignment -+ &push ("ebp"); -+ &mov ("ebp","esp"); -+ &sub ("esp",$max*4); -+ &mov ("ecx",&DWP(12,"ebp")); -+ &mov (&DWP(0,"esp"),"ecx"); -+ &mov ("edx",&DWP(16,"ebp")); -+ &mov (&DWP(4,"esp"),"edx"); -+ for($i=2;$i<$max;$i++) -+ { -+ # Some copies will be redundant/bogus... -+ &mov ("eax",&DWP(12+$i*4,"ebp")); -+ &mov (&DWP(0+$i*4,"esp"),"eax"); -+ } -+ &call_ptr (&DWP(8,"ebp"));# make the call... -+ &mov ("esp","ebp"); # ... and just restore the stack pointer -+ # without paying attention to what we called, -+ # (__cdecl *func) or (__stdcall *one). -+ &pop ("ebp"); -+ &ret (); -+ } -+&function_end_B("OPENSSL_indirect_call"); -+ -+&function_begin_B("OPENSSL_cleanse"); -+ &mov ("edx",&wparam(0)); -+ &mov ("ecx",&wparam(1)); -+ &xor ("eax","eax"); -+ &cmp ("ecx",7); -+ &jae (&label("lot")); -+ &cmp ("ecx",0); -+ &je (&label("ret")); -+&set_label("little"); -+ &mov (&BP(0,"edx"),"al"); -+ &sub ("ecx",1); -+ &lea ("edx",&DWP(1,"edx")); -+ &jnz (&label("little")); -+&set_label("ret"); -+ &ret (); -+ -+&set_label("lot",16); -+ &test ("edx",3); -+ &jz (&label("aligned")); -+ &mov (&BP(0,"edx"),"al"); -+ &lea ("ecx",&DWP(-1,"ecx")); -+ &lea ("edx",&DWP(1,"edx")); -+ &jmp (&label("lot")); -+&set_label("aligned"); -+ &mov (&DWP(0,"edx"),"eax"); -+ &lea ("ecx",&DWP(-4,"ecx")); -+ &test ("ecx",-4); -+ &lea ("edx",&DWP(4,"edx")); -+ &jnz (&label("aligned")); -+ &cmp ("ecx",0); -+ &jne (&label("little")); -+ &ret (); -+&function_end_B("OPENSSL_cleanse"); -+ -+&function_begin_B("CRYPTO_memcmp"); -+ &push ("esi"); -+ &push ("edi"); -+ &mov ("esi",&wparam(0)); -+ &mov ("edi",&wparam(1)); -+ &mov ("ecx",&wparam(2)); -+ &xor ("eax","eax"); -+ &xor ("edx","edx"); -+ &cmp ("ecx",0); -+ &je (&label("no_data")); -+&set_label("loop"); -+ &mov ("dl",&BP(0,"esi")); -+ &lea ("esi",&DWP(1,"esi")); -+ &xor ("dl",&BP(0,"edi")); -+ &lea ("edi",&DWP(1,"edi")); -+ &or ("al","dl"); -+ &dec ("ecx"); -+ &jnz (&label("loop")); -+ &neg ("eax"); -+ &shr ("eax",31); -+&set_label("no_data"); -+ &pop ("edi"); -+ &pop ("esi"); -+ &ret (); -+&function_end_B("CRYPTO_memcmp"); -+{ -+my $lasttick = "esi"; -+my $lastdiff = "ebx"; -+my $out = "edi"; -+my $cnt = "ecx"; -+my $max = "ebp"; -+ -+&function_begin("OPENSSL_instrument_bus"); -+ &mov ("eax",0); -+ if ($sse2) { -+ &picmeup("edx","OPENSSL_ia32cap_P"); -+ &bt (&DWP(0,"edx"),4); -+ &jnc (&label("nogo")); # no TSC -+ &bt (&DWP(0,"edx"),19); -+ &jnc (&label("nogo")); # no CLFLUSH -+ -+ &mov ($out,&wparam(0)); # load arguments -+ &mov ($cnt,&wparam(1)); -+ -+ # collect 1st tick -+ &rdtsc (); -+ &mov ($lasttick,"eax"); # lasttick = tick -+ &mov ($lastdiff,0); # lastdiff = 0 -+ &clflush(&DWP(0,$out)); -+ &data_byte(0xf0); # lock -+ &add (&DWP(0,$out),$lastdiff); -+ &jmp (&label("loop")); -+ -+&set_label("loop",16); -+ &rdtsc (); -+ &mov ("edx","eax"); # put aside tick (yes, I neglect edx) -+ &sub ("eax",$lasttick); # diff -+ &mov ($lasttick,"edx"); # lasttick = tick -+ &mov ($lastdiff,"eax"); # lastdiff = diff -+ &clflush(&DWP(0,$out)); -+ &data_byte(0xf0); # lock -+ &add (&DWP(0,$out),"eax"); # accumulate diff -+ &lea ($out,&DWP(4,$out)); # ++$out -+ &sub ($cnt,1); # --$cnt -+ &jnz (&label("loop")); -+ -+ &mov ("eax",&wparam(1)); -+&set_label("nogo"); -+ } -+&function_end("OPENSSL_instrument_bus"); -+ -+&function_begin("OPENSSL_instrument_bus2"); -+ &mov ("eax",0); -+ if ($sse2) { -+ &picmeup("edx","OPENSSL_ia32cap_P"); -+ &bt (&DWP(0,"edx"),4); -+ &jnc (&label("nogo")); # no TSC -+ &bt (&DWP(0,"edx"),19); -+ &jnc (&label("nogo")); # no CLFLUSH -+ -+ &mov ($out,&wparam(0)); # load arguments -+ &mov ($cnt,&wparam(1)); -+ &mov ($max,&wparam(2)); -+ -+ &rdtsc (); # collect 1st tick -+ &mov ($lasttick,"eax"); # lasttick = tick -+ &mov ($lastdiff,0); # lastdiff = 0 -+ -+ &clflush(&DWP(0,$out)); -+ &data_byte(0xf0); # lock -+ &add (&DWP(0,$out),$lastdiff); -+ -+ &rdtsc (); # collect 1st diff -+ &mov ("edx","eax"); # put aside tick (yes, I neglect edx) -+ &sub ("eax",$lasttick); # diff -+ &mov ($lasttick,"edx"); # lasttick = tick -+ &mov ($lastdiff,"eax"); # lastdiff = diff -+ &jmp (&label("loop2")); -+ -+&set_label("loop2",16); -+ &clflush(&DWP(0,$out)); -+ &data_byte(0xf0); # lock -+ &add (&DWP(0,$out),"eax"); # accumulate diff -+ -+ &sub ($max,1); -+ &jz (&label("done2")); -+ -+ &rdtsc (); -+ &mov ("edx","eax"); # put aside tick (yes, I neglect edx) -+ &sub ("eax",$lasttick); # diff -+ &mov ($lasttick,"edx"); # lasttick = tick -+ &cmp ("eax",$lastdiff); -+ &mov ($lastdiff,"eax"); # lastdiff = diff -+ &mov ("edx",0); -+ &setne ("dl"); -+ &sub ($cnt,"edx"); # conditional --$cnt -+ &lea ($out,&DWP(0,$out,"edx",4)); # conditional ++$out -+ &jnz (&label("loop2")); -+ -+&set_label("done2"); -+ &mov ("eax",&wparam(1)); -+ &sub ("eax",$cnt); -+&set_label("nogo"); -+ } -+&function_end("OPENSSL_instrument_bus2"); -+} -+ -+sub gen_random { -+my $rdop = shift; -+&function_begin_B("OPENSSL_ia32_${rdop}"); -+ &mov ("ecx",8); -+&set_label("loop"); -+ &${rdop}("eax"); -+ &jc (&label("break")); -+ &loop (&label("loop")); -+&set_label("break"); -+ &cmp ("eax",0); -+ &cmove ("eax","ecx"); -+ &ret (); -+&function_end_B("OPENSSL_ia32_${rdop}"); -+ -+&function_begin_B("OPENSSL_ia32_${rdop}_bytes"); -+ &push ("edi"); -+ &push ("ebx"); -+ &xor ("eax","eax"); # return value -+ &mov ("edi",&wparam(0)); -+ &mov ("ebx",&wparam(1)); -+ -+ &cmp ("ebx",0); -+ &je (&label("done")); -+ -+ &mov ("ecx",8); -+&set_label("loop"); -+ &${rdop}("edx"); -+ &jc (&label("break")); -+ &loop (&label("loop")); -+ &jmp (&label("done")); -+ -+&set_label("break",16); -+ &cmp ("ebx",4); -+ &jb (&label("tail")); -+ &mov (&DWP(0,"edi"),"edx"); -+ &lea ("edi",&DWP(4,"edi")); -+ &add ("eax",4); -+ &sub ("ebx",4); -+ &jz (&label("done")); -+ &mov ("ecx",8); -+ &jmp (&label("loop")); -+ -+&set_label("tail",16); -+ &mov (&BP(0,"edi"),"dl"); -+ &lea ("edi",&DWP(1,"edi")); -+ &inc ("eax"); -+ &shr ("edx",8); -+ &dec ("ebx"); -+ &jnz (&label("tail")); -+ -+&set_label("done"); -+ &pop ("ebx"); -+ &pop ("edi"); -+ &ret (); -+&function_end_B("OPENSSL_ia32_${rdop}_bytes"); -+} -+&gen_random("rdrand"); -+&gen_random("rdseed"); -+ -+&initseg("OPENSSL_cpuid_setup"); -+ -+&hidden("OPENSSL_cpuid_setup"); -+&hidden("OPENSSL_ia32cap_P"); -+ -+&asm_finish(); -+ -+close STDOUT; -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/README b/CryptoPkg/Library/OpensslLib/openssl/demos/README -new file mode 100644 -index 0000000..d2155ef ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/README -@@ -0,0 +1,9 @@ -+NOTE: Don't expect any of these programs to work with current -+OpenSSL releases, or even with later SSLeay releases. -+ -+Original README: -+============================================================================= -+ -+Some demo programs sent to me by various people -+ -+eric -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/Makefile b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/Makefile -new file mode 100644 -index 0000000..493e8a5 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/Makefile -@@ -0,0 +1,30 @@ -+# Quick instruction: -+# To build against an OpenSSL built in the source tree, do this: -+# -+# make OPENSSL_INCS_LOCATION=-I../../include OPENSSL_LIBS_LOCATION=-L../.. -+# -+# To run the demos when linked with a shared library (default): -+# -+# LD_LIBRARY_PATH=../.. ./server-arg -+# LD_LIBRARY_PATH=../.. ./server-cmod -+# LD_LIBRARY_PATH=../.. ./server-conf -+# LD_LIBRARY_PATH=../.. ./client-arg -+# LD_LIBRARY_PATH=../.. ./client-conf -+# LD_LIBRARY_PATH=../.. ./saccept -+# LD_LIBRARY_PATH=../.. ./sconnect -+ -+CFLAGS = $(OPENSSL_INCS_LOCATION) -+LDFLAGS = $(OPENSSL_LIBS_LOCATION) -lssl -lcrypto $(EX_LIBS) -+ -+all: client-arg client-conf saccept sconnect server-arg server-cmod server-conf -+ -+client-arg: client-arg.o -+client-conf: client-conf.o -+saccept: saccept.o -+sconnect: sconnect.o -+server-arg: server-arg.o -+server-cmod: server-cmod.o -+server-conf: server-conf.o -+ -+client-arg client-conf saccept sconnect server-arg server-cmod server-conf: -+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/README b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/README -new file mode 100644 -index 0000000..a36bb48 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/README -@@ -0,0 +1,7 @@ -+This directory contains some simple examples of the use of BIO's -+to simplify socket programming. -+ -+The client-conf, server-conf, client-arg and client-conf include examples -+of how to use the SSL_CONF API for configuration file or command line -+processing. -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/accept.cnf b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/accept.cnf -new file mode 100644 -index 0000000..eb69658 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/accept.cnf -@@ -0,0 +1,17 @@ -+# Example configuration file -+# Port to listen on -+Port = 4433 -+# Disable TLS v1.2 for test. -+# Protocol = ALL, -TLSv1.2 -+# Only support 3 curves -+Curves = P-521:P-384:P-256 -+# Restricted signature algorithms -+SignatureAlgorithms = RSA+SHA512:ECDSA+SHA512 -+Certificate=server.pem -+PrivateKey=server.pem -+ChainCAFile=root.pem -+VerifyCAFile=root.pem -+ -+# Request certificate -+VerifyMode=Request -+ClientCAFile=root.pem -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/client-arg.c b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/client-arg.c -new file mode 100644 -index 0000000..e8d5e46 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/client-arg.c -@@ -0,0 +1,117 @@ -+/* -+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *sbio = NULL, *out = NULL; -+ int len; -+ char tmpbuf[1024]; -+ SSL_CTX *ctx; -+ SSL_CONF_CTX *cctx; -+ SSL *ssl; -+ char **args = argv + 1; -+ const char *connect_str = "localhost:4433"; -+ int nargs = argc - 1; -+ -+ ctx = SSL_CTX_new(TLS_client_method()); -+ cctx = SSL_CONF_CTX_new(); -+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); -+ SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); -+ while (*args && **args == '-') { -+ int rv; -+ /* Parse standard arguments */ -+ rv = SSL_CONF_cmd_argv(cctx, &nargs, &args); -+ if (rv == -3) { -+ fprintf(stderr, "Missing argument for %s\n", *args); -+ goto end; -+ } -+ if (rv < 0) { -+ fprintf(stderr, "Error in command %s\n", *args); -+ ERR_print_errors_fp(stderr); -+ goto end; -+ } -+ /* If rv > 0 we processed something so proceed to next arg */ -+ if (rv > 0) -+ continue; -+ /* Otherwise application specific argument processing */ -+ if (strcmp(*args, "-connect") == 0) { -+ connect_str = args[1]; -+ if (connect_str == NULL) { -+ fprintf(stderr, "Missing -connect argument\n"); -+ goto end; -+ } -+ args += 2; -+ nargs -= 2; -+ continue; -+ } else { -+ fprintf(stderr, "Unknown argument %s\n", *args); -+ goto end; -+ } -+ } -+ -+ if (!SSL_CONF_CTX_finish(cctx)) { -+ fprintf(stderr, "Finish error\n"); -+ ERR_print_errors_fp(stderr); -+ goto end; -+ } -+ -+ /* -+ * We'd normally set some stuff like the verify paths and * mode here -+ * because as things stand this will connect to * any server whose -+ * certificate is signed by any CA. -+ */ -+ -+ sbio = BIO_new_ssl_connect(ctx); -+ -+ BIO_get_ssl(sbio, &ssl); -+ -+ if (!ssl) { -+ fprintf(stderr, "Can't locate SSL pointer\n"); -+ goto end; -+ } -+ -+ /* Don't want any retries */ -+ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); -+ -+ /* We might want to do other things with ssl here */ -+ -+ BIO_set_conn_hostname(sbio, connect_str); -+ -+ out = BIO_new_fp(stdout, BIO_NOCLOSE); -+ if (BIO_do_connect(sbio) <= 0) { -+ fprintf(stderr, "Error connecting to server\n"); -+ ERR_print_errors_fp(stderr); -+ goto end; -+ } -+ -+ if (BIO_do_handshake(sbio) <= 0) { -+ fprintf(stderr, "Error establishing SSL connection\n"); -+ ERR_print_errors_fp(stderr); -+ goto end; -+ } -+ -+ /* Could examine ssl here to get connection info */ -+ -+ BIO_puts(sbio, "GET / HTTP/1.0\n\n"); -+ for (;;) { -+ len = BIO_read(sbio, tmpbuf, 1024); -+ if (len <= 0) -+ break; -+ BIO_write(out, tmpbuf, len); -+ } -+ end: -+ SSL_CONF_CTX_free(cctx); -+ BIO_free_all(sbio); -+ BIO_free(out); -+ return 0; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/client-conf.c b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/client-conf.c -new file mode 100644 -index 0000000..e819030 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/client-conf.c -@@ -0,0 +1,126 @@ -+/* -+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *sbio = NULL, *out = NULL; -+ int i, len, rv; -+ char tmpbuf[1024]; -+ SSL_CTX *ctx = NULL; -+ SSL_CONF_CTX *cctx = NULL; -+ SSL *ssl = NULL; -+ CONF *conf = NULL; -+ STACK_OF(CONF_VALUE) *sect = NULL; -+ CONF_VALUE *cnf; -+ const char *connect_str = "localhost:4433"; -+ long errline = -1; -+ -+ conf = NCONF_new(NULL); -+ -+ if (NCONF_load(conf, "connect.cnf", &errline) <= 0) { -+ if (errline <= 0) -+ fprintf(stderr, "Error processing config file\n"); -+ else -+ fprintf(stderr, "Error on line %ld\n", errline); -+ goto end; -+ } -+ -+ sect = NCONF_get_section(conf, "default"); -+ -+ if (sect == NULL) { -+ fprintf(stderr, "Error retrieving default section\n"); -+ goto end; -+ } -+ -+ ctx = SSL_CTX_new(TLS_client_method()); -+ cctx = SSL_CONF_CTX_new(); -+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); -+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); -+ SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); -+ for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { -+ cnf = sk_CONF_VALUE_value(sect, i); -+ rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value); -+ if (rv > 0) -+ continue; -+ if (rv != -2) { -+ fprintf(stderr, "Error processing %s = %s\n", -+ cnf->name, cnf->value); -+ ERR_print_errors_fp(stderr); -+ goto end; -+ } -+ if (strcmp(cnf->name, "Connect") == 0) { -+ connect_str = cnf->value; -+ } else { -+ fprintf(stderr, "Unknown configuration option %s\n", cnf->name); -+ goto end; -+ } -+ } -+ -+ if (!SSL_CONF_CTX_finish(cctx)) { -+ fprintf(stderr, "Finish error\n"); -+ ERR_print_errors_fp(stderr); -+ goto end; -+ } -+ -+ /* -+ * We'd normally set some stuff like the verify paths and * mode here -+ * because as things stand this will connect to * any server whose -+ * certificate is signed by any CA. -+ */ -+ -+ sbio = BIO_new_ssl_connect(ctx); -+ -+ BIO_get_ssl(sbio, &ssl); -+ -+ if (!ssl) { -+ fprintf(stderr, "Can't locate SSL pointer\n"); -+ goto end; -+ } -+ -+ /* Don't want any retries */ -+ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); -+ -+ /* We might want to do other things with ssl here */ -+ -+ BIO_set_conn_hostname(sbio, connect_str); -+ -+ out = BIO_new_fp(stdout, BIO_NOCLOSE); -+ if (BIO_do_connect(sbio) <= 0) { -+ fprintf(stderr, "Error connecting to server\n"); -+ ERR_print_errors_fp(stderr); -+ goto end; -+ } -+ -+ if (BIO_do_handshake(sbio) <= 0) { -+ fprintf(stderr, "Error establishing SSL connection\n"); -+ ERR_print_errors_fp(stderr); -+ goto end; -+ } -+ -+ /* Could examine ssl here to get connection info */ -+ -+ BIO_puts(sbio, "GET / HTTP/1.0\n\n"); -+ for (;;) { -+ len = BIO_read(sbio, tmpbuf, 1024); -+ if (len <= 0) -+ break; -+ BIO_write(out, tmpbuf, len); -+ } -+ end: -+ SSL_CONF_CTX_free(cctx); -+ BIO_free_all(sbio); -+ BIO_free(out); -+ NCONF_free(conf); -+ return 0; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/cmod.cnf b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/cmod.cnf -new file mode 100644 -index 0000000..4c45dfb ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/cmod.cnf -@@ -0,0 +1,24 @@ -+# Example config module configuration -+ -+# Name supplied by application to CONF_modules_load_file -+# and section containing configuration -+testapp = test_sect -+ -+[test_sect] -+# list of confuration modules -+ -+# SSL configuration module -+ssl_conf = ssl_sect -+ -+[ssl_sect] -+# list of SSL configurations -+server = server_sect -+ -+[server_sect] -+# Only support 3 curves -+Curves = P-521:P-384:P-256 -+# Restricted signature algorithms -+SignatureAlgorithms = RSA+SHA512:ECDSA+SHA512 -+# Certificates and keys -+RSA.Certificate=server.pem -+ECDSA.Certificate=server-ec.pem -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/connect.cnf b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/connect.cnf -new file mode 100644 -index 0000000..4dee03c ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/connect.cnf -@@ -0,0 +1,9 @@ -+# Example configuration file -+# Connects to the default port of s_server -+Connect = localhost:4433 -+# Disable TLS v1.2 for test. -+# Protocol = ALL, -TLSv1.2 -+# Only support 3 curves -+Curves = P-521:P-384:P-256 -+# Restricted signature algorithms -+SignatureAlgorithms = RSA+SHA512:ECDSA+SHA512 -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/descrip.mms b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/descrip.mms -new file mode 100644 -index 0000000..8e127b0 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/descrip.mms -@@ -0,0 +1,47 @@ -+# This build description trusts that the following logical names are defined: -+# -+# For compilation: OPENSSL -+# For linking with shared libraries: OSSL$LIBCRYPTO_SHR and OSSL$LIBSSL_SHR -+# For linking with static libraries: OSSL$LIBCRYPTO and OSSL$LIBSSL -+# -+# These are normally defined with the OpenSSL startup procedure -+ -+# By default, we link with the shared libraries -+SHARED = TRUE -+ -+# Alternative, for linking with static libraries -+#SHARED = FALSE -+ -+.FIRST : -+ IF "$(SHARED)" .EQS. "TRUE" THEN DEFINE OPT []shared.opt -+ IF "$(SHARED)" .NES. "TRUE" THEN DEFINE OPT []static.opt -+ -+.LAST : -+ DEASSIGN OPT -+ -+.DEFAULT : -+ @ ! -+ -+# Because we use an option file, we need to redefine this -+.obj.exe : -+ $(LINK) $(LINKFLAGS) $<,OPT:/OPT -+ -+all : client-arg.exe client-conf.exe saccept.exe sconnect.exe - -+ server-arg.exe server-cmod.exe server-conf.exe -+ -+client-arg.exe : client-arg.obj -+client-conf.exe : client-conf.obj -+saccept.exe : saccept.obj -+sconnect.exe : sconnect.obj -+server-arg.exe : server-arg.obj -+server-cmod.exe : server-cmod.obj -+server-conf.exe : server-conf.obj -+ -+# Stoopid MMS doesn't infer this automatically... -+client-arg.obj : client-arg.c -+client-conf.obj : client-conf.c -+saccept.obj : saccept.c -+sconnect.obj : sconnect.c -+server-arg.obj : server-arg.c -+server-cmod.obj : server-cmod.c -+server-conf.obj : server-conf.c -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/intca.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/intca.pem -new file mode 100644 -index 0000000..3551ea9 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/intca.pem -@@ -0,0 +1,23 @@ -+-----BEGIN CERTIFICATE----- -+MIIDvjCCAqagAwIBAgIJAPzCy4CUW9/qMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV -+BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT -+VElORyBQVVJQT1NFUyBPTkxZMR0wGwYDVQQDDBRPcGVuU1NMIFRlc3QgUm9vdCBD -+QTAeFw0xNTA3MTQxMzIyMDVaFw0yNTA2MjExMzIyMDVaMHAxCzAJBgNVBAYTAlVL -+MRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVTVElORyBQ -+VVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJtZWRpYXRl -+IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsErw75CmLYD6pkrG -+W/YhAl/K8L5wJYxDjqu2FghxjD8K308W3EHq4uBxEwR1OHXaM1+6ZZw7/r2I37VL -+IdurBEAIEUdbzx0so74FPawgz5EW2CTqoJnK8F71/vo5Kj1VPwW46CxwxUR3cfvJ -+GNXND2ip0TcyTSPLROXOyQakcVfIGJmdSa1wHKi+c2gMA4emADudZUOYLrg80gr2 -+ldePm07ynbVsKKzCcStw8MdmoW9Qt3fLnPJn2TFUUBNWj+4kvL+88edWCVQXKNds -+ysD/CDrH4W/hjyPDStVsM6XpiNU0+L2ZY6fcj3OP8d0goOx45xotMn9m8hNkCGsr -+VXx9IwIDAQABo2MwYTAdBgNVHQ4EFgQUNsNsiOeV/rC97M4+PYarIYGH2towHwYD -+VR0jBBgwFoAUjBkP10IxdwUG4dOxn+s5+3hxOkUwDwYDVR0TAQH/BAUwAwEB/zAO -+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAANQT0pDWBQoT/RY76xz -+audadGz/dfYnwvSwT0RMFcXLcMVVRNqP0HeR8OP8qLaP7onRbNnEXNfos9pxXYlg -+j+/WjWTBLVcr3pX2Xtmcaqw3CGN9qbQI8B3JkYeijZmc5+3r5MzK/9R0w8Y/T9Xt -+CXEiQhtWHpPrFEfrExeVy2kjJNRctEfq3OTd1bjgX64zvTU7eR+MHFYKPoyMqwIR -+gjoVKinvovEwWoZe5kfMQwJNA3IgoJexX9BXbS8efAYF/ku3tS0laoZS/q6V/o5I -+RvG0OqnNgxhul+96PE5ujSaprsyvBswIUKt+e/BCxGaS6f2AJ8RmtoPOSfT4b9qN -+thI= -+-----END CERTIFICATE----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/root.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/root.pem -new file mode 100644 -index 0000000..3bd0e9b ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/root.pem -@@ -0,0 +1,22 @@ -+-----BEGIN CERTIFICATE----- -+MIIDtjCCAp6gAwIBAgIJAKkg71CjIAovMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV -+BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT -+VElORyBQVVJQT1NFUyBPTkxZMR0wGwYDVQQDDBRPcGVuU1NMIFRlc3QgUm9vdCBD -+QTAeFw0xNDAyMjMxMzA1MTNaFw0yNDAyMjExMzA1MTNaMGgxCzAJBgNVBAYTAlVL -+MRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVTVElORyBQ -+VVJQT1NFUyBPTkxZMR0wGwYDVQQDDBRPcGVuU1NMIFRlc3QgUm9vdCBDQTCCASIw -+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMaarigKGOra5Mc/LrhOkcmHzDs -+vkYL7dfaaht8fLBKRTYwzSBvO9x54koTWjq7HkbaxkYAg3HnDTkNCyzkGKNdM89H -+q/PtGIFFlceQIOat3Kjd05Iw3PtLEWTDjT6FMA9Mkjk/XbpmycqRIwNKtgICoFsG -+juIpc4P31kxK7i3ri+JnlyvVmRZjJxrheJB0qHGXilrOVDPOliDn//jXbcyzXemu -+R8KgAeQM4IIs9jYHJOgHrTItIpwa9wNTEp9KCGkO6xr20NkKyDp6XRyd+hmnUB7r -+77WTptvKPFFTjTDFqEtcif9U2kVkCfn2mSRO8noCbVH++fuR8LMWlD99gt8CAwEA -+AaNjMGEwHQYDVR0OBBYEFIwZD9dCMXcFBuHTsZ/rOft4cTpFMB8GA1UdIwQYMBaA -+FIwZD9dCMXcFBuHTsZ/rOft4cTpFMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -+BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCsoxVi49anYZ1aI/2rVJ5bvEd3ZvGn -+wx1Y+l75SQVYU2qX9CHNBVg1t8reIBN8yPEfBM1WcFPEg7Vy3zFaklMPm/oYXwVI -+/lX/LsfPUxdnQmONxLw4x/0booN1LV/dtRcebewUSqog6W9Z2fbTEe6srIBE4M5G -+Wa943lthlmQM6HzlU4D606PQ3zQbX08mue4eqQB813r4uSoI1MpGLqxkziBRFGGN -+T4VNYp8DeSVr3jHjNBmKCAPZxJIYElnLEK027OG00RH7sF7SGFDNsCjN1NmCvuRz -+9AHnjVIBNzIvI3uiOn9tngRDXBRIcUBsdYG19tal8yWBgrr9SdlqFy/Y -+-----END CERTIFICATE----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/saccept.c b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/saccept.c -new file mode 100644 -index 0000000..66c5c61 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/saccept.c -@@ -0,0 +1,122 @@ -+/* -+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/*- -+ * A minimal program to serve an SSL connection. -+ * It uses blocking. -+ * saccept host:port -+ * host is the interface IP to use. If any interface, use *:port -+ * The default it *:4433 -+ * -+ * cc -I../../include saccept.c -L../.. -lssl -lcrypto -ldl -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#define CERT_FILE "server.pem" -+ -+static int done = 0; -+ -+void interrupt(int sig) -+{ -+ done = 1; -+} -+ -+void sigsetup(void) -+{ -+ struct sigaction sa; -+ -+ /* -+ * Catch at most once, and don't restart the accept system call. -+ */ -+ sa.sa_flags = SA_RESETHAND; -+ sa.sa_handler = interrupt; -+ sigemptyset(&sa.sa_mask); -+ sigaction(SIGINT, &sa, NULL); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ char *port = NULL; -+ BIO *in = NULL; -+ BIO *ssl_bio, *tmp; -+ SSL_CTX *ctx; -+ char buf[512]; -+ int ret = 1, i; -+ -+ if (argc <= 1) -+ port = "*:4433"; -+ else -+ port = argv[1]; -+ -+ ctx = SSL_CTX_new(TLS_server_method()); -+ if (!SSL_CTX_use_certificate_chain_file(ctx, CERT_FILE)) -+ goto err; -+ if (!SSL_CTX_use_PrivateKey_file(ctx, CERT_FILE, SSL_FILETYPE_PEM)) -+ goto err; -+ if (!SSL_CTX_check_private_key(ctx)) -+ goto err; -+ -+ /* Setup server side SSL bio */ -+ ssl_bio = BIO_new_ssl(ctx, 0); -+ -+ if ((in = BIO_new_accept(port)) == NULL) -+ goto err; -+ -+ /* -+ * This means that when a new connection is accepted on 'in', The ssl_bio -+ * will be 'duplicated' and have the new socket BIO push into it. -+ * Basically it means the SSL BIO will be automatically setup -+ */ -+ BIO_set_accept_bios(in, ssl_bio); -+ -+ /* Arrange to leave server loop on interrupt */ -+ sigsetup(); -+ -+ again: -+ /* -+ * The first call will setup the accept socket, and the second will get a -+ * socket. In this loop, the first actual accept will occur in the -+ * BIO_read() function. -+ */ -+ -+ if (BIO_do_accept(in) <= 0) -+ goto err; -+ -+ while (!done) { -+ i = BIO_read(in, buf, 512); -+ if (i == 0) { -+ /* -+ * If we have finished, remove the underlying BIO stack so the -+ * next time we call any function for this BIO, it will attempt -+ * to do an accept -+ */ -+ printf("Done\n"); -+ tmp = BIO_pop(in); -+ BIO_free_all(tmp); -+ goto again; -+ } -+ if (i < 0) -+ goto err; -+ fwrite(buf, 1, i, stdout); -+ fflush(stdout); -+ } -+ -+ ret = 0; -+ err: -+ if (ret) { -+ ERR_print_errors_fp(stderr); -+ } -+ BIO_free(in); -+ exit(ret); -+ return (!ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/sconnect.c b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/sconnect.c -new file mode 100644 -index 0000000..664a1e0 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/sconnect.c -@@ -0,0 +1,131 @@ -+/* -+ * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/*- -+ * A minimal program to do SSL to a passed host and port. -+ * It is actually using non-blocking IO but in a very simple manner -+ * sconnect host:port - it does a 'GET / HTTP/1.0' -+ * -+ * cc -I../../include sconnect.c -L../.. -lssl -lcrypto -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define HOSTPORT "localhost:4433" -+#define CAFILE "root.pem" -+ -+extern int errno; -+ -+int main(argc, argv) -+int argc; -+char *argv[]; -+{ -+ const char *hostport = HOSTPORT; -+ const char *CAfile = CAFILE; -+ char *hostname; -+ char *cp; -+ BIO *out = NULL; -+ char buf[1024 * 10], *p; -+ SSL_CTX *ssl_ctx = NULL; -+ SSL *ssl; -+ BIO *ssl_bio; -+ int i, len, off, ret = 1; -+ -+ if (argc > 1) -+ hostport = argv[1]; -+ if (argc > 2) -+ CAfile = argv[2]; -+ -+ hostname = OPENSSL_strdup(hostport); -+ if ((cp = strchr(hostname, ':')) != NULL) -+ *cp = 0; -+ -+#ifdef WATT32 -+ dbug_init(); -+ sock_init(); -+#endif -+ -+ ssl_ctx = SSL_CTX_new(TLS_client_method()); -+ -+ /* Enable trust chain verification */ -+ SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); -+ SSL_CTX_load_verify_locations(ssl_ctx, CAfile, NULL); -+ -+ /* Lets make a SSL structure */ -+ ssl = SSL_new(ssl_ctx); -+ SSL_set_connect_state(ssl); -+ -+ /* Enable peername verification */ -+ if (SSL_set1_host(ssl, hostname) <= 0) -+ goto err; -+ -+ /* Use it inside an SSL BIO */ -+ ssl_bio = BIO_new(BIO_f_ssl()); -+ BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE); -+ -+ /* Lets use a connect BIO under the SSL BIO */ -+ out = BIO_new(BIO_s_connect()); -+ BIO_set_conn_hostname(out, hostport); -+ BIO_set_nbio(out, 1); -+ out = BIO_push(ssl_bio, out); -+ -+ p = "GET / HTTP/1.0\r\n\r\n"; -+ len = strlen(p); -+ -+ off = 0; -+ for (;;) { -+ i = BIO_write(out, &(p[off]), len); -+ if (i <= 0) { -+ if (BIO_should_retry(out)) { -+ fprintf(stderr, "write DELAY\n"); -+ sleep(1); -+ continue; -+ } else { -+ goto err; -+ } -+ } -+ off += i; -+ len -= i; -+ if (len <= 0) -+ break; -+ } -+ -+ for (;;) { -+ i = BIO_read(out, buf, sizeof(buf)); -+ if (i == 0) -+ break; -+ if (i < 0) { -+ if (BIO_should_retry(out)) { -+ fprintf(stderr, "read DELAY\n"); -+ sleep(1); -+ continue; -+ } -+ goto err; -+ } -+ fwrite(buf, 1, i, stdout); -+ } -+ -+ ret = 1; -+ goto done; -+ -+ err: -+ if (ERR_peek_error() == 0) { /* system call error */ -+ fprintf(stderr, "errno=%d ", errno); -+ perror("error"); -+ } else -+ ERR_print_errors_fp(stderr); -+ done: -+ BIO_free_all(out); -+ SSL_CTX_free(ssl_ctx); -+ return (ret == 1); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-arg.c b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-arg.c -new file mode 100644 -index 0000000..6056969 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-arg.c -@@ -0,0 +1,145 @@ -+/* -+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * A minimal program to serve an SSL connection. It uses blocking. It use the -+ * SSL_CONF API with the command line. cc -I../../include server-arg.c -+ * -L../.. -lssl -lcrypto -ldl -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+int main(int argc, char *argv[]) -+{ -+ char *port = "*:4433"; -+ BIO *ssl_bio, *tmp; -+ SSL_CTX *ctx; -+ SSL_CONF_CTX *cctx; -+ char buf[512]; -+ BIO *in = NULL; -+ int ret = 1, i; -+ char **args = argv + 1; -+ int nargs = argc - 1; -+ -+ ctx = SSL_CTX_new(TLS_server_method()); -+ -+ cctx = SSL_CONF_CTX_new(); -+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); -+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); -+ SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); -+ while (*args && **args == '-') { -+ int rv; -+ /* Parse standard arguments */ -+ rv = SSL_CONF_cmd_argv(cctx, &nargs, &args); -+ if (rv == -3) { -+ fprintf(stderr, "Missing argument for %s\n", *args); -+ goto err; -+ } -+ if (rv < 0) { -+ fprintf(stderr, "Error in command %s\n", *args); -+ ERR_print_errors_fp(stderr); -+ goto err; -+ } -+ /* If rv > 0 we processed something so proceed to next arg */ -+ if (rv > 0) -+ continue; -+ /* Otherwise application specific argument processing */ -+ if (strcmp(*args, "-port") == 0) { -+ port = args[1]; -+ if (port == NULL) { -+ fprintf(stderr, "Missing -port argument\n"); -+ goto err; -+ } -+ args += 2; -+ nargs -= 2; -+ continue; -+ } else { -+ fprintf(stderr, "Unknown argument %s\n", *args); -+ goto err; -+ } -+ } -+ -+ if (!SSL_CONF_CTX_finish(cctx)) { -+ fprintf(stderr, "Finish error\n"); -+ ERR_print_errors_fp(stderr); -+ goto err; -+ } -+#ifdef ITERATE_CERTS -+ /* -+ * Demo of how to iterate over all certificates in an SSL_CTX structure. -+ */ -+ { -+ X509 *x; -+ int rv; -+ rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST); -+ while (rv) { -+ X509 *x = SSL_CTX_get0_certificate(ctx); -+ X509_NAME_print_ex_fp(stdout, X509_get_subject_name(x), 0, -+ XN_FLAG_ONELINE); -+ printf("\n"); -+ rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT); -+ } -+ fflush(stdout); -+ } -+#endif -+ /* Setup server side SSL bio */ -+ ssl_bio = BIO_new_ssl(ctx, 0); -+ -+ if ((in = BIO_new_accept(port)) == NULL) -+ goto err; -+ -+ /* -+ * This means that when a new connection is accepted on 'in', The ssl_bio -+ * will be 'duplicated' and have the new socket BIO push into it. -+ * Basically it means the SSL BIO will be automatically setup -+ */ -+ BIO_set_accept_bios(in, ssl_bio); -+ -+ again: -+ /* -+ * The first call will setup the accept socket, and the second will get a -+ * socket. In this loop, the first actual accept will occur in the -+ * BIO_read() function. -+ */ -+ -+ if (BIO_do_accept(in) <= 0) -+ goto err; -+ -+ for (;;) { -+ i = BIO_read(in, buf, 512); -+ if (i == 0) { -+ /* -+ * If we have finished, remove the underlying BIO stack so the -+ * next time we call any function for this BIO, it will attempt -+ * to do an accept -+ */ -+ printf("Done\n"); -+ tmp = BIO_pop(in); -+ BIO_free_all(tmp); -+ goto again; -+ } -+ if (i < 0) -+ goto err; -+ fwrite(buf, 1, i, stdout); -+ fflush(stdout); -+ } -+ -+ ret = 0; -+ err: -+ if (ret) { -+ ERR_print_errors_fp(stderr); -+ } -+ BIO_free(in); -+ exit(ret); -+ return (!ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-cmod.c b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-cmod.c -new file mode 100644 -index 0000000..9cb2463 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-cmod.c -@@ -0,0 +1,95 @@ -+/* -+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * A minimal TLS server it ses SSL_CTX_config and a configuration file to -+ * set most server parameters. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+int main(int argc, char *argv[]) -+{ -+ unsigned char buf[512]; -+ char *port = "*:4433"; -+ BIO *in = NULL; -+ BIO *ssl_bio, *tmp; -+ SSL_CTX *ctx; -+ int ret = 1, i; -+ -+ ctx = SSL_CTX_new(TLS_server_method()); -+ -+ if (CONF_modules_load_file("cmod.cnf", "testapp", 0) <= 0) { -+ fprintf(stderr, "Error processing config file\n"); -+ goto err; -+ } -+ -+ if (SSL_CTX_config(ctx, "server") == 0) { -+ fprintf(stderr, "Error configuring server.\n"); -+ goto err; -+ } -+ -+ /* Setup server side SSL bio */ -+ ssl_bio = BIO_new_ssl(ctx, 0); -+ -+ if ((in = BIO_new_accept(port)) == NULL) -+ goto err; -+ -+ /* -+ * This means that when a new connection is accepted on 'in', The ssl_bio -+ * will be 'duplicated' and have the new socket BIO push into it. -+ * Basically it means the SSL BIO will be automatically setup -+ */ -+ BIO_set_accept_bios(in, ssl_bio); -+ -+ again: -+ /* -+ * The first call will setup the accept socket, and the second will get a -+ * socket. In this loop, the first actual accept will occur in the -+ * BIO_read() function. -+ */ -+ -+ if (BIO_do_accept(in) <= 0) -+ goto err; -+ -+ for (;;) { -+ i = BIO_read(in, buf, sizeof(buf)); -+ if (i == 0) { -+ /* -+ * If we have finished, remove the underlying BIO stack so the -+ * next time we call any function for this BIO, it will attempt -+ * to do an accept -+ */ -+ printf("Done\n"); -+ tmp = BIO_pop(in); -+ BIO_free_all(tmp); -+ goto again; -+ } -+ if (i < 0) { -+ if (BIO_should_retry(in)) -+ continue; -+ goto err; -+ } -+ fwrite(buf, 1, i, stdout); -+ fflush(stdout); -+ } -+ -+ ret = 0; -+ err: -+ if (ret) { -+ ERR_print_errors_fp(stderr); -+ } -+ BIO_free(in); -+ exit(ret); -+ return (!ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-conf.c b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-conf.c -new file mode 100644 -index 0000000..41b1308 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-conf.c -@@ -0,0 +1,140 @@ -+/* -+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * A minimal program to serve an SSL connection. It uses blocking. It uses -+ * the SSL_CONF API with a configuration file. cc -I../../include saccept.c -+ * -L../.. -lssl -lcrypto -ldl -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+int main(int argc, char *argv[]) -+{ -+ char *port = "*:4433"; -+ BIO *in = NULL; -+ BIO *ssl_bio, *tmp; -+ SSL_CTX *ctx; -+ SSL_CONF_CTX *cctx = NULL; -+ CONF *conf = NULL; -+ STACK_OF(CONF_VALUE) *sect = NULL; -+ CONF_VALUE *cnf; -+ long errline = -1; -+ char buf[512]; -+ int ret = 1, i; -+ -+ ctx = SSL_CTX_new(TLS_server_method()); -+ -+ conf = NCONF_new(NULL); -+ -+ if (NCONF_load(conf, "accept.cnf", &errline) <= 0) { -+ if (errline <= 0) -+ fprintf(stderr, "Error processing config file\n"); -+ else -+ fprintf(stderr, "Error on line %ld\n", errline); -+ goto err; -+ } -+ -+ sect = NCONF_get_section(conf, "default"); -+ -+ if (sect == NULL) { -+ fprintf(stderr, "Error retrieving default section\n"); -+ goto err; -+ } -+ -+ cctx = SSL_CONF_CTX_new(); -+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); -+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); -+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); -+ SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); -+ for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { -+ int rv; -+ cnf = sk_CONF_VALUE_value(sect, i); -+ rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value); -+ if (rv > 0) -+ continue; -+ if (rv != -2) { -+ fprintf(stderr, "Error processing %s = %s\n", -+ cnf->name, cnf->value); -+ ERR_print_errors_fp(stderr); -+ goto err; -+ } -+ if (strcmp(cnf->name, "Port") == 0) { -+ port = cnf->value; -+ } else { -+ fprintf(stderr, "Unknown configuration option %s\n", cnf->name); -+ goto err; -+ } -+ } -+ -+ if (!SSL_CONF_CTX_finish(cctx)) { -+ fprintf(stderr, "Finish error\n"); -+ ERR_print_errors_fp(stderr); -+ goto err; -+ } -+ -+ /* Setup server side SSL bio */ -+ ssl_bio = BIO_new_ssl(ctx, 0); -+ -+ if ((in = BIO_new_accept(port)) == NULL) -+ goto err; -+ -+ /* -+ * This means that when a new connection is accepted on 'in', The ssl_bio -+ * will be 'duplicated' and have the new socket BIO push into it. -+ * Basically it means the SSL BIO will be automatically setup -+ */ -+ BIO_set_accept_bios(in, ssl_bio); -+ -+ again: -+ /* -+ * The first call will setup the accept socket, and the second will get a -+ * socket. In this loop, the first actual accept will occur in the -+ * BIO_read() function. -+ */ -+ -+ if (BIO_do_accept(in) <= 0) -+ goto err; -+ -+ for (;;) { -+ i = BIO_read(in, buf, 512); -+ if (i == 0) { -+ /* -+ * If we have finished, remove the underlying BIO stack so the -+ * next time we call any function for this BIO, it will attempt -+ * to do an accept -+ */ -+ printf("Done\n"); -+ tmp = BIO_pop(in); -+ BIO_free_all(tmp); -+ goto again; -+ } -+ if (i < 0) { -+ if (BIO_should_retry(in)) -+ continue; -+ goto err; -+ } -+ fwrite(buf, 1, i, stdout); -+ fflush(stdout); -+ } -+ -+ ret = 0; -+ err: -+ if (ret) { -+ ERR_print_errors_fp(stderr); -+ } -+ BIO_free(in); -+ exit(ret); -+ return (!ret); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-ec.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-ec.pem -new file mode 100644 -index 0000000..a13fdc7 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server-ec.pem -@@ -0,0 +1,17 @@ -+-----BEGIN PRIVATE KEY----- -+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg/5kYU3PUlHwfdjEN -+lC1xTZEx3o55RgtSOuOCTryDfomhRANCAARW/qUFg+qZzjcFWrST4bmkRCFu8/rn -+KTHjW2vpBXYGXKDn4AbAfYXYhM9J7v1HkkrZBPPGx53eVzs61/Pgr6Rc -+-----END PRIVATE KEY----- -+-----BEGIN CERTIFICATE----- -+MIIBsTCCAVegAwIBAgIJALChLe0vZzgoMAoGCCqGSM49BAMCMDUxHzAdBgNVBAsM -+FlRlc3QgRUNEU0EgQ2VydGlmaWNhdGUxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0x -+NTEyMjIxNDUxMDRaFw00NDAxMDQxNDUxMDRaMDUxHzAdBgNVBAsMFlRlc3QgRUNE -+U0EgQ2VydGlmaWNhdGUxEjAQBgNVBAMMCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG -+CCqGSM49AwEHA0IABFb+pQWD6pnONwVatJPhuaREIW7z+ucpMeNba+kFdgZcoOfg -+BsB9hdiEz0nu/UeSStkE88bHnd5XOzrX8+CvpFyjUDBOMB0GA1UdDgQWBBROhkTJ -+lsm8Qd8pEgrrapccfFY5gjAfBgNVHSMEGDAWgBROhkTJlsm8Qd8pEgrrapccfFY5 -+gjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIFhyU/WZRcihilTpwFVm -+fly1JhwisouiZjLnPkRYZVzHAiEAgqxXfRQl1/phnEgO9gRcv2nFp9xvJiDgKPse -+VktDYjE= -+-----END CERTIFICATE----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server.pem -new file mode 100644 -index 0000000..8a4a51f ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/server.pem -@@ -0,0 +1,77 @@ -+subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = Test Server Cert -+issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA -+-----BEGIN CERTIFICATE----- -+MIIDyTCCArGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVSzEW -+MBQGA1UECgwNT3BlblNTTCBHcm91cDEiMCAGA1UECwwZRk9SIFRFU1RJTkcgUFVS -+UE9TRVMgT05MWTElMCMGA1UEAwwcT3BlblNTTCBUZXN0IEludGVybWVkaWF0ZSBD -+QTAgFw0xNjAxMDQwODU0NDZaGA8yMTE2MDEwNTA4NTQ0NlowZDELMAkGA1UEBhMC -+VUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBURVNUSU5H -+IFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgU2VydmVyIENlcnQwggEiMA0G -+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDzhPOSNtyyRspmeuUpxfNJKCLTuf7g -+3uQ4zu4iHOmRO5TQci+HhVlLZrHF9XqFXcIP0y4pWDbMSGuiorUmzmfiR7bfSdI/ -++qIQt8KXRH6HNG1t8ou0VSvWId5TS5Dq/er5ODUr9OaaDva7EquHIcMvvPQGuI+O -+EAcnleVCy9HVEIySrO4P3CNIicnGkwwiAud05yUAq/gPXBC1hTtmlPD7TVcGVSEi -+Jdvzqqlgv02qedGrkki6GY4S7GjZxrrf7Foc2EP+51LJzwLQx3/JfrCU41NEWAsu -+/Sl0tQabXESN+zJ1pDqoZ3uHMgpQjeGiE0olr+YcsSW/tJmiU9OiAr8RAgMBAAGj -+eDB2MB0GA1UdDgQWBBSCvM8AABPR9zklmifnr9LvIBturDAfBgNVHSMEGDAWgBQ2 -+w2yI55X+sL3szj49hqshgYfa2jAJBgNVHRMEAjAAMBMGA1UdJQQMMAoGCCsGAQUF -+BwMBMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAC78R -+sAr4uvkYOu/pSwQ3MYOFqZ0BnPuP0/AZW2zF7TLNy8g36GyH9rKxz2ffQEHRmPQN -+Z11Ohg3z03jw/sVzkgt2U5Ipv923sSeCZcu0nuNex3v9/x72ldYikZNhQOsw+2kr -+hx3OvE9R7xl9eyjz7BknsbY7PC3kiUY8SDdc5Fr/XMkHm3ge65oWYOHBjC5tAr5K -+FGCEjM3syxS+Li5X6yfDGiVSjOU4gJuZDCYbl7cEQexU2deds8EmpJJrrI7s4JcQ -+rraHI8+Hu8X9VLpZE1jl/fKJw3D0i53PoN2WhukIOg1Zv+ajMKQ4ubVfISH2ebox -++ybAZO8hxL6/I08/GQ== -+-----END CERTIFICATE----- -+subject= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Intermediate CA -+issuer= C = UK, O = OpenSSL Group, OU = FOR TESTING PURPOSES ONLY, CN = OpenSSL Test Root CA -+-----BEGIN CERTIFICATE----- -+MIIDvjCCAqagAwIBAgIJAPzCy4CUW9/qMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV -+BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT -+VElORyBQVVJQT1NFUyBPTkxZMR0wGwYDVQQDDBRPcGVuU1NMIFRlc3QgUm9vdCBD -+QTAeFw0xNTA3MTQxMzIyMDVaFw0yNTA2MjExMzIyMDVaMHAxCzAJBgNVBAYTAlVL -+MRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVTVElORyBQ -+VVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJtZWRpYXRl -+IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsErw75CmLYD6pkrG -+W/YhAl/K8L5wJYxDjqu2FghxjD8K308W3EHq4uBxEwR1OHXaM1+6ZZw7/r2I37VL -+IdurBEAIEUdbzx0so74FPawgz5EW2CTqoJnK8F71/vo5Kj1VPwW46CxwxUR3cfvJ -+GNXND2ip0TcyTSPLROXOyQakcVfIGJmdSa1wHKi+c2gMA4emADudZUOYLrg80gr2 -+ldePm07ynbVsKKzCcStw8MdmoW9Qt3fLnPJn2TFUUBNWj+4kvL+88edWCVQXKNds -+ysD/CDrH4W/hjyPDStVsM6XpiNU0+L2ZY6fcj3OP8d0goOx45xotMn9m8hNkCGsr -+VXx9IwIDAQABo2MwYTAdBgNVHQ4EFgQUNsNsiOeV/rC97M4+PYarIYGH2towHwYD -+VR0jBBgwFoAUjBkP10IxdwUG4dOxn+s5+3hxOkUwDwYDVR0TAQH/BAUwAwEB/zAO -+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAANQT0pDWBQoT/RY76xz -+audadGz/dfYnwvSwT0RMFcXLcMVVRNqP0HeR8OP8qLaP7onRbNnEXNfos9pxXYlg -+j+/WjWTBLVcr3pX2Xtmcaqw3CGN9qbQI8B3JkYeijZmc5+3r5MzK/9R0w8Y/T9Xt -+CXEiQhtWHpPrFEfrExeVy2kjJNRctEfq3OTd1bjgX64zvTU7eR+MHFYKPoyMqwIR -+gjoVKinvovEwWoZe5kfMQwJNA3IgoJexX9BXbS8efAYF/ku3tS0laoZS/q6V/o5I -+RvG0OqnNgxhul+96PE5ujSaprsyvBswIUKt+e/BCxGaS6f2AJ8RmtoPOSfT4b9qN -+thI= -+-----END CERTIFICATE----- -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpAIBAAKCAQEA84TzkjbcskbKZnrlKcXzSSgi07n+4N7kOM7uIhzpkTuU0HIv -+h4VZS2axxfV6hV3CD9MuKVg2zEhroqK1Js5n4ke230nSP/qiELfCl0R+hzRtbfKL -+tFUr1iHeU0uQ6v3q+Tg1K/Tmmg72uxKrhyHDL7z0BriPjhAHJ5XlQsvR1RCMkqzu -+D9wjSInJxpMMIgLndOclAKv4D1wQtYU7ZpTw+01XBlUhIiXb86qpYL9NqnnRq5JI -+uhmOEuxo2ca63+xaHNhD/udSyc8C0Md/yX6wlONTRFgLLv0pdLUGm1xEjfsydaQ6 -+qGd7hzIKUI3hohNKJa/mHLElv7SZolPTogK/EQIDAQABAoIBAADq9FwNtuE5IRQn -+zGtO4q7Y5uCzZ8GDNYr9RKp+P2cbuWDbvVAecYq2NV9QoIiWJOAYZKklOvekIju3 -+r0UZLA0PRiIrTg6NrESx3JrjWDK8QNlUO7CPTZ39/K+FrmMkV9lem9yxjJjyC34D -+AQB+YRTx+l14HppjdxNwHjAVQpIx/uO2F5xAMuk32+3K+pq9CZUtrofe1q4Agj9R -+5s8mSy9pbRo9kW9wl5xdEotz1LivFOEiqPUJTUq5J5PeMKao3vdK726XI4Z455Nm -+W2/MA0YV0ug2FYinHcZdvKM6dimH8GLfa3X8xKRfzjGjTiMSwsdjgMa4awY3tEHH -+674jhAECgYEA/zqMrc0zsbNk83sjgaYIug5kzEpN4ic020rSZsmQxSCerJTgNhmg -+utKSCt0Re09Jt3LqG48msahX8ycqDsHNvlEGPQSbMu9IYeO3Wr3fAm75GEtFWePY -+BhM73I7gkRt4s8bUiUepMG/wY45c5tRF23xi8foReHFFe9MDzh8fJFECgYEA9EFX -+4qAik1pOJGNei9BMwmx0I0gfVEIgu0tzeVqT45vcxbxr7RkTEaDoAG6PlbWP6D9a -+WQNLp4gsgRM90ZXOJ4up5DsAWDluvaF4/omabMA+MJJ5kGZ0gCj5rbZbKqUws7x8 -+bp+6iBfUPJUbcqNqFmi/08Yt7vrDnMnyMw2A/sECgYEAiiuRMxnuzVm34hQcsbhH -+6ymVqf7j0PW2qK0F4H1ocT9qhzWFd+RB3kHWrCjnqODQoI6GbGr/4JepHUpre1ex -+4UEN5oSS3G0ru0rC3U4C59dZ5KwDHFm7ffZ1pr52ljfQDUsrjjIMRtuiwNK2OoRa -+WSsqiaL+SDzSB+nBmpnAizECgYBdt/y6rerWUx4MhDwwtTnel7JwHyo2MDFS6/5g -+n8qC2Lj6/fMDRE22w+CA2esp7EJNQJGv+b27iFpbJEDh+/Lf5YzIT4MwVskQ5bYB -+JFcmRxUVmf4e09D7o705U/DjCgMH09iCsbLmqQ38ONIRSHZaJtMDtNTHD1yi+jF+ -+OT43gQKBgQC/2OHZoko6iRlNOAQ/tMVFNq7fL81GivoQ9F1U0Qr+DH3ZfaH8eIkX -+xT0ToMPJUzWAn8pZv0snA0um6SIgvkCuxO84OkANCVbttzXImIsL7pFzfcwV/ERK -+UM6j0ZuSMFOCr/lGPAoOQU0fskidGEHi1/kW+suSr28TqsyYZpwBDQ== -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/shared.opt b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/shared.opt -new file mode 100644 -index 0000000..4141b93 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/shared.opt -@@ -0,0 +1,2 @@ -+OSSL$LIBSSL_SHR/SHARE -+OSSL$LIBCRYPTO_SHR/SHARE -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/bio/static.opt b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/static.opt -new file mode 100644 -index 0000000..9ca1588 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/bio/static.opt -@@ -0,0 +1,2 @@ -+OSSL$LIBSSL/LIB -+OSSL$LIBCRYPTO/LIB -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/README b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/README -new file mode 100644 -index 0000000..126663a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/README -@@ -0,0 +1,21 @@ -+There is often a need to generate test certificates automatically using -+a script. This is often a cause for confusion which can result in incorrect -+CA certificates, obsolete V1 certificates or duplicate serial numbers. -+The range of command line options can be daunting for a beginner. -+ -+The mkcerts.sh script is an example of how to generate certificates -+automatically using scripts. Example creates a root CA, an intermediate CA -+signed by the root and several certificates signed by the intermediate CA. -+ -+The script then creates an empty index.txt file and adds entries for the -+certificates and generates a CRL. Then one certificate is revoked and a -+second CRL generated. -+ -+The script ocsprun.sh runs the test responder on port 8888 covering the -+client certificates. -+ -+The script ocspquery.sh queries the status of the certificates using the -+test responder. -+ -+ -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/apps.cnf b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/apps.cnf -new file mode 100644 -index 0000000..531afe6 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/apps.cnf -@@ -0,0 +1,69 @@ -+# -+# OpenSSL configuration file to create apps directory certificates -+# -+ -+# This definition stops the following lines choking if HOME or CN -+# is undefined. -+HOME = . -+RANDFILE = $ENV::HOME/.rnd -+CN = "Not Defined" -+ -+#################################################################### -+[ req ] -+default_bits = 2048 -+default_keyfile = privkey.pem -+# Don't prompt for fields: use those in section directly -+prompt = no -+distinguished_name = req_distinguished_name -+x509_extensions = v3_ca # The extensions to add to the self signed cert -+string_mask = utf8only -+ -+# req_extensions = v3_req # The extensions to add to a certificate request -+ -+[ req_distinguished_name ] -+countryName = UK -+ -+organizationName = OpenSSL Group -+organizationalUnitName = FOR TESTING PURPOSES ONLY -+# Take CN from environment so it can come from a script. -+commonName = $ENV::CN -+ -+[ usr_cert ] -+ -+# These extensions are added when 'ca' signs a request for an end entity -+# certificate -+ -+basicConstraints=critical, CA:FALSE -+keyUsage=critical, nonRepudiation, digitalSignature, keyEncipherment -+ -+# This will be displayed in Netscape's comment listbox. -+nsComment = "OpenSSL Generated Certificate" -+ -+[ ec_cert ] -+ -+# These extensions are added when 'ca' signs a request for an end entity -+# certificate -+ -+basicConstraints=critical, CA:FALSE -+keyUsage=critical, nonRepudiation, digitalSignature, keyAgreement -+ -+# This will be displayed in Netscape's comment listbox. -+nsComment = "OpenSSL Generated Certificate" -+ -+# PKIX recommendations harmless if included in all certificates. -+subjectKeyIdentifier=hash -+authorityKeyIdentifier=keyid -+ -+[ v3_ca ] -+ -+ -+# Extensions for a typical CA -+ -+# PKIX recommendation. -+ -+subjectKeyIdentifier=hash -+authorityKeyIdentifier=keyid:always -+basicConstraints = critical,CA:true -+keyUsage = critical, cRLSign, keyCertSign -+ -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/ckey.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/ckey.pem -new file mode 100644 -index 0000000..8e9054d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/ckey.pem -@@ -0,0 +1,27 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpQIBAAKCAQEAtK2p2x0S3C1ajftAc3GaWPsji6scw1k9Sw/XltbLQuDc11/f -+wwrUiFcje2CB3Ri6yD6+uCA3V12jEc4GdqzirJZhwgIhaTv42vfYBgiUcR9McEGr -+agFC3yVR3lIbOzhBjmXNp1on46irxnzU4pT+w58IuvYqUBavaEtfRZocFR5NsIOy -+mRhyNag8htOFK3wmTEYrb0vflFYT6SD47ogYtsd/xWSKS+YFyb7xSusR2Ot6Ktmr -+MswQE57QYJz+KiRVlnL0cduMBdT52Wm8blaC9mz50PyrzjQ68NyHapCoWDU7pe4x -+HLtzpXGSDMPuw4miiSwMym/2wReYJv6cFugLPQIDAQABAoIBAAZOyc9MhIwLSU4L -+p4RgQvM4UVVe8/Id+3XTZ8NsXExJbWxXfIhiqGjaIfL8u4vsgRjcl+v1s/jo2/iT -+KMab4o4D8gXD7UavQVDjtjb/ta79WL3SjRl2Uc9YjjMkyq6WmDNQeo2NKDdafCTB -+1uzSJtLNipB8Z53ELPuHJhxX9QMHrMnuha49riQgXZ7buP9iQrHJFhImBjSzbxJx -+L+TI6rkyLSf9Wi0Pd3L27Ob3QWNfNRYNSeTE+08eSRChkur5W0RuXAcuAICdQlCl -+LBvWO/LmmvbzCqiDcgy/TliSb6CGGwgiNG7LJZmlkYNj8laGwalNlYZs3UrVv6NO -+Br2loAECgYEA2kvCvPGj0Dg/6g7WhXDvAkEbcaL1tSeCxBbNH+6HS2UWMWvyTtCn -+/bbD519QIdkvayy1QjEf32GV/UjUVmlULMLBcDy0DGjtL3+XpIhLKWDNxN1v1/ai -+1oz23ZJCOgnk6K4qtFtlRS1XtynjA+rBetvYvLP9SKeFrnpzCgaA2r0CgYEA0+KX -+1ACXDTNH5ySX3kMjSS9xdINf+OOw4CvPHFwbtc9aqk2HePlEsBTz5I/W3rKwXva3 -+NqZ/bRqVVeZB/hHKFywgdUQk2Uc5z/S7Lw70/w1HubNTXGU06Ngb6zOFAo/o/TwZ -+zTP1BMIKSOB6PAZPS3l+aLO4FRIRotfFhgRHOoECgYEAmiZbqt8cJaJDB/5YYDzC -+mp3tSk6gIb936Q6M5VqkMYp9pIKsxhk0N8aDCnTU+kIK6SzWBpr3/d9Ecmqmfyq7 -+5SvWO3KyVf0WWK9KH0abhOm2BKm2HBQvI0DB5u8sUx2/hsvOnjPYDISbZ11t0MtK -+u35Zy89yMYcSsIYJjG/ROCUCgYEAgI2P9G5PNxEP5OtMwOsW84Y3Xat/hPAQFlI+ -+HES+AzbFGWJkeT8zL2nm95tVkFP1sggZ7Kxjz3w7cpx7GX0NkbWSE9O+T51pNASV -+tN1sQ3p5M+/a+cnlqgfEGJVvc7iAcXQPa3LEi5h2yPR49QYXAgG6cifn3dDSpmwn -+SUI7PQECgYEApGCIIpSRPLAEHTGmP87RBL1smurhwmy2s/pghkvUkWehtxg0sGHh -+kuaqDWcskogv+QC0sVdytiLSz8G0DwcEcsHK1Fkyb8A+ayiw6jWJDo2m9+IF4Fww -+1Te6jFPYDESnbhq7+TLGgHGhtwcu5cnb4vSuYXGXKupZGzoLOBbv1Zw= -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/intkey.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/intkey.pem -new file mode 100644 -index 0000000..d586cb7 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/intkey.pem -@@ -0,0 +1,27 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEowIBAAKCAQEAsErw75CmLYD6pkrGW/YhAl/K8L5wJYxDjqu2FghxjD8K308W -+3EHq4uBxEwR1OHXaM1+6ZZw7/r2I37VLIdurBEAIEUdbzx0so74FPawgz5EW2CTq -+oJnK8F71/vo5Kj1VPwW46CxwxUR3cfvJGNXND2ip0TcyTSPLROXOyQakcVfIGJmd -+Sa1wHKi+c2gMA4emADudZUOYLrg80gr2ldePm07ynbVsKKzCcStw8MdmoW9Qt3fL -+nPJn2TFUUBNWj+4kvL+88edWCVQXKNdsysD/CDrH4W/hjyPDStVsM6XpiNU0+L2Z -+Y6fcj3OP8d0goOx45xotMn9m8hNkCGsrVXx9IwIDAQABAoIBACg3wIV2o2KIJSZg -+sqXyHY+0GNEZMO5v9E2NAMo//N941lshaN6wrww5FbK39qH9yNylfxmFLe6sgJhA -+fLZprbcXgH+onto+Fpv4UqvCI+4WdHa03U3sJ+70SvxzSy1Gtrbc8FUPJl7qgrFf -+Nn5S8CgOwYb4J6KPguTh5G3Z9RPiCKObwOwEM34hrZUlgPS88wmzu9H6L2GM8A1v -+YBtEr0msBnlJBJOgStyUEfHW2KspNQ+VllQ6c0cedgFXUpl9EoKTLxP+WXwFI1sx -+jFCFzSrMqPcPz1PxU6bXoZE0WH6r+3c8WAW4xR/HVu04BrBDu0CGwn6zAXDy6wCU -+pWogDlkCgYEA4o+nIu2CTzqUlgc22pj+hjenfS5lnCtJfAdrXOJHmnuL+J9h8Nzz -+9kkL+/Y0Xg9bOM6xXPm+81UNpDvOLbUahSSQsfB+LNVEkthJIL4XIk083LsHjFaJ -+9SiCFRbf2OgWrEhe/c1drySwz9u/0f4Q7B6VGqxMnTDjzS5JacZ1pE8CgYEAxzMn -+/n/Dpdn+c4rf14BRNKCv1qBXngPNylKJCmiRpKRJAn+B+Msdwtggk/1Ihju21wSo -+IGy0Gw7WQd1Iq7V85cB2G5PAFY6ybpSV6G3QrzmzuvjHmKvXgUAuuaN+7Pp1YkMY -+rLVjUOcdP5JbXG6XnaCkHYJR8uapPwWPkDt+oO0CgYBI4yZGGlr92j7LNW70TJw1 -+2dnMcAzIfTSa7lgf/bxDetPBHKWJs8vYxA9S9BZM3Gvgjr6IxuAjsI0+9O6TzdvG -+UckrNc+h5Mq241ZDbmRK6MZXzOPUxlKDyJBw8Hb7dU82BeJpjJRDMG6hsHS5vh77 -+l6sodZ4ARCZFcEq1+N8ICQKBgDeBHJLAXO6YmFrvhkGQ4o+senJuSRuhabUHXGIH -+ExXyJNnKV5fQWOGSwTkbKRsmBmNRS9uFDoY/kxnVI8ucjUmjYAV9HNek5DkFs+OI -+vc4lYNwnN85li23bSWm2kcZMX2ra0URGYn8HdtHg4Q4XTq3ANhp21oi9FsmVrhP9 -+T+JdAoGBAK2ebwZ7CXFavDFo4mzLKkGitBjrSi/udFhZECXZWEbNzWlVc3Y3q0cU -+drDqUtbVm+/Xb5CMU044Gqq6SKdObAb3JElKmFylFL9fp2rfL/foUr2sdb87Vqdp -+2j5jZyvt1DKnNaJ7JaFbUdRxlvHQRiqKlZpafN/SMQ0jCs1bSgCg -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/mkacerts.sh b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/mkacerts.sh -new file mode 100644 -index 0000000..7098496 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/mkacerts.sh -@@ -0,0 +1,45 @@ -+#!/bin/sh -+ -+# Recreate the demo certificates in the apps directory. -+ -+OPENSSL=openssl -+ -+# Root CA: create certificate directly -+CN="OpenSSL Test Root CA" $OPENSSL req -config apps.cnf -x509 -nodes \ -+ -keyout root.pem -out root.pem -key rootkey.pem -new -days 3650 -+# Intermediate CA: request first -+CN="OpenSSL Test Intermediate CA" $OPENSSL req -config apps.cnf -nodes \ -+ -key intkey.pem -out intreq.pem -new -+# Sign request: CA extensions -+$OPENSSL x509 -req -in intreq.pem -CA root.pem -CAkey rootkey.pem -days 3630 \ -+ -extfile apps.cnf -extensions v3_ca -CAcreateserial -out intca.pem -+# Client certificate: request first -+CN="Test Client Cert" $OPENSSL req -config apps.cnf -nodes \ -+ -key ckey.pem -out creq.pem -new -+# Sign using intermediate CA -+$OPENSSL x509 -req -in creq.pem -CA intca.pem -CAkey intkey.pem -days 3600 \ -+ -extfile apps.cnf -extensions usr_cert -CAcreateserial | \ -+ $OPENSSL x509 -nameopt oneline -subject -issuer >client.pem -+# Server certificate: request first -+CN="Test Server Cert" $OPENSSL req -config apps.cnf -nodes \ -+ -key skey.pem -out sreq.pem -new -+# Sign using intermediate CA -+$OPENSSL x509 -req -in sreq.pem -CA intca.pem -CAkey intkey.pem -days 3600 \ -+ -extfile apps.cnf -extensions usr_cert -CAcreateserial | \ -+ $OPENSSL x509 -nameopt oneline -subject -issuer >server.pem -+# Server certificate #2: request first -+CN="Test Server Cert #2" $OPENSSL req -config apps.cnf -nodes \ -+ -key skey2.pem -out sreq2.pem -new -+# Sign using intermediate CA -+$OPENSSL x509 -req -in sreq2.pem -CA intca.pem -CAkey intkey.pem -days 3600 \ -+ -extfile apps.cnf -extensions usr_cert -CAcreateserial | \ -+ $OPENSSL x509 -nameopt oneline -subject -issuer >server2.pem -+ -+# Append keys to file. -+ -+cat skey.pem >>server.pem -+cat skey2.pem >>server2.pem -+cat ckey.pem >>client.pem -+ -+$OPENSSL verify -CAfile root.pem -untrusted intca.pem \ -+ server2.pem server.pem client.pem -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/mkxcerts.sh b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/mkxcerts.sh -new file mode 100644 -index 0000000..0f88a48 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/mkxcerts.sh -@@ -0,0 +1,29 @@ -+ -+# Create certificates using various algorithms to test multi-certificate -+# functionality. -+ -+OPENSSL=../../../apps/openssl -+CN="OpenSSL Test RSA SHA-1 cert" $OPENSSL req \ -+ -config apps.cnf -extensions usr_cert -x509 -nodes \ -+ -keyout tsha1.pem -out tsha1.pem -new -days 3650 -sha1 -+CN="OpenSSL Test RSA SHA-256 cert" $OPENSSL req \ -+ -config apps.cnf -extensions usr_cert -x509 -nodes \ -+ -keyout tsha256.pem -out tsha256.pem -new -days 3650 -sha256 -+CN="OpenSSL Test RSA SHA-512 cert" $OPENSSL req \ -+ -config apps.cnf -extensions usr_cert -x509 -nodes \ -+ -keyout tsha512.pem -out tsha512.pem -new -days 3650 -sha512 -+ -+# Create EC parameters -+ -+$OPENSSL ecparam -name P-256 -out ecp256.pem -+$OPENSSL ecparam -name P-384 -out ecp384.pem -+ -+CN="OpenSSL Test P-256 SHA-256 cert" $OPENSSL req \ -+ -config apps.cnf -extensions ec_cert -x509 -nodes \ -+ -nodes -keyout tecp256.pem -out tecp256.pem -newkey ec:ecp256.pem \ -+ -days 3650 -sha256 -+ -+CN="OpenSSL Test P-384 SHA-384 cert" $OPENSSL req \ -+ -config apps.cnf -extensions ec_cert -x509 -nodes \ -+ -nodes -keyout tecp384.pem -out tecp384.pem -newkey ec:ecp384.pem \ -+ -days 3650 -sha384 -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/rootkey.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/rootkey.pem -new file mode 100644 -index 0000000..2600aab ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/rootkey.pem -@@ -0,0 +1,27 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpgIBAAKCAQEA0xpquKAoY6trkxz8uuE6RyYfMOy+Rgvt19pqG3x8sEpFNjDN -+IG873HniShNaOrseRtrGRgCDcecNOQ0LLOQYo10zz0er8+0YgUWVx5Ag5q3cqN3T -+kjDc+0sRZMONPoUwD0ySOT9dumbJypEjA0q2AgKgWwaO4ilzg/fWTEruLeuL4meX -+K9WZFmMnGuF4kHSocZeKWs5UM86WIOf/+NdtzLNd6a5HwqAB5Azggiz2Ngck6Aet -+Mi0inBr3A1MSn0oIaQ7rGvbQ2QrIOnpdHJ36GadQHuvvtZOm28o8UVONMMWoS1yJ -+/1TaRWQJ+faZJE7yegJtUf75+5HwsxaUP32C3wIDAQABAoIBAQCEybEnwVamm0Vn -+nGw9AT+vUYN9Ou3VEdviUzk7YOrt2Un/9GKTbGSzItf80H+JQfqhhywBDIGiPDxN -+Dq9g5Xm6CP51/BdlsFYhuqukhDyt3d9XOXHEG4hlaarfP0KxeQXqGbhA2mMSxWVZ -+TkI/59blHNHRcCagjIJlGJhsFRYNO1/ApfA5zN7fWCFvH1XWZhuvsPDgUXKm4BS0 -+p3ol67MVJHRfYcLb/txBO5rBhSXinK0jEBiljRcE0rWzRycSedmDgG3SNV17wvA0 -+UWgMNpPcJ1b7Satr0nM7A8+siV8FRcfvPqCuGPKCYTrNn71hGJEhKXKwlURj9+95 -+O5yzRxjBAoGBAPtTRYN40/piRB0XLpi+zNh+4Ba4TGfXSymbaozgC/pI5wfgGXrz -+IpT9ujjV42r8TABHvXa6uiGm0cbxcUgq2n6Y8rf6iHxmn23ezCEBUs7rd6jtt11b -+m58T8o0XWyOgAovaH0UgzMtrlsZYR2fli5254oRkTWwaUTuO38z6CVddAoGBANcH -+nvdu3RniIYStsr5/deu7l81ZQ9rSiR1m3H6Wy8ryMIfkYfa0WqXhwNHrLrhvhLIQ -+7mGnJ+jAkJyVQULE6UdbmVW8tC58Dfrgz/1s7RMeUYPnOmRpx79c/LqZ2IunfFWx -+IvBvFu7vidEHA+1tU2N+oXNsU+B9XpfsJ+/d2QtrAoGBAJTuP58tFtClMp/agO5b -+AqC4bqqIBB704cGCK53XlsF2OhHcprzJH5ES2iub8+wOHit8V7Xn6SzP4jf2E58k -+Zd3nXM3RVNgDKC6/fE+CrUOZHYupcqOMCag29eDOGl/+DgQ5+ZXJXhKdaveWkJns -+2NNat/SkS4zn+4NDozOgZ7CxAoGBAIuXjfJRTUXNUDci0APtGO9U1AJiLbOzs4Gb -+0g539IqmWS0O7S3L/YDsolFkXOsssjcq2KYabsUhpX+RQVGIJWzGoS9QlqQKssSo -+Bz4c5Xbg2shHZtfi9+JaClNVJofazdOPcAAoDfpFFPHWnQ0YSOcxQLx+maEFok/7 -+5h1IputLAoGBAKGBWDPwskgRRfCAIFpCJLOu/9D30M/akMtO0kJYQpBjOaKuigUy -+ic7pthFVse/pMUljXHAd1hs2CTjMW1ukEusU3x1Ei6wvnHHqn0Hs+6D5NQFQkcMn -+7rejJ+bpJPRAn40AAV5hGBYI12XycB8ZgyPC4hTUK6unGVK06DC4qvdv -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/skey.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/skey.pem -new file mode 100644 -index 0000000..dbd403d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/skey.pem -@@ -0,0 +1,27 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpAIBAAKCAQEA84TzkjbcskbKZnrlKcXzSSgi07n+4N7kOM7uIhzpkTuU0HIv -+h4VZS2axxfV6hV3CD9MuKVg2zEhroqK1Js5n4ke230nSP/qiELfCl0R+hzRtbfKL -+tFUr1iHeU0uQ6v3q+Tg1K/Tmmg72uxKrhyHDL7z0BriPjhAHJ5XlQsvR1RCMkqzu -+D9wjSInJxpMMIgLndOclAKv4D1wQtYU7ZpTw+01XBlUhIiXb86qpYL9NqnnRq5JI -+uhmOEuxo2ca63+xaHNhD/udSyc8C0Md/yX6wlONTRFgLLv0pdLUGm1xEjfsydaQ6 -+qGd7hzIKUI3hohNKJa/mHLElv7SZolPTogK/EQIDAQABAoIBAADq9FwNtuE5IRQn -+zGtO4q7Y5uCzZ8GDNYr9RKp+P2cbuWDbvVAecYq2NV9QoIiWJOAYZKklOvekIju3 -+r0UZLA0PRiIrTg6NrESx3JrjWDK8QNlUO7CPTZ39/K+FrmMkV9lem9yxjJjyC34D -+AQB+YRTx+l14HppjdxNwHjAVQpIx/uO2F5xAMuk32+3K+pq9CZUtrofe1q4Agj9R -+5s8mSy9pbRo9kW9wl5xdEotz1LivFOEiqPUJTUq5J5PeMKao3vdK726XI4Z455Nm -+W2/MA0YV0ug2FYinHcZdvKM6dimH8GLfa3X8xKRfzjGjTiMSwsdjgMa4awY3tEHH -+674jhAECgYEA/zqMrc0zsbNk83sjgaYIug5kzEpN4ic020rSZsmQxSCerJTgNhmg -+utKSCt0Re09Jt3LqG48msahX8ycqDsHNvlEGPQSbMu9IYeO3Wr3fAm75GEtFWePY -+BhM73I7gkRt4s8bUiUepMG/wY45c5tRF23xi8foReHFFe9MDzh8fJFECgYEA9EFX -+4qAik1pOJGNei9BMwmx0I0gfVEIgu0tzeVqT45vcxbxr7RkTEaDoAG6PlbWP6D9a -+WQNLp4gsgRM90ZXOJ4up5DsAWDluvaF4/omabMA+MJJ5kGZ0gCj5rbZbKqUws7x8 -+bp+6iBfUPJUbcqNqFmi/08Yt7vrDnMnyMw2A/sECgYEAiiuRMxnuzVm34hQcsbhH -+6ymVqf7j0PW2qK0F4H1ocT9qhzWFd+RB3kHWrCjnqODQoI6GbGr/4JepHUpre1ex -+4UEN5oSS3G0ru0rC3U4C59dZ5KwDHFm7ffZ1pr52ljfQDUsrjjIMRtuiwNK2OoRa -+WSsqiaL+SDzSB+nBmpnAizECgYBdt/y6rerWUx4MhDwwtTnel7JwHyo2MDFS6/5g -+n8qC2Lj6/fMDRE22w+CA2esp7EJNQJGv+b27iFpbJEDh+/Lf5YzIT4MwVskQ5bYB -+JFcmRxUVmf4e09D7o705U/DjCgMH09iCsbLmqQ38ONIRSHZaJtMDtNTHD1yi+jF+ -+OT43gQKBgQC/2OHZoko6iRlNOAQ/tMVFNq7fL81GivoQ9F1U0Qr+DH3ZfaH8eIkX -+xT0ToMPJUzWAn8pZv0snA0um6SIgvkCuxO84OkANCVbttzXImIsL7pFzfcwV/ERK -+UM6j0ZuSMFOCr/lGPAoOQU0fskidGEHi1/kW+suSr28TqsyYZpwBDQ== -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/skey2.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/skey2.pem -new file mode 100644 -index 0000000..7853822 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/apps/skey2.pem -@@ -0,0 +1,27 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEowIBAAKCAQEA63Yu4/cnLRvi+BIwcoIz5hKmcziREG2tujKEBs4JVO3uV3+f -+UW/4YFULigKImXu/0fKyuMyeFu4l3V8NC6gachvAeWhiniN9sPgPU3AQKaF1y9gq -+2EBEI2cFCKS5WASItjZCY951ZKuXYJdYDgC4kPlvI4N5M4ORHPa4pqfa/dzfMLEi -+92sLGn7q5mArzn+5Xh2jD9Vif8w0RlDRxv1rQ413PGVBtfuhF1PSXNhbPtjpn+33 -+DdJdNACv8D4PDmjUtKyshqvSXSE/RURldW13v68efBWhOQiLXcAkmISbxfzveS1k -+KMSV8nuWwhS5rw0xMlavRTEgqbX7Jm14xGRrFwIDAQABAoIBAHLsTPihIfLnYIE5 -+x4GsQQ5zXeBw5ITDM37ktwHnQDC+rIzyUl1aLD1AZRBoKinXd4lOTqLZ4/NHKx4A -+DYr58mZtWyUmqLOMmQVuHXTZBlp7XtYuXMMNovQwjQlp9LicBeoBU6gQ5PVMtubD -+F4xGF89Sn0cTHW3iMkqTtQ5KcR1j57OcJO0FEb1vPvk2MXI5ZyAatUYE7YacbEzd -+rg02uIwx3FqNSkuSI79uz4hMdV5TPtuhxx9nTwj9aLUhXFeZ0mn2PVgVzEnnMoJb -++znlsZDgzDlJqdaD744YGWh8Z3OEssB35KfzFcdOeO6yH8lmv2Zfznk7pNPT7LTb -+Lae9VgkCgYEA92p1qnAB3NtJtNcaW53i0S5WJgS1hxWKvUDx3lTB9s8X9fHpqL1a -+E94fDfWzp/hax6FefUKIvBOukPLQ6bYjTMiFoOHzVirghAIuIUoMI5VtLhwD1hKs -+Lr7l/dptMgKb1nZHyXoKHRBthsy3K4+udsPi8TzMvYElgEqyQIe/Rk0CgYEA86GL -+8HC6zLszzKERDPBxrboRmoFvVUCTQDhsfj1M8aR3nQ8V5LkdIJc7Wqm/Ggfk9QRf -+rJ8M2WUMlU5CNnCn/KCrKzCNZIReze3fV+HnKdbcXGLvgbHPrhnz8yYehUFG+RGq -+bVyDWRU94T38izy2s5qMYrMJWZEYyXncSPbfcPMCgYAtaXfxcZ+V5xYPQFARMtiX -+5nZfggvDoJuXgx0h3tK/N2HBfcaSdzbaYLG4gTmZggc/jwnl2dl5E++9oSPhUdIG -+3ONSFUbxsOsGr9PBvnKd8WZZyUCXAVRjPBzAzF+whzQNWCZy/5htnz9LN7YDI9s0 -+5113Q96cheDZPFydZY0hHQKBgQDVbEhNukM5xCiNcu+f2SaMnLp9EjQ4h5g3IvaP -+5B16daw/Dw8LzcohWboqIxeAsze0GD/D1ZUJAEd0qBjC3g+a9BjefervCjKOzXng -+38mEUm+6EwVjJSQcjSmycEs+Sr/kwr/8i5WYvU32+jk4tFgMoC+o6tQe/Uesf68k -+z/dPVwKBgGbF7Vv1/3SmhlOy+zYyvJ0CrWtKxH9QP6tLIEgEpd8x7YTSuCH94yok -+kToMXYA3sWNPt22GbRDZ+rcp4c7HkDx6I6vpdP9aQEwJTp0EPy0sgWr2XwYmreIQ -+NFmkk8Itn9EY2R9VBaP7GLv5kvwxDdLAnmwGmzVtbmaVdxCaBwUk -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/ca.cnf b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/ca.cnf -new file mode 100644 -index 0000000..5a8a5f2 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/ca.cnf -@@ -0,0 +1,86 @@ -+# -+# OpenSSL example configuration file for automated certificate creation. -+# -+ -+# This definition stops the following lines choking if HOME or CN -+# is undefined. -+HOME = . -+RANDFILE = $ENV::HOME/.rnd -+CN = "Not Defined" -+default_ca = ca -+ -+#################################################################### -+[ req ] -+default_bits = 1024 -+default_keyfile = privkey.pem -+# Don't prompt for fields: use those in section directly -+prompt = no -+distinguished_name = req_distinguished_name -+x509_extensions = v3_ca # The extensions to add to the self signed cert -+string_mask = utf8only -+ -+# req_extensions = v3_req # The extensions to add to a certificate request -+ -+[ req_distinguished_name ] -+countryName = UK -+ -+organizationName = OpenSSL Group -+# Take CN from environment so it can come from a script. -+commonName = $ENV::CN -+ -+[ usr_cert ] -+ -+# These extensions are added when 'ca' signs a request for an end entity -+# certificate -+ -+basicConstraints=critical, CA:FALSE -+keyUsage=critical, nonRepudiation, digitalSignature, keyEncipherment -+ -+# This will be displayed in Netscape's comment listbox. -+nsComment = "OpenSSL Generated Certificate" -+ -+# PKIX recommendations harmless if included in all certificates. -+subjectKeyIdentifier=hash -+authorityKeyIdentifier=keyid -+# OCSP responder certificate -+[ ocsp_cert ] -+ -+basicConstraints=critical, CA:FALSE -+keyUsage=critical, nonRepudiation, digitalSignature, keyEncipherment -+ -+# This will be displayed in Netscape's comment listbox. -+nsComment = "OpenSSL Generated Certificate" -+ -+# PKIX recommendations harmless if included in all certificates. -+subjectKeyIdentifier=hash -+authorityKeyIdentifier=keyid -+extendedKeyUsage=OCSPSigning -+ -+[ dh_cert ] -+ -+# These extensions are added when 'ca' signs a request for an end entity -+# DH certificate -+ -+basicConstraints=critical, CA:FALSE -+keyUsage=critical, keyAgreement -+ -+# PKIX recommendations harmless if included in all certificates. -+subjectKeyIdentifier=hash -+authorityKeyIdentifier=keyid -+ -+[ v3_ca ] -+ -+ -+# Extensions for a typical CA -+ -+# PKIX recommendation. -+ -+subjectKeyIdentifier=hash -+authorityKeyIdentifier=keyid:always -+basicConstraints = critical,CA:true -+keyUsage = critical, cRLSign, keyCertSign -+ -+# Minimal CA entry to allow generation of CRLs. -+[ca] -+database=index.txt -+crlnumber=crlnum.txt -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/mkcerts.sh b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/mkcerts.sh -new file mode 100644 -index 0000000..18daa6b ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/mkcerts.sh -@@ -0,0 +1,96 @@ -+#!/bin/sh -+ -+OPENSSL=../../apps/openssl -+OPENSSL_CONF=../../apps/openssl.cnf -+export OPENSSL_CONF -+ -+# Root CA: create certificate directly -+CN="Test Root CA" $OPENSSL req -config ca.cnf -x509 -nodes \ -+ -keyout root.pem -out root.pem -newkey rsa:2048 -days 3650 -+# Intermediate CA: request first -+CN="Test Intermediate CA" $OPENSSL req -config ca.cnf -nodes \ -+ -keyout intkey.pem -out intreq.pem -newkey rsa:2048 -+# Sign request: CA extensions -+$OPENSSL x509 -req -in intreq.pem -CA root.pem -days 3600 \ -+ -extfile ca.cnf -extensions v3_ca -CAcreateserial -out intca.pem -+ -+# Server certificate: create request first -+CN="Test Server Cert" $OPENSSL req -config ca.cnf -nodes \ -+ -keyout skey.pem -out req.pem -newkey rsa:1024 -+# Sign request: end entity extensions -+$OPENSSL x509 -req -in req.pem -CA intca.pem -CAkey intkey.pem -days 3600 \ -+ -extfile ca.cnf -extensions usr_cert -CAcreateserial -out server.pem -+ -+# Client certificate: request first -+CN="Test Client Cert" $OPENSSL req -config ca.cnf -nodes \ -+ -keyout ckey.pem -out creq.pem -newkey rsa:1024 -+# Sign using intermediate CA -+$OPENSSL x509 -req -in creq.pem -CA intca.pem -CAkey intkey.pem -days 3600 \ -+ -extfile ca.cnf -extensions usr_cert -CAcreateserial -out client.pem -+ -+# Revoked certificate: request first -+CN="Test Revoked Cert" $OPENSSL req -config ca.cnf -nodes \ -+ -keyout revkey.pem -out rreq.pem -newkey rsa:1024 -+# Sign using intermediate CA -+$OPENSSL x509 -req -in rreq.pem -CA intca.pem -CAkey intkey.pem -days 3600 \ -+ -extfile ca.cnf -extensions usr_cert -CAcreateserial -out rev.pem -+ -+# OCSP responder certificate: request first -+CN="Test OCSP Responder Cert" $OPENSSL req -config ca.cnf -nodes \ -+ -keyout respkey.pem -out respreq.pem -newkey rsa:1024 -+# Sign using intermediate CA and responder extensions -+$OPENSSL x509 -req -in respreq.pem -CA intca.pem -CAkey intkey.pem -days 3600 \ -+ -extfile ca.cnf -extensions ocsp_cert -CAcreateserial -out resp.pem -+ -+# Example creating a PKCS#3 DH certificate. -+ -+# First DH parameters -+ -+[ -f dhp.pem ] || $OPENSSL genpkey -genparam -algorithm DH -pkeyopt dh_paramgen_prime_len:1024 -out dhp.pem -+ -+# Now a DH private key -+$OPENSSL genpkey -paramfile dhp.pem -out dhskey.pem -+# Create DH public key file -+$OPENSSL pkey -in dhskey.pem -pubout -out dhspub.pem -+# Certificate request, key just reuses old one as it is ignored when the -+# request is signed. -+CN="Test Server DH Cert" $OPENSSL req -config ca.cnf -new \ -+ -key skey.pem -out dhsreq.pem -+# Sign request: end entity DH extensions -+$OPENSSL x509 -req -in dhsreq.pem -CA root.pem -days 3600 \ -+ -force_pubkey dhspub.pem \ -+ -extfile ca.cnf -extensions dh_cert -CAcreateserial -out dhserver.pem -+ -+# DH client certificate -+ -+$OPENSSL genpkey -paramfile dhp.pem -out dhckey.pem -+$OPENSSL pkey -in dhckey.pem -pubout -out dhcpub.pem -+CN="Test Client DH Cert" $OPENSSL req -config ca.cnf -new \ -+ -key skey.pem -out dhcreq.pem -+$OPENSSL x509 -req -in dhcreq.pem -CA root.pem -days 3600 \ -+ -force_pubkey dhcpub.pem \ -+ -extfile ca.cnf -extensions dh_cert -CAcreateserial -out dhclient.pem -+ -+# Examples of CRL generation without the need to use 'ca' to issue -+# certificates. -+# Create zero length index file -+>index.txt -+# Create initial crl number file -+echo 01 >crlnum.txt -+# Add entries for server and client certs -+$OPENSSL ca -valid server.pem -keyfile root.pem -cert root.pem \ -+ -config ca.cnf -md sha1 -+$OPENSSL ca -valid client.pem -keyfile root.pem -cert root.pem \ -+ -config ca.cnf -md sha1 -+$OPENSSL ca -valid rev.pem -keyfile root.pem -cert root.pem \ -+ -config ca.cnf -md sha1 -+# Generate a CRL. -+$OPENSSL ca -gencrl -keyfile root.pem -cert root.pem -config ca.cnf \ -+ -md sha1 -crldays 1 -out crl1.pem -+# Revoke a certificate -+openssl ca -revoke rev.pem -crl_reason superseded \ -+ -keyfile root.pem -cert root.pem -config ca.cnf -md sha1 -+# Generate another CRL -+$OPENSSL ca -gencrl -keyfile root.pem -cert root.pem -config ca.cnf \ -+ -md sha1 -crldays 1 -out crl2.pem -+ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/ocspquery.sh b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/ocspquery.sh -new file mode 100644 -index 0000000..f664113 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/ocspquery.sh -@@ -0,0 +1,21 @@ -+# Example querying OpenSSL test responder. Assumes ocsprun.sh has been -+# called. -+ -+OPENSSL=../../apps/openssl -+OPENSSL_CONF=../../apps/openssl.cnf -+export OPENSSL_CONF -+ -+# Send responder queries for each certificate. -+ -+echo "Requesting OCSP status for each certificate" -+$OPENSSL ocsp -issuer intca.pem -cert client.pem -CAfile root.pem \ -+ -url http://127.0.0.1:8888/ -+$OPENSSL ocsp -issuer intca.pem -cert server.pem -CAfile root.pem \ -+ -url http://127.0.0.1:8888/ -+$OPENSSL ocsp -issuer intca.pem -cert rev.pem -CAfile root.pem \ -+ -url http://127.0.0.1:8888/ -+# One query for all three certificates. -+echo "Requesting OCSP status for three certificates in one request" -+$OPENSSL ocsp -issuer intca.pem \ -+ -cert client.pem -cert server.pem -cert rev.pem \ -+ -CAfile root.pem -url http://127.0.0.1:8888/ -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/certs/ocsprun.sh b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/ocsprun.sh -new file mode 100644 -index 0000000..a65e5f2 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/certs/ocsprun.sh -@@ -0,0 +1,14 @@ -+# Example of running an querying OpenSSL test OCSP responder. -+# This assumes "mkcerts.sh" or similar has been run to set up the -+# necessary file structure. -+ -+OPENSSL=../../apps/openssl -+OPENSSL_CONF=../../apps/openssl.cnf -+export OPENSSL_CONF -+ -+# Run OCSP responder. -+ -+PORT=8888 -+ -+$OPENSSL ocsp -port $PORT -index index.txt -CA intca.pem \ -+ -rsigner resp.pem -rkey respkey.pem -rother intca.pem $* -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cacert.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cacert.pem -new file mode 100644 -index 0000000..75cbb34 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cacert.pem -@@ -0,0 +1,18 @@ -+-----BEGIN CERTIFICATE----- -+MIIC6DCCAlGgAwIBAgIJAMfGO3rdo2uUMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV -+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv -+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTc0MzE3 -+WhcNMTcwNDEwMTc0MzE3WjBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBD -+aXR5MRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlN -+RSBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqJMal1uC1/1wz -+i5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtdc3rMcRgJaMbP+qaEcDXoIsZfYXGR -+ielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3dbBECq0hZKcbz7wfr+2OeNWm46iT -+jcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQABo4G7MIG4MB0GA1UdDgQWBBRHUypx -+CXFQYqewhGo72lWPQUsjoDCBiAYDVR0jBIGAMH6AFEdTKnEJcVBip7CEajvaVY9B -+SyOgoVukWTBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBDaXR5MRYwFAYD -+VQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlNRSBSb290IENB -+ggkAx8Y7et2ja5QwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQANI+Yc -+G/YDM1WMUGEzEkU9UhsIUqdyBebnK3+OyxZSouDcE/M10jFJzBf/F5b0uUGAKWwo -+u0dzmILfKjdfWe8EyCRafZcm00rVcO09i/63FBYzlHbmfUATIqZdhKzxxQMPs5mF -+1je+pHUpzIY8TSXyh/uD9IkAy04IHwGZQf9akw== -+-----END CERTIFICATE----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cakey.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cakey.pem -new file mode 100644 -index 0000000..3b53c5e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cakey.pem -@@ -0,0 +1,15 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIICXgIBAAKBgQCqJMal1uC1/1wzi5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtd -+c3rMcRgJaMbP+qaEcDXoIsZfYXGRielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3 -+dbBECq0hZKcbz7wfr+2OeNWm46iTjcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQAB -+AoGBAKWOZ2UTc1BkjDjz0XoscmAR8Rj77MdGzfOPkIxPultSW+3yZpkGNyUbnsH5 -+HAtf4Avai/m3bMN+s91kDpx9/g/I9ZEHPQLcDICETvwt/EHT7+hwvaQgsM+TgpMs -+tjlGZOWent6wVIuvwwzqOMXZLgK9FvY7upwgtrys4G3Kab5hAkEA2QzFflWyEvKS -+rMSaVtn/IjFilwa7H0IdakkjM34z4peerFTPBr4J47YD4RCR/dAvxyNy3zUxtH18 -+9R6dUixI6QJBAMitJD0xOkbGWBX8KVJvRiKOIdf/95ZUAgN/h3bWKy57EB9NYj3u -+jbxXcvdjfSqiITykkjAg7SG7nrlzJsu6CpcCQG6gVsy0auXDY0TRlASuaZ6I40Is -+uRUOgqWYj2uAaHuWYdZeB4LdO3cnX0TISFDAWom6JKNlnmbrCtR4fSDT13kCQQCU -++VQJyV3F5MDHsWbLt6eNR46AV5lpk/vatPXPlrZ/zwPs+PmRmGLICvNiDA2DdNDP -+wCx2Zjsj67CtY3rNitMJAkEAm09BQnjnbBXUb1rd2SjNDWTsu80Z+zLu8pAwXNhW -+8nsvMYqlYMIxuMPwu/QuTnMRhMZ08uhqoD3ukZnBeoMEVg== -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_comp.c b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_comp.c -new file mode 100644 -index 0000000..0d548f9 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_comp.c -@@ -0,0 +1,64 @@ -+/* -+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Simple S/MIME compress example */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ CMS_ContentInfo *cms = NULL; -+ int ret = 1; -+ -+ /* -+ * On OpenSSL 1.0.0+ only: -+ * for streaming set CMS_STREAM -+ */ -+ int flags = CMS_STREAM; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Open content being compressed */ -+ -+ in = BIO_new_file("comp.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* compress content */ -+ cms = CMS_compress(in, NID_zlib_compression, flags); -+ -+ if (!cms) -+ goto err; -+ -+ out = BIO_new_file("smcomp.txt", "w"); -+ if (!out) -+ goto err; -+ -+ /* Write out S/MIME message */ -+ if (!SMIME_write_CMS(out, cms, in, flags)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ -+ if (ret) { -+ fprintf(stderr, "Error Compressing Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ -+ CMS_ContentInfo_free(cms); -+ BIO_free(in); -+ BIO_free(out); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_ddec.c b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_ddec.c -new file mode 100644 -index 0000000..8f2e9ae ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_ddec.c -@@ -0,0 +1,88 @@ -+/* -+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * S/MIME detached data decrypt example: rarely done but should the need -+ * arise this is an example.... -+ */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL, *dcont = NULL; -+ X509 *rcert = NULL; -+ EVP_PKEY *rkey = NULL; -+ CMS_ContentInfo *cms = NULL; -+ int ret = 1; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Read in recipient certificate and private key */ -+ tbio = BIO_new_file("signer.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ BIO_reset(tbio); -+ -+ rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); -+ -+ if (!rcert || !rkey) -+ goto err; -+ -+ /* Open PEM file containing enveloped data */ -+ -+ in = BIO_new_file("smencr.pem", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* Parse PEM content */ -+ cms = PEM_read_bio_CMS(in, NULL, 0, NULL); -+ -+ if (!cms) -+ goto err; -+ -+ /* Open file containing detached content */ -+ dcont = BIO_new_file("smencr.out", "rb"); -+ -+ if (!in) -+ goto err; -+ -+ out = BIO_new_file("encrout.txt", "w"); -+ if (!out) -+ goto err; -+ -+ /* Decrypt S/MIME message */ -+ if (!CMS_decrypt(cms, rkey, rcert, dcont, out, 0)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ -+ if (ret) { -+ fprintf(stderr, "Error Decrypting Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ -+ CMS_ContentInfo_free(cms); -+ X509_free(rcert); -+ EVP_PKEY_free(rkey); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ BIO_free(dcont); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_dec.c b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_dec.c -new file mode 100644 -index 0000000..4f9428b ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_dec.c -@@ -0,0 +1,78 @@ -+/* -+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Simple S/MIME decryption example */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL; -+ X509 *rcert = NULL; -+ EVP_PKEY *rkey = NULL; -+ CMS_ContentInfo *cms = NULL; -+ int ret = 1; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Read in recipient certificate and private key */ -+ tbio = BIO_new_file("signer.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ BIO_reset(tbio); -+ -+ rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); -+ -+ if (!rcert || !rkey) -+ goto err; -+ -+ /* Open S/MIME message to decrypt */ -+ -+ in = BIO_new_file("smencr.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* Parse message */ -+ cms = SMIME_read_CMS(in, NULL); -+ -+ if (!cms) -+ goto err; -+ -+ out = BIO_new_file("decout.txt", "w"); -+ if (!out) -+ goto err; -+ -+ /* Decrypt S/MIME message */ -+ if (!CMS_decrypt(cms, rkey, rcert, NULL, out, 0)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ -+ if (ret) { -+ fprintf(stderr, "Error Decrypting Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ -+ CMS_ContentInfo_free(cms); -+ X509_free(rcert); -+ EVP_PKEY_free(rkey); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_denc.c b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_denc.c -new file mode 100644 -index 0000000..adba69b ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_denc.c -@@ -0,0 +1,97 @@ -+/* -+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * S/MIME detached data encrypt example: rarely done but should the need -+ * arise this is an example.... -+ */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL, *dout = NULL; -+ X509 *rcert = NULL; -+ STACK_OF(X509) *recips = NULL; -+ CMS_ContentInfo *cms = NULL; -+ int ret = 1; -+ -+ int flags = CMS_STREAM | CMS_DETACHED; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Read in recipient certificate */ -+ tbio = BIO_new_file("signer.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ if (!rcert) -+ goto err; -+ -+ /* Create recipient STACK and add recipient cert to it */ -+ recips = sk_X509_new_null(); -+ -+ if (!recips || !sk_X509_push(recips, rcert)) -+ goto err; -+ -+ /* -+ * sk_X509_pop_free will free up recipient STACK and its contents so set -+ * rcert to NULL so it isn't freed up twice. -+ */ -+ rcert = NULL; -+ -+ /* Open content being encrypted */ -+ -+ in = BIO_new_file("encr.txt", "r"); -+ -+ dout = BIO_new_file("smencr.out", "wb"); -+ -+ if (!in) -+ goto err; -+ -+ /* encrypt content */ -+ cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags); -+ -+ if (!cms) -+ goto err; -+ -+ out = BIO_new_file("smencr.pem", "w"); -+ if (!out) -+ goto err; -+ -+ if (!CMS_final(cms, in, dout, flags)) -+ goto err; -+ -+ /* Write out CMS structure without content */ -+ if (!PEM_write_bio_CMS(out, cms)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ -+ if (ret) { -+ fprintf(stderr, "Error Encrypting Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ -+ CMS_ContentInfo_free(cms); -+ X509_free(rcert); -+ sk_X509_pop_free(recips, X509_free); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(dout); -+ BIO_free(tbio); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_enc.c b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_enc.c -new file mode 100644 -index 0000000..4d17d72 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_enc.c -@@ -0,0 +1,92 @@ -+/* -+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Simple S/MIME encrypt example */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL; -+ X509 *rcert = NULL; -+ STACK_OF(X509) *recips = NULL; -+ CMS_ContentInfo *cms = NULL; -+ int ret = 1; -+ -+ /* -+ * On OpenSSL 1.0.0 and later only: -+ * for streaming set CMS_STREAM -+ */ -+ int flags = CMS_STREAM; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Read in recipient certificate */ -+ tbio = BIO_new_file("signer.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ if (!rcert) -+ goto err; -+ -+ /* Create recipient STACK and add recipient cert to it */ -+ recips = sk_X509_new_null(); -+ -+ if (!recips || !sk_X509_push(recips, rcert)) -+ goto err; -+ -+ /* -+ * sk_X509_pop_free will free up recipient STACK and its contents so set -+ * rcert to NULL so it isn't freed up twice. -+ */ -+ rcert = NULL; -+ -+ /* Open content being encrypted */ -+ -+ in = BIO_new_file("encr.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* encrypt content */ -+ cms = CMS_encrypt(recips, in, EVP_des_ede3_cbc(), flags); -+ -+ if (!cms) -+ goto err; -+ -+ out = BIO_new_file("smencr.txt", "w"); -+ if (!out) -+ goto err; -+ -+ /* Write out S/MIME message */ -+ if (!SMIME_write_CMS(out, cms, in, flags)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ -+ if (ret) { -+ fprintf(stderr, "Error Encrypting Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ -+ CMS_ContentInfo_free(cms); -+ X509_free(rcert); -+ sk_X509_pop_free(recips, X509_free); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_sign.c b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_sign.c -new file mode 100644 -index 0000000..15bd5b8 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_sign.c -@@ -0,0 +1,88 @@ -+/* -+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Simple S/MIME signing example */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL; -+ X509 *scert = NULL; -+ EVP_PKEY *skey = NULL; -+ CMS_ContentInfo *cms = NULL; -+ int ret = 1; -+ -+ /* -+ * For simple S/MIME signing use CMS_DETACHED. On OpenSSL 1.0.0 only: for -+ * streaming detached set CMS_DETACHED|CMS_STREAM for streaming -+ * non-detached set CMS_STREAM -+ */ -+ int flags = CMS_DETACHED | CMS_STREAM; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Read in signer certificate and private key */ -+ tbio = BIO_new_file("signer.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ scert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ BIO_reset(tbio); -+ -+ skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); -+ -+ if (!scert || !skey) -+ goto err; -+ -+ /* Open content being signed */ -+ -+ in = BIO_new_file("sign.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* Sign content */ -+ cms = CMS_sign(scert, skey, NULL, in, flags); -+ -+ if (!cms) -+ goto err; -+ -+ out = BIO_new_file("smout.txt", "w"); -+ if (!out) -+ goto err; -+ -+ if (!(flags & CMS_STREAM)) -+ BIO_reset(in); -+ -+ /* Write out S/MIME message */ -+ if (!SMIME_write_CMS(out, cms, in, flags)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ -+ if (ret) { -+ fprintf(stderr, "Error Signing Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ -+ CMS_ContentInfo_free(cms); -+ X509_free(scert); -+ EVP_PKEY_free(skey); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_sign2.c b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_sign2.c -new file mode 100644 -index 0000000..14ebf27 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_sign2.c -@@ -0,0 +1,98 @@ -+/* -+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* S/MIME signing example: 2 signers */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL; -+ X509 *scert = NULL, *scert2 = NULL; -+ EVP_PKEY *skey = NULL, *skey2 = NULL; -+ CMS_ContentInfo *cms = NULL; -+ int ret = 1; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ tbio = BIO_new_file("signer.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ scert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ BIO_reset(tbio); -+ -+ skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); -+ -+ BIO_free(tbio); -+ -+ tbio = BIO_new_file("signer2.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ scert2 = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ BIO_reset(tbio); -+ -+ skey2 = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); -+ -+ if (!scert2 || !skey2) -+ goto err; -+ -+ in = BIO_new_file("sign.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ cms = CMS_sign(NULL, NULL, NULL, in, CMS_STREAM | CMS_PARTIAL); -+ -+ if (!cms) -+ goto err; -+ -+ /* Add each signer in turn */ -+ -+ if (!CMS_add1_signer(cms, scert, skey, NULL, 0)) -+ goto err; -+ -+ if (!CMS_add1_signer(cms, scert2, skey2, NULL, 0)) -+ goto err; -+ -+ out = BIO_new_file("smout.txt", "w"); -+ if (!out) -+ goto err; -+ -+ /* NB: content included and finalized by SMIME_write_CMS */ -+ -+ if (!SMIME_write_CMS(out, cms, in, CMS_STREAM)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ -+ if (ret) { -+ fprintf(stderr, "Error Signing Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ -+ CMS_ContentInfo_free(cms); -+ X509_free(scert); -+ EVP_PKEY_free(skey); -+ X509_free(scert2); -+ EVP_PKEY_free(skey2); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_uncomp.c b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_uncomp.c -new file mode 100644 -index 0000000..3e3b4c4 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_uncomp.c -@@ -0,0 +1,58 @@ -+/* -+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Simple S/MIME uncompression example */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL; -+ CMS_ContentInfo *cms = NULL; -+ int ret = 1; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Open compressed content */ -+ -+ in = BIO_new_file("smcomp.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* Sign content */ -+ cms = SMIME_read_CMS(in, NULL); -+ -+ if (!cms) -+ goto err; -+ -+ out = BIO_new_file("smuncomp.txt", "w"); -+ if (!out) -+ goto err; -+ -+ /* Uncompress S/MIME message */ -+ if (!CMS_uncompress(cms, out, NULL, 0)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ -+ if (ret) { -+ fprintf(stderr, "Error Uncompressing Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ -+ CMS_ContentInfo_free(cms); -+ BIO_free(in); -+ BIO_free(out); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_ver.c b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_ver.c -new file mode 100644 -index 0000000..43c10e2 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/cms_ver.c -@@ -0,0 +1,85 @@ -+/* -+ * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Simple S/MIME verification example */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL, *cont = NULL; -+ X509_STORE *st = NULL; -+ X509 *cacert = NULL; -+ CMS_ContentInfo *cms = NULL; -+ -+ int ret = 1; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Set up trusted CA certificate store */ -+ -+ st = X509_STORE_new(); -+ -+ /* Read in CA certificate */ -+ tbio = BIO_new_file("cacert.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ cacert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ if (!cacert) -+ goto err; -+ -+ if (!X509_STORE_add_cert(st, cacert)) -+ goto err; -+ -+ /* Open message being verified */ -+ -+ in = BIO_new_file("smout.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* parse message */ -+ cms = SMIME_read_CMS(in, &cont); -+ -+ if (!cms) -+ goto err; -+ -+ /* File to output verified content to */ -+ out = BIO_new_file("smver.txt", "w"); -+ if (!out) -+ goto err; -+ -+ if (!CMS_verify(cms, NULL, st, cont, out, 0)) { -+ fprintf(stderr, "Verification Failure\n"); -+ goto err; -+ } -+ -+ fprintf(stderr, "Verification Successful\n"); -+ -+ ret = 0; -+ -+ err: -+ -+ if (ret) { -+ fprintf(stderr, "Error Verifying Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ -+ CMS_ContentInfo_free(cms); -+ X509_free(cacert); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/comp.txt b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/comp.txt -new file mode 100644 -index 0000000..1672328 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/comp.txt -@@ -0,0 +1,22 @@ -+Content-type: text/plain -+ -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -+Some Text To be Compressed -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/encr.txt b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/encr.txt -new file mode 100644 -index 0000000..0eceb40 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/encr.txt -@@ -0,0 +1,3 @@ -+Content-type: text/plain -+ -+Sample OpenSSL Data for CMS encryption -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/sign.txt b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/sign.txt -new file mode 100644 -index 0000000..c3f9d73 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/sign.txt -@@ -0,0 +1,3 @@ -+Content-type: text/plain -+ -+Test OpenSSL CMS Signed Content -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/signer.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/signer.pem -new file mode 100644 -index 0000000..bac16ba ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/signer.pem -@@ -0,0 +1,32 @@ -+-----BEGIN CERTIFICATE----- -+MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRhMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV -+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv -+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTI3 -+WhcNMTcwNDA5MTgyOTI3WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT -+TCB0ZXN0IFMvTUlNRSBzaWduZXIgMTEgMB4GCSqGSIb3DQEJARYRdGVzdDFAb3Bl -+bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL1ocAQ7ON2pIUXz -+jwKPzpPB9ozB6PFG6F6kARO+i0DiT6Qn8abUjwpHPU+lGys83QlpbkQVUD6Fv/4L -+ytihk6N9Pr/feECVcSZ20dI43WXjfYak14dSVrZkGNMMXqKmnnqtkAdD0oJN7A7y -+gcf8RuViV0kvk9/36eCMwMHrImfhAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI -+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW -+BBSyKqjvctIsFNBHULBTqr8SHtSxpDAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7 -+2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBvdYVoBfd4RV/xWSMXIcgw/i5OiwyX -+MsenQePll51MpglfArd7pUipUalCqlJt/Gs8kD16Ih1z1yuWYVTMlnDZ0PwbIOYn -++Jr8XLF9b1SMJt6PwckZZ0LZdIi2KwGAxVsIW1kjJAqu9o4YH37XW37yYdQRxfvv -+lDiQlgX0JtmLgA== -+-----END CERTIFICATE----- -+-----BEGIN RSA PRIVATE KEY----- -+MIICXAIBAAKBgQC9aHAEOzjdqSFF848Cj86TwfaMwejxRuhepAETvotA4k+kJ/Gm -+1I8KRz1PpRsrPN0JaW5EFVA+hb/+C8rYoZOjfT6/33hAlXEmdtHSON1l432GpNeH -+Ula2ZBjTDF6ipp56rZAHQ9KCTewO8oHH/EblYldJL5Pf9+ngjMDB6yJn4QIDAQAB -+AoGACCuYIWaYll80UzslYRvo8lC8nOfEb5v6bBKxBTQD98GLY+5hKywiG3RlPalG -+mb/fXQeSPReaRYgpdwD1OBEIOEMW9kLyqpzokC0xjpZ+MwsuJTlxCesk5GEsMa3o -+wC3QMmiRA7qrZ/SzTtwrs++9mZ/pxp8JZ6pKYUj8SE7/vV0CQQDz8Ix2t40E16hx -+04+XhClnGqydZJyLLSxcTU3ZVhYxL+efo/5hZ8tKpkcDi8wq6T03BOKrKxrlIW55 -+qDRNM24rAkEAxsWzu/rJhIouQyNoYygEIEYzFRlTQyZSg59u6dNiewMn27dOAbyc -+YT7B6da7e74QttTXo0lIllsX2S38+XsIIwJBANSRuIU3G66tkr5l4gnhhAaxqtuY -+sgVhvvdL8dvC9aG1Ifzt9hzBSthpHxbK+oYmK07HdhI8hLpIMLHYzoK7n3MCQEy4 -+4rccBcxyyYiAkjozp+QNNIpgTBMPJ6pGT7lRLiHtBeV4y1NASdv/LTnk+Fi69Bid -+7t3H24ytfHcHmS1yn6ECQF6Jmh4C7dlvp59zXp+t+VsXxa/8sq41vKNIj0Rx9vh5 -+xp9XL0C5ZpgmBnsTydP9pmkiL4ltLbMX0wJU6N2cmFw= -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/cms/signer2.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/signer2.pem -new file mode 100644 -index 0000000..25e23d1 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/cms/signer2.pem -@@ -0,0 +1,32 @@ -+-----BEGIN CERTIFICATE----- -+MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRiMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV -+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv -+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTQ0 -+WhcNMTcwNDA5MTgyOTQ0WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT -+TCB0ZXN0IFMvTUlNRSBzaWduZXIgMjEgMB4GCSqGSIb3DQEJARYRdGVzdDJAb3Bl -+bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANco7VPgX9vcGwmZ -+jYqjq1JiR7M38dsMNhuJyLRVjJ5/cpFluQydQuG1PhzOJ8zfYVFicOXKvbYuKuXW -+ozZIwzqEqWsNf36KHTLS6yOMG8I13cRInh+fAIKq9Z8Eh65I7FJzVsNsfEQrGfEW -+GMA8us24IaSvP3QkbfHJn/4RaKznAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI -+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW -+BBRlrLQJUB8uAa4q8B2OqvvTXonF5zAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7 -+2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBQbi2juGALg2k9m1hKpzR2lCGmGO3X -+h3Jh/l0vIxDr0RTgP2vBrtITlx655P/o1snoeTIpYG8uUnFnTE/6YakdayAIlxV4 -+aZl63AivZMpQB5SPaPH/jEsGJ8UQMfdiy4ORWIULupuPKlKwODNw7tVhQIACS/DR -+2aX6rl2JEuJ5Yg== -+-----END CERTIFICATE----- -+-----BEGIN RSA PRIVATE KEY----- -+MIICXAIBAAKBgQDXKO1T4F/b3BsJmY2Ko6tSYkezN/HbDDYbici0VYyef3KRZbkM -+nULhtT4czifM32FRYnDlyr22Lirl1qM2SMM6hKlrDX9+ih0y0usjjBvCNd3ESJ4f -+nwCCqvWfBIeuSOxSc1bDbHxEKxnxFhjAPLrNuCGkrz90JG3xyZ/+EWis5wIDAQAB -+AoGAUTB2bcIrKfGimjrBOGGOUmYXnD8uGnQ/LqENhU8K4vxApTD3ZRUqmbUknQYF -+6r8YH/e/llasw8QkF9qod+F5GTgsnyh/aMidFHKrXXbf1662scz9+S6crSXq9Eb2 -+CL57f6Kw61k6edrz8zHdA+rnTK00hzgzKCP4ZL5k8/55ueECQQD+BK+nsKi6CcKf -+m3Mh61Sf2Icm5JlMCKaihlbnh78lBN1imYUAfHJEnQ1ujxXB94R+6o9S+XrWTnTX -+2m/JNIfpAkEA2NaidX7Sv5jnRPkwJ02Srl0urxINLmg4bU0zmM3VoMklYBHWnMyr -+upPZGPh5TzCa+g6FTBmU8XK61wvnEKNcTwJBAM24VdnlBIDGbsx8RJ3vzLU30xz4 -+ff5J80okqjUQhwkgC3tTAZgHMTPITZyAXQqdvrxakoCMc6MkHxTBX08AMCECQHHL -+SdyxXrYv7waSY0PtANJCkpJLveEhzqMFxdMmCjtj9BpTojYNbv3uQxtIopj9YAdk -+gW2ray++zvC2DV/86x8CQH4UJwgO6JqU4bSgi6HiRNjDg26tJ0Beu8jjl1vrkIVX -+pHFwSUeLZUsT2/iTUSgYH4uYiZPgYNcKTCT9W6se30A= -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/evp/aesccm.c b/CryptoPkg/Library/OpensslLib/openssl/demos/evp/aesccm.c -new file mode 100644 -index 0000000..cc4d0b5 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/evp/aesccm.c -@@ -0,0 +1,125 @@ -+/* -+ * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * Simple AES CCM test program, uses the same NIST data used for the FIPS -+ * self test but uses the application level EVP APIs. -+ */ -+#include -+#include -+#include -+ -+/* AES-CCM test data from NIST public test vectors */ -+ -+static const unsigned char ccm_key[] = { -+ 0xce, 0xb0, 0x09, 0xae, 0xa4, 0x45, 0x44, 0x51, 0xfe, 0xad, 0xf0, 0xe6, -+ 0xb3, 0x6f, 0x45, 0x55, 0x5d, 0xd0, 0x47, 0x23, 0xba, 0xa4, 0x48, 0xe8 -+}; -+ -+static const unsigned char ccm_nonce[] = { -+ 0x76, 0x40, 0x43, 0xc4, 0x94, 0x60, 0xb7 -+}; -+ -+static const unsigned char ccm_adata[] = { -+ 0x6e, 0x80, 0xdd, 0x7f, 0x1b, 0xad, 0xf3, 0xa1, 0xc9, 0xab, 0x25, 0xc7, -+ 0x5f, 0x10, 0xbd, 0xe7, 0x8c, 0x23, 0xfa, 0x0e, 0xb8, 0xf9, 0xaa, 0xa5, -+ 0x3a, 0xde, 0xfb, 0xf4, 0xcb, 0xf7, 0x8f, 0xe4 -+}; -+ -+static const unsigned char ccm_pt[] = { -+ 0xc8, 0xd2, 0x75, 0xf9, 0x19, 0xe1, 0x7d, 0x7f, 0xe6, 0x9c, 0x2a, 0x1f, -+ 0x58, 0x93, 0x9d, 0xfe, 0x4d, 0x40, 0x37, 0x91, 0xb5, 0xdf, 0x13, 0x10 -+}; -+ -+static const unsigned char ccm_ct[] = { -+ 0x8a, 0x0f, 0x3d, 0x82, 0x29, 0xe4, 0x8e, 0x74, 0x87, 0xfd, 0x95, 0xa2, -+ 0x8a, 0xd3, 0x92, 0xc8, 0x0b, 0x36, 0x81, 0xd4, 0xfb, 0xc7, 0xbb, 0xfd -+}; -+ -+static const unsigned char ccm_tag[] = { -+ 0x2d, 0xd6, 0xef, 0x1c, 0x45, 0xd4, 0xcc, 0xb7, 0x23, 0xdc, 0x07, 0x44, -+ 0x14, 0xdb, 0x50, 0x6d -+}; -+ -+void aes_ccm_encrypt(void) -+{ -+ EVP_CIPHER_CTX *ctx; -+ int outlen, tmplen; -+ unsigned char outbuf[1024]; -+ printf("AES CCM Encrypt:\n"); -+ printf("Plaintext:\n"); -+ BIO_dump_fp(stdout, ccm_pt, sizeof(ccm_pt)); -+ ctx = EVP_CIPHER_CTX_new(); -+ /* Set cipher type and mode */ -+ EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL); -+ /* Set nonce length if default 96 bits is not appropriate */ -+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(ccm_nonce), -+ NULL); -+ /* Set tag length */ -+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(ccm_tag), NULL); -+ /* Initialise key and IV */ -+ EVP_EncryptInit_ex(ctx, NULL, NULL, ccm_key, ccm_nonce); -+ /* Set plaintext length: only needed if AAD is used */ -+ EVP_EncryptUpdate(ctx, NULL, &outlen, NULL, sizeof(ccm_pt)); -+ /* Zero or one call to specify any AAD */ -+ EVP_EncryptUpdate(ctx, NULL, &outlen, ccm_adata, sizeof(ccm_adata)); -+ /* Encrypt plaintext: can only be called once */ -+ EVP_EncryptUpdate(ctx, outbuf, &outlen, ccm_pt, sizeof(ccm_pt)); -+ /* Output encrypted block */ -+ printf("Ciphertext:\n"); -+ BIO_dump_fp(stdout, outbuf, outlen); -+ /* Finalise: note get no output for CCM */ -+ EVP_EncryptFinal_ex(ctx, outbuf, &outlen); -+ /* Get tag */ -+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outbuf); -+ /* Output tag */ -+ printf("Tag:\n"); -+ BIO_dump_fp(stdout, outbuf, 16); -+ EVP_CIPHER_CTX_free(ctx); -+} -+ -+void aes_ccm_decrypt(void) -+{ -+ EVP_CIPHER_CTX *ctx; -+ int outlen, tmplen, rv; -+ unsigned char outbuf[1024]; -+ printf("AES CCM Derypt:\n"); -+ printf("Ciphertext:\n"); -+ BIO_dump_fp(stdout, ccm_ct, sizeof(ccm_ct)); -+ ctx = EVP_CIPHER_CTX_new(); -+ /* Select cipher */ -+ EVP_DecryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL); -+ /* Set nonce length, omit for 96 bits */ -+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(ccm_nonce), -+ NULL); -+ /* Set expected tag value */ -+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, -+ sizeof(ccm_tag), (void *)ccm_tag); -+ /* Specify key and IV */ -+ EVP_DecryptInit_ex(ctx, NULL, NULL, ccm_key, ccm_nonce); -+ /* Set ciphertext length: only needed if we have AAD */ -+ EVP_DecryptUpdate(ctx, NULL, &outlen, NULL, sizeof(ccm_ct)); -+ /* Zero or one call to specify any AAD */ -+ EVP_DecryptUpdate(ctx, NULL, &outlen, ccm_adata, sizeof(ccm_adata)); -+ /* Decrypt plaintext, verify tag: can only be called once */ -+ rv = EVP_DecryptUpdate(ctx, outbuf, &outlen, ccm_ct, sizeof(ccm_ct)); -+ /* Output decrypted block: if tag verify failed we get nothing */ -+ if (rv > 0) { -+ printf("Plaintext:\n"); -+ BIO_dump_fp(stdout, outbuf, outlen); -+ } else -+ printf("Plaintext not available: tag verify failed.\n"); -+ EVP_CIPHER_CTX_free(ctx); -+} -+ -+int main(int argc, char **argv) -+{ -+ aes_ccm_encrypt(); -+ aes_ccm_decrypt(); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/evp/aesgcm.c b/CryptoPkg/Library/OpensslLib/openssl/demos/evp/aesgcm.c -new file mode 100644 -index 0000000..17b0ef4 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/evp/aesgcm.c -@@ -0,0 +1,120 @@ -+/* -+ * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* -+ * Simple AES GCM test program, uses the same NIST data used for the FIPS -+ * self test but uses the application level EVP APIs. -+ */ -+#include -+#include -+#include -+ -+/* AES-GCM test data from NIST public test vectors */ -+ -+static const unsigned char gcm_key[] = { -+ 0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92, 0x1c, 0x04, 0x65, 0x66, -+ 0x5f, 0x8a, 0xe6, 0xd1, 0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69, -+ 0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f -+}; -+ -+static const unsigned char gcm_iv[] = { -+ 0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84 -+}; -+ -+static const unsigned char gcm_pt[] = { -+ 0xf5, 0x6e, 0x87, 0x05, 0x5b, 0xc3, 0x2d, 0x0e, 0xeb, 0x31, 0xb2, 0xea, -+ 0xcc, 0x2b, 0xf2, 0xa5 -+}; -+ -+static const unsigned char gcm_aad[] = { -+ 0x4d, 0x23, 0xc3, 0xce, 0xc3, 0x34, 0xb4, 0x9b, 0xdb, 0x37, 0x0c, 0x43, -+ 0x7f, 0xec, 0x78, 0xde -+}; -+ -+static const unsigned char gcm_ct[] = { -+ 0xf7, 0x26, 0x44, 0x13, 0xa8, 0x4c, 0x0e, 0x7c, 0xd5, 0x36, 0x86, 0x7e, -+ 0xb9, 0xf2, 0x17, 0x36 -+}; -+ -+static const unsigned char gcm_tag[] = { -+ 0x67, 0xba, 0x05, 0x10, 0x26, 0x2a, 0xe4, 0x87, 0xd7, 0x37, 0xee, 0x62, -+ 0x98, 0xf7, 0x7e, 0x0c -+}; -+ -+void aes_gcm_encrypt(void) -+{ -+ EVP_CIPHER_CTX *ctx; -+ int outlen, tmplen; -+ unsigned char outbuf[1024]; -+ printf("AES GCM Encrypt:\n"); -+ printf("Plaintext:\n"); -+ BIO_dump_fp(stdout, gcm_pt, sizeof(gcm_pt)); -+ ctx = EVP_CIPHER_CTX_new(); -+ /* Set cipher type and mode */ -+ EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); -+ /* Set IV length if default 96 bits is not appropriate */ -+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), NULL); -+ /* Initialise key and IV */ -+ EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv); -+ /* Zero or more calls to specify any AAD */ -+ EVP_EncryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad)); -+ /* Encrypt plaintext */ -+ EVP_EncryptUpdate(ctx, outbuf, &outlen, gcm_pt, sizeof(gcm_pt)); -+ /* Output encrypted block */ -+ printf("Ciphertext:\n"); -+ BIO_dump_fp(stdout, outbuf, outlen); -+ /* Finalise: note get no output for GCM */ -+ EVP_EncryptFinal_ex(ctx, outbuf, &outlen); -+ /* Get tag */ -+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outbuf); -+ /* Output tag */ -+ printf("Tag:\n"); -+ BIO_dump_fp(stdout, outbuf, 16); -+ EVP_CIPHER_CTX_free(ctx); -+} -+ -+void aes_gcm_decrypt(void) -+{ -+ EVP_CIPHER_CTX *ctx; -+ int outlen, tmplen, rv; -+ unsigned char outbuf[1024]; -+ printf("AES GCM Derypt:\n"); -+ printf("Ciphertext:\n"); -+ BIO_dump_fp(stdout, gcm_ct, sizeof(gcm_ct)); -+ ctx = EVP_CIPHER_CTX_new(); -+ /* Select cipher */ -+ EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); -+ /* Set IV length, omit for 96 bits */ -+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), NULL); -+ /* Specify key and IV */ -+ EVP_DecryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv); -+ /* Zero or more calls to specify any AAD */ -+ EVP_DecryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad)); -+ /* Decrypt plaintext */ -+ EVP_DecryptUpdate(ctx, outbuf, &outlen, gcm_ct, sizeof(gcm_ct)); -+ /* Output decrypted block */ -+ printf("Plaintext:\n"); -+ BIO_dump_fp(stdout, outbuf, outlen); -+ /* Set expected tag value. */ -+ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(gcm_tag), gcm_tag); -+ /* Finalise: note get no output for GCM */ -+ rv = EVP_DecryptFinal_ex(ctx, outbuf, &outlen); -+ /* -+ * Print out return value. If this is not successful authentication -+ * failed and plaintext is not trustworthy. -+ */ -+ printf("Tag Verify %s\n", rv > 0 ? "Successful!" : "Failed!"); -+ EVP_CIPHER_CTX_free(ctx); -+} -+ -+int main(int argc, char **argv) -+{ -+ aes_gcm_encrypt(); -+ aes_gcm_decrypt(); -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/README b/CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/README -new file mode 100644 -index 0000000..c87434b ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/README -@@ -0,0 +1,3 @@ -+PKCS#12 demo applications -+ -+Written by Steve Henson. -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/pkread.c b/CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/pkread.c -new file mode 100644 -index 0000000..3b87d7a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/pkread.c -@@ -0,0 +1,68 @@ -+/* -+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/* Simple PKCS#12 file reader */ -+ -+int main(int argc, char **argv) -+{ -+ FILE *fp; -+ EVP_PKEY *pkey; -+ X509 *cert; -+ STACK_OF(X509) *ca = NULL; -+ PKCS12 *p12; -+ int i; -+ if (argc != 4) { -+ fprintf(stderr, "Usage: pkread p12file password opfile\n"); -+ exit(1); -+ } -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ if ((fp = fopen(argv[1], "rb")) == NULL) { -+ fprintf(stderr, "Error opening file %s\n", argv[1]); -+ exit(1); -+ } -+ p12 = d2i_PKCS12_fp(fp, NULL); -+ fclose(fp); -+ if (!p12) { -+ fprintf(stderr, "Error reading PKCS#12 file\n"); -+ ERR_print_errors_fp(stderr); -+ exit(1); -+ } -+ if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) { -+ fprintf(stderr, "Error parsing PKCS#12 file\n"); -+ ERR_print_errors_fp(stderr); -+ exit(1); -+ } -+ PKCS12_free(p12); -+ if ((fp = fopen(argv[3], "w")) == NULL) { -+ fprintf(stderr, "Error opening file %s\n", argv[1]); -+ exit(1); -+ } -+ if (pkey) { -+ fprintf(fp, "***Private Key***\n"); -+ PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL); -+ } -+ if (cert) { -+ fprintf(fp, "***User Certificate***\n"); -+ PEM_write_X509_AUX(fp, cert); -+ } -+ if (ca && sk_X509_num(ca)) { -+ fprintf(fp, "***Other Certificates***\n"); -+ for (i = 0; i < sk_X509_num(ca); i++) -+ PEM_write_X509_AUX(fp, sk_X509_value(ca, i)); -+ } -+ fclose(fp); -+ return 0; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/pkwrite.c b/CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/pkwrite.c -new file mode 100644 -index 0000000..e14cf83 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/pkcs12/pkwrite.c -@@ -0,0 +1,53 @@ -+/* -+ * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/* Simple PKCS#12 file creator */ -+ -+int main(int argc, char **argv) -+{ -+ FILE *fp; -+ EVP_PKEY *pkey; -+ X509 *cert; -+ PKCS12 *p12; -+ if (argc != 5) { -+ fprintf(stderr, "Usage: pkwrite infile password name p12file\n"); -+ exit(1); -+ } -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ if ((fp = fopen(argv[1], "r")) == NULL) { -+ fprintf(stderr, "Error opening file %s\n", argv[1]); -+ exit(1); -+ } -+ cert = PEM_read_X509(fp, NULL, NULL, NULL); -+ rewind(fp); -+ pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL); -+ fclose(fp); -+ p12 = PKCS12_create(argv[2], argv[3], pkey, cert, NULL, 0, 0, 0, 0, 0); -+ if (!p12) { -+ fprintf(stderr, "Error creating PKCS#12 structure\n"); -+ ERR_print_errors_fp(stderr); -+ exit(1); -+ } -+ if ((fp = fopen(argv[4], "wb")) == NULL) { -+ fprintf(stderr, "Error opening file %s\n", argv[1]); -+ ERR_print_errors_fp(stderr); -+ exit(1); -+ } -+ i2d_PKCS12_fp(fp, p12); -+ PKCS12_free(p12); -+ fclose(fp); -+ return 0; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/cacert.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/cacert.pem -new file mode 100644 -index 0000000..75cbb34 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/cacert.pem -@@ -0,0 +1,18 @@ -+-----BEGIN CERTIFICATE----- -+MIIC6DCCAlGgAwIBAgIJAMfGO3rdo2uUMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV -+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv -+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTc0MzE3 -+WhcNMTcwNDEwMTc0MzE3WjBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBD -+aXR5MRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlN -+RSBSb290IENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqJMal1uC1/1wz -+i5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtdc3rMcRgJaMbP+qaEcDXoIsZfYXGR -+ielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3dbBECq0hZKcbz7wfr+2OeNWm46iT -+jcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQABo4G7MIG4MB0GA1UdDgQWBBRHUypx -+CXFQYqewhGo72lWPQUsjoDCBiAYDVR0jBIGAMH6AFEdTKnEJcVBip7CEajvaVY9B -+SyOgoVukWTBXMQswCQYDVQQGEwJVSzESMBAGA1UEBxMJVGVzdCBDaXR5MRYwFAYD -+VQQKEw1PcGVuU1NMIEdyb3VwMRwwGgYDVQQDExNUZXN0IFMvTUlNRSBSb290IENB -+ggkAx8Y7et2ja5QwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQANI+Yc -+G/YDM1WMUGEzEkU9UhsIUqdyBebnK3+OyxZSouDcE/M10jFJzBf/F5b0uUGAKWwo -+u0dzmILfKjdfWe8EyCRafZcm00rVcO09i/63FBYzlHbmfUATIqZdhKzxxQMPs5mF -+1je+pHUpzIY8TSXyh/uD9IkAy04IHwGZQf9akw== -+-----END CERTIFICATE----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/cakey.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/cakey.pem -new file mode 100644 -index 0000000..3b53c5e ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/cakey.pem -@@ -0,0 +1,15 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIICXgIBAAKBgQCqJMal1uC1/1wzi5+dE4EZF2im3BgROm5PVMbwPY9V1t+KYvtd -+c3rMcRgJaMbP+qaEcDXoIsZfYXGRielgfDNZmZcj1y/FOum+Jc2OZMs3ggPmjIQ3 -+dbBECq0hZKcbz7wfr+2OeNWm46iTjcSIXpGIRhUYEzOgv7zb8oOU70IbbwIDAQAB -+AoGBAKWOZ2UTc1BkjDjz0XoscmAR8Rj77MdGzfOPkIxPultSW+3yZpkGNyUbnsH5 -+HAtf4Avai/m3bMN+s91kDpx9/g/I9ZEHPQLcDICETvwt/EHT7+hwvaQgsM+TgpMs -+tjlGZOWent6wVIuvwwzqOMXZLgK9FvY7upwgtrys4G3Kab5hAkEA2QzFflWyEvKS -+rMSaVtn/IjFilwa7H0IdakkjM34z4peerFTPBr4J47YD4RCR/dAvxyNy3zUxtH18 -+9R6dUixI6QJBAMitJD0xOkbGWBX8KVJvRiKOIdf/95ZUAgN/h3bWKy57EB9NYj3u -+jbxXcvdjfSqiITykkjAg7SG7nrlzJsu6CpcCQG6gVsy0auXDY0TRlASuaZ6I40Is -+uRUOgqWYj2uAaHuWYdZeB4LdO3cnX0TISFDAWom6JKNlnmbrCtR4fSDT13kCQQCU -++VQJyV3F5MDHsWbLt6eNR46AV5lpk/vatPXPlrZ/zwPs+PmRmGLICvNiDA2DdNDP -+wCx2Zjsj67CtY3rNitMJAkEAm09BQnjnbBXUb1rd2SjNDWTsu80Z+zLu8pAwXNhW -+8nsvMYqlYMIxuMPwu/QuTnMRhMZ08uhqoD3ukZnBeoMEVg== -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/encr.txt b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/encr.txt -new file mode 100644 -index 0000000..f163a32 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/encr.txt -@@ -0,0 +1,3 @@ -+Content-type: text/plain -+ -+Sample OpenSSL Data for PKCS#7 encryption -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/sign.txt b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/sign.txt -new file mode 100644 -index 0000000..af1341d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/sign.txt -@@ -0,0 +1,3 @@ -+Content-type: text/plain -+ -+Test OpenSSL Signed Content -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/signer.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/signer.pem -new file mode 100644 -index 0000000..bac16ba ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/signer.pem -@@ -0,0 +1,32 @@ -+-----BEGIN CERTIFICATE----- -+MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRhMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV -+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv -+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTI3 -+WhcNMTcwNDA5MTgyOTI3WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT -+TCB0ZXN0IFMvTUlNRSBzaWduZXIgMTEgMB4GCSqGSIb3DQEJARYRdGVzdDFAb3Bl -+bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL1ocAQ7ON2pIUXz -+jwKPzpPB9ozB6PFG6F6kARO+i0DiT6Qn8abUjwpHPU+lGys83QlpbkQVUD6Fv/4L -+ytihk6N9Pr/feECVcSZ20dI43WXjfYak14dSVrZkGNMMXqKmnnqtkAdD0oJN7A7y -+gcf8RuViV0kvk9/36eCMwMHrImfhAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI -+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW -+BBSyKqjvctIsFNBHULBTqr8SHtSxpDAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7 -+2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBvdYVoBfd4RV/xWSMXIcgw/i5OiwyX -+MsenQePll51MpglfArd7pUipUalCqlJt/Gs8kD16Ih1z1yuWYVTMlnDZ0PwbIOYn -++Jr8XLF9b1SMJt6PwckZZ0LZdIi2KwGAxVsIW1kjJAqu9o4YH37XW37yYdQRxfvv -+lDiQlgX0JtmLgA== -+-----END CERTIFICATE----- -+-----BEGIN RSA PRIVATE KEY----- -+MIICXAIBAAKBgQC9aHAEOzjdqSFF848Cj86TwfaMwejxRuhepAETvotA4k+kJ/Gm -+1I8KRz1PpRsrPN0JaW5EFVA+hb/+C8rYoZOjfT6/33hAlXEmdtHSON1l432GpNeH -+Ula2ZBjTDF6ipp56rZAHQ9KCTewO8oHH/EblYldJL5Pf9+ngjMDB6yJn4QIDAQAB -+AoGACCuYIWaYll80UzslYRvo8lC8nOfEb5v6bBKxBTQD98GLY+5hKywiG3RlPalG -+mb/fXQeSPReaRYgpdwD1OBEIOEMW9kLyqpzokC0xjpZ+MwsuJTlxCesk5GEsMa3o -+wC3QMmiRA7qrZ/SzTtwrs++9mZ/pxp8JZ6pKYUj8SE7/vV0CQQDz8Ix2t40E16hx -+04+XhClnGqydZJyLLSxcTU3ZVhYxL+efo/5hZ8tKpkcDi8wq6T03BOKrKxrlIW55 -+qDRNM24rAkEAxsWzu/rJhIouQyNoYygEIEYzFRlTQyZSg59u6dNiewMn27dOAbyc -+YT7B6da7e74QttTXo0lIllsX2S38+XsIIwJBANSRuIU3G66tkr5l4gnhhAaxqtuY -+sgVhvvdL8dvC9aG1Ifzt9hzBSthpHxbK+oYmK07HdhI8hLpIMLHYzoK7n3MCQEy4 -+4rccBcxyyYiAkjozp+QNNIpgTBMPJ6pGT7lRLiHtBeV4y1NASdv/LTnk+Fi69Bid -+7t3H24ytfHcHmS1yn6ECQF6Jmh4C7dlvp59zXp+t+VsXxa/8sq41vKNIj0Rx9vh5 -+xp9XL0C5ZpgmBnsTydP9pmkiL4ltLbMX0wJU6N2cmFw= -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/signer2.pem b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/signer2.pem -new file mode 100644 -index 0000000..25e23d1 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/signer2.pem -@@ -0,0 +1,32 @@ -+-----BEGIN CERTIFICATE----- -+MIICpjCCAg+gAwIBAgIJAJ+rfmEoLQRiMA0GCSqGSIb3DQEBBAUAMFcxCzAJBgNV -+BAYTAlVLMRIwEAYDVQQHEwlUZXN0IENpdHkxFjAUBgNVBAoTDU9wZW5TU0wgR3Jv -+dXAxHDAaBgNVBAMTE1Rlc3QgUy9NSU1FIFJvb3QgQ0EwHhcNMDcwNDEzMTgyOTQ0 -+WhcNMTcwNDA5MTgyOTQ0WjBWMQswCQYDVQQGEwJVSzElMCMGA1UEAxMcT3BlblNT -+TCB0ZXN0IFMvTUlNRSBzaWduZXIgMjEgMB4GCSqGSIb3DQEJARYRdGVzdDJAb3Bl -+bnNzbC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANco7VPgX9vcGwmZ -+jYqjq1JiR7M38dsMNhuJyLRVjJ5/cpFluQydQuG1PhzOJ8zfYVFicOXKvbYuKuXW -+ozZIwzqEqWsNf36KHTLS6yOMG8I13cRInh+fAIKq9Z8Eh65I7FJzVsNsfEQrGfEW -+GMA8us24IaSvP3QkbfHJn/4RaKznAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI -+AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW -+BBRlrLQJUB8uAa4q8B2OqvvTXonF5zAfBgNVHSMEGDAWgBRHUypxCXFQYqewhGo7 -+2lWPQUsjoDANBgkqhkiG9w0BAQQFAAOBgQBQbi2juGALg2k9m1hKpzR2lCGmGO3X -+h3Jh/l0vIxDr0RTgP2vBrtITlx655P/o1snoeTIpYG8uUnFnTE/6YakdayAIlxV4 -+aZl63AivZMpQB5SPaPH/jEsGJ8UQMfdiy4ORWIULupuPKlKwODNw7tVhQIACS/DR -+2aX6rl2JEuJ5Yg== -+-----END CERTIFICATE----- -+-----BEGIN RSA PRIVATE KEY----- -+MIICXAIBAAKBgQDXKO1T4F/b3BsJmY2Ko6tSYkezN/HbDDYbici0VYyef3KRZbkM -+nULhtT4czifM32FRYnDlyr22Lirl1qM2SMM6hKlrDX9+ih0y0usjjBvCNd3ESJ4f -+nwCCqvWfBIeuSOxSc1bDbHxEKxnxFhjAPLrNuCGkrz90JG3xyZ/+EWis5wIDAQAB -+AoGAUTB2bcIrKfGimjrBOGGOUmYXnD8uGnQ/LqENhU8K4vxApTD3ZRUqmbUknQYF -+6r8YH/e/llasw8QkF9qod+F5GTgsnyh/aMidFHKrXXbf1662scz9+S6crSXq9Eb2 -+CL57f6Kw61k6edrz8zHdA+rnTK00hzgzKCP4ZL5k8/55ueECQQD+BK+nsKi6CcKf -+m3Mh61Sf2Icm5JlMCKaihlbnh78lBN1imYUAfHJEnQ1ujxXB94R+6o9S+XrWTnTX -+2m/JNIfpAkEA2NaidX7Sv5jnRPkwJ02Srl0urxINLmg4bU0zmM3VoMklYBHWnMyr -+upPZGPh5TzCa+g6FTBmU8XK61wvnEKNcTwJBAM24VdnlBIDGbsx8RJ3vzLU30xz4 -+ff5J80okqjUQhwkgC3tTAZgHMTPITZyAXQqdvrxakoCMc6MkHxTBX08AMCECQHHL -+SdyxXrYv7waSY0PtANJCkpJLveEhzqMFxdMmCjtj9BpTojYNbv3uQxtIopj9YAdk -+gW2ray++zvC2DV/86x8CQH4UJwgO6JqU4bSgi6HiRNjDg26tJ0Beu8jjl1vrkIVX -+pHFwSUeLZUsT2/iTUSgYH4uYiZPgYNcKTCT9W6se30A= -+-----END RSA PRIVATE KEY----- -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smdec.c b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smdec.c -new file mode 100644 -index 0000000..c4d1b09 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smdec.c -@@ -0,0 +1,78 @@ -+/* -+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Simple S/MIME signing example */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL; -+ X509 *rcert = NULL; -+ EVP_PKEY *rkey = NULL; -+ PKCS7 *p7 = NULL; -+ int ret = 1; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Read in recipient certificate and private key */ -+ tbio = BIO_new_file("signer.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ BIO_reset(tbio); -+ -+ rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); -+ -+ if (!rcert || !rkey) -+ goto err; -+ -+ /* Open content being signed */ -+ -+ in = BIO_new_file("smencr.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* Sign content */ -+ p7 = SMIME_read_PKCS7(in, NULL); -+ -+ if (!p7) -+ goto err; -+ -+ out = BIO_new_file("encrout.txt", "w"); -+ if (!out) -+ goto err; -+ -+ /* Decrypt S/MIME message */ -+ if (!PKCS7_decrypt(p7, rkey, rcert, out, 0)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ if (ret) { -+ fprintf(stderr, "Error Signing Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ PKCS7_free(p7); -+ X509_free(rcert); -+ EVP_PKEY_free(rkey); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ -+ return ret; -+ -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smenc.c b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smenc.c -new file mode 100644 -index 0000000..5d36e9a ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smenc.c -@@ -0,0 +1,91 @@ -+/* -+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Simple S/MIME encrypt example */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL; -+ X509 *rcert = NULL; -+ STACK_OF(X509) *recips = NULL; -+ PKCS7 *p7 = NULL; -+ int ret = 1; -+ -+ /* -+ * On OpenSSL 0.9.9 only: -+ * for streaming set PKCS7_STREAM -+ */ -+ int flags = PKCS7_STREAM; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Read in recipient certificate */ -+ tbio = BIO_new_file("signer.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ if (!rcert) -+ goto err; -+ -+ /* Create recipient STACK and add recipient cert to it */ -+ recips = sk_X509_new_null(); -+ -+ if (!recips || !sk_X509_push(recips, rcert)) -+ goto err; -+ -+ /* -+ * sk_X509_pop_free will free up recipient STACK and its contents so set -+ * rcert to NULL so it isn't freed up twice. -+ */ -+ rcert = NULL; -+ -+ /* Open content being encrypted */ -+ -+ in = BIO_new_file("encr.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* encrypt content */ -+ p7 = PKCS7_encrypt(recips, in, EVP_des_ede3_cbc(), flags); -+ -+ if (!p7) -+ goto err; -+ -+ out = BIO_new_file("smencr.txt", "w"); -+ if (!out) -+ goto err; -+ -+ /* Write out S/MIME message */ -+ if (!SMIME_write_PKCS7(out, p7, in, flags)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ if (ret) { -+ fprintf(stderr, "Error Encrypting Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ PKCS7_free(p7); -+ X509_free(rcert); -+ sk_X509_pop_free(recips, X509_free); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ return ret; -+ -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smsign.c b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smsign.c -new file mode 100644 -index 0000000..ba0adb3 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smsign.c -@@ -0,0 +1,88 @@ -+/* -+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Simple S/MIME signing example */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL; -+ X509 *scert = NULL; -+ EVP_PKEY *skey = NULL; -+ PKCS7 *p7 = NULL; -+ int ret = 1; -+ -+ /* -+ * For simple S/MIME signing use PKCS7_DETACHED. On OpenSSL 0.9.9 only: -+ * for streaming detached set PKCS7_DETACHED|PKCS7_STREAM for streaming -+ * non-detached set PKCS7_STREAM -+ */ -+ int flags = PKCS7_DETACHED | PKCS7_STREAM; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Read in signer certificate and private key */ -+ tbio = BIO_new_file("signer.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ scert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ BIO_reset(tbio); -+ -+ skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); -+ -+ if (!scert || !skey) -+ goto err; -+ -+ /* Open content being signed */ -+ -+ in = BIO_new_file("sign.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* Sign content */ -+ p7 = PKCS7_sign(scert, skey, NULL, in, flags); -+ -+ if (!p7) -+ goto err; -+ -+ out = BIO_new_file("smout.txt", "w"); -+ if (!out) -+ goto err; -+ -+ if (!(flags & PKCS7_STREAM)) -+ BIO_reset(in); -+ -+ /* Write out S/MIME message */ -+ if (!SMIME_write_PKCS7(out, p7, in, flags)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ if (ret) { -+ fprintf(stderr, "Error Signing Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ PKCS7_free(p7); -+ X509_free(scert); -+ EVP_PKEY_free(skey); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ -+ return ret; -+ -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smsign2.c b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smsign2.c -new file mode 100644 -index 0000000..2b7f45b ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smsign2.c -@@ -0,0 +1,96 @@ -+/* -+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* S/MIME signing example: 2 signers. OpenSSL 0.9.9 only */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL; -+ X509 *scert = NULL, *scert2 = NULL; -+ EVP_PKEY *skey = NULL, *skey2 = NULL; -+ PKCS7 *p7 = NULL; -+ int ret = 1; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ tbio = BIO_new_file("signer.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ scert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ BIO_reset(tbio); -+ -+ skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); -+ -+ BIO_free(tbio); -+ -+ tbio = BIO_new_file("signer2.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ scert2 = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ BIO_reset(tbio); -+ -+ skey2 = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); -+ -+ if (!scert2 || !skey2) -+ goto err; -+ -+ in = BIO_new_file("sign.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ p7 = PKCS7_sign(NULL, NULL, NULL, in, PKCS7_STREAM | PKCS7_PARTIAL); -+ -+ if (!p7) -+ goto err; -+ -+ /* Add each signer in turn */ -+ -+ if (!PKCS7_sign_add_signer(p7, scert, skey, NULL, 0)) -+ goto err; -+ -+ if (!PKCS7_sign_add_signer(p7, scert2, skey2, NULL, 0)) -+ goto err; -+ -+ out = BIO_new_file("smout.txt", "w"); -+ if (!out) -+ goto err; -+ -+ /* NB: content included and finalized by SMIME_write_PKCS7 */ -+ -+ if (!SMIME_write_PKCS7(out, p7, in, PKCS7_STREAM)) -+ goto err; -+ -+ ret = 0; -+ -+ err: -+ if (ret) { -+ fprintf(stderr, "Error Signing Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ PKCS7_free(p7); -+ X509_free(scert); -+ EVP_PKEY_free(skey); -+ X509_free(scert2); -+ EVP_PKEY_free(skey2); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smver.c b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smver.c -new file mode 100644 -index 0000000..75411c4 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/demos/smime/smver.c -@@ -0,0 +1,83 @@ -+/* -+ * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+/* Simple S/MIME verification example */ -+#include -+#include -+#include -+ -+int main(int argc, char **argv) -+{ -+ BIO *in = NULL, *out = NULL, *tbio = NULL, *cont = NULL; -+ X509_STORE *st = NULL; -+ X509 *cacert = NULL; -+ PKCS7 *p7 = NULL; -+ -+ int ret = 1; -+ -+ OpenSSL_add_all_algorithms(); -+ ERR_load_crypto_strings(); -+ -+ /* Set up trusted CA certificate store */ -+ -+ st = X509_STORE_new(); -+ -+ /* Read in signer certificate and private key */ -+ tbio = BIO_new_file("cacert.pem", "r"); -+ -+ if (!tbio) -+ goto err; -+ -+ cacert = PEM_read_bio_X509(tbio, NULL, 0, NULL); -+ -+ if (!cacert) -+ goto err; -+ -+ if (!X509_STORE_add_cert(st, cacert)) -+ goto err; -+ -+ /* Open content being signed */ -+ -+ in = BIO_new_file("smout.txt", "r"); -+ -+ if (!in) -+ goto err; -+ -+ /* Sign content */ -+ p7 = SMIME_read_PKCS7(in, &cont); -+ -+ if (!p7) -+ goto err; -+ -+ /* File to output verified content to */ -+ out = BIO_new_file("smver.txt", "w"); -+ if (!out) -+ goto err; -+ -+ if (!PKCS7_verify(p7, NULL, st, cont, out, 0)) { -+ fprintf(stderr, "Verification Failure\n"); -+ goto err; -+ } -+ -+ fprintf(stderr, "Verification Successful\n"); -+ -+ ret = 0; -+ -+ err: -+ if (ret) { -+ fprintf(stderr, "Error Verifying Data\n"); -+ ERR_print_errors_fp(stderr); -+ } -+ PKCS7_free(p7); -+ X509_free(cacert); -+ BIO_free(in); -+ BIO_free(out); -+ BIO_free(tbio); -+ return ret; -+} -diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/CT_POLICY_EVAL_CTX_new.pod b/CryptoPkg/Library/OpensslLib/openssl/doc/CT_POLICY_EVAL_CTX_new.pod -new file mode 100644 -index 0000000..fedc58d ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/doc/CT_POLICY_EVAL_CTX_new.pod -@@ -0,0 +1,111 @@ -+=pod -+ -+=head1 NAME -+ -+CT_POLICY_EVAL_CTX_new, CT_POLICY_EVAL_CTX_free, -+CT_POLICY_EVAL_CTX_get0_cert, CT_POLICY_EVAL_CTX_set1_cert, -+CT_POLICY_EVAL_CTX_get0_issuer, CT_POLICY_EVAL_CTX_set1_issuer, -+CT_POLICY_EVAL_CTX_get0_log_store, CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE, -+CT_POLICY_EVAL_CTX_get_time, CT_POLICY_EVAL_CTX_set_time - -+Encapsulates the data required to evaluate whether SCTs meet a Certificate Transparency policy -+ -+=head1 SYNOPSIS -+ -+ #include -+ -+ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void); -+ void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx); -+ X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx); -+ int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert); -+ X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx); -+ int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer); -+ const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx); -+ void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx, CTLOG_STORE *log_store); -+ uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx); -+ void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms); -+ -+=head1 DESCRIPTION -+ -+A B is used by functions that evaluate whether Signed -+Certificate Timestamps (SCTs) fulfil a Certificate Transparency (CT) policy. -+This policy may be, for example, that at least one valid SCT is available. To -+determine this, an SCT's timestamp and signature must be verified. -+This requires: -+ -+=over -+ -+=item * the public key of the log that issued the SCT -+ -+=item * the certificate that the SCT was issued for -+ -+=item * the issuer certificate (if the SCT was issued for a pre-certificate) -+ -+=item * the current time -+ -+=back -+ -+The above requirements are met using the setters described below. -+ -+CT_POLICY_EVAL_CTX_new() creates an empty policy evaluation context. This -+should then be populated using: -+ -+=over -+ -+=item * CT_POLICY_EVAL_CTX_set1_cert() to provide the certificate the SCTs were issued for -+ -+Increments the reference count of the certificate. -+ -+=item * CT_POLICY_EVAL_CTX_set1_issuer() to provide the issuer certificate -+ -+Increments the reference count of the certificate. -+ -+=item * CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE() to provide a list of logs that are trusted as sources of SCTs -+ -+Holds a pointer to the CTLOG_STORE, so the CTLOG_STORE must outlive the -+CT_POLICY_EVAL_CTX. -+ -+=item * CT_POLICY_EVAL_CTX_set_time() to set the time SCTs should be compared with to determine if they are valid -+ -+The SCT timestamp will be compared to this time to check whether the SCT was -+issued in the future. RFC6962 states that "TLS clients MUST reject SCTs whose -+timestamp is in the future". By default, this will be set to 5 minutes in the -+future (e.g. (time() + 300) * 1000), to allow for clock drift. -+ -+The time should be in milliseconds since the Unix epoch. -+ -+=back -+ -+Each setter has a matching getter for accessing the current value. -+ -+When no longer required, the B should be passed to -+CT_POLICY_EVAL_CTX_free() to delete it. -+ -+=head1 NOTES -+ -+The issuer certificate only needs to be provided if at least one of the SCTs -+was issued for a pre-certificate. This will be the case for SCTs embedded in a -+certificate (i.e. those in an X.509 extension), but may not be the case for SCTs -+found in the TLS SCT extension or OCSP response. -+ -+=head1 RETURN VALUES -+ -+CT_POLICY_EVAL_CTX_new() will return NULL if malloc fails. -+ -+=head1 SEE ALSO -+ -+L -+ -+=head1 HISTORY -+ -+These functions were added in OpenSSL 1.1.0. -+ -+=head1 COPYRIGHT -+ -+Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. -+ -+Licensed under the OpenSSL license (the "License"). You may not use -+this file except in compliance with the License. You can obtain a copy -+in the file LICENSE in the source distribution or at -+L. -+ -+=cut -diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/certificates.txt b/CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/certificates.txt -new file mode 100644 -index 0000000..65f8fc8 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/certificates.txt -@@ -0,0 +1,110 @@ -+ -+ HOWTO certificates -+ -+1. Introduction -+ -+How you handle certificates depends a great deal on what your role is. -+Your role can be one or several of: -+ -+ - User of some client application -+ - User of some server application -+ - Certificate authority -+ -+This file is for users who wish to get a certificate of their own. -+Certificate authorities should read https://www.openssl.org/docs/apps/ca.html. -+ -+In all the cases shown below, the standard configuration file, as -+compiled into openssl, will be used. You may find it in /etc/, -+/usr/local/ssl/ or somewhere else. By default the file is named -+openssl.cnf and is described at https://www.openssl.org/docs/apps/config.html. -+You can specify a different configuration file using the -+'-config {file}' argument with the commands shown below. -+ -+ -+2. Relationship with keys -+ -+Certificates are related to public key cryptography by containing a -+public key. To be useful, there must be a corresponding private key -+somewhere. With OpenSSL, public keys are easily derived from private -+keys, so before you create a certificate or a certificate request, you -+need to create a private key. -+ -+Private keys are generated with 'openssl genrsa -out privkey.pem' if -+you want a RSA private key, or if you want a DSA private key: -+'openssl dsaparam -out dsaparam.pem 2048; openssl gendsa -out privkey.pem dsaparam.pem'. -+ -+The private keys created by these commands are not passphrase protected; -+it might or might not be the desirable thing. Further information on how to -+create private keys can be found at https://www.openssl.org/docs/HOWTO/keys.txt. -+The rest of this text assumes you have a private key in the file privkey.pem. -+ -+ -+3. Creating a certificate request -+ -+To create a certificate, you need to start with a certificate request -+(or, as some certificate authorities like to put it, "certificate -+signing request", since that's exactly what they do, they sign it and -+give you the result back, thus making it authentic according to their -+policies). A certificate request is sent to a certificate authority -+to get it signed into a certificate. You can also sign the certificate -+yourself if you have your own certificate authority or create a -+self-signed certificate (typically for testing purpose). -+ -+The certificate request is created like this: -+ -+ openssl req -new -key privkey.pem -out cert.csr -+ -+Now, cert.csr can be sent to the certificate authority, if they can -+handle files in PEM format. If not, use the extra argument '-outform' -+followed by the keyword for the format to use (see another HOWTO -+). In some cases, -outform does not let you output the -+certificate request in the right format and you will have to use one -+of the various other commands that are exposed by openssl (or get -+creative and use a combination of tools). -+ -+The certificate authority performs various checks (according to their -+policies) and usually waits for payment from you. Once that is -+complete, they send you your new certificate. -+ -+Section 5 will tell you more on how to handle the certificate you -+received. -+ -+ -+4. Creating a self-signed test certificate -+ -+You can create a self-signed certificate if you don't want to deal -+with a certificate authority, or if you just want to create a test -+certificate for yourself. This is similar to creating a certificate -+request, but creates a certificate instead of a certificate request. -+This is NOT the recommended way to create a CA certificate, see -+https://www.openssl.org/docs/apps/ca.html. -+ -+ openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 -+ -+ -+5. What to do with the certificate -+ -+If you created everything yourself, or if the certificate authority -+was kind enough, your certificate is a raw DER thing in PEM format. -+Your key most definitely is if you have followed the examples above. -+However, some (most?) certificate authorities will encode them with -+things like PKCS7 or PKCS12, or something else. Depending on your -+applications, this may be perfectly OK, it all depends on what they -+know how to decode. If not, There are a number of OpenSSL tools to -+convert between some (most?) formats. -+ -+So, depending on your application, you may have to convert your -+certificate and your key to various formats, most often also putting -+them together into one file. The ways to do this is described in -+another HOWTO , I will just mention the simplest case. -+In the case of a raw DER thing in PEM format, and assuming that's all -+right for your applications, simply concatenating the certificate and -+the key into a new file and using that one should be enough. With -+some applications, you don't even have to do that. -+ -+ -+By now, you have your certificate and your private key and can start -+using applications that depend on it. -+ -+-- -+Richard Levitte -diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/keys.txt b/CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/keys.txt -new file mode 100644 -index 0000000..ba0314f ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/keys.txt -@@ -0,0 +1,72 @@ -+ -+ HOWTO keys -+ -+1. Introduction -+ -+Keys are the basis of public key algorithms and PKI. Keys usually -+come in pairs, with one half being the public key and the other half -+being the private key. With OpenSSL, the private key contains the -+public key information as well, so a public key doesn't need to be -+generated separately. -+ -+Public keys come in several flavors, using different cryptographic -+algorithms. The most popular ones associated with certificates are -+RSA and DSA, and this HOWTO will show how to generate each of them. -+ -+ -+2. To generate a RSA key -+ -+A RSA key can be used both for encryption and for signing. -+ -+Generating a key for the RSA algorithm is quite easy, all you have to -+do is the following: -+ -+ openssl genrsa -des3 -out privkey.pem 2048 -+ -+With this variant, you will be prompted for a protecting password. If -+you don't want your key to be protected by a password, remove the flag -+'-des3' from the command line above. -+ -+ NOTE: if you intend to use the key together with a server -+ certificate, it may be a good thing to avoid protecting it -+ with a password, since that would mean someone would have to -+ type in the password every time the server needs to access -+ the key. -+ -+The number 2048 is the size of the key, in bits. Today, 2048 or -+higher is recommended for RSA keys, as fewer amount of bits is -+consider insecure or to be insecure pretty soon. -+ -+ -+3. To generate a DSA key -+ -+A DSA key can be used for signing only. It is important to -+know what a certificate request with a DSA key can really be used for. -+ -+Generating a key for the DSA algorithm is a two-step process. First, -+you have to generate parameters from which to generate the key: -+ -+ openssl dsaparam -out dsaparam.pem 2048 -+ -+The number 2048 is the size of the key, in bits. Today, 2048 or -+higher is recommended for DSA keys, as fewer amount of bits is -+consider insecure or to be insecure pretty soon. -+ -+When that is done, you can generate a key using the parameters in -+question (actually, several keys can be generated from the same -+parameters): -+ -+ openssl gendsa -des3 -out privkey.pem dsaparam.pem -+ -+With this variant, you will be prompted for a protecting password. If -+you don't want your key to be protected by a password, remove the flag -+'-des3' from the command line above. -+ -+ NOTE: if you intend to use the key together with a server -+ certificate, it may be a good thing to avoid protecting it -+ with a password, since that would mean someone would have to -+ type in the password every time the server needs to access -+ the key. -+ -+-- -+Richard Levitte -diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/proxy_certificates.txt b/CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/proxy_certificates.txt -new file mode 100644 -index 0000000..642bec9 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/doc/HOWTO/proxy_certificates.txt -@@ -0,0 +1,319 @@ -+ HOWTO proxy certificates -+ -+0. WARNING -+ -+NONE OF THE CODE PRESENTED HERE HAS BEEN CHECKED! The code is just examples to -+show you how things could be done. There might be typos or type conflicts, and -+you will have to resolve them. -+ -+1. Introduction -+ -+Proxy certificates are defined in RFC 3820. They are really usual certificates -+with the mandatory extension proxyCertInfo. -+ -+Proxy certificates are issued by an End Entity (typically a user), either -+directly with the EE certificate as issuing certificate, or by extension through -+an already issued proxy certificate. Proxy certificates are used to extend -+rights to some other entity (a computer process, typically, or sometimes to the -+user itself). This allows the entity to perform operations on behalf of the -+owner of the EE certificate. -+ -+See http://www.ietf.org/rfc/rfc3820.txt for more information. -+ -+ -+2. A warning about proxy certificates -+ -+No one seems to have tested proxy certificates with security in mind. To this -+date, it seems that proxy certificates have only been used in a context highly -+aware of them. -+ -+Existing applications might misbehave when trying to validate a chain of -+certificates which use a proxy certificate. They might incorrectly consider the -+leaf to be the certificate to check for authorisation data, which is controlled -+by the EE certificate owner. -+ -+subjectAltName and issuerAltName are forbidden in proxy certificates, and this -+is enforced in OpenSSL. The subject must be the same as the issuer, with one -+commonName added on. -+ -+Possible threats we can think of at this time include: -+ -+ - impersonation through commonName (think server certificates). -+ - use of additional extensions, possibly non-standard ones used in certain -+ environments, that would grant extra or different authorisation rights. -+ -+For these reasons, OpenSSL requires that the use of proxy certificates be -+explicitly allowed. Currently, this can be done using the following methods: -+ -+ - if the application directly calls X509_verify_cert(), it can first call: -+ -+ X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); -+ -+ Where ctx is the pointer which then gets passed to X509_verify_cert(). -+ -+ - proxy certificate validation can be enabled before starting the application -+ by setting the environment variable OPENSSL_ALLOW_PROXY_CERTS. -+ -+In the future, it might be possible to enable proxy certificates by editing -+openssl.cnf. -+ -+ -+3. How to create proxy certificates -+ -+Creating proxy certificates is quite easy, by taking advantage of a lack of -+checks in the 'openssl x509' application (*ahem*). You must first create a -+configuration section that contains a definition of the proxyCertInfo extension, -+for example: -+ -+ [ v3_proxy ] -+ # A proxy certificate MUST NEVER be a CA certificate. -+ basicConstraints=CA:FALSE -+ -+ # Usual authority key ID -+ authorityKeyIdentifier=keyid,issuer:always -+ -+ # The extension which marks this certificate as a proxy -+ proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB -+ -+It's also possible to specify the proxy extension in a separate section: -+ -+ proxyCertInfo=critical,@proxy_ext -+ -+ [ proxy_ext ] -+ language=id-ppl-anyLanguage -+ pathlen=0 -+ policy=text:BC -+ -+The policy value has a specific syntax, {syntag}:{string}, where the syntag -+determines what will be done with the string. The following syntags are -+recognised: -+ -+ text indicates that the string is simply bytes, without any encoding: -+ -+ policy=text:räksmörgås -+ -+ Previous versions of this design had a specific tag for UTF-8 text. -+ However, since the bytes are copied as-is anyway, there is no need for -+ such a specific tag. -+ -+ hex indicates the string is encoded in hex, with colons between each byte -+ (every second hex digit): -+ -+ policy=hex:72:E4:6B:73:6D:F6:72:67:E5:73 -+ -+ Previous versions of this design had a tag to insert a complete DER -+ blob. However, the only legal use for this would be to surround the -+ bytes that would go with the hex: tag with whatever is needed to -+ construct a correct OCTET STRING. The DER tag therefore felt -+ superfluous, and was removed. -+ -+ file indicates that the text of the policy should really be taken from a -+ file. The string is then really a file name. This is useful for -+ policies that are large (more than a few lines, e.g. XML documents). -+ -+The 'policy' setting can be split up in multiple lines like this: -+ -+ 0.policy=This is -+ 1.policy= a multi- -+ 2.policy=line policy. -+ -+NOTE: the proxy policy value is the part which determines the rights granted to -+the process using the proxy certificate. The value is completely dependent on -+the application reading and interpreting it! -+ -+Now that you have created an extension section for your proxy certificate, you -+can easily create a proxy certificate by doing: -+ -+ openssl req -new -config openssl.cnf -out proxy.req -keyout proxy.key -+ openssl x509 -req -CAcreateserial -in proxy.req -days 7 -out proxy.crt \ -+ -CA user.crt -CAkey user.key -extfile openssl.cnf -extensions v3_proxy -+ -+You can also create a proxy certificate using another proxy certificate as -+issuer (note: I'm using a different configuration section for it): -+ -+ openssl req -new -config openssl.cnf -out proxy2.req -keyout proxy2.key -+ openssl x509 -req -CAcreateserial -in proxy2.req -days 7 -out proxy2.crt \ -+ -CA proxy.crt -CAkey proxy.key -extfile openssl.cnf -extensions v3_proxy2 -+ -+ -+4. How to have your application interpret the policy? -+ -+The basic way to interpret proxy policies is to start with some default rights, -+then compute the resulting rights by checking the proxy certificate against -+the chain of proxy certificates, user certificate and CA certificates. You then -+use the final computed rights. Sounds easy, huh? It almost is. -+ -+The slightly complicated part is figuring out how to pass data between your -+application and the certificate validation procedure. -+ -+You need the following ingredients: -+ -+ - a callback function that will be called for every certificate being -+ validated. The callback be called several times for each certificate, -+ so you must be careful to do the proxy policy interpretation at the right -+ time. You also need to fill in the defaults when the EE certificate is -+ checked. -+ -+ - a data structure that is shared between your application code and the -+ callback. -+ -+ - a wrapper function that sets it all up. -+ -+ - an ex_data index function that creates an index into the generic ex_data -+ store that is attached to an X509 validation context. -+ -+Here is some skeleton code you can fill in: -+ -+ #include -+ #include -+ #include -+ #include -+ -+ #define total_rights 25 -+ -+ /* -+ * In this example, I will use a view of granted rights as a bit -+ * array, one bit for each possible right. -+ */ -+ typedef struct your_rights { -+ unsigned char rights[(total_rights + 7) / 8]; -+ } YOUR_RIGHTS; -+ -+ /* -+ * The following procedure will create an index for the ex_data -+ * store in the X509 validation context the first time it's called. -+ * Subsequent calls will return the same index. */ -+ static int get_proxy_auth_ex_data_idx(X509_STORE_CTX *ctx) -+ { -+ static volatile int idx = -1; -+ if (idx < 0) { -+ X509_STORE_lock(X509_STORE_CTX_get0_store(ctx)); -+ if (idx < 0) { -+ idx = X509_STORE_CTX_get_ex_new_index(0, -+ "for verify callback", -+ NULL,NULL,NULL); -+ } -+ X509_STORE_unlock(X509_STORE_CTX_get0_store(ctx)); -+ } -+ return idx; -+ } -+ -+ /* Callback to be given to the X509 validation procedure. */ -+ static int verify_callback(int ok, X509_STORE_CTX *ctx) -+ { -+ if (ok == 1) { -+ /* -+ * It's REALLY important you keep the proxy policy -+ * check within this section. It's important to know -+ * that when ok is 1, the certificates are checked -+ * from top to bottom. You get the CA root first, -+ * followed by the possible chain of intermediate -+ * CAs, followed by the EE certificate, followed by -+ * the possible proxy certificates. -+ */ -+ X509 *xs = X509_STORE_CTX_get_current_cert(ctx); -+ -+ if (X509_get_extension_flags(xs) & EXFLAG_PROXY) { -+ YOUR_RIGHTS *rights = -+ (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx, -+ get_proxy_auth_ex_data_idx(ctx)); -+ PROXY_CERT_INFO_EXTENSION *pci = -+ X509_get_ext_d2i(xs, NID_proxyCertInfo, NULL, NULL); -+ -+ switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) { -+ case NID_Independent: -+ /* -+ * Do whatever you need to grant explicit rights to -+ * this particular proxy certificate, usually by -+ * pulling them from some database. If there are none -+ * to be found, clear all rights (making this and any -+ * subsequent proxy certificate void of any rights). -+ */ -+ memset(rights->rights, 0, sizeof(rights->rights)); -+ break; -+ case NID_id_ppl_inheritAll: -+ /* -+ * This is basically a NOP, we simply let the current -+ * rights stand as they are. -+ */ -+ break; -+ default: -+ /* This is usually the most complex section of code. -+ * You really do whatever you want as long as you -+ * follow RFC 3820. In the example we use here, the -+ * simplest thing to do is to build another, temporary -+ * bit array and fill it with the rights granted by -+ * the current proxy certificate, then use it as a -+ * mask on the accumulated rights bit array, and -+ * voilà, you now have a new accumulated rights bit -+ * array. -+ */ -+ { -+ int i; -+ YOUR_RIGHTS tmp_rights; -+ memset(tmp_rights.rights, 0, sizeof(tmp_rights.rights)); -+ -+ /* -+ * process_rights() is supposed to be a procedure -+ * that takes a string and it's length, interprets -+ * it and sets the bits in the YOUR_RIGHTS pointed -+ * at by the third argument. -+ */ -+ process_rights((char *) pci->proxyPolicy->policy->data, -+ pci->proxyPolicy->policy->length, -+ &tmp_rights); -+ -+ for(i = 0; i < total_rights / 8; i++) -+ rights->rights[i] &= tmp_rights.rights[i]; -+ } -+ break; -+ } -+ PROXY_CERT_INFO_EXTENSION_free(pci); -+ } else if (!(X509_get_extension_flags(xs) & EXFLAG_CA)) { -+ /* We have an EE certificate, let's use it to set default! */ -+ YOUR_RIGHTS *rights = -+ (YOUR_RIGHTS *)X509_STORE_CTX_get_ex_data(ctx, -+ get_proxy_auth_ex_data_idx(ctx)); -+ -+ /* The following procedure finds out what rights the owner -+ * of the current certificate has, and sets them in the -+ * YOUR_RIGHTS structure pointed at by the second -+ * argument. -+ */ -+ set_default_rights(xs, rights); -+ } -+ } -+ return ok; -+ } -+ -+ static int my_X509_verify_cert(X509_STORE_CTX *ctx, -+ YOUR_RIGHTS *needed_rights) -+ { -+ int ok; -+ int (*save_verify_cb)(int ok,X509_STORE_CTX *ctx) = -+ X509_STORE_CTX_get_verify_cb(ctx); -+ YOUR_RIGHTS rights; -+ -+ X509_STORE_CTX_set_verify_cb(ctx, verify_callback); -+ X509_STORE_CTX_set_ex_data(ctx, get_proxy_auth_ex_data_idx(ctx), &rights); -+ X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); -+ ok = X509_verify_cert(ctx); -+ -+ if (ok == 1) { -+ ok = check_needed_rights(rights, needed_rights); -+ } -+ -+ X509_STORE_CTX_set_verify_cb(ctx, save_verify_cb); -+ -+ return ok; -+ } -+ -+ -+If you use SSL or TLS, you can easily set up a callback to have the -+certificates checked properly, using the code above: -+ -+ SSL_CTX_set_cert_verify_callback(s_ctx, my_X509_verify_cert, &needed_rights); -+ -+ -+-- -+Richard Levitte -diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/README b/CryptoPkg/Library/OpensslLib/openssl/doc/README -new file mode 100644 -index 0000000..5931290 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/doc/README -@@ -0,0 +1,20 @@ -+ -+README This file -+ -+fingerprints.txt -+ PGP fingerprints of authoried release signers -+ -+standards.txt -+ Moved to the web, https://www.openssl.org/docs/standards.html -+ -+HOWTO/ -+ A few how-to documents; not necessarily up-to-date -+apps/ -+ The openssl command-line tools; start with openssl.pod -+ssl/ -+ The SSL library; start with ssl.pod -+crypto/ -+ The cryptographic library; start with crypto.pod -+ -+Formatted versions of the manpages (apps,ssl,crypto) can be found at -+ https://www.openssl.org/docs/manpages.html -diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/SCT_validate.pod b/CryptoPkg/Library/OpensslLib/openssl/doc/SCT_validate.pod -new file mode 100644 -index 0000000..9868a28 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/doc/SCT_validate.pod -@@ -0,0 +1,98 @@ -+=pod -+ -+=head1 NAME -+ -+SCT_validate, SCT_LIST_validate, SCT_get_validation_status - -+checks Signed Certificate Timestamps (SCTs) are valid -+ -+=head1 SYNOPSIS -+ -+ #include -+ -+ typedef enum { -+ SCT_VALIDATION_STATUS_NOT_SET, -+ SCT_VALIDATION_STATUS_UNKNOWN_LOG, -+ SCT_VALIDATION_STATUS_VALID, -+ SCT_VALIDATION_STATUS_INVALID, -+ SCT_VALIDATION_STATUS_UNVERIFIED, -+ SCT_VALIDATION_STATUS_UNKNOWN_VERSION -+ } sct_validation_status_t; -+ -+ int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx); -+ int SCT_LIST_validate(const STACK_OF(SCT) *scts, CT_POLICY_EVAL_CTX *ctx); -+ sct_validation_status_t SCT_get_validation_status(const SCT *sct); -+ -+=head1 DESCRIPTION -+ -+SCT_validate() will check that an SCT is valid and verify its signature. -+SCT_LIST_validate() performs the same checks on an entire stack of SCTs. -+The result of the validation checks can be obtained by passing the SCT to -+SCT_get_validation_status(). -+ -+A CT_POLICY_EVAL_CTX must be provided that specifies: -+ -+=over -+ -+=item * The certificate the SCT was issued for. -+ -+Failure to provide the certificate will result in the validation status being -+SCT_VALIDATION_STATUS_UNVERIFIED. -+ -+=item * The issuer of that certificate. -+ -+This is only required if the SCT was issued for a pre-certificate -+(see RFC 6962). If it is required but not provided, the validation status will -+be SCT_VALIDATION_STATUS_UNVERIFIED. -+ -+=item * A CTLOG_STORE that contains the CT log that issued this SCT. -+ -+If the SCT was issued by a log that is not in this CTLOG_STORE, the validation -+status will be SCT_VALIDATION_STATUS_UNKNOWN_LOG. -+ -+=back -+ -+If the SCT is of an unsupported version (only v1 is currently supported), the -+validation status will be SCT_VALIDATION_STATUS_UNKNOWN_VERSION. -+ -+If the SCT's signature is incorrect, its timestamp is in the future (relative to -+the time in CT_POLICY_EVAL_CTX), or if it is otherwise invalid, the validation -+status will be SCT_VALIDATION_STATUS_INVALID. -+ -+If all checks pass, the validation status will be SCT_VALIDATION_STATUS_VALID. -+ -+=head1 NOTES -+ -+A return value of 0 from SCT_LIST_validate() should not be interpreted as a -+failure. At a minimum, only one valid SCT may provide sufficient confidence -+that a certificate has been publicly logged. -+ -+=head1 RETURN VALUES -+ -+SCT_validate() returns a negative integer if an internal error occurs, 0 if the -+SCT fails validation, or 1 if the SCT passes validation. -+ -+SCT_LIST_validate() returns a negative integer if an internal error occurs, 0 -+if any of SCTs fails validation, or 1 if they all pass validation. -+ -+SCT_get_validation_status() returns the validation status of the SCT. -+If SCT_validate() or SCT_LIST_validate() have not been passed that SCT, the -+returned value will be SCT_VALIDATION_STATUS_NOT_SET. -+ -+=head1 SEE ALSO -+ -+L -+ -+=head1 HISTORY -+ -+These functions were added in OpenSSL 1.1.0. -+ -+=head1 COPYRIGHT -+ -+Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. -+ -+Licensed under the OpenSSL license (the "License"). You may not use -+this file except in compliance with the License. You can obtain a copy -+in the file LICENSE in the source distribution or at -+L. -+ -+=cut -diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/SSL_CTX_set_ct_validation_callback.pod b/CryptoPkg/Library/OpensslLib/openssl/doc/SSL_CTX_set_ct_validation_callback.pod -new file mode 100644 -index 0000000..d818e00 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/doc/SSL_CTX_set_ct_validation_callback.pod -@@ -0,0 +1,142 @@ -+=pod -+ -+=head1 NAME -+ -+SSL_enable_ct, SSL_CTX_enable_ct, SSL_disable_ct, SSL_CTX_disable_ct, -+SSL_set_ct_validation_callback, SSL_CTX_set_ct_validation_callback, -+SSL_ct_is_enabled, SSL_CTX_ct_is_enabled - -+control Certificate Transparency policy -+ -+=head1 SYNOPSIS -+ -+ #include -+ -+ int SSL_enable_ct(SSL *s, int validation_mode); -+ int SSL_CTX_enable_ct(SSL_CTX *ctx, int validation_mode); -+ int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback, -+ void *arg); -+ int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx, -+ ssl_ct_validation_cb callback, -+ void *arg); -+ void SSL_disable_ct(SSL *s); -+ void SSL_CTX_disable_ct(SSL_CTX *ctx); -+ int SSL_ct_is_enabled(const SSL *s); -+ int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx); -+ -+=head1 DESCRIPTION -+ -+SSL_enable_ct() and SSL_CTX_enable_ct() enable the processing of signed -+certificate timestamps (SCTs) either for a given SSL connection or for all -+connections that share the given SSL context, respectively. -+This is accomplished by setting a built-in CT validation callback. -+The behaviour of the callback is determined by the B argument, -+which can be either of B or -+B as described below. -+ -+If B is equal to B, then in a full -+TLS handshake with the verification mode set to B, if the peer -+presents no valid SCTs the handshake will be aborted. -+If the verification mode is B, the handshake will continue -+despite lack of valid SCTs. -+However, in that case if the verification status before the built-in callback -+was B it will be set to B after the -+callback. -+Applications can call L to check the status at -+handshake completion, even after session resumption since the verification -+status is part of the saved session state. -+See L, , L. -+ -+If B is equal to B, then the -+handshake continues, and the verification status is not modified, regardless of -+the validation status of any SCTs. -+The application can still inspect the validation status of the SCTs at -+handshake completion. -+Note that with session resumption there will not be any SCTs presented during -+the handshake. -+Therefore, in applications that delay SCT policy enforcement until after -+handshake completion, such delayed SCT checks should only be performed when the -+session is not resumed. -+ -+SSL_set_ct_validation_callback() and SSL_CTX_set_ct_validation_callback() -+register a custom callback that may implement a different policy than either of -+the above. -+This callback can examine the peer's SCTs and determine whether they are -+sufficient to allow the connection to continue. -+The TLS handshake is aborted if the verification mode is not B -+and the callback returns a non-positive result. -+ -+An arbitrary callback context argument, B, can be passed in when setting -+the callback. -+This will be passed to the callback whenever it is invoked. -+Ownership of this context remains with the caller. -+ -+If no callback is set, SCTs will not be requested and Certificate Transparency -+validation will not occur. -+ -+No callback will be invoked when the peer presents no certificate, e.g. by -+employing an anonymous (aNULL) ciphersuite. -+In that case the handshake continues as it would had no callback been -+requested. -+Callbacks are also not invoked when the peer certificate chain is invalid or -+validated via DANE-TA(2) or DANE-EE(3) TLSA records which use a private X.509 -+PKI, or no X.509 PKI at all, respectively. -+Clients that require SCTs are expected to not have enabled any aNULL ciphers -+nor to have specified server verification via DANE-TA(2) or DANE-EE(3) TLSA -+records. -+ -+SSL_disable_ct() and SSL_CTX_disable_ct() turn off CT processing, whether -+enabled via the built-in or the custom callbacks, by setting a NULL callback. -+These may be implemented as macros. -+ -+SSL_ct_is_enabled() and SSL_CTX_ct_is_enabled() return 1 if CT processing is -+enabled via either SSL_enable_ct() or a non-null custom callback, and 0 -+otherwise. -+ -+=head1 NOTES -+ -+When SCT processing is enabled, OCSP stapling will be enabled. This is because -+one possible source of SCTs is the OCSP response from a server. -+ -+The time returned by SSL_SESSION_get_time() will be used to evaluate whether any -+presented SCTs have timestamps that are in the future (and therefore invalid). -+ -+=head1 RESTRICTIONS -+ -+Certificate Transparency validation cannot be enabled and so a callback cannot -+be set if a custom client extension handler has been registered to handle SCT -+extensions (B). -+ -+=head1 RETURN VALUES -+ -+SSL_enable_ct(), SSL_CTX_enable_ct(), SSL_CTX_set_ct_validation_callback() and -+SSL_set_ct_validation_callback() return 1 if the B is successfully -+set. -+They return 0 if an error occurs, e.g. a custom client extension handler has -+been setup to handle SCTs. -+ -+SSL_disable_ct() and SSL_CTX_disable_ct() do not return a result. -+ -+SSL_CTX_ct_is_enabled() and SSL_ct_is_enabled() return a 1 if a non-null CT -+validation callback is set, or 0 if no callback (or equivalently a NULL -+callback) is set. -+ -+=head1 SEE ALSO -+ -+L, -+, -+L, -+L, -+L, -+L, -+L -+ -+=head1 COPYRIGHT -+ -+Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. -+ -+Licensed under the OpenSSL license (the "License"). You may not use -+this file except in compliance with the License. You can obtain a copy -+in the file LICENSE in the source distribution or at -+L. -+ -+=cut -diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/apps/CA.pl.pod b/CryptoPkg/Library/OpensslLib/openssl/doc/apps/CA.pl.pod -new file mode 100644 -index 0000000..a7f3970 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/doc/apps/CA.pl.pod -@@ -0,0 +1,214 @@ -+=pod -+ -+=head1 NAME -+ -+CA.pl - friendlier interface for OpenSSL certificate programs -+ -+=head1 SYNOPSIS -+ -+B -+B<-?> | -+B<-h> | -+B<-help> -+ -+B -+B<-newcert> | -+B<-newreq> | -+B<-newreq-nodes> | -+B<-xsign> | -+B<-sign> | -+B<-signCA> | -+B<-signcert> | -+B<-crl> | -+B<-newca> -+[B<-extra-cmd> extra-params] -+ -+B B<-pkcs12> [B<-extra-pkcs12> extra-params] [B] -+ -+B B<-verify> [B<-extra-verify> extra-params] B... -+ -+B B<-revoke> [B<-extra-ca> extra-params] B [B] -+ -+=head1 DESCRIPTION -+ -+The B script is a perl script that supplies the relevant command line -+arguments to the B command for some common certificate operations. -+It is intended to simplify the process of certificate creation and management -+by the use of some simple options. -+ -+=head1 OPTIONS -+ -+=over 4 -+ -+=item B, B<-h>, B<-help> -+ -+prints a usage message. -+ -+=item B<-newcert> -+ -+creates a new self signed certificate. The private key is written to the file -+"newkey.pem" and the request written to the file "newreq.pem". -+This argument invokes B command. -+ -+=item B<-newreq> -+ -+creates a new certificate request. The private key is written to the file -+"newkey.pem" and the request written to the file "newreq.pem". -+Executes B command below the hood. -+ -+=item B<-newreq-nodes> -+ -+is like B<-newreq> except that the private key will not be encrypted. -+Uses B command. -+ -+=item B<-newca> -+ -+creates a new CA hierarchy for use with the B program (or the B<-signcert> -+and B<-xsign> options). The user is prompted to enter the filename of the CA -+certificates (which should also contain the private key) or by hitting ENTER -+details of the CA will be prompted for. The relevant files and directories -+are created in a directory called "demoCA" in the current directory. -+B and B commands are get invoked. -+ -+=item B<-pkcs12> -+ -+create a PKCS#12 file containing the user certificate, private key and CA -+certificate. It expects the user certificate and private key to be in the -+file "newcert.pem" and the CA certificate to be in the file demoCA/cacert.pem, -+it creates a file "newcert.p12". This command can thus be called after the -+B<-sign> option. The PKCS#12 file can be imported directly into a browser. -+If there is an additional argument on the command line it will be used as the -+"friendly name" for the certificate (which is typically displayed in the browser -+list box), otherwise the name "My Certificate" is used. -+Delegates work to B command. -+ -+=item B<-sign>, B<-signcert>, B<-xsign> -+ -+calls the B program to sign a certificate request. It expects the request -+to be in the file "newreq.pem". The new certificate is written to the file -+"newcert.pem" except in the case of the B<-xsign> option when it is written -+to standard output. Leverages B command. -+ -+=item B<-signCA> -+ -+this option is the same as the B<-signreq> option except it uses the configuration -+file section B and so makes the signed request a valid CA certificate. This -+is useful when creating intermediate CA from a root CA. -+Extra params are passed on to B command. -+ -+=item B<-signcert> -+ -+this option is the same as B<-sign> except it expects a self signed certificate -+to be present in the file "newreq.pem". -+Extra params are passed on to B and B commands. -+ -+=item B<-crl> -+ -+generate a CRL. Executes B command. -+ -+=item B<-revoke certfile [reason]> -+ -+revoke the certificate contained in the specified B. An optional -+reason may be specified, and must be one of: B, -+B, B, B, B, -+B, B, or B. -+Leverages B command. -+ -+=item B<-verify> -+ -+verifies certificates against the CA certificate for "demoCA". If no certificates -+are specified on the command line it tries to verify the file "newcert.pem". -+Invokes B command. -+ -+=item B<-extra-req> | B<-extra-ca> | B<-extra-pkcs12> | B<-extra-x509> | B<-extra-verify> -+ -+The purpose of these parameters is to allow optional parameters to be supplied -+to B that this command executes. The B<-extra-cmd> are specific to the -+option being used and the B command getting invoked. For example -+when this command invokes B extra parameters can be passed on -+with the B<-extra-req> parameter. The -+B commands being invoked per option are documented below. -+Users should consult B command documentation for more information. -+ -+=back -+ -+=head1 EXAMPLES -+ -+Create a CA hierarchy: -+ -+ CA.pl -newca -+ -+Complete certificate creation example: create a CA, create a request, sign -+the request and finally create a PKCS#12 file containing it. -+ -+ CA.pl -newca -+ CA.pl -newreq -+ CA.pl -signreq -+ CA.pl -pkcs12 "My Test Certificate" -+ -+=head1 DSA CERTIFICATES -+ -+Although the B creates RSA CAs and requests it is still possible to -+use it with DSA certificates and requests using the L command -+directly. The following example shows the steps that would typically be taken. -+ -+Create some DSA parameters: -+ -+ openssl dsaparam -out dsap.pem 1024 -+ -+Create a DSA CA certificate and private key: -+ -+ openssl req -x509 -newkey dsa:dsap.pem -keyout cacert.pem -out cacert.pem -+ -+Create the CA directories and files: -+ -+ CA.pl -newca -+ -+enter cacert.pem when prompted for the CA file name. -+ -+Create a DSA certificate request and private key (a different set of parameters -+can optionally be created first): -+ -+ openssl req -out newreq.pem -newkey dsa:dsap.pem -+ -+Sign the request: -+ -+ CA.pl -signreq -+ -+=head1 NOTES -+ -+Most of the filenames mentioned can be modified by editing the B script. -+ -+If the demoCA directory already exists then the B<-newca> command will not -+overwrite it and will do nothing. This can happen if a previous call using -+the B<-newca> option terminated abnormally. To get the correct behaviour -+delete the demoCA directory if it already exists. -+ -+Under some environments it may not be possible to run the B script -+directly (for example Win32) and the default configuration file location may -+be wrong. In this case the command: -+ -+ perl -S CA.pl -+ -+can be used and the B environment variable changed to point to -+the correct path of the configuration file. -+ -+The script is intended as a simple front end for the B program for use -+by a beginner. Its behaviour isn't always what is wanted. For more control over the -+behaviour of the certificate commands call the B command directly. -+ -+=head1 SEE ALSO -+ -+L, L, L, L, -+L -+ -+=head1 COPYRIGHT -+ -+Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. -+ -+Licensed under the OpenSSL license (the "License"). You may not use -+this file except in compliance with the License. You can obtain a copy -+in the file LICENSE in the source distribution or at -+L. -+ -+=cut -diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/apps/asn1parse.pod b/CryptoPkg/Library/OpensslLib/openssl/doc/apps/asn1parse.pod -new file mode 100644 -index 0000000..10a5aba ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/doc/apps/asn1parse.pod -@@ -0,0 +1,208 @@ -+=pod -+ -+=head1 NAME -+ -+asn1parse - ASN.1 parsing tool -+ -+=head1 SYNOPSIS -+ -+B B -+[B<-help>] -+[B<-inform PEM|DER>] -+[B<-in filename>] -+[B<-out filename>] -+[B<-noout>] -+[B<-offset number>] -+[B<-length number>] -+[B<-i>] -+[B<-oid filename>] -+[B<-dump>] -+[B<-dlimit num>] -+[B<-strparse offset>] -+[B<-genstr string>] -+[B<-genconf file>] -+[B<-strictpem>] -+ -+=head1 DESCRIPTION -+ -+The B command is a diagnostic utility that can parse ASN.1 -+structures. It can also be used to extract data from ASN.1 formatted data. -+ -+=head1 OPTIONS -+ -+=over 4 -+ -+=item B<-help> -+ -+Print out a usage message. -+ -+=item B<-inform> B -+ -+the input format. B is binary format and B (the default) is base64 -+encoded. -+ -+=item B<-in filename> -+ -+the input file, default is standard input -+ -+=item B<-out filename> -+ -+output file to place the DER encoded data into. If this -+option is not present then no data will be output. This is most useful when -+combined with the B<-strparse> option. -+ -+=item B<-noout> -+ -+don't output the parsed version of the input file. -+ -+=item B<-offset number> -+ -+starting offset to begin parsing, default is start of file. -+ -+=item B<-length number> -+ -+number of bytes to parse, default is until end of file. -+ -+=item B<-i> -+ -+indents the output according to the "depth" of the structures. -+ -+=item B<-oid filename> -+ -+a file containing additional OBJECT IDENTIFIERs (OIDs). The format of this -+file is described in the NOTES section below. -+ -+=item B<-dump> -+ -+dump unknown data in hex format. -+ -+=item B<-dlimit num> -+ -+like B<-dump>, but only the first B bytes are output. -+ -+=item B<-strparse offset> -+ -+parse the contents octets of the ASN.1 object starting at B. This -+option can be used multiple times to "drill down" into a nested structure. -+ -+=item B<-genstr string>, B<-genconf file> -+ -+generate encoded data based on B, B or both using -+L format. If B only is -+present then the string is obtained from the default section using the name -+B. The encoded data is passed through the ASN1 parser and printed out as -+though it came from a file, the contents can thus be examined and written to a -+file using the B option. -+ -+=item B<-strictpem> -+ -+If this option is used then B<-inform> will be ignored. Without this option any -+data in a PEM format input file will be treated as being base64 encoded and -+processed whether it has the normal PEM BEGIN and END markers or not. This -+option will ignore any data prior to the start of the BEGIN marker, or after an -+END marker in a PEM file. -+ -+=back -+ -+=head2 Output -+ -+The output will typically contain lines like this: -+ -+ 0:d=0 hl=4 l= 681 cons: SEQUENCE -+ -+..... -+ -+ 229:d=3 hl=3 l= 141 prim: BIT STRING -+ 373:d=2 hl=3 l= 162 cons: cont [ 3 ] -+ 376:d=3 hl=3 l= 159 cons: SEQUENCE -+ 379:d=4 hl=2 l= 29 cons: SEQUENCE -+ 381:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Subject Key Identifier -+ 386:d=5 hl=2 l= 22 prim: OCTET STRING -+ 410:d=4 hl=2 l= 112 cons: SEQUENCE -+ 412:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Authority Key Identifier -+ 417:d=5 hl=2 l= 105 prim: OCTET STRING -+ 524:d=4 hl=2 l= 12 cons: SEQUENCE -+ -+..... -+ -+This example is part of a self-signed certificate. Each line starts with the -+offset in decimal. B specifies the current depth. The depth is increased -+within the scope of any SET or SEQUENCE. B gives the header length -+(tag and length octets) of the current type. B gives the length of -+the contents octets. -+ -+The B<-i> option can be used to make the output more readable. -+ -+Some knowledge of the ASN.1 structure is needed to interpret the output. -+ -+In this example the BIT STRING at offset 229 is the certificate public key. -+The contents octets of this will contain the public key information. This can -+be examined using the option B<-strparse 229> to yield: -+ -+ 0:d=0 hl=3 l= 137 cons: SEQUENCE -+ 3:d=1 hl=3 l= 129 prim: INTEGER :E5D21E1F5C8D208EA7A2166C7FAF9F6BDF2059669C60876DDB70840F1A5AAFA59699FE471F379F1DD6A487E7D5409AB6A88D4A9746E24B91D8CF55DB3521015460C8EDE44EE8A4189F7A7BE77D6CD3A9AF2696F486855CF58BF0EDF2B4068058C7A947F52548DDF7E15E96B385F86422BEA9064A3EE9E1158A56E4A6F47E5897 -+ 135:d=1 hl=2 l= 3 prim: INTEGER :010001 -+ -+=head1 NOTES -+ -+If an OID is not part of OpenSSL's internal table it will be represented in -+numerical form (for example 1.2.3.4). The file passed to the B<-oid> option -+allows additional OIDs to be included. Each line consists of three columns, -+the first column is the OID in numerical format and should be followed by white -+space. The second column is the "short name" which is a single word followed -+by white space. The final column is the rest of the line and is the -+"long name". B displays the long name. Example: -+ -+C<1.2.3.4 shortName A long name> -+ -+=head1 EXAMPLES -+ -+Parse a file: -+ -+ openssl asn1parse -in file.pem -+ -+Parse a DER file: -+ -+ openssl asn1parse -inform DER -in file.der -+ -+Generate a simple UTF8String: -+ -+ openssl asn1parse -genstr 'UTF8:Hello World' -+ -+Generate and write out a UTF8String, don't print parsed output: -+ -+ openssl asn1parse -genstr 'UTF8:Hello World' -noout -out utf8.der -+ -+Generate using a config file: -+ -+ openssl asn1parse -genconf asn1.cnf -noout -out asn1.der -+ -+Example config file: -+ -+ asn1=SEQUENCE:seq_sect -+ -+ [seq_sect] -+ -+ field1=BOOL:TRUE -+ field2=EXP:0, UTF8:some random string -+ -+ -+=head1 BUGS -+ -+There should be options to change the format of output lines. The output of some -+ASN.1 types is not well handled (if at all). -+ -+=head1 SEE ALSO -+ -+L -+ -+=head1 COPYRIGHT -+ -+Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. -+ -+Licensed under the OpenSSL license (the "License"). You may not use -+this file except in compliance with the License. You can obtain a copy -+in the file LICENSE in the source distribution or at -+L. -+ -+=cut -diff --git a/CryptoPkg/Library/OpensslLib/openssl/doc/apps/ca.pod b/CryptoPkg/Library/OpensslLib/openssl/doc/apps/ca.pod -new file mode 100644 -index 0000000..c09db82 ---- /dev/null -+++ b/CryptoPkg/Library/OpensslLib/openssl/doc/apps/ca.pod -@@ -0,0 +1,719 @@ -+=pod -+ -+=head1 NAME -+ -+ca - sample minimal CA application -+ -+=head1 SYNOPSIS -+ -+B B -+[B<-help>] -+[B<-verbose>] -+[B<-config filename>] -+[B<-name section>] -+[B<-gencrl>] -+[B<-revoke file>] -+[B<-valid file>] -+[B<-status serial>] -+[B<-updatedb>] -+[B<-crl_reason reason>] -+[B<-crl_hold instruction>] -+[B<-crl_compromise time>] -+[B<-crl_CA_compromise time>] -+[B<-crldays days>] -+[B<-crlhours hours>] -+[B<-crlexts section>] -+[B<-startdate date>] -+[B<-enddate date>] -+[B<-days arg>] -+[B<-md arg>] -+[B<-policy arg>] -+[B<-keyfile arg>] -+[B<-keyform PEM|DER>] -+[B<-key arg>] -+[B<-passin arg>] -+[B<-cert file>] -+[B<-selfsign>] -+[B<-in file>] -+[B<-out file>] -+[B<-notext>] -+[B<-outdir dir>] -+[B<-infiles>] -+[B<-spkac file>] -+[B<-ss_cert file>] -+[B<-preserveDN>] -+[B<-noemailDN>] -+[B<-batch>] -+[B<-msie_hack>] -+[B<-extensions section>] -+[B<-extfile section>] -+[B<-engine id>] -+[B<-subj arg>] -+[B<-utf8>] -+[B<-create_serial>] -+[B<-multivalue-rdn>] -+ -+=head1 DESCRIPTION -+ -+The B command is a minimal CA application. It can be used -+to sign certificate requests in a variety of forms and generate -+CRLs it also maintains a text database of issued certificates -+and their status. -+ -+The options descriptions will be divided into each purpose. -+ -+=head1 OPTIONS -+ -+=over 4 -+ -+=item B<-help> -+ -+Print out a usage message. -+ -+=item B<-verbose> -+ -+this prints extra details about the operations being performed. -+ -+=item B<-config filename> -+ -+specifies the configuration file to use. -+Optional; for a description of the default value, -+see L. -+ -+=item B<-name section> -+ -+specifies the configuration file section to use (overrides -+B in the B section). -+ -+=item B<-in filename> -+ -+an input filename containing a single certificate request to be -+signed by the CA. -+ -+=item B<-ss_cert filename> -+ -+a single self-signed certificate to be signed by the CA. -+ -+=item B<-spkac filename> -+ -+a file containing a single Netscape signed public key and challenge -+and additional field values to be signed by the CA. See the B -+section for information on the required input and output format. -+ -+=item B<-infiles> -+ -+if present this should be the last option, all subsequent arguments -+are taken as the names of files containing certificate requests. -+ -+=item B<-out filename> -+ -+the output file to output certificates to. The default is standard -+output. The certificate details will also be printed out to this -+file in PEM format (except that B<-spkac> outputs DER format). -+ -+=item B<-outdir directory> -+ -+the directory to output certificates to. The certificate will be -+written to a filename consisting of the serial number in hex with -+".pem" appended. -+ -+=item B<-cert> -+ -+the CA certificate file. -+ -+=item B<-keyfile filename> -+ -+the private key to sign requests with. -+ -+=item B<-keyform PEM|DER> -+ -+the format of the data in the private key file. -+The default is PEM. -+ -+=item B<-key password> -+ -+the password used to encrypt the private key. Since on some -+systems the command line arguments are visible (e.g. Unix with -+the 'ps' utility) this option should be used with caution. -+ -+=item B<-selfsign> -+ -+indicates the issued certificates are to be signed with the key -+the certificate requests were signed with (given with B<-keyfile>). -+Certificate requests signed with a different key are ignored. If -+B<-spkac>, B<-ss_cert> or B<-gencrl> are given, B<-selfsign> is -+ignored. -+ -+A consequence of using B<-selfsign> is that the self-signed -+certificate appears among the entries in the certificate database -+(see the configuration option B), and uses the same -+serial number counter as all other certificates sign with the -+self-signed certificate. -+ -+=item B<-passin arg> -+ -+the key password source. For more information about the format of B -+see the B section in L. -+ -+=item B<-notext> -+ -+don't output the text form of a certificate to the output file. -+ -+=item B<-startdate date> -+ -+this allows the start date to be explicitly set. The format of the -+date is YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure). -+ -+=item B<-enddate date> -+ -+this allows the expiry date to be explicitly set. The format of the -+date is YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure). -+ -+=item B<-days arg> -+ -+the number of days to certify the certificate for. -+ -+=item B<-md alg> -+ -+the message digest to use. -+Any digest supported by the OpenSSL B command can be used. -+This option also applies to CRLs. -+ -+=item B<-policy arg> -+ -+this option defines the CA "policy" to use. This is a section in -+the configuration file which decides which fields should be mandatory -+or match the CA certificate. Check out the B section -+for more information. -+ -+=item B<-msie_hack> -+ -+this is a legacy option to make B work with very old versions of -+the IE certificate enrollment control "certenr3". It used UniversalStrings -+for almost everything. Since the old control has various security bugs -+its use is strongly discouraged. The newer control "Xenroll" does not -+need this option. -+ -+=item B<-preserveDN> -+ -+Normally the DN order of a certificate is the same as the order of the -+fields in the relevant policy section. When this option is set the order -+is the same as the request. This is largely for compatibility with the -+older IE enrollment control which would only accept certificates if their -+DNs match the order of the request. This is not needed for Xenroll. -+ -+=item B<-noemailDN> -+ -+The DN of a certificate can contain the EMAIL field if present in the -+request DN, however it is good policy just having the e-mail set into -+the altName extension of the certificate. When this option is set the -+EMAIL field is removed from the certificate' subject and set only in -+the, eventually present, extensions. The B keyword can be -+used in the configuration file to enable this behaviour. -+ -+=item B<-batch> -+ -+this sets the batch mode. In this mode no questions will be asked -+and all certificates will be certified automatically. -+ -+=item B<-extensions section> -+ -+the section of the configuration file containing certificate extensions -+to be added when a certificate is issued (defaults to B -+unless the B<-extfile> option is used). If no extension section is -+present then, a V1 certificate is created. If the extension section -+is present (even if it is empty), then a V3 certificate is created. See the:w -+L manual page for details of the -+extension section format. -+ -+=item B<-extfile file> -+ -+an additional configuration file to read certificate extensions from -+(using the default section unless the B<-extensions> option is also -+used). -+ -+=item B<-engine id> -+ -+specifying an engine (by its unique B string) will cause B -+to attempt to obtain a functional reference to the specified engine, -+thus initialising it if needed. The engine will then be set as the default -+for all available algorithms. -+ -+=item B<-subj arg> -+ -+supersedes subject name given in the request. -+The arg must be formatted as I, -+characters may be escaped by \ (backslash), no spaces are skipped. -+ -+=item B<-utf8> -+ -+this option causes field values to be interpreted as UTF8 strings, by -+default they are interpreted as ASCII. This means that the field -+values, whether prompted from a terminal or obtained from a -+configuration file, must be valid UTF8 strings. -+ -+=item B<-create_serial> -+ -+if reading serial from the text file as specified in the configuration -+fails, specifying this option creates a new random serial to be used as next -+serial number. -+ -+=item B<-multivalue-rdn> -+ -+This option causes the -subj argument to be interpreted with full -+support for multivalued RDNs. Example: -+ -+I -+ -+If -multi-rdn is not used then the UID value is I<123456+CN=John Doe>. -+ -+=back -+ -+=head1 CRL OPTIONS -+ -+=over 4 -+ -+=item B<-gencrl> -+ -+this option generates a CRL based on information in the index file. -+ -+=item B<-crldays num> -+ -+the number of days before the next CRL is due. That is the days from -+now to place in the CRL nextUpdate field. -+ -+=item B<-crlhours num> -+ -+the number of hours before the next CRL is due. -+ -+=item B<-revoke filename> -+ -+a filename containing a certificate to revoke. -+ -+=item B<-valid filename> -+ -+a filename containing a certificate to add a Valid certificate entry. -+ -+=item B<-status serial> -+ -+displays the revocation status of the certificate with the specified -+serial number and exits. -+ -+=item B<-updatedb> -+ -+Updates the database index to purge expired certificates. -+ -+=item B<-crl_reason reason> -+ -+revocation reason, where B is one of: B, B, -+B, B, B, B, -+B or B. The matching of B is case -+insensitive. Setting any revocation reason will make the CRL v2. -+ -+In practice B is not particularly useful because it is only used -+in delta CRLs which are not currently implemented. -+ -+=item B<-crl_hold instruction> -+ -+This sets the CRL revocation reason code to B and the hold -+instruction to B which must be an OID. Although any OID can be -+used only B (the use of which is discouraged by RFC2459) -+B or B will normally be used. -+ -+=item B<-crl_compromise time> -+ -+This sets the revocation reason to B and the compromise time to -+B